Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-03-18 23:02:30 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-03-18 23:02:30 +0300
commit41fe97390ceddf945f3d967b8fdb3de4c66b7dea (patch)
tree9c8d89a8624828992f06d892cd2f43818ff5dcc8
parent0804d2dc31052fb45a1efecedc8e06ce9bc32862 (diff)
Add latest changes from gitlab-org/gitlab@14-9-stable-eev14.9.0-rc42
-rw-r--r--.eslintignore1
-rw-r--r--.eslintrc.yml2
-rw-r--r--.gitlab-ci.yml9
-rw-r--r--.gitlab/CODEOWNERS180
-rw-r--r--.gitlab/ci/ci-templates.gitlab-ci.yml13
-rw-r--r--.gitlab/ci/frontend.gitlab-ci.yml2
-rw-r--r--.gitlab/ci/global.gitlab-ci.yml22
-rw-r--r--.gitlab/ci/memory.gitlab-ci.yml16
-rw-r--r--.gitlab/ci/rails.gitlab-ci.yml204
-rw-r--r--.gitlab/ci/reports.gitlab-ci.yml5
-rw-r--r--.gitlab/ci/review-apps/dast.gitlab-ci.yml2
-rw-r--r--.gitlab/ci/review-apps/qa.gitlab-ci.yml8
-rw-r--r--.gitlab/ci/rules.gitlab-ci.yml38
-rw-r--r--.gitlab/ci/setup.gitlab-ci.yml2
-rw-r--r--.gitlab/ci/yaml.gitlab-ci.yml2
-rw-r--r--.gitlab/issue_templates/Deprecations.md28
-rw-r--r--.gitlab/issue_templates/Design Sprint.md6
-rw-r--r--.gitlab/issue_templates/Doc_cleanup.md53
-rw-r--r--.gitlab/issue_templates/Dogfooding.md2
-rw-r--r--.gitlab/issue_templates/Feature Flag Roll Out.md5
-rw-r--r--.gitlab/issue_templates/Feature Proposal - lean.md6
-rw-r--r--.gitlab/issue_templates/Feature proposal - detailed.md15
-rw-r--r--.gitlab/issue_templates/Fulfillment Group UX Issue.md9
-rw-r--r--.gitlab/issue_templates/QA Failure.md7
-rw-r--r--.gitlab/issue_templates/Refactoring.md5
-rw-r--r--.gitlab/merge_request_templates/Pipeline Configuration.md2
-rw-r--r--.gitlab/merge_request_templates/Security Release.md2
-rw-r--r--.gitpod.yml4
-rw-r--r--.nvmrc2
-rw-r--r--.rubocop.yml14
-rw-r--r--.rubocop_todo.yml132
-rw-r--r--.rubocop_todo/database/multiple_databases.yml11
-rw-r--r--.rubocop_todo/gitlab/namespaced_class.yml1
-rw-r--r--.rubocop_todo/graphql/argument_uniqueness.yml4
-rw-r--r--.rubocop_todo/graphql/field_definitions.yml5
-rw-r--r--.rubocop_todo/graphql/field_method.yml4
-rw-r--r--.rubocop_todo/graphql/ordered_arguments.yml7
-rw-r--r--.rubocop_todo/graphql/ordered_fields.yml34
-rw-r--r--.rubocop_todo/graphql/unused_argument.yml5
-rw-r--r--.rubocop_todo/rails/include_url_helper.yml37
-rw-r--r--.rubocop_todo/rails/save_bang.yml4
-rw-r--r--.rubocop_todo/rspec/instance_variable.yml203
-rw-r--r--.rubocop_todo/rspec/timecop_travel.yml12
-rw-r--r--.rubocop_todo/rspec/verified_doubles.yml1206
-rw-r--r--.rubocop_todo/style/open_struct_use.yml1
-rw-r--r--CHANGELOG.md44
-rw-r--r--Dangerfile21
-rw-r--r--GITALY_SERVER_VERSION2
-rw-r--r--GITLAB_KAS_VERSION2
-rw-r--r--GITLAB_PAGES_VERSION2
-rw-r--r--GITLAB_SHELL_VERSION2
-rw-r--r--Gemfile22
-rw-r--r--Gemfile.lock90
-rwxr-xr-xRakefile2
-rw-r--r--app/assets/images/aws-cloud-formation.pngbin2545 -> 0 bytes
-rw-r--r--app/assets/images/vulnerability/kontra-logo.svg1
-rw-r--r--app/assets/images/vulnerability/scw-logo.svg1
-rw-r--r--app/assets/javascripts/access_tokens/components/expires_at_field.vue43
-rw-r--r--app/assets/javascripts/access_tokens/components/tokens_app.vue1
-rw-r--r--app/assets/javascripts/access_tokens/index.js2
-rw-r--r--app/assets/javascripts/activities.js2
-rw-r--r--app/assets/javascripts/admin/applications/components/delete_application.vue84
-rw-r--r--app/assets/javascripts/admin/applications/index.js15
-rw-r--r--app/assets/javascripts/admin/topics/components/remove_avatar.vue67
-rw-r--r--app/assets/javascripts/admin/topics/index.js22
-rw-r--r--app/assets/javascripts/admin/users/components/user_actions.vue7
-rw-r--r--app/assets/javascripts/admin/users/components/user_avatar.vue2
-rw-r--r--app/assets/javascripts/alert_management/components/alert_management_table.vue7
-rw-r--r--app/assets/javascripts/api.js8
-rw-r--r--app/assets/javascripts/attention_requests/components/navigation_popover.vue120
-rw-r--r--app/assets/javascripts/attention_requests/index.js73
-rw-r--r--app/assets/javascripts/authentication/webauthn/util.js11
-rw-r--r--app/assets/javascripts/behaviors/markdown/editor_extensions.js78
-rw-r--r--app/assets/javascripts/behaviors/markdown/marks/bold.js22
-rw-r--r--app/assets/javascripts/behaviors/markdown/marks/code.js17
-rw-r--r--app/assets/javascripts/behaviors/markdown/marks/inline_diff.js66
-rw-r--r--app/assets/javascripts/behaviors/markdown/marks/inline_html.js71
-rw-r--r--app/assets/javascripts/behaviors/markdown/marks/italic.js16
-rw-r--r--app/assets/javascripts/behaviors/markdown/marks/link.js58
-rw-r--r--app/assets/javascripts/behaviors/markdown/marks/math.js61
-rw-r--r--app/assets/javascripts/behaviors/markdown/marks/strike.js31
-rw-r--r--app/assets/javascripts/behaviors/markdown/nodes/audio.js9
-rw-r--r--app/assets/javascripts/behaviors/markdown/nodes/blockquote.js18
-rw-r--r--app/assets/javascripts/behaviors/markdown/nodes/bullet_list.js16
-rw-r--r--app/assets/javascripts/behaviors/markdown/nodes/code_block.js127
-rw-r--r--app/assets/javascripts/behaviors/markdown/nodes/description_details.js30
-rw-r--r--app/assets/javascripts/behaviors/markdown/nodes/description_list.js29
-rw-r--r--app/assets/javascripts/behaviors/markdown/nodes/description_term.js32
-rw-r--r--app/assets/javascripts/behaviors/markdown/nodes/details.js30
-rw-r--r--app/assets/javascripts/behaviors/markdown/nodes/doc.js21
-rw-r--r--app/assets/javascripts/behaviors/markdown/nodes/emoji.js84
-rw-r--r--app/assets/javascripts/behaviors/markdown/nodes/hard_break.js18
-rw-r--r--app/assets/javascripts/behaviors/markdown/nodes/heading.js26
-rw-r--r--app/assets/javascripts/behaviors/markdown/nodes/horizontal_rule.js15
-rw-r--r--app/assets/javascripts/behaviors/markdown/nodes/image.js83
-rw-r--r--app/assets/javascripts/behaviors/markdown/nodes/list_item.js17
-rw-r--r--app/assets/javascripts/behaviors/markdown/nodes/ordered_list.js29
-rw-r--r--app/assets/javascripts/behaviors/markdown/nodes/ordered_task_list.js38
-rw-r--r--app/assets/javascripts/behaviors/markdown/nodes/paragraph.js29
-rw-r--r--app/assets/javascripts/behaviors/markdown/nodes/playable.js93
-rw-r--r--app/assets/javascripts/behaviors/markdown/nodes/reference.js85
-rw-r--r--app/assets/javascripts/behaviors/markdown/nodes/summary.js32
-rw-r--r--app/assets/javascripts/behaviors/markdown/nodes/table.js32
-rw-r--r--app/assets/javascripts/behaviors/markdown/nodes/table_body.js30
-rw-r--r--app/assets/javascripts/behaviors/markdown/nodes/table_cell.js54
-rw-r--r--app/assets/javascripts/behaviors/markdown/nodes/table_head.js30
-rw-r--r--app/assets/javascripts/behaviors/markdown/nodes/table_header_row.js40
-rw-r--r--app/assets/javascripts/behaviors/markdown/nodes/table_of_contents.js49
-rw-r--r--app/assets/javascripts/behaviors/markdown/nodes/table_row.js30
-rw-r--r--app/assets/javascripts/behaviors/markdown/nodes/task_list.js39
-rw-r--r--app/assets/javascripts/behaviors/markdown/nodes/task_list_item.js70
-rw-r--r--app/assets/javascripts/behaviors/markdown/nodes/text.js23
-rw-r--r--app/assets/javascripts/behaviors/markdown/nodes/video.js10
-rw-r--r--app/assets/javascripts/behaviors/markdown/render_sandboxed_mermaid.js2
-rw-r--r--app/assets/javascripts/behaviors/markdown/schema.js32
-rw-r--r--app/assets/javascripts/behaviors/markdown/serializer.js32
-rw-r--r--app/assets/javascripts/behaviors/shortcuts/keybindings.js16
-rw-r--r--app/assets/javascripts/behaviors/shortcuts/shortcuts.js7
-rw-r--r--app/assets/javascripts/blob/components/blob_header.vue5
-rw-r--r--app/assets/javascripts/blob/components/blob_header_default_actions.vue3
-rw-r--r--app/assets/javascripts/blob/components/blob_header_viewer_switcher.vue7
-rw-r--r--app/assets/javascripts/blob/csv/csv_viewer.vue32
-rw-r--r--app/assets/javascripts/blob/template_selector.js23
-rw-r--r--app/assets/javascripts/blob_edit/blob_bundle.js11
-rw-r--r--app/assets/javascripts/boards/boards_util.js14
-rw-r--r--app/assets/javascripts/boards/components/board_filtered_search.vue6
-rw-r--r--app/assets/javascripts/boards/components/board_form.vue40
-rw-r--r--app/assets/javascripts/boards/components/board_list_header.vue14
-rw-r--r--app/assets/javascripts/boards/components/boards_selector.vue7
-rw-r--r--app/assets/javascripts/boards/filtered_search_boards.js81
-rw-r--r--app/assets/javascripts/boards/graphql.js1
-rw-r--r--app/assets/javascripts/boards/index.js42
-rw-r--r--app/assets/javascripts/boards/mount_filtered_search_issue_boards.js10
-rw-r--r--app/assets/javascripts/boards/stores/actions.js36
-rw-r--r--app/assets/javascripts/boards/stores/mutation_types.js3
-rw-r--r--app/assets/javascripts/boards/stores/mutations.js17
-rw-r--r--app/assets/javascripts/boards/stores/state.js1
-rw-r--r--app/assets/javascripts/branches/ajax_loading_spinner.js31
-rw-r--r--app/assets/javascripts/captcha/apollo_captcha_link.js2
-rw-r--r--app/assets/javascripts/captcha/captcha_modal.vue6
-rw-r--r--app/assets/javascripts/captcha/captcha_modal_axios_interceptor.js4
-rw-r--r--app/assets/javascripts/ci_lint/components/ci_lint.vue2
-rw-r--r--app/assets/javascripts/ci_secure_files/components/secure_files_list.vue133
-rw-r--r--app/assets/javascripts/ci_secure_files/index.js17
-rw-r--r--app/assets/javascripts/ci_settings_pipeline_triggers/components/triggers_list.vue16
-rw-r--r--app/assets/javascripts/ci_variable_list/ci_variable_list.js3
-rw-r--r--app/assets/javascripts/clusters/agents/components/create_token_button.vue246
-rw-r--r--app/assets/javascripts/clusters/agents/components/show.vue2
-rw-r--r--app/assets/javascripts/clusters/agents/components/token_table.vue41
-rw-r--r--app/assets/javascripts/clusters/agents/constants.js7
-rw-r--r--app/assets/javascripts/clusters/agents/graphql/cache_update.js24
-rw-r--r--app/assets/javascripts/clusters/agents/graphql/mutations/create_new_agent_token.mutation.graphql11
-rw-r--r--app/assets/javascripts/clusters/agents/index.js5
-rw-r--r--app/assets/javascripts/clusters/components/new_cluster.vue6
-rw-r--r--app/assets/javascripts/clusters_list/components/agent_table.vue27
-rw-r--r--app/assets/javascripts/clusters_list/components/agent_token.vue109
-rw-r--r--app/assets/javascripts/clusters_list/components/agents.vue3
-rw-r--r--app/assets/javascripts/clusters_list/components/available_agents_dropdown.vue50
-rw-r--r--app/assets/javascripts/clusters_list/components/clusters.vue8
-rw-r--r--app/assets/javascripts/clusters_list/components/clusters_actions.vue60
-rw-r--r--app/assets/javascripts/clusters_list/components/clusters_empty_state.vue4
-rw-r--r--app/assets/javascripts/clusters_list/components/clusters_main_view.vue36
-rw-r--r--app/assets/javascripts/clusters_list/components/delete_agent_button.vue2
-rw-r--r--app/assets/javascripts/clusters_list/components/install_agent_modal.vue175
-rw-r--r--app/assets/javascripts/clusters_list/constants.js145
-rw-r--r--app/assets/javascripts/clusters_list/graphql/cache_update.js10
-rw-r--r--app/assets/javascripts/clusters_list/graphql/queries/get_agents.query.graphql8
-rw-r--r--app/assets/javascripts/clusters_list/index.js58
-rw-r--r--app/assets/javascripts/clusters_list/load_clusters.js25
-rw-r--r--app/assets/javascripts/clusters_list/load_main_view.js57
-rw-r--r--app/assets/javascripts/code_navigation/components/app.vue27
-rw-r--r--app/assets/javascripts/code_quality_walkthrough/components/step.vue150
-rw-r--r--app/assets/javascripts/code_quality_walkthrough/constants.js67
-rw-r--r--app/assets/javascripts/code_quality_walkthrough/index.js14
-rw-r--r--app/assets/javascripts/code_quality_walkthrough/utils.js39
-rw-r--r--app/assets/javascripts/commons/nav/user_merge_requests.js23
-rw-r--r--app/assets/javascripts/content_editor/components/content_editor.vue29
-rw-r--r--app/assets/javascripts/content_editor/components/content_editor_provider.vue1
-rw-r--r--app/assets/javascripts/content_editor/components/editor_state_observer.vue34
-rw-r--r--app/assets/javascripts/content_editor/components/loading_indicator.vue39
-rw-r--r--app/assets/javascripts/content_editor/constants.js4
-rw-r--r--app/assets/javascripts/content_editor/extensions/attachment.js17
-rw-r--r--app/assets/javascripts/content_editor/extensions/code_block_highlight.js2
-rw-r--r--app/assets/javascripts/content_editor/extensions/paste_markdown.js86
-rw-r--r--app/assets/javascripts/content_editor/extensions/table.js3
-rw-r--r--app/assets/javascripts/content_editor/services/content_editor.js48
-rw-r--r--app/assets/javascripts/content_editor/services/create_content_editor.js13
-rw-r--r--app/assets/javascripts/content_editor/services/markdown_deserializer.js33
-rw-r--r--app/assets/javascripts/content_editor/services/markdown_serializer.js27
-rw-r--r--app/assets/javascripts/content_editor/services/markdown_sourcemap.js6
-rw-r--r--app/assets/javascripts/content_editor/services/serialization_helpers.js9
-rw-r--r--app/assets/javascripts/content_editor/services/upload_helpers.js19
-rw-r--r--app/assets/javascripts/contributors/stores/getters.js5
-rw-r--r--app/assets/javascripts/cycle_analytics/components/limit_warning_component.vue33
-rw-r--r--app/assets/javascripts/cycle_analytics/components/stage_table.vue2
-rw-r--r--app/assets/javascripts/cycle_analytics/components/total_time.vue (renamed from app/assets/javascripts/cycle_analytics/components/total_time_component.vue)0
-rw-r--r--app/assets/javascripts/cycle_analytics/components/value_stream_filters.vue61
-rw-r--r--app/assets/javascripts/deploy_tokens/components/revoke_button.vue6
-rw-r--r--app/assets/javascripts/deploy_tokens/init_revoke_button.js3
-rw-r--r--app/assets/javascripts/deprecated_notes.js33
-rw-r--r--app/assets/javascripts/diff.js42
-rw-r--r--app/assets/javascripts/diffs/components/commit_item.vue2
-rw-r--r--app/assets/javascripts/diffs/components/diff_content.vue4
-rw-r--r--app/assets/javascripts/diffs/components/diff_file_header.vue2
-rw-r--r--app/assets/javascripts/diffs/components/diff_view.vue18
-rw-r--r--app/assets/javascripts/diffs/components/hidden_files_warning.vue52
-rw-r--r--app/assets/javascripts/diffs/store/getters_versions_dropdowns.js13
-rw-r--r--app/assets/javascripts/dirty_submit/dirty_submit_form.js12
-rw-r--r--app/assets/javascripts/editor/extensions/source_editor_ci_schema_ext.js2
-rw-r--r--app/assets/javascripts/editor/schema/ci.json95
-rw-r--r--app/assets/javascripts/emoji/components/picker.vue1
-rw-r--r--app/assets/javascripts/environments/components/commit.vue1
-rw-r--r--app/assets/javascripts/environments/components/delete_environment_modal.vue3
-rw-r--r--app/assets/javascripts/environments/components/deployment.vue8
-rw-r--r--app/assets/javascripts/environments/components/enable_review_app_modal.vue10
-rw-r--r--app/assets/javascripts/environments/components/environment_actions.vue10
-rw-r--r--app/assets/javascripts/environments/components/environment_folder.vue115
-rw-r--r--app/assets/javascripts/environments/components/environments_app.vue390
-rw-r--r--app/assets/javascripts/environments/components/new_environment_folder.vue102
-rw-r--r--app/assets/javascripts/environments/components/new_environment_item.vue21
-rw-r--r--app/assets/javascripts/environments/components/new_environments_app.vue252
-rw-r--r--app/assets/javascripts/environments/constants.js10
-rw-r--r--app/assets/javascripts/environments/graphql/client.js49
-rw-r--r--app/assets/javascripts/environments/graphql/queries/folder.query.graphql4
-rw-r--r--app/assets/javascripts/environments/graphql/resolvers.js17
-rw-r--r--app/assets/javascripts/environments/index.js55
-rw-r--r--app/assets/javascripts/environments/new_index.js38
-rw-r--r--app/assets/javascripts/error_tracking/components/constants.js21
-rw-r--r--app/assets/javascripts/error_tracking/components/error_details.vue2
-rw-r--r--app/assets/javascripts/error_tracking/components/error_tracking_list.vue44
-rw-r--r--app/assets/javascripts/error_tracking/constants.js30
-rw-r--r--app/assets/javascripts/error_tracking/list.js8
-rw-r--r--app/assets/javascripts/error_tracking_settings/components/app.vue64
-rw-r--r--app/assets/javascripts/error_tracking_settings/constants.js7
-rw-r--r--app/assets/javascripts/experimentation/components/gitlab_experiment.vue2
-rw-r--r--app/assets/javascripts/filtered_search/filtered_search_dropdown.js3
-rw-r--r--app/assets/javascripts/gfm_auto_complete.js14
-rw-r--r--app/assets/javascripts/google_cloud/components/app.vue4
-rw-r--r--app/assets/javascripts/google_cloud/components/gcp_regions_form.vue62
-rw-r--r--app/assets/javascripts/google_cloud/components/gcp_regions_list.vue56
-rw-r--r--app/assets/javascripts/google_cloud/components/home.vue25
-rw-r--r--app/assets/javascripts/google_cloud/components/revoke_oauth.vue38
-rw-r--r--app/assets/javascripts/google_cloud/components/service_accounts_form.vue47
-rw-r--r--app/assets/javascripts/google_cloud/components/service_accounts_list.vue18
-rw-r--r--app/assets/javascripts/google_tag_manager/index.js44
-rw-r--r--app/assets/javascripts/gpg_badges.js3
-rw-r--r--app/assets/javascripts/graphql_shared/constants.js2
-rw-r--r--app/assets/javascripts/graphql_shared/possibleTypes.json2
-rw-r--r--app/assets/javascripts/graphql_shared/queries/users_search_with_mr_permissions.graphql24
-rw-r--r--app/assets/javascripts/groups/components/item_stats.vue2
-rw-r--r--app/assets/javascripts/header_search/components/header_search_autocomplete_items.vue18
-rw-r--r--app/assets/javascripts/header_search/components/header_search_default_items.vue4
-rw-r--r--app/assets/javascripts/header_search/index.js4
-rw-r--r--app/assets/javascripts/header_search/store/actions.js3
-rw-r--r--app/assets/javascripts/header_search/store/getters.js34
-rw-r--r--app/assets/javascripts/header_search/store/index.js3
-rw-r--r--app/assets/javascripts/header_search/store/mutations.js4
-rw-r--r--app/assets/javascripts/header_search/store/state.js12
-rw-r--r--app/assets/javascripts/ide/components/file_templates/bar.vue91
-rw-r--r--app/assets/javascripts/ide/components/file_templates/dropdown.vue2
-rw-r--r--app/assets/javascripts/ide/components/new_dropdown/modal.vue24
-rw-r--r--app/assets/javascripts/ide/components/repo_editor.vue12
-rw-r--r--app/assets/javascripts/import_entities/import_projects/components/import_projects_table.vue2
-rw-r--r--app/assets/javascripts/incidents/components/incidents_list.vue57
-rw-r--r--app/assets/javascripts/incidents/constants.js7
-rw-r--r--app/assets/javascripts/incidents/graphql/fragments/incident_fields.fragment.graphql1
-rw-r--r--app/assets/javascripts/incidents/list.js1
-rw-r--r--app/assets/javascripts/integrations/constants.js13
-rw-r--r--app/assets/javascripts/integrations/edit/components/active_checkbox.vue8
-rw-r--r--app/assets/javascripts/integrations/edit/components/integration_form.vue93
-rw-r--r--app/assets/javascripts/integrations/edit/components/jira_issues_fields.vue18
-rw-r--r--app/assets/javascripts/integrations/edit/components/jira_trigger_fields.vue15
-rw-r--r--app/assets/javascripts/integrations/edit/components/sections/connection.vue45
-rw-r--r--app/assets/javascripts/integrations/edit/components/sections/jira_issues.vue33
-rw-r--r--app/assets/javascripts/integrations/edit/components/sections/jira_trigger.vue32
-rw-r--r--app/assets/javascripts/integrations/edit/components/trigger_fields.vue6
-rw-r--r--app/assets/javascripts/integrations/edit/index.js14
-rw-r--r--app/assets/javascripts/integrations/edit/store/getters.js5
-rw-r--r--app/assets/javascripts/invite_members/components/invite_group_trigger.vue7
-rw-r--r--app/assets/javascripts/invite_members/components/invite_groups_modal.vue28
-rw-r--r--app/assets/javascripts/invite_members/components/invite_members_modal.vue34
-rw-r--r--app/assets/javascripts/invite_members/components/invite_modal_base.vue235
-rw-r--r--app/assets/javascripts/invite_members/init_invite_members_form.js7
-rw-r--r--app/assets/javascripts/invite_members/utils/get_invalid_feedback_message.js12
-rw-r--r--app/assets/javascripts/issuable/components/issuable_by_email.vue1
-rw-r--r--app/assets/javascripts/issues/create_merge_request_dropdown.js12
-rw-r--r--app/assets/javascripts/issues/list/components/issues_list_app.vue20
-rw-r--r--app/assets/javascripts/issues/list/constants.js11
-rw-r--r--app/assets/javascripts/issues/list/queries/get_issues.query.graphql3
-rw-r--r--app/assets/javascripts/issues/list/queries/get_issues_counts.query.graphql7
-rw-r--r--app/assets/javascripts/issues/list/queries/search_users.query.graphql4
-rw-r--r--app/assets/javascripts/issues/list/utils.js11
-rw-r--r--app/assets/javascripts/issues/show/components/delete_issue_modal.vue5
-rw-r--r--app/assets/javascripts/issues/show/components/description.vue41
-rw-r--r--app/assets/javascripts/issues/show/components/fields/description_template.vue5
-rw-r--r--app/assets/javascripts/issues/show/components/header_actions.vue16
-rw-r--r--app/assets/javascripts/issues/show/components/incidents/incident_tabs.vue8
-rw-r--r--app/assets/javascripts/issues/show/components/title.vue4
-rw-r--r--app/assets/javascripts/issues/show/index.js4
-rw-r--r--app/assets/javascripts/jira_connect/subscriptions/components/app.vue26
-rw-r--r--app/assets/javascripts/jira_connect/subscriptions/components/sign_in_button.vue40
-rw-r--r--app/assets/javascripts/jira_connect/subscriptions/components/sign_in_legacy_button.vue40
-rw-r--r--app/assets/javascripts/jira_connect/subscriptions/components/sign_in_oauth_button.vue124
-rw-r--r--app/assets/javascripts/jira_connect/subscriptions/components/user_link.vue23
-rw-r--r--app/assets/javascripts/jira_connect/subscriptions/constants.js21
-rw-r--r--app/assets/javascripts/jira_connect/subscriptions/index.js10
-rw-r--r--app/assets/javascripts/jira_connect/subscriptions/pages/sign_in.vue39
-rw-r--r--app/assets/javascripts/jira_connect/subscriptions/pkce.js60
-rw-r--r--app/assets/javascripts/jobs/components/job_app.vue17
-rw-r--r--app/assets/javascripts/jobs/components/job_log_controllers.vue20
-rw-r--r--app/assets/javascripts/jobs/components/job_sidebar_retry_button.vue22
-rw-r--r--app/assets/javascripts/jobs/components/log/line_header.vue2
-rw-r--r--app/assets/javascripts/jobs/components/sidebar.vue38
-rw-r--r--app/assets/javascripts/jobs/components/stages_dropdown.vue129
-rw-r--r--app/assets/javascripts/jobs/components/table/constants.js10
-rw-r--r--app/assets/javascripts/jobs/components/table/graphql/cache_config.js30
-rw-r--r--app/assets/javascripts/jobs/components/table/graphql/queries/get_jobs.query.graphql15
-rw-r--r--app/assets/javascripts/jobs/components/table/index.js8
-rw-r--r--app/assets/javascripts/jobs/components/table/jobs_table_app.vue67
-rw-r--r--app/assets/javascripts/jobs/index.js2
-rw-r--r--app/assets/javascripts/lib/utils/accessor.js8
-rw-r--r--app/assets/javascripts/lib/utils/array_utility.js10
-rw-r--r--app/assets/javascripts/lib/utils/common_utils.js13
-rw-r--r--app/assets/javascripts/lib/utils/ignore_while_pending.js26
-rw-r--r--app/assets/javascripts/lib/utils/rails_ujs.js5
-rw-r--r--app/assets/javascripts/lib/utils/resize_observer.js22
-rw-r--r--app/assets/javascripts/lib/utils/text_markdown.js54
-rw-r--r--app/assets/javascripts/lib/utils/url_utility.js14
-rw-r--r--app/assets/javascripts/loading_icon_for_legacy_js.js53
-rw-r--r--app/assets/javascripts/main.js18
-rw-r--r--app/assets/javascripts/member_expiration_date.js54
-rw-r--r--app/assets/javascripts/members/components/action_buttons/remove_member_button.vue3
-rw-r--r--app/assets/javascripts/members/components/action_buttons/user_action_buttons.vue3
-rw-r--r--app/assets/javascripts/members/components/filter_sort/members_filtered_search_bar.vue41
-rw-r--r--app/assets/javascripts/members/constants.js37
-rw-r--r--app/assets/javascripts/members/index.js2
-rw-r--r--app/assets/javascripts/merge_conflicts/merge_conflict_resolver_app.vue7
-rw-r--r--app/assets/javascripts/merge_request_tabs.js247
-rw-r--r--app/assets/javascripts/monitoring/components/charts/bar.vue34
-rw-r--r--app/assets/javascripts/monitoring/components/charts/column.vue34
-rw-r--r--app/assets/javascripts/monitoring/components/charts/gauge.vue36
-rw-r--r--app/assets/javascripts/monitoring/components/charts/heatmap.vue34
-rw-r--r--app/assets/javascripts/monitoring/components/charts/stacked_column.vue46
-rw-r--r--app/assets/javascripts/monitoring/components/charts/time_series.vue103
-rw-r--r--app/assets/javascripts/notes/components/discussion_filter.vue2
-rw-r--r--app/assets/javascripts/notes/components/note_header.vue13
-rw-r--r--app/assets/javascripts/notes/components/noteable_discussion.vue5
-rw-r--r--app/assets/javascripts/notes/components/noteable_note.vue8
-rw-r--r--app/assets/javascripts/packages_and_registries/container_registry/explorer/components/details_page/delete_alert.vue14
-rw-r--r--app/assets/javascripts/packages_and_registries/container_registry/explorer/components/details_page/details_header.vue14
-rw-r--r--app/assets/javascripts/packages_and_registries/container_registry/explorer/constants/details.js6
-rw-r--r--app/assets/javascripts/packages_and_registries/container_registry/explorer/graphql/queries/get_container_repository_metadata.query.graphql7
-rw-r--r--app/assets/javascripts/packages_and_registries/container_registry/explorer/graphql/queries/get_container_repository_tags_count.query.graphql6
-rw-r--r--app/assets/javascripts/packages_and_registries/container_registry/explorer/pages/details.vue13
-rw-r--r--app/assets/javascripts/packages_and_registries/container_registry/explorer/pages/list.vue66
-rw-r--r--app/assets/javascripts/packages_and_registries/settings/project/components/settings_form.vue17
-rw-r--r--app/assets/javascripts/packages_and_registries/settings/project/constants.js1
-rw-r--r--app/assets/javascripts/packages_and_registries/settings/project/graphql/utils/cache_update.js1
-rw-r--r--app/assets/javascripts/pages/admin/applications/index.js3
-rw-r--r--app/assets/javascripts/pages/admin/clusters/connect/index.js (renamed from app/assets/javascripts/pages/admin/clusters/new/index.js)0
-rw-r--r--app/assets/javascripts/pages/admin/topics/edit/index.js3
-rw-r--r--app/assets/javascripts/pages/dashboard/todos/index/todos.js8
-rw-r--r--app/assets/javascripts/pages/groups/clusters/connect/index.js (renamed from app/assets/javascripts/pages/groups/clusters/new/index.js)0
-rw-r--r--app/assets/javascripts/pages/groups/group_members/index.js15
-rw-r--r--app/assets/javascripts/pages/jira_connect/oauth_callbacks/index.js28
-rw-r--r--app/assets/javascripts/pages/projects/blob/show/index.js6
-rw-r--r--app/assets/javascripts/pages/projects/branches/index/index.js3
-rw-r--r--app/assets/javascripts/pages/projects/ci/secure_files/show/index.js3
-rw-r--r--app/assets/javascripts/pages/projects/clusters/connect/index.js (renamed from app/assets/javascripts/pages/projects/clusters/new/index.js)0
-rw-r--r--app/assets/javascripts/pages/projects/environments/index/index.js12
-rw-r--r--app/assets/javascripts/pages/projects/forks/new/components/app.vue43
-rw-r--r--app/assets/javascripts/pages/projects/forks/new/components/fork_form.vue25
-rw-r--r--app/assets/javascripts/pages/projects/forks/new/components/fork_groups_list.vue93
-rw-r--r--app/assets/javascripts/pages/projects/forks/new/components/fork_groups_list_item.vue148
-rw-r--r--app/assets/javascripts/pages/projects/forks/new/index.js79
-rw-r--r--app/assets/javascripts/pages/projects/learn_gitlab/components/learn_gitlab.vue7
-rw-r--r--app/assets/javascripts/pages/projects/learn_gitlab/components/learn_gitlab_info_card.vue10
-rw-r--r--app/assets/javascripts/pages/projects/learn_gitlab/components/learn_gitlab_section_link.vue4
-rw-r--r--app/assets/javascripts/pages/projects/learn_gitlab/constants/index.js1
-rw-r--r--app/assets/javascripts/pages/projects/learn_gitlab/index/index.js5
-rw-r--r--app/assets/javascripts/pages/projects/pages_domains/form.js15
-rw-r--r--app/assets/javascripts/pages/projects/pipeline_schedules/shared/components/target_branch_dropdown.js54
-rw-r--r--app/assets/javascripts/pages/projects/pipeline_schedules/shared/init_form.js53
-rw-r--r--app/assets/javascripts/pages/projects/project_members/index.js13
-rw-r--r--app/assets/javascripts/pages/shared/wikis/components/wiki_form.vue3
-rw-r--r--app/assets/javascripts/pages/users/activity_calendar.js11
-rw-r--r--app/assets/javascripts/performance_bar/components/detailed_metric.vue21
-rw-r--r--app/assets/javascripts/performance_bar/components/performance_bar_app.vue1
-rw-r--r--app/assets/javascripts/performance_bar/components/request_selector.vue38
-rw-r--r--app/assets/javascripts/performance_bar/constants.js14
-rw-r--r--app/assets/javascripts/performance_bar/index.js41
-rw-r--r--app/assets/javascripts/performance_bar/stores/performance_bar_store.js2
-rw-r--r--app/assets/javascripts/persistent_user_callout.js19
-rw-r--r--app/assets/javascripts/persistent_user_callouts.js1
-rw-r--r--app/assets/javascripts/pipeline_editor/components/commit/commit_form.vue18
-rw-r--r--app/assets/javascripts/pipeline_editor/components/commit/commit_section.vue6
-rw-r--r--app/assets/javascripts/pipeline_editor/components/drawer/pipeline_editor_drawer.vue22
-rw-r--r--app/assets/javascripts/pipeline_editor/components/editor/text_editor.vue3
-rw-r--r--app/assets/javascripts/pipeline_editor/components/pipeline_editor_tabs.vue8
-rw-r--r--app/assets/javascripts/pipeline_editor/components/ui/pipeline_editor_empty_state.vue7
-rw-r--r--app/assets/javascripts/pipeline_editor/constants.js45
-rw-r--r--app/assets/javascripts/pipeline_editor/index.js6
-rw-r--r--app/assets/javascripts/pipeline_editor/pipeline_editor_app.vue25
-rw-r--r--app/assets/javascripts/pipeline_editor/pipeline_editor_home.vue1
-rw-r--r--app/assets/javascripts/pipeline_wizard/components/commit.vue4
-rw-r--r--app/assets/javascripts/pipeline_wizard/components/input.vue99
-rw-r--r--app/assets/javascripts/pipeline_wizard/components/step.vue149
-rw-r--r--app/assets/javascripts/pipeline_wizard/components/widgets/list.vue195
-rw-r--r--app/assets/javascripts/pipeline_wizard/components/wrapper.vue185
-rw-r--r--app/assets/javascripts/pipeline_wizard/pipeline_wizard.vue65
-rw-r--r--app/assets/javascripts/pipeline_wizard/validators.js4
-rw-r--r--app/assets/javascripts/pipelines/components/header_component.vue4
-rw-r--r--app/assets/javascripts/pipelines/components/jobs/jobs_app.vue15
-rw-r--r--app/assets/javascripts/pipelines/components/pipelines_list/empty_state.vue100
-rw-r--r--app/assets/javascripts/pipelines/components/pipelines_list/pipeline_labels.vue170
-rw-r--r--app/assets/javascripts/pipelines/components/pipelines_list/pipeline_url.vue267
-rw-r--r--app/assets/javascripts/pipelines/components/pipelines_list/pipelines.vue16
-rw-r--r--app/assets/javascripts/pipelines/components/pipelines_list/pipelines_ci_templates.vue226
-rw-r--r--app/assets/javascripts/pipelines/components/pipelines_list/pipelines_commit.vue85
-rw-r--r--app/assets/javascripts/pipelines/components/pipelines_list/pipelines_filtered_search.vue6
-rw-r--r--app/assets/javascripts/pipelines/components/pipelines_list/pipelines_status_badge.vue30
-rw-r--r--app/assets/javascripts/pipelines/components/pipelines_list/pipelines_table.vue128
-rw-r--r--app/assets/javascripts/pipelines/components/pipelines_list/time_ago.vue8
-rw-r--r--app/assets/javascripts/pipelines/components/pipelines_list/tokens/pipeline_branch_name_token.vue7
-rw-r--r--app/assets/javascripts/pipelines/pipeline_details_bundle.js4
-rw-r--r--app/assets/javascripts/pipelines/pipelines_index.js6
-rw-r--r--app/assets/javascripts/profile/profile.js4
-rw-r--r--app/assets/javascripts/projects/pipelines/charts/index.js9
-rw-r--r--app/assets/javascripts/projects/project_new.js13
-rw-r--r--app/assets/javascripts/protected_branches/protected_branch_create.js24
-rw-r--r--app/assets/javascripts/protected_branches/protected_branch_edit.js66
-rw-r--r--app/assets/javascripts/ref/components/ref_selector.vue27
-rw-r--r--app/assets/javascripts/ref/stores/actions.js3
-rw-r--r--app/assets/javascripts/ref/stores/mutation_types.js1
-rw-r--r--app/assets/javascripts/ref/stores/mutations.js5
-rw-r--r--app/assets/javascripts/related_issues/components/related_issues_block.vue13
-rw-r--r--app/assets/javascripts/related_issues/components/related_issues_list.vue7
-rw-r--r--app/assets/javascripts/related_issues/components/related_issues_root.vue12
-rw-r--r--app/assets/javascripts/related_issues/index.js1
-rw-r--r--app/assets/javascripts/releases/components/app_index.vue2
-rw-r--r--app/assets/javascripts/releases/components/asset_links_form.vue12
-rw-r--r--app/assets/javascripts/releases/stores/modules/edit_new/actions.js2
-rw-r--r--app/assets/javascripts/releases/stores/modules/edit_new/getters.js14
-rw-r--r--app/assets/javascripts/reports/codequality_report/constants.js14
-rw-r--r--app/assets/javascripts/reports/constants.js1
-rw-r--r--app/assets/javascripts/repository/components/blob_button_group.vue14
-rw-r--r--app/assets/javascripts/repository/components/blob_content_viewer.vue77
-rw-r--r--app/assets/javascripts/repository/components/blob_edit.vue78
-rw-r--r--app/assets/javascripts/repository/components/blob_viewers/audio_viewer.vue20
-rw-r--r--app/assets/javascripts/repository/components/blob_viewers/csv_viewer.vue26
-rw-r--r--app/assets/javascripts/repository/components/blob_viewers/download_viewer.vue2
-rw-r--r--app/assets/javascripts/repository/components/blob_viewers/image_viewer.vue2
-rw-r--r--app/assets/javascripts/repository/components/blob_viewers/index.js2
-rw-r--r--app/assets/javascripts/repository/components/blob_viewers/lfs_viewer.vue2
-rw-r--r--app/assets/javascripts/repository/components/blob_viewers/pdf_viewer.vue2
-rw-r--r--app/assets/javascripts/repository/components/breadcrumbs.vue13
-rw-r--r--app/assets/javascripts/repository/components/delete_blob_modal.vue2
-rw-r--r--app/assets/javascripts/repository/constants.js10
-rw-r--r--app/assets/javascripts/repository/index.js4
-rw-r--r--app/assets/javascripts/repository/queries/application_info.query.graphql3
-rw-r--r--app/assets/javascripts/repository/queries/blob_info.query.graphql4
-rw-r--r--app/assets/javascripts/repository/queries/user_info.query.graphql8
-rw-r--r--app/assets/javascripts/runner/admin_runner_edit/admin_runner_edit_app.vue4
-rw-r--r--app/assets/javascripts/runner/admin_runner_show/admin_runner_show_app.vue4
-rw-r--r--app/assets/javascripts/runner/admin_runners/admin_runners_app.vue22
-rw-r--r--app/assets/javascripts/runner/components/cells/runner_actions_cell.vue118
-rw-r--r--app/assets/javascripts/runner/components/registration/registration_token_reset_dropdown_item.vue9
-rw-r--r--app/assets/javascripts/runner/components/runner_delete_button.vue144
-rw-r--r--app/assets/javascripts/runner/components/runner_edit_button.vue4
-rw-r--r--app/assets/javascripts/runner/components/runner_jobs.vue11
-rw-r--r--app/assets/javascripts/runner/components/runner_list.vue33
-rw-r--r--app/assets/javascripts/runner/components/runner_pause_button.vue20
-rw-r--r--app/assets/javascripts/runner/components/runner_paused_badge.vue12
-rw-r--r--app/assets/javascripts/runner/components/runner_projects.vue12
-rw-r--r--app/assets/javascripts/runner/components/runner_update_form.vue9
-rw-r--r--app/assets/javascripts/runner/constants.js16
-rw-r--r--app/assets/javascripts/runner/graphql/details/runner.query.graphql9
-rw-r--r--app/assets/javascripts/runner/graphql/details/runner_details.fragment.graphql (renamed from app/assets/javascripts/runner/graphql/runner_details.fragment.graphql)0
-rw-r--r--app/assets/javascripts/runner/graphql/details/runner_details_shared.fragment.graphql35
-rw-r--r--app/assets/javascripts/runner/graphql/details/runner_jobs.query.graphql (renamed from app/assets/javascripts/runner/graphql/get_runner_jobs.query.graphql)0
-rw-r--r--app/assets/javascripts/runner/graphql/details/runner_projects.query.graphql (renamed from app/assets/javascripts/runner/graphql/get_runner_projects.query.graphql)0
-rw-r--r--app/assets/javascripts/runner/graphql/details/runner_update.mutation.graphql15
-rw-r--r--app/assets/javascripts/runner/graphql/get_group_runners.query.graphql41
-rw-r--r--app/assets/javascripts/runner/graphql/get_runner.query.graphql10
-rw-r--r--app/assets/javascripts/runner/graphql/get_runners.query.graphql36
-rw-r--r--app/assets/javascripts/runner/graphql/list/admin_runners.query.graphql36
-rw-r--r--app/assets/javascripts/runner/graphql/list/admin_runners_count.query.graphql (renamed from app/assets/javascripts/runner/graphql/get_runners_count.query.graphql)0
-rw-r--r--app/assets/javascripts/runner/graphql/list/group_runners.query.graphql41
-rw-r--r--app/assets/javascripts/runner/graphql/list/group_runners_count.query.graphql (renamed from app/assets/javascripts/runner/graphql/get_group_runners_count.query.graphql)0
-rw-r--r--app/assets/javascripts/runner/graphql/list/list_item.fragment.graphql20
-rw-r--r--app/assets/javascripts/runner/graphql/list/runners_registration_token_reset.mutation.graphql (renamed from app/assets/javascripts/runner/graphql/runners_registration_token_reset.mutation.graphql)0
-rw-r--r--app/assets/javascripts/runner/graphql/runner_details_shared.fragment.graphql34
-rw-r--r--app/assets/javascripts/runner/graphql/runner_node.fragment.graphql20
-rw-r--r--app/assets/javascripts/runner/graphql/runner_update.mutation.graphql15
-rw-r--r--app/assets/javascripts/runner/graphql/shared/runner_delete.mutation.graphql (renamed from app/assets/javascripts/runner/graphql/runner_delete.mutation.graphql)0
-rw-r--r--app/assets/javascripts/runner/graphql/shared/runner_toggle_active.mutation.graphql (renamed from app/assets/javascripts/runner/graphql/runner_toggle_active.mutation.graphql)0
-rw-r--r--app/assets/javascripts/runner/group_runners/group_runners_app.vue57
-rw-r--r--app/assets/javascripts/search/topbar/components/app.vue55
-rw-r--r--app/assets/javascripts/security_configuration/components/constants.js34
-rw-r--r--app/assets/javascripts/security_configuration/components/feature_card.vue5
-rw-r--r--app/assets/javascripts/security_configuration/components/training_provider_list.vue139
-rw-r--r--app/assets/javascripts/security_configuration/constants.js6
-rw-r--r--app/assets/javascripts/security_configuration/graphql/cache_utils.js40
-rw-r--r--app/assets/javascripts/security_configuration/graphql/security_training_vulnerability.query.graphql10
-rw-r--r--app/assets/javascripts/sidebar/components/assignees/assignee_avatar.vue6
-rw-r--r--app/assets/javascripts/sidebar/components/assignees/assignee_avatar_link.vue4
-rw-r--r--app/assets/javascripts/sidebar/components/assignees/collapsed_assignee_list.vue6
-rw-r--r--app/assets/javascripts/sidebar/components/assignees/issuable_assignees.vue4
-rw-r--r--app/assets/javascripts/sidebar/components/assignees/sidebar_assignees.vue2
-rw-r--r--app/assets/javascripts/sidebar/components/assignees/sidebar_assignees_widget.vue20
-rw-r--r--app/assets/javascripts/sidebar/components/assignees/sidebar_invite_members.vue2
-rw-r--r--app/assets/javascripts/sidebar/components/assignees/sidebar_participant.vue28
-rw-r--r--app/assets/javascripts/sidebar/components/assignees/uncollapsed_assignee_list.vue2
-rw-r--r--app/assets/javascripts/sidebar/components/attention_requested_toggle.vue26
-rw-r--r--app/assets/javascripts/sidebar/components/incidents/constants.js25
-rw-r--r--app/assets/javascripts/sidebar/components/incidents/escalation_status.vue61
-rw-r--r--app/assets/javascripts/sidebar/components/incidents/sidebar_escalation_status.vue135
-rw-r--r--app/assets/javascripts/sidebar/components/incidents/utils.js5
-rw-r--r--app/assets/javascripts/sidebar/components/reviewers/uncollapsed_reviewer_list.vue2
-rw-r--r--app/assets/javascripts/sidebar/components/severity/severity.vue8
-rw-r--r--app/assets/javascripts/sidebar/constants.js19
-rw-r--r--app/assets/javascripts/sidebar/mount_sidebar.js57
-rw-r--r--app/assets/javascripts/sidebar/queries/escalation_status.query.graphql9
-rw-r--r--app/assets/javascripts/sidebar/queries/update_escalation_status.mutation.graphql10
-rw-r--r--app/assets/javascripts/sidebar/sidebar_bundle.js12
-rw-r--r--app/assets/javascripts/sidebar/sidebar_mediator.js2
-rw-r--r--app/assets/javascripts/single_file_diff.js3
-rw-r--r--app/assets/javascripts/terraform/components/empty_state.vue2
-rw-r--r--app/assets/javascripts/toggle_buttons.js63
-rw-r--r--app/assets/javascripts/toggles/index.js20
-rw-r--r--app/assets/javascripts/tracking/dispatch_snowplow_event.js7
-rw-r--r--app/assets/javascripts/tracking/tracking.js6
-rw-r--r--app/assets/javascripts/users_select/index.js6
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/extensions/base.vue95
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/extensions/child_content.vue95
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/mr_collapsible_extension.vue8
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/mr_widget_how_to_merge_modal.vue30
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/mr_widget_related_links.vue31
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/commit_message_dropdown.vue4
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/commits_header.vue2
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_conflicts.vue13
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_rebase.vue48
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/states/ready_to_merge.vue40
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/constants.js3
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/extensions/code_quality/index.js123
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/extensions/issues.js10
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/mixins/ready_to_merge.js11
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue21
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/queries/states/ready_to_merge.fragment.graphql2
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js10
-rw-r--r--app/assets/javascripts/vue_shared/components/awards_list.vue3
-rw-r--r--app/assets/javascripts/vue_shared/components/color_picker/color_picker.vue9
-rw-r--r--app/assets/javascripts/vue_shared/components/content_transition.vue32
-rw-r--r--app/assets/javascripts/vue_shared/components/dropdown/dropdown_widget/dropdown_widget.vue56
-rw-r--r--app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/base_token.vue33
-rw-r--r--app/assets/javascripts/vue_shared/components/markdown/field.vue24
-rw-r--r--app/assets/javascripts/vue_shared/components/markdown/header.vue25
-rw-r--r--app/assets/javascripts/vue_shared/components/notes/noteable_warning.vue42
-rw-r--r--app/assets/javascripts/vue_shared/components/runner_aws_deployments/constants.js22
-rw-r--r--app/assets/javascripts/vue_shared/components/runner_aws_deployments/runner_aws_deployments_modal.vue112
-rw-r--r--app/assets/javascripts/vue_shared/components/sidebar/queries/get_mr_assignees.query.graphql6
-rw-r--r--app/assets/javascripts/vue_shared/components/sidebar/queries/update_mr_assignees.mutation.graphql13
-rw-r--r--app/assets/javascripts/vue_shared/components/source_editor.vue9
-rw-r--r--app/assets/javascripts/vue_shared/components/source_viewer/source_viewer.vue12
-rw-r--r--app/assets/javascripts/vue_shared/components/source_viewer/utils.js10
-rw-r--r--app/assets/javascripts/vue_shared/components/user_avatar/user_avatar_image.vue80
-rw-r--r--app/assets/javascripts/vue_shared/components/user_avatar/user_avatar_image_new.vue106
-rw-r--r--app/assets/javascripts/vue_shared/components/user_avatar/user_avatar_image_old.vue110
-rw-r--r--app/assets/javascripts/vue_shared/components/user_avatar/user_avatar_link.vue54
-rw-r--r--app/assets/javascripts/vue_shared/components/user_avatar/user_avatar_link_new.vue117
-rw-r--r--app/assets/javascripts/vue_shared/components/user_avatar/user_avatar_link_old.vue117
-rw-r--r--app/assets/javascripts/vue_shared/components/user_popover/user_popover.vue2
-rw-r--r--app/assets/javascripts/vue_shared/components/user_select/user_select.vue126
-rw-r--r--app/assets/javascripts/vue_shared/components/web_ide_link.vue44
-rw-r--r--app/assets/javascripts/vue_shared/issuable/show/components/issuable_title.vue7
-rw-r--r--app/assets/javascripts/webpack_non_compiled_placeholder.js15
-rw-r--r--app/assets/javascripts/work_items/components/work_item_detail_modal.vue62
-rw-r--r--app/assets/javascripts/work_items/graphql/create_work_item.mutation.graphql14
-rw-r--r--app/assets/javascripts/work_items/graphql/provider.js23
-rw-r--r--app/assets/javascripts/work_items/graphql/resolvers.js43
-rw-r--r--app/assets/javascripts/work_items/graphql/typedefs.graphql8
-rw-r--r--app/assets/javascripts/work_items/graphql/update_work_item.mutation.graphql14
-rw-r--r--app/assets/javascripts/work_items/graphql/work_item.query.graphql12
-rw-r--r--app/assets/javascripts/work_items/pages/create_work_item.vue34
-rw-r--r--app/assets/javascripts/work_items/pages/work_item_root.vue36
-rw-r--r--app/assets/stylesheets/framework/contextual_sidebar.scss17
-rw-r--r--app/assets/stylesheets/framework/files.scss4
-rw-r--r--app/assets/stylesheets/framework/highlight.scss2
-rw-r--r--app/assets/stylesheets/framework/mixins.scss6
-rw-r--r--app/assets/stylesheets/framework/typography.scss4
-rw-r--r--app/assets/stylesheets/notify.scss29
-rw-r--r--app/assets/stylesheets/notify_base.scss25
-rw-r--r--app/assets/stylesheets/notify_enhanced.scss68
-rw-r--r--app/assets/stylesheets/page_bundles/merge_requests.scss8
-rw-r--r--app/assets/stylesheets/pages/issuable.scss9
-rw-r--r--app/assets/stylesheets/pages/projects.scss41
-rw-r--r--app/assets/stylesheets/pages/search.scss23
-rw-r--r--app/assets/stylesheets/startup/startup-dark.scss35
-rw-r--r--app/assets/stylesheets/startup/startup-general.scss26
-rw-r--r--app/assets/stylesheets/startup/startup-signin.scss13
-rw-r--r--app/assets/stylesheets/themes/_dark.scss1
-rw-r--r--app/assets/stylesheets/themes/theme_helper.scss9
-rw-r--r--app/assets/stylesheets/utilities.scss28
-rw-r--r--app/components/pajamas/component.rb23
-rw-r--r--app/components/pajamas/toggle_component.html.haml16
-rw-r--r--app/components/pajamas/toggle_component.rb34
-rw-r--r--app/controllers/admin/application_settings_controller.rb9
-rw-r--r--app/controllers/admin/broadcast_messages_controller.rb2
-rw-r--r--app/controllers/admin/clusters_controller.rb1
-rw-r--r--app/controllers/admin/cohorts_controller.rb2
-rw-r--r--app/controllers/admin/dev_ops_report_controller.rb2
-rw-r--r--app/controllers/admin/instance_review_controller.rb2
-rw-r--r--app/controllers/admin/integrations_controller.rb4
-rw-r--r--app/controllers/admin/runner_projects_controller.rb5
-rw-r--r--app/controllers/admin/runners_controller.rb8
-rw-r--r--app/controllers/admin/usage_trends_controller.rb2
-rw-r--r--app/controllers/admin/users_controller.rb4
-rw-r--r--app/controllers/application_controller.rb15
-rw-r--r--app/controllers/autocomplete_controller.rb10
-rw-r--r--app/controllers/clusters/clusters_controller.rb26
-rw-r--r--app/controllers/concerns/floc_opt_out.rb2
-rw-r--r--app/controllers/concerns/issuable_actions.rb14
-rw-r--r--app/controllers/concerns/issuable_collections_action.rb2
-rw-r--r--app/controllers/concerns/membership_actions.rb15
-rw-r--r--app/controllers/concerns/product_analytics_tracking.rb27
-rw-r--r--app/controllers/concerns/search_rate_limitable.rb15
-rw-r--r--app/controllers/concerns/sessionless_authentication.rb3
-rw-r--r--app/controllers/concerns/spammable_actions/akismet_mark_as_spam_action.rb11
-rw-r--r--app/controllers/concerns/spammable_actions/attributes.rb13
-rw-r--r--app/controllers/concerns/spammable_actions/captcha_check/common.rb32
-rw-r--r--app/controllers/concerns/spammable_actions/captcha_check/html_format_actions_support.rb5
-rw-r--r--app/controllers/concerns/spammable_actions/captcha_check/json_format_actions_support.rb11
-rw-r--r--app/controllers/concerns/spammable_actions/captcha_check/rest_api_actions_support.rb39
-rw-r--r--app/controllers/concerns/uploads_actions.rb2
-rw-r--r--app/controllers/dashboard/projects_controller.rb2
-rw-r--r--app/controllers/dashboard_controller.rb15
-rw-r--r--app/controllers/groups/application_controller.rb4
-rw-r--r--app/controllers/groups/boards_controller.rb1
-rw-r--r--app/controllers/groups/clusters_controller.rb1
-rw-r--r--app/controllers/groups/crm/contacts_controller.rb1
-rw-r--r--app/controllers/groups/crm/organizations_controller.rb1
-rw-r--r--app/controllers/groups/deploy_tokens_controller.rb3
-rw-r--r--app/controllers/groups/group_members_controller.rb6
-rw-r--r--app/controllers/groups/harbor/repositories_controller.rb24
-rw-r--r--app/controllers/groups/releases_controller.rb16
-rw-r--r--app/controllers/groups/runners_controller.rb14
-rw-r--r--app/controllers/groups/settings/ci_cd_controller.rb2
-rw-r--r--app/controllers/groups/settings/integrations_controller.rb4
-rw-r--r--app/controllers/groups/uploads_controller.rb2
-rw-r--r--app/controllers/groups_controller.rb4
-rw-r--r--app/controllers/jira_connect/events_controller.rb30
-rw-r--r--app/controllers/jira_connect/oauth_callbacks_controller.rb11
-rw-r--r--app/controllers/jira_connect/subscriptions_controller.rb4
-rw-r--r--app/controllers/profiles_controller.rb2
-rw-r--r--app/controllers/projects/application_controller.rb7
-rw-r--r--app/controllers/projects/blob_controller.rb18
-rw-r--r--app/controllers/projects/boards_controller.rb1
-rw-r--r--app/controllers/projects/builds_controller.rb3
-rw-r--r--app/controllers/projects/ci/pipeline_editor_controller.rb8
-rw-r--r--app/controllers/projects/ci/secure_files_controller.rb10
-rw-r--r--app/controllers/projects/cluster_agents_controller.rb4
-rw-r--r--app/controllers/projects/commit_controller.rb1
-rw-r--r--app/controllers/projects/commits_controller.rb2
-rw-r--r--app/controllers/projects/deploy_tokens_controller.rb2
-rw-r--r--app/controllers/projects/environments_controller.rb12
-rw-r--r--app/controllers/projects/error_tracking_controller.rb8
-rw-r--r--app/controllers/projects/forks_controller.rb8
-rw-r--r--app/controllers/projects/google_cloud/base_controller.rb27
-rw-r--r--app/controllers/projects/google_cloud/deployments_controller.rb5
-rw-r--r--app/controllers/projects/google_cloud/gcp_regions_controller.rb31
-rw-r--r--app/controllers/projects/google_cloud/revoke_oauth_controller.rb23
-rw-r--r--app/controllers/projects/google_cloud/service_accounts_controller.rb25
-rw-r--r--app/controllers/projects/google_cloud_controller.rb26
-rw-r--r--app/controllers/projects/harbor/application_controller.rb22
-rw-r--r--app/controllers/projects/harbor/repositories_controller.rb11
-rw-r--r--app/controllers/projects/incidents_controller.rb7
-rw-r--r--app/controllers/projects/issues_controller.rb30
-rw-r--r--app/controllers/projects/jobs_controller.rb2
-rw-r--r--app/controllers/projects/merge_requests/diffs_controller.rb4
-rw-r--r--app/controllers/projects/merge_requests_controller.rb21
-rw-r--r--app/controllers/projects/pipeline_schedules_controller.rb4
-rw-r--r--app/controllers/projects/pipelines/stages_controller.rb4
-rw-r--r--app/controllers/projects/pipelines/tests_controller.rb4
-rw-r--r--app/controllers/projects/pipelines_controller.rb58
-rw-r--r--app/controllers/projects/project_members_controller.rb21
-rw-r--r--app/controllers/projects/redirect_controller.rb20
-rw-r--r--app/controllers/projects/releases_controller.rb33
-rw-r--r--app/controllers/projects/runner_projects_controller.rb5
-rw-r--r--app/controllers/projects/runners_controller.rb8
-rw-r--r--app/controllers/projects/serverless/functions_controller.rb5
-rw-r--r--app/controllers/projects/services_controller.rb4
-rw-r--r--app/controllers/projects/settings/ci_cd_controller.rb2
-rw-r--r--app/controllers/projects/settings/operations_controller.rb4
-rw-r--r--app/controllers/projects/tags_controller.rb2
-rw-r--r--app/controllers/projects/tree_controller.rb1
-rw-r--r--app/controllers/projects_controller.rb27
-rw-r--r--app/controllers/registrations_controller.rb2
-rw-r--r--app/controllers/search_controller.rb10
-rw-r--r--app/controllers/uploads_controller.rb45
-rw-r--r--app/controllers/users_controller.rb4
-rw-r--r--app/events/repositories/keep_around_refs_created_event.rb14
-rw-r--r--app/experiments/application_experiment.rb14
-rw-r--r--app/experiments/combined_registration_experiment.rb11
-rw-r--r--app/experiments/in_product_guidance_environments_webide_experiment.rb6
-rw-r--r--app/experiments/new_project_sast_enabled_experiment.rb20
-rw-r--r--app/experiments/require_verification_for_namespace_creation_experiment.rb11
-rw-r--r--app/experiments/security_reports_mr_widget_prompt_experiment.rb8
-rw-r--r--app/finders/admin/projects_finder.rb2
-rw-r--r--app/finders/group_members_finder.rb7
-rw-r--r--app/finders/issuable_finder.rb10
-rw-r--r--app/finders/pending_todos_finder.rb9
-rw-r--r--app/finders/personal_access_tokens_finder.rb10
-rw-r--r--app/finders/projects/members/effective_access_level_finder.rb8
-rw-r--r--app/finders/projects/topics_finder.rb2
-rw-r--r--app/finders/releases/group_releases_finder.rb74
-rw-r--r--app/graphql/mutations/ci/pipeline/retry.rb5
-rw-r--r--app/graphql/mutations/ci/runner/delete.rb11
-rw-r--r--app/graphql/mutations/ci/runner/update.rb2
-rw-r--r--app/graphql/mutations/ci/runners_registration_token/reset.rb13
-rw-r--r--app/graphql/mutations/concerns/mutations/spam_protection.rb26
-rw-r--r--app/graphql/mutations/notes/base.rb6
-rw-r--r--app/graphql/mutations/notes/create/note.rb9
-rw-r--r--app/graphql/mutations/notes/update/base.rb6
-rw-r--r--app/graphql/mutations/saved_replies/base.rb39
-rw-r--r--app/graphql/mutations/saved_replies/create.rb26
-rw-r--r--app/graphql/mutations/saved_replies/update.rb31
-rw-r--r--app/graphql/mutations/work_items/create.rb2
-rw-r--r--app/graphql/mutations/work_items/create_from_task.rb64
-rw-r--r--app/graphql/mutations/work_items/delete.rb2
-rw-r--r--app/graphql/mutations/work_items/update.rb2
-rw-r--r--app/graphql/queries/burndown_chart/burnup.query.graphql9
-rw-r--r--app/graphql/resolvers/blobs_resolver.rb9
-rw-r--r--app/graphql/resolvers/ci/config_resolver.rb2
-rw-r--r--app/graphql/resolvers/concerns/group_issuable_resolver.rb23
-rw-r--r--app/graphql/resolvers/concerns/resolves_merge_requests.rb3
-rw-r--r--app/graphql/resolvers/concerns/resolves_pipelines.rb13
-rw-r--r--app/graphql/resolvers/group_issues_resolver.rb6
-rw-r--r--app/graphql/resolvers/group_members/notification_email_resolver.rb29
-rw-r--r--app/graphql/resolvers/group_merge_requests_resolver.rb5
-rw-r--r--app/graphql/resolvers/topics_resolver.rb4
-rw-r--r--app/graphql/resolvers/work_item_resolver.rb29
-rw-r--r--app/graphql/resolvers/work_items/types_resolver.rb14
-rw-r--r--app/graphql/types/alert_management/alert_type.rb7
-rw-r--r--app/graphql/types/base_enum.rb3
-rw-r--r--app/graphql/types/board_list_type.rb16
-rw-r--r--app/graphql/types/ci/analytics_type.rb36
-rw-r--r--app/graphql/types/ci/ci_cd_setting_type.rb12
-rw-r--r--app/graphql/types/ci/config/group_type.rb4
-rw-r--r--app/graphql/types/ci/config/job_type.rb30
-rw-r--r--app/graphql/types/ci/config/stage_type.rb4
-rw-r--r--app/graphql/types/ci/detailed_status_type.rb24
-rw-r--r--app/graphql/types/ci/group_type.rb8
-rw-r--r--app/graphql/types/ci/job_type.rb72
-rw-r--r--app/graphql/types/ci/runner_architecture_type.rb4
-rw-r--r--app/graphql/types/ci/runner_platform_type.rb8
-rw-r--r--app/graphql/types/ci/runner_type.rb86
-rw-r--r--app/graphql/types/ci/runner_web_url_edge.rb19
-rw-r--r--app/graphql/types/ci/stage_type.rb12
-rw-r--r--app/graphql/types/ci/status_action_type.rb6
-rw-r--r--app/graphql/types/ci/template_type.rb4
-rw-r--r--app/graphql/types/commit_action_type.rb16
-rw-r--r--app/graphql/types/commit_type.rb6
-rw-r--r--app/graphql/types/container_expiration_policy_type.rb6
-rw-r--r--app/graphql/types/container_repository_details_type.rb11
-rw-r--r--app/graphql/types/container_repository_tag_type.rb8
-rw-r--r--app/graphql/types/container_repository_type.rb14
-rw-r--r--app/graphql/types/dependency_proxy/blob_type.rb2
-rw-r--r--app/graphql/types/dependency_proxy/image_ttl_group_policy_type.rb2
-rw-r--r--app/graphql/types/dependency_proxy/manifest_type.rb6
-rw-r--r--app/graphql/types/design_management/design_collection_type.rb4
-rw-r--r--app/graphql/types/design_management/design_fields.rb2
-rw-r--r--app/graphql/types/design_management/design_type.rb10
-rw-r--r--app/graphql/types/diff_paths_input_type.rb4
-rw-r--r--app/graphql/types/diff_refs_type.rb4
-rw-r--r--app/graphql/types/diff_stats_summary_type.rb4
-rw-r--r--app/graphql/types/diff_stats_type.rb4
-rw-r--r--app/graphql/types/error_tracking/sentry_detailed_error_type.rb114
-rw-r--r--app/graphql/types/error_tracking/sentry_error_collection_type.rb6
-rw-r--r--app/graphql/types/error_tracking/sentry_error_frequency_type.rb6
-rw-r--r--app/graphql/types/error_tracking/sentry_error_stack_trace_context_type.rb8
-rw-r--r--app/graphql/types/error_tracking/sentry_error_stack_trace_entry_type.rb10
-rw-r--r--app/graphql/types/error_tracking/sentry_error_stack_trace_type.rb6
-rw-r--r--app/graphql/types/error_tracking/sentry_error_type.rb60
-rw-r--r--app/graphql/types/evidence_type.rb8
-rw-r--r--app/graphql/types/global_id_type.rb6
-rw-r--r--app/graphql/types/grafana_integration_type.rb12
-rw-r--r--app/graphql/types/group_member_type.rb4
-rw-r--r--app/graphql/types/group_type.rb5
-rw-r--r--app/graphql/types/issue_type.rb45
-rw-r--r--app/graphql/types/issues/negated_issue_filter_input_type.rb24
-rw-r--r--app/graphql/types/jira_import_type.rb12
-rw-r--r--app/graphql/types/jira_user_type.rb12
-rw-r--r--app/graphql/types/jira_users_mapping_input_type.rb8
-rw-r--r--app/graphql/types/label_type.rb16
-rw-r--r--app/graphql/types/merge_request_type.rb217
-rw-r--r--app/graphql/types/merge_requests/assignee_type.rb1
-rw-r--r--app/graphql/types/merge_requests/author_type.rb14
-rw-r--r--app/graphql/types/merge_requests/participant_type.rb14
-rw-r--r--app/graphql/types/merge_requests/reviewer_type.rb1
-rw-r--r--app/graphql/types/metadata/kas_type.rb4
-rw-r--r--app/graphql/types/metadata_type.rb8
-rw-r--r--app/graphql/types/metrics/dashboards/annotation_type.rb7
-rw-r--r--app/graphql/types/mutation_type.rb3
-rw-r--r--app/graphql/types/namespace/package_settings_type.rb6
-rw-r--r--app/graphql/types/namespace_type.rb20
-rw-r--r--app/graphql/types/notes/diff_image_position_input_type.rb8
-rw-r--r--app/graphql/types/notes/diff_position_base_input_type.rb4
-rw-r--r--app/graphql/types/notes/diff_position_input_type.rb6
-rw-r--r--app/graphql/types/notes/diff_position_type.rb16
-rw-r--r--app/graphql/types/notes/discussion_type.rb12
-rw-r--r--app/graphql/types/notes/note_type.rb10
-rw-r--r--app/graphql/types/packages/composer/json_type.rb2
-rw-r--r--app/graphql/types/packages/composer/metadatum_type.rb2
-rw-r--r--app/graphql/types/packages/conan/file_metadatum_type.rb6
-rw-r--r--app/graphql/types/packages/conan/metadatum_type.rb6
-rw-r--r--app/graphql/types/packages/helm/dependency_type.rb10
-rw-r--r--app/graphql/types/packages/helm/maintainer_type.rb2
-rw-r--r--app/graphql/types/packages/helm/metadata_type.rb24
-rw-r--r--app/graphql/types/packages/maven/metadatum_type.rb10
-rw-r--r--app/graphql/types/packages/nuget/metadatum_type.rb2
-rw-r--r--app/graphql/types/packages/package_dependency_link_type.rb4
-rw-r--r--app/graphql/types/packages/package_file_type.rb12
-rw-r--r--app/graphql/types/packages/package_tag_type.rb2
-rw-r--r--app/graphql/types/packages/package_type.rb18
-rw-r--r--app/graphql/types/project_statistics_type.rb20
-rw-r--r--app/graphql/types/project_type.rb63
-rw-r--r--app/graphql/types/projects/service_type.rb11
-rw-r--r--app/graphql/types/projects/service_type_enum.rb17
-rw-r--r--app/graphql/types/projects/services/jira_project_type.rb4
-rw-r--r--app/graphql/types/query_type.rb14
-rw-r--r--app/graphql/types/release_asset_link_type.rb12
-rw-r--r--app/graphql/types/release_links_type.rb20
-rw-r--r--app/graphql/types/release_type.rb32
-rw-r--r--app/graphql/types/repository/blob_type.rb12
-rw-r--r--app/graphql/types/repository_type.rb22
-rw-r--r--app/graphql/types/root_storage_statistics_type.rb12
-rw-r--r--app/graphql/types/saved_reply_type.rb21
-rw-r--r--app/graphql/types/task_completion_status.rb4
-rw-r--r--app/graphql/types/todo_type.rb30
-rw-r--r--app/graphql/types/todoable_interface.rb30
-rw-r--r--app/graphql/types/tree/blob_type.rb8
-rw-r--r--app/graphql/types/tree/submodule_type.rb4
-rw-r--r--app/graphql/types/tree/tree_entry_type.rb4
-rw-r--r--app/graphql/types/user_callout_type.rb4
-rw-r--r--app/graphql/types/user_interface.rb22
-rw-r--r--app/graphql/types/user_status_type.rb8
-rw-r--r--app/graphql/types/work_item_id_type.rb50
-rw-r--r--app/graphql/types/work_item_type.rb4
-rw-r--r--app/graphql/types/work_items/convert_task_input_type.rb36
-rw-r--r--app/helpers/access_tokens_helper.rb6
-rw-r--r--app/helpers/appearances_helper.rb2
-rw-r--r--app/helpers/application_helper.rb22
-rw-r--r--app/helpers/application_settings_helper.rb9
-rw-r--r--app/helpers/auth_helper.rb2
-rw-r--r--app/helpers/blob_helper.rb37
-rw-r--r--app/helpers/broadcast_messages_helper.rb43
-rw-r--r--app/helpers/ci/jobs_helper.rb3
-rw-r--r--app/helpers/ci/pipelines_helper.rb31
-rw-r--r--app/helpers/clusters_helper.rb42
-rw-r--r--app/helpers/commits_helper.rb13
-rw-r--r--app/helpers/container_expiration_policies_helper.rb5
-rw-r--r--app/helpers/container_registry_helper.rb3
-rw-r--r--app/helpers/dashboard_helper.rb4
-rw-r--r--app/helpers/deploy_tokens_helper.rb7
-rw-r--r--app/helpers/diff_helper.rb4
-rw-r--r--app/helpers/dropdowns_helper.rb2
-rw-r--r--app/helpers/explore_helper.rb37
-rw-r--r--app/helpers/groups/crm_settings_helper.rb2
-rw-r--r--app/helpers/groups/group_members_helper.rb4
-rw-r--r--app/helpers/icons_helper.rb40
-rw-r--r--app/helpers/integrations_helper.rb33
-rw-r--r--app/helpers/invite_members_helper.rb4
-rw-r--r--app/helpers/issues_helper.rb6
-rw-r--r--app/helpers/jira_connect_helper.rb28
-rw-r--r--app/helpers/labels_helper.rb26
-rw-r--r--app/helpers/lazy_image_tag_helper.rb3
-rw-r--r--app/helpers/learn_gitlab_helper.rb38
-rw-r--r--app/helpers/listbox_helper.rb13
-rw-r--r--app/helpers/markup_helper.rb7
-rw-r--r--app/helpers/merge_requests_helper.rb15
-rw-r--r--app/helpers/packages_helper.rb2
-rw-r--r--app/helpers/pagination_helper.rb4
-rw-r--r--app/helpers/preferences_helper.rb4
-rw-r--r--app/helpers/projects/cluster_agents_helper.rb4
-rw-r--r--app/helpers/projects/error_tracking_helper.rb14
-rw-r--r--app/helpers/projects_helper.rb21
-rw-r--r--app/helpers/routing/pseudonymization_helper.rb6
-rw-r--r--app/helpers/sessions_helper.rb2
-rw-r--r--app/helpers/sorting_helper.rb10
-rw-r--r--app/helpers/storage_helper.rb17
-rw-r--r--app/helpers/submodule_helper.rb2
-rw-r--r--app/helpers/todos_helper.rb2
-rw-r--r--app/helpers/tree_helper.rb2
-rw-r--r--app/helpers/users/callouts_helper.rb4
-rw-r--r--app/helpers/web_ide_button_helper.rb4
-rw-r--r--app/helpers/whats_new_helper.rb2
-rw-r--r--app/mailers/application_mailer.rb1
-rw-r--r--app/mailers/emails/profile.rb12
-rw-r--r--app/models/analytics/cycle_analytics/aggregation.rb75
-rw-r--r--app/models/application_record.rb11
-rw-r--r--app/models/application_setting.rb21
-rw-r--r--app/models/application_setting_implementation.rb9
-rw-r--r--app/models/blobs/notebook.rb12
-rw-r--r--app/models/broadcast_message.rb40
-rw-r--r--app/models/bulk_imports/entity.rb2
-rw-r--r--app/models/bulk_imports/export_status.rb7
-rw-r--r--app/models/ci/bridge.rb70
-rw-r--r--app/models/ci/build.rb16
-rw-r--r--app/models/ci/group_variable.rb1
-rw-r--r--app/models/ci/pipeline.rb13
-rw-r--r--app/models/ci/pipeline_schedule.rb12
-rw-r--r--app/models/ci/processable.rb2
-rw-r--r--app/models/ci/runner.rb8
-rw-r--r--app/models/ci/secure_file.rb4
-rw-r--r--app/models/concerns/blocks_json_serialization.rb18
-rw-r--r--app/models/concerns/blocks_unsafe_serialization.rb32
-rw-r--r--app/models/concerns/bulk_member_access_load.rb52
-rw-r--r--app/models/concerns/ci/has_deployment_name.rb15
-rw-r--r--app/models/concerns/ci/has_status.rb6
-rw-r--r--app/models/concerns/counter_attribute.rb26
-rw-r--r--app/models/concerns/deployment_platform.rb2
-rw-r--r--app/models/concerns/has_user_type.rb13
-rw-r--r--app/models/concerns/integrations/has_issue_tracker_fields.rb30
-rw-r--r--app/models/concerns/issuable.rb60
-rw-r--r--app/models/concerns/issuable_link.rb55
-rw-r--r--app/models/concerns/issue_resource_event.rb6
-rw-r--r--app/models/concerns/merge_request_reviewer_state.rb8
-rw-r--r--app/models/concerns/pg_full_text_searchable.rb111
-rw-r--r--app/models/concerns/runners_token_prefixable.rb6
-rw-r--r--app/models/concerns/select_for_project_authorization.rb6
-rw-r--r--app/models/concerns/sensitive_serializable_hash.rb46
-rw-r--r--app/models/concerns/spammable.rb11
-rw-r--r--app/models/concerns/timebox.rb1
-rw-r--r--app/models/concerns/token_authenticatable.rb10
-rw-r--r--app/models/concerns/token_authenticatable_strategies/base.rb8
-rw-r--r--app/models/concerns/token_authenticatable_strategies/digest.rb4
-rw-r--r--app/models/concerns/token_authenticatable_strategies/encrypted.rb4
-rw-r--r--app/models/concerns/update_namespace_statistics.rb54
-rw-r--r--app/models/container_repository.rb16
-rw-r--r--app/models/customer_relations/contact.rb18
-rw-r--r--app/models/customer_relations/issue_contact.rb8
-rw-r--r--app/models/customer_relations/organization.rb9
-rw-r--r--app/models/dependency_proxy/blob.rb3
-rw-r--r--app/models/dependency_proxy/manifest.rb3
-rw-r--r--app/models/deployment.rb1
-rw-r--r--app/models/diff_note.rb2
-rw-r--r--app/models/environment.rb15
-rw-r--r--app/models/error_tracking/project_error_tracking_setting.rb4
-rw-r--r--app/models/event_collection.rb48
-rw-r--r--app/models/group.rb10
-rw-r--r--app/models/hooks/web_hook.rb15
-rw-r--r--app/models/instance_configuration.rb3
-rw-r--r--app/models/integration.rb129
-rw-r--r--app/models/integrations/asana.rb4
-rw-r--r--app/models/integrations/bamboo.rb3
-rw-r--r--app/models/integrations/base_chat_notification.rb1
-rw-r--r--app/models/integrations/base_issue_tracker.rb26
-rw-r--r--app/models/integrations/bugzilla.rb4
-rw-r--r--app/models/integrations/campfire.rb4
-rw-r--r--app/models/integrations/confluence.rb4
-rw-r--r--app/models/integrations/custom_issue_tracker.rb5
-rw-r--r--app/models/integrations/discord.rb4
-rw-r--r--app/models/integrations/ewm.rb4
-rw-r--r--app/models/integrations/external_wiki.rb4
-rw-r--r--app/models/integrations/field.rb42
-rw-r--r--app/models/integrations/flowdock.rb4
-rw-r--r--app/models/integrations/hangouts_chat.rb4
-rw-r--r--app/models/integrations/harbor.rb104
-rw-r--r--app/models/integrations/irker.rb6
-rw-r--r--app/models/integrations/jenkins.rb4
-rw-r--r--app/models/integrations/jira.rb110
-rw-r--r--app/models/integrations/mattermost.rb3
-rw-r--r--app/models/integrations/pivotaltracker.rb3
-rw-r--r--app/models/integrations/prometheus.rb1
-rw-r--r--app/models/integrations/redmine.rb5
-rw-r--r--app/models/integrations/webex_teams.rb4
-rw-r--r--app/models/integrations/youtrack.rb4
-rw-r--r--app/models/integrations/zentao.rb5
-rw-r--r--app/models/issue.rb14
-rw-r--r--app/models/issue_link.rb37
-rw-r--r--app/models/issues/search_data.rb11
-rw-r--r--app/models/label.rb25
-rw-r--r--app/models/lfs_download_object.rb1
-rw-r--r--app/models/members/project_member.rb6
-rw-r--r--app/models/merge_request.rb45
-rw-r--r--app/models/milestone.rb1
-rw-r--r--app/models/namespace.rb32
-rw-r--r--app/models/namespace/traversal_hierarchy.rb17
-rw-r--r--app/models/namespaces/traversal/linear.rb9
-rw-r--r--app/models/namespaces/traversal/linear_scopes.rb28
-rw-r--r--app/models/note.rb1
-rw-r--r--app/models/packages/package_file.rb1
-rw-r--r--app/models/packages/pypi/metadatum.rb2
-rw-r--r--app/models/personal_access_token.rb1
-rw-r--r--app/models/preloaders/environments/deployment_preloader.rb22
-rw-r--r--app/models/project.rb79
-rw-r--r--app/models/project_authorization.rb2
-rw-r--r--app/models/project_import_data.rb7
-rw-r--r--app/models/project_pages_metadatum.rb4
-rw-r--r--app/models/project_team.rb44
-rw-r--r--app/models/projects/build_artifacts_size_refresh.rb91
-rw-r--r--app/models/projects/topic.rb7
-rw-r--r--app/models/projects/triggered_hooks.rb25
-rw-r--r--app/models/release.rb4
-rw-r--r--app/models/repository.rb5
-rw-r--r--app/models/snippet.rb16
-rw-r--r--app/models/storage/hashed.rb1
-rw-r--r--app/models/storage/legacy_project.rb1
-rw-r--r--app/models/todo.rb2
-rw-r--r--app/models/user.rb79
-rw-r--r--app/models/users/callout.rb8
-rw-r--r--app/models/users/credit_card_validation.rb2
-rw-r--r--app/models/users/group_callout.rb8
-rw-r--r--app/models/users/saved_reply.rb19
-rw-r--r--app/models/wiki.rb17
-rw-r--r--app/models/wiki_page.rb6
-rw-r--r--app/models/work_item.rb8
-rw-r--r--app/models/work_items/type.rb1
-rw-r--r--app/policies/alert_management/alert_policy.rb2
-rw-r--r--app/policies/application_setting_policy.rb5
-rw-r--r--app/policies/base_policy.rb2
-rw-r--r--app/policies/ci/runner_policy.rb6
-rw-r--r--app/policies/global_policy.rb1
-rw-r--r--app/policies/group_policy.rb7
-rw-r--r--app/policies/issue_policy.rb2
-rw-r--r--app/policies/project_policy.rb15
-rw-r--r--app/policies/user_policy.rb3
-rw-r--r--app/policies/users/saved_reply_policy.rb7
-rw-r--r--app/policies/work_item_policy.rb11
-rw-r--r--app/presenters/alert_management/alert_presenter.rb1
-rw-r--r--app/presenters/blob_presenter.rb21
-rw-r--r--app/presenters/blobs/notebook_presenter.rb9
-rw-r--r--app/presenters/ci/build_runner_presenter.rb5
-rw-r--r--app/presenters/ci/pipeline_presenter.rb1
-rw-r--r--app/presenters/clusterable_presenter.rb4
-rw-r--r--app/presenters/environment_presenter.rb2
-rw-r--r--app/presenters/gitlab/blame_presenter.rb9
-rw-r--r--app/presenters/instance_clusterable_presenter.rb5
-rw-r--r--app/presenters/label_presenter.rb4
-rw-r--r--app/presenters/merge_request_presenter.rb21
-rw-r--r--app/presenters/project_clusterable_presenter.rb4
-rw-r--r--app/presenters/project_presenter.rb17
-rw-r--r--app/presenters/release_presenter.rb6
-rw-r--r--app/presenters/releases/evidence_presenter.rb2
-rw-r--r--app/presenters/search_service_presenter.rb2
-rw-r--r--app/presenters/user_presenter.rb20
-rw-r--r--app/serializers/analytics/cycle_analytics/stage_entity.rb3
-rw-r--r--app/serializers/cluster_entity.rb2
-rw-r--r--app/serializers/cluster_error_entity.rb7
-rw-r--r--app/serializers/clusters/kubernetes_error_entity.rb9
-rw-r--r--app/serializers/deployment_entity.rb2
-rw-r--r--app/serializers/diffs_entity.rb4
-rw-r--r--app/serializers/environment_entity.rb1
-rw-r--r--app/serializers/environment_serializer.rb2
-rw-r--r--app/serializers/fork_namespace_entity.rb8
-rw-r--r--app/serializers/issue_sidebar_basic_entity.rb5
-rw-r--r--app/serializers/label_entity.rb4
-rw-r--r--app/serializers/member_entity.rb2
-rw-r--r--app/serializers/merge_request_widget_entity.rb6
-rw-r--r--app/serializers/pipeline_details_entity.rb5
-rw-r--r--app/serializers/service_event_entity.rb2
-rw-r--r--app/serializers/service_field_entity.rb2
-rw-r--r--app/services/alert_management/create_alert_issue_service.rb12
-rw-r--r--app/services/auth/container_registry_authentication_service.rb36
-rw-r--r--app/services/boards/base_items_list_service.rb27
-rw-r--r--app/services/bulk_create_integration_service.rb6
-rw-r--r--app/services/ci/after_requeue_job_service.rb28
-rw-r--r--app/services/ci/create_downstream_pipeline_service.rb14
-rw-r--r--app/services/ci/destroy_secure_file_service.rb11
-rw-r--r--app/services/ci/pipeline_processing/atomic_processing_service/status_collection.rb8
-rw-r--r--app/services/ci/register_runner_service.rb58
-rw-r--r--app/services/ci/retry_build_service.rb2
-rw-r--r--app/services/ci/retry_pipeline_service.rb17
-rw-r--r--app/services/ci/runners/assign_runner_service.rb28
-rw-r--r--app/services/ci/runners/register_runner_service.rb60
-rw-r--r--app/services/ci/runners/reset_registration_token_service.rb31
-rw-r--r--app/services/ci/runners/unassign_runner_service.rb28
-rw-r--r--app/services/ci/runners/unregister_runner_service.rb22
-rw-r--r--app/services/ci/runners/update_runner_service.rb21
-rw-r--r--app/services/ci/test_failure_history_service.rb1
-rw-r--r--app/services/ci/unregister_runner_service.rb16
-rw-r--r--app/services/ci/update_runner_service.rb19
-rw-r--r--app/services/concerns/members/bulk_create_users.rb13
-rw-r--r--app/services/concerns/rate_limited_service.rb6
-rw-r--r--app/services/concerns/update_repository_storage_methods.rb1
-rw-r--r--app/services/error_tracking/base_service.rb10
-rw-r--r--app/services/error_tracking/collect_error_service.rb2
-rw-r--r--app/services/google_cloud/create_service_accounts_service.rb7
-rw-r--r--app/services/google_cloud/gcp_region_add_or_replace_service.rb23
-rw-r--r--app/services/google_cloud/service_accounts_service.rb33
-rw-r--r--app/services/groups/deploy_tokens/create_service.rb2
-rw-r--r--app/services/groups/deploy_tokens/destroy_service.rb2
-rw-r--r--app/services/groups/deploy_tokens/revoke_service.rb16
-rw-r--r--app/services/groups/destroy_service.rb4
-rw-r--r--app/services/import/gitlab_projects/create_project_from_remote_file_service.rb91
-rw-r--r--app/services/import/gitlab_projects/create_project_from_uploaded_file_service.rb65
-rw-r--r--app/services/import/gitlab_projects/create_project_service.rb81
-rw-r--r--app/services/import/gitlab_projects/file_acquisition_strategies/file_upload.rb33
-rw-r--r--app/services/import/gitlab_projects/file_acquisition_strategies/remote_file.rb76
-rw-r--r--app/services/import/gitlab_projects/file_acquisition_strategies/remote_file_s3.rb93
-rw-r--r--app/services/incident_management/pager_duty/process_webhook_service.rb7
-rw-r--r--app/services/integrations/propagate_template_service.rb10
-rw-r--r--app/services/issuable_base_service.rb7
-rw-r--r--app/services/issuable_links/create_service.rb43
-rw-r--r--app/services/issuable_links/destroy_service.rb9
-rw-r--r--app/services/issue_links/create_service.rb27
-rw-r--r--app/services/issue_links/destroy_service.rb13
-rw-r--r--app/services/issues/create_service.rb8
-rw-r--r--app/services/issues/export_csv_service.rb6
-rw-r--r--app/services/issues/set_crm_contacts_service.rb2
-rw-r--r--app/services/issues/update_service.rb12
-rw-r--r--app/services/labels/base_service.rb156
-rw-r--r--app/services/loose_foreign_keys/batch_cleaner_service.rb2
-rw-r--r--app/services/members/projects/creator_service.rb2
-rw-r--r--app/services/merge_requests/approval_service.rb7
-rw-r--r--app/services/merge_requests/base_service.rb8
-rw-r--r--app/services/merge_requests/bulk_remove_attention_requested_service.rb2
-rw-r--r--app/services/merge_requests/create_service.rb8
-rw-r--r--app/services/merge_requests/export_csv_service.rb4
-rw-r--r--app/services/merge_requests/handle_assignees_change_service.rb4
-rw-r--r--app/services/merge_requests/merge_orchestration_service.rb2
-rw-r--r--app/services/merge_requests/mergeability/check_broken_status_service.rb22
-rw-r--r--app/services/merge_requests/mergeability/check_discussions_status_service.rb22
-rw-r--r--app/services/merge_requests/mergeability/check_draft_status_service.rb23
-rw-r--r--app/services/merge_requests/mergeability/check_open_status_service.rb23
-rw-r--r--app/services/merge_requests/mergeability/run_checks_service.rb4
-rw-r--r--app/services/merge_requests/reload_merge_head_diff_service.rb5
-rw-r--r--app/services/merge_requests/remove_approval_service.rb2
-rw-r--r--app/services/merge_requests/remove_attention_requested_service.rb11
-rw-r--r--app/services/merge_requests/reopen_service.rb6
-rw-r--r--app/services/merge_requests/toggle_attention_requested_service.rb7
-rw-r--r--app/services/notification_recipients/builder/merge_request_unmergeable.rb1
-rw-r--r--app/services/notification_recipients/builder/new_note.rb1
-rw-r--r--app/services/notification_recipients/builder/new_review.rb1
-rw-r--r--app/services/notification_recipients/builder/project_maintainers.rb1
-rw-r--r--app/services/notification_service.rb8
-rw-r--r--app/services/packages/pypi/create_package_service.rb2
-rw-r--r--app/services/personal_access_tokens/create_service.rb1
-rw-r--r--app/services/post_receive_service.rb2
-rw-r--r--app/services/projects/base_move_relations_service.rb1
-rw-r--r--app/services/projects/container_repository/cleanup_tags_service.rb8
-rw-r--r--app/services/projects/container_repository/gitlab/delete_tags_service.rb2
-rw-r--r--app/services/projects/container_repository/third_party/delete_tags_service.rb8
-rw-r--r--app/services/projects/create_service.rb2
-rw-r--r--app/services/projects/deploy_tokens/create_service.rb2
-rw-r--r--app/services/projects/deploy_tokens/destroy_service.rb2
-rw-r--r--app/services/projects/destroy_service.rb14
-rw-r--r--app/services/projects/lfs_pointers/lfs_download_service.rb1
-rw-r--r--app/services/projects/refresh_build_artifacts_size_statistics_service.rb32
-rw-r--r--app/services/projects/update_pages_service.rb14
-rw-r--r--app/services/repositories/base_service.rb2
-rw-r--r--app/services/repositories/destroy_rollback_service.rb8
-rw-r--r--app/services/repositories/destroy_service.rb6
-rw-r--r--app/services/security/ci_configuration/base_create_service.rb2
-rw-r--r--app/services/security/ci_configuration/container_scanning_create_service.rb3
-rw-r--r--app/services/security/ci_configuration/dependency_scanning_create_service.rb3
-rw-r--r--app/services/security/ci_configuration/sast_create_service.rb2
-rw-r--r--app/services/security/ci_configuration/sast_iac_create_service.rb3
-rw-r--r--app/services/security/ci_configuration/secret_detection_create_service.rb3
-rw-r--r--app/services/security/merge_reports_service.rb5
-rw-r--r--app/services/spam/spam_action_service.rb23
-rw-r--r--app/services/spam/spam_constants.rb18
-rw-r--r--app/services/spam/spam_params.rb10
-rw-r--r--app/services/spam/spam_verdict_service.rb17
-rw-r--r--app/services/system_note_service.rb8
-rw-r--r--app/services/system_notes/issuables_service.rb14
-rw-r--r--app/services/todo_service.rb21
-rw-r--r--app/services/users/migrate_to_ghost_user_service.rb21
-rw-r--r--app/services/users/saved_replies/create_service.rb29
-rw-r--r--app/services/users/saved_replies/update_service.rb26
-rw-r--r--app/services/web_hooks/log_execution_service.rb74
-rw-r--r--app/services/work_items/create_and_link_service.rb43
-rw-r--r--app/services/work_items/create_from_task_service.rb50
-rw-r--r--app/services/work_items/task_list_reference_replacement_service.rb52
-rw-r--r--app/uploaders/content_type_whitelist.rb2
-rw-r--r--app/validators/color_validator.rb10
-rw-r--r--app/validators/import/gitlab_projects/remote_file_validator.rb45
-rw-r--r--app/validators/json_schemas/security_ci_configuration_schemas/sast_ui_schema.json4
-rw-r--r--app/views/admin/abuse_reports/_abuse_report.html.haml4
-rw-r--r--app/views/admin/application_settings/_default_branch.html.haml17
-rw-r--r--app/views/admin/application_settings/_eks.html.haml8
-rw-r--r--app/views/admin/application_settings/_initial_branch_name.html.haml13
-rw-r--r--app/views/admin/application_settings/_prometheus.html.haml2
-rw-r--r--app/views/admin/application_settings/_registry.html.haml8
-rw-r--r--app/views/admin/application_settings/_search_limits.html.haml16
-rw-r--r--app/views/admin/application_settings/_signin.html.haml8
-rw-r--r--app/views/admin/application_settings/_sourcegraph.html.haml6
-rw-r--r--app/views/admin/application_settings/_usage.html.haml2
-rw-r--r--app/views/admin/application_settings/_visibility_and_access.html.haml3
-rw-r--r--app/views/admin/application_settings/appearances/_form.html.haml6
-rw-r--r--app/views/admin/application_settings/ci_cd.html.haml2
-rw-r--r--app/views/admin/application_settings/network.html.haml11
-rw-r--r--app/views/admin/application_settings/repository.html.haml6
-rw-r--r--app/views/admin/applications/_delete_form.html.haml9
-rw-r--r--app/views/admin/applications/index.html.haml2
-rw-r--r--app/views/admin/broadcast_messages/_form.html.haml15
-rw-r--r--app/views/admin/broadcast_messages/index.html.haml12
-rw-r--r--app/views/admin/dashboard/_security_newsletter_callout.html.haml1
-rw-r--r--app/views/admin/groups/_form.html.haml9
-rw-r--r--app/views/admin/hooks/_form.html.haml2
-rw-r--r--app/views/admin/runners/edit.html.haml15
-rw-r--r--app/views/admin/spam_logs/_spam_log.html.haml2
-rw-r--r--app/views/admin/topics/_form.html.haml2
-rw-r--r--app/views/admin/users/_head.html.haml4
-rw-r--r--app/views/admin/users/_users.html.haml17
-rw-r--r--app/views/ci/variables/_variable_row.html.haml27
-rw-r--r--app/views/clusters/clusters/_banner.html.haml2
-rw-r--r--app/views/clusters/clusters/_cluster_list.html.haml10
-rw-r--r--app/views/clusters/clusters/_gcp_signup_offer_banner.html.haml19
-rw-r--r--app/views/clusters/clusters/_multiple_clusters_message.html.haml4
-rw-r--r--app/views/clusters/clusters/_sidebar.html.haml4
-rw-r--r--app/views/clusters/clusters/cloud_providers/_cloud_provider_button.html.haml6
-rw-r--r--app/views/clusters/clusters/cloud_providers/_cloud_provider_selector.html.haml8
-rw-r--r--app/views/clusters/clusters/connect.html.haml11
-rw-r--r--app/views/clusters/clusters/gcp/_form.html.haml6
-rw-r--r--app/views/clusters/clusters/index.html.haml8
-rw-r--r--app/views/clusters/clusters/new.html.haml30
-rw-r--r--app/views/clusters/clusters/user/_form.html.haml8
-rw-r--r--app/views/dashboard/_activities.html.haml2
-rw-r--r--app/views/dashboard/groups/_groups.html.haml2
-rw-r--r--app/views/dashboard/todos/_todo.html.haml6
-rw-r--r--app/views/dashboard/todos/index.html.haml5
-rw-r--r--app/views/devise/shared/_email_opted_in.html.haml2
-rw-r--r--app/views/devise/shared/_terms_of_service_notice.html.haml2
-rw-r--r--app/views/discussions/_discussion.html.haml3
-rw-r--r--app/views/explore/groups/_groups.html.haml3
-rw-r--r--app/views/explore/projects/_filter.html.haml23
-rw-r--r--app/views/groups/_activities.html.haml2
-rw-r--r--app/views/groups/_archived_projects.html.haml3
-rw-r--r--app/views/groups/_import_group_from_another_instance_panel.html.haml3
-rw-r--r--app/views/groups/_shared_projects.html.haml3
-rw-r--r--app/views/groups/group_members/index.html.haml35
-rw-r--r--app/views/groups/harbor/repositories/index.html.haml9
-rw-r--r--app/views/groups/imports/show.html.haml2
-rw-r--r--app/views/groups/registry/repositories/index.html.haml1
-rw-r--r--app/views/groups/runners/_runner.html.haml8
-rw-r--r--app/views/groups/runners/_settings.html.haml14
-rw-r--r--app/views/groups/runners/edit.html.haml8
-rw-r--r--app/views/groups/runners/show.html.haml5
-rw-r--r--app/views/groups/settings/_permissions.html.haml3
-rw-r--r--app/views/groups/settings/_transfer.html.haml2
-rw-r--r--app/views/groups/settings/repository/_default_branch.html.haml24
-rw-r--r--app/views/groups/settings/repository/_initial_branch_name.html.haml22
-rw-r--r--app/views/groups/settings/repository/show.html.haml2
-rw-r--r--app/views/ide/_show.html.haml2
-rw-r--r--app/views/import/shared/_errors.html.haml14
-rw-r--r--app/views/jira_connect/oauth_callbacks/index.html.haml1
-rw-r--r--app/views/layouts/_head.html.haml3
-rw-r--r--app/views/layouts/_header_search.html.haml24
-rw-r--r--app/views/layouts/_page.html.haml29
-rw-r--r--app/views/layouts/group.html.haml3
-rw-r--r--app/views/layouts/header/_default.html.haml21
-rw-r--r--app/views/layouts/header/_registration_enabled_callout.html.haml9
-rw-r--r--app/views/layouts/header/_storage_enforcement_banner.html.haml9
-rw-r--r--app/views/layouts/header/_translations.html.haml1
-rw-r--r--app/views/layouts/notify.html.haml5
-rw-r--r--app/views/layouts/profile.html.haml4
-rw-r--r--app/views/layouts/service_desk.html.haml5
-rw-r--r--app/views/notify/_note_email.html.haml4
-rw-r--r--app/views/notify/access_token_created_email.html.haml7
-rw-r--r--app/views/notify/access_token_created_email.text.erb5
-rw-r--r--app/views/notify/issue_due_email.html.haml4
-rw-r--r--app/views/notify/new_issue_email.html.haml4
-rw-r--r--app/views/notify/new_merge_request_email.html.haml2
-rw-r--r--app/views/notify/new_release_email.html.haml2
-rw-r--r--app/views/notify/service_desk_new_note_email.html.haml2
-rw-r--r--app/views/profiles/accounts/show.html.haml2
-rw-r--r--app/views/profiles/chat_names/_chat_name.html.haml2
-rw-r--r--app/views/profiles/two_factor_auths/show.html.haml12
-rw-r--r--app/views/projects/_activity.html.haml2
-rw-r--r--app/views/projects/_commit_button.html.haml2
-rw-r--r--app/views/projects/_deletion_failed.html.haml11
-rw-r--r--app/views/projects/_files.html.haml3
-rw-r--r--app/views/projects/_gitlab_import_modal.html.haml14
-rw-r--r--app/views/projects/_import_project_pane.html.haml7
-rw-r--r--app/views/projects/_invite_groups_modal.html.haml2
-rw-r--r--app/views/projects/_last_push.html.haml8
-rw-r--r--app/views/projects/_merge_request_merge_method_settings.html.haml4
-rw-r--r--app/views/projects/_new_project_fields.html.haml16
-rw-r--r--app/views/projects/_project_templates.html.haml9
-rw-r--r--app/views/projects/artifacts/_artifact.html.haml2
-rw-r--r--app/views/projects/blob/_blob.html.haml3
-rw-r--r--app/views/projects/blob/_editor.html.haml3
-rw-r--r--app/views/projects/blob/_header.html.haml8
-rw-r--r--app/views/projects/blob/_upload.html.haml4
-rw-r--r--app/views/projects/blob/edit.html.haml18
-rw-r--r--app/views/projects/blob/new.html.haml5
-rw-r--r--app/views/projects/blob/viewers/_gitlab_ci_yml_loading.html.haml2
-rw-r--r--app/views/projects/blob/viewers/_loading.html.haml3
-rw-r--r--app/views/projects/blob/viewers/_loading_auxiliary.html.haml2
-rw-r--r--app/views/projects/blob/viewers/_metrics_dashboard_yml_loading.html.haml2
-rw-r--r--app/views/projects/blob/viewers/_route_map_loading.html.haml2
-rw-r--r--app/views/projects/blob/viewers/_sketch.html.haml3
-rw-r--r--app/views/projects/blob/viewers/_stl.html.haml2
-rw-r--r--app/views/projects/branches/new.html.haml3
-rw-r--r--app/views/projects/ci/secure_files/show.html.haml5
-rw-r--r--app/views/projects/commit/_commit_box.html.haml4
-rw-r--r--app/views/projects/commits/_commits.html.haml13
-rw-r--r--app/views/projects/commits/show.html.haml3
-rw-r--r--app/views/projects/diffs/_content.html.haml11
-rw-r--r--app/views/projects/diffs/_file.html.haml5
-rw-r--r--app/views/projects/diffs/_line.html.haml7
-rw-r--r--app/views/projects/diffs/_warning.html.haml1
-rw-r--r--app/views/projects/edit.html.haml4
-rw-r--r--app/views/projects/empty.html.haml81
-rw-r--r--app/views/projects/environments/index.html.haml24
-rw-r--r--app/views/projects/find_file/show.html.haml3
-rw-r--r--app/views/projects/forks/_fork_button.html.haml20
-rw-r--r--app/views/projects/forks/error.html.haml1
-rw-r--r--app/views/projects/forks/new.html.haml39
-rw-r--r--app/views/projects/google_cloud/gcp_regions/index.html.haml8
-rw-r--r--app/views/projects/harbor/repositories/index.html.haml9
-rw-r--r--app/views/projects/imports/show.html.haml2
-rw-r--r--app/views/projects/issues/_alert_moved_from_service_desk.html.haml1
-rw-r--r--app/views/projects/issues/_form.html.haml2
-rw-r--r--app/views/projects/issues/_service_desk_empty_state.html.haml4
-rw-r--r--app/views/projects/issues/index.html.haml2
-rw-r--r--app/views/projects/learn_gitlab/index.html.haml6
-rw-r--r--app/views/projects/merge_requests/_commits.html.haml4
-rw-r--r--app/views/projects/merge_requests/_mr_title.html.haml16
-rw-r--r--app/views/projects/merge_requests/creations/_new_compare.html.haml6
-rw-r--r--app/views/projects/merge_requests/creations/_new_submit.html.haml2
-rw-r--r--app/views/projects/merge_requests/invalid.html.haml25
-rw-r--r--app/views/projects/merge_requests/show.html.haml9
-rw-r--r--app/views/projects/milestones/show.html.haml1
-rw-r--r--app/views/projects/mirrors/_mirror_repos.html.haml5
-rw-r--r--app/views/projects/network/show.html.haml3
-rw-r--r--app/views/projects/pages/_ssl_limitations_warning.html.haml4
-rw-r--r--app/views/projects/pages_domains/_certificate.html.haml13
-rw-r--r--app/views/projects/pipeline_schedules/_form.html.haml9
-rw-r--r--app/views/projects/pipeline_schedules/_pipeline_schedule.html.haml7
-rw-r--r--app/views/projects/pipelines/_info.html.haml4
-rw-r--r--app/views/projects/pipelines/_with_tabs.html.haml15
-rw-r--r--app/views/projects/pipelines/charts.html.haml1
-rw-r--r--app/views/projects/pipelines/index.html.haml22
-rw-r--r--app/views/projects/pipelines/show.html.haml2
-rw-r--r--app/views/projects/project_members/import.html.haml15
-rw-r--r--app/views/projects/project_members/index.html.haml46
-rw-r--r--app/views/projects/protected_branches/shared/_create_protected_branch.html.haml5
-rw-r--r--app/views/projects/registry/repositories/index.html.haml1
-rw-r--r--app/views/projects/runners/_group_runners.html.haml6
-rw-r--r--app/views/projects/runners/_runner.html.haml4
-rw-r--r--app/views/projects/runners/_specific_runners.html.haml2
-rw-r--r--app/views/projects/services/_form.html.haml11
-rw-r--r--app/views/projects/services/prometheus/_custom_metrics.html.haml2
-rw-r--r--app/views/projects/services/prometheus/_metrics.html.haml2
-rw-r--r--app/views/projects/settings/_general.html.haml2
-rw-r--r--app/views/projects/settings/ci_cd/_form.html.haml2
-rw-r--r--app/views/projects/settings/packages_and_registries/show.html.haml2
-rw-r--r--app/views/projects/stage/_stage.html.haml15
-rw-r--r--app/views/projects/triggers/_trigger.html.haml2
-rw-r--r--app/views/sandbox/mermaid.html.erb3
-rw-r--r--app/views/search/results/_blob_highlight.html.haml8
-rw-r--r--app/views/shared/_default_branch_protection.html.haml4
-rw-r--r--app/views/shared/_gl_toggle.html.haml28
-rw-r--r--app/views/shared/_global_alert.html.haml20
-rw-r--r--app/views/shared/_logo_ukraine.svg5
-rw-r--r--app/views/shared/_new_project_item_select.html.haml2
-rw-r--r--app/views/shared/_service_ping_consent.html.haml1
-rw-r--r--app/views/shared/_two_factor_auth_recovery_settings_check.html.haml2
-rw-r--r--app/views/shared/access_tokens/_form.html.haml14
-rw-r--r--app/views/shared/blob/_markdown_buttons.html.haml4
-rw-r--r--app/views/shared/buttons/_project_feature_toggle.html.haml16
-rw-r--r--app/views/shared/deploy_tokens/_table.html.haml2
-rw-r--r--app/views/shared/doorkeeper/applications/_delete_form.html.haml4
-rw-r--r--app/views/shared/errors/_gitaly_unavailable.html.haml15
-rw-r--r--app/views/shared/issuable/_form.html.haml5
-rw-r--r--app/views/shared/issuable/_label_page_create.html.haml5
-rw-r--r--app/views/shared/issuable/_search_bar.html.haml6
-rw-r--r--app/views/shared/issuable/_sidebar.html.haml8
-rw-r--r--app/views/shared/issuable/_sidebar_assignees.html.haml2
-rw-r--r--app/views/shared/issuable/_sidebar_reviewers.html.haml2
-rw-r--r--app/views/shared/issuable/form/_metadata.html.haml10
-rw-r--r--app/views/shared/issuable/form/_title.html.haml6
-rw-r--r--app/views/shared/issue_type/_details_content.html.haml2
-rw-r--r--app/views/shared/labels/_sort_dropdown.html.haml12
-rw-r--r--app/views/shared/members/_invite_group.html.haml30
-rw-r--r--app/views/shared/members/_invite_member.html.haml28
-rw-r--r--app/views/shared/milestones/_delete_button.html.haml2
-rw-r--r--app/views/shared/milestones/_milestone_complete_alert.html.haml1
-rw-r--r--app/views/shared/milestones/_tab_loading.html.haml3
-rw-r--r--app/views/shared/nav/_sidebar_submenu.html.haml2
-rw-r--r--app/views/shared/notes/_hints.html.haml2
-rw-r--r--app/views/shared/projects/protected_branches/_update_protected_branch.html.haml5
-rw-r--r--app/views/shared/web_hooks/_hook_errors.html.haml3
-rw-r--r--app/views/shared/wikis/pages.html.haml11
-rw-r--r--app/views/users/_overview.html.haml8
-rw-r--r--app/workers/all_queues.yml38
-rw-r--r--app/workers/bulk_imports/export_request_worker.rb23
-rw-r--r--app/workers/bulk_imports/pipeline_worker.rb4
-rw-r--r--app/workers/ci/build_finished_worker.rb1
-rw-r--r--app/workers/ci/drop_pipeline_worker.rb2
-rw-r--r--app/workers/concerns/git_garbage_collect_methods.rb32
-rw-r--r--app/workers/container_expiration_policies/cleanup_container_repository_worker.rb2
-rw-r--r--app/workers/container_expiration_policy_worker.rb2
-rw-r--r--app/workers/database/batched_background_migration/ci_database_worker.rb12
-rw-r--r--app/workers/database/batched_background_migration/single_database_worker.rb83
-rw-r--r--app/workers/database/batched_background_migration_worker.rb53
-rw-r--r--app/workers/projects/git_garbage_collect_worker.rb6
-rw-r--r--app/workers/projects/refresh_build_artifacts_size_statistics_worker.rb51
-rw-r--r--app/workers/projects/schedule_refresh_build_artifacts_size_statistics_worker.rb18
-rw-r--r--app/workers/quality/test_data_cleanup_worker.rb33
-rw-r--r--app/workers/web_hook_worker.rb6
-rw-r--r--app/workers/wikis/git_garbage_collect_worker.rb6
-rwxr-xr-xbin/metrics-server1
-rwxr-xr-xbin/rspec-stackprof97
-rw-r--r--config/application.rb3
-rw-r--r--config/database.yml.decomposed-postgresql18
-rw-r--r--config/dependency_decisions.yml6
-rw-r--r--config/events/1647273260_projectsclustersindex_open_modal.yml18
-rw-r--r--config/events/1647273493_projectsclustersindex_click_button.yml19
-rw-r--r--config/events/20210915205050_code_quality_walkthrough_commit_ci_file_dismissed.yml21
-rw-r--r--config/events/20210915205051_code_quality_walkthrough_commit_ci_file_displayed.yml21
-rw-r--r--config/events/20210915205052_code_quality_walkthrough_commit_created.yml21
-rw-r--r--config/events/20210915205053_code_quality_walkthrough_cta_clicked.yml21
-rw-r--r--config/events/20210915205054_code_quality_walkthrough_failed_pipeline_displayed.yml21
-rw-r--r--config/events/20210915205055_code_quality_walkthrough_failed_pipeline_view_logs.yml21
-rw-r--r--config/events/20210915205056_code_quality_walkthrough_running_pipeline_dismissed.yml21
-rw-r--r--config/events/20210915205057_code_quality_walkthrough_running_pipeline_displayed.yml21
-rw-r--r--config/events/20210915205058_code_quality_walkthrough_success_pipeline_displayed.yml21
-rw-r--r--config/events/20210915205059_code_quality_walkthrough_success_pipeline_view_logs.yml21
-rw-r--r--config/feature_categories.yml4
-rw-r--r--config/feature_flags/development/allow_unsafe_ruby_regexp.yml8
-rw-r--r--config/feature_flags/development/broadcast_issue_updates.yml8
-rw-r--r--config/feature_flags/development/cache_shared_runners_enabled.yml8
-rw-r--r--config/feature_flags/development/chat_notification_deployment_protected_branch_filter.yml8
-rw-r--r--config/feature_flags/development/ci_bulk_insert_tags.yml8
-rw-r--r--config/feature_flags/development/ci_drop_cyclical_triggered_pipelines.yml8
-rw-r--r--config/feature_flags/development/ci_fix_order_of_subsequent_jobs.yml8
-rw-r--r--config/feature_flags/development/ci_pending_builds_maintain_denormalized_data.yml2
-rw-r--r--config/feature_flags/development/ci_pending_builds_queue_source.yml4
-rw-r--r--config/feature_flags/development/ci_pipeline_merge_request_presence_check.yml8
-rw-r--r--config/feature_flags/development/ci_queuing_use_denormalized_data_strategy.yml2
-rw-r--r--config/feature_flags/development/ci_trigger_forward_variables.yml8
-rw-r--r--config/feature_flags/development/cluster_vulnerabilities.yml8
-rw-r--r--config/feature_flags/development/consolidated_edit_button.yml8
-rw-r--r--config/feature_flags/development/container_expiration_policies_historic_entry.yml8
-rw-r--r--config/feature_flags/development/container_registry_expiration_policies_throttling.yml2
-rw-r--r--config/feature_flags/development/container_registry_follow_redirects_middleware.yml8
-rw-r--r--config/feature_flags/development/container_registry_migration_phase1.yml8
-rw-r--r--config/feature_flags/development/container_registry_migration_phase1_allow.yml8
-rw-r--r--config/feature_flags/development/container_registry_migration_phase1_deny.yml8
-rw-r--r--config/feature_flags/development/context_commits.yml8
-rw-r--r--config/feature_flags/development/create_project_namespace_on_project_create.yml8
-rw-r--r--config/feature_flags/development/default_merge_ref_for_diffs.yml8
-rw-r--r--config/feature_flags/development/disable_unsafe_regexp.yml8
-rw-r--r--config/feature_flags/development/dispensable_render.yml8
-rw-r--r--config/feature_flags/development/display_outdated_line_diff.yml8
-rw-r--r--config/feature_flags/development/enable_new_sentry_integration.yml8
-rw-r--r--config/feature_flags/development/enable_old_sentry_integration.yml8
-rw-r--r--config/feature_flags/development/enforce_security_report_validation.yml8
-rw-r--r--config/feature_flags/development/enhanced_notify_css.yml8
-rw-r--r--config/feature_flags/development/exit_registration_verification.yml8
-rw-r--r--config/feature_flags/development/fix_comment_scroll.yml8
-rw-r--r--config/feature_flags/development/fork_project_form.yml8
-rw-r--r--config/feature_flags/development/generic_packages.yml8
-rw-r--r--config/feature_flags/development/geo_token_user_authentication.yml4
-rw-r--r--config/feature_flags/development/gl_avatar_for_all_user_avatars.yml8
-rw-r--r--config/feature_flags/development/group_project_api_preload_plans.yml8
-rw-r--r--config/feature_flags/development/group_releases_finder_inoperator.yml8
-rw-r--r--config/feature_flags/development/harbor_registry_integration.yml8
-rw-r--r--config/feature_flags/development/header_read_timeout_buffered_io.yml2
-rw-r--r--config/feature_flags/development/import_project_from_remote_file_s3.yml8
-rw-r--r--config/feature_flags/development/import_relation_object_persistence.yml8
-rw-r--r--config/feature_flags/development/incident_timeline_event_tab.yml8
-rw-r--r--config/feature_flags/development/incremental_repository_backup.yml8
-rw-r--r--config/feature_flags/development/integrated_error_tracking.yml8
-rw-r--r--config/feature_flags/development/integration_form_sections.yml8
-rw-r--r--config/feature_flags/development/invite_members_group_modal.yml8
-rw-r--r--config/feature_flags/development/issue_boards_filtered_search.yml8
-rw-r--r--config/feature_flags/development/issues_full_text_search.yml8
-rw-r--r--config/feature_flags/development/iteration_cadences.yml2
-rw-r--r--config/feature_flags/development/jira_connect_installation_update.yml8
-rw-r--r--config/feature_flags/development/jira_connect_oauth.yml8
-rw-r--r--config/feature_flags/development/job_deployment_count.yml8
-rw-r--r--config/feature_flags/development/jobs_tab_vue.yml8
-rw-r--r--config/feature_flags/development/jupyter_clean_diffs.yml8
-rw-r--r--config/feature_flags/development/lfk_automatic_partition_creation.yml2
-rw-r--r--config/feature_flags/development/lfk_automatic_partition_dropping.yml2
-rw-r--r--config/feature_flags/development/lfk_fair_queueing.yml2
-rw-r--r--config/feature_flags/development/load_balancing_for_export_workers.yml8
-rw-r--r--config/feature_flags/development/merge_service_ping_instrumented_metrics.yml8
-rw-r--r--config/feature_flags/development/namespaces_cache_first_auto_devops_config.yml8
-rw-r--r--config/feature_flags/development/new_environments_table.yml8
-rw-r--r--config/feature_flags/development/new_vulnerability_form.yml8
-rw-r--r--config/feature_flags/development/optimized_housekeeping.yml8
-rw-r--r--config/feature_flags/development/pipeline_schedules_with_tags.yml8
-rw-r--r--config/feature_flags/development/preserve_latest_wal_locations_for_idempotent_jobs.yml8
-rw-r--r--config/feature_flags/development/prevent_sensitive_fields_from_serializable_hash.yml8
-rw-r--r--config/feature_flags/development/project_import_schedule_worker_job_tracker.yml8
-rw-r--r--config/feature_flags/development/projects_build_artifacts_size_refresh_high.yml8
-rw-r--r--config/feature_flags/development/projects_build_artifacts_size_refresh_low.yml8
-rw-r--r--config/feature_flags/development/projects_build_artifacts_size_refresh_medium.yml8
-rw-r--r--config/feature_flags/development/publish_project_deleted_event.yml8
-rw-r--r--config/feature_flags/development/rate_limit_profile_update_username.yml8
-rw-r--r--config/feature_flags/development/rate_limit_user_by_id_endpoint.yml8
-rw-r--r--config/feature_flags/development/rate_limit_user_sign_up_endpoint.yml8
-rw-r--r--config/feature_flags/development/rate_limit_username_exists_endpoint.yml8
-rw-r--r--config/feature_flags/development/rate_limited_service_issues_create.yml8
-rw-r--r--config/feature_flags/development/read_from_vulnerability_finding_evidence.yml8
-rw-r--r--config/feature_flags/development/real_time_issue_sidebar.yml8
-rw-r--r--config/feature_flags/development/rearrange_pipelines_table.yml8
-rw-r--r--config/feature_flags/development/remove_import_data_on_failure.yml2
-rw-r--r--config/feature_flags/development/rendered_diffs_viewer.yml8
-rw-r--r--config/feature_flags/development/roadmap_settings.yml8
-rw-r--r--config/feature_flags/development/role_targeted_broadcast_messages.yml8
-rw-r--r--config/feature_flags/development/route_hll_to_snowplow.yml8
-rw-r--r--config/feature_flags/development/saved_replies.yml8
-rw-r--r--config/feature_flags/development/secure_vulnerability_training.yml2
-rw-r--r--config/feature_flags/development/security_report_ingestion_framework.yml8
-rw-r--r--config/feature_flags/development/show_report_validation_warnings.yml8
-rw-r--r--config/feature_flags/development/snippets_binary_blob.yml8
-rw-r--r--config/feature_flags/development/source_editor_toolbar.yml8
-rw-r--r--config/feature_flags/development/spread_parallel_import.yml8
-rw-r--r--config/feature_flags/development/strong_parameters_for_project_controller.yml8
-rw-r--r--config/feature_flags/development/sync_traversal_ids_before_commit.yml8
-rw-r--r--config/feature_flags/development/track_error_tracking_activity.yml8
-rw-r--r--config/feature_flags/development/track_file_size_over_highlight_limit.yml8
-rw-r--r--config/feature_flags/development/track_highlight_timeouts.yml8
-rw-r--r--config/feature_flags/development/track_work_items_activity.yml8
-rw-r--r--config/feature_flags/development/ukraine_support_tanuki.yml8
-rw-r--r--config/feature_flags/development/update_all_mirrors_job_tracker.yml8
-rw-r--r--config/feature_flags/development/usage_data_i_snippets_show.yml8
-rw-r--r--config/feature_flags/development/use_received_header_for_incoming_emails.yml8
-rw-r--r--config/feature_flags/development/verify_protected_tags_for_pull_mirror.yml8
-rw-r--r--config/feature_flags/development/vsa_consistency_worker.yml8
-rw-r--r--config/feature_flags/development/vsa_incremental_worker.yml8
-rw-r--r--config/feature_flags/development/vulnerability_finding_replace_metadata.yml8
-rw-r--r--config/feature_flags/development/vulnerability_reads_table.yml8
-rw-r--r--config/feature_flags/development/web_ide_primary_edit.yml8
-rw-r--r--config/feature_flags/development/wiki_front_matter.yml8
-rw-r--r--config/feature_flags/experiment/change_continuous_onboarding_link_urls.yml8
-rw-r--r--config/feature_flags/experiment/ci_runner_templates.yml8
-rw-r--r--config/feature_flags/experiment/code_quality_walkthrough.yml8
-rw-r--r--config/feature_flags/experiment/confetti_post_signup.yml8
-rw-r--r--config/feature_flags/experiment/pipeline_editor_walkthrough.yml8
-rw-r--r--config/feature_flags/experiment/runners_availability_section.yml8
-rw-r--r--config/feature_flags/ops/api_kaminari_count_with_limit.yml4
-rw-r--r--config/feature_flags/ops/certificate_based_clusters.yml8
-rw-r--r--config/feature_flags/ops/deprecated_serverless.yml8
-rw-r--r--config/feature_flags/ops/gitlab_experiment.yml8
-rw-r--r--config/feature_flags/ops/purge_stale_security_findings.yml8
-rw-r--r--config/gitlab.yml.example20
-rw-r--r--config/gitlab_loose_foreign_keys.yml3
-rw-r--r--config/helpers/incremental_webpack_compiler/compiler.js2
-rw-r--r--config/initializers/01_active_record_database_tasks_configuration_flag.rb37
-rw-r--r--config/initializers/1_settings.rb19
-rw-r--r--config/initializers/7_prometheus_metrics.rb101
-rw-r--r--config/initializers/action_cable.rb1
-rw-r--r--config/initializers/database_query_analyzers.rb16
-rw-r--r--config/initializers/gitlab_experiment.rb2
-rw-r--r--config/initializers/http_hostname_override.rb1
-rw-r--r--config/initializers/rails_host_authorization.rb2
-rw-r--r--config/initializers/sidekiq.rb4
-rw-r--r--config/initializers_before_autoloader/000_inflections.rb1
-rw-r--r--config/mail_room.yml12
-rw-r--r--config/metrics/aggregates/common.yml24
-rw-r--r--config/metrics/counts_28d/20210216175542_ci_builds.yml3
-rw-r--r--config/metrics/counts_28d/20210216175544_ci_external_pipelines.yml3
-rw-r--r--config/metrics/counts_28d/20210216175546_ci_internal_pipelines.yml3
-rw-r--r--config/metrics/counts_28d/20210216175548_ci_pipeline_config_auto_devops.yml3
-rw-r--r--config/metrics/counts_28d/20210216175550_ci_pipeline_config_repository.yml3
-rw-r--r--config/metrics/counts_28d/20210216175552_ci_pipeline_schedules.yml3
-rw-r--r--config/metrics/counts_28d/20210216175554_ci_pipelines.yml3
-rw-r--r--config/metrics/counts_28d/20210216175556_ci_triggers.yml3
-rw-r--r--config/metrics/counts_28d/20210216181937_failed_deployments.yml2
-rw-r--r--config/metrics/counts_28d/20210216181941_successful_deployments.yml2
-rw-r--r--config/metrics/counts_28d/20210216181951_clusters_applications_runner.yml3
-rw-r--r--config/metrics/counts_28d/20220202160126_ci_users_executing_deployment_job_monthly.yml26
-rw-r--r--config/metrics/counts_28d/20220214202927_users_updating_work_item_title.yml25
-rw-r--r--config/metrics/counts_28d/20220221210352_users_creating_work_items_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20220222215951_xmau_plan.yml21
-rw-r--r--config/metrics/counts_28d/20220222215952_xmau_project_management.yml21
-rw-r--r--config/metrics/counts_28d/20220222215955_users_work_items.yml21
-rw-r--r--config/metrics/counts_28d/20220309183501_error_tracking_view_details_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20220309195504_error_tracking_view_list_monthly.yml25
-rw-r--r--config/metrics/counts_28d/20220315223227_error_tracking_total_unique_counts_monthly.yml26
-rw-r--r--config/metrics/counts_7d/20220202160120_ci_users_executing_deployment_job_weekly.yml26
-rw-r--r--config/metrics/counts_7d/20220216204730_users_updating_work_item_title_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20220221210026_users_creating_work_items_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20220222215851_xmau_plan.yml21
-rw-r--r--config/metrics/counts_7d/20220222215852_xmau_project_management.yml21
-rw-r--r--config/metrics/counts_7d/20220222215855_users_work_items.yml21
-rw-r--r--config/metrics/counts_7d/20220309183454_error_tracking_view_details_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20220309195457_error_tracking_view_list_weekly.yml25
-rw-r--r--config/metrics/counts_7d/20220315223220_error_tracking_total_unique_counts_weekly.yml26
-rw-r--r--config/metrics/counts_all/20210514141520_project_imports_total.yml2
-rw-r--r--config/metrics/counts_all/20220314362302_service_usage_data_download_payload.yml22
-rw-r--r--config/metrics/counts_all/20220315180122_projects_harbor_active.yml21
-rw-r--r--config/metrics/counts_all/20220315180124_groups_harbor_active.yml21
-rw-r--r--config/metrics/counts_all/20220315180127_instances_harbor_active.yml21
-rw-r--r--config/metrics/counts_all/20220315180129_projects_inheriting_harbor_active.yml21
-rw-r--r--config/metrics/counts_all/20220315180131_groups_inheriting_harbor_active.yml21
-rw-r--r--config/metrics/license/20210216183237_version.yml3
-rw-r--r--config/metrics/objects_schemas/git_version_schema.json9
-rw-r--r--config/metrics/settings/20220222181654_certificate_based_clusters_ff.yml24
-rw-r--r--config/routes.rb8
-rw-r--r--config/routes/group.rb3
-rw-r--r--config/routes/jira_connect.rb2
-rw-r--r--config/routes/project.rb15
-rw-r--r--config/sidekiq_queues.yml4
-rw-r--r--config/webpack.config.js14
-rw-r--r--danger/changelog/Dangerfile3
-rw-r--r--danger/database/Dangerfile4
-rw-r--r--danger/documentation/Dangerfile4
-rw-r--r--danger/feature_flag/Dangerfile2
-rw-r--r--danger/plugins/changelog.rb10
-rw-r--r--danger/product_intelligence/Dangerfile2
-rw-r--r--danger/specialization_labels/Dangerfile3
-rw-r--r--danger/specs/Dangerfile5
-rw-r--r--danger/z_metadata/Dangerfile14
-rw-r--r--data/deprecations/14-0-nfs-fot-git-repository-storage.yml24
-rw-r--r--data/deprecations/14-2-deprecation-release-cli.yml24
-rw-r--r--data/deprecations/14-2-deprecation-task-runner.yml24
-rw-r--r--data/deprecations/14-3-database-deprecate-legacy-database-conf.yml2
-rw-r--r--data/deprecations/14-3-deprecation_omniauth-kerberos_gem.yml3
-rw-r--r--data/deprecations/14-3-repository-push-audit-events.yml10
-rw-r--r--data/deprecations/14-5-certificate-based-integration-with-kubernetes.yml25
-rw-r--r--data/deprecations/14-5-deprecate-convert-instance-runner-to-project.yml8
-rw-r--r--data/deprecations/14-5-deprecate-defaultMergeCommitMessageWithDescription-graphql.yml24
-rw-r--r--data/deprecations/14-5-deprecate-opensuse-15-2.yml12
-rw-r--r--data/deprecations/14-5-deprecate-sles-12sp2.yml10
-rw-r--r--data/deprecations/14-5-deprecation-versions-packagetype.yml10
-rw-r--r--data/deprecations/14-5-deprecation-vsa-announce-deprecation-of-vsa-filtering-calculation.yml22
-rw-r--r--data/deprecations/14-5-disable_strict_host_key_checking.yml6
-rw-r--r--data/deprecations/14-5-geo-deprecate-promote-db.yml16
-rw-r--r--data/deprecations/14-5-geo-deprecate-promote-to-primary-node.yml16
-rw-r--r--data/deprecations/14-5-package-container-registry-api-group-update.yml8
-rw-r--r--data/deprecations/14-5-remove-dependency-proxy-permissions-flag.yml12
-rw-r--r--data/deprecations/14-5-remove-package-pipelines-api.yml12
-rw-r--r--data/deprecations/14-5-remove-pipelines-from-version-field.yml12
-rw-r--r--data/deprecations/14-5-runner-api-status-does-contain-paused.yml8
-rw-r--r--data/deprecations/14-5-runner-s3-authenticationtype-nonexplicit-config-deprecation.yml8
-rw-r--r--data/deprecations/14-6-Enforce-validation-of-security-schemas.yml24
-rw-r--r--data/deprecations/14-6-container-scanning-schemas-below-14.yml24
-rw-r--r--data/deprecations/14-6-coverage-fuzzing-schemas-below-14.yml24
-rw-r--r--data/deprecations/14-6-dast-schemas-below-14.yml24
-rw-r--r--data/deprecations/14-6-dependency-scanning-schemas-below-14.yml24
-rw-r--r--data/deprecations/14-6-deprecate-types.yml24
-rw-r--r--data/deprecations/14-6-deprecation-license-compliance-api-terms.yml24
-rw-r--r--data/deprecations/14-6-deprecation-secure-dependency-scanning-bundler-audit.yml24
-rw-r--r--data/deprecations/14-6-job_char_limit.yml24
-rw-r--r--data/deprecations/14-6-pipeline-fields-package-deprecation.yml10
-rw-r--r--data/deprecations/14-6-runner-api-status-renames-not_connected.yml6
-rw-r--r--data/deprecations/14-6-runner_api_new_stale_status_breaking_change.yml6
-rw-r--r--data/deprecations/14-6-sast-schemas-below-14.yml24
-rw-r--r--data/deprecations/14-6-secret-detection-schemas-below-14.yml24
-rw-r--r--data/deprecations/14-7-deprecate-godep-support-in-license-compliance.yml12
-rw-r--r--data/deprecations/14-7-deprecate-merged_by-api-field.yml26
-rw-r--r--data/deprecations/14-7-deprecate-static-site-editor.yml24
-rw-r--r--data/deprecations/14-7-pseudonymizer.yml12
-rw-r--r--data/deprecations/14-7-sidekiq-metrics-health-check-donfig.yml2
-rw-r--r--data/deprecations/14-8-Elasticsearch-6-8.yml11
-rw-r--r--data/deprecations/14-8-compliance-required-pipeline-configuration-premium.yml2
-rw-r--r--data/deprecations/14-8-compliance-status-check-api-field.yml2
-rw-r--r--data/deprecations/14-8-deprecate-projectFingerprint-from-PipelineSecurityReportFinding-GraphQL.yml2
-rw-r--r--data/deprecations/14-8-deprecation-secure-dependency-scanning-retire-js.yml24
-rw-r--r--data/deprecations/14-8-enforce-pat-expiration.yml20
-rw-r--r--data/deprecations/14-8-enforce-ssh-expiration.yml20
-rw-r--r--data/deprecations/14-8-geo-deprecate-db-rake-tasks.yml4
-rw-r--r--data/deprecations/14-8-geo-deprecate-replication-detail-routes.yml6
-rw-r--r--data/deprecations/14-8-gitaly-remove-per-repository-election.yml4
-rw-r--r--data/deprecations/14-8-graphql-ids.yml6
-rw-r--r--data/deprecations/14-8-grpc-proxy.yml2
-rw-r--r--data/deprecations/14-8-iteration-started-field.yml22
-rw-r--r--data/deprecations/14-8-nfs_support.yml2
-rw-r--r--data/deprecations/14-8-protect-cns-chs.yml2
-rw-r--r--data/deprecations/14-8-protect-vulnerability-check.yml2
-rw-r--r--data/deprecations/14-8-remove-support-for-fixup-in-commit-message-triggering-draft-status.yml12
-rw-r--r--data/deprecations/14-8-remove_ff_push_rules_supersede_code_owners.yml8
-rw-r--r--data/deprecations/14-8-request-profiling.yml4
-rw-r--r--data/deprecations/14-8-runner-api-active-field-replaced-with-paused-breaking-change.yml4
-rw-r--r--data/deprecations/14-8-runner-api-project_type-breaking-change.yml4
-rw-r--r--data/deprecations/14-8-runner-api-status-filter-does-accept-active-or-paused.yml4
-rw-r--r--data/deprecations/14-8-sast-secret-analyzer-image.yml2
-rw-r--r--data/deprecations/14-8-secure-and-protect-analyzer-bump.yml45
-rw-r--r--data/deprecations/14-8-secure-ca-python-deprecation.yml28
-rw-r--r--data/deprecations/14-9-deprecate-composer-download-permissions.yml11
-rw-r--r--data/deprecations/14-9-deprecate-permissions-change-package-settings.yml16
-rw-r--r--data/deprecations/14-9-deprecate-testcoveragesetting.yml2
-rw-r--r--data/deprecations/14-9-pages-daemon.yml16
-rw-r--r--data/deprecations/14-9-system_monitoring.yml14
-rw-r--r--data/deprecations/15-0-JTW_v2_update.yml28
-rw-r--r--data/deprecations/15-0-deprecate-monitor-logging.yml27
-rw-r--r--data/deprecations/15-0-deprecate-monitor-metrics.yml27
-rw-r--r--data/deprecations/15-0-deprecate-monitor-tracing.yml26
-rw-r--r--data/deprecations/15-0-instance-statistics-graphql-node-removal.yml2
-rw-r--r--data/deprecations/15-0-oauth-noexpiry.yml26
-rw-r--r--data/deprecations/15-0-oauth.yml26
-rw-r--r--data/deprecations/JTW_v2_update.yml28
-rw-r--r--data/deprecations/data/deprecations/14-9-secure-and-protect-analyzer-bump.yml.yml44
-rw-r--r--data/deprecations/distribution_deprecations_14-4.yml6
-rw-r--r--data/deprecations/templates/14-9-deprecation-htpassword-authentication-container-registry.yml11
-rw-r--r--data/removals/14_0/deprecation_bump_terraform_template_version.yml6
-rw-r--r--data/removals/14_0/removal-sidekiq_experimental_queue_selector.yml2
-rw-r--r--data/removals/14_0/removal_ci_project_config_path.yml1
-rw-r--r--data/removals/14_0/removal_enablement_pg11.yml2
-rw-r--r--data/removals/14_0/removal_enablement_ubuntu_16.yml3
-rw-r--r--data/removals/14_0/removal_runner_25555.yml1
-rw-r--r--data/removals/14_0/verify-ci-removal-parametertrace.yml2
-rw-r--r--data/removals/14_2/removal-verify-build-log.yml4
-rw-r--r--data/removals/14_3/removal-limit-tags-to-50.yml2
-rw-r--r--data/removals/14_3/removal-verify-pe-pipelinefindername.yml4
-rw-r--r--data/removals/14_3/removal_legacy_storage_setting.yml6
-rw-r--r--data/removals/14_6/limit_trigger_pipelines.yml4
-rw-r--r--data/removals/14_6/removal-release-cli-s3.yml4
-rw-r--r--data/removals/14_9/removal_monitor_respond_integrated_error_tracking.yml14
-rw-r--r--data/whats_new/202011230001_13_06.yml2
-rw-r--r--data/whats_new/202101140001_13_08.yml1
-rw-r--r--data/whats_new/202102180001_13_09.yml1
-rw-r--r--data/whats_new/202103220001_13_10.yml26
-rw-r--r--data/whats_new/202104220001_13_11.yml18
-rw-r--r--data/whats_new/202105220001_13_12.yml36
-rw-r--r--data/whats_new/202106220001_14_0.yml2
-rw-r--r--data/whats_new/202107220001_14_1.yml10
-rw-r--r--data/whats_new/2021102000001_14_04.yml3
-rw-r--r--data/whats_new/202112200001_14_06.yml4
-rw-r--r--data/whats_new/202201200001_14_07.yml1
-rw-r--r--data/whats_new/202202210001_14_08.yml7
-rw-r--r--data/whats_new/templates/YYYYMMDD0001_XX_YY.yml20
-rw-r--r--db/fixtures/development/33_triage_ops.rb139
-rw-r--r--db/migrate/20211007090229_create_issue_search_table.rb29
-rw-r--r--db/migrate/20211021115409_add_color_to_epics.rb10
-rw-r--r--db/migrate/20211021124715_add_text_limit_to_epics_color.rb13
-rw-r--r--db/migrate/20211203160952_add_updated_state_by_user_id_to_merge_request_reviewers.rb12
-rw-r--r--db/migrate/20211203161149_add_index_to_merge_request_reviewers_updated_state_by_user_id.rb15
-rw-r--r--db/migrate/20211203161840_add_updated_state_by_user_id_to_merge_request_assignees.rb9
-rw-r--r--db/migrate/20211203161942_add_index_to_merge_request_assignees_updated_state_by_user_id.rb15
-rw-r--r--db/migrate/20220105152547_add_foreign_key_to_updated_state_by_user_id_to_merge_request_assignees.rb15
-rw-r--r--db/migrate/20220105153149_add_foreign_key_to_updated_state_by_user_id_to_merge_request_reviewers.rb15
-rw-r--r--db/migrate/20220120211831_temp_index_for_group_namespace_member_backfill.rb17
-rw-r--r--db/migrate/20220124200927_add_index_to_issues.rb17
-rw-r--r--db/migrate/20220203074916_add_topics_lower_name_index.rb15
-rw-r--r--db/migrate/20220203134942_add_hidden_to_projects.rb11
-rw-r--r--db/migrate/20220204093120_create_analytics_cycle_analytics_aggregations.rb43
-rw-r--r--db/migrate/20220204193000_add_integrations_encrypted_properties.rb8
-rw-r--r--db/migrate/20220211090920_cleanup_populate_topics_non_private_projects_count.rb15
-rw-r--r--db/migrate/20220211125954_create_related_epic_links.rb18
-rw-r--r--db/migrate/20220215164709_update_application_settings_container_registry_exp_pol_worker_capacity_default.rb20
-rw-r--r--db/migrate/20220216110023_create_saved_replies.rb20
-rw-r--r--db/migrate/20220217100008_add_container_registry_expiration_policies_caching_to_application_settings.rb13
-rw-r--r--db/migrate/20220217113058_add_status_to_status_check_responses.rb7
-rw-r--r--db/migrate/20220221102333_change_maintenance_note_limit_in_ci_runner.rb db/migrate/20220221102333_change_maintainer_note_limit_in_ci_runner.rb14
-rw-r--r--db/migrate/20220222072536_add_target_access_levels_to_broadcast_messages.rb11
-rw-r--r--db/migrate/20220301002101_add_security_orchestration_policy_configuration_namespace_reference.rb11
-rw-r--r--db/migrate/20220301003502_add_security_orchestration_policy_configuration_namespace_index.rb27
-rw-r--r--db/migrate/20220301091503_add_not_null_constraint_to_security_policy_configurations.rb14
-rw-r--r--db/migrate/20220301175104_change_security_orchestration_policy_configuration_project_index.rb17
-rw-r--r--db/migrate/20220301175426_create_project_build_artifacts_size_refresh.rb24
-rw-r--r--db/migrate/20220303190555_add_comment_to_deployment_approvals.rb10
-rw-r--r--db/migrate/20220303191047_add_text_limit_to_deployment_approvals_comment.rb13
-rw-r--r--db/migrate/20220304052335_remove_not_null_contraint_on_title_from_sprints.rb17
-rw-r--r--db/migrate/20220304061631_remove_unique_index_for_sprints_on_iterations_cadence_id_and_title.rb15
-rw-r--r--db/migrate/20220304062107_remove_unique_index_for_sprints_on_project_id_and_title.rb15
-rw-r--r--db/migrate/20220304152729_add_default_to_required_python_on_packages_pypi_metadata.rb11
-rw-r--r--db/migrate/20220307203458_rename_user_email_lookup_limit_setting_to_search_settings.rb13
-rw-r--r--db/migrate/20220309100648_add_time_to_restore_service_dora_metric.rb7
-rw-r--r--db/migrate/20220310101118_update_holder_name_limit.rb28
-rw-r--r--db/migrate/20220314194149_add_project_ci_secure_files_to_plan_limits.rb7
-rw-r--r--db/post_migrate/20210329102724_add_new_trail_plans.rb4
-rw-r--r--db/post_migrate/20210805192450_update_trial_plans_ci_daily_pipeline_schedule_triggers.rb4
-rw-r--r--db/post_migrate/20210812013042_remove_duplicate_project_authorizations.rb111
-rw-r--r--db/post_migrate/20211026070408_backfill_issue_search_data.rb22
-rw-r--r--db/post_migrate/20211028100843_delete_issue_merge_request_taggings_records.rb6
-rw-r--r--db/post_migrate/20211029102822_add_open_source_plan.rb4
-rw-r--r--db/post_migrate/20220120211832_backfill_member_namespace_id_for_group_members.rb27
-rw-r--r--db/post_migrate/20220131000000_index_job_artifacts_on_trace_type_and_expire_at.rb16
-rw-r--r--db/post_migrate/20220131000001_schedule_trace_expiry_removal.rb55
-rw-r--r--db/post_migrate/20220204110725_backfill_cycle_analytics_aggregations.rb33
-rw-r--r--db/post_migrate/20220204194347_encrypt_integration_properties.rb22
-rw-r--r--db/post_migrate/20220207080758_update_api_indexes_for_projects.rb48
-rw-r--r--db/post_migrate/20220208080921_schedule_migrate_personal_namespace_project_maintainer_to_owner.rb25
-rw-r--r--db/post_migrate/20220215190020_rerun_convert_stringified_raw_metadata_hash_to_json.rb27
-rw-r--r--db/post_migrate/20220216201949_remove_package_files_limit_from_application_settings.rb18
-rw-r--r--db/post_migrate/20220217135229_validate_not_null_constraint_on_security_findings_uuid.rb13
-rw-r--r--db/post_migrate/20220221214928_remove_show_diff_preview_in_email_column.rb13
-rw-r--r--db/post_migrate/20220222191845_remove_not_null_constraint_for_security_scan_succeeded.rb11
-rw-r--r--db/post_migrate/20220222192524_create_not_null_constraint_releases_tag.rb13
-rw-r--r--db/post_migrate/20220222192525_remove_null_releases.rb24
-rw-r--r--db/post_migrate/20220223112304_schedule_nullify_orphan_runner_id_on_ci_builds.rb27
-rw-r--r--db/post_migrate/20220224000000_async_build_trace_expire_at_index.rb14
-rw-r--r--db/post_migrate/20220224204415_recreate_index_security_ci_builds_on_name_and_id_parser_with_new_features.rb31
-rw-r--r--db/post_migrate/20220225133705_cleanup_backfill_ci_queuing_tables.rb15
-rw-r--r--db/post_migrate/20220301093434_backfill_all_project_namespaces.rb30
-rw-r--r--db/post_migrate/20220302203410_create_index_security_ci_builds_on_name_and_id_parser_with_new_features.rb28
-rw-r--r--db/post_migrate/20220304165107_drop_partitioned_foreign_keys.rb19
-rw-r--r--db/post_migrate/20220304201847_add_unique_index_on_security_training_providers.rb15
-rw-r--r--db/post_migrate/20220305223212_add_security_training_providers.rb40
-rw-r--r--db/post_migrate/20220307192534_create_index_for_remove_duplicate_project_tag_releases.rb17
-rw-r--r--db/post_migrate/20220307192610_remove_duplicate_project_tag_releases.rb26
-rw-r--r--db/post_migrate/20220307192645_remove_index_for_remove_duplicate_project_tag_releases.rb17
-rw-r--r--db/post_migrate/20220307192725_create_unique_index_release_tag_project.rb23
-rw-r--r--db/post_migrate/20220307203459_rename_user_email_lookup_limit_setting_to_search_settings_cleanup.rb15
-rw-r--r--db/post_migrate/20220308000205_drop_old_index_security_ci_builds_on_name_and_id_parser_features.rb26
-rw-r--r--db/post_migrate/20220308115219_schedule_reset_duplicate_ci_runners_token_encrypted_values_on_projects.rb27
-rw-r--r--db/post_migrate/20220308115502_schedule_reset_duplicate_ci_runners_token_values_on_projects.rb27
-rw-r--r--db/post_migrate/20220309084838_remove_external_pull_request_tracking.rb15
-rw-r--r--db/post_migrate/20220309084954_remove_leftover_external_pull_request_deletions.rb30
-rw-r--r--db/post_migrate/20220309154855_add_index_on_issues_closed_incidents.rb15
-rw-r--r--db/post_migrate/20220310095341_add_async_index_ci_job_artifacts_project_id_created_at.rb16
-rw-r--r--db/post_migrate/20220310134207_add_index_project_id_and_released_at_and_id_on_releases.rb16
-rw-r--r--db/post_migrate/20220310141349_remove_dependency_list_usage_data_from_redis.rb13
-rw-r--r--db/post_migrate/20220314162342_add_index_ci_job_artifacts_project_id_created_at.rb15
-rw-r--r--db/schema_migrations/202108120130421
-rw-r--r--db/schema_migrations/202110070902291
-rw-r--r--db/schema_migrations/202110211154091
-rw-r--r--db/schema_migrations/202110211247151
-rw-r--r--db/schema_migrations/202110260704081
-rw-r--r--db/schema_migrations/202112031609521
-rw-r--r--db/schema_migrations/202112031611491
-rw-r--r--db/schema_migrations/202112031618401
-rw-r--r--db/schema_migrations/202112031619421
-rw-r--r--db/schema_migrations/202201051525471
-rw-r--r--db/schema_migrations/202201051531491
-rw-r--r--db/schema_migrations/202201202118311
-rw-r--r--db/schema_migrations/202201202118321
-rw-r--r--db/schema_migrations/202201242009271
-rw-r--r--db/schema_migrations/202201310000001
-rw-r--r--db/schema_migrations/202201310000011
-rw-r--r--db/schema_migrations/202202030749161
-rw-r--r--db/schema_migrations/202202031349421
-rw-r--r--db/schema_migrations/202202040931201
-rw-r--r--db/schema_migrations/202202041107251
-rw-r--r--db/schema_migrations/202202041930001
-rw-r--r--db/schema_migrations/202202041943471
-rw-r--r--db/schema_migrations/202202070807581
-rw-r--r--db/schema_migrations/202202080809211
-rw-r--r--db/schema_migrations/202202110909201
-rw-r--r--db/schema_migrations/202202111259541
-rw-r--r--db/schema_migrations/202202151647091
-rw-r--r--db/schema_migrations/202202151900201
-rw-r--r--db/schema_migrations/202202161100231
-rw-r--r--db/schema_migrations/202202162019491
-rw-r--r--db/schema_migrations/202202171000081
-rw-r--r--db/schema_migrations/202202171130581
-rw-r--r--db/schema_migrations/202202171352291
-rw-r--r--db/schema_migrations/202202211023331
-rw-r--r--db/schema_migrations/202202212149281
-rw-r--r--db/schema_migrations/202202220725361
-rw-r--r--db/schema_migrations/202202221918451
-rw-r--r--db/schema_migrations/202202221925241
-rw-r--r--db/schema_migrations/202202221925251
-rw-r--r--db/schema_migrations/202202231123041
-rw-r--r--db/schema_migrations/202202240000001
-rw-r--r--db/schema_migrations/202202242044151
-rw-r--r--db/schema_migrations/202202251337051
-rw-r--r--db/schema_migrations/202203010021011
-rw-r--r--db/schema_migrations/202203010035021
-rw-r--r--db/schema_migrations/202203010915031
-rw-r--r--db/schema_migrations/202203010934341
-rw-r--r--db/schema_migrations/202203011751041
-rw-r--r--db/schema_migrations/202203011754261
-rw-r--r--db/schema_migrations/202203022034101
-rw-r--r--db/schema_migrations/202203031905551
-rw-r--r--db/schema_migrations/202203031910471
-rw-r--r--db/schema_migrations/202203040523351
-rw-r--r--db/schema_migrations/202203040616311
-rw-r--r--db/schema_migrations/202203040621071
-rw-r--r--db/schema_migrations/202203041527291
-rw-r--r--db/schema_migrations/202203041651071
-rw-r--r--db/schema_migrations/202203042018471
-rw-r--r--db/schema_migrations/202203052232121
-rw-r--r--db/schema_migrations/202203071925341
-rw-r--r--db/schema_migrations/202203071926101
-rw-r--r--db/schema_migrations/202203071926451
-rw-r--r--db/schema_migrations/202203071927251
-rw-r--r--db/schema_migrations/202203072034581
-rw-r--r--db/schema_migrations/202203072034591
-rw-r--r--db/schema_migrations/202203080002051
-rw-r--r--db/schema_migrations/202203081152191
-rw-r--r--db/schema_migrations/202203081155021
-rw-r--r--db/schema_migrations/202203090848381
-rw-r--r--db/schema_migrations/202203090849541
-rw-r--r--db/schema_migrations/202203091006481
-rw-r--r--db/schema_migrations/202203091548551
-rw-r--r--db/schema_migrations/202203100953411
-rw-r--r--db/schema_migrations/202203101011181
-rw-r--r--db/schema_migrations/202203101342071
-rw-r--r--db/schema_migrations/202203101413491
-rw-r--r--db/schema_migrations/202203141623421
-rw-r--r--db/schema_migrations/202203141941491
-rw-r--r--db/structure.sql1714
-rw-r--r--doc/.vale/gitlab/CurrentStatus.yml5
-rw-r--r--doc/.vale/gitlab/HeadingContent.yml18
-rw-r--r--doc/.vale/gitlab/SubstitutionWarning.yml3
-rw-r--r--doc/.vale/gitlab/Substitutions.yml1
-rw-r--r--doc/.vale/gitlab/Uppercase.yml3
-rw-r--r--doc/.vale/gitlab/Wordy.yml7
-rw-r--r--doc/.vale/gitlab/spelling-exceptions.txt2
-rw-r--r--doc/administration/audit_event_streaming.md296
-rw-r--r--doc/administration/audit_events.md17
-rw-r--r--doc/administration/auditor_users.md4
-rw-r--r--doc/administration/auth/atlassian.md16
-rw-r--r--doc/administration/auth/ldap/ldap-troubleshooting.md14
-rw-r--r--doc/administration/cicd.md21
-rw-r--r--doc/administration/clusters/kas.md117
-rw-r--r--doc/administration/database_load_balancing.md9
-rw-r--r--doc/administration/docs_self_host.md2
-rw-r--r--doc/administration/encrypted_configuration.md2
-rw-r--r--doc/administration/feature_flags.md2
-rw-r--r--doc/administration/geo/disaster_recovery/index.md2
-rw-r--r--doc/administration/geo/disaster_recovery/runbooks/planned_failover_multi_node.md2
-rw-r--r--doc/administration/geo/disaster_recovery/runbooks/planned_failover_single_node.md2
-rw-r--r--doc/administration/geo/index.md32
-rw-r--r--doc/administration/geo/replication/object_storage.md2
-rw-r--r--doc/administration/geo/replication/troubleshooting.md21
-rw-r--r--doc/administration/geo/replication/using_a_geo_server.md9
-rw-r--r--doc/administration/geo/secondary_proxy/index.md2
-rw-r--r--doc/administration/geo/setup/database.md24
-rw-r--r--doc/administration/geo/setup/index.md14
-rw-r--r--doc/administration/get_started.md6
-rw-r--r--doc/administration/gitaly/index.md15
-rw-r--r--doc/administration/gitaly/praefect.md5
-rw-r--r--doc/administration/gitaly/recovery.md4
-rw-r--r--doc/administration/gitaly/troubleshooting.md44
-rw-r--r--doc/administration/incoming_email.md10
-rw-r--r--doc/administration/index.md4
-rw-r--r--doc/administration/instance_limits.md36
-rw-r--r--doc/administration/integration/plantuml.md17
-rw-r--r--doc/administration/integration/terminal.md5
-rw-r--r--doc/administration/job_artifacts.md72
-rw-r--r--doc/administration/logs.md9
-rw-r--r--doc/administration/monitoring/gitlab_self_monitoring_project/index.md5
-rw-r--r--doc/administration/monitoring/index.md3
-rw-r--r--doc/administration/monitoring/performance/img/performance_bar_request_selector_warning.pngbin10175 -> 0 bytes
-rw-r--r--doc/administration/monitoring/performance/performance_bar.md21
-rw-r--r--doc/administration/monitoring/prometheus/index.md2
-rw-r--r--doc/administration/object_storage.md3
-rw-r--r--doc/administration/operations/fast_ssh_key_lookup.md2
-rw-r--r--doc/administration/operations/puma.md231
-rw-r--r--doc/administration/package_information/deprecated_os.md9
-rw-r--r--doc/administration/package_information/index.md2
-rw-r--r--doc/administration/package_information/licensing.md2
-rw-r--r--doc/administration/package_information/omnibus_packages.md2
-rw-r--r--doc/administration/package_information/postgresql_versions.md2
-rw-r--r--doc/administration/package_information/signed_packages.md2
-rw-r--r--doc/administration/package_information/supported_os.md1
-rw-r--r--doc/administration/packages/container_registry.md51
-rw-r--r--doc/administration/pages/index.md10
-rw-r--r--doc/administration/postgresql/external.md2
-rw-r--r--doc/administration/raketasks/doctor.md4
-rw-r--r--doc/administration/reference_architectures/10k_users.md10
-rw-r--r--doc/administration/reference_architectures/25k_users.md10
-rw-r--r--doc/administration/reference_architectures/2k_users.md20
-rw-r--r--doc/administration/reference_architectures/3k_users.md10
-rw-r--r--doc/administration/reference_architectures/50k_users.md10
-rw-r--r--doc/administration/reference_architectures/5k_users.md10
-rw-r--r--doc/administration/reference_architectures/index.md99
-rw-r--r--doc/administration/reply_by_email.md2
-rw-r--r--doc/administration/repository_checks.md6
-rw-r--r--doc/administration/restart_gitlab.md7
-rw-r--r--doc/administration/sidekiq.md67
-rw-r--r--doc/administration/terraform_state.md4
-rw-r--r--doc/administration/troubleshooting/debug.md2
-rw-r--r--doc/administration/troubleshooting/gitlab_rails_cheat_sheet.md22
-rw-r--r--doc/administration/troubleshooting/img/AzureAD-scim_provisioning.pngbin539414 -> 80244 bytes
-rw-r--r--doc/administration/troubleshooting/linux_cheat_sheet.md2
-rw-r--r--doc/administration/troubleshooting/postgresql.md4
-rw-r--r--doc/administration/uploads.md2
-rw-r--r--doc/api/alert_management_alerts.md129
-rw-r--r--doc/api/api_resources.md1
-rw-r--r--doc/api/broadcast_messages.md70
-rw-r--r--doc/api/container_registry.md6
-rw-r--r--doc/api/dependencies.md2
-rw-r--r--doc/api/deploy_tokens.md92
-rw-r--r--doc/api/deployments.md16
-rw-r--r--doc/api/dora/metrics.md22
-rw-r--r--doc/api/environments.md87
-rw-r--r--doc/api/epics.md9
-rw-r--r--doc/api/features.md2
-rw-r--r--doc/api/geo_nodes.md17
-rw-r--r--doc/api/graphql/index.md105
-rw-r--r--doc/api/graphql/reference/index.md1019
-rw-r--r--doc/api/group_labels.md2
-rw-r--r--doc/api/group_wikis.md25
-rw-r--r--doc/api/groups.md16
-rw-r--r--doc/api/index.md34
-rw-r--r--doc/api/issues.md22
-rw-r--r--doc/api/jobs.md38
-rw-r--r--doc/api/linked_epics.md90
-rw-r--r--doc/api/merge_request_approvals.md6
-rw-r--r--doc/api/merge_requests.md228
-rw-r--r--doc/api/notes.md9
-rw-r--r--doc/api/oauth2.md4
-rw-r--r--doc/api/packages/pypi.md1
-rw-r--r--doc/api/project_import_export.md55
-rw-r--r--doc/api/project_snippets.md2
-rw-r--r--doc/api/projects.md19
-rw-r--r--doc/api/resource_access_tokens.md4
-rw-r--r--doc/api/runners.md64
-rw-r--r--doc/api/search.md18
-rw-r--r--doc/api/secure_files.md171
-rw-r--r--doc/api/settings.md18
-rw-r--r--doc/api/status_checks.md26
-rw-r--r--doc/api/system_hooks.md37
-rw-r--r--doc/api/topics.md25
-rw-r--r--doc/api/users.md28
-rw-r--r--doc/api/v3_to_v4.md4
-rw-r--r--doc/api/vulnerability_exports.md2
-rw-r--r--doc/api/wikis.md24
-rw-r--r--doc/architecture/blueprints/ci_scale/index.md6
-rw-r--r--doc/architecture/blueprints/composable_codebase_using_rails_engines/index.md2
-rw-r--r--doc/architecture/blueprints/consolidating_groups_and_projects/index.md2
-rw-r--r--doc/architecture/blueprints/container_registry_metadata_database/index.md2
-rw-r--r--doc/architecture/blueprints/gitlab_to_kubernetes_communication/index.md10
-rw-r--r--doc/architecture/blueprints/object_storage/index.md2
-rw-r--r--doc/architecture/blueprints/runner_scaling/gitlab-autoscaling-overview.pngbin94088 -> 37761 bytes
-rw-r--r--doc/ci/cloud_deployment/ecs/quick_start_guide.md44
-rw-r--r--doc/ci/cloud_services/index.md7
-rw-r--r--doc/ci/directed_acyclic_graph/index.md2
-rw-r--r--doc/ci/environments/deployment_approvals.md41
-rw-r--r--doc/ci/environments/img/environments_list_v14_3.pngbin14885 -> 0 bytes
-rw-r--r--doc/ci/environments/img/environments_list_v14_8.pngbin0 -> 43212 bytes
-rw-r--r--doc/ci/environments/index.md4
-rw-r--r--doc/ci/environments/protected_environments.md13
-rw-r--r--doc/ci/examples/authenticating-with-hashicorp-vault/index.md8
-rw-r--r--doc/ci/jobs/ci_job_token.md6
-rw-r--r--doc/ci/jobs/index.md3
-rw-r--r--doc/ci/jobs/job_control.md66
-rw-r--r--doc/ci/lint.md6
-rw-r--r--doc/ci/metrics_reports.md11
-rw-r--r--doc/ci/migration/circleci.md2
-rw-r--r--doc/ci/pipelines/cicd_minutes.md22
-rw-r--r--doc/ci/pipelines/img/pipeline_schedule_play.pngbin11400 -> 0 bytes
-rw-r--r--doc/ci/pipelines/img/pipeline_schedule_variables.pngbin6300 -> 0 bytes
-rw-r--r--doc/ci/pipelines/img/pipeline_schedules_list.pngbin12948 -> 0 bytes
-rw-r--r--doc/ci/pipelines/img/pipeline_schedules_new_form.pngbin20090 -> 0 bytes
-rw-r--r--doc/ci/pipelines/img/pipeline_schedules_ownership.pngbin5004 -> 0 bytes
-rw-r--r--doc/ci/pipelines/index.md22
-rw-r--r--doc/ci/pipelines/merge_request_pipelines.md4
-rw-r--r--doc/ci/pipelines/merge_trains.md4
-rw-r--r--doc/ci/pipelines/merged_results_pipelines.md2
-rw-r--r--doc/ci/pipelines/pipelines_for_merged_results.md4
-rw-r--r--doc/ci/pipelines/schedules.md159
-rw-r--r--doc/ci/pipelines/settings.md88
-rw-r--r--doc/ci/runners/build_cloud/linux_build_cloud.md9
-rw-r--r--doc/ci/runners/build_cloud/macos/environment.md9
-rw-r--r--doc/ci/runners/build_cloud/macos_build_cloud.md9
-rw-r--r--doc/ci/runners/build_cloud/windows_build_cloud.md9
-rw-r--r--doc/ci/runners/configure_runners.md10
-rw-r--r--doc/ci/runners/index.md6
-rw-r--r--doc/ci/runners/runner_cloud/linux_runner_cloud.md9
-rw-r--r--doc/ci/runners/runner_cloud/macos/environment.md9
-rw-r--r--doc/ci/runners/runner_cloud/macos_runner_cloud.md9
-rw-r--r--doc/ci/runners/runner_cloud/windows_runner_cloud.md9
-rw-r--r--doc/ci/runners/runners_scope.md4
-rw-r--r--doc/ci/runners/saas/linux_saas_runner.md2
-rw-r--r--doc/ci/runners/saas/macos/environment.md2
-rw-r--r--doc/ci/runners/saas/macos_saas_runner.md8
-rw-r--r--doc/ci/secrets/index.md4
-rw-r--r--doc/ci/services/index.md4
-rw-r--r--doc/ci/unit_test_reports.md7
-rw-r--r--doc/ci/variables/index.md2
-rw-r--r--doc/ci/yaml/gitlab_ci_yaml.md2
-rw-r--r--doc/ci/yaml/includes.md7
-rw-r--r--doc/ci/yaml/index.md63
-rw-r--r--doc/development/adding_database_indexes.md8
-rw-r--r--doc/development/agent/gitops.md9
-rw-r--r--doc/development/agent/identity.md9
-rw-r--r--doc/development/agent/index.md9
-rw-r--r--doc/development/agent/local.md9
-rw-r--r--doc/development/agent/repository_overview.md9
-rw-r--r--doc/development/agent/routing.md9
-rw-r--r--doc/development/agent/user_stories.md9
-rw-r--r--doc/development/api_graphql_styleguide.md12
-rw-r--r--doc/development/architecture.md14
-rw-r--r--doc/development/backend/create_source_code_be/index.md143
-rw-r--r--doc/development/background_migrations.md3
-rw-r--r--doc/development/bulk_import.md2
-rw-r--r--doc/development/caching.md7
-rw-r--r--doc/development/changelog.md1
-rw-r--r--doc/development/cicd/index.md7
-rw-r--r--doc/development/cicd/schema.md146
-rw-r--r--doc/development/cicd/templates.md36
-rw-r--r--doc/development/code_review.md24
-rw-r--r--doc/development/contributing/design.md2
-rw-r--r--doc/development/contributing/issue_workflow.md16
-rw-r--r--doc/development/contributing/merge_request_workflow.md5
-rw-r--r--doc/development/contributing/style_guides.md25
-rw-r--r--doc/development/contributing/verify/index.md236
-rw-r--r--doc/development/dangerbot.md36
-rw-r--r--doc/development/database/database_reviewer_guidelines.md9
-rw-r--r--doc/development/database/loose_foreign_keys.md168
-rw-r--r--doc/development/database/multiple_databases.md18
-rw-r--r--doc/development/database/strings_and_the_text_data_type.md20
-rw-r--r--doc/development/database_review.md10
-rw-r--r--doc/development/documentation/graphql_styleguide.md2
-rw-r--r--doc/development/documentation/index.md20
-rw-r--r--doc/development/documentation/redirects.md60
-rw-r--r--doc/development/documentation/styleguide/index.md88
-rw-r--r--doc/development/documentation/styleguide/word_list.md37
-rw-r--r--doc/development/documentation/testing.md37
-rw-r--r--doc/development/ee_features.md133
-rw-r--r--doc/development/emails.md3
-rw-r--r--doc/development/event_store.md2
-rw-r--r--doc/development/experiment_guide/experimentation.md4
-rw-r--r--doc/development/experiment_guide/gitlab_experiment.md4
-rw-r--r--doc/development/experiment_guide/index.md12
-rw-r--r--doc/development/export_csv.md2
-rw-r--r--doc/development/fe_guide/content_editor.md2
-rw-r--r--doc/development/fe_guide/icons.md34
-rw-r--r--doc/development/fe_guide/style/javascript.md2
-rw-r--r--doc/development/fe_guide/vue3_migration.md8
-rw-r--r--doc/development/feature_flags/controls.md6
-rw-r--r--doc/development/feature_flags/index.md5
-rw-r--r--doc/development/feature_flags/process.md4
-rw-r--r--doc/development/features_inside_dot_gitlab.md2
-rw-r--r--doc/development/file_storage.md2
-rw-r--r--doc/development/fips_compliance.md49
-rw-r--r--doc/development/foreign_keys.md6
-rw-r--r--doc/development/geo.md58
-rw-r--r--doc/development/gitlab_diagram_overview.odgbin50512 -> 0 bytes
-rw-r--r--doc/development/go_guide/go_upgrade.md2
-rw-r--r--doc/development/gotchas.md12
-rw-r--r--doc/development/i18n/proofreader.md4
-rw-r--r--doc/development/img/architecture_simplified.pngbin28516 -> 0 bytes
-rw-r--r--doc/development/img/architecture_simplified_v14_9.pngbin0 -> 44673 bytes
-rw-r--r--doc/development/img/merge_request_reports_v14_7.pngbin0 -> 66876 bytes
-rw-r--r--doc/development/img/merge_widget_v14_7.pngbin0 -> 56335 bytes
-rw-r--r--doc/development/import_project.md4
-rw-r--r--doc/development/index.md8
-rw-r--r--doc/development/insert_into_tables_in_batches.md2
-rw-r--r--doc/development/integrations/index.md332
-rw-r--r--doc/development/integrations/jira_connect.md49
-rw-r--r--doc/development/integrations/secure.md40
-rw-r--r--doc/development/internal_api.md9
-rw-r--r--doc/development/internal_api/index.md29
-rw-r--r--doc/development/internal_users.md2
-rw-r--r--doc/development/kubernetes.md2
-rw-r--r--doc/development/licensed_feature_availability.md9
-rw-r--r--doc/development/merge_request_application_and_rate_limit_guidelines.md28
-rw-r--r--doc/development/merge_request_concepts/index.md62
-rw-r--r--doc/development/merge_request_performance_guidelines.md49
-rw-r--r--doc/development/new_fe_guide/modules/widget_extensions.md1
-rw-r--r--doc/development/packages.md6
-rw-r--r--doc/development/performance.md293
-rw-r--r--doc/development/permissions.md25
-rw-r--r--doc/development/pipelines.md91
-rw-r--r--doc/development/product_qualified_lead_guide/index.md85
-rw-r--r--doc/development/profiling.md67
-rw-r--r--doc/development/rake_tasks.md16
-rw-r--r--doc/development/redis/new_redis_instance.md12
-rw-r--r--doc/development/secure_coding_guidelines.md102
-rw-r--r--doc/development/service_ping/implement.md77
-rw-r--r--doc/development/service_ping/index.md22
-rw-r--r--doc/development/service_ping/metrics_dictionary.md64
-rw-r--r--doc/development/service_ping/metrics_instrumentation.md44
-rw-r--r--doc/development/service_ping/review_guidelines.md5
-rw-r--r--doc/development/service_ping/usage_data.md70
-rw-r--r--doc/development/shared_files.md2
-rw-r--r--doc/development/sidekiq/idempotent_jobs.md10
-rw-r--r--doc/development/sidekiq/worker_attributes.md2
-rw-r--r--doc/development/sidekiq_style_guide.md4
-rw-r--r--doc/development/snowplow/implementation.md9
-rw-r--r--doc/development/spam_protection_and_captcha/exploratory_testing.md360
-rw-r--r--doc/development/spam_protection_and_captcha/graphql_api.md66
-rw-r--r--doc/development/spam_protection_and_captcha/index.md53
-rw-r--r--doc/development/spam_protection_and_captcha/model_and_services.md155
-rw-r--r--doc/development/spam_protection_and_captcha/web_ui.md196
-rw-r--r--doc/development/testing_guide/end_to_end/best_practices.md157
-rw-r--r--doc/development/testing_guide/end_to_end/feature_flags.md2
-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.md129
-rw-r--r--doc/development/testing_guide/flaky_tests.md11
-rw-r--r--doc/development/uploads.md431
-rw-r--r--doc/development/uploads/background.md154
-rw-r--r--doc/development/uploads/implementation.md190
-rw-r--r--doc/development/uploads/index.md14
-rw-r--r--doc/development/uploads/working_with_uploads.md163
-rw-r--r--doc/development/value_stream_analytics/img/object_hierarchy_example_V14_10.pngbin55849 -> 20826 bytes
-rw-r--r--doc/development/workspace/index.md120
-rw-r--r--doc/development/workspaces/index.md120
-rw-r--r--doc/install/aws/manual_install_aws.md4
-rw-r--r--doc/install/docker.md20
-rw-r--r--doc/install/google_cloud_platform/index.md24
-rw-r--r--doc/install/index.md4
-rw-r--r--doc/install/next_steps.md2
-rw-r--r--doc/install/openshift_and_gitlab/index.md8
-rw-r--r--doc/install/pivotal/index.md4
-rw-r--r--doc/install/relative_url.md8
-rw-r--r--doc/install/requirements.md4
-rw-r--r--doc/integration/azure.md271
-rw-r--r--doc/integration/elasticsearch.md53
-rw-r--r--doc/integration/external-issue-tracker.md20
-rw-r--r--doc/integration/gitlab.md7
-rw-r--r--doc/integration/jenkins.md4
-rw-r--r--doc/integration/jira/configure.md2
-rw-r--r--doc/integration/jira/connect-app.md2
-rw-r--r--doc/integration/jira/development_panel.md2
-rw-r--r--doc/integration/omniauth.md4
-rw-r--r--doc/integration/security_partners/index.md6
-rw-r--r--doc/integration/twitter.md4
-rw-r--r--doc/operations/error_tracking.md18
-rw-r--r--doc/operations/feature_flags.md102
-rw-r--r--doc/operations/incident_management/alerts.md41
-rw-r--r--doc/operations/incident_management/img/incident_list_v14_9.pngbin0 -> 45199 bytes
-rw-r--r--doc/operations/incident_management/img/incident_metrics_tab_text_link_modal_v14_9.pngbin0 -> 53167 bytes
-rw-r--r--doc/operations/incident_management/img/metric_image_url_dialog_v13_8.pngbin15876 -> 0 bytes
-rw-r--r--doc/operations/incident_management/incidents.md55
-rw-r--r--doc/operations/incident_management/oncall_schedules.md8
-rw-r--r--doc/operations/incident_management/paging.md30
-rw-r--r--doc/operations/metrics/dashboards/panel_types.md2
-rw-r--r--doc/operations/metrics/dashboards/templating_variables.md6
-rw-r--r--doc/push_rules/push_rules.md4
-rw-r--r--doc/raketasks/backup_restore.md33
-rw-r--r--doc/raketasks/features.md35
-rw-r--r--doc/raketasks/list_repos.md2
-rw-r--r--doc/security/rate_limits.md4
-rw-r--r--doc/security/two_factor_authentication.md41
-rw-r--r--doc/ssh/index.md18
-rw-r--r--doc/subscriptions/index.md2
-rw-r--r--doc/subscriptions/self_managed/index.md24
-rw-r--r--doc/topics/autodevops/customize.md6
-rw-r--r--doc/topics/autodevops/index.md8
-rw-r--r--doc/topics/autodevops/quick_start_guide.md9
-rw-r--r--doc/topics/autodevops/stages.md4
-rw-r--r--doc/topics/autodevops/upgrading_auto_deploy_dependencies.md4
-rw-r--r--doc/topics/cron/index.md3
-rw-r--r--doc/topics/git/tags.md2
-rw-r--r--doc/topics/gitlab_flow.md2
-rw-r--r--doc/topics/index.md9
-rw-r--r--doc/topics/offline/quick_start_guide.md61
-rw-r--r--doc/topics/release_your_application.md12
-rw-r--r--doc/topics/use_gitlab.md2
-rw-r--r--doc/tutorials/index.md1
-rw-r--r--doc/update/deprecations.md1143
-rw-r--r--doc/update/index.md142
-rw-r--r--doc/update/package/convert_to_ee.md6
-rw-r--r--doc/update/package/downgrade.md2
-rw-r--r--doc/update/package/index.md2
-rw-r--r--doc/update/plan_your_upgrade.md2
-rw-r--r--doc/update/removals.md136
-rw-r--r--doc/update/zero_downtime.md2
-rw-r--r--doc/user/admin_area/analytics/usage_trends.md3
-rw-r--r--doc/user/admin_area/broadcast_messages.md5
-rw-r--r--doc/user/admin_area/credentials_inventory.md11
-rw-r--r--doc/user/admin_area/img/credentials_inventory_gpg_keys_v13_10.pngbin20600 -> 0 bytes
-rw-r--r--doc/user/admin_area/img/credentials_inventory_gpg_keys_v14_9.pngbin0 -> 16956 bytes
-rw-r--r--doc/user/admin_area/img/credentials_inventory_personal_access_tokens_v14_9.pngbin0 -> 34445 bytes
-rw-r--r--doc/user/admin_area/img/credentials_inventory_project_access_tokens_v14_9.pngbin0 -> 19849 bytes
-rw-r--r--doc/user/admin_area/img/credentials_inventory_ssh_keys_v13_5.pngbin26813 -> 0 bytes
-rw-r--r--doc/user/admin_area/img/credentials_inventory_ssh_keys_v14_9.pngbin0 -> 29612 bytes
-rw-r--r--doc/user/admin_area/index.md13
-rw-r--r--doc/user/admin_area/license.md188
-rw-r--r--doc/user/admin_area/license_file.md127
-rw-r--r--doc/user/admin_area/reporting/spamcheck.md9
-rw-r--r--doc/user/admin_area/settings/account_and_limit_settings.md9
-rw-r--r--doc/user/admin_area/settings/continuous_integration.md23
-rw-r--r--doc/user/admin_area/settings/gitaly_timeouts.md2
-rw-r--r--doc/user/admin_area/settings/index.md3
-rw-r--r--doc/user/admin_area/settings/user_and_ip_rate_limits.md2
-rw-r--r--doc/user/admin_area/settings/visibility_and_access_controls.md48
-rw-r--r--doc/user/analytics/ci_cd_analytics.md60
-rw-r--r--doc/user/analytics/code_review_analytics.md2
-rw-r--r--doc/user/analytics/img/mr_throughput_chart_v13_3.pngbin17870 -> 0 bytes
-rw-r--r--doc/user/analytics/img/project_vsa_filter_v14_3.pngbin21120 -> 0 bytes
-rw-r--r--doc/user/analytics/img/project_vsa_stage_table_v14_4.pngbin38783 -> 0 bytes
-rw-r--r--doc/user/analytics/merge_request_analytics.md2
-rw-r--r--doc/user/analytics/value_stream_analytics.md316
-rw-r--r--doc/user/application_security/api_fuzzing/create_har_files.md2
-rw-r--r--doc/user/application_security/api_fuzzing/index.md7
-rw-r--r--doc/user/application_security/cluster_image_scanning/index.md16
-rw-r--r--doc/user/application_security/configuration/index.md7
-rw-r--r--doc/user/application_security/container_scanning/index.md22
-rw-r--r--doc/user/application_security/coverage_fuzzing/index.md10
-rw-r--r--doc/user/application_security/dast/checks/200.1.md6
-rw-r--r--doc/user/application_security/dast/checks/548.1.md8
-rw-r--r--doc/user/application_security/dast/checks/598.1.md31
-rw-r--r--doc/user/application_security/dast/checks/index.md1
-rw-r--r--doc/user/application_security/dast/index.md23
-rw-r--r--doc/user/application_security/dast_api/index.md8
-rw-r--r--doc/user/application_security/dependency_list/index.md2
-rw-r--r--doc/user/application_security/dependency_scanning/analyzers.md2
-rw-r--r--doc/user/application_security/dependency_scanning/index.md107
-rw-r--r--doc/user/application_security/iac_scanning/index.md11
-rw-r--r--doc/user/application_security/index.md10
-rw-r--r--doc/user/application_security/offline_deployments/index.md2
-rw-r--r--doc/user/application_security/policies/img/container_policy_rule_mode_v14_3.pngbin39343 -> 0 bytes
-rw-r--r--doc/user/application_security/policies/img/container_policy_yaml_mode_v14_3.pngbin50096 -> 0 bytes
-rw-r--r--doc/user/application_security/policies/img/policy_rule_mode_v14_9.pngbin0 -> 34025 bytes
-rw-r--r--doc/user/application_security/policies/img/policy_yaml_mode_v14_9.pngbin0 -> 27424 bytes
-rw-r--r--doc/user/application_security/policies/img/scan_result_policy_yaml_mode_v14_6.pngbin76484 -> 0 bytes
-rw-r--r--doc/user/application_security/policies/index.md4
-rw-r--r--doc/user/application_security/policies/scan-execution-policies.md10
-rw-r--r--doc/user/application_security/policies/scan-result-policies.md7
-rw-r--r--doc/user/application_security/sast/index.md71
-rw-r--r--doc/user/application_security/secret_detection/index.md18
-rw-r--r--doc/user/application_security/secret_detection/post_processing.md2
-rw-r--r--doc/user/application_security/vulnerabilities/index.md33
-rw-r--r--doc/user/application_security/vulnerability_report/index.md22
-rw-r--r--doc/user/clusters/agent/ci_cd_tunnel.md264
-rw-r--r--doc/user/clusters/agent/gitops.md140
-rw-r--r--doc/user/clusters/agent/gitops/secrets_management.md61
-rw-r--r--doc/user/clusters/agent/index.md200
-rw-r--r--doc/user/clusters/agent/install/index.md276
-rw-r--r--doc/user/clusters/agent/repository.md539
-rw-r--r--doc/user/clusters/agent/runner.md9
-rw-r--r--doc/user/clusters/agent/troubleshooting.md13
-rw-r--r--doc/user/clusters/agent/vulnerabilities.md113
-rw-r--r--doc/user/clusters/applications.md4
-rw-r--r--doc/user/clusters/create/index.md13
-rw-r--r--doc/user/clusters/crossplane.md2
-rw-r--r--doc/user/clusters/img/kubernetes-agent-ui-list_v14_8.pngbin22175 -> 0 bytes
-rw-r--r--doc/user/clusters/integrations.md12
-rw-r--r--doc/user/clusters/management_project.md2
-rw-r--r--doc/user/clusters/management_project_template.md139
-rw-r--r--doc/user/clusters/migrating_from_gma_to_project_template.md4
-rw-r--r--doc/user/compliance/compliance_report/index.md61
-rw-r--r--doc/user/compliance/license_compliance/index.md16
-rw-r--r--doc/user/crm/index.md7
-rw-r--r--doc/user/discussions/index.md9
-rw-r--r--doc/user/gitlab_com/index.md37
-rw-r--r--doc/user/group/clusters/index.md2
-rw-r--r--doc/user/group/epics/img/related_epic_block_v14_9.pngbin0 -> 31319 bytes
-rw-r--r--doc/user/group/epics/img/related_epics_add_v14_9.pngbin0 -> 27785 bytes
-rw-r--r--doc/user/group/epics/img/related_epics_remove_v14_9.pngbin0 -> 5034 bytes
-rw-r--r--doc/user/group/epics/index.md1
-rw-r--r--doc/user/group/epics/linked_epics.md79
-rw-r--r--doc/user/group/import/img/import_panel_v14_1.pngbin17447 -> 0 bytes
-rw-r--r--doc/user/group/import/img/new_group_navigation_v13_8.pngbin8644 -> 0 bytes
-rw-r--r--doc/user/group/import/index.md22
-rw-r--r--doc/user/group/index.md87
-rw-r--r--doc/user/group/iterations/index.md28
-rw-r--r--doc/user/group/planning_hierarchy/img/epic-view-ancestors-in-sidebar_v14_6.pngbin24780 -> 5010 bytes
-rw-r--r--doc/user/group/planning_hierarchy/img/issue-view-parent-epic-in-sidebar_v14_6.pngbin25077 -> 4994 bytes
-rw-r--r--doc/user/group/planning_hierarchy/img/view-project-work-item-hierarchy_v14_8.pngbin38783 -> 0 bytes
-rw-r--r--doc/user/group/planning_hierarchy/index.md20
-rw-r--r--doc/user/group/roadmap/img/epics_state_dropdown_v14_3.pngbin6994 -> 0 bytes
-rw-r--r--doc/user/group/roadmap/index.md17
-rw-r--r--doc/user/group/saml_sso/group_managed_accounts.md2
-rw-r--r--doc/user/group/saml_sso/index.md37
-rw-r--r--doc/user/group/saml_sso/scim_setup.md20
-rw-r--r--doc/user/group/settings/group_access_tokens.md2
-rw-r--r--doc/user/group/subgroups/img/mention_subgroups.pngbin14783 -> 0 bytes
-rw-r--r--doc/user/group/subgroups/index.md263
-rw-r--r--doc/user/group/value_stream_analytics/img/vsa_stage_table_v14_7.pngbin242008 -> 79595 bytes
-rw-r--r--doc/user/group/value_stream_analytics/index.md461
-rw-r--r--doc/user/index.md29
-rw-r--r--doc/user/infrastructure/clusters/connect/index.md4
-rw-r--r--doc/user/infrastructure/clusters/connect/new_eks_cluster.md132
-rw-r--r--doc/user/infrastructure/clusters/connect/new_gke_cluster.md131
-rw-r--r--doc/user/infrastructure/clusters/deploy/inventory_object.md98
-rw-r--r--doc/user/infrastructure/clusters/index.md9
-rw-r--r--doc/user/infrastructure/clusters/manage/management_project_applications/runner.md2
-rw-r--r--doc/user/infrastructure/clusters/migrate_to_gitlab_agent.md83
-rw-r--r--doc/user/infrastructure/iac/index.md16
-rw-r--r--doc/user/infrastructure/iac/mr_integration.md4
-rw-r--r--doc/user/infrastructure/iac/terraform_state.md8
-rw-r--r--doc/user/infrastructure/index.md4
-rw-r--r--doc/user/instance/clusters/index.md2
-rw-r--r--doc/user/markdown.md74
-rw-r--r--doc/user/packages/composer_repository/index.md3
-rw-r--r--doc/user/packages/container_registry/index.md14
-rw-r--r--doc/user/packages/container_registry/reduce_container_registry_storage.md66
-rw-r--r--doc/user/packages/dependency_proxy/index.md11
-rw-r--r--doc/user/packages/generic_packages/index.md33
-rw-r--r--doc/user/packages/package_registry/index.md6
-rw-r--r--doc/user/packages/package_registry/reduce_package_registry_storage.md2
-rw-r--r--doc/user/packages/pypi_repository/index.md4
-rw-r--r--doc/user/packages/terraform_module_registry/index.md6
-rw-r--r--doc/user/permissions.md512
-rw-r--r--doc/user/profile/account/delete_account.md79
-rw-r--r--doc/user/profile/img/personal_readme_setup_v14_5.pngbin26192 -> 10328 bytes
-rw-r--r--doc/user/profile/notifications.md1
-rw-r--r--doc/user/profile/personal_access_tokens.md4
-rw-r--r--doc/user/profile/preferences.md2
-rw-r--r--doc/user/project/badges.md2
-rw-r--r--doc/user/project/canary_deployments.md26
-rw-r--r--doc/user/project/clusters/add_eks_clusters.md6
-rw-r--r--doc/user/project/clusters/add_existing_cluster.md6
-rw-r--r--doc/user/project/clusters/add_gke_clusters.md2
-rw-r--r--doc/user/project/clusters/add_remove_clusters.md8
-rw-r--r--doc/user/project/clusters/cluster_access.md2
-rw-r--r--doc/user/project/clusters/deploy_to_cluster.md6
-rw-r--r--doc/user/project/clusters/gitlab_managed_clusters.md2
-rw-r--r--doc/user/project/clusters/index.md2
-rw-r--r--doc/user/project/clusters/multiple_kubernetes_clusters.md2
-rw-r--r--doc/user/project/clusters/protect/container_host_security/index.md2
-rw-r--r--doc/user/project/clusters/protect/container_host_security/quick_start_guide.md2
-rw-r--r--doc/user/project/clusters/protect/container_network_security/index.md2
-rw-r--r--doc/user/project/clusters/protect/container_network_security/quick_start_guide.md2
-rw-r--r--doc/user/project/clusters/protect/index.md2
-rw-r--r--doc/user/project/code_owners.md4
-rw-r--r--doc/user/project/deploy_boards.md6
-rw-r--r--doc/user/project/deploy_keys/img/public_deploy_key_v13_0.pngbin17220 -> 0 bytes
-rw-r--r--doc/user/project/deploy_keys/index.md211
-rw-r--r--doc/user/project/file_lock.md8
-rw-r--r--doc/user/project/highlighting.md68
-rw-r--r--doc/user/project/img/labels_sort_label_priority.pngbin42263 -> 0 bytes
-rw-r--r--doc/user/project/img/labels_sort_priority.pngbin41486 -> 0 bytes
-rw-r--r--doc/user/project/img/labels_subscriptions_v13_5.pngbin11375 -> 0 bytes
-rw-r--r--doc/user/project/import/bitbucket.md60
-rw-r--r--doc/user/project/import/clearcase.md2
-rw-r--r--doc/user/project/import/cvs.md2
-rw-r--r--doc/user/project/import/gitlab_com.md2
-rw-r--r--doc/user/project/import/jira.md15
-rw-r--r--doc/user/project/integrations/custom_issue_tracker.md2
-rw-r--r--doc/user/project/integrations/gitlab_slack_application.md16
-rw-r--r--doc/user/project/integrations/harbor.md50
-rw-r--r--doc/user/project/integrations/img/failed_badges.pngbin0 -> 46485 bytes
-rw-r--r--doc/user/project/integrations/img/failed_banner.pngbin0 -> 17440 bytes
-rw-r--r--doc/user/project/integrations/img/failed_banner_error.pngbin0 -> 13390 bytes
-rw-r--r--doc/user/project/integrations/mattermost_slash_commands.md16
-rw-r--r--doc/user/project/integrations/overview.md1
-rw-r--r--doc/user/project/integrations/webhook_events.md17
-rw-r--r--doc/user/project/integrations/webhooks.md57
-rw-r--r--doc/user/project/issue_board.md18
-rw-r--r--doc/user/project/issues/csv_export.md10
-rw-r--r--doc/user/project/issues/issue_data_and_actions.md4
-rw-r--r--doc/user/project/issues/managing_issues.md31
-rw-r--r--doc/user/project/issues/multiple_assignees_for_issues.md2
-rw-r--r--doc/user/project/issues/related_issues.md7
-rw-r--r--doc/user/project/issues/sorting_issue_lists.md6
-rw-r--r--doc/user/project/labels.md445
-rw-r--r--doc/user/project/members/index.md54
-rw-r--r--doc/user/project/members/share_project_with_groups.md62
-rw-r--r--doc/user/project/merge_requests/approvals/rules.md2
-rw-r--r--doc/user/project/merge_requests/approvals/settings.md4
-rw-r--r--doc/user/project/merge_requests/cherry_pick_changes.md7
-rw-r--r--doc/user/project/merge_requests/code_quality.md8
-rw-r--r--doc/user/project/merge_requests/commit_templates.md10
-rw-r--r--doc/user/project/merge_requests/commits.md10
-rw-r--r--doc/user/project/merge_requests/csv_export.md8
-rw-r--r--doc/user/project/merge_requests/fast_forward_merge.md2
-rw-r--r--doc/user/project/merge_requests/getting_started.md4
-rw-r--r--doc/user/project/merge_requests/img/ff_merge_rebase_v14_7.pngbin13865 -> 0 bytes
-rw-r--r--doc/user/project/merge_requests/img/ff_merge_rebase_v14_9.pngbin0 -> 17903 bytes
-rw-r--r--doc/user/project/merge_requests/img/merge_request_diff_v12_2.pngbin60405 -> 0 bytes
-rw-r--r--doc/user/project/merge_requests/load_performance_testing.md2
-rw-r--r--doc/user/project/merge_requests/resolve_conflicts.md9
-rw-r--r--doc/user/project/merge_requests/squash_and_merge.md2
-rw-r--r--doc/user/project/merge_requests/test_coverage_visualization.md7
-rw-r--r--doc/user/project/pages/custom_domains_ssl_tls_certification/dns_concepts.md2
-rw-r--r--doc/user/project/pages/custom_domains_ssl_tls_certification/index.md2
-rw-r--r--doc/user/project/pages/custom_domains_ssl_tls_certification/lets_encrypt_integration.md2
-rw-r--r--doc/user/project/pages/getting_started_part_one.md2
-rw-r--r--doc/user/project/pages/introduction.md22
-rw-r--r--doc/user/project/pages/lets_encrypt_for_gitlab_pages.md4
-rw-r--r--doc/user/project/pages/redirects.md8
-rw-r--r--doc/user/project/protected_branches.md37
-rw-r--r--doc/user/project/protected_tags.md12
-rw-r--r--doc/user/project/quick_actions.md45
-rw-r--r--doc/user/project/releases/index.md88
-rw-r--r--doc/user/project/repository/branches/default.md74
-rw-r--r--doc/user/project/repository/forking_workflow.md67
-rw-r--r--doc/user/project/repository/gpg_signed_commits/img/profile_settings_gpg_keys_paste_pub.pngbin13008 -> 0 bytes
-rw-r--r--doc/user/project/repository/gpg_signed_commits/index.md335
-rw-r--r--doc/user/project/repository/img/fork_form_v13_10.pngbin40932 -> 0 bytes
-rw-r--r--doc/user/project/repository/img/forking_workflow_choose_namespace_v13_10.pngbin18552 -> 0 bytes
-rw-r--r--doc/user/project/repository/jupyter_notebooks/index.md7
-rw-r--r--doc/user/project/repository/mirror/index.md4
-rw-r--r--doc/user/project/repository/mirror/push.md2
-rw-r--r--doc/user/project/repository/reducing_the_repo_size_using_git.md37
-rw-r--r--doc/user/project/repository/x509_signed_commits/index.md6
-rw-r--r--doc/user/project/requirements/index.md12
-rw-r--r--doc/user/project/service_desk.md46
-rw-r--r--doc/user/project/settings/import_export.md25
-rw-r--r--doc/user/project/settings/index.md6
-rw-r--r--doc/user/project/settings/project_access_tokens.md5
-rw-r--r--doc/user/project/static_site_editor/index.md48
-rw-r--r--doc/user/project/web_ide/index.md32
-rw-r--r--doc/user/project/wiki/group.md6
-rw-r--r--doc/user/project/working_with_projects.md79
-rw-r--r--doc/user/reserved_names.md11
-rw-r--r--doc/user/search/advanced_search.md6
-rw-r--r--doc/user/search/img/code_search.pngbin113383 -> 0 bytes
-rw-r--r--doc/user/search/img/code_search_git_blame_v14_9.pngbin0 -> 40505 bytes
-rw-r--r--doc/user/search/index.md35
-rw-r--r--doc/user/shortcuts.md140
-rw-r--r--doc/user/snippets.md17
-rw-r--r--doc/user/tasks.md2
-rw-r--r--doc/user/todos.md25
-rw-r--r--doc/user/usage_quotas.md7
-rw-r--r--doc/user/workspace/index.md2
-rw-r--r--docker/README.md3
-rw-r--r--fixtures/emojis/aliases.json4
-rw-r--r--jest.config.base.js2
-rw-r--r--lefthook.yml4
-rw-r--r--lib/api/admin/instance_clusters.rb5
-rw-r--r--lib/api/broadcast_messages.rb4
-rw-r--r--lib/api/ci/jobs.rb25
-rw-r--r--lib/api/ci/pipelines.rb10
-rw-r--r--lib/api/ci/runner.rb23
-rw-r--r--lib/api/ci/runners.rb10
-rw-r--r--lib/api/ci/secure_files.rb63
-rw-r--r--lib/api/commits.rb2
-rw-r--r--lib/api/concerns/packages/conan_endpoints.rb5
-rw-r--r--lib/api/container_repositories.rb8
-rw-r--r--lib/api/deploy_tokens.rb30
-rw-r--r--lib/api/entities/broadcast_message.rb2
-rw-r--r--lib/api/entities/ci/runner.rb4
-rw-r--r--lib/api/entities/ci/secure_file.rb1
-rw-r--r--lib/api/entities/container_registry.rb1
-rw-r--r--lib/api/entities/error_tracking.rb6
-rw-r--r--lib/api/entities/issuable_time_stats.rb2
-rw-r--r--lib/api/entities/label_basic.rb6
-rw-r--r--lib/api/entities/project.rb1
-rw-r--r--lib/api/entities/project_integration.rb15
-rw-r--r--lib/api/entities/user_safe.rb9
-rw-r--r--lib/api/entities/wiki_page.rb10
-rw-r--r--lib/api/error_tracking/collector.rb4
-rw-r--r--lib/api/generic_packages.rb6
-rw-r--r--lib/api/group_clusters.rb9
-rw-r--r--lib/api/helpers.rb17
-rw-r--r--lib/api/helpers/integrations_helpers.rb27
-rw-r--r--lib/api/helpers/projects_helpers.rb4
-rw-r--r--lib/api/helpers/wikis_helpers.rb4
-rw-r--r--lib/api/internal/base.rb6
-rw-r--r--lib/api/internal/kubernetes.rb1
-rw-r--r--lib/api/issues.rb17
-rw-r--r--lib/api/merge_requests.rb10
-rw-r--r--lib/api/notes.rb4
-rw-r--r--lib/api/package_files.rb2
-rw-r--r--lib/api/project_clusters.rb9
-rw-r--r--lib/api/project_import.rb82
-rw-r--r--lib/api/project_snippets.rb13
-rw-r--r--lib/api/pypi_packages.rb2
-rw-r--r--lib/api/repositories.rb2
-rw-r--r--lib/api/search.rb2
-rw-r--r--lib/api/snippets.rb13
-rw-r--r--lib/api/statistics.rb2
-rw-r--r--lib/api/system_hooks.rb12
-rw-r--r--lib/api/topics.rb14
-rw-r--r--lib/api/user_counts.rb8
-rw-r--r--lib/api/users.rb31
-rw-r--r--lib/api/validations/validators/file_path.rb3
-rw-r--r--lib/api/wikis.rb4
-rw-r--r--lib/atlassian/jira_connect.rb5
-rw-r--r--lib/atlassian/jira_connect/client.rb23
-rw-r--r--lib/atlassian/jira_connect/serializers/build_entity.rb2
-rw-r--r--lib/atlassian/jira_connect/serializers/environment_entity.rb13
-rw-r--r--lib/backup/artifacts.rb7
-rw-r--r--lib/backup/builds.rb7
-rw-r--r--lib/backup/database.rb77
-rw-r--r--lib/backup/files.rb27
-rw-r--r--lib/backup/gitaly_backup.rb18
-rw-r--r--lib/backup/gitaly_rpc_backup.rb9
-rw-r--r--lib/backup/lfs.rb7
-rw-r--r--lib/backup/manager.rb257
-rw-r--r--lib/backup/packages.rb7
-rw-r--r--lib/backup/pages.rb7
-rw-r--r--lib/backup/registry.rb8
-rw-r--r--lib/backup/repositories.rb24
-rw-r--r--lib/backup/task.rb46
-rw-r--r--lib/backup/terraform_state.rb7
-rw-r--r--lib/backup/uploads.rb7
-rw-r--r--lib/banzai/filter/front_matter_filter.rb5
-rw-r--r--lib/banzai/filter/image_link_filter.rb14
-rw-r--r--lib/banzai/filter/task_list_filter.rb3
-rw-r--r--lib/bulk_imports/clients/http.rb2
-rw-r--r--lib/container_registry/client.rb19
-rw-r--r--lib/container_registry/gitlab_api_client.rb45
-rw-r--r--lib/container_registry/registry.rb16
-rw-r--r--lib/container_registry/tag.rb2
-rw-r--r--lib/gitlab.rb16
-rw-r--r--lib/gitlab/analytics/cycle_analytics/request_params.rb21
-rw-r--r--lib/gitlab/application_rate_limiter.rb3
-rw-r--r--lib/gitlab/auth/auth_finders.rb1
-rw-r--r--lib/gitlab/auth/ldap/user.rb7
-rw-r--r--lib/gitlab/auth/o_auth/auth_hash.rb1
-rw-r--r--lib/gitlab/auth/o_auth/user.rb11
-rw-r--r--lib/gitlab/auth/request_authenticator.rb4
-rw-r--r--lib/gitlab/auth/saml/user.rb8
-rw-r--r--lib/gitlab/background_migration/backfill_issue_search_data.rb63
-rw-r--r--lib/gitlab/background_migration/backfill_jira_tracker_deployment_type2.rb2
-rw-r--r--lib/gitlab/background_migration/backfill_member_namespace_for_group_members.rb38
-rw-r--r--lib/gitlab/background_migration/batching_strategies/base_strategy.rb26
-rw-r--r--lib/gitlab/background_migration/batching_strategies/primary_key_batching_strategy.rb4
-rw-r--r--lib/gitlab/background_migration/encrypt_integration_properties.rb84
-rw-r--r--lib/gitlab/background_migration/fix_vulnerability_occurrences_with_hashes_as_raw_metadata.rb2
-rw-r--r--lib/gitlab/background_migration/job_coordinator.rb35
-rw-r--r--lib/gitlab/background_migration/migrate_personal_namespace_project_maintainer_to_owner.rb45
-rw-r--r--lib/gitlab/background_migration/nullify_orphan_runner_id_on_ci_builds.rb40
-rw-r--r--lib/gitlab/background_migration/project_namespaces/backfill_project_namespaces.rb15
-rw-r--r--lib/gitlab/background_migration/remove_all_trace_expiration_dates.rb53
-rw-r--r--lib/gitlab/background_migration/reset_duplicate_ci_runners_token_encrypted_values_on_projects.rb37
-rw-r--r--lib/gitlab/background_migration/reset_duplicate_ci_runners_token_values_on_projects.rb37
-rw-r--r--lib/gitlab/checks/base_bulk_checker.rb1
-rw-r--r--lib/gitlab/checks/base_single_checker.rb1
-rw-r--r--lib/gitlab/ci/build/policy/refs.rb2
-rw-r--r--lib/gitlab/ci/config/entry/job.rb8
-rw-r--r--lib/gitlab/ci/config/entry/policy.rb4
-rw-r--r--lib/gitlab/ci/config/entry/reports.rb16
-rw-r--r--lib/gitlab/ci/config/entry/reports/coverage_report.rb31
-rw-r--r--lib/gitlab/ci/config/entry/rules/rule.rb2
-rw-r--r--lib/gitlab/ci/config/entry/trigger.rb27
-rw-r--r--lib/gitlab/ci/config/entry/trigger/forward.rb32
-rw-r--r--lib/gitlab/ci/config/external/file/local.rb4
-rw-r--r--lib/gitlab/ci/config/yaml/tags/reference.rb8
-rw-r--r--lib/gitlab/ci/parsers/coverage/cobertura.rb134
-rw-r--r--lib/gitlab/ci/parsers/coverage/sax_document.rb110
-rw-r--r--lib/gitlab/ci/parsers/security/common.rb32
-rw-r--r--lib/gitlab/ci/parsers/security/validators/schema_validator.rb61
-rw-r--r--lib/gitlab/ci/pipeline/chain/create.rb10
-rw-r--r--lib/gitlab/ci/pipeline/logger.rb1
-rw-r--r--lib/gitlab/ci/reports/security/evidence.rb17
-rw-r--r--lib/gitlab/ci/reports/security/finding.rb5
-rw-r--r--lib/gitlab/ci/reports/security/report.rb7
-rw-r--r--lib/gitlab/ci/reports/test_suite_comparer.rb2
-rw-r--r--lib/gitlab/ci/status/build/waiting_for_approval.rb28
-rw-r--r--lib/gitlab/ci/templates/Android-Fastlane.gitlab-ci.yml23
-rw-r--r--lib/gitlab/ci/templates/Dart.gitlab-ci.yml2
-rw-r--r--lib/gitlab/ci/templates/Flutter.gitlab-ci.yml4
-rw-r--r--lib/gitlab/ci/templates/Go.gitlab-ci.yml6
-rw-r--r--lib/gitlab/ci/templates/Gradle.gitlab-ci.yml3
-rw-r--r--lib/gitlab/ci/templates/Grails.gitlab-ci.yml6
-rw-r--r--lib/gitlab/ci/templates/Jobs/Browser-Performance-Testing.gitlab-ci.yml12
-rw-r--r--lib/gitlab/ci/templates/Jobs/Browser-Performance-Testing.latest.gitlab-ci.yml9
-rw-r--r--lib/gitlab/ci/templates/Jobs/Build.gitlab-ci.yml4
-rw-r--r--lib/gitlab/ci/templates/Jobs/Build.latest.gitlab-ci.yml4
-rw-r--r--lib/gitlab/ci/templates/Jobs/Code-Quality.gitlab-ci.yml7
-rw-r--r--lib/gitlab/ci/templates/Jobs/DAST-Default-Branch-Deploy.gitlab-ci.yml2
-rw-r--r--lib/gitlab/ci/templates/Jobs/Dependency-Scanning.gitlab-ci.yml2
-rw-r--r--lib/gitlab/ci/templates/Jobs/Deploy.gitlab-ci.yml2
-rw-r--r--lib/gitlab/ci/templates/Jobs/Deploy.latest.gitlab-ci.yml2
-rw-r--r--lib/gitlab/ci/templates/Jobs/License-Scanning.gitlab-ci.yml2
-rw-r--r--lib/gitlab/ci/templates/Jobs/Load-Performance-Testing.gitlab-ci.yml7
-rw-r--r--lib/gitlab/ci/templates/Jobs/SAST-IaC.latest.gitlab-ci.yml2
-rw-r--r--lib/gitlab/ci/templates/Jobs/SAST.gitlab-ci.yml2
-rw-r--r--lib/gitlab/ci/templates/Jobs/Secret-Detection.gitlab-ci.yml53
-rw-r--r--lib/gitlab/ci/templates/Pages/HTML.gitlab-ci.yml2
-rw-r--r--lib/gitlab/ci/templates/Python.gitlab-ci.yml3
-rw-r--r--lib/gitlab/ci/templates/Ruby.gitlab-ci.yml2
-rw-r--r--lib/gitlab/ci/templates/Security/API-Fuzzing.gitlab-ci.yml2
-rw-r--r--lib/gitlab/ci/templates/Security/API-Fuzzing.latest.gitlab-ci.yml2
-rw-r--r--lib/gitlab/ci/templates/Security/DAST-API.gitlab-ci.yml2
-rw-r--r--lib/gitlab/ci/templates/Security/DAST-API.latest.gitlab-ci.yml2
-rw-r--r--lib/gitlab/ci/templates/Security/DAST-On-Demand-API-Scan.gitlab-ci.yml2
-rw-r--r--lib/gitlab/ci/templates/Security/DAST-On-Demand-Scan.gitlab-ci.yml2
-rw-r--r--lib/gitlab/ci/templates/Security/DAST.gitlab-ci.yml2
-rw-r--r--lib/gitlab/ci/templates/Security/DAST.latest.gitlab-ci.yml2
-rw-r--r--lib/gitlab/ci/templates/Security/Secure-Binaries.gitlab-ci.yml7
-rw-r--r--lib/gitlab/ci/templates/Terraform/Base.gitlab-ci.yml10
-rw-r--r--lib/gitlab/ci/templates/Verify/Accessibility.gitlab-ci.yml3
-rw-r--r--lib/gitlab/ci/templates/Verify/Browser-Performance.gitlab-ci.yml2
-rw-r--r--lib/gitlab/ci/templates/Verify/Browser-Performance.latest.gitlab-ci.yml2
-rw-r--r--lib/gitlab/ci/trace/remote_checksum.rb1
-rw-r--r--lib/gitlab/ci/variables/builder.rb33
-rw-r--r--lib/gitlab/ci/variables/builder/group.rb48
-rw-r--r--lib/gitlab/ci/yaml_processor.rb13
-rw-r--r--lib/gitlab/ci/yaml_processor/dag.rb18
-rw-r--r--lib/gitlab/color.rb222
-rw-r--r--lib/gitlab/config/entry/validators.rb40
-rw-r--r--lib/gitlab/content_security_policy/config_loader.rb2
-rw-r--r--lib/gitlab/content_security_policy/directives.rb4
-rw-r--r--lib/gitlab/current_settings.rb2
-rw-r--r--lib/gitlab/cycle_analytics/summary/base.rb18
-rw-r--r--lib/gitlab/cycle_analytics/summary/defaults.rb29
-rw-r--r--lib/gitlab/database.rb30
-rw-r--r--lib/gitlab/database/async_indexes/migration_helpers.rb9
-rw-r--r--lib/gitlab/database/background_migration/batched_job.rb29
-rw-r--r--lib/gitlab/database/background_migration/batched_job_transition_log.rb2
-rw-r--r--lib/gitlab/database/background_migration/batched_migration.rb2
-rw-r--r--lib/gitlab/database/background_migration/batched_migration_runner.rb11
-rw-r--r--lib/gitlab/database/count/exact_count_strategy.rb1
-rw-r--r--lib/gitlab/database/count/reltuples_count_strategy.rb3
-rw-r--r--lib/gitlab/database/each_database.rb37
-rw-r--r--lib/gitlab/database/gitlab_schema.rb4
-rw-r--r--lib/gitlab/database/gitlab_schemas.yml6
-rw-r--r--lib/gitlab/database/load_balancing.rb2
-rw-r--r--lib/gitlab/database/load_balancing/configuration.rb4
-rw-r--r--lib/gitlab/database/load_balancing/setup.rb3
-rw-r--r--lib/gitlab/database/migration_helpers/restrict_gitlab_schema.rb58
-rw-r--r--lib/gitlab/database/migrations/background_migration_helpers.rb2
-rw-r--r--lib/gitlab/database/migrations/instrumentation.rb6
-rw-r--r--lib/gitlab/database/migrations/observers/query_details.rb2
-rw-r--r--lib/gitlab/database/migrations/observers/query_log.rb2
-rw-r--r--lib/gitlab/database/migrations/observers/transaction_duration.rb2
-rw-r--r--lib/gitlab/database/migrations/runner.rb10
-rw-r--r--lib/gitlab/database/migrations/test_background_runner.rb49
-rw-r--r--lib/gitlab/database/partitioning.rb4
-rw-r--r--lib/gitlab/database/partitioning/partition_manager.rb1
-rw-r--r--lib/gitlab/database/partitioning/replace_table.rb1
-rw-r--r--lib/gitlab/database/query_analyzer.rb20
-rw-r--r--lib/gitlab/database/query_analyzers/prevent_cross_database_modification.rb2
-rw-r--r--lib/gitlab/database/query_analyzers/restrict_allowed_schemas.rb106
-rw-r--r--lib/gitlab/database/transaction/context.rb37
-rw-r--r--lib/gitlab/database/transaction/observer.rb1
-rw-r--r--lib/gitlab/database/type/color.rb21
-rw-r--r--lib/gitlab/diff/custom_diff.rb12
-rw-r--r--lib/gitlab/diff/file.rb26
-rw-r--r--lib/gitlab/diff/file_collection/base.rb11
-rw-r--r--lib/gitlab/diff/file_collection/merge_request_diff_base.rb9
-rw-r--r--lib/gitlab/diff/line.rb9
-rw-r--r--lib/gitlab/diff/rendered/notebook/diff_file.rb126
-rw-r--r--lib/gitlab/email/attachment_uploader.rb10
-rw-r--r--lib/gitlab/email/handler/service_desk_handler.rb22
-rw-r--r--lib/gitlab/email/html_parser.rb1
-rw-r--r--lib/gitlab/email/receiver.rb26
-rw-r--r--lib/gitlab/error_tracking.rb61
-rw-r--r--lib/gitlab/error_tracking/processor/grpc_error_processor.rb20
-rw-r--r--lib/gitlab/etag_caching/middleware.rb5
-rw-r--r--lib/gitlab/etag_caching/router.rb19
-rw-r--r--lib/gitlab/etag_caching/router/rails.rb126
-rw-r--r--lib/gitlab/etag_caching/router/restful.rb112
-rw-r--r--lib/gitlab/experiment/rollout/feature.rb15
-rw-r--r--lib/gitlab/experimentation.rb4
-rw-r--r--lib/gitlab/experimentation/controller_concern.rb2
-rw-r--r--lib/gitlab/experimentation/experiment.rb2
-rw-r--r--lib/gitlab/fips.rb25
-rw-r--r--lib/gitlab/form_builders/gitlab_ui_form_builder.rb4
-rw-r--r--lib/gitlab/front_matter.rb6
-rw-r--r--lib/gitlab/git/blame.rb1
-rw-r--r--lib/gitlab/git/repository.rb4
-rw-r--r--lib/gitlab/git/wiki.rb8
-rw-r--r--lib/gitlab/git_access_snippet.rb5
-rw-r--r--lib/gitlab/gitaly_client.rb2
-rw-r--r--lib/gitlab/gitaly_client/commit_service.rb2
-rw-r--r--lib/gitlab/gitaly_client/operation_service.rb81
-rw-r--r--lib/gitlab/gitaly_client/repository_service.rb14
-rw-r--r--lib/gitlab/gitaly_client/wiki_service.rb5
-rw-r--r--lib/gitlab/github_import/importer/diff_note_importer.rb8
-rw-r--r--lib/gitlab/github_import/importer/pull_requests_importer.rb4
-rw-r--r--lib/gitlab/github_import/parallel_scheduling.rb41
-rw-r--r--lib/gitlab/gon_helper.rb5
-rw-r--r--lib/gitlab/graphql/batch_key.rb1
-rw-r--r--lib/gitlab/graphql/loaders/batch_commit_loader.rb40
-rw-r--r--lib/gitlab/graphql/pagination/keyset/generic_keyset_pagination.rb8
-rw-r--r--lib/gitlab/harbor/client.rb43
-rw-r--r--lib/gitlab/health_checks/db_check.rb6
-rw-r--r--lib/gitlab/highlight.rb43
-rw-r--r--lib/gitlab/hook_data/issuable_builder.rb2
-rw-r--r--lib/gitlab/hook_data/issue_builder.rb21
-rw-r--r--lib/gitlab/hook_data/merge_request_builder.rb14
-rw-r--r--lib/gitlab/http_connection_adapter.rb7
-rw-r--r--lib/gitlab/i18n.rb16
-rw-r--r--lib/gitlab/import_export/base/relation_factory.rb2
-rw-r--r--lib/gitlab/import_export/base/relation_object_saver.rb109
-rw-r--r--lib/gitlab/import_export/command_line_util.rb29
-rw-r--r--lib/gitlab/import_export/file_importer.rb12
-rw-r--r--lib/gitlab/import_export/group/object_builder.rb9
-rw-r--r--lib/gitlab/import_export/group/relation_tree_restorer.rb24
-rw-r--r--lib/gitlab/import_export/json/streaming_serializer.rb2
-rw-r--r--lib/gitlab/import_export/project/import_export.yml1
-rw-r--r--lib/gitlab/insecure_key_fingerprint.rb1
-rw-r--r--lib/gitlab/integrations/sti_type.rb2
-rw-r--r--lib/gitlab/json.rb20
-rw-r--r--lib/gitlab/json_cache.rb24
-rw-r--r--lib/gitlab/kubernetes/kubeconfig/template.rb38
-rw-r--r--lib/gitlab/language_detection.rb2
-rw-r--r--lib/gitlab/mail_room.rb10
-rw-r--r--lib/gitlab/mail_room/authenticator.rb7
-rw-r--r--lib/gitlab/merge_requests/commit_message_generator.rb13
-rw-r--r--lib/gitlab/merge_requests/mergeability/check_result.rb4
-rw-r--r--lib/gitlab/merge_requests/mergeability/results_store.rb6
-rw-r--r--lib/gitlab/metrics/dashboard/stages/cluster_endpoint_inserter.rb2
-rw-r--r--lib/gitlab/metrics/subscribers/active_record.rb20
-rw-r--r--lib/gitlab/omniauth_initializer.rb26
-rw-r--r--lib/gitlab/pages/settings.rb2
-rw-r--r--lib/gitlab/pagination/gitaly_keyset_pager.rb1
-rw-r--r--lib/gitlab/pagination/keyset/cursor_based_request_context.rb1
-rw-r--r--lib/gitlab/pagination/keyset/header_builder.rb1
-rw-r--r--lib/gitlab/pagination/offset_pagination.rb3
-rw-r--r--lib/gitlab/patch/action_cable_redis_listener.rb26
-rw-r--r--lib/gitlab/path_regex.rb2
-rw-r--r--lib/gitlab/performance_bar/stats.rb6
-rw-r--r--lib/gitlab/process_supervisor.rb149
-rw-r--r--lib/gitlab/profiler.rb25
-rw-r--r--lib/gitlab/project_authorizations.rb2
-rw-r--r--lib/gitlab/prometheus/queries/base_query.rb1
-rw-r--r--lib/gitlab/quick_actions/issue_actions.rb4
-rw-r--r--lib/gitlab/quick_actions/merge_request_actions.rb10
-rw-r--r--lib/gitlab/regex.rb18
-rw-r--r--lib/gitlab/runtime.rb11
-rw-r--r--lib/gitlab/safe_request_loader.rb55
-rw-r--r--lib/gitlab/sanitizers/exif.rb29
-rw-r--r--lib/gitlab/seeder.rb37
-rw-r--r--lib/gitlab/sidekiq_middleware.rb2
-rw-r--r--lib/gitlab/sidekiq_middleware/duplicate_jobs/duplicate_job.rb7
-rw-r--r--lib/gitlab/sidekiq_middleware/server_metrics.rb16
-rw-r--r--lib/gitlab/sidekiq_middleware/size_limiter/validator.rb7
-rw-r--r--lib/gitlab/untrusted_regexp.rb10
-rw-r--r--lib/gitlab/untrusted_regexp/ruby_syntax.rb38
-rw-r--r--lib/gitlab/url_blocker.rb40
-rw-r--r--lib/gitlab/usage/metric_definition.rb4
-rw-r--r--lib/gitlab/usage/metrics/instrumentations/cert_based_clusters_ff_metric.rb15
-rw-r--r--lib/gitlab/usage/metrics/instrumentations/database_metric.rb7
-rw-r--r--lib/gitlab/usage/service_ping/instrumented_payload.rb41
-rw-r--r--lib/gitlab/usage/service_ping/payload_keys_processor.rb54
-rw-r--r--lib/gitlab/usage/service_ping_report.rb19
-rw-r--r--lib/gitlab/usage_data.rb12
-rw-r--r--lib/gitlab/usage_data_counters.rb3
-rw-r--r--lib/gitlab/usage_data_counters/hll_redis_counter.rb1
-rw-r--r--lib/gitlab/usage_data_counters/known_events/ci_users.yml5
-rw-r--r--lib/gitlab/usage_data_counters/known_events/common.yml1
-rw-r--r--lib/gitlab/usage_data_counters/known_events/error_tracking.yml11
-rw-r--r--lib/gitlab/usage_data_counters/known_events/quickactions.yml4
-rw-r--r--lib/gitlab/usage_data_counters/known_events/work_items.yml11
-rw-r--r--lib/gitlab/usage_data_counters/service_usage_data_counter.rb8
-rw-r--r--lib/gitlab/usage_data_counters/work_item_activity_unique_counter.rb28
-rw-r--r--lib/gitlab/usage_data_queries.rb10
-rw-r--r--lib/gitlab/utils.rb12
-rw-r--r--lib/gitlab/utils/strong_memoize.rb22
-rw-r--r--lib/gitlab/wiki_pages/front_matter_parser.rb20
-rw-r--r--lib/google_api/cloud_platform/client.rb8
-rw-r--r--lib/learn_gitlab/onboarding.rb16
-rw-r--r--lib/peek/views/active_record.rb8
-rw-r--r--lib/peek/views/detailed_view.rb2
-rw-r--r--lib/security/ci_configuration/base_build_action.rb5
-rw-r--r--lib/security/ci_configuration/sast_build_action.rb4
-rw-r--r--lib/serializers/unsafe_json.rb13
-rw-r--r--lib/sidebars/concerns/work_item_hierarchy.rb26
-rw-r--r--lib/sidebars/groups/menus/ci_cd_menu.rb2
-rw-r--r--lib/sidebars/groups/menus/customer_relations_menu.rb2
-rw-r--r--lib/sidebars/groups/menus/kubernetes_menu.rb5
-rw-r--r--lib/sidebars/groups/menus/packages_registries_menu.rb13
-rw-r--r--lib/sidebars/groups/menus/settings_menu.rb8
-rw-r--r--lib/sidebars/menu.rb1
-rw-r--r--lib/sidebars/projects/menus/infrastructure_menu.rb4
-rw-r--r--lib/sidebars/projects/menus/packages_registries_menu.rb13
-rw-r--r--lib/sidebars/projects/menus/project_information_menu.rb3
-rw-r--r--lib/spam/concerns/has_spam_action_response_fields.rb2
-rw-r--r--lib/tasks/ci/build_artifacts.rake20
-rw-r--r--lib/tasks/dev.rake6
-rw-r--r--lib/tasks/gitlab/background_migrations.rake113
-rw-r--r--lib/tasks/gitlab/db.rake106
-rw-r--r--lib/tasks/gitlab/docs/redirect.rake4
-rw-r--r--lib/tasks/gitlab/refresh_project_statistics_build_artifacts_size.rake23
-rw-r--r--lib/tasks/gitlab/setup.rake12
-rw-r--r--lib/tasks/gitlab/tw/codeowners.rake2
-rw-r--r--lib/tasks/rubocop.rake52
-rw-r--r--lib/tasks/tanuki_emoji.rake8
-rw-r--r--locale/am_ET/gitlab.po1534
-rw-r--r--locale/ar_SA/gitlab.po1570
-rw-r--r--locale/as_IN/gitlab.po1534
-rw-r--r--locale/az_AZ/gitlab.po1534
-rw-r--r--locale/ba_RU/gitlab.po1525
-rw-r--r--locale/bg/gitlab.po1536
-rw-r--r--locale/bn_BD/gitlab.po1534
-rw-r--r--locale/bn_IN/gitlab.po1534
-rw-r--r--locale/br_FR/gitlab.po1561
-rw-r--r--locale/bs_BA/gitlab.po1545
-rw-r--r--locale/ca_ES/gitlab.po1536
-rw-r--r--locale/cs_CZ/gitlab.po1552
-rw-r--r--locale/cy_GB/gitlab.po1570
-rw-r--r--locale/da_DK/gitlab.po1604
-rw-r--r--locale/de/gitlab.po1684
-rw-r--r--locale/el_GR/gitlab.po1534
-rw-r--r--locale/eo/gitlab.po1536
-rw-r--r--locale/es/gitlab.po2610
-rw-r--r--locale/et_EE/gitlab.po1534
-rw-r--r--locale/fa_IR/gitlab.po1534
-rw-r--r--locale/fi_FI/gitlab.po1534
-rw-r--r--locale/fil_PH/gitlab.po1534
-rw-r--r--locale/fr/gitlab.po1546
-rw-r--r--locale/gitlab.pot1629
-rw-r--r--locale/gl_ES/gitlab.po1534
-rw-r--r--locale/he_IL/gitlab.po1554
-rw-r--r--locale/hi_IN/gitlab.po1534
-rw-r--r--locale/hr_HR/gitlab.po1543
-rw-r--r--locale/hu_HU/gitlab.po1534
-rw-r--r--locale/hy_AM/gitlab.po1534
-rw-r--r--locale/id_ID/gitlab.po1525
-rw-r--r--locale/ig_NG/gitlab.po1525
-rw-r--r--locale/is_IS/gitlab.po1534
-rw-r--r--locale/it/gitlab.po1536
-rw-r--r--locale/ja/gitlab.po1571
-rw-r--r--locale/ka_GE/gitlab.po1534
-rw-r--r--locale/kab/gitlab.po1534
-rw-r--r--locale/ko/gitlab.po1547
-rw-r--r--locale/ku_TR/gitlab.po1534
-rw-r--r--locale/ky_KG/gitlab.po1534
-rw-r--r--locale/lt_LT/gitlab.po1552
-rw-r--r--locale/mk_MK/gitlab.po1534
-rw-r--r--locale/mn_MN/gitlab.po1534
-rw-r--r--locale/nb_NO/gitlab.po1598
-rw-r--r--locale/nl_NL/gitlab.po1536
-rw-r--r--locale/or_IN/gitlab.po1534
-rw-r--r--locale/pa_IN/gitlab.po1534
-rw-r--r--locale/pl_PL/gitlab.po1564
-rw-r--r--locale/pt_BR/gitlab.po1922
-rw-r--r--locale/pt_PT/gitlab.po1536
-rw-r--r--locale/ro_RO/gitlab.po1593
-rw-r--r--locale/ru/gitlab.po1734
-rw-r--r--locale/si_LK/gitlab.po3142
-rw-r--r--locale/sk_SK/gitlab.po1552
-rw-r--r--locale/sl_SI/gitlab.po1552
-rw-r--r--locale/sq_AL/gitlab.po1534
-rw-r--r--locale/sr_CS/gitlab.po1543
-rw-r--r--locale/sr_SP/gitlab.po1543
-rw-r--r--locale/sv_SE/gitlab.po1534
-rw-r--r--locale/sw_KE/gitlab.po1534
-rw-r--r--locale/ta_IN/gitlab.po1534
-rw-r--r--locale/tr_TR/gitlab.po1548
-rw-r--r--locale/uk/gitlab.po3192
-rw-r--r--locale/ur_PK/gitlab.po1534
-rw-r--r--locale/uz_UZ/gitlab.po1534
-rw-r--r--locale/vi_VN/gitlab.po1525
-rw-r--r--locale/zh_CN/gitlab.po2337
-rw-r--r--locale/zh_HK/gitlab.po1527
-rw-r--r--locale/zh_TW/gitlab.po1529
-rw-r--r--metrics_server/dependencies.rb1
-rw-r--r--metrics_server/metrics_server.rb23
-rw-r--r--package.json24
-rw-r--r--qa/Gemfile4
-rw-r--r--qa/Gemfile.lock66
-rw-r--r--qa/Rakefile23
-rw-r--r--qa/contracts/.gitignore2
-rw-r--r--qa/contracts/consumer/.node-version1
-rw-r--r--qa/contracts/consumer/endpoints/merge_request.js42
-rw-r--r--qa/contracts/consumer/fixtures/diffs.fixture.js89
-rw-r--r--qa/contracts/consumer/fixtures/discussions.fixture.js85
-rw-r--r--qa/contracts/consumer/fixtures/metadata.fixture.js96
-rw-r--r--qa/contracts/consumer/package.json17
-rw-r--r--qa/contracts/consumer/specs/diffs.spec.js35
-rw-r--r--qa/contracts/consumer/specs/discussions.spec.js35
-rw-r--r--qa/contracts/consumer/specs/metadata.spec.js35
-rw-r--r--qa/contracts/contracts/merge_request_page-merge_request_diffs_endpoint.json228
-rw-r--r--qa/contracts/contracts/merge_request_page-merge_request_discussions_endpoint.json235
-rw-r--r--qa/contracts/contracts/merge_request_page-merge_request_metadata_endpoint.json222
-rw-r--r--qa/contracts/provider/environments/base.rb24
-rw-r--r--qa/contracts/provider/environments/local.rb12
-rw-r--r--qa/contracts/provider/spec/diffs_helper.rb17
-rw-r--r--qa/contracts/provider/spec/discussions_helper.rb17
-rw-r--r--qa/contracts/provider/spec/metadata_helper.rb17
-rw-r--r--qa/contracts/provider/spec_helper.rb22
-rw-r--r--qa/knapsack/master_report.json1
-rw-r--r--qa/qa.rb9
-rw-r--r--qa/qa/git/location.rb1
-rw-r--r--qa/qa/page/component/new_snippet.rb5
-rw-r--r--qa/qa/page/component/snippet.rb4
-rw-r--r--qa/qa/page/dashboard/projects.rb14
-rw-r--r--qa/qa/page/dashboard/snippet/edit.rb5
-rw-r--r--qa/qa/page/dashboard/snippet/show.rb2
-rw-r--r--qa/qa/page/file/show.rb13
-rw-r--r--qa/qa/page/group/settings/general.rb10
-rw-r--r--qa/qa/page/main/login.rb5
-rw-r--r--qa/qa/page/merge_request/show.rb8
-rw-r--r--qa/qa/page/modal/delete_issue.rb17
-rw-r--r--qa/qa/page/project/fork/new.rb14
-rw-r--r--qa/qa/page/project/infrastructure/kubernetes/add.rb21
-rw-r--r--qa/qa/page/project/issue/show.rb16
-rw-r--r--qa/qa/page/project/new.rb10
-rw-r--r--qa/qa/page/project/pipeline_editor/new.rb19
-rw-r--r--qa/qa/page/project/pipeline_editor/show.rb20
-rw-r--r--qa/qa/page/project/settings/mirroring_repositories.rb11
-rw-r--r--qa/qa/page/project/show.rb2
-rw-r--r--qa/qa/page/project/web_ide/edit.rb2
-rw-r--r--qa/qa/page/trials/new.rb2
-rw-r--r--qa/qa/page/trials/select.rb11
-rw-r--r--qa/qa/resource/api_fabricator.rb19
-rw-r--r--qa/qa/resource/deploy_key.rb42
-rw-r--r--qa/qa/resource/fork.rb2
-rw-r--r--qa/qa/resource/group.rb9
-rw-r--r--qa/qa/resource/group_base.rb20
-rw-r--r--qa/qa/resource/kubernetes_cluster/project_cluster.rb3
-rw-r--r--qa/qa/resource/project.rb36
-rw-r--r--qa/qa/resource/protected_branch.rb10
-rw-r--r--qa/qa/resource/reusable_collection.rb4
-rw-r--r--qa/qa/resource/reusable_group.rb2
-rw-r--r--qa/qa/resource/reusable_project.rb2
-rw-r--r--qa/qa/resource/runner.rb5
-rw-r--r--qa/qa/runtime/allure_report.rb2
-rw-r--r--qa/qa/runtime/api/client.rb21
-rw-r--r--qa/qa/runtime/env.rb17
-rw-r--r--qa/qa/runtime/logger.rb26
-rw-r--r--qa/qa/scenario/test/integration/object_storage_gcs.rb13
-rw-r--r--qa/qa/scenario/test/integration/registry_with_cdn.rb14
-rw-r--r--qa/qa/service/praefect_manager.rb37
-rw-r--r--qa/qa/specs/features/api/1_manage/import_github_repo_spec.rb55
-rw-r--r--qa/qa/specs/features/api/1_manage/import_large_github_repo_spec.rb243
-rw-r--r--qa/qa/specs/features/api/1_manage/migration/gitlab_migration_group_spec.rb41
-rw-r--r--qa/qa/specs/features/api/1_manage/migration/gitlab_migration_members_spec.rb74
-rw-r--r--qa/qa/specs/features/api/1_manage/migration/gitlab_migration_pipeline_spec.rb59
-rw-r--r--qa/qa/specs/features/api/1_manage/migration/gitlab_project_migration_common.rb16
-rw-r--r--qa/qa/specs/features/api/1_manage/rate_limits_spec.rb42
-rw-r--r--qa/qa/specs/features/api/1_manage/users_spec.rb2
-rw-r--r--qa/qa/specs/features/api/3_create/gitaly/praefect_dataloss_spec.rb47
-rw-r--r--qa/qa/specs/features/api/3_create/repository/files_spec.rb8
-rw-r--r--qa/qa/specs/features/api/4_verify/remove_runner_spec.rb36
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/group/transfer_group_spec.rb51
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/group/transfer_project_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/login/2fa_recovery_spec.rb1
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/login/log_in_with_2fa_spec.rb1
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/project/add_project_member_spec.rb6
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/project/import_github_repo_spec.rb6
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/project/invite_group_to_project_spec.rb9
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/project/personal_project_permissions_spec.rb98
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/project/protected_tags_spec.rb13
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/project/view_project_activity_spec.rb5
-rw-r--r--qa/qa/specs/features/browser_ui/1_manage/user/user_access_termination_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/2_plan/email/trigger_email_notification_spec.rb3
-rw-r--r--qa/qa/specs/features/browser_ui/2_plan/issue/check_mentions_for_xss_spec.rb4
-rw-r--r--qa/qa/specs/features/browser_ui/2_plan/issue/mentions_spec.rb4
-rw-r--r--qa/qa/specs/features/browser_ui/2_plan/issue/real_time_assignee_spec.rb12
-rw-r--r--qa/qa/specs/features/browser_ui/2_plan/milestone/assign_milestone_spec.rb4
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/repository/move_project_create_fork_spec.rb1
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/repository/push_mirroring_lfs_over_http_spec.rb7
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/repository/push_mirroring_over_http_spec.rb5
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/repository/push_over_ssh_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/repository/ssh_key_support_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/snippet/clone_push_pull_personal_snippet_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/snippet/clone_push_pull_project_snippet_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/snippet/create_personal_snippet_spec.rb4
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/snippet/create_personal_snippet_with_multiple_files_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/snippet/create_project_snippet_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/snippet/create_project_snippet_with_multiple_files_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/web_ide/open_fork_in_web_ide_spec.rb5
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/web_ide/web_terminal_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/pipeline/include_local_config_file_paths_with_wildcard_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/pipeline/pipeline_editor_can_create_merge_request_spec.rb53
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/pipeline/pipeline_editor_lint_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/4_verify/pipeline/run_pipeline_via_web_only_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/container_registry/container_registry_omnibus_spec.rb149
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/package_registry/maven/maven_group_level_spec.rb314
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/package_registry/maven/maven_project_level_spec.rb219
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/package_registry/maven_repository_spec.rb233
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/package_registry/nuget/nuget_group_level_spec.rb182
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/package_registry/nuget/nuget_project_level_spec.rb164
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/package_registry/nuget_repository_spec.rb182
-rw-r--r--qa/qa/specs/features/browser_ui/6_release/deploy_key/add_deploy_key_spec.rb4
-rw-r--r--qa/qa/specs/features/browser_ui/6_release/deploy_key/clone_using_deploy_key_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/7_configure/auto_devops/auto_devops_templates_spec.rb2
-rw-r--r--qa/qa/specs/features/browser_ui/7_configure/auto_devops/create_project_with_auto_devops_spec.rb10
-rw-r--r--qa/qa/specs/runner.rb4
-rw-r--r--qa/qa/support/dates.rb4
-rw-r--r--qa/qa/support/formatters/allure_metadata_formatter.rb87
-rw-r--r--qa/qa/support/formatters/test_stats_formatter.rb86
-rw-r--r--qa/qa/support/influxdb_tools.rb83
-rw-r--r--qa/qa/support/loglinking.rb86
-rw-r--r--qa/qa/support/page_error_checker.rb18
-rw-r--r--qa/qa/support/repeater.rb5
-rw-r--r--qa/qa/tools/delete_test_resources.rb100
-rw-r--r--qa/qa/tools/delete_test_users.rb87
-rw-r--r--qa/qa/tools/reliable_report.rb30
-rw-r--r--qa/qa/tools/test_resource_data_processor.rb8
-rw-r--r--qa/qa/tools/test_resources_handler.rb180
-rw-r--r--qa/spec/page/logging_spec.rb19
-rw-r--r--qa/spec/resource/api_fabricator_spec.rb47
-rw-r--r--qa/spec/resource/reusable_collection_spec.rb22
-rw-r--r--qa/spec/runtime/env_spec.rb32
-rw-r--r--qa/spec/runtime/logger_spec.rb30
-rw-r--r--qa/spec/spec_helper.rb13
-rw-r--r--qa/spec/specs/allure_report_spec.rb5
-rw-r--r--qa/spec/support/formatters/allure_metadata_formatter_spec.rb3
-rw-r--r--qa/spec/support/formatters/test_stats_formatter_spec.rb20
-rw-r--r--qa/spec/support/loglinking_spec.rb185
-rw-r--r--qa/spec/support/page_error_checker_spec.rb66
-rw-r--r--qa/spec/support/repeater_spec.rb6
-rw-r--r--qa/spec/tools/reliable_report_spec.rb2
-rw-r--r--qa/spec/tools/test_resources_data_processor_spec.rb28
-rw-r--r--qa/tasks/contracts.rake47
-rw-r--r--rubocop/cop/database/multiple_databases.rb13
-rw-r--r--rubocop/cop/gitlab/avoid_uploaded_file_from_params.rb4
-rw-r--r--rubocop/cop/graphql/graphql_name_position.rb40
-rw-r--r--rubocop/formatter/todo_formatter.rb141
-rw-r--r--rubocop/todo_dir.rb81
-rwxr-xr-xscripts/generate-memory-metrics-on-boot29
-rw-r--r--scripts/gitlab_workhorse_component_helpers.sh73
-rwxr-xr-xscripts/ingest-reports-to-siem45
-rwxr-xr-xscripts/lint_templates_bash.rb76
-rwxr-xr-xscripts/merge-simplecov24
-rwxr-xr-xscripts/setup/find-jh-branch.rb2
-rwxr-xr-xscripts/trigger-build.rb4
-rw-r--r--scripts/utils.sh16
-rw-r--r--sidekiq_cluster/cli.rb109
-rw-r--r--sidekiq_cluster/sidekiq_cluster.rb10
-rw-r--r--spec/commands/sidekiq_cluster/cli_spec.rb216
-rw-r--r--spec/components/pajamas/component_spec.rb26
-rw-r--r--spec/components/pajamas/toggle_component_spec.rb107
-rw-r--r--spec/controllers/admin/application_settings_controller_spec.rb12
-rw-r--r--spec/controllers/admin/clusters_controller_spec.rb44
-rw-r--r--spec/controllers/admin/runner_projects_controller_spec.rb43
-rw-r--r--spec/controllers/admin/runners_controller_spec.rb2
-rw-r--r--spec/controllers/admin/topics_controller_spec.rb16
-rw-r--r--spec/controllers/application_controller_spec.rb18
-rw-r--r--spec/controllers/autocomplete_controller_spec.rb2
-rw-r--r--spec/controllers/boards/lists_controller_spec.rb4
-rw-r--r--spec/controllers/concerns/product_analytics_tracking_spec.rb171
-rw-r--r--spec/controllers/concerns/spammable_actions/akismet_mark_as_spam_action_spec.rb22
-rw-r--r--spec/controllers/concerns/spammable_actions/captcha_check/html_format_actions_support_spec.rb2
-rw-r--r--spec/controllers/concerns/spammable_actions/captcha_check/json_format_actions_support_spec.rb2
-rw-r--r--spec/controllers/concerns/spammable_actions/captcha_check/rest_api_actions_support_spec.rb86
-rw-r--r--spec/controllers/confirmations_controller_spec.rb2
-rw-r--r--spec/controllers/dashboard_controller_spec.rb55
-rw-r--r--spec/controllers/graphql_controller_spec.rb39
-rw-r--r--spec/controllers/groups/clusters_controller_spec.rb44
-rw-r--r--spec/controllers/groups/dependency_proxy_for_containers_controller_spec.rb22
-rw-r--r--spec/controllers/groups/group_members_controller_spec.rb118
-rw-r--r--spec/controllers/groups/releases_controller_spec.rb34
-rw-r--r--spec/controllers/groups/runners_controller_spec.rb38
-rw-r--r--spec/controllers/jira_connect/events_controller_spec.rb54
-rw-r--r--spec/controllers/passwords_controller_spec.rb2
-rw-r--r--spec/controllers/projects/blob_controller_spec.rb27
-rw-r--r--spec/controllers/projects/ci/pipeline_editor_controller_spec.rb12
-rw-r--r--spec/controllers/projects/ci/secure_files_controller_spec.rb49
-rw-r--r--spec/controllers/projects/clusters_controller_spec.rb44
-rw-r--r--spec/controllers/projects/environments_controller_spec.rb27
-rw-r--r--spec/controllers/projects/error_tracking_controller_spec.rb22
-rw-r--r--spec/controllers/projects/forks_controller_spec.rb9
-rw-r--r--spec/controllers/projects/incidents_controller_spec.rb1
-rw-r--r--spec/controllers/projects/issues_controller_spec.rb62
-rw-r--r--spec/controllers/projects/merge_requests/diffs_controller_spec.rb40
-rw-r--r--spec/controllers/projects/merge_requests_controller_spec.rb29
-rw-r--r--spec/controllers/projects/pipelines_controller_spec.rb35
-rw-r--r--spec/controllers/projects/project_members_controller_spec.rb224
-rw-r--r--spec/controllers/projects/releases_controller_spec.rb162
-rw-r--r--spec/controllers/projects/runners_controller_spec.rb2
-rw-r--r--spec/controllers/projects/serverless/functions_controller_spec.rb23
-rw-r--r--spec/controllers/projects/services_controller_spec.rb11
-rw-r--r--spec/controllers/projects/tags/releases_controller_spec.rb4
-rw-r--r--spec/controllers/projects/tags_controller_spec.rb2
-rw-r--r--spec/controllers/projects_controller_spec.rb71
-rw-r--r--spec/controllers/search_controller_spec.rb30
-rw-r--r--spec/controllers/sessions_controller_spec.rb6
-rw-r--r--spec/controllers/snippets_controller_spec.rb4
-rw-r--r--spec/db/schema_spec.rb2
-rw-r--r--spec/experiments/application_experiment_spec.rb77
-rw-r--r--spec/factories/analytics/cycle_analytics/aggregations.rb17
-rw-r--r--spec/factories/ci/reports/security/evidence.rb60
-rw-r--r--spec/factories/ci/reports/security/findings.rb49
-rw-r--r--spec/factories/customer_relations/issue_customer_relations_contacts.rb2
-rw-r--r--spec/factories/groups.rb9
-rw-r--r--spec/factories/integrations.rb63
-rw-r--r--spec/factories/merge_requests.rb4
-rw-r--r--spec/factories/project_hooks.rb4
-rw-r--r--spec/factories/projects.rb17
-rw-r--r--spec/factories/projects/build_artifacts_size_refreshes.rb27
-rw-r--r--spec/factories/releases.rb4
-rw-r--r--spec/factories/sequences.rb1
-rw-r--r--spec/factories/usage_data.rb28
-rw-r--r--spec/factories/users.rb8
-rw-r--r--spec/factories/users/saved_replies.rb10
-rw-r--r--spec/fast_spec_helper.rb3
-rw-r--r--spec/features/admin/admin_appearance_spec.rb2
-rw-r--r--spec/features/admin/admin_broadcast_messages_spec.rb27
-rw-r--r--spec/features/admin/admin_deploy_keys_spec.rb6
-rw-r--r--spec/features/admin/admin_groups_spec.rb2
-rw-r--r--spec/features/admin/admin_hook_logs_spec.rb2
-rw-r--r--spec/features/admin/admin_hooks_spec.rb10
-rw-r--r--spec/features/admin/admin_mode/login_spec.rb14
-rw-r--r--spec/features/admin/admin_mode/logout_spec.rb4
-rw-r--r--spec/features/admin/admin_projects_spec.rb34
-rw-r--r--spec/features/admin/admin_runners_spec.rb10
-rw-r--r--spec/features/admin/admin_sees_background_migrations_spec.rb8
-rw-r--r--spec/features/admin/admin_settings_spec.rb67
-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/eks_spec.rb6
-rw-r--r--spec/features/admin/users/user_spec.rb10
-rw-r--r--spec/features/admin/users/users_spec.rb12
-rw-r--r--spec/features/boards/board_filters_spec.rb2
-rw-r--r--spec/features/boards/boards_spec.rb90
-rw-r--r--spec/features/callouts/registration_enabled_spec.rb31
-rw-r--r--spec/features/clusters/cluster_detail_page_spec.rb14
-rw-r--r--spec/features/commits_spec.rb56
-rw-r--r--spec/features/dashboard/group_spec.rb2
-rw-r--r--spec/features/dashboard/issuables_counter_spec.rb80
-rw-r--r--spec/features/dashboard/milestones_spec.rb8
-rw-r--r--spec/features/dashboard/projects_spec.rb6
-rw-r--r--spec/features/dashboard/todos/todos_filtering_spec.rb2
-rw-r--r--spec/features/dashboard/todos/todos_spec.rb4
-rw-r--r--spec/features/dashboard/user_filters_projects_spec.rb10
-rw-r--r--spec/features/expand_collapse_diffs_spec.rb2
-rw-r--r--spec/features/explore/topics_spec.rb4
-rw-r--r--spec/features/file_uploads/user_avatar_spec.rb2
-rw-r--r--spec/features/global_search_spec.rb4
-rw-r--r--spec/features/groups/clusters/eks_spec.rb6
-rw-r--r--spec/features/groups/clusters/user_spec.rb12
-rw-r--r--spec/features/groups/container_registry_spec.rb2
-rw-r--r--spec/features/groups/group_settings_spec.rb50
-rw-r--r--spec/features/groups/issues_spec.rb16
-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/sort_labels_spec.rb4
-rw-r--r--spec/features/groups/members/leave_group_spec.rb8
-rw-r--r--spec/features/groups/members/manage_groups_spec.rb97
-rw-r--r--spec/features/groups/members/manage_members_spec.rb84
-rw-r--r--spec/features/groups/navbar_spec.rb25
-rw-r--r--spec/features/groups/settings/ci_cd_spec.rb18
-rw-r--r--spec/features/groups/settings/repository_spec.rb6
-rw-r--r--spec/features/groups/settings/user_searches_in_settings_spec.rb2
-rw-r--r--spec/features/groups_spec.rb77
-rw-r--r--spec/features/incidents/incident_details_spec.rb41
-rw-r--r--spec/features/incidents/incidents_list_spec.rb23
-rw-r--r--spec/features/incidents/user_views_incident_spec.rb8
-rw-r--r--spec/features/invites_spec.rb30
-rw-r--r--spec/features/issues/filtered_search/dropdown_assignee_spec.rb73
-rw-r--r--spec/features/issues/filtered_search/filter_issues_spec.rb10
-rw-r--r--spec/features/issues/form_spec.rb115
-rw-r--r--spec/features/issues/gfm_autocomplete_spec.rb22
-rw-r--r--spec/features/issues/incident_issue_spec.rb2
-rw-r--r--spec/features/issues/issue_detail_spec.rb4
-rw-r--r--spec/features/issues/issue_header_spec.rb8
-rw-r--r--spec/features/issues/issue_sidebar_spec.rb7
-rw-r--r--spec/features/issues/move_spec.rb2
-rw-r--r--spec/features/issues/spam_akismet_issue_creation_spec.rb178
-rw-r--r--spec/features/issues/spam_issues_spec.rb188
-rw-r--r--spec/features/issues/user_creates_branch_and_merge_request_spec.rb4
-rw-r--r--spec/features/issues/user_creates_issue_spec.rb4
-rw-r--r--spec/features/issues/user_sorts_issues_spec.rb8
-rw-r--r--spec/features/issues/user_views_issue_spec.rb2
-rw-r--r--spec/features/jira_connect/subscriptions_spec.rb11
-rw-r--r--spec/features/labels_hierarchy_spec.rb58
-rw-r--r--spec/features/markdown/copy_as_gfm_spec.rb9
-rw-r--r--spec/features/markdown/keyboard_shortcuts_spec.rb8
-rw-r--r--spec/features/markdown/sandboxed_mermaid_spec.rb2
-rw-r--r--spec/features/merge_request/user_edits_assignees_sidebar_spec.rb174
-rw-r--r--spec/features/merge_request/user_resolves_diff_notes_and_discussions_resolve_spec.rb8
-rw-r--r--spec/features/merge_request/user_sees_avatar_on_diff_notes_spec.rb1
-rw-r--r--spec/features/merge_request/user_sees_diff_spec.rb6
-rw-r--r--spec/features/merge_request/user_sees_merge_request_pipelines_spec.rb18
-rw-r--r--spec/features/merge_request/user_sees_merge_widget_spec.rb5
-rw-r--r--spec/features/merge_request/user_sees_mini_pipeline_graph_spec.rb2
-rw-r--r--spec/features/merge_request/user_sees_pipelines_spec.rb5
-rw-r--r--spec/features/merge_request/user_sees_suggest_pipeline_spec.rb3
-rw-r--r--spec/features/merge_requests/user_lists_merge_requests_spec.rb2
-rw-r--r--spec/features/milestones/user_views_milestones_spec.rb4
-rw-r--r--spec/features/oauth_login_spec.rb16
-rw-r--r--spec/features/password_reset_spec.rb8
-rw-r--r--spec/features/profiles/account_spec.rb8
-rw-r--r--spec/features/profiles/chat_names_spec.rb4
-rw-r--r--spec/features/profiles/password_spec.rb12
-rw-r--r--spec/features/profiles/user_visits_profile_preferences_page_spec.rb4
-rw-r--r--spec/features/profiles/user_visits_profile_spec.rb51
-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/blobs/blob_show_spec.rb618
-rw-r--r--spec/features/projects/blobs/edit_spec.rb2
-rw-r--r--spec/features/projects/blobs/user_views_pipeline_editor_button_spec.rb6
-rw-r--r--spec/features/projects/ci/editor_spec.rb10
-rw-r--r--spec/features/projects/ci/secure_files_spec.rb19
-rw-r--r--spec/features/projects/cluster_agents_spec.rb2
-rw-r--r--spec/features/projects/clusters/eks_spec.rb8
-rw-r--r--spec/features/projects/clusters/gcp_spec.rb26
-rw-r--r--spec/features/projects/clusters/user_spec.rb12
-rw-r--r--spec/features/projects/clusters_spec.rb36
-rw-r--r--spec/features/projects/commits/multi_view_diff_spec.rb85
-rw-r--r--spec/features/projects/container_registry_spec.rb2
-rw-r--r--spec/features/projects/environments/environment_metrics_spec.rb3
-rw-r--r--spec/features/projects/environments/environments_spec.rb86
-rw-r--r--spec/features/projects/files/project_owner_creates_license_file_spec.rb20
-rw-r--r--spec/features/projects/files/project_owner_sees_link_to_create_license_file_in_empty_project_spec.rb8
-rw-r--r--spec/features/projects/files/user_browses_files_spec.rb18
-rw-r--r--spec/features/projects/files/user_browses_lfs_files_spec.rb19
-rw-r--r--spec/features/projects/files/user_creates_directory_spec.rb6
-rw-r--r--spec/features/projects/files/user_creates_files_spec.rb10
-rw-r--r--spec/features/projects/files/user_deletes_files_spec.rb5
-rw-r--r--spec/features/projects/files/user_edits_files_spec.rb119
-rw-r--r--spec/features/projects/files/user_replaces_files_spec.rb11
-rw-r--r--spec/features/projects/fork_spec.rb195
-rw-r--r--spec/features/projects/integrations/user_activates_issue_tracker_spec.rb6
-rw-r--r--spec/features/projects/integrations/user_activates_jetbrains_teamcity_ci_spec.rb2
-rw-r--r--spec/features/projects/integrations/user_activates_jira_spec.rb6
-rw-r--r--spec/features/projects/integrations/user_activates_slack_slash_command_spec.rb4
-rw-r--r--spec/features/projects/jobs/user_browses_job_spec.rb7
-rw-r--r--spec/features/projects/jobs/user_browses_jobs_spec.rb2
-rw-r--r--spec/features/projects/jobs/user_triggers_manual_job_with_variables_spec.rb2
-rw-r--r--spec/features/projects/jobs_spec.rb18
-rw-r--r--spec/features/projects/labels/sort_labels_spec.rb4
-rw-r--r--spec/features/projects/members/group_members_spec.rb1
-rw-r--r--spec/features/projects/members/invite_group_spec.rb105
-rw-r--r--spec/features/projects/members/member_leaves_project_spec.rb4
-rw-r--r--spec/features/projects/members/user_requests_access_spec.rb6
-rw-r--r--spec/features/projects/navbar_spec.rb13
-rw-r--r--spec/features/projects/new_project_spec.rb72
-rw-r--r--spec/features/projects/pages/user_adds_domain_spec.rb2
-rw-r--r--spec/features/projects/pages/user_edits_lets_encrypt_settings_spec.rb4
-rw-r--r--spec/features/projects/pipeline_schedules_spec.rb12
-rw-r--r--spec/features/projects/pipelines/pipeline_spec.rb112
-rw-r--r--spec/features/projects/pipelines/pipelines_spec.rb130
-rw-r--r--spec/features/projects/releases/user_views_edit_release_spec.rb2
-rw-r--r--spec/features/projects/remote_mirror_spec.rb2
-rw-r--r--spec/features/projects/settings/registry_settings_spec.rb39
-rw-r--r--spec/features/projects/settings/user_interacts_with_deploy_keys_spec.rb4
-rw-r--r--spec/features/projects/settings/user_manages_project_members_spec.rb23
-rw-r--r--spec/features/projects/settings/user_renames_a_project_spec.rb6
-rw-r--r--spec/features/projects/settings/user_transfers_a_project_spec.rb6
-rw-r--r--spec/features/projects/settings/webhooks_settings_spec.rb4
-rw-r--r--spec/features/projects/show/redirects_spec.rb8
-rw-r--r--spec/features/projects/show/user_interacts_with_stars_spec.rb2
-rw-r--r--spec/features/projects/show/user_sees_git_instructions_spec.rb2
-rw-r--r--spec/features/projects/tags/user_views_tags_spec.rb2
-rw-r--r--spec/features/projects/tracings_spec.rb11
-rw-r--r--spec/features/projects/user_creates_project_spec.rb6
-rw-r--r--spec/features/projects/wikis_spec.rb2
-rw-r--r--spec/features/refactor_blob_viewer_disabled/projects/blobs/balsamiq_spec.rb18
-rw-r--r--spec/features/refactor_blob_viewer_disabled/projects/blobs/blob_line_permalink_updater_spec.rb103
-rw-r--r--spec/features/refactor_blob_viewer_disabled/projects/blobs/blob_show_spec.rb1154
-rw-r--r--spec/features/refactor_blob_viewer_disabled/projects/blobs/edit_spec.rb213
-rw-r--r--spec/features/refactor_blob_viewer_disabled/projects/blobs/shortcuts_blob_spec.rb45
-rw-r--r--spec/features/refactor_blob_viewer_disabled/projects/blobs/user_creates_new_blob_in_new_project_spec.rb63
-rw-r--r--spec/features/refactor_blob_viewer_disabled/projects/blobs/user_follows_pipeline_suggest_nudge_spec.rb80
-rw-r--r--spec/features/refactor_blob_viewer_disabled/projects/blobs/user_views_pipeline_editor_button_spec.rb46
-rw-r--r--spec/features/refactor_blob_viewer_disabled/projects/files/editing_a_file_spec.rb34
-rw-r--r--spec/features/refactor_blob_viewer_disabled/projects/files/find_file_keyboard_spec.rb42
-rw-r--r--spec/features/refactor_blob_viewer_disabled/projects/files/project_owner_creates_license_file_spec.rb72
-rw-r--r--spec/features/refactor_blob_viewer_disabled/projects/files/user_browses_files_spec.rb377
-rw-r--r--spec/features/refactor_blob_viewer_disabled/projects/files/user_browses_lfs_files_spec.rb86
-rw-r--r--spec/features/refactor_blob_viewer_disabled/projects/files/user_deletes_files_spec.rb74
-rw-r--r--spec/features/refactor_blob_viewer_disabled/projects/files/user_edits_files_spec.rb226
-rw-r--r--spec/features/refactor_blob_viewer_disabled/projects/files/user_replaces_files_spec.rb93
-rw-r--r--spec/features/search/user_searches_for_code_spec.rb125
-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.rb4
-rw-r--r--spec/features/search/user_searches_for_wiki_pages_spec.rb2
-rw-r--r--spec/features/static_site_editor_spec.rb11
-rw-r--r--spec/features/tags/developer_creates_tag_spec.rb8
-rw-r--r--spec/features/tags/developer_deletes_tag_spec.rb6
-rw-r--r--spec/features/tags/developer_updates_tag_spec.rb8
-rw-r--r--spec/features/tags/developer_views_tags_spec.rb20
-rw-r--r--spec/features/triggers_spec.rb2
-rw-r--r--spec/features/unsubscribe_links_spec.rb8
-rw-r--r--spec/features/users/active_sessions_spec.rb6
-rw-r--r--spec/features/users/login_spec.rb71
-rw-r--r--spec/features/users/logout_spec.rb4
-rw-r--r--spec/features/users/show_spec.rb2
-rw-r--r--spec/features/users/signup_spec.rb16
-rw-r--r--spec/features/users/terms_spec.rb10
-rw-r--r--spec/finders/issues_finder_spec.rb45
-rw-r--r--spec/finders/pending_todos_finder_spec.rb10
-rw-r--r--spec/finders/personal_access_tokens_finder_spec.rb21
-rw-r--r--spec/finders/projects/members/effective_access_level_finder_spec.rb41
-rw-r--r--spec/finders/projects/topics_finder_spec.rb6
-rw-r--r--spec/finders/releases/group_releases_finder_spec.rb204
-rw-r--r--spec/finders/releases_finder_spec.rb13
-rw-r--r--spec/fixtures/api/schemas/deployment.json3
-rw-r--r--spec/fixtures/api/schemas/environment.json2
-rw-r--r--spec/fixtures/api/schemas/list.json2
-rw-r--r--spec/fixtures/api/schemas/public_api/v4/deploy_token.json10
-rw-r--r--spec/fixtures/api/schemas/public_api/v4/system_hook.json24
-rw-r--r--spec/fixtures/api/schemas/public_api/v4/system_hooks.json9
-rw-r--r--spec/fixtures/emails/missing_delivered_to_header.eml35
-rw-r--r--spec/fixtures/emails/service_desk_reply_to_and_from.eml28
-rw-r--r--spec/fixtures/emails/valid_note_on_issuable.eml2
-rw-r--r--spec/fixtures/error_tracking/php_empty_transaction.json45
-rw-r--r--spec/fixtures/markdown/markdown_golden_master_examples.yml40
-rw-r--r--spec/fixtures/security_reports/master/gl-common-scanning-report.json140
-rw-r--r--spec/frontend/__helpers__/flush_promises.js1
-rw-r--r--spec/frontend/__helpers__/mocks/axios_utils.js2
-rw-r--r--spec/frontend/__helpers__/vuex_action_helper.js1
-rw-r--r--spec/frontend/access_tokens/components/__snapshots__/expires_at_field_spec.js.snap45
-rw-r--r--spec/frontend/access_tokens/components/expires_at_field_spec.js18
-rw-r--r--spec/frontend/admin/applications/components/__snapshots__/delete_application_spec.js.snap20
-rw-r--r--spec/frontend/admin/applications/components/delete_application_spec.js69
-rw-r--r--spec/frontend/admin/topics/components/__snapshots__/remove_avatar_spec.js.snap20
-rw-r--r--spec/frontend/admin/topics/components/remove_avatar_spec.js85
-rw-r--r--spec/frontend/admin/users/components/user_actions_spec.js20
-rw-r--r--spec/frontend/api_spec.js22
-rw-r--r--spec/frontend/attention_requests/components/navigation_popover_spec.js86
-rw-r--r--spec/frontend/authentication/webauthn/util_spec.js17
-rw-r--r--spec/frontend/blob/components/__snapshots__/blob_header_spec.js.snap3
-rw-r--r--spec/frontend/blob/components/blob_header_spec.js15
-rw-r--r--spec/frontend/blob/components/mock_data.js2
-rw-r--r--spec/frontend/blob/csv/csv_viewer_spec.js26
-rw-r--r--spec/frontend/blob_edit/blob_bundle_spec.js6
-rw-r--r--spec/frontend/boards/components/board_form_spec.js14
-rw-r--r--spec/frontend/boards/components/boards_selector_spec.js1
-rw-r--r--spec/frontend/boards/mock_data.js31
-rw-r--r--spec/frontend/boards/stores/actions_spec.js72
-rw-r--r--spec/frontend/boards/stores/mutations_spec.js40
-rw-r--r--spec/frontend/branches/ajax_loading_spinner_spec.js32
-rw-r--r--spec/frontend/ci_secure_files/components/secure_files_list_spec.js139
-rw-r--r--spec/frontend/ci_secure_files/mock_data.js18
-rw-r--r--spec/frontend/clusters/agents/components/create_token_button_spec.js257
-rw-r--r--spec/frontend/clusters/agents/components/token_table_spec.js43
-rw-r--r--spec/frontend/clusters/components/__snapshots__/new_cluster_spec.js.snap7
-rw-r--r--spec/frontend/clusters/components/new_cluster_spec.js4
-rw-r--r--spec/frontend/clusters/mock_data.js57
-rw-r--r--spec/frontend/clusters_list/components/agent_table_spec.js17
-rw-r--r--spec/frontend/clusters_list/components/agent_token_spec.js76
-rw-r--r--spec/frontend/clusters_list/components/available_agents_dropwdown_spec.js63
-rw-r--r--spec/frontend/clusters_list/components/clusters_actions_spec.js122
-rw-r--r--spec/frontend/clusters_list/components/clusters_empty_state_spec.js4
-rw-r--r--spec/frontend/clusters_list/components/clusters_main_view_spec.js149
-rw-r--r--spec/frontend/clusters_list/components/clusters_spec.js10
-rw-r--r--spec/frontend/clusters_list/components/install_agent_modal_spec.js75
-rw-r--r--spec/frontend/code_navigation/components/app_spec.js19
-rw-r--r--spec/frontend/code_quality_walkthrough/components/__snapshots__/step_spec.js.snap174
-rw-r--r--spec/frontend/code_quality_walkthrough/components/step_spec.js156
-rw-r--r--spec/frontend/content_editor/components/content_editor_alert_spec.js17
-rw-r--r--spec/frontend/content_editor/components/content_editor_spec.js77
-rw-r--r--spec/frontend/content_editor/components/editor_state_observer_spec.js63
-rw-r--r--spec/frontend/content_editor/components/loading_indicator_spec.js71
-rw-r--r--spec/frontend/content_editor/components/toolbar_button_spec.js2
-rw-r--r--spec/frontend/content_editor/components/toolbar_link_button_spec.js2
-rw-r--r--spec/frontend/content_editor/components/toolbar_text_style_dropdown_spec.js2
-rw-r--r--spec/frontend/content_editor/extensions/attachment_spec.js17
-rw-r--r--spec/frontend/content_editor/extensions/paste_markdown_spec.js127
-rw-r--r--spec/frontend/content_editor/markdown_processing_spec_helper.js2
-rw-r--r--spec/frontend/content_editor/services/content_editor_spec.js39
-rw-r--r--spec/frontend/content_editor/services/markdown_deserializer_spec.js62
-rw-r--r--spec/frontend/content_editor/services/markdown_serializer_spec.js13
-rw-r--r--spec/frontend/content_editor/services/markdown_sourcemap_spec.js29
-rw-r--r--spec/frontend/content_editor/test_utils.js20
-rw-r--r--spec/frontend/contributors/store/getters_spec.js2
-rw-r--r--spec/frontend/cycle_analytics/__snapshots__/total_time_component_spec.js.snap28
-rw-r--r--spec/frontend/cycle_analytics/__snapshots__/total_time_spec.js.snap28
-rw-r--r--spec/frontend/cycle_analytics/base_spec.js3
-rw-r--r--spec/frontend/cycle_analytics/limit_warning_component_spec.js41
-rw-r--r--spec/frontend/cycle_analytics/total_time_component_spec.js45
-rw-r--r--spec/frontend/cycle_analytics/total_time_spec.js45
-rw-r--r--spec/frontend/cycle_analytics/value_stream_filters_spec.js54
-rw-r--r--spec/frontend/cycle_analytics/value_stream_metrics_spec.js6
-rw-r--r--spec/frontend/deploy_tokens/components/revoke_button_spec.js5
-rw-r--r--spec/frontend/diffs/components/diff_view_spec.js12
-rw-r--r--spec/frontend/diffs/components/hidden_files_warning_spec.js18
-rw-r--r--spec/frontend/diffs/store/getters_versions_dropdowns_spec.js37
-rw-r--r--spec/frontend/dirty_submit/dirty_submit_form_spec.js33
-rw-r--r--spec/frontend/editor/source_editor_ci_schema_ext_spec.js9
-rw-r--r--spec/frontend/environment.js1
-rw-r--r--spec/frontend/environments/delete_environment_modal_spec.js31
-rw-r--r--spec/frontend/environments/enable_review_app_modal_spec.js14
-rw-r--r--spec/frontend/environments/environment_actions_spec.js17
-rw-r--r--spec/frontend/environments/environment_folder_spec.js132
-rw-r--r--spec/frontend/environments/environment_item_spec.js2
-rw-r--r--spec/frontend/environments/environments_app_spec.js497
-rw-r--r--spec/frontend/environments/graphql/resolvers_spec.js31
-rw-r--r--spec/frontend/environments/new_environment_folder_spec.js100
-rw-r--r--spec/frontend/environments/new_environment_item_spec.js2
-rw-r--r--spec/frontend/environments/new_environments_app_spec.js329
-rw-r--r--spec/frontend/error_tracking/components/error_details_spec.js6
-rw-r--r--spec/frontend/error_tracking/components/error_tracking_list_spec.js78
-rw-r--r--spec/frontend/error_tracking_settings/components/app_spec.js141
-rw-r--r--spec/frontend/fixtures/merge_requests.rb19
-rw-r--r--spec/frontend/fixtures/runner.rb48
-rw-r--r--spec/frontend/google_cloud/components/app_spec.js5
-rw-r--r--spec/frontend/google_cloud/components/gcp_regions_form_spec.js59
-rw-r--r--spec/frontend/google_cloud/components/gcp_regions_list_spec.js79
-rw-r--r--spec/frontend/google_cloud/components/home_spec.js3
-rw-r--r--spec/frontend/google_cloud/components/revoke_oauth_spec.js47
-rw-r--r--spec/frontend/google_cloud/components/service_accounts_form_spec.js2
-rw-r--r--spec/frontend/google_tag_manager/index_spec.js44
-rw-r--r--spec/frontend/graphql_shared/utils_spec.js2
-rw-r--r--spec/frontend/header_search/components/header_search_autocomplete_items_spec.js13
-rw-r--r--spec/frontend/header_search/store/actions_spec.js16
-rw-r--r--spec/frontend/header_search/store/getters_spec.js100
-rw-r--r--spec/frontend/header_search/store/mutations_spec.js4
-rw-r--r--spec/frontend/ide/components/file_templates/bar_spec.js8
-rw-r--r--spec/frontend/ide/components/new_dropdown/modal_spec.js4
-rw-r--r--spec/frontend/ide/components/repo_editor_spec.js58
-rw-r--r--spec/frontend/import_entities/import_projects/components/import_projects_table_spec.js2
-rw-r--r--spec/frontend/incidents/components/incidents_list_spec.js116
-rw-r--r--spec/frontend/incidents/mocks/incidents.json8
-rw-r--r--spec/frontend/integrations/edit/components/active_checkbox_spec.js9
-rw-r--r--spec/frontend/integrations/edit/components/integration_form_spec.js144
-rw-r--r--spec/frontend/integrations/edit/components/sections/connection_spec.js77
-rw-r--r--spec/frontend/integrations/edit/components/sections/jira_issues_spec.js34
-rw-r--r--spec/frontend/integrations/edit/components/sections/jira_trigger_spec.js34
-rw-r--r--spec/frontend/integrations/edit/components/trigger_fields_spec.js6
-rw-r--r--spec/frontend/integrations/edit/mock_data.js8
-rw-r--r--spec/frontend/integrations/edit/store/getters_spec.js21
-rw-r--r--spec/frontend/invite_members/components/invite_groups_modal_spec.js95
-rw-r--r--spec/frontend/invite_members/components/invite_members_modal_spec.js2
-rw-r--r--spec/frontend/invite_members/components/invite_modal_base_spec.js36
-rw-r--r--spec/frontend/issuable/related_issues/components/related_issues_block_spec.js6
-rw-r--r--spec/frontend/issuable/related_issues/components/related_issues_list_spec.js5
-rw-r--r--spec/frontend/issues/list/components/issues_list_app_spec.js29
-rw-r--r--spec/frontend/issues/list/utils_spec.js37
-rw-r--r--spec/frontend/issues/show/components/description_spec.js83
-rw-r--r--spec/frontend/issues/show/components/header_actions_spec.js71
-rw-r--r--spec/frontend/issues/show/components/incidents/incident_tabs_spec.js10
-rw-r--r--spec/frontend/jira_connect/subscriptions/components/app_spec.js56
-rw-r--r--spec/frontend/jira_connect/subscriptions/components/sign_in_button_spec.js58
-rw-r--r--spec/frontend/jira_connect/subscriptions/components/sign_in_legacy_button_spec.js58
-rw-r--r--spec/frontend/jira_connect/subscriptions/components/sign_in_oauth_button_spec.js204
-rw-r--r--spec/frontend/jira_connect/subscriptions/components/user_link_spec.js45
-rw-r--r--spec/frontend/jira_connect/subscriptions/pages/sign_in_spec.js111
-rw-r--r--spec/frontend/jira_connect/subscriptions/pkce_spec.js48
-rw-r--r--spec/frontend/jobs/components/job_app_spec.js1
-rw-r--r--spec/frontend/jobs/components/job_log_controllers_spec.js24
-rw-r--r--spec/frontend/jobs/components/job_sidebar_retry_button_spec.js13
-rw-r--r--spec/frontend/jobs/components/sidebar_spec.js43
-rw-r--r--spec/frontend/jobs/components/stages_dropdown_spec.js209
-rw-r--r--spec/frontend/jobs/components/table/graphql/cache_config_spec.js67
-rw-r--r--spec/frontend/jobs/components/table/job_table_app_spec.js59
-rw-r--r--spec/frontend/jobs/mock_data.js84
-rw-r--r--spec/frontend/lib/utils/array_utility_spec.js13
-rw-r--r--spec/frontend/lib/utils/common_utils_spec.js25
-rw-r--r--spec/frontend/lib/utils/ignore_while_pending_spec.js136
-rw-r--r--spec/frontend/lib/utils/resize_observer_spec.js41
-rw-r--r--spec/frontend/lib/utils/text_markdown_spec.js128
-rw-r--r--spec/frontend/lib/utils/url_utility_spec.js53
-rw-r--r--spec/frontend/loading_icon_for_legacy_js_spec.js43
-rw-r--r--spec/frontend/members/components/action_buttons/user_action_buttons_spec.js10
-rw-r--r--spec/frontend/members/components/filter_sort/members_filtered_search_bar_spec.js54
-rw-r--r--spec/frontend/merge_conflicts/components/merge_conflict_resolver_app_spec.js33
-rw-r--r--spec/frontend/merge_request_tabs_spec.js1
-rw-r--r--spec/frontend/monitoring/components/charts/time_series_spec.js15
-rw-r--r--spec/frontend/notes/components/note_header_spec.js20
-rw-r--r--spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/delete_alert_spec.js21
-rw-r--r--spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/details_header_spec.js30
-rw-r--r--spec/frontend/packages_and_registries/container_registry/explorer/mock_data.js10
-rw-r--r--spec/frontend/packages_and_registries/container_registry/explorer/pages/details_spec.js32
-rw-r--r--spec/frontend/packages_and_registries/container_registry/explorer/pages/list_spec.js106
-rw-r--r--spec/frontend/packages_and_registries/settings/project/settings/components/__snapshots__/settings_form_spec.js.snap2
-rw-r--r--spec/frontend/packages_and_registries/settings/project/settings/components/settings_form_spec.js26
-rw-r--r--spec/frontend/packages_and_registries/settings/project/settings/graphql/cache_updated_spec.js25
-rw-r--r--spec/frontend/pages/projects/forks/new/components/app_spec.js13
-rw-r--r--spec/frontend/pages/projects/forks/new/components/fork_form_spec.js28
-rw-r--r--spec/frontend/pages/projects/forks/new/components/fork_groups_list_item_spec.js73
-rw-r--r--spec/frontend/pages/projects/forks/new/components/fork_groups_list_spec.js123
-rw-r--r--spec/frontend/pages/projects/learn_gitlab/components/__snapshots__/learn_gitlab_spec.js.snap14
-rw-r--r--spec/frontend/pages/projects/learn_gitlab/components/learn_gitlab_section_link_spec.js8
-rw-r--r--spec/frontend/pages/projects/learn_gitlab/components/learn_gitlab_spec.js12
-rw-r--r--spec/frontend/pages/projects/learn_gitlab/components/mock_data.js1
-rw-r--r--spec/frontend/pages/projects/pages_domains/form_spec.js82
-rw-r--r--spec/frontend/pages/shared/wikis/components/wiki_form_spec.js14
-rw-r--r--spec/frontend/performance_bar/components/detailed_metric_spec.js24
-rw-r--r--spec/frontend/performance_bar/components/performance_bar_app_spec.js11
-rw-r--r--spec/frontend/performance_bar/components/request_selector_spec.js31
-rw-r--r--spec/frontend/performance_bar/index_spec.js30
-rw-r--r--spec/frontend/persistent_user_callout_spec.js100
-rw-r--r--spec/frontend/pipeline_editor/components/commit/commit_form_spec.js23
-rw-r--r--spec/frontend/pipeline_editor/components/commit/commit_section_spec.js1
-rw-r--r--spec/frontend/pipeline_editor/components/drawer/pipeline_editor_drawer_spec.js27
-rw-r--r--spec/frontend/pipeline_editor/components/editor/text_editor_spec.js11
-rw-r--r--spec/frontend/pipeline_editor/components/pipeline_editor_tabs_spec.js49
-rw-r--r--spec/frontend/pipeline_editor/pipeline_editor_app_spec.js86
-rw-r--r--spec/frontend/pipeline_wizard/components/input_spec.js79
-rw-r--r--spec/frontend/pipeline_wizard/components/step_spec.js227
-rw-r--r--spec/frontend/pipeline_wizard/components/widgets/list_spec.js212
-rw-r--r--spec/frontend/pipeline_wizard/components/widgets_spec.js49
-rw-r--r--spec/frontend/pipeline_wizard/components/wrapper_spec.js250
-rw-r--r--spec/frontend/pipeline_wizard/mock/yaml.js85
-rw-r--r--spec/frontend/pipeline_wizard/pipeline_wizard_spec.js102
-rw-r--r--spec/frontend/pipeline_wizard/validators_spec.js22
-rw-r--r--spec/frontend/pipelines/components/jobs/jobs_app_spec.js29
-rw-r--r--spec/frontend/pipelines/components/pipelines_filtered_search_spec.js2
-rw-r--r--spec/frontend/pipelines/header_component_spec.js25
-rw-r--r--spec/frontend/pipelines/pipeline_labels_spec.js168
-rw-r--r--spec/frontend/pipelines/pipeline_url_spec.js216
-rw-r--r--spec/frontend/pipelines/pipelines_ci_templates_spec.js107
-rw-r--r--spec/frontend/pipelines/pipelines_spec.js76
-rw-r--r--spec/frontend/pipelines/pipelines_table_spec.js63
-rw-r--r--spec/frontend/pipelines/tokens/pipeline_branch_name_token_spec.js47
-rw-r--r--spec/frontend/protected_branches/protected_branch_create_spec.js114
-rw-r--r--spec/frontend/protected_branches/protected_branch_edit_spec.js92
-rw-r--r--spec/frontend/ref/components/__snapshots__/ref_selector_spec.js.snap10
-rw-r--r--spec/frontend/ref/stores/mutations_spec.js8
-rw-r--r--spec/frontend/releases/components/asset_links_form_spec.js4
-rw-r--r--spec/frontend/releases/stores/modules/detail/getters_spec.js23
-rw-r--r--spec/frontend/repository/components/blob_content_viewer_spec.js106
-rw-r--r--spec/frontend/repository/components/blob_edit_spec.js100
-rw-r--r--spec/frontend/repository/components/blob_viewers/audio_viewer_spec.js23
-rw-r--r--spec/frontend/repository/components/blob_viewers/csv_viewer_spec.js27
-rw-r--r--spec/frontend/repository/components/blob_viewers/download_viewer_spec.js11
-rw-r--r--spec/frontend/repository/components/blob_viewers/lfs_viewer_spec.js11
-rw-r--r--spec/frontend/repository/components/blob_viewers/pdf_viewer_spec.js26
-rw-r--r--spec/frontend/repository/components/breadcrumbs_spec.js14
-rw-r--r--spec/frontend/repository/mock_data.js17
-rw-r--r--spec/frontend/runner/admin_runner_edit/admin_runner_edit_app_spec.js4
-rw-r--r--spec/frontend/runner/admin_runner_show/admin_runner_show_app_spec.js4
-rw-r--r--spec/frontend/runner/admin_runners/admin_runners_app_spec.js74
-rw-r--r--spec/frontend/runner/components/cells/runner_actions_cell_spec.js223
-rw-r--r--spec/frontend/runner/components/registration/registration_token_reset_dropdown_item_spec.js2
-rw-r--r--spec/frontend/runner/components/runner_delete_button_spec.js233
-rw-r--r--spec/frontend/runner/components/runner_jobs_spec.js4
-rw-r--r--spec/frontend/runner/components/runner_list_spec.js40
-rw-r--r--spec/frontend/runner/components/runner_pagination_spec.js18
-rw-r--r--spec/frontend/runner/components/runner_pause_button_spec.js24
-rw-r--r--spec/frontend/runner/components/runner_projects_spec.js4
-rw-r--r--spec/frontend/runner/components/runner_update_form_spec.js2
-rw-r--r--spec/frontend/runner/group_runners/group_runners_app_spec.js83
-rw-r--r--spec/frontend/runner/mock_data.js24
-rw-r--r--spec/frontend/search/topbar/components/app_spec.js33
-rw-r--r--spec/frontend/security_configuration/components/feature_card_spec.js2
-rw-r--r--spec/frontend/security_configuration/components/training_provider_list_spec.js189
-rw-r--r--spec/frontend/security_configuration/graphql/cache_utils_spec.js108
-rw-r--r--spec/frontend/security_configuration/mock_data.js63
-rw-r--r--spec/frontend/sidebar/components/assignees/sidebar_assignees_widget_spec.js27
-rw-r--r--spec/frontend/sidebar/components/assignees/sidebar_participant_spec.js41
-rw-r--r--spec/frontend/sidebar/components/attention_requested_toggle_spec.js62
-rw-r--r--spec/frontend/sidebar/components/incidents/escalation_status_spec.js52
-rw-r--r--spec/frontend/sidebar/components/incidents/escalation_utils_spec.js18
-rw-r--r--spec/frontend/sidebar/components/incidents/mock_data.js39
-rw-r--r--spec/frontend/sidebar/components/incidents/sidebar_escalation_status_spec.js207
-rw-r--r--spec/frontend/sidebar/mock_data.js29
-rw-r--r--spec/frontend/sidebar/sidebar_assignees_spec.js31
-rw-r--r--spec/frontend/sidebar/sidebar_mediator_spec.js3
-rw-r--r--spec/frontend/snippets/components/__snapshots__/snippet_blob_edit_spec.js.snap1
-rw-r--r--spec/frontend/snippets/components/__snapshots__/snippet_description_edit_spec.js.snap1
-rw-r--r--spec/frontend/terraform/components/empty_state_spec.js2
-rw-r--r--spec/frontend/test_setup.js1
-rw-r--r--spec/frontend/toggle_buttons_spec.js115
-rw-r--r--spec/frontend/toggles/index_spec.js6
-rw-r--r--spec/frontend/tracking/tracking_spec.js27
-rw-r--r--spec/frontend/users_select/index_spec.js35
-rw-r--r--spec/frontend/vue_mr_widget/components/extensions/child_content_spec.js40
-rw-r--r--spec/frontend/vue_mr_widget/components/mr_widget_rebase_spec.js47
-rw-r--r--spec/frontend/vue_mr_widget/components/mr_widget_related_links_spec.js29
-rw-r--r--spec/frontend/vue_mr_widget/components/states/mr_widget_conflicts_spec.js6
-rw-r--r--spec/frontend/vue_mr_widget/components/states/mr_widget_ready_to_merge_spec.js114
-rw-r--r--spec/frontend/vue_mr_widget/extentions/accessibility/index_spec.js8
-rw-r--r--spec/frontend/vue_mr_widget/extentions/code_quality/index_spec.js145
-rw-r--r--spec/frontend/vue_mr_widget/extentions/code_quality/mock_data.js87
-rw-r--r--spec/frontend/vue_mr_widget/mr_widget_how_to_merge_modal_spec.js4
-rw-r--r--spec/frontend/vue_mr_widget/mr_widget_options_spec.js2
-rw-r--r--spec/frontend/vue_shared/components/__snapshots__/content_transition_spec.js.snap41
-rw-r--r--spec/frontend/vue_shared/components/color_picker/color_picker_spec.js13
-rw-r--r--spec/frontend/vue_shared/components/content_transition_spec.js109
-rw-r--r--spec/frontend/vue_shared/components/filtered_search_bar/tokens/base_token_spec.js225
-rw-r--r--spec/frontend/vue_shared/components/markdown/field_spec.js41
-rw-r--r--spec/frontend/vue_shared/components/markdown/header_spec.js9
-rw-r--r--spec/frontend/vue_shared/components/notes/__snapshots__/noteable_warning_spec.js.snap10
-rw-r--r--spec/frontend/vue_shared/components/notes/noteable_warning_spec.js5
-rw-r--r--spec/frontend/vue_shared/components/paginated_table_with_search_and_tabs/paginated_table_with_search_and_tabs_spec.js2
-rw-r--r--spec/frontend/vue_shared/components/runner_aws_deployments/__snapshots__/runner_aws_deployments_modal_spec.js.snap216
-rw-r--r--spec/frontend/vue_shared/components/runner_aws_deployments/runner_aws_deployments_modal_spec.js50
-rw-r--r--spec/frontend/vue_shared/components/source_viewer/source_viewer_spec.js6
-rw-r--r--spec/frontend/vue_shared/components/source_viewer/utils_spec.js27
-rw-r--r--spec/frontend/vue_shared/components/user_avatar/user_avatar_image_new_spec.js127
-rw-r--r--spec/frontend/vue_shared/components/user_avatar/user_avatar_image_old_spec.js122
-rw-r--r--spec/frontend/vue_shared/components/user_avatar/user_avatar_image_spec.js96
-rw-r--r--spec/frontend/vue_shared/components/user_avatar/user_avatar_link_new_spec.js102
-rw-r--r--spec/frontend/vue_shared/components/user_avatar/user_avatar_link_old_spec.js102
-rw-r--r--spec/frontend/vue_shared/components/user_avatar/user_avatar_link_spec.js135
-rw-r--r--spec/frontend/vue_shared/components/user_popover/user_popover_spec.js6
-rw-r--r--spec/frontend/vue_shared/components/user_select_spec.js61
-rw-r--r--spec/frontend/vue_shared/components/web_ide_link_spec.js40
-rw-r--r--spec/frontend/vue_shared/issuable/show/components/issuable_title_spec.js6
-rw-r--r--spec/frontend/work_items/components/work_item_detail_spec.js40
-rw-r--r--spec/frontend/work_items/mock_data.js60
-rw-r--r--spec/frontend/work_items/pages/create_work_item_spec.js24
-rw-r--r--spec/frontend/work_items/pages/work_item_root_spec.js45
-rw-r--r--spec/frontend/work_items/router_spec.js1
-rw-r--r--spec/frontend_integration/ide/helpers/ide_helper.js2
-rw-r--r--spec/graphql/mutations/boards/issues/issue_move_list_spec.rb18
-rw-r--r--spec/graphql/mutations/ci/runner/delete_spec.rb72
-rw-r--r--spec/graphql/mutations/ci/runner/update_spec.rb6
-rw-r--r--spec/graphql/mutations/release_asset_links/create_spec.rb16
-rw-r--r--spec/graphql/mutations/saved_replies/create_spec.rb46
-rw-r--r--spec/graphql/mutations/saved_replies/update_spec.rb47
-rw-r--r--spec/graphql/resolvers/admin/analytics/usage_trends/measurements_resolver_spec.rb12
-rw-r--r--spec/graphql/resolvers/base_resolver_spec.rb10
-rw-r--r--spec/graphql/resolvers/blobs_resolver_spec.rb28
-rw-r--r--spec/graphql/resolvers/board_list_issues_resolver_spec.rb12
-rw-r--r--spec/graphql/resolvers/board_lists_resolver_spec.rb7
-rw-r--r--spec/graphql/resolvers/board_resolver_spec.rb4
-rw-r--r--spec/graphql/resolvers/ci/config_resolver_spec.rb40
-rw-r--r--spec/graphql/resolvers/ci/job_token_scope_resolver_spec.rb6
-rw-r--r--spec/graphql/resolvers/concerns/resolves_pipelines_spec.rb40
-rw-r--r--spec/graphql/resolvers/design_management/design_at_version_resolver_spec.rb12
-rw-r--r--spec/graphql/resolvers/design_management/design_resolver_spec.rb12
-rw-r--r--spec/graphql/resolvers/design_management/version/design_at_version_resolver_spec.rb6
-rw-r--r--spec/graphql/resolvers/design_management/version_in_collection_resolver_spec.rb6
-rw-r--r--spec/graphql/resolvers/design_management/version_resolver_spec.rb6
-rw-r--r--spec/graphql/resolvers/design_management/versions_resolver_spec.rb6
-rw-r--r--spec/graphql/resolvers/environments_resolver_spec.rb8
-rw-r--r--spec/graphql/resolvers/group_issues_resolver_spec.rb6
-rw-r--r--spec/graphql/resolvers/group_labels_resolver_spec.rb6
-rw-r--r--spec/graphql/resolvers/group_members/notification_email_resolver_spec.rb46
-rw-r--r--spec/graphql/resolvers/group_milestones_resolver_spec.rb24
-rw-r--r--spec/graphql/resolvers/issue_status_counts_resolver_spec.rb6
-rw-r--r--spec/graphql/resolvers/issues_resolver_spec.rb35
-rw-r--r--spec/graphql/resolvers/kas/agent_configurations_resolver_spec.rb6
-rw-r--r--spec/graphql/resolvers/labels_resolver_spec.rb4
-rw-r--r--spec/graphql/resolvers/namespace_projects_resolver_spec.rb4
-rw-r--r--spec/graphql/resolvers/package_pipelines_resolver_spec.rb24
-rw-r--r--spec/graphql/resolvers/paginated_tree_resolver_spec.rb6
-rw-r--r--spec/graphql/resolvers/project_milestones_resolver_spec.rb24
-rw-r--r--spec/graphql/resolvers/project_pipeline_resolver_spec.rb10
-rw-r--r--spec/graphql/resolvers/project_resolver_spec.rb4
-rw-r--r--spec/graphql/resolvers/projects/jira_projects_resolver_spec.rb13
-rw-r--r--spec/graphql/resolvers/projects/snippets_resolver_spec.rb6
-rw-r--r--spec/graphql/resolvers/snippets_resolver_spec.rb6
-rw-r--r--spec/graphql/resolvers/timelog_resolver_spec.rb49
-rw-r--r--spec/graphql/resolvers/topics_resolver_spec.rb6
-rw-r--r--spec/graphql/resolvers/user_discussions_count_resolver_spec.rb4
-rw-r--r--spec/graphql/resolvers/user_notes_count_resolver_spec.rb12
-rw-r--r--spec/graphql/resolvers/user_resolver_spec.rb14
-rw-r--r--spec/graphql/resolvers/users_resolver_spec.rb13
-rw-r--r--spec/graphql/resolvers/work_item_resolver_spec.rb43
-rw-r--r--spec/graphql/resolvers/work_items/types_resolver_spec.rb41
-rw-r--r--spec/graphql/types/alert_management/alert_type_spec.rb3
-rw-r--r--spec/graphql/types/base_enum_spec.rb8
-rw-r--r--spec/graphql/types/base_field_spec.rb28
-rw-r--r--spec/graphql/types/ci/runner_web_url_edge_spec.rb13
-rw-r--r--spec/graphql/types/commit_type_spec.rb2
-rw-r--r--spec/graphql/types/container_repository_details_type_spec.rb2
-rw-r--r--spec/graphql/types/design_management/design_type_spec.rb4
-rw-r--r--spec/graphql/types/global_id_type_spec.rb14
-rw-r--r--spec/graphql/types/group_member_type_spec.rb2
-rw-r--r--spec/graphql/types/merge_request_type_spec.rb4
-rw-r--r--spec/graphql/types/merge_requests/assignee_type_spec.rb7
-rw-r--r--spec/graphql/types/merge_requests/author_type_spec.rb7
-rw-r--r--spec/graphql/types/merge_requests/participant_type_spec.rb7
-rw-r--r--spec/graphql/types/merge_requests/reviewer_type_spec.rb48
-rw-r--r--spec/graphql/types/projects/base_service_type_spec.rb2
-rw-r--r--spec/graphql/types/projects/jira_service_type_spec.rb2
-rw-r--r--spec/graphql/types/projects/service_type_enum_spec.rb55
-rw-r--r--spec/graphql/types/projects/service_type_spec.rb2
-rw-r--r--spec/graphql/types/projects/services_enum_spec.rb13
-rw-r--r--spec/graphql/types/query_type_spec.rb1
-rw-r--r--spec/graphql/types/repository/blob_type_spec.rb4
-rw-r--r--spec/graphql/types/saved_reply_type_spec.rb13
-rw-r--r--spec/graphql/types/todo_type_spec.rb2
-rw-r--r--spec/graphql/types/todoable_interface_spec.rb29
-rw-r--r--spec/graphql/types/user_type_spec.rb59
-rw-r--r--spec/graphql/types/work_item_id_type_spec.rb51
-rw-r--r--spec/graphql/types/work_item_type_spec.rb17
-rw-r--r--spec/helpers/application_helper_spec.rb108
-rw-r--r--spec/helpers/application_settings_helper_spec.rb23
-rw-r--r--spec/helpers/blob_helper_spec.rb93
-rw-r--r--spec/helpers/broadcast_messages_helper_spec.rb85
-rw-r--r--spec/helpers/ci/pipelines_helper_spec.rb59
-rw-r--r--spec/helpers/clusters_helper_spec.rb137
-rw-r--r--spec/helpers/commits_helper_spec.rb25
-rw-r--r--spec/helpers/container_expiration_policies_helper_spec.rb23
-rw-r--r--spec/helpers/container_registry_helper_spec.rb16
-rw-r--r--spec/helpers/deploy_tokens_helper_spec.rb20
-rw-r--r--spec/helpers/explore_helper_spec.rb29
-rw-r--r--spec/helpers/groups/crm_settings_helper_spec.rb40
-rw-r--r--spec/helpers/icons_helper_spec.rb32
-rw-r--r--spec/helpers/integrations_helper_spec.rb27
-rw-r--r--spec/helpers/invite_members_helper_spec.rb11
-rw-r--r--spec/helpers/issues_helper_spec.rb8
-rw-r--r--spec/helpers/jira_connect_helper_spec.rb46
-rw-r--r--spec/helpers/labels_helper_spec.rb8
-rw-r--r--spec/helpers/learn_gitlab_helper_spec.rb79
-rw-r--r--spec/helpers/listbox_helper_spec.rb9
-rw-r--r--spec/helpers/markup_helper_spec.rb32
-rw-r--r--spec/helpers/merge_requests_helper_spec.rb33
-rw-r--r--spec/helpers/nav/top_nav_helper_spec.rb2
-rw-r--r--spec/helpers/notify_helper_spec.rb1
-rw-r--r--spec/helpers/packages_helper_spec.rb165
-rw-r--r--spec/helpers/preferences_helper_spec.rb24
-rw-r--r--spec/helpers/projects/cluster_agents_helper_spec.rb17
-rw-r--r--spec/helpers/projects/error_tracking_helper_spec.rb53
-rw-r--r--spec/helpers/projects_helper_spec.rb22
-rw-r--r--spec/helpers/routing/pseudonymization_helper_spec.rb26
-rw-r--r--spec/helpers/sessions_helper_spec.rb4
-rw-r--r--spec/helpers/sorting_helper_spec.rb12
-rw-r--r--spec/helpers/storage_helper_spec.rb43
-rw-r--r--spec/helpers/tree_helper_spec.rb2
-rw-r--r--spec/helpers/users/callouts_helper_spec.rb19
-rw-r--r--spec/helpers/web_ide_button_helper_spec.rb45
-rw-r--r--spec/helpers/whats_new_helper_spec.rb6
-rw-r--r--spec/lib/api/entities/ci/job_artifact_file_spec.rb18
-rw-r--r--spec/lib/api/entities/ci/job_request/dependency_spec.rb27
-rw-r--r--spec/lib/api/entities/user_spec.rb57
-rw-r--r--spec/lib/api/entities/wiki_page_spec.rb56
-rw-r--r--spec/lib/api/helpers_spec.rb20
-rw-r--r--spec/lib/atlassian/jira_connect/client_spec.rb22
-rw-r--r--spec/lib/atlassian/jira_connect/serializers/build_entity_spec.rb2
-rw-r--r--spec/lib/atlassian/jira_connect/serializers/deployment_entity_spec.rb23
-rw-r--r--spec/lib/atlassian/jira_connect_spec.rb29
-rw-r--r--spec/lib/backup/artifacts_spec.rb2
-rw-r--r--spec/lib/backup/database_spec.rb47
-rw-r--r--spec/lib/backup/files_spec.rb38
-rw-r--r--spec/lib/backup/gitaly_backup_spec.rb120
-rw-r--r--spec/lib/backup/gitaly_rpc_backup_spec.rb23
-rw-r--r--spec/lib/backup/lfs_spec.rb2
-rw-r--r--spec/lib/backup/manager_spec.rb844
-rw-r--r--spec/lib/backup/object_backup_spec.rb2
-rw-r--r--spec/lib/backup/pages_spec.rb2
-rw-r--r--spec/lib/backup/repositories_spec.rb53
-rw-r--r--spec/lib/backup/task_spec.rb27
-rw-r--r--spec/lib/backup/uploads_spec.rb2
-rw-r--r--spec/lib/banzai/filter/front_matter_filter_spec.rb53
-rw-r--r--spec/lib/banzai/filter/image_link_filter_spec.rb62
-rw-r--r--spec/lib/banzai/filter/issuable_reference_expansion_filter_spec.rb2
-rw-r--r--spec/lib/banzai/filter/reference_redactor_filter_spec.rb3
-rw-r--r--spec/lib/banzai/filter/references/external_issue_reference_filter_spec.rb19
-rw-r--r--spec/lib/banzai/filter/references/label_reference_filter_spec.rb2
-rw-r--r--spec/lib/banzai/filter/task_list_filter_spec.rb13
-rw-r--r--spec/lib/banzai/reference_redactor_spec.rb3
-rw-r--r--spec/lib/bulk_imports/clients/http_spec.rb4
-rw-r--r--spec/lib/bulk_imports/common/pipelines/labels_pipeline_spec.rb2
-rw-r--r--spec/lib/container_registry/client_spec.rb100
-rw-r--r--spec/lib/container_registry/gitlab_api_client_spec.rb52
-rw-r--r--spec/lib/container_registry/registry_spec.rb7
-rw-r--r--spec/lib/feature_spec.rb4
-rw-r--r--spec/lib/gitlab/analytics/cycle_analytics/median_spec.rb4
-rw-r--r--spec/lib/gitlab/auth/ldap/access_spec.rb2
-rw-r--r--spec/lib/gitlab/auth/ldap/authentication_spec.rb2
-rw-r--r--spec/lib/gitlab/auth/o_auth/provider_spec.rb8
-rw-r--r--spec/lib/gitlab/auth/o_auth/user_spec.rb132
-rw-r--r--spec/lib/gitlab/auth/request_authenticator_spec.rb32
-rw-r--r--spec/lib/gitlab/background_migration/backfill_issue_search_data_spec.rb57
-rw-r--r--spec/lib/gitlab/background_migration/backfill_member_namespace_for_group_members_spec.rb50
-rw-r--r--spec/lib/gitlab/background_migration/backfill_snippet_repositories_spec.rb12
-rw-r--r--spec/lib/gitlab/background_migration/batching_strategies/backfill_project_namespace_per_group_batching_strategy_spec.rb2
-rw-r--r--spec/lib/gitlab/background_migration/batching_strategies/base_strategy_spec.rb15
-rw-r--r--spec/lib/gitlab/background_migration/batching_strategies/primary_key_batching_strategy_spec.rb4
-rw-r--r--spec/lib/gitlab/background_migration/encrypt_integration_properties_spec.rb63
-rw-r--r--spec/lib/gitlab/background_migration/job_coordinator_spec.rb60
-rw-r--r--spec/lib/gitlab/background_migration/migrate_personal_namespace_project_maintainer_to_owner_spec.rb82
-rw-r--r--spec/lib/gitlab/background_migration/nullify_orphan_runner_id_on_ci_builds_spec.rb49
-rw-r--r--spec/lib/gitlab/background_migration/remove_all_trace_expiration_dates_spec.rb53
-rw-r--r--spec/lib/gitlab/background_migration/reset_duplicate_ci_runners_token_encrypted_values_on_projects_spec.rb37
-rw-r--r--spec/lib/gitlab/background_migration/reset_duplicate_ci_runners_token_values_on_projects_spec.rb37
-rw-r--r--spec/lib/gitlab/ci/build/policy/refs_spec.rb23
-rw-r--r--spec/lib/gitlab/ci/config/entry/bridge_spec.rb24
-rw-r--r--spec/lib/gitlab/ci/config/entry/include/rules/rule_spec.rb4
-rw-r--r--spec/lib/gitlab/ci/config/entry/job_spec.rb24
-rw-r--r--spec/lib/gitlab/ci/config/entry/policy_spec.rb48
-rw-r--r--spec/lib/gitlab/ci/config/entry/reports/coverage_report_spec.rb57
-rw-r--r--spec/lib/gitlab/ci/config/entry/reports_spec.rb47
-rw-r--r--spec/lib/gitlab/ci/config/entry/rules/rule_spec.rb24
-rw-r--r--spec/lib/gitlab/ci/config/entry/trigger/forward_spec.rb64
-rw-r--r--spec/lib/gitlab/ci/config/entry/trigger_spec.rb92
-rw-r--r--spec/lib/gitlab/ci/config/external/file/local_spec.rb10
-rw-r--r--spec/lib/gitlab/ci/config/yaml/tags/reference_spec.rb17
-rw-r--r--spec/lib/gitlab/ci/parsers/coverage/cobertura_spec.rb702
-rw-r--r--spec/lib/gitlab/ci/parsers/coverage/sax_document_spec.rb725
-rw-r--r--spec/lib/gitlab/ci/parsers/security/common_spec.rb494
-rw-r--r--spec/lib/gitlab/ci/parsers/security/validators/schema_validator_spec.rb63
-rw-r--r--spec/lib/gitlab/ci/pipeline/chain/cancel_pending_pipelines_spec.rb75
-rw-r--r--spec/lib/gitlab/ci/pipeline/chain/create_spec.rb16
-rw-r--r--spec/lib/gitlab/ci/reports/security/report_spec.rb10
-rw-r--r--spec/lib/gitlab/ci/status/build/waiting_for_approval_spec.rb49
-rw-r--r--spec/lib/gitlab/ci/templates/auto_devops_gitlab_ci_yaml_spec.rb22
-rw-r--r--spec/lib/gitlab/ci/variables/builder/group_spec.rb209
-rw-r--r--spec/lib/gitlab/ci/variables/builder_spec.rb100
-rw-r--r--spec/lib/gitlab/ci/yaml_processor/dag_spec.rb10
-rw-r--r--spec/lib/gitlab/ci/yaml_processor_spec.rb38
-rw-r--r--spec/lib/gitlab/color_spec.rb132
-rw-r--r--spec/lib/gitlab/config/entry/validators_spec.rb43
-rw-r--r--spec/lib/gitlab/current_settings_spec.rb15
-rw-r--r--spec/lib/gitlab/database/async_indexes/migration_helpers_spec.rb190
-rw-r--r--spec/lib/gitlab/database/background_migration/batched_job_spec.rb112
-rw-r--r--spec/lib/gitlab/database/background_migration/batched_job_transition_log_spec.rb2
-rw-r--r--spec/lib/gitlab/database/background_migration/batched_migration_runner_spec.rb23
-rw-r--r--spec/lib/gitlab/database/background_migration/batched_migration_spec.rb10
-rw-r--r--spec/lib/gitlab/database/background_migration/batched_migration_wrapper_spec.rb1
-rw-r--r--spec/lib/gitlab/database/each_database_spec.rb82
-rw-r--r--spec/lib/gitlab/database/load_balancing/configuration_spec.rb7
-rw-r--r--spec/lib/gitlab/database/load_balancing/setup_spec.rb2
-rw-r--r--spec/lib/gitlab/database/load_balancing_spec.rb12
-rw-r--r--spec/lib/gitlab/database/migration_helpers/restrict_gitlab_schema_spec.rb561
-rw-r--r--spec/lib/gitlab/database/migrations/background_migration_helpers_spec.rb12
-rw-r--r--spec/lib/gitlab/database/migrations/observers/query_details_spec.rb2
-rw-r--r--spec/lib/gitlab/database/migrations/observers/query_log_spec.rb2
-rw-r--r--spec/lib/gitlab/database/migrations/observers/transaction_duration_spec.rb2
-rw-r--r--spec/lib/gitlab/database/migrations/runner_spec.rb18
-rw-r--r--spec/lib/gitlab/database/migrations/test_background_runner_spec.rb120
-rw-r--r--spec/lib/gitlab/database/partitioning_spec.rb14
-rw-r--r--spec/lib/gitlab/database/query_analyzer_spec.rb17
-rw-r--r--spec/lib/gitlab/database/query_analyzers/restrict_allowed_schemas_spec.rb161
-rw-r--r--spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_projects_spec.rb2
-rw-r--r--spec/lib/gitlab/database/transaction/context_spec.rb20
-rw-r--r--spec/lib/gitlab/database/transaction/observer_spec.rb67
-rw-r--r--spec/lib/gitlab/database/type/color_spec.rb41
-rw-r--r--spec/lib/gitlab/database_spec.rb71
-rw-r--r--spec/lib/gitlab/diff/file_spec.rb44
-rw-r--r--spec/lib/gitlab/diff/rendered/notebook/diff_file_spec.rb107
-rw-r--r--spec/lib/gitlab/email/attachment_uploader_spec.rb24
-rw-r--r--spec/lib/gitlab/email/handler/create_issue_handler_spec.rb31
-rw-r--r--spec/lib/gitlab/email/handler/service_desk_handler_spec.rb15
-rw-r--r--spec/lib/gitlab/email/receiver_spec.rb34
-rw-r--r--spec/lib/gitlab/error_tracking/processor/grpc_error_processor_spec.rb142
-rw-r--r--spec/lib/gitlab/error_tracking/processor/sidekiq_processor_spec.rb126
-rw-r--r--spec/lib/gitlab/error_tracking_spec.rb131
-rw-r--r--spec/lib/gitlab/etag_caching/middleware_spec.rb3
-rw-r--r--spec/lib/gitlab/etag_caching/router/rails_spec.rb136
-rw-r--r--spec/lib/gitlab/etag_caching/router/restful_spec.rb130
-rw-r--r--spec/lib/gitlab/etag_caching/router_spec.rb2
-rw-r--r--spec/lib/gitlab/experiment/rollout/feature_spec.rb19
-rw-r--r--spec/lib/gitlab/experimentation/controller_concern_spec.rb2
-rw-r--r--spec/lib/gitlab/experimentation/experiment_spec.rb2
-rw-r--r--spec/lib/gitlab/fips_spec.rb51
-rw-r--r--spec/lib/gitlab/form_builders/gitlab_ui_form_builder_spec.rb23
-rw-r--r--spec/lib/gitlab/git/wiki_spec.rb16
-rw-r--r--spec/lib/gitlab/git_access_snippet_spec.rb32
-rw-r--r--spec/lib/gitlab/gitaly_client/operation_service_spec.rb163
-rw-r--r--spec/lib/gitlab/gitaly_client/repository_service_spec.rb42
-rw-r--r--spec/lib/gitlab/github_import/importer/diff_note_importer_spec.rb22
-rw-r--r--spec/lib/gitlab/github_import/importer/pull_requests_importer_spec.rb9
-rw-r--r--spec/lib/gitlab/github_import/parallel_scheduling_spec.rb64
-rw-r--r--spec/lib/gitlab/graphql/loaders/batch_commit_loader_spec.rb48
-rw-r--r--spec/lib/gitlab/graphql/markdown_field_spec.rb12
-rw-r--r--spec/lib/gitlab/graphql/mount_mutation_spec.rb8
-rw-r--r--spec/lib/gitlab/harbor/client_spec.rb28
-rw-r--r--spec/lib/gitlab/health_checks/db_check_spec.rb17
-rw-r--r--spec/lib/gitlab/highlight_spec.rb76
-rw-r--r--spec/lib/gitlab/hook_data/issue_builder_spec.rb8
-rw-r--r--spec/lib/gitlab/import_export/all_models.yml8
-rw-r--r--spec/lib/gitlab/import_export/base/relation_object_saver_spec.rb132
-rw-r--r--spec/lib/gitlab/import_export/command_line_util_spec.rb153
-rw-r--r--spec/lib/gitlab/import_export/file_importer_spec.rb25
-rw-r--r--spec/lib/gitlab/import_export/group/object_builder_spec.rb12
-rw-r--r--spec/lib/gitlab/import_export/group/tree_restorer_spec.rb282
-rw-r--r--spec/lib/gitlab/import_export/json/streaming_serializer_spec.rb22
-rw-r--r--spec/lib/gitlab/import_export/project/relation_factory_spec.rb16
-rw-r--r--spec/lib/gitlab/import_export/project/tree_restorer_spec.rb32
-rw-r--r--spec/lib/gitlab/import_export/safe_model_attributes.yml1
-rw-r--r--spec/lib/gitlab/integrations/sti_type_spec.rb114
-rw-r--r--spec/lib/gitlab/json_cache_spec.rb88
-rw-r--r--spec/lib/gitlab/kubernetes/kubeconfig/template_spec.rb45
-rw-r--r--spec/lib/gitlab/mail_room/authenticator_spec.rb20
-rw-r--r--spec/lib/gitlab/mail_room/mail_room_spec.rb184
-rw-r--r--spec/lib/gitlab/merge_requests/commit_message_generator_spec.rb88
-rw-r--r--spec/lib/gitlab/merge_requests/mergeability/check_result_spec.rb4
-rw-r--r--spec/lib/gitlab/merge_requests/mergeability/results_store_spec.rb18
-rw-r--r--spec/lib/gitlab/metrics/dashboard/cache_spec.rb2
-rw-r--r--spec/lib/gitlab/null_request_store_spec.rb2
-rw-r--r--spec/lib/gitlab/omniauth_initializer_spec.rb197
-rw-r--r--spec/lib/gitlab/pages/settings_spec.rb2
-rw-r--r--spec/lib/gitlab/patch/action_cable_redis_listener_spec.rb28
-rw-r--r--spec/lib/gitlab/path_regex_spec.rb5
-rw-r--r--spec/lib/gitlab/process_supervisor_spec.rb170
-rw-r--r--spec/lib/gitlab/profiler_spec.rb24
-rw-r--r--spec/lib/gitlab/project_authorizations_spec.rb2
-rw-r--r--spec/lib/gitlab/regex_spec.rb15
-rw-r--r--spec/lib/gitlab/runtime_spec.rb20
-rw-r--r--spec/lib/gitlab/safe_request_loader_spec.rb180
-rw-r--r--spec/lib/gitlab/safe_request_store_spec.rb4
-rw-r--r--spec/lib/gitlab/sanitizers/exif_spec.rb118
-rw-r--r--spec/lib/gitlab/seeder_spec.rb20
-rw-r--r--spec/lib/gitlab/sidekiq_middleware/duplicate_jobs/duplicate_job_spec.rb86
-rw-r--r--spec/lib/gitlab/untrusted_regexp/ruby_syntax_spec.rb40
-rw-r--r--spec/lib/gitlab/url_blocker_spec.rb104
-rw-r--r--spec/lib/gitlab/usage/metric_definition_spec.rb22
-rw-r--r--spec/lib/gitlab/usage/metrics/instrumentations/cert_based_clusters_ff_metric_spec.rb21
-rw-r--r--spec/lib/gitlab/usage/metrics/instrumentations/database_metric_spec.rb22
-rw-r--r--spec/lib/gitlab/usage/metrics/names_suggestions/generator_spec.rb4
-rw-r--r--spec/lib/gitlab/usage/service_ping/instrumented_payload_spec.rb49
-rw-r--r--spec/lib/gitlab/usage/service_ping/payload_keys_processor_spec.rb56
-rw-r--r--spec/lib/gitlab/usage/service_ping_report_spec.rb222
-rw-r--r--spec/lib/gitlab/usage_counters/pod_logs_spec.rb7
-rw-r--r--spec/lib/gitlab/usage_data_counters/hll_redis_counter_spec.rb5
-rw-r--r--spec/lib/gitlab/usage_data_counters/service_usage_data_counter_spec.rb7
-rw-r--r--spec/lib/gitlab/usage_data_counters/work_item_activity_unique_counter_spec.rb63
-rw-r--r--spec/lib/gitlab/usage_data_queries_spec.rb13
-rw-r--r--spec/lib/gitlab/usage_data_spec.rb16
-rw-r--r--spec/lib/gitlab/utils/strong_memoize_spec.rb30
-rw-r--r--spec/lib/gitlab/utils_spec.rb71
-rw-r--r--spec/lib/gitlab/wiki_pages/front_matter_parser_spec.rb29
-rw-r--r--spec/lib/gitlab_spec.rb119
-rw-r--r--spec/lib/google_api/cloud_platform/client_spec.rb16
-rw-r--r--spec/lib/learn_gitlab/onboarding_spec.rb2
-rw-r--r--spec/lib/learn_gitlab/project_spec.rb3
-rw-r--r--spec/lib/peek/views/active_record_spec.rb12
-rw-r--r--spec/lib/security/ci_configuration/sast_build_action_spec.rb8
-rw-r--r--spec/lib/security/ci_configuration/sast_iac_build_action_spec.rb120
-rw-r--r--spec/lib/serializers/unsafe_json_spec.rb27
-rw-r--r--spec/lib/sidebars/concerns/work_item_hierarchy_spec.rb21
-rw-r--r--spec/lib/sidebars/groups/menus/kubernetes_menu_spec.rb10
-rw-r--r--spec/lib/sidebars/groups/menus/packages_registries_menu_spec.rb35
-rw-r--r--spec/lib/sidebars/groups/menus/settings_menu_spec.rb12
-rw-r--r--spec/lib/sidebars/projects/menus/infrastructure_menu_spec.rb8
-rw-r--r--spec/lib/sidebars/projects/menus/packages_registries_menu_spec.rb21
-rw-r--r--spec/lib/sidebars/projects/menus/project_information_menu_spec.rb6
-rw-r--r--spec/mailers/emails/profile_spec.rb33
-rw-r--r--spec/metrics_server/metrics_server_spec.rb48
-rw-r--r--spec/migrations/20210805192450_update_trial_plans_ci_daily_pipeline_schedule_triggers_spec.rb8
-rw-r--r--spec/migrations/20210812013042_remove_duplicate_project_authorizations_spec.rb62
-rw-r--r--spec/migrations/20220204194347_encrypt_integration_properties_spec.rb40
-rw-r--r--spec/migrations/20220208080921_schedule_migrate_personal_namespace_project_maintainer_to_owner_spec.rb20
-rw-r--r--spec/migrations/20220222192524_create_not_null_constraint_releases_tag_spec.rb23
-rw-r--r--spec/migrations/20220222192525_remove_null_releases_spec.rb22
-rw-r--r--spec/migrations/20220305223212_add_security_training_providers_spec.rb25
-rw-r--r--spec/migrations/20220307192610_remove_duplicate_project_tag_releases_spec.rb47
-rw-r--r--spec/migrations/20220309084954_remove_leftover_external_pull_request_deletions_spec.rb43
-rw-r--r--spec/migrations/20220310141349_remove_dependency_list_usage_data_from_redis_spec.rb23
-rw-r--r--spec/migrations/add_new_trail_plans_spec.rb8
-rw-r--r--spec/migrations/add_open_source_plan_spec.rb8
-rw-r--r--spec/migrations/backfill_all_project_namespaces_spec.rb37
-rw-r--r--spec/migrations/backfill_cycle_analytics_aggregations_spec.rb36
-rw-r--r--spec/migrations/backfill_member_namespace_id_for_group_members_spec.rb29
-rw-r--r--spec/migrations/recreate_index_security_ci_builds_on_name_and_id_parser_with_new_features_spec.rb28
-rw-r--r--spec/migrations/remove_not_null_contraint_on_title_from_sprints_spec.rb29
-rw-r--r--spec/migrations/update_application_settings_container_registry_exp_pol_worker_capacity_default_spec.rb40
-rw-r--r--spec/models/analytics/cycle_analytics/aggregation_spec.rb138
-rw-r--r--spec/models/application_record_spec.rb12
-rw-r--r--spec/models/application_setting_spec.rb4
-rw-r--r--spec/models/broadcast_message_spec.rb150
-rw-r--r--spec/models/bulk_imports/export_status_spec.rb11
-rw-r--r--spec/models/ci/bridge_spec.rb68
-rw-r--r--spec/models/ci/build_spec.rb32
-rw-r--r--spec/models/ci/group_variable_spec.rb8
-rw-r--r--spec/models/ci/pipeline_schedule_spec.rb60
-rw-r--r--spec/models/ci/pipeline_spec.rb37
-rw-r--r--spec/models/ci/runner_spec.rb2
-rw-r--r--spec/models/ci/secure_file_spec.rb4
-rw-r--r--spec/models/concerns/batch_destroy_dependent_associations_spec.rb31
-rw-r--r--spec/models/concerns/blocks_json_serialization_spec.rb22
-rw-r--r--spec/models/concerns/blocks_unsafe_serialization_spec.rb17
-rw-r--r--spec/models/concerns/ci/has_deployment_name_spec.rb34
-rw-r--r--spec/models/concerns/deployment_platform_spec.rb12
-rw-r--r--spec/models/concerns/issuable_link_spec.rb43
-rw-r--r--spec/models/concerns/issuable_spec.rb43
-rw-r--r--spec/models/concerns/mentionable_spec.rb1
-rw-r--r--spec/models/concerns/pg_full_text_searchable_spec.rb177
-rw-r--r--spec/models/concerns/runners_token_prefixable_spec.rb15
-rw-r--r--spec/models/concerns/sensitive_serializable_hash_spec.rb150
-rw-r--r--spec/models/concerns/spammable_spec.rb4
-rw-r--r--spec/models/concerns/token_authenticatable_spec.rb6
-rw-r--r--spec/models/concerns/token_authenticatable_strategies/base_spec.rb18
-rw-r--r--spec/models/concerns/token_authenticatable_strategies/digest_spec.rb18
-rw-r--r--spec/models/concerns/token_authenticatable_strategies/encrypted_spec.rb10
-rw-r--r--spec/models/container_repository_spec.rb54
-rw-r--r--spec/models/customer_relations/contact_spec.rb55
-rw-r--r--spec/models/customer_relations/issue_contact_spec.rb30
-rw-r--r--spec/models/customer_relations/organization_spec.rb17
-rw-r--r--spec/models/dependency_proxy/blob_spec.rb4
-rw-r--r--spec/models/dependency_proxy/manifest_spec.rb4
-rw-r--r--spec/models/environment_spec.rb15
-rw-r--r--spec/models/error_tracking/project_error_tracking_setting_spec.rb19
-rw-r--r--spec/models/event_collection_spec.rb17
-rw-r--r--spec/models/external_pull_request_spec.rb4
-rw-r--r--spec/models/group_spec.rb135
-rw-r--r--spec/models/hooks/web_hook_log_spec.rb2
-rw-r--r--spec/models/hooks/web_hook_spec.rb12
-rw-r--r--spec/models/incident_management/issuable_escalation_status_spec.rb2
-rw-r--r--spec/models/instance_configuration_spec.rb6
-rw-r--r--spec/models/integration_spec.rb306
-rw-r--r--spec/models/integrations/base_issue_tracker_spec.rb22
-rw-r--r--spec/models/integrations/field_spec.rb118
-rw-r--r--spec/models/integrations/harbor_spec.rb133
-rw-r--r--spec/models/integrations/jira_spec.rb26
-rw-r--r--spec/models/integrations/slack_spec.rb2
-rw-r--r--spec/models/issue_link_spec.rb65
-rw-r--r--spec/models/issue_spec.rb1
-rw-r--r--spec/models/label_spec.rb15
-rw-r--r--spec/models/merge_request_assignee_spec.rb20
-rw-r--r--spec/models/merge_request_reviewer_spec.rb20
-rw-r--r--spec/models/merge_request_spec.rb109
-rw-r--r--spec/models/milestone_spec.rb11
-rw-r--r--spec/models/namespace/root_storage_statistics_spec.rb2
-rw-r--r--spec/models/namespace_spec.rb12
-rw-r--r--spec/models/packages/pypi/metadatum_spec.rb3
-rw-r--r--spec/models/personal_access_token_spec.rb11
-rw-r--r--spec/models/preloaders/environments/deployment_preloader_spec.rb18
-rw-r--r--spec/models/project_authorization_spec.rb50
-rw-r--r--spec/models/project_pages_metadatum_spec.rb11
-rw-r--r--spec/models/project_spec.rb218
-rw-r--r--spec/models/project_team_spec.rb2
-rw-r--r--spec/models/projects/build_artifacts_size_refresh_spec.rb227
-rw-r--r--spec/models/projects/topic_spec.rb14
-rw-r--r--spec/models/projects/triggered_hooks_spec.rb48
-rw-r--r--spec/models/repository_spec.rb8
-rw-r--r--spec/models/snippet_spec.rb81
-rw-r--r--spec/models/user_spec.rb108
-rw-r--r--spec/models/users/credit_card_validation_spec.rb2
-rw-r--r--spec/models/users/saved_reply_spec.rb16
-rw-r--r--spec/models/wiki_page_spec.rb57
-rw-r--r--spec/models/work_item_spec.rb12
-rw-r--r--spec/policies/application_setting_policy_spec.rb40
-rw-r--r--spec/policies/global_policy_spec.rb30
-rw-r--r--spec/policies/group_policy_spec.rb64
-rw-r--r--spec/policies/issue_policy_spec.rb32
-rw-r--r--spec/policies/project_policy_spec.rb96
-rw-r--r--spec/policies/work_item_policy_spec.rb94
-rw-r--r--spec/presenters/blob_presenter_spec.rb46
-rw-r--r--spec/presenters/blobs/notebook_presenter_spec.rb21
-rw-r--r--spec/presenters/ci/build_runner_presenter_spec.rb18
-rw-r--r--spec/presenters/group_clusterable_presenter_spec.rb6
-rw-r--r--spec/presenters/instance_clusterable_presenter_spec.rb6
-rw-r--r--spec/presenters/merge_request_presenter_spec.rb34
-rw-r--r--spec/presenters/project_clusterable_presenter_spec.rb6
-rw-r--r--spec/presenters/project_presenter_spec.rb6
-rw-r--r--spec/presenters/projects/security/configuration_presenter_spec.rb2
-rw-r--r--spec/presenters/search_service_presenter_spec.rb22
-rw-r--r--spec/presenters/user_presenter_spec.rb65
-rw-r--r--spec/requests/admin/background_migrations_controller_spec.rb8
-rw-r--r--spec/requests/api/admin/instance_clusters_spec.rb20
-rw-r--r--spec/requests/api/broadcast_messages_spec.rb23
-rw-r--r--spec/requests/api/ci/jobs_spec.rb51
-rw-r--r--spec/requests/api/ci/pipelines_spec.rb17
-rw-r--r--spec/requests/api/ci/runner/jobs_request_post_spec.rb6
-rw-r--r--spec/requests/api/ci/runner/jobs_trace_spec.rb8
-rw-r--r--spec/requests/api/ci/runner/runners_post_spec.rb8
-rw-r--r--spec/requests/api/ci/runner/runners_reset_spec.rb65
-rw-r--r--spec/requests/api/ci/runners_spec.rb8
-rw-r--r--spec/requests/api/ci/secure_files_spec.rb187
-rw-r--r--spec/requests/api/commits_spec.rb9
-rw-r--r--spec/requests/api/container_repositories_spec.rb64
-rw-r--r--spec/requests/api/deploy_tokens_spec.rb106
-rw-r--r--spec/requests/api/error_tracking/collector_spec.rb15
-rw-r--r--spec/requests/api/error_tracking/project_settings_spec.rb59
-rw-r--r--spec/requests/api/generic_packages_spec.rb11
-rw-r--r--spec/requests/api/graphql/ci/pipelines_spec.rb33
-rw-r--r--spec/requests/api/graphql/ci/runner_spec.rb33
-rw-r--r--spec/requests/api/graphql/ci/runner_web_url_edge_spec.rb57
-rw-r--r--spec/requests/api/graphql/container_repository/container_repository_details_spec.rb80
-rw-r--r--spec/requests/api/graphql/group/group_members_spec.rb46
-rw-r--r--spec/requests/api/graphql/group/issues_spec.rb25
-rw-r--r--spec/requests/api/graphql/group/merge_requests_spec.rb21
-rw-r--r--spec/requests/api/graphql/group/work_item_types_spec.rb4
-rw-r--r--spec/requests/api/graphql/mutations/issues/set_crm_contacts_spec.rb14
-rw-r--r--spec/requests/api/graphql/mutations/notes/create/note_spec.rb33
-rw-r--r--spec/requests/api/graphql/mutations/work_items/create_from_task_spec.rb87
-rw-r--r--spec/requests/api/graphql/namespace_query_spec.rb3
-rw-r--r--spec/requests/api/graphql/project/jira_service_spec.rb9
-rw-r--r--spec/requests/api/graphql/project/merge_request_spec.rb18
-rw-r--r--spec/requests/api/graphql/project/work_item_types_spec.rb4
-rw-r--r--spec/requests/api/graphql/query_spec.rb24
-rw-r--r--spec/requests/api/graphql/work_item_spec.rb75
-rw-r--r--spec/requests/api/group_clusters_spec.rb20
-rw-r--r--spec/requests/api/group_labels_spec.rb10
-rw-r--r--spec/requests/api/integrations_spec.rb10
-rw-r--r--spec/requests/api/internal/kubernetes_spec.rb1
-rw-r--r--spec/requests/api/internal/mail_room_spec.rb16
-rw-r--r--spec/requests/api/invitations_spec.rb21
-rw-r--r--spec/requests/api/issues/post_projects_issues_spec.rb2
-rw-r--r--spec/requests/api/issues/put_projects_issues_spec.rb22
-rw-r--r--spec/requests/api/labels_spec.rb22
-rw-r--r--spec/requests/api/members_spec.rb6
-rw-r--r--spec/requests/api/notes_spec.rb89
-rw-r--r--spec/requests/api/project_attributes.yml2
-rw-r--r--spec/requests/api/project_clusters_spec.rb20
-rw-r--r--spec/requests/api/project_import_spec.rb87
-rw-r--r--spec/requests/api/project_snippets_spec.rb4
-rw-r--r--spec/requests/api/projects_spec.rb34
-rw-r--r--spec/requests/api/pypi_packages_spec.rb8
-rw-r--r--spec/requests/api/releases_spec.rb6
-rw-r--r--spec/requests/api/repositories_spec.rb7
-rw-r--r--spec/requests/api/search_spec.rb11
-rw-r--r--spec/requests/api/snippets_spec.rb4
-rw-r--r--spec/requests/api/system_hooks_spec.rb49
-rw-r--r--spec/requests/api/terraform/state_spec.rb4
-rw-r--r--spec/requests/api/topics_spec.rb52
-rw-r--r--spec/requests/api/user_counts_spec.rb15
-rw-r--r--spec/requests/api/users_spec.rb58
-rw-r--r--spec/requests/api/wikis_spec.rb54
-rw-r--r--spec/requests/content_security_policy_spec.rb50
-rw-r--r--spec/requests/git_http_spec.rb48
-rw-r--r--spec/requests/groups/crm/contacts_controller_spec.rb6
-rw-r--r--spec/requests/groups/crm/organizations_controller_spec.rb6
-rw-r--r--spec/requests/groups/deploy_tokens_controller_spec.rb40
-rw-r--r--spec/requests/groups/harbor/repositories_controller_spec.rb69
-rw-r--r--spec/requests/jira_connect/oauth_callbacks_controller_spec.rb22
-rw-r--r--spec/requests/projects/google_cloud/deployments_controller_spec.rb71
-rw-r--r--spec/requests/projects/google_cloud/gcp_regions_controller_spec.rb152
-rw-r--r--spec/requests/projects/google_cloud/revoke_oauth_controller_spec.rb86
-rw-r--r--spec/requests/projects/google_cloud/service_accounts_controller_spec.rb105
-rw-r--r--spec/requests/projects/google_cloud_controller_spec.rb78
-rw-r--r--spec/requests/projects/harbor/repositories_controller_spec.rb69
-rw-r--r--spec/requests/projects/redirect_controller_spec.rb66
-rw-r--r--spec/routing/project_routing_spec.rb40
-rw-r--r--spec/rubocop/cop/database/establish_connection_spec.rb2
-rw-r--r--spec/rubocop/cop/database/multiple_databases_spec.rb10
-rw-r--r--spec/rubocop/cop/graphql/graphql_name_position_spec.rb44
-rw-r--r--spec/rubocop/formatter/todo_formatter_spec.rb284
-rw-r--r--spec/rubocop/todo_dir_spec.rb218
-rw-r--r--spec/serializers/ci/pipeline_entity_spec.rb3
-rw-r--r--spec/serializers/cluster_error_entity_spec.rb35
-rw-r--r--spec/serializers/clusters/kubernetes_error_entity_spec.rb35
-rw-r--r--spec/serializers/environment_entity_spec.rb2
-rw-r--r--spec/serializers/environment_serializer_spec.rb19
-rw-r--r--spec/serializers/fork_namespace_entity_spec.rb22
-rw-r--r--spec/serializers/issue_sidebar_basic_entity_spec.rb28
-rw-r--r--spec/serializers/label_serializer_spec.rb2
-rw-r--r--spec/serializers/merge_request_widget_entity_spec.rb2
-rw-r--r--spec/serializers/pipeline_details_entity_spec.rb14
-rw-r--r--spec/serializers/service_event_entity_spec.rb4
-rw-r--r--spec/serializers/service_field_entity_spec.rb4
-rw-r--r--spec/services/auth/container_registry_authentication_service_spec.rb139
-rw-r--r--spec/services/authorized_project_update/find_records_due_for_refresh_service_spec.rb33
-rw-r--r--spec/services/bulk_create_integration_service_spec.rb20
-rw-r--r--spec/services/ci/abort_pipelines_service_spec.rb43
-rw-r--r--spec/services/ci/after_requeue_job_service_spec.rb255
-rw-r--r--spec/services/ci/create_downstream_pipeline_service_spec.rb8
-rw-r--r--spec/services/ci/create_pipeline_service/artifacts_spec.rb67
-rw-r--r--spec/services/ci/create_pipeline_service/parameter_content_spec.rb2
-rw-r--r--spec/services/ci/create_pipeline_service/tags_spec.rb25
-rw-r--r--spec/services/ci/destroy_secure_file_service_spec.rb32
-rw-r--r--spec/services/ci/job_artifacts/create_service_spec.rb2
-rw-r--r--spec/services/ci/parse_dotenv_artifact_service_spec.rb24
-rw-r--r--spec/services/ci/register_runner_service_spec.rb234
-rw-r--r--spec/services/ci/retry_pipeline_service_spec.rb46
-rw-r--r--spec/services/ci/runners/assign_runner_service_spec.rb40
-rw-r--r--spec/services/ci/runners/register_runner_service_spec.rb234
-rw-r--r--spec/services/ci/runners/reset_registration_token_service_spec.rb76
-rw-r--r--spec/services/ci/runners/unassign_runner_service_spec.rb43
-rw-r--r--spec/services/ci/runners/unregister_runner_service_spec.rb15
-rw-r--r--spec/services/ci/runners/update_runner_service_spec.rb70
-rw-r--r--spec/services/ci/unregister_runner_service_spec.rb15
-rw-r--r--spec/services/ci/update_runner_service_spec.rb70
-rw-r--r--spec/services/concerns/rate_limited_service_spec.rb69
-rw-r--r--spec/services/error_tracking/base_service_spec.rb12
-rw-r--r--spec/services/error_tracking/collect_error_service_spec.rb17
-rw-r--r--spec/services/google_cloud/create_service_accounts_service_spec.rb25
-rw-r--r--spec/services/google_cloud/gcp_region_add_or_replace_service_spec.rb28
-rw-r--r--spec/services/google_cloud/service_accounts_service_spec.rb14
-rw-r--r--spec/services/groups/create_service_spec.rb20
-rw-r--r--spec/services/groups/deploy_tokens/revoke_service_spec.rb28
-rw-r--r--spec/services/groups/destroy_service_spec.rb13
-rw-r--r--spec/services/import/gitlab_projects/create_project_from_remote_file_service_spec.rb201
-rw-r--r--spec/services/import/gitlab_projects/create_project_from_uploaded_file_service_spec.rb71
-rw-r--r--spec/services/import/gitlab_projects/create_project_service_spec.rb179
-rw-r--r--spec/services/import/gitlab_projects/file_acquisition_strategies/file_upload_spec.rb26
-rw-r--r--spec/services/import/gitlab_projects/file_acquisition_strategies/remote_file_s3_spec.rb136
-rw-r--r--spec/services/import/gitlab_projects/file_acquisition_strategies/remote_file_spec.rb149
-rw-r--r--spec/services/issue_links/create_service_spec.rb188
-rw-r--r--spec/services/issue_links/destroy_service_spec.rb61
-rw-r--r--spec/services/issues/create_service_spec.rb85
-rw-r--r--spec/services/issues/set_crm_contacts_service_spec.rb2
-rw-r--r--spec/services/issues/update_service_spec.rb38
-rw-r--r--spec/services/labels/create_service_spec.rb3
-rw-r--r--spec/services/labels/promote_service_spec.rb2
-rw-r--r--spec/services/labels/update_service_spec.rb2
-rw-r--r--spec/services/members/projects/creator_service_spec.rb4
-rw-r--r--spec/services/merge_requests/approval_service_spec.rb2
-rw-r--r--spec/services/merge_requests/bulk_remove_attention_requested_service_spec.rb4
-rw-r--r--spec/services/merge_requests/create_service_spec.rb9
-rw-r--r--spec/services/merge_requests/handle_assignees_change_service_spec.rb8
-rw-r--r--spec/services/merge_requests/merge_orchestration_service_spec.rb4
-rw-r--r--spec/services/merge_requests/mergeability/check_broken_status_service_spec.rb43
-rw-r--r--spec/services/merge_requests/mergeability/check_discussions_status_service_spec.rb57
-rw-r--r--spec/services/merge_requests/mergeability/check_draft_status_service_spec.rb43
-rw-r--r--spec/services/merge_requests/mergeability/check_open_status_service_spec.rb43
-rw-r--r--spec/services/merge_requests/mergeability/run_checks_service_spec.rb15
-rw-r--r--spec/services/merge_requests/reload_merge_head_diff_service_spec.rb10
-rw-r--r--spec/services/merge_requests/remove_attention_requested_service_spec.rb31
-rw-r--r--spec/services/merge_requests/toggle_attention_requested_service_spec.rb25
-rw-r--r--spec/services/merge_requests/update_service_spec.rb8
-rw-r--r--spec/services/notification_service_spec.rb28
-rw-r--r--spec/services/packages/pypi/create_package_service_spec.rb16
-rw-r--r--spec/services/personal_access_tokens/create_service_spec.rb8
-rw-r--r--spec/services/projects/branches_by_mode_service_spec.rb26
-rw-r--r--spec/services/projects/container_repository/cleanup_tags_service_spec.rb24
-rw-r--r--spec/services/projects/create_service_spec.rb27
-rw-r--r--spec/services/projects/destroy_service_spec.rb35
-rw-r--r--spec/services/projects/import_service_spec.rb22
-rw-r--r--spec/services/projects/refresh_build_artifacts_size_statistics_service_spec.rb102
-rw-r--r--spec/services/projects/update_pages_service_spec.rb1
-rw-r--r--spec/services/quick_actions/interpret_service_spec.rb10
-rw-r--r--spec/services/repositories/destroy_rollback_service_spec.rb17
-rw-r--r--spec/services/repositories/destroy_service_spec.rb22
-rw-r--r--spec/services/security/merge_reports_service_spec.rb13
-rw-r--r--spec/services/service_ping/build_payload_service_spec.rb4
-rw-r--r--spec/services/spam/spam_action_service_spec.rb95
-rw-r--r--spec/services/spam/spam_params_spec.rb50
-rw-r--r--spec/services/spam/spam_verdict_service_spec.rb30
-rw-r--r--spec/services/system_note_service_spec.rb12
-rw-r--r--spec/services/system_notes/issuables_service_spec.rb8
-rw-r--r--spec/services/todo_service_spec.rb22
-rw-r--r--spec/services/users/refresh_authorized_projects_service_spec.rb31
-rw-r--r--spec/services/users/saved_replies/create_service_spec.rb44
-rw-r--r--spec/services/users/saved_replies/update_service_spec.rb40
-rw-r--r--spec/services/web_hook_service_spec.rb210
-rw-r--r--spec/services/web_hooks/log_execution_service_spec.rb237
-rw-r--r--spec/services/work_items/create_and_link_service_spec.rb96
-rw-r--r--spec/services/work_items/create_from_task_service_spec.rb97
-rw-r--r--spec/services/work_items/task_list_reference_replacement_service_spec.rb106
-rw-r--r--spec/services/work_items/update_service_spec.rb4
-rw-r--r--spec/spec_helper.rb26
-rw-r--r--spec/support/enable_multiple_database_metrics_by_default.rb8
-rw-r--r--spec/support/event_store.rb7
-rw-r--r--spec/support/helpers/ci/template_helpers.rb2
-rw-r--r--spec/support/helpers/content_security_policy_helpers.rb20
-rw-r--r--spec/support/helpers/database_connection_helpers.rb11
-rw-r--r--spec/support/helpers/graphql_helpers.rb6
-rw-r--r--spec/support/helpers/migrations_helpers.rb8
-rw-r--r--spec/support/helpers/navbar_structure_helper.rb8
-rw-r--r--spec/support/helpers/next_found_instance_of.rb32
-rw-r--r--spec/support/helpers/search_helpers.rb6
-rw-r--r--spec/support/helpers/sorting_helper.rb1
-rw-r--r--spec/support/helpers/stub_configuration.rb16
-rw-r--r--spec/support/helpers/terms_helper.rb4
-rw-r--r--spec/support/helpers/test_env.rb5
-rw-r--r--spec/support/helpers/usage_data_helpers.rb1
-rw-r--r--spec/support/matchers/be_color.rb20
-rw-r--r--spec/support/matchers/event_store.rb37
-rw-r--r--spec/support/matchers/pushed_frontend_feature_flags_matcher.rb8
-rw-r--r--spec/support/sentry.rb13
-rw-r--r--spec/support/shared_contexts/cache_allowed_users_in_namespace_shared_context.rb4
-rw-r--r--spec/support/shared_contexts/container_repositories_shared_context.rb9
-rw-r--r--spec/support/shared_contexts/lib/container_registry/client_stubs_shared_context.rb20
-rw-r--r--spec/support/shared_contexts/navbar_structure_context.rb3
-rw-r--r--spec/support/shared_contexts/spam_constants.rb5
-rw-r--r--spec/support/shared_examples/attention_request_cache_invalidation_examples.rb15
-rw-r--r--spec/support/shared_examples/blocks_unsafe_serialization_shared_examples.rb26
-rw-r--r--spec/support/shared_examples/controllers/clusters_controller_shared_examples.rb30
-rw-r--r--spec/support/shared_examples/controllers/rate_limited_endpoint_shared_examples.rb14
-rw-r--r--spec/support/shared_examples/controllers/unique_hll_events_examples.rb6
-rw-r--r--spec/support/shared_examples/controllers/uploads_actions_shared_examples.rb30
-rw-r--r--spec/support/shared_examples/controllers/wiki_actions_shared_examples.rb4
-rw-r--r--spec/support/shared_examples/features/clusters_shared_examples.rb14
-rw-r--r--spec/support/shared_examples/features/container_registry_shared_examples.rb17
-rw-r--r--spec/support/shared_examples/features/integrations/user_activates_mattermost_slash_command_integration_shared_examples.rb4
-rw-r--r--spec/support/shared_examples/features/manage_applications_shared_examples.rb2
-rw-r--r--spec/support/shared_examples/features/multiple_assignees_widget_mr_shared_examples.rb47
-rw-r--r--spec/support/shared_examples/features/project_upload_files_shared_examples.rb4
-rw-r--r--spec/support/shared_examples/features/wiki/user_creates_wiki_page_shared_examples.rb14
-rw-r--r--spec/support/shared_examples/features/wiki/user_updates_wiki_page_shared_examples.rb20
-rw-r--r--spec/support/shared_examples/features/wiki/user_views_wiki_page_shared_examples.rb15
-rw-r--r--spec/support/shared_examples/features/wiki/user_views_wiki_pages_shared_examples.rb2
-rw-r--r--spec/support/shared_examples/graphql/members_shared_examples.rb6
-rw-r--r--spec/support/shared_examples/graphql/mutations/security/ci_configuration_shared_examples.rb18
-rw-r--r--spec/support/shared_examples/graphql/types/merge_request_interactions_type_shared_examples.rb57
-rw-r--r--spec/support/shared_examples/integrations/integration_settings_form.rb11
-rw-r--r--spec/support/shared_examples/lib/gitlab/database/background_migration_job_shared_examples.rb4
-rw-r--r--spec/support/shared_examples/lib/gitlab/usage_data_counters/usage_counter_shared_examples.rb40
-rw-r--r--spec/support/shared_examples/lib/wikis_api_examples.rb76
-rw-r--r--spec/support/shared_examples/metrics/active_record_subscriber_shared_examples.rb35
-rw-r--r--spec/support/shared_examples/models/atomic_internal_id_shared_examples.rb2
-rw-r--r--spec/support/shared_examples/models/concerns/integrations/slack_mattermost_notifier_shared_examples.rb10
-rw-r--r--spec/support/shared_examples/models/concerns/limitable_shared_examples.rb2
-rw-r--r--spec/support/shared_examples/models/concerns/timebox_shared_examples.rb11
-rw-r--r--spec/support/shared_examples/models/concerns/update_namespace_statistics_shared_examples.rb54
-rw-r--r--spec/support/shared_examples/models/issuable_link_shared_examples.rb65
-rw-r--r--spec/support/shared_examples/models/member_shared_examples.rb45
-rw-r--r--spec/support/shared_examples/models/resource_event_shared_examples.rb28
-rw-r--r--spec/support/shared_examples/models/runners_token_prefix_shared_examples.rb13
-rw-r--r--spec/support/shared_examples/models/wiki_shared_examples.rb27
-rw-r--r--spec/support/shared_examples/namespaces/traversal_scope_examples.rb26
-rw-r--r--spec/support/shared_examples/requests/api/conan_packages_shared_examples.rb21
-rw-r--r--spec/support/shared_examples/requests/api/time_tracking_shared_examples.rb8
-rw-r--r--spec/support/shared_examples/requests/clusters/certificate_based_clusters_feature_flag_shared_examples.rb15
-rw-r--r--spec/support/shared_examples/row_lock_shared_examples.rb2
-rw-r--r--spec/support/shared_examples/sends_git_audit_streaming_event_shared_examples.rb61
-rw-r--r--spec/support/shared_examples/serializers/environment_serializer_shared_examples.rb17
-rw-r--r--spec/support/shared_examples/serializers/note_entity_shared_examples.rb23
-rw-r--r--spec/support/shared_examples/services/container_registry_auth_service_shared_examples.rb8
-rw-r--r--spec/support/shared_examples/services/incident_shared_examples.rb2
-rw-r--r--spec/support/shared_examples/services/issuable_links/create_links_shared_examples.rb133
-rw-r--r--spec/support/shared_examples/services/issuable_links/destroyable_issuable_links_shared_examples.rb42
-rw-r--r--spec/support/shared_examples/services/rate_limited_service_shared_examples.rb73
-rw-r--r--spec/support/shared_examples/services/security/ci_configuration/create_service_shared_examples.rb12
-rw-r--r--spec/support/shared_examples/workers/batched_background_migration_worker_shared_examples.rb198
-rw-r--r--spec/support/shared_examples/workers/concerns/git_garbage_collect_methods_shared_examples.rb70
-rw-r--r--spec/support/shared_examples/workers/concerns/reenqueuer_shared_examples.rb15
-rw-r--r--spec/support/silence_stdout.rb12
-rw-r--r--spec/support/view_component.rb7
-rw-r--r--spec/tasks/dev_rake_spec.rb38
-rw-r--r--spec/tasks/gitlab/background_migrations_rake_spec.rb127
-rw-r--r--spec/tasks/gitlab/backup_rake_spec.rb29
-rw-r--r--spec/tasks/gitlab/db_rake_spec.rb115
-rw-r--r--spec/tasks/gitlab/refresh_project_statistics_build_artifacts_size_rake_spec.rb48
-rw-r--r--spec/tasks/gitlab/setup_rake_spec.rb141
-rw-r--r--spec/tasks/rubocop_rake_spec.rb168
-rw-r--r--spec/tooling/danger/changelog_spec.rb467
-rw-r--r--spec/tooling/danger/datateam_spec.rb8
-rw-r--r--spec/tooling/danger/project_helper_spec.rb28
-rw-r--r--spec/tooling/docs/deprecation_handling_spec.rb2
-rw-r--r--spec/tooling/quality/test_level_spec.rb4
-rw-r--r--spec/validators/array_members_validator_spec.rb1
-rw-r--r--spec/validators/color_validator_spec.rb24
-rw-r--r--spec/validators/cron_validator_spec.rb2
-rw-r--r--spec/validators/future_date_validator_spec.rb1
-rw-r--r--spec/validators/import/gitlab_projects/remote_file_validator_spec.rb70
-rw-r--r--spec/views/admin/application_settings/_eks.html.haml_spec.rb4
-rw-r--r--spec/views/admin/application_settings/repository.html.haml_spec.rb5
-rw-r--r--spec/views/admin/broadcast_messages/index.html.haml_spec.rb36
-rw-r--r--spec/views/devise/sessions/new.html.haml_spec.rb2
-rw-r--r--spec/views/devise/shared/_signup_box.html.haml_spec.rb6
-rw-r--r--spec/views/groups/group_members/index.html.haml_spec.rb42
-rw-r--r--spec/views/layouts/_header_search.html.haml_spec.rb113
-rw-r--r--spec/views/layouts/_published_experiments.html.haml_spec.rb32
-rw-r--r--spec/views/projects/commits/_commit.html.haml_spec.rb6
-rw-r--r--spec/views/projects/empty.html.haml_spec.rb15
-rw-r--r--spec/views/projects/project_members/index.html.haml_spec.rb33
-rw-r--r--spec/views/projects/runners/_specific_runners.html.haml_spec.rb4
-rw-r--r--spec/views/projects/tags/index.html.haml_spec.rb6
-rw-r--r--spec/views/search/_results.html.haml_spec.rb39
-rw-r--r--spec/views/shared/_gl_toggle.haml_spec.rb85
-rw-r--r--spec/views/shared/_global_alert.html.haml_spec.rb29
-rw-r--r--spec/views/shared/issuable/_sidebar.html.haml_spec.rb31
-rw-r--r--spec/views/shared/wikis/_sidebar.html.haml_spec.rb2
-rw-r--r--spec/workers/bulk_imports/export_request_worker_spec.rb25
-rw-r--r--spec/workers/bulk_imports/pipeline_worker_spec.rb28
-rw-r--r--spec/workers/database/batched_background_migration/ci_database_worker_spec.rb7
-rw-r--r--spec/workers/database/batched_background_migration_worker_spec.rb118
-rw-r--r--spec/workers/deployments/hooks_worker_spec.rb4
-rw-r--r--spec/workers/every_sidekiq_worker_spec.rb1
-rw-r--r--spec/workers/loose_foreign_keys/cleanup_worker_spec.rb49
-rw-r--r--spec/workers/projects/refresh_build_artifacts_size_statistics_worker_spec.rb96
-rw-r--r--spec/workers/projects/schedule_refresh_build_artifacts_size_statistics_worker_spec.rb17
-rw-r--r--spec/workers/quality/test_data_cleanup_worker_spec.rb44
-rw-r--r--spec/workers/web_hook_worker_spec.rb9
-rw-r--r--storybook/config/webpack.config.js32
-rw-r--r--storybook/package.json3
-rw-r--r--storybook/yarn.lock1065
-rw-r--r--tooling/danger/changelog.rb232
-rw-r--r--tooling/danger/project_helper.rb16
-rw-r--r--tooling/docs/deprecation_handling.rb2
-rw-r--r--tooling/graphql/docs/helper.rb2
-rw-r--r--tooling/quality/test_level.rb1
-rw-r--r--vendor/assets/javascripts/vue-virtual-scroller/src/components/RecycleScroller.vue1
-rw-r--r--workhorse/.tool-versions2
-rw-r--r--workhorse/backend.go4
-rw-r--r--workhorse/backend_test.go3
-rw-r--r--workhorse/go.mod2
-rw-r--r--workhorse/go.sum87
-rw-r--r--workhorse/internal/artifacts/artifacts_store_test.go335
-rw-r--r--workhorse/internal/artifacts/artifacts_upload.go167
-rw-r--r--workhorse/internal/artifacts/artifacts_upload_test.go322
-rw-r--r--workhorse/internal/filestore/file_handler.go259
-rw-r--r--workhorse/internal/filestore/file_handler_test.go538
-rw-r--r--workhorse/internal/filestore/multi_hash.go48
-rw-r--r--workhorse/internal/filestore/reader.go17
-rw-r--r--workhorse/internal/filestore/reader_test.go46
-rw-r--r--workhorse/internal/filestore/save_file_opts.go171
-rw-r--r--workhorse/internal/filestore/save_file_opts_test.go342
-rw-r--r--workhorse/internal/lfs/lfs.go50
-rw-r--r--workhorse/internal/lfs/lfs_test.go61
-rw-r--r--workhorse/internal/objectstore/gocloud_object_test.go56
-rw-r--r--workhorse/internal/objectstore/multipart_test.go64
-rw-r--r--workhorse/internal/objectstore/object_test.go149
-rw-r--r--workhorse/internal/objectstore/s3_object_test.go174
-rw-r--r--workhorse/internal/objectstore/test/objectstore_stub.go278
-rw-r--r--workhorse/internal/staticpages/servefile.go3
-rw-r--r--workhorse/internal/staticpages/servefile_test.go3
-rw-r--r--workhorse/internal/testhelper/testhelper.go13
-rw-r--r--workhorse/internal/upload/accelerate.go37
-rw-r--r--workhorse/internal/upload/artifacts_store_test.go335
-rw-r--r--workhorse/internal/upload/artifacts_upload_test.go331
-rw-r--r--workhorse/internal/upload/artifacts_uploader.go167
-rw-r--r--workhorse/internal/upload/body_uploader.go35
-rw-r--r--workhorse/internal/upload/body_uploader_test.go10
-rw-r--r--workhorse/internal/upload/destination/destination.go236
-rw-r--r--workhorse/internal/upload/destination/destination_test.go504
-rw-r--r--workhorse/internal/upload/destination/filestore/filestore.go21
-rw-r--r--workhorse/internal/upload/destination/filestore/filestore_test.go38
-rw-r--r--workhorse/internal/upload/destination/multi_hash.go48
-rw-r--r--workhorse/internal/upload/destination/objectstore/doc.go3
-rw-r--r--workhorse/internal/upload/destination/objectstore/gocloud_object.go (renamed from workhorse/internal/objectstore/gocloud_object.go)0
-rw-r--r--workhorse/internal/upload/destination/objectstore/gocloud_object_test.go56
-rw-r--r--workhorse/internal/upload/destination/objectstore/multipart.go (renamed from workhorse/internal/objectstore/multipart.go)0
-rw-r--r--workhorse/internal/upload/destination/objectstore/multipart_test.go64
-rw-r--r--workhorse/internal/upload/destination/objectstore/object.go (renamed from workhorse/internal/objectstore/object.go)0
-rw-r--r--workhorse/internal/upload/destination/objectstore/object_test.go149
-rw-r--r--workhorse/internal/upload/destination/objectstore/prometheus.go (renamed from workhorse/internal/objectstore/prometheus.go)0
-rw-r--r--workhorse/internal/upload/destination/objectstore/s3_complete_multipart_api.go (renamed from workhorse/internal/objectstore/s3_complete_multipart_api.go)0
-rw-r--r--workhorse/internal/upload/destination/objectstore/s3_object.go (renamed from workhorse/internal/objectstore/s3_object.go)0
-rw-r--r--workhorse/internal/upload/destination/objectstore/s3_object_test.go174
-rw-r--r--workhorse/internal/upload/destination/objectstore/s3_session.go (renamed from workhorse/internal/objectstore/s3_session.go)0
-rw-r--r--workhorse/internal/upload/destination/objectstore/s3_session_test.go (renamed from workhorse/internal/objectstore/s3_session_test.go)0
-rw-r--r--workhorse/internal/upload/destination/objectstore/test/consts.go (renamed from workhorse/internal/objectstore/test/consts.go)0
-rw-r--r--workhorse/internal/upload/destination/objectstore/test/gocloud_stub.go (renamed from workhorse/internal/objectstore/test/gocloud_stub.go)0
-rw-r--r--workhorse/internal/upload/destination/objectstore/test/objectstore_stub.go278
-rw-r--r--workhorse/internal/upload/destination/objectstore/test/objectstore_stub_test.go (renamed from workhorse/internal/objectstore/test/objectstore_stub_test.go)0
-rw-r--r--workhorse/internal/upload/destination/objectstore/test/s3_stub.go (renamed from workhorse/internal/objectstore/test/s3_stub.go)0
-rw-r--r--workhorse/internal/upload/destination/objectstore/upload_strategy.go (renamed from workhorse/internal/objectstore/upload_strategy.go)0
-rw-r--r--workhorse/internal/upload/destination/objectstore/uploader.go (renamed from workhorse/internal/objectstore/uploader.go)0
-rw-r--r--workhorse/internal/upload/destination/reader.go17
-rw-r--r--workhorse/internal/upload/destination/reader_test.go46
-rw-r--r--workhorse/internal/upload/destination/upload_opts.go171
-rw-r--r--workhorse/internal/upload/destination/upload_opts_test.go342
-rw-r--r--workhorse/internal/upload/lfs_preparer.go47
-rw-r--r--workhorse/internal/upload/lfs_preparer_test.go59
-rw-r--r--workhorse/internal/upload/multipart_uploader.go28
-rw-r--r--workhorse/internal/upload/object_storage_preparer.go9
-rw-r--r--workhorse/internal/upload/preparer.go33
-rw-r--r--workhorse/internal/upload/rewrite.go10
-rw-r--r--workhorse/internal/upload/saved_file_tracker.go4
-rw-r--r--workhorse/internal/upload/saved_file_tracker_test.go6
-rw-r--r--workhorse/internal/upload/uploads.go26
-rw-r--r--workhorse/internal/upload/uploads_test.go20
-rw-r--r--workhorse/internal/upstream/.gitignore1
-rw-r--r--workhorse/internal/upstream/metrics.go103
-rw-r--r--workhorse/internal/upstream/routes.go27
-rw-r--r--workhorse/internal/upstream/routes_test.go30
-rw-r--r--workhorse/main_test.go41
-rw-r--r--workhorse/upload_test.go1
-rw-r--r--yarn.lock235
4442 files changed, 178336 insertions, 68552 deletions
diff --git a/.eslintignore b/.eslintignore
index 1d069e19385..b7769ef8970 100644
--- a/.eslintignore
+++ b/.eslintignore
@@ -9,3 +9,4 @@
/sitespeed-result/
/fixtures/**/*.graphql
spec/fixtures/**/*.graphql
+**/contracts/consumer/
diff --git a/.eslintrc.yml b/.eslintrc.yml
index 549f1771593..f5814639b36 100644
--- a/.eslintrc.yml
+++ b/.eslintrc.yml
@@ -105,6 +105,8 @@ overrides:
message: 'Avoid using "setData" on VTU wrapper'
- selector: MemberExpression[object.type!='ThisExpression'][property.type='Identifier'][property.name='$nextTick']
message: 'Using $nextTick from a component instance is discouraged. Import nextTick directly from the Vue package.'
+ - selector: Identifier[name='setImmediate']
+ message: 'Prefer explicit waitForPromises (or equivalent), or jest.runAllTimers (or equivalent) to vague setImmediate calls.'
- files:
- 'config/**/*'
- 'scripts/**/*'
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 1b551967cb3..05d4c2bb6d4 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -16,7 +16,7 @@ stages:
# in cases where jobs require Docker-in-Docker, the job
# definition must be extended with `.use-docker-in-docker`
default:
- image: ${REGISTRY_HOST}/${REGISTRY_GROUP}/gitlab-build-images:debian-${DEBIAN_VERSION}-ruby-2.7.patched-golang-1.16-git-2.33-lfs-2.9-chrome-97-node-14.15-yarn-1.22-postgresql-11-graphicsmagick-1.3.36
+ image: ${REGISTRY_HOST}/${REGISTRY_GROUP}/gitlab-build-images:debian-${DEBIAN_VERSION}-ruby-2.7.patched-golang-1.16-git-2.33-lfs-2.9-chrome-97-node-16.14-yarn-1.22-postgresql-11-graphicsmagick-1.3.36
tags:
- gitlab-org
# All jobs are interruptible by default
@@ -65,10 +65,15 @@ variables:
# we override the max_old_space_size to prevent OOM errors
NODE_OPTIONS: --max_old_space_size=3584
GIT_DEPTH: "20"
+ # 'GIT_STRATEGY: clone' optimizes the pack-objects cache hit ratio
+ GIT_STRATEGY: "clone"
GIT_SUBMODULE_STRATEGY: "none"
GET_SOURCES_ATTEMPTS: "3"
DEBIAN_VERSION: "bullseye"
+ TMP_TEST_FOLDER: "${CI_PROJECT_DIR}/tmp/tests"
+ GITLAB_WORKHORSE_FOLDER: "gitlab-workhorse"
+ TMP_TEST_GITLAB_WORKHORSE_PATH: "${TMP_TEST_FOLDER}/${GITLAB_WORKHORSE_FOLDER}"
KNAPSACK_RSPEC_SUITE_REPORT_PATH: knapsack/report-master.json
FLAKY_RSPEC_SUITE_REPORT_PATH: rspec/flaky/report-suite.json
RSPEC_TESTS_MAPPING_PATH: crystalball/mapping.json
@@ -86,6 +91,8 @@ variables:
CHECK_PRECOMPILED_ASSETS: "true"
FF_USE_FASTZIP: "true"
SKIP_FLAKY_TESTS_AUTOMATICALLY: "true"
+ # Run with decomposed databases by default
+ DECOMPOSED_DB: "true"
DOCS_REVIEW_APPS_DOMAIN: "178.62.207.141.nip.io"
DOCS_GITLAB_REPO_SUFFIX: "ee"
diff --git a/.gitlab/CODEOWNERS b/.gitlab/CODEOWNERS
index ab9805bda7d..26ce20e976d 100644
--- a/.gitlab/CODEOWNERS
+++ b/.gitlab/CODEOWNERS
@@ -208,7 +208,9 @@ lib/gitlab/checks/** @proglottis @toon @zj-gitlab
/doc/.markdownlint @marcel.amirault @eread @aqualls @cnorris
/doc/ @gl-docsteam
/doc/.vale/ @marcel.amirault @eread @aqualls @cnorris
-/doc/administration/application_settings_cache.md @marcia
+
+[Documentation Pages]
+/doc/administration/application_settings_cache.md @marcel.amirault
/doc/administration/audit_event_streaming.md @eread
/doc/administration/audit_events.md @eread
/doc/administration/audit_reports.md @eread
@@ -226,7 +228,7 @@ lib/gitlab/checks/** @proglottis @toon @zj-gitlab
/doc/administration/auth/oidc.md @eread
/doc/administration/auth/smartcard.md @eread
/doc/administration/cicd.md @marcel.amirault
-/doc/administration/clusters/kas.md @marcia
+/doc/administration/clusters/kas.md @sselhorn
/doc/administration/compliance.md @eread
/doc/administration/configure.md @axil
/doc/administration/consul.md @axil
@@ -259,17 +261,21 @@ lib/gitlab/checks/** @proglottis @toon @zj-gitlab
/doc/administration/maintenance_mode/index.md @axil
/doc/administration/merge_request_diffs.md @aqualls
/doc/administration/monitoring/ @ngaskill
+/doc/administration/monitoring/prometheus/index.md @axil
/doc/administration/nfs.md @axil
/doc/administration/object_storage.md @axil
/doc/administration/operations/ @axil
-/doc/administration/operations/sidekiq_memory_killer.md @marcia
+/doc/administration/operations/moving_repositories.md @eread
+/doc/administration/operations/sidekiq_memory_killer.md @marcel.amirault
/doc/administration/package_information/ @axil
/doc/administration/packages/ @ngaskill
-/doc/administration/pages/ @rdickenson
+/doc/administration/pages/index.md @rdickenson
+/doc/administration/pages/source.md @rdickenson
/doc/administration/polling.md @axil
-/doc/administration/postgresql/ @marcia
+/doc/administration/postgresql/ @aqualls
/doc/administration/pseudonymizer.md @axil
/doc/administration/raketasks/ @axil
+/doc/administration/raketasks/praefect.md @eread
/doc/administration/read_only_gitlab.md @axil
/doc/administration/redis/ @axil
/doc/administration/reference_architectures/ @axil
@@ -280,15 +286,16 @@ lib/gitlab/checks/** @proglottis @toon @zj-gitlab
/doc/administration/repository_storage_types.md @eread
/doc/administration/restart_gitlab.md @axil
/doc/administration/server_hooks.md @eread
+/doc/administration/sidekiq_health_check.md @axil
/doc/administration/sidekiq.md @axil
/doc/administration/smime_signing_email.md @axil
/doc/administration/snippets/index.md @aqualls
/doc/administration/static_objects_external_storage.md @aqualls
-/doc/administration/terraform_state.md @marcia
+/doc/administration/terraform_state.md @sselhorn
/doc/administration/timezone.md @axil
/doc/administration/troubleshooting/ @axil
-/doc/administration/troubleshooting/group_saml_scim.md @eread
-/doc/administration/troubleshooting/postgresql.md @marcia
+/doc/administration/troubleshooting/elasticsearch.md @rdickenson
+/doc/administration/troubleshooting/postgresql.md @aqualls
/doc/administration/uploads.md @axil
/doc/administration/user_settings.md @eread
/doc/administration/whats-new.md @kpaizee
@@ -336,7 +343,7 @@ lib/gitlab/checks/** @proglottis @toon @zj-gitlab
/doc/api/group_activity_analytics.md @fneill
/doc/api/group_badges.md @eread
/doc/api/group_boards.md @msedlakjakubowski
-/doc/api/group_clusters.md @marcia
+/doc/api/group_clusters.md @sselhorn
/doc/api/group_import_export.md @ngaskill
/doc/api/group_iterations.md @msedlakjakubowski
/doc/api/group_labels.md @msedlakjakubowski
@@ -349,7 +356,7 @@ lib/gitlab/checks/** @proglottis @toon @zj-gitlab
/doc/api/groups.md @eread
/doc/api/import.md @ngaskill
/doc/api/index.md @kpaizee
-/doc/api/instance_clusters.md @marcia
+/doc/api/instance_clusters.md @sselhorn
/doc/api/instance_level_ci_variables.md @marcel.amirault
/doc/api/integrations.md @kpaizee
/doc/api/invitations.md @kpaizee
@@ -389,7 +396,7 @@ lib/gitlab/checks/** @proglottis @toon @zj-gitlab
/doc/api/plan_limits.md @eread
/doc/api/project_aliases.md @aqualls
/doc/api/project_badges.md @aqualls
-/doc/api/project_clusters.md @marcia
+/doc/api/project_clusters.md @sselhorn
/doc/api/project_import_export.md @aqualls
/doc/api/project_level_variables.md @marcel.amirault
/doc/api/project_relations_export.md @ngaskill
@@ -408,7 +415,6 @@ lib/gitlab/checks/** @proglottis @toon @zj-gitlab
/doc/api/repositories.md @aqualls
/doc/api/repository_files.md @aqualls
/doc/api/repository_submodules.md @aqualls
-/doc/api/resource_access_tokens.md @eread
/doc/api/resource_groups.md @rdickenson
/doc/api/resource_iteration_events.md @msedlakjakubowski
/doc/api/resource_label_events.md @eread
@@ -418,6 +424,7 @@ lib/gitlab/checks/** @proglottis @toon @zj-gitlab
/doc/api/runners.md @sselhorn
/doc/api/scim.md @eread
/doc/api/search.md @aqualls
+/doc/api/secure_files.md @marcel.amirault
/doc/api/settings.md @eread
/doc/api/sidekiq_metrics.md @axil
/doc/api/snippet_repository_storage_moves.md @aqualls
@@ -435,7 +442,6 @@ lib/gitlab/checks/** @proglottis @toon @zj-gitlab
/doc/api/topics.md @fneill
/doc/api/usage_data.md @fneill
/doc/api/users.md @eread
-/doc/api/v3_to_v4.md @kpaizee
/doc/api/version.md @kpaizee
/doc/api/visual_review_discussions.md @eread
/doc/api/vulnerabilities.md @fneill
@@ -443,13 +449,14 @@ lib/gitlab/checks/** @proglottis @toon @zj-gitlab
/doc/api/vulnerability_findings.md @fneill
/doc/api/wikis.md @aqualls
/doc/architecture/blueprints/container_registry_metadata_database/index.md @ngaskill
-/doc/architecture/blueprints/database/scalability/patterns/ @marcia
-/doc/architecture/blueprints/gitlab_to_kubernetes_communication/index.md @marcia
+/doc/architecture/blueprints/database/scalability/patterns/ @aqualls
+/doc/architecture/blueprints/gitlab_to_kubernetes_communication/index.md @sselhorn
/doc/ci/caching/index.md @marcel.amirault
-/doc/ci/chatops/index.md @marcia
+/doc/ci/chatops/index.md @sselhorn
/doc/ci/ci_cd_for_external_repos/ @marcel.amirault
/doc/ci/cloud_deployment/ecs/quick_start_guide.md @rdickenson
/doc/ci/cloud_deployment/index.md @rdickenson
+/doc/ci/cloud_services/ @marcel.amirault
/doc/ci/directed_acyclic_graph/index.md @marcel.amirault
/doc/ci/docker/index.md @marcel.amirault
/doc/ci/docker/using_docker_build.md @marcel.amirault
@@ -457,7 +464,7 @@ lib/gitlab/checks/** @proglottis @toon @zj-gitlab
/doc/ci/docker/using_kaniko.md @marcel.amirault
/doc/ci/enable_or_disable_ci.md @marcel.amirault
/doc/ci/environments/ @rdickenson
-/doc/ci/examples/authenticating-with-hashicorp-vault/index.md @rdickenson
+/doc/ci/examples/authenticating-with-hashicorp-vault/index.md @marcel.amirault
/doc/ci/examples/deployment/composer-npm-deploy.md @rdickenson
/doc/ci/examples/deployment/index.md @rdickenson
/doc/ci/examples/end_to_end_testing_webdriverio/index.md @eread
@@ -485,7 +492,7 @@ lib/gitlab/checks/** @proglottis @toon @zj-gitlab
/doc/ci/resource_groups/index.md @rdickenson
/doc/ci/review_apps/index.md @eread
/doc/ci/runners/ @sselhorn
-/doc/ci/secrets/index.md @marcia
+/doc/ci/secrets/index.md @marcel.amirault
/doc/ci/services/ @sselhorn
/doc/ci/ssh_keys/index.md @marcel.amirault
/doc/ci/test_cases/index.md @msedlakjakubowski
@@ -495,104 +502,84 @@ lib/gitlab/checks/** @proglottis @toon @zj-gitlab
/doc/ci/variables/ @marcel.amirault
/doc/ci/yaml/ @marcel.amirault
/doc/ci/yaml/artifacts_reports.md @eread
-/doc/development/adding_database_indexes.md @marcia
+/doc/development/adding_database_indexes.md @aqualls
/doc/development/application_limits.md @axil
/doc/development/approval_rules.md @aqualls
/doc/development/audit_event_guide/index.md @eread
-/doc/development/auto_devops.md @marcia
-/doc/development/avoiding_downtime_in_migrations.md @marcia
-/doc/development/backend/ruby_style_guide.md @marcia
-/doc/development/background_migrations.md @marcia
+/doc/development/auto_devops.md @sselhorn
+/doc/development/avoiding_downtime_in_migrations.md @aqualls
+/doc/development/backend/create_source_code_be/index.md @aqualls
/doc/development/build_test_package.md @axil
/doc/development/bulk_import.md @ngaskill
/doc/development/cascading_settings.md @eread
-/doc/development/chatops_on_gitlabcom.md @marcia
+/doc/development/chatops_on_gitlabcom.md @sselhorn
/doc/development/cicd/cicd_reference_documentation_guide.md @marcel.amirault
/doc/development/cicd/index.md @marcel.amirault
+/doc/development/cicd/schema.md @marcel.amirault
/doc/development/cicd/templates.md @marcel.amirault
/doc/development/code_intelligence/index.md @aqualls
-/doc/development/contributing/ @marcia
-/doc/development/creating_enums.md @marcia
-/doc/development/database_debugging.md @marcia
-/doc/development/database_query_comments.md @marcia
-/doc/development/database_review.md @marcia
-/doc/development/database/ @marcia
-/doc/development/db_dump.md @marcia
+/doc/development/creating_enums.md @aqualls
+/doc/development/database_debugging.md @aqualls
+/doc/development/database_query_comments.md @aqualls
+/doc/development/database_review.md @aqualls
+/doc/development/database/ @aqualls
+/doc/development/db_dump.md @aqualls
/doc/development/developing_with_solargraph.md @aqualls
/doc/development/distributed_tracing.md @ngaskill
-/doc/development/documentation/feature_flags.md @marcia
-/doc/development/documentation/graphql_styleguide.md @marcia
+/doc/development/documentation/feature_flags.md @sselhorn
+/doc/development/documentation/graphql_styleguide.md @sselhorn
/doc/development/documentation/index.md @cnorris
/doc/development/documentation/redirects.md @cnorris
-/doc/development/documentation/restful_api_styleguide.md @marcia
/doc/development/documentation/review_apps.md @cnorris
/doc/development/documentation/structure.md @sselhorn
-/doc/development/documentation/styleguide/index.md @sselhorn
-/doc/development/documentation/styleguide/word_list.md @sselhorn
+/doc/development/documentation/styleguide/ @sselhorn
/doc/development/documentation/testing.md @cnorris
-/doc/development/elasticsearch.md @marcia
+/doc/development/elasticsearch.md @rdickenson
/doc/development/experiment_guide/ @kpaizee
/doc/development/export_csv.md @ngaskill
/doc/development/fe_guide/content_editor.md @aqualls
-/doc/development/fe_guide/dark_mode.md @marcia
-/doc/development/fe_guide/graphql.md @marcia
/doc/development/fe_guide/source_editor.md @aqualls
-/doc/development/feature_categorization/index.md @marcia
-/doc/development/feature_flags/controls.md @marcia
-/doc/development/feature_flags/index.md @marcia
/doc/development/filtering_by_label.md @msedlakjakubowski
-/doc/development/foreign_keys.md @marcia
+/doc/development/foreign_keys.md @aqualls
/doc/development/geo.md @axil
/doc/development/geo/framework.md @axil
/doc/development/git_object_deduplication.md @eread
/doc/development/gitaly.md @eread
-/doc/development/graphql_guide/batchloader.md @marcia
-/doc/development/graphql_guide/graphql_pro.md @kpaizee
-/doc/development/graphql_guide/index.md @kpaizee
-/doc/development/graphql_guide/pagination.md @kpaizee
-/doc/development/hash_indexes.md @marcia
+/doc/development/graphql_guide/ @kpaizee
+/doc/development/graphql_guide/batchloader.md @aqualls
+/doc/development/hash_indexes.md @aqualls
/doc/development/i18n/ @ngaskill
-/doc/development/image_scaling.md @marcia
+/doc/development/image_scaling.md @marcel.amirault
/doc/development/import_export.md @ngaskill
-/doc/development/index.md @marcia
-/doc/development/insert_into_tables_in_batches.md @marcia
-/doc/development/integrations/codesandbox.md @marcia
+/doc/development/insert_into_tables_in_batches.md @aqualls
/doc/development/integrations/jenkins.md @kpaizee
/doc/development/integrations/jira_connect.md @kpaizee
/doc/development/integrations/secure_partner_integration.md @rdickenson
/doc/development/integrations/secure.md @ngaskill
/doc/development/internal_api/ @aqualls
-/doc/development/internal_users.md @marcia
/doc/development/issuable-like-models.md @msedlakjakubowski
/doc/development/issue_types.md @msedlakjakubowski
-/doc/development/iterating_tables_in_batches.md @marcia
-/doc/development/kubernetes.md @marcia
+/doc/development/iterating_tables_in_batches.md @aqualls
+/doc/development/kubernetes.md @sselhorn
/doc/development/lfs.md @aqualls
/doc/development/licensed_feature_availability.md @sselhorn
-/doc/development/logging.md @ngaskill
/doc/development/maintenance_mode.md @axil
/doc/development/new_fe_guide/modules/widget_extensions.md @aqualls
-/doc/development/new_fe_guide/tips.md @marcia
/doc/development/omnibus.md @axil
-/doc/development/ordering_table_columns.md @marcia
+/doc/development/ordering_table_columns.md @aqualls
/doc/development/packages.md @ngaskill
-/doc/development/permissions.md @eread
-/doc/development/policies.md @eread
-/doc/development/prometheus_metrics.md @ngaskill
-/doc/development/query_performance.md @marcia
+/doc/development/product_qualified_lead_guide/index.md @kpaizee
+/doc/development/query_performance.md @aqualls
/doc/development/real_time.md @msedlakjakubowski
-/doc/development/secure_coding_guidelines.md @marcia
-/doc/development/serializing_data.md @marcia
+/doc/development/serializing_data.md @aqualls
/doc/development/service_ping/ @fneill
/doc/development/snowplow/ @fneill
-/doc/development/sql.md @marcia
-/doc/development/stage_group_dashboards.md @marcia
-/doc/development/swapping_tables.md @marcia
-/doc/development/testing_guide/best_practices.md @marcia
-/doc/development/testing_guide/end_to_end/best_practices.md @marcia
-/doc/development/understanding_explain_plans.md @marcia
+/doc/development/sql.md @aqualls
+/doc/development/swapping_tables.md @aqualls
+/doc/development/understanding_explain_plans.md @aqualls
/doc/development/value_stream_analytics.md @fneill
-/doc/development/verifying_database_capabilities.md @marcia
+/doc/development/value_stream_analytics/value_stream_analytics_aggregated_backend.md @fneill
+/doc/development/verifying_database_capabilities.md @aqualls
/doc/development/wikis.md @aqualls
/doc/development/work_items.md @msedlakjakubowski
/doc/development/work_items_widgets.md @msedlakjakubowski
@@ -605,7 +592,7 @@ lib/gitlab/checks/** @proglottis @toon @zj-gitlab
/doc/gitlab-basics/start-using-git.md @aqualls
/doc/install/ @axil
/doc/integration/ @kpaizee
-/doc/integration/elasticsearch.md @marcia
+/doc/integration/elasticsearch.md @rdickenson
/doc/integration/gitpod.md @aqualls
/doc/integration/kerberos.md @eread
/doc/integration/mattermost/index.md @axil
@@ -613,7 +600,7 @@ lib/gitlab/checks/** @proglottis @toon @zj-gitlab
/doc/integration/saml.md @eread
/doc/integration/security_partners/index.md @rdickenson
/doc/integration/sourcegraph.md @aqualls
-/doc/integration/vault.md @rdickenson
+/doc/integration/vault.md @sselhorn
/doc/operations/ @ngaskill
/doc/operations/feature_flags.md @rdickenson
/doc/operations/product_analytics.md @fneill
@@ -626,18 +613,17 @@ lib/gitlab/checks/** @proglottis @toon @zj-gitlab
/doc/raketasks/x509_signatures.md @aqualls
/doc/security/ @eread
/doc/ssh/index.md @eread
-/doc/subscriptions/ @sselhorn
+/doc/subscriptions/ @fneill
/doc/system_hooks/system_hooks.md @kpaizee
/doc/topics/authentication/index.md @eread
-/doc/topics/autodevops/customize.md @marcia
-/doc/topics/autodevops/ @marcia
+/doc/topics/autodevops/ @sselhorn
/doc/topics/git/ @aqualls
/doc/topics/gitlab_flow.md @aqualls
/doc/topics/offline/ @axil
/doc/topics/plan_and_track.md @msedlakjakubowski
/doc/update/ @axil
-/doc/update/mysql_to_postgresql.md @marcia
-/doc/update/upgrading_postgresql_using_slony.md @marcia
+/doc/update/mysql_to_postgresql.md @aqualls
+/doc/update/upgrading_postgresql_using_slony.md @aqualls
/doc/user/admin_area/analytics/ @fneill
/doc/user/admin_area/broadcast_messages.md @kpaizee
/doc/user/admin_area/credentials_inventory.md @eread
@@ -648,8 +634,9 @@ lib/gitlab/checks/** @proglottis @toon @zj-gitlab
/doc/user/admin_area/license.md @kpaizee
/doc/user/admin_area/merge_requests_approvals.md @aqualls
/doc/user/admin_area/moderate_users.md @eread
-/doc/user/admin_area/monitoring/background_migrations.md @marcia
+/doc/user/admin_area/monitoring/background_migrations.md @aqualls
/doc/user/admin_area/monitoring/health_check.md @ngaskill
+/doc/user/admin_area/reporting/spamcheck.md @axil
/doc/user/admin_area/review_abuse_reports.md @eread
/doc/user/admin_area/settings/account_and_limit_settings.md @aqualls
/doc/user/admin_area/settings/continuous_integration.md @marcel.amirault
@@ -667,6 +654,8 @@ lib/gitlab/checks/** @proglottis @toon @zj-gitlab
/doc/user/admin_area/settings/push_event_activities_limit.md @aqualls
/doc/user/admin_area/settings/rate_limit_on_issues_creation.md @msedlakjakubowski
/doc/user/admin_area/settings/rate_limit_on_notes_creation.md @msedlakjakubowski
+/doc/user/admin_area/settings/rate_limit_on_users_api.md @eread
+/doc/user/admin_area/settings/third_party_offers.md @fneill
/doc/user/admin_area/settings/visibility_and_access_controls.md @aqualls
/doc/user/analytics/ci_cd_analytics.md @rdickenson
/doc/user/analytics/ @fneill
@@ -674,20 +663,20 @@ lib/gitlab/checks/** @proglottis @toon @zj-gitlab
/doc/user/application_security/cluster_image_scanning/index.md @ngaskill
/doc/user/application_security/container_scanning/index.md @ngaskill
/doc/user/application_security/cve_id_request.md @fneill
-/doc/user/application_security/policies/index.md @ngaskill
+/doc/user/application_security/policies/ @ngaskill
/doc/user/application_security/security_dashboard/index.md @fneill
/doc/user/application_security/threat_monitoring/index.md @ngaskill
/doc/user/application_security/vulnerabilities/ @fneill
/doc/user/application_security/vulnerability_report/index.md @fneill
/doc/user/asciidoc.md @aqualls
/doc/user/award_emojis.md @msedlakjakubowski
-/doc/user/clusters/ @marcia
+/doc/user/clusters/ @sselhorn
/doc/user/compliance/compliance_report/index.md @eread
/doc/user/compliance/index.md @eread
/doc/user/compliance/license_compliance/index.md @rdickenson
+/doc/user/crm/index.md @msedlakjakubowski
/doc/user/discussions/index.md @aqualls
-/doc/user/feature_flags.md @marcia
-/doc/user/group/clusters/index.md @marcia
+/doc/user/group/clusters/index.md @sselhorn
/doc/user/group/contribution_analytics/index.md @fneill
/doc/user/group/custom_project_templates.md @ngaskill
/doc/user/group/devops_adoption/index.md @fneill
@@ -699,6 +688,7 @@ lib/gitlab/checks/** @proglottis @toon @zj-gitlab
/doc/user/group/insights/index.md @fneill
/doc/user/group/issues_analytics/index.md @msedlakjakubowski
/doc/user/group/iterations/index.md @msedlakjakubowski
+/doc/user/group/planning_hierarchy/index.md @msedlakjakubowski
/doc/user/group/repositories_analytics/index.md @eread
/doc/user/group/roadmap/index.md @msedlakjakubowski
/doc/user/group/saml_sso/group_managed_accounts.md @eread
@@ -707,31 +697,24 @@ lib/gitlab/checks/** @proglottis @toon @zj-gitlab
/doc/user/group/settings/import_export.md @ngaskill
/doc/user/group/subgroups/index.md @eread
/doc/user/group/value_stream_analytics/index.md @fneill
-/doc/user/infrastructure/clusters/ @marcia
-/doc/user/infrastructure/clusters/manage/clusters_health.md @marcia
+/doc/user/infrastructure/clusters/ @sselhorn
/doc/user/infrastructure/clusters/manage/management_project_applications/apparmor.md @ngaskill
-/doc/user/infrastructure/clusters/manage/management_project_applications/certmanager.md @marcia
/doc/user/infrastructure/clusters/manage/management_project_applications/cilium.md @ngaskill
/doc/user/infrastructure/clusters/manage/management_project_applications/elasticstack.md @ngaskill
/doc/user/infrastructure/clusters/manage/management_project_applications/falco.md @ngaskill
/doc/user/infrastructure/clusters/manage/management_project_applications/fluentd.md @ngaskill
-/doc/user/infrastructure/clusters/manage/management_project_applications/ingress.md @marcia
-/doc/user/infrastructure/clusters/manage/management_project_applications/prometheus.md @ngaskill
-/doc/user/infrastructure/clusters/manage/management_project_applications/runner.md @sselhorn
-/doc/user/infrastructure/clusters/manage/management_project_applications/sentry.md @ngaskill
-/doc/user/infrastructure/clusters/manage/management_project_applications/vault.md @marcia
-/doc/user/infrastructure/iac/ @marcia
-/doc/user/infrastructure/index.md @marcia
+/doc/user/infrastructure/iac/ @sselhorn
+/doc/user/infrastructure/index.md @ssehorn
/doc/user/markdown.md @aqualls
/doc/user/packages/ @ngaskill
-/doc/user/packages/infrastructure_registry/index.md @marcia
-/doc/user/packages/terraform_module_registry/index.md @marcia
+/doc/user/packages/infrastructure_registry/index.md @sselhorn
+/doc/user/packages/terraform_module_registry/index.md @sselhorn
/doc/user/permissions.md @eread
/doc/user/profile/ @eread
/doc/user/profile/notifications.md @msedlakjakubowski
/doc/user/project/autocomplete_characters.md @aqualls
/doc/user/project/badges.md @aqualls
-/doc/user/project/clusters/ @marcia
+/doc/user/project/clusters/ @sselhorn
/doc/user/project/clusters/kubernetes_pod_logs.md @ngaskill
/doc/user/project/clusters/protect/ @ngaskill
/doc/user/project/code_intelligence.md @aqualls
@@ -786,10 +769,11 @@ lib/gitlab/checks/** @proglottis @toon @zj-gitlab
/doc/user/project/wiki/index.md @aqualls
/doc/user/project/working_with_projects.md @fneill
/doc/user/reserved_names.md @fneill
-/doc/user/search/advanced_search.md @marcia
+/doc/user/search/advanced_search.md @rdickenson
/doc/user/search/index.md @aqualls
+/doc/user/shortcuts.md @aqualls
/doc/user/snippets.md @aqualls
/doc/user/tasks.md @msedlakjakubowski
/doc/user/todos.md @msedlakjakubowski
-/doc/user/usage_quotas.md @sselhorn
+/doc/user/usage_quotas.md @fneill
/doc/user/workspace/index.md @fneill
diff --git a/.gitlab/ci/ci-templates.gitlab-ci.yml b/.gitlab/ci/ci-templates.gitlab-ci.yml
new file mode 100644
index 00000000000..d6e2fdf2fbe
--- /dev/null
+++ b/.gitlab/ci/ci-templates.gitlab-ci.yml
@@ -0,0 +1,13 @@
+templates-shellcheck:
+ extends:
+ - .ci-templates:rules:shellcheck
+ - .default-before_script
+ - .default-retry
+ - .ruby-cache
+ - .use-pg13
+ stage: test
+ needs:
+ - setup-test-env
+ script:
+ - apt update && apt install -y shellcheck=0.7.1-1+deb11u1
+ - bundle exec scripts/lint_templates_bash.rb
diff --git a/.gitlab/ci/frontend.gitlab-ci.yml b/.gitlab/ci/frontend.gitlab-ci.yml
index ef5af342544..cb07384676d 100644
--- a/.gitlab/ci/frontend.gitlab-ci.yml
+++ b/.gitlab/ci/frontend.gitlab-ci.yml
@@ -11,7 +11,7 @@
- .default-retry
- .default-before_script
- .assets-compile-cache
- image: ${REGISTRY_HOST}/${REGISTRY_GROUP}/gitlab-build-images:debian-${DEBIAN_VERSION}-ruby-2.7-git-2.33-lfs-2.9-node-14.15-yarn-1.22-graphicsmagick-1.3.36
+ image: ${REGISTRY_HOST}/${REGISTRY_GROUP}/gitlab-build-images:debian-${DEBIAN_VERSION}-ruby-2.7-git-2.33-lfs-2.9-node-16.14-yarn-1.22-graphicsmagick-1.3.36
variables:
SETUP_DB: "false"
WEBPACK_VENDOR_DLL: "true"
diff --git a/.gitlab/ci/global.gitlab-ci.yml b/.gitlab/ci/global.gitlab-ci.yml
index 33b04faf731..146a7067acd 100644
--- a/.gitlab/ci/global.gitlab-ci.yml
+++ b/.gitlab/ci/global.gitlab-ci.yml
@@ -213,7 +213,7 @@
- *storybook-node-modules-cache-push
.use-pg11:
- image: ${REGISTRY_HOST}/${REGISTRY_GROUP}/gitlab-build-images:debian-${DEBIAN_VERSION}-ruby-2.7.patched-golang-1.16-git-2.33-lfs-2.9-chrome-97-node-14.15-yarn-1.22-postgresql-11-graphicsmagick-1.3.36
+ image: ${REGISTRY_HOST}/${REGISTRY_GROUP}/gitlab-build-images:debian-${DEBIAN_VERSION}-ruby-2.7.patched-golang-1.16-git-2.33-lfs-2.9-chrome-97-node-16.14-yarn-1.22-postgresql-11-graphicsmagick-1.3.36
services:
- name: postgres:11.6
command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
@@ -222,16 +222,16 @@
POSTGRES_HOST_AUTH_METHOD: trust
.use-pg12:
- image: ${REGISTRY_HOST}/${REGISTRY_GROUP}/gitlab-build-images:debian-${DEBIAN_VERSION}-ruby-2.7.patched-golang-1.16-git-2.33-lfs-2.9-chrome-97-node-14.15-yarn-1.22-postgresql-12-graphicsmagick-1.3.36
+ image: ${REGISTRY_HOST}/${REGISTRY_GROUP}/gitlab-build-images:debian-${DEBIAN_VERSION}-ruby-2.7.patched-golang-1.16-git-2.33-lfs-2.9-chrome-97-node-16.14-yarn-1.22-postgresql-12-graphicsmagick-1.3.36
services:
- name: postgres:12
command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
- - name: redis:5.0-alpine
+ - name: redis:6.0-alpine
variables:
POSTGRES_HOST_AUTH_METHOD: trust
.use-pg13:
- image: ${REGISTRY_HOST}/${REGISTRY_GROUP}/gitlab-build-images:debian-${DEBIAN_VERSION}-ruby-2.7.patched-golang-1.16-git-2.33-lfs-2.9-chrome-97-node-14.15-yarn-1.22-postgresql-13-graphicsmagick-1.3.36
+ image: ${REGISTRY_HOST}/${REGISTRY_GROUP}/gitlab-build-images:debian-${DEBIAN_VERSION}-ruby-2.7.patched-golang-1.16-git-2.33-lfs-2.9-chrome-97-node-16.14-yarn-1.22-postgresql-13-graphicsmagick-1.3.36
services:
- name: postgres:13
command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
@@ -240,34 +240,34 @@
POSTGRES_HOST_AUTH_METHOD: trust
.use-pg11-ee:
- image: ${REGISTRY_HOST}/${REGISTRY_GROUP}/gitlab-build-images:debian-${DEBIAN_VERSION}-ruby-2.7.patched-golang-1.16-git-2.33-lfs-2.9-chrome-97-node-14.15-yarn-1.22-postgresql-11-graphicsmagick-1.3.36
+ image: ${REGISTRY_HOST}/${REGISTRY_GROUP}/gitlab-build-images:debian-${DEBIAN_VERSION}-ruby-2.7.patched-golang-1.16-git-2.33-lfs-2.9-chrome-97-node-16.14-yarn-1.22-postgresql-11-graphicsmagick-1.3.36
services:
- name: postgres:11.6
command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
- name: redis:5.0-alpine
- - name: elasticsearch:7.14.2
+ - name: elasticsearch:7.17.0
command: ["elasticsearch", "-E", "discovery.type=single-node"]
variables:
POSTGRES_HOST_AUTH_METHOD: trust
.use-pg12-ee:
- image: ${REGISTRY_HOST}/${REGISTRY_GROUP}/gitlab-build-images:debian-${DEBIAN_VERSION}-ruby-2.7.patched-golang-1.16-git-2.33-lfs-2.9-chrome-97-node-14.15-yarn-1.22-postgresql-12-graphicsmagick-1.3.36
+ image: ${REGISTRY_HOST}/${REGISTRY_GROUP}/gitlab-build-images:debian-${DEBIAN_VERSION}-ruby-2.7.patched-golang-1.16-git-2.33-lfs-2.9-chrome-97-node-16.14-yarn-1.22-postgresql-12-graphicsmagick-1.3.36
services:
- name: postgres:12
command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
- - name: redis:5.0-alpine
- - name: elasticsearch:7.14.2
+ - name: redis:6.0-alpine
+ - name: elasticsearch:7.17.0
command: ["elasticsearch", "-E", "discovery.type=single-node"]
variables:
POSTGRES_HOST_AUTH_METHOD: trust
.use-pg13-ee:
- image: ${REGISTRY_HOST}/${REGISTRY_GROUP}/gitlab-build-images:debian-${DEBIAN_VERSION}-ruby-2.7.patched-golang-1.16-git-2.33-lfs-2.9-chrome-97-node-14.15-yarn-1.22-postgresql-13-graphicsmagick-1.3.36
+ image: ${REGISTRY_HOST}/${REGISTRY_GROUP}/gitlab-build-images:debian-${DEBIAN_VERSION}-ruby-2.7.patched-golang-1.16-git-2.33-lfs-2.9-chrome-97-node-16.14-yarn-1.22-postgresql-13-graphicsmagick-1.3.36
services:
- name: postgres:13
command: ["postgres", "-c", "fsync=off", "-c", "synchronous_commit=off", "-c", "full_page_writes=off"]
- name: redis:5.0-alpine
- - name: elasticsearch:7.14.2
+ - name: elasticsearch:7.17.0
command: ["elasticsearch", "-E", "discovery.type=single-node"]
variables:
POSTGRES_HOST_AUTH_METHOD: trust
diff --git a/.gitlab/ci/memory.gitlab-ci.yml b/.gitlab/ci/memory.gitlab-ci.yml
index c6572d9709c..efdae0715aa 100644
--- a/.gitlab/ci/memory.gitlab-ci.yml
+++ b/.gitlab/ci/memory.gitlab-ci.yml
@@ -9,7 +9,7 @@
artifacts:
reports:
metrics: "${METRICS_FILE}"
- expire_in: 31d
+ expire_in: 62d
# Show memory usage caused by invoking require per gem.
@@ -26,11 +26,17 @@ memory-on-boot:
NODE_ENV: "production"
RAILS_ENV: "production"
SETUP_DB: "true"
- MEMORY_ON_BOOT_FILE: "tmp/memory_on_boot.txt"
+ MEMORY_ON_BOOT_FILE_PREFIX: "tmp/memory_on_boot_"
+ TEST_COUNT: 5
script:
- - PATH_TO_HIT="/users/sign_in" CUT_OFF=0.3 bundle exec derailed exec perf:mem >> "${MEMORY_ON_BOOT_FILE}"
- - scripts/generate-memory-metrics-on-boot "${MEMORY_ON_BOOT_FILE}" >> "${METRICS_FILE}"
+ - |
+ for i in $(seq 1 $TEST_COUNT)
+ do
+ echo "Starting run $i out of $TEST_COUNT"
+ PATH_TO_HIT="/users/sign_in" CUT_OFF=0.3 bundle exec derailed exec perf:mem >> "${MEMORY_ON_BOOT_FILE_PREFIX}$i.txt"
+ done
+ - scripts/generate-memory-metrics-on-boot "${MEMORY_ON_BOOT_FILE_PREFIX}" "$TEST_COUNT" >> "${METRICS_FILE}"
artifacts:
paths:
- "${METRICS_FILE}"
- - "${MEMORY_ON_BOOT_FILE}"
+ - "${MEMORY_ON_BOOT_FILE_PREFIX}*.txt"
diff --git a/.gitlab/ci/rails.gitlab-ci.yml b/.gitlab/ci/rails.gitlab-ci.yml
index 8a4ea690c60..1c745e6d986 100644
--- a/.gitlab/ci/rails.gitlab-ci.yml
+++ b/.gitlab/ci/rails.gitlab-ci.yml
@@ -18,15 +18,14 @@
variables:
RSPEC_TESTS_MAPPING_ENABLED: "true"
-.decomposed-database:
+.single-db:
variables:
- DECOMPOSED_DB: "true"
+ DECOMPOSED_DB: "false"
-.decomposed-database-rspec:
- extends: .decomposed-database
+.single-db-rspec:
+ extends: .single-db
variables:
- GITLAB_LOAD_BALANCING_REUSE_PRIMARY_ci: "main"
- GITLAB_USE_MODEL_LOAD_BALANCING: "true"
+ GITLAB_USE_MODEL_LOAD_BALANCING: "false"
.rspec-base:
extends:
@@ -182,7 +181,7 @@
# rspec job parallel configs
############################
-#######################################################
+###############################################################
# EE/FOSS: default refs (MRs, default branch, schedules) jobs #
setup-test-env:
extends:
@@ -193,40 +192,53 @@ setup-test-env:
variables:
SETUP_DB: "false"
script:
+ - source scripts/gitlab_workhorse_component_helpers.sh
+ - run_timed_command "download_and_extract_gitlab_workhorse_package" || true
- run_timed_command "scripts/setup-test-env"
+ - run_timed_command "select_gitlab_workhorse_essentials"
- echo -e "\e[0Ksection_start:`date +%s`:gitaly-test-build[collapsed=true]\r\e[0KCompiling Gitaly binaries"
- run_timed_command "scripts/gitaly-test-build" # Do not use 'bundle exec' here
- echo -e "\e[0Ksection_end:`date +%s`:gitaly-test-build\r\e[0K"
-
artifacts:
expire_in: 7d
paths:
- config/secrets.yml
- - tmp/tests/gitaly/_build/bin/
- - tmp/tests/gitaly/_build/deps/git/install
- - tmp/tests/gitaly/config.toml
- - tmp/tests/gitaly/gitaly2.config.toml
- - tmp/tests/gitaly/internal/
- - tmp/tests/gitaly/internal_gitaly2/
- - tmp/tests/gitaly/internal_sockets/
- - tmp/tests/gitaly/Makefile
- - tmp/tests/gitaly/praefect.config.toml
- - tmp/tests/gitaly/ruby/
- - tmp/tests/gitlab-elasticsearch-indexer/bin/gitlab-elasticsearch-indexer
- - tmp/tests/gitlab-shell/
- - tmp/tests/gitlab-test-fork/
- - tmp/tests/gitlab-test-fork_bare/
- - tmp/tests/gitlab-test/
- - tmp/tests/gitlab-workhorse/gitlab-zip-metadata
- - tmp/tests/gitlab-workhorse/gitlab-zip-cat
- - tmp/tests/gitlab-workhorse/gitlab-workhorse
- - tmp/tests/gitlab-workhorse/gitlab-resize-image
- - tmp/tests/gitlab-workhorse/config.toml
- - tmp/tests/gitlab-workhorse/WORKHORSE_TREE
- - tmp/tests/repositories/
- - tmp/tests/second_storage/
+ - ${TMP_TEST_FOLDER}/gitaly/_build/bin/
+ - ${TMP_TEST_FOLDER}/gitaly/_build/deps/git/install
+ - ${TMP_TEST_FOLDER}/gitaly/config.toml
+ - ${TMP_TEST_FOLDER}/gitaly/gitaly2.config.toml
+ - ${TMP_TEST_FOLDER}/gitaly/internal/
+ - ${TMP_TEST_FOLDER}/gitaly/internal_gitaly2/
+ - ${TMP_TEST_FOLDER}/gitaly/internal_sockets/
+ - ${TMP_TEST_FOLDER}/gitaly/Makefile
+ - ${TMP_TEST_FOLDER}/gitaly/praefect.config.toml
+ - ${TMP_TEST_FOLDER}/gitaly/ruby/
+ - ${TMP_TEST_FOLDER}/gitlab-elasticsearch-indexer/bin/gitlab-elasticsearch-indexer
+ - ${TMP_TEST_FOLDER}/gitlab-shell/
+ - ${TMP_TEST_FOLDER}/gitlab-test-fork/
+ - ${TMP_TEST_FOLDER}/gitlab-test-fork_bare/
+ - ${TMP_TEST_FOLDER}/gitlab-test/
+ - ${TMP_TEST_FOLDER}/repositories/
+ - ${TMP_TEST_FOLDER}/second_storage/
+ - ${TMP_TEST_GITLAB_WORKHORSE_PATH}/
when: always
+build-components:
+ extends:
+ - setup-test-env
+ - .rails:rules:build-components
+ script:
+ - source scripts/gitlab_workhorse_component_helpers.sh
+ - 'gitlab_workhorse_archive_doesnt_exist || { echoinfo "INFO: Exiting early as package exists."; exit 0; }'
+ - run_timed_command "scripts/setup-test-env"
+ - run_timed_command "select_gitlab_workhorse_essentials"
+ - run_timed_command "create_gitlab_workhorse_package"
+ - run_timed_command "upload_gitlab_workhorse_package"
+ artifacts:
+ expire_in: 7d
+ paths:
+ - ${TMP_TEST_GITLAB_WORKHORSE_PATH}/
+
update-setup-test-env-cache:
extends:
- setup-test-env
@@ -264,11 +276,11 @@ rspec migration pg12 minimal:
- .minimal-rspec-tests
- .rails:rules:ee-and-foss-migration:minimal
-rspec migration pg12 decomposed:
+rspec migration pg12 single-db:
extends:
- rspec migration pg12
- - .decomposed-database-rspec
- - .rails:rules:decomposed-databases
+ - .single-db-rspec
+ - .rails:rules:single-db
rspec unit pg12:
extends:
@@ -282,11 +294,11 @@ rspec unit pg12 minimal:
- .minimal-rspec-tests
- .rails:rules:ee-and-foss-unit:minimal
-rspec unit pg12 decomposed:
+rspec unit pg12 single-db:
extends:
- rspec unit pg12
- - .decomposed-database-rspec
- - .rails:rules:decomposed-databases
+ - .single-db-rspec
+ - .rails:rules:single-db
rspec integration pg12:
extends:
@@ -300,11 +312,11 @@ rspec integration pg12 minimal:
- .minimal-rspec-tests
- .rails:rules:ee-and-foss-integration:minimal
-rspec integration pg12 decomposed:
+rspec integration pg12 single-db:
extends:
- rspec integration pg12
- - .decomposed-database-rspec
- - .rails:rules:decomposed-databases
+ - .single-db-rspec
+ - .rails:rules:single-db
rspec system pg12:
extends:
@@ -320,11 +332,11 @@ rspec system pg12 minimal:
- .minimal-rspec-tests
- .rails:rules:ee-and-foss-system:minimal
-rspec system pg12 decomposed:
+rspec system pg12 single-db:
extends:
- rspec system pg12
- - .decomposed-database-rspec
- - .rails:rules:decomposed-databases
+ - .single-db-rspec
+ - .rails:rules:single-db
# Dedicated job to test DB library code against PG11.
# Note that these are already tested against PG12 in the `rspec unit pg12` / `rspec-ee unit pg12` jobs.
@@ -351,22 +363,22 @@ db:rollback:
- scripts/db_tasks db:migrate VERSION=20210301200959
- scripts/db_tasks db:migrate SKIP_SCHEMA_VERSION_CHECK=true
-db:rollback decomposed:
+db:rollback single-db:
extends:
- db:rollback
- - .decomposed-database
- - .rails:rules:decomposed-databases
+ - .single-db
+ - .rails:rules:single-db
db:migrate:reset:
extends: .db-job-base
script:
- bundle exec rake db:migrate:reset
-db:migrate:reset decomposed:
+db:migrate:reset single-db:
extends:
- db:migrate:reset
- - .decomposed-database
- - .rails:rules:decomposed-databases
+ - .single-db
+ - .rails:rules:single-db
db:migrate-from-previous-major-version:
extends: .db-job-base
@@ -375,6 +387,8 @@ db:migrate-from-previous-major-version:
SETUP_DB: "false"
PROJECT_TO_CHECKOUT: "gitlab-foss"
TAG_TO_CHECKOUT: "v13.12.9"
+ # FIXME: make this job work with `GITLAB_USE_MODEL_LOAD_BALANCING: true`, see https://gitlab.com/gitlab-org/gitlab/-/issues/355573
+ GITLAB_USE_MODEL_LOAD_BALANCING: "false"
before_script:
- !reference [.default-before_script, before_script]
- '[[ -d "ee/" ]] || export PROJECT_TO_CHECKOUT="gitlab"'
@@ -388,11 +402,11 @@ db:migrate-from-previous-major-version:
script:
- run_timed_command "scripts/db_tasks db:migrate"
-db:migrate-from-previous-major-version-decomposed:
+db:migrate-from-previous-major-version-single-db:
extends:
- db:migrate-from-previous-major-version
- - .decomposed-database
- - .rails:rules:decomposed-databases
+ - .single-db
+ - .rails:rules:single-db
.db:check-schema-base:
extends:
@@ -409,9 +423,9 @@ db:check-schema:
- db:migrate-from-previous-major-version
- .db:check-schema-base
-db:check-schema-decomposed:
+db:check-schema-single-db:
extends:
- - db:migrate-from-previous-major-version-decomposed
+ - db:migrate-from-previous-major-version-single-db
- .db:check-schema-base
db:check-migrations:
@@ -423,11 +437,11 @@ db:check-migrations:
- scripts/validate_migration_schema
allow_failure: true
-db:check-migrations-decomposed:
+db:check-migrations-single-db:
extends:
- db:check-migrations
- - .decomposed-database
- - .rails:rules:decomposed-databases
+ - .single-db
+ - .rails:rules:single-db
db:migrate-non-superuser:
extends:
@@ -534,11 +548,11 @@ rspec:coverage:
- rspec unit pg12 minimal
- rspec integration pg12 minimal
- rspec system pg12 minimal
- # FOSS/EE decomposed jobs
- - rspec migration pg12 decomposed
- - rspec unit pg12 decomposed
- - rspec integration pg12 decomposed
- - rspec system pg12 decomposed
+ # FOSS/EE single-db jobs
+ - rspec migration pg12 single-db
+ - rspec unit pg12 single-db
+ - rspec integration pg12 single-db
+ - rspec system pg12 single-db
# EE jobs
- rspec-ee migration pg12
- rspec-ee unit pg12
@@ -549,11 +563,11 @@ rspec:coverage:
- rspec-ee unit pg12 minimal
- rspec-ee integration pg12 minimal
- rspec-ee system pg12 minimal
- # EE decomposed jobs
- - rspec-ee migration pg12 decomposed
- - rspec-ee unit pg12 decomposed
- - rspec-ee integration pg12 decomposed
- - rspec-ee system pg12 decomposed
+ # EE single-db jobs
+ - rspec-ee migration pg12 single-db
+ - rspec-ee unit pg12 single-db
+ - rspec-ee integration pg12 single-db
+ - rspec-ee system pg12 single-db
# Geo jobs
- rspec-ee unit pg12 geo
- rspec-ee integration pg12 geo
@@ -567,16 +581,16 @@ rspec:coverage:
# As-if-FOSS jobs
- rspec migration pg12-as-if-foss
- rspec migration pg12-as-if-foss minimal
- - rspec migration pg12-as-if-foss decomposed
+ - rspec migration pg12-as-if-foss single-db
- rspec unit pg12-as-if-foss
- rspec unit pg12-as-if-foss minimal
- - rspec unit pg12-as-if-foss decomposed
+ - rspec unit pg12-as-if-foss single-db
- rspec integration pg12-as-if-foss
- rspec integration pg12-as-if-foss minimal
- - rspec integration pg12-as-if-foss decomposed
+ - rspec integration pg12-as-if-foss single-db
- rspec system pg12-as-if-foss
- rspec system pg12-as-if-foss minimal
- - rspec system pg12-as-if-foss decomposed
+ - rspec system pg12-as-if-foss single-db
script:
- run_timed_command "bundle exec scripts/merge-simplecov"
coverage: '/LOC \((\d+\.\d+%)\) covered.$/'
@@ -666,11 +680,11 @@ rspec migration pg12-as-if-foss minimal:
- .minimal-rspec-tests
- .rails:rules:as-if-foss-migration:minimal
-rspec migration pg12-as-if-foss decomposed:
+rspec migration pg12-as-if-foss single-db:
extends:
- rspec migration pg12-as-if-foss
- - .decomposed-database-rspec
- - .rails:rules:decomposed-databases
+ - .single-db-rspec
+ - .rails:rules:single-db
rspec unit pg12-as-if-foss:
extends:
@@ -684,11 +698,11 @@ rspec unit pg12-as-if-foss minimal:
- .minimal-rspec-tests
- .rails:rules:as-if-foss-unit:minimal
-rspec unit pg12-as-if-foss decomposed:
+rspec unit pg12-as-if-foss single-db:
extends:
- rspec unit pg12-as-if-foss
- - .decomposed-database-rspec
- - .rails:rules:decomposed-databases
+ - .single-db-rspec
+ - .rails:rules:single-db
rspec integration pg12-as-if-foss:
extends:
@@ -702,11 +716,11 @@ rspec integration pg12-as-if-foss minimal:
- .minimal-rspec-tests
- .rails:rules:as-if-foss-integration:minimal
-rspec integration pg12-as-if-foss decomposed:
+rspec integration pg12-as-if-foss single-db:
extends:
- rspec integration pg12-as-if-foss
- - .decomposed-database-rspec
- - .rails:rules:decomposed-databases
+ - .single-db-rspec
+ - .rails:rules:single-db
rspec system pg12-as-if-foss:
extends:
@@ -720,11 +734,11 @@ rspec system pg12-as-if-foss minimal:
- .minimal-rspec-tests
- .rails:rules:as-if-foss-system:minimal
-rspec system pg12-as-if-foss decomposed:
+rspec system pg12-as-if-foss single-db:
extends:
- rspec system pg12-as-if-foss
- - .decomposed-database-rspec
- - .rails:rules:decomposed-databases
+ - .single-db-rspec
+ - .rails:rules:single-db
rspec migration pg12-as-if-jh:
extends:
@@ -764,11 +778,11 @@ rspec-ee migration pg12 minimal:
- .minimal-rspec-tests
- .rails:rules:ee-only-migration:minimal
-rspec-ee migration pg12 decomposed:
+rspec-ee migration pg12 single-db:
extends:
- rspec-ee migration pg12
- - .decomposed-database-rspec
- - .rails:rules:decomposed-databases
+ - .single-db-rspec
+ - .rails:rules:single-db
rspec-ee unit pg12:
extends:
@@ -782,11 +796,11 @@ rspec-ee unit pg12 minimal:
- .minimal-rspec-tests
- .rails:rules:ee-only-unit:minimal
-rspec-ee unit pg12 decomposed:
+rspec-ee unit pg12 single-db:
extends:
- rspec-ee unit pg12
- - .decomposed-database-rspec
- - .rails:rules:decomposed-databases
+ - .single-db-rspec
+ - .rails:rules:single-db
rspec-ee integration pg12:
extends:
@@ -800,11 +814,11 @@ rspec-ee integration pg12 minimal:
- .minimal-rspec-tests
- .rails:rules:ee-only-integration:minimal
-rspec-ee integration pg12 decomposed:
+rspec-ee integration pg12 single-db:
extends:
- rspec-ee integration pg12
- - .decomposed-database-rspec
- - .rails:rules:decomposed-databases
+ - .single-db-rspec
+ - .rails:rules:single-db
rspec-ee system pg12:
extends:
@@ -818,11 +832,11 @@ rspec-ee system pg12 minimal:
- .minimal-rspec-tests
- .rails:rules:ee-only-system:minimal
-rspec-ee system pg12 decomposed:
+rspec-ee system pg12 single-db:
extends:
- rspec-ee system pg12
- - .decomposed-database-rspec
- - .rails:rules:decomposed-databases
+ - .single-db-rspec
+ - .rails:rules:single-db
rspec-ee unit pg12 geo:
extends:
diff --git a/.gitlab/ci/reports.gitlab-ci.yml b/.gitlab/ci/reports.gitlab-ci.yml
index b9d2e31191a..d040abfe902 100644
--- a/.gitlab/ci/reports.gitlab-ci.yml
+++ b/.gitlab/ci/reports.gitlab-ci.yml
@@ -121,6 +121,11 @@ yarn-audit-dependency_scanning:
- cd .. && tar -I "gzip --best" -cf gitlab.tgz gitlab/
script:
- DEBUG=* node /usr/src/app/cli.js analyze --format gitlab --manager ${PACKAGE_MANAGER} gitlab.tgz | tee ${CI_PROJECT_DIR}/gl-dependency-scanning-report.json
+ after_script:
+ - mkdir ~/.aws
+ - '[[ -z "${AWS_SIEM_REPORT_INGESTION_CREDENTIALS_FILE}" ]] || mv "${AWS_SIEM_REPORT_INGESTION_CREDENTIALS_FILE}" ~/.aws/credentials'
+ - npm install --no-save --ignore-scripts @aws-sdk/client-s3@3.49.0
+ - scripts/ingest-reports-to-siem
artifacts:
paths:
- gl-dependency-scanning-report.json
diff --git a/.gitlab/ci/review-apps/dast.gitlab-ci.yml b/.gitlab/ci/review-apps/dast.gitlab-ci.yml
index d0ad4d23a82..df8ad4c517a 100644
--- a/.gitlab/ci/review-apps/dast.gitlab-ci.yml
+++ b/.gitlab/ci/review-apps/dast.gitlab-ci.yml
@@ -5,7 +5,7 @@
extends:
- .reports:rules:schedule-dast
image:
- name: "registry.gitlab.com/gitlab-org/security-products/dast:$DAST_VERSION"
+ name: "registry.gitlab.com/security-products/dast:$DAST_VERSION"
resource_group: dast_scan
variables:
DAST_USERNAME_FIELD: "user[login]"
diff --git a/.gitlab/ci/review-apps/qa.gitlab-ci.yml b/.gitlab/ci/review-apps/qa.gitlab-ci.yml
index eaf6429ad58..a955096992f 100644
--- a/.gitlab/ci/review-apps/qa.gitlab-ci.yml
+++ b/.gitlab/ci/review-apps/qa.gitlab-ci.yml
@@ -42,9 +42,6 @@
expire_in: 7 days
when: always
-.parallel-qa-base:
- parallel: 5
-
.allure-report-base:
image:
name: ${GITLAB_DEPENDENCY_PROXY}andrcuns/allure-report-publisher:0.4.2
@@ -82,7 +79,7 @@ review-qa-reliable:
extends:
- .review-qa-base
- .review:rules:review-qa-reliable
- - .parallel-qa-base
+ parallel: 8
retry: 1
variables:
QA_RUN_TYPE: review-qa-reliable
@@ -92,10 +89,11 @@ review-qa-all:
extends:
- .review-qa-base
- .review:rules:review-qa-all
- - .parallel-qa-base
+ parallel: 5
variables:
QA_RUN_TYPE: review-qa-all
QA_SCENARIO: Test::Instance::All
+ QA_SKIP_SMOKE_RELIABLE: "true"
review-performance:
extends:
diff --git a/.gitlab/ci/rules.gitlab-ci.yml b/.gitlab/ci/rules.gitlab-ci.yml
index a4bb99c49ad..70b532b97f4 100644
--- a/.gitlab/ci/rules.gitlab-ci.yml
+++ b/.gitlab/ci/rules.gitlab-ci.yml
@@ -61,8 +61,8 @@
.if-merge-request-labels-run-all-jest: &if-merge-request-labels-run-all-jest
if: '$CI_MERGE_REQUEST_LABELS =~ /pipeline:run-all-jest/'
-.if-merge-request-labels-run-decomposed: &if-merge-request-labels-run-decomposed
- if: '$CI_MERGE_REQUEST_LABELS =~ /pipeline:run-decomposed/'
+.if-merge-request-labels-run-single-db: &if-merge-request-labels-run-single-db
+ if: '$CI_MERGE_REQUEST_LABELS =~ /pipeline:run-single-db/'
.if-merge-request-labels-run-review-app: &if-merge-request-labels-run-review-app
if: '$CI_MERGE_REQUEST_LABELS =~ /pipeline:run-review-app/'
@@ -147,6 +147,9 @@
- "scripts/trigger-build.rb"
- "{,ee/,jh/}{bin,config}/**/*.rb"
+.ci-templates-patterns: &ci-templates-patterns
+ - "lib/gitlab/ci/templates/**/*.gitlab-ci.yml"
+
.ci-qa-patterns: &ci-qa-patterns
- ".gitlab-ci.yml"
- ".gitlab/ci/frontend.gitlab-ci.yml"
@@ -164,6 +167,7 @@
.yaml-lint-patterns: &yaml-lint-patterns
- ".gitlab-ci.yml"
- ".gitlab/ci/**/*.yml"
+ - "data/**/*.yml"
- "lib/gitlab/ci/templates/**/*.yml"
.docs-patterns: &docs-patterns
@@ -247,7 +251,7 @@
# List explicitly all the app/ dirs that are backend (i.e. all except app/assets).
- "{,ee/,jh/}{app/channels,app/controllers,app/finders,app/graphql,app/helpers,app/mailers,app/models,app/policies,app/presenters,app/serializers,app/services,app/uploaders,app/validators,app/views,app/workers}/**/*"
- "{,ee/,jh/}{bin,cable,config,db,generator_templates,lib}/**/*"
- - "{,ee/,jh/}spec/**/*.rb"
+ - "{,ee/,jh/}spec/**/*"
# CI changes
- ".gitlab-ci.yml"
- ".gitlab/ci/**/*"
@@ -441,6 +445,9 @@
- "GITLAB_WORKHORSE_VERSION"
- "workhorse/**/*"
- ".gitlab/ci/workhorse.gitlab-ci.yml"
+ # CI Templates changes
+ - "scripts/lint_templates_bash.rb"
+ - "lib/gitlab/ci/templates/**/*.gitlab-ci.yml"
.danger-patterns: &danger-patterns
- "Dangerfile"
@@ -609,6 +616,15 @@
when: manual
allow_failure: true
+######################
+# CI Templates Rules #
+######################
+.ci-templates:rules:shellcheck:
+ rules:
+ - changes: *ci-templates-patterns
+ - changes:
+ - scripts/lint_templates_bash.rb
+
##################
# Delivery rules #
##################
@@ -876,14 +892,26 @@
###############
# Rails rules #
###############
+.rails:rules:build-components:
+ rules:
+ - <<: *if-dot-com-ee-schedule
+ - <<: *if-dot-com-gitlab-org-default-branch
+ changes:
+ - "workhorse/**/*"
+ - <<: *if-dot-com-gitlab-org-merge-request
+ when: manual
+ allow_failure: true
+
.rails:rules:setup-test-env:
rules:
- changes: *setup-test-env-patterns
- <<: *if-merge-request-labels-run-all-rspec
-.rails:rules:decomposed-databases:
+.rails:rules:single-db:
rules:
- - <<: *if-merge-request-labels-run-decomposed
+ - <<: *if-merge-request-labels-run-single-db
+ - <<: *if-merge-request
+ changes: *db-patterns
- <<: *if-default-branch-schedule-nightly
.rails:rules:ee-and-foss-migration:
diff --git a/.gitlab/ci/setup.gitlab-ci.yml b/.gitlab/ci/setup.gitlab-ci.yml
index 1aeccfcb212..ad500fe0ddc 100644
--- a/.gitlab/ci/setup.gitlab-ci.yml
+++ b/.gitlab/ci/setup.gitlab-ci.yml
@@ -159,7 +159,7 @@ add-jh-folder:
script:
- JH_BRANCH=$(./scripts/setup/find-jh-branch.rb)
- 'echo "JH_BRANCH: ${JH_BRANCH}"'
- - curl --location -o "jh-folder.tar.gz" "https://gitlab.com/gitlab-org/gitlab-jh/gitlab/-/archive/${JH_BRANCH}/gitlab-${JH_BRANCH}.tar.gz?path=jh"
+ - curl --location -o "jh-folder.tar.gz" "https://gitlab.com/gitlab-org/gitlab-jh-mirrors/gitlab/-/archive/${JH_BRANCH}/gitlab-${JH_BRANCH}.tar.gz?path=jh"
- tar -xf "jh-folder.tar.gz"
- mv "gitlab-${JH_BRANCH}-jh/jh/" ./
- cp Gemfile.lock jh/
diff --git a/.gitlab/ci/yaml.gitlab-ci.yml b/.gitlab/ci/yaml.gitlab-ci.yml
index 218dc0a7859..606bb385325 100644
--- a/.gitlab/ci/yaml.gitlab-ci.yml
+++ b/.gitlab/ci/yaml.gitlab-ci.yml
@@ -8,6 +8,6 @@ lint-yaml:
stage: lint
needs: []
variables:
- LINT_PATHS: .gitlab-ci.yml .gitlab/ci lib/gitlab/ci/templates
+ LINT_PATHS: .gitlab-ci.yml .gitlab/ci lib/gitlab/ci/templates data/deprecations data/removals data/whats_new
script:
- yamllint --strict -f colored $LINT_PATHS
diff --git a/.gitlab/issue_templates/Deprecations.md b/.gitlab/issue_templates/Deprecations.md
index cea010153bb..2e48c272316 100644
--- a/.gitlab/issue_templates/Deprecations.md
+++ b/.gitlab/issue_templates/Deprecations.md
@@ -34,15 +34,33 @@ Which tier is this feature available in?
* Ultimate
-->
-### Checklist
+### Checklists
-- [ ] @mention your stage's stable counterparts on this issue. For example, Customer Support, Customer Success (Technical Account Manager), Product Marketing Manager.
+**Labels**
+
+- [ ] This issue is labeled ~deprecation, and with the relevant `~devops::`, `~group::`, and `~Category:` labels.
+- [ ] This issue is labeled ~"breaking change" if the removal of the deprecated item will be a [breaking change](https://about.gitlab.com/handbook/product/gitlab-the-product/#examples-of-breaking-changes).
+
+**Timeline**
+
+Please add links to the relevant merge requests.
+
+- As soon as possible, but no later than the third milestone preceding the major release (for example, given the following release schedule: `14.8, 14.9, 14.10, 15.0` – `14.8` is the third milestone preceding the major release):
+ - [ ] A [deprecation entry](https://about.gitlab.com/handbook/marketing/blog/release-posts/#creating-a-deprecation-entry) has been created so the deprecation will appear in release posts and on the [general deprecation page](https://docs.gitlab.com/ee/update/deprecations).
+ - [ ] Documentation has been updated to add a note about the [end-of-life](https://docs.gitlab.com/ee/development/documentation/styleguide/#end-of-life-for-features-or-products) and to mark the feature as [deprecated](https://docs.gitlab.com/ee/development/documentation/styleguide/#deprecated-features).
+- [ ] On or before the major milestone: A [removal entry](https://about.gitlab.com/handbook/marketing/blog/release-posts/#removals) has been created so the removal will appear on the [removals by milestones](https://docs.gitlab.com/ee/update/removals) page and be announced in the release post.
+- On the major milestone:
+ - [ ] The deprecated item has been removed.
+ - [ ] If the removal of the deprecated item is a [breaking change](https://about.gitlab.com/handbook/product/gitlab-the-product/#examples-of-breaking-changes), the merge request is labeled ~"breaking change".
+
+**Mentions**
+
+- [ ] Your stage's stable counterparts have been `@mentioned` on this issue. For example, Customer Support, Customer Success (Technical Account Manager), Product Marketing Manager.
- To see who the stable counterparts are for a product team visit [product categories](https://about.gitlab.com/handbook/product/categories/)
- If there is no stable counterpart listed for Sales/CS please mention `@timtams`
- If there is no stable counterpart listed for Support please mention `@gitlab-com/support/managers`
- If there is no stable counterpart listed for Marketing please mention `@cfoster3`
-
-- [ ] `@mention` your GPM so that they are aware of planned deprecations. The goal is to have reviews happen at least two releases before the final removal of the feature or introduction of a breaking change.
+- [ ] Your GPM has been `@mentioned` so that they are aware of planned deprecations. The goal is to have reviews happen at least two releases before the final removal of the feature or introduction of a breaking change.
### Deprecation Milestone
@@ -75,6 +93,6 @@ Use the following resources to find the appropriate labels:
/label ~"GitLab Free" ~"GitLab Premium" ~"GitLab Ultimate"
<!-- Identifies that this Issue is related to deprecating a feature -->
-/label ~"type::deprecation"
+/label ~"deprecation"
<!-- Add the ~"breaking change" label to this issue if necessary -->
diff --git a/.gitlab/issue_templates/Design Sprint.md b/.gitlab/issue_templates/Design Sprint.md
index 7772c2d5803..f85d41a112e 100644
--- a/.gitlab/issue_templates/Design Sprint.md
+++ b/.gitlab/issue_templates/Design Sprint.md
@@ -146,16 +146,18 @@ Deciding which persona we are focusing on will be part of the Day 1 discussions
* [Delaney (Development Team Lead)](https://about.gitlab.com/handbook/marketing/product-marketing/roles-personas/#delaney-development-team-lead)
* [Presley (Product Designer)](https://about.gitlab.com/handbook/marketing/product-marketing/roles-personas/#presley-product-designer)
* [Sasha (Software Developer)](https://about.gitlab.com/handbook/marketing/product-marketing/roles-personas/#sasha-software-developer)
-* [Devon (DevOps Engineer)](https://about.gitlab.com/handbook/marketing/product-marketing/roles-personas/#devon-devops-engineer)
+* [Priyanka (Platform Engineer)](https://about.gitlab.com/handbook/marketing/product-marketing/roles-personas/#priyanka-platform-engineer)
* [Sidney (Systems Administrator)](https://about.gitlab.com/handbook/marketing/product-marketing/roles-personas/#sidney-systems-administrator)
* [Sam (Security Analyst)](https://about.gitlab.com/handbook/marketing/product-marketing/roles-personas/#sam-security-analyst)
* [Rachel (Release Manager)](https://about.gitlab.com/handbook/marketing/product-marketing/roles-personas/#rachel-release-manager)
* [Alex (Security Operations Engineer)](https://about.gitlab.com/handbook/marketing/product-marketing/roles-personas/#alex-security-operations-engineer)
* [Simone (Software Engineer in Test)](https://about.gitlab.com/handbook/marketing/product-marketing/roles-personas/#simone-software-engineer-in-test)
* [Allison (Application Ops)](https://about.gitlab.com/handbook/marketing/product-marketing/roles-personas/#allison-application-ops)
-* [Priyanka (Platform Engineer)](https://about.gitlab.com/handbook/marketing/product-marketing/roles-personas/#priyanka-platform-engineer)
+* [Ingrid (Infrastructure Operator)](https://about.gitlab.com/handbook/product/personas/#ingrid-infrastructure-operator)
+* [Dakota (Application Development Director)](https://about.gitlab.com/handbook/product/personas/#dakota-application-development-director)
* [Dana (Data Analyst)](https://about.gitlab.com/handbook/marketing/product-marketing/roles-personas/#dana-data-analyst)
* [Eddie (Content Editor)](https://about.gitlab.com/handbook/marketing/product-marketing/roles-personas/#eddie-content-editor)
+
-->
## Agenda
diff --git a/.gitlab/issue_templates/Doc_cleanup.md b/.gitlab/issue_templates/Doc_cleanup.md
new file mode 100644
index 00000000000..69caea1ae1e
--- /dev/null
+++ b/.gitlab/issue_templates/Doc_cleanup.md
@@ -0,0 +1,53 @@
+<!--
+* Use this issue template for identifying issues to work on in existing documentation, normally identified
+* with our [Vale](https://docs.gitlab.com/ee/development/documentation/testing.html#vale) or [markdownlint](https://docs.gitlab.com/ee/development/documentation/testing.html#markdownlint) tools. Much of this identified work is suitable for first-time contributors or
+* for work during Hackathons.
+*
+* Normal documentation updates should use the Documentation template, and documentation work as part of
+* feature development should use the Feature Request template.
+-->
+
+## Identified documentation issue
+
+<!--
+* Include information about the issue that needs resolution. If the item is from an automated test,
+* be sure to include a copy/paste from the the test results. [This issue](https://gitlab.com/gitlab-org/gitlab/-/issues/339543) is an example of text to include with a Vale issue.
+*
+* Limit the identified work to be related to one another, and keep it to a reasonable amount. For example,
+* several moderate changes on one page, a few intermediate changes across five pages, or several very small
+* changes for up to 10 pages. Larger items should be broken out into other issues to better distribute
+* the opportunities for contributors.
+-->
+
+## Process
+
+If you, as a contributor, decide to take this work on, assign this issue to yourself, and create one or more linked
+merge requests that resolve this issue. Be sure to close this issue after all linked merge requests are completed.
+
+The work for this issue should involve only what's listed in the previous section. If you identify other work that
+needs to be done, create separate, unlinked MRs as needed to address those items.
+
+When using automated test results for identified work, use this issue to work only on the listed lines. For
+example, if the tests list several lines that show the word "admin" as needing to possibly be "administrator,"
+do not modify other parts of the page that may also include "admin," as the testing may have excluded those lines
+(for example, they may be part of the **Admin Area** of GitLab).
+
+## Additional information
+
+<!--
+* Any concepts, procedures, reference info we could add to make it easier to successfully use GitLab?
+* Include use cases, benefits, and/or goals for this work.
+* If adding content: What audience is it intended for? (What roles and scenarios?)
+ For ideas, see personas at https://about.gitlab.com/handbook/marketing/product-marketing/roles-personas/ or the persona labels at
+ https://gitlab.com/groups/gitlab-org/-/labels?subscribed=&search=persona%3A
+-->
+
+### Who can address the issue
+
+<!-- What if any special expertise is required to resolve this issue? -->
+
+### Other links/references
+
+<!-- For example, related GitLab issues/MRs -->
+
+/label ~documentation
diff --git a/.gitlab/issue_templates/Dogfooding.md b/.gitlab/issue_templates/Dogfooding.md
index d780fbd3f1f..9545c9bc9d4 100644
--- a/.gitlab/issue_templates/Dogfooding.md
+++ b/.gitlab/issue_templates/Dogfooding.md
@@ -1,6 +1,6 @@
<!--Lightweight issue template to encourage Dogfooding and educate team members about the importance of Dogfooding -->
-/label ~"dogfooding" ~"group::" ~"section::" ~"Category::"
+/label ~"dogfooding" ~"group::" ~"section::" ~"Category:"
## Feature to Dogfood
<!--Link to Description of feature (Documentation, Epic, Opportunity Canvas, etc.) -->
diff --git a/.gitlab/issue_templates/Feature Flag Roll Out.md b/.gitlab/issue_templates/Feature Flag Roll Out.md
index 590e627df75..0d150bcb56c 100644
--- a/.gitlab/issue_templates/Feature Flag Roll Out.md
+++ b/.gitlab/issue_templates/Feature Flag Roll Out.md
@@ -89,7 +89,8 @@ _Consider adding links to check for Sentry errors, Production logs for 5xx, 302s
- [ ] Ensure that you or a representative in development can be available for at least 2 hours after feature flag updates in production.
If a different developer will be covering, or an exception is needed, please inform the oncall SRE by using the `@sre-oncall` Slack alias.
- [ ] Ensure that documentation has been updated ([More info](https://docs.gitlab.com/ee/development/documentation/feature_flags.html#features-that-became-enabled-by-default)).
-- [ ] Announce on [the feature issue](ISSUE LINK) an estimated time this will be enabled on GitLab.com.
+- [ ] Announce on [the feature issue](ISSUE LINK) an estimated time this will be enabled on GitLab.com.
+- [ ] Ensure that any breaking changes have been announced following the [release post process](https://about.gitlab.com/handbook/marketing/blog/release-posts/#deprecations-removals-and-breaking-changes) to ensure GitLab customers are aware.
- [ ] Notify `#support_gitlab-com` and your team channel ([more guidance when this is necessary in the dev docs](https://docs.gitlab.com/ee/development/feature_flags/controls.html#communicate-the-change)).
### Global rollout on production
@@ -100,7 +101,7 @@ For visibility, all `/chatops` commands that target production should be execute
- If the feature flag in code has [an actor](https://docs.gitlab.com/ee/development/feature_flags/#feature-actors), perform **actor-based** rollout.
- [ ] `/chatops run feature set <feature-flag-name> <rollout-percentage> --actors`
- If the feature flag in code does **NOT** have [an actor](https://docs.gitlab.com/ee/development/feature_flags/#feature-actors), perform time-based rollout (**random** rollout).
- - [ ] `/chatops run feature set <feature-flag-name> <rollout-percentage>`
+ - [ ] `/chatops run feature set <feature-flag-name> <rollout-percentage> --random`
- Enable the feature globally on production environment.
- [ ] `/chatops run feature set <feature-flag-name> true`
- [ ] Announce on [the feature issue](ISSUE LINK) that the feature has been globally enabled.
diff --git a/.gitlab/issue_templates/Feature Proposal - lean.md b/.gitlab/issue_templates/Feature Proposal - lean.md
index 53ad17bbf39..c902c254618 100644
--- a/.gitlab/issue_templates/Feature Proposal - lean.md
+++ b/.gitlab/issue_templates/Feature Proposal - lean.md
@@ -25,17 +25,17 @@ Personas are described at https://about.gitlab.com/handbook/marketing/product-ma
* [Delaney (Development Team Lead)](https://about.gitlab.com/handbook/marketing/product-marketing/roles-personas/#delaney-development-team-lead)
* [Presley (Product Designer)](https://about.gitlab.com/handbook/marketing/product-marketing/roles-personas/#presley-product-designer)
* [Sasha (Software Developer)](https://about.gitlab.com/handbook/marketing/product-marketing/roles-personas/#sasha-software-developer)
-* [Devon (DevOps Engineer)](https://about.gitlab.com/handbook/marketing/product-marketing/roles-personas/#devon-devops-engineer)
+* [Priyanka (Platform Engineer)](https://about.gitlab.com/handbook/marketing/product-marketing/roles-personas/#priyanka-platform-engineer)
* [Sidney (Systems Administrator)](https://about.gitlab.com/handbook/marketing/product-marketing/roles-personas/#sidney-systems-administrator)
* [Sam (Security Analyst)](https://about.gitlab.com/handbook/marketing/product-marketing/roles-personas/#sam-security-analyst)
* [Rachel (Release Manager)](https://about.gitlab.com/handbook/marketing/product-marketing/roles-personas/#rachel-release-manager)
* [Alex (Security Operations Engineer)](https://about.gitlab.com/handbook/marketing/product-marketing/roles-personas/#alex-security-operations-engineer)
* [Simone (Software Engineer in Test)](https://about.gitlab.com/handbook/marketing/product-marketing/roles-personas/#simone-software-engineer-in-test)
* [Allison (Application Ops)](https://about.gitlab.com/handbook/marketing/product-marketing/roles-personas/#allison-application-ops)
-* [Priyanka (Platform Engineer)](https://about.gitlab.com/handbook/marketing/product-marketing/roles-personas/#priyanka-platform-engineer)
+* [Ingrid (Infrastructure Operator)](https://about.gitlab.com/handbook/product/personas/#ingrid-infrastructure-operator)
+* [Dakota (Application Development Director)](https://about.gitlab.com/handbook/product/personas/#dakota-application-development-director)
* [Dana (Data Analyst)](https://about.gitlab.com/handbook/marketing/product-marketing/roles-personas/#dana-data-analyst)
* [Eddie (Content Editor)](https://about.gitlab.com/handbook/marketing/product-marketing/roles-personas/#eddie-content-editor)
-
-->
### Feature Usage Metrics
diff --git a/.gitlab/issue_templates/Feature proposal - detailed.md b/.gitlab/issue_templates/Feature proposal - detailed.md
index 78faf146fbe..d60b5f24dee 100644
--- a/.gitlab/issue_templates/Feature proposal - detailed.md
+++ b/.gitlab/issue_templates/Feature proposal - detailed.md
@@ -4,7 +4,7 @@
<!-- What is the problem and solution you're proposing? This content sets the overall vision for the feature and serves as the release notes that will populate in various places, including the [release post blog](https://about.gitlab.com/releases/categories/releases/) and [Gitlab project releases](https://gitlab.com/gitlab-org/gitlab/-/releases). " -->
-### Problem to solve
+### Problem to solve
<!-- What problem do we solve? Try to define the who/what/why of the opportunity as a user story. For example, "As a (who), I want (what), so I can (why/value)." -->
@@ -19,16 +19,18 @@ Personas are described at https://about.gitlab.com/handbook/marketing/product-ma
* [Delaney (Development Team Lead)](https://about.gitlab.com/handbook/marketing/product-marketing/roles-personas/#delaney-development-team-lead)
* [Presley (Product Designer)](https://about.gitlab.com/handbook/marketing/product-marketing/roles-personas/#presley-product-designer)
* [Sasha (Software Developer)](https://about.gitlab.com/handbook/marketing/product-marketing/roles-personas/#sasha-software-developer)
-* [Devon (DevOps Engineer)](https://about.gitlab.com/handbook/marketing/product-marketing/roles-personas/#devon-devops-engineer)
+* [Priyanka (Platform Engineer)](https://about.gitlab.com/handbook/marketing/product-marketing/roles-personas/#priyanka-platform-engineer)
* [Sidney (Systems Administrator)](https://about.gitlab.com/handbook/marketing/product-marketing/roles-personas/#sidney-systems-administrator)
* [Sam (Security Analyst)](https://about.gitlab.com/handbook/marketing/product-marketing/roles-personas/#sam-security-analyst)
* [Rachel (Release Manager)](https://about.gitlab.com/handbook/marketing/product-marketing/roles-personas/#rachel-release-manager)
* [Alex (Security Operations Engineer)](https://about.gitlab.com/handbook/marketing/product-marketing/roles-personas/#alex-security-operations-engineer)
* [Simone (Software Engineer in Test)](https://about.gitlab.com/handbook/marketing/product-marketing/roles-personas/#simone-software-engineer-in-test)
* [Allison (Application Ops)](https://about.gitlab.com/handbook/marketing/product-marketing/roles-personas/#allison-application-ops)
-* [Priyanka (Platform Engineer)](https://about.gitlab.com/handbook/marketing/product-marketing/roles-personas/#priyanka-platform-engineer)
+* [Ingrid (Infrastructure Operator)](https://about.gitlab.com/handbook/product/personas/#ingrid-infrastructure-operator)
+* [Dakota (Application Development Director)](https://about.gitlab.com/handbook/product/personas/#dakota-application-development-director)
* [Dana (Data Analyst)](https://about.gitlab.com/handbook/marketing/product-marketing/roles-personas/#dana-data-analyst)
* [Eddie (Content Editor)](https://about.gitlab.com/handbook/marketing/product-marketing/roles-personas/#eddie-content-editor)
+
-->
### User experience goal
@@ -37,7 +39,6 @@ Personas are described at https://about.gitlab.com/handbook/marketing/product-ma
For example, "The user should be able to use the UI/API/.gitlab-ci.yml with GitLab to <perform a specific task>"
https://about.gitlab.com/handbook/engineering/ux/ux-research-training/user-story-mapping/ -->
-
### Proposal
<!-- How are we going to solve the problem? Try to include the user journey! https://about.gitlab.com/handbook/journeys/#user-journey -->
@@ -55,9 +56,9 @@ Consider adding checkboxes and expectations of users with certain levels of memb
* [ ] Add expected impact to Reporter (20) members
* [ ] Add expected impact to Developer (30) members
* [ ] Add expected impact to Maintainer (40) members
-* [ ] Add expected impact to Owner (50) members
+* [ ] Add expected impact to Owner (50) members
-Please consider performing a threat model for the code changes that are introduced as part of this feature. To get started, refer to our Threat Modeling handbook page https://about.gitlab.com/handbook/security/threat_modeling/#threat-modeling.
+Please consider performing a threat model for the code changes that are introduced as part of this feature. To get started, refer to our Threat Modeling handbook page https://about.gitlab.com/handbook/security/threat_modeling/#threat-modeling.
Don't hesitate to reach out to the Application Security Team (`@gitlab-com/gl-security/appsec`) to discuss any security concerns.
-->
@@ -91,7 +92,7 @@ See the test engineering planning process and reach out to your counterpart Soft
* Ultimate/Gold
-->
-### Feature Usage Metrics
+### Feature Usage Metrics
<!-- How are you going to track usage of this feature? Think about user behavior and their interaction with the product. What indicates someone is getting value from it?
diff --git a/.gitlab/issue_templates/Fulfillment Group UX Issue.md b/.gitlab/issue_templates/Fulfillment Group UX Issue.md
index 97f3782c4df..86db27e1c53 100644
--- a/.gitlab/issue_templates/Fulfillment Group UX Issue.md
+++ b/.gitlab/issue_templates/Fulfillment Group UX Issue.md
@@ -2,7 +2,7 @@
The goal of this template is to ensure we have captured all the information available to the product designer so they can approach the problem creatively and efficiently. Please add links to SSOT if this informatin exists elsewhere. -->
-### Who will use this solution?
+### Who will use this solution?
<!-- If known, include any of the following: types of users (e.g. Developer), personas, or specific company roles (e.g. Release Manager). It's okay to write "Unknown" and fill this field in later.
@@ -13,14 +13,15 @@ Personas are described at https://about.gitlab.com/handbook/marketing/product-ma
* [Delaney (Development Team Lead)](https://about.gitlab.com/handbook/marketing/product-marketing/roles-personas/#delaney-development-team-lead)
* [Presley (Product Designer)](https://about.gitlab.com/handbook/marketing/product-marketing/roles-personas/#presley-product-designer)
* [Sasha (Software Developer)](https://about.gitlab.com/handbook/marketing/product-marketing/roles-personas/#sasha-software-developer)
-* [Devon (DevOps Engineer)](https://about.gitlab.com/handbook/marketing/product-marketing/roles-personas/#devon-devops-engineer)
+* [Priyanka (Platform Engineer)](https://about.gitlab.com/handbook/marketing/product-marketing/roles-personas/#priyanka-platform-engineer)
* [Sidney (Systems Administrator)](https://about.gitlab.com/handbook/marketing/product-marketing/roles-personas/#sidney-systems-administrator)
* [Sam (Security Analyst)](https://about.gitlab.com/handbook/marketing/product-marketing/roles-personas/#sam-security-analyst)
* [Rachel (Release Manager)](https://about.gitlab.com/handbook/marketing/product-marketing/roles-personas/#rachel-release-manager)
* [Alex (Security Operations Engineer)](https://about.gitlab.com/handbook/marketing/product-marketing/roles-personas/#alex-security-operations-engineer)
* [Simone (Software Engineer in Test)](https://about.gitlab.com/handbook/marketing/product-marketing/roles-personas/#simone-software-engineer-in-test)
* [Allison (Application Ops)](https://about.gitlab.com/handbook/marketing/product-marketing/roles-personas/#allison-application-ops)
-* [Priyanka (Platform Engineer)](https://about.gitlab.com/handbook/marketing/product-marketing/roles-personas/#priyanka-platform-engineer)
+* [Ingrid (Infrastructure Operator)](https://about.gitlab.com/handbook/product/personas/#ingrid-infrastructure-operator)
+* [Dakota (Application Development Director)](https://about.gitlab.com/handbook/product/personas/#dakota-application-development-director)
* [Dana (Data Analyst)](https://about.gitlab.com/handbook/marketing/product-marketing/roles-personas/#dana-data-analyst)
* [Eddie (Content Editor)](https://about.gitlab.com/handbook/marketing/product-marketing/roles-personas/#eddie-content-editor)
@@ -54,5 +55,5 @@ Personas are described at https://about.gitlab.com/handbook/marketing/product-ma
-/label ~"group::" ~"section::" ~"Category::" ~UX
+/label ~"group::" ~"section::" ~"Category:" ~UX
diff --git a/.gitlab/issue_templates/QA Failure.md b/.gitlab/issue_templates/QA Failure.md
index 9751b40cb91..3171923d8c5 100644
--- a/.gitlab/issue_templates/QA Failure.md
+++ b/.gitlab/issue_templates/QA Failure.md
@@ -11,11 +11,16 @@ The issue should have the following:
- A link to the failing job.
- The stack trace from the job's logs in the "Stack trace" section below.
- A screenshot (if available), and HTML capture (if available), in the "Screenshot / HTML page" section below.
+- A link to the corresponding test case(s) in the summary.
--->
### Summary
+Failing job(s):
+Failing spec(s):
+
+Corresponding test case(s):
### Stack trace
@@ -52,7 +57,7 @@ If you include multiple screenshots it can be helpful to hide all but the first
/label ~Quality ~QA ~test
<!-- Test failure type label, please use just one.-->
-/label ~"failure::broken-test" ~"failure::flaky-test" ~"failure::stale-test" ~"failure::test-environment" ~"failure::investigating"
+/label ~"failure::broken-test" ~"failure::flaky-test" ~"failure::stale-test" ~"failure::test-environment" ~"failure::investigating" ~"failure::new"
<!--
Choose the stage that appears in the test path, e.g. ~"devops::create" for
diff --git a/.gitlab/issue_templates/Refactoring.md b/.gitlab/issue_templates/Refactoring.md
index df18dcf7656..453ae743237 100644
--- a/.gitlab/issue_templates/Refactoring.md
+++ b/.gitlab/issue_templates/Refactoring.md
@@ -42,8 +42,9 @@ please list them here.
Please select the appropriate label from the following:
~"feature::addition"
~"type::maintenance"
- ~"tooling::pipelines"
- ~"tooling::workflow"
+ ~"maintenance::refactor"
+ ~"maintenance::pipelines"
+ ~"maintenance::workflow"
-->
/label ~"type::maintenance"
diff --git a/.gitlab/merge_request_templates/Pipeline Configuration.md b/.gitlab/merge_request_templates/Pipeline Configuration.md
index a0b8d1cb8e4..336988d8bdf 100644
--- a/.gitlab/merge_request_templates/Pipeline Configuration.md
+++ b/.gitlab/merge_request_templates/Pipeline Configuration.md
@@ -35,4 +35,4 @@ This will help keep track of expected cost increases to the [GitLab project aver
- [ ] Consider communicating these changes to the broader team following the [communication guideline for pipeline changes](https://about.gitlab.com/handbook/engineering/quality/engineering-productivity/#pipeline-changes)
-/label ~"type::tooling" ~"tooling::pipelines" ~"Engineering Productivity"
+/label ~"maintenance::pipelines" ~"Engineering Productivity"
diff --git a/.gitlab/merge_request_templates/Security Release.md b/.gitlab/merge_request_templates/Security Release.md
index bfa80d65018..f43bddaa46e 100644
--- a/.gitlab/merge_request_templates/Security Release.md
+++ b/.gitlab/merge_request_templates/Security Release.md
@@ -31,7 +31,7 @@ See [the general developer security release guidelines](https://gitlab.com/gitla
## Maintainer checklist
- [ ] Correct milestone is applied and the title is matching across all backports.
-- [ ] Assigned to `@gitlab-release-tools-bot` with passing CI pipelines.
+- [ ] Assigned (_not_ as reviewer) to `@gitlab-release-tools-bot` with passing CI pipelines.
/label ~security
diff --git a/.gitpod.yml b/.gitpod.yml
index a67242e08a5..d1a709c55ea 100644
--- a/.gitpod.yml
+++ b/.gitpod.yml
@@ -20,6 +20,8 @@ tasks:
gdk config set gitlab.rails.port 443
gdk config set gitlab.rails.https.enabled true
gdk config set webpack.host 127.0.0.1
+ gdk config set webpack.static false
+ gdk config set webpack.live_reload false
# make documentation builds available
gdk config set gitlab_docs.enabled true
# reconfigure GDK
@@ -49,6 +51,8 @@ tasks:
gdk config set gitlab.rails.port 443
gdk config set gitlab.rails.https.enabled true
gdk config set webpack.host 127.0.0.1
+ gdk config set webpack.static false
+ gdk config set webpack.live_reload false
# reconfigure GDK
echo "$(date) – Reconfiguring GDK" | tee -a /workspace/startup.log
gdk reconfigure
diff --git a/.nvmrc b/.nvmrc
index 18711d290ea..832d3850644 100644
--- a/.nvmrc
+++ b/.nvmrc
@@ -1 +1 @@
-14.17.5
+16.14.0
diff --git a/.rubocop.yml b/.rubocop.yml
index 8416653d677..99424713bd8 100644
--- a/.rubocop.yml
+++ b/.rubocop.yml
@@ -16,6 +16,9 @@ inherit_from:
- ./rubocop/rubocop-migrations.yml
- ./rubocop/rubocop-usage-data.yml
- ./rubocop/rubocop-code_reuse.yml
+ <% Dir.glob('jh/rubocop/**/*.yml').each do |jh_rubocop_yaml| %>
+ - '<%= jh_rubocop_yaml %>'
+ <% end %>
inherit_mode:
merge:
@@ -43,6 +46,10 @@ AllCops:
CacheRootDirectory: <%= Dir.getwd %>/tmp
MaxFilesInCache: 30000
+Metrics/ParameterLists:
+ Exclude:
+ - 'app/components/**/*'
+
Cop/AvoidKeywordArgumentsInSidekiqWorkers:
Enabled: true
Include:
@@ -236,6 +243,10 @@ Rails/FindBy:
- 'spec/**/*.rb'
- 'ee/spec/**/*.rb'
+Rails/IndexBy:
+ Exclude:
+ - 'tooling/danger/**/*.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
@@ -604,8 +615,9 @@ Rails/TimeZone:
- 'ee/spec/workers/**/*'
- 'ee/lib/**/*'
- 'ee/spec/lib/**/*'
+ - 'spec/features/**/*'
+ - 'ee/spec/features/**/*'
-# WIP: See https://gitlab.com/gitlab-org/gitlab/-/issues/220040
Rails/SaveBang:
Enabled: true
AllowImplicitReturn: false
diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml
index ac8afd5c00c..2ffe70b4461 100644
--- a/.rubocop_todo.yml
+++ b/.rubocop_todo.yml
@@ -6,11 +6,6 @@
# Note that changes in the inspected code, or installation of new
# versions of RuboCop, may require this file to be generated again.
-# Offense count: 314
-# Cop supports --auto-correct.
-Capybara/CurrentPathExpectation:
- Enabled: false
-
# Offense count: 221
Capybara/VisibilityMatcher:
Enabled: false
@@ -20,11 +15,6 @@ Gitlab/PolicyRuleBoolean:
Exclude:
- 'ee/app/policies/ee/identity_provider_policy.rb'
-# Offense count: 5
-Graphql/IDType:
- Exclude:
- - 'app/graphql/mutations/boards/issues/issue_move_list.rb'
-
# Offense count: 2270
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, IndentationWidth.
@@ -32,13 +22,6 @@ Graphql/IDType:
Layout/ArgumentAlignment:
Enabled: false
-# Offense count: 54
-# Cop supports --auto-correct.
-# Configuration parameters: AllowAliasSyntax, AllowedMethods.
-# AllowedMethods: alias_method, public, protected, private
-Layout/EmptyLinesAroundAttributeAccessor:
- Enabled: false
-
# Offense count: 771
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, IndentationWidth.
@@ -124,11 +107,6 @@ Lint/BinaryOperatorWithIdenticalOperands:
Lint/ConstantDefinitionInBlock:
Enabled: false
-# Offense count: 1
-Lint/DuplicateRequire:
- Exclude:
- - 'ee/spec/lib/gitlab/auth/group_saml/user_spec.rb'
-
# Offense count: 2
# Configuration parameters: AllowComments.
Lint/EmptyFile:
@@ -136,13 +114,6 @@ Lint/EmptyFile:
- 'db/seeds.rb'
- 'ee/db/geo/seeds.rb'
-# Offense count: 8
-# Cop supports --auto-correct.
-Lint/IdentityComparison:
- Exclude:
- - 'spec/tooling/danger/weightage/maintainers_spec.rb'
- - 'spec/tooling/danger/weightage/reviewers_spec.rb'
-
# Offense count: 208
# Configuration parameters: MaximumRangeSize.
Lint/MissingCopEnableDirective:
@@ -182,11 +153,6 @@ Lint/StructNewOverride:
- 'app/serializers/environment_serializer.rb'
- 'lib/gitlab/ci/pipeline/duration.rb'
-# Offense count: 1
-Lint/UnreachableLoop:
- Exclude:
- - 'qa/qa/runtime/feature.rb'
-
# Offense count: 22
# Cop supports --auto-correct.
# Configuration parameters: AllowComments.
@@ -225,13 +191,6 @@ Naming/HeredocDelimiterCase:
Naming/HeredocDelimiterNaming:
Enabled: false
-# Offense count: 5
-# Configuration parameters: MinNameLength, AllowNamesEndingInNumbers, AllowedNames, ForbiddenNames.
-# AllowedNames: at, by, db, id, in, io, ip, of, on, os, pp, to
-Naming/MethodParameterName:
- Exclude:
- - 'lib/gitlab/diff/inline_diff.rb'
-
# Offense count: 218
# Cop supports --auto-correct.
# Configuration parameters: PreferredName.
@@ -278,16 +237,6 @@ Performance/DeletePrefix:
- 'spec/lib/gitlab/gfm/uploads_rewriter_spec.rb'
- 'spec/support/helpers/test_env.rb'
-# Offense count: 5
-# Cop supports --auto-correct.
-# Configuration parameters: SafeMultiline.
-Performance/DeleteSuffix:
- Exclude:
- - 'app/helpers/submodule_helper.rb'
- - 'app/workers/concerns/application_worker.rb'
- - 'ee/app/models/geo/upload_registry.rb'
- - 'ee/app/workers/geo/file_download_dispatch_worker/attachment_job_finder.rb'
-
# Offense count: 121
Performance/MethodObjectAsBlock:
Enabled: false
@@ -311,23 +260,6 @@ Performance/StringInclude:
- 'spec/spec_helper.rb'
- 'spec/support_specs/helpers/active_record/query_recorder_spec.rb'
-# Offense count: 18
-# Cop supports --auto-correct.
-Performance/Sum:
- Exclude:
- - 'app/controllers/projects/pipelines/tests_controller.rb'
- - 'app/models/application_setting_implementation.rb'
- - 'app/models/ci/pipeline.rb'
- - 'app/services/issues/export_csv_service.rb'
- - 'ee/spec/lib/gitlab/elastic/bulk_indexer_spec.rb'
- - 'lib/api/entities/issuable_time_stats.rb'
- - 'lib/container_registry/tag.rb'
- - 'lib/gitlab/ci/reports/test_suite_comparer.rb'
- - 'lib/gitlab/diff/file.rb'
- - 'lib/gitlab/usage_data.rb'
- - 'lib/peek/views/detailed_view.rb'
- - 'spec/models/namespace/root_storage_statistics_spec.rb'
-
# Offense count: 15209
# Configuration parameters: Prefixes.
# Prefixes: when, with, without
@@ -379,11 +311,6 @@ RSpec/ReturnFromStub:
RSpec/ScatteredLet:
Enabled: false
-# Offense count: 4
-RSpec/ScatteredSetup:
- Exclude:
- - 'spec/requests/api/jobs_spec.rb'
-
# Offense count: 10
# Configuration parameters: EnforcedStyle.
# SupportedStyles: symbols, strings
@@ -433,13 +360,6 @@ Rails/BelongsTo:
- 'app/models/deployment.rb'
- 'app/models/environment.rb'
-# Offense count: 93
-# Configuration parameters: Database, Include.
-# SupportedDatabases: mysql, postgresql
-# Include: db/migrate/*.rb
-Rails/BulkChangeTable:
- Enabled: false
-
# Offense count: 155
# Cop supports --auto-correct.
Rails/ContentTag:
@@ -485,24 +405,6 @@ Rails/HasManyOrHasOneDependent:
Rails/HelperInstanceVariable:
Enabled: false
-# Offense count: 17
-# Cop supports --auto-correct.
-Rails/IndexBy:
- Exclude:
- - 'app/graphql/types/design_management/design_fields.rb'
- - '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'
- - 'tooling/danger/sidekiq_queues.rb'
-
# Offense count: 47
# Cop supports --auto-correct.
Rails/IndexWith:
@@ -525,12 +427,6 @@ Rails/InverseOf:
Rails/LexicallyScopedActionFilter:
Enabled: false
-# Offense count: 2
-# Cop supports --auto-correct.
-Rails/LinkToBlank:
- Exclude:
- - 'app/helpers/projects_helper.rb'
- - 'ee/app/helpers/ee/users/callouts_helper.rb'
# Offense count: 1
# Cop supports --auto-correct.
@@ -572,14 +468,6 @@ Rails/RenderInline:
Exclude:
- 'ee/app/controllers/sitemap_controller.rb'
-# Offense count: 4
-# Cop supports --auto-correct.
-# Configuration parameters: EnforcedStyle.
-# SupportedStyles: conservative, aggressive
-Rails/ShortI18n:
- Exclude:
- - 'app/uploaders/content_type_whitelist.rb'
-
# Offense count: 1144
# Configuration parameters: ForbiddenMethods, AllowedMethods.
# ForbiddenMethods: decrement!, decrement_counter, increment!, increment_counter, insert, insert!, insert_all, insert_all!, toggle!, touch, touch_all, update_all, update_attribute, update_column, update_columns, update_counters, upsert, upsert_all
@@ -654,14 +542,6 @@ Style/CombinableLoops:
- 'spec/requests/api/members_spec.rb'
- 'spec/support/shared_examples/features/protected_branches_access_control_ce_shared_examples.rb'
-# Offense count: 1
-# Cop supports --auto-correct.
-# Configuration parameters: EnforcedStyle, SingleLineConditionsOnly, IncludeTernaryExpressions.
-# SupportedStyles: assign_to_condition, assign_inside_condition
-Style/ConditionalAssignment:
- Exclude:
- - 'lib/gitlab/database.rb'
-
# Offense count: 5
# Cop supports --auto-correct.
Style/EachWithObject:
@@ -777,18 +657,6 @@ Style/NumericLiteralPrefix:
Style/PercentLiteralDelimiters:
Enabled: false
-# Offense count: 26
-# Cop supports --auto-correct.
-# Configuration parameters: SafeForConstants.
-Style/RedundantFetchBlock:
- Exclude:
- - 'app/finders/admin/projects_finder.rb'
- - 'lib/gitlab/diff/file.rb'
- - 'spec/lib/gitlab/json_cache_spec.rb'
- - 'spec/lib/gitlab/metrics/dashboard/cache_spec.rb'
- - 'spec/lib/gitlab/null_request_store_spec.rb'
- - 'spec/lib/gitlab/safe_request_store_spec.rb'
-
# Offense count: 206
# Cop supports --auto-correct.
Style/RedundantInterpolation:
diff --git a/.rubocop_todo/database/multiple_databases.yml b/.rubocop_todo/database/multiple_databases.yml
index 69bc0b64a30..27e28128a98 100644
--- a/.rubocop_todo/database/multiple_databases.yml
+++ b/.rubocop_todo/database/multiple_databases.yml
@@ -1,13 +1,6 @@
---
Database/MultipleDatabases:
Exclude:
- - ee/lib/gitlab/geo/database_tasks.rb
- - ee/lib/gitlab/geo/geo_tasks.rb
- - ee/lib/gitlab/geo/health_check.rb
- - ee/lib/gitlab/geo/log_cursor/daemon.rb
- - ee/lib/pseudonymizer/dumper.rb
- - ee/lib/pseudonymizer/pager.rb
- - ee/spec/lib/pseudonymizer/dumper_spec.rb
- ee/spec/services/ee/merge_requests/update_service_spec.rb
- lib/backup/database.rb
- lib/backup/manager.rb
@@ -18,11 +11,7 @@ Database/MultipleDatabases:
- lib/gitlab/database/migrations/observers/query_log.rb
- lib/gitlab/database/partitioning_migration_helpers/backfill_partitioned_table.rb
- lib/gitlab/database.rb
- - lib/gitlab/gitlab_import/importer.rb
- lib/gitlab/health_checks/db_check.rb
- - lib/gitlab/import_export/base/relation_factory.rb
- - lib/gitlab/import_export/group/relation_tree_restorer.rb
- - lib/gitlab/legacy_github_import/importer.rb
- lib/gitlab/seeder.rb
- spec/db/schema_spec.rb
- spec/initializers/database_config_spec.rb
diff --git a/.rubocop_todo/gitlab/namespaced_class.yml b/.rubocop_todo/gitlab/namespaced_class.yml
index 7d0f69c9300..73f4a5deec0 100644
--- a/.rubocop_todo/gitlab/namespaced_class.yml
+++ b/.rubocop_todo/gitlab/namespaced_class.yml
@@ -496,7 +496,6 @@ Gitlab/NamespacedClass:
- app/serializers/build_trace_serializer.rb
- app/serializers/cluster_application_entity.rb
- app/serializers/cluster_entity.rb
- - app/serializers/cluster_error_entity.rb
- app/serializers/cluster_serializer.rb
- app/serializers/codequality_degradation_entity.rb
- app/serializers/codequality_reports_comparer_entity.rb
diff --git a/.rubocop_todo/graphql/argument_uniqueness.yml b/.rubocop_todo/graphql/argument_uniqueness.yml
new file mode 100644
index 00000000000..036d5d8ecdb
--- /dev/null
+++ b/.rubocop_todo/graphql/argument_uniqueness.yml
@@ -0,0 +1,4 @@
+---
+GraphQL/ArgumentUniqueness:
+ Exclude:
+ - app/graphql/resolvers/merge_requests_resolver.rb
diff --git a/.rubocop_todo/graphql/field_definitions.yml b/.rubocop_todo/graphql/field_definitions.yml
index e1245a53409..0e2399ba243 100644
--- a/.rubocop_todo/graphql/field_definitions.yml
+++ b/.rubocop_todo/graphql/field_definitions.yml
@@ -1,9 +1,4 @@
---
GraphQL/FieldDefinitions:
Exclude:
- - ee/app/graphql/types/ci/code_quality_degradation_type.rb
- - ee/app/graphql/types/epic_type.rb
- - ee/app/graphql/types/group_release_stats_type.rb
- - ee/app/graphql/types/iteration_type.rb
- - ee/app/graphql/types/requirements_management/requirement_type.rb
- ee/app/graphql/types/vulnerability_type.rb
diff --git a/.rubocop_todo/graphql/field_method.yml b/.rubocop_todo/graphql/field_method.yml
index 7c336451c41..6a05b3c23b8 100644
--- a/.rubocop_todo/graphql/field_method.yml
+++ b/.rubocop_todo/graphql/field_method.yml
@@ -1,8 +1,4 @@
---
GraphQL/FieldMethod:
Exclude:
- - app/graphql/types/ci/job_type.rb
- - app/graphql/types/merge_request_type.rb
- - app/graphql/types/metrics/dashboards/annotation_type.rb
- app/graphql/types/packages/package_details_type.rb
- - app/graphql/types/project_type.rb
diff --git a/.rubocop_todo/graphql/ordered_arguments.yml b/.rubocop_todo/graphql/ordered_arguments.yml
index def1b0085e4..1a30490e893 100644
--- a/.rubocop_todo/graphql/ordered_arguments.yml
+++ b/.rubocop_todo/graphql/ordered_arguments.yml
@@ -4,10 +4,3 @@ GraphQL/OrderedArguments:
- app/graphql/resolvers/base_issues_resolver.rb
- app/graphql/resolvers/design_management/designs_resolver.rb
- app/graphql/resolvers/design_management/version/design_at_version_resolver.rb
- - app/graphql/types/commit_action_type.rb
- - app/graphql/types/diff_paths_input_type.rb
- - app/graphql/types/issues/negated_issue_filter_input_type.rb
- - app/graphql/types/jira_users_mapping_input_type.rb
- - app/graphql/types/notes/diff_image_position_input_type.rb
- - app/graphql/types/notes/diff_position_base_input_type.rb
- - app/graphql/types/notes/diff_position_input_type.rb
diff --git a/.rubocop_todo/graphql/ordered_fields.yml b/.rubocop_todo/graphql/ordered_fields.yml
index 4aa6a2e7793..b6ddd018f4e 100644
--- a/.rubocop_todo/graphql/ordered_fields.yml
+++ b/.rubocop_todo/graphql/ordered_fields.yml
@@ -1,16 +1,6 @@
---
GraphQL/OrderedFields:
Exclude:
- - app/graphql/types/board_list_type.rb
- - app/graphql/types/ci/analytics_type.rb
- - app/graphql/types/ci/ci_cd_setting_type.rb
- - app/graphql/types/ci/config/group_type.rb
- - app/graphql/types/ci/config/job_type.rb
- - app/graphql/types/ci/config/stage_type.rb
- - app/graphql/types/ci/detailed_status_type.rb
- - app/graphql/types/ci/group_type.rb
- - app/graphql/types/ci/job_type.rb
- - app/graphql/types/ci/runner_architecture_type.rb
- app/graphql/types/ci/runner_platform_type.rb
- app/graphql/types/ci/runner_type.rb
- app/graphql/types/ci/stage_type.rb
@@ -32,14 +22,6 @@ GraphQL/OrderedFields:
- app/graphql/types/error_tracking/sentry_error_frequency_type.rb
- app/graphql/types/error_tracking/sentry_error_stack_trace_context_type.rb
- app/graphql/types/error_tracking/sentry_error_stack_trace_entry_type.rb
- - app/graphql/types/error_tracking/sentry_error_stack_trace_type.rb
- - app/graphql/types/error_tracking/sentry_error_type.rb
- - app/graphql/types/evidence_type.rb
- - app/graphql/types/grafana_integration_type.rb
- - app/graphql/types/issue_type.rb
- - app/graphql/types/jira_import_type.rb
- - app/graphql/types/jira_user_type.rb
- - app/graphql/types/label_type.rb
- app/graphql/types/merge_request_type.rb
- app/graphql/types/metadata/kas_type.rb
- app/graphql/types/metadata_type.rb
@@ -48,14 +30,6 @@ GraphQL/OrderedFields:
- app/graphql/types/notes/diff_position_type.rb
- app/graphql/types/notes/discussion_type.rb
- app/graphql/types/notes/note_type.rb
- - app/graphql/types/packages/composer/json_type.rb
- - app/graphql/types/packages/composer/metadatum_type.rb
- - app/graphql/types/packages/conan/file_metadatum_type.rb
- - app/graphql/types/packages/conan/metadatum_type.rb
- - app/graphql/types/packages/helm/dependency_type.rb
- - app/graphql/types/packages/helm/maintainer_type.rb
- - app/graphql/types/packages/helm/metadata_type.rb
- - app/graphql/types/packages/maven/metadatum_type.rb
- app/graphql/types/packages/nuget/metadatum_type.rb
- app/graphql/types/packages/package_dependency_link_type.rb
- app/graphql/types/packages/package_file_type.rb
@@ -71,14 +45,6 @@ GraphQL/OrderedFields:
- app/graphql/types/root_storage_statistics_type.rb
- app/graphql/types/task_completion_status.rb
- app/graphql/types/tree/blob_type.rb
- - app/graphql/types/tree/submodule_type.rb
- - app/graphql/types/tree/tree_entry_type.rb
- - app/graphql/types/user_callout_type.rb
- - app/graphql/types/user_status_type.rb
- - ee/app/graphql/types/analytics/devops_adoption/snapshot_type.rb
- - ee/app/graphql/types/epic_descendant_count_type.rb
- - ee/app/graphql/types/epic_descendant_weight_sum_type.rb
- - ee/app/graphql/types/epic_health_status_type.rb
- ee/app/graphql/types/epic_type.rb
- ee/app/graphql/types/geo/geo_node_type.rb
- ee/app/graphql/types/requirements_management/requirement_states_count_type.rb
diff --git a/.rubocop_todo/graphql/unused_argument.yml b/.rubocop_todo/graphql/unused_argument.yml
new file mode 100644
index 00000000000..c55d8551591
--- /dev/null
+++ b/.rubocop_todo/graphql/unused_argument.yml
@@ -0,0 +1,5 @@
+---
+GraphQL/UnusedArgument:
+ Exclude:
+ - app/graphql/mutations/jira_import/start.rb
+ - app/graphql/resolvers/packages_base_resolver.rb
diff --git a/.rubocop_todo/rails/include_url_helper.yml b/.rubocop_todo/rails/include_url_helper.yml
deleted file mode 100644
index 6a34c58ecf6..00000000000
--- a/.rubocop_todo/rails/include_url_helper.yml
+++ /dev/null
@@ -1,37 +0,0 @@
----
-Rails/IncludeUrlHelper:
- Exclude:
- - app/models/integrations/asana.rb
- - app/models/integrations/bamboo.rb
- - app/models/integrations/bugzilla.rb
- - app/models/integrations/campfire.rb
- - app/models/integrations/confluence.rb
- - app/models/integrations/custom_issue_tracker.rb
- - app/models/integrations/discord.rb
- - app/models/integrations/ewm.rb
- - app/models/integrations/external_wiki.rb
- - app/models/integrations/flowdock.rb
- - app/models/integrations/hangouts_chat.rb
- - app/models/integrations/irker.rb
- - app/models/integrations/jenkins.rb
- - app/models/integrations/mattermost.rb
- - app/models/integrations/pivotaltracker.rb
- - app/models/integrations/redmine.rb
- - app/models/integrations/webex_teams.rb
- - app/models/integrations/youtrack.rb
- - app/presenters/alert_management/alert_presenter.rb
- - app/presenters/environment_presenter.rb
- - app/presenters/gitlab/blame_presenter.rb
- - app/presenters/merge_request_presenter.rb
- - app/presenters/project_presenter.rb
- - app/presenters/release_presenter.rb
- - app/presenters/releases/evidence_presenter.rb
- - ee/app/helpers/license_helper.rb
- - ee/app/models/integrations/github.rb
- - ee/spec/helpers/ee/projects/security/configuration_helper_spec.rb
- - ee/spec/lib/banzai/filter/cross_project_issuable_information_filter_spec.rb
- - spec/helpers/merge_requests_helper_spec.rb
- - spec/helpers/nav/top_nav_helper_spec.rb
- - spec/helpers/notify_helper_spec.rb
- - spec/lib/banzai/filter/reference_redactor_filter_spec.rb
- - spec/lib/banzai/reference_redactor_spec.rb
diff --git a/.rubocop_todo/rails/save_bang.yml b/.rubocop_todo/rails/save_bang.yml
deleted file mode 100644
index e1698a83682..00000000000
--- a/.rubocop_todo/rails/save_bang.yml
+++ /dev/null
@@ -1,4 +0,0 @@
----
-Rails/SaveBang:
- Exclude:
- - ee/spec/lib/analytics/merge_request_metrics_calculator_spec.rb
diff --git a/.rubocop_todo/rspec/instance_variable.yml b/.rubocop_todo/rspec/instance_variable.yml
new file mode 100644
index 00000000000..6c147d22808
--- /dev/null
+++ b/.rubocop_todo/rspec/instance_variable.yml
@@ -0,0 +1,203 @@
+---
+RSpec/InstanceVariable:
+ Exclude:
+ - ee/spec/controllers/admin/application_settings_controller_spec.rb
+ - ee/spec/controllers/admin/geo/settings_controller_spec.rb
+ - ee/spec/controllers/ee/sessions_controller_spec.rb
+ - ee/spec/controllers/groups/groups_controller_spec.rb
+ - ee/spec/controllers/groups/omniauth_callbacks_controller_spec.rb
+ - ee/spec/controllers/passwords_controller_spec.rb
+ - ee/spec/features/markdown/markdown_spec.rb
+ - ee/spec/frontend/fixtures/dast_profiles.rb
+ - ee/spec/frontend/fixtures/epic.rb
+ - ee/spec/graphql/types/vulnerability_request_response_header_type_spec.rb
+ - ee/spec/graphql/types/vulnerability_request_type_spec.rb
+ - ee/spec/graphql/types/vulnerability_response_type_spec.rb
+ - ee/spec/helpers/ee/issuables_helper_spec.rb
+ - ee/spec/helpers/ee/namespace_storage_limit_alert_helper_spec.rb
+ - ee/spec/helpers/ee/wiki_helper_spec.rb
+ - ee/spec/helpers/notes_helper_spec.rb
+ - ee/spec/helpers/search_helper_spec.rb
+ - ee/spec/lib/ee/gitlab/elastic/helper_spec.rb
+ - ee/spec/lib/gitlab/elastic/search_results_spec.rb
+ - ee/spec/lib/gitlab/reference_extractor_spec.rb
+ - ee/spec/services/ee/merge_requests/update_service_spec.rb
+ - ee/spec/services/ee/notification_service_spec.rb
+ - ee/spec/services/ee/users/create_service_spec.rb
+ - ee/spec/services/ee/users/destroy_service_spec.rb
+ - ee/spec/services/geo/metrics_update_service_spec.rb
+ - ee/spec/services/groups/create_service_spec.rb
+ - ee/spec/services/groups/participants_service_spec.rb
+ - ee/spec/services/projects/create_from_template_service_spec.rb
+ - ee/spec/services/projects/create_service_spec.rb
+ - ee/spec/support/shared_examples/views/subscription_shared_examples.rb
+ - ee/spec/tasks/geo_rake_spec.rb
+ - ee/spec/views/projects/security/corpus_management/show.html.haml_spec.rb
+ - ee/spec/views/projects/security/dast_profiles/show.html.haml_spec.rb
+ - ee/spec/views/projects/security/dast_scanner_profiles/new.html.haml_spec.rb
+ - ee/spec/views/projects/security/dast_site_profiles/new.html.haml_spec.rb
+ - qa/qa/specs/features/api/1_manage/import_large_github_repo_spec.rb
+ - qa/qa/specs/features/api/1_manage/project_access_token_spec.rb
+ - qa/qa/specs/features/api/1_manage/user_access_termination_spec.rb
+ - qa/qa/specs/features/browser_ui/1_manage/login/2fa_recovery_spec.rb
+ - qa/qa/specs/features/browser_ui/1_manage/login/log_in_with_2fa_spec.rb
+ - qa/qa/specs/features/browser_ui/1_manage/login/register_spec.rb
+ - qa/qa/specs/features/browser_ui/1_manage/project/dashboard_images_spec.rb
+ - qa/qa/specs/features/browser_ui/1_manage/project/invite_group_to_project_spec.rb
+ - qa/qa/specs/features/browser_ui/1_manage/project/protected_tags_spec.rb
+ - qa/qa/specs/features/browser_ui/3_create/repository/push_over_http_file_size_spec.rb
+ - qa/qa/specs/features/browser_ui/3_create/repository/push_over_ssh_spec.rb
+ - qa/qa/specs/features/browser_ui/3_create/repository/user_views_commit_diff_patch_spec.rb
+ - qa/qa/specs/features/browser_ui/3_create/web_ide/add_file_template_spec.rb
+ - qa/qa/specs/features/browser_ui/3_create/web_ide/link_to_line_in_web_ide_spec.rb
+ - qa/qa/specs/features/browser_ui/3_create/web_ide/web_terminal_spec.rb
+ - qa/qa/specs/features/ee/api/1_manage/user/minimal_access_user_spec.rb
+ - qa/qa/specs/features/ee/browser_ui/12_geo/attachment_replication_spec.rb
+ - qa/qa/specs/features/ee/browser_ui/12_geo/geo_replication_ci_job_log_artifacts_spec.rb
+ - qa/qa/specs/features/ee/browser_ui/12_geo/rename_replication_spec.rb
+ - qa/qa/specs/features/ee/browser_ui/13_secure/create_merge_request_with_secure_spec.rb
+ - qa/qa/specs/features/ee/browser_ui/13_secure/license_compliance_spec.rb
+ - qa/qa/specs/features/ee/browser_ui/13_secure/merge_request_license_widget_spec.rb
+ - qa/qa/specs/features/ee/browser_ui/13_secure/project_security_dashboard_spec.rb
+ - qa/qa/specs/features/ee/browser_ui/13_secure/security_reports_spec.rb
+ - qa/qa/specs/features/ee/browser_ui/13_secure/vulnerability_management_spec.rb
+ - qa/qa/specs/features/ee/browser_ui/1_manage/group/group_audit_logs_1_spec.rb
+ - qa/qa/specs/features/ee/browser_ui/1_manage/group/group_file_template_spec.rb
+ - qa/qa/specs/features/ee/browser_ui/1_manage/group/group_ldap_sync_spec.rb
+ - qa/qa/specs/features/ee/browser_ui/1_manage/group/group_saml_non_enforced_sso_spec.rb
+ - qa/qa/specs/features/ee/browser_ui/1_manage/group/restrict_by_ip_address_spec.rb
+ - qa/qa/specs/features/ee/browser_ui/1_manage/project/project_templates_spec.rb
+ - qa/qa/specs/features/ee/browser_ui/2_plan/integrations/jira_issues_list_spec.rb
+ - qa/qa/specs/features/ee/browser_ui/2_plan/issue_boards/project_issue_boards_spec.rb
+ - qa/qa/specs/features/ee/browser_ui/2_plan/multiple_assignees_for_issues/more_than_four_assignees_spec.rb
+ - qa/qa/specs/features/ee/browser_ui/3_create/repository/code_owners_spec.rb
+ - qa/qa/specs/features/ee/browser_ui/3_create/repository/push_rules_spec.rb
+ - qa/qa/specs/features/ee/browser_ui/4_verify/cancelling_merge_request_in_merge_train_spec.rb
+ - qa/spec/support/repeater_spec.rb
+ - spec/commands/metrics_server/metrics_server_spec.rb
+ - spec/controllers/admin/clusters_controller_spec.rb
+ - spec/controllers/admin/topics/avatars_controller_spec.rb
+ - spec/controllers/concerns/renders_commits_spec.rb
+ - spec/controllers/confirmations_controller_spec.rb
+ - spec/controllers/groups/avatars_controller_spec.rb
+ - spec/controllers/groups/clusters_controller_spec.rb
+ - spec/controllers/import/bitbucket_controller_spec.rb
+ - spec/controllers/import/bitbucket_server_controller_spec.rb
+ - spec/controllers/metrics_controller_spec.rb
+ - spec/controllers/omniauth_callbacks_controller_spec.rb
+ - spec/controllers/passwords_controller_spec.rb
+ - spec/controllers/profiles/avatars_controller_spec.rb
+ - spec/controllers/projects/clusters_controller_spec.rb
+ - spec/controllers/sessions_controller_spec.rb
+ - spec/features/admin/admin_runners_spec.rb
+ - spec/features/calendar_spec.rb
+ - spec/features/issues/user_filters_issues_spec.rb
+ - spec/features/markdown/copy_as_gfm_spec.rb
+ - spec/features/markdown/gitlab_flavored_markdown_spec.rb
+ - spec/features/markdown/keyboard_shortcuts_spec.rb
+ - spec/features/markdown/markdown_spec.rb
+ - spec/features/merge_request/batch_comments_spec.rb
+ - spec/features/merge_request/user_sees_pipelines_spec.rb
+ - spec/features/merge_requests/user_lists_merge_requests_spec.rb
+ - spec/features/projects/diffs/diff_show_spec.rb
+ - spec/features/triggers_spec.rb
+ - spec/features/u2f_spec.rb
+ - spec/finders/admin/plans_finder_spec.rb
+ - spec/finders/groups_finder_spec.rb
+ - spec/finders/issues_finder_spec.rb
+ - spec/frontend/fixtures/listbox.rb
+ - spec/frontend/fixtures/raw.rb
+ - spec/frontend/fixtures/sessions.rb
+ - spec/frontend/fixtures/tabs.rb
+ - spec/frontend/fixtures/timezones.rb
+ - spec/frontend/fixtures/u2f.rb
+ - spec/frontend/fixtures/webauthn.rb
+ - spec/helpers/application_helper_spec.rb
+ - spec/helpers/award_emoji_helper_spec.rb
+ - spec/helpers/issuables_description_templates_helper_spec.rb
+ - spec/helpers/issuables_helper_spec.rb
+ - spec/helpers/notes_helper_spec.rb
+ - spec/helpers/projects_helper_spec.rb
+ - spec/helpers/search_helper_spec.rb
+ - spec/helpers/tree_helper_spec.rb
+ - spec/helpers/wiki_helper_spec.rb
+ - spec/lib/api/helpers/authentication_spec.rb
+ - spec/lib/banzai/filter/asset_proxy_filter_spec.rb
+ - spec/lib/extracts_path_spec.rb
+ - spec/lib/extracts_ref_spec.rb
+ - spec/lib/gitlab/auth/auth_finders_spec.rb
+ - spec/lib/gitlab/auth/ldap/person_spec.rb
+ - spec/lib/gitlab/background_migration/recalculate_vulnerabilities_occurrences_uuid_spec.rb
+ - spec/lib/gitlab/bitbucket_import/importer_spec.rb
+ - spec/lib/gitlab/chat_name_token_spec.rb
+ - spec/lib/gitlab/ci/lint_spec.rb
+ - spec/lib/gitlab/ci/status/composite_spec.rb
+ - spec/lib/gitlab/contributions_calendar_spec.rb
+ - spec/lib/gitlab/diff/parser_spec.rb
+ - spec/lib/gitlab/email/hook/smime_signature_interceptor_spec.rb
+ - spec/lib/gitlab/git/commit_spec.rb
+ - spec/lib/gitlab/git/diff_collection_spec.rb
+ - spec/lib/gitlab/git/diff_spec.rb
+ - spec/lib/gitlab/git/repository_spec.rb
+ - spec/lib/gitlab/http_spec.rb
+ - spec/lib/gitlab/import_export/group/legacy_tree_restorer_spec.rb
+ - spec/lib/gitlab/import_export/group/tree_restorer_spec.rb
+ - spec/lib/gitlab/import_export/project/tree_restorer_spec.rb
+ - spec/lib/gitlab/patch/prependable_spec.rb
+ - spec/lib/gitlab/popen_spec.rb
+ - spec/lib/gitlab/project_transfer_spec.rb
+ - spec/lib/gitlab/reference_extractor_spec.rb
+ - spec/lib/gitlab/tcp_checker_spec.rb
+ - spec/lib/gitlab/user_access_spec.rb
+ - spec/lib/gitlab/version_info_spec.rb
+ - spec/lib/gitlab/x509/certificate_spec.rb
+ - spec/mailers/emails/issues_spec.rb
+ - spec/migrations/20220106163326_add_has_issues_on_vulnerability_reads_trigger_spec.rb
+ - spec/migrations/rename_services_to_integrations_spec.rb
+ - spec/migrations/replace_external_wiki_triggers_spec.rb
+ - spec/models/group_spec.rb
+ - spec/models/integrations/assembla_spec.rb
+ - spec/models/integrations/campfire_spec.rb
+ - spec/models/integrations/irker_spec.rb
+ - spec/models/member_spec.rb
+ - spec/models/members/project_member_spec.rb
+ - spec/models/namespace_spec.rb
+ - spec/models/note_spec.rb
+ - spec/models/postgresql/replication_slot_spec.rb
+ - spec/models/project_spec.rb
+ - spec/models/user_spec.rb
+ - spec/models/users/in_product_marketing_email_spec.rb
+ - spec/rack_servers/puma_spec.rb
+ - spec/requests/api/admin/plan_limits_spec.rb
+ - spec/requests/api/merge_requests_spec.rb
+ - spec/requests/api/users_spec.rb
+ - spec/requests/git_http_spec.rb
+ - spec/requests/openid_connect_spec.rb
+ - spec/requests/projects/issues/discussions_spec.rb
+ - spec/rubocop/cop/migration/update_column_in_batches_spec.rb
+ - spec/serializers/pipeline_serializer_spec.rb
+ - spec/services/ci/create_pipeline_service/logger_spec.rb
+ - spec/services/ci/process_sync_events_service_spec.rb
+ - spec/services/labels/update_service_spec.rb
+ - spec/services/members/destroy_service_spec.rb
+ - spec/services/merge_requests/close_service_spec.rb
+ - spec/services/merge_requests/refresh_service_spec.rb
+ - spec/services/merge_requests/reopen_service_spec.rb
+ - spec/services/merge_requests/update_service_spec.rb
+ - spec/services/milestones/create_service_spec.rb
+ - spec/services/notes/post_process_service_spec.rb
+ - spec/services/notes/update_service_spec.rb
+ - spec/services/notification_service_spec.rb
+ - spec/services/pages/zip_directory_service_spec.rb
+ - spec/services/projects/create_from_template_service_spec.rb
+ - spec/services/projects/download_service_spec.rb
+ - spec/services/projects/fork_service_spec.rb
+ - spec/services/upload_service_spec.rb
+ - spec/support/shared_contexts/controllers/ldap_omniauth_callbacks_controller_shared_context.rb
+ - spec/support/shared_contexts/email_shared_context.rb
+ - spec/support/shared_examples/features/wiki/user_views_wiki_empty_shared_examples.rb
+ - spec/support/shared_examples/path_extraction_shared_examples.rb
+ - spec/support/shared_examples/requests/api/notes_shared_examples.rb
+ - spec/support_specs/helpers/stub_feature_flags_spec.rb
+ - spec/views/search/_results.html.haml_spec.rb
+ - spec/workers/emails_on_push_worker_spec.rb
diff --git a/.rubocop_todo/rspec/timecop_travel.yml b/.rubocop_todo/rspec/timecop_travel.yml
index 29044236deb..32133f6e55c 100644
--- a/.rubocop_todo/rspec/timecop_travel.yml
+++ b/.rubocop_todo/rspec/timecop_travel.yml
@@ -7,15 +7,5 @@ RSpec/TimecopTravel:
- ee/spec/lib/gitlab/geo/log_cursor/daemon_spec.rb
- ee/spec/models/broadcast_message_spec.rb
- ee/spec/models/burndown_spec.rb
- - qa/spec/support/repeater_spec.rb
- - spec/features/users/terms_spec.rb
- - spec/lib/feature_spec.rb
- - spec/models/broadcast_message_spec.rb
- - spec/models/concerns/issuable_spec.rb
- - spec/requests/api/ci/runner/jobs_trace_spec.rb
- - spec/requests/api/issues/put_projects_issues_spec.rb
- - spec/support/shared_contexts/cache_allowed_users_in_namespace_shared_context.rb
- - spec/support/shared_examples/requests/api/time_tracking_shared_examples.rb
- - spec/support/shared_examples/workers/concerns/reenqueuer_shared_examples.rb
- spec/workers/concerns/reenqueuer_spec.rb
- - spec/lib/gitlab/analytics/cycle_analytics/median_spec.rb
+ - qa/spec/support/repeater_spec.rb
diff --git a/.rubocop_todo/rspec/verified_doubles.yml b/.rubocop_todo/rspec/verified_doubles.yml
new file mode 100644
index 00000000000..7cffea49d3a
--- /dev/null
+++ b/.rubocop_todo/rspec/verified_doubles.yml
@@ -0,0 +1,1206 @@
+---
+RSpec/VerifiedDoubles:
+ Exclude:
+ - ee/spec/controllers/boards/issues_controller_spec.rb
+ - ee/spec/controllers/concerns/ee/routable_actions/sso_enforcement_redirect_spec.rb
+ - ee/spec/controllers/groups/clusters_controller_spec.rb
+ - ee/spec/controllers/groups/sso_controller_spec.rb
+ - ee/spec/controllers/oauth/geo_auth_controller_spec.rb
+ - ee/spec/controllers/projects/clusters_controller_spec.rb
+ - ee/spec/controllers/projects/security/network_policies_controller_spec.rb
+ - ee/spec/db/production/license_spec.rb
+ - ee/spec/elastic/migrate/20210510113500_delete_merge_requests_from_original_index_spec.rb
+ - ee/spec/elastic/migrate/20210510143200_delete_notes_from_original_index_spec.rb
+ - ee/spec/features/admin/groups/admin_subscription_alerts_spec.rb
+ - ee/spec/features/billings/billing_plans_spec.rb
+ - ee/spec/features/merge_trains/two_merge_requests_on_train_spec.rb
+ - ee/spec/features/profiles/account_spec.rb
+ - ee/spec/finders/license_template_finder_spec.rb
+ - ee/spec/finders/projects/integrations/jira/issues_finder_spec.rb
+ - ee/spec/finders/security/pipeline_vulnerabilities_finder_spec.rb
+ - ee/spec/finders/template_finder_spec.rb
+ - ee/spec/graphql/ee/resolvers/board_lists_resolver_spec.rb
+ - ee/spec/graphql/mutations/dast_scanner_profiles/create_spec.rb
+ - ee/spec/graphql/mutations/dast_site_profiles/create_spec.rb
+ - ee/spec/graphql/mutations/dast_site_profiles/delete_spec.rb
+ - ee/spec/graphql/mutations/dast_site_profiles/update_spec.rb
+ - ee/spec/graphql/mutations/incident_management/oncall_rotation/create_spec.rb
+ - ee/spec/graphql/mutations/issues/promote_to_epic_spec.rb
+ - ee/spec/graphql/mutations/issues/set_epic_spec.rb
+ - ee/spec/graphql/mutations/merge_requests/accept_spec.rb
+ - ee/spec/graphql/mutations/vulnerabilities/create_external_issue_link_spec.rb
+ - ee/spec/graphql/mutations/vulnerabilities/destroy_external_issue_link_spec.rb
+ - ee/spec/graphql/resolvers/board_groupings/epics_resolvers_spec.rb
+ - ee/spec/graphql/resolvers/external_issue_resolver_spec.rb
+ - ee/spec/graphql/resolvers/security_report_summary_resolver_spec.rb
+ - ee/spec/graphql/resolvers/vulnerabilities/details_resolver_spec.rb
+ - ee/spec/graphql/types/network_policy_type_spec.rb
+ - ee/spec/graphql/types/security/training_type_spec.rb
+ - ee/spec/helpers/billing_plans_helper_spec.rb
+ - ee/spec/helpers/ee/ci/runners_helper_spec.rb
+ - ee/spec/helpers/ee/integrations_helper_spec.rb
+ - ee/spec/helpers/ee/subscribable_banner_helper_spec.rb
+ - ee/spec/helpers/ee/trial_helper_spec.rb
+ - ee/spec/helpers/ee/trial_registration_helper_spec.rb
+ - ee/spec/helpers/kerberos_spnego_helper_spec.rb
+ - ee/spec/helpers/license_helper_spec.rb
+ - ee/spec/helpers/roadmaps_helper_spec.rb
+ - ee/spec/helpers/routing/pseudonymization_helper_spec.rb
+ - ee/spec/helpers/subscriptions_helper_spec.rb
+ - ee/spec/helpers/timeboxes_helper_spec.rb
+ - ee/spec/helpers/vulnerabilities_helper_spec.rb
+ - ee/spec/lib/ee/backup/repositories_spec.rb
+ - ee/spec/lib/ee/gitlab/background_migration/migrate_approver_to_approval_rules_in_batch_spec.rb
+ - ee/spec/lib/ee/gitlab/background_migration/migrate_approver_to_approval_rules_spec.rb
+ - ee/spec/lib/ee/gitlab/ci/matching/runner_matcher_spec.rb
+ - ee/spec/lib/ee/gitlab/ci/pipeline/quota/size_spec.rb
+ - ee/spec/lib/ee/gitlab/etag_caching/router/rails_spec.rb
+ - ee/spec/lib/ee/gitlab/gon_helper_spec.rb
+ - ee/spec/lib/elastic/latest/config_shared_examples.rb
+ - ee/spec/lib/elastic/latest/git_instance_proxy_spec.rb
+ - ee/spec/lib/elastic/migration_spec.rb
+ - ee/spec/lib/elastic/multi_version_class_proxy_spec.rb
+ - ee/spec/lib/elastic/multi_version_instance_proxy_spec.rb
+ - ee/spec/lib/gitlab/audit/target_spec.rb
+ - ee/spec/lib/gitlab/auth/group_saml/response_check_spec.rb
+ - ee/spec/lib/gitlab/auth/group_saml/token_actor_spec.rb
+ - ee/spec/lib/gitlab/auth/otp/session_enforcer_spec.rb
+ - ee/spec/lib/gitlab/authority_analyzer_spec.rb
+ - ee/spec/lib/gitlab/cache_spec.rb
+ - ee/spec/lib/gitlab/ci/pipeline/chain/limit/activity_spec.rb
+ - ee/spec/lib/gitlab/ci/pipeline/chain/limit/job_activity_spec.rb
+ - ee/spec/lib/gitlab/ci/pipeline/chain/limit/size_spec.rb
+ - ee/spec/lib/gitlab/code_owners/groups_loader_spec.rb
+ - ee/spec/lib/gitlab/code_owners/users_loader_spec.rb
+ - ee/spec/lib/gitlab/custom_file_templates_spec.rb
+ - ee/spec/lib/gitlab/elastic/client_spec.rb
+ - ee/spec/lib/gitlab/elastic/search_results_spec.rb
+ - ee/spec/lib/gitlab/expiring_subscription_message_spec.rb
+ - ee/spec/lib/gitlab/geo/git_ssh_proxy_spec.rb
+ - ee/spec/lib/gitlab/geo/log_cursor/lease_spec.rb
+ - ee/spec/lib/gitlab/geo/oauth/logout_token_spec.rb
+ - ee/spec/lib/gitlab/geo/oauth/session_spec.rb
+ - ee/spec/lib/gitlab/geo/replication/job_artifact_retriever_spec.rb
+ - ee/spec/lib/gitlab/geo/replication/job_artifact_transfer_spec.rb
+ - ee/spec/lib/gitlab/geo/replicator_spec.rb
+ - ee/spec/lib/gitlab/geo_spec.rb
+ - ee/spec/lib/gitlab/git_access_spec.rb
+ - ee/spec/lib/gitlab/graphql/aggregations/issues/lazy_block_aggregate_spec.rb
+ - ee/spec/lib/gitlab/import_export/group/relation_factory_spec.rb
+ - ee/spec/lib/gitlab/middleware/ip_restrictor_spec.rb
+ - ee/spec/lib/gitlab/patch/legacy_database_config_spec.rb
+ - ee/spec/lib/gitlab/prometheus/queries/cluster_query_spec.rb
+ - ee/spec/lib/gitlab/prometheus/queries/packet_flow_metrics_query_spec.rb
+ - ee/spec/lib/gitlab/prometheus/queries/packet_flow_query_spec.rb
+ - ee/spec/lib/gitlab/subscription_portal/clients/rest_spec.rb
+ - ee/spec/lib/sidebars/groups/menus/analytics_menu_spec.rb
+ - ee/spec/lib/system_check/app/elasticsearch_check_spec.rb
+ - ee/spec/lib/system_check/geo/geo_database_configured_check_spec.rb
+ - ee/spec/models/app_sec/fuzzing/api/ci_configuration_spec.rb
+ - ee/spec/models/approvable_spec.rb
+ - ee/spec/models/concerns/ee/sha_attribute_spec.rb
+ - ee/spec/models/concerns/geo/verification_state_spec.rb
+ - ee/spec/models/ee/ci/job_artifact_spec.rb
+ - ee/spec/models/ee/user_spec.rb
+ - ee/spec/models/elastic/index_setting_spec.rb
+ - ee/spec/models/geo/project_registry_spec.rb
+ - ee/spec/models/geo/secondary_usage_data_spec.rb
+ - ee/spec/models/geo_node_status_spec.rb
+ - ee/spec/models/integrations/github/status_message_spec.rb
+ - ee/spec/models/integrations/github_spec.rb
+ - ee/spec/models/project_spec.rb
+ - ee/spec/models/push_rule_spec.rb
+ - ee/spec/presenters/audit_event_presenter_spec.rb
+ - ee/spec/presenters/group_member_presenter_spec.rb
+ - ee/spec/presenters/merge_request_approver_presenter_spec.rb
+ - ee/spec/presenters/project_member_presenter_spec.rb
+ - ee/spec/requests/api/alert_management_alerts_spec.rb
+ - ee/spec/requests/api/geo_spec.rb
+ - ee/spec/requests/api/graphql/mutations/dast_site_profiles/delete_spec.rb
+ - ee/spec/requests/api/internal/base_spec.rb
+ - ee/spec/requests/api/ldap_spec.rb
+ - ee/spec/requests/api/visual_review_discussions_spec.rb
+ - ee/spec/requests/api/vulnerability_findings_spec.rb
+ - ee/spec/requests/callout_spec.rb
+ - ee/spec/requests/rack_attack_spec.rb
+ - ee/spec/serializers/blocking_merge_request_entity_spec.rb
+ - ee/spec/serializers/clusters/environment_entity_spec.rb
+ - ee/spec/serializers/dashboard_operations_project_entity_spec.rb
+ - ee/spec/serializers/dependency_entity_spec.rb
+ - ee/spec/serializers/ee/admin/user_entity_spec.rb
+ - ee/spec/serializers/ee/build_details_entity_spec.rb
+ - ee/spec/serializers/ee/ci/job_entity_spec.rb
+ - ee/spec/serializers/ee/ci/pipeline_entity_spec.rb
+ - ee/spec/serializers/ee/group_child_entity_spec.rb
+ - ee/spec/serializers/ee/issue_board_entity_spec.rb
+ - ee/spec/serializers/ee/issue_entity_spec.rb
+ - ee/spec/serializers/ee/issue_sidebar_extras_entity_spec.rb
+ - ee/spec/serializers/ee/merge_request_poll_cached_widget_entity_spec.rb
+ - ee/spec/serializers/ee/note_entity_spec.rb
+ - ee/spec/serializers/environment_entity_spec.rb
+ - ee/spec/serializers/epic_entity_spec.rb
+ - ee/spec/serializers/epic_note_entity_spec.rb
+ - ee/spec/serializers/integrations/jira_serializers/issue_detail_entity_spec.rb
+ - ee/spec/serializers/integrations/jira_serializers/issue_entity_spec.rb
+ - ee/spec/serializers/issuable_sidebar_extras_entity_spec.rb
+ - ee/spec/serializers/issues/linked_issue_feature_flag_entity_spec.rb
+ - ee/spec/serializers/linked_feature_flag_issue_entity_spec.rb
+ - ee/spec/serializers/merge_request_compliance_entity_spec.rb
+ - ee/spec/serializers/merge_request_poll_widget_entity_spec.rb
+ - ee/spec/serializers/merge_request_sidebar_basic_entity_spec.rb
+ - ee/spec/serializers/merge_request_widget_entity_spec.rb
+ - ee/spec/serializers/service_field_entity_spec.rb
+ - ee/spec/serializers/test_reports_comparer_serializer_spec.rb
+ - ee/spec/serializers/user_analytics_entity_spec.rb
+ - ee/spec/serializers/vulnerabilities/feedback_entity_spec.rb
+ - ee/spec/serializers/vulnerabilities/finding_entity_spec.rb
+ - ee/spec/serializers/vulnerabilities/finding_reports_comparer_entity_spec.rb
+ - ee/spec/serializers/vulnerabilities/finding_serializer_spec.rb
+ - ee/spec/serializers/vulnerability_note_entity_spec.rb
+ - ee/spec/services/alert_management/extract_alert_payload_fields_service_spec.rb
+ - ee/spec/services/app_sec/dast/scans/create_service_spec.rb
+ - ee/spec/services/app_sec/dast/site_profiles/update_service_spec.rb
+ - ee/spec/services/app_sec/fuzzing/api/ci_configuration_create_service_spec.rb
+ - ee/spec/services/ci/create_pipeline_service/dast_configuration_spec.rb
+ - ee/spec/services/ci/minutes/track_live_consumption_service_spec.rb
+ - ee/spec/services/ci/minutes/update_project_and_namespace_usage_service_spec.rb
+ - ee/spec/services/ci/pipeline_creation/drop_not_runnable_builds_service_spec.rb
+ - ee/spec/services/ci/pipeline_creation/start_pipeline_service_spec.rb
+ - ee/spec/services/dashboard/operations/list_service_spec.rb
+ - ee/spec/services/dashboard/projects/create_service_spec.rb
+ - ee/spec/services/ee/ci/job_artifacts/destroy_all_expired_service_spec.rb
+ - ee/spec/services/ee/ci/job_artifacts/destroy_batch_service_spec.rb
+ - ee/spec/services/ee/issues/create_service_spec.rb
+ - ee/spec/services/ee/issues/update_service_spec.rb
+ - ee/spec/services/ee/merge_requests/base_service_spec.rb
+ - ee/spec/services/ee/merge_requests/post_merge_service_spec.rb
+ - ee/spec/services/ee/merge_requests/refresh_service_spec.rb
+ - ee/spec/services/ee/notification_service_spec.rb
+ - ee/spec/services/ee/post_receive_service_spec.rb
+ - ee/spec/services/ee/service_ping/build_payload_service_spec.rb
+ - ee/spec/services/ee/service_ping/permit_data_categories_service_spec.rb
+ - ee/spec/services/ee/service_ping/service_ping_settings_spec.rb
+ - ee/spec/services/geo/blob_download_service_spec.rb
+ - ee/spec/services/geo/file_download_service_spec.rb
+ - ee/spec/services/geo/graphql_request_service_spec.rb
+ - ee/spec/services/geo/node_status_request_service_spec.rb
+ - ee/spec/services/geo/replication_toggle_request_service_spec.rb
+ - ee/spec/services/geo/repository_verification_primary_service_spec.rb
+ - ee/spec/services/gitlab_subscriptions/fetch_subscription_plans_service_spec.rb
+ - ee/spec/services/group_saml/group_managed_accounts/clean_up_members_service_spec.rb
+ - ee/spec/services/group_saml/sign_up_service_spec.rb
+ - ee/spec/services/groups/update_repository_storage_service_spec.rb
+ - ee/spec/services/ide/schemas_config_service_spec.rb
+ - ee/spec/services/incident_management/oncall_schedules/update_service_spec.rb
+ - ee/spec/services/incident_management/pending_escalations/process_service_spec.rb
+ - ee/spec/services/merge_requests/approval_service_spec.rb
+ - ee/spec/services/merge_requests/build_service_spec.rb
+ - ee/spec/services/merge_requests/reset_approvals_service_spec.rb
+ - ee/spec/services/namespaces/in_product_marketing_emails_service_spec.rb
+ - ee/spec/services/network_policies/delete_resource_service_spec.rb
+ - ee/spec/services/network_policies/deploy_resource_service_spec.rb
+ - ee/spec/services/network_policies/find_resource_service_spec.rb
+ - ee/spec/services/network_policies/resources_service_spec.rb
+ - ee/spec/services/projects/update_mirror_service_spec.rb
+ - ee/spec/services/projects/update_pages_service_spec.rb
+ - ee/spec/services/security/ingestion/ingest_report_slice_service_spec.rb
+ - ee/spec/services/security/orchestration/assign_service_spec.rb
+ - ee/spec/services/security/security_orchestration_policies/on_demand_scan_pipeline_configuration_service_spec.rb
+ - ee/spec/services/slash_commands/global_slack_handler_spec.rb
+ - ee/spec/services/status_page/publish_details_service_spec.rb
+ - ee/spec/services/status_page/publish_service_spec.rb
+ - ee/spec/services/status_page/trigger_publish_service_spec.rb
+ - ee/spec/services/system_note_service_spec.rb
+ - ee/spec/services/vulnerability_exports/export_service_spec.rb
+ - ee/spec/services/vulnerability_external_issue_links/create_service_spec.rb
+ - ee/spec/support/helpers/ee/ldap_helpers.rb
+ - ee/spec/support/prometheus/additional_metrics_shared_examples.rb
+ - ee/spec/support/shared_examples/controllers/analytics/cycle_analytics/shared_stage_shared_examples.rb
+ - ee/spec/support/shared_examples/controllers/cluster_metrics_shared_examples.rb
+ - ee/spec/support/shared_examples/models/concerns/blob_replicator_strategy_shared_examples.rb
+ - ee/spec/support/shared_examples/models/concerns/verifiable_replicator_shared_examples.rb
+ - ee/spec/support/shared_examples/models/geo_verifiable_registry_shared_examples.rb
+ - ee/spec/support/shared_examples/serializers/report_status_shared_examples.rb
+ - ee/spec/support/shared_examples/services/alert_management/alert_processing/oncall_notifications_shared_examples.rb
+ - ee/spec/support/shared_examples/services/base_sync_service_shared_examples.rb
+ - ee/spec/support/shared_examples/services/geo/geo_request_service_shared_examples.rb
+ - ee/spec/support/shared_examples/status_page/reference_links_examples.rb
+ - ee/spec/validators/json_schema_validator_spec.rb
+ - ee/spec/views/layouts/header/_ee_subscribable_banner.html.haml_spec.rb
+ - ee/spec/workers/ci/sync_reports_to_report_approval_rules_worker_spec.rb
+ - ee/spec/workers/geo/container_repository_sync_worker_spec.rb
+ - ee/spec/workers/geo/design_repository_sync_worker_spec.rb
+ - ee/spec/workers/geo/destroy_worker_spec.rb
+ - ee/spec/workers/geo/event_worker_spec.rb
+ - ee/spec/workers/geo/file_download_dispatch_worker_spec.rb
+ - ee/spec/workers/geo/file_download_worker_spec.rb
+ - ee/spec/workers/geo/metrics_update_worker_spec.rb
+ - ee/spec/workers/geo/prune_event_log_worker_spec.rb
+ - ee/spec/workers/geo/registry_sync_worker_spec.rb
+ - ee/spec/workers/geo/reverification_batch_worker_spec.rb
+ - ee/spec/workers/geo/sidekiq_cron_config_worker_spec.rb
+ - ee/spec/workers/geo/sync_timeout_cron_worker_spec.rb
+ - ee/spec/workers/geo/verification_batch_worker_spec.rb
+ - ee/spec/workers/geo/verification_cron_worker_spec.rb
+ - ee/spec/workers/geo/verification_timeout_worker_spec.rb
+ - ee/spec/workers/geo/verification_worker_spec.rb
+ - ee/spec/workers/iterations/cadences/create_iterations_worker_spec.rb
+ - ee/spec/workers/iterations/roll_over_issues_worker_spec.rb
+ - ee/spec/workers/ldap_group_sync_worker_spec.rb
+ - ee/spec/workers/merge_request_reset_approvals_worker_spec.rb
+ - ee/spec/workers/new_epic_worker_spec.rb
+ - ee/spec/workers/update_max_seats_used_for_gitlab_com_subscriptions_worker_spec.rb
+ - qa/spec/git/repository_spec.rb
+ - qa/spec/page/base_spec.rb
+ - qa/spec/page/validator_spec.rb
+ - qa/spec/page/view_spec.rb
+ - qa/spec/resource/api_fabricator_spec.rb
+ - qa/spec/resource/base_spec.rb
+ - qa/spec/runtime/application_settings_spec.rb
+ - qa/spec/runtime/feature_spec.rb
+ - qa/spec/runtime/release_spec.rb
+ - qa/spec/scenario/template_spec.rb
+ - qa/spec/scenario/test/integration/github_spec.rb
+ - qa/spec/scenario/test/sanity/selectors_spec.rb
+ - qa/spec/specs/allure_report_spec.rb
+ - qa/spec/support/formatters/allure_metadata_formatter_spec.rb
+ - qa/spec/support/page_error_checker_spec.rb
+ - qa/spec/support/run_spec.rb
+ - qa/spec/support/shared_examples/scenario_shared_examples.rb
+ - qa/spec/tools/long_running_spec_reporter_spec.rb
+ - spec/benchmarks/banzai_benchmark.rb
+ - spec/bin/feature_flag_spec.rb
+ - spec/controllers/admin/clusters_controller_spec.rb
+ - spec/controllers/application_controller_spec.rb
+ - spec/controllers/boards/issues_controller_spec.rb
+ - spec/controllers/boards/lists_controller_spec.rb
+ - spec/controllers/concerns/checks_collaboration_spec.rb
+ - spec/controllers/concerns/import_url_params_spec.rb
+ - spec/controllers/concerns/issuable_actions_spec.rb
+ - spec/controllers/concerns/issuable_collections_spec.rb
+ - spec/controllers/concerns/page_limiter_spec.rb
+ - spec/controllers/concerns/spammable_actions/akismet_mark_as_spam_action_spec.rb
+ - spec/controllers/concerns/spammable_actions/captcha_check/html_format_actions_support_spec.rb
+ - spec/controllers/concerns/spammable_actions/captcha_check/json_format_actions_support_spec.rb
+ - spec/controllers/dashboard/snippets_controller_spec.rb
+ - spec/controllers/explore/projects_controller_spec.rb
+ - spec/controllers/groups/clusters_controller_spec.rb
+ - spec/controllers/groups/dependency_proxy_auth_controller_spec.rb
+ - spec/controllers/groups/dependency_proxy_for_containers_controller_spec.rb
+ - spec/controllers/help_controller_spec.rb
+ - spec/controllers/import/bitbucket_controller_spec.rb
+ - spec/controllers/import/bitbucket_server_controller_spec.rb
+ - spec/controllers/import/bulk_imports_controller_spec.rb
+ - spec/controllers/import/fogbugz_controller_spec.rb
+ - spec/controllers/import/gitea_controller_spec.rb
+ - spec/controllers/import/github_controller_spec.rb
+ - spec/controllers/import/gitlab_controller_spec.rb
+ - spec/controllers/oauth/jira/authorizations_controller_spec.rb
+ - spec/controllers/omniauth_callbacks_controller_spec.rb
+ - spec/controllers/profiles/two_factor_auths_controller_spec.rb
+ - spec/controllers/projects/blob_controller_spec.rb
+ - spec/controllers/projects/branches_controller_spec.rb
+ - spec/controllers/projects/clusters_controller_spec.rb
+ - spec/controllers/projects/error_tracking/projects_controller_spec.rb
+ - spec/controllers/projects/error_tracking/stack_traces_controller_spec.rb
+ - spec/controllers/projects/error_tracking_controller_spec.rb
+ - spec/controllers/projects/import/jira_controller_spec.rb
+ - spec/controllers/projects/jobs_controller_spec.rb
+ - spec/controllers/projects/merge_requests/diffs_controller_spec.rb
+ - spec/controllers/projects/merge_requests_controller_spec.rb
+ - spec/controllers/projects/notes_controller_spec.rb
+ - spec/controllers/projects/pages_controller_spec.rb
+ - spec/controllers/projects/performance_monitoring/dashboards_controller_spec.rb
+ - spec/controllers/projects/pipelines_controller_spec.rb
+ - spec/controllers/projects/prometheus/metrics_controller_spec.rb
+ - spec/controllers/projects/registry/tags_controller_spec.rb
+ - spec/controllers/projects/settings/operations_controller_spec.rb
+ - spec/controllers/projects/snippets_controller_spec.rb
+ - spec/controllers/sessions_controller_spec.rb
+ - spec/dependencies/omniauth_saml_spec.rb
+ - spec/experiments/concerns/project_commit_count_spec.rb
+ - spec/factories/ci/job_artifacts.rb
+ - spec/factories/clusters/applications/helm.rb
+ - spec/features/admin/admin_system_info_spec.rb
+ - spec/features/clusters/create_agent_spec.rb
+ - spec/features/file_uploads/maven_package_spec.rb
+ - spec/features/groups/container_registry_spec.rb
+ - spec/features/help_pages_spec.rb
+ - spec/features/issuables/markdown_references/jira_spec.rb
+ - spec/features/markdown/markdown_spec.rb
+ - spec/features/profiles/personal_access_tokens_spec.rb
+ - spec/features/projects/clusters/gcp_spec.rb
+ - spec/features/projects/clusters_spec.rb
+ - spec/features/projects/container_registry_spec.rb
+ - spec/features/projects/integrations/user_activates_jira_spec.rb
+ - spec/finders/ci/auth_job_finder_spec.rb
+ - spec/finders/merge_requests/oldest_per_commit_finder_spec.rb
+ - spec/finders/projects/serverless/functions_finder_spec.rb
+ - spec/finders/repositories/changelog_commits_finder_spec.rb
+ - spec/finders/repositories/changelog_tag_finder_spec.rb
+ - spec/graphql/features/authorization_spec.rb
+ - spec/graphql/features/feature_flag_spec.rb
+ - spec/graphql/mutations/alert_management/alerts/todo/create_spec.rb
+ - spec/graphql/mutations/alert_management/update_alert_status_spec.rb
+ - spec/graphql/mutations/branches/create_spec.rb
+ - spec/graphql/mutations/ci/job_token_scope/add_project_spec.rb
+ - spec/graphql/mutations/ci/job_token_scope/remove_project_spec.rb
+ - spec/graphql/mutations/concerns/mutations/finds_by_gid_spec.rb
+ - spec/graphql/mutations/design_management/upload_spec.rb
+ - spec/graphql/mutations/environments/canary_ingress/update_spec.rb
+ - spec/graphql/mutations/merge_requests/accept_spec.rb
+ - spec/graphql/mutations/merge_requests/create_spec.rb
+ - spec/graphql/resolvers/design_management/versions_resolver_spec.rb
+ - spec/graphql/resolvers/error_tracking/sentry_detailed_error_resolver_spec.rb
+ - spec/graphql/resolvers/error_tracking/sentry_error_collection_resolver_spec.rb
+ - spec/graphql/resolvers/error_tracking/sentry_errors_resolver_spec.rb
+ - spec/graphql/resolvers/kas/agent_connections_resolver_spec.rb
+ - spec/graphql/resolvers/projects/jira_projects_resolver_spec.rb
+ - spec/graphql/types/ci/detailed_status_type_spec.rb
+ - spec/graphql/types/ci/status_action_type_spec.rb
+ - spec/graphql/types/kas/agent_connection_type_spec.rb
+ - spec/graphql/types/permission_types/base_permission_type_spec.rb
+ - spec/graphql/types/project_type_spec.rb
+ - spec/graphql/types/range_input_type_spec.rb
+ - spec/helpers/blame_helper_spec.rb
+ - spec/helpers/blob_helper_spec.rb
+ - spec/helpers/ci/pipelines_helper_spec.rb
+ - spec/helpers/ci/status_helper_spec.rb
+ - spec/helpers/ci/triggers_helper_spec.rb
+ - spec/helpers/commits_helper_spec.rb
+ - spec/helpers/dev_ops_report_helper_spec.rb
+ - spec/helpers/diff_helper_spec.rb
+ - spec/helpers/emails_helper_spec.rb
+ - spec/helpers/environments_helper_spec.rb
+ - spec/helpers/form_helper_spec.rb
+ - spec/helpers/gitlab_routing_helper_spec.rb
+ - spec/helpers/integrations_helper_spec.rb
+ - spec/helpers/issuables_helper_spec.rb
+ - spec/helpers/markup_helper_spec.rb
+ - spec/helpers/merge_requests_helper_spec.rb
+ - spec/helpers/notes_helper_spec.rb
+ - spec/helpers/numbers_helper_spec.rb
+ - spec/helpers/preferences_helper_spec.rb
+ - spec/helpers/projects_helper_spec.rb
+ - spec/helpers/routing/pseudonymization_helper_spec.rb
+ - spec/helpers/sorting_helper_spec.rb
+ - spec/helpers/submodule_helper_spec.rb
+ - spec/helpers/todos_helper_spec.rb
+ - spec/helpers/tree_helper_spec.rb
+ - spec/helpers/version_check_helper_spec.rb
+ - spec/initializers/doorkeeper_spec.rb
+ - spec/initializers/global_id_spec.rb
+ - spec/initializers/hangouts_chat_http_override_spec.rb
+ - spec/lib/api/base_spec.rb
+ - spec/lib/api/entities/ci/job_request/image_spec.rb
+ - spec/lib/api/entities/ci/job_request/port_spec.rb
+ - spec/lib/api/helpers/authentication_spec.rb
+ - spec/lib/api/helpers/caching_spec.rb
+ - spec/lib/api/helpers/graphql_helpers_spec.rb
+ - spec/lib/api/helpers/pagination_spec.rb
+ - spec/lib/api/helpers/pagination_strategies_spec.rb
+ - spec/lib/api/helpers/sse_helpers_spec.rb
+ - spec/lib/api/helpers/variables_helpers_spec.rb
+ - spec/lib/api/helpers_spec.rb
+ - spec/lib/atlassian/jira_connect/client_spec.rb
+ - spec/lib/backup/files_spec.rb
+ - spec/lib/backup/gitaly_rpc_backup_spec.rb
+ - spec/lib/backup/repositories_spec.rb
+ - spec/lib/banzai/cross_project_reference_spec.rb
+ - spec/lib/banzai/filter/gollum_tags_filter_spec.rb
+ - spec/lib/banzai/filter/repository_link_filter_spec.rb
+ - spec/lib/banzai/pipeline/wiki_pipeline_spec.rb
+ - spec/lib/banzai/querying_spec.rb
+ - spec/lib/banzai/reference_parser/base_parser_spec.rb
+ - spec/lib/banzai/reference_parser/commit_parser_spec.rb
+ - spec/lib/banzai/reference_parser/commit_range_parser_spec.rb
+ - spec/lib/banzai/render_context_spec.rb
+ - spec/lib/banzai/renderer_spec.rb
+ - spec/lib/bitbucket/connection_spec.rb
+ - spec/lib/bitbucket/paginator_spec.rb
+ - spec/lib/bitbucket_server/paginator_spec.rb
+ - spec/lib/bulk_imports/clients/http_spec.rb
+ - spec/lib/bulk_imports/common/extractors/graphql_extractor_spec.rb
+ - spec/lib/bulk_imports/common/extractors/rest_extractor_spec.rb
+ - spec/lib/bulk_imports/ndjson_pipeline_spec.rb
+ - spec/lib/bulk_imports/network_error_spec.rb
+ - spec/lib/bulk_imports/projects/pipelines/snippets_repository_pipeline_spec.rb
+ - spec/lib/bulk_imports/projects/transformers/project_attributes_transformer_spec.rb
+ - spec/lib/constraints/admin_constrainer_spec.rb
+ - spec/lib/constraints/feature_constrainer_spec.rb
+ - spec/lib/constraints/group_url_constrainer_spec.rb
+ - spec/lib/constraints/jira_encoded_url_constrainer_spec.rb
+ - spec/lib/constraints/project_url_constrainer_spec.rb
+ - spec/lib/constraints/user_url_constrainer_spec.rb
+ - spec/lib/csv_builder_spec.rb
+ - spec/lib/csv_builders/stream_spec.rb
+ - spec/lib/error_tracking/collector/dsn_spec.rb
+ - spec/lib/error_tracking/collector/sentry_auth_parser_spec.rb
+ - spec/lib/error_tracking/collector/sentry_request_parser_spec.rb
+ - spec/lib/error_tracking/sentry_client/issue_spec.rb
+ - spec/lib/extracts_path_spec.rb
+ - spec/lib/feature_spec.rb
+ - spec/lib/gitaly/server_spec.rb
+ - spec/lib/gitlab/api_authentication/token_locator_spec.rb
+ - spec/lib/gitlab/application_context_spec.rb
+ - spec/lib/gitlab/application_rate_limiter_spec.rb
+ - spec/lib/gitlab/asciidoc/include_processor_spec.rb
+ - spec/lib/gitlab/auth/auth_finders_spec.rb
+ - spec/lib/gitlab/auth/blocked_user_tracker_spec.rb
+ - spec/lib/gitlab/auth/ldap/adapter_spec.rb
+ - spec/lib/gitlab/auth/ldap/authentication_spec.rb
+ - spec/lib/gitlab/authorized_keys_spec.rb
+ - spec/lib/gitlab/avatar_cache_spec.rb
+ - spec/lib/gitlab/background_migration/base_job_spec.rb
+ - spec/lib/gitlab/background_migration/batching_strategies/base_strategy_spec.rb
+ - spec/lib/gitlab/background_migration/fix_merge_request_diff_commit_users_spec.rb
+ - spec/lib/gitlab/background_migration/job_coordinator_spec.rb
+ - spec/lib/gitlab/background_migration/migrate_merge_request_diff_commit_users_spec.rb
+ - spec/lib/gitlab/background_migration_spec.rb
+ - spec/lib/gitlab/bitbucket_import/importer_spec.rb
+ - spec/lib/gitlab/bitbucket_import/project_creator_spec.rb
+ - spec/lib/gitlab/bitbucket_server_import/importer_spec.rb
+ - spec/lib/gitlab/cache/import/caching_spec.rb
+ - spec/lib/gitlab/changelog/committer_spec.rb
+ - spec/lib/gitlab/chat/responder/base_spec.rb
+ - spec/lib/gitlab/chat/responder_spec.rb
+ - spec/lib/gitlab/ci/badge/coverage/metadata_spec.rb
+ - spec/lib/gitlab/ci/badge/coverage/template_spec.rb
+ - spec/lib/gitlab/ci/badge/pipeline/metadata_spec.rb
+ - spec/lib/gitlab/ci/badge/pipeline/template_spec.rb
+ - spec/lib/gitlab/ci/build/cache_spec.rb
+ - spec/lib/gitlab/ci/build/policy/changes_spec.rb
+ - spec/lib/gitlab/ci/build/policy/variables_spec.rb
+ - spec/lib/gitlab/ci/build/policy_spec.rb
+ - spec/lib/gitlab/ci/build/prerequisite/kubernetes_namespace_spec.rb
+ - spec/lib/gitlab/ci/build/rules/rule/clause/changes_spec.rb
+ - spec/lib/gitlab/ci/build/rules/rule_spec.rb
+ - spec/lib/gitlab/ci/build/rules_spec.rb
+ - spec/lib/gitlab/ci/build/status/reason_spec.rb
+ - spec/lib/gitlab/ci/config/entry/default_spec.rb
+ - spec/lib/gitlab/ci/config/entry/job_spec.rb
+ - spec/lib/gitlab/ci/config/entry/processable_spec.rb
+ - spec/lib/gitlab/ci/config/external/context_spec.rb
+ - spec/lib/gitlab/ci/config/external/file/local_spec.rb
+ - spec/lib/gitlab/ci/config/external/file/project_spec.rb
+ - spec/lib/gitlab/ci/config/external/rules_spec.rb
+ - spec/lib/gitlab/ci/parsers/test/junit_spec.rb
+ - spec/lib/gitlab/ci/pipeline/chain/command_spec.rb
+ - spec/lib/gitlab/ci/pipeline/chain/evaluate_workflow_rules_spec.rb
+ - spec/lib/gitlab/ci/pipeline/chain/helpers_spec.rb
+ - spec/lib/gitlab/ci/pipeline/chain/limit/deployments_spec.rb
+ - spec/lib/gitlab/ci/pipeline/chain/remove_unwanted_chat_jobs_spec.rb
+ - spec/lib/gitlab/ci/pipeline/chain/sequence_spec.rb
+ - spec/lib/gitlab/ci/pipeline/chain/skip_spec.rb
+ - spec/lib/gitlab/ci/pipeline/chain/template_usage_spec.rb
+ - spec/lib/gitlab/ci/pipeline/expression/lexeme/and_spec.rb
+ - spec/lib/gitlab/ci/pipeline/expression/lexeme/equals_spec.rb
+ - spec/lib/gitlab/ci/pipeline/expression/lexeme/matches_spec.rb
+ - spec/lib/gitlab/ci/pipeline/expression/lexeme/not_equals_spec.rb
+ - spec/lib/gitlab/ci/pipeline/expression/lexeme/not_matches_spec.rb
+ - spec/lib/gitlab/ci/pipeline/expression/lexeme/or_spec.rb
+ - spec/lib/gitlab/ci/pipeline/preloader_spec.rb
+ - spec/lib/gitlab/ci/pipeline/quota/deployments_spec.rb
+ - spec/lib/gitlab/ci/pipeline/seed/build_spec.rb
+ - spec/lib/gitlab/ci/reports/security/report_spec.rb
+ - spec/lib/gitlab/ci/status/build/action_spec.rb
+ - spec/lib/gitlab/ci/status/build/cancelable_spec.rb
+ - spec/lib/gitlab/ci/status/build/canceled_spec.rb
+ - spec/lib/gitlab/ci/status/build/created_spec.rb
+ - spec/lib/gitlab/ci/status/build/erased_spec.rb
+ - spec/lib/gitlab/ci/status/build/failed_allowed_spec.rb
+ - spec/lib/gitlab/ci/status/build/failed_spec.rb
+ - spec/lib/gitlab/ci/status/build/pending_spec.rb
+ - spec/lib/gitlab/ci/status/build/preparing_spec.rb
+ - spec/lib/gitlab/ci/status/build/retried_spec.rb
+ - spec/lib/gitlab/ci/status/build/retryable_spec.rb
+ - spec/lib/gitlab/ci/status/build/skipped_spec.rb
+ - spec/lib/gitlab/ci/status/build/stop_spec.rb
+ - spec/lib/gitlab/ci/status/build/unschedule_spec.rb
+ - spec/lib/gitlab/ci/status/canceled_spec.rb
+ - spec/lib/gitlab/ci/status/core_spec.rb
+ - spec/lib/gitlab/ci/status/created_spec.rb
+ - spec/lib/gitlab/ci/status/factory_spec.rb
+ - spec/lib/gitlab/ci/status/failed_spec.rb
+ - spec/lib/gitlab/ci/status/manual_spec.rb
+ - spec/lib/gitlab/ci/status/pending_spec.rb
+ - spec/lib/gitlab/ci/status/pipeline/blocked_spec.rb
+ - spec/lib/gitlab/ci/status/pipeline/delayed_spec.rb
+ - spec/lib/gitlab/ci/status/preparing_spec.rb
+ - spec/lib/gitlab/ci/status/running_spec.rb
+ - spec/lib/gitlab/ci/status/scheduled_spec.rb
+ - spec/lib/gitlab/ci/status/skipped_spec.rb
+ - spec/lib/gitlab/ci/status/stage/play_manual_spec.rb
+ - spec/lib/gitlab/ci/status/success_spec.rb
+ - spec/lib/gitlab/ci/status/success_warning_spec.rb
+ - spec/lib/gitlab/ci/status/waiting_for_resource_spec.rb
+ - spec/lib/gitlab/ci/trace/archive_spec.rb
+ - spec/lib/gitlab/ci/trace/remote_checksum_spec.rb
+ - spec/lib/gitlab/ci/trace/stream_spec.rb
+ - spec/lib/gitlab/ci/variables/builder_spec.rb
+ - spec/lib/gitlab/cleanup/orphan_lfs_file_references_spec.rb
+ - spec/lib/gitlab/cleanup/project_uploads_spec.rb
+ - spec/lib/gitlab/cleanup/remote_uploads_spec.rb
+ - spec/lib/gitlab/cluster/puma_worker_killer_observer_spec.rb
+ - spec/lib/gitlab/cluster/rack_timeout_observer_spec.rb
+ - spec/lib/gitlab/color_schemes_spec.rb
+ - spec/lib/gitlab/conan_token_spec.rb
+ - spec/lib/gitlab/config/entry/configurable_spec.rb
+ - spec/lib/gitlab/config/entry/factory_spec.rb
+ - spec/lib/gitlab/config/entry/simplifiable_spec.rb
+ - spec/lib/gitlab/config/entry/unspecified_spec.rb
+ - spec/lib/gitlab/config/entry/validator_spec.rb
+ - spec/lib/gitlab/conflict/file_spec.rb
+ - spec/lib/gitlab/cross_project_access/check_collection_spec.rb
+ - spec/lib/gitlab/database/async_indexes_spec.rb
+ - spec/lib/gitlab/database/background_migration/batched_migration_runner_spec.rb
+ - spec/lib/gitlab/database/background_migration/batched_migration_wrapper_spec.rb
+ - spec/lib/gitlab/database/batch_count_spec.rb
+ - spec/lib/gitlab/database/count_spec.rb
+ - spec/lib/gitlab/database/each_database_spec.rb
+ - spec/lib/gitlab/database/load_balancing/configuration_spec.rb
+ - spec/lib/gitlab/database/load_balancing/connection_proxy_spec.rb
+ - spec/lib/gitlab/database/load_balancing/host_list_spec.rb
+ - spec/lib/gitlab/database/load_balancing/host_spec.rb
+ - spec/lib/gitlab/database/load_balancing/load_balancer_spec.rb
+ - spec/lib/gitlab/database/load_balancing/rack_middleware_spec.rb
+ - spec/lib/gitlab/database/load_balancing/resolver_spec.rb
+ - spec/lib/gitlab/database/load_balancing/service_discovery_spec.rb
+ - spec/lib/gitlab/database/load_balancing/setup_spec.rb
+ - spec/lib/gitlab/database/load_balancing/sidekiq_server_middleware_spec.rb
+ - spec/lib/gitlab/database/load_balancing_spec.rb
+ - spec/lib/gitlab/database/migration_helpers_spec.rb
+ - spec/lib/gitlab/database/migrations/background_migration_helpers_spec.rb
+ - spec/lib/gitlab/database/migrations/instrumentation_spec.rb
+ - spec/lib/gitlab/database/migrations/lock_retry_mixin_spec.rb
+ - spec/lib/gitlab/database/migrations/observers/query_statistics_spec.rb
+ - spec/lib/gitlab/database/migrations/observers/total_database_size_change_spec.rb
+ - spec/lib/gitlab/database/migrations/runner_spec.rb
+ - spec/lib/gitlab/database/partitioning/monthly_strategy_spec.rb
+ - spec/lib/gitlab/database/partitioning/partition_manager_spec.rb
+ - spec/lib/gitlab/database/partitioning/partition_monitoring_spec.rb
+ - spec/lib/gitlab/database/partitioning/sliding_list_strategy_spec.rb
+ - spec/lib/gitlab/database/partitioning_migration_helpers/backfill_partitioned_table_spec.rb
+ - spec/lib/gitlab/database/partitioning_migration_helpers/table_management_helpers_spec.rb
+ - spec/lib/gitlab/database/partitioning_spec.rb
+ - spec/lib/gitlab/database/postgresql_adapter/empty_query_ping_spec.rb
+ - spec/lib/gitlab/database/postgresql_database_tasks/load_schema_versions_mixin_spec.rb
+ - spec/lib/gitlab/database/query_analyzer_spec.rb
+ - spec/lib/gitlab/database/reindexing/grafana_notifier_spec.rb
+ - spec/lib/gitlab/database/reindexing/reindex_concurrently_spec.rb
+ - spec/lib/gitlab/database/shared_model_spec.rb
+ - spec/lib/gitlab/database_spec.rb
+ - spec/lib/gitlab/diff/file_collection_sorter_spec.rb
+ - spec/lib/gitlab/diff/file_spec.rb
+ - spec/lib/gitlab/diff/line_spec.rb
+ - spec/lib/gitlab/diff/position_tracer_spec.rb
+ - spec/lib/gitlab/doctor/secrets_spec.rb
+ - spec/lib/gitlab/email/handler/service_desk_handler_spec.rb
+ - spec/lib/gitlab/email/receiver_spec.rb
+ - spec/lib/gitlab/email/service_desk_receiver_spec.rb
+ - spec/lib/gitlab/error_tracking/processor/sidekiq_processor_spec.rb
+ - spec/lib/gitlab/error_tracking_spec.rb
+ - spec/lib/gitlab/etag_caching/middleware_spec.rb
+ - spec/lib/gitlab/etag_caching/router/graphql_spec.rb
+ - spec/lib/gitlab/etag_caching/router/rails_spec.rb
+ - spec/lib/gitlab/etag_caching/router_spec.rb
+ - spec/lib/gitlab/event_store/store_spec.rb
+ - spec/lib/gitlab/experiment/rollout/feature_spec.rb
+ - spec/lib/gitlab/experimentation/controller_concern_spec.rb
+ - spec/lib/gitlab/experimentation/experiment_spec.rb
+ - spec/lib/gitlab/experimentation_spec.rb
+ - spec/lib/gitlab/external_authorization/access_spec.rb
+ - spec/lib/gitlab/external_authorization/logger_spec.rb
+ - spec/lib/gitlab/faraday/error_callback_spec.rb
+ - spec/lib/gitlab/feature_categories_spec.rb
+ - spec/lib/gitlab/git/blob_spec.rb
+ - spec/lib/gitlab/git/commit_spec.rb
+ - spec/lib/gitlab/git/repository_spec.rb
+ - spec/lib/gitlab/git/rugged_impl/use_rugged_spec.rb
+ - spec/lib/gitlab/git/tag_spec.rb
+ - spec/lib/gitlab/git_access_snippet_spec.rb
+ - spec/lib/gitlab/gitaly_client/commit_service_spec.rb
+ - spec/lib/gitlab/gitaly_client/conflict_files_stitcher_spec.rb
+ - spec/lib/gitlab/gitaly_client/conflicts_service_spec.rb
+ - spec/lib/gitlab/gitaly_client/health_check_service_spec.rb
+ - spec/lib/gitlab/gitaly_client/ref_service_spec.rb
+ - spec/lib/gitlab/gitaly_client/remote_service_spec.rb
+ - spec/lib/gitlab/gitaly_client/repository_service_spec.rb
+ - spec/lib/gitlab/gitaly_client_spec.rb
+ - spec/lib/gitlab/github_import/bulk_importing_spec.rb
+ - spec/lib/gitlab/github_import/client_spec.rb
+ - spec/lib/gitlab/github_import/importer/diff_note_importer_spec.rb
+ - spec/lib/gitlab/github_import/importer/diff_notes_importer_spec.rb
+ - spec/lib/gitlab/github_import/importer/issue_and_label_links_importer_spec.rb
+ - spec/lib/gitlab/github_import/importer/issue_importer_spec.rb
+ - spec/lib/gitlab/github_import/importer/issues_importer_spec.rb
+ - spec/lib/gitlab/github_import/importer/label_links_importer_spec.rb
+ - spec/lib/gitlab/github_import/importer/labels_importer_spec.rb
+ - spec/lib/gitlab/github_import/importer/lfs_objects_importer_spec.rb
+ - spec/lib/gitlab/github_import/importer/milestones_importer_spec.rb
+ - spec/lib/gitlab/github_import/importer/note_importer_spec.rb
+ - spec/lib/gitlab/github_import/importer/notes_importer_spec.rb
+ - spec/lib/gitlab/github_import/importer/pull_request_importer_spec.rb
+ - spec/lib/gitlab/github_import/importer/pull_request_merged_by_importer_spec.rb
+ - spec/lib/gitlab/github_import/importer/pull_request_review_importer_spec.rb
+ - spec/lib/gitlab/github_import/importer/pull_requests_importer_spec.rb
+ - spec/lib/gitlab/github_import/importer/pull_requests_merged_by_importer_spec.rb
+ - spec/lib/gitlab/github_import/importer/pull_requests_reviews_importer_spec.rb
+ - spec/lib/gitlab/github_import/importer/releases_importer_spec.rb
+ - spec/lib/gitlab/github_import/importer/repository_importer_spec.rb
+ - spec/lib/gitlab/github_import/importer/single_endpoint_diff_notes_importer_spec.rb
+ - spec/lib/gitlab/github_import/importer/single_endpoint_issue_notes_importer_spec.rb
+ - spec/lib/gitlab/github_import/importer/single_endpoint_merge_request_notes_importer_spec.rb
+ - spec/lib/gitlab/github_import/issuable_finder_spec.rb
+ - spec/lib/gitlab/github_import/markdown_text_spec.rb
+ - spec/lib/gitlab/github_import/milestone_finder_spec.rb
+ - spec/lib/gitlab/github_import/object_counter_spec.rb
+ - spec/lib/gitlab/github_import/page_counter_spec.rb
+ - spec/lib/gitlab/github_import/parallel_importer_spec.rb
+ - spec/lib/gitlab/github_import/parallel_scheduling_spec.rb
+ - spec/lib/gitlab/github_import/representation/diff_note_spec.rb
+ - spec/lib/gitlab/github_import/representation/issue_spec.rb
+ - spec/lib/gitlab/github_import/representation/note_spec.rb
+ - spec/lib/gitlab/github_import/representation/pull_request_review_spec.rb
+ - spec/lib/gitlab/github_import/representation/pull_request_spec.rb
+ - spec/lib/gitlab/github_import/representation/to_hash_spec.rb
+ - spec/lib/gitlab/github_import/representation/user_spec.rb
+ - spec/lib/gitlab/github_import/sequential_importer_spec.rb
+ - spec/lib/gitlab/github_import/user_finder_spec.rb
+ - spec/lib/gitlab/github_import_spec.rb
+ - spec/lib/gitlab/gon_helper_spec.rb
+ - spec/lib/gitlab/gpg/commit_spec.rb
+ - spec/lib/gitlab/gpg/invalid_gpg_signature_updater_spec.rb
+ - spec/lib/gitlab/gpg_spec.rb
+ - spec/lib/gitlab/grape_logging/loggers/exception_logger_spec.rb
+ - spec/lib/gitlab/grape_logging/loggers/perf_logger_spec.rb
+ - spec/lib/gitlab/grape_logging/loggers/queue_duration_logger_spec.rb
+ - spec/lib/gitlab/grape_logging/loggers/urgency_logger_spec.rb
+ - spec/lib/gitlab/graphql/authorize/object_authorization_spec.rb
+ - spec/lib/gitlab/graphql/batch_key_spec.rb
+ - spec/lib/gitlab/graphql/find_argument_in_parent_spec.rb
+ - spec/lib/gitlab/graphql/generic_tracing_spec.rb
+ - spec/lib/gitlab/graphql/lazy_spec.rb
+ - spec/lib/gitlab/graphql/loaders/issuable_loader_spec.rb
+ - spec/lib/gitlab/graphql/pagination/keyset/conditions/not_null_condition_spec.rb
+ - spec/lib/gitlab/graphql/pagination/keyset/conditions/null_condition_spec.rb
+ - spec/lib/gitlab/graphql/pagination/keyset/connection_generic_keyset_spec.rb
+ - spec/lib/gitlab/graphql/pagination/keyset/connection_spec.rb
+ - spec/lib/gitlab/graphql/present/field_extension_spec.rb
+ - spec/lib/gitlab/graphql/timeout_spec.rb
+ - spec/lib/gitlab/graphql/tracers/application_context_tracer_spec.rb
+ - spec/lib/gitlab/graphql/tracers/timer_tracer_spec.rb
+ - spec/lib/gitlab/health_checks/gitaly_check_spec.rb
+ - spec/lib/gitlab/hook_data/base_builder_spec.rb
+ - spec/lib/gitlab/hotlinking_detector_spec.rb
+ - spec/lib/gitlab/import/import_failure_service_spec.rb
+ - spec/lib/gitlab/import/metrics_spec.rb
+ - spec/lib/gitlab/import_export/attribute_cleaner_spec.rb
+ - spec/lib/gitlab/import_export/base/relation_factory_spec.rb
+ - spec/lib/gitlab/import_export/decompressed_archive_size_validator_spec.rb
+ - spec/lib/gitlab/import_export/group/relation_factory_spec.rb
+ - spec/lib/gitlab/import_export/importer_spec.rb
+ - spec/lib/gitlab/import_export/project/relation_factory_spec.rb
+ - spec/lib/gitlab/import_export/project/sample/relation_factory_spec.rb
+ - spec/lib/gitlab/import_export/project/tree_saver_spec.rb
+ - spec/lib/gitlab/issuables_count_for_state_spec.rb
+ - spec/lib/gitlab/issues/rebalancing/state_spec.rb
+ - spec/lib/gitlab/jira/middleware_spec.rb
+ - spec/lib/gitlab/jira_import/issue_serializer_spec.rb
+ - spec/lib/gitlab/jira_import/labels_importer_spec.rb
+ - spec/lib/gitlab/jira_import/metadata_collector_spec.rb
+ - spec/lib/gitlab/jira_import_spec.rb
+ - spec/lib/gitlab/job_waiter_spec.rb
+ - spec/lib/gitlab/json_cache_spec.rb
+ - spec/lib/gitlab/kas/client_spec.rb
+ - spec/lib/gitlab/kubernetes/config_map_spec.rb
+ - spec/lib/gitlab/kubernetes/default_namespace_spec.rb
+ - spec/lib/gitlab/kubernetes/helm/api_spec.rb
+ - spec/lib/gitlab/kubernetes/namespace_spec.rb
+ - spec/lib/gitlab/lazy_spec.rb
+ - spec/lib/gitlab/legacy_github_import/branch_formatter_spec.rb
+ - spec/lib/gitlab/legacy_github_import/comment_formatter_spec.rb
+ - spec/lib/gitlab/legacy_github_import/importer_spec.rb
+ - spec/lib/gitlab/legacy_github_import/issuable_formatter_spec.rb
+ - spec/lib/gitlab/legacy_github_import/issue_formatter_spec.rb
+ - spec/lib/gitlab/legacy_github_import/label_formatter_spec.rb
+ - spec/lib/gitlab/legacy_github_import/milestone_formatter_spec.rb
+ - spec/lib/gitlab/legacy_github_import/pull_request_formatter_spec.rb
+ - spec/lib/gitlab/legacy_github_import/release_formatter_spec.rb
+ - spec/lib/gitlab/legacy_github_import/user_formatter_spec.rb
+ - spec/lib/gitlab/lets_encrypt/client_spec.rb
+ - spec/lib/gitlab/mail_room/mail_room_spec.rb
+ - spec/lib/gitlab/manifest_import/metadata_spec.rb
+ - spec/lib/gitlab/markdown_cache/field_data_spec.rb
+ - spec/lib/gitlab/merge_requests/commit_message_generator_spec.rb
+ - spec/lib/gitlab/merge_requests/mergeability/redis_interface_spec.rb
+ - spec/lib/gitlab/metrics/boot_time_tracker_spec.rb
+ - spec/lib/gitlab/metrics/dashboard/importers/prometheus_metrics_spec.rb
+ - spec/lib/gitlab/metrics/elasticsearch_rack_middleware_spec.rb
+ - spec/lib/gitlab/metrics/exporter/base_exporter_spec.rb
+ - spec/lib/gitlab/metrics/exporter/gc_request_middleware_spec.rb
+ - spec/lib/gitlab/metrics/exporter/health_checks_middleware_spec.rb
+ - spec/lib/gitlab/metrics/exporter/metrics_middleware_spec.rb
+ - spec/lib/gitlab/metrics/rack_middleware_spec.rb
+ - spec/lib/gitlab/metrics/requests_rack_middleware_spec.rb
+ - spec/lib/gitlab/metrics/samplers/database_sampler_spec.rb
+ - spec/lib/gitlab/metrics/samplers/puma_sampler_spec.rb
+ - spec/lib/gitlab/metrics/samplers/ruby_sampler_spec.rb
+ - spec/lib/gitlab/metrics/sli_spec.rb
+ - spec/lib/gitlab/metrics/subscribers/action_cable_spec.rb
+ - spec/lib/gitlab/metrics/subscribers/action_view_spec.rb
+ - spec/lib/gitlab/metrics/subscribers/active_record_spec.rb
+ - spec/lib/gitlab/metrics/subscribers/external_http_spec.rb
+ - spec/lib/gitlab/metrics/subscribers/load_balancing_spec.rb
+ - spec/lib/gitlab/metrics/subscribers/rack_attack_spec.rb
+ - spec/lib/gitlab/metrics/subscribers/rails_cache_spec.rb
+ - spec/lib/gitlab/metrics/web_transaction_spec.rb
+ - spec/lib/gitlab/middleware/basic_health_check_spec.rb
+ - spec/lib/gitlab/middleware/compressed_json_spec.rb
+ - spec/lib/gitlab/middleware/go_spec.rb
+ - spec/lib/gitlab/middleware/handle_malformed_strings_spec.rb
+ - spec/lib/gitlab/middleware/multipart_spec.rb
+ - spec/lib/gitlab/middleware/query_analyzer_spec.rb
+ - spec/lib/gitlab/middleware/rails_queue_duration_spec.rb
+ - spec/lib/gitlab/middleware/release_env_spec.rb
+ - spec/lib/gitlab/middleware/sidekiq_web_static_spec.rb
+ - spec/lib/gitlab/middleware/speedscope_spec.rb
+ - spec/lib/gitlab/middleware/webhook_recursion_detection_spec.rb
+ - spec/lib/gitlab/octokit/middleware_spec.rb
+ - spec/lib/gitlab/optimistic_locking_spec.rb
+ - spec/lib/gitlab/pages/settings_spec.rb
+ - spec/lib/gitlab/pagination/cursor_based_keyset_spec.rb
+ - spec/lib/gitlab/pagination/gitaly_keyset_pager_spec.rb
+ - spec/lib/gitlab/pagination/keyset/cursor_based_request_context_spec.rb
+ - spec/lib/gitlab/pagination/keyset/cursor_pager_spec.rb
+ - spec/lib/gitlab/pagination/keyset/pager_spec.rb
+ - spec/lib/gitlab/pagination/keyset/request_context_spec.rb
+ - spec/lib/gitlab/pagination/keyset_spec.rb
+ - spec/lib/gitlab/pagination/offset_header_builder_spec.rb
+ - spec/lib/gitlab/pagination/offset_pagination_spec.rb
+ - spec/lib/gitlab/performance_bar/stats_spec.rb
+ - spec/lib/gitlab/phabricator_import/conduit/maniphest_spec.rb
+ - spec/lib/gitlab/phabricator_import/conduit/response_spec.rb
+ - spec/lib/gitlab/phabricator_import/conduit/user_spec.rb
+ - spec/lib/gitlab/polling_interval_spec.rb
+ - spec/lib/gitlab/popen/runner_spec.rb
+ - spec/lib/gitlab/process_management_spec.rb
+ - spec/lib/gitlab/profiler_spec.rb
+ - spec/lib/gitlab/prometheus/adapter_spec.rb
+ - spec/lib/gitlab/prometheus/queries/deployment_query_spec.rb
+ - spec/lib/gitlab/prometheus/queries/knative_invocation_query_spec.rb
+ - spec/lib/gitlab/prometheus/queries/matched_metric_query_spec.rb
+ - spec/lib/gitlab/query_limiting/middleware_spec.rb
+ - spec/lib/gitlab/quick_actions/dsl_spec.rb
+ - spec/lib/gitlab/repository_cache_spec.rb
+ - spec/lib/gitlab/routing_spec.rb
+ - spec/lib/gitlab/runtime_spec.rb
+ - spec/lib/gitlab/sanitizers/svg_spec.rb
+ - spec/lib/gitlab/search/abuse_validators/no_abusive_coercion_from_string_validator_spec.rb
+ - spec/lib/gitlab/search/abuse_validators/no_abusive_term_length_validator_spec.rb
+ - spec/lib/gitlab/serializer/pagination_spec.rb
+ - spec/lib/gitlab/sidekiq_config/cli_methods_spec.rb
+ - spec/lib/gitlab/sidekiq_config/worker_spec.rb
+ - spec/lib/gitlab/sidekiq_middleware/client_metrics_spec.rb
+ - spec/lib/gitlab/sidekiq_middleware/memory_killer_spec.rb
+ - spec/lib/gitlab/sidekiq_middleware/query_analyzer_spec.rb
+ - spec/lib/gitlab/sidekiq_middleware/server_metrics_spec.rb
+ - spec/lib/gitlab/sidekiq_middleware_spec.rb
+ - spec/lib/gitlab/sidekiq_status/client_middleware_spec.rb
+ - spec/lib/gitlab/sidekiq_status/server_middleware_spec.rb
+ - spec/lib/gitlab/slash_commands/command_spec.rb
+ - spec/lib/gitlab/slash_commands/deploy_spec.rb
+ - spec/lib/gitlab/slash_commands/issue_close_spec.rb
+ - spec/lib/gitlab/slash_commands/issue_comment_spec.rb
+ - spec/lib/gitlab/slash_commands/issue_new_spec.rb
+ - spec/lib/gitlab/slash_commands/issue_search_spec.rb
+ - spec/lib/gitlab/slash_commands/issue_show_spec.rb
+ - spec/lib/gitlab/slash_commands/presenters/run_spec.rb
+ - spec/lib/gitlab/slash_commands/run_spec.rb
+ - spec/lib/gitlab/spamcheck/client_spec.rb
+ - spec/lib/gitlab/submodule_links_spec.rb
+ - spec/lib/gitlab/suggestions/file_suggestion_spec.rb
+ - spec/lib/gitlab/tab_width_spec.rb
+ - spec/lib/gitlab/themes_spec.rb
+ - spec/lib/gitlab/tracking_spec.rb
+ - spec/lib/gitlab/usage/metric_spec.rb
+ - spec/lib/gitlab/usage/metrics/instrumentations/database_metric_spec.rb
+ - spec/lib/gitlab/usage/service_ping/payload_keys_processor_spec.rb
+ - spec/lib/gitlab/usage_data_counters/merge_request_activity_unique_counter_spec.rb
+ - spec/lib/gitlab/usage_data_spec.rb
+ - spec/lib/gitlab/utils/usage_data_spec.rb
+ - spec/lib/gitlab/verify/job_artifacts_spec.rb
+ - spec/lib/gitlab/verify/lfs_objects_spec.rb
+ - spec/lib/gitlab/verify/uploads_spec.rb
+ - spec/lib/gitlab/view/presenter/base_spec.rb
+ - spec/lib/gitlab/view/presenter/delegated_spec.rb
+ - spec/lib/gitlab/view/presenter/simple_spec.rb
+ - spec/lib/gitlab/workhorse_spec.rb
+ - spec/lib/gitlab_edition_spec.rb
+ - spec/lib/gitlab_spec.rb
+ - spec/lib/google_api/cloud_platform/client_spec.rb
+ - spec/lib/peek/views/active_record_spec.rb
+ - spec/lib/peek/views/bullet_detailed_spec.rb
+ - spec/lib/peek/views/external_http_spec.rb
+ - spec/lib/safe_zip/entry_spec.rb
+ - spec/lib/serializers/unsafe_json_spec.rb
+ - spec/lib/sidebars/projects/menus/analytics_menu_spec.rb
+ - spec/mailers/emails/service_desk_spec.rb
+ - spec/mailers/notify_spec.rb
+ - spec/metrics_server/metrics_server_spec.rb
+ - spec/migrations/20210406144743_backfill_total_tuple_count_for_batched_migrations_spec.rb
+ - spec/models/active_session_spec.rb
+ - spec/models/application_record_spec.rb
+ - spec/models/badge_spec.rb
+ - spec/models/badges/project_badge_spec.rb
+ - spec/models/bulk_imports/export_status_spec.rb
+ - spec/models/ci/build_spec.rb
+ - spec/models/ci/build_trace_chunk_spec.rb
+ - spec/models/ci/commit_with_pipeline_spec.rb
+ - spec/models/ci/group_spec.rb
+ - spec/models/ci/pipeline_spec.rb
+ - spec/models/clusters/applications/runner_spec.rb
+ - spec/models/clusters/cluster_spec.rb
+ - spec/models/clusters/platforms/kubernetes_spec.rb
+ - spec/models/commit_signatures/gpg_signature_spec.rb
+ - spec/models/commit_spec.rb
+ - spec/models/commit_status_spec.rb
+ - spec/models/concerns/atomic_internal_id_spec.rb
+ - spec/models/concerns/legacy_bulk_insert_spec.rb
+ - spec/models/concerns/prometheus_adapter_spec.rb
+ - spec/models/concerns/sha256_attribute_spec.rb
+ - spec/models/concerns/sha_attribute_spec.rb
+ - spec/models/concerns/token_authenticatable_strategies/base_spec.rb
+ - spec/models/concerns/token_authenticatable_strategies/encrypted_spec.rb
+ - spec/models/concerns/triggerable_hooks_spec.rb
+ - spec/models/concerns/x509_serial_number_attribute_spec.rb
+ - spec/models/design_management/design_action_spec.rb
+ - spec/models/design_management/design_at_version_spec.rb
+ - spec/models/diff_viewer/image_spec.rb
+ - spec/models/environment_spec.rb
+ - spec/models/error_tracking/project_error_tracking_setting_spec.rb
+ - spec/models/event_spec.rb
+ - spec/models/external_issue_spec.rb
+ - spec/models/hooks/web_hook_spec.rb
+ - spec/models/integrations/asana_spec.rb
+ - spec/models/integrations/chat_message/pipeline_message_spec.rb
+ - spec/models/integrations/jira_spec.rb
+ - spec/models/integrations/microsoft_teams_spec.rb
+ - spec/models/integrations/pipelines_email_spec.rb
+ - spec/models/issue_spec.rb
+ - spec/models/key_spec.rb
+ - spec/models/merge_request_diff_commit_spec.rb
+ - spec/models/merge_request_spec.rb
+ - spec/models/packages/package_spec.rb
+ - spec/models/plan_limits_spec.rb
+ - spec/models/project_import_state_spec.rb
+ - spec/models/project_spec.rb
+ - spec/models/ref_matcher_spec.rb
+ - spec/models/release_highlight_spec.rb
+ - spec/models/repository_spec.rb
+ - spec/models/shard_spec.rb
+ - spec/models/snippet_spec.rb
+ - spec/models/ssh_host_key_spec.rb
+ - spec/models/upload_spec.rb
+ - spec/models/user_spec.rb
+ - spec/policies/ci/bridge_policy_spec.rb
+ - spec/presenters/ci/build_presenter_spec.rb
+ - spec/presenters/ci/pipeline_artifacts/code_quality_mr_diff_presenter_spec.rb
+ - spec/presenters/group_member_presenter_spec.rb
+ - spec/presenters/merge_request_presenter_spec.rb
+ - spec/presenters/packages/nuget/search_results_presenter_spec.rb
+ - spec/presenters/project_member_presenter_spec.rb
+ - spec/presenters/project_presenter_spec.rb
+ - spec/requests/api/avatar_spec.rb
+ - spec/requests/api/container_registry_event_spec.rb
+ - spec/requests/api/graphql/mutations/design_management/delete_spec.rb
+ - spec/requests/api/graphql/mutations/snippets/create_spec.rb
+ - spec/requests/api/graphql/project/cluster_agents_spec.rb
+ - spec/requests/api/graphql/project/pipeline_spec.rb
+ - spec/requests/api/helpers_spec.rb
+ - spec/requests/api/import_bitbucket_server_spec.rb
+ - spec/requests/api/import_github_spec.rb
+ - spec/requests/api/internal/base_spec.rb
+ - spec/requests/api/maven_packages_spec.rb
+ - spec/requests/api/project_container_repositories_spec.rb
+ - spec/requests/api/users_preferences_spec.rb
+ - spec/requests/jwt_controller_spec.rb
+ - spec/requests/whats_new_controller_spec.rb
+ - spec/rubocop/migration_helpers_spec.rb
+ - spec/scripts/setup/find_jh_branch_spec.rb
+ - spec/serializers/accessibility_reports_comparer_serializer_spec.rb
+ - spec/serializers/admin/user_entity_spec.rb
+ - spec/serializers/base_discussion_entity_spec.rb
+ - spec/serializers/build_action_entity_spec.rb
+ - spec/serializers/build_details_entity_spec.rb
+ - spec/serializers/build_trace_entity_spec.rb
+ - spec/serializers/ci/dag_job_entity_spec.rb
+ - spec/serializers/ci/dag_job_group_entity_spec.rb
+ - spec/serializers/ci/dag_pipeline_entity_spec.rb
+ - spec/serializers/ci/dag_stage_entity_spec.rb
+ - spec/serializers/ci/daily_build_group_report_result_entity_spec.rb
+ - spec/serializers/ci/daily_build_group_report_result_serializer_spec.rb
+ - spec/serializers/ci/job_entity_spec.rb
+ - spec/serializers/ci/job_serializer_spec.rb
+ - spec/serializers/ci/pipeline_entity_spec.rb
+ - spec/serializers/codequality_reports_comparer_serializer_spec.rb
+ - spec/serializers/commit_entity_spec.rb
+ - spec/serializers/container_repositories_serializer_spec.rb
+ - spec/serializers/container_repository_entity_spec.rb
+ - spec/serializers/container_tag_entity_spec.rb
+ - spec/serializers/deployment_cluster_entity_spec.rb
+ - spec/serializers/deployment_entity_spec.rb
+ - spec/serializers/detailed_status_entity_spec.rb
+ - spec/serializers/diff_file_entity_spec.rb
+ - spec/serializers/diffs_entity_spec.rb
+ - spec/serializers/diffs_metadata_entity_spec.rb
+ - spec/serializers/discussion_entity_spec.rb
+ - spec/serializers/environment_entity_spec.rb
+ - spec/serializers/environment_serializer_spec.rb
+ - spec/serializers/environment_status_entity_spec.rb
+ - spec/serializers/feature_flag_entity_spec.rb
+ - spec/serializers/feature_flag_summary_entity_spec.rb
+ - spec/serializers/group_child_entity_spec.rb
+ - spec/serializers/group_child_serializer_spec.rb
+ - spec/serializers/import/manifest_provider_repo_entity_spec.rb
+ - spec/serializers/issuable_sidebar_extras_entity_spec.rb
+ - spec/serializers/issue_board_entity_spec.rb
+ - spec/serializers/issue_entity_spec.rb
+ - spec/serializers/lfs_file_lock_entity_spec.rb
+ - spec/serializers/linked_project_issue_entity_spec.rb
+ - spec/serializers/merge_request_poll_cached_widget_entity_spec.rb
+ - spec/serializers/merge_request_poll_widget_entity_spec.rb
+ - spec/serializers/merge_request_sidebar_basic_entity_spec.rb
+ - spec/serializers/merge_request_sidebar_extras_entity_spec.rb
+ - spec/serializers/merge_request_widget_commit_entity_spec.rb
+ - spec/serializers/merge_request_widget_entity_spec.rb
+ - spec/serializers/merge_requests/pipeline_entity_spec.rb
+ - spec/serializers/note_entity_spec.rb
+ - spec/serializers/paginated_diff_entity_spec.rb
+ - spec/serializers/pipeline_details_entity_spec.rb
+ - spec/serializers/pipeline_serializer_spec.rb
+ - spec/serializers/project_note_entity_spec.rb
+ - spec/serializers/prometheus_alert_entity_spec.rb
+ - spec/serializers/review_app_setup_entity_spec.rb
+ - spec/serializers/runner_entity_spec.rb
+ - spec/serializers/service_event_entity_spec.rb
+ - spec/serializers/service_field_entity_spec.rb
+ - spec/serializers/stage_entity_spec.rb
+ - spec/serializers/suggestion_entity_spec.rb
+ - spec/serializers/test_reports_comparer_serializer_spec.rb
+ - spec/serializers/test_suite_entity_spec.rb
+ - spec/serializers/trigger_variable_entity_spec.rb
+ - spec/services/access_token_validation_service_spec.rb
+ - spec/services/authorized_project_update/find_records_due_for_refresh_service_spec.rb
+ - spec/services/award_emojis/toggle_service_spec.rb
+ - spec/services/base_count_service_spec.rb
+ - spec/services/bulk_imports/file_download_service_spec.rb
+ - spec/services/ci/change_variables_service_spec.rb
+ - spec/services/ci/create_pipeline_service_spec.rb
+ - spec/services/ci/pipeline_creation/start_pipeline_service_spec.rb
+ - spec/services/ci/prepare_build_service_spec.rb
+ - spec/services/ci/process_pipeline_service_spec.rb
+ - spec/services/ci/register_job_service_spec.rb
+ - spec/services/ci/test_failure_history_service_spec.rb
+ - spec/services/ci/update_build_queue_service_spec.rb
+ - spec/services/ci/update_build_state_service_spec.rb
+ - spec/services/clusters/applications/check_ingress_ip_address_service_spec.rb
+ - spec/services/clusters/applications/create_service_spec.rb
+ - spec/services/clusters/applications/prometheus_update_service_spec.rb
+ - spec/services/clusters/applications/update_service_spec.rb
+ - spec/services/clusters/aws/finalize_creation_service_spec.rb
+ - spec/services/clusters/aws/provision_service_spec.rb
+ - spec/services/clusters/aws/verify_provision_status_service_spec.rb
+ - spec/services/clusters/build_kubernetes_namespace_service_spec.rb
+ - spec/services/clusters/kubernetes/create_or_update_namespace_service_spec.rb
+ - spec/services/clusters/kubernetes/create_or_update_service_account_service_spec.rb
+ - spec/services/container_expiration_policies/cleanup_service_spec.rb
+ - spec/services/deployments/create_service_spec.rb
+ - spec/services/discussions/capture_diff_note_position_service_spec.rb
+ - spec/services/error_tracking/base_service_spec.rb
+ - spec/services/error_tracking/issue_update_service_spec.rb
+ - spec/services/event_create_service_spec.rb
+ - spec/services/git/base_hooks_service_spec.rb
+ - spec/services/git/process_ref_changes_service_spec.rb
+ - spec/services/git/wiki_push_service/change_spec.rb
+ - spec/services/ide/schemas_config_service_spec.rb
+ - spec/services/import/bitbucket_server_service_spec.rb
+ - spec/services/import/github_service_spec.rb
+ - spec/services/import/gitlab_projects/create_project_from_remote_file_service_spec.rb
+ - spec/services/issues/create_service_spec.rb
+ - spec/services/issues/related_branches_service_spec.rb
+ - spec/services/jira_connect_subscriptions/create_service_spec.rb
+ - spec/services/merge_requests/add_todo_when_build_fails_service_spec.rb
+ - spec/services/merge_requests/approval_service_spec.rb
+ - spec/services/merge_requests/build_service_spec.rb
+ - spec/services/merge_requests/close_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/reopen_service_spec.rb
+ - spec/services/merge_requests/request_review_service_spec.rb
+ - spec/services/merge_requests/toggle_attention_requested_service_spec.rb
+ - spec/services/metrics/dashboard/clone_dashboard_service_spec.rb
+ - spec/services/metrics/dashboard/update_dashboard_service_spec.rb
+ - spec/services/metrics/users_starred_dashboards/create_service_spec.rb
+ - spec/services/milestones/update_service_spec.rb
+ - spec/services/namespaces/in_product_marketing_emails_service_spec.rb
+ - spec/services/namespaces/invite_team_email_service_spec.rb
+ - spec/services/notes/create_service_spec.rb
+ - spec/services/notes/render_service_spec.rb
+ - spec/services/notification_service_spec.rb
+ - spec/services/packages/generic/create_package_file_service_spec.rb
+ - spec/services/packages/maven/find_or_create_package_service_spec.rb
+ - spec/services/packages/maven/metadata/sync_service_spec.rb
+ - spec/services/packages/nuget/metadata_extraction_service_spec.rb
+ - spec/services/pages/zip_directory_service_spec.rb
+ - spec/services/post_receive_service_spec.rb
+ - spec/services/projects/after_import_service_spec.rb
+ - spec/services/projects/branches_by_mode_service_spec.rb
+ - spec/services/projects/create_service_spec.rb
+ - spec/services/projects/destroy_service_spec.rb
+ - spec/services/projects/import_service_spec.rb
+ - spec/services/projects/operations/update_service_spec.rb
+ - spec/services/projects/overwrite_project_service_spec.rb
+ - spec/services/projects/update_pages_service_spec.rb
+ - spec/services/projects/update_remote_mirror_service_spec.rb
+ - spec/services/projects/update_repository_storage_service_spec.rb
+ - spec/services/projects/update_service_spec.rb
+ - spec/services/repositories/changelog_service_spec.rb
+ - spec/services/search_service_spec.rb
+ - spec/services/service_ping/build_payload_service_spec.rb
+ - spec/services/service_ping/permit_data_categories_service_spec.rb
+ - spec/services/service_ping/service_ping_settings_spec.rb
+ - spec/services/service_ping/submit_service_ping_service_spec.rb
+ - spec/services/snippets/update_repository_storage_service_spec.rb
+ - spec/services/spam/akismet_mark_as_spam_service_spec.rb
+ - spec/services/spam/akismet_service_spec.rb
+ - spec/services/spam/ham_service_spec.rb
+ - spec/services/spam/spam_action_service_spec.rb
+ - spec/services/spam/spam_params_spec.rb
+ - spec/services/static_site_editor/config_service_spec.rb
+ - spec/services/system_note_service_spec.rb
+ - spec/services/system_notes/commit_service_spec.rb
+ - spec/services/system_notes/issuables_service_spec.rb
+ - spec/services/update_merge_request_metrics_service_spec.rb
+ - spec/services/users/activity_service_spec.rb
+ - spec/services/users/create_service_spec.rb
+ - spec/services/users/refresh_authorized_projects_service_spec.rb
+ - spec/services/users/update_service_spec.rb
+ - spec/services/web_hook_service_spec.rb
+ - spec/services/wiki_pages/base_service_spec.rb
+ - spec/spam/concerns/has_spam_action_response_fields_spec.rb
+ - spec/support/helpers/graphql_helpers.rb
+ - spec/support/helpers/import_spec_helper.rb
+ - spec/support/helpers/ldap_helpers.rb
+ - spec/support/helpers/project_forks_helper.rb
+ - spec/support/helpers/stub_metrics.rb
+ - spec/support/helpers/stub_spam_services.rb
+ - spec/support/import_export/common_util.rb
+ - spec/support/prometheus/additional_metrics_shared_examples.rb
+ - spec/support/shared_contexts/lib/gitlab/sidekiq_middleware/server_metrics_shared_context.rb
+ - spec/support/shared_contexts/services/projects/container_repository/delete_tags_service_shared_context.rb
+ - spec/support/shared_examples/controllers/githubish_import_controller_shared_examples.rb
+ - spec/support/shared_examples/controllers/snippets_sort_order_shared_examples.rb
+ - spec/support/shared_examples/graphql/mutations/http_integrations_shared_examples.rb
+ - spec/support/shared_examples/lib/gitlab/config/inheritable_shared_examples.rb
+ - spec/support/shared_examples/lib/gitlab/diff_file_collections_shared_examples.rb
+ - spec/support/shared_examples/metrics/active_record_subscriber_shared_examples.rb
+ - spec/support/shared_examples/metrics/sampler_shared_examples.rb
+ - spec/support/shared_examples/models/chat_integration_shared_examples.rb
+ - spec/support/shared_examples/models/concerns/integrations/slack_mattermost_notifier_shared_examples.rb
+ - spec/support/shared_examples/models/members_notifications_shared_example.rb
+ - spec/support/shared_examples/models/project_ci_cd_settings_shared_examples.rb
+ - spec/support/shared_examples/namespaces/hierarchy_examples.rb
+ - spec/support/shared_examples/requests/api/composer_packages_shared_examples.rb
+ - spec/support/shared_examples/requests/api/conan_packages_shared_examples.rb
+ - spec/support/shared_examples/requests/api/debian_common_shared_examples.rb
+ - spec/support/shared_examples/requests/api/nuget_endpoints_shared_examples.rb
+ - spec/support/shared_examples/requests/api/nuget_packages_shared_examples.rb
+ - spec/support/shared_examples/requests/api/pypi_packages_shared_examples.rb
+ - spec/support/shared_examples/requests/api/rubygems_packages_shared_examples.rb
+ - spec/support/shared_examples/requests/rack_attack_shared_examples.rb
+ - spec/support/shared_examples/serializers/diff_file_entity_shared_examples.rb
+ - spec/support/shared_examples/serializers/environment_serializer_shared_examples.rb
+ - spec/support/shared_examples/services/alert_management/alert_processing/alert_firing_shared_examples.rb
+ - spec/support/shared_examples/services/alert_management/alert_processing/notifications_shared_examples.rb
+ - spec/support/shared_examples/services/alert_management_shared_examples.rb
+ - spec/support/shared_examples/services/boards/issues_move_service_shared_examples.rb
+ - spec/support/shared_examples/services/check_ingress_ip_address_service_shared_examples.rb
+ - spec/support/shared_examples/services/jira/requests/base_shared_examples.rb
+ - spec/support/shared_examples/services/metrics/dashboard_shared_examples.rb
+ - spec/support/shared_examples/services/projects/update_repository_storage_service_shared_examples.rb
+ - spec/support/shared_examples/services/resource_events/synthetic_notes_builder_shared_examples.rb
+ - spec/support/shared_examples/workers/background_migration_worker_shared_examples.rb
+ - spec/support/shared_examples/workers/update_repository_move_shared_examples.rb
+ - spec/tasks/gettext_rake_spec.rb
+ - spec/tasks/gitlab/background_migrations_rake_spec.rb
+ - spec/tasks/gitlab/check_rake_spec.rb
+ - spec/tasks/gitlab/cleanup_rake_spec.rb
+ - spec/tasks/gitlab/db_rake_spec.rb
+ - spec/tasks/gitlab/packages/events_rake_spec.rb
+ - spec/tasks/gitlab/setup_rake_spec.rb
+ - spec/tooling/danger/project_helper_spec.rb
+ - spec/tooling/danger/specs_spec.rb
+ - spec/tooling/lib/tooling/helm3_client_spec.rb
+ - spec/tooling/lib/tooling/kubernetes_client_spec.rb
+ - spec/tooling/rspec_flaky/example_spec.rb
+ - spec/tooling/rspec_flaky/listener_spec.rb
+ - spec/uploaders/file_uploader_spec.rb
+ - spec/uploaders/object_storage_spec.rb
+ - spec/uploaders/personal_file_uploader_spec.rb
+ - spec/uploaders/records_uploads_spec.rb
+ - spec/views/projects/issues/show.html.haml_spec.rb
+ - spec/views/shared/milestones/_issuables.html.haml_spec.rb
+ - spec/views/shared/wikis/_sidebar.html.haml_spec.rb
+ - spec/workers/bulk_imports/export_request_worker_spec.rb
+ - spec/workers/bulk_imports/pipeline_worker_spec.rb
+ - spec/workers/chat_notification_worker_spec.rb
+ - spec/workers/ci/build_prepare_worker_spec.rb
+ - spec/workers/ci/create_cross_project_pipeline_worker_spec.rb
+ - spec/workers/ci/create_downstream_pipeline_worker_spec.rb
+ - spec/workers/ci/pipeline_bridge_status_worker_spec.rb
+ - spec/workers/ci/pipeline_success_unlock_artifacts_worker_spec.rb
+ - spec/workers/ci/ref_delete_unlock_artifacts_worker_spec.rb
+ - spec/workers/clusters/agents/delete_expired_events_worker_spec.rb
+ - spec/workers/concerns/application_worker_spec.rb
+ - spec/workers/concerns/gitlab/github_import/object_importer_spec.rb
+ - spec/workers/concerns/gitlab/github_import/stage_methods_spec.rb
+ - spec/workers/container_expiration_policies/cleanup_container_repository_worker_spec.rb
+ - spec/workers/create_commit_signature_worker_spec.rb
+ - spec/workers/environments/auto_stop_worker_spec.rb
+ - spec/workers/error_tracking_issue_link_worker_spec.rb
+ - spec/workers/gitlab/github_import/advance_stage_worker_spec.rb
+ - spec/workers/gitlab/github_import/import_diff_note_worker_spec.rb
+ - spec/workers/gitlab/github_import/import_issue_worker_spec.rb
+ - spec/workers/gitlab/github_import/import_note_worker_spec.rb
+ - spec/workers/gitlab/github_import/import_pull_request_worker_spec.rb
+ - spec/workers/gitlab/github_import/stage/finish_import_worker_spec.rb
+ - spec/workers/gitlab/github_import/stage/import_base_data_worker_spec.rb
+ - spec/workers/gitlab/github_import/stage/import_issues_and_diff_notes_worker_spec.rb
+ - spec/workers/gitlab/github_import/stage/import_lfs_objects_worker_spec.rb
+ - spec/workers/gitlab/github_import/stage/import_notes_worker_spec.rb
+ - spec/workers/gitlab/github_import/stage/import_pull_requests_merged_by_worker_spec.rb
+ - spec/workers/gitlab/github_import/stage/import_pull_requests_reviews_worker_spec.rb
+ - spec/workers/gitlab/github_import/stage/import_pull_requests_worker_spec.rb
+ - spec/workers/gitlab/github_import/stage/import_repository_worker_spec.rb
+ - spec/workers/gitlab_performance_bar_stats_worker_spec.rb
+ - spec/workers/invalid_gpg_signature_update_worker_spec.rb
+ - spec/workers/irker_worker_spec.rb
+ - spec/workers/issue_rebalancing_worker_spec.rb
+ - spec/workers/issues/rebalancing_worker_spec.rb
+ - spec/workers/merge_request_mergeability_check_worker_spec.rb
+ - spec/workers/new_issue_worker_spec.rb
+ - spec/workers/new_merge_request_worker_spec.rb
+ - spec/workers/pages_domain_ssl_renewal_worker_spec.rb
+ - spec/workers/pages_domain_verification_worker_spec.rb
+ - spec/workers/post_receive_spec.rb
+ - spec/workers/project_cache_worker_spec.rb
+ - spec/workers/propagate_integration_group_worker_spec.rb
+ - spec/workers/propagate_integration_inherit_descendant_worker_spec.rb
+ - spec/workers/propagate_integration_inherit_worker_spec.rb
+ - spec/workers/propagate_integration_project_worker_spec.rb
+ - spec/workers/purge_dependency_proxy_cache_worker_spec.rb
+ - spec/workers/repository_import_worker_spec.rb
+ - spec/workers/system_hook_push_worker_spec.rb
+ -
diff --git a/.rubocop_todo/style/open_struct_use.yml b/.rubocop_todo/style/open_struct_use.yml
index 80239770db0..c459ea9d49c 100644
--- a/.rubocop_todo/style/open_struct_use.yml
+++ b/.rubocop_todo/style/open_struct_use.yml
@@ -21,7 +21,6 @@ Style/OpenStructUse:
- spec/graphql/mutations/commits/create_spec.rb
- spec/helpers/application_settings_helper_spec.rb
- spec/helpers/profiles_helper_spec.rb
- - spec/lib/gitlab/auth/o_auth/provider_spec.rb
- spec/lib/gitlab/gitaly_client/blobs_stitcher_spec.rb
- spec/lib/gitlab/gitaly_client/diff_stitcher_spec.rb
- spec/lib/gitlab/legacy_github_import/project_creator_spec.rb
diff --git a/CHANGELOG.md b/CHANGELOG.md
index e6ea9e5ad56..214a038f31c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -717,6 +717,29 @@ entry.
- [Use `ssh_data` gem instead of `net-ssh` and `sshkey` where possible](gitlab-org/gitlab@59a0ee8605d509753c9aec719f8e0da77bcc679d) ([merge request](gitlab-org/gitlab!77424))
- [Remove feature flag already default enabled](gitlab-org/gitlab@9b7059a4bf9dc2ecdce1910a931cc6967d05b5ad) ([merge request](gitlab-org/gitlab!78238)) **GitLab Enterprise Edition**
+## 14.7.5 (2022-03-09)
+
+### Fixed (1 change)
+
+- [Ensure cleanup job artifacts task does not include pipeline artifacts](gitlab-org/gitlab@7b5e91bc78c46109e48537b20239d4ab649a971a) ([merge request](gitlab-org/gitlab!82430))
+
+### Other (1 change)
+
+- [Change to truncate table before adding finding_link_url_idx](gitlab-org/gitlab@6411ec61f40cb8648cea24ed26c1d69c8b910891) ([merge request](gitlab-org/gitlab!82430))
+
+## 14.7.4 (2022-02-25)
+
+### Security (8 changes)
+
+- [Limit commands_changes to certain keys](gitlab-org/security/gitlab@59351be8d1d868e31bc849482b266e4047710eeb) ([merge request](gitlab-org/security/gitlab!2226))
+- [Add runners_token prefix to Group and Project](gitlab-org/security/gitlab@74615b7fd5359c4da7f1a3ca9052685e81e1690f) ([merge request](gitlab-org/security/gitlab!2249))
+- [Anonymous user can enumerate all users through GraphQL endpoint](gitlab-org/security/gitlab@e213dfc546020d3f88b40cdfc0f877138b0aaef5) ([merge request](gitlab-org/security/gitlab!2119))
+- [Check for unsafe characters in email addresses before sending](gitlab-org/security/gitlab@395385ffccfd9d25063531ea955b179d9bc4f0c5) ([merge request](gitlab-org/security/gitlab!2207))
+- [Warn when snippet contains unretrievable files](gitlab-org/security/gitlab@dc4b3c00284e17bcbf20ec2ae1ee7e8a7efae9b2) ([merge request](gitlab-org/security/gitlab!2204))
+- [Prevent DOS when rendering math markdown](gitlab-org/security/gitlab@f01674f210dee4c803b4850292d16412463b18e3) ([merge request](gitlab-org/security/gitlab!2200))
+- [Check permission when creating members through service](gitlab-org/security/gitlab@4f9b302511ddfaf07af8d08d848252e0c64ff307) ([merge request](gitlab-org/security/gitlab!2210))
+- [Reset password field on page load](gitlab-org/security/gitlab@1a6541462e1ddd58ea9a172fbd3c0b9026760784) ([merge request](gitlab-org/security/gitlab!2193))
+
## 14.7.3 (2022-02-15)
### Fixed (2 changes)
@@ -1192,6 +1215,27 @@ See https://about.gitlab.com/releases/2022/02/03/security-release-gitlab-14-7-1-
- [Fix Gitlab/DelegatePredicateMethods offenses](gitlab-org/gitlab@518700a11025b0000ff3ce011638417a882612b0) by @edith007 ([merge request](gitlab-org/gitlab!76001))
- [Fix Rails/SaveBang offenses](gitlab-org/gitlab@513b0e1dbdf95ea595e7548ff26929e0be30ce29) by @edith007 ([merge request](gitlab-org/gitlab!75894)) **GitLab Enterprise Edition**
+## 14.6.6 (2022-03-01)
+
+### Fixed (3 changes)
+
+- [Ensure cleanup job artifacts task does not include pipeline artifacts](gitlab-org/gitlab@3fc3472de8bfa971985d122573e9896b17606678) ([merge request](gitlab-org/gitlab!81885))
+- [Fix Geo checksummable check failing when file is nil](gitlab-org/gitlab@38b55f334c558377de0b1b0d7f853e62723d9791) ([merge request](gitlab-org/gitlab!81885)) **GitLab Enterprise Edition**
+- [Resolve "Imports fail in 14.5.2 fail with HTTParty::UnsupportedURIScheme error"](gitlab-org/gitlab@b7cbf0c19d9702a0db3ee9a8f8897df5d7da72f1) ([merge request](gitlab-org/gitlab!81885))
+
+## 14.6.5 (2022-02-25)
+
+### Security (8 changes)
+
+- [Limit commands_changes to certain keys](gitlab-org/security/gitlab@138c437f2819d62ce4750fb84399d8868c844b01) ([merge request](gitlab-org/security/gitlab!2227))
+- [Add runners_token prefix to Group and Project](gitlab-org/security/gitlab@682d4e9b63d3d36901638edc75c1b265460d42dc) ([merge request](gitlab-org/security/gitlab!2250))
+- [Anonymous user can enumerate all users through GraphQL endpoint](gitlab-org/security/gitlab@2b00a8036b291d3ad5de551a5e13c2a0a39d0234) ([merge request](gitlab-org/security/gitlab!2102))
+- [Check for unsafe characters in email addresses before sending](gitlab-org/security/gitlab@6bc653b3dadefb3d2c80823786d43e6b7f8c4620) ([merge request](gitlab-org/security/gitlab!2208))
+- [Warn when snippet contains unretrievable files](gitlab-org/security/gitlab@f9ae9515ec98ab934f4aa3a35af0aca806bbe21d) ([merge request](gitlab-org/security/gitlab!2203))
+- [Prevent DOS when rendering math markdown](gitlab-org/security/gitlab@fd6d496df6f4b5eb3da0b851f9ff8ebb1d68d3f2) ([merge request](gitlab-org/security/gitlab!2201))
+- [Check permission when creating members through service](gitlab-org/security/gitlab@948e5103285de2a6cdb5152ff2c13ae4db2f4cda) ([merge request](gitlab-org/security/gitlab!2211))
+- [Reset password field on page load](gitlab-org/security/gitlab@1417b463f2771a4b17e068dea9de3aa6c4540962) ([merge request](gitlab-org/security/gitlab!2194))
+
## 14.6.4 (2022-02-03)
### Security
diff --git a/Dangerfile b/Dangerfile
index ca729f1b941..aaa1aae813b 100644
--- a/Dangerfile
+++ b/Dangerfile
@@ -24,24 +24,3 @@ return if helper.release_automation?
project_helper.rule_names.each do |rule|
danger.import_dangerfile(path: File.join('danger', rule))
end
-
-anything_to_post = status_report.values.any? { |data| data.any? }
-
-return unless helper.ci?
-
-def post_labels
- gitlab.api.update_merge_request(gitlab.mr_json['project_id'],
- gitlab.mr_json['iid'],
- add_labels: project_helper.labels_to_add.join(','))
-rescue Gitlab::Error::Forbidden
- labels = project_helper.labels_to_add.map { |label| %Q(~"#{label}") }
- warn("This Merge Request needs to be labelled with #{labels.join(' ')}. Please request a reviewer or maintainer to add them.")
-end
-
-if project_helper.labels_to_add.any?
- post_labels
-end
-
-if 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 5678d9d16ea..99cda256539 100644
--- a/GITALY_SERVER_VERSION
+++ b/GITALY_SERVER_VERSION
@@ -1 +1 @@
-14.8.4 \ No newline at end of file
+442277b91f5aa2822d52b810fd462a41c6cf5a0a
diff --git a/GITLAB_KAS_VERSION b/GITLAB_KAS_VERSION
index 6ebe0c0b057..44a5e718d50 100644
--- a/GITLAB_KAS_VERSION
+++ b/GITLAB_KAS_VERSION
@@ -1 +1 @@
-14.8.1
+14.9.0
diff --git a/GITLAB_PAGES_VERSION b/GITLAB_PAGES_VERSION
index b7921ae87bc..3ebf789f5a8 100644
--- a/GITLAB_PAGES_VERSION
+++ b/GITLAB_PAGES_VERSION
@@ -1 +1 @@
-1.54.0
+1.56.0
diff --git a/GITLAB_SHELL_VERSION b/GITLAB_SHELL_VERSION
index bb133229025..7e13e2ba8d4 100644
--- a/GITLAB_SHELL_VERSION
+++ b/GITLAB_SHELL_VERSION
@@ -1 +1 @@
-13.23.2
+13.24.0
diff --git a/Gemfile b/Gemfile
index 518c6d8cc53..ed18ae38318 100644
--- a/Gemfile
+++ b/Gemfile
@@ -11,6 +11,8 @@ gem 'responders', '~> 3.0'
gem 'sprockets', '~> 3.7.0'
+gem 'view_component', '~> 2.50.0'
+
# Default values for AR models
gem 'default_value_for', '~> 3.4.0'
@@ -153,7 +155,7 @@ gem 'html-pipeline', '~> 2.13.2'
gem 'deckar01-task_list', '2.3.1'
gem 'gitlab-markup', '~> 1.8.0'
gem 'github-markup', '~> 1.7.0', require: 'github/markup'
-gem 'commonmarker', '~> 0.23.2'
+gem 'commonmarker', '~> 0.23.4'
gem 'kramdown', '~> 2.3.1'
gem 'RedCloth', '~> 4.3.2'
gem 'rdoc', '~> 6.3.2'
@@ -290,7 +292,7 @@ gem 'autoprefixer-rails', '10.2.5.1'
gem 'terser', '1.0.2'
gem 'addressable', '~> 2.8'
-gem 'tanuki_emoji', '~> 0.5'
+gem 'tanuki_emoji', '~> 0.6'
gem 'gon', '~> 6.4.0'
gem 'request_store', '~> 1.5'
gem 'base32', '~> 0.3.0'
@@ -302,6 +304,9 @@ gem 'rack-attack', '~> 6.3.0'
# Sentry integration
gem 'sentry-raven', '~> 3.1'
+gem 'sentry-ruby', '~> 5.1.1'
+gem 'sentry-rails', '~> 5.1.1'
+gem 'sentry-sidekiq', '~> 5.1.1'
# PostgreSQL query parsing
#
@@ -374,7 +379,7 @@ group :development, :test do
gem 'spring', '~> 2.1.0'
gem 'spring-commands-rspec', '~> 1.0.4'
- gem 'gitlab-styles', '~> 6.6.0', require: false
+ gem 'gitlab-styles', '~> 7.0.0', require: false
gem 'haml_lint', '~> 0.36.0', require: false
gem 'bundler-audit', '~> 0.7.0.1', require: false
@@ -393,14 +398,16 @@ group :development, :test do
gem 'parallel', '~> 1.19', require: false
gem 'test_file_finder', '~> 0.1.3'
+
+ gem 'sigdump', '~> 0.2.4', require: 'sigdump/setup'
end
group :development, :test, :danger do
- gem 'gitlab-dangerfiles', '~> 2.8.0', require: false
+ gem 'gitlab-dangerfiles', '~> 2.11.0', require: false
end
group :development, :test, :coverage do
- gem 'simplecov', '~> 0.18.5', require: false
+ gem 'simplecov', '~> 0.21', require: false
gem 'simplecov-lcov', '~> 0.8.0', require: false
gem 'simplecov-cobertura', '~> 1.3.1', require: false
gem 'undercover', '~> 0.4.4', require: false
@@ -418,6 +425,7 @@ group :test do
gem 'fuubar', '~> 2.2.0'
gem 'rspec-retry', '~> 0.6.1'
gem 'rspec_profiling', '~> 0.0.6'
+ gem 'rspec-benchmark', '~> 0.6.0'
gem 'rspec-parameterized', require: false
gem 'capybara', '~> 3.35.3'
@@ -473,7 +481,7 @@ gem 'ssh_data', '~> 1.2'
gem 'spamcheck', '~> 0.1.0'
# Gitaly GRPC protocol definitions
-gem 'gitaly', '~> 14.8.0.pre.rc1'
+gem 'gitaly', '~> 14.9.0.pre.rc4'
# KAS GRPC protocol definitions
gem 'kas-grpc', '~> 0.0.2'
@@ -534,4 +542,4 @@ gem 'ipaddress', '~> 0.8.3'
gem 'parslet', '~> 1.8'
-gem 'ipynbdiff', '0.3.8'
+gem 'ipynbdiff', '0.4.4'
diff --git a/Gemfile.lock b/Gemfile.lock
index 71fe578b921..2b0057d353d 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -139,8 +139,11 @@ GEM
bcrypt (3.1.16)
benchmark (0.1.1)
benchmark-ips (2.3.0)
+ benchmark-malloc (0.2.0)
benchmark-memory (0.1.2)
memory_profiler (~> 0.9)
+ benchmark-perf (0.6.0)
+ benchmark-trend (0.4.0)
better_errors (2.9.1)
coderay (>= 1.0.0)
erubi (>= 1.0.0)
@@ -199,7 +202,7 @@ GEM
open4 (~> 1.3)
coderay (1.1.3)
colored2 (3.1.2)
- commonmarker (0.23.2)
+ commonmarker (0.23.4)
concurrent-ruby (1.1.9)
connection_pool (2.2.5)
contracts (0.11.0)
@@ -221,7 +224,7 @@ GEM
css_parser (1.7.0)
addressable
daemons (1.3.1)
- danger (8.4.2)
+ danger (8.4.5)
claide (~> 1.0)
claide-plugins (>= 0.9.2)
colored2 (~> 3.1)
@@ -238,6 +241,7 @@ GEM
danger
gitlab (~> 4.2, >= 4.2.0)
database_cleaner (1.7.0)
+ dead_end (3.1.1)
deckar01-task_list (2.3.1)
html-pipeline
declarative (0.0.20)
@@ -247,13 +251,15 @@ GEM
activerecord (>= 3.2.0, < 7.0)
deprecation_toolkit (1.5.1)
activesupport (>= 4.2)
- derailed_benchmarks (1.8.1)
+ derailed_benchmarks (2.1.1)
benchmark-ips (~> 2)
+ dead_end
get_process_mem (~> 0)
heapy (~> 0)
- memory_profiler (~> 0)
- mini_histogram (>= 0.2.1)
+ memory_profiler (>= 0, < 2)
+ mini_histogram (>= 0.3.0)
rack (>= 1)
+ rack-test
rake (> 10, < 14)
ruby-statistics (>= 2.1)
thor (>= 0.19, < 2)
@@ -275,7 +281,7 @@ GEM
diffy (3.3.0)
discordrb-webhooks (3.4.2)
rest-client (>= 2.0.0)
- docile (1.3.2)
+ docile (1.4.0)
domain_name (0.5.20190701)
unf (>= 0.0.5, < 1.0.0)
doorkeeper (5.5.0.rc2)
@@ -372,7 +378,7 @@ GEM
fast_blank (1.0.0)
fast_gettext (2.1.0)
ffaker (2.10.0)
- ffi (1.15.3)
+ ffi (1.15.5)
ffi-compiler (1.0.1)
ffi (>= 1.0.0)
rake
@@ -435,7 +441,7 @@ GEM
ruby-progressbar (~> 1.4)
fuzzyurl (0.9.0)
gemoji (3.0.1)
- get_process_mem (0.2.5)
+ get_process_mem (0.2.7)
ffi (~> 1.0)
gettext (3.3.6)
locale (>= 2.0.5)
@@ -449,7 +455,7 @@ GEM
rails (>= 3.2.0)
git (1.7.0)
rchardet (~> 1.8)
- gitaly (14.8.0.pre.rc1)
+ gitaly (14.9.0.pre.rc4)
grpc (~> 1.0)
github-markup (1.7.0)
gitlab (4.16.1)
@@ -457,8 +463,8 @@ GEM
terminal-table (~> 1.5, >= 1.5.1)
gitlab-chronic (0.10.5)
numerizer (~> 0.2)
- gitlab-dangerfiles (2.8.0)
- danger (>= 8.3.1)
+ gitlab-dangerfiles (2.11.0)
+ danger (>= 8.4.5)
danger-gitlab (>= 8.0.0)
gitlab-experiment (0.7.0)
activesupport (>= 3.0)
@@ -495,7 +501,7 @@ GEM
openid_connect (~> 1.2)
gitlab-sidekiq-fetcher (0.8.0)
sidekiq (~> 6.1)
- gitlab-styles (6.6.0)
+ gitlab-styles (7.0.0)
rubocop (~> 0.91, >= 0.91.1)
rubocop-gitlab-security (~> 0.1.1)
rubocop-graphql (~> 0.10)
@@ -639,7 +645,7 @@ GEM
mime-types (~> 3.0)
multi_xml (>= 0.5.2)
httpclient (2.8.3)
- i18n (1.9.1)
+ i18n (1.10.0)
concurrent-ruby (~> 1.0)
i18n_data (0.8.0)
icalendar (2.4.1)
@@ -648,9 +654,9 @@ GEM
invisible_captcha (1.1.0)
rails (>= 4.2)
ipaddress (0.8.3)
- ipynbdiff (0.3.8)
- diffy (= 3.3.0)
- json (= 2.5.1)
+ ipynbdiff (0.4.4)
+ diffy (~> 3.3)
+ json (~> 2.5, >= 2.5.1)
jaeger-client (1.1.0)
opentracing (~> 0.3)
thrift
@@ -1059,6 +1065,11 @@ GEM
rspec-core (~> 3.10.0)
rspec-expectations (~> 3.10.0)
rspec-mocks (~> 3.10.0)
+ rspec-benchmark (0.6.0)
+ benchmark-malloc (~> 0.2)
+ benchmark-perf (~> 0.6)
+ benchmark-trend (~> 0.4)
+ rspec (>= 3.0)
rspec-core (3.10.1)
rspec-support (~> 3.10.0)
rspec-expectations (3.10.1)
@@ -1104,7 +1115,7 @@ GEM
parser (>= 2.7.1.5)
rubocop-gitlab-security (0.1.1)
rubocop (>= 0.51)
- rubocop-graphql (0.10.3)
+ rubocop-graphql (0.13.0)
rubocop (>= 0.87, < 2)
rubocop-performance (1.9.2)
rubocop (>= 0.90.0, < 2.0)
@@ -1125,7 +1136,7 @@ GEM
ruby-saml (1.13.0)
nokogiri (>= 1.10.5)
rexml
- ruby-statistics (2.1.2)
+ ruby-statistics (3.0.0)
ruby2_keywords (0.0.4)
ruby_parser (3.15.0)
sexp_processor (~> 4.9)
@@ -1163,8 +1174,19 @@ GEM
selenium-webdriver (3.142.7)
childprocess (>= 0.5, < 4.0)
rubyzip (>= 1.2.2)
+ sentry-rails (5.1.1)
+ railties (>= 5.0)
+ sentry-ruby-core (~> 5.1.1)
sentry-raven (3.1.2)
faraday (>= 1.0)
+ sentry-ruby (5.1.1)
+ concurrent-ruby (~> 1.0, >= 1.0.2)
+ sentry-ruby-core (= 5.1.1)
+ sentry-ruby-core (5.1.1)
+ concurrent-ruby
+ sentry-sidekiq (5.1.1)
+ sentry-ruby-core (~> 5.1.1)
+ sidekiq (>= 3.0)
set (1.0.1)
settingslogic (2.0.9)
sexp_processor (4.15.1)
@@ -1178,19 +1200,22 @@ GEM
sidekiq-cron (1.2.0)
fugit (~> 1.1)
sidekiq (>= 4.2.1)
+ sigdump (0.2.4)
signet (0.14.0)
addressable (~> 2.3)
faraday (>= 0.17.3, < 2.0)
jwt (>= 1.5, < 3.0)
multi_json (~> 1.10)
simple_po_parser (1.1.2)
- simplecov (0.18.5)
+ simplecov (0.21.2)
docile (~> 1.1)
simplecov-html (~> 0.11)
+ simplecov_json_formatter (~> 0.1)
simplecov-cobertura (1.3.1)
simplecov (~> 0.8)
simplecov-html (0.12.3)
simplecov-lcov (0.8.0)
+ simplecov_json_formatter (0.1.4)
sixarm_ruby_unaccent (1.2.0)
slack-messenger (2.3.4)
snowplow-tracker (0.6.1)
@@ -1249,7 +1274,7 @@ GEM
sys-filesystem (1.4.3)
ffi (~> 1.1)
sysexits (1.2.0)
- tanuki_emoji (0.5.0)
+ tanuki_emoji (0.6.0)
temple (0.8.2)
terminal-table (1.8.0)
unicode-display_width (~> 1.1, >= 1.1.1)
@@ -1263,7 +1288,7 @@ GEM
daemons (~> 1.0, >= 1.0.9)
eventmachine (~> 1.0, >= 1.0.4)
rack (>= 1, < 3)
- thor (1.1.0)
+ thor (1.2.1)
thrift (0.14.0)
tilt (2.0.10)
timecop (0.9.1)
@@ -1337,6 +1362,9 @@ GEM
activerecord (>= 3.0)
activesupport (>= 3.0)
version_sorter (2.2.4)
+ view_component (2.50.0)
+ activesupport (>= 5.0.0, < 8.0)
+ method_source (~> 1.0)
vmstat (2.3.0)
warden (1.2.8)
rack (>= 2.0.6)
@@ -1415,7 +1443,7 @@ DEPENDENCIES
capybara-screenshot (~> 1.0.22)
carrierwave (~> 1.3)
charlock_holmes (~> 0.7.7)
- commonmarker (~> 0.23.2)
+ commonmarker (~> 0.23.4)
concurrent-ruby (~> 1.1)
connection_pool (~> 2.0)
countries (~> 3.0)
@@ -1463,10 +1491,10 @@ DEPENDENCIES
gettext (~> 3.3)
gettext_i18n_rails (~> 1.8.0)
gettext_i18n_rails_js (~> 1.3)
- gitaly (~> 14.8.0.pre.rc1)
+ gitaly (~> 14.9.0.pre.rc4)
github-markup (~> 1.7.0)
gitlab-chronic (~> 0.10.5)
- gitlab-dangerfiles (~> 2.8.0)
+ gitlab-dangerfiles (~> 2.11.0)
gitlab-experiment (~> 0.7.0)
gitlab-fog-azure-rm (~> 1.2.0)
gitlab-labkit (~> 0.22.0)
@@ -1477,7 +1505,7 @@ DEPENDENCIES
gitlab-net-dns (~> 0.9.1)
gitlab-omniauth-openid-connect (~> 0.9.0)
gitlab-sidekiq-fetcher (= 0.8.0)
- gitlab-styles (~> 6.6.0)
+ gitlab-styles (~> 7.0.0)
gitlab_chronic_duration (~> 0.10.6.2)
gitlab_omniauth-ldap (~> 2.1.1)
gon (~> 6.4.0)
@@ -1507,7 +1535,7 @@ DEPENDENCIES
icalendar
invisible_captcha (~> 1.1.0)
ipaddress (~> 0.8.3)
- ipynbdiff (= 0.3.8)
+ ipynbdiff (= 0.4.4)
jira-ruby (~> 2.1.4)
js_regex (~> 3.7)
json (~> 2.5.1)
@@ -1596,6 +1624,7 @@ DEPENDENCIES
rexml (~> 3.2.5)
rouge (~> 3.27.0)
rqrcode-rails3 (~> 0.1.7)
+ rspec-benchmark (~> 0.6.0)
rspec-parameterized
rspec-rails (~> 5.0.1)
rspec-retry (~> 0.6.1)
@@ -1614,13 +1643,17 @@ DEPENDENCIES
sd_notify (~> 0.1.0)
seed-fu (~> 2.3.7)
selenium-webdriver (~> 3.142)
+ sentry-rails (~> 5.1.1)
sentry-raven (~> 3.1)
+ sentry-ruby (~> 5.1.1)
+ sentry-sidekiq (~> 5.1.1)
settingslogic (~> 2.0.9)
shoulda-matchers (~> 4.0.1)
sidekiq (~> 6.4)
sidekiq-cron (~> 1.2)
+ sigdump (~> 0.2.4)
simple_po_parser (~> 1.1.2)
- simplecov (~> 0.18.5)
+ simplecov (~> 0.21)
simplecov-cobertura (~> 1.3.1)
simplecov-lcov (~> 0.8.0)
slack-messenger (~> 2.3.4)
@@ -1635,7 +1668,7 @@ DEPENDENCIES
stackprof (~> 0.2.15)
state_machines-activerecord (~> 0.8.0)
sys-filesystem (~> 1.4.3)
- tanuki_emoji (~> 0.5)
+ tanuki_emoji (~> 0.6)
terser (= 1.0.2)
test-prof (~> 1.0.7)
test_file_finder (~> 0.1.3)
@@ -1652,6 +1685,7 @@ DEPENDENCIES
valid_email (~> 0.1)
validates_hostname (~> 1.0.11)
version_sorter (~> 2.2.4)
+ view_component (~> 2.50.0)
vmstat (~> 2.3.0)
warning (~> 1.2.0)
webauthn (~> 2.3)
diff --git a/Rakefile b/Rakefile
index eb2f158972d..9545516d2a9 100755
--- a/Rakefile
+++ b/Rakefile
@@ -11,6 +11,8 @@ require File.expand_path('config/application', __dir__)
relative_url_conf = File.expand_path('config/initializers/relative_url', __dir__)
require relative_url_conf if File.exist?("#{relative_url_conf}.rb")
+require File.expand_path('config/initializers/01_active_record_database_tasks_configuration_flag.rb', __dir__)
+
Gitlab::Application.load_tasks
Knapsack.load_tasks if defined?(Knapsack)
diff --git a/app/assets/images/aws-cloud-formation.png b/app/assets/images/aws-cloud-formation.png
deleted file mode 100644
index 1d078309d86..00000000000
--- a/app/assets/images/aws-cloud-formation.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/vulnerability/kontra-logo.svg b/app/assets/images/vulnerability/kontra-logo.svg
new file mode 100644
index 00000000000..e12e2545e77
--- /dev/null
+++ b/app/assets/images/vulnerability/kontra-logo.svg
@@ -0,0 +1 @@
+<svg enable-background="new 0 0 50 50" viewBox="0 0 50 50" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="a" gradientUnits="userSpaceOnUse" x1="10.2941" x2="50" y1="17.8247" y2="17.8247"><stop offset="0" stop-color="#f39c63"/><stop offset="1" stop-color="#ef5d4f"/></linearGradient><linearGradient id="b"><stop offset="0" stop-color="#231c4f"/><stop offset="1" stop-color="#0a0430"/></linearGradient><linearGradient id="c" gradientUnits="userSpaceOnUse" x1="16.9118" x2="25" xlink:href="#b" y1="27.2046" y2="27.2046"/><linearGradient id="d" gradientUnits="userSpaceOnUse" x1="27.9412" x2="33.0882" xlink:href="#b" y1="22.0575" y2="22.0575"/><g clip-rule="evenodd" fill-rule="evenodd"><path d="m31.94 41.71-31.94 8.41v-21.23c0-4.73 3.19-8.87 7.77-10.07l19.29-5.08c6.4-1.68 12.65 3.14 12.65 9.75v8.14c0 4.74-3.19 8.88-7.77 10.08z" fill="#2b6af9"/><path d="m50 0v21.23c0 4.73-3.19 8.87-7.77 10.07l-14.79 3.89c-8.67 2.28-17.15-4.26-17.15-13.22v-3.49c0-4.73 3.19-8.87 7.77-10.07z" fill="url(#a)"/><path d="m23.36 36.33 16.35-4.3v-8.16c0-6.83-6.46-11.81-13.06-10.07l-16.35 4.3v8.16c-.01 6.82 6.45 11.8 13.06 10.07z" fill="#fff"/><circle cx="20.96" cy="27.2" fill="url(#c)" r="4.04"/><circle cx="30.51" cy="22.06" fill="url(#d)" r="2.57"/></g></svg> \ No newline at end of file
diff --git a/app/assets/images/vulnerability/scw-logo.svg b/app/assets/images/vulnerability/scw-logo.svg
new file mode 100644
index 00000000000..6d160ddc495
--- /dev/null
+++ b/app/assets/images/vulnerability/scw-logo.svg
@@ -0,0 +1 @@
+<svg enable-background="new 0 0 0 0" viewBox="0 0 800 780" xmlns="http://www.w3.org/2000/svg"><path d="m594.4 737.87c-.75-1.93-1.86-3.7-3.34-5.29-1.48-1.6-3.29-2.86-5.44-3.8-2.15-.93-4.62-1.4-7.41-1.4s-5.26.47-7.41 1.4c-2.14.94-3.96 2.21-5.43 3.8-1.48 1.59-2.59 3.36-3.34 5.29s-1.13 3.91-1.13 5.95v.96c0 1.96.36 3.91 1.1 5.86.73 1.96 1.82 3.74 3.28 5.35s3.27 2.91 5.43 3.89c2.17.98 4.67 1.46 7.5 1.46s5.33-.49 7.5-1.46c2.16-.98 3.98-2.28 5.43-3.89 1.46-1.61 2.55-3.4 3.28-5.35s1.1-3.91 1.1-5.86v-.96c.01-2.04-.37-4.02-1.12-5.95zm-4.01 13.45c-1.15 2.1-2.78 3.77-4.86 5.02-2.09 1.25-4.52 1.89-7.32 1.89-2.79 0-5.24-.63-7.32-1.89-2.09-1.25-3.71-2.93-4.86-5.02s-1.73-4.42-1.73-6.97c0-2.63.58-4.99 1.73-7.09 1.15-2.09 2.77-3.74 4.86-4.96 2.08-1.21 4.52-1.82 7.32-1.82 2.79 0 5.23.61 7.32 1.82 2.08 1.22 3.71 2.87 4.86 4.96 1.15 2.1 1.73 4.46 1.73 7.09 0 2.56-.58 4.88-1.73 6.97z" fill="#f79200"/><path d="m584.11 746.03c1.42-1.12 2.12-2.73 2.12-4.84s-.71-3.73-2.12-4.85c-1.42-1.11-3.4-1.67-5.95-1.67h-2.55-2.37-2.12v18.66h4.49v-5.62h2.55c.09 0 .17-.01.25-.01l3.81 5.64h5.1l-4.69-6.45c.54-.25 1.04-.52 1.48-.86zm-8.5-7.6h2.85c1.1 0 1.9.23 2.43.69s.79 1.15.79 2.07-.26 1.6-.79 2.06-1.33.68-2.43.68h-2.85z" fill="#f79200"/><path d="m333.8 753.41-17.62 7.9v-88.45s76.18-50.47 93.76-64.21c46.25-36.15 101.39-92.54 101.39-155.86v-22.33l40.76-32.62h-235.91v-83.73h280.18v138.69c0 180.72-251.84 295.81-262.56 300.61zm-17.53-638.54c21.22 2.88 121.7 20.25 195.07 97.32v62.85h85.03v-94.02l-10-11.68c-104.42-122.2-259.7-137.72-266.27-138.32l-3.92-.36v84.23c.03-.01.06-.01.09-.02z" fill="#ffbe12"/><path d="m316.18 397.85h-280.18v-216.82l9.99-11.68c104.42-122.21 259.7-137.73 266.25-138.33l3.94-.36v84.23c-21.06 2.97-122.24 20.87-195.17 97.32v74.53l-36.5 27.39h231.66v83.72zm-93.77 210.81c-46.27-36.15-101.4-87.26-101.4-143.31l20.24-28.41h-105.25v28.41c0 171.17 251.84 283.27 262.56 288.07l17.63 7.9v-88.45c-.01 0-76.2-50.47-93.78-64.21z" fill="#f79200"/></svg> \ No newline at end of file
diff --git a/app/assets/javascripts/access_tokens/components/expires_at_field.vue b/app/assets/javascripts/access_tokens/components/expires_at_field.vue
index 1fec186f2fa..561b2617c5f 100644
--- a/app/assets/javascripts/access_tokens/components/expires_at_field.vue
+++ b/app/assets/javascripts/access_tokens/components/expires_at_field.vue
@@ -1,15 +1,31 @@
<script>
-import { GlDatepicker, GlFormInput } from '@gitlab/ui';
+import { GlDatepicker, GlFormInput, GlFormGroup } from '@gitlab/ui';
+
+import { __ } from '~/locale';
export default {
name: 'ExpiresAtField',
- components: { GlDatepicker, GlFormInput },
+ i18n: {
+ label: __('Expiration date'),
+ },
+ components: {
+ GlDatepicker,
+ GlFormInput,
+ GlFormGroup,
+ MaxExpirationDateMessage: () =>
+ import('ee_component/access_tokens/components/max_expiration_date_message.vue'),
+ },
props: {
inputAttrs: {
type: Object,
required: false,
default: () => ({}),
},
+ maxDate: {
+ type: Date,
+ required: false,
+ default: () => null,
+ },
},
data() {
return {
@@ -20,13 +36,18 @@ export default {
</script>
<template>
- <gl-datepicker :target="null" :min-date="minDate">
- <gl-form-input
- v-bind="inputAttrs"
- class="datepicker gl-datepicker-input"
- autocomplete="off"
- inputmode="none"
- data-qa-selector="expiry_date_field"
- />
- </gl-datepicker>
+ <gl-form-group :label="$options.i18n.label" :label-for="inputAttrs.id">
+ <gl-datepicker :target="null" :min-date="minDate" :max-date="maxDate">
+ <gl-form-input
+ v-bind="inputAttrs"
+ class="datepicker gl-datepicker-input"
+ autocomplete="off"
+ inputmode="none"
+ data-qa-selector="expiry_date_field"
+ />
+ </gl-datepicker>
+ <template #description>
+ <max-expiration-date-message :max-date="maxDate" />
+ </template>
+ </gl-form-group>
</template>
diff --git a/app/assets/javascripts/access_tokens/components/tokens_app.vue b/app/assets/javascripts/access_tokens/components/tokens_app.vue
index 755991f64e0..10d4d62d803 100644
--- a/app/assets/javascripts/access_tokens/components/tokens_app.vue
+++ b/app/assets/javascripts/access_tokens/components/tokens_app.vue
@@ -100,6 +100,7 @@ export default {
<gl-link
:href="tokenData.resetPath"
:data-confirm="$options.i18n[tokenType].resetConfirmMessage"
+ data-confirm-btn-variant="danger"
data-method="put"
>{{ content }}</gl-link
>
diff --git a/app/assets/javascripts/access_tokens/index.js b/app/assets/javascripts/access_tokens/index.js
index 9a1e7d877f8..c59bd445539 100644
--- a/app/assets/javascripts/access_tokens/index.js
+++ b/app/assets/javascripts/access_tokens/index.js
@@ -17,6 +17,7 @@ export const initExpiresAtField = () => {
}
const { expiresAt: inputAttrs } = parseRailsFormFields(el);
+ const { maxDate } = el.dataset;
return new Vue({
el,
@@ -24,6 +25,7 @@ export const initExpiresAtField = () => {
return h(ExpiresAtField, {
props: {
inputAttrs,
+ maxDate: maxDate ? new Date(maxDate) : undefined,
},
});
},
diff --git a/app/assets/javascripts/activities.js b/app/assets/javascripts/activities.js
index 74e0e1b6225..7a78ccdb0cd 100644
--- a/app/assets/javascripts/activities.js
+++ b/app/assets/javascripts/activities.js
@@ -33,7 +33,7 @@ export default class Activities {
errorCallback: () =>
createFlash({
message: s__(
- 'Activity|An error occured while retrieving activity. Reload the page to try again.',
+ 'Activity|An error occurred while retrieving activity. Reload the page to try again.',
),
parent: this.containerEl,
}),
diff --git a/app/assets/javascripts/admin/applications/components/delete_application.vue b/app/assets/javascripts/admin/applications/components/delete_application.vue
new file mode 100644
index 00000000000..77694296b0a
--- /dev/null
+++ b/app/assets/javascripts/admin/applications/components/delete_application.vue
@@ -0,0 +1,84 @@
+<script>
+import { GlModal, GlSprintf } from '@gitlab/ui';
+import { __ } from '~/locale';
+import csrf from '~/lib/utils/csrf';
+
+export default {
+ components: {
+ GlModal,
+ GlSprintf,
+ },
+ data() {
+ return {
+ name: '',
+ path: '',
+ buttons: [],
+ };
+ },
+ mounted() {
+ this.buttons = document.querySelectorAll('.js-application-delete-button');
+
+ this.buttons.forEach((button) => button.addEventListener('click', this.buttonEvent));
+ },
+ destroy() {
+ this.buttons.forEach((button) => button.removeEventListener('click', this.buttonEvent));
+ },
+ methods: {
+ buttonEvent(e) {
+ e.preventDefault();
+ this.show(e.target.dataset);
+ },
+ show(dataset) {
+ const { name, path } = dataset;
+
+ this.name = name;
+ this.path = path;
+
+ this.$refs.deleteModal.show();
+ },
+ deleteApplication() {
+ this.$refs.deleteForm.submit();
+ },
+ },
+ i18n: {
+ destroy: __('Destroy'),
+ title: __('Confirm destroy application'),
+ body: __('Are you sure that you want to destroy %{application}'),
+ },
+ modal: {
+ actionPrimary: {
+ text: __('Destroy'),
+ attributes: {
+ variant: 'danger',
+ },
+ },
+ actionSecondary: {
+ text: __('Cancel'),
+ attributes: {
+ variant: 'default',
+ },
+ },
+ },
+ csrf,
+};
+</script>
+<template>
+ <gl-modal
+ ref="deleteModal"
+ :title="$options.i18n.title"
+ :action-primary="$options.modal.actionPrimary"
+ :action-secondary="$options.modal.actionSecondary"
+ modal-id="delete-application-modal"
+ size="sm"
+ @primary="deleteApplication"
+ ><gl-sprintf :message="$options.i18n.body">
+ <template #application>
+ <strong>{{ name }}</strong>
+ </template></gl-sprintf
+ >
+ <form ref="deleteForm" method="post" :action="path">
+ <input type="hidden" name="_method" value="delete" />
+ <input type="hidden" name="authenticity_token" :value="$options.csrf.token" />
+ </form>
+ </gl-modal>
+</template>
diff --git a/app/assets/javascripts/admin/applications/index.js b/app/assets/javascripts/admin/applications/index.js
new file mode 100644
index 00000000000..5875fd18729
--- /dev/null
+++ b/app/assets/javascripts/admin/applications/index.js
@@ -0,0 +1,15 @@
+import Vue from 'vue';
+import DeleteApplication from './components/delete_application.vue';
+
+export default () => {
+ const el = document.querySelector('.js-application-delete-modal');
+
+ if (!el) return false;
+
+ return new Vue({
+ el,
+ render(h) {
+ return h(DeleteApplication);
+ },
+ });
+};
diff --git a/app/assets/javascripts/admin/topics/components/remove_avatar.vue b/app/assets/javascripts/admin/topics/components/remove_avatar.vue
new file mode 100644
index 00000000000..5e94d6185e0
--- /dev/null
+++ b/app/assets/javascripts/admin/topics/components/remove_avatar.vue
@@ -0,0 +1,67 @@
+<script>
+import { uniqueId } from 'lodash';
+import { GlButton, GlModal, GlModalDirective } from '@gitlab/ui';
+import { __ } from '~/locale';
+import csrf from '~/lib/utils/csrf';
+
+export default {
+ components: {
+ GlButton,
+ GlModal,
+ },
+ directives: {
+ GlModal: GlModalDirective,
+ },
+ inject: ['path'],
+ data() {
+ return {
+ modalId: uniqueId('remove-topic-avatar-'),
+ };
+ },
+ methods: {
+ deleteApplication() {
+ this.$refs.deleteForm.submit();
+ },
+ },
+ i18n: {
+ remove: __('Remove avatar'),
+ title: __('Confirm remove avatar'),
+ body: __('Avatar will be removed. Are you sure?'),
+ },
+ modal: {
+ actionPrimary: {
+ text: __('Remove'),
+ attributes: {
+ variant: 'danger',
+ },
+ },
+ actionSecondary: {
+ text: __('Cancel'),
+ attributes: {
+ variant: 'default',
+ },
+ },
+ },
+ csrf,
+};
+</script>
+<template>
+ <div>
+ <gl-button v-gl-modal="modalId" variant="danger" category="secondary" class="gl-mt-2">{{
+ $options.i18n.remove
+ }}</gl-button>
+ <gl-modal
+ :title="$options.i18n.title"
+ :action-primary="$options.modal.actionPrimary"
+ :action-secondary="$options.modal.actionSecondary"
+ :modal-id="modalId"
+ size="sm"
+ @primary="deleteApplication"
+ >{{ $options.i18n.body }}
+ <form ref="deleteForm" method="post" :action="path">
+ <input type="hidden" name="_method" value="delete" />
+ <input type="hidden" name="authenticity_token" :value="$options.csrf.token" />
+ </form>
+ </gl-modal>
+ </div>
+</template>
diff --git a/app/assets/javascripts/admin/topics/index.js b/app/assets/javascripts/admin/topics/index.js
new file mode 100644
index 00000000000..8fbcadf3369
--- /dev/null
+++ b/app/assets/javascripts/admin/topics/index.js
@@ -0,0 +1,22 @@
+import Vue from 'vue';
+import RemoveAvatar from './components/remove_avatar.vue';
+
+export default () => {
+ const el = document.querySelector('.js-remove-topic-avatar');
+
+ if (!el) {
+ return false;
+ }
+
+ const { path } = el.dataset;
+
+ return new Vue({
+ el,
+ provide: {
+ path,
+ },
+ render(h) {
+ return h(RemoveAvatar);
+ },
+ });
+};
diff --git a/app/assets/javascripts/admin/users/components/user_actions.vue b/app/assets/javascripts/admin/users/components/user_actions.vue
index f5d21ece138..829174d7593 100644
--- a/app/assets/javascripts/admin/users/components/user_actions.vue
+++ b/app/assets/javascripts/admin/users/components/user_actions.vue
@@ -69,7 +69,6 @@ export default {
editButtonAttrs() {
return {
'data-testid': 'edit',
- icon: 'pencil-square',
href: this.userPaths.edit,
};
},
@@ -101,6 +100,7 @@ export default {
<gl-button
v-else
v-gl-tooltip="$options.i18n.edit"
+ icon="pencil-square"
v-bind="editButtonAttrs"
:aria-label="$options.i18n.edit"
/>
@@ -108,10 +108,9 @@ export default {
<div v-if="hasDropdownActions" class="gl-p-2">
<gl-dropdown
+ v-gl-tooltip="$options.i18n.userAdministration"
data-testid="dropdown-toggle"
- :text="$options.i18n.userAdministration"
- :text-sr-only="!showButtonLabels"
- icon="ellipsis_h"
+ icon="ellipsis_v"
data-qa-selector="user_actions_dropdown_toggle"
:data-qa-username="user.username"
no-caret
diff --git a/app/assets/javascripts/admin/users/components/user_avatar.vue b/app/assets/javascripts/admin/users/components/user_avatar.vue
index ce22595609d..dd354794cf3 100644
--- a/app/assets/javascripts/admin/users/components/user_avatar.vue
+++ b/app/assets/javascripts/admin/users/components/user_avatar.vue
@@ -27,8 +27,6 @@ export default {
return this.adminUserPath.replace('id', this.user.username);
},
adminUserMailto() {
- // NOTE: 'mailto:' is a false positive: https://gitlab.com/gitlab-org/frontend/eslint-plugin-i18n/issues/26#possible-false-positives
- // eslint-disable-next-line @gitlab/require-i18n-strings
return `mailto:${this.user.email}`;
},
userNoteShort() {
diff --git a/app/assets/javascripts/alert_management/components/alert_management_table.vue b/app/assets/javascripts/alert_management/components/alert_management_table.vue
index 84c2b216859..929f5d10956 100644
--- a/app/assets/javascripts/alert_management/components/alert_management_table.vue
+++ b/app/assets/javascripts/alert_management/components/alert_management_table.vue
@@ -12,8 +12,8 @@ import {
GlTooltipDirective,
} from '@gitlab/ui';
import getAlertsQuery from '~/graphql_shared/queries/get_alerts.query.graphql';
+import { sortObjectToString } from '~/lib/utils/table_utility';
import { fetchPolicies } from '~/lib/graphql';
-import { convertToSnakeCase } from '~/lib/utils/text_utility';
import { joinPaths, visitUrl } from '~/lib/utils/url_utility';
import { s__, __, n__ } from '~/locale';
import AlertStatus from '~/vue_shared/alert_details/components/alert_status.vue';
@@ -213,11 +213,8 @@ export default {
},
methods: {
fetchSortedData({ sortBy, sortDesc }) {
- const sortingDirection = sortDesc ? 'DESC' : 'ASC';
- const sortingColumn = convertToSnakeCase(sortBy).toUpperCase();
-
this.pagination = initialPaginationState;
- this.sort = `${sortingColumn}_${sortingDirection}`;
+ this.sort = sortObjectToString({ sortBy, sortDesc });
},
navigateToAlertDetails({ iid }, index, { metaKey }) {
return visitUrl(joinPaths(window.location.pathname, iid, 'details'), metaKey);
diff --git a/app/assets/javascripts/api.js b/app/assets/javascripts/api.js
index 8c996b448aa..35fc64d43e5 100644
--- a/app/assets/javascripts/api.js
+++ b/app/assets/javascripts/api.js
@@ -92,6 +92,7 @@ const Api = {
groupNotificationSettingsPath: '/api/:version/groups/:id/notification_settings',
notificationSettingsPath: '/api/:version/notification_settings',
deployKeysPath: '/api/:version/deploy_keys',
+ secureFilesPath: '/api/:version/projects/:project_id/secure_files',
group(groupId, callback = () => {}) {
const url = Api.buildUrl(Api.groupPath).replace(':id', groupId);
@@ -957,6 +958,13 @@ const Api = {
return axios.get(url, { params: { per_page: DEFAULT_PER_PAGE, ...params } });
},
+ // TODO: replace this when GraphQL support has been added https://gitlab.com/gitlab-org/gitlab/-/issues/352184
+ projectSecureFiles(projectId, options = {}) {
+ const url = Api.buildUrl(this.secureFilesPath).replace(':project_id', projectId);
+
+ return axios.get(url, { params: { per_page: DEFAULT_PER_PAGE, ...options } });
+ },
+
async updateNotificationSettings(projectId, groupId, data = {}) {
let url = Api.buildUrl(this.notificationSettingsPath);
diff --git a/app/assets/javascripts/attention_requests/components/navigation_popover.vue b/app/assets/javascripts/attention_requests/components/navigation_popover.vue
new file mode 100644
index 00000000000..1542bc9a7e9
--- /dev/null
+++ b/app/assets/javascripts/attention_requests/components/navigation_popover.vue
@@ -0,0 +1,120 @@
+<script>
+import { GlPopover, GlSprintf, GlButton, GlLink, GlIcon } from '@gitlab/ui';
+import { GlBreakpointInstance as bp } from '@gitlab/ui/dist/utils';
+import { helpPagePath } from '~/helpers/help_page_helper';
+import UserCalloutDismisser from '~/vue_shared/components/user_callout_dismisser.vue';
+
+export default {
+ components: {
+ GlPopover,
+ GlSprintf,
+ GlButton,
+ GlLink,
+ GlIcon,
+ UserCalloutDismisser,
+ },
+ inject: {
+ message: {
+ default: '',
+ },
+ observerElSelector: {
+ default: '',
+ },
+ observerElToggledClass: {
+ default: '',
+ },
+ featureName: {
+ default: '',
+ },
+ popoverTarget: {
+ default: '',
+ },
+ showAttentionIcon: {
+ default: false,
+ },
+ delay: {
+ default: 0,
+ },
+ popoverCssClass: {
+ default: '',
+ },
+ },
+ data() {
+ return {
+ showPopover: false,
+ popoverPlacement: this.popoverPosition(),
+ };
+ },
+ mounted() {
+ this.observeEl = document.querySelector(this.observerElSelector);
+ this.observer = new MutationObserver(this.callback);
+ this.observer.observe(this.observeEl, {
+ attributes: true,
+ });
+ this.callback();
+
+ window.addEventListener('resize', () => {
+ this.popoverPlacement = this.popoverPosition();
+ });
+ },
+ beforeDestroy() {
+ this.observer.disconnect();
+ },
+ methods: {
+ callback() {
+ if (this.showPopover) {
+ this.$root.$emit('bv::hide::popover');
+ }
+
+ setTimeout(() => this.toggleShowPopover(), this.delay);
+ },
+ toggleShowPopover() {
+ this.showPopover = this.observeEl.classList.contains(this.observerElToggledClass);
+ },
+ getPopoverTarget() {
+ return document.querySelector(this.popoverTarget);
+ },
+ popoverPosition() {
+ if (bp.isDesktop()) {
+ return 'left';
+ }
+
+ return 'bottom';
+ },
+ },
+ docsPage: helpPagePath('development/code_review.html'),
+};
+</script>
+
+<template>
+ <user-callout-dismisser :feature-name="featureName">
+ <template #default="{ shouldShowCallout, dismiss }">
+ <gl-popover
+ v-if="shouldShowCallout"
+ :show-close-button="false"
+ :target="() => getPopoverTarget()"
+ :show="showPopover"
+ :delay="0"
+ triggers="manual"
+ :placement="popoverPlacement"
+ boundary="window"
+ no-fade
+ :css-classes="[popoverCssClass]"
+ >
+ <p v-for="(m, index) in message" :key="index" class="gl-mb-5">
+ <gl-sprintf :message="m">
+ <template #strong="{ content }">
+ <strong><gl-icon v-if="showAttentionIcon" name="attention" /> {{ content }}</strong>
+ </template>
+ </gl-sprintf>
+ </p>
+ <div class="gl-display-flex gl-align-items-center">
+ <gl-button size="small" variant="confirm" class="gl-mr-5" @click.prevent.stop="dismiss">
+ {{ __('Got it!') }}
+ </gl-button>
+ <gl-link :href="$options.docsPage" target="_blank">{{ __('Learn more') }}</gl-link>
+ </div>
+ </gl-popover>
+ </template>
+ </user-callout-dismisser>
+</template>
diff --git a/app/assets/javascripts/attention_requests/index.js b/app/assets/javascripts/attention_requests/index.js
new file mode 100644
index 00000000000..2a142ab46e5
--- /dev/null
+++ b/app/assets/javascripts/attention_requests/index.js
@@ -0,0 +1,73 @@
+import Vue from 'vue';
+import VueApollo from 'vue-apollo';
+import { __ } from '~/locale';
+import createDefaultClient from '~/lib/graphql';
+import NavigationPopover from './components/navigation_popover.vue';
+
+Vue.use(VueApollo);
+
+const apolloProvider = new VueApollo({
+ defaultClient: createDefaultClient(),
+});
+
+export const initTopNavPopover = () => {
+ const el = document.getElementById('js-need-attention-nav-onboarding');
+
+ if (!el) return;
+
+ // eslint-disable-next-line no-new
+ new Vue({
+ el,
+ apolloProvider,
+ provide: {
+ observerElSelector: '.user-counter.dropdown',
+ observerElToggledClass: 'show',
+ message: [
+ __(
+ '%{strongStart}Need your attention%{strongEnd} are the merge requests that need your help to move forward, as an assignee or reviewer.',
+ ),
+ ],
+ featureName: 'attention_requests_top_nav',
+ popoverTarget: '#js-need-attention-nav',
+ },
+ render(h) {
+ return h(NavigationPopover);
+ },
+ });
+};
+
+export const initSideNavPopover = () => {
+ const el = document.getElementById('js-need-attention-sidebar-onboarding');
+
+ if (!el) return;
+
+ // eslint-disable-next-line no-new
+ new Vue({
+ el,
+ apolloProvider,
+ provide: {
+ observerElSelector: '.js-right-sidebar',
+ observerElToggledClass: 'right-sidebar-expanded',
+ message: [
+ __(
+ 'To ask someone to look at a merge request, select %{strongStart}Request attention%{strongEnd}. Select again to remove the request.',
+ ),
+ __(
+ 'Some actions remove attention requests, like a reviewer approving or anyone merging the merge request.',
+ ),
+ ],
+ featureName: 'attention_requests_side_nav',
+ popoverTarget: '.js-attention-request-toggle',
+ showAttentionIcon: true,
+ delay: 500,
+ popoverCssClass: 'attention-request-sidebar-popover',
+ },
+ render(h) {
+ return h(NavigationPopover);
+ },
+ });
+};
+
+export default () => {
+ initTopNavPopover();
+};
diff --git a/app/assets/javascripts/authentication/webauthn/util.js b/app/assets/javascripts/authentication/webauthn/util.js
index eeda2bfaeaf..2a0740cf488 100644
--- a/app/assets/javascripts/authentication/webauthn/util.js
+++ b/app/assets/javascripts/authentication/webauthn/util.js
@@ -46,6 +46,17 @@ export const bufferToBase64 = (input) => {
};
/**
+ * Return a URL-safe base64 string.
+ *
+ * RFC: https://datatracker.ietf.org/doc/html/rfc4648#section-5
+ * @param {String} base64Str
+ * @returns {String}
+ */
+export const base64ToBase64Url = (base64Str) => {
+ return base64Str.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
+};
+
+/**
* Returns a copy of the given object with the id property converted to buffer
*
* @param {Object} param
diff --git a/app/assets/javascripts/behaviors/markdown/editor_extensions.js b/app/assets/javascripts/behaviors/markdown/editor_extensions.js
index b512e4dbc8b..165031c3e7d 100644
--- a/app/assets/javascripts/behaviors/markdown/editor_extensions.js
+++ b/app/assets/javascripts/behaviors/markdown/editor_extensions.js
@@ -48,54 +48,48 @@ import Video from './nodes/video';
// from GFM should have a node or mark here.
// The GFM-to-HTML-to-GFM cycle is tested in spec/features/markdown/copy_as_gfm_spec.rb.
-export default [
- new Doc(),
- new Paragraph(),
- new Text(),
+export default {
+ nodes: [
+ Doc(),
+ Paragraph(),
+ Text(),
- new Blockquote(),
- new CodeBlock(),
- new HardBreak(),
- new Heading({ maxLevel: 6 }),
- new HorizontalRule(),
- new Image(),
+ Blockquote(),
+ CodeBlock(),
+ HardBreak(),
+ Heading(),
+ HorizontalRule(),
+ Image(),
- new Table(),
- new TableHead(),
- new TableBody(),
- new TableHeaderRow(),
- new TableRow(),
- new TableCell(),
+ Table(),
+ TableHead(),
+ TableBody(),
+ TableHeaderRow(),
+ TableRow(),
+ TableCell(),
- new Emoji(),
- new Reference(),
+ Emoji(),
+ Reference(),
- new TableOfContents(),
- new Video(),
- new Audio(),
+ TableOfContents(),
+ Video(),
+ Audio(),
- new BulletList(),
- new OrderedList(),
- new ListItem(),
+ BulletList(),
+ OrderedList(),
+ ListItem(),
- new DescriptionList(),
- new DescriptionTerm(),
- new DescriptionDetails(),
+ DescriptionList(),
+ DescriptionTerm(),
+ DescriptionDetails(),
- new TaskList(),
- new OrderedTaskList(),
- new TaskListItem(),
+ TaskList(),
+ OrderedTaskList(),
+ TaskListItem(),
- new Summary(),
- new Details(),
+ Summary(),
+ Details(),
+ ],
- new Bold(),
- new Italic(),
- new Strike(),
- new InlineDiff(),
-
- new Link(),
- new Code(),
- new MathMark(),
- new InlineHTML(),
-];
+ marks: [Bold(), Italic(), Strike(), InlineDiff(), Link(), Code(), MathMark(), InlineHTML()],
+};
diff --git a/app/assets/javascripts/behaviors/markdown/marks/bold.js b/app/assets/javascripts/behaviors/markdown/marks/bold.js
index 89e373220af..dd730947a5f 100644
--- a/app/assets/javascripts/behaviors/markdown/marks/bold.js
+++ b/app/assets/javascripts/behaviors/markdown/marks/bold.js
@@ -1,11 +1,17 @@
-/* eslint-disable class-methods-use-this */
-
-import { Bold as BaseBold } from 'tiptap-extensions';
import { defaultMarkdownSerializer } from '~/lib/prosemirror_markdown_serializer';
// Transforms generated HTML back to GFM for Banzai::Filter::MarkdownFilter
-export default class Bold extends BaseBold {
- get toMarkdown() {
- return defaultMarkdownSerializer.marks.strong;
- }
-}
+export default () => {
+ return {
+ name: 'bold',
+ schema: {
+ parseDOM: [
+ {
+ tag: 'strong',
+ },
+ ],
+ toDOM: () => ['strong', 0],
+ },
+ toMarkdown: defaultMarkdownSerializer.marks.strong,
+ };
+};
diff --git a/app/assets/javascripts/behaviors/markdown/marks/code.js b/app/assets/javascripts/behaviors/markdown/marks/code.js
index 68368dec676..ea5af8b4a1f 100644
--- a/app/assets/javascripts/behaviors/markdown/marks/code.js
+++ b/app/assets/javascripts/behaviors/markdown/marks/code.js
@@ -1,11 +1,12 @@
-/* eslint-disable class-methods-use-this */
-
-import { Code as BaseCode } from 'tiptap-extensions';
import { defaultMarkdownSerializer } from '~/lib/prosemirror_markdown_serializer';
// Transforms generated HTML back to GFM for Banzai::Filter::MarkdownFilter
-export default class Code extends BaseCode {
- get toMarkdown() {
- return defaultMarkdownSerializer.marks.code;
- }
-}
+export default () => ({
+ name: 'code',
+ schema: {
+ excludes: '_',
+ parseDOM: [{ tag: 'code' }],
+ toDOM: () => ['code', 0],
+ },
+ toMarkdown: defaultMarkdownSerializer.marks.code,
+});
diff --git a/app/assets/javascripts/behaviors/markdown/marks/inline_diff.js b/app/assets/javascripts/behaviors/markdown/marks/inline_diff.js
index 7f1506cd5d9..69d345c81e4 100644
--- a/app/assets/javascripts/behaviors/markdown/marks/inline_diff.js
+++ b/app/assets/javascripts/behaviors/markdown/marks/inline_diff.js
@@ -1,41 +1,29 @@
-/* eslint-disable class-methods-use-this */
-
-import { Mark } from 'tiptap';
-
// Transforms generated HTML back to GFM for Banzai::Filter::InlineDiffFilter
-export default class InlineDiff extends Mark {
- get name() {
- return 'inline_diff';
- }
-
- get schema() {
- return {
- attrs: {
- addition: {
- default: true,
- },
+export default () => ({
+ name: 'inline_diff',
+ schema: {
+ attrs: {
+ addition: {
+ default: true,
},
- parseDOM: [
- { tag: 'span.idiff.addition', attrs: { addition: true } },
- { tag: 'span.idiff.deletion', attrs: { addition: false } },
- ],
- toDOM: (node) => [
- 'span',
- { class: `idiff left right ${node.attrs.addition ? 'addition' : 'deletion'}` },
- 0,
- ],
- };
- }
-
- get toMarkdown() {
- return {
- mixable: true,
- open(state, mark) {
- return mark.attrs.addition ? '{+' : '{-';
- },
- close(state, mark) {
- return mark.attrs.addition ? '+}' : '-}';
- },
- };
- }
-}
+ },
+ parseDOM: [
+ { tag: 'span.idiff.addition', attrs: { addition: true } },
+ { tag: 'span.idiff.deletion', attrs: { addition: false } },
+ ],
+ toDOM: (node) => [
+ 'span',
+ { class: `idiff left right ${node.attrs.addition ? 'addition' : 'deletion'}` },
+ 0,
+ ],
+ },
+ toMarkdown: {
+ mixable: true,
+ open(_, mark) {
+ return mark.attrs.addition ? '{+' : '{-';
+ },
+ close(_, mark) {
+ return mark.attrs.addition ? '+}' : '-}';
+ },
+ },
+});
diff --git a/app/assets/javascripts/behaviors/markdown/marks/inline_html.js b/app/assets/javascripts/behaviors/markdown/marks/inline_html.js
index e957f81b774..4520598e0ab 100644
--- a/app/assets/javascripts/behaviors/markdown/marks/inline_html.js
+++ b/app/assets/javascripts/behaviors/markdown/marks/inline_html.js
@@ -1,46 +1,35 @@
-/* eslint-disable class-methods-use-this */
-
import { escape } from 'lodash';
-import { Mark } from 'tiptap';
// Transforms generated HTML back to GFM for Banzai::Filter::MarkdownFilter
-export default class InlineHTML extends Mark {
- get name() {
- return 'inline_html';
- }
-
- get schema() {
- return {
- excludes: '',
- attrs: {
- tag: {},
- title: { default: null },
- },
- parseDOM: [
- {
- tag: 'sup, sub, kbd, q, samp, var',
- getAttrs: (el) => ({ tag: el.nodeName.toLowerCase() }),
- },
- {
- tag: 'abbr',
- getAttrs: (el) => ({ tag: 'abbr', title: el.getAttribute('title') }),
- },
- ],
- toDOM: (node) => [node.attrs.tag, { title: node.attrs.title }, 0],
- };
- }
-
- get toMarkdown() {
- return {
- mixable: true,
- open(state, mark) {
- return `<${mark.attrs.tag}${
- mark.attrs.title ? ` title="${state.esc(escape(mark.attrs.title))}"` : ''
- }>`;
+export default () => ({
+ name: 'inline_html',
+ schema: {
+ excludes: '',
+ attrs: {
+ tag: {},
+ title: { default: null },
+ },
+ parseDOM: [
+ {
+ tag: 'sup, sub, kbd, q, samp, var',
+ getAttrs: (el) => ({ tag: el.nodeName.toLowerCase() }),
},
- close(state, mark) {
- return `</${mark.attrs.tag}>`;
+ {
+ tag: 'abbr',
+ getAttrs: (el) => ({ tag: 'abbr', title: el.getAttribute('title') }),
},
- };
- }
-}
+ ],
+ toDOM: (node) => [node.attrs.tag, { title: node.attrs.title }, 0],
+ },
+ toMarkdown: {
+ mixable: true,
+ open(state, mark) {
+ return `<${mark.attrs.tag}${
+ mark.attrs.title ? ` title="${state.esc(escape(mark.attrs.title))}"` : ''
+ }>`;
+ },
+ close(_, mark) {
+ return `</${mark.attrs.tag}>`;
+ },
+ },
+});
diff --git a/app/assets/javascripts/behaviors/markdown/marks/italic.js b/app/assets/javascripts/behaviors/markdown/marks/italic.js
index 7dc86102f18..3ec8f0071e9 100644
--- a/app/assets/javascripts/behaviors/markdown/marks/italic.js
+++ b/app/assets/javascripts/behaviors/markdown/marks/italic.js
@@ -1,11 +1,11 @@
-/* eslint-disable class-methods-use-this */
-
-import { Italic as BaseItalic } from 'tiptap-extensions';
import { defaultMarkdownSerializer } from '~/lib/prosemirror_markdown_serializer';
// Transforms generated HTML back to GFM for Banzai::Filter::MarkdownFilter
-export default class Italic extends BaseItalic {
- get toMarkdown() {
- return defaultMarkdownSerializer.marks.em;
- }
-}
+export default () => ({
+ name: 'italic',
+ schema: {
+ parseDOM: [{ tag: 'em' }],
+ toDOM: () => ['em', 0],
+ },
+ toMarkdown: defaultMarkdownSerializer.marks.em,
+});
diff --git a/app/assets/javascripts/behaviors/markdown/marks/link.js b/app/assets/javascripts/behaviors/markdown/marks/link.js
index b5e09017d83..977453fee01 100644
--- a/app/assets/javascripts/behaviors/markdown/marks/link.js
+++ b/app/assets/javascripts/behaviors/markdown/marks/link.js
@@ -1,21 +1,47 @@
-/* eslint-disable class-methods-use-this */
-
-import { Link as BaseLink } from 'tiptap-extensions';
import { defaultMarkdownSerializer } from '~/lib/prosemirror_markdown_serializer';
// Transforms generated HTML back to GFM for Banzai::Filter::MarkdownFilter
-export default class Link extends BaseLink {
- get toMarkdown() {
- return {
- mixable: true,
- open(state, mark, parent, index) {
- const open = defaultMarkdownSerializer.marks.link.open(state, mark, parent, index);
- return open === '<' ? '' : open;
+export default () => ({
+ name: 'link',
+ schema: {
+ attrs: {
+ href: {
+ default: null,
+ },
+ target: {
+ default: null,
+ },
+ },
+ inclusive: false,
+ parseDOM: [
+ {
+ tag: 'a[href]',
+ getAttrs: (dom) => ({
+ href: dom.getAttribute('href'),
+ target: dom.getAttribute('target'),
+ }),
},
- close(state, mark, parent, index) {
- const close = defaultMarkdownSerializer.marks.link.close(state, mark, parent, index);
- return close === '>' ? '' : close;
+ ],
+ toDOM: (node) => [
+ 'a',
+ {
+ ...node.attrs,
+ // eslint-disable-next-line @gitlab/require-i18n-strings
+ rel: 'noopener noreferrer nofollow',
+ target: node.attrs.target,
},
- };
- }
-}
+ 0,
+ ],
+ },
+ toMarkdown: {
+ mixable: true,
+ open(state, mark, parent, index) {
+ const open = defaultMarkdownSerializer.marks.link.open(state, mark, parent, index);
+ return open === '<' ? '' : open;
+ },
+ close(state, mark, parent, index) {
+ const close = defaultMarkdownSerializer.marks.link.close(state, mark, parent, index);
+ return close === '>' ? '' : close;
+ },
+ },
+});
diff --git a/app/assets/javascripts/behaviors/markdown/marks/math.js b/app/assets/javascripts/behaviors/markdown/marks/math.js
index ca25ff7d07d..a50a649b6eb 100644
--- a/app/assets/javascripts/behaviors/markdown/marks/math.js
+++ b/app/assets/javascripts/behaviors/markdown/marks/math.js
@@ -1,42 +1,31 @@
-/* eslint-disable class-methods-use-this */
-
-import { Mark } from 'tiptap';
import { defaultMarkdownSerializer } from '~/lib/prosemirror_markdown_serializer';
import { HIGHER_PARSE_RULE_PRIORITY } from '../constants';
// Transforms generated HTML back to GFM for Banzai::Filter::MathFilter
-export default class MathMark extends Mark {
- get name() {
- return 'math';
- }
-
- get schema() {
- return {
- parseDOM: [
- // Matches HTML generated by Banzai::Filter::MathFilter
- {
- tag: 'code.code.math[data-math-style=inline]',
- priority: HIGHER_PARSE_RULE_PRIORITY,
- },
- // Matches HTML after being transformed by app/assets/javascripts/behaviors/markdown/render_math.js
- {
- tag: 'span.katex',
- contentElement: 'annotation[encoding="application/x-tex"]',
- },
- ],
- toDOM: () => ['code', { class: 'code math', 'data-math-style': 'inline' }, 0],
- };
- }
-
- get toMarkdown() {
- return {
- escape: false,
- open(state, mark, parent, index) {
- return `$${defaultMarkdownSerializer.marks.code.open(state, mark, parent, index)}`;
+export default () => ({
+ name: 'math',
+ schema: {
+ parseDOM: [
+ // Matches HTML generated by Banzai::Filter::MathFilter
+ {
+ tag: 'code.code.math[data-math-style=inline]',
+ priority: HIGHER_PARSE_RULE_PRIORITY,
},
- close(state, mark, parent, index) {
- return `${defaultMarkdownSerializer.marks.code.close(state, mark, parent, index)}$`;
+ // Matches HTML after being transformed by app/assets/javascripts/behaviors/markdown/render_math.js
+ {
+ tag: 'span.katex',
+ contentElement: 'annotation[encoding="application/x-tex"]',
},
- };
- }
-}
+ ],
+ toDOM: () => ['code', { class: 'code math', 'data-math-style': 'inline' }, 0],
+ },
+ toMarkdown: {
+ escape: false,
+ open(state, mark, parent, index) {
+ return `$${defaultMarkdownSerializer.marks.code.open(state, mark, parent, index)}`;
+ },
+ close(state, mark, parent, index) {
+ return `${defaultMarkdownSerializer.marks.code.close(state, mark, parent, index)}$`;
+ },
+ },
+});
diff --git a/app/assets/javascripts/behaviors/markdown/marks/strike.js b/app/assets/javascripts/behaviors/markdown/marks/strike.js
index c2951a40a4b..967c0a120cd 100644
--- a/app/assets/javascripts/behaviors/markdown/marks/strike.js
+++ b/app/assets/javascripts/behaviors/markdown/marks/strike.js
@@ -1,15 +1,18 @@
-/* eslint-disable class-methods-use-this */
-
-import { Strike as BaseStrike } from 'tiptap-extensions';
-
// Transforms generated HTML back to GFM for Banzai::Filter::MarkdownFilter
-export default class Strike extends BaseStrike {
- get toMarkdown() {
- return {
- open: '~~',
- close: '~~',
- mixable: true,
- expelEnclosingWhitespace: true,
- };
- }
-}
+export default () => ({
+ name: 'strike',
+ schema: {
+ parseDOM: [
+ {
+ tag: 'del',
+ },
+ ],
+ toDOM: () => ['s', 0],
+ },
+ toMarkdown: {
+ open: '~~',
+ close: '~~',
+ mixable: true,
+ expelEnclosingWhitespace: true,
+ },
+});
diff --git a/app/assets/javascripts/behaviors/markdown/nodes/audio.js b/app/assets/javascripts/behaviors/markdown/nodes/audio.js
index 146349b118c..97ab86c6d23 100644
--- a/app/assets/javascripts/behaviors/markdown/nodes/audio.js
+++ b/app/assets/javascripts/behaviors/markdown/nodes/audio.js
@@ -1,9 +1,4 @@
-import Playable from './playable';
+import playable from './playable';
// Transforms generated HTML back to GFM for Banzai::Filter::AudioLinkFilter
-export default class Audio extends Playable {
- constructor() {
- super();
- this.mediaType = 'audio';
- }
-}
+export default () => playable({ mediaType: 'audio' });
diff --git a/app/assets/javascripts/behaviors/markdown/nodes/blockquote.js b/app/assets/javascripts/behaviors/markdown/nodes/blockquote.js
index 8b14a04e2fe..6a4552d47e4 100644
--- a/app/assets/javascripts/behaviors/markdown/nodes/blockquote.js
+++ b/app/assets/javascripts/behaviors/markdown/nodes/blockquote.js
@@ -1,13 +1,19 @@
-/* eslint-disable class-methods-use-this */
-
-import { Blockquote as BaseBlockquote } from 'tiptap-extensions';
import { defaultMarkdownSerializer } from '~/lib/prosemirror_markdown_serializer';
// Transforms generated HTML back to GFM for Banzai::Filter::MarkdownFilter
-export default class Blockquote extends BaseBlockquote {
+export default () => ({
+ name: 'blockquote',
+ schema: {
+ content: 'block*',
+ group: 'block',
+ defining: true,
+ draggable: false,
+ parseDOM: [{ tag: 'blockquote' }],
+ toDOM: () => ['blockquote', 0],
+ },
toMarkdown(state, node) {
if (!node.childCount) return;
defaultMarkdownSerializer.nodes.blockquote(state, node);
- }
-}
+ },
+});
diff --git a/app/assets/javascripts/behaviors/markdown/nodes/bullet_list.js b/app/assets/javascripts/behaviors/markdown/nodes/bullet_list.js
index ef1eafaa419..95cd3605da5 100644
--- a/app/assets/javascripts/behaviors/markdown/nodes/bullet_list.js
+++ b/app/assets/javascripts/behaviors/markdown/nodes/bullet_list.js
@@ -1,11 +1,15 @@
-/* eslint-disable class-methods-use-this */
-
-import { BulletList as BaseBulletList } from 'tiptap-extensions';
import { defaultMarkdownSerializer } from '~/lib/prosemirror_markdown_serializer';
// Transforms generated HTML back to GFM for Banzai::Filter::MarkdownFilter
-export default class BulletList extends BaseBulletList {
+export default () => ({
+ name: 'bullet_list',
+ schema: {
+ content: 'list_item+',
+ group: 'block',
+ parseDOM: [{ tag: 'ul' }],
+ toDOM: () => ['ul', 0],
+ },
toMarkdown(state, node) {
defaultMarkdownSerializer.nodes.bullet_list(state, node);
- }
-}
+ },
+});
diff --git a/app/assets/javascripts/behaviors/markdown/nodes/code_block.js b/app/assets/javascripts/behaviors/markdown/nodes/code_block.js
index cd90d67c60d..0ff59779e7d 100644
--- a/app/assets/javascripts/behaviors/markdown/nodes/code_block.js
+++ b/app/assets/javascripts/behaviors/markdown/nodes/code_block.js
@@ -1,7 +1,3 @@
-/* eslint-disable class-methods-use-this */
-
-import { CodeBlock as BaseCodeBlock } from 'tiptap-extensions';
-
const PLAINTEXT_LANG = 'plaintext';
// Transforms generated HTML back to GFM for:
@@ -9,68 +5,67 @@ const PLAINTEXT_LANG = 'plaintext';
// - Banzai::Filter::MathFilter
// - Banzai::Filter::MermaidFilter
// - Banzai::Filter::SuggestionFilter
-export default class CodeBlock extends BaseCodeBlock {
- get schema() {
- return {
- content: 'text*',
- marks: '',
- group: 'block',
- code: true,
- defining: true,
- attrs: {
- lang: { default: PLAINTEXT_LANG },
- },
- parseDOM: [
- // Matches HTML generated by Banzai::Filter::SyntaxHighlightFilter, Banzai::Filter::MathFilter, Banzai::Filter::MermaidFilter, or Banzai::Filter::SuggestionFilter
- {
- tag: 'pre.code.highlight',
- preserveWhitespace: 'full',
- getAttrs: (el) => {
- const lang = el.getAttribute('lang');
- if (!lang || lang === '') return {};
+export default () => ({
+ name: 'code_block',
+ schema: {
+ content: 'text*',
+ marks: '',
+ group: 'block',
+ code: true,
+ defining: true,
+ attrs: {
+ lang: { default: PLAINTEXT_LANG },
+ },
+ parseDOM: [
+ // Matches HTML generated by Banzai::Filter::SyntaxHighlightFilter, Banzai::Filter::MathFilter, Banzai::Filter::MermaidFilter, or Banzai::Filter::SuggestionFilter
+ {
+ tag: 'pre.code.highlight',
+ preserveWhitespace: 'full',
+ getAttrs: (el) => {
+ const lang = el.getAttribute('lang');
+ if (!lang || lang === '') return {};
- return { lang };
- },
- },
- // Matches HTML generated by Banzai::Filter::MathFilter,
- // after being transformed by app/assets/javascripts/behaviors/markdown/render_math.js
- {
- tag: 'span.katex-display',
- preserveWhitespace: 'full',
- contentElement: 'annotation[encoding="application/x-tex"]',
- attrs: { lang: 'math' },
- },
- // Matches HTML generated by Banzai::Filter::MermaidFilter,
- // after being transformed by app/assets/javascripts/behaviors/markdown/render_mermaid.js
- {
- tag: 'svg.mermaid',
- preserveWhitespace: 'full',
- contentElement: 'text.source',
- attrs: { lang: 'mermaid' },
- },
- // Matches HTML generated by Banzai::Filter::SuggestionFilter,
- // after being transformed by app/assets/javascripts/vue_shared/components/markdown/suggestions.vue
- {
- tag: '.md-suggestion',
- skip: true,
- },
- {
- tag: '.md-suggestion-header',
- ignore: true,
+ return { lang };
},
- {
- tag: '.md-suggestion-diff',
- preserveWhitespace: 'full',
- getContent: (el, schema) =>
- [...el.querySelectorAll('.line_content.new span')].map((span) =>
- schema.text(span.innerText),
- ),
- attrs: { lang: 'suggestion' },
- },
- ],
- toDOM: (node) => ['pre', { class: 'code highlight', lang: node.attrs.lang }, ['code', 0]],
- };
- }
+ },
+ // Matches HTML generated by Banzai::Filter::MathFilter,
+ // after being transformed by app/assets/javascripts/behaviors/markdown/render_math.js
+ {
+ tag: 'span.katex-display',
+ preserveWhitespace: 'full',
+ contentElement: 'annotation[encoding="application/x-tex"]',
+ attrs: { lang: 'math' },
+ },
+ // Matches HTML generated by Banzai::Filter::MermaidFilter,
+ // after being transformed by app/assets/javascripts/behaviors/markdown/render_mermaid.js
+ {
+ tag: 'svg.mermaid',
+ preserveWhitespace: 'full',
+ contentElement: 'text.source',
+ attrs: { lang: 'mermaid' },
+ },
+ // Matches HTML generated by Banzai::Filter::SuggestionFilter,
+ // after being transformed by app/assets/javascripts/vue_shared/components/markdown/suggestions.vue
+ {
+ tag: '.md-suggestion',
+ skip: true,
+ },
+ {
+ tag: '.md-suggestion-header',
+ ignore: true,
+ },
+ {
+ tag: '.md-suggestion-diff',
+ preserveWhitespace: 'full',
+ getContent: (el, schema) =>
+ [...el.querySelectorAll('.line_content.new span')].map((span) =>
+ schema.text(span.innerText),
+ ),
+ attrs: { lang: 'suggestion' },
+ },
+ ],
+ toDOM: (node) => ['pre', { class: 'code highlight', lang: node.attrs.lang }, ['code', 0]],
+ },
toMarkdown(state, node) {
if (!node.childCount) return;
@@ -95,5 +90,5 @@ export default class CodeBlock extends BaseCodeBlock {
state.write('```');
state.closeBlock(node);
- }
-}
+ },
+});
diff --git a/app/assets/javascripts/behaviors/markdown/nodes/description_details.js b/app/assets/javascripts/behaviors/markdown/nodes/description_details.js
index a4451d8ce8d..20760286045 100644
--- a/app/assets/javascripts/behaviors/markdown/nodes/description_details.js
+++ b/app/assets/javascripts/behaviors/markdown/nodes/description_details.js
@@ -1,22 +1,14 @@
-/* eslint-disable class-methods-use-this */
-
-import { Node } from 'tiptap';
-
// Transforms generated HTML back to GFM for Banzai::Filter::MarkdownFilter
-export default class DescriptionDetails extends Node {
- get name() {
- return 'description_details';
- }
+export default () => ({
+ name: 'description_details',
- get schema() {
- return {
- content: 'text*',
- marks: '',
- defining: true,
- parseDOM: [{ tag: 'dd' }],
- toDOM: () => ['dd', 0],
- };
- }
+ schema: {
+ content: 'text*',
+ marks: '',
+ defining: true,
+ parseDOM: [{ tag: 'dd' }],
+ toDOM: () => ['dd', 0],
+ },
toMarkdown(state, node) {
state.flushClose(1);
@@ -24,5 +16,5 @@ export default class DescriptionDetails extends Node {
state.text(node.textContent, false);
state.write('</dd>');
state.closeBlock(node);
- }
-}
+ },
+});
diff --git a/app/assets/javascripts/behaviors/markdown/nodes/description_list.js b/app/assets/javascripts/behaviors/markdown/nodes/description_list.js
index 6aa1aca29d7..c5305c48423 100644
--- a/app/assets/javascripts/behaviors/markdown/nodes/description_list.js
+++ b/app/assets/javascripts/behaviors/markdown/nodes/description_list.js
@@ -1,21 +1,12 @@
-/* eslint-disable class-methods-use-this */
-
-import { Node } from 'tiptap';
-
// Transforms generated HTML back to GFM for Banzai::Filter::MarkdownFilter
-export default class DescriptionList extends Node {
- get name() {
- return 'description_list';
- }
-
- get schema() {
- return {
- content: '(description_term+ description_details+)+',
- group: 'block',
- parseDOM: [{ tag: 'dl' }],
- toDOM: () => ['dl', 0],
- };
- }
+export default () => ({
+ name: 'description_list',
+ schema: {
+ content: '(description_term+ description_details+)+',
+ group: 'block',
+ parseDOM: [{ tag: 'dl' }],
+ toDOM: () => ['dl', 0],
+ },
toMarkdown(state, node) {
state.write('<dl>\n');
@@ -24,5 +15,5 @@ export default class DescriptionList extends Node {
state.ensureNewLine();
state.write('</dl>');
state.closeBlock(node);
- }
-}
+ },
+});
diff --git a/app/assets/javascripts/behaviors/markdown/nodes/description_term.js b/app/assets/javascripts/behaviors/markdown/nodes/description_term.js
index 89057ec6444..f78f7f13fc4 100644
--- a/app/assets/javascripts/behaviors/markdown/nodes/description_term.js
+++ b/app/assets/javascripts/behaviors/markdown/nodes/description_term.js
@@ -1,28 +1,18 @@
-/* eslint-disable class-methods-use-this */
-
-import { Node } from 'tiptap';
-
// Transforms generated HTML back to GFM for Banzai::Filter::MarkdownFilter
-export default class DescriptionTerm extends Node {
- get name() {
- return 'description_term';
- }
-
- get schema() {
- return {
- content: 'text*',
- marks: '',
- defining: true,
- parseDOM: [{ tag: 'dt' }],
- toDOM: () => ['dt', 0],
- };
- }
-
+export default () => ({
+ name: 'description_term',
+ schema: {
+ content: 'text*',
+ marks: '',
+ defining: true,
+ parseDOM: [{ tag: 'dt' }],
+ toDOM: () => ['dt', 0],
+ },
toMarkdown(state, node) {
state.flushClose(state.closed && state.closed.type === node.type ? 1 : 2);
state.write('<dt>');
state.text(node.textContent, false);
state.write('</dt>');
state.closeBlock(node);
- }
-}
+ },
+});
diff --git a/app/assets/javascripts/behaviors/markdown/nodes/details.js b/app/assets/javascripts/behaviors/markdown/nodes/details.js
index 1c40dbb8168..9fb0d60b93a 100644
--- a/app/assets/javascripts/behaviors/markdown/nodes/details.js
+++ b/app/assets/javascripts/behaviors/markdown/nodes/details.js
@@ -1,22 +1,12 @@
-/* eslint-disable class-methods-use-this */
-
-import { Node } from 'tiptap';
-
// Transforms generated HTML back to GFM for Banzai::Filter::MarkdownFilter
-export default class Details extends Node {
- get name() {
- return 'details';
- }
-
- get schema() {
- return {
- content: 'summary block*',
- group: 'block',
- parseDOM: [{ tag: 'details' }],
- toDOM: () => ['details', { open: true, onclick: 'return false', tabindex: '-1' }, 0],
- };
- }
-
+export default () => ({
+ name: 'details',
+ schema: {
+ content: 'summary block*',
+ group: 'block',
+ parseDOM: [{ tag: 'details' }],
+ toDOM: () => ['details', { open: true, onclick: 'return false', tabindex: '-1' }, 0],
+ },
toMarkdown(state, node) {
state.write('<details>\n');
state.renderContent(node);
@@ -24,5 +14,5 @@ export default class Details extends Node {
state.ensureNewLine();
state.write('</details>');
state.closeBlock(node);
- }
-}
+ },
+});
diff --git a/app/assets/javascripts/behaviors/markdown/nodes/doc.js b/app/assets/javascripts/behaviors/markdown/nodes/doc.js
index 88b16fd85da..3101e6e0e3a 100644
--- a/app/assets/javascripts/behaviors/markdown/nodes/doc.js
+++ b/app/assets/javascripts/behaviors/markdown/nodes/doc.js
@@ -1,15 +1,6 @@
-/* eslint-disable class-methods-use-this */
-
-import { Node } from 'tiptap';
-
-export default class Doc extends Node {
- get name() {
- return 'doc';
- }
-
- get schema() {
- return {
- content: 'block+',
- };
- }
-}
+export default () => ({
+ name: 'doc',
+ schema: {
+ content: 'block+',
+ },
+});
diff --git a/app/assets/javascripts/behaviors/markdown/nodes/emoji.js b/app/assets/javascripts/behaviors/markdown/nodes/emoji.js
index 9d0890aa1b4..086c277bad4 100644
--- a/app/assets/javascripts/behaviors/markdown/nodes/emoji.js
+++ b/app/assets/javascripts/behaviors/markdown/nodes/emoji.js
@@ -1,53 +1,43 @@
-/* eslint-disable class-methods-use-this */
-
-import { Node } from 'tiptap';
-
// Transforms generated HTML back to GFM for Banzai::Filter::EmojiFilter
-export default class Emoji extends Node {
- get name() {
- return 'emoji';
- }
-
- get schema() {
- return {
- inline: true,
- group: 'inline',
- attrs: {
- name: {},
- title: {},
- moji: {},
+export default () => ({
+ name: 'emoji',
+ schema: {
+ inline: true,
+ group: 'inline',
+ attrs: {
+ name: {},
+ title: {},
+ moji: {},
+ },
+ parseDOM: [
+ {
+ tag: 'gl-emoji',
+ getAttrs: (el) => ({
+ name: el.dataset.name,
+ title: el.getAttribute('title'),
+ moji: el.textContent,
+ }),
},
- parseDOM: [
- {
- tag: 'gl-emoji',
- getAttrs: (el) => ({
- name: el.dataset.name,
- title: el.getAttribute('title'),
- moji: el.textContent,
- }),
- },
- {
- tag: 'img.emoji',
- getAttrs: (el) => {
- const name = el.getAttribute('title').replace(/^:|:$/g, '');
+ {
+ tag: 'img.emoji',
+ getAttrs: (el) => {
+ const name = el.getAttribute('title').replace(/^:|:$/g, '');
- return {
- name,
- title: name,
- moji: name,
- };
- },
+ return {
+ name,
+ title: name,
+ moji: name,
+ };
},
- ],
- toDOM: (node) => [
- 'gl-emoji',
- { 'data-name': node.attrs.name, title: node.attrs.title },
- node.attrs.moji,
- ],
- };
- }
-
+ },
+ ],
+ toDOM: (node) => [
+ 'gl-emoji',
+ { 'data-name': node.attrs.name, title: node.attrs.title },
+ node.attrs.moji,
+ ],
+ },
toMarkdown(state, node) {
state.write(`:${node.attrs.name}:`);
- }
-}
+ },
+});
diff --git a/app/assets/javascripts/behaviors/markdown/nodes/hard_break.js b/app/assets/javascripts/behaviors/markdown/nodes/hard_break.js
index 59e5d8ab3e2..1668af9c3f4 100644
--- a/app/assets/javascripts/behaviors/markdown/nodes/hard_break.js
+++ b/app/assets/javascripts/behaviors/markdown/nodes/hard_break.js
@@ -1,10 +1,14 @@
-/* eslint-disable class-methods-use-this */
-
-import { HardBreak as BaseHardBreak } from 'tiptap-extensions';
-
// Transforms generated HTML back to GFM for Banzai::Filter::MarkdownFilter
-export default class HardBreak extends BaseHardBreak {
+export default () => ({
+ name: 'hard_break',
+ schema: {
+ inline: true,
+ group: 'inline',
+ selectable: false,
+ parseDOM: [{ tag: 'br' }],
+ toDOM: () => ['br'],
+ },
toMarkdown(state) {
if (!state.atBlank()) state.write(' \n');
- }
-}
+ },
+});
diff --git a/app/assets/javascripts/behaviors/markdown/nodes/heading.js b/app/assets/javascripts/behaviors/markdown/nodes/heading.js
index 29967e61ffa..21b4ec69b70 100644
--- a/app/assets/javascripts/behaviors/markdown/nodes/heading.js
+++ b/app/assets/javascripts/behaviors/markdown/nodes/heading.js
@@ -1,13 +1,27 @@
-/* eslint-disable class-methods-use-this */
-
-import { Heading as BaseHeading } from 'tiptap-extensions';
import { defaultMarkdownSerializer } from '~/lib/prosemirror_markdown_serializer';
// Transforms generated HTML back to GFM for Banzai::Filter::MarkdownFilter
-export default class Heading extends BaseHeading {
+export default ({ levels = [1, 2, 3, 4, 5, 6] } = {}) => ({
+ name: 'heading',
+ schema: {
+ attrs: {
+ level: {
+ default: 1,
+ },
+ },
+ content: 'inline*',
+ group: 'block',
+ defining: true,
+ draggable: false,
+ parseDOM: levels.map((level) => ({
+ tag: `h${level}`,
+ attrs: { level },
+ })),
+ toDOM: (node) => [`h${node.attrs.level}`, 0],
+ },
toMarkdown(state, node) {
if (!node.childCount) return;
defaultMarkdownSerializer.nodes.heading(state, node);
- }
-}
+ },
+});
diff --git a/app/assets/javascripts/behaviors/markdown/nodes/horizontal_rule.js b/app/assets/javascripts/behaviors/markdown/nodes/horizontal_rule.js
index ee3aa145dc3..2d7074e567f 100644
--- a/app/assets/javascripts/behaviors/markdown/nodes/horizontal_rule.js
+++ b/app/assets/javascripts/behaviors/markdown/nodes/horizontal_rule.js
@@ -1,11 +1,14 @@
-/* eslint-disable class-methods-use-this */
-
-import { HorizontalRule as BaseHorizontalRule } from 'tiptap-extensions';
import { defaultMarkdownSerializer } from '~/lib/prosemirror_markdown_serializer';
// Transforms generated HTML back to GFM for Banzai::Filter::MarkdownFilter
-export default class HorizontalRule extends BaseHorizontalRule {
+export default () => ({
+ name: 'horizontal_rule',
+ schema: {
+ group: 'block',
+ parseDOM: [{ tag: 'hr' }],
+ toDOM: () => ['hr'],
+ },
toMarkdown(state, node) {
defaultMarkdownSerializer.nodes.horizontal_rule(state, node);
- }
-}
+ },
+});
diff --git a/app/assets/javascripts/behaviors/markdown/nodes/image.js b/app/assets/javascripts/behaviors/markdown/nodes/image.js
index 16647d2f96e..370cc347a05 100644
--- a/app/assets/javascripts/behaviors/markdown/nodes/image.js
+++ b/app/assets/javascripts/behaviors/markdown/nodes/image.js
@@ -1,53 +1,48 @@
-/* eslint-disable class-methods-use-this */
-
-import { Image as BaseImage } from 'tiptap-extensions';
import { placeholderImage } from '~/lazy_loader';
import { defaultMarkdownSerializer } from '~/lib/prosemirror_markdown_serializer';
import { HIGHER_PARSE_RULE_PRIORITY } from '../constants';
-export default class Image extends BaseImage {
- get schema() {
- return {
- attrs: {
- src: {},
- alt: {
- default: null,
- },
- title: {
- default: null,
- },
+export default () => ({
+ name: 'image',
+ schema: {
+ attrs: {
+ src: {},
+ alt: {
+ default: null,
},
- group: 'inline',
- inline: true,
- draggable: true,
- parseDOM: [
- // Matches HTML generated by Banzai::Filter::ImageLinkFilter
- {
- tag: 'a.no-attachment-icon',
- priority: HIGHER_PARSE_RULE_PRIORITY,
- skip: true,
- },
- // Matches HTML generated by Banzai::Filter::ImageLazyLoadFilter
- {
- tag: 'img[src]:not(.emoji)',
- getAttrs: (el) => {
- const imageSrc = el.src;
- const imageUrl =
- imageSrc && imageSrc !== placeholderImage ? imageSrc : el.dataset.src || '';
+ title: {
+ default: null,
+ },
+ },
+ group: 'inline',
+ inline: true,
+ draggable: true,
+ parseDOM: [
+ // Matches HTML generated by Banzai::Filter::ImageLinkFilter
+ {
+ tag: 'a.no-attachment-icon',
+ priority: HIGHER_PARSE_RULE_PRIORITY,
+ skip: true,
+ },
+ // Matches HTML generated by Banzai::Filter::ImageLazyLoadFilter
+ {
+ tag: 'img[src]:not(.emoji)',
+ getAttrs: (el) => {
+ const imageSrc = el.src;
+ const imageUrl =
+ imageSrc && imageSrc !== placeholderImage ? imageSrc : el.dataset.src || '';
- return {
- src: imageUrl,
- title: el.getAttribute('title'),
- alt: el.getAttribute('alt'),
- };
- },
+ return {
+ src: imageUrl,
+ title: el.getAttribute('title'),
+ alt: el.getAttribute('alt'),
+ };
},
- ],
- toDOM: (node) => ['img', node.attrs],
- };
- }
-
+ },
+ ],
+ toDOM: (node) => ['img', node.attrs],
+ },
toMarkdown(state, node) {
defaultMarkdownSerializer.nodes.image(state, node);
- }
-}
+ },
+});
diff --git a/app/assets/javascripts/behaviors/markdown/nodes/list_item.js b/app/assets/javascripts/behaviors/markdown/nodes/list_item.js
index 7204b7c09ba..97c1f07427d 100644
--- a/app/assets/javascripts/behaviors/markdown/nodes/list_item.js
+++ b/app/assets/javascripts/behaviors/markdown/nodes/list_item.js
@@ -1,11 +1,16 @@
-/* eslint-disable class-methods-use-this */
-
-import { ListItem as BaseListItem } from 'tiptap-extensions';
import { defaultMarkdownSerializer } from '~/lib/prosemirror_markdown_serializer';
// Transforms generated HTML back to GFM for Banzai::Filter::MarkdownFilter
-export default class ListItem extends BaseListItem {
+export default () => ({
+ name: 'list_item',
+ schema: {
+ content: 'paragraph block*',
+ defining: true,
+ draggable: false,
+ parseDOM: [{ tag: 'li' }],
+ toDOM: () => ['li', 0],
+ },
toMarkdown(state, node) {
defaultMarkdownSerializer.nodes.list_item(state, node);
- }
-}
+ },
+});
diff --git a/app/assets/javascripts/behaviors/markdown/nodes/ordered_list.js b/app/assets/javascripts/behaviors/markdown/nodes/ordered_list.js
index 4c1542d14ea..f2f3eff266a 100644
--- a/app/assets/javascripts/behaviors/markdown/nodes/ordered_list.js
+++ b/app/assets/javascripts/behaviors/markdown/nodes/ordered_list.js
@@ -1,10 +1,25 @@
-/* eslint-disable class-methods-use-this */
-
-import { OrderedList as BaseOrderedList } from 'tiptap-extensions';
-
// Transforms generated HTML back to GFM for Banzai::Filter::MarkdownFilter
-export default class OrderedList extends BaseOrderedList {
+export default () => ({
+ name: 'ordered_list',
+ schema: {
+ attrs: {
+ order: {
+ default: 1,
+ },
+ },
+ content: 'list_item+',
+ group: 'block',
+ parseDOM: [
+ {
+ tag: 'ol',
+ getAttrs: (dom) => ({
+ order: dom.hasAttribute('start') ? dom.getAttribute('start') + 1 : 1,
+ }),
+ },
+ ],
+ toDOM: (node) => (node.attrs.order === 1 ? ['ol', 0] : ['ol', { start: node.attrs.order }, 0]),
+ },
toMarkdown(state, node) {
state.renderList(node, ' ', () => '1. ');
- }
-}
+ },
+});
diff --git a/app/assets/javascripts/behaviors/markdown/nodes/ordered_task_list.js b/app/assets/javascripts/behaviors/markdown/nodes/ordered_task_list.js
index a28d7be3758..53a6a0d9e07 100644
--- a/app/assets/javascripts/behaviors/markdown/nodes/ordered_task_list.js
+++ b/app/assets/javascripts/behaviors/markdown/nodes/ordered_task_list.js
@@ -1,29 +1,21 @@
-/* eslint-disable class-methods-use-this */
-
-import { Node } from 'tiptap';
import { HIGHER_PARSE_RULE_PRIORITY } from '../constants';
// Transforms generated HTML back to GFM for Banzai::Filter::TaskListFilter
-export default class OrderedTaskList extends Node {
- get name() {
- return 'ordered_task_list';
- }
-
- get schema() {
- return {
- group: 'block',
- content: '(task_list_item|list_item)+',
- parseDOM: [
- {
- priority: HIGHER_PARSE_RULE_PRIORITY,
- tag: 'ol.task-list',
- },
- ],
- toDOM: () => ['ol', { class: 'task-list' }, 0],
- };
- }
+export default () => ({
+ name: 'ordered_task_list',
+ schema: {
+ group: 'block',
+ content: '(task_list_item|list_item)+',
+ parseDOM: [
+ {
+ priority: HIGHER_PARSE_RULE_PRIORITY,
+ tag: 'ol.task-list',
+ },
+ ],
+ toDOM: () => ['ol', { class: 'task-list' }, 0],
+ },
toMarkdown(state, node) {
state.renderList(node, ' ', () => '1. ');
- }
-}
+ },
+});
diff --git a/app/assets/javascripts/behaviors/markdown/nodes/paragraph.js b/app/assets/javascripts/behaviors/markdown/nodes/paragraph.js
index 5fd098cd46f..310feebb390 100644
--- a/app/assets/javascripts/behaviors/markdown/nodes/paragraph.js
+++ b/app/assets/javascripts/behaviors/markdown/nodes/paragraph.js
@@ -1,24 +1,15 @@
-/* eslint-disable class-methods-use-this */
-
-import { Node } from 'tiptap';
import { defaultMarkdownSerializer } from '~/lib/prosemirror_markdown_serializer';
// Transforms generated HTML back to GFM for Banzai::Filter::MarkdownFilter
-export default class Paragraph extends Node {
- get name() {
- return 'paragraph';
- }
-
- get schema() {
- return {
- content: 'inline*',
- group: 'block',
- parseDOM: [{ tag: 'p' }],
- toDOM: () => ['p', 0],
- };
- }
-
+export default () => ({
+ name: 'paragraph',
+ schema: {
+ content: 'inline*',
+ group: 'block',
+ parseDOM: [{ tag: 'p' }],
+ toDOM: () => ['p', 0],
+ },
toMarkdown(state, node) {
defaultMarkdownSerializer.nodes.paragraph(state, node);
- }
-}
+ },
+});
diff --git a/app/assets/javascripts/behaviors/markdown/nodes/playable.js b/app/assets/javascripts/behaviors/markdown/nodes/playable.js
index 90cbaf9ef4c..7559c2a6a8a 100644
--- a/app/assets/javascripts/behaviors/markdown/nodes/playable.js
+++ b/app/assets/javascripts/behaviors/markdown/nodes/playable.js
@@ -1,7 +1,3 @@
-/* eslint-disable class-methods-use-this */
-/* eslint-disable @gitlab/require-i18n-strings */
-
-import { Node } from 'tiptap';
import { defaultMarkdownSerializer } from '~/lib/prosemirror_markdown_serializer';
/**
@@ -10,62 +6,51 @@ import { defaultMarkdownSerializer } from '~/lib/prosemirror_markdown_serializer
* the `mediaType` property in their constructors.
* @abstract
*/
-export default class Playable extends Node {
- constructor() {
- super();
- this.mediaType = '';
- this.extraElementAttrs = {};
- }
-
- get name() {
- return this.mediaType;
- }
-
- get schema() {
- const attrs = {
- src: {},
- alt: {
- default: null,
- },
- };
-
- const parseDOM = [
+export default ({ mediaType, extraElementAttrs = {} }) => {
+ const attrs = {
+ src: {},
+ alt: {
+ default: null,
+ },
+ };
+ const parseDOM = [
+ {
+ // eslint-disable-next-line @gitlab/require-i18n-strings
+ tag: `.${mediaType}-container`,
+ getAttrs: (el) => ({
+ src: el.querySelector(mediaType).src,
+ alt: el.querySelector(mediaType).dataset.title,
+ }),
+ },
+ ];
+ const toDOM = (node) => [
+ 'span',
+ { class: `media-container ${mediaType}-container` },
+ [
+ mediaType,
{
- tag: `.${this.mediaType}-container`,
- getAttrs: (el) => ({
- src: el.querySelector(this.mediaType).src,
- alt: el.querySelector(this.mediaType).dataset.title,
- }),
+ src: node.attrs.src,
+ controls: true,
+ 'data-setup': '{}',
+ 'data-title': node.attrs.alt,
+ ...extraElementAttrs,
},
- ];
-
- const toDOM = (node) => [
- 'span',
- { class: `media-container ${this.mediaType}-container` },
- [
- this.mediaType,
- {
- src: node.attrs.src,
- controls: true,
- 'data-setup': '{}',
- 'data-title': node.attrs.alt,
- ...this.extraElementAttrs,
- },
- ],
- ['a', { href: node.attrs.src }, node.attrs.alt],
- ];
+ ],
+ ['a', { href: node.attrs.src }, node.attrs.alt],
+ ];
- return {
+ return {
+ name: mediaType,
+ schema: {
attrs,
group: 'inline',
inline: true,
draggable: true,
parseDOM,
toDOM,
- };
- }
-
- toMarkdown(state, node) {
- defaultMarkdownSerializer.nodes.image(state, node);
- }
-}
+ },
+ toMarkdown(state, node) {
+ defaultMarkdownSerializer.nodes.image(state, node);
+ },
+ };
+};
diff --git a/app/assets/javascripts/behaviors/markdown/nodes/reference.js b/app/assets/javascripts/behaviors/markdown/nodes/reference.js
index dd82ea58ea5..9ae6ab07004 100644
--- a/app/assets/javascripts/behaviors/markdown/nodes/reference.js
+++ b/app/assets/javascripts/behaviors/markdown/nodes/reference.js
@@ -1,53 +1,44 @@
-/* eslint-disable class-methods-use-this */
-
-import { Node } from 'tiptap';
import { HIGHER_PARSE_RULE_PRIORITY } from '../constants';
// Transforms generated HTML back to GFM for Banzai::Filter::ReferenceFilter and subclasses
-export default class Reference extends Node {
- get name() {
- return 'reference';
- }
-
- get schema() {
- return {
- inline: true,
- group: 'inline',
- atom: true,
- attrs: {
- className: {},
- referenceType: {},
- originalText: { default: null },
- href: {},
- text: {},
+export default () => ({
+ name: 'reference',
+ schema: {
+ inline: true,
+ group: 'inline',
+ atom: true,
+ attrs: {
+ className: {},
+ referenceType: {},
+ originalText: { default: null },
+ href: {},
+ text: {},
+ },
+ parseDOM: [
+ {
+ tag: 'a.gfm:not([data-link=true])',
+ priority: HIGHER_PARSE_RULE_PRIORITY,
+ getAttrs: (el) => ({
+ className: el.className,
+ referenceType: el.dataset.referenceType,
+ originalText: el.dataset.original,
+ href: el.getAttribute('href'),
+ text: el.textContent,
+ }),
},
- parseDOM: [
- {
- tag: 'a.gfm:not([data-link=true])',
- priority: HIGHER_PARSE_RULE_PRIORITY,
- getAttrs: (el) => ({
- className: el.className,
- referenceType: el.dataset.referenceType,
- originalText: el.dataset.original,
- href: el.getAttribute('href'),
- text: el.textContent,
- }),
- },
- ],
- toDOM: (node) => [
- 'a',
- {
- class: node.attrs.className,
- href: node.attrs.href,
- 'data-reference-type': node.attrs.referenceType,
- 'data-original': node.attrs.originalText,
- },
- node.attrs.text,
- ],
- };
- }
-
+ ],
+ toDOM: (node) => [
+ 'a',
+ {
+ class: node.attrs.className,
+ href: node.attrs.href,
+ 'data-reference-type': node.attrs.referenceType,
+ 'data-original': node.attrs.originalText,
+ },
+ node.attrs.text,
+ ],
+ },
toMarkdown(state, node) {
state.write(node.attrs.originalText || node.attrs.text);
- }
-}
+ },
+});
diff --git a/app/assets/javascripts/behaviors/markdown/nodes/summary.js b/app/assets/javascripts/behaviors/markdown/nodes/summary.js
index 2e36e316d71..eb91b3c981e 100644
--- a/app/assets/javascripts/behaviors/markdown/nodes/summary.js
+++ b/app/assets/javascripts/behaviors/markdown/nodes/summary.js
@@ -1,27 +1,17 @@
-/* eslint-disable class-methods-use-this */
-
-import { Node } from 'tiptap';
-
// Transforms generated HTML back to GFM for Banzai::Filter::MarkdownFilter
-export default class Summary extends Node {
- get name() {
- return 'summary';
- }
-
- get schema() {
- return {
- content: 'text*',
- marks: '',
- defining: true,
- parseDOM: [{ tag: 'summary' }],
- toDOM: () => ['summary', 0],
- };
- }
-
+export default () => ({
+ name: 'summary',
+ schema: {
+ content: 'text*',
+ marks: '',
+ defining: true,
+ parseDOM: [{ tag: 'summary' }],
+ toDOM: () => ['summary', 0],
+ },
toMarkdown(state, node) {
state.write('<summary>');
state.text(node.textContent, false);
state.write('</summary>');
state.closeBlock(node);
- }
-}
+ },
+});
diff --git a/app/assets/javascripts/behaviors/markdown/nodes/table.js b/app/assets/javascripts/behaviors/markdown/nodes/table.js
index a7fcb9227cd..c766f7f1fba 100644
--- a/app/assets/javascripts/behaviors/markdown/nodes/table.js
+++ b/app/assets/javascripts/behaviors/markdown/nodes/table.js
@@ -1,25 +1,15 @@
-/* eslint-disable class-methods-use-this */
-
-import { Node } from 'tiptap';
-
// Transforms generated HTML back to GFM for Banzai::Filter::MarkdownFilter
-export default class Table extends Node {
- get name() {
- return 'table';
- }
-
- get schema() {
- return {
- content: 'table_head table_body',
- group: 'block',
- isolating: true,
- parseDOM: [{ tag: 'table' }],
- toDOM: () => ['table', 0],
- };
- }
-
+export default () => ({
+ name: 'table',
+ schema: {
+ content: 'table_head table_body',
+ group: 'block',
+ isolating: true,
+ parseDOM: [{ tag: 'table' }],
+ toDOM: () => ['table', 0],
+ },
toMarkdown(state, node) {
state.renderContent(node);
state.closeBlock(node);
- }
-}
+ },
+});
diff --git a/app/assets/javascripts/behaviors/markdown/nodes/table_body.js b/app/assets/javascripts/behaviors/markdown/nodes/table_body.js
index 403556dc0c8..0a49fb558ae 100644
--- a/app/assets/javascripts/behaviors/markdown/nodes/table_body.js
+++ b/app/assets/javascripts/behaviors/markdown/nodes/table_body.js
@@ -1,24 +1,14 @@
-/* eslint-disable class-methods-use-this */
-
-import { Node } from 'tiptap';
-
// Transforms generated HTML back to GFM for Banzai::Filter::MarkdownFilter
-export default class TableBody extends Node {
- get name() {
- return 'table_body';
- }
-
- get schema() {
- return {
- content: 'table_row+',
- parseDOM: [{ tag: 'tbody' }],
- toDOM: () => ['tbody', 0],
- };
- }
-
- toMarkdown(state, node) {
+export default () => ({
+ name: 'table_body',
+ schema: {
+ content: 'table_row+',
+ parseDOM: [{ tag: 'tbody' }],
+ toDOM: () => ['tbody', 0],
+ },
+ toMarkdown: (state, node) => {
state.flushClose(1);
state.renderContent(node);
state.closeBlock(node);
- }
-}
+ },
+});
diff --git a/app/assets/javascripts/behaviors/markdown/nodes/table_cell.js b/app/assets/javascripts/behaviors/markdown/nodes/table_cell.js
index ebb66cd4da5..f46344ba43c 100644
--- a/app/assets/javascripts/behaviors/markdown/nodes/table_cell.js
+++ b/app/assets/javascripts/behaviors/markdown/nodes/table_cell.js
@@ -1,35 +1,25 @@
-/* eslint-disable class-methods-use-this */
-
-import { Node } from 'tiptap';
-
// Transforms generated HTML back to GFM for Banzai::Filter::MarkdownFilter
-export default class TableCell extends Node {
- get name() {
- return 'table_cell';
- }
-
- get schema() {
- return {
- attrs: {
- header: { default: false },
- align: { default: null },
+export default () => ({
+ name: 'table_cell',
+ schema: {
+ attrs: {
+ header: { default: false },
+ align: { default: null },
+ },
+ content: 'inline*',
+ isolating: true,
+ parseDOM: [
+ {
+ tag: 'td, th',
+ getAttrs: (el) => ({
+ header: el.tagName === 'TH',
+ align: el.getAttribute('align') || el.style.textAlign,
+ }),
},
- content: 'inline*',
- isolating: true,
- parseDOM: [
- {
- tag: 'td, th',
- getAttrs: (el) => ({
- header: el.tagName === 'TH',
- align: el.getAttribute('align') || el.style.textAlign,
- }),
- },
- ],
- toDOM: (node) => [node.attrs.header ? 'th' : 'td', { align: node.attrs.align }, 0],
- };
- }
-
- toMarkdown(state, node) {
+ ],
+ toDOM: (node) => [node.attrs.header ? 'th' : 'td', { align: node.attrs.align }, 0],
+ },
+ toMarkdown: (state, node) => {
state.renderInline(node);
- }
-}
+ },
+});
diff --git a/app/assets/javascripts/behaviors/markdown/nodes/table_head.js b/app/assets/javascripts/behaviors/markdown/nodes/table_head.js
index 4cb94bf088c..2e9b53ee0ac 100644
--- a/app/assets/javascripts/behaviors/markdown/nodes/table_head.js
+++ b/app/assets/javascripts/behaviors/markdown/nodes/table_head.js
@@ -1,24 +1,14 @@
-/* eslint-disable class-methods-use-this */
-
-import { Node } from 'tiptap';
-
// Transforms generated HTML back to GFM for Banzai::Filter::MarkdownFilter
-export default class TableHead extends Node {
- get name() {
- return 'table_head';
- }
-
- get schema() {
- return {
- content: 'table_header_row',
- parseDOM: [{ tag: 'thead' }],
- toDOM: () => ['thead', 0],
- };
- }
-
- toMarkdown(state, node) {
+export default () => ({
+ name: 'table_head',
+ schema: {
+ content: 'table_header_row',
+ parseDOM: [{ tag: 'thead' }],
+ toDOM: () => ['thead', 0],
+ },
+ toMarkdown: (state, node) => {
state.flushClose(1);
state.renderContent(node);
state.closeBlock(node);
- }
-}
+ },
+});
diff --git a/app/assets/javascripts/behaviors/markdown/nodes/table_header_row.js b/app/assets/javascripts/behaviors/markdown/nodes/table_header_row.js
index 2cb2bb9e7fe..d8aa497066c 100644
--- a/app/assets/javascripts/behaviors/markdown/nodes/table_header_row.js
+++ b/app/assets/javascripts/behaviors/markdown/nodes/table_header_row.js
@@ -1,31 +1,23 @@
-/* eslint-disable class-methods-use-this */
-
import { HIGHER_PARSE_RULE_PRIORITY } from '../constants';
import TableRow from './table_row';
const CENTER_ALIGN = 'center';
// Transforms generated HTML back to GFM for Banzai::Filter::MarkdownFilter
-export default class TableHeaderRow extends TableRow {
- get name() {
- return 'table_header_row';
- }
-
- get schema() {
- return {
- content: 'table_cell+',
- parseDOM: [
- {
- tag: 'thead tr',
- priority: HIGHER_PARSE_RULE_PRIORITY,
- },
- ],
- toDOM: () => ['tr', 0],
- };
- }
-
- toMarkdown(state, node) {
- const cellWidths = super.toMarkdown(state, node);
+export default () => ({
+ name: 'table_header_row',
+ schema: {
+ content: 'table_cell+',
+ parseDOM: [
+ {
+ tag: 'thead tr',
+ priority: HIGHER_PARSE_RULE_PRIORITY,
+ },
+ ],
+ toDOM: () => ['tr', 0],
+ },
+ toMarkdown: (state, node) => {
+ const cellWidths = TableRow().toMarkdown(state, node);
state.flushClose(1);
@@ -40,5 +32,5 @@ export default class TableHeaderRow extends TableRow {
state.write('|');
state.closeBlock(node);
- }
-}
+ },
+});
diff --git a/app/assets/javascripts/behaviors/markdown/nodes/table_of_contents.js b/app/assets/javascripts/behaviors/markdown/nodes/table_of_contents.js
index db9072acc3a..4a0256c4644 100644
--- a/app/assets/javascripts/behaviors/markdown/nodes/table_of_contents.js
+++ b/app/assets/javascripts/behaviors/markdown/nodes/table_of_contents.js
@@ -1,35 +1,26 @@
-/* eslint-disable class-methods-use-this */
-
-import { Node } from 'tiptap';
import { __ } from '~/locale';
import { HIGHER_PARSE_RULE_PRIORITY } from '../constants';
// Transforms generated HTML back to GFM for Banzai::Filter::TableOfContentsFilter
-export default class TableOfContents extends Node {
- get name() {
- return 'table_of_contents';
- }
-
- get schema() {
- return {
- group: 'block',
- atom: true,
- parseDOM: [
- {
- tag: 'ul.section-nav',
- priority: HIGHER_PARSE_RULE_PRIORITY,
- },
- {
- tag: 'p.table-of-contents',
- priority: HIGHER_PARSE_RULE_PRIORITY,
- },
- ],
- toDOM: () => ['p', { class: 'table-of-contents' }, __('Table of Contents')],
- };
- }
-
- toMarkdown(state, node) {
+export default () => ({
+ name: 'table_of_contents',
+ schema: {
+ group: 'block',
+ atom: true,
+ parseDOM: [
+ {
+ tag: 'ul.section-nav',
+ priority: HIGHER_PARSE_RULE_PRIORITY,
+ },
+ {
+ tag: 'p.table-of-contents',
+ priority: HIGHER_PARSE_RULE_PRIORITY,
+ },
+ ],
+ toDOM: () => ['p', { class: 'table-of-contents' }, __('Table of Contents')],
+ },
+ toMarkdown: (state, node) => {
state.write('[[_TOC_]]');
state.closeBlock(node);
- }
-}
+ },
+});
diff --git a/app/assets/javascripts/behaviors/markdown/nodes/table_row.js b/app/assets/javascripts/behaviors/markdown/nodes/table_row.js
index 5852502773a..3830dae4f0d 100644
--- a/app/assets/javascripts/behaviors/markdown/nodes/table_row.js
+++ b/app/assets/javascripts/behaviors/markdown/nodes/table_row.js
@@ -1,22 +1,12 @@
-/* eslint-disable class-methods-use-this */
-
-import { Node } from 'tiptap';
-
// Transforms generated HTML back to GFM for Banzai::Filter::MarkdownFilter
-export default class TableRow extends Node {
- get name() {
- return 'table_row';
- }
-
- get schema() {
- return {
- content: 'table_cell+',
- parseDOM: [{ tag: 'tr' }],
- toDOM: () => ['tr', 0],
- };
- }
-
- toMarkdown(state, node) {
+export default () => ({
+ name: 'table_row',
+ schema: {
+ content: 'table_cell+',
+ parseDOM: [{ tag: 'tr' }],
+ toDOM: () => ['tr', 0],
+ },
+ toMarkdown: (state, node) => {
const cellWidths = [];
state.flushClose(1);
@@ -34,5 +24,5 @@ export default class TableRow extends Node {
state.closeBlock(node);
return cellWidths;
- }
-}
+ },
+});
diff --git a/app/assets/javascripts/behaviors/markdown/nodes/task_list.js b/app/assets/javascripts/behaviors/markdown/nodes/task_list.js
index 35ba2eb0674..3c3812ad8f7 100644
--- a/app/assets/javascripts/behaviors/markdown/nodes/task_list.js
+++ b/app/assets/javascripts/behaviors/markdown/nodes/task_list.js
@@ -1,29 +1,20 @@
-/* eslint-disable class-methods-use-this */
-
-import { Node } from 'tiptap';
import { HIGHER_PARSE_RULE_PRIORITY } from '../constants';
// Transforms generated HTML back to GFM for Banzai::Filter::TaskListFilter
-export default class TaskList extends Node {
- get name() {
- return 'task_list';
- }
-
- get schema() {
- return {
- group: 'block',
- content: '(task_list_item|list_item)+',
- parseDOM: [
- {
- priority: HIGHER_PARSE_RULE_PRIORITY,
- tag: 'ul.task-list',
- },
- ],
- toDOM: () => ['ul', { class: 'task-list' }, 0],
- };
- }
-
+export default () => ({
+ name: 'task_list',
+ schema: {
+ group: 'block',
+ content: '(task_list_item|list_item)+',
+ parseDOM: [
+ {
+ priority: HIGHER_PARSE_RULE_PRIORITY,
+ tag: 'ul.task-list',
+ },
+ ],
+ toDOM: () => ['ul', { class: 'task-list' }, 0],
+ },
toMarkdown(state, node) {
state.renderList(node, ' ', () => '* ');
- }
-}
+ },
+});
diff --git a/app/assets/javascripts/behaviors/markdown/nodes/task_list_item.js b/app/assets/javascripts/behaviors/markdown/nodes/task_list_item.js
index 56c2b17286d..10ffce9b1b8 100644
--- a/app/assets/javascripts/behaviors/markdown/nodes/task_list_item.js
+++ b/app/assets/javascripts/behaviors/markdown/nodes/task_list_item.js
@@ -1,50 +1,38 @@
-/* eslint-disable class-methods-use-this */
-
-import { Node } from 'tiptap';
import { HIGHER_PARSE_RULE_PRIORITY } from '../constants';
// Transforms generated HTML back to GFM for Banzai::Filter::TaskListFilter
-export default class TaskListItem extends Node {
- get name() {
- return 'task_list_item';
- }
-
- get schema() {
- return {
- attrs: {
- done: {
- default: false,
- },
+export default () => ({
+ name: 'task_list_item',
+ schema: {
+ attrs: {
+ done: {
+ default: false,
},
- defining: true,
- draggable: false,
- content: 'paragraph block*',
- parseDOM: [
- {
- priority: HIGHER_PARSE_RULE_PRIORITY,
- tag: 'li.task-list-item',
- getAttrs: (el) => {
- const checkbox = el.querySelector('input[type=checkbox].task-list-item-checkbox');
- return { done: checkbox && checkbox.checked };
- },
+ },
+ defining: true,
+ draggable: false,
+ content: 'paragraph block*',
+ parseDOM: [
+ {
+ priority: HIGHER_PARSE_RULE_PRIORITY,
+ tag: 'li.task-list-item',
+ getAttrs: (el) => {
+ const checkbox = el.querySelector('input[type=checkbox].task-list-item-checkbox');
+ return { done: checkbox && checkbox.checked };
},
- ],
- toDOM(node) {
- return [
- 'li',
- { class: 'task-list-item' },
- [
- 'input',
- { type: 'checkbox', class: 'task-list-item-checkbox', checked: node.attrs.done },
- ],
- ['div', { class: 'todo-content' }, 0],
- ];
},
- };
- }
-
+ ],
+ toDOM(node) {
+ return [
+ 'li',
+ { class: 'task-list-item' },
+ ['input', { type: 'checkbox', class: 'task-list-item-checkbox', checked: node.attrs.done }],
+ ['div', { class: 'todo-content' }, 0],
+ ];
+ },
+ },
toMarkdown(state, node) {
state.write(`[${node.attrs.done ? 'x' : ' '}] `);
state.renderContent(node);
- }
-}
+ },
+});
diff --git a/app/assets/javascripts/behaviors/markdown/nodes/text.js b/app/assets/javascripts/behaviors/markdown/nodes/text.js
index 0dc77a12f5c..0e1f0bc0e40 100644
--- a/app/assets/javascripts/behaviors/markdown/nodes/text.js
+++ b/app/assets/javascripts/behaviors/markdown/nodes/text.js
@@ -1,20 +1,11 @@
-/* eslint-disable class-methods-use-this */
-
-import { Node } from 'tiptap';
import { defaultMarkdownSerializer } from '~/lib/prosemirror_markdown_serializer';
-export default class Text extends Node {
- get name() {
- return 'text';
- }
-
- get schema() {
- return {
- group: 'inline',
- };
- }
-
+export default () => ({
+ name: 'text',
+ schema: {
+ group: 'inline',
+ },
toMarkdown(state, node) {
defaultMarkdownSerializer.nodes.text(state, node);
- }
-}
+ },
+});
diff --git a/app/assets/javascripts/behaviors/markdown/nodes/video.js b/app/assets/javascripts/behaviors/markdown/nodes/video.js
index 68085c2c416..aa1088826da 100644
--- a/app/assets/javascripts/behaviors/markdown/nodes/video.js
+++ b/app/assets/javascripts/behaviors/markdown/nodes/video.js
@@ -1,10 +1,4 @@
-import Playable from './playable';
+import playable from './playable';
// Transforms generated HTML back to GFM for Banzai::Filter::VideoLinkFilter
-export default class Video extends Playable {
- constructor() {
- super();
- this.mediaType = 'video';
- this.extraElementAttrs = { width: '400' };
- }
-}
+export default () => playable({ mediaType: 'video', extraElementAttrs: { width: '400' } });
diff --git a/app/assets/javascripts/behaviors/markdown/render_sandboxed_mermaid.js b/app/assets/javascripts/behaviors/markdown/render_sandboxed_mermaid.js
index 1d54a1b0c04..85a991a1ec9 100644
--- a/app/assets/javascripts/behaviors/markdown/render_sandboxed_mermaid.js
+++ b/app/assets/javascripts/behaviors/markdown/render_sandboxed_mermaid.js
@@ -88,7 +88,7 @@ function renderMermaidEl(el, source) {
const iframeEl = document.createElement('iframe');
setAttributes(iframeEl, {
src: getSandboxFrameSrc(),
- sandbox: 'allow-scripts',
+ sandbox: 'allow-scripts allow-popups',
frameBorder: 0,
scrolling: 'no',
width: '100%',
diff --git a/app/assets/javascripts/behaviors/markdown/schema.js b/app/assets/javascripts/behaviors/markdown/schema.js
index 8bea24584cc..1b0f46ff4cb 100644
--- a/app/assets/javascripts/behaviors/markdown/schema.js
+++ b/app/assets/javascripts/behaviors/markdown/schema.js
@@ -1,24 +1,20 @@
import { Schema } from 'prosemirror-model';
import editorExtensions from './editor_extensions';
-const nodes = editorExtensions
- .filter((extension) => extension.type === 'node')
- .reduce(
- (ns, { name, schema }) => ({
- ...ns,
- [name]: schema,
- }),
- {},
- );
+const nodes = editorExtensions.nodes.reduce(
+ (ns, { name, schema }) => ({
+ ...ns,
+ [name]: schema,
+ }),
+ {},
+);
-const marks = editorExtensions
- .filter((extension) => extension.type === 'mark')
- .reduce(
- (ms, { name, schema }) => ({
- ...ms,
- [name]: schema,
- }),
- {},
- );
+const marks = editorExtensions.marks.reduce(
+ (ms, { name, schema }) => ({
+ ...ms,
+ [name]: schema,
+ }),
+ {},
+);
export default new Schema({ nodes, marks });
diff --git a/app/assets/javascripts/behaviors/markdown/serializer.js b/app/assets/javascripts/behaviors/markdown/serializer.js
index a5f97d7748a..e3e8a380cd5 100644
--- a/app/assets/javascripts/behaviors/markdown/serializer.js
+++ b/app/assets/javascripts/behaviors/markdown/serializer.js
@@ -1,24 +1,20 @@
import { MarkdownSerializer } from '~/lib/prosemirror_markdown_serializer';
import editorExtensions from './editor_extensions';
-const nodes = editorExtensions
- .filter((extension) => extension.type === 'node')
- .reduce(
- (ns, { name, toMarkdown }) => ({
- ...ns,
- [name]: toMarkdown,
- }),
- {},
- );
+const nodes = editorExtensions.nodes.reduce(
+ (ns, { name, toMarkdown }) => ({
+ ...ns,
+ [name]: toMarkdown,
+ }),
+ {},
+);
-const marks = editorExtensions
- .filter((extension) => extension.type === 'mark')
- .reduce(
- (ms, { name, toMarkdown }) => ({
- ...ms,
- [name]: toMarkdown,
- }),
- {},
- );
+const marks = editorExtensions.marks.reduce(
+ (ms, { name, toMarkdown }) => ({
+ ...ms,
+ [name]: toMarkdown,
+ }),
+ {},
+);
export default new MarkdownSerializer(nodes, marks);
diff --git a/app/assets/javascripts/behaviors/shortcuts/keybindings.js b/app/assets/javascripts/behaviors/shortcuts/keybindings.js
index b27dccabdf8..23b66405844 100644
--- a/app/assets/javascripts/behaviors/shortcuts/keybindings.js
+++ b/app/assets/javascripts/behaviors/shortcuts/keybindings.js
@@ -131,6 +131,13 @@ export const ITALIC_TEXT = {
customizable: false,
};
+export const STRIKETHROUGH_TEXT = {
+ id: 'editing.strikethroughText',
+ description: __('Strikethrough text'),
+ defaultKeys: ['mod+shift+x'],
+ customizable: false,
+};
+
export const LINK_TEXT = {
id: 'editing.linkText',
description: __('Link text'),
@@ -511,7 +518,14 @@ export const GLOBAL_SHORTCUTS_GROUP = {
export const EDITING_SHORTCUTS_GROUP = {
id: 'editing',
name: __('Editing'),
- keybindings: [BOLD_TEXT, ITALIC_TEXT, LINK_TEXT, TOGGLE_MARKDOWN_PREVIEW, EDIT_RECENT_COMMENT],
+ keybindings: [
+ BOLD_TEXT,
+ ITALIC_TEXT,
+ STRIKETHROUGH_TEXT,
+ LINK_TEXT,
+ TOGGLE_MARKDOWN_PREVIEW,
+ EDIT_RECENT_COMMENT,
+ ],
};
export const WIKI_SHORTCUTS_GROUP = {
diff --git a/app/assets/javascripts/behaviors/shortcuts/shortcuts.js b/app/assets/javascripts/behaviors/shortcuts/shortcuts.js
index 9297b14aac9..4d78c7b56a0 100644
--- a/app/assets/javascripts/behaviors/shortcuts/shortcuts.js
+++ b/app/assets/javascripts/behaviors/shortcuts/shortcuts.js
@@ -173,12 +173,7 @@ export default class Shortcuts {
e.preventDefault();
const canaryCookieName = 'gitlab_canary';
const currentValue = parseBoolean(getCookie(canaryCookieName));
- setCookie(canaryCookieName, (!currentValue).toString(), {
- expires: 365,
- path: '/',
- // next.gitlab.com uses a leading period. See https://gitlab.com/gitlab-org/gitlab/-/issues/350186
- domain: `.${window.location.hostname}`,
- });
+ setCookie(canaryCookieName, (!currentValue).toString(), { expires: 365, path: '/' });
refreshCurrentPage();
}
diff --git a/app/assets/javascripts/blob/components/blob_header.vue b/app/assets/javascripts/blob/components/blob_header.vue
index c5ab28e6ec5..8a4fe1a9025 100644
--- a/app/assets/javascripts/blob/components/blob_header.vue
+++ b/app/assets/javascripts/blob/components/blob_header.vue
@@ -63,6 +63,9 @@ export default {
isEmpty() {
return this.blob.rawSize === 0;
},
+ blobSwitcherDocIcon() {
+ return this.blob.richViewer?.fileType === 'csv' ? 'table' : 'document';
+ },
},
watch: {
viewer(newVal, oldVal) {
@@ -90,7 +93,7 @@ export default {
</div>
<div class="gl-sm-display-flex file-actions">
- <viewer-switcher v-if="showViewerSwitcher" v-model="viewer" />
+ <viewer-switcher v-if="showViewerSwitcher" v-model="viewer" :doc-icon="blobSwitcherDocIcon" />
<slot name="actions"></slot>
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 12bcb24b0cc..61baf4fa495 100644
--- a/app/assets/javascripts/blob/components/blob_header_default_actions.vue
+++ b/app/assets/javascripts/blob/components/blob_header_default_actions.vue
@@ -1,6 +1,7 @@
<script>
import { GlButton, GlButtonGroup, GlTooltipDirective } from '@gitlab/ui';
import { sprintf, s__ } from '~/locale';
+import { setUrlParams, relativePathToAbsolute, getBaseURL } from '~/lib/utils/url_utility';
import {
BTN_COPY_CONTENTS_TITLE,
BTN_DOWNLOAD_TITLE,
@@ -56,7 +57,7 @@ export default {
},
computed: {
downloadUrl() {
- return `${this.rawPath}?inline=false`;
+ return setUrlParams({ inline: false }, relativePathToAbsolute(this.rawPath, getBaseURL()));
},
copyDisabled() {
return this.activeViewer === RICH_BLOB_VIEWER;
diff --git a/app/assets/javascripts/blob/components/blob_header_viewer_switcher.vue b/app/assets/javascripts/blob/components/blob_header_viewer_switcher.vue
index b2546d47694..7351df0f93b 100644
--- a/app/assets/javascripts/blob/components/blob_header_viewer_switcher.vue
+++ b/app/assets/javascripts/blob/components/blob_header_viewer_switcher.vue
@@ -21,6 +21,11 @@ export default {
default: SIMPLE_BLOB_VIEWER,
required: false,
},
+ docIcon: {
+ type: String,
+ default: 'document',
+ required: false,
+ },
},
computed: {
isSimpleViewer() {
@@ -62,7 +67,7 @@ export default {
:aria-label="$options.RICH_BLOB_VIEWER_TITLE"
:title="$options.RICH_BLOB_VIEWER_TITLE"
:selected="isRichViewer"
- icon="document"
+ :icon="docIcon"
category="primary"
variant="default"
class="js-blob-viewer-switch-btn"
diff --git a/app/assets/javascripts/blob/csv/csv_viewer.vue b/app/assets/javascripts/blob/csv/csv_viewer.vue
index 1f9d20a487f..169167625e0 100644
--- a/app/assets/javascripts/blob/csv/csv_viewer.vue
+++ b/app/assets/javascripts/blob/csv/csv_viewer.vue
@@ -14,6 +14,11 @@ export default {
type: String,
required: true,
},
+ remoteFile: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
},
data() {
return {
@@ -23,14 +28,29 @@ export default {
};
},
mounted() {
- const parsed = Papa.parse(this.csv, { skipEmptyLines: true });
- this.items = parsed.data;
-
- if (parsed.errors.length) {
- this.papaParseErrors = parsed.errors;
+ if (!this.remoteFile) {
+ const parsed = Papa.parse(this.csv, { skipEmptyLines: true });
+ this.handleParsedData(parsed);
+ } else {
+ Papa.parse(this.csv, {
+ download: true,
+ skipEmptyLines: true,
+ complete: (parsed) => {
+ this.handleParsedData(parsed);
+ },
+ });
}
+ },
+ methods: {
+ handleParsedData(parsed) {
+ this.items = parsed.data;
- this.loading = false;
+ if (parsed.errors.length) {
+ this.papaParseErrors = parsed.errors;
+ }
+
+ this.loading = false;
+ },
},
};
</script>
diff --git a/app/assets/javascripts/blob/template_selector.js b/app/assets/javascripts/blob/template_selector.js
index 9fa70ce3c62..7eb699eacbe 100644
--- a/app/assets/javascripts/blob/template_selector.js
+++ b/app/assets/javascripts/blob/template_selector.js
@@ -2,6 +2,7 @@
import $ from 'jquery';
import initDeprecatedJQueryDropdown from '~/deprecated_jquery_dropdown';
+import { loadingIconForLegacyJS } from '~/loading_icon_for_legacy_js';
export default class TemplateSelector {
constructor({ dropdown, data, pattern, wrapper, editor, $input } = {}) {
@@ -10,10 +11,9 @@ export default class TemplateSelector {
this.dropdown = dropdown;
this.$dropdownContainer = wrapper;
this.$filenameInput = $input || $('#file_name');
- this.$dropdownIcon = $('.dropdown-menu-toggle-icon', dropdown);
- this.$loadingIcon = $(
- '<div class="gl-spinner gl-spinner-orange gl-spinner-sm gl-absolute gl-top-3 gl-right-3 gl-display-none"></div>',
- ).insertAfter(this.$dropdownIcon);
+ this.dropdownIcon = dropdown[0].querySelector('.dropdown-menu-toggle-icon');
+ this.loadingIcon = loadingIconForLegacyJS({ classes: ['gl-display-none'] });
+ this.dropdownIcon.parentNode.insertBefore(this.loadingIcon, this.dropdownIcon.nextSibling);
this.initDropdown(dropdown, data);
this.listenForFilenameInput();
@@ -78,7 +78,12 @@ export default class TemplateSelector {
setEditorContent(file, { skipFocus } = {}) {
if (!file) return;
- const newValue = file.content;
+ let newValue = file.content;
+
+ const urlParams = new URLSearchParams(window.location.search);
+ if (urlParams.has('issue[description]')) {
+ newValue += `\n${urlParams.get('issue[description]')}`;
+ }
this.editor.setValue(newValue, 1);
@@ -95,12 +100,12 @@ export default class TemplateSelector {
}
startLoadingSpinner() {
- this.$loadingIcon.removeClass('gl-display-none');
- this.$dropdownIcon.addClass('gl-display-none');
+ this.loadingIcon.classList.remove('gl-display-none');
+ this.dropdownIcon.classList.add('gl-display-none');
}
stopLoadingSpinner() {
- this.$loadingIcon.addClass('gl-display-none');
- this.$dropdownIcon.removeClass('gl-display-none');
+ this.loadingIcon.classList.add('gl-display-none');
+ this.dropdownIcon.classList.remove('gl-display-none');
}
}
diff --git a/app/assets/javascripts/blob_edit/blob_bundle.js b/app/assets/javascripts/blob_edit/blob_bundle.js
index 2d9ffda06d0..425de914c17 100644
--- a/app/assets/javascripts/blob_edit/blob_bundle.js
+++ b/app/assets/javascripts/blob_edit/blob_bundle.js
@@ -2,7 +2,6 @@
import $ from 'jquery';
import initPopover from '~/blob/suggest_gitlab_ci_yml';
-import initCodeQualityWalkthrough from '~/code_quality_walkthrough';
import createFlash from '~/flash';
import { disableButtonIfEmptyField, setCookie } from '~/lib/utils/common_utils';
import Tracking from '~/tracking';
@@ -39,13 +38,6 @@ const initPopovers = () => {
}
};
-const initCodeQualityWalkthroughStep = () => {
- const codeQualityWalkthroughEl = document.querySelector('.js-code-quality-walkthrough');
- if (codeQualityWalkthroughEl) {
- initCodeQualityWalkthrough(codeQualityWalkthroughEl);
- }
-};
-
export const initUploadForm = () => {
const uploadBlobForm = $('.js-upload-blob-form');
if (uploadBlobForm.length) {
@@ -71,7 +63,7 @@ export default () => {
const isMarkdown = editBlobForm.data('is-markdown');
const previewMarkdownPath = editBlobForm.data('previewMarkdownPath');
const commitButton = $('.js-commit-button');
- const cancelLink = $('.btn.btn-cancel');
+ const cancelLink = $('#cancel-changes');
import('./edit_blob')
.then(({ default: EditBlob } = {}) => {
@@ -84,7 +76,6 @@ export default () => {
previewMarkdownPath,
});
initPopovers();
- initCodeQualityWalkthroughStep();
})
.catch((e) =>
createFlash({
diff --git a/app/assets/javascripts/boards/boards_util.js b/app/assets/javascripts/boards/boards_util.js
index 7e4d3ebb686..96cc774a280 100644
--- a/app/assets/javascripts/boards/boards_util.js
+++ b/app/assets/javascripts/boards/boards_util.js
@@ -1,5 +1,6 @@
import { sortBy, cloneDeep } from 'lodash';
-import { isGid } from '~/graphql_shared/utils';
+import { TYPE_BOARD, TYPE_ITERATION, TYPE_MILESTONE, TYPE_USER } from '~/graphql_shared/constants';
+import { isGid, convertToGraphQLId } from '~/graphql_shared/utils';
import { ListType, MilestoneIDs, AssigneeFilterType, MilestoneFilterType } from './constants';
export function getMilestone() {
@@ -80,19 +81,22 @@ export function formatListsPageInfo(lists) {
}
export function fullBoardId(boardId) {
- return `gid://gitlab/Board/${boardId}`;
+ if (!boardId) {
+ return null;
+ }
+ return convertToGraphQLId(TYPE_BOARD, boardId);
}
export function fullIterationId(id) {
- return `gid://gitlab/Iteration/${id}`;
+ return convertToGraphQLId(TYPE_ITERATION, id);
}
export function fullUserId(id) {
- return `gid://gitlab/User/${id}`;
+ return convertToGraphQLId(TYPE_USER, id);
}
export function fullMilestoneId(id) {
- return `gid://gitlab/Milestone/${id}`;
+ return convertToGraphQLId(TYPE_MILESTONE, id);
}
export function fullLabelId(label) {
diff --git a/app/assets/javascripts/boards/components/board_filtered_search.vue b/app/assets/javascripts/boards/components/board_filtered_search.vue
index 45192b5304a..95d4fd5bc0a 100644
--- a/app/assets/javascripts/boards/components/board_filtered_search.vue
+++ b/app/assets/javascripts/boards/components/board_filtered_search.vue
@@ -151,10 +151,10 @@ export default {
});
}
- if (this.filterParams['not[iteration_id]']) {
+ if (this.filterParams['not[iterationId]']) {
filteredSearchValue.push({
- type: 'iteration_id',
- value: { data: this.filterParams['not[iteration_id]'], operator: '!=' },
+ type: 'iteration',
+ value: { data: this.filterParams['not[iterationId]'], operator: '!=' },
});
}
diff --git a/app/assets/javascripts/boards/components/board_form.vue b/app/assets/javascripts/boards/components/board_form.vue
index cc048e2af1a..5fcf9514708 100644
--- a/app/assets/javascripts/boards/components/board_form.vue
+++ b/app/assets/javascripts/boards/components/board_form.vue
@@ -1,11 +1,9 @@
<script>
import { GlModal, GlAlert } from '@gitlab/ui';
import { mapGetters, mapActions, mapState } from 'vuex';
-import { TYPE_USER, TYPE_ITERATION, TYPE_MILESTONE } from '~/graphql_shared/constants';
-import { convertToGraphQLId, getIdFromGraphQLId } from '~/graphql_shared/utils';
import { getParameterByName, visitUrl } from '~/lib/utils/url_utility';
import { __, s__ } from '~/locale';
-import { fullLabelId } from '../boards_util';
+import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import { formType } from '../constants';
import createBoardMutation from '../graphql/board_create.mutation.graphql';
@@ -18,6 +16,7 @@ const boardDefaults = {
name: '',
labels: [],
milestone: {},
+ iterationCadence: {},
iteration: {},
assignee: {},
weight: null,
@@ -44,6 +43,7 @@ export default {
BoardConfigurationOptions,
GlAlert,
},
+ mixins: [glFeatureFlagMixin()],
inject: {
fullPath: {
default: '',
@@ -158,33 +158,8 @@ export default {
groupPath: this.isGroupBoard ? this.fullPath : undefined,
};
},
- issueBoardScopeMutationVariables() {
- return {
- weight: this.board.weight,
- assigneeId: this.board.assignee?.id
- ? convertToGraphQLId(TYPE_USER, this.board.assignee.id)
- : null,
- // Temporarily converting to milestone ID due to https://gitlab.com/gitlab-org/gitlab/-/issues/344779
- milestoneId: this.board.milestone?.id
- ? convertToGraphQLId(TYPE_MILESTONE, getIdFromGraphQLId(this.board.milestone.id))
- : null,
- // Temporarily converting to iteration ID due to https://gitlab.com/gitlab-org/gitlab/-/issues/344779
- iterationId: this.board.iteration?.id
- ? convertToGraphQLId(TYPE_ITERATION, getIdFromGraphQLId(this.board.iteration.id))
- : null,
- };
- },
- boardScopeMutationVariables() {
- return {
- labelIds: this.board.labels.map(fullLabelId),
- ...(this.isIssueBoard && this.issueBoardScopeMutationVariables),
- };
- },
mutationVariables() {
- return {
- ...this.baseMutationVariables,
- ...(this.scopedIssueBoardFeatureEnabled ? this.boardScopeMutationVariables : {}),
- };
+ return this.baseMutationVariables;
},
},
mounted() {
@@ -259,9 +234,12 @@ export default {
this.board = { ...boardDefaults, ...this.currentBoard };
}
},
- setIteration(iterationId) {
+ setIteration(iteration) {
+ if (this.glFeatures.iterationCadences) {
+ this.board.iterationCadenceId = iteration.iterationCadenceId;
+ }
this.$set(this.board, 'iteration', {
- id: iterationId,
+ id: iteration.id,
});
},
setBoardLabels(labels) {
diff --git a/app/assets/javascripts/boards/components/board_list_header.vue b/app/assets/javascripts/boards/components/board_list_header.vue
index 6835d83a66c..46b28d20da9 100644
--- a/app/assets/javascripts/boards/components/board_list_header.vue
+++ b/app/assets/javascripts/boards/components/board_list_header.vue
@@ -89,10 +89,6 @@ export default {
listTitle() {
return this.list?.label?.description || this.list?.assignee?.name || this.list.title || '';
},
- listIterationPeriod() {
- const iteration = this.list?.iteration;
- return iteration ? this.getIterationPeriod(iteration) : '';
- },
isIterationList() {
return this.listType === ListType.iteration;
},
@@ -108,9 +104,6 @@ export default {
showIterationListDetails() {
return this.isIterationList && this.showListDetails;
},
- iterationCadencesAvailable() {
- return this.isIterationList && this.glFeatures.iterationCadences;
- },
showListDetails() {
return !this.list.collapsed || !this.isSwimlanesHeader;
},
@@ -344,13 +337,6 @@ export default {
class="board-title-main-text gl-text-truncate"
>
{{ listTitle }}
- <span
- v-if="iterationCadencesAvailable"
- class="gl-display-inline-block gl-text-gray-400"
- data-testid="board-list-iteration-period"
- >
- {{ listIterationPeriod }}</span
- >
</span>
<span
v-if="listType === 'assignee'"
diff --git a/app/assets/javascripts/boards/components/boards_selector.vue b/app/assets/javascripts/boards/components/boards_selector.vue
index 6dbb1ea0050..91fdfd668fc 100644
--- a/app/assets/javascripts/boards/components/boards_selector.vue
+++ b/app/assets/javascripts/boards/components/boards_selector.vue
@@ -101,6 +101,7 @@ export default {
},
update(data) {
const board = data.workspace?.board;
+ this.setBoardConfig(board);
return {
...board,
labels: board?.labels?.nodes,
@@ -170,7 +171,7 @@ export default {
eventHub.$off('showBoardModal', this.showPage);
},
methods: {
- ...mapActions(['setError']),
+ ...mapActions(['setError', 'setBoardConfig']),
showPage(page) {
this.currentPage = page;
},
@@ -315,9 +316,7 @@ export default {
<gl-dropdown-item v-if="hasMissingBoards" class="no-pointer-events">
{{
- s__(
- 'IssueBoards|Some of your boards are hidden, activate a license to see them again.',
- )
+ s__('IssueBoards|Some of your boards are hidden, add a license to see them again.')
}}
</gl-dropdown-item>
</div>
diff --git a/app/assets/javascripts/boards/filtered_search_boards.js b/app/assets/javascripts/boards/filtered_search_boards.js
deleted file mode 100644
index 72586970008..00000000000
--- a/app/assets/javascripts/boards/filtered_search_boards.js
+++ /dev/null
@@ -1,81 +0,0 @@
-import { transformBoardConfig } from 'ee_else_ce/boards/boards_util';
-import FilteredSearchManager from 'ee_else_ce/filtered_search/filtered_search_manager';
-import IssuableFilteredSearchTokenKeys from 'ee_else_ce/filtered_search/issuable_filtered_search_token_keys';
-import { updateHistory } from '~/lib/utils/url_utility';
-import FilteredSearchContainer from '../filtered_search/container';
-import vuexstore from './stores';
-
-export default class FilteredSearchBoards extends FilteredSearchManager {
- constructor(store, updateUrl = false, cantEdit = []) {
- super({
- page: 'boards',
- isGroupDecendent: true,
- stateFiltersSelector: '.issues-state-filters',
- isGroup: IS_EE,
- useDefaultState: false,
- filteredSearchTokenKeys: IssuableFilteredSearchTokenKeys,
- });
-
- this.store = store;
- this.updateUrl = updateUrl;
-
- // Issue boards is slightly different, we handle all the requests async
- // instead or reloading the page, we just re-fire the list ajax requests
- this.isHandledAsync = true;
- this.cantEdit = cantEdit.filter((i) => typeof i === 'string');
- this.cantEditWithValue = cantEdit.filter((i) => typeof i === 'object');
-
- if (vuexstore.state.boardConfig) {
- const boardConfigPath = transformBoardConfig(vuexstore.state.boardConfig);
- // TODO Refactor: https://gitlab.com/gitlab-org/gitlab/-/issues/329274
- // here we are using "window.location.search" as a temporary store
- // only to unpack the params and do another validation inside
- // 'performSearch' and 'setFilter' vuex actions.
- if (boardConfigPath !== '') {
- const filterPath = window.location.search ? `${window.location.search}&` : '?';
- updateHistory({
- url: `${filterPath}${transformBoardConfig(vuexstore.state.boardConfig)}`,
- });
- }
- }
- }
-
- updateObject(path) {
- const groupByParam = new URLSearchParams(window.location.search).get('group_by');
- this.store.path = `${path.substr(1)}${groupByParam ? `&group_by=${groupByParam}` : ''}`;
-
- updateHistory({
- url: `?${path.substr(1)}${groupByParam ? `&group_by=${groupByParam}` : ''}`,
- });
- vuexstore.dispatch('performSearch');
- }
-
- removeTokens() {
- const tokens = FilteredSearchContainer.container.querySelectorAll('.js-visual-token');
-
- // Remove all the tokens as they will be replaced by the search manager
- [].forEach.call(tokens, (el) => {
- el.parentNode.removeChild(el);
- });
-
- this.filteredSearchInput.value = '';
- }
-
- updateTokens() {
- this.removeTokens();
-
- this.loadSearchParamsFromURL();
-
- // Get the placeholder back if search is empty
- this.filteredSearchInput.dispatchEvent(new Event('input'));
- }
-
- canEdit(tokenName, tokenValue) {
- if (this.cantEdit.includes(tokenName)) return false;
- return (
- this.cantEditWithValue.findIndex(
- (token) => token.name === tokenName && token.value === tokenValue,
- ) === -1
- );
- }
-}
diff --git a/app/assets/javascripts/boards/graphql.js b/app/assets/javascripts/boards/graphql.js
index 95863d4d5ac..d066a5d002e 100644
--- a/app/assets/javascripts/boards/graphql.js
+++ b/app/assets/javascripts/boards/graphql.js
@@ -10,5 +10,6 @@ export const gqlClient = createDefaultClient(
return object.__typename === 'BoardList' ? object.iid : defaultDataIdFromObject(object);
},
},
+ batchMax: 2,
},
);
diff --git a/app/assets/javascripts/boards/index.js b/app/assets/javascripts/boards/index.js
index f6073f9d981..b31b56e6839 100644
--- a/app/assets/javascripts/boards/index.js
+++ b/app/assets/javascripts/boards/index.js
@@ -8,8 +8,6 @@ import BoardAddNewColumnTrigger from '~/boards/components/board_add_new_column_t
import BoardApp from '~/boards/components/board_app.vue';
import '~/boards/filters/due_date_filters';
import { issuableTypes } from '~/boards/constants';
-import eventHub from '~/boards/eventhub';
-import FilteredSearchBoards from '~/boards/filtered_search_boards';
import initBoardsFilteredSearch from '~/boards/mount_filtered_search_issue_boards';
import store from '~/boards/stores';
import toggleFocusMode from '~/boards/toggle_focus';
@@ -30,6 +28,12 @@ const apolloProvider = new VueApollo({
function mountBoardApp(el) {
const { boardId, groupId, fullPath, rootPath } = el.dataset;
+ store.dispatch('fetchBoard', {
+ fullPath,
+ fullBoardId: fullBoardId(boardId),
+ boardType: el.dataset.parent,
+ });
+
store.dispatch('setInitialBoardData', {
boardId,
fullBoardId: fullBoardId(boardId),
@@ -37,30 +41,8 @@ function mountBoardApp(el) {
boardType: el.dataset.parent,
disabled: parseBoolean(el.dataset.disabled) || true,
issuableType: issuableTypes.issue,
- boardConfig: {
- milestoneId: parseInt(el.dataset.boardMilestoneId, 10),
- milestoneTitle: el.dataset.boardMilestoneTitle || '',
- iterationId: parseInt(el.dataset.boardIterationId, 10),
- iterationTitle: el.dataset.boardIterationTitle || '',
- assigneeId: el.dataset.boardAssigneeId,
- assigneeUsername: el.dataset.boardAssigneeUsername,
- labels: el.dataset.labels ? JSON.parse(el.dataset.labels) : [],
- labelIds: el.dataset.labelIds ? JSON.parse(el.dataset.labelIds) : [],
- weight: el.dataset.boardWeight ? parseInt(el.dataset.boardWeight, 10) : null,
- },
});
- if (!gon?.features?.issueBoardsFilteredSearch) {
- // Warning: FilteredSearchBoards has an implicit dependency on the Vuex state 'boardConfig'
- // Improve this situation in the future.
- const filterManager = new FilteredSearchBoards({ path: '' }, true, []);
- filterManager.setup();
-
- eventHub.$on('updateTokens', () => {
- filterManager.updateTokens();
- });
- }
-
// eslint-disable-next-line no-new
new Vue({
el,
@@ -110,10 +92,14 @@ export default () => {
}
});
- if (gon?.features?.issueBoardsFilteredSearch) {
- const { releasesFetchPath } = $boardApp.dataset;
- initBoardsFilteredSearch(apolloProvider, isLoggedIn(), releasesFetchPath);
- }
+ const { releasesFetchPath, epicFeatureAvailable, iterationFeatureAvailable } = $boardApp.dataset;
+ initBoardsFilteredSearch(
+ apolloProvider,
+ isLoggedIn(),
+ releasesFetchPath,
+ parseBoolean(epicFeatureAvailable),
+ parseBoolean(iterationFeatureAvailable),
+ );
mountBoardApp($boardApp);
diff --git a/app/assets/javascripts/boards/mount_filtered_search_issue_boards.js b/app/assets/javascripts/boards/mount_filtered_search_issue_boards.js
index 327fb9ba8d7..bb659eb075a 100644
--- a/app/assets/javascripts/boards/mount_filtered_search_issue_boards.js
+++ b/app/assets/javascripts/boards/mount_filtered_search_issue_boards.js
@@ -4,7 +4,13 @@ import store from '~/boards/stores';
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
import { queryToObject } from '~/lib/utils/url_utility';
-export default (apolloProvider, isSignedIn, releasesFetchPath) => {
+export default (
+ apolloProvider,
+ isSignedIn,
+ releasesFetchPath,
+ epicFeatureAvailable,
+ iterationFeatureAvailable,
+) => {
const el = document.getElementById('js-issue-board-filtered-search');
const rawFilterParams = queryToObject(window.location.search, { gatherArrays: true });
@@ -23,6 +29,8 @@ export default (apolloProvider, isSignedIn, releasesFetchPath) => {
initialFilterParams,
isSignedIn,
releasesFetchPath,
+ epicFeatureAvailable,
+ iterationFeatureAvailable,
},
store, // TODO: https://gitlab.com/gitlab-org/gitlab/-/issues/324094
apolloProvider,
diff --git a/app/assets/javascripts/boards/stores/actions.js b/app/assets/javascripts/boards/stores/actions.js
index 1ebfcfc331b..82307da2572 100644
--- a/app/assets/javascripts/boards/stores/actions.js
+++ b/app/assets/javascripts/boards/stores/actions.js
@@ -36,6 +36,8 @@ import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
import { queryToObject } from '~/lib/utils/url_utility';
import { s__ } from '~/locale';
import { gqlClient } from '../graphql';
+import projectBoardQuery from '../graphql/project_board.query.graphql';
+import groupBoardQuery from '../graphql/group_board.query.graphql';
import boardLabelsQuery from '../graphql/board_labels.query.graphql';
import groupBoardMilestonesQuery from '../graphql/group_board_milestones.query.graphql';
import groupProjectsQuery from '../graphql/group_projects.query.graphql';
@@ -46,10 +48,44 @@ import projectBoardMilestonesQuery from '../graphql/project_board_milestones.que
import * as types from './mutation_types';
export default {
+ fetchBoard: ({ commit, dispatch }, { fullPath, fullBoardId, boardType }) => {
+ const variables = {
+ fullPath,
+ boardId: fullBoardId,
+ };
+
+ return gqlClient
+ .query({
+ query: boardType === BoardType.group ? groupBoardQuery : projectBoardQuery,
+ variables,
+ })
+ .then(({ data }) => {
+ const board = data.workspace?.board;
+ commit(types.RECEIVE_BOARD_SUCCESS, board);
+ dispatch('setBoardConfig', board);
+ })
+ .catch(() => commit(types.RECEIVE_BOARD_FAILURE));
+ },
+
setInitialBoardData: ({ commit }, data) => {
commit(types.SET_INITIAL_BOARD_DATA, data);
},
+ setBoardConfig: ({ commit }, board) => {
+ const config = {
+ milestoneId: board.milestone?.id || null,
+ milestoneTitle: board.milestone?.title || null,
+ iterationId: board.iteration?.id || null,
+ iterationTitle: board.iteration?.title || null,
+ assigneeId: board.assignee?.id || null,
+ assigneeUsername: board.assignee?.username || null,
+ labels: board.labels?.nodes || [],
+ labelIds: board.labels?.nodes?.map((label) => label.id) || [],
+ weight: board.weight,
+ };
+ commit(types.SET_BOARD_CONFIG, config);
+ },
+
setActiveId({ commit }, { id, sidebarType }) {
commit(types.SET_ACTIVE_ID, { id, sidebarType });
},
diff --git a/app/assets/javascripts/boards/stores/mutation_types.js b/app/assets/javascripts/boards/stores/mutation_types.js
index 31b78014525..668a3b5e0f9 100644
--- a/app/assets/javascripts/boards/stores/mutation_types.js
+++ b/app/assets/javascripts/boards/stores/mutation_types.js
@@ -1,4 +1,7 @@
+export const RECEIVE_BOARD_SUCCESS = 'RECEIVE_BOARD_SUCCESS';
+export const RECEIVE_BOARD_FAILURE = 'RECEIVE_BOARD_FAILURE';
export const SET_INITIAL_BOARD_DATA = 'SET_INITIAL_BOARD_DATA';
+export const SET_BOARD_CONFIG = 'SET_BOARD_CONFIG';
export const SET_FILTERS = 'SET_FILTERS';
export const CREATE_LIST_SUCCESS = 'CREATE_LIST_SUCCESS';
export const CREATE_LIST_FAILURE = 'CREATE_LIST_FAILURE';
diff --git a/app/assets/javascripts/boards/stores/mutations.js b/app/assets/javascripts/boards/stores/mutations.js
index 2a2ce7652e6..9a50dcf05b8 100644
--- a/app/assets/javascripts/boards/stores/mutations.js
+++ b/app/assets/javascripts/boards/stores/mutations.js
@@ -33,10 +33,20 @@ export const addItemToList = ({ state, listId, itemId, moveBeforeId, moveAfterId
};
export default {
+ [mutationTypes.RECEIVE_BOARD_SUCCESS]: (state, board) => {
+ state.board = {
+ ...board,
+ labels: board?.labels?.nodes || [],
+ };
+ },
+
+ [mutationTypes.RECEIVE_BOARD_FAILURE]: (state) => {
+ state.error = s__('Boards|An error occurred while fetching the board. Please reload the page.');
+ },
+
[mutationTypes.SET_INITIAL_BOARD_DATA](state, data) {
const {
allowSubEpics,
- boardConfig,
boardId,
boardType,
disabled,
@@ -45,7 +55,6 @@ export default {
issuableType,
} = data;
state.allowSubEpics = allowSubEpics;
- state.boardConfig = boardConfig;
state.boardId = boardId;
state.boardType = boardType;
state.disabled = disabled;
@@ -54,6 +63,10 @@ export default {
state.issuableType = issuableType;
},
+ [mutationTypes.SET_BOARD_CONFIG](state, boardConfig) {
+ state.boardConfig = boardConfig;
+ },
+
[mutationTypes.RECEIVE_BOARD_LISTS_SUCCESS]: (state, lists) => {
state.boardLists = lists;
},
diff --git a/app/assets/javascripts/boards/stores/state.js b/app/assets/javascripts/boards/stores/state.js
index 80c51c966d2..7af4e5a8798 100644
--- a/app/assets/javascripts/boards/stores/state.js
+++ b/app/assets/javascripts/boards/stores/state.js
@@ -1,6 +1,7 @@
import { inactiveId, ListType } from '~/boards/constants';
export default () => ({
+ board: {},
boardType: null,
issuableType: null,
fullPath: null,
diff --git a/app/assets/javascripts/branches/ajax_loading_spinner.js b/app/assets/javascripts/branches/ajax_loading_spinner.js
deleted file mode 100644
index 79f4f919f3d..00000000000
--- a/app/assets/javascripts/branches/ajax_loading_spinner.js
+++ /dev/null
@@ -1,31 +0,0 @@
-import $ from 'jquery';
-
-export default class AjaxLoadingSpinner {
- static init() {
- const $elements = $('.js-ajax-loading-spinner');
- $elements.on('ajax:beforeSend', AjaxLoadingSpinner.ajaxBeforeSend);
- }
-
- static ajaxBeforeSend(e) {
- const button = e.target;
- const newButton = document.createElement('button');
- newButton.classList.add('btn', 'btn-default', 'disabled', 'gl-button');
- newButton.setAttribute('disabled', 'disabled');
-
- const spinner = document.createElement('span');
- spinner.classList.add('align-text-bottom', 'gl-spinner', 'gl-spinner-sm', 'gl-spinner-orange');
- newButton.appendChild(spinner);
-
- button.classList.add('hidden');
- button.parentNode.insertBefore(newButton, button.nextSibling);
-
- $(button).one('ajax:error', () => {
- newButton.remove();
- button.classList.remove('hidden');
- });
-
- $(button).one('ajax:success', () => {
- $(button).off('ajax:beforeSend', AjaxLoadingSpinner.ajaxBeforeSend);
- });
- }
-}
diff --git a/app/assets/javascripts/captcha/apollo_captcha_link.js b/app/assets/javascripts/captcha/apollo_captcha_link.js
index d63ffaf5f1a..2d154139c7b 100644
--- a/app/assets/javascripts/captcha/apollo_captcha_link.js
+++ b/app/assets/javascripts/captcha/apollo_captcha_link.js
@@ -12,7 +12,7 @@ export const apolloCaptchaLink = new ApolloLink((operation, forward) =>
const spamLogId = captchaError.extensions.spam_log_id;
return new Observable((observer) => {
- import('~/captcha/wait_for_captcha_to_be_solved')
+ import('jh_else_ce/captcha/wait_for_captcha_to_be_solved')
.then(({ waitForCaptchaToBeSolved }) => waitForCaptchaToBeSolved(captchaSiteKey))
.then((captchaResponse) => {
// If the captcha was solved correctly, we re-do our action while setting
diff --git a/app/assets/javascripts/captcha/captcha_modal.vue b/app/assets/javascripts/captcha/captcha_modal.vue
index a98a52a3130..b8b90b04beb 100644
--- a/app/assets/javascripts/captcha/captcha_modal.vue
+++ b/app/assets/javascripts/captcha/captcha_modal.vue
@@ -1,7 +1,7 @@
<script>
-// NOTE 1: This is similar to recaptcha_modal.vue, but it directly uses the reCAPTCHA Javascript API
-// (https://developers.google.com/recaptcha/docs/display#js_api) and gl-modal, rather than relying
-// on the form-based ReCAPTCHA HTML being pre-rendered by the backend and using deprecated-modal.
+// NOTE 1: This modal directly uses the reCAPTCHA Javascript API
+// (https://developers.google.com/recaptcha/docs/display#js_api) and gl-modal,
+// rather than relying form-based reCAPTCHA HTML being pre-rendered by the backend.
// NOTE 2: Even though this modal currently only supports reCAPTCHA, we use 'captcha' instead
// of 'recaptcha' throughout the code, so that we can easily add support for future alternative
diff --git a/app/assets/javascripts/captcha/captcha_modal_axios_interceptor.js b/app/assets/javascripts/captcha/captcha_modal_axios_interceptor.js
index fdab188f6be..19fde2500f1 100644
--- a/app/assets/javascripts/captcha/captcha_modal_axios_interceptor.js
+++ b/app/assets/javascripts/captcha/captcha_modal_axios_interceptor.js
@@ -9,7 +9,9 @@ function needsCaptchaResponse(err) {
const showCaptchaModalAndResubmit = async (axios, data, errConfig) => {
// NOTE: We asynchronously import and unbox the module. Since this is included globally, we don't
// do a regular import because that would increase the size of the webpack bundle.
- const { waitForCaptchaToBeSolved } = await import('~/captcha/wait_for_captcha_to_be_solved');
+ const { waitForCaptchaToBeSolved } = await import(
+ 'jh_else_ce/captcha/wait_for_captcha_to_be_solved'
+ );
// show the CAPTCHA modal and wait for it to be solved or closed
const captchaResponse = await waitForCaptchaToBeSolved(data.captcha_site_key);
diff --git a/app/assets/javascripts/ci_lint/components/ci_lint.vue b/app/assets/javascripts/ci_lint/components/ci_lint.vue
index d541e89756a..8db4cba529f 100644
--- a/app/assets/javascripts/ci_lint/components/ci_lint.vue
+++ b/app/assets/javascripts/ci_lint/components/ci_lint.vue
@@ -103,7 +103,7 @@ export default {
class="gl-mr-4"
:loading="loading"
category="primary"
- variant="success"
+ variant="confirm"
data-testid="ci-lint-validate"
@click="lint"
>{{ __('Validate') }}</gl-button
diff --git a/app/assets/javascripts/ci_secure_files/components/secure_files_list.vue b/app/assets/javascripts/ci_secure_files/components/secure_files_list.vue
new file mode 100644
index 00000000000..d70ade36fe9
--- /dev/null
+++ b/app/assets/javascripts/ci_secure_files/components/secure_files_list.vue
@@ -0,0 +1,133 @@
+<script>
+import { GlLink, GlLoadingIcon, GlPagination, GlTable } from '@gitlab/ui';
+import Api, { DEFAULT_PER_PAGE } from '~/api';
+import { helpPagePath } from '~/helpers/help_page_helper';
+import { __ } from '~/locale';
+import TimeagoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
+
+export default {
+ components: {
+ GlLink,
+ GlLoadingIcon,
+ GlPagination,
+ GlTable,
+ TimeagoTooltip,
+ },
+ inject: ['projectId'],
+ docsLink: helpPagePath('ci/secure_files/index'),
+ DEFAULT_PER_PAGE,
+ i18n: {
+ pagination: {
+ next: __('Next'),
+ prev: __('Prev'),
+ },
+ title: __('Secure Files'),
+ overviewMessage: __(
+ 'Use Secure Files to store files used by your pipelines such as Android keystores, or Apple provisioning profiles and signing certificates.',
+ ),
+ moreInformation: __('More information'),
+ },
+ data() {
+ return {
+ page: 1,
+ totalItems: 0,
+ loading: false,
+ projectSecureFiles: [],
+ };
+ },
+ fields: [
+ {
+ key: 'name',
+ label: __('Filename'),
+ },
+ {
+ key: 'permissions',
+ label: __('Permissions'),
+ },
+ {
+ key: 'created_at',
+ label: __('Uploaded'),
+ },
+ ],
+ computed: {
+ fields() {
+ return this.$options.fields;
+ },
+ },
+ watch: {
+ page(newPage) {
+ this.getProjectSecureFiles(newPage);
+ },
+ },
+ created() {
+ this.getProjectSecureFiles();
+ },
+ methods: {
+ async getProjectSecureFiles(page) {
+ this.loading = true;
+ const response = await Api.projectSecureFiles(this.projectId, { page });
+
+ this.totalItems = parseInt(response.headers?.['x-total'], 10) || 0;
+
+ this.projectSecureFiles = response.data;
+
+ this.loading = false;
+ },
+ },
+};
+</script>
+
+<template>
+ <div>
+ <h1 data-testid="title" class="gl-font-size-h1 gl-mt-3 gl-mb-0">{{ $options.i18n.title }}</h1>
+
+ <p>
+ <span data-testid="info-message" class="gl-mr-2">
+ {{ $options.i18n.overviewMessage }}
+ <gl-link :href="$options.docsLink" target="_blank">{{
+ $options.i18n.moreInformation
+ }}</gl-link>
+ </span>
+ </p>
+
+ <gl-table
+ :busy="loading"
+ :fields="fields"
+ :items="projectSecureFiles"
+ tbody-tr-class="js-ci-secure-files-row"
+ data-qa-selector="ci_secure_files_table_content"
+ sort-by="key"
+ sort-direction="asc"
+ stacked="lg"
+ table-class="text-secondary"
+ show-empty
+ sort-icon-left
+ no-sort-reset
+ >
+ <template #table-busy>
+ <gl-loading-icon size="lg" class="gl-my-5" />
+ </template>
+
+ <template #cell(name)="{ item }">
+ {{ item.name }}
+ </template>
+
+ <template #cell(permissions)="{ item }">
+ {{ item.permissions }}
+ </template>
+
+ <template #cell(created_at)="{ item }">
+ <timeago-tooltip :time="item.created_at" />
+ </template>
+ </gl-table>
+ <gl-pagination
+ v-if="!loading"
+ v-model="page"
+ :per-page="$options.DEFAULT_PER_PAGE"
+ :total-items="totalItems"
+ :next-text="$options.i18n.pagination.next"
+ :prev-text="$options.i18n.pagination.prev"
+ align="center"
+ />
+ </div>
+</template>
diff --git a/app/assets/javascripts/ci_secure_files/index.js b/app/assets/javascripts/ci_secure_files/index.js
new file mode 100644
index 00000000000..18b4ac6866e
--- /dev/null
+++ b/app/assets/javascripts/ci_secure_files/index.js
@@ -0,0 +1,17 @@
+import Vue from 'vue';
+import SecureFilesList from './components/secure_files_list.vue';
+
+export const initCiSecureFiles = (selector = '#js-ci-secure-files') => {
+ const containerEl = document.querySelector(selector);
+ const { projectId } = containerEl.dataset;
+
+ return new Vue({
+ el: containerEl,
+ provide: {
+ projectId,
+ },
+ render(createElement) {
+ return createElement(SecureFilesList);
+ },
+ });
+};
diff --git a/app/assets/javascripts/ci_settings_pipeline_triggers/components/triggers_list.vue b/app/assets/javascripts/ci_settings_pipeline_triggers/components/triggers_list.vue
index 4ab9b36058d..4156717908d 100644
--- a/app/assets/javascripts/ci_settings_pipeline_triggers/components/triggers_list.vue
+++ b/app/assets/javascripts/ci_settings_pipeline_triggers/components/triggers_list.vue
@@ -8,8 +8,12 @@ import UserAvatarLink from '~/vue_shared/components/user_avatar/user_avatar_link
export default {
i18n: {
+ copyTrigger: s__('Pipelines|Copy trigger token'),
editButton: s__('Pipelines|Edit'),
- revokeButton: s__('Pipelines|Revoke'),
+ revokeButton: s__('Pipelines|Revoke trigger'),
+ revokeButtonConfirm: s__(
+ 'Pipelines|By revoking a trigger you will break any processes making use of it. Are you sure?',
+ ),
},
components: {
GlTable,
@@ -72,7 +76,7 @@ export default {
:text="item.token"
data-testid="clipboard-btn"
data-qa-selector="clipboard_button"
- :title="s__('Pipelines|Copy trigger token')"
+ :title="$options.i18n.copyTrigger"
css-class="gl-border-none gl-py-0 gl-px-2"
/>
<div class="label-container">
@@ -122,13 +126,9 @@ export default {
:title="$options.i18n.revokeButton"
:aria-label="$options.i18n.revokeButton"
icon="remove"
- variant="warning"
- :data-confirm="
- s__(
- 'Pipelines|By revoking a trigger you will break any processes making use of it. Are you sure?',
- )
- "
+ :data-confirm="$options.i18n.revokeButtonConfirm"
data-method="delete"
+ data-confirm-btn-variant="danger"
rel="nofollow"
class="gl-ml-3"
data-testid="trigger_revoke_button"
diff --git a/app/assets/javascripts/ci_variable_list/ci_variable_list.js b/app/assets/javascripts/ci_variable_list/ci_variable_list.js
index 065cb4f5616..055e2f83e33 100644
--- a/app/assets/javascripts/ci_variable_list/ci_variable_list.js
+++ b/app/assets/javascripts/ci_variable_list/ci_variable_list.js
@@ -3,7 +3,6 @@ import SecretValues from '../behaviors/secret_values';
import CreateItemDropdown from '../create_item_dropdown';
import { parseBoolean } from '../lib/utils/common_utils';
import { s__ } from '../locale';
-import setupToggleButtons from '../toggle_buttons';
const ALL_ENVIRONMENTS_STRING = s__('CiVariable|All environments');
@@ -115,8 +114,6 @@ export default class VariableList {
initRow(rowEl) {
const $row = $(rowEl);
- setupToggleButtons($row[0]);
-
// Reset the resizable textarea
$row.find(this.inputMap.secret_value.selector).css('height', '');
diff --git a/app/assets/javascripts/clusters/agents/components/create_token_button.vue b/app/assets/javascripts/clusters/agents/components/create_token_button.vue
new file mode 100644
index 00000000000..3e1a8994fb8
--- /dev/null
+++ b/app/assets/javascripts/clusters/agents/components/create_token_button.vue
@@ -0,0 +1,246 @@
+<script>
+import {
+ GlButton,
+ GlModalDirective,
+ GlTooltip,
+ GlModal,
+ GlFormGroup,
+ GlFormInput,
+ GlFormTextarea,
+ GlAlert,
+} from '@gitlab/ui';
+import { s__, __ } from '~/locale';
+import Tracking from '~/tracking';
+import AgentToken from '~/clusters_list/components/agent_token.vue';
+import {
+ CREATE_TOKEN_MODAL,
+ EVENT_LABEL_MODAL,
+ EVENT_ACTIONS_OPEN,
+ EVENT_ACTIONS_CLICK,
+ TOKEN_NAME_LIMIT,
+ TOKEN_STATUS_ACTIVE,
+} from '../constants';
+import createNewAgentToken from '../graphql/mutations/create_new_agent_token.mutation.graphql';
+import getClusterAgentQuery from '../graphql/queries/get_cluster_agent.query.graphql';
+import { addAgentTokenToStore } from '../graphql/cache_update';
+
+const trackingMixin = Tracking.mixin({ label: EVENT_LABEL_MODAL });
+
+export default {
+ components: {
+ AgentToken,
+ GlButton,
+ GlTooltip,
+ GlModal,
+ GlFormGroup,
+ GlFormInput,
+ GlFormTextarea,
+ GlAlert,
+ },
+ directives: {
+ GlModalDirective,
+ },
+ mixins: [trackingMixin],
+ inject: ['agentName', 'projectPath', 'canAdminCluster'],
+ props: {
+ clusterAgentId: {
+ required: true,
+ type: String,
+ },
+ cursor: {
+ required: true,
+ type: Object,
+ },
+ },
+ modalId: CREATE_TOKEN_MODAL,
+ EVENT_ACTIONS_OPEN,
+ EVENT_ACTIONS_CLICK,
+ EVENT_LABEL_MODAL,
+ TOKEN_NAME_LIMIT,
+ i18n: {
+ createTokenButton: s__('ClusterAgents|Create token'),
+ modalTitle: s__('ClusterAgents|Create agent access token'),
+ unknownError: s__('ClusterAgents|An unknown error occurred. Please try again.'),
+ errorTitle: s__('ClusterAgents|Failed to create a token'),
+ dropdownDisabledHint: s__(
+ 'ClusterAgents|Requires a Maintainer or greater role to perform these actions',
+ ),
+ modalCancel: __('Cancel'),
+ modalClose: __('Close'),
+ tokenNameLabel: __('Name'),
+ tokenDescriptionLabel: __('Description (optional)'),
+ },
+ data() {
+ return {
+ token: {
+ name: null,
+ description: null,
+ },
+ agentToken: null,
+ error: null,
+ loading: false,
+ variables: {
+ agentName: this.agentName,
+ projectPath: this.projectPath,
+ tokenStatus: TOKEN_STATUS_ACTIVE,
+ ...this.cursor,
+ },
+ };
+ },
+ computed: {
+ modalBtnDisabled() {
+ return this.loading || !this.hasTokenName;
+ },
+ hasTokenName() {
+ return Boolean(this.token.name?.length);
+ },
+ },
+ methods: {
+ async createToken() {
+ this.loading = true;
+ this.error = null;
+
+ try {
+ const { errors: tokenErrors, secret } = await this.createAgentTokenMutation();
+
+ if (tokenErrors?.length > 0) {
+ throw new Error(tokenErrors[0]);
+ }
+
+ this.agentToken = secret;
+ } catch (error) {
+ if (error) {
+ this.error = error.message;
+ } else {
+ this.error = this.$options.i18n.unknownError;
+ }
+ } finally {
+ this.loading = false;
+ }
+ },
+ resetModal() {
+ this.agentToken = null;
+ this.token.name = null;
+ this.token.description = null;
+ this.error = null;
+ },
+ closeModal() {
+ this.$refs.modal.hide();
+ },
+ createAgentTokenMutation() {
+ return this.$apollo
+ .mutate({
+ mutation: createNewAgentToken,
+ variables: {
+ input: {
+ clusterAgentId: this.clusterAgentId,
+ name: this.token.name,
+ description: this.token.description,
+ },
+ },
+ update: (store, { data: { clusterAgentTokenCreate } }) => {
+ addAgentTokenToStore(
+ store,
+ clusterAgentTokenCreate,
+ getClusterAgentQuery,
+ this.variables,
+ );
+ },
+ })
+ .then(({ data: { clusterAgentTokenCreate } }) => clusterAgentTokenCreate);
+ },
+ },
+};
+</script>
+
+<template>
+ <div>
+ <div ref="addToken" class="gl-display-inline-block">
+ <gl-button
+ v-gl-modal-directive="$options.modalId"
+ :disabled="!canAdminCluster"
+ category="primary"
+ variant="confirm"
+ >{{ $options.i18n.createTokenButton }}
+ </gl-button>
+
+ <gl-tooltip
+ v-if="!canAdminCluster"
+ :target="() => $refs.addToken"
+ :title="$options.i18n.dropdownDisabledHint"
+ />
+ </div>
+
+ <gl-modal
+ ref="modal"
+ :modal-id="$options.modalId"
+ :title="$options.i18n.modalTitle"
+ static
+ lazy
+ @hidden="resetModal"
+ @show="track($options.EVENT_ACTIONS_OPEN)"
+ >
+ <gl-alert
+ v-if="error"
+ :title="$options.i18n.errorTitle"
+ :dismissible="false"
+ variant="danger"
+ class="gl-mb-5"
+ >
+ {{ error }}
+ </gl-alert>
+
+ <template v-if="!agentToken">
+ <gl-form-group :label="$options.i18n.tokenNameLabel">
+ <gl-form-input
+ v-model="token.name"
+ :max-length="$options.TOKEN_NAME_LIMIT"
+ :disabled="loading"
+ required
+ />
+ </gl-form-group>
+
+ <gl-form-group :label="$options.i18n.tokenDescriptionLabel">
+ <gl-form-textarea v-model="token.description" :disabled="loading" name="description" />
+ </gl-form-group>
+ </template>
+
+ <agent-token v-else :agent-token="agentToken" :modal-id="$options.modalId" />
+
+ <template #modal-footer>
+ <gl-button
+ v-if="!agentToken && !loading"
+ :data-track-action="$options.EVENT_ACTIONS_CLICK"
+ :data-track-label="$options.EVENT_LABEL_MODAL"
+ data-track-property="close"
+ data-testid="agent-token-close-button"
+ @click="closeModal"
+ >{{ $options.i18n.modalCancel }}
+ </gl-button>
+
+ <gl-button
+ v-if="!agentToken"
+ :disabled="modalBtnDisabled"
+ :loading="loading"
+ :data-track-action="$options.EVENT_ACTIONS_CLICK"
+ :data-track-label="$options.EVENT_LABEL_MODAL"
+ data-track-property="create-token"
+ variant="confirm"
+ type="submit"
+ @click="createToken"
+ >{{ $options.i18n.createTokenButton }}
+ </gl-button>
+
+ <gl-button
+ v-else
+ :data-track-action="$options.EVENT_ACTIONS_CLICK"
+ :data-track-label="$options.EVENT_LABEL_MODAL"
+ data-track-property="close"
+ variant="confirm"
+ @click="closeModal"
+ >{{ $options.i18n.modalClose }}
+ </gl-button>
+ </template>
+ </gl-modal>
+ </div>
+</template>
diff --git a/app/assets/javascripts/clusters/agents/components/show.vue b/app/assets/javascripts/clusters/agents/components/show.vue
index 63f068a9327..5df3e0811a5 100644
--- a/app/assets/javascripts/clusters/agents/components/show.vue
+++ b/app/assets/javascripts/clusters/agents/components/show.vue
@@ -143,7 +143,7 @@ export default {
<gl-loading-icon v-if="isLoading" size="md" class="gl-m-3" />
<div v-else>
- <token-table :tokens="tokens" />
+ <token-table :tokens="tokens" :cluster-agent-id="clusterAgent.id" :cursor="cursor" />
<div v-if="showPagination" class="gl-display-flex gl-justify-content-center gl-mt-5">
<gl-keyset-pagination v-bind="tokenPageInfo" @prev="prevPage" @next="nextPage" />
diff --git a/app/assets/javascripts/clusters/agents/components/token_table.vue b/app/assets/javascripts/clusters/agents/components/token_table.vue
index 019fac531d1..fbb39c28d78 100644
--- a/app/assets/javascripts/clusters/agents/components/token_table.vue
+++ b/app/assets/javascripts/clusters/agents/components/token_table.vue
@@ -1,17 +1,17 @@
<script>
-import { GlEmptyState, GlLink, GlTable, GlTooltip, GlTruncate } from '@gitlab/ui';
-import { helpPagePath } from '~/helpers/help_page_helper';
+import { GlEmptyState, GlTable, GlTooltip, GlTruncate } from '@gitlab/ui';
import { s__ } from '~/locale';
import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
+import CreateTokenButton from './create_token_button.vue';
export default {
components: {
GlEmptyState,
- GlLink,
GlTable,
GlTooltip,
GlTruncate,
TimeAgoTooltip,
+ CreateTokenButton,
},
i18n: {
createdBy: s__('ClusterAgents|Created by'),
@@ -19,7 +19,6 @@ export default {
dateCreated: s__('ClusterAgents|Date created'),
description: s__('ClusterAgents|Description'),
lastUsed: s__('ClusterAgents|Last contact'),
- learnMore: s__('ClusterAgents|Learn how to create an agent access token'),
name: s__('ClusterAgents|Name'),
neverUsed: s__('ClusterAgents|Never'),
noTokens: s__('ClusterAgents|This agent has no tokens'),
@@ -30,6 +29,14 @@ export default {
required: true,
type: Array,
},
+ clusterAgentId: {
+ required: true,
+ type: String,
+ },
+ cursor: {
+ required: true,
+ type: Object,
+ },
},
computed: {
fields() {
@@ -61,11 +68,6 @@ export default {
},
];
},
- learnMoreUrl() {
- return helpPagePath('user/clusters/agent/install/index', {
- anchor: 'register-an-agent-with-gitlab',
- });
- },
},
methods: {
createdByName(token) {
@@ -77,11 +79,11 @@ export default {
<template>
<div v-if="tokens.length">
- <div class="gl-text-right gl-my-5">
- <gl-link target="_blank" :href="learnMoreUrl">
- {{ $options.i18n.learnMore }}
- </gl-link>
- </div>
+ <create-token-button
+ class="gl-text-right gl-my-5"
+ :cluster-agent-id="clusterAgentId"
+ :cursor="cursor"
+ />
<gl-table
:items="tokens"
@@ -120,10 +122,9 @@ export default {
</gl-table>
</div>
- <gl-empty-state
- v-else
- :title="$options.i18n.noTokens"
- :primary-button-link="learnMoreUrl"
- :primary-button-text="$options.i18n.learnMore"
- />
+ <gl-empty-state v-else :title="$options.i18n.noTokens">
+ <template #actions>
+ <create-token-button :cluster-agent-id="clusterAgentId" :cursor="cursor" />
+ </template>
+ </gl-empty-state>
</template>
diff --git a/app/assets/javascripts/clusters/agents/constants.js b/app/assets/javascripts/clusters/agents/constants.js
index 98d4707b4de..50d8f5e9e40 100644
--- a/app/assets/javascripts/clusters/agents/constants.js
+++ b/app/assets/javascripts/clusters/agents/constants.js
@@ -37,3 +37,10 @@ export const EVENT_DETAILS = {
export const DEFAULT_ICON = 'token';
export const TOKEN_STATUS_ACTIVE = 'ACTIVE';
+
+export const CREATE_TOKEN_MODAL = 'create-token';
+export const EVENT_LABEL_MODAL = 'agent_token_creation_modal';
+export const EVENT_ACTIONS_OPEN = 'open_modal';
+export const EVENT_ACTIONS_CLICK = 'click_button';
+
+export const TOKEN_NAME_LIMIT = 255;
diff --git a/app/assets/javascripts/clusters/agents/graphql/cache_update.js b/app/assets/javascripts/clusters/agents/graphql/cache_update.js
new file mode 100644
index 00000000000..0219c4150eb
--- /dev/null
+++ b/app/assets/javascripts/clusters/agents/graphql/cache_update.js
@@ -0,0 +1,24 @@
+import produce from 'immer';
+
+export const hasErrors = ({ errors = [] }) => errors?.length;
+
+export function addAgentTokenToStore(store, clusterAgentTokenCreate, query, variables) {
+ if (!hasErrors(clusterAgentTokenCreate)) {
+ const { token } = clusterAgentTokenCreate;
+ const sourceData = store.readQuery({
+ query,
+ variables,
+ });
+
+ const data = produce(sourceData, (draftData) => {
+ draftData.project.clusterAgent.tokens.nodes.unshift(token);
+ draftData.project.clusterAgent.tokens.count += 1;
+ });
+
+ store.writeQuery({
+ query,
+ variables,
+ data,
+ });
+ }
+}
diff --git a/app/assets/javascripts/clusters/agents/graphql/mutations/create_new_agent_token.mutation.graphql b/app/assets/javascripts/clusters/agents/graphql/mutations/create_new_agent_token.mutation.graphql
new file mode 100644
index 00000000000..4a61263ba70
--- /dev/null
+++ b/app/assets/javascripts/clusters/agents/graphql/mutations/create_new_agent_token.mutation.graphql
@@ -0,0 +1,11 @@
+#import "../fragments/cluster_agent_token.fragment.graphql"
+
+mutation createNewAgentToken($input: ClusterAgentTokenCreateInput!) {
+ clusterAgentTokenCreate(input: $input) {
+ secret
+ token {
+ ...Token
+ }
+ errors
+ }
+}
diff --git a/app/assets/javascripts/clusters/agents/index.js b/app/assets/javascripts/clusters/agents/index.js
index ba7b3edba72..8a447f57f00 100644
--- a/app/assets/javascripts/clusters/agents/index.js
+++ b/app/assets/javascripts/clusters/agents/index.js
@@ -1,4 +1,5 @@
import Vue from 'vue';
+import { parseBoolean } from '~/lib/utils/common_utils';
import AgentShowPage from 'ee_else_ce/clusters/agents/components/show.vue';
import apolloProvider from './graphql/provider';
import createRouter from './router';
@@ -16,6 +17,8 @@ export default () => {
canAdminVulnerability,
emptyStateSvgPath,
projectPath,
+ kasAddress,
+ canAdminCluster,
} = el.dataset;
return new Vue({
@@ -28,6 +31,8 @@ export default () => {
canAdminVulnerability,
emptyStateSvgPath,
projectPath,
+ kasAddress,
+ canAdminCluster: parseBoolean(canAdminCluster),
},
render(createElement) {
return createElement(AgentShowPage);
diff --git a/app/assets/javascripts/clusters/components/new_cluster.vue b/app/assets/javascripts/clusters/components/new_cluster.vue
index 2e74ad073c5..8f3e2916270 100644
--- a/app/assets/javascripts/clusters/components/new_cluster.vue
+++ b/app/assets/javascripts/clusters/components/new_cluster.vue
@@ -5,9 +5,9 @@ import { s__ } from '~/locale';
export default {
i18n: {
- title: s__('ClusterIntegration|Enter the details for your Kubernetes cluster'),
+ title: s__('ClusterIntegration|Enter your Kubernetes cluster certificate details'),
information: s__(
- 'ClusterIntegration|Please enter access information for your Kubernetes cluster. If you need help, you can read our %{linkStart}documentation%{linkEnd} on Kubernetes',
+ 'ClusterIntegration|Enter details about your cluster. %{linkStart}How do I use a certificate to connect to my cluster?%{linkEnd}',
),
},
components: {
@@ -21,7 +21,7 @@ export default {
</script>
<template>
- <div>
+ <div class="gl-pt-4">
<h4>{{ $options.i18n.title }}</h4>
<p>
<gl-sprintf :message="$options.i18n.information">
diff --git a/app/assets/javascripts/clusters_list/components/agent_table.vue b/app/assets/javascripts/clusters_list/components/agent_table.vue
index 61c4904aacf..1144ce68e2c 100644
--- a/app/assets/javascripts/clusters_list/components/agent_table.vue
+++ b/app/assets/javascripts/clusters_list/components/agent_table.vue
@@ -1,5 +1,13 @@
<script>
-import { GlLink, GlTable, GlIcon, GlSprintf, GlTooltip, GlPopover } from '@gitlab/ui';
+import {
+ GlLink,
+ GlTable,
+ GlIcon,
+ GlSprintf,
+ GlTooltip,
+ GlTooltipDirective,
+ GlPopover,
+} from '@gitlab/ui';
import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
import timeagoMixin from '~/vue_shared/mixins/timeago';
import { helpPagePath } from '~/helpers/help_page_helper';
@@ -19,12 +27,18 @@ export default {
TimeAgoTooltip,
DeleteAgentButton,
},
+ directives: {
+ GlTooltip: GlTooltipDirective,
+ },
mixins: [timeagoMixin],
AGENT_STATUSES,
troubleshootingLink: helpPagePath('user/clusters/agent/troubleshooting'),
versionUpdateLink: helpPagePath('user/clusters/agent/install/index', {
anchor: 'update-the-agent-version',
}),
+ configHelpLink: helpPagePath('user/clusters/agent/install/index', {
+ anchor: 'create-an-agent-without-configuration-file',
+ }),
inject: ['gitlabVersion'],
props: {
agents: {
@@ -256,7 +270,16 @@ export default {
{{ getAgentConfigPath(item.name) }}
</gl-link>
- <span v-else>{{ getAgentConfigPath(item.name) }}</span>
+ <span v-else
+ >{{ $options.i18n.defaultConfigText }}
+ <gl-link
+ v-gl-tooltip
+ :href="$options.configHelpLink"
+ :title="$options.i18n.defaultConfigTooltip"
+ :aria-label="$options.i18n.defaultConfigTooltip"
+ class="gl-vertical-align-middle"
+ ><gl-icon name="question" :size="14" /></gl-link
+ ></span>
</span>
</template>
diff --git a/app/assets/javascripts/clusters_list/components/agent_token.vue b/app/assets/javascripts/clusters_list/components/agent_token.vue
new file mode 100644
index 00000000000..eab3fc3ed63
--- /dev/null
+++ b/app/assets/javascripts/clusters_list/components/agent_token.vue
@@ -0,0 +1,109 @@
+<script>
+import { GlAlert, GlFormInputGroup, GlLink, GlSprintf } from '@gitlab/ui';
+import { helpPagePath } from '~/helpers/help_page_helper';
+import ModalCopyButton from '~/vue_shared/components/modal_copy_button.vue';
+import CodeBlock from '~/vue_shared/components/code_block.vue';
+import { generateAgentRegistrationCommand } from '../clusters_util';
+import { I18N_AGENT_TOKEN } from '../constants';
+
+export default {
+ i18n: I18N_AGENT_TOKEN,
+ basicInstallPath: helpPagePath('user/clusters/agent/install/index', {
+ anchor: 'install-the-agent-into-the-cluster',
+ }),
+ advancedInstallPath: helpPagePath('user/clusters/agent/install/index', {
+ anchor: 'advanced-installation',
+ }),
+ components: {
+ GlAlert,
+ CodeBlock,
+ GlFormInputGroup,
+ GlLink,
+ GlSprintf,
+ ModalCopyButton,
+ },
+ inject: ['kasAddress'],
+ props: {
+ agentToken: {
+ required: true,
+ type: String,
+ },
+ modalId: {
+ required: true,
+ type: String,
+ },
+ },
+ computed: {
+ agentRegistrationCommand() {
+ return generateAgentRegistrationCommand(this.agentToken, this.kasAddress);
+ },
+ },
+};
+</script>
+
+<template>
+ <div>
+ <p>
+ <strong>{{ $options.i18n.tokenTitle }}</strong>
+ </p>
+
+ <p>
+ <gl-sprintf :message="$options.i18n.tokenBody">
+ <template #link="{ content }">
+ <gl-link :href="$options.basicInstallPath" target="_blank"> {{ content }}</gl-link>
+ </template>
+ </gl-sprintf>
+ </p>
+
+ <p>
+ <gl-alert
+ :title="$options.i18n.tokenSingleUseWarningTitle"
+ variant="warning"
+ :dismissible="false"
+ >
+ {{ $options.i18n.tokenSingleUseWarningBody }}
+ </gl-alert>
+ </p>
+
+ <p>
+ <gl-form-input-group readonly :value="agentToken" :select-on-click="true">
+ <template #append>
+ <modal-copy-button
+ :text="agentToken"
+ :title="$options.i18n.copyToken"
+ :modal-id="modalId"
+ />
+ </template>
+ </gl-form-input-group>
+ </p>
+
+ <p>
+ <strong>{{ $options.i18n.basicInstallTitle }}</strong>
+ </p>
+
+ <p>
+ {{ $options.i18n.basicInstallBody }}
+ </p>
+
+ <p class="gl-display-flex gl-align-items-flex-start">
+ <code-block class="gl-w-full" :code="agentRegistrationCommand" />
+ <modal-copy-button
+ :title="$options.i18n.copyCommand"
+ :text="agentRegistrationCommand"
+ :modal-id="modalId"
+ />
+ </p>
+
+ <p>
+ <strong>{{ $options.i18n.advancedInstallTitle }}</strong>
+ </p>
+
+ <p>
+ <gl-sprintf :message="$options.i18n.advancedInstallBody">
+ <template #link="{ content }">
+ <gl-link :href="$options.advancedInstallPath" target="_blank"> {{ content }}</gl-link>
+ </template>
+ </gl-sprintf>
+ </p>
+ </div>
+</template>
diff --git a/app/assets/javascripts/clusters_list/components/agents.vue b/app/assets/javascripts/clusters_list/components/agents.vue
index bf096f53e9d..70b9b8ac3c9 100644
--- a/app/assets/javascripts/clusters_list/components/agents.vue
+++ b/app/assets/javascripts/clusters_list/components/agents.vue
@@ -116,9 +116,6 @@ export default {
},
},
methods: {
- reloadAgents() {
- this.$apollo.queries.agents.refetch();
- },
nextPage() {
this.cursor = {
first: MAX_LIST_COUNT,
diff --git a/app/assets/javascripts/clusters_list/components/available_agents_dropdown.vue b/app/assets/javascripts/clusters_list/components/available_agents_dropdown.vue
index 1630d0d5c92..662cf2a7e36 100644
--- a/app/assets/javascripts/clusters_list/components/available_agents_dropdown.vue
+++ b/app/assets/javascripts/clusters_list/components/available_agents_dropdown.vue
@@ -1,5 +1,11 @@
<script>
-import { GlDropdown, GlDropdownItem } from '@gitlab/ui';
+import {
+ GlDropdown,
+ GlDropdownItem,
+ GlDropdownDivider,
+ GlSearchBoxByType,
+ GlSprintf,
+} from '@gitlab/ui';
import { I18N_AVAILABLE_AGENTS_DROPDOWN } from '../constants';
export default {
@@ -8,6 +14,9 @@ export default {
components: {
GlDropdown,
GlDropdownItem,
+ GlDropdownDivider,
+ GlSearchBoxByType,
+ GlSprintf,
},
props: {
isRegistering: {
@@ -22,6 +31,7 @@ export default {
data() {
return {
selectedAgent: null,
+ searchTerm: '',
};
},
computed: {
@@ -34,22 +44,45 @@ export default {
return this.selectedAgent;
},
+ shouldRenderCreateButton() {
+ return this.searchTerm && !this.availableAgents.includes(this.searchTerm);
+ },
+ filteredResults() {
+ const lowerCasedSearchTerm = this.searchTerm.toLowerCase();
+ return this.availableAgents.filter((resultString) =>
+ resultString.toLowerCase().includes(lowerCasedSearchTerm),
+ );
+ },
},
methods: {
selectAgent(agent) {
this.$emit('agentSelected', agent);
this.selectedAgent = agent;
+ this.clearSearch();
},
isSelected(agent) {
return this.selectedAgent === agent;
},
+ clearSearch() {
+ this.searchTerm = '';
+ },
+ focusSearch() {
+ this.$refs.searchInput.focusInput();
+ },
+ handleShow() {
+ this.clearSearch();
+ this.focusSearch();
+ },
},
};
</script>
<template>
- <gl-dropdown :text="dropdownText" :loading="isRegistering">
+ <gl-dropdown :text="dropdownText" :loading="isRegistering" @shown="handleShow">
+ <template #header>
+ <gl-search-box-by-type ref="searchInput" v-model.trim="searchTerm" />
+ </template>
<gl-dropdown-item
- v-for="agent in availableAgents"
+ v-for="agent in filteredResults"
:key="agent"
:is-checked="isSelected(agent)"
is-check-item
@@ -57,5 +90,16 @@ export default {
>
{{ agent }}
</gl-dropdown-item>
+ <gl-dropdown-item v-if="!filteredResults.length" ref="noMatchingResults">{{
+ $options.i18n.noResults
+ }}</gl-dropdown-item>
+ <template v-if="shouldRenderCreateButton">
+ <gl-dropdown-divider />
+ <gl-dropdown-item data-testid="create-config-button" @click="selectAgent(searchTerm)">
+ <gl-sprintf :message="$options.i18n.createButton">
+ <template #searchTerm>{{ searchTerm }}</template>
+ </gl-sprintf>
+ </gl-dropdown-item>
+ </template>
</gl-dropdown>
</template>
diff --git a/app/assets/javascripts/clusters_list/components/clusters.vue b/app/assets/javascripts/clusters_list/components/clusters.vue
index 7fb3aa3ff7e..59cfdde731d 100644
--- a/app/assets/javascripts/clusters_list/components/clusters.vue
+++ b/app/assets/javascripts/clusters_list/components/clusters.vue
@@ -6,7 +6,7 @@ import {
GlPagination,
GlDeprecatedSkeletonLoading as GlSkeletonLoading,
GlSprintf,
- GlTable,
+ GlTableLite,
GlTooltipDirective,
} from '@gitlab/ui';
import { mapState, mapActions } from 'vuex';
@@ -27,7 +27,7 @@ export default {
GlPagination,
GlSkeletonLoading,
GlSprintf,
- GlTable,
+ GlTableLite,
NodeErrorHelpText,
ClustersEmptyState,
},
@@ -229,7 +229,7 @@ export default {
<section v-else>
<ancestor-notice />
- <gl-table
+ <gl-table-lite
v-if="hasClusters"
:items="clusters"
:fields="fields"
@@ -326,7 +326,7 @@ export default {
{{ value }}
</gl-badge>
</template>
- </gl-table>
+ </gl-table-lite>
<clusters-empty-state v-else :is-child-component="isChildComponent" />
diff --git a/app/assets/javascripts/clusters_list/components/clusters_actions.vue b/app/assets/javascripts/clusters_list/components/clusters_actions.vue
index 5b8dc74b84f..ccb973f1eb8 100644
--- a/app/assets/javascripts/clusters_list/components/clusters_actions.vue
+++ b/app/assets/javascripts/clusters_list/components/clusters_actions.vue
@@ -1,5 +1,6 @@
<script>
import {
+ GlButton,
GlDropdown,
GlDropdownItem,
GlModalDirective,
@@ -14,6 +15,7 @@ export default {
i18n: CLUSTERS_ACTIONS,
INSTALL_AGENT_MODAL_ID,
components: {
+ GlButton,
GlDropdown,
GlDropdownItem,
GlDropdownDivider,
@@ -23,11 +25,27 @@ export default {
GlModalDirective,
GlTooltip: GlTooltipDirective,
},
- inject: ['newClusterPath', 'addClusterPath', 'canAddCluster'],
+ inject: [
+ 'newClusterPath',
+ 'addClusterPath',
+ 'canAddCluster',
+ 'displayClusterAgents',
+ 'certificateBasedClustersEnabled',
+ ],
computed: {
tooltip() {
- const { connectWithAgent, dropdownDisabledHint } = this.$options.i18n;
- return this.canAddCluster ? connectWithAgent : dropdownDisabledHint;
+ const { connectWithAgent, connectExistingCluster, dropdownDisabledHint } = this.$options.i18n;
+
+ if (!this.canAddCluster) {
+ return dropdownDisabledHint;
+ } else if (this.displayClusterAgents) {
+ return connectWithAgent;
+ }
+
+ return connectExistingCluster;
+ },
+ shouldTriggerModal() {
+ return this.canAddCluster && this.displayClusterAgents;
},
},
};
@@ -36,25 +54,29 @@ export default {
<template>
<div class="nav-controls gl-ml-auto">
<gl-dropdown
+ v-if="certificateBasedClustersEnabled"
ref="dropdown"
- v-gl-modal-directive="canAddCluster && $options.INSTALL_AGENT_MODAL_ID"
+ v-gl-modal-directive="shouldTriggerModal && $options.INSTALL_AGENT_MODAL_ID"
v-gl-tooltip="tooltip"
category="primary"
variant="confirm"
:text="$options.i18n.actionsButton"
:disabled="!canAddCluster"
- split
+ :split="displayClusterAgents"
right
>
- <gl-dropdown-section-header>{{ $options.i18n.agent }}</gl-dropdown-section-header>
- <gl-dropdown-item
- v-gl-modal-directive="$options.INSTALL_AGENT_MODAL_ID"
- data-testid="connect-new-agent-link"
- >
- {{ $options.i18n.connectWithAgent }}
- </gl-dropdown-item>
- <gl-dropdown-divider />
- <gl-dropdown-section-header>{{ $options.i18n.certificate }}</gl-dropdown-section-header>
+ <template v-if="displayClusterAgents">
+ <gl-dropdown-section-header>{{ $options.i18n.agent }}</gl-dropdown-section-header>
+ <gl-dropdown-item
+ v-gl-modal-directive="$options.INSTALL_AGENT_MODAL_ID"
+ data-testid="connect-new-agent-link"
+ >
+ {{ $options.i18n.connectWithAgent }}
+ </gl-dropdown-item>
+ <gl-dropdown-divider />
+ <gl-dropdown-section-header>{{ $options.i18n.certificate }}</gl-dropdown-section-header>
+ </template>
+
<gl-dropdown-item :href="newClusterPath" data-testid="new-cluster-link" @click.stop>
{{ $options.i18n.createNewCluster }}
</gl-dropdown-item>
@@ -62,5 +84,15 @@ export default {
{{ $options.i18n.connectExistingCluster }}
</gl-dropdown-item>
</gl-dropdown>
+ <gl-button
+ v-else
+ v-gl-modal-directive="$options.INSTALL_AGENT_MODAL_ID"
+ v-gl-tooltip="tooltip"
+ :disabled="!canAddCluster"
+ category="primary"
+ variant="confirm"
+ >
+ {{ $options.i18n.connectWithAgent }}
+ </gl-button>
</div>
</template>
diff --git a/app/assets/javascripts/clusters_list/components/clusters_empty_state.vue b/app/assets/javascripts/clusters_list/components/clusters_empty_state.vue
index ce601de57bd..76bec05cfc7 100644
--- a/app/assets/javascripts/clusters_list/components/clusters_empty_state.vue
+++ b/app/assets/javascripts/clusters_list/components/clusters_empty_state.vue
@@ -13,7 +13,7 @@ export default {
GlSprintf,
GlAlert,
},
- inject: ['emptyStateHelpText', 'clustersEmptyStateImage', 'newClusterPath'],
+ inject: ['emptyStateHelpText', 'clustersEmptyStateImage', 'addClusterPath'],
props: {
isChildComponent: {
default: false,
@@ -57,7 +57,7 @@ export default {
category="primary"
variant="confirm"
:disabled="!canAddCluster"
- :href="newClusterPath"
+ :href="addClusterPath"
>
{{ $options.i18n.buttonText }}
</gl-button>
diff --git a/app/assets/javascripts/clusters_list/components/clusters_main_view.vue b/app/assets/javascripts/clusters_list/components/clusters_main_view.vue
index 7dd5ece9b8e..aab6d3dc1f0 100644
--- a/app/assets/javascripts/clusters_list/components/clusters_main_view.vue
+++ b/app/assets/javascripts/clusters_list/components/clusters_main_view.vue
@@ -3,11 +3,13 @@ import { GlTabs, GlTab } from '@gitlab/ui';
import Tracking from '~/tracking';
import {
CLUSTERS_TABS,
+ CERTIFICATE_TAB,
MAX_CLUSTERS_LIST,
MAX_LIST_COUNT,
AGENT,
EVENT_LABEL_TABS,
EVENT_ACTIONS_CHANGE,
+ AGENT_TAB,
} from '../constants';
import Agents from './agents.vue';
import InstallAgentModal from './install_agent_modal.vue';
@@ -27,8 +29,8 @@ export default {
Agents,
InstallAgentModal,
},
- CLUSTERS_TABS,
mixins: [trackingMixin],
+ inject: ['displayClusterAgents', 'certificateBasedClustersEnabled'],
props: {
defaultBranchName: {
default: '.noBranch',
@@ -42,13 +44,30 @@ export default {
maxAgents: MAX_CLUSTERS_LIST,
};
},
+ computed: {
+ availableTabs() {
+ const clusterTabs = this.displayClusterAgents ? CLUSTERS_TABS : [CERTIFICATE_TAB];
+ return this.certificateBasedClustersEnabled ? clusterTabs : [AGENT_TAB];
+ },
+ },
+ watch: {
+ selectedTabIndex: {
+ handler(val) {
+ this.onTabChange(val);
+ },
+ immediate: true,
+ },
+ },
methods: {
- onTabChange(tabName) {
- this.selectedTabIndex = CLUSTERS_TABS.findIndex((tab) => tab.queryParamValue === tabName);
- this.maxAgents = tabName === AGENT ? MAX_LIST_COUNT : MAX_CLUSTERS_LIST;
+ setSelectedTab(tabName) {
+ this.selectedTabIndex = this.availableTabs.findIndex(
+ (tab) => tab.queryParamValue === tabName,
+ );
},
- trackTabChange(tab) {
- const tabName = CLUSTERS_TABS[tab].queryParamValue;
+ onTabChange(tab) {
+ const tabName = this.availableTabs[tab].queryParamValue;
+
+ this.maxAgents = tabName === AGENT ? MAX_LIST_COUNT : MAX_CLUSTERS_LIST;
this.track(EVENT_ACTIONS_CHANGE, { property: tabName });
},
},
@@ -61,10 +80,9 @@ export default {
sync-active-tab-with-query-params
nav-class="gl-flex-grow-1 gl-align-items-center"
lazy
- @input="trackTabChange"
>
<gl-tab
- v-for="(tab, idx) in $options.CLUSTERS_TABS"
+ v-for="(tab, idx) in availableTabs"
:key="idx"
:title="tab.title"
:query-param-value="tab.queryParamValue"
@@ -74,7 +92,7 @@ export default {
:is="tab.component"
:default-branch-name="defaultBranchName"
data-testid="clusters-tab-component"
- @changeTab="onTabChange"
+ @changeTab="setSelectedTab"
/>
</gl-tab>
diff --git a/app/assets/javascripts/clusters_list/components/delete_agent_button.vue b/app/assets/javascripts/clusters_list/components/delete_agent_button.vue
index 6588d304d5c..6f2c353a67b 100644
--- a/app/assets/javascripts/clusters_list/components/delete_agent_button.vue
+++ b/app/assets/javascripts/clusters_list/components/delete_agent_button.vue
@@ -116,7 +116,7 @@ export default {
this.$toast.show(this.error || successMessage);
- this.$refs.modal.hide();
+ this.$refs.modal?.hide();
}
},
deleteAgentMutation() {
diff --git a/app/assets/javascripts/clusters_list/components/install_agent_modal.vue b/app/assets/javascripts/clusters_list/components/install_agent_modal.vue
index 8fc0a66cd7e..ae0affe4c8b 100644
--- a/app/assets/javascripts/clusters_list/components/install_agent_modal.vue
+++ b/app/assets/javascripts/clusters_list/components/install_agent_modal.vue
@@ -1,18 +1,7 @@
<script>
-import {
- GlAlert,
- GlButton,
- GlFormGroup,
- GlFormInputGroup,
- GlLink,
- GlModal,
- GlSprintf,
-} from '@gitlab/ui';
+import { GlAlert, GlButton, GlFormGroup, GlLink, GlModal, GlSprintf } from '@gitlab/ui';
import { helpPagePath } from '~/helpers/help_page_helper';
-import ModalCopyButton from '~/vue_shared/components/modal_copy_button.vue';
-import CodeBlock from '~/vue_shared/components/code_block.vue';
import Tracking from '~/tracking';
-import { generateAgentRegistrationCommand } from '../clusters_util';
import {
INSTALL_AGENT_MODAL_ID,
I18N_AGENT_MODAL,
@@ -30,39 +19,32 @@ import createAgentToken from '../graphql/mutations/create_agent_token.mutation.g
import getAgentsQuery from '../graphql/queries/get_agents.query.graphql';
import agentConfigurations from '../graphql/queries/agent_configurations.query.graphql';
import AvailableAgentsDropdown from './available_agents_dropdown.vue';
+import AgentToken from './agent_token.vue';
const trackingMixin = Tracking.mixin({ label: EVENT_LABEL_MODAL });
export default {
modalId: INSTALL_AGENT_MODAL_ID,
+ i18n: I18N_AGENT_MODAL,
EVENT_ACTIONS_OPEN,
EVENT_ACTIONS_CLICK,
EVENT_LABEL_MODAL,
- basicInstallPath: helpPagePath('user/clusters/agent/install/index', {
- anchor: 'install-the-agent-into-the-cluster',
- }),
- advancedInstallPath: helpPagePath('user/clusters/agent/install/index', {
- anchor: 'advanced-installation',
- }),
enableKasPath: helpPagePath('administration/clusters/kas'),
- installAgentPath: helpPagePath('user/clusters/agent/install/index'),
registerAgentPath: helpPagePath('user/clusters/agent/install/index', {
anchor: 'register-an-agent-with-gitlab',
}),
components: {
AvailableAgentsDropdown,
- CodeBlock,
+ AgentToken,
GlAlert,
GlButton,
GlFormGroup,
- GlFormInputGroup,
GlLink,
GlModal,
GlSprintf,
- ModalCopyButton,
},
mixins: [trackingMixin],
- inject: ['projectPath', 'kasAddress', 'emptyStateImage'],
+ inject: ['projectPath', 'emptyStateImage'],
props: {
defaultBranchName: {
default: '.noBranch',
@@ -109,13 +91,10 @@ export default {
return !this.registering && this.agentName !== null;
},
canCancel() {
- return !this.registered && !this.registering && this.isAgentRegistrationModal;
+ return !this.registered && !this.registering && !this.kasDisabled;
},
canRegister() {
- return !this.registered && this.isAgentRegistrationModal;
- },
- agentRegistrationCommand() {
- return generateAgentRegistrationCommand(this.agentToken, this.kasAddress);
+ return !this.registered && !this.kasDisabled;
},
getAgentsQueryVariables() {
return {
@@ -125,32 +104,20 @@ export default {
projectPath: this.projectPath,
};
},
- i18n() {
- return I18N_AGENT_MODAL[this.modalType];
- },
+
repositoryPath() {
return `/${this.projectPath}`;
},
modalType() {
- return !this.availableAgents?.length && !this.registered
- ? MODAL_TYPE_EMPTY
- : MODAL_TYPE_REGISTER;
+ return this.kasDisabled ? MODAL_TYPE_EMPTY : MODAL_TYPE_REGISTER;
},
modalSize() {
- return this.isEmptyStateModal ? 'sm' : 'md';
- },
- isEmptyStateModal() {
- return this.modalType === MODAL_TYPE_EMPTY;
- },
- isAgentRegistrationModal() {
- return this.modalType === MODAL_TYPE_REGISTER;
- },
- isKasEnabledInEmptyStateModal() {
- return this.isEmptyStateModal && !this.kasDisabled;
+ return this.kasDisabled ? 'sm' : 'md';
},
},
methods: {
setAgentName(name) {
+ this.error = null;
this.agentName = name;
this.track(EVENT_ACTIONS_SELECT);
},
@@ -194,13 +161,13 @@ export default {
return createClusterAgent;
});
},
- createAgentTokenMutation(agendId) {
+ createAgentTokenMutation(agentId) {
return this.$apollo
.mutate({
mutation: createAgentToken,
variables: {
input: {
- clusterAgentId: agendId,
+ clusterAgentId: agentId,
name: this.agentName,
},
},
@@ -244,7 +211,7 @@ export default {
if (error) {
this.error = error.message;
} else {
- this.error = this.i18n.unknownError;
+ this.error = this.$options.i18n.unknownError;
}
} finally {
this.registering = false;
@@ -258,22 +225,21 @@ export default {
<gl-modal
ref="modal"
:modal-id="$options.modalId"
- :title="i18n.modalTitle"
+ :title="$options.i18n.modalTitle"
:size="modalSize"
static
lazy
@hidden="resetModal"
@show="track($options.EVENT_ACTIONS_OPEN, { property: modalType })"
>
- <template v-if="isAgentRegistrationModal">
+ <template v-if="!kasDisabled">
<template v-if="!registered">
- <p>
- <strong>{{ i18n.selectAgentTitle }}</strong>
- </p>
-
- <p class="gl-mb-0">{{ i18n.selectAgentBody }}</p>
- <p>
- <gl-link :href="$options.registerAgentPath"> {{ i18n.learnMoreLink }}</gl-link>
+ <p class="gl-mb-0">
+ <gl-sprintf :message="$options.i18n.modalBody">
+ <template #link="{ content }">
+ <gl-link :href="repositoryPath">{{ content }}</gl-link>
+ </template>
+ </gl-sprintf>
</p>
<form>
@@ -287,90 +253,36 @@ export default {
</gl-form-group>
</form>
- <p v-if="error">
- <gl-alert :title="i18n.registrationErrorTitle" variant="danger" :dismissible="false">
- {{ error }}
- </gl-alert>
- </p>
- </template>
-
- <template v-else>
- <p>
- <strong>{{ i18n.tokenTitle }}</strong>
- </p>
-
<p>
- <gl-sprintf :message="i18n.tokenBody">
- <template #link="{ content }">
- <gl-link :href="$options.basicInstallPath" target="_blank"> {{ content }}</gl-link>
- </template>
- </gl-sprintf>
+ <gl-link :href="$options.registerAgentPath"> {{ $options.i18n.learnMoreLink }}</gl-link>
</p>
- <p>
- <gl-alert :title="i18n.tokenSingleUseWarningTitle" variant="warning" :dismissible="false">
- {{ i18n.tokenSingleUseWarningBody }}
+ <p v-if="error">
+ <gl-alert
+ :title="$options.i18n.registrationErrorTitle"
+ variant="danger"
+ :dismissible="false"
+ >
+ {{ error }}
</gl-alert>
</p>
-
- <p>
- <gl-form-input-group readonly :value="agentToken" :select-on-click="true">
- <template #append>
- <modal-copy-button
- :text="agentToken"
- :title="i18n.copyToken"
- :modal-id="$options.modalId"
- />
- </template>
- </gl-form-input-group>
- </p>
-
- <p>
- <strong>{{ i18n.basicInstallTitle }}</strong>
- </p>
-
- <p>
- {{ i18n.basicInstallBody }}
- </p>
-
- <p>
- <code-block :code="agentRegistrationCommand" />
- </p>
-
- <p>
- <strong>{{ i18n.advancedInstallTitle }}</strong>
- </p>
-
- <p>
- <gl-sprintf :message="i18n.advancedInstallBody">
- <template #link="{ content }">
- <gl-link :href="$options.advancedInstallPath" target="_blank"> {{ content }}</gl-link>
- </template>
- </gl-sprintf>
- </p>
</template>
+
+ <agent-token v-else :agent-token="agentToken" :modal-id="$options.modalId" />
</template>
<template v-else>
<div class="gl-text-center gl-mb-5">
- <img :alt="i18n.altText" :src="emptyStateImage" height="100" />
+ <img :alt="$options.i18n.altText" :src="emptyStateImage" height="100" />
</div>
<p v-if="kasDisabled">
- <gl-sprintf :message="i18n.enableKasText">
+ <gl-sprintf :message="$options.i18n.enableKasText">
<template #link="{ content }">
<gl-link :href="$options.enableKasPath">{{ content }}</gl-link>
</template>
</gl-sprintf>
</p>
-
- <p v-else>
- <gl-sprintf :message="i18n.modalBody">
- <template #link="{ content }">
- <gl-link :href="$options.installAgentPath">{{ content }}</gl-link>
- </template>
- </gl-sprintf>
- </p>
</template>
<template #modal-footer>
@@ -382,7 +294,7 @@ export default {
:data-track-label="$options.EVENT_LABEL_MODAL"
data-track-property="close"
@click="closeModal"
- >{{ i18n.close }}
+ >{{ $options.i18n.close }}
</gl-button>
<gl-button
@@ -391,7 +303,7 @@ export default {
:data-track-label="$options.EVENT_LABEL_MODAL"
data-track-property="cancel"
@click="closeModal"
- >{{ i18n.cancel }}
+ >{{ $options.i18n.cancel }}
</gl-button>
<gl-button
@@ -403,25 +315,16 @@ export default {
:data-track-label="$options.EVENT_LABEL_MODAL"
data-track-property="register"
@click="registerAgent"
- >{{ i18n.registerAgentButton }}
+ >{{ $options.i18n.registerAgentButton }}
</gl-button>
<gl-button
- v-if="isEmptyStateModal"
+ v-if="kasDisabled"
:data-track-action="$options.EVENT_ACTIONS_CLICK"
:data-track-label="$options.EVENT_LABEL_MODAL"
data-track-property="done"
@click="closeModal"
- >{{ i18n.done }}
- </gl-button>
-
- <gl-button
- v-if="isKasEnabledInEmptyStateModal"
- :href="repositoryPath"
- variant="confirm"
- category="primary"
- data-testid="agent-primary-button"
- >{{ i18n.primaryButton }}
+ >{{ $options.i18n.close }}
</gl-button>
</template>
</gl-modal>
diff --git a/app/assets/javascripts/clusters_list/constants.js b/app/assets/javascripts/clusters_list/constants.js
index 5cf6fd050a1..c914ee518b2 100644
--- a/app/assets/javascripts/clusters_list/constants.js
+++ b/app/assets/javascripts/clusters_list/constants.js
@@ -75,74 +75,74 @@ export const I18N_AGENT_TABLE = {
neverConnectedText: s__('ClusterAgents|Never'),
versionMismatchTitle: s__('ClusterAgents|Agent version mismatch'),
versionMismatchText: s__(
- "ClusterAgents|The Agent version do not match each other across your cluster's pods. This can happen when a new Agent version was just deployed and Kubernetes is shutting down the old pods.",
+ "ClusterAgents|The agent version do not match each other across your cluster's pods. This can happen when a new agent version was just deployed and Kubernetes is shutting down the old pods.",
),
versionOutdatedTitle: s__('ClusterAgents|Agent version update required'),
versionOutdatedText: s__(
- 'ClusterAgents|Your Agent version is out of sync with your GitLab version (v%{version}), which might cause compatibility problems. Update the Agent installed on your cluster to the most recent version.',
+ 'ClusterAgents|Your agent version is out of sync with your GitLab version (v%{version}), which might cause compatibility problems. Update the agent installed on your cluster to the most recent version.',
),
versionMismatchOutdatedTitle: s__('ClusterAgents|Agent version mismatch and update'),
- viewDocsText: s__('ClusterAgents|How to update the Agent?'),
+ viewDocsText: s__('ClusterAgents|How to update an agent?'),
+ defaultConfigText: s__('ClusterAgents|Default configuration'),
+ defaultConfigTooltip: s__('ClusterAgents|What is default configuration?'),
};
-export const I18N_AGENT_MODAL = {
- agent_registration: {
- registerAgentButton: s__('ClusterAgents|Register'),
- close: __('Close'),
- cancel: __('Cancel'),
-
- modalTitle: s__('ClusterAgents|Connect a cluster through the Agent'),
- selectAgentTitle: s__('ClusterAgents|Select an agent to register with GitLab'),
- selectAgentBody: s__(
- 'ClusterAgents|Register an agent to generate a token that will be used to install the agent on your cluster in the next step.',
- ),
- learnMoreLink: s__('ClusterAgents|How to register an agent?'),
+export const I18N_AGENT_TOKEN = {
+ copyToken: s__('ClusterAgents|Copy token'),
+ copyCommand: s__('ClusterAgents|Copy command'),
+ tokenTitle: s__('ClusterAgents|Registration token'),
- copyToken: s__('ClusterAgents|Copy token'),
- tokenTitle: s__('ClusterAgents|Registration token'),
- tokenBody: s__(
- `ClusterAgents|The registration token will be used to connect the agent on your cluster to GitLab. %{linkStart}What are registration tokens?%{linkEnd}`,
- ),
+ tokenBody: s__(
+ `ClusterAgents|The registration token will be used to connect the agent on your cluster to GitLab. %{linkStart}What are registration tokens?%{linkEnd}`,
+ ),
+ tokenSingleUseWarningTitle: s__(
+ 'ClusterAgents|You cannot see this token again after you close this window.',
+ ),
+ tokenSingleUseWarningBody: s__(
+ `ClusterAgents|The recommended installation method includes the token. If you want to follow the advanced installation method provided in the docs, make sure you save the token value before you close this window.`,
+ ),
- tokenSingleUseWarningTitle: s__(
- 'ClusterAgents|You cannot see this token again after you close this window.',
- ),
- tokenSingleUseWarningBody: s__(
- `ClusterAgents|The recommended installation method includes the token. If you want to follow the advanced installation method provided in the docs, make sure you save the token value before you close this window.`,
- ),
+ basicInstallTitle: s__('ClusterAgents|Recommended installation method'),
+ basicInstallBody: __(
+ `Open a CLI and connect to the cluster you want to install the agent in. Use this installation method to minimize any manual steps. The token is already included in the command.`,
+ ),
- basicInstallTitle: s__('ClusterAgents|Recommended installation method'),
- basicInstallBody: __(
- `Open a CLI and connect to the cluster you want to install the agent in. Use this installation method to minimize any manual steps. The token is already included in the command.`,
- ),
+ advancedInstallTitle: s__('ClusterAgents|Advanced installation methods'),
+ advancedInstallBody: s__(
+ 'ClusterAgents|For the advanced installation method %{linkStart}see the documentation%{linkEnd}.',
+ ),
+};
- advancedInstallTitle: s__('ClusterAgents|Advanced installation methods'),
- advancedInstallBody: s__(
- 'ClusterAgents|For the advanced installation method %{linkStart}see the documentation%{linkEnd}.',
- ),
+export const I18N_AGENT_MODAL = {
+ registerAgentButton: s__('ClusterAgents|Register'),
+ close: __('Close'),
+ cancel: __('Cancel'),
- registrationErrorTitle: s__('ClusterAgents|Failed to register an agent'),
- unknownError: s__('ClusterAgents|An unknown error occurred. Please try again.'),
- },
- empty_state: {
- modalTitle: s__('ClusterAgents|Connect your cluster through the Agent'),
- modalBody: s__(
- "ClusterAgents|To install a new agent, first add the agent's configuration file to this repository. %{linkStart}Learn more about installing GitLab Agent.%{linkEnd}",
- ),
- enableKasText: s__(
- "ClusterAgents|Your instance doesn't have the %{linkStart}GitLab Agent Server (KAS)%{linkEnd} set up. Ask a GitLab Administrator to install it.",
- ),
- altText: s__('ClusterAgents|GitLab Agent for Kubernetes'),
- primaryButton: s__('ClusterAgents|Go to the repository files'),
- done: __('Cancel'),
- },
+ modalTitle: s__('ClusterAgents|Connect a cluster through an agent'),
+ modalBody: s__(
+ 'ClusterAgents|Add an agent configuration file to %{linkStart}this repository%{linkEnd} and select it, or create a new one to register with GitLab:',
+ ),
+ enableKasText: s__(
+ "ClusterAgents|Your instance doesn't have the %{linkStart}GitLab Agent Server (KAS)%{linkEnd} set up. Ask a GitLab Administrator to install it.",
+ ),
+ altText: s__('ClusterAgents|GitLab Agent for Kubernetes'),
+ learnMoreLink: s__('ClusterAgents|How do I register an agent?'),
+ copyToken: s__('ClusterAgents|Copy token'),
+ tokenTitle: s__('ClusterAgents|Registration token'),
+ tokenBody: s__(
+ `ClusterAgents|The registration token will be used to connect the agent on your cluster to GitLab. %{linkStart}What are registration tokens?%{linkEnd}`,
+ ),
+ registrationErrorTitle: s__('ClusterAgents|Failed to register an agent'),
+ unknownError: s__('ClusterAgents|An unknown error occurred. Please try again.'),
};
export const KAS_DISABLED_ERROR = 'Gitlab::Kas::Client::ConfigurationError';
export const I18N_AVAILABLE_AGENTS_DROPDOWN = {
- selectAgent: s__('ClusterAgents|Select an agent'),
- registeringAgent: s__('ClusterAgents|Registering Agent'),
+ selectAgent: s__('ClusterAgents|Select an agent or enter a name to create new'),
+ registeringAgent: s__('ClusterAgents|Registering agent'),
+ noResults: __('No matching results'),
+ createButton: s__('ClusterAgents|Create agent: %{searchTerm}'),
};
export const AGENT_STATUSES = {
@@ -197,8 +197,8 @@ export const I18N_CLUSTERS_EMPTY_STATE = {
export const AGENT_CARD_INFO = {
tabName: 'agent',
- title: sprintf(s__('ClusterAgents|%{number} of %{total} Agents')),
- emptyTitle: s__('ClusterAgents|No Agents'),
+ title: sprintf(s__('ClusterAgents|%{number} of %{total} agents')),
+ emptyTitle: s__('ClusterAgents|No agents'),
tooltip: {
label: s__('ClusterAgents|Recommended'),
title: s__('ClusterAgents|GitLab Agent'),
@@ -209,7 +209,7 @@ export const AGENT_CARD_INFO = {
),
link: helpPagePath('user/clusters/agent/index'),
},
- actionText: s__('ClusterAgents|Install new Agent'),
+ actionText: s__('ClusterAgents|Install a new agent'),
footerText: sprintf(s__('ClusterAgents|View all %{number} agents')),
installAgentDisabledHint: s__(
'ClusterAgents|Requires a Maintainer or greater role to install new agents',
@@ -232,28 +232,29 @@ export const CERTIFICATE_BASED_CARD_INFO = {
export const MAX_CLUSTERS_LIST = 6;
-export const CLUSTERS_TABS = [
- {
- title: s__('ClusterAgents|All'),
- component: 'ClustersViewAll',
- queryParamValue: 'all',
- },
- {
- title: s__('ClusterAgents|Agent'),
- component: 'agents',
- queryParamValue: 'agent',
- },
- {
- title: s__('ClusterAgents|Certificate'),
- component: 'clusters',
- queryParamValue: 'certificate_based',
- },
-];
+export const ALL_TAB = {
+ title: s__('ClusterAgents|All'),
+ component: 'ClustersViewAll',
+ queryParamValue: 'all',
+};
+
+export const AGENT_TAB = {
+ title: s__('ClusterAgents|Agent'),
+ component: 'agents',
+ queryParamValue: 'agent',
+};
+export const CERTIFICATE_TAB = {
+ title: s__('ClusterAgents|Certificate'),
+ component: 'clusters',
+ queryParamValue: 'certificate_based',
+};
+
+export const CLUSTERS_TABS = [ALL_TAB, AGENT_TAB, CERTIFICATE_TAB];
export const CLUSTERS_ACTIONS = {
actionsButton: s__('ClusterAgents|Actions'),
createNewCluster: s__('ClusterAgents|Create a new cluster'),
- connectWithAgent: s__('ClusterAgents|Connect with Agent'),
+ connectWithAgent: s__('ClusterAgents|Connect with an agent'),
connectExistingCluster: s__('ClusterAgents|Connect with a certificate'),
agent: s__('ClusterAgents|Agent'),
certificate: s__('ClusterAgents|Certificate'),
diff --git a/app/assets/javascripts/clusters_list/graphql/cache_update.js b/app/assets/javascripts/clusters_list/graphql/cache_update.js
index 6476b7a6c2f..e68f6a378c0 100644
--- a/app/assets/javascripts/clusters_list/graphql/cache_update.js
+++ b/app/assets/javascripts/clusters_list/graphql/cache_update.js
@@ -1,5 +1,4 @@
import produce from 'immer';
-import { getAgentConfigPath } from '../clusters_util';
export const hasErrors = ({ errors = [] }) => errors?.length;
@@ -12,17 +11,8 @@ export function addAgentToStore(store, createClusterAgent, query, variables) {
});
const data = produce(sourceData, (draftData) => {
- const configuration = {
- id: clusterAgent.id,
- name: clusterAgent.name,
- path: getAgentConfigPath(clusterAgent.name),
- webPath: clusterAgent.webPath,
- __typename: 'TreeEntry',
- };
-
draftData.project.clusterAgents.nodes.push(clusterAgent);
draftData.project.clusterAgents.count += 1;
- draftData.project.repository.tree.trees.nodes.push(configuration);
});
store.writeQuery({
diff --git a/app/assets/javascripts/clusters_list/graphql/queries/get_agents.query.graphql b/app/assets/javascripts/clusters_list/graphql/queries/get_agents.query.graphql
index f8efb6683f6..7743ffba5de 100644
--- a/app/assets/javascripts/clusters_list/graphql/queries/get_agents.query.graphql
+++ b/app/assets/javascripts/clusters_list/graphql/queries/get_agents.query.graphql
@@ -7,9 +7,7 @@ query getAgents(
$first: Int
$last: Int
$afterAgent: String
- $afterTree: String
$beforeAgent: String
- $beforeTree: String
) {
project(fullPath: $projectPath) {
id
@@ -27,17 +25,13 @@ query getAgents(
repository {
tree(path: ".gitlab/agents", ref: $defaultBranchName) {
- trees(first: $first, last: $last, after: $afterTree, before: $beforeTree) {
+ trees {
nodes {
id
name
path
webPath
}
-
- pageInfo {
- ...PageInfo
- }
}
}
}
diff --git a/app/assets/javascripts/clusters_list/index.js b/app/assets/javascripts/clusters_list/index.js
index 6148483dcb0..27eebc9d891 100644
--- a/app/assets/javascripts/clusters_list/index.js
+++ b/app/assets/javascripts/clusters_list/index.js
@@ -1,13 +1,63 @@
import { GlToast } from '@gitlab/ui';
import Vue from 'vue';
import VueApollo from 'vue-apollo';
-import loadClusters from './load_clusters';
-import loadMainView from './load_main_view';
+import { parseBoolean } from '~/lib/utils/common_utils';
+import createDefaultClient from '~/lib/graphql';
+import ClustersMainView from './components/clusters_main_view.vue';
+import { createStore } from './store';
Vue.use(GlToast);
Vue.use(VueApollo);
export default () => {
- loadClusters(Vue);
- loadMainView(Vue, VueApollo);
+ const el = document.querySelector('.js-clusters-main-view');
+
+ if (!el) {
+ return null;
+ }
+
+ const defaultClient = createDefaultClient();
+
+ const {
+ emptyStateImage,
+ defaultBranchName,
+ projectPath,
+ kasAddress,
+ newClusterPath,
+ addClusterPath,
+ emptyStateHelpText,
+ clustersEmptyStateImage,
+ canAddCluster,
+ canAdminCluster,
+ gitlabVersion,
+ displayClusterAgents,
+ certificateBasedClustersEnabled,
+ } = el.dataset;
+
+ return new Vue({
+ el,
+ apolloProvider: new VueApollo({ defaultClient }),
+ provide: {
+ emptyStateImage,
+ projectPath,
+ kasAddress,
+ newClusterPath,
+ addClusterPath,
+ emptyStateHelpText,
+ clustersEmptyStateImage,
+ canAddCluster: parseBoolean(canAddCluster),
+ canAdminCluster: parseBoolean(canAdminCluster),
+ gitlabVersion,
+ displayClusterAgents: parseBoolean(displayClusterAgents),
+ certificateBasedClustersEnabled: parseBoolean(certificateBasedClustersEnabled),
+ },
+ store: createStore(el.dataset),
+ render(createElement) {
+ return createElement(ClustersMainView, {
+ props: {
+ defaultBranchName,
+ },
+ });
+ },
+ });
};
diff --git a/app/assets/javascripts/clusters_list/load_clusters.js b/app/assets/javascripts/clusters_list/load_clusters.js
deleted file mode 100644
index 1bb3ea546b2..00000000000
--- a/app/assets/javascripts/clusters_list/load_clusters.js
+++ /dev/null
@@ -1,25 +0,0 @@
-import Clusters from './components/clusters.vue';
-import { createStore } from './store';
-
-export default (Vue) => {
- const el = document.querySelector('#js-clusters-list-app');
-
- if (!el) {
- return null;
- }
-
- const { emptyStateHelpText, newClusterPath, clustersEmptyStateImage } = el.dataset;
-
- return new Vue({
- el,
- provide: {
- emptyStateHelpText,
- newClusterPath,
- clustersEmptyStateImage,
- },
- store: createStore(el.dataset),
- render(createElement) {
- return createElement(Clusters);
- },
- });
-};
diff --git a/app/assets/javascripts/clusters_list/load_main_view.js b/app/assets/javascripts/clusters_list/load_main_view.js
deleted file mode 100644
index d52b1d4a64d..00000000000
--- a/app/assets/javascripts/clusters_list/load_main_view.js
+++ /dev/null
@@ -1,57 +0,0 @@
-import Vue from 'vue';
-import VueApollo from 'vue-apollo';
-import { parseBoolean } from '~/lib/utils/common_utils';
-import createDefaultClient from '~/lib/graphql';
-import ClustersMainView from './components/clusters_main_view.vue';
-import { createStore } from './store';
-
-Vue.use(VueApollo);
-
-export default () => {
- const el = document.querySelector('.js-clusters-main-view');
-
- if (!el) {
- return null;
- }
-
- const defaultClient = createDefaultClient();
-
- const {
- emptyStateImage,
- defaultBranchName,
- projectPath,
- kasAddress,
- newClusterPath,
- addClusterPath,
- emptyStateHelpText,
- clustersEmptyStateImage,
- canAddCluster,
- canAdminCluster,
- gitlabVersion,
- } = el.dataset;
-
- return new Vue({
- el,
- apolloProvider: new VueApollo({ defaultClient }),
- provide: {
- emptyStateImage,
- projectPath,
- kasAddress,
- newClusterPath,
- addClusterPath,
- emptyStateHelpText,
- clustersEmptyStateImage,
- canAddCluster: parseBoolean(canAddCluster),
- canAdminCluster: parseBoolean(canAdminCluster),
- gitlabVersion,
- },
- store: createStore(el.dataset),
- render(createElement) {
- return createElement(ClustersMainView, {
- props: {
- defaultBranchName,
- },
- });
- },
- });
-};
diff --git a/app/assets/javascripts/code_navigation/components/app.vue b/app/assets/javascripts/code_navigation/components/app.vue
index d38b38947b6..5c77f087d63 100644
--- a/app/assets/javascripts/code_navigation/components/app.vue
+++ b/app/assets/javascripts/code_navigation/components/app.vue
@@ -7,6 +7,23 @@ export default {
components: {
Popover,
},
+ props: {
+ codeNavigationPath: {
+ type: String,
+ required: false,
+ default: null,
+ },
+ blobPath: {
+ type: String,
+ required: false,
+ default: null,
+ },
+ pathPrefix: {
+ type: String,
+ required: false,
+ default: null,
+ },
+ },
computed: {
...mapState([
'currentDefinition',
@@ -16,6 +33,14 @@ export default {
]),
},
mounted() {
+ if (this.codeNavigationPath && this.blobPath && this.pathPrefix) {
+ const initialData = {
+ blobs: [{ path: this.blobPath, codeNavigationPath: this.codeNavigationPath }],
+ definitionPathPrefix: this.pathPrefix,
+ };
+ this.setInitialData(initialData);
+ }
+
this.body = document.body;
eventHub.$on('showBlobInteractionZones', this.showBlobInteractionZones);
@@ -28,7 +53,7 @@ export default {
this.removeGlobalEventListeners();
},
methods: {
- ...mapActions(['fetchData', 'showDefinition', 'showBlobInteractionZones']),
+ ...mapActions(['fetchData', 'showDefinition', 'showBlobInteractionZones', 'setInitialData']),
addGlobalEventListeners() {
if (this.body) {
this.body.addEventListener('click', this.showDefinition);
diff --git a/app/assets/javascripts/code_quality_walkthrough/components/step.vue b/app/assets/javascripts/code_quality_walkthrough/components/step.vue
deleted file mode 100644
index 1a23c96b7d6..00000000000
--- a/app/assets/javascripts/code_quality_walkthrough/components/step.vue
+++ /dev/null
@@ -1,150 +0,0 @@
-<script>
-import { GlPopover, GlSprintf, GlButton, GlAlert } from '@gitlab/ui';
-import { STEPS, STEPSTATES } from '../constants';
-import {
- isWalkthroughEnabled,
- getExperimentSettings,
- setExperimentSettings,
- track,
-} from '../utils';
-
-export default {
- target: '#js-code-quality-walkthrough',
- components: {
- GlPopover,
- GlSprintf,
- GlButton,
- GlAlert,
- },
- props: {
- step: {
- type: String,
- required: true,
- },
- link: {
- type: String,
- required: false,
- default: null,
- },
- },
- data() {
- return {
- dismissedSettings: getExperimentSettings(),
- currentStep: STEPSTATES[this.step],
- };
- },
- computed: {
- isPopoverVisible() {
- return (
- [
- STEPS.commitCiFile,
- STEPS.runningPipeline,
- STEPS.successPipeline,
- STEPS.failedPipeline,
- ].includes(this.step) &&
- isWalkthroughEnabled() &&
- !this.isDismissed
- );
- },
- isAlertVisible() {
- return this.step === STEPS.troubleshootJob && isWalkthroughEnabled() && !this.isDismissed;
- },
- isDismissed() {
- return this.dismissedSettings[this.step];
- },
- title() {
- return this.currentStep?.title || '';
- },
- body() {
- return this.currentStep?.body || '';
- },
- buttonText() {
- return this.currentStep?.buttonText || '';
- },
- buttonLink() {
- return [STEPS.successPipeline, STEPS.failedPipeline].includes(this.step) ? this.link : '';
- },
- placement() {
- return this.currentStep?.placement || 'bottom';
- },
- offset() {
- return this.currentStep?.offset || 0;
- },
- },
- created() {
- this.trackDisplayed();
- },
- updated() {
- this.trackDisplayed();
- },
- methods: {
- onDismiss() {
- this.$set(this.dismissedSettings, this.step, true);
- setExperimentSettings(this.dismissedSettings);
- const action = [STEPS.successPipeline, STEPS.failedPipeline].includes(this.step)
- ? 'view_logs'
- : 'dismissed';
- this.trackAction(action);
- },
- trackDisplayed() {
- if (this.isPopoverVisible || this.isAlertVisible) {
- this.trackAction('displayed');
- }
- },
- trackAction(action) {
- track(`${this.step}_${action}`);
- },
- },
-};
-</script>
-
-<template>
- <div>
- <gl-popover
- v-if="isPopoverVisible"
- :key="step"
- :target="$options.target"
- :placement="placement"
- :offset="offset"
- show
- triggers="manual"
- container="viewport"
- >
- <template #title>
- <gl-sprintf :message="title">
- <template #emoji="{ content }">
- <gl-emoji class="gl-mr-2" :data-name="content"
- /></template>
- </gl-sprintf>
- </template>
- <gl-sprintf :message="body">
- <template #strong="{ content }">
- <strong>{{ content }}</strong>
- </template>
- <template #lineBreak>
- <div class="gl-mt-5"></div>
- </template>
- <template #emoji="{ content }">
- <gl-emoji :data-name="content" />
- </template>
- </gl-sprintf>
- <div class="gl-mt-2 gl-text-right">
- <gl-button category="tertiary" variant="link" :href="buttonLink" @click="onDismiss">
- {{ buttonText }}
- </gl-button>
- </div>
- </gl-popover>
- <gl-alert
- v-if="isAlertVisible"
- variant="tip"
- :title="title"
- :primary-button-text="buttonText"
- :primary-button-link="link"
- class="gl-my-5"
- @primaryAction="trackAction('clicked')"
- @dismiss="onDismiss"
- >
- {{ body }}
- </gl-alert>
- </div>
-</template>
diff --git a/app/assets/javascripts/code_quality_walkthrough/constants.js b/app/assets/javascripts/code_quality_walkthrough/constants.js
deleted file mode 100644
index 011df06b5cc..00000000000
--- a/app/assets/javascripts/code_quality_walkthrough/constants.js
+++ /dev/null
@@ -1,67 +0,0 @@
-import { s__ } from '~/locale';
-
-export const EXPERIMENT_NAME = 'code_quality_walkthrough';
-
-export const STEPS = {
- commitCiFile: 'commit_ci_file',
- runningPipeline: 'running_pipeline',
- successPipeline: 'success_pipeline',
- failedPipeline: 'failed_pipeline',
- troubleshootJob: 'troubleshoot_job',
-};
-
-export const STEPSTATES = {
- [STEPS.commitCiFile]: {
- title: s__("codeQualityWalkthrough|Let's start by creating a new CI file."),
- body: s__(
- 'codeQualityWalkthrough|To begin with code quality, we first need to create a new CI file using our code editor. We added a code quality template in the code editor to help you get started %{emojiStart}wink%{emojiEnd} .%{lineBreak}Take some time to review the template, when you are ready, use the %{strongStart}commit changes%{strongEnd} button at the bottom of the page.',
- ),
- buttonText: s__('codeQualityWalkthrough|Got it'),
- placement: 'right',
- offset: 90,
- },
- [STEPS.runningPipeline]: {
- title: s__(
- 'codeQualityWalkthrough|Congrats! Your first pipeline is running %{emojiStart}zap%{emojiEnd}',
- ),
- body: s__(
- "codeQualityWalkthrough|Your pipeline can take a few minutes to run. If you enabled email notifications, you'll receive an email with your pipeline status. In the meantime, why don't you get some coffee? You earned it!",
- ),
- buttonText: s__('codeQualityWalkthrough|Got it'),
- offset: 97,
- },
- [STEPS.successPipeline]: {
- title: s__(
- "codeQualityWalkthrough|Well done! You've just automated your code quality review. %{emojiStart}raised_hands%{emojiEnd}",
- ),
- body: s__(
- 'codeQualityWalkthrough|A code quality job will now run every time you or your team members commit changes to your project. You can view the results of the code quality job in the job logs.',
- ),
- buttonText: s__('codeQualityWalkthrough|View the logs'),
- offset: 98,
- },
- [STEPS.failedPipeline]: {
- title: s__(
- "codeQualityWalkthrough|Something went wrong. %{emojiStart}thinking%{emojiEnd} Let's fix it.",
- ),
- body: s__(
- "codeQualityWalkthrough|Your job failed. No worries - this happens. Let's view the logs, and see how we can fix it.",
- ),
- buttonText: s__('codeQualityWalkthrough|View the logs'),
- offset: 98,
- },
- [STEPS.troubleshootJob]: {
- title: s__('codeQualityWalkthrough|Troubleshoot your code quality job'),
- body: s__(
- 'codeQualityWalkthrough|Not sure how to fix your failed job? We have compiled some tips on how to troubleshoot code quality jobs in the documentation.',
- ),
- buttonText: s__('codeQualityWalkthrough|Read the documentation'),
- },
-};
-
-export const PIPELINE_STATUSES = {
- running: 'running',
- successWithWarnings: 'success-with-warnings',
- success: 'success',
- failed: 'failed',
-};
diff --git a/app/assets/javascripts/code_quality_walkthrough/index.js b/app/assets/javascripts/code_quality_walkthrough/index.js
deleted file mode 100644
index b0592b8a84b..00000000000
--- a/app/assets/javascripts/code_quality_walkthrough/index.js
+++ /dev/null
@@ -1,14 +0,0 @@
-import Vue from 'vue';
-import Step from './components/step.vue';
-
-export default (el) =>
- new Vue({
- el,
- render(createElement) {
- return createElement(Step, {
- props: {
- step: el.dataset.step,
- },
- });
- },
- });
diff --git a/app/assets/javascripts/code_quality_walkthrough/utils.js b/app/assets/javascripts/code_quality_walkthrough/utils.js
deleted file mode 100644
index 894ec9a171d..00000000000
--- a/app/assets/javascripts/code_quality_walkthrough/utils.js
+++ /dev/null
@@ -1,39 +0,0 @@
-import { TRACKING_CONTEXT_SCHEMA } from '~/experimentation/constants';
-import { getExperimentData } from '~/experimentation/utils';
-import { setCookie, getCookie } from '~/lib/utils/common_utils';
-import { getParameterByName } from '~/lib/utils/url_utility';
-import Tracking from '~/tracking';
-import { EXPERIMENT_NAME } from './constants';
-
-export function getExperimentSettings() {
- return JSON.parse(getCookie(EXPERIMENT_NAME) || '{}');
-}
-
-export function setExperimentSettings(settings) {
- setCookie(EXPERIMENT_NAME, settings);
-}
-
-export function isWalkthroughEnabled() {
- return getParameterByName(EXPERIMENT_NAME);
-}
-
-export function track(action) {
- const { data } = getExperimentSettings();
-
- if (data) {
- Tracking.event(EXPERIMENT_NAME, action, {
- context: {
- schema: TRACKING_CONTEXT_SCHEMA,
- data,
- },
- });
- }
-}
-
-export function startCodeQualityWalkthrough() {
- const data = getExperimentData(EXPERIMENT_NAME);
-
- if (data) {
- setExperimentSettings({ data });
- }
-}
diff --git a/app/assets/javascripts/commons/nav/user_merge_requests.js b/app/assets/javascripts/commons/nav/user_merge_requests.js
index 84ab728274f..784e9cb2faa 100644
--- a/app/assets/javascripts/commons/nav/user_merge_requests.js
+++ b/app/assets/javascripts/commons/nav/user_merge_requests.js
@@ -23,7 +23,18 @@ function updateReviewerMergeRequestCounts(newCount) {
function updateMergeRequestCounts(newCount) {
const mergeRequestsCountEl = document.querySelector('.js-merge-requests-count');
mergeRequestsCountEl.textContent = newCount.toLocaleString();
- mergeRequestsCountEl.classList.toggle('hidden', Number(newCount) === 0);
+ mergeRequestsCountEl.classList.toggle('gl-display-none', Number(newCount) === 0);
+}
+
+function updateAttentionRequestsCount(count) {
+ const attentionCountEl = document.querySelector('.js-attention-count');
+ attentionCountEl.textContent = count.toLocaleString();
+
+ if (Number(count) === 0) {
+ attentionCountEl.classList.replace('badge-warning', 'badge-neutral');
+ } else {
+ attentionCountEl.classList.replace('badge-neutral', 'badge-warning');
+ }
}
/**
@@ -32,14 +43,22 @@ function updateMergeRequestCounts(newCount) {
export function refreshUserMergeRequestCounts() {
return getUserCounts()
.then(({ data }) => {
+ const attentionRequestsEnabled = window.gon?.features?.mrAttentionRequests;
const assignedMergeRequests = data.assigned_merge_requests;
const reviewerMergeRequests = data.review_requested_merge_requests;
- const fullCount = assignedMergeRequests + reviewerMergeRequests;
+ const attentionRequests = data.attention_requests;
+ const fullCount = attentionRequestsEnabled
+ ? attentionRequests
+ : assignedMergeRequests + reviewerMergeRequests;
updateUserMergeRequestCounts(assignedMergeRequests);
updateReviewerMergeRequestCounts(reviewerMergeRequests);
updateMergeRequestCounts(fullCount);
broadcastCount(fullCount);
+
+ if (attentionRequestsEnabled) {
+ updateAttentionRequestsCount(attentionRequests);
+ }
})
.catch((ex) => {
console.error(ex); // eslint-disable-line no-console
diff --git a/app/assets/javascripts/content_editor/components/content_editor.vue b/app/assets/javascripts/content_editor/components/content_editor.vue
index a8405fe37c7..a942c9f1149 100644
--- a/app/assets/javascripts/content_editor/components/content_editor.vue
+++ b/app/assets/javascripts/content_editor/components/content_editor.vue
@@ -1,17 +1,16 @@
<script>
-import { GlLoadingIcon } from '@gitlab/ui';
import { EditorContent as TiptapEditorContent } from '@tiptap/vue-2';
-import { LOADING_CONTENT_EVENT, LOADING_SUCCESS_EVENT, LOADING_ERROR_EVENT } from '../constants';
import { createContentEditor } from '../services/create_content_editor';
import ContentEditorAlert from './content_editor_alert.vue';
import ContentEditorProvider from './content_editor_provider.vue';
import EditorStateObserver from './editor_state_observer.vue';
import FormattingBubbleMenu from './formatting_bubble_menu.vue';
import TopToolbar from './top_toolbar.vue';
+import LoadingIndicator from './loading_indicator.vue';
export default {
components: {
- GlLoadingIcon,
+ LoadingIndicator,
ContentEditorAlert,
ContentEditorProvider,
TiptapEditorContent,
@@ -41,7 +40,6 @@ export default {
},
data() {
return {
- isLoadingContent: false,
focused: false,
};
},
@@ -55,25 +53,14 @@ export default {
extensions,
serializerConfig,
});
-
- this.contentEditor.on(LOADING_CONTENT_EVENT, this.displayLoadingIndicator);
- this.contentEditor.on(LOADING_SUCCESS_EVENT, this.hideLoadingIndicator);
- this.contentEditor.on(LOADING_ERROR_EVENT, this.hideLoadingIndicator);
+ },
+ mounted() {
this.$emit('initialized', this.contentEditor);
},
beforeDestroy() {
this.contentEditor.dispose();
- this.contentEditor.off(LOADING_CONTENT_EVENT, this.displayLoadingIndicator);
- this.contentEditor.off(LOADING_SUCCESS_EVENT, this.hideLoadingIndicator);
- this.contentEditor.off(LOADING_ERROR_EVENT, this.hideLoadingIndicator);
},
methods: {
- displayLoadingIndicator() {
- this.isLoadingContent = true;
- },
- hideLoadingIndicator() {
- this.isLoadingContent = false;
- },
focus() {
this.focused = true;
},
@@ -100,13 +87,11 @@ export default {
:class="{ 'is-focused': focused }"
>
<top-toolbar ref="toolbar" class="gl-mb-4" />
- <div v-if="isLoadingContent" class="gl-w-full gl-display-flex gl-justify-content-center">
- <gl-loading-icon size="sm" />
- </div>
- <template v-else>
+ <div class="gl-relative">
<formatting-bubble-menu />
<tiptap-editor-content class="md" :editor="contentEditor.tiptapEditor" />
- </template>
+ <loading-indicator />
+ </div>
</div>
</div>
</content-editor-provider>
diff --git a/app/assets/javascripts/content_editor/components/content_editor_provider.vue b/app/assets/javascripts/content_editor/components/content_editor_provider.vue
index 630aff9858f..cba3b627390 100644
--- a/app/assets/javascripts/content_editor/components/content_editor_provider.vue
+++ b/app/assets/javascripts/content_editor/components/content_editor_provider.vue
@@ -8,6 +8,7 @@ export default {
return {
contentEditor,
+ eventHub: contentEditor.eventHub,
tiptapEditor: contentEditor.tiptapEditor,
};
},
diff --git a/app/assets/javascripts/content_editor/components/editor_state_observer.vue b/app/assets/javascripts/content_editor/components/editor_state_observer.vue
index 0604047a953..02de6470cf2 100644
--- a/app/assets/javascripts/content_editor/components/editor_state_observer.vue
+++ b/app/assets/javascripts/content_editor/components/editor_state_observer.vue
@@ -1,5 +1,11 @@
<script>
import { debounce } from 'lodash';
+import {
+ LOADING_CONTENT_EVENT,
+ LOADING_SUCCESS_EVENT,
+ LOADING_ERROR_EVENT,
+ ALERT_EVENT,
+} from '../constants';
export const tiptapToComponentMap = {
update: 'docUpdate',
@@ -7,30 +13,48 @@ export const tiptapToComponentMap = {
transaction: 'transaction',
focus: 'focus',
blur: 'blur',
- alert: 'alert',
};
+export const eventHubEvents = [
+ ALERT_EVENT,
+ LOADING_CONTENT_EVENT,
+ LOADING_SUCCESS_EVENT,
+ LOADING_ERROR_EVENT,
+];
+
const getComponentEventName = (tiptapEventName) => tiptapToComponentMap[tiptapEventName];
export default {
- inject: ['tiptapEditor'],
+ inject: ['tiptapEditor', 'eventHub'],
created() {
this.disposables = [];
Object.keys(tiptapToComponentMap).forEach((tiptapEvent) => {
- const eventHandler = debounce((params) => this.handleTipTapEvent(tiptapEvent, params), 100);
+ const eventHandler = debounce(
+ (params) => this.bubbleEvent(getComponentEventName(tiptapEvent), params),
+ 100,
+ );
this.tiptapEditor?.on(tiptapEvent, eventHandler);
this.disposables.push(() => this.tiptapEditor?.off(tiptapEvent, eventHandler));
});
+
+ eventHubEvents.forEach((event) => {
+ const handler = (...params) => {
+ this.bubbleEvent(event, ...params);
+ };
+
+ this.eventHub.$on(event, handler);
+ this.disposables.push(() => this.eventHub?.$off(event, handler));
+ });
},
beforeDestroy() {
this.disposables.forEach((dispose) => dispose());
},
methods: {
- handleTipTapEvent(tiptapEvent, params) {
- this.$emit(getComponentEventName(tiptapEvent), params);
+ bubbleEvent(eventHubEvent, params) {
+ this.$emit(eventHubEvent, params);
},
},
render() {
diff --git a/app/assets/javascripts/content_editor/components/loading_indicator.vue b/app/assets/javascripts/content_editor/components/loading_indicator.vue
new file mode 100644
index 00000000000..5b9383d6e11
--- /dev/null
+++ b/app/assets/javascripts/content_editor/components/loading_indicator.vue
@@ -0,0 +1,39 @@
+<script>
+import { GlLoadingIcon } from '@gitlab/ui';
+import EditorStateObserver from './editor_state_observer.vue';
+
+export default {
+ components: {
+ GlLoadingIcon,
+ EditorStateObserver,
+ },
+ data() {
+ return {
+ isLoading: false,
+ };
+ },
+ methods: {
+ displayLoadingIndicator() {
+ this.isLoading = true;
+ },
+ hideLoadingIndicator() {
+ this.isLoading = false;
+ },
+ },
+};
+</script>
+<template>
+ <editor-state-observer
+ @loading="displayLoadingIndicator"
+ @loadingSuccess="hideLoadingIndicator"
+ @loadingError="hideLoadingIndicator"
+ >
+ <div
+ v-if="isLoading"
+ class="gl-w-full gl-display-flex gl-justify-content-center gl-align-items-center gl-absolute gl-top-0 gl-bottom-0"
+ >
+ <div class="gl-bg-white gl-absolute gl-w-full gl-h-full gl-opacity-3"></div>
+ <gl-loading-icon size="md" />
+ </div>
+ </editor-state-observer>
+</template>
diff --git a/app/assets/javascripts/content_editor/constants.js b/app/assets/javascripts/content_editor/constants.js
index 5e56078df01..a39a243ec6b 100644
--- a/app/assets/javascripts/content_editor/constants.js
+++ b/app/assets/javascripts/content_editor/constants.js
@@ -42,9 +42,10 @@ export const TEXT_STYLE_DROPDOWN_ITEMS = [
},
];
-export const LOADING_CONTENT_EVENT = 'loadingContent';
+export const LOADING_CONTENT_EVENT = 'loading';
export const LOADING_SUCCESS_EVENT = 'loadingSuccess';
export const LOADING_ERROR_EVENT = 'loadingError';
+export const ALERT_EVENT = 'alert';
export const PARSE_HTML_PRIORITY_LOWEST = 1;
export const PARSE_HTML_PRIORITY_DEFAULT = 50;
@@ -56,3 +57,4 @@ export const EXTENSION_PRIORITY_LOWER = 75;
* https://tiptap.dev/guide/custom-extensions/#priority
*/
export const EXTENSION_PRIORITY_DEFAULT = 100;
+export const EXTENSION_PRIORITY_HIGHEST = 200;
diff --git a/app/assets/javascripts/content_editor/extensions/attachment.js b/app/assets/javascripts/content_editor/extensions/attachment.js
index 72df1d071d1..9634730f637 100644
--- a/app/assets/javascripts/content_editor/extensions/attachment.js
+++ b/app/assets/javascripts/content_editor/extensions/attachment.js
@@ -9,15 +9,22 @@ export default Extension.create({
return {
uploadsPath: null,
renderMarkdown: null,
+ eventHub: null,
};
},
addCommands() {
return {
uploadAttachment: ({ file }) => () => {
- const { uploadsPath, renderMarkdown } = this.options;
+ const { uploadsPath, renderMarkdown, eventHub } = this.options;
- return handleFileEvent({ file, uploadsPath, renderMarkdown, editor: this.editor });
+ return handleFileEvent({
+ file,
+ uploadsPath,
+ renderMarkdown,
+ editor: this.editor,
+ eventHub,
+ });
},
};
},
@@ -29,23 +36,25 @@ export default Extension.create({
key: new PluginKey('attachment'),
props: {
handlePaste: (_, event) => {
- const { uploadsPath, renderMarkdown } = this.options;
+ const { uploadsPath, renderMarkdown, eventHub } = this.options;
return handleFileEvent({
editor,
file: event.clipboardData.files[0],
uploadsPath,
renderMarkdown,
+ eventHub,
});
},
handleDrop: (_, event) => {
- const { uploadsPath, renderMarkdown } = this.options;
+ const { uploadsPath, renderMarkdown, eventHub } = this.options;
return handleFileEvent({
editor,
file: event.dataTransfer.files[0],
uploadsPath,
renderMarkdown,
+ eventHub,
});
},
},
diff --git a/app/assets/javascripts/content_editor/extensions/code_block_highlight.js b/app/assets/javascripts/content_editor/extensions/code_block_highlight.js
index 9dc17fcd570..204ac07d401 100644
--- a/app/assets/javascripts/content_editor/extensions/code_block_highlight.js
+++ b/app/assets/javascripts/content_editor/extensions/code_block_highlight.js
@@ -1,5 +1,5 @@
import { CodeBlockLowlight } from '@tiptap/extension-code-block-lowlight';
-import * as lowlight from 'lowlight';
+import { lowlight } from 'lowlight/lib/all';
const extractLanguage = (element) => element.getAttribute('lang');
diff --git a/app/assets/javascripts/content_editor/extensions/paste_markdown.js b/app/assets/javascripts/content_editor/extensions/paste_markdown.js
new file mode 100644
index 00000000000..c349aa42a62
--- /dev/null
+++ b/app/assets/javascripts/content_editor/extensions/paste_markdown.js
@@ -0,0 +1,86 @@
+import { Extension } from '@tiptap/core';
+import { Plugin, PluginKey } from 'prosemirror-state';
+import { __ } from '~/locale';
+import { VARIANT_DANGER } from '~/flash';
+import createMarkdownDeserializer from '../services/markdown_deserializer';
+import {
+ ALERT_EVENT,
+ LOADING_CONTENT_EVENT,
+ LOADING_SUCCESS_EVENT,
+ LOADING_ERROR_EVENT,
+ EXTENSION_PRIORITY_HIGHEST,
+} from '../constants';
+
+const TEXT_FORMAT = 'text/plain';
+const HTML_FORMAT = 'text/html';
+const VS_CODE_FORMAT = 'vscode-editor-data';
+
+export default Extension.create({
+ name: 'pasteMarkdown',
+ priority: EXTENSION_PRIORITY_HIGHEST,
+ addOptions() {
+ return {
+ renderMarkdown: null,
+ };
+ },
+ addCommands() {
+ return {
+ pasteMarkdown: (markdown) => () => {
+ const { editor, options } = this;
+ const { renderMarkdown, eventHub } = options;
+ const deserializer = createMarkdownDeserializer({ render: renderMarkdown });
+
+ eventHub.$emit(LOADING_CONTENT_EVENT);
+
+ deserializer
+ .deserialize({ schema: editor.schema, content: markdown })
+ .then(({ document }) => {
+ if (!document) {
+ return;
+ }
+
+ const { state, view } = editor;
+ const { tr, selection } = state;
+
+ tr.replaceWith(selection.from - 1, selection.to, document.content);
+ view.dispatch(tr);
+ eventHub.$emit(LOADING_SUCCESS_EVENT);
+ })
+ .catch(() => {
+ eventHub.$emit(ALERT_EVENT, {
+ message: __('An error occurred while pasting text in the editor. Please try again.'),
+ variant: VARIANT_DANGER,
+ });
+ eventHub.$emit(LOADING_ERROR_EVENT);
+ });
+
+ return true;
+ },
+ };
+ },
+ addProseMirrorPlugins() {
+ return [
+ new Plugin({
+ key: new PluginKey('pasteMarkdown'),
+ props: {
+ handlePaste: (_, event) => {
+ const { clipboardData } = event;
+ const content = clipboardData.getData(TEXT_FORMAT);
+ const hasHTML = clipboardData.types.some((type) => type === HTML_FORMAT);
+ const hasVsCode = clipboardData.types.some((type) => type === VS_CODE_FORMAT);
+ const vsCodeMeta = hasVsCode ? JSON.parse(clipboardData.getData(VS_CODE_FORMAT)) : {};
+ const language = vsCodeMeta.mode;
+
+ if (!content || (hasHTML && !hasVsCode) || (hasVsCode && language !== 'markdown')) {
+ return false;
+ }
+
+ this.editor.commands.pasteMarkdown(content);
+
+ return true;
+ },
+ },
+ }),
+ ];
+ },
+});
diff --git a/app/assets/javascripts/content_editor/extensions/table.js b/app/assets/javascripts/content_editor/extensions/table.js
index 004bb8b815c..d7456ab4094 100644
--- a/app/assets/javascripts/content_editor/extensions/table.js
+++ b/app/assets/javascripts/content_editor/extensions/table.js
@@ -1,5 +1,6 @@
import { Table } from '@tiptap/extension-table';
import { debounce } from 'lodash';
+import { VARIANT_WARNING } from '~/flash';
import { __ } from '~/locale';
import { getMarkdownSource } from '../services/markdown_sourcemap';
import { shouldRenderHTMLTable } from '../services/serialization_helpers';
@@ -14,7 +15,7 @@ const onUpdate = debounce((editor) => {
message: __(
'The content editor may change the markdown formatting style of the document, which may not match your original markdown style.',
),
- variant: 'warning',
+ variant: VARIANT_WARNING,
});
alertShown = true;
diff --git a/app/assets/javascripts/content_editor/services/content_editor.js b/app/assets/javascripts/content_editor/services/content_editor.js
index a387322bff7..c5638da2daf 100644
--- a/app/assets/javascripts/content_editor/services/content_editor.js
+++ b/app/assets/javascripts/content_editor/services/content_editor.js
@@ -1,17 +1,23 @@
-import eventHubFactory from '~/helpers/event_hub_factory';
+import { TextSelection } from 'prosemirror-state';
import { LOADING_CONTENT_EVENT, LOADING_SUCCESS_EVENT, LOADING_ERROR_EVENT } from '../constants';
+
/* eslint-disable no-underscore-dangle */
export class ContentEditor {
- constructor({ tiptapEditor, serializer }) {
+ constructor({ tiptapEditor, serializer, deserializer, eventHub }) {
this._tiptapEditor = tiptapEditor;
this._serializer = serializer;
- this._eventHub = eventHubFactory();
+ this._deserializer = deserializer;
+ this._eventHub = eventHub;
}
get tiptapEditor() {
return this._tiptapEditor;
}
+ get eventHub() {
+ return this._eventHub;
+ }
+
get empty() {
const doc = this.tiptapEditor?.state.doc;
@@ -23,39 +29,31 @@ export class ContentEditor {
this.tiptapEditor.destroy();
}
- once(type, handler) {
- this._eventHub.$once(type, handler);
- }
-
- on(type, handler) {
- this._eventHub.$on(type, handler);
- }
-
- emit(type, params = {}) {
- this._eventHub.$emit(type, params);
- }
-
- off(type, handler) {
- this._eventHub.$off(type, handler);
- }
-
disposeAllEvents() {
this._eventHub.dispose();
}
async setSerializedContent(serializedContent) {
- const { _tiptapEditor: editor, _serializer: serializer } = this;
+ const { _tiptapEditor: editor, _deserializer: deserializer, _eventHub: eventHub } = this;
+ const { doc, tr } = editor.state;
+ const selection = TextSelection.create(doc, 0, doc.content.size);
try {
- this._eventHub.$emit(LOADING_CONTENT_EVENT);
- const document = await serializer.deserialize({
+ eventHub.$emit(LOADING_CONTENT_EVENT);
+ const { document } = await deserializer.deserialize({
schema: editor.schema,
content: serializedContent,
});
- editor.commands.setContent(document);
- this._eventHub.$emit(LOADING_SUCCESS_EVENT);
+
+ if (document) {
+ tr.setSelection(selection)
+ .replaceSelectionWith(document, false)
+ .setMeta('preventUpdate', true);
+ editor.view.dispatch(tr);
+ }
+ eventHub.$emit(LOADING_SUCCESS_EVENT);
} catch (e) {
- this._eventHub.$emit(LOADING_ERROR_EVENT, e);
+ eventHub.$emit(LOADING_ERROR_EVENT, e);
throw e;
}
}
diff --git a/app/assets/javascripts/content_editor/services/create_content_editor.js b/app/assets/javascripts/content_editor/services/create_content_editor.js
index f451357e211..d9d39a387d0 100644
--- a/app/assets/javascripts/content_editor/services/create_content_editor.js
+++ b/app/assets/javascripts/content_editor/services/create_content_editor.js
@@ -1,5 +1,6 @@
import { Editor } from '@tiptap/vue-2';
import { isFunction } from 'lodash';
+import eventHubFactory from '~/helpers/event_hub_factory';
import { PROVIDE_SERIALIZER_OR_RENDERER_ERROR } from '../constants';
import Attachment from '../extensions/attachment';
import Audio from '../extensions/audio';
@@ -38,6 +39,7 @@ import Loading from '../extensions/loading';
import MathInline from '../extensions/math_inline';
import OrderedList from '../extensions/ordered_list';
import Paragraph from '../extensions/paragraph';
+import PasteMarkdown from '../extensions/paste_markdown';
import Reference from '../extensions/reference';
import Strike from '../extensions/strike';
import Subscript from '../extensions/subscript';
@@ -54,6 +56,7 @@ import Video from '../extensions/video';
import WordBreak from '../extensions/word_break';
import { ContentEditor } from './content_editor';
import createMarkdownSerializer from './markdown_serializer';
+import createMarkdownDeserializer from './markdown_deserializer';
import trackInputRulesAndShortcuts from './track_input_rules_and_shortcuts';
const createTiptapEditor = ({ extensions = [], ...options } = {}) =>
@@ -78,8 +81,10 @@ export const createContentEditor = ({
throw new Error(PROVIDE_SERIALIZER_OR_RENDERER_ERROR);
}
+ const eventHub = eventHubFactory();
+
const builtInContentEditorExtensions = [
- Attachment.configure({ uploadsPath, renderMarkdown }),
+ Attachment.configure({ uploadsPath, renderMarkdown, eventHub }),
Audio,
Blockquote,
Bold,
@@ -116,6 +121,7 @@ export const createContentEditor = ({
MathInline,
OrderedList,
Paragraph,
+ PasteMarkdown.configure({ renderMarkdown, eventHub }),
Reference,
Strike,
Subscript,
@@ -135,7 +141,8 @@ export const createContentEditor = ({
const allExtensions = [...builtInContentEditorExtensions, ...extensions];
const trackedExtensions = allExtensions.map(trackInputRulesAndShortcuts);
const tiptapEditor = createTiptapEditor({ extensions: trackedExtensions, ...tiptapOptions });
- const serializer = createMarkdownSerializer({ render: renderMarkdown, serializerConfig });
+ const serializer = createMarkdownSerializer({ serializerConfig });
+ const deserializer = createMarkdownDeserializer({ render: renderMarkdown });
- return new ContentEditor({ tiptapEditor, serializer });
+ return new ContentEditor({ tiptapEditor, serializer, eventHub, deserializer });
};
diff --git a/app/assets/javascripts/content_editor/services/markdown_deserializer.js b/app/assets/javascripts/content_editor/services/markdown_deserializer.js
new file mode 100644
index 00000000000..cd4863d8eac
--- /dev/null
+++ b/app/assets/javascripts/content_editor/services/markdown_deserializer.js
@@ -0,0 +1,33 @@
+import { DOMParser as ProseMirrorDOMParser } from 'prosemirror-model';
+
+export default ({ render }) => {
+ /**
+ * Converts a Markdown string into a ProseMirror JSONDocument based
+ * on a ProseMirror schema.
+ *
+ * @param {Object} options — The schema and content for deserialization
+ * @param {ProseMirror.Schema} params.schema A ProseMirror schema that defines
+ * the types of content supported in the document
+ * @param {String} params.content An arbitrary markdown string
+ *
+ * @returns An object with the following properties:
+ * - document: A ProseMirror document object generated from the deserialized Markdown
+ * - dom: The Markdown Deserializer renders Markdown as HTML to generate the ProseMirror
+ * document. The dom property contains the HTML generated from the Markdown Source.
+ */
+ return {
+ deserialize: async ({ schema, content }) => {
+ const html = await render(content);
+
+ if (!html) return {};
+
+ const parser = new DOMParser();
+ const { body } = parser.parseFromString(html, 'text/html');
+
+ // append original source as a comment that nodes can access
+ body.append(document.createComment(content));
+
+ return { document: ProseMirrorDOMParser.fromSchema(schema).parse(body), dom: body };
+ },
+ };
+};
diff --git a/app/assets/javascripts/content_editor/services/markdown_serializer.js b/app/assets/javascripts/content_editor/services/markdown_serializer.js
index 925b411e51c..eaaf69c3068 100644
--- a/app/assets/javascripts/content_editor/services/markdown_serializer.js
+++ b/app/assets/javascripts/content_editor/services/markdown_serializer.js
@@ -1,4 +1,3 @@
-import { DOMParser as ProseMirrorDOMParser } from 'prosemirror-model';
import {
MarkdownSerializer as ProseMirrorMarkdownSerializer,
defaultMarkdownSerializer,
@@ -237,31 +236,7 @@ const defaultSerializerConfig = {
* that parses the Markdown and converts it into HTML.
* @returns a markdown serializer
*/
-export default ({ render = () => null, serializerConfig = {} } = {}) => ({
- /**
- * Converts a Markdown string into a ProseMirror JSONDocument based
- * on a ProseMirror schema.
- * @param {ProseMirror.Schema} params.schema A ProseMirror schema that defines
- * the types of content supported in the document
- * @param {String} params.content An arbitrary markdown string
- * @returns A ProseMirror JSONDocument
- */
- deserialize: async ({ schema, content }) => {
- const html = await render(content);
-
- if (!html) return null;
-
- const parser = new DOMParser();
- const { body } = parser.parseFromString(html, 'text/html');
-
- // append original source as a comment that nodes can access
- body.append(document.createComment(content));
-
- const state = ProseMirrorDOMParser.fromSchema(schema).parse(body);
-
- return state.toJSON();
- },
-
+export default ({ serializerConfig = {} } = {}) => ({
/**
* Converts a ProseMirror JSONDocument based
* on a ProseMirror schema into Markdown
diff --git a/app/assets/javascripts/content_editor/services/markdown_sourcemap.js b/app/assets/javascripts/content_editor/services/markdown_sourcemap.js
index a1199589c9b..4285e04bbab 100644
--- a/app/assets/javascripts/content_editor/services/markdown_sourcemap.js
+++ b/app/assets/javascripts/content_editor/services/markdown_sourcemap.js
@@ -1,7 +1,9 @@
-const getFullSource = (element) => {
+import { isString } from 'lodash';
+
+export const getFullSource = (element) => {
const commentNode = element.ownerDocument.body.lastChild;
- if (commentNode.nodeName === '#comment') {
+ if (commentNode?.nodeName === '#comment' && isString(commentNode.textContent)) {
return commentNode.textContent.split('\n');
}
diff --git a/app/assets/javascripts/content_editor/services/serialization_helpers.js b/app/assets/javascripts/content_editor/services/serialization_helpers.js
index 4d5a54c0347..5fdd294aa96 100644
--- a/app/assets/javascripts/content_editor/services/serialization_helpers.js
+++ b/app/assets/javascripts/content_editor/services/serialization_helpers.js
@@ -259,11 +259,16 @@ export function renderContent(state, node, forceRenderInline) {
}
}
-export function renderHTMLNode(tagName, forceRenderInline = false) {
+export function renderHTMLNode(tagName, forceRenderContentInline = false) {
return (state, node) => {
renderTagOpen(state, tagName, node.attrs);
- renderContent(state, node, forceRenderInline);
+ renderContent(state, node, forceRenderContentInline);
renderTagClose(state, tagName, false);
+
+ if (forceRenderContentInline) {
+ state.closeBlock(node);
+ state.flushClose();
+ }
};
}
diff --git a/app/assets/javascripts/content_editor/services/upload_helpers.js b/app/assets/javascripts/content_editor/services/upload_helpers.js
index f5bf2742748..1abecb8f414 100644
--- a/app/assets/javascripts/content_editor/services/upload_helpers.js
+++ b/app/assets/javascripts/content_editor/services/upload_helpers.js
@@ -1,3 +1,4 @@
+import { VARIANT_DANGER } from '~/flash';
import axios from '~/lib/utils/axios_utils';
import { __ } from '~/locale';
import { extractFilename, readFileAsDataURL } from './utils';
@@ -49,7 +50,7 @@ export const uploadFile = async ({ uploadsPath, renderMarkdown, file }) => {
return extractAttachmentLinkUrl(rendered);
};
-const uploadImage = async ({ editor, file, uploadsPath, renderMarkdown }) => {
+const uploadImage = async ({ editor, file, uploadsPath, renderMarkdown, eventHub }) => {
const encodedSrc = await readFileAsDataURL(file);
const { view } = editor;
@@ -72,14 +73,14 @@ const uploadImage = async ({ editor, file, uploadsPath, renderMarkdown }) => {
);
} catch (e) {
editor.commands.deleteRange({ from: position, to: position + 1 });
- editor.emit('alert', {
+ eventHub.$emit('alert', {
message: __('An error occurred while uploading the image. Please try again.'),
- variant: 'danger',
+ variant: VARIANT_DANGER,
});
}
};
-const uploadAttachment = async ({ editor, file, uploadsPath, renderMarkdown }) => {
+const uploadAttachment = async ({ editor, file, uploadsPath, renderMarkdown, eventHub }) => {
await Promise.resolve();
const { view } = editor;
@@ -103,23 +104,23 @@ const uploadAttachment = async ({ editor, file, uploadsPath, renderMarkdown }) =
);
} catch (e) {
editor.commands.deleteRange({ from, to: from + 1 });
- editor.emit('alert', {
+ eventHub.$emit('alert', {
message: __('An error occurred while uploading the file. Please try again.'),
- variant: 'danger',
+ variant: VARIANT_DANGER,
});
}
};
-export const handleFileEvent = ({ editor, file, uploadsPath, renderMarkdown }) => {
+export const handleFileEvent = ({ editor, file, uploadsPath, renderMarkdown, eventHub }) => {
if (!file) return false;
if (acceptedMimes.image.includes(file?.type)) {
- uploadImage({ editor, file, uploadsPath, renderMarkdown });
+ uploadImage({ editor, file, uploadsPath, renderMarkdown, eventHub });
return true;
}
- uploadAttachment({ editor, file, uploadsPath, renderMarkdown });
+ uploadAttachment({ editor, file, uploadsPath, renderMarkdown, eventHub });
return true;
};
diff --git a/app/assets/javascripts/contributors/stores/getters.js b/app/assets/javascripts/contributors/stores/getters.js
index 45b569066f8..79f5c701fb8 100644
--- a/app/assets/javascripts/contributors/stores/getters.js
+++ b/app/assets/javascripts/contributors/stores/getters.js
@@ -7,10 +7,11 @@ export const parsedData = (state) => {
state.chartData.forEach(({ date, author_name, author_email }) => {
total[date] = total[date] ? total[date] + 1 : 1;
- const authorData = byAuthorEmail[author_email];
+ const normalizedEmail = author_email.toLowerCase();
+ const authorData = byAuthorEmail[normalizedEmail];
if (!authorData) {
- byAuthorEmail[author_email] = {
+ byAuthorEmail[normalizedEmail] = {
name: author_name,
commits: 1,
dates: {
diff --git a/app/assets/javascripts/cycle_analytics/components/limit_warning_component.vue b/app/assets/javascripts/cycle_analytics/components/limit_warning_component.vue
deleted file mode 100644
index 4c44aac4e2a..00000000000
--- a/app/assets/javascripts/cycle_analytics/components/limit_warning_component.vue
+++ /dev/null
@@ -1,33 +0,0 @@
-<script>
-import { GlIcon, GlTooltipDirective } from '@gitlab/ui';
-
-export default {
- components: {
- GlIcon,
- },
- directives: {
- GlTooltip: GlTooltipDirective,
- },
- props: {
- count: {
- type: Number,
- required: true,
- },
- },
-};
-</script>
-<template>
- <span v-if="count === 50" class="events-info float-right">
- <gl-icon
- v-gl-tooltip="{
- title: n__(
- 'Limited to showing %d event at most',
- 'Limited to showing %d events at most',
- 50,
- ),
- }"
- name="warning"
- />
- {{ n__('Showing %d event', 'Showing %d events', 50) }}
- </span>
-</template>
diff --git a/app/assets/javascripts/cycle_analytics/components/stage_table.vue b/app/assets/javascripts/cycle_analytics/components/stage_table.vue
index ea5a1291a17..6a45969fd1a 100644
--- a/app/assets/javascripts/cycle_analytics/components/stage_table.vue
+++ b/app/assets/javascripts/cycle_analytics/components/stage_table.vue
@@ -18,7 +18,7 @@ import {
PAGINATION_SORT_DIRECTION_ASC,
PAGINATION_SORT_DIRECTION_DESC,
} from '../constants';
-import TotalTime from './total_time_component.vue';
+import TotalTime from './total_time.vue';
const DEFAULT_WORKFLOW_TITLE_PROPERTIES = {
thClass: 'gl-w-half',
diff --git a/app/assets/javascripts/cycle_analytics/components/total_time_component.vue b/app/assets/javascripts/cycle_analytics/components/total_time.vue
index a5a90a56974..a5a90a56974 100644
--- a/app/assets/javascripts/cycle_analytics/components/total_time_component.vue
+++ b/app/assets/javascripts/cycle_analytics/components/total_time.vue
diff --git a/app/assets/javascripts/cycle_analytics/components/value_stream_filters.vue b/app/assets/javascripts/cycle_analytics/components/value_stream_filters.vue
index 64461797c46..66bccf19496 100644
--- a/app/assets/javascripts/cycle_analytics/components/value_stream_filters.vue
+++ b/app/assets/javascripts/cycle_analytics/components/value_stream_filters.vue
@@ -1,16 +1,28 @@
<script>
+import { GlIcon, GlToggle, GlTooltipDirective } from '@gitlab/ui';
+import { s__ } from '~/locale';
import DateRange from '~/analytics/shared/components/daterange.vue';
import ProjectsDropdownFilter from '~/analytics/shared/components/projects_dropdown_filter.vue';
import { DATE_RANGE_LIMIT, PROJECTS_PER_PAGE } from '~/analytics/shared/constants';
import FilterBar from './filter_bar.vue';
+export const AGGREGATION_TOGGLE_LABEL = s__('CycleAnalytics|Filter by stop date');
+export const AGGREGATION_DESCRIPTION = s__(
+ 'CycleAnalytics|When enabled, the results show items with a stop event within the date range. When disabled, the results show items with a start event within the date range.',
+);
+
export default {
name: 'ValueStreamFilters',
components: {
+ GlIcon,
+ GlToggle,
DateRange,
ProjectsDropdownFilter,
FilterBar,
},
+ directives: {
+ GlTooltip: GlTooltipDirective,
+ },
props: {
selectedProjects: {
type: Array,
@@ -45,6 +57,21 @@ export default {
required: false,
default: null,
},
+ canToggleAggregation: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
+ isAggregationEnabled: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
+ isUpdatingAggregationData: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
},
computed: {
projectsQueryParams() {
@@ -54,8 +81,19 @@ export default {
};
},
},
+ methods: {
+ onUpdateAggregation(ev) {
+ if (!this.isUpdatingAggregationData) {
+ this.$emit('toggleAggregation', ev);
+ }
+ },
+ },
multiProjectSelect: true,
maxDateRange: DATE_RANGE_LIMIT,
+ i18n: {
+ AGGREGATION_TOGGLE_LABEL,
+ AGGREGATION_DESCRIPTION,
+ },
};
</script>
<template>
@@ -84,7 +122,28 @@ export default {
@selected="$emit('selectProject', $event)"
/>
</div>
- <div>
+ <div class="gl-display-flex gl-flex-direction-column gl-lg-flex-direction-row">
+ <div
+ v-if="canToggleAggregation"
+ class="gl-display-flex gl-text-align-center gl-my-2 gl-lg-mt-0 gl-lg-mb-0 gl-mr-5"
+ >
+ <gl-toggle
+ class="gl-flex-direction-row"
+ :value="isAggregationEnabled"
+ :label="$options.i18n.AGGREGATION_TOGGLE_LABEL"
+ :disabled="isUpdatingAggregationData"
+ label-position="left"
+ @change="onUpdateAggregation"
+ >
+ <template #label>
+ {{ $options.i18n.AGGREGATION_TOGGLE_LABEL }}&nbsp;<gl-icon
+ v-gl-tooltip.hover
+ :title="$options.i18n.AGGREGATION_DESCRIPTION"
+ name="information-o"
+ />
+ </template>
+ </gl-toggle>
+ </div>
<date-range
v-if="hasDateRangeFilter"
:start-date="startDate"
diff --git a/app/assets/javascripts/deploy_tokens/components/revoke_button.vue b/app/assets/javascripts/deploy_tokens/components/revoke_button.vue
index fdf8b7796bf..7879357a042 100644
--- a/app/assets/javascripts/deploy_tokens/components/revoke_button.vue
+++ b/app/assets/javascripts/deploy_tokens/components/revoke_button.vue
@@ -17,9 +17,6 @@ export default {
revokePath: {
default: '',
},
- buttonClass: {
- default: '',
- },
},
computed: {
modalId() {
@@ -38,10 +35,9 @@ export default {
<div>
<gl-button
v-gl-modal="modalId"
- :class="buttonClass"
category="primary"
variant="danger"
- class="float-right"
+ class="gl-float-right"
data-testid="revoke-button"
>{{ s__('DeployTokens|Revoke') }}</gl-button
>
diff --git a/app/assets/javascripts/deploy_tokens/init_revoke_button.js b/app/assets/javascripts/deploy_tokens/init_revoke_button.js
index 20187150a60..bc3f3c9ddf4 100644
--- a/app/assets/javascripts/deploy_tokens/init_revoke_button.js
+++ b/app/assets/javascripts/deploy_tokens/init_revoke_button.js
@@ -9,14 +9,13 @@ export default () => {
}
return containers.forEach((el) => {
- const { token, revokePath, buttonClass } = el.dataset;
+ const { token, revokePath } = el.dataset;
return new Vue({
el,
provide: {
token: JSON.parse(token),
revokePath,
- buttonClass,
},
render(h) {
return h(RevokeButton);
diff --git a/app/assets/javascripts/deprecated_notes.js b/app/assets/javascripts/deprecated_notes.js
index 82bbbe891e2..0707ae02872 100644
--- a/app/assets/javascripts/deprecated_notes.js
+++ b/app/assets/javascripts/deprecated_notes.js
@@ -1,6 +1,6 @@
/* eslint-disable no-restricted-properties, babel/camelcase,
no-unused-expressions, default-case,
-consistent-return, no-alert, no-param-reassign,
+consistent-return, no-param-reassign,
no-shadow, no-useless-escape,
class-methods-use-this */
@@ -17,9 +17,11 @@ import { escape, uniqueId } from 'lodash';
import Vue from 'vue';
import '~/lib/utils/jquery_at_who';
import AjaxCache from '~/lib/utils/ajax_cache';
+import { loadingIconForLegacyJS } from '~/loading_icon_for_legacy_js';
import syntaxHighlight from '~/syntax_highlight';
import CommentTypeDropdown from '~/notes/components/comment_type_dropdown.vue';
import * as constants from '~/notes/constants';
+import { confirmAction } from '~/lib/utils/confirm_via_gl_modal/confirm_via_gl_modal';
import Autosave from './autosave';
import loadAwardsHandler from './awards_handler';
import createFlash from './flash';
@@ -243,7 +245,7 @@ export default class Notes {
});
}
- keydownNoteText(e) {
+ async keydownNoteText(e) {
let discussionNoteForm;
let editNote;
let myLastNote;
@@ -276,9 +278,11 @@ export default class Notes {
discussionNoteForm = $textarea.closest('.js-discussion-note-form');
if (discussionNoteForm.length) {
if ($textarea.val() !== '') {
- if (!window.confirm(__('Your comment will be discarded.'))) {
- return;
- }
+ const confirmed = await confirmAction(__('Your comment will be discarded.'), {
+ primaryBtnVariant: 'danger',
+ primaryBtnText: __('Discard'),
+ });
+ if (!confirmed) return;
}
this.removeDiscussionNoteForm(discussionNoteForm);
return;
@@ -288,9 +292,14 @@ export default class Notes {
originalText = $textarea.closest('form').data('originalNote');
newText = $textarea.val();
if (originalText !== newText) {
- if (!window.confirm(__('Are you sure you want to discard this comment?'))) {
- return;
- }
+ const confirmed = await confirmAction(
+ __('Are you sure you want to discard this comment?'),
+ {
+ primaryBtnVariant: 'danger',
+ primaryBtnText: __('Discard'),
+ },
+ );
+ if (!confirmed) return;
}
return this.removeNoteEditForm(editNote);
}
@@ -1753,9 +1762,11 @@ export default class Notes {
// Show updated comment content temporarily
$noteBodyText.html(formContent);
$editingNote.removeClass('is-editing fade-in-full').addClass('being-posted fade-in-half');
- $editingNote
- .find('.note-headline-meta a')
- .html('<span class="spinner align-text-bottom"></span>');
+
+ const $timeAgo = $editingNote.find('.note-headline-meta a');
+
+ $timeAgo.empty();
+ $timeAgo.append(loadingIconForLegacyJS({ inline: true, size: 'sm' }));
// Make request to update comment on server
axios
diff --git a/app/assets/javascripts/diff.js b/app/assets/javascripts/diff.js
index 14d6e2db09d..a12829f8420 100644
--- a/app/assets/javascripts/diff.js
+++ b/app/assets/javascripts/diff.js
@@ -1,4 +1,5 @@
import $ from 'jquery';
+import { merge } from 'lodash';
import createFlash from '~/flash';
import axios from '~/lib/utils/axios_utils';
import { __ } from '~/locale';
@@ -41,6 +42,8 @@ export default class Diff {
}
this.openAnchoredDiff();
+
+ this.prepareRenderedDiff();
}
handleClickUnfold(e) {
@@ -150,4 +153,43 @@ export default class Diff {
.addClass('hll');
}
}
+
+ prepareRenderedDiff() {
+ const $elements = $('[data-diff-toggle-entity]');
+
+ if ($elements.length === 0) return;
+
+ const diff = this;
+
+ const elements = $elements.toArray().map(this.formatElementToObject).reduce(merge);
+
+ Object.values(elements).forEach((e) => {
+ e.toShowBtn.onclick = () => diff.showOneHideAnother('rendered', e); // eslint-disable-line no-param-reassign
+ e.toHideBtn.onclick = () => diff.showOneHideAnother('raw', e); // eslint-disable-line no-param-reassign
+
+ diff.showOneHideAnother('rendered', e);
+ });
+ }
+
+ formatElementToObject = (element) => {
+ const key = element.attributes['data-file-hash'].value;
+ const name = element.attributes['data-diff-toggle-entity'].value;
+
+ return { [key]: { [name]: element } };
+ };
+
+ showOneHideAnother = (mode, elements) => {
+ let { toShowBtn, toHideBtn, toShow, toHide } = elements;
+
+ if (mode === 'raw') {
+ [toShowBtn, toHideBtn] = [toHideBtn, toShowBtn];
+ [toShow, toHide] = [toHide, toShow];
+ }
+
+ toShowBtn.classList.add('selected');
+ toHideBtn.classList.remove('selected');
+
+ toHide.classList.add('hidden');
+ toShow.classList.remove('hidden');
+ };
}
diff --git a/app/assets/javascripts/diffs/components/commit_item.vue b/app/assets/javascripts/diffs/components/commit_item.vue
index df7cf83b3f0..ba10f6deb29 100644
--- a/app/assets/javascripts/diffs/components/commit_item.vue
+++ b/app/assets/javascripts/diffs/components/commit_item.vue
@@ -72,8 +72,6 @@ export default {
return this.author.id ? this.author.id : '';
},
authorUrl() {
- // name: 'mailto:' is a false positive: https://gitlab.com/gitlab-org/frontend/eslint-plugin-i18n/issues/26#possible-false-positives
- // eslint-disable-next-line @gitlab/require-i18n-strings
return this.author.web_url || `mailto:${this.commit.author_email}`;
},
authorAvatar() {
diff --git a/app/assets/javascripts/diffs/components/diff_content.vue b/app/assets/javascripts/diffs/components/diff_content.vue
index 858d9e221ae..7ed5713ebfa 100644
--- a/app/assets/javascripts/diffs/components/diff_content.vue
+++ b/app/assets/javascripts/diffs/components/diff_content.vue
@@ -163,8 +163,8 @@ export default {
v-if="diffFile.discussions.length"
class="diff-file-discussions"
:discussions="diffFile.discussions"
- :should-collapse-discussions="true"
- :render-avatar-badge="true"
+ should-collapse-discussions
+ render-avatar-badge
/>
<diff-file-drafts :file-hash="diffFileHash" class="diff-file-discussions" />
<note-form
diff --git a/app/assets/javascripts/diffs/components/diff_file_header.vue b/app/assets/javascripts/diffs/components/diff_file_header.vue
index 3cf1f69b08c..495c87a695c 100644
--- a/app/assets/javascripts/diffs/components/diff_file_header.vue
+++ b/app/assets/javascripts/diffs/components/diff_file_header.vue
@@ -431,7 +431,7 @@ export default {
class="js-ide-edit-blob"
data-qa-selector="edit_in_ide_button"
>
- {{ __('Edit in Web IDE') }}
+ {{ __('Open in Web IDE') }}
</gl-dropdown-item>
</template>
diff --git a/app/assets/javascripts/diffs/components/diff_view.vue b/app/assets/javascripts/diffs/components/diff_view.vue
index 333bf1b356c..f46b0a538f1 100644
--- a/app/assets/javascripts/diffs/components/diff_view.vue
+++ b/app/assets/javascripts/diffs/components/diff_view.vue
@@ -1,4 +1,5 @@
<script>
+import { GlSafeHtmlDirective as SafeHtml } from '@gitlab/ui';
import { mapGetters, mapState, mapActions } from 'vuex';
import { IdState } from 'vendor/vue-virtual-scroller';
import DraftNote from '~/batch_comments/components/draft_note.vue';
@@ -19,6 +20,9 @@ export default {
DiffCommentCell,
DraftNote,
},
+ directives: {
+ SafeHtml,
+ },
mixins: [
draftCommentsMixin,
glFeatureFlagsMixin(),
@@ -173,15 +177,17 @@ export default {
<div class="diff-grid-left diff-grid-3-col left-side">
<div class="diff-td diff-line-num"></div>
<div v-if="inline" class="diff-td diff-line-num"></div>
- <div class="diff-td line_content left-side gl-white-space-normal!">
- {{ line.left.rich_text }}
- </div>
+ <div
+ v-safe-html="line.left.rich_text"
+ class="diff-td line_content left-side gl-white-space-normal!"
+ ></div>
</div>
<div v-if="!inline" class="diff-grid-right diff-grid-3-col right-side">
<div class="diff-td diff-line-num"></div>
- <div class="diff-td line_content right-side gl-white-space-normal!">
- {{ line.left.rich_text }}
- </div>
+ <div
+ v-safe-html="line.left.rich_text"
+ class="diff-td line_content right-side gl-white-space-normal!"
+ ></div>
</div>
</div>
</template>
diff --git a/app/assets/javascripts/diffs/components/hidden_files_warning.vue b/app/assets/javascripts/diffs/components/hidden_files_warning.vue
index baf7471582a..b9962682848 100644
--- a/app/assets/javascripts/diffs/components/hidden_files_warning.vue
+++ b/app/assets/javascripts/diffs/components/hidden_files_warning.vue
@@ -1,6 +1,19 @@
<script>
-/* eslint-disable @gitlab/vue-require-i18n-strings */
+import { GlAlert, GlSprintf } from '@gitlab/ui';
+import { __ } from '~/locale';
+
+export const i18n = {
+ title: __('Too many changes to show.'),
+ plainDiff: __('Plain diff'),
+ emailPatch: __('Email patch'),
+};
+
export default {
+ i18n,
+ components: {
+ GlAlert,
+ GlSprintf,
+ },
props: {
total: {
type: String,
@@ -23,17 +36,28 @@ export default {
</script>
<template>
- <div class="alert alert-warning">
- <h4>
- {{ __('Too many changes to show.') }}
- <div class="float-right">
- <a :href="plainDiffPath" class="btn btn-sm"> {{ __('Plain diff') }} </a>
- <a :href="emailPatchPath" class="btn btn-sm"> {{ __('Email patch') }} </a>
- </div>
- </h4>
- <p>
- To preserve performance only <strong> {{ visible }} of {{ total }} </strong> files are
- displayed.
- </p>
- </div>
+ <gl-alert
+ variant="warning"
+ :title="$options.i18n.title"
+ :primary-button-text="$options.i18n.plainDiff"
+ :primary-button-link="plainDiffPath"
+ :secondary-button-text="$options.i18n.emailPatch"
+ :secondary-button-link="emailPatchPath"
+ :dismissible="false"
+ >
+ <gl-sprintf
+ :message="
+ sprintf(
+ __(
+ 'To preserve performance only %{strongStart}%{visible} of %{total}%{strongEnd} files are displayed.',
+ ),
+ { visible, total },
+ )
+ "
+ >
+ <template #strong="{ content }">
+ <strong>{{ content }}</strong>
+ </template>
+ </gl-sprintf>
+ </gl-alert>
</template>
diff --git a/app/assets/javascripts/diffs/store/getters_versions_dropdowns.js b/app/assets/javascripts/diffs/store/getters_versions_dropdowns.js
index 65ffd42fa27..734407dec45 100644
--- a/app/assets/javascripts/diffs/store/getters_versions_dropdowns.js
+++ b/app/assets/javascripts/diffs/store/getters_versions_dropdowns.js
@@ -15,24 +15,19 @@ export const diffCompareDropdownTargetVersions = (state, getters) => {
// startVersion only exists if the user has selected a version other
// than "base" so if startVersion is null then base must be selected
- const defaultMergeRefForDiffs = window.gon?.features?.defaultMergeRefForDiffs || false;
const diffHeadParam = getParameterByName('diff_head');
- const diffHead = parseBoolean(diffHeadParam) || (!diffHeadParam && defaultMergeRefForDiffs);
- const isBaseSelected = !state.startVersion && !diffHead;
+ const diffHead = parseBoolean(diffHeadParam) || !diffHeadParam;
+ const isBaseSelected = !state.startVersion;
const isHeadSelected = !state.startVersion && diffHead;
let baseVersion = null;
- if (
- !defaultMergeRefForDiffs ||
- (defaultMergeRefForDiffs && !state.mergeRequestDiff.head_version_path)
- ) {
+ if (!state.mergeRequestDiff.head_version_path) {
baseVersion = {
versionName: state.targetBranchName,
version_index: DIFF_COMPARE_BASE_VERSION_INDEX,
href: state.mergeRequestDiff.base_version_path,
isBase: true,
- selected:
- isBaseSelected || (defaultMergeRefForDiffs && !state.mergeRequestDiff.head_version_path),
+ selected: isBaseSelected,
};
}
diff --git a/app/assets/javascripts/dirty_submit/dirty_submit_form.js b/app/assets/javascripts/dirty_submit/dirty_submit_form.js
index db13daf0799..83dd4b0a124 100644
--- a/app/assets/javascripts/dirty_submit/dirty_submit_form.js
+++ b/app/assets/javascripts/dirty_submit/dirty_submit_form.js
@@ -1,11 +1,13 @@
import $ from 'jquery';
import { memoize, throttle } from 'lodash';
+import createEventHub from '~/helpers/event_hub_factory';
class DirtySubmitForm {
constructor(form) {
this.form = form;
this.dirtyInputs = [];
this.isDisabled = true;
+ this.events = createEventHub();
this.init();
}
@@ -36,11 +38,21 @@ class DirtySubmitForm {
this.form.addEventListener('submit', (event) => this.formSubmit(event));
}
+ addInputsListener(callback) {
+ this.events.$on('input', callback);
+ }
+
+ removeInputsListener(callback) {
+ this.events.$off('input', callback);
+ }
+
updateDirtyInput(event) {
const { target } = event;
if (!target.dataset.isDirtySubmitInput) return;
+ this.events.$emit('input', event);
+
this.updateDirtyInputs(target);
this.toggleSubmission();
}
diff --git a/app/assets/javascripts/editor/extensions/source_editor_ci_schema_ext.js b/app/assets/javascripts/editor/extensions/source_editor_ci_schema_ext.js
index 0290bb84b5f..b41eae88c54 100644
--- a/app/assets/javascripts/editor/extensions/source_editor_ci_schema_ext.js
+++ b/app/assets/javascripts/editor/extensions/source_editor_ci_schema_ext.js
@@ -14,7 +14,7 @@ export class CiSchemaExtension {
// to fetch schema files, hence the `gon.gitlab_url`
// reference. This prevents error:
// "Failed to execute 'fetch' on 'WorkerGlobalScope'"
- const absoluteSchemaUrl = gon.gitlab_url + ciSchemaPath;
+ const absoluteSchemaUrl = new URL(ciSchemaPath, gon.gitlab_url).href;
const modelFileName = instance.getModel().uri.path.split('/').pop();
registerSchema({
diff --git a/app/assets/javascripts/editor/schema/ci.json b/app/assets/javascripts/editor/schema/ci.json
index 4d9fe6ff851..1c56327c03c 100644
--- a/app/assets/javascripts/editor/schema/ci.json
+++ b/app/assets/javascripts/editor/schema/ci.json
@@ -423,37 +423,34 @@
"description": "Defines secrets to be injected as environment variables",
"additionalProperties": {
"type": "object",
- "additionalProperties": {
- "type": "object",
- "description": "Environment variable name",
- "properties": {
- "vault": {
- "oneOf": [
- {
- "type": "string",
- "description": "The secret to be fetched from Vault (e.g. 'production/db/password@ops' translates to secret 'ops/data/production/db', field `password`)"
- },
- {
- "type": "object",
- "properties": {
- "engine": {
- "type": "object",
- "properties": {
- "name": { "type": "string" },
- "path": { "type": "string" }
- },
- "required": ["name", "path"]
+ "description": "Environment variable name",
+ "properties": {
+ "vault": {
+ "oneOf": [
+ {
+ "type": "string",
+ "description": "The secret to be fetched from Vault (e.g. 'production/db/password@ops' translates to secret 'ops/data/production/db', field `password`)"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "engine": {
+ "type": "object",
+ "properties": {
+ "name": { "type": "string" },
+ "path": { "type": "string" }
},
- "path": { "type": "string" },
- "field": { "type": "string" }
+ "required": ["name", "path"]
},
- "required": ["engine", "path", "field"]
- }
- ]
- }
- },
- "required": ["vault"]
- }
+ "path": { "type": "string" },
+ "field": { "type": "string" }
+ },
+ "required": ["engine", "path", "field"]
+ }
+ ]
+ }
+ },
+ "required": ["vault"]
}
},
"before_script": {
@@ -1250,7 +1247,7 @@
"oneOf": [
{
"type": "object",
- "description": "Trigger a multi-project pipeline. Read more: https://docs.gitlab.com/ee/ci/yaml/README.html#simple-trigger-syntax-for-multi-project-pipelines",
+ "description": "Trigger a multi-project pipeline. Read more: https://docs.gitlab.com/ee/ci/pipelines/multi_project_pipelines.html#specify-a-downstream-pipeline-branch",
"additionalProperties": false,
"properties": {
"project": {
@@ -1266,6 +1263,23 @@
"description": "You can mirror the pipeline status from the triggered pipeline to the source bridge job by using strategy: depend",
"type": "string",
"enum": ["depend"]
+ },
+ "forward": {
+ "description": "Specify what to forward to the downstream pipeline.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "yaml_variables": {
+ "type": "boolean",
+ "description": "Variables defined in the trigger job are passed to downstream pipelines.",
+ "default": true
+ },
+ "pipeline_variables": {
+ "type": "boolean",
+ "description": "Variables added for manual pipeline runs are passed to downstream pipelines.",
+ "default": false
+ }
+ }
}
},
"required": ["project"],
@@ -1275,7 +1289,7 @@
},
{
"type": "object",
- "description": "Trigger a child pipeline. Read more: https://docs.gitlab.com/ee/ci/yaml/README.html#trigger-syntax-for-child-pipeline",
+ "description": "Trigger a child pipeline. Read more: https://docs.gitlab.com/ee/ci/pipelines/parent_child_pipelines.html",
"additionalProperties": false,
"properties": {
"include": {
@@ -1365,11 +1379,28 @@
"description": "You can mirror the pipeline status from the triggered pipeline to the source bridge job by using strategy: depend",
"type": "string",
"enum": ["depend"]
+ },
+ "forward": {
+ "description": "Specify what to forward to the downstream pipeline.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "yaml_variables": {
+ "type": "boolean",
+ "description": "Variables defined in the trigger job are passed to downstream pipelines.",
+ "default": true
+ },
+ "pipeline_variables": {
+ "type": "boolean",
+ "description": "Variables added for manual pipeline runs are passed to downstream pipelines.",
+ "default": false
+ }
+ }
}
}
},
{
- "description": "Path to the project, e.g. `group/project`, or `group/sub-group/project`.",
+ "description": "Path to the project, e.g. `group/project`, or `group/sub-group/project`. Read more: https://docs.gitlab.com/ee/ci/pipelines/multi_project_pipelines.html#define-multi-project-pipelines-in-your-gitlab-ciyml-file",
"type": "string",
"pattern": "\\S/\\S"
}
diff --git a/app/assets/javascripts/emoji/components/picker.vue b/app/assets/javascripts/emoji/components/picker.vue
index 686b5ffff9e..840297b870a 100644
--- a/app/assets/javascripts/emoji/components/picker.vue
+++ b/app/assets/javascripts/emoji/components/picker.vue
@@ -108,6 +108,7 @@ export default {
class="gl-mx-5! gl-mb-2!"
autofocus
debounce="500"
+ :aria-label="__('Search for an emoji')"
@input="onSearchInput"
/>
<div
diff --git a/app/assets/javascripts/environments/components/commit.vue b/app/assets/javascripts/environments/components/commit.vue
index 54b94480685..8577bf629a3 100644
--- a/app/assets/javascripts/environments/components/commit.vue
+++ b/app/assets/javascripts/environments/components/commit.vue
@@ -22,7 +22,6 @@ export default {
return this.commit?.message;
},
commitAuthorPath() {
- // eslint-disable-next-line @gitlab/require-i18n-strings
return this.commit?.author?.path || `mailto:${escape(this.commit?.authorEmail)}`;
},
commitAuthorAvatar() {
diff --git a/app/assets/javascripts/environments/components/delete_environment_modal.vue b/app/assets/javascripts/environments/components/delete_environment_modal.vue
index d3d4c7d23d8..3173c2bd644 100644
--- a/app/assets/javascripts/environments/components/delete_environment_modal.vue
+++ b/app/assets/javascripts/environments/components/delete_environment_modal.vue
@@ -62,7 +62,8 @@ export default {
mutation: deleteEnvironmentMutation,
variables: { environment: this.environment },
})
- .then(([message]) => {
+ .then(({ data }) => {
+ const [message] = data?.deleteEvironment?.errors ?? [];
if (message) {
createFlash({ message });
}
diff --git a/app/assets/javascripts/environments/components/deployment.vue b/app/assets/javascripts/environments/components/deployment.vue
index f98edb6bb7d..19284b26d51 100644
--- a/app/assets/javascripts/environments/components/deployment.vue
+++ b/app/assets/javascripts/environments/components/deployment.vue
@@ -102,6 +102,9 @@ export default {
refPath() {
return this.ref?.refPath;
},
+ needsApproval() {
+ return this.deployment.pendingApprovalCount > 0;
+ },
},
methods: {
toggleCollapse() {
@@ -116,6 +119,7 @@ export default {
showDetails: __('Show details'),
hideDetails: __('Hide details'),
triggerer: s__('Deployment|Triggerer'),
+ needsApproval: s__('Deployment|Needs Approval'),
job: __('Job'),
api: __('API'),
branch: __('Branch'),
@@ -153,6 +157,9 @@ export default {
<div :class="$options.headerDetailsClasses">
<div :class="$options.deploymentStatusClasses">
<deployment-status-badge v-if="status" :status="status" />
+ <gl-badge v-if="needsApproval" variant="warning">
+ {{ $options.i18n.needsApproval }}
+ </gl-badge>
<gl-badge v-if="latest" variant="info">{{ $options.i18n.latestBadge }}</gl-badge>
</div>
<div class="gl-display-flex gl-align-items-center gl-gap-x-5">
@@ -199,6 +206,7 @@ export default {
</gl-button>
</div>
<commit v-if="commit" :commit="commit" class="gl-mt-3" />
+ <div class="gl-mt-3"><slot name="approval"></slot></div>
<gl-collapse :visible="visible">
<div
class="gl-display-flex gl-md-align-items-center gl-mt-5 gl-flex-direction-column gl-md-flex-direction-row gl-pr-4 gl-md-pr-0"
diff --git a/app/assets/javascripts/environments/components/enable_review_app_modal.vue b/app/assets/javascripts/environments/components/enable_review_app_modal.vue
index b757c55bfdb..4d43ee156fb 100644
--- a/app/assets/javascripts/environments/components/enable_review_app_modal.vue
+++ b/app/assets/javascripts/environments/components/enable_review_app_modal.vue
@@ -1,5 +1,6 @@
<script>
import { GlLink, GlModal, GlSprintf } from '@gitlab/ui';
+import { uniqueId } from 'lodash';
import { helpPagePath } from '~/helpers/help_page_helper';
import { s__ } from '~/locale';
import ModalCopyButton from '~/vue_shared/components/modal_copy_button.vue';
@@ -44,6 +45,11 @@ export default {
copyToClipboardText: s__('EnableReviewApp|Copy snippet text'),
title: s__('ReviewApp|Enable Review App'),
},
+ data() {
+ const modalInfoCopyId = uniqueId('enable-review-app-copy-string-');
+
+ return { modalInfoCopyId };
+ },
computed: {
modalInfoCopyStr() {
return `deploy_review:
@@ -99,14 +105,14 @@ export default {
</gl-sprintf>
</p>
<div class="gl-display-flex align-items-start">
- <pre class="gl-w-full" data-testid="enable-review-app-copy-string">
+ <pre :id="modalInfoCopyId" class="gl-w-full" data-testid="enable-review-app-copy-string">
{{ modalInfoCopyStr }} </pre
>
<modal-copy-button
:title="$options.modalInfo.copyToClipboardText"
- :text="$options.modalInfo.copyString"
:modal-id="modalId"
css-classes="border-0"
+ :target="`#${modalInfoCopyId}`"
/>
</div>
</div>
diff --git a/app/assets/javascripts/environments/components/environment_actions.vue b/app/assets/javascripts/environments/components/environment_actions.vue
index 98c95507168..c7e024aadec 100644
--- a/app/assets/javascripts/environments/components/environment_actions.vue
+++ b/app/assets/javascripts/environments/components/environment_actions.vue
@@ -1,5 +1,6 @@
<script>
import { GlDropdown, GlDropdownItem, GlIcon, GlTooltipDirective } from '@gitlab/ui';
+import { confirmAction } from '~/lib/utils/confirm_via_gl_modal/confirm_via_gl_modal';
import { formatTime } from '~/lib/utils/datetime_utility';
import { __, s__, sprintf } from '~/locale';
import eventHub from '../event_hub';
@@ -37,7 +38,7 @@ export default {
},
},
methods: {
- onClickAction(action) {
+ async onClickAction(action) {
if (action.scheduledAt) {
const confirmationMessage = sprintf(
s__(
@@ -45,9 +46,10 @@ export default {
),
{ jobName: action.name },
);
- // https://gitlab.com/gitlab-org/gitlab-foss/issues/52156
- // eslint-disable-next-line no-alert
- if (!window.confirm(confirmationMessage)) {
+
+ const confirmed = await confirmAction(confirmationMessage);
+
+ if (!confirmed) {
return;
}
}
diff --git a/app/assets/javascripts/environments/components/environment_folder.vue b/app/assets/javascripts/environments/components/environment_folder.vue
new file mode 100644
index 00000000000..d5c6d26cfd0
--- /dev/null
+++ b/app/assets/javascripts/environments/components/environment_folder.vue
@@ -0,0 +1,115 @@
+<script>
+import { GlButton, GlCollapse, GlIcon, GlBadge, GlLink } from '@gitlab/ui';
+import { __, s__ } from '~/locale';
+import pollIntervalQuery from '../graphql/queries/poll_interval.query.graphql';
+import folderQuery from '../graphql/queries/folder.query.graphql';
+import { ENVIRONMENT_COUNT_BY_SCOPE } from '../constants';
+import EnvironmentItem from './new_environment_item.vue';
+
+export default {
+ components: {
+ EnvironmentItem,
+ GlButton,
+ GlCollapse,
+ GlIcon,
+ GlBadge,
+ GlLink,
+ },
+ props: {
+ nestedEnvironment: {
+ type: Object,
+ required: true,
+ },
+ scope: {
+ type: String,
+ required: true,
+ },
+ },
+ data() {
+ return { visible: false, interval: undefined };
+ },
+ apollo: {
+ folder: {
+ query: folderQuery,
+ variables() {
+ return { environment: this.nestedEnvironment.latest, scope: this.scope };
+ },
+ pollInterval() {
+ return this.interval;
+ },
+ },
+ interval: {
+ query: pollIntervalQuery,
+ },
+ },
+ i18n: {
+ collapse: __('Collapse'),
+ expand: __('Expand'),
+ link: s__('Environments|Show all'),
+ },
+ computed: {
+ icons() {
+ return this.visible
+ ? { caret: 'angle-down', folder: 'folder-open' }
+ : { caret: 'angle-right', folder: 'folder-o' };
+ },
+ label() {
+ return this.visible ? this.$options.i18n.collapse : this.$options.i18n.expand;
+ },
+ count() {
+ const count = ENVIRONMENT_COUNT_BY_SCOPE[this.scope];
+ return this.folder?.[count] ?? 0;
+ },
+ folderClass() {
+ return { 'gl-font-weight-bold': this.visible };
+ },
+ folderPath() {
+ return this.nestedEnvironment.latest.folderPath;
+ },
+ environments() {
+ return this.folder?.environments;
+ },
+ },
+ methods: {
+ toggleCollapse() {
+ this.visible = !this.visible;
+ },
+ isFirstEnvironment(index) {
+ return index === 0;
+ },
+ },
+};
+</script>
+<template>
+ <div
+ :class="{ 'gl-pb-5': !visible }"
+ class="gl-border-b-solid gl-border-gray-100 gl-border-1 gl-pt-3"
+ >
+ <div class="gl-w-full gl-display-flex gl-align-items-center gl-px-3">
+ <gl-button
+ class="gl-mr-4 gl-fill-current-color gl-text-gray-500"
+ :aria-label="label"
+ :icon="icons.caret"
+ size="small"
+ category="tertiary"
+ @click="toggleCollapse"
+ />
+ <gl-icon class="gl-mr-2 gl-fill-current-color gl-text-gray-500" :name="icons.folder" />
+ <div class="gl-mr-2 gl-text-gray-500" :class="folderClass">
+ {{ nestedEnvironment.name }}
+ </div>
+ <gl-badge size="sm" class="gl-mr-auto">{{ count }}</gl-badge>
+ <gl-link v-if="visible" :href="folderPath">{{ $options.i18n.link }}</gl-link>
+ </div>
+ <gl-collapse :visible="visible">
+ <environment-item
+ v-for="(environment, index) in environments"
+ :key="environment.name"
+ :environment="environment"
+ :class="{ 'gl-mt-5': isFirstEnvironment(index) }"
+ class="gl-border-gray-100 gl-border-t-solid gl-border-1 gl-pt-3"
+ in-folder
+ />
+ </gl-collapse>
+ </div>
+</template>
diff --git a/app/assets/javascripts/environments/components/environments_app.vue b/app/assets/javascripts/environments/components/environments_app.vue
index acc16ecd874..c7008c03099 100644
--- a/app/assets/javascripts/environments/components/environments_app.vue
+++ b/app/assets/javascripts/environments/components/environments_app.vue
@@ -1,188 +1,272 @@
<script>
-import { GlBadge, GlButton, GlModalDirective, GlTab, GlTabs } from '@gitlab/ui';
-import createFlash from '~/flash';
-import { s__ } from '~/locale';
-import eventHub from '../event_hub';
-import environmentsMixin from '../mixins/environments_mixin';
-import EnvironmentsPaginationApiMixin from '../mixins/environments_pagination_api_mixin';
-import ConfirmRollbackModal from './confirm_rollback_modal.vue';
-import DeleteEnvironmentModal from './delete_environment_modal.vue';
-import emptyState from './empty_state.vue';
+import { GlBadge, GlPagination, GlTab, GlTabs } from '@gitlab/ui';
+import { s__, __, sprintf } from '~/locale';
+import { updateHistory, setUrlParams, queryToObject } from '~/lib/utils/url_utility';
+import environmentAppQuery from '../graphql/queries/environment_app.query.graphql';
+import pollIntervalQuery from '../graphql/queries/poll_interval.query.graphql';
+import pageInfoQuery from '../graphql/queries/page_info.query.graphql';
+import environmentToDeleteQuery from '../graphql/queries/environment_to_delete.query.graphql';
+import environmentToRollbackQuery from '../graphql/queries/environment_to_rollback.query.graphql';
+import environmentToStopQuery from '../graphql/queries/environment_to_stop.query.graphql';
+import environmentToChangeCanaryQuery from '../graphql/queries/environment_to_change_canary.query.graphql';
+import { ENVIRONMENTS_SCOPE } from '../constants';
+import EnvironmentFolder from './environment_folder.vue';
import EnableReviewAppModal from './enable_review_app_modal.vue';
import StopEnvironmentModal from './stop_environment_modal.vue';
+import EnvironmentItem from './new_environment_item.vue';
+import ConfirmRollbackModal from './confirm_rollback_modal.vue';
+import DeleteEnvironmentModal from './delete_environment_modal.vue';
+import CanaryUpdateModal from './canary_update_modal.vue';
+import EmptyState from './empty_state.vue';
export default {
- i18n: {
- newEnvironmentButtonLabel: s__('Environments|New environment'),
- reviewAppButtonLabel: s__('Environments|Enable review app'),
- },
- modal: {
- id: 'enable-review-app-info',
- },
components: {
+ DeleteEnvironmentModal,
+ CanaryUpdateModal,
ConfirmRollbackModal,
- emptyState,
+ EmptyState,
+ EnvironmentFolder,
EnableReviewAppModal,
+ EnvironmentItem,
+ StopEnvironmentModal,
GlBadge,
- GlButton,
+ GlPagination,
GlTab,
GlTabs,
- StopEnvironmentModal,
- DeleteEnvironmentModal,
},
- directives: {
- 'gl-modal': GlModalDirective,
- },
- mixins: [EnvironmentsPaginationApiMixin, environmentsMixin],
- props: {
- endpoint: {
- type: String,
- required: true,
+ apollo: {
+ environmentApp: {
+ query: environmentAppQuery,
+ variables() {
+ return {
+ scope: this.scope,
+ page: this.page ?? 1,
+ };
+ },
+ pollInterval() {
+ return this.interval;
+ },
+ },
+ interval: {
+ query: pollIntervalQuery,
+ },
+ pageInfo: {
+ query: pageInfoQuery,
+ },
+ environmentToDelete: {
+ query: environmentToDeleteQuery,
},
- canCreateEnvironment: {
- type: Boolean,
- required: true,
+ environmentToRollback: {
+ query: environmentToRollbackQuery,
},
- newEnvironmentPath: {
- type: String,
- required: true,
+ environmentToStop: {
+ query: environmentToStopQuery,
},
- helpPagePath: {
- type: String,
- required: true,
+ environmentToChangeCanary: {
+ query: environmentToChangeCanaryQuery,
+ },
+ weight: {
+ query: environmentToChangeCanaryQuery,
},
},
-
- created() {
- eventHub.$on('toggleFolder', this.toggleFolder);
- eventHub.$on('toggleDeployBoard', this.toggleDeployBoard);
+ inject: ['newEnvironmentPath', 'canCreateEnvironment', 'helpPagePath'],
+ i18n: {
+ newEnvironmentButtonLabel: s__('Environments|New environment'),
+ reviewAppButtonLabel: s__('Environments|Enable review app'),
+ available: __('Available'),
+ stopped: __('Stopped'),
+ prevPage: __('Go to previous page'),
+ nextPage: __('Go to next page'),
+ next: __('Next'),
+ prev: __('Prev'),
+ goto: (page) => sprintf(__('Go to page %{page}'), { page }),
},
-
- beforeDestroy() {
- // eslint-disable-next-line @gitlab/no-global-event-off
- eventHub.$off('toggleFolder');
- // eslint-disable-next-line @gitlab/no-global-event-off
- eventHub.$off('toggleDeployBoard');
+ modalId: 'enable-review-app-info',
+ data() {
+ const { page = '1', scope } = queryToObject(window.location.search);
+ return {
+ interval: undefined,
+ isReviewAppModalVisible: false,
+ page: parseInt(page, 10),
+ pageInfo: {},
+ scope: Object.values(ENVIRONMENTS_SCOPE).includes(scope)
+ ? scope
+ : ENVIRONMENTS_SCOPE.AVAILABLE,
+ environmentToDelete: {},
+ environmentToRollback: {},
+ environmentToStop: {},
+ environmentToChangeCanary: {},
+ weight: 0,
+ };
},
-
- methods: {
- toggleDeployBoard(model) {
- this.store.toggleDeployBoard(model.id);
+ computed: {
+ canSetupReviewApp() {
+ return this.environmentApp?.reviewApp?.canSetupReviewApp;
},
- toggleFolder(folder) {
- this.store.toggleFolder(folder);
-
- if (!folder.isOpen) {
- this.fetchChildEnvironments(folder, true);
- }
+ folders() {
+ return this.environmentApp?.environments?.filter((e) => e.size > 1) ?? [];
},
-
- fetchChildEnvironments(folder, showLoader = false) {
- this.store.updateEnvironmentProp(folder, 'isLoadingFolderContent', showLoader);
-
- this.service
- .getFolderContent(folder.folder_path, folder.state)
- .then((response) => this.store.setfolderContent(folder, response.data.environments))
- .then(() => this.store.updateEnvironmentProp(folder, 'isLoadingFolderContent', false))
- .catch(() => {
- createFlash({
- message: s__('Environments|An error occurred while fetching the environments.'),
- });
- this.store.updateEnvironmentProp(folder, 'isLoadingFolderContent', false);
- });
+ environments() {
+ return this.environmentApp?.environments?.filter((e) => e.size === 1) ?? [];
},
+ hasEnvironments() {
+ return this.environments.length > 0 || this.folders.length > 0;
+ },
+ availableCount() {
+ return this.environmentApp?.availableCount;
+ },
+ addEnvironment() {
+ if (!this.canCreateEnvironment) {
+ return null;
+ }
- successCallback(resp) {
- this.saveData(resp);
-
- // We need to verify if any folder is open to also update it
- const openFolders = this.store.getOpenFolders();
- if (openFolders.length) {
- openFolders.forEach((folder) => this.fetchChildEnvironments(folder));
+ return {
+ text: this.$options.i18n.newEnvironmentButtonLabel,
+ attributes: {
+ href: this.newEnvironmentPath,
+ category: 'primary',
+ variant: 'confirm',
+ },
+ };
+ },
+ openReviewAppModal() {
+ if (!this.canSetupReviewApp) {
+ return null;
}
+
+ return {
+ text: this.$options.i18n.reviewAppButtonLabel,
+ attributes: {
+ category: 'secondary',
+ variant: 'confirm',
+ },
+ };
+ },
+ stoppedCount() {
+ return this.environmentApp?.stoppedCount;
},
+ totalItems() {
+ return this.pageInfo?.total;
+ },
+ itemsPerPage() {
+ return this.pageInfo?.perPage;
+ },
+ },
+ mounted() {
+ window.addEventListener('popstate', this.syncPageFromQueryParams);
},
+ destroyed() {
+ window.removeEventListener('popstate', this.syncPageFromQueryParams);
+ this.$apollo.queries.environmentApp.stopPolling();
+ },
+ methods: {
+ showReviewAppModal() {
+ this.isReviewAppModalVisible = true;
+ },
+ setScope(scope) {
+ this.scope = scope;
+ this.moveToPage(1);
+ },
+ movePage(direction) {
+ this.moveToPage(this.pageInfo[`${direction}Page`]);
+ },
+ moveToPage(page) {
+ this.page = page;
+ updateHistory({
+ url: setUrlParams({ page: this.page }),
+ title: document.title,
+ });
+ this.resetPolling();
+ },
+ syncPageFromQueryParams() {
+ const { page = '1' } = queryToObject(window.location.search);
+ this.page = parseInt(page, 10);
+ },
+ resetPolling() {
+ this.$apollo.queries.environmentApp.stopPolling();
+ this.$apollo.queries.environmentApp.refetch();
+ this.$nextTick(() => {
+ if (this.interval) {
+ this.$apollo.queries.environmentApp.startPolling(this.interval);
+ }
+ });
+ },
+ },
+ ENVIRONMENTS_SCOPE,
};
</script>
<template>
- <div class="environments-section">
- <stop-environment-modal :environment="environmentInStopModal" />
- <delete-environment-modal :environment="environmentInDeleteModal" />
- <confirm-rollback-modal :environment="environmentInRollbackModal" />
-
- <div class="gl-w-full">
- <div class="gl-display-flex gl-flex-direction-column gl-mt-3 gl-md-display-none!">
- <gl-button
- v-if="state.reviewAppDetails.can_setup_review_app"
- v-gl-modal="$options.modal.id"
- data-testid="enable-review-app"
- variant="info"
- category="secondary"
- type="button"
- class="gl-mb-3 gl-flex-grow-1"
- >{{ $options.i18n.reviewAppButtonLabel }}</gl-button
- >
- <gl-button
- v-if="canCreateEnvironment"
- :href="newEnvironmentPath"
- data-testid="new-environment"
- category="primary"
- variant="confirm"
- >{{ $options.i18n.newEnvironmentButtonLabel }}</gl-button
- >
- </div>
- <gl-tabs :value="activeTab" content-class="gl-display-none">
- <gl-tab
- v-for="(tab, idx) in tabs"
- :key="idx"
- :title-item-class="`js-environments-tab-${tab.scope}`"
- @click="onChangeTab(tab.scope)"
- >
- <template #title>
- <span>{{ tab.name }}</span>
- <gl-badge size="sm" class="gl-tab-counter-badge">{{ tab.count }}</gl-badge>
- </template>
- </gl-tab>
- <template #tabs-end>
- <div
- class="gl-display-none gl-md-display-flex gl-lg-align-items-center gl-lg-flex-direction-row gl-lg-flex-fill-1 gl-lg-justify-content-end gl-lg-mt-0"
- >
- <gl-button
- v-if="state.reviewAppDetails.can_setup_review_app"
- v-gl-modal="$options.modal.id"
- data-testid="enable-review-app"
- variant="info"
- category="secondary"
- type="button"
- class="gl-mb-3 gl-lg-mr-3 gl-lg-mb-0"
- >{{ $options.i18n.reviewAppButtonLabel }}</gl-button
- >
- <gl-button
- v-if="canCreateEnvironment"
- :href="newEnvironmentPath"
- data-testid="new-environment"
- category="primary"
- variant="confirm"
- >{{ $options.i18n.newEnvironmentButtonLabel }}</gl-button
- >
- </div>
+ <div>
+ <enable-review-app-modal
+ v-if="canSetupReviewApp"
+ v-model="isReviewAppModalVisible"
+ :modal-id="$options.modalId"
+ data-testid="enable-review-app-modal"
+ />
+ <delete-environment-modal :environment="environmentToDelete" graphql />
+ <stop-environment-modal :environment="environmentToStop" graphql />
+ <confirm-rollback-modal :environment="environmentToRollback" graphql />
+ <canary-update-modal :environment="environmentToChangeCanary" :weight="weight" />
+ <gl-tabs
+ :action-secondary="addEnvironment"
+ :action-primary="openReviewAppModal"
+ sync-active-tab-with-query-params
+ query-param-name="scope"
+ @primary="showReviewAppModal"
+ >
+ <gl-tab
+ :query-param-value="$options.ENVIRONMENTS_SCOPE.AVAILABLE"
+ @click="setScope($options.ENVIRONMENTS_SCOPE.AVAILABLE)"
+ >
+ <template #title>
+ <span>{{ $options.i18n.available }}</span>
+ <gl-badge size="sm" class="gl-tab-counter-badge">
+ {{ availableCount }}
+ </gl-badge>
</template>
- </gl-tabs>
- <container
- :is-loading="isLoading"
- :environments="state.environments"
- :pagination="state.paginationInformation"
- @onChangePage="onChangePage"
+ </gl-tab>
+ <gl-tab
+ :query-param-value="$options.ENVIRONMENTS_SCOPE.STOPPED"
+ @click="setScope($options.ENVIRONMENTS_SCOPE.STOPPED)"
>
- <template v-if="!isLoading && state.environments.length === 0" #empty-state>
- <empty-state :help-path="helpPagePath" />
+ <template #title>
+ <span>{{ $options.i18n.stopped }}</span>
+ <gl-badge size="sm" class="gl-tab-counter-badge">
+ {{ stoppedCount }}
+ </gl-badge>
</template>
- </container>
- <enable-review-app-modal
- v-if="state.reviewAppDetails.can_setup_review_app"
- :modal-id="$options.modal.id"
- data-testid="enable-review-app-modal"
+ </gl-tab>
+ </gl-tabs>
+ <template v-if="hasEnvironments">
+ <environment-folder
+ v-for="folder in folders"
+ :key="folder.name"
+ class="gl-mb-3"
+ :scope="scope"
+ :nested-environment="folder"
+ />
+ <environment-item
+ v-for="environment in environments"
+ :key="environment.name"
+ class="gl-mb-3 gl-border-gray-100 gl-border-1 gl-border-b-solid"
+ :environment="environment.latest"
+ @change="resetPolling"
/>
- </div>
+ </template>
+ <empty-state v-else :help-path="helpPagePath" />
+ <gl-pagination
+ align="center"
+ :total-items="totalItems"
+ :per-page="itemsPerPage"
+ :value="page"
+ :next="$options.i18n.next"
+ :prev="$options.i18n.prev"
+ :label-previous-page="$options.prevPage"
+ :label-next-page="$options.nextPage"
+ :label-page="$options.goto"
+ @next="movePage('next')"
+ @previous="movePage('previous')"
+ @input="moveToPage"
+ />
</div>
</template>
diff --git a/app/assets/javascripts/environments/components/new_environment_folder.vue b/app/assets/javascripts/environments/components/new_environment_folder.vue
deleted file mode 100644
index 0d3867a4d74..00000000000
--- a/app/assets/javascripts/environments/components/new_environment_folder.vue
+++ /dev/null
@@ -1,102 +0,0 @@
-<script>
-import { GlButton, GlCollapse, GlIcon, GlBadge, GlLink } from '@gitlab/ui';
-import { __, s__ } from '~/locale';
-import folderQuery from '../graphql/queries/folder.query.graphql';
-import EnvironmentItem from './new_environment_item.vue';
-
-export default {
- components: {
- EnvironmentItem,
- GlButton,
- GlCollapse,
- GlIcon,
- GlBadge,
- GlLink,
- },
- props: {
- nestedEnvironment: {
- type: Object,
- required: true,
- },
- },
- data() {
- return { visible: false };
- },
- apollo: {
- folder: {
- query: folderQuery,
- variables() {
- return { environment: this.nestedEnvironment.latest };
- },
- },
- },
- i18n: {
- collapse: __('Collapse'),
- expand: __('Expand'),
- link: s__('Environments|Show all'),
- },
- computed: {
- icons() {
- return this.visible
- ? { caret: 'angle-down', folder: 'folder-open' }
- : { caret: 'angle-right', folder: 'folder-o' };
- },
- label() {
- return this.visible ? this.$options.i18n.collapse : this.$options.i18n.expand;
- },
- count() {
- return this.folder?.availableCount ?? 0;
- },
- folderClass() {
- return { 'gl-font-weight-bold': this.visible };
- },
- folderPath() {
- return this.nestedEnvironment.latest.folderPath;
- },
- environments() {
- return this.folder?.environments;
- },
- },
- methods: {
- toggleCollapse() {
- this.visible = !this.visible;
- },
- isFirstEnvironment(index) {
- return index === 0;
- },
- },
-};
-</script>
-<template>
- <div
- :class="{ 'gl-pb-5': !visible }"
- class="gl-border-b-solid gl-border-gray-100 gl-border-1 gl-pt-3"
- >
- <div class="gl-w-full gl-display-flex gl-align-items-center gl-px-3">
- <gl-button
- class="gl-mr-4 gl-fill-current-color gl-text-gray-500"
- :aria-label="label"
- :icon="icons.caret"
- size="small"
- category="tertiary"
- @click="toggleCollapse"
- />
- <gl-icon class="gl-mr-2 gl-fill-current-color gl-text-gray-500" :name="icons.folder" />
- <div class="gl-mr-2 gl-text-gray-500" :class="folderClass">
- {{ nestedEnvironment.name }}
- </div>
- <gl-badge size="sm" class="gl-mr-auto">{{ count }}</gl-badge>
- <gl-link v-if="visible" :href="folderPath">{{ $options.i18n.link }}</gl-link>
- </div>
- <gl-collapse :visible="visible">
- <environment-item
- v-for="(environment, index) in environments"
- :key="environment.name"
- :environment="environment"
- :class="{ 'gl-mt-5': isFirstEnvironment(index) }"
- class="gl-border-gray-100 gl-border-t-solid gl-border-1 gl-pt-3"
- in-folder
- />
- </gl-collapse>
- </div>
-</template>
diff --git a/app/assets/javascripts/environments/components/new_environment_item.vue b/app/assets/javascripts/environments/components/new_environment_item.vue
index 27a763fb9c4..f35fabccae7 100644
--- a/app/assets/javascripts/environments/components/new_environment_item.vue
+++ b/app/assets/javascripts/environments/components/new_environment_item.vue
@@ -40,6 +40,9 @@ export default {
Terminal,
TimeAgoTooltip,
Delete,
+ EnvironmentAlert: () => import('ee_component/environments/components/environment_alert.vue'),
+ EnvironmentApproval: () =>
+ import('ee_component/environments/components/environment_approval.vue'),
},
directives: {
GlTooltip,
@@ -97,6 +100,9 @@ export default {
hasDeployment() {
return Boolean(this.environment?.upcomingDeployment || this.environment?.lastDeployment);
},
+ hasOpenedAlert() {
+ return this.environment?.hasOpenedAlert;
+ },
actions() {
if (!this.lastDeployment) {
return [];
@@ -296,12 +302,20 @@ export default {
class="gl-pl-4"
/>
</div>
- <div v-if="upcomingDeployment" :class="$options.deploymentClasses">
+ <div
+ v-if="upcomingDeployment"
+ :class="$options.deploymentClasses"
+ data-testid="upcoming-deployment-content"
+ >
<deployment
:deployment="upcomingDeployment"
:class="{ 'gl-ml-7': inFolder }"
class="gl-pl-4"
- />
+ >
+ <template #approval>
+ <environment-approval :environment="environment" @change="$emit('change')" />
+ </template>
+ </deployment>
</div>
</template>
<div v-else :class="$options.deploymentClasses">
@@ -319,6 +333,9 @@ export default {
class="gl-pl-4"
/>
</div>
+ <div v-if="hasOpenedAlert" class="gl-bg-gray-10 gl-md-px-7">
+ <environment-alert :environment="environment" class="gl-pl-4 gl-py-5" />
+ </div>
</gl-collapse>
</div>
</template>
diff --git a/app/assets/javascripts/environments/components/new_environments_app.vue b/app/assets/javascripts/environments/components/new_environments_app.vue
deleted file mode 100644
index 3699f39b611..00000000000
--- a/app/assets/javascripts/environments/components/new_environments_app.vue
+++ /dev/null
@@ -1,252 +0,0 @@
-<script>
-import { GlBadge, GlPagination, GlTab, GlTabs } from '@gitlab/ui';
-import { s__, __, sprintf } from '~/locale';
-import { updateHistory, setUrlParams, queryToObject } from '~/lib/utils/url_utility';
-import environmentAppQuery from '../graphql/queries/environment_app.query.graphql';
-import pollIntervalQuery from '../graphql/queries/poll_interval.query.graphql';
-import pageInfoQuery from '../graphql/queries/page_info.query.graphql';
-import environmentToDeleteQuery from '../graphql/queries/environment_to_delete.query.graphql';
-import environmentToRollbackQuery from '../graphql/queries/environment_to_rollback.query.graphql';
-import environmentToStopQuery from '../graphql/queries/environment_to_stop.query.graphql';
-import environmentToChangeCanaryQuery from '../graphql/queries/environment_to_change_canary.query.graphql';
-import EnvironmentFolder from './new_environment_folder.vue';
-import EnableReviewAppModal from './enable_review_app_modal.vue';
-import StopEnvironmentModal from './stop_environment_modal.vue';
-import EnvironmentItem from './new_environment_item.vue';
-import ConfirmRollbackModal from './confirm_rollback_modal.vue';
-import DeleteEnvironmentModal from './delete_environment_modal.vue';
-import CanaryUpdateModal from './canary_update_modal.vue';
-
-export default {
- components: {
- DeleteEnvironmentModal,
- CanaryUpdateModal,
- ConfirmRollbackModal,
- EnvironmentFolder,
- EnableReviewAppModal,
- EnvironmentItem,
- StopEnvironmentModal,
- GlBadge,
- GlPagination,
- GlTab,
- GlTabs,
- },
- apollo: {
- environmentApp: {
- query: environmentAppQuery,
- variables() {
- return {
- scope: this.scope,
- page: this.page ?? 1,
- };
- },
- pollInterval() {
- return this.interval;
- },
- },
- interval: {
- query: pollIntervalQuery,
- },
- pageInfo: {
- query: pageInfoQuery,
- },
- environmentToDelete: {
- query: environmentToDeleteQuery,
- },
- environmentToRollback: {
- query: environmentToRollbackQuery,
- },
- environmentToStop: {
- query: environmentToStopQuery,
- },
- environmentToChangeCanary: {
- query: environmentToChangeCanaryQuery,
- },
- weight: {
- query: environmentToChangeCanaryQuery,
- },
- },
- inject: ['newEnvironmentPath', 'canCreateEnvironment'],
- i18n: {
- newEnvironmentButtonLabel: s__('Environments|New environment'),
- reviewAppButtonLabel: s__('Environments|Enable review app'),
- available: __('Available'),
- stopped: __('Stopped'),
- prevPage: __('Go to previous page'),
- nextPage: __('Go to next page'),
- next: __('Next'),
- prev: __('Prev'),
- goto: (page) => sprintf(__('Go to page %{page}'), { page }),
- },
- modalId: 'enable-review-app-info',
- data() {
- const { page = '1', scope = 'available' } = queryToObject(window.location.search);
- return {
- interval: undefined,
- isReviewAppModalVisible: false,
- page: parseInt(page, 10),
- scope,
- environmentToDelete: {},
- environmentToRollback: {},
- environmentToStop: {},
- environmentToChangeCanary: {},
- weight: 0,
- };
- },
- computed: {
- canSetupReviewApp() {
- return this.environmentApp?.reviewApp?.canSetupReviewApp;
- },
- folders() {
- return this.environmentApp?.environments?.filter((e) => e.size > 1) ?? [];
- },
- environments() {
- return this.environmentApp?.environments?.filter((e) => e.size === 1) ?? [];
- },
- availableCount() {
- return this.environmentApp?.availableCount;
- },
- addEnvironment() {
- if (!this.canCreateEnvironment) {
- return null;
- }
-
- return {
- text: this.$options.i18n.newEnvironmentButtonLabel,
- attributes: {
- href: this.newEnvironmentPath,
- category: 'primary',
- variant: 'confirm',
- },
- };
- },
- openReviewAppModal() {
- if (!this.canSetupReviewApp) {
- return null;
- }
-
- return {
- text: this.$options.i18n.reviewAppButtonLabel,
- attributes: {
- category: 'secondary',
- variant: 'confirm',
- },
- };
- },
- stoppedCount() {
- return this.environmentApp?.stoppedCount;
- },
- totalItems() {
- return this.pageInfo?.total;
- },
- itemsPerPage() {
- return this.pageInfo?.perPage;
- },
- },
- mounted() {
- window.addEventListener('popstate', this.syncPageFromQueryParams);
- },
- destroyed() {
- window.removeEventListener('popstate', this.syncPageFromQueryParams);
- this.$apollo.queries.environmentApp.stopPolling();
- },
- methods: {
- showReviewAppModal() {
- this.isReviewAppModalVisible = true;
- },
- setScope(scope) {
- this.scope = scope;
- this.moveToPage(1);
- },
- movePage(direction) {
- this.moveToPage(this.pageInfo[`${direction}Page`]);
- },
- moveToPage(page) {
- this.page = page;
- updateHistory({
- url: setUrlParams({ page: this.page }),
- title: document.title,
- });
- this.resetPolling();
- },
- syncPageFromQueryParams() {
- const { page = '1' } = queryToObject(window.location.search);
- this.page = parseInt(page, 10);
- },
- resetPolling() {
- this.$apollo.queries.environmentApp.stopPolling();
- this.$nextTick(() => {
- if (this.interval) {
- this.$apollo.queries.environmentApp.startPolling(this.interval);
- } else {
- this.$apollo.queries.environmentApp.refetch({ scope: this.scope, page: this.page });
- }
- });
- },
- },
-};
-</script>
-<template>
- <div>
- <enable-review-app-modal
- v-if="canSetupReviewApp"
- v-model="isReviewAppModalVisible"
- :modal-id="$options.modalId"
- data-testid="enable-review-app-modal"
- />
- <delete-environment-modal :environment="environmentToDelete" graphql />
- <stop-environment-modal :environment="environmentToStop" graphql />
- <confirm-rollback-modal :environment="environmentToRollback" graphql />
- <canary-update-modal :environment="environmentToChangeCanary" :weight="weight" />
- <gl-tabs
- :action-secondary="addEnvironment"
- :action-primary="openReviewAppModal"
- sync-active-tab-with-query-params
- query-param-name="scope"
- @primary="showReviewAppModal"
- >
- <gl-tab query-param-value="available" @click="setScope('available')">
- <template #title>
- <span>{{ $options.i18n.available }}</span>
- <gl-badge size="sm" class="gl-tab-counter-badge">
- {{ availableCount }}
- </gl-badge>
- </template>
- </gl-tab>
- <gl-tab query-param-value="stopped" @click="setScope('stopped')">
- <template #title>
- <span>{{ $options.i18n.stopped }}</span>
- <gl-badge size="sm" class="gl-tab-counter-badge">
- {{ stoppedCount }}
- </gl-badge>
- </template>
- </gl-tab>
- </gl-tabs>
- <environment-folder
- v-for="folder in folders"
- :key="folder.name"
- class="gl-mb-3"
- :nested-environment="folder"
- />
- <environment-item
- v-for="environment in environments"
- :key="environment.name"
- class="gl-mb-3 gl-border-gray-100 gl-border-1 gl-border-b-solid"
- :environment="environment.latest"
- />
- <gl-pagination
- align="center"
- :total-items="totalItems"
- :per-page="itemsPerPage"
- :value="page"
- :next="$options.i18n.next"
- :prev="$options.i18n.prev"
- :label-previous-page="$options.prevPage"
- :label-next-page="$options.nextPage"
- :label-page="$options.goto"
- @next="movePage('next')"
- @previous="movePage('previous')"
- @input="moveToPage"
- />
- </div>
-</template>
diff --git a/app/assets/javascripts/environments/constants.js b/app/assets/javascripts/environments/constants.js
index 6d427bef4e6..942491039d6 100644
--- a/app/assets/javascripts/environments/constants.js
+++ b/app/assets/javascripts/environments/constants.js
@@ -38,3 +38,13 @@ export const CANARY_STATUS = {
};
export const CANARY_UPDATE_MODAL = 'confirm-canary-change';
+
+export const ENVIRONMENTS_SCOPE = {
+ AVAILABLE: 'available',
+ STOPPED: 'stopped',
+};
+
+export const ENVIRONMENT_COUNT_BY_SCOPE = {
+ [ENVIRONMENTS_SCOPE.AVAILABLE]: 'availableCount',
+ [ENVIRONMENTS_SCOPE.STOPPED]: 'stoppedCount',
+};
diff --git a/app/assets/javascripts/environments/graphql/client.js b/app/assets/javascripts/environments/graphql/client.js
index 64b18c2003b..26514b59995 100644
--- a/app/assets/javascripts/environments/graphql/client.js
+++ b/app/assets/javascripts/environments/graphql/client.js
@@ -2,6 +2,9 @@ import VueApollo from 'vue-apollo';
import createDefaultClient from '~/lib/graphql';
import environmentApp from './queries/environment_app.query.graphql';
import pageInfoQuery from './queries/page_info.query.graphql';
+import environmentToDeleteQuery from './queries/environment_to_delete.query.graphql';
+import environmentToRollbackQuery from './queries/environment_to_rollback.query.graphql';
+import environmentToStopQuery from './queries/environment_to_stop.query.graphql';
import { resolvers } from './resolvers';
import typeDefs from './typedefs.graphql';
@@ -33,6 +36,52 @@ export const apolloProvider = (endpoint) => {
},
},
});
+
+ cache.writeQuery({
+ query: environmentToDeleteQuery,
+ data: {
+ environmentToDelete: {
+ name: 'null',
+ __typename: 'LocalEnvironment',
+ id: '0',
+ deletePath: null,
+ folderPath: null,
+ retryUrl: null,
+ autoStopPath: null,
+ lastDeployment: null,
+ },
+ },
+ });
+ cache.writeQuery({
+ query: environmentToStopQuery,
+ data: {
+ environmentToStop: {
+ name: 'null',
+ __typename: 'LocalEnvironment',
+ id: '0',
+ deletePath: null,
+ folderPath: null,
+ retryUrl: null,
+ autoStopPath: null,
+ lastDeployment: null,
+ },
+ },
+ });
+ cache.writeQuery({
+ query: environmentToRollbackQuery,
+ data: {
+ environmentToRollback: {
+ name: 'null',
+ __typename: 'LocalEnvironment',
+ id: '0',
+ deletePath: null,
+ folderPath: null,
+ retryUrl: null,
+ autoStopPath: null,
+ lastDeployment: null,
+ },
+ },
+ });
return new VueApollo({
defaultClient,
});
diff --git a/app/assets/javascripts/environments/graphql/queries/folder.query.graphql b/app/assets/javascripts/environments/graphql/queries/folder.query.graphql
index 3292c916b2e..e8c145ee916 100644
--- a/app/assets/javascripts/environments/graphql/queries/folder.query.graphql
+++ b/app/assets/javascripts/environments/graphql/queries/folder.query.graphql
@@ -1,5 +1,5 @@
-query getEnvironmentFolder($environment: NestedLocalEnvironment) {
- folder(environment: $environment) @client {
+query getEnvironmentFolder($environment: NestedLocalEnvironment, $scope: String) {
+ folder(environment: $environment, scope: $scope) @client {
availableCount
environments
stoppedCount
diff --git a/app/assets/javascripts/environments/graphql/resolvers.js b/app/assets/javascripts/environments/graphql/resolvers.js
index dc763b77157..a7866c1e778 100644
--- a/app/assets/javascripts/environments/graphql/resolvers.js
+++ b/app/assets/javascripts/environments/graphql/resolvers.js
@@ -11,6 +11,7 @@ import environmentToRollbackQuery from './queries/environment_to_rollback.query.
import environmentToStopQuery from './queries/environment_to_stop.query.graphql';
import environmentToDeleteQuery from './queries/environment_to_delete.query.graphql';
import environmentToChangeCanaryQuery from './queries/environment_to_change_canary.query.graphql';
+import isEnvironmentStoppingQuery from './queries/is_environment_stopping.query.graphql';
import pageInfoQuery from './queries/page_info.query.graphql';
const buildErrors = (errors = []) => ({
@@ -58,8 +59,8 @@ export const resolvers = (endpoint) => ({
};
});
},
- folder(_, { environment: { folderPath } }) {
- return axios.get(folderPath, { params: { per_page: 3 } }).then((res) => ({
+ folder(_, { environment: { folderPath }, scope }) {
+ return axios.get(folderPath, { params: { scope, per_page: 3 } }).then((res) => ({
availableCount: res.data.available_count,
environments: res.data.environments.map(mapEnvironment),
stoppedCount: res.data.stopped_count,
@@ -71,11 +72,21 @@ export const resolvers = (endpoint) => ({
},
},
Mutation: {
- stopEnvironment(_, { environment }) {
+ stopEnvironment(_, { environment }, { client }) {
+ client.writeQuery({
+ query: isEnvironmentStoppingQuery,
+ variables: { environment },
+ data: { isEnvironmentStopping: true },
+ });
return axios
.post(environment.stopPath)
.then(() => buildErrors())
.catch(() => {
+ client.writeQuery({
+ query: isEnvironmentStoppingQuery,
+ variables: { environment },
+ data: { isEnvironmentStopping: false },
+ });
return buildErrors([
s__('Environments|An error occurred while stopping the environment, please try again'),
]);
diff --git a/app/assets/javascripts/environments/index.js b/app/assets/javascripts/environments/index.js
index 3b1d35c1f22..d9a523fd806 100644
--- a/app/assets/javascripts/environments/index.js
+++ b/app/assets/javascripts/environments/index.js
@@ -1,48 +1,37 @@
import Vue from 'vue';
import VueApollo from 'vue-apollo';
-import createDefaultClient from '~/lib/graphql';
import { parseBoolean } from '../lib/utils/common_utils';
-import Translate from '../vue_shared/translate';
-import environmentsComponent from './components/environments_app.vue';
+import { apolloProvider } from './graphql/client';
+import EnvironmentsApp from './components/environments_app.vue';
-Vue.use(Translate);
Vue.use(VueApollo);
-const apolloProvider = new VueApollo({
- defaultClient: createDefaultClient(),
-});
-
export default (el) => {
if (el) {
+ const {
+ canCreateEnvironment,
+ endpoint,
+ newEnvironmentPath,
+ helpPagePath,
+ projectPath,
+ defaultBranchName,
+ projectId,
+ } = el.dataset;
+
return new Vue({
el,
- components: {
- environmentsComponent,
- },
- apolloProvider,
+ apolloProvider: apolloProvider(endpoint),
provide: {
- projectPath: el.dataset.projectPath,
- defaultBranchName: el.dataset.defaultBranchName,
- },
- data() {
- const environmentsData = el.dataset;
-
- return {
- endpoint: environmentsData.environmentsDataEndpoint,
- newEnvironmentPath: environmentsData.newEnvironmentPath,
- helpPagePath: environmentsData.helpPagePath,
- canCreateEnvironment: parseBoolean(environmentsData.canCreateEnvironment),
- };
+ projectPath,
+ defaultBranchName,
+ endpoint,
+ newEnvironmentPath,
+ helpPagePath,
+ projectId,
+ canCreateEnvironment: parseBoolean(canCreateEnvironment),
},
- render(createElement) {
- return createElement('environments-component', {
- props: {
- endpoint: this.endpoint,
- newEnvironmentPath: this.newEnvironmentPath,
- helpPagePath: this.helpPagePath,
- canCreateEnvironment: this.canCreateEnvironment,
- },
- });
+ render(h) {
+ return h(EnvironmentsApp);
},
});
}
diff --git a/app/assets/javascripts/environments/new_index.js b/app/assets/javascripts/environments/new_index.js
deleted file mode 100644
index dd5c709c75a..00000000000
--- a/app/assets/javascripts/environments/new_index.js
+++ /dev/null
@@ -1,38 +0,0 @@
-import Vue from 'vue';
-import VueApollo from 'vue-apollo';
-import { parseBoolean } from '../lib/utils/common_utils';
-import { apolloProvider } from './graphql/client';
-import EnvironmentsApp from './components/new_environments_app.vue';
-
-Vue.use(VueApollo);
-
-export default (el) => {
- if (el) {
- const {
- canCreateEnvironment,
- endpoint,
- newEnvironmentPath,
- helpPagePath,
- projectPath,
- defaultBranchName,
- } = el.dataset;
-
- return new Vue({
- el,
- apolloProvider: apolloProvider(endpoint),
- provide: {
- projectPath,
- defaultBranchName,
- endpoint,
- newEnvironmentPath,
- helpPagePath,
- canCreateEnvironment: parseBoolean(canCreateEnvironment),
- },
- render(h) {
- return h(EnvironmentsApp);
- },
- });
- }
-
- return null;
-};
diff --git a/app/assets/javascripts/error_tracking/components/constants.js b/app/assets/javascripts/error_tracking/components/constants.js
deleted file mode 100644
index 41b952e26d8..00000000000
--- a/app/assets/javascripts/error_tracking/components/constants.js
+++ /dev/null
@@ -1,21 +0,0 @@
-export const severityLevel = {
- FATAL: 'fatal',
- ERROR: 'error',
- WARNING: 'warning',
- INFO: 'info',
- DEBUG: 'debug',
-};
-
-export const severityLevelVariant = {
- [severityLevel.FATAL]: 'danger',
- [severityLevel.ERROR]: 'neutral',
- [severityLevel.WARNING]: 'warning',
- [severityLevel.INFO]: 'info',
- [severityLevel.DEBUG]: 'muted',
-};
-
-export const errorStatus = {
- IGNORED: 'ignored',
- RESOLVED: 'resolved',
- UNRESOLVED: 'unresolved',
-};
diff --git a/app/assets/javascripts/error_tracking/components/error_details.vue b/app/assets/javascripts/error_tracking/components/error_details.vue
index e00fec6fddf..0a8abdc90c6 100644
--- a/app/assets/javascripts/error_tracking/components/error_details.vue
+++ b/app/assets/javascripts/error_tracking/components/error_details.vue
@@ -26,7 +26,7 @@ import {
trackErrorStatusUpdateOptions,
} from '../utils';
-import { severityLevel, severityLevelVariant, errorStatus } from './constants';
+import { severityLevel, severityLevelVariant, errorStatus } from '../constants';
import Stacktrace from './stacktrace.vue';
const SENTRY_TIMEOUT = 10000;
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 5db8c8cf8d3..3d540d46b3c 100644
--- a/app/assets/javascripts/error_tracking/components/error_tracking_list.vue
+++ b/app/assets/javascripts/error_tracking/components/error_tracking_list.vue
@@ -1,5 +1,6 @@
<script>
import {
+ GlAlert,
GlEmptyState,
GlButton,
GlIcon,
@@ -10,6 +11,7 @@ import {
GlDropdown,
GlDropdownItem,
GlDropdownDivider,
+ GlSprintf,
GlTooltipDirective,
GlPagination,
} from '@gitlab/ui';
@@ -21,6 +23,7 @@ import { __ } from '~/locale';
import Tracking from '~/tracking';
import TimeAgo from '~/vue_shared/components/time_ago_tooltip.vue';
import { trackErrorListViewsOptions, trackErrorStatusUpdateOptions } from '../utils';
+import { I18N_ERROR_TRACKING_LIST } from '../constants';
import ErrorTrackingActions from './error_tracking_actions.vue';
export const tableDataClass = 'table-col d-flex d-md-table-cell align-items-center';
@@ -29,6 +32,7 @@ export default {
FIRST_PAGE: 1,
PREV_PAGE: 1,
NEXT_PAGE: 2,
+ i18n: I18N_ERROR_TRACKING_LIST,
fields: [
{
key: 'error',
@@ -71,6 +75,7 @@ export default {
frequency: __('Frequency'),
},
components: {
+ GlAlert,
GlEmptyState,
GlButton,
GlDropdown,
@@ -81,6 +86,7 @@ export default {
GlLoadingIcon,
GlTable,
GlFormInput,
+ GlSprintf,
GlPagination,
TimeAgo,
ErrorTrackingActions,
@@ -117,12 +123,17 @@ export default {
type: String,
required: true,
},
+ showIntegratedTrackingDisabledAlert: {
+ type: Boolean,
+ required: false,
+ },
},
hasLocalStorage: AccessorUtils.canUseLocalStorage(),
data() {
return {
errorSearchQuery: '',
pageValue: this.$options.FIRST_PAGE,
+ isAlertDismissed: false,
};
},
computed: {
@@ -142,6 +153,9 @@ export default {
errorTrackingHelpUrl() {
return helpPagePath('operations/error_tracking');
},
+ showIntegratedDisabledAlert() {
+ return !this.isAlertDismissed && this.showIntegratedTrackingDisabledAlert;
+ },
},
watch: {
pagination() {
@@ -150,6 +164,8 @@ export default {
}
},
},
+ epicLink: 'https://gitlab.com/gitlab-org/gitlab/-/issues/353639',
+ featureFlagLink: helpPagePath('operations/error_tracking'),
created() {
if (this.errorTrackingEnabled) {
this.setEndpoint(this.indexPath);
@@ -232,6 +248,34 @@ export default {
<template>
<div class="error-list">
<div v-if="errorTrackingEnabled">
+ <gl-alert
+ v-if="showIntegratedDisabledAlert"
+ variant="danger"
+ data-testid="integrated-disabled-alert"
+ @dismiss="isAlertDismissed = true"
+ >
+ <gl-sprintf :message="this.$options.i18n.integratedErrorTrackingDisabledText">
+ <template #epicLink="{ content }">
+ <gl-link :href="$options.epicLink" target="_blank">{{ content }}</gl-link>
+ </template>
+ <template #flagLink="{ content }">
+ <gl-link :href="$options.featureFlagLink" target="_blank">{{ content }}</gl-link>
+ </template>
+ <template #settingsLink="{ content }">
+ <gl-link :href="enableErrorTrackingLink" target="_blank">{{ content }}</gl-link>
+ </template>
+ </gl-sprintf>
+ <div>
+ <gl-button
+ category="primary"
+ variant="confirm"
+ :href="enableErrorTrackingLink"
+ class="gl-mr-auto gl-mt-3"
+ >
+ {{ $options.i18n.viewProjectSettingsButton }}
+ </gl-button>
+ </div>
+ </gl-alert>
<div
class="row flex-column flex-md-row align-items-md-center m-0 mt-sm-2 p-3 p-sm-3 bg-secondary border"
>
diff --git a/app/assets/javascripts/error_tracking/constants.js b/app/assets/javascripts/error_tracking/constants.js
new file mode 100644
index 00000000000..f01bac2e81d
--- /dev/null
+++ b/app/assets/javascripts/error_tracking/constants.js
@@ -0,0 +1,30 @@
+import { s__ } from '~/locale';
+
+export const severityLevel = {
+ FATAL: 'fatal',
+ ERROR: 'error',
+ WARNING: 'warning',
+ INFO: 'info',
+ DEBUG: 'debug',
+};
+
+export const severityLevelVariant = {
+ [severityLevel.FATAL]: 'danger',
+ [severityLevel.ERROR]: 'neutral',
+ [severityLevel.WARNING]: 'warning',
+ [severityLevel.INFO]: 'info',
+ [severityLevel.DEBUG]: 'muted',
+};
+
+export const errorStatus = {
+ IGNORED: 'ignored',
+ RESOLVED: 'resolved',
+ UNRESOLVED: 'unresolved',
+};
+
+export const I18N_ERROR_TRACKING_LIST = {
+ integratedErrorTrackingDisabledText: s__(
+ 'ErrorTracking|Integrated error tracking is %{epicLinkStart}turned off by default%{epicLinkEnd} and no longer active for this project. To re-enable error tracking on self-hosted instances, you can either %{flagLinkStart}turn on the feature flag%{flagLinkEnd} for integrated error tracking, or provide a %{settingsLinkStart}Sentry API URL and Auth Token%{settingsLinkEnd} on your project settings page. However, error tracking is not ready for production use and cannot be enabled on GitLab.com.',
+ ),
+ viewProjectSettingsButton: s__('ErrorTracking|View project settings'),
+};
diff --git a/app/assets/javascripts/error_tracking/list.js b/app/assets/javascripts/error_tracking/list.js
index 9c729407009..8b2086e1522 100644
--- a/app/assets/javascripts/error_tracking/list.js
+++ b/app/assets/javascripts/error_tracking/list.js
@@ -14,10 +14,15 @@ export default () => {
projectPath,
listPath,
} = domEl.dataset;
- let { errorTrackingEnabled, userCanEnableErrorTracking } = domEl.dataset;
+ let {
+ errorTrackingEnabled,
+ userCanEnableErrorTracking,
+ showIntegratedTrackingDisabledAlert,
+ } = domEl.dataset;
errorTrackingEnabled = parseBoolean(errorTrackingEnabled);
userCanEnableErrorTracking = parseBoolean(userCanEnableErrorTracking);
+ showIntegratedTrackingDisabledAlert = parseBoolean(showIntegratedTrackingDisabledAlert);
// eslint-disable-next-line no-new
new Vue({
@@ -36,6 +41,7 @@ export default () => {
userCanEnableErrorTracking,
projectPath,
listPath,
+ showIntegratedTrackingDisabledAlert,
},
});
},
diff --git a/app/assets/javascripts/error_tracking_settings/components/app.vue b/app/assets/javascripts/error_tracking_settings/components/app.vue
index 4808cd1d1c0..e850d954e0a 100644
--- a/app/assets/javascripts/error_tracking_settings/components/app.vue
+++ b/app/assets/javascripts/error_tracking_settings/components/app.vue
@@ -1,29 +1,40 @@
<script>
import {
+ GlAlert,
GlButton,
GlFormGroup,
GlFormCheckbox,
GlFormRadioGroup,
GlFormRadio,
GlFormInputGroup,
+ GlLink,
+ GlSprintf,
} from '@gitlab/ui';
import { mapActions, mapGetters, mapState } from 'vuex';
import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
+import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
+import { helpPagePath } from '~/helpers/help_page_helper';
+import { I18N_ERROR_TRACKING_SETTINGS } from '../constants';
import ErrorTrackingForm from './error_tracking_form.vue';
import ProjectDropdown from './project_dropdown.vue';
export default {
+ i18n: I18N_ERROR_TRACKING_SETTINGS,
components: {
ErrorTrackingForm,
+ GlAlert,
GlButton,
GlFormCheckbox,
GlFormGroup,
GlFormRadioGroup,
GlFormRadio,
GlFormInputGroup,
+ GlLink,
+ GlSprintf,
ProjectDropdown,
ClipboardButton,
},
+ mixins: [glFeatureFlagsMixin()],
props: {
initialApiHost: {
type: String,
@@ -62,6 +73,11 @@ export default {
default: null,
},
},
+ data() {
+ return {
+ isAlertDismissed: false,
+ };
+ },
computed: {
...mapGetters([
'dropdownLabel',
@@ -81,12 +97,34 @@ export default {
showGitlabDsnSetting() {
return this.integrated && this.enabled && this.gitlabDsn;
},
+ showIntegratedErrorTracking() {
+ return this.glFeatures.integratedErrorTracking === true;
+ },
+ setInitialEnabled() {
+ if (this.showIntegratedErrorTracking) {
+ return this.initialEnabled;
+ }
+ if (this.initialIntegrated === 'true') {
+ return 'false';
+ }
+ return this.initialEnabled;
+ },
+ showIntegratedTrackingDisabledAlert() {
+ return (
+ !this.isAlertDismissed &&
+ !this.showIntegratedErrorTracking &&
+ this.initialIntegrated === 'true' &&
+ this.initialEnabled === 'true'
+ );
+ },
},
+ epicLink: 'https://gitlab.com/gitlab-org/gitlab/-/issues/353639',
+ featureFlagLink: helpPagePath('operations/error_tracking'),
created() {
this.setInitialState({
apiHost: this.initialApiHost,
- enabled: this.initialEnabled,
- integrated: this.initialIntegrated,
+ enabled: this.setInitialEnabled,
+ integrated: this.showIntegratedErrorTracking && this.initialIntegrated,
project: this.initialProject,
token: this.initialToken,
listProjectsEndpoint: this.listProjectsEndpoint,
@@ -104,21 +142,41 @@ export default {
handleSubmit() {
this.updateSettings();
},
+ dismissAlert() {
+ this.isAlertDismissed = true;
+ },
},
};
</script>
<template>
<div>
+ <gl-alert v-if="showIntegratedTrackingDisabledAlert" variant="danger" @dismiss="dismissAlert">
+ <gl-sprintf :message="this.$options.i18n.integratedErrorTrackingDisabledText">
+ <template #epicLink="{ content }">
+ <gl-link :href="$options.epicLink" target="_blank">{{ content }}</gl-link>
+ </template>
+ <template #flagLink="{ content }">
+ <gl-link :href="$options.featureFlagLink" target="_blank">{{ content }}</gl-link>
+ </template>
+ </gl-sprintf>
+ </gl-alert>
+
<gl-form-group
:label="s__('ErrorTracking|Enable error tracking')"
label-for="error-tracking-enabled"
>
- <gl-form-checkbox id="error-tracking-enabled" :checked="enabled" @change="updateEnabled">
+ <gl-form-checkbox
+ id="error-tracking-enabled"
+ :checked="enabled"
+ data-testid="error-tracking-enabled"
+ @change="updateEnabled"
+ >
{{ s__('ErrorTracking|Active') }}
</gl-form-checkbox>
</gl-form-group>
<gl-form-group
+ v-if="showIntegratedErrorTracking"
:label="s__('ErrorTracking|Error tracking backend')"
data-testid="tracking-backend-settings"
>
diff --git a/app/assets/javascripts/error_tracking_settings/constants.js b/app/assets/javascripts/error_tracking_settings/constants.js
new file mode 100644
index 00000000000..ee86c55e843
--- /dev/null
+++ b/app/assets/javascripts/error_tracking_settings/constants.js
@@ -0,0 +1,7 @@
+import { s__ } from '~/locale';
+
+export const I18N_ERROR_TRACKING_SETTINGS = {
+ integratedErrorTrackingDisabledText: s__(
+ 'ErrorTracking|Integrated error tracking is %{epicLinkStart}turned off by default%{epicLinkEnd} and no longer active for this project. To re-enable error tracking on self-hosted instances, you can either %{flagLinkStart}turn on the feature flag%{flagLinkEnd} for integrated error tracking, or provide a Sentry API URL and Auth Token below. However, error tracking is not ready for production use and cannot be enabled on GitLab.com.',
+ ),
+};
diff --git a/app/assets/javascripts/experimentation/components/gitlab_experiment.vue b/app/assets/javascripts/experimentation/components/gitlab_experiment.vue
index 294dbf77991..678ce447e80 100644
--- a/app/assets/javascripts/experimentation/components/gitlab_experiment.vue
+++ b/app/assets/javascripts/experimentation/components/gitlab_experiment.vue
@@ -9,7 +9,7 @@ export default {
},
},
render() {
- return this.$slots?.[getExperimentVariant(this.name)];
+ return this.$scopedSlots?.[getExperimentVariant(this.name)]?.();
},
};
</script>
diff --git a/app/assets/javascripts/filtered_search/filtered_search_dropdown.js b/app/assets/javascripts/filtered_search/filtered_search_dropdown.js
index fcc7caa9ff2..9de291b7809 100644
--- a/app/assets/javascripts/filtered_search/filtered_search_dropdown.js
+++ b/app/assets/javascripts/filtered_search/filtered_search_dropdown.js
@@ -1,3 +1,4 @@
+import { loadingIconForLegacyJS } from '~/loading_icon_for_legacy_js';
import { FILTER_TYPE } from './constants';
import DropdownUtils from './dropdown_utils';
import FilteredSearchDropdownManager from './filtered_search_dropdown_manager';
@@ -13,7 +14,7 @@ export default class FilteredSearchDropdown {
this.filter = filter;
this.dropdown = dropdown;
this.loadingTemplate = `<div class="filter-dropdown-loading">
- <span class="spinner"></span>
+ ${loadingIconForLegacyJS().outerHTML}
</div>`;
this.bindEvents();
}
diff --git a/app/assets/javascripts/gfm_auto_complete.js b/app/assets/javascripts/gfm_auto_complete.js
index bf29a356abd..8cb2e9e249b 100644
--- a/app/assets/javascripts/gfm_auto_complete.js
+++ b/app/assets/javascripts/gfm_auto_complete.js
@@ -3,6 +3,7 @@ import '~/lib/utils/jquery_at_who';
import { escape as lodashEscape, sortBy, template, escapeRegExp } from 'lodash';
import * as Emoji from '~/emoji';
import axios from '~/lib/utils/axios_utils';
+import { loadingIconForLegacyJS } from '~/loading_icon_for_legacy_js';
import { s__, __, sprintf } from '~/locale';
import { isUserBusy } from '~/set_status_modal/utils';
import SidebarMediator from '~/sidebar/sidebar_mediator';
@@ -574,6 +575,10 @@ class GfmAutoComplete {
// Do not match if there is no `~` before the cursor
return null;
}
+ if (subtext.endsWith('~~')) {
+ // Do not match if there are two consecutive `~` characters (strikethrough) before the cursor
+ return null;
+ }
const lastCandidate = subtext.split(flag).pop();
if (labels.find((label) => label.title.startsWith(lastCandidate))) {
return lastCandidate;
@@ -953,9 +958,14 @@ GfmAutoComplete.Contacts = {
return `<li><small>${firstName} ${lastName}</small> ${escape(email)}</li>`;
},
};
+
+const loadingSpinner = loadingIconForLegacyJS({
+ inline: true,
+ classes: ['gl-mr-2'],
+}).outerHTML;
+
GfmAutoComplete.Loading = {
- template:
- '<li style="pointer-events: none;"><span class="spinner align-text-bottom mr-1"></span>Loading...</li>',
+ template: `<li style="pointer-events: none;">${loadingSpinner}Loading...</li>`,
};
export default GfmAutoComplete;
diff --git a/app/assets/javascripts/google_cloud/components/app.vue b/app/assets/javascripts/google_cloud/components/app.vue
index 64784755b66..03b256297f6 100644
--- a/app/assets/javascripts/google_cloud/components/app.vue
+++ b/app/assets/javascripts/google_cloud/components/app.vue
@@ -4,6 +4,7 @@ import { __ } from '~/locale';
import Home from './home.vue';
import IncubationBanner from './incubation_banner.vue';
import ServiceAccountsForm from './service_accounts_form.vue';
+import GcpRegionsForm from './gcp_regions_form.vue';
import NoGcpProjects from './errors/no_gcp_projects.vue';
import GcpError from './errors/gcp_error.vue';
@@ -11,6 +12,7 @@ const SCREEN_GCP_ERROR = 'gcp_error';
const SCREEN_HOME = 'home';
const SCREEN_NO_GCP_PROJECTS = 'no_gcp_projects';
const SCREEN_SERVICE_ACCOUNTS_FORM = 'service_accounts_form';
+const SCREEN_GCP_REGIONS_FORM = 'gcp_regions_form';
export default {
components: {
@@ -34,6 +36,8 @@ export default {
return NoGcpProjects;
case SCREEN_SERVICE_ACCOUNTS_FORM:
return ServiceAccountsForm;
+ case SCREEN_GCP_REGIONS_FORM:
+ return GcpRegionsForm;
default:
throw new Error(__('Unknown screen'));
}
diff --git a/app/assets/javascripts/google_cloud/components/gcp_regions_form.vue b/app/assets/javascripts/google_cloud/components/gcp_regions_form.vue
new file mode 100644
index 00000000000..23011e5a5b0
--- /dev/null
+++ b/app/assets/javascripts/google_cloud/components/gcp_regions_form.vue
@@ -0,0 +1,62 @@
+<script>
+import { GlButton, GlFormGroup, GlFormSelect } from '@gitlab/ui';
+import { __, s__ } from '~/locale';
+
+export default {
+ components: { GlButton, GlFormGroup, GlFormSelect },
+ props: {
+ availableRegions: { required: true, type: Array },
+ refs: { required: true, type: Array },
+ cancelPath: { required: true, type: String },
+ },
+ i18n: {
+ title: __('Configure region for environment'),
+ gcpRegionLabel: __('Region'),
+ gcpRegionDescription: __('List of suitable GCP locations'),
+ refsLabel: s__('GoogleCloud|Refs'),
+ refsDescription: s__('GoogleCloud|Configured region is linked to the selected branch or tag'),
+ submitLabel: __('Configure region'),
+ cancelLabel: __('Cancel'),
+ },
+};
+</script>
+
+<template>
+ <div>
+ <header class="gl-my-5 gl-border-b-1 gl-border-b-gray-100 gl-border-b-solid">
+ <h1 class="gl-font-size-h1">{{ $options.i18n.title }}</h1>
+ </header>
+
+ <gl-form-group
+ label-for="ref"
+ :label="$options.i18n.refsLabel"
+ :description="$options.i18n.refsDescription"
+ >
+ <gl-form-select id="ref" name="ref" required>
+ <option value="*">{{ __('All') }}</option>
+ <option v-for="ref in refs" :key="ref" :value="ref">
+ {{ ref }}
+ </option>
+ </gl-form-select>
+ </gl-form-group>
+
+ <gl-form-group
+ label-for="gcp_region"
+ :label="$options.i18n.gcpRegionLabel"
+ :description="$options.i18n.gcpRegionDescription"
+ >
+ <gl-form-select id="gcp_region" name="gcp_region" required :list="availableRegions">
+ <option v-for="(region, index) in availableRegions" :key="index" :value="region">
+ {{ region }}
+ </option>
+ </gl-form-select>
+ </gl-form-group>
+
+ <div class="form-actions row">
+ <gl-button type="submit" category="primary" variant="confirm">
+ {{ $options.i18n.submitLabel }}
+ </gl-button>
+ <gl-button class="gl-ml-1" :href="cancelPath">{{ $options.i18n.cancelLabel }}</gl-button>
+ </div>
+ </div>
+</template>
diff --git a/app/assets/javascripts/google_cloud/components/gcp_regions_list.vue b/app/assets/javascripts/google_cloud/components/gcp_regions_list.vue
new file mode 100644
index 00000000000..1cc5a85198a
--- /dev/null
+++ b/app/assets/javascripts/google_cloud/components/gcp_regions_list.vue
@@ -0,0 +1,56 @@
+<script>
+import { GlButton, GlEmptyState, GlTable } from '@gitlab/ui';
+import { __ } from '~/locale';
+
+export default {
+ components: { GlButton, GlEmptyState, GlTable },
+ props: {
+ list: {
+ type: Array,
+ required: true,
+ },
+ createUrl: {
+ type: String,
+ required: true,
+ },
+ emptyIllustrationUrl: {
+ type: String,
+ required: true,
+ },
+ },
+ tableFields: [
+ { key: 'environment', label: __('Environment'), sortable: true },
+ { key: 'gcp_region', label: __('Region'), sortable: true },
+ ],
+ i18n: {
+ emptyStateTitle: __('No regions configured'),
+ description: __('Configure your environments to be deployed to specific geographical regions'),
+ emptyStateAction: __('Add a GCP region'),
+ configureRegions: __('Configure regions'),
+ listTitle: __('Regions'),
+ },
+};
+</script>
+
+<template>
+ <div>
+ <gl-empty-state
+ v-if="list.length === 0"
+ :title="$options.i18n.emptyStateTitle"
+ :description="$options.i18n.description"
+ :primary-button-link="createUrl"
+ :primary-button-text="$options.i18n.configureRegions"
+ />
+
+ <div v-else>
+ <h2 class="gl-font-size-h2">{{ $options.i18n.listTitle }}</h2>
+ <p>{{ $options.i18n.description }}</p>
+
+ <gl-table :items="list" :fields="$options.tableFields" />
+
+ <gl-button :href="createUrl" category="primary" variant="info">
+ {{ $options.i18n.configureRegions }}
+ </gl-button>
+ </div>
+ </div>
+</template>
diff --git a/app/assets/javascripts/google_cloud/components/home.vue b/app/assets/javascripts/google_cloud/components/home.vue
index c08d8bb7c51..e41337e2679 100644
--- a/app/assets/javascripts/google_cloud/components/home.vue
+++ b/app/assets/javascripts/google_cloud/components/home.vue
@@ -1,14 +1,18 @@
<script>
import { GlTabs, GlTab } from '@gitlab/ui';
import DeploymentsServiceTable from './deployments_service_table.vue';
+import RevokeOauth from './revoke_oauth.vue';
import ServiceAccountsList from './service_accounts_list.vue';
+import GcpRegionsList from './gcp_regions_list.vue';
export default {
components: {
GlTabs,
GlTab,
DeploymentsServiceTable,
+ RevokeOauth,
ServiceAccountsList,
+ GcpRegionsList,
},
props: {
serviceAccounts: {
@@ -19,6 +23,10 @@ export default {
type: String,
required: true,
},
+ configureGcpRegionsUrl: {
+ type: String,
+ required: true,
+ },
emptyIllustrationUrl: {
type: String,
required: true,
@@ -31,6 +39,14 @@ export default {
type: String,
required: true,
},
+ gcpRegions: {
+ type: Array,
+ required: true,
+ },
+ revokeOauthUrl: {
+ type: String,
+ required: true,
+ },
},
};
</script>
@@ -44,6 +60,15 @@ export default {
:create-url="createServiceAccountUrl"
:empty-illustration-url="emptyIllustrationUrl"
/>
+ <hr />
+ <gcp-regions-list
+ class="gl-mx-4"
+ :empty-illustration-url="emptyIllustrationUrl"
+ :create-url="configureGcpRegionsUrl"
+ :list="gcpRegions"
+ />
+ <hr v-if="revokeOauthUrl" />
+ <revoke-oauth v-if="revokeOauthUrl" :url="revokeOauthUrl" />
</gl-tab>
<gl-tab :title="__('Deployments')">
<deployments-service-table
diff --git a/app/assets/javascripts/google_cloud/components/revoke_oauth.vue b/app/assets/javascripts/google_cloud/components/revoke_oauth.vue
new file mode 100644
index 00000000000..07d966894f6
--- /dev/null
+++ b/app/assets/javascripts/google_cloud/components/revoke_oauth.vue
@@ -0,0 +1,38 @@
+<script>
+import { GlButton, GlForm } from '@gitlab/ui';
+import csrf from '~/lib/utils/csrf';
+import { s__ } from '~/locale';
+
+export const GOOGLE_CLOUD_REVOKE_TITLE = s__('GoogleCloud|Revoke authorizations');
+export const GOOGLE_CLOUD_REVOKE_DESCRIPTION = s__(
+ 'GoogleCloud|Revoke authorizations granted to GitLab. This does not invalidate service accounts.',
+);
+
+export default {
+ components: { GlButton, GlForm },
+ csrf,
+ props: {
+ url: {
+ type: String,
+ required: true,
+ },
+ },
+ i18n: {
+ title: GOOGLE_CLOUD_REVOKE_TITLE,
+ description: GOOGLE_CLOUD_REVOKE_DESCRIPTION,
+ },
+};
+</script>
+
+<template>
+ <div class="gl-mx-4">
+ <h2 class="gl-font-size-h2">{{ $options.i18n.title }}</h2>
+ <p>{{ $options.i18n.description }}</p>
+ <gl-form :action="url" method="post">
+ <input :value="$options.csrf.token" type="hidden" name="authenticity_token" />
+ <gl-button category="secondary" variant="warning" type="submit">
+ {{ $options.i18n.title }}
+ </gl-button>
+ </gl-form>
+ </div>
+</template>
diff --git a/app/assets/javascripts/google_cloud/components/service_accounts_form.vue b/app/assets/javascripts/google_cloud/components/service_accounts_form.vue
index 551783e6c50..faec94e735b 100644
--- a/app/assets/javascripts/google_cloud/components/service_accounts_form.vue
+++ b/app/assets/javascripts/google_cloud/components/service_accounts_form.vue
@@ -1,26 +1,29 @@
<script>
-import { GlButton, GlFormGroup, GlFormSelect, GlFormCheckbox } from '@gitlab/ui';
-import { __ } from '~/locale';
+import { GlButton, GlFormCheckbox, GlFormGroup, GlFormSelect } from '@gitlab/ui';
+import { s__ } from '~/locale';
export default {
+ ALL_REFS: '*',
components: { GlButton, GlFormGroup, GlFormSelect, GlFormCheckbox },
props: {
gcpProjects: { required: true, type: Array },
- environments: { required: true, type: Array },
+ refs: { required: true, type: Array },
cancelPath: { required: true, type: String },
},
i18n: {
- title: __('Create service account'),
- gcpProjectLabel: __('Google Cloud project'),
- gcpProjectDescription: __(
- 'New service account is generated for the selected Google Cloud project',
+ title: s__('GoogleCloud|Create service account'),
+ gcpProjectLabel: s__('GoogleCloud|Google Cloud project'),
+ gcpProjectDescription: s__(
+ 'GoogleCloud|New service account is generated for the selected Google Cloud project',
),
- environmentLabel: __('Environment'),
- environmentDescription: __('Generated service account is linked to the selected environment'),
- submitLabel: __('Create service account'),
- cancelLabel: __('Cancel'),
- checkboxLabel: __(
- 'I understand the responsibilities involved with managing service account keys',
+ refsLabel: s__('GoogleCloud|Refs'),
+ refsDescription: s__(
+ 'GoogleCloud|Generated service account is linked to the selected branch or tag',
+ ),
+ submitLabel: s__('GoogleCloud|Create service account'),
+ cancelLabel: s__('GoogleCloud|Cancel'),
+ checkboxLabel: s__(
+ 'GoogleCloud|I understand the responsibilities involved with managing service account keys',
),
},
};
@@ -47,18 +50,14 @@ export default {
</gl-form-select>
</gl-form-group>
<gl-form-group
- label-for="environment"
- :label="$options.i18n.environmentLabel"
- :description="$options.i18n.environmentDescription"
+ label-for="ref"
+ :label="$options.i18n.refsLabel"
+ :description="$options.i18n.refsDescription"
>
- <gl-form-select id="environment" name="environment" required>
- <option value="*">{{ __('All') }}</option>
- <option
- v-for="environment in environments"
- :key="environment.name"
- :value="environment.name"
- >
- {{ environment.name }}
+ <gl-form-select id="ref" name="ref" required>
+ <option :value="$options.ALL_REFS">{{ __('All') }}</option>
+ <option v-for="ref in refs" :key="ref" :value="ref">
+ {{ ref }}
</option>
</gl-form-select>
</gl-form-group>
diff --git a/app/assets/javascripts/google_cloud/components/service_accounts_list.vue b/app/assets/javascripts/google_cloud/components/service_accounts_list.vue
index 4db84746482..37b716d7be5 100644
--- a/app/assets/javascripts/google_cloud/components/service_accounts_list.vue
+++ b/app/assets/javascripts/google_cloud/components/service_accounts_list.vue
@@ -18,16 +18,12 @@ export default {
required: true,
},
},
- data() {
- return {
- tableFields: [
- { key: 'environment', label: __('Environment'), sortable: true },
- { key: 'gcp_project', label: __('Google Cloud Project'), sortable: true },
- { key: 'service_account_exists', label: __('Service Account'), sortable: true },
- { key: 'service_account_key_exists', label: __('Service Account Key'), sortable: true },
- ],
- };
- },
+ tableFields: [
+ { key: 'ref', label: __('Environment'), sortable: true },
+ { key: 'gcp_project', label: __('Google Cloud Project'), sortable: true },
+ { key: 'service_account_exists', label: __('Service Account'), sortable: true },
+ { key: 'service_account_key_exists', label: __('Service Account Key'), sortable: true },
+ ],
i18n: {
createServiceAccount: __('Create service account'),
found: __('✔'),
@@ -62,7 +58,7 @@ export default {
<h2 class="gl-font-size-h2">{{ $options.i18n.serviceAccountsTitle }}</h2>
<p>{{ $options.i18n.serviceAccountsDescription }}</p>
- <gl-table :items="list" :fields="tableFields">
+ <gl-table :items="list" :fields="$options.tableFields">
<template #cell(service_account_exists)="{ value }">
{{ value ? $options.i18n.found : $options.i18n.notFound }}
</template>
diff --git a/app/assets/javascripts/google_tag_manager/index.js b/app/assets/javascripts/google_tag_manager/index.js
index 55987ce64e6..f42152006d2 100644
--- a/app/assets/javascripts/google_tag_manager/index.js
+++ b/app/assets/javascripts/google_tag_manager/index.js
@@ -150,7 +150,7 @@ export const trackSaasTrialProject = () => {
});
};
-export const trackSaasTrialProjectImport = () => {
+export const trackProjectImport = () => {
if (!isSupported()) {
return;
}
@@ -159,7 +159,7 @@ export const trackSaasTrialProjectImport = () => {
importButtons.forEach((button) => {
button.addEventListener('click', () => {
const { platform } = button.dataset;
- pushEvent('saasTrialProjectImport', { saasProjectImport: platform });
+ pushEvent('projectImport', { platform });
});
});
};
@@ -231,3 +231,43 @@ export const trackTransaction = (transactionDetails) => {
pushEnhancedEcommerceEvent('EECtransactionSuccess', eventData);
};
+
+export const trackAddToCartUsageTab = () => {
+ if (!isSupported()) {
+ return;
+ }
+
+ const getStartedButton = document.querySelector('.js-buy-additional-minutes');
+ getStartedButton.addEventListener('click', () => {
+ window.dataLayer.push({
+ event: 'EECproductAddToCart',
+ ecommerce: {
+ currencyCode: 'USD',
+ add: {
+ products: [
+ {
+ name: 'CI/CD Minutes',
+ id: '0003',
+ price: '10',
+ brand: 'GitLab',
+ category: 'DevOps',
+ variant: 'add-on',
+ quantity: 1,
+ },
+ ],
+ },
+ },
+ });
+ });
+};
+
+export const trackCombinedGroupProjectForm = () => {
+ if (!isSupported()) {
+ return;
+ }
+
+ const form = document.querySelector('.js-groups-projects-form');
+ form.addEventListener('submit', () => {
+ pushEvent('combinedGroupProjectFormSubmit');
+ });
+};
diff --git a/app/assets/javascripts/gpg_badges.js b/app/assets/javascripts/gpg_badges.js
index 7964e762dac..d376c9f76ba 100644
--- a/app/assets/javascripts/gpg_badges.js
+++ b/app/assets/javascripts/gpg_badges.js
@@ -2,6 +2,7 @@ import $ from 'jquery';
import createFlash from '~/flash';
import axios from '~/lib/utils/axios_utils';
import { queryToObject } from '~/lib/utils/url_utility';
+import { loadingIconForLegacyJS } from '~/loading_icon_for_legacy_js';
import { __ } from '~/locale';
@@ -14,7 +15,7 @@ export default class GpgBadges {
const badges = $('.js-loading-gpg-badge');
- badges.html('<span class="gl-spinner gl-spinner-orange gl-spinner-sm"></span>');
+ badges.html(loadingIconForLegacyJS());
badges.children().attr('aria-label', __('Loading'));
const displayError = () =>
diff --git a/app/assets/javascripts/graphql_shared/constants.js b/app/assets/javascripts/graphql_shared/constants.js
index 3b36c3e6ac5..4ebb49b4756 100644
--- a/app/assets/javascripts/graphql_shared/constants.js
+++ b/app/assets/javascripts/graphql_shared/constants.js
@@ -1,9 +1,11 @@
export const MINIMUM_SEARCH_LENGTH = 3;
+export const TYPE_BOARD = 'Board';
export const TYPE_CI_RUNNER = 'Ci::Runner';
export const TYPE_CRM_CONTACT = 'CustomerRelations::Contact';
export const TYPE_DISCUSSION = 'Discussion';
export const TYPE_EPIC = 'Epic';
+export const TYPE_EPIC_BOARD = 'Boards::EpicBoard';
export const TYPE_GROUP = 'Group';
export const TYPE_ISSUE = 'Issue';
export const TYPE_ITERATION = 'Iteration';
diff --git a/app/assets/javascripts/graphql_shared/possibleTypes.json b/app/assets/javascripts/graphql_shared/possibleTypes.json
index 9a24d2a3afc..01116067887 100644
--- a/app/assets/javascripts/graphql_shared/possibleTypes.json
+++ b/app/assets/javascripts/graphql_shared/possibleTypes.json
@@ -1 +1 @@
-{"AlertManagementIntegration":["AlertManagementHttpIntegration","AlertManagementPrometheusIntegration"],"CurrentUserTodos":["BoardEpic","Design","Epic","EpicIssue","Issue","MergeRequest"],"DependencyLinkMetadata":["NugetDependencyLinkMetadata"],"DesignFields":["Design","DesignAtVersion"],"Entry":["Blob","Submodule","TreeEntry"],"Eventable":["BoardEpic","Epic"],"Issuable":["Epic","Issue","MergeRequest"],"JobNeedUnion":["CiBuildNeed","CiJob"],"MemberInterface":["GroupMember","ProjectMember"],"NoteableInterface":["AlertManagementAlert","BoardEpic","Design","Epic","EpicIssue","Issue","MergeRequest","Snippet","Vulnerability"],"NoteableType":["Design","Issue","MergeRequest"],"OrchestrationPolicy":["ScanExecutionPolicy","ScanResultPolicy"],"PackageFileMetadata":["ConanFileMetadata","HelmFileMetadata"],"PackageMetadata":["ComposerMetadata","ConanMetadata","MavenMetadata","NugetMetadata","PypiMetadata"],"ResolvableInterface":["Discussion","Note"],"Service":["BaseService","JiraService"],"TimeboxReportInterface":["Iteration","Milestone"],"User":["MergeRequestAssignee","MergeRequestReviewer","UserCore"],"VulnerabilityDetail":["VulnerabilityDetailBase","VulnerabilityDetailBoolean","VulnerabilityDetailCode","VulnerabilityDetailCommit","VulnerabilityDetailDiff","VulnerabilityDetailFileLocation","VulnerabilityDetailInt","VulnerabilityDetailList","VulnerabilityDetailMarkdown","VulnerabilityDetailModuleLocation","VulnerabilityDetailTable","VulnerabilityDetailText","VulnerabilityDetailUrl"],"VulnerabilityLocation":["VulnerabilityLocationClusterImageScanning","VulnerabilityLocationContainerScanning","VulnerabilityLocationCoverageFuzzing","VulnerabilityLocationDast","VulnerabilityLocationDependencyScanning","VulnerabilityLocationGeneric","VulnerabilityLocationSast","VulnerabilityLocationSecretDetection"]}
+{"AlertManagementIntegration":["AlertManagementHttpIntegration","AlertManagementPrometheusIntegration"],"CurrentUserTodos":["BoardEpic","Design","Epic","EpicIssue","Issue","MergeRequest"],"DependencyLinkMetadata":["NugetDependencyLinkMetadata"],"DesignFields":["Design","DesignAtVersion"],"Entry":["Blob","Submodule","TreeEntry"],"Eventable":["BoardEpic","Epic"],"Issuable":["Epic","Issue","MergeRequest","WorkItem"],"JobNeedUnion":["CiBuildNeed","CiJob"],"MemberInterface":["GroupMember","ProjectMember"],"NoteableInterface":["AlertManagementAlert","BoardEpic","Design","Epic","EpicIssue","Issue","MergeRequest","Snippet","Vulnerability"],"NoteableType":["Design","Issue","MergeRequest"],"OrchestrationPolicy":["ScanExecutionPolicy","ScanResultPolicy"],"PackageFileMetadata":["ConanFileMetadata","HelmFileMetadata"],"PackageMetadata":["ComposerMetadata","ConanMetadata","MavenMetadata","NugetMetadata","PypiMetadata"],"ResolvableInterface":["Discussion","Note"],"Service":["BaseService","JiraService"],"TimeboxReportInterface":["Iteration","Milestone"],"Todoable":["AlertManagementAlert","BoardEpic","Commit","Design","Epic","EpicIssue","Issue","MergeRequest"],"User":["MergeRequestAssignee","MergeRequestAuthor","MergeRequestParticipant","MergeRequestReviewer","UserCore"],"VulnerabilityDetail":["VulnerabilityDetailBase","VulnerabilityDetailBoolean","VulnerabilityDetailCode","VulnerabilityDetailCommit","VulnerabilityDetailDiff","VulnerabilityDetailFileLocation","VulnerabilityDetailInt","VulnerabilityDetailList","VulnerabilityDetailMarkdown","VulnerabilityDetailModuleLocation","VulnerabilityDetailTable","VulnerabilityDetailText","VulnerabilityDetailUrl"],"VulnerabilityLocation":["VulnerabilityLocationClusterImageScanning","VulnerabilityLocationContainerScanning","VulnerabilityLocationCoverageFuzzing","VulnerabilityLocationDast","VulnerabilityLocationDependencyScanning","VulnerabilityLocationGeneric","VulnerabilityLocationSast","VulnerabilityLocationSecretDetection"]} \ No newline at end of file
diff --git a/app/assets/javascripts/graphql_shared/queries/users_search_with_mr_permissions.graphql b/app/assets/javascripts/graphql_shared/queries/users_search_with_mr_permissions.graphql
new file mode 100644
index 00000000000..2bd016feb19
--- /dev/null
+++ b/app/assets/javascripts/graphql_shared/queries/users_search_with_mr_permissions.graphql
@@ -0,0 +1,24 @@
+#import "../fragments/user.fragment.graphql"
+#import "~/graphql_shared/fragments/user_availability.fragment.graphql"
+
+query projectUsersSearchWithMRPermissions(
+ $search: String!
+ $fullPath: ID!
+ $mergeRequestId: MergeRequestID!
+) {
+ workspace: project(fullPath: $fullPath) {
+ id
+ users: projectMembers(search: $search, relations: [DIRECT, INHERITED, INVITED_GROUPS]) {
+ nodes {
+ id
+ mergeRequestInteraction(id: $mergeRequestId) {
+ canMerge
+ }
+ user {
+ ...User
+ ...UserAvailability
+ }
+ }
+ }
+ }
+}
diff --git a/app/assets/javascripts/groups/components/item_stats.vue b/app/assets/javascripts/groups/components/item_stats.vue
index c24eeed9f03..3620c884c5f 100644
--- a/app/assets/javascripts/groups/components/item_stats.vue
+++ b/app/assets/javascripts/groups/components/item_stats.vue
@@ -68,7 +68,7 @@ export default {
/>
<item-stats-value
v-if="isGroup"
- :title="__('Members')"
+ :title="__('Direct members')"
:value="item.memberCount"
css-class="number-users gl-ml-5"
icon-name="users"
diff --git a/app/assets/javascripts/header_search/components/header_search_autocomplete_items.vue b/app/assets/javascripts/header_search/components/header_search_autocomplete_items.vue
index 9f4f4768247..c0e2c18bece 100644
--- a/app/assets/javascripts/header_search/components/header_search_autocomplete_items.vue
+++ b/app/assets/javascripts/header_search/components/header_search_autocomplete_items.vue
@@ -4,20 +4,28 @@ import {
GlDropdownSectionHeader,
GlDropdownDivider,
GlAvatar,
+ GlAlert,
GlLoadingIcon,
GlSafeHtmlDirective as SafeHtml,
} from '@gitlab/ui';
import { mapState, mapGetters } from 'vuex';
+import { s__ } from '~/locale';
import highlight from '~/lib/utils/highlight';
import { GROUPS_CATEGORY, PROJECTS_CATEGORY, LARGE_AVATAR_PX, SMALL_AVATAR_PX } from '../constants';
export default {
name: 'HeaderSearchAutocompleteItems',
+ i18n: {
+ autocompleteErrorMessage: s__(
+ 'GlobalSearch|There was an error fetching search autocomplete suggestions.',
+ ),
+ },
components: {
GlDropdownItem,
GlDropdownSectionHeader,
GlDropdownDivider,
GlAvatar,
+ GlAlert,
GlLoadingIcon,
},
directives: {
@@ -31,7 +39,7 @@ export default {
},
},
computed: {
- ...mapState(['search', 'loading']),
+ ...mapState(['search', 'loading', 'autocompleteError']),
...mapGetters(['autocompleteGroupedSearchOptions']),
},
watch: {
@@ -93,5 +101,13 @@ export default {
</div>
</template>
<gl-loading-icon v-else size="lg" class="my-4" />
+ <gl-alert
+ v-if="autocompleteError"
+ class="gl-text-body gl-mt-2"
+ :dismissible="false"
+ variant="danger"
+ >
+ {{ $options.i18n.autocompleteErrorMessage }}
+ </gl-alert>
</div>
</template>
diff --git a/app/assets/javascripts/header_search/components/header_search_default_items.vue b/app/assets/javascripts/header_search/components/header_search_default_items.vue
index 53e63bc6cca..04deaba7b0f 100644
--- a/app/assets/javascripts/header_search/components/header_search_default_items.vue
+++ b/app/assets/javascripts/header_search/components/header_search_default_items.vue
@@ -24,8 +24,8 @@ export default {
...mapGetters(['defaultSearchOptions']),
sectionHeader() {
return (
- this.searchContext.project?.name ||
- this.searchContext.group?.name ||
+ this.searchContext?.project?.name ||
+ this.searchContext?.group?.name ||
this.$options.i18n.allGitLab
);
},
diff --git a/app/assets/javascripts/header_search/index.js b/app/assets/javascripts/header_search/index.js
index d7e21f55ea5..4af8513ecdb 100644
--- a/app/assets/javascripts/header_search/index.js
+++ b/app/assets/javascripts/header_search/index.js
@@ -5,7 +5,7 @@ import createStore from './store';
Vue.use(Translate);
-export const initHeaderSearchApp = () => {
+export const initHeaderSearchApp = (search = '') => {
const el = document.getElementById('js-header-search');
if (!el) {
@@ -18,7 +18,7 @@ export const initHeaderSearchApp = () => {
return new Vue({
el,
- store: createStore({ searchPath, issuesPath, mrPath, autocompletePath, searchContext }),
+ store: createStore({ searchPath, issuesPath, mrPath, autocompletePath, searchContext, search }),
render(createElement) {
return createElement(HeaderSearchApp);
},
diff --git a/app/assets/javascripts/header_search/store/actions.js b/app/assets/javascripts/header_search/store/actions.js
index 0ba956f3ed1..ee4c312fed0 100644
--- a/app/assets/javascripts/header_search/store/actions.js
+++ b/app/assets/javascripts/header_search/store/actions.js
@@ -1,6 +1,4 @@
-import createFlash from '~/flash';
import axios from '~/lib/utils/axios_utils';
-import { __ } from '~/locale';
import * as types from './mutation_types';
export const fetchAutocompleteOptions = ({ commit, getters }) => {
@@ -10,7 +8,6 @@ export const fetchAutocompleteOptions = ({ commit, getters }) => {
.then(({ data }) => commit(types.RECEIVE_AUTOCOMPLETE_SUCCESS, data))
.catch(() => {
commit(types.RECEIVE_AUTOCOMPLETE_ERROR);
- createFlash({ message: __('There was an error fetching search autocomplete suggestions') });
});
};
diff --git a/app/assets/javascripts/header_search/store/getters.js b/app/assets/javascripts/header_search/store/getters.js
index a1348a8aa3f..87dec95153f 100644
--- a/app/assets/javascripts/header_search/store/getters.js
+++ b/app/assets/javascripts/header_search/store/getters.js
@@ -17,9 +17,12 @@ export const searchQuery = (state) => {
{
search: state.search,
nav_source: 'navbar',
- project_id: state.searchContext.project?.id,
- group_id: state.searchContext.group?.id,
+ project_id: state.searchContext?.project?.id,
+ group_id: state.searchContext?.group?.id,
scope: state.searchContext?.scope,
+ snippets: state.searchContext?.for_snippets ? true : null,
+ search_code: state.searchContext?.code_search ? true : null,
+ repository_ref: state.searchContext?.ref,
},
isNil,
);
@@ -31,7 +34,7 @@ export const autocompleteQuery = (state) => {
const query = omitBy(
{
term: state.search,
- project_id: state.searchContext.project?.id,
+ project_id: state.searchContext?.project?.id,
project_ref: state.searchContext?.ref,
},
isNil,
@@ -42,16 +45,16 @@ export const autocompleteQuery = (state) => {
export const scopedIssuesPath = (state) => {
return (
- state.searchContext.project_metadata?.issues_path ||
- state.searchContext.group_metadata?.issues_path ||
+ state.searchContext?.project_metadata?.issues_path ||
+ state.searchContext?.group_metadata?.issues_path ||
state.issuesPath
);
};
export const scopedMRPath = (state) => {
return (
- state.searchContext.project_metadata?.mr_path ||
- state.searchContext.group_metadata?.mr_path ||
+ state.searchContext?.project_metadata?.mr_path ||
+ state.searchContext?.group_metadata?.mr_path ||
state.mrPath
);
};
@@ -96,6 +99,9 @@ export const projectUrl = (state) => {
project_id: state.searchContext?.project?.id,
group_id: state.searchContext?.group?.id,
scope: state.searchContext?.scope,
+ snippets: state.searchContext?.for_snippets ? true : null,
+ search_code: state.searchContext?.code_search ? true : null,
+ repository_ref: state.searchContext?.ref,
},
isNil,
);
@@ -110,6 +116,9 @@ export const groupUrl = (state) => {
nav_source: 'navbar',
group_id: state.searchContext?.group?.id,
scope: state.searchContext?.scope,
+ snippets: state.searchContext?.for_snippets ? true : null,
+ search_code: state.searchContext?.code_search ? true : null,
+ repository_ref: state.searchContext?.ref,
},
isNil,
);
@@ -123,6 +132,9 @@ export const allUrl = (state) => {
search: state.search,
nav_source: 'navbar',
scope: state.searchContext?.scope,
+ snippets: state.searchContext?.for_snippets ? true : null,
+ search_code: state.searchContext?.code_search ? true : null,
+ repository_ref: state.searchContext?.ref,
},
isNil,
);
@@ -133,19 +145,19 @@ export const allUrl = (state) => {
export const scopedSearchOptions = (state, getters) => {
const options = [];
- if (state.searchContext.project) {
+ if (state.searchContext?.project) {
options.push({
html_id: 'scoped-in-project',
- scope: state.searchContext.project.name,
+ scope: state.searchContext.project?.name || '',
description: MSG_IN_PROJECT,
url: getters.projectUrl,
});
}
- if (state.searchContext.group) {
+ if (state.searchContext?.group) {
options.push({
html_id: 'scoped-in-group',
- scope: state.searchContext.group.name,
+ scope: state.searchContext.group?.name || '',
description: MSG_IN_GROUP,
url: getters.groupUrl,
});
diff --git a/app/assets/javascripts/header_search/store/index.js b/app/assets/javascripts/header_search/store/index.js
index 06cca4be8a7..b83433c5b49 100644
--- a/app/assets/javascripts/header_search/store/index.js
+++ b/app/assets/javascripts/header_search/store/index.js
@@ -13,11 +13,12 @@ export const getStoreConfig = ({
mrPath,
autocompletePath,
searchContext,
+ search,
}) => ({
actions,
getters,
mutations,
- state: createState({ searchPath, issuesPath, mrPath, autocompletePath, searchContext }),
+ state: createState({ searchPath, issuesPath, mrPath, autocompletePath, searchContext, search }),
});
const createStore = (config) => new Vuex.Store(getStoreConfig(config));
diff --git a/app/assets/javascripts/header_search/store/mutations.js b/app/assets/javascripts/header_search/store/mutations.js
index 26b4a8854fe..92948bec515 100644
--- a/app/assets/javascripts/header_search/store/mutations.js
+++ b/app/assets/javascripts/header_search/store/mutations.js
@@ -4,19 +4,23 @@ export default {
[types.REQUEST_AUTOCOMPLETE](state) {
state.loading = true;
state.autocompleteOptions = [];
+ state.autocompleteError = false;
},
[types.RECEIVE_AUTOCOMPLETE_SUCCESS](state, data) {
state.loading = false;
state.autocompleteOptions = data.map((d, i) => {
return { html_id: `autocomplete-${d.category}-${i}`, ...d };
});
+ state.autocompleteError = false;
},
[types.RECEIVE_AUTOCOMPLETE_ERROR](state) {
state.loading = false;
state.autocompleteOptions = [];
+ state.autocompleteError = true;
},
[types.CLEAR_AUTOCOMPLETE](state) {
state.autocompleteOptions = [];
+ state.autocompleteError = false;
},
[types.SET_SEARCH](state, value) {
state.search = value;
diff --git a/app/assets/javascripts/header_search/store/state.js b/app/assets/javascripts/header_search/store/state.js
index 3d4073f0583..bebdbc7b92e 100644
--- a/app/assets/javascripts/header_search/store/state.js
+++ b/app/assets/javascripts/header_search/store/state.js
@@ -1,11 +1,19 @@
-const createState = ({ searchPath, issuesPath, mrPath, autocompletePath, searchContext }) => ({
+const createState = ({
searchPath,
issuesPath,
mrPath,
autocompletePath,
searchContext,
- search: '',
+ search,
+}) => ({
+ searchPath,
+ issuesPath,
+ mrPath,
+ autocompletePath,
+ searchContext,
+ search,
autocompleteOptions: [],
+ autocompleteError: false,
loading: false,
});
export default createState;
diff --git a/app/assets/javascripts/ide/components/file_templates/bar.vue b/app/assets/javascripts/ide/components/file_templates/bar.vue
index 0803925104d..0921b5a5424 100644
--- a/app/assets/javascripts/ide/components/file_templates/bar.vue
+++ b/app/assets/javascripts/ide/components/file_templates/bar.vue
@@ -1,17 +1,46 @@
<script>
-import { GlButton } from '@gitlab/ui';
+import { GlButton, GlDropdown, GlDropdownItem, GlLoadingIcon, GlSearchBoxByType } from '@gitlab/ui';
import { mapActions, mapGetters, mapState } from 'vuex';
-import Dropdown from './dropdown.vue';
+import { __ } from '~/locale';
+
+const barLabel = __('File templates');
+const templateListDropdownLabel = __('Choose a template...');
+const templateTypesDropdownLabel = __('Choose a type...');
+const undoButtonText = __('Undo');
export default {
+ i18n: {
+ barLabel,
+ templateListDropdownLabel,
+ templateTypesDropdownLabel,
+ undoButtonText,
+ },
components: {
- Dropdown,
GlButton,
+ GlDropdown,
+ GlDropdownItem,
+ GlLoadingIcon,
+ GlSearchBoxByType,
+ },
+ data() {
+ return {
+ search: '',
+ };
},
computed: {
...mapGetters(['activeFile']),
...mapGetters('fileTemplates', ['templateTypes']),
- ...mapState('fileTemplates', ['selectedTemplateType', 'updateSuccess']),
+ ...mapState('fileTemplates', [
+ 'selectedTemplateType',
+ 'updateSuccess',
+ 'templates',
+ 'isLoading',
+ ]),
+ filteredTemplateTypes() {
+ return this.templates.filter((t) => {
+ return t.name.toLowerCase().includes(this.search.toLowerCase());
+ });
+ },
showTemplatesDropdown() {
return Object.keys(this.selectedTemplateType).length > 0;
},
@@ -26,6 +55,7 @@ export default {
...mapActions('fileTemplates', [
'setSelectedTemplateType',
'fetchTemplate',
+ 'fetchTemplateTypes',
'undoFileTemplate',
]),
setInitialType() {
@@ -50,27 +80,46 @@ export default {
<template>
<div
- class="d-flex align-items-center ide-file-templates qa-file-templates-bar gl-relative gl-z-index-1"
+ class="gl-display-flex gl-align-items-center ide-file-templates qa-file-templates-bar gl-relative gl-z-index-1"
>
- <strong class="gl-mr-3"> {{ __('File templates') }} </strong>
- <dropdown
- :data="templateTypes"
- :label="selectedTemplateType.name || __('Choose a type...')"
- class="mr-2"
- @click="selectTemplateType"
- />
- <dropdown
+ <strong class="gl-mr-3"> {{ $options.i18n.barLabel }} </strong>
+ <gl-dropdown
+ class="gl-mr-6"
+ :text="selectedTemplateType.name || $options.i18n.templateTypesDropdownLabel"
+ >
+ <gl-dropdown-item
+ v-for="template in templateTypes"
+ :key="template.key"
+ @click.prevent="selectTemplateType(template)"
+ >
+ {{ template.name }}
+ </gl-dropdown-item>
+ </gl-dropdown>
+ <gl-dropdown
v-if="showTemplatesDropdown"
- :label="__('Choose a template...')"
- :is-async-data="true"
- :searchable="true"
- :title="__('File templates')"
- class="mr-2 qa-file-template-dropdown"
- @click="selectTemplate"
- />
+ class="gl-mr-6 qa-file-template-dropdown"
+ :text="$options.i18n.templateListDropdownLabel"
+ @show="fetchTemplateTypes"
+ >
+ <template #header>
+ <gl-search-box-by-type v-model.trim="search" data-qa-selector="dropdown_filter_input" />
+ </template>
+ <div>
+ <gl-loading-icon v-if="isLoading" />
+ <template v-else>
+ <gl-dropdown-item
+ v-for="template in filteredTemplateTypes"
+ :key="template.key"
+ @click="selectTemplate(template)"
+ >
+ {{ template.name }}
+ </gl-dropdown-item>
+ </template>
+ </div>
+ </gl-dropdown>
<transition name="fade">
<gl-button v-show="updateSuccess" category="secondary" variant="default" @click="undo">
- {{ __('Undo') }}
+ {{ $options.i18n.undoButtonText }}
</gl-button>
</transition>
</div>
diff --git a/app/assets/javascripts/ide/components/file_templates/dropdown.vue b/app/assets/javascripts/ide/components/file_templates/dropdown.vue
index ec61e3374d7..e8b42ac9490 100644
--- a/app/assets/javascripts/ide/components/file_templates/dropdown.vue
+++ b/app/assets/javascripts/ide/components/file_templates/dropdown.vue
@@ -84,7 +84,7 @@ export default {
v-model="search"
:placeholder="__('Filter...')"
type="search"
- class="dropdown-input-field qa-dropdown-filter-input"
+ class="dropdown-input-field"
/>
<gl-icon name="search" class="dropdown-input-search" />
</div>
diff --git a/app/assets/javascripts/ide/components/new_dropdown/modal.vue b/app/assets/javascripts/ide/components/new_dropdown/modal.vue
index 1c5a00568eb..e3c230f7660 100644
--- a/app/assets/javascripts/ide/components/new_dropdown/modal.vue
+++ b/app/assets/javascripts/ide/components/new_dropdown/modal.vue
@@ -6,6 +6,10 @@ import { __, sprintf } from '~/locale';
import { modalTypes } from '../../constants';
import { trimPathComponents, getPathParent } from '../../utils';
+const i18n = {
+ cancelButtonText: __('Cancel'),
+};
+
export default {
components: {
GlModal,
@@ -43,6 +47,18 @@ export default {
return __('Create file');
},
+ actionPrimary() {
+ return {
+ text: this.buttonLabel,
+ attributes: [{ variant: 'confirm' }],
+ };
+ },
+ actionCancel() {
+ return {
+ text: i18n.cancelButtonText,
+ attributes: [{ variant: 'default' }],
+ };
+ },
isCreatingNewFile() {
return this.modalType === modalTypes.blob;
},
@@ -136,11 +152,11 @@ export default {
data-qa-selector="new_file_modal"
data-testid="ide-new-entry"
:title="modalTitle"
- :ok-title="buttonLabel"
- ok-variant="success"
size="lg"
- @ok="submitForm"
- @hide="resetData"
+ :action-primary="actionPrimary"
+ :action-cancel="actionCancel"
+ @primary="submitForm"
+ @cancel="resetData"
>
<div class="form-group row">
<label class="label-bold col-form-label col-sm-2"> {{ __('Name') }} </label>
diff --git a/app/assets/javascripts/ide/components/repo_editor.vue b/app/assets/javascripts/ide/components/repo_editor.vue
index 05493db1dff..f14d86114b8 100644
--- a/app/assets/javascripts/ide/components/repo_editor.vue
+++ b/app/assets/javascripts/ide/components/repo_editor.vue
@@ -147,6 +147,9 @@ export default {
fileType() {
return this.previewMode?.id || '';
},
+ showTabs() {
+ return !this.shouldHideEditor && this.isEditModeActive && this.previewMode;
+ },
},
watch: {
'file.name': {
@@ -194,6 +197,9 @@ export default {
this.refreshEditorDimensions();
}
},
+ showTabs() {
+ this.$nextTick(() => this.refreshEditorDimensions());
+ },
rightPaneIsOpen() {
this.refreshEditorDimensions();
},
@@ -410,7 +416,7 @@ export default {
}
},
refreshEditorDimensions() {
- if (this.showEditor) {
+ if (this.showEditor && this.editor) {
this.editor.updateDimensions();
}
},
@@ -495,7 +501,7 @@ export default {
<template>
<div id="ide" class="blob-viewer-container blob-editor-container">
- <div v-if="!shouldHideEditor && isEditModeActive" class="ide-mode-tabs clearfix">
+ <div v-if="showTabs" class="ide-mode-tabs clearfix">
<ul class="nav-links float-left border-bottom-0">
<li :class="editTabCSS">
<a
@@ -506,7 +512,7 @@ export default {
>{{ __('Edit') }}</a
>
</li>
- <li v-if="previewMode" :class="previewTabCSS">
+ <li :class="previewTabCSS">
<a
href="javascript:void(0);"
role="button"
diff --git a/app/assets/javascripts/import_entities/import_projects/components/import_projects_table.vue b/app/assets/javascripts/import_entities/import_projects/components/import_projects_table.vue
index b9f0b5012ac..bd0f4cd5dd7 100644
--- a/app/assets/javascripts/import_entities/import_projects/components/import_projects_table.vue
+++ b/app/assets/javascripts/import_entities/import_projects/components/import_projects_table.vue
@@ -137,7 +137,7 @@ export default {
<gl-form-input
data-qa-selector="githubish_import_filter_field"
name="filter"
- :placeholder="__('Filter your repositories by name')"
+ :placeholder="__('Filter by name')"
autofocus
size="lg"
@keyup.enter="setFilter($event.target.value)"
diff --git a/app/assets/javascripts/incidents/components/incidents_list.vue b/app/assets/javascripts/incidents/components/incidents_list.vue
index 7a904bdb6ad..324797ad645 100644
--- a/app/assets/javascripts/incidents/components/incidents_list.vue
+++ b/app/assets/javascripts/incidents/components/incidents_list.vue
@@ -1,5 +1,6 @@
<script>
import {
+ GlLink,
GlLoadingIcon,
GlTable,
GlAvatarsInline,
@@ -24,9 +25,11 @@ import {
} from '~/vue_shared/components/paginated_table_with_search_and_tabs/constants';
import PaginatedTableWithSearchAndTabs from '~/vue_shared/components/paginated_table_with_search_and_tabs/paginated_table_with_search_and_tabs.vue';
import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
+import TooltipOnTruncate from '~/vue_shared/components/tooltip_on_truncate/tooltip_on_truncate.vue';
import {
I18N,
INCIDENT_STATUS_TABS,
+ ESCALATION_STATUSES,
TH_CREATED_AT_TEST_ID,
TH_INCIDENT_SLA_TEST_ID,
TH_SEVERITY_TEST_ID,
@@ -38,7 +41,7 @@ import {
import getIncidentsCountByStatus from '../graphql/queries/get_count_by_status.query.graphql';
import getIncidents from '../graphql/queries/get_incidents.query.graphql';
-const MAX_VISIBLE_ASSIGNEES = 4;
+const MAX_VISIBLE_ASSIGNEES = 3;
export default {
trackIncidentCreateNewOptions,
@@ -49,7 +52,7 @@ export default {
{
key: 'severity',
label: s__('IncidentManagement|Severity'),
- thClass: `${thClass} w-15p`,
+ thClass: `${thClass} gl-w-15p`,
tdClass: `${tdClass} sortable-cell`,
actualSortKey: 'SEVERITY',
sortable: true,
@@ -62,6 +65,12 @@ export default {
tdClass,
},
{
+ key: 'escalationStatus',
+ label: s__('IncidentManagement|Status'),
+ thClass: `${thClass} gl-w-eighth gl-pointer-events-none`,
+ tdClass,
+ },
+ {
key: 'createdAt',
label: s__('IncidentManagement|Date created'),
thClass: `${thClass} gl-w-eighth`,
@@ -73,7 +82,7 @@ export default {
{
key: 'incidentSla',
label: s__('IncidentManagement|Time to SLA'),
- thClass: `gl-text-right gl-w-eighth`,
+ thClass: `gl-text-right gl-w-10p`,
tdClass: `${tdClass} gl-text-right`,
thAttr: TH_INCIDENT_SLA_TEST_ID,
actualSortKey: 'SLA_DUE_AT',
@@ -83,13 +92,13 @@ export default {
{
key: 'assignees',
label: s__('IncidentManagement|Assignees'),
- thClass: 'gl-pointer-events-none w-15p',
+ thClass: 'gl-pointer-events-none gl-w-15',
tdClass,
},
{
key: 'published',
label: s__('IncidentManagement|Published'),
- thClass: `${thClass} w-15p`,
+ thClass: `${thClass} gl-w-15`,
tdClass: `${tdClass} sortable-cell`,
actualSortKey: 'PUBLISHED',
sortable: true,
@@ -98,6 +107,7 @@ export default {
],
MAX_VISIBLE_ASSIGNEES,
components: {
+ GlLink,
GlLoadingIcon,
GlTable,
GlAvatarsInline,
@@ -112,6 +122,7 @@ export default {
GlEmptyState,
SeverityToken,
PaginatedTableWithSearchAndTabs,
+ TooltipOnTruncate,
},
directives: {
GlTooltip: GlTooltipDirective,
@@ -129,6 +140,7 @@ export default {
'assigneeUsernameQuery',
'slaFeatureAvailable',
'canCreateIncident',
+ 'incidentEscalationsAvailable',
],
apollo: {
incidents: {
@@ -222,6 +234,7 @@ export default {
const isHidden = {
published: !this.publishedAvailable,
incidentSla: !this.slaFeatureAvailable,
+ escalationStatus: !this.incidentEscalationsAvailable,
};
return this.$options.fields.filter(({ key }) => !isHidden[key]);
@@ -260,7 +273,7 @@ export default {
return Boolean(assignees.nodes?.length);
},
navigateToIncidentDetails({ iid }) {
- return visitUrl(joinPaths(this.issuePath, INCIDENT_DETAILS_PATH, iid));
+ return visitUrl(this.showIncidentLink({ iid }));
},
navigateToCreateNewIncident() {
const { category, action } = this.$options.trackIncidentCreateNewOptions;
@@ -283,6 +296,12 @@ export default {
getSeverity(severity) {
return INCIDENT_SEVERITY[severity];
},
+ getEscalationStatus(escalationStatus) {
+ return ESCALATION_STATUSES[escalationStatus] || this.$options.i18n.noEscalationStatus;
+ },
+ showIncidentLink({ iid }) {
+ return joinPaths(this.issuePath, INCIDENT_DETAILS_PATH, iid);
+ },
pageChanged(pagination) {
this.pagination = pagination;
},
@@ -370,7 +389,14 @@ export default {
<template #cell(title)="{ item }">
<div :class="{ 'gl-display-flex gl-align-items-center': item.state === 'closed' }">
- <div class="gl-max-w-full text-truncate" :title="item.title">{{ item.title }}</div>
+ <gl-link
+ v-gl-tooltip
+ :title="item.title"
+ data-testid="incident-link"
+ :href="showIncidentLink(item)"
+ >
+ {{ item.title }}
+ </gl-link>
<gl-icon
v-if="item.state === 'closed'"
name="issue-close"
@@ -381,8 +407,21 @@ export default {
</div>
</template>
+ <template v-if="incidentEscalationsAvailable" #cell(escalationStatus)="{ item }">
+ <tooltip-on-truncate
+ :title="getEscalationStatus(item.escalationStatus)"
+ data-testid="incident-escalation-status"
+ class="gl-display-block gl-text-truncate"
+ >
+ {{ getEscalationStatus(item.escalationStatus) }}
+ </tooltip-on-truncate>
+ </template>
+
<template #cell(createdAt)="{ item }">
- <time-ago-tooltip :time="item.createdAt" />
+ <time-ago-tooltip
+ :time="item.createdAt"
+ class="gl-display-block gl-max-w-full gl-text-truncate"
+ />
</template>
<template v-if="slaFeatureAvailable" #cell(incidentSla)="{ item }">
@@ -392,6 +431,7 @@ export default {
:project-path="projectPath"
:sla-due-at="item.slaDueAt"
data-testid="incident-sla"
+ class="gl-display-block gl-max-w-full gl-text-truncate"
/>
</template>
@@ -432,6 +472,7 @@ export default {
:un-published="$options.i18n.unPublished"
/>
</template>
+
<template #table-busy>
<gl-loading-icon size="lg" color="dark" class="mt-3" />
</template>
diff --git a/app/assets/javascripts/incidents/constants.js b/app/assets/javascripts/incidents/constants.js
index 23909ae3b6c..21cdbef05a1 100644
--- a/app/assets/javascripts/incidents/constants.js
+++ b/app/assets/javascripts/incidents/constants.js
@@ -7,6 +7,7 @@ export const I18N = {
unassigned: s__('IncidentManagement|Unassigned'),
createIncidentBtnLabel: s__('IncidentManagement|Create incident'),
unPublished: s__('IncidentManagement|Unpublished'),
+ noEscalationStatus: s__('IncidentManagement|None'),
emptyState: {
title: s__('IncidentManagement|Display your incidents in a dedicated view'),
emptyClosedTabTitle: s__('IncidentManagement|There are no closed incidents'),
@@ -37,6 +38,12 @@ export const INCIDENT_STATUS_TABS = [
},
];
+export const ESCALATION_STATUSES = {
+ TRIGGERED: s__('AlertManagement|Triggered'),
+ ACKNOWLEDGED: s__('AlertManagement|Acknowledged'),
+ RESOLVED: s__('AlertManagement|Resolved'),
+};
+
export const DEFAULT_PAGE_SIZE = 20;
export const TH_CREATED_AT_TEST_ID = { 'data-testid': 'incident-management-created-at-sort' };
export const TH_SEVERITY_TEST_ID = { 'data-testid': 'incident-management-severity-sort' };
diff --git a/app/assets/javascripts/incidents/graphql/fragments/incident_fields.fragment.graphql b/app/assets/javascripts/incidents/graphql/fragments/incident_fields.fragment.graphql
index faa68d37088..b72941966c6 100644
--- a/app/assets/javascripts/incidents/graphql/fragments/incident_fields.fragment.graphql
+++ b/app/assets/javascripts/incidents/graphql/fragments/incident_fields.fragment.graphql
@@ -1,4 +1,5 @@
# eslint-disable-next-line @graphql-eslint/require-id-when-available
fragment IncidentFields on Issue {
severity
+ escalationStatus
}
diff --git a/app/assets/javascripts/incidents/list.js b/app/assets/javascripts/incidents/list.js
index 1d40f1093a4..c0f16a43d5c 100644
--- a/app/assets/javascripts/incidents/list.js
+++ b/app/assets/javascripts/incidents/list.js
@@ -46,6 +46,7 @@ export default () => {
assigneeUsernameQuery,
slaFeatureAvailable: parseBoolean(slaFeatureAvailable),
canCreateIncident: parseBoolean(canCreateIncident),
+ incidentEscalationsAvailable: parseBoolean(gon?.features?.incidentEscalations),
},
apolloProvider,
render(createElement) {
diff --git a/app/assets/javascripts/integrations/constants.js b/app/assets/javascripts/integrations/constants.js
index 004601bc0a3..c5ed5bb08a9 100644
--- a/app/assets/javascripts/integrations/constants.js
+++ b/app/assets/javascripts/integrations/constants.js
@@ -1,6 +1,7 @@
import { s__, __ } from '~/locale';
export const integrationLevels = {
+ PROJECT: 'project',
GROUP: 'group',
INSTANCE: 'instance',
};
@@ -24,3 +25,15 @@ export const I18N_SUCCESSFUL_CONNECTION_MESSAGE = s__('Integrations|Connection s
export const settingsTabTitle = __('Settings');
export const overridesTabTitle = s__('Integrations|Projects using custom settings');
+
+export const integrationFormSections = {
+ CONNECTION: 'connection',
+ JIRA_TRIGGER: 'jira_trigger',
+ JIRA_ISSUES: 'jira_issues',
+};
+
+export const integrationFormSectionComponents = {
+ [integrationFormSections.CONNECTION]: 'IntegrationSectionConnection',
+ [integrationFormSections.JIRA_TRIGGER]: 'IntegrationSectionJiraTrigger',
+ [integrationFormSections.JIRA_ISSUES]: 'IntegrationSectionJiraIssues',
+};
diff --git a/app/assets/javascripts/integrations/edit/components/active_checkbox.vue b/app/assets/javascripts/integrations/edit/components/active_checkbox.vue
index 5ddf3aeb639..a4415a5a2b3 100644
--- a/app/assets/javascripts/integrations/edit/components/active_checkbox.vue
+++ b/app/assets/javascripts/integrations/edit/components/active_checkbox.vue
@@ -1,6 +1,6 @@
<script>
import { GlFormGroup, GlFormCheckbox } from '@gitlab/ui';
-import { mapGetters } from 'vuex';
+import { mapGetters, mapState } from 'vuex';
export default {
name: 'ActiveCheckbox',
@@ -15,6 +15,10 @@ export default {
},
computed: {
...mapGetters(['isInheriting', 'propsSource']),
+ ...mapState(['customState']),
+ disabled() {
+ return this.isInheriting || this.customState.activateDisabled;
+ },
},
mounted() {
this.activated = this.propsSource.initialActivated;
@@ -34,7 +38,7 @@ export default {
<gl-form-checkbox
v-model="activated"
class="gl-display-block"
- :disabled="isInheriting"
+ :disabled="disabled"
@change="onChange"
>
{{ __('Active') }}
diff --git a/app/assets/javascripts/integrations/edit/components/integration_form.vue b/app/assets/javascripts/integrations/edit/components/integration_form.vue
index 007a384f41e..6e89872ff68 100644
--- a/app/assets/javascripts/integrations/edit/components/integration_form.vue
+++ b/app/assets/javascripts/integrations/edit/components/integration_form.vue
@@ -3,12 +3,14 @@ import { GlButton, GlModalDirective, GlSafeHtmlDirective as SafeHtml, GlForm } f
import axios from 'axios';
import * as Sentry from '@sentry/browser';
import { mapState, mapActions, mapGetters } from 'vuex';
+
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import {
I18N_FETCH_TEST_SETTINGS_DEFAULT_ERROR_MESSAGE,
I18N_DEFAULT_ERROR_MESSAGE,
I18N_SUCCESSFUL_CONNECTION_MESSAGE,
integrationLevels,
+ integrationFormSectionComponents,
} from '~/integrations/constants';
import { refreshCurrentPage } from '~/lib/utils/url_utility';
import csrf from '~/lib/utils/csrf';
@@ -33,6 +35,18 @@ export default {
DynamicField,
ConfirmationModal,
ResetConfirmationModal,
+ IntegrationSectionConnection: () =>
+ import(
+ /* webpackChunkName: 'integrationSectionConnection' */ '~/integrations/edit/components/sections/connection.vue'
+ ),
+ IntegrationSectionJiraIssues: () =>
+ import(
+ /* webpackChunkName: 'integrationSectionJiraIssues' */ '~/integrations/edit/components/sections/jira_issues.vue'
+ ),
+ IntegrationSectionJiraTrigger: () =>
+ import(
+ /* webpackChunkName: 'integrationSectionJiraTrigger' */ '~/integrations/edit/components/sections/jira_trigger.vue'
+ ),
GlButton,
GlForm,
},
@@ -41,10 +55,13 @@ export default {
SafeHtml,
},
mixins: [glFeatureFlagsMixin()],
- props: {
+ provide() {
+ return {
+ hasSections: this.hasSections,
+ };
+ },
+ inject: {
helpHtml: {
- type: String,
- required: false,
default: '',
},
},
@@ -81,28 +98,42 @@ export default {
disableButtons() {
return Boolean(this.isSaving || this.isResetting || this.isTesting);
},
- form() {
- return this.$refs.integrationForm.$el;
+ sectionsEnabled() {
+ return this.glFeatures.integrationFormSections;
+ },
+ hasSections() {
+ return this.sectionsEnabled && this.customState.sections.length !== 0;
+ },
+ fieldsWithoutSection() {
+ return this.sectionsEnabled
+ ? this.propsSource.fields.filter((field) => !field.section)
+ : this.propsSource.fields;
},
},
methods: {
...mapActions(['setOverride', 'requestJiraIssueTypes']),
+ fieldsForSection(section) {
+ return this.propsSource.fields.filter((field) => field.section === section.type);
+ },
+ form() {
+ return this.$refs.integrationForm.$el;
+ },
setIsValidated() {
this.isValidated = true;
},
onSaveClick() {
this.isSaving = true;
- if (this.integrationActive && !this.form.checkValidity()) {
+ if (this.integrationActive && !this.form().checkValidity()) {
this.isSaving = false;
this.setIsValidated();
return;
}
- this.form.submit();
+ this.form().submit();
},
onTestClick() {
- if (!this.form.checkValidity()) {
+ if (!this.form().checkValidity()) {
this.setIsValidated();
return;
}
@@ -147,7 +178,7 @@ export default {
this.requestJiraIssueTypes(this.getFormData());
},
getFormData() {
- return new FormData(this.form);
+ return new FormData(this.form());
},
onToggleIntegrationState(integrationActive) {
this.integrationActive = integrationActive;
@@ -159,6 +190,7 @@ export default {
FORBID_ATTR: [], // This is trusted input so we can override the default config to allow data-* attributes
},
csrf,
+ integrationFormSectionComponents,
};
</script>
@@ -187,46 +219,75 @@ export default {
@change="setOverride"
/>
+ <template v-if="hasSections">
+ <div
+ v-for="(section, index) in customState.sections"
+ :key="section.type"
+ :class="{ 'gl-border-b gl-pb-3 gl-mb-6': index !== customState.sections.length - 1 }"
+ data-testid="integration-section"
+ >
+ <div class="row">
+ <div class="col-lg-4">
+ <h4 class="gl-mt-0">{{ section.title }}</h4>
+ <p v-safe-html="section.description"></p>
+ </div>
+
+ <div class="col-lg-8">
+ <component
+ :is="$options.integrationFormSectionComponents[section.type]"
+ :fields="fieldsForSection(section)"
+ :is-validated="isValidated"
+ @toggle-integration-active="onToggleIntegrationState"
+ @request-jira-issue-types="onRequestJiraIssueTypes"
+ />
+ </div>
+ </div>
+ </div>
+ </template>
+
<div class="row">
<div class="col-lg-4"></div>
<div class="col-lg-8">
<!-- helpHtml is trusted input -->
- <div v-if="helpHtml" v-safe-html:[$options.helpHtmlConfig]="helpHtml"></div>
+ <div v-if="helpHtml && !hasSections" v-safe-html:[$options.helpHtmlConfig]="helpHtml"></div>
<active-checkbox
- v-if="propsSource.showActive"
+ v-if="propsSource.showActive && !hasSections"
:key="`${currentKey}-active-checkbox`"
@toggle-integration-active="onToggleIntegrationState"
/>
<jira-trigger-fields
- v-if="isJira"
+ v-if="isJira && !hasSections"
:key="`${currentKey}-jira-trigger-fields`"
v-bind="propsSource.triggerFieldsProps"
:is-validated="isValidated"
/>
<trigger-fields
- v-else-if="propsSource.triggerEvents.length"
+ v-else-if="propsSource.triggerEvents.length && !hasSections"
:key="`${currentKey}-trigger-fields`"
:events="propsSource.triggerEvents"
:type="propsSource.type"
/>
<dynamic-field
- v-for="field in propsSource.fields"
+ v-for="field in fieldsWithoutSection"
:key="`${currentKey}-${field.name}`"
v-bind="field"
:is-validated="isValidated"
/>
<jira-issues-fields
- v-if="isJira && !isInstanceOrGroupLevel"
+ v-if="isJira && !isInstanceOrGroupLevel && !hasSections"
:key="`${currentKey}-jira-issues-fields`"
v-bind="propsSource.jiraIssuesProps"
:is-validated="isValidated"
@request-jira-issue-types="onRequestJiraIssueTypes"
/>
+ </div>
+ </div>
+ <div v-if="isEditable" class="row">
+ <div :class="hasSections ? 'col' : 'col-lg-8 offset-lg-4'">
<div
- v-if="isEditable"
class="footer-block row-content-block gl-display-flex gl-justify-content-space-between"
>
<div>
diff --git a/app/assets/javascripts/integrations/edit/components/jira_issues_fields.vue b/app/assets/javascripts/integrations/edit/components/jira_issues_fields.vue
index 7f2f7620a86..7cf8e11f162 100644
--- a/app/assets/javascripts/integrations/edit/components/jira_issues_fields.vue
+++ b/app/assets/javascripts/integrations/edit/components/jira_issues_fields.vue
@@ -16,6 +16,11 @@ export default {
JiraIssueCreationVulnerabilities: () =>
import('ee_component/integrations/edit/components/jira_issue_creation_vulnerabilities.vue'),
},
+ inject: {
+ hasSections: {
+ default: false,
+ },
+ },
props: {
showJiraIssuesIntegration: {
type: Boolean,
@@ -83,17 +88,17 @@ export default {
i18n: {
sectionTitle: s__('JiraService|View Jira issues in GitLab'),
sectionDescription: s__(
- 'JiraService|Work on Jira issues without leaving GitLab. Adds a Jira menu to access your list of Jira issues and view any issue as read-only.',
+ 'JiraService|Work on Jira issues without leaving GitLab. Add a Jira menu to access a read-only list of your Jira issues.',
),
enableCheckboxLabel: s__('JiraService|Enable Jira issues'),
enableCheckboxHelp: s__(
- 'JiraService|Warning: All GitLab users that have access to this GitLab project are able to view all issues from the Jira project specified below.',
+ 'JiraService|Warning: All GitLab users with access to this GitLab project can view all issues from the Jira project you select.',
),
projectKeyLabel: s__('JiraService|Jira project key'),
projectKeyPlaceholder: s__('JiraService|For example, AB'),
requiredFieldFeedback: __('This field is required.'),
issueTrackerConflictWarning: s__(
- 'JiraService|Displaying Jira issues while leaving the GitLab issue functionality enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used.',
+ 'JiraService|Displaying Jira issues while leaving GitLab issues also enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used.',
),
},
};
@@ -101,9 +106,12 @@ export default {
<template>
<div>
- <gl-form-group :label="$options.i18n.sectionTitle" label-for="jira-issue-settings">
+ <gl-form-group
+ :label="hasSections ? null : $options.i18n.sectionTitle"
+ label-for="jira-issue-settings"
+ >
<div id="jira-issue-settings">
- <p>
+ <p v-if="!hasSections">
{{ $options.i18n.sectionDescription }}
</p>
<template v-if="showJiraIssuesIntegration">
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 df5946b814a..3c06660e7c5 100644
--- a/app/assets/javascripts/integrations/edit/components/jira_trigger_fields.vue
+++ b/app/assets/javascripts/integrations/edit/components/jira_trigger_fields.vue
@@ -62,6 +62,11 @@ export default {
GlLink,
GlSprintf,
},
+ inject: {
+ hasSections: {
+ default: false,
+ },
+ },
props: {
initialTriggerCommit: {
type: Boolean,
@@ -134,12 +139,14 @@ export default {
<template>
<div>
<gl-form-group
- :label="__('Trigger')"
+ :label="hasSections ? null : __('Trigger')"
label-for="service[trigger]"
:description="
- s__(
- 'Integrations|When you mention a Jira issue in a commit or merge request, GitLab creates a remote link and comment (if enabled).',
- )
+ hasSections
+ ? null
+ : s__(
+ 'JiraService|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="triggerCommit || false" />
diff --git a/app/assets/javascripts/integrations/edit/components/sections/connection.vue b/app/assets/javascripts/integrations/edit/components/sections/connection.vue
new file mode 100644
index 00000000000..364e9324e43
--- /dev/null
+++ b/app/assets/javascripts/integrations/edit/components/sections/connection.vue
@@ -0,0 +1,45 @@
+<script>
+import { mapGetters } from 'vuex';
+
+import ActiveCheckbox from '../active_checkbox.vue';
+import DynamicField from '../dynamic_field.vue';
+
+export default {
+ name: 'IntegrationSectionConnection',
+ components: {
+ ActiveCheckbox,
+ DynamicField,
+ },
+ props: {
+ fields: {
+ type: Array,
+ required: false,
+ default: () => [],
+ },
+ isValidated: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
+ },
+ computed: {
+ ...mapGetters(['currentKey', 'propsSource']),
+ },
+};
+</script>
+
+<template>
+ <div>
+ <active-checkbox
+ v-if="propsSource.showActive"
+ :key="`${currentKey}-active-checkbox`"
+ @toggle-integration-active="$emit('toggle-integration-active', $event)"
+ />
+ <dynamic-field
+ v-for="field in fields"
+ :key="`${currentKey}-${field.name}`"
+ v-bind="field"
+ :is-validated="isValidated"
+ />
+ </div>
+</template>
diff --git a/app/assets/javascripts/integrations/edit/components/sections/jira_issues.vue b/app/assets/javascripts/integrations/edit/components/sections/jira_issues.vue
new file mode 100644
index 00000000000..75202209d38
--- /dev/null
+++ b/app/assets/javascripts/integrations/edit/components/sections/jira_issues.vue
@@ -0,0 +1,33 @@
+<script>
+import { mapGetters } from 'vuex';
+
+import JiraIssuesFields from '../jira_issues_fields.vue';
+
+export default {
+ name: 'IntegrationSectionJiraIssues',
+ components: {
+ JiraIssuesFields,
+ },
+ props: {
+ isValidated: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
+ },
+ computed: {
+ ...mapGetters(['currentKey', 'propsSource']),
+ },
+};
+</script>
+
+<template>
+ <div>
+ <jira-issues-fields
+ :key="`${currentKey}-jira-issues-fields`"
+ v-bind="propsSource.jiraIssuesProps"
+ :is-validated="isValidated"
+ @request-jira-issue-types="$emit('request-jira-issue-types')"
+ />
+ </div>
+</template>
diff --git a/app/assets/javascripts/integrations/edit/components/sections/jira_trigger.vue b/app/assets/javascripts/integrations/edit/components/sections/jira_trigger.vue
new file mode 100644
index 00000000000..f36d3b1fbda
--- /dev/null
+++ b/app/assets/javascripts/integrations/edit/components/sections/jira_trigger.vue
@@ -0,0 +1,32 @@
+<script>
+import { mapGetters } from 'vuex';
+
+import JiraTriggerFields from '../jira_trigger_fields.vue';
+
+export default {
+ name: 'IntegrationSectionJiraTrigger',
+ components: {
+ JiraTriggerFields,
+ },
+ props: {
+ isValidated: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
+ },
+ computed: {
+ ...mapGetters(['currentKey', 'propsSource']),
+ },
+};
+</script>
+
+<template>
+ <div>
+ <jira-trigger-fields
+ :key="`${currentKey}-jira-trigger-fields`"
+ v-bind="propsSource.triggerFieldsProps"
+ :is-validated="isValidated"
+ />
+ </div>
+</template>
diff --git a/app/assets/javascripts/integrations/edit/components/trigger_fields.vue b/app/assets/javascripts/integrations/edit/components/trigger_fields.vue
index 433fe21ad76..92042a5c981 100644
--- a/app/assets/javascripts/integrations/edit/components/trigger_fields.vue
+++ b/app/assets/javascripts/integrations/edit/components/trigger_fields.vue
@@ -1,6 +1,5 @@
<script>
import { GlFormGroup, GlFormCheckbox, GlFormInput } from '@gitlab/ui';
-import { startCase } from 'lodash';
import { mapGetters } from 'vuex';
import { __ } from '~/locale';
@@ -45,7 +44,6 @@ export default {
fieldName(name) {
return `service[${name}]`;
},
- startCase,
},
};
</script>
@@ -58,10 +56,10 @@ export default {
data-testid="trigger-fields-group"
>
<div id="trigger-fields" class="gl-pt-3">
- <gl-form-group v-for="event in events" :key="event.title" :description="event.description">
+ <gl-form-group v-for="event in events" :key="event.name" :description="event.description">
<input :name="checkboxName(event.name)" type="hidden" :value="event.value || false" />
<gl-form-checkbox v-model="event.value" :disabled="isInheriting">
- {{ startCase(event.title) }}
+ {{ event.title }}
</gl-form-checkbox>
<gl-form-input
v-if="event.field"
diff --git a/app/assets/javascripts/integrations/edit/index.js b/app/assets/javascripts/integrations/edit/index.js
index fbda8c1e3d0..3e58dd0be99 100644
--- a/app/assets/javascripts/integrations/edit/index.js
+++ b/app/assets/javascripts/integrations/edit/index.js
@@ -22,6 +22,7 @@ function parseDatasetToProps(data) {
editProjectPath,
learnMorePath,
triggerEvents,
+ sections,
fields,
inheritFromId,
integrationLevel,
@@ -38,6 +39,7 @@ function parseDatasetToProps(data) {
const {
showActive,
activated,
+ activateDisabled,
editable,
canTest,
commitEvents,
@@ -53,6 +55,7 @@ function parseDatasetToProps(data) {
return {
initialActivated: activated,
showActive,
+ activateDisabled,
type,
cancelPath,
editable,
@@ -81,6 +84,7 @@ function parseDatasetToProps(data) {
},
learnMorePath,
triggerEvents: JSON.parse(triggerEvents),
+ sections: JSON.parse(sections, { deep: true }),
fields: convertObjectPropsToCamelCase(JSON.parse(fields), { deep: true }),
inheritFromId: parseInt(inheritFromId, 10),
integrationLevel,
@@ -114,13 +118,13 @@ export default function initIntegrationSettingsForm() {
return new Vue({
el: customSettingsEl,
+ name: 'IntegrationEditRoot',
store: createStore(initialState),
+ provide: {
+ helpHtml,
+ },
render(createElement) {
- return createElement(IntegrationForm, {
- props: {
- helpHtml,
- },
- });
+ return createElement(IntegrationForm);
},
});
}
diff --git a/app/assets/javascripts/integrations/edit/store/getters.js b/app/assets/javascripts/integrations/edit/store/getters.js
index b79132128cc..b0adc444395 100644
--- a/app/assets/javascripts/integrations/edit/store/getters.js
+++ b/app/assets/javascripts/integrations/edit/store/getters.js
@@ -1,5 +1,10 @@
+import { integrationLevels } from '~/integrations/constants';
+
export const isInheriting = (state) => (state.defaultState === null ? false : !state.override);
+export const isProjectLevel = (state) =>
+ state.customState.integrationLevel === integrationLevels.PROJECT;
+
export const propsSource = (state, getters) =>
getters.isInheriting ? state.defaultState : state.customState;
diff --git a/app/assets/javascripts/invite_members/components/invite_group_trigger.vue b/app/assets/javascripts/invite_members/components/invite_group_trigger.vue
index c08a4d75c59..424a9d3fabd 100644
--- a/app/assets/javascripts/invite_members/components/invite_group_trigger.vue
+++ b/app/assets/javascripts/invite_members/components/invite_group_trigger.vue
@@ -28,7 +28,12 @@ export default {
</script>
<template>
- <gl-button :class="classes" data-qa-selector="invite_a_group_button" @click="openModal">
+ <gl-button
+ :class="classes"
+ data-qa-selector="invite_a_group_button"
+ data-test-id="invite-group-button"
+ @click="openModal"
+ >
{{ displayText }}
</gl-button>
</template>
diff --git a/app/assets/javascripts/invite_members/components/invite_groups_modal.vue b/app/assets/javascripts/invite_members/components/invite_groups_modal.vue
index 6598000c464..f266d978ffa 100644
--- a/app/assets/javascripts/invite_members/components/invite_groups_modal.vue
+++ b/app/assets/javascripts/invite_members/components/invite_groups_modal.vue
@@ -4,6 +4,7 @@ import Api from '~/api';
import { BV_SHOW_MODAL, BV_HIDE_MODAL } from '~/lib/utils/constants';
import { GROUP_FILTERS, GROUP_MODAL_LABELS } from '../constants';
import eventHub from '../event_hub';
+import { getInvalidFeedbackMessage } from '../utils/get_invalid_feedback_message';
import GroupSelect from './group_select.vue';
import InviteModalBase from './invite_modal_base.vue';
@@ -55,6 +56,8 @@ export default {
},
data() {
return {
+ invalidFeedbackMessage: '',
+ isLoading: false,
modalId: uniqueId('invite-groups-modal-'),
groupToBeSharedWith: {},
};
@@ -83,13 +86,19 @@ export default {
});
},
methods: {
+ showInvalidFeedbackMessage(response) {
+ this.invalidFeedbackMessage = getInvalidFeedbackMessage(response);
+ },
openModal() {
this.$root.$emit(BV_SHOW_MODAL, this.modalId);
},
closeModal() {
this.$root.$emit(BV_HIDE_MODAL, this.modalId);
},
- sendInvite({ onError, onSuccess, data: { accessLevel, expiresAt } }) {
+ sendInvite({ accessLevel, expiresAt }) {
+ this.invalidFeedbackMessage = '';
+ this.isLoading = true;
+
const apiShareWithGroup = this.isProject
? Api.projectShareWithGroup.bind(Api)
: Api.groupShareWithGroup.bind(Api);
@@ -101,18 +110,27 @@ export default {
expires_at: expiresAt,
})
.then(() => {
- onSuccess();
this.showSuccessMessage();
})
- .catch(onError);
+ .catch((e) => {
+ this.showInvalidFeedbackMessage(e);
+ })
+ .finally(() => {
+ this.isLoading = false;
+ });
},
resetFields() {
+ this.invalidFeedbackMessage = '';
+ this.isLoading = false;
this.groupToBeSharedWith = {};
},
showSuccessMessage() {
this.$toast.show(this.$options.labels.toastMessageSuccessful, this.toastOptions);
this.closeModal();
},
+ clearValidation() {
+ this.invalidFeedbackMessage = '';
+ },
},
labels: GROUP_MODAL_LABELS,
};
@@ -129,10 +147,12 @@ export default {
:label-intro-text="labelIntroText"
:label-search-field="$options.labels.searchField"
:submit-disabled="inviteDisabled"
+ :invalid-feedback-message="invalidFeedbackMessage"
+ :is-loading="isLoading"
@reset="resetFields"
@submit="sendInvite"
>
- <template #select="{ clearValidation }">
+ <template #select>
<group-select
v-model="groupToBeSharedWith"
:access-levels="accessLevels"
diff --git a/app/assets/javascripts/invite_members/components/invite_members_modal.vue b/app/assets/javascripts/invite_members/components/invite_members_modal.vue
index 6c0fc5caf26..be48a58d838 100644
--- a/app/assets/javascripts/invite_members/components/invite_members_modal.vue
+++ b/app/assets/javascripts/invite_members/components/invite_members_modal.vue
@@ -21,6 +21,7 @@ import {
} from '../constants';
import eventHub from '../event_hub';
import { responseMessageFromSuccess } from '../utils/response_message_parser';
+import { getInvalidFeedbackMessage } from '../utils/get_invalid_feedback_message';
import ModalConfetti from './confetti.vue';
import MembersTokenSelect from './members_token_select.vue';
@@ -84,6 +85,8 @@ export default {
},
data() {
return {
+ invalidFeedbackMessage: '',
+ isLoading: false,
modalId: uniqueId('invite-members-modal-'),
newUsersToInvite: [],
selectedTasksToBeDone: [],
@@ -152,6 +155,9 @@ export default {
}
},
methods: {
+ showInvalidFeedbackMessage(response) {
+ this.invalidFeedbackMessage = getInvalidFeedbackMessage(response);
+ },
partitionNewUsersToInvite() {
const [usersToInviteByEmail, usersToAddById] = partition(
this.newUsersToInvite,
@@ -176,7 +182,10 @@ export default {
const tracking = new ExperimentTracking(experimentName);
tracking.event(eventName);
},
- sendInvite({ onError, onSuccess, data: { accessLevel, expiresAt } }) {
+ sendInvite({ accessLevel, expiresAt }) {
+ this.isLoading = true;
+ this.invalidFeedbackMessage = '';
+
const [usersToInviteByEmail, usersToAddById] = this.partitionNewUsersToInvite();
const promises = [];
const baseData = {
@@ -220,19 +229,17 @@ export default {
const message = responseMessageFromSuccess(responses);
if (message) {
- onError({
- response: {
- data: {
- message,
- },
- },
+ this.showInvalidFeedbackMessage({
+ response: { data: { message } },
});
} else {
- onSuccess();
this.showSuccessMessage();
}
})
- .catch(onError);
+ .catch((e) => this.showInvalidFeedbackMessage(e))
+ .finally(() => {
+ this.isLoading = false;
+ });
},
trackinviteMembersForTask() {
const label = 'selected_tasks_to_be_done';
@@ -241,6 +248,8 @@ export default {
tracking.event(INVITE_MEMBERS_FOR_TASK.submit);
},
resetFields() {
+ this.isLoading = false;
+ this.invalidFeedbackMessage = '';
this.newUsersToInvite = [];
this.selectedTasksToBeDone = [];
[this.selectedTaskProject] = this.projects;
@@ -260,6 +269,9 @@ export default {
onAccessLevelUpdate(val) {
this.selectedAccessLevel = val;
},
+ clearValidation() {
+ this.invalidFeedbackMessage = '';
+ },
},
labels: MEMBER_MODAL_LABELS,
};
@@ -276,6 +288,8 @@ export default {
:label-search-field="$options.labels.searchField"
:form-group-description="$options.labels.placeHolder"
:submit-disabled="inviteDisabled"
+ :invalid-feedback-message="invalidFeedbackMessage"
+ :is-loading="isLoading"
@reset="resetFields"
@submit="sendInvite"
@access-level="onAccessLevelUpdate"
@@ -288,7 +302,7 @@ export default {
<span v-if="isCelebration">{{ $options.labels.modal.celebrate.intro }} </span>
<modal-confetti v-if="isCelebration" />
</template>
- <template #select="{ clearValidation, validationState, labelId }">
+ <template #select="{ validationState, labelId }">
<members-token-select
v-model="newUsersToInvite"
class="gl-mb-2"
diff --git a/app/assets/javascripts/invite_members/components/invite_modal_base.vue b/app/assets/javascripts/invite_members/components/invite_modal_base.vue
index fc00f5b9343..bafbe94b8bd 100644
--- a/app/assets/javascripts/invite_members/components/invite_modal_base.vue
+++ b/app/assets/javascripts/invite_members/components/invite_modal_base.vue
@@ -10,19 +10,27 @@ import {
GlButton,
GlFormInput,
} from '@gitlab/ui';
-import { unescape } from 'lodash';
-import { sanitize } from '~/lib/dompurify';
import { sprintf } from '~/locale';
+import ContentTransition from '~/vue_shared/components/content_transition.vue';
import {
ACCESS_LEVEL,
ACCESS_EXPIRE_DATE,
- INVALID_FEEDBACK_MESSAGE_DEFAULT,
READ_MORE_TEXT,
INVITE_BUTTON_TEXT,
CANCEL_BUTTON_TEXT,
HEADER_CLOSE_LABEL,
} from '../constants';
-import { responseMessageFromError } from '../utils/response_message_parser';
+
+const DEFAULT_SLOT = 'default';
+const DEFAULT_SLOTS = [
+ {
+ key: DEFAULT_SLOT,
+ attributes: {
+ class: 'invite-modal-content',
+ 'data-testid': 'invite-modal-initial-content',
+ },
+ },
+];
export default {
components: {
@@ -35,6 +43,7 @@ export default {
GlSprintf,
GlButton,
GlFormInput,
+ ContentTransition,
},
inheritAttrs: false,
props: {
@@ -80,14 +89,37 @@ export default {
required: false,
default: false,
},
+ isLoading: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
+ invalidFeedbackMessage: {
+ type: String,
+ required: false,
+ default: '',
+ },
+ submitButtonText: {
+ type: String,
+ required: false,
+ default: INVITE_BUTTON_TEXT,
+ },
+ currentSlot: {
+ type: String,
+ required: false,
+ default: DEFAULT_SLOT,
+ },
+ extraSlots: {
+ type: Array,
+ required: false,
+ default: () => [],
+ },
},
data() {
// Be sure to check out reset!
return {
- invalidFeedbackMessage: '',
selectedAccessLevel: this.defaultAccessLevel,
selectedDate: undefined,
- isLoading: false,
minDate: new Date(),
};
},
@@ -106,6 +138,9 @@ export default {
(key) => this.accessLevels[key] === Number(this.selectedAccessLevel),
);
},
+ contentSlots() {
+ return [...DEFAULT_SLOTS, ...(this.extraSlots || [])];
+ },
},
watch: {
selectedAccessLevel: {
@@ -116,16 +151,9 @@ export default {
},
},
methods: {
- showInvalidFeedbackMessage(response) {
- const message = this.unescapeMsg(responseMessageFromError(response));
-
- this.invalidFeedbackMessage = message || INVALID_FEEDBACK_MESSAGE_DEFAULT;
- },
reset() {
// This component isn't necessarily disposed,
// so we might need to reset it's state.
- this.isLoading = false;
- this.invalidFeedbackMessage = '';
this.selectedAccessLevel = this.defaultAccessLevel;
this.selectedDate = undefined;
@@ -135,33 +163,15 @@ export default {
this.reset();
this.$refs.modal.hide();
},
- clearValidation() {
- this.invalidFeedbackMessage = '';
- },
changeSelectedItem(item) {
this.selectedAccessLevel = item;
},
submit() {
- this.isLoading = true;
- this.invalidFeedbackMessage = '';
-
this.$emit('submit', {
- onSuccess: () => {
- this.isLoading = false;
- },
- onError: (...args) => {
- this.isLoading = false;
- this.showInvalidFeedbackMessage(...args);
- },
- data: {
- accessLevel: this.selectedAccessLevel,
- expiresAt: this.selectedDate,
- },
+ accessLevel: this.selectedAccessLevel,
+ expiresAt: this.selectedDate,
});
},
- unescapeMsg(message) {
- return unescape(sanitize(message, { ALLOWED_TAGS: [] }));
- },
},
HEADER_CLOSE_LABEL,
ACCESS_EXPIRE_DATE,
@@ -169,6 +179,7 @@ export default {
READ_MORE_TEXT,
INVITE_BUTTON_TEXT,
CANCEL_BUTTON_TEXT,
+ DEFAULT_SLOT,
};
</script>
@@ -185,91 +196,105 @@ export default {
@close="reset"
@hide="reset"
>
- <div class="gl-display-flex" data-testid="modal-base-intro-text">
- <slot name="intro-text-before"></slot>
- <p>
- <gl-sprintf :message="introText">
- <template #strong="{ content }">
- <strong>{{ content }}</strong>
- </template>
- </gl-sprintf>
- </p>
- <slot name="intro-text-after"></slot>
- </div>
-
- <gl-form-group
- :invalid-feedback="invalidFeedbackMessage"
- :state="validationState"
- :description="formGroupDescription"
- data-testid="members-form-group"
+ <content-transition
+ class="gl-display-grid"
+ transition-name="invite-modal-transition"
+ :slots="contentSlots"
+ :current-slot="currentSlot"
>
- <label :id="selectLabelId" class="col-form-label">{{ labelSearchField }}</label>
- <slot
- name="select"
- v-bind="{ clearValidation, validationState, labelId: selectLabelId }"
- ></slot>
- </gl-form-group>
+ <template #[$options.DEFAULT_SLOT]>
+ <div class="gl-display-flex" data-testid="modal-base-intro-text">
+ <slot name="intro-text-before"></slot>
+ <p>
+ <gl-sprintf :message="introText">
+ <template #strong="{ content }">
+ <strong>{{ content }}</strong>
+ </template>
+ </gl-sprintf>
+ </p>
+ <slot name="intro-text-after"></slot>
+ </div>
- <label class="gl-font-weight-bold">{{ $options.ACCESS_LEVEL }}</label>
- <div class="gl-mt-2 gl-w-half gl-xs-w-full">
- <gl-dropdown
- class="gl-shadow-none gl-w-full"
- data-qa-selector="access_level_dropdown"
- v-bind="$attrs"
- :text="selectedRoleName"
- >
- <template v-for="(key, item) in accessLevels">
- <gl-dropdown-item
- :key="key"
- active-class="is-active"
- is-check-item
- :is-checked="key === selectedAccessLevel"
- @click="changeSelectedItem(key)"
- >
- <div>{{ item }}</div>
- </gl-dropdown-item>
- </template>
- </gl-dropdown>
- </div>
+ <gl-form-group
+ :invalid-feedback="invalidFeedbackMessage"
+ :state="validationState"
+ :description="formGroupDescription"
+ data-testid="members-form-group"
+ >
+ <label :id="selectLabelId" class="col-form-label">{{ labelSearchField }}</label>
+ <slot name="select" v-bind="{ validationState, labelId: selectLabelId }"></slot>
+ </gl-form-group>
- <div class="gl-mt-2 gl-w-half gl-xs-w-full">
- <gl-sprintf :message="$options.READ_MORE_TEXT">
- <template #link="{ content }">
- <gl-link :href="helpLink" target="_blank">{{ content }}</gl-link>
- </template>
- </gl-sprintf>
- </div>
+ <label class="gl-font-weight-bold">{{ $options.ACCESS_LEVEL }}</label>
+ <div class="gl-mt-2 gl-w-half gl-xs-w-full">
+ <gl-dropdown
+ class="gl-shadow-none gl-w-full"
+ data-qa-selector="access_level_dropdown"
+ v-bind="$attrs"
+ :text="selectedRoleName"
+ >
+ <template v-for="(key, item) in accessLevels">
+ <gl-dropdown-item
+ :key="key"
+ active-class="is-active"
+ is-check-item
+ :is-checked="key === selectedAccessLevel"
+ @click="changeSelectedItem(key)"
+ >
+ <div>{{ item }}</div>
+ </gl-dropdown-item>
+ </template>
+ </gl-dropdown>
+ </div>
- <label class="gl-mt-5 gl-display-block" for="expires_at">{{
- $options.ACCESS_EXPIRE_DATE
- }}</label>
- <div class="gl-mt-2 gl-w-half gl-xs-w-full gl-display-inline-block">
- <gl-datepicker
- v-model="selectedDate"
- class="gl-display-inline!"
- :min-date="minDate"
- :target="null"
- >
- <template #default="{ formattedDate }">
- <gl-form-input class="gl-w-full" :value="formattedDate" :placeholder="__(`YYYY-MM-DD`)" />
- </template>
- </gl-datepicker>
- </div>
- <slot name="form-after"></slot>
+ <div class="gl-mt-2 gl-w-half gl-xs-w-full">
+ <gl-sprintf :message="$options.READ_MORE_TEXT">
+ <template #link="{ content }">
+ <gl-link :href="helpLink" target="_blank">{{ content }}</gl-link>
+ </template>
+ </gl-sprintf>
+ </div>
+ <label class="gl-mt-5 gl-display-block" for="expires_at">{{
+ $options.ACCESS_EXPIRE_DATE
+ }}</label>
+ <div class="gl-mt-2 gl-w-half gl-xs-w-full gl-display-inline-block">
+ <gl-datepicker
+ v-model="selectedDate"
+ class="gl-display-inline!"
+ :min-date="minDate"
+ :target="null"
+ >
+ <template #default="{ formattedDate }">
+ <gl-form-input
+ class="gl-w-full"
+ :value="formattedDate"
+ :placeholder="__(`YYYY-MM-DD`)"
+ />
+ </template>
+ </gl-datepicker>
+ </div>
+ <slot name="form-after"></slot>
+ </template>
+ <template v-for="{ key } in extraSlots" #[key]>
+ <slot :name="key"></slot>
+ </template>
+ </content-transition>
<template #modal-footer>
- <gl-button data-testid="cancel-button" @click="closeModal">
- {{ $options.CANCEL_BUTTON_TEXT }}
- </gl-button>
+ <slot name="cancel-button">
+ <gl-button data-testid="cancel-button" @click="closeModal">
+ {{ $options.CANCEL_BUTTON_TEXT }}
+ </gl-button>
+ </slot>
<gl-button
:disabled="submitDisabled"
:loading="isLoading"
- variant="success"
+ variant="confirm"
data-qa-selector="invite_button"
data-testid="invite-button"
@click="submit"
>
- {{ $options.INVITE_BUTTON_TEXT }}
+ {{ submitButtonText }}
</gl-button>
</template>
</gl-modal>
diff --git a/app/assets/javascripts/invite_members/init_invite_members_form.js b/app/assets/javascripts/invite_members/init_invite_members_form.js
deleted file mode 100644
index 5f8688755ba..00000000000
--- a/app/assets/javascripts/invite_members/init_invite_members_form.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import { disableButtonIfEmptyField } from '~/lib/utils/common_utils';
-
-// This is only used when `invite_members_group_modal` feature flag is disabled.
-// This file can be removed when `invite_members_group_modal` feature flag is removed
-export default () => {
- disableButtonIfEmptyField('#user_ids', 'input[name=commit]', 'change');
-};
diff --git a/app/assets/javascripts/invite_members/utils/get_invalid_feedback_message.js b/app/assets/javascripts/invite_members/utils/get_invalid_feedback_message.js
new file mode 100644
index 00000000000..62f66d009dc
--- /dev/null
+++ b/app/assets/javascripts/invite_members/utils/get_invalid_feedback_message.js
@@ -0,0 +1,12 @@
+import { unescape } from 'lodash';
+import { sanitize } from '~/lib/dompurify';
+import { INVALID_FEEDBACK_MESSAGE_DEFAULT } from '../constants';
+import { responseMessageFromError } from './response_message_parser';
+
+const unescapeMsg = (message) => unescape(sanitize(message, { ALLOWED_TAGS: [] }));
+
+export const getInvalidFeedbackMessage = (response) => {
+ const message = unescapeMsg(responseMessageFromError(response));
+
+ return message || INVALID_FEEDBACK_MESSAGE_DEFAULT;
+};
diff --git a/app/assets/javascripts/issuable/components/issuable_by_email.vue b/app/assets/javascripts/issuable/components/issuable_by_email.vue
index 512fa6f8c68..fcebae3af71 100644
--- a/app/assets/javascripts/issuable/components/issuable_by_email.vue
+++ b/app/assets/javascripts/issuable/components/issuable_by_email.vue
@@ -65,7 +65,6 @@ export default {
const body = sprintf(__('Enter the %{name} description'), {
name: this.issuableName,
});
- // eslint-disable-next-line @gitlab/require-i18n-strings
return `mailto:${this.email}?subject=${subject}&body=${body}`;
},
},
diff --git a/app/assets/javascripts/issues/create_merge_request_dropdown.js b/app/assets/javascripts/issues/create_merge_request_dropdown.js
index a3752c7043c..247f8dd0bd6 100644
--- a/app/assets/javascripts/issues/create_merge_request_dropdown.js
+++ b/app/assets/javascripts/issues/create_merge_request_dropdown.js
@@ -10,6 +10,7 @@ import ISetter from '~/filtered_search/droplab/plugins/input_setter';
import createFlash from '~/flash';
import axios from '~/lib/utils/axios_utils';
import { __, sprintf } from '~/locale';
+import { mergeUrlParams } from '~/lib/utils/url_utility';
// Todo: Remove this when fixing issue in input_setter plugin
const InputSetter = { ...ISetter };
@@ -171,12 +172,21 @@ export default class CreateMergeRequestDropdown {
this.isCreatingMergeRequest = true;
return this.createBranch().then(() => {
- window.location.href = canCreateConfidentialMergeRequest()
+ let path = canCreateConfidentialMergeRequest()
? this.createMrPath.replace(
this.projectPath,
confidentialMergeRequestState.selectedProject.pathWithNamespace,
)
: this.createMrPath;
+ path = mergeUrlParams(
+ {
+ 'merge_request[target_branch]': this.refInput.value,
+ 'merge_request[source_branch]': this.branchInput.value,
+ },
+ path,
+ );
+
+ window.location.href = path;
});
});
}
diff --git a/app/assets/javascripts/issues/list/components/issues_list_app.vue b/app/assets/javascripts/issues/list/components/issues_list_app.vue
index 3866a7b3305..a532fa5b771 100644
--- a/app/assets/javascripts/issues/list/components/issues_list_app.vue
+++ b/app/assets/javascripts/issues/list/components/issues_list_app.vue
@@ -39,8 +39,11 @@ import { IssuableListTabs, IssuableStates } from '~/vue_shared/issuable/list/con
import {
CREATED_DESC,
i18n,
+ ISSUE_REFERENCE,
MAX_LIST_SIZE,
PAGE_SIZE,
+ PARAM_PAGE_AFTER,
+ PARAM_PAGE_BEFORE,
PARAM_STATE,
RELATIVE_POSITION_ASC,
TOKEN_TYPE_ASSIGNEE,
@@ -134,6 +137,8 @@ export default {
},
},
data() {
+ const pageAfter = getParameterByName(PARAM_PAGE_AFTER);
+ const pageBefore = getParameterByName(PARAM_PAGE_BEFORE);
const state = getParameterByName(PARAM_STATE);
const defaultSortKey = state === IssuableStates.Closed ? UPDATED_DESC : CREATED_DESC;
const dashboardSortKey = getSortKey(this.initialSort);
@@ -165,7 +170,7 @@ export default {
issuesCounts: {},
issuesError: null,
pageInfo: {},
- pageParams: getInitialPageParams(sortKey),
+ pageParams: getInitialPageParams(sortKey, pageAfter, pageBefore),
showBulkEditSidebar: false,
sortKey,
state: state || IssuableStates.Opened,
@@ -219,11 +224,13 @@ export default {
},
computed: {
queryVariables() {
+ const isIidSearch = ISSUE_REFERENCE.test(this.searchQuery);
return {
fullPath: this.fullPath,
+ iid: isIidSearch ? this.searchQuery.slice(1) : undefined,
isProject: this.isProject,
isSignedIn: this.isSignedIn,
- search: this.searchQuery,
+ search: isIidSearch ? undefined : this.searchQuery,
sort: this.sortKey,
state: this.state,
...this.pageParams,
@@ -234,7 +241,12 @@ export default {
return this.isProject ? ITEM_TYPE.PROJECT : ITEM_TYPE.GROUP;
},
hasSearch() {
- return this.searchQuery || Object.keys(this.urlFilterParams).length;
+ return (
+ this.searchQuery ||
+ Object.keys(this.urlFilterParams).length ||
+ this.pageParams.afterCursor ||
+ this.pageParams.beforeCursor
+ );
},
isBulkEditButtonDisabled() {
return this.showBulkEditSidebar || !this.issues.length;
@@ -391,6 +403,8 @@ export default {
},
urlParams() {
return {
+ page_after: this.pageParams.afterCursor,
+ page_before: this.pageParams.beforeCursor,
search: this.searchQuery,
sort: urlSortParams[this.sortKey],
state: this.state,
diff --git a/app/assets/javascripts/issues/list/constants.js b/app/assets/javascripts/issues/list/constants.js
index 284167a933f..4b07a078512 100644
--- a/app/assets/javascripts/issues/list/constants.js
+++ b/app/assets/javascripts/issues/list/constants.js
@@ -52,20 +52,15 @@ export const i18n = {
upvotes: __('Upvotes'),
};
+export const ISSUE_REFERENCE = /^#\d+$/;
export const MAX_LIST_SIZE = 10;
export const PAGE_SIZE = 20;
export const PAGE_SIZE_MANUAL = 100;
+export const PARAM_PAGE_AFTER = 'page_after';
+export const PARAM_PAGE_BEFORE = 'page_before';
export const PARAM_STATE = 'state';
export const RELATIVE_POSITION = 'relative_position';
-export const defaultPageSizeParams = {
- firstPageSize: PAGE_SIZE,
-};
-
-export const largePageSizeParams = {
- firstPageSize: PAGE_SIZE_MANUAL,
-};
-
export const BLOCKING_ISSUES_ASC = 'BLOCKING_ISSUES_ASC';
export const BLOCKING_ISSUES_DESC = 'BLOCKING_ISSUES_DESC';
export const CREATED_ASC = 'CREATED_ASC';
diff --git a/app/assets/javascripts/issues/list/queries/get_issues.query.graphql b/app/assets/javascripts/issues/list/queries/get_issues.query.graphql
index be8deb3fe97..529262d2162 100644
--- a/app/assets/javascripts/issues/list/queries/get_issues.query.graphql
+++ b/app/assets/javascripts/issues/list/queries/get_issues.query.graphql
@@ -5,6 +5,7 @@ query getIssues(
$isProject: Boolean = false
$isSignedIn: Boolean = false
$fullPath: ID!
+ $iid: String
$search: String
$sort: IssueSort
$state: IssuableState
@@ -29,6 +30,7 @@ query getIssues(
id
issues(
includeSubgroups: true
+ iid: $iid
search: $search
sort: $sort
state: $state
@@ -59,6 +61,7 @@ query getIssues(
project(fullPath: $fullPath) @include(if: $isProject) {
id
issues(
+ iid: $iid
search: $search
sort: $sort
state: $state
diff --git a/app/assets/javascripts/issues/list/queries/get_issues_counts.query.graphql b/app/assets/javascripts/issues/list/queries/get_issues_counts.query.graphql
index 1a345fd2877..58e7ce32e7c 100644
--- a/app/assets/javascripts/issues/list/queries/get_issues_counts.query.graphql
+++ b/app/assets/javascripts/issues/list/queries/get_issues_counts.query.graphql
@@ -1,6 +1,7 @@
query getIssuesCount(
$isProject: Boolean = false
$fullPath: ID!
+ $iid: String
$search: String
$assigneeId: String
$assigneeUsernames: [String!]
@@ -20,6 +21,7 @@ query getIssuesCount(
openedIssues: issues(
includeSubgroups: true
state: opened
+ iid: $iid
search: $search
assigneeId: $assigneeId
assigneeUsernames: $assigneeUsernames
@@ -37,6 +39,7 @@ query getIssuesCount(
closedIssues: issues(
includeSubgroups: true
state: closed
+ iid: $iid
search: $search
assigneeId: $assigneeId
assigneeUsernames: $assigneeUsernames
@@ -54,6 +57,7 @@ query getIssuesCount(
allIssues: issues(
includeSubgroups: true
state: all
+ iid: $iid
search: $search
assigneeId: $assigneeId
assigneeUsernames: $assigneeUsernames
@@ -73,6 +77,7 @@ query getIssuesCount(
id
openedIssues: issues(
state: opened
+ iid: $iid
search: $search
assigneeId: $assigneeId
assigneeUsernames: $assigneeUsernames
@@ -91,6 +96,7 @@ query getIssuesCount(
}
closedIssues: issues(
state: closed
+ iid: $iid
search: $search
assigneeId: $assigneeId
assigneeUsernames: $assigneeUsernames
@@ -109,6 +115,7 @@ query getIssuesCount(
}
allIssues: issues(
state: all
+ iid: $iid
search: $search
assigneeId: $assigneeId
assigneeUsernames: $assigneeUsernames
diff --git a/app/assets/javascripts/issues/list/queries/search_users.query.graphql b/app/assets/javascripts/issues/list/queries/search_users.query.graphql
index 92517ad35d0..46b48e4e41c 100644
--- a/app/assets/javascripts/issues/list/queries/search_users.query.graphql
+++ b/app/assets/javascripts/issues/list/queries/search_users.query.graphql
@@ -3,7 +3,7 @@
query searchUsers($fullPath: ID!, $search: String, $isProject: Boolean = false) {
group(fullPath: $fullPath) @skip(if: $isProject) {
id
- groupMembers(search: $search) {
+ groupMembers(search: $search, relations: [DIRECT, INHERITED, SHARED_FROM_GROUPS]) {
nodes {
id
user {
@@ -14,7 +14,7 @@ query searchUsers($fullPath: ID!, $search: String, $isProject: Boolean = false)
}
project(fullPath: $fullPath) @include(if: $isProject) {
id
- projectMembers(search: $search) {
+ projectMembers(search: $search, relations: [DIRECT, INHERITED, INVITED_GROUPS]) {
nodes {
id
user {
diff --git a/app/assets/javascripts/issues/list/utils.js b/app/assets/javascripts/issues/list/utils.js
index 6322968b3f0..4b77bd9bc5f 100644
--- a/app/assets/javascripts/issues/list/utils.js
+++ b/app/assets/javascripts/issues/list/utils.js
@@ -10,16 +10,16 @@ import {
BLOCKING_ISSUES_DESC,
CREATED_ASC,
CREATED_DESC,
- defaultPageSizeParams,
DUE_DATE_ASC,
DUE_DATE_DESC,
filters,
LABEL_PRIORITY_ASC,
LABEL_PRIORITY_DESC,
- largePageSizeParams,
MILESTONE_DUE_ASC,
MILESTONE_DUE_DESC,
NORMAL_FILTER,
+ PAGE_SIZE,
+ PAGE_SIZE_MANUAL,
POPULARITY_ASC,
POPULARITY_DESC,
PRIORITY_ASC,
@@ -43,8 +43,11 @@ import {
WEIGHT_DESC,
} from './constants';
-export const getInitialPageParams = (sortKey) =>
- sortKey === RELATIVE_POSITION_ASC ? largePageSizeParams : defaultPageSizeParams;
+export const getInitialPageParams = (sortKey, afterCursor, beforeCursor) => ({
+ firstPageSize: sortKey === RELATIVE_POSITION_ASC ? PAGE_SIZE_MANUAL : PAGE_SIZE,
+ afterCursor,
+ beforeCursor,
+});
export const getSortKey = (sort) =>
Object.keys(urlSortParams).find((key) => urlSortParams[key] === sort);
diff --git a/app/assets/javascripts/issues/show/components/delete_issue_modal.vue b/app/assets/javascripts/issues/show/components/delete_issue_modal.vue
index 26862346b86..47b09bd6aa0 100644
--- a/app/assets/javascripts/issues/show/components/delete_issue_modal.vue
+++ b/app/assets/javascripts/issues/show/components/delete_issue_modal.vue
@@ -31,7 +31,10 @@ export default {
computed: {
actionPrimary() {
return {
- attributes: { variant: 'danger' },
+ attributes: {
+ variant: 'danger',
+ 'data-qa-selector': 'confirm_delete_issue_button',
+ },
text: this.title,
};
},
diff --git a/app/assets/javascripts/issues/show/components/description.vue b/app/assets/javascripts/issues/show/components/description.vue
index eeccf886b65..68ed7bb4062 100644
--- a/app/assets/javascripts/issues/show/components/description.vue
+++ b/app/assets/javascripts/issues/show/components/description.vue
@@ -10,7 +10,9 @@ import $ from 'jquery';
import createFlash from '~/flash';
import { __, sprintf } from '~/locale';
import TaskList from '~/task_list';
+import Tracking from '~/tracking';
import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
+import WorkItemDetailModal from '~/work_items/components/work_item_detail_modal.vue';
import CreateWorkItem from '~/work_items/pages/create_work_item.vue';
import animateMixin from '../mixins/animate';
@@ -24,8 +26,9 @@ export default {
GlPopover,
CreateWorkItem,
GlButton,
+ WorkItemDetailModal,
},
- mixins: [animateMixin, glFeatureFlagMixin()],
+ mixins: [animateMixin, glFeatureFlagMixin(), Tracking.mixin()],
props: {
canUpdate: {
type: Boolean,
@@ -68,9 +71,13 @@ export default {
initialUpdate: true,
taskButtons: [],
activeTask: {},
+ workItemId: null,
};
},
computed: {
+ showWorkItemDetailModal() {
+ return Boolean(this.workItemId);
+ },
workItemsEnabled() {
return this.glFeatures.workItems;
},
@@ -194,7 +201,13 @@ export default {
closeCreateTaskModal() {
this.$refs.modal.hide();
},
- handleCreateTask(title) {
+ closeWorkItemDetailModal() {
+ this.workItemId = null;
+ },
+ handleWorkItemDetailModalError(message) {
+ createFlash({ message });
+ },
+ handleCreateTask({ id, title, type }) {
const listItem = this.$el.querySelector(`#${this.activeTask.id}`).parentElement;
const taskBadge = document.createElement('span');
taskBadge.innerHTML = `
@@ -204,12 +217,28 @@ export default {
<span class="badge badge-info badge-pill gl-badge sm gl-mr-1">
${__('Task')}
</span>
- <a href="#">${title}</a>
`;
+ const button = this.createWorkItemDetailButton(id, title, type);
+ taskBadge.append(button);
+
listItem.insertBefore(taskBadge, listItem.lastChild);
listItem.removeChild(listItem.lastChild);
this.closeCreateTaskModal();
},
+ createWorkItemDetailButton(id, title, type) {
+ const button = document.createElement('button');
+ button.addEventListener('click', () => {
+ this.workItemId = id;
+ this.track('viewed_work_item_from_modal', {
+ category: 'workItems:show',
+ label: 'work_item_view',
+ property: `type_${type}`,
+ });
+ });
+ button.classList.add('btn-link');
+ button.innerText = title;
+ return button;
+ },
focusButton() {
this.$refs.convertButton[0].$el.focus();
},
@@ -262,6 +291,12 @@ export default {
@onCreate="handleCreateTask"
/>
</gl-modal>
+ <work-item-detail-modal
+ :visible="showWorkItemDetailModal"
+ :work-item-id="workItemId"
+ @close="closeWorkItemDetailModal"
+ @error="handleWorkItemDetailModalError"
+ />
<template v-if="workItemsEnabled">
<gl-popover
v-for="item in taskButtons"
diff --git a/app/assets/javascripts/issues/show/components/fields/description_template.vue b/app/assets/javascripts/issues/show/components/fields/description_template.vue
index 9ce49b65a1a..d528641dcb6 100644
--- a/app/assets/javascripts/issues/show/components/fields/description_template.vue
+++ b/app/assets/javascripts/issues/show/components/fields/description_template.vue
@@ -68,7 +68,10 @@ export default {
data-toggle="dropdown"
>
<span class="dropdown-toggle-text">{{ __('Choose a template') }}</span>
- <gl-icon name="chevron-down" class="gl-absolute gl-top-3 gl-right-3 gl-text-gray-500" />
+ <gl-icon
+ name="chevron-down"
+ class="gl-absolute gl-top-3 gl-right-3 gl-text-gray-500 dropdown-menu-toggle-icon"
+ />
</button>
<div class="dropdown-menu dropdown-select">
<div class="dropdown-title gl-display-flex gl-justify-content-center">
diff --git a/app/assets/javascripts/issues/show/components/header_actions.vue b/app/assets/javascripts/issues/show/components/header_actions.vue
index 8ba08472ea0..adf449aca7b 100644
--- a/app/assets/javascripts/issues/show/components/header_actions.vue
+++ b/app/assets/javascripts/issues/show/components/header_actions.vue
@@ -128,13 +128,21 @@ export default {
});
},
newIssueTypeText() {
- return sprintf(__('New %{issueType}'), { issueType: this.issueType });
+ return sprintf(__('New related %{issueType}'), { issueType: this.issueType });
},
showToggleIssueStateButton() {
const canClose = !this.isClosed && this.canUpdateIssue;
const canReopen = this.isClosed && this.canReopenIssue;
return canClose || canReopen;
},
+ hasDesktopDropdown() {
+ return (
+ this.canCreateIssue || this.canPromoteToEpic || !this.isIssueAuthor || this.canReportSpam
+ );
+ },
+ hasMobileDropdown() {
+ return this.hasDesktopDropdown || this.showToggleIssueStateButton;
+ },
},
created() {
eventHub.$on('toggle.issuable.state', this.toggleIssueState);
@@ -223,10 +231,12 @@ export default {
<template>
<div class="detail-page-header-actions gl-display-flex">
<gl-dropdown
+ v-if="hasMobileDropdown"
class="gl-sm-display-none! w-100"
block
:text="dropdownText"
data-qa-selector="issue_actions_dropdown"
+ data-testid="mobile-dropdown"
:loading="isToggleStateButtonLoading"
>
<gl-dropdown-item
@@ -276,11 +286,14 @@ export default {
</gl-button>
<gl-dropdown
+ v-if="hasDesktopDropdown"
class="gl-display-none gl-sm-display-inline-flex! gl-ml-3"
icon="ellipsis_v"
category="tertiary"
+ data-qa-selector="issue_actions_ellipsis_dropdown"
:text="dropdownText"
:text-sr-only="true"
+ data-testid="desktop-dropdown"
no-caret
right
>
@@ -311,6 +324,7 @@ export default {
<gl-dropdown-item
v-gl-modal="$options.deleteModalId"
variant="danger"
+ data-qa-selector="delete_issue_button"
@click="track('click_dropdown')"
>
{{ deleteButtonText }}
diff --git a/app/assets/javascripts/issues/show/components/incidents/incident_tabs.vue b/app/assets/javascripts/issues/show/components/incidents/incident_tabs.vue
index 4790062ab7d..04ddc7f3501 100644
--- a/app/assets/javascripts/issues/show/components/incidents/incident_tabs.vue
+++ b/app/assets/javascripts/issues/show/components/incidents/incident_tabs.vue
@@ -5,6 +5,7 @@ import { trackIncidentDetailsViewsOptions } from '~/incidents/constants';
import { s__ } from '~/locale';
import Tracking from '~/tracking';
import AlertDetailsTable from '~/vue_shared/components/alert_details_table.vue';
+import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import DescriptionComponent from '../description.vue';
import getAlert from './graphql/queries/get_alert.graphql';
import HighlightBar from './highlight_bar.vue';
@@ -17,7 +18,10 @@ export default {
GlTabs,
HighlightBar,
MetricsTab: () => import('ee_component/issues/show/components/incidents/metrics_tab.vue'),
+ TimelineTab: () =>
+ import('ee_component/issues/show/components/incidents/timeline_events_tab.vue'),
},
+ mixins: [glFeatureFlagsMixin()],
inject: ['fullPath', 'iid', 'uploadMetricsFeatureAvailable'],
apollo: {
alert: {
@@ -47,6 +51,9 @@ export default {
loading() {
return this.$apollo.queries.alert.loading;
},
+ incidentTabEnabled() {
+ return this.glFeatures.incidentTimelineEvents && this.glFeatures.incidentTimelineEventTab;
+ },
},
mounted() {
this.trackPageViews();
@@ -76,6 +83,7 @@ export default {
>
<alert-details-table :alert="alert" :loading="loading" />
</gl-tab>
+ <timeline-tab v-if="incidentTabEnabled" data-testid="timeline-events-tab" />
</gl-tabs>
</div>
</template>
diff --git a/app/assets/javascripts/issues/show/components/title.vue b/app/assets/javascripts/issues/show/components/title.vue
index 5e92211685a..1982147e454 100644
--- a/app/assets/javascripts/issues/show/components/title.vue
+++ b/app/assets/javascripts/issues/show/components/title.vue
@@ -68,7 +68,7 @@ export default {
<template>
<div class="title-container">
- <h2
+ <h1
v-safe-html="titleHtml"
:class="{
'issue-realtime-pre-pulse': preAnimation,
@@ -76,7 +76,7 @@ export default {
}"
class="title qa-title"
dir="auto"
- ></h2>
+ ></h1>
<gl-button
v-if="showInlineEditButton && canUpdate"
v-gl-tooltip.bottom
diff --git a/app/assets/javascripts/issues/show/index.js b/app/assets/javascripts/issues/show/index.js
index f5c71f9691f..c9af5d9b4a7 100644
--- a/app/assets/javascripts/issues/show/index.js
+++ b/app/assets/javascripts/issues/show/index.js
@@ -77,9 +77,7 @@ export function initIssueApp(issueData, store) {
const { fullPath } = el.dataset;
- if (gon?.features?.fixCommentScroll) {
- scrollToTargetOnResize();
- }
+ scrollToTargetOnResize();
bootstrapApollo({ ...issueState, issueType: el.dataset.issueType });
diff --git a/app/assets/javascripts/jira_connect/subscriptions/components/app.vue b/app/assets/javascripts/jira_connect/subscriptions/components/app.vue
index 905e242e977..afdb414e82c 100644
--- a/app/assets/javascripts/jira_connect/subscriptions/components/app.vue
+++ b/app/assets/javascripts/jira_connect/subscriptions/components/app.vue
@@ -3,6 +3,7 @@ import { GlAlert, GlLink, GlSprintf } from '@gitlab/ui';
import { isEmpty } from 'lodash';
import { mapState, mapMutations } from 'vuex';
import { retrieveAlert } from '~/jira_connect/subscriptions/utils';
+import { I18N_DEFAULT_SIGN_IN_ERROR_MESSAGE } from '../constants';
import { SET_ALERT } from '../store/mutation_types';
import SignInPage from '../pages/sign_in.vue';
import SubscriptionsPage from '../pages/subscriptions.vue';
@@ -28,6 +29,11 @@ export default {
default: [],
},
},
+ data() {
+ return {
+ user: null,
+ };
+ },
computed: {
...mapState(['alert']),
shouldShowAlert() {
@@ -37,7 +43,7 @@ export default {
return !isEmpty(this.subscriptions);
},
userSignedIn() {
- return Boolean(!this.usersPath);
+ return Boolean(!this.usersPath || this.user);
},
},
created() {
@@ -51,6 +57,15 @@ export default {
const { linkUrl, title, message, variant } = retrieveAlert() || {};
this.setAlert({ linkUrl, title, message, variant });
},
+ onSignInOauth(user) {
+ this.user = user;
+ },
+ onSignInError() {
+ this.setAlert({
+ message: I18N_DEFAULT_SIGN_IN_ERROR_MESSAGE,
+ variant: 'danger',
+ });
+ },
},
};
</script>
@@ -78,11 +93,16 @@ export default {
</template>
</gl-alert>
- <user-link :user-signed-in="userSignedIn" :has-subscriptions="hasSubscriptions" />
+ <user-link :user-signed-in="userSignedIn" :has-subscriptions="hasSubscriptions" :user="user" />
<h2 class="gl-text-center gl-mb-7">{{ s__('JiraService|GitLab for Jira Configuration') }}</h2>
<div class="gl-layout-w-limited gl-mx-auto gl-px-5 gl-mb-7">
- <sign-in-page v-if="!userSignedIn" :has-subscriptions="hasSubscriptions" />
+ <sign-in-page
+ v-if="!userSignedIn"
+ :has-subscriptions="hasSubscriptions"
+ @sign-in-oauth="onSignInOauth"
+ @error="onSignInError"
+ />
<subscriptions-page v-else :has-subscriptions="hasSubscriptions" />
</div>
</div>
diff --git a/app/assets/javascripts/jira_connect/subscriptions/components/sign_in_button.vue b/app/assets/javascripts/jira_connect/subscriptions/components/sign_in_button.vue
deleted file mode 100644
index 627abcdd4a0..00000000000
--- a/app/assets/javascripts/jira_connect/subscriptions/components/sign_in_button.vue
+++ /dev/null
@@ -1,40 +0,0 @@
-<script>
-import { GlButton } from '@gitlab/ui';
-import { getGitlabSignInURL } from '~/jira_connect/subscriptions/utils';
-import { s__ } from '~/locale';
-
-export default {
- components: {
- GlButton,
- },
- props: {
- usersPath: {
- type: String,
- required: true,
- },
- },
- data() {
- return {
- signInURL: '',
- };
- },
- created() {
- this.setSignInURL();
- },
- methods: {
- async setSignInURL() {
- this.signInURL = await getGitlabSignInURL(this.usersPath);
- },
- },
- i18n: {
- defaultButtonText: s__('Integrations|Sign in to GitLab'),
- },
-};
-</script>
-<template>
- <gl-button category="primary" variant="info" :href="signInURL" target="_blank">
- <slot>
- {{ $options.i18n.defaultButtonText }}
- </slot>
- </gl-button>
-</template>
diff --git a/app/assets/javascripts/jira_connect/subscriptions/components/sign_in_legacy_button.vue b/app/assets/javascripts/jira_connect/subscriptions/components/sign_in_legacy_button.vue
new file mode 100644
index 00000000000..ec718d5b3ca
--- /dev/null
+++ b/app/assets/javascripts/jira_connect/subscriptions/components/sign_in_legacy_button.vue
@@ -0,0 +1,40 @@
+<script>
+import { GlButton } from '@gitlab/ui';
+import { getGitlabSignInURL } from '~/jira_connect/subscriptions/utils';
+import { I18N_DEFAULT_SIGN_IN_BUTTON_TEXT } from '~/jira_connect/subscriptions/constants';
+
+export default {
+ components: {
+ GlButton,
+ },
+ props: {
+ usersPath: {
+ type: String,
+ required: true,
+ },
+ },
+ data() {
+ return {
+ signInURL: '',
+ };
+ },
+ created() {
+ this.setSignInURL();
+ },
+ methods: {
+ async setSignInURL() {
+ this.signInURL = await getGitlabSignInURL(this.usersPath);
+ },
+ },
+ i18n: {
+ defaultButtonText: I18N_DEFAULT_SIGN_IN_BUTTON_TEXT,
+ },
+};
+</script>
+<template>
+ <gl-button category="primary" variant="info" :href="signInURL" target="_blank">
+ <slot>
+ {{ $options.i18n.defaultButtonText }}
+ </slot>
+ </gl-button>
+</template>
diff --git a/app/assets/javascripts/jira_connect/subscriptions/components/sign_in_oauth_button.vue b/app/assets/javascripts/jira_connect/subscriptions/components/sign_in_oauth_button.vue
new file mode 100644
index 00000000000..d7ec909cb28
--- /dev/null
+++ b/app/assets/javascripts/jira_connect/subscriptions/components/sign_in_oauth_button.vue
@@ -0,0 +1,124 @@
+<script>
+import { GlButton } from '@gitlab/ui';
+import axios from '~/lib/utils/axios_utils';
+import {
+ I18N_DEFAULT_SIGN_IN_BUTTON_TEXT,
+ OAUTH_WINDOW_OPTIONS,
+ PKCE_CODE_CHALLENGE_DIGEST_ALGORITHM,
+} from '~/jira_connect/subscriptions/constants';
+import { setUrlParams } from '~/lib/utils/url_utility';
+import AccessorUtilities from '~/lib/utils/accessor';
+
+import { createCodeVerifier, createCodeChallenge } from '../pkce';
+
+export default {
+ components: {
+ GlButton,
+ },
+ inject: ['oauthMetadata'],
+ data() {
+ return {
+ token: null,
+ loading: false,
+ codeVerifier: null,
+ canUseCrypto: AccessorUtilities.canUseCrypto(),
+ };
+ },
+ mounted() {
+ window.addEventListener('message', this.handleWindowMessage);
+ },
+ beforeDestroy() {
+ window.removeEventListener('message', this.handleWindowMessage);
+ },
+ methods: {
+ async startOAuthFlow() {
+ this.loading = true;
+
+ // Generate state necessary for PKCE OAuth flow
+ this.codeVerifier = createCodeVerifier();
+ const codeChallenge = await createCodeChallenge(this.codeVerifier);
+
+ // Build the initial OAuth authorization URL
+ const { oauth_authorize_url: oauthAuthorizeURL } = this.oauthMetadata;
+ const oauthAuthorizeURLWithChallenge = setUrlParams(
+ {
+ code_challenge: codeChallenge,
+ code_challenge_method: PKCE_CODE_CHALLENGE_DIGEST_ALGORITHM.short,
+ },
+ oauthAuthorizeURL,
+ );
+
+ window.open(
+ oauthAuthorizeURLWithChallenge,
+ this.$options.i18n.defaultButtonText,
+ OAUTH_WINDOW_OPTIONS,
+ );
+ },
+ async handleWindowMessage(event) {
+ if (window.origin !== event.origin) {
+ this.loading = false;
+ this.handleError();
+ return;
+ }
+
+ // Verify that OAuth state isn't altered.
+ const state = event.data?.state;
+ if (state !== this.oauthMetadata.state) {
+ this.loading = false;
+ this.handleError();
+ return;
+ }
+
+ // Request access token and load the authenticated user.
+ const code = event.data?.code;
+ try {
+ const accessToken = await this.getOAuthToken(code);
+ await this.loadUser(accessToken);
+ } catch (e) {
+ this.handleError();
+ } finally {
+ this.loading = false;
+ }
+ },
+ handleError() {
+ this.$emit('error');
+ },
+ async getOAuthToken(code) {
+ const {
+ oauth_token_payload: oauthTokenPayload,
+ oauth_token_url: oauthTokenURL,
+ } = this.oauthMetadata;
+ const { data } = await axios.post(oauthTokenURL, {
+ ...oauthTokenPayload,
+ code,
+ code_verifier: this.codeVerifier,
+ });
+
+ return data.access_token;
+ },
+ async loadUser(accessToken) {
+ const { data } = await axios.get('/api/v4/user', {
+ headers: { Authorization: `Bearer ${accessToken}` },
+ });
+
+ this.$emit('sign-in', data);
+ },
+ },
+ i18n: {
+ defaultButtonText: I18N_DEFAULT_SIGN_IN_BUTTON_TEXT,
+ },
+};
+</script>
+<template>
+ <gl-button
+ category="primary"
+ variant="info"
+ :loading="loading"
+ :disabled="!canUseCrypto"
+ @click="startOAuthFlow"
+ >
+ <slot>
+ {{ $options.i18n.defaultButtonText }}
+ </slot>
+ </gl-button>
+</template>
diff --git a/app/assets/javascripts/jira_connect/subscriptions/components/user_link.vue b/app/assets/javascripts/jira_connect/subscriptions/components/user_link.vue
index fad3d2616d8..5e2c83aff65 100644
--- a/app/assets/javascripts/jira_connect/subscriptions/components/user_link.vue
+++ b/app/assets/javascripts/jira_connect/subscriptions/components/user_link.vue
@@ -25,6 +25,11 @@ export default {
type: Boolean,
required: true,
},
+ user: {
+ type: Object,
+ required: false,
+ default: null,
+ },
},
data() {
return {
@@ -32,8 +37,19 @@ export default {
};
},
computed: {
+ gitlabUserName() {
+ return gon.current_username ?? this.user?.username;
+ },
gitlabUserHandle() {
- return `@${gon.current_username}`;
+ return this.gitlabUserName ? `@${this.gitlabUserName}` : undefined;
+ },
+ gitlabUserLink() {
+ return this.gitlabUserPath ?? `${gon.relative_root_url}/${this.gitlabUserName}`;
+ },
+ signedInText() {
+ return this.gitlabUserHandle
+ ? this.$options.i18n.signedInAsUserText
+ : this.$options.i18n.signedInText;
},
},
async created() {
@@ -42,14 +58,15 @@ export default {
i18n: {
signInText: __('Sign in to GitLab'),
signedInAsUserText: __('Signed in to GitLab as %{user_link}'),
+ signedInText: __('Signed in to GitLab'),
},
};
</script>
<template>
<div class="jira-connect-user gl-font-base">
- <gl-sprintf v-if="userSignedIn" :message="$options.i18n.signedInAsUserText">
+ <gl-sprintf v-if="userSignedIn" :message="signedInText">
<template #user_link>
- <gl-link data-testid="gitlab-user-link" :href="gitlabUserPath" target="_blank">
+ <gl-link data-testid="gitlab-user-link" :href="gitlabUserLink" target="_blank">
{{ gitlabUserHandle }}
</gl-link>
</template>
diff --git a/app/assets/javascripts/jira_connect/subscriptions/constants.js b/app/assets/javascripts/jira_connect/subscriptions/constants.js
index 2a65b7bc1fa..d30ebdbb487 100644
--- a/app/assets/javascripts/jira_connect/subscriptions/constants.js
+++ b/app/assets/javascripts/jira_connect/subscriptions/constants.js
@@ -1,5 +1,26 @@
+import { s__ } from '~/locale';
+
export const DEFAULT_GROUPS_PER_PAGE = 10;
export const ALERT_LOCALSTORAGE_KEY = 'gitlab_alert';
export const MINIMUM_SEARCH_TERM_LENGTH = 3;
export const ADD_NAMESPACE_MODAL_ID = 'add-namespace-modal';
+
+export const I18N_DEFAULT_SIGN_IN_BUTTON_TEXT = s__('Integrations|Sign in to GitLab');
+export const I18N_DEFAULT_SIGN_IN_ERROR_MESSAGE = s__('Integrations|Failed to sign in to GitLab.');
+
+const OAUTH_WINDOW_SIZE = 800;
+export const OAUTH_WINDOW_OPTIONS = [
+ 'resizable=yes',
+ 'scrollbars=yes',
+ 'status=yes',
+ `width=${OAUTH_WINDOW_SIZE}`,
+ `height=${OAUTH_WINDOW_SIZE}`,
+ `left=${window.screen.width / 2 - OAUTH_WINDOW_SIZE / 2}`,
+ `top=${window.screen.height / 2 - OAUTH_WINDOW_SIZE / 2}`,
+].join(',');
+
+export const PKCE_CODE_CHALLENGE_DIGEST_ALGORITHM = {
+ long: 'SHA-256',
+ short: 'S256',
+};
diff --git a/app/assets/javascripts/jira_connect/subscriptions/index.js b/app/assets/javascripts/jira_connect/subscriptions/index.js
index cd1fc1d4455..320f0f8aa6c 100644
--- a/app/assets/javascripts/jira_connect/subscriptions/index.js
+++ b/app/assets/javascripts/jira_connect/subscriptions/index.js
@@ -21,7 +21,14 @@ export function initJiraConnect() {
Vue.use(Translate);
Vue.use(GlFeatureFlagsPlugin);
- const { groupsPath, subscriptions, subscriptionsPath, usersPath, gitlabUserPath } = el.dataset;
+ const {
+ groupsPath,
+ subscriptions,
+ subscriptionsPath,
+ usersPath,
+ gitlabUserPath,
+ oauthMetadata,
+ } = el.dataset;
sizeToParent();
return new Vue({
@@ -33,6 +40,7 @@ export function initJiraConnect() {
subscriptionsPath,
usersPath,
gitlabUserPath,
+ oauthMetadata: oauthMetadata ? JSON.parse(oauthMetadata) : null,
},
render(createElement) {
return createElement(JiraConnectApp);
diff --git a/app/assets/javascripts/jira_connect/subscriptions/pages/sign_in.vue b/app/assets/javascripts/jira_connect/subscriptions/pages/sign_in.vue
index 2bce5afc72b..a24ee33b723 100644
--- a/app/assets/javascripts/jira_connect/subscriptions/pages/sign_in.vue
+++ b/app/assets/javascripts/jira_connect/subscriptions/pages/sign_in.vue
@@ -1,14 +1,17 @@
<script>
import { s__ } from '~/locale';
+
+import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import SubscriptionsList from '../components/subscriptions_list.vue';
-import SignInButton from '../components/sign_in_button.vue';
export default {
name: 'SignInPage',
components: {
SubscriptionsList,
- SignInButton,
+ SignInLegacyButton: () => import('../components/sign_in_legacy_button.vue'),
+ SignInOauthButton: () => import('../components/sign_in_oauth_button.vue'),
},
+ mixins: [glFeatureFlagMixin()],
inject: ['usersPath'],
props: {
hasSubscriptions: {
@@ -16,25 +19,47 @@ export default {
required: true,
},
},
+ computed: {
+ useSignInOauthButton() {
+ return this.glFeatures.jiraConnectOauth;
+ },
+ },
i18n: {
- signinButtonTextWithSubscriptions: s__('Integrations|Sign in to add namespaces'),
+ signInButtonTextWithSubscriptions: s__('Integrations|Sign in to add namespaces'),
signInText: s__('JiraService|Sign in to GitLab.com to get started.'),
},
+ methods: {
+ onSignInError() {
+ this.$emit('error');
+ },
+ },
};
</script>
<template>
<div v-if="hasSubscriptions">
<div class="gl-display-flex gl-justify-content-end">
- <sign-in-button :users-path="usersPath">
- {{ $options.i18n.signinButtonTextWithSubscriptions }}
- </sign-in-button>
+ <sign-in-oauth-button
+ v-if="useSignInOauthButton"
+ @sign-in="$emit('sign-in-oauth', $event)"
+ @error="onSignInError"
+ >
+ {{ $options.i18n.signInButtonTextWithSubscriptions }}
+ </sign-in-oauth-button>
+ <sign-in-legacy-button v-else :users-path="usersPath">
+ {{ $options.i18n.signInButtonTextWithSubscriptions }}
+ </sign-in-legacy-button>
</div>
<subscriptions-list />
</div>
<div v-else class="gl-text-center">
<p class="gl-mb-7">{{ $options.i18n.signInText }}</p>
- <sign-in-button class="gl-mb-7" :users-path="usersPath" />
+ <sign-in-oauth-button
+ v-if="useSignInOauthButton"
+ @sign-in="$emit('sign-in-oauth', $event)"
+ @error="onSignInError"
+ />
+ <sign-in-legacy-button v-else class="gl-mb-7" :users-path="usersPath" />
</div>
</template>
diff --git a/app/assets/javascripts/jira_connect/subscriptions/pkce.js b/app/assets/javascripts/jira_connect/subscriptions/pkce.js
new file mode 100644
index 00000000000..18ea5cae860
--- /dev/null
+++ b/app/assets/javascripts/jira_connect/subscriptions/pkce.js
@@ -0,0 +1,60 @@
+import { bufferToBase64, base64ToBase64Url } from '~/authentication/webauthn/util';
+import { PKCE_CODE_CHALLENGE_DIGEST_ALGORITHM } from './constants';
+
+// PKCE codeverifier should have a maximum length of 128 characters.
+// Using 96 bytes generates a string of 128 characters.
+// RFC: https://datatracker.ietf.org/doc/html/rfc7636#section-4.1
+export const CODE_VERIFIER_BYTES = 96;
+
+/**
+ * Generate a cryptographically random string.
+ * @param {Number} lengthBytes
+ * @returns {String} a random string
+ */
+function getRandomString(lengthBytes) {
+ // generate random values and load them into byteArray.
+ const byteArray = new Uint8Array(lengthBytes);
+ window.crypto.getRandomValues(byteArray);
+
+ // Convert array to string
+ const randomString = bufferToBase64(byteArray);
+ return randomString;
+}
+
+/**
+ * Creates a code verifier to be used for OAuth PKCE authentication.
+ * The code verifier has 128 characters.
+ *
+ * RFC: https://datatracker.ietf.org/doc/html/rfc7636#section-4.1
+ * @returns {String} code verifier
+ */
+export function createCodeVerifier() {
+ const verifier = getRandomString(CODE_VERIFIER_BYTES);
+ return base64ToBase64Url(verifier);
+}
+
+/**
+ * Creates a code challenge for OAuth PKCE authentication.
+ * The code challenge is derived from the given [codeVerifier].
+ * [codeVerifier] is tranformed in the following way (as per the RFC):
+ * code_challenge = BASE64URL-ENCODE(SHA256(ASCII(codeVerifier)))
+ *
+ * RFC: https://datatracker.ietf.org/doc/html/rfc7636#section-4.2
+ * @param {String} codeVerifier
+ * @returns {String} code challenge
+ */
+export async function createCodeChallenge(codeVerifier) {
+ // Generate SHA-256 digest of the [codeVerifier]
+ const buffer = new TextEncoder().encode(codeVerifier);
+ const digestArrayBuffer = await window.crypto.subtle.digest(
+ PKCE_CODE_CHALLENGE_DIGEST_ALGORITHM.long,
+ buffer,
+ );
+
+ // Convert digest to a Base64URL-encoded string
+ const digestHash = bufferToBase64(digestArrayBuffer);
+ // Escape string to remove reserved charaters
+ const codeChallenge = base64ToBase64Url(digestHash);
+
+ return codeChallenge;
+}
diff --git a/app/assets/javascripts/jobs/components/job_app.vue b/app/assets/javascripts/jobs/components/job_app.vue
index fe4158a1bd1..85fe5ed7e26 100644
--- a/app/assets/javascripts/jobs/components/job_app.vue
+++ b/app/assets/javascripts/jobs/components/job_app.vue
@@ -3,7 +3,6 @@ import { GlLoadingIcon, GlIcon, GlSafeHtmlDirective as SafeHtml, GlAlert } from
import { GlBreakpointInstance as bp } from '@gitlab/ui/dist/utils';
import { throttle, isEmpty } from 'lodash';
import { mapGetters, mapState, mapActions } from 'vuex';
-import CodeQualityWalkthrough from '~/code_quality_walkthrough/components/step.vue';
import { isScrolledToBottom } from '~/lib/utils/scroll_utils';
import { __, sprintf } from '~/locale';
import CiHeader from '~/vue_shared/components/header_ci_component.vue';
@@ -33,7 +32,6 @@ export default {
GlLoadingIcon,
SharedRunner: () => import('ee_component/jobs/components/shared_runner_limit_block.vue'),
GlAlert,
- CodeQualityWalkthrough,
},
directives: {
SafeHtml,
@@ -69,11 +67,6 @@ export default {
required: false,
default: null,
},
- codeQualityHelpUrl: {
- type: String,
- required: false,
- default: null,
- },
},
computed: {
...mapState([
@@ -123,9 +116,6 @@ export default {
return this.shouldRenderCalloutMessage && !this.hasUnmetPrerequisitesFailure;
},
- shouldRenderCodeQualityWalkthrough() {
- return this.job.status.group === 'failed-with-warnings';
- },
itemName() {
return sprintf(__('Job %{jobName}'), { jobName: this.job.name });
},
@@ -224,11 +214,6 @@ export default {
>
<div v-safe-html="job.callout_message"></div>
</gl-alert>
- <code-quality-walkthrough
- v-if="shouldRenderCodeQualityWalkthrough"
- step="troubleshoot_job"
- :link="codeQualityHelpUrl"
- />
</header>
<!-- EO Header Section -->
@@ -288,7 +273,6 @@ export default {
'sidebar-collapsed': !isSidebarOpen,
'has-archived-block': job.archived,
}"
- :erase-path="job.erase_path"
:size="jobLogSize"
:raw-path="job.raw_path"
:is-scroll-bottom-disabled="isScrollBottomDisabled"
@@ -325,6 +309,7 @@ export default {
'right-sidebar-expanded': isSidebarOpen,
'right-sidebar-collapsed': !isSidebarOpen,
}"
+ :erase-path="job.erase_path"
:artifact-help-url="artifactHelpUrl"
data-testid="job-sidebar"
/>
diff --git a/app/assets/javascripts/jobs/components/job_log_controllers.vue b/app/assets/javascripts/jobs/components/job_log_controllers.vue
index 8e35fd91481..eb6a284dfaf 100644
--- a/app/assets/javascripts/jobs/components/job_log_controllers.vue
+++ b/app/assets/javascripts/jobs/components/job_log_controllers.vue
@@ -5,7 +5,6 @@ import { __, s__, sprintf } from '~/locale';
export default {
i18n: {
- eraseLogButtonLabel: s__('Job|Erase job log and artifacts'),
scrollToBottomButtonLabel: s__('Job|Scroll to bottom'),
scrollToTopButtonLabel: s__('Job|Scroll to top'),
showRawButtonLabel: s__('Job|Show complete raw'),
@@ -18,11 +17,6 @@ export default {
GlTooltip: GlTooltipDirective,
},
props: {
- erasePath: {
- type: String,
- required: false,
- default: null,
- },
size: {
type: Number,
required: true,
@@ -97,20 +91,6 @@ export default {
data-testid="job-raw-link-controller"
icon="doc-text"
/>
-
- <gl-button
- v-if="erasePath"
- v-gl-tooltip.body
- :title="$options.i18n.eraseLogButtonLabel"
- :aria-label="$options.i18n.eraseLogButtonLabel"
- :href="erasePath"
- :data-confirm="__('Are you sure you want to erase this build?')"
- class="gl-ml-3"
- data-testid="job-log-erase-link"
- data-confirm-btn-variant="danger"
- data-method="post"
- icon="remove"
- />
<!-- eo links -->
<!-- scroll buttons -->
diff --git a/app/assets/javascripts/jobs/components/job_sidebar_retry_button.vue b/app/assets/javascripts/jobs/components/job_sidebar_retry_button.vue
index a43b3297d75..a7bf365d35c 100644
--- a/app/assets/javascripts/jobs/components/job_sidebar_retry_button.vue
+++ b/app/assets/javascripts/jobs/components/job_sidebar_retry_button.vue
@@ -1,5 +1,5 @@
<script>
-import { GlButton, GlLink, GlModalDirective } from '@gitlab/ui';
+import { GlButton, GlModalDirective } from '@gitlab/ui';
import { mapGetters } from 'vuex';
import { JOB_SIDEBAR } from '../constants';
@@ -10,7 +10,6 @@ export default {
},
components: {
GlButton,
- GlLink,
},
directives: {
GlModal: GlModalDirective,
@@ -37,9 +36,18 @@ export default {
:aria-label="$options.i18n.retryLabel"
category="primary"
variant="confirm"
- >{{ $options.i18n.retryLabel }}</gl-button
- >
- <gl-link v-else :href="href" class="btn gl-button btn-confirm" data-method="post" rel="nofollow"
- >{{ $options.i18n.retryLabel }}
- </gl-link>
+ icon="retry"
+ data-testid="retry-job-button"
+ />
+
+ <gl-button
+ v-else
+ :href="href"
+ :aria-label="$options.i18n.retryLabel"
+ category="primary"
+ variant="confirm"
+ icon="retry"
+ data-method="post"
+ data-testid="retry-job-link"
+ />
</template>
diff --git a/app/assets/javascripts/jobs/components/log/line_header.vue b/app/assets/javascripts/jobs/components/log/line_header.vue
index 3bb1f58573c..c72d488f844 100644
--- a/app/assets/javascripts/jobs/components/log/line_header.vue
+++ b/app/assets/javascripts/jobs/components/log/line_header.vue
@@ -43,7 +43,7 @@ export default {
<template>
<div
- class="log-line collapsible-line d-flex justify-content-between ws-normal"
+ class="log-line collapsible-line d-flex justify-content-between ws-normal gl-align-items-flex-start"
role="button"
@click="handleOnClick"
>
diff --git a/app/assets/javascripts/jobs/components/sidebar.vue b/app/assets/javascripts/jobs/components/sidebar.vue
index 9aa1503c7c3..1b4c9ebdf7d 100644
--- a/app/assets/javascripts/jobs/components/sidebar.vue
+++ b/app/assets/javascripts/jobs/components/sidebar.vue
@@ -1,7 +1,8 @@
<script>
-import { GlButton, GlIcon } from '@gitlab/ui';
+import { GlButton, GlIcon, GlTooltipDirective } from '@gitlab/ui';
import { isEmpty } from 'lodash';
import { mapActions, mapGetters, mapState } from 'vuex';
+import { s__ } from '~/locale';
import TooltipOnTruncate from '~/vue_shared/components/tooltip_on_truncate/tooltip_on_truncate.vue';
import { JOB_SIDEBAR } from '../constants';
import ArtifactsBlock from './artifacts_block.vue';
@@ -18,10 +19,17 @@ export const forwardDeploymentFailureModalId = 'forward-deployment-failure';
export default {
name: 'JobSidebar',
i18n: {
+ eraseLogButtonLabel: s__('Job|Erase job log and artifacts'),
+ eraseLogConfirmText: s__('Job|Are you sure you want to erase this job log and artifacts?'),
+ cancelJobButtonLabel: s__('Job|Cancel'),
+ retryJobButtonLabel: s__('Job|Retry'),
...JOB_SIDEBAR,
},
borderTopClass: ['gl-border-t-solid', 'gl-border-t-1', 'gl-border-t-gray-100'],
forwardDeploymentFailureModalId,
+ directives: {
+ GlTooltip: GlTooltipDirective,
+ },
components: {
ArtifactsBlock,
CommitBlock,
@@ -41,6 +49,11 @@ export default {
required: false,
default: '',
},
+ erasePath: {
+ type: String,
+ required: false,
+ default: null,
+ },
},
computed: {
...mapGetters(['hasForwardDeploymentFailure']),
@@ -81,8 +94,24 @@ export default {
</h4>
</tooltip-on-truncate>
<div class="gl-flex-grow-1 gl-flex-shrink-0 gl-text-right">
+ <gl-button
+ v-if="erasePath"
+ v-gl-tooltip.left
+ :title="$options.i18n.eraseLogButtonLabel"
+ :aria-label="$options.i18n.eraseLogButtonLabel"
+ :href="erasePath"
+ :data-confirm="$options.i18n.eraseLogConfirmText"
+ class="gl-mr-2"
+ data-testid="job-log-erase-link"
+ data-confirm-btn-variant="danger"
+ data-method="post"
+ icon="remove"
+ />
<job-sidebar-retry-button
v-if="job.retry_path"
+ v-gl-tooltip.left
+ :title="$options.i18n.retryJobButtonLabel"
+ :aria-label="$options.i18n.retryJobButtonLabel"
:category="retryButtonCategory"
:href="job.retry_path"
:modal-id="$options.forwardDeploymentFailureModalId"
@@ -92,12 +121,15 @@ export default {
/>
<gl-button
v-if="job.cancel_path"
+ v-gl-tooltip.left
+ :title="$options.i18n.cancelJobButtonLabel"
+ :aria-label="$options.i18n.cancelJobButtonLabel"
:href="job.cancel_path"
+ icon="cancel"
data-method="post"
data-testid="cancel-button"
rel="nofollow"
- >{{ $options.i18n.cancel }}
- </gl-button>
+ />
</div>
<gl-button
diff --git a/app/assets/javascripts/jobs/components/stages_dropdown.vue b/app/assets/javascripts/jobs/components/stages_dropdown.vue
index 1780afd39e8..7c4811b2d6f 100644
--- a/app/assets/javascripts/jobs/components/stages_dropdown.vue
+++ b/app/assets/javascripts/jobs/components/stages_dropdown.vue
@@ -1,8 +1,12 @@
<script>
-import { GlLink, GlDropdown, GlDropdownItem } from '@gitlab/ui';
+import { GlLink, GlDropdown, GlDropdownItem, GlSprintf } from '@gitlab/ui';
import { isEmpty } from 'lodash';
+import Mousetrap from 'mousetrap';
+import { s__ } from '~/locale';
import CiIcon from '~/vue_shared/components/ci_icon.vue';
import clipboardButton from '~/vue_shared/components/clipboard_button.vue';
+import { clickCopyToClipboardButton } from '~/behaviors/copy_to_clipboard';
+import { keysFor, MR_COPY_SOURCE_BRANCH_NAME } from '~/behaviors/shortcuts/keybindings';
export default {
components: {
@@ -11,6 +15,7 @@ export default {
GlDropdown,
GlDropdownItem,
GlLink,
+ GlSprintf,
},
props: {
pipeline: {
@@ -36,11 +41,43 @@ export default {
isMergeRequestPipeline() {
return Boolean(this.pipeline.flags && this.pipeline.flags.merge_request_pipeline);
},
+ pipelineInfo() {
+ if (!this.hasRef) {
+ return s__('Job|%{boldStart}Pipeline%{boldEnd} %{id}');
+ } else if (!this.isTriggeredByMergeRequest) {
+ return s__('Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{ref}');
+ } else if (!this.isMergeRequestPipeline) {
+ return s__('Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source}');
+ }
+
+ return s__(
+ 'Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source} into %{target}',
+ );
+ },
+ },
+ mounted() {
+ Mousetrap.bind(keysFor(MR_COPY_SOURCE_BRANCH_NAME), this.handleKeyboardCopy);
+ },
+ beforeDestroy() {
+ Mousetrap.unbind(keysFor(MR_COPY_SOURCE_BRANCH_NAME));
},
methods: {
onStageClick(stage) {
this.$emit('requestSidebarStageDropdown', stage);
},
+ handleKeyboardCopy() {
+ let button;
+
+ if (!this.hasRef) {
+ return;
+ } else if (!this.isTriggeredByMergeRequest) {
+ button = this.$refs['copy-source-ref-link'];
+ } else {
+ button = this.$refs['copy-source-branch-link'];
+ }
+
+ clickCopyToClipboardButton(button.$el);
+ },
},
};
</script>
@@ -48,54 +85,72 @@ export default {
<div class="dropdown">
<div class="js-pipeline-info" data-testid="pipeline-info">
<ci-icon :status="pipeline.details.status" />
-
- <span class="font-weight-bold">{{ s__('Job|Pipeline') }}</span>
- <gl-link
- :href="pipeline.path"
- class="js-pipeline-path link-commit"
- data-testid="pipeline-path"
- data-qa-selector="pipeline_path"
- >#{{ pipeline.id }}</gl-link
- >
- <template v-if="hasRef">
- {{ s__('Job|for') }}
-
- <template v-if="isTriggeredByMergeRequest">
+ <gl-sprintf :message="pipelineInfo">
+ <template #bold="{ content }">
+ <span class="font-weight-bold">{{ content }}</span>
+ </template>
+ <template #id>
+ <gl-link
+ :href="pipeline.path"
+ class="js-pipeline-path link-commit"
+ data-testid="pipeline-path"
+ data-qa-selector="pipeline_path"
+ >#{{ pipeline.id }}</gl-link
+ >
+ </template>
+ <template #mrId>
<gl-link
:href="pipeline.merge_request.path"
class="link-commit ref-name"
data-testid="mr-link"
>!{{ pipeline.merge_request.iid }}</gl-link
>
- {{ s__('Job|with') }}
+ </template>
+ <template #ref>
+ <gl-link
+ :href="pipeline.ref.path"
+ class="link-commit ref-name"
+ data-testid="source-ref-link"
+ >{{ pipeline.ref.name }}</gl-link
+ ><clipboard-button
+ ref="copy-source-ref-link"
+ :text="pipeline.ref.name"
+ :title="__('Copy reference')"
+ category="tertiary"
+ size="small"
+ data-testid="copy-source-ref-link"
+ />
+ </template>
+ <template #source>
<gl-link
:href="pipeline.merge_request.source_branch_path"
class="link-commit ref-name"
data-testid="source-branch-link"
>{{ pipeline.merge_request.source_branch }}</gl-link
- >
-
- <template v-if="isMergeRequestPipeline">
- {{ s__('Job|into') }}
- <gl-link
- :href="pipeline.merge_request.target_branch_path"
- class="link-commit ref-name"
- data-testid="target-branch-link"
- >{{ pipeline.merge_request.target_branch }}</gl-link
- >
- </template>
+ ><clipboard-button
+ ref="copy-source-branch-link"
+ :text="pipeline.merge_request.source_branch"
+ :title="__('Copy branch name')"
+ category="tertiary"
+ size="small"
+ data-testid="copy-source-branch-link"
+ />
+ </template>
+ <template #target>
+ <gl-link
+ :href="pipeline.merge_request.target_branch_path"
+ class="link-commit ref-name"
+ data-testid="target-branch-link"
+ >{{ pipeline.merge_request.target_branch }}</gl-link
+ ><clipboard-button
+ :text="pipeline.merge_request.target_branch"
+ :title="__('Copy branch name')"
+ category="tertiary"
+ size="small"
+ data-testid="copy-target-branch-link"
+ />
</template>
- <gl-link v-else :href="pipeline.ref.path" class="link-commit ref-name">{{
- pipeline.ref.name
- }}</gl-link
- ><clipboard-button
- :text="pipeline.ref.name"
- :title="__('Copy reference')"
- category="tertiary"
- size="small"
- data-testid="copy-source-ref-link"
- />
- </template>
+ </gl-sprintf>
</div>
<gl-dropdown :text="selectedStage" class="js-selected-stage gl-w-full gl-mt-3">
diff --git a/app/assets/javascripts/jobs/components/table/constants.js b/app/assets/javascripts/jobs/components/table/constants.js
index 962979ba573..951d9324813 100644
--- a/app/assets/javascripts/jobs/components/table/constants.js
+++ b/app/assets/javascripts/jobs/components/table/constants.js
@@ -1,16 +1,6 @@
import { s__, __ } from '~/locale';
import { DEFAULT_TH_CLASSES } from '~/lib/utils/constants';
-export const GRAPHQL_PAGE_SIZE = 30;
-
-export const initialPaginationState = {
- currentPage: 1,
- prevPageCursor: '',
- nextPageCursor: '',
- first: GRAPHQL_PAGE_SIZE,
- last: null,
-};
-
/* Error constants */
export const POST_FAILURE = 'post_failure';
export const DEFAULT = 'default';
diff --git a/app/assets/javascripts/jobs/components/table/graphql/cache_config.js b/app/assets/javascripts/jobs/components/table/graphql/cache_config.js
new file mode 100644
index 00000000000..b9946925c95
--- /dev/null
+++ b/app/assets/javascripts/jobs/components/table/graphql/cache_config.js
@@ -0,0 +1,30 @@
+import { isEqual } from 'lodash';
+
+export default {
+ typePolicies: {
+ Project: {
+ fields: {
+ jobs: {
+ keyArgs: false,
+ },
+ },
+ },
+ CiJobConnection: {
+ merge(existing = {}, incoming, { args = {} }) {
+ let nodes;
+
+ if (Object.keys(existing).length !== 0 && isEqual(existing?.statuses, args?.statuses)) {
+ nodes = [...existing.nodes, ...incoming.nodes];
+ } else {
+ nodes = [...incoming.nodes];
+ }
+
+ return {
+ nodes,
+ statuses: Array.isArray(args.statuses) ? [...args.statuses] : args.statuses,
+ pageInfo: incoming.pageInfo,
+ };
+ },
+ },
+ },
+};
diff --git a/app/assets/javascripts/jobs/components/table/graphql/queries/get_jobs.query.graphql b/app/assets/javascripts/jobs/components/table/graphql/queries/get_jobs.query.graphql
index 88937185a8c..151e49af87e 100644
--- a/app/assets/javascripts/jobs/components/table/graphql/queries/get_jobs.query.graphql
+++ b/app/assets/javascripts/jobs/components/table/graphql/queries/get_jobs.query.graphql
@@ -1,25 +1,22 @@
-query getJobs(
- $fullPath: ID!
- $first: Int
- $last: Int
- $after: String
- $before: String
- $statuses: [CiJobStatus!]
-) {
+query getJobs($fullPath: ID!, $after: String, $statuses: [CiJobStatus!]) {
project(fullPath: $fullPath) {
id
- jobs(after: $after, before: $before, first: $first, last: $last, statuses: $statuses) {
+ __typename
+ jobs(after: $after, first: 30, statuses: $statuses) {
pageInfo {
endCursor
hasNextPage
hasPreviousPage
startCursor
+ __typename
}
nodes {
+ __typename
artifacts {
nodes {
downloadPath
fileType
+ __typename
}
}
allowFailure
diff --git a/app/assets/javascripts/jobs/components/table/index.js b/app/assets/javascripts/jobs/components/table/index.js
index f24daf90815..1b9c7cdcfdd 100644
--- a/app/assets/javascripts/jobs/components/table/index.js
+++ b/app/assets/javascripts/jobs/components/table/index.js
@@ -4,12 +4,18 @@ import VueApollo from 'vue-apollo';
import JobsTableApp from '~/jobs/components/table/jobs_table_app.vue';
import createDefaultClient from '~/lib/graphql';
import { parseBoolean } from '~/lib/utils/common_utils';
+import cacheConfig from './graphql/cache_config';
Vue.use(VueApollo);
Vue.use(GlToast);
const apolloProvider = new VueApollo({
- defaultClient: createDefaultClient(),
+ defaultClient: createDefaultClient(
+ {},
+ {
+ cacheConfig,
+ },
+ ),
});
export default (containerId = 'js-jobs-table') => {
diff --git a/app/assets/javascripts/jobs/components/table/jobs_table_app.vue b/app/assets/javascripts/jobs/components/table/jobs_table_app.vue
index 81f42c1e293..864e322eecd 100644
--- a/app/assets/javascripts/jobs/components/table/jobs_table_app.vue
+++ b/app/assets/javascripts/jobs/components/table/jobs_table_app.vue
@@ -1,7 +1,6 @@
<script>
-import { GlAlert, GlPagination, GlSkeletonLoader } from '@gitlab/ui';
+import { GlAlert, GlSkeletonLoader, GlIntersectionObserver, GlLoadingIcon } from '@gitlab/ui';
import { __ } from '~/locale';
-import { GRAPHQL_PAGE_SIZE, initialPaginationState } from './constants';
import eventHub from './event_hub';
import GetJobs from './graphql/queries/get_jobs.query.graphql';
import JobsTable from './jobs_table.vue';
@@ -11,14 +10,16 @@ import JobsTableTabs from './jobs_table_tabs.vue';
export default {
i18n: {
errorMsg: __('There was an error fetching the jobs for your project.'),
+ loadingAriaLabel: __('Loading'),
},
components: {
GlAlert,
- GlPagination,
GlSkeletonLoader,
JobsTable,
JobsTableEmptyState,
JobsTableTabs,
+ GlIntersectionObserver,
+ GlLoadingIcon,
},
inject: {
fullPath: {
@@ -31,10 +32,6 @@ export default {
variables() {
return {
fullPath: this.fullPath,
- first: this.pagination.first,
- last: this.pagination.last,
- after: this.pagination.nextPageCursor,
- before: this.pagination.prevPageCursor,
};
},
update(data) {
@@ -57,7 +54,7 @@ export default {
hasError: false,
isAlertDismissed: false,
scope: null,
- pagination: initialPaginationState,
+ firstLoad: true,
};
},
computed: {
@@ -67,14 +64,8 @@ export default {
showEmptyState() {
return this.jobs.list.length === 0 && !this.scope;
},
- prevPage() {
- return Math.max(this.pagination.currentPage - 1, 0);
- },
- nextPage() {
- return this.jobs.pageInfo?.hasNextPage ? this.pagination.currentPage + 1 : null;
- },
- showPaginationControls() {
- return Boolean(this.prevPage || this.nextPage) && !this.$apollo.loading;
+ hasNextPage() {
+ return this.jobs?.pageInfo?.hasNextPage;
},
},
mounted() {
@@ -88,26 +79,22 @@ export default {
this.$apollo.queries.jobs.refetch({ statuses: this.scope });
},
fetchJobsByStatus(scope) {
+ this.firstLoad = true;
+
this.scope = scope;
this.$apollo.queries.jobs.refetch({ statuses: scope });
},
- handlePageChange(page) {
- const { startCursor, endCursor } = this.jobs.pageInfo;
+ fetchMoreJobs() {
+ this.firstLoad = false;
- if (page > this.pagination.currentPage) {
- this.pagination = {
- ...initialPaginationState,
- nextPageCursor: endCursor,
- currentPage: page,
- };
- } else {
- this.pagination = {
- last: GRAPHQL_PAGE_SIZE,
- first: null,
- prevPageCursor: startCursor,
- currentPage: page,
- };
+ if (!this.$apollo.queries.jobs.loading) {
+ this.$apollo.queries.jobs.fetchMore({
+ variables: {
+ fullPath: this.fullPath,
+ after: this.jobs?.pageInfo?.endCursor,
+ },
+ });
}
},
},
@@ -128,7 +115,7 @@ export default {
<jobs-table-tabs @fetchJobsByStatus="fetchJobsByStatus" />
- <div v-if="$apollo.loading" class="gl-mt-5">
+ <div v-if="$apollo.loading && firstLoad" class="gl-mt-5">
<gl-skeleton-loader :width="1248" :height="73">
<circle cx="748.031" cy="37.7193" r="15.0307" />
<circle cx="787.241" cy="37.7193" r="15.0307" />
@@ -149,14 +136,12 @@ export default {
<jobs-table v-else :jobs="jobs.list" />
- <gl-pagination
- v-if="showPaginationControls"
- :value="pagination.currentPage"
- :prev-page="prevPage"
- :next-page="nextPage"
- align="center"
- class="gl-mt-3"
- @input="handlePageChange"
- />
+ <gl-intersection-observer v-if="hasNextPage" @appear="fetchMoreJobs">
+ <gl-loading-icon
+ v-if="$apollo.loading"
+ size="md"
+ :aria-label="$options.i18n.loadingAriaLabel"
+ />
+ </gl-intersection-observer>
</div>
</template>
diff --git a/app/assets/javascripts/jobs/index.js b/app/assets/javascripts/jobs/index.js
index 6e958ea1842..26dd38bbe08 100644
--- a/app/assets/javascripts/jobs/index.js
+++ b/app/assets/javascripts/jobs/index.js
@@ -14,7 +14,6 @@ const initializeJobPage = (element) => {
const {
artifactHelpUrl,
deploymentHelpUrl,
- codeQualityHelpUrl,
runnerSettingsUrl,
subscriptionsMoreMinutesUrl,
endpoint,
@@ -39,7 +38,6 @@ const initializeJobPage = (element) => {
props: {
artifactHelpUrl,
deploymentHelpUrl,
- codeQualityHelpUrl,
runnerSettingsUrl,
subscriptionsMoreMinutesUrl,
endpoint,
diff --git a/app/assets/javascripts/lib/utils/accessor.js b/app/assets/javascripts/lib/utils/accessor.js
index d4a6d70c62c..f7cdc564538 100644
--- a/app/assets/javascripts/lib/utils/accessor.js
+++ b/app/assets/javascripts/lib/utils/accessor.js
@@ -50,8 +50,16 @@ function canUseLocalStorage() {
return safe;
}
+/**
+ * Determines if `window.crypto` is available.
+ */
+function canUseCrypto() {
+ return window.crypto?.subtle !== undefined;
+}
+
const AccessorUtilities = {
canUseLocalStorage,
+ canUseCrypto,
};
export default AccessorUtilities;
diff --git a/app/assets/javascripts/lib/utils/array_utility.js b/app/assets/javascripts/lib/utils/array_utility.js
index 197e7790ed7..04f9cb1cdb5 100644
--- a/app/assets/javascripts/lib/utils/array_utility.js
+++ b/app/assets/javascripts/lib/utils/array_utility.js
@@ -18,3 +18,13 @@ export const swapArrayItems = (array, leftIndex = 0, rightIndex = 0) => {
copy[rightIndex] = temp;
return copy;
};
+
+/**
+ * Return an array with all duplicate items from the given array
+ *
+ * @param {Array} array - The source array
+ * @returns {Array} new array with all duplicate items
+ */
+export const getDuplicateItemsFromArray = (array) => [
+ ...new Set(array.filter((value, index) => array.indexOf(value) !== index)),
+];
diff --git a/app/assets/javascripts/lib/utils/common_utils.js b/app/assets/javascripts/lib/utils/common_utils.js
index cf6ce2c4889..96d019f62f2 100644
--- a/app/assets/javascripts/lib/utils/common_utils.js
+++ b/app/assets/javascripts/lib/utils/common_utils.js
@@ -130,19 +130,6 @@ export const isInViewport = (el, offset = {}) => {
);
};
-export const parseUrl = (url) => {
- const parser = document.createElement('a');
- parser.href = url;
- return parser;
-};
-
-export const parseUrlPathname = (url) => {
- const parsedUrl = parseUrl(url);
- // parsedUrl.pathname will return an absolute path for Firefox and a relative path for IE11
- // We have to make sure we always have an absolute path.
- return parsedUrl.pathname.charAt(0) === '/' ? parsedUrl.pathname : `/${parsedUrl.pathname}`;
-};
-
export const isMetaKey = (e) => e.metaKey || e.ctrlKey || e.altKey || e.shiftKey;
// Identify following special clicks
diff --git a/app/assets/javascripts/lib/utils/ignore_while_pending.js b/app/assets/javascripts/lib/utils/ignore_while_pending.js
new file mode 100644
index 00000000000..e85a573c8f2
--- /dev/null
+++ b/app/assets/javascripts/lib/utils/ignore_while_pending.js
@@ -0,0 +1,26 @@
+/**
+ * This will wrap the given function to make sure that it is only triggered once
+ * while executing asynchronously
+ *
+ * @param {Function} fn some function that returns a promise
+ * @returns A function that will only be triggered *once* while the promise is executing
+ */
+export const ignoreWhilePending = (fn) => {
+ const isPendingMap = new WeakMap();
+ const defaultContext = {};
+
+ // We need this to be a function so we get the `this`
+ return function ignoreWhilePendingInner(...args) {
+ const context = this || defaultContext;
+
+ if (isPendingMap.get(context)) {
+ return Promise.resolve();
+ }
+
+ isPendingMap.set(context, true);
+
+ return fn.apply(this, args).finally(() => {
+ isPendingMap.delete(context);
+ });
+ };
+};
diff --git a/app/assets/javascripts/lib/utils/rails_ujs.js b/app/assets/javascripts/lib/utils/rails_ujs.js
index 6b1985a23ba..b4f425da871 100644
--- a/app/assets/javascripts/lib/utils/rails_ujs.js
+++ b/app/assets/javascripts/lib/utils/rails_ujs.js
@@ -1,5 +1,6 @@
import Rails from '@rails/ujs';
import { confirmViaGlModal } from './confirm_via_gl_modal/confirm_via_gl_modal';
+import { ignoreWhilePending } from './ignore_while_pending';
function monkeyPatchConfirmModal() {
/**
@@ -18,8 +19,10 @@ function monkeyPatchConfirmModal() {
* @param element {HTMLElement} Element that was clicked on
* @returns {boolean}
*/
+ const safeConfirm = ignoreWhilePending(confirmViaGlModal);
+
function confirmViaModal(message, element) {
- confirmViaGlModal(message, element)
+ safeConfirm(message, element)
.then((confirmed) => {
if (confirmed) {
Rails.confirm = () => true;
diff --git a/app/assets/javascripts/lib/utils/resize_observer.js b/app/assets/javascripts/lib/utils/resize_observer.js
index e72c6fe1679..5d194340b9e 100644
--- a/app/assets/javascripts/lib/utils/resize_observer.js
+++ b/app/assets/javascripts/lib/utils/resize_observer.js
@@ -10,22 +10,30 @@ export function createResizeObserver() {
});
}
-// watches for change in size of a container element (e.g. for lazy-loaded images)
-// and scroll the target element to the top of the content area
-// stop watching after any user input. So if user opens sidebar or manually
-// scrolls the page we don't hijack their scroll position
+/**
+ * Watches for change in size of a container element (e.g. for lazy-loaded images)
+ * and scrolls the target note to the top of the content area.
+ * Stops watching after any user input. So if user opens sidebar or manually
+ * scrolls the page we don't hijack their scroll position
+ *
+ * @param {Object} options
+ * @param {string} options.targetId - id of element to scroll to
+ * @param {string} options.container - Selector of element containing target
+ *
+ * @return {ResizeObserver|null} - ResizeObserver instance if target looks like a note DOM ID
+ */
export function scrollToTargetOnResize({
- target = window.location.hash,
+ targetId = window.location.hash.slice(1),
container = '#content-body',
} = {}) {
- if (!target) return null;
+ if (!targetId) return null;
const ro = createResizeObserver();
const containerEl = document.querySelector(container);
let interactionListenersAdded = false;
function keepTargetAtTop() {
- const anchorEl = document.querySelector(target);
+ const anchorEl = document.getElementById(targetId);
if (!anchorEl) return;
diff --git a/app/assets/javascripts/lib/utils/text_markdown.js b/app/assets/javascripts/lib/utils/text_markdown.js
index ec6789d81ec..ac2eb34260c 100644
--- a/app/assets/javascripts/lib/utils/text_markdown.js
+++ b/app/assets/javascripts/lib/utils/text_markdown.js
@@ -9,7 +9,7 @@ const LINK_TAG_PATTERN = '[{text}](url)';
// a bullet point character (*+-) and an optional checkbox ([ ] [x])
// OR a number with a . after it and an optional checkbox ([ ] [x])
// followed by one or more whitespace characters
-const LIST_LINE_HEAD_PATTERN = /^(?<indent>\s*)(?<leader>((?<isOl>[*+-])|(?<isUl>\d+\.))( \[([x ])\])?\s)(?<content>.)?/;
+const LIST_LINE_HEAD_PATTERN = /^(?<indent>\s*)(?<leader>((?<isUl>[*+-])|(?<isOl>\d+\.))( \[([x ])\])?\s)(?<content>.)?/;
function selectedText(text, textarea) {
return text.substring(textarea.selectionStart, textarea.selectionEnd);
@@ -31,8 +31,19 @@ function lineBefore(text, textarea, trimNewlines = true) {
return split[split.length - 1];
}
-function lineAfter(text, textarea) {
- return text.substring(textarea.selectionEnd).trim().split('\n')[0];
+function lineAfter(text, textarea, trimNewlines = true) {
+ let split = text.substring(textarea.selectionEnd);
+
+ if (trimNewlines) {
+ split = split.trim();
+ } else {
+ // remove possible leading newline to get at the real line
+ split = split.replace(/^\n/, '');
+ }
+
+ split = split.split('\n');
+
+ return split[0];
}
function convertMonacoSelectionToAceFormat(sel) {
@@ -329,6 +340,25 @@ function handleSurroundSelectedText(e, textArea) {
}
/* eslint-enable @gitlab/require-i18n-strings */
+/**
+ * Returns the content for a new line following a list item.
+ *
+ * @param {Object} result - regex match of the current line
+ * @param {Object?} nextLineResult - regex match of the next line
+ * @returns string with the new list item
+ */
+function continueOlText(result, nextLineResult) {
+ const { indent, leader } = result.groups;
+ const { indent: nextIndent, isOl: nextIsOl } = nextLineResult?.groups ?? {};
+
+ const [numStr, postfix = ''] = leader.split('.');
+
+ const incrementBy = nextIsOl && nextIndent === indent ? 0 : 1;
+ const num = parseInt(numStr, 10) + incrementBy;
+
+ return `${indent}${num}.${postfix}`;
+}
+
function handleContinueList(e, textArea) {
if (!gon.features?.markdownContinueLists) return;
if (!(e.key === 'Enter')) return;
@@ -339,7 +369,7 @@ function handleContinueList(e, textArea) {
const result = currentLine.match(LIST_LINE_HEAD_PATTERN);
if (result) {
- const { indent, content, leader } = result.groups;
+ const { leader, indent, content, isOl } = result.groups;
const prevLineEmpty = !content;
if (prevLineEmpty) {
@@ -349,12 +379,22 @@ function handleContinueList(e, textArea) {
return;
}
- const itemInsert = `${indent}${leader}`;
+ let itemToInsert;
+
+ if (isOl) {
+ const nextLine = lineAfter(textArea.value, textArea, false);
+ const nextLineResult = nextLine.match(LIST_LINE_HEAD_PATTERN);
+
+ itemToInsert = continueOlText(result, nextLineResult);
+ } else {
+ // isUl
+ itemToInsert = `${indent}${leader}`;
+ }
e.preventDefault();
updateText({
- tag: itemInsert,
+ tag: itemToInsert,
textArea,
blockTag: '',
wrap: false,
@@ -367,6 +407,8 @@ function handleContinueList(e, textArea) {
export function keypressNoteText(e) {
const textArea = this;
+ if ($(textArea).atwho?.('isSelecting')) return;
+
handleContinueList(e, textArea);
handleSurroundSelectedText(e, textArea);
}
diff --git a/app/assets/javascripts/lib/utils/url_utility.js b/app/assets/javascripts/lib/utils/url_utility.js
index 12462a2575e..335cd6a16e5 100644
--- a/app/assets/javascripts/lib/utils/url_utility.js
+++ b/app/assets/javascripts/lib/utils/url_utility.js
@@ -18,6 +18,20 @@ function resetRegExp(regex) {
return regex;
}
+/**
+ * Returns the absolute pathname for a relative or absolute URL string.
+ *
+ * A few examples of inputs and outputs:
+ * 1) 'http://a.com/b/c/d' => '/b/c/d'
+ * 2) '/b/c/d' => '/b/c/d'
+ * 3) 'b/c/d' => '/b/c/d' or '[path]/b/c/d' depending of the current path of the
+ * document.location
+ */
+export const parseUrlPathname = (url) => {
+ const { pathname } = new URL(url, document.location.href);
+ return pathname;
+};
+
// Returns a decoded url parameter value
// - Treats '+' as '%20'
function decodeUrlParameter(val) {
diff --git a/app/assets/javascripts/loading_icon_for_legacy_js.js b/app/assets/javascripts/loading_icon_for_legacy_js.js
new file mode 100644
index 00000000000..d50a4275424
--- /dev/null
+++ b/app/assets/javascripts/loading_icon_for_legacy_js.js
@@ -0,0 +1,53 @@
+import Vue from 'vue';
+import { GlLoadingIcon } from '@gitlab/ui';
+import { __ } from '~/locale';
+
+const defaultValue = (prop) => GlLoadingIcon.props[prop]?.default;
+
+/**
+ * Returns a loading icon/spinner element.
+ *
+ * This should *only* be used in existing legacy areas of code where Vue is not
+ * in use, as part of the migration strategy defined in
+ * https://gitlab.com/groups/gitlab-org/-/epics/7626.
+ *
+ * @param {object} props - The props to configure the spinner.
+ * @param {boolean} props.inline - Display the spinner inline; otherwise, as a block.
+ * @param {string} props.color - The color of the spinner ('dark' or 'light')
+ * @param {string} props.size - The size of the spinner ('sm', 'md', 'lg', 'xl')
+ * @param {string[]} props.classes - Additional classes to apply to the element.
+ * @param {string} props.label - The ARIA label to apply to the spinner.
+ * @returns {HTMLElement}
+ */
+export const loadingIconForLegacyJS = ({
+ inline = defaultValue('inline'),
+ color = defaultValue('color'),
+ size = defaultValue('size'),
+ classes = [],
+ label = __('Loading'),
+} = {}) => {
+ const mountEl = document.createElement('div');
+
+ const vm = new Vue({
+ el: mountEl,
+ render(h) {
+ return h(GlLoadingIcon, {
+ class: classes,
+ props: {
+ inline,
+ color,
+ size,
+ label,
+ },
+ });
+ },
+ });
+
+ // Ensure it's rendered
+ vm.$forceUpdate();
+
+ const el = vm.$el.cloneNode(true);
+ vm.$destroy();
+
+ return el;
+};
diff --git a/app/assets/javascripts/main.js b/app/assets/javascripts/main.js
index f78b4da181e..b3cb93e74f2 100644
--- a/app/assets/javascripts/main.js
+++ b/app/assets/javascripts/main.js
@@ -116,16 +116,18 @@ function deferredInitialisation() {
);
}
- const search = document.querySelector('#search');
- if (search) {
- search.addEventListener(
+ const searchInputBox = document.querySelector('#search');
+ if (searchInputBox) {
+ searchInputBox.addEventListener(
'focus',
() => {
if (gon.features?.newHeaderSearch) {
import(/* webpackChunkName: 'globalSearch' */ '~/header_search')
.then(async ({ initHeaderSearchApp }) => {
- await initHeaderSearchApp();
- document.querySelector('#search').focus();
+ // In case the user started searching before we bootstrapped, let's pass the search along.
+ const initialSearchValue = searchInputBox.value;
+ await initHeaderSearchApp(initialSearchValue);
+ searchInputBox.focus();
})
.catch(() => {});
} else {
@@ -159,6 +161,12 @@ function deferredInitialisation() {
// Adding a helper class to activate animations only after all is rendered
setTimeout(() => $body.addClass('page-initialised'), 1000);
+
+ if (window.gon?.features?.mrAttentionRequests) {
+ import('~/attention_requests')
+ .then((module) => module.default())
+ .catch(() => {});
+ }
}
const $body = $('body');
diff --git a/app/assets/javascripts/member_expiration_date.js b/app/assets/javascripts/member_expiration_date.js
deleted file mode 100644
index a28427eb9ac..00000000000
--- a/app/assets/javascripts/member_expiration_date.js
+++ /dev/null
@@ -1,54 +0,0 @@
-import $ from 'jquery';
-import Pikaday from 'pikaday';
-import { parsePikadayDate, pikadayToString } from './lib/utils/datetime_utility';
-
-// Add datepickers to all `js-access-expiration-date` elements. If those elements are
-// children of an element with the `clearable-input` class, and have a sibling
-// `js-clear-input` element, then show that element when there is a value in the
-// datepicker, and make clicking on that element clear the field.
-//
-export default function memberExpirationDate(selector = '.js-access-expiration-date') {
- function toggleClearInput() {
- $(this)
- .closest('.clearable-input')
- .toggleClass('has-value', $(this).val() !== '');
- }
- const inputs = $(selector);
-
- inputs.each((i, el) => {
- const $input = $(el);
-
- const calendar = new Pikaday({
- field: $input.get(0),
- theme: 'gitlab-theme animate-picker',
- format: 'yyyy-mm-dd',
- minDate: new Date(),
- container: $input.parent().get(0),
- parse: (dateString) => parsePikadayDate(dateString),
- toString: (date) => pikadayToString(date),
- onSelect(dateText) {
- $input.val(calendar.toString(dateText));
-
- toggleClearInput.call($input);
- },
- firstDay: gon.first_day_of_week,
- });
-
- calendar.setDate(parsePikadayDate($input.val()));
- $input.data('pikaday', calendar);
- });
-
- inputs.next('.js-clear-input').on('click', function clicked(event) {
- event.preventDefault();
-
- const input = $(this).closest('.clearable-input').find(selector);
- const calendar = input.data('pikaday');
-
- calendar.setDate(null);
- toggleClearInput.call(input);
- });
-
- inputs.on('blur', toggleClearInput);
-
- inputs.each(toggleClearInput);
-}
diff --git a/app/assets/javascripts/members/components/action_buttons/remove_member_button.vue b/app/assets/javascripts/members/components/action_buttons/remove_member_button.vue
index 01606d07554..27c67e84675 100644
--- a/app/assets/javascripts/members/components/action_buttons/remove_member_button.vue
+++ b/app/assets/javascripts/members/components/action_buttons/remove_member_button.vue
@@ -25,7 +25,8 @@ export default {
},
title: {
type: String,
- required: true,
+ required: false,
+ default: null,
},
icon: {
type: String,
diff --git a/app/assets/javascripts/members/components/action_buttons/user_action_buttons.vue b/app/assets/javascripts/members/components/action_buttons/user_action_buttons.vue
index 594da7f68cc..122e0a142a9 100644
--- a/app/assets/javascripts/members/components/action_buttons/user_action_buttons.vue
+++ b/app/assets/javascripts/members/components/action_buttons/user_action_buttons.vue
@@ -61,7 +61,7 @@ export default {
};
},
removeMemberButtonText() {
- return this.isInvitedUser ? null : __('Remove user');
+ return this.isInvitedUser ? null : __('Remove member');
},
removeMemberButtonIcon() {
return this.isInvitedUser ? 'remove' : '';
@@ -86,7 +86,6 @@ export default {
:icon="removeMemberButtonIcon"
:button-text="removeMemberButtonText"
:button-category="removeMemberButtonCategory"
- :title="s__('Member|Remove member')"
/>
</div>
<div v-else-if="permissions.canOverride && !member.isOverridden" class="gl-px-1">
diff --git a/app/assets/javascripts/members/components/filter_sort/members_filtered_search_bar.vue b/app/assets/javascripts/members/components/filter_sort/members_filtered_search_bar.vue
index 633dee75237..ca60f876c6f 100644
--- a/app/assets/javascripts/members/components/filter_sort/members_filtered_search_bar.vue
+++ b/app/assets/javascripts/members/components/filter_sort/members_filtered_search_bar.vue
@@ -1,5 +1,4 @@
<script>
-import { GlFilteredSearchToken } from '@gitlab/ui';
import { mapState } from 'vuex';
import {
getParameterByName,
@@ -7,46 +6,24 @@ import {
queryToObject,
redirectTo,
} from '~/lib/utils/url_utility';
-import { s__ } from '~/locale';
import {
SEARCH_TOKEN_TYPE,
SORT_QUERY_PARAM_NAME,
ACTIVE_TAB_QUERY_PARAM_NAME,
-} from '~/members/constants';
-import { OPERATOR_IS_ONLY } from '~/vue_shared/components/filtered_search_bar/constants';
+ AVAILABLE_FILTERED_SEARCH_TOKENS,
+} from 'ee_else_ce/members/constants';
import FilteredSearchBar from '~/vue_shared/components/filtered_search_bar/filtered_search_bar_root.vue';
export default {
name: 'MembersFilteredSearchBar',
components: { FilteredSearchBar },
- availableTokens: [
- {
- type: 'two_factor',
- icon: 'lock',
- title: s__('Members|2FA'),
- token: GlFilteredSearchToken,
- unique: true,
- operators: OPERATOR_IS_ONLY,
- options: [
- { value: 'enabled', title: s__('Members|Enabled') },
- { value: 'disabled', title: s__('Members|Disabled') },
- ],
- requiredPermissions: 'canManageMembers',
- },
- {
- type: 'with_inherited_permissions',
- icon: 'group',
- title: s__('Members|Membership'),
- token: GlFilteredSearchToken,
- unique: true,
- operators: OPERATOR_IS_ONLY,
- options: [
- { value: 'exclude', title: s__('Members|Direct') },
- { value: 'only', title: s__('Members|Inherited') },
- ],
- },
- ],
- inject: ['namespace', 'sourceId', 'canManageMembers'],
+ availableTokens: AVAILABLE_FILTERED_SEARCH_TOKENS,
+ inject: {
+ namespace: {},
+ sourceId: {},
+ canManageMembers: {},
+ canFilterByEnterprise: { default: false },
+ },
data() {
return {
initialFilterValue: [],
diff --git a/app/assets/javascripts/members/constants.js b/app/assets/javascripts/members/constants.js
index 273f1acebc7..49ce00a1689 100644
--- a/app/assets/javascripts/members/constants.js
+++ b/app/assets/javascripts/members/constants.js
@@ -1,4 +1,7 @@
-import { __ } from '~/locale';
+import { GlFilteredSearchToken } from '@gitlab/ui';
+
+import { __, s__ } from '~/locale';
+import { OPERATOR_IS_ONLY } from '~/vue_shared/components/filtered_search_bar/constants';
export const FIELD_KEY_ACCOUNT = 'account';
export const FIELD_KEY_SOURCE = 'source';
@@ -82,6 +85,38 @@ export const DEFAULT_SORT = {
sortDesc: false,
};
+export const FILTERED_SEARCH_TOKEN_TWO_FACTOR = {
+ type: 'two_factor',
+ icon: 'lock',
+ title: s__('Members|2FA'),
+ token: GlFilteredSearchToken,
+ unique: true,
+ operators: OPERATOR_IS_ONLY,
+ options: [
+ { value: 'enabled', title: s__('Members|Enabled') },
+ { value: 'disabled', title: s__('Members|Disabled') },
+ ],
+ requiredPermissions: 'canManageMembers',
+};
+
+export const FILTERED_SEARCH_TOKEN_WITH_INHERITED_PERMISSIONS = {
+ type: 'with_inherited_permissions',
+ icon: 'group',
+ title: s__('Members|Membership'),
+ token: GlFilteredSearchToken,
+ unique: true,
+ operators: OPERATOR_IS_ONLY,
+ options: [
+ { value: 'exclude', title: s__('Members|Direct') },
+ { value: 'only', title: s__('Members|Inherited') },
+ ],
+};
+
+export const AVAILABLE_FILTERED_SEARCH_TOKENS = [
+ FILTERED_SEARCH_TOKEN_TWO_FACTOR,
+ FILTERED_SEARCH_TOKEN_WITH_INHERITED_PERMISSIONS,
+];
+
export const AVATAR_SIZE = 48;
export const MEMBER_TYPES = {
diff --git a/app/assets/javascripts/members/index.js b/app/assets/javascripts/members/index.js
index 510e89240f4..0df876cabd7 100644
--- a/app/assets/javascripts/members/index.js
+++ b/app/assets/javascripts/members/index.js
@@ -18,6 +18,7 @@ export const initMembersApp = (el, options) => {
sourceId,
canManageMembers,
canExportMembers,
+ canFilterByEnterprise,
exportCsvPath,
...vuexStoreAttributes
} = parseDataAttributes(el);
@@ -60,6 +61,7 @@ export const initMembersApp = (el, options) => {
currentUserId: gon.current_user_id || null,
sourceId,
canManageMembers,
+ canFilterByEnterprise,
canExportMembers,
exportCsvPath,
},
diff --git a/app/assets/javascripts/merge_conflicts/merge_conflict_resolver_app.vue b/app/assets/javascripts/merge_conflicts/merge_conflict_resolver_app.vue
index 5fcc778a714..fdcb99351a7 100644
--- a/app/assets/javascripts/merge_conflicts/merge_conflict_resolver_app.vue
+++ b/app/assets/javascripts/merge_conflicts/merge_conflict_resolver_app.vue
@@ -1,5 +1,5 @@
<script>
-import { GlSprintf, GlButton, GlButtonGroup } from '@gitlab/ui';
+import { GlSprintf, GlButton, GlButtonGroup, GlLoadingIcon } from '@gitlab/ui';
import { mapGetters, mapState, mapActions } from 'vuex';
import { __ } from '~/locale';
import FileIcon from '~/vue_shared/components/file_icon.vue';
@@ -23,6 +23,7 @@ export default {
GlButton,
GlButtonGroup,
GlSprintf,
+ GlLoadingIcon,
FileIcon,
DiffFileEditor,
InlineConflictLines,
@@ -72,9 +73,7 @@ export default {
</script>
<template>
<div id="conflicts">
- <div v-if="isLoading" class="loading">
- <div class="spinner spinner-md"></div>
- </div>
+ <gl-loading-icon v-if="isLoading" size="md" data-testid="loading-spinner" />
<div v-if="hasError" class="nothing-here-block">
{{ conflictsData.errorMessage }}
</div>
diff --git a/app/assets/javascripts/merge_request_tabs.js b/app/assets/javascripts/merge_request_tabs.js
index ad0117844cd..61f7a079d77 100644
--- a/app/assets/javascripts/merge_request_tabs.js
+++ b/app/assets/javascripts/merge_request_tabs.js
@@ -2,13 +2,8 @@
import { GlBreakpointInstance as bp } from '@gitlab/ui/dist/utils';
import $ from 'jquery';
import Vue from 'vue';
-import {
- getCookie,
- parseUrlPathname,
- isMetaClick,
- parseBoolean,
- scrollToElement,
-} from '~/lib/utils/common_utils';
+import { getCookie, isMetaClick, parseBoolean, scrollToElement } from '~/lib/utils/common_utils';
+import { parseUrlPathname } from '~/lib/utils/url_utility';
import createEventHub from '~/helpers/event_hub_factory';
import BlobForkSuggestion from './blob/blob_fork_suggestion';
import Diff from './diff';
@@ -70,6 +65,103 @@ const FAST_DELAY_FOR_RERENDER = 75;
// Store the `location` object, allowing for easier stubbing in tests
let { location } = window;
+function scrollToContainer(container) {
+ if (location.hash) {
+ const $el = $(`${container} ${location.hash}:not(.match)`);
+
+ if ($el.length) {
+ scrollToElement($el[0]);
+ }
+ }
+}
+
+function computeTopOffset(tabs) {
+ const navbar = document.querySelector('.navbar-gitlab');
+ const peek = document.getElementById('js-peek');
+ let stickyTop;
+
+ stickyTop = navbar ? navbar.offsetHeight : 0;
+ stickyTop = peek ? stickyTop + peek.offsetHeight : stickyTop;
+ stickyTop = tabs ? stickyTop + tabs.offsetHeight : stickyTop;
+
+ return stickyTop;
+}
+
+function mountPipelines() {
+ const pipelineTableViewEl = document.querySelector('#commit-pipeline-table-view');
+ const { mrWidgetData } = gl;
+ const table = new Vue({
+ components: {
+ CommitPipelinesTable: () => import('~/commit/pipelines/pipelines_table.vue'),
+ },
+ provide: {
+ artifactsEndpoint: pipelineTableViewEl.dataset.artifactsEndpoint,
+ artifactsEndpointPlaceholder: pipelineTableViewEl.dataset.artifactsEndpointPlaceholder,
+ targetProjectFullPath: mrWidgetData?.target_project_full_path || '',
+ },
+ render(createElement) {
+ return createElement('commit-pipelines-table', {
+ props: {
+ endpoint: pipelineTableViewEl.dataset.endpoint,
+ emptyStateSvgPath: pipelineTableViewEl.dataset.emptyStateSvgPath,
+ errorStateSvgPath: pipelineTableViewEl.dataset.errorStateSvgPath,
+ canCreatePipelineInTargetProject: Boolean(
+ mrWidgetData?.can_create_pipeline_in_target_project,
+ ),
+ sourceProjectFullPath: mrWidgetData?.source_project_full_path || '',
+ targetProjectFullPath: mrWidgetData?.target_project_full_path || '',
+ projectId: pipelineTableViewEl.dataset.projectId,
+ mergeRequestId: mrWidgetData ? mrWidgetData.iid : null,
+ },
+ });
+ },
+ }).$mount();
+
+ // $mount(el) replaces the el with the new rendered component. We need it in order to mount
+ // it everytime this tab is clicked - https://vuejs.org/v2/api/#vm-mount
+ pipelineTableViewEl.appendChild(table.$el);
+
+ return table;
+}
+
+function destroyPipelines(app) {
+ if (app && app.$destroy) {
+ app.$destroy();
+
+ document.querySelector('#commit-pipeline-table-view').innerHTML = '';
+ }
+
+ return null;
+}
+
+function loadDiffs({ url, sticky }) {
+ return axios.get(`${url}.json${location.search}`).then(({ data }) => {
+ const $container = $('#diffs');
+ $container.html(data.html);
+ initDiffStatsDropdown(sticky);
+
+ localTimeAgo(document.querySelectorAll('#diffs .js-timeago'));
+ syntaxHighlight($('#diffs .js-syntax-highlight'));
+
+ new Diff();
+ scrollToContainer('#diffs');
+
+ $('.diff-file').each((i, el) => {
+ new BlobForkSuggestion({
+ openButtons: $(el).find('.js-edit-blob-link-fork-toggler'),
+ forkButtons: $(el).find('.js-fork-suggestion-button'),
+ cancelButtons: $(el).find('.js-cancel-fork-suggestion-button'),
+ suggestionSections: $(el).find('.js-file-fork-suggestion-section'),
+ actionTextPieces: $(el).find('.js-file-fork-suggestion-section-action'),
+ }).init();
+ });
+ });
+}
+
+function toggleLoader(state) {
+ $('.mr-loading-status .loading').toggleClass('hide', !state);
+}
+
export default class MergeRequestTabs {
constructor({ action, setUrl, stubLocation } = {}) {
this.mergeRequestTabs = document.querySelector('.merge-request-tabs-container');
@@ -107,13 +199,7 @@ export default class MergeRequestTabs {
}
this.bindEvents();
- if (
- this.mergeRequestTabs &&
- this.mergeRequestTabs.querySelector(`a[data-action='${action}']`) &&
- this.mergeRequestTabs.querySelector(`a[data-action='${action}']`).click
- ) {
- this.mergeRequestTabs.querySelector(`a[data-action='${action}']`).click();
- }
+ this.mergeRequestTabs?.querySelector(`a[data-action='${action}']`)?.click?.();
}
bindEvents() {
@@ -132,15 +218,6 @@ export default class MergeRequestTabs {
$('.merge-request-tabs a[data-toggle="tabvue"]').off('click', this.clickTab);
}
- destroyPipelinesView() {
- if (this.commitPipelinesTable) {
- this.commitPipelinesTable.$destroy();
- this.commitPipelinesTable = null;
-
- document.querySelector('#commit-pipeline-table-view').innerHTML = '';
- }
- }
-
storeScroll() {
if (this.currentTab) {
this.scrollPositions[this.currentTab] = document.documentElement.scrollTop;
@@ -207,11 +284,11 @@ export default class MergeRequestTabs {
this.loadCommits(href);
this.expandView();
this.resetViewContainer();
- this.destroyPipelinesView();
+ this.commitPipelinesTable = destroyPipelines(this.commitPipelinesTable);
} else if (action === 'new') {
this.expandView();
this.resetViewContainer();
- this.destroyPipelinesView();
+ this.commitPipelinesTable = destroyPipelines(this.commitPipelinesTable);
} else if (this.isDiffAction(action)) {
if (!isInVueNoteablePage()) {
/*
@@ -228,7 +305,7 @@ export default class MergeRequestTabs {
this.shrinkView();
}
this.expandViewContainer();
- this.destroyPipelinesView();
+ this.commitPipelinesTable = destroyPipelines(this.commitPipelinesTable);
this.commitsTab.classList.remove('active');
} else if (action === 'pipelines') {
this.resetViewContainer();
@@ -247,7 +324,7 @@ export default class MergeRequestTabs {
this.expandView();
}
this.resetViewContainer();
- this.destroyPipelinesView();
+ this.commitPipelinesTable = destroyPipelines(this.commitPipelinesTable);
}
$('.detail-page-description').renderGFM();
@@ -280,16 +357,6 @@ export default class MergeRequestTabs {
this.eventHub.$emit('MergeRequestTabChange', action);
}
- scrollToContainerElement(container) {
- if (location.hash) {
- const $el = $(`${container} ${location.hash}:not(.match)`);
-
- if ($el.length) {
- scrollToElement($el[0]);
- }
- }
- }
-
// Replaces the current merge request-specific action in the URL with a new one
//
// If the action is "notes", the URL is reset to the standard
@@ -356,7 +423,7 @@ export default class MergeRequestTabs {
return;
}
- this.toggleLoading(true);
+ toggleLoader(true);
axios
.get(`${source}.json`)
@@ -365,15 +432,15 @@ export default class MergeRequestTabs {
commitsDiv.innerHTML = data.html;
localTimeAgo(commitsDiv.querySelectorAll('.js-timeago'));
this.commitsLoaded = true;
- this.scrollToContainerElement('#commits');
+ scrollToContainer('#commits');
- this.toggleLoading(false);
+ toggleLoader(false);
return import('./add_context_commits_modal');
})
.then((m) => m.default())
.catch(() => {
- this.toggleLoading(false);
+ toggleLoader(false);
createFlash({
message: __('An error occurred while fetching this tab.'),
});
@@ -381,39 +448,7 @@ export default class MergeRequestTabs {
}
mountPipelinesView() {
- const pipelineTableViewEl = document.querySelector('#commit-pipeline-table-view');
- const { mrWidgetData } = gl;
-
- this.commitPipelinesTable = new Vue({
- components: {
- CommitPipelinesTable: () => import('~/commit/pipelines/pipelines_table.vue'),
- },
- provide: {
- artifactsEndpoint: pipelineTableViewEl.dataset.artifactsEndpoint,
- artifactsEndpointPlaceholder: pipelineTableViewEl.dataset.artifactsEndpointPlaceholder,
- targetProjectFullPath: mrWidgetData?.target_project_full_path || '',
- },
- render(createElement) {
- return createElement('commit-pipelines-table', {
- props: {
- endpoint: pipelineTableViewEl.dataset.endpoint,
- emptyStateSvgPath: pipelineTableViewEl.dataset.emptyStateSvgPath,
- errorStateSvgPath: pipelineTableViewEl.dataset.errorStateSvgPath,
- canCreatePipelineInTargetProject: Boolean(
- mrWidgetData?.can_create_pipeline_in_target_project,
- ),
- sourceProjectFullPath: mrWidgetData?.source_project_full_path || '',
- targetProjectFullPath: mrWidgetData?.target_project_full_path || '',
- projectId: pipelineTableViewEl.dataset.projectId,
- mergeRequestId: mrWidgetData ? mrWidgetData.iid : null,
- },
- });
- },
- }).$mount();
-
- // $mount(el) replaces the el with the new rendered component. We need it in order to mount
- // it everytime this tab is clicked - https://vuejs.org/v2/api/#vm-mount
- pipelineTableViewEl.appendChild(this.commitPipelinesTable.$el);
+ this.commitPipelinesTable = mountPipelines();
}
// load the diff tab content from the backend
@@ -423,57 +458,31 @@ export default class MergeRequestTabs {
return;
}
- // We extract pathname for the current Changes tab anchor href
- // some pages like MergeRequestsController#new has query parameters on that anchor
- const urlPathname = parseUrlPathname(source);
-
- this.toggleLoading(true);
-
- axios
- .get(`${urlPathname}.json${location.search}`)
- .then(({ data }) => {
- const $container = $('#diffs');
- $container.html(data.html);
- initDiffStatsDropdown(this.stickyTop);
-
- localTimeAgo(document.querySelectorAll('#diffs .js-timeago'));
- syntaxHighlight($('#diffs .js-syntax-highlight'));
+ toggleLoader(true);
+ loadDiffs({
+ // We extract pathname for the current Changes tab anchor href
+ // some pages like MergeRequestsController#new has query parameters on that anchor
+ url: parseUrlPathname(source),
+ sticky: computeTopOffset(this.mergeRequestTabs),
+ })
+ .then(() => {
if (this.isDiffAction(this.currentAction)) {
this.expandViewContainer();
}
- this.diffsLoaded = true;
- new Diff();
- this.scrollToContainerElement('#diffs');
-
- $('.diff-file').each((i, el) => {
- new BlobForkSuggestion({
- openButtons: $(el).find('.js-edit-blob-link-fork-toggler'),
- forkButtons: $(el).find('.js-fork-suggestion-button'),
- cancelButtons: $(el).find('.js-cancel-fork-suggestion-button'),
- suggestionSections: $(el).find('.js-file-fork-suggestion-section'),
- actionTextPieces: $(el).find('.js-file-fork-suggestion-section-action'),
- }).init();
- });
-
- this.toggleLoading(false);
+ this.diffsLoaded = true;
})
.catch(() => {
- this.toggleLoading(false);
createFlash({
message: __('An error occurred while fetching this tab.'),
});
+ })
+ .finally(() => {
+ toggleLoader(false);
});
}
- // Show or hide the loading spinner
- //
- // status - Boolean, true to show, false to hide
- toggleLoading(status) {
- $('.mr-loading-status .loading').toggleClass('hide', !status);
- }
-
diffViewType() {
return $('.js-diff-view-buttons button.active').data('viewType');
}
@@ -529,18 +538,4 @@ export default class MergeRequestTabs {
}
}, 0);
}
-
- get stickyTop() {
- let stickyTop = this.navbar ? this.navbar.offsetHeight : 0;
-
- if (this.peek) {
- stickyTop += this.peek.offsetHeight;
- }
-
- if (this.mergeRequestTabs) {
- stickyTop += this.mergeRequestTabs.offsetHeight;
- }
-
- return stickyTop;
- }
}
diff --git a/app/assets/javascripts/monitoring/components/charts/bar.vue b/app/assets/javascripts/monitoring/components/charts/bar.vue
index a4cef5ea256..1e0f4b10297 100644
--- a/app/assets/javascripts/monitoring/components/charts/bar.vue
+++ b/app/assets/javascripts/monitoring/components/charts/bar.vue
@@ -1,5 +1,4 @@
<script>
-import { GlResizeObserverDirective } from '@gitlab/ui';
import { GlBarChart } from '@gitlab/ui/dist/charts';
import { getSvgIconPathContent } from '~/lib/utils/icon_utils';
import { chartHeight } from '../../constants';
@@ -9,9 +8,6 @@ export default {
components: {
GlBarChart,
},
- directives: {
- GlResizeObserverDirective,
- },
props: {
graphData: {
type: Object,
@@ -60,11 +56,6 @@ export default {
formatLegendLabel(query) {
return query.label;
},
- onResize() {
- if (!this.$refs.barChart) return;
- const { width } = this.$refs.barChart.$el.getBoundingClientRect();
- this.width = width;
- },
setSvg(name) {
getSvgIconPathContent(name)
.then((path) => {
@@ -81,17 +72,16 @@ export default {
};
</script>
<template>
- <div v-gl-resize-observer-directive="onResize">
- <gl-bar-chart
- ref="barChart"
- v-bind="$attrs"
- :data="chartData"
- :option="chartOptions"
- :width="width"
- :height="height"
- :x-axis-title="xAxisTitle"
- :y-axis-title="yAxisTitle"
- :x-axis-type="xAxisType"
- />
- </div>
+ <gl-bar-chart
+ ref="barChart"
+ v-bind="$attrs"
+ :responsive="true"
+ :data="chartData"
+ :option="chartOptions"
+ :width="width"
+ :height="height"
+ :x-axis-title="xAxisTitle"
+ :y-axis-title="yAxisTitle"
+ :x-axis-type="xAxisType"
+ />
</template>
diff --git a/app/assets/javascripts/monitoring/components/charts/column.vue b/app/assets/javascripts/monitoring/components/charts/column.vue
index 37251af2049..e8f54b1fa34 100644
--- a/app/assets/javascripts/monitoring/components/charts/column.vue
+++ b/app/assets/javascripts/monitoring/components/charts/column.vue
@@ -1,5 +1,4 @@
<script>
-import { GlResizeObserverDirective } from '@gitlab/ui';
import { GlColumnChart } from '@gitlab/ui/dist/charts';
import { makeDataSeries } from '~/helpers/monitor_helper';
import { getSvgIconPathContent } from '~/lib/utils/icon_utils';
@@ -12,9 +11,6 @@ export default {
components: {
GlColumnChart,
},
- directives: {
- GlResizeObserverDirective,
- },
props: {
graphData: {
type: Object,
@@ -83,11 +79,6 @@ export default {
formatLegendLabel(query) {
return query.label;
},
- onResize() {
- if (!this.$refs.columnChart) return;
- const { width } = this.$refs.columnChart.$el.getBoundingClientRect();
- this.width = width;
- },
setSvg(name) {
getSvgIconPathContent(name)
.then((path) => {
@@ -101,17 +92,16 @@ export default {
};
</script>
<template>
- <div v-gl-resize-observer-directive="onResize">
- <gl-column-chart
- ref="columnChart"
- v-bind="$attrs"
- :bars="barChartData"
- :option="chartOptions"
- :width="width"
- :height="height"
- :x-axis-title="xAxisTitle"
- :y-axis-title="yAxisTitle"
- :x-axis-type="xAxisType"
- />
- </div>
+ <gl-column-chart
+ ref="columnChart"
+ v-bind="$attrs"
+ :responsive="true"
+ :bars="barChartData"
+ :option="chartOptions"
+ :width="width"
+ :height="height"
+ :x-axis-title="xAxisTitle"
+ :y-axis-title="yAxisTitle"
+ :x-axis-type="xAxisType"
+ />
</template>
diff --git a/app/assets/javascripts/monitoring/components/charts/gauge.vue b/app/assets/javascripts/monitoring/components/charts/gauge.vue
index 461ff06be72..0477ff19ffe 100644
--- a/app/assets/javascripts/monitoring/components/charts/gauge.vue
+++ b/app/assets/javascripts/monitoring/components/charts/gauge.vue
@@ -1,5 +1,4 @@
<script>
-import { GlResizeObserverDirective } from '@gitlab/ui';
import { GlGaugeChart } from '@gitlab/ui/dist/charts';
import { isFinite, isArray, isInteger } from 'lodash';
import { getFormatter, SUPPORTED_FORMATS } from '~/lib/utils/unit_format';
@@ -10,9 +9,6 @@ export default {
components: {
GlGaugeChart,
},
- directives: {
- GlResizeObserverDirective,
- },
props: {
graphData: {
type: Object,
@@ -96,27 +92,19 @@ export default {
return this.queryResult || NaN;
},
},
- methods: {
- onResize() {
- if (!this.$refs.gaugeChart) return;
- const { width } = this.$refs.gaugeChart.$el.getBoundingClientRect();
- this.width = width;
- },
- },
};
</script>
<template>
- <div v-gl-resize-observer-directive="onResize">
- <gl-gauge-chart
- ref="gaugeChart"
- v-bind="$attrs"
- :value="value"
- :min="rangeValues.min"
- :max="rangeValues.max"
- :thresholds="thresholdsValue"
- :text="textValue"
- :split-number="splitValue"
- :width="width"
- />
- </div>
+ <gl-gauge-chart
+ ref="gaugeChart"
+ v-bind="$attrs"
+ :responsive="true"
+ :value="value"
+ :min="rangeValues.min"
+ :max="rangeValues.max"
+ :thresholds="thresholdsValue"
+ :text="textValue"
+ :split-number="splitValue"
+ :width="width"
+ />
</template>
diff --git a/app/assets/javascripts/monitoring/components/charts/heatmap.vue b/app/assets/javascripts/monitoring/components/charts/heatmap.vue
index ed888ef022c..12add274a90 100644
--- a/app/assets/javascripts/monitoring/components/charts/heatmap.vue
+++ b/app/assets/javascripts/monitoring/components/charts/heatmap.vue
@@ -1,5 +1,4 @@
<script>
-import { GlResizeObserverDirective } from '@gitlab/ui';
import { GlHeatmap } from '@gitlab/ui/dist/charts';
import { formatDate, timezones, formats } from '../../format_date';
import { graphDataValidatorForValues } from '../../utils';
@@ -8,9 +7,6 @@ export default {
components: {
GlHeatmap,
},
- directives: {
- GlResizeObserverDirective,
- },
props: {
graphData: {
type: Object,
@@ -61,26 +57,18 @@ export default {
return this.graphData.metrics[0];
},
},
- methods: {
- onResize() {
- if (this.$refs.heatmapChart) return;
- const { width } = this.$refs.heatmapChart.$el.getBoundingClientRect();
- this.width = width;
- },
- },
};
</script>
<template>
- <div v-gl-resize-observer-directive="onResize">
- <gl-heatmap
- ref="heatmapChart"
- v-bind="$attrs"
- :data-series="chartData"
- :x-axis-name="xAxisName"
- :y-axis-name="yAxisName"
- :x-axis-labels="xAxisLabels"
- :y-axis-labels="yAxisLabels"
- :width="width"
- />
- </div>
+ <gl-heatmap
+ ref="heatmapChart"
+ v-bind="$attrs"
+ :responsive="true"
+ :data-series="chartData"
+ :x-axis-name="xAxisName"
+ :y-axis-name="yAxisName"
+ :x-axis-labels="xAxisLabels"
+ :y-axis-labels="yAxisLabels"
+ :width="width"
+ />
</template>
diff --git a/app/assets/javascripts/monitoring/components/charts/stacked_column.vue b/app/assets/javascripts/monitoring/components/charts/stacked_column.vue
index a53f899f752..0cf39448d6b 100644
--- a/app/assets/javascripts/monitoring/components/charts/stacked_column.vue
+++ b/app/assets/javascripts/monitoring/components/charts/stacked_column.vue
@@ -1,5 +1,4 @@
<script>
-import { GlResizeObserverDirective } from '@gitlab/ui';
import { GlStackedColumnChart } from '@gitlab/ui/dist/charts';
import { getSvgIconPathContent } from '~/lib/utils/icon_utils';
import { s__ } from '~/locale';
@@ -12,9 +11,6 @@ export default {
components: {
GlStackedColumnChart,
},
- directives: {
- GlResizeObserverDirective,
- },
props: {
graphData: {
type: Object,
@@ -125,32 +121,26 @@ export default {
console.error('SVG could not be rendered correctly: ', e);
});
},
- onResize() {
- if (!this.$refs.chart) return;
- const { width } = this.$refs.chart.$el.getBoundingClientRect();
- this.width = width;
- },
},
};
</script>
<template>
- <div v-gl-resize-observer-directive="onResize">
- <gl-stacked-column-chart
- ref="chart"
- v-bind="$attrs"
- :bars="chartData"
- :option="chartOptions"
- :x-axis-title="xAxisTitle"
- :y-axis-title="yAxisTitle"
- :x-axis-type="xAxisType"
- :group-by="groupBy"
- :width="width"
- :height="height"
- :legend-layout="legendLayout"
- :legend-average-text="legendAverageText"
- :legend-current-text="legendCurrentText"
- :legend-max-text="legendMaxText"
- :legend-min-text="legendMinText"
- />
- </div>
+ <gl-stacked-column-chart
+ ref="chart"
+ v-bind="$attrs"
+ :responsive="true"
+ :bars="chartData"
+ :option="chartOptions"
+ :x-axis-title="xAxisTitle"
+ :y-axis-title="yAxisTitle"
+ :x-axis-type="xAxisType"
+ :group-by="groupBy"
+ :width="width"
+ :height="height"
+ :legend-layout="legendLayout"
+ :legend-average-text="legendAverageText"
+ :legend-current-text="legendCurrentText"
+ :legend-max-text="legendMaxText"
+ :legend-min-text="legendMinText"
+ />
</template>
diff --git a/app/assets/javascripts/monitoring/components/charts/time_series.vue b/app/assets/javascripts/monitoring/components/charts/time_series.vue
index 5529a94874b..a95b143920b 100644
--- a/app/assets/javascripts/monitoring/components/charts/time_series.vue
+++ b/app/assets/javascripts/monitoring/components/charts/time_series.vue
@@ -1,5 +1,5 @@
<script>
-import { GlLink, GlTooltip, GlResizeObserverDirective, GlIcon } from '@gitlab/ui';
+import { GlLink, GlTooltip, GlIcon } from '@gitlab/ui';
import { GlAreaChart, GlLineChart, GlChartSeriesLabel } from '@gitlab/ui/dist/charts';
import { isEmpty, omit, throttle } from 'lodash';
import { makeDataSeries } from '~/helpers/monitor_helper';
@@ -28,9 +28,6 @@ export default {
GlLink,
GlIcon,
},
- directives: {
- GlResizeObserverDirective,
- },
inheritAttrs: false,
props: {
graphData: {
@@ -366,64 +363,58 @@ export default {
eChart.off('datazoom');
eChart.on('datazoom', this.throttledDatazoom);
},
- onResize() {
- if (!this.$refs.chart) return;
- const { width } = this.$refs.chart.$el.getBoundingClientRect();
- this.width = width;
- },
},
};
</script>
<template>
- <div v-gl-resize-observer-directive="onResize">
- <component
- :is="glChartComponent"
- ref="chart"
- v-bind="$attrs"
- :group-id="groupId"
- :data="chartData"
- :option="chartOptions"
- :format-tooltip-text="formatTooltipText"
- :format-annotations-tooltip-text="formatAnnotationsTooltipText"
- :width="width"
- :height="height"
- :legend-layout="legendLayout"
- :legend-average-text="legendAverageText"
- :legend-current-text="legendCurrentText"
- :legend-max-text="legendMaxText"
- :legend-min-text="legendMinText"
- @created="onChartCreated"
- @updated="onChartUpdated"
- >
- <template #tooltip-title>
- <template v-if="tooltip.type === 'deployments'">
- {{ __('Deployed') }}
- </template>
- <div v-else class="text-nowrap">
- {{ tooltip.title }}
- </div>
+ <component
+ :is="glChartComponent"
+ ref="chart"
+ v-bind="$attrs"
+ :responsive="true"
+ :group-id="groupId"
+ :data="chartData"
+ :option="chartOptions"
+ :format-tooltip-text="formatTooltipText"
+ :format-annotations-tooltip-text="formatAnnotationsTooltipText"
+ :width="width"
+ :height="height"
+ :legend-layout="legendLayout"
+ :legend-average-text="legendAverageText"
+ :legend-current-text="legendCurrentText"
+ :legend-max-text="legendMaxText"
+ :legend-min-text="legendMinText"
+ @created="onChartCreated"
+ @updated="onChartUpdated"
+ >
+ <template #tooltip-title>
+ <template v-if="tooltip.type === 'deployments'">
+ {{ __('Deployed') }}
</template>
- <template #tooltip-content>
- <div v-if="tooltip.type === 'deployments'" class="d-flex align-items-center">
- <gl-icon name="commit" class="mr-2" />
- <gl-link :href="tooltip.commitUrl">{{ tooltip.sha }}</gl-link>
- </div>
- <template v-else>
- <div
- v-for="(content, key) in tooltip.content"
- :key="key"
- class="d-flex justify-content-between"
- >
- <gl-chart-series-label :color="isMultiSeries ? content.color : ''">
- {{ content.name }}
- </gl-chart-series-label>
- <div class="gl-ml-7">
- {{ content.value }}
- </div>
+ <div v-else class="text-nowrap">
+ {{ tooltip.title }}
+ </div>
+ </template>
+ <template #tooltip-content>
+ <div v-if="tooltip.type === 'deployments'" class="d-flex align-items-center">
+ <gl-icon name="commit" class="mr-2" />
+ <gl-link :href="tooltip.commitUrl">{{ tooltip.sha }}</gl-link>
+ </div>
+ <template v-else>
+ <div
+ v-for="(content, key) in tooltip.content"
+ :key="key"
+ class="d-flex justify-content-between"
+ >
+ <gl-chart-series-label :color="isMultiSeries ? content.color : ''">
+ {{ content.name }}
+ </gl-chart-series-label>
+ <div class="gl-ml-7">
+ {{ content.value }}
</div>
- </template>
+ </div>
</template>
- </component>
- </div>
+ </template>
+ </component>
</template>
diff --git a/app/assets/javascripts/notes/components/discussion_filter.vue b/app/assets/javascripts/notes/components/discussion_filter.vue
index 102afaf308f..d5a7fc36ace 100644
--- a/app/assets/javascripts/notes/components/discussion_filter.vue
+++ b/app/assets/javascripts/notes/components/discussion_filter.vue
@@ -116,7 +116,7 @@ export default {
<gl-dropdown
v-if="displayFilters"
id="discussion-filter-dropdown"
- class="gl-mr-3 full-width-mobile discussion-filter-container js-discussion-filter-container"
+ class="full-width-mobile discussion-filter-container js-discussion-filter-container"
data-qa-selector="discussion_filter_dropdown"
:text="currentFilter.title"
:disabled="isLoading"
diff --git a/app/assets/javascripts/notes/components/note_header.vue b/app/assets/javascripts/notes/components/note_header.vue
index 0925195d4bb..71d767c3b95 100644
--- a/app/assets/javascripts/notes/components/note_header.vue
+++ b/app/assets/javascripts/notes/components/note_header.vue
@@ -6,6 +6,7 @@ import {
GlSafeHtmlDirective as SafeHtml,
} from '@gitlab/ui';
import { mapActions } from 'vuex';
+import { __ } from '~/locale';
import timeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
import UserNameWithStatus from '../../sidebar/components/assignees/user_name_with_status.vue';
@@ -139,6 +140,10 @@ export default {
return selectedAuthor?.availability || '';
},
},
+ i18n: {
+ showThread: __('Show thread'),
+ hideThread: __('Hide thread'),
+ },
};
</script>
@@ -148,10 +153,16 @@ export default {
<button
class="note-action-button discussion-toggle-button js-vue-toggle-button"
type="button"
+ data-testid="thread-toggle"
@click="handleToggle"
>
<gl-icon ref="chevronIcon" :name="toggleChevronIconName" />
- {{ __('Toggle thread') }}
+ <template v-if="expanded">
+ {{ $options.i18n.hideThread }}
+ </template>
+ <template v-else>
+ {{ $options.i18n.showThread }}
+ </template>
</button>
</div>
<template v-if="hasAuthor">
diff --git a/app/assets/javascripts/notes/components/noteable_discussion.vue b/app/assets/javascripts/notes/components/noteable_discussion.vue
index ddf72587ba3..c4602363da1 100644
--- a/app/assets/javascripts/notes/components/noteable_discussion.vue
+++ b/app/assets/javascripts/notes/components/noteable_discussion.vue
@@ -6,6 +6,7 @@ import createFlash from '~/flash';
import { clearDraft, getDiscussionReplyKey } from '~/lib/utils/autosave';
import { isLoggedIn } from '~/lib/utils/common_utils';
import { confirmAction } from '~/lib/utils/confirm_via_gl_modal/confirm_via_gl_modal';
+import { ignoreWhilePending } from '~/lib/utils/ignore_while_pending';
import { s__, __ } from '~/locale';
import diffLineNoteFormMixin from '~/notes/mixins/diff_line_note_form';
import TimelineEntryItem from '~/vue_shared/components/notes/timeline_entry_item.vue';
@@ -171,7 +172,7 @@ export default {
this.expandDiscussion({ discussionId: this.discussion.id });
}
},
- async cancelReplyForm(shouldConfirm, isDirty) {
+ cancelReplyForm: ignoreWhilePending(async function cancelReplyForm(shouldConfirm, isDirty) {
if (shouldConfirm && isDirty) {
const msg = s__('Notes|Are you sure you want to cancel creating this comment?');
@@ -188,7 +189,7 @@ export default {
this.isReplying = false;
clearDraft(this.autosaveKey);
- },
+ }),
saveReply(noteText, form, callback) {
if (!noteText) {
this.cancelReplyForm();
diff --git a/app/assets/javascripts/notes/components/noteable_note.vue b/app/assets/javascripts/notes/components/noteable_note.vue
index 7bad10616cc..a271ac91f6e 100644
--- a/app/assets/javascripts/notes/components/noteable_note.vue
+++ b/app/assets/javascripts/notes/components/noteable_note.vue
@@ -7,6 +7,7 @@ import { confirmAction } from '~/lib/utils/confirm_via_gl_modal/confirm_via_gl_m
import { INLINE_DIFF_LINES_KEY } from '~/diffs/constants';
import createFlash from '~/flash';
import httpStatusCodes from '~/lib/utils/http_status';
+import { ignoreWhilePending } from '~/lib/utils/ignore_while_pending';
import { truncateSha } from '~/lib/utils/text_utility';
import TimelineEntryItem from '~/vue_shared/components/notes/timeline_entry_item.vue';
import { __, s__, sprintf } from '../../locale';
@@ -350,7 +351,10 @@ export default {
parent: this.$el,
});
},
- async formCancelHandler({ shouldConfirm, isDirty }) {
+ formCancelHandler: ignoreWhilePending(async function formCancelHandler({
+ shouldConfirm,
+ isDirty,
+ }) {
if (shouldConfirm && isDirty) {
const msg = __('Are you sure you want to cancel editing this comment?');
const confirmed = await confirmAction(msg);
@@ -364,7 +368,7 @@ export default {
}
this.isEditing = false;
this.$emit('cancelForm');
- },
+ }),
recoverNoteContent(noteText) {
// we need to do this to prevent noteForm inconsistent content warning
// this is something we intentionally do so we need to recover the content
diff --git a/app/assets/javascripts/packages_and_registries/container_registry/explorer/components/details_page/delete_alert.vue b/app/assets/javascripts/packages_and_registries/container_registry/explorer/components/details_page/delete_alert.vue
index 56d2ff86fb7..1b7d5af6134 100644
--- a/app/assets/javascripts/packages_and_registries/container_registry/explorer/components/details_page/delete_alert.vue
+++ b/app/assets/javascripts/packages_and_registries/container_registry/explorer/components/details_page/delete_alert.vue
@@ -1,7 +1,11 @@
<script>
import { GlSprintf, GlAlert, GlLink } from '@gitlab/ui';
-import { ALERT_MESSAGES, ADMIN_GARBAGE_COLLECTION_TIP } from '../../constants/index';
+import {
+ ALERT_MESSAGES,
+ ADMIN_GARBAGE_COLLECTION_TIP,
+ ALERT_DANGER_IMPORTING,
+} from '../../constants/index';
export default {
components: {
@@ -23,6 +27,7 @@ export default {
},
},
garbageCollectionHelpPagePath: { type: String, required: false, default: '' },
+ containerRegistryImportingHelpPagePath: { type: String, required: false, default: '' },
isAdmin: {
type: Boolean,
default: false,
@@ -48,6 +53,11 @@ export default {
}
return config;
},
+ alertHref() {
+ return this.deleteAlertType === ALERT_DANGER_IMPORTING
+ ? this.containerRegistryImportingHelpPagePath
+ : this.garbageCollectionHelpPagePath;
+ },
},
};
</script>
@@ -61,7 +71,7 @@ export default {
>
<gl-sprintf :message="deleteAlertConfig.message">
<template #docLink="{ content }">
- <gl-link :href="garbageCollectionHelpPagePath" target="_blank">
+ <gl-link :href="alertHref" target="_blank">
{{ content }}
</gl-link>
</template>
diff --git a/app/assets/javascripts/packages_and_registries/container_registry/explorer/components/details_page/details_header.vue b/app/assets/javascripts/packages_and_registries/container_registry/explorer/components/details_page/details_header.vue
index 29c181f04fb..ab0418388cd 100644
--- a/app/assets/javascripts/packages_and_registries/container_registry/explorer/components/details_page/details_header.vue
+++ b/app/assets/javascripts/packages_and_registries/container_registry/explorer/components/details_page/details_header.vue
@@ -4,6 +4,7 @@ import { sprintf, n__, s__ } from '~/locale';
import MetadataItem from '~/vue_shared/components/registry/metadata_item.vue';
import TitleArea from '~/vue_shared/components/registry/title_area.vue';
import timeagoMixin from '~/vue_shared/mixins/timeago';
+import { numberToHumanSize } from '~/lib/utils/number_utils';
import {
UPDATED_AT,
CLEANUP_UNSCHEDULED_TEXT,
@@ -23,7 +24,7 @@ import {
ROOT_IMAGE_TOOLTIP,
} from '../../constants/index';
-import getContainerRepositoryTagsCountQuery from '../../graphql/queries/get_container_repository_tags_count.query.graphql';
+import getContainerRepositoryMetadata from '../../graphql/queries/get_container_repository_metadata.query.graphql';
export default {
name: 'DetailsHeader',
@@ -50,7 +51,7 @@ export default {
},
apollo: {
containerRepository: {
- query: getContainerRepositoryTagsCountQuery,
+ query: getContainerRepositoryMetadata,
variables() {
return {
id: this.image.id,
@@ -101,6 +102,10 @@ export default {
imageName() {
return this.imageDetails.name || ROOT_IMAGE_TEXT;
},
+ formattedSize() {
+ const { size } = this.imageDetails;
+ return size ? numberToHumanSize(Number(size)) : null;
+ },
},
};
</script>
@@ -119,10 +124,15 @@ export default {
:aria-label="rootImageTooltip"
/>
</template>
+
<template #metadata-tags-count>
<metadata-item icon="tag" :text="tagCountText" data-testid="tags-count" />
</template>
+ <template v-if="formattedSize" #metadata-size>
+ <metadata-item icon="disk" :text="formattedSize" data-testid="image-size" />
+ </template>
+
<template #metadata-cleanup>
<metadata-item
icon="expire"
diff --git a/app/assets/javascripts/packages_and_registries/container_registry/explorer/constants/details.js b/app/assets/javascripts/packages_and_registries/container_registry/explorer/constants/details.js
index 8b8769a884d..3c7f7ca9aa8 100644
--- a/app/assets/javascripts/packages_and_registries/container_registry/explorer/constants/details.js
+++ b/app/assets/javascripts/packages_and_registries/container_registry/explorer/constants/details.js
@@ -93,6 +93,10 @@ export const DETAILS_DELETE_IMAGE_ERROR_MESSAGE = s__(
'ContainerRegistry|Something went wrong while scheduling the image for deletion.',
);
+export const DETAILS_IMPORTING_ERROR_MESSAGE = s__(
+ 'ContainerRegistry|Tags temporarily cannot be marked for deletion. Please try again in a few minutes. %{docLinkStart}More details%{docLinkEnd}.',
+);
+
export const DELETE_IMAGE_CONFIRMATION_TITLE = s__('ContainerRegistry|Delete image repository?');
export const DELETE_IMAGE_CONFIRMATION_TEXT = s__(
'ContainerRegistry|Deleting the image repository will delete all images and tags inside. This action cannot be undone. Please type the following to confirm: %{code}',
@@ -133,6 +137,7 @@ export const ALERT_DANGER_TAG = 'danger_tag';
export const ALERT_SUCCESS_TAGS = 'success_tags';
export const ALERT_DANGER_TAGS = 'danger_tags';
export const ALERT_DANGER_IMAGE = 'danger_image';
+export const ALERT_DANGER_IMPORTING = 'danger_importing';
export const DELETE_SCHEDULED = 'DELETE_SCHEDULED';
export const DELETE_FAILED = 'DELETE_FAILED';
@@ -143,6 +148,7 @@ export const ALERT_MESSAGES = {
[ALERT_SUCCESS_TAGS]: DELETE_TAGS_SUCCESS_MESSAGE,
[ALERT_DANGER_TAGS]: DELETE_TAGS_ERROR_MESSAGE,
[ALERT_DANGER_IMAGE]: DETAILS_DELETE_IMAGE_ERROR_MESSAGE,
+ [ALERT_DANGER_IMPORTING]: DETAILS_IMPORTING_ERROR_MESSAGE,
};
export const UNFINISHED_STATUS = 'UNFINISHED';
diff --git a/app/assets/javascripts/packages_and_registries/container_registry/explorer/graphql/queries/get_container_repository_metadata.query.graphql b/app/assets/javascripts/packages_and_registries/container_registry/explorer/graphql/queries/get_container_repository_metadata.query.graphql
new file mode 100644
index 00000000000..f1f67b98407
--- /dev/null
+++ b/app/assets/javascripts/packages_and_registries/container_registry/explorer/graphql/queries/get_container_repository_metadata.query.graphql
@@ -0,0 +1,7 @@
+query getContainerRepositoryMetadata($id: ID!) {
+ containerRepository(id: $id) {
+ id
+ tagsCount
+ size
+ }
+}
diff --git a/app/assets/javascripts/packages_and_registries/container_registry/explorer/graphql/queries/get_container_repository_tags_count.query.graphql b/app/assets/javascripts/packages_and_registries/container_registry/explorer/graphql/queries/get_container_repository_tags_count.query.graphql
deleted file mode 100644
index 9092a71edb0..00000000000
--- a/app/assets/javascripts/packages_and_registries/container_registry/explorer/graphql/queries/get_container_repository_tags_count.query.graphql
+++ /dev/null
@@ -1,6 +0,0 @@
-query getContainerRepositoryTagsCount($id: ID!) {
- containerRepository(id: $id) {
- id
- tagsCount
- }
-}
diff --git a/app/assets/javascripts/packages_and_registries/container_registry/explorer/pages/details.vue b/app/assets/javascripts/packages_and_registries/container_registry/explorer/pages/details.vue
index 931849c9918..71a85d8885e 100644
--- a/app/assets/javascripts/packages_and_registries/container_registry/explorer/pages/details.vue
+++ b/app/assets/javascripts/packages_and_registries/container_registry/explorer/pages/details.vue
@@ -20,6 +20,7 @@ import {
ALERT_SUCCESS_TAGS,
ALERT_DANGER_TAGS,
ALERT_DANGER_IMAGE,
+ ALERT_DANGER_IMPORTING,
FETCH_IMAGES_LIST_ERROR_MESSAGE,
UNFINISHED_STATUS,
MISSING_OR_DELETED_IMAGE_BREADCRUMB,
@@ -32,6 +33,8 @@ import deleteContainerRepositoryTagsMutation from '../graphql/mutations/delete_c
import getContainerRepositoryDetailsQuery from '../graphql/queries/get_container_repository_details.query.graphql';
import getContainerRepositoryTagsQuery from '../graphql/queries/get_container_repository_tags.query.graphql';
+const REPOSITORY_IMPORTING_ERROR_MESSAGE = 'repository importing';
+
export default {
name: 'RegistryDetailsPage',
components: {
@@ -147,12 +150,17 @@ export default {
});
if (data?.destroyContainerRepositoryTags?.errors[0]) {
- throw new Error();
+ throw new Error(data.destroyContainerRepositoryTags.errors[0]);
}
this.deleteAlertType =
itemsToBeDeleted.length === 0 ? ALERT_SUCCESS_TAG : ALERT_SUCCESS_TAGS;
} catch (e) {
- this.deleteAlertType = itemsToBeDeleted.length === 0 ? ALERT_DANGER_TAG : ALERT_DANGER_TAGS;
+ if (e.message === REPOSITORY_IMPORTING_ERROR_MESSAGE) {
+ this.deleteAlertType = ALERT_DANGER_IMPORTING;
+ } else {
+ this.deleteAlertType =
+ itemsToBeDeleted.length === 0 ? ALERT_DANGER_TAG : ALERT_DANGER_TAGS;
+ }
}
this.mutationLoading = false;
@@ -188,6 +196,7 @@ export default {
<delete-alert
v-model="deleteAlertType"
:garbage-collection-help-page-path="config.garbageCollectionHelpPagePath"
+ :container-registry-importing-help-page-path="config.containerRegistryImportingHelpPagePath"
:is-admin="config.isAdmin"
class="gl-my-2"
/>
diff --git a/app/assets/javascripts/packages_and_registries/container_registry/explorer/pages/list.vue b/app/assets/javascripts/packages_and_registries/container_registry/explorer/pages/list.vue
index e2acebf39d6..5f9e614bebb 100644
--- a/app/assets/javascripts/packages_and_registries/container_registry/explorer/pages/list.vue
+++ b/app/assets/javascripts/packages_and_registries/container_registry/explorer/pages/list.vue
@@ -13,9 +13,8 @@ import getContainerRepositoriesQuery from 'shared_queries/container_registry/get
import createFlash from '~/flash';
import CleanupPolicyEnabledAlert from '~/packages_and_registries/shared/components/cleanup_policy_enabled_alert.vue';
import { FILTERED_SEARCH_TERM } from '~/packages_and_registries/shared/constants';
-import { extractFilterAndSorting } from '~/packages_and_registries/shared/utils';
import Tracking from '~/tracking';
-import RegistrySearch from '~/vue_shared/components/registry/registry_search.vue';
+import PersistedSearch from '~/packages_and_registries/shared/components/persisted_search.vue';
import DeleteImage from '../components/delete_image.vue';
import RegistryHeader from '../components/list_page/registry_header.vue';
@@ -61,8 +60,8 @@ export default {
GlSkeletonLoader,
RegistryHeader,
DeleteImage,
- RegistrySearch,
CleanupPolicyEnabledAlert,
+ PersistedSearch,
},
directives: {
GlTooltip: GlTooltipDirective,
@@ -130,8 +129,7 @@ export default {
containerRepositoriesCount: 0,
itemToDelete: {},
deleteAlertType: null,
- filter: [],
- sorting: { orderBy: 'UPDATED', sort: 'desc' },
+ sorting: null,
name: null,
mutationLoading: false,
fetchBaseQuery: false,
@@ -154,7 +152,7 @@ export default {
queryVariables() {
return {
name: this.name,
- sort: this.sortBy,
+ sort: this.sorting,
fullPath: this.config.isGroupPage ? this.config.groupPath : this.config.projectPath,
isGroupPage: this.config.isGroupPage,
first: GRAPHQL_PAGE_SIZE,
@@ -182,24 +180,6 @@ export default {
? DELETE_IMAGE_SUCCESS_MESSAGE
: DELETE_IMAGE_ERROR_MESSAGE;
},
- sortBy() {
- const { orderBy, sort } = this.sorting;
- return `${orderBy}_${sort}`.toUpperCase();
- },
- },
- mounted() {
- const { sorting, filters } = extractFilterAndSorting(this.$route.query);
-
- this.filter = [...filters];
- this.name = filters[0]?.value.data;
- this.sorting = { ...this.sorting, ...sorting };
-
- // If the two graphql calls - which are not batched - resolve togheter we will have a race
- // condition when apollo sets the cache, with this we give the 'base' call an headstart
- this.fetchBaseQuery = true;
- setTimeout(() => {
- this.fetchAdditionalDetails = true;
- }, 200);
},
methods: {
deleteImage(item) {
@@ -258,18 +238,20 @@ export default {
this.track('confirm_delete');
this.mutationLoading = true;
},
- updateSorting(value) {
- this.sorting = {
- ...this.sorting,
- ...value,
- };
- },
- doFilter() {
- const search = this.filter.find((i) => i.type === FILTERED_SEARCH_TERM);
+ handleSearchUpdate({ sort, filters }) {
+ this.sorting = sort;
+
+ const search = filters.find((i) => i.type === FILTERED_SEARCH_TERM);
this.name = search?.value?.data;
- },
- updateUrlQueryString(query) {
- this.$router.push({ query });
+
+ if (!this.fetchBaseQuery && !this.fetchAdditionalDetails) {
+ // If the two graphql calls - which are not batched - resolve together we will have a race
+ // condition when apollo sets the cache, with this we give the 'base' call an headstart
+ this.fetchBaseQuery = true;
+ setTimeout(() => {
+ this.fetchAdditionalDetails = true;
+ }, 200);
+ }
},
},
};
@@ -332,16 +314,12 @@ export default {
/>
</template>
</registry-header>
-
- <registry-search
- :filter="filter"
- :sorting="sorting"
- :tokens="[]"
+ <persisted-search
+ class="gl-mb-5"
:sortable-fields="$options.searchConfig"
- @sorting:changed="updateSorting"
- @filter:changed="filter = $event"
- @filter:submit="doFilter"
- @query:changed="updateUrlQueryString"
+ :default-order="$options.searchConfig[0].orderBy"
+ default-sort="desc"
+ @update="handleSearchUpdate"
/>
<div v-if="isLoading" class="gl-mt-5">
diff --git a/app/assets/javascripts/packages_and_registries/settings/project/components/settings_form.vue b/app/assets/javascripts/packages_and_registries/settings/project/components/settings_form.vue
index 6030af9d2c3..ae2d5f4fbc5 100644
--- a/app/assets/javascripts/packages_and_registries/settings/project/components/settings_form.vue
+++ b/app/assets/javascripts/packages_and_registries/settings/project/components/settings_form.vue
@@ -13,7 +13,6 @@ import {
REMOVE_INFO_TEXT,
EXPIRATION_SCHEDULE_LABEL,
NAME_REGEX_LABEL,
- NAME_REGEX_PLACEHOLDER,
NAME_REGEX_DESCRIPTION,
CADENCE_LABEL,
EXPIRATION_POLICY_FOOTER_NOTE,
@@ -68,7 +67,6 @@ export default {
REMOVE_INFO_TEXT,
EXPIRATION_SCHEDULE_LABEL,
NAME_REGEX_LABEL,
- NAME_REGEX_PLACEHOLDER,
NAME_REGEX_DESCRIPTION,
CADENCE_LABEL,
EXPIRATION_POLICY_FOOTER_NOTE,
@@ -141,6 +139,17 @@ export default {
[model]: state,
};
},
+ encapsulateError(path, message) {
+ return {
+ graphQLErrors: [
+ {
+ extensions: {
+ problems: [{ path: [path], message }],
+ },
+ },
+ ],
+ };
+ },
submit() {
this.track('submit_form');
this.apiErrors = {};
@@ -156,7 +165,8 @@ export default {
.then(({ data }) => {
const errorMessage = data?.updateContainerExpirationPolicy?.errors[0];
if (errorMessage) {
- this.$toast.show(errorMessage);
+ const customError = this.encapsulateError('nameRegex', errorMessage);
+ throw customError;
} else {
this.$toast.show(UPDATE_SETTINGS_SUCCESS_MESSAGE);
}
@@ -273,7 +283,6 @@ export default {
:error="apiErrors.nameRegex"
:disabled="isFieldDisabled"
:label="$options.i18n.NAME_REGEX_LABEL"
- :placeholder="$options.i18n.NAME_REGEX_PLACEHOLDER"
:description="$options.i18n.NAME_REGEX_DESCRIPTION"
name="remove-regex"
data-testid="remove-regex-input"
diff --git a/app/assets/javascripts/packages_and_registries/settings/project/constants.js b/app/assets/javascripts/packages_and_registries/settings/project/constants.js
index 4d477fbd05d..841585c5646 100644
--- a/app/assets/javascripts/packages_and_registries/settings/project/constants.js
+++ b/app/assets/javascripts/packages_and_registries/settings/project/constants.js
@@ -32,7 +32,6 @@ export const REMOVE_INFO_TEXT = s__(
);
export const EXPIRATION_SCHEDULE_LABEL = s__('ContainerRegistry|Remove tags older than:');
export const NAME_REGEX_LABEL = s__('ContainerRegistry|Remove tags matching:');
-export const NAME_REGEX_PLACEHOLDER = '.*';
export const NAME_REGEX_DESCRIPTION = s__(
'ContainerRegistry|Tags with names that match this regex pattern are removed. %{linkStart}View regex examples.%{linkEnd}',
);
diff --git a/app/assets/javascripts/packages_and_registries/settings/project/graphql/utils/cache_update.js b/app/assets/javascripts/packages_and_registries/settings/project/graphql/utils/cache_update.js
index c4b2af13862..5e0be3834cb 100644
--- a/app/assets/javascripts/packages_and_registries/settings/project/graphql/utils/cache_update.js
+++ b/app/assets/javascripts/packages_and_registries/settings/project/graphql/utils/cache_update.js
@@ -10,6 +10,7 @@ export const updateContainerExpirationPolicy = (projectPath) => (client, { data:
const data = produce(sourceData, (draftState) => {
draftState.project.containerExpirationPolicy = {
+ ...draftState.project.containerExpirationPolicy,
...updatedData.updateContainerExpirationPolicy.containerExpirationPolicy,
};
});
diff --git a/app/assets/javascripts/pages/admin/applications/index.js b/app/assets/javascripts/pages/admin/applications/index.js
new file mode 100644
index 00000000000..3397b02aeba
--- /dev/null
+++ b/app/assets/javascripts/pages/admin/applications/index.js
@@ -0,0 +1,3 @@
+import initApplicationDeleteButtons from '~/admin/applications';
+
+initApplicationDeleteButtons();
diff --git a/app/assets/javascripts/pages/admin/clusters/new/index.js b/app/assets/javascripts/pages/admin/clusters/connect/index.js
index de9ded87ef3..de9ded87ef3 100644
--- a/app/assets/javascripts/pages/admin/clusters/new/index.js
+++ b/app/assets/javascripts/pages/admin/clusters/connect/index.js
diff --git a/app/assets/javascripts/pages/admin/topics/edit/index.js b/app/assets/javascripts/pages/admin/topics/edit/index.js
index c4e05bbd092..f5e6d044865 100644
--- a/app/assets/javascripts/pages/admin/topics/edit/index.js
+++ b/app/assets/javascripts/pages/admin/topics/edit/index.js
@@ -2,7 +2,10 @@ import $ from 'jquery';
import GLForm from '~/gl_form';
import initFilePickers from '~/file_pickers';
import ZenMode from '~/zen_mode';
+import initRemoveAvatar from '~/admin/topics';
new GLForm($('.js-project-topic-form')); // eslint-disable-line no-new
initFilePickers();
new ZenMode(); // eslint-disable-line no-new
+
+initRemoveAvatar();
diff --git a/app/assets/javascripts/pages/dashboard/todos/index/todos.js b/app/assets/javascripts/pages/dashboard/todos/index/todos.js
index cabb1b24ae6..c4bbbdcd8ec 100644
--- a/app/assets/javascripts/pages/dashboard/todos/index/todos.js
+++ b/app/assets/javascripts/pages/dashboard/todos/index/todos.js
@@ -96,6 +96,8 @@ export default class Todos {
target.setAttribute('disabled', true);
target.classList.add('disabled');
+ target.querySelector('.gl-spinner-container').classList.add('gl-mr-2');
+
axios[target.dataset.method](target.dataset.href)
.then(({ data }) => {
this.updateRowState(target);
@@ -118,6 +120,8 @@ export default class Todos {
target.removeAttribute('disabled');
target.classList.remove('disabled');
+ target.querySelector('.gl-spinner-container').classList.remove('gl-mr-2');
+
if (isInactive === true) {
restoreBtn.classList.add('hidden');
doneBtn.classList.remove('hidden');
@@ -140,6 +144,8 @@ export default class Todos {
target.setAttribute('disabled', true);
target.classList.add('disabled');
+ target.querySelector('.gl-spinner-container').classList.add('gl-mr-2');
+
axios[target.dataset.method](target.dataset.href, {
ids: this.todo_ids,
})
@@ -163,6 +169,8 @@ export default class Todos {
target.removeAttribute('disabled');
target.classList.remove('disabled');
+ target.querySelector('.gl-spinner-container').classList.remove('gl-mr-2');
+
this.todo_ids = target === markAllDoneBtn ? data.updated_ids : [];
undoAllBtn.classList.toggle('hidden');
markAllDoneBtn.classList.toggle('hidden');
diff --git a/app/assets/javascripts/pages/groups/clusters/new/index.js b/app/assets/javascripts/pages/groups/clusters/connect/index.js
index de9ded87ef3..de9ded87ef3 100644
--- a/app/assets/javascripts/pages/groups/clusters/new/index.js
+++ b/app/assets/javascripts/pages/groups/clusters/connect/index.js
diff --git a/app/assets/javascripts/pages/groups/group_members/index.js b/app/assets/javascripts/pages/groups/group_members/index.js
index 14ce3f775b1..280b544af3c 100644
--- a/app/assets/javascripts/pages/groups/group_members/index.js
+++ b/app/assets/javascripts/pages/groups/group_members/index.js
@@ -1,16 +1,12 @@
import { groupMemberRequestFormatter } from '~/groups/members/utils';
-import groupsSelect from '~/groups_select';
import initInviteGroupTrigger from '~/invite_members/init_invite_group_trigger';
import initInviteGroupsModal from '~/invite_members/init_invite_groups_modal';
-import initInviteMembersForm from '~/invite_members/init_invite_members_form';
import initInviteMembersModal from '~/invite_members/init_invite_members_modal';
import initInviteMembersTrigger from '~/invite_members/init_invite_members_trigger';
import { s__ } from '~/locale';
-import memberExpirationDate from '~/member_expiration_date';
import { initMembersApp } from '~/members';
import { MEMBER_TYPES } from '~/members/constants';
import { groupLinkRequestFormatter } from '~/members/utils';
-import UsersSelect from '~/users_select';
const SHARED_FIELDS = ['account', 'maxRole', 'expiration', 'actions'];
@@ -22,7 +18,7 @@ initMembersApp(document.querySelector('.js-group-members-list-app'), {
requestFormatter: groupMemberRequestFormatter,
filteredSearchBar: {
show: true,
- tokens: ['two_factor', 'with_inherited_permissions'],
+ tokens: ['two_factor', 'with_inherited_permissions', 'enterprise'],
searchParam: 'search',
placeholder: s__('Members|Filter members'),
recentSearchesStorageKey: 'group_members',
@@ -53,16 +49,7 @@ initMembersApp(document.querySelector('.js-group-members-list-app'), {
},
});
-groupsSelect();
-memberExpirationDate();
-memberExpirationDate('.js-access-expiration-date-groups');
initInviteMembersModal();
initInviteGroupsModal();
initInviteMembersTrigger();
initInviteGroupTrigger();
-
-// This is only used when `invite_members_group_modal` feature flag is disabled.
-// This can be removed when `invite_members_group_modal` feature flag is removed.
-initInviteMembersForm();
-
-new UsersSelect(); // eslint-disable-line no-new
diff --git a/app/assets/javascripts/pages/jira_connect/oauth_callbacks/index.js b/app/assets/javascripts/pages/jira_connect/oauth_callbacks/index.js
new file mode 100644
index 00000000000..3fe238dcb35
--- /dev/null
+++ b/app/assets/javascripts/pages/jira_connect/oauth_callbacks/index.js
@@ -0,0 +1,28 @@
+function getOriginURL() {
+ const origin = new URL(window.opener.location);
+ origin.hash = '';
+ origin.search = '';
+
+ return origin;
+}
+
+function postMessageToJiraConnectApp(data) {
+ window.opener.postMessage(data, getOriginURL().toString());
+}
+
+function initOAuthCallbacks() {
+ const params = new URLSearchParams(window.location.search);
+ if (params.has('code') && params.has('state')) {
+ postMessageToJiraConnectApp({
+ success: true,
+ code: params.get('code'),
+ state: params.get('state'),
+ });
+ } else {
+ postMessageToJiraConnectApp({ success: false });
+ }
+
+ window.close();
+}
+
+initOAuthCallbacks();
diff --git a/app/assets/javascripts/pages/projects/blob/show/index.js b/app/assets/javascripts/pages/projects/blob/show/index.js
index 2fc9a111405..740fdb8a96a 100644
--- a/app/assets/javascripts/pages/projects/blob/show/index.js
+++ b/app/assets/javascripts/pages/projects/blob/show/index.js
@@ -1,4 +1,5 @@
import Vue from 'vue';
+import Vuex from 'vuex';
import VueApollo from 'vue-apollo';
import VueRouter from 'vue-router';
import TableOfContents from '~/blob/components/table_contents.vue';
@@ -11,7 +12,9 @@ import initWebIdeLink from '~/pages/projects/shared/web_ide_link';
import commitPipelineStatus from '~/projects/tree/components/commit_pipeline_status_component.vue';
import BlobContentViewer from '~/repository/components/blob_content_viewer.vue';
import '~/sourcegraph/load';
+import createStore from '~/code_navigation/store';
+Vue.use(Vuex);
Vue.use(VueApollo);
Vue.use(VueRouter);
@@ -29,6 +32,7 @@ if (viewBlobEl) {
// eslint-disable-next-line no-new
new Vue({
el: viewBlobEl,
+ store: createStore(),
router,
apolloProvider,
provide: {
@@ -78,7 +82,7 @@ GpgBadges.fetch();
const codeNavEl = document.getElementById('js-code-navigation');
-if (codeNavEl) {
+if (codeNavEl && !viewBlobEl) {
const { codeNavigationPath, blobPath, definitionPathPrefix } = codeNavEl.dataset;
// eslint-disable-next-line promise/catch-or-return
diff --git a/app/assets/javascripts/pages/projects/branches/index/index.js b/app/assets/javascripts/pages/projects/branches/index/index.js
index d279c4cbb08..f3530b46845 100644
--- a/app/assets/javascripts/pages/projects/branches/index/index.js
+++ b/app/assets/javascripts/pages/projects/branches/index/index.js
@@ -1,12 +1,9 @@
import initDeprecatedRemoveRowBehavior from '~/behaviors/deprecated_remove_row_behavior';
-import AjaxLoadingSpinner from '~/branches/ajax_loading_spinner';
import BranchSortDropdown from '~/branches/branch_sort_dropdown';
import initDiverganceGraph from '~/branches/divergence_graph';
import initDeleteBranchButton from '~/branches/init_delete_branch_button';
import initDeleteBranchModal from '~/branches/init_delete_branch_modal';
-AjaxLoadingSpinner.init();
-
const { divergingCountsEndpoint, defaultBranch } = document.querySelector(
'.js-branch-list',
).dataset;
diff --git a/app/assets/javascripts/pages/projects/ci/secure_files/show/index.js b/app/assets/javascripts/pages/projects/ci/secure_files/show/index.js
new file mode 100644
index 00000000000..61486606665
--- /dev/null
+++ b/app/assets/javascripts/pages/projects/ci/secure_files/show/index.js
@@ -0,0 +1,3 @@
+import { initCiSecureFiles } from '~/ci_secure_files';
+
+initCiSecureFiles();
diff --git a/app/assets/javascripts/pages/projects/clusters/new/index.js b/app/assets/javascripts/pages/projects/clusters/connect/index.js
index de9ded87ef3..de9ded87ef3 100644
--- a/app/assets/javascripts/pages/projects/clusters/new/index.js
+++ b/app/assets/javascripts/pages/projects/clusters/connect/index.js
diff --git a/app/assets/javascripts/pages/projects/environments/index/index.js b/app/assets/javascripts/pages/projects/environments/index/index.js
index f0554d64ddc..8e0d9ee0eab 100644
--- a/app/assets/javascripts/pages/projects/environments/index/index.js
+++ b/app/assets/javascripts/pages/projects/environments/index/index.js
@@ -1,11 +1,5 @@
-import initEnvironments from '~/environments/';
-import initNewEnvironments from '~/environments/new_index';
+import initEnvironments from '~/environments/index';
-let el = document.getElementById('environments-list-view');
+const el = document.getElementById('environments-table');
-if (el) {
- initEnvironments(el);
-} else {
- el = document.getElementById('environments-table');
- initNewEnvironments(el);
-}
+initEnvironments(el);
diff --git a/app/assets/javascripts/pages/projects/forks/new/components/app.vue b/app/assets/javascripts/pages/projects/forks/new/components/app.vue
index 7fb41c6e7b7..0995a2118b1 100644
--- a/app/assets/javascripts/pages/projects/forks/new/components/app.vue
+++ b/app/assets/javascripts/pages/projects/forks/new/components/app.vue
@@ -10,38 +10,6 @@ export default {
type: String,
required: true,
},
- endpoint: {
- type: String,
- required: true,
- },
- projectFullPath: {
- type: String,
- required: true,
- },
- projectId: {
- type: String,
- required: true,
- },
- projectName: {
- type: String,
- required: true,
- },
- projectPath: {
- type: String,
- required: true,
- },
- projectDescription: {
- type: String,
- required: true,
- },
- projectVisibility: {
- type: String,
- required: true,
- },
- restrictedVisibilityLevels: {
- type: Array,
- required: true,
- },
},
};
</script>
@@ -62,16 +30,7 @@ export default {
</p>
</div>
<div class="col-lg-9">
- <fork-form
- :endpoint="endpoint"
- :project-full-path="projectFullPath"
- :project-id="projectId"
- :project-name="projectName"
- :project-path="projectPath"
- :project-description="projectDescription"
- :project-visibility="projectVisibility"
- :restricted-visibility-levels="restrictedVisibilityLevels"
- />
+ <fork-form />
</div>
</div>
</template>
diff --git a/app/assets/javascripts/pages/projects/forks/new/components/fork_form.vue b/app/assets/javascripts/pages/projects/forks/new/components/fork_form.vue
index 25b62e6c971..701bf0c1e1d 100644
--- a/app/assets/javascripts/pages/projects/forks/new/components/fork_form.vue
+++ b/app/assets/javascripts/pages/projects/forks/new/components/fork_form.vue
@@ -72,40 +72,29 @@ export default {
visibilityHelpPath: {
default: '',
},
- },
- props: {
endpoint: {
- type: String,
- required: true,
+ default: '',
},
projectFullPath: {
- type: String,
- required: true,
+ default: '',
},
projectId: {
- type: String,
- required: true,
+ default: '',
},
projectName: {
- type: String,
- required: true,
+ default: '',
},
projectPath: {
- type: String,
- required: true,
+ default: '',
},
projectDescription: {
- type: String,
- required: false,
default: '',
},
projectVisibility: {
- type: String,
- required: true,
+ default: '',
},
restrictedVisibilityLevels: {
- type: Array,
- required: true,
+ default: [],
},
},
data() {
diff --git a/app/assets/javascripts/pages/projects/forks/new/components/fork_groups_list.vue b/app/assets/javascripts/pages/projects/forks/new/components/fork_groups_list.vue
deleted file mode 100644
index 10753de6cd0..00000000000
--- a/app/assets/javascripts/pages/projects/forks/new/components/fork_groups_list.vue
+++ /dev/null
@@ -1,93 +0,0 @@
-<script>
-import { GlTabs, GlTab, GlLoadingIcon, GlSearchBoxByType } from '@gitlab/ui';
-import createFlash from '~/flash';
-import axios from '~/lib/utils/axios_utils';
-import { __ } from '~/locale';
-import ForkGroupsListItem from './fork_groups_list_item.vue';
-
-export default {
- components: {
- GlTabs,
- GlTab,
- GlLoadingIcon,
- GlSearchBoxByType,
- ForkGroupsListItem,
- },
- props: {
- endpoint: {
- type: String,
- required: true,
- },
- },
- data() {
- return {
- namespaces: null,
- filter: '',
- };
- },
- computed: {
- filteredNamespaces() {
- return this.namespaces.filter((n) =>
- n.name.toLowerCase().includes(this.filter.toLowerCase()),
- );
- },
- },
-
- mounted() {
- this.loadGroups();
- },
-
- methods: {
- loadGroups() {
- axios
- .get(this.endpoint)
- .then((response) => {
- this.namespaces = response.data.namespaces;
- })
- .catch(() =>
- createFlash({
- message: __('There was a problem fetching groups.'),
- }),
- );
- },
- },
-
- i18n: {
- searchPlaceholder: __('Search by name'),
- },
-};
-</script>
-<template>
- <gl-tabs class="fork-groups">
- <gl-tab :title="__('Groups and subgroups')">
- <gl-loading-icon v-if="!namespaces" size="md" class="gl-mt-3" />
- <template v-else-if="namespaces.length === 0">
- <div class="gl-text-center">
- <div class="h5">{{ __('No available groups to fork the project.') }}</div>
- <p class="gl-mt-5">
- {{ __('You must have permission to create a project in a group before forking.') }}
- </p>
- </div>
- </template>
- <div v-else-if="filteredNamespaces.length === 0" class="gl-text-center gl-mt-3">
- {{ s__('GroupsTree|No groups matched your search') }}
- </div>
- <ul v-else class="groups-list group-list-tree">
- <fork-groups-list-item
- v-for="(namespace, index) in filteredNamespaces"
- :key="index"
- :group="namespace"
- />
- </ul>
- </gl-tab>
- <template #tabs-end>
- <gl-search-box-by-type
- v-if="namespaces && namespaces.length"
- v-model="filter"
- :placeholder="$options.i18n.searchPlaceholder"
- class="gl-align-self-center gl-ml-auto fork-filtered-search"
- data-qa-selector="fork_groups_list_search_field"
- />
- </template>
- </gl-tabs>
-</template>
diff --git a/app/assets/javascripts/pages/projects/forks/new/components/fork_groups_list_item.vue b/app/assets/javascripts/pages/projects/forks/new/components/fork_groups_list_item.vue
deleted file mode 100644
index d41488acf46..00000000000
--- a/app/assets/javascripts/pages/projects/forks/new/components/fork_groups_list_item.vue
+++ /dev/null
@@ -1,148 +0,0 @@
-<script>
-import {
- GlLink,
- GlButton,
- GlIcon,
- GlAvatar,
- GlTooltipDirective,
- GlTooltip,
- GlBadge,
- GlSafeHtmlDirective as SafeHtml,
-} from '@gitlab/ui';
-import { VISIBILITY_TYPE_ICON, GROUP_VISIBILITY_TYPE } from '~/groups/constants';
-import csrf from '~/lib/utils/csrf';
-import UserAccessRoleBadge from '~/vue_shared/components/user_access_role_badge.vue';
-
-export default {
- components: {
- GlIcon,
- GlAvatar,
- GlBadge,
- GlButton,
- GlTooltip,
- GlLink,
- UserAccessRoleBadge,
- },
- directives: {
- GlTooltip: GlTooltipDirective,
- SafeHtml,
- },
- props: {
- group: {
- type: Object,
- required: true,
- },
- },
- data() {
- return { namespaces: null, isForking: false };
- },
-
- computed: {
- rowClass() {
- return {
- 'has-description': this.group.description,
- 'being-removed': this.isGroupPendingRemoval,
- };
- },
- isGroupPendingRemoval() {
- return this.group.marked_for_deletion;
- },
- hasForkedProject() {
- return Boolean(this.group.forked_project_path);
- },
- visibilityIcon() {
- return VISIBILITY_TYPE_ICON[this.group.visibility];
- },
- visibilityTooltip() {
- return GROUP_VISIBILITY_TYPE[this.group.visibility];
- },
- isSelectButtonDisabled() {
- return !this.group.can_create_project;
- },
- },
-
- methods: {
- fork() {
- this.isForking = true;
- this.$refs.form.submit();
- },
- },
-
- csrf,
-};
-</script>
-<template>
- <li :class="rowClass" class="group-row">
- <div class="group-row-contents gl-display-flex gl-align-items-center gl-py-3 gl-pr-5">
- <div
- class="folder-toggle-wrap gl-mr-3 gl-display-flex gl-align-items-center gl-text-gray-500"
- >
- <gl-icon name="folder-o" />
- </div>
- <gl-link
- :href="group.relative_path"
- class="gl-display-none gl-flex-shrink-0 gl-sm-display-flex gl-mr-3"
- >
- <gl-avatar :size="32" shape="rect" :entity-name="group.name" :src="group.avatarUrl" />
- </gl-link>
- <div class="gl-min-w-0 gl-display-flex gl-flex-grow-1 gl-flex-shrink-1 gl-align-items-center">
- <div class="gl-min-w-0 gl-flex-grow-1 flex-shrink-1">
- <div class="title gl-display-flex gl-align-items-center gl-flex-wrap gl-mr-3">
- <gl-link :href="group.relative_path" class="gl-mt-3 gl-mr-3 gl-text-gray-900!">
- {{ group.full_name }}
- </gl-link>
- <gl-icon
- v-gl-tooltip.hover.bottom
- class="gl-display-inline-flex gl-mt-3 gl-mr-3 gl-text-gray-500"
- :name="visibilityIcon"
- :title="visibilityTooltip"
- />
- <gl-badge
- v-if="isGroupPendingRemoval"
- variant="warning"
- class="gl-display-none gl-sm-display-flex gl-mt-3 gl-mr-1"
- >{{ __('pending deletion') }}</gl-badge
- >
- <user-access-role-badge v-if="group.permission" class="gl-mt-3">
- {{ group.permission }}
- </user-access-role-badge>
- </div>
- <div v-if="group.description" class="description gl-line-height-20">
- <span v-safe-html="group.markdown_description"> </span>
- </div>
- </div>
- <div class="gl-display-flex gl-flex-shrink-0">
- <gl-button
- v-if="hasForkedProject"
- class="gl-h-7 gl-text-decoration-none!"
- :href="group.forked_project_path"
- >{{ __('Go to fork') }}</gl-button
- >
- <template v-else>
- <div ref="selectButtonWrapper">
- <form ref="form" method="POST" :action="group.fork_path">
- <input type="hidden" name="authenticity_token" :value="$options.csrf.token" />
- <gl-button
- type="submit"
- class="gl-h-7"
- :data-qa-name="group.full_name"
- category="secondary"
- variant="success"
- :disabled="isSelectButtonDisabled"
- :loading="isForking"
- @click="fork"
- >{{ __('Select') }}</gl-button
- >
- </form>
- </div>
- <gl-tooltip v-if="isSelectButtonDisabled" :target="() => $refs.selectButtonWrapper">
- {{
- __('You must have permission to create a project in a namespace before forking.')
- }}
- </gl-tooltip>
- </template>
- </div>
- </div>
- </div>
- </li>
-</template>
diff --git a/app/assets/javascripts/pages/projects/forks/new/index.js b/app/assets/javascripts/pages/projects/forks/new/index.js
index 1a171252048..cbf74f755e7 100644
--- a/app/assets/javascripts/pages/projects/forks/new/index.js
+++ b/app/assets/javascripts/pages/projects/forks/new/index.js
@@ -1,61 +1,42 @@
import Vue from 'vue';
import App from './components/app.vue';
-import ForkGroupsList from './components/fork_groups_list.vue';
const mountElement = document.getElementById('fork-groups-mount-element');
-if (gon.features.forkProjectForm) {
- const {
- forkIllustration,
- endpoint,
+const {
+ forkIllustration,
+ endpoint,
+ newGroupPath,
+ projectFullPath,
+ visibilityHelpPath,
+ projectId,
+ projectName,
+ projectPath,
+ projectDescription,
+ projectVisibility,
+ restrictedVisibilityLevels,
+} = mountElement.dataset;
+
+// eslint-disable-next-line no-new
+new Vue({
+ el: mountElement,
+ provide: {
newGroupPath,
- projectFullPath,
visibilityHelpPath,
+ endpoint,
+ projectFullPath,
projectId,
projectName,
projectPath,
projectDescription,
projectVisibility,
- restrictedVisibilityLevels,
- } = mountElement.dataset;
-
- // eslint-disable-next-line no-new
- new Vue({
- el: mountElement,
- provide: {
- newGroupPath,
- visibilityHelpPath,
- },
- render(h) {
- return h(App, {
- props: {
- forkIllustration,
- endpoint,
- newGroupPath,
- projectFullPath,
- visibilityHelpPath,
- projectId,
- projectName,
- projectPath,
- projectDescription,
- projectVisibility,
- restrictedVisibilityLevels: JSON.parse(restrictedVisibilityLevels),
- },
- });
- },
- });
-} else {
- const { endpoint } = mountElement.dataset;
-
- // eslint-disable-next-line no-new
- new Vue({
- el: mountElement,
- render(h) {
- return h(ForkGroupsList, {
- props: {
- endpoint,
- },
- });
- },
- });
-}
+ restrictedVisibilityLevels: JSON.parse(restrictedVisibilityLevels),
+ },
+ render(h) {
+ return h(App, {
+ props: {
+ forkIllustration,
+ },
+ });
+ },
+});
diff --git a/app/assets/javascripts/pages/projects/learn_gitlab/components/learn_gitlab.vue b/app/assets/javascripts/pages/projects/learn_gitlab/components/learn_gitlab.vue
index adae97c6b6f..67962d69fa5 100644
--- a/app/assets/javascripts/pages/projects/learn_gitlab/components/learn_gitlab.vue
+++ b/app/assets/javascripts/pages/projects/learn_gitlab/components/learn_gitlab.vue
@@ -27,11 +27,6 @@ export default {
required: true,
type: Object,
},
- inviteMembers: {
- type: Boolean,
- required: false,
- default: false,
- },
project: {
required: true,
type: Object,
@@ -54,7 +49,7 @@ export default {
},
},
mounted() {
- if (this.inviteMembers && this.getCookieForInviteMembers()) {
+ if (this.getCookieForInviteMembers()) {
this.openInviteMembersModal('celebrate');
}
diff --git a/app/assets/javascripts/pages/projects/learn_gitlab/components/learn_gitlab_info_card.vue b/app/assets/javascripts/pages/projects/learn_gitlab/components/learn_gitlab_info_card.vue
index ad6dfbf41ca..09cc0032871 100644
--- a/app/assets/javascripts/pages/projects/learn_gitlab/components/learn_gitlab_info_card.vue
+++ b/app/assets/javascripts/pages/projects/learn_gitlab/components/learn_gitlab_info_card.vue
@@ -64,15 +64,7 @@ export default {
<img :src="svg" :alt="actionLabel" />
<h6>{{ title }}</h6>
<p class="gl-font-sm gl-text-gray-700">{{ description }}</p>
- <gl-link
- :href="url"
- target="_blank"
- rel="noopener noreferrer"
- data-track-action="click_link"
- :data-track-label="actionLabel"
- data-track-property="Growth::Activation::Experiment::LearnGitLabB"
- >{{ actionLabel }}</gl-link
- >
+ <gl-link :href="url" target="_blank" rel="noopener noreferrer" />
</div>
</gl-card>
</template>
diff --git a/app/assets/javascripts/pages/projects/learn_gitlab/components/learn_gitlab_section_link.vue b/app/assets/javascripts/pages/projects/learn_gitlab/components/learn_gitlab_section_link.vue
index d0ec02bbd0c..573f996a254 100644
--- a/app/assets/javascripts/pages/projects/learn_gitlab/components/learn_gitlab_section_link.vue
+++ b/app/assets/javascripts/pages/projects/learn_gitlab/components/learn_gitlab_section_link.vue
@@ -32,7 +32,7 @@ export default {
);
},
openInNewTab() {
- return ACTION_LABELS[this.action]?.openInNewTab === true;
+ return ACTION_LABELS[this.action]?.openInNewTab === true || this.value.openInNewTab === true;
},
},
methods: {
@@ -65,8 +65,6 @@ export default {
data-testid="uncompleted-learn-gitlab-link"
data-track-action="click_link"
:data-track-label="$options.i18n.ACTION_LABELS[action].title"
- data-track-property="Growth::Conversion::Experiment::LearnGitLab"
- data-track-experiment="change_continuous_onboarding_link_urls"
>
{{ $options.i18n.ACTION_LABELS[action].title }}
</gl-link>
diff --git a/app/assets/javascripts/pages/projects/learn_gitlab/constants/index.js b/app/assets/javascripts/pages/projects/learn_gitlab/constants/index.js
index 880cf699e5e..1887c48dd1b 100644
--- a/app/assets/javascripts/pages/projects/learn_gitlab/constants/index.js
+++ b/app/assets/javascripts/pages/projects/learn_gitlab/constants/index.js
@@ -62,7 +62,6 @@ export const ACTION_LABELS = {
description: s__('LearnGitLab|Scan your code to uncover vulnerabilities before deploying.'),
section: 'deploy',
position: 1,
- openInNewTab: true,
},
issueCreated: {
title: s__('LearnGitLab|Create an issue'),
diff --git a/app/assets/javascripts/pages/projects/learn_gitlab/index/index.js b/app/assets/javascripts/pages/projects/learn_gitlab/index/index.js
index c62cab1a425..63357ea9c72 100644
--- a/app/assets/javascripts/pages/projects/learn_gitlab/index/index.js
+++ b/app/assets/javascripts/pages/projects/learn_gitlab/index/index.js
@@ -1,6 +1,6 @@
import Vue from 'vue';
import initInviteMembersModal from '~/invite_members/init_invite_members_modal';
-import { convertObjectPropsToCamelCase, parseBoolean } from '~/lib/utils/common_utils';
+import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
import LearnGitlab from '../components/learn_gitlab.vue';
function initLearnGitlab() {
@@ -13,13 +13,12 @@ function initLearnGitlab() {
const actions = convertObjectPropsToCamelCase(JSON.parse(el.dataset.actions));
const sections = convertObjectPropsToCamelCase(JSON.parse(el.dataset.sections));
const project = convertObjectPropsToCamelCase(JSON.parse(el.dataset.project));
- const { inviteMembers } = el.dataset;
return new Vue({
el,
render(createElement) {
return createElement(LearnGitlab, {
- props: { actions, sections, project, inviteMembers: parseBoolean(inviteMembers) },
+ props: { actions, sections, project },
});
},
});
diff --git a/app/assets/javascripts/pages/projects/pages_domains/form.js b/app/assets/javascripts/pages/projects/pages_domains/form.js
index 169530685ad..6836d399fa4 100644
--- a/app/assets/javascripts/pages/projects/pages_domains/form.js
+++ b/app/assets/javascripts/pages/projects/pages_domains/form.js
@@ -1,4 +1,4 @@
-import setupToggleButtons from '~/toggle_buttons';
+import { initToggle } from '~/toggles';
function updateVisibility(selector, isVisible) {
Array.from(document.querySelectorAll(selector)).forEach((el) => {
@@ -11,12 +11,12 @@ function updateVisibility(selector, isVisible) {
}
export default () => {
- const toggleContainer = document.querySelector('.js-auto-ssl-toggle-container');
+ const sslToggle = initToggle(document.querySelector('.js-enable-ssl-gl-toggle'));
+ const sslToggleInput = document.querySelector('.js-project-feature-toggle-input');
- if (toggleContainer) {
- const onToggleButtonClicked = (isAutoSslEnabled) => {
+ if (sslToggle) {
+ sslToggle.$on('change', (isAutoSslEnabled) => {
updateVisibility('.js-shown-unless-auto-ssl', !isAutoSslEnabled);
-
updateVisibility('.js-shown-if-auto-ssl', isAutoSslEnabled);
Array.from(document.querySelectorAll('.js-enabled-unless-auto-ssl')).forEach((el) => {
@@ -26,8 +26,9 @@ export default () => {
el.removeAttribute('disabled');
}
});
- };
- setupToggleButtons(toggleContainer, onToggleButtonClicked);
+ sslToggleInput.setAttribute('value', isAutoSslEnabled);
+ });
}
+ return sslToggle;
};
diff --git a/app/assets/javascripts/pages/projects/pipeline_schedules/shared/components/target_branch_dropdown.js b/app/assets/javascripts/pages/projects/pipeline_schedules/shared/components/target_branch_dropdown.js
deleted file mode 100644
index 6017cd653e4..00000000000
--- a/app/assets/javascripts/pages/projects/pipeline_schedules/shared/components/target_branch_dropdown.js
+++ /dev/null
@@ -1,54 +0,0 @@
-import $ from 'jquery';
-import initDeprecatedJQueryDropdown from '~/deprecated_jquery_dropdown';
-
-export default class TargetBranchDropdown {
- constructor() {
- this.$dropdown = $('.js-target-branch-dropdown');
- this.$dropdownToggle = this.$dropdown.find('.dropdown-toggle-text');
- this.$input = $('#schedule_ref');
- this.initDefaultBranch();
- this.initDropdown();
- }
-
- initDropdown() {
- initDeprecatedJQueryDropdown(this.$dropdown, {
- data: this.formatBranchesList(),
- filterable: true,
- selectable: true,
- toggleLabel: (item) => item.name,
- search: {
- fields: ['name'],
- },
- clicked: (cfg) => this.updateInputValue(cfg),
- text: (item) => item.name,
- });
-
- this.setDropdownToggle();
- }
-
- formatBranchesList() {
- return this.$dropdown.data('data').map((val) => ({ name: val }));
- }
-
- setDropdownToggle() {
- const initialValue = this.$input.val();
-
- this.$dropdownToggle.text(initialValue);
- }
-
- initDefaultBranch() {
- const initialValue = this.$input.val();
- const defaultBranch = this.$dropdown.data('defaultBranch');
-
- if (!initialValue) {
- this.$input.val(defaultBranch);
- }
- }
-
- updateInputValue({ selectedObj, e }) {
- e.preventDefault();
-
- this.$input.val(selectedObj.name);
- gl.pipelineScheduleFieldErrors.updateFormValidityState();
- }
-}
diff --git a/app/assets/javascripts/pages/projects/pipeline_schedules/shared/init_form.js b/app/assets/javascripts/pages/projects/pipeline_schedules/shared/init_form.js
index 9056c76d6ca..9c039a6be81 100644
--- a/app/assets/javascripts/pages/projects/pipeline_schedules/shared/init_form.js
+++ b/app/assets/javascripts/pages/projects/pipeline_schedules/shared/init_form.js
@@ -1,10 +1,12 @@
import $ from 'jquery';
import Vue from 'vue';
+import { __ } from '~/locale';
+import RefSelector from '~/ref/components/ref_selector.vue';
+import { REF_TYPE_BRANCHES, REF_TYPE_TAGS } from '~/ref/constants';
import setupNativeFormVariableList from '../../../../ci_variable_list/native_form_variable_list';
import GlFieldErrors from '../../../../gl_field_errors';
import Translate from '../../../../vue_shared/translate';
import intervalPatternInput from './components/interval_pattern_input.vue';
-import TargetBranchDropdown from './components/target_branch_dropdown';
import TimezoneDropdown from './components/timezone_dropdown';
Vue.use(Translate);
@@ -30,6 +32,52 @@ function initIntervalPatternInput() {
});
}
+function getEnabledRefTypes() {
+ const refTypes = [REF_TYPE_BRANCHES];
+
+ if (gon.features.pipelineSchedulesWithTags) {
+ refTypes.push(REF_TYPE_TAGS);
+ }
+
+ return refTypes;
+}
+
+function initTargetRefDropdown() {
+ const $refField = document.getElementById('schedule_ref');
+ const el = document.querySelector('.js-target-ref-dropdown');
+ const { projectId, defaultBranch } = el.dataset;
+
+ if (!$refField.value) {
+ $refField.value = defaultBranch;
+ }
+
+ const refDropdown = new Vue({
+ el,
+ render(h) {
+ return h(RefSelector, {
+ props: {
+ enabledRefTypes: getEnabledRefTypes(),
+ projectId,
+ value: $refField.value,
+ useSymbolicRefNames: true,
+ translations: {
+ dropdownHeader: gon.features.pipelineSchedulesWithTags
+ ? __('Select target branch or tag')
+ : __('Select target branch'),
+ },
+ },
+ class: 'gl-w-full',
+ });
+ },
+ });
+
+ refDropdown.$children[0].$on('input', (newRef) => {
+ $refField.value = newRef;
+ });
+
+ return refDropdown;
+}
+
export default () => {
/* Most of the form is written in haml, but for fields with more complex behaviors,
* you should mount individual Vue components here. If at some point components need
@@ -48,9 +96,10 @@ export default () => {
gl.pipelineScheduleFieldErrors.updateFormValidityState();
},
});
- gl.targetBranchDropdown = new TargetBranchDropdown();
gl.pipelineScheduleFieldErrors = new GlFieldErrors(formElement);
+ initTargetRefDropdown();
+
setupNativeFormVariableList({
container: $('.js-ci-variable-list-section'),
formField: 'schedule',
diff --git a/app/assets/javascripts/pages/projects/project_members/index.js b/app/assets/javascripts/pages/projects/project_members/index.js
index 26c42247cf7..2c0394dc12c 100644
--- a/app/assets/javascripts/pages/projects/project_members/index.js
+++ b/app/assets/javascripts/pages/projects/project_members/index.js
@@ -1,33 +1,20 @@
-import groupsSelect from '~/groups_select';
import initImportAProjectModal from '~/invite_members/init_import_a_project_modal';
import initInviteGroupTrigger from '~/invite_members/init_invite_group_trigger';
-import initInviteMembersForm from '~/invite_members/init_invite_members_form';
import initInviteMembersModal from '~/invite_members/init_invite_members_modal';
import initInviteGroupsModal from '~/invite_members/init_invite_groups_modal';
import initInviteMembersTrigger from '~/invite_members/init_invite_members_trigger';
import { s__ } from '~/locale';
-import memberExpirationDate from '~/member_expiration_date';
import { initMembersApp } from '~/members';
import { MEMBER_TYPES } from '~/members/constants';
import { groupLinkRequestFormatter } from '~/members/utils';
import { projectMemberRequestFormatter } from '~/projects/members/utils';
-import UsersSelect from '~/users_select';
-groupsSelect();
-memberExpirationDate();
-memberExpirationDate('.js-access-expiration-date-groups');
initImportAProjectModal();
initInviteMembersModal();
initInviteGroupsModal();
initInviteMembersTrigger();
initInviteGroupTrigger();
-// This is only used when `invite_members_group_modal` feature flag is disabled.
-// This can be removed when `invite_members_group_modal` feature flag is removed.
-initInviteMembersForm();
-
-new UsersSelect(); // eslint-disable-line no-new
-
const SHARED_FIELDS = ['account', 'maxRole', 'expiration', 'actions'];
initMembersApp(document.querySelector('.js-project-members-list-app'), {
[MEMBER_TYPES.user]: {
diff --git a/app/assets/javascripts/pages/shared/wikis/components/wiki_form.vue b/app/assets/javascripts/pages/shared/wikis/components/wiki_form.vue
index c28de88554a..8ef31b9b983 100644
--- a/app/assets/javascripts/pages/shared/wikis/components/wiki_form.vue
+++ b/app/assets/javascripts/pages/shared/wikis/components/wiki_form.vue
@@ -60,7 +60,7 @@ export default {
contentEditor: {
renderFailed: {
message: s__(
- 'WikiPage|An error occured while trying to render the content editor. Please try again later.',
+ 'WikiPage|An error occurred while trying to render the content editor. Please try again later.',
),
primaryAction: s__('WikiPage|Retry'),
},
@@ -495,6 +495,7 @@ export default {
:textarea-value="content"
:markdown-docs-path="pageInfo.markdownHelpPath"
:uploads-path="pageInfo.uploadsPath"
+ :enable-preview="isMarkdownFormat"
class="bordered-box"
>
<template #textarea>
diff --git a/app/assets/javascripts/pages/users/activity_calendar.js b/app/assets/javascripts/pages/users/activity_calendar.js
index 7f4e79976bc..996e12bc105 100644
--- a/app/assets/javascripts/pages/users/activity_calendar.js
+++ b/app/assets/javascripts/pages/users/activity_calendar.js
@@ -7,6 +7,7 @@ import axios from '~/lib/utils/axios_utils';
import { getDayName, getDayDifference } from '~/lib/utils/datetime_utility';
import { formatDate } from '~/lib/utils/datetime/date_format_utility';
import { n__, s__, __ } from '~/locale';
+import { loadingIconForLegacyJS } from '~/loading_icon_for_legacy_js';
const d3 = { select };
@@ -24,12 +25,6 @@ const CONTRIB_LEGENDS = [
{ title: __('30+ contributions'), min: 30 },
];
-const LOADING_HTML = `
- <div class="text-center">
- <div class="spinner spinner-md"></div>
- </div>
-`;
-
function getSystemDate(systemUtcOffsetSeconds) {
const date = new Date();
const localUtcOffsetMinutes = 0 - date.getTimezoneOffset();
@@ -286,7 +281,9 @@ export default class ActivityCalendar {
this.currentSelectedDate.getDate(),
].join('-');
- $(this.activitiesContainer).html(LOADING_HTML);
+ $(this.activitiesContainer)
+ .empty()
+ .append(loadingIconForLegacyJS({ size: 'lg' }));
axios
.get(this.calendarActivitiesPath, {
diff --git a/app/assets/javascripts/performance_bar/components/detailed_metric.vue b/app/assets/javascripts/performance_bar/components/detailed_metric.vue
index 1bb82e1d8e6..0640faae8b7 100644
--- a/app/assets/javascripts/performance_bar/components/detailed_metric.vue
+++ b/app/assets/javascripts/performance_bar/components/detailed_metric.vue
@@ -1,5 +1,5 @@
<script>
-import { GlButton, GlModal, GlModalDirective, GlSegmentedControl } from '@gitlab/ui';
+import { GlButton, GlDropdown, GlDropdownItem, GlModal, GlModalDirective } from '@gitlab/ui';
import { __, s__ } from '~/locale';
import { sortOrders, sortOrderOptions } from '../constants';
@@ -9,8 +9,9 @@ export default {
components: {
RequestWarning,
GlButton,
+ GlDropdown,
+ GlDropdownItem,
GlModal,
- GlSegmentedControl,
},
directives: {
'gl-modal': GlModalDirective,
@@ -156,13 +157,19 @@ export default {
</div>
</div>
</div>
- <gl-segmented-control
+ <gl-dropdown
v-if="displaySortOrder"
+ :text="$options.sortOrderOptions[sortOrder]"
+ right
data-testid="performance-bar-sort-order"
- :options="$options.sortOrderOptions"
- :checked="sortOrder"
- @input="changeSortOrder"
- />
+ >
+ <gl-dropdown-item
+ v-for="option in Object.keys($options.sortOrderOptions)"
+ :key="option"
+ @click="changeSortOrder(option)"
+ >{{ $options.sortOrderOptions[option] }}</gl-dropdown-item
+ >
+ </gl-dropdown>
</div>
<hr />
<table class="table gl-table">
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 710f49b833c..0f744e858f2 100644
--- a/app/assets/javascripts/performance_bar/components/performance_bar_app.vue
+++ b/app/assets/javascripts/performance_bar/components/performance_bar_app.vue
@@ -134,6 +134,7 @@ export default {
methods: {
changeCurrentRequest(newRequestId) {
this.currentRequest = newRequestId;
+ this.$emit('change-request', newRequestId);
},
flamegraphPath(mode) {
return mergeUrlParams(
diff --git a/app/assets/javascripts/performance_bar/components/request_selector.vue b/app/assets/javascripts/performance_bar/components/request_selector.vue
index a46ac620f48..ffc22c2113d 100644
--- a/app/assets/javascripts/performance_bar/components/request_selector.vue
+++ b/app/assets/javascripts/performance_bar/components/request_selector.vue
@@ -1,15 +1,5 @@
<script>
-import { GlPopover, GlSafeHtmlDirective } from '@gitlab/ui';
-import { glEmojiTag } from '~/emoji';
-import { n__ } from '~/locale';
-
export default {
- components: {
- GlPopover,
- },
- directives: {
- SafeHtml: GlSafeHtmlDirective,
- },
props: {
currentRequest: {
type: Object,
@@ -25,27 +15,11 @@ export default {
currentRequestId: this.currentRequest.id,
};
},
- computed: {
- requestsWithWarnings() {
- return this.requests.filter((request) => request.hasWarnings);
- },
- warningMessage() {
- return n__(
- '%d request with warnings',
- '%d requests with warnings',
- this.requestsWithWarnings.length,
- );
- },
- },
watch: {
currentRequestId(newRequestId) {
this.$emit('change-current-request', newRequestId);
},
},
- methods: {
- glEmojiTag,
- },
- safeHtmlConfig: { ADD_TAGS: ['gl-emoji'] },
};
</script>
<template>
@@ -58,19 +32,7 @@ export default {
data-qa-selector="request_dropdown_option"
>
{{ request.truncatedUrl }}
- <span v-if="request.hasWarnings">(!)</span>
</option>
</select>
- <span v-if="requestsWithWarnings.length" class="gl-cursor-default">
- <span
- id="performance-bar-request-selector-warning"
- v-safe-html:[$options.safeHtmlConfig]="glEmojiTag('warning')"
- ></span>
- <gl-popover
- placement="bottom"
- target="performance-bar-request-selector-warning"
- :content="warningMessage"
- />
- </span>
</div>
</template>
diff --git a/app/assets/javascripts/performance_bar/constants.js b/app/assets/javascripts/performance_bar/constants.js
index 9659383edd9..09745797424 100644
--- a/app/assets/javascripts/performance_bar/constants.js
+++ b/app/assets/javascripts/performance_bar/constants.js
@@ -5,13 +5,7 @@ export const sortOrders = {
CHRONOLOGICAL: 'chronological',
};
-export const sortOrderOptions = [
- {
- value: sortOrders.DURATION,
- text: s__('PerformanceBar|Sort by duration'),
- },
- {
- value: sortOrders.CHRONOLOGICAL,
- text: s__('PerformanceBar|Sort chronologically'),
- },
-];
+export const sortOrderOptions = {
+ [sortOrders.DURATION]: s__('PerformanceBar|Sort by duration'),
+ [sortOrders.CHRONOLOGICAL]: s__('PerformanceBar|Sort chronologically'),
+};
diff --git a/app/assets/javascripts/performance_bar/index.js b/app/assets/javascripts/performance_bar/index.js
index eb5b50dd1ec..e7f84eacdca 100644
--- a/app/assets/javascripts/performance_bar/index.js
+++ b/app/assets/javascripts/performance_bar/index.js
@@ -1,5 +1,6 @@
import '../webpack';
+import { isEmpty } from 'lodash';
import Vue from 'vue';
import axios from '~/lib/utils/axios_utils';
import { numberToHumanSize } from '~/lib/utils/number_utils';
@@ -37,9 +38,10 @@ const initPerformanceBar = (el) => {
};
},
mounted() {
- PerformanceBarService.registerInterceptor(this.peekUrl, this.loadRequestDetails);
+ PerformanceBarService.registerInterceptor(this.peekUrl, this.addRequest);
- this.loadRequestDetails(this.requestId, window.location.href);
+ this.addRequest(this.requestId, window.location.href);
+ this.loadRequestDetails(this.requestId);
},
beforeDestroy() {
PerformanceBarService.removeInterceptor();
@@ -51,26 +53,32 @@ const initPerformanceBar = (el) => {
// want to trace the request.
axios.get(urlOrRequestId);
} else {
- this.loadRequestDetails(urlOrRequestId, urlOrRequestId);
+ this.addRequest(urlOrRequestId, urlOrRequestId);
}
},
- loadRequestDetails(requestId, requestUrl) {
+ addRequest(requestId, requestUrl) {
if (!this.store.canTrackRequest(requestUrl)) {
return;
}
this.store.addRequest(requestId, requestUrl);
+ },
+ loadRequestDetails(requestId) {
+ const request = this.store.findRequest(requestId);
+
+ if (request && isEmpty(request.details)) {
+ return PerformanceBarService.fetchRequestDetails(this.peekUrl, requestId)
+ .then((res) => {
+ this.store.addRequestDetails(requestId, res.data);
+ if (this.requestId === requestId) this.collectFrontendPerformanceMetrics();
+ })
+ .catch(() =>
+ // eslint-disable-next-line no-console
+ console.warn(`Error getting performance bar results for ${requestId}`),
+ );
+ }
- PerformanceBarService.fetchRequestDetails(this.peekUrl, requestId)
- .then((res) => {
- this.store.addRequestDetails(requestId, res.data);
-
- if (this.requestId === requestId) this.collectFrontendPerformanceMetrics();
- })
- .catch(() =>
- // eslint-disable-next-line no-console
- console.warn(`Error getting performance bar results for ${requestId}`),
- );
+ return Promise.resolve();
},
collectFrontendPerformanceMetrics() {
if (performance) {
@@ -82,7 +90,9 @@ const initPerformanceBar = (el) => {
let summary = {};
if (navigationEntries.length > 0) {
const backend = Math.round(navigationEntries[0].responseEnd);
- const firstContentfulPaint = Math.round(paintEntries[1].startTime);
+ const firstContentfulPaint = Math.round(
+ paintEntries.find((entry) => entry.name === 'first-contentful-paint')?.startTime,
+ );
const domContentLoaded = Math.round(navigationEntries[0].domContentLoadedEventEnd);
summary = {
@@ -141,6 +151,7 @@ const initPerformanceBar = (el) => {
},
on: {
'add-request': this.addRequestManually,
+ 'change-request': this.loadRequestDetails,
},
});
},
diff --git a/app/assets/javascripts/performance_bar/stores/performance_bar_store.js b/app/assets/javascripts/performance_bar/stores/performance_bar_store.js
index 51a8eb5ca69..5a69960e4d9 100644
--- a/app/assets/javascripts/performance_bar/stores/performance_bar_store.js
+++ b/app/assets/javascripts/performance_bar/stores/performance_bar_store.js
@@ -12,7 +12,6 @@ export default class PerformanceBarStore {
url: requestUrl,
truncatedUrl: shortUrl,
details: {},
- hasWarnings: false,
});
}
@@ -27,7 +26,6 @@ export default class PerformanceBarStore {
const request = this.findRequest(requestId);
request.details = requestDetails.data;
- request.hasWarnings = requestDetails.has_warnings;
return request;
}
diff --git a/app/assets/javascripts/persistent_user_callout.js b/app/assets/javascripts/persistent_user_callout.js
index b003302ec8e..7c424088c8b 100644
--- a/app/assets/javascripts/persistent_user_callout.js
+++ b/app/assets/javascripts/persistent_user_callout.js
@@ -13,23 +13,25 @@ export default class PersistentUserCallout {
this.featureId = featureId;
this.groupId = groupId;
this.deferLinks = parseBoolean(deferLinks);
+ this.closeButtons = this.container.querySelectorAll('.js-close');
this.init();
}
init() {
- const closeButton = this.container.querySelector('.js-close');
const followLink = this.container.querySelector('.js-follow-link');
- if (closeButton) {
- this.handleCloseButtonCallout(closeButton);
+ if (this.closeButtons.length) {
+ this.handleCloseButtonCallout();
} else if (followLink) {
this.handleFollowLinkCallout(followLink);
}
}
- handleCloseButtonCallout(closeButton) {
- closeButton.addEventListener('click', (event) => this.dismiss(event));
+ handleCloseButtonCallout() {
+ this.closeButtons.forEach((closeButton) => {
+ closeButton.addEventListener('click', this.dismiss);
+ });
if (this.deferLinks) {
this.container.addEventListener('click', (event) => {
@@ -47,7 +49,7 @@ export default class PersistentUserCallout {
followLink.addEventListener('click', (event) => this.registerCalloutWithLink(event));
}
- dismiss(event, deferredLinkOptions = null) {
+ dismiss = (event, deferredLinkOptions = null) => {
event.preventDefault();
axios
@@ -57,6 +59,9 @@ export default class PersistentUserCallout {
})
.then(() => {
this.container.remove();
+ this.closeButtons.forEach((closeButton) => {
+ closeButton.removeEventListener('click', this.dismiss);
+ });
if (deferredLinkOptions) {
const { href, target } = deferredLinkOptions;
@@ -70,7 +75,7 @@ export default class PersistentUserCallout {
),
});
});
- }
+ };
registerCalloutWithLink(event) {
event.preventDefault();
diff --git a/app/assets/javascripts/persistent_user_callouts.js b/app/assets/javascripts/persistent_user_callouts.js
index 337c204c36a..f6de21ec0c5 100644
--- a/app/assets/javascripts/persistent_user_callouts.js
+++ b/app/assets/javascripts/persistent_user_callouts.js
@@ -11,6 +11,7 @@ const PERSISTENT_USER_CALLOUTS = [
'.js-eoa-bronze-plan-banner',
'.js-security-newsletter-callout',
'.js-approaching-seats-count-threshold',
+ '.js-storage-enforcement-banner',
];
const initCallouts = () => {
diff --git a/app/assets/javascripts/pipeline_editor/components/commit/commit_form.vue b/app/assets/javascripts/pipeline_editor/components/commit/commit_form.vue
index ca78f194a82..8536db78dfb 100644
--- a/app/assets/javascripts/pipeline_editor/components/commit/commit_form.vue
+++ b/app/assets/javascripts/pipeline_editor/components/commit/commit_form.vue
@@ -31,6 +31,14 @@ export default {
required: false,
default: '',
},
+ hasUnsavedChanges: {
+ type: Boolean,
+ required: true,
+ },
+ isNewCiConfigFile: {
+ type: Boolean,
+ required: true,
+ },
isSaving: {
type: Boolean,
required: false,
@@ -50,11 +58,14 @@ export default {
};
},
computed: {
+ isCommitFormFilledOut() {
+ return this.message && this.targetBranch;
+ },
isCurrentBranchTarget() {
return this.targetBranch === this.currentBranch;
},
- submitDisabled() {
- return !(this.message && this.targetBranch);
+ isSubmitDisabled() {
+ return !this.isCommitFormFilledOut || (!this.hasUnsavedChanges && !this.isNewCiConfigFile);
},
},
watch: {
@@ -125,6 +136,7 @@ export default {
v-if="!isCurrentBranchTarget"
v-model="openMergeRequest"
data-testid="new-mr-checkbox"
+ data-qa-selector="new_mr_checkbox"
class="gl-mt-3"
>
<gl-sprintf :message="$options.i18n.startMergeRequest">
@@ -143,7 +155,7 @@ export default {
category="primary"
variant="confirm"
data-qa-selector="commit_changes_button"
- :disabled="submitDisabled"
+ :disabled="isSubmitDisabled"
:loading="isSaving"
>
{{ $options.i18n.commitChanges }}
diff --git a/app/assets/javascripts/pipeline_editor/components/commit/commit_section.vue b/app/assets/javascripts/pipeline_editor/components/commit/commit_section.vue
index 8ff1aea020f..4ef598d6ff3 100644
--- a/app/assets/javascripts/pipeline_editor/components/commit/commit_section.vue
+++ b/app/assets/javascripts/pipeline_editor/components/commit/commit_section.vue
@@ -37,6 +37,10 @@ export default {
required: false,
default: '',
},
+ hasUnsavedChanges: {
+ type: Boolean,
+ required: true,
+ },
isNewCiConfigFile: {
type: Boolean,
required: false,
@@ -151,6 +155,8 @@ export default {
<commit-form
:current-branch="currentBranch"
:default-message="defaultCommitMessage"
+ :has-unsaved-changes="hasUnsavedChanges"
+ :is-new-ci-config-file="isNewCiConfigFile"
:is-saving="isSaving"
:scroll-to-commit-form="scrollToCommitForm"
v-on="$listeners"
diff --git a/app/assets/javascripts/pipeline_editor/components/drawer/pipeline_editor_drawer.vue b/app/assets/javascripts/pipeline_editor/components/drawer/pipeline_editor_drawer.vue
index 7bc096ce2c8..9cb070a5517 100644
--- a/app/assets/javascripts/pipeline_editor/components/drawer/pipeline_editor_drawer.vue
+++ b/app/assets/javascripts/pipeline_editor/components/drawer/pipeline_editor_drawer.vue
@@ -2,7 +2,6 @@
import { GlButton, GlIcon } from '@gitlab/ui';
import { __ } from '~/locale';
import LocalStorageSync from '~/vue_shared/components/local_storage_sync.vue';
-import { experiment } from '~/experimentation/utils';
import { DRAWER_EXPANDED_KEY } from '../../constants';
import FirstPipelineCard from './cards/first_pipeline_card.vue';
import GettingStartedCard from './cards/getting_started_card.vue';
@@ -50,29 +49,8 @@ export default {
},
mounted() {
this.setTopPosition();
- this.setInitialExpandState();
},
methods: {
- setInitialExpandState() {
- let isExpanded;
-
- experiment('pipeline_editor_walkthrough', {
- control: () => {
- isExpanded = true;
- },
- candidate: () => {
- isExpanded = false;
- },
- });
-
- // We check in the local storage and if no value is defined, we want the default
- // to be true. We want to explicitly set it to true here so that the drawer
- // animates to open on load.
- const localValue = localStorage.getItem(this.$options.localDrawerKey);
- if (localValue === null) {
- this.isExpanded = isExpanded;
- }
- },
setTopPosition() {
const navbarEl = document.querySelector('.js-navbar');
diff --git a/app/assets/javascripts/pipeline_editor/components/editor/text_editor.vue b/app/assets/javascripts/pipeline_editor/components/editor/text_editor.vue
index 5177cea900c..255e3cb31f1 100644
--- a/app/assets/javascripts/pipeline_editor/components/editor/text_editor.vue
+++ b/app/assets/javascripts/pipeline_editor/components/editor/text_editor.vue
@@ -3,6 +3,7 @@ import { EDITOR_READY_EVENT } from '~/editor/constants';
import { CiSchemaExtension } from '~/editor/extensions/source_editor_ci_schema_ext';
import SourceEditor from '~/vue_shared/components/source_editor.vue';
import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
+import { SOURCE_EDITOR_DEBOUNCE } from '../../constants';
export default {
editorOptions: {
@@ -10,6 +11,7 @@ export default {
// autocomplete for keywords
quickSuggestions: true,
},
+ debounceValue: SOURCE_EDITOR_DEBOUNCE,
components: {
SourceEditor,
},
@@ -34,6 +36,7 @@ export default {
<div class="gl-border-solid gl-border-gray-100 gl-border-1 gl-border-t-none!">
<source-editor
ref="editor"
+ :debounce-value="$options.debounceValue"
:editor-options="$options.editorOptions"
:file-name="ciConfigPath"
v-bind="$attrs"
diff --git a/app/assets/javascripts/pipeline_editor/components/pipeline_editor_tabs.vue b/app/assets/javascripts/pipeline_editor/components/pipeline_editor_tabs.vue
index c75b1d4bb11..5cff93c884f 100644
--- a/app/assets/javascripts/pipeline_editor/components/pipeline_editor_tabs.vue
+++ b/app/assets/javascripts/pipeline_editor/components/pipeline_editor_tabs.vue
@@ -4,7 +4,6 @@ import { s__ } from '~/locale';
import PipelineGraph from '~/pipelines/components/pipeline_graph/pipeline_graph.vue';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import { getParameterValues, setUrlParams, updateHistory } from '~/lib/utils/url_utility';
-import GitlabExperiment from '~/experimentation/components/gitlab_experiment.vue';
import {
CREATE_TAB,
EDITOR_APP_STATUS_EMPTY,
@@ -66,7 +65,6 @@ export default {
GlTabs,
PipelineGraph,
TextEditor,
- GitlabExperiment,
WalkthroughPopover,
},
mixins: [glFeatureFlagsMixin()],
@@ -158,11 +156,7 @@ export default {
data-testid="editor-tab"
@click="setCurrentTab($options.tabConstants.CREATE_TAB)"
>
- <gitlab-experiment name="pipeline_editor_walkthrough">
- <template #candidate>
- <walkthrough-popover v-if="isNewCiConfigFile" v-on="$listeners" />
- </template>
- </gitlab-experiment>
+ <walkthrough-popover v-if="isNewCiConfigFile" v-on="$listeners" />
<ci-editor-header />
<text-editor :commit-sha="commitSha" :value="ciFileContent" v-on="$listeners" />
</editor-tab>
diff --git a/app/assets/javascripts/pipeline_editor/components/ui/pipeline_editor_empty_state.vue b/app/assets/javascripts/pipeline_editor/components/ui/pipeline_editor_empty_state.vue
index dcd08c9de8d..aee71999373 100644
--- a/app/assets/javascripts/pipeline_editor/components/ui/pipeline_editor_empty_state.vue
+++ b/app/assets/javascripts/pipeline_editor/components/ui/pipeline_editor_empty_state.vue
@@ -41,7 +41,12 @@ export default {
</template>
</gl-sprintf>
</p>
- <gl-button variant="confirm" class="gl-mt-3" @click="createEmptyConfigFile">
+ <gl-button
+ variant="confirm"
+ class="gl-mt-3"
+ data-qa-selector="create_new_ci_button"
+ @click="createEmptyConfigFile"
+ >
{{ $options.i18n.btnText }}
</gl-button>
</div>
diff --git a/app/assets/javascripts/pipeline_editor/constants.js b/app/assets/javascripts/pipeline_editor/constants.js
index a65463d02aa..2ebc4306405 100644
--- a/app/assets/javascripts/pipeline_editor/constants.js
+++ b/app/assets/javascripts/pipeline_editor/constants.js
@@ -1,3 +1,5 @@
+import { s__ } from '~/locale';
+
// Values for CI_CONFIG_STATUS_* comes from lint graphQL
export const CI_CONFIG_STATUS_INVALID = 'INVALID';
export const CI_CONFIG_STATUS_VALID = 'VALID';
@@ -47,6 +49,7 @@ export const DRAWER_EXPANDED_KEY = 'pipeline_editor_drawer_expanded';
export const BRANCH_PAGINATION_LIMIT = 20;
export const BRANCH_SEARCH_DEBOUNCE = '500';
+export const SOURCE_EDITOR_DEBOUNCE = 500;
export const STARTER_TEMPLATE_NAME = 'Getting-Started';
@@ -61,3 +64,45 @@ export const TEMPLATE_REPOSITORY_URL =
'https://gitlab.com/gitlab-org/gitlab-foss/tree/master/lib/gitlab/ci/templates';
export const COMMIT_SHA_POLL_INTERVAL = 1000;
+
+export const RUNNERS_AVAILABILITY_SECTION_EXPERIMENT_NAME = 'runners_availability_section';
+export const RUNNERS_SETTINGS_LINK_CLICKED_EVENT = 'runners_settings_link_clicked';
+export const RUNNERS_DOCUMENTATION_LINK_CLICKED_EVENT = 'runners_documentation_link_clicked';
+export const RUNNERS_SETTINGS_BUTTON_CLICKED_EVENT = 'runners_settings_button_clicked';
+export const I18N = {
+ title: s__('Pipelines|Get started with GitLab CI/CD'),
+ runners: {
+ title: s__('Pipelines|Runners are available to run your jobs now'),
+ subtitle: s__(
+ 'Pipelines|GitLab Runner is an application that works with GitLab CI/CD to run jobs in a pipeline. There are active runners available to run your jobs right now. If you prefer, you can %{settingsLinkStart}configure your runners%{settingsLinkEnd} or %{docsLinkStart}learn more%{docsLinkEnd} about runners.',
+ ),
+ },
+ noRunners: {
+ title: s__('Pipelines|No runners detected'),
+ subtitle: s__(
+ 'Pipelines|A GitLab Runner is an application that works with GitLab CI/CD to run jobs in a pipeline. Install GitLab Runner and register your own runners to get started with CI/CD.',
+ ),
+ cta: s__('Pipelines|Install GitLab Runner'),
+ },
+ learnBasics: {
+ title: s__('Pipelines|Learn the basics of pipelines and .yml files'),
+ subtitle: s__(
+ 'Pipelines|Use a sample %{codeStart}.gitlab-ci.yml%{codeEnd} template file to explore how CI/CD works.',
+ ),
+ gettingStarted: {
+ title: s__('Pipelines|"Hello world" with GitLab CI'),
+ description: s__(
+ 'Pipelines|Get familiar with GitLab CI syntax by setting up a simple pipeline running a "Hello world" script to see how it runs, explore how CI/CD works.',
+ ),
+ cta: s__('Pipelines|Try test template'),
+ },
+ },
+ templates: {
+ title: s__('Pipelines|Ready to set up CI/CD for your project?'),
+ subtitle: s__(
+ "Pipelines|Use a template based on your project's language or framework to get started with GitLab CI/CD.",
+ ),
+ description: s__('Pipelines|CI/CD template to test and deploy your %{name} project.'),
+ cta: s__('Pipelines|Use template'),
+ },
+};
diff --git a/app/assets/javascripts/pipeline_editor/index.js b/app/assets/javascripts/pipeline_editor/index.js
index 04f91cb3d1e..732fc665c9e 100644
--- a/app/assets/javascripts/pipeline_editor/index.js
+++ b/app/assets/javascripts/pipeline_editor/index.js
@@ -2,7 +2,6 @@ import Vue from 'vue';
import VueApollo from 'vue-apollo';
import createDefaultClient from '~/lib/graphql';
-import { resetServiceWorkersPublicPath } from '../lib/utils/webpack';
import { EDITOR_APP_STATUS_LOADING } from './constants';
import { CODE_SNIPPET_SOURCE_SETTINGS } from './components/code_snippet_alert/constants';
import getCurrentBranch from './graphql/queries/client/current_branch.query.graphql';
@@ -14,11 +13,6 @@ import typeDefs from './graphql/typedefs.graphql';
import PipelineEditorApp from './pipeline_editor_app.vue';
export const initPipelineEditor = (selector = '#js-pipeline-editor') => {
- // Prevent issues loading syntax validation workers
- // Fixes https://gitlab.com/gitlab-org/gitlab/-/issues/297252
- // TODO Remove when https://gitlab.com/gitlab-org/gitlab/-/issues/321656 is resolved
- resetServiceWorkersPublicPath();
-
const el = document.querySelector(selector);
if (!el) {
diff --git a/app/assets/javascripts/pipeline_editor/pipeline_editor_app.vue b/app/assets/javascripts/pipeline_editor/pipeline_editor_app.vue
index 1da50c55a68..a5436ca63cb 100644
--- a/app/assets/javascripts/pipeline_editor/pipeline_editor_app.vue
+++ b/app/assets/javascripts/pipeline_editor/pipeline_editor_app.vue
@@ -69,9 +69,10 @@ export default {
// If it's a brand new file, we don't want to fetch the content.
// Then when the user commits the first time, the query would run
// to get the initial file content, but we already have it in `lastCommitedContent`
- // so we skip the loading altogether.
- skip({ isNewCiConfigFile, lastCommittedContent }) {
- return isNewCiConfigFile || lastCommittedContent;
+ // so we skip the loading altogether. We also wait for the currentBranch
+ // to have been fetched
+ skip() {
+ return this.shouldSkipBlobContentQuery;
},
variables() {
return {
@@ -128,8 +129,8 @@ export default {
},
ciConfigData: {
query: getCiConfigData,
- skip({ currentCiFileContent }) {
- return !currentCiFileContent;
+ skip() {
+ return this.shouldSkipCiConfigQuery;
},
variables() {
return {
@@ -174,6 +175,9 @@ export default {
},
commitSha: {
query: getLatestCommitShaQuery,
+ skip({ currentBranch }) {
+ return !currentBranch;
+ },
variables() {
return {
projectPath: this.projectFullPath,
@@ -181,7 +185,7 @@ export default {
};
},
update(data) {
- const latestCommitSha = data.project?.repository?.tree?.lastCommit?.sha;
+ const latestCommitSha = data?.project?.repository?.tree?.lastCommit?.sha;
if (this.isFetchingCommitSha && latestCommitSha === this.commitSha) {
this.$apollo.queries.commitSha.startPolling(COMMIT_SHA_POLL_INTERVAL);
@@ -192,6 +196,9 @@ export default {
this.$apollo.queries.commitSha.stopPolling();
return latestCommitSha;
},
+ error() {
+ this.reportFailure(LOAD_FAILURE_UNKNOWN);
+ },
},
currentBranch: {
query: getCurrentBranch,
@@ -234,6 +241,12 @@ export default {
isEmpty() {
return this.currentCiFileContent === '';
},
+ shouldSkipBlobContentQuery() {
+ return this.isNewCiConfigFile || this.lastCommittedContent || !this.currentBranch;
+ },
+ shouldSkipCiConfigQuery() {
+ return !this.currentCiFileContent || !this.commitSha;
+ },
},
i18n: {
resetModal: {
diff --git a/app/assets/javascripts/pipeline_editor/pipeline_editor_home.vue b/app/assets/javascripts/pipeline_editor/pipeline_editor_home.vue
index bb759477e1e..631dd8a2c00 100644
--- a/app/assets/javascripts/pipeline_editor/pipeline_editor_home.vue
+++ b/app/assets/javascripts/pipeline_editor/pipeline_editor_home.vue
@@ -131,6 +131,7 @@ export default {
:ref="$options.commitSectionRef"
:ci-file-content="ciFileContent"
:commit-sha="commitSha"
+ :has-unsaved-changes="hasUnsavedChanges"
:is-new-ci-config-file="isNewCiConfigFile"
:scroll-to-commit-form="scrollToCommitForm"
@scrolled-to-commit-form="setScrollToCommitForm(false)"
diff --git a/app/assets/javascripts/pipeline_wizard/components/commit.vue b/app/assets/javascripts/pipeline_wizard/components/commit.vue
index 518b41c66b1..e68458a494f 100644
--- a/app/assets/javascripts/pipeline_wizard/components/commit.vue
+++ b/app/assets/javascripts/pipeline_wizard/components/commit.vue
@@ -195,7 +195,7 @@ export default {
data-testid="branch_selector_group"
label-for="branch"
>
- <ref-selector id="branch" v-model="branch" data-testid="branch" :project-id="projectPath" />
+ <ref-selector id="branch" v-model="branch" :project-id="projectPath" data-testid="branch" />
</gl-form-group>
<gl-alert
v-if="!!commitError"
@@ -206,7 +206,7 @@ export default {
>
{{ commitError }}
</gl-alert>
- <step-nav show-back-button v-bind="$props" @back="$emit('go-back')">
+ <step-nav show-back-button v-bind="$props" @back="$emit('back')">
<template #after>
<gl-button
:disabled="isCommitButtonEnabled"
diff --git a/app/assets/javascripts/pipeline_wizard/components/input.vue b/app/assets/javascripts/pipeline_wizard/components/input.vue
new file mode 100644
index 00000000000..9a0c8026648
--- /dev/null
+++ b/app/assets/javascripts/pipeline_wizard/components/input.vue
@@ -0,0 +1,99 @@
+<script>
+import { isNode, isDocument, isSeq, visit } from 'yaml';
+import { capitalize } from 'lodash';
+import TextWidget from '~/pipeline_wizard/components/widgets/text.vue';
+import ListWidget from '~/pipeline_wizard/components/widgets/list.vue';
+
+const widgets = {
+ TextWidget,
+ ListWidget,
+};
+
+function isNullOrUndefined(v) {
+ return [undefined, null].includes(v);
+}
+
+export default {
+ components: {
+ ...widgets,
+ },
+ props: {
+ template: {
+ type: Object,
+ required: true,
+ validator: (v) => isNode(v),
+ },
+ compiled: {
+ type: Object,
+ required: true,
+ validator: (v) => isDocument(v) || isNode(v),
+ },
+ target: {
+ type: String,
+ required: true,
+ validator: (v) => /^\$.*/g.test(v),
+ },
+ widget: {
+ type: String,
+ required: true,
+ validator: (v) => {
+ return Object.keys(widgets).includes(`${capitalize(v)}Widget`);
+ },
+ },
+ validate: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
+ },
+ computed: {
+ path() {
+ let res;
+ visit(this.template, (seqKey, node, path) => {
+ if (node && node.value === this.target) {
+ // `path` is an array of objects (all the node's parents)
+ // So this reducer will reduce it to an array of the path's keys,
+ // e.g. `[ 'foo', 'bar', '0' ]`
+ res = path.reduce((p, { key }) => (key ? [...p, `${key}`] : p), []);
+ const parent = path[path.length - 1];
+ if (isSeq(parent)) {
+ res.push(seqKey);
+ }
+ }
+ });
+ return res;
+ },
+ },
+ methods: {
+ compile(v) {
+ if (!this.path) return;
+ if (isNullOrUndefined(v)) {
+ this.compiled.deleteIn(this.path);
+ }
+ this.compiled.setIn(this.path, v);
+ },
+ onModelChange(v) {
+ this.$emit('beforeUpdate:compiled');
+ this.compile(v);
+ this.$emit('update:compiled', this.compiled);
+ this.$emit('highlight', this.path);
+ },
+ onValidationStateChange(v) {
+ this.$emit('update:valid', v);
+ },
+ },
+};
+</script>
+
+<template>
+ <div>
+ <component
+ :is="`${widget}-widget`"
+ ref="widget"
+ :validate="validate"
+ v-bind="$attrs"
+ @input="onModelChange"
+ @update:valid="onValidationStateChange"
+ />
+ </div>
+</template>
diff --git a/app/assets/javascripts/pipeline_wizard/components/step.vue b/app/assets/javascripts/pipeline_wizard/components/step.vue
new file mode 100644
index 00000000000..c6f793e4cc5
--- /dev/null
+++ b/app/assets/javascripts/pipeline_wizard/components/step.vue
@@ -0,0 +1,149 @@
+<script>
+import { GlAlert } from '@gitlab/ui';
+import { isNode, isDocument, parseDocument, Document } from 'yaml';
+import { merge } from '~/lib/utils/yaml';
+import { s__ } from '~/locale';
+import { logError } from '~/lib/logger';
+import InputWrapper from './input.vue';
+import StepNav from './step_nav.vue';
+
+export default {
+ name: 'PipelineWizardStep',
+ i18n: {
+ errors: {
+ cloneErrorUserMessage: s__(
+ 'PipelineWizard|There was an unexpected error trying to set up the template. The error has been logged.',
+ ),
+ },
+ },
+ components: {
+ StepNav,
+ InputWrapper,
+ GlAlert,
+ },
+ props: {
+ // As the inputs prop we expect to receive an array of instructions
+ // on how to display the input fields that will be used to obtain the
+ // user's input. Each input instruction needs a target prop, specifying
+ // the placeholder in the template that will be replaced by the user's
+ // input. The selected widget may require additional validation for the
+ // input object.
+ inputs: {
+ type: Array,
+ required: true,
+ validator: (value) =>
+ value.every((i) => {
+ return i?.target && i?.widget;
+ }),
+ },
+ template: {
+ type: null,
+ required: true,
+ validator: (v) => isNode(v),
+ },
+ hasPreviousStep: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
+ compiled: {
+ type: Object,
+ required: true,
+ validator: (v) => isDocument(v),
+ },
+ },
+ data() {
+ return {
+ wasCompiled: false,
+ validate: false,
+ inputValidStates: Array(this.inputs.length).fill(null),
+ error: null,
+ };
+ },
+ computed: {
+ inputValidStatesThatAreNotNull() {
+ return this.inputValidStates?.filter((s) => s !== null);
+ },
+ areAllInputValidStatesNull() {
+ return !this.inputValidStatesThatAreNotNull?.length;
+ },
+ isValid() {
+ return this.areAllInputValidStatesNull || this.inputValidStatesThatAreNotNull.every((s) => s);
+ },
+ },
+ methods: {
+ forceClone(yamlNode) {
+ try {
+ // document.clone() will only clone the root document object,
+ // but the references to the child nodes inside will be retained.
+ // So in order to ensure a full clone, we need to stringify
+ // and parse until there's a better implementation in the
+ // yaml package.
+ return parseDocument(new Document(yamlNode).toString());
+ } catch (e) {
+ // eslint-disable-next-line @gitlab/require-i18n-strings
+ logError('An unexpected error occurred while trying to clone a template', e);
+ this.error = this.$options.i18n.errors.cloneErrorUserMessage;
+ return null;
+ }
+ },
+ compile() {
+ if (this.wasCompiled) return;
+ // NOTE: This modifies this.compiled without triggering reactivity.
+ // this is done on purpose, see
+ // https://gitlab.com/gitlab-org/gitlab/-/merge_requests/81412#note_862972703
+ // for more information
+ merge(this.compiled, this.forceClone(this.template));
+ this.wasCompiled = true;
+ },
+ onUpdate(c) {
+ this.$emit('update:compiled', c);
+ },
+ onPrevClick() {
+ this.$emit('back');
+ },
+ async onNextClick() {
+ this.validate = true;
+ await this.$nextTick();
+ if (this.isValid) {
+ this.$emit('next');
+ }
+ },
+ onInputValidationStateChange(inputId, value) {
+ this.$set(this.inputValidStates, inputId, value);
+ },
+ onHighlight(path) {
+ this.$emit('update:highlight', path);
+ },
+ },
+};
+</script>
+<template>
+ <div>
+ <gl-alert v-if="error" class="gl-mb-4" variant="danger">
+ {{ error }}
+ </gl-alert>
+ <input-wrapper
+ v-for="(input, i) in inputs"
+ :key="input.target"
+ :compiled="compiled"
+ :target="input.target"
+ :template="template"
+ :validate="validate"
+ :widget="input.widget"
+ class="gl-mb-2"
+ v-bind="input"
+ @highlight="onHighlight"
+ @update:valid="(validationState) => onInputValidationStateChange(i, validationState)"
+ @update:compiled="onUpdate"
+ @beforeUpdate:compiled.once="compile"
+ />
+ <step-nav
+ :next-button-enabled="isValid"
+ :show-back-button="hasPreviousStep"
+ show-next-button
+ @back="onPrevClick"
+ @next="onNextClick"
+ />
+ </div>
+</template>
diff --git a/app/assets/javascripts/pipeline_wizard/components/widgets/list.vue b/app/assets/javascripts/pipeline_wizard/components/widgets/list.vue
new file mode 100644
index 00000000000..a5ce56daf07
--- /dev/null
+++ b/app/assets/javascripts/pipeline_wizard/components/widgets/list.vue
@@ -0,0 +1,195 @@
+<script>
+import { uniqueId } from 'lodash';
+import { GlButton, GlFormGroup, GlFormInputGroup } from '@gitlab/ui';
+import { s__ } from '~/locale';
+
+const VALIDATION_STATE = {
+ NO_VALIDATION: null,
+ INVALID: false,
+ VALID: true,
+};
+
+export const i18n = {
+ addStepButtonLabel: s__('PipelineWizardListWidget|add another step'),
+ removeStepButtonLabel: s__('PipelineWizardListWidget|remove step'),
+ invalidFeedback: s__('PipelineWizardInputValidation|This value is not valid'),
+ errors: {
+ needsAnyValueError: s__('PipelineWizardInputValidation|At least one entry is required'),
+ },
+};
+
+export default {
+ i18n,
+ name: 'ListWidget',
+ components: {
+ GlButton,
+ GlFormGroup,
+ GlFormInputGroup,
+ },
+ props: {
+ label: {
+ type: String,
+ required: true,
+ },
+ description: {
+ type: String,
+ required: false,
+ default: null,
+ },
+ placeholder: {
+ type: String,
+ required: false,
+ default: null,
+ },
+ default: {
+ type: Array,
+ required: false,
+ default: null,
+ },
+ invalidFeedback: {
+ type: String,
+ required: false,
+ default: i18n.invalidFeedback,
+ },
+ id: {
+ type: String,
+ required: false,
+ default: () => uniqueId('listWidget-'),
+ },
+ pattern: {
+ type: String,
+ required: false,
+ default: null,
+ },
+ required: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
+ validate: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
+ },
+ data() {
+ return {
+ touched: false,
+ value: this.default ? this.default.map(this.getAsValueEntry) : [this.getAsValueEntry(null)],
+ };
+ },
+ computed: {
+ sanitizedValue() {
+ // Filter out empty steps
+ return this.value.filter(({ value }) => Boolean(value)).map(({ value }) => value) || [];
+ },
+ hasAnyValue() {
+ return this.value.some(({ value }) => Boolean(value));
+ },
+ needsAnyValue() {
+ return this.required && !this.value.some(({ value }) => Boolean(value));
+ },
+ inputFieldStates() {
+ return this.value.map(this.getValidationStateForValue);
+ },
+ inputGroupState() {
+ return this.showValidationState
+ ? this.inputFieldStates.every((v) => v !== VALIDATION_STATE.INVALID)
+ : VALIDATION_STATE.NO_VALIDATION;
+ },
+ showValidationState() {
+ return this.touched || this.validate;
+ },
+ feedback() {
+ return this.needsAnyValue
+ ? this.$options.i18n.errors.needsAnyValueError
+ : this.invalidFeedback;
+ },
+ },
+ async created() {
+ if (this.default) {
+ // emit an updated default value
+ await this.$nextTick();
+ this.$emit('input', this.sanitizedValue);
+ }
+ },
+ methods: {
+ addInputField() {
+ this.value.push(this.getAsValueEntry(null));
+ },
+ getAsValueEntry(value) {
+ return {
+ id: uniqueId('listValue-'),
+ value,
+ };
+ },
+ getValidationStateForValue({ value }, fieldIndex) {
+ // If we require a value to be set, mark the first
+ // field as invalid, but not all of them.
+ if (this.needsAnyValue && fieldIndex === 0) return VALIDATION_STATE.INVALID;
+ if (!value) return VALIDATION_STATE.NO_VALIDATION;
+ return this.passesPatternValidation(value)
+ ? VALIDATION_STATE.VALID
+ : VALIDATION_STATE.INVALID;
+ },
+ passesPatternValidation(v) {
+ return !this.pattern || new RegExp(this.pattern).test(v);
+ },
+ async onValueUpdate() {
+ await this.$nextTick();
+ this.$emit('input', this.sanitizedValue);
+ },
+ onTouch() {
+ this.touched = true;
+ },
+ removeValue(index) {
+ this.value.splice(index, 1);
+ this.onValueUpdate();
+ },
+ },
+};
+</script>
+
+<template>
+ <div class="gl-mb-6">
+ <gl-form-group
+ :invalid-feedback="feedback"
+ :label="label"
+ :label-description="description"
+ :state="inputGroupState"
+ class="gl-mb-2"
+ >
+ <gl-form-input-group
+ v-for="(item, i) in value"
+ :key="item.id"
+ v-model.trim="value[i].value"
+ :placeholder="i === 0 ? placeholder : undefined"
+ :state="inputFieldStates[i]"
+ class="gl-mb-2"
+ type="text"
+ @blur="onTouch"
+ @input="onValueUpdate"
+ >
+ <template v-if="value.length > 1" #append>
+ <gl-button
+ :aria-label="$options.i18n.removeStepButtonLabel"
+ category="secondary"
+ data-testid="remove-step-button"
+ icon="remove"
+ @click="removeValue"
+ />
+ </template>
+ </gl-form-input-group>
+ </gl-form-group>
+ <gl-button
+ category="tertiary"
+ data-testid="add-step-button"
+ icon="plus"
+ size="small"
+ variant="confirm"
+ @click="addInputField"
+ >
+ {{ $options.i18n.addStepButtonLabel }}
+ </gl-button>
+ </div>
+</template>
diff --git a/app/assets/javascripts/pipeline_wizard/components/wrapper.vue b/app/assets/javascripts/pipeline_wizard/components/wrapper.vue
new file mode 100644
index 00000000000..b7207576ddc
--- /dev/null
+++ b/app/assets/javascripts/pipeline_wizard/components/wrapper.vue
@@ -0,0 +1,185 @@
+<script>
+import { GlProgressBar } from '@gitlab/ui';
+import { Document } from 'yaml';
+import { merge } from '~/lib/utils/yaml';
+import { __ } from '~/locale';
+import { isValidStepSeq } from '~/pipeline_wizard/validators';
+import YamlEditor from './editor.vue';
+import WizardStep from './step.vue';
+import CommitStep from './commit.vue';
+
+export const i18n = {
+ stepNofN: __('Step %{currentStep} of %{stepCount}'),
+ draft: __('Draft: %{filename}'),
+ overlayMessage: __(`Start inputting changes and we will generate a
+ YAML-file for you to add to your repository`),
+};
+
+export default {
+ name: 'PipelineWizardWrapper',
+ i18n,
+ components: {
+ GlProgressBar,
+ YamlEditor,
+ WizardStep,
+ CommitStep,
+ },
+ props: {
+ steps: {
+ type: Object,
+ required: true,
+ validator: isValidStepSeq,
+ },
+ projectPath: {
+ type: String,
+ required: true,
+ },
+ defaultBranch: {
+ type: String,
+ required: true,
+ },
+ filename: {
+ type: String,
+ required: true,
+ },
+ },
+ data() {
+ return {
+ highlightPath: null,
+ currentStepIndex: 0,
+ // TODO: In order to support updating existing pipelines, the below
+ // should contain a parsed version of an existing .gitlab-ci.yml.
+ // See https://gitlab.com/gitlab-org/gitlab/-/issues/355306
+ compiled: new Document({}),
+ showPlaceholder: true,
+ pipelineBlob: null,
+ placeholder: this.getPlaceholder(),
+ };
+ },
+ computed: {
+ currentStepConfig() {
+ return this.steps.get(this.currentStepIndex);
+ },
+ currentStepInputs() {
+ return this.currentStepConfig.get('inputs').toJSON();
+ },
+ currentStepTemplate() {
+ return this.currentStepConfig.get('template', true);
+ },
+ currentStep() {
+ return this.currentStepIndex + 1;
+ },
+ stepCount() {
+ return this.steps.items.length + 1;
+ },
+ progress() {
+ return Math.ceil((this.currentStep / (this.stepCount + 1)) * 100);
+ },
+ isLastStep() {
+ return this.currentStep === this.stepCount;
+ },
+ },
+ watch: {
+ isLastStep(value) {
+ if (value) this.resetHighlight();
+ },
+ },
+ methods: {
+ resetHighlight() {
+ this.highlightPath = null;
+ },
+ onUpdate() {
+ this.showPlaceholder = false;
+ },
+ onEditorUpdate(blob) {
+ // TODO: In a later iteration, we could add a loopback allowing for
+ // changes from the editor to flow back into the model
+ // see https://gitlab.com/gitlab-org/gitlab/-/issues/355312
+ this.pipelineBlob = blob;
+ },
+ getPlaceholder() {
+ const doc = new Document({});
+ this.steps.items.forEach((tpl) => {
+ merge(doc, tpl.get('template').clone());
+ });
+ return doc;
+ },
+ },
+};
+</script>
+
+<template>
+ <div class="row gl-mt-8">
+ <main class="col-md-6 gl-pr-8">
+ <header class="gl-mb-5">
+ <h3 class="text-secondary gl-mt-0" data-testid="step-count">
+ {{ sprintf($options.i18n.stepNofN, { currentStep, stepCount }) }}
+ </h3>
+ <gl-progress-bar :value="progress" variant="success" />
+ </header>
+ <section class="gl-mb-4">
+ <commit-step
+ v-if="isLastStep"
+ ref="step"
+ :default-branch="defaultBranch"
+ :file-content="pipelineBlob"
+ :filename="filename"
+ :project-path="projectPath"
+ @back="currentStepIndex--"
+ />
+ <wizard-step
+ v-else
+ :key="currentStepIndex"
+ ref="step"
+ :compiled.sync="compiled"
+ :has-next-step="currentStepIndex < steps.items.length"
+ :has-previous-step="currentStepIndex > 0"
+ :highlight.sync="highlightPath"
+ :inputs="currentStepInputs"
+ :template="currentStepTemplate"
+ @back="currentStepIndex--"
+ @next="currentStepIndex++"
+ @update:compiled="onUpdate"
+ />
+ </section>
+ </main>
+ <aside class="col-md-6 gl-pt-3">
+ <div
+ class="gl-border-1 gl-border-gray-100 gl-border-solid border-radius-default gl-bg-gray-10"
+ >
+ <h6 class="gl-p-2 gl-px-4 text-secondary" data-testid="editor-header">
+ {{ sprintf($options.i18n.draft, { filename }) }}
+ </h6>
+ <div class="gl-relative gl-overflow-hidden">
+ <yaml-editor
+ :aria-hidden="showPlaceholder"
+ :doc="showPlaceholder ? placeholder : compiled"
+ :filename="filename"
+ :highlight="highlightPath"
+ class="gl-w-full"
+ @update:yaml="onEditorUpdate"
+ />
+ <div
+ v-if="showPlaceholder"
+ class="gl-absolute gl-top-0 gl-right-0 gl-bottom-0 gl-left-0 gl-filter-blur-1"
+ data-testid="placeholder-overlay"
+ >
+ <div
+ class="gl-absolute gl-top-0 gl-right-0 gl-bottom-0 gl-left-0 bg-white gl-opacity-5 gl-z-index-2"
+ ></div>
+ <div
+ class="gl-relative gl-h-full gl-display-flex gl-align-items-center gl-justify-content-center gl-z-index-3"
+ >
+ <div class="gl-max-w-34">
+ <h4 data-testid="filename">{{ filename }}</h4>
+ <p data-testid="description">
+ {{ $options.i18n.overlayMessage }}
+ </p>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </aside>
+ </div>
+</template>
diff --git a/app/assets/javascripts/pipeline_wizard/pipeline_wizard.vue b/app/assets/javascripts/pipeline_wizard/pipeline_wizard.vue
new file mode 100644
index 00000000000..7200b4e3782
--- /dev/null
+++ b/app/assets/javascripts/pipeline_wizard/pipeline_wizard.vue
@@ -0,0 +1,65 @@
+<script>
+import { parseDocument } from 'yaml';
+import WizardWrapper from './components/wrapper.vue';
+
+export default {
+ name: 'PipelineWizard',
+ components: {
+ WizardWrapper,
+ },
+ props: {
+ template: {
+ type: String,
+ required: true,
+ },
+ projectPath: {
+ type: String,
+ required: true,
+ },
+ defaultBranch: {
+ type: String,
+ required: true,
+ },
+ defaultFilename: {
+ type: String,
+ required: false,
+ default: '.gitlab-ci.yml',
+ },
+ },
+ computed: {
+ parsedTemplate() {
+ return this.template ? parseDocument(this.template) : null;
+ },
+ title() {
+ return this.parsedTemplate?.get('title');
+ },
+ description() {
+ return this.parsedTemplate?.get('description');
+ },
+ filename() {
+ return this.parsedTemplate?.get('filename') || this.defaultFilename;
+ },
+ steps() {
+ return this.parsedTemplate?.get('steps');
+ },
+ },
+};
+</script>
+
+<template>
+ <div>
+ <div class="gl-my-8">
+ <h2 class="gl-mb-4" data-testid="title">{{ title }}</h2>
+ <p class="text-tertiary gl-font-lg gl-max-w-80" data-testid="description">
+ {{ description }}
+ </p>
+ </div>
+ <wizard-wrapper
+ v-if="steps"
+ :default-branch="defaultBranch"
+ :filename="filename"
+ :project-path="projectPath"
+ :steps="steps"
+ />
+ </div>
+</template>
diff --git a/app/assets/javascripts/pipeline_wizard/validators.js b/app/assets/javascripts/pipeline_wizard/validators.js
new file mode 100644
index 00000000000..57cd56b23a5
--- /dev/null
+++ b/app/assets/javascripts/pipeline_wizard/validators.js
@@ -0,0 +1,4 @@
+import { isSeq } from 'yaml';
+
+export const isValidStepSeq = (v) =>
+ isSeq(v) && v.items.every((s) => s.get('inputs') && s.get('template'));
diff --git a/app/assets/javascripts/pipelines/components/header_component.vue b/app/assets/javascripts/pipelines/components/header_component.vue
index 6a4d1bb44f2..ac97c9d2743 100644
--- a/app/assets/javascripts/pipelines/components/header_component.vue
+++ b/app/assets/javascripts/pipelines/components/header_component.vue
@@ -174,6 +174,8 @@ export default {
});
if (errors.length > 0) {
+ this.isRetrying = false;
+
this.reportFailure(POST_FAILURE);
} else {
await this.$apollo.queries.pipeline.refetch();
@@ -182,6 +184,8 @@ export default {
}
}
} catch {
+ this.isRetrying = false;
+
this.reportFailure(POST_FAILURE);
}
},
diff --git a/app/assets/javascripts/pipelines/components/jobs/jobs_app.vue b/app/assets/javascripts/pipelines/components/jobs/jobs_app.vue
index 99fb5c146ba..b45f3e4f32c 100644
--- a/app/assets/javascripts/pipelines/components/jobs/jobs_app.vue
+++ b/app/assets/javascripts/pipelines/components/jobs/jobs_app.vue
@@ -60,6 +60,15 @@ export default {
iid: this.pipelineIid,
};
},
+ loading() {
+ return this.$apollo.queries.jobs.loading;
+ },
+ showSkeletonLoader() {
+ return this.firstLoad && this.loading;
+ },
+ showLoadingSpinner() {
+ return !this.firstLoad && this.loading;
+ },
},
mounted() {
eventHub.$on('jobActionPerformed', this.handleJobAction);
@@ -69,7 +78,7 @@ export default {
},
methods: {
handleJobAction() {
- this.firstLoad = true;
+ this.firstLoad = false;
this.$apollo.queries.jobs.refetch();
},
@@ -98,7 +107,7 @@ export default {
<template>
<div>
- <div v-if="$apollo.loading && firstLoad" class="gl-mt-5">
+ <div v-if="showSkeletonLoader" class="gl-mt-5">
<gl-skeleton-loader :width="1248" :height="73">
<circle cx="748.031" cy="37.7193" r="15.0307" />
<circle cx="787.241" cy="37.7193" r="15.0307" />
@@ -118,7 +127,7 @@ export default {
<jobs-table v-else :jobs="jobs" :table-fields="$options.fields" data-testid="jobs-tab-table" />
<gl-intersection-observer v-if="jobsPageInfo.hasNextPage" @appear="fetchMoreJobs">
- <gl-loading-icon v-if="$apollo.loading" size="md" />
+ <gl-loading-icon v-if="showLoadingSpinner" size="md" />
</gl-intersection-observer>
</div>
</template>
diff --git a/app/assets/javascripts/pipelines/components/pipelines_list/empty_state.vue b/app/assets/javascripts/pipelines/components/pipelines_list/empty_state.vue
index 1ce6654e0e9..0380ba646cc 100644
--- a/app/assets/javascripts/pipelines/components/pipelines_list/empty_state.vue
+++ b/app/assets/javascripts/pipelines/components/pipelines_list/empty_state.vue
@@ -1,33 +1,15 @@
<script>
-import { GlEmptyState, GlButton } from '@gitlab/ui';
-import { startCodeQualityWalkthrough, track } from '~/code_quality_walkthrough/utils';
-import GitlabExperiment from '~/experimentation/components/gitlab_experiment.vue';
-import ExperimentTracking from '~/experimentation/experiment_tracking';
-import { getExperimentData } from '~/experimentation/utils';
-import { helpPagePath } from '~/helpers/help_page_helper';
+import { GlEmptyState } from '@gitlab/ui';
import { s__ } from '~/locale';
import PipelinesCiTemplates from './pipelines_ci_templates.vue';
export default {
i18n: {
- title: s__('Pipelines|Build with confidence'),
- description: s__(`Pipelines|GitLab CI/CD can automatically build,
- test, and deploy your code. Let GitLab take care of time
- consuming tasks, so you can spend more time creating.`),
- aboutRunnersBtnText: s__('Pipelines|Learn about Runners'),
- installRunnersBtnText: s__('Pipelines|Install GitLab Runners'),
- codeQualityTitle: s__('Pipelines|Improve code quality with GitLab CI/CD'),
- codeQualityDescription: s__(`Pipelines|To keep your codebase simple,
- readable, and accessible to contributors, use GitLab CI/CD
- to analyze your code quality with every push to your project.`),
- codeQualityBtnText: s__('Pipelines|Add a code quality job'),
noCiDescription: s__('Pipelines|This project is not currently set up to run pipelines.'),
},
name: 'PipelinesEmptyState',
components: {
GlEmptyState,
- GlButton,
- GitlabExperiment,
PipelinesCiTemplates,
},
props: {
@@ -39,88 +21,26 @@ export default {
type: Boolean,
required: true,
},
- codeQualityPagePath: {
- type: String,
- required: false,
- default: null,
- },
ciRunnerSettingsPath: {
type: String,
required: false,
default: null,
},
- },
- computed: {
- ciHelpPagePath() {
- return helpPagePath('ci/quick_start/index.md');
- },
- isCodeQualityExperimentActive() {
- return this.canSetCi && Boolean(getExperimentData('code_quality_walkthrough'));
- },
- isCiRunnerTemplatesExperimentActive() {
- return this.canSetCi && Boolean(getExperimentData('ci_runner_templates'));
- },
- },
- mounted() {
- startCodeQualityWalkthrough();
- },
- methods: {
- trackClick() {
- track('cta_clicked');
- },
- trackCiRunnerTemplatesClick(action) {
- const tracking = new ExperimentTracking('ci_runner_templates');
- tracking.event(action);
+ anyRunnersAvailable: {
+ type: Boolean,
+ required: false,
+ default: true,
},
},
};
</script>
<template>
<div>
- <gitlab-experiment v-if="isCodeQualityExperimentActive" name="code_quality_walkthrough">
- <template #control><pipelines-ci-templates /></template>
- <template #candidate>
- <gl-empty-state
- :title="$options.i18n.codeQualityTitle"
- :svg-path="emptyStateSvgPath"
- :description="$options.i18n.codeQualityDescription"
- >
- <template #actions>
- <gl-button :href="codeQualityPagePath" variant="confirm" @click="trackClick()">
- {{ $options.i18n.codeQualityBtnText }}
- </gl-button>
- </template>
- </gl-empty-state>
- </template>
- </gitlab-experiment>
- <gitlab-experiment v-else-if="isCiRunnerTemplatesExperimentActive" name="ci_runner_templates">
- <template #control><pipelines-ci-templates /></template>
- <template #candidate>
- <gl-empty-state
- :title="$options.i18n.title"
- :svg-path="emptyStateSvgPath"
- :description="$options.i18n.description"
- >
- <template #actions>
- <gl-button
- :href="ciRunnerSettingsPath"
- variant="confirm"
- @click="trackCiRunnerTemplatesClick('install_runners_button_clicked')"
- >
- {{ $options.i18n.installRunnersBtnText }}
- </gl-button>
- <gl-button
- :href="ciHelpPagePath"
- variant="default"
- @click="trackCiRunnerTemplatesClick('learn_button_clicked')"
- >
- {{ $options.i18n.aboutRunnersBtnText }}
- </gl-button>
- </template>
- </gl-empty-state>
- </template>
- </gitlab-experiment>
- <pipelines-ci-templates v-else-if="canSetCi" />
+ <pipelines-ci-templates
+ v-if="canSetCi"
+ :ci-runner-settings-path="ciRunnerSettingsPath"
+ :any-runners-available="anyRunnersAvailable"
+ />
<gl-empty-state
v-else
title=""
diff --git a/app/assets/javascripts/pipelines/components/pipelines_list/pipeline_labels.vue b/app/assets/javascripts/pipelines/components/pipelines_list/pipeline_labels.vue
new file mode 100644
index 00000000000..40b2454b8c1
--- /dev/null
+++ b/app/assets/javascripts/pipelines/components/pipelines_list/pipeline_labels.vue
@@ -0,0 +1,170 @@
+<script>
+import { GlLink, GlPopover, GlSprintf, GlTooltipDirective, GlBadge } from '@gitlab/ui';
+import { helpPagePath } from '~/helpers/help_page_helper';
+import { SCHEDULE_ORIGIN } from '../../constants';
+
+export default {
+ components: {
+ GlBadge,
+ GlLink,
+ GlPopover,
+ GlSprintf,
+ },
+ directives: {
+ GlTooltip: GlTooltipDirective,
+ },
+ inject: {
+ targetProjectFullPath: {
+ default: '',
+ },
+ },
+ props: {
+ pipeline: {
+ type: Object,
+ required: true,
+ },
+ pipelineScheduleUrl: {
+ type: String,
+ required: true,
+ },
+ },
+ computed: {
+ isScheduled() {
+ return this.pipeline.source === SCHEDULE_ORIGIN;
+ },
+ isInFork() {
+ return Boolean(
+ this.targetProjectFullPath &&
+ this.pipeline?.project?.full_path !== `/${this.targetProjectFullPath}`,
+ );
+ },
+ autoDevopsTagId() {
+ return `pipeline-url-autodevops-${this.pipeline.id}`;
+ },
+ autoDevopsHelpPath() {
+ return helpPagePath('topics/autodevops/index.md');
+ },
+ },
+};
+</script>
+<template>
+ <div class="label-container gl-mt-1">
+ <gl-badge
+ v-if="isScheduled"
+ v-gl-tooltip
+ :href="pipelineScheduleUrl"
+ target="__blank"
+ :title="__('This pipeline was triggered by a schedule.')"
+ variant="info"
+ size="sm"
+ data-testid="pipeline-url-scheduled"
+ >{{ __('Scheduled') }}</gl-badge
+ >
+ <gl-badge
+ v-if="pipeline.flags.latest"
+ v-gl-tooltip
+ :title="__('Latest pipeline for the most recent commit on this branch')"
+ variant="success"
+ size="sm"
+ data-testid="pipeline-url-latest"
+ >{{ __('latest') }}</gl-badge
+ >
+ <gl-badge
+ v-if="pipeline.flags.merge_train_pipeline"
+ v-gl-tooltip
+ :title="
+ s__(
+ 'Pipeline|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch.',
+ )
+ "
+ variant="info"
+ size="sm"
+ data-testid="pipeline-url-train"
+ >{{ s__('Pipeline|merge train') }}</gl-badge
+ >
+ <gl-badge
+ v-if="pipeline.flags.yaml_errors"
+ v-gl-tooltip
+ :title="pipeline.yaml_errors"
+ variant="danger"
+ size="sm"
+ data-testid="pipeline-url-yaml"
+ >{{ __('yaml invalid') }}</gl-badge
+ >
+ <gl-badge
+ v-if="pipeline.flags.failure_reason"
+ v-gl-tooltip
+ :title="pipeline.failure_reason"
+ variant="danger"
+ size="sm"
+ data-testid="pipeline-url-failure"
+ >{{ __('error') }}</gl-badge
+ >
+ <template v-if="pipeline.flags.auto_devops">
+ <gl-link
+ :id="autoDevopsTagId"
+ tabindex="0"
+ data-testid="pipeline-url-autodevops"
+ role="button"
+ >
+ <gl-badge variant="info" size="sm">
+ {{ __('Auto DevOps') }}
+ </gl-badge>
+ </gl-link>
+ <gl-popover :target="autoDevopsTagId" triggers="focus" placement="top">
+ <template #title>
+ <div class="gl-font-weight-normal gl-line-height-normal">
+ <gl-sprintf
+ :message="
+ __(
+ 'This pipeline makes use of a predefined CI/CD configuration enabled by %{strongStart}Auto DevOps.%{strongEnd}',
+ )
+ "
+ >
+ <template #strong="{ content }">
+ <b>{{ content }}</b>
+ </template>
+ </gl-sprintf>
+ </div>
+ </template>
+ <gl-link
+ :href="autoDevopsHelpPath"
+ data-testid="pipeline-url-autodevops-link"
+ target="_blank"
+ >
+ {{ __('Learn more about Auto DevOps') }}
+ </gl-link>
+ </gl-popover>
+ </template>
+
+ <gl-badge
+ v-if="pipeline.flags.stuck"
+ variant="warning"
+ size="sm"
+ data-testid="pipeline-url-stuck"
+ >{{ __('stuck') }}</gl-badge
+ >
+ <gl-badge
+ v-if="pipeline.flags.detached_merge_request_pipeline"
+ v-gl-tooltip
+ :title="
+ s__(
+ `Pipeline|This pipeline ran on the contents of this merge request's source branch, not the target branch.`,
+ )
+ "
+ variant="info"
+ size="sm"
+ data-testid="pipeline-url-detached"
+ >{{ s__('Pipeline|merge request') }}</gl-badge
+ >
+ <gl-badge
+ v-if="isInFork"
+ v-gl-tooltip
+ :title="__('Pipeline ran in fork of project')"
+ variant="info"
+ size="sm"
+ data-testid="pipeline-url-fork"
+ >{{ __('fork') }}</gl-badge
+ >
+ </div>
+</template>
diff --git a/app/assets/javascripts/pipelines/components/pipelines_list/pipeline_url.vue b/app/assets/javascripts/pipelines/components/pipelines_list/pipeline_url.vue
index 7c78abae77f..1dcbd77a92d 100644
--- a/app/assets/javascripts/pipelines/components/pipelines_list/pipeline_url.vue
+++ b/app/assets/javascripts/pipelines/components/pipelines_list/pipeline_url.vue
@@ -1,29 +1,20 @@
<script>
-import { GlIcon, GlLink, GlPopover, GlSprintf, GlTooltipDirective, GlBadge } from '@gitlab/ui';
-import { __, sprintf } from '~/locale';
-import { helpPagePath } from '~/helpers/help_page_helper';
-import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
+import { GlIcon, GlLink, GlTooltipDirective } from '@gitlab/ui';
+import { __ } from '~/locale';
import TooltipOnTruncate from '~/vue_shared/components/tooltip_on_truncate/tooltip_on_truncate.vue';
-import { SCHEDULE_ORIGIN, ICONS } from '../../constants';
+import { ICONS } from '../../constants';
+import PipelineLabels from './pipeline_labels.vue';
export default {
components: {
GlIcon,
GlLink,
- GlPopover,
- GlSprintf,
- GlBadge,
+ PipelineLabels,
TooltipOnTruncate,
},
directives: {
GlTooltip: GlTooltipDirective,
},
- mixins: [glFeatureFlagMixin()],
- inject: {
- targetProjectFullPath: {
- default: '',
- },
- },
props: {
pipeline: {
type: Object,
@@ -37,27 +28,8 @@ export default {
type: String,
required: true,
},
- viewType: {
- type: String,
- required: true,
- },
},
computed: {
- isScheduled() {
- return this.pipeline.source === SCHEDULE_ORIGIN;
- },
- isInFork() {
- return Boolean(
- this.targetProjectFullPath &&
- this.pipeline?.project?.full_path !== `/${this.targetProjectFullPath}`,
- );
- },
- autoDevopsTagId() {
- return `pipeline-url-autodevops-${this.pipeline.id}`;
- },
- autoDevopsHelpPath() {
- return helpPagePath('topics/autodevops/index.md');
- },
mergeRequestRef() {
return this.pipeline?.merge_request;
},
@@ -139,205 +111,66 @@ export default {
commitTitle() {
return this.pipeline?.commit?.title;
},
- hasAuthor() {
- return (
- this.commitAuthor?.avatar_url && this.commitAuthor?.path && this.commitAuthor?.username
- );
- },
- userImageAltDescription() {
- return this.commitAuthor?.username
- ? sprintf(__("%{username}'s avatar"), { username: this.commitAuthor.username })
- : null;
- },
- rearrangePipelinesTable() {
- return this.glFeatures?.rearrangePipelinesTable;
- },
},
};
</script>
<template>
<div class="pipeline-tags" data-testid="pipeline-url-table-cell">
- <template v-if="rearrangePipelinesTable">
- <div class="commit-title gl-mb-2" data-testid="commit-title-container">
- <span v-if="commitTitle" class="gl-display-flex">
- <tooltip-on-truncate :title="commitTitle" class="flex-truncate-child gl-flex-grow-1">
- <gl-link
- :href="commitUrl"
- class="commit-row-message gl-text-gray-900"
- data-testid="commit-title"
- >{{ commitTitle }}</gl-link
- >
- </tooltip-on-truncate>
- </span>
- <span v-else>{{ __("Can't find HEAD commit for this branch") }}</span>
- </div>
- <div class="gl-mb-2">
- <gl-link
- :href="pipeline.path"
- class="gl-text-decoration-underline gl-text-blue-600!"
- data-testid="pipeline-url-link"
- data-qa-selector="pipeline_url_link"
- >
- #{{ pipeline[pipelineKey] }}
- </gl-link>
- <!--Commit row-->
- <div class="icon-container gl-display-inline-block">
- <gl-icon
- v-gl-tooltip
- :name="commitIcon"
- :title="commitIconTooltipTitle"
- data-testid="commit-icon-type"
- />
- </div>
- <tooltip-on-truncate :title="tooltipTitle" truncate-target="child" placement="top">
+ <div class="commit-title gl-mb-2" data-testid="commit-title-container">
+ <span v-if="commitTitle" class="gl-display-flex">
+ <tooltip-on-truncate :title="commitTitle" class="gl-flex-grow-1 gl-text-truncate">
<gl-link
- v-if="mergeRequestRef"
- :href="mergeRequestRef.path"
- class="ref-name"
- data-testid="merge-request-ref"
- >{{ mergeRequestRef.iid }}</gl-link
+ :href="commitUrl"
+ class="commit-row-message gl-text-gray-900"
+ data-testid="commit-title"
+ >{{ commitTitle }}</gl-link
>
- <gl-link v-else :href="refUrl" class="ref-name" data-testid="commit-ref-name">{{
- commitRef.name
- }}</gl-link>
</tooltip-on-truncate>
+ </span>
+ <span v-else>{{ __("Can't find HEAD commit for this branch") }}</span>
+ </div>
+ <div class="gl-mb-2">
+ <gl-link
+ :href="pipeline.path"
+ class="gl-text-decoration-underline gl-text-blue-600! gl-mr-3"
+ data-testid="pipeline-url-link"
+ data-qa-selector="pipeline_url_link"
+ >
+ #{{ pipeline[pipelineKey] }}
+ </gl-link>
+ <!--Commit row-->
+ <div class="icon-container gl-display-inline-block gl-mr-1">
<gl-icon
v-gl-tooltip
- name="commit"
- class="commit-icon"
- :title="__('Commit')"
- data-testid="commit-icon"
+ :name="commitIcon"
+ :title="commitIconTooltipTitle"
+ data-testid="commit-icon-type"
/>
-
- <gl-link :href="commitUrl" class="commit-sha mr-0" data-testid="commit-short-sha">{{
- commitShortSha
- }}</gl-link>
- <!--End of commit row-->
</div>
- </template>
- <gl-link
- v-if="!rearrangePipelinesTable"
- :href="pipeline.path"
- class="gl-text-decoration-underline"
- data-testid="pipeline-url-link"
- data-qa-selector="pipeline_url_link"
- >
- #{{ pipeline[pipelineKey] }}
- </gl-link>
- <div class="label-container gl-mt-1">
- <gl-badge
- v-if="isScheduled"
- v-gl-tooltip
- :href="pipelineScheduleUrl"
- target="__blank"
- :title="__('This pipeline was triggered by a schedule.')"
- variant="info"
- size="sm"
- data-testid="pipeline-url-scheduled"
- >{{ __('Scheduled') }}</gl-badge
- >
- <gl-badge
- v-if="pipeline.flags.latest"
- v-gl-tooltip
- :title="__('Latest pipeline for the most recent commit on this branch')"
- variant="success"
- size="sm"
- data-testid="pipeline-url-latest"
- >{{ __('latest') }}</gl-badge
- >
- <gl-badge
- v-if="pipeline.flags.merge_train_pipeline"
- v-gl-tooltip
- :title="__('This is a merge train pipeline')"
- variant="info"
- size="sm"
- data-testid="pipeline-url-train"
- >{{ __('train') }}</gl-badge
- >
- <gl-badge
- v-if="pipeline.flags.yaml_errors"
- v-gl-tooltip
- :title="pipeline.yaml_errors"
- variant="danger"
- size="sm"
- data-testid="pipeline-url-yaml"
- >{{ __('yaml invalid') }}</gl-badge
- >
- <gl-badge
- v-if="pipeline.flags.failure_reason"
- v-gl-tooltip
- :title="pipeline.failure_reason"
- variant="danger"
- size="sm"
- data-testid="pipeline-url-failure"
- >{{ __('error') }}</gl-badge
- >
- <template v-if="pipeline.flags.auto_devops">
+ <tooltip-on-truncate :title="tooltipTitle" truncate-target="child" placement="top">
<gl-link
- :id="autoDevopsTagId"
- tabindex="0"
- data-testid="pipeline-url-autodevops"
- role="button"
+ v-if="mergeRequestRef"
+ :href="mergeRequestRef.path"
+ class="ref-name gl-mr-3"
+ data-testid="merge-request-ref"
+ >{{ mergeRequestRef.iid }}</gl-link
>
- <gl-badge variant="info" size="sm">
- {{ __('Auto DevOps') }}
- </gl-badge>
- </gl-link>
- <gl-popover :target="autoDevopsTagId" triggers="focus" placement="top">
- <template #title>
- <div class="gl-font-weight-normal gl-line-height-normal">
- <gl-sprintf
- :message="
- __(
- 'This pipeline makes use of a predefined CI/CD configuration enabled by %{strongStart}Auto DevOps.%{strongEnd}',
- )
- "
- >
- <template #strong="{ content }">
- <b>{{ content }}</b>
- </template>
- </gl-sprintf>
- </div>
- </template>
- <gl-link
- :href="autoDevopsHelpPath"
- data-testid="pipeline-url-autodevops-link"
- target="_blank"
- >
- {{ __('Learn more about Auto DevOps') }}
- </gl-link>
- </gl-popover>
- </template>
-
- <gl-badge
- v-if="pipeline.flags.stuck"
- variant="warning"
- size="sm"
- data-testid="pipeline-url-stuck"
- >{{ __('stuck') }}</gl-badge
- >
- <gl-badge
- v-if="pipeline.flags.detached_merge_request_pipeline"
- v-gl-tooltip
- :title="
- __(
- 'Merge request pipelines 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 merge request pipelines.',
- )
- "
- variant="info"
- size="sm"
- data-testid="pipeline-url-detached"
- >{{ __('detached') }}</gl-badge
- >
- <gl-badge
- v-if="isInFork"
+ <gl-link v-else :href="refUrl" class="ref-name gl-mr-3" data-testid="commit-ref-name">{{
+ commitRef.name
+ }}</gl-link>
+ </tooltip-on-truncate>
+ <gl-icon
v-gl-tooltip
- :title="__('Pipeline ran in fork of project')"
- variant="info"
- size="sm"
- data-testid="pipeline-url-fork"
- >{{ __('fork') }}</gl-badge
- >
+ name="commit"
+ class="commit-icon gl-mr-1"
+ :title="__('Commit')"
+ data-testid="commit-icon"
+ />
+ <gl-link :href="commitUrl" class="commit-sha mr-0" data-testid="commit-short-sha">{{
+ commitShortSha
+ }}</gl-link>
+ <!--End of commit row-->
</div>
+ <pipeline-labels :pipeline-schedule-url="pipelineScheduleUrl" :pipeline="pipeline" />
</div>
</template>
diff --git a/app/assets/javascripts/pipelines/components/pipelines_list/pipelines.vue b/app/assets/javascripts/pipelines/components/pipelines_list/pipelines.vue
index e7ff5449331..db9dc74863d 100644
--- a/app/assets/javascripts/pipelines/components/pipelines_list/pipelines.vue
+++ b/app/assets/javascripts/pipelines/components/pipelines_list/pipelines.vue
@@ -98,19 +98,24 @@ export default {
type: String,
required: true,
},
+ defaultBranchName: {
+ type: String,
+ required: false,
+ default: null,
+ },
params: {
type: Object,
required: true,
},
- codeQualityPagePath: {
+ ciRunnerSettingsPath: {
type: String,
required: false,
default: null,
},
- ciRunnerSettingsPath: {
- type: String,
+ anyRunnersAvailable: {
+ type: Boolean,
required: false,
- default: null,
+ default: true,
},
},
data() {
@@ -347,6 +352,7 @@ export default {
<pipelines-filtered-search
class="gl-display-flex gl-flex-grow-1 gl-mr-4"
:project-id="projectId"
+ :default-branch-name="defaultBranchName"
:params="validatedParams"
@filterPipelines="filterPipelines"
/>
@@ -380,8 +386,8 @@ export default {
v-else-if="stateToRender === $options.stateMap.emptyState"
:empty-state-svg-path="emptyStateSvgPath"
:can-set-ci="canCreatePipeline"
- :code-quality-page-path="codeQualityPagePath"
:ci-runner-settings-path="ciRunnerSettingsPath"
+ :any-runners-available="anyRunnersAvailable"
/>
<gl-empty-state
diff --git a/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_ci_templates.vue b/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_ci_templates.vue
index 83f6356f31a..d50229e47c4 100644
--- a/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_ci_templates.vue
+++ b/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_ci_templates.vue
@@ -1,8 +1,19 @@
<script>
-import { GlAvatar, GlButton, GlCard, GlSprintf } from '@gitlab/ui';
+import { GlAvatar, GlButton, GlCard, GlSprintf, GlIcon, GlLink } from '@gitlab/ui';
import { mergeUrlParams } from '~/lib/utils/url_utility';
-import { s__, sprintf } from '~/locale';
-import { STARTER_TEMPLATE_NAME } from '~/pipeline_editor/constants';
+import { sprintf } from '~/locale';
+import {
+ STARTER_TEMPLATE_NAME,
+ RUNNERS_AVAILABILITY_SECTION_EXPERIMENT_NAME,
+ RUNNERS_SETTINGS_LINK_CLICKED_EVENT,
+ RUNNERS_DOCUMENTATION_LINK_CLICKED_EVENT,
+ RUNNERS_SETTINGS_BUTTON_CLICKED_EVENT,
+ I18N,
+} from '~/pipeline_editor/constants';
+import { helpPagePath } from '~/helpers/help_page_helper';
+import GitlabExperiment from '~/experimentation/components/gitlab_experiment.vue';
+import ExperimentTracking from '~/experimentation/experiment_tracking';
+import { isExperimentVariant } from '~/experimentation/utils';
import Tracking from '~/tracking';
export default {
@@ -11,39 +22,37 @@ export default {
GlButton,
GlCard,
GlSprintf,
+ GlIcon,
+ GlLink,
+ GitlabExperiment,
},
mixins: [Tracking.mixin()],
STARTER_TEMPLATE_NAME,
- i18n: {
- cta: s__('Pipelines|Use template'),
- testTemplates: {
- title: s__('Pipelines|Use a sample CI/CD template'),
- subtitle: s__(
- 'Pipelines|Use a sample %{codeStart}.gitlab-ci.yml%{codeEnd} template file to explore how CI/CD works.',
- ),
- gettingStarted: {
- title: s__('Pipelines|Get started with GitLab CI/CD'),
- description: s__(
- 'Pipelines|Get familiar with GitLab CI/CD syntax by starting with a basic 3 stage CI/CD pipeline.',
- ),
- },
+ RUNNERS_AVAILABILITY_SECTION_EXPERIMENT_NAME,
+ RUNNERS_SETTINGS_LINK_CLICKED_EVENT,
+ RUNNERS_DOCUMENTATION_LINK_CLICKED_EVENT,
+ RUNNERS_SETTINGS_BUTTON_CLICKED_EVENT,
+ I18N,
+ inject: ['pipelineEditorPath', 'suggestedCiTemplates'],
+ props: {
+ ciRunnerSettingsPath: {
+ type: String,
+ required: false,
+ default: null,
},
- templates: {
- title: s__('Pipelines|Use a CI/CD template'),
- subtitle: s__(
- "Pipelines|Use a template based on your project's language or framework to get started with GitLab CI/CD.",
- ),
- description: s__('Pipelines|CI/CD template to test and deploy your %{name} project.'),
+ anyRunnersAvailable: {
+ type: Boolean,
+ required: false,
+ default: true,
},
},
- inject: ['pipelineEditorPath', 'suggestedCiTemplates'],
data() {
const templates = this.suggestedCiTemplates.map(({ name, logo }) => {
return {
name,
logo,
link: mergeUrlParams({ template: name }, this.pipelineEditorPath),
- description: sprintf(this.$options.i18n.templates.description, { name }),
+ description: sprintf(this.$options.I18N.templates.description, { name }),
};
});
@@ -53,39 +62,104 @@ export default {
{ template: STARTER_TEMPLATE_NAME },
this.pipelineEditorPath,
),
+ tracker: null,
};
},
+ computed: {
+ sharedRunnersHelpPagePath() {
+ return helpPagePath('ci/runners/runners_scope', { anchor: 'shared-runners' });
+ },
+ runnersAvailabilitySectionExperimentEnabled() {
+ return isExperimentVariant(RUNNERS_AVAILABILITY_SECTION_EXPERIMENT_NAME);
+ },
+ },
+ created() {
+ this.tracker = new ExperimentTracking(RUNNERS_AVAILABILITY_SECTION_EXPERIMENT_NAME);
+ },
methods: {
trackEvent(template) {
this.track('template_clicked', {
label: template,
});
},
+ trackExperimentEvent(action) {
+ this.tracker.event(action);
+ },
},
};
</script>
<template>
<div>
- <h2 class="gl-font-size-h2 gl-text-gray-900">{{ $options.i18n.testTemplates.title }}</h2>
- <p class="gl-text-gray-800 gl-mb-6">
- <gl-sprintf :message="$options.i18n.testTemplates.subtitle">
- <template #code="{ content }">
- <code>{{ content }}</code>
- </template>
- </gl-sprintf>
- </p>
+ <h2 class="gl-font-size-h2 gl-text-gray-900">{{ $options.I18N.title }}</h2>
- <div class="row gl-mb-8">
- <div class="col-12">
+ <gitlab-experiment :name="$options.RUNNERS_AVAILABILITY_SECTION_EXPERIMENT_NAME">
+ <template #candidate>
+ <div v-if="anyRunnersAvailable">
+ <h2 class="gl-font-base gl-text-gray-900">
+ <gl-icon name="check-circle-filled" class="gl-text-green-500 gl-mr-2" :size="12" />
+ {{ $options.I18N.runners.title }}
+ </h2>
+ <p class="gl-text-gray-800 gl-mb-6">
+ <gl-sprintf :message="$options.I18N.runners.subtitle">
+ <template #settingsLink="{ content }">
+ <gl-link
+ data-testid="settings-link"
+ :href="ciRunnerSettingsPath"
+ @click="trackExperimentEvent($options.RUNNERS_SETTINGS_LINK_CLICKED_EVENT)"
+ >{{ content }}</gl-link
+ >
+ </template>
+ <template #docsLink="{ content }">
+ <gl-link
+ data-testid="documentation-link"
+ :href="sharedRunnersHelpPagePath"
+ @click="trackExperimentEvent($options.RUNNERS_DOCUMENTATION_LINK_CLICKED_EVENT)"
+ >{{ content }}</gl-link
+ >
+ </template>
+ </gl-sprintf>
+ </p>
+ </div>
+
+ <div v-else>
+ <h2 class="gl-font-base gl-text-gray-900">
+ <gl-icon name="warning-solid" class="gl-text-red-600 gl-mr-2" :size="14" />
+ {{ $options.I18N.noRunners.title }}
+ </h2>
+ <p class="gl-text-gray-800 gl-mb-6">{{ $options.I18N.noRunners.subtitle }}</p>
+ <gl-button
+ data-testid="settings-button"
+ category="primary"
+ variant="confirm"
+ :href="ciRunnerSettingsPath"
+ @click="trackExperimentEvent($options.RUNNERS_SETTINGS_BUTTON_CLICKED_EVENT)"
+ >
+ {{ $options.I18N.noRunners.cta }}
+ </gl-button>
+ </div>
+ </template>
+ </gitlab-experiment>
+
+ <template v-if="!runnersAvailabilitySectionExperimentEnabled || anyRunnersAvailable">
+ <h2 class="gl-font-lg gl-text-gray-900">{{ $options.I18N.learnBasics.title }}</h2>
+ <p class="gl-text-gray-800 gl-mb-6">
+ <gl-sprintf :message="$options.I18N.learnBasics.subtitle">
+ <template #code="{ content }">
+ <code>{{ content }}</code>
+ </template>
+ </gl-sprintf>
+ </p>
+
+ <div class="gl-lg-w-25p gl-lg-pr-5 gl-mb-8">
<gl-card>
<div class="gl-flex-direction-row">
<div class="gl-py-5"><gl-emoji class="gl-font-size-h2-xl" data-name="wave" /></div>
<div class="gl-mb-3">
- <strong class="gl-text-gray-800 gl-mb-2">{{
- $options.i18n.testTemplates.gettingStarted.title
- }}</strong>
+ <strong class="gl-text-gray-800 gl-mb-2">
+ {{ $options.I18N.learnBasics.gettingStarted.title }}
+ </strong>
</div>
- <p class="gl-font-sm">{{ $options.i18n.testTemplates.gettingStarted.description }}</p>
+ <p class="gl-font-sm">{{ $options.I18N.learnBasics.gettingStarted.description }}</p>
</div>
<gl-button
@@ -95,51 +169,51 @@ export default {
data-testid="test-template-link"
@click="trackEvent($options.STARTER_TEMPLATE_NAME)"
>
- {{ $options.i18n.cta }}
+ {{ $options.I18N.learnBasics.gettingStarted.cta }}
</gl-button>
</gl-card>
</div>
- </div>
- <h2 class="gl-font-size-h2 gl-text-gray-900">{{ $options.i18n.templates.title }}</h2>
- <p class="gl-text-gray-800 gl-mb-6">{{ $options.i18n.templates.subtitle }}</p>
+ <h2 class="gl-font-lg gl-text-gray-900">{{ $options.I18N.templates.title }}</h2>
+ <p class="gl-text-gray-800 gl-mb-6">{{ $options.I18N.templates.subtitle }}</p>
- <ul class="gl-list-style-none gl-pl-0">
- <li v-for="template in templates" :key="template.name">
- <div
- class="gl-display-flex gl-align-items-center gl-justify-content-space-between gl-border-b-solid gl-border-b-1 gl-border-b-gray-100 gl-pb-3 gl-pt-3"
- >
- <div class="gl-display-flex gl-flex-direction-row gl-align-items-center">
- <gl-avatar
- :src="template.logo"
- :size="64"
- class="gl-mr-6 gl-bg-white dark-mode-override"
- shape="rect"
- :alt="template.name"
- data-testid="template-logo"
- />
- <div class="gl-flex-direction-row">
- <div class="gl-mb-3">
- <strong class="gl-text-gray-800" data-testid="template-name">{{
- template.name
- }}</strong>
+ <ul class="gl-list-style-none gl-pl-0">
+ <li v-for="template in templates" :key="template.name">
+ <div
+ class="gl-display-flex gl-align-items-center gl-justify-content-space-between gl-border-b-solid gl-border-b-1 gl-border-b-gray-100 gl-pb-3 gl-pt-3"
+ >
+ <div class="gl-display-flex gl-flex-direction-row gl-align-items-center">
+ <gl-avatar
+ :src="template.logo"
+ :size="48"
+ class="gl-mr-5 gl-bg-white dark-mode-override"
+ shape="rect"
+ :alt="template.name"
+ data-testid="template-logo"
+ />
+ <div class="gl-flex-direction-row">
+ <div class="gl-mb-3">
+ <strong class="gl-text-gray-800" data-testid="template-name">
+ {{ template.name }}
+ </strong>
+ </div>
+ <p class="gl-mb-0 gl-font-sm" data-testid="template-description">
+ {{ template.description }}
+ </p>
</div>
- <p class="gl-mb-0 gl-font-sm" data-testid="template-description">
- {{ template.description }}
- </p>
</div>
+ <gl-button
+ category="primary"
+ variant="confirm"
+ :href="template.link"
+ data-testid="template-link"
+ @click="trackEvent(template.name)"
+ >
+ {{ $options.I18N.templates.cta }}
+ </gl-button>
</div>
- <gl-button
- category="primary"
- variant="confirm"
- :href="template.link"
- data-testid="template-link"
- @click="trackEvent(template.name)"
- >
- {{ $options.i18n.cta }}
- </gl-button>
- </div>
- </li>
- </ul>
+ </li>
+ </ul>
+ </template>
</div>
</template>
diff --git a/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_commit.vue b/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_commit.vue
deleted file mode 100644
index cc676883c1d..00000000000
--- a/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_commit.vue
+++ /dev/null
@@ -1,85 +0,0 @@
-<script>
-import { CHILD_VIEW } from '~/pipelines/constants';
-import CommitComponent from '~/vue_shared/components/commit.vue';
-
-export default {
- components: {
- CommitComponent,
- },
- props: {
- pipeline: {
- type: Object,
- required: true,
- },
- viewType: {
- type: String,
- required: true,
- },
- },
- computed: {
- commitAuthor() {
- let commitAuthorInformation;
-
- if (!this.pipeline || !this.pipeline.commit) {
- return null;
- }
-
- // 1. person who is an author of a commit might be a GitLab user
- if (this.pipeline.commit.author) {
- // 2. if person who is an author of a commit is a GitLab user
- // they can have a GitLab avatar
- if (this.pipeline.commit.author.avatar_url) {
- commitAuthorInformation = this.pipeline.commit.author;
-
- // 3. If GitLab user does not have avatar, they might have a Gravatar
- } else if (this.pipeline.commit.author_gravatar_url) {
- commitAuthorInformation = {
- ...this.pipeline.commit.author,
- avatar_url: this.pipeline.commit.author_gravatar_url,
- };
- }
- // 4. If committer is not a GitLab User, they can have a Gravatar
- } else {
- commitAuthorInformation = {
- avatar_url: this.pipeline.commit.author_gravatar_url,
- path: `mailto:${this.pipeline.commit.author_email}`,
- username: this.pipeline.commit.author_name,
- };
- }
-
- return commitAuthorInformation;
- },
- commitTag() {
- return this.pipeline?.ref?.tag;
- },
- commitRef() {
- return this.pipeline?.ref;
- },
- commitUrl() {
- return this.pipeline?.commit?.commit_path;
- },
- commitShortSha() {
- return this.pipeline?.commit?.short_id;
- },
- commitTitle() {
- return this.pipeline?.commit?.title;
- },
- isChildView() {
- return this.viewType === CHILD_VIEW;
- },
- },
-};
-</script>
-
-<template>
- <commit-component
- :tag="commitTag"
- :commit-ref="commitRef"
- :commit-url="commitUrl"
- :merge-request-ref="pipeline.merge_request"
- :short-sha="commitShortSha"
- :title="commitTitle"
- :author="commitAuthor"
- :show-ref-info="!isChildView"
- />
-</template>
diff --git a/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_filtered_search.vue b/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_filtered_search.vue
index 2dfdaa0ea28..4d28545a035 100644
--- a/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_filtered_search.vue
+++ b/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_filtered_search.vue
@@ -24,6 +24,11 @@ export default {
type: String,
required: true,
},
+ defaultBranchName: {
+ type: String,
+ required: false,
+ default: null,
+ },
params: {
type: Object,
required: true,
@@ -57,6 +62,7 @@ export default {
token: PipelineBranchNameToken,
operators: OPERATOR_IS_ONLY,
projectId: this.projectId,
+ defaultBranchName: this.defaultBranchName,
disabled: this.selectedTypes.includes(this.$options.tagType),
},
{
diff --git a/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_status_badge.vue b/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_status_badge.vue
index 54901c2d13f..e765a8cd86c 100644
--- a/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_status_badge.vue
+++ b/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_status_badge.vue
@@ -1,18 +1,13 @@
<script>
-import CodeQualityWalkthrough from '~/code_quality_walkthrough/components/step.vue';
-import { PIPELINE_STATUSES } from '~/code_quality_walkthrough/constants';
import { CHILD_VIEW } from '~/pipelines/constants';
import CiBadge from '~/vue_shared/components/ci_badge_link.vue';
-import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import PipelinesTimeago from './time_ago.vue';
export default {
components: {
- CodeQualityWalkthrough,
CiBadge,
PipelinesTimeago,
},
- mixins: [glFeatureFlagsMixin()],
props: {
pipeline: {
type: Object,
@@ -30,23 +25,6 @@ export default {
isChildView() {
return this.viewType === CHILD_VIEW;
},
- shouldRenderCodeQualityWalkthrough() {
- return Object.values(PIPELINE_STATUSES).includes(this.pipelineStatus.group);
- },
- codeQualityStep() {
- const prefix = [PIPELINE_STATUSES.successWithWarnings, PIPELINE_STATUSES.failed].includes(
- this.pipelineStatus.group,
- )
- ? 'failed'
- : this.pipelineStatus.group;
- return `${prefix}_pipeline`;
- },
- codeQualityBuildPath() {
- return this.pipeline?.details?.code_quality_build_path;
- },
- rearrangePipelinesTable() {
- return this.glFeatures?.rearrangePipelinesTable;
- },
},
};
</script>
@@ -54,18 +32,12 @@ export default {
<template>
<div>
<ci-badge
- id="js-code-quality-walkthrough"
class="gl-mb-3"
:status="pipelineStatus"
:show-text="!isChildView"
:icon-classes="'gl-vertical-align-middle!'"
data-qa-selector="pipeline_commit_status"
/>
- <pipelines-timeago v-if="rearrangePipelinesTable" class="gl-mt-3" :pipeline="pipeline" />
- <code-quality-walkthrough
- v-if="shouldRenderCodeQualityWalkthrough"
- :step="codeQualityStep"
- :link="codeQualityBuildPath"
- />
+ <pipelines-timeago class="gl-mt-3" :pipeline="pipeline" />
</div>
</template>
diff --git a/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_table.vue b/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_table.vue
index 9919a18cb99..6f0e67e1ae0 100644
--- a/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_table.vue
+++ b/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_table.vue
@@ -1,16 +1,13 @@
<script>
import { GlTableLite, GlTooltipDirective } from '@gitlab/ui';
import { s__, __ } from '~/locale';
-import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import eventHub from '../../event_hub';
import PipelineMiniGraph from './pipeline_mini_graph.vue';
import PipelineOperations from './pipeline_operations.vue';
import PipelineStopModal from './pipeline_stop_modal.vue';
import PipelineTriggerer from './pipeline_triggerer.vue';
import PipelineUrl from './pipeline_url.vue';
-import PipelinesCommit from './pipelines_commit.vue';
import PipelinesStatusBadge from './pipelines_status_badge.vue';
-import PipelinesTimeago from './time_ago.vue';
const DEFAULT_TD_CLASS = 'gl-p-5!';
const HIDE_TD_ON_MOBILE = 'gl-display-none! gl-lg-display-table-cell!';
@@ -22,19 +19,57 @@ export default {
GlTableLite,
LinkedPipelinesMiniList: () =>
import('ee_component/vue_shared/components/linked_pipelines_mini_list.vue'),
- PipelinesCommit,
PipelineMiniGraph,
PipelineOperations,
PipelinesStatusBadge,
PipelineStopModal,
- PipelinesTimeago,
PipelineTriggerer,
PipelineUrl,
},
+ tableFields: [
+ {
+ key: 'status',
+ label: s__('Pipeline|Status'),
+ thClass: DEFAULT_TH_CLASSES,
+ columnClass: 'gl-w-15p',
+ tdClass: DEFAULT_TD_CLASS,
+ thAttr: { 'data-testid': 'status-th' },
+ },
+ {
+ key: 'pipeline',
+ label: __('Pipeline'),
+ thClass: DEFAULT_TH_CLASSES,
+ tdClass: `${DEFAULT_TD_CLASS}`,
+ columnClass: 'gl-w-30p',
+ thAttr: { 'data-testid': 'pipeline-th' },
+ },
+ {
+ key: 'triggerer',
+ label: s__('Pipeline|Triggerer'),
+ thClass: DEFAULT_TH_CLASSES,
+ tdClass: `${DEFAULT_TD_CLASS} ${HIDE_TD_ON_MOBILE}`,
+ columnClass: 'gl-w-10p',
+ thAttr: { 'data-testid': 'triggerer-th' },
+ },
+ {
+ key: 'stages',
+ label: s__('Pipeline|Stages'),
+ thClass: DEFAULT_TH_CLASSES,
+ tdClass: DEFAULT_TD_CLASS,
+ columnClass: 'gl-w-quarter',
+ thAttr: { 'data-testid': 'stages-th' },
+ },
+ {
+ key: 'actions',
+ thClass: DEFAULT_TH_CLASSES,
+ tdClass: DEFAULT_TD_CLASS,
+ columnClass: 'gl-w-15p',
+ thAttr: { 'data-testid': 'actions-th' },
+ },
+ ],
directives: {
GlTooltip: GlTooltipDirective,
},
- mixins: [glFeatureFlagMixin()],
props: {
pipelines: {
type: Array,
@@ -67,76 +102,6 @@ export default {
cancelingPipeline: null,
};
},
- computed: {
- tableFields() {
- const fields = [
- {
- key: 'status',
- label: s__('Pipeline|Status'),
- thClass: DEFAULT_TH_CLASSES,
- columnClass: this.rearrangePipelinesTable ? 'gl-w-15p' : 'gl-w-10p',
- tdClass: DEFAULT_TD_CLASS,
- thAttr: { 'data-testid': 'status-th' },
- },
- {
- key: 'pipeline',
- label: this.rearrangePipelinesTable ? __('Pipeline') : this.pipelineKeyOption.label,
- thClass: DEFAULT_TH_CLASSES,
- tdClass: this.rearrangePipelinesTable
- ? `${DEFAULT_TD_CLASS}`
- : `${DEFAULT_TD_CLASS} ${HIDE_TD_ON_MOBILE}`,
- columnClass: this.rearrangePipelinesTable ? 'gl-w-30p' : 'gl-w-10p',
- thAttr: { 'data-testid': 'pipeline-th' },
- },
- {
- key: 'triggerer',
- label: s__('Pipeline|Triggerer'),
- thClass: DEFAULT_TH_CLASSES,
- tdClass: `${DEFAULT_TD_CLASS} ${HIDE_TD_ON_MOBILE}`,
- columnClass: 'gl-w-10p',
- thAttr: { 'data-testid': 'triggerer-th' },
- },
- {
- key: 'commit',
- label: s__('Pipeline|Commit'),
- thClass: DEFAULT_TH_CLASSES,
- tdClass: DEFAULT_TD_CLASS,
- columnClass: 'gl-w-20p',
- thAttr: { 'data-testid': 'commit-th' },
- },
- {
- key: 'stages',
- label: s__('Pipeline|Stages'),
- thClass: DEFAULT_TH_CLASSES,
- tdClass: DEFAULT_TD_CLASS,
- columnClass: 'gl-w-quarter',
- thAttr: { 'data-testid': 'stages-th' },
- },
- {
- key: 'timeago',
- label: s__('Pipeline|Duration'),
- thClass: DEFAULT_TH_CLASSES,
- tdClass: DEFAULT_TD_CLASS,
- columnClass: this.rearrangePipelinesTable ? 'gl-w-5p' : 'gl-w-15p',
- thAttr: { 'data-testid': 'timeago-th' },
- },
- {
- key: 'actions',
- thClass: DEFAULT_TH_CLASSES,
- tdClass: DEFAULT_TD_CLASS,
- columnClass: 'gl-w-15p',
- thAttr: { 'data-testid': 'actions-th' },
- },
- ];
-
- return !this.rearrangePipelinesTable
- ? fields
- : fields.filter((field) => !['commit', 'timeago'].includes(field.key));
- },
- rearrangePipelinesTable() {
- return this.glFeatures?.rearrangePipelinesTable;
- },
- },
watch: {
pipelines() {
this.cancelingPipeline = null;
@@ -167,7 +132,7 @@ export default {
<template>
<div class="ci-table">
<gl-table-lite
- :fields="tableFields"
+ :fields="$options.tableFields"
:items="pipelines"
tbody-tr-class="commit"
:tbody-tr-attr="{ 'data-testid': 'pipeline-table-row' }"
@@ -192,7 +157,6 @@ export default {
:pipeline="item"
:pipeline-schedule-url="pipelineScheduleUrl"
:pipeline-key="pipelineKeyOption.key"
- :view-type="viewType"
/>
</template>
@@ -200,10 +164,6 @@ export default {
<pipeline-triggerer :pipeline="item" />
</template>
- <template #cell(commit)="{ item }">
- <pipelines-commit :pipeline="item" :view-type="viewType" />
- </template>
-
<template #cell(stages)="{ item }">
<div class="stage-cell">
<!-- This empty div should be removed, see https://gitlab.com/gitlab-org/gitlab/-/issues/323488 -->
@@ -229,10 +189,6 @@ export default {
</div>
</template>
- <template #cell(timeago)="{ item }">
- <pipelines-timeago :pipeline="item" />
- </template>
-
<template #cell(actions)="{ item }">
<pipeline-operations :pipeline="item" :canceling-pipeline="cancelingPipeline" />
</template>
diff --git a/app/assets/javascripts/pipelines/components/pipelines_list/time_ago.vue b/app/assets/javascripts/pipelines/components/pipelines_list/time_ago.vue
index c45e3f24567..cde963e4051 100644
--- a/app/assets/javascripts/pipelines/components/pipelines_list/time_ago.vue
+++ b/app/assets/javascripts/pipelines/components/pipelines_list/time_ago.vue
@@ -1,6 +1,5 @@
<script>
import { GlIcon, GlTooltipDirective } from '@gitlab/ui';
-import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import timeagoMixin from '~/vue_shared/mixins/timeago';
export default {
@@ -8,7 +7,7 @@ export default {
GlTooltip: GlTooltipDirective,
},
components: { GlIcon },
- mixins: [timeagoMixin, glFeatureFlagMixin()],
+ mixins: [timeagoMixin],
props: {
pipeline: {
type: Object,
@@ -54,14 +53,11 @@ export default {
showSkipped() {
return !this.duration && !this.finishedTime && this.skipped;
},
- shouldDisplayAsBlock() {
- return this.glFeatures?.rearrangePipelinesTable;
- },
},
};
</script>
<template>
- <div class="{ 'gl-display-block': shouldDisplayAsBlock }">
+ <div class="gl-display-block">
<span v-if="showInProgress" data-testid="pipeline-in-progress">
<gl-icon v-if="stuck" name="warning" class="gl-mr-2" :size="12" data-testid="warning-icon" />
<gl-icon
diff --git a/app/assets/javascripts/pipelines/components/pipelines_list/tokens/pipeline_branch_name_token.vue b/app/assets/javascripts/pipelines/components/pipelines_list/tokens/pipeline_branch_name_token.vue
index 5409e68cdc4..1db2898b72a 100644
--- a/app/assets/javascripts/pipelines/components/pipelines_list/tokens/pipeline_branch_name_token.vue
+++ b/app/assets/javascripts/pipelines/components/pipelines_list/tokens/pipeline_branch_name_token.vue
@@ -35,6 +35,13 @@ export default {
Api.branches(this.config.projectId, searchterm)
.then(({ data }) => {
this.branches = data.map((branch) => branch.name);
+ if (!searchterm && this.config.defaultBranchName) {
+ // Shift the default branch to the top of the list
+ this.branches = this.branches.filter(
+ (branch) => branch !== this.config.defaultBranchName,
+ );
+ this.branches.unshift(this.config.defaultBranchName);
+ }
this.loading = false;
})
.catch((err) => {
diff --git a/app/assets/javascripts/pipelines/pipeline_details_bundle.js b/app/assets/javascripts/pipelines/pipeline_details_bundle.js
index bfb95e5ab0c..801f71cb364 100644
--- a/app/assets/javascripts/pipelines/pipeline_details_bundle.js
+++ b/app/assets/javascripts/pipelines/pipeline_details_bundle.js
@@ -69,9 +69,7 @@ export default async function initPipelineDetailsBundle() {
}
try {
- if (gon.features?.jobsTabVue) {
- createPipelineJobsApp(SELECTORS.PIPELINE_JOBS);
- }
+ createPipelineJobsApp(SELECTORS.PIPELINE_JOBS);
} catch {
createFlash({
message: __('An error occurred while loading the Jobs tab.'),
diff --git a/app/assets/javascripts/pipelines/pipelines_index.js b/app/assets/javascripts/pipelines/pipelines_index.js
index c4c2b5f2927..f4d9a44a754 100644
--- a/app/assets/javascripts/pipelines/pipelines_index.js
+++ b/app/assets/javascripts/pipelines/pipelines_index.js
@@ -36,9 +36,10 @@ export const initPipelinesIndex = (selector = '#pipelines-list-vue') => {
ciLintPath,
resetCachePath,
projectId,
+ defaultBranchName,
params,
- codeQualityPagePath,
ciRunnerSettingsPath,
+ anyRunnersAvailable,
} = el.dataset;
return new Vue({
@@ -75,9 +76,10 @@ export const initPipelinesIndex = (selector = '#pipelines-list-vue') => {
ciLintPath,
resetCachePath,
projectId,
+ defaultBranchName,
params: JSON.parse(params),
- codeQualityPagePath,
ciRunnerSettingsPath,
+ anyRunnersAvailable: parseBoolean(anyRunnersAvailable),
},
});
},
diff --git a/app/assets/javascripts/profile/profile.js b/app/assets/javascripts/profile/profile.js
index ff9b47cdcd6..25fefff219c 100644
--- a/app/assets/javascripts/profile/profile.js
+++ b/app/assets/javascripts/profile/profile.js
@@ -1,5 +1,5 @@
import $ from 'jquery';
-import createFlash from '~/flash';
+import createFlash, { FLASH_TYPES } from '~/flash';
import axios from '~/lib/utils/axios_utils';
import { parseBoolean } from '~/lib/utils/common_utils';
import { Rails } from '~/lib/utils/rails_ujs';
@@ -86,7 +86,7 @@ export default class Profile {
createFlash({
message: data.message,
- type: 'notice',
+ type: data.status === 'error' ? FLASH_TYPES.ALERT : FLASH_TYPES.NOTICE,
});
})
.then(() => {
diff --git a/app/assets/javascripts/projects/pipelines/charts/index.js b/app/assets/javascripts/projects/pipelines/charts/index.js
index 94d32609e5d..28b77f6defd 100644
--- a/app/assets/javascripts/projects/pipelines/charts/index.js
+++ b/app/assets/javascripts/projects/pipelines/charts/index.js
@@ -11,7 +11,13 @@ const apolloProvider = new VueApollo({
});
const mountPipelineChartsApp = (el) => {
- const { projectPath, failedPipelinesLink, coverageChartPath, defaultBranch } = el.dataset;
+ const {
+ projectPath,
+ failedPipelinesLink,
+ coverageChartPath,
+ defaultBranch,
+ testRunsEmptyStateImagePath,
+ } = el.dataset;
const shouldRenderDoraCharts = parseBoolean(el.dataset.shouldRenderDoraCharts);
const shouldRenderQualitySummary = parseBoolean(el.dataset.shouldRenderQualitySummary);
@@ -30,6 +36,7 @@ const mountPipelineChartsApp = (el) => {
shouldRenderQualitySummary,
coverageChartPath,
defaultBranch,
+ testRunsEmptyStateImagePath,
},
render: (createElement) => createElement(ProjectPipelinesCharts, {}),
});
diff --git a/app/assets/javascripts/projects/project_new.js b/app/assets/javascripts/projects/project_new.js
index 62e2cec874a..f1b7e3df7d6 100644
--- a/app/assets/javascripts/projects/project_new.js
+++ b/app/assets/javascripts/projects/project_new.js
@@ -120,15 +120,6 @@ const bindHowToImport = () => {
});
});
});
-
- $('.how_to_import_link').on('click', (e) => {
- e.preventDefault();
- $(e.currentTarget).next('.modal').show();
- });
-
- $('.modal-header .close').on('click', () => {
- $('.modal').hide();
- });
};
const bindEvents = () => {
@@ -153,8 +144,8 @@ const bindEvents = () => {
bindHowToImport();
- $('.btn_import_gitlab_project').on('click', () => {
- const importHref = $('a.btn_import_gitlab_project').attr('href');
+ $('.btn_import_gitlab_project').on('click contextmenu', () => {
+ const importHref = $('a.btn_import_gitlab_project').attr('data-href');
$('.btn_import_gitlab_project').attr(
'href',
`${importHref}?namespace_id=${$(
diff --git a/app/assets/javascripts/protected_branches/protected_branch_create.js b/app/assets/javascripts/protected_branches/protected_branch_create.js
index d4b52860261..16eb5c3de32 100644
--- a/app/assets/javascripts/protected_branches/protected_branch_create.js
+++ b/app/assets/javascripts/protected_branches/protected_branch_create.js
@@ -5,6 +5,7 @@ import AccessorUtilities from '~/lib/utils/accessor';
import axios from '~/lib/utils/axios_utils';
import { __ } from '~/locale';
import AccessDropdown from '~/projects/settings/access_dropdown';
+import { initToggle } from '~/toggles';
import { ACCESS_LEVELS, LEVEL_TYPES } from './constants';
export default class ProtectedBranchCreate {
@@ -15,25 +16,18 @@ export default class ProtectedBranchCreate {
this.isLocalStorageAvailable = AccessorUtilities.canUseLocalStorage();
this.currentProjectUserDefaults = {};
this.buildDropdowns();
- this.$forcePushToggle = this.$form.find('.js-force-push-toggle');
- this.$codeOwnerToggle = this.$form.find('.js-code-owner-toggle');
- this.bindEvents();
- }
- bindEvents() {
- this.$forcePushToggle.on('click', this.onForcePushToggleClick.bind(this));
+ this.forcePushToggle = initToggle(document.querySelector('.js-force-push-toggle'));
+
if (this.hasLicense) {
- this.$codeOwnerToggle.on('click', this.onCodeOwnerToggleClick.bind(this));
+ this.codeOwnerToggle = initToggle(document.querySelector('.js-code-owner-toggle'));
}
- this.$form.on('submit', this.onFormSubmit.bind(this));
- }
- onForcePushToggleClick() {
- this.$forcePushToggle.toggleClass('is-checked');
+ this.bindEvents();
}
- onCodeOwnerToggleClick() {
- this.$codeOwnerToggle.toggleClass('is-checked');
+ bindEvents() {
+ this.$form.on('submit', this.onFormSubmit.bind(this));
}
buildDropdowns() {
@@ -92,8 +86,8 @@ export default class ProtectedBranchCreate {
authenticity_token: this.$form.find('input[name="authenticity_token"]').val(),
protected_branch: {
name: this.$form.find('input[name="protected_branch[name]"]').val(),
- allow_force_push: this.$forcePushToggle.hasClass('is-checked'),
- code_owner_approval_required: this.$codeOwnerToggle.hasClass('is-checked'),
+ allow_force_push: this.forcePushToggle.value,
+ code_owner_approval_required: this.codeOwnerToggle?.value ?? false,
},
};
diff --git a/app/assets/javascripts/protected_branches/protected_branch_edit.js b/app/assets/javascripts/protected_branches/protected_branch_edit.js
index 86273cfdda6..15e706e38c6 100644
--- a/app/assets/javascripts/protected_branches/protected_branch_edit.js
+++ b/app/assets/javascripts/protected_branches/protected_branch_edit.js
@@ -3,6 +3,7 @@ import createFlash from '~/flash';
import axios from '~/lib/utils/axios_utils';
import { __ } from '~/locale';
import AccessDropdown from '~/projects/settings/access_dropdown';
+import { initToggle } from '~/toggles';
import { ACCESS_LEVELS, LEVEL_TYPES } from './constants';
export default class ProtectedBranchEdit {
@@ -14,8 +15,6 @@ export default class ProtectedBranchEdit {
this.$wrap = options.$wrap;
this.$allowedToMergeDropdown = this.$wrap.find('.js-allowed-to-merge');
this.$allowedToPushDropdown = this.$wrap.find('.js-allowed-to-push');
- this.$forcePushToggle = this.$wrap.find('.js-force-push-toggle');
- this.$codeOwnerToggle = this.$wrap.find('.js-code-owner-toggle');
this.$wraps[ACCESS_LEVELS.MERGE] = this.$allowedToMergeDropdown.closest(
`.${ACCESS_LEVELS.MERGE}-container`,
@@ -25,36 +24,47 @@ export default class ProtectedBranchEdit {
);
this.buildDropdowns();
- this.bindEvents();
+ this.initToggles();
}
- bindEvents() {
- this.$forcePushToggle.on('click', this.onForcePushToggleClick.bind(this));
- if (this.hasLicense) {
- this.$codeOwnerToggle.on('click', this.onCodeOwnerToggleClick.bind(this));
+ initToggles() {
+ const wrap = this.$wrap.get(0);
+
+ const forcePushToggle = initToggle(wrap.querySelector('.js-force-push-toggle'));
+ if (forcePushToggle) {
+ forcePushToggle.$on('change', (value) => {
+ forcePushToggle.isLoading = true;
+ forcePushToggle.disabled = true;
+ this.updateProtectedBranch(
+ {
+ allow_force_push: value,
+ },
+ () => {
+ forcePushToggle.isLoading = false;
+ forcePushToggle.disabled = false;
+ },
+ );
+ });
}
- }
-
- onForcePushToggleClick() {
- this.$forcePushToggle.toggleClass('is-checked');
- this.$forcePushToggle.prop('disabled', true);
-
- const formData = {
- allow_force_push: this.$forcePushToggle.hasClass('is-checked'),
- };
-
- this.updateProtectedBranch(formData, () => this.$forcePushToggle.prop('disabled', false));
- }
- onCodeOwnerToggleClick() {
- this.$codeOwnerToggle.toggleClass('is-checked');
- this.$codeOwnerToggle.prop('disabled', true);
-
- const formData = {
- code_owner_approval_required: this.$codeOwnerToggle.hasClass('is-checked'),
- };
-
- this.updateProtectedBranch(formData, () => this.$codeOwnerToggle.prop('disabled', false));
+ if (this.hasLicense) {
+ const codeOwnerToggle = initToggle(wrap.querySelector('.js-code-owner-toggle'));
+ if (codeOwnerToggle) {
+ codeOwnerToggle.$on('change', (value) => {
+ codeOwnerToggle.isLoading = true;
+ codeOwnerToggle.disabled = true;
+ this.updateProtectedBranch(
+ {
+ code_owner_approval_required: value,
+ },
+ () => {
+ codeOwnerToggle.isLoading = false;
+ codeOwnerToggle.disabled = false;
+ },
+ );
+ });
+ }
+ }
}
updateProtectedBranch(formData, callback) {
diff --git a/app/assets/javascripts/ref/components/ref_selector.vue b/app/assets/javascripts/ref/components/ref_selector.vue
index ce781c64006..d02526160fd 100644
--- a/app/assets/javascripts/ref/components/ref_selector.vue
+++ b/app/assets/javascripts/ref/components/ref_selector.vue
@@ -58,6 +58,11 @@ export default {
required: false,
default: () => ({}),
},
+ useSymbolicRefNames: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
/** The validation state of this component. */
state: {
@@ -121,8 +126,15 @@ export default {
query: this.lastQuery,
};
},
+ selectedRefForDisplay() {
+ if (this.useSymbolicRefNames && this.selectedRef) {
+ return this.selectedRef.replace(/^refs\/(tags|heads)\//, '');
+ }
+
+ return this.selectedRef;
+ },
buttonText() {
- return this.selectedRef || this.i18n.noRefSelected;
+ return this.selectedRefForDisplay || this.i18n.noRefSelected;
},
},
watch: {
@@ -164,9 +176,20 @@ export default {
},
{ immediate: true },
);
+
+ this.$watch(
+ 'useSymbolicRefNames',
+ () => this.setUseSymbolicRefNames(this.useSymbolicRefNames),
+ { immediate: true },
+ );
},
methods: {
- ...mapActions(['setEnabledRefTypes', 'setProjectId', 'setSelectedRef']),
+ ...mapActions([
+ 'setEnabledRefTypes',
+ 'setUseSymbolicRefNames',
+ 'setProjectId',
+ 'setSelectedRef',
+ ]),
...mapActions({ storeSearch: 'search' }),
focusSearchBox() {
this.$refs.searchBox.$el.querySelector('input').focus();
diff --git a/app/assets/javascripts/ref/stores/actions.js b/app/assets/javascripts/ref/stores/actions.js
index 3832cc0c21d..a6019f21e73 100644
--- a/app/assets/javascripts/ref/stores/actions.js
+++ b/app/assets/javascripts/ref/stores/actions.js
@@ -5,6 +5,9 @@ import * as types from './mutation_types';
export const setEnabledRefTypes = ({ commit }, refTypes) =>
commit(types.SET_ENABLED_REF_TYPES, refTypes);
+export const setUseSymbolicRefNames = ({ commit }, useSymbolicRefNames) =>
+ commit(types.SET_USE_SYMBOLIC_REF_NAMES, useSymbolicRefNames);
+
export const setProjectId = ({ commit }, projectId) => commit(types.SET_PROJECT_ID, projectId);
export const setSelectedRef = ({ commit }, selectedRef) =>
diff --git a/app/assets/javascripts/ref/stores/mutation_types.js b/app/assets/javascripts/ref/stores/mutation_types.js
index c26f4fa00c7..4c602908cae 100644
--- a/app/assets/javascripts/ref/stores/mutation_types.js
+++ b/app/assets/javascripts/ref/stores/mutation_types.js
@@ -1,4 +1,5 @@
export const SET_ENABLED_REF_TYPES = 'SET_ENABLED_REF_TYPES';
+export const SET_USE_SYMBOLIC_REF_NAMES = 'SET_USE_SYMBOLIC_REF_NAMES';
export const SET_PROJECT_ID = 'SET_PROJECT_ID';
export const SET_SELECTED_REF = 'SET_SELECTED_REF';
diff --git a/app/assets/javascripts/ref/stores/mutations.js b/app/assets/javascripts/ref/stores/mutations.js
index f91cbae8462..e078d3333d4 100644
--- a/app/assets/javascripts/ref/stores/mutations.js
+++ b/app/assets/javascripts/ref/stores/mutations.js
@@ -7,6 +7,9 @@ export default {
[types.SET_ENABLED_REF_TYPES](state, refTypes) {
state.enabledRefTypes = refTypes;
},
+ [types.SET_USE_SYMBOLIC_REF_NAMES](state, useSymbolicRefNames) {
+ state.useSymbolicRefNames = useSymbolicRefNames;
+ },
[types.SET_PROJECT_ID](state, projectId) {
state.projectId = projectId;
},
@@ -28,6 +31,7 @@ export default {
state.matches.branches = {
list: convertObjectPropsToCamelCase(response.data).map((b) => ({
name: b.name,
+ value: state.useSymbolicRefNames ? `refs/heads/${b.name}` : undefined,
default: b.default,
})),
totalCount: parseInt(response.headers[X_TOTAL_HEADER], 10),
@@ -46,6 +50,7 @@ export default {
state.matches.tags = {
list: convertObjectPropsToCamelCase(response.data).map((b) => ({
name: b.name,
+ value: state.useSymbolicRefNames ? `refs/tags/${b.name}` : undefined,
})),
totalCount: parseInt(response.headers[X_TOTAL_HEADER], 10),
error: null,
diff --git a/app/assets/javascripts/related_issues/components/related_issues_block.vue b/app/assets/javascripts/related_issues/components/related_issues_block.vue
index bc97fab9ad2..eeb4c254a1b 100644
--- a/app/assets/javascripts/related_issues/components/related_issues_block.vue
+++ b/app/assets/javascripts/related_issues/components/related_issues_block.vue
@@ -85,6 +85,16 @@ export default {
required: false,
default: true,
},
+ autoCompleteEpics: {
+ type: Boolean,
+ required: false,
+ default: true,
+ },
+ autoCompleteIssues: {
+ type: Boolean,
+ required: false,
+ default: true,
+ },
},
computed: {
hasRelatedIssues() {
@@ -198,6 +208,8 @@ export default {
:input-value="inputValue"
:pending-references="pendingReferences"
:auto-complete-sources="autoCompleteSources"
+ :auto-complete-epics="autoCompleteEpics"
+ :auto-complete-issues="autoCompleteIssues"
:path-id-separator="pathIdSeparator"
@pendingIssuableRemoveRequest="$emit('pendingIssuableRemoveRequest', $event)"
@addIssuableFormInput="$emit('addIssuableFormInput', $event)"
@@ -210,6 +222,7 @@ export default {
<related-issues-list
v-for="category in categorisedIssues"
:key="category.linkType"
+ :list-link-type="category.linkType"
:heading="$options.linkedIssueTypesTextMap[category.linkType]"
:can-admin="canAdmin"
:can-reorder="canReorder"
diff --git a/app/assets/javascripts/related_issues/components/related_issues_list.vue b/app/assets/javascripts/related_issues/components/related_issues_list.vue
index 8b39851405e..174049b15fe 100644
--- a/app/assets/javascripts/related_issues/components/related_issues_list.vue
+++ b/app/assets/javascripts/related_issues/components/related_issues_list.vue
@@ -21,6 +21,11 @@ export default {
required: false,
default: false,
},
+ listLinkType: {
+ type: String,
+ required: false,
+ default: '',
+ },
heading: {
type: String,
required: false,
@@ -91,7 +96,7 @@ export default {
</script>
<template>
- <div>
+ <div :data-link-type="listLinkType">
<h4 v-if="heading" class="gl-font-base mt-0">{{ heading }}</h4>
<div
class="related-issues-token-body bordered-box bg-white"
diff --git a/app/assets/javascripts/related_issues/components/related_issues_root.vue b/app/assets/javascripts/related_issues/components/related_issues_root.vue
index 7e2fda8495c..40d58c04753 100644
--- a/app/assets/javascripts/related_issues/components/related_issues_root.vue
+++ b/app/assets/javascripts/related_issues/components/related_issues_root.vue
@@ -71,6 +71,16 @@ export default {
required: false,
default: true,
},
+ autoCompleteEpics: {
+ type: Boolean,
+ required: false,
+ default: true,
+ },
+ autoCompleteIssues: {
+ type: Boolean,
+ required: false,
+ default: true,
+ },
pathIdSeparator: {
type: String,
required: false,
@@ -241,6 +251,8 @@ export default {
:is-form-visible="isFormVisible"
:input-value="inputValue"
:auto-complete-sources="autoCompleteSources"
+ :auto-complete-epics="autoCompleteEpics"
+ :auto-complete-issues="autoCompleteIssues"
:issuable-type="issuableType"
:path-id-separator="pathIdSeparator"
:show-categorized-issues="showCategorizedIssues"
diff --git a/app/assets/javascripts/related_issues/index.js b/app/assets/javascripts/related_issues/index.js
index 35858be90b2..b61f1cf2470 100644
--- a/app/assets/javascripts/related_issues/index.js
+++ b/app/assets/javascripts/related_issues/index.js
@@ -21,6 +21,7 @@ export default function initRelatedIssues() {
showCategorizedIssues: parseBoolean(
relatedIssuesRootElement.dataset.showCategorizedIssues,
),
+ autoCompleteEpics: false,
},
}),
});
diff --git a/app/assets/javascripts/releases/components/app_index.vue b/app/assets/javascripts/releases/components/app_index.vue
index c2c91f406a1..e53bfea7389 100644
--- a/app/assets/javascripts/releases/components/app_index.vue
+++ b/app/assets/javascripts/releases/components/app_index.vue
@@ -68,7 +68,7 @@ export default {
:href="newReleasePath"
:aria-describedby="shouldRenderEmptyState && 'releases-description'"
category="primary"
- variant="success"
+ variant="confirm"
data-testid="new-release-button"
>
{{ __('New release') }}
diff --git a/app/assets/javascripts/releases/components/asset_links_form.vue b/app/assets/javascripts/releases/components/asset_links_form.vue
index b9601428850..b81da399a7b 100644
--- a/app/assets/javascripts/releases/components/asset_links_form.vue
+++ b/app/assets/javascripts/releases/components/asset_links_form.vue
@@ -56,6 +56,9 @@ export default {
hasDuplicateUrl(link) {
return Boolean(this.getLinkErrors(link).isDuplicate);
},
+ hasDuplicateName(link) {
+ return Boolean(this.getLinkErrors(link).isTitleDuplicate);
+ },
hasBadFormat(link) {
return Boolean(this.getLinkErrors(link).isBadFormat);
},
@@ -72,7 +75,7 @@ export default {
return !this.hasDuplicateUrl(link) && !this.hasBadFormat(link) && !this.hasEmptyUrl(link);
},
isNameValid(link) {
- return !this.hasEmptyName(link);
+ return !this.hasEmptyName(link) && !this.hasDuplicateName(link);
},
/**
@@ -121,7 +124,7 @@ export default {
<p>
{{
__(
- '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.',
+ 'Point to any links you like: documentation, built binaries, or other related materials. These can be internal or external links from your GitLab instance. Each URL and link title must be unique.',
)
}}
</p>
@@ -165,7 +168,7 @@ export default {
</gl-sprintf>
</span>
<span v-else-if="hasDuplicateUrl(link)" class="invalid-feedback d-inline">
- {{ __('This URL is already used for another link; duplicate URLs are not allowed') }}
+ {{ __('This URL already exists.') }}
</span>
</template>
</gl-form-group>
@@ -191,6 +194,9 @@ export default {
<span v-if="hasEmptyName(link)" class="invalid-feedback d-inline">
{{ __('Link title is required') }}
</span>
+ <span v-else-if="hasDuplicateName(link)" class="invalid-feedback d-inline">
+ {{ __('This title already exists.') }}
+ </span>
</template>
</gl-form-group>
diff --git a/app/assets/javascripts/releases/stores/modules/edit_new/actions.js b/app/assets/javascripts/releases/stores/modules/edit_new/actions.js
index 576f099248e..b3ba4f9263a 100644
--- a/app/assets/javascripts/releases/stores/modules/edit_new/actions.js
+++ b/app/assets/javascripts/releases/stores/modules/edit_new/actions.js
@@ -162,7 +162,7 @@ const createReleaseLink = async ({ state, link }) => {
input: {
projectPath: state.projectPath,
tagName: state.tagName,
- name: link.name,
+ name: link.name.trim(),
url: link.url,
linkType: link.linkType.toUpperCase(),
directAssetPath: link.directAssetPath,
diff --git a/app/assets/javascripts/releases/stores/modules/edit_new/getters.js b/app/assets/javascripts/releases/stores/modules/edit_new/getters.js
index d83ec05872a..d4f49e53619 100644
--- a/app/assets/javascripts/releases/stores/modules/edit_new/getters.js
+++ b/app/assets/javascripts/releases/stores/modules/edit_new/getters.js
@@ -1,5 +1,6 @@
import { isEmpty } from 'lodash';
import { hasContent } from '~/lib/utils/text_utility';
+import { getDuplicateItemsFromArray } from '~/lib/utils/array_utility';
/**
* @returns {Boolean} `true` if the app is editing an existing release.
@@ -95,6 +96,17 @@ export const validationErrors = (state) => {
}
});
+ // check for duplicated Link Titles
+ const linkTitles = state.release.assets.links.map((link) => link.name.trim());
+ const duplicatedTitles = getDuplicateItemsFromArray(linkTitles);
+
+ // add a validation error for each link that shares Link Title
+ state.release.assets.links.forEach((link) => {
+ if (hasContent(link.name) && duplicatedTitles.includes(link.name.trim())) {
+ errors.assets.links[link.id].isTitleDuplicate = true;
+ }
+ });
+
return errors;
};
@@ -131,7 +143,7 @@ export const releaseCreateMutatationVariables = (state, getters) => {
ref: state.createFrom,
assets: {
links: getters.releaseLinksToCreate.map(({ name, url, linkType }) => ({
- name,
+ name: name.trim(),
url,
linkType: linkType.toUpperCase(),
})),
diff --git a/app/assets/javascripts/reports/codequality_report/constants.js b/app/assets/javascripts/reports/codequality_report/constants.js
index 502977e714c..0c472b24471 100644
--- a/app/assets/javascripts/reports/codequality_report/constants.js
+++ b/app/assets/javascripts/reports/codequality_report/constants.js
@@ -15,3 +15,17 @@ export const SEVERITY_ICONS = {
blocker: 'severity-critical',
unknown: 'severity-unknown',
};
+
+// This is the icons mapping for the code Quality Merge-Request Widget Extension
+// once the refactor_mr_widgets_extensions flag is activated the above SEVERITY_ICONS
+// need be removed and this variable needs to be rename to SEVERITY_ICONS
+// Rollout Issue: https://gitlab.com/gitlab-org/gitlab/-/issues/341759
+
+export const SEVERITY_ICONS_EXTENSION = {
+ info: 'severityInfo',
+ minor: 'severityLow',
+ major: 'severityMedium',
+ critical: 'severityHigh',
+ blocker: 'severityCritical',
+ unknown: 'severityUnknown',
+};
diff --git a/app/assets/javascripts/reports/constants.js b/app/assets/javascripts/reports/constants.js
index 53273aeff33..bad6fa1e7b9 100644
--- a/app/assets/javascripts/reports/constants.js
+++ b/app/assets/javascripts/reports/constants.js
@@ -18,6 +18,7 @@ export const ICON_WARNING = 'warning';
export const ICON_SUCCESS = 'success';
export const ICON_NOTFOUND = 'notfound';
export const ICON_PENDING = 'pending';
+export const ICON_FAILED = 'failed';
export const status = {
LOADING,
diff --git a/app/assets/javascripts/repository/components/blob_button_group.vue b/app/assets/javascripts/repository/components/blob_button_group.vue
index 857795c71b0..d79ccde61a8 100644
--- a/app/assets/javascripts/repository/components/blob_button_group.vue
+++ b/app/assets/javascripts/repository/components/blob_button_group.vue
@@ -7,6 +7,8 @@ import getRefMixin from '../mixins/get_ref';
import DeleteBlobModal from './delete_blob_modal.vue';
import UploadBlobModal from './upload_blob_modal.vue';
+const REPLACE_BLOB_MODAL_ID = 'modal-replace-blob';
+
export default {
i18n: {
replace: __('Replace'),
@@ -76,9 +78,6 @@ export default {
},
},
computed: {
- replaceModalId() {
- return uniqueId('replace-modal');
- },
replaceModalTitle() {
return sprintf(__('Replace %{name}'), { name: this.name });
},
@@ -95,13 +94,14 @@ export default {
methods: {
showModal(modalId) {
if (this.showForkSuggestion) {
- this.$emit('fork');
+ this.$emit('fork', 'view');
return;
}
this.$refs[modalId].show();
},
},
+ replaceBlobModalId: REPLACE_BLOB_MODAL_ID,
};
</script>
@@ -118,7 +118,7 @@ export default {
data-testid="lock"
:data-qa-selector="lockBtnQASelector"
/>
- <gl-button data-testid="replace" @click="showModal(replaceModalId)">
+ <gl-button data-testid="replace" @click="showModal($options.replaceBlobModalId)">
{{ $options.i18n.replace }}
</gl-button>
<gl-button data-testid="delete" @click="showModal(deleteModalId)">
@@ -126,8 +126,8 @@ export default {
</gl-button>
</gl-button-group>
<upload-blob-modal
- :ref="replaceModalId"
- :modal-id="replaceModalId"
+ :ref="$options.replaceBlobModalId"
+ :modal-id="$options.replaceBlobModalId"
:modal-title="replaceModalTitle"
:commit-message="replaceModalTitle"
:target-branch="targetBranch || ref"
diff --git a/app/assets/javascripts/repository/components/blob_content_viewer.vue b/app/assets/javascripts/repository/components/blob_content_viewer.vue
index 52963b49f68..85652301f4d 100644
--- a/app/assets/javascripts/repository/components/blob_content_viewer.vue
+++ b/app/assets/javascripts/repository/components/blob_content_viewer.vue
@@ -10,11 +10,14 @@ import { isLoggedIn } from '~/lib/utils/common_utils';
import { __ } from '~/locale';
import { redirectTo } from '~/lib/utils/url_utility';
import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
+import WebIdeLink from '~/vue_shared/components/web_ide_link.vue';
+import CodeIntelligence from '~/code_navigation/components/app.vue';
import getRefMixin from '../mixins/get_ref';
import blobInfoQuery from '../queries/blob_info.query.graphql';
+import userInfoQuery from '../queries/user_info.query.graphql';
+import applicationInfoQuery from '../queries/application_info.query.graphql';
import { DEFAULT_BLOB_INFO, TEXT_FILE_TYPE, LFS_STORAGE } from '../constants';
import BlobButtonGroup from './blob_button_group.vue';
-import BlobEdit from './blob_edit.vue';
import ForkSuggestion from './fork_suggestion.vue';
import { loadViewer } from './blob_viewers';
@@ -24,12 +27,13 @@ export default {
},
components: {
BlobHeader,
- BlobEdit,
BlobButtonGroup,
BlobContent,
GlLoadingIcon,
GlButton,
ForkSuggestion,
+ WebIdeLink,
+ CodeIntelligence,
},
mixins: [getRefMixin, glFeatureFlagMixin()],
inject: {
@@ -38,6 +42,18 @@ export default {
},
},
apollo: {
+ gitpodEnabled: {
+ query: applicationInfoQuery,
+ error() {
+ this.displayError();
+ },
+ },
+ currentUser: {
+ query: userInfoQuery,
+ error() {
+ this.displayError();
+ },
+ },
project: {
query: blobInfoQuery,
variables() {
@@ -78,8 +94,11 @@ export default {
legacySimpleViewer: null,
isBinary: false,
isLoadingLegacyViewer: false,
+ isRenderingLegacyTextViewer: false,
activeViewerType: SIMPLE_BLOB_VIEWER,
- project: DEFAULT_BLOB_INFO,
+ project: DEFAULT_BLOB_INFO.project,
+ gitpodEnabled: DEFAULT_BLOB_INFO.gitpodEnabled,
+ currentUser: DEFAULT_BLOB_INFO.currentUser,
};
},
computed: {
@@ -142,9 +161,13 @@ export default {
return this.isLoggedIn && !canModifyBlob && createMergeRequestIn && forkProject;
},
forkPath() {
- return this.forkTarget === 'ide'
- ? this.blobInfo.ideForkAndEditPath
- : this.blobInfo.forkAndEditPath;
+ const forkPaths = {
+ ide: this.blobInfo.ideForkAndEditPath,
+ simple: this.blobInfo.forkAndEditPath,
+ view: this.blobInfo.forkAndViewPath,
+ };
+
+ return forkPaths[this.forkTarget];
},
isUsingLfs() {
return this.blobInfo.storedExternally && this.blobInfo.externalStorage === LFS_STORAGE;
@@ -163,7 +186,13 @@ export default {
.get(`${this.blobInfo.webPath}?format=json&viewer=${type}`)
.then(({ data: { html, binary } }) => {
if (type === SIMPLE_BLOB_VIEWER) {
+ this.isRenderingLegacyTextViewer = true;
+
this.legacySimpleViewer = html;
+
+ window.requestIdleCallback(() => {
+ this.isRenderingLegacyTextViewer = false;
+ });
} else {
this.legacyRichViewer = html;
}
@@ -213,26 +242,25 @@ export default {
@viewer-changed="switchViewer"
>
<template #actions>
- <blob-edit
+ <web-ide-link
v-if="!blobInfo.archived"
:show-edit-button="!isBinaryFileType"
- :edit-path="blobInfo.editBlobPath"
- :web-ide-path="blobInfo.ideEditPath"
+ class="gl-mr-3"
+ :edit-url="blobInfo.editBlobPath"
+ :web-ide-url="blobInfo.ideEditPath"
:needs-to-fork="showForkSuggestion"
+ :show-pipeline-editor-button="Boolean(blobInfo.pipelineEditorPath)"
+ :pipeline-editor-url="blobInfo.pipelineEditorPath"
+ :gitpod-url="blobInfo.gitpodBlobUrl"
+ :show-gitpod-button="gitpodEnabled"
+ :gitpod-enabled="currentUser && currentUser.gitpodEnabled"
+ :user-preferences-gitpod-path="currentUser && currentUser.preferencesGitpodPath"
+ :user-profile-enable-gitpod-path="currentUser && currentUser.profileEnableGitpodPath"
+ is-blob
+ disable-fork-modal
@edit="editBlob"
/>
- <gl-button
- v-if="blobInfo.pipelineEditorPath"
- class="gl-mr-3"
- category="secondary"
- variant="confirm"
- data-testid="pipeline-editor"
- :href="blobInfo.pipelineEditorPath"
- >
- {{ $options.i18n.pipelineEditor }}
- </gl-button>
-
<blob-button-group
v-if="isLoggedIn && !blobInfo.archived"
:path="path"
@@ -246,7 +274,7 @@ export default {
:is-locked="Boolean(pathLockedByUser)"
:can-lock="canLock"
:show-fork-suggestion="showForkSuggestion"
- @fork="setForkTarget('ide')"
+ @fork="setForkTarget('view')"
/>
</template>
</blob-header>
@@ -265,8 +293,15 @@ export default {
:active-viewer="viewer"
:hide-line-numbers="true"
:loading="isLoadingLegacyViewer"
+ :data-loading="isRenderingLegacyTextViewer"
/>
<component :is="blobViewer" v-else :blob="blobInfo" class="blob-viewer" />
+ <code-intelligence
+ v-if="blobViewer || legacyViewerLoaded"
+ :code-navigation-path="blobInfo.codeNavigationPath"
+ :blob-path="blobInfo.path"
+ :path-prefix="blobInfo.projectBlobPathRoot"
+ />
</div>
</div>
</template>
diff --git a/app/assets/javascripts/repository/components/blob_edit.vue b/app/assets/javascripts/repository/components/blob_edit.vue
deleted file mode 100644
index 69e2bd563c9..00000000000
--- a/app/assets/javascripts/repository/components/blob_edit.vue
+++ /dev/null
@@ -1,78 +0,0 @@
-<script>
-import { GlButton } from '@gitlab/ui';
-import { __ } from '~/locale';
-import WebIdeLink from '~/vue_shared/components/web_ide_link.vue';
-import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
-
-export default {
- i18n: {
- edit: __('Edit'),
- webIde: __('Web IDE'),
- },
- components: {
- GlButton,
- WebIdeLink,
- },
- mixins: [glFeatureFlagsMixin()],
- props: {
- showEditButton: {
- type: Boolean,
- required: true,
- },
- editPath: {
- type: String,
- required: true,
- },
- webIdePath: {
- type: String,
- required: true,
- },
- needsToFork: {
- type: Boolean,
- required: false,
- default: false,
- },
- },
- methods: {
- onEdit(target) {
- this.$emit('edit', target);
- },
- },
-};
-</script>
-
-<template>
- <web-ide-link
- v-if="glFeatures.consolidatedEditButton"
- :show-edit-button="showEditButton"
- class="gl-mr-3"
- :edit-url="editPath"
- :web-ide-url="webIdePath"
- :needs-to-fork="needsToFork"
- :is-blob="true"
- disable-fork-modal
- @edit="onEdit"
- />
- <div v-else>
- <gl-button
- v-if="showEditButton"
- class="gl-mr-2"
- category="primary"
- variant="confirm"
- data-testid="edit"
- @click="onEdit('simple')"
- >
- {{ $options.i18n.edit }}
- </gl-button>
-
- <gl-button
- class="gl-mr-3"
- category="primary"
- variant="confirm"
- data-testid="web-ide"
- @click="onEdit('ide')"
- >
- {{ $options.i18n.webIde }}
- </gl-button>
- </div>
-</template>
diff --git a/app/assets/javascripts/repository/components/blob_viewers/audio_viewer.vue b/app/assets/javascripts/repository/components/blob_viewers/audio_viewer.vue
new file mode 100644
index 00000000000..048730c02c1
--- /dev/null
+++ b/app/assets/javascripts/repository/components/blob_viewers/audio_viewer.vue
@@ -0,0 +1,20 @@
+<script>
+export default {
+ props: {
+ blob: {
+ type: Object,
+ required: true,
+ },
+ },
+ data() {
+ return {
+ src: this.blob.rawPath,
+ };
+ },
+};
+</script>
+<template>
+ <div class="gl-text-center gl-p-7">
+ <audio :src="src" controls data-testid="audio"></audio>
+ </div>
+</template>
diff --git a/app/assets/javascripts/repository/components/blob_viewers/csv_viewer.vue b/app/assets/javascripts/repository/components/blob_viewers/csv_viewer.vue
new file mode 100644
index 00000000000..86a0bb9fad0
--- /dev/null
+++ b/app/assets/javascripts/repository/components/blob_viewers/csv_viewer.vue
@@ -0,0 +1,26 @@
+<script>
+import CsvViewer from '~/blob/csv/csv_viewer.vue';
+
+export default {
+ components: {
+ CsvViewer,
+ },
+ props: {
+ blob: {
+ type: Object,
+ required: true,
+ },
+ },
+ data() {
+ return {
+ url: this.blob.rawPath,
+ };
+ },
+};
+</script>
+
+<template>
+ <div>
+ <csv-viewer :csv="url" remote-file data-testid="csv" />
+ </div>
+</template>
diff --git a/app/assets/javascripts/repository/components/blob_viewers/download_viewer.vue b/app/assets/javascripts/repository/components/blob_viewers/download_viewer.vue
index f7b318c64d9..be5e9685ccd 100644
--- a/app/assets/javascripts/repository/components/blob_viewers/download_viewer.vue
+++ b/app/assets/javascripts/repository/components/blob_viewers/download_viewer.vue
@@ -17,7 +17,7 @@ export default {
data() {
return {
fileName: this.blob.name,
- filePath: this.blob.rawPath,
+ filePath: this.blob.externalStorageUrl || this.blob.rawPath,
fileSize: this.blob.rawSize || 0,
};
},
diff --git a/app/assets/javascripts/repository/components/blob_viewers/image_viewer.vue b/app/assets/javascripts/repository/components/blob_viewers/image_viewer.vue
index 5027f7877aa..014f1abc121 100644
--- a/app/assets/javascripts/repository/components/blob_viewers/image_viewer.vue
+++ b/app/assets/javascripts/repository/components/blob_viewers/image_viewer.vue
@@ -16,6 +16,6 @@ export default {
</script>
<template>
<div class="gl-text-center gl-p-7 gl-bg-gray-50">
- <img :src="url" :alt="alt" data-testid="image" />
+ <img :src="url" :alt="alt" data-testid="image" class="gl-max-w-full" />
</div>
</template>
diff --git a/app/assets/javascripts/repository/components/blob_viewers/index.js b/app/assets/javascripts/repository/components/blob_viewers/index.js
index e942f59e7d8..cbe18ea396e 100644
--- a/app/assets/javascripts/repository/components/blob_viewers/index.js
+++ b/app/assets/javascripts/repository/components/blob_viewers/index.js
@@ -1,4 +1,5 @@
const viewers = {
+ csv: () => import('./csv_viewer.vue'),
download: () => import('./download_viewer.vue'),
image: () => import('./image_viewer.vue'),
video: () => import('./video_viewer.vue'),
@@ -6,6 +7,7 @@ const viewers = {
text: () => import('~/vue_shared/components/source_viewer/source_viewer.vue'),
pdf: () => import('./pdf_viewer.vue'),
lfs: () => import('./lfs_viewer.vue'),
+ audio: () => import('./audio_viewer.vue'),
};
export const loadViewer = (type, isUsingLfs) => {
diff --git a/app/assets/javascripts/repository/components/blob_viewers/lfs_viewer.vue b/app/assets/javascripts/repository/components/blob_viewers/lfs_viewer.vue
index 6dc7e10662e..9d39764e9a4 100644
--- a/app/assets/javascripts/repository/components/blob_viewers/lfs_viewer.vue
+++ b/app/assets/javascripts/repository/components/blob_viewers/lfs_viewer.vue
@@ -21,7 +21,7 @@ export default {
data() {
return {
fileName: this.blob.name,
- filePath: this.blob.rawPath,
+ filePath: this.blob.externalStorageUrl || this.blob.rawPath,
};
},
};
diff --git a/app/assets/javascripts/repository/components/blob_viewers/pdf_viewer.vue b/app/assets/javascripts/repository/components/blob_viewers/pdf_viewer.vue
index c3df5984426..37c8f636757 100644
--- a/app/assets/javascripts/repository/components/blob_viewers/pdf_viewer.vue
+++ b/app/assets/javascripts/repository/components/blob_viewers/pdf_viewer.vue
@@ -18,7 +18,7 @@ export default {
},
data() {
return {
- url: this.blob.rawPath,
+ url: this.blob.externalStorageUrl || this.blob.rawPath,
fileSize: this.blob.rawSize,
totalPages: 0,
};
diff --git a/app/assets/javascripts/repository/components/breadcrumbs.vue b/app/assets/javascripts/repository/components/breadcrumbs.vue
index d3717f10ec7..08faf19d12a 100644
--- a/app/assets/javascripts/repository/components/breadcrumbs.vue
+++ b/app/assets/javascripts/repository/components/breadcrumbs.vue
@@ -148,11 +148,16 @@ export default {
.reduce(
(acc, name, i) => {
const path = joinPaths(i > 0 ? acc[i].path : '', escapeFileUrl(name));
+ const isLastPath = i === this.currentPath.split('/').length - 1;
+ const to =
+ this.isBlobPath && isLastPath
+ ? `/-/blob/${joinPaths(this.escapedRef, path)}`
+ : `/-/tree/${joinPaths(this.escapedRef, path)}`;
return acc.concat({
name,
path,
- to: `/-/tree/${joinPaths(this.escapedRef, path)}`,
+ to,
});
},
[
@@ -274,9 +279,11 @@ export default {
return items;
},
+ isBlobPath() {
+ return this.$route.name === 'blobPath' || this.$route.name === 'blobPathDecoded';
+ },
renderAddToTreeDropdown() {
- const isBlobPath = this.$route.name === 'blobPath' || this.$route.name === 'blobPathDecoded';
- return !isBlobPath && (this.canCollaborate || this.canCreateMrFromFork);
+ return !this.isBlobPath && (this.canCollaborate || this.canCreateMrFromFork);
},
},
methods: {
diff --git a/app/assets/javascripts/repository/components/delete_blob_modal.vue b/app/assets/javascripts/repository/components/delete_blob_modal.vue
index f3c9aea36f1..baf8449b188 100644
--- a/app/assets/javascripts/repository/components/delete_blob_modal.vue
+++ b/app/assets/javascripts/repository/components/delete_blob_modal.vue
@@ -87,7 +87,7 @@ export default {
fields: {
// fields key must match case of form name for validation directive to work
commit_message: initFormField({ value: this.commitMessage }),
- branch_name: initFormField({ value: this.targetBranch }),
+ branch_name: initFormField({ value: this.targetBranch, skipValidation: !this.canPushCode }),
},
};
return {
diff --git a/app/assets/javascripts/repository/constants.js b/app/assets/javascripts/repository/constants.js
index e206d9bfbd2..bb9d3180be8 100644
--- a/app/assets/javascripts/repository/constants.js
+++ b/app/assets/javascripts/repository/constants.js
@@ -27,6 +27,12 @@ export const PDF_MAX_PAGE_LIMIT = 50;
export const ROW_APPEAR_DELAY = 150;
export const DEFAULT_BLOB_INFO = {
+ gitpodEnabled: false,
+ currentUser: {
+ gitpodEnabled: false,
+ preferencesGitpodPath: null,
+ profileEnableGitpodPath: null,
+ },
userPermissions: {
pushCode: false,
downloadCode: false,
@@ -49,9 +55,13 @@ export const DEFAULT_BLOB_INFO = {
tooLarge: false,
path: '',
editBlobPath: '',
+ gitpodBlobUrl: '',
ideEditPath: '',
forkAndEditPath: '',
ideForkAndEditPath: '',
+ codeNavigationPath: '',
+ projectBlobPathRoot: '',
+ forkAndViewPath: '',
storedExternally: false,
externalStorage: '',
environmentFormattedExternalUrl: '',
diff --git a/app/assets/javascripts/repository/index.js b/app/assets/javascripts/repository/index.js
index 120c32caefd..b38a1cfdc7b 100644
--- a/app/assets/javascripts/repository/index.js
+++ b/app/assets/javascripts/repository/index.js
@@ -1,10 +1,12 @@
import { GlButton } from '@gitlab/ui';
import Vue from 'vue';
+import Vuex from 'vuex';
import { parseBoolean } from '~/lib/utils/common_utils';
import { escapeFileUrl } from '~/lib/utils/url_utility';
import { __ } from '~/locale';
import initWebIdeLink from '~/pages/projects/shared/web_ide_link';
import PerformancePlugin from '~/performance/vue_performance_plugin';
+import createStore from '~/code_navigation/store';
import App from './components/app.vue';
import Breadcrumbs from './components/breadcrumbs.vue';
import DirectoryDownloadLinks from './components/directory_download_links.vue';
@@ -19,6 +21,7 @@ import createRouter from './router';
import { updateFormAction } from './utils/dom';
import { setTitle } from './utils/title';
+Vue.use(Vuex);
Vue.use(PerformancePlugin, {
components: ['SimpleViewer', 'BlobContent'],
});
@@ -200,6 +203,7 @@ export default function setupVueRepositoryList() {
// eslint-disable-next-line no-new
new Vue({
el,
+ store: createStore(),
router,
apolloProvider,
render(h) {
diff --git a/app/assets/javascripts/repository/queries/application_info.query.graphql b/app/assets/javascripts/repository/queries/application_info.query.graphql
new file mode 100644
index 00000000000..fd69de39f75
--- /dev/null
+++ b/app/assets/javascripts/repository/queries/application_info.query.graphql
@@ -0,0 +1,3 @@
+query getApplicationInfo {
+ gitpodEnabled
+}
diff --git a/app/assets/javascripts/repository/queries/blob_info.query.graphql b/app/assets/javascripts/repository/queries/blob_info.query.graphql
index 78323fdc5f4..8baee80e5d6 100644
--- a/app/assets/javascripts/repository/queries/blob_info.query.graphql
+++ b/app/assets/javascripts/repository/queries/blob_info.query.graphql
@@ -28,9 +28,13 @@ query getBlobInfo(
language
path
editBlobPath
+ gitpodBlobUrl
ideEditPath
forkAndEditPath
ideForkAndEditPath
+ codeNavigationPath
+ projectBlobPathRoot
+ forkAndViewPath
environmentFormattedExternalUrl
environmentExternalUrlForRouteMap
canModifyBlob
diff --git a/app/assets/javascripts/repository/queries/user_info.query.graphql b/app/assets/javascripts/repository/queries/user_info.query.graphql
new file mode 100644
index 00000000000..114947a423d
--- /dev/null
+++ b/app/assets/javascripts/repository/queries/user_info.query.graphql
@@ -0,0 +1,8 @@
+query getUserInfo {
+ currentUser {
+ id
+ gitpodEnabled
+ preferencesGitpodPath
+ profileEnableGitpodPath
+ }
+}
diff --git a/app/assets/javascripts/runner/admin_runner_edit/admin_runner_edit_app.vue b/app/assets/javascripts/runner/admin_runner_edit/admin_runner_edit_app.vue
index 4d2ca9b0c58..c2db3b9facd 100644
--- a/app/assets/javascripts/runner/admin_runner_edit/admin_runner_edit_app.vue
+++ b/app/assets/javascripts/runner/admin_runner_edit/admin_runner_edit_app.vue
@@ -5,7 +5,7 @@ import { convertToGraphQLId } from '~/graphql_shared/utils';
import RunnerHeader from '../components/runner_header.vue';
import RunnerUpdateForm from '../components/runner_update_form.vue';
import { I18N_FETCH_ERROR } from '../constants';
-import getRunnerQuery from '../graphql/get_runner.query.graphql';
+import runnerQuery from '../graphql/details/runner.query.graphql';
import { captureException } from '../sentry_utils';
export default {
@@ -27,7 +27,7 @@ export default {
},
apollo: {
runner: {
- query: getRunnerQuery,
+ query: runnerQuery,
variables() {
return {
id: convertToGraphQLId(TYPE_CI_RUNNER, this.runnerId),
diff --git a/app/assets/javascripts/runner/admin_runner_show/admin_runner_show_app.vue b/app/assets/javascripts/runner/admin_runner_show/admin_runner_show_app.vue
index 2795ddbbbcb..86ad912f017 100644
--- a/app/assets/javascripts/runner/admin_runner_show/admin_runner_show_app.vue
+++ b/app/assets/javascripts/runner/admin_runner_show/admin_runner_show_app.vue
@@ -8,7 +8,7 @@ import RunnerPauseButton from '../components/runner_pause_button.vue';
import RunnerHeader from '../components/runner_header.vue';
import RunnerDetails from '../components/runner_details.vue';
import { I18N_FETCH_ERROR } from '../constants';
-import getRunnerQuery from '../graphql/get_runner.query.graphql';
+import runnerQuery from '../graphql/details/runner.query.graphql';
import { captureException } from '../sentry_utils';
export default {
@@ -35,7 +35,7 @@ export default {
},
apollo: {
runner: {
- query: getRunnerQuery,
+ query: runnerQuery,
variables() {
return {
id: convertToGraphQLId(TYPE_CI_RUNNER, this.runnerId),
diff --git a/app/assets/javascripts/runner/admin_runners/admin_runners_app.vue b/app/assets/javascripts/runner/admin_runners/admin_runners_app.vue
index a968d4029f8..8aba91eedf7 100644
--- a/app/assets/javascripts/runner/admin_runners/admin_runners_app.vue
+++ b/app/assets/javascripts/runner/admin_runners/admin_runners_app.vue
@@ -12,6 +12,7 @@ import RunnerName from '../components/runner_name.vue';
import RunnerStats from '../components/stat/runner_stats.vue';
import RunnerPagination from '../components/runner_pagination.vue';
import RunnerTypeTabs from '../components/runner_type_tabs.vue';
+import RunnerActionsCell from '../components/cells/runner_actions_cell.vue';
import { statusTokenConfig } from '../components/search_tokens/status_token_config';
import { tagTokenConfig } from '../components/search_tokens/tag_token_config';
@@ -25,8 +26,8 @@ import {
STATUS_STALE,
I18N_FETCH_ERROR,
} from '../constants';
-import getRunnersQuery from '../graphql/get_runners.query.graphql';
-import getRunnersCountQuery from '../graphql/get_runners_count.query.graphql';
+import runnersAdminQuery from '../graphql/list/admin_runners.query.graphql';
+import runnersAdminCountQuery from '../graphql/list/admin_runners_count.query.graphql';
import {
fromUrlQueryToSearch,
fromSearchToUrl,
@@ -35,7 +36,7 @@ import {
import { captureException } from '../sentry_utils';
const runnersCountSmartQuery = {
- query: getRunnersCountQuery,
+ query: runnersAdminCountQuery,
fetchPolicy: fetchPolicies.CACHE_AND_NETWORK,
update(data) {
return data?.runners?.count;
@@ -57,6 +58,7 @@ export default {
RunnerStats,
RunnerPagination,
RunnerTypeTabs,
+ RunnerActionsCell,
},
props: {
registrationToken: {
@@ -75,7 +77,7 @@ export default {
},
apollo: {
runners: {
- query: getRunnersQuery,
+ query: runnersAdminQuery,
// Runners can be updated by users directly in this list.
// A "cache and network" policy prevents outdated filtered
// results.
@@ -187,6 +189,7 @@ export default {
deep: true,
handler() {
// TODO Implement back button response using onpopstate
+ // See: https://gitlab.com/gitlab-org/gitlab/-/issues/333804
updateHistory({
url: fromSearchToUrl(this.search),
title: document.title,
@@ -221,6 +224,10 @@ export default {
}
return '';
},
+ onDeleted({ message }) {
+ this.$root.$toast?.show(message);
+ this.$apollo.queries.runners.refetch();
+ },
reportToSentry(error) {
captureException({ error, component: this.$options.name });
},
@@ -278,6 +285,13 @@ export default {
<runner-name :runner="runner" />
</gl-link>
</template>
+ <template #runner-actions-cell="{ runner }">
+ <runner-actions-cell
+ :runner="runner"
+ :edit-url="runner.editAdminUrl"
+ @deleted="onDeleted"
+ />
+ </template>
</runner-list>
<runner-pagination
v-model="search.pagination"
diff --git a/app/assets/javascripts/runner/components/cells/runner_actions_cell.vue b/app/assets/javascripts/runner/components/cells/runner_actions_cell.vue
index ae9c774f2a2..c69321de001 100644
--- a/app/assets/javascripts/runner/components/cells/runner_actions_cell.vue
+++ b/app/assets/javascripts/runner/components/cells/runner_actions_cell.vue
@@ -1,60 +1,30 @@
<script>
-import { GlButton, GlButtonGroup, GlModalDirective, GlTooltipDirective } from '@gitlab/ui';
-import { createAlert } from '~/flash';
-import { s__, sprintf } from '~/locale';
-import runnerDeleteMutation from '~/runner/graphql/runner_delete.mutation.graphql';
-import { captureException } from '~/runner/sentry_utils';
-import { getIdFromGraphQLId } from '~/graphql_shared/utils';
+import { GlButtonGroup } from '@gitlab/ui';
import RunnerEditButton from '../runner_edit_button.vue';
import RunnerPauseButton from '../runner_pause_button.vue';
-import RunnerDeleteModal from '../runner_delete_modal.vue';
-
-const I18N_DELETE = s__('Runners|Delete runner');
-const I18N_DELETED_TOAST = s__('Runners|Runner %{name} was deleted');
+import RunnerDeleteButton from '../runner_delete_button.vue';
export default {
name: 'RunnerActionsCell',
components: {
- GlButton,
GlButtonGroup,
RunnerEditButton,
RunnerPauseButton,
- RunnerDeleteModal,
- },
- directives: {
- GlTooltip: GlTooltipDirective,
- GlModal: GlModalDirective,
+ RunnerDeleteButton,
},
props: {
runner: {
type: Object,
required: true,
},
+ editUrl: {
+ type: String,
+ default: null,
+ required: false,
+ },
},
- data() {
- return {
- updating: false,
- deleting: false,
- };
- },
+ emits: ['deleted'],
computed: {
- deleteTitle() {
- if (this.deleting) {
- // Prevent a "sticky" tooltip: If this button is disabled,
- // mouseout listeners don't run leaving the tooltip stuck
- return '';
- }
- return I18N_DELETE;
- },
- runnerId() {
- return getIdFromGraphQLId(this.runner.id);
- },
- runnerName() {
- return `#${this.runnerId} (${this.runner.shortSha})`;
- },
- runnerDeleteModalId() {
- return `delete-runner-modal-${this.runnerId}`;
- },
canUpdate() {
return this.runner.userPermissions?.updateRunner;
},
@@ -63,79 +33,17 @@ export default {
},
},
methods: {
- async onDelete() {
- // Deleting stays "true" until this row is removed,
- // should only change back if the operation fails.
- this.deleting = true;
- try {
- const {
- data: {
- runnerDelete: { errors },
- },
- } = await this.$apollo.mutate({
- mutation: runnerDeleteMutation,
- variables: {
- input: {
- id: this.runner.id,
- },
- },
- awaitRefetchQueries: true,
- refetchQueries: ['getRunners', 'getGroupRunners'],
- });
- if (errors && errors.length) {
- throw new Error(errors.join(' '));
- } else {
- // Use $root to have the toast message stay after this element is removed
- this.$root.$toast?.show(sprintf(I18N_DELETED_TOAST, { name: this.runnerName }));
- }
- } catch (e) {
- this.deleting = false;
- this.onError(e);
- }
- },
-
- onError(error) {
- const { message } = error;
- createAlert({ message });
-
- this.reportToSentry(error);
- },
- reportToSentry(error) {
- captureException({ error, component: this.$options.name });
+ onDeleted(value) {
+ this.$emit('deleted', value);
},
},
- I18N_DELETE,
};
</script>
<template>
<gl-button-group>
- <!--
- This button appears for administrators: those with
- access to the adminUrl. More advanced permissions policies
- will allow more granular permissions.
-
- See https://gitlab.com/gitlab-org/gitlab/-/issues/334802
- -->
- <runner-edit-button v-if="canUpdate && runner.editAdminUrl" :href="runner.editAdminUrl" />
+ <runner-edit-button v-if="canUpdate && editUrl" :href="editUrl" />
<runner-pause-button v-if="canUpdate" :runner="runner" :compact="true" />
- <gl-button
- v-if="canDelete"
- v-gl-tooltip.hover.viewport="deleteTitle"
- v-gl-modal="runnerDeleteModalId"
- :aria-label="deleteTitle"
- icon="close"
- :loading="deleting"
- variant="danger"
- data-testid="delete-runner"
- />
-
- <runner-delete-modal
- v-if="canDelete"
- :ref="runnerDeleteModalId"
- :modal-id="runnerDeleteModalId"
- :runner-name="runnerName"
- @primary="onDelete"
- />
+ <runner-delete-button v-if="canDelete" :runner="runner" :compact="true" @deleted="onDeleted" />
</gl-button-group>
</template>
diff --git a/app/assets/javascripts/runner/components/registration/registration_token_reset_dropdown_item.vue b/app/assets/javascripts/runner/components/registration/registration_token_reset_dropdown_item.vue
index 54c35e483dc..1234054c660 100644
--- a/app/assets/javascripts/runner/components/registration/registration_token_reset_dropdown_item.vue
+++ b/app/assets/javascripts/runner/components/registration/registration_token_reset_dropdown_item.vue
@@ -4,7 +4,7 @@ import { createAlert } from '~/flash';
import { TYPE_GROUP, TYPE_PROJECT } from '~/graphql_shared/constants';
import { convertToGraphQLId } from '~/graphql_shared/utils';
import { __, s__ } from '~/locale';
-import runnersRegistrationTokenResetMutation from '~/runner/graphql/runners_registration_token_reset.mutation.graphql';
+import runnersRegistrationTokenResetMutation from '~/runner/graphql/list/runners_registration_token_reset.mutation.graphql';
import { captureException } from '~/runner/sentry_utils';
import { INSTANCE_TYPE, GROUP_TYPE, PROJECT_TYPE } from '../../constants';
@@ -98,17 +98,14 @@ export default {
},
onError(error) {
const { message } = error;
- createAlert({ message });
- this.reportToSentry(error);
+ createAlert({ message });
+ captureException({ error, component: this.$options.name });
},
onSuccess(token) {
this.$toast?.show(s__('Runners|New registration token generated!'));
this.$emit('tokenReset', token);
},
- reportToSentry(error) {
- captureException({ error, component: this.$options.name });
- },
},
};
</script>
diff --git a/app/assets/javascripts/runner/components/runner_delete_button.vue b/app/assets/javascripts/runner/components/runner_delete_button.vue
new file mode 100644
index 00000000000..854c983f4da
--- /dev/null
+++ b/app/assets/javascripts/runner/components/runner_delete_button.vue
@@ -0,0 +1,144 @@
+<script>
+import { GlButton, GlModalDirective, GlTooltipDirective } from '@gitlab/ui';
+import runnerDeleteMutation from '~/runner/graphql/shared/runner_delete.mutation.graphql';
+import { createAlert } from '~/flash';
+import { sprintf } from '~/locale';
+import { captureException } from '~/runner/sentry_utils';
+import { getIdFromGraphQLId } from '~/graphql_shared/utils';
+import { I18N_DELETE_RUNNER, I18N_DELETED_TOAST } from '../constants';
+import RunnerDeleteModal from './runner_delete_modal.vue';
+
+export default {
+ name: 'RunnerDeleteButton',
+ components: {
+ GlButton,
+ RunnerDeleteModal,
+ },
+ directives: {
+ GlTooltip: GlTooltipDirective,
+ GlModal: GlModalDirective,
+ },
+ props: {
+ runner: {
+ type: Object,
+ required: true,
+ validator: (runner) => {
+ return runner?.id && runner?.shortSha;
+ },
+ },
+ compact: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
+ },
+ emits: ['deleted'],
+ data() {
+ return {
+ deleting: false,
+ };
+ },
+ computed: {
+ runnerId() {
+ return getIdFromGraphQLId(this.runner.id);
+ },
+ runnerName() {
+ return `#${this.runnerId} (${this.runner.shortSha})`;
+ },
+ runnerDeleteModalId() {
+ return `delete-runner-modal-${this.runnerId}`;
+ },
+ icon() {
+ if (this.compact) {
+ return 'close';
+ }
+ return '';
+ },
+ buttonContent() {
+ if (this.compact) {
+ return null;
+ }
+ return I18N_DELETE_RUNNER;
+ },
+ buttonClass() {
+ // Ensure a square button is shown when compact: true.
+ // Without this class we will have distorted/rectangular button.
+ if (this.compact) {
+ return 'btn-icon';
+ }
+ return null;
+ },
+ ariaLabel() {
+ if (this.compact) {
+ return I18N_DELETE_RUNNER;
+ }
+ return null;
+ },
+ tooltip() {
+ // Only show tooltip when compact.
+ // Also prevent a "sticky" tooltip: If this button is
+ // disabled, mouseout listeners don't run leaving the tooltip stuck
+ if (this.compact && !this.deleting) {
+ return I18N_DELETE_RUNNER;
+ }
+ return '';
+ },
+ },
+ methods: {
+ async onDelete() {
+ // Deleting stays "true" until this row is removed,
+ // should only change back if the operation fails.
+ this.deleting = true;
+ try {
+ const {
+ data: {
+ runnerDelete: { errors },
+ },
+ } = await this.$apollo.mutate({
+ mutation: runnerDeleteMutation,
+ variables: {
+ input: {
+ id: this.runner.id,
+ },
+ },
+ });
+ if (errors && errors.length) {
+ throw new Error(errors.join(' '));
+ } else {
+ this.$emit('deleted', {
+ message: sprintf(I18N_DELETED_TOAST, { name: this.runnerName }),
+ });
+ }
+ } catch (e) {
+ this.deleting = false;
+ this.onError(e);
+ }
+ },
+ onError(error) {
+ const { message } = error;
+
+ createAlert({ message });
+ captureException({ error, component: this.$options.name });
+ },
+ },
+};
+</script>
+
+<template>
+ <gl-button
+ v-gl-tooltip.hover.viewport="tooltip"
+ v-gl-modal="runnerDeleteModalId"
+ :aria-label="ariaLabel"
+ :icon="icon"
+ :class="buttonClass"
+ :loading="deleting"
+ variant="danger"
+ >
+ {{ buttonContent }}
+ <runner-delete-modal
+ :modal-id="runnerDeleteModalId"
+ :runner-name="runnerName"
+ @primary="onDelete"
+ />
+ </gl-button>
+</template>
diff --git a/app/assets/javascripts/runner/components/runner_edit_button.vue b/app/assets/javascripts/runner/components/runner_edit_button.vue
index b115be09e69..33e0acaf5c0 100644
--- a/app/assets/javascripts/runner/components/runner_edit_button.vue
+++ b/app/assets/javascripts/runner/components/runner_edit_button.vue
@@ -1,8 +1,6 @@
<script>
import { GlButton, GlTooltipDirective } from '@gitlab/ui';
-import { __ } from '~/locale';
-
-const I18N_EDIT = __('Edit');
+import { I18N_EDIT } from '../constants';
export default {
components: {
diff --git a/app/assets/javascripts/runner/components/runner_jobs.vue b/app/assets/javascripts/runner/components/runner_jobs.vue
index c13e7e90168..eb77babcc57 100644
--- a/app/assets/javascripts/runner/components/runner_jobs.vue
+++ b/app/assets/javascripts/runner/components/runner_jobs.vue
@@ -1,7 +1,7 @@
<script>
import { GlSkeletonLoading } from '@gitlab/ui';
import { createAlert } from '~/flash';
-import getRunnerJobsQuery from '../graphql/get_runner_jobs.query.graphql';
+import runnerJobsQuery from '../graphql/details/runner_jobs.query.graphql';
import { I18N_FETCH_ERROR, I18N_NO_JOBS_FOUND, RUNNER_DETAILS_JOBS_PAGE_SIZE } from '../constants';
import { captureException } from '../sentry_utils';
import { getPaginationVariables } from '../utils';
@@ -34,7 +34,7 @@ export default {
},
apollo: {
jobs: {
- query: getRunnerJobsQuery,
+ query: runnerJobsQuery,
variables() {
return this.variables;
},
@@ -46,7 +46,7 @@ export default {
},
error(error) {
createAlert({ message: I18N_FETCH_ERROR });
- this.reportToSentry(error);
+ captureException({ error, component: this.$options.name });
},
},
},
@@ -62,11 +62,6 @@ export default {
return this.$apollo.queries.jobs.loading;
},
},
- methods: {
- reportToSentry(error) {
- captureException({ error, component: this.$options.name });
- },
- },
I18N_NO_JOBS_FOUND,
};
</script>
diff --git a/app/assets/javascripts/runner/components/runner_list.vue b/app/assets/javascripts/runner/components/runner_list.vue
index bb36882d3ae..51749b0255f 100644
--- a/app/assets/javascripts/runner/components/runner_list.vue
+++ b/app/assets/javascripts/runner/components/runner_list.vue
@@ -1,22 +1,20 @@
<script>
-import { GlTable, GlTooltipDirective, GlSkeletonLoader } from '@gitlab/ui';
+import { GlTableLite, GlTooltipDirective, GlSkeletonLoader } from '@gitlab/ui';
import TooltipOnTruncate from '~/vue_shared/components/tooltip_on_truncate/tooltip_on_truncate.vue';
import { getIdFromGraphQLId } from '~/graphql_shared/utils';
import { __, s__ } from '~/locale';
import TimeAgo from '~/vue_shared/components/time_ago_tooltip.vue';
import { formatJobCount, tableField } from '../utils';
-import RunnerActionsCell from './cells/runner_actions_cell.vue';
import RunnerSummaryCell from './cells/runner_summary_cell.vue';
import RunnerStatusCell from './cells/runner_status_cell.vue';
import RunnerTags from './runner_tags.vue';
export default {
components: {
- GlTable,
+ GlTableLite,
GlSkeletonLoader,
TooltipOnTruncate,
TimeAgo,
- RunnerActionsCell,
RunnerSummaryCell,
RunnerTags,
RunnerStatusCell,
@@ -35,6 +33,16 @@ export default {
required: true,
},
},
+ computed: {
+ tableClass() {
+ // <gl-table-lite> does not provide a busy state, add
+ // simple support for it.
+ // See http://bootstrap-vue.org/docs/components/table#table-busy-state
+ return {
+ 'gl-opacity-6': this.loading,
+ };
+ },
+ },
methods: {
formatJobCount(jobCount) {
return formatJobCount(jobCount);
@@ -62,8 +70,9 @@ export default {
</script>
<template>
<div>
- <gl-table
- :busy="loading"
+ <gl-table-lite
+ :aria-busy="loading"
+ :class="tableClass"
:items="runners"
:fields="$options.fields"
:tbody-tr-attr="runnerTrAttr"
@@ -72,10 +81,6 @@ export default {
primary-key="id"
fixed
>
- <template v-if="!runners.length" #table-busy>
- <gl-skeleton-loader v-for="i in 4" :key="i" />
- </template>
-
<template #cell(status)="{ item }">
<runner-status-cell :runner="item" />
</template>
@@ -114,8 +119,12 @@ export default {
</template>
<template #cell(actions)="{ item }">
- <runner-actions-cell :runner="item" />
+ <slot name="runner-actions-cell" :runner="item"></slot>
</template>
- </gl-table>
+ </gl-table-lite>
+
+ <template v-if="!runners.length && loading">
+ <gl-skeleton-loader v-for="i in 4" :key="i" />
+ </template>
</div>
</template>
diff --git a/app/assets/javascripts/runner/components/runner_pause_button.vue b/app/assets/javascripts/runner/components/runner_pause_button.vue
index a8b259f5b90..c88634bfbd9 100644
--- a/app/assets/javascripts/runner/components/runner_pause_button.vue
+++ b/app/assets/javascripts/runner/components/runner_pause_button.vue
@@ -1,9 +1,9 @@
<script>
import { GlButton, GlTooltipDirective } from '@gitlab/ui';
-import runnerToggleActiveMutation from '~/runner/graphql/runner_toggle_active.mutation.graphql';
+import runnerToggleActiveMutation from '~/runner/graphql/shared/runner_toggle_active.mutation.graphql';
import { createAlert } from '~/flash';
import { captureException } from '~/runner/sentry_utils';
-import { I18N_PAUSE, I18N_RESUME } from '../constants';
+import { I18N_PAUSE, I18N_PAUSE_TOOLTIP, I18N_RESUME, I18N_RESUME_TOOLTIP } from '../constants';
export default {
name: 'RunnerPauseButton',
@@ -52,11 +52,10 @@ export default {
return null;
},
tooltip() {
- // Only show tooltip when compact.
- // Also prevent a "sticky" tooltip: If this button is
- // disabled, mouseout listeners don't run leaving the tooltip stuck
- if (this.compact && !this.updating) {
- return this.label;
+ // Prevent a "sticky" tooltip: If this button is disabled,
+ // mouseout listeners don't run leaving the tooltip stuck
+ if (!this.updating) {
+ return this.isActive ? I18N_PAUSE_TOOLTIP : I18N_RESUME_TOOLTIP;
}
return '';
},
@@ -92,11 +91,8 @@ export default {
},
onError(error) {
const { message } = error;
- createAlert({ message });
- this.reportToSentry(error);
- },
- reportToSentry(error) {
+ createAlert({ message });
captureException({ error, component: this.$options.name });
},
},
@@ -105,7 +101,7 @@ export default {
<template>
<gl-button
- v-gl-tooltip.hover.viewport="tooltip"
+ v-gl-tooltip="tooltip"
v-bind="$attrs"
:aria-label="ariaLabel"
:icon="icon"
diff --git a/app/assets/javascripts/runner/components/runner_paused_badge.vue b/app/assets/javascripts/runner/components/runner_paused_badge.vue
index d1e6fa05e4d..27618290ce6 100644
--- a/app/assets/javascripts/runner/components/runner_paused_badge.vue
+++ b/app/assets/javascripts/runner/components/runner_paused_badge.vue
@@ -1,6 +1,6 @@
<script>
import { GlBadge, GlTooltipDirective } from '@gitlab/ui';
-import { I18N_PAUSED_RUNNER_DESCRIPTION } from '../constants';
+import { I18N_PAUSED_DESCRIPTION } from '../constants';
export default {
components: {
@@ -9,17 +9,11 @@ export default {
directives: {
GlTooltip: GlTooltipDirective,
},
- i18n: {
- I18N_PAUSED_RUNNER_DESCRIPTION,
- },
+ I18N_PAUSED_DESCRIPTION,
};
</script>
<template>
- <gl-badge
- v-gl-tooltip="$options.i18n.I18N_PAUSED_RUNNER_DESCRIPTION"
- variant="danger"
- v-bind="$attrs"
- >
+ <gl-badge v-gl-tooltip="$options.I18N_PAUSED_DESCRIPTION" variant="danger" v-bind="$attrs">
{{ s__('Runners|paused') }}
</gl-badge>
</template>
diff --git a/app/assets/javascripts/runner/components/runner_projects.vue b/app/assets/javascripts/runner/components/runner_projects.vue
index c4065a24ff2..f8ec29b8a24 100644
--- a/app/assets/javascripts/runner/components/runner_projects.vue
+++ b/app/assets/javascripts/runner/components/runner_projects.vue
@@ -2,7 +2,7 @@
import { GlSkeletonLoading } from '@gitlab/ui';
import { sprintf, formatNumber } from '~/locale';
import { createAlert } from '~/flash';
-import getRunnerProjectsQuery from '../graphql/get_runner_projects.query.graphql';
+import runnerProjectsQuery from '../graphql/details/runner_projects.query.graphql';
import {
I18N_ASSIGNED_PROJECTS,
I18N_NONE,
@@ -41,7 +41,7 @@ export default {
},
apollo: {
projects: {
- query: getRunnerProjectsQuery,
+ query: runnerProjectsQuery,
variables() {
return this.variables;
},
@@ -55,8 +55,7 @@ export default {
},
error(error) {
createAlert({ message: I18N_FETCH_ERROR });
-
- this.reportToSentry(error);
+ captureException({ error, component: this.$options.name });
},
},
},
@@ -77,11 +76,6 @@ export default {
});
},
},
- methods: {
- reportToSentry(error) {
- captureException({ error, component: this.$options.name });
- },
- },
I18N_NONE,
};
</script>
diff --git a/app/assets/javascripts/runner/components/runner_update_form.vue b/app/assets/javascripts/runner/components/runner_update_form.vue
index e3deb94236e..e44450a2a8d 100644
--- a/app/assets/javascripts/runner/components/runner_update_form.vue
+++ b/app/assets/javascripts/runner/components/runner_update_form.vue
@@ -15,7 +15,7 @@ import { createAlert, VARIANT_SUCCESS } from '~/flash';
import { __ } from '~/locale';
import { captureException } from '~/runner/sentry_utils';
import { ACCESS_LEVEL_NOT_PROTECTED, ACCESS_LEVEL_REF_PROTECTED, PROJECT_TYPE } from '../constants';
-import runnerUpdateMutation from '../graphql/runner_update.mutation.graphql';
+import runnerUpdateMutation from '../graphql/details/runner_update.mutation.graphql';
export default {
name: 'RunnerUpdateForm',
@@ -82,9 +82,9 @@ export default {
this.onSuccess();
} catch (error) {
const { message } = error;
- createAlert({ message });
- this.reportToSentry(error);
+ createAlert({ message });
+ captureException({ error, component: this.$options.name });
} finally {
this.saving = false;
}
@@ -93,9 +93,6 @@ export default {
createAlert({ message: __('Changes saved.'), variant: VARIANT_SUCCESS });
this.model = runnerToModel(this.runner);
},
- reportToSentry(error) {
- captureException({ error, component: this.$options.name });
- },
},
ACCESS_LEVEL_NOT_PROTECTED,
ACCESS_LEVEL_REF_PROTECTED,
diff --git a/app/assets/javascripts/runner/constants.js b/app/assets/javascripts/runner/constants.js
index 1544efaaae2..bd5be2175ad 100644
--- a/app/assets/javascripts/runner/constants.js
+++ b/app/assets/javascripts/runner/constants.js
@@ -35,12 +35,20 @@ export const I18N_STALE_RUNNER_DESCRIPTION = s__(
'Runners|No contact from this runner in over 3 months',
);
-// Active flag
+// Actions
+export const I18N_EDIT = __('Edit');
+
export const I18N_PAUSE = __('Pause');
+export const I18N_PAUSE_TOOLTIP = s__('Runners|Pause from accepting jobs');
+export const I18N_PAUSED_DESCRIPTION = s__('Runners|Not accepting jobs');
+
export const I18N_RESUME = __('Resume');
+export const I18N_RESUME_TOOLTIP = s__('Runners|Resume accepting jobs');
+
+export const I18N_DELETE_RUNNER = s__('Runners|Delete runner');
+export const I18N_DELETED_TOAST = s__('Runners|Runner %{name} was deleted');
export const I18N_LOCKED_RUNNER_DESCRIPTION = s__('Runners|You cannot assign to other projects');
-export const I18N_PAUSED_RUNNER_DESCRIPTION = s__('Runners|Not available to run jobs');
// Runner details
@@ -91,8 +99,8 @@ export const ACCESS_LEVEL_REF_PROTECTED = 'REF_PROTECTED';
// CiRunnerSort
export const CREATED_DESC = 'CREATED_DESC';
-export const CREATED_ASC = 'CREATED_ASC'; // TODO Add this to the API
-export const CONTACTED_DESC = 'CONTACTED_DESC'; // TODO Add this to the API
+export const CREATED_ASC = 'CREATED_ASC';
+export const CONTACTED_DESC = 'CONTACTED_DESC';
export const CONTACTED_ASC = 'CONTACTED_ASC';
export const DEFAULT_SORT = CREATED_DESC;
diff --git a/app/assets/javascripts/runner/graphql/details/runner.query.graphql b/app/assets/javascripts/runner/graphql/details/runner.query.graphql
new file mode 100644
index 00000000000..4792a186160
--- /dev/null
+++ b/app/assets/javascripts/runner/graphql/details/runner.query.graphql
@@ -0,0 +1,9 @@
+#import "ee_else_ce/runner/graphql/details/runner_details.fragment.graphql"
+
+query getRunner($id: CiRunnerID!) {
+ # We have an id in deeply nested fragment
+ # eslint-disable-next-line @graphql-eslint/require-id-when-available
+ runner(id: $id) {
+ ...RunnerDetails
+ }
+}
diff --git a/app/assets/javascripts/runner/graphql/runner_details.fragment.graphql b/app/assets/javascripts/runner/graphql/details/runner_details.fragment.graphql
index 2449ee0fc0f..2449ee0fc0f 100644
--- a/app/assets/javascripts/runner/graphql/runner_details.fragment.graphql
+++ b/app/assets/javascripts/runner/graphql/details/runner_details.fragment.graphql
diff --git a/app/assets/javascripts/runner/graphql/details/runner_details_shared.fragment.graphql b/app/assets/javascripts/runner/graphql/details/runner_details_shared.fragment.graphql
new file mode 100644
index 00000000000..d8c67728fac
--- /dev/null
+++ b/app/assets/javascripts/runner/graphql/details/runner_details_shared.fragment.graphql
@@ -0,0 +1,35 @@
+fragment RunnerDetailsShared on CiRunner {
+ __typename
+ id
+ runnerType
+ active
+ accessLevel
+ runUntagged
+ locked
+ ipAddress
+ description
+ maximumTimeout
+ jobCount
+ tagList
+ createdAt
+ status(legacyMode: null)
+ contactedAt
+ version
+ editAdminUrl
+ userPermissions {
+ updateRunner
+ deleteRunner
+ }
+ groups {
+ # Only a single group can be loaded here, while projects
+ # are loaded separately using the query with pagination
+ # parameters `runner_projects.query.graphql`.
+ nodes {
+ id
+ avatarUrl
+ name
+ fullName
+ webUrl
+ }
+ }
+}
diff --git a/app/assets/javascripts/runner/graphql/get_runner_jobs.query.graphql b/app/assets/javascripts/runner/graphql/details/runner_jobs.query.graphql
index 2b1decd3ddd..2b1decd3ddd 100644
--- a/app/assets/javascripts/runner/graphql/get_runner_jobs.query.graphql
+++ b/app/assets/javascripts/runner/graphql/details/runner_jobs.query.graphql
diff --git a/app/assets/javascripts/runner/graphql/get_runner_projects.query.graphql b/app/assets/javascripts/runner/graphql/details/runner_projects.query.graphql
index f97237b8267..f97237b8267 100644
--- a/app/assets/javascripts/runner/graphql/get_runner_projects.query.graphql
+++ b/app/assets/javascripts/runner/graphql/details/runner_projects.query.graphql
diff --git a/app/assets/javascripts/runner/graphql/details/runner_update.mutation.graphql b/app/assets/javascripts/runner/graphql/details/runner_update.mutation.graphql
new file mode 100644
index 00000000000..e4bf51e2c30
--- /dev/null
+++ b/app/assets/javascripts/runner/graphql/details/runner_update.mutation.graphql
@@ -0,0 +1,15 @@
+#import "ee_else_ce/runner/graphql/details/runner_details.fragment.graphql"
+
+# Mutation for updates from the runner form, loads
+# attributes shown in the runner details.
+
+mutation runnerUpdate($input: RunnerUpdateInput!) {
+ runnerUpdate(input: $input) {
+ # We have an id in deep nested fragment
+ # eslint-disable-next-line @graphql-eslint/require-id-when-available
+ runner {
+ ...RunnerDetails
+ }
+ errors
+ }
+}
diff --git a/app/assets/javascripts/runner/graphql/get_group_runners.query.graphql b/app/assets/javascripts/runner/graphql/get_group_runners.query.graphql
deleted file mode 100644
index 986dd16b992..00000000000
--- a/app/assets/javascripts/runner/graphql/get_group_runners.query.graphql
+++ /dev/null
@@ -1,41 +0,0 @@
-#import "~/runner/graphql/runner_node.fragment.graphql"
-#import "~/graphql_shared/fragments/pageInfo.fragment.graphql"
-
-query getGroupRunners(
- $groupFullPath: ID!
- $before: String
- $after: String
- $first: Int
- $last: Int
- $status: CiRunnerStatus
- $type: CiRunnerType
- $search: String
- $sort: CiRunnerSort
-) {
- group(fullPath: $groupFullPath) {
- id # Apollo required
- runners(
- membership: DESCENDANTS
- before: $before
- after: $after
- first: $first
- last: $last
- status: $status
- type: $type
- search: $search
- sort: $sort
- ) {
- edges {
- webUrl
- node {
- __typename
- ...RunnerNode
- }
- }
- pageInfo {
- __typename
- ...PageInfo
- }
- }
- }
-}
diff --git a/app/assets/javascripts/runner/graphql/get_runner.query.graphql b/app/assets/javascripts/runner/graphql/get_runner.query.graphql
deleted file mode 100644
index f6ce8281c64..00000000000
--- a/app/assets/javascripts/runner/graphql/get_runner.query.graphql
+++ /dev/null
@@ -1,10 +0,0 @@
-#import "ee_else_ce/runner/graphql/runner_details.fragment.graphql"
-
-query getRunner($id: CiRunnerID!) {
- # We have an id in deeply nested fragment
- # eslint-disable-next-line @graphql-eslint/require-id-when-available
- runner(id: $id) {
- __typename
- ...RunnerDetails
- }
-}
diff --git a/app/assets/javascripts/runner/graphql/get_runners.query.graphql b/app/assets/javascripts/runner/graphql/get_runners.query.graphql
deleted file mode 100644
index ed03a8c34ae..00000000000
--- a/app/assets/javascripts/runner/graphql/get_runners.query.graphql
+++ /dev/null
@@ -1,36 +0,0 @@
-#import "~/runner/graphql/runner_node.fragment.graphql"
-#import "~/graphql_shared/fragments/pageInfo.fragment.graphql"
-
-query getRunners(
- $before: String
- $after: String
- $first: Int
- $last: Int
- $status: CiRunnerStatus
- $type: CiRunnerType
- $tagList: [String!]
- $search: String
- $sort: CiRunnerSort
-) {
- runners(
- before: $before
- after: $after
- first: $first
- last: $last
- status: $status
- type: $type
- tagList: $tagList
- search: $search
- sort: $sort
- ) {
- nodes {
- ...RunnerNode
- adminUrl
- editAdminUrl
- }
- pageInfo {
- __typename
- ...PageInfo
- }
- }
-}
diff --git a/app/assets/javascripts/runner/graphql/list/admin_runners.query.graphql b/app/assets/javascripts/runner/graphql/list/admin_runners.query.graphql
new file mode 100644
index 00000000000..8df4c2fc65c
--- /dev/null
+++ b/app/assets/javascripts/runner/graphql/list/admin_runners.query.graphql
@@ -0,0 +1,36 @@
+#import "~/runner/graphql/list/list_item.fragment.graphql"
+#import "~/graphql_shared/fragments/pageInfo.fragment.graphql"
+
+query getRunners(
+ $before: String
+ $after: String
+ $first: Int
+ $last: Int
+ $status: CiRunnerStatus
+ $type: CiRunnerType
+ $tagList: [String!]
+ $search: String
+ $sort: CiRunnerSort
+) {
+ runners(
+ before: $before
+ after: $after
+ first: $first
+ last: $last
+ status: $status
+ type: $type
+ tagList: $tagList
+ search: $search
+ sort: $sort
+ ) {
+ nodes {
+ ...ListItem
+ adminUrl
+ editAdminUrl
+ }
+ pageInfo {
+ __typename
+ ...PageInfo
+ }
+ }
+}
diff --git a/app/assets/javascripts/runner/graphql/get_runners_count.query.graphql b/app/assets/javascripts/runner/graphql/list/admin_runners_count.query.graphql
index 181a4495cae..181a4495cae 100644
--- a/app/assets/javascripts/runner/graphql/get_runners_count.query.graphql
+++ b/app/assets/javascripts/runner/graphql/list/admin_runners_count.query.graphql
diff --git a/app/assets/javascripts/runner/graphql/list/group_runners.query.graphql b/app/assets/javascripts/runner/graphql/list/group_runners.query.graphql
new file mode 100644
index 00000000000..b517f5e89a8
--- /dev/null
+++ b/app/assets/javascripts/runner/graphql/list/group_runners.query.graphql
@@ -0,0 +1,41 @@
+#import "~/runner/graphql/list/list_item.fragment.graphql"
+#import "~/graphql_shared/fragments/pageInfo.fragment.graphql"
+
+query getGroupRunners(
+ $groupFullPath: ID!
+ $before: String
+ $after: String
+ $first: Int
+ $last: Int
+ $status: CiRunnerStatus
+ $type: CiRunnerType
+ $search: String
+ $sort: CiRunnerSort
+) {
+ group(fullPath: $groupFullPath) {
+ id # Apollo required
+ runners(
+ membership: DESCENDANTS
+ before: $before
+ after: $after
+ first: $first
+ last: $last
+ status: $status
+ type: $type
+ search: $search
+ sort: $sort
+ ) {
+ edges {
+ webUrl
+ editUrl
+ node {
+ ...ListItem
+ }
+ }
+ pageInfo {
+ __typename
+ ...PageInfo
+ }
+ }
+ }
+}
diff --git a/app/assets/javascripts/runner/graphql/get_group_runners_count.query.graphql b/app/assets/javascripts/runner/graphql/list/group_runners_count.query.graphql
index 554eb09e372..554eb09e372 100644
--- a/app/assets/javascripts/runner/graphql/get_group_runners_count.query.graphql
+++ b/app/assets/javascripts/runner/graphql/list/group_runners_count.query.graphql
diff --git a/app/assets/javascripts/runner/graphql/list/list_item.fragment.graphql b/app/assets/javascripts/runner/graphql/list/list_item.fragment.graphql
new file mode 100644
index 00000000000..620c18c5bc0
--- /dev/null
+++ b/app/assets/javascripts/runner/graphql/list/list_item.fragment.graphql
@@ -0,0 +1,20 @@
+fragment ListItem on CiRunner {
+ __typename
+ id
+ description
+ runnerType
+ shortSha
+ version
+ revision
+ ipAddress
+ active
+ locked
+ jobCount
+ tagList
+ contactedAt
+ status(legacyMode: null)
+ userPermissions {
+ updateRunner
+ deleteRunner
+ }
+}
diff --git a/app/assets/javascripts/runner/graphql/runners_registration_token_reset.mutation.graphql b/app/assets/javascripts/runner/graphql/list/runners_registration_token_reset.mutation.graphql
index 9c2797732ad..9c2797732ad 100644
--- a/app/assets/javascripts/runner/graphql/runners_registration_token_reset.mutation.graphql
+++ b/app/assets/javascripts/runner/graphql/list/runners_registration_token_reset.mutation.graphql
diff --git a/app/assets/javascripts/runner/graphql/runner_details_shared.fragment.graphql b/app/assets/javascripts/runner/graphql/runner_details_shared.fragment.graphql
deleted file mode 100644
index 74760bbaa07..00000000000
--- a/app/assets/javascripts/runner/graphql/runner_details_shared.fragment.graphql
+++ /dev/null
@@ -1,34 +0,0 @@
-fragment RunnerDetailsShared on CiRunner {
- id
- runnerType
- active
- accessLevel
- runUntagged
- locked
- ipAddress
- description
- maximumTimeout
- jobCount
- tagList
- createdAt
- status(legacyMode: null)
- contactedAt
- version
- editAdminUrl
- userPermissions {
- updateRunner
- deleteRunner
- }
- groups {
- # Only a single group can be loaded here, while projects
- # are loaded separately using the query with pagination
- # parameters `get_runner_projects.query.graphql`.
- nodes {
- id
- avatarUrl
- name
- fullName
- webUrl
- }
- }
-}
diff --git a/app/assets/javascripts/runner/graphql/runner_node.fragment.graphql b/app/assets/javascripts/runner/graphql/runner_node.fragment.graphql
deleted file mode 100644
index fbdef817f2f..00000000000
--- a/app/assets/javascripts/runner/graphql/runner_node.fragment.graphql
+++ /dev/null
@@ -1,20 +0,0 @@
-fragment RunnerNode on CiRunner {
- __typename
- id
- description
- runnerType
- shortSha
- version
- revision
- ipAddress
- active
- locked
- jobCount
- tagList
- contactedAt
- status(legacyMode: null)
- userPermissions {
- updateRunner
- deleteRunner
- }
-}
diff --git a/app/assets/javascripts/runner/graphql/runner_update.mutation.graphql b/app/assets/javascripts/runner/graphql/runner_update.mutation.graphql
deleted file mode 100644
index 8d1b75828be..00000000000
--- a/app/assets/javascripts/runner/graphql/runner_update.mutation.graphql
+++ /dev/null
@@ -1,15 +0,0 @@
-#import "ee_else_ce/runner/graphql/runner_details.fragment.graphql"
-
-# Mutation for updates from the runner form, loads
-# attributes shown in the runner details.
-
-mutation runnerUpdate($input: RunnerUpdateInput!) {
- runnerUpdate(input: $input) {
- # We have an id in deep nested fragment
- # eslint-disable-next-line @graphql-eslint/require-id-when-available
- runner {
- ...RunnerDetails
- }
- errors
- }
-}
diff --git a/app/assets/javascripts/runner/graphql/runner_delete.mutation.graphql b/app/assets/javascripts/runner/graphql/shared/runner_delete.mutation.graphql
index d580ea2785e..d580ea2785e 100644
--- a/app/assets/javascripts/runner/graphql/runner_delete.mutation.graphql
+++ b/app/assets/javascripts/runner/graphql/shared/runner_delete.mutation.graphql
diff --git a/app/assets/javascripts/runner/graphql/runner_toggle_active.mutation.graphql b/app/assets/javascripts/runner/graphql/shared/runner_toggle_active.mutation.graphql
index 9b15570dbc0..9b15570dbc0 100644
--- a/app/assets/javascripts/runner/graphql/runner_toggle_active.mutation.graphql
+++ b/app/assets/javascripts/runner/graphql/shared/runner_toggle_active.mutation.graphql
diff --git a/app/assets/javascripts/runner/group_runners/group_runners_app.vue b/app/assets/javascripts/runner/group_runners/group_runners_app.vue
index c4ee0ad4dfb..35fd7fff6d3 100644
--- a/app/assets/javascripts/runner/group_runners/group_runners_app.vue
+++ b/app/assets/javascripts/runner/group_runners/group_runners_app.vue
@@ -12,19 +12,20 @@ import RunnerName from '../components/runner_name.vue';
import RunnerStats from '../components/stat/runner_stats.vue';
import RunnerPagination from '../components/runner_pagination.vue';
import RunnerTypeTabs from '../components/runner_type_tabs.vue';
+import RunnerActionsCell from '../components/cells/runner_actions_cell.vue';
import { statusTokenConfig } from '../components/search_tokens/status_token_config';
import {
- I18N_FETCH_ERROR,
GROUP_FILTERED_SEARCH_NAMESPACE,
GROUP_TYPE,
PROJECT_TYPE,
STATUS_ONLINE,
STATUS_OFFLINE,
STATUS_STALE,
+ I18N_FETCH_ERROR,
} from '../constants';
-import getGroupRunnersQuery from '../graphql/get_group_runners.query.graphql';
-import getGroupRunnersCountQuery from '../graphql/get_group_runners_count.query.graphql';
+import groupRunnersQuery from '../graphql/list/group_runners.query.graphql';
+import groupRunnersCountQuery from '../graphql/list/group_runners_count.query.graphql';
import {
fromUrlQueryToSearch,
fromSearchToUrl,
@@ -33,7 +34,7 @@ import {
import { captureException } from '../sentry_utils';
const runnersCountSmartQuery = {
- query: getGroupRunnersCountQuery,
+ query: groupRunnersCountQuery,
fetchPolicy: fetchPolicies.CACHE_AND_NETWORK,
update(data) {
return data?.group?.runners?.count;
@@ -55,6 +56,7 @@ export default {
RunnerStats,
RunnerPagination,
RunnerTypeTabs,
+ RunnerActionsCell,
},
props: {
registrationToken: {
@@ -74,15 +76,15 @@ export default {
return {
search: fromUrlQueryToSearch(),
runners: {
- webUrls: [],
items: [],
+ urlsById: {},
pageInfo: {},
},
};
},
apollo: {
runners: {
- query: getGroupRunnersQuery,
+ query: groupRunnersQuery,
// Runners can be updated by users directly in this list.
// A "cache and network" policy prevents outdated filtered
// results.
@@ -91,12 +93,23 @@ export default {
return this.variables;
},
update(data) {
- const { runners } = data?.group || {};
+ const { edges = [], pageInfo = {} } = data?.group?.runners || {};
+
+ const items = [];
+ const urlsById = {};
+
+ edges.forEach(({ node, webUrl, editUrl }) => {
+ items.push(node);
+ urlsById[node.id] = {
+ web: webUrl,
+ edit: editUrl,
+ };
+ });
return {
- webUrls: runners?.edges.map(({ webUrl }) => webUrl) || [],
- items: runners?.edges.map(({ node }) => node) || [],
- pageInfo: runners?.pageInfo || {},
+ items,
+ urlsById,
+ pageInfo,
};
},
error(error) {
@@ -190,6 +203,7 @@ export default {
deep: true,
handler() {
// TODO Implement back button reponse using onpopstate
+ // See https://gitlab.com/gitlab-org/gitlab/-/issues/333804
updateHistory({
url: fromSearchToUrl(this.search),
title: document.title,
@@ -221,6 +235,16 @@ export default {
}
return null;
},
+ webUrl(runner) {
+ return this.runners.urlsById[runner.id]?.web;
+ },
+ editUrl(runner) {
+ return this.runners.urlsById[runner.id]?.edit;
+ },
+ onDeleted({ message }) {
+ this.$root.$toast?.show(message);
+ this.$apollo.queries.runners.refetch();
+ },
reportToSentry(error) {
captureException({ error, component: this.$options.name });
},
@@ -272,13 +296,20 @@ export default {
</div>
<template v-else>
<runner-list :runners="runners.items" :loading="runnersLoading">
- <template #runner-name="{ runner, index }">
- <gl-link :href="runners.webUrls[index]">
+ <template #runner-name="{ runner }">
+ <gl-link :href="webUrl(runner)">
<runner-name :runner="runner" />
</gl-link>
</template>
+ <template #runner-actions-cell="{ runner }">
+ <runner-actions-cell :runner="runner" :edit-url="editUrl(runner)" @deleted="onDeleted" />
+ </template>
</runner-list>
- <runner-pagination v-model="search.pagination" :page-info="runners.pageInfo" />
+ <runner-pagination
+ v-model="search.pagination"
+ class="gl-mt-3"
+ :page-info="runners.pageInfo"
+ />
</template>
</div>
</template>
diff --git a/app/assets/javascripts/search/topbar/components/app.vue b/app/assets/javascripts/search/topbar/components/app.vue
index 65114ee066e..f27dae8249d 100644
--- a/app/assets/javascripts/search/topbar/components/app.vue
+++ b/app/assets/javascripts/search/topbar/components/app.vue
@@ -1,17 +1,20 @@
<script>
-import { GlForm, GlSearchBoxByType, GlButton } from '@gitlab/ui';
+import { GlSearchBoxByClick } from '@gitlab/ui';
import { mapState, mapActions } from 'vuex';
+import { s__ } from '~/locale';
import GroupFilter from './group_filter.vue';
import ProjectFilter from './project_filter.vue';
export default {
name: 'GlobalSearchTopbar',
+ i18n: {
+ searchPlaceholder: s__(`GlobalSearch|Search for projects, issues, etc.`),
+ searchLabel: s__(`GlobalSearch|What are you searching for?`),
+ },
components: {
- GlForm,
- GlSearchBoxByType,
+ GlSearchBoxByClick,
GroupFilter,
ProjectFilter,
- GlButton,
},
props: {
groupInitialData: {
@@ -49,28 +52,24 @@ export default {
</script>
<template>
- <gl-form class="search-page-form" @submit.prevent="applyQuery">
- <section class="gl-lg-display-flex gl-align-items-flex-end">
- <div class="gl-flex-grow-1 gl-mb-4 gl-lg-mb-0 gl-lg-mr-2">
- <label>{{ __('What are you searching for?') }}</label>
- <gl-search-box-by-type
- id="dashboard_search"
- v-model="search"
- name="search"
- :placeholder="__(`Search for projects, issues, etc.`)"
- />
- </div>
- <div v-if="showFilters" class="gl-mb-4 gl-lg-mb-0 gl-lg-mx-2">
- <label class="gl-display-block">{{ __('Group') }}</label>
- <group-filter :initial-data="groupInitialData" />
- </div>
- <div v-if="showFilters" class="gl-mb-4 gl-lg-mb-0 gl-lg-mx-2">
- <label class="gl-display-block">{{ __('Project') }}</label>
- <project-filter :initial-data="projectInitialData" />
- </div>
- <gl-button class="btn-search gl-lg-ml-2" category="primary" variant="confirm" type="submit"
- >{{ __('Search') }}
- </gl-button>
- </section>
- </gl-form>
+ <section class="search-page-form gl-lg-display-flex gl-align-items-flex-end">
+ <div class="gl-flex-grow-1 gl-mb-4 gl-lg-mb-0 gl-lg-mr-2">
+ <label>{{ $options.i18n.searchLabel }}</label>
+ <gl-search-box-by-click
+ id="dashboard_search"
+ v-model="search"
+ name="search"
+ :placeholder="$options.i18n.searchPlaceholder"
+ @submit="applyQuery"
+ />
+ </div>
+ <div v-if="showFilters" class="gl-mb-4 gl-lg-mb-0 gl-lg-mx-2">
+ <label class="gl-display-block">{{ __('Group') }}</label>
+ <group-filter :initial-data="groupInitialData" />
+ </div>
+ <div v-if="showFilters" class="gl-mb-4 gl-lg-mb-0 gl-lg-mx-2">
+ <label class="gl-display-block">{{ __('Project') }}</label>
+ <project-filter :initial-data="projectInitialData" />
+ </div>
+ </section>
</template>
diff --git a/app/assets/javascripts/security_configuration/components/constants.js b/app/assets/javascripts/security_configuration/components/constants.js
index 81d222438e3..39a2939f52a 100644
--- a/app/assets/javascripts/security_configuration/components/constants.js
+++ b/app/assets/javascripts/security_configuration/components/constants.js
@@ -16,6 +16,8 @@ import {
REPORT_TYPE_LICENSE_COMPLIANCE,
} from '~/vue_shared/security_reports/constants';
+import kontraLogo from 'images/vulnerability/kontra-logo.svg';
+import scwLogo from 'images/vulnerability/scw-logo.svg';
import configureSastMutation from '../graphql/configure_sast.mutation.graphql';
import configureSastIacMutation from '../graphql/configure_iac.mutation.graphql';
import configureSecretDetectionMutation from '../graphql/configure_secret_detection.mutation.graphql';
@@ -222,14 +224,12 @@ export const securityFeatures = [
helpPath: COVERAGE_FUZZING_HELP_PATH,
configurationHelpPath: COVERAGE_FUZZING_CONFIG_HELP_PATH,
type: REPORT_TYPE_COVERAGE_FUZZING,
- secondary: gon?.features?.corpusManagementUi
- ? {
- type: REPORT_TYPE_CORPUS_MANAGEMENT,
- name: CORPUS_MANAGEMENT_NAME,
- description: CORPUS_MANAGEMENT_DESCRIPTION,
- configurationText: CORPUS_MANAGEMENT_CONFIG_TEXT,
- }
- : {},
+ secondary: {
+ type: REPORT_TYPE_CORPUS_MANAGEMENT,
+ name: CORPUS_MANAGEMENT_NAME,
+ description: CORPUS_MANAGEMENT_DESCRIPTION,
+ configurationText: CORPUS_MANAGEMENT_CONFIG_TEXT,
+ },
},
];
@@ -281,3 +281,21 @@ export const featureToMutationMap = {
export const AUTO_DEVOPS_ENABLED_ALERT_DISMISSED_STORAGE_KEY =
'security_configuration_auto_devops_enabled_dismissed_projects';
+
+// Fetch the svg path from the GraphQL query once this issue is resolved
+// https://gitlab.com/gitlab-org/gitlab/-/issues/346899
+export const TEMP_PROVIDER_LOGOS = {
+ Kontra: {
+ svg: kontraLogo,
+ },
+ [__('Secure Code Warrior')]: {
+ svg: scwLogo,
+ },
+};
+
+// Use the `url` field from the GraphQL query once this issue is resolved
+// https://gitlab.com/gitlab-org/gitlab/-/issues/356129
+export const TEMP_PROVIDER_URLS = {
+ Kontra: 'https://application.security/',
+ [__('Secure Code Warrior')]: 'https://www.securecodewarrior.com/',
+};
diff --git a/app/assets/javascripts/security_configuration/components/feature_card.vue b/app/assets/javascripts/security_configuration/components/feature_card.vue
index 1c37d8008de..cd5ad86e1a8 100644
--- a/app/assets/javascripts/security_configuration/components/feature_card.vue
+++ b/app/assets/javascripts/security_configuration/components/feature_card.vue
@@ -31,13 +31,12 @@ export default {
const button = this.enabled
? {
text: this.$options.i18n.configureFeature,
- category: 'secondary',
}
: {
text: this.$options.i18n.enableFeature,
- category: 'primary',
};
+ button.category = 'secondary';
button.text = sprintf(button.text, { feature: this.shortName });
return button;
@@ -126,7 +125,7 @@ export default {
v-else-if="showManageViaMr"
:feature="feature"
variant="confirm"
- category="primary"
+ category="secondary"
class="gl-mt-5"
:data-qa-selector="`${feature.type}_mr_button`"
@error="onError"
diff --git a/app/assets/javascripts/security_configuration/components/training_provider_list.vue b/app/assets/javascripts/security_configuration/components/training_provider_list.vue
index 539e2bff17c..bb540303cfd 100644
--- a/app/assets/javascripts/security_configuration/components/training_provider_list.vue
+++ b/app/assets/javascripts/security_configuration/components/training_provider_list.vue
@@ -1,15 +1,31 @@
<script>
-import { GlAlert, GlCard, GlToggle, GlLink, GlSkeletonLoader } from '@gitlab/ui';
+import {
+ GlAlert,
+ GlTooltipDirective,
+ GlCard,
+ GlToggle,
+ GlLink,
+ GlSkeletonLoader,
+ GlIcon,
+ GlSafeHtmlDirective,
+} from '@gitlab/ui';
import * as Sentry from '@sentry/browser';
import Tracking from '~/tracking';
-import { __ } from '~/locale';
+import { __, s__ } from '~/locale';
import {
TRACK_TOGGLE_TRAINING_PROVIDER_ACTION,
TRACK_TOGGLE_TRAINING_PROVIDER_LABEL,
+ TRACK_PROVIDER_LEARN_MORE_CLICK_ACTION,
+ TRACK_PROVIDER_LEARN_MORE_CLICK_LABEL,
} from '~/security_configuration/constants';
import dismissUserCalloutMutation from '~/graphql_shared/mutations/dismiss_user_callout.mutation.graphql';
-import securityTrainingProvidersQuery from '../graphql/security_training_providers.query.graphql';
-import configureSecurityTrainingProvidersMutation from '../graphql/configure_security_training_providers.mutation.graphql';
+import securityTrainingProvidersQuery from '~/security_configuration/graphql/security_training_providers.query.graphql';
+import configureSecurityTrainingProvidersMutation from '~/security_configuration/graphql/configure_security_training_providers.mutation.graphql';
+import {
+ updateSecurityTrainingCache,
+ updateSecurityTrainingOptimisticResponse,
+} from '~/security_configuration/graphql/cache_utils';
+import { TEMP_PROVIDER_LOGOS, TEMP_PROVIDER_URLS } from './constants';
const i18n = {
providerQueryErrorMessage: __(
@@ -18,6 +34,10 @@ const i18n = {
configMutationErrorMessage: __(
'Could not save configuration. Please refresh the page, or try again later.',
),
+ primaryTraining: s__('SecurityTraining|Primary Training'),
+ primaryTrainingDescription: s__(
+ 'SecurityTraining|Training from this partner takes precedence when more than one training partner is enabled.',
+ ),
};
export default {
@@ -27,6 +47,11 @@ export default {
GlToggle,
GlLink,
GlSkeletonLoader,
+ GlIcon,
+ },
+ directives: {
+ GlTooltip: GlTooltipDirective,
+ SafeHtml: GlSafeHtmlDirective,
},
mixins: [Tracking.mixin()],
inject: ['projectFullPath'],
@@ -49,12 +74,14 @@ export default {
data() {
return {
errorMessage: '',
- providerLoadingId: null,
securityTrainingProviders: [],
hasTouchedConfiguration: false,
};
},
computed: {
+ enabledProviders() {
+ return this.securityTrainingProviders.filter(({ isEnabled }) => isEnabled);
+ },
isLoading() {
return this.$apollo.queries.securityTrainingProviders.loading;
},
@@ -89,15 +116,41 @@ export default {
Sentry.captureException(e);
}
},
- toggleProvider(provider) {
- const { isEnabled } = provider;
+ async toggleProvider(provider) {
+ const { isEnabled, isPrimary } = provider;
const toggledIsEnabled = !isEnabled;
this.trackProviderToggle(provider.id, toggledIsEnabled);
- this.storeProvider({ ...provider, isEnabled: toggledIsEnabled });
+
+ // when the current primary provider gets disabled then set the first enabled to be the new primary
+ if (!toggledIsEnabled && isPrimary && this.enabledProviders.length > 1) {
+ const firstOtherEnabledProvider = this.enabledProviders.find(
+ ({ id }) => id !== provider.id,
+ );
+ this.setPrimaryProvider(firstOtherEnabledProvider);
+ }
+
+ this.storeProvider({
+ ...provider,
+ isEnabled: toggledIsEnabled,
+ });
},
- async storeProvider({ id, isEnabled, isPrimary }) {
- this.providerLoadingId = id;
+ setPrimaryProvider(provider) {
+ this.storeProvider({ ...provider, isPrimary: true });
+ },
+ async storeProvider(provider) {
+ const { id, isEnabled, isPrimary } = provider;
+ let nextIsPrimary = isPrimary;
+
+ // if the current provider has been disabled it can't be primary
+ if (!isEnabled) {
+ nextIsPrimary = false;
+ }
+
+ // if the current provider is the only enabled provider it should be primary
+ if (isEnabled && !this.enabledProviders.length) {
+ nextIsPrimary = true;
+ }
try {
const {
@@ -111,9 +164,18 @@ export default {
projectPath: this.projectFullPath,
providerId: id,
isEnabled,
- isPrimary,
+ isPrimary: nextIsPrimary,
},
},
+ optimisticResponse: updateSecurityTrainingOptimisticResponse({
+ id,
+ isEnabled,
+ isPrimary: nextIsPrimary,
+ }),
+ update: updateSecurityTrainingCache({
+ query: securityTrainingProvidersQuery,
+ variables: { fullPath: this.projectFullPath },
+ }),
});
if (errors.length > 0) {
@@ -124,8 +186,6 @@ export default {
this.hasTouchedConfiguration = true;
} catch {
this.errorMessage = this.$options.i18n.configMutationErrorMessage;
- } finally {
- this.providerLoadingId = null;
}
},
trackProviderToggle(providerId, providerIsEnabled) {
@@ -137,8 +197,16 @@ export default {
},
});
},
+ trackProviderLearnMoreClick(providerId) {
+ this.track(TRACK_PROVIDER_LEARN_MORE_CLICK_ACTION, {
+ label: TRACK_PROVIDER_LEARN_MORE_CLICK_LABEL,
+ property: providerId,
+ });
+ },
},
i18n,
+ TEMP_PROVIDER_LOGOS,
+ TEMP_PROVIDER_URLS,
};
</script>
@@ -165,15 +233,54 @@ export default {
:value="provider.isEnabled"
:label="__('Training mode')"
label-position="hidden"
- :is-loading="providerLoadingId === provider.id"
@change="toggleProvider(provider)"
/>
- <div class="gl-ml-5">
+ <div v-if="$options.TEMP_PROVIDER_LOGOS[provider.name]" class="gl-ml-4">
+ <div
+ v-safe-html="$options.TEMP_PROVIDER_LOGOS[provider.name].svg"
+ data-testid="provider-logo"
+ style="width: 18px"
+ role="presentation"
+ ></div>
+ </div>
+ <div class="gl-ml-3">
<h3 class="gl-font-lg gl-m-0 gl-mb-2">{{ provider.name }}</h3>
<p>
{{ provider.description }}
- <gl-link :href="provider.url" target="_blank">{{ __('Learn more.') }}</gl-link>
+ <gl-link
+ v-if="$options.TEMP_PROVIDER_URLS[provider.name]"
+ :href="$options.TEMP_PROVIDER_URLS[provider.name]"
+ target="_blank"
+ @click="trackProviderLearnMoreClick(provider.id)"
+ >
+ {{ __('Learn more.') }}
+ </gl-link>
</p>
+ <!-- Note: The following `div` and it's content will be replaced by 'GlFormRadio' once https://gitlab.com/gitlab-org/gitlab-ui/-/issues/1720#note_857342988 is resolved -->
+ <div
+ class="gl-form-radio custom-control custom-radio"
+ data-testid="primary-provider-radio"
+ >
+ <input
+ :id="`security-training-provider-${provider.id}`"
+ type="radio"
+ :checked="provider.isPrimary"
+ class="custom-control-input"
+ :disabled="!provider.isEnabled"
+ @change="setPrimaryProvider(provider)"
+ />
+ <label
+ class="custom-control-label"
+ :for="`security-training-provider-${provider.id}`"
+ >
+ {{ $options.i18n.primaryTraining }}
+ </label>
+ <gl-icon
+ v-gl-tooltip="$options.i18n.primaryTrainingDescription"
+ name="information-o"
+ class="gl-ml-2 gl-cursor-help"
+ />
+ </div>
</div>
</div>
</gl-card>
diff --git a/app/assets/javascripts/security_configuration/constants.js b/app/assets/javascripts/security_configuration/constants.js
index dc76436e91d..14eb10ac2aa 100644
--- a/app/assets/javascripts/security_configuration/constants.js
+++ b/app/assets/javascripts/security_configuration/constants.js
@@ -1,2 +1,8 @@
export const TRACK_TOGGLE_TRAINING_PROVIDER_ACTION = 'toggle_security_training_provider';
export const TRACK_TOGGLE_TRAINING_PROVIDER_LABEL = 'update_security_training_provider';
+export const TRACK_CLICK_TRAINING_LINK_ACTION = 'click_security_training_link';
+export const TRACK_PROVIDER_LEARN_MORE_CLICK_ACTION = 'click_link';
+export const TRACK_PROVIDER_LEARN_MORE_CLICK_LABEL = 'security_training_provider';
+export const TRACK_TRAINING_LOADED_ACTION = 'security_training_link_loaded';
+export const TRACK_PROMOTION_BANNER_CTA_CLICK_ACTION = 'click_button';
+export const TRACK_PROMOTION_BANNER_CTA_CLICK_LABEL = 'security_training_promotion_cta';
diff --git a/app/assets/javascripts/security_configuration/graphql/cache_utils.js b/app/assets/javascripts/security_configuration/graphql/cache_utils.js
new file mode 100644
index 00000000000..6d5258b01dc
--- /dev/null
+++ b/app/assets/javascripts/security_configuration/graphql/cache_utils.js
@@ -0,0 +1,40 @@
+import produce from 'immer';
+
+export const updateSecurityTrainingOptimisticResponse = (changes) => ({
+ // False positive i18n lint: https://gitlab.com/gitlab-org/frontend/eslint-plugin-i18n/issues/26
+ // eslint-disable-next-line @gitlab/require-i18n-strings
+ __typename: 'Mutation',
+ securityTrainingUpdate: {
+ __typename: 'SecurityTrainingUpdatePayload',
+ training: {
+ __typename: 'ProjectSecurityTraining',
+ ...changes,
+ },
+ errors: [],
+ },
+});
+
+export const updateSecurityTrainingCache = ({ query, variables }) => (cache, { data }) => {
+ const {
+ securityTrainingUpdate: { training: updatedProvider },
+ } = data;
+ const { project } = cache.readQuery({ query, variables });
+ if (!updatedProvider.isPrimary) {
+ return;
+ }
+
+ // when we set a new primary provider, we need to unset the previous one(s)
+ const updatedProject = produce(project, (draft) => {
+ draft.securityTrainingProviders.forEach((provider) => {
+ // eslint-disable-next-line no-param-reassign
+ provider.isPrimary = provider.id === updatedProvider.id;
+ });
+ });
+
+ // write to the cache
+ cache.writeQuery({
+ query,
+ variables,
+ data: { project: updatedProject },
+ });
+};
diff --git a/app/assets/javascripts/security_configuration/graphql/security_training_vulnerability.query.graphql b/app/assets/javascripts/security_configuration/graphql/security_training_vulnerability.query.graphql
new file mode 100644
index 00000000000..f0474614dab
--- /dev/null
+++ b/app/assets/javascripts/security_configuration/graphql/security_training_vulnerability.query.graphql
@@ -0,0 +1,10 @@
+query getSecurityTrainingUrls($projectFullPath: ID!, $identifierExternalIds: [String!]!) {
+ project(fullPath: $projectFullPath) {
+ id
+ securityTrainingUrls(identifierExternalIds: $identifierExternalIds) {
+ name
+ status
+ url
+ }
+ }
+}
diff --git a/app/assets/javascripts/sidebar/components/assignees/assignee_avatar.vue b/app/assets/javascripts/sidebar/components/assignees/assignee_avatar.vue
index da9ff407faf..240e12ee597 100644
--- a/app/assets/javascripts/sidebar/components/assignees/assignee_avatar.vue
+++ b/app/assets/javascripts/sidebar/components/assignees/assignee_avatar.vue
@@ -1,5 +1,6 @@
<script>
import { GlIcon } from '@gitlab/ui';
+import { IssuableType } from '~/issues/constants';
import { __, sprintf } from '~/locale';
export default {
@@ -31,10 +32,11 @@ export default {
);
},
isMergeRequest() {
- return this.issuableType === 'merge_request';
+ return this.issuableType === IssuableType.MergeRequest;
},
hasMergeIcon() {
- return this.isMergeRequest && !this.user.can_merge;
+ const canMerge = this.user.mergeRequestInteraction?.canMerge || this.user.can_merge;
+ return this.isMergeRequest && !canMerge;
},
},
};
diff --git a/app/assets/javascripts/sidebar/components/assignees/assignee_avatar_link.vue b/app/assets/javascripts/sidebar/components/assignees/assignee_avatar_link.vue
index 2a237e7ace0..578c344da02 100644
--- a/app/assets/javascripts/sidebar/components/assignees/assignee_avatar_link.vue
+++ b/app/assets/javascripts/sidebar/components/assignees/assignee_avatar_link.vue
@@ -1,5 +1,6 @@
<script>
import { GlTooltipDirective, GlLink } from '@gitlab/ui';
+import { IssuableType } from '~/issues/constants';
import { __ } from '~/locale';
import { isUserBusy } from '~/set_status_modal/utils';
import AssigneeAvatar from './assignee_avatar.vue';
@@ -71,7 +72,8 @@ export default {
},
computed: {
cannotMerge() {
- return this.issuableType === 'merge_request' && !this.user.can_merge;
+ const canMerge = this.user.mergeRequestInteraction?.canMerge || this.user.can_merge;
+ return this.issuableType === IssuableType.MergeRequest && !canMerge;
},
tooltipTitle() {
const { name = '', availability = '' } = this.user;
diff --git a/app/assets/javascripts/sidebar/components/assignees/collapsed_assignee_list.vue b/app/assets/javascripts/sidebar/components/assignees/collapsed_assignee_list.vue
index 6a74ab83c22..856687c00ae 100644
--- a/app/assets/javascripts/sidebar/components/assignees/collapsed_assignee_list.vue
+++ b/app/assets/javascripts/sidebar/components/assignees/collapsed_assignee_list.vue
@@ -58,7 +58,7 @@ export default {
return this.users.length > 2;
},
allAssigneesCanMerge() {
- return this.users.every((user) => user.can_merge);
+ return this.users.every((user) => user.can_merge || user.mergeRequestInteraction?.canMerge);
},
sidebarAvatarCounter() {
if (this.users.length > DEFAULT_MAX_COUNTER) {
@@ -77,7 +77,9 @@ export default {
return '';
}
- const mergeLength = this.users.filter((u) => u.can_merge).length;
+ const mergeLength = this.users.filter(
+ (u) => u.can_merge || u.mergeRequestInteraction?.canMerge,
+ ).length;
if (mergeLength === this.users.length) {
return '';
diff --git a/app/assets/javascripts/sidebar/components/assignees/issuable_assignees.vue b/app/assets/javascripts/sidebar/components/assignees/issuable_assignees.vue
index a3379784bc1..59a4eb54bbe 100644
--- a/app/assets/javascripts/sidebar/components/assignees/issuable_assignees.vue
+++ b/app/assets/javascripts/sidebar/components/assignees/issuable_assignees.vue
@@ -44,7 +44,7 @@ export default {
<div class="gl-display-flex gl-flex-direction-column issuable-assignees">
<div
v-if="emptyUsers"
- class="gl-display-flex gl-align-items-center gl-text-gray-500 gl-mt-2 hide-collapsed"
+ class="gl-display-flex gl-align-items-center gl-text-gray-500 hide-collapsed"
data-testid="none"
>
<span> {{ __('None') }}</span>
@@ -65,7 +65,7 @@ export default {
v-else
:users="users"
:issuable-type="issuableType"
- class="gl-text-gray-800 gl-mt-2 hide-collapsed"
+ class="gl-text-gray-800 hide-collapsed"
@toggle-attention-requested="toggleAttentionRequested"
/>
</div>
diff --git a/app/assets/javascripts/sidebar/components/assignees/sidebar_assignees.vue b/app/assets/javascripts/sidebar/components/assignees/sidebar_assignees.vue
index 453dd1b0580..e596d6292bf 100644
--- a/app/assets/javascripts/sidebar/components/assignees/sidebar_assignees.vue
+++ b/app/assets/javascripts/sidebar/components/assignees/sidebar_assignees.vue
@@ -63,7 +63,7 @@ export default {
computed: {
shouldEnableRealtime() {
// Note: Realtime is only available on issues right now, future support for MR wil be built later.
- return this.glFeatures.realTimeIssueSidebar && this.issuableType === 'issue';
+ return this.issuableType === 'issue';
},
queryVariables() {
return {
diff --git a/app/assets/javascripts/sidebar/components/assignees/sidebar_assignees_widget.vue b/app/assets/javascripts/sidebar/components/assignees/sidebar_assignees_widget.vue
index 18654b73ab3..7743004a293 100644
--- a/app/assets/javascripts/sidebar/components/assignees/sidebar_assignees_widget.vue
+++ b/app/assets/javascripts/sidebar/components/assignees/sidebar_assignees_widget.vue
@@ -1,6 +1,5 @@
<script>
import { GlDropdownItem } from '@gitlab/ui';
-import { cloneDeep } from 'lodash';
import Vue from 'vue';
import createFlash from '~/flash';
import { IssuableType } from '~/issues/constants';
@@ -101,7 +100,10 @@ export default {
}
const issuable = data.workspace?.issuable;
if (issuable) {
- this.selected = cloneDeep(issuable.assignees.nodes);
+ this.selected = issuable.assignees.nodes.map((node) => ({
+ ...node,
+ canMerge: node.mergeRequestInteraction?.canMerge || false,
+ }));
}
},
error() {
@@ -112,7 +114,7 @@ export default {
computed: {
shouldEnableRealtime() {
// Note: Realtime is only available on issues right now, future support for MR wil be built later.
- return this.glFeatures.realTimeIssueSidebar && this.issuableType === IssuableType.Issue;
+ return this.issuableType === IssuableType.Issue;
},
queryVariables() {
return {
@@ -141,6 +143,7 @@ export default {
username: gon?.current_username,
name: gon?.current_user_fullname,
avatarUrl: gon?.current_user_avatar_url,
+ canMerge: this.issuable?.userPermissions?.canMerge || false,
};
},
signedIn() {
@@ -206,8 +209,8 @@ export default {
expandWidget() {
this.$refs.toggle.expand();
},
- focusSearch() {
- this.$refs.userSelect.focusSearch();
+ showDropdown() {
+ this.$refs.userSelect.showDropdown();
},
showError() {
createFlash({ message: __('An error occurred while fetching participants.') });
@@ -236,11 +239,11 @@ export default {
:initial-loading="isAssigneesLoading"
:title="assigneeText"
:is-dirty="isDirty"
- @open="focusSearch"
+ @open="showDropdown"
@close="saveAssignees"
>
<template #collapsed>
- <slot name="collapsed" :users="assignees" :on-click="expandWidget"></slot>
+ <slot name="collapsed" :users="assignees"></slot>
<issuable-assignees
:users="assignees"
:issuable-type="issuableType"
@@ -256,12 +259,13 @@ export default {
:text="$options.i18n.assignees"
:header-text="$options.i18n.assignTo"
:iid="iid"
+ :issuable-id="issuableId"
:full-path="fullPath"
:allow-multiple-assignees="allowMultipleAssignees"
:current-user="currentUser"
:issuable-type="issuableType"
:is-editing="edit"
- class="gl-w-full dropdown-menu-user"
+ class="gl-w-full dropdown-menu-user gl-mt-n3"
@toggle="collapseWidget"
@error="showError"
@input="setDirtyState"
diff --git a/app/assets/javascripts/sidebar/components/assignees/sidebar_invite_members.vue b/app/assets/javascripts/sidebar/components/assignees/sidebar_invite_members.vue
index 8ef65ef7308..28bc5afc1a4 100644
--- a/app/assets/javascripts/sidebar/components/assignees/sidebar_invite_members.vue
+++ b/app/assets/javascripts/sidebar/components/assignees/sidebar_invite_members.vue
@@ -30,6 +30,6 @@ export default {
:event="$options.dataTrackEvent"
:label="$options.dataTrackLabel"
:trigger-source="triggerSource"
- classes="gl-display-block gl-pl-6 gl-hover-text-decoration-none gl-hover-text-blue-800!"
+ classes="gl-display-block gl-pl-0 gl-hover-text-decoration-none gl-hover-text-blue-800!"
/>
</template>
diff --git a/app/assets/javascripts/sidebar/components/assignees/sidebar_participant.vue b/app/assets/javascripts/sidebar/components/assignees/sidebar_participant.vue
index e2a38a100b9..19f588b28be 100644
--- a/app/assets/javascripts/sidebar/components/assignees/sidebar_participant.vue
+++ b/app/assets/javascripts/sidebar/components/assignees/sidebar_participant.vue
@@ -1,17 +1,24 @@
<script>
-import { GlAvatarLabeled, GlAvatarLink } from '@gitlab/ui';
+import { GlAvatarLabeled, GlAvatarLink, GlIcon } from '@gitlab/ui';
+import { IssuableType } from '~/issues/constants';
import { s__, sprintf } from '~/locale';
export default {
components: {
GlAvatarLabeled,
GlAvatarLink,
+ GlIcon,
},
props: {
user: {
type: Object,
required: true,
},
+ issuableType: {
+ type: String,
+ required: false,
+ default: IssuableType.Issue,
+ },
},
computed: {
userLabel() {
@@ -22,6 +29,9 @@ export default {
author: this.user.name,
});
},
+ hasCannotMergeIcon() {
+ return this.issuableType === IssuableType.MergeRequest && !this.user.canMerge;
+ },
},
};
</script>
@@ -31,9 +41,19 @@ export default {
<gl-avatar-labeled
:size="32"
:label="userLabel"
- :sub-label="user.username"
+ :sub-label="`@${user.username}`"
:src="user.avatarUrl || user.avatar || user.avatar_url"
- class="gl-align-items-center"
- />
+ class="gl-align-items-center gl-relative"
+ >
+ <template #meta>
+ <gl-icon
+ v-if="hasCannotMergeIcon"
+ name="warning-solid"
+ aria-hidden="true"
+ class="merge-icon"
+ :size="12"
+ />
+ </template>
+ </gl-avatar-labeled>
</gl-avatar-link>
</template>
diff --git a/app/assets/javascripts/sidebar/components/assignees/uncollapsed_assignee_list.vue b/app/assets/javascripts/sidebar/components/assignees/uncollapsed_assignee_list.vue
index a27dbee31ec..558fe8ca2aa 100644
--- a/app/assets/javascripts/sidebar/components/assignees/uncollapsed_assignee_list.vue
+++ b/app/assets/javascripts/sidebar/components/assignees/uncollapsed_assignee_list.vue
@@ -114,7 +114,7 @@ export default {
class="gl-display-inline-block"
>
<attention-requested-toggle
- v-if="showVerticalList && user.can_update_merge_request"
+ v-if="showVerticalList"
:user="user"
type="assignee"
@toggle-attention-requested="toggleAttentionRequested"
diff --git a/app/assets/javascripts/sidebar/components/attention_requested_toggle.vue b/app/assets/javascripts/sidebar/components/attention_requested_toggle.vue
index 42e56906e2c..6ba88939373 100644
--- a/app/assets/javascripts/sidebar/components/attention_requested_toggle.vue
+++ b/app/assets/javascripts/sidebar/components/attention_requested_toggle.vue
@@ -8,6 +8,8 @@ export default {
attentionRequestedReviewer: __('Request attention to review'),
attentionRequestedAssignee: __('Request attention'),
removeAttentionRequested: __('Remove attention request'),
+ attentionRequestedNoPermission: __('Attention requested'),
+ noAttentionRequestedNoPermission: __('No attention request'),
},
components: {
GlButton,
@@ -33,17 +35,25 @@ export default {
computed: {
tooltipTitle() {
if (this.user.attention_requested) {
- return this.$options.i18n.removeAttentionRequested;
+ if (this.user.can_update_merge_request) {
+ return this.$options.i18n.removeAttentionRequested;
+ }
+
+ return this.$options.i18n.attentionRequestedNoPermission;
+ }
+
+ if (this.user.can_update_merge_request) {
+ return this.type === 'reviewer'
+ ? this.$options.i18n.attentionRequestedReviewer
+ : this.$options.i18n.attentionRequestedAssignee;
}
- return this.type === 'reviewer'
- ? this.$options.i18n.attentionRequestedReviewer
- : this.$options.i18n.attentionRequestedAssignee;
+ return this.$options.i18n.noAttentionRequestedNoPermission;
},
},
methods: {
toggleAttentionRequired() {
- if (this.loading) return;
+ if (this.loading || !this.user.can_update_merge_request) return;
this.$root.$emit(BV_HIDE_TOOLTIP);
this.loading = true;
@@ -60,12 +70,16 @@ export default {
</script>
<template>
- <span v-gl-tooltip.left.viewport="tooltipTitle">
+ <span
+ v-gl-tooltip.left.viewport="tooltipTitle"
+ class="gl-display-inline-block js-attention-request-toggle"
+ >
<gl-button
:loading="loading"
:variant="user.attention_requested ? 'warning' : 'default'"
:icon="user.attention_requested ? 'attention-solid' : 'attention'"
:aria-label="tooltipTitle"
+ :class="{ 'gl-pointer-events-none': !user.can_update_merge_request }"
size="small"
category="tertiary"
@click="toggleAttentionRequired"
diff --git a/app/assets/javascripts/sidebar/components/incidents/constants.js b/app/assets/javascripts/sidebar/components/incidents/constants.js
new file mode 100644
index 00000000000..cd05a6099fd
--- /dev/null
+++ b/app/assets/javascripts/sidebar/components/incidents/constants.js
@@ -0,0 +1,25 @@
+import { s__ } from '~/locale';
+
+export const STATUS_TRIGGERED = 'TRIGGERED';
+export const STATUS_ACKNOWLEDGED = 'ACKNOWLEDGED';
+export const STATUS_RESOLVED = 'RESOLVED';
+
+export const STATUS_TRIGGERED_LABEL = s__('IncidentManagement|Triggered');
+export const STATUS_ACKNOWLEDGED_LABEL = s__('IncidentManagement|Acknowledged');
+export const STATUS_RESOLVED_LABEL = s__('IncidentManagement|Resolved');
+
+export const STATUS_LABELS = {
+ [STATUS_TRIGGERED]: STATUS_TRIGGERED_LABEL,
+ [STATUS_ACKNOWLEDGED]: STATUS_ACKNOWLEDGED_LABEL,
+ [STATUS_RESOLVED]: STATUS_RESOLVED_LABEL,
+};
+
+export const i18n = {
+ fetchError: s__(
+ 'IncidentManagement|An error occurred while fetching the incident status. Please reload the page.',
+ ),
+ title: s__('IncidentManagement|Status'),
+ updateError: s__(
+ 'IncidentManagement|An error occurred while updating the incident status. Please reload the page and try again.',
+ ),
+};
diff --git a/app/assets/javascripts/sidebar/components/incidents/escalation_status.vue b/app/assets/javascripts/sidebar/components/incidents/escalation_status.vue
new file mode 100644
index 00000000000..2c32cf89387
--- /dev/null
+++ b/app/assets/javascripts/sidebar/components/incidents/escalation_status.vue
@@ -0,0 +1,61 @@
+<script>
+import { GlDropdown, GlDropdownItem } from '@gitlab/ui';
+import { i18n, STATUS_ACKNOWLEDGED, STATUS_TRIGGERED, STATUS_RESOLVED } from './constants';
+import { getStatusLabel } from './utils';
+
+const STATUS_LIST = [STATUS_TRIGGERED, STATUS_ACKNOWLEDGED, STATUS_RESOLVED];
+
+export default {
+ i18n,
+ STATUS_LIST,
+ components: {
+ GlDropdown,
+ GlDropdownItem,
+ },
+ props: {
+ value: {
+ type: String,
+ required: false,
+ default: null,
+ validator(value) {
+ return [...STATUS_LIST, null].includes(value);
+ },
+ },
+ },
+ computed: {
+ currentStatusLabel() {
+ return this.getStatusLabel(this.value);
+ },
+ },
+ methods: {
+ show() {
+ this.$refs.dropdown.show();
+ },
+ hide() {
+ this.$refs.dropdown.hide();
+ },
+ getStatusLabel,
+ },
+};
+</script>
+
+<template>
+ <gl-dropdown
+ ref="dropdown"
+ block
+ :text="currentStatusLabel"
+ toggle-class="dropdown-menu-toggle gl-mb-2"
+ >
+ <slot name="header"> </slot>
+ <gl-dropdown-item
+ v-for="status in $options.STATUS_LIST"
+ :key="status"
+ data-testid="status-dropdown-item"
+ :is-check-item="true"
+ :is-checked="status === value"
+ @click="$emit('input', status)"
+ >
+ {{ getStatusLabel(status) }}
+ </gl-dropdown-item>
+ </gl-dropdown>
+</template>
diff --git a/app/assets/javascripts/sidebar/components/incidents/sidebar_escalation_status.vue b/app/assets/javascripts/sidebar/components/incidents/sidebar_escalation_status.vue
new file mode 100644
index 00000000000..67ae1e6fcab
--- /dev/null
+++ b/app/assets/javascripts/sidebar/components/incidents/sidebar_escalation_status.vue
@@ -0,0 +1,135 @@
+<script>
+import { GlIcon, GlTooltipDirective } from '@gitlab/ui';
+import { escalationStatusQuery, escalationStatusMutation } from '~/sidebar/constants';
+import { createAlert } from '~/flash';
+import { logError } from '~/lib/logger';
+import EscalationStatus from 'ee_else_ce/sidebar/components/incidents/escalation_status.vue';
+import SidebarEditableItem from '../sidebar_editable_item.vue';
+import { i18n } from './constants';
+import { getStatusLabel } from './utils';
+
+export default {
+ i18n,
+ components: {
+ EscalationStatus,
+ SidebarEditableItem,
+ GlIcon,
+ },
+ directives: {
+ GlTooltip: GlTooltipDirective,
+ },
+ props: {
+ iid: {
+ type: String,
+ required: true,
+ },
+ projectPath: {
+ type: String,
+ required: true,
+ },
+ issuableType: {
+ required: true,
+ type: String,
+ },
+ },
+ data() {
+ return {
+ status: null,
+ isUpdating: false,
+ };
+ },
+ apollo: {
+ status: {
+ query() {
+ return escalationStatusQuery;
+ },
+ variables() {
+ return {
+ fullPath: this.projectPath,
+ iid: this.iid,
+ };
+ },
+ update(data) {
+ return data.workspace?.issuable?.escalationStatus;
+ },
+ error(error) {
+ const message = this.$options.i18n.fetchError;
+ createAlert({ message });
+ logError(message, error);
+ },
+ },
+ },
+ computed: {
+ isLoading() {
+ return this.$apollo.queries.status.loading;
+ },
+ currentStatusLabel() {
+ return getStatusLabel(this.status);
+ },
+ tooltipText() {
+ return `${this.$options.i18n.title}: ${this.currentStatusLabel}`;
+ },
+ },
+ methods: {
+ updateStatus(status) {
+ this.isUpdating = true;
+ this.closeSidebar();
+ return this.$apollo
+ .mutate({
+ mutation: escalationStatusMutation,
+ variables: {
+ status,
+ iid: this.iid,
+ projectPath: this.projectPath,
+ },
+ })
+ .then(({ data: { issueSetEscalationStatus } }) => {
+ this.status = issueSetEscalationStatus.issue.escalationStatus;
+ })
+ .catch((error) => {
+ const message = this.$options.i18n.updateError;
+ createAlert({ message });
+ logError(message, error);
+ })
+ .finally(() => {
+ this.isUpdating = false;
+ });
+ },
+ closeSidebar() {
+ this.close();
+ this.$refs.editable.collapse();
+ },
+ open() {
+ this.$refs.escalationStatus.show();
+ },
+ close() {
+ this.$refs.escalationStatus.hide();
+ },
+ },
+};
+</script>
+
+<template>
+ <sidebar-editable-item
+ ref="editable"
+ :title="$options.i18n.title"
+ :initial-loading="isLoading"
+ :loading="isUpdating"
+ @open="open"
+ @close="close"
+ >
+ <template #default>
+ <escalation-status ref="escalationStatus" :value="status" @input="updateStatus" />
+ </template>
+ <template #collapsed>
+ <div
+ v-gl-tooltip.viewport.left="tooltipText"
+ class="sidebar-collapsed-icon"
+ data-testid="status-icon"
+ >
+ <gl-icon name="status" :size="16" />
+ </div>
+ <span class="hide-collapsed text-secondary">{{ currentStatusLabel }}</span>
+ </template>
+ </sidebar-editable-item>
+</template>
diff --git a/app/assets/javascripts/sidebar/components/incidents/utils.js b/app/assets/javascripts/sidebar/components/incidents/utils.js
new file mode 100644
index 00000000000..59bf1ea466c
--- /dev/null
+++ b/app/assets/javascripts/sidebar/components/incidents/utils.js
@@ -0,0 +1,5 @@
+import { s__ } from '~/locale';
+
+import { STATUS_LABELS } from './constants';
+
+export const getStatusLabel = (status) => STATUS_LABELS[status] ?? s__('IncidentManagement|None');
diff --git a/app/assets/javascripts/sidebar/components/reviewers/uncollapsed_reviewer_list.vue b/app/assets/javascripts/sidebar/components/reviewers/uncollapsed_reviewer_list.vue
index adaf1b65f3f..9485802d3da 100644
--- a/app/assets/javascripts/sidebar/components/reviewers/uncollapsed_reviewer_list.vue
+++ b/app/assets/javascripts/sidebar/components/reviewers/uncollapsed_reviewer_list.vue
@@ -98,7 +98,7 @@ export default {
data-testid="reviewer"
>
<attention-requested-toggle
- v-if="glFeatures.mrAttentionRequests && user.can_update_merge_request"
+ v-if="glFeatures.mrAttentionRequests"
:user="user"
type="reviewer"
@toggle-attention-requested="toggleAttentionRequested"
diff --git a/app/assets/javascripts/sidebar/components/severity/severity.vue b/app/assets/javascripts/sidebar/components/severity/severity.vue
index 7e7d62256c9..0db856543d0 100644
--- a/app/assets/javascripts/sidebar/components/severity/severity.vue
+++ b/app/assets/javascripts/sidebar/components/severity/severity.vue
@@ -1,9 +1,11 @@
<script>
import { GlIcon } from '@gitlab/ui';
+import TooltipOnTruncate from '~/vue_shared/components/tooltip_on_truncate/tooltip_on_truncate.vue';
export default {
components: {
GlIcon,
+ TooltipOnTruncate,
},
props: {
severity: {
@@ -30,13 +32,15 @@ export default {
<template>
<div
- class="incident-severity gl-display-inline-flex gl-align-items-center gl-justify-content-between"
+ class="incident-severity gl-display-inline-flex gl-align-items-center gl-justify-content-between gl-max-w-full"
>
<gl-icon
:size="iconSize"
:name="`severity-${severity.icon}`"
:class="[`icon-${severity.icon}`, { 'gl-mr-3': !iconOnly }]"
/>
- <span v-if="!iconOnly">{{ severity.label }}</span>
+ <tooltip-on-truncate v-if="!iconOnly" :title="severity.label" class="gl-text-truncate">{{
+ severity.label
+ }}</tooltip-on-truncate>
</div>
</template>
diff --git a/app/assets/javascripts/sidebar/constants.js b/app/assets/javascripts/sidebar/constants.js
index 0238fb8e8d5..989dc574bc3 100644
--- a/app/assets/javascripts/sidebar/constants.js
+++ b/app/assets/javascripts/sidebar/constants.js
@@ -1,7 +1,8 @@
import { s__, sprintf } from '~/locale';
import updateIssueLabelsMutation from '~/boards/graphql/issue_set_labels.mutation.graphql';
+import userSearchQuery from '~/graphql_shared/queries/users_search.query.graphql';
+import userSearchWithMRPermissionsQuery from '~/graphql_shared/queries/users_search_with_mr_permissions.graphql';
import { IssuableType, WorkspaceType } from '~/issues/constants';
-import { DEFAULT_DEBOUNCE_AND_THROTTLE_MS } from '~/lib/utils/constants';
import epicConfidentialQuery from '~/sidebar/queries/epic_confidential.query.graphql';
import epicDueDateQuery from '~/sidebar/queries/epic_due_date.query.graphql';
import epicParticipantsQuery from '~/sidebar/queries/epic_participants.query.graphql';
@@ -49,12 +50,12 @@ import getMergeRequestParticipants from '~/vue_shared/components/sidebar/queries
import getMrTimelogsQuery from '~/vue_shared/components/sidebar/queries/get_mr_timelogs.query.graphql';
import updateIssueAssigneesMutation from '~/vue_shared/components/sidebar/queries/update_issue_assignees.mutation.graphql';
import updateMergeRequestAssigneesMutation from '~/vue_shared/components/sidebar/queries/update_mr_assignees.mutation.graphql';
+import getEscalationStatusQuery from '~/sidebar/queries/escalation_status.query.graphql';
+import updateEscalationStatusMutation from '~/sidebar/queries/update_escalation_status.mutation.graphql';
import projectIssueMilestoneMutation from './queries/project_issue_milestone.mutation.graphql';
import projectIssueMilestoneQuery from './queries/project_issue_milestone.query.graphql';
import projectMilestonesQuery from './queries/project_milestones.query.graphql';
-export const ASSIGNEES_DEBOUNCE_DELAY = DEFAULT_DEBOUNCE_AND_THROTTLE_MS;
-
export const defaultEpicSort = 'TITLE_ASC';
export const epicIidPattern = /^&(?<iid>\d+)$/;
@@ -91,6 +92,15 @@ export const participantsQueries = {
},
};
+export const userSearchQueries = {
+ [IssuableType.Issue]: {
+ query: userSearchQuery,
+ },
+ [IssuableType.MergeRequest]: {
+ query: userSearchWithMRPermissionsQuery,
+ },
+};
+
export const confidentialityQueries = {
[IssuableType.Issue]: {
query: issueConfidentialQuery,
@@ -305,3 +315,6 @@ export function dropdowni18nText(issuableAttribute, issuableType) {
),
};
}
+
+export const escalationStatusQuery = getEscalationStatusQuery;
+export const escalationStatusMutation = updateEscalationStatusMutation;
diff --git a/app/assets/javascripts/sidebar/mount_sidebar.js b/app/assets/javascripts/sidebar/mount_sidebar.js
index c29784aa328..2a7d967cb61 100644
--- a/app/assets/javascripts/sidebar/mount_sidebar.js
+++ b/app/assets/javascripts/sidebar/mount_sidebar.js
@@ -10,6 +10,7 @@ import {
isInIssuePage,
isInDesignPage,
isInIncidentPage,
+ isInMRPage,
parseBoolean,
} from '~/lib/utils/common_utils';
import { __ } from '~/locale';
@@ -27,9 +28,11 @@ import { DropdownVariant } from '~/vue_shared/components/sidebar/labels_select_v
import LabelsSelectWidget from '~/vue_shared/components/sidebar/labels_select_widget/labels_select_root.vue';
import { LabelType } from '~/vue_shared/components/sidebar/labels_select_widget/constants';
import eventHub from '~/sidebar/event_hub';
+import { refreshUserMergeRequestCounts } from '~/commons/nav/user_merge_requests';
import Translate from '../vue_shared/translate';
import SidebarAssignees from './components/assignees/sidebar_assignees.vue';
import CopyEmailToClipboard from './components/copy_email_to_clipboard.vue';
+import SidebarEscalationStatus from './components/incidents/sidebar_escalation_status.vue';
import IssuableLockForm from './components/lock/issuable_lock_form.vue';
import SidebarReviewers from './components/reviewers/sidebar_reviewers.vue';
import SidebarSeverity from './components/severity/sidebar_severity.vue';
@@ -134,6 +137,8 @@ function mountAssigneesComponent() {
if (!el) return;
const { id, iid, fullPath, editable } = getSidebarOptions();
+ const isIssuablePage = isInIssuePage() || isInIncidentPage() || isInDesignPage();
+ const issuableType = isIssuablePage ? IssuableType.Issue : IssuableType.MergeRequest;
// eslint-disable-next-line no-new
new Vue({
el,
@@ -151,21 +156,16 @@ function mountAssigneesComponent() {
props: {
iid: String(iid),
fullPath,
- issuableType:
- isInIssuePage() || isInIncidentPage() || isInDesignPage()
- ? IssuableType.Issue
- : IssuableType.MergeRequest,
+ issuableType,
issuableId: id,
allowMultipleAssignees: !el.dataset.maxAssignees,
},
scopedSlots: {
- collapsed: ({ users, onClick }) =>
+ collapsed: ({ users }) =>
createElement(CollapsedAssigneeList, {
props: {
users,
- },
- nativeOn: {
- click: onClick,
+ issuableType,
},
}),
},
@@ -567,6 +567,36 @@ function mountSeverityComponent() {
});
}
+function mountEscalationStatusComponent() {
+ const statusContainerEl = document.querySelector('#js-escalation-status');
+
+ if (!statusContainerEl) {
+ return false;
+ }
+
+ const { issuableType } = getSidebarOptions();
+ const { canUpdate, issueIid, projectPath } = statusContainerEl.dataset;
+
+ return new Vue({
+ el: statusContainerEl,
+ apolloProvider,
+ components: {
+ SidebarEscalationStatus,
+ },
+ provide: {
+ canUpdate: parseBoolean(canUpdate),
+ },
+ render: (createElement) =>
+ createElement('sidebar-escalation-status', {
+ props: {
+ iid: issueIid,
+ issuableType,
+ projectPath,
+ },
+ }),
+ });
+}
+
function mountCopyEmailComponent() {
const el = document.getElementById('issuable-copy-email');
@@ -584,7 +614,7 @@ function mountCopyEmailComponent() {
}
const isAssigneesWidgetShown =
- (isInIssuePage() || isInDesignPage()) && gon.features.issueAssigneesWidget;
+ (isInIssuePage() || isInDesignPage() || isInMRPage()) && gon.features.issueAssigneesWidget;
export function mountSidebar(mediator, store) {
initInviteMembersModal();
@@ -618,10 +648,13 @@ export function mountSidebar(mediator, store) {
mountSeverityComponent();
+ mountEscalationStatusComponent();
+
if (window.gon?.features?.mrAttentionRequests) {
- eventHub.$on('removeCurrentUserAttentionRequested', () =>
- mediator.removeCurrentUserAttentionRequested(),
- );
+ eventHub.$on('removeCurrentUserAttentionRequested', () => {
+ mediator.removeCurrentUserAttentionRequested();
+ refreshUserMergeRequestCounts();
+ });
}
}
diff --git a/app/assets/javascripts/sidebar/queries/escalation_status.query.graphql b/app/assets/javascripts/sidebar/queries/escalation_status.query.graphql
new file mode 100644
index 00000000000..cb7c5a0fbe7
--- /dev/null
+++ b/app/assets/javascripts/sidebar/queries/escalation_status.query.graphql
@@ -0,0 +1,9 @@
+query escalationStatusQuery($fullPath: ID!, $iid: String) {
+ workspace: project(fullPath: $fullPath) {
+ id
+ issuable: issue(iid: $iid) {
+ id
+ escalationStatus
+ }
+ }
+}
diff --git a/app/assets/javascripts/sidebar/queries/update_escalation_status.mutation.graphql b/app/assets/javascripts/sidebar/queries/update_escalation_status.mutation.graphql
new file mode 100644
index 00000000000..a4aff7968df
--- /dev/null
+++ b/app/assets/javascripts/sidebar/queries/update_escalation_status.mutation.graphql
@@ -0,0 +1,10 @@
+mutation updateEscalationStatus($projectPath: ID!, $status: IssueEscalationStatus!, $iid: String!) {
+ issueSetEscalationStatus(input: { projectPath: $projectPath, status: $status, iid: $iid }) {
+ errors
+ clientMutationId
+ issue {
+ id
+ escalationStatus
+ }
+ }
+}
diff --git a/app/assets/javascripts/sidebar/sidebar_bundle.js b/app/assets/javascripts/sidebar/sidebar_bundle.js
index 1be670f7590..74ab65e4e04 100644
--- a/app/assets/javascripts/sidebar/sidebar_bundle.js
+++ b/app/assets/javascripts/sidebar/sidebar_bundle.js
@@ -3,7 +3,17 @@ import Mediator from './sidebar_mediator';
export default (store) => {
const mediator = new Mediator(getSidebarOptions());
- mediator.fetch();
+ mediator
+ .fetch()
+ .then(() => {
+ if (window.gon?.features?.mrAttentionRequests) {
+ return import('~/attention_requests');
+ }
+
+ return null;
+ })
+ .then((module) => module?.initSideNavPopover())
+ .catch(() => {});
mountSidebar(mediator, store);
};
diff --git a/app/assets/javascripts/sidebar/sidebar_mediator.js b/app/assets/javascripts/sidebar/sidebar_mediator.js
index 4664bb56958..83fb8f31dfb 100644
--- a/app/assets/javascripts/sidebar/sidebar_mediator.js
+++ b/app/assets/javascripts/sidebar/sidebar_mediator.js
@@ -2,6 +2,7 @@ import Store from '~/sidebar/stores/sidebar_store';
import createFlash from '~/flash';
import { __, sprintf } from '~/locale';
import toast from '~/vue_shared/plugins/global_toast';
+import { refreshUserMergeRequestCounts } from '~/commons/nav/user_merge_requests';
import { visitUrl } from '../lib/utils/url_utility';
import Service from './services/sidebar_service';
@@ -125,6 +126,7 @@ export default class SidebarMediator {
this.store.updateReviewer(user.id, 'attention_requested');
this.store.updateAssignee(user.id, 'attention_requested');
+ refreshUserMergeRequestCounts();
callback();
} catch (error) {
callback();
diff --git a/app/assets/javascripts/single_file_diff.js b/app/assets/javascripts/single_file_diff.js
index d2841156e55..b7159fd6835 100644
--- a/app/assets/javascripts/single_file_diff.js
+++ b/app/assets/javascripts/single_file_diff.js
@@ -1,6 +1,7 @@
/* eslint-disable consistent-return */
import $ from 'jquery';
+import { loadingIconForLegacyJS } from '~/loading_icon_for_legacy_js';
import { spriteIcon } from '~/lib/utils/common_utils';
import FilesCommentButton from './files_comment_button';
import createFlash from './flash';
@@ -10,7 +11,7 @@ import { __ } from './locale';
import syntaxHighlight from './syntax_highlight';
const WRAPPER = '<div class="diff-content"></div>';
-const LOADING_HTML = '<span class="spinner"></span>';
+const LOADING_HTML = loadingIconForLegacyJS().outerHTML;
const ERROR_HTML = `<div class="nothing-here-block">${spriteIcon(
'warning-solid',
's16',
diff --git a/app/assets/javascripts/terraform/components/empty_state.vue b/app/assets/javascripts/terraform/components/empty_state.vue
index a5a613b7282..fd9177bef3f 100644
--- a/app/assets/javascripts/terraform/components/empty_state.vue
+++ b/app/assets/javascripts/terraform/components/empty_state.vue
@@ -16,7 +16,7 @@ export default {
},
computed: {
docsUrl() {
- return helpPagePath('user/infrastructure/terraform_state');
+ return helpPagePath('user/infrastructure/iac/terraform_state');
},
},
};
diff --git a/app/assets/javascripts/toggle_buttons.js b/app/assets/javascripts/toggle_buttons.js
deleted file mode 100644
index 5b85107991a..00000000000
--- a/app/assets/javascripts/toggle_buttons.js
+++ /dev/null
@@ -1,63 +0,0 @@
-import $ from 'jquery';
-import createFlash from './flash';
-import { parseBoolean } from './lib/utils/common_utils';
-import { __ } from './locale';
-
-/*
- example HAML:
- ```
- %button.js-project-feature-toggle.project-feature-toggle{ type: "button",
- class: "#{'is-checked' if enabled?}",
- 'aria-label': _('Toggle Kubernetes Cluster') }
- %input{ type: "hidden", class: 'js-project-feature-toggle-input', value: enabled? }
- ```
-*/
-
-function updateToggle(toggle, isOn) {
- toggle.classList.toggle('is-checked', isOn);
-}
-
-function onToggleClicked(toggle, input, clickCallback) {
- const previousIsOn = parseBoolean(input.value);
-
- // Visually change the toggle and start loading
- updateToggle(toggle, !previousIsOn);
- toggle.setAttribute('disabled', true);
- toggle.classList.toggle('is-loading', true);
-
- Promise.resolve(clickCallback(!previousIsOn, toggle))
- .then(() => {
- // Actually change the input value
- input.setAttribute('value', !previousIsOn);
- })
- .catch(() => {
- // Revert the visuals if something goes wrong
- updateToggle(toggle, previousIsOn);
- })
- .then(() => {
- // Remove the loading indicator in any case
- toggle.removeAttribute('disabled');
- toggle.classList.toggle('is-loading', false);
-
- $(input).trigger('trigger-change');
- })
- .catch(() => {
- createFlash({
- message: __('Something went wrong when toggling the button'),
- });
- });
-}
-
-export default function setupToggleButtons(container, clickCallback = () => {}) {
- const toggles = container.querySelectorAll('.js-project-feature-toggle');
-
- toggles.forEach((toggle) => {
- const input = toggle.querySelector('.js-project-feature-toggle-input');
- const isOn = parseBoolean(input.value);
-
- // Get the visible toggle in sync with the hidden input
- updateToggle(toggle, isOn);
-
- toggle.addEventListener('click', onToggleClicked.bind(null, toggle, input, clickCallback));
- });
-}
diff --git a/app/assets/javascripts/toggles/index.js b/app/assets/javascripts/toggles/index.js
index 046b9fc7dcd..5848b3a424c 100644
--- a/app/assets/javascripts/toggles/index.js
+++ b/app/assets/javascripts/toggles/index.js
@@ -8,16 +8,12 @@ export const initToggle = (el) => {
return false;
}
- const {
- name,
- isChecked,
- disabled,
- isLoading,
- label,
- help,
- labelPosition,
- ...dataset
- } = el.dataset;
+ const { name, id, isChecked, disabled, isLoading, label, help, labelPosition, ...dataset } =
+ el.dataset || {};
+
+ const dataAttrs = Object.fromEntries(
+ Object.entries(dataset).map(([key, value]) => [`data-${kebabCase(key)}`, value]),
+ );
return new Vue({
el,
@@ -50,9 +46,7 @@ export const initToggle = (el) => {
labelPosition,
},
class: el.className,
- attrs: Object.fromEntries(
- Object.entries(dataset).map(([key, value]) => [`data-${kebabCase(key)}`, value]),
- ),
+ attrs: { id, ...dataAttrs },
on: {
change: (newValue) => {
this.value = newValue;
diff --git a/app/assets/javascripts/tracking/dispatch_snowplow_event.js b/app/assets/javascripts/tracking/dispatch_snowplow_event.js
index bc9d7384ea4..7e596f5f36f 100644
--- a/app/assets/javascripts/tracking/dispatch_snowplow_event.js
+++ b/app/assets/javascripts/tracking/dispatch_snowplow_event.js
@@ -10,7 +10,8 @@ export function dispatchSnowplowEvent(
throw new Error('Tracking: no category provided for tracking.');
}
- const { label, property, value, extra = {} } = data;
+ const { label, property, extra = {} } = data;
+ let { value } = data;
const standardContext = getStandardContext({ extra });
const contexts = [standardContext];
@@ -19,5 +20,9 @@ export function dispatchSnowplowEvent(
contexts.push(data.context);
}
+ if (value !== undefined) {
+ value = Number(value);
+ }
+
return window.snowplow('trackStructEvent', category, action, label, property, value, contexts);
}
diff --git a/app/assets/javascripts/tracking/tracking.js b/app/assets/javascripts/tracking/tracking.js
index c26abc261ed..173eef0646b 100644
--- a/app/assets/javascripts/tracking/tracking.js
+++ b/app/assets/javascripts/tracking/tracking.js
@@ -10,6 +10,8 @@ import {
addReferrersCacheEntry,
} from './utils';
+const ALLOWED_URL_HASHES = ['#diff', '#note'];
+
export default class Tracking {
static queuedEvents = [];
static initialized = false;
@@ -183,7 +185,9 @@ export default class Tracking {
originalUrl: window.location.href,
});
- window.snowplow('setCustomUrl', pageLinks.url);
+ const appendHash = ALLOWED_URL_HASHES.some((prefix) => window.location.hash.startsWith(prefix));
+ const customUrl = `${pageUrl}${appendHash ? window.location.hash : ''}`;
+ window.snowplow('setCustomUrl', customUrl);
if (document.referrer) {
const node = referrers.find((links) => links.originalUrl === document.referrer);
diff --git a/app/assets/javascripts/users_select/index.js b/app/assets/javascripts/users_select/index.js
index 8ed92e6b948..656c851aa3d 100644
--- a/app/assets/javascripts/users_select/index.js
+++ b/app/assets/javascripts/users_select/index.js
@@ -210,7 +210,7 @@ function UsersSelect(currentUser, els, options = {}) {
return axios.put(issueURL, data).then(({ data }) => {
let user = {};
- let tooltipTitle = user.name;
+ let tooltipTitle;
$dropdown.trigger('loaded.gl.dropdown');
$loading.addClass('gl-display-none');
if (data.assignee) {
@@ -806,7 +806,9 @@ UsersSelect.prototype.renderRow = function (
</strong>
${
username
- ? `<span class="dropdown-menu-user-username gl-text-gray-400">${username}</span>`
+ ? `<span class="dropdown-menu-user-username gl-text-gray-400">${escape(
+ username,
+ )}</span>`
: ''
}
${this.renderApprovalRules(elsClassName, user.applicable_approval_rules)}
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/extensions/base.vue b/app/assets/javascripts/vue_merge_request_widget/components/extensions/base.vue
index a25b4ab54e5..684386883c8 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/extensions/base.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/extensions/base.vue
@@ -2,21 +2,20 @@
import {
GlButton,
GlLoadingIcon,
- GlLink,
- GlBadge,
GlSafeHtmlDirective,
GlTooltipDirective,
GlIntersectionObserver,
} from '@gitlab/ui';
import { once } from 'lodash';
import * as Sentry from '@sentry/browser';
+import { DynamicScroller, DynamicScrollerItem } from 'vendor/vue-virtual-scroller';
import api from '~/api';
import { sprintf, s__, __ } from '~/locale';
-import SmartVirtualList from '~/vue_shared/components/smart_virtual_list.vue';
import Poll from '~/lib/utils/poll';
import { EXTENSION_ICON_CLASS, EXTENSION_ICONS } from '../../constants';
import StatusIcon from './status_icon.vue';
import Actions from './actions.vue';
+import ChildContent from './child_content.vue';
import { generateText } from './utils';
export const LOADING_STATES = {
@@ -30,12 +29,12 @@ export default {
components: {
GlButton,
GlLoadingIcon,
- GlLink,
- GlBadge,
GlIntersectionObserver,
- SmartVirtualList,
StatusIcon,
Actions,
+ ChildContent,
+ DynamicScroller,
+ DynamicScrollerItem,
},
directives: {
SafeHtml: GlSafeHtmlDirective,
@@ -188,7 +187,7 @@ export default {
this.fetchFullData(this.$props)
.then((data) => {
this.loadingState = null;
- this.fullData = data;
+ this.fullData = data.map((x, i) => ({ id: i, ...x }));
})
.catch((e) => {
this.loadingState = LOADING_STATES.expandedError;
@@ -196,9 +195,6 @@ export default {
Sentry.captureException(e);
});
},
- isArray(arr) {
- return Array.isArray(arr);
- },
appear(index) {
if (index === this.fullData.length - 1) {
this.showFade = false;
@@ -281,80 +277,33 @@ export default {
<div v-if="isLoadingExpanded" class="report-block-container">
<gl-loading-icon size="sm" inline /> {{ __('Loading...') }}
</div>
- <smart-virtual-list
+ <dynamic-scroller
v-else-if="hasFullData"
- :length="fullData.length"
- :remain="20"
- :size="32"
- wtag="ul"
- wclass="report-block-list"
+ :items="fullData"
+ :min-item-size="32"
class="report-block-container gl-px-5 gl-py-0"
>
- <li
- v-for="(data, index) in fullData"
- :key="data.id"
- :class="{
- 'gl-border-b-solid gl-border-b-1 gl-border-gray-100': index !== fullData.length - 1,
- }"
- class="gl-py-3 gl-pl-7"
- data-testid="extension-list-item"
- >
- <div class="gl-w-full">
- <div v-if="data.header" class="gl-mb-2">
- <template v-if="isArray(data.header)">
- <component
- :is="headerI === 0 ? 'strong' : 'span'"
- v-for="(header, headerI) in data.header"
- :key="headerI"
- v-safe-html="generateText(header)"
- class="gl-display-block"
- />
- </template>
- <strong v-else v-safe-html="generateText(data.header)"></strong>
- </div>
- <div class="gl-display-flex">
- <status-icon
- v-if="data.icon"
- :icon-name="data.icon.name"
- :size="12"
- class="gl-pl-0"
- />
+ <template #default="{ item, index, active }">
+ <dynamic-scroller-item :item="item" :active="active" :class="{ active }">
+ <div
+ :class="{
+ 'gl-border-b-solid gl-border-b-1 gl-border-gray-100': index !== fullData.length - 1,
+ }"
+ class="gl-py-3 gl-pl-7"
+ data-testid="extension-list-item"
+ >
<gl-intersection-observer
:options="{ rootMargin: '100px', thresholds: 0.1 }"
class="gl-w-full"
@appear="appear(index)"
@disappear="disappear(index)"
>
- <div class="gl-flex-wrap gl-display-flex gl-w-full">
- <div class="gl-mr-4 gl-display-flex gl-align-items-center">
- <p v-safe-html="generateText(data.text)" class="gl-m-0"></p>
- </div>
- <div v-if="data.link">
- <gl-link :href="data.link.href">{{ data.link.text }}</gl-link>
- </div>
- <div v-if="data.supportingText">
- <p v-safe-html="generateText(data.supportingText)" class="gl-m-0"></p>
- </div>
- <gl-badge v-if="data.badge" :variant="data.badge.variant || 'info'">
- {{ data.badge.text }}
- </gl-badge>
-
- <actions
- :widget="$options.label || $options.name"
- :tertiary-buttons="data.actions"
- class="gl-ml-auto"
- />
- </div>
- <p
- v-if="data.subtext"
- v-safe-html="generateText(data.subtext)"
- class="gl-m-0 gl-font-sm"
- ></p>
+ <child-content :data="item" :widget-label="widgetLabel" :level="2" />
</gl-intersection-observer>
</div>
- </div>
- </li>
- </smart-virtual-list>
+ </dynamic-scroller-item>
+ </template>
+ </dynamic-scroller>
<div
:class="{ show: showFade }"
class="fade mr-extenson-scrim gl-absolute gl-left-0 gl-bottom-0 gl-w-full gl-h-7 gl-pointer-events-none"
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/extensions/child_content.vue b/app/assets/javascripts/vue_merge_request_widget/components/extensions/child_content.vue
new file mode 100644
index 00000000000..5f42c6c7acb
--- /dev/null
+++ b/app/assets/javascripts/vue_merge_request_widget/components/extensions/child_content.vue
@@ -0,0 +1,95 @@
+<script>
+import { GlBadge, GlLink, GlSafeHtmlDirective } from '@gitlab/ui';
+import StatusIcon from './status_icon.vue';
+import Actions from './actions.vue';
+import { generateText } from './utils';
+
+export default {
+ name: 'ChildContent',
+ components: {
+ GlBadge,
+ GlLink,
+ StatusIcon,
+ Actions,
+ },
+ directives: {
+ SafeHtml: GlSafeHtmlDirective,
+ },
+ props: {
+ data: {
+ type: Object,
+ required: true,
+ },
+ widgetLabel: {
+ type: String,
+ required: true,
+ },
+ level: {
+ type: Number,
+ required: true,
+ },
+ },
+ methods: {
+ isArray(arr) {
+ return Array.isArray(arr);
+ },
+ generateText,
+ },
+};
+</script>
+
+<template>
+ <div :class="{ 'gl-pl-6': level === 3 }" class="gl-w-full">
+ <div v-if="data.header" class="gl-mb-2">
+ <template v-if="isArray(data.header)">
+ <component
+ :is="headerI === 0 ? 'strong' : 'span'"
+ v-for="(header, headerI) in data.header"
+ :key="headerI"
+ v-safe-html="generateText(header)"
+ class="gl-display-block"
+ />
+ </template>
+ <strong v-else v-safe-html="generateText(data.header)"></strong>
+ </div>
+ <div class="gl-display-flex">
+ <status-icon v-if="data.icon" :icon-name="data.icon.name" :size="12" class="gl-pl-0" />
+ <div class="gl-w-full">
+ <div class="gl-flex-wrap gl-display-flex gl-w-full">
+ <div class="gl-mr-4 gl-display-flex gl-align-items-center">
+ <p v-safe-html="generateText(data.text)" class="gl-m-0"></p>
+ </div>
+ <div v-if="data.link">
+ <gl-link :href="data.link.href">{{ data.link.text }}</gl-link>
+ </div>
+ <div v-if="data.supportingText">
+ <p v-safe-html="generateText(data.supportingText)" class="gl-m-0"></p>
+ </div>
+ <gl-badge v-if="data.badge" :variant="data.badge.variant || 'info'">
+ {{ data.badge.text }}
+ </gl-badge>
+ <actions :widget="widgetLabel" :tertiary-buttons="data.actions" class="gl-ml-auto" />
+ </div>
+ <p
+ v-if="data.subtext"
+ v-safe-html="generateText(data.subtext)"
+ class="gl-m-0 gl-font-sm"
+ ></p>
+ </div>
+ </div>
+ <template v-if="data.children && level === 2">
+ <ul class="gl-m-0 gl-p-0 gl-list-style-none">
+ <li>
+ <child-content
+ v-for="childData in data.children"
+ :key="childData.id"
+ :data="childData"
+ :widget-label="widgetLabel"
+ :level="3"
+ data-testid="child-content"
+ />
+ </li>
+ </ul>
+ </template>
+ </div>
+</template>
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/mr_collapsible_extension.vue b/app/assets/javascripts/vue_merge_request_widget/components/mr_collapsible_extension.vue
index b75f2dce54e..f5667aee15b 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/mr_collapsible_extension.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/mr_collapsible_extension.vue
@@ -70,7 +70,9 @@ export default {
<template v-if="isCollapsed">
<slot name="header"></slot>
<gl-button
- variant="link"
+ category="tertiary"
+ variant="confirm"
+ size="small"
data-testid="mr-collapsible-title"
:disabled="isLoading"
:class="{ 'border-0': isLoading }"
@@ -81,7 +83,9 @@ export default {
</template>
<gl-button
v-else
- variant="link"
+ category="tertiary"
+ variant="confirm"
+ size="small"
data-testid="mr-collapsible-title"
:disabled="isLoading"
:class="{ 'border-0': isLoading }"
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_how_to_merge_modal.vue b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_how_to_merge_modal.vue
index 68cff1368af..b062833cdf8 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_how_to_merge_modal.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_how_to_merge_modal.vue
@@ -1,6 +1,7 @@
<script>
/* eslint-disable @gitlab/require-i18n-strings */
import { GlModal, GlLink, GlSprintf } from '@gitlab/ui';
+import { helpPagePath } from '~/helpers/help_page_helper';
import { escapeShellString } from '~/lib/utils/text_utility';
import { __ } from '~/locale';
import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
@@ -10,24 +11,26 @@ export default {
steps: {
step1: {
label: __('Step 1.'),
- help: __('Fetch and check out the branch for this merge request'),
+ help: __("Fetch and check out this merge request's feature branch:"),
},
step2: {
label: __('Step 2.'),
- help: __('Review the changes locally'),
+ help: __('Review the changes locally.'),
},
step3: {
label: __('Step 3.'),
- help: __('Merge the branch and fix any conflicts that come up'),
+ help: __(
+ 'Merge the feature branch into the target branch and fix any conflicts. %{linkStart}How do I fix them?%{linkEnd}',
+ ),
},
step4: {
label: __('Step 4.'),
- help: __('Push the result of the merge to GitLab'),
+ help: __('Push the target branch up to GitLab.'),
},
},
copyCommands: __('Copy commands'),
tip: __(
- '%{strongStart}Tip:%{strongEnd} You can also checkout merge requests locally by %{linkStart}following these guidelines%{linkEnd}',
+ '%{strongStart}Tip:%{strongEnd} You can also check out merge requests locally. %{linkStart}Learn more.%{linkEnd}',
),
title: __('Check out, review, and merge locally'),
},
@@ -74,6 +77,13 @@ export default {
default: null,
},
},
+ data() {
+ return {
+ resolveConflictsFromCli: helpPagePath('ee/user/project/merge_requests/conflicts.html', {
+ anchor: 'resolve-conflicts-from-the-command-line',
+ }),
+ };
+ },
computed: {
mergeInfo1() {
const escapedOriginBranch = escapeShellString(`origin/${this.sourceBranch}`);
@@ -138,7 +148,13 @@ export default {
<strong>
{{ $options.i18n.steps.step3.label }}
</strong>
- {{ $options.i18n.steps.step3.help }}
+ <gl-sprintf :message="$options.i18n.steps.step3.help">
+ <template #link="{ content }">
+ <gl-link class="gl-display-inline-block" :href="resolveConflictsFromCli">
+ {{ content }}
+ </gl-link>
+ </template>
+ </gl-sprintf>
</p>
<div class="gl-display-flex">
<pre class="gl-w-full" data-testid="how-to-merge-instructions">{{ mergeInfo2 }}</pre>
@@ -163,7 +179,7 @@ export default {
/>
</div>
<p v-if="reviewingDocsPath">
- <gl-sprintf :message="$options.i18n.tip">
+ <gl-sprintf data-testid="docs-tip" :message="$options.i18n.tip">
<template #strong="{ content }">
<strong>{{ content }}</strong>
</template>
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_related_links.vue b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_related_links.vue
index 730d11b1208..2cef37d5c2e 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_related_links.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_related_links.vue
@@ -1,5 +1,5 @@
<script>
-import { GlSafeHtmlDirective as SafeHtml } from '@gitlab/ui';
+import { GlSafeHtmlDirective as SafeHtml, GlLink } from '@gitlab/ui';
import { s__, n__ } from '~/locale';
import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
@@ -8,6 +8,9 @@ export default {
directives: {
SafeHtml,
},
+ components: {
+ GlLink,
+ },
mixins: [glFeatureFlagMixin()],
props: {
relatedLinks: {
@@ -37,6 +40,17 @@ export default {
return n__('mrWidget|Closes issue', 'mrWidget|Closes issues', this.relatedLinks.closingCount);
},
+ assignIssueText() {
+ if (this.relatedLinks.unassignedCount > 1) {
+ return s__('mrWidget|Assign yourself to these issues');
+ }
+ return s__('mrWidget|Assign yourself to this issue');
+ },
+ shouldShowAssignToMeLink() {
+ return (
+ this.relatedLinks.unassignedCount && this.relatedLinks.assignToMe && this.showAssignToMe
+ );
+ },
},
};
</script>
@@ -44,23 +58,28 @@ export default {
<section>
<p
v-if="relatedLinks.closing"
- :class="{ 'gl-display-line gl-m-0': glFeatures.restructuredMrWidget }"
+ :class="{ 'gl-display-inline gl-m-0': glFeatures.restructuredMrWidget }"
>
{{ closesText }}
<span v-safe-html="relatedLinks.closing"></span>
</p>
<p
v-if="relatedLinks.mentioned"
- :class="{ 'gl-display-line gl-m-0': glFeatures.restructuredMrWidget }"
+ :class="{ 'gl-display-inline gl-m-0': glFeatures.restructuredMrWidget }"
>
+ <span v-if="relatedLinks.closing && glFeatures.restructuredMrWidget">&middot;</span>
{{ n__('mrWidget|Mentions issue', 'mrWidget|Mentions issues', relatedLinks.mentionedCount) }}
<span v-safe-html="relatedLinks.mentioned"></span>
</p>
<p
- v-if="relatedLinks.assignToMe && showAssignToMe"
- :class="{ 'gl-display-line gl-m-0': glFeatures.restructuredMrWidget }"
+ v-if="shouldShowAssignToMeLink"
+ :class="{ 'gl-display-inline gl-m-0': glFeatures.restructuredMrWidget }"
>
- <span v-html="relatedLinks.assignToMe /* eslint-disable-line vue/no-v-html */"></span>
+ <span>
+ <gl-link rel="nofollow" data-method="post" :href="relatedLinks.assignToMe">{{
+ assignIssueText
+ }}</gl-link>
+ </span>
</p>
</section>
</template>
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/commit_message_dropdown.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/commit_message_dropdown.vue
index 73d75352cb5..5baeb309f79 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/states/commit_message_dropdown.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/states/commit_message_dropdown.vue
@@ -21,7 +21,9 @@ export default {
<gl-dropdown
right
text="Use an existing commit message"
- variant="link"
+ category="tertiary"
+ variant="confirm"
+ size="small"
class="mr-commit-dropdown"
>
<gl-dropdown-item
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/commits_header.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/commits_header.vue
index 5c4a526bcc3..400759aa086 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/states/commits_header.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/states/commits_header.vue
@@ -77,7 +77,7 @@ export default {
:target-branch="targetBranch"
/>
</span>
- <gl-button variant="link" class="modify-message-button">
+ <gl-button category="tertiary" variant="confirm" size="small" class="modify-message-button">
{{ modifyLinkMessage }}
</gl-button>
</span>
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_conflicts.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_conflicts.vue
index a2c9cfe53cc..7435f578852 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_conflicts.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_conflicts.vue
@@ -82,17 +82,8 @@ export default {
return this.mr.shouldBeRebased;
},
- sourceBranchProtected() {
- if (this.glFeatures.mergeRequestWidgetGraphql) {
- return this.stateData.sourceBranchProtected;
- }
-
- return this.mr.sourceBranchProtected;
- },
showResolveButton() {
- return (
- this.mr.conflictResolutionPath && this.canPushToSourceBranch && !this.sourceBranchProtected
- );
+ return this.mr.conflictResolutionPath && this.canPushToSourceBranch;
},
},
};
@@ -144,7 +135,7 @@ export default {
:size="glFeatures.restructuredMrWidget ? 'small' : 'medium'"
data-testid="merge-locally-button"
>
- {{ s__('mrWidget|Merge locally') }}
+ {{ s__('mrWidget|Resolve locally') }}
</gl-button>
</template>
</div>
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 bb0fb410d3e..ebdc8309cd5 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
@@ -3,13 +3,11 @@ import { GlButton, GlSkeletonLoader } from '@gitlab/ui';
import createFlash from '~/flash';
import { __ } from '~/locale';
import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
-import ActionsButton from '~/vue_shared/components/actions_button.vue';
import simplePoll from '../../../lib/utils/simple_poll';
import eventHub from '../../event_hub';
import mergeRequestQueryVariablesMixin from '../../mixins/merge_request_query_variables';
import rebaseQuery from '../../queries/states/rebase.query.graphql';
import statusIcon from '../mr_widget_status_icon.vue';
-import { REBASE_BUTTON_KEY, REBASE_WITHOUT_CI_BUTTON_KEY } from '../../constants';
export default {
name: 'MRWidgetRebase',
@@ -28,7 +26,6 @@ export default {
components: {
statusIcon,
GlSkeletonLoader,
- ActionsButton,
GlButton,
},
mixins: [glFeatureFlagMixin(), mergeRequestQueryVariablesMixin],
@@ -47,7 +44,6 @@ export default {
state: {},
isMakingRequest: false,
rebasingError: null,
- selectedRebaseAction: REBASE_BUTTON_KEY,
};
},
computed: {
@@ -93,28 +89,6 @@ export default {
fastForwardMergeText() {
return __('Merge blocked: the source branch must be rebased onto the target branch.');
},
- actions() {
- return [this.rebaseAction, this.rebaseWithoutCiAction].filter((action) => action);
- },
- rebaseAction() {
- return {
- key: REBASE_BUTTON_KEY,
- text: __('Rebase'),
- secondaryText: __('Rebases and triggers a pipeline'),
- attrs: {
- 'data-qa-selector': 'mr_rebase_button',
- },
- handle: () => this.rebase(),
- };
- },
- rebaseWithoutCiAction() {
- return {
- key: REBASE_WITHOUT_CI_BUTTON_KEY,
- text: __('Rebase without CI'),
- secondaryText: __('Performs a rebase but skips triggering a new pipeline'),
- handle: () => this.rebase({ skipCi: true }),
- };
- },
},
methods: {
rebase({ skipCi = false } = {}) {
@@ -138,8 +112,8 @@ export default {
}
});
},
- selectRebaseAction(key) {
- this.selectedRebaseAction = key;
+ rebaseWithoutCi() {
+ return this.rebase({ skipCi: true });
},
checkRebaseStatus(continuePolling, stopPolling) {
this.service
@@ -198,10 +172,10 @@ export default {
>
<div
v-if="!rebaseInProgress && canPushToSourceBranch && !isMakingRequest"
- class="accept-merge-holder clearfix js-toggle-container accept-action media space-children"
+ class="accept-merge-holder clearfix js-toggle-container accept-action media space-children gl-align-items-center"
>
<gl-button
- v-if="!glFeatures.restructuredMrWidget && !showRebaseWithoutCi"
+ v-if="!glFeatures.restructuredMrWidget"
:loading="isMakingRequest"
variant="confirm"
data-qa-selector="mr_rebase_button"
@@ -210,14 +184,16 @@ export default {
>
{{ __('Rebase') }}
</gl-button>
- <actions-button
+ <gl-button
v-if="!glFeatures.restructuredMrWidget && showRebaseWithoutCi"
- :actions="actions"
- :selected-key="selectedRebaseAction"
+ :loading="isMakingRequest"
variant="confirm"
- category="primary"
- @select="selectRebaseAction"
- />
+ category="secondary"
+ data-testid="rebase-without-ci-button"
+ @click="rebaseWithoutCi"
+ >
+ {{ __('Rebase without pipeline') }}
+ </gl-button>
<span
v-if="!rebasingError"
:class="{ 'gl-ml-0! gl-text-body!': glFeatures.restructuredMrWidget }"
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/ready_to_merge.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/ready_to_merge.vue
index bc094501e89..4f8faeb877f 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/states/ready_to_merge.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/states/ready_to_merge.vue
@@ -82,6 +82,13 @@ export default {
};
this.loading = false;
+ if (!this.commitMessageIsTouched) {
+ this.commitMessage = this.state.defaultMergeCommitMessage;
+ }
+ if (!this.squashCommitMessageIsTouched) {
+ this.squashCommitMessage = this.state.defaultSquashCommitMessage;
+ }
+
if (this.state.mergeTrainsCount !== null && this.state.mergeTrainsCount !== undefined) {
this.initPolling();
}
@@ -133,9 +140,11 @@ export default {
isMakingRequest: false,
isMergingImmediately: false,
commitMessage: this.mr.commitMessage,
+ commitMessageIsTouched: false,
squashBeforeMerge: this.mr.squashIsSelected,
isSquashReadOnly: this.mr.squashIsReadonly,
squashCommitMessage: this.mr.squashCommitMessage,
+ squashCommitMessageIsTouched: false,
isPipelineFailedModalVisibleMergeTrain: false,
isPipelineFailedModalVisibleNormalMerge: false,
editCommitMessage: false,
@@ -295,13 +304,6 @@ export default {
return enableSquashBeforeMerge;
},
- shouldShowMergeControls() {
- if (this.glFeatures.restructuredMrWidget) {
- return this.restructuredWidgetShowMergeButtons;
- }
-
- return this.isMergeAllowed || this.isAutoMergeAvailable;
- },
shouldShowSquashEdit() {
return this.squashBeforeMerge && this.shouldShowSquashBeforeMerge;
},
@@ -472,6 +474,14 @@ export default {
});
});
},
+ setCommitMessage(val) {
+ this.commitMessage = val;
+ this.commitMessageIsTouched = true;
+ },
+ setSquashCommitMessage(val) {
+ this.squashCommitMessage = val;
+ this.squashCommitMessageIsTouched = true;
+ },
},
i18n: {
mergeCommitTemplateHintText: s__(
@@ -637,21 +647,23 @@ export default {
>
<commit-edit
v-if="shouldShowSquashEdit"
- v-model="squashCommitMessage"
+ :value="squashCommitMessage"
:label="__('Squash commit message')"
input-id="squash-message-edit"
class="gl-m-0! gl-p-0!"
+ @input="setSquashCommitMessage"
>
<template #header>
- <commit-message-dropdown v-model="squashCommitMessage" :commits="commits" />
+ <commit-message-dropdown :commits="commits" @input="setSquashCommitMessage" />
</template>
</commit-edit>
<commit-edit
v-if="shouldShowMergeEdit"
- v-model="commitMessage"
+ :value="commitMessage"
:label="__('Merge commit message')"
input-id="merge-message-edit"
class="gl-m-0! gl-p-0!"
+ @input="setCommitMessage"
/>
<li class="gl-m-0! gl-p-0!">
<p class="form-text text-muted">
@@ -755,20 +767,22 @@ export default {
<ul class="border-top content-list commits-list flex-list">
<commit-edit
v-if="shouldShowSquashEdit"
- v-model="squashCommitMessage"
+ :value="squashCommitMessage"
:label="__('Squash commit message')"
input-id="squash-message-edit"
squash
+ @input="setSquashCommitMessage"
>
<template #header>
- <commit-message-dropdown v-model="squashCommitMessage" :commits="commits" />
+ <commit-message-dropdown :commits="commits" @input="setSquashCommitMessage" />
</template>
</commit-edit>
<commit-edit
v-if="shouldShowMergeEdit"
- v-model="commitMessage"
+ :value="commitMessage"
:label="__('Merge commit message')"
input-id="merge-message-edit"
+ @input="setCommitMessage"
/>
<li>
<p class="form-text text-muted">
diff --git a/app/assets/javascripts/vue_merge_request_widget/constants.js b/app/assets/javascripts/vue_merge_request_widget/constants.js
index d337a554663..533bb38a88c 100644
--- a/app/assets/javascripts/vue_merge_request_widget/constants.js
+++ b/app/assets/javascripts/vue_merge_request_widget/constants.js
@@ -166,6 +166,3 @@ export const EXTENSION_SUMMARY_FAILED_CLASS = 'gl-text-red-500';
export const EXTENSION_SUMMARY_NEUTRAL_CLASS = 'gl-text-gray-700';
export { STATE_MACHINE };
-
-export const REBASE_BUTTON_KEY = 'rebase';
-export const REBASE_WITHOUT_CI_BUTTON_KEY = 'rebaseWithoutCi';
diff --git a/app/assets/javascripts/vue_merge_request_widget/extensions/code_quality/index.js b/app/assets/javascripts/vue_merge_request_widget/extensions/code_quality/index.js
new file mode 100644
index 00000000000..d32db50874c
--- /dev/null
+++ b/app/assets/javascripts/vue_merge_request_widget/extensions/code_quality/index.js
@@ -0,0 +1,123 @@
+import { n__, s__, sprintf } from '~/locale';
+import axios from '~/lib/utils/axios_utils';
+import { EXTENSION_ICONS } from '~/vue_merge_request_widget/constants';
+import { SEVERITY_ICONS_EXTENSION } from '~/reports/codequality_report/constants';
+import { parseCodeclimateMetrics } from '~/reports/codequality_report/store/utils/codequality_parser';
+import { capitalizeFirstCharacter } from '~/lib/utils/text_utility';
+
+export default {
+ name: 'WidgetCodeQuality',
+ props: ['codeQuality', 'blobPath'],
+ i18n: {
+ label: s__('ciReport|Code Quality'),
+ loading: s__('ciReport|Code Quality test metrics results are being parsed'),
+ error: s__('ciReport|Code Quality failed loading results'),
+ },
+ expandEvent: 'i_testing_code_quality_widget_total',
+ computed: {
+ summary() {
+ const { newErrors, resolvedErrors, errorSummary } = this.collapsedData;
+ if (errorSummary.errored >= 1 && errorSummary.resolved >= 1) {
+ const improvements = sprintf(
+ n__(
+ '%{strongOpen}%{errors}%{strongClose} point',
+ '%{strongOpen}%{errors}%{strongClose} points',
+ resolvedErrors.length,
+ ),
+ {
+ errors: resolvedErrors.length,
+ strongOpen: '<strong>',
+ strongClose: '</strong>',
+ },
+ false,
+ );
+
+ const degradations = sprintf(
+ n__(
+ '%{strongOpen}%{errors}%{strongClose} point',
+ '%{strongOpen}%{errors}%{strongClose} points',
+ newErrors.length,
+ ),
+ { errors: newErrors.length, strongOpen: '<strong>', strongClose: '</strong>' },
+ false,
+ );
+ return sprintf(
+ s__(`ciReport|Code Quality improved on ${improvements} and degraded on ${degradations}.`),
+ );
+ } else if (errorSummary.resolved >= 1) {
+ const improvements = n__('%d point', '%d points', resolvedErrors.length);
+ return sprintf(s__(`ciReport|Code Quality improved on ${improvements}.`));
+ } else if (errorSummary.errored >= 1) {
+ const degradations = n__('%d point', '%d points', newErrors.length);
+ return sprintf(s__(`ciReport|Code Quality degraded on ${degradations}.`));
+ }
+ return s__(`ciReport|No changes to Code Quality.`);
+ },
+ statusIcon() {
+ if (this.collapsedData.errorSummary?.errored >= 1) {
+ return EXTENSION_ICONS.warning;
+ }
+ return EXTENSION_ICONS.success;
+ },
+ },
+ methods: {
+ fetchCollapsedData() {
+ return Promise.all([this.fetchReport(this.codeQuality)]).then((values) => {
+ return {
+ resolvedErrors: parseCodeclimateMetrics(
+ values[0].resolved_errors,
+ this.blobPath.head_path,
+ ),
+ newErrors: parseCodeclimateMetrics(values[0].new_errors, this.blobPath.head_path),
+ existingErrors: parseCodeclimateMetrics(
+ values[0].existing_errors,
+ this.blobPath.head_path,
+ ),
+ errorSummary: values[0].summary,
+ };
+ });
+ },
+ fetchFullData() {
+ const fullData = [];
+
+ this.collapsedData.newErrors.map((e) => {
+ return fullData.push({
+ text: `${capitalizeFirstCharacter(e.severity)} - ${e.description}`,
+ subtext: sprintf(
+ s__(`ciReport|in %{open_link}${e.file_path}:${e.line}%{close_link}`),
+ {
+ open_link: `<a class="gl-text-decoration-underline" href="${e.urlPath}">`,
+ close_link: '</a>',
+ },
+ false,
+ ),
+ icon: {
+ name: SEVERITY_ICONS_EXTENSION[e.severity],
+ },
+ });
+ });
+
+ this.collapsedData.resolvedErrors.map((e) => {
+ return fullData.push({
+ text: `${capitalizeFirstCharacter(e.severity)} - ${e.description}`,
+ subtext: sprintf(
+ s__(`ciReport|in %{open_link}${e.file_path}:${e.line}%{close_link}`),
+ {
+ open_link: `<a class="gl-text-decoration-underline" href="${e.urlPath}">`,
+ close_link: '</a>',
+ },
+ false,
+ ),
+ icon: {
+ name: SEVERITY_ICONS_EXTENSION[e.severity],
+ },
+ });
+ });
+
+ return Promise.resolve(fullData);
+ },
+ fetchReport(endpoint) {
+ return axios.get(endpoint).then((res) => res.data);
+ },
+ },
+};
diff --git a/app/assets/javascripts/vue_merge_request_widget/extensions/issues.js b/app/assets/javascripts/vue_merge_request_widget/extensions/issues.js
index 4aeebf095c4..e52f2c2c666 100644
--- a/app/assets/javascripts/vue_merge_request_widget/extensions/issues.js
+++ b/app/assets/javascripts/vue_merge_request_widget/extensions/issues.js
@@ -88,6 +88,16 @@ export default {
// text: 'Link text', // Required: Text to be used inside the link
// },
actions: [{ text: 'Full report', href: 'https://gitlab.com', target: '_blank' }],
+ children: [
+ {
+ id: `child-${issue.id}`,
+ header: 'New',
+ text: '%{critical_start}1 Critical%{critical_end}',
+ icon: {
+ name: EXTENSION_ICONS.error,
+ },
+ },
+ ],
}));
});
},
diff --git a/app/assets/javascripts/vue_merge_request_widget/mixins/ready_to_merge.js b/app/assets/javascripts/vue_merge_request_widget/mixins/ready_to_merge.js
index 247a3711fc8..627ddb0445e 100644
--- a/app/assets/javascripts/vue_merge_request_widget/mixins/ready_to_merge.js
+++ b/app/assets/javascripts/vue_merge_request_widget/mixins/ready_to_merge.js
@@ -1,8 +1,6 @@
import { __ } from '~/locale';
-export const MERGE_DISABLED_TEXT = __(
- 'Merge blocked: all merge request dependencies must be merged or closed.',
-);
+export const MERGE_DISABLED_TEXT = __('You can only merge once the items above are resolved.');
export const MERGE_DISABLED_SKIPPED_PIPELINE_TEXT = __(
"Merge blocked: pipeline must succeed. It's waiting for a manual job to continue.",
);
@@ -22,6 +20,13 @@ export default {
this.mr.preventMerge,
);
},
+ shouldShowMergeControls() {
+ if (this.glFeatures.restructuredMrWidget) {
+ return this.restructuredWidgetShowMergeButtons;
+ }
+
+ return this.isMergeAllowed || this.isAutoMergeAvailable;
+ },
mergeDisabledText() {
if (this.pipeline?.status === PIPELINE_SKIPPED_STATUS) {
return MERGE_DISABLED_SKIPPED_PIPELINE_TEXT;
diff --git a/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue b/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue
index 11de58aa344..965746e79fb 100644
--- a/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/mr_widget_options.vue
@@ -46,6 +46,7 @@ import mergeRequestQueryVariablesMixin from './mixins/merge_request_query_variab
import getStateQuery from './queries/get_state.query.graphql';
import terraformExtension from './extensions/terraform';
import accessibilityExtension from './extensions/accessibility';
+import codeQualityExtension from './extensions/code_quality';
export default {
// False positive i18n lint: https://gitlab.com/gitlab-org/frontend/eslint-plugin-i18n/issues/25
@@ -241,6 +242,11 @@ export default {
this.registerTerraformPlans();
}
},
+ shouldRenderCodeQuality(newVal) {
+ if (newVal) {
+ this.registerCodeQualityExtension();
+ }
+ },
shouldShowAccessibilityReport(newVal) {
if (newVal) {
this.registerAccessibilityExtension();
@@ -352,6 +358,8 @@ export default {
return Promise.resolve();
},
initPolling() {
+ if (this.startingPollInterval <= 0) return;
+
this.pollingInterval = new SmartInterval({
callback: this.checkStatus,
startingInterval: this.startingPollInterval,
@@ -435,10 +443,10 @@ export default {
notify.notifyMe(title, message, this.mr.gitlabLogo);
},
resumePolling() {
- this.pollingInterval.resume();
+ this.pollingInterval?.resume();
},
stopPolling() {
- this.pollingInterval.stopTimer();
+ this.pollingInterval?.stopTimer();
},
bindEventHubListeners() {
eventHub.$on('MRWidgetUpdateRequested', (cb) => {
@@ -489,6 +497,11 @@ export default {
registerExtension(accessibilityExtension);
}
},
+ registerCodeQualityExtension() {
+ if (this.shouldRenderCodeQuality && this.shouldShowExtension) {
+ registerExtension(codeQualityExtension);
+ }
+ },
},
};
</script>
@@ -544,7 +557,7 @@ export default {
</div>
<extensions-container :mr="mr" />
<grouped-codequality-reports-app
- v-if="shouldRenderCodeQuality"
+ v-if="shouldRenderCodeQuality && !shouldShowExtension"
:head-blob-path="mr.headBlobPath"
:base-blob-path="mr.baseBlobPath"
:codequality-reports-path="mr.codequalityReportsPath"
@@ -574,7 +587,7 @@ export default {
/>
<grouped-accessibility-reports-app
- v-if="shouldShowAccessibilityReport"
+ v-if="shouldShowAccessibilityReport && !shouldShowExtension"
:endpoint="mr.accessibilityReportPath"
/>
diff --git a/app/assets/javascripts/vue_merge_request_widget/queries/states/ready_to_merge.fragment.graphql b/app/assets/javascripts/vue_merge_request_widget/queries/states/ready_to_merge.fragment.graphql
index d85794f7245..99e6f4e9beb 100644
--- a/app/assets/javascripts/vue_merge_request_widget/queries/states/ready_to_merge.fragment.graphql
+++ b/app/assets/javascripts/vue_merge_request_widget/queries/states/ready_to_merge.fragment.graphql
@@ -1,9 +1,11 @@
fragment ReadyToMerge on Project {
+ __typename
id
onlyAllowMergeIfPipelineSucceeds
mergeRequestsFfOnlyEnabled
squashReadOnly
mergeRequest(iid: $iid) {
+ __typename
id
autoMergeEnabled
shouldRemoveSourceBranch
diff --git a/app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js b/app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js
index 5378dabf638..eb07609d5d6 100644
--- a/app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js
+++ b/app/assets/javascripts/vue_merge_request_widget/stores/mr_widget_store.js
@@ -32,9 +32,15 @@ export default class MergeRequestStore {
this.setPaths(data);
this.setData(data);
+ this.initCodeQualityReport(data);
this.setGitpodData(data);
}
+ initCodeQualityReport(data) {
+ this.blobPath = data.blob_path;
+ this.codeQuality = data.codequality_reports_path;
+ }
+
setData(data, isRebased) {
this.initApprovals();
@@ -82,14 +88,16 @@ export default class MergeRequestStore {
const { closing } = links;
const mentioned = links.mentioned_but_not_closing;
const assignToMe = links.assign_to_closing;
+ const unassignedCount = links.assign_to_closing_count;
- if (closing || mentioned || assignToMe) {
+ if (closing || mentioned || unassignedCount) {
this.relatedLinks = {
closing,
mentioned,
assignToMe,
closingCount: links.closing_count,
mentionedCount: links.mentioned_count,
+ unassignedCount: links.assign_to_closing_count,
};
}
}
diff --git a/app/assets/javascripts/vue_shared/components/awards_list.vue b/app/assets/javascripts/vue_shared/components/awards_list.vue
index b6010d4b70c..96970f4ce2f 100644
--- a/app/assets/javascripts/vue_shared/components/awards_list.vue
+++ b/app/assets/javascripts/vue_shared/components/awards_list.vue
@@ -199,12 +199,15 @@ export default {
<div v-if="canAwardEmoji" class="award-menu-holder gl-my-2">
<emoji-picker
v-if="glFeatures.improvedEmojiPicker"
+ v-gl-tooltip.viewport
+ :title="__('Add reaction')"
:toggle-class="['add-reaction-button btn-icon gl-relative!', { 'is-active': isMenuOpen }]"
@click="handleAward"
@shown="setIsMenuOpen(true)"
@hidden="setIsMenuOpen(false)"
>
<template #button-content>
+ <span class="gl-sr-only">{{ __('Add reaction') }}</span>
<span class="reaction-control-icon reaction-control-icon-neutral">
<gl-icon name="slight-smile" />
</span>
diff --git a/app/assets/javascripts/vue_shared/components/color_picker/color_picker.vue b/app/assets/javascripts/vue_shared/components/color_picker/color_picker.vue
index 7563c35dfc8..7a166f9a3e4 100644
--- a/app/assets/javascripts/vue_shared/components/color_picker/color_picker.vue
+++ b/app/assets/javascripts/vue_shared/components/color_picker/color_picker.vue
@@ -7,6 +7,7 @@
:invalid-feedback="__('Please enter a valid hex (#RRGGBB or #RGB) color value')"
:label="__('Background color')"
:value="#FF0000"
+ :suggestedColors="{ '#ff0000': 'Red', '#808080': 'Gray' }",
state="isValidColor"
/>
*/
@@ -48,6 +49,11 @@ export default {
required: false,
default: null,
},
+ suggestedColors: {
+ type: Object,
+ required: false,
+ default: () => gon.suggested_label_colors,
+ },
},
computed: {
description() {
@@ -55,9 +61,6 @@ export default {
? this.$options.i18n.fullDescription
: this.$options.i18n.shortDescription;
},
- suggestedColors() {
- return gon.suggested_label_colors;
- },
previewColor() {
if (this.state) {
return { backgroundColor: this.value };
diff --git a/app/assets/javascripts/vue_shared/components/content_transition.vue b/app/assets/javascripts/vue_shared/components/content_transition.vue
new file mode 100644
index 00000000000..446610d6b91
--- /dev/null
+++ b/app/assets/javascripts/vue_shared/components/content_transition.vue
@@ -0,0 +1,32 @@
+<script>
+export default {
+ props: {
+ currentSlot: {
+ type: String,
+ required: true,
+ },
+ slots: {
+ type: Array,
+ required: true,
+ },
+ transitionName: {
+ type: String,
+ required: true,
+ },
+ },
+ methods: {
+ shouldShow(key) {
+ return this.currentSlot === key;
+ },
+ },
+};
+</script>
+<template>
+ <div>
+ <transition v-for="{ key, attributes } in slots" :key="key" :name="transitionName">
+ <div v-show="shouldShow(key)" v-bind="attributes">
+ <slot :name="key"></slot>
+ </div>
+ </transition>
+ </div>
+</template>
diff --git a/app/assets/javascripts/vue_shared/components/dropdown/dropdown_widget/dropdown_widget.vue b/app/assets/javascripts/vue_shared/components/dropdown/dropdown_widget/dropdown_widget.vue
index 153b0981813..2a79ccc2648 100644
--- a/app/assets/javascripts/vue_shared/components/dropdown/dropdown_widget/dropdown_widget.vue
+++ b/app/assets/javascripts/vue_shared/components/dropdown/dropdown_widget/dropdown_widget.vue
@@ -1,22 +1,28 @@
<script>
import {
+ GlIcon,
GlLoadingIcon,
GlDropdown,
GlDropdownForm,
GlDropdownDivider,
GlDropdownItem,
+ GlDropdownSectionHeader,
GlSearchBoxByType,
} from '@gitlab/ui';
import { __ } from '~/locale';
+import TooltipOnTruncate from '~/vue_shared/components/tooltip_on_truncate/tooltip_on_truncate.vue';
export default {
components: {
+ GlIcon,
GlLoadingIcon,
GlDropdown,
GlDropdownForm,
GlDropdownDivider,
GlDropdownItem,
+ GlDropdownSectionHeader,
GlSearchBoxByType,
+ TooltipOnTruncate,
},
props: {
selectText: {
@@ -39,6 +45,11 @@ export default {
required: false,
default: () => [],
},
+ groupedOptions: {
+ type: Array,
+ required: false,
+ default: () => [],
+ },
isLoading: {
type: Boolean,
required: false,
@@ -79,11 +90,7 @@ export default {
if (Array.isArray(this.selected)) {
return this.selected.some((label) => label.title === option.title);
}
- return (
- this.selected &&
- ((option.name && this.selected.name === option.name) ||
- (option.title && this.selected.title === option.title))
- );
+ return this.selected && option.id && this.selected.id === option.id;
},
showDropdown() {
this.$refs.dropdown.show();
@@ -101,6 +108,9 @@ export default {
// TODO: this has some knowledge of the context where the component is used. We could later rework it.
return option.username || null;
},
+ optionKey(option) {
+ return option.key ? option.key : option.id;
+ },
},
i18n: {
noMatchingResults: __('No matching results'),
@@ -154,10 +164,10 @@ export default {
</template>
<gl-dropdown-item
v-for="option in options"
- :key="option.id"
+ :key="optionKey(option)"
:is-checked="isSelected(option)"
- :is-check-centered="true"
- :is-check-item="true"
+ is-check-centered
+ is-check-item
:avatar-url="avatarUrl(option)"
:secondary-text="secondaryText(option)"
data-testid="unselected-option"
@@ -167,6 +177,36 @@ export default {
{{ option.title }}
</slot>
</gl-dropdown-item>
+ <template v-for="(optionGroup, index) in groupedOptions">
+ <gl-dropdown-divider v-if="index !== 0" :key="index" />
+ <gl-dropdown-section-header :key="optionGroup.id">
+ <div class="gl-display-flex gl-max-w-full">
+ <tooltip-on-truncate
+ :title="optionGroup.title"
+ class="gl-text-truncate gl-flex-grow-1"
+ >
+ {{ optionGroup.title }}
+ </tooltip-on-truncate>
+ <span v-if="optionGroup.secondaryText" class="gl-float-right gl-font-weight-normal">
+ <gl-icon name="clock" class="gl-mr-2" />
+ {{ optionGroup.secondaryText }}
+ </span>
+ </div>
+ </gl-dropdown-section-header>
+ <gl-dropdown-item
+ v-for="option in optionGroup.options"
+ :key="optionKey(option)"
+ :is-checked="isSelected(option)"
+ is-check-centered
+ is-check-item
+ data-testid="unselected-option"
+ @click="selectOption(option)"
+ >
+ <slot name="item" :item="option">
+ {{ option.title }}
+ </slot>
+ </gl-dropdown-item>
+ </template>
<gl-dropdown-item v-if="noOptionsFound" class="gl-pl-6!">
{{ $options.i18n.noMatchingResults }}
</gl-dropdown-item>
diff --git a/app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/base_token.vue b/app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/base_token.vue
index 157068b2c0f..e7923e0b55e 100644
--- a/app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/base_token.vue
+++ b/app/assets/javascripts/vue_shared/components/filtered_search_bar/tokens/base_token.vue
@@ -76,9 +76,10 @@ export default {
},
data() {
return {
+ hasFetched: false, // use this to avoid flash of `No suggestions found` before fetching
searchKey: '',
recentSuggestions: this.config.recentSuggestionsStorageKey
- ? getRecentlyUsedSuggestions(this.config.recentSuggestionsStorageKey)
+ ? getRecentlyUsedSuggestions(this.config.recentSuggestionsStorageKey) ?? []
: [],
};
},
@@ -86,6 +87,9 @@ export default {
isRecentSuggestionsEnabled() {
return Boolean(this.config.recentSuggestionsStorageKey);
},
+ suggestionsEnabled() {
+ return !this.config.suggestionsDisabled;
+ },
recentTokenIds() {
return this.recentSuggestions.map((tokenValue) => tokenValue[this.valueIdentifier]);
},
@@ -134,17 +138,6 @@ export default {
showAvailableSuggestions() {
return this.availableSuggestions.length > 0;
},
- showSuggestions() {
- // These conditions must match the template under `#suggestions` slot
- // See https://gitlab.com/gitlab-org/gitlab/-/merge_requests/65817#note_632619411
- return (
- this.showDefaultSuggestions ||
- this.showRecentSuggestions ||
- this.showPreloadedSuggestions ||
- this.suggestionsLoading ||
- this.showAvailableSuggestions
- );
- },
searchTerm() {
return this.searchBy && this.activeTokenValue
? this.activeTokenValue[this.searchBy]
@@ -161,6 +154,13 @@ export default {
}
},
},
+ suggestionsLoading: {
+ handler(loading) {
+ if (loading) {
+ this.hasFetched = true;
+ }
+ },
+ },
},
methods: {
handleInput: debounce(function debouncedSearch({ data, operator }) {
@@ -216,7 +216,7 @@ export default {
<template #view="viewTokenProps">
<slot name="view" :view-token-props="{ ...viewTokenProps, activeTokenValue }"></slot>
</template>
- <template v-if="showSuggestions" #suggestions>
+ <template v-if="suggestionsEnabled" #suggestions>
<template v-if="showDefaultSuggestions">
<gl-filtered-search-suggestion
v-for="token in availableDefaultSuggestions"
@@ -238,12 +238,13 @@ export default {
:suggestions="preloadedSuggestions"
></slot>
<gl-loading-icon v-if="suggestionsLoading" size="sm" />
+ <template v-else-if="showAvailableSuggestions">
+ <slot name="suggestions-list" :suggestions="availableSuggestions"></slot>
+ </template>
<gl-dropdown-text v-else-if="showNoMatchesText">
{{ __('No matches found') }}
</gl-dropdown-text>
- <template v-else>
- <slot name="suggestions-list" :suggestions="availableSuggestions"></slot>
- </template>
+ <gl-dropdown-text v-else-if="hasFetched">{{ __('No suggestions found') }}</gl-dropdown-text>
</template>
</gl-filtered-search-token>
</template>
diff --git a/app/assets/javascripts/vue_shared/components/markdown/field.vue b/app/assets/javascripts/vue_shared/components/markdown/field.vue
index cbf38984e23..e1020ce656b 100644
--- a/app/assets/javascripts/vue_shared/components/markdown/field.vue
+++ b/app/assets/javascripts/vue_shared/components/markdown/field.vue
@@ -48,6 +48,11 @@ export default {
required: false,
default: '',
},
+ enablePreview: {
+ type: Boolean,
+ required: false,
+ default: true,
+ },
addSpacingClasses: {
type: Boolean,
required: false,
@@ -113,6 +118,7 @@ export default {
markdownPreviewLoading: false,
previewMarkdown: false,
suggestions: this.note.suggestions || [],
+ debouncedFetchMarkdownLoading: false,
};
},
computed: {
@@ -198,12 +204,22 @@ export default {
const justRemovedAll = hadAll && !hasAll;
if (justAddedAll) {
+ this.debouncedFetchMarkdownLoading = false;
this.debouncedFetchMarkdown();
} else if (justRemovedAll) {
+ this.debouncedFetchMarkdownLoading = true;
this.referencedUsers = [];
}
},
},
+ enablePreview: {
+ immediate: true,
+ handler(newVal) {
+ if (!newVal) {
+ this.showWriteTab();
+ }
+ },
+ },
},
mounted() {
// GLForm class handles all the toolbar buttons
@@ -271,7 +287,12 @@ export default {
},
debouncedFetchMarkdown: debounce(function debouncedFetchMarkdown() {
- return this.fetchMarkdown();
+ return this.fetchMarkdown().then(() => {
+ if (this.debouncedFetchMarkdownLoading) {
+ this.referencedUsers = [];
+ this.debouncedFetchMarkdownLoading = false;
+ }
+ });
}, 400),
renderMarkdown(data = {}) {
@@ -301,6 +322,7 @@ export default {
:preview-markdown="previewMarkdown"
:line-content="lineContent"
:can-suggest="canSuggest"
+ :enable-preview="enablePreview"
:show-suggest-popover="showSuggestPopover"
:suggestion-start-index="suggestionsStartIndex"
data-testid="markdownHeader"
diff --git a/app/assets/javascripts/vue_shared/components/markdown/header.vue b/app/assets/javascripts/vue_shared/components/markdown/header.vue
index 3b99afa9e3d..13189670e17 100644
--- a/app/assets/javascripts/vue_shared/components/markdown/header.vue
+++ b/app/assets/javascripts/vue_shared/components/markdown/header.vue
@@ -1,7 +1,13 @@
<script>
import { GlPopover, GlButton, GlTooltipDirective, GlTabs, GlTab } from '@gitlab/ui';
import $ from 'jquery';
-import { keysFor, BOLD_TEXT, ITALIC_TEXT, LINK_TEXT } from '~/behaviors/shortcuts/keybindings';
+import {
+ keysFor,
+ BOLD_TEXT,
+ ITALIC_TEXT,
+ STRIKETHROUGH_TEXT,
+ LINK_TEXT,
+} from '~/behaviors/shortcuts/keybindings';
import { getSelectedFragment } from '~/lib/utils/common_utils';
import { s__, __ } from '~/locale';
import { CopyAsGFM } from '../../../behaviors/markdown/copy_as_gfm';
@@ -43,6 +49,11 @@ export default {
required: false,
default: 0,
},
+ enablePreview: {
+ type: Boolean,
+ required: false,
+ default: true,
+ },
},
data() {
return {
@@ -144,6 +155,7 @@ export default {
shortcuts: {
bold: keysFor(BOLD_TEXT),
italic: keysFor(ITALIC_TEXT),
+ strikethrough: keysFor(STRIKETHROUGH_TEXT),
link: keysFor(LINK_TEXT),
},
i18n: {
@@ -164,6 +176,7 @@ export default {
@click="writeMarkdownTab($event)"
/>
<gl-tab
+ v-if="enablePreview"
title-link-class="gl-pt-3 gl-px-3 js-md-preview-button"
:title="$options.i18n.previewTabTitle"
:active="previewMarkdown"
@@ -194,6 +207,16 @@ export default {
icon="italic"
/>
<toolbar-button
+ tag="~~"
+ :button-title="
+ sprintf(s__('MarkdownEditor|Add strikethrough text (%{modifierKey}⇧X)'), {
+ modifierKey,
+ })
+ "
+ :shortcuts="$options.shortcuts.strikethrough"
+ icon="strikethrough"
+ />
+ <toolbar-button
:prepend="true"
:tag="tag"
:button-title="__('Insert a quote')"
diff --git a/app/assets/javascripts/vue_shared/components/notes/noteable_warning.vue b/app/assets/javascripts/vue_shared/components/notes/noteable_warning.vue
index 0b302f22062..7a7074da084 100644
--- a/app/assets/javascripts/vue_shared/components/notes/noteable_warning.vue
+++ b/app/assets/javascripts/vue_shared/components/notes/noteable_warning.vue
@@ -1,12 +1,7 @@
<script>
-import { GlLink, GlIcon } from '@gitlab/ui';
-import { escape } from 'lodash';
+import { GlLink, GlIcon, GlSprintf } from '@gitlab/ui';
import { __, sprintf } from '~/locale';
-function buildDocsLinkStart(path) {
- return `<a href="${escape(path)}" target="_blank" rel="noopener noreferrer">`;
-}
-
const NoteableTypeText = {
Issue: __('issue'),
Epic: __('epic'),
@@ -17,6 +12,7 @@ export default {
components: {
GlIcon,
GlLink,
+ GlSprintf,
},
props: {
isLocked: {
@@ -59,20 +55,6 @@ export default {
noteableTypeText() {
return NoteableTypeText[this.noteableType];
},
- confidentialAndLockedDiscussionText() {
- return sprintf(
- __(
- 'This %{noteableTypeText} is %{confidentialLinkStart}confidential%{linkEnd} and %{lockedLinkStart}locked%{linkEnd}.',
- ),
- {
- noteableTypeText: this.noteableTypeText,
- confidentialLinkStart: buildDocsLinkStart(this.confidentialNoteableDocsPath),
- lockedLinkStart: buildDocsLinkStart(this.lockedNoteableDocsPath),
- linkEnd: '</a>',
- },
- false,
- );
- },
confidentialContextText() {
return sprintf(__('This is a confidential %{noteableTypeText}.'), {
noteableTypeText: this.noteableTypeText,
@@ -91,9 +73,23 @@ export default {
<gl-icon v-if="!isLockedAndConfidential" :name="warningIcon" :size="16" class="icon inline" />
<span v-if="isLockedAndConfidential" ref="lockedAndConfidential">
- <span
- v-html="confidentialAndLockedDiscussionText /* eslint-disable-line vue/no-v-html */"
- ></span>
+ <span>
+ <gl-sprintf
+ :message="
+ __(
+ 'This %{noteableTypeText} is %{confidentialLinkStart}confidential%{confidentialLinkEnd} and %{lockedLinkStart}locked%{lockedLinkEnd}.',
+ )
+ "
+ >
+ <template #noteableTypeText>{{ noteableTypeText }}</template>
+ <template #confidentialLink="{ content }">
+ <gl-link :href="confidentialNoteableDocsPath" target="_blank">{{ content }}</gl-link>
+ </template>
+ <template #lockedLink="{ content }">
+ <gl-link :href="lockedNoteableDocsPath" target="_blank">{{ content }}</gl-link>
+ </template>
+ </gl-sprintf>
+ </span>
{{
__("People without permission will never get a notification and won't be able to comment.")
}}
diff --git a/app/assets/javascripts/vue_shared/components/runner_aws_deployments/constants.js b/app/assets/javascripts/vue_shared/components/runner_aws_deployments/constants.js
index 46361c6eb32..88c975b97b9 100644
--- a/app/assets/javascripts/vue_shared/components/runner_aws_deployments/constants.js
+++ b/app/assets/javascripts/vue_shared/components/runner_aws_deployments/constants.js
@@ -1,7 +1,5 @@
import { s__, sprintf } from '~/locale';
-export const EXPERIMENT_NAME = 'ci_runner_templates';
-
export const README_URL =
'https://gitlab.com/guided-explorations/aws/gitlab-runner-autoscaling-aws-asg/-/blob/main/easybuttons.md';
@@ -16,7 +14,11 @@ export const EASY_BUTTONS = [
templateName:
'easybutton-amazon-linux-2-docker-manual-scaling-with-schedule-ondemandonly.cf.yml',
description: s__(
- 'Runners|Amazon Linux 2 Docker HA with manual scaling and optional scheduling. Non-spot. Default choice for Linux Docker executor.',
+ 'Runners|Amazon Linux 2 Docker HA with manual scaling and optional scheduling. Non-spot.',
+ ),
+ moreDetails1: s__('Runners|No spot. This is the default choice for Linux Docker executor.'),
+ moreDetails2: s__(
+ 'Runners|A capacity of 1 enables warm HA through Auto Scaling group re-spawn. A capacity of 2 enables hot HA because the service is available even when a node is lost. A capacity of 3 or more enables hot HA and manual scaling of runner fleet.',
),
},
{
@@ -28,12 +30,20 @@ export const EASY_BUTTONS = [
),
{ percentage: '100%' },
),
+ moreDetails1: sprintf(s__('Runners|%{percentage} spot.'), { percentage: '100%' }),
+ moreDetails2: s__(
+ 'Runners|Capacity of 1 enables warm HA through Auto Scaling group re-spawn. Capacity of 2 enables hot HA because the service is available even when a node is lost. Capacity of 3 or more enables hot HA and manual scaling of runner fleet.',
+ ),
},
{
stackName: 'win2019-shell-non-spot',
templateName: 'easybutton-windows2019-shell-manual-scaling-with-scheduling-ondemandonly.cf.yml',
description: s__(
- 'Runners|Windows 2019 Shell with manual scaling and optional scheduling. Non-spot. Default choice for Windows Shell executor.',
+ 'Runners|Windows 2019 Shell with manual scaling and optional scheduling. Non-spot.',
+ ),
+ moreDetails1: s__('Runners|No spot. Default choice for Windows Shell executor.'),
+ moreDetails2: s__(
+ 'Runners|Capacity of 1 enables warm HA through Auto Scaling group re-spawn. Capacity of 2 enables hot HA because the service is available even when a node is lost. Capacity of 3 or more enables hot HA and manual scaling of runner fleet.',
),
},
{
@@ -45,5 +55,9 @@ export const EASY_BUTTONS = [
),
{ percentage: '100%' },
),
+ moreDetails1: sprintf(s__('Runners|%{percentage} spot.'), { percentage: '100%' }),
+ moreDetails2: s__(
+ 'Runners|Capacity of 1 enables warm HA through Auto Scaling group re-spawn. Capacity of 2 enables hot HA because the service is available even when a node is lost. Capacity of 3 or more enables hot HA and manual scaling of runner fleet.',
+ ),
},
];
diff --git a/app/assets/javascripts/vue_shared/components/runner_aws_deployments/runner_aws_deployments_modal.vue b/app/assets/javascripts/vue_shared/components/runner_aws_deployments/runner_aws_deployments_modal.vue
index 57cc25caa25..eee65d90285 100644
--- a/app/assets/javascripts/vue_shared/components/runner_aws_deployments/runner_aws_deployments_modal.vue
+++ b/app/assets/javascripts/vue_shared/components/runner_aws_deployments/runner_aws_deployments_modal.vue
@@ -1,35 +1,44 @@
<script>
-import { GlModal, GlSprintf, GlLink } from '@gitlab/ui';
-import awsCloudFormationImageUrl from 'images/aws-cloud-formation.png';
-import ExperimentTracking from '~/experimentation/experiment_tracking';
-import { getBaseURL, objectToQuery } from '~/lib/utils/url_utility';
-import { __, s__ } from '~/locale';
import {
- EXPERIMENT_NAME,
- README_URL,
- CF_BASE_URL,
- TEMPLATES_BASE_URL,
- EASY_BUTTONS,
-} from './constants';
+ GlModal,
+ GlSprintf,
+ GlLink,
+ GlFormRadioGroup,
+ GlFormRadio,
+ GlAccordion,
+ GlAccordionItem,
+} from '@gitlab/ui';
+import Tracking from '~/tracking';
+import { getBaseURL, objectToQuery, visitUrl } from '~/lib/utils/url_utility';
+import { __, s__ } from '~/locale';
+import { README_URL, CF_BASE_URL, TEMPLATES_BASE_URL, EASY_BUTTONS } from './constants';
export default {
components: {
GlModal,
GlSprintf,
GlLink,
+ GlFormRadioGroup,
+ GlFormRadio,
+ GlAccordion,
+ GlAccordionItem,
},
+ mixins: [Tracking.mixin()],
props: {
modalId: {
type: String,
required: true,
},
- imgSrc: {
- type: String,
- required: false,
- default: awsCloudFormationImageUrl,
- },
+ },
+ data() {
+ return {
+ selected: this.$options.easyButtons[0],
+ };
},
methods: {
+ borderBottom(idx) {
+ return idx < this.$options.easyButtons.length - 1;
+ },
easyButtonUrl(easyButton) {
const params = {
templateURL: TEMPLATES_BASE_URL + easyButton.templateName,
@@ -39,21 +48,30 @@ export default {
return CF_BASE_URL + objectToQuery(params);
},
trackCiRunnerTemplatesClick(stackName) {
- const tracking = new ExperimentTracking(EXPERIMENT_NAME);
- tracking.event(`template_clicked_${stackName}`);
+ this.track('template_clicked', {
+ label: stackName,
+ });
+ },
+ handleModalPrimary() {
+ this.trackCiRunnerTemplatesClick(this.selected.stackName);
+ visitUrl(this.easyButtonUrl(this.selected), true);
},
},
i18n: {
title: s__('Runners|Deploy GitLab Runner in AWS'),
instructions: s__(
- 'Runners|For each solution, you will choose a capacity. 1 enables warm HA through Auto Scaling group re-spawn. 2 enables hot HA because the service is available even when a node is lost. 3 or more enables hot HA and manual scaling of runner fleet.',
+ 'Runners|Select your preferred option here. In the next step, you can choose the capacity for your runner in the AWS CloudFormation console.',
),
- dont_see_what_you_are_looking_for: s__(
- "Rnners|Don't see what you are looking for? See the full list of options, including a fully customizable option, %{linkStart}here%{linkEnd}.",
- ),
- note: s__(
- 'Runners|If you do not select an AWS VPC, the runner will deploy to the Default VPC in the AWS Region you select. Please consult with your AWS administrator to understand if there are any security risks to deploying into the Default VPC in any given region in your AWS account.',
+ chooseRunner: s__('Runners|Choose your preferred GitLab Runner'),
+ dontSeeWhatYouAreLookingFor: s__(
+ "Runners|Don't see what you are looking for? See the full list of options, including a fully customizable option %{linkStart}here%{linkEnd}.",
),
+ moreDetails: __('More Details'),
+ lessDetails: __('Less Details'),
+ },
+ deployButton: {
+ text: s__('Runners|Deploy GitLab Runner in AWS'),
+ attributes: [{ variant: 'confirm' }],
},
closeButton: {
text: __('Cancel'),
@@ -67,37 +85,41 @@ export default {
<gl-modal
:modal-id="modalId"
:title="$options.i18n.title"
+ :action-primary="$options.deployButton"
:action-secondary="$options.closeButton"
size="sm"
+ @primary="handleModalPrimary"
>
<p>{{ $options.i18n.instructions }}</p>
- <ul class="gl-list-style-none gl-p-0 gl-mb-0">
- <li v-for="easyButton in $options.easyButtons" :key="easyButton.templateName">
- <gl-link
- :href="easyButtonUrl(easyButton)"
- target="_blank"
- class="gl-display-flex gl-font-weight-bold"
- @click="trackCiRunnerTemplatesClick(easyButton.stackName)"
- >
- <img
- :title="easyButton.stackName"
- :alt="easyButton.stackName"
- :src="imgSrc"
- width="46"
- height="46"
- class="gl-mt-2 gl-mr-5 gl-mb-6"
- />
+ <gl-form-radio-group v-model="selected" :label="$options.i18n.chooseRunner" label-sr-only>
+ <gl-form-radio
+ v-for="(easyButton, idx) in $options.easyButtons"
+ :key="easyButton.templateName"
+ :value="easyButton"
+ class="gl-py-5 gl-pl-8"
+ :class="{ 'gl-border-b': borderBottom(idx) }"
+ >
+ <div class="gl-mt-n1 gl-pl-4 gl-pb-2 gl-font-weight-bold">
{{ easyButton.description }}
- </gl-link>
- </li>
- </ul>
+ <gl-accordion :header-level="3" class="gl-pt-3">
+ <gl-accordion-item
+ :title="$options.i18n.moreDetails"
+ :title-visible="$options.i18n.lessDetails"
+ class="gl-font-weight-normal"
+ >
+ <p class="gl-pt-2">{{ easyButton.moreDetails1 }}</p>
+ <p class="gl-m-0">{{ easyButton.moreDetails2 }}</p>
+ </gl-accordion-item>
+ </gl-accordion>
+ </div>
+ </gl-form-radio>
+ </gl-form-radio-group>
<p>
- <gl-sprintf :message="$options.i18n.dont_see_what_you_are_looking_for">
+ <gl-sprintf :message="$options.i18n.dontSeeWhatYouAreLookingFor">
<template #link="{ content }">
<gl-link :href="$options.readmeUrl" target="_blank">{{ content }}</gl-link>
</template>
</gl-sprintf>
</p>
- <p class="gl-font-sm gl-mb-0">{{ $options.i18n.note }}</p>
</gl-modal>
</template>
diff --git a/app/assets/javascripts/vue_shared/components/sidebar/queries/get_mr_assignees.query.graphql b/app/assets/javascripts/vue_shared/components/sidebar/queries/get_mr_assignees.query.graphql
index 81e19e48d75..7127940bb05 100644
--- a/app/assets/javascripts/vue_shared/components/sidebar/queries/get_mr_assignees.query.graphql
+++ b/app/assets/javascripts/vue_shared/components/sidebar/queries/get_mr_assignees.query.graphql
@@ -10,8 +10,14 @@ query getMrAssignees($fullPath: ID!, $iid: String!) {
nodes {
...User
...UserAvailability
+ mergeRequestInteraction {
+ canMerge
+ }
}
}
+ userPermissions {
+ canMerge
+ }
}
}
}
diff --git a/app/assets/javascripts/vue_shared/components/sidebar/queries/update_mr_assignees.mutation.graphql b/app/assets/javascripts/vue_shared/components/sidebar/queries/update_mr_assignees.mutation.graphql
index 77140ea36d8..5fec2ccbdfb 100644
--- a/app/assets/javascripts/vue_shared/components/sidebar/queries/update_mr_assignees.mutation.graphql
+++ b/app/assets/javascripts/vue_shared/components/sidebar/queries/update_mr_assignees.mutation.graphql
@@ -2,21 +2,18 @@
#import "~/graphql_shared/fragments/user_availability.fragment.graphql"
mutation mergeRequestSetAssignees($iid: String!, $assigneeUsernames: [String!]!, $fullPath: ID!) {
- mergeRequestSetAssignees(
+ issuableSetAssignees: mergeRequestSetAssignees(
input: { iid: $iid, assigneeUsernames: $assigneeUsernames, projectPath: $fullPath }
) {
- mergeRequest {
+ issuable: mergeRequest {
id
assignees {
nodes {
...User
...UserAvailability
- }
- }
- participants {
- nodes {
- ...User
- ...UserAvailability
+ mergeRequestInteraction {
+ canMerge
+ }
}
}
}
diff --git a/app/assets/javascripts/vue_shared/components/source_editor.vue b/app/assets/javascripts/vue_shared/components/source_editor.vue
index 011cad4267c..6a0bf07c8b4 100644
--- a/app/assets/javascripts/vue_shared/components/source_editor.vue
+++ b/app/assets/javascripts/vue_shared/components/source_editor.vue
@@ -46,6 +46,11 @@ export default {
required: false,
default: () => ({}),
},
+ debounceValue: {
+ type: Number,
+ required: false,
+ default: CONTENT_UPDATE_DEBOUNCE,
+ },
},
data() {
return {
@@ -73,9 +78,7 @@ export default {
...this.editorOptions,
});
- this.editor.onDidChangeModelContent(
- debounce(this.onFileChange.bind(this), CONTENT_UPDATE_DEBOUNCE),
- );
+ this.editor.onDidChangeModelContent(debounce(this.onFileChange.bind(this), this.debounceValue));
},
beforeDestroy() {
this.editor.dispose();
diff --git a/app/assets/javascripts/vue_shared/components/source_viewer/source_viewer.vue b/app/assets/javascripts/vue_shared/components/source_viewer/source_viewer.vue
index 5aae1812de3..4a78cbacec0 100644
--- a/app/assets/javascripts/vue_shared/components/source_viewer/source_viewer.vue
+++ b/app/assets/javascripts/vue_shared/components/source_viewer/source_viewer.vue
@@ -35,16 +35,20 @@ export default {
},
highlightedContent() {
let highlightedContent;
+ let { language } = this;
if (this.hljs) {
- if (!this.language) {
- highlightedContent = this.hljs.highlightAuto(this.content).value;
+ if (!language) {
+ const hljsHighlightAuto = this.hljs.highlightAuto(this.content);
+
+ highlightedContent = hljsHighlightAuto.value;
+ language = hljsHighlightAuto.language;
} else if (this.languageDefinition) {
highlightedContent = this.hljs.highlight(this.content, { language: this.language }).value;
}
}
- return wrapLines(highlightedContent);
+ return wrapLines(highlightedContent, language);
},
},
watch: {
@@ -110,7 +114,7 @@ export default {
data-qa-selector="blob_viewer_file_content"
>
<line-numbers :lines="lineNumbers" />
- <pre class="code gl-pb-0!"><code v-safe-html="highlightedContent"></code>
+ <pre class="code highlight gl-pb-0!"><code v-safe-html="highlightedContent"></code>
</pre>
</div>
</template>
diff --git a/app/assets/javascripts/vue_shared/components/source_viewer/utils.js b/app/assets/javascripts/vue_shared/components/source_viewer/utils.js
index e64e564bf61..d726a8a55ff 100644
--- a/app/assets/javascripts/vue_shared/components/source_viewer/utils.js
+++ b/app/assets/javascripts/vue_shared/components/source_viewer/utils.js
@@ -1,11 +1,13 @@
-export const wrapLines = (content) => {
+export const wrapLines = (content, language) => {
+ const isValidLanguage = /^[a-z\d\-_]+$/.test(language); // To prevent the possibility of a vulnerability we only allow languages that contain alphanumeric characters ([a-z\d), dashes (-) or underscores (_).
+
return (
content &&
content
.split('\n')
.map((line, i) => {
let formattedLine;
- const idAttribute = `id="LC${i + 1}"`;
+ const attributes = `id="LC${i + 1}" lang="${isValidLanguage ? language : ''}"`;
if (line.includes('<span class="hljs') && !line.includes('</span>')) {
/**
@@ -14,9 +16,9 @@ export const wrapLines = (content) => {
* example (before): <span class="hljs-code">```bash
* example (after): <span id="LC67" class="hljs-code">```bash
*/
- formattedLine = line.replace(/(?=class="hljs)/, `${idAttribute} `);
+ formattedLine = line.replace(/(?=class="hljs)/, `${attributes} `);
} else {
- formattedLine = `<span ${idAttribute} class="line">${line}</span>`;
+ formattedLine = `<span ${attributes} class="line">${line}</span>`;
}
return formattedLine;
diff --git a/app/assets/javascripts/vue_shared/components/user_avatar/user_avatar_image.vue b/app/assets/javascripts/vue_shared/components/user_avatar/user_avatar_image.vue
index efb99eb0d94..d07f65cf5c1 100644
--- a/app/assets/javascripts/vue_shared/components/user_avatar/user_avatar_image.vue
+++ b/app/assets/javascripts/vue_shared/components/user_avatar/user_avatar_image.vue
@@ -1,30 +1,33 @@
<script>
/* This is a re-usable vue component for rendering a user avatar that
- does not need to link to the user's profile. The image and an optional
- tooltip can be configured by props passed to this component.
+ does not need to link to the user's profile. The image and an optional
+ tooltip can be configured by props passed to this component.
- Sample configuration:
+ Sample configuration:
- <user-avatar-image
- :lazy="true"
- :img-src="userAvatarSrc"
- :img-alt="tooltipText"
- :tooltip-text="tooltipText"
- tooltip-placement="top"
- />
+ <user-avatar-image
+ lazy
+ :img-src="userAvatarSrc"
+ :img-alt="tooltipText"
+ :tooltip-text="tooltipText"
+ tooltip-placement="top"
+ />
-*/
+ */
-import { GlTooltip } from '@gitlab/ui';
import defaultAvatarUrl from 'images/no_avatar.png';
import { __ } from '~/locale';
-import { placeholderImage } from '../../../lazy_loader';
+import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
+import UserAvatarImageNew from './user_avatar_image_new.vue';
+import UserAvatarImageOld from './user_avatar_image_old.vue';
export default {
name: 'UserAvatarImage',
components: {
- GlTooltip,
+ UserAvatarImageNew,
+ UserAvatarImageOld,
},
+ mixins: [glFeatureFlagMixin()],
props: {
lazy: {
type: Boolean,
@@ -62,51 +65,14 @@ export default {
default: 'top',
},
},
- computed: {
- // API response sends null when gravatar is disabled and
- // we provide an empty string when we use it inside user avatar link.
- // In both cases we should render the defaultAvatarUrl
- sanitizedSource() {
- let baseSrc = this.imgSrc === '' || this.imgSrc === null ? defaultAvatarUrl : this.imgSrc;
- // Only adds the width to the URL if its not a base64 data image
- if (!(baseSrc.indexOf('data:') === 0) && !baseSrc.includes('?'))
- baseSrc += `?width=${this.size}`;
- return baseSrc;
- },
- resultantSrcAttribute() {
- return this.lazy ? placeholderImage : this.sanitizedSource;
- },
- avatarSizeClass() {
- return `s${this.size}`;
- },
- },
};
</script>
<template>
- <span>
- <img
- ref="userAvatarImage"
- :class="{
- lazy: lazy,
- [avatarSizeClass]: true,
- [cssClasses]: true,
- }"
- :src="resultantSrcAttribute"
- :width="size"
- :height="size"
- :alt="imgAlt"
- :data-src="sanitizedSource"
- class="avatar"
- />
- <gl-tooltip
- v-if="tooltipText || $slots.default"
- :target="() => $refs.userAvatarImage"
- :placement="tooltipPlacement"
- boundary="window"
- class="js-user-avatar-image-tooltip"
- >
- <slot> {{ tooltipText }} </slot>
- </gl-tooltip>
- </span>
+ <user-avatar-image-new v-if="glFeatures.glAvatarForAllUserAvatars" v-bind="$props">
+ <slot></slot>
+ </user-avatar-image-new>
+ <user-avatar-image-old v-else v-bind="$props">
+ <slot></slot>
+ </user-avatar-image-old>
</template>
diff --git a/app/assets/javascripts/vue_shared/components/user_avatar/user_avatar_image_new.vue b/app/assets/javascripts/vue_shared/components/user_avatar/user_avatar_image_new.vue
new file mode 100644
index 00000000000..f52a3471ea4
--- /dev/null
+++ b/app/assets/javascripts/vue_shared/components/user_avatar/user_avatar_image_new.vue
@@ -0,0 +1,106 @@
+<script>
+/* This is a re-usable vue component for rendering a user avatar that
+ does not need to link to the user's profile. The image and an optional
+ tooltip can be configured by props passed to this component.
+
+ Sample configuration:
+
+ <user-avatar
+ lazy
+ :img-src="userAvatarSrc"
+ :img-alt="tooltipText"
+ :tooltip-text="tooltipText"
+ tooltip-placement="top"
+ />
+
+ */
+
+import { GlTooltip, GlAvatar } from '@gitlab/ui';
+import defaultAvatarUrl from 'images/no_avatar.png';
+import { __ } from '~/locale';
+import { placeholderImage } from '../../../lazy_loader';
+
+export default {
+ name: 'UserAvatarImageNew',
+ components: {
+ GlTooltip,
+ GlAvatar,
+ },
+ props: {
+ lazy: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
+ imgSrc: {
+ type: String,
+ required: false,
+ default: defaultAvatarUrl,
+ },
+ cssClasses: {
+ type: String,
+ required: false,
+ default: '',
+ },
+ imgAlt: {
+ type: String,
+ required: false,
+ default: __('user avatar'),
+ },
+ size: {
+ type: Number,
+ required: false,
+ default: 20,
+ },
+ tooltipText: {
+ type: String,
+ required: false,
+ default: '',
+ },
+ tooltipPlacement: {
+ type: String,
+ required: false,
+ default: 'top',
+ },
+ },
+ computed: {
+ // API response sends null when gravatar is disabled and
+ // we provide an empty string when we use it inside user avatar link.
+ // In both cases we should render the defaultAvatarUrl
+ sanitizedSource() {
+ let baseSrc = this.imgSrc === '' || this.imgSrc === null ? defaultAvatarUrl : this.imgSrc;
+ // Only adds the width to the URL if its not a base64 data image
+ if (!(baseSrc.indexOf('data:') === 0) && !baseSrc.includes('?'))
+ baseSrc += `?width=${this.size}`;
+ return baseSrc;
+ },
+ resultantSrcAttribute() {
+ return this.lazy ? placeholderImage : this.sanitizedSource;
+ },
+ },
+};
+</script>
+
+<template>
+ <span>
+ <gl-avatar
+ ref="userAvatar"
+ :class="{
+ lazy: lazy,
+ [cssClasses]: true,
+ }"
+ :src="resultantSrcAttribute"
+ :data-src="sanitizedSource"
+ :size="size"
+ :alt="imgAlt"
+ />
+
+ <gl-tooltip
+ :target="() => $refs.userAvatar.$el"
+ :placement="tooltipPlacement"
+ boundary="window"
+ >
+ <slot> {{ tooltipText }}</slot>
+ </gl-tooltip>
+ </span>
+</template>
diff --git a/app/assets/javascripts/vue_shared/components/user_avatar/user_avatar_image_old.vue b/app/assets/javascripts/vue_shared/components/user_avatar/user_avatar_image_old.vue
new file mode 100644
index 00000000000..bca10c76038
--- /dev/null
+++ b/app/assets/javascripts/vue_shared/components/user_avatar/user_avatar_image_old.vue
@@ -0,0 +1,110 @@
+<script>
+/* This is a re-usable vue component for rendering a user avatar that
+ does not need to link to the user's profile. The image and an optional
+ tooltip can be configured by props passed to this component.
+
+ Sample configuration:
+
+ <user-avatar-image
+ lazy
+ :img-src="userAvatarSrc"
+ :img-alt="tooltipText"
+ :tooltip-text="tooltipText"
+ tooltip-placement="top"
+ />
+
+ */
+
+import { GlTooltip } from '@gitlab/ui';
+import defaultAvatarUrl from 'images/no_avatar.png';
+import { __ } from '~/locale';
+import { placeholderImage } from '../../../lazy_loader';
+
+export default {
+ name: 'UserAvatarImageOld',
+ components: {
+ GlTooltip,
+ },
+ props: {
+ lazy: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
+ imgSrc: {
+ type: String,
+ required: false,
+ default: defaultAvatarUrl,
+ },
+ cssClasses: {
+ type: String,
+ required: false,
+ default: '',
+ },
+ imgAlt: {
+ type: String,
+ required: false,
+ default: __('user avatar'),
+ },
+ size: {
+ type: Number,
+ required: false,
+ default: 20,
+ },
+ tooltipText: {
+ type: String,
+ required: false,
+ default: '',
+ },
+ tooltipPlacement: {
+ type: String,
+ required: false,
+ default: 'top',
+ },
+ },
+ computed: {
+ // API response sends null when gravatar is disabled and
+ // we provide an empty string when we use it inside user avatar link.
+ // In both cases we should render the defaultAvatarUrl
+ sanitizedSource() {
+ let baseSrc = this.imgSrc === '' || this.imgSrc === null ? defaultAvatarUrl : this.imgSrc;
+ // Only adds the width to the URL if its not a base64 data image
+ if (!(baseSrc.indexOf('data:') === 0) && !baseSrc.includes('?'))
+ baseSrc += `?width=${this.size}`;
+ return baseSrc;
+ },
+ resultantSrcAttribute() {
+ return this.lazy ? placeholderImage : this.sanitizedSource;
+ },
+ avatarSizeClass() {
+ return `s${this.size}`;
+ },
+ },
+};
+</script>
+
+<template>
+ <span>
+ <img
+ ref="userAvatarImage"
+ :class="{
+ lazy: lazy,
+ [avatarSizeClass]: true,
+ [cssClasses]: true,
+ }"
+ :src="resultantSrcAttribute"
+ :width="size"
+ :height="size"
+ :alt="imgAlt"
+ :data-src="sanitizedSource"
+ class="avatar"
+ />
+ <gl-tooltip
+ :target="() => $refs.userAvatarImage"
+ :placement="tooltipPlacement"
+ boundary="window"
+ >
+ <slot> {{ tooltipText }}</slot>
+ </gl-tooltip>
+ </span>
+</template>
diff --git a/app/assets/javascripts/vue_shared/components/user_avatar/user_avatar_link.vue b/app/assets/javascripts/vue_shared/components/user_avatar/user_avatar_link.vue
index 04423aac651..887deff17c9 100644
--- a/app/assets/javascripts/vue_shared/components/user_avatar/user_avatar_link.vue
+++ b/app/assets/javascripts/vue_shared/components/user_avatar/user_avatar_link.vue
@@ -17,18 +17,17 @@
*/
-import { GlLink, GlTooltipDirective } from '@gitlab/ui';
-import userAvatarImage from './user_avatar_image.vue';
+import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
+import UserAvatarLinkNew from './user_avatar_link_new.vue';
+import UserAvatarLinkOld from './user_avatar_link_old.vue';
export default {
name: 'UserAvatarLink',
components: {
- GlLink,
- userAvatarImage,
- },
- directives: {
- GlTooltip: GlTooltipDirective,
+ UserAvatarLinkNew,
+ UserAvatarLinkOld,
},
+ mixins: [glFeatureFlagMixin()],
props: {
lazy: {
type: Boolean,
@@ -76,36 +75,21 @@ export default {
default: '',
},
},
- computed: {
- shouldShowUsername() {
- return this.username.length > 0;
- },
- avatarTooltipText() {
- return this.shouldShowUsername ? '' : this.tooltipText;
- },
- },
};
</script>
<template>
- <gl-link :href="linkHref" class="user-avatar-link">
- <user-avatar-image
- :img-src="imgSrc"
- :img-alt="imgAlt"
- :css-classes="imgCssClasses"
- :size="imgSize"
- :tooltip-text="avatarTooltipText"
- :tooltip-placement="tooltipPlacement"
- :lazy="lazy"
- >
- <slot></slot> </user-avatar-image
- ><span
- v-if="shouldShowUsername"
- v-gl-tooltip
- :title="tooltipText"
- :tooltip-placement="tooltipPlacement"
- class="js-user-avatar-link-username"
- >{{ username }}</span
- ><slot name="avatar-badge"></slot>
- </gl-link>
+ <user-avatar-link-new v-if="glFeatures.glAvatarForAllUserAvatars" v-bind="$props">
+ <slot></slot>
+ <template #avatar-badge>
+ <slot name="avatar-badge"></slot>
+ </template>
+ </user-avatar-link-new>
+
+ <user-avatar-link-old v-else v-bind="$props">
+ <slot></slot>
+ <template #avatar-badge>
+ <slot name="avatar-badge"></slot>
+ </template>
+ </user-avatar-link-old>
</template>
diff --git a/app/assets/javascripts/vue_shared/components/user_avatar/user_avatar_link_new.vue b/app/assets/javascripts/vue_shared/components/user_avatar/user_avatar_link_new.vue
new file mode 100644
index 00000000000..3b459569274
--- /dev/null
+++ b/app/assets/javascripts/vue_shared/components/user_avatar/user_avatar_link_new.vue
@@ -0,0 +1,117 @@
+<script>
+/* This is a re-usable vue component for rendering a user avatar wrapped in
+ a clickable link (likely to the user's profile). The link, image, and
+ tooltip can be configured by props passed to this component.
+
+ Sample configuration:
+
+ <user-avatar-link
+ :link-href="userProfileUrl"
+ :img-src="userAvatarSrc"
+ :img-alt="tooltipText"
+ :img-size="20"
+ :tooltip-text="tooltipText"
+ :tooltip-placement="top"
+ :username="username"
+ />
+
+*/
+
+import { GlAvatarLink, GlTooltipDirective } from '@gitlab/ui';
+import UserAvatarImage from './user_avatar_image.vue';
+
+export default {
+ name: 'UserAvatarLinkNew',
+ components: {
+ UserAvatarImage,
+ GlAvatarLink,
+ },
+ directives: {
+ GlTooltip: GlTooltipDirective,
+ },
+ props: {
+ lazy: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
+ linkHref: {
+ type: String,
+ required: false,
+ default: '',
+ },
+ imgSrc: {
+ type: String,
+ required: false,
+ default: '',
+ },
+ imgAlt: {
+ type: String,
+ required: false,
+ default: '',
+ },
+ imgCssClasses: {
+ type: String,
+ required: false,
+ default: '',
+ },
+ imgSize: {
+ type: Number,
+ required: false,
+ default: 20,
+ },
+ tooltipText: {
+ type: String,
+ required: false,
+ default: '',
+ },
+ tooltipPlacement: {
+ type: String,
+ required: false,
+ default: 'top',
+ },
+ username: {
+ type: String,
+ required: false,
+ default: '',
+ },
+ },
+ computed: {
+ shouldShowUsername() {
+ return this.username.length > 0;
+ },
+ avatarTooltipText() {
+ return this.shouldShowUsername ? '' : this.tooltipText;
+ },
+ },
+};
+</script>
+
+<template>
+ <gl-avatar-link :href="linkHref" class="user-avatar-link">
+ <user-avatar-image
+ :img-src="imgSrc"
+ :img-alt="imgAlt"
+ :css-classes="imgCssClasses"
+ :size="imgSize"
+ :tooltip-text="avatarTooltipText"
+ :tooltip-placement="tooltipPlacement"
+ :lazy="lazy"
+ >
+ <slot></slot>
+ </user-avatar-image>
+
+ <span
+ v-if="shouldShowUsername"
+ v-gl-tooltip
+ :title="tooltipText"
+ :tooltip-placement="tooltipPlacement"
+ class="gl-ml-3"
+ data-testid="user-avatar-link-username"
+ >
+ {{ username }}
+ </span>
+
+ <slot name="avatar-badge"></slot>
+ </gl-avatar-link>
+</template>
diff --git a/app/assets/javascripts/vue_shared/components/user_avatar/user_avatar_link_old.vue b/app/assets/javascripts/vue_shared/components/user_avatar/user_avatar_link_old.vue
new file mode 100644
index 00000000000..c2e46e61e1b
--- /dev/null
+++ b/app/assets/javascripts/vue_shared/components/user_avatar/user_avatar_link_old.vue
@@ -0,0 +1,117 @@
+<script>
+/* This is a re-usable vue component for rendering a user avatar wrapped in
+ a clickable link (likely to the user's profile). The link, image, and
+ tooltip can be configured by props passed to this component.
+
+ Sample configuration:
+
+ <user-avatar-link
+ :link-href="userProfileUrl"
+ :img-src="userAvatarSrc"
+ :img-alt="tooltipText"
+ :img-size="20"
+ :tooltip-text="tooltipText"
+ :tooltip-placement="top"
+ :username="username"
+ />
+
+*/
+
+import { GlLink, GlTooltipDirective } from '@gitlab/ui';
+import UserAvatarImage from './user_avatar_image.vue';
+
+export default {
+ name: 'UserAvatarLinkOld',
+ components: {
+ GlLink,
+ UserAvatarImage,
+ },
+ directives: {
+ GlTooltip: GlTooltipDirective,
+ },
+ props: {
+ lazy: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
+ linkHref: {
+ type: String,
+ required: false,
+ default: '',
+ },
+ imgSrc: {
+ type: String,
+ required: false,
+ default: '',
+ },
+ imgAlt: {
+ type: String,
+ required: false,
+ default: '',
+ },
+ imgCssClasses: {
+ type: String,
+ required: false,
+ default: '',
+ },
+ imgSize: {
+ type: Number,
+ required: false,
+ default: 20,
+ },
+ tooltipText: {
+ type: String,
+ required: false,
+ default: '',
+ },
+ tooltipPlacement: {
+ type: String,
+ required: false,
+ default: 'top',
+ },
+ username: {
+ type: String,
+ required: false,
+ default: '',
+ },
+ },
+ computed: {
+ shouldShowUsername() {
+ return this.username.length > 0;
+ },
+ avatarTooltipText() {
+ return this.shouldShowUsername ? '' : this.tooltipText;
+ },
+ },
+};
+</script>
+
+<template>
+ <span>
+ <gl-link :href="linkHref" class="user-avatar-link">
+ <user-avatar-image
+ :img-src="imgSrc"
+ :img-alt="imgAlt"
+ :css-classes="imgCssClasses"
+ :size="imgSize"
+ :tooltip-text="avatarTooltipText"
+ :tooltip-placement="tooltipPlacement"
+ :lazy="lazy"
+ >
+ <slot></slot>
+ </user-avatar-image>
+
+ <span
+ v-if="shouldShowUsername"
+ v-gl-tooltip
+ :title="tooltipText"
+ :tooltip-placement="tooltipPlacement"
+ data-testid="user-avatar-link-username"
+ >
+ {{ username }}
+ </span>
+ <slot name="avatar-badge"></slot>
+ </gl-link>
+ </span>
+</template>
diff --git a/app/assets/javascripts/vue_shared/components/user_popover/user_popover.vue b/app/assets/javascripts/vue_shared/components/user_popover/user_popover.vue
index 05e0c3b0be3..41507ca94e2 100644
--- a/app/assets/javascripts/vue_shared/components/user_popover/user_popover.vue
+++ b/app/assets/javascripts/vue_shared/components/user_popover/user_popover.vue
@@ -116,7 +116,7 @@ export default {
<div v-if="statusHtml" class="gl-mb-2" data-testid="user-popover-status">
<span v-safe-html:[$options.safeHtmlConfig]="statusHtml"></span>
</div>
- <div v-if="user.bot" class="gl-text-blue-500">
+ <div v-if="user.bot && user.websiteUrl" class="gl-text-blue-500">
<gl-icon name="question" />
<gl-link data-testid="user-popover-bot-docs-link" :href="user.websiteUrl">
<gl-sprintf :message="__('Learn more about %{username}')">
diff --git a/app/assets/javascripts/vue_shared/components/user_select/user_select.vue b/app/assets/javascripts/vue_shared/components/user_select/user_select.vue
index b85cae0c64f..9df5254155e 100644
--- a/app/assets/javascripts/vue_shared/components/user_select/user_select.vue
+++ b/app/assets/javascripts/vue_shared/components/user_select/user_select.vue
@@ -1,4 +1,5 @@
<script>
+import { debounce } from 'lodash';
import {
GlDropdown,
GlDropdownForm,
@@ -6,11 +7,14 @@ import {
GlDropdownItem,
GlSearchBoxByType,
GlLoadingIcon,
+ GlTooltipDirective,
} from '@gitlab/ui';
-import searchUsers from '~/graphql_shared/queries/users_search.query.graphql';
import { __ } from '~/locale';
import SidebarParticipant from '~/sidebar/components/assignees/sidebar_participant.vue';
-import { ASSIGNEES_DEBOUNCE_DELAY, participantsQueries } from '~/sidebar/constants';
+import { IssuableType } from '~/issues/constants';
+import { DEFAULT_DEBOUNCE_AND_THROTTLE_MS } from '~/lib/utils/constants';
+import { participantsQueries, userSearchQueries } from '~/sidebar/constants';
+import { convertToGraphQLId } from '~/graphql_shared/utils';
export default {
i18n: {
@@ -25,6 +29,9 @@ export default {
SidebarParticipant,
GlLoadingIcon,
},
+ directives: {
+ GlTooltip: GlTooltipDirective,
+ },
props: {
headerText: {
type: String,
@@ -58,13 +65,18 @@ export default {
issuableType: {
type: String,
required: false,
- default: 'issue',
+ default: IssuableType.Issue,
},
isEditing: {
type: Boolean,
required: false,
default: true,
},
+ issuableId: {
+ type: Number,
+ required: false,
+ default: null,
+ },
},
data() {
return {
@@ -89,28 +101,35 @@ export default {
};
},
update(data) {
- return data.workspace?.issuable?.participants.nodes;
+ return data.workspace?.issuable?.participants.nodes.map((node) => ({
+ ...node,
+ canMerge: false,
+ }));
},
error() {
this.$emit('error');
},
},
searchUsers: {
- query: searchUsers,
+ query() {
+ return userSearchQueries[this.issuableType].query;
+ },
variables() {
- return {
- fullPath: this.fullPath,
- search: this.search,
- first: 20,
- };
+ return this.searchUsersVariables;
},
skip() {
return !this.isEditing;
},
update(data) {
- return data.workspace?.users?.nodes.filter((x) => x?.user).map(({ user }) => user) || [];
+ return (
+ data.workspace?.users?.nodes
+ .filter((x) => x?.user)
+ .map((node) => ({
+ ...node.user,
+ canMerge: node.mergeRequestInteraction?.canMerge || false,
+ })) || []
+ );
},
- debounce: ASSIGNEES_DEBOUNCE_DELAY,
error() {
this.$emit('error');
this.isSearching = false;
@@ -121,6 +140,23 @@ export default {
},
},
computed: {
+ isMergeRequest() {
+ return this.issuableType === IssuableType.MergeRequest;
+ },
+ searchUsersVariables() {
+ const variables = {
+ fullPath: this.fullPath,
+ search: this.search,
+ first: 20,
+ };
+ if (!this.isMergeRequest) {
+ return variables;
+ }
+ return {
+ ...variables,
+ mergeRequestId: convertToGraphQLId('MergeRequest', this.issuableId),
+ };
+ },
isLoading() {
return this.$apollo.queries.searchUsers.loading || this.$apollo.queries.participants.loading;
},
@@ -135,8 +171,8 @@ export default {
// TODO this de-duplication is temporary (BE fix required)
// https://gitlab.com/gitlab-org/gitlab/-/issues/327822
- const mergedSearchResults = filteredParticipants
- .concat(this.searchUsers)
+ const mergedSearchResults = this.searchUsers
+ .concat(filteredParticipants)
.reduce(
(acc, current) => (acc.some((user) => current.id === user.id) ? acc : [...acc, current]),
[],
@@ -179,6 +215,7 @@ export default {
return this.selectedFiltered.length === 0;
},
},
+
watch: {
// We need to add this watcher to track the moment when user is alredy typing
// but query is still not started due to debounce
@@ -188,15 +225,21 @@ export default {
}
},
},
+ created() {
+ this.debouncedSearchKeyUpdate = debounce(this.setSearchKey, DEFAULT_DEBOUNCE_AND_THROTTLE_MS);
+ },
methods: {
selectAssignee(user) {
let selected = [...this.value];
if (!this.allowMultipleAssignees) {
selected = [user];
+ this.$emit('input', selected);
+ this.$refs.dropdown.hide();
+ this.$emit('toggle');
} else {
selected.push(user);
+ this.$emit('input', selected);
}
- this.$emit('input', selected);
},
unselect(name) {
const selected = this.value.filter((user) => user.username !== name);
@@ -205,6 +248,9 @@ export default {
focusSearch() {
this.$refs.search.focusInput();
},
+ showDropdown() {
+ this.$refs.dropdown.show();
+ },
showDivider(list) {
return list.length > 0 && this.isSearchEmpty;
},
@@ -216,22 +262,37 @@ export default {
const currentUser = usersCopy.find((user) => user.username === this.currentUser.username);
if (currentUser) {
+ currentUser.canMerge = this.currentUser.canMerge;
const index = usersCopy.indexOf(currentUser);
usersCopy.splice(0, 0, usersCopy.splice(index, 1)[0]);
}
return usersCopy;
},
+ setSearchKey(value) {
+ this.search = value.trim();
+ },
+ tooltipText(user) {
+ if (!this.isMergeRequest) {
+ return '';
+ }
+ return user.canMerge ? '' : __('Cannot merge');
+ },
},
};
</script>
<template>
- <gl-dropdown class="show" :text="text" @toggle="$emit('toggle')">
+ <gl-dropdown ref="dropdown" :text="text" @toggle="$emit('toggle')" @shown="focusSearch">
<template #header>
<p class="gl-font-weight-bold gl-text-center gl-mt-2 gl-mb-4">{{ headerText }}</p>
<gl-dropdown-divider />
- <gl-search-box-by-type ref="search" v-model.trim="search" class="js-dropdown-input-field" />
+ <gl-search-box-by-type
+ ref="search"
+ :value="search"
+ class="js-dropdown-input-field"
+ @input="debouncedSearchKeyUpdate"
+ />
</template>
<gl-dropdown-form class="gl-relative gl-min-h-7">
<gl-loading-icon
@@ -247,7 +308,7 @@ export default {
:is-checked="selectedIsEmpty"
:is-check-centered="true"
data-testid="unassign"
- @click="$emit('input', [])"
+ @click.native.capture.stop="$emit('input', [])"
>
<span :class="selectedIsEmpty ? 'gl-pl-0' : 'gl-pl-6'" class="gl-font-weight-bold">{{
$options.i18n.unassigned
@@ -258,27 +319,44 @@ export default {
<gl-dropdown-item
v-for="item in selectedFiltered"
:key="item.id"
+ v-gl-tooltip.left.viewport
+ :title="tooltipText(item)"
+ boundary="viewport"
is-checked
is-check-centered
data-testid="selected-participant"
- @click.stop="unselect(item.username)"
+ @click.native.capture.stop="unselect(item.username)"
>
- <sidebar-participant :user="item" />
+ <sidebar-participant :user="item" :issuable-type="issuableType" />
</gl-dropdown-item>
<template v-if="showCurrentUser">
<gl-dropdown-divider />
- <gl-dropdown-item data-testid="current-user" @click.stop="selectAssignee(currentUser)">
- <sidebar-participant :user="currentUser" class="gl-pl-6!" />
+ <gl-dropdown-item
+ data-testid="current-user"
+ @click.native.capture.stop="selectAssignee(currentUser)"
+ >
+ <sidebar-participant
+ :user="currentUser"
+ :issuable-type="issuableType"
+ class="gl-pl-6!"
+ />
</gl-dropdown-item>
</template>
<gl-dropdown-divider v-if="showDivider(unselectedFiltered)" />
<gl-dropdown-item
v-for="unselectedUser in unselectedFiltered"
:key="unselectedUser.id"
+ v-gl-tooltip.left.viewport
+ :title="tooltipText(unselectedUser)"
+ boundary="viewport"
data-testid="unselected-participant"
- @click="selectAssignee(unselectedUser)"
+ @click.native.capture.stop="selectAssignee(unselectedUser)"
>
- <sidebar-participant :user="unselectedUser" class="gl-pl-6!" />
+ <sidebar-participant
+ :user="unselectedUser"
+ :issuable-type="issuableType"
+ class="gl-pl-6!"
+ />
</gl-dropdown-item>
<gl-dropdown-item v-if="noUsersFound" data-testid="empty-results" class="gl-pl-6!">
{{ __('No matching results') }}
diff --git a/app/assets/javascripts/vue_shared/components/web_ide_link.vue b/app/assets/javascripts/vue_shared/components/web_ide_link.vue
index 82022d1f4d6..199516b3eb3 100644
--- a/app/assets/javascripts/vue_shared/components/web_ide_link.vue
+++ b/app/assets/javascripts/vue_shared/components/web_ide_link.vue
@@ -8,6 +8,7 @@ import ConfirmForkModal from '~/vue_shared/components/confirm_fork_modal.vue';
const KEY_EDIT = 'edit';
const KEY_WEB_IDE = 'webide';
const KEY_GITPOD = 'gitpod';
+const KEY_PIPELINE_EDITOR = 'pipeline_editor';
export default {
components: {
@@ -64,6 +65,11 @@ export default {
required: false,
default: false,
},
+ showPipelineEditorButton: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
userPreferencesGitpodPath: {
type: String,
required: false,
@@ -79,6 +85,11 @@ export default {
required: false,
default: '',
},
+ pipelineEditorUrl: {
+ type: String,
+ required: false,
+ default: '',
+ },
webIdeUrl: {
type: String,
required: false,
@@ -117,14 +128,19 @@ export default {
},
data() {
return {
- selection: KEY_WEB_IDE,
+ selection: this.showPipelineEditorButton ? KEY_PIPELINE_EDITOR : KEY_WEB_IDE,
showEnableGitpodModal: false,
showForkModal: false,
};
},
computed: {
actions() {
- return [this.webIdeAction, this.editAction, this.gitpodAction].filter((action) => action);
+ return [
+ this.pipelineEditorAction,
+ this.webIdeAction,
+ this.editAction,
+ this.gitpodAction,
+ ].filter((action) => action);
},
editAction() {
if (!this.showEditButton) {
@@ -162,7 +178,7 @@ export default {
if (this.webIdeText) {
return this.webIdeText;
} else if (this.isBlob) {
- return __('Edit in Web IDE');
+ return __('Open in Web IDE');
} else if (this.isFork) {
return __('Edit fork in Web IDE');
}
@@ -202,6 +218,9 @@ export default {
};
},
gitpodActionText() {
+ if (this.isBlob) {
+ return __('Open in Gitpod');
+ }
return this.gitpodText || __('Gitpod');
},
computedShowGitpodButton() {
@@ -209,11 +228,28 @@ export default {
this.showGitpodButton && this.userPreferencesGitpodPath && this.userProfileEnableGitpodPath
);
},
+ pipelineEditorAction() {
+ if (!this.showPipelineEditorButton) {
+ return null;
+ }
+
+ const secondaryText = __('Edit, lint, and visualize your pipeline.');
+
+ return {
+ key: KEY_PIPELINE_EDITOR,
+ text: __('Edit in pipeline editor'),
+ secondaryText,
+ tooltip: secondaryText,
+ attrs: {
+ 'data-qa-selector': 'pipeline_editor_button',
+ },
+ href: this.pipelineEditorUrl,
+ };
+ },
gitpodAction() {
if (!this.computedShowGitpodButton) {
return null;
}
-
const handleOptions = this.gitpodEnabled
? { href: this.gitpodUrl }
: {
diff --git a/app/assets/javascripts/vue_shared/issuable/show/components/issuable_title.vue b/app/assets/javascripts/vue_shared/issuable/show/components/issuable_title.vue
index b96ce0c43f7..45941174a62 100644
--- a/app/assets/javascripts/vue_shared/issuable/show/components/issuable_title.vue
+++ b/app/assets/javascripts/vue_shared/issuable/show/components/issuable_title.vue
@@ -58,7 +58,12 @@ export default {
<template>
<div>
<div class="title-container">
- <h2 v-safe-html="issuable.titleHtml || issuable.title" class="title qa-title" dir="auto"></h2>
+ <h1
+ v-safe-html="issuable.titleHtml || issuable.title"
+ class="title qa-title"
+ dir="auto"
+ data-testid="title"
+ ></h1>
<gl-button
v-if="enableEdit"
v-gl-tooltip.bottom
diff --git a/app/assets/javascripts/webpack_non_compiled_placeholder.js b/app/assets/javascripts/webpack_non_compiled_placeholder.js
index 55ac2f0be6a..af671e72129 100644
--- a/app/assets/javascripts/webpack_non_compiled_placeholder.js
+++ b/app/assets/javascripts/webpack_non_compiled_placeholder.js
@@ -1,3 +1,4 @@
+/* globals LIVE_RELOAD */
const div = document.createElement('div');
Object.assign(div.style, {
@@ -15,6 +16,10 @@ Object.assign(div.style, {
'text-align': 'center',
});
+const reloadMessage = LIVE_RELOAD
+ ? 'You have live_reload enabled, the page will reload automatically when complete.'
+ : 'You have live_reload disabled, the page will reload automatically in a few seconds.';
+
div.innerHTML = `
<!-- https://github.com/webpack/media/blob/master/logo/icon-square-big.svg -->
<svg height="50" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 1200">
@@ -30,9 +35,15 @@ div.innerHTML = `
Learn more <a href="https://gitlab.com/gitlab-org/gitlab-development-kit/-/blob/main/doc/configuration.md#webpack-settings">here</a>.
</p>
<p>
- If you have live_reload enabled, the page will reload automatically when complete.<br />
- Otherwise, please <a href="">reload the page manually in a few seconds</a>
+ ${reloadMessage}<br />
+ If it doesn't, please <a href="">reload the page manually</a>.
</p>
`;
document.body.append(div);
+
+if (!LIVE_RELOAD) {
+ setTimeout(() => {
+ window.location.reload();
+ }, 5000);
+}
diff --git a/app/assets/javascripts/work_items/components/work_item_detail_modal.vue b/app/assets/javascripts/work_items/components/work_item_detail_modal.vue
new file mode 100644
index 00000000000..942677bb937
--- /dev/null
+++ b/app/assets/javascripts/work_items/components/work_item_detail_modal.vue
@@ -0,0 +1,62 @@
+<script>
+import { GlModal } from '@gitlab/ui';
+import { s__ } from '~/locale';
+import workItemQuery from '../graphql/work_item.query.graphql';
+import ItemTitle from './item_title.vue';
+
+export default {
+ components: {
+ GlModal,
+ ItemTitle,
+ },
+ props: {
+ visible: {
+ type: Boolean,
+ required: true,
+ },
+ workItemId: {
+ type: String,
+ required: false,
+ default: null,
+ },
+ },
+ data() {
+ return {
+ workItem: {},
+ };
+ },
+ apollo: {
+ workItem: {
+ query: workItemQuery,
+ variables() {
+ return {
+ id: this.workItemId,
+ };
+ },
+ update(data) {
+ return data.workItem;
+ },
+ skip() {
+ return !this.workItemId;
+ },
+ error() {
+ this.$emit(
+ 'error',
+ s__('WorkItem|Something went wrong when fetching the work item. Please try again.'),
+ );
+ },
+ },
+ },
+ computed: {
+ workItemTitle() {
+ return this.workItem?.title;
+ },
+ },
+};
+</script>
+
+<template>
+ <gl-modal hide-footer modal-id="work-item-detail-modal" :visible="visible" @hide="$emit('close')">
+ <item-title class="gl-m-0!" :initial-title="workItemTitle" />
+ </gl-modal>
+</template>
diff --git a/app/assets/javascripts/work_items/graphql/create_work_item.mutation.graphql b/app/assets/javascripts/work_items/graphql/create_work_item.mutation.graphql
index 2f302dae7d7..9312d1c582b 100644
--- a/app/assets/javascripts/work_items/graphql/create_work_item.mutation.graphql
+++ b/app/assets/javascripts/work_items/graphql/create_work_item.mutation.graphql
@@ -1,16 +1,16 @@
#import './widget.fragment.graphql'
-mutation createWorkItem($input: LocalCreateWorkItemInput) {
- localCreateWorkItem(input: $input) @client {
+mutation createWorkItem($input: WorkItemCreateInput!) {
+ workItemCreate(input: $input) {
workItem {
id
- type
- widgets {
+ title
+ workItemType {
+ id
+ }
+ widgets @client {
nodes {
...WidgetBase
- ... on LocalTitleWidget {
- contentText
- }
}
}
}
diff --git a/app/assets/javascripts/work_items/graphql/provider.js b/app/assets/javascripts/work_items/graphql/provider.js
index 676fffb12d8..28328a840cf 100644
--- a/app/assets/javascripts/work_items/graphql/provider.js
+++ b/app/assets/javascripts/work_items/graphql/provider.js
@@ -10,29 +10,28 @@ export function createApolloProvider() {
const defaultClient = createDefaultClient(resolvers, {
typeDefs,
+ cacheConfig: {
+ possibleTypes: {
+ LocalWorkItemWidget: ['LocalTitleWidget'],
+ },
+ },
});
defaultClient.cache.writeQuery({
query: workItemQuery,
variables: {
- id: '1',
+ id: 'gid://gitlab/WorkItem/1',
},
data: {
- workItem: {
+ localWorkItem: {
__typename: 'LocalWorkItem',
- id: '1',
+ id: 'gid://gitlab/WorkItem/1',
type: 'FEATURE',
+ // eslint-disable-next-line @gitlab/require-i18n-strings
+ title: 'Test Work Item',
widgets: {
__typename: 'LocalWorkItemWidgetConnection',
- nodes: [
- {
- __typename: 'LocalTitleWidget',
- type: 'TITLE',
- enabled: true,
- // eslint-disable-next-line @gitlab/require-i18n-strings
- contentText: 'Test Work Item Title',
- },
- ],
+ nodes: [],
},
},
},
diff --git a/app/assets/javascripts/work_items/graphql/resolvers.js b/app/assets/javascripts/work_items/graphql/resolvers.js
index 63d5234d083..fb74e27f840 100644
--- a/app/assets/javascripts/work_items/graphql/resolvers.js
+++ b/app/assets/javascripts/work_items/graphql/resolvers.js
@@ -1,53 +1,24 @@
-import { uuids } from '~/lib/utils/uuids';
import workItemQuery from './work_item.query.graphql';
export const resolvers = {
Mutation: {
- localCreateWorkItem(_, { input }, { cache }) {
- const id = uuids()[0];
- const workItem = {
- __typename: 'LocalWorkItem',
- type: 'FEATURE',
- id,
- widgets: {
- __typename: 'LocalWorkItemWidgetConnection',
- nodes: [
- {
- __typename: 'LocalTitleWidget',
- type: 'TITLE',
- enabled: true,
- contentText: input.title,
- },
- ],
- },
- };
-
- cache.writeQuery({ query: workItemQuery, variables: { id }, data: { workItem } });
-
- return {
- __typename: 'LocalCreateWorkItemPayload',
- workItem,
- };
- },
-
localUpdateWorkItem(_, { input }, { cache }) {
- const workItemTitle = {
- __typename: 'LocalTitleWidget',
- type: 'TITLE',
- enabled: true,
- contentText: input.title,
- };
const workItem = {
__typename: 'LocalWorkItem',
type: 'FEATURE',
id: input.id,
+ title: input.title,
widgets: {
__typename: 'LocalWorkItemWidgetConnection',
- nodes: [workItemTitle],
+ nodes: [],
},
};
- cache.writeQuery({ query: workItemQuery, variables: { id: input.id }, data: { workItem } });
+ cache.writeQuery({
+ query: workItemQuery,
+ variables: { id: input.id },
+ data: { localWorkItem: workItem },
+ });
return {
__typename: 'LocalUpdateWorkItemPayload',
diff --git a/app/assets/javascripts/work_items/graphql/typedefs.graphql b/app/assets/javascripts/work_items/graphql/typedefs.graphql
index 177eea00322..9b4811203f5 100644
--- a/app/assets/javascripts/work_items/graphql/typedefs.graphql
+++ b/app/assets/javascripts/work_items/graphql/typedefs.graphql
@@ -22,14 +22,10 @@ type LocalWorkItemWidgetConnection {
pageInfo: PageInfo!
}
-type LocalTitleWidget implements LocalWorkItemWidget {
- type: LocalWidgetType!
- contentText: String!
-}
-
type LocalWorkItem {
id: ID!
type: LocalWorkItemType!
+ title: String!
widgets: [LocalWorkItemWidgetConnection]
}
@@ -51,7 +47,7 @@ type LocalUpdateWorkItemPayload {
}
extend type Query {
- workItem(id: ID!): LocalWorkItem!
+ localWorkItem(id: ID!): LocalWorkItem!
}
extend type Mutation {
diff --git a/app/assets/javascripts/work_items/graphql/update_work_item.mutation.graphql b/app/assets/javascripts/work_items/graphql/update_work_item.mutation.graphql
index f0563f099b2..efb1ed8d6df 100644
--- a/app/assets/javascripts/work_items/graphql/update_work_item.mutation.graphql
+++ b/app/assets/javascripts/work_items/graphql/update_work_item.mutation.graphql
@@ -1,16 +1,16 @@
#import './widget.fragment.graphql'
-mutation updateWorkItem($input: LocalUpdateWorkItemInput) {
- localUpdateWorkItem(input: $input) @client {
+mutation workItemUpdate($input: WorkItemUpdateInput!) {
+ workItemUpdate(input: $input) {
workItem {
id
- type
- widgets {
+ title
+ workItemType {
+ id
+ }
+ widgets @client {
nodes {
...WidgetBase
- ... on LocalTitleWidget {
- contentText
- }
}
}
}
diff --git a/app/assets/javascripts/work_items/graphql/work_item.query.graphql b/app/assets/javascripts/work_items/graphql/work_item.query.graphql
index 9f173f7c302..b32cb4f28fb 100644
--- a/app/assets/javascripts/work_items/graphql/work_item.query.graphql
+++ b/app/assets/javascripts/work_items/graphql/work_item.query.graphql
@@ -1,15 +1,15 @@
#import './widget.fragment.graphql'
query WorkItem($id: ID!) {
- workItem(id: $id) @client {
+ workItem(id: $id) {
id
- type
- widgets {
+ title
+ workItemType {
+ id
+ }
+ widgets @client {
nodes {
...WidgetBase
- ... on LocalTitleWidget {
- contentText
- }
}
}
}
diff --git a/app/assets/javascripts/work_items/pages/create_work_item.vue b/app/assets/javascripts/work_items/pages/create_work_item.vue
index 6c3bcf8f6a8..cc90cedb110 100644
--- a/app/assets/javascripts/work_items/pages/create_work_item.vue
+++ b/app/assets/javascripts/work_items/pages/create_work_item.vue
@@ -1,6 +1,8 @@
<script>
import { GlButton, GlAlert, GlLoadingIcon, GlDropdown, GlDropdownItem } from '@gitlab/ui';
import { s__ } from '~/locale';
+import { getIdFromGraphQLId } from '~/graphql_shared/utils';
+import workItemQuery from '../graphql/work_item.query.graphql';
import createWorkItemMutation from '../graphql/create_work_item.mutation.graphql';
import projectWorkItemTypesQuery from '../graphql/project_work_item_types.query.graphql';
@@ -67,21 +69,45 @@ export default {
variables: {
input: {
title: this.title,
+ projectPath: this.fullPath,
+ workItemTypeId: this.selectedWorkItemType?.id,
},
},
+ update(store, { data: { workItemCreate } }) {
+ const { id, title, workItemType } = workItemCreate.workItem;
+
+ store.writeQuery({
+ query: workItemQuery,
+ variables: {
+ id,
+ },
+ data: {
+ workItem: {
+ __typename: 'WorkItem',
+ id,
+ title,
+ workItemType,
+ widgets: {
+ __typename: 'LocalWorkItemWidgetConnection',
+ nodes: [],
+ },
+ },
+ },
+ });
+ },
});
const {
data: {
- localCreateWorkItem: {
- workItem: { id },
+ workItemCreate: {
+ workItem: { id, type },
},
},
} = response;
if (!this.isModal) {
- this.$router.push({ name: 'workItem', params: { id } });
+ this.$router.push({ name: 'workItem', params: { id: `${getIdFromGraphQLId(id)}` } });
} else {
- this.$emit('onCreate', this.title);
+ this.$emit('onCreate', { id, title: this.title, type });
}
} catch {
this.error = s__(
diff --git a/app/assets/javascripts/work_items/pages/work_item_root.vue b/app/assets/javascripts/work_items/pages/work_item_root.vue
index 4262e169655..32b6fc231a8 100644
--- a/app/assets/javascripts/work_items/pages/work_item_root.vue
+++ b/app/assets/javascripts/work_items/pages/work_item_root.vue
@@ -1,9 +1,10 @@
<script>
-import { GlAlert } from '@gitlab/ui';
+import { GlAlert, GlLoadingIcon } from '@gitlab/ui';
+import { convertToGraphQLId } from '~/graphql_shared/utils';
import Tracking from '~/tracking';
import workItemQuery from '../graphql/work_item.query.graphql';
import updateWorkItemMutation from '../graphql/update_work_item.mutation.graphql';
-import { widgetTypes, WI_TITLE_TRACK_LABEL } from '../constants';
+import { WI_TITLE_TRACK_LABEL } from '../constants';
import ItemTitle from '../components/item_title.vue';
@@ -14,6 +15,7 @@ export default {
components: {
ItemTitle,
GlAlert,
+ GlLoadingIcon,
},
mixins: [trackingMixin],
props: {
@@ -24,7 +26,7 @@ export default {
},
data() {
return {
- workItem: null,
+ workItem: {},
error: false,
};
},
@@ -33,7 +35,7 @@ export default {
query: workItemQuery,
variables() {
return {
- id: this.id,
+ id: this.gid,
};
},
},
@@ -47,19 +49,19 @@ export default {
property: '[type_work_item]',
};
},
- titleWidgetData() {
- return this.workItem?.widgets?.nodes?.find((widget) => widget.type === widgetTypes.title);
+ gid() {
+ return convertToGraphQLId('WorkItem', this.id);
},
},
methods: {
- async updateWorkItem(title) {
+ async updateWorkItem(updatedTitle) {
try {
await this.$apollo.mutate({
mutation: updateWorkItemMutation,
variables: {
input: {
- id: this.id,
- title,
+ id: this.gid,
+ title: updatedTitle,
},
},
});
@@ -79,12 +81,18 @@ export default {
}}</gl-alert>
<!-- Title widget placeholder -->
<div>
- <item-title
- v-if="titleWidgetData"
- :initial-title="titleWidgetData.contentText"
- data-testid="title"
- @title-changed="updateWorkItem"
+ <gl-loading-icon
+ v-if="$apollo.queries.workItem.loading"
+ size="md"
+ data-testid="loading-types"
/>
+ <template v-else>
+ <item-title
+ :initial-title="workItem.title"
+ data-testid="title"
+ @title-changed="updateWorkItem"
+ />
+ </template>
</div>
</section>
</template>
diff --git a/app/assets/stylesheets/framework/contextual_sidebar.scss b/app/assets/stylesheets/framework/contextual_sidebar.scss
index 7b4f68e7a44..e06c71dccf0 100644
--- a/app/assets/stylesheets/framework/contextual_sidebar.scss
+++ b/app/assets/stylesheets/framework/contextual_sidebar.scss
@@ -360,27 +360,10 @@
}
> li {
- // TODO: Remove this block once all sidebar badges use gl_badge_tag
- // https://gitlab.com/gitlab-org/gitlab/-/issues/350061
- .badge.badge-pill:not(.gl-badge) {
- @include gl-rounded-lg;
- @include gl-py-1;
- @include gl-px-3;
- background-color: $blue-100;
- color: $blue-700;
- }
-
&.active {
.sidebar-sub-level-items:not(.is-fly-out-only) {
display: block;
}
-
- // TODO: Remove this block once all sidebar badges use gl_badge_tag
- // https://gitlab.com/gitlab-org/gitlab/-/issues/350061
- .badge.badge-pill:not(.gl-badge) {
- @include gl-font-weight-normal;
- color: $blue-700;
- }
}
}
diff --git a/app/assets/stylesheets/framework/files.scss b/app/assets/stylesheets/framework/files.scss
index 9387500e66f..e378fcb6129 100644
--- a/app/assets/stylesheets/framework/files.scss
+++ b/app/assets/stylesheets/framework/files.scss
@@ -377,10 +377,6 @@ span.idiff {
color: $gl-text-color;
}
- .file-actions .ide-edit-button {
- z-index: 2;
- }
-
@include media-breakpoint-down(md) {
.file-actions {
margin-top: $gl-padding-8;
diff --git a/app/assets/stylesheets/framework/highlight.scss b/app/assets/stylesheets/framework/highlight.scss
index 122c605e603..a80643e695b 100644
--- a/app/assets/stylesheets/framework/highlight.scss
+++ b/app/assets/stylesheets/framework/highlight.scss
@@ -87,7 +87,7 @@ td.line-numbers {
}
.project-highlight-puc .unicode-bidi::before {
- content: '�';
+ content: '\FFFD';
cursor: pointer;
text-decoration: underline wavy $red-500;
}
diff --git a/app/assets/stylesheets/framework/mixins.scss b/app/assets/stylesheets/framework/mixins.scss
index 1e51bf3d974..1caf02937d5 100644
--- a/app/assets/stylesheets/framework/mixins.scss
+++ b/app/assets/stylesheets/framework/mixins.scss
@@ -439,6 +439,12 @@
.na {
color: inherit;
}
+
+ // Rouge `Comment` token (quoted text in email body)
+ .c {
+ color: $gl-grayish-blue;
+ font-style: italic;
+ }
}
}
}
diff --git a/app/assets/stylesheets/framework/typography.scss b/app/assets/stylesheets/framework/typography.scss
index feedc40b487..b1e44a81267 100644
--- a/app/assets/stylesheets/framework/typography.scss
+++ b/app/assets/stylesheets/framework/typography.scss
@@ -158,8 +158,8 @@
}
hr {
- // Darken 'whitesmoke' a bit to make it more visible in note bodies
- border-color: darken($gray-normal, 8%);
+ border-color: rgba($black, 0.15);
+
margin: 10px 0;
}
diff --git a/app/assets/stylesheets/notify.scss b/app/assets/stylesheets/notify.scss
index feb4ea77e58..2d501781119 100644
--- a/app/assets/stylesheets/notify.scss
+++ b/app/assets/stylesheets/notify.scss
@@ -1,24 +1,4 @@
-@import 'framework/mixins';
-@import 'framework/variables';
-
-img {
- max-width: 100%;
- height: auto;
-}
-
-p.details {
- font-style: italic;
- color: $gray-500;
-}
-
-.footer > p {
- font-size: small;
- color: $gray-500;
-}
-
-pre.commit-message {
- white-space: pre-wrap;
-}
+@import 'notify_base';
.gl-label-scoped {
border: 2px solid currentColor;
@@ -40,6 +20,11 @@ pre.commit-message {
color: $gl-text-color;
}
+.gl-label-text-scoped {
+ padding: 0 5px;
+ color: $gl-text-color;
+}
+
.content {
.markdown-code-block pre.code {
padding: $gl-padding-8 $input-horizontal-padding;
@@ -47,6 +32,4 @@ pre.commit-message {
border: 1px solid $gray-100;
border-radius: $border-radius-small;
}
-
- @include email-code-block;
}
diff --git a/app/assets/stylesheets/notify_base.scss b/app/assets/stylesheets/notify_base.scss
new file mode 100644
index 00000000000..8c6f9a27077
--- /dev/null
+++ b/app/assets/stylesheets/notify_base.scss
@@ -0,0 +1,25 @@
+@import 'framework/mixins';
+@import 'framework/variables';
+
+img {
+ max-width: 100%;
+ height: auto;
+}
+
+p.details {
+ font-style: italic;
+ color: $gray-500;
+}
+
+.footer > p {
+ font-size: small;
+ color: $gray-500;
+}
+
+pre.commit-message {
+ white-space: pre-wrap;
+}
+
+.content {
+ @include email-code-block;
+}
diff --git a/app/assets/stylesheets/notify_enhanced.scss b/app/assets/stylesheets/notify_enhanced.scss
new file mode 100644
index 00000000000..5df5a8592bf
--- /dev/null
+++ b/app/assets/stylesheets/notify_enhanced.scss
@@ -0,0 +1,68 @@
+// Import a subset of the GitLab UI framework:
+// keep parts that affect elements that can appear in emails;
+// omit Bootstrap Reboot since it adds unnecessary styles to every element.
+@import 'notify_base';
+@import 'bootstrap/scss/functions';
+@import 'bootstrap/scss/variables';
+@import 'bootstrap/scss/mixins';
+@import 'bootstrap/scss/code';
+@import '@gitlab/ui/src/scss/variables';
+@import '@gitlab/ui/src/scss/utility-mixins/index';
+@import '@gitlab/ui/src/scss/components';
+@import 'bootstrap_migration';
+@import 'framework/common';
+@import 'framework/gfm';
+@import 'framework/kbd';
+@import 'framework/tables';
+@import 'framework/typography';
+@import 'framework/emojis';
+
+body {
+ font-family: $regular-font;
+ font-size: inherit;
+}
+
+a {
+ text-decoration: none;
+}
+
+.content {
+ .md {
+ padding: 1rem 0;
+ }
+
+ hr {
+ border: 1px solid #e1e1e1;
+ }
+
+ blockquote {
+ border-top-width: 0;
+ border-bottom-width: 0;
+ border-right-width: 0;
+
+ &:dir(rtl) {
+ border-left-width: 0;
+ border-right-width: inherit;
+ }
+ }
+
+ table {
+ border-collapse: collapse;
+ }
+
+ .diff-table.code,
+ table.code {
+ width: auto;
+
+ td {
+ padding: inherit;
+
+ pre {
+ background-color: inherit;
+ margin: 0;
+ padding: 0;
+ border: inherit;
+ }
+ }
+ }
+}
diff --git a/app/assets/stylesheets/page_bundles/merge_requests.scss b/app/assets/stylesheets/page_bundles/merge_requests.scss
index 63e951be698..34a3d936a67 100644
--- a/app/assets/stylesheets/page_bundles/merge_requests.scss
+++ b/app/assets/stylesheets/page_bundles/merge_requests.scss
@@ -745,6 +745,10 @@ $tabs-holder-z-index: 250;
}
}
+.mr-section-container .resize-observer > object {
+ height: 0;
+}
+
// TODO: Move to GitLab UI
.mr-extenson-scrim {
background: linear-gradient(to bottom, rgba($gray-light, 0), rgba($gray-light, 1));
@@ -753,3 +757,7 @@ $tabs-holder-z-index: 250;
background: linear-gradient(to bottom, rgba(#333, 0), rgba(#333, 1));
}
}
+
+.attention-request-sidebar-popover {
+ z-index: 999;
+}
diff --git a/app/assets/stylesheets/pages/issuable.scss b/app/assets/stylesheets/pages/issuable.scss
index fa07d29b536..c00af802c06 100644
--- a/app/assets/stylesheets/pages/issuable.scss
+++ b/app/assets/stylesheets/pages/issuable.scss
@@ -108,12 +108,15 @@
.merge-icon {
color: $orange-400;
position: absolute;
- bottom: 0;
- right: 0;
filter: drop-shadow(0 0 0.5px $white) drop-shadow(0 0 1px $white) drop-shadow(0 0 2px $white);
}
}
+.assignee .merge-icon {
+ top: calc(50% + 0.25rem);
+ left: 1.275rem;
+}
+
.reviewer .merge-icon {
bottom: -3px;
right: -3px;
@@ -399,7 +402,7 @@
/*
This change should be temporary, because the DOM currently gets
generated from a ruby definition in `app/helpers/button_helper.rb`.
- As soon as the `copy to clipboard` button will be transfered to
+ As soon as the `copy to clipboard` button will be transferred to
Vue this should be adjusted as well.
*/
flex: 1;
diff --git a/app/assets/stylesheets/pages/projects.scss b/app/assets/stylesheets/pages/projects.scss
index ac3d4dad585..8034389adc8 100644
--- a/app/assets/stylesheets/pages/projects.scss
+++ b/app/assets/stylesheets/pages/projects.scss
@@ -134,47 +134,6 @@
}
}
-.fork-thumbnail {
- width: calc((100% / 2) - #{$gl-padding * 2});
-
- @include media-breakpoint-up(md) {
- width: calc((100% / 4) - #{$gl-padding * 2});
- }
-
- @include media-breakpoint-up(lg) {
- width: calc((100% / 5) - #{$gl-padding * 2});
- }
-
- &:hover:not(.disabled),
- &.forked {
- background-color: $blue-50;
- border-color: $blue-200;
- }
-
- .avatar-container,
- .identicon {
- float: none;
- margin-left: auto;
- margin-right: auto;
- }
-
- a.disabled {
- opacity: 0.3;
- cursor: not-allowed;
- }
-}
-
-.fork-thumbnail-container {
- display: flex;
- flex-wrap: wrap;
- margin-left: -$gl-padding;
- margin-right: -$gl-padding;
-
- > h5 {
- width: 100%;
- }
-}
-
.project-template {
> .form-group {
margin-bottom: 0;
diff --git a/app/assets/stylesheets/pages/search.scss b/app/assets/stylesheets/pages/search.scss
index 4c31cc6e111..c84a83c1fab 100644
--- a/app/assets/stylesheets/pages/search.scss
+++ b/app/assets/stylesheets/pages/search.scss
@@ -252,7 +252,8 @@ input[type='checkbox']:hover {
.btn-search,
.btn-success,
- .dropdown-menu-toggle {
+ .dropdown-menu-toggle,
+ .gl-new-dropdown {
width: 100%;
margin-top: 5px;
@@ -270,7 +271,8 @@ input[type='checkbox']:hover {
}
}
- .dropdown-menu-toggle {
+ .dropdown-menu-toggle,
+ .gl-new-dropdown {
@include media-breakpoint-up(sm) {
width: 180px;
margin-top: 0;
@@ -366,12 +368,13 @@ input[type='checkbox']:hover {
}
}
-// Disable webkit input icons, link to solution: https://stackoverflow.com/questions/9421551/how-do-i-remove-all-default-webkit-search-field-styling
-/* stylelint-disable property-no-vendor-prefix */
-input[type='search']::-webkit-search-decoration,
-input[type='search']::-webkit-search-cancel-button,
-input[type='search']::-webkit-search-results-button,
-input[type='search']::-webkit-search-results-decoration {
- -webkit-appearance: none;
+// Disable Webkit's search input styles
+input[type='search'] {
+ /* stylelint-disable-next-line property-no-vendor-prefix */
+ -webkit-appearance: textfield;
+
+ &::-webkit-search-cancel-button,
+ &::-webkit-search-results-button {
+ @include gl-display-none;
+ }
}
-/* stylelint-enable */
diff --git a/app/assets/stylesheets/startup/startup-dark.scss b/app/assets/stylesheets/startup/startup-dark.scss
index 1397590cc31..00195f553dc 100644
--- a/app/assets/stylesheets/startup/startup-dark.scss
+++ b/app/assets/stylesheets/startup/startup-dark.scss
@@ -993,19 +993,6 @@ input {
.top-nav-toggle .dropdown-icon {
margin-right: 0.5rem;
}
-.tanuki-logo .tanuki-left-ear,
-.tanuki-logo .tanuki-right-ear,
-.tanuki-logo .tanuki-nose {
- fill: #e24329;
-}
-.tanuki-logo .tanuki-left-eye,
-.tanuki-logo .tanuki-right-eye {
- fill: #fc6d26;
-}
-.tanuki-logo .tanuki-left-cheek,
-.tanuki-logo .tanuki-right-cheek {
- fill: #fca326;
-}
.context-header {
position: relative;
margin-right: 2px;
@@ -1393,24 +1380,11 @@ input {
border-radius: 4px;
box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.08);
}
-.sidebar-top-level-items > li .badge.badge-pill:not(.gl-badge) {
- border-radius: 0.5rem;
- padding-top: 0.125rem;
- padding-bottom: 0.125rem;
- padding-left: 0.5rem;
- padding-right: 0.5rem;
- background-color: #064787;
- color: #9dc7f1;
-}
.sidebar-top-level-items
> li.active
.sidebar-sub-level-items:not(.is-fly-out-only) {
display: block;
}
-.sidebar-top-level-items > li.active .badge.badge-pill:not(.gl-badge) {
- font-weight: 400;
- color: #9dc7f1;
-}
.sidebar-top-level-items li > a.gl-link {
color: #fafafa;
}
@@ -1786,7 +1760,6 @@ body.gl-dark {
--border-color: #4f4f4f;
--white: #333;
--black: #fff;
- --black-normal: #fafafa;
--svg-status-bg: #333;
}
.nav-sidebar li a {
@@ -1824,6 +1797,9 @@ body.gl-dark .navbar-gitlab .navbar-sub-nav {
body.gl-dark .navbar-gitlab .nav > li {
color: #fafafa;
}
+body.gl-dark .navbar-gitlab .nav > li.header-search-new {
+ color: #fafafa;
+}
body.gl-dark .navbar-gitlab .nav > li > a .notification-dot {
border: 2px solid #fafafa;
}
@@ -1861,8 +1837,8 @@ body.gl-dark
body.gl-dark .header-search {
background-color: rgba(250, 250, 250, 0.2) !important;
}
-body.gl-dark .header-search svg {
- color: rgba(250, 250, 250, 0.8) !important;
+body.gl-dark .header-search svg.gl-search-box-by-type-search-icon {
+ color: rgba(250, 250, 250, 0.8);
}
body.gl-dark .header-search input {
background-color: transparent;
@@ -2017,7 +1993,6 @@ body.gl-dark {
--border-color: #4f4f4f;
--white: #333;
--black: #fff;
- --black-normal: #fafafa;
--svg-status-bg: #333;
}
.tab-width-8 {
diff --git a/app/assets/stylesheets/startup/startup-general.scss b/app/assets/stylesheets/startup/startup-general.scss
index 0d35c400676..6d66e207bdc 100644
--- a/app/assets/stylesheets/startup/startup-general.scss
+++ b/app/assets/stylesheets/startup/startup-general.scss
@@ -978,19 +978,6 @@ input {
.top-nav-toggle .dropdown-icon {
margin-right: 0.5rem;
}
-.tanuki-logo .tanuki-left-ear,
-.tanuki-logo .tanuki-right-ear,
-.tanuki-logo .tanuki-nose {
- fill: #e24329;
-}
-.tanuki-logo .tanuki-left-eye,
-.tanuki-logo .tanuki-right-eye {
- fill: #fc6d26;
-}
-.tanuki-logo .tanuki-left-cheek,
-.tanuki-logo .tanuki-right-cheek {
- fill: #fca326;
-}
.context-header {
position: relative;
margin-right: 2px;
@@ -1378,24 +1365,11 @@ input {
border-radius: 4px;
box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.08);
}
-.sidebar-top-level-items > li .badge.badge-pill:not(.gl-badge) {
- border-radius: 0.5rem;
- padding-top: 0.125rem;
- padding-bottom: 0.125rem;
- padding-left: 0.5rem;
- padding-right: 0.5rem;
- background-color: #cbe2f9;
- color: #0b5cad;
-}
.sidebar-top-level-items
> li.active
.sidebar-sub-level-items:not(.is-fly-out-only) {
display: block;
}
-.sidebar-top-level-items > li.active .badge.badge-pill:not(.gl-badge) {
- font-weight: 400;
- color: #0b5cad;
-}
.sidebar-top-level-items li > a.gl-link {
color: #303030;
}
diff --git a/app/assets/stylesheets/startup/startup-signin.scss b/app/assets/stylesheets/startup/startup-signin.scss
index c5cbe58ec27..213d1c013a0 100644
--- a/app/assets/stylesheets/startup/startup-signin.scss
+++ b/app/assets/stylesheets/startup/startup-signin.scss
@@ -514,19 +514,6 @@ label.label-bold {
.navbar-empty .brand-header-logo {
max-height: 100%;
}
-.tanuki-logo .tanuki-left-ear,
-.tanuki-logo .tanuki-right-ear,
-.tanuki-logo .tanuki-nose {
- fill: #e24329;
-}
-.tanuki-logo .tanuki-left-eye,
-.tanuki-logo .tanuki-right-eye {
- fill: #fc6d26;
-}
-.tanuki-logo .tanuki-left-cheek,
-.tanuki-logo .tanuki-right-cheek {
- fill: #fca326;
-}
input::-moz-placeholder {
color: #868686;
opacity: 1;
diff --git a/app/assets/stylesheets/themes/_dark.scss b/app/assets/stylesheets/themes/_dark.scss
index 9db134ffa65..3cb8c58a380 100644
--- a/app/assets/stylesheets/themes/_dark.scss
+++ b/app/assets/stylesheets/themes/_dark.scss
@@ -199,7 +199,6 @@ body.gl-dark {
--white: #{$white};
--black: #{$black};
- --black-normal: #{$black-normal};
--svg-status-bg: #{$white};
diff --git a/app/assets/stylesheets/themes/theme_helper.scss b/app/assets/stylesheets/themes/theme_helper.scss
index ec0928fc3d4..c6e29c7f8b0 100644
--- a/app/assets/stylesheets/themes/theme_helper.scss
+++ b/app/assets/stylesheets/themes/theme_helper.scss
@@ -64,6 +64,10 @@
> li {
color: $search-and-nav-links;
+ &.header-search-new {
+ color: $sidebar-text;
+ }
+
> a {
.notification-dot {
border: 2px solid $nav-svg-color;
@@ -151,10 +155,11 @@
background-color: rgba($search-and-nav-links, 0.3) !important;
}
- svg {
- color: rgba($search-and-nav-links, 0.8) !important;
+ svg.gl-search-box-by-type-search-icon {
+ color: rgba($search-and-nav-links, 0.8);
}
+
input {
background-color: transparent;
color: rgba($search-and-nav-links, 0.8);
diff --git a/app/assets/stylesheets/utilities.scss b/app/assets/stylesheets/utilities.scss
index 8a4f9c32f9f..0511a179980 100644
--- a/app/assets/stylesheets/utilities.scss
+++ b/app/assets/stylesheets/utilities.scss
@@ -342,4 +342,32 @@ to @gitlab/ui by https://gitlab.com/gitlab-org/gitlab-ui/-/issues/1709
margin-bottom: $gl-spacing-scale-12 !important; // only need !important for now so that it overrides styles from @gitlab/ui which currently take precedence
}
}
+
/* End gitlab-ui#1709 */
+
+/*
+ * The below two styles will be moved to @gitlab/ui by
+ * https://gitlab.com/gitlab-org/gitlab-ui/-/issues/1750
+ */
+.gl-max-w-34 {
+ max-width: 34 * $grid-size;
+}
+
+.gl-max-w-80 {
+ max-width: 80 * $grid-size;
+}
+
+/*
+ * The below style will be moved to @gitlab/ui by
+ * https://gitlab.com/gitlab-org/gitlab-ui/-/issues/1751
+ */
+.gl-filter-blur-1 {
+ backdrop-filter: blur(2px);
+ /* stylelint-disable property-no-vendor-prefix */
+ -webkit-backdrop-filter: blur(2px); // still required by Safari
+}
+
+// Will be moved to @gitlab/ui by https://gitlab.com/gitlab-org/gitlab-ui/-/merge_requests/2708
+.gl-inset-border-l-3-red-600 {
+ box-shadow: inset $gl-border-size-3 0 0 0 $red-600;
+}
diff --git a/app/components/pajamas/component.rb b/app/components/pajamas/component.rb
new file mode 100644
index 00000000000..b05d93b680e
--- /dev/null
+++ b/app/components/pajamas/component.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+module Pajamas
+ class Component < ViewComponent::Base
+ private
+
+ # :nocov:
+
+ # Filter a given a value against a list of allowed values
+ # If no value is given or value is not allowed return default one
+ #
+ # @param [Object] value
+ # @param [Enumerable] allowed_values
+ # @param [Object] default
+ def filter_attribute(value, allowed_values, default: nil)
+ return default unless value
+ return value if allowed_values.include?(value)
+
+ default
+ end
+ # :nocov:
+ end
+end
diff --git a/app/components/pajamas/toggle_component.html.haml b/app/components/pajamas/toggle_component.html.haml
new file mode 100644
index 00000000000..1716e8b69c3
--- /dev/null
+++ b/app/components/pajamas/toggle_component.html.haml
@@ -0,0 +1,16 @@
+%span{ class: @classes,
+ data: { name: @name,
+ id: @id,
+ is_checked: @is_checked.to_s,
+ disabled: @is_disabled.to_s,
+ is_loading: @is_loading.to_s,
+ label: @label,
+ help: @help,
+ label_position: @label_position,
+ **@data } }
+
+-# Leverage this block to render a rich help text. To render a plain text help text,
+-# prefer the `help` parameter.
+- if content.present?
+ .gl-text-secondary.gl-mt-1
+ = content
diff --git a/app/components/pajamas/toggle_component.rb b/app/components/pajamas/toggle_component.rb
new file mode 100644
index 00000000000..2d99f3d3b69
--- /dev/null
+++ b/app/components/pajamas/toggle_component.rb
@@ -0,0 +1,34 @@
+# frozen_string_literal: true
+
+# Renders a GlToggle root element
+# To actually initialize the component, make sure to call the initToggle helper from ~/toggles.
+class Pajamas::ToggleComponent < Pajamas::Component
+ LABEL_POSITION_OPTIONS = [:top, :left, :hidden].freeze
+
+ # @param [String] classes
+ # @param [String] label
+ # @param [Symbol] label_position :top, :left or :hidden
+ # @param [String] id
+ # @param [String] name
+ # @param [String] help
+ # @param [Hash] data
+ # @param [Boolean] is_disabled
+ # @param [Boolean] is_checked
+ # @param [Boolean] is_loading
+ def initialize(
+ classes:, label: nil, label_position: nil,
+ id: nil, name: nil, help: nil, data: {},
+ is_disabled: false, is_checked: false, is_loading: false)
+
+ @id = id
+ @name = name
+ @classes = classes
+ @label = label
+ @label_position = filter_attribute(label_position, LABEL_POSITION_OPTIONS)
+ @help = help
+ @data = data
+ @is_disabled = is_disabled
+ @is_checked = is_checked
+ @is_loading = is_loading
+ end
+end
diff --git a/app/controllers/admin/application_settings_controller.rb b/app/controllers/admin/application_settings_controller.rb
index 1d0930ba73c..0dd85376050 100644
--- a/app/controllers/admin/application_settings_controller.rb
+++ b/app/controllers/admin/application_settings_controller.rb
@@ -66,12 +66,17 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
render html: Gitlab::Highlight.highlight('payload.json', usage_data_json, language: 'json')
end
- format.json { render json: Gitlab::Usage::ServicePingReport.for(output: :all_metrics_values, cached: true).to_json }
+
+ format.json do
+ Gitlab::UsageDataCounters::ServiceUsageDataCounter.count(:download_payload_click)
+
+ render json: Gitlab::Usage::ServicePingReport.for(output: :all_metrics_values, cached: true).to_json
+ end
end
end
def reset_registration_token
- @application_setting.reset_runners_registration_token!
+ ::Ci::Runners::ResetRegistrationTokenService.new(@application_setting, current_user).execute
flash[:notice] = _('New runners registration token has been generated!')
redirect_to admin_runners_path
diff --git a/app/controllers/admin/broadcast_messages_controller.rb b/app/controllers/admin/broadcast_messages_controller.rb
index 4660b0bfbb0..ef843a84e6c 100644
--- a/app/controllers/admin/broadcast_messages_controller.rb
+++ b/app/controllers/admin/broadcast_messages_controller.rb
@@ -65,6 +65,6 @@ class Admin::BroadcastMessagesController < Admin::ApplicationController
target_path
broadcast_type
dismissable
- ))
+ ), target_access_levels: []).reverse_merge!(target_access_levels: [])
end
end
diff --git a/app/controllers/admin/clusters_controller.rb b/app/controllers/admin/clusters_controller.rb
index 9a642e53d86..052c8821588 100644
--- a/app/controllers/admin/clusters_controller.rb
+++ b/app/controllers/admin/clusters_controller.rb
@@ -2,6 +2,7 @@
class Admin::ClustersController < Clusters::ClustersController
include EnforcesAdminAuthentication
+ before_action :ensure_feature_enabled!
layout 'admin'
diff --git a/app/controllers/admin/cohorts_controller.rb b/app/controllers/admin/cohorts_controller.rb
index e750b5c5ad4..468a1077694 100644
--- a/app/controllers/admin/cohorts_controller.rb
+++ b/app/controllers/admin/cohorts_controller.rb
@@ -5,6 +5,8 @@ class Admin::CohortsController < Admin::ApplicationController
feature_category :devops_reports
+ urgency :low
+
def index
@cohorts = load_cohorts
track_cohorts_visit
diff --git a/app/controllers/admin/dev_ops_report_controller.rb b/app/controllers/admin/dev_ops_report_controller.rb
index a235af7c538..47e3337aed7 100644
--- a/app/controllers/admin/dev_ops_report_controller.rb
+++ b/app/controllers/admin/dev_ops_report_controller.rb
@@ -9,6 +9,8 @@ class Admin::DevOpsReportController < Admin::ApplicationController
feature_category :devops_reports
+ urgency :low
+
# rubocop: disable CodeReuse/ActiveRecord
def show
@metric = DevOpsReport::Metric.order(:created_at).last&.present
diff --git a/app/controllers/admin/instance_review_controller.rb b/app/controllers/admin/instance_review_controller.rb
index 1ce6e66c6de..cc801bce5b7 100644
--- a/app/controllers/admin/instance_review_controller.rb
+++ b/app/controllers/admin/instance_review_controller.rb
@@ -2,6 +2,8 @@
class Admin::InstanceReviewController < Admin::ApplicationController
feature_category :devops_reports
+ urgency :low
+
def index
redirect_to("#{Gitlab::SubscriptionPortal.subscriptions_instance_review_url}?#{instance_review_params}")
end
diff --git a/app/controllers/admin/integrations_controller.rb b/app/controllers/admin/integrations_controller.rb
index ad0ee0b2cef..db9835e65ec 100644
--- a/app/controllers/admin/integrations_controller.rb
+++ b/app/controllers/admin/integrations_controller.rb
@@ -5,6 +5,10 @@ class Admin::IntegrationsController < Admin::ApplicationController
before_action :not_found, unless: -> { instance_level_integrations? }
+ before_action do
+ push_frontend_feature_flag(:integration_form_sections, default_enabled: :yaml)
+ end
+
feature_category :integrations
def overrides
diff --git a/app/controllers/admin/runner_projects_controller.rb b/app/controllers/admin/runner_projects_controller.rb
index 598c536d652..a4055cbe990 100644
--- a/app/controllers/admin/runner_projects_controller.rb
+++ b/app/controllers/admin/runner_projects_controller.rb
@@ -8,7 +8,7 @@ class Admin::RunnerProjectsController < Admin::ApplicationController
def create
@runner = Ci::Runner.find(params[:runner_project][:runner_id])
- if @runner.assign_to(@project, current_user)
+ if ::Ci::Runners::AssignRunnerService.new(@runner, @project, current_user).execute
redirect_to edit_admin_runner_url(@runner), notice: s_('Runners|Runner assigned to project.')
else
redirect_to edit_admin_runner_url(@runner), alert: 'Failed adding runner to project'
@@ -18,7 +18,8 @@ class Admin::RunnerProjectsController < Admin::ApplicationController
def destroy
rp = Ci::RunnerProject.find(params[:id])
runner = rp.runner
- rp.destroy
+
+ ::Ci::Runners::UnassignRunnerService.new(rp, current_user).execute
redirect_to edit_admin_runner_url(runner), status: :found, notice: s_('Runners|Runner unassigned from project.')
end
diff --git a/app/controllers/admin/runners_controller.rb b/app/controllers/admin/runners_controller.rb
index f7f78ab3229..2744be0150c 100644
--- a/app/controllers/admin/runners_controller.rb
+++ b/app/controllers/admin/runners_controller.rb
@@ -23,7 +23,7 @@ class Admin::RunnersController < Admin::ApplicationController
end
def update
- if Ci::UpdateRunnerService.new(@runner).update(runner_params)
+ if Ci::Runners::UpdateRunnerService.new(@runner).update(runner_params)
respond_to do |format|
format.html { redirect_to edit_admin_runner_path(@runner) }
end
@@ -34,13 +34,13 @@ class Admin::RunnersController < Admin::ApplicationController
end
def destroy
- Ci::UnregisterRunnerService.new(@runner).execute
+ Ci::Runners::UnregisterRunnerService.new(@runner, current_user).execute
redirect_to admin_runners_path, status: :found
end
def resume
- if Ci::UpdateRunnerService.new(@runner).update(active: true)
+ if Ci::Runners::UpdateRunnerService.new(@runner).update(active: true)
redirect_to admin_runners_path, notice: _('Runner was successfully updated.')
else
redirect_to admin_runners_path, alert: _('Runner was not updated.')
@@ -48,7 +48,7 @@ class Admin::RunnersController < Admin::ApplicationController
end
def pause
- if Ci::UpdateRunnerService.new(@runner).update(active: false)
+ if Ci::Runners::UpdateRunnerService.new(@runner).update(active: false)
redirect_to admin_runners_path, notice: _('Runner was successfully updated.')
else
redirect_to admin_runners_path, alert: _('Runner was not updated.')
diff --git a/app/controllers/admin/usage_trends_controller.rb b/app/controllers/admin/usage_trends_controller.rb
index 0b315517594..2cede1aec05 100644
--- a/app/controllers/admin/usage_trends_controller.rb
+++ b/app/controllers/admin/usage_trends_controller.rb
@@ -7,6 +7,8 @@ class Admin::UsageTrendsController < Admin::ApplicationController
feature_category :devops_reports
+ urgency :low
+
def index
end
end
diff --git a/app/controllers/admin/users_controller.rb b/app/controllers/admin/users_controller.rb
index c1fa104ffda..f19333d5d57 100644
--- a/app/controllers/admin/users_controller.rb
+++ b/app/controllers/admin/users_controller.rb
@@ -2,6 +2,7 @@
class Admin::UsersController < Admin::ApplicationController
include RoutableActions
+ include SortingHelper
before_action :user, except: [:index, :new, :create]
before_action :check_impersonation_availability, only: :impersonate
@@ -18,7 +19,8 @@ class Admin::UsersController < Admin::ApplicationController
@users = User.filter_items(params[:filter]).order_name_asc
@users = @users.search(params[:search_query], with_private_emails: true) if params[:search_query].present?
@users = users_with_included_associations(@users)
- @users = @users.sort_by_attribute(@sort = params[:sort])
+ @sort = params[:sort].presence || sort_value_name
+ @users = @users.sort_by_attribute(@sort)
@users = @users.page(params[:page])
@users = @users.without_count if paginate_without_count?
end
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 8e758c669db..1d17e8aa085 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -111,6 +111,15 @@ class ApplicationController < ActionController::Base
render plain: e.message, status: :too_many_requests
end
+ content_security_policy do |p|
+ next if p.directives.blank?
+ next unless Gitlab::CurrentSettings.snowplow_enabled? && !Gitlab::CurrentSettings.snowplow_collector_hostname.blank?
+
+ default_connect_src = p.directives['connect-src'] || p.directives['default-src']
+ connect_src_values = Array.wrap(default_connect_src) | [Gitlab::CurrentSettings.snowplow_collector_hostname]
+ p.connect_src(*connect_src_values)
+ end
+
def redirect_back_or_default(default: root_path, options: {})
redirect_back(fallback_location: default, **options)
end
@@ -237,19 +246,19 @@ class ApplicationController < ActionController::Base
end
def git_not_found!
- render "errors/git_not_found.html", layout: "errors", status: :not_found
+ render template: "errors/git_not_found", formats: :html, layout: "errors", status: :not_found
end
def render_403
respond_to do |format|
- format.html { render "errors/access_denied", layout: "errors", status: :forbidden }
+ format.html { render template: "errors/access_denied", formats: :html, layout: "errors", status: :forbidden }
format.any { head :forbidden }
end
end
def render_404
respond_to do |format|
- format.html { render "errors/not_found", layout: "errors", status: :not_found }
+ format.html { render template: "errors/not_found", formats: :html, layout: "errors", status: :not_found }
# Prevent the Rails CSRF protector from thinking a missing .js file is a JavaScript file
format.js { render json: '', status: :not_found, content_type: 'application/json' }
format.any { head :not_found }
diff --git a/app/controllers/autocomplete_controller.rb b/app/controllers/autocomplete_controller.rb
index ee5caf63703..4bcd1be9f53 100644
--- a/app/controllers/autocomplete_controller.rb
+++ b/app/controllers/autocomplete_controller.rb
@@ -1,8 +1,10 @@
# frozen_string_literal: true
class AutocompleteController < ApplicationController
+ include SearchRateLimitable
+
skip_before_action :authenticate_user!, only: [:users, :award_emojis, :merge_request_target_branches]
- before_action :check_email_search_rate_limit!, only: [:users]
+ before_action :check_search_rate_limit!, only: [:users, :projects]
feature_category :users, [:users, :user]
feature_category :projects, [:projects]
@@ -72,12 +74,6 @@ class AutocompleteController < ApplicationController
def target_branch_params
params.permit(:group_id, :project_id).select { |_, v| v.present? }
end
-
- def check_email_search_rate_limit!
- search_params = Gitlab::Search::Params.new(params)
-
- check_rate_limit!(:user_email_lookup, scope: [current_user]) if search_params.email_lookup?
- end
end
AutocompleteController.prepend_mod_with('AutocompleteController')
diff --git a/app/controllers/clusters/clusters_controller.rb b/app/controllers/clusters/clusters_controller.rb
index c12ceca9c3b..d9179129983 100644
--- a/app/controllers/clusters/clusters_controller.rb
+++ b/app/controllers/clusters/clusters_controller.rb
@@ -9,15 +9,25 @@ class Clusters::ClustersController < Clusters::BaseController
before_action :generate_gcp_authorize_url, only: [:new]
before_action :validate_gcp_token, only: [:new]
before_action :gcp_cluster, only: [:new]
- before_action :user_cluster, only: [:new]
+ before_action :user_cluster, only: [:new, :connect]
before_action :authorize_read_cluster!, only: [:show, :index]
- before_action :authorize_create_cluster!, only: [:new, :authorize_aws_role]
+ before_action :authorize_create_cluster!, only: [:new, :connect, :authorize_aws_role]
before_action :authorize_update_cluster!, only: [:update]
before_action :update_applications_status, only: [:cluster_status]
+ before_action :ensure_feature_enabled!, except: :index
helper_method :token_in_session
STATUS_POLLING_INTERVAL = 10_000
+ AWS_CSP_DOMAINS = %w[https://ec2.ap-east-1.amazonaws.com https://ec2.ap-northeast-1.amazonaws.com https://ec2.ap-northeast-2.amazonaws.com https://ec2.ap-northeast-3.amazonaws.com https://ec2.ap-south-1.amazonaws.com https://ec2.ap-southeast-1.amazonaws.com https://ec2.ap-southeast-2.amazonaws.com https://ec2.ca-central-1.amazonaws.com https://ec2.eu-central-1.amazonaws.com https://ec2.eu-north-1.amazonaws.com https://ec2.eu-west-1.amazonaws.com https://ec2.eu-west-2.amazonaws.com https://ec2.eu-west-3.amazonaws.com https://ec2.me-south-1.amazonaws.com https://ec2.sa-east-1.amazonaws.com https://ec2.us-east-1.amazonaws.com https://ec2.us-east-2.amazonaws.com https://ec2.us-west-1.amazonaws.com https://ec2.us-west-2.amazonaws.com https://ec2.af-south-1.amazonaws.com https://iam.amazonaws.com].freeze
+
+ content_security_policy do |p|
+ next if p.directives.blank?
+
+ default_connect_src = p.directives['connect-src'] || p.directives['default-src']
+ connect_src_values = Array.wrap(default_connect_src) | AWS_CSP_DOMAINS
+ p.connect_src(*connect_src_values)
+ end
def index
@clusters = cluster_list
@@ -142,7 +152,7 @@ class Clusters::ClustersController < Clusters::BaseController
validate_gcp_token
gcp_cluster
- render :new, locals: { active_tab: 'add' }
+ render :connect
end
end
@@ -163,7 +173,17 @@ class Clusters::ClustersController < Clusters::BaseController
private
+ def certificate_based_clusters_enabled?
+ Feature.enabled?(:certificate_based_clusters, clusterable, default_enabled: :yaml, type: :ops)
+ end
+
+ def ensure_feature_enabled!
+ render_404 unless certificate_based_clusters_enabled?
+ end
+
def cluster_list
+ return [] unless certificate_based_clusters_enabled?
+
finder = ClusterAncestorsFinder.new(clusterable.subject, current_user)
clusters = finder.execute
diff --git a/app/controllers/concerns/floc_opt_out.rb b/app/controllers/concerns/floc_opt_out.rb
index 3039af02bbb..50a52cecda9 100644
--- a/app/controllers/concerns/floc_opt_out.rb
+++ b/app/controllers/concerns/floc_opt_out.rb
@@ -4,7 +4,7 @@ module FlocOptOut
extend ActiveSupport::Concern
included do
- after_action :set_floc_opt_out_header, unless: :floc_enabled?
+ before_action :set_floc_opt_out_header, unless: :floc_enabled?
end
def floc_enabled?
diff --git a/app/controllers/concerns/issuable_actions.rb b/app/controllers/concerns/issuable_actions.rb
index eae087bca4d..ae90bd59d01 100644
--- a/app/controllers/concerns/issuable_actions.rb
+++ b/app/controllers/concerns/issuable_actions.rb
@@ -17,10 +17,6 @@ module IssuableActions
def show
respond_to do |format|
format.html do
- @show_crm_contacts = issuable.is_a?(Issue) && # rubocop:disable Gitlab/ModuleWithInstanceVariables
- can?(current_user, :read_crm_contact, issuable.project.group) &&
- CustomerRelations::Contact.exists_for_group?(issuable.project.group)
-
@issuable_sidebar = serializer.represent(issuable, serializer: 'sidebar') # rubocop:disable Gitlab/ModuleWithInstanceVariables
render 'show'
end
@@ -43,18 +39,18 @@ module IssuableActions
if updated_issuable.is_a?(Spammable)
respond_to do |format|
format.html do
- # NOTE: This redirect is intentionally only performed in the case where the updated
- # issuable is a spammable, and intentionally is not performed in the non-spammable case.
- # This preserves the legacy behavior of this action.
if updated_issuable.valid?
+ # NOTE: This redirect is intentionally only performed in the case where the valid updated
+ # issuable is a spammable, and intentionally is not performed below in the
+ # valid non-spammable case. This preserves the legacy behavior of this action.
redirect_to spammable_path
else
- with_captcha_check_html_format { render :edit }
+ with_captcha_check_html_format(spammable: spammable) { render :edit }
end
end
format.json do
- with_captcha_check_json_format { render_entity_json }
+ with_captcha_check_json_format(spammable: spammable) { render_entity_json }
end
end
else
diff --git a/app/controllers/concerns/issuable_collections_action.rb b/app/controllers/concerns/issuable_collections_action.rb
index b68db0e3f9f..96cf6021ea9 100644
--- a/app/controllers/concerns/issuable_collections_action.rb
+++ b/app/controllers/concerns/issuable_collections_action.rb
@@ -17,7 +17,7 @@ module IssuableCollectionsAction
respond_to do |format|
format.html
- format.atom { render layout: 'xml.atom' }
+ format.atom { render layout: 'xml' }
end
end
diff --git a/app/controllers/concerns/membership_actions.rb b/app/controllers/concerns/membership_actions.rb
index f716c1f6c2f..0b9024dc3db 100644
--- a/app/controllers/concerns/membership_actions.rb
+++ b/app/controllers/concerns/membership_actions.rb
@@ -4,17 +4,6 @@ module MembershipActions
include MembersPresentation
extend ActiveSupport::Concern
- def create
- create_params = params.permit(:user_ids, :access_level, :expires_at)
- result = Members::CreateService.new(current_user, create_params.merge({ source: membershipable, invite_source: "#{plain_source_type}-members-page" })).execute
-
- if result[:status] == :success
- redirect_to members_page_url, notice: _('Users were successfully added.')
- else
- redirect_to members_page_url, alert: result[:message]
- end
- end
-
def update
update_params = params.require(root_params_key).permit(:access_level, :expires_at)
member = membershipable.members_and_requesters.find(params[:id])
@@ -79,8 +68,8 @@ module MembershipActions
notice: _('Your request for access has been queued for review.')
else
redirect_to polymorphic_path(membershipable),
- alert: _("Your request for access could not be processed: %{error_meesage}") %
- { error_meesage: access_requester.errors.full_messages.to_sentence }
+ alert: _("Your request for access could not be processed: %{error_message}") %
+ { error_message: access_requester.errors.full_messages.to_sentence }
end
end
diff --git a/app/controllers/concerns/product_analytics_tracking.rb b/app/controllers/concerns/product_analytics_tracking.rb
new file mode 100644
index 00000000000..03296d6b233
--- /dev/null
+++ b/app/controllers/concerns/product_analytics_tracking.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+module ProductAnalyticsTracking
+ include Gitlab::Tracking::Helpers
+ include RedisTracking
+ extend ActiveSupport::Concern
+
+ class_methods do
+ def track_event(*controller_actions, name:, conditions: nil, destinations: [:redis_hll], &block)
+ custom_conditions = [:trackable_html_request?, *conditions]
+
+ after_action only: controller_actions, if: custom_conditions do
+ route_events_to(destinations, name, &block)
+ end
+ end
+ end
+
+ private
+
+ def route_events_to(destinations, name, &block)
+ track_unique_redis_hll_event(name, &block) if destinations.include?(:redis_hll)
+
+ if destinations.include?(:snowplow) && Feature.enabled?(:route_hll_to_snowplow, tracking_namespace_source, default_enabled: :yaml)
+ Gitlab::Tracking.event(self.class.to_s, name, namespace: tracking_namespace_source, user: current_user)
+ end
+ end
+end
diff --git a/app/controllers/concerns/search_rate_limitable.rb b/app/controllers/concerns/search_rate_limitable.rb
new file mode 100644
index 00000000000..a77ebd276b6
--- /dev/null
+++ b/app/controllers/concerns/search_rate_limitable.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+module SearchRateLimitable
+ extend ActiveSupport::Concern
+
+ private
+
+ def check_search_rate_limit!
+ if current_user
+ check_rate_limit!(:search_rate_limit, scope: [current_user])
+ else
+ check_rate_limit!(:search_rate_limit_unauthenticated, scope: [request.ip])
+ end
+ end
+end
diff --git a/app/controllers/concerns/sessionless_authentication.rb b/app/controllers/concerns/sessionless_authentication.rb
index 1f17f9f4e1b..48daacc09c2 100644
--- a/app/controllers/concerns/sessionless_authentication.rb
+++ b/app/controllers/concerns/sessionless_authentication.rb
@@ -26,6 +26,9 @@ module SessionlessAuthentication
# for every request. If you want the token to work as a
# sign in token, you can simply remove store: false.
sign_in(user, store: false, message: :sessionless_sign_in)
+ elsif request_authenticator.can_sign_in_bot?(user)
+ # we suppress callbacks to avoid redirecting the bot
+ sign_in(user, store: false, message: :sessionless_sign_in, run_callbacks: false)
end
end
diff --git a/app/controllers/concerns/spammable_actions/akismet_mark_as_spam_action.rb b/app/controllers/concerns/spammable_actions/akismet_mark_as_spam_action.rb
index 234c591ffb7..044519004b2 100644
--- a/app/controllers/concerns/spammable_actions/akismet_mark_as_spam_action.rb
+++ b/app/controllers/concerns/spammable_actions/akismet_mark_as_spam_action.rb
@@ -2,7 +2,6 @@
module SpammableActions::AkismetMarkAsSpamAction
extend ActiveSupport::Concern
- include SpammableActions::Attributes
included do
before_action :authorize_submit_spammable!, only: :mark_as_spam
@@ -22,7 +21,15 @@ module SpammableActions::AkismetMarkAsSpamAction
access_denied! unless current_user.can_admin_all_resources?
end
+ def spammable
+ # The class extending this module should define the #spammable method to return
+ # the Spammable model instance via: `alias_method :spammable , <:model_name>`
+ raise NotImplementedError, "#{self.class} should implement #{__method__}"
+ end
+
def spammable_path
- raise NotImplementedError, "#{self.class} does not implement #{__method__}"
+ # The class extending this module should define the #spammable_path method to return
+ # the route helper pointing to the action to show the Spammable instance
+ raise NotImplementedError, "#{self.class} should implement #{__method__}"
end
end
diff --git a/app/controllers/concerns/spammable_actions/attributes.rb b/app/controllers/concerns/spammable_actions/attributes.rb
deleted file mode 100644
index d7060e47c07..00000000000
--- a/app/controllers/concerns/spammable_actions/attributes.rb
+++ /dev/null
@@ -1,13 +0,0 @@
-# frozen_string_literal: true
-
-module SpammableActions
- module Attributes
- extend ActiveSupport::Concern
-
- private
-
- def spammable
- raise NotImplementedError, "#{self.class} does not implement #{__method__}"
- end
- end
-end
diff --git a/app/controllers/concerns/spammable_actions/captcha_check/common.rb b/app/controllers/concerns/spammable_actions/captcha_check/common.rb
index 7c047e02a1d..aaeb6b3ba83 100644
--- a/app/controllers/concerns/spammable_actions/captcha_check/common.rb
+++ b/app/controllers/concerns/spammable_actions/captcha_check/common.rb
@@ -1,23 +1,25 @@
# frozen_string_literal: true
-module SpammableActions::CaptchaCheck
- module Common
- extend ActiveSupport::Concern
+module SpammableActions
+ module CaptchaCheck
+ module Common
+ extend ActiveSupport::Concern
- private
+ private
- def with_captcha_check_common(captcha_render_lambda:, &block)
- # If the Spammable indicates that CAPTCHA is not necessary (either due to it not being flagged
- # as spam, or if spam/captcha is disabled for some reason), then we will go ahead and
- # yield to the block containing the action's original behavior, then return.
- return yield unless spammable.render_recaptcha?
+ def with_captcha_check_common(spammable:, captcha_render_lambda:, &block)
+ # If the Spammable indicates that CAPTCHA is not necessary (either due to it not being flagged
+ # as spam, or if spam/captcha is disabled for some reason), then we will go ahead and
+ # yield to the block containing the action's original behavior, then return.
+ return yield unless spammable.render_recaptcha?
- # If we got here, we need to render the CAPTCHA instead of yielding to action's original
- # behavior. We will present a CAPTCHA to be solved by executing the lambda which was passed
- # as the `captcha_render_lambda:` argument. This lambda contains either the HTML-specific or
- # JSON-specific behavior to cause the CAPTCHA modal to be rendered.
- Gitlab::Recaptcha.load_configurations!
- captcha_render_lambda.call
+ # If we got here, we need to render the CAPTCHA instead of yielding to action's original
+ # behavior. We will present a CAPTCHA to be solved by executing the lambda which was passed
+ # as the `captcha_render_lambda:` argument. This lambda contains either the HTML-specific or
+ # JSON-specific behavior to cause the CAPTCHA modal to be rendered.
+ Gitlab::Recaptcha.load_configurations!
+ captcha_render_lambda.call
+ end
end
end
end
diff --git a/app/controllers/concerns/spammable_actions/captcha_check/html_format_actions_support.rb b/app/controllers/concerns/spammable_actions/captcha_check/html_format_actions_support.rb
index f687c0fcf2d..b254916cdd6 100644
--- a/app/controllers/concerns/spammable_actions/captcha_check/html_format_actions_support.rb
+++ b/app/controllers/concerns/spammable_actions/captcha_check/html_format_actions_support.rb
@@ -8,7 +8,6 @@
# which supports JSON format should be used instead.
module SpammableActions::CaptchaCheck::HtmlFormatActionsSupport
extend ActiveSupport::Concern
- include SpammableActions::Attributes
include SpammableActions::CaptchaCheck::Common
included do
@@ -17,9 +16,9 @@ module SpammableActions::CaptchaCheck::HtmlFormatActionsSupport
private
- def with_captcha_check_html_format(&block)
+ def with_captcha_check_html_format(spammable:, &block)
captcha_render_lambda = -> { render :captcha_check }
- with_captcha_check_common(captcha_render_lambda: captcha_render_lambda, &block)
+ with_captcha_check_common(spammable: spammable, captcha_render_lambda: captcha_render_lambda, &block)
end
# Convert spam/CAPTCHA values from form field params to headers, because all spam-related services
diff --git a/app/controllers/concerns/spammable_actions/captcha_check/json_format_actions_support.rb b/app/controllers/concerns/spammable_actions/captcha_check/json_format_actions_support.rb
index 0bfea05abc7..4a278a7b233 100644
--- a/app/controllers/concerns/spammable_actions/captcha_check/json_format_actions_support.rb
+++ b/app/controllers/concerns/spammable_actions/captcha_check/json_format_actions_support.rb
@@ -4,22 +4,27 @@
# In other words, forms handled by actions which use a `respond_to` of `format.js` or `format.json`.
#
# For example, for all Javascript based form submissions and Vue components which use Apollo and Axios
+# which are directly handled by a controller other than `GraphqlController`. For example, issue
+# update currently uses this module.
+#
+# However, requests which directly hit `GraphqlController` will not use this module - the
+# `Mutations::SpamProtection` module handles those requests (for example, snippet create/update
+# requests)
#
# If the request is handled by actions via `format.html`, then the corresponding module which
# supports HTML format should be used instead.
module SpammableActions::CaptchaCheck::JsonFormatActionsSupport
extend ActiveSupport::Concern
- include SpammableActions::Attributes
include SpammableActions::CaptchaCheck::Common
include Spam::Concerns::HasSpamActionResponseFields
private
- def with_captcha_check_json_format(&block)
+ def with_captcha_check_json_format(spammable:, &block)
# NOTE: "409 - Conflict" seems to be the most appropriate HTTP status code for a response
# which requires a CAPTCHA to be solved in order for the request to be resubmitted.
# https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.10
captcha_render_lambda = -> { render json: spam_action_response_fields(spammable), status: :conflict }
- with_captcha_check_common(captcha_render_lambda: captcha_render_lambda, &block)
+ with_captcha_check_common(spammable: spammable, captcha_render_lambda: captcha_render_lambda, &block)
end
end
diff --git a/app/controllers/concerns/spammable_actions/captcha_check/rest_api_actions_support.rb b/app/controllers/concerns/spammable_actions/captcha_check/rest_api_actions_support.rb
new file mode 100644
index 00000000000..2ebfa90e6da
--- /dev/null
+++ b/app/controllers/concerns/spammable_actions/captcha_check/rest_api_actions_support.rb
@@ -0,0 +1,39 @@
+# frozen_string_literal: true
+
+# This module should be included to support CAPTCHA check for REST API actions via Grape.
+#
+# If the request is directly handled by a controller action, then the corresponding module which
+# supports HTML or JSON formats should be used instead.
+module SpammableActions::CaptchaCheck::RestApiActionsSupport
+ extend ActiveSupport::Concern
+ include SpammableActions::CaptchaCheck::Common
+ include Spam::Concerns::HasSpamActionResponseFields
+
+ private
+
+ def with_captcha_check_rest_api(spammable:, &block)
+ # In the case of the REST API, the request is handled by Grape, so if there is a spam-related
+ # error, we don't render directly, instead we will pass the error message and other necessary
+ # fields to the Grape api error helper for it to handle.
+ captcha_render_lambda = -> do
+ fields = spam_action_response_fields(spammable)
+
+ fields.delete :spam
+ # NOTE: "409 - Conflict" seems to be the most appropriate HTTP status code for a response
+ # which requires a CAPTCHA to be solved in order for the request to be resubmitted.
+ # https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.10
+ status = 409
+
+ # NOTE: This nested 'error' key may not be consistent with all other API error responses,
+ # because they are not currently consistent across different API endpoints
+ # and models. Some (snippets) will nest errors in an errors key like this,
+ # while others (issues) will return the model's errors hash without an errors key,
+ # while still others just return a plain string error.
+ # See https://gitlab.com/groups/gitlab-org/-/epics/5527#revisit-inconsistent-shape-of-error-responses-in-rest-api
+ fields[:message] = { error: spammable.errors.full_messages.to_sentence }
+ render_structured_api_error!(fields, status)
+ end
+
+ with_captcha_check_common(spammable: spammable, captcha_render_lambda: captcha_render_lambda, &block)
+ end
+end
diff --git a/app/controllers/concerns/uploads_actions.rb b/app/controllers/concerns/uploads_actions.rb
index e1bfe92f61b..c9b6e8923fe 100644
--- a/app/controllers/concerns/uploads_actions.rb
+++ b/app/controllers/concerns/uploads_actions.rb
@@ -143,7 +143,7 @@ module UploadsActions
end
def bypass_auth_checks_on_uploads?
- if ::Feature.enabled?(:enforce_auth_checks_on_uploads, default_enabled: :yaml)
+ if ::Feature.enabled?(:enforce_auth_checks_on_uploads, project, default_enabled: :yaml)
false
else
action_name == 'show' && embeddable?
diff --git a/app/controllers/dashboard/projects_controller.rb b/app/controllers/dashboard/projects_controller.rb
index 0074bcac360..4d6c7a63516 100644
--- a/app/controllers/dashboard/projects_controller.rb
+++ b/app/controllers/dashboard/projects_controller.rb
@@ -23,7 +23,7 @@ class Dashboard::ProjectsController < Dashboard::ApplicationController
end
format.atom do
load_events
- render layout: 'xml.atom'
+ render layout: 'xml'
end
format.json do
render json: {
diff --git a/app/controllers/dashboard_controller.rb b/app/controllers/dashboard_controller.rb
index f94da77609f..f25cc1bbc32 100644
--- a/app/controllers/dashboard_controller.rb
+++ b/app/controllers/dashboard_controller.rb
@@ -20,10 +20,6 @@ class DashboardController < Dashboard::ApplicationController
urgency :low, [:merge_requests]
- before_action only: [:merge_requests] do
- push_frontend_feature_flag(:mr_attention_requests, default_enabled: :yaml)
- end
-
def activity
respond_to do |format|
format.html
@@ -71,10 +67,15 @@ class DashboardController < Dashboard::ApplicationController
end
def check_filters_presence!
- no_scalar_filters_set = finder_type.scalar_params.none? { |k| params.key?(k) }
- no_array_filters_set = finder_type.array_params.none? { |k, _| params.key?(k) }
+ no_scalar_filters_set = finder_type.scalar_params.none? { |k| params[k].present? }
+ no_array_filters_set = finder_type.array_params.none? { |k, _| params[k].present? }
+
+ # The `in` param is a modifier of `search`. If it's present while the `search`
+ # param isn't, the finder won't use the `in` param. We consider this as a no
+ # filter scenario.
+ no_search_filter_set = params[:in].present? && params[:search].blank?
- @no_filters_set = no_scalar_filters_set && no_array_filters_set
+ @no_filters_set = (no_scalar_filters_set && no_array_filters_set) || no_search_filter_set
return unless @no_filters_set
diff --git a/app/controllers/groups/application_controller.rb b/app/controllers/groups/application_controller.rb
index f9c875b80b2..bf72ade32d0 100644
--- a/app/controllers/groups/application_controller.rb
+++ b/app/controllers/groups/application_controller.rb
@@ -82,6 +82,10 @@ class Groups::ApplicationController < ApplicationController
def has_project_list?
false
end
+
+ def validate_root_group!
+ render_404 unless group.root?
+ end
end
Groups::ApplicationController.prepend_mod_with('Groups::ApplicationController')
diff --git a/app/controllers/groups/boards_controller.rb b/app/controllers/groups/boards_controller.rb
index 6fac6fcf426..641b3adb12b 100644
--- a/app/controllers/groups/boards_controller.rb
+++ b/app/controllers/groups/boards_controller.rb
@@ -7,7 +7,6 @@ class Groups::BoardsController < Groups::ApplicationController
before_action :assign_endpoint_vars
before_action do
- push_frontend_feature_flag(:issue_boards_filtered_search, group, default_enabled: :yaml)
push_frontend_feature_flag(:board_multi_select, group, default_enabled: :yaml)
push_frontend_feature_flag(:iteration_cadences, group, default_enabled: :yaml)
experiment(:prominent_create_board_btn, subject: current_user) do |e|
diff --git a/app/controllers/groups/clusters_controller.rb b/app/controllers/groups/clusters_controller.rb
index 666a96d6fc0..2fe9faa252f 100644
--- a/app/controllers/groups/clusters_controller.rb
+++ b/app/controllers/groups/clusters_controller.rb
@@ -3,6 +3,7 @@
class Groups::ClustersController < Clusters::ClustersController
include ControllerWithCrossProjectAccessCheck
+ before_action :ensure_feature_enabled!
prepend_before_action :group
requires_cross_project_access
diff --git a/app/controllers/groups/crm/contacts_controller.rb b/app/controllers/groups/crm/contacts_controller.rb
index f00f4d1df25..b59e20d9cea 100644
--- a/app/controllers/groups/crm/contacts_controller.rb
+++ b/app/controllers/groups/crm/contacts_controller.rb
@@ -3,6 +3,7 @@
class Groups::Crm::ContactsController < Groups::ApplicationController
feature_category :team_planning
+ before_action :validate_root_group!
before_action :authorize_read_crm_contact!
def new
diff --git a/app/controllers/groups/crm/organizations_controller.rb b/app/controllers/groups/crm/organizations_controller.rb
index ab720f490be..f8536b4f538 100644
--- a/app/controllers/groups/crm/organizations_controller.rb
+++ b/app/controllers/groups/crm/organizations_controller.rb
@@ -3,6 +3,7 @@
class Groups::Crm::OrganizationsController < Groups::ApplicationController
feature_category :team_planning
+ before_action :validate_root_group!
before_action :authorize_read_crm_organization!
def new
diff --git a/app/controllers/groups/deploy_tokens_controller.rb b/app/controllers/groups/deploy_tokens_controller.rb
index 79152bf2695..9ef22aa33dc 100644
--- a/app/controllers/groups/deploy_tokens_controller.rb
+++ b/app/controllers/groups/deploy_tokens_controller.rb
@@ -6,8 +6,7 @@ class Groups::DeployTokensController < Groups::ApplicationController
feature_category :continuous_delivery
def revoke
- @token = @group.deploy_tokens.find(params[:id])
- @token.revoke!
+ Groups::DeployTokens::RevokeService.new(@group, current_user, params).execute
redirect_to group_settings_repository_path(@group, anchor: 'js-deploy-tokens')
end
diff --git a/app/controllers/groups/group_members_controller.rb b/app/controllers/groups/group_members_controller.rb
index 6e59f159636..ece1083d4d1 100644
--- a/app/controllers/groups/group_members_controller.rb
+++ b/app/controllers/groups/group_members_controller.rb
@@ -16,7 +16,7 @@ class Groups::GroupMembersController < Groups::ApplicationController
before_action :authorize_admin_group_member!, except: admin_not_required_endpoints
skip_before_action :check_two_factor_requirement, only: :leave
- skip_cross_project_access_check :index, :create, :update, :destroy, :request_access,
+ skip_cross_project_access_check :index, :update, :destroy, :request_access,
:approve_access_request, :leave, :resend_invite,
:override
@@ -26,8 +26,6 @@ class Groups::GroupMembersController < Groups::ApplicationController
@sort = params[:sort].presence || sort_value_name
if can?(current_user, :admin_group_member, @group)
- @skip_groups = @group.related_group_ids
-
@invited_members = invited_members
@invited_members = @invited_members.search_invite_email(params[:search_invited]) if params[:search_invited].present?
@invited_members = present_invited_members(@invited_members)
@@ -38,8 +36,6 @@ class Groups::GroupMembersController < Groups::ApplicationController
@requesters = present_members(
AccessRequestsFinder.new(@group).execute(current_user)
)
-
- @group_member = @group.group_members.new
end
# MembershipActions concern
diff --git a/app/controllers/groups/harbor/repositories_controller.rb b/app/controllers/groups/harbor/repositories_controller.rb
new file mode 100644
index 00000000000..364607f9b20
--- /dev/null
+++ b/app/controllers/groups/harbor/repositories_controller.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+module Groups
+ module Harbor
+ class RepositoriesController < Groups::ApplicationController
+ feature_category :integrations
+
+ before_action :harbor_registry_enabled!
+ before_action do
+ push_frontend_feature_flag(:harbor_registry_integration)
+ end
+
+ def show
+ render :index
+ end
+
+ private
+
+ def harbor_registry_enabled!
+ render_404 unless Feature.enabled?(:harbor_registry_integration)
+ end
+ end
+ end
+end
diff --git a/app/controllers/groups/releases_controller.rb b/app/controllers/groups/releases_controller.rb
index 6a42f30b847..db5385ecc71 100644
--- a/app/controllers/groups/releases_controller.rb
+++ b/app/controllers/groups/releases_controller.rb
@@ -15,11 +15,17 @@ module Groups
private
def releases
- ReleasesFinder
- .new(@group, current_user, { include_subgroups: true })
- .execute(preload: false)
- .page(params[:page])
- .per(30)
+ if Feature.enabled?(:group_releases_finder_inoperator)
+ Releases::GroupReleasesFinder
+ .new(@group, current_user, { include_subgroups: true, page: params[:page], per: 30 })
+ .execute(preload: false)
+ else
+ ReleasesFinder
+ .new(@group, current_user, { include_subgroups: true })
+ .execute(preload: false)
+ .page(params[:page])
+ .per(30)
+ end
end
end
end
diff --git a/app/controllers/groups/runners_controller.rb b/app/controllers/groups/runners_controller.rb
index b194aeff80d..dabef978ee1 100644
--- a/app/controllers/groups/runners_controller.rb
+++ b/app/controllers/groups/runners_controller.rb
@@ -24,7 +24,7 @@ class Groups::RunnersController < Groups::ApplicationController
end
def update
- if Ci::UpdateRunnerService.new(@runner).update(runner_params)
+ if Ci::Runners::UpdateRunnerService.new(@runner).update(runner_params)
redirect_to group_runner_path(@group, @runner), notice: _('Runner was successfully updated.')
else
render 'edit'
@@ -32,17 +32,17 @@ class Groups::RunnersController < Groups::ApplicationController
end
def destroy
- if @runner.belongs_to_more_than_one_project?
- redirect_to group_settings_ci_cd_path(@group, anchor: 'runners-settings'), status: :found, alert: _('Runner was not deleted because it is assigned to multiple projects.')
- else
- Ci::UnregisterRunnerService.new(@runner).execute
+ if can?(current_user, :delete_runner, @runner)
+ Ci::Runners::UnregisterRunnerService.new(@runner, current_user).execute
redirect_to group_settings_ci_cd_path(@group, anchor: 'runners-settings'), status: :found
+ else
+ redirect_to group_settings_ci_cd_path(@group, anchor: 'runners-settings'), status: :found, alert: _('Runner cannot be deleted, please contact your administrator.')
end
end
def resume
- if Ci::UpdateRunnerService.new(@runner).update(active: true)
+ if Ci::Runners::UpdateRunnerService.new(@runner).update(active: true)
redirect_to group_settings_ci_cd_path(@group, anchor: 'runners-settings'), notice: _('Runner was successfully updated.')
else
redirect_to group_settings_ci_cd_path(@group, anchor: 'runners-settings'), alert: _('Runner was not updated.')
@@ -50,7 +50,7 @@ class Groups::RunnersController < Groups::ApplicationController
end
def pause
- if Ci::UpdateRunnerService.new(@runner).update(active: false)
+ if Ci::Runners::UpdateRunnerService.new(@runner).update(active: false)
redirect_to group_settings_ci_cd_path(@group, anchor: 'runners-settings'), notice: _('Runner was successfully updated.')
else
redirect_to group_settings_ci_cd_path(@group, anchor: 'runners-settings'), alert: _('Runner was not updated.')
diff --git a/app/controllers/groups/settings/ci_cd_controller.rb b/app/controllers/groups/settings/ci_cd_controller.rb
index a290ef9b5e7..9b9e3f7b0bc 100644
--- a/app/controllers/groups/settings/ci_cd_controller.rb
+++ b/app/controllers/groups/settings/ci_cd_controller.rb
@@ -36,7 +36,7 @@ module Groups
end
def reset_registration_token
- @group.reset_runners_token!
+ ::Ci::Runners::ResetRegistrationTokenService.new(@group, current_user).execute
flash[:notice] = _('GroupSettings|New runners registration token has been generated!')
redirect_to group_settings_ci_cd_path
diff --git a/app/controllers/groups/settings/integrations_controller.rb b/app/controllers/groups/settings/integrations_controller.rb
index 0a63c3d304b..ec64e75a68e 100644
--- a/app/controllers/groups/settings/integrations_controller.rb
+++ b/app/controllers/groups/settings/integrations_controller.rb
@@ -7,6 +7,10 @@ module Groups
before_action :authorize_admin_group!
+ before_action do
+ push_frontend_feature_flag(:integration_form_sections, group, default_enabled: :yaml)
+ end
+
feature_category :integrations
layout 'group_settings'
diff --git a/app/controllers/groups/uploads_controller.rb b/app/controllers/groups/uploads_controller.rb
index 387f7be56cd..49249f87d31 100644
--- a/app/controllers/groups/uploads_controller.rb
+++ b/app/controllers/groups/uploads_controller.rb
@@ -4,7 +4,7 @@ class Groups::UploadsController < Groups::ApplicationController
include UploadsActions
include WorkhorseRequest
- skip_before_action :group, if: -> { bypass_auth_checks_on_uploads? }
+ skip_before_action :group, if: -> { action_name == 'show' && embeddable? }
before_action :authorize_upload_file!, only: [:create, :authorize]
before_action :verify_workhorse_api!, only: [:authorize]
diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb
index 12af76efe0d..b53d9b1be04 100644
--- a/app/controllers/groups_controller.rb
+++ b/app/controllers/groups_controller.rb
@@ -212,7 +212,7 @@ class GroupsController < Groups::ApplicationController
def issues
return super if !html_request? || Feature.disabled?(:vue_issues_list, group, default_enabled: :yaml)
- @has_issues = IssuesFinder.new(current_user, group_id: group.id).execute
+ @has_issues = IssuesFinder.new(current_user, group_id: group.id, include_subgroups: true).execute
.non_archived
.exists?
@@ -235,7 +235,7 @@ class GroupsController < Groups::ApplicationController
def render_details_view_atom
load_events
- render layout: 'xml.atom', template: 'groups/show'
+ render layout: 'xml', template: 'groups/show'
end
# rubocop: disable CodeReuse/ActiveRecord
diff --git a/app/controllers/jira_connect/events_controller.rb b/app/controllers/jira_connect/events_controller.rb
index 1ea0a92662b..327192857f6 100644
--- a/app/controllers/jira_connect/events_controller.rb
+++ b/app/controllers/jira_connect/events_controller.rb
@@ -7,11 +7,13 @@ class JiraConnect::EventsController < JiraConnect::ApplicationController
before_action :verify_asymmetric_atlassian_jwt!
def installed
- return head :ok if current_jira_installation
+ unless Feature.enabled?(:jira_connect_installation_update, default_enabled: :yaml)
+ return head :ok if current_jira_installation
+ end
- installation = JiraConnectInstallation.new(event_params)
+ success = current_jira_installation ? update_installation : create_installation
- if installation.save
+ if success
head :ok
else
head :unprocessable_entity
@@ -28,8 +30,24 @@ class JiraConnect::EventsController < JiraConnect::ApplicationController
private
- def event_params
- params.permit(:clientKey, :sharedSecret, :baseUrl).transform_keys(&:underscore)
+ def create_installation
+ JiraConnectInstallation.new(create_params).save
+ end
+
+ def update_installation
+ current_jira_installation.update(update_params)
+ end
+
+ def create_params
+ transformed_params.permit(:client_key, :shared_secret, :base_url)
+ end
+
+ def update_params
+ transformed_params.permit(:shared_secret, :base_url)
+ end
+
+ def transformed_params
+ @transformed_params ||= params.transform_keys(&:underscore)
end
def verify_asymmetric_atlassian_jwt!
@@ -43,7 +61,7 @@ class JiraConnect::EventsController < JiraConnect::ApplicationController
def jwt_verification_claims
{
aud: jira_connect_base_url(protocol: 'https'),
- iss: event_params[:client_key],
+ iss: transformed_params[:client_key],
qsh: Atlassian::Jwt.create_query_string_hash(request.url, request.method, jira_connect_base_url)
}
end
diff --git a/app/controllers/jira_connect/oauth_callbacks_controller.rb b/app/controllers/jira_connect/oauth_callbacks_controller.rb
new file mode 100644
index 00000000000..f603a563402
--- /dev/null
+++ b/app/controllers/jira_connect/oauth_callbacks_controller.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+# This controller's role is to serve as a landing page
+# that users get redirected to after installing and authenticating
+# The GitLab.com for Jira App (https://marketplace.atlassian.com/apps/1221011/gitlab-com-for-jira-cloud)
+#
+class JiraConnect::OauthCallbacksController < ApplicationController
+ feature_category :integrations
+
+ def index; end
+end
diff --git a/app/controllers/jira_connect/subscriptions_controller.rb b/app/controllers/jira_connect/subscriptions_controller.rb
index fcd95c7942c..ec6ba07a125 100644
--- a/app/controllers/jira_connect/subscriptions_controller.rb
+++ b/app/controllers/jira_connect/subscriptions_controller.rb
@@ -16,6 +16,10 @@ class JiraConnect::SubscriptionsController < JiraConnect::ApplicationController
p.style_src(*style_src_values)
end
+ before_action do
+ push_frontend_feature_flag(:jira_connect_oauth, @user, default_enabled: :yaml)
+ end
+
before_action :allow_rendering_in_iframe, only: :index
before_action :verify_qsh_claim!, only: :index
before_action :authenticate_user!, only: :create
diff --git a/app/controllers/profiles_controller.rb b/app/controllers/profiles_controller.rb
index 46738651960..d57a293ab4d 100644
--- a/app/controllers/profiles_controller.rb
+++ b/app/controllers/profiles_controller.rb
@@ -7,7 +7,7 @@ class ProfilesController < Profiles::ApplicationController
before_action :user
before_action :authorize_change_username!, only: :update_username
before_action only: :update_username do
- check_rate_limit!(:profile_update_username, scope: current_user) if Feature.enabled?(:rate_limit_profile_update_username, default_enabled: :yaml)
+ check_rate_limit!(:profile_update_username, scope: current_user)
end
skip_before_action :require_email, only: [:show, :update]
before_action do
diff --git a/app/controllers/projects/application_controller.rb b/app/controllers/projects/application_controller.rb
index 7a03e7b84b7..62233c8c3c9 100644
--- a/app/controllers/projects/application_controller.rb
+++ b/app/controllers/projects/application_controller.rb
@@ -24,11 +24,14 @@ class Projects::ApplicationController < ApplicationController
return unless params[:project_id] || params[:id]
path = File.join(params[:namespace_id], params[:project_id] || params[:id])
- auth_proc = ->(project) { !project.pending_delete? }
@project = find_routable!(Project, path, request.fullpath, extra_authorization_proc: auth_proc)
end
+ def auth_proc
+ ->(project) { !project.pending_delete? }
+ end
+
def build_canonical_path(project)
params[:namespace_id] = project.namespace.to_param
params[:project_id] = project.to_param
@@ -89,3 +92,5 @@ class Projects::ApplicationController < ApplicationController
return render_404 unless @project.feature_available?(:issues, current_user)
end
end
+
+Projects::ApplicationController.prepend_mod_with('Projects::ApplicationController')
diff --git a/app/controllers/projects/blob_controller.rb b/app/controllers/projects/blob_controller.rb
index b30ef7506aa..26a7b5662be 100644
--- a/app/controllers/projects/blob_controller.rb
+++ b/app/controllers/projects/blob_controller.rb
@@ -35,7 +35,6 @@ class Projects::BlobController < Projects::ApplicationController
before_action :editor_variables, except: [:show, :preview, :diff]
before_action :validate_diff_params, only: :diff
before_action :set_last_commit_sha, only: [:edit, :update]
- before_action :track_experiment, only: :create
track_redis_hll_event :create, :update, name: 'g_edit_by_sfe'
@@ -45,7 +44,6 @@ class Projects::BlobController < Projects::ApplicationController
before_action do
push_frontend_feature_flag(:refactor_blob_viewer, @project, default_enabled: :yaml)
push_frontend_feature_flag(:highlight_js, @project, default_enabled: :yaml)
- push_frontend_feature_flag(:consolidated_edit_button, @project, default_enabled: :yaml)
push_licensed_feature(:file_locks) if @project.licensed_feature_available?(:file_locks)
end
@@ -55,7 +53,7 @@ class Projects::BlobController < Projects::ApplicationController
def create
create_commit(Files::CreateService, success_notice: _("The file has been successfully created."),
- success_path: -> { create_success_path },
+ success_path: -> { project_blob_path(@project, File.join(@branch_name, @file_path)) },
failure_view: :new,
failure_path: project_new_blob_path(@project, @ref))
end
@@ -283,20 +281,6 @@ class Projects::BlobController < Projects::ApplicationController
def visitor_id
current_user&.id
end
-
- def create_success_path
- if params[:code_quality_walkthrough]
- project_pipelines_path(@project, code_quality_walkthrough: true)
- else
- project_blob_path(@project, File.join(@branch_name, @file_path))
- end
- end
-
- def track_experiment
- return unless params[:code_quality_walkthrough]
-
- experiment(:code_quality_walkthrough, namespace: @project.root_ancestor).track(:commit_created)
- end
end
Projects::BlobController.prepend_mod
diff --git a/app/controllers/projects/boards_controller.rb b/app/controllers/projects/boards_controller.rb
index 0170cff6160..c44a0830e2e 100644
--- a/app/controllers/projects/boards_controller.rb
+++ b/app/controllers/projects/boards_controller.rb
@@ -7,7 +7,6 @@ class Projects::BoardsController < Projects::ApplicationController
before_action :check_issues_available!
before_action :assign_endpoint_vars
before_action do
- push_frontend_feature_flag(:issue_boards_filtered_search, project&.group, default_enabled: :yaml)
push_frontend_feature_flag(:board_multi_select, project, default_enabled: :yaml)
push_frontend_feature_flag(:iteration_cadences, project&.group, default_enabled: :yaml)
experiment(:prominent_create_board_btn, subject: current_user) do |e|
diff --git a/app/controllers/projects/builds_controller.rb b/app/controllers/projects/builds_controller.rb
index c5f6ed1c105..61e8e5b015a 100644
--- a/app/controllers/projects/builds_controller.rb
+++ b/app/controllers/projects/builds_controller.rb
@@ -5,6 +5,9 @@ class Projects::BuildsController < Projects::ApplicationController
feature_category :continuous_integration
+ urgency :high, [:index, :show]
+ urgency :low, [:raw]
+
def index
redirect_to project_jobs_path(project)
end
diff --git a/app/controllers/projects/ci/pipeline_editor_controller.rb b/app/controllers/projects/ci/pipeline_editor_controller.rb
index 6f12e3940dd..8c6e8f0e126 100644
--- a/app/controllers/projects/ci/pipeline_editor_controller.rb
+++ b/app/controllers/projects/ci/pipeline_editor_controller.rb
@@ -2,7 +2,6 @@
class Projects::Ci::PipelineEditorController < Projects::ApplicationController
before_action :check_can_collaborate!
- before_action :setup_walkthrough_experiment, only: :show
before_action do
push_frontend_feature_flag(:schema_linting, @project, default_enabled: :yaml)
end
@@ -19,11 +18,4 @@ class Projects::Ci::PipelineEditorController < Projects::ApplicationController
def check_can_collaborate!
render_404 unless can_collaborate_with_project?(@project)
end
-
- def setup_walkthrough_experiment
- experiment(:pipeline_editor_walkthrough, namespace: @project.namespace, sticky_to: current_user) do |e|
- e.candidate {}
- e.publish_to_database
- end
- end
end
diff --git a/app/controllers/projects/ci/secure_files_controller.rb b/app/controllers/projects/ci/secure_files_controller.rb
new file mode 100644
index 00000000000..5141d0188b0
--- /dev/null
+++ b/app/controllers/projects/ci/secure_files_controller.rb
@@ -0,0 +1,10 @@
+# frozen_string_literal: true
+
+class Projects::Ci::SecureFilesController < Projects::ApplicationController
+ before_action :authorize_read_secure_files!
+
+ feature_category :pipeline_authoring
+
+ def show
+ end
+end
diff --git a/app/controllers/projects/cluster_agents_controller.rb b/app/controllers/projects/cluster_agents_controller.rb
index 84bb01ee266..282b9ef1fb7 100644
--- a/app/controllers/projects/cluster_agents_controller.rb
+++ b/app/controllers/projects/cluster_agents_controller.rb
@@ -3,10 +3,6 @@
class Projects::ClusterAgentsController < Projects::ApplicationController
before_action :authorize_can_read_cluster_agent!
- before_action do
- push_frontend_feature_flag(:cluster_vulnerabilities, project, default_enabled: :yaml)
- end
-
feature_category :kubernetes_management
def show
diff --git a/app/controllers/projects/commit_controller.rb b/app/controllers/projects/commit_controller.rb
index 0ce0b8b8895..0c26b402876 100644
--- a/app/controllers/projects/commit_controller.rb
+++ b/app/controllers/projects/commit_controller.rb
@@ -164,6 +164,7 @@ class Projects::CommitController < Projects::ApplicationController
opts = diff_options
opts[:ignore_whitespace_change] = true if params[:format] == 'diff'
+ opts[:use_extra_viewer_as_main] = false
@diffs = commit.diffs(opts)
@notes_count = commit.notes.count
diff --git a/app/controllers/projects/commits_controller.rb b/app/controllers/projects/commits_controller.rb
index 82a13b60b13..60b8e45f5be 100644
--- a/app/controllers/projects/commits_controller.rb
+++ b/app/controllers/projects/commits_controller.rb
@@ -30,7 +30,7 @@ class Projects::CommitsController < Projects::ApplicationController
respond_to do |format|
format.html
- format.atom { render layout: 'xml.atom' }
+ format.atom { render layout: 'xml' }
format.json do
pager_json(
diff --git a/app/controllers/projects/deploy_tokens_controller.rb b/app/controllers/projects/deploy_tokens_controller.rb
index 3c890bbafdf..42c2d8b17f1 100644
--- a/app/controllers/projects/deploy_tokens_controller.rb
+++ b/app/controllers/projects/deploy_tokens_controller.rb
@@ -12,3 +12,5 @@ class Projects::DeployTokensController < Projects::ApplicationController
redirect_to project_settings_repository_path(project, anchor: 'js-deploy-tokens')
end
end
+
+Projects::DeployTokensController.prepend_mod
diff --git a/app/controllers/projects/environments_controller.rb b/app/controllers/projects/environments_controller.rb
index 84ebdcd9364..eabc048e341 100644
--- a/app/controllers/projects/environments_controller.rb
+++ b/app/controllers/projects/environments_controller.rb
@@ -29,13 +29,14 @@ class Projects::EnvironmentsController < Projects::ApplicationController
feature_category :continuous_delivery
def index
- @environments = project.environments
- .with_state(params[:scope] || :available)
@project = ProjectPresenter.new(project, current_user: current_user)
respond_to do |format|
format.html
format.json do
+ @environments = project.environments
+ .with_state(params[:scope] || :available)
+
Gitlab::PollingInterval.set_header(response, interval: 3_000)
environments_count_by_state = project.environments.count_by_state
@@ -52,14 +53,15 @@ class Projects::EnvironmentsController < Projects::ApplicationController
# Returns all environments for a given folder
# rubocop: disable CodeReuse/ActiveRecord
def folder
- folder_environments = project.environments.where(environment_type: params[:id])
- @environments = folder_environments.with_state(params[:scope] || :available)
- .order(:name)
@folder = params[:id]
respond_to do |format|
format.html
format.json do
+ folder_environments = project.environments.where(environment_type: params[:id])
+ @environments = folder_environments.with_state(params[:scope] || :available)
+ .order(:name)
+
render json: {
environments: serialize_environments(request, response),
available_count: folder_environments.available.count,
diff --git a/app/controllers/projects/error_tracking_controller.rb b/app/controllers/projects/error_tracking_controller.rb
index 8700d3c2198..06383d26133 100644
--- a/app/controllers/projects/error_tracking_controller.rb
+++ b/app/controllers/projects/error_tracking_controller.rb
@@ -6,6 +6,10 @@ class Projects::ErrorTrackingController < Projects::ErrorTracking::BaseControlle
before_action :authorize_read_sentry_issue!
before_action :set_issue_id, only: :details
+ before_action only: [:index] do
+ push_frontend_feature_flag(:integrated_error_tracking, project)
+ end
+
def index
respond_to do |format|
format.html
@@ -75,7 +79,7 @@ class Projects::ErrorTrackingController < Projects::ErrorTracking::BaseControlle
end
def list_issues_params
- params.permit(:search_term, :sort, :cursor, :issue_status)
+ params.permit(:search_term, :sort, :cursor, :issue_status).merge(tracking_event: :error_tracking_view_list)
end
def issue_update_params
@@ -83,7 +87,7 @@ class Projects::ErrorTrackingController < Projects::ErrorTracking::BaseControlle
end
def issue_details_params
- params.permit(:issue_id)
+ params.permit(:issue_id).merge(tracking_event: :error_tracking_view_details)
end
def set_issue_id
diff --git a/app/controllers/projects/forks_controller.rb b/app/controllers/projects/forks_controller.rb
index 475c41eec9c..3208a5076e7 100644
--- a/app/controllers/projects/forks_controller.rb
+++ b/app/controllers/projects/forks_controller.rb
@@ -17,10 +17,6 @@ class Projects::ForksController < Projects::ApplicationController
feature_category :source_code_management
urgency :low, [:index]
- before_action do
- push_frontend_feature_flag(:fork_project_form, @project, default_enabled: :yaml)
- end
-
def index
@sort = forks_params[:sort]
@@ -54,9 +50,7 @@ class Projects::ForksController < Projects::ApplicationController
format.json do
namespaces = load_namespaces_with_associations - [project.namespace]
- namespaces = [current_user.namespace] + namespaces if
- Feature.enabled?(:fork_project_form, project, default_enabled: :yaml) &&
- can_fork_to?(current_user.namespace)
+ namespaces = [current_user.namespace] + namespaces if can_fork_to?(current_user.namespace)
render json: {
namespaces: ForkNamespaceSerializer.new.represent(
diff --git a/app/controllers/projects/google_cloud/base_controller.rb b/app/controllers/projects/google_cloud/base_controller.rb
index f4a773a62f6..f293ec752ab 100644
--- a/app/controllers/projects/google_cloud/base_controller.rb
+++ b/app/controllers/projects/google_cloud/base_controller.rb
@@ -10,18 +10,25 @@ class Projects::GoogleCloud::BaseController < Projects::ApplicationController
private
def admin_project_google_cloud!
- access_denied! unless can?(current_user, :admin_project_google_cloud, project)
+ unless can?(current_user, :admin_project_google_cloud, project)
+ track_event('admin_project_google_cloud!', 'access_denied', 'invalid_user')
+ access_denied!
+ end
end
def google_oauth2_enabled!
config = Gitlab::Auth::OAuth::Provider.config_for('google_oauth2')
if config.app_id.blank? || config.app_secret.blank?
+ track_event('google_oauth2_enabled!', 'access_denied', { reason: 'google_oauth2_not_configured', config: config })
access_denied! 'This GitLab instance not configured for Google Oauth2.'
end
end
def feature_flag_enabled!
- access_denied! unless Feature.enabled?(:incubation_5mp_google_cloud, project)
+ unless Feature.enabled?(:incubation_5mp_google_cloud)
+ track_event('feature_flag_enabled!', 'access_denied', 'feature_flag_not_enabled')
+ access_denied!
+ end
end
def validate_gcp_token!
@@ -53,9 +60,21 @@ class Projects::GoogleCloud::BaseController < Projects::ApplicationController
session[GoogleApi::CloudPlatform::Client.session_key_for_expires_at]
end
- def handle_gcp_error(error, project)
- Gitlab::ErrorTracking.track_exception(error, project_id: project.id)
+ def handle_gcp_error(action, error)
+ track_event(action, 'gcp_error', error)
@js_data = { screen: 'gcp_error', error: error.to_s }.to_json
render status: :unauthorized, template: 'projects/google_cloud/errors/gcp_error'
end
+
+ def track_event(action, label, property)
+ options = { label: label, project: project, user: current_user }
+
+ if property.is_a?(String)
+ options[:property] = property
+ else
+ options[:extra] = property
+ end
+
+ Gitlab::Tracking.event('Projects::GoogleCloud', action, **options)
+ end
end
diff --git a/app/controllers/projects/google_cloud/deployments_controller.rb b/app/controllers/projects/google_cloud/deployments_controller.rb
index 1941eb8a5f9..4867d344c5a 100644
--- a/app/controllers/projects/google_cloud/deployments_controller.rb
+++ b/app/controllers/projects/google_cloud/deployments_controller.rb
@@ -9,6 +9,7 @@ class Projects::GoogleCloud::DeploymentsController < Projects::GoogleCloud::Base
.new(project, current_user, params).execute
if enable_cloud_run_response[:status] == :error
+ track_event('deployments#cloud_run', 'enable_cloud_run_error', enable_cloud_run_response)
flash[:error] = enable_cloud_run_response[:message]
redirect_to project_google_cloud_index_path(project)
else
@@ -17,15 +18,17 @@ class Projects::GoogleCloud::DeploymentsController < Projects::GoogleCloud::Base
.new(project, current_user, params).execute
if generate_pipeline_response[:status] == :error
+ track_event('deployments#cloud_run', 'generate_pipeline_error', generate_pipeline_response)
flash[:error] = 'Failed to generate pipeline'
redirect_to project_google_cloud_index_path(project)
else
cloud_run_mr_params = cloud_run_mr_params(generate_pipeline_response[:branch_name])
+ track_event('deployments#cloud_run', 'cloud_run_success', cloud_run_mr_params)
redirect_to project_new_merge_request_path(project, merge_request: cloud_run_mr_params)
end
end
rescue Google::Apis::ClientError => error
- handle_gcp_error(error, project)
+ handle_gcp_error('deployments#cloud_run', error)
end
def cloud_storage
diff --git a/app/controllers/projects/google_cloud/gcp_regions_controller.rb b/app/controllers/projects/google_cloud/gcp_regions_controller.rb
new file mode 100644
index 00000000000..beeb91cfd80
--- /dev/null
+++ b/app/controllers/projects/google_cloud/gcp_regions_controller.rb
@@ -0,0 +1,31 @@
+# frozen_string_literal: true
+
+class Projects::GoogleCloud::GcpRegionsController < Projects::GoogleCloud::BaseController
+ # filtered list of GCP cloud run locations...
+ # ...that have domain mapping available
+ # Source https://cloud.google.com/run/docs/locations 2022-01-30
+ AVAILABLE_REGIONS = %w[asia-east1 asia-northeast1 asia-southeast1 europe-north1 europe-west1 europe-west4 us-central1 us-east1 us-east4 us-west1].freeze
+
+ def index
+ @google_cloud_path = project_google_cloud_index_path(project)
+ params = { per_page: 50 }
+ branches = BranchesFinder.new(project.repository, params).execute(gitaly_pagination: true)
+ tags = TagsFinder.new(project.repository, params).execute(gitaly_pagination: true)
+ refs = (branches + tags).map(&:name)
+ js_data = {
+ screen: 'gcp_regions_form',
+ availableRegions: AVAILABLE_REGIONS,
+ refs: refs,
+ cancelPath: project_google_cloud_index_path(project)
+ }
+ @js_data = js_data.to_json
+ track_event('gcp_regions#index', 'form_render', js_data)
+ end
+
+ def create
+ permitted_params = params.permit(:ref, :gcp_region)
+ response = GoogleCloud::GcpRegionAddOrReplaceService.new(project).execute(permitted_params[:ref], permitted_params[:gcp_region])
+ track_event('gcp_regions#create', 'form_submit', response)
+ redirect_to project_google_cloud_index_path(project), notice: _('GCP region configured')
+ end
+end
diff --git a/app/controllers/projects/google_cloud/revoke_oauth_controller.rb b/app/controllers/projects/google_cloud/revoke_oauth_controller.rb
new file mode 100644
index 00000000000..03d1474707b
--- /dev/null
+++ b/app/controllers/projects/google_cloud/revoke_oauth_controller.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+class Projects::GoogleCloud::RevokeOauthController < Projects::GoogleCloud::BaseController
+ before_action :validate_gcp_token!
+
+ def create
+ google_api_client = GoogleApi::CloudPlatform::Client.new(token_in_session, nil)
+ response = google_api_client.revoke_authorizations
+
+ if response.success?
+ status = 'success'
+ redirect_message = { notice: s_('GoogleCloud|Google OAuth2 token revocation requested') }
+ else
+ status = 'failed'
+ redirect_message = { alert: s_('GoogleCloud|Google OAuth2 token revocation request failed') }
+ end
+
+ session.delete(GoogleApi::CloudPlatform::Client.session_key_for_token)
+ track_event('revoke_oauth#create', 'create', status)
+
+ redirect_to project_google_cloud_index_path(project), redirect_message
+ end
+end
diff --git a/app/controllers/projects/google_cloud/service_accounts_controller.rb b/app/controllers/projects/google_cloud/service_accounts_controller.rb
index b5f2b658235..5d8b2030d5c 100644
--- a/app/controllers/projects/google_cloud/service_accounts_controller.rb
+++ b/app/controllers/projects/google_cloud/service_accounts_controller.rb
@@ -10,30 +10,41 @@ class Projects::GoogleCloud::ServiceAccountsController < Projects::GoogleCloud::
if gcp_projects.empty?
@js_data = { screen: 'no_gcp_projects' }.to_json
+ track_event('service_accounts#index', 'form_error', 'no_gcp_projects')
render status: :unauthorized, template: 'projects/google_cloud/errors/no_gcp_projects'
else
- @js_data = {
+ params = { per_page: 50 }
+ branches = BranchesFinder.new(project.repository, params).execute(gitaly_pagination: true)
+ tags = TagsFinder.new(project.repository, params).execute(gitaly_pagination: true)
+ refs = (branches + tags).map(&:name)
+ js_data = {
screen: 'service_accounts_form',
gcpProjects: gcp_projects,
- environments: project.environments,
+ refs: refs,
cancelPath: project_google_cloud_index_path(project)
- }.to_json
+ }
+ @js_data = js_data.to_json
+
+ track_event('service_accounts#index', 'form_success', js_data)
end
rescue Google::Apis::ClientError => error
- handle_gcp_error(error, project)
+ handle_gcp_error('service_accounts#index', error)
end
def create
+ permitted_params = params.permit(:gcp_project, :ref)
+
response = GoogleCloud::CreateServiceAccountsService.new(
project,
current_user,
google_oauth2_token: token_in_session,
- gcp_project_id: params[:gcp_project],
- environment_name: params[:environment]
+ gcp_project_id: permitted_params[:gcp_project],
+ environment_name: permitted_params[:ref]
).execute
+ track_event('service_accounts#create', 'form_submit', response)
redirect_to project_google_cloud_index_path(project), notice: response.message
rescue Google::Apis::ClientError, Google::Apis::ServerError, Google::Apis::AuthorizationError => error
- handle_gcp_error(error, project)
+ handle_gcp_error('service_accounts#create', error)
end
end
diff --git a/app/controllers/projects/google_cloud_controller.rb b/app/controllers/projects/google_cloud_controller.rb
index 206a8c7e391..49bb4bec859 100644
--- a/app/controllers/projects/google_cloud_controller.rb
+++ b/app/controllers/projects/google_cloud_controller.rb
@@ -1,14 +1,34 @@
# frozen_string_literal: true
class Projects::GoogleCloudController < Projects::GoogleCloud::BaseController
+ GCP_REGION_CI_VAR_KEY = 'GCP_REGION'
+
def index
- @js_data = {
+ js_data = {
screen: 'home',
serviceAccounts: GoogleCloud::ServiceAccountsService.new(project).find_for_project,
createServiceAccountUrl: project_google_cloud_service_accounts_path(project),
enableCloudRunUrl: project_google_cloud_deployments_cloud_run_path(project),
enableCloudStorageUrl: project_google_cloud_deployments_cloud_storage_path(project),
- emptyIllustrationUrl: ActionController::Base.helpers.image_path('illustrations/pipelines_empty.svg')
- }.to_json
+ emptyIllustrationUrl: ActionController::Base.helpers.image_path('illustrations/pipelines_empty.svg'),
+ configureGcpRegionsUrl: project_google_cloud_gcp_regions_path(project),
+ gcpRegions: gcp_regions,
+ revokeOauthUrl: revoke_oauth_url
+ }
+ @js_data = js_data.to_json
+ track_event('google_cloud#index', 'index', js_data)
+ end
+
+ private
+
+ def gcp_regions
+ list = ::Ci::VariablesFinder.new(project, { key: GCP_REGION_CI_VAR_KEY }).execute
+ list.map { |variable| { gcp_region: variable.value, environment: variable.environment_scope } }
+ end
+
+ def revoke_oauth_url
+ google_token_valid = GoogleApi::CloudPlatform::Client.new(token_in_session, nil)
+ .validate_token(expires_at_in_session)
+ google_token_valid ? project_google_cloud_revoke_oauth_index_path(project) : nil
end
end
diff --git a/app/controllers/projects/harbor/application_controller.rb b/app/controllers/projects/harbor/application_controller.rb
new file mode 100644
index 00000000000..e6e694783fa
--- /dev/null
+++ b/app/controllers/projects/harbor/application_controller.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+module Projects
+ module Harbor
+ class ApplicationController < Projects::ApplicationController
+ layout 'project'
+
+ before_action :harbor_registry_enabled!
+ before_action do
+ push_frontend_feature_flag(:harbor_registry_integration)
+ end
+
+ feature_category :integrations
+
+ private
+
+ def harbor_registry_enabled!
+ render_404 unless Feature.enabled?(:harbor_registry_integration)
+ end
+ end
+ end
+end
diff --git a/app/controllers/projects/harbor/repositories_controller.rb b/app/controllers/projects/harbor/repositories_controller.rb
new file mode 100644
index 00000000000..dd3e3dc1978
--- /dev/null
+++ b/app/controllers/projects/harbor/repositories_controller.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+module Projects
+ module Harbor
+ class RepositoriesController < ::Projects::Harbor::ApplicationController
+ def show
+ render :index
+ end
+ end
+ end
+end
diff --git a/app/controllers/projects/incidents_controller.rb b/app/controllers/projects/incidents_controller.rb
index 3395e75666e..293581a6744 100644
--- a/app/controllers/projects/incidents_controller.rb
+++ b/app/controllers/projects/incidents_controller.rb
@@ -6,6 +6,11 @@ class Projects::IncidentsController < Projects::ApplicationController
before_action :authorize_read_issue!
before_action :load_incident, only: [:show]
+ before_action do
+ push_frontend_feature_flag(:incident_escalations, @project)
+ push_frontend_feature_flag(:incident_timeline_event_tab, @project, default_enabled: :yaml)
+ push_licensed_feature(:incident_timeline_events) if @project.licensed_feature_available?(:incident_timeline_events)
+ end
feature_category :incident_management
@@ -43,3 +48,5 @@ class Projects::IncidentsController < Projects::ApplicationController
IssueSerializer.new(current_user: current_user, project: incident.project)
end
end
+
+Projects::IncidentsController.prepend_mod
diff --git a/app/controllers/projects/issues_controller.rb b/app/controllers/projects/issues_controller.rb
index 1b98810b09b..d4474b9d5a3 100644
--- a/app/controllers/projects/issues_controller.rb
+++ b/app/controllers/projects/issues_controller.rb
@@ -36,11 +36,6 @@ class Projects::IssuesController < Projects::ApplicationController
before_action :authorize_import_issues!, only: [:import_csv]
before_action :authorize_download_code!, only: [:related_branches]
- # Limit the amount of issues created per minute
- before_action -> { check_rate_limit!(:issues_create, scope: [@project, @current_user])},
- only: [:create],
- if: -> { Feature.disabled?('rate_limited_service_issues_create', project, default_enabled: :yaml) }
-
before_action do
push_frontend_feature_flag(:improved_emoji_picker, project, default_enabled: :yaml)
push_frontend_feature_flag(:vue_issues_list, project&.group, default_enabled: :yaml)
@@ -50,12 +45,10 @@ class Projects::IssuesController < Projects::ApplicationController
end
before_action only: :show do
- push_frontend_feature_flag(:real_time_issue_sidebar, project, default_enabled: :yaml)
push_frontend_feature_flag(:confidential_notes, project&.group, default_enabled: :yaml)
push_frontend_feature_flag(:issue_assignees_widget, project, default_enabled: :yaml)
push_frontend_feature_flag(:paginated_issue_discussions, project, default_enabled: :yaml)
- push_frontend_feature_flag(:fix_comment_scroll, project, default_enabled: :yaml)
- push_frontend_feature_flag(:work_items, project, default_enabled: :yaml)
+ push_frontend_feature_flag(:work_items, project&.group, default_enabled: :yaml)
end
around_action :allow_gitaly_ref_name_caching, only: [:discussions]
@@ -79,13 +72,16 @@ class Projects::IssuesController < Projects::ApplicationController
attr_accessor :vulnerability_id
def index
- set_issuables_index if !html_request? || Feature.disabled?(:vue_issues_list, project&.group, default_enabled: :yaml)
-
- @issues = @issuables
+ if html_request? && Feature.enabled?(:vue_issues_list, project&.group, default_enabled: :yaml)
+ set_sort_order
+ else
+ set_issuables_index
+ @issues = @issuables
+ end
respond_to do |format|
format.html
- format.atom { render layout: 'xml.atom' }
+ format.atom { render layout: 'xml' }
format.json do
render json: {
html: view_to_html_string("projects/issues/_issues"),
@@ -112,6 +108,8 @@ class Projects::IssuesController < Projects::ApplicationController
@issue = @noteable = service.execute
+ @add_related_issue = add_related_issue
+
@merge_request_to_resolve_discussions_of = service.merge_request_to_resolve_discussions_of
if params[:discussion_to_resolve]
@@ -128,6 +126,7 @@ class Projects::IssuesController < Projects::ApplicationController
def create
create_params = issue_params.merge(
+ add_related_issue: add_related_issue,
merge_request_to_resolve_discussions_of: params[:merge_request_to_resolve_discussions_of],
discussion_to_resolve: params[:discussion_to_resolve]
)
@@ -150,7 +149,7 @@ class Projects::IssuesController < Projects::ApplicationController
redirect_to project_issue_path(@project, @issue)
else
# NOTE: this CAPTCHA support method is indirectly included via IssuableActions
- with_captcha_check_html_format { render :new }
+ with_captcha_check_html_format(spammable: spammable) { render :new }
end
end
@@ -383,6 +382,11 @@ class Projects::IssuesController < Projects::ApplicationController
action_name == 'service_desk'
end
+ def add_related_issue
+ add_related_issue = project.issues.find_by_iid(params[:add_related_issue])
+ add_related_issue if Ability.allowed?(current_user, :read_issue, add_related_issue)
+ end
+
# Overridden in EE
def create_vulnerability_issue_feedback(issue); end
end
diff --git a/app/controllers/projects/jobs_controller.rb b/app/controllers/projects/jobs_controller.rb
index bfc2fe6432d..b0f032a01e5 100644
--- a/app/controllers/projects/jobs_controller.rb
+++ b/app/controllers/projects/jobs_controller.rb
@@ -4,6 +4,8 @@ class Projects::JobsController < Projects::ApplicationController
include SendFileUpload
include ContinueParams
+ urgency :low, [:index, :show, :trace, :retry, :play, :cancel, :unschedule, :status, :erase, :raw]
+
before_action :find_job_as_build, except: [:index, :play, :show]
before_action :find_job_as_processable, only: [:play, :show]
before_action :authorize_read_build_trace!, only: [:trace, :raw]
diff --git a/app/controllers/projects/merge_requests/diffs_controller.rb b/app/controllers/projects/merge_requests/diffs_controller.rb
index 9bc9c19157a..0dcc2bc3181 100644
--- a/app/controllers/projects/merge_requests/diffs_controller.rb
+++ b/app/controllers/projects/merge_requests/diffs_controller.rb
@@ -111,9 +111,7 @@ class Projects::MergeRequests::DiffsController < Projects::MergeRequests::Applic
allow_tree_conflicts: display_merge_conflicts_in_diff?
)
- if @merge_request.project.context_commits_enabled?
- options[:context_commits] = @merge_request.recent_context_commits
- end
+ options[:context_commits] = @merge_request.recent_context_commits
render json: DiffsSerializer.new(request).represent(diffs, options)
end
diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb
index 6445f920db5..60d7920f83e 100644
--- a/app/controllers/projects/merge_requests_controller.rb
+++ b/app/controllers/projects/merge_requests_controller.rb
@@ -30,14 +30,10 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
before_action :set_issuables_index, only: [:index]
before_action :authenticate_user!, only: [:assign_related_issues]
before_action :check_user_can_push_to_source_branch!, only: [:rebase]
- before_action only: [:index, :show] do
- push_frontend_feature_flag(:mr_attention_requests, project, default_enabled: :yaml)
- end
before_action only: [:show] do
push_frontend_feature_flag(:file_identifier_hash)
push_frontend_feature_flag(:merge_request_widget_graphql, project, default_enabled: :yaml)
- push_frontend_feature_flag(:default_merge_ref_for_diffs, project, default_enabled: :yaml)
push_frontend_feature_flag(:core_security_mr_widget_counts, project)
push_frontend_feature_flag(:paginated_notes, project, default_enabled: :yaml)
push_frontend_feature_flag(:confidential_notes, project, default_enabled: :yaml)
@@ -45,8 +41,9 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
push_frontend_feature_flag(:restructured_mr_widget, project, default_enabled: :yaml)
push_frontend_feature_flag(:refactor_mr_widgets_extensions, project, default_enabled: :yaml)
push_frontend_feature_flag(:rebase_without_ci_ui, project, default_enabled: :yaml)
- push_frontend_feature_flag(:rearrange_pipelines_table, project, default_enabled: :yaml)
push_frontend_feature_flag(:markdown_continue_lists, project, default_enabled: :yaml)
+ push_frontend_feature_flag(:secure_vulnerability_training, project, default_enabled: :yaml)
+ push_frontend_feature_flag(:issue_assignees_widget, @project, default_enabled: :yaml)
# Usage data feature flags
push_frontend_feature_flag(:users_expanding_widgets_usage_data, project, default_enabled: :yaml)
push_frontend_feature_flag(:diff_settings_usage_data, default_enabled: :yaml)
@@ -87,7 +84,8 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
:ci_environments_status,
:destroy,
:rebase,
- :discussions
+ :discussions,
+ :pipelines
]
def index
@@ -95,7 +93,7 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
respond_to do |format|
format.html
- format.atom { render layout: 'xml.atom' }
+ format.atom { render layout: 'xml' }
format.json do
render json: {
html: view_to_html_string("projects/merge_requests/_merge_requests")
@@ -220,8 +218,6 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
end
def context_commits
- return render_404 unless project.context_commits_enabled?
-
# Get commits from repository
# or from cache if already merged
commits = ContextCommitsFinder.new(project, @merge_request, { search: params[:search], limit: params[:limit], offset: params[:offset] }).execute
@@ -553,12 +549,7 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
end
def endpoint_metadata_url(project, merge_request)
- params = request.query_parameters
- params[:view] = "inline"
-
- if Feature.enabled?(:default_merge_ref_for_diffs, project, default_enabled: :yaml)
- params = params.merge(diff_head: true)
- end
+ params = request.query_parameters.merge(view: 'inline', diff_head: true)
diffs_metadata_project_json_merge_request_path(project, merge_request, 'json', params)
end
diff --git a/app/controllers/projects/pipeline_schedules_controller.rb b/app/controllers/projects/pipeline_schedules_controller.rb
index ac94cc001dd..271c31b6429 100644
--- a/app/controllers/projects/pipeline_schedules_controller.rb
+++ b/app/controllers/projects/pipeline_schedules_controller.rb
@@ -10,6 +10,10 @@ class Projects::PipelineSchedulesController < Projects::ApplicationController
before_action :authorize_update_pipeline_schedule!, except: [:index, :new, :create, :play]
before_action :authorize_admin_pipeline_schedule!, only: [:destroy]
+ before_action do
+ push_frontend_feature_flag(:pipeline_schedules_with_tags, @project, default_enabled: :yaml)
+ end
+
feature_category :continuous_integration
# rubocop: disable CodeReuse/ActiveRecord
diff --git a/app/controllers/projects/pipelines/stages_controller.rb b/app/controllers/projects/pipelines/stages_controller.rb
index ce08b49ce9f..0447bbf29e7 100644
--- a/app/controllers/projects/pipelines/stages_controller.rb
+++ b/app/controllers/projects/pipelines/stages_controller.rb
@@ -5,6 +5,10 @@ module Projects
class StagesController < Projects::Pipelines::ApplicationController
before_action :authorize_update_pipeline!
+ urgency :low, [
+ :play_manual
+ ]
+
def play_manual
::Ci::PlayManualStageService
.new(@project, current_user, pipeline: pipeline)
diff --git a/app/controllers/projects/pipelines/tests_controller.rb b/app/controllers/projects/pipelines/tests_controller.rb
index 25ec7ab1335..602fc02686a 100644
--- a/app/controllers/projects/pipelines/tests_controller.rb
+++ b/app/controllers/projects/pipelines/tests_controller.rb
@@ -42,9 +42,9 @@ module Projects
end
def test_suite
- suite = builds.map do |build|
+ suite = builds.sum do |build|
build.collect_test_reports!(Gitlab::Ci::Reports::TestReports.new)
- end.sum
+ end
Gitlab::Ci::Reports::TestFailureHistory.new(suite.failed.values, project).load!
diff --git a/app/controllers/projects/pipelines_controller.rb b/app/controllers/projects/pipelines_controller.rb
index 7f680bbf121..8279bb20769 100644
--- a/app/controllers/projects/pipelines_controller.rb
+++ b/app/controllers/projects/pipelines_controller.rb
@@ -4,6 +4,9 @@ class Projects::PipelinesController < Projects::ApplicationController
include ::Gitlab::Utils::StrongMemoize
include RedisTracking
+ urgency :default, [:status]
+ urgency :low, [:index, :new, :builds, :show, :failures, :create, :stage, :retry, :dag, :cancel]
+
before_action :disable_query_limiting, only: [:create, :retry]
before_action :pipeline, except: [:index, :new, :create, :charts, :config_variables]
before_action :set_pipeline_path, only: [:show]
@@ -13,13 +16,6 @@ class Projects::PipelinesController < Projects::ApplicationController
before_action :authorize_create_pipeline!, only: [:new, :create, :config_variables]
before_action :authorize_update_pipeline!, only: [:retry, :cancel]
before_action :ensure_pipeline, only: [:show, :downloadable_artifacts]
- before_action do
- push_frontend_feature_flag(:rearrange_pipelines_table, project, default_enabled: :yaml)
- end
-
- before_action do
- push_frontend_feature_flag(:jobs_tab_vue, @project, default_enabled: :yaml)
- end
# Will be removed with https://gitlab.com/gitlab-org/gitlab/-/issues/225596
before_action :redirect_for_legacy_scope_filter, only: [:index], if: -> { request.format.html? }
@@ -55,8 +51,7 @@ class Projects::PipelinesController < Projects::ApplicationController
respond_to do |format|
format.html do
- enable_code_quality_walkthrough_experiment
- enable_ci_runner_templates_experiment
+ enable_runners_availability_section_experiment
end
format.json do
Gitlab::PollingInterval.set_header(response, interval: POLLING_INTERVAL)
@@ -166,14 +161,20 @@ class Projects::PipelinesController < Projects::ApplicationController
end
def retry
- ::Ci::RetryPipelineWorker.perform_async(pipeline.id, current_user.id) # rubocop:disable CodeReuse/Worker
+ # Check for access before execution to allow for async execution while still returning access results
+ access_response = ::Ci::RetryPipelineService.new(@project, current_user).check_access(pipeline)
+
+ if access_response.error?
+ response = { json: { errors: [access_response.message] }, status: access_response.http_status }
+ else
+ response = { json: {}, status: :no_content }
+ ::Ci::RetryPipelineWorker.perform_async(pipeline.id, current_user.id) # rubocop:disable CodeReuse/Worker
+ end
respond_to do |format|
- format.html do
- redirect_back_or_default default: project_pipelines_path(project)
+ format.json do
+ render response
end
-
- format.json { head :no_content }
end
end
@@ -224,7 +225,7 @@ class Projects::PipelinesController < Projects::ApplicationController
PipelineSerializer
.new(project: @project, current_user: @current_user)
.with_pagination(request, response)
- .represent(@pipelines, disable_coverage: true, preload: true, code_quality_walkthrough: params[:code_quality_walkthrough].present?)
+ .represent(@pipelines, disable_coverage: true, preload: true)
end
def render_show
@@ -309,28 +310,13 @@ class Projects::PipelinesController < Projects::ApplicationController
params.permit(:scope, :username, :ref, :status, :source)
end
- def enable_code_quality_walkthrough_experiment
- experiment(:code_quality_walkthrough, namespace: project.root_ancestor) do |e|
- e.exclude! unless current_user
- e.exclude! unless can?(current_user, :create_pipeline, project)
- e.exclude! unless project.root_ancestor.recent?
- e.exclude! if @pipelines_count.to_i > 0
- e.exclude! if helpers.has_gitlab_ci?(project)
-
- e.control {}
- e.candidate {}
- e.publish_to_database
- end
- end
-
- def enable_ci_runner_templates_experiment
- experiment(:ci_runner_templates, namespace: project.root_ancestor) do |e|
- e.exclude! unless current_user
- e.exclude! unless can?(current_user, :create_pipeline, project)
- e.exclude! if @pipelines_count.to_i > 0
- e.exclude! if helpers.has_gitlab_ci?(project)
+ def enable_runners_availability_section_experiment
+ return unless current_user
+ return unless can?(current_user, :create_pipeline, project)
+ return if @pipelines_count.to_i > 0
+ return if helpers.has_gitlab_ci?(project)
- e.control {}
+ experiment(:runners_availability_section, namespace: project.root_ancestor) do |e|
e.candidate {}
e.publish_to_database
end
diff --git a/app/controllers/projects/project_members_controller.rb b/app/controllers/projects/project_members_controller.rb
index dc0614c6bdd..0279a65f262 100644
--- a/app/controllers/projects/project_members_controller.rb
+++ b/app/controllers/projects/project_members_controller.rb
@@ -13,8 +13,6 @@ class Projects::ProjectMembersController < Projects::ApplicationController
def index
@sort = params[:sort].presence || sort_value_name
- @skip_groups = @project.related_group_ids
-
@group_links = @project.project_group_links
@group_links = @group_links.search(params[:search_groups]) if params[:search_groups].present?
@@ -24,25 +22,6 @@ class Projects::ProjectMembersController < Projects::ApplicationController
end
@project_members = present_members(non_invited_members.page(params[:page]))
-
- @project_member = @project.project_members.new
- end
-
- def import
- @projects = Project.visible_to_user_and_access_level(current_user, Gitlab::Access::MAINTAINER).order_id_desc
- end
-
- def apply_import
- source_project = Project.find(params[:source_project_id])
-
- if can?(current_user, :admin_project_member, source_project)
- status = @project.team.import(source_project, current_user)
- notice = status ? "Successfully imported" : "Import failed"
- else
- return render_404
- end
-
- redirect_to(project_project_members_path(project), notice: notice)
end
# MembershipActions concern
diff --git a/app/controllers/projects/redirect_controller.rb b/app/controllers/projects/redirect_controller.rb
new file mode 100644
index 00000000000..6bcbe87ee42
--- /dev/null
+++ b/app/controllers/projects/redirect_controller.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+# Projects::RedirectController is used to resolve the route projects/:id.
+# It's helpful for this to be in its own controller so that the
+# ProjectsController can assume that :namespace_id exists
+class Projects::RedirectController < ::ApplicationController
+ skip_before_action :authenticate_user!
+
+ feature_category :projects
+
+ def redirect_from_id
+ project = Project.find(params[:id])
+
+ if can?(current_user, :read_project, project)
+ redirect_to project
+ else
+ render_404
+ end
+ end
+end
diff --git a/app/controllers/projects/releases_controller.rb b/app/controllers/projects/releases_controller.rb
index 7fba6cc5bf4..1a2baf96020 100644
--- a/app/controllers/projects/releases_controller.rb
+++ b/app/controllers/projects/releases_controller.rb
@@ -7,6 +7,7 @@ class Projects::ReleasesController < Projects::ApplicationController
before_action :authorize_read_release!
before_action :authorize_update_release!, only: %i[edit update]
before_action :authorize_create_release!, only: :new
+ before_action :validate_suffix_path, :fetch_latest_tag, only: :latest_permalink
before_action only: :index do
push_frontend_feature_flag(:releases_index_apollo_client, project, default_enabled: :yaml)
end
@@ -26,10 +27,24 @@ class Projects::ReleasesController < Projects::ApplicationController
redirect_to link.url
end
+ def latest_permalink
+ unless @latest_tag.present?
+ return render_404
+ end
+
+ query_parameters_except_order_by = request.query_parameters.except(:order_by)
+
+ redirect_url = project_release_url(@project, @latest_tag)
+ redirect_url += "/#{params[:suffix_path]}" if params[:suffix_path]
+ redirect_url += "?#{query_parameters_except_order_by.compact.to_param}" if query_parameters_except_order_by.present?
+
+ redirect_to redirect_url
+ end
+
private
- def releases
- ReleasesFinder.new(@project, current_user).execute
+ def releases(params = {})
+ ReleasesFinder.new(@project, current_user, params).execute
end
def authorize_update_release!
@@ -51,4 +66,18 @@ class Projects::ReleasesController < Projects::ApplicationController
def sanitized_tag_name
CGI.unescape(params[:tag])
end
+
+ # Default order_by is 'released_at', which is set in ReleasesFinder.
+ # Also if the passed order_by is invalid, we reject and default to 'released_at'.
+ def fetch_latest_tag
+ allowed_values = ['released_at']
+
+ params.reject! { |key, value| key.to_sym == :order_by && !allowed_values.any?(value) }
+
+ @latest_tag = releases(order_by: params[:order_by]).first&.tag
+ end
+
+ def validate_suffix_path
+ Gitlab::Utils.check_path_traversal!(params[:suffix_path]) if params[:suffix_path]
+ end
end
diff --git a/app/controllers/projects/runner_projects_controller.rb b/app/controllers/projects/runner_projects_controller.rb
index 39db7618db0..b77ce070492 100644
--- a/app/controllers/projects/runner_projects_controller.rb
+++ b/app/controllers/projects/runner_projects_controller.rb
@@ -14,7 +14,7 @@ class Projects::RunnerProjectsController < Projects::ApplicationController
path = project_runners_path(project)
- if @runner.assign_to(project, current_user)
+ if ::Ci::Runners::AssignRunnerService.new(@runner, @project, current_user).execute
redirect_to path, notice: s_('Runners|Runner assigned to project.')
else
assign_to_messages = @runner.errors.messages[:assign_to]
@@ -26,7 +26,8 @@ class Projects::RunnerProjectsController < Projects::ApplicationController
def destroy
runner_project = project.runner_projects.find(params[:id])
- runner_project.destroy
+
+ ::Ci::Runners::UnassignRunnerService.new(runner_project, current_user).execute
redirect_to project_runners_path(project), status: :found, notice: s_('Runners|Runner unassigned from project.')
end
diff --git a/app/controllers/projects/runners_controller.rb b/app/controllers/projects/runners_controller.rb
index 192a29730d9..0eda8e3352d 100644
--- a/app/controllers/projects/runners_controller.rb
+++ b/app/controllers/projects/runners_controller.rb
@@ -14,7 +14,7 @@ class Projects::RunnersController < Projects::ApplicationController
end
def update
- if Ci::UpdateRunnerService.new(@runner).update(runner_params)
+ if Ci::Runners::UpdateRunnerService.new(@runner).update(runner_params)
redirect_to project_runner_path(@project, @runner), notice: _('Runner was successfully updated.')
else
render 'edit'
@@ -23,14 +23,14 @@ class Projects::RunnersController < Projects::ApplicationController
def destroy
if @runner.only_for?(project)
- Ci::UnregisterRunnerService.new(@runner).execute
+ Ci::Runners::UnregisterRunnerService.new(@runner, current_user).execute
end
redirect_to project_runners_path(@project), status: :found
end
def resume
- if Ci::UpdateRunnerService.new(@runner).update(active: true)
+ if Ci::Runners::UpdateRunnerService.new(@runner).update(active: true)
redirect_to project_runners_path(@project), notice: _('Runner was successfully updated.')
else
redirect_to project_runners_path(@project), alert: _('Runner was not updated.')
@@ -38,7 +38,7 @@ class Projects::RunnersController < Projects::ApplicationController
end
def pause
- if Ci::UpdateRunnerService.new(@runner).update(active: false)
+ if Ci::Runners::UpdateRunnerService.new(@runner).update(active: false)
redirect_to project_runners_path(@project), notice: _('Runner was successfully updated.')
else
redirect_to project_runners_path(@project), alert: _('Runner was not updated.')
diff --git a/app/controllers/projects/serverless/functions_controller.rb b/app/controllers/projects/serverless/functions_controller.rb
index 3fc379a135a..b6f77a6d515 100644
--- a/app/controllers/projects/serverless/functions_controller.rb
+++ b/app/controllers/projects/serverless/functions_controller.rb
@@ -3,6 +3,7 @@
module Projects
module Serverless
class FunctionsController < Projects::ApplicationController
+ before_action :ensure_feature_enabled!
before_action :authorize_read_cluster!
feature_category :not_owned
@@ -69,6 +70,10 @@ module Projects
def serialize_function(function)
Projects::Serverless::ServiceSerializer.new(current_user: @current_user, project: project).represent(function)
end
+
+ def ensure_feature_enabled!
+ render_404 unless Feature.enabled?(:deprecated_serverless, project, default_enabled: :yaml, type: :ops)
+ end
end
end
end
diff --git a/app/controllers/projects/services_controller.rb b/app/controllers/projects/services_controller.rb
index 1321111faaf..105f8efde7b 100644
--- a/app/controllers/projects/services_controller.rb
+++ b/app/controllers/projects/services_controller.rb
@@ -13,6 +13,10 @@ class Projects::ServicesController < Projects::ApplicationController
before_action :set_deprecation_notice_for_prometheus_integration, only: [:edit, :update]
before_action :redirect_deprecated_prometheus_integration, only: [:update]
+ before_action do
+ push_frontend_feature_flag(:integration_form_sections, project, default_enabled: :yaml)
+ end
+
respond_to :html
layout "project_settings"
diff --git a/app/controllers/projects/settings/ci_cd_controller.rb b/app/controllers/projects/settings/ci_cd_controller.rb
index dd2fb57f7ac..3f4d26bb6ec 100644
--- a/app/controllers/projects/settings/ci_cd_controller.rb
+++ b/app/controllers/projects/settings/ci_cd_controller.rb
@@ -64,7 +64,7 @@ module Projects
end
def reset_registration_token
- @project.reset_runners_token!
+ ::Ci::Runners::ResetRegistrationTokenService.new(@project, current_user).execute
flash[:toast] = _("New runners registration token has been generated!")
redirect_to namespace_project_settings_ci_cd_path
diff --git a/app/controllers/projects/settings/operations_controller.rb b/app/controllers/projects/settings/operations_controller.rb
index 56e201c592f..43c72b358db 100644
--- a/app/controllers/projects/settings/operations_controller.rb
+++ b/app/controllers/projects/settings/operations_controller.rb
@@ -7,6 +7,10 @@ module Projects
before_action :authorize_admin_operations!
before_action :authorize_read_prometheus_alerts!, only: [:reset_alerting_token]
+ before_action do
+ push_frontend_feature_flag(:integrated_error_tracking, project)
+ end
+
respond_to :json, only: [:reset_alerting_token, :reset_pagerduty_token]
helper_method :error_tracking_setting
diff --git a/app/controllers/projects/tags_controller.rb b/app/controllers/projects/tags_controller.rb
index 6472d3c3454..eb3579551bd 100644
--- a/app/controllers/projects/tags_controller.rb
+++ b/app/controllers/projects/tags_controller.rb
@@ -42,7 +42,7 @@ class Projects::TagsController < Projects::ApplicationController
status = @tags_loading_error ? :service_unavailable : :ok
format.html { render status: status }
- format.atom { render layout: 'xml.atom', status: status }
+ format.atom { render layout: 'xml', status: status }
end
end
# rubocop: enable CodeReuse/ActiveRecord
diff --git a/app/controllers/projects/tree_controller.rb b/app/controllers/projects/tree_controller.rb
index 4f905a2d565..e447fc3f3fe 100644
--- a/app/controllers/projects/tree_controller.rb
+++ b/app/controllers/projects/tree_controller.rb
@@ -22,7 +22,6 @@ class Projects::TreeController < Projects::ApplicationController
push_frontend_feature_flag(:refactor_blob_viewer, @project, default_enabled: :yaml)
push_frontend_feature_flag(:highlight_js, @project, default_enabled: :yaml)
push_licensed_feature(:file_locks) if @project.licensed_feature_available?(:file_locks)
- push_frontend_feature_flag(:consolidated_edit_button, @project, default_enabled: :yaml)
end
feature_category :source_code_management
diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb
index 519d9cd0d52..507a8b66942 100644
--- a/app/controllers/projects_controller.rb
+++ b/app/controllers/projects_controller.rb
@@ -17,10 +17,10 @@ class ProjectsController < Projects::ApplicationController
around_action :allow_gitaly_ref_name_caching, only: [:index, :show]
before_action :disable_query_limiting, only: [:show, :create]
- before_action :authenticate_user!, except: [:index, :show, :activity, :refs, :resolve, :unfoldered_environment_names]
+ before_action :authenticate_user!, except: [:index, :show, :activity, :refs, :unfoldered_environment_names]
before_action :redirect_git_extension, only: [:show]
- before_action :project, except: [:index, :new, :create, :resolve]
- before_action :repository, except: [:index, :new, :create, :resolve]
+ before_action :project, except: [:index, :new, :create]
+ before_action :repository, except: [:index, :new, :create]
before_action :verify_git_import_enabled, only: [:create]
before_action :project_export_enabled, only: [:export, :download_export, :remove_export, :generate_new_export]
before_action :present_project, only: [:edit]
@@ -41,7 +41,6 @@ class ProjectsController < Projects::ApplicationController
push_frontend_feature_flag(:increase_page_size_exponentially, @project, default_enabled: :yaml)
push_frontend_feature_flag(:new_dir_modal, @project, default_enabled: :yaml)
push_licensed_feature(:file_locks) if @project.present? && @project.licensed_feature_available?(:file_locks)
- push_frontend_feature_flag(:consolidated_edit_button, @project, default_enabled: :yaml)
push_frontend_feature_flag(:work_items, @project, default_enabled: :yaml)
end
@@ -49,7 +48,7 @@ class ProjectsController < Projects::ApplicationController
feature_category :projects, [
:index, :show, :new, :create, :edit, :update, :transfer,
- :destroy, :resolve, :archive, :unarchive, :toggle_star, :activity
+ :destroy, :archive, :unarchive, :toggle_star, :activity
]
feature_category :source_code_management, [:remove_fork, :housekeeping, :refs]
@@ -174,7 +173,7 @@ class ProjectsController < Projects::ApplicationController
format.atom do
load_events
@events = @events.select { |event| event.visible_to_user?(current_user) }
- render layout: 'xml.atom'
+ render layout: 'xml'
end
end
end
@@ -325,16 +324,6 @@ class ProjectsController < Projects::ApplicationController
end
# rubocop: enable CodeReuse/ActiveRecord
- def resolve
- @project = Project.find(params[:id])
-
- if can?(current_user, :read_project, @project)
- redirect_to @project
- else
- render_404
- end
- end
-
def unfoldered_environment_names
respond_to do |format|
format.json do
@@ -346,11 +335,7 @@ class ProjectsController < Projects::ApplicationController
private
def refs_params
- if Feature.enabled?(:strong_parameters_for_project_controller, @project, default_enabled: :yaml)
- params.permit(:search, :sort, :ref, find: [])
- else
- params
- end
+ params.permit(:search, :sort, :ref, find: [])
end
# Render project landing depending of which features are available
diff --git a/app/controllers/registrations_controller.rb b/app/controllers/registrations_controller.rb
index 057c451ace2..7011bf856e3 100644
--- a/app/controllers/registrations_controller.rb
+++ b/app/controllers/registrations_controller.rb
@@ -15,7 +15,7 @@ class RegistrationsController < Devise::RegistrationsController
before_action :load_recaptcha, only: :new
before_action :set_invite_params, only: :new
before_action only: [:create] do
- check_rate_limit!(:user_sign_up, scope: request.ip) if Feature.enabled?(:rate_limit_user_sign_up_endpoint, default_enabled: :yaml)
+ check_rate_limit!(:user_sign_up, scope: request.ip)
end
before_action only: [:new] do
diff --git a/app/controllers/search_controller.rb b/app/controllers/search_controller.rb
index e38eeaed367..817da658f14 100644
--- a/app/controllers/search_controller.rb
+++ b/app/controllers/search_controller.rb
@@ -4,6 +4,7 @@ class SearchController < ApplicationController
include ControllerWithCrossProjectAccessCheck
include SearchHelper
include RedisTracking
+ include SearchRateLimitable
RESCUE_FROM_TIMEOUT_ACTIONS = [:count, :show, :autocomplete].freeze
@@ -17,7 +18,7 @@ class SearchController < ApplicationController
search_term_present = params[:search].present? || params[:term].present?
search_term_present && !params[:project_id].present?
end
- before_action :check_email_search_rate_limit!, only: [:show, :count, :autocomplete]
+ before_action :check_search_rate_limit!, only: [:show, :count, :autocomplete]
rescue_from ActiveRecord::QueryCanceled, with: :render_timeout
@@ -25,6 +26,7 @@ class SearchController < ApplicationController
feature_category :global_search
urgency :high, [:opensearch]
+ urgency :low, [:count]
def show
@project = search_service.project
@@ -201,12 +203,6 @@ class SearchController < ApplicationController
render status: :request_timeout
end
end
-
- def check_email_search_rate_limit!
- return unless search_service.params.email_lookup?
-
- check_rate_limit!(:user_email_lookup, scope: [current_user])
- end
end
SearchController.prepend_mod_with('SearchController')
diff --git a/app/controllers/uploads_controller.rb b/app/controllers/uploads_controller.rb
index d7eb3ccd274..4df0ef78907 100644
--- a/app/controllers/uploads_controller.rb
+++ b/app/controllers/uploads_controller.rb
@@ -40,30 +40,29 @@ class UploadsController < ApplicationController
upload_model_class.find(params[:id])
end
- def authorize_access!
- authorized =
- case model
- when Note
- can?(current_user, :read_project, model.project)
- when Snippet, ProjectSnippet
- can?(current_user, :read_snippet, model)
- when User
- # We validate the current user has enough (writing)
- # access to itself when a secret is given.
- # For instance, user avatars are readable by anyone,
- # while temporary, user snippet uploads are not.
- !secret? || can?(current_user, :update_user, model)
- when Appearance
- true
- when Projects::Topic
- true
- else
- permission = "read_#{model.class.underscore}".to_sym
-
- can?(current_user, permission, model)
- end
+ def authorized?
+ case model
+ when Note
+ can?(current_user, :read_project, model.project)
+ when Snippet, ProjectSnippet
+ can?(current_user, :read_snippet, model)
+ when User
+ # We validate the current user has enough (writing)
+ # access to itself when a secret is given.
+ # For instance, user avatars are readable by anyone,
+ # while temporary, user snippet uploads are not.
+ !secret? || can?(current_user, :update_user, model)
+ when Appearance
+ true
+ when Projects::Topic
+ true
+ else
+ can?(current_user, "read_#{model.class.underscore}".to_sym, model)
+ end
+ end
- render_unauthorized unless authorized
+ def authorize_access!
+ render_unauthorized unless authorized?
end
def authorize_create_access!
diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb
index f6cef7e133c..dc02e4a3e87 100644
--- a/app/controllers/users_controller.rb
+++ b/app/controllers/users_controller.rb
@@ -24,7 +24,7 @@ class UsersController < ApplicationController
before_action :authorize_read_user_profile!,
only: [:calendar, :calendar_activities, :groups, :projects, :contributed, :starred, :snippets, :followers, :following]
before_action only: [:exists] do
- check_rate_limit!(:username_exists, scope: request.ip) if Feature.enabled?(:rate_limit_username_exists_endpoint, default_enabled: :yaml)
+ check_rate_limit!(:username_exists, scope: request.ip)
end
feature_category :users
@@ -35,7 +35,7 @@ class UsersController < ApplicationController
format.atom do
load_events
- render layout: 'xml.atom'
+ render layout: 'xml'
end
format.json do
diff --git a/app/events/repositories/keep_around_refs_created_event.rb b/app/events/repositories/keep_around_refs_created_event.rb
new file mode 100644
index 00000000000..2ac499e6e21
--- /dev/null
+++ b/app/events/repositories/keep_around_refs_created_event.rb
@@ -0,0 +1,14 @@
+# frozen_string_literal: true
+
+module Repositories
+ class KeepAroundRefsCreatedEvent < ::Gitlab::EventStore::Event
+ def schema
+ {
+ 'type' => 'object',
+ 'properties' => {
+ 'project_id' => { 'type' => 'integer' }
+ }
+ }
+ end
+ end
+end
diff --git a/app/experiments/application_experiment.rb b/app/experiments/application_experiment.rb
index f6af7ca15bb..f74e7fe3b1d 100644
--- a/app/experiments/application_experiment.rb
+++ b/app/experiments/application_experiment.rb
@@ -1,19 +1,7 @@
# frozen_string_literal: true
class ApplicationExperiment < Gitlab::Experiment
- def publish(_result = nil)
- super
-
- publish_to_client
- end
-
- def publish_to_client
- return unless should_track?
-
- Gon.push({ experiment: { name => signature } }, true)
- rescue NoMethodError
- # means we're not in the request cycle, and can't add to Gon. Log a warning maybe?
- end
+ control { nil } # provide a default control for anonymous experiments
def publish_to_database
ActiveSupport::Deprecation.warn('publish_to_database is deprecated and should not be used for reporting anymore')
diff --git a/app/experiments/combined_registration_experiment.rb b/app/experiments/combined_registration_experiment.rb
index 576e10815aa..38295cec0d3 100644
--- a/app/experiments/combined_registration_experiment.rb
+++ b/app/experiments/combined_registration_experiment.rb
@@ -3,6 +3,9 @@
class CombinedRegistrationExperiment < ApplicationExperiment
include Rails.application.routes.url_helpers
+ control { new_users_sign_up_group_path }
+ candidate { new_users_sign_up_groups_project_path }
+
def key_for(source, _ = nil)
super(source, 'force_company_trial')
end
@@ -10,12 +13,4 @@ class CombinedRegistrationExperiment < ApplicationExperiment
def redirect_path
run
end
-
- def control_behavior
- new_users_sign_up_group_path
- end
-
- def candidate_behavior
- new_users_sign_up_groups_project_path
- end
end
diff --git a/app/experiments/in_product_guidance_environments_webide_experiment.rb b/app/experiments/in_product_guidance_environments_webide_experiment.rb
index 6567ec0b3f1..78602874cb7 100644
--- a/app/experiments/in_product_guidance_environments_webide_experiment.rb
+++ b/app/experiments/in_product_guidance_environments_webide_experiment.rb
@@ -1,11 +1,9 @@
# frozen_string_literal: true
class InProductGuidanceEnvironmentsWebideExperiment < ApplicationExperiment
- exclude :has_environments?
+ control { false }
- def control_behavior
- false
- end
+ exclude :has_environments?
private
diff --git a/app/experiments/new_project_sast_enabled_experiment.rb b/app/experiments/new_project_sast_enabled_experiment.rb
index ee9d0dc1700..4aca4c875b2 100644
--- a/app/experiments/new_project_sast_enabled_experiment.rb
+++ b/app/experiments/new_project_sast_enabled_experiment.rb
@@ -1,21 +1,15 @@
# frozen_string_literal: true
class NewProjectSastEnabledExperiment < ApplicationExperiment
- def publish(_result = nil)
+ control { }
+ variant(:candidate) { }
+ variant(:free_indicator) { }
+ variant(:unchecked_candidate) { }
+ variant(:unchecked_free_indicator) { }
+
+ def publish(*args)
super
publish_to_database
end
-
- def candidate_behavior
- end
-
- def free_indicator_behavior
- end
-
- def unchecked_candidate_behavior
- end
-
- def unchecked_free_indicator_behavior
- end
end
diff --git a/app/experiments/require_verification_for_namespace_creation_experiment.rb b/app/experiments/require_verification_for_namespace_creation_experiment.rb
index 0c47f5d183c..cb667c6ae60 100644
--- a/app/experiments/require_verification_for_namespace_creation_experiment.rb
+++ b/app/experiments/require_verification_for_namespace_creation_experiment.rb
@@ -1,18 +1,13 @@
# frozen_string_literal: true
class RequireVerificationForNamespaceCreationExperiment < ApplicationExperiment
+ control { false }
+ candidate { true }
+
exclude :existing_user
EXPERIMENT_START_DATE = Date.new(2022, 1, 31)
- def control_behavior
- false
- end
-
- def candidate_behavior
- true
- end
-
def candidate?
run
end
diff --git a/app/experiments/security_reports_mr_widget_prompt_experiment.rb b/app/experiments/security_reports_mr_widget_prompt_experiment.rb
index bcb9d64fcb7..51b81be672d 100644
--- a/app/experiments/security_reports_mr_widget_prompt_experiment.rb
+++ b/app/experiments/security_reports_mr_widget_prompt_experiment.rb
@@ -1,14 +1,12 @@
# frozen_string_literal: true
class SecurityReportsMrWidgetPromptExperiment < ApplicationExperiment
+ control { }
+ candidate { }
+
def publish(_result = nil)
super
publish_to_database
end
-
- # This is a purely client side experiment, and since we don't have a nicer
- # way to define variants yet, we define them here.
- def candidate_behavior
- end
end
diff --git a/app/finders/admin/projects_finder.rb b/app/finders/admin/projects_finder.rb
index 53dbf65c43a..fc18bb1984a 100644
--- a/app/finders/admin/projects_finder.rb
+++ b/app/finders/admin/projects_finder.rb
@@ -69,7 +69,7 @@ class Admin::ProjectsFinder
end
def sort(items)
- sort = params.fetch(:sort) { 'latest_activity_desc' }
+ sort = params.fetch(:sort, 'latest_activity_desc')
items.sort_by_attribute(sort)
end
end
diff --git a/app/finders/group_members_finder.rb b/app/finders/group_members_finder.rb
index fff17098c7b..4213a3f1965 100644
--- a/app/finders/group_members_finder.rb
+++ b/app/finders/group_members_finder.rb
@@ -60,6 +60,8 @@ class GroupMembersFinder < UnionFinder
members = members.filter_by_2fa(params[:two_factor])
end
+ members = apply_additional_filters(members)
+
by_created_at(members)
end
@@ -84,6 +86,11 @@ class GroupMembersFinder < UnionFinder
raise ArgumentError, "#{(include_relations - RELATIONS).first} #{INVALID_RELATION_TYPE_ERROR_MSG}"
end
end
+
+ def apply_additional_filters(members)
+ # overridden in EE to include additional filtering conditions.
+ members
+ end
end
GroupMembersFinder.prepend_mod_with('GroupMembersFinder')
diff --git a/app/finders/issuable_finder.rb b/app/finders/issuable_finder.rb
index 3e436f30971..bf7b2265ded 100644
--- a/app/finders/issuable_finder.rb
+++ b/app/finders/issuable_finder.rb
@@ -46,6 +46,7 @@ class IssuableFinder
requires_cross_project_access unless: -> { params.project? }
+ FULL_TEXT_SEARCH_TERM_REGEX = /\A[\p{ASCII}|\p{Latin}]+\z/.freeze
NEGATABLE_PARAMS_HELPER_KEYS = %i[project_id scope status include_subgroups].freeze
attr_accessor :current_user, :params
@@ -331,6 +332,8 @@ class IssuableFinder
return items if items.is_a?(ActiveRecord::NullRelation)
return items if Feature.enabled?(:disable_anonymous_search, type: :ops) && current_user.nil?
+ return items.pg_full_text_search(search) if use_full_text_search?
+
if use_cte_for_search?
cte = Gitlab::SQL::CTE.new(klass.table_name, items)
@@ -341,6 +344,13 @@ class IssuableFinder
end
# rubocop: enable CodeReuse/ActiveRecord
+ def use_full_text_search?
+ params[:in].blank? &&
+ klass.try(:pg_full_text_searchable_columns).present? &&
+ params[:search] =~ FULL_TEXT_SEARCH_TERM_REGEX &&
+ Feature.enabled?(:issues_full_text_search, params.project || params.group, default_enabled: :yaml)
+ end
+
# rubocop: disable CodeReuse/ActiveRecord
def by_iids(items)
params[:iids].present? ? items.where(iid: params[:iids]) : items
diff --git a/app/finders/pending_todos_finder.rb b/app/finders/pending_todos_finder.rb
index 509370b49a8..babff65cc37 100644
--- a/app/finders/pending_todos_finder.rb
+++ b/app/finders/pending_todos_finder.rb
@@ -27,7 +27,8 @@ class PendingTodosFinder
todos = by_target_id(todos)
todos = by_target_type(todos)
todos = by_discussion(todos)
- by_commit_id(todos)
+ todos = by_commit_id(todos)
+ by_action(todos)
end
def by_project(todos)
@@ -69,4 +70,10 @@ class PendingTodosFinder
todos
end
end
+
+ def by_action(todos)
+ return todos if params[:action].blank?
+
+ todos.for_action(params[:action])
+ end
end
diff --git a/app/finders/personal_access_tokens_finder.rb b/app/finders/personal_access_tokens_finder.rb
index 4a6eed8f5ee..be266045951 100644
--- a/app/finders/personal_access_tokens_finder.rb
+++ b/app/finders/personal_access_tokens_finder.rb
@@ -17,6 +17,7 @@ class PersonalAccessTokensFinder
tokens = by_users(tokens)
tokens = by_impersonation(tokens)
tokens = by_state(tokens)
+ tokens = by_owner_type(tokens)
sort(tokens)
end
@@ -32,6 +33,15 @@ class PersonalAccessTokensFinder
tokens
end
+ def by_owner_type(tokens)
+ case @params[:owner_type]
+ when 'human'
+ tokens.owner_is_human
+ else
+ tokens
+ end
+ end
+
def by_user(tokens)
return tokens unless @params[:user]
diff --git a/app/finders/projects/members/effective_access_level_finder.rb b/app/finders/projects/members/effective_access_level_finder.rb
index 4538fc4c855..90474aba02c 100644
--- a/app/finders/projects/members/effective_access_level_finder.rb
+++ b/app/finders/projects/members/effective_access_level_finder.rb
@@ -40,7 +40,7 @@ module Projects
avenues = [authorizable_project_members]
avenues << if project.personal?
- project_owner_acting_as_maintainer
+ project_owner
else
authorizable_group_members
end
@@ -85,9 +85,11 @@ module Projects
Member.from_union(members)
end
- def project_owner_acting_as_maintainer
+ # workaround until we migrate Project#owners to have membership with
+ # OWNER access level
+ def project_owner
user_id = project.namespace.owner.id
- access_level = Gitlab::Access::MAINTAINER
+ access_level = Gitlab::Access::OWNER
Member
.from(generate_from_statement([[user_id, access_level]])) # rubocop: disable CodeReuse/ActiveRecord
diff --git a/app/finders/projects/topics_finder.rb b/app/finders/projects/topics_finder.rb
index 7c3abc27cf7..c26b166a786 100644
--- a/app/finders/projects/topics_finder.rb
+++ b/app/finders/projects/topics_finder.rb
@@ -12,7 +12,7 @@ module Projects
end
def execute
- topics = Projects::Topic.order_by_total_projects_count
+ topics = Projects::Topic.order_by_non_private_projects_count
by_search(topics)
end
diff --git a/app/finders/releases/group_releases_finder.rb b/app/finders/releases/group_releases_finder.rb
new file mode 100644
index 00000000000..d87ba8c0b03
--- /dev/null
+++ b/app/finders/releases/group_releases_finder.rb
@@ -0,0 +1,74 @@
+# frozen_string_literal: true
+module Releases
+ ##
+ # The GroupReleasesFinder does not support all the options of ReleasesFinder
+ # due to use of InOperatorOptimization for finding subprojects/subgroups
+ #
+ # order_by - only ordering by released_at is supported
+ # filter by tag - currently not supported
+ class GroupReleasesFinder
+ include Gitlab::Utils::StrongMemoize
+
+ attr_reader :parent, :current_user, :params
+
+ def initialize(parent, current_user = nil, params = {})
+ @parent = parent
+ @current_user = current_user
+ @params = params
+
+ params[:order_by] ||= 'released_at'
+ params[:sort] ||= 'desc'
+ params[:page] ||= 0
+ params[:per] ||= 30
+ end
+
+ def execute(preload: true)
+ return Release.none unless Ability.allowed?(current_user, :read_release, parent)
+
+ releases = get_releases(preload: preload)
+
+ paginate_releases(releases)
+ end
+
+ private
+
+ def include_subgroups?
+ params.fetch(:include_subgroups, false)
+ end
+
+ def accessible_projects_scope
+ if include_subgroups?
+ Project.for_group_and_its_subgroups(parent)
+ else
+ parent.projects
+ end
+ end
+
+ # rubocop: disable CodeReuse/ActiveRecord
+ def get_releases(preload: true)
+ Gitlab::Pagination::Keyset::InOperatorOptimization::QueryBuilder.new(
+ scope: releases_scope(preload: preload),
+ array_scope: accessible_projects_scope.select(:id),
+ array_mapping_scope: -> (project_id_expression) { Release.where(Release.arel_table[:project_id].eq(project_id_expression)) },
+ finder_query: -> (order_by, id_expression) { Release.where(Release.arel_table[:id].eq(id_expression)) }
+ )
+ .execute
+ end
+
+ def releases_scope(preload: true)
+ scope = Release.all
+ scope = order_releases(scope)
+ scope = scope.preloaded if preload
+ scope
+ end
+
+ def order_releases(scope)
+ scope.sort_by_attribute("released_at_#{params[:sort]}").order(id: params[:sort])
+ end
+
+ def paginate_releases(releases)
+ releases.page(params[:page].to_i).per(params[:per])
+ end
+ # rubocop: enable CodeReuse/ActiveRecord
+ end
+end
diff --git a/app/graphql/mutations/ci/pipeline/retry.rb b/app/graphql/mutations/ci/pipeline/retry.rb
index ee93f99703e..895397a96ab 100644
--- a/app/graphql/mutations/ci/pipeline/retry.rb
+++ b/app/graphql/mutations/ci/pipeline/retry.rb
@@ -17,10 +17,11 @@ module Mutations
pipeline = authorized_find!(id: id)
project = pipeline.project
- ::Ci::RetryPipelineService.new(project, current_user).execute(pipeline)
+ service_response = ::Ci::RetryPipelineService.new(project, current_user).execute(pipeline)
+
{
pipeline: pipeline,
- errors: errors_on_object(pipeline)
+ errors: errors_on_object(pipeline) + service_response.errors
}
end
end
diff --git a/app/graphql/mutations/ci/runner/delete.rb b/app/graphql/mutations/ci/runner/delete.rb
index 21c3d55881c..1713ec0bf6d 100644
--- a/app/graphql/mutations/ci/runner/delete.rb
+++ b/app/graphql/mutations/ci/runner/delete.rb
@@ -17,20 +17,11 @@ module Mutations
def resolve(id:, **runner_attrs)
runner = authorized_find!(id)
- error = authenticate_delete_runner!(runner)
- return { errors: [error] } if error
-
- ::Ci::UnregisterRunnerService.new(runner).execute
+ ::Ci::Runners::UnregisterRunnerService.new(runner, current_user).execute
{ errors: runner.errors.full_messages }
end
- def authenticate_delete_runner!(runner)
- return if current_user.can_admin_all_resources?
-
- "Runner #{runner.to_global_id} associated with more than one project" if runner.runner_projects.count > 1
- end
-
def find_object(id)
# TODO: remove this line when the compatibility layer is removed
# See: https://gitlab.com/gitlab-org/gitlab/-/issues/257883
diff --git a/app/graphql/mutations/ci/runner/update.rb b/app/graphql/mutations/ci/runner/update.rb
index e6123b4283a..3432840f60f 100644
--- a/app/graphql/mutations/ci/runner/update.rb
+++ b/app/graphql/mutations/ci/runner/update.rb
@@ -53,7 +53,7 @@ module Mutations
def resolve(id:, **runner_attrs)
runner = authorized_find!(id)
- unless ::Ci::UpdateRunnerService.new(runner).update(runner_attrs)
+ unless ::Ci::Runners::UpdateRunnerService.new(runner).update(runner_attrs)
return { runner: nil, errors: runner.errors.full_messages }
end
diff --git a/app/graphql/mutations/ci/runners_registration_token/reset.rb b/app/graphql/mutations/ci/runners_registration_token/reset.rb
index 7976e8fb70d..29ef7aa2e81 100644
--- a/app/graphql/mutations/ci/runners_registration_token/reset.rb
+++ b/app/graphql/mutations/ci/runners_registration_token/reset.rb
@@ -45,20 +45,19 @@ module Mutations
def reset_token(type:, **args)
id = args[:id]
+ scope = nil
case type
when 'instance_type'
raise Gitlab::Graphql::Errors::ArgumentError, "id must not be specified for '#{type}' scope" if id.present?
- authorize!(:global)
-
- ApplicationSetting.current.reset_runners_registration_token!
- ApplicationSetting.current_without_cache.runners_registration_token
+ scope = ApplicationSetting.current
+ authorize!(scope)
when 'group_type', 'project_type'
- project_or_group = authorized_find!(type: type, id: id)
- project_or_group.reset_runners_token!
- project_or_group.runners_token
+ scope = authorized_find!(type: type, id: id)
end
+
+ ::Ci::Runners::ResetRegistrationTokenService.new(scope, current_user).execute if scope
end
end
end
diff --git a/app/graphql/mutations/concerns/mutations/spam_protection.rb b/app/graphql/mutations/concerns/mutations/spam_protection.rb
index 341067710b2..e61f66c02a5 100644
--- a/app/graphql/mutations/concerns/mutations/spam_protection.rb
+++ b/app/graphql/mutations/concerns/mutations/spam_protection.rb
@@ -16,30 +16,16 @@ module Mutations
private
- def spam_action_response(object)
- fields = spam_action_response_fields(object)
-
- # If the SpamActionService detected something as spam,
- # this is non-recoverable and the needs_captcha_response
- # should not be considered
- kind = if fields[:spam]
- :spam
- elsif fields[:needs_captcha_response]
- :needs_captcha_response
- end
-
- [kind, fields]
- end
-
def check_spam_action_response!(object)
- kind, fields = spam_action_response(object)
+ fields = spam_action_response_fields(object)
- case kind
- when :needs_captcha_response
+ if fields[:spam]
+ # If the SpamActionService detected something as spam, this is non-recoverable and the
+ # needs_captcha_response and other CAPTCHA-related fields should not be returned
+ raise SpamDisallowedError.new(SPAM_DISALLOWED_MESSAGE, extensions: { spam: true })
+ elsif fields[:needs_captcha_response]
fields.delete :spam
raise NeedsCaptchaResponseError.new(NEEDS_CAPTCHA_RESPONSE_MESSAGE, extensions: fields)
- when :spam
- raise SpamDisallowedError.new(SPAM_DISALLOWED_MESSAGE, extensions: { spam: true })
else
nil
end
diff --git a/app/graphql/mutations/notes/base.rb b/app/graphql/mutations/notes/base.rb
index d6c8121eee7..65bb9e4644c 100644
--- a/app/graphql/mutations/notes/base.rb
+++ b/app/graphql/mutations/notes/base.rb
@@ -3,6 +3,12 @@
module Mutations
module Notes
class Base < BaseMutation
+ QUICK_ACTION_ONLY_WARNING = <<~NB
+ If the body of the Note contains only quick actions,
+ the Note will be destroyed during an update, and no Note will be
+ returned.
+ NB
+
field :note,
Types::Notes::NoteType,
null: true,
diff --git a/app/graphql/mutations/notes/create/note.rb b/app/graphql/mutations/notes/create/note.rb
index 5a5d62a8c20..1cfc11c6b11 100644
--- a/app/graphql/mutations/notes/create/note.rb
+++ b/app/graphql/mutations/notes/create/note.rb
@@ -5,12 +5,18 @@ module Mutations
module Create
class Note < Base
graphql_name 'CreateNote'
+ description "Creates a Note.\n#{QUICK_ACTION_ONLY_WARNING}"
argument :discussion_id,
::Types::GlobalIDType[::Discussion],
required: false,
description: 'Global ID of the discussion this note is in reply to.'
+ argument :merge_request_diff_head_sha,
+ GraphQL::Types::String,
+ required: false,
+ description: 'SHA of the head commit which is used to ensure that the merge request has not been updated since the request was sent.'
+
private
def create_note_params(noteable, args)
@@ -28,7 +34,8 @@ module Mutations
end
super(noteable, args).merge({
- in_reply_to_discussion_id: discussion_id
+ in_reply_to_discussion_id: discussion_id,
+ merge_request_diff_head_sha: args[:merge_request_diff_head_sha]
})
end
diff --git a/app/graphql/mutations/notes/update/base.rb b/app/graphql/mutations/notes/update/base.rb
index 2dfa7b815a1..4c6df2776cc 100644
--- a/app/graphql/mutations/notes/update/base.rb
+++ b/app/graphql/mutations/notes/update/base.rb
@@ -6,12 +6,6 @@ module Mutations
# This is a Base class for the Note update mutations and is not
# mounted as a GraphQL mutation itself.
class Base < Mutations::Notes::Base
- QUICK_ACTION_ONLY_WARNING = <<~NB
- If the body of the Note contains only quick actions,
- the Note will be destroyed during the update, and no Note will be
- returned.
- NB
-
authorize :admin_note
argument :id,
diff --git a/app/graphql/mutations/saved_replies/base.rb b/app/graphql/mutations/saved_replies/base.rb
new file mode 100644
index 00000000000..468263b0f9d
--- /dev/null
+++ b/app/graphql/mutations/saved_replies/base.rb
@@ -0,0 +1,39 @@
+# frozen_string_literal: true
+
+module Mutations
+ module SavedReplies
+ class Base < BaseMutation
+ field :saved_reply, Types::SavedReplyType,
+ null: true,
+ description: 'Updated saved reply.'
+
+ private
+
+ def present_result(result)
+ if result.success?
+ {
+ saved_reply: result[:saved_reply],
+ errors: []
+ }
+ else
+ {
+ saved_reply: nil,
+ errors: result.message
+ }
+ end
+ end
+
+ def feature_enabled?
+ Feature.enabled?(:saved_replies, current_user, default_enabled: :yaml)
+ end
+
+ def find_object(id)
+ # TODO: remove this line when the compatibility layer is removed
+ # See: https://gitlab.com/gitlab-org/gitlab/-/issues/257883
+ id = ::Types::GlobalIDType[::Users::SavedReply].coerce_isolated_input(id)
+
+ GitlabSchema.find_by_gid(id)
+ end
+ end
+ end
+end
diff --git a/app/graphql/mutations/saved_replies/create.rb b/app/graphql/mutations/saved_replies/create.rb
new file mode 100644
index 00000000000..d97461a1c2a
--- /dev/null
+++ b/app/graphql/mutations/saved_replies/create.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+module Mutations
+ module SavedReplies
+ class Create < Base
+ graphql_name 'SavedReplyCreate'
+
+ authorize :create_saved_replies
+
+ argument :name, GraphQL::Types::String,
+ required: true,
+ description: copy_field_description(Types::SavedReplyType, :name)
+
+ argument :content, GraphQL::Types::String,
+ required: true,
+ description: copy_field_description(Types::SavedReplyType, :content)
+
+ def resolve(name:, content:)
+ raise Gitlab::Graphql::Errors::ResourceNotAvailable, 'Feature disabled' unless feature_enabled?
+
+ result = ::Users::SavedReplies::CreateService.new(current_user: current_user, name: name, content: content).execute
+ present_result(result)
+ end
+ end
+ end
+end
diff --git a/app/graphql/mutations/saved_replies/update.rb b/app/graphql/mutations/saved_replies/update.rb
new file mode 100644
index 00000000000..bacc6ceb39e
--- /dev/null
+++ b/app/graphql/mutations/saved_replies/update.rb
@@ -0,0 +1,31 @@
+# frozen_string_literal: true
+
+module Mutations
+ module SavedReplies
+ class Update < Base
+ graphql_name 'SavedReplyUpdate'
+
+ authorize :update_saved_replies
+
+ argument :id, Types::GlobalIDType[::Users::SavedReply],
+ required: true,
+ description: copy_field_description(Types::SavedReplyType, :id)
+
+ argument :name, GraphQL::Types::String,
+ required: true,
+ description: copy_field_description(Types::SavedReplyType, :name)
+
+ argument :content, GraphQL::Types::String,
+ required: true,
+ description: copy_field_description(Types::SavedReplyType, :content)
+
+ def resolve(id:, name:, content:)
+ raise Gitlab::Graphql::Errors::ResourceNotAvailable, 'Feature disabled' unless feature_enabled?
+
+ saved_reply = authorized_find!(id)
+ result = ::Users::SavedReplies::UpdateService.new(current_user: current_user, saved_reply: saved_reply, name: name, content: content).execute
+ present_result(result)
+ end
+ end
+ end
+end
diff --git a/app/graphql/mutations/work_items/create.rb b/app/graphql/mutations/work_items/create.rb
index 81454db62b1..48f0f470988 100644
--- a/app/graphql/mutations/work_items/create.rb
+++ b/app/graphql/mutations/work_items/create.rb
@@ -33,7 +33,7 @@ module Mutations
def resolve(project_path:, **attributes)
project = authorized_find!(project_path)
- unless Feature.enabled?(:work_items, project)
+ unless Feature.enabled?(:work_items, project, default_enabled: :yaml)
return { errors: ['`work_items` feature flag disabled for this project'] }
end
diff --git a/app/graphql/mutations/work_items/create_from_task.rb b/app/graphql/mutations/work_items/create_from_task.rb
new file mode 100644
index 00000000000..16d1e646167
--- /dev/null
+++ b/app/graphql/mutations/work_items/create_from_task.rb
@@ -0,0 +1,64 @@
+# frozen_string_literal: true
+
+module Mutations
+ module WorkItems
+ class CreateFromTask < BaseMutation
+ graphql_name 'WorkItemCreateFromTask'
+
+ include Mutations::SpamProtection
+
+ description "Creates a work item from a task in another work item's description." \
+ " Available only when feature flag `work_items` is enabled. This feature is experimental and is subject to change without notice."
+
+ authorize :update_work_item
+
+ argument :id, ::Types::GlobalIDType[::WorkItem],
+ required: true,
+ description: 'Global ID of the work item.'
+ argument :work_item_data, ::Types::WorkItems::ConvertTaskInputType,
+ required: true,
+ description: 'Arguments necessary to convert a task into a work item.',
+ prepare: ->(attributes, _ctx) { attributes.to_h }
+
+ field :work_item, Types::WorkItemType,
+ null: true,
+ description: 'Updated work item.'
+
+ field :new_work_item, Types::WorkItemType,
+ null: true,
+ description: 'New work item created from task.'
+
+ def resolve(id:, work_item_data:)
+ work_item = authorized_find!(id: id)
+
+ unless Feature.enabled?(:work_items, work_item.project, default_enabled: :yaml)
+ return { errors: ['`work_items` feature flag disabled for this project'] }
+ end
+
+ spam_params = ::Spam::SpamParams.new_from_request(request: context[:request])
+
+ result = ::WorkItems::CreateFromTaskService.new(
+ work_item: work_item,
+ current_user: current_user,
+ work_item_params: work_item_data,
+ spam_params: spam_params
+ ).execute
+
+ check_spam_action_response!(result[:work_item]) if result[:work_item]
+
+ response = { errors: result.errors }
+ response.merge!(work_item: work_item, new_work_item: result[:work_item]) if result.success?
+
+ response
+ end
+
+ private
+
+ def find_object(id:)
+ # TODO: Remove coercion when working on https://gitlab.com/gitlab-org/gitlab/-/issues/257883
+ id = ::Types::GlobalIDType[::WorkItem].coerce_isolated_input(id)
+ GitlabSchema.find_by_gid(id)
+ end
+ end
+ end
+end
diff --git a/app/graphql/mutations/work_items/delete.rb b/app/graphql/mutations/work_items/delete.rb
index 71792a802c0..f32354878ec 100644
--- a/app/graphql/mutations/work_items/delete.rb
+++ b/app/graphql/mutations/work_items/delete.rb
@@ -20,7 +20,7 @@ module Mutations
def resolve(id:)
work_item = authorized_find!(id: id)
- unless Feature.enabled?(:work_items, work_item.project)
+ unless Feature.enabled?(:work_items, work_item.project, default_enabled: :yaml)
return { errors: ['`work_items` feature flag disabled for this project'] }
end
diff --git a/app/graphql/mutations/work_items/update.rb b/app/graphql/mutations/work_items/update.rb
index 3ab9ba2d502..2700cbdb709 100644
--- a/app/graphql/mutations/work_items/update.rb
+++ b/app/graphql/mutations/work_items/update.rb
@@ -28,7 +28,7 @@ module Mutations
def resolve(id:, **attributes)
work_item = authorized_find!(id: id)
- unless Feature.enabled?(:work_items, work_item.project)
+ unless Feature.enabled?(:work_items, work_item.project, default_enabled: :yaml)
return { errors: ['`work_items` feature flag disabled for this project'] }
end
diff --git a/app/graphql/queries/burndown_chart/burnup.query.graphql b/app/graphql/queries/burndown_chart/burnup.query.graphql
index 7a389a6def5..0795645f8b7 100644
--- a/app/graphql/queries/burndown_chart/burnup.query.graphql
+++ b/app/graphql/queries/burndown_chart/burnup.query.graphql
@@ -1,4 +1,9 @@
-query BurnupTimesSeriesData($id: ID!, $isIteration: Boolean = false, $weight: Boolean = false) {
+query BurnupTimesSeriesData(
+ $id: ID!
+ $isIteration: Boolean = false
+ $weight: Boolean = false
+ $fullPath: String
+) {
milestone(id: $id) @skip(if: $isIteration) {
__typename
id
@@ -37,7 +42,7 @@ query BurnupTimesSeriesData($id: ID!, $isIteration: Boolean = false, $weight: Bo
__typename
id
title
- report {
+ report(fullPath: $fullPath) {
__typename
burnupTimeSeries {
__typename
diff --git a/app/graphql/resolvers/blobs_resolver.rb b/app/graphql/resolvers/blobs_resolver.rb
index d0eb2deaf48..0704a845bb0 100644
--- a/app/graphql/resolvers/blobs_resolver.rb
+++ b/app/graphql/resolvers/blobs_resolver.rb
@@ -30,8 +30,17 @@ module Resolvers
return [] if repository.empty?
ref ||= repository.root_ref
+ validate_ref(ref)
repository.blobs_at(paths.map { |path| [ref, path] })
end
+
+ private
+
+ def validate_ref(ref)
+ unless Gitlab::GitRefValidator.validate(ref)
+ raise Gitlab::Graphql::Errors::ArgumentError, 'Ref is not valid'
+ end
+ end
end
end
diff --git a/app/graphql/resolvers/ci/config_resolver.rb b/app/graphql/resolvers/ci/config_resolver.rb
index 387185b5171..f9d60650443 100644
--- a/app/graphql/resolvers/ci/config_resolver.rb
+++ b/app/graphql/resolvers/ci/config_resolver.rb
@@ -38,6 +38,8 @@ module Resolvers
.validate(content, dry_run: dry_run)
response(result).merge(merged_yaml: result.merged_yaml)
+ rescue GRPC::InvalidArgument => error
+ Gitlab::ErrorTracking.track_and_raise_exception(error, sha: sha)
end
private
diff --git a/app/graphql/resolvers/concerns/group_issuable_resolver.rb b/app/graphql/resolvers/concerns/group_issuable_resolver.rb
index 542ff5374ff..92d22409ff2 100644
--- a/app/graphql/resolvers/concerns/group_issuable_resolver.rb
+++ b/app/graphql/resolvers/concerns/group_issuable_resolver.rb
@@ -3,12 +3,21 @@
module GroupIssuableResolver
extend ActiveSupport::Concern
- class_methods do
- def include_subgroups(name_of_things)
- argument :include_subgroups, GraphQL::Types::Boolean,
- required: false,
- default_value: false,
- description: "Include #{name_of_things} belonging to subgroups"
- end
+ included do
+ argument :include_subgroups, GraphQL::Types::Boolean,
+ required: false,
+ default_value: false,
+ description: "Include #{issuable_collection_name} belonging to subgroups"
+
+ argument :include_archived, GraphQL::Types::Boolean,
+ required: false,
+ default_value: false,
+ description: "Return #{issuable_collection_name} from archived projects"
+ end
+
+ def resolve(**args)
+ args[:non_archived] = !args.delete(:include_archived)
+
+ super
end
end
diff --git a/app/graphql/resolvers/concerns/resolves_merge_requests.rb b/app/graphql/resolvers/concerns/resolves_merge_requests.rb
index 75f1ee478a8..a72b9a09118 100644
--- a/app/graphql/resolvers/concerns/resolves_merge_requests.rb
+++ b/app/graphql/resolvers/concerns/resolves_merge_requests.rb
@@ -51,7 +51,8 @@ module ResolvesMergeRequests
milestone: [:milestone],
security_auto_fix: [:author],
head_pipeline: [:merge_request_diff, { head_pipeline: [:merge_request] }],
- timelogs: [:timelogs]
+ timelogs: [:timelogs],
+ committers: [merge_request_diff: [:merge_request_diff_commits]]
}
end
end
diff --git a/app/graphql/resolvers/concerns/resolves_pipelines.rb b/app/graphql/resolvers/concerns/resolves_pipelines.rb
index 42c4c22a938..764ed9b15fd 100644
--- a/app/graphql/resolvers/concerns/resolves_pipelines.rb
+++ b/app/graphql/resolvers/concerns/resolves_pipelines.rb
@@ -20,11 +20,22 @@ module ResolvesPipelines
GraphQL::Types::String,
required: false,
description: "Filter pipelines by the sha of the commit they are run for."
-
argument :source,
GraphQL::Types::String,
required: false,
description: "Filter pipelines by their source."
+
+ argument :updated_after, Types::TimeType,
+ required: false,
+ description: 'Pipelines updated after this date.'
+ argument :updated_before, Types::TimeType,
+ required: false,
+ description: 'Pipelines updated before this date.'
+
+ argument :username,
+ GraphQL::Types::String,
+ required: false,
+ description: "Filter pipelines by the user that triggered the pipeline."
end
class_methods do
diff --git a/app/graphql/resolvers/group_issues_resolver.rb b/app/graphql/resolvers/group_issues_resolver.rb
index 28f9266974f..05c5e803539 100644
--- a/app/graphql/resolvers/group_issues_resolver.rb
+++ b/app/graphql/resolvers/group_issues_resolver.rb
@@ -3,9 +3,11 @@
module Resolvers
class GroupIssuesResolver < BaseIssuesResolver
- include GroupIssuableResolver
+ def self.issuable_collection_name
+ 'issues'
+ end
- include_subgroups 'issues'
+ include GroupIssuableResolver
def ready?(**args)
if args.dig(:not, :release_tag).present?
diff --git a/app/graphql/resolvers/group_members/notification_email_resolver.rb b/app/graphql/resolvers/group_members/notification_email_resolver.rb
new file mode 100644
index 00000000000..6cff4fbf531
--- /dev/null
+++ b/app/graphql/resolvers/group_members/notification_email_resolver.rb
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+module Resolvers
+ module GroupMembers
+ class NotificationEmailResolver < BaseResolver
+ include Gitlab::Graphql::Authorize::AuthorizeResource
+
+ type GraphQL::Types::String, null: true
+
+ def resolve
+ authorize!
+
+ BatchLoader::GraphQL.for(object.user_id).batch do |user_ids, loader|
+ User.find(user_ids).each do |user|
+ loader.call(user.id, user.notification_email_for(object.group))
+ end
+ end
+ end
+
+ def authorize!
+ raise_resource_not_available_error! unless user_is_admin?
+ end
+
+ def user_is_admin?
+ context[:current_user].present? && context[:current_user].can_admin_all_resources?
+ end
+ end
+ end
+end
diff --git a/app/graphql/resolvers/group_merge_requests_resolver.rb b/app/graphql/resolvers/group_merge_requests_resolver.rb
index 34a4c67bc56..da1b6169c07 100644
--- a/app/graphql/resolvers/group_merge_requests_resolver.rb
+++ b/app/graphql/resolvers/group_merge_requests_resolver.rb
@@ -2,13 +2,16 @@
module Resolvers
class GroupMergeRequestsResolver < MergeRequestsResolver
+ def self.issuable_collection_name
+ 'merge requests'
+ end
+
include GroupIssuableResolver
alias_method :group, :object
type Types::MergeRequestType.connection_type, null: true
- include_subgroups 'merge requests'
accept_assignee
accept_author
diff --git a/app/graphql/resolvers/topics_resolver.rb b/app/graphql/resolvers/topics_resolver.rb
index d8199f3d89b..68e2ff69282 100644
--- a/app/graphql/resolvers/topics_resolver.rb
+++ b/app/graphql/resolvers/topics_resolver.rb
@@ -10,9 +10,9 @@ module Resolvers
def resolve(**args)
if args[:search].present?
- ::Projects::Topic.search(args[:search]).order_by_total_projects_count
+ ::Projects::Topic.search(args[:search]).order_by_non_private_projects_count
else
- ::Projects::Topic.order_by_total_projects_count
+ ::Projects::Topic.order_by_non_private_projects_count
end
end
end
diff --git a/app/graphql/resolvers/work_item_resolver.rb b/app/graphql/resolvers/work_item_resolver.rb
new file mode 100644
index 00000000000..7cf52339815
--- /dev/null
+++ b/app/graphql/resolvers/work_item_resolver.rb
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+module Resolvers
+ class WorkItemResolver < BaseResolver
+ include Gitlab::Graphql::Authorize::AuthorizeResource
+
+ authorize :read_work_item
+
+ type Types::WorkItemType, null: true
+
+ argument :id, ::Types::GlobalIDType[::WorkItem], required: true, description: 'Global ID of the work item.'
+
+ def resolve(id:)
+ work_item = authorized_find!(id: id)
+ return unless Feature.enabled?(:work_items, work_item.project, default_enabled: :yaml)
+
+ work_item
+ end
+
+ private
+
+ def find_object(id:)
+ # TODO: remove this line when the compatibility layer is removed
+ # See: https://gitlab.com/gitlab-org/gitlab/-/issues/257883
+ id = ::Types::GlobalIDType[::WorkItem].coerce_isolated_input(id)
+ GitlabSchema.find_by_gid(id)
+ end
+ end
+end
diff --git a/app/graphql/resolvers/work_items/types_resolver.rb b/app/graphql/resolvers/work_items/types_resolver.rb
index b7a32e13423..67a9d57d42f 100644
--- a/app/graphql/resolvers/work_items/types_resolver.rb
+++ b/app/graphql/resolvers/work_items/types_resolver.rb
@@ -5,10 +5,20 @@ module Resolvers
class TypesResolver < BaseResolver
type Types::WorkItems::TypeType.connection_type, null: true
- def resolve
+ argument :taskable, ::GraphQL::Types::Boolean,
+ required: false,
+ description: 'If `true`, only taskable work item types will be returned.' \
+ ' Argument is experimental and can be removed in the future without notice.'
+
+ def resolve(taskable: nil)
+ return unless Feature.enabled?(:work_items, object, default_enabled: :yaml)
+
# This will require a finder in the future when groups/projects get their work item types
# All groups/projects use the default types for now
- ::WorkItems::Type.default.order_by_name_asc
+ base_scope = ::WorkItems::Type.default
+ base_scope = base_scope.by_type(:task) if taskable
+
+ base_scope.order_by_name_asc
end
end
end
diff --git a/app/graphql/types/alert_management/alert_type.rb b/app/graphql/types/alert_management/alert_type.rb
index 7495d46179c..43b7bbb419f 100644
--- a/app/graphql/types/alert_management/alert_type.rb
+++ b/app/graphql/types/alert_management/alert_type.rb
@@ -9,6 +9,7 @@ module Types
present_using ::AlertManagement::AlertPresenter
implements(Types::Notes::NoteableInterface)
+ implements(Types::TodoableInterface)
authorize :read_alert_management_alert
@@ -127,6 +128,12 @@ module Types
null: true,
description: 'Alert condition for Prometheus.'
+ field :web_url,
+ GraphQL::Types::String,
+ method: :details_url,
+ null: false,
+ description: 'URL of the alert.'
+
def notes
object.ordered_notes
end
diff --git a/app/graphql/types/base_enum.rb b/app/graphql/types/base_enum.rb
index d70236f16f9..0224aeddac6 100644
--- a/app/graphql/types/base_enum.rb
+++ b/app/graphql/types/base_enum.rb
@@ -1,5 +1,6 @@
# frozen_string_literal: true
+# rubocop:disable Graphql/GraphqlNamePosition
module Types
class BaseEnum < GraphQL::Schema::Enum
class CustomValue < GraphQL::Schema::EnumValue
@@ -37,7 +38,7 @@ module Types
description(enum_mod.description) if use_description
enum_mod.definition.each do |key, content|
- value(key.to_s.upcase, **content)
+ value(key.to_s.upcase, value: key.to_s, description: content[:description])
end
end
# rubocop: enable Graphql/Descriptions
diff --git a/app/graphql/types/board_list_type.rb b/app/graphql/types/board_list_type.rb
index 733006369ea..7f4c49df429 100644
--- a/app/graphql/types/board_list_type.rb
+++ b/app/graphql/types/board_list_type.rb
@@ -14,18 +14,18 @@ module Types
null: false,
description: 'ID (global ID) of the list.'
- field :title, GraphQL::Types::String, null: false,
- description: 'Title of the list.'
- field :list_type, GraphQL::Types::String, null: false,
- description: 'Type of the list.'
- field :position, GraphQL::Types::Int, null: true,
- description: 'Position of list within the board.'
- field :label, Types::LabelType, null: true,
- description: 'Label of the list.'
field :collapsed, GraphQL::Types::Boolean, null: true,
description: 'Indicates if the list is collapsed for this user.'
field :issues_count, GraphQL::Types::Int, null: true,
description: 'Count of issues in the list.'
+ field :label, Types::LabelType, null: true,
+ description: 'Label of the list.'
+ field :list_type, GraphQL::Types::String, null: false,
+ description: 'Type of the list.'
+ field :position, GraphQL::Types::Int, null: true,
+ description: 'Position of list within the board.'
+ field :title, GraphQL::Types::String, null: false,
+ description: 'Title of the list.'
field :issues, ::Types::IssueType.connection_type, null: true,
description: 'Board issues.',
diff --git a/app/graphql/types/ci/analytics_type.rb b/app/graphql/types/ci/analytics_type.rb
index f52b9eae229..a77b8026f86 100644
--- a/app/graphql/types/ci/analytics_type.rb
+++ b/app/graphql/types/ci/analytics_type.rb
@@ -6,28 +6,28 @@ module Types
class AnalyticsType < BaseObject
graphql_name 'PipelineAnalytics'
- field :week_pipelines_totals, [GraphQL::Types::Int], null: true,
- description: 'Total weekly pipeline count.'
- field :week_pipelines_successful, [GraphQL::Types::Int], null: true,
- description: 'Total weekly successful pipeline count.'
- field :week_pipelines_labels, [GraphQL::Types::String], null: true,
- description: 'Labels for the weekly pipeline count.'
- field :month_pipelines_totals, [GraphQL::Types::Int], null: true,
- description: 'Total monthly pipeline count.'
- field :month_pipelines_successful, [GraphQL::Types::Int], null: true,
- description: 'Total monthly successful pipeline count.'
field :month_pipelines_labels, [GraphQL::Types::String], null: true,
description: 'Labels for the monthly pipeline count.'
- field :year_pipelines_totals, [GraphQL::Types::Int], null: true,
- description: 'Total yearly pipeline count.'
- field :year_pipelines_successful, [GraphQL::Types::Int], null: true,
- description: 'Total yearly successful pipeline count.'
- field :year_pipelines_labels, [GraphQL::Types::String], null: true,
- description: 'Labels for the yearly pipeline count.'
- field :pipeline_times_values, [GraphQL::Types::Int], null: true,
- description: 'Pipeline times.'
+ field :month_pipelines_successful, [GraphQL::Types::Int], null: true,
+ description: 'Total monthly successful pipeline count.'
+ field :month_pipelines_totals, [GraphQL::Types::Int], null: true,
+ description: 'Total monthly pipeline count.'
field :pipeline_times_labels, [GraphQL::Types::String], null: true,
description: 'Pipeline times labels.'
+ field :pipeline_times_values, [GraphQL::Types::Int], null: true,
+ description: 'Pipeline times.'
+ field :week_pipelines_labels, [GraphQL::Types::String], null: true,
+ description: 'Labels for the weekly pipeline count.'
+ field :week_pipelines_successful, [GraphQL::Types::Int], null: true,
+ description: 'Total weekly successful pipeline count.'
+ field :week_pipelines_totals, [GraphQL::Types::Int], null: true,
+ description: 'Total weekly pipeline count.'
+ field :year_pipelines_labels, [GraphQL::Types::String], null: true,
+ description: 'Labels for the yearly pipeline count.'
+ field :year_pipelines_successful, [GraphQL::Types::Int], null: true,
+ description: 'Total yearly successful pipeline count.'
+ field :year_pipelines_totals, [GraphQL::Types::Int], null: true,
+ description: 'Total yearly pipeline count.'
end
end
end
diff --git a/app/graphql/types/ci/ci_cd_setting_type.rb b/app/graphql/types/ci/ci_cd_setting_type.rb
index 790deab8f68..e43af6f3e78 100644
--- a/app/graphql/types/ci/ci_cd_setting_type.rb
+++ b/app/graphql/types/ci/ci_cd_setting_type.rb
@@ -7,18 +7,18 @@ module Types
authorize :admin_project
+ field :job_token_scope_enabled, GraphQL::Types::Boolean, null: true,
+ description: 'Indicates CI job tokens generated in this project have restricted access to resources.',
+ method: :job_token_scope_enabled?
+ field :keep_latest_artifact, GraphQL::Types::Boolean, null: true,
+ description: 'Whether to keep the latest builds artifacts.',
+ method: :keep_latest_artifacts_available?
field :merge_pipelines_enabled, GraphQL::Types::Boolean, null: true,
description: 'Whether merge pipelines are enabled.',
method: :merge_pipelines_enabled?
field :merge_trains_enabled, GraphQL::Types::Boolean, null: true,
description: 'Whether merge trains are enabled.',
method: :merge_trains_enabled?
- field :keep_latest_artifact, GraphQL::Types::Boolean, null: true,
- description: 'Whether to keep the latest builds artifacts.',
- method: :keep_latest_artifacts_available?
- field :job_token_scope_enabled, GraphQL::Types::Boolean, null: true,
- description: 'Indicates CI job tokens generated in this project have restricted access to resources.',
- method: :job_token_scope_enabled?
field :project, Types::ProjectType, null: true,
description: 'Project the CI/CD settings belong to.'
end
diff --git a/app/graphql/types/ci/config/group_type.rb b/app/graphql/types/ci/config/group_type.rb
index e5cb0d4e72f..19076fe9c20 100644
--- a/app/graphql/types/ci/config/group_type.rb
+++ b/app/graphql/types/ci/config/group_type.rb
@@ -7,10 +7,10 @@ module Types
class GroupType < BaseObject
graphql_name 'CiConfigGroup'
- field :name, GraphQL::Types::String, null: true,
- description: 'Name of the job group.'
field :jobs, Types::Ci::Config::JobType.connection_type, null: true,
description: 'Jobs in group.'
+ field :name, GraphQL::Types::String, null: true,
+ description: 'Name of the job group.'
field :size, GraphQL::Types::Int, null: true,
description: 'Size of the job group.'
end
diff --git a/app/graphql/types/ci/config/job_type.rb b/app/graphql/types/ci/config/job_type.rb
index 4cf6780ef60..20279143635 100644
--- a/app/graphql/types/ci/config/job_type.rb
+++ b/app/graphql/types/ci/config/job_type.rb
@@ -7,33 +7,33 @@ module Types
class JobType < BaseObject
graphql_name 'CiConfigJob'
- field :name, GraphQL::Types::String, null: true,
- description: 'Name of the job.'
- field :group_name, GraphQL::Types::String, null: true,
- description: 'Name of the job group.'
- field :stage, GraphQL::Types::String, null: true,
- description: 'Name of the job stage.'
- field :needs, Types::Ci::Config::NeedType.connection_type, null: true,
- description: 'Builds that must complete before the jobs run.'
+ field :after_script, [GraphQL::Types::String], null: true,
+ description: 'Override a set of commands that are executed after the job.'
field :allow_failure, GraphQL::Types::Boolean, null: true,
description: 'Allow job to fail.'
field :before_script, [GraphQL::Types::String], null: true,
description: 'Override a set of commands that are executed before the job.'
- field :script, [GraphQL::Types::String], null: true,
- description: 'Shell script that is executed by a runner.'
- field :after_script, [GraphQL::Types::String], null: true,
- description: 'Override a set of commands that are executed after the job.'
- field :when, GraphQL::Types::String, null: true,
- description: 'When to run the job.',
- resolver_method: :restrict_when_to_run_jobs
field :environment, GraphQL::Types::String, null: true,
description: 'Name of an environment to which the job deploys.'
field :except, Types::Ci::Config::JobRestrictionType, null: true,
description: 'Limit when jobs are not created.'
+ field :group_name, GraphQL::Types::String, null: true,
+ description: 'Name of the job group.'
+ field :name, GraphQL::Types::String, null: true,
+ description: 'Name of the job.'
+ field :needs, Types::Ci::Config::NeedType.connection_type, null: true,
+ description: 'Builds that must complete before the jobs run.'
field :only, Types::Ci::Config::JobRestrictionType, null: true,
description: 'Jobs are created when these conditions do not apply.'
+ field :script, [GraphQL::Types::String], null: true,
+ description: 'Shell script that is executed by a runner.'
+ field :stage, GraphQL::Types::String, null: true,
+ description: 'Name of the job stage.'
field :tags, [GraphQL::Types::String], null: true,
description: 'List of tags that are used to select a runner.'
+ field :when, GraphQL::Types::String, null: true,
+ description: 'When to run the job.',
+ resolver_method: :restrict_when_to_run_jobs
def restrict_when_to_run_jobs
object[:when]
diff --git a/app/graphql/types/ci/config/stage_type.rb b/app/graphql/types/ci/config/stage_type.rb
index 7e2aa9470f2..5b1163edac2 100644
--- a/app/graphql/types/ci/config/stage_type.rb
+++ b/app/graphql/types/ci/config/stage_type.rb
@@ -7,10 +7,10 @@ module Types
class StageType < BaseObject
graphql_name 'CiConfigStage'
- field :name, GraphQL::Types::String, null: true,
- description: 'Name of the stage.'
field :groups, Types::Ci::Config::GroupType.connection_type, null: true,
description: 'Groups of jobs for the stage.'
+ field :name, GraphQL::Types::String, null: true,
+ description: 'Name of the stage.'
end
end
end
diff --git a/app/graphql/types/ci/detailed_status_type.rb b/app/graphql/types/ci/detailed_status_type.rb
index 4433e921971..e3413551a3f 100644
--- a/app/graphql/types/ci/detailed_status_type.rb
+++ b/app/graphql/types/ci/detailed_status_type.rb
@@ -6,20 +6,23 @@ module Types
class DetailedStatusType < BaseObject
graphql_name 'DetailedStatus'
- field :id, GraphQL::Types::String, null: false,
- description: 'ID for a detailed status.',
- extras: [:parent]
- field :group, GraphQL::Types::String, null: true,
- description: 'Group of the status.'
- field :icon, GraphQL::Types::String, null: true,
- description: 'Icon of the status.'
- field :favicon, GraphQL::Types::String, null: true,
- description: 'Favicon of the status.'
+ field :action, Types::Ci::StatusActionType, null: true,
+ calls_gitaly: true,
+ description: 'Action information for the status. This includes method, button title, icon, path, and title.'
field :details_path, GraphQL::Types::String, null: true,
description: 'Path of the details for the status.'
+ field :favicon, GraphQL::Types::String, null: true,
+ description: 'Favicon of the status.'
+ field :group, GraphQL::Types::String, null: true,
+ description: 'Group of the status.'
field :has_details, GraphQL::Types::Boolean, null: true,
description: 'Indicates if the status has further details.',
method: :has_details?
+ field :icon, GraphQL::Types::String, null: true,
+ description: 'Icon of the status.'
+ field :id, GraphQL::Types::String, null: false,
+ description: 'ID for a detailed status.',
+ extras: [:parent]
field :label, GraphQL::Types::String, null: true,
calls_gitaly: true,
description: 'Label of the status.'
@@ -28,9 +31,6 @@ module Types
field :tooltip, GraphQL::Types::String, null: true,
description: 'Tooltip associated with the status.',
method: :status_tooltip
- field :action, Types::Ci::StatusActionType, null: true,
- calls_gitaly: true,
- description: 'Action information for the status. This includes method, button title, icon, path, and title.'
def id(parent:)
"#{object.id}-#{parent.object.object.id}"
diff --git a/app/graphql/types/ci/group_type.rb b/app/graphql/types/ci/group_type.rb
index 3ae23ba9bd4..c3c73ef170c 100644
--- a/app/graphql/types/ci/group_type.rb
+++ b/app/graphql/types/ci/group_type.rb
@@ -6,16 +6,16 @@ module Types
class GroupType < BaseObject
graphql_name 'CiGroup'
+ field :detailed_status, Types::Ci::DetailedStatusType, null: true,
+ description: 'Detailed status of the group.'
field :id, GraphQL::Types::String, null: false,
description: 'ID for a group.'
+ field :jobs, Ci::JobType.connection_type, null: true,
+ description: 'Jobs in group.'
field :name, GraphQL::Types::String, null: true,
description: 'Name of the job group.'
field :size, GraphQL::Types::Int, null: true,
description: 'Size of the group.'
- field :jobs, Ci::JobType.connection_type, null: true,
- description: 'Jobs in group.'
- field :detailed_status, Types::Ci::DetailedStatusType, null: true,
- description: 'Detailed status of the group.'
def detailed_status
object.detailed_status(context[:current_user])
diff --git a/app/graphql/types/ci/job_type.rb b/app/graphql/types/ci/job_type.rb
index 1320b96907e..83054553bd8 100644
--- a/app/graphql/types/ci/job_type.rb
+++ b/app/graphql/types/ci/job_type.rb
@@ -11,38 +11,38 @@ module Types
expose_permissions Types::PermissionTypes::Ci::Job
+ field :allow_failure, ::GraphQL::Types::Boolean, null: false,
+ description: 'Whether the job is allowed to fail.'
+ field :duration, GraphQL::Types::Int, null: true,
+ description: 'Duration of the job in seconds.'
field :id, ::Types::GlobalIDType[::CommitStatus].as('JobID'), null: true,
description: 'ID of the job.'
- field :pipeline, Types::Ci::PipelineType, null: true,
- description: 'Pipeline the job belongs to.'
field :name, GraphQL::Types::String, null: true,
description: 'Name of the job.'
field :needs, BuildNeedType.connection_type, null: true,
description: 'References to builds that must complete before the jobs run.'
+ field :pipeline, Types::Ci::PipelineType, null: true,
+ description: 'Pipeline the job belongs to.'
+ field :stage, Types::Ci::StageType, null: true,
+ description: 'Stage of the job.'
field :status,
type: ::Types::Ci::JobStatusEnum,
null: true,
description: "Status of the job."
- field :stage, Types::Ci::StageType, null: true,
- description: 'Stage of the job.'
- field :allow_failure, ::GraphQL::Types::Boolean, null: false,
- description: 'Whether the job is allowed to fail.'
- field :duration, GraphQL::Types::Int, null: true,
- description: 'Duration of the job in seconds.'
field :tags, [GraphQL::Types::String], null: true,
description: 'Tags for the current job.'
# Life-cycle timestamps:
field :created_at, Types::TimeType, null: false,
description: "When the job was created."
- field :queued_at, Types::TimeType, null: true,
- description: 'When the job was enqueued and marked as pending.'
- field :started_at, Types::TimeType, null: true,
- description: 'When the job was started.'
field :finished_at, Types::TimeType, null: true,
description: 'When a job has finished running.'
+ field :queued_at, Types::TimeType, null: true,
+ description: 'When the job was enqueued and marked as pending.'
field :scheduled_at, Types::TimeType, null: true,
description: 'Schedule for the build.'
+ field :started_at, Types::TimeType, null: true,
+ description: 'When the job was started.'
# Life-cycle durations:
field :queued_duration,
@@ -50,40 +50,40 @@ module Types
null: true,
description: 'How long the job was enqueued before starting.'
- field :downstream_pipeline, Types::Ci::PipelineType, null: true,
- description: 'Downstream pipeline for a bridge.'
- field :previous_stage_jobs_or_needs, Types::Ci::JobNeedUnion.connection_type, null: true,
- description: 'Jobs that must complete before the job runs. Returns `BuildNeed`, which is the needed jobs if the job uses the `needs` keyword, or the previous stage jobs otherwise.'
- field :detailed_status, Types::Ci::DetailedStatusType, null: true,
- description: 'Detailed status of the job.'
+ field :active, GraphQL::Types::Boolean, null: false, method: :active?,
+ description: 'Indicates the job is active.'
field :artifacts, Types::Ci::JobArtifactType.connection_type, null: true,
description: 'Artifacts generated by the job.'
- field :short_sha, type: GraphQL::Types::String, null: false,
- description: 'Short SHA1 ID of the commit.'
- field :scheduling_type, GraphQL::Types::String, null: true,
- description: 'Type of job scheduling. Value is `dag` if the job uses the `needs` keyword, and `stage` otherwise.'
+ field :cancelable, GraphQL::Types::Boolean, null: false, method: :cancelable?,
+ description: 'Indicates the job can be canceled.'
field :commit_path, GraphQL::Types::String, null: true,
description: 'Path to the commit that triggered the job.'
+ field :coverage, GraphQL::Types::Float, null: true,
+ description: 'Coverage level of the job.'
+ field :created_by_tag, GraphQL::Types::Boolean, null: false,
+ description: 'Whether the job was created by a tag.', method: :tag?
+ field :detailed_status, Types::Ci::DetailedStatusType, null: true,
+ description: 'Detailed status of the job.'
+ field :downstream_pipeline, Types::Ci::PipelineType, null: true,
+ description: 'Downstream pipeline for a bridge.'
+ field :manual_job, GraphQL::Types::Boolean, null: true,
+ description: 'Whether the job has a manual action.'
+ field :playable, GraphQL::Types::Boolean, null: false, method: :playable?,
+ description: 'Indicates the job can be played.'
+ field :previous_stage_jobs_or_needs, Types::Ci::JobNeedUnion.connection_type, null: true,
+ description: 'Jobs that must complete before the job runs. Returns `BuildNeed`, which is the needed jobs if the job uses the `needs` keyword, or the previous stage jobs otherwise.'
field :ref_name, GraphQL::Types::String, null: true,
description: 'Ref name of the job.'
field :ref_path, GraphQL::Types::String, null: true,
description: 'Path to the ref.'
- field :playable, GraphQL::Types::Boolean, null: false, method: :playable?,
- description: 'Indicates the job can be played.'
field :retryable, GraphQL::Types::Boolean, null: false, method: :retryable?,
description: 'Indicates the job can be retried.'
- field :cancelable, GraphQL::Types::Boolean, null: false, method: :cancelable?,
- description: 'Indicates the job can be canceled.'
- field :active, GraphQL::Types::Boolean, null: false, method: :active?,
- description: 'Indicates the job is active.'
+ field :scheduling_type, GraphQL::Types::String, null: true,
+ description: 'Type of job scheduling. Value is `dag` if the job uses the `needs` keyword, and `stage` otherwise.'
+ field :short_sha, type: GraphQL::Types::String, null: false,
+ description: 'Short SHA1 ID of the commit.'
field :stuck, GraphQL::Types::Boolean, null: false, method: :stuck?,
description: 'Indicates the job is stuck.'
- field :coverage, GraphQL::Types::Float, null: true,
- description: 'Coverage level of the job.'
- field :created_by_tag, GraphQL::Types::Boolean, null: false,
- description: 'Whether the job was created by a tag.'
- field :manual_job, GraphQL::Types::Boolean, null: true,
- description: 'Whether the job has a manual action.'
field :triggered, GraphQL::Types::Boolean, null: true,
description: 'Whether the job was triggered.'
@@ -173,10 +173,6 @@ module Types
object&.coverage
end
- def created_by_tag
- object.tag?
- end
-
def manual_job
object.try(:action?)
end
diff --git a/app/graphql/types/ci/runner_architecture_type.rb b/app/graphql/types/ci/runner_architecture_type.rb
index 08d3f98592b..eb576cf09ce 100644
--- a/app/graphql/types/ci/runner_architecture_type.rb
+++ b/app/graphql/types/ci/runner_architecture_type.rb
@@ -6,10 +6,10 @@ module Types
class RunnerArchitectureType < BaseObject
graphql_name 'RunnerArchitecture'
- field :name, GraphQL::Types::String, null: false,
- description: 'Name of the runner platform architecture.'
field :download_location, GraphQL::Types::String, null: false,
description: 'Download location for the runner for the platform architecture.'
+ field :name, GraphQL::Types::String, null: false,
+ description: 'Name of the runner platform architecture.'
end
end
end
diff --git a/app/graphql/types/ci/runner_platform_type.rb b/app/graphql/types/ci/runner_platform_type.rb
index ffcf6364968..3c893615b20 100644
--- a/app/graphql/types/ci/runner_platform_type.rb
+++ b/app/graphql/types/ci/runner_platform_type.rb
@@ -6,12 +6,12 @@ module Types
class RunnerPlatformType < BaseObject
graphql_name 'RunnerPlatform'
- field :name, GraphQL::Types::String, null: false,
- description: 'Name slug of the runner platform.'
- field :human_readable_name, GraphQL::Types::String, null: false,
- description: 'Human readable name of the runner platform.'
field :architectures, Types::Ci::RunnerArchitectureType.connection_type, null: true,
description: 'Runner architectures supported for the platform.'
+ field :human_readable_name, GraphQL::Types::String, null: false,
+ description: 'Human readable name of the runner platform.'
+ field :name, GraphQL::Types::String, null: false,
+ description: 'Name slug of the runner platform.'
end
end
end
diff --git a/app/graphql/types/ci/runner_type.rb b/app/graphql/types/ci/runner_type.rb
index 9094c6b96e4..a7f0730f07e 100644
--- a/app/graphql/types/ci/runner_type.rb
+++ b/app/graphql/types/ci/runner_type.rb
@@ -16,54 +16,20 @@ module Types
alias_method :runner, :object
- field :id, ::Types::GlobalIDType[::Ci::Runner], null: false,
- description: 'ID of the runner.'
- field :description, GraphQL::Types::String, null: true,
- description: 'Description of the runner.'
- field :created_at, Types::TimeType, null: true,
- description: 'Timestamp of creation of this runner.'
- field :contacted_at, Types::TimeType, null: true,
- description: 'Timestamp of last contact from this runner.',
- method: :contacted_at
- field :token_expires_at, Types::TimeType, null: true,
- description: 'Runner token expiration time.',
- method: :token_expires_at
- field :maximum_timeout, GraphQL::Types::Int, null: true,
- description: 'Maximum timeout (in seconds) for jobs processed by the runner.'
field :access_level, ::Types::Ci::RunnerAccessLevelEnum, null: false,
description: 'Access level of the runner.'
field :active, GraphQL::Types::Boolean, null: false,
description: 'Indicates the runner is allowed to receive jobs.',
deprecated: { reason: 'Use paused', milestone: '14.8' }
- field :paused, GraphQL::Types::Boolean, null: false,
- description: 'Indicates the runner is paused and not available to run jobs.'
- field :status,
- Types::Ci::RunnerStatusEnum,
- null: false,
- description: 'Status of the runner.',
- resolver: ::Resolvers::Ci::RunnerStatusResolver
- field :version, GraphQL::Types::String, null: true,
- description: 'Version of the runner.'
- field :short_sha, GraphQL::Types::String, null: true,
- description: %q(First eight characters of the runner's token used to authenticate new job requests. Used as the runner's unique ID.)
- field :revision, GraphQL::Types::String, null: true,
- description: 'Revision of the runner.'
- field :locked, GraphQL::Types::Boolean, null: true,
- description: 'Indicates the runner is locked.'
- field :run_untagged, GraphQL::Types::Boolean, null: false,
- description: 'Indicates the runner is able to run untagged jobs.'
- field :ip_address, GraphQL::Types::String, null: true,
- description: 'IP address of the runner.'
- field :runner_type, ::Types::Ci::RunnerTypeEnum, null: false,
- description: 'Type of the runner.'
- field :tag_list, [GraphQL::Types::String], null: true,
- description: 'Tags associated with the runner.'
- field :project_count, GraphQL::Types::Int, null: true,
- description: 'Number of projects that the runner is associated with.'
- field :job_count, GraphQL::Types::Int, null: true,
- description: "Number of jobs processed by the runner (limited to #{JOB_COUNT_LIMIT}, plus one to indicate that more items exist)."
field :admin_url, GraphQL::Types::String, null: true,
description: 'Admin URL of the runner. Only available for administrators.'
+ field :contacted_at, Types::TimeType, null: true,
+ description: 'Timestamp of last contact from this runner.',
+ method: :contacted_at
+ field :created_at, Types::TimeType, null: true,
+ description: 'Timestamp of creation of this runner.'
+ field :description, GraphQL::Types::String, null: true,
+ description: 'Description of the runner.'
field :edit_admin_url, GraphQL::Types::String, null: true,
description: 'Admin form URL of the runner. Only available for administrators.'
field :executor_name, GraphQL::Types::String, null: true,
@@ -72,12 +38,46 @@ module Types
feature_flag: :graphql_ci_runner_executor
field :groups, ::Types::GroupType.connection_type, null: true,
description: 'Groups the runner is associated with. For group runners only.'
- field :projects, ::Types::ProjectType.connection_type, null: true,
- description: 'Projects the runner is associated with. For project runners only.'
+ field :id, ::Types::GlobalIDType[::Ci::Runner], null: false,
+ description: 'ID of the runner.'
+ field :ip_address, GraphQL::Types::String, null: true,
+ description: 'IP address of the runner.'
+ field :job_count, GraphQL::Types::Int, null: true,
+ description: "Number of jobs processed by the runner (limited to #{JOB_COUNT_LIMIT}, plus one to indicate that more items exist)."
field :jobs, ::Types::Ci::JobType.connection_type, null: true,
description: 'Jobs assigned to the runner.',
authorize: :read_builds,
resolver: ::Resolvers::Ci::RunnerJobsResolver
+ field :locked, GraphQL::Types::Boolean, null: true,
+ description: 'Indicates the runner is locked.'
+ field :maximum_timeout, GraphQL::Types::Int, null: true,
+ description: 'Maximum timeout (in seconds) for jobs processed by the runner.'
+ field :paused, GraphQL::Types::Boolean, null: false,
+ description: 'Indicates the runner is paused and not available to run jobs.'
+ field :project_count, GraphQL::Types::Int, null: true,
+ description: 'Number of projects that the runner is associated with.'
+ field :projects, ::Types::ProjectType.connection_type, null: true,
+ description: 'Projects the runner is associated with. For project runners only.'
+ field :revision, GraphQL::Types::String, null: true,
+ description: 'Revision of the runner.'
+ field :run_untagged, GraphQL::Types::Boolean, null: false,
+ description: 'Indicates the runner is able to run untagged jobs.'
+ field :runner_type, ::Types::Ci::RunnerTypeEnum, null: false,
+ description: 'Type of the runner.'
+ field :short_sha, GraphQL::Types::String, null: true,
+ description: %q(First eight characters of the runner's token used to authenticate new job requests. Used as the runner's unique ID.)
+ field :status,
+ Types::Ci::RunnerStatusEnum,
+ null: false,
+ description: 'Status of the runner.',
+ resolver: ::Resolvers::Ci::RunnerStatusResolver
+ field :tag_list, [GraphQL::Types::String], null: true,
+ description: 'Tags associated with the runner.'
+ field :token_expires_at, Types::TimeType, null: true,
+ description: 'Runner token expiration time.',
+ method: :token_expires_at
+ field :version, GraphQL::Types::String, null: true,
+ description: 'Version of the runner.'
def job_count
# We limit to 1 above the JOB_COUNT_LIMIT to indicate that more items exist after JOB_COUNT_LIMIT
diff --git a/app/graphql/types/ci/runner_web_url_edge.rb b/app/graphql/types/ci/runner_web_url_edge.rb
index 368e16f972c..035d75c22c6 100644
--- a/app/graphql/types/ci/runner_web_url_edge.rb
+++ b/app/graphql/types/ci/runner_web_url_edge.rb
@@ -6,6 +6,9 @@ module Types
class RunnerWebUrlEdge < ::Types::BaseEdge
include FindClosest
+ field :edit_url, GraphQL::Types::String, null: true,
+ description: 'Web URL of the runner edit page. The value depends on where you put this field in the query. You can use it for projects or groups.',
+ extras: [:parent]
field :web_url, GraphQL::Types::String, null: true,
description: 'Web URL of the runner. The value depends on where you put this field in the query. You can use it for projects or groups.',
extras: [:parent]
@@ -16,14 +19,26 @@ module Types
@runner = node.node
end
+ def edit_url(parent:)
+ runner_url(parent: parent, url_type: :edit_url)
+ end
+
def web_url(parent:)
+ runner_url(parent: parent, url_type: :default)
+ end
+
+ private
+
+ def runner_url(parent:, url_type: :default)
owner = closest_parent([::Types::ProjectType, ::Types::GroupType], parent)
+ # Only ::Group is supported at the moment, future iterations will include ::Project.
+ # See https://gitlab.com/gitlab-org/gitlab/-/issues/16338
case owner
when ::Group
+ return Gitlab::Routing.url_helpers.edit_group_runner_url(owner, @runner) if url_type == :edit_url
+
Gitlab::Routing.url_helpers.group_runner_url(owner, @runner)
- when ::Project
- Gitlab::Routing.url_helpers.project_runner_url(owner, @runner)
end
end
end
diff --git a/app/graphql/types/ci/stage_type.rb b/app/graphql/types/ci/stage_type.rb
index 70e78e391a7..dcb3092d15a 100644
--- a/app/graphql/types/ci/stage_type.rb
+++ b/app/graphql/types/ci/stage_type.rb
@@ -6,17 +6,17 @@ module Types
graphql_name 'CiStage'
authorize :read_build
- field :id, GraphQL::Types::ID, null: false,
- description: 'ID of the stage.'
- field :name, type: GraphQL::Types::String, null: true,
- description: 'Name of the stage.'
+ field :detailed_status, Types::Ci::DetailedStatusType, null: true,
+ description: 'Detailed status of the stage.'
field :groups, type: Ci::GroupType.connection_type, null: true,
extras: [:lookahead],
description: 'Group of jobs for the stage.'
- field :detailed_status, Types::Ci::DetailedStatusType, null: true,
- description: 'Detailed status of the stage.'
+ field :id, GraphQL::Types::ID, null: false,
+ description: 'ID of the stage.'
field :jobs, Types::Ci::JobType.connection_type, null: true,
description: 'Jobs for the stage.'
+ field :name, type: GraphQL::Types::String, null: true,
+ description: 'Name of the stage.'
field :status, GraphQL::Types::String,
null: true,
description: 'Status of the pipeline stage.'
diff --git a/app/graphql/types/ci/status_action_type.rb b/app/graphql/types/ci/status_action_type.rb
index 15e5344e130..26ca3c1438a 100644
--- a/app/graphql/types/ci/status_action_type.rb
+++ b/app/graphql/types/ci/status_action_type.rb
@@ -5,13 +5,13 @@ module Types
class StatusActionType < BaseObject
graphql_name 'StatusAction'
- field :id, GraphQL::Types::String, null: false,
- description: 'ID for a status action.',
- extras: [:parent]
field :button_title, GraphQL::Types::String, null: true,
description: 'Title for the button, for example: Retry this job.'
field :icon, GraphQL::Types::String, null: true,
description: 'Icon used in the action button.'
+ field :id, GraphQL::Types::String, null: false,
+ description: 'ID for a status action.',
+ extras: [:parent]
field :method, GraphQL::Types::String, null: true,
description: 'Method for the action, for example: :post.',
resolver_method: :action_method
diff --git a/app/graphql/types/ci/template_type.rb b/app/graphql/types/ci/template_type.rb
index 7e7ee44025f..4f1ec6436de 100644
--- a/app/graphql/types/ci/template_type.rb
+++ b/app/graphql/types/ci/template_type.rb
@@ -7,10 +7,10 @@ module Types
graphql_name 'CiTemplate'
description 'GitLab CI/CD configuration template.'
- field :name, GraphQL::Types::String, null: false,
- description: 'Name of the CI template.'
field :content, GraphQL::Types::String, null: false,
description: 'Contents of the CI template.'
+ field :name, GraphQL::Types::String, null: false,
+ description: 'Name of the CI template.'
end
end
end
diff --git a/app/graphql/types/commit_action_type.rb b/app/graphql/types/commit_action_type.rb
index 6f6d6a418dc..1aa3a4e7ee1 100644
--- a/app/graphql/types/commit_action_type.rb
+++ b/app/graphql/types/commit_action_type.rb
@@ -4,17 +4,17 @@ module Types
class CommitActionType < BaseInputObject
argument :action, type: Types::CommitActionModeEnum, required: true,
description: 'Action to perform: create, delete, move, update, or chmod.'
- argument :file_path, type: GraphQL::Types::String, required: true,
- description: 'Full path to the file.'
argument :content, type: GraphQL::Types::String, required: false,
description: 'Content of the file.'
- argument :previous_path, type: GraphQL::Types::String, required: false,
- description: 'Original full path to the file being moved.'
- argument :last_commit_id, type: GraphQL::Types::String, required: false,
- description: 'Last known file commit ID.'
- argument :execute_filemode, type: GraphQL::Types::Boolean, 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.'
+ argument :execute_filemode, type: GraphQL::Types::Boolean, required: false,
+ description: 'Enables/disables the execute flag on the file.'
+ argument :file_path, type: GraphQL::Types::String, required: true,
+ description: 'Full path to the file.'
+ argument :last_commit_id, type: GraphQL::Types::String, required: false,
+ description: 'Last known file commit ID.'
+ argument :previous_path, type: GraphQL::Types::String, required: false,
+ description: 'Original full path to the file being moved.'
end
end
diff --git a/app/graphql/types/commit_type.rb b/app/graphql/types/commit_type.rb
index 8bc00359ccb..c3a6d6f7faa 100644
--- a/app/graphql/types/commit_type.rb
+++ b/app/graphql/types/commit_type.rb
@@ -8,6 +8,8 @@ module Types
present_using CommitPresenter
+ implements(Types::TodoableInterface)
+
field :id, type: GraphQL::Types::ID, null: false,
description: 'ID (global ID) of the commit.'
@@ -41,12 +43,12 @@ module Types
field :signature_html, type: GraphQL::Types::String, null: true, calls_gitaly: true,
description: 'Rendered HTML of the commit signature.'
- field :author_name, type: GraphQL::Types::String, null: true,
- description: 'Commit authors name.'
field :author_email, type: GraphQL::Types::String, null: true,
description: "Commit author's email."
field :author_gravatar, type: GraphQL::Types::String, null: true,
description: 'Commit authors gravatar.'
+ field :author_name, type: GraphQL::Types::String, null: true,
+ description: 'Commit authors name.'
# models/commit lazy loads the author by email
field :author, type: Types::UserType, null: true,
diff --git a/app/graphql/types/container_expiration_policy_type.rb b/app/graphql/types/container_expiration_policy_type.rb
index 6d6df21fe3f..0e9534be684 100644
--- a/app/graphql/types/container_expiration_policy_type.rb
+++ b/app/graphql/types/container_expiration_policy_type.rb
@@ -8,14 +8,14 @@ module Types
authorize :destroy_container_image
+ field :cadence, Types::ContainerExpirationPolicyCadenceEnum, null: false, description: 'This container expiration policy schedule.'
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::Types::Boolean, 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, Types::UntrustedRegexp, null: true, description: 'Tags with names matching this regex pattern will expire.'
field :name_regex_keep, Types::UntrustedRegexp, 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.'
+ field :older_than, Types::ContainerExpirationPolicyOlderThanEnum, null: true, description: 'Tags older that this will expire.'
+ field :updated_at, Types::TimeType, null: false, description: 'Timestamp of when the container expiration policy was updated.'
end
end
diff --git a/app/graphql/types/container_repository_details_type.rb b/app/graphql/types/container_repository_details_type.rb
index e713aaebe36..1ee9e76a1c8 100644
--- a/app/graphql/types/container_repository_details_type.rb
+++ b/app/graphql/types/container_repository_details_type.rb
@@ -15,8 +15,19 @@ module Types
max_page_size: 20,
resolver: Resolvers::ContainerRepositoryTagsResolver
+ field :size,
+ GraphQL::Types::Float,
+ null: true,
+ description: 'Deduplicated size of the image repository in bytes. This is only available on GitLab.com for repositories created after `2021-11-04`.'
+
def can_delete
Ability.allowed?(current_user, :destroy_container_image, object)
end
+
+ def size
+ object.size
+ rescue Faraday::Error
+ raise ::Gitlab::Graphql::Errors::ResourceNotAvailable, "Can't connect to the Container Registry. If this error persists, please review the troubleshooting documentation."
+ end
end
end
diff --git a/app/graphql/types/container_repository_tag_type.rb b/app/graphql/types/container_repository_tag_type.rb
index 206d6a3426c..d9665175449 100644
--- a/app/graphql/types/container_repository_tag_type.rb
+++ b/app/graphql/types/container_repository_tag_type.rb
@@ -8,15 +8,15 @@ module Types
authorize :read_container_image
+ field :can_delete, GraphQL::Types::Boolean, null: false, description: 'Can the current user delete this tag.'
+ field :created_at, Types::TimeType, null: true, description: 'Timestamp when the tag was created.'
+ field :digest, GraphQL::Types::String, null: true, description: 'Digest of the tag.'
+ field :location, GraphQL::Types::String, null: false, description: 'URL of the tag.'
field :name, GraphQL::Types::String, null: false, description: 'Name of the tag.'
field :path, GraphQL::Types::String, null: false, description: 'Path of the tag.'
- field :location, GraphQL::Types::String, null: false, description: 'URL of the tag.'
- field :digest, GraphQL::Types::String, null: true, description: 'Digest of the tag.'
field :revision, GraphQL::Types::String, null: true, description: 'Revision of the tag.'
field :short_revision, GraphQL::Types::String, null: true, description: 'Short revision of the tag.'
field :total_size, GraphQL::Types::BigInt, null: true, description: 'Size of the tag.'
- field :created_at, Types::TimeType, null: true, description: 'Timestamp when the tag was created.'
- field :can_delete, GraphQL::Types::Boolean, null: false, description: 'Can the current user delete this tag.'
def can_delete
Ability.allowed?(current_user, :destroy_container_image, object)
diff --git a/app/graphql/types/container_repository_type.rb b/app/graphql/types/container_repository_type.rb
index 1fe5cf112f0..3cd3730010b 100644
--- a/app/graphql/types/container_repository_type.rb
+++ b/app/graphql/types/container_repository_type.rb
@@ -8,18 +8,18 @@ module Types
authorize :read_container_image
+ field :can_delete, GraphQL::Types::Boolean, null: false, description: 'Can the current user delete the container repository.'
+ field :created_at, Types::TimeType, null: false, description: 'Timestamp when the container repository was created.'
+ field :expiration_policy_cleanup_status, Types::ContainerRepositoryCleanupStatusEnum, null: true, description: 'Tags cleanup status for the container repository.'
+ field :expiration_policy_started_at, Types::TimeType, null: true, description: 'Timestamp when the cleanup done by the expiration policy was started on the container repository.'
field :id, GraphQL::Types::ID, null: false, description: 'ID of the container repository.'
+ field :location, GraphQL::Types::String, null: false, description: 'URL of the container repository.'
field :name, GraphQL::Types::String, null: false, description: 'Name of the container repository.'
field :path, GraphQL::Types::String, null: false, description: 'Path of the container repository.'
- field :location, GraphQL::Types::String, null: false, description: 'URL of the container repository.'
- field :created_at, Types::TimeType, null: false, description: 'Timestamp when the container repository was created.'
- field :updated_at, Types::TimeType, null: false, description: 'Timestamp when the container repository was updated.'
- field :expiration_policy_started_at, Types::TimeType, null: true, description: 'Timestamp when the cleanup done by the expiration policy was started on the container repository.'
- field :expiration_policy_cleanup_status, Types::ContainerRepositoryCleanupStatusEnum, null: true, description: 'Tags cleanup status for the container repository.'
+ field :project, Types::ProjectType, null: false, description: 'Project of the container registry.'
field :status, Types::ContainerRepositoryStatusEnum, null: true, description: 'Status of the container repository.'
field :tags_count, GraphQL::Types::Int, null: false, description: 'Number of tags associated with this image.'
- field :can_delete, GraphQL::Types::Boolean, null: false, description: 'Can the current user delete the container repository.'
- field :project, Types::ProjectType, null: false, description: 'Project of the container registry.'
+ field :updated_at, Types::TimeType, null: false, description: 'Timestamp when the container repository was updated.'
def can_delete
Ability.allowed?(current_user, :update_container_image, object)
diff --git a/app/graphql/types/dependency_proxy/blob_type.rb b/app/graphql/types/dependency_proxy/blob_type.rb
index f5a78fbb3ba..b5cebe516aa 100644
--- a/app/graphql/types/dependency_proxy/blob_type.rb
+++ b/app/graphql/types/dependency_proxy/blob_type.rb
@@ -9,8 +9,8 @@ module Types
authorize :read_dependency_proxy
field :created_at, Types::TimeType, null: false, description: 'Date of creation.'
- field :updated_at, Types::TimeType, null: false, description: 'Date of most recent update.'
field :file_name, GraphQL::Types::String, null: false, description: 'Name of the blob.'
field :size, GraphQL::Types::String, null: false, description: 'Size of the blob file.'
+ field :updated_at, Types::TimeType, null: false, description: 'Date of most recent update.'
end
end
diff --git a/app/graphql/types/dependency_proxy/image_ttl_group_policy_type.rb b/app/graphql/types/dependency_proxy/image_ttl_group_policy_type.rb
index 29bba7122d0..9ab7c50998d 100644
--- a/app/graphql/types/dependency_proxy/image_ttl_group_policy_type.rb
+++ b/app/graphql/types/dependency_proxy/image_ttl_group_policy_type.rb
@@ -8,9 +8,9 @@ module Types
authorize :read_dependency_proxy
+ field :created_at, Types::TimeType, null: true, description: 'Timestamp of creation.'
field :enabled, GraphQL::Types::Boolean, null: false, description: 'Indicates whether the policy is enabled or disabled.'
field :ttl, GraphQL::Types::Int, null: true, description: 'Number of days to retain a cached image file.'
- field :created_at, Types::TimeType, null: true, description: 'Timestamp of creation.'
field :updated_at, Types::TimeType, null: true, description: 'Timestamp of the most recent update.'
end
end
diff --git a/app/graphql/types/dependency_proxy/manifest_type.rb b/app/graphql/types/dependency_proxy/manifest_type.rb
index ef9f730df43..ab22f540f48 100644
--- a/app/graphql/types/dependency_proxy/manifest_type.rb
+++ b/app/graphql/types/dependency_proxy/manifest_type.rb
@@ -8,13 +8,13 @@ module Types
authorize :read_dependency_proxy
- field :id, ::Types::GlobalIDType[::DependencyProxy::Manifest], null: false, description: 'ID of the manifest.'
field :created_at, Types::TimeType, null: false, description: 'Date of creation.'
- field :updated_at, Types::TimeType, null: false, description: 'Date of most recent update.'
+ field :digest, GraphQL::Types::String, null: false, description: 'Digest of the manifest.'
field :file_name, GraphQL::Types::String, null: false, description: 'Name of the manifest.'
+ field :id, ::Types::GlobalIDType[::DependencyProxy::Manifest], null: false, description: 'ID of the manifest.'
field :image_name, GraphQL::Types::String, null: false, description: 'Name of the image.'
field :size, GraphQL::Types::String, null: false, description: 'Size of the manifest file.'
- field :digest, GraphQL::Types::String, null: false, description: 'Digest of the manifest.'
+ field :updated_at, Types::TimeType, null: false, description: 'Date of most recent update.'
def image_name
object.file_name.chomp(File.extname(object.file_name))
diff --git a/app/graphql/types/design_management/design_collection_type.rb b/app/graphql/types/design_management/design_collection_type.rb
index 570eac907f3..91978aa37b0 100644
--- a/app/graphql/types/design_management/design_collection_type.rb
+++ b/app/graphql/types/design_management/design_collection_type.rb
@@ -8,10 +8,10 @@ module Types
authorize :read_design
- field :project, Types::ProjectType, null: false,
- description: 'Project associated with the design collection.'
field :issue, Types::IssueType, null: false,
description: 'Issue associated with the design collection.'
+ field :project, Types::ProjectType, null: false,
+ description: 'Project associated with the design collection.'
field :designs,
Types::DesignManagement::DesignType.connection_type,
diff --git a/app/graphql/types/design_management/design_fields.rb b/app/graphql/types/design_management/design_fields.rb
index 75f1aaa8c60..364f72a519f 100644
--- a/app/graphql/types/design_management/design_fields.rb
+++ b/app/graphql/types/design_management/design_fields.rb
@@ -62,7 +62,7 @@ module Types
def cached_actions_for_version(version)
Gitlab::SafeRequestStore.fetch(['DesignFields', 'actions_for_version', version.id]) do
- version.actions.to_h { |dv| [dv.design_id, dv] }
+ version.actions.index_by(&:design_id)
end
end
diff --git a/app/graphql/types/design_management/design_type.rb b/app/graphql/types/design_management/design_type.rb
index 2f40bf5ebfd..4c0b1162306 100644
--- a/app/graphql/types/design_management/design_type.rb
+++ b/app/graphql/types/design_management/design_type.rb
@@ -13,6 +13,12 @@ module Types
implements(Types::Notes::NoteableInterface)
implements(Types::DesignManagement::DesignFields)
implements(Types::CurrentUserTodos)
+ implements(Types::TodoableInterface)
+
+ field :web_url,
+ GraphQL::Types::String,
+ null: false,
+ description: 'URL of the design.'
field :versions,
Types::DesignManagement::VersionType.connection_type,
@@ -40,6 +46,10 @@ module Types
def request_cache_base_key
self.class.name
end
+
+ def web_url
+ Gitlab::UrlBuilder.build(object)
+ end
end
end
end
diff --git a/app/graphql/types/diff_paths_input_type.rb b/app/graphql/types/diff_paths_input_type.rb
index cdcff1a7e34..c5c75105fda 100644
--- a/app/graphql/types/diff_paths_input_type.rb
+++ b/app/graphql/types/diff_paths_input_type.rb
@@ -2,9 +2,9 @@
module Types
class DiffPathsInputType < BaseInputObject
- argument :old_path, GraphQL::Types::String, required: false,
- description: 'Path of the file on the start SHA.'
argument :new_path, GraphQL::Types::String, required: false,
description: 'Path of the file on the HEAD SHA.'
+ argument :old_path, GraphQL::Types::String, required: false,
+ description: 'Path of the file on the start SHA.'
end
end
diff --git a/app/graphql/types/diff_refs_type.rb b/app/graphql/types/diff_refs_type.rb
index b19d09c789c..a03d72a4dc2 100644
--- a/app/graphql/types/diff_refs_type.rb
+++ b/app/graphql/types/diff_refs_type.rb
@@ -6,10 +6,10 @@ module Types
class DiffRefsType < BaseObject
graphql_name 'DiffRefs'
- field :head_sha, GraphQL::Types::String, null: false,
- description: 'SHA of the HEAD at the time the comment was made.'
field :base_sha, GraphQL::Types::String, null: true,
description: 'Merge base of the branch the comment was made on.'
+ field :head_sha, GraphQL::Types::String, null: false,
+ description: 'SHA of the HEAD at the time the comment was made.'
field :start_sha, GraphQL::Types::String, null: false,
description: 'SHA of the branch being compared against.'
end
diff --git a/app/graphql/types/diff_stats_summary_type.rb b/app/graphql/types/diff_stats_summary_type.rb
index 079c73d0759..95705ddecf3 100644
--- a/app/graphql/types/diff_stats_summary_type.rb
+++ b/app/graphql/types/diff_stats_summary_type.rb
@@ -10,10 +10,10 @@ module Types
field :additions, GraphQL::Types::Int, null: false,
description: 'Number of lines added.'
- field :deletions, GraphQL::Types::Int, null: false,
- description: 'Number of lines deleted.'
field :changes, GraphQL::Types::Int, null: false,
description: 'Number of lines changed.'
+ field :deletions, GraphQL::Types::Int, null: false,
+ description: 'Number of lines deleted.'
field :file_count, GraphQL::Types::Int, null: false,
description: 'Number of files changed.'
diff --git a/app/graphql/types/diff_stats_type.rb b/app/graphql/types/diff_stats_type.rb
index 60aacca8ce5..da366fec8c3 100644
--- a/app/graphql/types/diff_stats_type.rb
+++ b/app/graphql/types/diff_stats_type.rb
@@ -8,12 +8,12 @@ module Types
description 'Changes to a single file'
- field :path, GraphQL::Types::String, null: false,
- description: 'File path, relative to repository root.'
field :additions, GraphQL::Types::Int, null: false,
description: 'Number of lines added to this file.'
field :deletions, GraphQL::Types::Int, null: false,
description: 'Number of lines deleted from this file.'
+ field :path, GraphQL::Types::String, null: false,
+ description: 'File path, relative to repository root.'
end
# rubocop: enable Graphql/AuthorizeTypes
end
diff --git a/app/graphql/types/error_tracking/sentry_detailed_error_type.rb b/app/graphql/types/error_tracking/sentry_detailed_error_type.rb
index 826ae61a1a3..b19ab80f96d 100644
--- a/app/graphql/types/error_tracking/sentry_detailed_error_type.rb
+++ b/app/graphql/types/error_tracking/sentry_detailed_error_type.rb
@@ -10,46 +10,68 @@ module Types
authorize :read_sentry_issue
- field :id, GraphQL::Types::ID,
- null: false,
- description: 'ID (global ID) of the error.'
- field :integrated, GraphQL::Types::Boolean,
- null: true,
- description: 'Error tracking backend.'
- field :sentry_id, GraphQL::Types::String,
- method: :id,
- null: false,
- description: 'ID (Sentry ID) of the error.'
- field :title, GraphQL::Types::String,
+ field :count, GraphQL::Types::Int,
null: false,
- description: 'Title of the error.'
- field :type, GraphQL::Types::String,
+ description: 'Count of occurrences.'
+ field :culprit, GraphQL::Types::String,
null: false,
- description: 'Type of the error.'
- field :user_count, GraphQL::Types::Int,
+ description: 'Culprit of the error.'
+ field :external_base_url, GraphQL::Types::String,
null: false,
- description: 'Count of users affected by the error.'
- field :count, GraphQL::Types::Int,
+ description: 'External Base URL of the Sentry Instance.'
+ field :external_url, GraphQL::Types::String,
null: false,
- description: 'Count of occurrences.'
+ description: 'External URL of the error.'
+ field :first_release_last_commit, GraphQL::Types::String,
+ null: true,
+ description: 'Commit the error was first seen.'
+ field :first_release_short_version, GraphQL::Types::String,
+ null: true,
+ description: 'Release short version the error was first seen.'
+ field :first_release_version, GraphQL::Types::String,
+ null: true,
+ description: 'Release version the error was first seen.'
field :first_seen, Types::TimeType,
null: false,
description: 'Timestamp when the error was first seen.'
+ field :frequency, [Types::ErrorTracking::SentryErrorFrequencyType],
+ null: false,
+ description: 'Last 24hr stats of the error.'
+ field :gitlab_commit, GraphQL::Types::String,
+ null: true,
+ description: 'GitLab commit SHA attributed to the Error based on the release version.'
+ field :gitlab_commit_path, GraphQL::Types::String,
+ null: true,
+ description: 'Path to the GitLab page for the GitLab commit attributed to the error.'
+ field :gitlab_issue_path, GraphQL::Types::String,
+ method: :gitlab_issue,
+ null: true,
+ description: 'URL of GitLab Issue.'
+ field :id, GraphQL::Types::ID,
+ null: false,
+ description: 'ID (global ID) of the error.'
+ field :integrated, GraphQL::Types::Boolean,
+ null: true,
+ description: 'Error tracking backend.'
+ field :last_release_last_commit, GraphQL::Types::String,
+ null: true,
+ description: 'Commit the error was last seen.'
+ field :last_release_short_version, GraphQL::Types::String,
+ null: true,
+ description: 'Release short version the error was last seen.'
+ field :last_release_version, GraphQL::Types::String,
+ null: true,
+ description: 'Release version the error was last seen.'
field :last_seen, Types::TimeType,
null: false,
description: 'Timestamp when the error was last seen.'
field :message, GraphQL::Types::String,
null: true,
description: 'Sentry metadata message of the error.'
- field :culprit, GraphQL::Types::String,
- null: false,
- description: 'Culprit of the error.'
- field :external_base_url, GraphQL::Types::String,
- null: false,
- description: 'External Base URL of the Sentry Instance.'
- field :external_url, GraphQL::Types::String,
+ field :sentry_id, GraphQL::Types::String,
+ method: :id,
null: false,
- description: 'External URL of the error.'
+ description: 'ID (Sentry ID) of the error.'
field :sentry_project_id, GraphQL::Types::ID,
method: :project_id,
null: false,
@@ -68,40 +90,18 @@ module Types
field :status, Types::ErrorTracking::SentryErrorStatusEnum,
null: false,
description: 'Status of the error.'
- field :frequency, [Types::ErrorTracking::SentryErrorFrequencyType],
- null: false,
- description: 'Last 24hr stats of the error.'
- field :first_release_last_commit, GraphQL::Types::String,
- null: true,
- description: 'Commit the error was first seen.'
- field :last_release_last_commit, GraphQL::Types::String,
- null: true,
- description: 'Commit the error was last seen.'
- field :first_release_short_version, GraphQL::Types::String,
- null: true,
- description: 'Release short version the error was first seen.'
- field :last_release_short_version, GraphQL::Types::String,
- null: true,
- description: 'Release short version the error was last seen.'
- field :first_release_version, GraphQL::Types::String,
- null: true,
- description: 'Release version the error was first seen.'
- field :last_release_version, GraphQL::Types::String,
- null: true,
- description: 'Release version the error was last seen.'
- field :gitlab_commit, GraphQL::Types::String,
- null: true,
- description: 'GitLab commit SHA attributed to the Error based on the release version.'
- field :gitlab_commit_path, GraphQL::Types::String,
- null: true,
- description: 'Path to the GitLab page for the GitLab commit attributed to the error.'
- field :gitlab_issue_path, GraphQL::Types::String,
- method: :gitlab_issue,
- null: true,
- description: 'URL of GitLab Issue.'
field :tags, Types::ErrorTracking::SentryErrorTagsType,
null: false,
description: 'Tags associated with the Sentry Error.'
+ field :title, GraphQL::Types::String,
+ null: false,
+ description: 'Title of the error.'
+ field :type, GraphQL::Types::String,
+ null: false,
+ description: 'Type of the error.'
+ field :user_count, GraphQL::Types::Int,
+ null: false,
+ description: 'Count of users affected by the error.'
end
end
end
diff --git a/app/graphql/types/error_tracking/sentry_error_collection_type.rb b/app/graphql/types/error_tracking/sentry_error_collection_type.rb
index 2d8c3d3d326..9790560929b 100644
--- a/app/graphql/types/error_tracking/sentry_error_collection_type.rb
+++ b/app/graphql/types/error_tracking/sentry_error_collection_type.rb
@@ -8,15 +8,15 @@ module Types
authorize :read_sentry_issue
- field :errors,
- description: "Collection of Sentry Errors.",
- resolver: Resolvers::ErrorTracking::SentryErrorsResolver
field :detailed_error,
description: 'Detailed version of a Sentry error on the project.',
resolver: Resolvers::ErrorTracking::SentryDetailedErrorResolver
field :error_stack_trace,
description: 'Stack Trace of Sentry Error.',
resolver: Resolvers::ErrorTracking::SentryErrorStackTraceResolver
+ field :errors,
+ description: "Collection of Sentry Errors.",
+ resolver: Resolvers::ErrorTracking::SentryErrorsResolver
field :external_url,
GraphQL::Types::String,
null: true,
diff --git a/app/graphql/types/error_tracking/sentry_error_frequency_type.rb b/app/graphql/types/error_tracking/sentry_error_frequency_type.rb
index 49a1b1e0476..f67becb3774 100644
--- a/app/graphql/types/error_tracking/sentry_error_frequency_type.rb
+++ b/app/graphql/types/error_tracking/sentry_error_frequency_type.rb
@@ -6,12 +6,12 @@ module Types
class SentryErrorFrequencyType < ::Types::BaseObject
graphql_name 'SentryErrorFrequency'
- field :time, Types::TimeType,
- null: false,
- description: "Time the error frequency stats were recorded."
field :count, GraphQL::Types::Int,
null: false,
description: "Count of errors received since the previously recorded time."
+ field :time, Types::TimeType,
+ null: false,
+ description: "Time the error frequency stats were recorded."
end
# rubocop: enable Graphql/AuthorizeTypes
end
diff --git a/app/graphql/types/error_tracking/sentry_error_stack_trace_context_type.rb b/app/graphql/types/error_tracking/sentry_error_stack_trace_context_type.rb
index ad31854b30c..d4b806c4e1e 100644
--- a/app/graphql/types/error_tracking/sentry_error_stack_trace_context_type.rb
+++ b/app/graphql/types/error_tracking/sentry_error_stack_trace_context_type.rb
@@ -7,14 +7,14 @@ module Types
graphql_name 'SentryErrorStackTraceContext'
description 'An object context for a Sentry error stack trace'
- field :line,
- GraphQL::Types::Int,
- null: false,
- description: 'Line number of the context.'
field :code,
GraphQL::Types::String,
null: false,
description: 'Code number of the context.'
+ field :line,
+ GraphQL::Types::Int,
+ null: false,
+ description: 'Line number of the context.'
def line
object[0]
diff --git a/app/graphql/types/error_tracking/sentry_error_stack_trace_entry_type.rb b/app/graphql/types/error_tracking/sentry_error_stack_trace_entry_type.rb
index e8f78004569..c33baa06052 100644
--- a/app/graphql/types/error_tracking/sentry_error_stack_trace_entry_type.rb
+++ b/app/graphql/types/error_tracking/sentry_error_stack_trace_entry_type.rb
@@ -7,18 +7,18 @@ module Types
graphql_name 'SentryErrorStackTraceEntry'
description 'An object containing a stack trace entry for a Sentry error'
- field :function, GraphQL::Types::String,
+ field :col, GraphQL::Types::String,
null: true,
description: 'Function in which the Sentry error occurred.'
- field :col, GraphQL::Types::String,
+ field :file_name, GraphQL::Types::String,
+ null: true,
+ description: 'File in which the Sentry error occurred.'
+ field :function, GraphQL::Types::String,
null: true,
description: 'Function in which the Sentry error occurred.'
field :line, GraphQL::Types::String,
null: true,
description: 'Function in which the Sentry error occurred.'
- field :file_name, GraphQL::Types::String,
- null: true,
- description: 'File in which the Sentry error occurred.'
field :trace_context, [Types::ErrorTracking::SentryErrorStackTraceContextType],
null: true,
description: 'Context of the Sentry error.'
diff --git a/app/graphql/types/error_tracking/sentry_error_stack_trace_type.rb b/app/graphql/types/error_tracking/sentry_error_stack_trace_type.rb
index dff52d77109..5c7aecf16ee 100644
--- a/app/graphql/types/error_tracking/sentry_error_stack_trace_type.rb
+++ b/app/graphql/types/error_tracking/sentry_error_stack_trace_type.rb
@@ -8,12 +8,12 @@ module Types
authorize :read_sentry_issue
- field :issue_id, GraphQL::Types::String,
- null: false,
- description: 'ID of the Sentry error.'
field :date_received, GraphQL::Types::String,
null: false,
description: 'Time the stack trace was received by Sentry.'
+ field :issue_id, GraphQL::Types::String,
+ null: false,
+ description: 'ID of the Sentry error.'
field :stack_trace_entries, [Types::ErrorTracking::SentryErrorStackTraceEntryType],
null: false,
description: 'Stack trace entries for the Sentry error.'
diff --git a/app/graphql/types/error_tracking/sentry_error_type.rb b/app/graphql/types/error_tracking/sentry_error_type.rb
index aaa6cbfb28f..5f871155737 100644
--- a/app/graphql/types/error_tracking/sentry_error_type.rb
+++ b/app/graphql/types/error_tracking/sentry_error_type.rb
@@ -9,49 +9,34 @@ module Types
present_using SentryErrorPresenter
- field :id, GraphQL::Types::ID,
- null: false,
- description: 'ID (global ID) of the error.'
- field :sentry_id, GraphQL::Types::String,
- method: :id,
- null: false,
- description: 'ID (Sentry ID) of the error.'
- field :first_seen, Types::TimeType,
- null: false,
- description: 'Timestamp when the error was first seen.'
- field :last_seen, Types::TimeType,
- null: false,
- description: 'Timestamp when the error was last seen.'
- field :title, GraphQL::Types::String,
- null: false,
- description: 'Title of the error.'
- field :type, GraphQL::Types::String,
- null: false,
- description: 'Type of the error.'
- field :user_count, GraphQL::Types::Int,
- null: false,
- description: 'Count of users affected by the error.'
field :count, GraphQL::Types::Int,
null: false,
description: 'Count of occurrences.'
- field :message, GraphQL::Types::String,
- null: true,
- description: 'Sentry metadata message of the error.'
field :culprit, GraphQL::Types::String,
null: false,
description: 'Culprit of the error.'
field :external_url, GraphQL::Types::String,
null: false,
description: 'External URL of the error.'
- field :short_id, GraphQL::Types::String,
- null: false,
- description: 'Short ID (Sentry ID) of the error.'
- field :status, Types::ErrorTracking::SentryErrorStatusEnum,
+ field :first_seen, Types::TimeType,
null: false,
- description: 'Status of the error.'
+ description: 'Timestamp when the error was first seen.'
field :frequency, [Types::ErrorTracking::SentryErrorFrequencyType],
null: false,
description: 'Last 24hr stats of the error.'
+ field :id, GraphQL::Types::ID,
+ null: false,
+ description: 'ID (global ID) of the error.'
+ field :last_seen, Types::TimeType,
+ null: false,
+ description: 'Timestamp when the error was last seen.'
+ field :message, GraphQL::Types::String,
+ null: true,
+ description: 'Sentry metadata message of the error.'
+ field :sentry_id, GraphQL::Types::String,
+ method: :id,
+ null: false,
+ description: 'ID (Sentry ID) of the error.'
field :sentry_project_id, GraphQL::Types::ID,
method: :project_id,
null: false,
@@ -64,6 +49,21 @@ module Types
method: :project_slug,
null: false,
description: 'Slug of the project affected by the error.'
+ field :short_id, GraphQL::Types::String,
+ null: false,
+ description: 'Short ID (Sentry ID) of the error.'
+ field :status, Types::ErrorTracking::SentryErrorStatusEnum,
+ null: false,
+ description: 'Status of the error.'
+ field :title, GraphQL::Types::String,
+ null: false,
+ description: 'Title of the error.'
+ field :type, GraphQL::Types::String,
+ null: false,
+ description: 'Type of the error.'
+ field :user_count, GraphQL::Types::Int,
+ null: false,
+ description: 'Count of users affected by the error.'
end
# rubocop: enable Graphql/AuthorizeTypes
end
diff --git a/app/graphql/types/evidence_type.rb b/app/graphql/types/evidence_type.rb
index 33f46c712f1..ed644a4b2c6 100644
--- a/app/graphql/types/evidence_type.rb
+++ b/app/graphql/types/evidence_type.rb
@@ -9,13 +9,13 @@ module Types
present_using Releases::EvidencePresenter
+ field :collected_at, Types::TimeType, null: true,
+ description: 'Timestamp when the evidence was collected.'
+ field :filepath, GraphQL::Types::String, null: true,
+ description: 'URL from where the evidence can be downloaded.'
field :id, GraphQL::Types::ID, null: false,
description: 'ID of the evidence.'
field :sha, GraphQL::Types::String, null: true,
description: 'SHA1 ID of the evidence hash.'
- field :filepath, GraphQL::Types::String, 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/global_id_type.rb b/app/graphql/types/global_id_type.rb
index c44c268b43f..4f92b5e8cc2 100644
--- a/app/graphql/types/global_id_type.rb
+++ b/app/graphql/types/global_id_type.rb
@@ -49,7 +49,11 @@ module Types
# Construct a restricted type, that can only be inhabited by an ID of
# a given model class.
def self.[](model_class)
- @id_types ||= {}
+ @id_types ||= {
+ # WorkItem has a special class as we want to allow IssueID
+ # on WorkItemID while we transition into work items
+ ::WorkItem => ::Types::WorkItemIdType
+ }
@id_types[model_class] ||= Class.new(self) do
model_name = model_class.name
diff --git a/app/graphql/types/grafana_integration_type.rb b/app/graphql/types/grafana_integration_type.rb
index 26fefd51e08..2bbc0d34db6 100644
--- a/app/graphql/types/grafana_integration_type.rb
+++ b/app/graphql/types/grafana_integration_type.rb
@@ -6,14 +6,14 @@ module Types
authorize :admin_operations
- field :id, GraphQL::Types::ID, null: false,
- description: 'Internal ID of the Grafana integration.'
- field :grafana_url, GraphQL::Types::String, null: false,
- description: 'URL for the Grafana host for the Grafana integration.'
- field :enabled, GraphQL::Types::Boolean, null: false,
- description: 'Indicates whether Grafana integration is enabled.'
field :created_at, Types::TimeType, null: false,
description: 'Timestamp of the issue\'s creation.'
+ field :enabled, GraphQL::Types::Boolean, null: false,
+ description: 'Indicates whether Grafana integration is enabled.'
+ field :grafana_url, GraphQL::Types::String, null: false,
+ description: 'URL for the Grafana host for the Grafana integration.'
+ field :id, GraphQL::Types::ID, null: false,
+ description: 'Internal ID of the Grafana integration.'
field :updated_at, Types::TimeType, null: false,
description: 'Timestamp of the issue\'s last activity.'
end
diff --git a/app/graphql/types/group_member_type.rb b/app/graphql/types/group_member_type.rb
index d68abc11bba..18242f7b8b1 100644
--- a/app/graphql/types/group_member_type.rb
+++ b/app/graphql/types/group_member_type.rb
@@ -13,6 +13,10 @@ module Types
field :group, Types::GroupType, null: true,
description: 'Group that a User is a member of.'
+ field :notification_email,
+ resolver: Resolvers::GroupMembers::NotificationEmailResolver,
+ description: "Group notification email for User. Only availble for admins."
+
def group
Gitlab::Graphql::Loaders::BatchModelLoader.new(Group, object.source_id).find
end
diff --git a/app/graphql/types/group_type.rb b/app/graphql/types/group_type.rb
index 5f63aa20953..a94cd6fad20 100644
--- a/app/graphql/types/group_type.rb
+++ b/app/graphql/types/group_type.rb
@@ -209,8 +209,9 @@ module Types
field :work_item_types, Types::WorkItems::TypeType.connection_type,
resolver: Resolvers::WorkItems::TypesResolver,
- description: 'Work item types available to the group.',
- feature_flag: :work_items
+ description: 'Work item types available to the group.' \
+ ' Returns `null` if `work_items` feature flag is disabled.' \
+ ' This flag is disabled by default, because the feature is experimental and is subject to change without notice.'
def label(title:)
BatchLoader::GraphQL.for(title).batch(key: group) do |titles, loader, args|
diff --git a/app/graphql/types/issue_type.rb b/app/graphql/types/issue_type.rb
index ee57961ee4a..07450c38616 100644
--- a/app/graphql/types/issue_type.rb
+++ b/app/graphql/types/issue_type.rb
@@ -8,6 +8,7 @@ module Types
implements(Types::Notes::NoteableInterface)
implements(Types::CurrentUserTodos)
+ implements(Types::TodoableInterface)
authorize :read_issue
@@ -15,16 +16,16 @@ module Types
present_using IssuePresenter
+ field :description, GraphQL::Types::String, null: true,
+ description: 'Description of the issue.'
field :id, GraphQL::Types::ID, null: false,
description: "ID of the issue."
field :iid, GraphQL::Types::ID, null: false,
description: "Internal ID of the issue."
- field :title, GraphQL::Types::String, null: false,
- description: 'Title of the issue.'
- field :description, GraphQL::Types::String, null: true,
- description: 'Description of the issue.'
field :state, IssueStateEnum, null: false,
description: 'State of the issue.'
+ field :title, GraphQL::Types::String, null: false,
+ description: 'Title of the issue.'
field :reference, GraphQL::Types::String, null: false,
description: 'Internal reference of the issue. Returned in shortened format by default.',
@@ -47,52 +48,52 @@ module Types
field :milestone, Types::MilestoneType, null: true,
description: 'Milestone of the issue.'
- field :due_date, Types::TimeType, null: true,
- description: 'Due date of the issue.'
field :confidential, GraphQL::Types::Boolean, null: false,
description: 'Indicates the issue is confidential.'
+ field :discussion_locked, GraphQL::Types::Boolean, null: false,
+ description: 'Indicates discussion is locked on the issue.'
+ field :due_date, Types::TimeType, null: true,
+ description: 'Due date of the issue.'
field :hidden, GraphQL::Types::Boolean, null: true, resolver_method: :hidden?,
description: 'Indicates the issue is hidden because the author has been banned. ' \
'Will always return `null` if `ban_user_feature_flag` feature flag is disabled.'
- field :discussion_locked, GraphQL::Types::Boolean, null: false,
- description: 'Indicates discussion is locked on the issue.'
- field :upvotes, GraphQL::Types::Int, null: false,
- description: 'Number of upvotes the issue has received.'
field :downvotes, GraphQL::Types::Int, null: false,
description: 'Number of downvotes the issue has received.'
field :merge_requests_count, GraphQL::Types::Int, null: false,
description: 'Number of merge requests that close the issue on merge.',
resolver: Resolvers::MergeRequestsCountResolver
- field :user_notes_count, GraphQL::Types::Int, null: false,
- description: 'Number of user notes of the issue.',
- resolver: Resolvers::UserNotesCountResolver
+ field :relative_position, GraphQL::Types::Int, null: true,
+ description: 'Relative position of the issue (used for positioning in epic tree and issue boards).'
+ field :upvotes, GraphQL::Types::Int, null: false,
+ description: 'Number of upvotes the issue has received.'
field :user_discussions_count, GraphQL::Types::Int, null: false,
description: 'Number of user discussions in the issue.',
resolver: Resolvers::UserDiscussionsCountResolver
+ field :user_notes_count, GraphQL::Types::Int, null: false,
+ description: 'Number of user notes of the issue.',
+ resolver: Resolvers::UserNotesCountResolver
field :web_path, GraphQL::Types::String, null: false, method: :issue_path,
description: 'Web path of the issue.'
field :web_url, GraphQL::Types::String, null: false,
description: 'Web URL of the issue.'
- field :relative_position, GraphQL::Types::Int, null: true,
- description: 'Relative position of the issue (used for positioning in epic tree and issue boards).'
- field :participants, Types::UserType.connection_type, null: true, complexity: 5,
- description: 'List of participants in the issue.',
- resolver: Resolvers::Users::ParticipantsResolver
field :emails_disabled, GraphQL::Types::Boolean, null: false,
method: :project_emails_disabled?,
description: 'Indicates if a project has email notifications disabled: `true` if email notifications are disabled.'
+ field :human_time_estimate, GraphQL::Types::String, null: true,
+ description: 'Human-readable time estimate of the issue.'
+ field :human_total_time_spent, GraphQL::Types::String, null: true,
+ description: 'Human-readable total time reported as spent on the issue.'
+ field :participants, Types::UserType.connection_type, null: true, complexity: 5,
+ description: 'List of participants in the issue.',
+ resolver: Resolvers::Users::ParticipantsResolver
field :subscribed, GraphQL::Types::Boolean, method: :subscribed?, null: false, complexity: 5,
description: 'Indicates the currently logged in user is subscribed to the issue.'
field :time_estimate, GraphQL::Types::Int, null: false,
description: 'Time estimate of the issue.'
field :total_time_spent, GraphQL::Types::Int, null: false,
description: 'Total time reported as spent on the issue.'
- field :human_time_estimate, GraphQL::Types::String, null: true,
- description: 'Human-readable time estimate of the issue.'
- field :human_total_time_spent, GraphQL::Types::String, null: true,
- description: 'Human-readable total time reported as spent on the issue.'
field :closed_at, Types::TimeType, null: true,
description: 'Timestamp of when the issue was closed.'
diff --git a/app/graphql/types/issues/negated_issue_filter_input_type.rb b/app/graphql/types/issues/negated_issue_filter_input_type.rb
index 73e090a4802..fc39efd2493 100644
--- a/app/graphql/types/issues/negated_issue_filter_input_type.rb
+++ b/app/graphql/types/issues/negated_issue_filter_input_type.rb
@@ -5,6 +5,15 @@ module Types
class NegatedIssueFilterInputType < BaseInputObject
graphql_name 'NegatedIssueFilterInput'
+ argument :assignee_id, GraphQL::Types::String,
+ required: false,
+ description: 'ID of a user not assigned to the issues.'
+ argument :assignee_usernames, [GraphQL::Types::String],
+ required: false,
+ description: 'Usernames of users not assigned to the issue.'
+ argument :author_username, GraphQL::Types::String,
+ required: false,
+ description: "Username of a user who didn't author the issue."
argument :iids, [GraphQL::Types::String],
required: false,
description: 'List of IIDs of issues to exclude. For example, `[1, 2]`.'
@@ -14,24 +23,15 @@ module Types
argument :milestone_title, [GraphQL::Types::String],
required: false,
description: 'Milestone not applied to this issue.'
- argument :release_tag, [GraphQL::Types::String],
- required: false,
- description: "Release tag not associated with the issue's milestone. Ignored when parent is a group."
- argument :author_username, GraphQL::Types::String,
- required: false,
- description: "Username of a user who didn't author the issue."
- argument :assignee_usernames, [GraphQL::Types::String],
- required: false,
- description: 'Usernames of users not assigned to the issue.'
- argument :assignee_id, GraphQL::Types::String,
- required: false,
- description: 'ID of a user not assigned to the issues.'
argument :milestone_wildcard_id, ::Types::NegatedMilestoneWildcardIdEnum,
required: false,
description: 'Filter by negated milestone wildcard values.'
argument :my_reaction_emoji, GraphQL::Types::String,
required: false,
description: 'Filter by reaction emoji applied by the current user.'
+ argument :release_tag, [GraphQL::Types::String],
+ required: false,
+ description: "Release tag not associated with the issue's milestone. Ignored when parent is a group."
argument :types, [Types::IssueTypeEnum],
as: :issue_types,
description: 'Filters out issues by the given issue types.',
diff --git a/app/graphql/types/jira_import_type.rb b/app/graphql/types/jira_import_type.rb
index 0cdfc178350..8477f0b97f0 100644
--- a/app/graphql/types/jira_import_type.rb
+++ b/app/graphql/types/jira_import_type.rb
@@ -8,16 +8,16 @@ module Types
field :created_at, Types::TimeType, null: true,
description: 'Timestamp of when the Jira import was created.'
+ field :failed_to_import_count, GraphQL::Types::Int, null: false,
+ description: 'Count of issues that failed to import.'
+ field :imported_issues_count, GraphQL::Types::Int, null: false,
+ description: 'Count of issues that were successfully imported.'
+ field :jira_project_key, GraphQL::Types::String, null: false,
+ description: 'Project key for the imported Jira project.'
field :scheduled_at, Types::TimeType, null: true,
description: 'Timestamp of when the Jira import was scheduled.'
field :scheduled_by, Types::UserType, null: true,
description: 'User that started the Jira import.'
- field :jira_project_key, GraphQL::Types::String, null: false,
- description: 'Project key for the imported Jira project.'
- field :imported_issues_count, GraphQL::Types::Int, null: false,
- description: 'Count of issues that were successfully imported.'
- field :failed_to_import_count, GraphQL::Types::Int, null: false,
- description: 'Count of issues that failed to import.'
field :total_issue_count, GraphQL::Types::Int, null: false,
description: 'Total count of issues that were attempted to import.'
end
diff --git a/app/graphql/types/jira_user_type.rb b/app/graphql/types/jira_user_type.rb
index 6e1c349726c..aba05385ece 100644
--- a/app/graphql/types/jira_user_type.rb
+++ b/app/graphql/types/jira_user_type.rb
@@ -6,18 +6,18 @@ module Types
class JiraUserType < BaseObject
graphql_name 'JiraUser'
+ field :gitlab_id, GraphQL::Types::Int, null: true,
+ description: 'ID of the matched GitLab user.'
+ field :gitlab_name, GraphQL::Types::String, null: true,
+ description: 'Name of the matched GitLab user.'
+ field :gitlab_username, GraphQL::Types::String, null: true,
+ description: 'Username of the matched GitLab user.'
field :jira_account_id, GraphQL::Types::String, null: false,
description: 'Account ID of the Jira user.'
field :jira_display_name, GraphQL::Types::String, null: false,
description: 'Display name of the Jira user.'
field :jira_email, GraphQL::Types::String, null: true,
description: 'Email of the Jira user, returned only for users with public emails.'
- field :gitlab_id, GraphQL::Types::Int, null: true,
- description: 'ID of the matched GitLab user.'
- field :gitlab_username, GraphQL::Types::String, null: true,
- description: 'Username of the matched GitLab user.'
- field :gitlab_name, GraphQL::Types::String, null: true,
- description: 'Name of the matched GitLab user.'
end
# rubocop: enable Graphql/AuthorizeTypes
end
diff --git a/app/graphql/types/jira_users_mapping_input_type.rb b/app/graphql/types/jira_users_mapping_input_type.rb
index 37fd05370c0..4df2e27b45a 100644
--- a/app/graphql/types/jira_users_mapping_input_type.rb
+++ b/app/graphql/types/jira_users_mapping_input_type.rb
@@ -4,13 +4,13 @@ module Types
class JiraUsersMappingInputType < BaseInputObject
graphql_name 'JiraUsersMappingInputType'
- argument :jira_account_id,
- GraphQL::Types::String,
- required: true,
- description: 'Jira account ID of the user.'
argument :gitlab_id,
GraphQL::Types::Int,
required: false,
description: 'ID of the GitLab user.'
+ argument :jira_account_id,
+ GraphQL::Types::String,
+ required: true,
+ description: 'Jira account ID of the user.'
end
end
diff --git a/app/graphql/types/label_type.rb b/app/graphql/types/label_type.rb
index 5a10bcfee74..b5b3e20bcbc 100644
--- a/app/graphql/types/label_type.rb
+++ b/app/graphql/types/label_type.rb
@@ -8,18 +8,18 @@ module Types
authorize :read_label
- field :id, GraphQL::Types::ID, null: false,
- description: 'Label ID.'
- field :description, GraphQL::Types::String, null: true,
- description: 'Description of the label (Markdown rendered as HTML for caching).'
- field :title, GraphQL::Types::String, null: false,
- description: 'Content of the label.'
field :color, GraphQL::Types::String, null: false,
description: 'Background color of the label.'
- field :text_color, GraphQL::Types::String, null: false,
- description: 'Text color of the label.'
field :created_at, Types::TimeType, null: false,
description: 'When this label was created.'
+ field :description, GraphQL::Types::String, null: true,
+ description: 'Description of the label (Markdown rendered as HTML for caching).'
+ field :id, GraphQL::Types::ID, null: false,
+ description: 'Label ID.'
+ field :text_color, GraphQL::Types::String, null: false,
+ description: 'Text color of the label.'
+ field :title, GraphQL::Types::String, null: false,
+ description: 'Content of the label.'
field :updated_at, Types::TimeType, null: false,
description: 'When this label was last updated.'
diff --git a/app/graphql/types/merge_request_type.rb b/app/graphql/types/merge_request_type.rb
index ea05671c79c..af198d03c3f 100644
--- a/app/graphql/types/merge_request_type.rb
+++ b/app/graphql/types/merge_request_type.rb
@@ -8,6 +8,7 @@ module Types
implements(Types::Notes::NoteableInterface)
implements(Types::CurrentUserTodos)
+ implements(Types::TodoableInterface)
authorize :read_merge_request
@@ -15,94 +16,96 @@ module Types
present_using MergeRequestPresenter
+ field :created_at, Types::TimeType, null: false,
+ description: 'Timestamp of when the merge request was created.'
+ field :description, GraphQL::Types::String, null: true,
+ description: 'Description of the merge request (Markdown rendered as HTML for caching).'
+ field :diff_head_sha, GraphQL::Types::String, null: true,
+ description: 'Diff head SHA of the merge request.'
+ field :diff_refs, Types::DiffRefsType, null: true,
+ description: 'References of the base SHA, the head SHA, and the start SHA for this merge request.'
+ field :diff_stats, [Types::DiffStatsType], null: true, calls_gitaly: true,
+ description: 'Details about which files were changed in this merge request.' do
+ argument :path, GraphQL::Types::String, required: false, description: 'Specific file path.'
+ end
+ field :draft, GraphQL::Types::Boolean, method: :draft?, null: false,
+ description: 'Indicates if the merge request is a draft.'
field :id, GraphQL::Types::ID, null: false,
description: 'ID of the merge request.'
field :iid, GraphQL::Types::String, null: false,
description: 'Internal ID of the merge request.'
- field :title, GraphQL::Types::String, null: false,
- description: 'Title of the merge request.'
- field :description, GraphQL::Types::String, null: true,
- description: 'Description of the merge request (Markdown rendered as HTML for caching).'
- field :state, MergeRequestStateEnum, null: false,
- description: 'State of the merge request.'
- field :created_at, Types::TimeType, null: false,
- 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 :merge_when_pipeline_succeeds, GraphQL::Types::Boolean, null: true,
+ description: 'Indicates if the merge has been set to be merged when its pipeline succeeds (MWPS).'
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,
- description: 'Target project of the merge request.'
- field :diff_refs, Types::DiffRefsType, null: true,
- description: 'References of the base SHA, the head SHA, and the start SHA for this merge request.'
field :project, Types::ProjectType, null: false,
description: 'Alias for target_project.'
field :project_id, GraphQL::Types::Int, null: false, method: :target_project_id,
description: 'ID of the merge request project.'
- field :source_project_id, GraphQL::Types::Int, null: true,
- description: 'ID of the merge request source project.'
- field :target_project_id, GraphQL::Types::Int, null: false,
- description: 'ID of the merge request target project.'
field :source_branch, GraphQL::Types::String, null: false,
description: 'Source branch of the merge request.'
field :source_branch_protected, GraphQL::Types::Boolean, null: false, calls_gitaly: true,
description: 'Indicates if the source branch is protected.'
+ field :source_project, Types::ProjectType, null: true,
+ description: 'Source project of the merge request.'
+ field :source_project_id, GraphQL::Types::Int, null: true,
+ description: 'ID of the merge request source project.'
+ field :state, MergeRequestStateEnum, null: false,
+ description: 'State of the merge request.'
field :target_branch, GraphQL::Types::String, null: false,
description: 'Target branch of the merge request.'
- field :draft, GraphQL::Types::Boolean, method: :draft?, null: false,
- description: 'Indicates if the merge request is a draft.'
- field :merge_when_pipeline_succeeds, GraphQL::Types::Boolean, null: true,
- description: 'Indicates if the merge has been set to be merged when its pipeline succeeds (MWPS).'
- field :diff_head_sha, GraphQL::Types::String, null: true,
- description: 'Diff head SHA of the merge request.'
- field :diff_stats, [Types::DiffStatsType], null: true, calls_gitaly: true,
- description: 'Details about which files were changed in this merge request.' do
- argument :path, GraphQL::Types::String, required: false, description: 'Specific file path.'
- end
+ field :target_project, Types::ProjectType, null: false,
+ description: 'Target project of the merge request.'
+ field :target_project_id, GraphQL::Types::Int, null: false,
+ description: 'ID of the merge request target project.'
+ field :title, GraphQL::Types::String, null: false,
+ description: 'Title of the merge request.'
+ field :updated_at, Types::TimeType, null: false,
+ description: 'Timestamp of when the merge request was last updated.'
+ field :allow_collaboration, GraphQL::Types::Boolean, null: true,
+ description: 'Indicates if members of the target project can push to the fork.'
+ field :default_merge_commit_message, GraphQL::Types::String, null: true, calls_gitaly: true,
+ description: 'Default merge commit message of the merge request.'
+ field :default_merge_commit_message_with_description, GraphQL::Types::String, null: true,
+ description: 'Default merge commit message of the merge request with description. Will have the same value as `defaultMergeCommitMessage` when project has `mergeCommitTemplate` set.',
+ deprecated: { reason: 'Define merge commit template in project and use `defaultMergeCommitMessage`', milestone: '14.5' }
+ field :default_squash_commit_message, GraphQL::Types::String, null: true, calls_gitaly: true,
+ description: 'Default squash commit message of the merge request.'
field :diff_stats_summary, Types::DiffStatsSummaryType, null: true, calls_gitaly: true,
description: 'Summary of which files were changed in this merge request.'
- field :merge_commit_sha, GraphQL::Types::String, null: true,
- description: 'SHA of the merge request commit (set once merged).'
- field :user_notes_count, GraphQL::Types::Int, null: true,
- description: 'User notes count of the merge request.',
- resolver: Resolvers::UserNotesCountResolver
- field :user_discussions_count, GraphQL::Types::Int, null: true,
- description: 'Number of user discussions in the merge request.',
- resolver: Resolvers::UserDiscussionsCountResolver
- field :should_remove_source_branch, GraphQL::Types::Boolean, method: :should_remove_source_branch?, null: true,
- description: 'Indicates if the source branch of the merge request will be deleted after merge.'
+ field :diverged_from_target_branch, GraphQL::Types::Boolean,
+ null: false, calls_gitaly: true,
+ method: :diverged_from_target_branch?,
+ description: 'Indicates if the source branch is behind the target branch.'
+ field :downvotes, GraphQL::Types::Int, null: false,
+ description: 'Number of downvotes for the merge request.'
field :force_remove_source_branch, GraphQL::Types::Boolean, method: :force_remove_source_branch?, null: true,
description: 'Indicates if the project settings will lead to source branch deletion after merge.'
+ field :in_progress_merge_commit_sha, GraphQL::Types::String, null: true,
+ description: 'Commit SHA of the merge request if merge is in progress.'
+ field :merge_commit_sha, GraphQL::Types::String, null: true,
+ description: 'SHA of the merge request commit (set once merged).'
+ field :merge_error, GraphQL::Types::String, null: true,
+ description: 'Error message due to a merge error.'
+ field :merge_ongoing, GraphQL::Types::Boolean, method: :merge_ongoing?, null: false,
+ description: 'Indicates if a merge is currently occurring.'
field :merge_status, GraphQL::Types::String, method: :public_merge_status, null: true,
description: 'Status of the merge request.',
deprecated: { reason: :renamed, replacement: 'MergeRequest.mergeStatusEnum', milestone: '14.0' }
field :merge_status_enum, ::Types::MergeRequests::MergeStatusEnum,
method: :public_merge_status, null: true,
description: 'Merge status of the merge request.'
- field :in_progress_merge_commit_sha, GraphQL::Types::String, null: true,
- description: 'Commit SHA of the merge request if merge is in progress.'
- field :merge_error, GraphQL::Types::String, null: true,
- description: 'Error message due to a merge error.'
- field :allow_collaboration, GraphQL::Types::Boolean, null: true,
- description: 'Indicates if members of the target project can push to the fork.'
- field :should_be_rebased, GraphQL::Types::Boolean, method: :should_be_rebased?, null: false, calls_gitaly: true,
- description: 'Indicates if the merge request will be rebased.'
+ field :mergeable_discussions_state, GraphQL::Types::Boolean, null: true,
+ description: 'Indicates if all discussions in the merge request have been resolved, allowing the merge request to be merged.'
field :rebase_commit_sha, GraphQL::Types::String, null: true,
description: 'Rebase commit SHA of the merge request.'
field :rebase_in_progress, GraphQL::Types::Boolean, method: :rebase_in_progress?, null: false, calls_gitaly: true,
description: 'Indicates if there is a rebase currently in progress for the merge request.'
- field :default_merge_commit_message, GraphQL::Types::String, null: true, calls_gitaly: true,
- description: 'Default merge commit message of the merge request.'
- field :default_merge_commit_message_with_description, GraphQL::Types::String, null: true,
- description: 'Default merge commit message of the merge request with description. Will have the same value as `defaultMergeCommitMessage` when project has `mergeCommitTemplate` set.',
- deprecated: { reason: 'Define merge commit template in project and use `defaultMergeCommitMessage`', milestone: '14.5' }
- field :default_squash_commit_message, GraphQL::Types::String, null: true, calls_gitaly: true,
- description: 'Default squash commit message of the merge request.'
- field :merge_ongoing, GraphQL::Types::Boolean, method: :merge_ongoing?, null: false,
- description: 'Indicates if a merge is currently occurring.'
+ field :should_be_rebased, GraphQL::Types::Boolean, method: :should_be_rebased?, null: false, calls_gitaly: true,
+ description: 'Indicates if the merge request will be rebased.'
+ field :should_remove_source_branch, GraphQL::Types::Boolean, method: :should_remove_source_branch?, null: true,
+ description: 'Indicates if the source branch of the merge request will be deleted after merge.'
field :source_branch_exists, GraphQL::Types::Boolean,
null: false, calls_gitaly: true,
method: :source_branch_exists?,
@@ -111,18 +114,16 @@ module Types
null: false, calls_gitaly: true,
method: :target_branch_exists?,
description: 'Indicates if the target branch of the merge request exists.'
- field :diverged_from_target_branch, GraphQL::Types::Boolean,
- null: false, calls_gitaly: true,
- method: :diverged_from_target_branch?,
- description: 'Indicates if the source branch is behind the target branch.'
- field :mergeable_discussions_state, GraphQL::Types::Boolean, 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::Types::String, null: true,
- description: 'Web URL of the merge request.'
field :upvotes, GraphQL::Types::Int, null: false,
description: 'Number of upvotes for the merge request.'
- field :downvotes, GraphQL::Types::Int, null: false,
- description: 'Number of downvotes for the merge request.'
+ field :user_discussions_count, GraphQL::Types::Int, null: true,
+ description: 'Number of user discussions in the merge request.',
+ resolver: Resolvers::UserDiscussionsCountResolver
+ field :user_notes_count, GraphQL::Types::Int, null: true,
+ description: 'User notes count of the merge request.',
+ resolver: Resolvers::UserNotesCountResolver
+ field :web_url, GraphQL::Types::String, null: true,
+ description: 'Web URL of the merge request.'
field :head_pipeline, Types::Ci::PipelineType, null: true, method: :actual_head_pipeline,
description: 'Pipeline running on the branch HEAD of the merge request.'
@@ -131,84 +132,82 @@ module Types
description: 'Pipelines for the merge request. Note: for performance reasons, no more than the most recent 500 pipelines will be returned.',
resolver: Resolvers::MergeRequestPipelinesResolver
- field :milestone, Types::MilestoneType, null: true,
- description: 'Milestone of the merge request.'
field :assignees,
type: Types::MergeRequests::AssigneeType.connection_type,
null: true,
complexity: 5,
description: 'Assignees of the merge request.'
- field :reviewers,
- type: Types::MergeRequests::ReviewerType.connection_type,
- null: true,
- complexity: 5,
- description: 'Users from whom a review has been requested.'
- field :author, Types::UserType, null: true,
+ field :author, Types::MergeRequests::AuthorType, null: true,
description: 'User who created this merge request.'
- field :participants, Types::UserType.connection_type, null: true, complexity: 15,
- description: 'Participants in the merge request. This includes the author, assignees, reviewers, and users mentioned in notes.',
- resolver: Resolvers::Users::ParticipantsResolver
- field :subscribed, GraphQL::Types::Boolean, method: :subscribed?, null: false, complexity: 5,
- description: 'Indicates if the currently logged in user is subscribed to this merge request.'
- field :labels, Types::LabelType.connection_type, null: true, complexity: 5,
- description: 'Labels of the merge request.'
field :discussion_locked, GraphQL::Types::Boolean,
description: 'Indicates if comments on the merge request are locked to members only.',
null: false
- field :time_estimate, GraphQL::Types::Int, null: false,
- description: 'Time estimate of the merge request.'
- field :total_time_spent, GraphQL::Types::Int, null: false,
- description: 'Total time reported as spent on the merge request.'
field :human_time_estimate, GraphQL::Types::String, null: true,
description: 'Human-readable time estimate of the merge request.'
field :human_total_time_spent, GraphQL::Types::String, null: true,
description: 'Human-readable total time reported as spent on the merge request.'
+ field :labels, Types::LabelType.connection_type, null: true, complexity: 5,
+ description: 'Labels of the merge request.'
+ field :milestone, Types::MilestoneType, null: true,
+ description: 'Milestone of the merge request.'
+ field :participants, Types::MergeRequests::ParticipantType.connection_type, null: true, complexity: 15,
+ description: 'Participants in the merge request. This includes the author, assignees, reviewers, and users mentioned in notes.',
+ resolver: Resolvers::Users::ParticipantsResolver
field :reference, GraphQL::Types::String, null: false, method: :to_reference,
description: 'Internal reference of the merge request. Returned in shortened format by default.' do
argument :full, GraphQL::Types::Boolean, required: false, default_value: false,
description: 'Boolean option specifying whether the reference should be returned in full.'
end
- field :task_completion_status, Types::TaskCompletionStatus, null: false,
- description: Types::TaskCompletionStatus.description
+ field :auto_merge_enabled, GraphQL::Types::Boolean, null: false,
+ description: 'Indicates if auto merge is enabled for the merge request.'
field :commit_count, GraphQL::Types::Int, null: true, method: :commits_count,
description: 'Number of commits in the merge request.'
field :conflicts, GraphQL::Types::Boolean, null: false, method: :cannot_be_merged?,
description: 'Indicates if the merge request has conflicts.'
- field :auto_merge_enabled, GraphQL::Types::Boolean, null: false,
- description: 'Indicates if auto merge is enabled for the merge request.'
+ field :reviewers,
+ type: Types::MergeRequests::ReviewerType.connection_type,
+ null: true,
+ complexity: 5,
+ description: 'Users from whom a review has been requested.'
+ field :subscribed, GraphQL::Types::Boolean, method: :subscribed?, null: false, complexity: 5,
+ description: 'Indicates if the currently logged in user is subscribed to this merge request.'
+ field :task_completion_status, Types::TaskCompletionStatus, null: false,
+ description: Types::TaskCompletionStatus.description
+ field :time_estimate, GraphQL::Types::Int, null: false,
+ description: 'Time estimate of the merge request.'
+ field :total_time_spent, GraphQL::Types::Int, null: false,
+ description: 'Total time reported as spent on the merge request.'
field :approved_by, Types::UserType.connection_type, null: true,
- description: 'Users who approved the merge request.'
- field :squash_on_merge, GraphQL::Types::Boolean, null: false, method: :squash_on_merge?,
- description: 'Indicates if squash on merge is enabled.'
- field :squash, GraphQL::Types::Boolean, null: false,
- description: 'Indicates if squash on merge is enabled.'
+ description: 'Users who approved the merge request.', method: :approved_by_users
+ field :auto_merge_strategy, GraphQL::Types::String, null: true,
+ description: 'Selected auto merge strategy.'
field :available_auto_merge_strategies, [GraphQL::Types::String], null: true, calls_gitaly: true,
description: 'Array of available auto merge strategies.'
- field :has_ci, GraphQL::Types::Boolean, null: false, method: :has_ci?,
- description: 'Indicates if the merge request has CI.'
- field :mergeable, GraphQL::Types::Boolean, null: false, method: :mergeable?, calls_gitaly: true,
- description: 'Indicates if the merge request is mergeable.'
field :commits, Types::CommitType.connection_type, null: true,
calls_gitaly: true, description: 'Merge request commits.'
+ field :committers, Types::UserType.connection_type, null: true, complexity: 5,
+ calls_gitaly: true, description: 'Users who have added commits to the merge request.'
field :commits_without_merge_commits, Types::CommitType.connection_type, null: true,
calls_gitaly: true, description: 'Merge request commits excluding merge commits.'
- field :security_auto_fix, GraphQL::Types::Boolean, null: true,
- description: 'Indicates if the merge request is created by @GitLab-Security-Bot.'
- field :auto_merge_strategy, GraphQL::Types::String, null: true,
- description: 'Selected auto merge strategy.'
+ field :has_ci, GraphQL::Types::Boolean, null: false, method: :has_ci?,
+ description: 'Indicates if the merge request has CI.'
field :merge_user, Types::UserType, null: true,
description: 'User who merged this merge request or set it to merge when pipeline succeeds.'
+ field :mergeable, GraphQL::Types::Boolean, null: false, method: :mergeable?, calls_gitaly: true,
+ description: 'Indicates if the merge request is mergeable.'
+ field :security_auto_fix, GraphQL::Types::Boolean, null: true,
+ description: 'Indicates if the merge request is created by @GitLab-Security-Bot.'
+ field :squash, GraphQL::Types::Boolean, null: false,
+ description: 'Indicates if squash on merge is enabled.'
+ field :squash_on_merge, GraphQL::Types::Boolean, null: false, method: :squash_on_merge?,
+ description: 'Indicates if squash on merge is enabled.'
field :timelogs, Types::TimelogType.connection_type, null: false,
description: 'Timelogs on the merge request.'
markdown_field :title_html, null: true
markdown_field :description_html, null: true
- def approved_by
- object.approved_by_users
- end
-
def user_notes_count
BatchLoader::GraphQL.for(object.id).batch(key: :merge_request_user_notes_count) do |ids, loader, args|
counts = Note.count_for_collection(ids, 'MergeRequest').index_by(&:noteable_id)
@@ -279,10 +278,6 @@ module Types
object.author == User.security_bot
end
- def reviewers
- object.reviewers
- end
-
def merge_user
object.metrics&.merged_by || object.merge_user
end
diff --git a/app/graphql/types/merge_requests/assignee_type.rb b/app/graphql/types/merge_requests/assignee_type.rb
index 24321d057a3..a0ba74597ba 100644
--- a/app/graphql/types/merge_requests/assignee_type.rb
+++ b/app/graphql/types/merge_requests/assignee_type.rb
@@ -6,7 +6,6 @@ module Types
graphql_name 'MergeRequestAssignee'
description 'A user assigned to a merge request.'
- include FindClosest
include ::Types::MergeRequests::InteractsWithMergeRequest
authorize :read_user
diff --git a/app/graphql/types/merge_requests/author_type.rb b/app/graphql/types/merge_requests/author_type.rb
new file mode 100644
index 00000000000..56ad3190547
--- /dev/null
+++ b/app/graphql/types/merge_requests/author_type.rb
@@ -0,0 +1,14 @@
+# frozen_string_literal: true
+
+module Types
+ module MergeRequests
+ class AuthorType < ::Types::UserType
+ graphql_name 'MergeRequestAuthor'
+ description 'The author of the merge request.'
+
+ include ::Types::MergeRequests::InteractsWithMergeRequest
+
+ authorize :read_user
+ end
+ end
+end
diff --git a/app/graphql/types/merge_requests/participant_type.rb b/app/graphql/types/merge_requests/participant_type.rb
new file mode 100644
index 00000000000..86d627097b2
--- /dev/null
+++ b/app/graphql/types/merge_requests/participant_type.rb
@@ -0,0 +1,14 @@
+# frozen_string_literal: true
+
+module Types
+ module MergeRequests
+ class ParticipantType < ::Types::UserType
+ graphql_name 'MergeRequestParticipant'
+ description 'A user participating in a merge request.'
+
+ include ::Types::MergeRequests::InteractsWithMergeRequest
+
+ authorize :read_user
+ end
+ end
+end
diff --git a/app/graphql/types/merge_requests/reviewer_type.rb b/app/graphql/types/merge_requests/reviewer_type.rb
index 11f7ceaf461..e5bc5812816 100644
--- a/app/graphql/types/merge_requests/reviewer_type.rb
+++ b/app/graphql/types/merge_requests/reviewer_type.rb
@@ -6,7 +6,6 @@ module Types
graphql_name 'MergeRequestReviewer'
description 'A user assigned to a merge request as a reviewer.'
- include FindClosest
include ::Types::MergeRequests::InteractsWithMergeRequest
authorize :read_user
diff --git a/app/graphql/types/metadata/kas_type.rb b/app/graphql/types/metadata/kas_type.rb
index 54a8a6ec40d..6a8d54b6c7d 100644
--- a/app/graphql/types/metadata/kas_type.rb
+++ b/app/graphql/types/metadata/kas_type.rb
@@ -9,10 +9,10 @@ module Types
field :enabled, GraphQL::Types::Boolean, null: false,
description: 'Indicates whether the Kubernetes Agent Server is enabled.'
- field :version, GraphQL::Types::String, null: true,
- description: 'KAS version.'
field :external_url, GraphQL::Types::String, null: true,
description: 'URL used by the Agents to communicate with KAS.'
+ field :version, GraphQL::Types::String, null: true,
+ description: 'KAS version.'
end
end
end
diff --git a/app/graphql/types/metadata_type.rb b/app/graphql/types/metadata_type.rb
index ed1e697711d..6fb141a50c9 100644
--- a/app/graphql/types/metadata_type.rb
+++ b/app/graphql/types/metadata_type.rb
@@ -6,11 +6,11 @@ module Types
authorize :read_instance_metadata
- field :version, GraphQL::Types::String, null: false,
- description: 'Version.'
- field :revision, GraphQL::Types::String, null: false,
- description: 'Revision.'
field :kas, ::Types::Metadata::KasType, null: false,
description: 'Metadata about KAS.'
+ field :revision, GraphQL::Types::String, null: false,
+ description: 'Revision.'
+ field :version, GraphQL::Types::String, null: false,
+ description: 'Version.'
end
end
diff --git a/app/graphql/types/metrics/dashboards/annotation_type.rb b/app/graphql/types/metrics/dashboards/annotation_type.rb
index 0c787476f54..0621cf4d674 100644
--- a/app/graphql/types/metrics/dashboards/annotation_type.rb
+++ b/app/graphql/types/metrics/dashboards/annotation_type.rb
@@ -14,17 +14,14 @@ module Types
description: 'ID of the annotation.'
field :panel_id, GraphQL::Types::String, null: true,
- description: 'ID of a dashboard panel to which the annotation should be scoped.'
+ description: 'ID of a dashboard panel to which the annotation should be scoped.',
+ method: :panel_xid
field :starting_at, Types::TimeType, null: true,
description: 'Timestamp marking start of annotated time span.'
field :ending_at, Types::TimeType, null: true,
description: 'Timestamp marking end of annotated time span.'
-
- def panel_id
- object.panel_xid
- end
end
end
end
diff --git a/app/graphql/types/mutation_type.rb b/app/graphql/types/mutation_type.rb
index 3c735231595..e6072820eea 100644
--- a/app/graphql/types/mutation_type.rb
+++ b/app/graphql/types/mutation_type.rb
@@ -126,8 +126,11 @@ module Types
mount_mutation Mutations::Packages::DestroyFile
mount_mutation Mutations::Echo
mount_mutation Mutations::WorkItems::Create
+ mount_mutation Mutations::WorkItems::CreateFromTask
mount_mutation Mutations::WorkItems::Delete
mount_mutation Mutations::WorkItems::Update
+ mount_mutation Mutations::SavedReplies::Create
+ mount_mutation Mutations::SavedReplies::Update
end
end
diff --git a/app/graphql/types/namespace/package_settings_type.rb b/app/graphql/types/namespace/package_settings_type.rb
index d573cc9ded5..cb546bbf3ec 100644
--- a/app/graphql/types/namespace/package_settings_type.rb
+++ b/app/graphql/types/namespace/package_settings_type.rb
@@ -8,9 +8,9 @@ module Types
authorize :read_package_settings
- field :maven_duplicates_allowed, GraphQL::Types::Boolean, null: false, description: 'Indicates whether duplicate Maven packages are allowed for this namespace.'
- field :maven_duplicate_exception_regex, Types::UntrustedRegexp, null: true, description: 'When maven_duplicates_allowed is false, you can publish duplicate packages with names that match this regex. Otherwise, this setting has no effect.'
- field :generic_duplicates_allowed, GraphQL::Types::Boolean, null: false, description: 'Indicates whether duplicate generic packages are allowed for this namespace.'
field :generic_duplicate_exception_regex, Types::UntrustedRegexp, null: true, description: 'When generic_duplicates_allowed is false, you can publish duplicate packages with names that match this regex. Otherwise, this setting has no effect.'
+ field :generic_duplicates_allowed, GraphQL::Types::Boolean, null: false, description: 'Indicates whether duplicate generic packages are allowed for this namespace.'
+ field :maven_duplicate_exception_regex, Types::UntrustedRegexp, null: true, description: 'When maven_duplicates_allowed is false, you can publish duplicate packages with names that match this regex. Otherwise, this setting has no effect.'
+ field :maven_duplicates_allowed, GraphQL::Types::Boolean, null: false, description: 'Indicates whether duplicate Maven packages are allowed for this namespace.'
end
end
diff --git a/app/graphql/types/namespace_type.rb b/app/graphql/types/namespace_type.rb
index ba90fb06cb2..de6a078c6ef 100644
--- a/app/graphql/types/namespace_type.rb
+++ b/app/graphql/types/namespace_type.rb
@@ -9,24 +9,28 @@ module Types
field :id, GraphQL::Types::ID, null: false,
description: 'ID of the namespace.'
- field :name, GraphQL::Types::String, null: false,
- description: 'Name of the namespace.'
- field :path, GraphQL::Types::String, null: false,
- description: 'Path of the namespace.'
field :full_name, GraphQL::Types::String, null: false,
description: 'Full name of the namespace.'
field :full_path, GraphQL::Types::ID, null: false,
description: 'Full path of the namespace.'
+ field :name, GraphQL::Types::String, null: false,
+ description: 'Name of the namespace.'
+ field :path, GraphQL::Types::String, null: false,
+ description: 'Path of the namespace.'
+
+ field :cross_project_pipeline_available, GraphQL::Types::Boolean, null: false,
+ resolver_method: :cross_project_pipeline_available?,
+ description: 'Indicates if the cross_project_pipeline feature is available for the namespace.'
field :description, GraphQL::Types::String, null: true,
description: 'Description of the namespace.'
- field :visibility, GraphQL::Types::String, null: true,
- description: 'Visibility of the namespace.'
field :lfs_enabled, GraphQL::Types::Boolean, null: true, method: :lfs_enabled?,
description: 'Indicates if Large File Storage (LFS) is enabled for namespace.'
field :request_access_enabled, GraphQL::Types::Boolean, null: true,
description: 'Indicates if users can request access to namespace.'
+ field :visibility, GraphQL::Types::String, null: true,
+ description: 'Visibility of the namespace.'
field :root_storage_statistics, Types::RootStorageStatisticsType,
null: true,
@@ -48,6 +52,10 @@ module Types
markdown_field :description_html, null: true
+ def cross_project_pipeline_available?
+ object.licensed_feature_available?(:cross_project_pipelines)
+ end
+
def root_storage_statistics
Gitlab::Graphql::Loaders::BatchRootStorageStatisticsLoader.new(object.id).find
end
diff --git a/app/graphql/types/notes/diff_image_position_input_type.rb b/app/graphql/types/notes/diff_image_position_input_type.rb
index d56c67bbec8..d535dea2e07 100644
--- a/app/graphql/types/notes/diff_image_position_input_type.rb
+++ b/app/graphql/types/notes/diff_image_position_input_type.rb
@@ -5,14 +5,14 @@ module Types
class DiffImagePositionInputType < DiffPositionBaseInputType
graphql_name 'DiffImagePositionInput'
+ argument :height, GraphQL::Types::Int, required: true,
+ description: copy_field_description(Types::Notes::DiffPositionType, :height)
+ argument :width, GraphQL::Types::Int, required: true,
+ description: copy_field_description(Types::Notes::DiffPositionType, :width)
argument :x, GraphQL::Types::Int, required: true,
description: copy_field_description(Types::Notes::DiffPositionType, :x)
argument :y, GraphQL::Types::Int, required: true,
description: copy_field_description(Types::Notes::DiffPositionType, :y)
- argument :width, GraphQL::Types::Int, required: true,
- description: copy_field_description(Types::Notes::DiffPositionType, :width)
- argument :height, GraphQL::Types::Int, required: true,
- description: copy_field_description(Types::Notes::DiffPositionType, :height)
end
end
end
diff --git a/app/graphql/types/notes/diff_position_base_input_type.rb b/app/graphql/types/notes/diff_position_base_input_type.rb
index e773fbbc8a1..2780dbab573 100644
--- a/app/graphql/types/notes/diff_position_base_input_type.rb
+++ b/app/graphql/types/notes/diff_position_base_input_type.rb
@@ -3,10 +3,10 @@
module Types
module Notes
class DiffPositionBaseInputType < BaseInputObject
+ argument :base_sha, GraphQL::Types::String, required: false,
+ description: copy_field_description(Types::DiffRefsType, :base_sha)
argument :head_sha, GraphQL::Types::String, required: true,
description: copy_field_description(Types::DiffRefsType, :head_sha)
- argument :base_sha, GraphQL::Types::String, required: false,
- description: copy_field_description(Types::DiffRefsType, :base_sha)
argument :start_sha, GraphQL::Types::String, required: true,
description: copy_field_description(Types::DiffRefsType, :start_sha)
diff --git a/app/graphql/types/notes/diff_position_input_type.rb b/app/graphql/types/notes/diff_position_input_type.rb
index 18ce6672d14..ccde4188f29 100644
--- a/app/graphql/types/notes/diff_position_input_type.rb
+++ b/app/graphql/types/notes/diff_position_input_type.rb
@@ -5,10 +5,10 @@ module Types
class DiffPositionInputType < DiffPositionBaseInputType
graphql_name 'DiffPositionInput'
- argument :old_line, GraphQL::Types::Int, required: false,
- description: copy_field_description(Types::Notes::DiffPositionType, :old_line)
argument :new_line, GraphQL::Types::Int, required: false,
- description: copy_field_description(Types::Notes::DiffPositionType, :new_line)
+ description: "#{copy_field_description(Types::Notes::DiffPositionType, :new_line)} Please see the [REST API Documentation](https://docs.gitlab.com/ee/api/discussions.html#create-a-new-thread-in-the-merge-request-diff) for more information on how to use this field."
+ argument :old_line, GraphQL::Types::Int, required: false,
+ description: "#{copy_field_description(Types::Notes::DiffPositionType, :old_line)} Please see the [REST API Documentation](https://docs.gitlab.com/ee/api/discussions.html#create-a-new-thread-in-the-merge-request-diff) for more information on how to use this field."
end
end
end
diff --git a/app/graphql/types/notes/diff_position_type.rb b/app/graphql/types/notes/diff_position_type.rb
index 9c756d56b97..531bd0edac0 100644
--- a/app/graphql/types/notes/diff_position_type.rb
+++ b/app/graphql/types/notes/diff_position_type.rb
@@ -12,28 +12,28 @@ module Types
field :file_path, GraphQL::Types::String, null: false,
description: 'Path of the file that was changed.'
- field :old_path, GraphQL::Types::String, null: true,
- description: 'Path of the file on the start SHA.'
field :new_path, GraphQL::Types::String, null: true,
description: 'Path of the file on the HEAD SHA.'
+ field :old_path, GraphQL::Types::String, null: true,
+ description: 'Path of the file on the start SHA.'
field :position_type, Types::Notes::PositionTypeEnum, null: false,
description: 'Type of file the position refers to.'
# Fields for text positions
- field :old_line, GraphQL::Types::Int, null: true,
- description: 'Line on start SHA that was changed.'
field :new_line, GraphQL::Types::Int, null: true,
description: 'Line on HEAD SHA that was changed.'
+ field :old_line, GraphQL::Types::Int, null: true,
+ description: 'Line on start SHA that was changed.'
# Fields for image positions
+ field :height, GraphQL::Types::Int, null: true,
+ description: 'Total height of the image.'
+ field :width, GraphQL::Types::Int, null: true,
+ description: 'Total width of the image.'
field :x, GraphQL::Types::Int, null: true,
description: 'X position of the note.'
field :y, GraphQL::Types::Int, null: true,
description: 'Y position of the note.'
- field :width, GraphQL::Types::Int, null: true,
- description: 'Total width of the image.'
- field :height, GraphQL::Types::Int, null: true,
- description: 'Total height of the image.'
def old_line
object.old_line if object.on_text?
diff --git a/app/graphql/types/notes/discussion_type.rb b/app/graphql/types/notes/discussion_type.rb
index ffe61c9ff88..89778b2a99a 100644
--- a/app/graphql/types/notes/discussion_type.rb
+++ b/app/graphql/types/notes/discussion_type.rb
@@ -11,16 +11,16 @@ module Types
implements(Types::ResolvableInterface)
- field :id, DiscussionID, null: false,
- description: "ID of this discussion."
- field :reply_id, DiscussionID, null: false,
- description: 'ID used to reply to this discussion.'
field :created_at, Types::TimeType, null: false,
description: "Timestamp of the discussion's creation."
- field :notes, Types::Notes::NoteType.connection_type, null: false,
- description: 'All notes in the discussion.'
+ field :id, DiscussionID, null: false,
+ description: "ID of this discussion."
field :noteable, Types::NoteableType, null: true,
description: 'Object which the discussion belongs to.'
+ field :notes, Types::Notes::NoteType.connection_type, null: false,
+ description: 'All notes in the discussion.'
+ field :reply_id, DiscussionID, null: false,
+ description: 'ID used to reply to this discussion.'
# DiscussionID.coerce_result is suitable here, but will always mark this
# as being a 'Discussion'. Using `GlobalId.build` guarantees that we get
diff --git a/app/graphql/types/notes/note_type.rb b/app/graphql/types/notes/note_type.rb
index 7314c137010..32f3ff7f556 100644
--- a/app/graphql/types/notes/note_type.rb
+++ b/app/graphql/types/notes/note_type.rb
@@ -33,17 +33,17 @@ module Types
method: :note,
description: 'Content of the note.'
+ field :confidential, GraphQL::Types::Boolean, null: true,
+ description: 'Indicates if this note is confidential.',
+ method: :confidential?
field :created_at, Types::TimeType, null: false,
description: 'Timestamp of the note creation.'
- field :updated_at, Types::TimeType, null: false,
- description: "Timestamp of the note's last activity."
field :discussion, Types::Notes::DiscussionType, null: true,
description: 'Discussion this note is a part of.'
field :position, Types::Notes::DiffPositionType, null: true,
description: 'Position of this note on a diff.'
- field :confidential, GraphQL::Types::Boolean, null: true,
- description: 'Indicates if this note is confidential.',
- method: :confidential?
+ field :updated_at, Types::TimeType, null: false,
+ description: "Timestamp of the note's last activity."
field :url, GraphQL::Types::String,
null: true,
description: 'URL to view this Note in the Web UI.'
diff --git a/app/graphql/types/packages/composer/json_type.rb b/app/graphql/types/packages/composer/json_type.rb
index 6c121043301..84f08adb021 100644
--- a/app/graphql/types/packages/composer/json_type.rb
+++ b/app/graphql/types/packages/composer/json_type.rb
@@ -8,9 +8,9 @@ module Types
graphql_name 'PackageComposerJsonType'
description 'Represents a composer JSON file'
+ field :license, GraphQL::Types::String, null: true, description: 'License set in the Composer JSON file.'
field :name, GraphQL::Types::String, null: true, description: 'Name set in the Composer JSON file.'
field :type, GraphQL::Types::String, null: true, description: 'Type set in the Composer JSON file.'
- field :license, GraphQL::Types::String, null: true, description: 'License set in the Composer JSON file.'
field :version, GraphQL::Types::String, null: true, description: 'Version set in the Composer JSON file.'
end
end
diff --git a/app/graphql/types/packages/composer/metadatum_type.rb b/app/graphql/types/packages/composer/metadatum_type.rb
index 092e729ec56..d28ee87b878 100644
--- a/app/graphql/types/packages/composer/metadatum_type.rb
+++ b/app/graphql/types/packages/composer/metadatum_type.rb
@@ -9,8 +9,8 @@ module Types
authorize :read_package
- field :target_sha, GraphQL::Types::String, null: false, description: 'Target SHA of the package.'
field :composer_json, Types::Packages::Composer::JsonType, null: false, description: 'Data of the Composer JSON file.'
+ field :target_sha, GraphQL::Types::String, null: false, description: 'Target SHA of the package.'
end
end
end
diff --git a/app/graphql/types/packages/conan/file_metadatum_type.rb b/app/graphql/types/packages/conan/file_metadatum_type.rb
index 9a26fd5de51..012e03ece8f 100644
--- a/app/graphql/types/packages/conan/file_metadatum_type.rb
+++ b/app/graphql/types/packages/conan/file_metadatum_type.rb
@@ -11,11 +11,11 @@ module Types
authorize :read_package
+ field :conan_file_type, ::Types::Packages::Conan::MetadatumFileTypeEnum, null: false, description: 'Type of the Conan file.'
+ field :conan_package_reference, GraphQL::Types::String, null: true, description: 'Reference of the Conan package.'
field :id, ::Types::GlobalIDType[::Packages::Conan::FileMetadatum], null: false, description: 'ID of the metadatum.'
- field :recipe_revision, GraphQL::Types::String, null: false, description: 'Revision of the Conan recipe.'
field :package_revision, GraphQL::Types::String, null: true, description: 'Revision of the package.'
- field :conan_package_reference, GraphQL::Types::String, null: true, description: 'Reference of the Conan package.'
- field :conan_file_type, ::Types::Packages::Conan::MetadatumFileTypeEnum, null: false, description: 'Type of the Conan file.'
+ field :recipe_revision, GraphQL::Types::String, null: false, description: 'Revision of the Conan recipe.'
end
end
end
diff --git a/app/graphql/types/packages/conan/metadatum_type.rb b/app/graphql/types/packages/conan/metadatum_type.rb
index cdfd0aa4483..d410d6d6d33 100644
--- a/app/graphql/types/packages/conan/metadatum_type.rb
+++ b/app/graphql/types/packages/conan/metadatum_type.rb
@@ -9,13 +9,13 @@ module Types
authorize :read_package
- field :id, ::Types::GlobalIDType[::Packages::Conan::Metadatum], null: false, description: 'ID of the metadatum.'
field :created_at, Types::TimeType, null: false, description: 'Date of creation.'
- field :updated_at, Types::TimeType, null: false, description: 'Date of most recent update.'
- field :package_username, GraphQL::Types::String, null: false, description: 'Username of the Conan package.'
+ field :id, ::Types::GlobalIDType[::Packages::Conan::Metadatum], null: false, description: 'ID of the metadatum.'
field :package_channel, GraphQL::Types::String, null: false, description: 'Channel of the Conan package.'
+ field :package_username, GraphQL::Types::String, null: false, description: 'Username of the Conan package.'
field :recipe, GraphQL::Types::String, null: false, description: 'Recipe of the Conan package.'
field :recipe_path, GraphQL::Types::String, null: false, description: 'Recipe path of the Conan package.'
+ field :updated_at, Types::TimeType, null: false, description: 'Date of most recent update.'
end
end
end
diff --git a/app/graphql/types/packages/helm/dependency_type.rb b/app/graphql/types/packages/helm/dependency_type.rb
index 35598c2b1d7..72a47d0af51 100644
--- a/app/graphql/types/packages/helm/dependency_type.rb
+++ b/app/graphql/types/packages/helm/dependency_type.rb
@@ -9,14 +9,14 @@ module Types
description 'Represents a Helm dependency'
# Need to be synced with app/validators/json_schemas/helm_metadata.json#dependencies
- field :name, GraphQL::Types::String, null: true, description: 'Name of the dependency.'
- field :version, GraphQL::Types::String, null: true, description: 'Version of the dependency.'
- field :repository, GraphQL::Types::String, null: true, description: 'Repository of the dependency.'
+ field :alias, GraphQL::Types::String, null: true, description: 'Alias of the dependency.', resolver_method: :resolve_alias
field :condition, GraphQL::Types::String, null: true, description: 'Condition of the dependency.'
- field :tags, [GraphQL::Types::String], null: true, description: 'Tags of the dependency.'
field :enabled, GraphQL::Types::Boolean, null: true, description: 'Indicates the dependency is enabled.'
field :import_values, [GraphQL::Types::JSON], null: true, description: 'Import-values of the dependency.', hash_key: "import-values" # rubocop:disable Graphql/JSONType
- field :alias, GraphQL::Types::String, null: true, description: 'Alias of the dependency.', resolver_method: :resolve_alias
+ field :name, GraphQL::Types::String, null: true, description: 'Name of the dependency.'
+ field :repository, GraphQL::Types::String, null: true, description: 'Repository of the dependency.'
+ field :tags, [GraphQL::Types::String], null: true, description: 'Tags of the dependency.'
+ field :version, GraphQL::Types::String, null: true, description: 'Version of the dependency.'
# field :alias` conflicts with a built-in method
def resolve_alias
diff --git a/app/graphql/types/packages/helm/maintainer_type.rb b/app/graphql/types/packages/helm/maintainer_type.rb
index 6d25a26c46b..e029ff6fd94 100644
--- a/app/graphql/types/packages/helm/maintainer_type.rb
+++ b/app/graphql/types/packages/helm/maintainer_type.rb
@@ -9,8 +9,8 @@ module Types
description 'Represents a Helm maintainer'
# Need to be synced with app/validators/json_schemas/helm_metadata.json#maintainers
- field :name, GraphQL::Types::String, null: true, description: 'Name of the maintainer.'
field :email, GraphQL::Types::String, null: true, description: 'Email of the maintainer.'
+ field :name, GraphQL::Types::String, null: true, description: 'Name of the maintainer.'
field :url, GraphQL::Types::String, null: true, description: 'URL of the maintainer.'
end
end
diff --git a/app/graphql/types/packages/helm/metadata_type.rb b/app/graphql/types/packages/helm/metadata_type.rb
index eeb3e8087a8..ccc5a3029cd 100644
--- a/app/graphql/types/packages/helm/metadata_type.rb
+++ b/app/graphql/types/packages/helm/metadata_type.rb
@@ -9,23 +9,23 @@ module Types
description 'Represents the contents of a Helm Chart.yml file'
# Need to be synced with app/validators/json_schemas/helm_metadata.json
- field :name, GraphQL::Types::String, null: false, description: 'Name of the chart.'
- field :home, GraphQL::Types::String, null: true, description: 'URL of the home page.'
- field :sources, [GraphQL::Types::String], null: true, description: 'URLs of the source code for the chart.'
- field :version, GraphQL::Types::String, null: false, description: 'Version of the chart.'
- field :description, GraphQL::Types::String, null: true, description: 'Description of the chart.'
- field :keywords, [GraphQL::Types::String], null: true, description: 'Keywords for the chart.'
- field :maintainers, [Types::Packages::Helm::MaintainerType], null: true, description: 'Maintainers of the chart.'
- field :icon, GraphQL::Types::String, null: true, description: 'URL to an SVG or PNG image for the chart.'
+ field :annotations, GraphQL::Types::JSON, null: true, description: 'Annotations for the chart.' # rubocop:disable Graphql/JSONType
field :api_version, GraphQL::Types::String, null: false, description: 'API version of the chart.', hash_key: "apiVersion"
- field :condition, GraphQL::Types::String, null: true, description: 'Condition for the chart.'
- field :tags, GraphQL::Types::String, null: true, description: 'Tags for the chart.'
field :app_version, GraphQL::Types::String, null: true, description: 'App version of the chart.', hash_key: "appVersion"
+ field :condition, GraphQL::Types::String, null: true, description: 'Condition for the chart.'
+ field :dependencies, [Types::Packages::Helm::DependencyType], null: true, description: 'Dependencies of the chart.'
field :deprecated, GraphQL::Types::Boolean, null: true, description: 'Indicates if the chart is deprecated.'
- field :annotations, GraphQL::Types::JSON, null: true, description: 'Annotations for the chart.' # rubocop:disable Graphql/JSONType
+ field :description, GraphQL::Types::String, null: true, description: 'Description of the chart.'
+ field :home, GraphQL::Types::String, null: true, description: 'URL of the home page.'
+ field :icon, GraphQL::Types::String, null: true, description: 'URL to an SVG or PNG image for the chart.'
+ field :keywords, [GraphQL::Types::String], null: true, description: 'Keywords for the chart.'
field :kube_version, GraphQL::Types::String, null: true, description: 'Kubernetes versions for the chart.', hash_key: "kubeVersion"
- field :dependencies, [Types::Packages::Helm::DependencyType], null: true, description: 'Dependencies of the chart.'
+ field :maintainers, [Types::Packages::Helm::MaintainerType], null: true, description: 'Maintainers of the chart.'
+ field :name, GraphQL::Types::String, null: false, description: 'Name of the chart.'
+ field :sources, [GraphQL::Types::String], null: true, description: 'URLs of the source code for the chart.'
+ field :tags, GraphQL::Types::String, null: true, description: 'Tags for the chart.'
field :type, GraphQL::Types::String, null: true, description: 'Type of the chart.', hash_key: "appVersion"
+ field :version, GraphQL::Types::String, null: false, description: 'Version of the chart.'
end
end
end
diff --git a/app/graphql/types/packages/maven/metadatum_type.rb b/app/graphql/types/packages/maven/metadatum_type.rb
index eb3829648d1..b59f5235d7b 100644
--- a/app/graphql/types/packages/maven/metadatum_type.rb
+++ b/app/graphql/types/packages/maven/metadatum_type.rb
@@ -9,13 +9,13 @@ module Types
authorize :read_package
- field :id, ::Types::GlobalIDType[::Packages::Maven::Metadatum], null: false, description: 'ID of the metadatum.'
- field :created_at, Types::TimeType, null: false, description: 'Date of creation.'
- field :updated_at, Types::TimeType, null: false, description: 'Date of most recent update.'
- field :path, GraphQL::Types::String, null: false, description: 'Path of the Maven package.'
field :app_group, GraphQL::Types::String, null: false, description: 'App group of the Maven package.'
- field :app_version, GraphQL::Types::String, null: true, description: 'App version of the Maven package.'
field :app_name, GraphQL::Types::String, null: false, description: 'App name of the Maven package.'
+ field :app_version, GraphQL::Types::String, null: true, description: 'App version of the Maven package.'
+ field :created_at, Types::TimeType, null: false, description: 'Date of creation.'
+ field :id, ::Types::GlobalIDType[::Packages::Maven::Metadatum], null: false, description: 'ID of the metadatum.'
+ field :path, GraphQL::Types::String, null: false, description: 'Path of the Maven package.'
+ field :updated_at, Types::TimeType, null: false, description: 'Date of most recent update.'
end
end
end
diff --git a/app/graphql/types/packages/nuget/metadatum_type.rb b/app/graphql/types/packages/nuget/metadatum_type.rb
index b58fd954a74..fd9f1039d3c 100644
--- a/app/graphql/types/packages/nuget/metadatum_type.rb
+++ b/app/graphql/types/packages/nuget/metadatum_type.rb
@@ -9,10 +9,10 @@ module Types
authorize :read_package
+ field :icon_url, GraphQL::Types::String, null: true, description: 'Icon URL of the Nuget package.'
field :id, ::Types::GlobalIDType[::Packages::Nuget::Metadatum], null: false, description: 'ID of the metadatum.'
field :license_url, GraphQL::Types::String, null: true, description: 'License URL of the Nuget package.'
field :project_url, GraphQL::Types::String, null: true, description: 'Project URL of the Nuget package.'
- field :icon_url, GraphQL::Types::String, null: true, description: 'Icon URL of the Nuget package.'
end
end
end
diff --git a/app/graphql/types/packages/package_dependency_link_type.rb b/app/graphql/types/packages/package_dependency_link_type.rb
index eceb8319748..8b1d4abf3ba 100644
--- a/app/graphql/types/packages/package_dependency_link_type.rb
+++ b/app/graphql/types/packages/package_dependency_link_type.rb
@@ -7,9 +7,9 @@ module Types
description 'Represents a package dependency link'
authorize :read_package
- field :id, ::Types::GlobalIDType[::Packages::DependencyLink], null: false, description: 'ID of the dependency link.'
- field :dependency_type, Types::Packages::PackageDependencyTypeEnum, null: false, description: 'Dependency type.'
field :dependency, Types::Packages::PackageDependencyType, null: true, description: 'Dependency.'
+ field :dependency_type, Types::Packages::PackageDependencyTypeEnum, null: false, description: 'Dependency type.'
+ field :id, ::Types::GlobalIDType[::Packages::DependencyLink], null: false, description: 'ID of the dependency link.'
field :metadata, Types::Packages::DependencyLinkMetadataType, null: true, description: 'Dependency link metadata.'
# NOTE: This method must be kept in sync with the union
diff --git a/app/graphql/types/packages/package_file_type.rb b/app/graphql/types/packages/package_file_type.rb
index f90a0992bf8..b058dc0ab0d 100644
--- a/app/graphql/types/packages/package_file_type.rb
+++ b/app/graphql/types/packages/package_file_type.rb
@@ -7,17 +7,17 @@ module Types
description 'Represents a package file'
authorize :read_package
- field :id, ::Types::GlobalIDType[::Packages::PackageFile], null: false, description: 'ID of the file.'
field :created_at, Types::TimeType, null: false, description: 'Created date.'
- field :updated_at, Types::TimeType, null: false, description: 'Updated date.'
- field :size, GraphQL::Types::String, null: false, description: 'Size of the package file.'
- field :file_name, GraphQL::Types::String, null: false, description: 'Name of the package file.'
field :download_path, GraphQL::Types::String, null: false, description: 'Download path of the package file.'
field :file_md5, GraphQL::Types::String, null: true, description: 'Md5 of the package file.'
- field :file_sha1, GraphQL::Types::String, null: true, description: 'Sha1 of the package file.'
- field :file_sha256, GraphQL::Types::String, null: true, description: 'Sha256 of the package file.'
field :file_metadata, Types::Packages::FileMetadataType, null: true,
description: 'File metadata.'
+ field :file_name, GraphQL::Types::String, null: false, description: 'Name of the package file.'
+ field :file_sha1, GraphQL::Types::String, null: true, description: 'Sha1 of the package file.'
+ field :file_sha256, GraphQL::Types::String, null: true, description: 'Sha256 of the package file.'
+ field :id, ::Types::GlobalIDType[::Packages::PackageFile], null: false, description: 'ID of the file.'
+ field :size, GraphQL::Types::String, null: false, description: 'Size of the package file.'
+ field :updated_at, Types::TimeType, null: false, description: 'Updated date.'
# NOTE: This method must be kept in sync with the union
# type: `Types::Packages::FileMetadataType`.
diff --git a/app/graphql/types/packages/package_tag_type.rb b/app/graphql/types/packages/package_tag_type.rb
index f1f96c42e27..9d462e90b6f 100644
--- a/app/graphql/types/packages/package_tag_type.rb
+++ b/app/graphql/types/packages/package_tag_type.rb
@@ -7,9 +7,9 @@ module Types
description 'Represents a package tag'
authorize :read_package
+ field :created_at, Types::TimeType, null: false, description: 'Created date.'
field :id, GraphQL::Types::ID, null: false, description: 'ID of the tag.'
field :name, GraphQL::Types::String, null: false, description: 'Name of the tag.'
- field :created_at, Types::TimeType, null: false, description: 'Created date.'
field :updated_at, Types::TimeType, null: false, description: 'Updated date.'
end
end
diff --git a/app/graphql/types/packages/package_type.rb b/app/graphql/types/packages/package_type.rb
index d1312cb963d..1155be28e08 100644
--- a/app/graphql/types/packages/package_type.rb
+++ b/app/graphql/types/packages/package_type.rb
@@ -13,23 +13,23 @@ module Types
field :id, ::Types::GlobalIDType[::Packages::Package], null: false,
description: 'ID of the package.'
- field :name, GraphQL::Types::String, null: false, description: 'Name of the package.'
+ field :can_destroy, GraphQL::Types::Boolean, null: false, description: 'Whether the user can destroy the package.'
field :created_at, Types::TimeType, null: false, description: 'Date of creation.'
- field :updated_at, Types::TimeType, null: false, description: 'Date of most recent update.'
- field :version, GraphQL::Types::String, null: true, description: 'Version string.'
+ field :metadata, Types::Packages::MetadataType, null: true,
+ description: 'Package metadata.'
+ field :name, GraphQL::Types::String, null: false, description: 'Name of the package.'
field :package_type, Types::Packages::PackageTypeEnum, null: false, description: 'Package type.'
- field :tags, Types::Packages::PackageTagType.connection_type, null: true, description: 'Package tags.'
- field :project, Types::ProjectType, null: false, description: 'Project where the package is stored.'
field :pipelines, Types::Ci::PipelineType.connection_type, null: true,
description: 'Pipelines that built the package.',
deprecated: { reason: 'Due to scalability concerns, this field is going to be removed', milestone: '14.6' }
- field :metadata, Types::Packages::MetadataType, null: true,
- description: 'Package metadata.'
+ field :project, Types::ProjectType, null: false, description: 'Project where the package is stored.'
+ field :status, Types::Packages::PackageStatusEnum, null: false, description: 'Package status.'
+ field :tags, Types::Packages::PackageTagType.connection_type, null: true, description: 'Package tags.'
+ field :updated_at, Types::TimeType, null: false, description: 'Date of most recent update.'
+ field :version, GraphQL::Types::String, null: true, description: 'Version string.'
field :versions, ::Types::Packages::PackageType.connection_type, null: true,
description: 'Other versions of the package.',
deprecated: { reason: 'This field is now only returned in the PackageDetailsType', milestone: '13.11' }
- field :status, Types::Packages::PackageStatusEnum, null: false, description: 'Package status.'
- field :can_destroy, GraphQL::Types::Boolean, null: false, description: 'Whether the user can destroy the package.'
def project
Gitlab::Graphql::Loaders::BatchModelLoader.new(Project, object.project_id).find
diff --git a/app/graphql/types/project_statistics_type.rb b/app/graphql/types/project_statistics_type.rb
index ab2b9c2a3af..1146774b43c 100644
--- a/app/graphql/types/project_statistics_type.rb
+++ b/app/graphql/types/project_statistics_type.rb
@@ -9,23 +9,23 @@ module Types
field :commit_count, GraphQL::Types::Float, null: false,
description: 'Commit count of the project.'
- field :storage_size, GraphQL::Types::Float, null: false,
- description: 'Storage size of the project in bytes.'
- field :repository_size, GraphQL::Types::Float, null: false,
- description: 'Repository size of the project in bytes.'
- field :lfs_objects_size, GraphQL::Types::Float, null: false,
- description: 'Large File Storage (LFS) object size of the project in bytes.'
field :build_artifacts_size, GraphQL::Types::Float, null: false,
description: 'Build artifacts size of the project in bytes.'
+ field :lfs_objects_size, GraphQL::Types::Float, null: false,
+ description: 'Large File Storage (LFS) object size of the project in bytes.'
field :packages_size, GraphQL::Types::Float, null: false,
description: 'Packages size of the project in bytes.'
- field :wiki_size, GraphQL::Types::Float, null: true,
- description: 'Wiki size of the project in bytes.'
- field :snippets_size, GraphQL::Types::Float, null: true,
- description: 'Snippets size of the project in bytes.'
field :pipeline_artifacts_size, GraphQL::Types::Float, null: true,
description: 'CI Pipeline artifacts size in bytes.'
+ field :repository_size, GraphQL::Types::Float, null: false,
+ description: 'Repository size of the project in bytes.'
+ field :snippets_size, GraphQL::Types::Float, null: true,
+ description: 'Snippets size of the project in bytes.'
+ field :storage_size, GraphQL::Types::Float, null: false,
+ description: 'Storage size of the project in bytes.'
field :uploads_size, GraphQL::Types::Float, null: true,
description: 'Uploads size of the project in bytes.'
+ field :wiki_size, GraphQL::Types::Float, null: true,
+ description: 'Wiki size of the project in bytes.'
end
end
diff --git a/app/graphql/types/project_type.rb b/app/graphql/types/project_type.rb
index dc428e7bdce..47e9a6c11fc 100644
--- a/app/graphql/types/project_type.rb
+++ b/app/graphql/types/project_type.rb
@@ -11,43 +11,43 @@ module Types
field :id, GraphQL::Types::ID, null: false,
description: 'ID of the project.'
+ field :ci_config_path_or_default, GraphQL::Types::String, null: false,
+ description: 'Path of the CI configuration file.'
field :full_path, GraphQL::Types::ID, null: false,
description: 'Full path of the project.'
field :path, GraphQL::Types::String, null: false,
description: 'Path of the project.'
- field :ci_config_path_or_default, GraphQL::Types::String, null: false,
- description: 'Path of the CI configuration file.'
field :sast_ci_configuration, Types::CiConfiguration::Sast::Type, null: true,
calls_gitaly: true,
description: 'SAST CI configuration for the project.'
- field :name_with_namespace, GraphQL::Types::String, null: false,
- description: 'Full name of the project with its namespace.'
field :name, GraphQL::Types::String, null: false,
description: 'Name of the project (without namespace).'
+ field :name_with_namespace, GraphQL::Types::String, null: false,
+ description: 'Full name of the project with its namespace.'
field :description, GraphQL::Types::String, null: true,
description: 'Short description of the project.'
field :tag_list, GraphQL::Types::String, null: true,
deprecated: { reason: 'Use `topics`', milestone: '13.12' },
- description: 'List of project topics (not Git tags).'
+ description: 'List of project topics (not Git tags).', method: :topic_list
field :topics, [GraphQL::Types::String], null: true,
- description: 'List of project topics.'
+ description: 'List of project topics.', method: :topic_list
- field :ssh_url_to_repo, GraphQL::Types::String, null: true,
- description: 'URL to connect to the project via SSH.'
field :http_url_to_repo, GraphQL::Types::String, null: true,
description: 'URL to connect to the project via HTTPS.'
+ field :ssh_url_to_repo, GraphQL::Types::String, null: true,
+ description: 'URL to connect to the project via SSH.'
field :web_url, GraphQL::Types::String, null: true,
description: 'Web URL of the project.'
- field :star_count, GraphQL::Types::Int, null: false,
- description: 'Number of times the project has been starred.'
field :forks_count, GraphQL::Types::Int, null: false, calls_gitaly: true, # 4 times
description: 'Number of times the project has been forked.'
+ field :star_count, GraphQL::Types::Int, null: false,
+ description: 'Number of times the project has been starred.'
field :created_at, Types::TimeType, null: true,
description: 'Timestamp of the project creation.'
@@ -60,12 +60,12 @@ module Types
field :visibility, GraphQL::Types::String, null: true,
description: 'Visibility of the project.'
- field :shared_runners_enabled, GraphQL::Types::Boolean, null: true,
- description: 'Indicates if shared runners are enabled for the project.'
field :lfs_enabled, GraphQL::Types::Boolean, null: true,
description: 'Indicates if the project has Large File Storage (LFS) enabled.'
field :merge_requests_ff_only_enabled, GraphQL::Types::Boolean, null: true,
description: 'Indicates if no merge commits should be created and all merges should instead be fast-forwarded, which means that merging is only allowed if the branch could be fast-forwarded.'
+ field :shared_runners_enabled, GraphQL::Types::Boolean, null: true,
+ description: 'Indicates if shared runners are enabled for the project.'
field :service_desk_enabled, GraphQL::Types::Boolean, null: true,
description: 'Indicates if the project has service desk enabled.'
@@ -85,33 +85,35 @@ module Types
field :open_issues_count, GraphQL::Types::Int, null: true,
description: 'Number of open issues for the project.'
+ field :allow_merge_on_skipped_pipeline, GraphQL::Types::Boolean, 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 :autoclose_referenced_issues, GraphQL::Types::Boolean, null: true,
+ description: 'Indicates if issues referenced by merge requests and commits within the default branch are closed automatically.'
field :import_status, GraphQL::Types::String, null: true,
description: 'Status of import background job of the project.'
field :jira_import_status, GraphQL::Types::String, null: true,
description: 'Status of Jira import background job of the project.'
- field :only_allow_merge_if_pipeline_succeeds, GraphQL::Types::Boolean, null: true,
- description: 'Indicates if merge requests of the project can only be merged with successful jobs.'
- field :allow_merge_on_skipped_pipeline, GraphQL::Types::Boolean, 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::Types::Boolean, null: true,
- description: 'Indicates if users can request member access to the project.'
field :only_allow_merge_if_all_discussions_are_resolved, GraphQL::Types::Boolean, null: true,
description: 'Indicates if merge requests of the project can only be merged when all the discussions are resolved.'
+ field :only_allow_merge_if_pipeline_succeeds, GraphQL::Types::Boolean, null: true,
+ description: 'Indicates if merge requests of the project can only be merged with successful jobs.'
field :printing_merge_request_link_enabled, GraphQL::Types::Boolean, null: true,
description: '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.'
field :remove_source_branch_after_merge, GraphQL::Types::Boolean, null: true,
description: 'Indicates if `Delete source branch` option should be enabled by default for all new merge requests of the project.'
- field :autoclose_referenced_issues, GraphQL::Types::Boolean, null: true,
- description: 'Indicates if issues referenced by merge requests and commits within the default branch are closed automatically.'
- field :suggestion_commit_message, GraphQL::Types::String, null: true,
- description: 'Commit message used to apply merge request suggestions.'
+ field :request_access_enabled, GraphQL::Types::Boolean, null: true,
+ description: 'Indicates if users can request member access to the project.'
field :squash_read_only, GraphQL::Types::Boolean, null: false, method: :squash_readonly?,
description: 'Indicates if `squashReadOnly` is enabled.'
+ field :suggestion_commit_message, GraphQL::Types::String, null: true,
+ description: 'Commit message used to apply merge request suggestions.'
+ # No, the quotes are not a typo. Used to get around circular dependencies.
+ # See https://gitlab.com/gitlab-org/gitlab/-/merge_requests/27536#note_871009675
+ field :group, 'Types::GroupType', null: true,
+ description: 'Group of the project.'
field :namespace, Types::NamespaceType, null: true,
description: 'Namespace of the project.'
- field :group, Types::GroupType, null: true,
- description: 'Group of the project.'
field :statistics, Types::ProjectStatisticsType,
null: true,
@@ -397,8 +399,9 @@ module Types
field :work_item_types, Types::WorkItems::TypeType.connection_type,
resolver: Resolvers::WorkItems::TypesResolver,
- description: 'Work item types available to the project.',
- feature_flag: :work_items
+ description: 'Work item types available to the project.' \
+ ' Returns `null` if `work_items` feature flag is disabled.' \
+ ' This flag is disabled by default, because the feature is experimental and is subject to change without notice.'
def label(title:)
BatchLoader::GraphQL.for(title).batch(key: project) do |titles, loader, args|
@@ -458,14 +461,6 @@ module Types
object.service_desk_address
end
- def tag_list
- object.topic_list
- end
-
- def topics
- object.topic_list
- end
-
private
def project
diff --git a/app/graphql/types/projects/service_type.rb b/app/graphql/types/projects/service_type.rb
index 4a9e5dcbfe9..88b7b95aa57 100644
--- a/app/graphql/types/projects/service_type.rb
+++ b/app/graphql/types/projects/service_type.rb
@@ -10,9 +10,20 @@ module Types
# https://gitlab.com/gitlab-org/gitlab/-/issues/213088
field :type, GraphQL::Types::String, null: true,
description: 'Class name of the service.'
+ field :service_type, ::Types::Projects::ServiceTypeEnum, null: true,
+ description: 'Type of the service.'
field :active, GraphQL::Types::Boolean, null: true,
description: 'Indicates if the service is active.'
+ def type
+ enum = ::Types::Projects::ServiceTypeEnum.coerce_result(service_type, context)
+ enum.downcase.camelize
+ end
+
+ def service_type
+ object.type
+ end
+
definition_methods do
def resolve_type(object, context)
if object.is_a?(::Integrations::Jira)
diff --git a/app/graphql/types/projects/service_type_enum.rb b/app/graphql/types/projects/service_type_enum.rb
index 027026dc16c..d0cecbfea49 100644
--- a/app/graphql/types/projects/service_type_enum.rb
+++ b/app/graphql/types/projects/service_type_enum.rb
@@ -5,8 +5,21 @@ module Types
class ServiceTypeEnum < BaseEnum
graphql_name 'ServiceType'
- ::Integration.available_integration_types(include_dev: false).each do |type|
- value type.underscore.upcase, value: type, description: "#{type} type"
+ class << self
+ private
+
+ def type_description(name, type)
+ "#{type} type"
+ end
+ end
+
+ # This prepend must stay here because the dynamic block below depends on it.
+ prepend_mod # rubocop: disable Cop/InjectEnterpriseEditionModule
+
+ ::Integration.available_integration_names(include_dev: false).each do |name|
+ type = "#{name.camelize}Service"
+ domain_value = Integration.integration_name_to_type(name)
+ value type.underscore.upcase, value: domain_value, description: type_description(name, type)
end
end
end
diff --git a/app/graphql/types/projects/services/jira_project_type.rb b/app/graphql/types/projects/services/jira_project_type.rb
index 957ac91db6b..0ff1b9d8903 100644
--- a/app/graphql/types/projects/services/jira_project_type.rb
+++ b/app/graphql/types/projects/services/jira_project_type.rb
@@ -9,11 +9,11 @@ module Types
field :key, GraphQL::Types::String, null: false,
description: 'Key of the Jira project.'
+ field :name, GraphQL::Types::String, null: true,
+ description: 'Name of the Jira project.'
field :project_id, GraphQL::Types::Int, null: false,
description: 'ID of the Jira project.',
method: :id
- field :name, GraphQL::Types::String, null: true,
- description: 'Name of the Jira project.'
end
# rubocop:enable Graphql/AuthorizeTypes
end
diff --git a/app/graphql/types/query_type.rb b/app/graphql/types/query_type.rb
index 4a4d6727c3f..cc46c7e86e4 100644
--- a/app/graphql/types/query_type.rb
+++ b/app/graphql/types/query_type.rb
@@ -87,6 +87,12 @@ module Types
argument :id, ::Types::GlobalIDType[::Issue], required: true, description: 'Global ID of the issue.'
end
+ field :work_item, Types::WorkItemType,
+ null: true,
+ resolver: Resolvers::WorkItemResolver,
+ description: 'Find a work item. Returns `null` if `work_items` feature flag is disabled.' \
+ ' The feature is experimental and is subject to change without notice.'
+
field :merge_request, Types::MergeRequestType,
null: true,
description: 'Find a merge request.' do
@@ -145,6 +151,10 @@ module Types
resolver: Resolvers::TopicsResolver,
description: "Find project topics."
+ field :gitpod_enabled, GraphQL::Types::Boolean,
+ null: true,
+ description: "Whether Gitpod is enabled in application settings."
+
def design_management
DesignManagementObject.new(nil)
end
@@ -189,6 +199,10 @@ module Types
Gitlab::CurrentSettings.current_application_settings
end
+ def gitpod_enabled
+ application_settings.gitpod_enabled
+ end
+
def query_complexity
context.query
end
diff --git a/app/graphql/types/release_asset_link_type.rb b/app/graphql/types/release_asset_link_type.rb
index 02961f2f73f..33dcb5125e3 100644
--- a/app/graphql/types/release_asset_link_type.rb
+++ b/app/graphql/types/release_asset_link_type.rb
@@ -7,21 +7,21 @@ module Types
authorize :read_release
+ field :external, GraphQL::Types::Boolean, null: true, method: :external?,
+ description: 'Indicates the link points to an external resource.'
field :id, GraphQL::Types::ID, null: false,
description: 'ID of the link.'
+ field :link_type, Types::ReleaseAssetLinkTypeEnum, null: true,
+ description: 'Type of the link: `other`, `runbook`, `image`, `package`; defaults to `other`.'
field :name, GraphQL::Types::String, null: true,
description: 'Name of the link.'
field :url, GraphQL::Types::String, null: true,
description: 'URL of the link.'
- field :link_type, Types::ReleaseAssetLinkTypeEnum, null: true,
- description: 'Type of the link: `other`, `runbook`, `image`, `package`; defaults to `other`.'
- field :external, GraphQL::Types::Boolean, null: true, method: :external?,
- description: 'Indicates the link points to an external resource.'
- field :direct_asset_url, GraphQL::Types::String, null: true,
- description: 'Direct asset URL of the link.'
field :direct_asset_path, GraphQL::Types::String, null: true, method: :filepath,
description: 'Relative path for the direct asset link.'
+ field :direct_asset_url, GraphQL::Types::String, null: true,
+ description: 'Direct asset URL of the link.'
def direct_asset_url
return object.url unless object.filepath
diff --git a/app/graphql/types/release_links_type.rb b/app/graphql/types/release_links_type.rb
index 37ad52ce6d0..b7a1a5a9dbe 100644
--- a/app/graphql/types/release_links_type.rb
+++ b/app/graphql/types/release_links_type.rb
@@ -10,25 +10,25 @@ module Types
present_using ReleasePresenter
- field :self_url, GraphQL::Types::String, null: true,
- description: 'HTTP URL of the release.'
+ field :closed_issues_url, GraphQL::Types::String, null: true,
+ description: 'HTTP URL of the issues page, filtered by this release and `state=closed`.',
+ authorize: :download_code
+ field :closed_merge_requests_url, GraphQL::Types::String, null: true,
+ description: 'HTTP URL of the merge request page , filtered by this release and `state=closed`.',
+ authorize: :download_code
field :edit_url, GraphQL::Types::String, null: true,
description: "HTTP URL of the release's edit page.",
authorize: :update_release
- field :opened_merge_requests_url, GraphQL::Types::String, null: true,
- description: 'HTTP URL of the merge request page, filtered by this release and `state=open`.',
- authorize: :download_code
field :merged_merge_requests_url, GraphQL::Types::String, null: true,
description: 'HTTP URL of the merge request page , filtered by this release and `state=merged`.',
authorize: :download_code
- field :closed_merge_requests_url, GraphQL::Types::String, null: true,
- description: 'HTTP URL of the merge request page , filtered by this release and `state=closed`.',
- authorize: :download_code
field :opened_issues_url, GraphQL::Types::String, null: true,
description: 'HTTP URL of the issues page, filtered by this release and `state=open`.',
authorize: :download_code
- field :closed_issues_url, GraphQL::Types::String, null: true,
- description: 'HTTP URL of the issues page, filtered by this release and `state=closed`.',
+ field :opened_merge_requests_url, GraphQL::Types::String, null: true,
+ description: 'HTTP URL of the merge request page, filtered by this release and `state=open`.',
authorize: :download_code
+ field :self_url, GraphQL::Types::String, null: true,
+ description: 'HTTP URL of the release.'
end
end
diff --git a/app/graphql/types/release_type.rb b/app/graphql/types/release_type.rb
index fbc3779ea9b..95b6b43bb46 100644
--- a/app/graphql/types/release_type.rb
+++ b/app/graphql/types/release_type.rb
@@ -13,30 +13,30 @@ module Types
present_using ReleasePresenter
- field :tag_name, GraphQL::Types::String, null: true, method: :tag,
- description: 'Name of the tag associated with the release.'
- field :tag_path, GraphQL::Types::String, null: true,
- description: 'Relative web path to the tag associated with the release.',
- authorize: :download_code
+ field :assets, Types::ReleaseAssetsType, null: true, method: :itself,
+ description: 'Assets of the release.'
+ field :created_at, Types::TimeType, null: true,
+ description: 'Timestamp of when the release was created.'
field :description, GraphQL::Types::String, null: true,
description: 'Description (also known as "release notes") of the release.'
+ field :evidences, Types::EvidenceType.connection_type, null: true,
+ description: 'Evidence for the release.'
+ field :links, Types::ReleaseLinksType, null: true, method: :itself,
+ description: 'Links of the release.'
+ field :milestones, Types::MilestoneType.connection_type, null: true,
+ description: 'Milestones associated to the release.',
+ resolver: ::Resolvers::ReleaseMilestonesResolver
field :name, GraphQL::Types::String, null: true,
description: 'Name of the release.'
- field :created_at, Types::TimeType, null: true,
- description: 'Timestamp of when the release was created.'
field :released_at, Types::TimeType, null: true,
description: 'Timestamp of when the release was released.'
+ field :tag_name, GraphQL::Types::String, null: true, method: :tag,
+ description: 'Name of the tag associated with the release.'
+ field :tag_path, GraphQL::Types::String, null: true,
+ description: 'Relative web path to the tag associated with the release.',
+ authorize: :download_code
field :upcoming_release, GraphQL::Types::Boolean, null: true, method: :upcoming_release?,
description: 'Indicates the release is an upcoming release.'
- field :assets, Types::ReleaseAssetsType, null: true, method: :itself,
- description: 'Assets of the release.'
- field :links, Types::ReleaseLinksType, null: true, method: :itself,
- description: 'Links of the release.'
- field :milestones, Types::MilestoneType.connection_type, null: true,
- description: 'Milestones associated to the release.',
- resolver: ::Resolvers::ReleaseMilestonesResolver
- 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/repository/blob_type.rb b/app/graphql/types/repository/blob_type.rb
index bfd59763a07..652e2882584 100644
--- a/app/graphql/types/repository/blob_type.rb
+++ b/app/graphql/types/repository/blob_type.rb
@@ -41,6 +41,9 @@ module Types
field :ide_fork_and_edit_path, GraphQL::Types::String, null: true,
description: 'Web path to edit this blob in the Web IDE using a forked project.'
+ field :fork_and_view_path, GraphQL::Types::String, null: true,
+ description: 'Web path to view this blob using a forked project.'
+
field :size, GraphQL::Types::Int, null: true,
description: 'Size (in bytes) of the blob.'
@@ -74,6 +77,9 @@ module Types
field :pipeline_editor_path, GraphQL::Types::String, null: true,
description: 'Web path to edit .gitlab-ci.yml file.'
+ field :gitpod_blob_url, GraphQL::Types::String, null: true,
+ description: 'URL to the blob within Gitpod.'
+
field :find_file_path, GraphQL::Types::String, null: true,
description: 'Web path to find file.'
@@ -131,6 +137,12 @@ module Types
null: true,
calls_gitaly: true
+ field :code_navigation_path, GraphQL::Types::String, null: true, calls_gitaly: true,
+ description: 'Web path for code navigation.'
+
+ field :project_blob_path_root, GraphQL::Types::String, null: true,
+ description: 'Web path for the root of the blob.'
+
def raw_text_blob
object.data unless object.binary?
end
diff --git a/app/graphql/types/repository_type.rb b/app/graphql/types/repository_type.rb
index fc9860900c9..aa02f0058da 100644
--- a/app/graphql/types/repository_type.rb
+++ b/app/graphql/types/repository_type.rb
@@ -6,17 +6,6 @@ module Types
authorize :download_code
- field :root_ref, GraphQL::Types::String, null: true, calls_gitaly: true,
- description: 'Default branch of the repository.'
- field :empty, GraphQL::Types::Boolean, null: false, method: :empty?, calls_gitaly: true,
- description: 'Indicates repository has no visible content.'
- field :exists, GraphQL::Types::Boolean, null: false, method: :exists?, calls_gitaly: true,
- description: 'Indicates a corresponding Git repository exists on disk.'
- field :tree, Types::Tree::TreeType, null: true, resolver: Resolvers::TreeResolver, calls_gitaly: true,
- description: 'Tree of the repository.'
- field :paginated_tree, Types::Tree::TreeType.connection_type, null: true, resolver: Resolvers::PaginatedTreeResolver, calls_gitaly: true,
- max_page_size: 100,
- description: 'Paginated tree of the repository.'
field :blobs, Types::Repository::BlobType.connection_type, null: true, resolver: Resolvers::BlobsResolver, calls_gitaly: true,
description: 'Blobs contained within the repository'
field :branch_names, [GraphQL::Types::String], null: true, calls_gitaly: true,
@@ -26,5 +15,16 @@ module Types
description: 'Shows a disk path of the repository.',
null: true,
authorize: :read_storage_disk_path
+ field :empty, GraphQL::Types::Boolean, null: false, method: :empty?, calls_gitaly: true,
+ description: 'Indicates repository has no visible content.'
+ field :exists, GraphQL::Types::Boolean, null: false, method: :exists?, calls_gitaly: true,
+ description: 'Indicates a corresponding Git repository exists on disk.'
+ field :paginated_tree, Types::Tree::TreeType.connection_type, null: true, resolver: Resolvers::PaginatedTreeResolver, calls_gitaly: true,
+ max_page_size: 100,
+ description: 'Paginated tree of the repository.'
+ field :root_ref, GraphQL::Types::String, null: true, calls_gitaly: true,
+ description: 'Default branch of the repository.'
+ field :tree, Types::Tree::TreeType, null: true, resolver: Resolvers::TreeResolver, calls_gitaly: true,
+ description: 'Tree of the repository.'
end
end
diff --git a/app/graphql/types/root_storage_statistics_type.rb b/app/graphql/types/root_storage_statistics_type.rb
index 4dcadf1274f..467331c5643 100644
--- a/app/graphql/types/root_storage_statistics_type.rb
+++ b/app/graphql/types/root_storage_statistics_type.rb
@@ -6,15 +6,15 @@ module Types
authorize :read_statistics
- field :storage_size, GraphQL::Types::Float, null: false, description: 'Total storage in bytes.'
- field :repository_size, GraphQL::Types::Float, null: false, description: 'Git repository size in bytes.'
- field :lfs_objects_size, GraphQL::Types::Float, null: false, description: 'LFS objects size in bytes.'
field :build_artifacts_size, GraphQL::Types::Float, null: false, description: 'CI artifacts size in bytes.'
+ field :dependency_proxy_size, GraphQL::Types::Float, null: false, description: 'Dependency Proxy sizes in bytes.'
+ field :lfs_objects_size, GraphQL::Types::Float, null: false, description: 'LFS objects size in bytes.'
field :packages_size, GraphQL::Types::Float, null: false, description: 'Packages size in bytes.'
- field :wiki_size, GraphQL::Types::Float, null: false, description: 'Wiki size in bytes.'
- field :snippets_size, GraphQL::Types::Float, null: false, description: 'Snippets size in bytes.'
field :pipeline_artifacts_size, GraphQL::Types::Float, null: false, description: 'CI pipeline artifacts size in bytes.'
+ field :repository_size, GraphQL::Types::Float, null: false, description: 'Git repository size in bytes.'
+ field :snippets_size, GraphQL::Types::Float, null: false, description: 'Snippets size in bytes.'
+ field :storage_size, GraphQL::Types::Float, null: false, description: 'Total storage in bytes.'
field :uploads_size, GraphQL::Types::Float, null: false, description: 'Uploads size in bytes.'
- field :dependency_proxy_size, GraphQL::Types::Float, null: false, description: 'Dependency Proxy sizes in bytes.'
+ field :wiki_size, GraphQL::Types::Float, null: false, description: 'Wiki size in bytes.'
end
end
diff --git a/app/graphql/types/saved_reply_type.rb b/app/graphql/types/saved_reply_type.rb
new file mode 100644
index 00000000000..329f431b10e
--- /dev/null
+++ b/app/graphql/types/saved_reply_type.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+module Types
+ class SavedReplyType < BaseObject
+ graphql_name 'SavedReply'
+
+ authorize :read_saved_replies
+
+ field :id, Types::GlobalIDType[::Users::SavedReply],
+ null: false,
+ description: 'Global ID of the saved reply.'
+
+ field :content, GraphQL::Types::String,
+ null: false,
+ description: 'Content of the saved reply.'
+
+ field :name, GraphQL::Types::String,
+ null: false,
+ description: 'Name of the saved reply.'
+ end
+end
diff --git a/app/graphql/types/task_completion_status.rb b/app/graphql/types/task_completion_status.rb
index 3aa19ff9413..9a979b04d37 100644
--- a/app/graphql/types/task_completion_status.rb
+++ b/app/graphql/types/task_completion_status.rb
@@ -8,10 +8,10 @@ module Types
graphql_name 'TaskCompletionStatus'
description 'Completion status of tasks'
- field :count, GraphQL::Types::Int, null: false,
- description: 'Number of total tasks.'
field :completed_count, GraphQL::Types::Int, null: false,
description: 'Number of completed tasks.'
+ field :count, GraphQL::Types::Int, null: false,
+ description: 'Number of total tasks.'
end
# rubocop: enable Graphql/AuthorizeTypes
end
diff --git a/app/graphql/types/todo_type.rb b/app/graphql/types/todo_type.rb
index 34ba2c75b5f..f21b2b261a3 100644
--- a/app/graphql/types/todo_type.rb
+++ b/app/graphql/types/todo_type.rb
@@ -18,7 +18,7 @@ module Types
null: true,
authorize: :read_project
- field :group, Types::GroupType,
+ field :group, 'Types::GroupType',
description: 'Group this to-do item is associated with.',
null: true,
authorize: :read_group
@@ -31,6 +31,11 @@ module Types
description: 'Action of the to-do item.',
null: false
+ field :target, Types::TodoableInterface,
+ description: 'Target of the to-do item.',
+ calls_gitaly: true,
+ null: false
+
field :target_type, Types::TodoTargetEnum,
description: 'Target type of the to-do item.',
null: false
@@ -59,5 +64,28 @@ module Types
def author
Gitlab::Graphql::Loaders::BatchModelLoader.new(User, object.author_id).find
end
+
+ def target
+ if object.for_commit?
+ Gitlab::Graphql::Loaders::BatchCommitLoader.new(
+ container_class: Project,
+ container_id: object.project_id,
+ oid: object.commit_id
+ ).find
+ else
+ Gitlab::Graphql::Loaders::BatchModelLoader.new(target_type_class, object.target_id).find
+ end
+ end
+
+ private
+
+ def target_type_class
+ klass = object.target_type.safe_constantize
+ raise "Invalid target type \"#{object.target_type}\"" unless klass < Todoable
+
+ klass
+ end
end
end
+
+Types::TodoType.prepend_mod
diff --git a/app/graphql/types/todoable_interface.rb b/app/graphql/types/todoable_interface.rb
new file mode 100644
index 00000000000..7d437973c12
--- /dev/null
+++ b/app/graphql/types/todoable_interface.rb
@@ -0,0 +1,30 @@
+# frozen_string_literal: true
+
+module Types
+ module TodoableInterface
+ include Types::BaseInterface
+
+ graphql_name 'Todoable'
+
+ field :web_url, GraphQL::Types::String, null: true, description: 'URL of this object.'
+
+ def self.resolve_type(object, context)
+ case object
+ when Issue
+ Types::IssueType
+ when MergeRequest
+ Types::MergeRequestType
+ when ::DesignManagement::Design
+ Types::DesignManagement::DesignType
+ when ::AlertManagement::Alert
+ Types::AlertManagement::AlertType
+ when Commit
+ Types::CommitType
+ else
+ raise "Unknown GraphQL type for #{object}"
+ end
+ end
+ end
+end
+
+Types::TodoableInterface.prepend_mod
diff --git a/app/graphql/types/tree/blob_type.rb b/app/graphql/types/tree/blob_type.rb
index bcff65be652..284542e1d2a 100644
--- a/app/graphql/types/tree/blob_type.rb
+++ b/app/graphql/types/tree/blob_type.rb
@@ -9,15 +9,15 @@ module Types
implements Types::Tree::EntryType
present_using BlobPresenter
- field :web_url, GraphQL::Types::String, null: true,
- description: 'Web URL of the blob.'
- field :web_path, GraphQL::Types::String, null: true,
- description: 'Web path of the blob.'
field :lfs_oid, GraphQL::Types::String, null: true,
calls_gitaly: true,
description: 'LFS ID of the blob.'
field :mode, GraphQL::Types::String, null: true,
description: 'Blob mode in numeric format.'
+ field :web_path, GraphQL::Types::String, null: true,
+ description: 'Web path of the blob.'
+ field :web_url, GraphQL::Types::String, null: true,
+ description: 'Web URL of the blob.'
def lfs_oid
Gitlab::Graphql::Loaders::BatchLfsOidLoader.new(object.repository, object.id).find
diff --git a/app/graphql/types/tree/submodule_type.rb b/app/graphql/types/tree/submodule_type.rb
index bc7828dbffa..8f462011f0f 100644
--- a/app/graphql/types/tree/submodule_type.rb
+++ b/app/graphql/types/tree/submodule_type.rb
@@ -8,10 +8,10 @@ module Types
implements Types::Tree::EntryType
- field :web_url, type: GraphQL::Types::String, null: true,
- description: 'Web URL for the sub-module.'
field :tree_url, type: GraphQL::Types::String, null: true,
description: 'Tree URL for the sub-module.'
+ field :web_url, type: GraphQL::Types::String, null: true,
+ description: 'Web URL for the sub-module.'
end
# rubocop: enable Graphql/AuthorizeTypes
end
diff --git a/app/graphql/types/tree/tree_entry_type.rb b/app/graphql/types/tree/tree_entry_type.rb
index cdc84c8e318..28024fd010b 100644
--- a/app/graphql/types/tree/tree_entry_type.rb
+++ b/app/graphql/types/tree/tree_entry_type.rb
@@ -10,10 +10,10 @@ module Types
implements Types::Tree::EntryType
present_using TreeEntryPresenter
- field :web_url, GraphQL::Types::String, null: true,
- description: 'Web URL for the tree entry (directory).'
field :web_path, GraphQL::Types::String, null: true,
description: 'Web path for the tree entry (directory).'
+ field :web_url, GraphQL::Types::String, null: true,
+ description: 'Web URL for the tree entry (directory).'
end
# rubocop: enable Graphql/AuthorizeTypes
end
diff --git a/app/graphql/types/user_callout_type.rb b/app/graphql/types/user_callout_type.rb
index 0ff32d68400..526027322ef 100644
--- a/app/graphql/types/user_callout_type.rb
+++ b/app/graphql/types/user_callout_type.rb
@@ -4,9 +4,9 @@ module Types
class UserCalloutType < BaseObject # rubocop:disable Graphql/AuthorizeTypes
graphql_name 'UserCallout'
- field :feature_name, UserCalloutFeatureNameEnum, null: true,
- description: 'Name of the feature that the callout is for.'
field :dismissed_at, Types::TimeType, null: true,
description: 'Date when the callout was dismissed.'
+ field :feature_name, UserCalloutFeatureNameEnum, null: true,
+ description: 'Name of the feature that the callout is for.'
end
end
diff --git a/app/graphql/types/user_interface.rb b/app/graphql/types/user_interface.rb
index 24fca80d5a9..2c9592a7f5a 100644
--- a/app/graphql/types/user_interface.rb
+++ b/app/graphql/types/user_interface.rb
@@ -115,6 +115,19 @@ module Types
extras: [:lookahead],
complexity: 5,
resolver: ::Resolvers::TimelogResolver
+ field :saved_replies,
+ Types::SavedReplyType.connection_type,
+ null: true,
+ description: 'Saved replies authored by the user.'
+
+ field :gitpod_enabled, GraphQL::Types::Boolean, null: true,
+ description: 'Whether Gitpod is enabled at the user level.'
+
+ field :preferences_gitpod_path, GraphQL::Types::String, null: true,
+ description: 'Web path to the Gitpod section within user preferences.'
+
+ field :profile_enable_gitpod_path, GraphQL::Types::String, null: true,
+ description: 'Web path to enable Gitpod for the user.'
definition_methods do
def resolve_type(object, context)
@@ -125,14 +138,7 @@ module Types
end
def redacted_name
- return object.name unless object.project_bot?
-
- return object.name if context[:current_user]&.can?(:read_project, object.projects.first)
-
- # If the requester does not have permission to read the project bot name,
- # the API returns an arbitrary string. UI changes will be addressed in a follow up issue:
- # https://gitlab.com/gitlab-org/gitlab/-/issues/346058
- '****'
+ object.redacted_name(context[:current_user])
end
end
end
diff --git a/app/graphql/types/user_status_type.rb b/app/graphql/types/user_status_type.rb
index 61abec0ba96..68c00bffe48 100644
--- a/app/graphql/types/user_status_type.rb
+++ b/app/graphql/types/user_status_type.rb
@@ -7,11 +7,11 @@ module Types
markdown_field :message_html, null: true,
description: 'HTML of the user status message'
- field :message, GraphQL::Types::String, null: true,
- description: 'User status message.'
- field :emoji, GraphQL::Types::String, null: true,
- description: 'String representation of emoji.'
field :availability, Types::AvailabilityEnum, null: false,
description: 'User availability status.'
+ field :emoji, GraphQL::Types::String, null: true,
+ description: 'String representation of emoji.'
+ field :message, GraphQL::Types::String, null: true,
+ description: 'User status message.'
end
end
diff --git a/app/graphql/types/work_item_id_type.rb b/app/graphql/types/work_item_id_type.rb
new file mode 100644
index 00000000000..ddcf3416014
--- /dev/null
+++ b/app/graphql/types/work_item_id_type.rb
@@ -0,0 +1,50 @@
+# frozen_string_literal: true
+
+module Types
+ # rubocop:disable Graphql/AuthorizeTypes
+ # TODO: This type should be removed when Work Items become generally available.
+ # This mechanism is introduced temporarily to make the client implementation easier during this transition.
+ class WorkItemIdType < GlobalIDType
+ graphql_name 'WorkItemID'
+ description <<~DESC
+ A `WorkItemID` is a global ID. It is encoded as a string.
+
+ An example `WorkItemID` is: `"gid://gitlab/WorkItem/1"`.
+
+ While we transition from Issues into Work Items this type will temporarily support
+ `IssueID` like: `"gid://gitlab/Issue/1"`. This behavior will be removed without notice in the future.
+ DESC
+
+ class << self
+ def coerce_result(gid, ctx)
+ global_id = ::Gitlab::GlobalId.as_global_id(gid, model_name: 'WorkItem')
+
+ raise GraphQL::CoercionError, "Expected a WorkItem ID, got #{global_id}" unless suitable?(global_id)
+
+ # Always return a WorkItemID even if an Issue is returned by a resolver
+ work_item_gid(global_id).to_s
+ end
+
+ def coerce_input(string, ctx)
+ gid = super
+ # Always return a WorkItemID even if an Issue Global ID is provided as input
+ return work_item_gid(gid) if suitable?(gid)
+
+ raise GraphQL::CoercionError, "#{string.inspect} does not represent an instance of WorkItem"
+ end
+
+ def suitable?(gid)
+ return false if gid&.model_name&.safe_constantize.blank?
+
+ [::WorkItem, ::Issue].any? { |model_class| gid.model_class == model_class }
+ end
+
+ private
+
+ def work_item_gid(gid)
+ GlobalID.new(::Gitlab::GlobalId.build(model_name: 'WorkItem', id: gid.model_id))
+ end
+ end
+ end
+ # rubocop:enable Graphql/AuthorizeTypes
+end
diff --git a/app/graphql/types/work_item_type.rb b/app/graphql/types/work_item_type.rb
index 15a5557b489..512b9ef64d2 100644
--- a/app/graphql/types/work_item_type.rb
+++ b/app/graphql/types/work_item_type.rb
@@ -4,7 +4,7 @@ module Types
class WorkItemType < BaseObject
graphql_name 'WorkItem'
- authorize :read_issue
+ authorize :read_work_item
field :description, GraphQL::Types::String, null: true,
description: 'Description of the work item.'
@@ -12,6 +12,8 @@ module Types
description: 'Global ID of the work item.'
field :iid, GraphQL::Types::ID, null: false,
description: 'Internal ID of the work item.'
+ field :lock_version, GraphQL::Types::Int, null: false,
+ description: 'Lock version of the work item. Incremented each time the work item is updated.'
field :state, WorkItemStateEnum, null: false,
description: 'State of the work item.'
field :title, GraphQL::Types::String, null: false,
diff --git a/app/graphql/types/work_items/convert_task_input_type.rb b/app/graphql/types/work_items/convert_task_input_type.rb
new file mode 100644
index 00000000000..1f142c6815c
--- /dev/null
+++ b/app/graphql/types/work_items/convert_task_input_type.rb
@@ -0,0 +1,36 @@
+# frozen_string_literal: true
+
+module Types
+ module WorkItems
+ class ConvertTaskInputType < BaseInputObject
+ graphql_name 'WorkItemConvertTaskInput'
+
+ argument :line_number_end, GraphQL::Types::Int,
+ required: true,
+ description: 'Last line in the Markdown source that defines the list item task.'
+ argument :line_number_start, GraphQL::Types::Int,
+ required: true,
+ description: 'First line in the Markdown source that defines the list item task.'
+ argument :lock_version, GraphQL::Types::Int,
+ required: true,
+ description: 'Current lock version of the work item containing the task in the description.'
+ argument :title, GraphQL::Types::String,
+ required: true,
+ description: 'Full string of the task to be replaced. New title for the created work item.'
+ argument :work_item_type_id, ::Types::GlobalIDType[::WorkItems::Type],
+ required: true,
+ description: 'Global ID of the work item type used to create the new work item.',
+ prepare: ->(attribute, _ctx) { work_item_type_global_id(attribute) }
+
+ class << self
+ def work_item_type_global_id(global_id)
+ # TODO: remove this line when the compatibility layer is removed
+ # See: https://gitlab.com/gitlab-org/gitlab/-/issues/257883
+ global_id = ::Types::GlobalIDType[::WorkItems::Type].coerce_isolated_input(global_id)
+
+ global_id&.model_id
+ end
+ end
+ end
+ end
+end
diff --git a/app/helpers/access_tokens_helper.rb b/app/helpers/access_tokens_helper.rb
index 1d38262159f..d8d44601327 100644
--- a/app/helpers/access_tokens_helper.rb
+++ b/app/helpers/access_tokens_helper.rb
@@ -27,4 +27,10 @@ module AccessTokensHelper
}
}.to_json
end
+
+ def expires_at_field_data
+ {}
+ end
end
+
+AccessTokensHelper.prepend_mod
diff --git a/app/helpers/appearances_helper.rb b/app/helpers/appearances_helper.rb
index 5ca360f38da..cb43d911a2f 100644
--- a/app/helpers/appearances_helper.rb
+++ b/app/helpers/appearances_helper.rb
@@ -38,6 +38,8 @@ module AppearancesHelper
def brand_header_logo
if current_appearance&.header_logo?
image_tag current_appearance.header_logo_path, class: 'brand-header-logo'
+ elsif Feature.enabled?(:ukraine_support_tanuki)
+ render partial: 'shared/logo_ukraine', formats: :svg
else
render partial: 'shared/logo', formats: :svg
end
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index e675c01bcbb..feeedb0a501 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -18,6 +18,28 @@ module ApplicationHelper
end
end
+ def dispensable_render(...)
+ render(...)
+ rescue StandardError => error
+ if Feature.enabled?(:dispensable_render, default_enabled: :yaml)
+ Gitlab::ErrorTracking.track_and_raise_for_dev_exception(error)
+ nil
+ else
+ raise error
+ end
+ end
+
+ def dispensable_render_if_exists(...)
+ render_if_exists(...)
+ rescue StandardError => error
+ if Feature.enabled?(:dispensable_render, default_enabled: :yaml)
+ Gitlab::ErrorTracking.track_and_raise_for_dev_exception(error)
+ nil
+ else
+ raise error
+ end
+ end
+
def partial_exists?(partial)
lookup_context.exists?(partial, [], true)
end
diff --git a/app/helpers/application_settings_helper.rb b/app/helpers/application_settings_helper.rb
index fa9b3bfc912..a9c13b2fdeb 100644
--- a/app/helpers/application_settings_helper.rb
+++ b/app/helpers/application_settings_helper.rb
@@ -212,6 +212,7 @@ module ApplicationSettingsHelper
:auto_devops_enabled,
:auto_devops_domain,
:container_expiration_policies_enable_historic_entries,
+ :container_registry_expiration_policies_caching,
:container_registry_token_expire_delay,
:default_artifacts_expire_in,
:default_branch_name,
@@ -423,7 +424,8 @@ module ApplicationSettingsHelper
:sidekiq_job_limiter_compression_threshold_bytes,
:sidekiq_job_limiter_limit_bytes,
:suggest_pipeline_enabled,
- :user_email_lookup_limit,
+ :search_rate_limit,
+ :search_rate_limit_unauthenticated,
:users_get_by_id_limit,
:users_get_by_id_limit_allowlist_raw,
:runner_token_expiration_interval,
@@ -463,7 +465,10 @@ module ApplicationSettingsHelper
end
def instance_clusters_enabled?
- can?(current_user, :read_cluster, Clusters::Instance.new)
+ clusterable = Clusters::Instance.new
+
+ Feature.enabled?(:certificate_based_clusters, clusterable, default_enabled: :yaml, type: :ops) &&
+ can?(current_user, :read_cluster, clusterable)
end
def omnibus_protected_paths_throttle?
diff --git a/app/helpers/auth_helper.rb b/app/helpers/auth_helper.rb
index fb2fa547447..ba6c0380edf 100644
--- a/app/helpers/auth_helper.rb
+++ b/app/helpers/auth_helper.rb
@@ -178,7 +178,7 @@ module AuthHelper
end
def google_tag_manager_enabled?
- return false unless Gitlab.dev_env_or_com?
+ return false unless Gitlab.com?
if Feature.enabled?(:gtm_nonce, type: :ops)
extra_config.has_key?('google_tag_manager_nonce_id') &&
diff --git a/app/helpers/blob_helper.rb b/app/helpers/blob_helper.rb
index f0e8ff7778e..fcf6a177984 100644
--- a/app/helpers/blob_helper.rb
+++ b/app/helpers/blob_helper.rb
@@ -65,40 +65,13 @@ module BlobHelper
return unless blob = readable_blob(options, path, project, ref)
common_classes = "btn gl-button btn-confirm js-edit-blob gl-ml-3 #{options[:extra_class]}"
- data = { track_action: 'click_edit', track_label: 'edit' }
-
- if Feature.enabled?(:web_ide_primary_edit, project.group)
- common_classes += " btn-inverted"
- data[:track_property] = 'secondary'
- end
edit_button_tag(blob,
common_classes,
_('Edit'),
edit_blob_path(project, ref, path, options),
project,
- ref,
- data)
- end
-
- def ide_edit_button(project = @project, ref = @ref, path = @path, blob:)
- return unless blob
-
- common_classes = 'btn gl-button btn-confirm ide-edit-button gl-ml-3'
- data = { track_action: 'click_edit_ide', track_label: 'web_ide' }
-
- unless Feature.enabled?(:web_ide_primary_edit, project.group)
- common_classes += " btn-inverted"
- data[:track_property] = 'secondary'
- end
-
- edit_button_tag(blob,
- common_classes,
- _('Web IDE'),
- ide_edit_path(project, ref, path),
- project,
- ref,
- data)
+ ref)
end
def modify_file_button(project = @project, ref = @ref, path = @path, blob:, label:, action:, btn_class:, modal_type:)
@@ -363,16 +336,16 @@ module BlobHelper
content_tag(:span, button, class: 'has-tooltip', title: _('You can only edit files when you are on a branch'), data: { container: 'body' })
end
- def edit_link_tag(link_text, edit_path, common_classes, data)
- link_to link_text, edit_path, class: "#{common_classes}", data: data
+ def edit_link_tag(link_text, edit_path, common_classes)
+ link_to link_text, edit_path, class: "#{common_classes}"
end
- def edit_button_tag(blob, common_classes, text, edit_path, project, ref, data)
+ def edit_button_tag(blob, common_classes, text, edit_path, project, ref)
if !on_top_of_branch?(project, ref)
edit_disabled_button_tag(text, common_classes)
# This condition only applies to users who are logged in
elsif !current_user || (current_user && can_modify_blob?(blob, project, ref))
- edit_link_tag(text, edit_path, common_classes, data)
+ edit_link_tag(text, edit_path, common_classes)
elsif can?(current_user, :fork_project, project) && can?(current_user, :create_merge_request_in, project)
edit_fork_button_tag(common_classes, project, text, edit_blob_fork_params(edit_path))
end
diff --git a/app/helpers/broadcast_messages_helper.rb b/app/helpers/broadcast_messages_helper.rb
index 881e11b10ea..dda834ee2c5 100644
--- a/app/helpers/broadcast_messages_helper.rb
+++ b/app/helpers/broadcast_messages_helper.rb
@@ -1,14 +1,22 @@
# frozen_string_literal: true
module BroadcastMessagesHelper
+ include Gitlab::Utils::StrongMemoize
+
def current_broadcast_banner_messages
- BroadcastMessage.current_banner_messages(request.path).select do |message|
+ BroadcastMessage.current_banner_messages(
+ current_path: request.path,
+ user_access_level: current_user_access_level_for_project_or_group
+ ).select do |message|
cookies["hide_broadcast_message_#{message.id}"].blank?
end
end
def current_broadcast_notification_message
- not_hidden_messages = BroadcastMessage.current_notification_messages(request.path).select do |message|
+ not_hidden_messages = BroadcastMessage.current_notification_messages(
+ current_path: request.path,
+ user_access_level: current_user_access_level_for_project_or_group
+ ).select do |message|
cookies["hide_broadcast_message_#{message.id}"].blank?
end
not_hidden_messages.last
@@ -61,4 +69,35 @@ module BroadcastMessagesHelper
def broadcast_type_options
BroadcastMessage.broadcast_types.keys.map { |w| [w.humanize, w] }
end
+
+ def target_access_level_options
+ BroadcastMessage::ALLOWED_TARGET_ACCESS_LEVELS.map do |access_level|
+ [Gitlab::Access.human_access(access_level), access_level]
+ end
+ end
+
+ def target_access_levels_display(access_levels)
+ access_levels.map do |access_level|
+ Gitlab::Access.human_access(access_level)
+ end.join(', ')
+ end
+
+ private
+
+ def current_user_access_level_for_project_or_group
+ return if Feature.disabled?(:role_targeted_broadcast_messages, default_enabled: :yaml)
+ return unless current_user.present?
+
+ strong_memoize(:current_user_access_level_for_project_or_group) do
+ if controller.is_a? Projects::ApplicationController
+ next unless @project
+
+ @project.team.max_member_access(current_user.id)
+ elsif controller.is_a? Groups::ApplicationController
+ next unless @group
+
+ @group.max_member_access_for_user(current_user)
+ end
+ end
+ end
end
diff --git a/app/helpers/ci/jobs_helper.rb b/app/helpers/ci/jobs_helper.rb
index c0dca66bac8..14e52b120f3 100644
--- a/app/helpers/ci/jobs_helper.rb
+++ b/app/helpers/ci/jobs_helper.rb
@@ -14,8 +14,7 @@ module Ci
"build_stage" => @build.stage,
"log_state" => '',
"build_options" => javascript_build_options,
- "retry_outdated_job_docs_url" => help_page_path('ci/pipelines/settings', anchor: 'retry-outdated-jobs'),
- "code_quality_help_url" => help_page_path('user/project/merge_requests/code_quality', anchor: 'troubleshooting')
+ "retry_outdated_job_docs_url" => help_page_path('ci/pipelines/settings', anchor: 'retry-outdated-jobs')
}
end
diff --git a/app/helpers/ci/pipelines_helper.rb b/app/helpers/ci/pipelines_helper.rb
index 6104a1256d5..8d2f83409be 100644
--- a/app/helpers/ci/pipelines_helper.rb
+++ b/app/helpers/ci/pipelines_helper.rb
@@ -78,6 +78,37 @@ module Ci
pipeline.stuck?
end
+ def pipelines_list_data(project, list_url)
+ artifacts_endpoint_placeholder = ':pipeline_artifacts_id'
+
+ data = {
+ endpoint: list_url,
+ project_id: project.id,
+ default_branch_name: project.default_branch,
+ params: params.to_json,
+ artifacts_endpoint: downloadable_artifacts_project_pipeline_path(project, artifacts_endpoint_placeholder, format: :json),
+ artifacts_endpoint_placeholder: artifacts_endpoint_placeholder,
+ pipeline_schedule_url: pipeline_schedules_path(project),
+ empty_state_svg_path: image_path('illustrations/pipelines_empty.svg'),
+ error_state_svg_path: image_path('illustrations/pipelines_failed.svg'),
+ no_pipelines_svg_path: image_path('illustrations/pipelines_pending.svg'),
+ can_create_pipeline: can?(current_user, :create_pipeline, project).to_s,
+ new_pipeline_path: can?(current_user, :create_pipeline, project) && new_project_pipeline_path(project),
+ ci_lint_path: can?(current_user, :create_pipeline, project) && project_ci_lint_path(project),
+ reset_cache_path: can?(current_user, :admin_pipeline, project) && reset_cache_project_settings_ci_cd_path(project),
+ has_gitlab_ci: has_gitlab_ci?(project).to_s,
+ pipeline_editor_path: can?(current_user, :create_pipeline, project) && project_ci_pipeline_editor_path(project),
+ suggested_ci_templates: suggested_ci_templates.to_json,
+ ci_runner_settings_path: project_settings_ci_cd_path(project, ci_runner_templates: true, anchor: 'js-runners-settings')
+ }
+
+ experiment(:runners_availability_section, namespace: project.root_ancestor) do |e|
+ e.candidate { data[:any_runners_available] = project.active_runners.exists?.to_s }
+ end
+
+ data
+ end
+
private
def warning_markdown(pipeline)
diff --git a/app/helpers/clusters_helper.rb b/app/helpers/clusters_helper.rb
index 1475a26ca09..959dac1254e 100644
--- a/app/helpers/clusters_helper.rb
+++ b/app/helpers/clusters_helper.rb
@@ -1,17 +1,6 @@
# frozen_string_literal: true
module ClustersHelper
- def create_new_cluster_label(provider: nil)
- case provider
- when 'aws'
- s_('ClusterIntegration|Create new cluster on EKS')
- when 'gcp'
- s_('ClusterIntegration|Create new cluster on GKE')
- else
- s_('ClusterIntegration|Create new cluster')
- end
- end
-
def display_cluster_agents?(clusterable)
clusterable.is_a?(Project)
end
@@ -26,22 +15,19 @@ module ClustersHelper
gcp: { path: image_path('illustrations/logos/google_gke.svg'), text: s_('ClusterIntegration|Google GKE') }
},
clusters_empty_state_image: image_path('illustrations/empty-state/empty-state-clusters.svg'),
+ empty_state_image: image_path('illustrations/empty-state/empty-state-agents.svg'),
empty_state_help_text: clusterable.empty_state_help_text,
- new_cluster_path: clusterable.new_path(tab: 'create'),
+ new_cluster_path: clusterable.new_path,
+ add_cluster_path: clusterable.connect_path,
can_add_cluster: clusterable.can_add_cluster?.to_s,
- can_admin_cluster: clusterable.can_admin_cluster?.to_s
- }
- end
-
- def js_clusters_data(clusterable)
- {
- default_branch_name: clusterable.default_branch,
- empty_state_image: image_path('illustrations/empty-state/empty-state-agents.svg'),
- project_path: clusterable.full_path,
- add_cluster_path: clusterable.new_path(tab: 'add'),
+ can_admin_cluster: clusterable.can_admin_cluster?.to_s,
+ display_cluster_agents: display_cluster_agents?(clusterable).to_s,
+ certificate_based_clusters_enabled: Feature.enabled?(:certificate_based_clusters, clusterable, default_enabled: :yaml, type: :ops).to_s,
+ default_branch_name: default_branch_name(clusterable),
+ project_path: clusterable_project_path(clusterable),
kas_address: Gitlab::Kas.external_url,
gitlab_version: Gitlab.version_info
- }.merge(js_clusters_list_data(clusterable))
+ }
end
def js_cluster_form_data(cluster, can_edit)
@@ -122,4 +108,14 @@ module ClustersHelper
def can_admin_cluster?(user, cluster)
can?(user, :admin_cluster, cluster)
end
+
+ private
+
+ def default_branch_name(clusterable)
+ clusterable.default_branch if clusterable.is_a?(Project)
+ end
+
+ def clusterable_project_path(clusterable)
+ clusterable.full_path if clusterable.is_a?(Project)
+ end
end
diff --git a/app/helpers/commits_helper.rb b/app/helpers/commits_helper.rb
index 43e727ac483..c78e906e052 100644
--- a/app/helpers/commits_helper.rb
+++ b/app/helpers/commits_helper.rb
@@ -182,6 +182,19 @@ module CommitsHelper
project_commit_path(project, DEFAULT_SHA).sub("/#{DEFAULT_SHA}", '/$COMMIT_SHA')
end
+ def diff_mode_swap_button(mode, file_hash)
+ icon = mode == 'raw' ? 'doc-code' : 'doc-text'
+ entity = mode == 'raw' ? 'toHideBtn' : 'toShowBtn'
+ title = "Display #{mode} diff"
+
+ link_to("##{mode}-diff-#{file_hash}",
+ class: "btn gl-button btn-default btn-file-option has-tooltip btn-show-#{mode}-diff",
+ title: title,
+ data: { file_hash: file_hash, diff_toggle_entity: entity }) do
+ sprite_icon(icon)
+ end
+ end
+
protected
# Private: Returns a link to a person. If the person has a matching user and
diff --git a/app/helpers/container_expiration_policies_helper.rb b/app/helpers/container_expiration_policies_helper.rb
index 52f68ac53f0..0005682e979 100644
--- a/app/helpers/container_expiration_policies_helper.rb
+++ b/app/helpers/container_expiration_policies_helper.rb
@@ -25,8 +25,7 @@ module ContainerExpirationPoliciesHelper
end
end
- def container_expiration_policies_historic_entry_enabled?(project)
- Gitlab::CurrentSettings.container_expiration_policies_enable_historic_entries ||
- Feature.enabled?(:container_expiration_policies_historic_entry, project)
+ def container_expiration_policies_historic_entry_enabled?
+ Gitlab::CurrentSettings.container_expiration_policies_enable_historic_entries
end
end
diff --git a/app/helpers/container_registry_helper.rb b/app/helpers/container_registry_helper.rb
index 1b77b639ce1..255b8183164 100644
--- a/app/helpers/container_registry_helper.rb
+++ b/app/helpers/container_registry_helper.rb
@@ -2,8 +2,7 @@
module ContainerRegistryHelper
def container_registry_expiration_policies_throttling?
- Feature.enabled?(:container_registry_expiration_policies_throttling) &&
- ContainerRegistry::Client.supports_tag_delete?
+ Feature.enabled?(:container_registry_expiration_policies_throttling, default_enabled: :yaml)
end
def container_repository_gid_prefix
diff --git a/app/helpers/dashboard_helper.rb b/app/helpers/dashboard_helper.rb
index f0e1f252917..bcb1f63840d 100644
--- a/app/helpers/dashboard_helper.rb
+++ b/app/helpers/dashboard_helper.rb
@@ -15,6 +15,10 @@ module DashboardHelper
merge_requests_dashboard_path(reviewer_username: current_user.username)
end
+ def attention_requested_mrs_dashboard_path
+ merge_requests_dashboard_path(attention: current_user.username)
+ end
+
def dashboard_nav_links
@dashboard_nav_links ||= get_dashboard_nav_links
end
diff --git a/app/helpers/deploy_tokens_helper.rb b/app/helpers/deploy_tokens_helper.rb
index d6fbe0b6b45..560d2fcd29f 100644
--- a/app/helpers/deploy_tokens_helper.rb
+++ b/app/helpers/deploy_tokens_helper.rb
@@ -16,4 +16,11 @@ module DeployTokensHelper
Gitlab.config.packages.enabled &&
can?(current_user, :read_package, group_or_project)
end
+
+ def deploy_token_revoke_button_data(token:, group_or_project:)
+ {
+ token: token.to_json(only: [:id, :name]),
+ revoke_path: revoke_deploy_token_path(group_or_project, token)
+ }
+ end
end
diff --git a/app/helpers/diff_helper.rb b/app/helpers/diff_helper.rb
index 2b5f726dad1..100d5c0281c 100644
--- a/app/helpers/diff_helper.rb
+++ b/app/helpers/diff_helper.rb
@@ -28,7 +28,7 @@ module DiffHelper
end
def diff_options
- options = { ignore_whitespace_change: hide_whitespace?, expanded: diffs_expanded? }
+ options = { ignore_whitespace_change: hide_whitespace?, expanded: diffs_expanded?, use_extra_viewer_as_main: true }
if action_name == 'diff_for_path'
options[:expanded] = true
@@ -74,7 +74,7 @@ module DiffHelper
end
def diff_link_number(line_type, match, text)
- line_type == match ? " " : text
+ line_type == match || text == 0 ? " " : text
end
def parallel_diff_discussions(left, right, diff_file)
diff --git a/app/helpers/dropdowns_helper.rb b/app/helpers/dropdowns_helper.rb
index 0092743f96e..a910d3d7c9d 100644
--- a/app/helpers/dropdowns_helper.rb
+++ b/app/helpers/dropdowns_helper.rb
@@ -129,7 +129,7 @@ module DropdownsHelper
end
def dropdown_loading
- spinner = loading_icon(container: true, size: "md", css_class: "gl-mt-7")
+ spinner = gl_loading_icon(size: "md", css_class: "gl-mt-7")
content_tag(:div, spinner, class: "dropdown-loading")
end
end
diff --git a/app/helpers/explore_helper.rb b/app/helpers/explore_helper.rb
index 026dbd60ac6..1defe480059 100644
--- a/app/helpers/explore_helper.rb
+++ b/app/helpers/explore_helper.rb
@@ -19,26 +19,10 @@ module ExploreHelper
request_path_with_options(options)
end
- def filter_audit_path(options = {})
- exist_opts = {
- entity_type: params[:entity_type],
- entity_id: params[:entity_id],
- created_before: params[:created_before],
- created_after: params[:created_after],
- sort: params[:sort]
- }
- options = exist_opts.merge(options).delete_if { |key, value| value.blank? }
- request_path_with_options(options)
- end
-
def filter_groups_path(options = {})
request_path_with_options(options)
end
- def explore_controller?
- controller.class.name.split("::").first == "Explore"
- end
-
def explore_nav_links
@explore_nav_links ||= get_explore_nav_links
end
@@ -47,14 +31,27 @@ module ExploreHelper
explore_nav_links.include?(link)
end
- def any_explore_nav_link?(links)
- links.any? { |link| explore_nav_link?(link) }
- end
-
def public_visibility_restricted?
Gitlab::VisibilityLevel.public_visibility_restricted?
end
+ def projects_filter_items
+ [
+ { value: _('Any'), text: _('Any'), href: filter_projects_path(visibility_level: nil) },
+ *Gitlab::VisibilityLevel.options.keys.map do |key|
+ {
+ value: key,
+ text: key,
+ href: filter_projects_path(visibility_level: Gitlab::VisibilityLevel.options[key])
+ }
+ end
+ ]
+ end
+
+ def projects_filter_selected(visibility_level)
+ visibility_level.present? ? visibility_level_label(visibility_level.to_i) : _('Any')
+ end
+
private
def get_explore_nav_links
diff --git a/app/helpers/groups/crm_settings_helper.rb b/app/helpers/groups/crm_settings_helper.rb
index ab47ec40b13..d7ca25a9d1b 100644
--- a/app/helpers/groups/crm_settings_helper.rb
+++ b/app/helpers/groups/crm_settings_helper.rb
@@ -2,7 +2,7 @@
module Groups
module CrmSettingsHelper
- def crm_feature_flag_enabled?(group)
+ def crm_feature_available?(group)
Feature.enabled?(:customer_relations, group)
end
end
diff --git a/app/helpers/groups/group_members_helper.rb b/app/helpers/groups/group_members_helper.rb
index 07ab246b089..a719d80a1a1 100644
--- a/app/helpers/groups/group_members_helper.rb
+++ b/app/helpers/groups/group_members_helper.rb
@@ -9,10 +9,6 @@ module Groups::GroupMembersHelper
{ multiple: true, class: 'input-clamp qa-member-select-field ', scope: :all, email_user: true }
end
- def render_invite_member_for_group(group, default_access_level)
- render 'shared/members/invite_member', submit_url: group_group_members_path(group), access_levels: group.access_level_roles, default_access_level: default_access_level
- end
-
def group_members_app_data(group, members:, invited:, access_requests:)
{
user: group_members_list_data(group, members, { param_name: :page, params: { invited_members_page: nil, search_invited: nil } }),
diff --git a/app/helpers/icons_helper.rb b/app/helpers/icons_helper.rb
index 32d808c960c..6f7ac069fe4 100644
--- a/app/helpers/icons_helper.rb
+++ b/app/helpers/icons_helper.rb
@@ -49,13 +49,39 @@ module IconsHelper
end
end
- def loading_icon(container: false, color: 'orange', size: 'sm', css_class: nil)
- css_classes = ['gl-spinner', "gl-spinner-#{color}", "gl-spinner-#{size}"]
- css_classes << "#{css_class}" unless css_class.blank?
-
- spinner = content_tag(:span, "", { class: css_classes.join(' '), aria: { label: _('Loading') } })
-
- container == true ? content_tag(:div, spinner, { class: 'gl-spinner-container' }) : spinner
+ # Creates a GitLab UI loading icon/spinner.
+ #
+ # Examples:
+ # # Default
+ # gl_loading_icon
+ #
+ # # Sizes
+ # gl_loading_icon(size: 'md')
+ # gl_loading_icon(size: 'lg')
+ # gl_loading_icon(size: 'xl')
+ #
+ # # Colors
+ # gl_loading_icon(color: 'light')
+ #
+ # # Block/Inline
+ # gl_loading_icon(inline: true)
+ #
+ # # Custom classes
+ # gl_loading_icon(css_class: "foo-bar")
+ #
+ # See also https://gitlab-org.gitlab.io/gitlab-ui/?path=/story/base-loading-icon--default
+ def gl_loading_icon(inline: false, color: 'dark', size: 'sm', css_class: nil)
+ spinner = content_tag(:span, "", {
+ class: %[gl-spinner gl-spinner-#{color} gl-spinner-#{size} gl-vertical-align-text-bottom!],
+ aria: { label: _('Loading') }
+ })
+
+ container_classes = ['gl-spinner-container']
+ container_classes << css_class unless css_class.blank?
+ content_tag(inline ? :span : :div, spinner, {
+ class: container_classes,
+ role: 'status'
+ })
end
def external_snippet_icon(name)
diff --git a/app/helpers/integrations_helper.rb b/app/helpers/integrations_helper.rb
index f5ba978e860..b960ed46ba9 100644
--- a/app/helpers/integrations_helper.rb
+++ b/app/helpers/integrations_helper.rb
@@ -1,6 +1,35 @@
# frozen_string_literal: true
module IntegrationsHelper
+ def integration_event_title(event)
+ case event
+ when "push", "push_events"
+ _("Push")
+ when "tag_push", "tag_push_events"
+ _("Tag push")
+ when "note", "note_events"
+ _("Note")
+ when "confidential_note", "confidential_note_events"
+ _("Confidential note")
+ when "issue", "issue_events"
+ _("Issue")
+ when "confidential_issue", "confidential_issue_events"
+ _("Confidential issue")
+ when "merge_request", "merge_request_events"
+ _("Merge request")
+ when "pipeline", "pipeline_events"
+ _("Pipeline")
+ when "wiki_page", "wiki_page_events"
+ _("Wiki page")
+ when "commit", "commit_events"
+ _("Commit")
+ when "deployment"
+ _("Deployment")
+ when "alert"
+ _("Alert")
+ end
+ end
+
def integration_event_description(integration, event)
case integration
when Integrations::Jira
@@ -75,7 +104,8 @@ module IntegrationsHelper
form_data = {
id: integration.id,
show_active: integration.show_active_box?.to_s,
- activated: (integration.active || integration.new_record?).to_s,
+ activated: (integration.active || (integration.new_record? && integration.activate_disabled_reason.nil?)).to_s,
+ activate_disabled: integration.activate_disabled_reason.present?.to_s,
type: integration.to_param,
merge_request_events: integration.merge_requests_events.to_s,
commit_events: integration.commit_events.to_s,
@@ -83,6 +113,7 @@ module IntegrationsHelper
comment_detail: integration.comment_detail,
learn_more_path: integrations_help_page_path,
trigger_events: trigger_events_for_integration(integration),
+ sections: integration.sections.to_json,
fields: fields_for_integration(integration),
inherit_from_id: integration.inherit_from_id,
integration_level: integration_level(integration),
diff --git a/app/helpers/invite_members_helper.rb b/app/helpers/invite_members_helper.rb
index 1f225e9c0e5..a2dde29e25d 100644
--- a/app/helpers/invite_members_helper.rb
+++ b/app/helpers/invite_members_helper.rb
@@ -6,7 +6,7 @@ module InviteMembersHelper
def can_invite_members_for_project?(project)
# do not use the can_admin_project_member? helper here due to structure of the view and how membership_locked?
# is leveraged for inviting groups
- Feature.enabled?(:invite_members_group_modal, project.group, default_enabled: :yaml) && can?(current_user, :admin_project_member, project)
+ can?(current_user, :admin_project_member, project)
end
def invite_accepted_notice(member)
@@ -73,7 +73,7 @@ module InviteMembersHelper
def show_invite_members_for_task?(source)
return unless current_user
- invite_for_help_continuous_onboarding = source.is_a?(Project) && experiment(:invite_for_help_continuous_onboarding, namespace: source.namespace).variant.name == 'candidate'
+ invite_for_help_continuous_onboarding = source.is_a?(Project) && experiment(:invite_for_help_continuous_onboarding, namespace: source.namespace).assigned.name == 'candidate'
params[:open_modal] == 'invite_members_for_task' || invite_for_help_continuous_onboarding
end
diff --git a/app/helpers/issues_helper.rb b/app/helpers/issues_helper.rb
index 8e7f5060412..298162fe970 100644
--- a/app/helpers/issues_helper.rb
+++ b/app/helpers/issues_helper.rb
@@ -169,7 +169,7 @@ module IssuesHelper
end
def issue_header_actions_data(project, issuable, current_user)
- new_issuable_params = { issue: { description: _('Related to #%{issue_id}.') % { issue_id: issuable.iid } + "\n\n" } }
+ new_issuable_params = { issue: {}, add_related_issue: issuable.iid }
if issuable.incident?
new_issuable_params[:issuable_template] = 'incident'
new_issuable_params[:issue][:issue_type] = 'incident'
@@ -209,7 +209,7 @@ module IssuesHelper
}
end
- def project_issues_list_data(project, current_user, finder)
+ def project_issues_list_data(project, current_user)
common_issues_list_data(project, current_user).merge(
can_bulk_update: can?(current_user, :admin_issue, project).to_s,
can_edit: can?(current_user, :admin_project, project).to_s,
@@ -223,7 +223,7 @@ module IssuesHelper
is_project: true.to_s,
markdown_help_path: help_page_path('user/markdown'),
max_attachment_size: number_to_human_size(Gitlab::CurrentSettings.max_attachment_size.megabytes),
- new_issue_path: new_project_issue_path(project, issue: { milestone_id: finder.milestones.first.try(:id) }),
+ new_issue_path: new_project_issue_path(project),
project_import_jira_path: project_import_jira_path(project),
quick_actions_help_path: help_page_path('user/project/quick_actions'),
releases_path: project_releases_path(project, format: :json),
diff --git a/app/helpers/jira_connect_helper.rb b/app/helpers/jira_connect_helper.rb
index 9a0f0944fd1..67b85b26f9e 100644
--- a/app/helpers/jira_connect_helper.rb
+++ b/app/helpers/jira_connect_helper.rb
@@ -9,12 +9,38 @@ module JiraConnectHelper
subscriptions: subscriptions.map { |s| serialize_subscription(s) }.to_json,
subscriptions_path: jira_connect_subscriptions_path,
users_path: current_user ? nil : jira_connect_users_path, # users_path is used to determine if user is signed in
- gitlab_user_path: current_user ? user_path(current_user) : nil
+ gitlab_user_path: current_user ? user_path(current_user) : nil,
+ oauth_metadata: Feature.enabled?(:jira_connect_oauth, current_user) ? jira_connect_oauth_data.to_json : nil
}
end
private
+ def jira_connect_oauth_data
+ oauth_authorize_url = oauth_authorization_url(
+ client_id: ENV['JIRA_CONNECT_OAUTH_CLIENT_ID'],
+ response_type: 'code',
+ scope: 'api',
+ redirect_uri: jira_connect_oauth_callbacks_url,
+ state: oauth_state
+ )
+
+ {
+ oauth_authorize_url: oauth_authorize_url,
+ oauth_token_url: oauth_token_url,
+ state: oauth_state,
+ oauth_token_payload: {
+ grant_type: :authorization_code,
+ client_id: ENV['JIRA_CONNECT_OAUTH_CLIENT_ID'],
+ redirect_uri: jira_connect_oauth_callbacks_url
+ }
+ }
+ end
+
+ def oauth_state
+ @oauth_state ||= SecureRandom.hex(32)
+ end
+
def serialize_subscription(subscription)
{
group: {
diff --git a/app/helpers/labels_helper.rb b/app/helpers/labels_helper.rb
index 2150729cb2a..877785c9eaf 100644
--- a/app/helpers/labels_helper.rb
+++ b/app/helpers/labels_helper.rb
@@ -61,7 +61,7 @@ module LabelsHelper
render_label_text(
label.name,
suffix: suffix,
- css_class: "gl-label-text #{text_color_class_for_bg(label.color)}",
+ css_class: "gl-label-text #{label.text_color_class}",
bg_color: label.color
)
end
@@ -114,30 +114,8 @@ module LabelsHelper
end
end
- def text_color_class_for_bg(bg_color)
- if light_color?(bg_color)
- 'gl-label-text-dark'
- else
- 'gl-label-text-light'
- end
- end
-
def text_color_for_bg(bg_color)
- if light_color?(bg_color)
- '#333333'
- else
- '#FFFFFF'
- end
- end
-
- def light_color?(color)
- if color.length == 4
- r, g, b = color[1, 4].scan(/./).map { |v| (v * 2).hex }
- else
- r, g, b = color[1, 7].scan(/.{2}/).map(&:hex)
- end
-
- (r + g + b) > 500
+ ::Gitlab::Color.of(bg_color).contrast
end
def labels_filter_path_with_defaults(only_group_labels: false, include_ancestor_groups: true, include_descendant_groups: false)
diff --git a/app/helpers/lazy_image_tag_helper.rb b/app/helpers/lazy_image_tag_helper.rb
index 0c5744b46ae..d0bdaaae5f8 100644
--- a/app/helpers/lazy_image_tag_helper.rb
+++ b/app/helpers/lazy_image_tag_helper.rb
@@ -1,12 +1,15 @@
# frozen_string_literal: true
module LazyImageTagHelper
+ include PreferencesHelper
+
def placeholder_image
"data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="
end
# Override the default ActionView `image_tag` helper to support lazy-loading
def image_tag(source, options = {})
+ source = options[:dark_variant] if options[:dark_variant] && user_application_dark_mode?
options = options.symbolize_keys
unless options.delete(:lazy) == false
diff --git a/app/helpers/learn_gitlab_helper.rb b/app/helpers/learn_gitlab_helper.rb
index 7dfd9ed47e3..60f3b12d736 100644
--- a/app/helpers/learn_gitlab_helper.rb
+++ b/app/helpers/learn_gitlab_helper.rb
@@ -1,6 +1,10 @@
# frozen_string_literal: true
module LearnGitlabHelper
+ IMAGE_PATH_PLAN = "learn_gitlab/section_plan.svg"
+ IMAGE_PATH_DEPLOY = "learn_gitlab/section_deploy.svg"
+ IMAGE_PATH_WORKSPACE = "learn_gitlab/section_workspace.svg"
+
def learn_gitlab_enabled?(project)
return false unless current_user
@@ -25,19 +29,7 @@ module LearnGitlabHelper
def onboarding_actions_data(project)
attributes = onboarding_progress(project).attributes.symbolize_keys
- urls_to_use = nil
-
- experiment(
- :change_continuous_onboarding_link_urls,
- namespace: project.namespace,
- actor: current_user,
- sticky_to: project.namespace
- ) do |e|
- e.control { urls_to_use = action_urls }
- e.candidate { urls_to_use = new_action_urls(project) }
- end
-
- urls_to_use.to_h do |action, url|
+ action_urls(project).to_h do |action, url|
[
action,
url: url,
@@ -50,13 +42,13 @@ module LearnGitlabHelper
def onboarding_sections_data
{
workspace: {
- svg: image_path("learn_gitlab/section_workspace.svg")
+ svg: image_path(IMAGE_PATH_WORKSPACE)
},
plan: {
- svg: image_path("learn_gitlab/section_plan.svg")
+ svg: image_path(IMAGE_PATH_PLAN)
},
deploy: {
- svg: image_path("learn_gitlab/section_deploy.svg")
+ svg: image_path(IMAGE_PATH_DEPLOY)
}
}
end
@@ -65,22 +57,20 @@ module LearnGitlabHelper
{ name: project.name }
end
- def action_urls
- LearnGitlab::Onboarding::ACTION_ISSUE_IDS.transform_values { |id| project_issue_url(learn_gitlab_project, id) }
- .merge(LearnGitlab::Onboarding::ACTION_DOC_URLS)
- end
-
- def new_action_urls(project)
- action_urls.merge(
+ def action_urls(project)
+ action_issue_urls.merge(
issue_created: project_issues_path(project),
git_write: project_path(project),
- pipeline_created: project_pipelines_path(project),
merge_request_created: project_merge_requests_path(project),
user_added: project_members_url(project),
security_scan_enabled: project_security_configuration_path(project)
)
end
+ def action_issue_urls
+ LearnGitlab::Onboarding::ACTION_ISSUE_IDS.transform_values { |id| project_issue_url(learn_gitlab_project, id) }
+ end
+
def learn_gitlab_project
@learn_gitlab_project ||= LearnGitlab::Project.new(current_user).project
end
diff --git a/app/helpers/listbox_helper.rb b/app/helpers/listbox_helper.rb
index d24680bc0b0..16caf862c7b 100644
--- a/app/helpers/listbox_helper.rb
+++ b/app/helpers/listbox_helper.rb
@@ -16,8 +16,10 @@ module ListboxHelper
# the sort key), `text` is the user-facing string for the item, and `href` is
# the path to redirect to when that item is selected.
#
- # The `selected` parameter is the currently selected `value`, and must
- # correspond to one of the `items`, or be `nil`. When `selected.nil?`, the first item is selected.
+ # The `selected` parameter is the currently selected `value`, and should
+ # correspond to one of the `items`, or be `nil`. When `selected.nil?` or
+ # a value which does not correspond to one of the items, the first item is
+ # selected.
#
# The final parameter `html_options` applies arbitrary attributes to the
# returned tag. Some of these are passed to the underlying Vue component as
@@ -37,9 +39,12 @@ module ListboxHelper
webpack_bundle_tag 'redirect_listbox'
end
- selected ||= items.first[:value]
selected_option = items.find { |opt| opt[:value] == selected }
- raise ArgumentError, "cannot find #{selected} in #{items}" unless selected_option
+
+ unless selected_option
+ selected_option = items.first
+ selected = selected_option[:value]
+ end
button = button_tag(type: :button, class: DROPDOWN_BUTTON_CLASSES) do
content_tag(:span, selected_option[:text], class: DROPDOWN_INNER_CLASS) +
diff --git a/app/helpers/markup_helper.rb b/app/helpers/markup_helper.rb
index f16d9f6325b..7a4cc61af79 100644
--- a/app/helpers/markup_helper.rb
+++ b/app/helpers/markup_helper.rb
@@ -127,7 +127,7 @@ module MarkupHelper
text = wiki_page.content
return '' unless text.present?
- context = render_wiki_content_context(@wiki, wiki_page, context)
+ context = render_wiki_content_context(wiki_page.wiki, wiki_page, context)
html = markup_unsafe(wiki_page.path, text, context)
prepare_for_rendering(html, context)
@@ -181,7 +181,8 @@ module MarkupHelper
wiki: wiki,
repository: wiki.repository,
page_slug: wiki_page.slug,
- issuable_reference_expansion_enabled: true
+ issuable_reference_expansion_enabled: true,
+ requested_path: wiki_page.path
).merge(render_wiki_content_context_container(wiki))
end
@@ -263,7 +264,7 @@ module MarkupHelper
end
def asciidoc_unsafe(text, context = {})
- context.merge!(
+ context.reverse_merge!(
commit: @commit,
ref: @ref,
requested_path: @path
diff --git a/app/helpers/merge_requests_helper.rb b/app/helpers/merge_requests_helper.rb
index abb7128470f..84a3802c72c 100644
--- a/app/helpers/merge_requests_helper.rb
+++ b/app/helpers/merge_requests_helper.rb
@@ -150,11 +150,20 @@ module MergeRequestsHelper
review_requested_count = review_requested_merge_requests_count
total_count = assigned_count + review_requested_count
- {
+ counts = {
assigned: assigned_count,
review_requested: review_requested_count,
total: total_count
}
+
+ if Feature.enabled?(:mr_attention_requests, default_enabled: :yaml)
+ attention_requested_count = attention_requested_merge_requests_count
+
+ counts[:attention_requested_count] = attention_requested_count
+ counts[:total] = attention_requested_count
+ end
+
+ counts
end
end
@@ -205,6 +214,10 @@ module MergeRequestsHelper
current_user.review_requested_open_merge_requests_count
end
+ def attention_requested_merge_requests_count
+ current_user.attention_requested_open_merge_requests_count
+ end
+
def default_suggestion_commit_message
@project.suggestion_commit_message.presence || Gitlab::Suggestions::CommitMessage::DEFAULT_SUGGESTION_COMMIT_MESSAGE
end
diff --git a/app/helpers/packages_helper.rb b/app/helpers/packages_helper.rb
index 402a363349f..01075862618 100644
--- a/app/helpers/packages_helper.rb
+++ b/app/helpers/packages_helper.rb
@@ -50,8 +50,6 @@ module PackagesHelper
Gitlab.com? &&
Gitlab.config.registry.enabled &&
project.feature_available?(:container_registry, current_user) &&
- !Gitlab::CurrentSettings.container_expiration_policies_enable_historic_entries &&
- Feature.enabled?(:container_expiration_policies_historic_entry, project) &&
project.container_expiration_policy.nil? &&
project.container_repositories.exists?
end
diff --git a/app/helpers/pagination_helper.rb b/app/helpers/pagination_helper.rb
index 3167142e193..88bf09f0c03 100644
--- a/app/helpers/pagination_helper.rb
+++ b/app/helpers/pagination_helper.rb
@@ -22,4 +22,8 @@ module PaginationHelper
def paginate_with_count(collection, remote: nil, total_pages: nil)
paginate(collection, remote: remote, theme: 'gitlab', total_pages: total_pages)
end
+
+ def page_size
+ Kaminari.config.default_per_page
+ end
end
diff --git a/app/helpers/preferences_helper.rb b/app/helpers/preferences_helper.rb
index 17450e5b26b..6a8c39b5b15 100644
--- a/app/helpers/preferences_helper.rb
+++ b/app/helpers/preferences_helper.rb
@@ -62,6 +62,10 @@ module PreferencesHelper
@user_application_theme ||= Gitlab::Themes.for_user(current_user).css_class
end
+ def user_application_dark_mode?
+ user_application_theme == 'gl-dark'
+ end
+
def user_application_theme_css_filename
@user_application_theme_css_filename ||= Gitlab::Themes.for_user(current_user).css_filename
end
diff --git a/app/helpers/projects/cluster_agents_helper.rb b/app/helpers/projects/cluster_agents_helper.rb
index 43d520d0eab..c17cb787c9f 100644
--- a/app/helpers/projects/cluster_agents_helper.rb
+++ b/app/helpers/projects/cluster_agents_helper.rb
@@ -7,7 +7,9 @@ module Projects::ClusterAgentsHelper
agent_name: agent_name,
can_admin_vulnerability: can?(current_user, :admin_vulnerability, project).to_s,
empty_state_svg_path: image_path('illustrations/operations-dashboard_empty.svg'),
- project_path: project.full_path
+ project_path: project.full_path,
+ kas_address: Gitlab::Kas.external_url,
+ can_admin_cluster: can?(current_user, :admin_cluster, project).to_s
}
end
end
diff --git a/app/helpers/projects/error_tracking_helper.rb b/app/helpers/projects/error_tracking_helper.rb
index 5be4f67bde8..471565d162c 100644
--- a/app/helpers/projects/error_tracking_helper.rb
+++ b/app/helpers/projects/error_tracking_helper.rb
@@ -12,7 +12,8 @@ module Projects::ErrorTrackingHelper
'error-tracking-enabled' => error_tracking_enabled.to_s,
'project-path' => project.full_path,
'list-path' => project_error_tracking_index_path(project),
- 'illustration-path' => image_path('illustrations/cluster_popover.svg')
+ 'illustration-path' => image_path('illustrations/cluster_popover.svg'),
+ 'show-integrated-tracking-disabled-alert' => show_integrated_tracking_disabled_alert?(project).to_s
}
end
@@ -27,4 +28,15 @@ module Projects::ErrorTrackingHelper
'issue-stack-trace-path' => stack_trace_project_error_tracking_index_path(*opts)
}
end
+
+ private
+
+ def show_integrated_tracking_disabled_alert?(project)
+ return false if ::Feature.enabled?(:integrated_error_tracking, project)
+
+ setting ||= project.error_tracking_setting ||
+ project.build_error_tracking_setting
+
+ setting.integrated_enabled?
+ end
end
diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb
index 6098ef63ec3..8a75f545a32 100644
--- a/app/helpers/projects_helper.rb
+++ b/app/helpers/projects_helper.rb
@@ -160,7 +160,7 @@ module ProjectsHelper
end
def link_to_autodeploy_doc
- link_to _('About auto deploy'), help_page_path('topics/autodevops/stages.md', anchor: 'auto-deploy'), target: '_blank'
+ link_to _('About auto deploy'), help_page_path('topics/autodevops/stages.md', anchor: 'auto-deploy'), target: '_blank', rel: 'noopener'
end
def autodeploy_flash_notice(branch_name)
@@ -431,19 +431,26 @@ module ProjectsHelper
end
def import_from_bitbucket_message
- link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: help_page_path("integration/bitbucket") }
+ configure_oauth_import_message('Bitbucket', help_page_path("integration/bitbucket"))
+ end
+
+ def import_from_gitlab_message
+ configure_oauth_import_message('GitLab.com', help_page_path("integration/gitlab"))
+ end
+ private
+
+ def configure_oauth_import_message(provider, help_url)
str = if current_user.admin?
- 'ImportProjects|To enable importing projects from Bitbucket, as administrator you need to configure %{link_start}OAuth integration%{link_end}'
+ 'ImportProjects|To enable importing projects from %{provider}, as administrator you need to configure %{link_start}OAuth integration%{link_end}'
else
- 'ImportProjects|To enable importing projects from Bitbucket, ask your GitLab administrator to configure %{link_start}OAuth integration%{link_end}'
+ 'ImportProjects|To enable importing projects from %{provider}, ask your GitLab administrator to configure %{link_start}OAuth integration%{link_end}'
end
- s_(str).html_safe % { link_start: link_start, link_end: '</a>'.html_safe }
+ link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: help_url }
+ s_(str).html_safe % { provider: provider, link_start: link_start, link_end: '</a>'.html_safe }
end
- private
-
def tab_ability_map
{
cycle_analytics: :read_cycle_analytics,
diff --git a/app/helpers/routing/pseudonymization_helper.rb b/app/helpers/routing/pseudonymization_helper.rb
index fd9907edc37..f1fafd563ce 100644
--- a/app/helpers/routing/pseudonymization_helper.rb
+++ b/app/helpers/routing/pseudonymization_helper.rb
@@ -15,7 +15,7 @@ module Routing
end
def mask_params
- return default_root_url + @request.original_fullpath unless has_maskable_params?
+ return @request.original_url unless has_maskable_params?
masked_params = @request.path_parameters.to_h do |key, value|
case key
@@ -66,10 +66,6 @@ module Routing
query_string_hash
end
-
- def default_root_url
- Gitlab::Routing.url_helpers.root_url(only_path: false)
- end
end
def masked_page_url(group:, project:)
diff --git a/app/helpers/sessions_helper.rb b/app/helpers/sessions_helper.rb
index e9466a9e97e..f0389000eb3 100644
--- a/app/helpers/sessions_helper.rb
+++ b/app/helpers/sessions_helper.rb
@@ -5,7 +5,7 @@ module SessionsHelper
def recently_confirmed_com?
strong_memoize(:recently_confirmed_com) do
- ::Gitlab.dev_env_or_com? &&
+ ::Gitlab.com? &&
!!flash[:notice]&.include?(t(:confirmed, scope: [:devise, :confirmations]))
end
end
diff --git a/app/helpers/sorting_helper.rb b/app/helpers/sorting_helper.rb
index fb30e8ca059..4db14d5cc4d 100644
--- a/app/helpers/sorting_helper.rb
+++ b/app/helpers/sorting_helper.rb
@@ -328,6 +328,16 @@ module SortingHelper
sort_direction_button(url, reverse_sort, sort_value)
end
+
+ def admin_users_sort_options(path_params)
+ users_sort_options_hash.map do |value, text|
+ {
+ value: value,
+ text: text,
+ href: admin_users_path(sort: value, **path_params)
+ }
+ end
+ end
end
SortingHelper.prepend_mod_with('SortingHelper')
diff --git a/app/helpers/storage_helper.rb b/app/helpers/storage_helper.rb
index 34ba66db444..a075ccc38f5 100644
--- a/app/helpers/storage_helper.rb
+++ b/app/helpers/storage_helper.rb
@@ -25,16 +25,17 @@ module StorageHelper
end
def storage_enforcement_banner_info(namespace)
+ return unless can?(current_user, :admin_namespace, namespace)
return if namespace.paid?
return unless namespace.storage_enforcement_date && namespace.storage_enforcement_date >= Date.today
return if user_dismissed_storage_enforcement_banner?(namespace)
{
text: html_escape_once(s_("UsageQuota|From %{storage_enforcement_date} storage limits will apply to this namespace. " \
- "View and manage your usage in %{strong_start}Group Settings &gt; Usage quotas%{strong_end}.")).html_safe %
- { storage_enforcement_date: namespace.storage_enforcement_date, strong_start: "<strong>".html_safe, strong_end: "</strong>".html_safe },
+ "View and manage your usage in %{strong_start}%{namespace_type} settings &gt; Usage quotas%{strong_end}.")).html_safe %
+ { storage_enforcement_date: namespace.storage_enforcement_date, strong_start: "<strong>".html_safe, strong_end: "</strong>".html_safe, namespace_type: namespace.type },
variant: 'warning',
- callouts_path: group_callouts_path,
+ callouts_path: namespace.user_namespace? ? callouts_path : group_callouts_path,
callouts_feature_name: storage_enforcement_banner_user_callouts_feature_name(namespace),
learn_more_link: link_to(_('Learn more.'), help_page_path('/'), rel: 'noopener noreferrer', target: '_blank') # TBD: https://gitlab.com/gitlab-org/gitlab/-/issues/350632
}
@@ -52,13 +53,17 @@ module StorageHelper
return :first if days_to_enforcement_date > 30
return :second if days_to_enforcement_date > 15 && days_to_enforcement_date <= 30
return :third if days_to_enforcement_date > 7 && days_to_enforcement_date <= 15
- return :fourth if days_to_enforcement_date > 0 && days_to_enforcement_date <= 7
+ return :fourth if days_to_enforcement_date >= 0 && days_to_enforcement_date <= 7
end
def user_dismissed_storage_enforcement_banner?(namespace)
return false unless current_user
- current_user.dismissed_callout_for_group?(feature_name: storage_enforcement_banner_user_callouts_feature_name(namespace),
- group: namespace)
+ if namespace.user_namespace?
+ current_user.dismissed_callout?(feature_name: storage_enforcement_banner_user_callouts_feature_name(namespace))
+ else
+ current_user.dismissed_callout_for_group?(feature_name: storage_enforcement_banner_user_callouts_feature_name(namespace),
+ group: namespace)
+ end
end
end
diff --git a/app/helpers/submodule_helper.rb b/app/helpers/submodule_helper.rb
index f1e0be3a622..d3af6a00181 100644
--- a/app/helpers/submodule_helper.rb
+++ b/app/helpers/submodule_helper.rb
@@ -32,7 +32,7 @@ module SubmoduleHelper
namespace.sub!(%r{\A/}, '')
project.rstrip!
- project.sub!(/\.git\z/, '')
+ project.delete_suffix!('.git')
if self_url?(url, namespace, project)
[
diff --git a/app/helpers/todos_helper.rb b/app/helpers/todos_helper.rb
index 79767ca76b7..60bf79f3114 100644
--- a/app/helpers/todos_helper.rb
+++ b/app/helpers/todos_helper.rb
@@ -18,7 +18,7 @@ module TodosHelper
when Todo::ASSIGNED then todo.self_added? ? 'assigned' : 'assigned you'
when Todo::REVIEW_REQUESTED then 'requested a review of'
when Todo::MENTIONED then "mentioned #{todo_action_subject(todo)} on"
- when Todo::BUILD_FAILED then 'The build failed for'
+ when Todo::BUILD_FAILED then 'The pipeline failed in'
when Todo::MARKED then 'added a todo for'
when Todo::APPROVAL_REQUIRED then "set #{todo_action_subject(todo)} as an approver for"
when Todo::UNMERGEABLE then 'Could not merge'
diff --git a/app/helpers/tree_helper.rb b/app/helpers/tree_helper.rb
index 23a9601aed7..2fef4ae98a9 100644
--- a/app/helpers/tree_helper.rb
+++ b/app/helpers/tree_helper.rb
@@ -203,9 +203,11 @@ module TreeHelper
show_edit_button: show_edit_button?(options),
show_web_ide_button: show_web_ide_button?,
show_gitpod_button: show_gitpod_button?,
+ show_pipeline_editor_button: show_pipeline_editor_button?(@project, @path),
web_ide_url: web_ide_url,
edit_url: edit_url(options),
+ pipeline_editor_url: project_ci_pipeline_editor_path(@project, branch_name: @ref),
gitpod_url: gitpod_url,
user_preferences_gitpod_path: profile_preferences_path(anchor: 'user_gitpod_enabled'),
diff --git a/app/helpers/users/callouts_helper.rb b/app/helpers/users/callouts_helper.rb
index 32b0d7b3fe3..87c8bf5cb28 100644
--- a/app/helpers/users/callouts_helper.rb
+++ b/app/helpers/users/callouts_helper.rb
@@ -10,6 +10,7 @@ module Users
REGISTRATION_ENABLED_CALLOUT = 'registration_enabled_callout'
UNFINISHED_TAG_CLEANUP_CALLOUT = 'unfinished_tag_cleanup_callout'
SECURITY_NEWSLETTER_CALLOUT = 'security_newsletter_callout'
+ REGISTRATION_ENABLED_CALLOUT_ALLOWED_CONTROLLER_PATHS = [/^root/, /^dashboard\S*/, /^admin\S*/].freeze
def show_gke_cluster_integration_callout?(project)
active_nav_link?(controller: sidebar_operations_paths) &&
@@ -47,7 +48,8 @@ module Users
!Gitlab.com? &&
current_user&.admin? &&
signup_enabled? &&
- !user_dismissed?(REGISTRATION_ENABLED_CALLOUT)
+ !user_dismissed?(REGISTRATION_ENABLED_CALLOUT) &&
+ REGISTRATION_ENABLED_CALLOUT_ALLOWED_CONTROLLER_PATHS.any? { |path| controller.controller_path.match?(path) }
end
def dismiss_two_factor_auth_recovery_settings_check
diff --git a/app/helpers/web_ide_button_helper.rb b/app/helpers/web_ide_button_helper.rb
index 6c73d365e8e..9ec22a659d3 100644
--- a/app/helpers/web_ide_button_helper.rb
+++ b/app/helpers/web_ide_button_helper.rb
@@ -29,6 +29,10 @@ module WebIdeButtonHelper
show_web_ide_button? && Gitlab::CurrentSettings.gitpod_enabled
end
+ def show_pipeline_editor_button?(project, path)
+ can_view_pipeline_editor?(project) && path == project.ci_config_path_or_default
+ end
+
def can_push_code?
current_user&.can?(:push_code, @project)
end
diff --git a/app/helpers/whats_new_helper.rb b/app/helpers/whats_new_helper.rb
index ccccfcb930b..bbf56c51c6d 100644
--- a/app/helpers/whats_new_helper.rb
+++ b/app/helpers/whats_new_helper.rb
@@ -10,7 +10,7 @@ module WhatsNewHelper
end
def display_whats_new?
- (Gitlab.dev_env_org_or_com? || user_signed_in?) &&
+ (Gitlab.org_or_com? || user_signed_in?) &&
!Gitlab::CurrentSettings.current_application_settings.whats_new_variant_disabled?
end
diff --git a/app/mailers/application_mailer.rb b/app/mailers/application_mailer.rb
index e0c95370072..94ed83a7d4a 100644
--- a/app/mailers/application_mailer.rb
+++ b/app/mailers/application_mailer.rb
@@ -7,6 +7,7 @@ class ApplicationMailer < ActionMailer::Base
helper MarkupHelper
attr_accessor :current_user
+
helper_method :current_user, :can?
default from: proc { default_sender_address.format }
diff --git a/app/mailers/emails/profile.rb b/app/mailers/emails/profile.rb
index 592c394bb48..28e51ba311b 100644
--- a/app/mailers/emails/profile.rb
+++ b/app/mailers/emails/profile.rb
@@ -58,6 +58,18 @@ module Emails
end
# rubocop: enable CodeReuse/ActiveRecord
+ def access_token_created_email(user, token_name)
+ return unless user&.active?
+
+ @user = user
+ @target_url = profile_personal_access_tokens_url
+ @token_name = token_name
+
+ Gitlab::I18n.with_locale(@user.preferred_language) do
+ mail(to: @user.notification_email_or_default, subject: subject(_("A new personal access token has been created")))
+ end
+ end
+
def access_token_about_to_expire_email(user, token_names)
return unless user
diff --git a/app/models/analytics/cycle_analytics/aggregation.rb b/app/models/analytics/cycle_analytics/aggregation.rb
new file mode 100644
index 00000000000..44d2dc369f7
--- /dev/null
+++ b/app/models/analytics/cycle_analytics/aggregation.rb
@@ -0,0 +1,75 @@
+# frozen_string_literal: true
+
+class Analytics::CycleAnalytics::Aggregation < ApplicationRecord
+ include FromUnion
+
+ belongs_to :group, optional: false
+
+ validates :incremental_runtimes_in_seconds, :incremental_processed_records, :last_full_run_runtimes_in_seconds, :last_full_run_processed_records, presence: true, length: { maximum: 10 }, allow_blank: true
+
+ scope :priority_order, -> (column_to_sort = :last_incremental_run_at) { order(arel_table[column_to_sort].asc.nulls_first) }
+ scope :enabled, -> { where('enabled IS TRUE') }
+
+ def estimated_next_run_at
+ return unless enabled
+ return if last_incremental_run_at.nil?
+
+ estimation = duration_until_the_next_aggregation_job +
+ average_aggregation_duration +
+ (last_incremental_run_at - earliest_last_run_at)
+
+ estimation < 1 ? nil : estimation.from_now
+ end
+
+ def self.safe_create_for_group(group)
+ top_level_group = group.root_ancestor
+ aggregation = find_by(group_id: top_level_group.id)
+ return aggregation if aggregation.present?
+
+ insert({ group_id: top_level_group.id }, unique_by: :group_id)
+ find_by(group_id: top_level_group.id)
+ end
+
+ private
+
+ # The aggregation job is scheduled every 10 minutes: */10 * * * *
+ def duration_until_the_next_aggregation_job
+ (10 - (DateTime.current.minute % 10)).minutes.seconds
+ end
+
+ def average_aggregation_duration
+ return 0.seconds if incremental_runtimes_in_seconds.empty?
+
+ average = incremental_runtimes_in_seconds.sum.fdiv(incremental_runtimes_in_seconds.size)
+ average.seconds
+ end
+
+ def earliest_last_run_at
+ max = self.class.select(:last_incremental_run_at)
+ .where(enabled: true)
+ .where.not(last_incremental_run_at: nil)
+ .priority_order
+ .limit(1)
+ .to_sql
+
+ connection.select_value("(#{max})")
+ end
+
+ def self.load_batch(last_run_at, column_to_query = :last_incremental_run_at, batch_size = 100)
+ last_run_at_not_set = Analytics::CycleAnalytics::Aggregation
+ .enabled
+ .where(column_to_query => nil)
+ .priority_order(column_to_query)
+ .limit(batch_size)
+
+ last_run_at_before = Analytics::CycleAnalytics::Aggregation
+ .enabled
+ .where(arel_table[column_to_query].lt(last_run_at))
+ .priority_order(column_to_query)
+ .limit(batch_size)
+
+ Analytics::CycleAnalytics::Aggregation
+ .from_union([last_run_at_not_set, last_run_at_before], remove_order: false, remove_duplicates: false)
+ .limit(batch_size)
+ end
+end
diff --git a/app/models/application_record.rb b/app/models/application_record.rb
index 06ff18ca409..198a3653cd3 100644
--- a/app/models/application_record.rb
+++ b/app/models/application_record.rb
@@ -5,6 +5,7 @@ class ApplicationRecord < ActiveRecord::Base
include Transactions
include LegacyBulkInsert
include CrossDatabaseModification
+ include SensitiveSerializableHash
self.abstract_class = true
@@ -60,8 +61,10 @@ class ApplicationRecord < ActiveRecord::Base
end
# Start a new transaction with a shorter-than-usual statement timeout. This is
- # currently one third of the default 15-second timeout
- def self.with_fast_read_statement_timeout(timeout_ms = 5000)
+ # currently one third of the default 15-second timeout with a 500ms buffer
+ # to allow callers gracefully handling the errors to still complete within
+ # the 5s target duration of a low urgency request.
+ def self.with_fast_read_statement_timeout(timeout_ms = 4500)
::Gitlab::Database::LoadBalancing::Session.current.fallback_to_replicas_for_ambiguous_queries do
transaction(requires_new: true) do # rubocop:disable Performance/ActiveRecordSubtransactions
connection.exec_query("SET LOCAL statement_timeout = #{timeout_ms}")
@@ -99,6 +102,10 @@ class ApplicationRecord < ActiveRecord::Base
where('EXISTS (?)', query.select(1))
end
+ def self.where_not_exists(query)
+ where('NOT EXISTS (?)', query.select(1))
+ end
+
def self.declarative_enum(enum_mod)
enum(enum_mod.key => enum_mod.values)
end
diff --git a/app/models/application_setting.rb b/app/models/application_setting.rb
index 02fbf0f855e..c7aad7ff861 100644
--- a/app/models/application_setting.rb
+++ b/app/models/application_setting.rb
@@ -11,6 +11,7 @@ class ApplicationSetting < ApplicationRecord
ignore_columns %i[elasticsearch_shards elasticsearch_replicas], remove_with: '14.4', remove_after: '2021-09-22'
ignore_columns %i[static_objects_external_storage_auth_token], remove_with: '14.9', remove_after: '2022-03-22'
ignore_column %i[max_package_files_for_package_destruction], remove_with: '14.9', remove_after: '2022-03-22'
+ ignore_column :user_email_lookup_limit, remove_with: '15.0', remove_after: '2022-04-18'
INSTANCE_REVIEW_MIN_USERS = 50
GRAFANA_URL_ERROR_MESSAGE = 'Please check your Grafana URL setting in ' \
@@ -362,6 +363,9 @@ class ApplicationSetting < ApplicationRecord
:container_registry_expiration_policies_worker_capacity,
numericality: { only_integer: true, greater_than_or_equal_to: 0 }
+ validates :container_registry_expiration_policies_caching,
+ inclusion: { in: [true, false], message: _('must be a boolean value') }
+
validates :container_registry_import_max_tags_count,
:container_registry_import_max_retries,
:container_registry_import_start_max_retries,
@@ -516,9 +520,12 @@ class ApplicationSetting < ApplicationRecord
validates :notes_create_limit,
numericality: { only_integer: true, greater_than_or_equal_to: 0 }
- validates :user_email_lookup_limit,
+ validates :search_rate_limit,
numericality: { only_integer: true, greater_than_or_equal_to: 0 }
+ validates :search_rate_limit_unauthenticated,
+ numericality: { only_integer: true, greater_than_or_equal_to: 0 }
+
validates :notes_create_limit_allowlist,
length: { maximum: 100, message: N_('is too long (maximum is 100 entries)') },
allow_nil: false
@@ -650,7 +657,17 @@ class ApplicationSetting < ApplicationRecord
users_count >= INSTANCE_REVIEW_MIN_USERS
end
+ Recursion = Class.new(RuntimeError)
+
def self.create_from_defaults
+ # this is posssible if calls to create the record depend on application
+ # settings themselves. This was seen in the case of a feature flag called by
+ # `transaction` that ended up requiring application settings to determine metrics behavior.
+ # If something like that happens, we break the loop here, and let the caller decide how to manage it.
+ raise Recursion if Thread.current[:application_setting_create_from_defaults]
+
+ Thread.current[:application_setting_create_from_defaults] = true
+
check_schema!
transaction(requires_new: true) do # rubocop:disable Performance/ActiveRecordSubtransactions
@@ -659,6 +676,8 @@ class ApplicationSetting < ApplicationRecord
rescue ActiveRecord::RecordNotUnique
# We already have an ApplicationSetting record, so just return it.
current_without_cache
+ ensure
+ Thread.current[:application_setting_create_from_defaults] = nil
end
def self.find_or_create_without_cache
diff --git a/app/models/application_setting_implementation.rb b/app/models/application_setting_implementation.rb
index 415f0b35f3a..42049713883 100644
--- a/app/models/application_setting_implementation.rb
+++ b/app/models/application_setting_implementation.rb
@@ -218,7 +218,9 @@ module ApplicationSettingImplementation
valid_runner_registrars: VALID_RUNNER_REGISTRAR_TYPES,
wiki_page_max_content_bytes: 50.megabytes,
container_registry_delete_tags_service_timeout: 250,
- container_registry_expiration_policies_worker_capacity: 0,
+ container_registry_expiration_policies_worker_capacity: 4,
+ container_registry_cleanup_tags_service_max_list_size: 200,
+ container_registry_expiration_policies_caching: true,
container_registry_import_max_tags_count: 100,
container_registry_import_max_retries: 3,
container_registry_import_start_max_retries: 50,
@@ -231,7 +233,8 @@ module ApplicationSettingImplementation
rate_limiting_response_text: nil,
whats_new_variant: 0,
user_deactivation_emails_enabled: true,
- user_email_lookup_limit: 60,
+ search_rate_limit: 30,
+ search_rate_limit_unauthenticated: 10,
users_get_by_id_limit: 300,
users_get_by_id_limit_allowlist: []
}
@@ -402,7 +405,7 @@ module ApplicationSettingImplementation
def normalized_repository_storage_weights
strong_memoize(:normalized_repository_storage_weights) do
repository_storages_weights = repository_storages_weighted.slice(*Gitlab.config.repositories.storages.keys)
- weights_total = repository_storages_weights.values.reduce(:+)
+ weights_total = repository_storages_weights.values.sum
repository_storages_weights.transform_values do |w|
next w if weights_total == 0
diff --git a/app/models/blobs/notebook.rb b/app/models/blobs/notebook.rb
new file mode 100644
index 00000000000..bdb438cccd9
--- /dev/null
+++ b/app/models/blobs/notebook.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+module Blobs
+ class Notebook < ::Blob
+ attr_reader :data
+
+ def initialize(blob, data)
+ super(blob.__getobj__, blob.container)
+ @data = data
+ end
+ end
+end
diff --git a/app/models/broadcast_message.rb b/app/models/broadcast_message.rb
index 1ee5c081840..949902fbb77 100644
--- a/app/models/broadcast_message.rb
+++ b/app/models/broadcast_message.rb
@@ -4,12 +4,21 @@ class BroadcastMessage < ApplicationRecord
include CacheMarkdownField
include Sortable
+ ALLOWED_TARGET_ACCESS_LEVELS = [
+ Gitlab::Access::GUEST,
+ Gitlab::Access::REPORTER,
+ Gitlab::Access::DEVELOPER,
+ Gitlab::Access::MAINTAINER,
+ Gitlab::Access::OWNER
+ ].freeze
+
cache_markdown_field :message, pipeline: :broadcast_message, whitelisted: true
validates :message, presence: true
validates :starts_at, presence: true
validates :ends_at, presence: true
validates :broadcast_type, presence: true
+ validates :target_access_levels, inclusion: { in: ALLOWED_TARGET_ACCESS_LEVELS }
validates :color, allow_blank: true, color: true
validates :font, allow_blank: true, color: true
@@ -29,20 +38,20 @@ class BroadcastMessage < ApplicationRecord
}
class << self
- def current_banner_messages(current_path = nil)
- fetch_messages BANNER_CACHE_KEY, current_path do
+ def current_banner_messages(current_path: nil, user_access_level: nil)
+ fetch_messages BANNER_CACHE_KEY, current_path, user_access_level do
current_and_future_messages.banner
end
end
- def current_notification_messages(current_path = nil)
- fetch_messages NOTIFICATION_CACHE_KEY, current_path do
+ def current_notification_messages(current_path: nil, user_access_level: nil)
+ fetch_messages NOTIFICATION_CACHE_KEY, current_path, user_access_level do
current_and_future_messages.notification
end
end
- def current(current_path = nil)
- fetch_messages CACHE_KEY, current_path do
+ def current(current_path: nil, user_access_level: nil)
+ fetch_messages CACHE_KEY, current_path, user_access_level do
current_and_future_messages
end
end
@@ -53,7 +62,7 @@ class BroadcastMessage < ApplicationRecord
def cache
::Gitlab::SafeRequestStore.fetch(:broadcast_message_json_cache) do
- Gitlab::JsonCache.new(cache_key_with_version: false)
+ Gitlab::JsonCache.new
end
end
@@ -63,7 +72,7 @@ class BroadcastMessage < ApplicationRecord
private
- def fetch_messages(cache_key, current_path)
+ def fetch_messages(cache_key, current_path, user_access_level)
messages = cache.fetch(cache_key, as: BroadcastMessage, expires_in: cache_expires_in) do
yield
end
@@ -74,7 +83,13 @@ class BroadcastMessage < ApplicationRecord
# displaying we'll refresh the cache so we don't need to keep filtering.
cache.expire(cache_key) if now_or_future != messages
- now_or_future.select(&:now?).select { |message| message.matches_current_path(current_path) }
+ messages = now_or_future.select(&:now?)
+ messages = messages.select do |message|
+ message.matches_current_user_access_level?(user_access_level)
+ end
+ messages.select do |message|
+ message.matches_current_path(current_path)
+ end
end
end
@@ -102,6 +117,13 @@ class BroadcastMessage < ApplicationRecord
now? || future?
end
+ def matches_current_user_access_level?(user_access_level)
+ return false if target_access_levels.present? && Feature.disabled?(:role_targeted_broadcast_messages, default_enabled: :yaml)
+ return true unless target_access_levels.present?
+
+ target_access_levels.include? user_access_level
+ end
+
def matches_current_path(current_path)
return false if current_path.blank? && target_path.present?
return true if current_path.blank? || target_path.blank?
diff --git a/app/models/bulk_imports/entity.rb b/app/models/bulk_imports/entity.rb
index 38b7da76306..a7e1384641c 100644
--- a/app/models/bulk_imports/entity.rb
+++ b/app/models/bulk_imports/entity.rb
@@ -20,6 +20,8 @@
class BulkImports::Entity < ApplicationRecord
self.table_name = 'bulk_import_entities'
+ FailedError = Class.new(StandardError)
+
belongs_to :bulk_import, optional: false
belongs_to :parent, class_name: 'BulkImports::Entity', optional: true
diff --git a/app/models/bulk_imports/export_status.rb b/app/models/bulk_imports/export_status.rb
index abf064adaae..cae6aad27da 100644
--- a/app/models/bulk_imports/export_status.rb
+++ b/app/models/bulk_imports/export_status.rb
@@ -30,7 +30,12 @@ module BulkImports
def export_status
strong_memoize(:export_status) do
- fetch_export_status.find { |item| item['relation'] == relation }
+ status = fetch_export_status
+
+ # Consider empty response as failed export
+ raise StandardError, 'Empty export status response' unless status&.present?
+
+ status.find { |item| item['relation'] == relation }
end
rescue StandardError => e
{ 'status' => Export::FAILED, 'error' => e.message }
diff --git a/app/models/ci/bridge.rb b/app/models/ci/bridge.rb
index 50bda64d537..2ff777bfc89 100644
--- a/app/models/ci/bridge.rb
+++ b/app/models/ci/bridge.rb
@@ -11,6 +11,11 @@ module Ci
InvalidBridgeTypeError = Class.new(StandardError)
InvalidTransitionError = Class.new(StandardError)
+ FORWARD_DEFAULTS = {
+ yaml_variables: true,
+ pipeline_variables: false
+ }.freeze
+
belongs_to :project
belongs_to :trigger_request
has_many :sourced_pipelines, class_name: "::Ci::Sources::Pipeline",
@@ -199,12 +204,13 @@ module Ci
end
def downstream_variables
- variables = scoped_variables.concat(pipeline.persisted_variables)
-
- variables.to_runner_variables.yield_self do |all_variables|
- yaml_variables.to_a.map do |hash|
- { key: hash[:key], value: ::ExpandVariables.expand(hash[:value], all_variables) }
- end
+ if ::Feature.enabled?(:ci_trigger_forward_variables, project, default_enabled: :yaml)
+ calculate_downstream_variables
+ .reverse # variables priority
+ .uniq { |var| var[:key] } # only one variable key to pass
+ .reverse
+ else
+ legacy_downstream_variables
end
end
@@ -250,6 +256,58 @@ module Ci
}
}
end
+
+ def legacy_downstream_variables
+ variables = scoped_variables.concat(pipeline.persisted_variables)
+
+ variables.to_runner_variables.yield_self do |all_variables|
+ yaml_variables.to_a.map do |hash|
+ { key: hash[:key], value: ::ExpandVariables.expand(hash[:value], all_variables) }
+ end
+ end
+ end
+
+ def calculate_downstream_variables
+ expand_variables = scoped_variables
+ .concat(pipeline.persisted_variables)
+ .to_runner_variables
+
+ # The order of this list refers to the priority of the variables
+ downstream_yaml_variables(expand_variables) +
+ downstream_pipeline_variables(expand_variables)
+ end
+
+ def downstream_yaml_variables(expand_variables)
+ return [] unless forward_yaml_variables?
+
+ yaml_variables.to_a.map do |hash|
+ { key: hash[:key], value: ::ExpandVariables.expand(hash[:value], expand_variables) }
+ end
+ end
+
+ def downstream_pipeline_variables(expand_variables)
+ return [] unless forward_pipeline_variables?
+
+ pipeline.variables.to_a.map do |variable|
+ { key: variable.key, value: ::ExpandVariables.expand(variable.value, expand_variables) }
+ end
+ end
+
+ def forward_yaml_variables?
+ strong_memoize(:forward_yaml_variables) do
+ result = options&.dig(:trigger, :forward, :yaml_variables)
+
+ result.nil? ? FORWARD_DEFAULTS[:yaml_variables] : result
+ end
+ end
+
+ def forward_pipeline_variables?
+ strong_memoize(:forward_pipeline_variables) do
+ result = options&.dig(:trigger, :forward, :pipeline_variables)
+
+ result.nil? ? FORWARD_DEFAULTS[:pipeline_variables] : result
+ end
+ end
end
end
diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb
index c4d1a2c740b..68ec196a9ee 100644
--- a/app/models/ci/build.rb
+++ b/app/models/ci/build.rb
@@ -10,6 +10,8 @@ module Ci
include Presentable
include Importable
include Ci::HasRef
+ include HasDeploymentName
+
extend ::Gitlab::Utils::Override
BuildArchivedError = Class.new(StandardError)
@@ -35,6 +37,8 @@ module Ci
DEGRADATION_THRESHOLD_VARIABLE_NAME = 'DEGRADATION_THRESHOLD'
RUNNERS_STATUS_CACHE_EXPIRATION = 1.minute
+ DEPLOYMENT_NAMES = %w[deploy release rollout].freeze
+
has_one :deployment, as: :deployable, class_name: 'Deployment'
has_one :pending_state, class_name: 'Ci::BuildPendingState', inverse_of: :build
has_one :queuing_entry, class_name: 'Ci::PendingBuild', foreign_key: :build_id
@@ -68,6 +72,7 @@ module Ci
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 :harbor_integration, to: :project
delegate :trigger_short_token, to: :trigger_request, allow_nil: true
##
@@ -579,6 +584,7 @@ module Ci
.append(key: 'CI_REGISTRY_PASSWORD', value: token.to_s, public: false, masked: true)
.append(key: 'CI_REPOSITORY_URL', value: repo_url.to_s, public: false)
.concat(deploy_token_variables)
+ .concat(harbor_variables)
end
end
@@ -615,6 +621,12 @@ module Ci
end
end
+ def harbor_variables
+ return [] unless harbor_integration.try(:activated?)
+
+ Gitlab::Ci::Variables::Collection.new(harbor_integration.ci_variables)
+ end
+
def features
{
trace_sections: true,
@@ -1123,6 +1135,10 @@ module Ci
.include?(exit_code)
end
+ def track_deployment_usage
+ Gitlab::Utils::UsageData.track_usage_event('ci_users_executing_deployment_job', user_id) if user_id.present? && count_user_deployment?
+ end
+
protected
def run_status_commit_hooks!
diff --git a/app/models/ci/group_variable.rb b/app/models/ci/group_variable.rb
index 165bee5c54d..0af5533613f 100644
--- a/app/models/ci/group_variable.rb
+++ b/app/models/ci/group_variable.rb
@@ -18,5 +18,6 @@ module Ci
scope :unprotected, -> { where(protected: false) }
scope :by_environment_scope, -> (environment_scope) { where(environment_scope: environment_scope) }
+ scope :for_groups, ->(group_ids) { where(group_id: group_ids) }
end
end
diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb
index a1311b8555f..ae3ea7aa03f 100644
--- a/app/models/ci/pipeline.rb
+++ b/app/models/ci/pipeline.rb
@@ -25,6 +25,7 @@ module Ci
}.freeze
CONFIG_EXTENSION = '.gitlab-ci.yml'
DEFAULT_CONFIG_PATH = CONFIG_EXTENSION
+ CANCELABLE_STATUSES = (Ci::HasStatus::CANCELABLE_STATUSES + ['manual']).freeze
BridgeStatusError = Class.new(StandardError)
@@ -421,9 +422,7 @@ module Ci
sql = sql.where(ref: ref) if ref
- sql.each_with_object({}) do |pipeline, hash|
- hash[pipeline.sha] = pipeline
- end
+ sql.index_by(&:sha)
end
def self.latest_successful_ids_per_project
@@ -653,7 +652,7 @@ module Ci
def coverage
coverage_array = latest_statuses.map(&:coverage).compact
if coverage_array.size >= 1
- coverage_array.reduce(:+) / coverage_array.size
+ coverage_array.sum / coverage_array.size
end
end
@@ -1165,11 +1164,7 @@ module Ci
end
def merge_request?
- if Feature.enabled?(:ci_pipeline_merge_request_presence_check, default_enabled: :yaml)
- merge_request_id.present? && merge_request
- else
- merge_request_id.present?
- end
+ merge_request_id.present? && merge_request.present?
end
def external_pull_request?
diff --git a/app/models/ci/pipeline_schedule.rb b/app/models/ci/pipeline_schedule.rb
index b915495ac38..96e5567e85e 100644
--- a/app/models/ci/pipeline_schedule.rb
+++ b/app/models/ci/pipeline_schedule.rb
@@ -66,6 +66,18 @@ module Ci
project.actual_limits.limit_for(:ci_daily_pipeline_schedule_triggers)
end
+ def ref_for_display
+ return unless ref.present?
+
+ ref.gsub(%r{^refs/(heads|tags)/}, '')
+ end
+
+ def for_tag?
+ return false unless ref.present?
+
+ ref.start_with? 'refs/tags/'
+ end
+
private
def worker_cron_expression
diff --git a/app/models/ci/processable.rb b/app/models/ci/processable.rb
index 372df8cc264..4d119706a43 100644
--- a/app/models/ci/processable.rb
+++ b/app/models/ci/processable.rb
@@ -16,7 +16,7 @@ module Ci
scope :with_needs, -> (names = nil) do
needs = Ci::BuildNeed.scoped_build.select(1)
needs = needs.where(name: names) if names
- where('EXISTS (?)', needs).preload(:needs)
+ where('EXISTS (?)', needs)
end
scope :without_needs, -> (names = nil) do
diff --git a/app/models/ci/runner.rb b/app/models/ci/runner.rb
index 11150e839a3..4228da279a4 100644
--- a/app/models/ci/runner.rb
+++ b/app/models/ci/runner.rb
@@ -59,7 +59,7 @@ module Ci
AVAILABLE_TYPES_LEGACY = %w[specific shared].freeze
AVAILABLE_TYPES = runner_types.keys.freeze
- AVAILABLE_STATUSES = %w[active paused online offline not_connected never_contacted stale].freeze # TODO: Remove in %15.0: active, paused, not_connected. Relevant issues: https://gitlab.com/gitlab-org/gitlab/-/issues/347303, https://gitlab.com/gitlab-org/gitlab/-/issues/347305, https://gitlab.com/gitlab-org/gitlab/-/issues/344648
+ AVAILABLE_STATUSES = %w[active paused online offline not_connected never_contacted stale].freeze # TODO: Remove in %15.0: not_connected. In %16.0: active, paused. Relevant issues: https://gitlab.com/gitlab-org/gitlab/-/issues/347303, https://gitlab.com/gitlab-org/gitlab/-/issues/347305, https://gitlab.com/gitlab-org/gitlab/-/issues/344648
AVAILABLE_SCOPES = (AVAILABLE_TYPES_LEGACY + AVAILABLE_TYPES + AVAILABLE_STATUSES).freeze
FORM_EDITABLE = %i[description tag_list active run_untagged locked access_level maximum_timeout_human_readable].freeze
@@ -200,7 +200,7 @@ module Ci
validates :config, json_schema: { filename: 'ci_runner_config' }
- validates :maintenance_note, length: { maximum: 255 }
+ validates :maintenance_note, length: { maximum: 1024 }
alias_attribute :maintenance_note, :maintainer_note
@@ -329,9 +329,9 @@ module Ci
end
# DEPRECATED
- # TODO Remove in %15.0 in favor of `status` for REST calls, see https://gitlab.com/gitlab-org/gitlab/-/issues/344648
+ # TODO Remove in %16.0 in favor of `status` for REST calls
def deprecated_rest_status
- if contacted_at.nil?
+ if contacted_at.nil? # TODO Remove in %15.0, see https://gitlab.com/gitlab-org/gitlab/-/issues/344648
:not_connected
elsif active?
online? ? :online : :offline
diff --git a/app/models/ci/secure_file.rb b/app/models/ci/secure_file.rb
index 56f632b6232..18f0093ea41 100644
--- a/app/models/ci/secure_file.rb
+++ b/app/models/ci/secure_file.rb
@@ -3,10 +3,14 @@
module Ci
class SecureFile < Ci::ApplicationRecord
include FileStoreMounter
+ include Limitable
FILE_SIZE_LIMIT = 5.megabytes.freeze
CHECKSUM_ALGORITHM = 'sha256'
+ self.limit_scope = :project
+ self.limit_name = 'project_ci_secure_files'
+
belongs_to :project, optional: false
validates :file, presence: true, file_size: { maximum: FILE_SIZE_LIMIT }
diff --git a/app/models/concerns/blocks_json_serialization.rb b/app/models/concerns/blocks_json_serialization.rb
deleted file mode 100644
index 18c00532d78..00000000000
--- a/app/models/concerns/blocks_json_serialization.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-# frozen_string_literal: true
-
-# Overrides `as_json` and `to_json` to raise an exception when called in order
-# to prevent accidentally exposing attributes
-#
-# Not that would ever happen... but just in case.
-module BlocksJsonSerialization
- extend ActiveSupport::Concern
-
- JsonSerializationError = Class.new(StandardError)
-
- def to_json(*)
- raise JsonSerializationError,
- "JSON serialization has been disabled on #{self.class.name}"
- end
-
- alias_method :as_json, :to_json
-end
diff --git a/app/models/concerns/blocks_unsafe_serialization.rb b/app/models/concerns/blocks_unsafe_serialization.rb
new file mode 100644
index 00000000000..72adbe70f15
--- /dev/null
+++ b/app/models/concerns/blocks_unsafe_serialization.rb
@@ -0,0 +1,32 @@
+# frozen_string_literal: true
+
+# Overrides `#serializable_hash` to raise an exception when called without the `only` option
+# in order to prevent accidentally exposing attributes.
+#
+# An `unsafe: true` option can also be passed in to bypass this check.
+#
+# `#serializable_hash` is used by ActiveModel serializers like `ActiveModel::Serializers::JSON`
+# which overrides `#as_json` and `#to_json`.
+#
+module BlocksUnsafeSerialization
+ extend ActiveSupport::Concern
+ extend ::Gitlab::Utils::Override
+
+ UnsafeSerializationError = Class.new(StandardError)
+
+ override :serializable_hash
+ def serializable_hash(options = nil)
+ return super if allow_serialization?(options)
+
+ raise UnsafeSerializationError,
+ "Serialization has been disabled on #{self.class.name}"
+ end
+
+ private
+
+ def allow_serialization?(options = nil)
+ return false unless options
+
+ !!(options[:only] || options[:unsafe])
+ end
+end
diff --git a/app/models/concerns/bulk_member_access_load.rb b/app/models/concerns/bulk_member_access_load.rb
index 927d6ccb28f..efc65e55e40 100644
--- a/app/models/concerns/bulk_member_access_load.rb
+++ b/app/models/concerns/bulk_member_access_load.rb
@@ -1,61 +1,19 @@
# frozen_string_literal: true
-# Returns and caches in thread max member access for a resource
-#
module BulkMemberAccessLoad
extend ActiveSupport::Concern
included do
- # Determine the maximum access level for a group of resources in bulk.
- #
- # Returns a Hash mapping resource ID -> maximum access level.
- def max_member_access_for_resource_ids(resource_klass, resource_ids, &block)
- raise 'Block is mandatory' unless block_given?
-
- memoization_index = self.id
- memoization_class = self.class
-
- resource_ids = resource_ids.uniq
- memo_id = "#{memoization_class}:#{memoization_index}"
- access = load_access_hash(resource_klass, memo_id)
-
- # Look up only the IDs we need
- resource_ids -= access.keys
-
- return access if resource_ids.empty?
-
- resource_access = yield(resource_ids)
-
- access.merge!(resource_access)
-
- missing_resource_ids = resource_ids - resource_access.keys
-
- missing_resource_ids.each do |resource_id|
- access[resource_id] = Gitlab::Access::NO_ACCESS
- end
-
- access
- end
-
def merge_value_to_request_store(resource_klass, resource_id, value)
- max_member_access_for_resource_ids(resource_klass, [resource_id]) do
+ Gitlab::SafeRequestLoader.execute(resource_key: max_member_access_for_resource_key(resource_klass),
+ resource_ids: [resource_id],
+ default_value: Gitlab::Access::NO_ACCESS) do
{ resource_id => value }
end
end
- private
-
- def max_member_access_for_resource_key(klass, memoization_index)
- "max_member_access_for_#{klass.name.underscore.pluralize}:#{memoization_index}"
- end
-
- def load_access_hash(resource_klass, memo_id)
- return {} unless Gitlab::SafeRequestStore.active?
-
- key = max_member_access_for_resource_key(resource_klass, memo_id)
- Gitlab::SafeRequestStore[key] ||= {}
-
- Gitlab::SafeRequestStore[key]
+ def max_member_access_for_resource_key(klass)
+ "max_member_access_for_#{klass.name.underscore.pluralize}:#{self.class}:#{self.id}"
end
end
end
diff --git a/app/models/concerns/ci/has_deployment_name.rb b/app/models/concerns/ci/has_deployment_name.rb
new file mode 100644
index 00000000000..fe288134872
--- /dev/null
+++ b/app/models/concerns/ci/has_deployment_name.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+module Ci
+ module HasDeploymentName
+ extend ActiveSupport::Concern
+
+ def count_user_deployment?
+ Feature.enabled?(:job_deployment_count) && deployment_name?
+ end
+
+ def deployment_name?
+ self.class::DEPLOYMENT_NAMES.any? { |n| name.downcase.include?(n) }
+ end
+ end
+end
diff --git a/app/models/concerns/ci/has_status.rb b/app/models/concerns/ci/has_status.rb
index ccaccec3b6b..313c767e59f 100644
--- a/app/models/concerns/ci/has_status.rb
+++ b/app/models/concerns/ci/has_status.rb
@@ -7,12 +7,16 @@ module Ci
DEFAULT_STATUS = 'created'
BLOCKED_STATUS = %w[manual scheduled].freeze
AVAILABLE_STATUSES = %w[created waiting_for_resource preparing pending running success failed canceled skipped manual scheduled].freeze
+ # TODO: replace STARTED_STATUSES with data from BUILD_STARTED_RUNNING_STATUSES in https://gitlab.com/gitlab-org/gitlab/-/issues/273378
+ # see https://gitlab.com/gitlab-org/gitlab/-/merge_requests/82149#note_865508501
+ BUILD_STARTED_RUNNING_STATUSES = %w[running success failed].freeze
STARTED_STATUSES = %w[running success failed skipped manual scheduled].freeze
ACTIVE_STATUSES = %w[waiting_for_resource preparing pending running].freeze
COMPLETED_STATUSES = %w[success failed canceled skipped].freeze
ORDERED_STATUSES = %w[failed preparing pending running waiting_for_resource manual scheduled canceled success skipped created].freeze
PASSED_WITH_WARNINGS_STATUSES = %w[failed canceled].to_set.freeze
EXCLUDE_IGNORED_STATUSES = %w[manual failed canceled].to_set.freeze
+ CANCELABLE_STATUSES = %w[running waiting_for_resource preparing pending created scheduled].freeze
STATUSES_ENUM = { created: 0, pending: 1, running: 2, success: 3,
failed: 4, canceled: 5, skipped: 6, manual: 7,
scheduled: 8, preparing: 9, waiting_for_resource: 10 }.freeze
@@ -85,7 +89,7 @@ module Ci
scope :waiting_for_resource_or_upcoming, -> { with_status(:created, :scheduled, :waiting_for_resource) }
scope :cancelable, -> do
- where(status: [:running, :waiting_for_resource, :preparing, :pending, :created, :scheduled])
+ where(status: klass::CANCELABLE_STATUSES)
end
scope :without_statuses, -> (names) do
diff --git a/app/models/concerns/counter_attribute.rb b/app/models/concerns/counter_attribute.rb
index 4bfeba338d2..b41b1ba6008 100644
--- a/app/models/concerns/counter_attribute.rb
+++ b/app/models/concerns/counter_attribute.rb
@@ -102,9 +102,7 @@ module CounterAttribute
run_after_commit_or_now do
if counter_attribute_enabled?(attribute)
- redis_state do |redis|
- redis.incrby(counter_key(attribute), increment)
- end
+ increment_counter(attribute, increment)
FlushCounterIncrementsWorker.perform_in(WORKER_DELAY, self.class.name, self.id, attribute)
else
@@ -115,6 +113,28 @@ module CounterAttribute
true
end
+ def increment_counter(attribute, increment)
+ if counter_attribute_enabled?(attribute)
+ redis_state do |redis|
+ redis.incrby(counter_key(attribute), increment)
+ end
+ end
+ end
+
+ def clear_counter!(attribute)
+ if counter_attribute_enabled?(attribute)
+ redis_state { |redis| redis.del(counter_key(attribute)) }
+ end
+ end
+
+ def get_counter_value(attribute)
+ if counter_attribute_enabled?(attribute)
+ redis_state do |redis|
+ redis.get(counter_key(attribute)).to_i
+ end
+ end
+ end
+
def counter_key(attribute)
"project:{#{project_id}}:counters:#{self.class}:#{id}:#{attribute}"
end
diff --git a/app/models/concerns/deployment_platform.rb b/app/models/concerns/deployment_platform.rb
index b6245e29746..d9c622f247a 100644
--- a/app/models/concerns/deployment_platform.rb
+++ b/app/models/concerns/deployment_platform.rb
@@ -3,6 +3,8 @@
module DeploymentPlatform
# rubocop:disable Gitlab/ModuleWithInstanceVariables
def deployment_platform(environment: nil)
+ return if Feature.disabled?(:certificate_based_clusters, default_enabled: :yaml, type: :ops)
+
@deployment_platform ||= {}
@deployment_platform[environment] ||= find_deployment_platform(environment)
diff --git a/app/models/concerns/has_user_type.rb b/app/models/concerns/has_user_type.rb
index 28ee54afaa9..ad070090dd5 100644
--- a/app/models/concerns/has_user_type.rb
+++ b/app/models/concerns/has_user_type.rb
@@ -46,4 +46,17 @@ module HasUserType
def internal?
ghost? || (bot? && !project_bot?)
end
+
+ def redacted_name(viewing_user)
+ return self.name unless self.project_bot?
+
+ return self.name if self.groups.any? && viewing_user&.can?(:read_group, self.groups.first)
+
+ return self.name if viewing_user&.can?(:read_project, self.projects.first)
+
+ # If the requester does not have permission to read the project bot name,
+ # the API returns an arbitrary string. UI changes will be addressed in a follow up issue:
+ # https://gitlab.com/gitlab-org/gitlab/-/issues/346058
+ '****'
+ end
end
diff --git a/app/models/concerns/integrations/has_issue_tracker_fields.rb b/app/models/concerns/integrations/has_issue_tracker_fields.rb
new file mode 100644
index 00000000000..b1def38d019
--- /dev/null
+++ b/app/models/concerns/integrations/has_issue_tracker_fields.rb
@@ -0,0 +1,30 @@
+# frozen_string_literal: true
+
+module Integrations
+ module HasIssueTrackerFields
+ extend ActiveSupport::Concern
+
+ included do
+ field :project_url,
+ required: true,
+ storage: :data_fields,
+ title: -> { _('Project URL') },
+ help: -> { s_('IssueTracker|The URL to the project in the external issue tracker.') }
+
+ field :issues_url,
+ required: true,
+ storage: :data_fields,
+ title: -> { s_('IssueTracker|Issue URL') },
+ help: -> do
+ format s_('IssueTracker|The URL to view an issue in the external issue tracker. Must contain %{colon_id}.'),
+ colon_id: '<code>:id</code>'.html_safe
+ end
+
+ field :new_issue_url,
+ required: true,
+ storage: :data_fields,
+ title: -> { s_('IssueTracker|New issue URL') },
+ help: -> { s_('IssueTracker|The URL to create an issue in the external issue tracker.') }
+ end
+ end
+end
diff --git a/app/models/concerns/issuable.rb b/app/models/concerns/issuable.rb
index 0138c0ad20f..1eb30e88f16 100644
--- a/app/models/concerns/issuable.rb
+++ b/app/models/concerns/issuable.rb
@@ -74,6 +74,7 @@ module Issuable
end
has_many :note_authors, -> { distinct }, through: :notes, source: :author
+ has_many :user_note_authors, -> { distinct.where("notes.system = false") }, through: :notes, source: :author
has_many :label_links, as: :target, inverse_of: :target
has_many :labels, through: :label_links
@@ -464,37 +465,54 @@ module Issuable
false
end
- def to_hook_data(user, old_associations: {})
- changes = previous_changes
+ def hook_association_changes(old_associations)
+ changes = {}
- if old_associations
- old_labels = old_associations.fetch(:labels, labels)
- old_assignees = old_associations.fetch(:assignees, assignees)
- old_severity = old_associations.fetch(:severity, severity)
+ old_labels = old_associations.fetch(:labels, labels)
+ old_assignees = old_associations.fetch(:assignees, assignees)
+ old_severity = old_associations.fetch(:severity, severity)
- if old_labels != labels
- changes[:labels] = [old_labels.map(&:hook_attrs), labels.map(&:hook_attrs)]
- end
+ if old_labels != labels
+ changes[:labels] = [old_labels.map(&:hook_attrs), labels.map(&:hook_attrs)]
+ end
- if old_assignees != assignees
- changes[:assignees] = [old_assignees.map(&:hook_attrs), assignees.map(&:hook_attrs)]
- end
+ if old_assignees != assignees
+ changes[:assignees] = [old_assignees.map(&:hook_attrs), assignees.map(&:hook_attrs)]
+ end
+
+ if supports_severity? && old_severity != severity
+ changes[:severity] = [old_severity, severity]
+ end
+
+ if supports_escalation? && escalation_status
+ current_escalation_status = escalation_status.status_name
+ old_escalation_status = old_associations.fetch(:escalation_status, current_escalation_status)
- if supports_severity? && old_severity != severity
- changes[:severity] = [old_severity, severity]
+ if old_escalation_status != current_escalation_status
+ changes[:escalation_status] = [old_escalation_status, current_escalation_status]
end
+ end
- if self.respond_to?(:total_time_spent)
- old_total_time_spent = old_associations.fetch(:total_time_spent, total_time_spent)
- old_time_change = old_associations.fetch(:time_change, time_change)
+ if self.respond_to?(:total_time_spent)
+ old_total_time_spent = old_associations.fetch(:total_time_spent, total_time_spent)
+ old_time_change = old_associations.fetch(:time_change, time_change)
- if old_total_time_spent != total_time_spent
- changes[:total_time_spent] = [old_total_time_spent, total_time_spent]
- changes[:time_change] = [old_time_change, time_change]
- end
+ if old_total_time_spent != total_time_spent
+ changes[:total_time_spent] = [old_total_time_spent, total_time_spent]
+ changes[:time_change] = [old_time_change, time_change]
end
end
+ changes
+ end
+
+ def to_hook_data(user, old_associations: {})
+ changes = previous_changes
+
+ if old_associations.present?
+ changes.merge!(hook_association_changes(old_associations))
+ end
+
Gitlab::HookData::IssuableBuilder.new(self).build(user: user, changes: changes)
end
diff --git a/app/models/concerns/issuable_link.rb b/app/models/concerns/issuable_link.rb
new file mode 100644
index 00000000000..3e14507bc70
--- /dev/null
+++ b/app/models/concerns/issuable_link.rb
@@ -0,0 +1,55 @@
+# frozen_string_literal: true
+
+# == IssuableLink concern
+#
+# Contains common functionality shared between related Issues and related Epics
+#
+# Used by IssueLink, Epic::RelatedEpicLink
+#
+module IssuableLink
+ extend ActiveSupport::Concern
+
+ TYPE_RELATES_TO = 'relates_to'
+ TYPE_BLOCKS = 'blocks' ## EE-only. Kept here to be used on link_type enum.
+
+ class_methods do
+ def inverse_link_type(type)
+ type
+ end
+
+ def issuable_type
+ raise NotImplementedError
+ end
+ end
+
+ included do
+ validates :source, presence: true
+ validates :target, presence: true
+ validates :source, uniqueness: { scope: :target_id, message: 'is already related' }
+ validate :check_self_relation
+ validate :check_opposite_relation
+
+ enum link_type: { TYPE_RELATES_TO => 0, TYPE_BLOCKS => 1 }
+
+ private
+
+ def check_self_relation
+ return unless source && target
+
+ if source == target
+ errors.add(:source, 'cannot be related to itself')
+ end
+ end
+
+ def check_opposite_relation
+ return unless source && target
+
+ if self.class.base_class.find_by(source: target, target: source)
+ errors.add(:source, "is already related to this #{self.class.issuable_type}")
+ end
+ end
+ end
+end
+
+IssuableLink.prepend_mod_with('IssuableLink')
+IssuableLink::ClassMethods.prepend_mod_with('IssuableLink::ClassMethods')
diff --git a/app/models/concerns/issue_resource_event.rb b/app/models/concerns/issue_resource_event.rb
index 1c24032dbbb..5cbc937e465 100644
--- a/app/models/concerns/issue_resource_event.rb
+++ b/app/models/concerns/issue_resource_event.rb
@@ -8,6 +8,10 @@ module IssueResourceEvent
scope :by_issue, ->(issue) { where(issue_id: issue.id) }
- scope :by_issue_ids_and_created_at_earlier_or_equal_to, ->(issue_ids, time) { where(issue_id: issue_ids).where('created_at <= ?', time) }
+ scope :by_created_at_earlier_or_equal_to, ->(time) { where('created_at <= ?', time) }
+ scope :by_issue_ids, ->(issue_ids) do
+ table = self.klass.arel_table
+ where(table[:issue_id].in(issue_ids))
+ end
end
end
diff --git a/app/models/concerns/merge_request_reviewer_state.rb b/app/models/concerns/merge_request_reviewer_state.rb
index 5859f43a70c..893d06b4da8 100644
--- a/app/models/concerns/merge_request_reviewer_state.rb
+++ b/app/models/concerns/merge_request_reviewer_state.rb
@@ -14,6 +14,14 @@ module MergeRequestReviewerState
presence: true,
inclusion: { in: self.states.keys }
+ belongs_to :updated_state_by, class_name: 'User', foreign_key: :updated_state_by_user_id
+
after_initialize :set_state, unless: :persisted?
+
+ def attention_requested_by
+ return unless attention_requested?
+
+ updated_state_by
+ end
end
end
diff --git a/app/models/concerns/pg_full_text_searchable.rb b/app/models/concerns/pg_full_text_searchable.rb
new file mode 100644
index 00000000000..68357c44300
--- /dev/null
+++ b/app/models/concerns/pg_full_text_searchable.rb
@@ -0,0 +1,111 @@
+# frozen_string_literal: true
+
+# This module adds PG full-text search capabilities to a model.
+# A `search_data` association with a `search_vector` column is required.
+#
+# Declare the fields that will be part of the search vector with their
+# corresponding weights. Possible values for weight are A, B, C, or D.
+# For example:
+#
+# include PgFullTextSearchable
+# pg_full_text_searchable columns: [{ name: 'title', weight: 'A' }, { name: 'description', weight: 'B' }]
+#
+# This module sets up an after_commit hook that updates the search data
+# when the searchable columns are changed. You will need to implement the
+# `#persist_pg_full_text_search_vector` method that does the actual insert or update.
+#
+# This also adds a `pg_full_text_search` scope so you can do:
+#
+# Model.pg_full_text_search("some search term")
+
+module PgFullTextSearchable
+ extend ActiveSupport::Concern
+
+ LONG_WORDS_REGEX = %r([A-Za-z0-9+/@]{50,}).freeze
+ TSVECTOR_MAX_LENGTH = 1.megabyte.freeze
+ TEXT_SEARCH_DICTIONARY = 'english'
+
+ def update_search_data!
+ tsvector_sql_nodes = self.class.pg_full_text_searchable_columns.map do |column, weight|
+ tsvector_arel_node(column, weight)&.to_sql
+ end
+
+ persist_pg_full_text_search_vector(Arel.sql(tsvector_sql_nodes.compact.join(' || ')))
+ rescue ActiveRecord::StatementInvalid => e
+ raise unless e.cause.is_a?(PG::ProgramLimitExceeded) && e.message.include?('string is too long for tsvector')
+
+ Gitlab::AppJsonLogger.error(
+ message: 'Error updating search data: string is too long for tsvector',
+ class: self.class.name,
+ model_id: self.id
+ )
+ end
+
+ private
+
+ def persist_pg_full_text_search_vector(search_vector)
+ raise NotImplementedError
+ end
+
+ def tsvector_arel_node(column, weight)
+ return if self[column].blank?
+
+ column_text = self[column].gsub(LONG_WORDS_REGEX, ' ')
+ column_text = column_text[0..(TSVECTOR_MAX_LENGTH - 1)]
+ column_text = ActiveSupport::Inflector.transliterate(column_text)
+
+ Arel::Nodes::NamedFunction.new(
+ 'setweight',
+ [
+ Arel::Nodes::NamedFunction.new(
+ 'to_tsvector',
+ [Arel::Nodes.build_quoted(TEXT_SEARCH_DICTIONARY), Arel::Nodes.build_quoted(column_text)]
+ ),
+ Arel::Nodes.build_quoted(weight)
+ ]
+ )
+ end
+
+ included do
+ cattr_reader :pg_full_text_searchable_columns do
+ {}
+ end
+ end
+
+ class_methods do
+ def pg_full_text_searchable(columns:)
+ raise 'Full text search columns already defined!' if pg_full_text_searchable_columns.present?
+
+ columns.each do |column|
+ pg_full_text_searchable_columns[column[:name]] = column[:weight]
+ end
+
+ # We update this outside the transaction because this could raise an error if the resulting tsvector
+ # is too long. When that happens, we still persist the create / update but the model will not have a
+ # search data record. This is fine in most cases because this is a very rare occurrence and only happens
+ # with strings that are most likely unsearchable anyway.
+ #
+ # We also do not want to use a subtransaction here due to: https://gitlab.com/groups/gitlab-org/-/epics/6540
+ after_save_commit do
+ next unless pg_full_text_searchable_columns.keys.any? { |f| saved_changes.has_key?(f) }
+
+ update_search_data!
+ end
+ end
+
+ def pg_full_text_search(search_term)
+ search_data_table = reflect_on_association(:search_data).klass.arel_table
+
+ joins(:search_data).where(
+ Arel::Nodes::InfixOperation.new(
+ '@@',
+ search_data_table[:search_vector],
+ Arel::Nodes::NamedFunction.new(
+ 'websearch_to_tsquery',
+ [Arel::Nodes.build_quoted(TEXT_SEARCH_DICTIONARY), Arel::Nodes.build_quoted(search_term)]
+ )
+ )
+ )
+ end
+ end
+end
diff --git a/app/models/concerns/runners_token_prefixable.rb b/app/models/concerns/runners_token_prefixable.rb
index 1aea874337e..99bbbece7c7 100644
--- a/app/models/concerns/runners_token_prefixable.rb
+++ b/app/models/concerns/runners_token_prefixable.rb
@@ -1,14 +1,8 @@
# frozen_string_literal: true
module RunnersTokenPrefixable
- extend ActiveSupport::Concern
-
# Prefix for runners_token which can be used to invalidate existing tokens.
# The value chosen here is GR (for Gitlab Runner) combined with the rotation
# date (20220225) decimal to hex encoded.
RUNNERS_TOKEN_PREFIX = 'GR1348941'
-
- def runners_token_prefix
- RUNNERS_TOKEN_PREFIX
- end
end
diff --git a/app/models/concerns/select_for_project_authorization.rb b/app/models/concerns/select_for_project_authorization.rb
index 49342e30db6..5a7e16eb2c4 100644
--- a/app/models/concerns/select_for_project_authorization.rb
+++ b/app/models/concerns/select_for_project_authorization.rb
@@ -8,8 +8,10 @@ module SelectForProjectAuthorization
select("projects.id AS project_id", "members.access_level")
end
- def select_as_maintainer_for_project_authorization
- select(["projects.id AS project_id", "#{Gitlab::Access::MAINTAINER} AS access_level"])
+ # workaround until we migrate Project#owners to have membership with
+ # OWNER access level
+ def select_project_owner_for_project_authorization
+ select(["projects.id AS project_id", "#{Gitlab::Access::OWNER} AS access_level"])
end
end
end
diff --git a/app/models/concerns/sensitive_serializable_hash.rb b/app/models/concerns/sensitive_serializable_hash.rb
new file mode 100644
index 00000000000..725ec60e9b6
--- /dev/null
+++ b/app/models/concerns/sensitive_serializable_hash.rb
@@ -0,0 +1,46 @@
+# frozen_string_literal: true
+
+module SensitiveSerializableHash
+ extend ActiveSupport::Concern
+
+ included do
+ class_attribute :attributes_exempt_from_serializable_hash, default: []
+ end
+
+ class_methods do
+ def prevent_from_serialization(*keys)
+ self.attributes_exempt_from_serializable_hash ||= []
+ self.attributes_exempt_from_serializable_hash.concat keys
+ end
+ end
+
+ # Override serializable_hash to exclude sensitive attributes by default
+ #
+ # In general, prefer NOT to use serializable_hash / to_json / as_json in favor
+ # of serializers / entities instead which has an allowlist of attributes
+ def serializable_hash(options = nil)
+ return super unless prevent_sensitive_fields_from_serializable_hash?
+ return super if options && options[:unsafe_serialization_hash]
+
+ options = options.try(:dup) || {}
+ options[:except] = Array(options[:except]).dup
+
+ options[:except].concat self.class.attributes_exempt_from_serializable_hash
+
+ if self.class.respond_to?(:encrypted_attributes)
+ options[:except].concat self.class.encrypted_attributes.keys
+
+ # Per https://github.com/attr-encrypted/attr_encrypted/blob/a96693e9a2a25f4f910bf915e29b0f364f277032/lib/attr_encrypted.rb#L413
+ options[:except].concat self.class.encrypted_attributes.values.map { |v| v[:attribute] }
+ options[:except].concat self.class.encrypted_attributes.values.map { |v| "#{v[:attribute]}_iv" }
+ end
+
+ super(options)
+ end
+
+ private
+
+ def prevent_sensitive_fields_from_serializable_hash?
+ Feature.enabled?(:prevent_sensitive_fields_from_serializable_hash, default_enabled: :yaml)
+ end
+end
diff --git a/app/models/concerns/spammable.rb b/app/models/concerns/spammable.rb
index 4901cd832ff..b475eb79aa3 100644
--- a/app/models/concerns/spammable.rb
+++ b/app/models/concerns/spammable.rb
@@ -12,7 +12,7 @@ module Spammable
included do
has_one :user_agent_detail, as: :subject, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
- attr_accessor :spam
+ attr_writer :spam
attr_accessor :needs_recaptcha
attr_accessor :spam_log
@@ -29,6 +29,10 @@ module Spammable
delegate :ip_address, :user_agent, to: :user_agent_detail, allow_nil: true
end
+ def spam
+ !!@spam # rubocop:disable Gitlab/ModuleWithInstanceVariables
+ end
+
def submittable_as_spam_by?(current_user)
current_user && current_user.admin? && submittable_as_spam?
end
@@ -74,8 +78,9 @@ module Spammable
end
def recaptcha_error!
- self.errors.add(:base, "Your #{spammable_entity_type} has been recognized as spam. "\
- "Please, change the content or solve the reCAPTCHA to proceed.")
+ self.errors.add(:base, _("Your %{spammable_entity_type} has been recognized as spam. "\
+ "Please, change the content or solve the reCAPTCHA to proceed.") \
+ % { spammable_entity_type: spammable_entity_type })
end
def unrecoverable_spam_error!
diff --git a/app/models/concerns/timebox.rb b/app/models/concerns/timebox.rb
index 943ef3fa59f..d53594eb5af 100644
--- a/app/models/concerns/timebox.rb
+++ b/app/models/concerns/timebox.rb
@@ -44,7 +44,6 @@ module Timebox
validates :group, presence: true, unless: :project
validates :project, presence: true, unless: :group
- validates :title, presence: true
validate :timebox_type_check
validate :start_date_should_be_less_than_due_date, if: proc { |m| m.start_date.present? && m.due_date.present? }
diff --git a/app/models/concerns/token_authenticatable.rb b/app/models/concerns/token_authenticatable.rb
index f44ad8ebe90..d91ec161b84 100644
--- a/app/models/concerns/token_authenticatable.rb
+++ b/app/models/concerns/token_authenticatable.rb
@@ -8,6 +8,10 @@ module TokenAuthenticatable
@encrypted_token_authenticatable_fields ||= []
end
+ def token_authenticatable_fields
+ @token_authenticatable_fields ||= []
+ end
+
private
def add_authentication_token_field(token_field, options = {})
@@ -23,6 +27,8 @@ module TokenAuthenticatable
strategy = TokenAuthenticatableStrategies::Base
.fabricate(self, token_field, options)
+ prevent_from_serialization(*strategy.token_fields) if respond_to?(:prevent_from_serialization)
+
if options.fetch(:unique, true)
define_singleton_method("find_by_#{token_field}") do |token|
strategy.find_token_authenticatable(token)
@@ -82,9 +88,5 @@ module TokenAuthenticatable
@token_authenticatable_module ||=
const_set(:TokenAuthenticatable, Module.new).tap(&method(:include))
end
-
- def token_authenticatable_fields
- @token_authenticatable_fields ||= []
- end
end
end
diff --git a/app/models/concerns/token_authenticatable_strategies/base.rb b/app/models/concerns/token_authenticatable_strategies/base.rb
index 2cec4ab460e..2b677f37c89 100644
--- a/app/models/concerns/token_authenticatable_strategies/base.rb
+++ b/app/models/concerns/token_authenticatable_strategies/base.rb
@@ -23,6 +23,14 @@ module TokenAuthenticatableStrategies
raise NotImplementedError
end
+ def token_fields
+ result = [token_field]
+
+ result << @expires_at_field if expirable?
+
+ result
+ end
+
# Default implementation returns the token as-is
def format_token(instance, token)
instance.send("format_#{@token_field}", token) # rubocop:disable GitlabSecurity/PublicSend
diff --git a/app/models/concerns/token_authenticatable_strategies/digest.rb b/app/models/concerns/token_authenticatable_strategies/digest.rb
index 9926662ed66..5c94f25949f 100644
--- a/app/models/concerns/token_authenticatable_strategies/digest.rb
+++ b/app/models/concerns/token_authenticatable_strategies/digest.rb
@@ -2,6 +2,10 @@
module TokenAuthenticatableStrategies
class Digest < Base
+ def token_fields
+ super + [token_field_name]
+ end
+
def find_token_authenticatable(token, unscoped = false)
return unless token
diff --git a/app/models/concerns/token_authenticatable_strategies/encrypted.rb b/app/models/concerns/token_authenticatable_strategies/encrypted.rb
index e957d09fbc6..1db88c27181 100644
--- a/app/models/concerns/token_authenticatable_strategies/encrypted.rb
+++ b/app/models/concerns/token_authenticatable_strategies/encrypted.rb
@@ -2,6 +2,10 @@
module TokenAuthenticatableStrategies
class Encrypted < Base
+ def token_fields
+ super + [encrypted_field]
+ end
+
def find_token_authenticatable(token, unscoped = false)
return if token.blank?
diff --git a/app/models/concerns/update_namespace_statistics.rb b/app/models/concerns/update_namespace_statistics.rb
new file mode 100644
index 00000000000..26d6fc10228
--- /dev/null
+++ b/app/models/concerns/update_namespace_statistics.rb
@@ -0,0 +1,54 @@
+# frozen_string_literal: true
+
+# This module provides helpers for updating `NamespaceStatistics` with `after_save` and
+# `after_destroy` hooks.
+#
+# Models including this module must respond to and return a `namespace`
+#
+# Example:
+#
+# class DependencyProxy::Manifest
+# include UpdateNamespaceStatistics
+#
+# belongs_to :group
+# alias_attribute :namespace, :group
+#
+# update_namespace_statistics namespace_statistics_name: :dependency_proxy_size
+# end
+module UpdateNamespaceStatistics
+ extend ActiveSupport::Concern
+ include AfterCommitQueue
+
+ class_methods do
+ attr_reader :namespace_statistics_name, :statistic_attribute
+
+ # Configure the model to update `namespace_statistics_name` on NamespaceStatistics,
+ # when `statistic_attribute` changes
+ #
+ # - namespace_statistics_name: A column of `NamespaceStatistics` to update
+ # - statistic_attribute: An attribute of the current model, default to `size`
+ def update_namespace_statistics(namespace_statistics_name:, statistic_attribute: :size)
+ @namespace_statistics_name = namespace_statistics_name
+ @statistic_attribute = statistic_attribute
+
+ after_save(:schedule_namespace_statistics_refresh, if: :update_namespace_statistics?)
+ after_destroy(:schedule_namespace_statistics_refresh)
+ end
+
+ private :update_namespace_statistics
+ end
+
+ included do
+ private
+
+ def update_namespace_statistics?
+ saved_change_to_attribute?(self.class.statistic_attribute)
+ end
+
+ def schedule_namespace_statistics_refresh
+ run_after_commit do
+ Groups::UpdateStatisticsWorker.perform_async(namespace.id, [self.class.namespace_statistics_name])
+ end
+ end
+ end
+end
diff --git a/app/models/container_repository.rb b/app/models/container_repository.rb
index 1f123cb0244..fa03d73646d 100644
--- a/app/models/container_repository.rb
+++ b/app/models/container_repository.rb
@@ -14,6 +14,8 @@ class ContainerRepository < ApplicationRecord
ABORTABLE_MIGRATION_STATES = (ACTIVE_MIGRATION_STATES + %w[pre_import_done default]).freeze
MIGRATION_STATES = (IDLE_MIGRATION_STATES + ACTIVE_MIGRATION_STATES).freeze
+ MIGRATION_PHASE_1_STARTED_AT = Date.new(2021, 11, 4).freeze
+
TooManyImportsError = Class.new(StandardError)
NativeImportError = Class.new(StandardError)
@@ -64,7 +66,7 @@ class ContainerRepository < ApplicationRecord
# feature flag since it is only accessed in this query.
# https://gitlab.com/gitlab-org/gitlab/-/issues/350543 tracks the rollout and
# removal of this feature flag.
- joins(:project).where(
+ joins(project: [:namespace]).where(
migration_state: [:default],
created_at: ...ContainerRegistry::Migration.created_before
).with_target_import_tier
@@ -74,7 +76,7 @@ class ContainerRepository < ApplicationRecord
FROM feature_gates
WHERE feature_gates.feature_key = 'container_registry_phase_2_deny_list'
AND feature_gates.key = 'actors'
- AND feature_gates.value = concat('Group:', projects.namespace_id)
+ AND feature_gates.value = concat('Group:', namespaces.traversal_ids[1])
)"
)
end
@@ -408,6 +410,16 @@ class ContainerRepository < ApplicationRecord
update!(expiration_policy_started_at: Time.zone.now)
end
+ def size
+ strong_memoize(:size) do
+ next unless Gitlab.com?
+ next if self.created_at.before?(MIGRATION_PHASE_1_STARTED_AT)
+ next unless gitlab_api_client.supports_gitlab_api?
+
+ gitlab_api_client.repository_details(self.path, with_size: true)['size_bytes']
+ end
+ end
+
def migration_in_active_state?
migration_state.in?(ACTIVE_MIGRATION_STATES)
end
diff --git a/app/models/customer_relations/contact.rb b/app/models/customer_relations/contact.rb
index a981351f4a0..4fa2c3fb8cf 100644
--- a/app/models/customer_relations/contact.rb
+++ b/app/models/customer_relations/contact.rb
@@ -23,8 +23,9 @@ class CustomerRelations::Contact < ApplicationRecord
validates :last_name, presence: true, length: { maximum: 255 }
validates :email, length: { maximum: 255 }
validates :description, length: { maximum: 1024 }
+ validates :email, uniqueness: { scope: :group_id }
validate :validate_email_format
- validate :unique_email_for_group_hierarchy
+ validate :validate_root_group
def self.reference_prefix
'[contact:'
@@ -41,14 +42,13 @@ class CustomerRelations::Contact < ApplicationRecord
def self.find_ids_by_emails(group, emails)
raise ArgumentError, "Cannot lookup more than #{MAX_PLUCK} emails" if emails.length > MAX_PLUCK
- where(group_id: group.self_and_ancestor_ids, email: emails)
- .pluck(:id)
+ where(group: group, email: emails).pluck(:id)
end
def self.exists_for_group?(group)
return false unless group
- exists?(group_id: group.self_and_ancestor_ids)
+ exists?(group: group)
end
private
@@ -59,13 +59,9 @@ class CustomerRelations::Contact < ApplicationRecord
self.errors.add(:email, I18n.t(:invalid, scope: 'valid_email.validations.email')) unless ValidateEmail.valid?(self.email)
end
- def unique_email_for_group_hierarchy
- return unless group
- return unless email
+ def validate_root_group
+ return if group&.root?
- duplicate_email_exists = CustomerRelations::Contact
- .where(group_id: group.self_and_hierarchy.pluck(:id), email: email)
- .where.not(id: id).exists?
- self.errors.add(:email, _('contact with same email already exists in group hierarchy')) if duplicate_email_exists
+ self.errors.add(:base, _('contacts can only be added to root groups'))
end
end
diff --git a/app/models/customer_relations/issue_contact.rb b/app/models/customer_relations/issue_contact.rb
index 3e9d1e97c8c..dc7a3fd87bc 100644
--- a/app/models/customer_relations/issue_contact.rb
+++ b/app/models/customer_relations/issue_contact.rb
@@ -6,7 +6,7 @@ class CustomerRelations::IssueContact < ApplicationRecord
belongs_to :issue, optional: false, inverse_of: :customer_relations_contacts
belongs_to :contact, optional: false, inverse_of: :issue_contacts
- validate :contact_belongs_to_issue_group_or_ancestor
+ validate :contact_belongs_to_root_group
def self.find_contact_ids_by_emails(issue_id, emails)
raise ArgumentError, "Cannot lookup more than #{MAX_PLUCK} emails" if emails.length > MAX_PLUCK
@@ -24,11 +24,11 @@ class CustomerRelations::IssueContact < ApplicationRecord
private
- def contact_belongs_to_issue_group_or_ancestor
+ def contact_belongs_to_root_group
return unless contact&.group_id
return unless issue&.project&.namespace_id
- return if issue.project.group&.self_and_ancestor_ids&.include?(contact.group_id)
+ return if issue.project.root_ancestor&.id == contact.group_id
- errors.add(:base, _('The contact does not belong to the issue group or an ancestor'))
+ errors.add(:base, _("The contact does not belong to the issue group's root ancestor"))
end
end
diff --git a/app/models/customer_relations/organization.rb b/app/models/customer_relations/organization.rb
index c206d1e05f5..a23b9d8fe28 100644
--- a/app/models/customer_relations/organization.rb
+++ b/app/models/customer_relations/organization.rb
@@ -19,9 +19,18 @@ class CustomerRelations::Organization < ApplicationRecord
validates :name, uniqueness: { case_sensitive: false, scope: [:group_id] }
validates :name, length: { maximum: 255 }
validates :description, length: { maximum: 1024 }
+ validate :validate_root_group
def self.find_by_name(group_id, name)
where(group: group_id)
.where('LOWER(name) = LOWER(?)', name)
end
+
+ private
+
+ def validate_root_group
+ return if group&.root?
+
+ self.errors.add(:base, _('organizations can only be added to root groups'))
+ end
end
diff --git a/app/models/dependency_proxy/blob.rb b/app/models/dependency_proxy/blob.rb
index f7b08f1d077..dc40ff62adb 100644
--- a/app/models/dependency_proxy/blob.rb
+++ b/app/models/dependency_proxy/blob.rb
@@ -5,8 +5,10 @@ class DependencyProxy::Blob < ApplicationRecord
include TtlExpirable
include Packages::Destructible
include EachBatch
+ include UpdateNamespaceStatistics
belongs_to :group
+ alias_attribute :namespace, :group
MAX_FILE_SIZE = 5.gigabytes.freeze
@@ -17,6 +19,7 @@ class DependencyProxy::Blob < ApplicationRecord
scope :with_files_stored_locally, -> { where(file_store: ::DependencyProxy::FileUploader::Store::LOCAL) }
mount_file_store_uploader DependencyProxy::FileUploader
+ update_namespace_statistics namespace_statistics_name: :dependency_proxy_size
def self.total_size
sum(:size)
diff --git a/app/models/dependency_proxy/manifest.rb b/app/models/dependency_proxy/manifest.rb
index c2587ffac9d..5ad746e4cd1 100644
--- a/app/models/dependency_proxy/manifest.rb
+++ b/app/models/dependency_proxy/manifest.rb
@@ -5,8 +5,10 @@ class DependencyProxy::Manifest < ApplicationRecord
include TtlExpirable
include Packages::Destructible
include EachBatch
+ include UpdateNamespaceStatistics
belongs_to :group
+ alias_attribute :namespace, :group
MAX_FILE_SIZE = 10.megabytes.freeze
DIGEST_HEADER = 'Docker-Content-Digest'
@@ -20,6 +22,7 @@ class DependencyProxy::Manifest < ApplicationRecord
scope :with_files_stored_locally, -> { where(file_store: ::DependencyProxy::FileUploader::Store::LOCAL) }
mount_file_store_uploader DependencyProxy::FileUploader
+ update_namespace_statistics namespace_statistics_name: :dependency_proxy_size
def self.find_by_file_name_or_digest(file_name:, digest:)
find_by(file_name: file_name) || find_by(digest: digest)
diff --git a/app/models/deployment.rb b/app/models/deployment.rb
index 46409465209..c06c809538a 100644
--- a/app/models/deployment.rb
+++ b/app/models/deployment.rb
@@ -8,7 +8,6 @@ class Deployment < ApplicationRecord
include Importable
include Gitlab::Utils::StrongMemoize
include FastDestroyAll
- include FromUnion
StatusUpdateError = Class.new(StandardError)
StatusSyncError = Class.new(StandardError)
diff --git a/app/models/diff_note.rb b/app/models/diff_note.rb
index 6ebac6384bc..02979d5f804 100644
--- a/app/models/diff_note.rb
+++ b/app/models/diff_note.rb
@@ -145,7 +145,7 @@ class DiffNote < Note
end
def fetch_diff_file
- return note_diff_file.raw_diff_file if note_diff_file
+ return note_diff_file.raw_diff_file if note_diff_file && !note_diff_file.raw_diff_file.has_renderable?
if created_at_diff?(noteable.diff_refs)
# We're able to use the already persisted diffs (Postgres) if we're
diff --git a/app/models/environment.rb b/app/models/environment.rb
index 51a9024721b..450ed6206d5 100644
--- a/app/models/environment.rb
+++ b/app/models/environment.rb
@@ -461,11 +461,16 @@ class Environment < ApplicationRecord
# See https://en.wikipedia.org/wiki/Deployment_environment for industry standard deployment environments
def guess_tier
case name
- when %r{dev|review|trunk}i then self.class.tiers[:development]
- when %r{test|qc}i then self.class.tiers[:testing]
- when %r{st(a|)g|mod(e|)l|pre|demo}i then self.class.tiers[:staging]
- when %r{pr(o|)d|live}i then self.class.tiers[:production]
- else self.class.tiers[:other]
+ when /(dev|review|trunk)/i
+ self.class.tiers[:development]
+ when /(test|tst|int|ac(ce|)pt|qa|qc|control|quality)/i
+ self.class.tiers[:testing]
+ when /(st(a|)g|mod(e|)l|pre|demo)/i
+ self.class.tiers[:staging]
+ when /(pr(o|)d|live)/i
+ self.class.tiers[:production]
+ else
+ self.class.tiers[:other]
end
end
end
diff --git a/app/models/error_tracking/project_error_tracking_setting.rb b/app/models/error_tracking/project_error_tracking_setting.rb
index 25f812645b1..0a429bb7afd 100644
--- a/app/models/error_tracking/project_error_tracking_setting.rb
+++ b/app/models/error_tracking/project_error_tracking_setting.rb
@@ -59,6 +59,10 @@ module ErrorTracking
integrated
end
+ def integrated_enabled?
+ enabled? && integrated_client?
+ end
+
def gitlab_dsn
strong_memoize(:gitlab_dsn) do
client_key&.sentry_dsn
diff --git a/app/models/event_collection.rb b/app/models/event_collection.rb
index f799377a15f..fc093894847 100644
--- a/app/models/event_collection.rb
+++ b/app/models/event_collection.rb
@@ -44,31 +44,31 @@ class EventCollection
private
def project_events
- relation_with_join_lateral('project_id', projects)
+ in_operator_optimized_relation('project_id', projects)
end
- def project_and_group_events
- group_events = relation_with_join_lateral('group_id', groups)
+ def group_events
+ in_operator_optimized_relation('group_id', groups)
+ end
+ def project_and_group_events
Event.from_union([project_events, group_events]).recent
end
- # This relation is built using JOIN LATERAL, producing faster queries than a
- # regular LIMIT + OFFSET approach.
- def relation_with_join_lateral(parent_column, parents)
- parents_for_lateral = parents.select(:id).to_sql
-
- lateral = filtered_events
- # Applying the limit here (before we filter (permissions) means we may get less than limit)
- .limit(limit_for_join_lateral)
- .where("events.#{parent_column} = parents_for_lateral.id") # rubocop:disable GitlabSecurity/SqlInjection
- .to_sql
-
- # The outer query does not need to re-apply the filters since the JOIN
- # LATERAL body already takes care of this.
- base_relation
- .from("(#{parents_for_lateral}) parents_for_lateral")
- .joins("JOIN LATERAL (#{lateral}) AS #{Event.table_name} ON true")
+ def in_operator_optimized_relation(parent_column, parents)
+ scope = filtered_events
+ array_scope = parents.select(:id)
+ array_mapping_scope = -> (parent_id_expression) { Event.where(Event.arel_table[parent_column].eq(parent_id_expression)).reorder(id: :desc) }
+ finder_query = -> (id_expression) { Event.where(Event.arel_table[:id].eq(id_expression)) }
+
+ Gitlab::Pagination::Keyset::InOperatorOptimization::QueryBuilder
+ .new(
+ scope: scope,
+ array_scope: array_scope,
+ array_mapping_scope: array_mapping_scope,
+ finder_query: finder_query
+ )
+ .execute
end
def filtered_events
@@ -85,16 +85,6 @@ class EventCollection
Event.unscoped.recent
end
- def limit_for_join_lateral
- # Applying the OFFSET on the inside of a JOIN LATERAL leads to incorrect
- # results. To work around this we need to increase the inner limit for every
- # page.
- #
- # This means that on page 1 we use LIMIT 20, and an outer OFFSET of 0. On
- # page 2 we use LIMIT 40 and an outer OFFSET of 20.
- @limit + @offset
- end
-
def current_page
(@offset / @limit) + 1
end
diff --git a/app/models/group.rb b/app/models/group.rb
index 1d6a3a14450..14d088dd38b 100644
--- a/app/models/group.rb
+++ b/app/models/group.rb
@@ -19,7 +19,6 @@ class Group < Namespace
include BulkMemberAccessLoad
include ChronicDurationAttribute
include RunnerTokenExpirationInterval
- include RunnersTokenPrefixable
extend ::Gitlab::Utils::Override
@@ -120,7 +119,7 @@ class Group < Namespace
add_authentication_token_field :runners_token,
encrypted: -> { Feature.enabled?(:groups_tokens_optional_encryption, default_enabled: true) ? :optional : :required },
- prefix: RunnersTokenPrefixable::RUNNERS_TOKEN_PREFIX
+ prefix: RunnersTokenPrefixable::RUNNERS_TOKEN_PREFIX
after_create :post_create_hook
after_destroy :post_destroy_hook
@@ -676,7 +675,7 @@ class Group < Namespace
override :format_runners_token
def format_runners_token(token)
- "#{runners_token_prefix}#{token}"
+ "#{RunnersTokenPrefixable::RUNNERS_TOKEN_PREFIX}#{token}"
end
def project_creation_level
@@ -817,7 +816,9 @@ class Group < Namespace
private
def max_member_access(user_ids)
- max_member_access_for_resource_ids(User, user_ids) do |user_ids|
+ Gitlab::SafeRequestLoader.execute(resource_key: max_member_access_for_resource_key(User),
+ resource_ids: user_ids,
+ default_value: Gitlab::Access::NO_ACCESS) do |user_ids|
members_with_parents.where(user_id: user_ids).group(:user_id).maximum(:access_level)
end
end
@@ -892,6 +893,7 @@ class Group < Namespace
.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'))
+ .where(group_member_table[:state].eq(::Member::STATE_ACTIVE))
.non_minimal_access
end
diff --git a/app/models/hooks/web_hook.rb b/app/models/hooks/web_hook.rb
index 7e538238cbd..88941df691c 100644
--- a/app/models/hooks/web_hook.rb
+++ b/app/models/hooks/web_hook.rb
@@ -37,14 +37,14 @@ class WebHook < ApplicationRecord
!temporarily_disabled? && !permanently_disabled?
end
- def temporarily_disabled?
- return false unless web_hooks_disable_failed?
+ def temporarily_disabled?(ignore_flag: false)
+ return false unless ignore_flag || web_hooks_disable_failed?
disabled_until.present? && disabled_until >= Time.current
end
- def permanently_disabled?
- return false unless web_hooks_disable_failed?
+ def permanently_disabled?(ignore_flag: false)
+ return false unless ignore_flag || web_hooks_disable_failed?
recent_failures > FAILURE_THRESHOLD
end
@@ -106,6 +106,13 @@ class WebHook < ApplicationRecord
save(validate: false)
end
+ def active_state(ignore_flag: false)
+ return :permanently_disabled if permanently_disabled?(ignore_flag: ignore_flag)
+ return :temporarily_disabled if temporarily_disabled?(ignore_flag: ignore_flag)
+
+ :enabled
+ end
+
# @return [Boolean] Whether or not the WebHook is currently throttled.
def rate_limited?
return false unless rate_limit
diff --git a/app/models/instance_configuration.rb b/app/models/instance_configuration.rb
index 2016024b2f4..00e55d0fd89 100644
--- a/app/models/instance_configuration.rb
+++ b/app/models/instance_configuration.rb
@@ -118,7 +118,8 @@ class InstanceConfiguration
group_export_download: application_setting_limit_per_minute(:group_download_export_limit),
group_import: application_setting_limit_per_minute(:group_import_limit),
raw_blob: application_setting_limit_per_minute(:raw_blob_request_limit),
- user_email_lookup: application_setting_limit_per_minute(:user_email_lookup_limit),
+ search_rate_limit: application_setting_limit_per_minute(:search_rate_limit),
+ search_rate_limit_unauthenticated: application_setting_limit_per_minute(:search_rate_limit_unauthenticated),
users_get_by_id: {
enabled: application_settings[:users_get_by_id_limit] > 0,
requests_per_period: application_settings[:users_get_by_id_limit],
diff --git a/app/models/integration.rb b/app/models/integration.rb
index e9cd90649ba..274c16507b7 100644
--- a/app/models/integration.rb
+++ b/app/models/integration.rb
@@ -9,10 +9,18 @@ class Integration < ApplicationRecord
include Integrations::HasDataFields
include FromUnion
include EachBatch
+ include IgnorableColumns
+
+ ignore_column :template, remove_with: '15.0', remove_after: '2022-04-22'
+ ignore_column :type, remove_with: '15.0', remove_after: '2022-04-22'
+
+ UnknownType = Class.new(StandardError)
+
+ self.inheritance_column = :type_new
INTEGRATION_NAMES = %w[
asana assembla bamboo bugzilla buildkite campfire confluence custom_issue_tracker datadog discord
- drone_ci emails_on_push ewm external_wiki flowdock hangouts_chat irker jira
+ drone_ci emails_on_push ewm external_wiki flowdock hangouts_chat harbor irker jira
mattermost mattermost_slash_commands microsoft_teams packagist pipelines_email
pivotaltracker prometheus pushover redmine slack slack_slash_commands teamcity unify_circuit webex_teams youtrack zentao
].freeze
@@ -37,9 +45,21 @@ class Integration < ApplicationRecord
Integrations::BaseSlashCommands
].freeze
+ SECTION_TYPE_CONNECTION = 'connection'
+
serialize :properties, JSON # rubocop:disable Cop/ActiveRecordSerialize
- attribute :type, Gitlab::Integrations::StiType.new
+ attr_encrypted :encrypted_properties_tmp,
+ attribute: :encrypted_properties,
+ mode: :per_attribute_iv,
+ key: Settings.attr_encrypted_db_key_base_32,
+ algorithm: 'aes-256-gcm',
+ marshal: true,
+ marshaler: ::Gitlab::Json,
+ encode: false,
+ encode_iv: false
+
+ alias_attribute :type, :type_new
default_value_for :active, false
default_value_for :alert_events, true
@@ -57,6 +77,8 @@ class Integration < ApplicationRecord
default_value_for :wiki_page_events, true
after_initialize :initialize_properties
+ after_initialize :copy_properties_to_encrypted_properties
+ before_save :copy_properties_to_encrypted_properties
after_commit :reset_updated_properties
@@ -74,9 +96,10 @@ class Integration < ApplicationRecord
validate :validate_belongs_to_project_or_group
scope :external_issue_trackers, -> { where(category: 'issue_tracker').active }
- scope :external_wikis, -> { where(type: 'ExternalWikiService').active }
+ scope :by_name, ->(name) { by_type(integration_name_to_type(name)) }
+ scope :external_wikis, -> { by_name(:external_wiki).active }
scope :active, -> { where(active: true) }
- scope :by_type, -> (type) { where(type: type) }
+ scope :by_type, ->(type) { where(type: type) } # INTERNAL USE ONLY: use by_name instead
scope :by_active_flag, -> (flag) { where(active: flag) }
scope :inherit_from_id, -> (id) { where(inherit_from_id: id) }
scope :with_default_settings, -> { where.not(inherit_from_id: nil) }
@@ -99,6 +122,39 @@ class Integration < ApplicationRecord
scope :alert_hooks, -> { where(alert_events: true, active: true) }
scope :deployment, -> { where(category: 'deployment') }
+ class << self
+ private
+
+ attr_writer :field_storage
+
+ def field_storage
+ @field_storage || :properties
+ end
+ end
+
+ # :nocov: Tested on subclasses.
+ def self.field(name, storage: field_storage, **attrs)
+ fields << ::Integrations::Field.new(name: name, **attrs)
+
+ case storage
+ when :properties
+ prop_accessor(name)
+ when :data_fields
+ data_field(name)
+ else
+ raise ArgumentError, "Unknown field storage: #{storage}"
+ end
+ end
+ # :nocov:
+
+ def self.fields
+ @fields ||= []
+ end
+
+ def fields
+ self.class.fields
+ end
+
# Provide convenient accessor methods for each serialized property.
# Also keep track of updated properties in a similar way as ActiveModel::Dirty
def self.prop_accessor(*args)
@@ -112,8 +168,10 @@ class Integration < ApplicationRecord
def #{arg}=(value)
self.properties ||= {}
+ self.encrypted_properties_tmp = properties
updated_properties['#{arg}'] = #{arg} unless #{arg}_changed?
self.properties['#{arg}'] = value
+ self.encrypted_properties_tmp['#{arg}'] = value
end
def #{arg}_changed?
@@ -158,10 +216,6 @@ class Integration < ApplicationRecord
self.supported_events.map { |event| IntegrationsHelper.integration_event_field_name(event) }
end
- def self.supported_event_actions
- %w[]
- end
-
def self.supported_events
%w[commit push tag_push issue confidential_issue merge_request wiki_page]
end
@@ -226,7 +280,7 @@ class Integration < ApplicationRecord
end
# Returns a list of available integration types.
- # Example: ["AsanaService", ...]
+ # Example: ["Integrations::Asana", ...]
def self.available_integration_types(include_project_specific: true, include_dev: true)
available_integration_names(include_project_specific: include_project_specific, include_dev: include_dev).map do
integration_name_to_type(_1)
@@ -234,22 +288,27 @@ class Integration < ApplicationRecord
end
# Returns the model for the given integration name.
- # Example: "asana" => Integrations::Asana
+ # Example: :asana => Integrations::Asana
def self.integration_name_to_model(name)
type = integration_name_to_type(name)
integration_type_to_model(type)
end
# Returns the STI type for the given integration name.
- # Example: "asana" => "AsanaService"
+ # Example: "asana" => "Integrations::Asana"
def self.integration_name_to_type(name)
- "#{name}_service".camelize
+ name = name.to_s
+ if available_integration_names.exclude?(name)
+ Gitlab::ErrorTracking.track_and_raise_for_dev_exception(UnknownType.new(name.inspect))
+ else
+ "Integrations::#{name.camelize}"
+ end
end
# Returns the model for the given STI type.
- # Example: "AsanaService" => Integrations::Asana
+ # Example: "Integrations::Asana" => Integrations::Asana
def self.integration_type_to_model(type)
- Gitlab::Integrations::StiType.new.cast(type).constantize
+ type.constantize
end
private_class_method :integration_type_to_model
@@ -298,7 +357,7 @@ class Integration < ApplicationRecord
from_union([
active.where(instance: true),
active.where(group_id: group_ids, inherit_from_id: nil)
- ]).order(Arel.sql("type ASC, array_position(#{array}::bigint[], #{table_name}.group_id), instance DESC")).group_by(&:type).each do |type, records|
+ ]).order(Arel.sql("type_new ASC, array_position(#{array}::bigint[], #{table_name}.group_id), instance DESC")).group_by(&:type).each do |type, records|
build_from_integration(records.first, association => scope.id).save
end
end
@@ -330,6 +389,10 @@ class Integration < ApplicationRecord
true
end
+ def activate_disabled_reason
+ nil
+ end
+
def category
read_attribute(:category).to_sym
end
@@ -338,6 +401,12 @@ class Integration < ApplicationRecord
self.properties = {} if has_attribute?(:properties) && properties.nil?
end
+ def copy_properties_to_encrypted_properties
+ self.encrypted_properties_tmp = properties
+ rescue ActiveModel::MissingAttributeError
+ # ignore - in a record built from using a restricted select list
+ end
+
def title
# implement inside child
end
@@ -355,8 +424,7 @@ class Integration < ApplicationRecord
self.class.to_param
end
- def fields
- # implement inside child
+ def sections
[]
end
@@ -371,8 +439,24 @@ class Integration < ApplicationRecord
%w[active]
end
+ # return a hash of columns => values suitable for passing to insert_all
def to_integration_hash
- as_json(methods: :type, except: %w[id instance project_id group_id])
+ column = self.class.attribute_aliases.fetch('type', 'type')
+ copy_properties_to_encrypted_properties
+
+ as_json(except: %w[id instance project_id group_id encrypted_properties_tmp])
+ .merge(column => type)
+ .merge(reencrypt_properties)
+ end
+
+ def reencrypt_properties
+ unless properties.nil? || properties.empty?
+ alg = self.class.encrypted_attributes[:encrypted_properties_tmp][:algorithm]
+ iv = generate_iv(alg)
+ ep = self.class.encrypt(:encrypted_properties_tmp, properties, { iv: iv })
+ end
+
+ { 'encrypted_properties' => ep, 'encrypted_properties_iv' => iv }
end
def to_data_fields_hash
@@ -392,7 +476,10 @@ class Integration < ApplicationRecord
end
def api_field_names
- fields.pluck(:name).grep_v(/password|token|key|title|description/)
+ fields
+ .reject { _1[:type] == 'password' }
+ .pluck(:name)
+ .grep_v(/password|token|key/)
end
def global_fields
@@ -410,10 +497,6 @@ class Integration < ApplicationRecord
end
end
- def configurable_event_actions
- self.class.supported_event_actions
- end
-
def supported_events
self.class.supported_events
end
diff --git a/app/models/integrations/asana.rb b/app/models/integrations/asana.rb
index 7949563a1dc..054f0606dd2 100644
--- a/app/models/integrations/asana.rb
+++ b/app/models/integrations/asana.rb
@@ -4,8 +4,6 @@ require 'asana'
module Integrations
class Asana < Integration
- include ActionView::Helpers::UrlHelper
-
prop_accessor :api_key, :restrict_to_branch
validates :api_key, presence: true, if: :activated?
@@ -18,7 +16,7 @@ module Integrations
end
def help
- docs_link = link_to _('Learn more.'), Rails.application.routes.url_helpers.help_page_url('user/project/integrations/asana'), target: '_blank', rel: 'noopener noreferrer'
+ docs_link = ActionController::Base.helpers.link_to _('Learn more.'), Rails.application.routes.url_helpers.help_page_url('user/project/integrations/asana'), target: '_blank', rel: 'noopener noreferrer'
s_('Add commit messages as comments to Asana tasks. %{docs_link}').html_safe % { docs_link: docs_link.html_safe }
end
diff --git a/app/models/integrations/bamboo.rb b/app/models/integrations/bamboo.rb
index 57767c63cf4..c614a9415ab 100644
--- a/app/models/integrations/bamboo.rb
+++ b/app/models/integrations/bamboo.rb
@@ -2,7 +2,6 @@
module Integrations
class Bamboo < BaseCi
- include ActionView::Helpers::UrlHelper
include ReactivelyCached
prepend EnableSslVerification
@@ -36,7 +35,7 @@ module Integrations
end
def help
- docs_link = link_to _('Learn more.'), Rails.application.routes.url_helpers.help_page_url('user/project/integrations/bamboo'), target: '_blank', rel: 'noopener noreferrer'
+ docs_link = ActionController::Base.helpers.link_to _('Learn more.'), Rails.application.routes.url_helpers.help_page_url('user/project/integrations/bamboo'), target: '_blank', rel: 'noopener noreferrer'
s_('BambooService|Run CI/CD pipelines with Atlassian Bamboo. You must set up automatic revision labeling and a repository trigger in Bamboo. %{docs_link}').html_safe % { docs_link: docs_link.html_safe }
end
diff --git a/app/models/integrations/base_chat_notification.rb b/app/models/integrations/base_chat_notification.rb
index d0d54a92021..d5b6357cb66 100644
--- a/app/models/integrations/base_chat_notification.rb
+++ b/app/models/integrations/base_chat_notification.rb
@@ -241,7 +241,6 @@ module Integrations
def notify_for_ref?(data)
return true if data[:object_kind] == 'tag_push'
- return true if data[:object_kind] == 'deployment' && !Feature.enabled?(:chat_notification_deployment_protected_branch_filter, project)
ref = data[:ref] || data.dig(:object_attributes, :ref)
return true if ref.blank? # No need to check protected branches when there is no ref
diff --git a/app/models/integrations/base_issue_tracker.rb b/app/models/integrations/base_issue_tracker.rb
index 42a6a3a19c8..458d0199e7a 100644
--- a/app/models/integrations/base_issue_tracker.rb
+++ b/app/models/integrations/base_issue_tracker.rb
@@ -4,10 +4,6 @@ module Integrations
class BaseIssueTracker < Integration
validate :one_issue_tracker, if: :activated?, on: :manual_change
- # TODO: we can probably just delegate as part of
- # https://gitlab.com/gitlab-org/gitlab/issues/29404
- data_field :project_url, :issues_url, :new_issue_url
-
default_value_for :category, 'issue_tracker'
before_validation :handle_properties
@@ -72,14 +68,6 @@ module Integrations
issue_url(iid)
end
- def fields
- [
- { type: 'text', name: 'project_url', title: _('Project URL'), help: s_('IssueTracker|The URL to the project in the external issue tracker.'), required: true },
- { type: 'text', name: 'issues_url', title: s_('IssueTracker|Issue URL'), help: s_('IssueTracker|The URL to view an issue in the external issue tracker. Must contain %{colon_id}.') % { colon_id: '<code>:id</code>'.html_safe }, required: true },
- { type: 'text', name: 'new_issue_url', title: s_('IssueTracker|New issue URL'), help: s_('IssueTracker|The URL to create an issue in the external issue tracker.'), required: true }
- ]
- end
-
def initialize_properties
{}
end
@@ -132,8 +120,18 @@ module Integrations
# implement inside child
end
+ def activate_disabled_reason
+ { trackers: other_external_issue_trackers } if other_external_issue_trackers.any?
+ end
+
private
+ def other_external_issue_trackers
+ return [] unless project_level?
+
+ @other_external_issue_trackers ||= project.integrations.external_issue_trackers.where.not(id: id)
+ end
+
def enabled_in_gitlab_config
Gitlab.config.issues_tracker &&
Gitlab.config.issues_tracker.values.any? &&
@@ -145,10 +143,10 @@ module Integrations
end
def one_issue_tracker
- return if template? || instance?
+ return if instance?
return if project.blank?
- if project.integrations.external_issue_trackers.where.not(id: id).any?
+ if other_external_issue_trackers.any?
errors.add(:base, _('Another issue tracker is already in use. Only one issue tracker service can be active at a time'))
end
end
diff --git a/app/models/integrations/bugzilla.rb b/app/models/integrations/bugzilla.rb
index 9251015acb8..74e282f6848 100644
--- a/app/models/integrations/bugzilla.rb
+++ b/app/models/integrations/bugzilla.rb
@@ -2,7 +2,7 @@
module Integrations
class Bugzilla < BaseIssueTracker
- include ActionView::Helpers::UrlHelper
+ include Integrations::HasIssueTrackerFields
validates :project_url, :issues_url, :new_issue_url, presence: true, public_url: true, if: :activated?
@@ -15,7 +15,7 @@ module Integrations
end
def help
- docs_link = link_to _('Learn more.'), Rails.application.routes.url_helpers.help_page_url('user/project/integrations/bugzilla'), target: '_blank', rel: 'noopener noreferrer'
+ docs_link = ActionController::Base.helpers.link_to _('Learn more.'), Rails.application.routes.url_helpers.help_page_url('user/project/integrations/bugzilla'), target: '_blank', rel: 'noopener noreferrer'
s_("IssueTracker|Use Bugzilla as this project's issue tracker. %{docs_link}").html_safe % { docs_link: docs_link.html_safe }
end
diff --git a/app/models/integrations/campfire.rb b/app/models/integrations/campfire.rb
index c78fc6eff51..81e6c2411b8 100644
--- a/app/models/integrations/campfire.rb
+++ b/app/models/integrations/campfire.rb
@@ -2,8 +2,6 @@
module Integrations
class Campfire < Integration
- include ActionView::Helpers::UrlHelper
-
prop_accessor :token, :subdomain, :room
validates :token, presence: true, if: :activated?
@@ -16,7 +14,7 @@ module Integrations
end
def help
- docs_link = link_to _('Learn more.'), Rails.application.routes.url_helpers.help_page_url('api/services', anchor: 'campfire'), target: '_blank', rel: 'noopener noreferrer'
+ docs_link = ActionController::Base.helpers.link_to _('Learn more.'), Rails.application.routes.url_helpers.help_page_url('api/services', anchor: 'campfire'), target: '_blank', rel: 'noopener noreferrer'
s_('CampfireService|Send notifications about push events to Campfire chat rooms. %{docs_link}').html_safe % { docs_link: docs_link.html_safe }
end
diff --git a/app/models/integrations/confluence.rb b/app/models/integrations/confluence.rb
index 7f111f482dd..65adce7a8d6 100644
--- a/app/models/integrations/confluence.rb
+++ b/app/models/integrations/confluence.rb
@@ -2,8 +2,6 @@
module Integrations
class Confluence < Integration
- include ActionView::Helpers::UrlHelper
-
VALID_SCHEME_MATCH = %r{\Ahttps?\Z}.freeze
VALID_HOST_MATCH = %r{\A.+\.atlassian\.net\Z}.freeze
VALID_PATH_MATCH = %r{\A/wiki(/|\Z)}.freeze
@@ -39,7 +37,7 @@ module Integrations
s_(
'ConfluenceService|Your GitLab wiki is still available at %{wiki_link}. To re-enable the link to the GitLab wiki, disable this integration.' %
- { wiki_link: link_to(wiki_url, wiki_url) }
+ { wiki_link: ActionController::Base.helpers.link_to(wiki_url, wiki_url) }
).html_safe
else
s_('ConfluenceService|Link to a Confluence Workspace from the sidebar. Enabling this integration replaces the "Wiki" sidebar link with a link to the Confluence Workspace. The GitLab wiki is still available at the original URL.').html_safe
diff --git a/app/models/integrations/custom_issue_tracker.rb b/app/models/integrations/custom_issue_tracker.rb
index 635a9d093e9..3770e813eaa 100644
--- a/app/models/integrations/custom_issue_tracker.rb
+++ b/app/models/integrations/custom_issue_tracker.rb
@@ -2,7 +2,8 @@
module Integrations
class CustomIssueTracker < BaseIssueTracker
- include ActionView::Helpers::UrlHelper
+ include HasIssueTrackerFields
+
validates :project_url, :issues_url, :new_issue_url, presence: true, public_url: true, if: :activated?
def title
@@ -14,7 +15,7 @@ module Integrations
end
def help
- docs_link = link_to _('Learn more.'), Rails.application.routes.url_helpers.help_page_url('user/project/integrations/custom_issue_tracker'), target: '_blank', rel: 'noopener noreferrer'
+ docs_link = ActionController::Base.helpers.link_to _('Learn more.'), Rails.application.routes.url_helpers.help_page_url('user/project/integrations/custom_issue_tracker'), target: '_blank', rel: 'noopener noreferrer'
s_('IssueTracker|Use a custom issue tracker that is not in the integration list. %{docs_link}').html_safe % { docs_link: docs_link.html_safe }
end
diff --git a/app/models/integrations/discord.rb b/app/models/integrations/discord.rb
index 21993dd3c43..790e41e5a2a 100644
--- a/app/models/integrations/discord.rb
+++ b/app/models/integrations/discord.rb
@@ -4,8 +4,6 @@ require "discordrb/webhooks"
module Integrations
class Discord < BaseChatNotification
- include ActionView::Helpers::UrlHelper
-
ATTACHMENT_REGEX = /: (?<entry>.*?)\n - (?<name>.*)\n*/.freeze
def title
@@ -21,7 +19,7 @@ module Integrations
end
def help
- docs_link = link_to _('How do I set up this service?'), Rails.application.routes.url_helpers.help_page_url('user/project/integrations/discord_notifications'), target: '_blank', rel: 'noopener noreferrer'
+ docs_link = ActionController::Base.helpers.link_to _('How do I set up this service?'), Rails.application.routes.url_helpers.help_page_url('user/project/integrations/discord_notifications'), target: '_blank', rel: 'noopener noreferrer'
s_('Send notifications about project events to a Discord channel. %{docs_link}').html_safe % { docs_link: docs_link.html_safe }
end
diff --git a/app/models/integrations/ewm.rb b/app/models/integrations/ewm.rb
index 24d343b7cb4..1b86ef73c85 100644
--- a/app/models/integrations/ewm.rb
+++ b/app/models/integrations/ewm.rb
@@ -2,7 +2,7 @@
module Integrations
class Ewm < BaseIssueTracker
- include ActionView::Helpers::UrlHelper
+ include HasIssueTrackerFields
validates :project_url, :issues_url, :new_issue_url, presence: true, public_url: true, if: :activated?
@@ -19,7 +19,7 @@ module Integrations
end
def help
- docs_link = link_to _('Learn more.'), Rails.application.routes.url_helpers.help_page_url('user/project/integrations/ewm'), target: '_blank', rel: 'noopener noreferrer'
+ docs_link = ActionController::Base.helpers.link_to _('Learn more.'), Rails.application.routes.url_helpers.help_page_url('user/project/integrations/ewm'), target: '_blank', rel: 'noopener noreferrer'
s_("IssueTracker|Use IBM Engineering Workflow Management as this project's issue tracker. %{docs_link}").html_safe % { docs_link: docs_link.html_safe }
end
diff --git a/app/models/integrations/external_wiki.rb b/app/models/integrations/external_wiki.rb
index 2a8d598117b..18c48411e30 100644
--- a/app/models/integrations/external_wiki.rb
+++ b/app/models/integrations/external_wiki.rb
@@ -2,8 +2,6 @@
module Integrations
class ExternalWiki < Integration
- include ActionView::Helpers::UrlHelper
-
prop_accessor :external_wiki_url
validates :external_wiki_url, presence: true, public_url: true, if: :activated?
@@ -33,7 +31,7 @@ module Integrations
end
def help
- docs_link = link_to _('Learn more.'), Rails.application.routes.url_helpers.help_page_url('user/project/wiki/index', anchor: 'link-an-external-wiki'), target: '_blank', rel: 'noopener noreferrer'
+ docs_link = ActionController::Base.helpers.link_to _('Learn more.'), Rails.application.routes.url_helpers.help_page_url('user/project/wiki/index', anchor: 'link-an-external-wiki'), target: '_blank', rel: 'noopener noreferrer'
s_('Link an external wiki from the project\'s sidebar. %{docs_link}').html_safe % { docs_link: docs_link.html_safe }
end
diff --git a/app/models/integrations/field.rb b/app/models/integrations/field.rb
new file mode 100644
index 00000000000..49ab97677db
--- /dev/null
+++ b/app/models/integrations/field.rb
@@ -0,0 +1,42 @@
+# frozen_string_literal: true
+
+module Integrations
+ class Field
+ SENSITIVE_NAME = %r/token|key|password|passphrase|secret/.freeze
+
+ ATTRIBUTES = %i[
+ section type placeholder required choices value checkbox_label
+ title help
+ non_empty_password_help
+ non_empty_password_title
+ api_only
+ ].freeze
+
+ attr_reader :name
+
+ def initialize(name:, type: 'text', api_only: false, **attributes)
+ @name = name.to_s.freeze
+
+ attributes[:type] = SENSITIVE_NAME.match?(@name) ? 'password' : type
+ attributes[:api_only] = api_only
+ @attributes = attributes.freeze
+ end
+
+ def [](key)
+ return name if key == :name
+
+ value = @attributes[key]
+ return value.call if value.respond_to?(:call)
+
+ value
+ end
+
+ def sensitive?
+ @attributes[:type] == 'password'
+ end
+
+ ATTRIBUTES.each do |name|
+ define_method(name) { self[name] }
+ end
+ end
+end
diff --git a/app/models/integrations/flowdock.rb b/app/models/integrations/flowdock.rb
index 443f61e65dd..476cdc35585 100644
--- a/app/models/integrations/flowdock.rb
+++ b/app/models/integrations/flowdock.rb
@@ -2,8 +2,6 @@
module Integrations
class Flowdock < Integration
- include ActionView::Helpers::UrlHelper
-
prop_accessor :token
validates :token, presence: true, if: :activated?
@@ -16,7 +14,7 @@ module Integrations
end
def help
- docs_link = link_to _('Learn more.'), Rails.application.routes.url_helpers.help_page_url('api/services', anchor: 'flowdock'), target: '_blank', rel: 'noopener noreferrer'
+ docs_link = ActionController::Base.helpers.link_to _('Learn more.'), Rails.application.routes.url_helpers.help_page_url('api/services', anchor: 'flowdock'), target: '_blank', rel: 'noopener noreferrer'
s_('FlowdockService|Send event notifications from GitLab to Flowdock flows. %{docs_link}').html_safe % { docs_link: docs_link.html_safe }
end
diff --git a/app/models/integrations/hangouts_chat.rb b/app/models/integrations/hangouts_chat.rb
index 0d6b9fb1019..8c68c9ff95a 100644
--- a/app/models/integrations/hangouts_chat.rb
+++ b/app/models/integrations/hangouts_chat.rb
@@ -2,8 +2,6 @@
module Integrations
class HangoutsChat < BaseChatNotification
- include ActionView::Helpers::UrlHelper
-
def title
'Google Chat'
end
@@ -17,7 +15,7 @@ module Integrations
end
def help
- docs_link = link_to _('How do I set up a Google Chat webhook?'), Rails.application.routes.url_helpers.help_page_url('user/project/integrations/hangouts_chat'), target: '_blank', rel: 'noopener noreferrer'
+ docs_link = ActionController::Base.helpers.link_to _('How do I set up a Google Chat webhook?'), Rails.application.routes.url_helpers.help_page_url('user/project/integrations/hangouts_chat'), target: '_blank', rel: 'noopener noreferrer'
s_('Before enabling this integration, create a webhook for the room in Google Chat where you want to receive notifications from this project. %{docs_link}').html_safe % { docs_link: docs_link.html_safe }
end
diff --git a/app/models/integrations/harbor.rb b/app/models/integrations/harbor.rb
new file mode 100644
index 00000000000..4c76e418886
--- /dev/null
+++ b/app/models/integrations/harbor.rb
@@ -0,0 +1,104 @@
+# frozen_string_literal: true
+
+module Integrations
+ class Harbor < Integration
+ prop_accessor :url, :project_name, :username, :password
+
+ validates :url, public_url: true, presence: true, if: :activated?
+ validates :project_name, presence: true, if: :activated?
+ validates :username, presence: true, if: :activated?
+ validates :password, format: { with: ::Ci::Maskable::REGEX }, if: :activated?
+
+ before_validation :reset_username_and_password
+
+ def title
+ 'Harbor'
+ end
+
+ def description
+ s_("HarborIntegration|Use Harbor as this project's container registry.")
+ end
+
+ def help
+ s_("HarborIntegration|After the Harbor integration is activated, global variables ‘$HARBOR_USERNAME’, ‘$HARBOR_PASSWORD’, ‘$HARBOR_URL’ and ‘$HARBOR_PROJECT’ will be created for CI/CD use.")
+ end
+
+ class << self
+ def to_param
+ name.demodulize.downcase
+ end
+
+ def supported_events
+ []
+ end
+
+ def supported_event_actions
+ []
+ end
+ end
+
+ def test(*_args)
+ client.ping
+ end
+
+ def fields
+ [
+ {
+ type: 'text',
+ name: 'url',
+ title: s_('HarborIntegration|Harbor URL'),
+ placeholder: 'https://demo.goharbor.io',
+ help: s_('HarborIntegration|Base URL of the Harbor instance.'),
+ required: true
+ },
+ {
+ type: 'text',
+ name: 'project_name',
+ title: s_('HarborIntegration|Harbor project name'),
+ help: s_('HarborIntegration|The name of the project in Harbor.')
+ },
+ {
+ type: 'text',
+ name: 'username',
+ title: s_('HarborIntegration|Harbor username'),
+ required: true
+ },
+ {
+ type: 'text',
+ name: 'password',
+ title: s_('HarborIntegration|Harbor password'),
+ non_empty_password_title: s_('HarborIntegration|Enter Harbor password'),
+ non_empty_password_help: s_('HarborIntegration|Password for your Harbor username.'),
+ required: true
+ }
+ ]
+ end
+
+ def ci_variables
+ return [] unless activated?
+
+ [
+ { key: 'HARBOR_URL', value: url },
+ { key: 'HARBOR_PROJECT', value: project_name },
+ { key: 'HARBOR_USERNAME', value: username },
+ { key: 'HARBOR_PASSWORD', value: password, public: false, masked: true }
+ ]
+ end
+
+ private
+
+ def client
+ @client ||= ::Gitlab::Harbor::Client.new(self)
+ end
+
+ def reset_username_and_password
+ if url_changed? && !password_touched?
+ self.password = nil
+ end
+
+ if url_changed? && !username_touched?
+ self.username = nil
+ end
+ end
+ end
+end
diff --git a/app/models/integrations/irker.rb b/app/models/integrations/irker.rb
index cea4aa2038d..116d1fb233d 100644
--- a/app/models/integrations/irker.rb
+++ b/app/models/integrations/irker.rb
@@ -4,8 +4,6 @@ require 'uri'
module Integrations
class Irker < Integration
- include ActionView::Helpers::UrlHelper
-
prop_accessor :server_host, :server_port, :default_irc_uri
prop_accessor :recipients, :channels
boolean_accessor :colorize_messages
@@ -44,7 +42,7 @@ module Integrations
end
def fields
- recipients_docs_link = link_to s_('IrkerService|How to enter channels or users?'), Rails.application.routes.url_helpers.help_page_url('user/project/integrations/irker', anchor: 'enter-irker-recipients'), target: '_blank', rel: 'noopener noreferrer'
+ recipients_docs_link = ActionController::Base.helpers.link_to s_('IrkerService|How to enter channels or users?'), Rails.application.routes.url_helpers.help_page_url('user/project/integrations/irker', anchor: 'enter-irker-recipients'), target: '_blank', rel: 'noopener noreferrer'
[
{ type: 'text', name: 'server_host', placeholder: 'localhost', title: s_('IrkerService|Server host (optional)'),
help: s_('IrkerService|irker daemon hostname (defaults to localhost).') },
@@ -61,7 +59,7 @@ module Integrations
end
def help
- docs_link = link_to _('Learn more.'), Rails.application.routes.url_helpers.help_page_url('user/project/integrations/irker', anchor: 'set-up-an-irker-daemon'), target: '_blank', rel: 'noopener noreferrer'
+ docs_link = ActionController::Base.helpers.link_to _('Learn more.'), Rails.application.routes.url_helpers.help_page_url('user/project/integrations/irker', anchor: 'set-up-an-irker-daemon'), target: '_blank', rel: 'noopener noreferrer'
s_('IrkerService|Send update messages to an irker server. Before you can use this, you need to set up the irker daemon. %{docs_link}').html_safe % { docs_link: docs_link.html_safe }
end
diff --git a/app/models/integrations/jenkins.rb b/app/models/integrations/jenkins.rb
index 5ea92170c26..32f11ee23eb 100644
--- a/app/models/integrations/jenkins.rb
+++ b/app/models/integrations/jenkins.rb
@@ -3,7 +3,7 @@
module Integrations
class Jenkins < BaseCi
include HasWebHook
- include ActionView::Helpers::UrlHelper
+
prepend EnableSslVerification
extend Gitlab::Utils::Override
@@ -65,7 +65,7 @@ module Integrations
end
def help
- docs_link = link_to _('Learn more.'), Rails.application.routes.url_helpers.help_page_url('integration/jenkins'), target: '_blank', rel: 'noopener noreferrer'
+ docs_link = ActionController::Base.helpers.link_to _('Learn more.'), Rails.application.routes.url_helpers.help_page_url('integration/jenkins'), target: '_blank', rel: 'noopener noreferrer'
s_('Run CI/CD pipelines with Jenkins when you push to a repository, or when a merge request is created, updated, or merged. %{docs_link}').html_safe % { docs_link: docs_link.html_safe }
end
diff --git a/app/models/integrations/jira.rb b/app/models/integrations/jira.rb
index 966ad07afad..74ece57000f 100644
--- a/app/models/integrations/jira.rb
+++ b/app/models/integrations/jira.rb
@@ -15,6 +15,9 @@ module Integrations
ATLASSIAN_REFERRER_GITLAB_COM = { atlOrigin: 'eyJpIjoiY2QyZTJiZDRkNGZhNGZlMWI3NzRkNTBmZmVlNzNiZTkiLCJwIjoianN3LWdpdGxhYi1pbnQifQ' }.freeze
ATLASSIAN_REFERRER_SELF_MANAGED = { atlOrigin: 'eyJpIjoiYjM0MTA4MzUyYTYxNDVkY2IwMzVjOGQ3ZWQ3NzMwM2QiLCJwIjoianN3LWdpdGxhYlNNLWludCJ9' }.freeze
+ SECTION_TYPE_JIRA_TRIGGER = 'jira_trigger'
+ SECTION_TYPE_JIRA_ISSUES = 'jira_issues'
+
validates :url, public_url: true, presence: true, if: :activated?
validates :api_url, public_url: true, allow_blank: true
validates :username, presence: true, if: :activated?
@@ -28,11 +31,6 @@ module Integrations
# We should use username/password for Jira Server and email/api_token for Jira Cloud,
# for more information check: https://gitlab.com/gitlab-org/gitlab-foss/issues/49936.
- # TODO: we can probably just delegate as part of
- # https://gitlab.com/gitlab-org/gitlab/issues/29404
- data_field :username, :password, :url, :api_url, :jira_issue_transition_automatic, :jira_issue_transition_id, :project_key, :issues_enabled,
- :vulnerabilities_enabled, :vulnerabilities_issuetype
-
before_validation :reset_password
after_commit :update_deployment_type, on: [:create, :update], if: :update_deployment_type?
@@ -41,16 +39,50 @@ module Integrations
all_details: 2
}
+ self.field_storage = :data_fields
+
+ field :url,
+ section: SECTION_TYPE_CONNECTION,
+ required: true,
+ title: -> { s_('JiraService|Web URL') },
+ help: -> { s_('JiraService|Base URL of the Jira instance.') },
+ placeholder: 'https://jira.example.com'
+
+ field :api_url,
+ section: SECTION_TYPE_CONNECTION,
+ title: -> { s_('JiraService|Jira API URL') },
+ help: -> { s_('JiraService|If different from Web URL.') }
+
+ field :username,
+ section: SECTION_TYPE_CONNECTION,
+ required: true,
+ title: -> { s_('JiraService|Username or Email') },
+ help: -> { s_('JiraService|Use a username for server version and an email for cloud version.') }
+
+ field :password,
+ section: SECTION_TYPE_CONNECTION,
+ required: true,
+ title: -> { s_('JiraService|Password or API token') },
+ non_empty_password_title: -> { s_('JiraService|Enter new password or API token') },
+ non_empty_password_help: -> { s_('JiraService|Leave blank to use your current password or API token.') },
+ help: -> { s_('JiraService|Use a password for server version and an API token for cloud version.') }
+
+ # TODO: we can probably just delegate as part of
+ # https://gitlab.com/gitlab-org/gitlab/issues/29404
+ # These fields are API only, so no field definition is required.
+ data_field :jira_issue_transition_automatic
+ data_field :jira_issue_transition_id
+ data_field :project_key
+ data_field :issues_enabled
+ data_field :vulnerabilities_enabled
+ data_field :vulnerabilities_issuetype
+
# When these are false GitLab does not create cross reference
# comments on Jira except when an issue gets transitioned.
def self.supported_events
%w(commit merge_request)
end
- def self.supported_event_actions
- %w(comment)
- end
-
# {PROJECT-KEY}-{NUMBER} Examples: JIRA-1, PROJECT-1
def self.reference_pattern(only_long: true)
@reference_pattern ||= /(?<issue>\b#{Gitlab::Regex.jira_issue_key_regex})/
@@ -111,8 +143,8 @@ module Integrations
end
def help
- jira_doc_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: help_page_url('integration/jira/index.html') }
- s_("JiraService|You need to configure Jira before enabling this integration. For more details, read the %{jira_doc_link_start}Jira integration documentation%{link_end}.") % { jira_doc_link_start: jira_doc_link_start, link_end: '</a>'.html_safe }
+ jira_doc_link_start = '<a href="%{url}">'.html_safe % { url: help_page_url('integration/jira/index.html') }
+ s_("JiraService|You must configure Jira before enabling this integration. %{jira_doc_link_start}Learn more.%{link_end}") % { jira_doc_link_start: jira_doc_link_start, link_end: '</a>'.html_safe }
end
def title
@@ -127,39 +159,32 @@ module Integrations
'jira'
end
- def fields
- [
- {
- type: 'text',
- name: 'url',
- title: s_('JiraService|Web URL'),
- placeholder: 'https://jira.example.com',
- help: s_('JiraService|Base URL of the Jira instance.'),
- required: true
- },
- {
- type: 'text',
- name: 'api_url',
- title: s_('JiraService|Jira API URL'),
- help: s_('JiraService|If different from Web URL.')
- },
+ def sections
+ jira_issues_link_start = '<a href="%{url}">'.html_safe % { url: help_page_url('integration/jira/issues.html') }
+
+ sections = [
{
- type: 'text',
- name: 'username',
- title: s_('JiraService|Username or Email'),
- help: s_('JiraService|Use a username for server version and an email for cloud version.'),
- required: true
+ type: SECTION_TYPE_CONNECTION,
+ title: s_('Integrations|Connection details'),
+ description: help
},
{
- type: 'password',
- name: 'password',
- title: s_('JiraService|Password or API token'),
- non_empty_password_title: s_('JiraService|Enter new password or API token'),
- non_empty_password_help: s_('JiraService|Leave blank to use your current password or API token.'),
- help: s_('JiraService|Use a password for server version and an API token for cloud version.'),
- required: true
+ type: SECTION_TYPE_JIRA_TRIGGER,
+ title: _('Trigger'),
+ description: s_('JiraService|When a Jira issue is mentioned in a commit or merge request, a remote link and comment (if enabled) will be created.')
}
]
+
+ # Jira issues is currently only configurable on the project level.
+ if project_level?
+ sections.push({
+ type: SECTION_TYPE_JIRA_ISSUES,
+ title: _('Issues'),
+ description: s_('JiraService|Work on Jira issues without leaving GitLab. Add a Jira menu to access a read-only list of your Jira issues. %{jira_issues_link_start}Learn more.%{link_end}') % { jira_issues_link_start: jira_issues_link_start, link_end: '</a>'.html_safe }
+ })
+ end
+
+ sections
end
def web_url(path = nil, **params)
@@ -180,17 +205,12 @@ module Integrations
url.to_s
end
- override :project_url
- def project_url
- web_url
- end
+ alias_method :project_url, :web_url
- override :issues_url
def issues_url
web_url('browse/:id')
end
- override :new_issue_url
def new_issue_url
web_url('secure/CreateIssue!default.jspa')
end
diff --git a/app/models/integrations/mattermost.rb b/app/models/integrations/mattermost.rb
index 07a5086b8e9..d9ccbb7ea34 100644
--- a/app/models/integrations/mattermost.rb
+++ b/app/models/integrations/mattermost.rb
@@ -3,7 +3,6 @@
module Integrations
class Mattermost < BaseChatNotification
include SlackMattermostNotifier
- include ActionView::Helpers::UrlHelper
def title
s_('Mattermost notifications')
@@ -18,7 +17,7 @@ module Integrations
end
def help
- docs_link = link_to _('Learn more.'), Rails.application.routes.url_helpers.help_page_url('user/project/integrations/mattermost'), target: '_blank', rel: 'noopener noreferrer'
+ docs_link = ActionController::Base.helpers.link_to _('Learn more.'), Rails.application.routes.url_helpers.help_page_url('user/project/integrations/mattermost'), target: '_blank', rel: 'noopener noreferrer'
s_('Send notifications about project events to Mattermost channels. %{docs_link}').html_safe % { docs_link: docs_link.html_safe }
end
diff --git a/app/models/integrations/pivotaltracker.rb b/app/models/integrations/pivotaltracker.rb
index 24cfd51eb55..5b9ac023b7e 100644
--- a/app/models/integrations/pivotaltracker.rb
+++ b/app/models/integrations/pivotaltracker.rb
@@ -2,7 +2,6 @@
module Integrations
class Pivotaltracker < Integration
- include ActionView::Helpers::UrlHelper
API_ENDPOINT = 'https://www.pivotaltracker.com/services/v5/source_commits'
prop_accessor :token, :restrict_to_branch
@@ -17,7 +16,7 @@ module Integrations
end
def help
- docs_link = link_to _('Learn more.'), Rails.application.routes.url_helpers.help_page_url('user/project/integrations/pivotal_tracker'), target: '_blank', rel: 'noopener noreferrer'
+ docs_link = ActionController::Base.helpers.link_to _('Learn more.'), Rails.application.routes.url_helpers.help_page_url('user/project/integrations/pivotal_tracker'), target: '_blank', rel: 'noopener noreferrer'
s_('Add commit messages as comments to Pivotal Tracker stories. %{docs_link}').html_safe % { docs_link: docs_link.html_safe }
end
diff --git a/app/models/integrations/prometheus.rb b/app/models/integrations/prometheus.rb
index 5746343c31c..2e275dab91b 100644
--- a/app/models/integrations/prometheus.rb
+++ b/app/models/integrations/prometheus.rb
@@ -115,7 +115,6 @@ module Integrations
end
def prometheus_available?
- return false if template?
return false unless project
project.all_clusters.enabled.eager_load(:integration_prometheus).any? do |cluster|
diff --git a/app/models/integrations/redmine.rb b/app/models/integrations/redmine.rb
index 990b538f294..bc2a64b0848 100644
--- a/app/models/integrations/redmine.rb
+++ b/app/models/integrations/redmine.rb
@@ -2,7 +2,8 @@
module Integrations
class Redmine < BaseIssueTracker
- include ActionView::Helpers::UrlHelper
+ include Integrations::HasIssueTrackerFields
+
validates :project_url, :issues_url, :new_issue_url, presence: true, public_url: true, if: :activated?
def title
@@ -14,7 +15,7 @@ module Integrations
end
def help
- docs_link = link_to _('Learn more.'), Rails.application.routes.url_helpers.help_page_url('user/project/integrations/redmine'), target: '_blank', rel: 'noopener noreferrer'
+ docs_link = ActionController::Base.helpers.link_to _('Learn more.'), Rails.application.routes.url_helpers.help_page_url('user/project/integrations/redmine'), target: '_blank', rel: 'noopener noreferrer'
s_('IssueTracker|Use Redmine as the issue tracker. %{docs_link}').html_safe % { docs_link: docs_link.html_safe }
end
diff --git a/app/models/integrations/webex_teams.rb b/app/models/integrations/webex_teams.rb
index 7660eda6f83..345dd98cbc1 100644
--- a/app/models/integrations/webex_teams.rb
+++ b/app/models/integrations/webex_teams.rb
@@ -2,8 +2,6 @@
module Integrations
class WebexTeams < BaseChatNotification
- include ActionView::Helpers::UrlHelper
-
def title
s_("WebexTeamsService|Webex Teams")
end
@@ -17,7 +15,7 @@ module Integrations
end
def help
- docs_link = link_to _('Learn more.'), Rails.application.routes.url_helpers.help_page_url('user/project/integrations/webex_teams'), target: '_blank', rel: 'noopener noreferrer'
+ docs_link = ActionController::Base.helpers.link_to _('Learn more.'), Rails.application.routes.url_helpers.help_page_url('user/project/integrations/webex_teams'), target: '_blank', rel: 'noopener noreferrer'
s_("WebexTeamsService|Send notifications about project events to a Webex Teams conversation. %{docs_link}") % { docs_link: docs_link.html_safe }
end
diff --git a/app/models/integrations/youtrack.rb b/app/models/integrations/youtrack.rb
index 10531717f11..ab6e1da27f8 100644
--- a/app/models/integrations/youtrack.rb
+++ b/app/models/integrations/youtrack.rb
@@ -2,7 +2,7 @@
module Integrations
class Youtrack < BaseIssueTracker
- include ActionView::Helpers::UrlHelper
+ include Integrations::HasIssueTrackerFields
validates :project_url, :issues_url, presence: true, public_url: true, if: :activated?
@@ -24,7 +24,7 @@ module Integrations
end
def help
- docs_link = link_to _('Learn more.'), Rails.application.routes.url_helpers.help_page_url('user/project/integrations/youtrack'), target: '_blank', rel: 'noopener noreferrer'
+ docs_link = ActionController::Base.helpers.link_to _('Learn more.'), Rails.application.routes.url_helpers.help_page_url('user/project/integrations/youtrack'), target: '_blank', rel: 'noopener noreferrer'
s_("IssueTracker|Use YouTrack as this project's issue tracker. %{docs_link}").html_safe % { docs_link: docs_link.html_safe }
end
diff --git a/app/models/integrations/zentao.rb b/app/models/integrations/zentao.rb
index 493d42cc40b..c33df465fde 100644
--- a/app/models/integrations/zentao.rb
+++ b/app/models/integrations/zentao.rb
@@ -11,7 +11,6 @@ module Integrations
validates :api_token, presence: true, if: :activated?
validates :zentao_product_xid, presence: true, if: :activated?
- # License Level: EEP_FEATURES
def self.issues_license_available?(project)
project&.licensed_feature_available?(:zentao_issues_integration)
end
@@ -48,10 +47,6 @@ module Integrations
%w()
end
- def self.supported_event_actions
- %w()
- end
-
def fields
[
{
diff --git a/app/models/issue.rb b/app/models/issue.rb
index 68ea6cb3abc..75727fff2cd 100644
--- a/app/models/issue.rb
+++ b/app/models/issue.rb
@@ -24,6 +24,7 @@ class Issue < ApplicationRecord
include Todoable
include FromUnion
include EachBatch
+ include PgFullTextSearchable
extend ::Gitlab::Utils::Override
@@ -77,6 +78,7 @@ class Issue < ApplicationRecord
end
end
+ has_one :search_data, class_name: 'Issues::SearchData'
has_one :issuable_severity
has_one :sentry_issue
has_one :alert_management_alert, class_name: 'AlertManagement::Alert'
@@ -102,6 +104,8 @@ class Issue < ApplicationRecord
alias_attribute :external_author, :service_desk_reply_to
+ pg_full_text_searchable columns: [{ name: 'title', weight: 'A' }, { name: 'description', weight: 'B' }]
+
scope :in_projects, ->(project_ids) { where(project_id: project_ids) }
scope :not_in_projects, ->(project_ids) { where.not(project_id: project_ids) }
@@ -233,6 +237,11 @@ class Issue < ApplicationRecord
def order_upvotes_asc
reorder(upvotes_count: :asc)
end
+
+ override :pg_full_text_search
+ def pg_full_text_search(search_term)
+ super.where('issue_search_data.project_id = issues.project_id')
+ end
end
def next_object_by_relative_position(ignoring: nil, order: :asc)
@@ -611,6 +620,11 @@ class Issue < ApplicationRecord
private
+ override :persist_pg_full_text_search_vector
+ def persist_pg_full_text_search_vector(search_vector)
+ Issues::SearchData.upsert({ project_id: project_id, issue_id: id, search_vector: search_vector }, unique_by: %i(project_id issue_id))
+ end
+
def spammable_attribute_changed?
title_changed? ||
description_changed? ||
diff --git a/app/models/issue_link.rb b/app/models/issue_link.rb
index 920586cc1ba..1bd34aa0083 100644
--- a/app/models/issue_link.rb
+++ b/app/models/issue_link.rb
@@ -2,46 +2,17 @@
class IssueLink < ApplicationRecord
include FromUnion
+ include IssuableLink
belongs_to :source, class_name: 'Issue'
belongs_to :target, class_name: 'Issue'
- validates :source, presence: true
- validates :target, presence: true
- validates :source, uniqueness: { scope: :target_id, message: 'is already related' }
- validate :check_self_relation
- validate :check_opposite_relation
-
scope :for_source_issue, ->(issue) { where(source_id: issue.id) }
scope :for_target_issue, ->(issue) { where(target_id: issue.id) }
- TYPE_RELATES_TO = 'relates_to'
- TYPE_BLOCKS = 'blocks'
- # we don't store is_blocked_by in the db but need it for displaying the relation
- # from the target (used in IssueLink.inverse_link_type)
- TYPE_IS_BLOCKED_BY = 'is_blocked_by'
-
- enum link_type: { TYPE_RELATES_TO => 0, TYPE_BLOCKS => 1 }
-
- def self.inverse_link_type(type)
- type
- end
-
- private
-
- def check_self_relation
- return unless source && target
-
- if source == target
- errors.add(:source, 'cannot be related to itself')
- end
- end
-
- def check_opposite_relation
- return unless source && target
-
- if IssueLink.find_by(source: target, target: source)
- errors.add(:source, 'is already related to this issue')
+ class << self
+ def issuable_type
+ :issue
end
end
end
diff --git a/app/models/issues/search_data.rb b/app/models/issues/search_data.rb
new file mode 100644
index 00000000000..0eda292796d
--- /dev/null
+++ b/app/models/issues/search_data.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+module Issues
+ class SearchData < ApplicationRecord
+ extend SuppressCompositePrimaryKeyWarning
+
+ self.table_name = 'issue_search_data'
+
+ belongs_to :issue
+ end
+end
diff --git a/app/models/label.rb b/app/models/label.rb
index 0ebbb5b9bd3..4c9f071f43a 100644
--- a/app/models/label.rb
+++ b/app/models/label.rb
@@ -12,8 +12,9 @@ class Label < ApplicationRecord
cache_markdown_field :description, pipeline: :single_line
- DEFAULT_COLOR = '#6699cc'
+ DEFAULT_COLOR = ::Gitlab::Color.of('#6699cc')
+ attribute :color, ::Gitlab::Database::Type::Color.new
default_value_for :color, DEFAULT_COLOR
has_many :lists, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
@@ -22,9 +23,9 @@ class Label < ApplicationRecord
has_many :issues, through: :label_links, source: :target, source_type: 'Issue'
has_many :merge_requests, through: :label_links, source: :target, source_type: 'MergeRequest'
- before_validation :strip_whitespace_from_title_and_color
+ before_validation :strip_whitespace_from_title
- validates :color, color: true, allow_blank: false
+ validates :color, color: true, presence: true
# Don't allow ',' for label titles
validates :title, presence: true, format: { with: /\A[^,]+\z/ }
@@ -212,15 +213,23 @@ class Label < ApplicationRecord
end
def text_color
- LabelsHelper.text_color_for_bg(self.color)
+ color.contrast
end
def title=(value)
- write_attribute(:title, sanitize_value(value)) if value.present?
+ if value.blank?
+ super
+ else
+ write_attribute(:title, sanitize_value(value))
+ end
end
def description=(value)
- write_attribute(:description, sanitize_value(value)) if value.present?
+ if value.blank?
+ super
+ else
+ write_attribute(:description, sanitize_value(value))
+ end
end
##
@@ -285,8 +294,8 @@ class Label < ApplicationRecord
CGI.unescapeHTML(Sanitize.clean(value.to_s))
end
- def strip_whitespace_from_title_and_color
- %w(color title).each { |attr| self[attr] = self[attr]&.strip }
+ def strip_whitespace_from_title
+ self[:title] = title&.strip
end
end
diff --git a/app/models/lfs_download_object.rb b/app/models/lfs_download_object.rb
index 319499fd1b7..3df6742fbc9 100644
--- a/app/models/lfs_download_object.rb
+++ b/app/models/lfs_download_object.rb
@@ -4,6 +4,7 @@ class LfsDownloadObject
include ActiveModel::Validations
attr_accessor :oid, :size, :link, :headers
+
delegate :sanitized_url, :credentials, to: :sanitized_uri
validates :oid, format: { with: /\A\h{64}\z/ }
diff --git a/app/models/members/project_member.rb b/app/models/members/project_member.rb
index 3a449055bc1..3e19f294253 100644
--- a/app/models/members/project_member.rb
+++ b/app/models/members/project_member.rb
@@ -94,9 +94,9 @@ class ProjectMember < Member
override :access_level_inclusion
def access_level_inclusion
- return if access_level.in?(Gitlab::Access.values)
-
- errors.add(:access_level, "is not included in the list")
+ unless access_level.in?(Gitlab::Access.all_values)
+ errors.add(:access_level, "is not included in the list")
+ end
end
override :refresh_member_authorized_projects
diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb
index 29540cbde2f..854325e1fcd 100644
--- a/app/models/merge_request.rb
+++ b/app/models/merge_request.rb
@@ -1016,8 +1016,24 @@ class MergeRequest < ApplicationRecord
merge_request_diff.persisted? || create_merge_request_diff
end
- def create_merge_request_diff
+ def eager_fetch_ref!
+ return unless valid?
+
+ # has_internal_id normally attempts to allocate the iid in the
+ # before_create hook, but we need the iid to be available before
+ # that to fetch the ref into the target project.
+ track_target_project_iid!
+ ensure_target_project_iid!
+
fetch_ref!
+ # Prevent the after_create hook from fetching the source branch again.
+ @skip_fetch_ref = true
+ end
+
+ def create_merge_request_diff
+ # Callers such as MergeRequests::BuildService may not call eager_fetch_ref!. Just
+ # in case they haven't, we fetch the ref.
+ fetch_ref! unless skip_fetch_ref
# n+1: https://gitlab.com/gitlab-org/gitlab/-/issues/19377
Gitlab::GitalyClient.allow_n_plus_1_calls do
@@ -1136,15 +1152,20 @@ class MergeRequest < ApplicationRecord
# rubocop: disable CodeReuse/ServiceClass
def mergeable_state?(skip_ci_check: false, skip_discussions_check: false)
- return false unless open?
- return false if work_in_progress?
- return false if broken?
- return false unless skip_discussions_check || mergeable_discussions_state?
-
if Feature.enabled?(:improved_mergeability_checks, self.project, default_enabled: :yaml)
- additional_checks = MergeRequests::Mergeability::RunChecksService.new(merge_request: self, params: { skip_ci_check: skip_ci_check })
+ additional_checks = MergeRequests::Mergeability::RunChecksService.new(
+ merge_request: self,
+ params: {
+ skip_ci_check: skip_ci_check,
+ skip_discussions_check: skip_discussions_check
+ }
+ )
additional_checks.execute.all?(&:success?)
else
+ return false unless open?
+ return false if draft?
+ return false if broken?
+ return false unless skip_discussions_check || mergeable_discussions_state?
return false unless skip_ci_check || mergeable_ci_state?
true
@@ -1921,10 +1942,18 @@ class MergeRequest < ApplicationRecord
merge_request_assignees.find_by(user_id: user.id)
end
+ def merge_request_assignees_with(user_ids)
+ merge_request_assignees.where(user_id: user_ids)
+ end
+
def find_reviewer(user)
merge_request_reviewers.find_by(user_id: user.id)
end
+ def merge_request_reviewers_with(user_ids)
+ merge_request_reviewers.where(user_id: user_ids)
+ end
+
def enabled_reports
{
sast: report_type_enabled?(:sast),
@@ -1950,6 +1979,8 @@ class MergeRequest < ApplicationRecord
private
+ attr_accessor :skip_fetch_ref
+
def set_draft_status
self.draft = draft?
end
diff --git a/app/models/milestone.rb b/app/models/milestone.rb
index 2c95cc2672c..86da29dd27a 100644
--- a/app/models/milestone.rb
+++ b/app/models/milestone.rb
@@ -35,6 +35,7 @@ class Milestone < ApplicationRecord
scope :with_api_entity_associations, -> { preload(project: [:project_feature, :route, namespace: :route]) }
scope :order_by_dates_and_title, -> { order(due_date: :asc, start_date: :asc, title: :asc) }
+ validates :title, presence: true
validates_associated :milestone_releases, message: -> (_, obj) { obj[:value].map(&:errors).map(&:full_messages).join(",") }
validate :uniqueness_of_title, if: :title_changed?
diff --git a/app/models/namespace.rb b/app/models/namespace.rb
index 5c55f4d3def..ffaeb2071f6 100644
--- a/app/models/namespace.rb
+++ b/app/models/namespace.rb
@@ -117,6 +117,7 @@ class Namespace < ApplicationRecord
before_create :sync_share_with_group_lock_with_parent
before_update :sync_share_with_group_lock_with_parent, if: :parent_changed?
after_update :force_share_with_group_lock_on_descendants, if: -> { saved_change_to_share_with_group_lock? && share_with_group_lock? }
+ after_update :expire_first_auto_devops_config_cache, if: -> { saved_change_to_auto_devops_enabled? }
# Legacy Storage specific hooks
@@ -401,7 +402,11 @@ class Namespace < ApplicationRecord
return { scope: :group, status: auto_devops_enabled } unless auto_devops_enabled.nil?
strong_memoize(:first_auto_devops_config) do
- if has_parent?
+ if has_parent? && cache_first_auto_devops_config?
+ Rails.cache.fetch(first_auto_devops_config_cache_key_for(id), expires_in: 1.day) do
+ parent.first_auto_devops_config
+ end
+ elsif has_parent?
parent.first_auto_devops_config
else
{ scope: :instance, status: Gitlab::CurrentSettings.auto_devops_enabled? }
@@ -509,10 +514,6 @@ class Namespace < ApplicationRecord
Feature.enabled?(:block_issue_repositioning, self, type: :ops, default_enabled: :yaml)
end
- def project_namespace_creation_enabled?
- Feature.enabled?(:create_project_namespace_on_project_create, self, default_enabled: :yaml)
- end
-
def storage_enforcement_date
# should return something like Date.new(2022, 02, 03)
# TBD: https://gitlab.com/gitlab-org/gitlab/-/issues/350632
@@ -621,6 +622,20 @@ class Namespace < ApplicationRecord
.update_all(share_with_group_lock: true)
end
+ def expire_first_auto_devops_config_cache
+ return unless cache_first_auto_devops_config?
+
+ descendants_to_expire = self_and_descendants.as_ids
+ return if descendants_to_expire.load.empty?
+
+ keys = descendants_to_expire.map { |group| first_auto_devops_config_cache_key_for(group.id) }
+ Rails.cache.delete_multi(keys)
+ end
+
+ def cache_first_auto_devops_config?
+ ::Feature.enabled?(:namespaces_cache_first_auto_devops_config, default_enabled: :yaml)
+ end
+
def write_projects_repository_config
all_projects.find_each do |project|
project.set_full_path
@@ -638,6 +653,13 @@ class Namespace < ApplicationRecord
Namespaces::SyncEvent.enqueue_worker
end
end
+
+ def first_auto_devops_config_cache_key_for(group_id)
+ return "namespaces:{first_auto_devops_config}:#{group_id}" unless sync_traversal_ids?
+
+ # Use SHA2 of `traversal_ids` to account for moving a namespace within the same root ancestor hierarchy.
+ "namespaces:{#{traversal_ids.first}}:first_auto_devops_config:#{group_id}:#{Digest::SHA2.hexdigest(traversal_ids.join(' '))}"
+ end
end
Namespace.prepend_mod_with('Namespace')
diff --git a/app/models/namespace/traversal_hierarchy.rb b/app/models/namespace/traversal_hierarchy.rb
index 34086a8af5d..d2de85b5dd4 100644
--- a/app/models/namespace/traversal_hierarchy.rb
+++ b/app/models/namespace/traversal_hierarchy.rb
@@ -31,15 +31,16 @@ class Namespace
# ActiveRecord. https://github.com/rails/rails/issues/13496
# Ideally it would be:
# `incorrect_traversal_ids.update_all('traversal_ids = cte.traversal_ids')`
- sql = """
- UPDATE namespaces
- SET traversal_ids = cte.traversal_ids
- FROM (#{recursive_traversal_ids}) as cte
- WHERE namespaces.id = cte.id
- AND namespaces.traversal_ids::bigint[] <> cte.traversal_ids
- """
+ sql = <<-SQL
+ UPDATE namespaces
+ SET traversal_ids = cte.traversal_ids
+ FROM (#{recursive_traversal_ids}) as cte
+ WHERE namespaces.id = cte.id
+ AND namespaces.traversal_ids::bigint[] <> cte.traversal_ids
+ SQL
+
Namespace.transaction do
- @root.lock!
+ @root.lock!("FOR NO KEY UPDATE")
Namespace.connection.exec_query(sql)
end
rescue ActiveRecord::Deadlocked
diff --git a/app/models/namespaces/traversal/linear.rb b/app/models/namespaces/traversal/linear.rb
index 99a5b8cb063..1963745cf4d 100644
--- a/app/models/namespaces/traversal/linear.rb
+++ b/app/models/namespaces/traversal/linear.rb
@@ -44,22 +44,15 @@ module Namespaces
included do
before_update :lock_both_roots, if: -> { sync_traversal_ids? && parent_id_changed? }
after_update :sync_traversal_ids, if: -> { sync_traversal_ids? && saved_change_to_parent_id? }
- # sync traversal_ids on namespace create, which can happen quite early within a transaction, thus keeping the lock on root namespace record
- # for a relatively long time, e.g. creating the project namespace when a project is being created.
- after_create :sync_traversal_ids, if: -> { sync_traversal_ids? && !sync_traversal_ids_before_commit? }
# This uses rails internal before_commit API to sync traversal_ids on namespace create, right before transaction is committed.
# This helps reduce the time during which the root namespace record is locked to ensure updated traversal_ids are valid
- before_commit :sync_traversal_ids, on: [:create], if: -> { sync_traversal_ids? && sync_traversal_ids_before_commit? }
+ before_commit :sync_traversal_ids, on: [:create], if: -> { sync_traversal_ids? }
end
def sync_traversal_ids?
Feature.enabled?(:sync_traversal_ids, root_ancestor, default_enabled: :yaml)
end
- def sync_traversal_ids_before_commit?
- Feature.enabled?(:sync_traversal_ids_before_commit, root_ancestor, default_enabled: :yaml)
- end
-
def use_traversal_ids?
return false unless Feature.enabled?(:use_traversal_ids, default_enabled: :yaml)
diff --git a/app/models/namespaces/traversal/linear_scopes.rb b/app/models/namespaces/traversal/linear_scopes.rb
index 09d69a5f77a..0cac4c9143a 100644
--- a/app/models/namespaces/traversal/linear_scopes.rb
+++ b/app/models/namespaces/traversal/linear_scopes.rb
@@ -126,36 +126,26 @@ module Namespaces
end
def self_and_descendants_with_comparison_operators(include_self: true)
- base = all.select(
- :traversal_ids,
- 'LEAD (namespaces.traversal_ids, 1) OVER (ORDER BY namespaces.traversal_ids ASC) next_traversal_ids'
- )
+ base = all.select(:traversal_ids)
base_cte = Gitlab::SQL::CTE.new(:descendants_base_cte, base)
namespaces = Arel::Table.new(:namespaces)
# Bound the search space to ourselves (optional) and descendants.
#
- # WHERE (base_cte.next_traversal_ids IS NULL OR base_cte.next_traversal_ids > namespaces.traversal_ids)
- # AND next_traversal_ids_sibling(base_cte.traversal_ids) > namespaces.traversal_ids
+ # WHERE next_traversal_ids_sibling(base_cte.traversal_ids) > namespaces.traversal_ids
records = unscoped
+ .distinct
+ .with(base_cte.to_arel)
.from([base_cte.table, namespaces])
- .where(base_cte.table[:next_traversal_ids].eq(nil).or(base_cte.table[:next_traversal_ids].gt(namespaces[:traversal_ids])))
.where(next_sibling_func(base_cte.table[:traversal_ids]).gt(namespaces[:traversal_ids]))
# AND base_cte.traversal_ids <= namespaces.traversal_ids
- records = if include_self
- records.where(base_cte.table[:traversal_ids].lteq(namespaces[:traversal_ids]))
- else
- records.where(base_cte.table[:traversal_ids].lt(namespaces[:traversal_ids]))
- end
-
- records_cte = Gitlab::SQL::CTE.new(:descendants_cte, records)
-
- unscoped
- .unscope(where: [:type])
- .with(base_cte.to_arel, records_cte.to_arel)
- .from(records_cte.alias_to(namespaces))
+ if include_self
+ records.where(base_cte.table[:traversal_ids].lteq(namespaces[:traversal_ids]))
+ else
+ records.where(base_cte.table[:traversal_ids].lt(namespaces[:traversal_ids]))
+ end
end
def next_sibling_func(*args)
diff --git a/app/models/note.rb b/app/models/note.rb
index a84da066968..4f2e7ebe2c5 100644
--- a/app/models/note.rb
+++ b/app/models/note.rb
@@ -609,7 +609,6 @@ class Note < ApplicationRecord
def show_outdated_changes?
return false unless for_merge_request?
- return false unless Feature.enabled?(:display_outdated_line_diff, noteable.source_project, default_enabled: :yaml)
return false unless system?
return false unless change_position&.line_range
diff --git a/app/models/packages/package_file.rb b/app/models/packages/package_file.rb
index fc7c348dfdb..ad8140ac684 100644
--- a/app/models/packages/package_file.rb
+++ b/app/models/packages/package_file.rb
@@ -49,6 +49,7 @@ class Packages::PackageFile < ApplicationRecord
scope :preload_conan_file_metadata, -> { preload(:conan_file_metadatum) }
scope :preload_debian_file_metadata, -> { preload(:debian_file_metadatum) }
scope :preload_helm_file_metadata, -> { preload(:helm_file_metadatum) }
+ scope :order_id_asc, -> { order(id: :asc) }
scope :for_rubygem_with_file_name, ->(project, file_name) do
joins(:package).merge(project.packages.rubygems).with_file_name(file_name)
diff --git a/app/models/packages/pypi/metadatum.rb b/app/models/packages/pypi/metadatum.rb
index 2e4d61eaf53..ff247fedb59 100644
--- a/app/models/packages/pypi/metadatum.rb
+++ b/app/models/packages/pypi/metadatum.rb
@@ -6,7 +6,7 @@ class Packages::Pypi::Metadatum < ApplicationRecord
belongs_to :package, -> { where(package_type: :pypi) }, inverse_of: :pypi_metadatum
validates :package, presence: true
- validates :required_python, length: { maximum: 255 }, allow_blank: true
+ validates :required_python, length: { maximum: 255 }, allow_nil: false
validate :pypi_package_type
diff --git a/app/models/personal_access_token.rb b/app/models/personal_access_token.rb
index 2f515f3443d..021ff789b13 100644
--- a/app/models/personal_access_token.rb
+++ b/app/models/personal_access_token.rb
@@ -34,6 +34,7 @@ class PersonalAccessToken < ApplicationRecord
scope :order_expires_at_asc, -> { reorder(expires_at: :asc) }
scope :order_expires_at_desc, -> { reorder(expires_at: :desc) }
scope :project_access_token, -> { includes(:user).where(user: { user_type: :project_bot }) }
+ scope :owner_is_human, -> { includes(:user).where(user: { user_type: :human }) }
validates :scopes, presence: true
validate :validate_scopes
diff --git a/app/models/preloaders/environments/deployment_preloader.rb b/app/models/preloaders/environments/deployment_preloader.rb
index fcf892698bb..251d1837f19 100644
--- a/app/models/preloaders/environments/deployment_preloader.rb
+++ b/app/models/preloaders/environments/deployment_preloader.rb
@@ -21,11 +21,13 @@ module Preloaders
def load_deployment_association(association_name, association_attributes)
return unless environments.present?
- union_arg = environments.inject([]) do |result, environment|
- result << environment.association(association_name).scope
- end
-
- union_sql = Deployment.from_union(union_arg).to_sql
+ # Not using Gitlab::SQL::Union as `order_by` in the SQL constructed is ignored.
+ # See:
+ # 1) https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/sql/union.rb#L7
+ # 2) https://gitlab.com/gitlab-org/gitlab/-/issues/353966#note_860928647
+ union_sql = environments.map do |environment|
+ "(#{environment.association(association_name).scope.to_sql})"
+ end.join(' UNION ')
deployments = Deployment
.from("(#{union_sql}) #{::Deployment.table_name}")
@@ -34,8 +36,16 @@ module Preloaders
deployments_by_environment_id = deployments.index_by(&:environment_id)
environments.each do |environment|
- environment.association(association_name).target = deployments_by_environment_id[environment.id]
+ associated_deployment = deployments_by_environment_id[environment.id]
+
+ environment.association(association_name).target = associated_deployment
environment.association(association_name).loaded!
+
+ if associated_deployment
+ # `last?` in DeploymentEntity requires this environment to be loaded
+ associated_deployment.association(:environment).target = environment
+ associated_deployment.association(:environment).loaded!
+ end
end
end
end
diff --git a/app/models/project.rb b/app/models/project.rb
index f89e616a5ca..155ebe88d33 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -38,7 +38,7 @@ class Project < ApplicationRecord
include GitlabRoutingHelper
include BulkMemberAccessLoad
include RunnerTokenExpirationInterval
- include RunnersTokenPrefixable
+ include BlocksUnsafeSerialization
extend Gitlab::Cache::RequestCache
extend Gitlab::Utils::Override
@@ -196,6 +196,7 @@ class Project < ApplicationRecord
has_one :external_wiki_integration, class_name: 'Integrations::ExternalWiki'
has_one :flowdock_integration, class_name: 'Integrations::Flowdock'
has_one :hangouts_chat_integration, class_name: 'Integrations::HangoutsChat'
+ has_one :harbor_integration, class_name: 'Integrations::Harbor'
has_one :irker_integration, class_name: 'Integrations::Irker'
has_one :jenkins_integration, class_name: 'Integrations::Jenkins'
has_one :jira_integration, class_name: 'Integrations::Jira'
@@ -344,22 +345,18 @@ class Project < ApplicationRecord
has_many :stages, class_name: 'Ci::Stage', inverse_of: :project
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
- # bulk that doesn't involve loading the rows into memory. As a result we're
- # still using `dependent: :destroy` here.
has_many :pending_builds, class_name: 'Ci::PendingBuild'
- has_many :builds, class_name: 'Ci::Build', inverse_of: :project, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
+ has_many :builds, class_name: 'Ci::Build', inverse_of: :project
has_many :processables, class_name: 'Ci::Processable', inverse_of: :project
- has_many :build_trace_chunks, class_name: 'Ci::BuildTraceChunk', through: :builds, source: :trace_chunks
+ has_many :build_trace_chunks, class_name: 'Ci::BuildTraceChunk', through: :builds, source: :trace_chunks, dependent: :restrict_with_error
has_many :build_report_results, class_name: 'Ci::BuildReportResult', inverse_of: :project
- has_many :job_artifacts, class_name: 'Ci::JobArtifact'
- has_many :pipeline_artifacts, class_name: 'Ci::PipelineArtifact', inverse_of: :project
+ has_many :job_artifacts, class_name: 'Ci::JobArtifact', dependent: :restrict_with_error
+ has_many :pipeline_artifacts, class_name: 'Ci::PipelineArtifact', inverse_of: :project, dependent: :restrict_with_error
has_many :runner_projects, class_name: 'Ci::RunnerProject', inverse_of: :project
has_many :runners, through: :runner_projects, source: :runner, class_name: 'Ci::Runner'
has_many :variables, class_name: 'Ci::Variable'
has_many :triggers, class_name: 'Ci::Trigger'
- has_many :secure_files, class_name: 'Ci::SecureFile'
+ has_many :secure_files, class_name: 'Ci::SecureFile', dependent: :restrict_with_error
has_many :environments
has_many :environments_for_dashboard, -> { from(with_rank.unfoldered.available, :environments).where('rank <= 3') }, class_name: 'Environment'
has_many :deployments
@@ -462,7 +459,7 @@ class Project < ApplicationRecord
delegate :name, to: :owner, allow_nil: true, prefix: true
delegate :members, to: :team, prefix: true
delegate :add_user, :add_users, to: :team
- delegate :add_guest, :add_reporter, :add_developer, :add_maintainer, :add_role, to: :team
+ delegate :add_guest, :add_reporter, :add_developer, :add_maintainer, :add_owner, :add_role, to: :team
delegate :group_runners_enabled, :group_runners_enabled=, to: :ci_cd_settings, allow_nil: true
delegate :root_ancestor, to: :namespace, allow_nil: true
delegate :last_pipeline, to: :commit, allow_nil: true
@@ -501,11 +498,15 @@ class Project < ApplicationRecord
presence: true,
project_path: true,
length: { maximum: 255 }
+ validates :path,
+ format: { with: Gitlab::Regex.oci_repository_path_regex,
+ message: Gitlab::Regex.oci_repository_path_regex_message },
+ if: :path_changed?
validates :project_feature, presence: true
validates :namespace, presence: true
- validates :project_namespace, presence: true, on: :create, if: -> { self.namespace && self.root_namespace.project_namespace_creation_enabled? }
+ validates :project_namespace, presence: true, on: :create, if: -> { self.namespace }
validates :project_namespace, presence: true, on: :update, if: -> { self.project_namespace_id_changed?(to: nil) }
validates :name, uniqueness: { scope: :namespace_id }
validates :import_url, public_url: { schemes: ->(project) { project.persisted? ? VALID_MIRROR_PROTOCOLS : VALID_IMPORT_PROTOCOLS },
@@ -529,6 +530,7 @@ class Project < ApplicationRecord
# Scopes
scope :pending_delete, -> { where(pending_delete: true) }
scope :without_deleted, -> { where(pending_delete: false) }
+ scope :not_hidden, -> { where(hidden: false) }
scope :not_aimed_for_deletion, -> { where(marked_for_deletion_at: nil).without_deleted }
scope :with_storage_feature, ->(feature) do
@@ -1006,10 +1008,6 @@ class Project < ApplicationRecord
Feature.enabled?(:unlink_fork_network_upon_visibility_decrease, self, default_enabled: true)
end
- def context_commits_enabled?
- Feature.enabled?(:context_commits, self.group, default_enabled: :yaml)
- end
-
# LFS and hashed repository storage are required for using Design Management.
def design_management_enabled?
lfs_enabled? && hashed_storage?(:repository)
@@ -1565,14 +1563,17 @@ class Project < ApplicationRecord
# rubocop: disable CodeReuse/ServiceClass
def execute_hooks(data, hooks_scope = :push_hooks)
run_after_commit_or_now do
- hooks.hooks_for(hooks_scope).select_active(hooks_scope, data).each do |hook|
- hook.async_execute(data, hooks_scope.to_s)
- end
+ triggered_hooks(hooks_scope, data).execute
SystemHooksService.new.execute_hooks(data, hooks_scope)
end
end
# rubocop: enable CodeReuse/ServiceClass
+ def triggered_hooks(hooks_scope, data)
+ triggered = ::Projects::TriggeredHooks.new(hooks_scope, data)
+ triggered.add_hooks(hooks)
+ end
+
def execute_integrations(data, hooks_scope = :push_hooks)
# Call only service hooks that are active for this scope
run_after_commit_or_now do
@@ -1876,13 +1877,9 @@ class Project < ApplicationRecord
ensure_runners_token!
end
- def runners_token_prefix
- RUNNERS_TOKEN_PREFIX
- end
-
override :format_runners_token
def format_runners_token(token)
- "#{runners_token_prefix}#{token}"
+ "#{RunnersTokenPrefixable::RUNNERS_TOKEN_PREFIX}#{token}"
end
def pages_deployed?
@@ -1938,12 +1935,12 @@ class Project < ApplicationRecord
.delete_all
end
- def mark_pages_as_deployed(artifacts_archive: nil)
- ensure_pages_metadatum.update!(deployed: true, artifacts_archive: artifacts_archive)
+ def mark_pages_as_deployed
+ ensure_pages_metadatum.update!(deployed: true)
end
def mark_pages_as_not_deployed
- ensure_pages_metadatum.update!(deployed: false, artifacts_archive: nil, pages_deployment: nil)
+ ensure_pages_metadatum.update!(deployed: false)
end
def update_pages_deployment!(deployment)
@@ -2521,7 +2518,18 @@ class Project < ApplicationRecord
end
def access_request_approvers_to_be_notified
- members.maintainers.connected_to_user.order_recent_sign_in.limit(Member::ACCESS_REQUEST_APPROVERS_TO_BE_NOTIFIED_LIMIT)
+ # For a personal project:
+ # The creator is added as a member with `Owner` access level, starting from GitLab 14.8
+ # The creator was added as a member with `Maintainer` access level, before GitLab 14.8
+ # So, to make sure access requests for all personal projects work as expected,
+ # we need to filter members with the scope `owners_and_maintainers`.
+ access_request_approvers = if personal?
+ members.owners_and_maintainers
+ else
+ members.maintainers
+ end
+
+ access_request_approvers.connected_to_user.order_recent_sign_in.limit(Member::ACCESS_REQUEST_APPROVERS_TO_BE_NOTIFIED_LIMIT)
end
def pages_lookup_path(trim_prefix: nil, domain: nil)
@@ -2817,6 +2825,10 @@ class Project < ApplicationRecord
end
end
+ def pending_delete_or_hidden?
+ pending_delete? || hidden?
+ end
+
private
# overridden in EE
@@ -2838,7 +2850,9 @@ class Project < ApplicationRecord
if @topic_list != self.topic_list
self.topics.delete_all
- self.topics = @topic_list.map { |topic| Projects::Topic.find_or_create_by(name: topic) }
+ self.topics = @topic_list.map do |topic|
+ Projects::Topic.where('lower(name) = ?', topic.downcase).order(total_projects_count: :desc).first_or_create(name: topic)
+ end
end
@topic_list = nil
@@ -3010,16 +3024,15 @@ class Project < ApplicationRecord
end
def ensure_project_namespace_in_sync
- # create project_namespace when project is created if create_project_namespace_on_project_create FF is enabled
+ # create project_namespace when project is created
build_project_namespace if project_namespace_creation_enabled?
- # regardless of create_project_namespace_on_project_create FF we need
- # to keep project and project namespace in sync if there is one
+ # we need to keep project and project namespace in sync if there is one
sync_attributes(project_namespace) if sync_project_namespace?
end
def project_namespace_creation_enabled?
- new_record? && !project_namespace && self.namespace && self.root_namespace.project_namespace_creation_enabled?
+ new_record? && !project_namespace && self.namespace
end
def sync_project_namespace?
diff --git a/app/models/project_authorization.rb b/app/models/project_authorization.rb
index c76332b21cd..5c6fdec16ca 100644
--- a/app/models/project_authorization.rb
+++ b/app/models/project_authorization.rb
@@ -9,7 +9,7 @@ class ProjectAuthorization < ApplicationRecord
validates :project, presence: true
validates :access_level, inclusion: { in: Gitlab::Access.all_values }, presence: true
- validates :user, uniqueness: { scope: [:project, :access_level] }, presence: true
+ validates :user, uniqueness: { scope: :project }, presence: true
def self.select_from_union(relations)
from_union(relations)
diff --git a/app/models/project_import_data.rb b/app/models/project_import_data.rb
index d374ee120d1..3b514d5c5ff 100644
--- a/app/models/project_import_data.rb
+++ b/app/models/project_import_data.rb
@@ -14,7 +14,12 @@ class ProjectImportData < ApplicationRecord
insecure_mode: true,
algorithm: 'aes-256-cbc'
- serialize :data, JSON # rubocop:disable Cop/ActiveRecordSerialize
+ # NOTE
+ # We are serializing a project as `data` in an "unsafe" way here
+ # because the credentials are necessary for a successful import.
+ # This is safe because the serialization is only going between rails
+ # and the database, never to any end users.
+ serialize :data, Serializers::UnsafeJson # rubocop:disable Cop/ActiveRecordSerialize
validates :project, presence: true
diff --git a/app/models/project_pages_metadatum.rb b/app/models/project_pages_metadatum.rb
index 58dbac9057f..dc1e9319340 100644
--- a/app/models/project_pages_metadatum.rb
+++ b/app/models/project_pages_metadatum.rb
@@ -4,11 +4,13 @@ class ProjectPagesMetadatum < ApplicationRecord
extend SuppressCompositePrimaryKeyWarning
include EachBatch
+ include IgnorableColumns
self.primary_key = :project_id
+ ignore_columns :artifacts_archive_id, remove_with: '15.0', remove_after: '2022-04-22'
+
belongs_to :project, inverse_of: :pages_metadatum
- belongs_to :artifacts_archive, class_name: 'Ci::JobArtifact'
belongs_to :pages_deployment
scope :deployed, -> { where(deployed: true) }
diff --git a/app/models/project_team.rb b/app/models/project_team.rb
index c3c7508df9f..4b89d95c1a3 100644
--- a/app/models/project_team.rb
+++ b/app/models/project_team.rb
@@ -23,6 +23,10 @@ class ProjectTeam
add_user(user, :maintainer, current_user: current_user)
end
+ def add_owner(user, current_user: nil)
+ add_user(user, :owner, current_user: current_user)
+ end
+
def add_role(user, role, current_user: nil)
public_send(:"add_#{role}", user, current_user: current_user) # rubocop:disable GitlabSecurity/PublicSend
end
@@ -103,7 +107,9 @@ class ProjectTeam
if group
group.owners
else
- [project.owner]
+ # workaround until we migrate Project#owners to have membership with
+ # OWNER access level
+ Array.wrap(fetch_members(Gitlab::Access::OWNER)) | Array.wrap(project.owner)
end
end
@@ -173,7 +179,9 @@ class ProjectTeam
#
# Returns a Hash mapping user ID -> maximum access level.
def max_member_access_for_user_ids(user_ids)
- project.max_member_access_for_resource_ids(User, user_ids) do |user_ids|
+ Gitlab::SafeRequestLoader.execute(resource_key: project.max_member_access_for_resource_key(User),
+ resource_ids: user_ids,
+ default_value: Gitlab::Access::NO_ACCESS) do |user_ids|
project.project_authorizations
.where(user: user_ids)
.group(:user_id)
@@ -190,31 +198,15 @@ class ProjectTeam
end
def contribution_check_for_user_ids(user_ids)
- user_ids = user_ids.uniq
- key = "contribution_check_for_users:#{project.id}"
-
- Gitlab::SafeRequestStore[key] ||= {}
- contributors = Gitlab::SafeRequestStore[key] || {}
-
- user_ids -= contributors.keys
-
- return contributors if user_ids.empty?
-
- resource_contributors = project.merge_requests
- .merged
- .where(author_id: user_ids, target_branch: project.default_branch.to_s)
- .pluck(:author_id)
- .product([true]).to_h
-
- contributors.merge!(resource_contributors)
-
- missing_resource_ids = user_ids - resource_contributors.keys
-
- missing_resource_ids.each do |resource_id|
- contributors[resource_id] = false
+ Gitlab::SafeRequestLoader.execute(resource_key: "contribution_check_for_users:#{project.id}",
+ resource_ids: user_ids,
+ default_value: false) do |user_ids|
+ project.merge_requests
+ .merged
+ .where(author_id: user_ids, target_branch: project.default_branch.to_s)
+ .pluck(:author_id)
+ .product([true]).to_h
end
-
- contributors
end
def contributor?(user_id)
diff --git a/app/models/projects/build_artifacts_size_refresh.rb b/app/models/projects/build_artifacts_size_refresh.rb
new file mode 100644
index 00000000000..afb67b79f0d
--- /dev/null
+++ b/app/models/projects/build_artifacts_size_refresh.rb
@@ -0,0 +1,91 @@
+# frozen_string_literal: true
+
+module Projects
+ class BuildArtifactsSizeRefresh < ApplicationRecord
+ include BulkInsertSafe
+
+ STALE_WINDOW = 3.days
+
+ self.table_name = 'project_build_artifacts_size_refreshes'
+
+ belongs_to :project
+
+ validates :project, presence: true
+
+ STATES = {
+ created: 1,
+ running: 2,
+ pending: 3
+ }.freeze
+
+ state_machine :state, initial: :created do
+ # created -> running <-> pending
+ state :created, value: STATES[:created]
+ state :running, value: STATES[:running]
+ state :pending, value: STATES[:pending]
+
+ event :process do
+ transition [:created, :pending, :running] => :running
+ end
+
+ event :requeue do
+ transition running: :pending
+ end
+
+ # set it only the first time we execute the refresh
+ before_transition created: :running do |refresh|
+ refresh.reset_project_statistics!
+ refresh.refresh_started_at = Time.zone.now
+ end
+
+ before_transition running: any do |refresh, transition|
+ refresh.updated_at = Time.zone.now
+ end
+
+ before_transition running: :pending do |refresh, transition|
+ refresh.last_job_artifact_id = transition.args.first
+ end
+ end
+
+ scope :stale, -> { with_state(:running).where('updated_at < ?', STALE_WINDOW.ago) }
+ scope :remaining, -> { with_state(:created, :pending).or(stale) }
+
+ def self.enqueue_refresh(projects)
+ now = Time.zone.now
+
+ records = Array(projects).map do |project|
+ new(project: project, state: STATES[:created], created_at: now, updated_at: now)
+ end
+
+ bulk_insert!(records, skip_duplicates: true)
+ end
+
+ def self.process_next_refresh!
+ next_refresh = nil
+
+ transaction do
+ next_refresh = remaining
+ .order(:state, :updated_at)
+ .lock('FOR UPDATE SKIP LOCKED')
+ .take
+
+ next_refresh&.process!
+ end
+
+ next_refresh
+ end
+
+ def reset_project_statistics!
+ statistics = project.statistics
+ statistics.update!(build_artifacts_size: 0)
+ statistics.clear_counter!(:build_artifacts_size)
+ end
+
+ def next_batch(limit:)
+ project.job_artifacts.select(:id, :size)
+ .where('created_at <= ? AND id > ?', refresh_started_at, last_job_artifact_id.to_i)
+ .order(:created_at)
+ .limit(limit)
+ end
+ end
+end
diff --git a/app/models/projects/topic.rb b/app/models/projects/topic.rb
index 78bc2df2e1e..b42b03f0618 100644
--- a/app/models/projects/topic.rb
+++ b/app/models/projects/topic.rb
@@ -7,18 +7,19 @@ module Projects
include Avatarable
include Gitlab::SQL::Pattern
- validates :name, presence: true, uniqueness: true, length: { maximum: 255 }
+ validates :name, presence: true, length: { maximum: 255 }
+ validates :name, uniqueness: { case_sensitive: false }, if: :name_changed?
validates :description, length: { maximum: 1024 }
has_many :project_topics, class_name: 'Projects::ProjectTopic'
has_many :projects, through: :project_topics
- scope :order_by_total_projects_count, -> { order(total_projects_count: :desc).order(id: :asc) }
+ scope :order_by_non_private_projects_count, -> { order(non_private_projects_count: :desc).order(id: :asc) }
scope :reorder_by_similarity, -> (search) do
order_expression = Gitlab::Database::SimilarityScore.build_expression(search: search, rules: [
{ column: arel_table['name'] }
])
- reorder(order_expression.desc, arel_table['total_projects_count'].desc, arel_table['id'])
+ reorder(order_expression.desc, arel_table['non_private_projects_count'].desc, arel_table['id'])
end
class << self
diff --git a/app/models/projects/triggered_hooks.rb b/app/models/projects/triggered_hooks.rb
new file mode 100644
index 00000000000..e3aa3d106b7
--- /dev/null
+++ b/app/models/projects/triggered_hooks.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+module Projects
+ class TriggeredHooks
+ def initialize(scope, data)
+ @scope = scope
+ @data = data
+ @relations = []
+ end
+
+ def add_hooks(relation)
+ @relations << relation
+ self
+ end
+
+ def execute
+ # Assumes that the relations implement TriggerableHooks
+ @relations.each do |hooks|
+ hooks.hooks_for(@scope).select_active(@scope, @data).each do |hook|
+ hook.async_execute(@data, @scope.to_s)
+ end
+ end
+ end
+ end
+end
diff --git a/app/models/release.rb b/app/models/release.rb
index 0fda6940249..c6c0920c4d0 100644
--- a/app/models/release.rb
+++ b/app/models/release.rb
@@ -5,6 +5,8 @@ class Release < ApplicationRecord
include CacheMarkdownField
include Importable
include Gitlab::Utils::StrongMemoize
+ include EachBatch
+ include FromUnion
cache_markdown_field :description
@@ -24,6 +26,8 @@ class Release < ApplicationRecord
before_create :set_released_at
validates :project, :tag, presence: true
+ validates :tag, uniqueness: { scope: :project_id }
+
validates :description, length: { maximum: Gitlab::Database::MAX_TEXT_SIZE_LIMIT }, if: :description_changed?
validates_associated :milestone_releases, message: -> (_, obj) { obj[:value].map(&:errors).map(&:full_messages).join(",") }
validates :links, nested_attributes_duplicates: { scope: :release, child_attributes: %i[name url filepath] }
diff --git a/app/models/repository.rb b/app/models/repository.rb
index be8e530c650..346478b6689 100644
--- a/app/models/repository.rb
+++ b/app/models/repository.rb
@@ -15,6 +15,7 @@ class Repository
heads
tags
replace
+ #{REF_MERGE_REQUEST}
#{REF_ENVIRONMENTS}
#{REF_KEEP_AROUND}
#{REF_PIPELINES}
@@ -1084,10 +1085,10 @@ class Repository
blob.data
end
- def create_if_not_exists
+ def create_if_not_exists(default_branch = nil)
return if exists?
- raw.create_repository
+ raw.create_repository(default_branch)
after_create
true
diff --git a/app/models/snippet.rb b/app/models/snippet.rb
index b04fca64c87..38aaeff5c9a 100644
--- a/app/models/snippet.rb
+++ b/app/models/snippet.rb
@@ -350,24 +350,10 @@ class Snippet < ApplicationRecord
snippet_repository&.shard_name || Repository.pick_storage_shard
end
- # Repositories are created with a default branch. This branch
- # can be different from the default branch set in the platform.
- # This method changes the `HEAD` file to point to the existing
- # default branch in case it's different.
- def change_head_to_default_branch
- return unless repository.exists?
- # All snippets must have at least 1 file. Therefore, if
- # `HEAD` is empty is because it's pointing to the wrong
- # default branch
- return unless repository.empty? || list_files('HEAD').empty?
-
- repository.raw_repository.write_ref('HEAD', "refs/heads/#{default_branch}")
- end
-
def create_repository
return if repository_exists? && snippet_repository
- repository.create_if_not_exists
+ repository.create_if_not_exists(default_branch)
track_snippet_repository(repository.storage)
end
diff --git a/app/models/storage/hashed.rb b/app/models/storage/hashed.rb
index c61cd3b6b30..05e93f00912 100644
--- a/app/models/storage/hashed.rb
+++ b/app/models/storage/hashed.rb
@@ -3,6 +3,7 @@
module Storage
class Hashed
attr_accessor :container
+
delegate :gitlab_shell, :repository_storage, to: :container
REPOSITORY_PATH_PREFIX = '@hashed'
diff --git a/app/models/storage/legacy_project.rb b/app/models/storage/legacy_project.rb
index 092e5249a3e..0d12a629b8e 100644
--- a/app/models/storage/legacy_project.rb
+++ b/app/models/storage/legacy_project.rb
@@ -3,6 +3,7 @@
module Storage
class LegacyProject
attr_accessor :project
+
delegate :namespace, :gitlab_shell, :repository_storage, to: :project
def initialize(project)
diff --git a/app/models/todo.rb b/app/models/todo.rb
index dc436570f52..eb5d9965955 100644
--- a/app/models/todo.rb
+++ b/app/models/todo.rb
@@ -34,6 +34,8 @@ class Todo < ApplicationRecord
ATTENTION_REQUESTED => :attention_requested
}.freeze
+ ACTIONS_MULTIPLE_ALLOWED = [Todo::MENTIONED, Todo::DIRECTLY_ADDRESSED].freeze
+
belongs_to :author, class_name: "User"
belongs_to :note
belongs_to :project
diff --git a/app/models/user.rb b/app/models/user.rb
index 9cd238904ff..b3bdc2c1c42 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -16,7 +16,7 @@ class User < ApplicationRecord
include FeatureGate
include CreatedAtFilterable
include BulkMemberAccessLoad
- include BlocksJsonSerialization
+ include BlocksUnsafeSerialization
include WithUploads
include OptionallySearch
include FromUnion
@@ -135,6 +135,7 @@ class User < ApplicationRecord
has_many :u2f_registrations, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
has_many :webauthn_registrations
has_many :chat_names, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
+ has_many :saved_replies, class_name: '::Users::SavedReply'
has_one :user_synced_attributes_metadata, autosave: true
has_one :aws_role, class_name: 'Aws::Role'
@@ -276,24 +277,22 @@ class User < ApplicationRecord
after_update :username_changed_hook, if: :saved_change_to_username?
after_destroy :post_destroy_hook
after_destroy :remove_key_cache
- after_create :add_primary_email_to_emails!, if: :confirmed?
- after_commit(on: :update) do
- if previous_changes.key?('email')
- # Add the old primary email to Emails if not added already - this should be removed
- # after the background migration for MR https://gitlab.com/gitlab-org/gitlab/-/merge_requests/70872/ has completed,
- # as the primary email is now added to Emails upon confirmation
- # Issue to remove that: https://gitlab.com/gitlab-org/gitlab/-/issues/344134
- previous_confirmed_at = previous_changes.key?('confirmed_at') ? previous_changes['confirmed_at'][0] : confirmed_at
- previous_email = previous_changes[:email][0]
- if previous_confirmed_at && !emails.exists?(email: previous_email)
- # rubocop: disable CodeReuse/ServiceClass
- Emails::CreateService.new(self, user: self, email: previous_email).execute(confirmed_at: previous_confirmed_at)
- # rubocop: enable CodeReuse/ServiceClass
- end
+ after_save if: -> { saved_change_to_email? && confirmed? } do
+ email_to_confirm = self.emails.find_by(email: self.email)
- update_invalid_gpg_signatures
+ if email_to_confirm.present?
+ if skip_confirmation_period_expiry_check
+ email_to_confirm.force_confirm
+ else
+ email_to_confirm.confirm
+ end
+ else
+ add_primary_email_to_emails!
end
end
+ after_commit(on: :update) do
+ update_invalid_gpg_signatures if previous_changes.key?('email')
+ end
after_initialize :set_projects_limit
@@ -1692,6 +1691,12 @@ class User < ApplicationRecord
end
end
+ def attention_requested_open_merge_requests_count(force: false)
+ Rails.cache.fetch(attention_request_cache_key, force: force, expires_in: COUNT_CACHE_VALIDITY_PERIOD) do
+ MergeRequestsFinder.new(self, attention: self.username, state: 'opened', non_archived: true).execute.count
+ end
+ end
+
def assigned_open_issues_count(force: false)
Rails.cache.fetch(['users', id, 'assigned_open_issues_count'], force: force, expires_in: COUNT_CACHE_VALIDITY_PERIOD) do
IssuesFinder.new(self, assignee_id: self.id, state: 'opened', non_archived: true).execute.count
@@ -1735,6 +1740,11 @@ class User < ApplicationRecord
def invalidate_merge_request_cache_counts
Rails.cache.delete(['users', id, 'assigned_open_merge_requests_count'])
Rails.cache.delete(['users', id, 'review_requested_open_merge_requests_count'])
+ invalidate_attention_requested_count
+ end
+
+ def invalidate_attention_requested_count
+ Rails.cache.delete(attention_request_cache_key)
end
def invalidate_todos_cache_counts
@@ -1746,6 +1756,10 @@ class User < ApplicationRecord
Rails.cache.delete(['users', id, 'personal_projects_count'])
end
+ def attention_request_cache_key
+ ['users', id, 'attention_requested_open_merge_requests_count']
+ end
+
# This is copied from Devise::Models::Lockable#valid_for_authentication?, as our auth
# flow means we don't call that automatically (and can't conveniently do so).
#
@@ -1846,7 +1860,9 @@ class User < ApplicationRecord
#
# Returns a Hash mapping project ID -> maximum access level.
def max_member_access_for_project_ids(project_ids)
- max_member_access_for_resource_ids(Project, project_ids) do |project_ids|
+ Gitlab::SafeRequestLoader.execute(resource_key: max_member_access_for_resource_key(Project),
+ resource_ids: project_ids,
+ default_value: Gitlab::Access::NO_ACCESS) do |project_ids|
project_authorizations.where(project: project_ids)
.group(:project_id)
.maximum(:access_level)
@@ -1861,7 +1877,9 @@ class User < ApplicationRecord
#
# Returns a Hash mapping project ID -> maximum access level.
def max_member_access_for_group_ids(group_ids)
- max_member_access_for_resource_ids(Group, group_ids) do |group_ids|
+ Gitlab::SafeRequestLoader.execute(resource_key: max_member_access_for_resource_key(Group),
+ resource_ids: group_ids,
+ default_value: Gitlab::Access::NO_ACCESS) do |group_ids|
group_members.where(source: group_ids).group(:source_id).maximum(:access_level)
end
end
@@ -1993,29 +2011,6 @@ class User < ApplicationRecord
ci_job_token_scope.present?
end
- # override from Devise::Models::Confirmable
- #
- # Add the primary email to user.emails (or confirm it if it was already
- # present) when the primary email is confirmed.
- def confirm(args = {})
- saved = super(args)
- return false unless saved
-
- email_to_confirm = self.emails.find_by(email: self.email)
-
- if email_to_confirm.present?
- if skip_confirmation_period_expiry_check
- email_to_confirm.force_confirm(args)
- else
- email_to_confirm.confirm(args)
- end
- else
- add_primary_email_to_emails!
- end
-
- saved
- end
-
def user_project
strong_memoize(:user_project) do
personal_projects.find_by(path: username, visibility_level: Gitlab::VisibilityLevel::PUBLIC)
@@ -2166,7 +2161,7 @@ class User < ApplicationRecord
end
def signup_email_invalid_message
- self.new_record? ? _('is not allowed for sign-up.') : _('is not allowed.')
+ self.new_record? ? _('is not allowed for sign-up. Please use your regular email address.') : _('is not allowed. Please use your regular email address.')
end
def check_username_format
diff --git a/app/models/users/callout.rb b/app/models/users/callout.rb
index 5c39e29a128..0922323e12b 100644
--- a/app/models/users/callout.rb
+++ b/app/models/users/callout.rb
@@ -42,7 +42,13 @@ module Users
security_newsletter_callout: 39,
verification_reminder: 40, # EE-only
ci_deprecation_warning_for_types_keyword: 41,
- security_training_feature_promotion: 42 # EE-only
+ security_training_feature_promotion: 42, # EE-only
+ storage_enforcement_banner_first_enforcement_threshold: 43,
+ storage_enforcement_banner_second_enforcement_threshold: 44,
+ storage_enforcement_banner_third_enforcement_threshold: 45,
+ storage_enforcement_banner_fourth_enforcement_threshold: 46,
+ attention_requests_top_nav: 47,
+ attention_requests_side_nav: 48
}
validates :feature_name,
diff --git a/app/models/users/credit_card_validation.rb b/app/models/users/credit_card_validation.rb
index 556ee03605d..998a5deb0fd 100644
--- a/app/models/users/credit_card_validation.rb
+++ b/app/models/users/credit_card_validation.rb
@@ -8,7 +8,7 @@ module Users
belongs_to :user
- validates :holder_name, length: { maximum: 26 }
+ validates :holder_name, length: { maximum: 50 }
validates :network, length: { maximum: 32 }
validates :last_digits, allow_nil: true, numericality: {
greater_than_or_equal_to: 0, less_than_or_equal_to: 9999
diff --git a/app/models/users/group_callout.rb b/app/models/users/group_callout.rb
index 0dc449719ab..839be8d2a48 100644
--- a/app/models/users/group_callout.rb
+++ b/app/models/users/group_callout.rb
@@ -11,10 +11,10 @@ module Users
enum feature_name: {
invite_members_banner: 1,
approaching_seat_count_threshold: 2, # EE-only
- storage_enforcement_banner_first_enforcement_threshold: 43,
- storage_enforcement_banner_second_enforcement_threshold: 44,
- storage_enforcement_banner_third_enforcement_threshold: 45,
- storage_enforcement_banner_fourth_enforcement_threshold: 46
+ storage_enforcement_banner_first_enforcement_threshold: 3,
+ storage_enforcement_banner_second_enforcement_threshold: 4,
+ storage_enforcement_banner_third_enforcement_threshold: 5,
+ storage_enforcement_banner_fourth_enforcement_threshold: 6
}
validates :group, presence: true
diff --git a/app/models/users/saved_reply.rb b/app/models/users/saved_reply.rb
new file mode 100644
index 00000000000..7737d826b05
--- /dev/null
+++ b/app/models/users/saved_reply.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+module Users
+ class SavedReply < ApplicationRecord
+ self.table_name = 'saved_replies'
+
+ belongs_to :user
+
+ validates :user_id, :name, :content, presence: true
+ validates :name,
+ length: { maximum: 255 },
+ uniqueness: { scope: [:user_id] },
+ format: {
+ with: Gitlab::Regex.saved_reply_name_regex,
+ message: Gitlab::Regex.saved_reply_name_regex_message
+ }
+ validates :content, length: { maximum: 10000 }
+ end
+end
diff --git a/app/models/wiki.rb b/app/models/wiki.rb
index e114e30d589..622070abd88 100644
--- a/app/models/wiki.rb
+++ b/app/models/wiki.rb
@@ -87,8 +87,7 @@ class Wiki
end
def create_wiki_repository
- repository.create_if_not_exists
- change_head_to_default_branch
+ repository.create_if_not_exists(default_branch)
raise CouldNotCreateWikiError unless repository_exists?
rescue StandardError => err
@@ -150,10 +149,10 @@ class Wiki
# the page.
#
# Returns an initialized WikiPage instance or nil
- def find_page(title, version = nil)
+ def find_page(title, version = nil, load_content: true)
page_title, page_dir = page_title_and_dir(title)
- if page = wiki.page(title: page_title, version: version, dir: page_dir)
+ if page = wiki.page(title: page_title, version: version, dir: page_dir, load_content: load_content)
WikiPage.new(self, page)
end
end
@@ -322,16 +321,6 @@ class Wiki
def default_message(action, title)
"#{user.username} #{action} page: #{title}"
end
-
- def change_head_to_default_branch
- # If the wiki has commits in the 'HEAD' branch means that the current
- # HEAD is pointing to the right branch. If not, it could mean that either
- # the repo has just been created or that 'HEAD' is pointing
- # to the wrong branch and we need to rewrite it
- return if repository.raw_repository.commit_count('HEAD') != 0
-
- repository.raw_repository.write_ref('HEAD', "refs/heads/#{default_branch}")
- end
end
Wiki.prepend_mod_with('Wiki')
diff --git a/app/models/wiki_page.rb b/app/models/wiki_page.rb
index 3dbbbcdfe23..803b9781ac4 100644
--- a/app/models/wiki_page.rb
+++ b/app/models/wiki_page.rb
@@ -45,6 +45,7 @@ class WikiPage
# The GitLab Wiki instance.
attr_reader :wiki
+
delegate :container, to: :wiki
# The raw Gitlab::Git::WikiPage instance.
@@ -315,7 +316,6 @@ class WikiPage
end
def update_front_matter(attrs)
- return unless Gitlab::WikiPages::FrontMatterParser.enabled?(container)
return unless attrs.has_key?(:front_matter)
fm_yaml = serialize_front_matter(attrs[:front_matter])
@@ -326,7 +326,7 @@ class WikiPage
def parsed_content
strong_memoize(:parsed_content) do
- Gitlab::WikiPages::FrontMatterParser.new(raw_content, container).parse
+ Gitlab::WikiPages::FrontMatterParser.new(raw_content).parse
end
end
@@ -404,3 +404,5 @@ class WikiPage
})
end
end
+
+WikiPage.prepend_mod
diff --git a/app/models/work_item.rb b/app/models/work_item.rb
index 99f05e4a181..557694da35a 100644
--- a/app/models/work_item.rb
+++ b/app/models/work_item.rb
@@ -7,4 +7,12 @@ class WorkItem < Issue
def noteable_target_type_name
'issue'
end
+
+ private
+
+ def record_create_action
+ super
+
+ Gitlab::UsageDataCounters::WorkItemActivityUniqueCounter.track_work_item_created_action(author: author)
+ end
end
diff --git a/app/models/work_items/type.rb b/app/models/work_items/type.rb
index 494c4f5abe4..080513b28e9 100644
--- a/app/models/work_items/type.rb
+++ b/app/models/work_items/type.rb
@@ -38,6 +38,7 @@ module WorkItems
scope :default, -> { where(namespace: nil) }
scope :order_by_name_asc, -> { order('LOWER(name)') }
+ scope :by_type, ->(base_type) { where(base_type: base_type) }
def self.default_by_type(type)
find_by(namespace_id: nil, base_type: type)
diff --git a/app/policies/alert_management/alert_policy.rb b/app/policies/alert_management/alert_policy.rb
index 85fafcde2cc..e2383921c82 100644
--- a/app/policies/alert_management/alert_policy.rb
+++ b/app/policies/alert_management/alert_policy.rb
@@ -5,3 +5,5 @@ module AlertManagement
delegate { @subject.project }
end
end
+
+AlertManagement::AlertPolicy.prepend_mod
diff --git a/app/policies/application_setting_policy.rb b/app/policies/application_setting_policy.rb
index 114c71fd99d..6d0b5f36fa4 100644
--- a/app/policies/application_setting_policy.rb
+++ b/app/policies/application_setting_policy.rb
@@ -1,5 +1,8 @@
# frozen_string_literal: true
class ApplicationSettingPolicy < BasePolicy # rubocop:disable Gitlab/NamespacedClass
- rule { admin }.enable :read_application_setting
+ rule { admin }.policy do
+ enable :read_application_setting
+ enable :update_runners_registration_token
+ end
end
diff --git a/app/policies/base_policy.rb b/app/policies/base_policy.rb
index 77897c5807f..f8e7a912896 100644
--- a/app/policies/base_policy.rb
+++ b/app/policies/base_policy.rb
@@ -67,7 +67,7 @@ class BasePolicy < DeclarativePolicy::Base
rule { default }.enable :read_cross_project
- condition(:is_gitlab_com, score: 0, scope: :global) { ::Gitlab.dev_env_or_com? }
+ condition(:is_gitlab_com, score: 0, scope: :global) { ::Gitlab.com? }
end
BasePolicy.prepend_mod_with('BasePolicy')
diff --git a/app/policies/ci/runner_policy.rb b/app/policies/ci/runner_policy.rb
index bdbe7021276..6dfe9cc496b 100644
--- a/app/policies/ci/runner_policy.rb
+++ b/app/policies/ci/runner_policy.rb
@@ -9,6 +9,10 @@ module Ci
@user.owns_runner?(@subject)
end
+ condition(:belongs_to_multiple_projects) do
+ @subject.belongs_to_more_than_one_project?
+ end
+
rule { anonymous }.prevent_all
rule { admin }.policy do
@@ -22,6 +26,8 @@ module Ci
enable :delete_runner
end
+ rule { ~admin & belongs_to_multiple_projects }.prevent :delete_runner
+
rule { ~admin & locked }.prevent :assign_runner
end
end
diff --git a/app/policies/global_policy.rb b/app/policies/global_policy.rb
index 2a2ddf29899..fa7b117f3cd 100644
--- a/app/policies/global_policy.rb
+++ b/app/policies/global_policy.rb
@@ -115,7 +115,6 @@ class GlobalPolicy < BasePolicy
enable :approve_user
enable :reject_user
enable :read_usage_trends_measurement
- enable :update_runners_registration_token
end
# We can't use `read_statistics` because the user may have different permissions for different projects
diff --git a/app/policies/group_policy.rb b/app/policies/group_policy.rb
index 76e5b3ece53..7a49ad3d4aa 100644
--- a/app/policies/group_policy.rb
+++ b/app/policies/group_policy.rb
@@ -80,9 +80,8 @@ class GroupPolicy < Namespaces::GroupProjectNamespaceSharedPolicy
condition(:crm_enabled, score: 0, scope: :subject) { Feature.enabled?(:customer_relations, @subject) && @subject.crm_enabled? }
- with_scope :subject
- condition(:group_runner_registration_allowed, score: 0, scope: :subject) do
- Feature.disabled?(:runner_registration_control) || Gitlab::CurrentSettings.valid_runner_registrars.include?('group')
+ condition(:group_runner_registration_allowed) do
+ Feature.disabled?(:runner_registration_control, default_enabled: :yaml) || Gitlab::CurrentSettings.valid_runner_registrars.include?('group')
end
rule { can?(:read_group) & design_management_enabled }.policy do
@@ -280,7 +279,7 @@ class GroupPolicy < Namespaces::GroupProjectNamespaceSharedPolicy
prevent :admin_crm_organization
end
- rule { ~group_runner_registration_allowed }.policy do
+ rule { ~admin & ~group_runner_registration_allowed }.policy do
prevent :register_group_runners
end
diff --git a/app/policies/issue_policy.rb b/app/policies/issue_policy.rb
index c9c13b29643..a667c843bc6 100644
--- a/app/policies/issue_policy.rb
+++ b/app/policies/issue_policy.rb
@@ -13,7 +13,7 @@ class IssuePolicy < IssuablePolicy
end
desc "User can read contacts belonging to the issue group"
- condition(:can_read_crm_contacts, scope: :subject) { @user.can?(:read_crm_contact, @subject.project.group) }
+ condition(:can_read_crm_contacts, scope: :subject) { @user.can?(:read_crm_contact, @subject.project.root_ancestor) }
desc "Issue is confidential"
condition(:confidential, scope: :subject) { @subject.confidential? }
diff --git a/app/policies/project_policy.rb b/app/policies/project_policy.rb
index 4cc5ed06d61..09085bef9f0 100644
--- a/app/policies/project_policy.rb
+++ b/app/policies/project_policy.rb
@@ -194,6 +194,10 @@ class ProjectPolicy < BasePolicy
condition(:"#{f}_disabled", score: 32) { !access_allowed_to?(f.to_sym) }
end
+ condition(:project_runner_registration_allowed) do
+ Feature.disabled?(:runner_registration_control, default_enabled: :yaml) || Gitlab::CurrentSettings.valid_runner_registrars.include?('project')
+ end
+
# `:read_project` may be prevented in EE, but `:read_project_for_iids` should
# not.
rule { guest | admin }.enable :read_project_for_iids
@@ -230,6 +234,8 @@ class ProjectPolicy < BasePolicy
enable :set_emails_disabled
enable :set_show_default_award_emojis
enable :set_warn_about_potentially_unwanted_characters
+
+ enable :register_project_runners
end
rule { can?(:guest_access) }.policy do
@@ -264,8 +270,6 @@ class ProjectPolicy < BasePolicy
enable :create_work_item
end
- rule { can?(:update_issue) }.enable :update_work_item
-
# These abilities are not allowed to admins that are not members of the project,
# that's why they are defined separately.
rule { guest & can?(:download_code) }.enable :build_download_code
@@ -409,6 +413,7 @@ class ProjectPolicy < BasePolicy
enable :admin_feature_flag
enable :admin_feature_flags_user_lists
enable :update_escalation_status
+ enable :read_secure_files
end
rule { can?(:developer_access) & user_confirmed? }.policy do
@@ -455,8 +460,10 @@ class ProjectPolicy < BasePolicy
enable :update_freeze_period
enable :destroy_freeze_period
enable :admin_feature_flags_client
+ enable :register_project_runners
enable :update_runners_registration_token
enable :admin_project_google_cloud
+ enable :admin_secure_files
end
rule { public_project & metrics_dashboard_allowed }.policy do
@@ -729,6 +736,10 @@ class ProjectPolicy < BasePolicy
enable :access_security_and_compliance
end
+ rule { ~admin & ~project_runner_registration_allowed }.policy do
+ prevent :register_project_runners
+ end
+
private
def user_is_user?
diff --git a/app/policies/user_policy.rb b/app/policies/user_policy.rb
index 018c061af9f..de99cbffb6f 100644
--- a/app/policies/user_policy.rb
+++ b/app/policies/user_policy.rb
@@ -23,9 +23,12 @@ class UserPolicy < BasePolicy
enable :destroy_user
enable :update_user
enable :update_user_status
+ enable :create_saved_replies
+ enable :update_saved_replies
enable :read_user_personal_access_tokens
enable :read_group_count
enable :read_user_groups
+ enable :read_saved_replies
end
rule { default }.enable :read_user_profile
diff --git a/app/policies/users/saved_reply_policy.rb b/app/policies/users/saved_reply_policy.rb
new file mode 100644
index 00000000000..be76c526012
--- /dev/null
+++ b/app/policies/users/saved_reply_policy.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+module Users
+ class SavedReplyPolicy < BasePolicy
+ delegate { @subject.user }
+ end
+end
diff --git a/app/policies/work_item_policy.rb b/app/policies/work_item_policy.rb
index 7ba5102a406..b4723bc7ed8 100644
--- a/app/policies/work_item_policy.rb
+++ b/app/policies/work_item_policy.rb
@@ -1,12 +1,9 @@
# frozen_string_literal: true
-class WorkItemPolicy < BasePolicy
- delegate { @subject.project }
+class WorkItemPolicy < IssuePolicy
+ rule { can?(:owner_access) | is_author }.enable :delete_work_item
- desc 'User is author of the work item'
- condition(:author) do
- @user && @user == @subject.author
- end
+ rule { can?(:update_issue) }.enable :update_work_item
- rule { can?(:owner_access) | author }.enable :delete_work_item
+ rule { can?(:read_issue) }.enable :read_work_item
end
diff --git a/app/presenters/alert_management/alert_presenter.rb b/app/presenters/alert_management/alert_presenter.rb
index b692935d229..659e991e9d8 100644
--- a/app/presenters/alert_management/alert_presenter.rb
+++ b/app/presenters/alert_management/alert_presenter.rb
@@ -3,7 +3,6 @@
module AlertManagement
class AlertPresenter < Gitlab::View::Presenter::Delegated
include IncidentManagement::Settings
- include ActionView::Helpers::UrlHelper
presents ::AlertManagement::Alert
delegator_override_with Gitlab::Utils::StrongMemoize # This module inclusion is expected. See https://gitlab.com/gitlab-org/gitlab/-/issues/352884.
diff --git a/app/presenters/blob_presenter.rb b/app/presenters/blob_presenter.rb
index 47b72df32a2..aeab914dc9e 100644
--- a/app/presenters/blob_presenter.rb
+++ b/app/presenters/blob_presenter.rb
@@ -1,5 +1,4 @@
# frozen_string_literal: true
-require 'ipynbdiff'
class BlobPresenter < Gitlab::View::Presenter::Delegated
include ApplicationHelper
@@ -56,13 +55,19 @@ class BlobPresenter < Gitlab::View::Presenter::Delegated
end
def replace_path
- url_helpers.project_create_blob_path(project, ref_qualified_path)
+ url_helpers.project_update_blob_path(project, ref_qualified_path)
end
def pipeline_editor_path
project_ci_pipeline_editor_path(project, branch_name: blob.commit_id) if can_collaborate_with_project?(project) && blob.path == project.ci_config_path_or_default
end
+ def gitpod_blob_url
+ return unless Gitlab::CurrentSettings.gitpod_enabled && !current_user.nil? && current_user.gitpod_enabled
+
+ "#{Gitlab::CurrentSettings.gitpod_url}##{url_helpers.project_tree_url(project, tree_join(blob.commit_id, blob.path || ''))}"
+ end
+
def find_file_path
url_helpers.project_find_file_path(project, ref_qualified_path)
end
@@ -104,6 +109,10 @@ class BlobPresenter < Gitlab::View::Presenter::Delegated
fork_path_for_current_user(project, ide_edit_path)
end
+ def fork_and_view_path
+ fork_path_for_current_user(project, web_path)
+ end
+
def can_modify_blob?
super(blob, project, blob.commit_id)
end
@@ -128,6 +137,14 @@ class BlobPresenter < Gitlab::View::Presenter::Delegated
external_storage_url_or_path(url_helpers.project_raw_url(project, ref_qualified_path), project)
end
+ def code_navigation_path
+ Gitlab::CodeNavigationPath.new(project, blob.commit_id).full_json_path_for(blob.path)
+ end
+
+ def project_blob_path_root
+ project_blob_path(project, blob.commit_id)
+ end
+
private
def url_helpers
diff --git a/app/presenters/blobs/notebook_presenter.rb b/app/presenters/blobs/notebook_presenter.rb
new file mode 100644
index 00000000000..16ae1e71191
--- /dev/null
+++ b/app/presenters/blobs/notebook_presenter.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+module Blobs
+ class NotebookPresenter < ::BlobPresenter
+ def gitattr_language
+ 'md'
+ end
+ end
+end
diff --git a/app/presenters/ci/build_runner_presenter.rb b/app/presenters/ci/build_runner_presenter.rb
index 8e1b675d051..082993130a1 100644
--- a/app/presenters/ci/build_runner_presenter.rb
+++ b/app/presenters/ci/build_runner_presenter.rb
@@ -105,10 +105,7 @@ module Ci
end
def refspec_for_persistent_ref
- # Use persistent_ref.sha because it sometimes causes 'git fetch' to do
- # less work. See
- # https://gitlab.com/gitlab-com/gl-infra/scalability/-/issues/746.
- "+#{pipeline.persistent_ref.sha}:#{pipeline.persistent_ref.path}"
+ "+#{pipeline.persistent_ref.path}:#{pipeline.persistent_ref.path}"
end
def persistent_ref_exist?
diff --git a/app/presenters/ci/pipeline_presenter.rb b/app/presenters/ci/pipeline_presenter.rb
index 2818e6da036..410b633df50 100644
--- a/app/presenters/ci/pipeline_presenter.rb
+++ b/app/presenters/ci/pipeline_presenter.rb
@@ -5,7 +5,6 @@ module Ci
include Gitlab::Utils::StrongMemoize
delegator_override_with Gitlab::Utils::StrongMemoize # This module inclusion is expected. See https://gitlab.com/gitlab-org/gitlab/-/issues/352884.
- delegator_override_with ActionView::Helpers::TagHelper # TODO: Remove `ActionView::Helpers::UrlHelper` inclusion as it overrides `Ci::Pipeline#tag`
# We use a class method here instead of a constant, allowing EE to redefine
# the returned `Hash` more easily.
diff --git a/app/presenters/clusterable_presenter.rb b/app/presenters/clusterable_presenter.rb
index cc466e0ff81..82152ce42ae 100644
--- a/app/presenters/clusterable_presenter.rb
+++ b/app/presenters/clusterable_presenter.rb
@@ -32,6 +32,10 @@ class ClusterablePresenter < Gitlab::View::Presenter::Delegated
new_polymorphic_path([clusterable, :cluster], options)
end
+ def connect_path
+ polymorphic_path([clusterable, :clusters], action: :connect)
+ end
+
def authorize_aws_role_path
polymorphic_path([clusterable, :clusters], action: :authorize_aws_role)
end
diff --git a/app/presenters/environment_presenter.rb b/app/presenters/environment_presenter.rb
index 6c8da86187c..fe828fb9fd8 100644
--- a/app/presenters/environment_presenter.rb
+++ b/app/presenters/environment_presenter.rb
@@ -1,8 +1,6 @@
# frozen_string_literal: true
class EnvironmentPresenter < Gitlab::View::Presenter::Delegated
- include ActionView::Helpers::UrlHelper
-
presents ::Environment, as: :environment
def path
diff --git a/app/presenters/gitlab/blame_presenter.rb b/app/presenters/gitlab/blame_presenter.rb
index e9340a42e51..5dd2f3adda5 100644
--- a/app/presenters/gitlab/blame_presenter.rb
+++ b/app/presenters/gitlab/blame_presenter.rb
@@ -2,7 +2,6 @@
module Gitlab
class BlamePresenter < Gitlab::View::Presenter::Simple
- include ActionView::Helpers::UrlHelper
include ActionView::Helpers::TranslationHelper
include ActionView::Context
include AvatarsHelper
@@ -75,5 +74,13 @@ module Gitlab
def project_duration
@project_duration ||= age_map_duration(groups, project)
end
+
+ def link_to(*args, &block)
+ ActionController::Base.helpers.link_to(*args, &block)
+ end
+
+ def mail_to(*args, &block)
+ ActionController::Base.helpers.mail_to(*args, &block)
+ end
end
end
diff --git a/app/presenters/instance_clusterable_presenter.rb b/app/presenters/instance_clusterable_presenter.rb
index f2550eb17e3..9e4a3b403ea 100644
--- a/app/presenters/instance_clusterable_presenter.rb
+++ b/app/presenters/instance_clusterable_presenter.rb
@@ -38,6 +38,11 @@ class InstanceClusterablePresenter < ClusterablePresenter
admin_cluster_path(cluster, params)
end
+ override :connect_path
+ def connect_path
+ connect_admin_clusters_path
+ end
+
override :create_user_clusters_path
def create_user_clusters_path
create_user_admin_clusters_path
diff --git a/app/presenters/label_presenter.rb b/app/presenters/label_presenter.rb
index 8d604f9a0f6..6929bf79fdf 100644
--- a/app/presenters/label_presenter.rb
+++ b/app/presenters/label_presenter.rb
@@ -14,6 +14,10 @@ class LabelPresenter < Gitlab::View::Presenter::Delegated
end
end
+ def text_color_class
+ "gl-label-text-#{label.color.contrast.luminosity}"
+ end
+
def destroy_path
case label
when GroupLabel then group_label_path(label.group, label)
diff --git a/app/presenters/merge_request_presenter.rb b/app/presenters/merge_request_presenter.rb
index 8450679dd79..6dd3908b21d 100644
--- a/app/presenters/merge_request_presenter.rb
+++ b/app/presenters/merge_request_presenter.rb
@@ -1,7 +1,6 @@
# frozen_string_literal: true
class MergeRequestPresenter < Gitlab::View::Presenter::Delegated
- include ActionView::Helpers::UrlHelper
include GitlabRoutingHelper
include MarkupHelper
include TreeHelper
@@ -150,7 +149,11 @@ class MergeRequestPresenter < Gitlab::View::Presenter::Delegated
)
end
- def assign_to_closing_issues_link
+ def assign_to_closing_issues_path
+ assign_related_issues_project_merge_request_path(project, merge_request)
+ end
+
+ def assign_to_closing_issues_count
# rubocop: disable CodeReuse/ServiceClass
issues = MergeRequests::AssignIssuesService.new(project: project,
current_user: current_user,
@@ -158,14 +161,7 @@ class MergeRequestPresenter < Gitlab::View::Presenter::Delegated
merge_request: merge_request,
closes_issues: closing_issues
}).assignable_issues
- path = assign_related_issues_project_merge_request_path(project, merge_request)
- if issues.present?
- if issues.count > 1
- link_to _('Assign yourself to these issues'), path, method: :post
- else
- link_to _('Assign yourself to this issue'), path, method: :post
- end
- end
+ issues.count
# rubocop: enable CodeReuse/ServiceClass
end
@@ -290,6 +286,11 @@ class MergeRequestPresenter < Gitlab::View::Presenter::Delegated
def user_can_fork_project?
can?(current_user, :fork_project, project)
end
+
+ # Avoid including ActionView::Helpers::UrlHelper
+ def link_to(*args)
+ ApplicationController.helpers.link_to(*args)
+ end
end
MergeRequestPresenter.prepend_mod_with('MergeRequestPresenter')
diff --git a/app/presenters/project_clusterable_presenter.rb b/app/presenters/project_clusterable_presenter.rb
index 6c4d1143c0f..624fa1e0cb0 100644
--- a/app/presenters/project_clusterable_presenter.rb
+++ b/app/presenters/project_clusterable_presenter.rb
@@ -22,12 +22,12 @@ class ProjectClusterablePresenter < ClusterablePresenter
override :sidebar_text
def sidebar_text
- s_('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.')
+ s_('ClusterIntegration|Use GitLab to deploy to your cluster, run jobs, use review apps, and more.')
end
override :learn_more_link
def learn_more_link
- ApplicationController.helpers.link_to(s_('ClusterIntegration|Learn more about Kubernetes'), help_page_path('user/project/clusters/index'), target: '_blank', rel: 'noopener noreferrer')
+ ApplicationController.helpers.link_to(s_('ClusterIntegration|Learn more about Kubernetes.'), help_page_path('user/project/clusters/index'), target: '_blank', rel: 'noopener noreferrer')
end
def metrics_dashboard_path(cluster)
diff --git a/app/presenters/project_presenter.rb b/app/presenters/project_presenter.rb
index 9e64d2d43a2..098519cdffe 100644
--- a/app/presenters/project_presenter.rb
+++ b/app/presenters/project_presenter.rb
@@ -2,7 +2,6 @@
class ProjectPresenter < Gitlab::View::Presenter::Delegated
include ActionView::Helpers::NumberHelper
- include ActionView::Helpers::UrlHelper
include GitlabRoutingHelper
include StorageHelper
include TreeHelper
@@ -138,17 +137,6 @@ class ProjectPresenter < Gitlab::View::Presenter::Delegated
ide_edit_path(project, default_branch_or_main, 'README.md')
end
- def add_code_quality_ci_yml_path
- add_special_file_path(
- file_name: ci_config_path_or_default,
- commit_message: s_("CommitMessage|Add %{file_name} and create a code quality job") % { file_name: ci_config_path_or_default },
- additional_params: {
- template: 'Code-Quality',
- code_quality_walkthrough: true
- }
- )
- end
-
def license_short_name
license = repository.license
license&.nickname || license&.name || 'LICENSE'
@@ -473,6 +461,11 @@ class ProjectPresenter < Gitlab::View::Presenter::Delegated
project.topics.map(&:name)
end
end
+
+ # Avoid including ActionView::Helpers::UrlHelper
+ def content_tag(*args)
+ ActionController::Base.helpers.content_tag(*args)
+ end
end
ProjectPresenter.prepend_mod_with('ProjectPresenter')
diff --git a/app/presenters/release_presenter.rb b/app/presenters/release_presenter.rb
index dac42af38bf..fc47ece6199 100644
--- a/app/presenters/release_presenter.rb
+++ b/app/presenters/release_presenter.rb
@@ -1,14 +1,8 @@
# frozen_string_literal: true
class ReleasePresenter < Gitlab::View::Presenter::Delegated
- include ActionView::Helpers::UrlHelper
-
presents ::Release, as: :release
- # TODO: Remove `delegate` as it's redundant due to SimpleDelegator.
- delegator_override :tag, :project
- delegate :project, :tag, to: :release
-
def commit_path
return unless release.commit && can_download_code?
diff --git a/app/presenters/releases/evidence_presenter.rb b/app/presenters/releases/evidence_presenter.rb
index bdc053a303b..f7da6ceb8fe 100644
--- a/app/presenters/releases/evidence_presenter.rb
+++ b/app/presenters/releases/evidence_presenter.rb
@@ -2,8 +2,6 @@
module Releases
class EvidencePresenter < Gitlab::View::Presenter::Delegated
- include ActionView::Helpers::UrlHelper
-
presents ::Releases::Evidence, as: :evidence
def filepath
diff --git a/app/presenters/search_service_presenter.rb b/app/presenters/search_service_presenter.rb
index 72f967b8beb..4755b88cbea 100644
--- a/app/presenters/search_service_presenter.rb
+++ b/app/presenters/search_service_presenter.rb
@@ -25,7 +25,7 @@ class SearchServicePresenter < Gitlab::View::Presenter::Delegated
case scope
when 'users'
- objects.eager_load(:status) # rubocop:disable CodeReuse/ActiveRecord
+ objects.eager_load(:status) if objects.respond_to?(:eager_load) # rubocop:disable CodeReuse/ActiveRecord
when 'commits'
prepare_commits_for_rendering(objects)
else
diff --git a/app/presenters/user_presenter.rb b/app/presenters/user_presenter.rb
index 5a99f10b6e7..dc775fb4160 100644
--- a/app/presenters/user_presenter.rb
+++ b/app/presenters/user_presenter.rb
@@ -11,6 +11,22 @@ class UserPresenter < Gitlab::View::Presenter::Delegated
should_be_private? ? ProjectMember.none : user.project_members
end
+ def preferences_gitpod_path
+ profile_preferences_path(anchor: 'user_gitpod_enabled') if application_gitpod_enabled?
+ end
+
+ def profile_enable_gitpod_path
+ profile_path(user: { gitpod_enabled: true }) if application_gitpod_enabled?
+ end
+
+ delegator_override :saved_replies
+ def saved_replies
+ return ::Users::SavedReply.none unless Feature.enabled?(:saved_replies, current_user, default_enabled: :yaml)
+ return ::Users::SavedReply.none unless current_user.can?(:read_saved_replies, user)
+
+ user.saved_replies
+ end
+
private
def can?(*args)
@@ -20,4 +36,8 @@ class UserPresenter < Gitlab::View::Presenter::Delegated
def should_be_private?
!Ability.allowed?(current_user, :read_user_profile, user)
end
+
+ def application_gitpod_enabled?
+ Gitlab::CurrentSettings.gitpod_enabled
+ end
end
diff --git a/app/serializers/analytics/cycle_analytics/stage_entity.rb b/app/serializers/analytics/cycle_analytics/stage_entity.rb
index cfbf6f60e38..c1d415dfb40 100644
--- a/app/serializers/analytics/cycle_analytics/stage_entity.rb
+++ b/app/serializers/analytics/cycle_analytics/stage_entity.rb
@@ -57,7 +57,8 @@ module Analytics
def html_description(event)
options = {}
if event.label_based?
- options[:label_html] = render_label(event.label, link: '', small: true, tooltip: true)
+ label = event.label.present(issuable_subject: event.label.subject)
+ options[:label_html] = render_label(label, link: '', small: true, tooltip: true)
end
content_tag(:p) { event.html_description(options).html_safe }
diff --git a/app/serializers/cluster_entity.rb b/app/serializers/cluster_entity.rb
index ba42e14be22..e2d24e74b29 100644
--- a/app/serializers/cluster_entity.rb
+++ b/app/serializers/cluster_entity.rb
@@ -24,7 +24,7 @@ class ClusterEntity < Grape::Entity
end
expose :kubernetes_errors do |cluster|
- ClusterErrorEntity.new(cluster)
+ Clusters::KubernetesErrorEntity.new(cluster)
end
expose :enable_advanced_logs_querying do |cluster|
diff --git a/app/serializers/cluster_error_entity.rb b/app/serializers/cluster_error_entity.rb
deleted file mode 100644
index c749537cb94..00000000000
--- a/app/serializers/cluster_error_entity.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-# frozen_string_literal: true
-
-class ClusterErrorEntity < Grape::Entity
- expose :connection_error
- expose :metrics_connection_error
- expose :node_connection_error
-end
diff --git a/app/serializers/clusters/kubernetes_error_entity.rb b/app/serializers/clusters/kubernetes_error_entity.rb
new file mode 100644
index 00000000000..ceab10f232e
--- /dev/null
+++ b/app/serializers/clusters/kubernetes_error_entity.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+module Clusters
+ class KubernetesErrorEntity < Grape::Entity
+ expose :connection_error
+ expose :metrics_connection_error
+ expose :node_connection_error
+ end
+end
diff --git a/app/serializers/deployment_entity.rb b/app/serializers/deployment_entity.rb
index 7a2fba73f3a..020c66af777 100644
--- a/app/serializers/deployment_entity.rb
+++ b/app/serializers/deployment_entity.rb
@@ -73,3 +73,5 @@ class DeploymentEntity < Grape::Entity
request.try(:project) || options[:project]
end
end
+
+DeploymentEntity.prepend_mod
diff --git a/app/serializers/diffs_entity.rb b/app/serializers/diffs_entity.rb
index e0565a1e506..c818fcd6215 100644
--- a/app/serializers/diffs_entity.rb
+++ b/app/serializers/diffs_entity.rb
@@ -23,7 +23,7 @@ class DiffsEntity < Grape::Entity
CommitEntity.represent(options[:commit], commit_options(options))
end
- expose :context_commits, using: API::Entities::Commit, if: -> (diffs, options) { merge_request&.project&.context_commits_enabled? } do |diffs|
+ expose :context_commits, using: API::Entities::Commit do |diffs|
options[:context_commits]
end
@@ -89,7 +89,7 @@ class DiffsEntity < Grape::Entity
project_blob_path(merge_request.project, merge_request.diff_head_sha)
end
- expose :context_commits_diff, if: -> (_) { merge_request&.project&.context_commits_enabled? } do |diffs, options|
+ expose :context_commits_diff do |diffs, options|
next unless merge_request.context_commits_diff.commits_count > 0
ContextCommitsDiffEntity.represent(
diff --git a/app/serializers/environment_entity.rb b/app/serializers/environment_entity.rb
index 6105b52fbda..d484f60ed8f 100644
--- a/app/serializers/environment_entity.rb
+++ b/app/serializers/environment_entity.rb
@@ -20,6 +20,7 @@ class EnvironmentEntity < Grape::Entity
expose :last_deployment, using: DeploymentEntity
expose :stop_action_available?, as: :has_stop_action
expose :rollout_status, if: -> (*) { can_read_deploy_board? }, using: RolloutStatusEntity
+ expose :tier
expose :upcoming_deployment, if: -> (environment) { environment.upcoming_deployment } do |environment, ops|
DeploymentEntity.represent(environment.upcoming_deployment,
diff --git a/app/serializers/environment_serializer.rb b/app/serializers/environment_serializer.rb
index 8d9b73b2290..a8645c8670d 100644
--- a/app/serializers/environment_serializer.rb
+++ b/app/serializers/environment_serializer.rb
@@ -60,7 +60,7 @@ class EnvironmentSerializer < BaseSerializer
Preloaders::Environments::DeploymentPreloader.new(resource)
.execute_with_union(:upcoming_deployment, deployment_associations)
- resource.all.to_a.tap do |environments|
+ resource.to_a.tap do |environments|
environments.each do |environment|
# Batch loading the commits of the deployments
environment.last_deployment&.commit&.try(:lazy_author)
diff --git a/app/serializers/fork_namespace_entity.rb b/app/serializers/fork_namespace_entity.rb
index 2be37d23a05..997abb0f148 100644
--- a/app/serializers/fork_namespace_entity.rb
+++ b/app/serializers/fork_namespace_entity.rb
@@ -30,14 +30,6 @@ class ForkNamespaceEntity < Grape::Entity
markdown_description(namespace)
end
- expose :can_create_project do |namespace, options|
- if Feature.enabled?(:fork_project_form, options[:project], default_enabled: :yaml)
- true
- else
- options[:current_user].can?(:create_projects, namespace)
- end
- end
-
private
# rubocop: disable CodeReuse/ActiveRecord
diff --git a/app/serializers/issue_sidebar_basic_entity.rb b/app/serializers/issue_sidebar_basic_entity.rb
index 9c6601afd5e..7222b5df425 100644
--- a/app/serializers/issue_sidebar_basic_entity.rb
+++ b/app/serializers/issue_sidebar_basic_entity.rb
@@ -10,6 +10,11 @@ class IssueSidebarBasicEntity < IssuableSidebarBasicEntity
can?(current_user, :update_escalation_status, issue.project)
end
end
+
+ expose :show_crm_contacts do |issuable|
+ current_user&.can?(:read_crm_contact, issuable.project.root_ancestor) &&
+ CustomerRelations::Contact.exists_for_group?(issuable.project.root_ancestor)
+ end
end
IssueSidebarBasicEntity.prepend_mod_with('IssueSidebarBasicEntity')
diff --git a/app/serializers/label_entity.rb b/app/serializers/label_entity.rb
index e586d7f8407..5785715390f 100644
--- a/app/serializers/label_entity.rb
+++ b/app/serializers/label_entity.rb
@@ -4,7 +4,9 @@ class LabelEntity < Grape::Entity
expose :id
expose :title
- expose :color
+ expose :color do |label|
+ label.color.to_s
+ end
expose :description
expose :group_id
expose :project_id
diff --git a/app/serializers/member_entity.rb b/app/serializers/member_entity.rb
index f2f97f560e0..bfb5b3eeae6 100644
--- a/app/serializers/member_entity.rb
+++ b/app/serializers/member_entity.rb
@@ -41,7 +41,7 @@ class MemberEntity < Grape::Entity
expose :valid_level_roles, as: :valid_roles
expose :user, if: -> (member) { member.user.present? } do |member, options|
- MemberUserEntity.represent(member.user, source: options[:source])
+ MemberUserEntity.represent(member.user, options)
end
expose :state
diff --git a/app/serializers/merge_request_widget_entity.rb b/app/serializers/merge_request_widget_entity.rb
index b9c71e6d97b..21ab20747d0 100644
--- a/app/serializers/merge_request_widget_entity.rb
+++ b/app/serializers/merge_request_widget_entity.rb
@@ -104,7 +104,11 @@ class MergeRequestWidgetEntity < Grape::Entity
# include them if they are explicitly requested on first load.
expose :issues_links, if: -> (_, opts) { opts[:issues_links] } do
expose :assign_to_closing do |merge_request|
- presenter(merge_request).assign_to_closing_issues_link
+ presenter(merge_request).assign_to_closing_issues_path
+ end
+
+ expose :assign_to_closing_count do |merge_request|
+ presenter(merge_request).assign_to_closing_issues_count
end
expose :closing do |merge_request|
diff --git a/app/serializers/pipeline_details_entity.rb b/app/serializers/pipeline_details_entity.rb
index f459e700c03..76797a773b5 100644
--- a/app/serializers/pipeline_details_entity.rb
+++ b/app/serializers/pipeline_details_entity.rb
@@ -10,11 +10,6 @@ class PipelineDetailsEntity < Ci::PipelineEntity
expose :details do
expose :manual_actions, using: BuildActionEntity
expose :scheduled_actions, using: BuildActionEntity
- expose :code_quality_build_path, if: -> (_, options) { options[:code_quality_walkthrough] } do |pipeline|
- next unless code_quality_build = pipeline.builds.finished.find_by_name('code_quality')
-
- project_job_path(pipeline.project, code_quality_build, code_quality_walkthrough: true)
- end
end
expose :triggered_by_pipeline, as: :triggered_by, with: TriggeredPipelineEntity
diff --git a/app/serializers/service_event_entity.rb b/app/serializers/service_event_entity.rb
index a1fbfa1d4c4..49a4944b2b0 100644
--- a/app/serializers/service_event_entity.rb
+++ b/app/serializers/service_event_entity.rb
@@ -4,7 +4,7 @@ class ServiceEventEntity < Grape::Entity
include RequestAwareEntity
expose :title do |event|
- event
+ IntegrationsHelper.integration_event_title(event)
end
expose :event_field_name, as: :name
diff --git a/app/serializers/service_field_entity.rb b/app/serializers/service_field_entity.rb
index aad9db5ffea..b13f2c0e217 100644
--- a/app/serializers/service_field_entity.rb
+++ b/app/serializers/service_field_entity.rb
@@ -4,7 +4,7 @@ class ServiceFieldEntity < Grape::Entity
include RequestAwareEntity
include Gitlab::Utils::StrongMemoize
- expose :type, :name, :placeholder, :required, :choices, :checkbox_label
+ expose :section, :type, :name, :placeholder, :required, :choices, :checkbox_label
expose :title do |field|
non_empty_password?(field) ? field[:non_empty_password_title] : field[:title]
diff --git a/app/services/alert_management/create_alert_issue_service.rb b/app/services/alert_management/create_alert_issue_service.rb
index ab8d1176b9e..34c2003bd01 100644
--- a/app/services/alert_management/create_alert_issue_service.rb
+++ b/app/services/alert_management/create_alert_issue_service.rb
@@ -22,9 +22,7 @@ module AlertManagement
return result unless result.success?
issue = result.payload[:issue]
- update_title_for(issue)
-
- SystemNoteService.new_alert_issue(alert, issue, user)
+ perform_after_create_tasks(issue)
result
end
@@ -56,6 +54,12 @@ module AlertManagement
issue.update!(title: "#{DEFAULT_INCIDENT_TITLE} #{issue.iid}")
end
+ def perform_after_create_tasks(issue)
+ update_title_for(issue)
+
+ SystemNoteService.new_alert_issue(alert, issue, user)
+ end
+
def error(message, issue = nil)
ServiceResponse.error(payload: { issue: issue }, message: message)
end
@@ -75,3 +79,5 @@ module AlertManagement
end
end
end
+
+AlertManagement::CreateAlertIssueService.prepend_mod
diff --git a/app/services/auth/container_registry_authentication_service.rb b/app/services/auth/container_registry_authentication_service.rb
index 84518fd6b0e..bb6a52eb2f4 100644
--- a/app/services/auth/container_registry_authentication_service.rb
+++ b/app/services/auth/container_registry_authentication_service.rb
@@ -59,12 +59,7 @@ module Auth
token.expire_time = token_expire_at
token[:access] = names.map do |name|
- {
- type: type,
- name: name,
- actions: actions,
- migration_eligible: type == 'repository' ? migration_eligible(repository_path: name) : nil
- }.compact
+ { type: type, name: name, actions: actions }
end
token.encoded
@@ -136,12 +131,7 @@ module Auth
#
ensure_container_repository!(path, authorized_actions)
- {
- type: type,
- name: path.to_s,
- actions: authorized_actions,
- migration_eligible: self.class.migration_eligible(project: requested_project)
- }.compact
+ { type: type, name: path.to_s, actions: authorized_actions }
end
def actively_importing?(actions, path)
@@ -153,28 +143,6 @@ module Auth
container_repository.migration_importing?
end
- def self.migration_eligible(project: nil, repository_path: nil)
- return unless Feature.enabled?(:container_registry_migration_phase1)
-
- # project has precedence over repository_path. If only the latter is provided, we find the corresponding Project.
- unless project
- return unless repository_path
-
- project = ContainerRegistry::Path.new(repository_path).repository_project
- end
-
- # The migration process will start by allowing only specific test and gitlab-org projects using the
- # `container_registry_migration_phase1_allow` FF. We'll then move on to a percentage rollout using this same FF.
- # To remove the risk of impacting enterprise customers that rely heavily on the registry during the percentage
- # rollout, we'll add their top-level group/namespace to the `container_registry_migration_phase1_deny` FF. Later,
- # we'll remove them manually from this deny list, and their new repositories will become eligible.
- Feature.disabled?(:container_registry_migration_phase1_deny, project.root_ancestor) &&
- Feature.enabled?(:container_registry_migration_phase1_allow, project)
- rescue ContainerRegistry::Path::InvalidRegistryPathError => ex
- Gitlab::ErrorTracking.track_and_raise_for_dev_exception(ex, **Gitlab::ApplicationContext.current)
- false
- end
-
##
# Because we do not have two way communication with registry yet,
# we create a container repository image resource when push to the
diff --git a/app/services/boards/base_items_list_service.rb b/app/services/boards/base_items_list_service.rb
index a3e24844587..01fad14d036 100644
--- a/app/services/boards/base_items_list_service.rb
+++ b/app/services/boards/base_items_list_service.rb
@@ -12,21 +12,32 @@ module Boards
end
# rubocop: disable CodeReuse/ActiveRecord
- def metadata
- issuables = item_model.arel_table
- keys = metadata_fields.keys
+ def metadata(required_fields = [:issue_count, :total_issue_weight])
+ fields = metadata_fields(required_fields)
+ keys = fields.keys
# TODO: eliminate need for SQL literal fragment
- columns = Arel.sql(metadata_fields.values_at(*keys).join(', '))
- results = item_model.where(id: init_collection.select(issuables[:id])).pluck(columns)
+ columns = Arel.sql(fields.values_at(*keys).join(', '))
+ results = item_model.where(id: collection_ids)
+ results = query_additions(results, required_fields)
+ results = results.select(columns)
- Hash[keys.zip(results.flatten)]
+ Hash[keys.zip(results.pluck(columns).flatten)]
end
# rubocop: enable CodeReuse/ActiveRecord
private
- def metadata_fields
- { size: 'COUNT(*)' }
+ # override if needed
+ def query_additions(items, required_fields)
+ items
+ end
+
+ def collection_ids
+ @collection_ids ||= init_collection.select(item_model.arel_table[:id])
+ end
+
+ def metadata_fields(required_fields)
+ required_fields&.include?(:issue_count) ? { size: 'COUNT(*)' } : {}
end
def order(items)
diff --git a/app/services/bulk_create_integration_service.rb b/app/services/bulk_create_integration_service.rb
index a7fe4c776b7..3a214122ed3 100644
--- a/app/services/bulk_create_integration_service.rb
+++ b/app/services/bulk_create_integration_service.rb
@@ -32,11 +32,7 @@ class BulkCreateIntegrationService
end
def integration_hash
- if integration.template?
- integration.to_integration_hash
- else
- integration.to_integration_hash.tap { |json| json['inherit_from_id'] = integration.inherit_from_id || integration.id }
- end
+ integration.to_integration_hash.tap { |json| json['inherit_from_id'] = integration.inherit_from_id || integration.id }
end
def data_fields_hash
diff --git a/app/services/ci/after_requeue_job_service.rb b/app/services/ci/after_requeue_job_service.rb
index 097b29cf143..bc70dd3bea4 100644
--- a/app/services/ci/after_requeue_job_service.rb
+++ b/app/services/ci/after_requeue_job_service.rb
@@ -22,9 +22,15 @@ module Ci
end
def dependent_jobs
- stage_dependent_jobs
- .or(needs_dependent_jobs.except(:preload))
+ dependent_jobs = stage_dependent_jobs
+ .or(needs_dependent_jobs)
.ordered_by_stage
+
+ if ::Feature.enabled?(:ci_fix_order_of_subsequent_jobs, @processable.pipeline.project, default_enabled: :yaml)
+ dependent_jobs = ordered_by_dag(dependent_jobs)
+ end
+
+ dependent_jobs
end
def process(job)
@@ -44,5 +50,23 @@ module Ci
def skipped_jobs
@skipped_jobs ||= @processable.pipeline.processables.skipped
end
+
+ # rubocop: disable CodeReuse/ActiveRecord
+ def ordered_by_dag(jobs)
+ sorted_job_names = sort_jobs(jobs).each_with_index.to_h
+
+ jobs.preload(:needs).group_by(&:stage_idx).flat_map do |_, stage_jobs|
+ stage_jobs.sort_by { |job| sorted_job_names.fetch(job.name) }
+ end
+ end
+
+ def sort_jobs(jobs)
+ Gitlab::Ci::YamlProcessor::Dag.order(
+ jobs.to_h do |job|
+ [job.name, job.needs.map(&:name)]
+ end
+ )
+ end
+ # rubocop: enable CodeReuse/ActiveRecord
end
end
diff --git a/app/services/ci/create_downstream_pipeline_service.rb b/app/services/ci/create_downstream_pipeline_service.rb
index a2e53cbf9b8..034bab93108 100644
--- a/app/services/ci/create_downstream_pipeline_service.rb
+++ b/app/services/ci/create_downstream_pipeline_service.rb
@@ -120,15 +120,13 @@ module Ci
def has_cyclic_dependency?
return false if @bridge.triggers_child_pipeline?
- if Feature.enabled?(:ci_drop_cyclical_triggered_pipelines, @bridge.project, default_enabled: :yaml)
- pipeline_checksums = @bridge.pipeline.self_and_upstreams.filter_map do |pipeline|
- config_checksum(pipeline) unless pipeline.child?
- end
-
- # To avoid false positives we allow 1 cycle in the ancestry and
- # fail when 2 cycles are detected: A -> B -> A -> B -> A
- pipeline_checksums.tally.any? { |_checksum, occurrences| occurrences > 2 }
+ pipeline_checksums = @bridge.pipeline.self_and_upstreams.filter_map do |pipeline|
+ config_checksum(pipeline) unless pipeline.child?
end
+
+ # To avoid false positives we allow 1 cycle in the ancestry and
+ # fail when 2 cycles are detected: A -> B -> A -> B -> A
+ pipeline_checksums.tally.any? { |_checksum, occurrences| occurrences > 2 }
end
def has_max_descendants_depth?
diff --git a/app/services/ci/destroy_secure_file_service.rb b/app/services/ci/destroy_secure_file_service.rb
new file mode 100644
index 00000000000..7145ace7f31
--- /dev/null
+++ b/app/services/ci/destroy_secure_file_service.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+module Ci
+ class DestroySecureFileService < BaseService
+ def execute(secure_file)
+ raise Gitlab::Access::AccessDeniedError unless can?(current_user, :admin_secure_files, secure_file.project)
+
+ secure_file.destroy!
+ end
+ end
+end
diff --git a/app/services/ci/pipeline_processing/atomic_processing_service/status_collection.rb b/app/services/ci/pipeline_processing/atomic_processing_service/status_collection.rb
index 883a70c9795..4d1b2e07d7f 100644
--- a/app/services/ci/pipeline_processing/atomic_processing_service/status_collection.rb
+++ b/app/services/ci/pipeline_processing/atomic_processing_service/status_collection.rb
@@ -91,17 +91,13 @@ module Ci
def all_statuses_by_id
strong_memoize(:all_statuses_by_id) do
- all_statuses.to_h do |row|
- [row[:id], row]
- end
+ all_statuses.index_by { |row| row[:id] }
end
end
def all_statuses_by_name
strong_memoize(:statuses_by_name) do
- all_statuses.to_h do |row|
- [row[:name], row]
- end
+ all_statuses.index_by { |row| row[:name] }
end
end
diff --git a/app/services/ci/register_runner_service.rb b/app/services/ci/register_runner_service.rb
deleted file mode 100644
index 7c6cd82565d..00000000000
--- a/app/services/ci/register_runner_service.rb
+++ /dev/null
@@ -1,58 +0,0 @@
-# frozen_string_literal: true
-
-module Ci
- class RegisterRunnerService
- def execute(registration_token, attributes)
- runner_type_attrs = extract_runner_type_attrs(registration_token)
-
- return unless runner_type_attrs
-
- ::Ci::Runner.create(attributes.merge(runner_type_attrs))
- end
-
- private
-
- def extract_runner_type_attrs(registration_token)
- @attrs_from_token ||= check_token(registration_token)
-
- return unless @attrs_from_token
-
- attrs = @attrs_from_token.clone
- case attrs[:runner_type]
- when :project_type
- attrs[:projects] = [attrs.delete(:scope)]
- when :group_type
- attrs[:groups] = [attrs.delete(:scope)]
- end
-
- attrs
- end
-
- def check_token(registration_token)
- if runner_registration_token_valid?(registration_token)
- # Create shared runner. Requires admin access
- { runner_type: :instance_type }
- elsif runner_registrar_valid?('project') && project = ::Project.find_by_runners_token(registration_token)
- # Create a specific runner for the project
- { runner_type: :project_type, scope: project }
- elsif runner_registrar_valid?('group') && group = ::Group.find_by_runners_token(registration_token)
- # Create a specific runner for the group
- { runner_type: :group_type, scope: group }
- end
- end
-
- def runner_registration_token_valid?(registration_token)
- ActiveSupport::SecurityUtils.secure_compare(registration_token, Gitlab::CurrentSettings.runners_registration_token)
- end
-
- def runner_registrar_valid?(type)
- Feature.disabled?(:runner_registration_control) || Gitlab::CurrentSettings.valid_runner_registrars.include?(type)
- end
-
- def token_scope
- @attrs_from_token[:scope]
- end
- end
-end
-
-Ci::RegisterRunnerService.prepend_mod
diff --git a/app/services/ci/retry_build_service.rb b/app/services/ci/retry_build_service.rb
index 73c5d0163da..906e5cec4f3 100644
--- a/app/services/ci/retry_build_service.rb
+++ b/app/services/ci/retry_build_service.rb
@@ -65,7 +65,7 @@ module Ci
def check_access!(build)
unless can?(current_user, :update_build, build)
- raise Gitlab::Access::AccessDeniedError
+ raise Gitlab::Access::AccessDeniedError, '403 Forbidden'
end
end
diff --git a/app/services/ci/retry_pipeline_service.rb b/app/services/ci/retry_pipeline_service.rb
index 9ad46ca7585..d40643e1513 100644
--- a/app/services/ci/retry_pipeline_service.rb
+++ b/app/services/ci/retry_pipeline_service.rb
@@ -5,9 +5,8 @@ module Ci
include Gitlab::OptimisticLocking
def execute(pipeline)
- unless can?(current_user, :update_pipeline, pipeline)
- raise Gitlab::Access::AccessDeniedError
- end
+ access_response = check_access(pipeline)
+ return access_response if access_response.error?
pipeline.ensure_scheduling_type!
@@ -30,6 +29,18 @@ module Ci
Ci::ProcessPipelineService
.new(pipeline)
.execute
+
+ ServiceResponse.success
+ rescue Gitlab::Access::AccessDeniedError => e
+ ServiceResponse.error(message: e.message, http_status: :forbidden)
+ end
+
+ def check_access(pipeline)
+ if can?(current_user, :update_pipeline, pipeline)
+ ServiceResponse.success
+ else
+ ServiceResponse.error(message: '403 Forbidden', http_status: :forbidden)
+ end
end
private
diff --git a/app/services/ci/runners/assign_runner_service.rb b/app/services/ci/runners/assign_runner_service.rb
new file mode 100644
index 00000000000..886cd3a4e44
--- /dev/null
+++ b/app/services/ci/runners/assign_runner_service.rb
@@ -0,0 +1,28 @@
+# frozen_string_literal: true
+
+module Ci
+ module Runners
+ class AssignRunnerService
+ # @param [Ci::Runner] runner: the runner to assign to a project
+ # @param [Project] project: the new project to assign the runner to
+ # @param [User] user: the user performing the operation
+ def initialize(runner, project, user)
+ @runner = runner
+ @project = project
+ @user = user
+ end
+
+ def execute
+ return false unless @user.present? && @user.can?(:assign_runner, @runner)
+
+ @runner.assign_to(@project, @user)
+ end
+
+ private
+
+ attr_reader :runner, :project, :user
+ end
+ end
+end
+
+Ci::Runners::AssignRunnerService.prepend_mod
diff --git a/app/services/ci/runners/register_runner_service.rb b/app/services/ci/runners/register_runner_service.rb
new file mode 100644
index 00000000000..7978d094d9b
--- /dev/null
+++ b/app/services/ci/runners/register_runner_service.rb
@@ -0,0 +1,60 @@
+# frozen_string_literal: true
+
+module Ci
+ module Runners
+ class RegisterRunnerService
+ def execute(registration_token, attributes)
+ runner_type_attrs = extract_runner_type_attrs(registration_token)
+
+ return unless runner_type_attrs
+
+ ::Ci::Runner.create(attributes.merge(runner_type_attrs))
+ end
+
+ private
+
+ def extract_runner_type_attrs(registration_token)
+ @attrs_from_token ||= check_token(registration_token)
+
+ return unless @attrs_from_token
+
+ attrs = @attrs_from_token.clone
+ case attrs[:runner_type]
+ when :project_type
+ attrs[:projects] = [attrs.delete(:scope)]
+ when :group_type
+ attrs[:groups] = [attrs.delete(:scope)]
+ end
+
+ attrs
+ end
+
+ def check_token(registration_token)
+ if runner_registration_token_valid?(registration_token)
+ # Create shared runner. Requires admin access
+ { runner_type: :instance_type }
+ elsif runner_registrar_valid?('project') && project = ::Project.find_by_runners_token(registration_token)
+ # Create a specific runner for the project
+ { runner_type: :project_type, scope: project }
+ elsif runner_registrar_valid?('group') && group = ::Group.find_by_runners_token(registration_token)
+ # Create a specific runner for the group
+ { runner_type: :group_type, scope: group }
+ end
+ end
+
+ def runner_registration_token_valid?(registration_token)
+ ActiveSupport::SecurityUtils.secure_compare(registration_token, Gitlab::CurrentSettings.runners_registration_token)
+ end
+
+ def runner_registrar_valid?(type)
+ Feature.disabled?(:runner_registration_control, default_enabled: :yaml) || Gitlab::CurrentSettings.valid_runner_registrars.include?(type)
+ end
+
+ def token_scope
+ @attrs_from_token[:scope]
+ end
+ end
+ end
+end
+
+Ci::Runners::RegisterRunnerService.prepend_mod
diff --git a/app/services/ci/runners/reset_registration_token_service.rb b/app/services/ci/runners/reset_registration_token_service.rb
new file mode 100644
index 00000000000..bbe49c04644
--- /dev/null
+++ b/app/services/ci/runners/reset_registration_token_service.rb
@@ -0,0 +1,31 @@
+# frozen_string_literal: true
+
+module Ci
+ module Runners
+ class ResetRegistrationTokenService
+ # @param [ApplicationSetting, Project, Group] scope: the scope of the reset operation
+ # @param [User] user: the user performing the operation
+ def initialize(scope, user)
+ @scope = scope
+ @user = user
+ end
+
+ def execute
+ return unless @user.present? && @user.can?(:update_runners_registration_token, scope)
+
+ case scope
+ when ::ApplicationSetting
+ scope.reset_runners_registration_token!
+ ApplicationSetting.current_without_cache.runners_registration_token
+ when ::Group, ::Project
+ scope.reset_runners_token!
+ scope.runners_token
+ end
+ end
+
+ private
+
+ attr_reader :scope, :user
+ end
+ end
+end
diff --git a/app/services/ci/runners/unassign_runner_service.rb b/app/services/ci/runners/unassign_runner_service.rb
new file mode 100644
index 00000000000..1e46cf6add8
--- /dev/null
+++ b/app/services/ci/runners/unassign_runner_service.rb
@@ -0,0 +1,28 @@
+# frozen_string_literal: true
+
+module Ci
+ module Runners
+ class UnassignRunnerService
+ # @param [Ci::RunnerProject] runner_project the runner/project association to destroy
+ # @param [User] user the user performing the operation
+ def initialize(runner_project, user)
+ @runner_project = runner_project
+ @runner = runner_project.runner
+ @project = runner_project.project
+ @user = user
+ end
+
+ def execute
+ return false unless @user.present? && @user.can?(:assign_runner, @runner)
+
+ @runner_project.destroy
+ end
+
+ private
+
+ attr_reader :runner, :project, :user
+ end
+ end
+end
+
+Ci::Runners::UnassignRunnerService.prepend_mod
diff --git a/app/services/ci/runners/unregister_runner_service.rb b/app/services/ci/runners/unregister_runner_service.rb
new file mode 100644
index 00000000000..4ee1e73c458
--- /dev/null
+++ b/app/services/ci/runners/unregister_runner_service.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+module Ci
+ module Runners
+ class UnregisterRunnerService
+ attr_reader :runner, :author
+
+ # @param [Ci::Runner] runner the runner to unregister/destroy
+ # @param [User, authentication token String] author the user or the authentication token that authorizes the removal
+ def initialize(runner, author)
+ @runner = runner
+ @author = author
+ end
+
+ def execute
+ @runner&.destroy
+ end
+ end
+ end
+end
+
+Ci::Runners::UnregisterRunnerService.prepend_mod
diff --git a/app/services/ci/runners/update_runner_service.rb b/app/services/ci/runners/update_runner_service.rb
new file mode 100644
index 00000000000..6cc080f81c2
--- /dev/null
+++ b/app/services/ci/runners/update_runner_service.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+module Ci
+ module Runners
+ class UpdateRunnerService
+ attr_reader :runner
+
+ def initialize(runner)
+ @runner = runner
+ end
+
+ def update(params)
+ params[:active] = !params.delete(:paused) if params.include?(:paused)
+
+ runner.update(params).tap do |updated|
+ runner.tick_runner_queue if updated
+ end
+ end
+ end
+ end
+end
diff --git a/app/services/ci/test_failure_history_service.rb b/app/services/ci/test_failure_history_service.rb
index a3f45c1b9cd..7323ad417ea 100644
--- a/app/services/ci/test_failure_history_service.rb
+++ b/app/services/ci/test_failure_history_service.rb
@@ -17,6 +17,7 @@ module Ci
MAX_TRACKABLE_FAILURES = 200
attr_reader :pipeline
+
delegate :project, to: :pipeline
def initialize(pipeline)
diff --git a/app/services/ci/unregister_runner_service.rb b/app/services/ci/unregister_runner_service.rb
deleted file mode 100644
index 97d9852b7ed..00000000000
--- a/app/services/ci/unregister_runner_service.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-# frozen_string_literal: true
-
-module Ci
- class UnregisterRunnerService
- attr_reader :runner
-
- # @param [Ci::Runner] runner the runner to unregister/destroy
- def initialize(runner)
- @runner = runner
- end
-
- def execute
- @runner&.destroy
- end
- end
-end
diff --git a/app/services/ci/update_runner_service.rb b/app/services/ci/update_runner_service.rb
deleted file mode 100644
index 4a17e25c0cc..00000000000
--- a/app/services/ci/update_runner_service.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-# frozen_string_literal: true
-
-module Ci
- class UpdateRunnerService
- attr_reader :runner
-
- def initialize(runner)
- @runner = runner
- end
-
- def update(params)
- params[:active] = !params.delete(:paused) if params.include?(:paused)
-
- runner.update(params).tap do |updated|
- runner.tick_runner_queue if updated
- end
- end
- end
-end
diff --git a/app/services/concerns/members/bulk_create_users.rb b/app/services/concerns/members/bulk_create_users.rb
index 9cfef96311e..3f8971dde74 100644
--- a/app/services/concerns/members/bulk_create_users.rb
+++ b/app/services/concerns/members/bulk_create_users.rb
@@ -47,16 +47,15 @@ module Members
end
end
- if user_ids.present?
- # we should handle the idea of existing members where users are passed as users - https://gitlab.com/gitlab-org/gitlab/-/issues/352617
- # the below will automatically discard invalid user_ids
- users.concat(User.id_in(user_ids))
+ # the below will automatically discard invalid user_ids
+ users.concat(User.id_in(user_ids)) if user_ids.present?
+ users.uniq! # de-duplicate just in case as there is no controlling if user records and ids are sent multiple times
+
+ if users.present?
# helps not have to perform another query per user id to see if the member exists later on when fetching
- existing_members = source.members_and_requesters.where(user_id: user_ids).index_by(&:user_id) # rubocop:disable CodeReuse/ActiveRecord
+ existing_members = source.members_and_requesters.where(user_id: users).index_by(&:user_id) # rubocop:disable CodeReuse/ActiveRecord
end
- users.uniq! # de-duplicate just in case as there is no controlling if user records and ids are sent multiple times
-
[emails, users, existing_members]
end
end
diff --git a/app/services/concerns/rate_limited_service.rb b/app/services/concerns/rate_limited_service.rb
index c8dc60355cf..5d7247a5b99 100644
--- a/app/services/concerns/rate_limited_service.rb
+++ b/app/services/concerns/rate_limited_service.rb
@@ -36,7 +36,6 @@ module RateLimitedService
def rate_limit!(service)
evaluated_scope = evaluated_scope_for(service)
- return if feature_flag_disabled?(evaluated_scope[:project])
if rate_limiter.throttled?(key, **opts.merge(scope: evaluated_scope.values, users_allowlist: users_allowlist))
raise RateLimitedError.new(key: key, rate_limiter: rate_limiter), _('This endpoint has been requested too many times. Try again later.')
@@ -54,14 +53,11 @@ module RateLimitedService
all[var] = service.public_send(var) # rubocop: disable GitlabSecurity/PublicSend
end
end
-
- def feature_flag_disabled?(project)
- Feature.disabled?("rate_limited_service_#{key}", project, default_enabled: :yaml)
- end
end
prepended do
attr_accessor :rate_limiter_bypassed
+
cattr_accessor :rate_limiter_scoped_and_keyed
def self.rate_limit(key:, opts:, rate_limiter: ::Gitlab::ApplicationRateLimiter)
diff --git a/app/services/concerns/update_repository_storage_methods.rb b/app/services/concerns/update_repository_storage_methods.rb
index cbcd0b7f56b..b21d05f4178 100644
--- a/app/services/concerns/update_repository_storage_methods.rb
+++ b/app/services/concerns/update_repository_storage_methods.rb
@@ -6,6 +6,7 @@ module UpdateRepositoryStorageMethods
Error = Class.new(StandardError)
attr_reader :repository_storage_move
+
delegate :container, :source_storage_name, :destination_storage_name, to: :repository_storage_move
def initialize(repository_storage_move)
diff --git a/app/services/error_tracking/base_service.rb b/app/services/error_tracking/base_service.rb
index 289c125b9d1..598621f70e1 100644
--- a/app/services/error_tracking/base_service.rb
+++ b/app/services/error_tracking/base_service.rb
@@ -1,7 +1,13 @@
# frozen_string_literal: true
module ErrorTracking
- class BaseService < ::BaseService
+ class BaseService < ::BaseProjectService
+ include Gitlab::Utils::UsageData
+
+ def initialize(project, user = nil, params = {})
+ super(project: project, current_user: user, params: params.dup)
+ end
+
def execute
return unauthorized if unauthorized
@@ -21,6 +27,8 @@ module ErrorTracking
yield if block_given?
+ track_usage_event(params[:tracking_event], current_user.id) if params[:tracking_event]
+
success(parse_response(response))
end
diff --git a/app/services/error_tracking/collect_error_service.rb b/app/services/error_tracking/collect_error_service.rb
index 50508c9810a..6376b743255 100644
--- a/app/services/error_tracking/collect_error_service.rb
+++ b/app/services/error_tracking/collect_error_service.rb
@@ -60,7 +60,7 @@ module ErrorTracking
end
def actor
- return event['transaction'] if event['transaction']
+ return event['transaction'] if event['transaction'].present?
# Some SDKs do not have a transaction attribute.
# So we build it by combining function name and module name from
diff --git a/app/services/google_cloud/create_service_accounts_service.rb b/app/services/google_cloud/create_service_accounts_service.rb
index e360b3a8e4e..51d08cc5b55 100644
--- a/app/services/google_cloud/create_service_accounts_service.rb
+++ b/app/services/google_cloud/create_service_accounts_service.rb
@@ -12,7 +12,7 @@ module GoogleCloud
service_account.project_id,
service_account.to_json,
service_account_key.to_json,
- environment_protected?
+ ProtectedBranch.protected?(project, environment_name) || ProtectedTag.protected?(project, environment_name)
)
ServiceResponse.success(message: _('Service account generated successfully'), payload: {
@@ -50,11 +50,6 @@ module GoogleCloud
def service_account_desc
"GitLab generated service account for project '#{project.name}' and environment '#{environment_name}'"
end
-
- # Overridden in EE
- def environment_protected?
- false
- end
end
end
diff --git a/app/services/google_cloud/gcp_region_add_or_replace_service.rb b/app/services/google_cloud/gcp_region_add_or_replace_service.rb
new file mode 100644
index 00000000000..467f818bcc7
--- /dev/null
+++ b/app/services/google_cloud/gcp_region_add_or_replace_service.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+module GoogleCloud
+ class GcpRegionAddOrReplaceService < ::BaseService
+ def execute(environment, region)
+ gcp_region_key = Projects::GoogleCloudController::GCP_REGION_CI_VAR_KEY
+
+ change_params = { variable_params: { key: gcp_region_key, value: region, environment_scope: environment } }
+ filter_params = { key: gcp_region_key, filter: { environment_scope: environment } }
+
+ existing_variable = ::Ci::VariablesFinder.new(project, filter_params).execute.first
+
+ if existing_variable
+ change_params[:action] = :update
+ change_params[:variable] = existing_variable
+ else
+ change_params[:action] = :create
+ end
+
+ ::Ci::ChangeVariableService.new(container: project, current_user: current_user, params: change_params).execute
+ end
+ end
+end
diff --git a/app/services/google_cloud/service_accounts_service.rb b/app/services/google_cloud/service_accounts_service.rb
index 3014daf08e2..b791f07cd65 100644
--- a/app/services/google_cloud/service_accounts_service.rb
+++ b/app/services/google_cloud/service_accounts_service.rb
@@ -14,12 +14,12 @@ module GoogleCloud
#
# This method looks up GitLab project's CI vars
# and returns Google Cloud Service Accounts combinations
- # aligning GitLab project and environment to GCP projects
+ # aligning GitLab project and ref to GCP projects
def find_for_project
- group_vars_by_environment.map do |environment_scope, value|
+ group_vars_by_ref.map do |environment_scope, value|
{
- environment: environment_scope,
+ ref: environment_scope,
gcp_project: value['GCP_PROJECT_ID'],
service_account_exists: value['GCP_SERVICE_ACCOUNT'].present?,
service_account_key_exists: value['GCP_SERVICE_ACCOUNT_KEY'].present?
@@ -27,21 +27,21 @@ module GoogleCloud
end
end
- def add_for_project(environment, gcp_project_id, service_account, service_account_key, is_protected)
+ def add_for_project(ref, gcp_project_id, service_account, service_account_key, is_protected)
project_var_create_or_replace(
- environment,
+ ref,
'GCP_PROJECT_ID',
gcp_project_id,
is_protected
)
project_var_create_or_replace(
- environment,
+ ref,
'GCP_SERVICE_ACCOUNT',
service_account,
is_protected
)
project_var_create_or_replace(
- environment,
+ ref,
'GCP_SERVICE_ACCOUNT_KEY',
service_account_key,
is_protected
@@ -50,7 +50,7 @@ module GoogleCloud
private
- def group_vars_by_environment
+ def group_vars_by_ref
filtered_vars = project.variables.filter { |variable| GCP_KEYS.include? variable.key }
filtered_vars.each_with_object({}) do |variable, grouped|
grouped[variable.environment_scope] ||= {}
@@ -59,10 +59,19 @@ module GoogleCloud
end
def project_var_create_or_replace(environment_scope, key, value, is_protected)
- params = { key: key, filter: { environment_scope: environment_scope } }
- existing_variable = ::Ci::VariablesFinder.new(project, params).execute.first
- existing_variable.destroy if existing_variable
- project.variables.create!(key: key, value: value, environment_scope: environment_scope, protected: is_protected)
+ change_params = { variable_params: { key: key, value: value, environment_scope: environment_scope, protected: is_protected } }
+ filter_params = { key: key, filter: { environment_scope: environment_scope } }
+
+ existing_variable = ::Ci::VariablesFinder.new(project, filter_params).execute.first
+
+ if existing_variable
+ change_params[:action] = :update
+ change_params[:variable] = existing_variable
+ else
+ change_params[:action] = :create
+ end
+
+ ::Ci::ChangeVariableService.new(container: project, current_user: current_user, params: change_params).execute
end
end
end
diff --git a/app/services/groups/deploy_tokens/create_service.rb b/app/services/groups/deploy_tokens/create_service.rb
index aee423659ef..4b0541e78a1 100644
--- a/app/services/groups/deploy_tokens/create_service.rb
+++ b/app/services/groups/deploy_tokens/create_service.rb
@@ -13,3 +13,5 @@ module Groups
end
end
end
+
+Groups::DeployTokens::CreateService.prepend_mod
diff --git a/app/services/groups/deploy_tokens/destroy_service.rb b/app/services/groups/deploy_tokens/destroy_service.rb
index 6dae22f29d2..4745d00ed7f 100644
--- a/app/services/groups/deploy_tokens/destroy_service.rb
+++ b/app/services/groups/deploy_tokens/destroy_service.rb
@@ -11,3 +11,5 @@ module Groups
end
end
end
+
+Groups::DeployTokens::DestroyService.prepend_mod
diff --git a/app/services/groups/deploy_tokens/revoke_service.rb b/app/services/groups/deploy_tokens/revoke_service.rb
new file mode 100644
index 00000000000..cf91d3b27fa
--- /dev/null
+++ b/app/services/groups/deploy_tokens/revoke_service.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+module Groups
+ module DeployTokens
+ class RevokeService < BaseService
+ attr_accessor :token
+
+ def execute
+ @token = group.deploy_tokens.find(params[:id])
+ @token.revoke!
+ end
+ end
+ end
+end
+
+Groups::DeployTokens::RevokeService.prepend_mod
diff --git a/app/services/groups/destroy_service.rb b/app/services/groups/destroy_service.rb
index 5ffa746e109..c88c139a22e 100644
--- a/app/services/groups/destroy_service.rb
+++ b/app/services/groups/destroy_service.rb
@@ -11,11 +11,15 @@ module Groups
# rubocop: disable CodeReuse/ActiveRecord
def execute
+ # TODO - add a policy check here https://gitlab.com/gitlab-org/gitlab/-/issues/353082
+ raise DestroyError, "You can't delete this group because you're blocked." if current_user.blocked?
+
group.prepare_for_destroy
group.projects.includes(:project_feature).each do |project|
# Execute the destruction of the models immediately to ensure atomic cleanup.
success = ::Projects::DestroyService.new(project, current_user).execute
+
raise DestroyError, "Project #{project.id} can't be deleted" unless success
end
diff --git a/app/services/import/gitlab_projects/create_project_from_remote_file_service.rb b/app/services/import/gitlab_projects/create_project_from_remote_file_service.rb
deleted file mode 100644
index edb9dc8ad91..00000000000
--- a/app/services/import/gitlab_projects/create_project_from_remote_file_service.rb
+++ /dev/null
@@ -1,91 +0,0 @@
-# frozen_string_literal: true
-
-module Import
- module GitlabProjects
- class CreateProjectFromRemoteFileService < CreateProjectFromUploadedFileService
- FILE_SIZE_LIMIT = 10.gigabytes
- ALLOWED_CONTENT_TYPES = [
- 'application/gzip', # most common content-type when fetching a tar.gz
- 'application/x-tar' # aws-s3 uses x-tar for tar.gz files
- ].freeze
-
- validate :valid_remote_import_url?
- validate :validate_file_size
- validate :validate_content_type
-
- private
-
- def required_params
- [:path, :namespace, :remote_import_url]
- end
-
- def project_params
- super
- .except(:file)
- .merge(import_export_upload: ::ImportExportUpload.new(
- remote_import_url: params[:remote_import_url]
- ))
- end
-
- def valid_remote_import_url?
- ::Gitlab::UrlBlocker.validate!(
- params[:remote_import_url],
- allow_localhost: allow_local_requests?,
- allow_local_network: allow_local_requests?,
- schemes: %w(http https)
- )
-
- true
- rescue ::Gitlab::UrlBlocker::BlockedUrlError => e
- errors.add(:base, e.message)
-
- false
- end
-
- def allow_local_requests?
- ::Gitlab::CurrentSettings.allow_local_requests_from_web_hooks_and_services?
- end
-
- def validate_content_type
- # AWS-S3 presigned URLs don't respond to HTTP HEAD requests,
- # so file type cannot be validated
- # https://gitlab.com/gitlab-org/gitlab/-/merge_requests/75170#note_748059103
- return if amazon_s3?
-
- if headers['content-type'].blank?
- errors.add(:base, "Missing 'ContentType' header")
- elsif !ALLOWED_CONTENT_TYPES.include?(headers['content-type'])
- errors.add(:base, "Remote file content type '%{content_type}' not allowed. (Allowed content types: %{allowed})" % {
- content_type: headers['content-type'],
- allowed: ALLOWED_CONTENT_TYPES.join(', ')
- })
- end
- end
-
- def validate_file_size
- # AWS-S3 presigned URLs don't respond to HTTP HEAD requests,
- # so file size cannot be validated
- # https://gitlab.com/gitlab-org/gitlab/-/merge_requests/75170#note_748059103
- return if amazon_s3?
-
- if headers['content-length'].to_i == 0
- errors.add(:base, "Missing 'ContentLength' header")
- elsif headers['content-length'].to_i > FILE_SIZE_LIMIT
- errors.add(:base, 'Remote file larger than limit. (limit %{limit})' % {
- limit: ActiveSupport::NumberHelper.number_to_human_size(FILE_SIZE_LIMIT)
- })
- end
- end
-
- def amazon_s3?
- headers['Server'] == 'AmazonS3' && headers['x-amz-request-id'].present?
- end
-
- def headers
- return {} if params[:remote_import_url].blank? || !valid_remote_import_url?
-
- @headers ||= Gitlab::HTTP.head(params[:remote_import_url]).headers
- end
- end
- end
-end
diff --git a/app/services/import/gitlab_projects/create_project_from_uploaded_file_service.rb b/app/services/import/gitlab_projects/create_project_from_uploaded_file_service.rb
deleted file mode 100644
index 35d52a11288..00000000000
--- a/app/services/import/gitlab_projects/create_project_from_uploaded_file_service.rb
+++ /dev/null
@@ -1,65 +0,0 @@
-# frozen_string_literal: true
-
-module Import
- module GitlabProjects
- class CreateProjectFromUploadedFileService
- include ActiveModel::Validations
- include ::Services::ReturnServiceResponses
-
- validate :required_params_presence
-
- def initialize(current_user, params = {})
- @current_user = current_user
- @params = params.dup
- end
-
- def execute
- return error(errors.full_messages.first) unless valid?
- return error(project.errors.full_messages&.first) unless project.saved?
-
- success(project)
- rescue StandardError => e
- error(e.message)
- end
-
- private
-
- attr_reader :current_user, :params
-
- def error(message)
- super(message, :bad_request)
- end
-
- def project
- @project ||= ::Projects::GitlabProjectsImportService.new(
- current_user,
- project_params,
- params[:override]
- ).execute
- end
-
- def project_params
- {
- name: params[:name],
- path: params[:path],
- namespace_id: params[:namespace].id,
- file: params[:file],
- overwrite: params[:overwrite],
- import_type: 'gitlab_project'
- }
- end
-
- def required_params
- [:path, :namespace, :file]
- end
-
- def required_params_presence
- required_params
- .select { |key| params[key].blank? }
- .each do |missing_parameter|
- errors.add(:base, "Parameter '#{missing_parameter}' is required")
- end
- end
- end
- end
-end
diff --git a/app/services/import/gitlab_projects/create_project_service.rb b/app/services/import/gitlab_projects/create_project_service.rb
new file mode 100644
index 00000000000..1613c4dde25
--- /dev/null
+++ b/app/services/import/gitlab_projects/create_project_service.rb
@@ -0,0 +1,81 @@
+# frozen_string_literal: true
+
+# Creates a new project with an associated project export file to be imported
+# The associated project export file might be associated with different strategies
+# to acquire the file to be imported, the default file_acquisition_strategy
+# is uploading a file (Import::GitlabProjects::FileAcquisitionStrategies::FileUpload)
+module Import
+ module GitlabProjects
+ class CreateProjectService
+ include ActiveModel::Validations
+ include ::Services::ReturnServiceResponses
+
+ validates_presence_of :path, :namespace
+
+ # Creates a new CreateProjectService.
+ #
+ # @param [User] current_user
+ # @param [Hash] :params
+ # @param [Import::GitlabProjects::FileAcquisitionStrategies::*] :file_acquisition_strategy
+ def initialize(current_user, params:, file_acquisition_strategy: FileAcquisitionStrategies::FileUpload)
+ @current_user = current_user
+ @params = params.dup
+ @strategy = file_acquisition_strategy.new(current_user: current_user, params: params)
+ end
+
+ # Creates a project with the strategy parameters
+ #
+ # @return [Services::ServiceReponse]
+ def execute
+ return error(errors.full_messages) unless valid?
+ return error(project.errors.full_messages) unless project.saved?
+
+ success(project)
+ rescue StandardError => e
+ error(e.message)
+ end
+
+ # Cascade the validation to strategy
+ def valid?
+ super && strategy.valid?
+ end
+
+ # Merge with strategy's errors
+ def errors
+ super.tap { _1.merge!(strategy.errors) }
+ end
+
+ def read_attribute_for_validation(key)
+ params[key]
+ end
+
+ private
+
+ attr_reader :current_user, :params, :strategy
+
+ def error(messages)
+ messages = Array.wrap(messages)
+ message = messages.shift
+ super(message, :bad_request, pass_back: { other_errors: messages })
+ end
+
+ def project
+ @project ||= ::Projects::GitlabProjectsImportService.new(
+ current_user,
+ project_params,
+ params[:override]
+ ).execute
+ end
+
+ def project_params
+ {
+ name: params[:name],
+ path: params[:path],
+ namespace_id: params[:namespace].id,
+ overwrite: params[:overwrite],
+ import_type: 'gitlab_project'
+ }.merge(strategy.project_params)
+ end
+ end
+ end
+end
diff --git a/app/services/import/gitlab_projects/file_acquisition_strategies/file_upload.rb b/app/services/import/gitlab_projects/file_acquisition_strategies/file_upload.rb
new file mode 100644
index 00000000000..8bee3067d6c
--- /dev/null
+++ b/app/services/import/gitlab_projects/file_acquisition_strategies/file_upload.rb
@@ -0,0 +1,33 @@
+# frozen_string_literal: true
+
+module Import
+ module GitlabProjects
+ module FileAcquisitionStrategies
+ class FileUpload
+ include ActiveModel::Validations
+
+ validate :uploaded_file
+
+ def initialize(current_user: nil, params:)
+ @params = params
+ end
+
+ def project_params
+ @project_params ||= @params.slice(:file)
+ end
+
+ def file
+ @file ||= @params[:file]
+ end
+
+ private
+
+ def uploaded_file
+ return if file.present? && file.is_a?(UploadedFile)
+
+ errors.add(:file, 'must be uploaded')
+ end
+ end
+ end
+ end
+end
diff --git a/app/services/import/gitlab_projects/file_acquisition_strategies/remote_file.rb b/app/services/import/gitlab_projects/file_acquisition_strategies/remote_file.rb
new file mode 100644
index 00000000000..ae9a450660c
--- /dev/null
+++ b/app/services/import/gitlab_projects/file_acquisition_strategies/remote_file.rb
@@ -0,0 +1,76 @@
+# frozen_string_literal: true
+
+module Import
+ module GitlabProjects
+ module FileAcquisitionStrategies
+ class RemoteFile
+ include ActiveModel::Validations
+
+ def self.allow_local_requests?
+ ::Gitlab::CurrentSettings.allow_local_requests_from_web_hooks_and_services?
+ end
+
+ validates :file_url, addressable_url: {
+ schemes: %w(https),
+ allow_localhost: allow_local_requests?,
+ allow_local_network: allow_local_requests?,
+ dns_rebind_protection: true
+ }
+ validate :aws_s3, if: :validate_aws_s3?
+ # When removing the import_project_from_remote_file_s3 remove the
+ # whole condition of this validation:
+ validates_with RemoteFileValidator, if: -> { validate_aws_s3? || !s3_request? }
+
+ def initialize(current_user: nil, params:)
+ @params = params
+ end
+
+ def project_params
+ @project_parms ||= {
+ import_export_upload: ::ImportExportUpload.new(remote_import_url: file_url)
+ }
+ end
+
+ def file_url
+ @file_url ||= params[:remote_import_url]
+ end
+
+ def content_type
+ @content_type ||= headers['content-type']
+ end
+
+ def content_length
+ @content_length ||= headers['content-length'].to_i
+ end
+
+ private
+
+ attr_reader :params
+
+ def aws_s3
+ if s3_request?
+ errors.add(:base, 'To import from AWS S3 use `projects/remote-import-s3`')
+ end
+ end
+
+ def s3_request?
+ headers['Server'] == 'AmazonS3' && headers['x-amz-request-id'].present?
+ end
+
+ def validate_aws_s3?
+ ::Feature.enabled?(:import_project_from_remote_file_s3, default_enabled: :yaml)
+ end
+
+ def headers
+ return {} if file_url.blank?
+
+ @headers ||= Gitlab::HTTP.head(file_url, timeout: 1.second).headers
+ rescue StandardError => e
+ errors.add(:base, "Failed to retrive headers: #{e.message}")
+
+ {}
+ end
+ end
+ end
+ end
+end
diff --git a/app/services/import/gitlab_projects/file_acquisition_strategies/remote_file_s3.rb b/app/services/import/gitlab_projects/file_acquisition_strategies/remote_file_s3.rb
new file mode 100644
index 00000000000..5cbca53582d
--- /dev/null
+++ b/app/services/import/gitlab_projects/file_acquisition_strategies/remote_file_s3.rb
@@ -0,0 +1,93 @@
+# frozen_string_literal: true
+
+module Import
+ module GitlabProjects
+ module FileAcquisitionStrategies
+ class RemoteFileS3
+ include ActiveModel::Validations
+ include Gitlab::Utils::StrongMemoize
+
+ def self.allow_local_requests?
+ ::Gitlab::CurrentSettings.allow_local_requests_from_web_hooks_and_services?
+ end
+
+ validates_presence_of :region, :bucket_name, :file_key, :access_key_id, :secret_access_key
+ validates :file_url, addressable_url: {
+ schemes: %w(https),
+ allow_localhost: allow_local_requests?,
+ allow_local_network: allow_local_requests?,
+ dns_rebind_protection: true
+ }
+
+ validates_with RemoteFileValidator
+
+ # The import itself has a limit of 24h, since the URL is created before the import starts
+ # we add an expiration a bit longer to ensure it won't expire during the import.
+ URL_EXPIRATION = 28.hours.seconds
+
+ def initialize(current_user: nil, params:)
+ @params = params
+ end
+
+ def project_params
+ @project_parms ||= {
+ import_export_upload: ::ImportExportUpload.new(remote_import_url: file_url)
+ }
+ end
+
+ def file_url
+ @file_url ||= s3_object&.presigned_url(:get, expires_in: URL_EXPIRATION.to_i)
+ end
+
+ def content_type
+ @content_type ||= s3_object&.content_type
+ end
+
+ def content_length
+ @content_length ||= s3_object&.content_length.to_i
+ end
+
+ # Make the validated params/methods accessible
+ def read_attribute_for_validation(key)
+ return file_url if key == :file_url
+
+ params[key]
+ end
+
+ private
+
+ attr_reader :params
+
+ def s3_object
+ strong_memoize(:s3_object) do
+ build_s3_options
+ end
+ end
+
+ def build_s3_options
+ object = Aws::S3::Object.new(
+ params[:bucket_name],
+ params[:file_key],
+ client: Aws::S3::Client.new(
+ region: params[:region],
+ access_key_id: params[:access_key_id],
+ secret_access_key: params[:secret_access_key]
+ )
+ )
+
+ # Force validate if the object exists and is accessible
+ # Some exceptions are only raised when trying to access the object data
+ unless object.exists?
+ errors.add(:base, "File not found '#{params[:file_key]}' in '#{params[:bucket_name]}'")
+ return
+ end
+
+ object
+ rescue StandardError => e
+ errors.add(:base, "Failed to open '#{params[:file_key]}' in '#{params[:bucket_name]}': #{e.message}")
+ nil
+ end
+ end
+ end
+ end
+end
diff --git a/app/services/incident_management/pager_duty/process_webhook_service.rb b/app/services/incident_management/pager_duty/process_webhook_service.rb
index ccbca671b37..a49e639ea62 100644
--- a/app/services/incident_management/pager_duty/process_webhook_service.rb
+++ b/app/services/incident_management/pager_duty/process_webhook_service.rb
@@ -2,7 +2,7 @@
module IncidentManagement
module PagerDuty
- class ProcessWebhookService
+ class ProcessWebhookService < ::BaseProjectService
include Gitlab::Utils::StrongMemoize
include IncidentManagement::Settings
@@ -13,7 +13,8 @@ module IncidentManagement
PAGER_DUTY_PROCESSABLE_EVENT_TYPES = %w(incident.trigger).freeze
def initialize(project, payload)
- @project = project
+ super(project: project)
+
@payload = payload
end
@@ -29,7 +30,7 @@ module IncidentManagement
private
- attr_reader :project, :payload
+ attr_reader :payload
def process_incidents
pager_duty_processable_events.each do |event|
diff --git a/app/services/integrations/propagate_template_service.rb b/app/services/integrations/propagate_template_service.rb
deleted file mode 100644
index 85a82ba4c8e..00000000000
--- a/app/services/integrations/propagate_template_service.rb
+++ /dev/null
@@ -1,10 +0,0 @@
-# frozen_string_literal: true
-
-module Integrations
- # TODO: Remove this as part of https://gitlab.com/gitlab-org/gitlab/-/issues/335178
- class PropagateTemplateService
- def self.propagate(_integration)
- # no-op
- end
- end
-end
diff --git a/app/services/issuable_base_service.rb b/app/services/issuable_base_service.rb
index 95093b88155..a63c54df4a6 100644
--- a/app/services/issuable_base_service.rb
+++ b/app/services/issuable_base_service.rb
@@ -160,7 +160,7 @@ class IssuableBaseService < ::BaseProjectService
params.delete(:escalation_status)
).execute
- return unless result.success? && result.payload.present?
+ return unless result.success? && result[:escalation_status].present?
@escalation_status_change_reason = result[:escalation_status].delete(:status_change_reason)
@@ -486,7 +486,10 @@ class IssuableBaseService < ::BaseProjectService
associations[:description] = issuable.description
associations[:reviewers] = issuable.reviewers.to_a if issuable.allows_reviewers?
associations[:severity] = issuable.severity if issuable.supports_severity?
- associations[:escalation_status] = issuable.escalation_status&.slice(:status, :policy_id) if issuable.supports_escalation?
+
+ if issuable.supports_escalation? && issuable.escalation_status
+ associations[:escalation_status] = issuable.escalation_status.status_name
+ end
associations
end
diff --git a/app/services/issuable_links/create_service.rb b/app/services/issuable_links/create_service.rb
index 81685f81afa..802260c8fae 100644
--- a/app/services/issuable_links/create_service.rb
+++ b/app/services/issuable_links/create_service.rb
@@ -17,7 +17,7 @@ module IssuableLinks
# otherwise create issue links for the issues which
# are still not assigned and return success message.
if render_conflict_error?
- return error(issuables_assigned_message, 409)
+ return error(issuables_already_assigned_message, 409)
end
if render_not_found_error?
@@ -36,6 +36,20 @@ module IssuableLinks
success
end
+ # rubocop: disable CodeReuse/ActiveRecord
+ def relate_issuables(referenced_issuable)
+ link = link_class.find_or_initialize_by(source: issuable, target: referenced_issuable)
+
+ set_link_type(link)
+
+ if link.changed? && link.save
+ create_notes(referenced_issuable)
+ end
+
+ link
+ end
+ # rubocop: enable CodeReuse/ActiveRecord
+
private
def render_conflict_error?
@@ -96,6 +110,23 @@ module IssuableLinks
{}
end
+ def issuables_already_assigned_message
+ _('%{issuable}(s) already assigned' % { issuable: target_issuable_type.capitalize })
+ end
+
+ def issuables_not_found_message
+ _('No matching %{issuable} found. Make sure that you are adding a valid %{issuable} URL.' % { issuable: target_issuable_type })
+ end
+
+ def target_issuable_type
+ :issue
+ end
+
+ def create_notes(referenced_issuable)
+ SystemNoteService.relate_issuable(issuable, referenced_issuable, current_user)
+ SystemNoteService.relate_issuable(referenced_issuable, issuable, current_user)
+ end
+
def linkable_issuables(objects)
raise NotImplementedError
end
@@ -104,16 +135,12 @@ module IssuableLinks
raise NotImplementedError
end
- def relate_issuables(referenced_object)
+ def link_class
raise NotImplementedError
end
- def issuables_assigned_message
- _("Issue(s) already assigned")
- end
-
- def issuables_not_found_message
- _("No matching issue found. Make sure that you are adding a valid issue URL.")
+ def set_link_type(_link)
+ # no-op
end
end
end
diff --git a/app/services/issuable_links/destroy_service.rb b/app/services/issuable_links/destroy_service.rb
index 28035bbb291..19edd008b0a 100644
--- a/app/services/issuable_links/destroy_service.rb
+++ b/app/services/issuable_links/destroy_service.rb
@@ -4,11 +4,13 @@ module IssuableLinks
class DestroyService < BaseService
include IncidentManagement::UsageData
- attr_reader :link, :current_user
+ attr_reader :link, :current_user, :source, :target
def initialize(link, user)
@link = link
@current_user = user
+ @source = link.source
+ @target = link.target
end
def execute
@@ -22,6 +24,11 @@ module IssuableLinks
private
+ def create_notes
+ SystemNoteService.unrelate_issuable(source, target, current_user)
+ SystemNoteService.unrelate_issuable(target, source, current_user)
+ end
+
def after_destroy
create_notes
track_event
diff --git a/app/services/issue_links/create_service.rb b/app/services/issue_links/create_service.rb
index a022d3e0bcf..1c6621ce0a1 100644
--- a/app/services/issue_links/create_service.rb
+++ b/app/services/issue_links/create_service.rb
@@ -2,44 +2,25 @@
module IssueLinks
class CreateService < IssuableLinks::CreateService
- # rubocop: disable CodeReuse/ActiveRecord
- def relate_issuables(referenced_issue)
- link = IssueLink.find_or_initialize_by(source: issuable, target: referenced_issue)
-
- set_link_type(link)
-
- if link.changed? && link.save
- create_notes(referenced_issue)
- end
-
- link
- end
- # rubocop: enable CodeReuse/ActiveRecord
-
def linkable_issuables(issues)
@linkable_issuables ||= begin
issues.select { |issue| can?(current_user, :admin_issue_link, issue) }
end
end
- def create_notes(referenced_issue)
- SystemNoteService.relate_issue(issuable, referenced_issue, current_user)
- SystemNoteService.relate_issue(referenced_issue, issuable, current_user)
- end
-
def previous_related_issuables
@related_issues ||= issuable.related_issues(current_user).to_a
end
private
- def set_link_type(_link)
- # EE only
- end
-
def track_event
track_incident_action(current_user, issuable, :incident_relate)
end
+
+ def link_class
+ IssueLink
+ end
end
end
diff --git a/app/services/issue_links/destroy_service.rb b/app/services/issue_links/destroy_service.rb
index 25a45fc697b..e2422ecaca9 100644
--- a/app/services/issue_links/destroy_service.rb
+++ b/app/services/issue_links/destroy_service.rb
@@ -4,23 +4,10 @@ module IssueLinks
class DestroyService < IssuableLinks::DestroyService
private
- def source
- @source ||= link.source
- end
-
- def target
- @target ||= link.target
- end
-
def permission_to_remove_relation?
can?(current_user, :admin_issue_link, source) && can?(current_user, :admin_issue_link, target)
end
- def create_notes
- SystemNoteService.unrelate_issue(source, target, current_user)
- SystemNoteService.unrelate_issue(target, source, current_user)
- end
-
def track_event
track_incident_action(current_user, target, :incident_unrelate)
end
diff --git a/app/services/issues/create_service.rb b/app/services/issues/create_service.rb
index 7fbf7c6af58..7ab663718db 100644
--- a/app/services/issues/create_service.rb
+++ b/app/services/issues/create_service.rb
@@ -23,6 +23,7 @@ module Issues
handle_move_between_ids(@issue)
+ @add_related_issue ||= params.delete(:add_related_issue)
filter_resolve_discussion_params
create(@issue, skip_system_notes: skip_system_notes)
@@ -52,6 +53,7 @@ module Issues
# Add new items to Issues::AfterCreateService if they can be performed in Sidekiq
def after_create(issue)
user_agent_detail_service.create
+ handle_add_related_issue(issue)
resolve_discussions_with_issue(issue)
create_escalation_status(issue)
@@ -91,6 +93,12 @@ module Issues
def user_agent_detail_service
UserAgentDetailService.new(spammable: @issue, spam_params: spam_params)
end
+
+ def handle_add_related_issue(issue)
+ return unless @add_related_issue
+
+ IssueLinks::CreateService.new(issue, issue.author, { target_issuable: @add_related_issue }).execute
+ end
end
end
diff --git a/app/services/issues/export_csv_service.rb b/app/services/issues/export_csv_service.rb
index 3809d8bc347..7076e858155 100644
--- a/app/services/issues/export_csv_service.rb
+++ b/app/services/issues/export_csv_service.rb
@@ -23,11 +23,11 @@ module Issues
def header_to_value_hash
{
+ 'Title' => 'title',
+ 'Description' => 'description',
'Issue ID' => 'iid',
'URL' => -> (issue) { issue_url(issue) },
- 'Title' => 'title',
'State' => -> (issue) { issue.closed? ? 'Closed' : 'Open' },
- 'Description' => 'description',
'Author' => 'author_name',
'Author Username' => -> (issue) { issue.author&.username },
'Assignee' => -> (issue) { issue.assignees.map(&:name).join(', ') },
@@ -52,7 +52,7 @@ module Issues
# rubocop: disable CodeReuse/ActiveRecord
def issue_time_spent(issue)
- issue.timelogs.map(&:time_spent).sum
+ issue.timelogs.sum(&:time_spent)
end
# rubocop: enable CodeReuse/ActiveRecord
end
diff --git a/app/services/issues/set_crm_contacts_service.rb b/app/services/issues/set_crm_contacts_service.rb
index 2edc944435b..5836097f1fd 100644
--- a/app/services/issues/set_crm_contacts_service.rb
+++ b/app/services/issues/set_crm_contacts_service.rb
@@ -52,7 +52,7 @@ module Issues
end
def add_by_email
- contact_ids = ::CustomerRelations::Contact.find_ids_by_emails(project_group, emails(:add_emails))
+ contact_ids = ::CustomerRelations::Contact.find_ids_by_emails(project_group.root_ancestor, emails(:add_emails))
add_by_id(contact_ids)
end
diff --git a/app/services/issues/update_service.rb b/app/services/issues/update_service.rb
index 8372cd919e5..88c4ff1a8bb 100644
--- a/app/services/issues/update_service.rb
+++ b/app/services/issues/update_service.rb
@@ -51,7 +51,6 @@ module Issues
old_mentioned_users = old_associations.fetch(:mentioned_users, [])
old_assignees = old_associations.fetch(:assignees, [])
old_severity = old_associations[:severity]
- old_escalation_status = old_associations[:escalation_status]
if has_changes?(issue, old_labels: old_labels, old_assignees: old_assignees)
todo_service.resolve_todos_for_target(issue, current_user)
@@ -68,7 +67,7 @@ module Issues
handle_milestone_change(issue)
handle_added_mentions(issue, old_mentioned_users)
handle_severity_change(issue, old_severity)
- handle_escalation_status_change(issue, old_escalation_status)
+ handle_escalation_status_change(issue)
handle_issue_type_change(issue)
end
@@ -80,9 +79,7 @@ module Issues
todo_service.reassigned_assignable(issue, current_user, old_assignees)
track_incident_action(current_user, issue, :incident_assigned)
- if Feature.enabled?(:broadcast_issue_updates, issue.project, default_enabled: :yaml)
- GraphqlTriggers.issuable_assignees_updated(issue)
- end
+ GraphqlTriggers.issuable_assignees_updated(issue)
end
def handle_task_changes(issuable)
@@ -196,9 +193,8 @@ module Issues
::IncidentManagement::AddSeveritySystemNoteWorker.perform_async(issue.id, current_user.id)
end
- def handle_escalation_status_change(issue, old_escalation_status)
- return unless old_escalation_status.present?
- return if issue.escalation_status&.slice(:status, :policy_id) == old_escalation_status
+ def handle_escalation_status_change(issue)
+ return unless issue.supports_escalation? && issue.escalation_status
::IncidentManagement::IssuableEscalationStatuses::AfterUpdateService.new(
issue,
diff --git a/app/services/labels/base_service.rb b/app/services/labels/base_service.rb
index ead7f2ea607..f694e6d47a0 100644
--- a/app/services/labels/base_service.rb
+++ b/app/services/labels/base_service.rb
@@ -2,162 +2,8 @@
module Labels
class BaseService < ::BaseService
- COLOR_NAME_TO_HEX = {
- black: '#000000',
- silver: '#C0C0C0',
- gray: '#808080',
- white: '#FFFFFF',
- maroon: '#800000',
- red: '#FF0000',
- purple: '#800080',
- fuchsia: '#FF00FF',
- green: '#008000',
- lime: '#00FF00',
- olive: '#808000',
- yellow: '#FFFF00',
- navy: '#000080',
- blue: '#0000FF',
- teal: '#008080',
- aqua: '#00FFFF',
- orange: '#FFA500',
- aliceblue: '#F0F8FF',
- antiquewhite: '#FAEBD7',
- aquamarine: '#7FFFD4',
- azure: '#F0FFFF',
- beige: '#F5F5DC',
- bisque: '#FFE4C4',
- blanchedalmond: '#FFEBCD',
- blueviolet: '#8A2BE2',
- brown: '#A52A2A',
- burlywood: '#DEB887',
- cadetblue: '#5F9EA0',
- chartreuse: '#7FFF00',
- chocolate: '#D2691E',
- coral: '#FF7F50',
- cornflowerblue: '#6495ED',
- cornsilk: '#FFF8DC',
- crimson: '#DC143C',
- darkblue: '#00008B',
- darkcyan: '#008B8B',
- darkgoldenrod: '#B8860B',
- darkgray: '#A9A9A9',
- darkgreen: '#006400',
- darkgrey: '#A9A9A9',
- darkkhaki: '#BDB76B',
- darkmagenta: '#8B008B',
- darkolivegreen: '#556B2F',
- darkorange: '#FF8C00',
- darkorchid: '#9932CC',
- darkred: '#8B0000',
- darksalmon: '#E9967A',
- darkseagreen: '#8FBC8F',
- darkslateblue: '#483D8B',
- darkslategray: '#2F4F4F',
- darkslategrey: '#2F4F4F',
- darkturquoise: '#00CED1',
- darkviolet: '#9400D3',
- deeppink: '#FF1493',
- deepskyblue: '#00BFFF',
- dimgray: '#696969',
- dimgrey: '#696969',
- dodgerblue: '#1E90FF',
- firebrick: '#B22222',
- floralwhite: '#FFFAF0',
- forestgreen: '#228B22',
- gainsboro: '#DCDCDC',
- ghostwhite: '#F8F8FF',
- gold: '#FFD700',
- goldenrod: '#DAA520',
- greenyellow: '#ADFF2F',
- grey: '#808080',
- honeydew: '#F0FFF0',
- hotpink: '#FF69B4',
- indianred: '#CD5C5C',
- indigo: '#4B0082',
- ivory: '#FFFFF0',
- khaki: '#F0E68C',
- lavender: '#E6E6FA',
- lavenderblush: '#FFF0F5',
- lawngreen: '#7CFC00',
- lemonchiffon: '#FFFACD',
- lightblue: '#ADD8E6',
- lightcoral: '#F08080',
- lightcyan: '#E0FFFF',
- lightgoldenrodyellow: '#FAFAD2',
- lightgray: '#D3D3D3',
- lightgreen: '#90EE90',
- lightgrey: '#D3D3D3',
- lightpink: '#FFB6C1',
- lightsalmon: '#FFA07A',
- lightseagreen: '#20B2AA',
- lightskyblue: '#87CEFA',
- lightslategray: '#778899',
- lightslategrey: '#778899',
- lightsteelblue: '#B0C4DE',
- lightyellow: '#FFFFE0',
- limegreen: '#32CD32',
- linen: '#FAF0E6',
- mediumaquamarine: '#66CDAA',
- mediumblue: '#0000CD',
- mediumorchid: '#BA55D3',
- mediumpurple: '#9370DB',
- mediumseagreen: '#3CB371',
- mediumslateblue: '#7B68EE',
- mediumspringgreen: '#00FA9A',
- mediumturquoise: '#48D1CC',
- mediumvioletred: '#C71585',
- midnightblue: '#191970',
- mintcream: '#F5FFFA',
- mistyrose: '#FFE4E1',
- moccasin: '#FFE4B5',
- navajowhite: '#FFDEAD',
- oldlace: '#FDF5E6',
- olivedrab: '#6B8E23',
- orangered: '#FF4500',
- orchid: '#DA70D6',
- palegoldenrod: '#EEE8AA',
- palegreen: '#98FB98',
- paleturquoise: '#AFEEEE',
- palevioletred: '#DB7093',
- papayawhip: '#FFEFD5',
- peachpuff: '#FFDAB9',
- peru: '#CD853F',
- pink: '#FFC0CB',
- plum: '#DDA0DD',
- powderblue: '#B0E0E6',
- rosybrown: '#BC8F8F',
- royalblue: '#4169E1',
- saddlebrown: '#8B4513',
- salmon: '#FA8072',
- sandybrown: '#F4A460',
- seagreen: '#2E8B57',
- seashell: '#FFF5EE',
- sienna: '#A0522D',
- skyblue: '#87CEEB',
- slateblue: '#6A5ACD',
- slategray: '#708090',
- slategrey: '#708090',
- snow: '#FFFAFA',
- springgreen: '#00FF7F',
- steelblue: '#4682B4',
- tan: '#D2B48C',
- thistle: '#D8BFD8',
- tomato: '#FF6347',
- turquoise: '#40E0D0',
- violet: '#EE82EE',
- wheat: '#F5DEB3',
- whitesmoke: '#F5F5F5',
- yellowgreen: '#9ACD32',
- rebeccapurple: '#663399'
- }.freeze
-
def convert_color_name_to_hex
- color = params[:color]
- color_name = color.strip.downcase
-
- return color if color_name.start_with?('#')
-
- COLOR_NAME_TO_HEX[color_name.to_sym] || color
+ ::Gitlab::Color.of(params[:color])
end
end
end
diff --git a/app/services/loose_foreign_keys/batch_cleaner_service.rb b/app/services/loose_foreign_keys/batch_cleaner_service.rb
index f3db2037911..b89de15a568 100644
--- a/app/services/loose_foreign_keys/batch_cleaner_service.rb
+++ b/app/services/loose_foreign_keys/batch_cleaner_service.rb
@@ -54,7 +54,7 @@ module LooseForeignKeys
attr_reader :parent_table, :loose_foreign_key_definitions, :deleted_parent_records, :modification_tracker, :deleted_records_counter, :deleted_records_rescheduled_count, :deleted_records_incremented_count
def handle_over_limit
- return if Feature.disabled?(:lfk_fair_queueing)
+ return if Feature.disabled?(:lfk_fair_queueing, default_enabled: :yaml)
records_to_reschedule = []
records_to_increment = []
diff --git a/app/services/members/projects/creator_service.rb b/app/services/members/projects/creator_service.rb
index 2e974177075..4dba81acf73 100644
--- a/app/services/members/projects/creator_service.rb
+++ b/app/services/members/projects/creator_service.rb
@@ -4,7 +4,7 @@ module Members
module Projects
class CreatorService < Members::CreatorService
def self.access_levels
- Gitlab::Access.sym_options
+ Gitlab::Access.sym_options_with_owner
end
private
diff --git a/app/services/merge_requests/approval_service.rb b/app/services/merge_requests/approval_service.rb
index 3f39b2742c6..37c2676e51c 100644
--- a/app/services/merge_requests/approval_service.rb
+++ b/app/services/merge_requests/approval_service.rb
@@ -11,10 +11,11 @@ module MergeRequests
reset_approvals_cache(merge_request)
create_event(merge_request)
+ stream_audit_event(merge_request)
create_approval_note(merge_request)
mark_pending_todos_as_done(merge_request)
execute_approval_hooks(merge_request, current_user)
- remove_attention_requested(merge_request, current_user)
+ remove_attention_requested(merge_request)
merge_request_activity_counter.track_approve_mr_action(user: current_user)
success
@@ -52,6 +53,10 @@ module MergeRequests
def create_event(merge_request)
event_service.approve_mr(merge_request, current_user)
end
+
+ def stream_audit_event(merge_request)
+ # Defined in EE
+ end
end
end
diff --git a/app/services/merge_requests/base_service.rb b/app/services/merge_requests/base_service.rb
index 3363fc90997..2ab623bacf8 100644
--- a/app/services/merge_requests/base_service.rb
+++ b/app/services/merge_requests/base_service.rb
@@ -60,7 +60,9 @@ module MergeRequests
merge_request_activity_counter.track_reviewers_changed_action(user: current_user)
unless new_reviewers.include?(current_user)
- remove_attention_requested(merge_request, current_user)
+ remove_attention_requested(merge_request)
+
+ merge_request.merge_request_reviewers_with(new_reviewers).update_all(updated_state_by_user_id: current_user.id)
end
end
@@ -251,10 +253,10 @@ module MergeRequests
::MergeRequests::BulkRemoveAttentionRequestedService.new(project: merge_request.project, current_user: current_user, merge_request: merge_request, users: users.uniq).execute
end
- def remove_attention_requested(merge_request, user)
+ def remove_attention_requested(merge_request)
return unless merge_request.attention_requested_enabled?
- ::MergeRequests::RemoveAttentionRequestedService.new(project: merge_request.project, current_user: current_user, merge_request: merge_request, user: user).execute
+ ::MergeRequests::RemoveAttentionRequestedService.new(project: merge_request.project, current_user: current_user, merge_request: merge_request).execute
end
end
end
diff --git a/app/services/merge_requests/bulk_remove_attention_requested_service.rb b/app/services/merge_requests/bulk_remove_attention_requested_service.rb
index 6573b623779..774f2c2ee35 100644
--- a/app/services/merge_requests/bulk_remove_attention_requested_service.rb
+++ b/app/services/merge_requests/bulk_remove_attention_requested_service.rb
@@ -19,6 +19,8 @@ module MergeRequests
merge_request.merge_request_assignees.where(user_id: users).update_all(state: :reviewed)
merge_request.merge_request_reviewers.where(user_id: users).update_all(state: :reviewed)
+ users.each { |user| user.invalidate_attention_requested_count }
+
success
end
# rubocop: enable CodeReuse/ActiveRecord
diff --git a/app/services/merge_requests/create_service.rb b/app/services/merge_requests/create_service.rb
index c1292d924b2..9c525ae8489 100644
--- a/app/services/merge_requests/create_service.rb
+++ b/app/services/merge_requests/create_service.rb
@@ -31,6 +31,14 @@ module MergeRequests
private
+ def before_create(merge_request)
+ # If the fetching of the source branch occurs in an ActiveRecord
+ # callback (e.g. after_create), a database transaction will be
+ # open while the Gitaly RPC waits. To avoid an idle in transaction
+ # timeout, we do this before we attempt to save the merge request.
+ merge_request.eager_fetch_ref!
+ end
+
def set_projects!
# @project is used to determine whether the user can set the merge request's
# assignee, milestone and labels. Whether they can depends on their
diff --git a/app/services/merge_requests/export_csv_service.rb b/app/services/merge_requests/export_csv_service.rb
index 8f2a70575e5..1f8dec69ef0 100644
--- a/app/services/merge_requests/export_csv_service.rb
+++ b/app/services/merge_requests/export_csv_service.rb
@@ -13,11 +13,11 @@ module MergeRequests
def header_to_value_hash
{
+ 'Title' => 'title',
+ 'Description' => 'description',
'MR IID' => 'iid',
'URL' => -> (merge_request) { merge_request_url(merge_request) },
- 'Title' => 'title',
'State' => 'state',
- 'Description' => 'description',
'Source Branch' => 'source_branch',
'Target Branch' => 'target_branch',
'Source Project ID' => 'source_project_id',
diff --git a/app/services/merge_requests/handle_assignees_change_service.rb b/app/services/merge_requests/handle_assignees_change_service.rb
index 97be9fe8d9f..a169a6dc0b6 100644
--- a/app/services/merge_requests/handle_assignees_change_service.rb
+++ b/app/services/merge_requests/handle_assignees_change_service.rb
@@ -21,10 +21,12 @@ module MergeRequests
merge_request_activity_counter.track_users_assigned_to_mr(users: new_assignees)
merge_request_activity_counter.track_assignees_changed_action(user: current_user)
+ merge_request.merge_request_assignees_with(new_assignees).update_all(updated_state_by_user_id: current_user.id)
+
execute_assignees_hooks(merge_request, old_assignees) if options[:execute_hooks]
unless new_assignees.include?(current_user)
- remove_attention_requested(merge_request, current_user)
+ remove_attention_requested(merge_request)
end
end
diff --git a/app/services/merge_requests/merge_orchestration_service.rb b/app/services/merge_requests/merge_orchestration_service.rb
index 24341ef1145..5f3d2174840 100644
--- a/app/services/merge_requests/merge_orchestration_service.rb
+++ b/app/services/merge_requests/merge_orchestration_service.rb
@@ -26,7 +26,7 @@ module MergeRequests
def can_merge_immediately?(merge_request)
merge_request.can_be_merged_by?(current_user) &&
- merge_request.mergeable_state?
+ merge_request.mergeable?
end
def can_merge_automatically?(merge_request)
diff --git a/app/services/merge_requests/mergeability/check_broken_status_service.rb b/app/services/merge_requests/mergeability/check_broken_status_service.rb
new file mode 100644
index 00000000000..9a54a4292c8
--- /dev/null
+++ b/app/services/merge_requests/mergeability/check_broken_status_service.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+module MergeRequests
+ module Mergeability
+ class CheckBrokenStatusService < CheckBaseService
+ def execute
+ if merge_request.broken?
+ failure
+ else
+ success
+ end
+ end
+
+ def skip?
+ false
+ end
+
+ def cacheable?
+ false
+ end
+ end
+ end
+end
diff --git a/app/services/merge_requests/mergeability/check_discussions_status_service.rb b/app/services/merge_requests/mergeability/check_discussions_status_service.rb
new file mode 100644
index 00000000000..9b4eab9d399
--- /dev/null
+++ b/app/services/merge_requests/mergeability/check_discussions_status_service.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+module MergeRequests
+ module Mergeability
+ class CheckDiscussionsStatusService < CheckBaseService
+ def execute
+ if merge_request.mergeable_discussions_state?
+ success
+ else
+ failure
+ end
+ end
+
+ def skip?
+ params[:skip_discussions_check].present?
+ end
+
+ def cacheable?
+ false
+ end
+ end
+ end
+end
diff --git a/app/services/merge_requests/mergeability/check_draft_status_service.rb b/app/services/merge_requests/mergeability/check_draft_status_service.rb
new file mode 100644
index 00000000000..bc940e2116d
--- /dev/null
+++ b/app/services/merge_requests/mergeability/check_draft_status_service.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+module MergeRequests
+ module Mergeability
+ class CheckDraftStatusService < CheckBaseService
+ def execute
+ if merge_request.draft?
+ failure
+ else
+ success
+ end
+ end
+
+ def skip?
+ false
+ end
+
+ def cacheable?
+ false
+ end
+ end
+ end
+end
diff --git a/app/services/merge_requests/mergeability/check_open_status_service.rb b/app/services/merge_requests/mergeability/check_open_status_service.rb
new file mode 100644
index 00000000000..361af946e3f
--- /dev/null
+++ b/app/services/merge_requests/mergeability/check_open_status_service.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+module MergeRequests
+ module Mergeability
+ class CheckOpenStatusService < CheckBaseService
+ def execute
+ if merge_request.open?
+ success
+ else
+ failure
+ end
+ end
+
+ def skip?
+ false
+ end
+
+ def cacheable?
+ false
+ end
+ end
+ end
+end
diff --git a/app/services/merge_requests/mergeability/run_checks_service.rb b/app/services/merge_requests/mergeability/run_checks_service.rb
index c1d65fb65cc..03c6d985c23 100644
--- a/app/services/merge_requests/mergeability/run_checks_service.rb
+++ b/app/services/merge_requests/mergeability/run_checks_service.rb
@@ -7,6 +7,10 @@ module MergeRequests
# We want to have the cheapest checks first in the list,
# that way we can fail fast before running the more expensive ones
CHECKS = [
+ CheckOpenStatusService,
+ CheckDraftStatusService,
+ CheckBrokenStatusService,
+ CheckDiscussionsStatusService,
CheckCiStatusService
].freeze
diff --git a/app/services/merge_requests/reload_merge_head_diff_service.rb b/app/services/merge_requests/reload_merge_head_diff_service.rb
index f02a9bd3139..4724dd1c068 100644
--- a/app/services/merge_requests/reload_merge_head_diff_service.rb
+++ b/app/services/merge_requests/reload_merge_head_diff_service.rb
@@ -9,7 +9,6 @@ module MergeRequests
end
def execute
- return error("default_merge_ref_for_diffs feature flag is disabled") unless enabled?
return error("Merge request has no merge ref head.") unless merge_request.merge_ref_head.present?
error_msg = recreate_merge_head_diff
@@ -23,10 +22,6 @@ module MergeRequests
attr_reader :merge_request
- def enabled?
- Feature.enabled?(:default_merge_ref_for_diffs, merge_request.project, default_enabled: :yaml)
- end
-
def recreate_merge_head_diff
merge_request.merge_head_diff&.destroy!
diff --git a/app/services/merge_requests/remove_approval_service.rb b/app/services/merge_requests/remove_approval_service.rb
index 198a21884b8..c7bc3532264 100644
--- a/app/services/merge_requests/remove_approval_service.rb
+++ b/app/services/merge_requests/remove_approval_service.rb
@@ -17,7 +17,7 @@ module MergeRequests
reset_approvals_cache(merge_request)
create_note(merge_request)
merge_request_activity_counter.track_unapprove_mr_action(user: current_user)
- remove_attention_requested(merge_request, current_user)
+ remove_attention_requested(merge_request)
end
success
diff --git a/app/services/merge_requests/remove_attention_requested_service.rb b/app/services/merge_requests/remove_attention_requested_service.rb
index b727c24415e..a32a8071471 100644
--- a/app/services/merge_requests/remove_attention_requested_service.rb
+++ b/app/services/merge_requests/remove_attention_requested_service.rb
@@ -2,13 +2,12 @@
module MergeRequests
class RemoveAttentionRequestedService < MergeRequests::BaseService
- attr_accessor :merge_request, :user
+ attr_accessor :merge_request
- def initialize(project:, current_user:, merge_request:, user:)
+ def initialize(project:, current_user:, merge_request:)
super(project: project, current_user: current_user)
@merge_request = merge_request
- @user = user
end
def execute
@@ -18,6 +17,8 @@ module MergeRequests
update_state(reviewer)
update_state(assignee)
+ current_user.invalidate_attention_requested_count
+
success
else
error("User is not a reviewer or assignee of the merge request")
@@ -27,11 +28,11 @@ module MergeRequests
private
def assignee
- merge_request.find_assignee(user)
+ merge_request.find_assignee(current_user)
end
def reviewer
- merge_request.find_reviewer(user)
+ merge_request.find_reviewer(current_user)
end
def update_state(reviewer_or_assignee)
diff --git a/app/services/merge_requests/reopen_service.rb b/app/services/merge_requests/reopen_service.rb
index 35c50d63da0..4612688f78b 100644
--- a/app/services/merge_requests/reopen_service.rb
+++ b/app/services/merge_requests/reopen_service.rb
@@ -6,6 +6,8 @@ module MergeRequests
return merge_request unless can?(current_user, :reopen_merge_request, merge_request)
if merge_request.reopen
+ users = merge_request.assignees | merge_request.reviewers
+
create_event(merge_request)
create_note(merge_request, 'reopened')
merge_request_activity_counter.track_reopen_mr_action(user: current_user)
@@ -13,11 +15,13 @@ module MergeRequests
execute_hooks(merge_request, 'reopen')
merge_request.reload_diff(current_user)
merge_request.mark_as_unchecked
- invalidate_cache_counts(merge_request, users: merge_request.assignees | merge_request.reviewers)
+ invalidate_cache_counts(merge_request, users: users)
merge_request.update_project_counter_caches
merge_request.cache_merge_request_closes_issues!(current_user)
merge_request.cleanup_schedule&.destroy
merge_request.update_column(:merge_ref_sha, nil)
+
+ users.each { |user| user.invalidate_attention_requested_count }
end
merge_request
diff --git a/app/services/merge_requests/toggle_attention_requested_service.rb b/app/services/merge_requests/toggle_attention_requested_service.rb
index d9f81ac310f..64cdcd725a2 100644
--- a/app/services/merge_requests/toggle_attention_requested_service.rb
+++ b/app/services/merge_requests/toggle_attention_requested_service.rb
@@ -18,12 +18,14 @@ module MergeRequests
update_state(reviewer)
update_state(assignee)
+ user.invalidate_attention_requested_count
+
if reviewer&.attention_requested? || assignee&.attention_requested?
create_attention_request_note
notity_user
if current_user.id != user.id
- remove_attention_requested(merge_request, current_user)
+ remove_attention_requested(merge_request)
end
else
create_remove_attention_request_note
@@ -59,7 +61,8 @@ module MergeRequests
end
def update_state(reviewer_or_assignee)
- reviewer_or_assignee&.update(state: reviewer_or_assignee&.attention_requested? ? :reviewed : :attention_requested)
+ reviewer_or_assignee&.update(state: reviewer_or_assignee&.attention_requested? ? :reviewed : :attention_requested,
+ updated_state_by: current_user)
end
end
end
diff --git a/app/services/notification_recipients/builder/merge_request_unmergeable.rb b/app/services/notification_recipients/builder/merge_request_unmergeable.rb
index 24d96b98002..b9facf07a3a 100644
--- a/app/services/notification_recipients/builder/merge_request_unmergeable.rb
+++ b/app/services/notification_recipients/builder/merge_request_unmergeable.rb
@@ -4,6 +4,7 @@ module NotificationRecipients
module Builder
class MergeRequestUnmergeable < Base
attr_reader :target
+
def initialize(merge_request)
@target = merge_request
end
diff --git a/app/services/notification_recipients/builder/new_note.rb b/app/services/notification_recipients/builder/new_note.rb
index 17e4728d352..dcf6d23298a 100644
--- a/app/services/notification_recipients/builder/new_note.rb
+++ b/app/services/notification_recipients/builder/new_note.rb
@@ -4,6 +4,7 @@ module NotificationRecipients
module Builder
class NewNote < Base
attr_reader :note
+
def initialize(note)
@note = note
end
diff --git a/app/services/notification_recipients/builder/new_review.rb b/app/services/notification_recipients/builder/new_review.rb
index 3b1296f6967..84598c3d4ad 100644
--- a/app/services/notification_recipients/builder/new_review.rb
+++ b/app/services/notification_recipients/builder/new_review.rb
@@ -4,6 +4,7 @@ module NotificationRecipients
module Builder
class NewReview < Base
attr_reader :review
+
def initialize(review)
@review = review
end
diff --git a/app/services/notification_recipients/builder/project_maintainers.rb b/app/services/notification_recipients/builder/project_maintainers.rb
index e8f22c00a83..a295929a1a9 100644
--- a/app/services/notification_recipients/builder/project_maintainers.rb
+++ b/app/services/notification_recipients/builder/project_maintainers.rb
@@ -14,6 +14,7 @@ module NotificationRecipients
return [] unless project
add_recipients(project.team.maintainers, :mention, nil)
+ add_recipients(project.team.owners, :mention, nil)
end
def acting_user
diff --git a/app/services/notification_service.rb b/app/services/notification_service.rb
index 5b1733422d0..aa7e636b8a4 100644
--- a/app/services/notification_service.rb
+++ b/app/services/notification_service.rb
@@ -18,6 +18,7 @@
class NotificationService
class Async
attr_reader :parent
+
delegate :respond_to_missing, to: :parent
def initialize(parent)
@@ -64,6 +65,13 @@ class NotificationService
end
end
+ # Notify the owner of the account when a new personal access token is created
+ def access_token_created(user, token_name)
+ return unless user.can?(:receive_notifications)
+
+ mailer.access_token_created_email(user, token_name).deliver_later
+ end
+
# Notify the owner of the personal access token, when it is about to expire
# And mark the token with about_to_expire_delivered
def access_token_about_to_expire(user, token_names)
diff --git a/app/services/packages/pypi/create_package_service.rb b/app/services/packages/pypi/create_package_service.rb
index b988c191734..5d7e967ceb0 100644
--- a/app/services/packages/pypi/create_package_service.rb
+++ b/app/services/packages/pypi/create_package_service.rb
@@ -9,7 +9,7 @@ module Packages
::Packages::Package.transaction do
meta = Packages::Pypi::Metadatum.new(
package: created_package,
- required_python: params[:requires_python]
+ required_python: params[:requires_python] || ''
)
unless meta.valid?
diff --git a/app/services/personal_access_tokens/create_service.rb b/app/services/personal_access_tokens/create_service.rb
index 7555ba26768..e2f2e220750 100644
--- a/app/services/personal_access_tokens/create_service.rb
+++ b/app/services/personal_access_tokens/create_service.rb
@@ -16,6 +16,7 @@ module PersonalAccessTokens
if token.persisted?
log_event(token)
+ notification_service.access_token_created(target_user, token.name)
ServiceResponse.success(payload: { personal_access_token: token })
else
ServiceResponse.error(message: token.errors.full_messages.to_sentence, payload: { personal_access_token: token })
diff --git a/app/services/post_receive_service.rb b/app/services/post_receive_service.rb
index f5638b0aa40..15c978e6763 100644
--- a/app/services/post_receive_service.rb
+++ b/app/services/post_receive_service.rb
@@ -86,7 +86,7 @@ class PostReceiveService
banner = nil
if project
- scoped_messages = BroadcastMessage.current_banner_messages(project.full_path).select do |message|
+ scoped_messages = BroadcastMessage.current_banner_messages(current_path: project.full_path).select do |message|
message.target_path.present? && message.matches_current_path(project.full_path)
end
diff --git a/app/services/projects/base_move_relations_service.rb b/app/services/projects/base_move_relations_service.rb
index 3a159cef58b..bd5a39d3b59 100644
--- a/app/services/projects/base_move_relations_service.rb
+++ b/app/services/projects/base_move_relations_service.rb
@@ -3,6 +3,7 @@
module Projects
class BaseMoveRelationsService < BaseService
attr_reader :source_project
+
def execute(source_project, remove_remaining_elements: true)
return if source_project.blank?
diff --git a/app/services/projects/container_repository/cleanup_tags_service.rb b/app/services/projects/container_repository/cleanup_tags_service.rb
index 1a788abac12..72f3fddb4c3 100644
--- a/app/services/projects/container_repository/cleanup_tags_service.rb
+++ b/app/services/projects/container_repository/cleanup_tags_service.rb
@@ -145,12 +145,14 @@ module Projects
end
def caching_enabled?
- container_expiration_policy &&
- older_than.present?
+ result = ::Gitlab::CurrentSettings.current_application_settings.container_registry_expiration_policies_caching &&
+ container_expiration_policy &&
+ older_than.present?
+ !!result
end
def throttling_enabled?
- Feature.enabled?(:container_registry_expiration_policies_throttling)
+ Feature.enabled?(:container_registry_expiration_policies_throttling, default_enabled: :yaml)
end
def max_list_size
diff --git a/app/services/projects/container_repository/gitlab/delete_tags_service.rb b/app/services/projects/container_repository/gitlab/delete_tags_service.rb
index 589aac5c3ac..f109cb0ca20 100644
--- a/app/services/projects/container_repository/gitlab/delete_tags_service.rb
+++ b/app/services/projects/container_repository/gitlab/delete_tags_service.rb
@@ -54,7 +54,7 @@ module Projects
def throttling_enabled?
strong_memoize(:feature_flag) do
- Feature.enabled?(:container_registry_expiration_policies_throttling)
+ Feature.enabled?(:container_registry_expiration_policies_throttling, default_enabled: :yaml)
end
end
diff --git a/app/services/projects/container_repository/third_party/delete_tags_service.rb b/app/services/projects/container_repository/third_party/delete_tags_service.rb
index 404642acf72..4184c676fc3 100644
--- a/app/services/projects/container_repository/third_party/delete_tags_service.rb
+++ b/app/services/projects/container_repository/third_party/delete_tags_service.rb
@@ -41,14 +41,12 @@ module Projects
# update the manifests of the tags with the new dummy image
def replace_tag_manifests(dummy_manifest)
- deleted_tags = {}
-
- @tag_names.each do |name|
+ deleted_tags = @tag_names.map do |name|
digest = @container_repository.client.put_tag(@container_repository.path, name, dummy_manifest)
next unless digest
- deleted_tags[name] = digest
- end
+ [name, digest]
+ end.compact.to_h
# make sure the digests are the same (it should always be)
digests = deleted_tags.values.uniq
diff --git a/app/services/projects/create_service.rb b/app/services/projects/create_service.rb
index c885369dfec..252e1d76bef 100644
--- a/app/services/projects/create_service.rb
+++ b/app/services/projects/create_service.rb
@@ -147,7 +147,7 @@ module Projects
priority: UserProjectAccessChangedService::LOW_PRIORITY
)
else
- @project.add_maintainer(@project.namespace.owner, current_user: current_user)
+ @project.add_owner(@project.namespace.owner, current_user: current_user)
end
end
diff --git a/app/services/projects/deploy_tokens/create_service.rb b/app/services/projects/deploy_tokens/create_service.rb
index 592198ef241..2486544b150 100644
--- a/app/services/projects/deploy_tokens/create_service.rb
+++ b/app/services/projects/deploy_tokens/create_service.rb
@@ -13,3 +13,5 @@ module Projects
end
end
end
+
+Projects::DeployTokens::CreateService.prepend_mod
diff --git a/app/services/projects/deploy_tokens/destroy_service.rb b/app/services/projects/deploy_tokens/destroy_service.rb
index e063f86a65c..7ac1b52b0af 100644
--- a/app/services/projects/deploy_tokens/destroy_service.rb
+++ b/app/services/projects/deploy_tokens/destroy_service.rb
@@ -11,3 +11,5 @@ module Projects
end
end
end
+
+Projects::DeployTokens::DestroyService.prepend_mod
diff --git a/app/services/projects/destroy_service.rb b/app/services/projects/destroy_service.rb
index 95af5a6863f..a73244c6971 100644
--- a/app/services/projects/destroy_service.rb
+++ b/app/services/projects/destroy_service.rb
@@ -37,7 +37,7 @@ module Projects
system_hook_service.execute_hooks_for(project, :destroy)
log_info("Project \"#{project.full_path}\" was deleted")
- publish_project_deleted_event_for(project) if Feature.enabled?(:publish_project_deleted_event, default_enabled: :yaml)
+ publish_project_deleted_event_for(project)
current_user.invalidate_personal_projects_count
@@ -72,7 +72,13 @@ module Projects
end
def remove_snippets
- response = ::Snippets::BulkDestroyService.new(current_user, project.snippets).execute
+ # We're setting the hard_delete param because we dont need to perform the access checks within the service since
+ # the user has enough access rights to remove the project and its resources.
+ response = ::Snippets::BulkDestroyService.new(current_user, project.snippets).execute(hard_delete: true)
+
+ if response.error?
+ log_error("Snippet deletion failed on #{project.full_path} with the following message: #{response.message}")
+ end
response.success?
end
@@ -194,6 +200,10 @@ module Projects
::Ci::DestroyPipelineService.new(project, current_user).execute(pipeline)
end
+ project.secure_files.find_each(batch_size: BATCH_SIZE) do |secure_file| # rubocop: disable CodeReuse/ActiveRecord
+ ::Ci::DestroySecureFileService.new(project, current_user).execute(secure_file)
+ end
+
deleted_count = ::CommitStatus.for_project(project).delete_all
Gitlab::AppLogger.info(
diff --git a/app/services/projects/lfs_pointers/lfs_download_service.rb b/app/services/projects/lfs_pointers/lfs_download_service.rb
index 9da72d9300e..76005a1c96e 100644
--- a/app/services/projects/lfs_pointers/lfs_download_service.rb
+++ b/app/services/projects/lfs_pointers/lfs_download_service.rb
@@ -11,6 +11,7 @@ module Projects
LARGE_FILE_SIZE = 1.megabytes
attr_reader :lfs_download_object
+
delegate :oid, :size, :credentials, :sanitized_url, :headers, to: :lfs_download_object, prefix: :lfs
def initialize(project, lfs_download_object)
diff --git a/app/services/projects/refresh_build_artifacts_size_statistics_service.rb b/app/services/projects/refresh_build_artifacts_size_statistics_service.rb
new file mode 100644
index 00000000000..794c042ea39
--- /dev/null
+++ b/app/services/projects/refresh_build_artifacts_size_statistics_service.rb
@@ -0,0 +1,32 @@
+# frozen_string_literal: true
+
+module Projects
+ class RefreshBuildArtifactsSizeStatisticsService
+ BATCH_SIZE = 1000
+
+ def execute
+ refresh = Projects::BuildArtifactsSizeRefresh.process_next_refresh!
+ return unless refresh
+
+ batch = refresh.next_batch(limit: BATCH_SIZE).to_a
+
+ if batch.any?
+ # We are doing the sum in ruby because the query takes too long when done in SQL
+ total_artifacts_size = batch.sum(&:size)
+
+ Projects::BuildArtifactsSizeRefresh.transaction do
+ # Mark the refresh ready for another worker to pick up and process the next batch
+ refresh.requeue!(batch.last.id)
+
+ refresh.project.statistics.delayed_increment_counter(:build_artifacts_size, total_artifacts_size)
+ end
+ else
+ # Remove the refresh job from the table if there are no more
+ # remaining job artifacts to calculate for the given project.
+ refresh.destroy!
+ end
+
+ refresh
+ end
+ end
+end
diff --git a/app/services/projects/update_pages_service.rb b/app/services/projects/update_pages_service.rb
index 0000e713cb4..2ec965fe2f4 100644
--- a/app/services/projects/update_pages_service.rb
+++ b/app/services/projects/update_pages_service.rb
@@ -22,8 +22,8 @@ module Projects
register_attempt
# Create status notifying the deployment of pages
- @status = build_commit_status
- ::Ci::Pipelines::AddJobService.new(@build.pipeline).execute!(@status) do |job|
+ @commit_status = build_commit_status
+ ::Ci::Pipelines::AddJobService.new(@build.pipeline).execute!(@commit_status) do |job|
job.enqueue!
job.run!
end
@@ -46,17 +46,17 @@ module Projects
private
def success
- @status.success
- @project.mark_pages_as_deployed(artifacts_archive: build.job_artifacts_archive)
+ @commit_status.success
+ @project.mark_pages_as_deployed
super
end
def error(message)
register_failure
log_error("Projects::UpdatePagesService: #{message}")
- @status.allow_failure = !latest?
- @status.description = message
- @status.drop(:script_failure)
+ @commit_status.allow_failure = !latest?
+ @commit_status.description = message
+ @commit_status.drop(:script_failure)
super
end
diff --git a/app/services/repositories/base_service.rb b/app/services/repositories/base_service.rb
index efb6f6de8db..13ad126f8f0 100644
--- a/app/services/repositories/base_service.rb
+++ b/app/services/repositories/base_service.rb
@@ -18,8 +18,6 @@ class Repositories::BaseService < BaseService
end
def mv_repository(from_path, to_path)
- return true unless repo_exists?(from_path)
-
gitlab_shell.mv_repository(repository.shard, from_path, to_path)
end
diff --git a/app/services/repositories/destroy_rollback_service.rb b/app/services/repositories/destroy_rollback_service.rb
index 5ef4e11bf55..a19e305607f 100644
--- a/app/services/repositories/destroy_rollback_service.rb
+++ b/app/services/repositories/destroy_rollback_service.rb
@@ -12,8 +12,14 @@ class Repositories::DestroyRollbackService < Repositories::BaseService
log_info(%Q{Repository "#{removal_path}" moved to "#{disk_path}" for repository "#{full_path}"})
success
- else
+ elsif repo_exists?(removal_path)
+ # If the repo does not exist, there is no need to return an
+ # error because there was nothing to do.
move_error(removal_path)
+ else
+ success
end
+ rescue Gitlab::Git::Repository::NoRepository
+ success
end
end
diff --git a/app/services/repositories/destroy_service.rb b/app/services/repositories/destroy_service.rb
index 1e34dfbe398..c5a0af56066 100644
--- a/app/services/repositories/destroy_service.rb
+++ b/app/services/repositories/destroy_service.rb
@@ -30,8 +30,12 @@ class Repositories::DestroyService < Repositories::BaseService
log_info("Repository \"#{full_path}\" was removed")
success
- else
+ elsif repo_exists?(disk_path)
move_error(disk_path)
+ else
+ success
end
+ rescue Gitlab::Git::Repository::NoRepository
+ success
end
end
diff --git a/app/services/security/ci_configuration/base_create_service.rb b/app/services/security/ci_configuration/base_create_service.rb
index ea77cd98ba3..7f3b66d40e1 100644
--- a/app/services/security/ci_configuration/base_create_service.rb
+++ b/app/services/security/ci_configuration/base_create_service.rb
@@ -41,7 +41,7 @@ module Security
end
def existing_gitlab_ci_content
- @gitlab_ci_yml ||= project.repository.gitlab_ci_yml_for(project.repository.root_ref_sha)
+ @gitlab_ci_yml ||= project.ci_config_for(project.repository.root_ref_sha)
YAML.safe_load(@gitlab_ci_yml) if @gitlab_ci_yml
end
diff --git a/app/services/security/ci_configuration/container_scanning_create_service.rb b/app/services/security/ci_configuration/container_scanning_create_service.rb
index 788533575e6..da2f1ac0981 100644
--- a/app/services/security/ci_configuration/container_scanning_create_service.rb
+++ b/app/services/security/ci_configuration/container_scanning_create_service.rb
@@ -6,7 +6,8 @@ module Security
private
def action
- Security::CiConfiguration::ContainerScanningBuildAction.new(project.auto_devops_enabled?, existing_gitlab_ci_content).generate
+ Security::CiConfiguration::ContainerScanningBuildAction.new(project.auto_devops_enabled?, existing_gitlab_ci_content,
+ project.ci_config_path).generate
end
def next_branch
diff --git a/app/services/security/ci_configuration/dependency_scanning_create_service.rb b/app/services/security/ci_configuration/dependency_scanning_create_service.rb
index 71e8d5025ae..b11eccc680c 100644
--- a/app/services/security/ci_configuration/dependency_scanning_create_service.rb
+++ b/app/services/security/ci_configuration/dependency_scanning_create_service.rb
@@ -6,7 +6,8 @@ module Security
private
def action
- Security::CiConfiguration::DependencyScanningBuildAction.new(project.auto_devops_enabled?, existing_gitlab_ci_content).generate
+ Security::CiConfiguration::DependencyScanningBuildAction.new(project.auto_devops_enabled?, existing_gitlab_ci_content,
+ project.ci_config_path).generate
end
def next_branch
diff --git a/app/services/security/ci_configuration/sast_create_service.rb b/app/services/security/ci_configuration/sast_create_service.rb
index 47e01847b17..d78e22f1fe1 100644
--- a/app/services/security/ci_configuration/sast_create_service.rb
+++ b/app/services/security/ci_configuration/sast_create_service.rb
@@ -26,7 +26,7 @@ module Security
nil
end
- Security::CiConfiguration::SastBuildAction.new(project.auto_devops_enabled?, params, existing_content).generate
+ Security::CiConfiguration::SastBuildAction.new(project.auto_devops_enabled?, params, existing_content, project.ci_config_path).generate
end
def next_branch
diff --git a/app/services/security/ci_configuration/sast_iac_create_service.rb b/app/services/security/ci_configuration/sast_iac_create_service.rb
index 80e9cf963da..fbc65484216 100644
--- a/app/services/security/ci_configuration/sast_iac_create_service.rb
+++ b/app/services/security/ci_configuration/sast_iac_create_service.rb
@@ -6,7 +6,8 @@ module Security
private
def action
- Security::CiConfiguration::SastIacBuildAction.new(project.auto_devops_enabled?, existing_gitlab_ci_content).generate
+ Security::CiConfiguration::SastIacBuildAction.new(project.auto_devops_enabled?, existing_gitlab_ci_content,
+ project.ci_config_path).generate
end
def next_branch
diff --git a/app/services/security/ci_configuration/secret_detection_create_service.rb b/app/services/security/ci_configuration/secret_detection_create_service.rb
index ff3458d36fc..ca5138b6ed6 100644
--- a/app/services/security/ci_configuration/secret_detection_create_service.rb
+++ b/app/services/security/ci_configuration/secret_detection_create_service.rb
@@ -6,7 +6,8 @@ module Security
private
def action
- Security::CiConfiguration::SecretDetectionBuildAction.new(project.auto_devops_enabled?, existing_gitlab_ci_content).generate
+ Security::CiConfiguration::SecretDetectionBuildAction.new(project.auto_devops_enabled?, existing_gitlab_ci_content,
+ project.ci_config_path).generate
end
def next_branch
diff --git a/app/services/security/merge_reports_service.rb b/app/services/security/merge_reports_service.rb
index 5f6f98a3c39..a982ec7efe2 100644
--- a/app/services/security/merge_reports_service.rb
+++ b/app/services/security/merge_reports_service.rb
@@ -21,7 +21,10 @@ module Security
source_reports.first.type,
source_reports.first.pipeline,
source_reports.first.created_at
- ).tap { |report| report.errors = source_reports.flat_map(&:errors) }
+ ).tap do |report|
+ report.errors = source_reports.flat_map(&:errors)
+ report.warnings = source_reports.flat_map(&:warnings)
+ end
end
def copy_resources_to_target_report
diff --git a/app/services/spam/spam_action_service.rb b/app/services/spam/spam_action_service.rb
index 2a28b66f09b..4fa9c0e4993 100644
--- a/app/services/spam/spam_action_service.rb
+++ b/app/services/spam/spam_action_service.rb
@@ -65,22 +65,19 @@ module Spam
# ask the SpamVerdictService what to do with the target.
spam_verdict_service.execute.tap do |result|
case result
- when CONDITIONAL_ALLOW
- # at the moment, this means "ask for reCAPTCHA"
- create_spam_log
-
- break if target.allow_possible_spam?
-
- target.needs_recaptcha!
- when DISALLOW
- # TODO: remove `unless target.allow_possible_spam?` once this flag has been passed to `SpamVerdictService`
- # https://gitlab.com/gitlab-org/gitlab/-/issues/214739
- target.spam! unless target.allow_possible_spam?
- create_spam_log
when BLOCK_USER
# TODO: improve BLOCK_USER handling, non-existent until now
# https://gitlab.com/gitlab-org/gitlab/-/issues/329666
- target.spam! unless target.allow_possible_spam?
+ target.spam!
+ create_spam_log
+ when DISALLOW
+ target.spam!
+ create_spam_log
+ when CONDITIONAL_ALLOW
+ # This means "require a CAPTCHA to be solved"
+ target.needs_recaptcha!
+ create_spam_log
+ when OVERRIDE_VIA_ALLOW_POSSIBLE_SPAM
create_spam_log
when ALLOW
target.clear_spam_flags!
diff --git a/app/services/spam/spam_constants.rb b/app/services/spam/spam_constants.rb
index b654fbbbcc8..d300525710c 100644
--- a/app/services/spam/spam_constants.rb
+++ b/app/services/spam/spam_constants.rb
@@ -2,11 +2,12 @@
module Spam
module SpamConstants
- CONDITIONAL_ALLOW = "conditional_allow"
- DISALLOW = "disallow"
- ALLOW = "allow"
- BLOCK_USER = "block"
- NOOP = "noop"
+ BLOCK_USER = 'block'
+ DISALLOW = 'disallow'
+ CONDITIONAL_ALLOW = 'conditional_allow'
+ OVERRIDE_VIA_ALLOW_POSSIBLE_SPAM = 'override_via_allow_possible_spam'
+ ALLOW = 'allow'
+ NOOP = 'noop'
SUPPORTED_VERDICTS = {
BLOCK_USER => {
@@ -18,11 +19,14 @@ module Spam
CONDITIONAL_ALLOW => {
priority: 3
},
- ALLOW => {
+ OVERRIDE_VIA_ALLOW_POSSIBLE_SPAM => {
priority: 4
},
- NOOP => {
+ ALLOW => {
priority: 5
+ },
+ NOOP => {
+ priority: 6
}
}.freeze
end
diff --git a/app/services/spam/spam_params.rb b/app/services/spam/spam_params.rb
index ccc17a42f01..81db6b390b2 100644
--- a/app/services/spam/spam_params.rb
+++ b/app/services/spam/spam_params.rb
@@ -25,6 +25,7 @@ module Spam
# then the spam check may fail, or the SpamLog or UserAgentDetail may have missing fields.
class SpamParams
def self.new_from_request(request:)
+ self.normalize_grape_request_headers(request: request)
self.new(
captcha_response: request.headers['X-GitLab-Captcha-Response'],
spam_log_id: request.headers['X-GitLab-Spam-Log-Id'],
@@ -52,5 +53,14 @@ module Spam
other.user_agent == user_agent &&
other.referer == referer
end
+
+ def self.normalize_grape_request_headers(request:)
+ # If needed, make a normalized copy of Grape headers with the case of 'GitLab' (with an
+ # uppercase 'L') instead of 'Gitlab' (with a lowercase 'l'), because Grape header helper keys
+ # are "coerced into a capitalized kebab case". See https://github.com/ruby-grape/grape#request
+ %w[X-Gitlab-Captcha-Response X-Gitlab-Spam-Log-Id].each do |header|
+ request.headers[header.gsub('Gitlab', 'GitLab')] = request.headers[header] if request.headers.key?(header)
+ end
+ end
end
end
diff --git a/app/services/spam/spam_verdict_service.rb b/app/services/spam/spam_verdict_service.rb
index c8bdcf4310b..e73b2666c02 100644
--- a/app/services/spam/spam_verdict_service.rb
+++ b/app/services/spam/spam_verdict_service.rb
@@ -39,21 +39,24 @@ module Spam
return ALLOW unless valid_results.any?
# Favour the most restrictive result.
- final_verdict = valid_results.min_by { |v| SUPPORTED_VERDICTS[v][:priority] }
+ verdict = valid_results.min_by { |v| SUPPORTED_VERDICTS[v][:priority] }
+
+ # The target can override the verdict via the `allow_possible_spam` feature flag
+ verdict = OVERRIDE_VIA_ALLOW_POSSIBLE_SPAM if override_via_allow_possible_spam?(verdict: verdict)
logger.info(class: self.class.name,
akismet_verdict: akismet_verdict,
spam_check_verdict: original_spamcheck_result,
extra_attributes: spamcheck_attribs,
spam_check_rtt: external_spam_check_round_trip_time.real,
- final_verdict: final_verdict,
+ final_verdict: verdict,
username: user.username,
user_id: user.id,
target_type: target.class.to_s,
project_id: target.project_id
)
- final_verdict
+ verdict
end
private
@@ -87,6 +90,14 @@ module Spam
end
end
+ def override_via_allow_possible_spam?(verdict:)
+ # If the verdict is already going to allow (because current verdict's priority value is greater
+ # than the override verdict's priority value), then we don't need to override it.
+ return false if SUPPORTED_VERDICTS[verdict][:priority] > SUPPORTED_VERDICTS[OVERRIDE_VIA_ALLOW_POSSIBLE_SPAM][:priority]
+
+ target.allow_possible_spam?
+ end
+
def spamcheck_client
@spamcheck_client ||= Gitlab::Spamcheck::Client.new
end
diff --git a/app/services/system_note_service.rb b/app/services/system_note_service.rb
index 1f1edad7a69..9db39a5e174 100644
--- a/app/services/system_note_service.rb
+++ b/app/services/system_note_service.rb
@@ -49,12 +49,12 @@ module SystemNoteService
::SystemNotes::IssuablesService.new(noteable: issuable, project: project, author: author).change_issuable_contacts(added_count, removed_count)
end
- def relate_issue(noteable, noteable_ref, user)
- ::SystemNotes::IssuablesService.new(noteable: noteable, project: noteable.project, author: user).relate_issue(noteable_ref)
+ def relate_issuable(noteable, noteable_ref, user)
+ ::SystemNotes::IssuablesService.new(noteable: noteable, project: noteable.project, author: user).relate_issuable(noteable_ref)
end
- def unrelate_issue(noteable, noteable_ref, user)
- ::SystemNotes::IssuablesService.new(noteable: noteable, project: noteable.project, author: user).unrelate_issue(noteable_ref)
+ def unrelate_issuable(noteable, noteable_ref, user)
+ ::SystemNotes::IssuablesService.new(noteable: noteable, project: noteable.project, author: user).unrelate_issuable(noteable_ref)
end
# Called when the due_date of a Noteable is changed
diff --git a/app/services/system_notes/issuables_service.rb b/app/services/system_notes/issuables_service.rb
index 09f36bb6501..89212288a6b 100644
--- a/app/services/system_notes/issuables_service.rb
+++ b/app/services/system_notes/issuables_service.rb
@@ -10,8 +10,9 @@ module SystemNotes
# "marked this issue as related to gitlab-foss#9001"
#
# Returns the created Note object
- def relate_issue(noteable_ref)
- body = "marked this issue as related to #{noteable_ref.to_reference(noteable.project)}"
+ def relate_issuable(noteable_ref)
+ issuable_type = noteable.to_ability_name.humanize(capitalize: false)
+ body = "marked this #{issuable_type} as related to #{noteable_ref.to_reference(noteable.resource_parent)}"
issue_activity_counter.track_issue_related_action(author: author) if noteable.is_a?(Issue)
@@ -26,8 +27,8 @@ module SystemNotes
# "removed the relation with gitlab-foss#9001"
#
# Returns the created Note object
- def unrelate_issue(noteable_ref)
- body = "removed the relation with #{noteable_ref.to_reference(noteable.project)}"
+ def unrelate_issuable(noteable_ref)
+ body = "removed the relation with #{noteable_ref.to_reference(noteable.resource_parent)}"
issue_activity_counter.track_issue_unrelated_action(author: author) if noteable.is_a?(Issue)
@@ -160,6 +161,7 @@ module SystemNotes
body = "changed title from **#{marked_old_title}** to **#{marked_new_title}**"
issue_activity_counter.track_issue_title_changed_action(author: author) if noteable.is_a?(Issue)
+ work_item_activity_counter.track_work_item_title_changed_action(author: author) if noteable.is_a?(WorkItem)
create_note(NoteSummary.new(noteable, project, author, body, action: 'title'))
end
@@ -484,6 +486,10 @@ module SystemNotes
Gitlab::UsageDataCounters::IssueActivityUniqueCounter
end
+ def work_item_activity_counter
+ Gitlab::UsageDataCounters::WorkItemActivityUniqueCounter
+ end
+
def track_cross_reference_action
issue_activity_counter.track_issue_cross_referenced_action(author: author) if noteable.is_a?(Issue)
end
diff --git a/app/services/todo_service.rb b/app/services/todo_service.rb
index 091f441831a..64309c7f786 100644
--- a/app/services/todo_service.rb
+++ b/app/services/todo_service.rb
@@ -9,6 +9,7 @@
#
class TodoService
include Gitlab::Utils::UsageData
+
# When create an issue we should:
#
# * create a todo for assignee if issue is assigned
@@ -229,8 +230,24 @@ class TodoService
return if users.empty?
- users_with_pending_todos = pending_todos(users, attributes).distinct_user_ids
- users.reject! { |user| users_with_pending_todos.include?(user.id) && Feature.disabled?(:multiple_todos, user) }
+ users_single_todos, users_multiple_todos = users.partition { |u| Feature.disabled?(:multiple_todos, u) }
+ excluded_user_ids = []
+
+ if users_single_todos.present?
+ excluded_user_ids += pending_todos(
+ users_single_todos,
+ attributes.slice(:project_id, :target_id, :target_type, :commit_id, :discussion)
+ ).distinct_user_ids
+ end
+
+ if users_multiple_todos.present? && !Todo::ACTIONS_MULTIPLE_ALLOWED.include?(attributes.fetch(:action))
+ excluded_user_ids += pending_todos(
+ users_multiple_todos,
+ attributes.slice(:project_id, :target_id, :target_type, :commit_id, :discussion, :action)
+ ).distinct_user_ids
+ end
+
+ users.reject! { |user| excluded_user_ids.include?(user.id) }
todos = users.map do |user|
issue_type = attributes.delete(:issue_type)
diff --git a/app/services/users/migrate_to_ghost_user_service.rb b/app/services/users/migrate_to_ghost_user_service.rb
index 575614e8743..604b83f621f 100644
--- a/app/services/users/migrate_to_ghost_user_service.rb
+++ b/app/services/users/migrate_to_ghost_user_service.rb
@@ -66,20 +66,20 @@ module Users
# rubocop: disable CodeReuse/ActiveRecord
def migrate_issues
- user.issues.update_all(author_id: ghost_user.id)
- Issue.where(last_edited_by_id: user.id).update_all(last_edited_by_id: ghost_user.id)
+ batched_migrate(Issue, :author_id)
+ batched_migrate(Issue, :last_edited_by_id)
end
# rubocop: enable CodeReuse/ActiveRecord
# rubocop: disable CodeReuse/ActiveRecord
def migrate_merge_requests
- user.merge_requests.update_all(author_id: ghost_user.id)
- MergeRequest.where(merge_user_id: user.id).update_all(merge_user_id: ghost_user.id)
+ batched_migrate(MergeRequest, :author_id)
+ batched_migrate(MergeRequest, :merge_user_id)
end
# rubocop: enable CodeReuse/ActiveRecord
def migrate_notes
- user.notes.update_all(author_id: ghost_user.id)
+ batched_migrate(Note, :author_id)
end
def migrate_abuse_reports
@@ -96,8 +96,17 @@ module Users
end
def migrate_reviews
- user.reviews.update_all(author_id: ghost_user.id)
+ batched_migrate(Review, :author_id)
end
+
+ # rubocop:disable CodeReuse/ActiveRecord
+ def batched_migrate(base_scope, column)
+ loop do
+ update_count = base_scope.where(column => user.id).limit(100).update_all(column => ghost_user.id)
+ break if update_count == 0
+ end
+ end
+ # rubocop:enable CodeReuse/ActiveRecord
end
end
diff --git a/app/services/users/saved_replies/create_service.rb b/app/services/users/saved_replies/create_service.rb
new file mode 100644
index 00000000000..21378ec4435
--- /dev/null
+++ b/app/services/users/saved_replies/create_service.rb
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+module Users
+ module SavedReplies
+ class CreateService
+ def initialize(current_user:, name:, content:)
+ @current_user = current_user
+ @name = name
+ @content = content
+ end
+
+ def execute
+ saved_reply = saved_replies.build(name: name, content: content)
+
+ if saved_reply.save
+ ServiceResponse.success(payload: { saved_reply: saved_reply })
+ else
+ ServiceResponse.error(message: saved_reply.errors.full_messages)
+ end
+ end
+
+ private
+
+ attr_reader :current_user, :name, :content
+
+ delegate :saved_replies, to: :current_user
+ end
+ end
+end
diff --git a/app/services/users/saved_replies/update_service.rb b/app/services/users/saved_replies/update_service.rb
new file mode 100644
index 00000000000..ab0a3eaf87d
--- /dev/null
+++ b/app/services/users/saved_replies/update_service.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+module Users
+ module SavedReplies
+ class UpdateService
+ def initialize(current_user:, saved_reply:, name:, content:)
+ @current_user = current_user
+ @saved_reply = saved_reply
+ @name = name
+ @content = content
+ end
+
+ def execute
+ if saved_reply.update(name: name, content: content)
+ ServiceResponse.success(payload: { saved_reply: saved_reply.reset })
+ else
+ ServiceResponse.error(message: saved_reply.errors.full_messages)
+ end
+ end
+
+ private
+
+ attr_reader :current_user, :saved_reply, :name, :content
+ end
+ end
+end
diff --git a/app/services/web_hooks/log_execution_service.rb b/app/services/web_hooks/log_execution_service.rb
index 6e58e15f093..0ee7c41469f 100644
--- a/app/services/web_hooks/log_execution_service.rb
+++ b/app/services/web_hooks/log_execution_service.rb
@@ -2,34 +2,86 @@
module WebHooks
class LogExecutionService
+ include ::Gitlab::ExclusiveLeaseHelpers
+
+ LOCK_TTL = 15.seconds.freeze
+ LOCK_SLEEP = 0.25.seconds.freeze
+ LOCK_RETRY = 65
+
attr_reader :hook, :log_data, :response_category
def initialize(hook:, log_data:, response_category:)
@hook = hook
- @log_data = log_data
+ @log_data = log_data.transform_keys(&:to_sym)
@response_category = response_category
+ @prev_state = hook.active_state(ignore_flag: true)
end
def execute
- update_hook_executability
+ update_hook_failure_state
log_execution
end
private
def log_execution
- WebHookLog.create!(web_hook: hook, **log_data.transform_keys(&:to_sym))
+ WebHookLog.create!(web_hook: hook, **log_data)
end
- def update_hook_executability
- case response_category
- when :ok
- hook.enable!
- when :error
- hook.backoff!
- when :failed
- hook.failed!
+ # Perform this operation within an `Gitlab::ExclusiveLease` lock to make it
+ # safe to be called concurrently from different workers.
+ def update_hook_failure_state
+ in_lock(lock_name, ttl: LOCK_TTL, sleep_sec: LOCK_SLEEP, retries: LOCK_RETRY) do |retried|
+ hook.reset # Reload within the lock so properties are guaranteed to be current.
+
+ case response_category
+ when :ok
+ hook.enable!
+ when :error
+ hook.backoff!
+ when :failed
+ hook.failed!
+ end
+
+ log_state_change
end
+ rescue Gitlab::ExclusiveLeaseHelpers::FailedToObtainLockError
+ raise if raise_lock_error?
+ end
+
+ def log_state_change
+ new_state = hook.active_state(ignore_flag: true)
+
+ return if @prev_state == new_state
+
+ Gitlab::AuthLogger.info(
+ message: 'WebHook change active_state',
+ # identification
+ hook_id: hook.id,
+ hook_type: hook.type,
+ project_id: hook.project_id,
+ group_id: hook.group_id,
+ # relevant data
+ prev_state: @prev_state,
+ new_state: new_state,
+ duration: log_data[:execution_duration],
+ response_status: log_data[:response_status],
+ recent_hook_failures: hook.recent_failures,
+ # context
+ **Gitlab::ApplicationContext.current
+ )
+ end
+
+ def lock_name
+ "web_hooks:update_hook_failure_state:#{hook.id}"
+ end
+
+ # Allow an error to be raised after failing to obtain a lease only if the hook
+ # is not already in the correct failure state.
+ def raise_lock_error?
+ hook.reset # Reload so properties are guaranteed to be current.
+
+ hook.executable? != (response_category == :ok)
end
end
end
diff --git a/app/services/work_items/create_and_link_service.rb b/app/services/work_items/create_and_link_service.rb
new file mode 100644
index 00000000000..534d220a846
--- /dev/null
+++ b/app/services/work_items/create_and_link_service.rb
@@ -0,0 +1,43 @@
+# frozen_string_literal: true
+
+module WorkItems
+ # Create and link operations are not run inside a transaction in this class
+ # because CreateFromTaskService also creates a transaction.
+ # This class should always be run inside a transaction as we could end up with
+ # new work items that were never associated with other work items as expected.
+ class CreateAndLinkService
+ def initialize(project:, current_user: nil, params: {}, spam_params:, link_params: {})
+ @create_service = CreateService.new(
+ project: project,
+ current_user: current_user,
+ params: params,
+ spam_params: spam_params
+ )
+ @project = project
+ @current_user = current_user
+ @link_params = link_params
+ end
+
+ def execute
+ create_result = @create_service.execute
+ return create_result if create_result.error?
+
+ work_item = create_result[:work_item]
+ return ::ServiceResponse.success(payload: payload(work_item)) if @link_params.blank?
+
+ result = IssueLinks::CreateService.new(work_item, @current_user, @link_params).execute
+
+ if result[:status] == :success
+ ::ServiceResponse.success(payload: payload(work_item))
+ else
+ ::ServiceResponse.error(message: result[:message], http_status: 404)
+ end
+ end
+
+ private
+
+ def payload(work_item)
+ { work_item: work_item }
+ end
+ end
+end
diff --git a/app/services/work_items/create_from_task_service.rb b/app/services/work_items/create_from_task_service.rb
new file mode 100644
index 00000000000..4203c96e676
--- /dev/null
+++ b/app/services/work_items/create_from_task_service.rb
@@ -0,0 +1,50 @@
+# frozen_string_literal: true
+
+module WorkItems
+ class CreateFromTaskService
+ def initialize(work_item:, current_user: nil, work_item_params: {}, spam_params:)
+ @work_item = work_item
+ @current_user = current_user
+ @work_item_params = work_item_params
+ @spam_params = spam_params
+ @errors = []
+ end
+
+ def execute
+ transaction_result = ApplicationRecord.transaction do
+ create_and_link_result = CreateAndLinkService.new(
+ project: @work_item.project,
+ current_user: @current_user,
+ params: @work_item_params.slice(:title, :work_item_type_id),
+ spam_params: @spam_params,
+ link_params: { target_issuable: @work_item }
+ ).execute
+
+ if create_and_link_result.error?
+ @errors += create_and_link_result.errors
+ raise ActiveRecord::Rollback
+ end
+
+ replacement_result = TaskListReferenceReplacementService.new(
+ work_item: @work_item,
+ work_item_reference: create_and_link_result[:work_item].to_reference,
+ line_number_start: @work_item_params[:line_number_start],
+ line_number_end: @work_item_params[:line_number_end],
+ title: @work_item_params[:title],
+ lock_version: @work_item_params[:lock_version]
+ ).execute
+
+ if replacement_result.error?
+ @errors += replacement_result.errors
+ raise ActiveRecord::Rollback
+ end
+
+ create_and_link_result
+ end
+
+ return transaction_result if transaction_result
+
+ ::ServiceResponse.error(message: @errors, http_status: 422)
+ end
+ end
+end
diff --git a/app/services/work_items/task_list_reference_replacement_service.rb b/app/services/work_items/task_list_reference_replacement_service.rb
new file mode 100644
index 00000000000..1044a4feb88
--- /dev/null
+++ b/app/services/work_items/task_list_reference_replacement_service.rb
@@ -0,0 +1,52 @@
+# frozen_string_literal: true
+
+module WorkItems
+ class TaskListReferenceReplacementService
+ STALE_OBJECT_MESSAGE = 'Stale work item. Check lock version'
+
+ def initialize(work_item:, work_item_reference:, line_number_start:, line_number_end:, title:, lock_version:)
+ @work_item = work_item
+ @work_item_reference = work_item_reference
+ @line_number_start = line_number_start
+ @line_number_end = line_number_end
+ @title = title
+ @lock_version = lock_version
+ end
+
+ def execute
+ return ::ServiceResponse.error(message: STALE_OBJECT_MESSAGE) if @work_item.lock_version > @lock_version
+ return ::ServiceResponse.error(message: 'line_number_start must be greater than 0') if @line_number_start < 1
+ return ::ServiceResponse.error(message: 'line_number_end must be greater or equal to line_number_start') if @line_number_end < @line_number_start
+ return ::ServiceResponse.error(message: "Work item description can't be blank") if @work_item.description.blank?
+
+ source_lines = @work_item.description.split("\n")
+ markdown_task_first_line = source_lines[@line_number_start - 1]
+ task_line = Taskable::ITEM_PATTERN.match(markdown_task_first_line)
+
+ return ::ServiceResponse.error(message: "Unable to detect a task on line #{@line_number_start}") unless task_line
+
+ captures = task_line.captures
+
+ markdown_task_first_line.sub!(Taskable::ITEM_PATTERN, "#{captures[0]} #{captures[1]} #{@work_item_reference}+")
+
+ source_lines[@line_number_start - 1] = markdown_task_first_line
+ remove_additional_lines!(source_lines)
+
+ @work_item.update!(description: source_lines.join("\n"))
+
+ ::ServiceResponse.success
+ rescue ActiveRecord::StaleObjectError
+ ::ServiceResponse.error(message: STALE_OBJECT_MESSAGE)
+ end
+
+ private
+
+ def remove_additional_lines!(source_lines)
+ return if @line_number_end <= @line_number_start
+
+ source_lines.delete_if.each_with_index do |_line, index|
+ index >= @line_number_start && index < @line_number_end
+ end
+ end
+ end
+end
diff --git a/app/uploaders/content_type_whitelist.rb b/app/uploaders/content_type_whitelist.rb
index 64bde16cb69..82c6b9b3a61 100644
--- a/app/uploaders/content_type_whitelist.rb
+++ b/app/uploaders/content_type_whitelist.rb
@@ -30,7 +30,7 @@ module ContentTypeWhitelist
content_type = mime_magic_content_type(new_file.path)
unless whitelisted_content_type?(content_type)
- message = I18n.translate(:"errors.messages.content_type_whitelist_error", allowed_types: Array(content_type_whitelist).join(", "))
+ message = I18n.t(:"errors.messages.content_type_whitelist_error", allowed_types: Array(content_type_whitelist).join(", "))
raise CarrierWave::IntegrityError, message
end
end
diff --git a/app/validators/color_validator.rb b/app/validators/color_validator.rb
index 974dfbbf394..d108e4c5426 100644
--- a/app/validators/color_validator.rb
+++ b/app/validators/color_validator.rb
@@ -12,11 +12,13 @@
# end
#
class ColorValidator < ActiveModel::EachValidator
- PATTERN = /\A\#(?:[0-9A-Fa-f]{3}){1,2}\Z/.freeze
-
def validate_each(record, attribute, value)
- unless value =~ PATTERN
- record.errors.add(attribute, "must be a valid color code")
+ case value
+ when NilClass then return
+ when ::Gitlab::Color then return if value.valid?
+ when ::String then return if ::Gitlab::Color.new(value).valid?
end
+
+ record.errors.add(attribute, "must be a valid color code")
end
end
diff --git a/app/validators/import/gitlab_projects/remote_file_validator.rb b/app/validators/import/gitlab_projects/remote_file_validator.rb
new file mode 100644
index 00000000000..67bf102e928
--- /dev/null
+++ b/app/validators/import/gitlab_projects/remote_file_validator.rb
@@ -0,0 +1,45 @@
+# frozen_string_literal: true
+
+module Import
+ module GitlabProjects
+ # Validates the given object's #content_type and #content_length accordingly
+ # with the Project Import requirements
+ class RemoteFileValidator < ActiveModel::Validator
+ FILE_SIZE_LIMIT = 10.gigabytes
+ ALLOWED_CONTENT_TYPES = [
+ 'application/gzip',
+ # S3 uses different file types
+ 'application/x-tar',
+ 'application/x-gzip'
+ ].freeze
+
+ def validate(record)
+ validate_content_length(record)
+ validate_content_type(record)
+ end
+
+ private
+
+ def validate_content_length(record)
+ if record.content_length.to_i <= 0
+ record.errors.add(:content_length, :size_too_small, file_size: humanize(1.byte))
+ elsif record.content_length > FILE_SIZE_LIMIT
+ record.errors.add(:content_length, :size_too_big, file_size: humanize(FILE_SIZE_LIMIT))
+ end
+ end
+
+ def humanize(number)
+ ActiveSupport::NumberHelper.number_to_human_size(number)
+ end
+
+ def validate_content_type(record)
+ return if ALLOWED_CONTENT_TYPES.include?(record.content_type)
+
+ record.errors.add(:content_type, "'%{content_type}' not allowed. (Allowed: %{allowed})" % {
+ content_type: record.content_type,
+ allowed: ALLOWED_CONTENT_TYPES.join(', ')
+ })
+ end
+ end
+ end
+end
diff --git a/app/validators/json_schemas/security_ci_configuration_schemas/sast_ui_schema.json b/app/validators/json_schemas/security_ci_configuration_schemas/sast_ui_schema.json
index 20be49f9eae..19258ee7677 100644
--- a/app/validators/json_schemas/security_ci_configuration_schemas/sast_ui_schema.json
+++ b/app/validators/json_schemas/security_ci_configuration_schemas/sast_ui_schema.json
@@ -2,8 +2,8 @@
"$schema": "http://json-schema.org/draft-07/schema#",
"global": [
{
- "field" : "SECURE_ANALYZERS_PREFIX",
- "label" : "Image prefix",
+ "field": "SECURE_ANALYZERS_PREFIX",
+ "label": "Image prefix",
"type": "string",
"default_value": "",
"value": "",
diff --git a/app/views/admin/abuse_reports/_abuse_report.html.haml b/app/views/admin/abuse_reports/_abuse_report.html.haml
index dbfc7bf1046..00e5650b551 100644
--- a/app/views/admin/abuse_reports/_abuse_report.html.haml
+++ b/app/views/admin/abuse_reports/_abuse_report.html.haml
@@ -25,9 +25,9 @@
%td
- if user
= link_to _('Remove user & report'), admin_abuse_report_path(abuse_report, remove_user: true),
- data: { confirm: _("USER %{user} WILL BE REMOVED! Are you sure?") % { user: user.name } }, remote: true, method: :delete, class: "gl-button btn btn-block btn-danger js-remove-tr"
+ data: { confirm: _("USER %{user} WILL BE REMOVED! Are you sure?") % { user: user.name }, confirm_btn_variant: "danger" }, aria: { label: _('Remove user & report') }, remote: true, method: :delete, class: "gl-button btn btn-block btn-danger js-remove-tr"
- if user && !user.blocked?
- = link_to _('Block user'), block_admin_user_path(user), data: {confirm: _('USER WILL BE BLOCKED! Are you sure?')}, method: :put, class: "gl-button btn btn-default btn-block"
+ = link_to _('Block user'), block_admin_user_path(user), data: { confirm: _('USER WILL BE BLOCKED! Are you sure?') }, aria: { label: _('Block user') }, method: :put, class: "gl-button btn btn-default btn-block"
- else
.gl-button.btn.btn-default.disabled.btn-block
= _('Already blocked')
diff --git a/app/views/admin/application_settings/_default_branch.html.haml b/app/views/admin/application_settings/_default_branch.html.haml
new file mode 100644
index 00000000000..f5f45d7a6e9
--- /dev/null
+++ b/app/views/admin/application_settings/_default_branch.html.haml
@@ -0,0 +1,17 @@
+= gitlab_ui_form_for @application_setting, url: repository_admin_application_settings_path(anchor: 'js-default-branch-name'), html: { class: 'fieldset-form' } do |f|
+ = form_errors(@application_setting)
+
+ - fallback_branch_name = "<code>#{Gitlab::DefaultBranch.value}</code>"
+
+ %fieldset
+ .form-group
+ = f.label :default_branch_name, _('Initial default branch name'), class: 'label-light'
+ = f.text_field :default_branch_name, placeholder: Gitlab::DefaultBranch.value, class: 'form-control gl-form-input'
+ %span.form-text.text-muted
+ = (s_("AdminSettings|If not specified at the group or instance level, the default is %{default_initial_branch_name}. Does not affect existing repositories.") % { default_initial_branch_name: fallback_branch_name } ).html_safe
+
+ = render 'shared/default_branch_protection', f: f
+
+ = render_if_exists 'admin/application_settings/group_owners_can_manage_default_branch_protection_setting', form: f
+
+ = f.submit _('Save changes'), class: 'gl-button btn-confirm'
diff --git a/app/views/admin/application_settings/_eks.html.haml b/app/views/admin/application_settings/_eks.html.haml
index c83e28d7f0b..d9c0a01beb0 100644
--- a/app/views/admin/application_settings/_eks.html.haml
+++ b/app/views/admin/application_settings/_eks.html.haml
@@ -22,15 +22,15 @@
= f.label :eks_account_id, _('Account ID'), class: 'label-bold'
= f.text_field :eks_account_id, class: 'form-control gl-form-input'
.form-group
- = f.label :eks_access_key_id, _('Access key ID'), class: 'label-bold'
+ = f.label :eks_access_key_id, _('AWS access key ID (Optional)'), class: 'label-bold'
= f.text_field :eks_access_key_id, class: 'form-control gl-form-input'
.form-text.text-muted
- = _('AWS Access Key. Only required if not using role instance credentials')
+ = _('Only required if not using role instance credentials.')
.form-group
- = f.label :eks_secret_access_key, _('Secret access key'), class: 'label-bold'
+ = f.label :eks_secret_access_key, _('AWS secret access key (Optional)'), class: 'label-bold'
= f.password_field :eks_secret_access_key, autocomplete: 'off', class: 'form-control gl-form-input'
.form-text.text-muted
- = _('AWS Secret Access Key. Only required if not using role instance credentials')
+ = _('Only required if not using role instance credentials.')
= f.submit _('Save changes'), class: "gl-button btn btn-confirm"
diff --git a/app/views/admin/application_settings/_initial_branch_name.html.haml b/app/views/admin/application_settings/_initial_branch_name.html.haml
deleted file mode 100644
index 8832bc02056..00000000000
--- a/app/views/admin/application_settings/_initial_branch_name.html.haml
+++ /dev/null
@@ -1,13 +0,0 @@
-= form_for @application_setting, url: repository_admin_application_settings_path(anchor: 'js-default-branch-name'), html: { class: 'fieldset-form' } do |f|
- = form_errors(@application_setting)
-
- - fallback_branch_name = "<code>#{Gitlab::DefaultBranch.value}</code>"
-
- %fieldset
- .form-group
- = f.label :default_branch_name, _('Default initial branch name'), class: 'label-light'
- = f.text_field :default_branch_name, placeholder: Gitlab::DefaultBranch.value, class: 'form-control gl-form-input'
- %span.form-text.text-muted
- = (s_("AdminSettings|If not specified at the group or instance level, the default is %{default_initial_branch_name}. Does not affect existing repositories.") % { default_initial_branch_name: fallback_branch_name } ).html_safe
-
- = f.submit _('Save changes'), class: 'gl-button btn-confirm'
diff --git a/app/views/admin/application_settings/_prometheus.html.haml b/app/views/admin/application_settings/_prometheus.html.haml
index 08befa59952..11830fac336 100644
--- a/app/views/admin/application_settings/_prometheus.html.haml
+++ b/app/views/admin/application_settings/_prometheus.html.haml
@@ -13,7 +13,7 @@
- unless Gitlab::Metrics.metrics_folder_present?
.form-text.text-muted
%strong.cred= _("WARNING:")
- = _("Environment variable %{code_start}%{environment_variable}%{code_end} does not exist or is not pointing to a valid directory.").html_safe % { environment_variable: prometheus_multiproc_dir, code_start: '<code>'.html_safe, code_end: '</code>'.html_safe }
+ = _("Environment variable %{environment_variable} does not exist or is not pointing to a valid directory.").html_safe % { environment_variable: '<code>prometheus_multiproc_dir</code>'.html_safe }
= link_to sprite_icon('question-o'), help_page_path('administration/monitoring/prometheus/gitlab_metrics', anchor: 'metrics-shared-directory')
.form-group
= f.label :metrics_method_call_threshold, _('Method call threshold (ms)'), class: 'label-bold'
diff --git a/app/views/admin/application_settings/_registry.html.haml b/app/views/admin/application_settings/_registry.html.haml
index b55c2f05300..364a7cf5a8e 100644
--- a/app/views/admin/application_settings/_registry.html.haml
+++ b/app/views/admin/application_settings/_registry.html.haml
@@ -30,5 +30,13 @@
= f.number_field :container_registry_cleanup_tags_service_max_list_size, min: 0, class: 'form-control'
.form-text.text-muted
= _("The maximum number of tags that a single worker accepts for cleanup. If the number of tags goes above this limit, the list of tags to delete is truncated to this number. To remove this limit, set it to 0.")
+ .form-group
+ .form-check
+ = f.check_box :container_registry_expiration_policies_caching, class: 'form-check-input'
+ = f.label :container_registry_expiration_policies_caching, class: 'form-check-label' do
+ = _("Enable container expiration caching.")
+ .form-text.text-muted
+ = _("When enabled, cleanup polices execute faster but put more load on Redis.")
+ = link_to sprite_icon('question-o'), help_page_path('user/packages/container_registry/reduce_container_registry_storage', anchor: 'set-cleanup-limits-to-conserve-resources')
= f.submit _('Save changes'), class: "gl-button btn btn-confirm"
diff --git a/app/views/admin/application_settings/_search_limits.html.haml b/app/views/admin/application_settings/_search_limits.html.haml
new file mode 100644
index 00000000000..945c9397f0d
--- /dev/null
+++ b/app/views/admin/application_settings/_search_limits.html.haml
@@ -0,0 +1,16 @@
+= form_for @application_setting, url: network_admin_application_settings_path(anchor: 'js-search-limits-settings'), html: { class: 'fieldset-form' } do |f|
+ = form_errors(@application_setting)
+
+ %fieldset
+ .form-group
+ = f.label :search_rate_limit, _('Maximum number of requests per minute for an authenticated user'), class: 'label-bold'
+ .form-text.gl-text-gray-600
+ = _("Set this number to 0 to disable the limit.")
+ = f.number_field :search_rate_limit, class: 'form-control gl-form-input'
+
+ .form-group
+ = f.label :search_rate_limit_unauthenticated, _('Maximum number of requests per minute for an unauthenticated IP address'), class: 'label-bold'
+ = f.number_field :search_rate_limit_unauthenticated, class: 'form-control gl-form-input'
+
+
+ = f.submit _('Save changes'), class: "gl-button btn btn-confirm", data: { qa_selector: 'save_changes_button' }
diff --git a/app/views/admin/application_settings/_signin.html.haml b/app/views/admin/application_settings/_signin.html.haml
index 156e7d3fb76..bce210d28d3 100644
--- a/app/views/admin/application_settings/_signin.html.haml
+++ b/app/views/admin/application_settings/_signin.html.haml
@@ -8,17 +8,17 @@
= f.label :password_authentication_enabled_for_web, class: 'form-check-label' do
= _('Allow password authentication for the web interface')
.form-text.text-muted
- = _('When inactive, an external authentication provider must be used.')
+ = _('Clear this checkbox to use an external authentication provider instead.')
.form-group
.form-check
= f.check_box :password_authentication_enabled_for_git, class: 'form-check-input'
= f.label :password_authentication_enabled_for_git, class: 'form-check-label' do
= _('Allow password authentication for Git over HTTP(S)')
.form-text.text-muted
- When inactive, a Personal Access Token
- if Gitlab::Auth::Ldap::Config.enabled?
- or LDAP password
- must be used to authenticate.
+ = _('Clear this checkbox to use a personal access token or LDAP password instead.')
+ - else
+ = _('Clear this checkbox to use a personal access token instead.')
- if omniauth_enabled? && button_based_providers.any?
%fieldset.form-group
%legend.gl-font-base.gl-mb-3.gl-border-none.gl-font-weight-bold= _('Enabled OAuth authentication sources')
diff --git a/app/views/admin/application_settings/_sourcegraph.html.haml b/app/views/admin/application_settings/_sourcegraph.html.haml
index b92cf7b156a..65b2a95bcc1 100644
--- a/app/views/admin/application_settings/_sourcegraph.html.haml
+++ b/app/views/admin/application_settings/_sourcegraph.html.haml
@@ -12,7 +12,7 @@
- link_end = "#{sprite_icon('external-link', size: 12, css_class: 'ml-1 vertical-align-center')}</a>".html_safe
= s_('SourcegraphAdmin|Enable code intelligence powered by %{link_start}Sourcegraph%{link_end} on your GitLab instance\'s code views and merge requests.').html_safe % { link_start: link_start, link_end: link_end }
%span
- = link_to s_('SourcegraphAdmin|More information'), help_page_path('integration/sourcegraph.md'), target: '_blank', rel: 'noopener noreferrer'
+ = link_to s_('SourcegraphAdmin|Learn more.'), help_page_path('integration/sourcegraph.md'), target: '_blank', rel: 'noopener noreferrer'
.settings-content
@@ -29,10 +29,10 @@
= f.check_box :sourcegraph_public_only, class: 'form-check-input'
= f.label :sourcegraph_public_only, s_('SourcegraphAdmin|Block on private and internal projects'), class: 'form-check-label'
.form-text.text-muted
- = s_('SourcegraphAdmin|If checked, only public projects will have code intelligence and communicate with Sourcegraph.')
+ = s_('SourcegraphAdmin|Only public projects have code intelligence enabled and communicate with Sourcegraph.')
.form-group
= f.label :sourcegraph_url, s_('SourcegraphAdmin|Sourcegraph URL'), class: 'label-bold'
- = f.text_field :sourcegraph_url, class: 'form-control gl-form-input', placeholder: s_('SourcegraphAdmin|e.g. https://sourcegraph.example.com')
+ = f.text_field :sourcegraph_url, class: 'form-control gl-form-input', placeholder: s_('SourcegraphAdmin|https://sourcegraph.example.com')
.form-text.text-muted
= s_('SourcegraphAdmin|Configure the URL to a Sourcegraph instance which can read your GitLab projects.')
= f.submit s_('SourcegraphAdmin|Save changes'), class: 'gl-button btn btn-confirm'
diff --git a/app/views/admin/application_settings/_usage.html.haml b/app/views/admin/application_settings/_usage.html.haml
index 326aae26d5e..02031880fab 100644
--- a/app/views/admin/application_settings/_usage.html.haml
+++ b/app/views/admin/application_settings/_usage.html.haml
@@ -27,7 +27,7 @@
%p.mb-2= s_('%{service_ping_link_start}What information is shared with GitLab Inc.?%{service_ping_link_end}').html_safe % { service_ping_link_start: service_ping_link_start, service_ping_link_end: '</a>'.html_safe }
%button.gl-button.btn.btn-default.js-payload-preview-trigger{ type: 'button', data: { payload_selector: ".#{payload_class}" } }
- .gl-spinner.js-spinner.gl-display-none.gl-mr-2
+ = gl_loading_icon(css_class: 'js-spinner gl-display-none gl-mr-2')
.js-text.gl-display-inline= _('Preview payload')
%pre.service-data-payload-container.js-syntax-highlight.code.highlight.gl-mt-2.gl-display-none{ class: payload_class, data: { endpoint: usage_data_admin_application_settings_path(format: :html) } }
- else
diff --git a/app/views/admin/application_settings/_visibility_and_access.html.haml b/app/views/admin/application_settings/_visibility_and_access.html.haml
index e56c898b236..b0810d3d48a 100644
--- a/app/views/admin/application_settings/_visibility_and_access.html.haml
+++ b/app/views/admin/application_settings/_visibility_and_access.html.haml
@@ -2,9 +2,6 @@
= form_errors(@application_setting)
%fieldset
- = render 'shared/default_branch_protection', f: f
- = render_if_exists 'admin/application_settings/group_owners_can_manage_default_branch_protection_setting', form: f
-
= render 'shared/project_creation_levels', f: f, method: :default_project_creation, legend: s_('ProjectCreationLevel|Default project creation protection')
= render_if_exists 'admin/application_settings/default_project_deletion_protection_setting', form: f
= render_if_exists 'admin/application_settings/default_delayed_project_deletion_setting', form: f
diff --git a/app/views/admin/application_settings/appearances/_form.html.haml b/app/views/admin/application_settings/appearances/_form.html.haml
index 0f7f0109a54..84c26da8772 100644
--- a/app/views/admin/application_settings/appearances/_form.html.haml
+++ b/app/views/admin/application_settings/appearances/_form.html.haml
@@ -16,7 +16,7 @@
= image_tag @appearance.header_logo_path, class: 'appearance-light-logo-preview'
- if @appearance.persisted?
%br
- = link_to _('Remove header logo'), header_logos_admin_application_settings_appearances_path, data: { confirm: _("Header logo will be removed. Are you sure?") }, method: :delete, class: "btn gl-button btn-danger btn-danger-secondary btn-sm"
+ = link_to _('Remove header logo'), header_logos_admin_application_settings_appearances_path, data: { confirm: _("Header logo will be removed. Are you sure?"), confirm_btn_variant: "danger" }, aria: { label: _('Remove header logo') }, method: :delete, class: "btn gl-button btn-danger btn-danger-secondary btn-sm"
%hr
= f.hidden_field :header_logo_cache
= f.file_field :header_logo, class: "", accept: 'image/*'
@@ -35,7 +35,7 @@
= image_tag @appearance.favicon_path, class: 'appearance-light-logo-preview'
- if @appearance.persisted?
%br
- = link_to _('Remove favicon'), favicon_admin_application_settings_appearances_path, data: { confirm: _("Favicon will be removed. Are you sure?") }, method: :delete, class: "btn gl-button btn-danger btn-danger-secondary btn-sm"
+ = link_to _('Remove favicon'), favicon_admin_application_settings_appearances_path, data: { confirm: _("Favicon will be removed. Are you sure?"), confirm_btn_variant: "danger" }, aria: { label: _('Remove favicon') }, method: :delete, class: "btn gl-button btn-danger btn-danger-secondary btn-sm"
%hr
= f.hidden_field :favicon_cache
= f.file_field :favicon, class: '', accept: 'image/*'
@@ -67,7 +67,7 @@
= image_tag @appearance.logo_path, class: 'appearance-logo-preview'
- if @appearance.persisted?
%br
- = link_to _('Remove logo'), logo_admin_application_settings_appearances_path, data: { confirm: _("Logo will be removed. Are you sure?") }, method: :delete, class: "btn gl-button btn-danger btn-danger-secondary btn-sm remove-logo"
+ = link_to _('Remove logo'), logo_admin_application_settings_appearances_path, data: { confirm: _("Logo will be removed. Are you sure?"), confirm_btn_variant: "danger" }, aria: { label: _('Remove logo') }, method: :delete, class: "btn gl-button btn-danger btn-danger-secondary btn-sm remove-logo"
%hr
= f.hidden_field :logo_cache
= f.file_field :logo, class: "", accept: 'image/*'
diff --git a/app/views/admin/application_settings/ci_cd.html.haml b/app/views/admin/application_settings/ci_cd.html.haml
index 18ec43407c3..762dba69e6a 100644
--- a/app/views/admin/application_settings/ci_cd.html.haml
+++ b/app/views/admin/application_settings/ci_cd.html.haml
@@ -39,7 +39,7 @@
.settings-content
= render 'registry'
-- if Feature.enabled?(:runner_registration_control)
+- if Feature.enabled?(:runner_registration_control, default_enabled: :yaml)
%section.settings.as-runner.no-animate#js-runner-settings{ class: ('expanded' if expanded_by_default?) }
.settings-header
%h4
diff --git a/app/views/admin/application_settings/network.html.haml b/app/views/admin/application_settings/network.html.haml
index 90183b028f0..ea35b7ab9c4 100644
--- a/app/views/admin/application_settings/network.html.haml
+++ b/app/views/admin/application_settings/network.html.haml
@@ -48,6 +48,17 @@
.settings-content
= render partial: 'network_rate_limits', locals: { anchor: 'js-files-limits-settings', setting_fragment: 'files_api' }
+%section.settings.as-search-limits.no-animate#js-search-limits-settings{ class: ('expanded' if expanded_by_default?) }
+ .settings-header
+ %h4
+ = _('Search rate limits')
+ %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' }
+ = expanded_by_default? ? _('Collapse') : _('Expand')
+ %p
+ = _('Set rate limits for searches performed by web or API requests.')
+ .settings-content
+ = render 'search_limits'
+
%section.settings.as-deprecated-limits.no-animate#js-deprecated-limits-settings{ class: ('expanded' if expanded_by_default?) }
.settings-header
%h4
diff --git a/app/views/admin/application_settings/repository.html.haml b/app/views/admin/application_settings/repository.html.haml
index ac200002cd2..c3a39ddf86d 100644
--- a/app/views/admin/application_settings/repository.html.haml
+++ b/app/views/admin/application_settings/repository.html.haml
@@ -5,13 +5,13 @@
%section.settings.as-default-branch-name.no-animate#js-default-branch-name{ class: ('expanded' if expanded_by_default?) }
.settings-header
%h4
- = _('Default initial branch name')
+ = _('Default branch')
%button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' }
= expanded_by_default? ? _('Collapse') : _('Expand')
%p
- = s_('AdminSettings|The default name for the initial branch of new repositories created in the instance.')
+ = s_('AdminSettings|Set the initial name and protections for the default branch of new repositories created in the instance.')
.settings-content
- = render 'initial_branch_name'
+ = render 'default_branch'
%section.settings.as-mirror.no-animate#js-mirror-settings{ class: ('expanded' if expanded_by_default?) }
.settings-header
diff --git a/app/views/admin/applications/_delete_form.html.haml b/app/views/admin/applications/_delete_form.html.haml
index d348ad507c2..16ec8014c5e 100644
--- a/app/views/admin/applications/_delete_form.html.haml
+++ b/app/views/admin/applications/_delete_form.html.haml
@@ -1,4 +1,5 @@
-- submit_btn_css ||= 'gl-button btn btn-danger btn-sm'
-= form_tag admin_application_path(application) do
- %input{ :name => "_method", :type => "hidden", :value => "delete" }/
- = submit_tag 'Destroy', class: submit_btn_css, data: { confirm: _('Are you sure?') }
+
+- submit_btn_css ||= 'gl-button btn btn-danger btn-sm js-application-delete-button'
+%button{ class: submit_btn_css, data: { path: admin_application_path(application), name: application.name } }
+ = _('Destroy')
+
diff --git a/app/views/admin/applications/index.html.haml b/app/views/admin/applications/index.html.haml
index 28a7bd1820a..86a4ab00ba3 100644
--- a/app/views/admin/applications/index.html.haml
+++ b/app/views/admin/applications/index.html.haml
@@ -33,3 +33,5 @@
%td= render 'delete_form', application: application
= paginate @applications, theme: 'gitlab'
+
+.js-application-delete-modal
diff --git a/app/views/admin/broadcast_messages/_form.html.haml b/app/views/admin/broadcast_messages/_form.html.haml
index b68c22b6942..3e698f0508c 100644
--- a/app/views/admin/broadcast_messages/_form.html.haml
+++ b/app/views/admin/broadcast_messages/_form.html.haml
@@ -16,7 +16,7 @@
- else
= _('Your message here')
-= form_for [:admin, @broadcast_message], html: { class: 'broadcast-message-form js-quick-submit js-requires-input'} do |f|
+= gitlab_ui_form_for [:admin, @broadcast_message], html: { class: 'broadcast-message-form js-quick-submit js-requires-input'} do |f|
= form_errors(@broadcast_message)
.form-group.row.mt-4
@@ -52,9 +52,16 @@
.col-sm-2.col-form-label.pt-0
= f.label :starts_at, _("Dismissable")
.col-sm-10
- = f.check_box :dismissable
- = f.label :dismissable do
- = _('Allow users to dismiss the broadcast message')
+ = f.gitlab_ui_checkbox_component :dismissable, _('Allow users to dismiss the broadcast message')
+ - if Feature.enabled?(:role_targeted_broadcast_messages, default_enabled: :yaml)
+ .form-group.row
+ .col-sm-2.col-form-label
+ = f.label :target_access_levels, _('Target roles')
+ .col-sm-10
+ - target_access_level_options.each do |human_access_level, access_level|
+ = f.gitlab_ui_checkbox_component :target_access_levels, human_access_level, checked_value: access_level, unchecked_value: false, checkbox_options: { multiple: true }
+ .form-text.text-muted
+ = _('The broadcast message displays only to users in projects and groups who have these roles.')
.form-group.row.js-toggle-colors-container.toggle-colors.hide
.col-sm-2.col-form-label
= f.label :font, _("Font Color")
diff --git a/app/views/admin/broadcast_messages/index.html.haml b/app/views/admin/broadcast_messages/index.html.haml
index 3f07bea7840..54c2a9d5250 100644
--- a/app/views/admin/broadcast_messages/index.html.haml
+++ b/app/views/admin/broadcast_messages/index.html.haml
@@ -1,10 +1,11 @@
- breadcrumb_title _("Messages")
- page_title _("Broadcast Messages")
+- targeted_broadcast_messages_enabled = Feature.enabled?(:role_targeted_broadcast_messages, default_enabled: :yaml)
%h3.page-title
= _('Broadcast Messages')
%p.light
- = _('Broadcast messages are displayed for every user and can be used to notify users about scheduled maintenance, recent upgrades and more.')
+ = _('Use banners and notifications to notify your users about scheduled maintenance, recent upgrades, and more.')
= render 'form'
@@ -19,8 +20,10 @@
%th= _('Preview')
%th= _('Starts')
%th= _('Ends')
- %th= _(' Target Path')
- %th= _(' Type')
+ - if targeted_broadcast_messages_enabled
+ %th= _('Target roles')
+ %th= _('Target Path')
+ %th= _('Type')
%th &nbsp;
%tbody
- @broadcast_messages.each do |message|
@@ -33,6 +36,9 @@
= message.starts_at
%td
= message.ends_at
+ - if targeted_broadcast_messages_enabled
+ %td
+ = target_access_levels_display(message.target_access_levels)
%td
= message.target_path
%td
diff --git a/app/views/admin/dashboard/_security_newsletter_callout.html.haml b/app/views/admin/dashboard/_security_newsletter_callout.html.haml
index 3aba91e8765..aced997bada 100644
--- a/app/views/admin/dashboard/_security_newsletter_callout.html.haml
+++ b/app/views/admin/dashboard/_security_newsletter_callout.html.haml
@@ -4,7 +4,6 @@
title: s_('AdminArea|Get security updates from GitLab and stay up to date'),
variant: :tip,
alert_class: 'js-security-newsletter-callout',
- is_contained: true,
alert_data: { feature_id: Users::CalloutsHelper::SECURITY_NEWSLETTER_CALLOUT, dismiss_endpoint: callouts_path, defer_links: 'true' },
close_button_data: { testid: 'close-security-newsletter-callout' } do
.gl-alert-body
diff --git a/app/views/admin/groups/_form.html.haml b/app/views/admin/groups/_form.html.haml
index 91a018121c0..0c3ce1f3fa4 100644
--- a/app/views/admin/groups/_form.html.haml
+++ b/app/views/admin/groups/_form.html.haml
@@ -27,12 +27,9 @@
- if @group.new_record?
.form-group.row
.offset-sm-2.col-sm-10
- .gl-alert.gl-alert-
- .gl-alert-container
- = sprite_icon('information-o', size: 16, css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title')
- .gl-alert-content
- .gl-alert-body
- = render 'shared/group_tips'
+ = render 'shared/global_alert', dismissible: false do
+ .gl-alert-body
+ = render 'shared/group_tips'
.form-actions
= f.submit _('Create group'), class: "gl-button btn btn-confirm"
= link_to _('Cancel'), admin_groups_path, class: "gl-button btn btn-default btn-cancel"
diff --git a/app/views/admin/hooks/_form.html.haml b/app/views/admin/hooks/_form.html.haml
index 459df5c8d85..bd63172a0ee 100644
--- a/app/views/admin/hooks/_form.html.haml
+++ b/app/views/admin/hooks/_form.html.haml
@@ -3,7 +3,7 @@
.form-group
= form.label :url, _('URL'), class: 'label-bold'
= form.text_field :url, class: 'form-control gl-form-input'
- %p.form-text.text-muted= _('URL must be percent-encoded if neccessary.')
+ %p.form-text.text-muted= _('URL must be percent-encoded if necessary.')
.form-group
= form.label :token, _('Secret token'), class: 'label-bold'
= form.text_field :token, class: 'form-control gl-form-input'
diff --git a/app/views/admin/runners/edit.html.haml b/app/views/admin/runners/edit.html.haml
index b65fead49ab..55fd09ac203 100644
--- a/app/views/admin/runners/edit.html.haml
+++ b/app/views/admin/runners/edit.html.haml
@@ -25,15 +25,12 @@
- if project
%tr
%td
- .gl-alert.gl-alert-danger
- .gl-alert-container
- = sprite_icon('error', size: 16, css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title')
- .gl-alert-content
- .gl-alert-body
- %strong
- = project.full_name
- .gl-alert-actions
- = link_to _('Disable'), admin_namespace_project_runner_project_path(project.namespace, project, runner_project), method: :delete, class: 'btn gl-alert-action btn-confirm btn-md gl-button'
+ = render 'shared/global_alert',
+ variant: :danger,
+ dismissible: false,
+ title: project.full_name do
+ .gl-alert-actions
+ = link_to _('Disable'), admin_namespace_project_runner_project_path(project.namespace, project, runner_project), method: :delete, class: 'btn gl-alert-action btn-confirm btn-md gl-button'
%table.table{ data: { testid: 'unassigned-projects' } }
%thead
diff --git a/app/views/admin/spam_logs/_spam_log.html.haml b/app/views/admin/spam_logs/_spam_log.html.haml
index 2bfe905fb9d..cd6df5f30f3 100644
--- a/app/views/admin/spam_logs/_spam_log.html.haml
+++ b/app/views/admin/spam_logs/_spam_log.html.haml
@@ -24,7 +24,7 @@
%td
- if user
= link_to _('Remove user'), admin_spam_log_path(spam_log, remove_user: true),
- data: { confirm: _("USER %{user_name} WILL BE REMOVED! Are you sure?") % { user_name: user.name } }, method: :delete, class: "gl-button btn btn-sm btn-danger"
+ data: { confirm: _("USER %{user_name} WILL BE REMOVED! Are you sure?") % { user_name: user.name }, confirm_btn_variant: 'danger' }, aria: { label: _('Remove user') }, method: :delete, class: "gl-button btn btn-sm btn-danger"
%td
- if spam_log.submitted_as_ham?
.gl-button.btn.btn-default.btn-sm.disabled.gl-mb-3
diff --git a/app/views/admin/topics/_form.html.haml b/app/views/admin/topics/_form.html.haml
index 21a1d74a8c6..c40484ea494 100644
--- a/app/views/admin/topics/_form.html.haml
+++ b/app/views/admin/topics/_form.html.haml
@@ -27,7 +27,7 @@
= topic_icon(@topic, alt: _('Topic avatar'), class: 'avatar topic-avatar s90')
= render 'shared/choose_avatar_button', f: f
- if @topic.avatar?
- = link_to _('Remove avatar'), admin_topic_avatar_path(@topic), data: { confirm: _('Avatar will be removed. Are you sure?')}, method: :delete, class: 'gl-button btn btn-danger-secondary gl-mt-2'
+ .js-remove-topic-avatar{ data: { path: admin_topic_avatar_path(@topic) } }
- if @topic.new_record?
.form-actions
diff --git a/app/views/admin/users/_head.html.haml b/app/views/admin/users/_head.html.haml
index ca14d898d79..e429a16d5ec 100644
--- a/app/views/admin/users/_head.html.haml
+++ b/app/views/admin/users/_head.html.haml
@@ -27,8 +27,6 @@
= render_if_exists 'admin/users/gma_user_badge'
.gl-my-3.gl-display-flex.gl-flex-wrap.gl-my-n2.gl-mx-n2
- .gl-p-2
- #js-admin-user-actions{ data: admin_user_actions_data_attributes(@user) }
- if @user != current_user
.gl-p-2
- if impersonation_enabled? && @user.can?(:log_in)
@@ -36,6 +34,8 @@
- if can_force_email_confirmation?(@user)
%button.btn.gl-button.btn-info.js-confirm-modal-button{ data: confirm_user_data(@user) }
= _('Confirm user')
+ .gl-p-2
+ #js-admin-user-actions{ data: admin_user_actions_data_attributes(@user) }
= gl_tabs_nav do
= gl_tab_link_to _("Account"), admin_user_path(@user)
= gl_tab_link_to _("Groups and projects"), projects_admin_user_path(@user)
diff --git a/app/views/admin/users/_users.html.haml b/app/views/admin/users/_users.html.haml
index 6fdf383d571..ad7ce57ebda 100644
--- a/app/views/admin/users/_users.html.haml
+++ b/app/views/admin/users/_users.html.haml
@@ -60,21 +60,12 @@
= hidden_field_tag :sort, @sort
= sprite_icon('search', css_class: 'search-icon')
= button_tag s_('AdminUsers|Search users') if Rails.env.test?
- .dropdown.gl-ml-3
- = label_tag 'Sort by', nil, class: 'label-bold'
- - toggle_text = @sort.present? ? users_sort_options_hash[@sort] : sort_title_name
- = dropdown_toggle(toggle_text, { toggle: 'dropdown' })
- %ul.dropdown-menu.dropdown-menu-right
- %li.dropdown-header
- = s_('AdminUsers|Sort by')
- %li
- - users_sort_options_hash.each do |value, title|
- = link_to admin_users_path(sort: value, filter: params[:filter], search_query: params[:search_query]) do
- = title
+ .dropdown.gl-sm-ml-3
+ = label_tag s_('AdminUsers|Sort by')
+ = gl_redirect_listbox_tag admin_users_sort_options(filter: params[:filter], search_query: params[:search_query]), @sort, data: { right: true }
#js-admin-users-app{ data: admin_users_data_attributes(@users) }
- .gl-spinner-container.gl-my-7
- %span.gl-vertical-align-bottom.gl-spinner.gl-spinner-dark.gl-spinner-lg{ aria: { label: _('Loading') } }
+ = gl_loading_icon(size: 'lg', css_class: 'gl-my-7')
= paginate_collection @users
diff --git a/app/views/ci/variables/_variable_row.html.haml b/app/views/ci/variables/_variable_row.html.haml
index 3a7f7a241ac..483c767d029 100644
--- a/app/views/ci/variables/_variable_row.html.haml
+++ b/app/views/ci/variables/_variable_row.html.haml
@@ -1,23 +1,16 @@
- form_field = local_assigns.fetch(:form_field, nil)
- variable = local_assigns.fetch(:variable, nil)
-- only_key_value = local_assigns.fetch(:only_key_value, false)
- id = variable&.id
- variable_type = variable&.variable_type
- key = variable&.key
- value = variable&.value
-- is_protected_default = ci_variable_protected_by_default?
-- is_protected = ci_variable_protected?(variable, only_key_value)
-- is_masked_default = false
-- is_masked = ci_variable_masked?(variable, only_key_value)
- id_input_name = "#{form_field}[variables_attributes][][id]"
- destroy_input_name = "#{form_field}[variables_attributes][][_destroy]"
- variable_type_input_name = "#{form_field}[variables_attributes][][variable_type]"
- key_input_name = "#{form_field}[variables_attributes][][key]"
- value_input_name = "#{form_field}[variables_attributes][][secret_value]"
-- protected_input_name = "#{form_field}[variables_attributes][][protected]"
-- masked_input_name = "#{form_field}[variables_attributes][][masked]"
%li.js-row.ci-variable-row{ data: { is_persisted: "#{!id.nil?}" } }
.ci-variable-row-body.border-bottom
@@ -40,25 +33,5 @@
%p.masking-validation-error.gl-field-error.hide
= s_("CiVariables|Cannot use Masked Variable with current value")
= link_to sprite_icon('question-o'), help_page_path('ci/variables/index', anchor: 'mask-a-cicd-variable'), target: '_blank', rel: 'noopener noreferrer'
- - unless only_key_value
- .ci-variable-body-item.ci-variable-protected-item.table-section.section-20.mr-0.border-top-0
- .gl-mr-3
- = s_("CiVariable|Protected")
- = render "shared/buttons/project_feature_toggle", is_checked: is_protected, label: s_("CiVariable|Toggle protected") do
- %input{ type: "hidden",
- class: 'js-ci-variable-input-protected js-project-feature-toggle-input',
- name: protected_input_name,
- value: is_protected,
- data: { default: is_protected_default.to_s } }
- .ci-variable-body-item.ci-variable-masked-item.table-section.section-20.mr-0.border-top-0
- .gl-mr-3
- = s_("CiVariable|Masked")
- = render "shared/buttons/project_feature_toggle", is_checked: is_masked, label: s_("CiVariable|Toggle masked"), class_list: "js-project-feature-toggle project-feature-toggle qa-variable-masked" do
- %input{ type: "hidden",
- class: 'js-ci-variable-input-masked js-project-feature-toggle-input',
- name: masked_input_name,
- value: is_masked,
- data: { default: is_masked_default.to_s } }
- = render_if_exists 'ci/variables/environment_scope', form_field: form_field, variable: variable
%button.gl-button.btn.btn-default.btn-icon.js-row-remove-button.ci-variable-row-remove-button.table-section{ type: 'button', 'aria-label': s_('CiVariables|Remove variable row') }
= sprite_icon('close')
diff --git a/app/views/clusters/clusters/_banner.html.haml b/app/views/clusters/clusters/_banner.html.haml
index 1ca4f9c670e..6fb3f26ff4f 100644
--- a/app/views/clusters/clusters/_banner.html.haml
+++ b/app/views/clusters/clusters/_banner.html.haml
@@ -9,7 +9,6 @@
= render 'shared/global_alert',
variant: :warning,
alert_class: 'hidden js-cluster-api-unreachable',
- is_contained: true,
close_button_class: 'js-close' do
.gl-alert-body
= s_('ClusterIntegration|Your cluster API is unreachable. Please ensure your API URL is correct.')
@@ -17,7 +16,6 @@
= render 'shared/global_alert',
variant: :warning,
alert_class: 'hidden js-cluster-authentication-failure js-cluster-api-unreachable',
- is_contained: true,
close_button_class: 'js-close' do
.gl-alert-body
= s_('ClusterIntegration|There was a problem authenticating with your cluster. Please ensure your CA Certificate and Token are valid.')
diff --git a/app/views/clusters/clusters/_cluster_list.html.haml b/app/views/clusters/clusters/_cluster_list.html.haml
deleted file mode 100644
index e5e1b68225e..00000000000
--- a/app/views/clusters/clusters/_cluster_list.html.haml
+++ /dev/null
@@ -1,10 +0,0 @@
-- if !clusters.empty?
- .top-area.adjust
- .gl-display-block.gl-text-right.gl-my-4.gl-w-full
- - if clusterable.can_add_cluster?
- = link_to s_('ClusterIntegration|Connect cluster with certificate'), clusterable.new_path, class: 'btn gl-button btn-confirm js-add-cluster gl-py-2', data: { qa_selector: 'integrate_kubernetes_cluster_button' }
- - else
- %span.btn.gl-button.btn-confirm.js-add-cluster.disabled.gl-py-2
- = s_("ClusterIntegration|Connect cluster with certificate")
-
-#js-clusters-list-app{ data: js_clusters_list_data(clusterable) }
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 9d249931a34..3a4632affdc 100644
--- a/app/views/clusters/clusters/_gcp_signup_offer_banner.html.haml
+++ b/app/views/clusters/clusters/_gcp_signup_offer_banner.html.haml
@@ -1,11 +1,10 @@
- link = link_to(s_('ClusterIntegration|sign up'), 'https://console.cloud.google.com/freetrial?utm_campaign=2018_cpanel&utm_source=gitlab&utm_medium=referral', target: '_blank', rel: 'noopener noreferrer')
-.gcp-signup-offer.gl-alert.gl-alert-info.gl-my-3{ role: 'alert', data: { feature_id: Users::CalloutsHelper::GCP_SIGNUP_OFFER, dismiss_endpoint: callouts_path } }
- .gl-alert-container
- %button.js-close.btn.gl-dismiss-btn.btn-default.btn-sm.gl-button.btn-default-tertiary.btn-icon{ type: 'button', 'aria-label' => _('Dismiss') }
- = sprite_icon('close', size: 16, css_class: 'gl-icon')
- = sprite_icon('information-o', size: 16, css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title')
- .gl-alert-content
- %h4.gl-alert-title= s_('ClusterIntegration|Did you know?')
- %p.gl-alert-body= s_('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.').html_safe % { sign_up_link: link }
- %a.gl-button.btn-confirm.text-decoration-none{ href: 'https://cloud.google.com/partners/partnercredit/?pcn_code=0014M00001h35gDQAQ#contact-form', target: '_blank', rel: 'noopener noreferrer' }
- = s_("ClusterIntegration|Apply for credit")
+= render 'shared/global_alert',
+ title: s_('ClusterIntegration|Did you know?'),
+ alert_class: 'gcp-signup-offer',
+ alert_data: { feature_id: Users::CalloutsHelper::GCP_SIGNUP_OFFER, dismiss_endpoint: callouts_path } do
+ .gl-alert-body
+ = s_('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.').html_safe % { sign_up_link: link }
+ .gl-alert-actions
+ %a.gl-button.btn-confirm.text-decoration-none{ href: 'https://cloud.google.com/partners/partnercredit/?pcn_code=0014M00001h35gDQAQ#contact-form', target: '_blank', rel: 'noopener noreferrer' }
+ = s_("ClusterIntegration|Apply for credit")
diff --git a/app/views/clusters/clusters/_multiple_clusters_message.html.haml b/app/views/clusters/clusters/_multiple_clusters_message.html.haml
index ed95744c11d..04c1f9b6e7a 100644
--- a/app/views/clusters/clusters/_multiple_clusters_message.html.haml
+++ b/app/views/clusters/clusters/_multiple_clusters_message.html.haml
@@ -2,5 +2,5 @@
- help_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe
- help_link_end = '</a>'.html_safe
-%p
- = s_('ClusterIntegration|If you are setting up multiple clusters and are using Auto DevOps, %{help_link_start}read this first%{help_link_end}.').html_safe % { help_link_start: help_link_start % { url: autodevops_help_url }, help_link_end: help_link_end }
+%p.gl-font-weight-bold
+ = s_('ClusterIntegration|Using AutoDevOps with multiple clusters? %{help_link_start}Read this first.%{help_link_end}').html_safe % { help_link_start: help_link_start % { url: autodevops_help_url }, help_link_end: help_link_end }
diff --git a/app/views/clusters/clusters/_sidebar.html.haml b/app/views/clusters/clusters/_sidebar.html.haml
index 31add011bfa..bda774ee780 100644
--- a/app/views/clusters/clusters/_sidebar.html.haml
+++ b/app/views/clusters/clusters/_sidebar.html.haml
@@ -1,5 +1,5 @@
-%h4.gl-mt-0
- = s_('ClusterIntegration|Add a Kubernetes cluster integration')
+%h3
+ = s_('ClusterIntegration|Connect a Kubernetes cluster')
%p
= clusterable.sidebar_text
%p
diff --git a/app/views/clusters/clusters/cloud_providers/_cloud_provider_button.html.haml b/app/views/clusters/clusters/cloud_providers/_cloud_provider_button.html.haml
index c10983a5405..826dc749dad 100644
--- a/app/views/clusters/clusters/cloud_providers/_cloud_provider_button.html.haml
+++ b/app/views/clusters/clusters/cloud_providers/_cloud_provider_button.html.haml
@@ -3,10 +3,10 @@
- logo_path = local_assigns.fetch(:logo_path)
- label = local_assigns.fetch(:label)
- last = local_assigns.fetch(:last, false)
-- classes = ["btn btn-light btn-outline flex-fill d-inline-flex flex-column justify-content-center align-items-center w-50 js-create-#{provider}-cluster-button"]
-- conditional_classes = [('mr-3' unless last), ('active' if is_current_provider)]
+- classes = ["btn btn-confirm gl-button btn-confirm-secondary gl-flex-direction-column gl-w-half js-create-#{provider}-cluster-button"]
+- conditional_classes = [('gl-mr-5' unless last), ('active' if is_current_provider)]
= link_to clusterable.new_path(provider: provider), class: classes + conditional_classes do
- .svg-content.p-2= image_tag logo_path, alt: label, class: 'gl-w-64 gl-h-64'
+ .svg-content.gl-p-3= image_tag logo_path, alt: label, class: 'gl-w-64 gl-h-64'
%span
= label
diff --git a/app/views/clusters/clusters/cloud_providers/_cloud_provider_selector.html.haml b/app/views/clusters/clusters/cloud_providers/_cloud_provider_selector.html.haml
index aee355bbf71..321fb854e0d 100644
--- a/app/views/clusters/clusters/cloud_providers/_cloud_provider_selector.html.haml
+++ b/app/views/clusters/clusters/cloud_providers/_cloud_provider_selector.html.haml
@@ -1,10 +1,10 @@
- gke_label = s_('ClusterIntegration|Google GKE')
- eks_label = s_('ClusterIntegration|Amazon EKS')
-- create_cluster_label = s_('ClusterIntegration|Create cluster on')
-.d-flex.flex-column.p-3
- %h4.mb-3
+- create_cluster_label = s_('ClusterIntegration|Where do you want to create a cluster?')
+.gl-p-5
+ %h4.gl-mb-5
= create_cluster_label
- .d-flex
+ .gl-display-flex
= render partial: 'clusters/clusters/cloud_providers/cloud_provider_button',
locals: { provider: 'aws', label: eks_label, logo_path: 'illustrations/logos/amazon_eks.svg' }
= render partial: 'clusters/clusters/cloud_providers/cloud_provider_button',
diff --git a/app/views/clusters/clusters/connect.html.haml b/app/views/clusters/clusters/connect.html.haml
new file mode 100644
index 00000000000..1043f78bd3c
--- /dev/null
+++ b/app/views/clusters/clusters/connect.html.haml
@@ -0,0 +1,11 @@
+- @content_class = 'limit-container-width' unless fluid_layout
+- add_to_breadcrumbs _('Kubernetes Clusters'), clusterable.index_path
+- breadcrumb_title _('Connect a cluster')
+- page_title _('Connect a Kubernetes Cluster')
+
+.row.gl-mt-3
+ .col-md-3
+ = render 'sidebar'
+ .col-md-9
+ #js-cluster-new{ data: js_cluster_new }
+ = render 'clusters/clusters/user/form'
diff --git a/app/views/clusters/clusters/gcp/_form.html.haml b/app/views/clusters/clusters/gcp/_form.html.haml
index c8105fd1152..58b8e8b1003 100644
--- a/app/views/clusters/clusters/gcp/_form.html.haml
+++ b/app/views/clusters/clusters/gcp/_form.html.haml
@@ -67,20 +67,20 @@
label_class: 'label-bold' }
.form-text.text-muted
= s_('ClusterIntegration|Uses the Cloud Run, Istio, and HTTP Load Balancing addons for this cluster.')
- = link_to _('More information'), help_page_path('user/project/clusters/add_gke_clusters.md', anchor: 'cloud-run-for-anthos'), target: '_blank', rel: 'noopener noreferrer'
+ = link_to _('Learn more.'), help_page_path('user/project/clusters/add_gke_clusters.md', anchor: 'cloud-run-for-anthos'), target: '_blank', rel: 'noopener noreferrer'
.form-group
= field.check_box :managed, { label: s_('ClusterIntegration|GitLab-managed cluster'),
label_class: 'label-bold' }
.form-text.text-muted
= s_('ClusterIntegration|Allow GitLab to manage namespaces and service accounts for this cluster.')
- = link_to _('More information'), help_page_path('user/project/clusters/gitlab_managed_clusters.md'), target: '_blank', rel: 'noopener noreferrer'
+ = link_to _('Learn more.'), help_page_path('user/project/clusters/gitlab_managed_clusters.md'), target: '_blank', rel: 'noopener noreferrer'
.form-group
= field.check_box :namespace_per_environment, { label: s_('ClusterIntegration|Namespace per environment'), label_class: 'label-bold' }
.form-text.text-muted
= s_('ClusterIntegration|Deploy each environment to its own namespace. Otherwise, environments within a project share a project-wide namespace. Note that anyone who can trigger a deployment of a namespace can read its secrets. If modified, existing environments will use their current namespaces until the cluster cache is cleared.')
- = link_to _('More information'), help_page_path('user/project/clusters/deploy_to_cluster.md', anchor: 'custom-namespace'), target: '_blank', rel: 'noopener noreferrer'
+ = link_to _('Learn more.'), help_page_path('user/project/clusters/deploy_to_cluster.md', anchor: 'custom-namespace'), target: '_blank', rel: 'noopener noreferrer'
.form-group.js-gke-cluster-creation-submit-container
= field.submit s_('ClusterIntegration|Create Kubernetes cluster'),
diff --git a/app/views/clusters/clusters/index.html.haml b/app/views/clusters/clusters/index.html.haml
index 457e34b306a..abe9cc9f27d 100644
--- a/app/views/clusters/clusters/index.html.haml
+++ b/app/views/clusters/clusters/index.html.haml
@@ -4,9 +4,5 @@
= render_gcp_signup_offer
.clusters-container
- - if display_cluster_agents?(clusterable)
- .gl-my-6
- .js-clusters-main-view{ data: js_clusters_data(clusterable) }
-
- - else
- = render 'cluster_list', clusters: @clusters
+ .gl-my-6
+ .js-clusters-main-view{ data: js_clusters_list_data(clusterable) }
diff --git a/app/views/clusters/clusters/new.html.haml b/app/views/clusters/clusters/new.html.haml
index 7af7a812338..a184f412565 100644
--- a/app/views/clusters/clusters/new.html.haml
+++ b/app/views/clusters/clusters/new.html.haml
@@ -1,9 +1,8 @@
-- breadcrumb_title _('Kubernetes')
-- page_title _('Kubernetes Cluster')
+- @content_class = 'limit-container-width' unless fluid_layout
+- add_to_breadcrumbs _('Kubernetes Clusters'), clusterable.index_path
+- breadcrumb_title _('Create a cluster')
+- page_title _('Create a Kubernetes cluster')
- provider = params[:provider]
-- active_tab = params[:tab] || local_assigns.fetch(:active_tab, 'create')
-- is_active_tab_create = active_tab === 'create'
-- is_active_tab_add = active_tab === 'add'
= render_gcp_signup_offer
@@ -11,21 +10,8 @@
.col-md-3
= render 'sidebar'
.col-md-9
- = gl_tabs_nav({ class: 'nav-justified' }) do
- = gl_tab_link_to clusterable.new_path(tab: 'create'), { item_active: is_active_tab_create } do
- %span= create_new_cluster_label(provider: params[:provider])
- = gl_tab_link_to s_('ClusterIntegration|Connect existing cluster'), clusterable.new_path(tab: 'add'), { item_active: is_active_tab_add, qa_selector: 'add_existing_cluster_tab' }
+ = render 'clusters/clusters/cloud_providers/cloud_provider_selector'
- .tab-content
- - if is_active_tab_create
- .tab-pane.active{ role: 'tabpanel' }
- = render 'clusters/clusters/cloud_providers/cloud_provider_selector'
-
- - if ['aws', 'gcp'].include?(provider)
- .p-3.border-top
- = render "clusters/clusters/#{provider}/new"
-
- - if is_active_tab_add
- .tab-pane.active.gl-p-5{ role: 'tabpanel' }
- #js-cluster-new{ data: js_cluster_new }
- = render 'clusters/clusters/user/form'
+ - if ['aws', 'gcp'].include?(provider)
+ .gl-p-5.gl-border-1.gl-border-t-solid.gl-border-gray-100
+ = render "clusters/clusters/#{provider}/new"
diff --git a/app/views/clusters/clusters/user/_form.html.haml b/app/views/clusters/clusters/user/_form.html.haml
index 29af79cee5f..2dd15ebd266 100644
--- a/app/views/clusters/clusters/user/_form.html.haml
+++ b/app/views/clusters/clusters/user/_form.html.haml
@@ -1,6 +1,6 @@
-- more_info_link = link_to _('More information'), help_page_path('user/project/clusters/add_remove_clusters.md',
+- more_info_link = link_to _('Learn more.'), help_page_path('user/project/clusters/add_remove_clusters.md',
anchor: 'add-existing-cluster'), target: '_blank', rel: 'noopener noreferrer'
-- rbac_help_link = link_to _('More information'), help_page_path('user/project/clusters/add_remove_clusters.md',
+- rbac_help_link = link_to _('Learn more.'), help_page_path('user/project/clusters/add_remove_clusters.md',
anchor: 'access-controls'), target: '_blank', rel: 'noopener noreferrer'
- api_url_help_text = s_('ClusterIntegration|The URL used to access the Kubernetes API.')
@@ -47,13 +47,13 @@
label_class: 'label-bold' }
.form-text.text-muted
= s_('ClusterIntegration|Allow GitLab to manage namespaces and service accounts for this cluster.')
- = link_to _('More information'), help_page_path('user/project/clusters/gitlab_managed_clusters.md'), target: '_blank', rel: 'noopener noreferrer'
+ = link_to _('Learn more.'), help_page_path('user/project/clusters/gitlab_managed_clusters.md'), target: '_blank', rel: 'noopener noreferrer'
.form-group
= field.check_box :namespace_per_environment, { label: s_('ClusterIntegration|Namespace per environment'), label_class: 'label-bold' }
.form-text.text-muted
= s_('ClusterIntegration|Deploy each environment to its own namespace. Otherwise, environments within a project share a project-wide namespace. Note that anyone who can trigger a deployment of a namespace can read its secrets. If modified, existing environments will use their current namespaces until the cluster cache is cleared.')
- = link_to _('More information'), help_page_path('user/project/clusters/deploy_to_cluster.md', anchor: 'custom-namespace'), target: '_blank', rel: 'noopener noreferrer'
+ = link_to _('Learn more.'), help_page_path('user/project/clusters/deploy_to_cluster.md', anchor: 'custom-namespace'), target: '_blank', rel: 'noopener noreferrer'
= field.fields_for :platform_kubernetes, @user_cluster.platform_kubernetes do |platform_kubernetes_field|
- if @user_cluster.allow_user_defined_namespace?
diff --git a/app/views/dashboard/_activities.html.haml b/app/views/dashboard/_activities.html.haml
index ec07c636b79..7c948260d4b 100644
--- a/app/views/dashboard/_activities.html.haml
+++ b/app/views/dashboard/_activities.html.haml
@@ -6,4 +6,4 @@
.content_list
.loading
- .gl-spinner.gl-spinner-md
+ = gl_loading_icon(size: 'md')
diff --git a/app/views/dashboard/groups/_groups.html.haml b/app/views/dashboard/groups/_groups.html.haml
index d5cd4b66e2b..601b6a8b1a7 100644
--- a/app/views/dashboard/groups/_groups.html.haml
+++ b/app/views/dashboard/groups/_groups.html.haml
@@ -1,4 +1,2 @@
.js-groups-list-holder
#js-groups-tree{ data: { hide_projects: 'true', endpoint: dashboard_groups_path(format: :json), path: dashboard_groups_path, form_sel: 'form#group-filter-form', filter_sel: '.js-groups-list-filter', holder_sel: '.js-groups-list-holder', dropdown_sel: '.js-group-filter-dropdown-wrap' } }
- .loading-container.text-center.prepend-top-20
- .gl-spinner.gl-spinner-md
diff --git a/app/views/dashboard/todos/_todo.html.haml b/app/views/dashboard/todos/_todo.html.haml
index 2c6c721a51c..c932b416b66 100644
--- a/app/views/dashboard/todos/_todo.html.haml
+++ b/app/views/dashboard/todos/_todo.html.haml
@@ -50,12 +50,12 @@
.todo-actions.gl-ml-3
- if todo.pending?
= link_to dashboard_todo_path(todo), method: :delete, class: 'gl-button btn btn-default btn-loading d-flex align-items-center js-done-todo', data: { href: dashboard_todo_path(todo) } do
+ = gl_loading_icon(inline: true)
Done
- %span.gl-spinner.ml-1
= link_to restore_dashboard_todo_path(todo), method: :patch, class: 'gl-button btn btn-default btn-loading d-flex align-items-center js-undo-todo hidden', data: { href: restore_dashboard_todo_path(todo) } do
+ = gl_loading_icon(inline: true)
Undo
- %span.gl-spinner.ml-1
- else
= link_to restore_dashboard_todo_path(todo), method: :patch, class: 'gl-button btn btn-default btn-loading d-flex align-items-center js-add-todo', data: { href: restore_dashboard_todo_path(todo) } do
+ = gl_loading_icon(inline: true)
Add a to do
- %span.gl-spinner.ml-1
diff --git a/app/views/dashboard/todos/index.html.haml b/app/views/dashboard/todos/index.html.haml
index f6dc62e1d44..1d711f366c4 100644
--- a/app/views/dashboard/todos/index.html.haml
+++ b/app/views/dashboard/todos/index.html.haml
@@ -2,6 +2,7 @@
- page_title _("To-Do List")
- header_title _("To-Do List"), dashboard_todos_path
+= render_two_factor_auth_recovery_settings_check
= render_dashboard_ultimate_trial(current_user)
- add_page_specific_style 'page_bundles/todos'
@@ -22,11 +23,11 @@
- if @allowed_todos.any?(&:pending?)
.gl-mr-3
= link_to destroy_all_dashboard_todos_path(todos_filter_params), class: 'gl-button btn btn-default btn-loading align-items-center js-todos-mark-all', method: :delete, data: { href: destroy_all_dashboard_todos_path(todos_filter_params) } do
+ = gl_loading_icon(inline: true)
= s_("Todos|Mark all as done")
- %span.gl-spinner.ml-1
= link_to bulk_restore_dashboard_todos_path, class: 'gl-button btn btn-default btn-loading align-items-center js-todos-undo-all hidden', method: :patch , data: { href: bulk_restore_dashboard_todos_path(todos_filter_params) } do
+ = gl_loading_icon(inline: true)
= s_("Todos|Undo mark all as done")
- %span.gl-spinner.ml-1
.todos-filters
.issues-details-filters.row-content-block.second-block
diff --git a/app/views/devise/shared/_email_opted_in.html.haml b/app/views/devise/shared/_email_opted_in.html.haml
index 3817f9f651d..898b8f31f1d 100644
--- a/app/views/devise/shared/_email_opted_in.html.haml
+++ b/app/views/devise/shared/_email_opted_in.html.haml
@@ -1,4 +1,4 @@
-- return unless Gitlab.dev_env_or_com?
+- return unless Gitlab.com?
.gl-mb-3.js-email-opt-in.hidden
.gl-font-weight-bold.gl-mb-3
diff --git a/app/views/devise/shared/_terms_of_service_notice.html.haml b/app/views/devise/shared/_terms_of_service_notice.html.haml
index 75d567a03fd..1c6dc1f2d5d 100644
--- a/app/views/devise/shared/_terms_of_service_notice.html.haml
+++ b/app/views/devise/shared/_terms_of_service_notice.html.haml
@@ -1,7 +1,7 @@
- return unless Gitlab::CurrentSettings.current_application_settings.enforce_terms?
%p.gl-text-gray-500.gl-mt-5.gl-mb-0
- - if Gitlab.dev_env_or_com?
+ - if Gitlab.com?
= html_escape(s_("SignUp|By clicking %{button_text}, I agree that I have read and accepted the GitLab %{link_start}Terms of Use and Privacy Policy%{link_end}")) % { button_text: button_text,
link_start: "<a href='#{terms_path}' target='_blank' rel='noreferrer noopener'>".html_safe, link_end: '</a>'.html_safe }
- else
diff --git a/app/views/discussions/_discussion.html.haml b/app/views/discussions/_discussion.html.haml
index 075eb99fc36..477f6c73388 100644
--- a/app/views/discussions/_discussion.html.haml
+++ b/app/views/discussions/_discussion.html.haml
@@ -11,7 +11,8 @@
%button.note-action-button.discussion-toggle-button.js-toggle-button{ type: "button", class: ("js-toggle-lazy-diff" unless expanded) }
= sprite_icon('chevron-up', css_class: "js-sidebar-collapse #{'hidden' unless expanded}")
= sprite_icon('chevron-down', css_class: "js-sidebar-expand #{'hidden' if expanded}")
- = _('Toggle thread')
+ %span.js-sidebar-collapse{ class: "#{'hidden' unless expanded}" }= _('Hide thread')
+ %span.js-sidebar-expand{ class: "#{'hidden' if expanded}" }= _('Show thread')
= link_to_member(@project, discussion.author, avatar: false)
.inline.discussion-headline-light
diff --git a/app/views/explore/groups/_groups.html.haml b/app/views/explore/groups/_groups.html.haml
index 0358fc524d3..bb2bd193565 100644
--- a/app/views/explore/groups/_groups.html.haml
+++ b/app/views/explore/groups/_groups.html.haml
@@ -1,4 +1,3 @@
.js-groups-list-holder
#js-groups-tree{ data: { hide_projects: 'true', endpoint: explore_groups_path(format: :json), path: explore_groups_path, form_sel: 'form#group-filter-form', filter_sel: '.js-groups-list-filter', holder_sel: '.js-groups-list-holder', dropdown_sel: '.js-group-filter-dropdown-wrap' } }
- .loading-container.text-center.prepend-top-20
- .gl-spinner.gl-spinner-md
+ = gl_loading_icon(size: 'md', css_class: 'gl-mt-6')
diff --git a/app/views/explore/projects/_filter.html.haml b/app/views/explore/projects/_filter.html.haml
index 2ead8fc2cfd..f02d30081b6 100644
--- a/app/views/explore/projects/_filter.html.haml
+++ b/app/views/explore/projects/_filter.html.haml
@@ -1,22 +1,9 @@
- has_label = local_assigns.fetch(:has_label, false)
- feature_project_list_filter_bar = Feature.enabled?(:project_list_filter_bar)
+- klass = feature_project_list_filter_bar ? 'gl-ml-3 gl-display-flex gl-flex-grow-1 gl-flex-shrink-1' : 'gl-ml-3'
+- selected = projects_filter_selected(params[:visibility_level])
- if current_user
- .dropdown.js-project-filter-dropdown-wrap{ class: ('d-flex flex-grow-1 flex-shrink-1' if feature_project_list_filter_bar) }
- %button.dropdown-menu-toggle{ href: '#', "data-toggle" => "dropdown", 'data-display' => 'static' }
- - unless has_label
- %span= _("Visibility:")
- - if params[:visibility_level].present?
- = visibility_level_label(params[:visibility_level].to_i)
- - else
- = _('Any')
- = sprite_icon('chevron-down', css_class: 'dropdown-menu-toggle-icon gl-top-3')
- %ul.dropdown-menu.dropdown-menu-right
- %li
- = link_to filter_projects_path(visibility_level: nil) do
- = _('Any')
- - Gitlab::VisibilityLevel.values.each do |level|
- %li{ class: active_when(level.to_s == params[:visibility_level]) || 'light' }
- = link_to filter_projects_path(visibility_level: level) do
- = visibility_level_icon(level)
- = visibility_level_label(level)
+ - unless has_label
+ %span.gl-float-left= _("Visibility:")
+ = gl_redirect_listbox_tag(projects_filter_items, selected, class: klass, data: { right: true })
diff --git a/app/views/groups/_activities.html.haml b/app/views/groups/_activities.html.haml
index 1695d3b5539..614d9610f31 100644
--- a/app/views/groups/_activities.html.haml
+++ b/app/views/groups/_activities.html.haml
@@ -6,4 +6,4 @@
.content_list
.loading
- .gl-spinner.gl-spinner-md
+ = gl_loading_icon(size: 'md')
diff --git a/app/views/groups/_archived_projects.html.haml b/app/views/groups/_archived_projects.html.haml
index 959c26acae0..21107cc22a1 100644
--- a/app/views/groups/_archived_projects.html.haml
+++ b/app/views/groups/_archived_projects.html.haml
@@ -4,5 +4,4 @@
%ul.content-list{ data: { hide_projects: 'false', group_id: group.id, path: group_path(group) } }
.js-groups-list-holder
- .loading-container.text-center.prepend-top-20
- .gl-spinner.gl-spinner-md
+ = gl_loading_icon(size: 'md', css_class: 'gl-mt-6')
diff --git a/app/views/groups/_import_group_from_another_instance_panel.html.haml b/app/views/groups/_import_group_from_another_instance_panel.html.haml
index 3b079ea00b7..5b9cd80799c 100644
--- a/app/views/groups/_import_group_from_another_instance_panel.html.haml
+++ b/app/views/groups/_import_group_from_another_instance_panel.html.haml
@@ -23,7 +23,8 @@
= f.label :bulk_import_gitlab_access_token, s_('GroupsNew|Personal access token'), for: 'import_gitlab_token'
.gl-font-weight-normal
- pat_link_start = '<a href="%{url}" target="_blank">'.html_safe % { url: help_page_path('user/profile/personal_access_tokens') }
- = s_('GroupsNew|Navigate to user settings to find your %{link_start}personal access token%{link_end}.').html_safe % { link_start: pat_link_start, link_end: '</a>'.html_safe }
+ - short_living_link_start = '<a href="%{url}" target="_blank">'.html_safe % { url: help_page_path('security/token_overview', anchor: 'security-considerations') }
+ = s_('GroupsNew|Create this in the %{pat_link_start}user settings%{pat_link_end} of the source GitLab instance. For %{short_living_link_start}security reasons%{short_living_link_end}, use a short expiration date when creating the token.').html_safe % { pat_link_start: pat_link_start, pat_link_end: '</a>'.html_safe, short_living_link_start: short_living_link_start, short_living_link_end: '</a>'.html_safe }
= f.text_field :bulk_import_gitlab_access_token, placeholder: s_('GroupsNew|e.g. h8d3f016698e...'), class: 'gl-form-input gl-mt-3 col-xs-12 col-sm-8',
required: true,
autocomplete: 'off',
diff --git a/app/views/groups/_shared_projects.html.haml b/app/views/groups/_shared_projects.html.haml
index bfd056ccdd2..ef6410ad439 100644
--- a/app/views/groups/_shared_projects.html.haml
+++ b/app/views/groups/_shared_projects.html.haml
@@ -4,5 +4,4 @@
%ul.content-list{ data: { hide_projects: 'false', group_id: group.id, path: group_path(group) } }
.js-groups-list-holder
- .loading-container.text-center.prepend-top-20
- .gl-spinner.gl-spinner-md
+ = gl_loading_icon
diff --git a/app/views/groups/group_members/index.html.haml b/app/views/groups/group_members/index.html.haml
index d1f56a50907..5c579cf6488 100644
--- a/app/views/groups/group_members/index.html.haml
+++ b/app/views/groups/group_members/index.html.haml
@@ -1,6 +1,5 @@
- add_page_specific_style 'page_bundles/members'
- page_title _('Group members')
-- groups_select_tag_data = group_select_data(@group).merge({ skip_groups: @skip_groups })
.row.gl-mt-3
.col-lg-12
@@ -11,28 +10,15 @@
= _('Group members')
%p
= html_escape(_('You can invite a new member to %{strong_start}%{group_name}%{strong_end}.')) % { group_name: @group.name, strong_start: '<strong>'.html_safe, strong_end: '</strong>'.html_safe }
- - if Feature.enabled?(:invite_members_group_modal, @group, default_enabled: :yaml)
- .gl-w-half.gl-xs-w-full
- .gl-display-flex.gl-flex-wrap.gl-justify-content-end.gl-mb-3
- .js-invite-group-trigger{ data: { classes: 'gl-mt-3 gl-sm-w-auto gl-w-full', display_text: _('Invite a group') } }
- .js-invite-members-trigger{ data: { variant: 'success',
- classes: 'gl-mt-3 gl-sm-w-auto gl-w-full gl-sm-ml-3',
- trigger_source: 'group-members-page',
- display_text: _('Invite members') } }
- = render 'groups/invite_groups_modal', group: @group
- = render 'groups/invite_members_modal', group: @group
- - if can_admin_group_member?(@group) && Feature.disabled?(:invite_members_group_modal, @group, default_enabled: :yaml)
- %hr.gl-mt-4
- %ul.nav-links.nav.nav-tabs.gitlab-tabs{ role: 'tablist' }
- %li.nav-tab{ role: 'presentation' }
- %a.nav-link.active{ href: '#invite-member-pane', id: 'invite-member-tab', data: { toggle: 'tab' }, role: 'tab' }= _('Invite member')
- %li.nav-tab{ role: 'presentation' }
- %a.nav-link{ href: '#invite-group-pane', id: 'invite-group-tab', data: { toggle: 'tab', qa_selector: 'invite_group_tab' }, role: 'tab' }= _('Invite group')
- .tab-content.gitlab-tab-content
- .tab-pane.active{ id: 'invite-member-pane', role: 'tabpanel' }
- = render_invite_member_for_group(@group, @group_member.access_level)
- .tab-pane{ id: 'invite-group-pane', role: 'tabpanel' }
- = render 'shared/members/invite_group', submit_url: group_group_links_path(@group), access_levels: GroupMember.access_level_roles, default_access_level: @group_member.access_level, group_link_field: 'shared_with_group_id', group_access_field: 'shared_group_access', groups_select_tag_data: groups_select_tag_data
+ .gl-w-half.gl-xs-w-full
+ .gl-display-flex.gl-flex-wrap.gl-justify-content-end.gl-mb-3
+ .js-invite-group-trigger{ data: { classes: 'gl-mt-3 gl-sm-w-auto gl-w-full', display_text: _('Invite a group') } }
+ .js-invite-members-trigger{ data: { variant: 'confirm',
+ classes: 'gl-mt-3 gl-sm-w-auto gl-w-full gl-sm-ml-3',
+ trigger_source: 'group-members-page',
+ display_text: _('Invite members') } }
+ = render 'groups/invite_groups_modal', group: @group
+ = render 'groups/invite_members_modal', group: @group
= render_if_exists 'groups/group_members/ldap_sync'
@@ -40,5 +26,4 @@
members: @members,
invited: @invited_members,
access_requests: @requesters).to_json } }
- .loading
- .gl-spinner.gl-spinner-md
+ = gl_loading_icon(css_class: 'gl-my-5', size: 'md')
diff --git a/app/views/groups/harbor/repositories/index.html.haml b/app/views/groups/harbor/repositories/index.html.haml
new file mode 100644
index 00000000000..1ee15557e21
--- /dev/null
+++ b/app/views/groups/harbor/repositories/index.html.haml
@@ -0,0 +1,9 @@
+- page_title _("Harbor Registry")
+- @content_class = "limit-container-width" unless fluid_layout
+
+#js-harbor-registry-list-group{ data: { endpoint: group_harbor_registries_path(@group),
+ "no_containers_image" => image_path('illustrations/docker-empty-state.svg'),
+ "containers_error_image" => image_path('illustrations/docker-error-state.svg'),
+ "help_page_path" => help_page_path('user/packages/container_registry/index'),
+ connection_error: (!!@connection_error).to_s,
+ invalid_path_error: (!!@invalid_path_error).to_s, } }
diff --git a/app/views/groups/imports/show.html.haml b/app/views/groups/imports/show.html.haml
index 79cac364016..9cfb58da7e4 100644
--- a/app/views/groups/imports/show.html.haml
+++ b/app/views/groups/imports/show.html.haml
@@ -4,7 +4,7 @@
.save-group-loader
.center
%h2
- %i.loading.gl-spinner
+ = gl_loading_icon(size: 'md')
= page_title
%p
= s_('GroupImport|Please wait while we import the group for you. Refresh at will.')
diff --git a/app/views/groups/registry/repositories/index.html.haml b/app/views/groups/registry/repositories/index.html.haml
index f6d05959d2e..6060d697f52 100644
--- a/app/views/groups/registry/repositories/index.html.haml
+++ b/app/views/groups/registry/repositories/index.html.haml
@@ -12,6 +12,7 @@
"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'),
"run_cleanup_policies_help_page_path" => help_page_path('administration/packages/container_registry', anchor: 'run-the-cleanup-policy-now'),
+ "container_registry_importing_help_page_path" => help_page_path('user/packages/container_registry/index', anchor: 'tags-temporarily-cannot-be-marked-for-deletion'),
"is_admin": current_user&.admin.to_s,
is_group_page: "true",
"group_path": @group.full_path,
diff --git a/app/views/groups/runners/_runner.html.haml b/app/views/groups/runners/_runner.html.haml
index 78ce5b3e110..b2d8b9668e7 100644
--- a/app/views/groups/runners/_runner.html.haml
+++ b/app/views/groups/runners/_runner.html.haml
@@ -9,7 +9,7 @@
- if runner.locked?
= gl_badge_tag s_('Runners|locked'), variant: :warning, size: :sm
- unless runner.active?
- = gl_badge_tag s_('Runners|paused'), variant: :danger, size: :sm
+ = gl_badge_tag s_('Runners|paused'), { variant: :danger, size: :sm }, { title: s_('Runners|Not accepting jobs'), data: { toggle: 'tooltip', container: 'body' } }
.table-section.section-30
.table-mobile-header{ role: 'rowheader' }= s_('Runners|Runner')
@@ -33,7 +33,7 @@
.table-mobile-header{ role: 'rowheader' }= _('Projects')
.table-mobile-content
- if runner.group_type?
- = _('n/a')
+ \-
- else
= runner.runner_projects.count(:all)
@@ -64,10 +64,10 @@
= sprite_icon('pencil', css_class: 'gl-icon')
.btn-group
- if runner.active?
- = link_to pause_group_runner_path(@group, runner), method: :post, class: 'gl-button btn btn-default btn-icon has-tooltip', title: _('Pause'), ref: 'tooltip', aria: { label: _('Pause') }, data: { placement: 'top', container: 'body', confirm: _('Are you sure?') } do
+ = link_to pause_group_runner_path(@group, runner), method: :post, class: 'gl-button btn btn-default btn-icon', title: s_('Runners|Pause from accepting jobs'), ref: 'tooltip', aria: { label: _('Pause') }, data: { toggle: 'tooltip', container: 'body', confirm: _('Are you sure?') } do
= sprite_icon('pause', css_class: 'gl-icon')
- else
- = link_to resume_group_runner_path(@group, runner), method: :post, class: 'gl-button btn btn-default btn-icon has-tooltip', title: _('Resume'), ref: 'tooltip', aria: { label: _('Resume') }, data: { placement: 'top', container: 'body'} do
+ = link_to resume_group_runner_path(@group, runner), method: :post, class: 'gl-button btn btn-default btn-icon', title: s_('Runners|Resume accepting jobs'), ref: 'tooltip', aria: { label: _('Resume') }, data: { toggle: 'tooltip', container: 'body'} do
= sprite_icon('play', css_class: 'gl-icon')
- if runner.belongs_to_more_than_one_project?
- delete_runner_tooltip = _('Multi-project Runners cannot be removed')
diff --git a/app/views/groups/runners/_settings.html.haml b/app/views/groups/runners/_settings.html.haml
index 55960703f9a..bbcadc08a8b 100644
--- a/app/views/groups/runners/_settings.html.haml
+++ b/app/views/groups/runners/_settings.html.haml
@@ -1,3 +1,17 @@
+- if Feature.enabled?(:runner_list_group_view_vue_ui, @group, default_enabled: :yaml)
+ .gl-card.gl-px-8.gl-py-6.gl-line-height-20
+ .gl-card-body.gl-display-flex{ :class => "gl-p-0!" }
+ .gl-banner-illustration
+ = image_tag('illustrations/rocket-launch-md.svg', alt: s_('Runners|Rocket launch illustration'))
+ .gl-banner-content
+ %h1.gl-banner-title
+ = s_('Runners|New group runners view')
+ %p
+ = s_('Runners|The new view gives you more space and better visibility into your fleet of runners.')
+ %a.btn.btn-confirm.btn-md.gl-button{ :href => group_runners_path(@group) }
+ %span.gl-button-text
+ = s_('Runners|Take me there!')
+
= render 'shared/runners/runner_description'
%hr
diff --git a/app/views/groups/runners/edit.html.haml b/app/views/groups/runners/edit.html.haml
index a0d7b8acb47..4a5bab94246 100644
--- a/app/views/groups/runners/edit.html.haml
+++ b/app/views/groups/runners/edit.html.haml
@@ -1,8 +1,14 @@
- breadcrumb_title _('Edit')
- page_title _('Edit'), "##{@runner.id} (#{@runner.short_sha})"
-- add_to_breadcrumbs _('CI/CD Settings'), group_settings_ci_cd_path(@group)
+
+- if Feature.enabled?(:runner_list_group_view_vue_ui, @group, default_enabled: :yaml)
+ - add_to_breadcrumbs _('Runners'), group_runners_path(@group)
+- else
+ - add_to_breadcrumbs _('CI/CD Settings'), group_settings_ci_cd_path(@group)
+
- add_to_breadcrumbs "#{@runner.short_sha}", group_runner_path(@group, @runner)
+
%h2.page-title
= s_('Runners|Runner #%{runner_id}' % { runner_id: @runner.id })
= render 'shared/runners/runner_type_badge', runner: @runner
diff --git a/app/views/groups/runners/show.html.haml b/app/views/groups/runners/show.html.haml
index 5cf83e8ccfd..72701491c67 100644
--- a/app/views/groups/runners/show.html.haml
+++ b/app/views/groups/runners/show.html.haml
@@ -1,3 +1,6 @@
-- add_to_breadcrumbs _('CI/CD Settings'), group_settings_ci_cd_path(@group)
+- if Feature.enabled?(:runner_list_group_view_vue_ui, @group, default_enabled: :yaml)
+ - add_to_breadcrumbs _('Runners'), group_runners_path(@group)
+- else
+ - add_to_breadcrumbs _('CI/CD Settings'), group_settings_ci_cd_path(@group)
= render 'shared/runners/runner_details', runner: @runner
diff --git a/app/views/groups/settings/_permissions.html.haml b/app/views/groups/settings/_permissions.html.haml
index d4b74665398..dd62c9e118d 100644
--- a/app/views/groups/settings/_permissions.html.haml
+++ b/app/views/groups/settings/_permissions.html.haml
@@ -35,7 +35,6 @@
= render_if_exists 'groups/settings/ip_restriction', f: f, group: @group
= render_if_exists 'groups/settings/allowed_email_domain', f: f, group: @group
= render 'groups/settings/lfs', f: f
- = render 'groups/settings/default_branch_protection', f: f, group: @group
= render 'groups/settings/project_creation_level', f: f, group: @group
= render 'groups/settings/subgroup_creation_level', f: f, group: @group
= render_if_exists 'groups/settings/prevent_forking', f: f, group: @group
@@ -43,7 +42,7 @@
= render_if_exists 'groups/personal_access_token_expiration_policy', f: f, group: @group
= render 'groups/settings/membership', f: f, group: @group
- - if crm_feature_flag_enabled?(@group)
+ - if crm_feature_available?(@group)
%h5= _('Customer relations')
.form-group.gl-mb-3
= f.gitlab_ui_checkbox_component :crm_enabled,
diff --git a/app/views/groups/settings/_transfer.html.haml b/app/views/groups/settings/_transfer.html.haml
index d52d9d59ab3..dde8213b293 100644
--- a/app/views/groups/settings/_transfer.html.haml
+++ b/app/views/groups/settings/_transfer.html.haml
@@ -16,5 +16,5 @@
.gl-alert.gl-alert-info.gl-mb-5
= sprite_icon('information-o', size: 16, css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title')
.gl-alert-body
- = html_escape(_("This group can't be transfered because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group.")) % { linkStart: "<a href=\"#{help_page_path('subscriptions/index', anchor: 'change-the-linked-namespace')}\">".html_safe, linkEnd: '</a>'.html_safe }
+ = html_escape(_("This group can't be transferred because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group.")) % { linkStart: "<a href=\"#{help_page_path('subscriptions/index', anchor: 'change-the-linked-namespace')}\">".html_safe, linkEnd: '</a>'.html_safe }
.js-transfer-group-form{ data: initial_data }
diff --git a/app/views/groups/settings/repository/_default_branch.html.haml b/app/views/groups/settings/repository/_default_branch.html.haml
new file mode 100644
index 00000000000..f2644465a49
--- /dev/null
+++ b/app/views/groups/settings/repository/_default_branch.html.haml
@@ -0,0 +1,24 @@
+%section.settings.as-default-branch-name.no-animate#js-default-branch-name{ class: ('expanded' if expanded_by_default?) }
+ .settings-header
+ %h4.settings-title.js-settings-toggle.js-settings-toggle-trigger-only
+ = _('Default branch')
+ %button.gl-button.js-settings-toggle{ type: 'button' }
+ = expanded_by_default? ? _('Collapse') : _('Expand')
+ %p
+ = s_('GroupSettings|Set the initial name and protections for the default branch of new repositories created in the group.')
+ .settings-content
+ = gitlab_ui_form_for @group, url: group_path(@group, anchor: 'js-default-branch-name'), html: { class: 'fieldset-form' } do |f|
+ = form_errors(@group)
+ - fallback_branch_name = "<code>#{Gitlab::DefaultBranch.value(object: @group)}</code>"
+
+ %fieldset
+ .form-group
+ = f.label :default_branch_name, _('Initial default branch name'), class: 'label-light'
+ = f.text_field :default_branch_name, value: group.namespace_settings&.default_branch_name, placeholder: Gitlab::DefaultBranch.value(object: @group), class: 'form-control'
+ %span.form-text.text-muted
+ = (s_("GroupSettings|If not specified at the group or instance level, the default is %{default_initial_branch_name}. Does not affect existing repositories.") % { default_initial_branch_name: fallback_branch_name }).html_safe
+
+ = render 'groups/settings/default_branch_protection', f: f, group: @group
+
+ = f.hidden_field :redirect_target, value: "repository_settings"
+ = f.submit _('Save changes'), class: 'btn gl-button btn-confirm'
diff --git a/app/views/groups/settings/repository/_initial_branch_name.html.haml b/app/views/groups/settings/repository/_initial_branch_name.html.haml
deleted file mode 100644
index 15a3bacf12d..00000000000
--- a/app/views/groups/settings/repository/_initial_branch_name.html.haml
+++ /dev/null
@@ -1,22 +0,0 @@
-%section.settings.as-default-branch-name.no-animate#js-default-branch-name{ class: ('expanded' if expanded_by_default?) }
- .settings-header
- %h4.settings-title.js-settings-toggle.js-settings-toggle-trigger-only
- = _('Default initial branch name')
- %button.gl-button.js-settings-toggle{ type: 'button' }
- = expanded_by_default? ? _('Collapse') : _('Expand')
- %p
- = s_('GroupSettings|The default name for the initial branch of new repositories created in the group.')
- .settings-content
- = form_for @group, url: group_path(@group, anchor: 'js-default-branch-name'), html: { class: 'fieldset-form' } do |f|
- = form_errors(@group)
- - fallback_branch_name = "<code>#{Gitlab::DefaultBranch.value(object: @group)}</code>"
-
- %fieldset
- .form-group
- = f.label :default_branch_name, _('Default initial branch name'), class: 'label-light'
- = f.text_field :default_branch_name, value: group.namespace_settings&.default_branch_name, placeholder: Gitlab::DefaultBranch.value(object: @group), class: 'form-control'
- %span.form-text.text-muted
- = (s_("GroupSettings|If not specified at the group or instance level, the default is %{default_initial_branch_name}. Does not affect existing repositories.") % { default_initial_branch_name: fallback_branch_name }).html_safe
-
- = f.hidden_field :redirect_target, value: "repository_settings"
- = f.submit _('Save changes'), class: 'btn gl-button btn-confirm'
diff --git a/app/views/groups/settings/repository/show.html.haml b/app/views/groups/settings/repository/show.html.haml
index a5819320405..072c8c4d821 100644
--- a/app/views/groups/settings/repository/show.html.haml
+++ b/app/views/groups/settings/repository/show.html.haml
@@ -4,4 +4,4 @@
- deploy_token_description = s_('DeployTokens|Group deploy tokens allow access to the packages, repositories, and registry images within the group.')
= render "shared/deploy_tokens/index", group_or_project: @group, description: deploy_token_description
-= render "initial_branch_name", group: @group
+= render "default_branch", group: @group
diff --git a/app/views/ide/_show.html.haml b/app/views/ide/_show.html.haml
index 755c4151115..95c15612adf 100644
--- a/app/views/ide/_show.html.haml
+++ b/app/views/ide/_show.html.haml
@@ -9,5 +9,5 @@
#ide.ide-loading{ data: ide_data }
.text-center
- .gl-spinner.gl-spinner-md
+ = gl_loading_icon(size: 'md')
%h2.clgray= _('Loading the GitLab IDE...')
diff --git a/app/views/import/shared/_errors.html.haml b/app/views/import/shared/_errors.html.haml
index badd8c1278f..3e8a99c541a 100644
--- a/app/views/import/shared/_errors.html.haml
+++ b/app/views/import/shared/_errors.html.haml
@@ -1,8 +1,8 @@
- if @errors.present?
- .gl-alert.gl-alert-danger.gl-mb-5
- .gl-alert-container
- = sprite_icon('error', size: 16, css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title')
- .gl-alert-content
- .gl-alert-body
- - @errors.each do |error|
- = error
+ = render 'shared/global_alert',
+ variant: :danger,
+ dismissible: false,
+ alert_class: 'gl-mb-5' do
+ .gl-alert-body
+ - @errors.each do |error|
+ = error
diff --git a/app/views/jira_connect/oauth_callbacks/index.html.haml b/app/views/jira_connect/oauth_callbacks/index.html.haml
new file mode 100644
index 00000000000..d35834bf05d
--- /dev/null
+++ b/app/views/jira_connect/oauth_callbacks/index.html.haml
@@ -0,0 +1 @@
+%p= s_('Integrations|You can close this window.')
diff --git a/app/views/layouts/_head.html.haml b/app/views/layouts/_head.html.haml
index 5ca4a2f9888..15cd9bece71 100644
--- a/app/views/layouts/_head.html.haml
+++ b/app/views/layouts/_head.html.haml
@@ -38,6 +38,7 @@
= render 'layouts/startup_css', { startup_filename: local_assigns.fetch(:startup_filename, nil) }
- if user_application_theme == 'gl-dark'
+ %meta{ name: 'color-scheme', content: 'dark light' }
= stylesheet_link_tag_defer "application_dark"
= yield :page_specific_styles
= stylesheet_link_tag_defer "application_utilities_dark"
@@ -56,7 +57,7 @@
= Gon::Base.render_data(nonce: content_security_policy_nonce)
- = javascript_include_tag locale_path unless I18n.locale == :en
+ = render_if_exists 'layouts/header/translations'
= webpack_bundle_tag "sentry" if Gitlab.config.sentry.enabled
= webpack_bundle_tag 'performance_bar' if performance_bar_enabled?
diff --git a/app/views/layouts/_header_search.html.haml b/app/views/layouts/_header_search.html.haml
new file mode 100644
index 00000000000..d2fe9a9a6ee
--- /dev/null
+++ b/app/views/layouts/_header_search.html.haml
@@ -0,0 +1,24 @@
+#js-header-search.header-search{ data: { 'search-context' => header_search_context.to_json,
+'search-path' => search_path,
+'issues-path' => issues_dashboard_path,
+'mr-path' => merge_requests_dashboard_path,
+'autocomplete-path' => search_autocomplete_path } }
+ = form_tag search_path, method: :get do |_f|
+ .gl-search-box-by-type
+ = sprite_icon('search', css_class: 'gl-search-box-by-type-search-icon gl-icon')
+ %input{ id: 'search', name: 'search', type: "text", placeholder: s_('GlobalSearch|Search GitLab'), class: 'form-control gl-form-input gl-search-box-by-type-input', autocomplete: 'off' }
+
+ = hidden_field_tag :group_id, header_search_context[:group][:id] if header_search_context[:group]
+ = hidden_field_tag :project_id, header_search_context[:project][:id] if header_search_context[:project]
+
+ - if header_search_context[:group] || header_search_context[:project]
+ = hidden_field_tag :scope, header_search_context[:scope]
+ = hidden_field_tag :search_code, header_search_context[:code_search]
+
+ = hidden_field_tag :snippets, header_search_context[:for_snippets]
+ = hidden_field_tag :repository_ref, header_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'
diff --git a/app/views/layouts/_page.html.haml b/app/views/layouts/_page.html.haml
index b7299df1bc1..a656b61dc8f 100644
--- a/app/views/layouts/_page.html.haml
+++ b/app/views/layouts/_page.html.haml
@@ -3,23 +3,22 @@
= render "layouts/nav/sidebar/#{nav}"
.content-wrapper.content-wrapper-margin{ class: "#{@content_wrapper_class}" }
.mobile-overlay
- = render_if_exists 'layouts/header/verification_reminder'
+ = dispensable_render_if_exists 'layouts/header/verification_reminder'
.alert-wrapper.gl-force-block-formatting-context
- = render 'shared/outdated_browser'
- = render_if_exists "layouts/header/licensed_user_count_threshold"
- = render_if_exists "layouts/header/token_expiry_notification"
- = render "layouts/broadcast"
- = render "layouts/header/read_only_banner"
- = render "layouts/header/registration_enabled_callout"
- = render "layouts/nav/classification_level_banner"
+ = dispensable_render 'shared/outdated_browser'
+ = dispensable_render_if_exists "layouts/header/licensed_user_count_threshold"
+ = dispensable_render_if_exists "layouts/header/token_expiry_notification"
+ = dispensable_render "layouts/broadcast"
+ = dispensable_render "layouts/header/read_only_banner"
+ = dispensable_render "layouts/header/registration_enabled_callout"
+ = dispensable_render "layouts/nav/classification_level_banner"
= yield :flash_message
- = render "shared/service_ping_consent"
- = render_two_factor_auth_recovery_settings_check
- = render_if_exists "layouts/header/ee_subscribable_banner"
- = render_if_exists "layouts/header/seats_count_alert"
- = render_if_exists "shared/namespace_storage_limit_alert"
- = render_if_exists "shared/namespace_user_cap_reached_alert"
- = render_if_exists "shared/new_user_signups_cap_reached_alert"
+ = dispensable_render "shared/service_ping_consent"
+ = dispensable_render_if_exists "layouts/header/ee_subscribable_banner"
+ = dispensable_render_if_exists "layouts/header/seats_count_alert"
+ = dispensable_render_if_exists "shared/namespace_storage_limit_alert"
+ = dispensable_render_if_exists "shared/namespace_user_cap_reached_alert"
+ = dispensable_render_if_exists "shared/new_user_signups_cap_reached_alert"
= yield :page_level_alert
= yield :group_invite_members_banner
- unless @hide_breadcrumbs
diff --git a/app/views/layouts/group.html.haml b/app/views/layouts/group.html.haml
index 58fed89dfe7..940724e0e4a 100644
--- a/app/views/layouts/group.html.haml
+++ b/app/views/layouts/group.html.haml
@@ -6,6 +6,9 @@
- display_namespace_storage_limit_alert!
- @left_sidebar = true
+- content_for :flash_message do
+ = render "layouts/header/storage_enforcement_banner", namespace: @group
+
- content_for :page_specific_javascripts do
- if current_user
= javascript_tag do
diff --git a/app/views/layouts/header/_default.html.haml b/app/views/layouts/header/_default.html.haml
index 871d1213c0e..512a4185bee 100644
--- a/app/views/layouts/header/_default.html.haml
+++ b/app/views/layouts/header/_default.html.haml
@@ -38,17 +38,10 @@
= render 'layouts/header/new_dropdown', class: 'gl-display-none gl-sm-display-block'
- if top_nav_show_search
- search_menu_item = top_nav_search_menu_item_attrs
- %li.nav-item.d-none.d-lg-block.m-auto
+ %li.nav-item.header-search-new.d-none.d-lg-block.m-auto
- unless current_controller?(:search)
- if Feature.enabled?(:new_header_search)
- #js-header-search.header-search{ data: { 'search-context' => header_search_context.to_json,
- 'search-path' => search_path,
- 'issues-path' => issues_dashboard_path,
- 'mr-path' => merge_requests_dashboard_path,
- 'autocomplete-path' => search_autocomplete_path } }
- .gl-search-box-by-type
- = sprite_icon('search', css_class: 'gl-search-box-by-type-search-icon gl-icon')
- %input{ type: "text", placeholder: s_('GlobalSearch|Search GitLab'), class: 'form-control gl-form-input gl-search-box-by-type-input', id: 'search', autocomplete: 'off' }
+ = render 'layouts/header_search'
- else
= render 'layouts/search'
%li.nav-item{ class: 'd-none d-sm-inline-block d-lg-none' }
@@ -68,7 +61,8 @@
= number_with_delimiter(issues_count)
- if header_link?(:merge_requests)
= nav_link(path: 'dashboard#merge_requests', html_options: { class: "user-counter dropdown" }) do
- = link_to assigned_mrs_dashboard_path, class: 'dashboard-shortcuts-merge_requests', title: _('Merge requests'), aria: { label: _('Merge requests') },
+ - top_level_link = Feature.enabled?(:mr_attention_requests, default_enabled: :yaml) ? attention_requested_mrs_dashboard_path : assigned_mrs_dashboard_path
+ = link_to top_level_link, class: 'dashboard-shortcuts-merge_requests', title: _('Merge requests'), aria: { label: _('Merge requests') },
data: { qa_selector: 'merge_requests_shortcut_button',
toggle: "dropdown",
placement: 'bottom',
@@ -84,6 +78,13 @@
%ul
%li.dropdown-header
= _('Merge requests')
+ - if Feature.enabled?(:mr_attention_requests, default_enabled: :yaml)
+ %li#js-need-attention-nav
+ #js-need-attention-nav-onboarding
+ = link_to attention_requested_mrs_dashboard_path, class: 'gl-display-flex! gl-align-items-center js-prefetch-document' do
+ = _('Need your attention')
+ = gl_badge_tag user_merge_requests_counts[:attention_requested_count], { size: :sm, variant: user_merge_requests_counts[:attention_requested_count] == 0 ? :neutral : :warning }, { class: 'merge-request-badge gl-ml-auto js-attention-count' }
+ %li.divider
%li
= link_to assigned_mrs_dashboard_path, class: 'gl-display-flex! gl-align-items-center js-prefetch-document' do
= _('Assigned to you')
diff --git a/app/views/layouts/header/_registration_enabled_callout.html.haml b/app/views/layouts/header/_registration_enabled_callout.html.haml
index 90f3ac61614..d1d23c86c81 100644
--- a/app/views/layouts/header/_registration_enabled_callout.html.haml
+++ b/app/views/layouts/header/_registration_enabled_callout.html.haml
@@ -1,14 +1,17 @@
- return unless show_registration_enabled_user_callout?
= render 'shared/global_alert',
- title: _('Open registration is enabled on your instance.'),
+ title: _('Anyone can register for an account.'),
variant: :warning,
alert_class: 'js-registration-enabled-callout',
alert_data: { feature_id: Users::CalloutsHelper::REGISTRATION_ENABLED_CALLOUT, dismiss_endpoint: callouts_path },
close_button_data: { testid: 'close-registration-enabled-callout' } do
.gl-alert-body
- = html_escape(_('%{anchorOpen}Learn more%{anchorClose} about how you can customize / disable registration on your instance.')) % { anchorOpen: "<a href=\"#{help_page_path('user/admin_area/settings/sign_up_restrictions')}\" class=\"gl-link\">".html_safe, anchorClose: '</a>'.html_safe }
+ = _('Only allow anyone to register for accounts on GitLab instances that you intend to be used by anyone. Allowing anyone to register makes GitLab instances more vulnerable.')
.gl-alert-actions
= link_to general_admin_application_settings_path(anchor: 'js-signup-settings'), class: 'btn gl-alert-action btn-confirm btn-md gl-button' do
%span.gl-button-text
- = _('View setting')
+ = _('Turn off')
+ %button.btn.gl-alert-action.btn-default.btn-md.gl-button.js-close
+ %span.gl-button-text
+ = _('Acknowledge')
diff --git a/app/views/layouts/header/_storage_enforcement_banner.html.haml b/app/views/layouts/header/_storage_enforcement_banner.html.haml
new file mode 100644
index 00000000000..851fc57e44d
--- /dev/null
+++ b/app/views/layouts/header/_storage_enforcement_banner.html.haml
@@ -0,0 +1,9 @@
+- return unless current_user
+- namespace = local_assigns.fetch(:namespace)
+- banner_info = storage_enforcement_banner_info(namespace)
+- return unless banner_info.present?
+
+= render 'shared/global_alert', variant: :warning, alert_class: 'js-storage-enforcement-banner', alert_data: { feature_id: banner_info[:callouts_feature_name], dismiss_endpoint: banner_info[:callouts_path], group_id: namespace.id, defer_links: "true" } do
+ .gl-alert-body
+ = banner_info[:text]
+ = banner_info[:learn_more_link]
diff --git a/app/views/layouts/header/_translations.html.haml b/app/views/layouts/header/_translations.html.haml
new file mode 100644
index 00000000000..979f39ad3e0
--- /dev/null
+++ b/app/views/layouts/header/_translations.html.haml
@@ -0,0 +1 @@
+= javascript_include_tag locale_path unless I18n.locale == :en
diff --git a/app/views/layouts/notify.html.haml b/app/views/layouts/notify.html.haml
index e922b505be8..3b979f69cac 100644
--- a/app/views/layouts/notify.html.haml
+++ b/app/views/layouts/notify.html.haml
@@ -3,7 +3,10 @@
%meta{ content: "text/html; charset=utf-8", "http-equiv" => "Content-Type" }
%title
GitLab
- = stylesheet_link_tag 'notify'
+ - if Feature.enabled?(:enhanced_notify_css)
+ = stylesheet_link_tag 'notify_enhanced'
+ - else
+ = stylesheet_link_tag 'notify'
= yield :head
%body
.content
diff --git a/app/views/layouts/profile.html.haml b/app/views/layouts/profile.html.haml
index 17153e72e6e..322a77116c8 100644
--- a/app/views/layouts/profile.html.haml
+++ b/app/views/layouts/profile.html.haml
@@ -5,4 +5,8 @@
- @left_sidebar = true
- enable_search_settings locals: { container_class: 'gl-my-5' }
+
+- content_for :flash_message do
+ = render "layouts/header/storage_enforcement_banner", namespace: current_user.namespace
+
= render template: "layouts/application"
diff --git a/app/views/layouts/service_desk.html.haml b/app/views/layouts/service_desk.html.haml
index 26d15a74403..a838ba91d26 100644
--- a/app/views/layouts/service_desk.html.haml
+++ b/app/views/layouts/service_desk.html.haml
@@ -5,7 +5,10 @@
%title
GitLab
-# haml-lint:enable NoPlainNodes
- = stylesheet_link_tag 'notify'
+ - if Feature.enabled?(:enhanced_notify_css)
+ = stylesheet_link_tag 'notify_enhanced'
+ - else
+ = stylesheet_link_tag 'notify'
= yield :head
%body
.content
diff --git a/app/views/notify/_note_email.html.haml b/app/views/notify/_note_email.html.haml
index ad0c873bf56..55984472047 100644
--- a/app/views/notify/_note_email.html.haml
+++ b/app/views/notify/_note_email.html.haml
@@ -25,11 +25,11 @@
= content_for :head do
= stylesheet_link_tag 'mailers/highlighted_diff_email'
- %table
+ %table.code
= render partial: "projects/diffs/email_line",
collection: discussion.truncated_diff_lines(diff_limit: diff_limit),
as: :line,
locals: { diff_file: discussion.diff_file }
-%div{ style: note_style }
+.md{ style: note_style }
= markdown(note.note, pipeline: :email, author: note.author, current_user: @recipient, issuable_reference_expansion_enabled: true)
diff --git a/app/views/notify/access_token_created_email.html.haml b/app/views/notify/access_token_created_email.html.haml
new file mode 100644
index 00000000000..9eea8f44142
--- /dev/null
+++ b/app/views/notify/access_token_created_email.html.haml
@@ -0,0 +1,7 @@
+%p
+ = _('Hi %{username}!') % { username: sanitize_name(@user.name) }
+%p
+ = html_escape(_('A new personal access token, named %{token_name}, has been created.')) % { token_name: @token_name }
+%p
+ - pat_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: @target_url }
+ = html_escape(_('You can check it in your %{pat_link_start}personal access tokens%{pat_link_end} settings.')) % { pat_link_start: pat_link_start, pat_link_end: '</a>'.html_safe }
diff --git a/app/views/notify/access_token_created_email.text.erb b/app/views/notify/access_token_created_email.text.erb
new file mode 100644
index 00000000000..caf01410de6
--- /dev/null
+++ b/app/views/notify/access_token_created_email.text.erb
@@ -0,0 +1,5 @@
+<%= _('Hi %{username}!') % { username: sanitize_name(@user.name) } %>
+
+<%= _('A new personal access token, named %{token_name}, has been created.') % { token_name: @token_name } %>
+
+<%= _('You can check it in your in your personal access tokens settings %{pat_link}.') % { pat_link: @target_url } %>
diff --git a/app/views/notify/issue_due_email.html.haml b/app/views/notify/issue_due_email.html.haml
index c9cd9c32b54..e512d7732e2 100644
--- a/app/views/notify/issue_due_email.html.haml
+++ b/app/views/notify/issue_due_email.html.haml
@@ -8,5 +8,5 @@
This issue is due on: #{@issue.due_date.to_s(:medium)}
- if @issue.description
- %div
- = markdown(@issue.description, pipeline: :email, author: @issue.author, current_user: @recipient, issuable_reference_expansion_enabled: true)
+ .md
+ = markdown(@issue.description, pipeline: :email, author: @issue.author, current_user: @recipient, issuable_reference_expansion_enabled: true)
diff --git a/app/views/notify/new_issue_email.html.haml b/app/views/notify/new_issue_email.html.haml
index 439604a950a..592b3f453af 100644
--- a/app/views/notify/new_issue_email.html.haml
+++ b/app/views/notify/new_issue_email.html.haml
@@ -7,5 +7,5 @@
= assignees_label(@issue)
- if @issue.description
- %div
- = markdown(@issue.description, pipeline: :email, author: @issue.author, current_user: @recipient, issuable_reference_expansion_enabled: true)
+ .md
+ = markdown(@issue.description, pipeline: :email, author: @issue.author, current_user: @recipient, issuable_reference_expansion_enabled: true)
diff --git a/app/views/notify/new_merge_request_email.html.haml b/app/views/notify/new_merge_request_email.html.haml
index 54fb6573c26..f67ac5f8fb2 100644
--- a/app/views/notify/new_merge_request_email.html.haml
+++ b/app/views/notify/new_merge_request_email.html.haml
@@ -15,5 +15,5 @@
= render_if_exists 'notify/merge_request_approvers', presenter: @mr_presenter
- if @merge_request.description
- %div
+ .md
= markdown(@merge_request.description, pipeline: :email, author: @merge_request.author, current_user: @recipient, issuable_reference_expansion_enabled: true)
diff --git a/app/views/notify/new_release_email.html.haml b/app/views/notify/new_release_email.html.haml
index 1cd3a2340c6..09c0e7a8abd 100644
--- a/app/views/notify/new_release_email.html.haml
+++ b/app/views/notify/new_release_email.html.haml
@@ -1,7 +1,7 @@
- release_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: @target_url }
- description_details = { tag: @release.tag, name: @project.name, release_link_start: release_link_start, release_link_end: '</a>'.html_safe }
-%div{ style: "font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif;" }
+.md{ style: "font-family: 'Helvetica Neue',Helvetica,Arial,sans-serif;" }
%p
= _("A new Release %{tag} for %{name} was published. Visit the %{release_link_start}Releases page%{release_link_end} to read more about it.").html_safe % description_details
diff --git a/app/views/notify/service_desk_new_note_email.html.haml b/app/views/notify/service_desk_new_note_email.html.haml
index 186bdf133e3..0c16cf3315f 100644
--- a/app/views/notify/service_desk_new_note_email.html.haml
+++ b/app/views/notify/service_desk_new_note_email.html.haml
@@ -1,5 +1,5 @@
- if Gitlab::CurrentSettings.email_author_in_body
%div
= _("%{author_link} wrote:").html_safe % { author_link: link_to(@note.author_name, user_url(@note.author)) }
-%div
+.md
= markdown(@note.note, pipeline: :email, author: @note.author, issuable_reference_expansion_enabled: true)
diff --git a/app/views/profiles/accounts/show.html.haml b/app/views/profiles/accounts/show.html.haml
index 97056db6b74..fdcee3670b7 100644
--- a/app/views/profiles/accounts/show.html.haml
+++ b/app/views/profiles/accounts/show.html.haml
@@ -5,7 +5,6 @@
= render 'shared/global_alert',
variant: :info,
alert_class: 'gl-my-5',
- is_contained: true,
dismissible: false do
.gl-alert-body
= s_('Profiles|Some options are unavailable for LDAP accounts')
@@ -14,7 +13,6 @@
= render 'shared/global_alert',
variant: :success,
alert_class: 'gl-my-5',
- is_contained: true,
close_button_class: 'js-close-2fa-enabled-success-alert' do
.gl-alert-body
= html_escape(_('You have set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}.')) % { anchorOpen: '<a href="%{href}">'.html_safe % { href: help_page_path('user/profile/account/two_factor_authentication', anchor: 'generate-new-recovery-codes-using-ssh') }, anchorClose: '</a>'.html_safe }
diff --git a/app/views/profiles/chat_names/_chat_name.html.haml b/app/views/profiles/chat_names/_chat_name.html.haml
index 3206fca6bcd..8f80c9fdc6c 100644
--- a/app/views/profiles/chat_names/_chat_name.html.haml
+++ b/app/views/profiles/chat_names/_chat_name.html.haml
@@ -24,4 +24,4 @@
= _('Never')
%td
- = link_to _('Remove'), profile_chat_name_path(chat_name), method: :delete, class: 'gl-button btn btn-danger float-right', data: { confirm: _('Are you sure you want to revoke this nickname?') }
+ = link_to _('Remove'), profile_chat_name_path(chat_name), method: :delete, class: 'gl-button btn btn-danger float-right', aria: { label: _('Remove') }, data: { confirm: _('Are you sure you want to remove this nickname?'), confirm_btn_variant: 'danger' }
diff --git a/app/views/profiles/two_factor_auths/show.html.haml b/app/views/profiles/two_factor_auths/show.html.haml
index aae6212f964..5f8b21b2646 100644
--- a/app/views/profiles/two_factor_auths/show.html.haml
+++ b/app/views/profiles/two_factor_auths/show.html.haml
@@ -40,12 +40,10 @@
= _('Time based: Yes')
= form_tag profile_two_factor_auth_path, method: :post do |f|
- if @error
- .gl-alert.gl-alert-danger.gl-mb-5
- .gl-alert-container
- .gl-alert-content
- %p.gl-alert-body.gl-md-0
- = @error[:message]
- = link_to _('Try the troubleshooting steps here.'), help_page_path('user/profile/account/two_factor_authentication.md', anchor: 'troubleshooting'), target: '_blank', rel: 'noopener noreferrer'
+ = render 'shared/global_alert', title: @error[:message], variant: :danger, dismissible: false do
+ .gl-alert-body
+ = link_to _('Try the troubleshooting steps here.'), help_page_path('user/profile/account/two_factor_authentication.md', anchor: 'troubleshooting'), target: '_blank', rel: 'noopener noreferrer'
+
.form-group
= label_tag :pin_code, _('Pin code'), class: "label-bold"
= text_field_tag :pin_code, nil, class: "form-control gl-form-input", required: true, data: { qa_selector: 'pin_code_field' }
@@ -113,7 +111,7 @@
%span.gl-text-gray-500
= _("no name set")
%td= registration[:created_at].to_date.to_s(:medium)
- %td= link_to _('Delete'), registration[:delete_path], method: :delete, class: "gl-button btn btn-danger float-right", data: { confirm: _('Are you sure you want to delete this device? This action cannot be undone.') }
+ %td= link_to _('Delete'), registration[:delete_path], method: :delete, class: "gl-button btn btn-danger float-right", data: { confirm: _('Are you sure you want to delete this device? This action cannot be undone.'), confirm_btn_variant: "danger" }, aria: { label: _('Delete') }
- else
.settings-message.text-center
diff --git a/app/views/projects/_activity.html.haml b/app/views/projects/_activity.html.haml
index c5a0b6a1428..05166395067 100644
--- a/app/views/projects/_activity.html.haml
+++ b/app/views/projects/_activity.html.haml
@@ -11,4 +11,4 @@
.content_list.project-activity{ :"data-href" => activity_project_path(@project) }
.loading
- .gl-spinner.gl-spinner-md
+ = gl_loading_icon(size: 'md')
diff --git a/app/views/projects/_commit_button.html.haml b/app/views/projects/_commit_button.html.haml
index 2c18921d874..d987c4b1033 100644
--- a/app/views/projects/_commit_button.html.haml
+++ b/app/views/projects/_commit_button.html.haml
@@ -2,6 +2,6 @@
= button_tag 'Commit changes', id: 'commit-changes', class: 'gl-button btn btn-confirm js-commit-button qa-commit-button'
= link_to _('Cancel'), cancel_path,
- class: 'gl-button btn btn-default gl-ml-3', data: {confirm: leave_edit_message}
+ id: 'cancel-changes', class: 'gl-button btn btn-default gl-ml-3', data: {confirm: leave_edit_message, confirm_btn_variant: "danger"}, aria: { label: _('Discard changes') }
= render 'shared/projects/edit_information'
diff --git a/app/views/projects/_deletion_failed.html.haml b/app/views/projects/_deletion_failed.html.haml
index 21c799f5bb6..b713b805009 100644
--- a/app/views/projects/_deletion_failed.html.haml
+++ b/app/views/projects/_deletion_failed.html.haml
@@ -1,10 +1,7 @@
- project = local_assigns.fetch(:project)
- return unless project.delete_error.present?
-.project-deletion-failed-message.gl-alert.gl-alert-warning
- .gl-alert-container
- = sprite_icon('warning', size: 16, css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title')
- .gl-alert-content
- .gl-alert-body
- This project was scheduled for deletion, but failed with the following message:
- = project.delete_error
+= render 'shared/global_alert', variant: :warning, dismissible: false, alert_class: 'project-deletion-failed-message' do
+ .gl-alert-body
+ This project was scheduled for deletion, but failed with the following message:
+ = project.delete_error
diff --git a/app/views/projects/_files.html.haml b/app/views/projects/_files.html.haml
index 2f4a61865f8..a7cf50623f0 100644
--- a/app/views/projects/_files.html.haml
+++ b/app/views/projects/_files.html.haml
@@ -12,8 +12,7 @@
.info-well.gl-display-none.gl-sm-display-flex.project-last-commit.gl-flex-direction-column
#js-last-commit.gl-m-auto
- .gl-spinner-container.m-auto
- = loading_icon(size: 'md', color: 'dark', css_class: 'align-text-bottom')
+ = gl_loading_icon(size: 'md')
#js-code-owners
- if is_project_overview
diff --git a/app/views/projects/_gitlab_import_modal.html.haml b/app/views/projects/_gitlab_import_modal.html.haml
deleted file mode 100644
index 689e100ab96..00000000000
--- a/app/views/projects/_gitlab_import_modal.html.haml
+++ /dev/null
@@ -1,14 +0,0 @@
-#gitlab_import_modal.modal
- .modal-dialog
- .modal-content
- .modal-header
- %h3.modal-title Import projects from GitLab.com
- %button.close{ type: "button", "data-dismiss": "modal", "aria-label" => _('Close') }
- %span{ "aria-hidden": "true" } &times;
- .modal-body
- To enable importing projects from GitLab.com,
- - if current_user.admin?
- as administrator you need to configure
- - else
- ask your GitLab administrator to configure
- = link_to 'OAuth integration', help_page_path("integration/gitlab")
diff --git a/app/views/projects/_import_project_pane.html.haml b/app/views/projects/_import_project_pane.html.haml
index aca7b73267b..a8b809d1871 100644
--- a/app/views/projects/_import_project_pane.html.haml
+++ b/app/views/projects/_import_project_pane.html.haml
@@ -8,7 +8,7 @@
.import-buttons
- if gitlab_project_import_enabled?
.import_gitlab_project.has-tooltip{ data: { container: 'body', qa_selector: 'gitlab_import_button' } }
- = link_to new_import_gitlab_project_path, class: 'gl-button btn-default btn btn_import_gitlab_project js-import-project-btn', data: { platform: 'gitlab_export', **tracking_attrs_data(track_label, 'click_button', 'gitlab_export') } do
+ = link_to '#', class: 'gl-button btn-default btn btn_import_gitlab_project js-import-project-btn', data: { href: new_import_gitlab_project_path, platform: 'gitlab_export', **tracking_attrs_data(track_label, 'click_button', 'gitlab_export') } do
.gl-button-icon
= sprite_icon('tanuki')
= _("GitLab export")
@@ -36,12 +36,11 @@
%div
- if gitlab_import_enabled?
%div
- = link_to status_import_gitlab_path, class: "gl-button btn-default btn import_gitlab js-import-project-btn #{'how_to_import_link' unless gitlab_import_configured?}", data: { platform: 'gitlab_com', **tracking_attrs_data(track_label, 'click_button', 'gitlab_com') } do
+ = link_to status_import_gitlab_path, class: "gl-button btn-default btn import_gitlab js-import-project-btn #{'js-how-to-import-link' unless gitlab_import_configured?}",
+ data: { modal_title: _("Import projects from GitLab.com"), modal_message: import_from_gitlab_message, platform: 'gitlab_com', **tracking_attrs_data(track_label, 'click_button', 'gitlab_com') } do
.gl-button-icon
= sprite_icon('tanuki')
= _("GitLab.com")
- - unless gitlab_import_configured?
- = render 'projects/gitlab_import_modal'
- if fogbugz_import_enabled?
%div
diff --git a/app/views/projects/_invite_groups_modal.html.haml b/app/views/projects/_invite_groups_modal.html.haml
index d16e87d1c26..40dc0009b24 100644
--- a/app/views/projects/_invite_groups_modal.html.haml
+++ b/app/views/projects/_invite_groups_modal.html.haml
@@ -1,3 +1,3 @@
-- return unless can_admin_project_member?(project)
+- return unless can_invite_members_for_project?(project)
.js-invite-groups-modal{ data: common_invite_group_modal_data(project, ProjectMember, 'true') }
diff --git a/app/views/projects/_last_push.html.haml b/app/views/projects/_last_push.html.haml
index 9ba7d25b662..88cce9e71c0 100644
--- a/app/views/projects/_last_push.html.haml
+++ b/app/views/projects/_last_push.html.haml
@@ -1,9 +1,9 @@
- event = last_push_event
- if event && show_last_push_widget?(event)
- .gl-alert.gl-alert-success.mt-2{ role: 'alert' }
- = sprite_icon('check-circle', size: 16, css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title')
- %button.js-close-banner.gl-alert-dismiss{ type: 'button', 'aria-label' => _('Dismiss') }
- = sprite_icon('close', size: 16, css_class: 'gl-icon')
+ = render 'shared/global_alert',
+ variant: :success,
+ alert_class: 'gl-mt-3',
+ close_button_class: 'js-close-banner' do
.gl-alert-body
%span= s_("LastPushEvent|You pushed to")
%strong.gl-display-inline-flex.gl-max-w-50p{ data: { toggle: 'tooltip' }, title: event.ref_name }
diff --git a/app/views/projects/_merge_request_merge_method_settings.html.haml b/app/views/projects/_merge_request_merge_method_settings.html.haml
index 778586a592e..250f7e94e84 100644
--- a/app/views/projects/_merge_request_merge_method_settings.html.haml
+++ b/app/views/projects/_merge_request_merge_method_settings.html.haml
@@ -19,9 +19,9 @@
.text-secondary
= s_('ProjectSettings|Every merge creates a merge commit.')
%br
- = s_('ProjectSettings|Fast-forward merges only.')
+ = s_('ProjectSettings|Merging is only allowed when the source branch is up-to-date with its target.')
%br
- = s_('ProjectSettings|When there is a merge conflict, the user is given the option to rebase.')
+ = s_('ProjectSettings|When semi-linear merge is not possible, the user is given the option to rebase.')
.form-check.mb-2
= form.radio_button :merge_method, :ff, class: "js-merge-method-radio form-check-input", data: { qa_selector: 'merge_ff_radio' }
diff --git a/app/views/projects/_new_project_fields.html.haml b/app/views/projects/_new_project_fields.html.haml
index 966587a9210..1fb045544aa 100644
--- a/app/views/projects/_new_project_fields.html.haml
+++ b/app/views/projects/_new_project_fields.html.haml
@@ -8,7 +8,7 @@
.form-group.project-name.col-sm-12
= f.label :name, class: 'label-bold' do
%span= _("Project name")
- = f.text_field :name, placeholder: "My awesome project", class: "form-control gl-form-input input-lg", data: { track_label: "#{track_label}", track_action: "activate_form_input", track_property: "project_name", track_value: "" }, required: true, aria: { required: true }
+ = f.text_field :name, placeholder: "My awesome project", class: "form-control gl-form-input input-lg", data: { qa_selector: 'project_name', track_label: "#{track_label}", track_action: "activate_form_input", track_property: "project_name", track_value: "" }, required: true, aria: { required: true }
.form-group.project-path.col-sm-6
= f.label :namespace_id, class: 'label-bold' do
%span= _('Project URL')
@@ -29,14 +29,13 @@
.form-group.project-path.col-sm-6
= f.label :path, class: 'label-bold' do
%span= _("Project slug")
- = f.text_field :path, placeholder: "my-awesome-project", class: "form-control gl-form-input", required: true, aria: { required: true }, data: { username: current_user.username }
+ = f.text_field :path, placeholder: "my-awesome-project", class: "form-control gl-form-input", required: true, aria: { required: true }, data: { qa_selector: 'project_path', username: current_user.username }
- if current_user.can_create_group?
.form-text.text-muted
- link_start_group_path = '<a href="%{path}">' % { path: new_group_path }
- project_tip = s_('ProjectsNew|Want to house several dependent projects under the same namespace? %{link_start}Create a group.%{link_end}') % { link_start: link_start_group_path, link_end: '</a>' }
= project_tip.html_safe
-.gl-alert.gl-alert-success.gl-mb-4.gl-display-none.js-user-readme-repo
- = sprite_icon('check-circle', size: 16, css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title')
+= render 'shared/global_alert', alert_class: "gl-mb-4 gl-display-none js-user-readme-repo", dismissible: false, variant: :success do
.gl-alert-body
- help_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: help_page_path('user/profile/index', anchor: 'add-details-to-your-profile-with-a-readme') }
= html_escape(_('%{project_path} is a project that you can use to add a README to your GitLab profile. Create a public project and initialize the repository with a README to get started. %{help_link_start}Learn more.%{help_link_end}')) % { project_path: "<strong>#{current_user.username} / #{current_user.username}</strong>".html_safe, help_link_start: help_link_start, help_link_end: '</a>'.html_safe }
@@ -44,14 +43,15 @@
.form-group
= f.label :description, class: 'label-bold' do
= s_('ProjectsNew|Project description %{tag_start}(optional)%{tag_end}').html_safe % { tag_start: '<span>'.html_safe, tag_end: '</span>'.html_safe }
- = f.text_area :description, placeholder: s_('ProjectsNew|Description format'), class: "form-control gl-form-input", rows: 3, maxlength: 250, data: { track_label: "#{track_label}", track_action: "activate_form_input", track_property: "project_description", track_value: "" }
+ = f.text_area :description, placeholder: s_('ProjectsNew|Description format'), class: "form-control gl-form-input", rows: 3, maxlength: 250, data: { qa_selector: 'project_description', track_label: "#{track_label}", track_action: "activate_form_input", track_property: "project_description", track_value: "" }
-.js-deployment-target-select
+- unless Gitlab::CurrentSettings.current_application_settings.hide_third_party_offers?
+ .js-deployment-target-select
= f.label :visibility_level, class: 'label-bold' do
= s_('ProjectsNew|Visibility Level')
= link_to sprite_icon('question-o'), help_page_path('public_access/public_access'), aria: { label: 'Documentation for Visibility Level' }, target: '_blank', rel: 'noopener noreferrer'
-= render 'shared/visibility_level', f: f, visibility_level: visibility_level.to_i, can_change_visibility_level: true, form_model: @project, with_label: false
+= render 'shared/visibility_level', f: f, visibility_level: visibility_level.to_i, can_change_visibility_level: true, form_model: @project, with_label: false, data: { qa_selector: 'visibility_radios'}
- if !hide_init_with_readme
= f.label :project_configuration, class: 'label-bold' do
@@ -74,5 +74,5 @@
- e.variant(:unchecked_free_indicator) do
= render 'new_project_initialize_with_sast', experiment_name: e.name, track_label: track_label, checked: false, with_free_badge: true
-= f.submit _('Create project'), class: "btn gl-button btn-confirm", data: { track_label: "#{track_label}", track_action: "click_button", track_property: "create_project", track_value: "" }
+= f.submit _('Create project'), class: "btn gl-button btn-confirm", data: { qa_selector: 'project_create_button', track_label: "#{track_label}", track_action: "click_button", track_property: "create_project", track_value: "" }
= link_to _('Cancel'), dashboard_projects_path, class: 'btn gl-button btn-default btn-cancel', data: { track_label: "#{track_label}", track_action: "click_button", track_property: "cancel", track_value: "" }
diff --git a/app/views/projects/_project_templates.html.haml b/app/views/projects/_project_templates.html.haml
index 68489fba06c..d00ed2afa3c 100644
--- a/app/views/projects/_project_templates.html.haml
+++ b/app/views/projects/_project_templates.html.haml
@@ -1,11 +1,10 @@
- f ||= local_assigns[:f]
.project-templates-buttons
- %ul.nav-tabs.nav-links.nav.scrolling-tabs
- %li.built-in-tab
- %a.nav-link.active{ href: "#built-in", data: { toggle: 'tab'} }
- = _('Built-in')
- = gl_tab_counter_badge Gitlab::ProjectTemplate.all.count + Gitlab::SampleDataTemplate.all.count
+ = gl_tabs_nav({ class: 'nav-links scrolling-tabs gl-display-flex gl-flex-grow-1 gl-flex-nowrap gl-border-0' }) do
+ = gl_tab_link_to '#built-in', tab_class: 'built-in-tab', class: 'active', data: { toggle: 'tab' } do
+ = _('Built-in')
+ = gl_tab_counter_badge Gitlab::ProjectTemplate.all.count + Gitlab::SampleDataTemplate.all.count
.tab-content
.project-templates-buttons.import-buttons.tab-pane.active#built-in
diff --git a/app/views/projects/artifacts/_artifact.html.haml b/app/views/projects/artifacts/_artifact.html.haml
index 229de2f759c..9e548582396 100644
--- a/app/views/projects/artifacts/_artifact.html.haml
+++ b/app/views/projects/artifacts/_artifact.html.haml
@@ -57,5 +57,5 @@
= sprite_icon('folder-open', css_class: 'gl-icon')
- if can?(current_user, :destroy_artifacts, @project)
- = link_to project_artifact_path(@project, artifact), data: { placement: 'top', container: 'body', confirm: _('Are you sure you want to delete these artifacts?') }, method: :delete, title: _('Delete artifacts'), ref: 'tooltip', aria: { label: _('Delete artifacts') }, class: 'gl-button btn btn-danger btn-icon has-tooltip' do
+ = link_to project_artifact_path(@project, artifact), data: { placement: 'top', container: 'body', confirm: _('Are you sure you want to delete these artifacts?'), confirm_btn_variant: "danger" }, method: :delete, title: _('Delete artifacts'), ref: 'tooltip', aria: { label: _('Delete artifacts') }, class: 'gl-button btn btn-danger btn-icon has-tooltip' do
= sprite_icon('remove', css_class: 'gl-icon')
diff --git a/app/views/projects/blob/_blob.html.haml b/app/views/projects/blob/_blob.html.haml
index 919cafe7ce8..85b9a69ab4c 100644
--- a/app/views/projects/blob/_blob.html.haml
+++ b/app/views/projects/blob/_blob.html.haml
@@ -21,8 +21,7 @@
project_path: @project.full_path,
target_branch: project.empty_repo? ? ref : @ref,
original_branch: @ref } }
- .gl-spinner-container
- = loading_icon(size: 'md')
+ = gl_loading_icon(size: 'md')
- else
%article.file-holder
= render 'projects/blob/header', blob: blob
diff --git a/app/views/projects/blob/_editor.html.haml b/app/views/projects/blob/_editor.html.haml
index 41333c416de..c9303e19d5d 100644
--- a/app/views/projects/blob/_editor.html.haml
+++ b/app/views/projects/blob/_editor.html.haml
@@ -45,5 +45,4 @@
- if local_assigns[:path]
.js-edit-mode-pane#preview.hide
.center
- %h2
- %i.icon-spinner.icon-spin
+ = gl_loading_icon(size: 'lg')
diff --git a/app/views/projects/blob/_header.html.haml b/app/views/projects/blob/_header.html.haml
index 74df53a8d15..8260aa0fb7e 100644
--- a/app/views/projects/blob/_header.html.haml
+++ b/app/views/projects/blob/_header.html.haml
@@ -5,13 +5,7 @@
.file-actions.gl-display-flex.gl-align-items-center.gl-flex-wrap.gl-md-justify-content-end<
= render 'projects/blob/viewer_switcher', blob: blob unless blame
- - if Feature.enabled?(:consolidated_edit_button, @project)
- = render 'shared/web_ide_button', blob: blob
- - else
- = edit_blob_button(@project, @ref, @path, blob: blob)
- = ide_edit_button(@project, @ref, @path, blob: blob)
- - if can_view_pipeline_editor?(@project) && @path == @project.ci_config_path_or_default
- = link_to "Pipeline Editor", project_ci_pipeline_editor_path(@project, branch_name: @ref), class: "btn gl-button btn-confirm-secondary gl-ml-3"
+ = render 'shared/web_ide_button', blob: blob
.btn-group{ role: "group", class: ("gl-ml-3" if current_user) }>
= render_if_exists 'projects/blob/header_file_locks_link'
- if current_user
diff --git a/app/views/projects/blob/_upload.html.haml b/app/views/projects/blob/_upload.html.haml
index 6d2751bb7d4..1d3bec1ad44 100644
--- a/app/views/projects/blob/_upload.html.haml
+++ b/app/views/projects/blob/_upload.html.haml
@@ -20,8 +20,8 @@
= render 'shared/new_commit_form', placeholder: placeholder, ref: local_assigns[:ref]
.form-actions
- = button_tag class: 'btn gl-button btn-confirm btn-upload-file', id: 'submit-all', type: 'button' do
- .gl-spinner.gl-mr-2.js-loading-icon.hidden
+ = button_tag class: 'btn gl-button btn-confirm btn-upload-file gl-mr-2', id: 'submit-all', type: 'button' do
+ = gl_loading_icon(inline: true, css_class: 'gl-mr-2 js-loading-icon hidden')
= button_title
= link_to _("Cancel"), '#', class: "btn gl-button btn-default btn-cancel", "data-dismiss" => "modal"
diff --git a/app/views/projects/blob/edit.html.haml b/app/views/projects/blob/edit.html.haml
index 8378ce2c7e5..773137ff3f2 100644
--- a/app/views/projects/blob/edit.html.haml
+++ b/app/views/projects/blob/edit.html.haml
@@ -4,14 +4,16 @@
- webpack_preload_asset_tag('monaco')
- if @conflict
- .gl-alert.gl-alert-danger.gl-mb-5.gl-mt-5
- .gl-alert-container
- = sprite_icon('error', size: 16, css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title')
- .gl-alert-content
- .gl-alert-body
- Someone edited the file the same time you did. Please check out
- = link_to _('the file'), project_blob_path(@project, tree_join(@branch_name, @file_path)), target: "_blank", rel: 'noopener noreferrer', class: 'gl-link'
- and make sure your changes will not unintentionally remove theirs.
+ = render 'shared/global_alert',
+ alert_class: 'gl-mb-5 gl-mt-5',
+ variant: :danger,
+ dismissible: false do
+ - blob_url = project_blob_path(@project, @id)
+ - external_link_icon = content_tag 'span', { aria: { label: _('Opens new window') }} do
+ - sprite_icon('external-link', css_class: 'gl-icon').html_safe
+ - blob_link_start = '<a href="%{url}" class="gl-link" target="_blank" rel="noopener noreferrer">'.html_safe % { url: blob_url }
+ = _('Someone edited the file the same time you did. Please check out %{link_start}the file %{icon}%{link_end} and make sure your changes will not unintentionally remove theirs.').html_safe % { link_start: blob_link_start, link_end: '</a>'.html_safe , icon: external_link_icon }
+
%h3.page-title.blob-edit-page-title
Edit file
diff --git a/app/views/projects/blob/new.html.haml b/app/views/projects/blob/new.html.haml
index 2aeffa88c8f..60877db581f 100644
--- a/app/views/projects/blob/new.html.haml
+++ b/app/views/projects/blob/new.html.haml
@@ -1,16 +1,13 @@
- breadcrumb_title _("Repository")
- page_title _("New File"), @path.presence, @ref
-%h3.page-title.blob-new-page-title#js-code-quality-walkthrough
+%h3.page-title.blob-new-page-title
= _('New file')
- .js-code-quality-walkthrough{ data: { step: 'commit_ci_file' } }
.file-editor
= form_tag(project_create_blob_path(@project, @id), method: :post, class: 'js-edit-blob-form js-new-blob-form js-quick-submit js-requires-input', data: blob_editor_paths(@project)) do
= render 'projects/blob/editor', ref: @ref
= render 'shared/new_commit_form', placeholder: "Add new file"
- - if params[:code_quality_walkthrough]
- = hidden_field_tag 'code_quality_walkthrough', 'true'
= hidden_field_tag 'content', '', id: 'file-content'
= render 'projects/commit_button', ref: @ref,
cancel_path: project_tree_path(@project, @id)
diff --git a/app/views/projects/blob/viewers/_gitlab_ci_yml_loading.html.haml b/app/views/projects/blob/viewers/_gitlab_ci_yml_loading.html.haml
index cf57f1b531d..2b8f62d98bf 100644
--- a/app/views/projects/blob/viewers/_gitlab_ci_yml_loading.html.haml
+++ b/app/views/projects/blob/viewers/_gitlab_ci_yml_loading.html.haml
@@ -1,4 +1,4 @@
-= loading_icon(css_class: "gl-vertical-align-text-bottom mr-1")
+= gl_loading_icon(inline: true, css_class: "gl-mr-2!")
= s_('Pipelines|Validating GitLab CI configuration…')
= link_to _('Learn more'), help_page_path('ci/yaml/index')
diff --git a/app/views/projects/blob/viewers/_loading.html.haml b/app/views/projects/blob/viewers/_loading.html.haml
index 18fd0d87ce6..9cb934da7c0 100644
--- a/app/views/projects/blob/viewers/_loading.html.haml
+++ b/app/views/projects/blob/viewers/_loading.html.haml
@@ -1,2 +1 @@
-.text-center.gl-mt-4.gl-mb-3
- = loading_icon(size: "md", css_class: "qa-spinner")
+= gl_loading_icon(size: "md", css_class: "qa-spinner gl-my-4")
diff --git a/app/views/projects/blob/viewers/_loading_auxiliary.html.haml b/app/views/projects/blob/viewers/_loading_auxiliary.html.haml
index 5a2212e0b4e..19aa96a9302 100644
--- a/app/views/projects/blob/viewers/_loading_auxiliary.html.haml
+++ b/app/views/projects/blob/viewers/_loading_auxiliary.html.haml
@@ -1,2 +1,2 @@
-= loading_icon(css_class: "gl-vertical-align-text-bottom")
+= gl_loading_icon(inline: true)
= _("Analyzing file…")
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
index db4b04eaeb8..5e355ecc4b8 100644
--- a/app/views/projects/blob/viewers/_metrics_dashboard_yml_loading.html.haml
+++ b/app/views/projects/blob/viewers/_metrics_dashboard_yml_loading.html.haml
@@ -1,4 +1,4 @@
-= loading_icon(css_class: "gl-vertical-align-text-bottom mr-1")
+= gl_loading_icon(inline: true, css_class: "mr-1")
= _('Metrics Dashboard YAML definition') + '…'
= link_to _('Learn more'), help_page_path('operations/metrics/dashboards/yaml.md')
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 c48ab84654f..d9e965246a8 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 @@
-= loading_icon(css_class: "gl-vertical-align-text-bottom gl-mr-1")
+= gl_loading_icon(inline: true, css_class: "gl-mr-1")
Validating Route Map…
= link_to 'Learn more', help_page_path('ci/environments/index.md', anchor: 'go-from-source-files-to-public-pages')
diff --git a/app/views/projects/blob/viewers/_sketch.html.haml b/app/views/projects/blob/viewers/_sketch.html.haml
index 08c21258d3f..4feaa7392fd 100644
--- a/app/views/projects/blob/viewers/_sketch.html.haml
+++ b/app/views/projects/blob/viewers/_sketch.html.haml
@@ -1,3 +1,2 @@
.file-content#js-sketch-viewer{ data: { endpoint: blob_raw_path } }
- .text-center.gl-mt-4.gl-mb-3.js-loading-icon
- = loading_icon(size: "md")
+ = gl_loading_icon(size: "md", css_class: "gl-my-4 js-loading-icon")
diff --git a/app/views/projects/blob/viewers/_stl.html.haml b/app/views/projects/blob/viewers/_stl.html.haml
index f98deebacf9..8bf0339fc3c 100644
--- a/app/views/projects/blob/viewers/_stl.html.haml
+++ b/app/views/projects/blob/viewers/_stl.html.haml
@@ -1,6 +1,6 @@
.file-content.is-stl-loading
.text-center#js-stl-viewer{ data: { endpoint: blob_raw_path } }
- = loading_icon(size: "md", css_class: "gl-mt-4 gl-mb-3")
+ = gl_loading_icon(size: "md", css_class: "gl-my-4")
.text-center.gl-mt-3.gl-mb-3.stl-controls
.btn-group
%button.gl-button.btn.btn-default.btn-sm.js-material-changer{ data: { type: 'wireframe' } }
diff --git a/app/views/projects/branches/new.html.haml b/app/views/projects/branches/new.html.haml
index 8ee7910de4b..5cc83111b34 100644
--- a/app/views/projects/branches/new.html.haml
+++ b/app/views/projects/branches/new.html.haml
@@ -4,8 +4,7 @@
- if @error
= render 'shared/global_alert',
variant: :danger,
- close_button_class: 'js-close',
- is_contained: true do
+ close_button_class: 'js-close' do
.gl-alert-body
= @error
%h3.page-title
diff --git a/app/views/projects/ci/secure_files/show.html.haml b/app/views/projects/ci/secure_files/show.html.haml
new file mode 100644
index 00000000000..db0734be6bd
--- /dev/null
+++ b/app/views/projects/ci/secure_files/show.html.haml
@@ -0,0 +1,5 @@
+- @content_class = "limit-container-width"
+
+- page_title s_('Secure Files')
+
+#js-ci-secure-files{ data: { project_id: @project.id } }
diff --git a/app/views/projects/commit/_commit_box.html.haml b/app/views/projects/commit/_commit_box.html.haml
index 36d3520cb59..a3343aa4228 100644
--- a/app/views/projects/commit/_commit_box.html.haml
+++ b/app/views/projects/commit/_commit_box.html.haml
@@ -37,13 +37,13 @@
- @commit.parents.each do |parent|
= link_to parent.short_id, project_commit_path(@project, parent), class: "commit-sha"
.commit-info.branches
- .gl-spinner.vertical-align-middle
+ = gl_loading_icon(inline: true, css_class: 'gl-vertical-align-middle')
.well-segment.merge-request-info
.icon-container
= custom_icon('mr_bold')
%span.commit-info.merge-requests{ 'data-project-commit-path' => merge_requests_project_commit_path(@project, @commit.id, format: :json) }
- .gl-spinner.vertical-align-middle
+ = gl_loading_icon(inline: true, css_class: 'gl-vertical-align-middle')
- if can?(current_user, :read_pipeline, @last_pipeline)
.well-segment.pipeline-info
diff --git a/app/views/projects/commits/_commits.html.haml b/app/views/projects/commits/_commits.html.haml
index 9e0dd93c683..02b5fe00ad0 100644
--- a/app/views/projects/commits/_commits.html.haml
+++ b/app/views/projects/commits/_commits.html.haml
@@ -22,7 +22,7 @@
- if context_commits.present?
%li.commit-header.js-commit-header
%span.font-weight-bold= n_("%d previously merged commit", "%d previously merged commits", context_commits.count) % context_commits.count
- - if project.context_commits_enabled? && can_update_merge_request
+ - if can_update_merge_request
%button.gl-button.btn.btn-default.ml-3.add-review-item-modal-trigger{ type: "button", data: { context_commits_empty: 'false' } }
= _('Add/remove')
@@ -34,13 +34,14 @@
= render partial: 'projects/commits/commit', collection: context_commits, locals: { project: project, ref: ref, merge_request: merge_request }
- if hidden > 0
- %li.gl-alert.gl-alert-warning
- .gl-alert-container
- = sprite_icon('warning', size: 16, css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title')
- .gl-alert-content
+ %li
+ = render 'shared/global_alert',
+ variant: :warning,
+ dismissible: false do
+ .gl-alert-body
= n_('%s additional commit has been omitted to prevent performance issues.', '%s additional commits have been omitted to prevent performance issues.', hidden) % number_with_delimiter(hidden)
-- if project.context_commits_enabled? && can_update_merge_request && context_commits&.empty?
+- if can_update_merge_request && context_commits&.empty?
%button.gl-button.btn.btn-default.mt-3.add-review-item-modal-trigger{ type: "button", data: { context_commits_empty: 'true' } }
= _('Add previously merged commits')
diff --git a/app/views/projects/commits/show.html.haml b/app/views/projects/commits/show.html.haml
index 22a5bada311..36641a8c508 100644
--- a/app/views/projects/commits/show.html.haml
+++ b/app/views/projects/commits/show.html.haml
@@ -34,5 +34,4 @@
%div{ id: dom_id(@project) }
%ol#commits-list.list-unstyled.content_list
= render 'commits', project: @project, ref: @ref
- .loading.hide
- = loading_icon(size: "lg")
+ = gl_loading_icon(size: 'lg', css_class: 'loading hide')
diff --git a/app/views/projects/diffs/_content.html.haml b/app/views/projects/diffs/_content.html.haml
index 718f129cba8..23f9afe8352 100644
--- a/app/views/projects/diffs/_content.html.haml
+++ b/app/views/projects/diffs/_content.html.haml
@@ -1,3 +1,12 @@
- diff_file = local_assigns.fetch(:diff_file, nil)
+- file_hash = hexdigest(diff_file.file_path)
+
.diff-content
- = render 'projects/diffs/viewer', viewer: diff_file.viewer
+ - if diff_file.has_renderable?
+ %div{ id: "#raw-diff-#{file_hash}", data: { file_hash: file_hash, diff_toggle_entity: 'toHide' } }
+ = render 'projects/diffs/viewer', viewer: diff_file.viewer
+ %div{ id: "#rendered-diff-#{file_hash}", data: { file_hash: file_hash, diff_toggle_entity: 'toShow' } }
+ = render 'projects/diffs/viewer', viewer: diff_file.rendered.viewer
+ - else
+ = render 'projects/diffs/viewer', viewer: diff_file.viewer
+
diff --git a/app/views/projects/diffs/_file.html.haml b/app/views/projects/diffs/_file.html.haml
index 418a65118f5..0638481d968 100644
--- a/app/views/projects/diffs/_file.html.haml
+++ b/app/views/projects/diffs/_file.html.haml
@@ -25,6 +25,11 @@
= edit_blob_button(@merge_request.source_project, @merge_request.source_branch, diff_file.new_path,
blob: diff_file.blob, link_opts: link_opts)
+ - if diff_file.has_renderable?
+ .btn-group.gl-ml-3
+ = diff_mode_swap_button('rendered', file_hash)
+ = diff_mode_swap_button('raw', file_hash)
+
- if image_diff && image_replaced
= view_file_button(diff_file.old_content_sha, diff_file.old_path, project, replaced: true)
diff --git a/app/views/projects/diffs/_line.html.haml b/app/views/projects/diffs/_line.html.haml
index 330e2f564c9..a5d3328b439 100644
--- a/app/views/projects/diffs/_line.html.haml
+++ b/app/views/projects/diffs/_line.html.haml
@@ -3,7 +3,7 @@
- plain = local_assigns.fetch(:plain, false)
- discussions = local_assigns.fetch(:discussions, nil)
- line_code = diff_file.line_code(line)
-- if discussions && line.discussable?
+- if discussions
- line_discussions = discussions[line_code]
%tr.line_holder{ class: line.type, id: (line_code unless plain) }
@@ -15,11 +15,12 @@
%td.new_line.diff-line-num
%td.line_content.match= line.text
- else
- %td.old_line.diff-line-num{ class: [line.type, ("js-avatar-container" if !plain)], data: { linenumber: line.old_pos } }
+ %td.old_line.diff-line-num{ class: [line.type, ("js-avatar-container" unless plain)], data: { linenumber: line.old_pos } }
- if plain
= diff_link_number(line.type, "new", line.old_pos)
- else
- = add_diff_note_button(line_code, diff_file.position(line), line.type)
+ - if line.discussable?
+ = add_diff_note_button(line_code, diff_file.position(line), line.type)
%a{ href: "##{line_code}", data: { linenumber: diff_link_number(line.type, "new", line.old_pos) } }
%td.new_line.diff-line-num{ class: line.type, data: { linenumber: line.new_pos } }
diff --git a/app/views/projects/diffs/_warning.html.haml b/app/views/projects/diffs/_warning.html.haml
index 1d9b1b13d5c..3d31773694f 100644
--- a/app/views/projects/diffs/_warning.html.haml
+++ b/app/views/projects/diffs/_warning.html.haml
@@ -1,7 +1,6 @@
= render 'shared/global_alert',
title: _('Too many changes to show.'),
variant: :warning,
- is_contained: true,
alert_class: 'gl-mb-5' do
.gl-alert-body
= html_escape(_("To preserve performance only %{strong_open}%{display_size} of %{real_size}%{strong_close} files are displayed.")) % { display_size: diff_files.size, real_size: diff_files.real_size, strong_open: '<strong>'.html_safe, strong_close: '</strong>'.html_safe }
diff --git a/app/views/projects/edit.html.haml b/app/views/projects/edit.html.haml
index f32514141c5..1609d81c0fd 100644
--- a/app/views/projects/edit.html.haml
+++ b/app/views/projects/edit.html.haml
@@ -66,6 +66,8 @@
%p= s_('ProjectSettings|Housekeeping, export, archive, change path, transfer, and delete.')
.settings-content
+ = render_if_exists 'projects/settings/restore', project: @project
+
.sub-section
%h4= _('Housekeeping')
%p
@@ -107,6 +109,6 @@
.save-project-loader.hide
.center
%h2
- .gl-spinner.gl-spinner-md.align-text-bottom
+ = gl_loading_icon(inline: true, size: 'md', css_class: 'gl-vertical-align-middle')
= _('Saving project.')
%p= _('Please wait a moment, this page will automatically refresh when ready.')
diff --git a/app/views/projects/empty.html.haml b/app/views/projects/empty.html.haml
index c3fbf774faa..6a54eedf6c8 100644
--- a/app/views/projects/empty.html.haml
+++ b/app/views/projects/empty.html.haml
@@ -1,5 +1,6 @@
- @content_class = "limit-container-width" unless fluid_layout
- default_branch_name = @project.default_branch_or_main
+- escaped_default_branch_name = default_branch_name.shellescape
- @skip_current_level_breadcrumb = true
= render partial: 'flash_messages', locals: { project: @project }
@@ -31,51 +32,47 @@
%p
= _('You can also upload existing files from your computer using the instructions below.')
.git-empty.js-git-empty
- %fieldset
- %h5= _('Git global setup')
- %pre.bg-light
- :preserve
- git config --global user.name "#{h git_user_name}"
- git config --global user.email "#{h git_user_email}"
+ %h5= _('Git global setup')
+ %pre.bg-light
+ :preserve
+ git config --global user.name "#{h git_user_name}"
+ git config --global user.email "#{h git_user_email}"
- %fieldset
- %h5= _('Create a new repository')
- %pre.bg-light
- :preserve
- git clone #{ content_tag(:span, default_url_to_repo, class: 'js-clone')}
- cd #{h @project.path}
- git switch -c #{h default_branch_name}
- touch README.md
- git add README.md
- git commit -m "add README"
- - if @project.can_current_user_push_to_default_branch?
- %span><
- git push -u origin #{h default_branch_name }
+ %h5= _('Create a new repository')
+ %pre.bg-light
+ :preserve
+ git clone #{ content_tag(:span, default_url_to_repo, class: 'js-clone')}
+ cd #{h @project.path}
+ git switch -c #{h escaped_default_branch_name}
+ touch README.md
+ git add README.md
+ git commit -m "add README"
+ - if @project.can_current_user_push_to_default_branch?
+ %span><
+ git push -u origin #{h escaped_default_branch_name }
- %fieldset
- %h5= _('Push an existing folder')
- %pre.bg-light
- :preserve
- cd existing_folder
- git init --initial-branch=#{h default_branch_name}
- git remote add origin #{ content_tag(:span, default_url_to_repo, class: 'js-clone')}
- git add .
- git commit -m "Initial commit"
- - if @project.can_current_user_push_to_default_branch?
- %span><
- git push -u origin #{h default_branch_name }
+ %h5= _('Push an existing folder')
+ %pre.bg-light
+ :preserve
+ cd existing_folder
+ git init --initial-branch=#{h escaped_default_branch_name}
+ git remote add origin #{ content_tag(:span, default_url_to_repo, class: 'js-clone')}
+ git add .
+ git commit -m "Initial commit"
+ - if @project.can_current_user_push_to_default_branch?
+ %span><
+ git push -u origin #{h escaped_default_branch_name }
- %fieldset
- %h5= _('Push an existing Git repository')
- %pre.bg-light
- :preserve
- cd existing_repo
- git remote rename origin old-origin
- git remote add origin #{ content_tag(:span, default_url_to_repo, class: 'js-clone')}
- - if @project.can_current_user_push_to_default_branch?
- %span><
- git push -u origin --all
- git push -u origin --tags
+ %h5= _('Push an existing Git repository')
+ %pre.bg-light
+ :preserve
+ cd existing_repo
+ git remote rename origin old-origin
+ git remote add origin #{ content_tag(:span, default_url_to_repo, class: 'js-clone')}
+ - if @project.can_current_user_push_to_default_branch?
+ %span><
+ git push -u origin --all
+ git push -u origin --tags
- if @project.upload_anchor_data.present?
= render 'projects/blob/upload', title: _('Upload New File'), placeholder: _('Upload New File'), button_title: _('Upload file'), form_path: project_create_blob_path(@project, default_branch_name), ref: default_branch_name, method: :post
diff --git a/app/views/projects/environments/index.html.haml b/app/views/projects/environments/index.html.haml
index 2b05ffe3eea..e4b8750b96c 100644
--- a/app/views/projects/environments/index.html.haml
+++ b/app/views/projects/environments/index.html.haml
@@ -1,19 +1,11 @@
- page_title _("Environments")
- add_page_specific_style 'page_bundles/environments'
-- if Feature.enabled?(:new_environments_table)
- #environments-table{ data: { endpoint: project_environments_path(@project, format: :json),
- "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/index.md"),
- "project-path" => @project.full_path,
- "default-branch-name" => @project.default_branch_or_main } }
-- else
- #environments-list-view{ data: { environments_data: environments_list_data,
- "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/index.md"),
- "project-path" => @project.full_path,
- "default-branch-name" => @project.default_branch_or_main } }
+#environments-table{ data: { endpoint: project_environments_path(@project, format: :json),
+ "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/index.md"),
+ "project-path" => @project.full_path,
+ "project-id" => @project.id,
+ "default-branch-name" => @project.default_branch_or_main } }
diff --git a/app/views/projects/find_file/show.html.haml b/app/views/projects/find_file/show.html.haml
index 194b10e9ef4..af5ad06d30e 100644
--- a/app/views/projects/find_file/show.html.haml
+++ b/app/views/projects/find_file/show.html.haml
@@ -23,5 +23,4 @@
= _('There are no matching files')
%p.text-secondary
= _('Try using a different search term to find the file you are looking for.')
- .text-center.gl-mt-3.loading
- = loading_icon(size: 'md')
+ = gl_loading_icon(size: 'md', css_class: 'gl-mt-3 loading')
diff --git a/app/views/projects/forks/_fork_button.html.haml b/app/views/projects/forks/_fork_button.html.haml
deleted file mode 100644
index 84259890a44..00000000000
--- a/app/views/projects/forks/_fork_button.html.haml
+++ /dev/null
@@ -1,20 +0,0 @@
-- avatar = namespace_icon(namespace, 100)
-- can_create_project = current_user.can?(:create_projects, namespace)
-
-.bordered-box.fork-thumbnail.text-center.gl-m-3.gl-pb-5{ class: ("disabled" unless can_create_project) }
- - if /no_((\w*)_)*avatar/.match(avatar)
- = group_icon(namespace, class: "avatar rect-avatar s100 identicon mx-auto")
- - else
- .avatar-container.s100.mx-auto.gl-mt-5
- = image_tag(avatar, class: "avatar s100")
- %h5.gl-mt-3
- = namespace.human_name
- - if forked_project = namespace.find_fork_of(@project)
- = link_to _("Go to project"), project_path(forked_project), class: "btn gl-button btn-default"
- - else
- %div{ class: ('has-tooltip' unless can_create_project),
- title: (_('You have reached your project limit') unless can_create_project) }
- = link_to _("Select"), project_forks_path(@project, namespace_key: namespace.id),
- data: { qa_selector: 'fork_namespace_button', qa_name: namespace.human_name },
- method: "POST",
- class: ["btn gl-button btn-confirm", ("disabled" unless can_create_project)]
diff --git a/app/views/projects/forks/error.html.haml b/app/views/projects/forks/error.html.haml
index 30e2e9f19d9..7933e0e07b3 100644
--- a/app/views/projects/forks/error.html.haml
+++ b/app/views/projects/forks/error.html.haml
@@ -4,7 +4,6 @@
title: _('Fork Error!'),
variant: :danger,
alert_class: 'gl-mt-5',
- is_contained: true,
dismissible: false do
.gl-alert-body
%p
diff --git a/app/views/projects/forks/new.html.haml b/app/views/projects/forks/new.html.haml
index 8848fbae9cb..7243852e1f5 100644
--- a/app/views/projects/forks/new.html.haml
+++ b/app/views/projects/forks/new.html.haml
@@ -1,30 +1,13 @@
- page_title s_("ForkProject|Fork project")
-- if Feature.enabled?(:fork_project_form, @project, default_enabled: :yaml)
- #fork-groups-mount-element{ data: { fork_illustration: image_path('illustrations/project-create-new-sm.svg'),
- endpoint: new_project_fork_path(@project, format: :json),
- new_group_path: new_group_path,
- project_full_path: project_path(@project),
- visibility_help_path: help_page_path("public_access/public_access"),
- project_id: @project.id,
- project_name: @project.name,
- project_path: @project.path,
- project_description: @project.description,
- project_visibility: @project.visibility,
- restricted_visibility_levels: Gitlab::CurrentSettings.restricted_visibility_levels.to_json } }
-- else
- .row.gl-mt-3
- .col-lg-3
- %h4.gl-mt-0
- = s_("ForkProject|Fork project")
- %p
- = s_("ForkProject|A fork is a copy of a project.")
- %br
- = s_('ForkProject|Forking a repository allows you to make changes without affecting the original project.')
- .col-lg-9
- - if @own_namespace.present?
- .fork-thumbnail-container.js-fork-content
- %h5.gl-mt-0.gl-mb-0.gl-ml-3.gl-mr-3
- = s_("ForkProject|Select a namespace to fork the project")
- = render 'fork_button', namespace: @own_namespace
- #fork-groups-mount-element{ data: { endpoint: new_project_fork_path(@project, format: :json) } }
+#fork-groups-mount-element{ data: { fork_illustration: image_path('illustrations/project-create-new-sm.svg'),
+ endpoint: new_project_fork_path(@project, format: :json),
+ new_group_path: new_group_path,
+ project_full_path: project_path(@project),
+ visibility_help_path: help_page_path("public_access/public_access"),
+ project_id: @project.id,
+ project_name: @project.name,
+ project_path: @project.path,
+ project_description: @project.description,
+ project_visibility: @project.visibility,
+ restricted_visibility_levels: Gitlab::CurrentSettings.restricted_visibility_levels.to_json } }
diff --git a/app/views/projects/google_cloud/gcp_regions/index.html.haml b/app/views/projects/google_cloud/gcp_regions/index.html.haml
new file mode 100644
index 00000000000..3a6f8ca059d
--- /dev/null
+++ b/app/views/projects/google_cloud/gcp_regions/index.html.haml
@@ -0,0 +1,8 @@
+- add_to_breadcrumbs _('Google Cloud'), @google_cloud_path
+- breadcrumb_title _('Regions')
+- page_title _('Regions')
+
+- @content_class = "limit-container-width" unless fluid_layout
+
+= form_tag project_google_cloud_gcp_regions_path(@project), method: 'post' do
+ #js-google-cloud{ data: @js_data }
diff --git a/app/views/projects/harbor/repositories/index.html.haml b/app/views/projects/harbor/repositories/index.html.haml
new file mode 100644
index 00000000000..b3f5b91596d
--- /dev/null
+++ b/app/views/projects/harbor/repositories/index.html.haml
@@ -0,0 +1,9 @@
+- page_title _("Harbor Registry")
+- @content_class = "limit-container-width" unless fluid_layout
+
+#js-harbor-registry-list-project{ data: { endpoint: project_harbor_registry_index_path(@project),
+ "no_containers_image" => image_path('illustrations/docker-empty-state.svg'),
+ "containers_error_image" => image_path('illustrations/docker-error-state.svg'),
+ "help_page_path" => help_page_path('user/packages/container_registry/index'),
+ connection_error: (!!@connection_error).to_s,
+ invalid_path_error: (!!@invalid_path_error).to_s, } }
diff --git a/app/views/projects/imports/show.html.haml b/app/views/projects/imports/show.html.haml
index 0c1efab2195..8096bc6cead 100644
--- a/app/views/projects/imports/show.html.haml
+++ b/app/views/projects/imports/show.html.haml
@@ -4,7 +4,7 @@
.save-project-loader
.center
%h2
- = loading_icon
+ = gl_loading_icon(inline: true)
= import_in_progress_title
- if !has_ci_cd_only_params? && @project.external_import?
%p.monospace git clone --bare #{@project.safe_import_url}
diff --git a/app/views/projects/issues/_alert_moved_from_service_desk.html.haml b/app/views/projects/issues/_alert_moved_from_service_desk.html.haml
index 662270fb8e1..26bd65fbe26 100644
--- a/app/views/projects/issues/_alert_moved_from_service_desk.html.haml
+++ b/app/views/projects/issues/_alert_moved_from_service_desk.html.haml
@@ -4,7 +4,6 @@
= render 'shared/global_alert',
variant: :warning,
- is_contained: true,
close_button_class: 'js-close',
alert_class: 'hide js-alert-moved-from-service-desk-warning gl-mt-5' do
.gl-alert-body.gl-mr-3
diff --git a/app/views/projects/issues/_form.html.haml b/app/views/projects/issues/_form.html.haml
index d85c448b29a..34e46807fb6 100644
--- a/app/views/projects/issues/_form.html.haml
+++ b/app/views/projects/issues/_form.html.haml
@@ -1,3 +1,3 @@
= form_for [@project, @issue],
- html: { class: 'issue-form common-note-form gl-mt-3 js-quick-submit js-requires-input' } do |f|
+ html: { class: 'issue-form common-note-form gl-mt-3 js-quick-submit gl-show-field-errors' } do |f|
= render 'shared/issuable/form', f: f, issuable: @issue
diff --git a/app/views/projects/issues/_service_desk_empty_state.html.haml b/app/views/projects/issues/_service_desk_empty_state.html.haml
index 3e0b80700fe..efc319ed8df 100644
--- a/app/views/projects/issues/_service_desk_empty_state.html.haml
+++ b/app/views/projects/issues/_service_desk_empty_state.html.haml
@@ -6,7 +6,7 @@
- if Gitlab::ServiceDesk.supported?
.empty-state
.svg-content
- = render 'shared/empty_states/icons/service_desk_empty_state.svg'
+ = render partial: 'shared/empty_states/icons/service_desk_empty_state', formats: :svg
.text-content
%h4= title_text
@@ -25,7 +25,7 @@
- else
.empty-state
.svg-content
- = render 'shared/empty_states/icons/service_desk_setup.svg'
+ = render partial: 'shared/empty_states/icons/service_desk_setup', formats: :svg
.text-content
- if can_edit_project_settings
%h4= s_('ServiceDesk|Service Desk is not supported')
diff --git a/app/views/projects/issues/index.html.haml b/app/views/projects/issues/index.html.haml
index 10c48177ae4..d74b6c0639c 100644
--- a/app/views/projects/issues/index.html.haml
+++ b/app/views/projects/issues/index.html.haml
@@ -14,7 +14,7 @@
project_path: @project.full_path } }
- if Feature.enabled?(:vue_issues_list, @project&.group, default_enabled: :yaml)
- .js-issues-list{ data: project_issues_list_data(@project, current_user, finder) }
+ .js-issues-list{ data: project_issues_list_data(@project, current_user) }
- if @can_bulk_update
= render 'shared/issuable/bulk_update_sidebar', type: :issues
- elsif project_issues(@project).exists?
diff --git a/app/views/projects/learn_gitlab/index.html.haml b/app/views/projects/learn_gitlab/index.html.haml
index 9924b172875..0e950c26d34 100644
--- a/app/views/projects/learn_gitlab/index.html.haml
+++ b/app/views/projects/learn_gitlab/index.html.haml
@@ -5,8 +5,4 @@
= render 'projects/invite_members_modal', project: @project
-- experiment(:confetti_post_signup, actor: current_user) do |e|
- - e.control do
- #js-learn-gitlab-app{ data: data }
- - e.candidate do
- #js-learn-gitlab-app{ data: data.merge(invite_members: 'true') }
+#js-learn-gitlab-app{ data: data }
diff --git a/app/views/projects/merge_requests/_commits.html.haml b/app/views/projects/merge_requests/_commits.html.haml
index ecf5df5d3b4..14ddaf8d2b7 100644
--- a/app/views/projects/merge_requests/_commits.html.haml
+++ b/app/views/projects/merge_requests/_commits.html.haml
@@ -5,7 +5,7 @@
= custom_icon ('illustration_no_commits')
%h4
= _('There are no commits yet.')
- - if @project&.context_commits_enabled? && can_update_merge_request
+ - if can_update_merge_request
%p
= _('Push commits to the source branch or add previously merged commits to review them.')
%button.btn.gl-button.btn-confirm.add-review-item-modal-trigger{ type: "button", data: { commits_empty: 'true', context_commits_empty: 'true' } }
@@ -14,5 +14,5 @@
%ol#commits-list.list-unstyled
= render "projects/commits/commits", merge_request: @merge_request
-- if @project&.context_commits_enabled? && can_update_merge_request && @merge_request.iid
+- if can_update_merge_request && @merge_request.iid
.add-review-item-modal-wrapper{ data: { context_commits_path: context_commits_project_json_merge_request_url(@merge_request&.project, @merge_request, :json), target_branch: @merge_request.target_branch, merge_request_iid: @merge_request.iid, project_id: @merge_request.project.id } }
diff --git a/app/views/projects/merge_requests/_mr_title.html.haml b/app/views/projects/merge_requests/_mr_title.html.haml
index f2a271da771..d894aeaad65 100644
--- a/app/views/projects/merge_requests/_mr_title.html.haml
+++ b/app/views/projects/merge_requests/_mr_title.html.haml
@@ -6,12 +6,12 @@
= cache(cache_key, expires_in: 1.day) do
- if @merge_request.closed_or_merged_without_fork?
- .gl-alert.gl-alert-danger.gl-mb-5
- .gl-alert-container
- = sprite_icon('error', size: 16, css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title')
- .gl-alert-content
- .gl-alert-body
- The source project of this merge request has been removed.
+ = render 'shared/global_alert',
+ alert_class: 'gl-mb-5',
+ variant: :danger,
+ dismissible: false do
+ .gl-alert-body
+ = _('The source project of this merge request has been removed.')
.detail-page-header.border-bottom-0.pt-0.pb-0
.detail-page-header-body
@@ -45,9 +45,9 @@
%li= link_to _('Report abuse'), new_abuse_report_path(user_id: @merge_request.author.id, ref_url: merge_request_url(@merge_request))
- if can_update_merge_request
- = link_to _('Edit'), edit_project_merge_request_path(@project, @merge_request), class: "d-none d-md-block btn gl-button btn-default btn-grouped js-issuable-edit", data: { qa_selector: "edit_button" }
+ = link_to _('Edit'), edit_project_merge_request_path(@project, @merge_request), class: "gl-display-none gl-md-display-block btn gl-button btn-default btn-grouped js-issuable-edit", data: { qa_selector: "edit_button" }
- if can_update_merge_request && !are_close_and_open_buttons_hidden
= render 'projects/merge_requests/close_reopen_draft_report_toggle'
- elsif !@merge_request.merged?
- = link_to _('Report abuse'), new_abuse_report_path(user_id: @merge_request.author.id, ref_url: merge_request_url(@merge_request)), class: 'gl-display-none gl-md-display-block gl-button btn btn-default float-right gl-ml-3', title: _('Report abuse')
+ = link_to _('Report abuse'), new_abuse_report_path(user_id: @merge_request.author.id, ref_url: merge_request_url(@merge_request)), class: 'gl-display-none gl-md-display-block gl-button btn btn-default gl-float-right gl-ml-3', title: _('Report abuse')
diff --git a/app/views/projects/merge_requests/creations/_new_compare.html.haml b/app/views/projects/merge_requests/creations/_new_compare.html.haml
index ea778517374..e2ac8ef5abc 100644
--- a/app/views/projects/merge_requests/creations/_new_compare.html.haml
+++ b/app/views/projects/merge_requests/creations/_new_compare.html.haml
@@ -29,8 +29,7 @@
= dropdown_content
= dropdown_loading
.card-footer
- .text-center
- .js-source-loading.mt-1.gl-spinner
+ = gl_loading_icon(css_class: 'js-source-loading gl-my-3')
%ul.list-unstyled.mr_source_commit
.col-lg-6
@@ -58,8 +57,7 @@
= dropdown_content
= dropdown_loading
.card-footer
- .text-center
- .js-target-loading.mt-1.gl-spinner
+ = gl_loading_icon(css_class: 'js-target-loading gl-my-3')
%ul.list-unstyled.mr_target_commit
- if @merge_request.errors.any?
diff --git a/app/views/projects/merge_requests/creations/_new_submit.html.haml b/app/views/projects/merge_requests/creations/_new_submit.html.haml
index 0036f1b4bde..253f50d5090 100644
--- a/app/views/projects/merge_requests/creations/_new_submit.html.haml
+++ b/app/views/projects/merge_requests/creations/_new_submit.html.haml
@@ -48,4 +48,4 @@
.mr-loading-status
.loading.hide
- .gl-spinner.gl-spinner-md
+ = gl_loading_icon(size: 'md')
diff --git a/app/views/projects/merge_requests/invalid.html.haml b/app/views/projects/merge_requests/invalid.html.haml
index 28fd0b83824..aa68fe031bb 100644
--- a/app/views/projects/merge_requests/invalid.html.haml
+++ b/app/views/projects/merge_requests/invalid.html.haml
@@ -9,16 +9,15 @@
= render "projects/merge_requests/mr_title"
= render "projects/merge_requests/mr_box"
- .gl-alert.gl-alert-danger
- .gl-alert-container
- = sprite_icon('error', size: 16, css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title')
- .gl-alert-content{ role: 'alert' }
- .gl-alert-body
- - if @merge_request.for_fork? && !@merge_request.source_project
- = err_fork_project_removed
- - elsif !@merge_request.source_branch_exists?
- = err_source_branch.html_safe % { branch_badge: gl_badge_tag(@merge_request.source_branch, variant: :info, size: :sm), path_badge: gl_badge_tag(@merge_request.source_project_path, variant: :info, size: :sm) }
- - elsif !@merge_request.target_branch_exists?
- = err_target_branch.html_safe % { branch_badge: gl_badge_tag(@merge_request.target_branch, variant: :info, size: :sm), path_badge: gl_badge_tag(@merge_request.source_project_path, variant: :info, size: :sm) }
- - else
- = err_internal
+ = render 'shared/global_alert',
+ variant: :danger,
+ dismissible: false do
+ .gl-alert-body
+ - if @merge_request.for_fork? && !@merge_request.source_project
+ = err_fork_project_removed
+ - elsif !@merge_request.source_branch_exists?
+ = err_source_branch.html_safe % { branch_badge: gl_badge_tag(@merge_request.source_branch, variant: :info, size: :sm), path_badge: gl_badge_tag(@merge_request.source_project_path, variant: :info, size: :sm) }
+ - elsif !@merge_request.target_branch_exists?
+ = err_target_branch.html_safe % { branch_badge: gl_badge_tag(@merge_request.target_branch, variant: :info, size: :sm), path_badge: gl_badge_tag(@merge_request.source_project_path, variant: :info, size: :sm) }
+ - else
+ = err_internal
diff --git a/app/views/projects/merge_requests/show.html.haml b/app/views/projects/merge_requests/show.html.haml
index a7667d03138..008f2588dbd 100644
--- a/app/views/projects/merge_requests/show.html.haml
+++ b/app/views/projects/merge_requests/show.html.haml
@@ -76,14 +76,12 @@
= render "projects/merge_requests/tabs/pane", name: "pipelines", id: "pipelines", class: "pipelines" do
- if @number_of_pipelines.nonzero?
= render 'projects/commit/pipelines_list', disable_initialization: true, endpoint: pipelines_project_merge_request_path(@project, @merge_request)
- - params = request.query_parameters
- - if Feature.enabled?(:default_merge_ref_for_diffs, @project, default_enabled: :yaml)
- - params = params.merge(diff_head: true)
+ - params = request.query_parameters.merge(diff_head: true)
= render "projects/merge_requests/tabs/pane", name: "diffs", id: "js-diffs-app", class: "diffs", data: diffs_tab_pane_data(@project, @merge_request, params)
.mr-loading-status
.loading.hide
- .gl-spinner.gl-spinner-md
+ = gl_loading_icon(size: 'lg')
= render 'shared/issuable/sidebar', issuable_sidebar: @issuable_sidebar, assignees: @merge_request.assignees, reviewers: @merge_request.reviewers, source_branch: @merge_request.source_branch
@@ -94,5 +92,8 @@
#js-review-bar
+- if Feature.enabled?(:mr_attention_requests, default_enabled: :yaml)
+ #js-need-attention-sidebar-onboarding
+
= render 'projects/invite_members_modal', project: @project
= render 'shared/web_ide_path'
diff --git a/app/views/projects/milestones/show.html.haml b/app/views/projects/milestones/show.html.haml
index dbde3346b81..225f8c7dd66 100644
--- a/app/views/projects/milestones/show.html.haml
+++ b/app/views/projects/milestones/show.html.haml
@@ -15,7 +15,6 @@
= render 'shared/global_alert',
variant: :info,
dismissible: false,
- is_contained: true,
alert_data: { testid: 'no-issues-alert' },
alert_class: 'gl-mt-3 gl-mb-5' do
.gl-alert-body
diff --git a/app/views/projects/mirrors/_mirror_repos.html.haml b/app/views/projects/mirrors/_mirror_repos.html.haml
index b2fa735f76f..3af95633214 100644
--- a/app/views/projects/mirrors/_mirror_repos.html.haml
+++ b/app/views/projects/mirrors/_mirror_repos.html.haml
@@ -37,8 +37,9 @@
.panel-footer
= f.submit _('Mirror repository'), class: 'gl-button btn btn-confirm js-mirror-submit qa-mirror-repository-button', name: :update_remote_mirror
- else
- .gl-alert.gl-alert-info{ role: 'alert' }
- = sprite_icon('information-o', css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title')
+ = render 'shared/global_alert',
+ dismissible: false,
+ variant: :info do
.gl-alert-body
= _('Mirror settings are only available to GitLab administrators.')
diff --git a/app/views/projects/network/show.html.haml b/app/views/projects/network/show.html.haml
index 4cabb930433..b6700c9ed1e 100644
--- a/app/views/projects/network/show.html.haml
+++ b/app/views/projects/network/show.html.haml
@@ -16,5 +16,4 @@
- if @commit
.network-graph.gl-bg-white.gl-overflow-scroll.gl-overflow-x-hidden{ data: { url: @url, commit_url: @commit_url, ref: @ref, commit_id: @commit.id } }
- .text-center.gl-mt-3
- .gl-spinner.gl-spinner-md
+ = gl_loading_icon(size: 'md', css_class: 'gl-mt-3')
diff --git a/app/views/projects/pages/_ssl_limitations_warning.html.haml b/app/views/projects/pages/_ssl_limitations_warning.html.haml
index de74b703e95..24f51aa91e6 100644
--- a/app/views/projects/pages/_ssl_limitations_warning.html.haml
+++ b/app/views/projects/pages/_ssl_limitations_warning.html.haml
@@ -2,6 +2,6 @@
= sprite_icon("warning-solid", css_class: "gl-text-orange-600")
%strong= _("Warning:")
- pages_host = Gitlab.config.pages.host
- - docs_link_start = "<a href='#{help_page_path('user/project/pages/introduction', anchor: 'limitations')}' target='_blank' rel='noopener noreferrer'>".html_safe
+ - docs_link_start = "<a href='#{help_page_path('user/project/pages/introduction', anchor: 'subdomains-of-subdomains')}' target='_blank' rel='noopener noreferrer'>".html_safe
- link_end = '</a>'.html_safe
- = s_("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. %{docs_link_start}Learn more.%{link_end}").html_safe % { pages_host: pages_host, docs_link_start: docs_link_start, link_end: link_end }
+ = s_("GitLabPages|When using Pages under the general domain of a GitLab instance (%{pages_host}), you cannot use HTTPS with subdomains of subdomains. If your namespace or groupname contains a dot, it does not work. This is a limitation of the HTTP Over TLS protocol. HTTP pages work if you don't redirect HTTP to HTTPS. %{docs_link_start}Learn more.%{link_end}").html_safe % { pages_host: pages_host, docs_link_start: docs_link_start, link_end: link_end }
diff --git a/app/views/projects/pages_domains/_certificate.html.haml b/app/views/projects/pages_domains/_certificate.html.haml
index 33db7896065..861305dc93b 100644
--- a/app/views/projects/pages_domains/_certificate.html.haml
+++ b/app/views/projects/pages_domains/_certificate.html.haml
@@ -14,14 +14,13 @@
- lets_encrypt_link_start = "<a href=\"%{lets_encrypt_link_url}\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"text-nowrap\">".html_safe % { lets_encrypt_link_url: lets_encrypt_link_url }
- lets_encrypt_link_end = "</a>".html_safe
= _("Automatic certificate management using %{lets_encrypt_link_start}Let's Encrypt%{lets_encrypt_link_end}").html_safe % { lets_encrypt_link_start: lets_encrypt_link_start, lets_encrypt_link_end: lets_encrypt_link_end }
- %button{ type: "button", id: "pages_domain_auto_ssl_enabled_button",
- class: "js-project-feature-toggle project-feature-toggle mt-2 #{"is-checked" if auto_ssl_available_and_enabled}",
- "aria-label": _("Automatic certificate management using Let's Encrypt") }
+ = render Pajamas::ToggleComponent.new(id: 'pages_domain_auto_ssl_enabled_button',
+ classes: 'js-project-feature-toggle js-enable-ssl-gl-toggle mt-2',
+ is_checked: auto_ssl_available_and_enabled,
+ label: _("Automatic certificate management using Let's Encrypt"),
+ label_position: :hidden)
= f.hidden_field :auto_ssl_enabled?, class: "js-project-feature-toggle-input"
- %span.toggle-icon
- = sprite_icon("status_success_borderless", size: 18, css_class: "gl-text-blue-500 toggle-status-checked")
- = sprite_icon("status_failed_borderless", size: 18, css_class: "gl-text-gray-400 toggle-status-unchecked")
- %p.text-secondary.mt-3
+ %p.gl-text-secondary.gl-mt-1
- docs_link_url = help_page_path("user/project/pages/custom_domains_ssl_tls_certification/lets_encrypt_integration.md")
- docs_link_start = "<a href=\"%{docs_link_url}\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"text-nowrap\">".html_safe % { docs_link_url: docs_link_url }
- docs_link_end = "</a>".html_safe
diff --git a/app/views/projects/pipeline_schedules/_form.html.haml b/app/views/projects/pipeline_schedules/_form.html.haml
index 66aee7dedf3..0818c3d5cff 100644
--- a/app/views/projects/pipeline_schedules/_form.html.haml
+++ b/app/views/projects/pipeline_schedules/_form.html.haml
@@ -15,8 +15,9 @@
= f.text_field :cron_timezone, value: @schedule.cron_timezone, id: 'schedule_cron_timezone', class: 'hidden', name: 'schedule[cron_timezone]', required: true
.form-group.row
.col-md-9
- = f.label :ref, _('Target Branch'), class: 'label-bold'
- = dropdown_tag(_("Select target branch"), options: { toggle_class: 'gl-button btn btn-default js-target-branch-dropdown w-100', dropdown_class: 'git-revision-dropdown w-100', title: _("Select target branch"), filter: true, placeholder: s_("OfSearchInADropdown|Filter"), data: { data: @project.repository.branch_names, default_branch: @project.default_branch } } )
+ = f.label :ref, Feature.enabled?(:pipeline_schedules_with_tags, default_enabled: :yaml) ? _('Target branch or tag') : _('Target branch'), class: 'label-bold'
+ %div{ data: { testid: 'schedule-target-ref' } }
+ .js-target-ref-dropdown{ data: { project_id: @project.id, default_branch: @project.default_branch } }
= f.text_field :ref, value: @schedule.ref, id: 'schedule_ref', class: 'hidden', name: 'schedule[ref]', required: true
.form-group.row.js-ci-variable-list-section
.col-md-9
@@ -24,8 +25,8 @@
#{ s_('PipelineSchedules|Variables') }
%ul.ci-variable-list
- @schedule.variables.each do |variable|
- = render 'ci/variables/variable_row', form_field: 'schedule', variable: variable, only_key_value: true
- = render 'ci/variables/variable_row', form_field: 'schedule', only_key_value: true
+ = render 'ci/variables/variable_row', form_field: 'schedule', variable: variable
+ = render 'ci/variables/variable_row', form_field: 'schedule'
- if @schedule.variables.size > 0
%button.gl-button.btn.btn-confirm-secondary.gl-mt-3.js-secret-value-reveal-button{ type: 'button', data: { secret_reveal_status: "#{@schedule.variables.size == 0}" } }
- if @schedule.variables.size == 0
diff --git a/app/views/projects/pipeline_schedules/_pipeline_schedule.html.haml b/app/views/projects/pipeline_schedules/_pipeline_schedule.html.haml
index 908de68f825..edcd44563f7 100644
--- a/app/views/projects/pipeline_schedules/_pipeline_schedule.html.haml
+++ b/app/views/projects/pipeline_schedules/_pipeline_schedule.html.haml
@@ -3,9 +3,12 @@
%td
= pipeline_schedule.description
%td.branch-name-cell
- = sprite_icon('fork', size: 12)
+ - if pipeline_schedule.for_tag?
+ = sprite_icon('tag', size: 12)
+ - else
+ = sprite_icon('fork', size: 12)
- if pipeline_schedule.ref.present?
- = link_to pipeline_schedule.ref, project_ref_path(@project, pipeline_schedule.ref), class: "ref-name"
+ = link_to pipeline_schedule.ref_for_display, project_ref_path(@project, pipeline_schedule.ref_for_display), class: "ref-name"
%td
- if pipeline_schedule.last_pipeline
.status-icon-container{ class: "ci-status-icon-#{pipeline_schedule.last_pipeline.status}" }
diff --git a/app/views/projects/pipelines/_info.html.haml b/app/views/projects/pipelines/_info.html.haml
index 4e93d7a04e7..54435f675a7 100644
--- a/app/views/projects/pipelines/_info.html.haml
+++ b/app/views/projects/pipelines/_info.html.haml
@@ -27,7 +27,7 @@
- if @pipeline.latest?
= gl_badge_tag s_('Pipelines|latest'), { variant: :success, size: :sm }, { class: 'js-pipeline-url-latest has-tooltip', title: _("Latest pipeline for the most recent commit on this branch") }
- if @pipeline.merge_train_pipeline?
- = gl_badge_tag s_('Pipelines|train'), { variant: :info, size: :sm }, { class: 'js-pipeline-url-train has-tooltip', title: _("This is a merge train pipeline") }
+ = gl_badge_tag s_('Pipelines|merge train'), { variant: :info, size: :sm }, { class: 'js-pipeline-url-train has-tooltip', title: s_("Pipelines|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch.") }
- if @pipeline.has_yaml_errors?
= gl_badge_tag s_('Pipelines|yaml invalid'), { variant: :danger, size: :sm }, { class: 'js-pipeline-url-yaml has-tooltip', title: @pipeline.yaml_errors }
- if @pipeline.failure_reason?
@@ -38,7 +38,7 @@
- popover_content_text = _('Learn more about Auto DevOps')
= gl_badge_tag s_('Pipelines|Auto DevOps'), { variant: :info, size: :sm }, { class: 'js-pipeline-url-autodevops', href: "#", tabindex: "0", role: "button", data: { container: 'body', toggle: 'popover', placement: 'top', html: 'true', triggers: 'focus', title: "<div class='gl-font-weight-normal gl-line-height-normal'>#{popover_title_text}</div>", content: "<a href='#{popover_content_url}' target='_blank' rel='noopener noreferrer nofollow'>#{popover_content_text}</a>" } }
- if @pipeline.detached_merge_request_pipeline?
- = gl_badge_tag s_('Pipelines|detached'), { variant: :info, size: :sm }, { class: 'js-pipeline-url-mergerequest has-tooltip', title: _('Merge request pipelines 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 merge request pipelines.') }
+ = gl_badge_tag s_('Pipelines|merge request'), { variant: :info, size: :sm }, { class: 'js-pipeline-url-mergerequest has-tooltip', title: s_("Pipelines|This pipeline ran on the contents of this merge request's source branch, not the target branch.") }
- if @pipeline.stuck?
= gl_badge_tag s_('Pipelines|stuck'), { variant: :warning, size: :sm }, { class: 'js-pipeline-url-stuck has-tooltip' }
diff --git a/app/views/projects/pipelines/_with_tabs.html.haml b/app/views/projects/pipelines/_with_tabs.html.haml
index e844a3d4779..88e6b98b115 100644
--- a/app/views/projects/pipelines/_with_tabs.html.haml
+++ b/app/views/projects/pipelines/_with_tabs.html.haml
@@ -29,20 +29,7 @@
#js-tab-builds.tab-pane
- if stages.present?
- - if Feature.enabled?(:jobs_tab_vue, @project, default_enabled: :yaml)
- #js-pipeline-jobs-vue{ data: { full_path: @project.full_path, pipeline_iid: @pipeline.iid } }
- - else
- .table-holder.pipeline-holder
- %table.table.ci-table.pipeline
- %thead
- %tr
- %th= _('Status')
- %th= _('Name')
- %th= _('Job ID')
- %th
- %th= _('Coverage')
- %th
- = render partial: "projects/stage/stage", collection: stages, as: :stage
+ #js-pipeline-jobs-vue{ data: { full_path: @project.full_path, pipeline_iid: @pipeline.iid } }
- if @pipeline.failed_builds.present?
#js-tab-failures.build-failures.tab-pane.build-page
diff --git a/app/views/projects/pipelines/charts.html.haml b/app/views/projects/pipelines/charts.html.haml
index 547e2c8a7f4..5a655e7e83d 100644
--- a/app/views/projects/pipelines/charts.html.haml
+++ b/app/views/projects/pipelines/charts.html.haml
@@ -5,4 +5,5 @@
should_render_quality_summary: should_render_quality_summary.to_s,
failed_pipelines_link: project_pipelines_path(@project, page: '1', scope: 'all', status: 'failed'),
coverage_chart_path: charts_project_graph_path(@project, @project.default_branch),
+ test_runs_empty_state_image_path: image_path('illustrations/pipeline.svg'),
default_branch: @project.default_branch } }
diff --git a/app/views/projects/pipelines/index.html.haml b/app/views/projects/pipelines/index.html.haml
index ae76d4905e0..f4b242ffc40 100644
--- a/app/views/projects/pipelines/index.html.haml
+++ b/app/views/projects/pipelines/index.html.haml
@@ -1,28 +1,10 @@
- page_title _('Pipelines')
- add_page_specific_style 'page_bundles/pipelines'
- add_page_specific_style 'page_bundles/ci_status'
-- artifacts_endpoint_placeholder = ':pipeline_artifacts_id'
= render_if_exists "shared/shared_runners_minutes_limit_flash_message"
-- list_url = project_pipelines_path(@project, format: :json, code_quality_walkthrough: params[:code_quality_walkthrough])
+- list_url = project_pipelines_path(@project, format: :json)
- add_page_startup_api_call list_url
-#pipelines-list-vue{ data: { endpoint: list_url,
- project_id: @project.id,
- params: params.to_json,
- "artifacts-endpoint" => downloadable_artifacts_project_pipeline_path(@project, artifacts_endpoint_placeholder, format: :json),
- "artifacts-endpoint-placeholder" => artifacts_endpoint_placeholder,
- "pipeline-schedule-url" => pipeline_schedules_path(@project),
- "empty-state-svg-path" => image_path('illustrations/pipelines_empty.svg'),
- "error-state-svg-path" => image_path('illustrations/pipelines_failed.svg'),
- "no-pipelines-svg-path" => image_path('illustrations/pipelines_pending.svg'),
- "can-create-pipeline" => can?(current_user, :create_pipeline, @project).to_s,
- "new-pipeline-path" => can?(current_user, :create_pipeline, @project) && new_project_pipeline_path(@project),
- "ci-lint-path" => can?(current_user, :create_pipeline, @project) && project_ci_lint_path(@project),
- "reset-cache-path" => can?(current_user, :admin_pipeline, @project) && reset_cache_project_settings_ci_cd_path(@project),
- "has-gitlab-ci" => has_gitlab_ci?(@project).to_s,
- "pipeline-editor-path" => can?(current_user, :create_pipeline, @project) && project_ci_pipeline_editor_path(@project),
- "suggested-ci-templates" => suggested_ci_templates.to_json,
- "code-quality-page-path" => @project.present(current_user: current_user).add_code_quality_ci_yml_path,
- "ci-runner-settings-path" => project_settings_ci_cd_path(@project, ci_runner_templates: true, anchor: 'js-runners-settings') } }
+#pipelines-list-vue{ data: pipelines_list_data(@project, list_url) }
diff --git a/app/views/projects/pipelines/show.html.haml b/app/views/projects/pipelines/show.html.haml
index 70815dbe7a7..ba498352278 100644
--- a/app/views/projects/pipelines/show.html.haml
+++ b/app/views/projects/pipelines/show.html.haml
@@ -20,7 +20,7 @@
.bs-callout.bs-callout-danger
%h4= _('Found errors in your %{gitlab_ci_yml}:') % { gitlab_ci_yml: '.gitlab-ci.yml' }
%ul
- - @pipeline.yaml_errors.split(",").each do |error|
+ - @pipeline.yaml_errors.split("\n").each do |error|
%li= error
- lint_link_url = project_ci_pipeline_editor_path(@project, tab: "LINT_TAB")
- lint_link_start = '<a href="%{url}" class="gl-text-blue-500!">'.html_safe % { url: lint_link_url }
diff --git a/app/views/projects/project_members/import.html.haml b/app/views/projects/project_members/import.html.haml
deleted file mode 100644
index 2f953db0d65..00000000000
--- a/app/views/projects/project_members/import.html.haml
+++ /dev/null
@@ -1,15 +0,0 @@
-- page_title _("Import members")
-
-%h3.page-title
- = _("Import members from another project")
-%p.light
- = _("Only project members will be imported. Group members will be skipped.")
-%hr
-= form_tag apply_import_project_project_members_path(@project), method: 'post' do
- .form-group.row
- = label_tag :source_project_id, _("Project"), class: 'col-form-label col-sm-2'
- .col-sm-10= select_tag(:source_project_id, options_from_collection_for_select(@projects, :id, :name_with_namespace), prompt: "Select project", class: "select2 lg", required: true)
-
- .form-actions
- = button_tag _('Import project members'), class: "btn gl-button btn-success"
- = link_to _("Cancel"), project_project_members_path(@project), class: "btn gl-button btn-cancel"
diff --git a/app/views/projects/project_members/index.html.haml b/app/views/projects/project_members/index.html.haml
index 220e44679cd..f97b9a2b02f 100644
--- a/app/views/projects/project_members/index.html.haml
+++ b/app/views/projects/project_members/index.html.haml
@@ -23,7 +23,7 @@
.js-invite-group-trigger{ data: { classes: 'gl-mt-3 gl-sm-w-auto gl-w-full gl-sm-ml-3', display_text: _('Invite a group') } }
= render 'projects/invite_groups_modal', project: @project
- if can_admin_project_member?(@project)
- .js-invite-members-trigger{ data: { variant: 'success',
+ .js-invite-members-trigger{ data: { variant: 'confirm',
classes: 'gl-mt-3 gl-sm-w-auto gl-w-full gl-sm-ml-3',
trigger_source: 'project-members-page',
display_text: _('Invite members') } }
@@ -39,51 +39,9 @@
%p
= html_escape(_("Members can be added by project %{i_open}Maintainers%{i_close} or %{i_open}Owners%{i_close}")) % { i_open: '<i>'.html_safe, i_close: '</i>'.html_safe }
- - if Feature.disabled?(:invite_members_group_modal, @project.group, default_enabled: :yaml) && can?(current_user, :admin_project_member, @project) && project_can_be_shared?
- - if !membership_locked? && @project.allowed_to_share_with_group?
- %ul.nav-links.nav.nav-tabs.gitlab-tabs{ role: 'tablist' }
- %li.nav-tab{ role: 'presentation' }
- %a.nav-link.active{ href: '#invite-member-pane', id: 'invite-member-tab', data: { toggle: 'tab' }, role: 'tab' }= _("Invite member")
- %li.nav-tab{ role: 'presentation', class: ('active' if membership_locked?) }
- %a.nav-link{ href: '#invite-group-pane', id: 'invite-group-tab', data: { toggle: 'tab', qa_selector: 'invite_group_tab' }, role: 'tab' }= _("Invite group")
-
- .tab-content.gitlab-tab-content
- .tab-pane.active{ id: 'invite-member-pane', role: 'tabpanel' }
- = render 'shared/members/invite_member',
- submit_url: project_project_members_path(@project),
- access_levels: ProjectMember.access_level_roles,
- default_access_level: @project_member.access_level,
- can_import_members?: can_admin_project_member?(@project),
- import_path: import_project_project_members_path(@project)
- .tab-pane{ id: 'invite-group-pane', role: 'tabpanel', class: ('active' if membership_locked?) }
- = render 'shared/members/invite_group',
- submit_url: project_group_links_path(@project),
- access_levels: ProjectGroupLink.access_options,
- default_access_level: ProjectGroupLink.default_access,
- group_link_field: 'link_group_id',
- group_access_field: 'link_group_access',
- groups_select_tag_data: { min_access_level: Gitlab::Access::GUEST, skip_groups: @skip_groups }
- - elsif !membership_locked?
- .invite-member
- = render 'shared/members/invite_member',
- submit_url: project_project_members_path(@project),
- access_levels: ProjectMember.access_level_roles,
- default_access_level: @project_member.access_level,
- can_import_members?: can_admin_project_member?(@project),
- import_path: import_project_project_members_path(@project)
- - elsif @project.allowed_to_share_with_group?
- .invite-group
- = render 'shared/members/invite_group',
- access_levels: ProjectGroupLink.access_options,
- default_access_level: ProjectGroupLink.default_access,
- submit_url: project_group_links_path(@project),
- group_link_field: 'link_group_id',
- group_access_field: 'link_group_access',
- groups_select_tag_data: { min_access_level: Gitlab::Access::GUEST, skip_groups: @skip_groups }
.js-project-members-list-app{ data: { members_data: project_members_app_data_json(@project,
members: @project_members,
group_links: @group_links,
invited: @invited_members,
access_requests: @requesters) } }
- .loading
- .gl-spinner.gl-spinner-md
+ = gl_loading_icon(css_class: 'gl-my-5', size: 'md')
diff --git a/app/views/projects/protected_branches/shared/_create_protected_branch.html.haml b/app/views/projects/protected_branches/shared/_create_protected_branch.html.haml
index 57fc9a16c0a..e5810930be2 100644
--- a/app/views/projects/protected_branches/shared/_create_protected_branch.html.haml
+++ b/app/views/projects/protected_branches/shared/_create_protected_branch.html.haml
@@ -24,8 +24,9 @@
.form-group.row
= f.label :allow_force_push, s_("ProtectedBranch|Allowed to force push:"), class: 'col-md-2 gl-text-left text-md-right'
.col-md-10
- = render "shared/buttons/project_feature_toggle", class_list: "js-force-push-toggle project-feature-toggle"
- .form-text.gl-text-gray-600.gl-mt-0
+ = render Pajamas::ToggleComponent.new(classes: 'js-force-push-toggle',
+ label: s_("ProtectedBranch|Allowed to force push"),
+ label_position: :hidden) do
- force_push_docs_url = help_page_url('topics/git/git_rebase', anchor: 'force-push')
- force_push_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: force_push_docs_url }
= (s_("ProtectedBranch|Allow all users with push access to %{tag_start}force push%{tag_end}.") % { tag_start: force_push_link_start, tag_end: '</a>' }).html_safe
diff --git a/app/views/projects/registry/repositories/index.html.haml b/app/views/projects/registry/repositories/index.html.haml
index 3efe1fd2e82..aab5e9fca98 100644
--- a/app/views/projects/registry/repositories/index.html.haml
+++ b/app/views/projects/registry/repositories/index.html.haml
@@ -15,6 +15,7 @@
"expiration_policy_help_page_path" => help_page_path('user/packages/container_registry/reduce_container_registry_storage', anchor: 'cleanup-policy'),
"garbage_collection_help_page_path" => help_page_path('administration/packages/container_registry', anchor: 'container-registry-garbage-collection'),
"run_cleanup_policies_help_page_path" => help_page_path('administration/packages/container_registry', anchor: 'run-the-cleanup-policy-now'),
+ "container_registry_importing_help_page_path" => help_page_path('user/packages/container_registry/index', anchor: 'tags-temporarily-cannot-be-marked-for-deletion'),
"project_path": @project.full_path,
"gid_prefix": container_repository_gid_prefix,
"is_admin": current_user&.admin.to_s,
diff --git a/app/views/projects/runners/_group_runners.html.haml b/app/views/projects/runners/_group_runners.html.haml
index c25fd7a7587..8134ee8f417 100644
--- a/app/views/projects/runners/_group_runners.html.haml
+++ b/app/views/projects/runners/_group_runners.html.haml
@@ -28,7 +28,11 @@
= _('This group does not have any group runners yet.')
- if can?(current_user, :admin_group_runners, @project.group)
- - group_link = link_to _("group's CI/CD settings."), group_settings_ci_cd_path(@project.group)
+ - if Feature.enabled?(:runner_list_group_view_vue_ui, @group, default_enabled: :yaml)
+ - register_runners_path = group_runners_path(@project.group)
+ - else
+ - register_runners_path = group_settings_ci_cd_path(@project.group)
+ - group_link = link_to _("group's CI/CD settings."), register_runners_path
= _('Group owners can register group runners in the %{link}').html_safe % { link: group_link }
- else
= _('Ask your group owner to set up a group runner.')
diff --git a/app/views/projects/runners/_runner.html.haml b/app/views/projects/runners/_runner.html.haml
index 28e5618f8b0..5eaf6c9d22b 100644
--- a/app/views/projects/runners/_runner.html.haml
+++ b/app/views/projects/runners/_runner.html.haml
@@ -16,10 +16,10 @@
= link_to edit_project_runner_path(@project, runner), class: 'btn gl-button btn-icon', title: _('Edit'), aria: { label: _('Edit') }, data: { testid: 'edit-runner-link', toggle: 'tooltip', placement: 'top', container: 'body' } do
= sprite_icon('pencil')
- if runner.active?
- = link_to pause_project_runner_path(@project, runner), method: :post, class: 'btn gl-button btn-icon', title: _('Pause'), aria: { label: _('Pause') }, data: { toggle: 'tooltip', placement: 'top', container: 'body', confirm: _("Are you sure?") } do
+ = link_to pause_project_runner_path(@project, runner), method: :post, class: 'btn gl-button btn-icon', title: s_('Runners|Pause from accepting jobs'), aria: { label: _('Pause') }, data: { toggle: 'tooltip', container: 'body', confirm: _("Are you sure?") } do
= sprite_icon('pause')
- else
- = link_to resume_project_runner_path(@project, runner), method: :post, class: 'btn gl-button btn-icon', title: _('Resume'), aria: { label: _('Resume') }, data: { toggle: 'tooltip', placement: 'top', container: 'body' } do
+ = link_to resume_project_runner_path(@project, runner), method: :post, class: 'btn gl-button btn-icon', title: s_('Runners|Resume accepting jobs'), aria: { label: _('Resume') }, data: { toggle: 'tooltip', container: 'body' } do
= sprite_icon('play')
- if runner.belongs_to_one_project?
= link_to _('Remove runner'), project_runner_path(@project, runner), data: { confirm: _("Are you sure?") }, method: :delete, class: 'btn gl-button btn-danger'
diff --git a/app/views/projects/runners/_specific_runners.html.haml b/app/views/projects/runners/_specific_runners.html.haml
index 1357846876e..3634bacb6ec 100644
--- a/app/views/projects/runners/_specific_runners.html.haml
+++ b/app/views/projects/runners/_specific_runners.html.haml
@@ -2,7 +2,7 @@
= _('Specific runners')
.bs-callout.help-callout
- - if valid_runner_registrars.include?('project')
+ - if can?(current_user, :register_project_runners, @project)
= _('These runners are specific to this project.')
- if params[:ci_runner_templates]
%hr
diff --git a/app/views/projects/services/_form.html.haml b/app/views/projects/services/_form.html.haml
index 65b93dc930a..7a47b504b7c 100644
--- a/app/views/projects/services/_form.html.haml
+++ b/app/views/projects/services/_form.html.haml
@@ -1,6 +1,17 @@
- if lookup_context.template_exists?('top', "projects/services/#{integration.to_param}", true)
= render "projects/services/#{integration.to_param}/top", integration: integration
+- if integration.activate_disabled_reason.present? && integration.activate_disabled_reason[:trackers].any?
+ -# When using integration.activate_disabled_reason[:trackers], it's potentially insecure to use the raw records
+ -# when passed directly to the frontend. Only use specific fields that are needed for render.
+ -# For example, we can get the link to each tracker with scoped_edit_integration_path(tracker, tracker.project)
+ = render 'shared/global_alert',
+ title: s_('ExternalIssueIntegration|Another issue tracker is already in use'),
+ variant: :warning,
+ dismissible: false do
+ .gl-alert-body
+ = s_('ExternalIssueIntegration|Only one issue tracker integration can be active at a time. Please disable the active tracker first and try again.')
+
%h3.page-title
= integration.title
- if integration.operating?
diff --git a/app/views/projects/services/prometheus/_custom_metrics.html.haml b/app/views/projects/services/prometheus/_custom_metrics.html.haml
index 4586ee844c0..896249c6163 100644
--- a/app/views/projects/services/prometheus/_custom_metrics.html.haml
+++ b/app/views/projects/services/prometheus/_custom_metrics.html.haml
@@ -18,7 +18,7 @@
.flash-text
.loading-metrics.js-loading-custom-metrics
%p.m-3
- = loading_icon(css_class: 'metrics-load-spinner')
+ = gl_loading_icon(inline: true, css_class: 'metrics-load-spinner')
= s_('PrometheusService|Finding custom metrics...')
.empty-metrics.hidden.js-empty-custom-metrics
%p.text-tertiary.m-3.js-no-active-integration-text.hidden
diff --git a/app/views/projects/services/prometheus/_metrics.html.haml b/app/views/projects/services/prometheus/_metrics.html.haml
index 0d41584652f..8794f3e24da 100644
--- a/app/views/projects/services/prometheus/_metrics.html.haml
+++ b/app/views/projects/services/prometheus/_metrics.html.haml
@@ -16,7 +16,7 @@
.card-body
.loading-metrics.js-loading-metrics
%p.m-3
- = loading_icon(css_class: 'metrics-load-spinner')
+ = gl_loading_icon(inline: true, css_class: 'metrics-load-spinner')
= s_('PrometheusService|Finding and configuring metrics...')
.empty-metrics.hidden.js-empty-metrics
%p.text-tertiary.m-3
diff --git a/app/views/projects/settings/_general.html.haml b/app/views/projects/settings/_general.html.haml
index 960b1d67610..3a62c6f41cc 100644
--- a/app/views/projects/settings/_general.html.haml
+++ b/app/views/projects/settings/_general.html.haml
@@ -23,7 +23,7 @@
.row
.form-group.col-md-9
= f.label :description, _('Project description (optional)'), class: 'label-bold'
- = f.text_area :description, class: 'form-control gl-form-input', rows: 3, maxlength: 250
+ = f.text_area :description, class: 'form-control gl-form-input', rows: 3
.row= render_if_exists 'projects/classification_policy_settings', f: f
diff --git a/app/views/projects/settings/ci_cd/_form.html.haml b/app/views/projects/settings/ci_cd/_form.html.haml
index c70e153ae41..66a1cbb4649 100644
--- a/app/views/projects/settings/ci_cd/_form.html.haml
+++ b/app/views/projects/settings/ci_cd/_form.html.haml
@@ -94,7 +94,7 @@
.input-group-text /
%p.form-text.text-muted
= html_escape(_('The regular expression used to find test coverage output in the job log. For example, use %{regex} for Simplecov (Ruby). Leave blank to disable.')) % { regex: '<code>\(\d+.\d+%\)</code>'.html_safe }
- = link_to sprite_icon('question-o'), help_page_path('ci/pipelines/settings', anchor: 'add-test-coverage-results-to-a-merge-request-deprecated'), target: '_blank', rel: 'noopener noreferrer'
+ = link_to sprite_icon('question-o'), help_page_path('ci/pipelines/settings', anchor: 'add-test-coverage-results-using-project-settings-deprecated'), target: '_blank', rel: 'noopener noreferrer'
= f.submit _('Save changes'), class: "btn gl-button btn-confirm", data: { qa_selector: 'save_general_pipelines_changes_button' }
diff --git a/app/views/projects/settings/packages_and_registries/show.html.haml b/app/views/projects/settings/packages_and_registries/show.html.haml
index 07910899aa0..658b2f2e65c 100644
--- a/app/views/projects/settings/packages_and_registries/show.html.haml
+++ b/app/views/projects/settings/packages_and_registries/show.html.haml
@@ -9,7 +9,7 @@
older_than_options: older_than_options.to_json,
is_admin: current_user&.admin.to_s,
admin_settings_path: ci_cd_admin_application_settings_path(anchor: 'js-registry-settings'),
- enable_historic_entries: container_expiration_policies_historic_entry_enabled?(@project).to_s,
+ enable_historic_entries: container_expiration_policies_historic_entry_enabled?.to_s,
help_page_path: help_page_path('user/packages/container_registry/reduce_container_registry_storage', anchor: 'cleanup-policy'),
show_cleanup_policy_on_alert: show_cleanup_policy_on_alert(@project).to_s,
tags_regex_help_page_path: help_page_path('user/packages/container_registry/reduce_container_registry_storage', anchor: 'regex-pattern-examples') } }
diff --git a/app/views/projects/stage/_stage.html.haml b/app/views/projects/stage/_stage.html.haml
deleted file mode 100644
index 387c8fb3234..00000000000
--- a/app/views/projects/stage/_stage.html.haml
+++ /dev/null
@@ -1,15 +0,0 @@
-- stage = stage.present(current_user: current_user)
-
-%tr
- %th{ colspan: 10 }
- %strong
- %a{ name: stage.name }
- %span{ class: "ci-status-link ci-status-icon-#{stage.status}" }
- = ci_icon_for_status(stage.status)
- &nbsp;
- = stage.name.titleize
-= render stage.latest_ordered_statuses, stage: false, ref: false, pipeline_link: false, allow_retry: true
-= render stage.retried_ordered_statuses, stage: false, ref: false, pipeline_link: false, retried: true
-%tr
- %td{ colspan: 10 }
- &nbsp;
diff --git a/app/views/projects/triggers/_trigger.html.haml b/app/views/projects/triggers/_trigger.html.haml
index 9d082436aa7..ce036606a1c 100644
--- a/app/views/projects/triggers/_trigger.html.haml
+++ b/app/views/projects/triggers/_trigger.html.haml
@@ -33,5 +33,5 @@
= link_to edit_project_trigger_path(@project, trigger), method: :get, title: "Edit", class: "gl-button btn btn-default btn-icon" do
= sprite_icon('pencil')
- if can?(current_user, :manage_trigger, trigger)
- = link_to project_trigger_path(@project, trigger), data: { confirm: revoke_trigger_confirmation, testid: 'trigger_revoke_button' }, method: :delete, title: "Revoke", class: "gl-button btn btn-default btn-icon btn-trigger-revoke gl-ml-3" do
+ = link_to project_trigger_path(@project, trigger), aria: { label: _('Revoke') }, data: { confirm: revoke_trigger_confirmation, testid: 'trigger_revoke_button', confirm_btn_variant: "danger" }, method: :delete, title: "Revoke", class: "gl-button btn btn-default btn-icon btn-trigger-revoke gl-ml-3" do
= sprite_icon('remove')
diff --git a/app/views/sandbox/mermaid.html.erb b/app/views/sandbox/mermaid.html.erb
index 2d2391c8866..48c7baeaeed 100644
--- a/app/views/sandbox/mermaid.html.erb
+++ b/app/views/sandbox/mermaid.html.erb
@@ -2,6 +2,9 @@
<html>
<head>
<%= webpack_bundle_tag("sandboxed_mermaid") %>
+ <% if params[:darkMode] == 'true' %>
+ <meta name="color-scheme" content="dark light">
+ <% end %>
</head>
<body>
<div id="app"></div>
diff --git a/app/views/search/results/_blob_highlight.html.haml b/app/views/search/results/_blob_highlight.html.haml
index de1fa9a7fd5..729eda331b5 100644
--- a/app/views/search/results/_blob_highlight.html.haml
+++ b/app/views/search/results/_blob_highlight.html.haml
@@ -10,7 +10,13 @@
.line-numbers
.gl-display-flex
%span.diff-line-num.gl-pl-3
- %a.has-tooltip{ href: "#{blame_link}#L#{i}", id: "blame-L#{i}", 'data-line-number' => i, title: _('View blame') }
+ %a.has-tooltip{ href: "#{blame_link}#L#{i}",
+ id: "blame-L#{i}",
+ data: { "line_number" => i,
+ "track_action" => 'click_link',
+ "track_label" => 'git_blame',
+ "track_property" => 'search_result' },
+ title: _('View blame') }
= sprite_icon('git')
%span.diff-line-num.flex-grow-1.gl-pr-3
%a{ href: "#{blob_link}#L#{i}", id: "blob-L#{i}", 'data-line-number' => i, class: 'gl-display-flex! gl-align-items-center gl-justify-content-end' }
diff --git a/app/views/shared/_default_branch_protection.html.haml b/app/views/shared/_default_branch_protection.html.haml
index 7a6152f6d96..1a660f3f896 100644
--- a/app/views/shared/_default_branch_protection.html.haml
+++ b/app/views/shared/_default_branch_protection.html.haml
@@ -1,4 +1,4 @@
-%fieldset.form-group
- %legend.h5.gl-border-none.gl-mt-0.gl-mb-3= _('Default branch protection')
+.form-group
+ %legend.h5.gl-border-none.gl-mt-0.gl-mb-3= _('Initial default branch protection')
- Gitlab::Access.protection_options.each do |option|
= f.gitlab_ui_radio_component :default_branch_protection, option[:value], option[:label], help_text: option[:help_text]
diff --git a/app/views/shared/_gl_toggle.html.haml b/app/views/shared/_gl_toggle.html.haml
deleted file mode 100644
index afaa6b6df92..00000000000
--- a/app/views/shared/_gl_toggle.html.haml
+++ /dev/null
@@ -1,28 +0,0 @@
--# This partial renders a GlToggle root element.
--# To actually initialize the component, make sure to call the initToggle helper from ~/toggles.
-
-- classes = local_assigns.fetch(:classes)
-- name = local_assigns.fetch(:name, nil)
-- is_checked = local_assigns.fetch(:is_checked, false).to_s
-- disabled = local_assigns.fetch(:disabled, false).to_s
-- is_loading = local_assigns.fetch(:is_loading, false).to_s
-- label = local_assigns.fetch(:label, nil)
-- help = local_assigns.fetch(:help, nil)
-- label_position = local_assigns.fetch(:label_position, nil)
-- data = local_assigns.fetch(:data, {})
-
-%span{ class: classes,
- data: { name: name,
- is_checked: is_checked,
- disabled: disabled,
- is_loading: is_loading,
- label: label,
- help: help,
- label_position: label_position,
- **data } }
-
--# Leverage this block to render a rich help text. To render a plain text help text,
--# prefer the `help` parameter.
-- if yield.present?
- .gl-text-secondary.gl-mt-1
- = yield
diff --git a/app/views/shared/_global_alert.html.haml b/app/views/shared/_global_alert.html.haml
index 1eaf21fc568..cb7ad32e474 100644
--- a/app/views/shared/_global_alert.html.haml
+++ b/app/views/shared/_global_alert.html.haml
@@ -8,16 +8,14 @@
- close_button_class = local_assigns.fetch(:close_button_class, nil)
- close_button_data = local_assigns.fetch(:close_button_data, nil)
- icon = icons[variant]
-- alert_container_class = [container_class, @content_class] unless fluid_layout || local_assigns.fetch(:is_contained, false)
%div{ role: 'alert', class: ['gl-alert', "gl-alert-#{variant}", alert_class], data: alert_data }
- .gl-alert-container{ class: alert_container_class }
- = sprite_icon(icon, size: 16, css_class: "gl-alert-icon#{' gl-alert-icon-no-title' if title.nil?}")
- - if dismissible
- %button.btn.gl-dismiss-btn.btn-default.btn-sm.gl-button.btn-default-tertiary.btn-icon.js-close{ type: 'button', aria: { label: _('Dismiss') }, class: close_button_class, data: close_button_data }
- = sprite_icon('close', size: 16)
- .gl-alert-content{ role: 'alert' }
- - if title
- %h4.gl-alert-title
- = title
- = yield
+ = sprite_icon(icon, css_class: "gl-alert-icon#{' gl-alert-icon-no-title' if title.nil?}")
+ - if dismissible
+ %button.btn.gl-dismiss-btn.btn-default.btn-sm.gl-button.btn-default-tertiary.btn-icon.js-close{ type: 'button', aria: { label: _('Dismiss') }, class: close_button_class, data: close_button_data }
+ = sprite_icon('close')
+ .gl-alert-content{ role: 'alert' }
+ - if title
+ %h4.gl-alert-title
+ = title
+ = yield
diff --git a/app/views/shared/_logo_ukraine.svg b/app/views/shared/_logo_ukraine.svg
new file mode 100644
index 00000000000..e2c2bb3855d
--- /dev/null
+++ b/app/views/shared/_logo_ukraine.svg
@@ -0,0 +1,5 @@
+<svg width="24" height="24" class="tanuki-logo" viewBox="0 0 24 24">
+ <path d="M4.89929534,0.3165 L7.56629534,8.5025 L16.3922953,8.5025 L19.0592953,0.3165 C19.1962953,-0.1055 19.8432953,-0.1055 19.9792953,0.3165 L23.9122953,12.6095 C23.9722953,12.7935 23.9722953,12.9895 23.9192953,13.1695 L0.0392953418,13.1695 C-0.0143874393,12.9863283 -0.0119492421,12.7912726 0.0462953418,12.6095 L3.97929534,0.3165 C4.11529534,-0.1055 4.76229534,-0.1055 4.89929534,0.3165 Z" id="Path" fill="#005BBB"></path>
+ <path d="M7.20329534,9.0025 L16.7552953,9.0025 L16.8682953,8.6575 L19.5182953,0.5185 L23.4362953,12.7615 C23.4961172,12.9376949 23.435535,13.1323657 23.2862953,13.2435 L23.2852953,13.2455 L11.9852953,21.4655 L11.9792953,21.4715 L0.673295342,13.2455 C0.522422013,13.1321007 0.462258936,12.9374792 0.522295342,12.7615 L4.43929534,0.5185 L7.09029534,8.6585 L7.20329534,9.0025 Z" id="Shape" stroke="#FFFFFF" opacity="0.32" stroke-linejoin="round"></path>
+ <path d="M0.0012953418,12.8575 C-0.0152229638,13.1685309 0.127095079,13.4667211 0.379295342,13.6495 L11.9792953,22.0895 L11.9862953,22.0845 L11.9922953,22.0895 L11.9872953,22.0835 L23.5792953,13.6495 C23.8319507,13.466647 23.9743476,13.1679148 23.9572953,12.8565 L0.0012953418,12.8565 L0.0012953418,12.8575 Z" id="Path" fill="#FFD500"></path>
+</svg> \ No newline at end of file
diff --git a/app/views/shared/_new_project_item_select.html.haml b/app/views/shared/_new_project_item_select.html.haml
index 08003346d09..74a397d7a03 100644
--- a/app/views/shared/_new_project_item_select.html.haml
+++ b/app/views/shared/_new_project_item_select.html.haml
@@ -1,7 +1,7 @@
- if any_projects?(@projects)
.project-item-select-holder.btn-group.gl-ml-auto.gl-mr-auto.gl-relative.gl-overflow-hidden{ class: 'gl-display-flex!' }
%a.btn.gl-button.btn-confirm.js-new-project-item-link.block-truncated.qa-new-project-item-link{ href: '', data: { label: local_assigns[:label], type: local_assigns[:type] }, class: "gl-m-0!" }
- = loading_icon(color: 'light')
+ = gl_loading_icon(inline: true, color: 'light')
= project_select_tag :project_path, class: "project-item-select gl-absolute! gl-visibility-hidden", data: { include_groups: local_assigns[:include_groups], order_by: 'last_activity_at', relative_path: local_assigns[:path], with_shared: local_assigns[:with_shared], include_projects_in_subgroups: local_assigns[:include_projects_in_subgroups] }, with_feature_enabled: local_assigns[:with_feature_enabled]
%button.btn.dropdown-toggle.btn-confirm.btn-md.gl-button.gl-dropdown-toggle.dropdown-toggle-split.new-project-item-select-button.qa-new-project-item-select-button.gl-p-0.gl-w-100{ class: "gl-m-0!", 'aria-label': _('Toggle project select') }
= sprite_icon('chevron-down')
diff --git a/app/views/shared/_service_ping_consent.html.haml b/app/views/shared/_service_ping_consent.html.haml
index 821d92e9d7e..9cdff35ead2 100644
--- a/app/views/shared/_service_ping_consent.html.haml
+++ b/app/views/shared/_service_ping_consent.html.haml
@@ -1,7 +1,6 @@
- if session[:ask_for_usage_stats_consent]
= render 'shared/global_alert',
variant: :info,
- is_contained: true,
alert_class: 'service-ping-consent-message' do
.gl-alert-body
- docs_link = link_to _('collect usage information'), help_page_path('user/admin_area/settings/usage_statistics.md'), class: 'gl-link'
diff --git a/app/views/shared/_two_factor_auth_recovery_settings_check.html.haml b/app/views/shared/_two_factor_auth_recovery_settings_check.html.haml
index e7239661313..f21acd26ada 100644
--- a/app/views/shared/_two_factor_auth_recovery_settings_check.html.haml
+++ b/app/views/shared/_two_factor_auth_recovery_settings_check.html.haml
@@ -1,6 +1,6 @@
= render 'shared/global_alert',
variant: :warning,
- alert_class: 'js-recovery-settings-callout',
+ alert_class: 'js-recovery-settings-callout gl-mt-5',
alert_data: { feature_id: Users::CalloutsHelper::TWO_FACTOR_AUTH_RECOVERY_SETTINGS_CHECK, dismiss_endpoint: callouts_path, defer_links: 'true' },
close_button_data: { testid: 'close-account-recovery-regular-check-callout' } do
.gl-alert-body
diff --git a/app/views/shared/access_tokens/_form.html.haml b/app/views/shared/access_tokens/_form.html.haml
index a52b7236137..0b68cfe65e5 100644
--- a/app/views/shared/access_tokens/_form.html.haml
+++ b/app/views/shared/access_tokens/_form.html.haml
@@ -19,18 +19,14 @@
.row
= f.label :name, _('Token name'), class: 'label-bold col-md-12'
.col-md-6
+ - resource_type = resource.is_a?(Group) ? "group" : "project"
= f.text_field :name, class: 'form-control gl-form-input', required: true, data: { qa_selector: 'access_token_name_field' }, :'aria-describedby' => 'access_token_help_text'
- %span.form-text.text-muted.col-md-12#access_token_help_text= _('For example, the application using the token or the purpose of the token.')
+ %span.form-text.text-muted.col-md-12#access_token_help_text= _("For example, the application using the token or the purpose of the token. Do not give sensitive information for the name of the token, as it will be visible to all %{resource_type} members.") % { resource_type: resource_type }
.row
- .form-group.col-md-6
- = f.label :expires_at, _('Expiration date'), class: 'label-bold'
- .input-icon-wrapper
-
- = render_if_exists 'personal_access_tokens/callout_max_personal_access_token_lifetime'
-
- .js-access-tokens-expires-at
- = f.text_field :expires_at, class: 'datepicker gl-datepicker-input form-control gl-form-input', placeholder: 'YYYY-MM-DD', autocomplete: 'off', data: { js_name: 'expiresAt' }
+ .col
+ .js-access-tokens-expires-at{ data: expires_at_field_data }
+ = f.text_field :expires_at, class: 'datepicker gl-datepicker-input form-control gl-form-input', placeholder: 'YYYY-MM-DD', autocomplete: 'off', data: { js_name: 'expiresAt' }
- if resource
.row
diff --git a/app/views/shared/blob/_markdown_buttons.html.haml b/app/views/shared/blob/_markdown_buttons.html.haml
index e02c24b93f1..60641006e96 100644
--- a/app/views/shared/blob/_markdown_buttons.html.haml
+++ b/app/views/shared/blob/_markdown_buttons.html.haml
@@ -9,6 +9,10 @@
data: { "md-tag" => "_", "md-shortcuts": '["mod+i"]' },
title: sprintf(s_("MarkdownEditor|Add italic text (%{modifier_key}I)") % { modifier_key: modifier_key }) })
+ = markdown_toolbar_button({ icon: "strikethrough",
+ data: { "md-tag" => "~~", "md-shortcuts": '["mod+shift+x"]' },
+ title: sprintf(s_("MarkdownEditor|Add strikethrough text (%{modifier_key}⇧X)") % { modifier_key: modifier_key }) })
+
= 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") })
diff --git a/app/views/shared/buttons/_project_feature_toggle.html.haml b/app/views/shared/buttons/_project_feature_toggle.html.haml
deleted file mode 100644
index 321fbee1b35..00000000000
--- a/app/views/shared/buttons/_project_feature_toggle.html.haml
+++ /dev/null
@@ -1,16 +0,0 @@
-- class_list ||= "js-project-feature-toggle project-feature-toggle"
-- data ||= nil
-- disabled ||= false
-- is_checked ||= false
-- label ||= nil
-
-%button{ type: 'button',
- class: "#{class_list} #{'is-disabled' if disabled} #{'is-checked' if is_checked}",
- "aria-label": label,
- disabled: disabled,
- data: data }
- - if yield.present?
- = yield
- %span.toggle-icon
- = sprite_icon('status_success_borderless', size: 18, css_class: 'gl-text-blue-500 toggle-status-checked')
- = sprite_icon('status_failed_borderless', size: 18, css_class: 'gl-text-gray-400 toggle-status-unchecked')
diff --git a/app/views/shared/deploy_tokens/_table.html.haml b/app/views/shared/deploy_tokens/_table.html.haml
index db9c646b694..a7bf3bfb81e 100644
--- a/app/views/shared/deploy_tokens/_table.html.haml
+++ b/app/views/shared/deploy_tokens/_table.html.haml
@@ -25,7 +25,7 @@
%span.token-never-expires-label= _('Never')
%td= token.scopes.present? ? token.scopes.join(', ') : _('no scopes selected')
%td
- .js-deploy-token-revoke-button{ data: { button_class: 'float-right', token: token.to_json, revoke_path: revoke_deploy_token_path(group_or_project, token) } }
+ .js-deploy-token-revoke-button{ data: deploy_token_revoke_button_data(token: token, group_or_project: group_or_project) }
- else
.settings-message.text-center
diff --git a/app/views/shared/doorkeeper/applications/_delete_form.html.haml b/app/views/shared/doorkeeper/applications/_delete_form.html.haml
index caa553bc2ef..7cce0652f6f 100644
--- a/app/views/shared/doorkeeper/applications/_delete_form.html.haml
+++ b/app/views/shared/doorkeeper/applications/_delete_form.html.haml
@@ -2,9 +2,9 @@
= form_tag path do
%input{ :name => "_method", :type => "hidden", :value => "delete" }
- if defined? small
- = button_tag type: "submit", class: "gl-button btn btn-danger btn-icon", data: { confirm: _("Are you sure?") } do
+ = button_tag type: "submit", class: "gl-button btn btn-danger btn-icon", data: { confirm: _("Are you sure?"), confirm_btn_variant: "danger" } do
%span.sr-only
= _('Destroy')
= sprite_icon('remove')
- else
- = submit_tag _('Destroy'), data: { confirm: _("Are you sure?") }, class: submit_btn_css
+ = submit_tag _('Destroy'), data: { confirm: _("Are you sure?"), confirm_btn_variant: "danger" }, aria: { label: _('Destroy') }, class: submit_btn_css
diff --git a/app/views/shared/errors/_gitaly_unavailable.html.haml b/app/views/shared/errors/_gitaly_unavailable.html.haml
index 96a68cbcdc6..366d4585435 100644
--- a/app/views/shared/errors/_gitaly_unavailable.html.haml
+++ b/app/views/shared/errors/_gitaly_unavailable.html.haml
@@ -1,8 +1,7 @@
-.gl-alert.gl-alert-danger.gl-mb-5.gl-mt-5
- .gl-alert-container
- = sprite_icon('error', size: 16, css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title')
- .gl-alert-content
- .gl-alert-title
- = reason
- .gl-alert-body
- = s_('The git server, Gitaly, is not available at this time. Please contact your administrator.')
+= render 'shared/global_alert',
+ alert_class: 'gl-my-5',
+ variant: :danger,
+ dismissible: false,
+ title: reason do
+ .gl-alert-body
+ = s_('The git server, Gitaly, is not available at this time. Please contact your administrator.')
diff --git a/app/views/shared/issuable/_form.html.haml b/app/views/shared/issuable/_form.html.haml
index ae896b7348d..3f6e7a6fb32 100644
--- a/app/views/shared/issuable/_form.html.haml
+++ b/app/views/shared/issuable/_form.html.haml
@@ -9,7 +9,6 @@
= render 'shared/global_alert',
variant: :danger,
dismissible: false,
- is_contained: true,
alert_class: 'gl-mb-5' do
.gl-alert-body
Someone edited the #{issuable.class.model_name.human.downcase} the same time you did.
@@ -20,7 +19,9 @@
= render 'shared/issuable/form/branch_chooser', issuable: issuable, form: form
.form-group.row
- = form.label :title, class: 'col-form-label col-sm-2'
+ = form.label :title, class: 'col-form-label col-sm-2' do
+ = _('Title')
+ %i{ aria: { hidden: true } }= '*'
= render 'shared/issuable/form/title', issuable: issuable, form: form, has_wip_commits: commits && commits.detect(&:work_in_progress?)
#js-suggestions{ data: { project_path: @project.full_path } }
diff --git a/app/views/shared/issuable/_label_page_create.html.haml b/app/views/shared/issuable/_label_page_create.html.haml
index 84cdf129cb2..6a58acf8c05 100644
--- a/app/views/shared/issuable/_label_page_create.html.haml
+++ b/app/views/shared/issuable/_label_page_create.html.haml
@@ -6,10 +6,7 @@
.dropdown-page-two.dropdown-new-label
= dropdown_title(create_label_title(subject), options: { back: true, close: show_close })
= dropdown_content do
- .js-label-error.gl-alert.gl-alert-danger.gl-mb-3
- .gl-alert-container
- = sprite_icon('error', size: 16, css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title')
- .gl-alert-content
+ = render 'shared/global_alert', variant: :danger, alert_class: 'js-label-error gl-mb-3', dismissible: false
%input#new_label_name.default-dropdown-input{ type: "text", placeholder: _('Name new label') }
.suggest-colors.suggest-colors-dropdown
= render_suggested_colors
diff --git a/app/views/shared/issuable/_search_bar.html.haml b/app/views/shared/issuable/_search_bar.html.haml
index b02c6b65359..37a79a50fb1 100644
--- a/app/views/shared/issuable/_search_bar.html.haml
+++ b/app/views/shared/issuable/_search_bar.html.haml
@@ -5,10 +5,6 @@
- placeholder = local_assigns[:placeholder] || _('Search or filter results...')
- block_css_class = type != :productivity_analytics ? 'row-content-block second-block' : ''
- is_epic_board = board&.to_type == "EpicBoard"
-- if @group.present?
- - ff_resource = @group
-- else
- - ff_resource = board&.resource_parent&.group
- if is_epic_board
- user_can_admin_list = can?(current_user, :admin_epic_board_list, board.resource_parent)
@@ -31,7 +27,7 @@
= check_box_tag checkbox_id, nil, false, class: "check-all-issues left"
- if is_epic_board
#js-board-filtered-search{ data: { full_path: @group&.full_path } }
- - elsif Feature.enabled?(:issue_boards_filtered_search, ff_resource, default_enabled: :yaml) && board
+ - elsif board
#js-issue-board-filtered-search
- else
.issues-other-filters.filtered-search-wrapper.d-flex.flex-column.flex-md-row
diff --git a/app/views/shared/issuable/_sidebar.html.haml b/app/views/shared/issuable/_sidebar.html.haml
index 7787e5dd660..37d31515307 100644
--- a/app/views/shared/issuable/_sidebar.html.haml
+++ b/app/views/shared/issuable/_sidebar.html.haml
@@ -27,7 +27,7 @@
- if issuable_sidebar[:supports_escalation]
.block.escalation-status{ data: { testid: 'escalation_status_container' } }
- #js-escalation-status{ data: { can_edit: issuable_sidebar.dig(:current_user, :can_update_escalation_status).to_s, project_path: issuable_sidebar[:project_full_path], issue_iid: issuable_sidebar[:iid] } }
+ #js-escalation-status{ data: { can_update: issuable_sidebar.dig(:current_user, :can_update_escalation_status).to_s, project_path: issuable_sidebar[:project_full_path], issue_iid: issuable_sidebar[:iid] } }
= render_if_exists 'shared/issuable/sidebar_escalation_policy', issuable_sidebar: issuable_sidebar
- if @project.group.present?
@@ -41,7 +41,7 @@
.block{ class: 'gl-pt-0! gl-collapse-empty', data: { qa_selector: 'iteration_container', testid: 'iteration_container' } }<
= render_if_exists 'shared/issuable/iteration_select', can_edit: can_edit_issuable.to_s, group_path: @project.group.full_path, project_path: issuable_sidebar[:project_full_path], issue_iid: issuable_sidebar[:iid], issuable_type: issuable_type
- - if @show_crm_contacts
+ - if issuable_sidebar[:show_crm_contacts]
.block.contact
#js-issue-crm-contacts{ data: { issue_id: issuable_sidebar[:id] } }
@@ -50,7 +50,7 @@
// Fallback while content is loading
.title.hide-collapsed
= _('Time tracking')
- = loading_icon(css_class: 'gl-vertical-align-text-bottom')
+ = gl_loading_icon(inline: true)
- if issuable_sidebar.has_key?(:due_date)
#js-due-date-entry-point
@@ -109,8 +109,8 @@
= dropdown_loading
= dropdown_footer add_content_class: true do
%button.gl-button.btn.btn-confirm.sidebar-move-issue-confirmation-button.js-move-issue-confirmation-button{ type: 'button', disabled: true }
+ = gl_loading_icon(inline: true, css_class: 'sidebar-move-issue-confirmation-loading-icon gl-mr-2')
= _('Move')
- = loading_icon(css_class: 'gl-vertical-align-text-bottom sidebar-move-issue-confirmation-loading-icon')
-# haml-lint:disable InlineJavaScript
%script.js-sidebar-options{ type: "application/json" }= issuable_sidebar_options(issuable_sidebar).to_json.html_safe
diff --git a/app/views/shared/issuable/_sidebar_assignees.html.haml b/app/views/shared/issuable/_sidebar_assignees.html.haml
index 9a0b25f4015..2fd4c598580 100644
--- a/app/views/shared/issuable/_sidebar_assignees.html.haml
+++ b/app/views/shared/issuable/_sidebar_assignees.html.haml
@@ -7,7 +7,7 @@
directly_invite_members: can_admin_project_member?(@project) } }
.title.hide-collapsed
= _('Assignee')
- = loading_icon(css_class: 'gl-vertical-align-text-bottom')
+ = gl_loading_icon(inline: true)
.js-sidebar-assignee-data.selectbox.hide-collapsed
- if assignees.none?
diff --git a/app/views/shared/issuable/_sidebar_reviewers.html.haml b/app/views/shared/issuable/_sidebar_reviewers.html.haml
index bc76d292dd6..ce252e74570 100644
--- a/app/views/shared/issuable/_sidebar_reviewers.html.haml
+++ b/app/views/shared/issuable/_sidebar_reviewers.html.haml
@@ -3,7 +3,7 @@
#js-vue-sidebar-reviewers{ data: { field: issuable_type, signed_in: signed_in } }
.title.hide-collapsed
= _('Reviewer')
- = loading_icon(css_class: 'gl-vertical-align-text-bottom')
+ = gl_loading_icon(inline: true)
.selectbox.hide-collapsed
- if reviewers.none?
diff --git a/app/views/shared/issuable/form/_metadata.html.haml b/app/views/shared/issuable/form/_metadata.html.haml
index 9e42c528a11..34720576526 100644
--- a/app/views/shared/issuable/form/_metadata.html.haml
+++ b/app/views/shared/issuable/form/_metadata.html.haml
@@ -4,6 +4,16 @@
- has_due_date = issuable.has_attribute?(:due_date)
- form = local_assigns.fetch(:form)
+- if @add_related_issue
+ .form-group.row
+ .offset-sm-2.col-sm-10
+ .form-check
+ = check_box_tag :add_related_issue, @add_related_issue.iid, true, class: 'form-check-input'
+ = label_tag :add_related_issue, class: 'form-check-label' do
+ - add_related_issue_link = link_to "\##{@add_related_issue.iid}", issue_path(@add_related_issue), class: ['has-tooltip'], title: @add_related_issue.title
+ #{_('Relate to %{issuable_type} %{add_related_issue_link}').html_safe % { issuable_type: @add_related_issue.issue_type, add_related_issue_link: add_related_issue_link }}
+ %p.text-muted= _('Adds this %{issuable_type} as related to the %{issuable_type} it was created from') % { issuable_type: @add_related_issue.issue_type }
+
- if issuable.respond_to?(:confidential) && can?(current_user, :set_confidentiality, issuable)
.form-group.row
.offset-sm-2.col-sm-10
diff --git a/app/views/shared/issuable/form/_title.html.haml b/app/views/shared/issuable/form/_title.html.haml
index 257ad7a8518..6b00cdc5e24 100644
--- a/app/views/shared/issuable/form/_title.html.haml
+++ b/app/views/shared/issuable/form/_title.html.haml
@@ -8,9 +8,9 @@
- add_wip_text = (_('%{link_start}Start the title with %{draft_snippet}%{link_end} to prevent a merge request draft from merging before it\'s ready.') % { link_start: toggle_wip_link_start, link_end: toggle_wip_link_end, draft_snippet: '<code>Draft:</code>'.html_safe } ).html_safe
- remove_wip_text = (_('%{link_start}Remove the %{draft_snippet} prefix%{link_end} from the title to allow this merge request to be merged when it\'s ready.' ) % { link_start: toggle_wip_link_start, link_end: toggle_wip_link_end, draft_snippet: '<code>Draft</code>'.html_safe } ).html_safe
-%div{ class: div_class }
- = form.text_field :title, required: true, maxlength: 255, autofocus: true,
- autocomplete: 'off', class: 'form-control pad qa-issuable-form-title', placeholder: _('Title'), dir: 'auto'
+%div{ class: div_class, data: { testid: 'issue-title-input-field' } }
+ = form.text_field :title, required: true, aria: { required: true }, maxlength: 255, autofocus: true,
+ autocomplete: 'off', class: 'form-control pad qa-issuable-form-title', placeholder: _('Title'), dir: 'auto'
- if issuable.respond_to?(:work_in_progress?)
.form-text.text-muted
diff --git a/app/views/shared/issue_type/_details_content.html.haml b/app/views/shared/issue_type/_details_content.html.haml
index e5197acf06f..1babc6885c2 100644
--- a/app/views/shared/issue_type/_details_content.html.haml
+++ b/app/views/shared/issue_type/_details_content.html.haml
@@ -5,7 +5,7 @@
.detail-page-description.content-block
#js-issuable-app{ data: { initial: issuable_initial_data(issuable).to_json, full_path: @project.full_path } }
.title-container
- %h2.title= markdown_field(issuable, :title)
+ %h1.title= markdown_field(issuable, :title)
- if issuable.description.present?
.description
.md= markdown_field(issuable, :description)
diff --git a/app/views/shared/labels/_sort_dropdown.html.haml b/app/views/shared/labels/_sort_dropdown.html.haml
index cfc00bd41ca..bb582b159ba 100644
--- a/app/views/shared/labels/_sort_dropdown.html.haml
+++ b/app/views/shared/labels/_sort_dropdown.html.haml
@@ -1,9 +1,3 @@
-- sort_title = label_sort_options_hash[@sort] || sort_title_name_desc
-.dropdown.inline
- %button.dropdown-menu-toggle{ type: 'button', data: { toggle: 'dropdown' } }
- = sort_title
- = sprite_icon('chevron-down', css_class: 'dropdown-menu-toggle-icon gl-top-3')
- %ul.dropdown-menu.dropdown-menu-right.dropdown-menu-sort
- %li
- - label_sort_options_hash.each do |value, title|
- = sortable_item(title, page_filter_path(sort: value), sort_title)
+- label_sort_options = label_sort_options_hash.map { |value, text| { value: value, text: text, href: page_filter_path(sort: value) } }
+
+= gl_redirect_listbox_tag label_sort_options, @sort, data: { right: true }
diff --git a/app/views/shared/members/_invite_group.html.haml b/app/views/shared/members/_invite_group.html.haml
deleted file mode 100644
index cefdf825eaa..00000000000
--- a/app/views/shared/members/_invite_group.html.haml
+++ /dev/null
@@ -1,30 +0,0 @@
-- access_levels = local_assigns[:access_levels]
-- default_access_level = local_assigns[:default_access_level]
-- submit_url = local_assigns[:submit_url]
-- group_link_field = local_assigns[:group_link_field]
-- group_access_field = local_assigns[:group_access_field]
-- groups_select_tag_data = local_assigns[:groups_select_tag_data]
-
-.row
- .col-sm-12
- = form_tag submit_url, class: 'invite-group-form js-requires-input', method: :post do
- .form-group
- = label_tag group_link_field, _("Select a group to invite"), class: "label-bold"
- = groups_select_tag(group_link_field, data: groups_select_tag_data, class: 'input-clamp qa-group-select-field', required: true)
- .form-text.text-muted.gl-mb-3
- = _('Group sharing provides access to all group members (including members who inherited group membership from a parent group).')
- .form-group
- = label_tag group_access_field, _("Max role"), class: "label-bold"
- .select-wrapper
- = select_tag group_access_field, options_for_select(access_levels, default_access_level), data: { qa_selector: 'group_access_field' }, class: "form-control select-control"
- = sprite_icon('chevron-down', css_class: "gl-icon gl-absolute gl-top-3 gl-right-3 gl-text-gray-200")
- .form-text.text-muted.gl-mb-3
- - permissions_docs_path = help_page_path('user/permissions')
- - link_start = %q{<a href="%{url}">}.html_safe % { url: permissions_docs_path }
- = _("%{link_start}Learn more%{link_end} about roles.").html_safe % { link_start: link_start, link_end: '</a>'.html_safe }
- .form-group
- = label_tag :expires_at, _('Access expiration date'), class: 'label-bold'
- .clearable-input
- = text_field_tag :expires_at, nil, class: 'form-control js-access-expiration-date-groups', placeholder: _('Expiration date'), id: 'expires_at_groups'
- = sprite_icon('close', size: 16, css_class: 'clear-icon js-clear-input gl-text-gray-200')
- = submit_tag _("Invite"), class: "gl-button btn btn-confirm gl-mr-3", data: { qa_selector: 'invite_group_button' }
diff --git a/app/views/shared/members/_invite_member.html.haml b/app/views/shared/members/_invite_member.html.haml
deleted file mode 100644
index e6863ed56a5..00000000000
--- a/app/views/shared/members/_invite_member.html.haml
+++ /dev/null
@@ -1,28 +0,0 @@
-- access_levels = local_assigns[:access_levels]
-- default_access_level = local_assigns[:default_access_level]
-- submit_url = local_assigns[:submit_url]
-- can_import_members = local_assigns[:can_import_members?]
-- import_path = local_assigns[:import_path]
-.row
- .col-sm-12
- = form_tag submit_url, class: 'invite-users-form', data: { testid: 'invite-users-form' }, method: :post do
- .form-group
- = label_tag :user_ids, _("GitLab member or Email address"), class: "label-bold"
- = users_select_tag(:user_ids, multiple: true, class: 'input-clamp qa-member-select-field', scope: :all, email_user: true, placeholder: 'Search for members to update or invite')
- .form-group
- = label_tag :access_level, _("Select a role"), class: "label-bold"
- .select-wrapper
- = select_tag :access_level, options_for_select(access_levels, default_access_level), class: "form-control project-access-select select-control"
- = sprite_icon('chevron-down', css_class: "gl-icon gl-absolute gl-top-3 gl-right-3 gl-text-gray-200")
- .form-text.text-muted.gl-mb-3
- - permissions_docs_path = help_page_path('user/permissions')
- - link_start = %q{<a href="%{url}">}.html_safe % { url: permissions_docs_path }
- = _("%{link_start}Learn more%{link_end} about roles.").html_safe % { link_start: link_start, link_end: '</a>'.html_safe }
- .form-group
- = label_tag :expires_at, _('Access expiration date'), class: 'label-bold'
- .clearable-input
- = text_field_tag :expires_at, nil, class: 'form-control js-access-expiration-date', placeholder: 'Expiration date'
- = sprite_icon('close', size: 16, css_class: 'clear-icon js-clear-input gl-text-gray-200')
- = submit_tag _("Invite"), class: "gl-button btn btn-confirm gl-mr-2", data: { qa_selector: 'invite_member_button' }
- - if can_import_members
- = link_to _("Import"), import_path, class: "gl-button btn btn-default", title: _("Import members from another project")
diff --git a/app/views/shared/milestones/_delete_button.html.haml b/app/views/shared/milestones/_delete_button.html.haml
index 6d4ff255f06..8a709a36835 100644
--- a/app/views/shared/milestones/_delete_button.html.haml
+++ b/app/views/shared/milestones/_delete_button.html.haml
@@ -6,7 +6,7 @@
milestone_issue_count: @milestone.issues.count,
milestone_merge_request_count: @milestone.merge_requests.count },
disabled: true }
+ = gl_loading_icon(inline: true, css_class: "gl-mr-2 js-loading-icon hidden")
= _('Delete')
- .gl-spinner.js-loading-icon.hidden
#js-delete-milestone-modal
diff --git a/app/views/shared/milestones/_milestone_complete_alert.html.haml b/app/views/shared/milestones/_milestone_complete_alert.html.haml
index 1c25fae747e..5b05fdb6019 100644
--- a/app/views/shared/milestones/_milestone_complete_alert.html.haml
+++ b/app/views/shared/milestones/_milestone_complete_alert.html.haml
@@ -3,7 +3,6 @@
- if milestone.complete? && milestone.active?
= render 'shared/global_alert',
variant: :success,
- is_contained: true,
alert_data: { testid: 'all-issues-closed-alert' },
dismissible: false do
.gl-alert-body
diff --git a/app/views/shared/milestones/_tab_loading.html.haml b/app/views/shared/milestones/_tab_loading.html.haml
index b19e994ef80..ebd4ef7d4c3 100644
--- a/app/views/shared/milestones/_tab_loading.html.haml
+++ b/app/views/shared/milestones/_tab_loading.html.haml
@@ -1,2 +1 @@
-.text-center.gl-mt-3
- .gl-spinner.gl-spinner-md
+= gl_loading_icon(size: 'md', css_class: 'gl-mt-3')
diff --git a/app/views/shared/nav/_sidebar_submenu.html.haml b/app/views/shared/nav/_sidebar_submenu.html.haml
index 750e6c9ee57..344dafe7c0f 100644
--- a/app/views/shared/nav/_sidebar_submenu.html.haml
+++ b/app/views/shared/nav/_sidebar_submenu.html.haml
@@ -4,7 +4,7 @@
%strong.fly-out-top-item-name
= sidebar_menu.title
- if sidebar_menu.has_pill?
- %span.badge.badge-pill.count.fly-out-badge{ **sidebar_menu.pill_html_options }
+ = gl_badge_tag({ variant: :info, size: :sm }, { class: "count fly-out-badge #{sidebar_menu.pill_html_options[:class]}" }) do
= number_with_delimiter(sidebar_menu.pill_count)
- if sidebar_menu.has_renderable_items?
diff --git a/app/views/shared/notes/_hints.html.haml b/app/views/shared/notes/_hints.html.haml
index 6c8b2a9e5bb..8a79a17b166 100644
--- a/app/views/shared/notes/_hints.html.haml
+++ b/app/views/shared/notes/_hints.html.haml
@@ -18,7 +18,7 @@
%span.attaching-file-message
-# Populated by app/assets/javascripts/dropzone_input.js
%span.uploading-progress 0%
- = loading_icon(css_class: 'align-text-bottom gl-mr-2')
+ = gl_loading_icon(inline: true, css_class: 'gl-mr-2')
%span.uploading-error-container.hide
%span.uploading-error-icon
diff --git a/app/views/shared/projects/protected_branches/_update_protected_branch.html.haml b/app/views/shared/projects/protected_branches/_update_protected_branch.html.haml
index 3cbe35e5c15..32b9044c551 100644
--- a/app/views/shared/projects/protected_branches/_update_protected_branch.html.haml
+++ b/app/views/shared/projects/protected_branches/_update_protected_branch.html.haml
@@ -34,4 +34,7 @@
= _('Members of %{group} can also push to this branch: %{branch}') % { group: (group_push_access_levels.size > 1 ? 'these groups' : 'this group'), branch: group_push_access_levels.map(&:humanize).to_sentence }
%td
- = render "shared/buttons/project_feature_toggle", is_checked: protected_branch.allow_force_push, label: s_("ProtectedBranch|Toggle allowed to force push"), class_list: "js-force-push-toggle project-feature-toggle", data: { qa_selector: 'force_push_toggle_button', qa_branch_name: protected_branch.name }
+ = render Pajamas::ToggleComponent.new(classes: 'js-force-push-toggle',
+ label: s_("ProtectedBranch|Toggle allowed to force push"),
+ is_checked: protected_branch.allow_force_push,
+ label_position: :hidden)
diff --git a/app/views/shared/web_hooks/_hook_errors.html.haml b/app/views/shared/web_hooks/_hook_errors.html.haml
index 23010b8349c..03f373783f8 100644
--- a/app/views/shared/web_hooks/_hook_errors.html.haml
+++ b/app/views/shared/web_hooks/_hook_errors.html.haml
@@ -13,7 +13,6 @@
= render 'shared/global_alert',
title: s_('Webhooks|Webhook was automatically disabled'),
variant: :danger,
- is_contained: true,
close_button_class: 'js-close' do
.gl-alert-body
= s_('Webhooks|The webhook was triggered more than %{limit} times per minute and is now disabled. To re-enable this webhook, fix the problems shown in %{strong_start}Recent events%{strong_end}, then re-test your settings. %{support_link_start}Contact Support%{support_link_end} if you need help re-enabling your webhook.').html_safe % placeholders
@@ -21,7 +20,6 @@
= render 'shared/global_alert',
title: s_('Webhooks|Webhook failed to connect'),
variant: :danger,
- is_contained: true,
close_button_class: 'js-close' do
.gl-alert-body
= s_('Webhooks|The webhook failed to connect, and is disabled. To re-enable it, check %{strong_start}Recent events%{strong_end} for error details, then test your settings below.').html_safe % { strong_start: strong_start, strong_end: strong_end }
@@ -35,7 +33,6 @@
= render 'shared/global_alert',
title: s_('Webhooks|Webhook fails to connect'),
variant: :warning,
- is_contained: true,
close_button_class: 'js-close' do
.gl-alert-body
= s_('Webhooks|The webhook %{help_link_start}failed to connect%{help_link_end}, and will retry in %{retry_time}. To re-enable it, check %{strong_start}Recent events%{strong_end} for error details, then test your settings below.').html_safe % placeholders
diff --git a/app/views/shared/wikis/pages.html.haml b/app/views/shared/wikis/pages.html.haml
index 0a8ca309823..abe7753b9f1 100644
--- a/app/views/shared/wikis/pages.html.haml
+++ b/app/views/shared/wikis/pages.html.haml
@@ -1,8 +1,8 @@
- 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])
- add_page_specific_style 'page_bundles/wiki'
+- wiki_sort_options = [{ text: s_("Wiki|Title"), value: 'title', href: wiki_path(@wiki, action: :pages, sort: Wiki::TITLE_ORDER)}, { text: s_("Wiki|Created date"), value: 'created_at', href: wiki_path(@wiki, action: :pages, sort: Wiki::CREATED_AT_ORDER) }]
.wiki-page-header.top-area.flex-column.flex-lg-row
%h3.page-title.gl-flex-grow-1
@@ -15,14 +15,7 @@
.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 gl-button btn-default' }
- = sort_title
- = sprite_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)
+ = gl_redirect_listbox_tag wiki_sort_options, params[:sort], data: { right: true }
= wiki_sort_controls(@wiki, params[:sort], params[:direction])
%ul.wiki-pages-list.content-list
diff --git a/app/views/users/_overview.html.haml b/app/views/users/_overview.html.haml
index c0a6ab44a26..a7875f9b089 100644
--- a/app/views/users/_overview.html.haml
+++ b/app/views/users/_overview.html.haml
@@ -3,7 +3,7 @@
.row.d-none.d-sm-flex
.col-12.calendar-block.gl-my-3
.user-calendar.light{ data: { calendar_path: user_calendar_path(@user, :json), calendar_activities_path: user_calendar_activities_path, utc_offset: local_timezone_instance(@user.timezone).now.utc_offset } }
- .gl-spinner.gl-spinner-md.gl-my-8
+ = gl_loading_icon(size: 'md', css_class: 'gl-my-8')
.user-calendar-error.invisible
= _('There was an error loading users activity calendar.')
%a.js-retry-load{ href: '#' }
@@ -35,8 +35,7 @@
= Feature.enabled?(:security_auto_fix) && @user.bot? ? s_('UserProfile|Bot activity') : s_('UserProfile|Activity')
= link_to s_('UserProfile|View all'), user_activity_path, class: "hide js-view-all"
.overview-content-list{ data: { href: user_activity_path, qa_selector: 'user_activity_content' } }
- .center.light.loading
- .gl-spinner.gl-spinner-md
+ = gl_loading_icon(size: 'md', css_class: 'loading')
- unless Feature.enabled?(:security_auto_fix) && @user.bot?
.col-md-12.col-lg-6
@@ -47,5 +46,4 @@
= s_('UserProfile|Personal projects')
= link_to s_('UserProfile|View all'), user_projects_path, class: "hide js-view-all"
.overview-content-list{ data: { href: user_projects_path } }
- .center.light.loading
- .gl-spinner.gl-spinner-md
+ = gl_loading_icon(size: 'md', css_class: 'loading')
diff --git a/app/workers/all_queues.yml b/app/workers/all_queues.yml
index fb1fcb7937c..48bdee4062b 100644
--- a/app/workers/all_queues.yml
+++ b/app/workers/all_queues.yml
@@ -309,6 +309,15 @@
:weight: 1
:idempotent: true
:tags: []
+- :name: cronjob:database_batched_background_migration_ci_database
+ :worker_name: Database::BatchedBackgroundMigration::CiDatabaseWorker
+ :feature_category: :database
+ :has_external_dependencies:
+ :urgency: :low
+ :resource_boundary: :unknown
+ :weight: 1
+ :idempotent: true
+ :tags: []
- :name: cronjob:database_drop_detached_partitions
:worker_name: Database::DropDetachedPartitionsWorker
:feature_category: :database
@@ -552,6 +561,15 @@
:weight: 1
:idempotent:
:tags: []
+- :name: cronjob:projects_schedule_refresh_build_artifacts_size_statistics
+ :worker_name: Projects::ScheduleRefreshBuildArtifactsSizeStatisticsWorker
+ :feature_category: :build_artifacts
+ :has_external_dependencies:
+ :urgency: :low
+ :resource_boundary: :unknown
+ :weight: 1
+ :idempotent: true
+ :tags: []
- :name: cronjob:prune_old_events
:worker_name: PruneOldEventsWorker
:feature_category: :users
@@ -561,6 +579,15 @@
:weight: 1
:idempotent:
:tags: []
+- :name: cronjob:quality_test_data_cleanup
+ :worker_name: Quality::TestDataCleanupWorker
+ :feature_category: :quality_management
+ :has_external_dependencies:
+ :urgency: :low
+ :resource_boundary: :unknown
+ :weight: 1
+ :idempotent: true
+ :tags: []
- :name: cronjob:releases_manage_evidence
:worker_name: Releases::ManageEvidenceWorker
:feature_category: :release_evidence
@@ -1654,7 +1681,7 @@
:worker_name: Ci::DropPipelineWorker
:feature_category: :continuous_integration
:has_external_dependencies:
- :urgency: :low
+ :urgency: :high
:resource_boundary: :unknown
:weight: 3
:idempotent: true
@@ -2785,6 +2812,15 @@
:weight: 1
:idempotent: true
:tags: []
+- :name: projects_refresh_build_artifacts_size_statistics
+ :worker_name: Projects::RefreshBuildArtifactsSizeStatisticsWorker
+ :feature_category: :build_artifacts
+ :has_external_dependencies:
+ :urgency: :low
+ :resource_boundary: :unknown
+ :weight: 1
+ :idempotent: true
+ :tags: []
- :name: projects_schedule_bulk_repository_shard_moves
:worker_name: Projects::ScheduleBulkRepositoryShardMovesWorker
:feature_category: :gitaly
diff --git a/app/workers/bulk_imports/export_request_worker.rb b/app/workers/bulk_imports/export_request_worker.rb
index 8bc0acc9b22..21040178cee 100644
--- a/app/workers/bulk_imports/export_request_worker.rb
+++ b/app/workers/bulk_imports/export_request_worker.rb
@@ -14,6 +14,10 @@ module BulkImports
entity = BulkImports::Entity.find(entity_id)
request_export(entity)
+ rescue BulkImports::NetworkError => e
+ log_export_failure(e, entity)
+
+ entity.fail_op!
end
private
@@ -28,5 +32,24 @@ module BulkImports
token: configuration.access_token
)
end
+
+ def log_export_failure(exception, entity)
+ attributes = {
+ bulk_import_entity_id: entity.id,
+ pipeline_class: 'ExportRequestWorker',
+ exception_class: exception.class.to_s,
+ exception_message: exception.message.truncate(255),
+ correlation_id_value: Labkit::Correlation::CorrelationId.current_or_new_id
+ }
+
+ Gitlab::Import::Logger.warn(
+ attributes.merge(
+ bulk_import_id: entity.bulk_import.id,
+ bulk_import_entity_type: entity.source_type
+ )
+ )
+
+ BulkImports::Failure.create(attributes)
+ end
end
end
diff --git a/app/workers/bulk_imports/pipeline_worker.rb b/app/workers/bulk_imports/pipeline_worker.rb
index 8e5d7013c2c..03ec2f058ca 100644
--- a/app/workers/bulk_imports/pipeline_worker.rb
+++ b/app/workers/bulk_imports/pipeline_worker.rb
@@ -43,6 +43,10 @@ module BulkImports
private
def run(pipeline_tracker)
+ if pipeline_tracker.entity.failed?
+ raise(Entity::FailedError, 'Failed entity status')
+ end
+
if ndjson_pipeline?(pipeline_tracker)
status = ExportStatus.new(pipeline_tracker, pipeline_tracker.pipeline_class.relation)
diff --git a/app/workers/ci/build_finished_worker.rb b/app/workers/ci/build_finished_worker.rb
index 56cfaa7e674..70c234bd4c7 100644
--- a/app/workers/ci/build_finished_worker.rb
+++ b/app/workers/ci/build_finished_worker.rb
@@ -39,6 +39,7 @@ module Ci
# We execute these async as these are independent operations.
BuildHooksWorker.perform_async(build.id)
ChatNotificationWorker.perform_async(build.id) if build.pipeline.chat?
+ build.track_deployment_usage
if build.failed? && !build.auto_retry_expected?
::Ci::MergeRequests::AddTodoWhenBuildFailsWorker.perform_async(build.id)
diff --git a/app/workers/ci/drop_pipeline_worker.rb b/app/workers/ci/drop_pipeline_worker.rb
index edb97c3cac5..6018290b3a2 100644
--- a/app/workers/ci/drop_pipeline_worker.rb
+++ b/app/workers/ci/drop_pipeline_worker.rb
@@ -9,6 +9,8 @@ module Ci
sidekiq_options retry: 3
include PipelineQueue
+ urgency :high
+
idempotent!
def perform(pipeline_id, failure_reason)
diff --git a/app/workers/concerns/git_garbage_collect_methods.rb b/app/workers/concerns/git_garbage_collect_methods.rb
index c46deeb716f..13b7e7b5b1f 100644
--- a/app/workers/concerns/git_garbage_collect_methods.rb
+++ b/app/workers/concerns/git_garbage_collect_methods.rb
@@ -83,17 +83,27 @@ module GitGarbageCollectMethods
def gitaly_call(task, resource)
repository = resource.repository.raw_repository
- client = get_gitaly_client(task, repository)
-
- case task
- when :prune, :gc
- client.garbage_collect(bitmaps_enabled?, prune: task == :prune)
- when :full_repack
- client.repack_full(bitmaps_enabled?)
- when :incremental_repack
- client.repack_incremental
- when :pack_refs
- client.pack_refs
+ if Feature.enabled?(:optimized_housekeeping, container(resource), default_enabled: :yaml)
+ client = repository.gitaly_repository_client
+
+ if task == :prune
+ client.prune_unreachable_objects
+ else
+ client.optimize_repository
+ end
+ else
+ client = get_gitaly_client(task, repository)
+
+ case task
+ when :prune, :gc
+ client.garbage_collect(bitmaps_enabled?, prune: task == :prune)
+ when :full_repack
+ client.repack_full(bitmaps_enabled?)
+ when :incremental_repack
+ client.repack_incremental
+ when :pack_refs
+ client.pack_refs
+ end
end
rescue GRPC::NotFound => e
Gitlab::GitLogger.error("#{__method__} failed:\nRepository not found")
diff --git a/app/workers/container_expiration_policies/cleanup_container_repository_worker.rb b/app/workers/container_expiration_policies/cleanup_container_repository_worker.rb
index 7f7a77d0524..cd3ed5d4c9b 100644
--- a/app/workers/container_expiration_policies/cleanup_container_repository_worker.rb
+++ b/app/workers/container_expiration_policies/cleanup_container_repository_worker.rb
@@ -123,7 +123,7 @@ module ContainerExpirationPolicies
end
def throttling_enabled?
- Feature.enabled?(:container_registry_expiration_policies_throttling)
+ Feature.enabled?(:container_registry_expiration_policies_throttling, default_enabled: :yaml)
end
def max_cleanup_execution_time
diff --git a/app/workers/container_expiration_policy_worker.rb b/app/workers/container_expiration_policy_worker.rb
index 16ac61976eb..308ccfe2cb3 100644
--- a/app/workers/container_expiration_policy_worker.rb
+++ b/app/workers/container_expiration_policy_worker.rb
@@ -99,7 +99,7 @@ class ContainerExpirationPolicyWorker # rubocop:disable Scalability/IdempotentWo
end
def throttling_enabled?
- Feature.enabled?(:container_registry_expiration_policies_throttling)
+ Feature.enabled?(:container_registry_expiration_policies_throttling, default_enabled: :yaml)
end
def lease_timeout
diff --git a/app/workers/database/batched_background_migration/ci_database_worker.rb b/app/workers/database/batched_background_migration/ci_database_worker.rb
new file mode 100644
index 00000000000..98ec6f98123
--- /dev/null
+++ b/app/workers/database/batched_background_migration/ci_database_worker.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+module Database
+ module BatchedBackgroundMigration
+ class CiDatabaseWorker # rubocop:disable Scalability/IdempotentWorker
+ include SingleDatabaseWorker
+
+ def self.tracking_database
+ @tracking_database ||= Gitlab::Database::CI_DATABASE_NAME
+ end
+ end
+ end
+end
diff --git a/app/workers/database/batched_background_migration/single_database_worker.rb b/app/workers/database/batched_background_migration/single_database_worker.rb
new file mode 100644
index 00000000000..78c82a6549f
--- /dev/null
+++ b/app/workers/database/batched_background_migration/single_database_worker.rb
@@ -0,0 +1,83 @@
+# frozen_string_literal: true
+
+module Database
+ module BatchedBackgroundMigration
+ module SingleDatabaseWorker
+ extend ActiveSupport::Concern
+
+ include ApplicationWorker
+ include CronjobQueue # rubocop:disable Scalability/CronWorkerContext
+
+ LEASE_TIMEOUT_MULTIPLIER = 3
+ MINIMUM_LEASE_TIMEOUT = 10.minutes.freeze
+ INTERVAL_VARIANCE = 5.seconds.freeze
+
+ included do
+ data_consistency :always
+ feature_category :database
+ idempotent!
+ end
+
+ class_methods do
+ # :nocov:
+ def tracking_database
+ raise NotImplementedError, "#{self.name} does not implement #{__method__}"
+ end
+ # :nocov:
+
+ def lease_key
+ name.demodulize.underscore
+ end
+ end
+
+ def perform
+ unless base_model
+ Sidekiq.logger.info(
+ class: self.class.name,
+ database: self.class.tracking_database,
+ message: 'skipping migration execution for unconfigured database')
+
+ return
+ end
+
+ Gitlab::Database::SharedModel.using_connection(base_model.connection) do
+ break unless Feature.enabled?(:execute_batched_migrations_on_schedule, type: :ops, default_enabled: :yaml) && active_migration
+
+ with_exclusive_lease(active_migration.interval) do
+ # Now that we have the exclusive lease, reload migration in case another process has changed it.
+ # This is a temporary solution until we have better concurrency handling around job execution
+ #
+ # We also have to disable this cop, because ApplicationRecord aliases reset to reload, but our database
+ # models don't inherit from ApplicationRecord
+ active_migration.reload # rubocop:disable Cop/ActiveRecordAssociationReload
+
+ run_active_migration if active_migration.active? && active_migration.interval_elapsed?(variance: INTERVAL_VARIANCE)
+ end
+ end
+ end
+
+ private
+
+ def active_migration
+ @active_migration ||= Gitlab::Database::BackgroundMigration::BatchedMigration.active_migration
+ end
+
+ def run_active_migration
+ Gitlab::Database::BackgroundMigration::BatchedMigrationRunner.new(connection: base_model.connection).run_migration_job(active_migration)
+ end
+
+ def base_model
+ @base_model ||= Gitlab::Database.database_base_models[self.class.tracking_database]
+ end
+
+ def with_exclusive_lease(interval)
+ timeout = [interval * LEASE_TIMEOUT_MULTIPLIER, MINIMUM_LEASE_TIMEOUT].max
+ lease = Gitlab::ExclusiveLease.new(self.class.lease_key, timeout: timeout)
+
+ yield if lease.try_obtain
+ ensure
+ lease&.cancel
+ end
+ end
+ end
+end
diff --git a/app/workers/database/batched_background_migration_worker.rb b/app/workers/database/batched_background_migration_worker.rb
index fda539b372d..29804be832d 100644
--- a/app/workers/database/batched_background_migration_worker.rb
+++ b/app/workers/database/batched_background_migration_worker.rb
@@ -1,56 +1,11 @@
# frozen_string_literal: true
module Database
- class BatchedBackgroundMigrationWorker
- include ApplicationWorker
+ class BatchedBackgroundMigrationWorker # rubocop:disable Scalability/IdempotentWorker
+ include BatchedBackgroundMigration::SingleDatabaseWorker
- data_consistency :always
-
- include CronjobQueue # rubocop:disable Scalability/CronWorkerContext
-
- feature_category :database
- idempotent!
-
- LEASE_TIMEOUT_MULTIPLIER = 3
- MINIMUM_LEASE_TIMEOUT = 10.minutes.freeze
- INTERVAL_VARIANCE = 5.seconds.freeze
-
- def perform
- return unless Feature.enabled?(:execute_batched_migrations_on_schedule, type: :ops, default_enabled: :yaml) && active_migration
-
- with_exclusive_lease(active_migration.interval) do
- # Now that we have the exclusive lease, reload migration in case another process has changed it.
- # This is a temporary solution until we have better concurrency handling around job execution
- #
- # We also have to disable this cop, because ApplicationRecord aliases reset to reload, but our database
- # models don't inherit from ApplicationRecord
- active_migration.reload # rubocop:disable Cop/ActiveRecordAssociationReload
-
- run_active_migration if active_migration.active? && active_migration.interval_elapsed?(variance: INTERVAL_VARIANCE)
- end
- end
-
- private
-
- def active_migration
- @active_migration ||= Gitlab::Database::BackgroundMigration::BatchedMigration.active_migration
- end
-
- def run_active_migration
- Gitlab::Database::BackgroundMigration::BatchedMigrationRunner.new.run_migration_job(active_migration)
- end
-
- def with_exclusive_lease(interval)
- timeout = [interval * LEASE_TIMEOUT_MULTIPLIER, MINIMUM_LEASE_TIMEOUT].max
- lease = Gitlab::ExclusiveLease.new(lease_key, timeout: timeout)
-
- yield if lease.try_obtain
- ensure
- lease&.cancel
- end
-
- def lease_key
- self.class.name.demodulize.underscore
+ def self.tracking_database
+ @tracking_database ||= Gitlab::Database::MAIN_DATABASE_NAME.to_sym
end
end
end
diff --git a/app/workers/projects/git_garbage_collect_worker.rb b/app/workers/projects/git_garbage_collect_worker.rb
index d16583975fc..a70c52abde2 100644
--- a/app/workers/projects/git_garbage_collect_worker.rb
+++ b/app/workers/projects/git_garbage_collect_worker.rb
@@ -7,6 +7,12 @@ module Projects
private
+ # Used for getting a project/group out of the resource in order to scope a feature flag
+ # Can be removed within https://gitlab.com/gitlab-org/gitlab/-/issues/353607
+ def container(resource)
+ resource
+ end
+
override :find_resource
def find_resource(id)
Project.find(id)
diff --git a/app/workers/projects/refresh_build_artifacts_size_statistics_worker.rb b/app/workers/projects/refresh_build_artifacts_size_statistics_worker.rb
new file mode 100644
index 00000000000..a91af72cc2c
--- /dev/null
+++ b/app/workers/projects/refresh_build_artifacts_size_statistics_worker.rb
@@ -0,0 +1,51 @@
+# frozen_string_literal: true
+
+module Projects
+ class RefreshBuildArtifactsSizeStatisticsWorker
+ include ApplicationWorker
+ include LimitedCapacity::Worker
+
+ MAX_RUNNING_LOW = 2
+ MAX_RUNNING_MEDIUM = 20
+ MAX_RUNNING_HIGH = 50
+
+ data_consistency :always
+
+ feature_category :build_artifacts
+
+ idempotent!
+
+ def perform_work(*args)
+ refresh = Projects::RefreshBuildArtifactsSizeStatisticsService.new.execute
+ return unless refresh
+
+ log_extra_metadata_on_done(:project_id, refresh.project_id)
+ log_extra_metadata_on_done(:last_job_artifact_id, refresh.last_job_artifact_id)
+ log_extra_metadata_on_done(:last_batch, refresh.destroyed?)
+ log_extra_metadata_on_done(:refresh_started_at, refresh.refresh_started_at)
+ end
+
+ def remaining_work_count(*args)
+ # LimitedCapacity::Worker only needs to know if there is work left to do
+ # so we can get by with an EXISTS query rather than a count.
+ # https://gitlab.com/gitlab-org/gitlab/-/issues/356167
+ if Projects::BuildArtifactsSizeRefresh.remaining.any?
+ 1
+ else
+ 0
+ end
+ end
+
+ def max_running_jobs
+ if ::Feature.enabled?(:projects_build_artifacts_size_refresh_high)
+ MAX_RUNNING_HIGH
+ elsif ::Feature.enabled?(:projects_build_artifacts_size_refresh_medium)
+ MAX_RUNNING_MEDIUM
+ elsif ::Feature.enabled?(:projects_build_artifacts_size_refresh_low)
+ MAX_RUNNING_LOW
+ else
+ 0
+ end
+ end
+ end
+end
diff --git a/app/workers/projects/schedule_refresh_build_artifacts_size_statistics_worker.rb b/app/workers/projects/schedule_refresh_build_artifacts_size_statistics_worker.rb
new file mode 100644
index 00000000000..ed2b642d998
--- /dev/null
+++ b/app/workers/projects/schedule_refresh_build_artifacts_size_statistics_worker.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+module Projects
+ class ScheduleRefreshBuildArtifactsSizeStatisticsWorker
+ include ApplicationWorker
+ include CronjobQueue # rubocop:disable Scalability/CronWorkerContext
+
+ data_consistency :always
+
+ feature_category :build_artifacts
+
+ idempotent!
+
+ def perform
+ Projects::RefreshBuildArtifactsSizeStatisticsWorker.perform_with_capacity
+ end
+ end
+end
diff --git a/app/workers/quality/test_data_cleanup_worker.rb b/app/workers/quality/test_data_cleanup_worker.rb
new file mode 100644
index 00000000000..68b36cacbbf
--- /dev/null
+++ b/app/workers/quality/test_data_cleanup_worker.rb
@@ -0,0 +1,33 @@
+# frozen_string_literal: true
+
+module Quality
+ class TestDataCleanupWorker
+ include ApplicationWorker
+
+ data_consistency :always
+ feature_category :quality_management
+ urgency :low
+
+ include CronjobQueue
+ idempotent!
+
+ KEEP_RECENT_DATA_DAY = 3
+ GROUP_PATH_PATTERN = 'test-group-fulfillment'
+ GROUP_OWNER_EMAIL_PATTERN = %w(test-user- gitlab-qa-user qa-user-).freeze
+
+ # Remove test groups generated in E2E tests on gstg
+ # rubocop: disable CodeReuse/ActiveRecord
+ def perform
+ return unless Gitlab.staging?
+
+ Group.where('path like ?', "#{GROUP_PATH_PATTERN}%").where('created_at < ?', KEEP_RECENT_DATA_DAY.days.ago).each do |group|
+ next unless GROUP_OWNER_EMAIL_PATTERN.any? { |pattern| group.owners.first.email.include?(pattern) }
+
+ with_context(namespace: group, user: group.owners.first) do
+ Groups::DestroyService.new(group, group.owners.first).execute
+ end
+ end
+ end
+ # rubocop: enable CodeReuse/ActiveRecord
+ end
+end
diff --git a/app/workers/web_hook_worker.rb b/app/workers/web_hook_worker.rb
index fdcd22128a3..301f3720991 100644
--- a/app/workers/web_hook_worker.rb
+++ b/app/workers/web_hook_worker.rb
@@ -13,9 +13,6 @@ class WebHookWorker
worker_has_external_dependencies!
- # Webhook recursion detection properties may be passed through the `data` arg.
- # This will be migrated to the `params` arg over the next few releases.
- # See https://gitlab.com/gitlab-org/gitlab/-/issues/347389.
def perform(hook_id, data, hook_name, params = {})
hook = WebHook.find_by_id(hook_id)
return unless hook
@@ -23,9 +20,6 @@ class WebHookWorker
data = data.with_indifferent_access
params.symbolize_keys!
- # TODO: Remove in 14.9 https://gitlab.com/gitlab-org/gitlab/-/issues/347389
- params[:recursion_detection_request_uuid] ||= data.delete(:_gitlab_recursion_detection_request_uuid)
-
# Before executing the hook, reapply any recursion detection UUID that was initially
# present in the request header so the hook can pass this same header value in its request.
Gitlab::WebHooks::RecursionDetection.set_request_uuid(params[:recursion_detection_request_uuid])
diff --git a/app/workers/wikis/git_garbage_collect_worker.rb b/app/workers/wikis/git_garbage_collect_worker.rb
index 1b455c50618..b00190c6b98 100644
--- a/app/workers/wikis/git_garbage_collect_worker.rb
+++ b/app/workers/wikis/git_garbage_collect_worker.rb
@@ -7,6 +7,12 @@ module Wikis
private
+ # Used for getting a project/group out of the resource in order to scope a feature flag
+ # Can be removed within https://gitlab.com/gitlab-org/gitlab/-/issues/353607
+ def container(resource)
+ resource.container
+ end
+
override :find_resource
def find_resource(id)
Project.find(id).wiki
diff --git a/bin/metrics-server b/bin/metrics-server
index f8eca93908e..d4c9779d1dd 100755
--- a/bin/metrics-server
+++ b/bin/metrics-server
@@ -1,6 +1,7 @@
#!/usr/bin/env ruby
# frozen_string_literal: true
+require_relative '../metrics_server/dependencies'
require_relative '../metrics_server/metrics_server'
target = ENV['METRICS_SERVER_TARGET']
diff --git a/bin/rspec-stackprof b/bin/rspec-stackprof
index 018bfe7da4b..4d72b44976b 100755
--- a/bin/rspec-stackprof
+++ b/bin/rspec-stackprof
@@ -1,18 +1,95 @@
#!/usr/bin/env ruby
+# frozen_string_literal: true
require_relative '../config/bundler_setup'
require 'stackprof'
-$:.unshift 'spec'
-require 'spec_helper'
+require 'rspec'
+require 'optparse'
-filename = ARGV[0].split('/').last
-interval = ENV.fetch('INTERVAL', 1000).to_i
-limit = ENV.fetch('LIMIT', 20)
-raw = ENV.fetch('RAW', false) == 'true'
-output_file = "tmp/#{filename}.dump"
+defaults = {
+ mode: 'wall',
+ limit: 20,
+ raw: false,
+ mode_interval: 1000,
+ mode_object_interval: 1,
+ speedscope: false
+}
+
+options = {
+ mode: ENV.fetch('MODE', defaults[:mode]) || defaults[:mode],
+ interval: ENV['INTERVAL'],
+ limit: ENV.fetch('LIMIT', nil) || defaults[:limit],
+ raw: ENV.fetch('RAW', false) === 'true' || defaults[:raw],
+ output: ENV.fetch('OUTPUT', nil),
+ speedscope: ENV.fetch('SPEEDSCOPE', false) === 'true' || defaults[:speedscope]
+}
+
+OptionParser.new do |opt|
+ opt.banner = <<DOCSTRING
+Run rspec with stackprof enabled.
+
+Usage:
+ #{__FILE__} [--mode=<wall|cpu|object>] [--interval=<interval>] [--limit=<limit>] [--raw=false|true] [--speedscope=false|true] [--output=filename] filename [rspec options]
-StackProf.run(mode: :wall, out: output_file, interval: interval, raw: raw) do
- RSpec::Core::Runner.run(ARGV, $stderr, $stdout)
+Examples:
+ #{__FILE__} --mode=wall --interval=#{defaults[:mode_interval]} --limit=#{defaults[:limit]} --raw=true --output=tmp/example.dump spec/controllers/help_controller_spec.rb
+ #{__FILE__} spec/policies/project_policy_spec.rb -e 'project visibility'
+ #{__FILE__} --speedscope=true spec/controllers/help_controller_spec.rb
+ MODE=cpu LIMIT=5 #{__FILE__} spec/controllers/help_controller_spec.rb
+DOCSTRING
+ opt.separator ''
+ opt.separator 'Options:'
+
+ opt.on('--mode wall|cpu|object', "sampling mode (default: #{defaults[:mode]}) [$MODE]")
+ opt.on('--interval integer', Integer, "sample interval for mode selected. wall/cpu: microseconds with a default of #{defaults[:mode_interval]}, object: seconds with a default of #{defaults[:mode_object_interval]} [$INTERVAL]")
+ opt.on('--limit integer', Integer, "limit output to N entries (default: #{defaults[:limit]}) [$LIMIT]")
+ opt.on('--raw true|false', FalseClass, 'collect extra data required for flamegraph [$RAW]')
+ opt.on('--output filename', String, 'output filename (default: tmp/rspec-filename.dump) [$OUTPUT]')
+ opt.on('--speedscope true|false', FalseClass, "output in speedscope format (default: #{defaults[:speedscope]}) [$SPEEDSCOPE]")
+end.order!(into: options)
+
+case options[:mode]
+when 'wall'
+ options[:interval] ||= defaults[:mode_interval]
+when 'cpu'
+ options[:interval] ||= defaults[:mode_interval]
+when 'object'
+ options[:interval] ||= defaults[:mode_object_interval]
+else
+ raise ArgumentError, "Invalid mode: #{options[:mode]}"
end
-system("bundle exec stackprof #{output_file} --text --limit #{limit}")
+filename = ARGV[0].split('/').last
+extension = options[:speedscope] ? 'json' : 'dump'
+options[:output] ||= "tmp/#{filename}.#{extension}"
+options[:interval] = options[:interval].to_i
+
+if options[:speedscope]
+ profile = StackProf.run(mode: options[:mode].to_sym, interval: options[:interval], raw: true) do
+ RSpec::Core::Runner.run(ARGV, $stderr, $stdout)
+ end
+
+ File.write(options[:output].to_s, Gitlab::Json.generate(profile))
+
+ puts <<DOCSTRING
+Wrote speedscope profile to: #{options[:output]}
+
+If you have speedscope installed:
+ Run: speedscope #{options[:output]}
+
+On OSX:
+ Run: cat #{options[:output]} | pbcopy
+ Then paste it into https://www.speedscope.app/
+
+Alternatively:
+ Upload the file manually to https://www.speedscope.app/
+DOCSTRING
+else
+ StackProf.run(mode: options[:mode].to_sym, out: options[:output], interval: options[:interval], raw: options[:raw]) do
+ RSpec::Core::Runner.run(ARGV, $stderr, $stdout)
+ end
+
+ cmd = %W(bundle exec stackprof #{options[:output]} --text --limit #{options[:limit]})
+ puts '> ' + cmd.join(' ')
+ system(*cmd)
+end
diff --git a/config/application.rb b/config/application.rb
index 8d795e6bc4e..76541daa9e1 100644
--- a/config/application.rb
+++ b/config/application.rb
@@ -18,6 +18,8 @@ module Gitlab
class Application < Rails::Application
config.load_defaults 6.1
+ config.view_component.preview_route = "/-/view_component/previews"
+
# This section contains configuration from Rails upgrades to override the new defaults so that we
# keep existing behavior.
#
@@ -247,6 +249,7 @@ module Gitlab
config.assets.precompile << "mailer.css"
config.assets.precompile << "mailer_client_specific.css"
config.assets.precompile << "notify.css"
+ config.assets.precompile << "notify_enhanced.css"
config.assets.precompile << "mailers/*.css"
config.assets.precompile << "page_bundles/_mixins_and_variables_and_functions.css"
config.assets.precompile << "page_bundles/admin/application_settings_metrics_and_profiling.css"
diff --git a/config/database.yml.decomposed-postgresql b/config/database.yml.decomposed-postgresql
index 729d8447077..23c7f052f5a 100644
--- a/config/database.yml.decomposed-postgresql
+++ b/config/database.yml.decomposed-postgresql
@@ -1,4 +1,22 @@
#
+# PRODUCTION
+#
+production:
+ main:
+ adapter: postgresql
+ encoding: unicode
+ database: gitlabhq_production
+ username: git
+ password: "secure password"
+ host: localhost
+ ci:
+ adapter: postgresql
+ encoding: unicode
+ database: gitlabhq_production_ci
+ username: git
+ password: "secure password"
+ host: localhost
+#
# Development specific
#
development:
diff --git a/config/dependency_decisions.yml b/config/dependency_decisions.yml
index 894e60b61f2..22dd75fc64d 100644
--- a/config/dependency_decisions.yml
+++ b/config/dependency_decisions.yml
@@ -362,3 +362,9 @@
- - :approve
- 0.0.62
- *2
+- - :approve
+ - argparse
+ - :who: Lukas Eipert
+ :why: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/79864#note_845406018
+ :versions: [2.0.1]
+ :when: 2022-02-24 10:44:26.669326000 Z
diff --git a/config/events/1647273260_projectsclustersindex_open_modal.yml b/config/events/1647273260_projectsclustersindex_open_modal.yml
new file mode 100644
index 00000000000..065a99e78ef
--- /dev/null
+++ b/config/events/1647273260_projectsclustersindex_open_modal.yml
@@ -0,0 +1,18 @@
+---
+description: Create token modal opened from the agent's page
+category: default
+action: open_modal
+label_description: agent_token_creation_modal
+product_section: ops
+product_stage: configure
+product_group: group::configure
+milestone: "14.9"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/82690
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
+
diff --git a/config/events/1647273493_projectsclustersindex_click_button.yml b/config/events/1647273493_projectsclustersindex_click_button.yml
new file mode 100644
index 00000000000..2dabfba8204
--- /dev/null
+++ b/config/events/1647273493_projectsclustersindex_click_button.yml
@@ -0,0 +1,19 @@
+---
+description: Button clicked within the create token modal on the agent's page
+category: default
+action: click_button
+label_description: agent_token_creation_modal
+property_description: One of "create-token", "close"
+product_section: ops
+product_stage: configure
+product_group: group::configure
+milestone: "14.9"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/82690
+distributions:
+- ce
+- ee
+tiers:
+- free
+- premium
+- ultimate
+
diff --git a/config/events/20210915205050_code_quality_walkthrough_commit_ci_file_dismissed.yml b/config/events/20210915205050_code_quality_walkthrough_commit_ci_file_dismissed.yml
deleted file mode 100644
index 7ce1a3d9b76..00000000000
--- a/config/events/20210915205050_code_quality_walkthrough_commit_ci_file_dismissed.yml
+++ /dev/null
@@ -1,21 +0,0 @@
-description: "Commit CI file dismissed"
-category: "`code_quality_walkthrough`"
-action: commit_ci_file_dismissed
-label_description: ""
-property_description: ""
-value_description: ""
-extra_properties:
-identifiers:
-product_section: growth
-product_stage: growth
-product_group: group::activation
-product_category:
-milestone: "13.12"
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/58900
-distributions:
-- ce
-- ee
-tiers:
-- free
-- premium
-- ultimate
diff --git a/config/events/20210915205051_code_quality_walkthrough_commit_ci_file_displayed.yml b/config/events/20210915205051_code_quality_walkthrough_commit_ci_file_displayed.yml
deleted file mode 100644
index 4fbece2fef8..00000000000
--- a/config/events/20210915205051_code_quality_walkthrough_commit_ci_file_displayed.yml
+++ /dev/null
@@ -1,21 +0,0 @@
-description: "Commit CI file displayed"
-category: "`code_quality_walkthrough`"
-action: commit_ci_file_displayed
-label_description: ""
-property_description: ""
-value_description: ""
-extra_properties:
-identifiers:
-product_section: growth
-product_stage: growth
-product_group: group::activation
-product_category:
-milestone: "13.12"
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/58900
-distributions:
-- ce
-- ee
-tiers:
-- free
-- premium
-- ultimate
diff --git a/config/events/20210915205052_code_quality_walkthrough_commit_created.yml b/config/events/20210915205052_code_quality_walkthrough_commit_created.yml
deleted file mode 100644
index 5e8d8a1250a..00000000000
--- a/config/events/20210915205052_code_quality_walkthrough_commit_created.yml
+++ /dev/null
@@ -1,21 +0,0 @@
-description: "Commit created"
-category: "`code_quality_walkthrough`"
-action: commit_created
-label_description: ""
-property_description: ""
-value_description: ""
-extra_properties:
-identifiers:
-product_section: growth
-product_stage: growth
-product_group: group::activation
-product_category:
-milestone: "13.12"
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/58900
-distributions:
-- ce
-- ee
-tiers:
-- free
-- premium
-- ultimate
diff --git a/config/events/20210915205053_code_quality_walkthrough_cta_clicked.yml b/config/events/20210915205053_code_quality_walkthrough_cta_clicked.yml
deleted file mode 100644
index 684bb681045..00000000000
--- a/config/events/20210915205053_code_quality_walkthrough_cta_clicked.yml
+++ /dev/null
@@ -1,21 +0,0 @@
-description: "Click empty state CTA"
-category: "`code_quality_walkthrough`"
-action: cta_clicked
-label_description: ""
-property_description: ""
-value_description: ""
-extra_properties:
-identifiers:
-product_section: growth
-product_stage: growth
-product_group: group::activation
-product_category:
-milestone: "13.12"
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/58900
-distributions:
-- ce
-- ee
-tiers:
-- free
-- premium
-- ultimate
diff --git a/config/events/20210915205054_code_quality_walkthrough_failed_pipeline_displayed.yml b/config/events/20210915205054_code_quality_walkthrough_failed_pipeline_displayed.yml
deleted file mode 100644
index 517da8eac13..00000000000
--- a/config/events/20210915205054_code_quality_walkthrough_failed_pipeline_displayed.yml
+++ /dev/null
@@ -1,21 +0,0 @@
-description: "Show failed pipeline"
-category: "`code_quality_walkthrough`"
-action: failed_pipeline_displayed
-label_description: ""
-property_description: ""
-value_description: ""
-extra_properties:
-identifiers:
-product_section: growth
-product_stage: growth
-product_group: group::activation
-product_category:
-milestone: "13.12"
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/58900
-distributions:
-- ce
-- ee
-tiers:
-- free
-- premium
-- ultimate
diff --git a/config/events/20210915205055_code_quality_walkthrough_failed_pipeline_view_logs.yml b/config/events/20210915205055_code_quality_walkthrough_failed_pipeline_view_logs.yml
deleted file mode 100644
index adb4400f288..00000000000
--- a/config/events/20210915205055_code_quality_walkthrough_failed_pipeline_view_logs.yml
+++ /dev/null
@@ -1,21 +0,0 @@
-description: "Show failed pipeline logs"
-category: "`code_quality_walkthrough`"
-action: failed_pipeline_view_logs
-label_description: ""
-property_description: ""
-value_description: ""
-extra_properties:
-identifiers:
-product_section: growth
-product_stage: growth
-product_group: group::activation
-product_category:
-milestone: "13.12"
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/58900
-distributions:
-- ce
-- ee
-tiers:
-- free
-- premium
-- ultimate
diff --git a/config/events/20210915205056_code_quality_walkthrough_running_pipeline_dismissed.yml b/config/events/20210915205056_code_quality_walkthrough_running_pipeline_dismissed.yml
deleted file mode 100644
index 7fcff9644f4..00000000000
--- a/config/events/20210915205056_code_quality_walkthrough_running_pipeline_dismissed.yml
+++ /dev/null
@@ -1,21 +0,0 @@
-description: "Dismiss running pipeline"
-category: "`code_quality_walkthrough`"
-action: running_pipeline_dismissed
-label_description: ""
-property_description: ""
-value_description: ""
-extra_properties:
-identifiers:
-product_section: growth
-product_stage: growth
-product_group: group::activation
-product_category:
-milestone: "13.12"
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/58900
-distributions:
-- ce
-- ee
-tiers:
-- free
-- premium
-- ultimate
diff --git a/config/events/20210915205057_code_quality_walkthrough_running_pipeline_displayed.yml b/config/events/20210915205057_code_quality_walkthrough_running_pipeline_displayed.yml
deleted file mode 100644
index b7faa132d8b..00000000000
--- a/config/events/20210915205057_code_quality_walkthrough_running_pipeline_displayed.yml
+++ /dev/null
@@ -1,21 +0,0 @@
-description: "Show running pipeline"
-category: "`code_quality_walkthrough`"
-action: running_pipeline_displayed
-label_description: ""
-property_description: ""
-value_description: ""
-extra_properties:
-identifiers:
-product_section: growth
-product_stage: growth
-product_group: group::activation
-product_category:
-milestone: "13.12"
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/58900
-distributions:
-- ce
-- ee
-tiers:
-- free
-- premium
-- ultimate
diff --git a/config/events/20210915205058_code_quality_walkthrough_success_pipeline_displayed.yml b/config/events/20210915205058_code_quality_walkthrough_success_pipeline_displayed.yml
deleted file mode 100644
index d5909cdab89..00000000000
--- a/config/events/20210915205058_code_quality_walkthrough_success_pipeline_displayed.yml
+++ /dev/null
@@ -1,21 +0,0 @@
-description: "Show succeeded pipeline"
-category: "`code_quality_walkthrough`"
-action: success_pipeline_displayed
-label_description: ""
-property_description: ""
-value_description: ""
-extra_properties:
-identifiers:
-product_section: growth
-product_stage: growth
-product_group: group::activation
-product_category:
-milestone: "13.12"
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/58900
-distributions:
-- ce
-- ee
-tiers:
-- free
-- premium
-- ultimate
diff --git a/config/events/20210915205059_code_quality_walkthrough_success_pipeline_view_logs.yml b/config/events/20210915205059_code_quality_walkthrough_success_pipeline_view_logs.yml
deleted file mode 100644
index 253bf3c3577..00000000000
--- a/config/events/20210915205059_code_quality_walkthrough_success_pipeline_view_logs.yml
+++ /dev/null
@@ -1,21 +0,0 @@
-description: "Show succeeded pipeline logs"
-category: "`code_quality_walkthrough`"
-action: success_pipeline_view_logs
-label_description: ""
-property_description: ""
-value_description: ""
-extra_properties:
-identifiers:
-product_section: growth
-product_stage: growth
-product_group: group::activation
-product_category:
-milestone: "13.12"
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/58900
-distributions:
-- ce
-- ee
-tiers:
-- free
-- premium
-- ultimate
diff --git a/config/feature_categories.yml b/config/feature_categories.yml
index 00b213d307b..c422d2da691 100644
--- a/config/feature_categories.yml
+++ b/config/feature_categories.yml
@@ -31,6 +31,7 @@
- continuous_delivery
- continuous_integration
- continuous_integration_scaling
+- continuous_verification
- database
- dataops
- delivery
@@ -74,7 +75,6 @@
- kubernetes_management
- license
- license_compliance
-- live_preview
- logging
- memory
- merge_trains
@@ -110,7 +110,6 @@
- secrets_management
- security_benchmarking
- security_orchestration
-- self_monitoring
- service_desk
- service_ping
- sharding
@@ -119,7 +118,6 @@
- static_application_security_testing
- static_site_editor
- subgroups
-- synthetic_monitoring
- team_planning
- tracing
- usage_ping
diff --git a/config/feature_flags/development/allow_unsafe_ruby_regexp.yml b/config/feature_flags/development/allow_unsafe_ruby_regexp.yml
deleted file mode 100644
index 029b1454ea4..00000000000
--- a/config/feature_flags/development/allow_unsafe_ruby_regexp.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: allow_unsafe_ruby_regexp
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/10566
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/257849
-milestone: '11.10'
-type: development
-group: group::pipeline execution
-default_enabled: false
diff --git a/config/feature_flags/development/broadcast_issue_updates.yml b/config/feature_flags/development/broadcast_issue_updates.yml
deleted file mode 100644
index c38263528a9..00000000000
--- a/config/feature_flags/development/broadcast_issue_updates.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: broadcast_issue_updates
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/30732
-rollout_issue_url: https://gitlab.com/gitlab-com/gl-infra/production/-/issues/3413
-milestone: '13.0'
-type: development
-group: group::project management
-default_enabled: true
diff --git a/config/feature_flags/development/cache_shared_runners_enabled.yml b/config/feature_flags/development/cache_shared_runners_enabled.yml
deleted file mode 100644
index 4dde6c852a6..00000000000
--- a/config/feature_flags/development/cache_shared_runners_enabled.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: cache_shared_runners_enabled
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68002
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/338267
-milestone: '14.2'
-type: development
-group: group::optimize
-default_enabled: true
diff --git a/config/feature_flags/development/chat_notification_deployment_protected_branch_filter.yml b/config/feature_flags/development/chat_notification_deployment_protected_branch_filter.yml
deleted file mode 100644
index 0b81a06c593..00000000000
--- a/config/feature_flags/development/chat_notification_deployment_protected_branch_filter.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: chat_notification_deployment_protected_branch_filter
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/74423
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/349131
-milestone: '14.7'
-type: development
-group: group::integrations
-default_enabled: false
diff --git a/config/feature_flags/development/ci_bulk_insert_tags.yml b/config/feature_flags/development/ci_bulk_insert_tags.yml
deleted file mode 100644
index 52a3e22379c..00000000000
--- a/config/feature_flags/development/ci_bulk_insert_tags.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: ci_bulk_insert_tags
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/73198
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/346124
-milestone: '14.6'
-type: development
-group: group::pipeline execution
-default_enabled: true
diff --git a/config/feature_flags/development/ci_drop_cyclical_triggered_pipelines.yml b/config/feature_flags/development/ci_drop_cyclical_triggered_pipelines.yml
deleted file mode 100644
index 3c7204f444b..00000000000
--- a/config/feature_flags/development/ci_drop_cyclical_triggered_pipelines.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: ci_drop_cyclical_triggered_pipelines
-introduced_by_url: https://gitlab.com/gitlab-org/security/gitlab/-/merge_requests/1195
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/329390
-milestone: '13.12'
-type: development
-group: group::pipeline execution
-default_enabled: false
diff --git a/config/feature_flags/development/ci_fix_order_of_subsequent_jobs.yml b/config/feature_flags/development/ci_fix_order_of_subsequent_jobs.yml
new file mode 100644
index 00000000000..9a98604d0a8
--- /dev/null
+++ b/config/feature_flags/development/ci_fix_order_of_subsequent_jobs.yml
@@ -0,0 +1,8 @@
+---
+name: ci_fix_order_of_subsequent_jobs
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/74394
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/345587
+milestone: '14.9'
+type: development
+group: group::pipeline authoring
+default_enabled: false
diff --git a/config/feature_flags/development/ci_pending_builds_maintain_denormalized_data.yml b/config/feature_flags/development/ci_pending_builds_maintain_denormalized_data.yml
index 3a5ec00c32d..51c9fd21564 100644
--- a/config/feature_flags/development/ci_pending_builds_maintain_denormalized_data.yml
+++ b/config/feature_flags/development/ci_pending_builds_maintain_denormalized_data.yml
@@ -1,7 +1,7 @@
---
name: ci_pending_builds_maintain_denormalized_data
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/75425
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/332951
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/354496
milestone: '14.6'
type: development
group: group::pipeline execution
diff --git a/config/feature_flags/development/ci_pending_builds_queue_source.yml b/config/feature_flags/development/ci_pending_builds_queue_source.yml
index f6edd0e98ea..5fc2fcdb77a 100644
--- a/config/feature_flags/development/ci_pending_builds_queue_source.yml
+++ b/config/feature_flags/development/ci_pending_builds_queue_source.yml
@@ -1,8 +1,8 @@
---
name: ci_pending_builds_queue_source
introduced_by_url:
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/350884
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/354496
milestone: '14.0'
type: development
group: group::pipeline execution
-default_enabled: false
+default_enabled: true
diff --git a/config/feature_flags/development/ci_pipeline_merge_request_presence_check.yml b/config/feature_flags/development/ci_pipeline_merge_request_presence_check.yml
deleted file mode 100644
index 19f674aa27c..00000000000
--- a/config/feature_flags/development/ci_pipeline_merge_request_presence_check.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: ci_pipeline_merge_request_presence_check
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/78574
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/350734
-milestone: '14.8'
-type: development
-group: group::pipeline execution
-default_enabled: true
diff --git a/config/feature_flags/development/ci_queuing_use_denormalized_data_strategy.yml b/config/feature_flags/development/ci_queuing_use_denormalized_data_strategy.yml
index 53515ddab5a..43c7c8e7c2a 100644
--- a/config/feature_flags/development/ci_queuing_use_denormalized_data_strategy.yml
+++ b/config/feature_flags/development/ci_queuing_use_denormalized_data_strategy.yml
@@ -1,7 +1,7 @@
---
name: ci_queuing_use_denormalized_data_strategy
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/76543
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/332951
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/354496
milestone: '14.6'
type: development
group: group::pipeline execution
diff --git a/config/feature_flags/development/ci_trigger_forward_variables.yml b/config/feature_flags/development/ci_trigger_forward_variables.yml
new file mode 100644
index 00000000000..34e418599b4
--- /dev/null
+++ b/config/feature_flags/development/ci_trigger_forward_variables.yml
@@ -0,0 +1,8 @@
+---
+name: ci_trigger_forward_variables
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/82676
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/355572
+milestone: '14.9'
+type: development
+group: group::pipeline authoring
+default_enabled: false
diff --git a/config/feature_flags/development/cluster_vulnerabilities.yml b/config/feature_flags/development/cluster_vulnerabilities.yml
deleted file mode 100644
index 9d7f3228d66..00000000000
--- a/config/feature_flags/development/cluster_vulnerabilities.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: cluster_vulnerabilities
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/73321
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/343917
-milestone: '14.5'
-type: development
-group: group::container security
-default_enabled: true
diff --git a/config/feature_flags/development/consolidated_edit_button.yml b/config/feature_flags/development/consolidated_edit_button.yml
deleted file mode 100644
index c618f70555b..00000000000
--- a/config/feature_flags/development/consolidated_edit_button.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: consolidated_edit_button
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/44311
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/270433
-milestone: '13.5'
-type: development
-group: group::editor
-default_enabled: false
diff --git a/config/feature_flags/development/container_expiration_policies_historic_entry.yml b/config/feature_flags/development/container_expiration_policies_historic_entry.yml
deleted file mode 100644
index ab2111b3159..00000000000
--- a/config/feature_flags/development/container_expiration_policies_historic_entry.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: container_expiration_policies_historic_entry
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/44444
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/262639
-milestone: '13.5'
-type: development
-group: group::package
-default_enabled: false
diff --git a/config/feature_flags/development/container_registry_expiration_policies_throttling.yml b/config/feature_flags/development/container_registry_expiration_policies_throttling.yml
index f9aa6bde700..e22c7c3177b 100644
--- a/config/feature_flags/development/container_registry_expiration_policies_throttling.yml
+++ b/config/feature_flags/development/container_registry_expiration_policies_throttling.yml
@@ -5,4 +5,4 @@ rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/238190
milestone: '13.4'
type: development
group: group::package
-default_enabled: false
+default_enabled: true
diff --git a/config/feature_flags/development/container_registry_follow_redirects_middleware.yml b/config/feature_flags/development/container_registry_follow_redirects_middleware.yml
new file mode 100644
index 00000000000..6b0ded9dbc4
--- /dev/null
+++ b/config/feature_flags/development/container_registry_follow_redirects_middleware.yml
@@ -0,0 +1,8 @@
+---
+name: container_registry_follow_redirects_middleware
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/81056
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/353291
+milestone: '14.9'
+type: development
+group: group::package
+default_enabled: true
diff --git a/config/feature_flags/development/container_registry_migration_phase1.yml b/config/feature_flags/development/container_registry_migration_phase1.yml
deleted file mode 100644
index 85fbdcfab01..00000000000
--- a/config/feature_flags/development/container_registry_migration_phase1.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: container_registry_migration_phase1
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/63907
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/335703
-milestone: '14.1'
-type: development
-group: group::package
-default_enabled: false
diff --git a/config/feature_flags/development/container_registry_migration_phase1_allow.yml b/config/feature_flags/development/container_registry_migration_phase1_allow.yml
deleted file mode 100644
index 1e8d260c93b..00000000000
--- a/config/feature_flags/development/container_registry_migration_phase1_allow.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: container_registry_migration_phase1_allow
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/63907
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/335705
-milestone: '14.1'
-type: development
-group: group::package
-default_enabled: false
diff --git a/config/feature_flags/development/container_registry_migration_phase1_deny.yml b/config/feature_flags/development/container_registry_migration_phase1_deny.yml
deleted file mode 100644
index 1aa66059045..00000000000
--- a/config/feature_flags/development/container_registry_migration_phase1_deny.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: container_registry_migration_phase1_deny
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/63907
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/335706
-milestone: '14.1'
-type: development
-group: group::package
-default_enabled: false
diff --git a/config/feature_flags/development/context_commits.yml b/config/feature_flags/development/context_commits.yml
deleted file mode 100644
index 521ab5d0a6f..00000000000
--- a/config/feature_flags/development/context_commits.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: context_commits
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/23701
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/320757
-milestone: '12.8'
-type: development
-group: group::code review
-default_enabled: true
diff --git a/config/feature_flags/development/create_project_namespace_on_project_create.yml b/config/feature_flags/development/create_project_namespace_on_project_create.yml
deleted file mode 100644
index 0d6ea8b2784..00000000000
--- a/config/feature_flags/development/create_project_namespace_on_project_create.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: create_project_namespace_on_project_create
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/70972
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/344954
-milestone: '14.5'
-type: development
-group: group::workspace
-default_enabled: true
diff --git a/config/feature_flags/development/default_merge_ref_for_diffs.yml b/config/feature_flags/development/default_merge_ref_for_diffs.yml
deleted file mode 100644
index f197044d47f..00000000000
--- a/config/feature_flags/development/default_merge_ref_for_diffs.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: default_merge_ref_for_diffs
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/34472
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/276917
-milestone: '13.4'
-type: development
-group: group::code review
-default_enabled: true
diff --git a/config/feature_flags/development/disable_unsafe_regexp.yml b/config/feature_flags/development/disable_unsafe_regexp.yml
new file mode 100644
index 00000000000..196b647082e
--- /dev/null
+++ b/config/feature_flags/development/disable_unsafe_regexp.yml
@@ -0,0 +1,8 @@
+---
+name: disable_unsafe_regexp
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/79611
+rollout_issue_url:
+milestone: '14.9'
+type: development
+group: group::pipeline execution
+default_enabled: false
diff --git a/config/feature_flags/development/dispensable_render.yml b/config/feature_flags/development/dispensable_render.yml
new file mode 100644
index 00000000000..6f1689b325a
--- /dev/null
+++ b/config/feature_flags/development/dispensable_render.yml
@@ -0,0 +1,8 @@
+---
+name: dispensable_render
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/81546
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/354337
+milestone: '14.9'
+type: development
+group: group::activation
+default_enabled: true
diff --git a/config/feature_flags/development/display_outdated_line_diff.yml b/config/feature_flags/development/display_outdated_line_diff.yml
deleted file mode 100644
index 979575da381..00000000000
--- a/config/feature_flags/development/display_outdated_line_diff.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: display_outdated_line_diff
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/72597
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/345491
-milestone: '14.5'
-type: development
-group: group::code review
-default_enabled: true
diff --git a/config/feature_flags/development/enable_new_sentry_integration.yml b/config/feature_flags/development/enable_new_sentry_integration.yml
new file mode 100644
index 00000000000..00665f80ed6
--- /dev/null
+++ b/config/feature_flags/development/enable_new_sentry_integration.yml
@@ -0,0 +1,8 @@
+---
+name: enable_new_sentry_integration
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/72428
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/344832
+milestone: '14.9'
+type: development
+group: group::pipeline execution
+default_enabled: false
diff --git a/config/feature_flags/development/enable_old_sentry_integration.yml b/config/feature_flags/development/enable_old_sentry_integration.yml
new file mode 100644
index 00000000000..4911dbfdc78
--- /dev/null
+++ b/config/feature_flags/development/enable_old_sentry_integration.yml
@@ -0,0 +1,8 @@
+---
+name: enable_old_sentry_integration
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/72428
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/344832
+milestone: '14.9'
+type: development
+group: group::pipeline execution
+default_enabled: true
diff --git a/config/feature_flags/development/enforce_security_report_validation.yml b/config/feature_flags/development/enforce_security_report_validation.yml
deleted file mode 100644
index ada5863b4d7..00000000000
--- a/config/feature_flags/development/enforce_security_report_validation.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: enforce_security_report_validation
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/79798
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/351000
-milestone: '14.8'
-type: development
-group: group::threat insights
-default_enabled: false
diff --git a/config/feature_flags/development/enhanced_notify_css.yml b/config/feature_flags/development/enhanced_notify_css.yml
new file mode 100644
index 00000000000..e47db3ba435
--- /dev/null
+++ b/config/feature_flags/development/enhanced_notify_css.yml
@@ -0,0 +1,8 @@
+---
+name: enhanced_notify_css
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/78604
+rollout_issue_url:
+milestone: '14.8'
+type: development
+group: group::project management
+default_enabled: false
diff --git a/config/feature_flags/development/exit_registration_verification.yml b/config/feature_flags/development/exit_registration_verification.yml
new file mode 100644
index 00000000000..c544ebc2943
--- /dev/null
+++ b/config/feature_flags/development/exit_registration_verification.yml
@@ -0,0 +1,8 @@
+---
+name: exit_registration_verification
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/80286
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/352397
+milestone: '14.8'
+type: development
+group: group::activation
+default_enabled: false
diff --git a/config/feature_flags/development/fix_comment_scroll.yml b/config/feature_flags/development/fix_comment_scroll.yml
deleted file mode 100644
index 706cd816288..00000000000
--- a/config/feature_flags/development/fix_comment_scroll.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: fix_comment_scroll
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/76340
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/349638
-milestone: '14.7'
-type: development
-group: group::project management
-default_enabled: false
diff --git a/config/feature_flags/development/fork_project_form.yml b/config/feature_flags/development/fork_project_form.yml
deleted file mode 100644
index 90532c78c8a..00000000000
--- a/config/feature_flags/development/fork_project_form.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: fork_project_form
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/53544
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/321387
-milestone: '13.10'
-type: development
-group: group::source code
-default_enabled: true
diff --git a/config/feature_flags/development/generic_packages.yml b/config/feature_flags/development/generic_packages.yml
deleted file mode 100644
index b2ab35c713c..00000000000
--- a/config/feature_flags/development/generic_packages.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: generic_packages
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/40045
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/239133
-milestone: '13.4'
-type: development
-group: group::release
-default_enabled: true
diff --git a/config/feature_flags/development/geo_token_user_authentication.yml b/config/feature_flags/development/geo_token_user_authentication.yml
index 779e9b92351..aab95c93312 100644
--- a/config/feature_flags/development/geo_token_user_authentication.yml
+++ b/config/feature_flags/development/geo_token_user_authentication.yml
@@ -1,8 +1,8 @@
---
name: geo_token_user_authentication
-introduced_by_url:
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/79431
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/351450
milestone: '14.8'
type: development
group: group::geo
-default_enabled: false
+default_enabled: true
diff --git a/config/feature_flags/development/gl_avatar_for_all_user_avatars.yml b/config/feature_flags/development/gl_avatar_for_all_user_avatars.yml
new file mode 100644
index 00000000000..a3fee67a7f6
--- /dev/null
+++ b/config/feature_flags/development/gl_avatar_for_all_user_avatars.yml
@@ -0,0 +1,8 @@
+---
+name: gl_avatar_for_all_user_avatars
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/81437
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/353477
+milestone: '14.9'
+type: development
+group: group::foundations
+default_enabled: false
diff --git a/config/feature_flags/development/group_project_api_preload_plans.yml b/config/feature_flags/development/group_project_api_preload_plans.yml
deleted file mode 100644
index 3854bed461a..00000000000
--- a/config/feature_flags/development/group_project_api_preload_plans.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: group_project_api_preload_plans
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/77538
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/350176
-milestone: '14.7'
-type: development
-group: group::authentication and authorization
-default_enabled: false
diff --git a/config/feature_flags/development/group_releases_finder_inoperator.yml b/config/feature_flags/development/group_releases_finder_inoperator.yml
new file mode 100644
index 00000000000..c76c328b5bf
--- /dev/null
+++ b/config/feature_flags/development/group_releases_finder_inoperator.yml
@@ -0,0 +1,8 @@
+---
+name: group_releases_finder_inoperator
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/80093
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/355463
+milestone: '14.9'
+type: development
+group: group::release
+default_enabled: false
diff --git a/config/feature_flags/development/harbor_registry_integration.yml b/config/feature_flags/development/harbor_registry_integration.yml
new file mode 100644
index 00000000000..84d9709ca30
--- /dev/null
+++ b/config/feature_flags/development/harbor_registry_integration.yml
@@ -0,0 +1,8 @@
+---
+name: harbor_registry_integration
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/81593
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/353595
+milestone: '14.9'
+type: development
+group: group::package
+default_enabled: false
diff --git a/config/feature_flags/development/header_read_timeout_buffered_io.yml b/config/feature_flags/development/header_read_timeout_buffered_io.yml
index 552052e2d9b..ba7ef4cc000 100644
--- a/config/feature_flags/development/header_read_timeout_buffered_io.yml
+++ b/config/feature_flags/development/header_read_timeout_buffered_io.yml
@@ -5,4 +5,4 @@ rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/350233
milestone: '14.8'
type: development
group: group::integrations
-default_enabled: false
+default_enabled: true
diff --git a/config/feature_flags/development/import_project_from_remote_file_s3.yml b/config/feature_flags/development/import_project_from_remote_file_s3.yml
new file mode 100644
index 00000000000..c7d52202726
--- /dev/null
+++ b/config/feature_flags/development/import_project_from_remote_file_s3.yml
@@ -0,0 +1,8 @@
+---
+name: import_project_from_remote_file_s3
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/77259
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/350571
+milestone: '14.9'
+type: development
+group: group::import
+default_enabled: false
diff --git a/config/feature_flags/development/import_relation_object_persistence.yml b/config/feature_flags/development/import_relation_object_persistence.yml
new file mode 100644
index 00000000000..e182ea31a72
--- /dev/null
+++ b/config/feature_flags/development/import_relation_object_persistence.yml
@@ -0,0 +1,8 @@
+---
+name: import_relation_object_persistence
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/79963
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/354497
+milestone: '14.9'
+type: development
+group: group::import
+default_enabled: false
diff --git a/config/feature_flags/development/incident_timeline_event_tab.yml b/config/feature_flags/development/incident_timeline_event_tab.yml
new file mode 100644
index 00000000000..01dd9276007
--- /dev/null
+++ b/config/feature_flags/development/incident_timeline_event_tab.yml
@@ -0,0 +1,8 @@
+---
+name: incident_timeline_event_tab
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/80802
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/353426
+milestone: '14.9'
+type: development
+group: group::respond
+default_enabled: false
diff --git a/config/feature_flags/development/incremental_repository_backup.yml b/config/feature_flags/development/incremental_repository_backup.yml
new file mode 100644
index 00000000000..d9eb97ba327
--- /dev/null
+++ b/config/feature_flags/development/incremental_repository_backup.yml
@@ -0,0 +1,8 @@
+---
+name: incremental_repository_backup
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/79589
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/355945
+milestone: '14.9'
+type: development
+group: group::gitaly
+default_enabled: false
diff --git a/config/feature_flags/development/integrated_error_tracking.yml b/config/feature_flags/development/integrated_error_tracking.yml
new file mode 100644
index 00000000000..fb302daed57
--- /dev/null
+++ b/config/feature_flags/development/integrated_error_tracking.yml
@@ -0,0 +1,8 @@
+---
+name: integrated_error_tracking
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/81767
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/353956
+milestone: '14.9'
+type: development
+group: group::respond
+default_enabled: false
diff --git a/config/feature_flags/development/integration_form_sections.yml b/config/feature_flags/development/integration_form_sections.yml
new file mode 100644
index 00000000000..bb03174d2fd
--- /dev/null
+++ b/config/feature_flags/development/integration_form_sections.yml
@@ -0,0 +1,8 @@
+---
+name: integration_form_sections
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/80712
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/352827
+milestone: '14.9'
+type: development
+group: group::integrations
+default_enabled: true
diff --git a/config/feature_flags/development/invite_members_group_modal.yml b/config/feature_flags/development/invite_members_group_modal.yml
deleted file mode 100644
index ab28a2c6e24..00000000000
--- a/config/feature_flags/development/invite_members_group_modal.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: invite_members_group_modal
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/37906
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/247208
-milestone: '13.5'
-type: development
-group: group::expansion
-default_enabled: true
diff --git a/config/feature_flags/development/issue_boards_filtered_search.yml b/config/feature_flags/development/issue_boards_filtered_search.yml
deleted file mode 100644
index dadbbd1b2fc..00000000000
--- a/config/feature_flags/development/issue_boards_filtered_search.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: issue_boards_filtered_search
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/61752
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/331649
-milestone: '14.1'
-type: development
-group: group::product planning
-default_enabled: true
diff --git a/config/feature_flags/development/issues_full_text_search.yml b/config/feature_flags/development/issues_full_text_search.yml
new file mode 100644
index 00000000000..354dbede75f
--- /dev/null
+++ b/config/feature_flags/development/issues_full_text_search.yml
@@ -0,0 +1,8 @@
+---
+name: issues_full_text_search
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/71913
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/354784
+milestone: '14.5'
+type: development
+group: group::project management
+default_enabled: false
diff --git a/config/feature_flags/development/iteration_cadences.yml b/config/feature_flags/development/iteration_cadences.yml
index 2a496449a6a..c90743020d6 100644
--- a/config/feature_flags/development/iteration_cadences.yml
+++ b/config/feature_flags/development/iteration_cadences.yml
@@ -1,7 +1,7 @@
---
name: iteration_cadences
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/54822
-rollout_issue_url:
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/354878
milestone: '13.10'
type: development
group: group::project management
diff --git a/config/feature_flags/development/jira_connect_installation_update.yml b/config/feature_flags/development/jira_connect_installation_update.yml
new file mode 100644
index 00000000000..a92a7dafc14
--- /dev/null
+++ b/config/feature_flags/development/jira_connect_installation_update.yml
@@ -0,0 +1,8 @@
+---
+name: jira_connect_installation_update
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/83038
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/356083
+milestone: '14.9'
+type: development
+group: group::integrations
+default_enabled: false
diff --git a/config/feature_flags/development/jira_connect_oauth.yml b/config/feature_flags/development/jira_connect_oauth.yml
new file mode 100644
index 00000000000..2f090d56bd1
--- /dev/null
+++ b/config/feature_flags/development/jira_connect_oauth.yml
@@ -0,0 +1,8 @@
+---
+name: jira_connect_oauth
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/81126
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/355048
+milestone: '14.9'
+type: development
+group: group::integrations
+default_enabled: false
diff --git a/config/feature_flags/development/job_deployment_count.yml b/config/feature_flags/development/job_deployment_count.yml
new file mode 100644
index 00000000000..9a101da9a99
--- /dev/null
+++ b/config/feature_flags/development/job_deployment_count.yml
@@ -0,0 +1,8 @@
+---
+name: job_deployment_count
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/79272
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/351591
+milestone: '14.8'
+type: development
+group: group::release
+default_enabled: false
diff --git a/config/feature_flags/development/jobs_tab_vue.yml b/config/feature_flags/development/jobs_tab_vue.yml
deleted file mode 100644
index d6e797f66a5..00000000000
--- a/config/feature_flags/development/jobs_tab_vue.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: jobs_tab_vue
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/76146
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/347371
-milestone: '14.6'
-type: development
-group: group::pipeline execution
-default_enabled: true
diff --git a/config/feature_flags/development/jupyter_clean_diffs.yml b/config/feature_flags/development/jupyter_clean_diffs.yml
deleted file mode 100644
index 0f3f6fe3057..00000000000
--- a/config/feature_flags/development/jupyter_clean_diffs.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: jupyter_clean_diffs
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/71477
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/343433
-milestone: '14.5'
-type: development
-group: group::incubation
-default_enabled: true
diff --git a/config/feature_flags/development/lfk_automatic_partition_creation.yml b/config/feature_flags/development/lfk_automatic_partition_creation.yml
index 72678ff9cbf..5eb50d36f27 100644
--- a/config/feature_flags/development/lfk_automatic_partition_creation.yml
+++ b/config/feature_flags/development/lfk_automatic_partition_creation.yml
@@ -5,4 +5,4 @@ rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/346907
milestone: '14.6'
type: development
group: group::sharding
-default_enabled: false
+default_enabled: true
diff --git a/config/feature_flags/development/lfk_automatic_partition_dropping.yml b/config/feature_flags/development/lfk_automatic_partition_dropping.yml
index 5b908a3309e..a45d6b8f346 100644
--- a/config/feature_flags/development/lfk_automatic_partition_dropping.yml
+++ b/config/feature_flags/development/lfk_automatic_partition_dropping.yml
@@ -5,4 +5,4 @@ rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/346908
milestone: '14.6'
type: development
group: group::sharding
-default_enabled: false
+default_enabled: true
diff --git a/config/feature_flags/development/lfk_fair_queueing.yml b/config/feature_flags/development/lfk_fair_queueing.yml
index ac67ffa14f0..6dc6cb72e56 100644
--- a/config/feature_flags/development/lfk_fair_queueing.yml
+++ b/config/feature_flags/development/lfk_fair_queueing.yml
@@ -5,4 +5,4 @@ rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/351082
milestone: '14.8'
type: development
group: group::sharding
-default_enabled: false
+default_enabled: true
diff --git a/config/feature_flags/development/load_balancing_for_export_workers.yml b/config/feature_flags/development/load_balancing_for_export_workers.yml
deleted file mode 100644
index 04ebd8b4a04..00000000000
--- a/config/feature_flags/development/load_balancing_for_export_workers.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: load_balancing_for_export_workers
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68153
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/338615
-milestone: '14.2'
-type: development
-group: group::import
-default_enabled: false
diff --git a/config/feature_flags/development/merge_service_ping_instrumented_metrics.yml b/config/feature_flags/development/merge_service_ping_instrumented_metrics.yml
new file mode 100644
index 00000000000..4a19544bb9f
--- /dev/null
+++ b/config/feature_flags/development/merge_service_ping_instrumented_metrics.yml
@@ -0,0 +1,8 @@
+---
+name: merge_service_ping_instrumented_metrics
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/77629
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/352964
+milestone: '14.8'
+type: development
+group: group::product intelligence
+default_enabled: true
diff --git a/config/feature_flags/development/namespaces_cache_first_auto_devops_config.yml b/config/feature_flags/development/namespaces_cache_first_auto_devops_config.yml
new file mode 100644
index 00000000000..6d15df2bb91
--- /dev/null
+++ b/config/feature_flags/development/namespaces_cache_first_auto_devops_config.yml
@@ -0,0 +1,8 @@
+---
+name: namespaces_cache_first_auto_devops_config
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/80937
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/353503
+milestone: '14.9'
+type: development
+group: group::authentication and authorization
+default_enabled: false
diff --git a/config/feature_flags/development/new_environments_table.yml b/config/feature_flags/development/new_environments_table.yml
deleted file mode 100644
index b97a4d49cd8..00000000000
--- a/config/feature_flags/development/new_environments_table.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: new_environments_table
-introduced_by_url:
-rollout_issue_url:
-milestone: '14.4'
-type: development
-group: group::release
-default_enabled: false
diff --git a/config/feature_flags/development/new_vulnerability_form.yml b/config/feature_flags/development/new_vulnerability_form.yml
new file mode 100644
index 00000000000..ee812484928
--- /dev/null
+++ b/config/feature_flags/development/new_vulnerability_form.yml
@@ -0,0 +1,8 @@
+---
+name: new_vulnerability_form
+introduced_by_url:
+rollout_issue_url:
+milestone: '14.9'
+type: development
+group: group::threat insights
+default_enabled: false
diff --git a/config/feature_flags/development/optimized_housekeeping.yml b/config/feature_flags/development/optimized_housekeeping.yml
new file mode 100644
index 00000000000..9a5b9244116
--- /dev/null
+++ b/config/feature_flags/development/optimized_housekeeping.yml
@@ -0,0 +1,8 @@
+---
+name: optimized_housekeeping
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/81465
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/353607
+milestone: '14.9'
+type: development
+group: group::source code
+default_enabled: false
diff --git a/config/feature_flags/development/pipeline_schedules_with_tags.yml b/config/feature_flags/development/pipeline_schedules_with_tags.yml
new file mode 100644
index 00000000000..9eb7b60d300
--- /dev/null
+++ b/config/feature_flags/development/pipeline_schedules_with_tags.yml
@@ -0,0 +1,8 @@
+---
+name: pipeline_schedules_with_tags
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/81476
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/354421
+milestone: '14.9'
+type: development
+group: group::pipeline execution
+default_enabled: true
diff --git a/config/feature_flags/development/preserve_latest_wal_locations_for_idempotent_jobs.yml b/config/feature_flags/development/preserve_latest_wal_locations_for_idempotent_jobs.yml
deleted file mode 100644
index 24e4823997d..00000000000
--- a/config/feature_flags/development/preserve_latest_wal_locations_for_idempotent_jobs.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: preserve_latest_wal_locations_for_idempotent_jobs
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/66280
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/338350
-milestone: '14.3'
-type: development
-group: group::memory
-default_enabled: true
diff --git a/config/feature_flags/development/prevent_sensitive_fields_from_serializable_hash.yml b/config/feature_flags/development/prevent_sensitive_fields_from_serializable_hash.yml
new file mode 100644
index 00000000000..7bcbe6b79c2
--- /dev/null
+++ b/config/feature_flags/development/prevent_sensitive_fields_from_serializable_hash.yml
@@ -0,0 +1,8 @@
+---
+name: prevent_sensitive_fields_from_serializable_hash
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/81773
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/353878
+milestone: '14.9'
+type: development
+group: group::sharding
+default_enabled: false
diff --git a/config/feature_flags/development/project_import_schedule_worker_job_tracker.yml b/config/feature_flags/development/project_import_schedule_worker_job_tracker.yml
deleted file mode 100644
index 5dae4ddc60c..00000000000
--- a/config/feature_flags/development/project_import_schedule_worker_job_tracker.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: project_import_schedule_worker_job_tracker
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/79097
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/351408
-milestone: '14.8'
-type: development
-group: group::scalability
-default_enabled: false
diff --git a/config/feature_flags/development/projects_build_artifacts_size_refresh_high.yml b/config/feature_flags/development/projects_build_artifacts_size_refresh_high.yml
new file mode 100644
index 00000000000..77b5feafd6a
--- /dev/null
+++ b/config/feature_flags/development/projects_build_artifacts_size_refresh_high.yml
@@ -0,0 +1,8 @@
+---
+name: projects_build_artifacts_size_refresh_high
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/81306
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/356018
+milestone: '14.9'
+type: development
+group: group::pipeline insights
+default_enabled: false
diff --git a/config/feature_flags/development/projects_build_artifacts_size_refresh_low.yml b/config/feature_flags/development/projects_build_artifacts_size_refresh_low.yml
new file mode 100644
index 00000000000..cefecb245e3
--- /dev/null
+++ b/config/feature_flags/development/projects_build_artifacts_size_refresh_low.yml
@@ -0,0 +1,8 @@
+---
+name: projects_build_artifacts_size_refresh_low
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/81306
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/356018
+milestone: '14.9'
+type: development
+group: group::pipeline insights
+default_enabled: false
diff --git a/config/feature_flags/development/projects_build_artifacts_size_refresh_medium.yml b/config/feature_flags/development/projects_build_artifacts_size_refresh_medium.yml
new file mode 100644
index 00000000000..caeb6647782
--- /dev/null
+++ b/config/feature_flags/development/projects_build_artifacts_size_refresh_medium.yml
@@ -0,0 +1,8 @@
+---
+name: projects_build_artifacts_size_refresh_medium
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/81306
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/356018
+milestone: '14.9'
+type: development
+group: group::pipeline insights
+default_enabled: false
diff --git a/config/feature_flags/development/publish_project_deleted_event.yml b/config/feature_flags/development/publish_project_deleted_event.yml
deleted file mode 100644
index 1287ebe9f66..00000000000
--- a/config/feature_flags/development/publish_project_deleted_event.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: publish_project_deleted_event
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/78862
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/351073
-milestone: '14.8'
-type: development
-group: group::pipeline insights
-default_enabled: false
diff --git a/config/feature_flags/development/rate_limit_profile_update_username.yml b/config/feature_flags/development/rate_limit_profile_update_username.yml
deleted file mode 100644
index e72e3d605e3..00000000000
--- a/config/feature_flags/development/rate_limit_profile_update_username.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: rate_limit_profile_update_username
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/77221
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/349132
-milestone: '14.7'
-type: development
-group: group::optimize
-default_enabled: false
diff --git a/config/feature_flags/development/rate_limit_user_by_id_endpoint.yml b/config/feature_flags/development/rate_limit_user_by_id_endpoint.yml
deleted file mode 100644
index d5523b7541b..00000000000
--- a/config/feature_flags/development/rate_limit_user_by_id_endpoint.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: rate_limit_user_by_id_endpoint
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/73069
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/348796
-milestone: '14.6'
-type: development
-group: group::optimize
-default_enabled: false
diff --git a/config/feature_flags/development/rate_limit_user_sign_up_endpoint.yml b/config/feature_flags/development/rate_limit_user_sign_up_endpoint.yml
deleted file mode 100644
index af1957e54c8..00000000000
--- a/config/feature_flags/development/rate_limit_user_sign_up_endpoint.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: rate_limit_user_sign_up_endpoint
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/77835
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/349843
-milestone: '14.7'
-type: development
-group: group::optimize
-default_enabled: false
diff --git a/config/feature_flags/development/rate_limit_username_exists_endpoint.yml b/config/feature_flags/development/rate_limit_username_exists_endpoint.yml
deleted file mode 100644
index 5a82dc96943..00000000000
--- a/config/feature_flags/development/rate_limit_username_exists_endpoint.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: rate_limit_username_exists_endpoint
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/77119
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/348974
-milestone: '14.7'
-type: development
-group: group::optimize
-default_enabled: false
diff --git a/config/feature_flags/development/rate_limited_service_issues_create.yml b/config/feature_flags/development/rate_limited_service_issues_create.yml
deleted file mode 100644
index 95ece10aa6c..00000000000
--- a/config/feature_flags/development/rate_limited_service_issues_create.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: rate_limited_service_issues_create
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68526
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/342677
-milestone: '14.4'
-type: development
-group: group::project management
-default_enabled: false
diff --git a/config/feature_flags/development/read_from_vulnerability_finding_evidence.yml b/config/feature_flags/development/read_from_vulnerability_finding_evidence.yml
deleted file mode 100644
index 076339c4f32..00000000000
--- a/config/feature_flags/development/read_from_vulnerability_finding_evidence.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: read_from_vulnerability_finding_evidence
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/79883
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/352632
-milestone: '14.8'
-type: development
-group: group::threat insights
-default_enabled: false
diff --git a/config/feature_flags/development/real_time_issue_sidebar.yml b/config/feature_flags/development/real_time_issue_sidebar.yml
deleted file mode 100644
index 12d3da86cad..00000000000
--- a/config/feature_flags/development/real_time_issue_sidebar.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: real_time_issue_sidebar
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/30239
-rollout_issue_url: https://gitlab.com/gitlab-com/gl-infra/delivery/-/issues/1210
-milestone: '13.0'
-type: development
-group: group::project management
-default_enabled: true
diff --git a/config/feature_flags/development/rearrange_pipelines_table.yml b/config/feature_flags/development/rearrange_pipelines_table.yml
deleted file mode 100644
index 4f16d6651b6..00000000000
--- a/config/feature_flags/development/rearrange_pipelines_table.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: rearrange_pipelines_table
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/72545
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/343286
-milestone: '14.8'
-type: development
-group: group::pipeline execution
-default_enabled: true
diff --git a/config/feature_flags/development/remove_import_data_on_failure.yml b/config/feature_flags/development/remove_import_data_on_failure.yml
index 5fa82eee981..341e027f28b 100644
--- a/config/feature_flags/development/remove_import_data_on_failure.yml
+++ b/config/feature_flags/development/remove_import_data_on_failure.yml
@@ -5,4 +5,4 @@ rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/352156
milestone: '14.8'
type: development
group: group::source code
-default_enabled: false
+default_enabled: true
diff --git a/config/feature_flags/development/rendered_diffs_viewer.yml b/config/feature_flags/development/rendered_diffs_viewer.yml
new file mode 100644
index 00000000000..e159b2656e1
--- /dev/null
+++ b/config/feature_flags/development/rendered_diffs_viewer.yml
@@ -0,0 +1,8 @@
+---
+name: rendered_diffs_viewer
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/75500
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/352831
+milestone: '14.9'
+type: development
+group: group::incubation
+default_enabled: false
diff --git a/config/feature_flags/development/roadmap_settings.yml b/config/feature_flags/development/roadmap_settings.yml
deleted file mode 100644
index 78704a90d06..00000000000
--- a/config/feature_flags/development/roadmap_settings.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: roadmap_settings
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/78626
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/350830
-milestone: '14.8'
-type: development
-group: group::product planning
-default_enabled: true
diff --git a/config/feature_flags/development/role_targeted_broadcast_messages.yml b/config/feature_flags/development/role_targeted_broadcast_messages.yml
new file mode 100644
index 00000000000..3de916d9e6d
--- /dev/null
+++ b/config/feature_flags/development/role_targeted_broadcast_messages.yml
@@ -0,0 +1,8 @@
+---
+name: role_targeted_broadcast_messages
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/81232
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/351736
+milestone: '14.9'
+type: development
+group: group::activation
+default_enabled: false
diff --git a/config/feature_flags/development/route_hll_to_snowplow.yml b/config/feature_flags/development/route_hll_to_snowplow.yml
new file mode 100644
index 00000000000..3c8f7826a0a
--- /dev/null
+++ b/config/feature_flags/development/route_hll_to_snowplow.yml
@@ -0,0 +1,8 @@
+---
+name: route_hll_to_snowplow
+introduced_by_url: https://gitlab.com/gitlab-org/product-intelligence/-/issues/498
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/354442
+milestone: '14.9'
+type: development
+group: group::product intelligence
+default_enabled: false
diff --git a/config/feature_flags/development/saved_replies.yml b/config/feature_flags/development/saved_replies.yml
new file mode 100644
index 00000000000..b6a7151addf
--- /dev/null
+++ b/config/feature_flags/development/saved_replies.yml
@@ -0,0 +1,8 @@
+---
+name: saved_replies
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/80811
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/352956
+milestone: '14.9'
+type: development
+group: group::project management
+default_enabled: false
diff --git a/config/feature_flags/development/secure_vulnerability_training.yml b/config/feature_flags/development/secure_vulnerability_training.yml
index 58117482e25..7dbc25f1ebf 100644
--- a/config/feature_flags/development/secure_vulnerability_training.yml
+++ b/config/feature_flags/development/secure_vulnerability_training.yml
@@ -5,4 +5,4 @@ rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/346308
milestone: '14.6'
type: development
group: group::threat insights
-default_enabled: false
+default_enabled: true
diff --git a/config/feature_flags/development/security_report_ingestion_framework.yml b/config/feature_flags/development/security_report_ingestion_framework.yml
deleted file mode 100644
index 6c146b7073d..00000000000
--- a/config/feature_flags/development/security_report_ingestion_framework.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: security_report_ingestion_framework
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/66735
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/343332
-milestone: '14.4'
-type: development
-group: group::threat insights
-default_enabled: true
diff --git a/config/feature_flags/development/show_report_validation_warnings.yml b/config/feature_flags/development/show_report_validation_warnings.yml
new file mode 100644
index 00000000000..551d432a928
--- /dev/null
+++ b/config/feature_flags/development/show_report_validation_warnings.yml
@@ -0,0 +1,8 @@
+---
+name: show_report_validation_warnings
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/80930
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/353125
+milestone: '14.9'
+type: development
+group: group::threat insights
+default_enabled: true
diff --git a/config/feature_flags/development/snippets_binary_blob.yml b/config/feature_flags/development/snippets_binary_blob.yml
deleted file mode 100644
index 72a959858d9..00000000000
--- a/config/feature_flags/development/snippets_binary_blob.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: snippets_binary_blob
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/37419
-rollout_issue_url:
-milestone: '13.3'
-type: development
-group: group::editor
-default_enabled: false
diff --git a/config/feature_flags/development/source_editor_toolbar.yml b/config/feature_flags/development/source_editor_toolbar.yml
new file mode 100644
index 00000000000..6fe2dd2d306
--- /dev/null
+++ b/config/feature_flags/development/source_editor_toolbar.yml
@@ -0,0 +1,8 @@
+---
+name: source_editor_toolbar
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/82304
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/354748
+milestone: '14.9'
+type: development
+group: group::editor
+default_enabled: false
diff --git a/config/feature_flags/development/spread_parallel_import.yml b/config/feature_flags/development/spread_parallel_import.yml
new file mode 100644
index 00000000000..1e75502e032
--- /dev/null
+++ b/config/feature_flags/development/spread_parallel_import.yml
@@ -0,0 +1,8 @@
+---
+name: spread_parallel_import
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/81026
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/353217
+milestone: '14.9'
+type: development
+group: group::source code
+default_enabled: true
diff --git a/config/feature_flags/development/strong_parameters_for_project_controller.yml b/config/feature_flags/development/strong_parameters_for_project_controller.yml
deleted file mode 100644
index 458bfc4c485..00000000000
--- a/config/feature_flags/development/strong_parameters_for_project_controller.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: strong_parameters_for_project_controller
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/79956
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/352251
-milestone: '14.8'
-type: development
-group: group::source code
-default_enabled: false
diff --git a/config/feature_flags/development/sync_traversal_ids_before_commit.yml b/config/feature_flags/development/sync_traversal_ids_before_commit.yml
deleted file mode 100644
index f8f1e854fa5..00000000000
--- a/config/feature_flags/development/sync_traversal_ids_before_commit.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: sync_traversal_ids_before_commit
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/79964
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/352499
-group: group::workspace
-type: development
-default_enabled: false
-milestone: '14.8'
diff --git a/config/feature_flags/development/track_error_tracking_activity.yml b/config/feature_flags/development/track_error_tracking_activity.yml
new file mode 100644
index 00000000000..c21a8d1aede
--- /dev/null
+++ b/config/feature_flags/development/track_error_tracking_activity.yml
@@ -0,0 +1,8 @@
+---
+name: track_error_tracking_activity
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/82543
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/355112
+milestone: '14.9'
+type: development
+group: group::respond
+default_enabled: false
diff --git a/config/feature_flags/development/track_file_size_over_highlight_limit.yml b/config/feature_flags/development/track_file_size_over_highlight_limit.yml
deleted file mode 100644
index 431c646f54d..00000000000
--- a/config/feature_flags/development/track_file_size_over_highlight_limit.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: track_file_size_over_highlight_limit
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/61273
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/330374
-milestone: '13.12'
-type: development
-group: group::code review
-default_enabled: false
diff --git a/config/feature_flags/development/track_highlight_timeouts.yml b/config/feature_flags/development/track_highlight_timeouts.yml
deleted file mode 100644
index a85749e5187..00000000000
--- a/config/feature_flags/development/track_highlight_timeouts.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: track_highlight_timeouts
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/60956
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/329909
-milestone: '13.12'
-type: development
-group: group::code review
-default_enabled: false
diff --git a/config/feature_flags/development/track_work_items_activity.yml b/config/feature_flags/development/track_work_items_activity.yml
new file mode 100644
index 00000000000..e4614f2d5e2
--- /dev/null
+++ b/config/feature_flags/development/track_work_items_activity.yml
@@ -0,0 +1,8 @@
+---
+name: track_work_items_activity
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/80532
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/352903
+milestone: '14.9'
+type: development
+group: group::project management
+default_enabled: false
diff --git a/config/feature_flags/development/ukraine_support_tanuki.yml b/config/feature_flags/development/ukraine_support_tanuki.yml
new file mode 100644
index 00000000000..3a2c64a5aa4
--- /dev/null
+++ b/config/feature_flags/development/ukraine_support_tanuki.yml
@@ -0,0 +1,8 @@
+---
+name: ukraine_support_tanuki
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/82050
+rollout_issue_url:
+milestone: '14.9'
+type: development
+group: group::editor
+default_enabled: false
diff --git a/config/feature_flags/development/update_all_mirrors_job_tracker.yml b/config/feature_flags/development/update_all_mirrors_job_tracker.yml
deleted file mode 100644
index 507f32550c3..00000000000
--- a/config/feature_flags/development/update_all_mirrors_job_tracker.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: update_all_mirrors_job_tracker
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/79097
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/351420
-milestone: '14.8'
-type: development
-group: group::scalability
-default_enabled: false
diff --git a/config/feature_flags/development/usage_data_i_snippets_show.yml b/config/feature_flags/development/usage_data_i_snippets_show.yml
deleted file mode 100644
index 446338d5b95..00000000000
--- a/config/feature_flags/development/usage_data_i_snippets_show.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: usage_data_i_snippets_show
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/48113
-rollout_issue_url:
-milestone: '13.7'
-type: development
-group: group::editor
-default_enabled: true
diff --git a/config/feature_flags/development/use_received_header_for_incoming_emails.yml b/config/feature_flags/development/use_received_header_for_incoming_emails.yml
new file mode 100644
index 00000000000..e466a266367
--- /dev/null
+++ b/config/feature_flags/development/use_received_header_for_incoming_emails.yml
@@ -0,0 +1,8 @@
+---
+name: use_received_header_for_incoming_emails
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/81489
+rollout_issue_url:
+milestone: '14.9'
+type: development
+group: group::certify
+default_enabled: true
diff --git a/config/feature_flags/development/verify_protected_tags_for_pull_mirror.yml b/config/feature_flags/development/verify_protected_tags_for_pull_mirror.yml
new file mode 100644
index 00000000000..44da565181f
--- /dev/null
+++ b/config/feature_flags/development/verify_protected_tags_for_pull_mirror.yml
@@ -0,0 +1,8 @@
+---
+name: verify_protected_tags_for_pull_mirror
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/80388
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/352494
+milestone: '14.9'
+type: development
+group: group::source code
+default_enabled: true
diff --git a/config/feature_flags/development/vsa_consistency_worker.yml b/config/feature_flags/development/vsa_consistency_worker.yml
new file mode 100644
index 00000000000..d880f38af69
--- /dev/null
+++ b/config/feature_flags/development/vsa_consistency_worker.yml
@@ -0,0 +1,8 @@
+---
+name: vsa_consistency_worker
+introduced_by_url:
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/355709
+milestone: '14.9'
+type: development
+group: group::optimize
+default_enabled: false
diff --git a/config/feature_flags/development/vsa_incremental_worker.yml b/config/feature_flags/development/vsa_incremental_worker.yml
new file mode 100644
index 00000000000..9caad7818e7
--- /dev/null
+++ b/config/feature_flags/development/vsa_incremental_worker.yml
@@ -0,0 +1,8 @@
+---
+name: vsa_incremental_worker
+introduced_by_url:
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/353453
+milestone: '14.9'
+type: development
+group: group::optimize
+default_enabled: true
diff --git a/config/feature_flags/development/vulnerability_finding_replace_metadata.yml b/config/feature_flags/development/vulnerability_finding_replace_metadata.yml
deleted file mode 100644
index 2774547668f..00000000000
--- a/config/feature_flags/development/vulnerability_finding_replace_metadata.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: vulnerability_finding_replace_metadata
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/66868
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/337253
-milestone: '14.2'
-group: group::threat insights
-type: development
-default_enabled: false
diff --git a/config/feature_flags/development/vulnerability_reads_table.yml b/config/feature_flags/development/vulnerability_reads_table.yml
new file mode 100644
index 00000000000..68e6ffead14
--- /dev/null
+++ b/config/feature_flags/development/vulnerability_reads_table.yml
@@ -0,0 +1,8 @@
+---
+name: vulnerability_reads_table
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/76220
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/348151
+milestone: '14.9'
+type: development
+group: group::threat insights
+default_enabled: false
diff --git a/config/feature_flags/development/web_ide_primary_edit.yml b/config/feature_flags/development/web_ide_primary_edit.yml
deleted file mode 100644
index 5a609ae1d88..00000000000
--- a/config/feature_flags/development/web_ide_primary_edit.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: web_ide_primary_edit
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/35957
-rollout_issue_url:
-milestone: '13.3'
-type: development
-group: group::editor
-default_enabled: false
diff --git a/config/feature_flags/development/wiki_front_matter.yml b/config/feature_flags/development/wiki_front_matter.yml
deleted file mode 100644
index 39196440d17..00000000000
--- a/config/feature_flags/development/wiki_front_matter.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: wiki_front_matter
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/27706
-rollout_issue_url:
-milestone: '12.10'
-type: development
-group: group::editor
-default_enabled: false
diff --git a/config/feature_flags/experiment/change_continuous_onboarding_link_urls.yml b/config/feature_flags/experiment/change_continuous_onboarding_link_urls.yml
deleted file mode 100644
index e65d7cd8d94..00000000000
--- a/config/feature_flags/experiment/change_continuous_onboarding_link_urls.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: change_continuous_onboarding_link_urls
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/71408
-rollout_issue_url:
-milestone: '14.5'
-type: experiment
-group: group::conversion
-default_enabled: false
diff --git a/config/feature_flags/experiment/ci_runner_templates.yml b/config/feature_flags/experiment/ci_runner_templates.yml
deleted file mode 100644
index e791581f67a..00000000000
--- a/config/feature_flags/experiment/ci_runner_templates.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: ci_runner_templates
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/58357
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/326725
-milestone: "14.0"
-type: experiment
-group: group::activation
-default_enabled: false
diff --git a/config/feature_flags/experiment/code_quality_walkthrough.yml b/config/feature_flags/experiment/code_quality_walkthrough.yml
deleted file mode 100644
index 572a0dc0a9f..00000000000
--- a/config/feature_flags/experiment/code_quality_walkthrough.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: code_quality_walkthrough
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/58900
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/327229
-milestone: "13.12"
-type: experiment
-group: group::activation
-default_enabled: false
diff --git a/config/feature_flags/experiment/confetti_post_signup.yml b/config/feature_flags/experiment/confetti_post_signup.yml
deleted file mode 100644
index 9f677bf252a..00000000000
--- a/config/feature_flags/experiment/confetti_post_signup.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: confetti_post_signup
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/70011
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/339890
-milestone: '14.5'
-type: experiment
-group: group::expansion
-default_enabled: false
diff --git a/config/feature_flags/experiment/pipeline_editor_walkthrough.yml b/config/feature_flags/experiment/pipeline_editor_walkthrough.yml
deleted file mode 100644
index 6d8895cbab7..00000000000
--- a/config/feature_flags/experiment/pipeline_editor_walkthrough.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: pipeline_editor_walkthrough
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/73050
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/345558
-milestone: '14.5'
-type: experiment
-group: group::activation
-default_enabled: false
diff --git a/config/feature_flags/experiment/runners_availability_section.yml b/config/feature_flags/experiment/runners_availability_section.yml
new file mode 100644
index 00000000000..41286c94e02
--- /dev/null
+++ b/config/feature_flags/experiment/runners_availability_section.yml
@@ -0,0 +1,8 @@
+---
+name: runners_availability_section
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/80717
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/352850
+milestone: '14.9'
+type: experiment
+group: group::activation
+default_enabled: false
diff --git a/config/feature_flags/ops/api_kaminari_count_with_limit.yml b/config/feature_flags/ops/api_kaminari_count_with_limit.yml
index a55e3e67710..c11c6758189 100644
--- a/config/feature_flags/ops/api_kaminari_count_with_limit.yml
+++ b/config/feature_flags/ops/api_kaminari_count_with_limit.yml
@@ -1,8 +1,8 @@
---
name: api_kaminari_count_with_limit
introduced_by_url: https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/23931
-rollout_issue_url:
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/353077
milestone: '11.8'
type: ops
group: group::integrations
-default_enabled: false
+default_enabled: true
diff --git a/config/feature_flags/ops/certificate_based_clusters.yml b/config/feature_flags/ops/certificate_based_clusters.yml
new file mode 100644
index 00000000000..eaf4151b80a
--- /dev/null
+++ b/config/feature_flags/ops/certificate_based_clusters.yml
@@ -0,0 +1,8 @@
+---
+name: certificate_based_clusters
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/81054
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/353410
+milestone: '14.9'
+type: ops
+group: group::configure
+default_enabled: true
diff --git a/config/feature_flags/ops/deprecated_serverless.yml b/config/feature_flags/ops/deprecated_serverless.yml
new file mode 100644
index 00000000000..0982778f139
--- /dev/null
+++ b/config/feature_flags/ops/deprecated_serverless.yml
@@ -0,0 +1,8 @@
+---
+name: deprecated_serverless
+introduced_by_url: 'https://gitlab.com/gitlab-org/gitlab/-/merge_requests/81493'
+rollout_issue_url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/353901'
+milestone: '14.9'
+type: ops
+group: 'group::configure'
+default_enabled: true
diff --git a/config/feature_flags/ops/gitlab_experiment.yml b/config/feature_flags/ops/gitlab_experiment.yml
new file mode 100644
index 00000000000..bd676fc7c9c
--- /dev/null
+++ b/config/feature_flags/ops/gitlab_experiment.yml
@@ -0,0 +1,8 @@
+---
+name: gitlab_experiment
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/81834
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/353921
+milestone: '14.9'
+type: ops
+group: group::conversion
+default_enabled: true
diff --git a/config/feature_flags/ops/purge_stale_security_findings.yml b/config/feature_flags/ops/purge_stale_security_findings.yml
new file mode 100644
index 00000000000..322f31b62ce
--- /dev/null
+++ b/config/feature_flags/ops/purge_stale_security_findings.yml
@@ -0,0 +1,8 @@
+---
+name: purge_stale_security_findings
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/81423
+rollout_issue_url:
+milestone: '14.9'
+type: ops
+group: group::threat insights
+default_enabled: false
diff --git a/config/gitlab.yml.example b/config/gitlab.yml.example
index 6758afc91c4..88af8cc12aa 100644
--- a/config/gitlab.yml.example
+++ b/config/gitlab.yml.example
@@ -185,7 +185,7 @@ production: &base
## Reply by email
# Allow users to comment on issues and merge requests by replying to notification emails.
- # For documentation on how to set this up, see http://doc.gitlab.com/ce/administration/reply_by_email.html
+ # For documentation on how to set this up, see https://docs.gitlab.com/ee/administration/reply_by_email.html
incoming_email:
enabled: false
@@ -230,7 +230,23 @@ production: &base
# client_id: "YOUR-CLIENT-ID"
# client_secret: "YOUR-CLIENT-SECRET"
- # File that contains the shared secret key for verifying access for mailroom's incoming_email.
+ # How mailroom delivers email content to Rails. There are two methods at the moment:
+ # - sidekiq: mailroom pushes the email content to Sidekiq directly. This job
+ # is then picked up by Sidekiq.
+ # - webhook: mailroom triggers a HTTP POST request to Rails web server. The
+ # content is embedded into the request body.
+ # Default is sidekiq.
+ # delivery_method: sidekiq
+
+ # When the delivery method is webhook, those configs tell the url that
+ # mailroom can contact to. Note that the combined url must not end with "/".
+ # At the moment, the webhook delivery method doesn't support HTTP/HTTPs via
+ # UNIX socket.
+ # gitlab_url: "http://gitlab.example"
+
+ # When the delivery method is webhook, this config is the file that
+ # contains the shared secret key for verifying access for mailroom's
+ # incoming_email.
# Default is '.gitlab_mailroom_secret' relative to Rails.root (i.e. root of the GitLab app).
# secret_file: /home/git/gitlab/.gitlab_mailroom_secret
diff --git a/config/gitlab_loose_foreign_keys.yml b/config/gitlab_loose_foreign_keys.yml
index f46e005dacf..7f9539c3604 100644
--- a/config/gitlab_loose_foreign_keys.yml
+++ b/config/gitlab_loose_foreign_keys.yml
@@ -78,9 +78,6 @@ ci_pipelines:
- table: merge_requests
column: merge_request_id
on_delete: async_delete
- - table: external_pull_requests
- column: external_pull_request_id
- on_delete: async_nullify
- table: users
column: user_id
on_delete: async_nullify
diff --git a/config/helpers/incremental_webpack_compiler/compiler.js b/config/helpers/incremental_webpack_compiler/compiler.js
index 0ef090bce24..2614501faa4 100644
--- a/config/helpers/incremental_webpack_compiler/compiler.js
+++ b/config/helpers/incremental_webpack_compiler/compiler.js
@@ -102,7 +102,7 @@ class IncrementalWebpackCompiler {
setTimeout(() => {
devServer.invalidate(() => {
- if (devServer.sockets) {
+ if (Array.isArray(devServer.webSocketServer && devServer.webSocketServer.clients)) {
devServer.sendMessage(devServer.webSocketServer.clients, 'static-changed');
}
});
diff --git a/config/initializers/01_active_record_database_tasks_configuration_flag.rb b/config/initializers/01_active_record_database_tasks_configuration_flag.rb
new file mode 100644
index 00000000000..37374a41a30
--- /dev/null
+++ b/config/initializers/01_active_record_database_tasks_configuration_flag.rb
@@ -0,0 +1,37 @@
+# frozen_string_literal: true
+
+if Rails::VERSION::MAJOR >= 7
+ raise "Remove `#{__FILE__}`. This is backport of `database_tasks:` Rails 7.x feature."
+end
+
+# This backports `database_tasks:` feature to skip running migrations for some databases
+# PR: https://github.com/rails/rails/pull/42794/files
+
+module DatabaseTasks
+ module ActiveRecordDatabaseConfigurations
+ def configs_for(env_name: nil, name: nil, include_replicas: false)
+ configs = super
+
+ unless include_replicas
+ if name
+ configs = nil unless configs&.database_tasks?
+ else
+ configs = configs.select do |db_config|
+ db_config.database_tasks?
+ end
+ end
+ end
+
+ configs
+ end
+ end
+
+ module ActiveRecordDatabaseConfigurationsHashConfig
+ def database_tasks? # :nodoc:
+ !replica? && !!configuration_hash.fetch(:database_tasks, true)
+ end
+ end
+end
+
+ActiveRecord::DatabaseConfigurations.prepend(DatabaseTasks::ActiveRecordDatabaseConfigurations)
+ActiveRecord::DatabaseConfigurations::HashConfig.prepend(DatabaseTasks::ActiveRecordDatabaseConfigurationsHashConfig)
diff --git a/config/initializers/1_settings.rb b/config/initializers/1_settings.rb
index 07d6e8e4882..25d142566f0 100644
--- a/config/initializers/1_settings.rb
+++ b/config/initializers/1_settings.rb
@@ -611,28 +611,40 @@ Settings.cron_jobs['ci_delete_unit_tests_worker']['job_class'] = 'Ci::DeleteUnit
Settings.cron_jobs['batched_background_migrations_worker'] ||= Settingslogic.new({})
Settings.cron_jobs['batched_background_migrations_worker']['cron'] ||= '* * * * *'
Settings.cron_jobs['batched_background_migrations_worker']['job_class'] = 'Database::BatchedBackgroundMigrationWorker'
+Settings.cron_jobs['batched_background_migration_worker_ci_database'] ||= Settingslogic.new({})
+Settings.cron_jobs['batched_background_migration_worker_ci_database']['cron'] ||= '* * * * *'
+Settings.cron_jobs['batched_background_migration_worker_ci_database']['job_class'] = 'Database::BatchedBackgroundMigration::CiDatabaseWorker'
Settings.cron_jobs['issues_reschedule_stuck_issue_rebalances'] ||= Settingslogic.new({})
Settings.cron_jobs['issues_reschedule_stuck_issue_rebalances']['cron'] ||= '*/15 * * * *'
Settings.cron_jobs['issues_reschedule_stuck_issue_rebalances']['job_class'] = 'Issues::RescheduleStuckIssueRebalancesWorker'
Settings.cron_jobs['clusters_integrations_check_prometheus_health_worker'] ||= Settingslogic.new({})
Settings.cron_jobs['clusters_integrations_check_prometheus_health_worker']['cron'] ||= '0 * * * *'
Settings.cron_jobs['clusters_integrations_check_prometheus_health_worker']['job_class'] = 'Clusters::Integrations::CheckPrometheusHealthWorker'
+Settings.cron_jobs['projects_schedule_refresh_build_artifacts_size_statistics_worker'] ||= Settingslogic.new({})
+Settings.cron_jobs['projects_schedule_refresh_build_artifacts_size_statistics_worker']['cron'] ||= '2/17 * * * *'
+Settings.cron_jobs['projects_schedule_refresh_build_artifacts_size_statistics_worker']['job_class'] = 'Projects::ScheduleRefreshBuildArtifactsSizeStatisticsWorker'
Gitlab.ee do
Settings.cron_jobs['analytics_devops_adoption_create_all_snapshots_worker'] ||= Settingslogic.new({})
Settings.cron_jobs['analytics_devops_adoption_create_all_snapshots_worker']['cron'] ||= '0 1 * * *'
Settings.cron_jobs['analytics_devops_adoption_create_all_snapshots_worker']['job_class'] = 'Analytics::DevopsAdoption::CreateAllSnapshotsWorker'
+ Settings.cron_jobs['analytics_cycle_analytics_incremental_worker'] ||= Settingslogic.new({})
+ Settings.cron_jobs['analytics_cycle_analytics_incremental_worker']['cron'] ||= '*/10 * * * *'
+ Settings.cron_jobs['analytics_cycle_analytics_incremental_worker']['job_class'] = 'Analytics::CycleAnalytics::IncrementalWorker'
+ Settings.cron_jobs['analytics_cycle_analytics_consistency_worker'] ||= Settingslogic.new({})
+ Settings.cron_jobs['analytics_cycle_analytics_consistency_worker']['cron'] ||= '*/30 * * * *'
+ Settings.cron_jobs['analytics_cycle_analytics_consistency_worker']['job_class'] = 'Analytics::CycleAnalytics::ConsistencyWorker'
Settings.cron_jobs['active_user_count_threshold_worker'] ||= Settingslogic.new({})
Settings.cron_jobs['active_user_count_threshold_worker']['cron'] ||= '0 12 * * *'
Settings.cron_jobs['active_user_count_threshold_worker']['job_class'] = 'ActiveUserCountThresholdWorker'
Settings.cron_jobs['adjourned_group_deletion_worker'] ||= Settingslogic.new({})
- Settings.cron_jobs['adjourned_group_deletion_worker']['cron'] ||= '0 3 * * *'
+ Settings.cron_jobs['adjourned_group_deletion_worker']['cron'] ||= '0 2 * * *'
Settings.cron_jobs['adjourned_group_deletion_worker']['job_class'] = 'AdjournedGroupDeletionWorker'
Settings.cron_jobs['clear_shared_runners_minutes_worker'] ||= Settingslogic.new({})
Settings.cron_jobs['clear_shared_runners_minutes_worker']['cron'] ||= '0 0 1 * *'
Settings.cron_jobs['clear_shared_runners_minutes_worker']['job_class'] = 'ClearSharedRunnersMinutesWorker'
Settings.cron_jobs['adjourned_projects_deletion_cron_worker'] ||= Settingslogic.new({})
- Settings.cron_jobs['adjourned_projects_deletion_cron_worker']['cron'] ||= '0 4 * * *'
+ Settings.cron_jobs['adjourned_projects_deletion_cron_worker']['cron'] ||= '0 7 * * *'
Settings.cron_jobs['adjourned_projects_deletion_cron_worker']['job_class'] = 'AdjournedProjectsDeletionCronWorker'
Settings.cron_jobs['geo_verification_cron_worker'] ||= Settingslogic.new({})
Settings.cron_jobs['geo_verification_cron_worker']['cron'] ||= '* * * * *'
@@ -739,6 +751,9 @@ Gitlab.ee do
Settings.cron_jobs['security_orchestration_policy_rule_schedule_worker'] ||= Settingslogic.new({})
Settings.cron_jobs['security_orchestration_policy_rule_schedule_worker']['cron'] ||= '*/15 * * * *'
Settings.cron_jobs['security_orchestration_policy_rule_schedule_worker']['job_class'] = 'Security::OrchestrationPolicyRuleScheduleWorker'
+ Settings.cron_jobs['security_findings_cleanup_worker'] ||= Settingslogic.new({})
+ Settings.cron_jobs['security_findings_cleanup_worker']['cron'] ||= '0 */4 * * 6,0'
+ Settings.cron_jobs['security_findings_cleanup_worker']['job_class'] = 'Security::Findings::CleanupWorker'
Settings.cron_jobs['app_sec_dast_profile_schedule_worker'] ||= Settingslogic.new({})
Settings.cron_jobs['app_sec_dast_profile_schedule_worker']['cron'] ||= '7-59/15 * * * *'
Settings.cron_jobs['app_sec_dast_profile_schedule_worker']['job_class'] = 'AppSec::Dast::ProfileScheduleWorker'
diff --git a/config/initializers/7_prometheus_metrics.rb b/config/initializers/7_prometheus_metrics.rb
index c55b074f9c8..e4d47d53815 100644
--- a/config/initializers/7_prometheus_metrics.rb
+++ b/config/initializers/7_prometheus_metrics.rb
@@ -1,5 +1,8 @@
# frozen_string_literal: true
+PUMA_EXTERNAL_METRICS_SERVER = Gitlab::Utils.to_boolean(ENV['PUMA_EXTERNAL_METRICS_SERVER'])
+require Rails.root.join('metrics_server', 'metrics_server') if PUMA_EXTERNAL_METRICS_SERVER
+
# Keep separate directories for separate processes
def prometheus_default_multiproc_dir
return unless Rails.env.development? || Rails.env.test?
@@ -34,8 +37,6 @@ end
::Prometheus::Client.configure do |config|
config.logger = Gitlab::AppLogger
- config.initial_mmap_file_size = 4 * 1024
-
config.multiprocess_files_dir = ENV['prometheus_multiproc_dir'] || prometheus_default_multiproc_dir
config.pid_provider = ::Prometheus::PidProvider.method(:worker_id)
@@ -46,6 +47,10 @@ Gitlab::Application.configure do |config|
config.middleware.insert_after(Labkit::Middleware::Rack, Gitlab::Metrics::RequestsRackMiddleware)
end
+# Any actions beyond this check should only execute outside of tests, when running in an application
+# context (i.e. not in the Rails console or rspec) and when users have enabled metrics.
+return if Rails.env.test? || !Gitlab::Runtime.application? || !Gitlab::Metrics.prometheus_metrics_enabled?
+
if Gitlab::Runtime.sidekiq? && (!ENV['SIDEKIQ_WORKER_ID'] || ENV['SIDEKIQ_WORKER_ID'] == '0')
# The single worker outside of a sidekiq-cluster, or the first worker (sidekiq_0)
# in a cluster of processes, is responsible for serving health checks.
@@ -64,67 +69,75 @@ if Gitlab::Runtime.sidekiq? && (!ENV['SIDEKIQ_WORKER_ID'] || ENV['SIDEKIQ_WORKER
end
end
-if !Rails.env.test? && Gitlab::Metrics.prometheus_metrics_enabled?
- Gitlab::Cluster::LifecycleEvents.on_master_start do
- if Gitlab::Runtime.puma?
- Gitlab::Metrics::Samplers::PumaSampler.instance.start
- end
+Gitlab::Cluster::LifecycleEvents.on_master_start do
+ Gitlab::Metrics.gauge(:deployments, 'GitLab Version', {}, :max).set({ version: Gitlab::VERSION, revision: Gitlab.revision }, 1)
- Gitlab::Metrics.gauge(:deployments, 'GitLab Version', {}, :max).set({ version: Gitlab::VERSION, revision: Gitlab.revision }, 1)
+ if Gitlab::Runtime.puma?
+ Gitlab::Metrics::Samplers::PumaSampler.instance.start
- Gitlab::Ci::Parsers.instrument!
- rescue IOError => e
- Gitlab::ErrorTracking.track_exception(e)
- Gitlab::Metrics.error_detected!
+ if PUMA_EXTERNAL_METRICS_SERVER && Settings.monitoring.web_exporter.enabled
+ MetricsServer.start_for_puma
+ else
+ Gitlab::Metrics::Exporter::WebExporter.instance.start
+ end
end
- Gitlab::Cluster::LifecycleEvents.on_worker_start do
- defined?(::Prometheus::Client.reinitialize_on_pid_change) && ::Prometheus::Client.reinitialize_on_pid_change
- logger = Gitlab::AppLogger
- Gitlab::Metrics::Samplers::RubySampler.initialize_instance(logger: logger).start
- Gitlab::Metrics::Samplers::DatabaseSampler.initialize_instance(logger: logger).start
- Gitlab::Metrics::Samplers::ThreadsSampler.initialize_instance(logger: logger).start
-
- if Gitlab::Runtime.web_server?
- Gitlab::Metrics::Samplers::ActionCableSampler.instance(logger: logger).start
- end
+ Gitlab::Ci::Parsers.instrument!
+rescue IOError => e
+ Gitlab::ErrorTracking.track_exception(e)
+ Gitlab::Metrics.error_detected!
+end
- if Gitlab.ee? && Gitlab::Runtime.sidekiq?
- Gitlab::Metrics::Samplers::GlobalSearchSampler.instance(logger: logger).start
+Gitlab::Cluster::LifecycleEvents.on_worker_start do
+ defined?(::Prometheus::Client.reinitialize_on_pid_change) && ::Prometheus::Client.reinitialize_on_pid_change
+ logger = Gitlab::AppLogger
+ Gitlab::Metrics::Samplers::RubySampler.initialize_instance(logger: logger).start
+ Gitlab::Metrics::Samplers::DatabaseSampler.initialize_instance(logger: logger).start
+ Gitlab::Metrics::Samplers::ThreadsSampler.initialize_instance(logger: logger).start
+
+ if Gitlab::Runtime.puma?
+ # Since we are observing a metrics server from the Puma primary, we would inherit
+ # this supervision thread after forking into workers, so we need to explicitly stop it here.
+ if PUMA_EXTERNAL_METRICS_SERVER
+ ::MetricsServer::PumaProcessSupervisor.instance.stop
+ else
+ Gitlab::Metrics::Exporter::WebExporter.instance.stop
end
- Gitlab::Ci::Parsers.instrument!
- rescue IOError => e
- Gitlab::ErrorTracking.track_exception(e)
- Gitlab::Metrics.error_detected!
+ Gitlab::Metrics::Samplers::ActionCableSampler.instance(logger: logger).start
end
-end
-if Gitlab::Runtime.web_server?
- Gitlab::Cluster::LifecycleEvents.on_master_start do
- Gitlab::Metrics::Exporter::WebExporter.instance.start
+ if Gitlab.ee? && Gitlab::Runtime.sidekiq?
+ Gitlab::Metrics::Samplers::GlobalSearchSampler.instance(logger: logger).start
end
+ Gitlab::Ci::Parsers.instrument!
+rescue IOError => e
+ Gitlab::ErrorTracking.track_exception(e)
+ Gitlab::Metrics.error_detected!
+end
+
+if Gitlab::Runtime.puma?
Gitlab::Cluster::LifecycleEvents.on_before_graceful_shutdown do
# We need to ensure that before we re-exec or shutdown server
- # we do stop the exporter
- Gitlab::Metrics::Exporter::WebExporter.instance.stop
+ # we also stop the metrics server
+ if PUMA_EXTERNAL_METRICS_SERVER
+ ::MetricsServer::PumaProcessSupervisor.instance.shutdown
+ else
+ Gitlab::Metrics::Exporter::WebExporter.instance.stop
+ end
end
Gitlab::Cluster::LifecycleEvents.on_before_master_restart do
# We need to ensure that before we re-exec server
- # we do stop the exporter
+ # we also stop the metrics server
#
# We do it again, for being extra safe,
# but it should not be needed
- Gitlab::Metrics::Exporter::WebExporter.instance.stop
- end
-
- Gitlab::Cluster::LifecycleEvents.on_worker_start do
- # The `#close_on_exec=` takes effect only on `execve`
- # but this does not happen for Ruby fork
- #
- # This does stop server, as it is running on master.
- Gitlab::Metrics::Exporter::WebExporter.instance.stop
+ if PUMA_EXTERNAL_METRICS_SERVER
+ ::MetricsServer::PumaProcessSupervisor.instance.shutdown
+ else
+ Gitlab::Metrics::Exporter::WebExporter.instance.stop
+ end
end
end
diff --git a/config/initializers/action_cable.rb b/config/initializers/action_cable.rb
index 0d2073586be..3f9ceb7cfa7 100644
--- a/config/initializers/action_cable.rb
+++ b/config/initializers/action_cable.rb
@@ -10,6 +10,7 @@ Rails.application.configure do
end
ActionCable::SubscriptionAdapter::Base.prepend(Gitlab::Patch::ActionCableSubscriptionAdapterIdentifier)
+ActionCable::SubscriptionAdapter::Redis::Listener.prepend(Gitlab::Patch::ActionCableRedisListener)
# https://github.com/rails/rails/blob/bb5ac1623e8de08c1b7b62b1368758f0d3bb6379/actioncable/lib/action_cable/subscription_adapter/redis.rb#L18
ActionCable::SubscriptionAdapter::Redis.redis_connector = lambda do |config|
diff --git a/config/initializers/database_query_analyzers.rb b/config/initializers/database_query_analyzers.rb
index 8a2fe1d8388..d1010e054af 100644
--- a/config/initializers/database_query_analyzers.rb
+++ b/config/initializers/database_query_analyzers.rb
@@ -1,15 +1,13 @@
# frozen_string_literal: true
# Currently we register validator only for `dev` or `test` environment
-if Gitlab.dev_or_test_env? || Gitlab::Utils.to_boolean(ENV['GITLAB_ENABLE_QUERY_ANALYZERS'], default: false)
- Gitlab::Database::QueryAnalyzer.instance.hook!
- Gitlab::Database::QueryAnalyzer.instance.all_analyzers.append(::Gitlab::Database::QueryAnalyzers::GitlabSchemasMetrics)
+Gitlab::Database::QueryAnalyzer.instance.hook!
+Gitlab::Database::QueryAnalyzer.instance.all_analyzers.append(::Gitlab::Database::QueryAnalyzers::GitlabSchemasMetrics)
- if Rails.env.test? || Gitlab::Utils.to_boolean(ENV['ENABLE_CROSS_DATABASE_MODIFICATION_DETECTION'], default: false)
- Gitlab::Database::QueryAnalyzer.instance.all_analyzers.append(::Gitlab::Database::QueryAnalyzers::PreventCrossDatabaseModification)
- end
+if Rails.env.test? || Gitlab::Utils.to_boolean(ENV['ENABLE_CROSS_DATABASE_MODIFICATION_DETECTION'], default: false)
+ Gitlab::Database::QueryAnalyzer.instance.all_analyzers.append(::Gitlab::Database::QueryAnalyzers::PreventCrossDatabaseModification)
+end
- Gitlab::Application.configure do |config|
- config.middleware.use(Gitlab::Middleware::QueryAnalyzer)
- end
+Gitlab::Application.configure do |config|
+ config.middleware.use(Gitlab::Middleware::QueryAnalyzer)
end
diff --git a/config/initializers/gitlab_experiment.rb b/config/initializers/gitlab_experiment.rb
index fdb21d90c28..9a6ef325c9e 100644
--- a/config/initializers/gitlab_experiment.rb
+++ b/config/initializers/gitlab_experiment.rb
@@ -49,7 +49,7 @@ Gitlab::Experiment.configure do |config|
#
valid_domains = %w[about.gitlab.com docs.gitlab.com gitlab.com gdk.test localhost]
config.redirect_url_validator = lambda do |url|
- Gitlab.dev_env_or_com? && (url = URI.parse(url)) && valid_domains.include?(url.host)
+ Gitlab.com? && (url = URI.parse(url)) && valid_domains.include?(url.host)
rescue URI::InvalidURIError
false
end
diff --git a/config/initializers/http_hostname_override.rb b/config/initializers/http_hostname_override.rb
index 5d2739c1f58..3d840cd3251 100644
--- a/config/initializers/http_hostname_override.rb
+++ b/config/initializers/http_hostname_override.rb
@@ -34,6 +34,7 @@ end
class Net::HTTP
attr_accessor :hostname_override
+
SSL_IVNAMES << :@hostname_override
SSL_ATTRIBUTES << :hostname_override
diff --git a/config/initializers/rails_host_authorization.rb b/config/initializers/rails_host_authorization.rb
index 22bb6fb7061..6fe4679433c 100644
--- a/config/initializers/rails_host_authorization.rb
+++ b/config/initializers/rails_host_authorization.rb
@@ -8,7 +8,7 @@ if Gitlab.config.gitlab.allowed_hosts.present?
end
if Rails.env.development?
- Rails.application.config.hosts += [Gitlab.config.gitlab.host, 'unix', 'host.docker.internal']
+ Rails.application.config.hosts += [Gitlab.config.gitlab.host, 'unix', 'host.docker.internal', 'docker.for.mac.localhost']
if ENV['RAILS_HOSTS']
additional_hosts = ENV['RAILS_HOSTS'].split(',').select(&:presence)
diff --git a/config/initializers/sidekiq.rb b/config/initializers/sidekiq.rb
index baf252a5d10..25984c45318 100644
--- a/config/initializers/sidekiq.rb
+++ b/config/initializers/sidekiq.rb
@@ -30,8 +30,6 @@ Sidekiq.configure_server do |config|
config.options[:strict] = false
config.options[:queues] = Gitlab::SidekiqConfig.expand_queues(config.options[:queues])
- Sidekiq.logger.info "Listening on queues #{config.options[:queues].uniq.sort}"
-
if enable_json_logs
config.log_formatter = Gitlab::SidekiqLogging::JSONFormatter.new
config.options[:job_logger] = Gitlab::SidekiqLogging::StructuredLogger
@@ -41,6 +39,8 @@ Sidekiq.configure_server do |config|
config.error_handlers.reject! { |handler| handler.is_a?(Sidekiq::ExceptionHandler::Logger) }
end
+ Sidekiq.logger.info "Listening on queues #{config.options[:queues].uniq.sort}"
+
config.redis = queues_config_hash
config.server_middleware(&Gitlab::SidekiqMiddleware.server_configurator(
diff --git a/config/initializers_before_autoloader/000_inflections.rb b/config/initializers_before_autoloader/000_inflections.rb
index 876ae5da230..64686bdd962 100644
--- a/config/initializers_before_autoloader/000_inflections.rb
+++ b/config/initializers_before_autoloader/000_inflections.rb
@@ -40,4 +40,5 @@ ActiveSupport::Inflector.inflections do |inflect|
inflect.acronym 'JH'
inflect.acronym 'CSP'
inflect.acronym 'VSCode'
+ inflect.acronym 'FIPS'
end
diff --git a/config/mail_room.yml b/config/mail_room.yml
index 669925c2390..49cb765ebe6 100644
--- a/config/mail_room.yml
+++ b/config/mail_room.yml
@@ -1,7 +1,7 @@
:mailboxes:
<%
require_relative "../lib/gitlab/mail_room" unless defined?(Gitlab::MailRoom)
- Gitlab::MailRoom.enabled_configs.each do |_key, config|
+ Gitlab::MailRoom.enabled_configs.each do |key, config|
%>
-
:host: <%= config[:host].to_json %>
@@ -26,6 +26,7 @@
<%= config.slice(:inbox_options).to_yaml(indentation: 8).gsub(/^---\n/, '') %>
<% end %>
+ <% if config[:delivery_method] == Gitlab::MailRoom::DELIVERY_METHOD_SIDEKIQ %>
:delivery_method: sidekiq
:delivery_options:
:redis_url: <%= config[:redis_url].to_json %>
@@ -41,6 +42,15 @@
:port: <%= sentinel[:port] %>
<% end %>
<% end %>
+ <% elsif config[:delivery_method] == Gitlab::MailRoom::DELIVERY_METHOD_WEBHOOK %>
+ :delivery_method: postback
+ :delivery_options:
+ :delivery_url: <%= config[:gitlab_url] %>/api/v4/internal/mail_room/<%= key %>
+ :jwt_auth_header: <%= Gitlab::MailRoom::INTERNAL_API_REQUEST_HEADER %>
+ :jwt_issuer: <%= Gitlab::MailRoom::INTERNAL_API_REQUEST_JWT_ISSUER %>
+ :jwt_algorithm: "HS256"
+ :jwt_secret_path: <%= config[:secret_file] %>
+ <% end %>
:arbitration_method: redis
:arbitration_options:
diff --git a/config/metrics/aggregates/common.yml b/config/metrics/aggregates/common.yml
index 50d5122e806..0a9aec02b1a 100644
--- a/config/metrics/aggregates/common.yml
+++ b/config/metrics/aggregates/common.yml
@@ -62,3 +62,27 @@
- 'i_testing_group_code_coverage_visit_total'
- 'i_testing_load_performance_widget_total'
- 'i_testing_metrics_report_widget_total'
+- name: xmau_plan
+ operator: OR
+ source: redis
+ time_frame: [7d, 28d]
+ events:
+ - users_creating_work_items
+ - users_updating_work_item_title
+ feature_flag: track_work_items_activity
+- name: xmau_project_management
+ operator: OR
+ source: redis
+ time_frame: [7d, 28d]
+ events:
+ - users_creating_work_items
+ - users_updating_work_item_title
+ feature_flag: track_work_items_activity
+- name: users_work_items
+ operator: OR
+ source: redis
+ time_frame: [7d, 28d]
+ events:
+ - users_creating_work_items
+ - users_updating_work_item_title
+ feature_flag: track_work_items_activity
diff --git a/config/metrics/counts_28d/20210216175542_ci_builds.yml b/config/metrics/counts_28d/20210216175542_ci_builds.yml
index 0c1523797c0..8664ee1bcc9 100644
--- a/config/metrics/counts_28d/20210216175542_ci_builds.yml
+++ b/config/metrics/counts_28d/20210216175542_ci_builds.yml
@@ -18,4 +18,5 @@ tier:
- premium
- ultimate
performance_indicator_type: []
-milestone: "<13.9"
+milestone: "12.9"
+introduced_by_url: "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/26441"
diff --git a/config/metrics/counts_28d/20210216175544_ci_external_pipelines.yml b/config/metrics/counts_28d/20210216175544_ci_external_pipelines.yml
index b13560ede4c..d21d70c8abb 100644
--- a/config/metrics/counts_28d/20210216175544_ci_external_pipelines.yml
+++ b/config/metrics/counts_28d/20210216175544_ci_external_pipelines.yml
@@ -18,4 +18,5 @@ tier:
- premium
- ultimate
performance_indicator_type: []
-milestone: "<13.9"
+milestone: "12.9"
+introduced_by_url: "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/26441"
diff --git a/config/metrics/counts_28d/20210216175546_ci_internal_pipelines.yml b/config/metrics/counts_28d/20210216175546_ci_internal_pipelines.yml
index 4d9b6b2cd9c..47bf8c9c821 100644
--- a/config/metrics/counts_28d/20210216175546_ci_internal_pipelines.yml
+++ b/config/metrics/counts_28d/20210216175546_ci_internal_pipelines.yml
@@ -18,4 +18,5 @@ tier:
- premium
- ultimate
performance_indicator_type: []
-milestone: "<13.9"
+milestone: "12.9"
+introduced_by_url: "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/26441"
diff --git a/config/metrics/counts_28d/20210216175548_ci_pipeline_config_auto_devops.yml b/config/metrics/counts_28d/20210216175548_ci_pipeline_config_auto_devops.yml
index 5c4f21f3b3c..fe7fcb65895 100644
--- a/config/metrics/counts_28d/20210216175548_ci_pipeline_config_auto_devops.yml
+++ b/config/metrics/counts_28d/20210216175548_ci_pipeline_config_auto_devops.yml
@@ -18,4 +18,5 @@ tier:
- premium
- ultimate
performance_indicator_type: []
-milestone: "<13.9"
+milestone: "12.9"
+introduced_by_url: "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/26441"
diff --git a/config/metrics/counts_28d/20210216175550_ci_pipeline_config_repository.yml b/config/metrics/counts_28d/20210216175550_ci_pipeline_config_repository.yml
index d27548980b0..9d12339717d 100644
--- a/config/metrics/counts_28d/20210216175550_ci_pipeline_config_repository.yml
+++ b/config/metrics/counts_28d/20210216175550_ci_pipeline_config_repository.yml
@@ -18,4 +18,5 @@ tier:
- premium
- ultimate
performance_indicator_type: []
-milestone: "<13.9"
+milestone: "12.9"
+introduced_by_url: "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/26441"
diff --git a/config/metrics/counts_28d/20210216175552_ci_pipeline_schedules.yml b/config/metrics/counts_28d/20210216175552_ci_pipeline_schedules.yml
index 75129e5d824..bfc39e672ca 100644
--- a/config/metrics/counts_28d/20210216175552_ci_pipeline_schedules.yml
+++ b/config/metrics/counts_28d/20210216175552_ci_pipeline_schedules.yml
@@ -18,4 +18,5 @@ tier:
- premium
- ultimate
performance_indicator_type: []
-milestone: "<13.9"
+milestone: "12.9"
+introduced_by_url: "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/26441"
diff --git a/config/metrics/counts_28d/20210216175554_ci_pipelines.yml b/config/metrics/counts_28d/20210216175554_ci_pipelines.yml
index ee32c2baed9..3c0c401f38b 100644
--- a/config/metrics/counts_28d/20210216175554_ci_pipelines.yml
+++ b/config/metrics/counts_28d/20210216175554_ci_pipelines.yml
@@ -22,4 +22,5 @@ performance_indicator_type:
- smau
- gmau
- paid_gmau
-milestone: "<13.9"
+milestone: "12.9"
+introduced_by_url: "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/26441"
diff --git a/config/metrics/counts_28d/20210216175556_ci_triggers.yml b/config/metrics/counts_28d/20210216175556_ci_triggers.yml
index 80842966536..c70a9337c6c 100644
--- a/config/metrics/counts_28d/20210216175556_ci_triggers.yml
+++ b/config/metrics/counts_28d/20210216175556_ci_triggers.yml
@@ -18,4 +18,5 @@ tier:
- premium
- ultimate
performance_indicator_type: []
-milestone: "<13.9"
+milestone: "12.9"
+introduced_by_url: "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/26441"
diff --git a/config/metrics/counts_28d/20210216181937_failed_deployments.yml b/config/metrics/counts_28d/20210216181937_failed_deployments.yml
index 9ef4157ce2d..78622151915 100644
--- a/config/metrics/counts_28d/20210216181937_failed_deployments.yml
+++ b/config/metrics/counts_28d/20210216181937_failed_deployments.yml
@@ -1,7 +1,7 @@
---
data_category: optional
key_path: usage_activity_by_stage_monthly.release.failed_deployments
-description: Total failed deployments
+description: Disinct users who initiated a failed deployment.
product_section: ops
product_stage: release
product_group: group::release
diff --git a/config/metrics/counts_28d/20210216181941_successful_deployments.yml b/config/metrics/counts_28d/20210216181941_successful_deployments.yml
index f21cb609208..10c9de1817f 100644
--- a/config/metrics/counts_28d/20210216181941_successful_deployments.yml
+++ b/config/metrics/counts_28d/20210216181941_successful_deployments.yml
@@ -1,7 +1,7 @@
---
data_category: optional
key_path: usage_activity_by_stage_monthly.release.successful_deployments
-description: Total successful deployments
+description: Disinct users who initiated a successful deployment.
product_section: ops
product_stage: release
product_group: group::release
diff --git a/config/metrics/counts_28d/20210216181951_clusters_applications_runner.yml b/config/metrics/counts_28d/20210216181951_clusters_applications_runner.yml
index 4d676e436b2..eebce0dcb81 100644
--- a/config/metrics/counts_28d/20210216181951_clusters_applications_runner.yml
+++ b/config/metrics/counts_28d/20210216181951_clusters_applications_runner.yml
@@ -18,5 +18,6 @@ tier:
- premium
- ultimate
performance_indicator_type: []
-milestone: "<13.9"
+milestone: "12.9"
+introduced_by_url: "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/26441"
milestone_removed: "14.4"
diff --git a/config/metrics/counts_28d/20220202160126_ci_users_executing_deployment_job_monthly.yml b/config/metrics/counts_28d/20220202160126_ci_users_executing_deployment_job_monthly.yml
new file mode 100644
index 00000000000..d33dd895022
--- /dev/null
+++ b/config/metrics/counts_28d/20220202160126_ci_users_executing_deployment_job_monthly.yml
@@ -0,0 +1,26 @@
+---
+key_path: redis_hll_counters.ci_users.ci_users_executing_deployment_job_monthly
+description: Monthly counts of times users have executed deployment jobs
+product_section: ops
+product_stage: release
+product_group: group::release
+product_category: continuous_delivery
+value_type: number
+status: active
+milestone: "14.8"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/79272
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+performance_indicator_type: []
+options:
+ events:
+ - ci_users_executing_deployment_job
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
diff --git a/config/metrics/counts_28d/20220214202927_users_updating_work_item_title.yml b/config/metrics/counts_28d/20220214202927_users_updating_work_item_title.yml
new file mode 100644
index 00000000000..734bf674f00
--- /dev/null
+++ b/config/metrics/counts_28d/20220214202927_users_updating_work_item_title.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.work_items.users_updating_work_item_title_monthly
+description: Unique users updating a work item's title
+product_category: team planning
+product_section: dev
+product_stage: plan
+product_group: group::project management
+value_type: number
+status: active
+milestone: '14.9'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/80532
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+options:
+ events:
+ - users_updating_work_item_title
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
diff --git a/config/metrics/counts_28d/20220221210352_users_creating_work_items_monthly.yml b/config/metrics/counts_28d/20220221210352_users_creating_work_items_monthly.yml
new file mode 100644
index 00000000000..30cd65425fe
--- /dev/null
+++ b/config/metrics/counts_28d/20220221210352_users_creating_work_items_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.work_items.users_creating_work_items_monthly
+description: Unique users creating work items
+product_category: team planning
+product_section: dev
+product_stage: plan
+product_group: group::project management
+value_type: number
+status: active
+milestone: '14.9'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/81201
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+options:
+ events:
+ - users_creating_work_items
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
diff --git a/config/metrics/counts_28d/20220222215951_xmau_plan.yml b/config/metrics/counts_28d/20220222215951_xmau_plan.yml
new file mode 100644
index 00000000000..bab5f66eecd
--- /dev/null
+++ b/config/metrics/counts_28d/20220222215951_xmau_plan.yml
@@ -0,0 +1,21 @@
+---
+key_path: counts_monthly.aggregated_metrics.xmau_plan
+description: Unique users interacting with Plan features
+product_category: team planning
+product_section: dev
+product_stage: plan
+product_group: group::project management
+value_type: number
+status: active
+milestone: '14.9'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/81336
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
diff --git a/config/metrics/counts_28d/20220222215952_xmau_project_management.yml b/config/metrics/counts_28d/20220222215952_xmau_project_management.yml
new file mode 100644
index 00000000000..0f970f2a344
--- /dev/null
+++ b/config/metrics/counts_28d/20220222215952_xmau_project_management.yml
@@ -0,0 +1,21 @@
+---
+key_path: counts_monthly.aggregated_metrics.xmau_project_management
+description: Unique users interacting with Project Management features
+product_category: team planning
+product_section: dev
+product_stage: plan
+product_group: group::project management
+value_type: number
+status: active
+milestone: '14.9'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/81336
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
diff --git a/config/metrics/counts_28d/20220222215955_users_work_items.yml b/config/metrics/counts_28d/20220222215955_users_work_items.yml
new file mode 100644
index 00000000000..a0111383f1d
--- /dev/null
+++ b/config/metrics/counts_28d/20220222215955_users_work_items.yml
@@ -0,0 +1,21 @@
+---
+key_path: counts_monthly.aggregated_metrics.users_work_items
+description: Unique users interacting with work items
+product_category: team planning
+product_section: dev
+product_stage: plan
+product_group: group::product planning
+value_type: number
+status: active
+milestone: '14.9'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/81336
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
diff --git a/config/metrics/counts_28d/20220309183501_error_tracking_view_details_monthly.yml b/config/metrics/counts_28d/20220309183501_error_tracking_view_details_monthly.yml
new file mode 100644
index 00000000000..3a25e0a5a4b
--- /dev/null
+++ b/config/metrics/counts_28d/20220309183501_error_tracking_view_details_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.error_tracking.error_tracking_view_details_monthly
+description: Unique users viewing the error details page
+product_section: ops
+product_stage: monitor
+product_group: respond
+product_category: error_tracking
+value_type: number
+status: active
+milestone: "14.9"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/82543
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+options:
+ events:
+ - error_tracking_view_details
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
diff --git a/config/metrics/counts_28d/20220309195504_error_tracking_view_list_monthly.yml b/config/metrics/counts_28d/20220309195504_error_tracking_view_list_monthly.yml
new file mode 100644
index 00000000000..c94cca65514
--- /dev/null
+++ b/config/metrics/counts_28d/20220309195504_error_tracking_view_list_monthly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.error_tracking.error_tracking_view_list_monthly
+description: Unique users viewing the list of errors in the project
+product_section: ops
+product_stage: monitor
+product_group: respond
+product_category: error_tracking
+value_type: number
+status: active
+milestone: "14.9"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/82543
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+options:
+ events:
+ - error_tracking_view_list
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
diff --git a/config/metrics/counts_28d/20220315223227_error_tracking_total_unique_counts_monthly.yml b/config/metrics/counts_28d/20220315223227_error_tracking_total_unique_counts_monthly.yml
new file mode 100644
index 00000000000..50a854eb455
--- /dev/null
+++ b/config/metrics/counts_28d/20220315223227_error_tracking_total_unique_counts_monthly.yml
@@ -0,0 +1,26 @@
+---
+key_path: redis_hll_counters.error_tracking.error_tracking_total_unique_counts_monthly
+description: Total unique users accessing error tracking routes
+product_section: ops
+product_stage: monitor
+product_group: respond
+product_category: error_tracking
+value_type: number
+status: active
+milestone: "14.9"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/82543
+time_frame: 28d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+options:
+ events:
+ - error_tracking_view_list
+ - error_tracking_view_details
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
diff --git a/config/metrics/counts_7d/20220202160120_ci_users_executing_deployment_job_weekly.yml b/config/metrics/counts_7d/20220202160120_ci_users_executing_deployment_job_weekly.yml
new file mode 100644
index 00000000000..ca5f67e0ac5
--- /dev/null
+++ b/config/metrics/counts_7d/20220202160120_ci_users_executing_deployment_job_weekly.yml
@@ -0,0 +1,26 @@
+---
+key_path: redis_hll_counters.ci_users.ci_users_executing_deployment_job_weekly
+description: Weekly counts of times users have executed deployment jobs
+product_section: ops
+product_stage: release
+product_group: group::release
+product_category: continuous_delivery
+value_type: number
+status: active
+milestone: "14.8"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/79272
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+performance_indicator_type: []
+options:
+ events:
+ - ci_users_executing_deployment_job
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
diff --git a/config/metrics/counts_7d/20220216204730_users_updating_work_item_title_weekly.yml b/config/metrics/counts_7d/20220216204730_users_updating_work_item_title_weekly.yml
new file mode 100644
index 00000000000..92fb6dbd03d
--- /dev/null
+++ b/config/metrics/counts_7d/20220216204730_users_updating_work_item_title_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.work_items.users_updating_work_item_title_weekly
+description: Unique users updating a work item's title
+product_category: team planning
+product_section: dev
+product_stage: plan
+product_group: group::project management
+value_type: number
+status: active
+milestone: '14.9'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/80532
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+options:
+ events:
+ - users_updating_work_item_title
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
diff --git a/config/metrics/counts_7d/20220221210026_users_creating_work_items_weekly.yml b/config/metrics/counts_7d/20220221210026_users_creating_work_items_weekly.yml
new file mode 100644
index 00000000000..0c7e18ec458
--- /dev/null
+++ b/config/metrics/counts_7d/20220221210026_users_creating_work_items_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.work_items.users_creating_work_items_weekly
+description: Unique users creating work items
+product_category: team planning
+product_section: dev
+product_stage: plan
+product_group: group::project management
+value_type: number
+status: active
+milestone: '14.9'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/81201
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+options:
+ events:
+ - users_creating_work_items
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
diff --git a/config/metrics/counts_7d/20220222215851_xmau_plan.yml b/config/metrics/counts_7d/20220222215851_xmau_plan.yml
new file mode 100644
index 00000000000..cc393d6b0a5
--- /dev/null
+++ b/config/metrics/counts_7d/20220222215851_xmau_plan.yml
@@ -0,0 +1,21 @@
+---
+key_path: counts_weekly.aggregated_metrics.xmau_plan
+description: Unique users interacting with Plan features
+product_category: team planning
+product_section: dev
+product_stage: plan
+product_group: group::project management
+value_type: number
+status: active
+milestone: '14.9'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/81336
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
diff --git a/config/metrics/counts_7d/20220222215852_xmau_project_management.yml b/config/metrics/counts_7d/20220222215852_xmau_project_management.yml
new file mode 100644
index 00000000000..40eaf21889e
--- /dev/null
+++ b/config/metrics/counts_7d/20220222215852_xmau_project_management.yml
@@ -0,0 +1,21 @@
+---
+key_path: counts_weekly.aggregated_metrics.xmau_project_management
+description: Unique users interacting with Project Management features
+product_category: team planning
+product_section: dev
+product_stage: plan
+product_group: group::project management
+value_type: number
+status: active
+milestone: '14.9'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/81336
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
diff --git a/config/metrics/counts_7d/20220222215855_users_work_items.yml b/config/metrics/counts_7d/20220222215855_users_work_items.yml
new file mode 100644
index 00000000000..fe77e885449
--- /dev/null
+++ b/config/metrics/counts_7d/20220222215855_users_work_items.yml
@@ -0,0 +1,21 @@
+---
+key_path: counts_weekly.aggregated_metrics.users_work_items
+description: Unique users interacting with work items
+product_category: team planning
+product_section: dev
+product_stage: plan
+product_group: group::product planning
+value_type: number
+status: active
+milestone: '14.9'
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/81336
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
diff --git a/config/metrics/counts_7d/20220309183454_error_tracking_view_details_weekly.yml b/config/metrics/counts_7d/20220309183454_error_tracking_view_details_weekly.yml
new file mode 100644
index 00000000000..bb487abef6d
--- /dev/null
+++ b/config/metrics/counts_7d/20220309183454_error_tracking_view_details_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.error_tracking.error_tracking_view_details_weekly
+description: Unique users viewing the error details page
+product_section: ops
+product_stage: monitor
+product_group: respond
+product_category: error_tracking
+value_type: number
+status: active
+milestone: "14.9"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/82543
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+options:
+ events:
+ - error_tracking_view_details
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
diff --git a/config/metrics/counts_7d/20220309195457_error_tracking_view_list_weekly.yml b/config/metrics/counts_7d/20220309195457_error_tracking_view_list_weekly.yml
new file mode 100644
index 00000000000..e75e6a20c81
--- /dev/null
+++ b/config/metrics/counts_7d/20220309195457_error_tracking_view_list_weekly.yml
@@ -0,0 +1,25 @@
+---
+key_path: redis_hll_counters.error_tracking.error_tracking_view_list_weekly
+description: Unique users viewing the list of errors in the project
+product_section: ops
+product_stage: monitor
+product_group: respond
+product_category: error_tracking
+value_type: number
+status: active
+milestone: "14.9"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/82543
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+options:
+ events:
+ - error_tracking_view_list
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
diff --git a/config/metrics/counts_7d/20220315223220_error_tracking_total_unique_counts_weekly.yml b/config/metrics/counts_7d/20220315223220_error_tracking_total_unique_counts_weekly.yml
new file mode 100644
index 00000000000..851fd6d0925
--- /dev/null
+++ b/config/metrics/counts_7d/20220315223220_error_tracking_total_unique_counts_weekly.yml
@@ -0,0 +1,26 @@
+---
+key_path: redis_hll_counters.error_tracking.error_tracking_total_unique_counts_weekly
+description: Total unique users accessing error tracking routes
+product_section: ops
+product_stage: monitor
+product_group: respond
+product_category: error_tracking
+value_type: number
+status: active
+milestone: "14.9"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/82543
+time_frame: 7d
+data_source: redis_hll
+data_category: optional
+instrumentation_class: RedisHLLMetric
+options:
+ events:
+ - error_tracking_view_list
+ - error_tracking_view_details
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
diff --git a/config/metrics/counts_all/20210514141520_project_imports_total.yml b/config/metrics/counts_all/20210514141520_project_imports_total.yml
index 3846e3b9fc7..1c5a42c4892 100644
--- a/config/metrics/counts_all/20210514141520_project_imports_total.yml
+++ b/config/metrics/counts_all/20210514141520_project_imports_total.yml
@@ -1,7 +1,7 @@
---
data_category: optional
key_path: usage_activity_by_stage.manage.project_imports.total
-description: 'Count number of projects imported monthly'
+description: Number of projects imported
product_section: dev
product_stage: manage
product_group: group::import
diff --git a/config/metrics/counts_all/20220314362302_service_usage_data_download_payload.yml b/config/metrics/counts_all/20220314362302_service_usage_data_download_payload.yml
new file mode 100644
index 00000000000..0174f9a6222
--- /dev/null
+++ b/config/metrics/counts_all/20220314362302_service_usage_data_download_payload.yml
@@ -0,0 +1,22 @@
+---
+key_path: counts.service_usage_data_download_payload_click
+description: Count Download Payload button clicks
+data_category: optional
+name: count_promoted_issues
+product_section: growth
+product_stage: growth
+product_group: group::product intelligence
+product_category: collection
+value_type: number
+status: active
+time_frame: all
+data_source: redis
+distribution:
+ - ce
+ - ee
+tier:
+ - free
+ - premium
+ - ultimate
+performance_indicator_type: []
+milestone: "14.9"
diff --git a/config/metrics/counts_all/20220315180122_projects_harbor_active.yml b/config/metrics/counts_all/20220315180122_projects_harbor_active.yml
new file mode 100644
index 00000000000..90bdad02b8b
--- /dev/null
+++ b/config/metrics/counts_all/20220315180122_projects_harbor_active.yml
@@ -0,0 +1,21 @@
+---
+data_category: optional
+key_path: counts.projects_harbor_active
+description: Count of projects with active integrations for Harbor
+product_section: dev
+product_stage: ecosystem
+product_group: group::integrations
+product_category: integrations
+value_type: number
+status: active
+time_frame: all
+data_source: database
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+performance_indicator_type: []
+milestone: "14.9"
diff --git a/config/metrics/counts_all/20220315180124_groups_harbor_active.yml b/config/metrics/counts_all/20220315180124_groups_harbor_active.yml
new file mode 100644
index 00000000000..6fc8d9a8ec2
--- /dev/null
+++ b/config/metrics/counts_all/20220315180124_groups_harbor_active.yml
@@ -0,0 +1,21 @@
+---
+data_category: optional
+key_path: counts.groups_harbor_active
+description: Count of groups with active integrations for Harbor
+product_section: dev
+product_stage: ecosystem
+product_group: group::integrations
+product_category: integrations
+value_type: number
+status: active
+time_frame: all
+data_source: database
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+performance_indicator_type: []
+milestone: "14.9"
diff --git a/config/metrics/counts_all/20220315180127_instances_harbor_active.yml b/config/metrics/counts_all/20220315180127_instances_harbor_active.yml
new file mode 100644
index 00000000000..a5621da5390
--- /dev/null
+++ b/config/metrics/counts_all/20220315180127_instances_harbor_active.yml
@@ -0,0 +1,21 @@
+---
+data_category: optional
+key_path: counts.instances_harbor_active
+description: Count of active instance-level integrations for Harbor
+product_section: dev
+product_stage: ecosystem
+product_group: group::integrations
+product_category: integrations
+value_type: number
+status: active
+time_frame: all
+data_source: database
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+performance_indicator_type: []
+milestone: "14.9"
diff --git a/config/metrics/counts_all/20220315180129_projects_inheriting_harbor_active.yml b/config/metrics/counts_all/20220315180129_projects_inheriting_harbor_active.yml
new file mode 100644
index 00000000000..97c31b331aa
--- /dev/null
+++ b/config/metrics/counts_all/20220315180129_projects_inheriting_harbor_active.yml
@@ -0,0 +1,21 @@
+---
+data_category: optional
+key_path: counts.projects_inheriting_harbor_active
+description: Count of active projects inheriting integrations for Harbor
+product_section: dev
+product_stage: ecosystem
+product_group: group::integrations
+product_category: integrations
+value_type: number
+status: active
+time_frame: all
+data_source: database
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+performance_indicator_type: []
+milestone: "14.9"
diff --git a/config/metrics/counts_all/20220315180131_groups_inheriting_harbor_active.yml b/config/metrics/counts_all/20220315180131_groups_inheriting_harbor_active.yml
new file mode 100644
index 00000000000..7091a87632f
--- /dev/null
+++ b/config/metrics/counts_all/20220315180131_groups_inheriting_harbor_active.yml
@@ -0,0 +1,21 @@
+---
+data_category: optional
+key_path: counts.groups_inheriting_harbor_active
+description: Count of active groups inheriting integrations for Harbor
+product_section: dev
+product_stage: ecosystem
+product_group: group::integrations
+product_category: integrations
+value_type: number
+status: active
+time_frame: all
+data_source: database
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
+performance_indicator_type: []
+milestone: "14.9"
diff --git a/config/metrics/license/20210216183237_version.yml b/config/metrics/license/20210216183237_version.yml
index 6517c3bc4f5..8d00f03f52b 100644
--- a/config/metrics/license/20210216183237_version.yml
+++ b/config/metrics/license/20210216183237_version.yml
@@ -6,7 +6,8 @@ product_section: enablement
product_stage: enablement
product_group: group::distribution
product_category: ''
-value_type: string
+value_type: object
+value_json_schema: 'config/metrics/objects_schemas/git_version_schema.json'
status: active
milestone: "<13.9"
time_frame: none
diff --git a/config/metrics/objects_schemas/git_version_schema.json b/config/metrics/objects_schemas/git_version_schema.json
new file mode 100644
index 00000000000..2489b05e188
--- /dev/null
+++ b/config/metrics/objects_schemas/git_version_schema.json
@@ -0,0 +1,9 @@
+{
+ "type": "object",
+ "required": ["major"],
+ "properties": {
+ "major": { "type": "number", "description": "Major version number" },
+ "minor": { "type": "number", "description": "Minor version number" },
+ "patch": { "type": "number", "description": "Patch number" }
+ }
+}
diff --git a/config/metrics/settings/20220222181654_certificate_based_clusters_ff.yml b/config/metrics/settings/20220222181654_certificate_based_clusters_ff.yml
new file mode 100644
index 00000000000..6e17601e76d
--- /dev/null
+++ b/config/metrics/settings/20220222181654_certificate_based_clusters_ff.yml
@@ -0,0 +1,24 @@
+---
+key_path: settings.certificate_based_clusters_ff
+name: "certificate_based_clusters_ff"
+description: "Certificate-based clusters feature flag"
+product_section: ops
+product_stage: configure
+product_group: group::configure
+product_category:
+value_type: boolean
+status: active
+milestone: "14.9"
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/81311
+time_frame: none
+data_source: database
+data_category: optional
+instrumentation_class: CertBasedClustersFfMetric
+performance_indicator_type: []
+distribution:
+- ce
+- ee
+tier:
+- free
+- premium
+- ultimate
diff --git a/config/routes.rb b/config/routes.rb
index a57795bea0c..9342de492ec 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -69,7 +69,10 @@ Rails.application.routes.draw do
resources :groups, only: [:new, :create]
resources :projects, only: [:new, :create]
resources :groups_projects, only: [:new, :create] do
- post :import, on: :collection
+ collection do
+ post :import
+ put :exit
+ end
end
draw :verification
end
@@ -232,6 +235,7 @@ Rails.application.routes.draw do
concern :clusterable do
resources :clusters, only: [:index, :new, :show, :update, :destroy] do
collection do
+ get :connect
post :create_user
post :create_gcp
post :create_aws
@@ -266,7 +270,7 @@ Rails.application.routes.draw do
resources :projects, only: [:index, :new, :create]
- get '/projects/:id' => 'projects#resolve'
+ get '/projects/:id' => 'projects/redirect#redirect_from_id'
draw :git_http
draw :api
diff --git a/config/routes/group.rb b/config/routes/group.rb
index c313f7209fb..fecd3135cba 100644
--- a/config/routes/group.rb
+++ b/config/routes/group.rb
@@ -94,7 +94,7 @@ constraints(::Constraints::GroupUrlConstrainer.new) do
concerns :clusterable
- resources :group_members, only: [:index, :create, :update, :destroy], concerns: :access_requestable do
+ resources :group_members, only: [:index, :update, :destroy], concerns: :access_requestable do
post :resend_invite, on: :member
delete :leave, on: :collection
end
@@ -118,6 +118,7 @@ constraints(::Constraints::GroupUrlConstrainer.new) do
end
resources :container_registries, only: [:index, :show], controller: 'registry/repositories'
+ resources :harbor_registries, only: [:index, :show], controller: 'harbor/repositories'
resource :dependency_proxy, only: [:show, :update]
resources :email_campaigns, only: :index
diff --git a/config/routes/jira_connect.rb b/config/routes/jira_connect.rb
index 1e871d52c80..344f0114364 100644
--- a/config/routes/jira_connect.rb
+++ b/config/routes/jira_connect.rb
@@ -20,4 +20,6 @@ namespace :jira_connect do
put :update
end
end
+
+ resources :oauth_callbacks, only: [:index]
end
diff --git a/config/routes/project.rb b/config/routes/project.rb
index 8536ec9fc05..1783f3acc68 100644
--- a/config/routes/project.rb
+++ b/config/routes/project.rb
@@ -96,6 +96,7 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do
namespace :ci do
resource :lint, only: [:show, :create]
resource :pipeline_editor, only: [:show], controller: :pipeline_editor, path: 'editor'
+ resource :secure_files, only: [:show], controller: :secure_files, path: 'secure_files'
resources :daily_build_group_report_results, only: [:index], constraints: { format: /(csv|json)/ }
namespace :prometheus_metrics do
resources :histograms, only: [:create], constraints: { format: 'json' }
@@ -162,14 +163,9 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do
end
end
- resources :project_members, except: [:show, :new, :edit], constraints: { id: %r{[a-zA-Z./0-9_\-#%+:]+} }, concerns: :access_requestable do
+ resources :project_members, except: [:show, :new, :create, :edit], constraints: { id: %r{[a-zA-Z./0-9_\-#%+:]+} }, concerns: :access_requestable do
collection do
delete :leave
-
- # Used for import team
- # from another project
- get :import
- post :apply_import
end
member do
@@ -240,6 +236,8 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do
end
end
+ get 'releases/permalink/latest(/)(*suffix_path)', to: 'releases#latest_permalink', as: :latest_release_permalink, format: false
+
resources :logs, only: [:index] do
collection do
get :k8s
@@ -319,7 +317,9 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do
resources :google_cloud, only: [:index]
namespace :google_cloud do
+ resources :revoke_oauth, only: [:create]
resources :service_accounts, only: [:index, :create]
+ resources :gcp_regions, only: [:index, :create]
get '/deployments/cloud_run', to: 'deployments#cloud_run'
get '/deployments/cloud_storage', to: 'deployments#cloud_storage'
@@ -541,6 +541,9 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do
resources :container_registry, only: [:index, :destroy, :show], # rubocop: disable Cop/PutProjectRoutesUnderScope
controller: 'registry/repositories'
+ resources :harbor_registry, only: [:index, :show], # rubocop: disable Cop/PutProjectRoutesUnderScope
+ controller: 'harbor/repositories'
+
namespace :registry do
resources :repository, only: [] do # rubocop: disable Cop/PutProjectRoutesUnderScope
# We default to JSON format in the controller to avoid ambiguity.
diff --git a/config/sidekiq_queues.yml b/config/sidekiq_queues.yml
index 401471d02d9..a0f1ea4fa06 100644
--- a/config/sidekiq_queues.yml
+++ b/config/sidekiq_queues.yml
@@ -29,8 +29,6 @@
- 1
- - analytics_code_review_metrics
- 1
-- - analytics_cycle_analytics_group_data_loader
- - 1
- - analytics_devops_adoption_create_snapshot
- 1
- - analytics_usage_trends_counter_job
@@ -365,6 +363,8 @@
- 1
- - projects_process_sync_events
- 1
+- - projects_refresh_build_artifacts_size_statistics
+ - 1
- - projects_schedule_bulk_repository_shard_moves
- 1
- - projects_update_repository_storage
diff --git a/config/webpack.config.js b/config/webpack.config.js
index 7b559c8881b..360c5be05d4 100644
--- a/config/webpack.config.js
+++ b/config/webpack.config.js
@@ -44,7 +44,6 @@ const { DEV_SERVER_HOST, DEV_SERVER_PUBLIC_ADDR } = process.env;
const DEV_SERVER_PORT = parseInt(process.env.DEV_SERVER_PORT, 10);
const DEV_SERVER_ALLOWED_HOSTS =
process.env.DEV_SERVER_ALLOWED_HOSTS && process.env.DEV_SERVER_ALLOWED_HOSTS.split(',');
-const DEV_SERVER_HTTPS = process.env.DEV_SERVER_HTTPS && process.env.DEV_SERVER_HTTPS !== 'false';
const DEV_SERVER_LIVERELOAD = IS_DEV_SERVER && process.env.DEV_SERVER_LIVERELOAD !== 'false';
const INCREMENTAL_COMPILER_ENABLED =
IS_DEV_SERVER &&
@@ -364,6 +363,10 @@ module.exports = {
name: '[name].[contenthash:8].[ext]',
},
},
+ {
+ test: /\.(yml|yaml)$/,
+ loader: 'raw-loader',
+ },
],
},
@@ -678,6 +681,7 @@ module.exports = {
IS_JH: IS_JH ? 'window.gon && window.gon.jh' : JSON.stringify(false),
// This is used by Sourcegraph because these assets are loaded dnamically
'process.env.SOURCEGRAPH_PUBLIC_PATH': JSON.stringify(SOURCEGRAPH_PUBLIC_PATH),
+ ...(IS_PRODUCTION ? {} : { LIVE_RELOAD: DEV_SERVER_LIVERELOAD }),
}),
/* Pikaday has a optional dependency to moment.
@@ -709,8 +713,14 @@ module.exports = {
},
host: DEV_SERVER_HOST || 'localhost',
port: DEV_SERVER_PORT || 3808,
- https: DEV_SERVER_HTTPS,
+ // Setting up hot module reloading
+ // HMR works by setting up a websocket server and injecting
+ // a client script which connects to that server.
+ // The server will push messages to the client to reload parts
+ // of the JavaScript or reload the page if necessary
+ webSocketServer: DEV_SERVER_LIVERELOAD ? 'ws' : false,
hot: DEV_SERVER_LIVERELOAD,
+ liveReload: DEV_SERVER_LIVERELOAD,
// The following settings are mainly needed for HMR support in gitpod.
// Per default only local hosts are allowed, but here we could
// allow different hosts (e.g. ['.gitpod'], all of gitpod),
diff --git a/danger/changelog/Dangerfile b/danger/changelog/Dangerfile
deleted file mode 100644
index 83c6f68869b..00000000000
--- a/danger/changelog/Dangerfile
+++ /dev/null
@@ -1,3 +0,0 @@
-# frozen_string_literal: true
-
-changelog.check!
diff --git a/danger/database/Dangerfile b/danger/database/Dangerfile
index b4e06c21fe4..0128f0fa195 100644
--- a/danger/database/Dangerfile
+++ b/danger/database/Dangerfile
@@ -65,7 +65,7 @@ if gitlab.mr_labels.include?('database') || db_paths_to_review.any?
markdown(DB_REMOVE_MESSAGE)
end
- unless helper.has_database_scoped_labels?
- project_helper.labels_to_add << 'database::review pending'
+ unless helper.has_scoped_label_with_scope?("database")
+ helper.labels_to_add << 'database::review pending'
end
end
diff --git a/danger/documentation/Dangerfile b/danger/documentation/Dangerfile
index 918c787075e..41c75a9f176 100644
--- a/danger/documentation/Dangerfile
+++ b/danger/documentation/Dangerfile
@@ -5,7 +5,7 @@ def feature_mr?
end
DOCUMENTATION_UPDATE_MISSING = <<~MSG
-~"feature::addition" and ~"feature::enhancement" merge requests normally have a documentation change. Consider adding a documentation update or confirming the documentation plan with the [Technical Writer counterpart](https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers).
+~"feature::addition" and ~"feature::enhancement" merge requests normally have a documentation change. Consider adding a documentation update or confirming the documentation plan with the [Technical Writer counterpart](https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments).
For more information, see:
@@ -36,6 +36,6 @@ markdown(<<~MARKDOWN)
The review does not need to block merging this merge request. See the:
- [Metadata for the `*.md` files](https://docs.gitlab.com/ee/development/documentation/#metadata) that you've changed. The first few lines of each `*.md` file identify the stage and group most closely associated with your docs change.
- - The [Technical Writer assigned](https://about.gitlab.com/handbook/engineering/technical-writing/#designated-technical-writers) for that stage and group.
+ - The [Technical Writer assigned](https://about.gitlab.com/handbook/engineering/technical-writing/#assignments) for that stage and group.
- [Documentation workflows](https://docs.gitlab.com/ee/development/documentation/workflow.html) for information on when to assign a merge request for review.
MARKDOWN
diff --git a/danger/feature_flag/Dangerfile b/danger/feature_flag/Dangerfile
index d6c1c53cddc..5fe9d42a7a1 100644
--- a/danger/feature_flag/Dangerfile
+++ b/danger/feature_flag/Dangerfile
@@ -58,7 +58,7 @@ def message_for_feature_flag_with_group!(feature_flag:, mr_group_label:)
return if feature_flag.group_match_mr_label?(mr_group_label)
if mr_group_label.nil?
- project_helper.labels_to_add << feature_flag.group
+ helper.labels_to_add << feature_flag.group
else
fail %(`group` is set to ~"#{feature_flag.group}" in #{gitlab.html_link(feature_flag.path)}, which does not match ~"#{mr_group_label}" set on the MR!)
end
diff --git a/danger/plugins/changelog.rb b/danger/plugins/changelog.rb
deleted file mode 100644
index 02ff405c410..00000000000
--- a/danger/plugins/changelog.rb
+++ /dev/null
@@ -1,10 +0,0 @@
-# frozen_string_literal: true
-
-require_relative '../../tooling/danger/changelog'
-
-module Danger
- class Changelog < ::Danger::Plugin
- # Put the helper code somewhere it can be tested
- include Tooling::Danger::Changelog
- end
-end
diff --git a/danger/product_intelligence/Dangerfile b/danger/product_intelligence/Dangerfile
index 01a2f9b6feb..8f782e3de65 100644
--- a/danger/product_intelligence/Dangerfile
+++ b/danger/product_intelligence/Dangerfile
@@ -19,4 +19,4 @@ return if product_intelligence_paths_to_review.empty? || product_intelligence.sk
warn format(CHANGED_FILES_MESSAGE, changed_files: helper.markdown_list(product_intelligence_paths_to_review)) unless product_intelligence.has_approved_label?
-project_helper.labels_to_add.concat(labels_to_add) unless labels_to_add.empty?
+helper.labels_to_add.concat(labels_to_add) unless labels_to_add.empty?
diff --git a/danger/specialization_labels/Dangerfile b/danger/specialization_labels/Dangerfile
index cb4c8c96f4f..f161c470f36 100644
--- a/danger/specialization_labels/Dangerfile
+++ b/danger/specialization_labels/Dangerfile
@@ -9,7 +9,6 @@ SPECIALIZATIONS = {
ux: 'UX',
docs: 'documentation',
qa: 'QA',
- tooling: 'type::tooling',
ci_template: 'ci::templates',
feature_flag: 'feature flag'
}.freeze
@@ -26,4 +25,4 @@ labels_to_add = helper.changes_by_category.each_with_object([]) do |(category, _
memo << label
end
-project_helper.labels_to_add.concat(labels_to_add) if labels_to_add.any?
+helper.labels_to_add.concat(labels_to_add) if labels_to_add.any?
diff --git a/danger/specs/Dangerfile b/danger/specs/Dangerfile
index c4f609f5806..8ef046f7bc1 100644
--- a/danger/specs/Dangerfile
+++ b/danger/specs/Dangerfile
@@ -1,9 +1,8 @@
# frozen_string_literal: true
NO_SPECS_LABELS = [
- 'type::tooling',
- 'tooling::pipelines',
- 'tooling::workflow',
+ 'maintenance::pipelines',
+ 'maintenance::workflow',
'documentation',
'QA'
].freeze
diff --git a/danger/z_metadata/Dangerfile b/danger/z_metadata/Dangerfile
index 0a70554486f..546fdc8de5f 100644
--- a/danger/z_metadata/Dangerfile
+++ b/danger/z_metadata/Dangerfile
@@ -4,24 +4,10 @@
DEFAULT_BRANCH = 'master'
-TYPE_LABELS = [
- 'type::feature',
- 'feature::addition',
- 'type::maintenance',
- 'type::tooling',
- 'tooling::pipelines',
- 'tooling::workflow',
- 'type::bug'
-].freeze
-
if gitlab.mr_body.size < 5
fail "Please provide a proper merge request description."
end
-if (TYPE_LABELS & (gitlab.mr_labels + project_helper.labels_to_add)).empty?
- warn 'Please add a [merge request type](https://about.gitlab.com/handbook/engineering/metrics/#work-type-classification) to this merge request.'
-end
-
unless gitlab.mr_json["assignee"]
warn "This merge request does not have any assignee yet. Setting an assignee clarifies who needs to take action on the merge request at any given time."
end
diff --git a/data/deprecations/14-0-nfs-fot-git-repository-storage.yml b/data/deprecations/14-0-nfs-fot-git-repository-storage.yml
index fd5db7f8835..9e02524b022 100644
--- a/data/deprecations/14-0-nfs-fot-git-repository-storage.yml
+++ b/data/deprecations/14-0-nfs-fot-git-repository-storage.yml
@@ -1,10 +1,10 @@
-- name: "NFS for Git repository storage" # The name of the feature to be deprecated
- announcement_milestone: "14.0" # The milestone when this feature was first announced as deprecated.
- announcement_date: "2021-06-22" # The date of the milestone release when this feature was first announced as deprecated
- removal_milestone: "15.0" # The milestone when this feature is planned to be removed
- removal_date: "2022-05-22" # (optional - may be required in the future) YYYY-MM-DD format - the date of the milestone release when this feature is planned to be removed
+- name: "NFS for Git repository storage" # The name of the feature to be deprecated
+ announcement_milestone: "14.0" # The milestone when this feature was first announced as deprecated.
+ announcement_date: "2021-06-22" # The date of the milestone release when this feature was first announced as deprecated
+ removal_milestone: "15.0" # The milestone when this feature is planned to be removed
+ removal_date: "2022-05-22" # (optional - may be required in the future) YYYY-MM-DD format - the date of the milestone release when this feature is planned to be removed
breaking_change: true
- body: | # Do not modify this line, instead modify the lines below.
+ body: | # Do not modify this line, instead modify the lines below.
With the general availability of Gitaly Cluster ([introduced in GitLab 13.0](https://about.gitlab.com/releases/2020/05/22/gitlab-13-0-released/)), we have deprecated development (bugfixes, performance improvements, etc) for NFS for Git repository storage in GitLab 14.0. We will continue to provide technical support for NFS for Git repositories throughout 14.x, but we will remove all support for NFS in GitLab 15.0. Please see our official [Statement of Support](https://about.gitlab.com/support/statement-of-support.html#gitaly-and-nfs) for further information.
Gitaly Cluster offers tremendous benefits for our customers such as:
@@ -15,9 +15,9 @@
We encourage customers currently using NFS for Git repositories to plan their migration by reviewing our documentation on [migrating to Gitaly Cluster](https://docs.gitlab.com/ee/administration/gitaly/index.html#migrate-to-gitaly-cluster).
- stage: # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
- tiers: # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
- issue_url: # (optional) This is a link to the deprecation issue in GitLab
- documentation_url: # (optional) This is a link to the current documentation page
- image_url: # (optional) This is a link to a thumbnail image depicting the feature
- video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
+ stage: # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
+ tiers: # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
+ issue_url: # (optional) This is a link to the deprecation issue in GitLab
+ documentation_url: # (optional) This is a link to the current documentation page
+ image_url: # (optional) This is a link to a thumbnail image depicting the feature
+ video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
diff --git a/data/deprecations/14-2-deprecation-release-cli.yml b/data/deprecations/14-2-deprecation-release-cli.yml
index 809d8eb1e8b..fe53dea309a 100644
--- a/data/deprecations/14-2-deprecation-release-cli.yml
+++ b/data/deprecations/14-2-deprecation-release-cli.yml
@@ -1,14 +1,14 @@
-- name: "Release CLI distributed as a generic package" # The name of the feature to be deprecated
- announcement_milestone: "14.2" # The milestone when this feature was first announced as deprecated.
- announcement_date: "2021-08-22" # The date of the milestone release when this feature was first announced as deprecated
- removal_milestone: "14.6" # The milestone when this feature is planned to be removed
- removal_date: "2021-12-22" # the date of the milestone release when this feature is planned to be removed
+- name: "Release CLI distributed as a generic package" # The name of the feature to be deprecated
+ announcement_milestone: "14.2" # The milestone when this feature was first announced as deprecated.
+ announcement_date: "2021-08-22" # The date of the milestone release when this feature was first announced as deprecated
+ removal_milestone: "14.6" # The milestone when this feature is planned to be removed
+ removal_date: "2021-12-22" # the date of the milestone release when this feature is planned to be removed
breaking_change: false
- body: | # Do not modify this line, instead modify the lines below.
+ body: | # Do not modify this line, instead modify the lines below.
The [release-cli](https://gitlab.com/gitlab-org/release-cli) will be released as a [generic package](https://gitlab.com/gitlab-org/release-cli/-/packages) starting in GitLab 14.2. We will continue to deploy it as a binary to S3 until GitLab 14.5 and stop distributing it in S3 in GitLab 14.6.
- stage: # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
- tiers: # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
- issue_url: # (optional) This is a link to the deprecation issue in GitLab
- documentation_url: # (optional) This is a link to the current documentation page
- image_url: # (optional) This is a link to a thumbnail image depicting the feature
- video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
+ stage: # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
+ tiers: # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
+ issue_url: # (optional) This is a link to the deprecation issue in GitLab
+ documentation_url: # (optional) This is a link to the current documentation page
+ image_url: # (optional) This is a link to a thumbnail image depicting the feature
+ video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
diff --git a/data/deprecations/14-2-deprecation-task-runner.yml b/data/deprecations/14-2-deprecation-task-runner.yml
index 8162b5c4d4e..1b72330c5bd 100644
--- a/data/deprecations/14-2-deprecation-task-runner.yml
+++ b/data/deprecations/14-2-deprecation-task-runner.yml
@@ -1,17 +1,17 @@
-- name: "Rename Task Runner pod to Toolbox" # The name of the feature to be deprecated
- announcement_milestone: "14.2" # The milestone when this feature was first announced as deprecated.
- announcement_date: "2021-08-22" # The date of the milestone release when this feature was first announced as deprecated
- removal_milestone: "14.5" # The milestone when this feature is planned to be removed
- removal_date: "2021-11-22" # the date of the milestone release when this feature is planned to be removed
+- name: "Rename Task Runner pod to Toolbox" # The name of the feature to be deprecated
+ announcement_milestone: "14.2" # The milestone when this feature was first announced as deprecated.
+ announcement_date: "2021-08-22" # The date of the milestone release when this feature was first announced as deprecated
+ removal_milestone: "14.5" # The milestone when this feature is planned to be removed
+ removal_date: "2021-11-22" # the date of the milestone release when this feature is planned to be removed
breaking_change: false
- body: | # Do not modify this line, instead modify the lines below.
+ body: | # Do not modify this line, instead modify the lines below.
The Task Runner pod is used to execute periodic housekeeping tasks within the GitLab application and is often confused with the GitLab Runner. Thus, [Task Runner will be renamed to Toolbox](https://gitlab.com/groups/gitlab-org/charts/-/epics/25).
This will result in the rename of the sub-chart: `gitlab/task-runner` to `gitlab/toolbox`. Resulting pods will be named along the lines of `{{ .Release.Name }}-toolbox`, which will often be `gitlab-toolbox`. They will be locatable with the label `app=toolbox`.
- stage: # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
- tiers: # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
- issue_url: # (optional) This is a link to the deprecation issue in GitLab
- documentation_url: # (optional) This is a link to the current documentation page
- image_url: # (optional) This is a link to a thumbnail image depicting the feature
- video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
+ stage: # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
+ tiers: # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
+ issue_url: # (optional) This is a link to the deprecation issue in GitLab
+ documentation_url: # (optional) This is a link to the current documentation page
+ image_url: # (optional) This is a link to a thumbnail image depicting the feature
+ video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
diff --git a/data/deprecations/14-3-database-deprecate-legacy-database-conf.yml b/data/deprecations/14-3-database-deprecate-legacy-database-conf.yml
index 29e55337261..3644b681da0 100644
--- a/data/deprecations/14-3-database-deprecate-legacy-database-conf.yml
+++ b/data/deprecations/14-3-database-deprecate-legacy-database-conf.yml
@@ -2,7 +2,7 @@
announcement_milestone: "14.3"
announcement_date: "2021-09-22"
removal_milestone: "15.0"
- removal_date: "2022-05-22" # the date of the milestone release when this feature is planned to be removed
+ removal_date: "2022-05-22" # the date of the milestone release when this feature is planned to be removed
breaking_change: true
body: |
The syntax of [GitLabs database](https://docs.gitlab.com/omnibus/settings/database.html)
diff --git a/data/deprecations/14-3-deprecation_omniauth-kerberos_gem.yml b/data/deprecations/14-3-deprecation_omniauth-kerberos_gem.yml
index 17c6cbc8e7a..ba7c07eaf83 100644
--- a/data/deprecations/14-3-deprecation_omniauth-kerberos_gem.yml
+++ b/data/deprecations/14-3-deprecation_omniauth-kerberos_gem.yml
@@ -4,7 +4,7 @@
removal_milestone: "15.0"
removal_date: "2022-05-22"
breaking_change: true
- body: | # Do not modify this line, instead modify the lines below.
+ body: | # Do not modify this line, instead modify the lines below.
The `omniauth-kerberos` gem will be removed in our next major release, GitLab 15.0.
This gem has not been maintained and has very little usage. We therefore plan to remove support for this authentication method and recommend using the Kerberos [SPNEGO](https://en.wikipedia.org/wiki/SPNEGO) integration instead. You can follow the [upgrade instructions](https://docs.gitlab.com/ee/integration/kerberos.html#upgrading-from-password-based-to-ticket-based-kerberos-sign-ins) to upgrade from the `omniauth-kerberos` integration to the supported one.
@@ -14,4 +14,3 @@
tiers: [Premium, Ultimate]
issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/337384
documentation_url: https://docs.gitlab.com/ee/integration/kerberos.html#upgrading-from-password-based-to-ticket-based-kerberos-sign-ins
-
diff --git a/data/deprecations/14-3-repository-push-audit-events.yml b/data/deprecations/14-3-repository-push-audit-events.yml
index 97a7a01b593..587dc98d03c 100644
--- a/data/deprecations/14-3-repository-push-audit-events.yml
+++ b/data/deprecations/14-3-repository-push-audit-events.yml
@@ -1,10 +1,10 @@
- name: "Audit events for repository push events"
- announcement_milestone: "14.3" # The milestone when this feature was first announced as deprecated.
- announcement_date: "2021-09-22" # https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69024
- removal_milestone: "15.0" # the milestone when this feature is planned to be removed
- removal_date: "2022-05-22" # the date of the milestone release when this feature is planned to be removed
+ announcement_milestone: "14.3" # The milestone when this feature was first announced as deprecated.
+ announcement_date: "2021-09-22" # https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69024
+ removal_milestone: "15.0" # the milestone when this feature is planned to be removed
+ removal_date: "2022-05-22" # the date of the milestone release when this feature is planned to be removed
breaking_change: true
- body: | # Do not modify this line, instead modify the lines below.
+ body: | # Do not modify this line, instead modify the lines below.
Audit events for [repository events](https://docs.gitlab.com/ee/administration/audit_events.html#repository-push-deprecated) are now deprecated and will be removed in GitLab 15.0.
These events have always been disabled by default and had to be manually enabled with a
diff --git a/data/deprecations/14-5-certificate-based-integration-with-kubernetes.yml b/data/deprecations/14-5-certificate-based-integration-with-kubernetes.yml
index 698d8b0dc69..5cf9354cd05 100644
--- a/data/deprecations/14-5-certificate-based-integration-with-kubernetes.yml
+++ b/data/deprecations/14-5-certificate-based-integration-with-kubernetes.yml
@@ -2,22 +2,25 @@
announcement_milestone: "14.5"
announcement_date: "2021-11-15"
removal_milestone: "15.6"
- removal_date: "2022-11-22" # the date of the milestone release when this feature is planned to be removed
+ removal_date: "2022-11-22" # the date of the milestone release when this feature is planned to be removed
breaking_change: true
body: |
- [We are deprecating the certificate-based integration with Kubernetes](https://about.gitlab.com/blog/2021/11/15/deprecating-the-cert-based-kubernetes-integration/).
- The timeline of removal of the integration from the product is planned to happen in two steps, starting with milestone 15.0 and finishing in GitLab version 15.6.
+ [The certificate-based integration with Kubernetes will be deprecated and removed](https://about.gitlab.com/blog/2021/11/15/deprecating-the-cert-based-kubernetes-integration/).
- In 15.0, we plan to introduce a feature flag that will allow GitLab Self-Managed customers to keep the certificate-based integration enabled, it will be disabled by default. We plan to remove this feature flag together with the underlying code in GitLab version 15.6.
- The certificate-based integration will continue to receive security and
- critical fixes, and features built on the integration will continue to work with supported Kubernetes
- versions until the final removal in 15.6.
+ If you are a self-managed customer, in GitLab 15.0, a feature flag will be introduced so you can keep
+ certificate-based integration enabled. The flag will be disabled by default.
+ The flag and the related code will be removed in GitLab 15.6.
- For a more robust, secure, forthcoming, and reliable integration with Kubernetes, we recommend the use of the
- [Kubernetes Agent](https://docs.gitlab.com/ee/user/clusters/agent/) to connect Kubernetes clusters with GitLab.
- We provide [migration plans](https://docs.gitlab.com/ee/user/infrastructure/clusters/migrate_to_gitlab_agent.html) in the documentation.
+ Until the final removal in 15.6, features built on the integration will continue to work, and
+ GitLab will continue to fix security and critical issues.
- For updates and details around this deprecation, follow this [epic](https://gitlab.com/groups/gitlab-org/configure/-/epics/8).
+ If you use GitLab.com, certificate-based integrations will cease functioning in 15.0.
+
+ For a more robust, secure, forthcoming, and reliable integration with Kubernetes, we recommend you use the
+ [agent for Kubernetes](https://docs.gitlab.com/ee/user/clusters/agent/) to connect Kubernetes clusters with GitLab.
+ See the documentation for [how to migrate](https://docs.gitlab.com/ee/user/infrastructure/clusters/migrate_to_gitlab_agent.html).
+
+ For updates and details about this deprecation, follow [this epic](https://gitlab.com/groups/gitlab-org/configure/-/epics/8).
stage: Configure
tiers: [Free, Silver, Gold, Core, Premium, Ultimate]
issue_url: 'https://gitlab.com/groups/gitlab-org/configure/-/epics/8'
diff --git a/data/deprecations/14-5-deprecate-convert-instance-runner-to-project.yml b/data/deprecations/14-5-deprecate-convert-instance-runner-to-project.yml
index 9cf806da021..9b45454fef8 100644
--- a/data/deprecations/14-5-deprecate-convert-instance-runner-to-project.yml
+++ b/data/deprecations/14-5-deprecate-convert-instance-runner-to-project.yml
@@ -1,10 +1,10 @@
- name: "Converting an instance (shared) runner to a project (specific) runner"
- announcement_milestone: "14.5" # The milestone when this feature was first announced as deprecated.
+ announcement_milestone: "14.5" # The milestone when this feature was first announced as deprecated.
announcement_date: "2021-11-22"
- removal_milestone: "15.0" # the milestone when this feature is planned to be removed
- removal_date: "2022-05-22" # the date of the milestone release when this feature is planned to be removed
+ removal_milestone: "15.0" # the milestone when this feature is planned to be removed
+ removal_date: "2022-05-22" # the date of the milestone release when this feature is planned to be removed
breaking_change: true
- body: | # Do not modify this line, instead modify the lines below.
+ body: | # Do not modify this line, instead modify the lines below.
In GitLab 15.0, we will remove the feature that enables you to convert an instance (shared) runner to a project (specific) runner. Users who need to add a runner to only a particular project can register a runner to the project directly.
stage: Verify
diff --git a/data/deprecations/14-5-deprecate-defaultMergeCommitMessageWithDescription-graphql.yml b/data/deprecations/14-5-deprecate-defaultMergeCommitMessageWithDescription-graphql.yml
index af172f47ed1..2dfc20ae14e 100644
--- a/data/deprecations/14-5-deprecate-defaultMergeCommitMessageWithDescription-graphql.yml
+++ b/data/deprecations/14-5-deprecate-defaultMergeCommitMessageWithDescription-graphql.yml
@@ -1,15 +1,15 @@
-- name: "`defaultMergeCommitMessageWithDescription` GraphQL API field" # The name of the feature to be deprecated
- announcement_milestone: "14.5" # The milestone when this feature was first announced as deprecated.
- announcement_date: "2021-11-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
- removal_milestone: "15.0" # The milestone when this feature is planned to be removed
- removal_date: "2022-05-22" # the date of the milestone release when this feature is planned to be removed
+- name: "`defaultMergeCommitMessageWithDescription` GraphQL API field" # The name of the feature to be deprecated
+ announcement_milestone: "14.5" # The milestone when this feature was first announced as deprecated.
+ announcement_date: "2021-11-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
+ removal_milestone: "15.0" # The milestone when this feature is planned to be removed
+ removal_date: "2022-05-22" # the date of the milestone release when this feature is planned to be removed
breaking_change: true
- body: | # Do not modify this line, instead modify the lines below.
+ body: | # Do not modify this line, instead modify the lines below.
The GraphQL API field `defaultMergeCommitMessageWithDescription` has been deprecated and will be removed in GitLab 15.0. For projects with a commit message template set, it will ignore the template.
# The following items are not published on the docs page, but may be used in the future.
- stage: # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
- tiers: # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
- issue_url: # (optional) This is a link to the deprecation issue in GitLab
- documentation_url: # (optional) This is a link to the current documentation page
- image_url: # (optional) This is a link to a thumbnail image depicting the feature
- video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
+ stage: # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
+ tiers: # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
+ issue_url: # (optional) This is a link to the deprecation issue in GitLab
+ documentation_url: # (optional) This is a link to the current documentation page
+ image_url: # (optional) This is a link to a thumbnail image depicting the feature
+ video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
diff --git a/data/deprecations/14-5-deprecate-opensuse-15-2.yml b/data/deprecations/14-5-deprecate-opensuse-15-2.yml
index f95a80e6eac..877fcf7e3a6 100644
--- a/data/deprecations/14-5-deprecate-opensuse-15-2.yml
+++ b/data/deprecations/14-5-deprecate-opensuse-15-2.yml
@@ -1,10 +1,10 @@
-- name: "openSUSE Leap 15.2 packages" # The name of the feature to be deprecated
- announcement_milestone: "14.5" # The milestone when this feature was first announced as deprecated.
- announcement_date: "2021-11-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
- removal_milestone: "14.8" # The milestone when this feature is planned to be removed
- removal_date: "2022-02-22" # the date of the milestone release when this feature is planned to be removed
+- name: "openSUSE Leap 15.2 packages" # The name of the feature to be deprecated
+ announcement_milestone: "14.5" # The milestone when this feature was first announced as deprecated.
+ announcement_date: "2021-11-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
+ removal_milestone: "14.8" # The milestone when this feature is planned to be removed
+ removal_date: "2022-02-22" # the date of the milestone release when this feature is planned to be removed
breaking_change: false
- body: | # Do not modify this line, instead modify the lines below.
+ body: | # Do not modify this line, instead modify the lines below.
Distribution support and security updates for openSUSE Leap 15.2 are [ending December 2021](https://en.opensuse.org/Lifetime#openSUSE_Leap).
Starting in 14.5 we are providing packages for openSUSE Leap 15.3, and will stop providing packages for openSUSE Leap 15.2 in the 14.8 milestone.
diff --git a/data/deprecations/14-5-deprecate-sles-12sp2.yml b/data/deprecations/14-5-deprecate-sles-12sp2.yml
index 9c6d1f6da52..69f8eb73bfd 100644
--- a/data/deprecations/14-5-deprecate-sles-12sp2.yml
+++ b/data/deprecations/14-5-deprecate-sles-12sp2.yml
@@ -1,8 +1,8 @@
-- name: "Support for SLES 12 SP2" # The name of the feature to be deprecated
- announcement_milestone: "14.5" # The milestone when this feature was first announced as deprecated.
+- name: "Support for SLES 12 SP2" # The name of the feature to be deprecated
+ announcement_milestone: "14.5" # The milestone when this feature was first announced as deprecated.
announcement_date: "2021-11-22"
- removal_milestone: "15.0" # the milestone when this feature is planned to be removed
- removal_date: "2022-05-22" # the date of the milestone release when this feature is planned to be removed
+ removal_milestone: "15.0" # the milestone when this feature is planned to be removed
+ removal_date: "2022-05-22" # the date of the milestone release when this feature is planned to be removed
breaking_change: true
- body: | # Do not modify this line, instead modify the lines below.
+ body: | # Do not modify this line, instead modify the lines below.
Long term service and support (LTSS) for SUSE Linux Enterprise Server (SLES) 12 SP2 [ended on March 31, 2021](https://www.suse.com/lifecycle/). The CA certificates on SP2 include the expired DST root certificate, and it's not getting new CA certificate package updates. We have implemented some [workarounds](https://gitlab.com/gitlab-org/gitlab-omnibus-builder/-/merge_requests/191), but we will not be able to continue to keep the build running properly.
diff --git a/data/deprecations/14-5-deprecation-versions-packagetype.yml b/data/deprecations/14-5-deprecation-versions-packagetype.yml
index 92188b1b21d..da6e705b94f 100644
--- a/data/deprecations/14-5-deprecation-versions-packagetype.yml
+++ b/data/deprecations/14-5-deprecation-versions-packagetype.yml
@@ -1,10 +1,10 @@
- name: "`Versions` on base `PackageType`"
- announcement_milestone: "14.5" # The milestone when this feature was first announced as deprecated.
- announcement_date: "2021-11-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
- removal_milestone: "15.0" # The milestone when this feature is planned to be removed
- removal_date: "2022-05-22" # the date of the milestone release when this feature is planned to be removed
+ announcement_milestone: "14.5" # The milestone when this feature was first announced as deprecated.
+ announcement_date: "2021-11-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
+ removal_milestone: "15.0" # The milestone when this feature is planned to be removed
+ removal_date: "2022-05-22" # the date of the milestone release when this feature is planned to be removed
breaking_change: true
- body: | # Do not modify this line, instead modify the lines below.
+ body: | # Do not modify this line, instead modify the lines below.
As part of the work to create a [Package Registry GraphQL API](https://gitlab.com/groups/gitlab-org/-/epics/6318), the Package group deprecated the `Version` type for the basic `PackageType` type and moved it to [`PackageDetailsType`](https://docs.gitlab.com/ee/api/graphql/reference/index.html#packagedetailstype).
In milestone 15.0, we will completely remove `Version` from `PackageType`.
diff --git a/data/deprecations/14-5-deprecation-vsa-announce-deprecation-of-vsa-filtering-calculation.yml b/data/deprecations/14-5-deprecation-vsa-announce-deprecation-of-vsa-filtering-calculation.yml
index 2c16aca5df6..0ba7b828f8d 100644
--- a/data/deprecations/14-5-deprecation-vsa-announce-deprecation-of-vsa-filtering-calculation.yml
+++ b/data/deprecations/14-5-deprecation-vsa-announce-deprecation-of-vsa-filtering-calculation.yml
@@ -1,15 +1,15 @@
-- name: "Value Stream Analytics filtering calculation change" # The name of the feature to be deprecated
- announcement_milestone: "14.5" # The milestone when this feature was first announced as deprecated.
- announcement_date: "2021-11-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
- removal_milestone: "15.0" # The milestone when this feature is planned to be removed
- removal_date: "2022-05-22" # the date of the milestone release when this feature is planned to be removed
+- name: "Value Stream Analytics filtering calculation change" # The name of the feature to be deprecated
+ announcement_milestone: "14.5" # The milestone when this feature was first announced as deprecated.
+ announcement_date: "2021-11-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
+ removal_milestone: "15.0" # The milestone when this feature is planned to be removed
+ removal_date: "2022-05-22" # the date of the milestone release when this feature is planned to be removed
breaking_change: true
- body: | # Do not modify this line, instead modify the lines below.
+ body: | # Do not modify this line, instead modify the lines below.
We are changing how the date filter works in Value Stream Analytics. Instead of filtering by the time that the issue or merge request was created, the date filter will filter by the end event time of the given stage. This will result in completely different figures after this change has rolled out.
If you monitor Value Stream Analytics metrics and rely on the date filter, to avoid losing data, you must save the data prior to this change.
- stage: manage # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
- tiers: # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
- issue_url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/343210' # (optional) This is a link to the deprecation issue in GitLab
- documentation_url: "https://docs.gitlab.com/ee/user/analytics/value_stream_analytics.html#filter-value-stream-analytics-data" # (optional) This is a link to the current documentation page
- image_url: "vsa_warning.png" # (optional) This is a link to a thumbnail image depicting the feature
+ stage: manage # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
+ tiers: # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
+ issue_url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/343210' # (optional) This is a link to the deprecation issue in GitLab
+ documentation_url: "https://docs.gitlab.com/ee/user/analytics/value_stream_analytics.html#filter-value-stream-analytics-data" # (optional) This is a link to the current documentation page
+ image_url: "vsa_warning.png" # (optional) This is a link to a thumbnail image depicting the feature
diff --git a/data/deprecations/14-5-disable_strict_host_key_checking.yml b/data/deprecations/14-5-disable_strict_host_key_checking.yml
index a3a6a3bf223..b2091578ff4 100644
--- a/data/deprecations/14-5-disable_strict_host_key_checking.yml
+++ b/data/deprecations/14-5-disable_strict_host_key_checking.yml
@@ -1,10 +1,10 @@
- name: "Known host required for GitLab Runner SSH executor"
- announcement_milestone: "14.5" # The milestone when this feature was first announced as deprecated.
+ announcement_milestone: "14.5" # The milestone when this feature was first announced as deprecated.
announcement_date: "2021-11-22"
- removal_milestone: "15.0" # the milestone when this feature is planned to be removed
+ removal_milestone: "15.0" # the milestone when this feature is planned to be removed
removal_date: "2022-05-22"
breaking_change: true
- body: | # Do not modify this line, instead modify the lines below.
+ body: | # Do not modify this line, instead modify the lines below.
In [GitLab 14.3](https://gitlab.com/gitlab-org/gitlab-runner/-/merge_requests/3074), we added a configuration setting in the GitLab Runner `config.toml` file. This setting, [`[runners.ssh.disable_strict_host_key_checking]`](https://docs.gitlab.com/runner/executors/ssh.html#security), controls whether or not to use strict host key checking with the SSH executor.
In GitLab 15.0 and later, the default value for this configuration option will change from `true` to `false`. This means that strict host key checking will be enforced when using the GitLab Runner SSH executor.
diff --git a/data/deprecations/14-5-geo-deprecate-promote-db.yml b/data/deprecations/14-5-geo-deprecate-promote-db.yml
index 81a2d10e35b..0dbd785c1a0 100644
--- a/data/deprecations/14-5-geo-deprecate-promote-db.yml
+++ b/data/deprecations/14-5-geo-deprecate-promote-db.yml
@@ -1,14 +1,14 @@
-- name: "`promote-db` command from `gitlab-ctl`" # The name of the feature to be deprecated
- announcement_milestone: "14.5" # The milestone when this feature was first announced as deprecated.
- announcement_date: "2021-11-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
- removal_milestone: "15.0" # The milestone when this feature is planned to be removed
+- name: "`promote-db` command from `gitlab-ctl`" # The name of the feature to be deprecated
+ announcement_milestone: "14.5" # The milestone when this feature was first announced as deprecated.
+ announcement_date: "2021-11-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
+ removal_milestone: "15.0" # The milestone when this feature is planned to be removed
removal_date: "2022-05-22"
breaking_change: true
- body: | # Do not modify this line, instead modify the lines below.
+ body: | # Do not modify this line, instead modify the lines below.
In GitLab 14.5, we introduced the command `gitlab-ctl promote` to promote any Geo secondary node to a primary during a failover. This command replaces `gitlab-ctl promote-db` which is used to promote database nodes in multi-node Geo secondary sites. `gitlab-ctl promote-db` will continue to function as-is and be available until GitLab 15.0. We recommend that Geo customers begin testing the new `gitlab-ctl promote` command in their staging environments and incorporating the new command in their failover procedures.
stage: "Enablement"
tiers: [Premium, Ultimate]
issue_url: "https://gitlab.com/gitlab-org/gitlab/-/issues/345207"
- documentation_url: # (optional) This is a link to the current documentation page
- image_url: # (optional) This is a link to a thumbnail image depicting the feature
- video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
+ documentation_url: # (optional) This is a link to the current documentation page
+ image_url: # (optional) This is a link to a thumbnail image depicting the feature
+ video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
diff --git a/data/deprecations/14-5-geo-deprecate-promote-to-primary-node.yml b/data/deprecations/14-5-geo-deprecate-promote-to-primary-node.yml
index bbecfcd65ec..69034bcd33d 100644
--- a/data/deprecations/14-5-geo-deprecate-promote-to-primary-node.yml
+++ b/data/deprecations/14-5-geo-deprecate-promote-to-primary-node.yml
@@ -1,14 +1,14 @@
-- name: "`promote-to-primary-node` command from `gitlab-ctl`" # The name of the feature to be deprecated
- announcement_milestone: "14.5" # The milestone when this feature was first announced as deprecated.
- announcement_date: "2021-11-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
- removal_milestone: "15.0" # The milestone when this feature is planned to be removed
+- name: "`promote-to-primary-node` command from `gitlab-ctl`" # The name of the feature to be deprecated
+ announcement_milestone: "14.5" # The milestone when this feature was first announced as deprecated.
+ announcement_date: "2021-11-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
+ removal_milestone: "15.0" # The milestone when this feature is planned to be removed
removal_date: "2022-05-22"
breaking_change: true
- body: | # Do not modify this line, instead modify the lines below.
+ body: | # Do not modify this line, instead modify the lines below.
In GitLab 14.5, we introduced the command `gitlab-ctl promote` to promote any Geo secondary node to a primary during a failover. This command replaces `gitlab-ctl promote-to-primary-node` which was only usable for single-node Geo sites. `gitlab-ctl promote-to-primary-node` will continue to function as-is and be available until GitLab 15.0. We recommend that Geo customers begin testing the new `gitlab-ctl promote` command in their staging environments and incorporating the new command in their failover procedures.
stage: "Enablement"
tiers: [Premium, Ultimate]
issue_url: "https://gitlab.com/gitlab-org/gitlab/-/issues/345207"
- documentation_url: # (optional) This is a link to the current documentation page
- image_url: # (optional) This is a link to a thumbnail image depicting the feature
- video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
+ documentation_url: # (optional) This is a link to the current documentation page
+ image_url: # (optional) This is a link to a thumbnail image depicting the feature
+ video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
diff --git a/data/deprecations/14-5-package-container-registry-api-group-update.yml b/data/deprecations/14-5-package-container-registry-api-group-update.yml
index 951de288d90..67e3557cae3 100644
--- a/data/deprecations/14-5-package-container-registry-api-group-update.yml
+++ b/data/deprecations/14-5-package-container-registry-api-group-update.yml
@@ -1,10 +1,10 @@
- name: "Update to the Container Registry group-level API"
- announcement_milestone: "14.5" # The milestone when this feature was first announced as deprecated.
+ announcement_milestone: "14.5" # The milestone when this feature was first announced as deprecated.
announcement_date: "2021-11-22"
- removal_milestone: "15.0" # the milestone when this feature is planned to be removed
- removal_date: "2022-05-22" # the date of the milestone release when this feature is planned to be removed
+ removal_milestone: "15.0" # the milestone when this feature is planned to be removed
+ removal_date: "2022-05-22" # the date of the milestone release when this feature is planned to be removed
breaking_change: true
- body: | # Do not modify this line, instead modify the lines below.
+ body: | # Do not modify this line, instead modify the lines below.
In milestone 15.0, support for the `tags` and `tags_count` parameters will be removed from the Container Registry API that [gets registry repositories from a group](../api/container_registry.md#within-a-group).
The `GET /groups/:id/registry/repositories` endpoint will remain, but won't return any info about tags. To get the info about tags, you can use the existing `GET /registry/repositories/:id` endpoint, which will continue to support the `tags` and `tag_count` options as it does today. The latter must be called once per image repository.
diff --git a/data/deprecations/14-5-remove-dependency-proxy-permissions-flag.yml b/data/deprecations/14-5-remove-dependency-proxy-permissions-flag.yml
index 098be766942..2229637f527 100644
--- a/data/deprecations/14-5-remove-dependency-proxy-permissions-flag.yml
+++ b/data/deprecations/14-5-remove-dependency-proxy-permissions-flag.yml
@@ -1,10 +1,10 @@
-- name: "`dependency_proxy_for_private_groups` feature flag" # The name of the feature to be deprecated
- announcement_milestone: "14.5" # The milestone when this feature was first announced as deprecated.
- announcement_date: "2021-11-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
- removal_milestone: "15.0" # The milestone when this feature is planned to be removed
- removal_date: "2022-05-22" # the date of the milestone release when this feature is planned to be removed
+- name: "`dependency_proxy_for_private_groups` feature flag" # The name of the feature to be deprecated
+ announcement_milestone: "14.5" # The milestone when this feature was first announced as deprecated.
+ announcement_date: "2021-11-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
+ removal_milestone: "15.0" # The milestone when this feature is planned to be removed
+ removal_date: "2022-05-22" # the date of the milestone release when this feature is planned to be removed
breaking_change: true
- body: | # Do not modify this line, instead modify the lines below.
+ body: | # Do not modify this line, instead modify the lines below.
We added a feature flag because [GitLab-#11582](https://gitlab.com/gitlab-org/gitlab/-/issues/11582) changed how public groups use the Dependency Proxy. Prior to this change, you could use the Dependency Proxy without authentication. The change requires authentication to use the Dependency Proxy.
In milestone 15.0, we will remove the feature flag entirely. Moving forward, you must authenticate when using the Dependency Proxy.
diff --git a/data/deprecations/14-5-remove-package-pipelines-api.yml b/data/deprecations/14-5-remove-package-pipelines-api.yml
index 46ef1213da8..392636f90a0 100644
--- a/data/deprecations/14-5-remove-package-pipelines-api.yml
+++ b/data/deprecations/14-5-remove-package-pipelines-api.yml
@@ -1,10 +1,10 @@
-- name: "Package pipelines in API payload is paginated" # The name of the feature to be deprecated
- announcement_milestone: "14.5" # The milestone when this feature was first announced as deprecated.
- announcement_date: "2021-11-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
- removal_milestone: "15.0" # The milestone when this feature is planned to be removed
- removal_date: "2022-05-22" # the date of the milestone release when this feature is planned to be removed
+- name: "Package pipelines in API payload is paginated" # The name of the feature to be deprecated
+ announcement_milestone: "14.5" # The milestone when this feature was first announced as deprecated.
+ announcement_date: "2021-11-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
+ removal_milestone: "15.0" # The milestone when this feature is planned to be removed
+ removal_date: "2022-05-22" # the date of the milestone release when this feature is planned to be removed
breaking_change: true
- body: | # Do not modify this line, instead modify the lines below.
+ body: | # Do not modify this line, instead modify the lines below.
A request to the API for `/api/v4/projects/:id/packages` returns a paginated result of packages. Each package lists all of its pipelines in this response. This is a performance concern, as it's possible for a package to have hundreds or thousands of associated pipelines.
In milestone 15.0, we will remove the `pipelines` attribute from the API response.
diff --git a/data/deprecations/14-5-remove-pipelines-from-version-field.yml b/data/deprecations/14-5-remove-pipelines-from-version-field.yml
index fc8ec519fa7..98174daa26c 100644
--- a/data/deprecations/14-5-remove-pipelines-from-version-field.yml
+++ b/data/deprecations/14-5-remove-pipelines-from-version-field.yml
@@ -1,10 +1,10 @@
-- name: "`pipelines` field from the `version` field" # The name of the feature to be deprecated
- announcement_milestone: "14.5" # The milestone when this feature was first announced as deprecated.
- announcement_date: "2021-11-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
- removal_milestone: "15.0" # The milestone when this feature is planned to be removed
- removal_date: "2022-05-22" # The date of the milestone release when this feature is planned to be removed
+- name: "`pipelines` field from the `version` field" # The name of the feature to be deprecated
+ announcement_milestone: "14.5" # The milestone when this feature was first announced as deprecated.
+ announcement_date: "2021-11-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
+ removal_milestone: "15.0" # The milestone when this feature is planned to be removed
+ removal_date: "2022-05-22" # The date of the milestone release when this feature is planned to be removed
breaking_change: true
- body: | # Do not modify this line, instead modify the lines below.
+ body: | # Do not modify this line, instead modify the lines below.
In GraphQL, there are two `pipelines` fields that you can use in a [`PackageDetailsType`](https://docs.gitlab.com/ee/api/graphql/reference/#packagedetailstype) to get the pipelines for package versions:
- The `versions` field's `pipelines` field. This returns all the pipelines associated with all the package's versions, which can pull an unbounded number of objects in memory and create performance concerns.
diff --git a/data/deprecations/14-5-runner-api-status-does-contain-paused.yml b/data/deprecations/14-5-runner-api-status-does-contain-paused.yml
index c3fbe553706..46f1ef89b53 100644
--- a/data/deprecations/14-5-runner-api-status-does-contain-paused.yml
+++ b/data/deprecations/14-5-runner-api-status-does-contain-paused.yml
@@ -1,10 +1,10 @@
- name: "REST and GraphQL API Runner status will not return `paused`"
- announcement_milestone: "14.5" # The milestone when this feature was first announced as deprecated.
+ announcement_milestone: "14.5" # The milestone when this feature was first announced as deprecated.
announcement_date: "2021-11-22"
- removal_milestone: "15.0" # the milestone when this feature is planned to be removed
- removal_date: "2022-05-22" # the date of the milestone release when this feature is planned to be removed
+ removal_milestone: "15.0" # the milestone when this feature is planned to be removed
+ removal_date: "2022-05-22" # the date of the milestone release when this feature is planned to be removed
breaking_change: true
- body: | # Do not modify this line, instead modify the lines below.
+ body: | # Do not modify this line, instead modify the lines below.
The GitLab Runner REST and GraphQL API endpoints will not return `paused` or `active` as a status in GitLab 15.0.
A runner's status will only relate to runner contact status, such as:
diff --git a/data/deprecations/14-5-runner-s3-authenticationtype-nonexplicit-config-deprecation.yml b/data/deprecations/14-5-runner-s3-authenticationtype-nonexplicit-config-deprecation.yml
index d957b79e450..7026438f649 100644
--- a/data/deprecations/14-5-runner-s3-authenticationtype-nonexplicit-config-deprecation.yml
+++ b/data/deprecations/14-5-runner-s3-authenticationtype-nonexplicit-config-deprecation.yml
@@ -1,10 +1,10 @@
- name: "Must explicitly assign `AuthenticationType` for `[runners.cache.s3]`"
- announcement_milestone: "14.5" # The milestone when this feature was first announced as deprecated.
+ announcement_milestone: "14.5" # The milestone when this feature was first announced as deprecated.
announcement_date: "2021-11-22"
- removal_milestone: "15.0" # the milestone when this feature is planned to be removed
- removal_date: "2022-05-22" # the date of the milestone release when this feature is planned to be removed
+ removal_milestone: "15.0" # the milestone when this feature is planned to be removed
+ removal_date: "2022-05-22" # the date of the milestone release when this feature is planned to be removed
breaking_change: true
- body: | # Do not modify this line, instead modify the lines below.
+ body: | # Do not modify this line, instead modify the lines below.
In GitLab 15.0 and later, to access the AWS S3 cache, you must specify the `AuthenticationType` for [`[runners.cache.s3]`](https://docs.gitlab.com/runner/configuration/advanced-configuration.html#the-runnerscaches3-section). The `AuthenticationType` must be `IAM` or `credentials`.
Prior to 14.5, if you did not define the `AuthenticationType`, GitLab Runner chose a type for you.
diff --git a/data/deprecations/14-6-Enforce-validation-of-security-schemas.yml b/data/deprecations/14-6-Enforce-validation-of-security-schemas.yml
index 42de723ee99..b80fd45239e 100644
--- a/data/deprecations/14-6-Enforce-validation-of-security-schemas.yml
+++ b/data/deprecations/14-6-Enforce-validation-of-security-schemas.yml
@@ -1,9 +1,9 @@
-- name: "Enforced validation of security report schemas" # The name of the feature to be deprecated
- announcement_milestone: "14.7" # The milestone when this feature was first announced as deprecated.
- announcement_date: "2022-01-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
- removal_milestone: "15.0" # The milestone when this feature is planned to be removed
- removal_date: "2022-05-22" # the date of the milestone release when this feature is planned to be removed
- body: | # Do not modify this line, instead modify the lines below.
+- name: "Enforced validation of security report schemas" # The name of the feature to be deprecated
+ announcement_milestone: "14.7" # The milestone when this feature was first announced as deprecated.
+ announcement_date: "2022-01-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
+ removal_milestone: "15.0" # The milestone when this feature is planned to be removed
+ removal_date: "2022-05-22" # the date of the milestone release when this feature is planned to be removed
+ body: | # Do not modify this line, instead modify the lines below.
[Security report schemas](https://gitlab.com/gitlab-org/security-products/security-report-schemas/-/releases)
versions earlier than 14.0.0 will no longer be supported in GitLab 15.0. Reports that do not pass validation
against the schema version declared in the report will also no longer be supported in GitLab 15.0.
@@ -18,9 +18,9 @@
[warning](https://gitlab.com/gitlab-org/gitlab/-/issues/335789#note_672853791)
in the Vulnerability Report.
# The following items are not published on the docs page, but may be used in the future.
- stage: Secure # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
- tiers: [Core, Premium, Ultimate] # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
- issue_url: https://gitlab.com/groups/gitlab-org/-/epics/6968 # (optional) This is a link to the deprecation issue in GitLab
- documentation_url: # (optional) This is a link to the current documentation page
- image_url: # (optional) This is a link to a thumbnail image depicting the feature
- video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
+ stage: Secure # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
+ tiers: [Core, Premium, Ultimate] # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
+ issue_url: https://gitlab.com/groups/gitlab-org/-/epics/6968 # (optional) This is a link to the deprecation issue in GitLab
+ documentation_url: # (optional) This is a link to the current documentation page
+ image_url: # (optional) This is a link to a thumbnail image depicting the feature
+ video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
diff --git a/data/deprecations/14-6-container-scanning-schemas-below-14.yml b/data/deprecations/14-6-container-scanning-schemas-below-14.yml
index b79418d5765..9427c9f0e88 100644
--- a/data/deprecations/14-6-container-scanning-schemas-below-14.yml
+++ b/data/deprecations/14-6-container-scanning-schemas-below-14.yml
@@ -1,9 +1,9 @@
-- name: "Container scanning schemas below 14.0.0" # The name of the feature to be deprecated
- announcement_milestone: "14.7" # The milestone when this feature was first announced as deprecated.
- announcement_date: "2022-01-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
- removal_milestone: "15.0" # The milestone when this feature is planned to be removed
- removal_date: "2022-05-22" # the date of the milestone release when this feature is planned to be removed
- body: | # Do not modify this line, instead modify the lines below.
+- name: "Container scanning schemas below 14.0.0" # The name of the feature to be deprecated
+ announcement_milestone: "14.7" # The milestone when this feature was first announced as deprecated.
+ announcement_date: "2022-01-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
+ removal_milestone: "15.0" # The milestone when this feature is planned to be removed
+ removal_date: "2022-05-22" # the date of the milestone release when this feature is planned to be removed
+ body: | # Do not modify this line, instead modify the lines below.
[Container scanning report schemas](https://gitlab.com/gitlab-org/security-products/security-report-schemas/-/releases)
versions earlier than 14.0.0 will no longer be supported in GitLab 15.0. Reports that do not pass validation
against the schema version declared in the report will also no longer be supported in GitLab 15.0.
@@ -15,9 +15,9 @@
[warning](https://gitlab.com/gitlab-org/gitlab/-/issues/335789#note_672853791)
in the Vulnerability Report.
# The following items are not published on the docs page, but may be used in the future.
- stage: # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
- tiers: # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
- issue_url: # (optional) This is a link to the deprecation issue in GitLab
- documentation_url: # (optional) This is a link to the current documentation page
- image_url: # (optional) This is a link to a thumbnail image depicting the feature
- video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
+ stage: # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
+ tiers: # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
+ issue_url: # (optional) This is a link to the deprecation issue in GitLab
+ documentation_url: # (optional) This is a link to the current documentation page
+ image_url: # (optional) This is a link to a thumbnail image depicting the feature
+ video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
diff --git a/data/deprecations/14-6-coverage-fuzzing-schemas-below-14.yml b/data/deprecations/14-6-coverage-fuzzing-schemas-below-14.yml
index 13babcc26ba..78d076294ed 100644
--- a/data/deprecations/14-6-coverage-fuzzing-schemas-below-14.yml
+++ b/data/deprecations/14-6-coverage-fuzzing-schemas-below-14.yml
@@ -1,9 +1,9 @@
-- name: "Coverage guided fuzzing schemas below 14.0.0" # The name of the feature to be deprecated
- announcement_milestone: "14.7" # The milestone when this feature was first announced as deprecated.
- announcement_date: "2022-01-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
- removal_milestone: "15.0" # The milestone when this feature is planned to be removed
- removal_date: "2022-05-22" # the date of the milestone release when this feature is planned to be removed
- body: | # Do not modify this line, instead modify the lines below.
+- name: "Coverage guided fuzzing schemas below 14.0.0" # The name of the feature to be deprecated
+ announcement_milestone: "14.7" # The milestone when this feature was first announced as deprecated.
+ announcement_date: "2022-01-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
+ removal_milestone: "15.0" # The milestone when this feature is planned to be removed
+ removal_date: "2022-05-22" # the date of the milestone release when this feature is planned to be removed
+ body: | # Do not modify this line, instead modify the lines below.
[Coverage guided fuzzing report schemas](https://gitlab.com/gitlab-org/security-products/security-report-schemas/-/releases)
below version 14.0.0 will no longer be supported in GitLab 15.0. Reports that do not pass validation
against the schema version declared in the report will also no longer be supported in GitLab 15.0.
@@ -18,9 +18,9 @@
[warning](https://gitlab.com/gitlab-org/gitlab/-/issues/335789#note_672853791)
in the Vulnerability Report.
# The following items are not published on the docs page, but may be used in the future.
- stage: # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
- tiers: # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
- issue_url: # (optional) This is a link to the deprecation issue in GitLab
- documentation_url: # (optional) This is a link to the current documentation page
- image_url: # (optional) This is a link to a thumbnail image depicting the feature
- video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
+ stage: # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
+ tiers: # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
+ issue_url: # (optional) This is a link to the deprecation issue in GitLab
+ documentation_url: # (optional) This is a link to the current documentation page
+ image_url: # (optional) This is a link to a thumbnail image depicting the feature
+ video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
diff --git a/data/deprecations/14-6-dast-schemas-below-14.yml b/data/deprecations/14-6-dast-schemas-below-14.yml
index afd27a1fa7a..305cf9469f9 100644
--- a/data/deprecations/14-6-dast-schemas-below-14.yml
+++ b/data/deprecations/14-6-dast-schemas-below-14.yml
@@ -1,9 +1,9 @@
-- name: "DAST schemas below 14.0.0" # The name of the feature to be deprecated
- announcement_milestone: "14.7" # The milestone when this feature was first announced as deprecated.
- announcement_date: "2022-01-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
- removal_milestone: "15.0" # The milestone when this feature is planned to be removed
- removal_date: "2022-05-22" # the date of the milestone release when this feature is planned to be removed
- body: | # Do not modify this line, instead modify the lines below.
+- name: "DAST schemas below 14.0.0" # The name of the feature to be deprecated
+ announcement_milestone: "14.7" # The milestone when this feature was first announced as deprecated.
+ announcement_date: "2022-01-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
+ removal_milestone: "15.0" # The milestone when this feature is planned to be removed
+ removal_date: "2022-05-22" # the date of the milestone release when this feature is planned to be removed
+ body: | # Do not modify this line, instead modify the lines below.
[DAST report schemas](https://gitlab.com/gitlab-org/security-products/security-report-schemas/-/releases)
versions earlier than 14.0.0 will no longer be supported in GitLab 15.0. Reports that do not pass validation
against the schema version declared in the report will also no longer be supported as of GitLab 15.0.
@@ -18,9 +18,9 @@
[warning to be displayed](https://gitlab.com/gitlab-org/gitlab/-/issues/335789#note_672853791)
in the Vulnerability Report.
# The following items are not published on the docs page, but may be used in the future.
- stage: # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
- tiers: # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
- issue_url: # (optional) This is a link to the deprecation issue in GitLab
- documentation_url: # (optional) This is a link to the current documentation page
- image_url: # (optional) This is a link to a thumbnail image depicting the feature
- video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
+ stage: # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
+ tiers: # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
+ issue_url: # (optional) This is a link to the deprecation issue in GitLab
+ documentation_url: # (optional) This is a link to the current documentation page
+ image_url: # (optional) This is a link to a thumbnail image depicting the feature
+ video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
diff --git a/data/deprecations/14-6-dependency-scanning-schemas-below-14.yml b/data/deprecations/14-6-dependency-scanning-schemas-below-14.yml
index 226cffc3afc..f04130bc68f 100644
--- a/data/deprecations/14-6-dependency-scanning-schemas-below-14.yml
+++ b/data/deprecations/14-6-dependency-scanning-schemas-below-14.yml
@@ -1,9 +1,9 @@
-- name: "Dependency scanning schemas below 14.0.0" # The name of the feature to be deprecated
- announcement_milestone: "14.7" # The milestone when this feature was first announced as deprecated.
- announcement_date: "2022-01-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
- removal_milestone: "15.0" # The milestone when this feature is planned to be removed
- removal_date: "2022-05-22" # the date of the milestone release when this feature is planned to be removed
- body: | # Do not modify this line, instead modify the lines below.
+- name: "Dependency scanning schemas below 14.0.0" # The name of the feature to be deprecated
+ announcement_milestone: "14.7" # The milestone when this feature was first announced as deprecated.
+ announcement_date: "2022-01-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
+ removal_milestone: "15.0" # The milestone when this feature is planned to be removed
+ removal_date: "2022-05-22" # the date of the milestone release when this feature is planned to be removed
+ body: | # Do not modify this line, instead modify the lines below.
[Dependency scanning report schemas](https://gitlab.com/gitlab-org/security-products/security-report-schemas/-/releases)
versions earlier than 14.0.0 will no longer be supported in GitLab 15.0. Reports that do not pass validation
against the schema version declared in the report will also no longer be supported as of GitLab 15.0.
@@ -18,9 +18,9 @@
[warning to be displayed](https://gitlab.com/gitlab-org/gitlab/-/issues/335789#note_672853791)
in the Vulnerability Report.
# The following items are not published on the docs page, but may be used in the future.
- stage: # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
- tiers: # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
- issue_url: # (optional) This is a link to the deprecation issue in GitLab
- documentation_url: # (optional) This is a link to the current documentation page
- image_url: # (optional) This is a link to a thumbnail image depicting the feature
- video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
+ stage: # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
+ tiers: # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
+ issue_url: # (optional) This is a link to the deprecation issue in GitLab
+ documentation_url: # (optional) This is a link to the current documentation page
+ image_url: # (optional) This is a link to a thumbnail image depicting the feature
+ video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
diff --git a/data/deprecations/14-6-deprecate-types.yml b/data/deprecations/14-6-deprecate-types.yml
index f8886eeef37..3db9f574d38 100644
--- a/data/deprecations/14-6-deprecate-types.yml
+++ b/data/deprecations/14-6-deprecate-types.yml
@@ -1,15 +1,15 @@
-- name: "`type` and `types` keyword in CI/CD configuration" # The name of the feature to be deprecated
- announcement_milestone: "14.6" # The milestone when this feature was first announced as deprecated.
- announcement_date: "2021-12-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
- removal_milestone: "15.0" # The milestone when this feature is planned to be removed
- removal_date: "2022-05-22" # the date of the milestone release when this feature is planned to be removed
+- name: "`type` and `types` keyword in CI/CD configuration" # The name of the feature to be deprecated
+ announcement_milestone: "14.6" # The milestone when this feature was first announced as deprecated.
+ announcement_date: "2021-12-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
+ removal_milestone: "15.0" # The milestone when this feature is planned to be removed
+ removal_date: "2022-05-22" # the date of the milestone release when this feature is planned to be removed
breaking_change: true
- body: | # Do not modify this line, instead modify the lines below.
+ body: | # Do not modify this line, instead modify the lines below.
The `type` and `types` CI/CD keywords will be removed in GitLab 15.0. Pipelines that use these keywords will stop working, so you must switch to `stage` and `stages`, which have the same behavior.
# The following items are not published on the docs page, but may be used in the future.
- stage: # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
- tiers: # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
- issue_url: # (optional) This is a link to the deprecation issue in GitLab
- documentation_url: # (optional) This is a link to the current documentation page
- image_url: # (optional) This is a link to a thumbnail image depicting the feature
- video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
+ stage: # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
+ tiers: # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
+ issue_url: # (optional) This is a link to the deprecation issue in GitLab
+ documentation_url: # (optional) This is a link to the current documentation page
+ image_url: # (optional) This is a link to a thumbnail image depicting the feature
+ video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
diff --git a/data/deprecations/14-6-deprecation-license-compliance-api-terms.yml b/data/deprecations/14-6-deprecation-license-compliance-api-terms.yml
index e09205f2d9b..344d1a04a4b 100644
--- a/data/deprecations/14-6-deprecation-license-compliance-api-terms.yml
+++ b/data/deprecations/14-6-deprecation-license-compliance-api-terms.yml
@@ -1,17 +1,17 @@
-- name: "Legacy approval status names from License Compliance API" # The name of the feature to be deprecated
- announcement_milestone: "14.6" # The milestone when this feature was first announced as deprecated.
- announcement_date: "2021-12-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
- removal_milestone: "15.0" # The milestone when this feature is planned to be removed
+- name: "Legacy approval status names from License Compliance API" # The name of the feature to be deprecated
+ announcement_milestone: "14.6" # The milestone when this feature was first announced as deprecated.
+ announcement_date: "2021-12-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
+ removal_milestone: "15.0" # The milestone when this feature is planned to be removed
breaking_change: true
- body: | # Do not modify this line, instead modify the lines below.
+ body: | # Do not modify this line, instead modify the lines below.
We deprecated legacy names for approval status of license policy (blacklisted, approved) in the `managed_licenses` API but they are still used in our API queries and responses. They will be removed in 15.0.
If you are using our License Compliance API you should stop using the `approved` and `blacklisted` query parameters, they are now `allowed` and `denied`. In 15.0 the responses will also stop using `approved` and `blacklisted` so you need to adjust any of your custom tools to use the old and new values so they do not break with the 15.0 release.
# The following items are not published on the docs page, but may be used in the future.
- stage: secure # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
- tiers: ultimate # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
- issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/335707 # (optional) This is a link to the deprecation issue in GitLab
- documentation_url: # (optional) This is a link to the current documentation page
- image_url: # (optional) This is a link to a thumbnail image depicting the feature
- video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
- removal_date: "2022-05-22" # (optional - may be required in the future) YYYY-MM-DD format. This should almost always be the 22nd of a month (YYYY-MM-22), the date of the milestone release when this feature is planned to be removed
+ stage: secure # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
+ tiers: ultimate # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
+ issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/335707 # (optional) This is a link to the deprecation issue in GitLab
+ documentation_url: # (optional) This is a link to the current documentation page
+ image_url: # (optional) This is a link to a thumbnail image depicting the feature
+ video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
+ removal_date: "2022-05-22" # (optional - may be required in the future) YYYY-MM-DD format. This should almost always be the 22nd of a month (YYYY-MM-22), the date of the milestone release when this feature is planned to be removed
diff --git a/data/deprecations/14-6-deprecation-secure-dependency-scanning-bundler-audit.yml b/data/deprecations/14-6-deprecation-secure-dependency-scanning-bundler-audit.yml
index 4f4a2ad8a7d..72039930348 100644
--- a/data/deprecations/14-6-deprecation-secure-dependency-scanning-bundler-audit.yml
+++ b/data/deprecations/14-6-deprecation-secure-dependency-scanning-bundler-audit.yml
@@ -1,17 +1,17 @@
-- name: "bundler-audit Dependency Scanning tool" # The name of the feature to be deprecated
- announcement_milestone: "14.6" # The milestone when this feature was first announced as deprecated.
- announcement_date: "2021-12-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
- removal_milestone: "15.0" # The milestone when this feature is planned to be removed
+- name: "bundler-audit Dependency Scanning tool" # The name of the feature to be deprecated
+ announcement_milestone: "14.6" # The milestone when this feature was first announced as deprecated.
+ announcement_date: "2021-12-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
+ removal_milestone: "15.0" # The milestone when this feature is planned to be removed
breaking_change: true
- body: | # Do not modify this line, instead modify the lines below.
+ body: | # Do not modify this line, instead modify the lines below.
As of 14.6 bundler-audit is being deprecated from Dependency Scanning. It will continue to be in our CI/CD template while deprecated. We are removing bundler-audit from Dependency Scanning on May 22, 2022 in 15.0. After this removal Ruby scanning functionality will not be affected as it is still being covered by Gemnasium.
If you have explicitly excluded bundler-audit using DS_EXCLUDED_ANALYZERS you will need to clean up (remove the reference) in 15.0. If you have customized your pipeline's Dependency Scanning configuration, for example to edit the `bundler-audit-dependency_scanning` job, you will want to switch to gemnasium-dependency_scanning before removal in 15.0, to prevent your pipeline from failing. If you have not used the DS_EXCLUDED_ANALYZERS to reference bundler-audit, or customized your template specifically for bundler-audit, you will not need to take action.
# The following items are not published on the docs page, but may be used in the future.
- stage: secure # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
- tiers: ultimate # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
- issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/289832 # (optional) This is a link to the deprecation issue in GitLab
- documentation_url: https://docs.gitlab.com/ee/user/application_security/dependency_scanning/analyzers.html # (optional) This is a link to the current documentation page
- image_url: # (optional) This is a link to a thumbnail image depicting the feature
- video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
- removal_date: "2022-05-22" # (optional - may be required in the future) YYYY-MM-DD format. This should almost always be the 22nd of a month (YYYY-MM-22), the date of the milestone release when this feature is planned to be removed
+ stage: secure # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
+ tiers: ultimate # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
+ issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/289832 # (optional) This is a link to the deprecation issue in GitLab
+ documentation_url: https://docs.gitlab.com/ee/user/application_security/dependency_scanning/analyzers.html # (optional) This is a link to the current documentation page
+ image_url: # (optional) This is a link to a thumbnail image depicting the feature
+ video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
+ removal_date: "2022-05-22" # (optional - may be required in the future) YYYY-MM-DD format. This should almost always be the 22nd of a month (YYYY-MM-22), the date of the milestone release when this feature is planned to be removed
diff --git a/data/deprecations/14-6-job_char_limit.yml b/data/deprecations/14-6-job_char_limit.yml
index 6570b1b8e81..ee3efafe9f6 100644
--- a/data/deprecations/14-6-job_char_limit.yml
+++ b/data/deprecations/14-6-job_char_limit.yml
@@ -1,15 +1,15 @@
-- name: "CI/CD job name length limit" # The name of the feature to be deprecated
- announcement_milestone: "14.6" # The milestone when this feature was first announced as deprecated.
- announcement_date: "2021-12-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
- removal_milestone: "15.0" # The milestone when this feature is planned to be removed
- removal_date: "2022-05-22" # (optional - may be required in the future) YYYY-MM-DD format - the date of the milestone release when this feature is planned to be removed
+- name: "CI/CD job name length limit" # The name of the feature to be deprecated
+ announcement_milestone: "14.6" # The milestone when this feature was first announced as deprecated.
+ announcement_date: "2021-12-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
+ removal_milestone: "15.0" # The milestone when this feature is planned to be removed
+ removal_date: "2022-05-22" # (optional - may be required in the future) YYYY-MM-DD format - the date of the milestone release when this feature is planned to be removed
breaking_change: true
- body: | # Do not modify this line, instead modify the lines below.
+ body: | # Do not modify this line, instead modify the lines below.
In GitLab 15.0 we are going to limit the number of characters in CI/CD job names to 255. Any pipeline with job names that exceed the 255 character limit will stop working after the 15.0 release.
# The following items are not published on the docs page, but may be used in the future.
- stage: # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
- tiers: # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
- issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/342800 # (optional) This is a link to the deprecation issue in GitLab
- documentation_url: # (optional) This is a link to the current documentation page
- image_url: # (optional) This is a link to a thumbnail image depicting the feature
- video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
+ stage: # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
+ tiers: # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
+ issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/342800 # (optional) This is a link to the deprecation issue in GitLab
+ documentation_url: # (optional) This is a link to the current documentation page
+ image_url: # (optional) This is a link to a thumbnail image depicting the feature
+ video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
diff --git a/data/deprecations/14-6-pipeline-fields-package-deprecation.yml b/data/deprecations/14-6-pipeline-fields-package-deprecation.yml
index 897886d2d0b..14892d2bbae 100644
--- a/data/deprecations/14-6-pipeline-fields-package-deprecation.yml
+++ b/data/deprecations/14-6-pipeline-fields-package-deprecation.yml
@@ -1,10 +1,10 @@
- name: "`pipelines` fields in the Package GraphQL types"
- announcement_milestone: "14.6" # The milestone when this feature was first announced as deprecated.
- announcement_date: "2021-12-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
- removal_milestone: "15.0" # The milestone when this feature is planned to be removed
- removal_date: "2022-05-22" # the date of the milestone release when this feature is planned to be removed
+ announcement_milestone: "14.6" # The milestone when this feature was first announced as deprecated.
+ announcement_date: "2021-12-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
+ removal_milestone: "15.0" # The milestone when this feature is planned to be removed
+ removal_date: "2022-05-22" # the date of the milestone release when this feature is planned to be removed
breaking_change: true
- body: | # Do not modify this line, instead modify the lines below.
+ body: | # Do not modify this line, instead modify the lines below.
As part of the work to create a [Package Registry GraphQL API](https://gitlab.com/groups/gitlab-org/-/epics/6318), the Package group deprecated the `pipelines` fields in all Package-related GraphQL types. As of GitLab 14.6, the `pipelines` field is deprecated in [`Package`](https://docs.gitlab.com/ee/api/graphql/reference/index.html#package) and [`PackageDetailsType`](https://docs.gitlab.com/ee/api/graphql/reference/index.html#packagedetailstype) due to scalability and performance concerns.
In milestone 15.0, we will completely remove `pipelines` from `Package` and `PackageDetailsType`. You can follow and contribute to work on a replacement in the epic [GitLab-#7214](https://gitlab.com/groups/gitlab-org/-/epics/7214).
diff --git a/data/deprecations/14-6-runner-api-status-renames-not_connected.yml b/data/deprecations/14-6-runner-api-status-renames-not_connected.yml
index a535cfbf7a7..a2aba7cadbe 100644
--- a/data/deprecations/14-6-runner-api-status-renames-not_connected.yml
+++ b/data/deprecations/14-6-runner-api-status-renames-not_connected.yml
@@ -1,9 +1,9 @@
- name: "Runner status `not_connected` API value"
- announcement_milestone: "14.6" # The milestone when this feature was first announced as deprecated.
- removal_milestone: "15.0" # the milestone when this feature is planned to be removed
+ announcement_milestone: "14.6" # The milestone when this feature was first announced as deprecated.
+ removal_milestone: "15.0" # the milestone when this feature is planned to be removed
removal_date: "2022-05-22"
breaking_change: true
- body: | # Do not modify this line, instead modify the lines below.
+ body: | # Do not modify this line, instead modify the lines below.
The GitLab Runner REST and GraphQL [API](https://docs.gitlab.com/ee/api/runners.html#runners-api) endpoints
will return `never_contacted` instead of `not_connected` as the status values in 15.0.
diff --git a/data/deprecations/14-6-runner_api_new_stale_status_breaking_change.yml b/data/deprecations/14-6-runner_api_new_stale_status_breaking_change.yml
index 3cf6ed69354..0f21318d329 100644
--- a/data/deprecations/14-6-runner_api_new_stale_status_breaking_change.yml
+++ b/data/deprecations/14-6-runner_api_new_stale_status_breaking_change.yml
@@ -1,10 +1,10 @@
- name: "API: `stale` status returned instead of `offline` or `not_connected`"
- announcement_milestone: "14.6" # The milestone when this feature was first announced as deprecated.
+ announcement_milestone: "14.6" # The milestone when this feature was first announced as deprecated.
announcement_date: "2021-12-22"
- removal_milestone: "15.0" # the milestone when this feature is planned to be removed
+ removal_milestone: "15.0" # the milestone when this feature is planned to be removed
removal_date: "2022-05-22"
breaking_change: true
- body: | # Do not modify this line, instead modify the lines below.
+ body: | # Do not modify this line, instead modify the lines below.
A breaking change will occur for the Runner [API](https://docs.gitlab.com/ee/api/runners.html#runners-api) endpoints in 15.0.
Instead of the GitLab Runner API endpoints returning `offline` and `not_connected` for runners that have not contacted the GitLab instance in the past three months, the API endpoints will return the `stale` value, which was introduced in 14.6.
diff --git a/data/deprecations/14-6-sast-schemas-below-14.yml b/data/deprecations/14-6-sast-schemas-below-14.yml
index 02e112ec4b8..635eaa3624b 100644
--- a/data/deprecations/14-6-sast-schemas-below-14.yml
+++ b/data/deprecations/14-6-sast-schemas-below-14.yml
@@ -1,9 +1,9 @@
-- name: "SAST schemas below 14.0.0" # The name of the feature to be deprecated
- announcement_milestone: "14.7" # The milestone when this feature was first announced as deprecated.
- announcement_date: "2022-01-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
- removal_milestone: "15.0" # The milestone when this feature is planned to be removed
- removal_date: "2022-05-22" # the date of the milestone release when this feature is planned to be removed
- body: | # Do not modify this line, instead modify the lines below.
+- name: "SAST schemas below 14.0.0" # The name of the feature to be deprecated
+ announcement_milestone: "14.7" # The milestone when this feature was first announced as deprecated.
+ announcement_date: "2022-01-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
+ removal_milestone: "15.0" # The milestone when this feature is planned to be removed
+ removal_date: "2022-05-22" # the date of the milestone release when this feature is planned to be removed
+ body: | # Do not modify this line, instead modify the lines below.
[SAST report schemas](https://gitlab.com/gitlab-org/security-products/security-report-schemas/-/releases)
versions earlier than 14.0.0 will no longer be supported in GitLab 15.0. Reports that do not pass validation
against the schema version declared in the report will also no longer be supported as of GitLab 15.0.
@@ -18,9 +18,9 @@
[warning](https://gitlab.com/gitlab-org/gitlab/-/issues/335789#note_672853791)
in the Vulnerability Report.
# The following items are not published on the docs page, but may be used in the future.
- stage: # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
- tiers: # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
- issue_url: # (optional) This is a link to the deprecation issue in GitLab
- documentation_url: # (optional) This is a link to the current documentation page
- image_url: # (optional) This is a link to a thumbnail image depicting the feature
- video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
+ stage: # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
+ tiers: # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
+ issue_url: # (optional) This is a link to the deprecation issue in GitLab
+ documentation_url: # (optional) This is a link to the current documentation page
+ image_url: # (optional) This is a link to a thumbnail image depicting the feature
+ video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
diff --git a/data/deprecations/14-6-secret-detection-schemas-below-14.yml b/data/deprecations/14-6-secret-detection-schemas-below-14.yml
index d366e08a8c0..16af233df44 100644
--- a/data/deprecations/14-6-secret-detection-schemas-below-14.yml
+++ b/data/deprecations/14-6-secret-detection-schemas-below-14.yml
@@ -1,9 +1,9 @@
-- name: "Secret detection schemas below 14.0.0" # The name of the feature to be deprecated
- announcement_milestone: "14.7" # The milestone when this feature was first announced as deprecated.
- announcement_date: "2022-01-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
- removal_milestone: "15.0" # The milestone when this feature is planned to be removed
- removal_date: "2022-05-22" # the date of the milestone release when this feature is planned to be removed
- body: | # Do not modify this line, instead modify the lines below.
+- name: "Secret detection schemas below 14.0.0" # The name of the feature to be deprecated
+ announcement_milestone: "14.7" # The milestone when this feature was first announced as deprecated.
+ announcement_date: "2022-01-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
+ removal_milestone: "15.0" # The milestone when this feature is planned to be removed
+ removal_date: "2022-05-22" # the date of the milestone release when this feature is planned to be removed
+ body: | # Do not modify this line, instead modify the lines below.
[Secret detection report schemas](https://gitlab.com/gitlab-org/security-products/security-report-schemas/-/releases)
versions earlier than 14.0.0 will no longer be supported in GitLab 15.0. Reports that do not pass validation
against the schema version declared in the report will also no longer be supported as of GitLab 15.0.
@@ -18,9 +18,9 @@
[warning](https://gitlab.com/gitlab-org/gitlab/-/issues/335789#note_672853791)
in the Vulnerability Report.
# The following items are not published on the docs page, but may be used in the future.
- stage: # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
- tiers: # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
- issue_url: # (optional) This is a link to the deprecation issue in GitLab
- documentation_url: # (optional) This is a link to the current documentation page
- image_url: # (optional) This is a link to a thumbnail image depicting the feature
- video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
+ stage: # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
+ tiers: # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
+ issue_url: # (optional) This is a link to the deprecation issue in GitLab
+ documentation_url: # (optional) This is a link to the current documentation page
+ image_url: # (optional) This is a link to a thumbnail image depicting the feature
+ video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
diff --git a/data/deprecations/14-7-deprecate-godep-support-in-license-compliance.yml b/data/deprecations/14-7-deprecate-godep-support-in-license-compliance.yml
index cf986341884..9d0e2aa91dc 100644
--- a/data/deprecations/14-7-deprecate-godep-support-in-license-compliance.yml
+++ b/data/deprecations/14-7-deprecate-godep-support-in-license-compliance.yml
@@ -1,9 +1,9 @@
-- name: "Godep support in License Compliance" # The name of the feature to be deprecated
- announcement_milestone: "14.7" # The milestone when this feature was first announced as deprecated.
- announcement_date: "2022-01-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
- removal_milestone: "15.0" # The milestone when this feature is planned to be removed
- removal_date: "2022-05-22" # This should almost always be the 22nd of a month (YYYY-MM-22), the date of the milestone release when this feature is planned to be removed.
- body: | # Do not modify this line, instead modify the lines below.
+- name: "Godep support in License Compliance" # The name of the feature to be deprecated
+ announcement_milestone: "14.7" # The milestone when this feature was first announced as deprecated.
+ announcement_date: "2022-01-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
+ removal_milestone: "15.0" # The milestone when this feature is planned to be removed
+ removal_date: "2022-05-22" # This should almost always be the 22nd of a month (YYYY-MM-22), the date of the milestone release when this feature is planned to be removed.
+ body: | # Do not modify this line, instead modify the lines below.
The Godep dependency manager for Golang was deprecated in 2020 by Go and
has been replaced with Go modules.
To reduce our maintenance cost we are deprecating License Compliance for Godep projects as of 14.7
diff --git a/data/deprecations/14-7-deprecate-merged_by-api-field.yml b/data/deprecations/14-7-deprecate-merged_by-api-field.yml
index e2ecef1aa6a..0a84b118981 100644
--- a/data/deprecations/14-7-deprecate-merged_by-api-field.yml
+++ b/data/deprecations/14-7-deprecate-merged_by-api-field.yml
@@ -10,18 +10,18 @@
#
# Please delete this line and above before submitting your merge request.
-- name: "merged_by API field" # The name of the feature to be deprecated
- announcement_milestone: "14.7" # The milestone when this feature was first announced as deprecated.
- announcement_date: "2022-01-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
- removal_milestone: "15.0" # The milestone when this feature is planned to be removed
- removal_date: "2022-05-22" # the date of the milestone release when this feature is planned to be removed
- breaking_change: true # If this deprecation is a breaking change, set this value to true
- body: | # Do not modify this line, instead modify the lines below.
+- name: "merged_by API field" # The name of the feature to be deprecated
+ announcement_milestone: "14.7" # The milestone when this feature was first announced as deprecated.
+ announcement_date: "2022-01-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
+ removal_milestone: "15.0" # The milestone when this feature is planned to be removed
+ removal_date: "2022-05-22" # the date of the milestone release when this feature is planned to be removed
+ breaking_change: true # If this deprecation is a breaking change, set this value to true
+ body: | # Do not modify this line, instead modify the lines below.
The `merged_by` field in the [merge request API](https://docs.gitlab.com/ee/api/merge_requests.html#list-merge-requests) is being deprecated and will be removed in GitLab 15.0. This field is being replaced with the `merge_user` field (already present in GraphQL) which more correctly identifies who merged a merge request when performing actions (merge when pipeline succeeds, add to merge train) other than a simple merge.
# The following items are not published on the docs page, but may be used in the future.
- stage: create # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
- tiers: # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
- issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/350534 # (optional) This is a link to the deprecation issue in GitLab
- documentation_url: # (optional) This is a link to the current documentation page
- image_url: # (optional) This is a link to a thumbnail image depicting the feature
- video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
+ stage: create # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
+ tiers: # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
+ issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/350534 # (optional) This is a link to the deprecation issue in GitLab
+ documentation_url: # (optional) This is a link to the current documentation page
+ image_url: # (optional) This is a link to a thumbnail image depicting the feature
+ video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
diff --git a/data/deprecations/14-7-deprecate-static-site-editor.yml b/data/deprecations/14-7-deprecate-static-site-editor.yml
index e522699e823..18f2ec26645 100644
--- a/data/deprecations/14-7-deprecate-static-site-editor.yml
+++ b/data/deprecations/14-7-deprecate-static-site-editor.yml
@@ -1,14 +1,14 @@
-- name: "Static Site Editor" # The name of the feature to be deprecated
- announcement_milestone: "14.7" # The milestone when this feature was first announced as deprecated.
- announcement_date: "2022-01-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
- removal_milestone: "15.0" # The milestone when this feature is planned to be removed
- removal_date: "2022-05-22" # This should almost always be the 22nd of a month (YYYY-MM-22), the date of the milestone release when this feature is planned to be removed.
- body: | # Do not modify this line, instead modify the lines below.
+- name: "Static Site Editor" # The name of the feature to be deprecated
+ announcement_milestone: "14.7" # The milestone when this feature was first announced as deprecated.
+ announcement_date: "2022-01-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
+ removal_milestone: "15.0" # The milestone when this feature is planned to be removed
+ removal_date: "2022-05-22" # This should almost always be the 22nd of a month (YYYY-MM-22), the date of the milestone release when this feature is planned to be removed.
+ body: | # Do not modify this line, instead modify the lines below.
The Static Site Editor will no longer be available starting in GitLab 15.0. Improvements to the Markdown editing experience across GitLab will deliver smiliar benefit but with a wider reach. Incoming requests to the Static Site Editor will be redirected to the Web IDE. Current users of the Static Site Editor can view the [documentation](https://docs.gitlab.com/ee/user/project/static_site_editor/) for more information, including how to remove the configuration files from existing projects.
# The following items are not published on the docs page, but may be used in the future.
- stage: Create # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
- tiers: [Free, Premium, Ultimate] # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
- issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/347137 # (optional) This is a link to the deprecation issue in GitLab
- documentation_url: https://docs.gitlab.com/ee/user/project/static_site_editor/ # (optional) This is a link to the current documentation page
- image_url: # (optional) This is a link to a thumbnail image depicting the feature
- video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
+ stage: Create # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
+ tiers: [Free, Premium, Ultimate] # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
+ issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/347137 # (optional) This is a link to the deprecation issue in GitLab
+ documentation_url: https://docs.gitlab.com/ee/user/project/static_site_editor/ # (optional) This is a link to the current documentation page
+ image_url: # (optional) This is a link to a thumbnail image depicting the feature
+ video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
diff --git a/data/deprecations/14-7-pseudonymizer.yml b/data/deprecations/14-7-pseudonymizer.yml
index bd8cb215496..f278cd506e2 100644
--- a/data/deprecations/14-7-pseudonymizer.yml
+++ b/data/deprecations/14-7-pseudonymizer.yml
@@ -1,9 +1,9 @@
-- name: "Pseudonymizer" # The name of the feature to be deprecated
- announcement_milestone: "14.7" # The milestone when this feature was first announced as deprecated.
- announcement_date: "2022-01-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
- removal_milestone: "15.0" # The milestone when this feature is planned to be removed
- removal_date: "2022-05-22" # This should almost always be the 22nd of a month (YYYY-MM-22), the date of the milestone release when this feature is planned to be removed.
- body: | # Do not modify this line, instead modify the lines below.
+- name: "Pseudonymizer" # The name of the feature to be deprecated
+ announcement_milestone: "14.7" # The milestone when this feature was first announced as deprecated.
+ announcement_date: "2022-01-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
+ removal_milestone: "15.0" # The milestone when this feature is planned to be removed
+ removal_date: "2022-05-22" # This should almost always be the 22nd of a month (YYYY-MM-22), the date of the milestone release when this feature is planned to be removed.
+ body: | # Do not modify this line, instead modify the lines below.
The Pseudonymizer feature is generally unused,
can cause production issues with large databases,
and can interfere with object storage development.
diff --git a/data/deprecations/14-7-sidekiq-metrics-health-check-donfig.yml b/data/deprecations/14-7-sidekiq-metrics-health-check-donfig.yml
index 34c262b1539..1faec65e9ef 100644
--- a/data/deprecations/14-7-sidekiq-metrics-health-check-donfig.yml
+++ b/data/deprecations/14-7-sidekiq-metrics-health-check-donfig.yml
@@ -4,7 +4,7 @@
removal_milestone: "15.0"
removal_date: "2022-05-22"
breaking_change: true
- body: | # Do not modify this line, instead modify the lines below.
+ body: | # Do not modify this line, instead modify the lines below.
Exporting Sidekiq metrics and health checks using a single process and port is deprecated.
Support will be removed in 15.0.
diff --git a/data/deprecations/14-8-Elasticsearch-6-8.yml b/data/deprecations/14-8-Elasticsearch-6-8.yml
index 20f32966f24..28a25803d41 100644
--- a/data/deprecations/14-8-Elasticsearch-6-8.yml
+++ b/data/deprecations/14-8-Elasticsearch-6-8.yml
@@ -2,17 +2,16 @@
announcement_milestone: "14.8"
announcement_date: "2022-02-22"
removal_milestone: "15.0"
- removal_date: "2022-05-22"
- breaking_change: true
- body: |
+ removal_date: "2022-05-22"
+ breaking_change: true
+ body: |
Elasticsearch 6.8 is deprecated in GitLab 14.8 and scheduled for removal in GitLab 15.0.
Customers using Elasticsearch 6.8 need to upgrade their Elasticsearch version to 7.x prior to upgrading to GitLab 15.0.
We recommend using the latest version of Elasticsearch 7 to benefit from all Elasticsearch improvements.
Elasticsearch 6.8 is also incompatible with Amazon OpenSearch, which we [plan to support in GitLab 15.0](https://gitlab.com/gitlab-org/gitlab/-/issues/327560).
- stage: Enablement
- tiers: [Premium, Ultimate]
+ stage: Enablement
+ tiers: [Premium, Ultimate]
issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/350275
documentation_url: https://docs.gitlab.com/ee/integration/elasticsearch.html#version-requirements
-
diff --git a/data/deprecations/14-8-compliance-required-pipeline-configuration-premium.yml b/data/deprecations/14-8-compliance-required-pipeline-configuration-premium.yml
index 73ba7d8011a..104dbc5f72d 100644
--- a/data/deprecations/14-8-compliance-required-pipeline-configuration-premium.yml
+++ b/data/deprecations/14-8-compliance-required-pipeline-configuration-premium.yml
@@ -5,7 +5,7 @@
removal_date: "2022-05-22"
breaking_change: true
reporter: sam.white
- body: | # Do not modify this line, instead modify the lines below.
+ body: | # Do not modify this line, instead modify the lines below.
The [required pipeline configuration](https://docs.gitlab.com/ee/user/admin_area/settings/continuous_integration.html#required-pipeline-configuration) feature is deprecated in GitLab 14.8 for Premium customers and is scheduled for removal in GitLab 15.0. This feature is not deprecated for GitLab Ultimate customers.
This change to move the feature to GitLab's Ultimate tier is intended to help our features better align with our [pricing philosophy](https://about.gitlab.com/company/pricing/#three-tiers) as we see demand for this feature originating primarily from executives.
diff --git a/data/deprecations/14-8-compliance-status-check-api-field.yml b/data/deprecations/14-8-compliance-status-check-api-field.yml
index f32a8379481..5ad653c8fce 100644
--- a/data/deprecations/14-8-compliance-status-check-api-field.yml
+++ b/data/deprecations/14-8-compliance-status-check-api-field.yml
@@ -5,7 +5,7 @@
removal_date: "2022-05-22"
breaking_change: true
reporter: sam.white
- body: | # Do not modify this line, instead modify the lines below.
+ body: | # Do not modify this line, instead modify the lines below.
The [external status check API](https://docs.gitlab.com/ee/api/status_checks.html) was originally implemented to
support pass-by-default requests to mark a status check as passing. Pass-by-default requests are now deprecated.
Specifically, the following are deprecated:
diff --git a/data/deprecations/14-8-deprecate-projectFingerprint-from-PipelineSecurityReportFinding-GraphQL.yml b/data/deprecations/14-8-deprecate-projectFingerprint-from-PipelineSecurityReportFinding-GraphQL.yml
index ea75e70afe3..0638f86968a 100644
--- a/data/deprecations/14-8-deprecate-projectFingerprint-from-PipelineSecurityReportFinding-GraphQL.yml
+++ b/data/deprecations/14-8-deprecate-projectFingerprint-from-PipelineSecurityReportFinding-GraphQL.yml
@@ -2,7 +2,7 @@
announcement_milestone: "14.8" # The milestone when this feature was first announced as deprecated.
announcement_date: "2022-02-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
removal_milestone: "15.0" # The milestone when this feature is planned to be removed
- removal_date: "2022-05-22" # The date of the milestone release when this feature is planned to be removed. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
+ removal_date: "2022-05-22" # The date of the milestone release when this feature is planned to be removed. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
breaking_change: true # If this deprecation is a breaking change, set this value to true
reporter: matt_wilson # GitLab username of the person reporting the deprecation
body: | # Do not modify this line, instead modify the lines below.
diff --git a/data/deprecations/14-8-deprecation-secure-dependency-scanning-retire-js.yml b/data/deprecations/14-8-deprecation-secure-dependency-scanning-retire-js.yml
index a5e5ce6e9ea..3713ae532b3 100644
--- a/data/deprecations/14-8-deprecation-secure-dependency-scanning-retire-js.yml
+++ b/data/deprecations/14-8-deprecation-secure-dependency-scanning-retire-js.yml
@@ -1,17 +1,17 @@
-- name: "Retire-JS Dependency Scanning tool" # The name of the feature to be deprecated
- announcement_milestone: "14.8" # The milestone when this feature was first announced as deprecated.
- announcement_date: "2022-02-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
- removal_milestone: "15.0" # The milestone when this feature is planned to be removed
+- name: "Retire-JS Dependency Scanning tool" # The name of the feature to be deprecated
+ announcement_milestone: "14.8" # The milestone when this feature was first announced as deprecated.
+ announcement_date: "2022-02-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
+ removal_milestone: "15.0" # The milestone when this feature is planned to be removed
breaking_change: true
- body: | # Do not modify this line, instead modify the lines below.
+ body: | # Do not modify this line, instead modify the lines below.
As of 14.8 the retire.js job is being deprecated from Dependency Scanning. It will continue to be included in our CI/CD template while deprecated. We are removing retire.js from Dependency Scanning on May 22, 2022 in GitLab 15.0. JavaScript scanning functionality will not be affected as it is still being covered by Gemnasium.
If you have explicitly excluded retire.js using DS_EXCLUDED_ANALYZERS you will need to clean up (remove the reference) in 15.0. If you have customized your pipeline's Dependency Scanning configuration related to the `retire-js-dependency_scanning` job you will want to switch to gemnasium-dependency_scanning before the removal in 15.0, to prevent your pipeline from failing. If you have not used the DS_EXCLUDED_ANALYZERS to reference retire.js, or customized your template specifically for retire.js, you will not need to take action.
# The following items are not published on the docs page, but may be used in the future.
- stage: secure # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
- tiers: ultimate # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
- issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/350510 # (optional) This is a link to the deprecation issue in GitLab
- documentation_url: https://docs.gitlab.com/ee/user/application_security/dependency_scanning/analyzers.html # (optional) This is a link to the current documentation page
- image_url: # (optional) This is a link to a thumbnail image depicting the feature
- video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
- removal_date: "2022-05-22" # (optional - may be required in the future) YYYY-MM-DD format. This should almost always be the 22nd of a month (YYYY-MM-22), the date of the milestone release when this feature is planned to be removed
+ stage: secure # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
+ tiers: ultimate # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
+ issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/350510 # (optional) This is a link to the deprecation issue in GitLab
+ documentation_url: https://docs.gitlab.com/ee/user/application_security/dependency_scanning/analyzers.html # (optional) This is a link to the current documentation page
+ image_url: # (optional) This is a link to a thumbnail image depicting the feature
+ video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
+ removal_date: "2022-05-22" # (optional - may be required in the future) YYYY-MM-DD format. This should almost always be the 22nd of a month (YYYY-MM-22), the date of the milestone release when this feature is planned to be removed
diff --git a/data/deprecations/14-8-enforce-pat-expiration.yml b/data/deprecations/14-8-enforce-pat-expiration.yml
index 6c6fdf31fe6..bb5155984ef 100644
--- a/data/deprecations/14-8-enforce-pat-expiration.yml
+++ b/data/deprecations/14-8-enforce-pat-expiration.yml
@@ -1,13 +1,13 @@
-- name: "Optional enforcement of PAT expiration" # The name of the feature to be deprecated
- announcement_milestone: "14.8" # The milestone when this feature was first announced as deprecated.
- announcement_date: "2022-02-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
- removal_milestone: "15.0" # The milestone when this feature is planned to be removed
- removal_date: "2022-05-22" # The date of the milestone release when this feature is planned to be removed. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
- breaking_change: true # If this deprecation is a breaking change, set this value to true
- reporter: djensen # GitLab username of the person reporting the deprecation
- body: | # Do not modify this line, instead modify the lines below.
+- name: "Optional enforcement of PAT expiration" # The name of the feature to be deprecated
+ announcement_milestone: "14.8" # The milestone when this feature was first announced as deprecated.
+ announcement_date: "2022-02-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
+ removal_milestone: "15.0" # The milestone when this feature is planned to be removed
+ removal_date: "2022-05-22" # The date of the milestone release when this feature is planned to be removed. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
+ breaking_change: true # If this deprecation is a breaking change, set this value to true
+ reporter: djensen # GitLab username of the person reporting the deprecation
+ body: | # Do not modify this line, instead modify the lines below.
The feature to disable enforcement of PAT expiration is unusual from a security perspective.
We have become concerned that this unusual feature could create unexpected behavior for users.
Unexpected behavior in a security feature is inherently dangerous, so we have decided to remove this feature.
- issue_url: "https://gitlab.com/gitlab-org/gitlab/-/issues/351962" # (optional) This is a link to the deprecation issue in GitLab
- documentation_url: "https://docs.gitlab.com/ee/user/admin_area/settings/account_and_limit_settings.html#allow-expired-personal-access-tokens-to-be-used-deprecated" # (optional) This is a link to the current documentation page
+ issue_url: "https://gitlab.com/gitlab-org/gitlab/-/issues/351962" # (optional) This is a link to the deprecation issue in GitLab
+ documentation_url: "https://docs.gitlab.com/ee/user/admin_area/settings/account_and_limit_settings.html#allow-expired-personal-access-tokens-to-be-used-deprecated" # (optional) This is a link to the current documentation page
diff --git a/data/deprecations/14-8-enforce-ssh-expiration.yml b/data/deprecations/14-8-enforce-ssh-expiration.yml
index 815d592a2a9..2f8362001df 100644
--- a/data/deprecations/14-8-enforce-ssh-expiration.yml
+++ b/data/deprecations/14-8-enforce-ssh-expiration.yml
@@ -1,13 +1,13 @@
-- name: "Optional enforcement of SSH expiration" # The name of the feature to be deprecated
- announcement_milestone: "14.8" # The milestone when this feature was first announced as deprecated.
- announcement_date: "2022-02-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
- removal_milestone: "15.0" # The milestone when this feature is planned to be removed
- removal_date: "2022-05-22" # The date of the milestone release when this feature is planned to be removed. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
- breaking_change: true # If this deprecation is a breaking change, set this value to true
- reporter: djensen # GitLab username of the person reporting the deprecation
- body: | # Do not modify this line, instead modify the lines below.
+- name: "Optional enforcement of SSH expiration" # The name of the feature to be deprecated
+ announcement_milestone: "14.8" # The milestone when this feature was first announced as deprecated.
+ announcement_date: "2022-02-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
+ removal_milestone: "15.0" # The milestone when this feature is planned to be removed
+ removal_date: "2022-05-22" # The date of the milestone release when this feature is planned to be removed. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
+ breaking_change: true # If this deprecation is a breaking change, set this value to true
+ reporter: djensen # GitLab username of the person reporting the deprecation
+ body: | # Do not modify this line, instead modify the lines below.
The feature to disable enforcement of SSH expiration is unusual from a security perspective.
We have become concerned that this unusual feature could create unexpected behavior for users.
Unexpected behavior in a security feature is inherently dangerous, so we have decided to remove this feature.
- issue_url: "https://gitlab.com/gitlab-org/gitlab/-/issues/351963" # (optional) This is a link to the deprecation issue in GitLab
- documentation_url: "https://docs.gitlab.com/ee/user/admin_area/settings/account_and_limit_settings.html#allow-expired-ssh-keys-to-be-used-deprecated" # (optional) This is a link to the current documentation page
+ issue_url: "https://gitlab.com/gitlab-org/gitlab/-/issues/351963" # (optional) This is a link to the deprecation issue in GitLab
+ documentation_url: "https://docs.gitlab.com/ee/user/admin_area/settings/account_and_limit_settings.html#allow-expired-ssh-keys-to-be-used-deprecated" # (optional) This is a link to the current documentation page
diff --git a/data/deprecations/14-8-geo-deprecate-db-rake-tasks.yml b/data/deprecations/14-8-geo-deprecate-db-rake-tasks.yml
index 137ae01f63b..d38e579e3e6 100644
--- a/data/deprecations/14-8-geo-deprecate-db-rake-tasks.yml
+++ b/data/deprecations/14-8-geo-deprecate-db-rake-tasks.yml
@@ -2,7 +2,7 @@
announcement_milestone: "14.8"
announcement_date: "2022-02-22"
removal_milestone: "15.0"
- removal_date: "2022-05-22"
+ removal_date: "2022-05-22"
breaking_change: false
reporter: nhxnguyen
body: |
@@ -28,7 +28,7 @@
- `geo:db:test:purge` -> `db:test:purge:geo`
stage: "Enablement"
tiers: ["Premium", "Ultimate"]
- issue_url: "https://gitlab.com/gitlab-org/gitlab/-/issues/351945"
+ issue_url: "https://gitlab.com/gitlab-org/gitlab/-/issues/351945"
documentation_url: # (optional) This is a link to the current documentation page
image_url: # (optional) This is a link to a thumbnail image depicting the feature
video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
diff --git a/data/deprecations/14-8-geo-deprecate-replication-detail-routes.yml b/data/deprecations/14-8-geo-deprecate-replication-detail-routes.yml
index 94a026edd81..c28dc849f72 100644
--- a/data/deprecations/14-8-geo-deprecate-replication-detail-routes.yml
+++ b/data/deprecations/14-8-geo-deprecate-replication-detail-routes.yml
@@ -10,6 +10,6 @@
stage: "Enablement"
tiers: ["Premium", "Ultimate"]
issue_url: "https://gitlab.com/gitlab-org/gitlab/-/issues/351345"
- documentation_url: # (optional) This is a link to the current documentation page
- image_url: # (optional) This is a link to a thumbnail image depicting the feature
- video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
+ documentation_url: # (optional) This is a link to the current documentation page
+ image_url: # (optional) This is a link to a thumbnail image depicting the feature
+ video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
diff --git a/data/deprecations/14-8-gitaly-remove-per-repository-election.yml b/data/deprecations/14-8-gitaly-remove-per-repository-election.yml
index 334da51c4a0..7edaff9821f 100644
--- a/data/deprecations/14-8-gitaly-remove-per-repository-election.yml
+++ b/data/deprecations/14-8-gitaly-remove-per-repository-election.yml
@@ -2,7 +2,7 @@
announcement_milestone: "14.8" # The milestone when this feature was first announced as deprecated.
announcement_date: "2022-02-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
removal_milestone: "14.9" # The milestone when this feature is planned to be removed
- removal_date: "2022-03-22" # The date of the milestone release when this feature is planned to be removed. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
+ removal_date: "2022-03-22" # The date of the milestone release when this feature is planned to be removed. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
breaking_change: false # If this deprecation is a breaking change, set this value to true
reporter: mjwood # GitLab username of the person reporting the deprecation
body: | # Do not modify this line, instead modify the lines below.
@@ -13,7 +13,7 @@
# The following items are not published on the docs page, but may be used in the future.
stage: # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
tiers: # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
- issue_url: "https://gitlab.com/gitlab-org/gitlab/-/issues/352612" # (optional) This is a link to the deprecation issue in GitLab
+ issue_url: "https://gitlab.com/gitlab-org/gitlab/-/issues/352612" # (optional) This is a link to the deprecation issue in GitLab
documentation_url: # (optional) This is a link to the current documentation page
image_url: # (optional) This is a link to a thumbnail image depicting the feature
video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
diff --git a/data/deprecations/14-8-graphql-ids.yml b/data/deprecations/14-8-graphql-ids.yml
index dd73f310335..67ff418c51a 100644
--- a/data/deprecations/14-8-graphql-ids.yml
+++ b/data/deprecations/14-8-graphql-ids.yml
@@ -2,7 +2,7 @@
announcement_milestone: "14.8"
announcement_date: "2022-02-22"
removal_milestone: "15.0"
- removal_date: "2022-04-22"
+ removal_date: "2022-04-22"
breaking_change: true
reporter: alexkalderimis
body: | # Do not modify this line, instead modify the lines below.
@@ -52,7 +52,7 @@
}
}
```
-
+
This query works now, and will continue to work after GitLab 15.0.
You should convert any queries in the first form (using `ID` as a named type in the signature)
to one of the other two forms (using the correct appropriate type in the signature, or using
@@ -60,7 +60,7 @@
# The following items are not published on the docs page, but may be used in the future.
stage: # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
tiers: # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
- issue_url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/257883'
+ issue_url: 'https://gitlab.com/gitlab-org/gitlab/-/issues/257883'
documentation_url: # (optional) This is a link to the current documentation page
image_url: # (optional) This is a link to a thumbnail image depicting the feature
video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
diff --git a/data/deprecations/14-8-grpc-proxy.yml b/data/deprecations/14-8-grpc-proxy.yml
index 353c0abc901..1ec505fd216 100644
--- a/data/deprecations/14-8-grpc-proxy.yml
+++ b/data/deprecations/14-8-grpc-proxy.yml
@@ -2,7 +2,7 @@
announcement_milestone: "14.8" # The milestone when this feature was first announced as deprecated.
announcement_date: "2022-02-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
removal_milestone: "15.0" # The milestone when this feature is planned to be removed
- removal_date: 2022-05-22 # The date of the milestone release when this feature is planned to be removed. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
+ removal_date: "2022-05-22" # The date of the milestone release when this feature is planned to be removed. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
breaking_change: true # If this deprecation is a breaking change, set this value to true
reporter: jacobvosmaer-gitlab # GitLab username of the person reporting the deprecation
body: | # Do not modify this line, instead modify the lines below.
diff --git a/data/deprecations/14-8-iteration-started-field.yml b/data/deprecations/14-8-iteration-started-field.yml
index 590c9800db6..e323b93752b 100644
--- a/data/deprecations/14-8-iteration-started-field.yml
+++ b/data/deprecations/14-8-iteration-started-field.yml
@@ -1,15 +1,15 @@
-- name: "`started` iterations API field" # The name of the feature to be deprecated
- announcement_milestone: "14.8" # The milestone when this feature was first announced as deprecated.
- announcement_date: "2022-02-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
- removal_milestone: "15.0" # The milestone when this feature is planned to be removed
- removal_date: "2022-05-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
- breaking_change: true # If this deprecation is a breaking change, set this value to true
- body: | # Do not modify this line, instead modify the lines below.
+- name: "`started` iterations API field" # The name of the feature to be deprecated
+ announcement_milestone: "14.8" # The milestone when this feature was first announced as deprecated.
+ announcement_date: "2022-02-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
+ removal_milestone: "15.0" # The milestone when this feature is planned to be removed
+ removal_date: "2022-05-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
+ breaking_change: true # If this deprecation is a breaking change, set this value to true
+ body: | # Do not modify this line, instead modify the lines below.
The `started` field in the [iterations API](https://docs.gitlab.com/ee/api/iterations.html#list-project-iterations) is being deprecated and will be removed in GitLab 15.0. This field is being replaced with the `current` field (already available) which aligns with the naming for other time-based entities, such as milestones.
# The following items are not published on the docs page, but may be used in the future.
stage: plan
- tiers: # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
+ tiers: # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/334018
- documentation_url: # (optional) This is a link to the current documentation page
- image_url: # (optional) This is a link to a thumbnail image depicting the feature
- video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
+ documentation_url: # (optional) This is a link to the current documentation page
+ image_url: # (optional) This is a link to a thumbnail image depicting the feature
+ video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
diff --git a/data/deprecations/14-8-nfs_support.yml b/data/deprecations/14-8-nfs_support.yml
index 832b309e979..534975b0642 100644
--- a/data/deprecations/14-8-nfs_support.yml
+++ b/data/deprecations/14-8-nfs_support.yml
@@ -20,7 +20,7 @@
- [Distributed read capabilities](https://docs.gitlab.com/ee/administration/gitaly/#distributed-reads)
# The following items are not published on the docs page, but may be used in the future.
- stage: Gitaly # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
+ stage: Gitaly # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
tiers: # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
issue_url: # (optional) This is a link to the deprecation issue in GitLab
documentation_url: # (optional) This is a link to the current documentation page
diff --git a/data/deprecations/14-8-protect-cns-chs.yml b/data/deprecations/14-8-protect-cns-chs.yml
index b3a4cc8c1e8..8ea76d1b371 100644
--- a/data/deprecations/14-8-protect-cns-chs.yml
+++ b/data/deprecations/14-8-protect-cns-chs.yml
@@ -5,7 +5,7 @@
removal_date: "2022-05-22"
breaking_change: true
reporter: sam.white
- body: | # Do not modify this line, instead modify the lines below.
+ body: | # Do not modify this line, instead modify the lines below.
All functionality related to GitLab's Container Network Security and Container Host Security categories is deprecated in GitLab 14.8 and scheduled for removal in GitLab 15.0. Users who need a replacement for this functionality are encouraged to evaluate the following open source projects as potential solutions that can be installed and managed outside of GitLab: [AppArmor](https://gitlab.com/apparmor/apparmor), [Cilium](https://github.com/cilium/cilium), [Falco](https://github.com/falcosecurity/falco), [FluentD](https://github.com/fluent/fluentd), [Pod Security Admission](https://kubernetes.io/docs/concepts/security/pod-security-admission/). To integrate these technologies into GitLab, add the desired Helm charts into your copy of the [Cluster Management Project Template](https://docs.gitlab.com/ee/user/clusters/management_project_template.html). Deploy these Helm charts in production by calling commands through the GitLab [Secure CI/CD Tunnel](https://docs.gitlab.com/ee/user/clusters/agent/repository.html#run-kubectl-commands-using-the-cicd-tunnel).
As part of this change, the following specific capabilities within GitLab are now deprecated, and are scheduled for removal in GitLab 15.0:
diff --git a/data/deprecations/14-8-protect-vulnerability-check.yml b/data/deprecations/14-8-protect-vulnerability-check.yml
index 0f8fb44081a..ddb296886b2 100644
--- a/data/deprecations/14-8-protect-vulnerability-check.yml
+++ b/data/deprecations/14-8-protect-vulnerability-check.yml
@@ -5,7 +5,7 @@
removal_date: "2022-05-22"
breaking_change: true
reporter: sam.white
- body: | # Do not modify this line, instead modify the lines below.
+ body: | # Do not modify this line, instead modify the lines below.
The vulnerability check feature is deprecated in GitLab 14.8 and scheduled for removal in GitLab 15.0. We encourage you to migrate to the new security approvals feature instead. You can do so by navigating to **Security & Compliance > Policies** and creating a new Scan Result Policy.
The new security approvals feature is similar to vulnerability check. For example, both can require approvals for MRs that contain security vulnerabilities. However, security approvals improve the previous experience in several ways:
diff --git a/data/deprecations/14-8-remove-support-for-fixup-in-commit-message-triggering-draft-status.yml b/data/deprecations/14-8-remove-support-for-fixup-in-commit-message-triggering-draft-status.yml
index cda67e53b8e..f738b71f1b7 100644
--- a/data/deprecations/14-8-remove-support-for-fixup-in-commit-message-triggering-draft-status.yml
+++ b/data/deprecations/14-8-remove-support-for-fixup-in-commit-message-triggering-draft-status.yml
@@ -1,9 +1,9 @@
-- name: "`fixup!` commit messages setting draft status of associated Merge Request" # The name of the feature to be deprecated
- announcement_milestone: "14.8" # The milestone when this feature was first announced as deprecated.
- announcement_date: "2022-02-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
- removal_milestone: "15.0" # The milestone when this feature is planned to be removed
- removal_date: "2022-06-22" # This should almost always be the 22nd of a month (YYYY-MM-22), the date of the milestone release when this feature is planned to be removed.
- body: | # Do not modify this line, instead modify the lines below.
+- name: "`fixup!` commit messages setting draft status of associated Merge Request" # The name of the feature to be deprecated
+ announcement_milestone: "14.8" # The milestone when this feature was first announced as deprecated.
+ announcement_date: "2022-02-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
+ removal_milestone: "15.0" # The milestone when this feature is planned to be removed
+ removal_date: "2022-06-22" # This should almost always be the 22nd of a month (YYYY-MM-22), the date of the milestone release when this feature is planned to be removed.
+ body: | # Do not modify this line, instead modify the lines below.
The use of `fixup!` as a commit message to trigger draft status
of the associated Merge Request is generally unused, and can cause
confusion with other uses of the term. "Draft" is the preferred
diff --git a/data/deprecations/14-8-remove_ff_push_rules_supersede_code_owners.yml b/data/deprecations/14-8-remove_ff_push_rules_supersede_code_owners.yml
index b93b25c00d0..4029443cc76 100644
--- a/data/deprecations/14-8-remove_ff_push_rules_supersede_code_owners.yml
+++ b/data/deprecations/14-8-remove_ff_push_rules_supersede_code_owners.yml
@@ -2,15 +2,15 @@
announcement_milestone: "14.8" # The milestone when this feature was first announced as deprecated.
announcement_date: "2022-02-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
removal_milestone: "15.0" # The milestone when this feature is planned to be removed
- removal_date: "2022-05-22" # The date of the milestone release when this feature is planned to be removed. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
- breaking_change: true # If this deprecation is a breaking change, set this value to true
+ removal_date: "2022-05-22" # The date of the milestone release when this feature is planned to be removed. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
+ breaking_change: true # If this deprecation is a breaking change, set this value to true
reporter: sarahwaldner # GitLab username of the person reporting the deprecation
body: | # Do not modify this line, instead modify the lines below.
The feature flag `PUSH_RULES_SUPERSEDE_CODE_OWNERS` is being removed in GitLab 15.0. Upon its removal, push rules will supersede CODEOWNERS. The CODEOWNERS feature will no longer be available for access control.
# The following items are not published on the docs page, but may be used in the future.
- stage: create # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
+ stage: create # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
tiers: # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
- issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/262019 # (optional) This is a link to the deprecation issue in GitLab
+ issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/262019 # (optional) This is a link to the deprecation issue in GitLab
documentation_url: # (optional) This is a link to the current documentation page
image_url: # (optional) This is a link to a thumbnail image depicting the feature
video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
diff --git a/data/deprecations/14-8-request-profiling.yml b/data/deprecations/14-8-request-profiling.yml
index 8b549a6002f..82d2aadd149 100644
--- a/data/deprecations/14-8-request-profiling.yml
+++ b/data/deprecations/14-8-request-profiling.yml
@@ -1,11 +1,11 @@
- name: "Request profiling"
announcement_milestone: "14.8"
announcement_date: "2021-02-22"
- removal_milestone: "15.0"
+ removal_milestone: "15.0"
removal_date: "2022-05-22"
breaking_change: true
reporter: iroussos
- body: | # Do not modify this line, instead modify the lines below.
+ body: | # Do not modify this line, instead modify the lines below.
[Request profiling](https://docs.gitlab.com/ee/administration/monitoring/performance/request_profiling.html) is deprecated in GitLab 14.8 and scheduled for removal in GitLab 15.0.
We're working on [consolidating our profiling tools](https://gitlab.com/groups/gitlab-org/-/epics/7327) and making them more easily accessible.
diff --git a/data/deprecations/14-8-runner-api-active-field-replaced-with-paused-breaking-change.yml b/data/deprecations/14-8-runner-api-active-field-replaced-with-paused-breaking-change.yml
index 63178061aae..0300641e540 100644
--- a/data/deprecations/14-8-runner-api-active-field-replaced-with-paused-breaking-change.yml
+++ b/data/deprecations/14-8-runner-api-active-field-replaced-with-paused-breaking-change.yml
@@ -29,5 +29,5 @@
tiers: [Core, Premium, Ultimate]
issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/347211
documentation_url: https://docs.gitlab.com/ee/api/runners.html
- image_url: # (optional) This is a link to a thumbnail image depicting the feature
- video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
+ image_url: # (optional) This is a link to a thumbnail image depicting the feature
+ video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
diff --git a/data/deprecations/14-8-runner-api-project_type-breaking-change.yml b/data/deprecations/14-8-runner-api-project_type-breaking-change.yml
index 67cd854aa89..d965d830c58 100644
--- a/data/deprecations/14-8-runner-api-project_type-breaking-change.yml
+++ b/data/deprecations/14-8-runner-api-project_type-breaking-change.yml
@@ -11,5 +11,5 @@
tiers: [Core, Premium, Ultimate]
issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/351466
documentation_url: https://docs.gitlab.com/ee/api/runners.html
- image_url: # (optional) This is a link to a thumbnail image depicting the feature
- video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
+ image_url: # (optional) This is a link to a thumbnail image depicting the feature
+ video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
diff --git a/data/deprecations/14-8-runner-api-status-filter-does-accept-active-or-paused.yml b/data/deprecations/14-8-runner-api-status-filter-does-accept-active-or-paused.yml
index 51472b3cd28..8f706840f0d 100644
--- a/data/deprecations/14-8-runner-api-status-filter-does-accept-active-or-paused.yml
+++ b/data/deprecations/14-8-runner-api-status-filter-does-accept-active-or-paused.yml
@@ -1,10 +1,10 @@
- name: "REST API Runner will not accept `status` filter values of `active` or `paused`"
- announcement_milestone: "14.8" # The milestone when this feature was first announced as deprecated.
+ announcement_milestone: "14.8" # The milestone when this feature was first announced as deprecated.
announcement_date: "2022-02-22"
removal_milestone: "16.0"
removal_date: "2023-04-22"
breaking_change: true
- body: | # Do not modify this line, instead modify the lines below.
+ body: | # Do not modify this line, instead modify the lines below.
The GitLab Runner REST endpoints will stop accepting `paused` or `active` as a status value in GitLab 16.0.
A runner's status will only relate to runner contact status, such as: `online`, `offline`.
diff --git a/data/deprecations/14-8-sast-secret-analyzer-image.yml b/data/deprecations/14-8-sast-secret-analyzer-image.yml
index b1cb5c82764..cc7e559722d 100644
--- a/data/deprecations/14-8-sast-secret-analyzer-image.yml
+++ b/data/deprecations/14-8-sast-secret-analyzer-image.yml
@@ -12,7 +12,7 @@
Starting in GitLab 14.8, new versions of GitLab Secure and Protect analyzers are published to a new registry location under `registry.gitlab.com/security-products`.
We will update the default value of [GitLab-managed CI/CD templates](https://gitlab.com/gitlab-org/gitlab/-/tree/master/lib/gitlab/ci/templates/Security) to reflect this change:
-
+
- For all analyzers except Container Scanning, we will update the variable `SECURE_ANALYZERS_PREFIX` to the new image registry location.
- For Container Scanning, the default image address is already updated. There is no `SECURE_ANALYZERS_PREFIX` variable for Container Scanning.
diff --git a/data/deprecations/14-8-secure-and-protect-analyzer-bump.yml b/data/deprecations/14-8-secure-and-protect-analyzer-bump.yml
new file mode 100644
index 00000000000..b8eedeeaadb
--- /dev/null
+++ b/data/deprecations/14-8-secure-and-protect-analyzer-bump.yml
@@ -0,0 +1,45 @@
+- name: "Secure and Protect analyzer major version update" # The name of the feature to be deprecated
+ announcement_milestone: "14.8" # The milestone when this feature was first announced as deprecated.
+ announcement_date: "2022-02-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
+ removal_milestone: "15.0" # The milestone when this feature is planned to be removed
+ removal_date: "2022-05-22" # The date of the milestone release when this feature is planned to be removed. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
+ breaking_change: true # If this deprecation is a breaking change, set this value to true
+ reporter: NicoleSchwartz # GitLab username of the person reporting the deprecation
+ body: | # Do not modify this line, instead modify the lines below.
+ The Secure and Protect stages will be bumping the major versions of their analyzers in tandem with the GitLab 15.0 release. This major bump will enable a clear delineation for analyzers, between:
+
+ - Those released prior to May 22, 2022, which generate reports that _are not_ subject to stringent schema validation.
+ - Those released after May 22, 2022, which generate reports that _are_ subject to stringent schema validation.
+
+ If you are not using the default inclusion templates, or have pinned your analyzer version(s) you will need to update your CI/CD job definition to either remove the pinned version or to update the latest major version.
+ Users of GitLab 12.0-14.10 will continue to experience analyzer updates as normal until the release of GitLab 15.0, following which all newly fixed bugs and newly released features in the new major versions of the analyzers will not be available in the deprecated versions because we do not backport bugs and new features as per our [maintenance policy](https://docs.gitlab.com/ee/policy/maintenance.html). As required security patches will be backported within the latest 3 minor releases.
+ Specifically, the following are being deprecated and will no longer be updated after 15.0 GitLab release:
+
+ - API Security: version 1
+ - Container Scanning: version 4
+ - Coverage-guided fuzz testing: version 2
+ - Dependency Scanning: version 2
+ - Dynamic Application Security Testing (DAST): version 2
+ - Infrastructure as Code (IaC) Scanning: version 1
+ - License Scanning: version 3
+ - Secret Detection: version 3
+ - Static Application Security Testing (SAST): version 2 of [all analyzers](https://docs.gitlab.com/ee/user/application_security/sast/#supported-languages-and-frameworks), except `gosec` which is currently at version 3
+ - `bandit`: version 2
+ - `brakeman`: version 2
+ - `eslint`: version 2
+ - `flawfinder`: version 2
+ - `gosec`: version 3
+ - `kubesec`: version 2
+ - `mobsf`: version 2
+ - `nodejs-scan`: version 2
+ - `phpcs-security-audit`: version 2
+ - `pmd-apex`: version 2
+ - `security-code-scan`: version 2
+ - `semgrep`: version 2
+ - `sobelow`: version 2
+ - `spotbugs`: version 2
+# The following items are not published on the docs page, but may be used in the future.
+ stage: secure, protect # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
+ tiers: Free, Silver, Gold, Core, Premium, Ultimate # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
+ issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/350936 # (optional) This is a link to the deprecation issue in GitLab
+ documentation_url: # (optional) This is a link to the current documentation page
diff --git a/data/deprecations/14-8-secure-ca-python-deprecation.yml b/data/deprecations/14-8-secure-ca-python-deprecation.yml
index c4b5c2e36b7..c97271e4db2 100644
--- a/data/deprecations/14-8-secure-ca-python-deprecation.yml
+++ b/data/deprecations/14-8-secure-ca-python-deprecation.yml
@@ -1,10 +1,10 @@
-- name: "Dependency Scanning Python 3.9 and 3.6 image deprecation" # The name of the feature to be deprecated
- announcement_milestone: "14.8" # The milestone when this feature was first announced as deprecated.
- announcement_date: "2021-02-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
- removal_milestone: "15.0" # The milestone when this feature is planned to be removed
- removal_date: 2021-05-22 # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
- breaking_change: true # If this deprecation is a breaking change, set this value to true
- body: | # Do not modify this line, instead modify the lines below.
+- name: "Dependency Scanning Python 3.9 and 3.6 image deprecation" # The name of the feature to be deprecated
+ announcement_milestone: "14.8" # The milestone when this feature was first announced as deprecated.
+ announcement_date: "2021-02-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
+ removal_milestone: "15.0" # The milestone when this feature is planned to be removed
+ removal_date: "2021-05-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
+ breaking_change: true # If this deprecation is a breaking change, set this value to true
+ body: | # Do not modify this line, instead modify the lines below.
For those using Dependency Scanning for Python projects, we are deprecating the default `gemnasium-python:2` image which uses Python 3.6 as well as the custom `gemnasium-python:2-python-3.9` image which uses Python 3.9. The new default image as of GitLab 15.0 will be for Python 3.9 as it is a [supported version](https://endoflife.date/python) and 3.6 [is no longer supported](https://endoflife.date/python).
For users using Python 3.9 or 3.9-compatible projects, you should not need to take action and dependency scanning should begin to work in GitLab 15.0. If you wish to test the new container now please run a test pipeline in your project with this container (which will be removed in 15.0). Use the Python 3.9 image:
@@ -17,7 +17,7 @@
For users using Python 3.6, as of GitLab 15.0 you will no longer be able to use the default template for dependency scanning. You will need to switch to use the deprecated `gemnasium-python:2` analyzer image. If you are impacted by this please comment in [this issue](https://gitlab.com/gitlab-org/gitlab/-/issues/351503) so we can extend the removal if needed.
- For users using the 3.9 special exception image, you must instead use the default value and no longer override your container. To verify if you are using the 3.9 special exception image, check your `.gitlab-ci.yml` file for the following reference:
+ For users using the 3.9 special exception image, you must instead use the default value and no longer override your container. To verify if you are using the 3.9 special exception image, check your `.gitlab-ci.yml` file for the following reference:
```yaml
gemnasium-python-dependency_scanning:
@@ -25,9 +25,9 @@
name: registry.gitlab.com/gitlab-org/security-products/analyzers/gemnasium-python:2-python-3.9
```
# The following items are not published on the docs page, but may be used in the future.
- stage: secure # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
- tiers: ultimate # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
- issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/334060 # (optional) This is a link to the deprecation issue in GitLab
- documentation_url: # (optional) This is a link to the current documentation page
- image_url: # (optional) This is a link to a thumbnail image depicting the feature
- video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
+ stage: secure # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
+ tiers: ultimate # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
+ issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/334060 # (optional) This is a link to the deprecation issue in GitLab
+ documentation_url: # (optional) This is a link to the current documentation page
+ image_url: # (optional) This is a link to a thumbnail image depicting the feature
+ video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
diff --git a/data/deprecations/14-9-deprecate-composer-download-permissions.yml b/data/deprecations/14-9-deprecate-composer-download-permissions.yml
new file mode 100644
index 00000000000..79cb2a81c53
--- /dev/null
+++ b/data/deprecations/14-9-deprecate-composer-download-permissions.yml
@@ -0,0 +1,11 @@
+- name: "Permissions change for downloading Composer dependencies"
+ announcement_milestone: "14.9"
+ announcement_date: "2022-03-22"
+ removal_milestone: "15.0"
+ removal_date: "2022-05-22"
+ breaking_change: true
+ reporter: trizzi
+ body: | # Do not modify this line, instead modify the lines below.
+ The GitLab Composer repository can be used to push, search, fetch metadata about, and download PHP dependencies. All these actions require authentication, except for downloading dependencies.
+
+ Downloading Composer dependencies without authentication is deprecated in GitLab 14.9, and will be removed in GitLab 15.0. Starting with GitLab 15.0, you must authenticate to download Composer dependencies.
diff --git a/data/deprecations/14-9-deprecate-permissions-change-package-settings.yml b/data/deprecations/14-9-deprecate-permissions-change-package-settings.yml
new file mode 100644
index 00000000000..740b3ca2e0d
--- /dev/null
+++ b/data/deprecations/14-9-deprecate-permissions-change-package-settings.yml
@@ -0,0 +1,16 @@
+- name: "GraphQL permissions change for Package settings"
+ announcement_milestone: "14.9"
+ announcement_date: "2022-03-22"
+ removal_milestone: "15.0"
+ removal_date: "2022-05-22"
+ breaking_change: true
+ reporter: trizzi
+ body: | # Do not modify this line, instead modify the lines below.
+ The GitLab Package stage offers a Package Registry, Container Registry, and Dependency Proxy to help you manage all of your dependencies using GitLab. Each of these product categories has a variety of settings that can be adjusted using the API.
+
+ The permissions model for GraphQL is being updated. After 15.0, users with the Guest, Reporter, and Developer role can no longer update these settings:
+
+ - [Package Registry settings](https://docs.gitlab.com/ee/api/graphql/reference/#packagesettings)
+ - [Container Registry cleanup policy](https://docs.gitlab.com/ee/api/graphql/reference/#containerexpirationpolicy)
+ - [Dependency Proxy time-to-live policy](https://docs.gitlab.com/ee/api/graphql/reference/#dependencyproxyimagettlgrouppolicy)
+ - [Enabling the Dependency Proxy for your group](https://docs.gitlab.com/ee/api/graphql/reference/#dependencyproxysetting)
diff --git a/data/deprecations/14-9-deprecate-testcoveragesetting.yml b/data/deprecations/14-9-deprecate-testcoveragesetting.yml
index 19bc6004b02..9015172eeb9 100644
--- a/data/deprecations/14-9-deprecate-testcoveragesetting.yml
+++ b/data/deprecations/14-9-deprecate-testcoveragesetting.yml
@@ -7,7 +7,7 @@
reporter: jreporter # GitLab username of the person reporting the deprecation
body: | # Do not modify this line, instead modify the lines below.
To simplify setting a test coverage pattern, in GitLab 15.0 the
- [project setting for test coverage parsing](https://docs.gitlab.com/ee/ci/pipelines/settings.html#add-test-coverage-results-to-a-merge-request-deprecated)
+ [project setting for test coverage parsing](https://docs.gitlab.com/ee/ci/pipelines/settings.html#add-test-coverage-results-using-project-settings-deprecated)
is being removed.
Instead, using the project’s `.gitlab-ci.yml`, provide a regular expression with the `coverage` keyword to set
diff --git a/data/deprecations/14-9-pages-daemon.yml b/data/deprecations/14-9-pages-daemon.yml
new file mode 100644
index 00000000000..a8fb5924ac6
--- /dev/null
+++ b/data/deprecations/14-9-pages-daemon.yml
@@ -0,0 +1,16 @@
+- name: "GitLab Pages running as daemon" # The name of the feature to be deprecated
+ announcement_milestone: "14.9" # The milestone when this feature was first announced as deprecated.
+ announcement_date: "2022-03-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
+ removal_milestone: "15.0" # The milestone when this feature is planned to be removed
+ removal_date: "2022-05-22" # The date of the milestone release when this feature is planned to be removed. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
+ breaking_change: false # If this deprecation is a breaking change, set this value to true
+ reporter: cbalane # GitLab username of the person reporting the deprecation
+ body: | # Do not modify this line, instead modify the lines below.
+ In 15.0, support for daemon mode for GitLab Pages will be removed.
+ # The following items are not published on the docs page, but may be used in the future.
+ stage: # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
+ tiers: # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
+ issue_url: # (optional) This is a link to the deprecation issue in GitLab
+ documentation_url: # (optional) This is a link to the current documentation page
+ image_url: # (optional) This is a link to a thumbnail image depicting the feature
+ video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
diff --git a/data/deprecations/14-9-system_monitoring.yml b/data/deprecations/14-9-system_monitoring.yml
new file mode 100644
index 00000000000..6c8dc61db4d
--- /dev/null
+++ b/data/deprecations/14-9-system_monitoring.yml
@@ -0,0 +1,14 @@
+- name: "GitLab self-monitoring" # The name of the feature to be deprecated
+ announcement_milestone: "14.9" # The milestone when this feature was first announced as deprecated.
+ announcement_date: "2022-03-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
+ removal_milestone: "15.0" # The milestone when this feature is planned to be removed
+ removal_date: "2022-05-22" # The date of the milestone release when this feature is planned to be removed. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
+ breaking_change: true # If this deprecation is a breaking change, set this value to true
+ reporter: abellucci # GitLab username of the person reporting the deprecation
+ body: | # Do not modify this line, instead modify the lines below.
+ GitLab self-monitoring gives administrators of self-hosted GitLab instances the tools to monitor the health of their instances. This feature is deprecated in GitLab 14.9, and is scheduled for removal in 15.0.
+# The following items are not published on the docs page, but may be used in the future.
+ stage: Monitor # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
+ tiers: [Core, Premium, Ultimate] # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
+ issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/348909 # (optional) This is a link to the deprecation issue in GitLab
+ documentation_url: https://docs.gitlab.com/ee/administration/monitoring/gitlab_self_monitoring_project/ # (optional) This is a link to the current documentation page
diff --git a/data/deprecations/15-0-JTW_v2_update.yml b/data/deprecations/15-0-JTW_v2_update.yml
new file mode 100644
index 00000000000..39880d7fbe0
--- /dev/null
+++ b/data/deprecations/15-0-JTW_v2_update.yml
@@ -0,0 +1,28 @@
+# This is a template for a feature deprecation
+# A deprecation typically occurs when a feature or capability is planned to be removed in a future release.
+# Deprecations should be announced at least two releases prior to removal. Any breaking changes should only be done in major releases.
+#
+# Below is an example of what a single entry should look like, it's required attributes,
+# and what types we expect those attribute values to be.
+#
+# For more information please refer to the handbook documentation here:
+# https://about.gitlab.com/handbook/marketing/blog/release-posts/#deprecations
+#
+# Please delete this line and above before submitting your merge request.
+
+- name: "Changes to the `CI_JOB_JWT`" # The name of the feature to be deprecated
+ announcement_milestone: "14.8" # The milestone when this feature was first announced as deprecated.
+ announcement_date: "2022-02-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
+ removal_milestone: "15.0" # The milestone when this feature is planned to be removed
+ removal_date: "2022-05-22" # The date of the milestone release when this feature is planned to be removed. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
+ breaking_change: true # If this deprecation is a breaking change, set this value to true
+ reporter: dhershkovitch # GitLab username of the person reporting the deprecation
+ body: | # Do not modify this line, instead modify the lines below.
+ The `CI_JOB_JWT` will be updated to support a wider variety of cloud providers. It will be changed to match [`CI_JOB_JWT_V2`](https://docs.gitlab.com/ee/ci/variables/predefined_variables.html), but this change may not be backwards compatible for all users, including Hashicorp Vault users. To maintain the current behavior, users can switch to using `CI_JOB_JWT_V1`, or update their configuration in GitLab 15.0 to use the improved `CI_JOB_JWT`.
+# The following items are not published on the docs page, but may be used in the future.
+ stage: # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
+ tiers: # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
+ issue_url: # (optional) This is a link to the deprecation issue in GitLab
+ documentation_url: # (optional) This is a link to the current documentation page
+ image_url: # (optional) This is a link to a thumbnail image depicting the feature
+ video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
diff --git a/data/deprecations/15-0-deprecate-monitor-logging.yml b/data/deprecations/15-0-deprecate-monitor-logging.yml
index facb66e4ee8..8dbae6f5c4c 100644
--- a/data/deprecations/15-0-deprecate-monitor-logging.yml
+++ b/data/deprecations/15-0-deprecate-monitor-logging.yml
@@ -1,16 +1,15 @@
-- name: "Logging in GitLab" # The name of the feature to be deprecated
- announcement_milestone: "14.7" # The milestone when this feature was first announced as deprecated.
- announcement_date: "2022-01-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
- removal_milestone: "15.0" # The milestone when this feature is planned to be removed
- removal_date: "2022-05-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
- breaking_change: true # If this deprecation is a breaking change, set this value to true
- body: | # Do not modify this line, instead modify the lines below.
+- name: "Logging in GitLab" # The name of the feature to be deprecated
+ announcement_milestone: "14.7" # The milestone when this feature was first announced as deprecated.
+ announcement_date: "2022-01-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
+ removal_milestone: "15.0" # The milestone when this feature is planned to be removed
+ removal_date: "2022-05-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
+ breaking_change: true # If this deprecation is a breaking change, set this value to true
+ body: | # Do not modify this line, instead modify the lines below.
The logging features in GitLab allow users to install the ELK stack (Elasticsearch, Logstash, and Kibana) to aggregate and manage application logs. Users can search for relevant logs in GitLab. However, since deprecating certificate-based integration with Kubernetes clusters and GitLab Managed Apps, we don't have a recommended solution for logging within GitLab. For more information, you can follow the issue for [integrating Opstrace with GitLab](https://gitlab.com/groups/gitlab-org/-/epics/6976).
# The following items are not published on the docs page, but may be used in the future.
- stage: Monitor # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
- tiers: [Free] # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
- issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/346485 # (optional) This is a link to the deprecation issue in GitLab
- documentation_url: https://docs.gitlab.com/ee/operations/#aggregate-and-store-logs-deprecated # (optional) This is a link to the current documentation page
- image_url: # (optional) This is a link to a thumbnail image depicting the feature
- video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
-
+ stage: Monitor # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
+ tiers: [Free] # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
+ issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/346485 # (optional) This is a link to the deprecation issue in GitLab
+ documentation_url: https://docs.gitlab.com/ee/operations/#aggregate-and-store-logs-deprecated # (optional) This is a link to the current documentation page
+ image_url: # (optional) This is a link to a thumbnail image depicting the feature
+ video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
diff --git a/data/deprecations/15-0-deprecate-monitor-metrics.yml b/data/deprecations/15-0-deprecate-monitor-metrics.yml
index 0a28785105f..f5fa63b9c40 100644
--- a/data/deprecations/15-0-deprecate-monitor-metrics.yml
+++ b/data/deprecations/15-0-deprecate-monitor-metrics.yml
@@ -1,17 +1,16 @@
-- name: "Monitor performance metrics through Prometheus" # The name of the feature to be deprecated
- announcement_milestone: "14.7" # The milestone when this feature was first announced as deprecated.
- announcement_date: "2022-01-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
- removal_milestone: "15.0" # The milestone when this feature is planned to be removed
- removal_date: "2022-05-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
- breaking_change: true # If this deprecation is a breaking change, set this value to true
- body: | # Do not modify this line, instead modify the lines below.
+- name: "Monitor performance metrics through Prometheus" # The name of the feature to be deprecated
+ announcement_milestone: "14.7" # The milestone when this feature was first announced as deprecated.
+ announcement_date: "2022-01-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
+ removal_milestone: "15.0" # The milestone when this feature is planned to be removed
+ removal_date: "2022-05-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
+ breaking_change: true # If this deprecation is a breaking change, set this value to true
+ body: | # Do not modify this line, instead modify the lines below.
By displaying data stored in a Prometheus instance, GitLab allows users to view performance metrics. GitLab also displays visualizations of these metrics in dashboards. The user can connect to a previously-configured external Prometheus instance, or set up Prometheus as a GitLab Managed App.
However, since certificate-based integration with Kubernetes clusters is deprecated in GitLab, the metrics functionality in GitLab that relies on Prometheus is also deprecated. This includes the metrics visualizations in dashboards. GitLab is working to develop a single user experience based on [Opstrace](https://about.gitlab.com/press/releases/2021-12-14-gitlab-acquires-opstrace-to-expand-its-devops-platform-with-open-source-observability-solution.html). An [issue exists](https://gitlab.com/groups/gitlab-org/-/epics/6976) for you to follow work on the Opstrace integration.
# The following items are not published on the docs page, but may be used in the future.
- stage: Monitor # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
- tiers: [Free] # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
- issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/346541 # (optional) This is a link to the deprecation issue in GitLab
- documentation_url: https://docs.gitlab.com/ee/operations/metrics/dashboards/ # (optional) This is a link to the current documentation page
- image_url: # (optional) This is a link to a thumbnail image depicting the feature
- video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
-
+ stage: Monitor # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
+ tiers: [Free] # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
+ issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/346541 # (optional) This is a link to the deprecation issue in GitLab
+ documentation_url: https://docs.gitlab.com/ee/operations/metrics/dashboards/ # (optional) This is a link to the current documentation page
+ image_url: # (optional) This is a link to a thumbnail image depicting the feature
+ video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
diff --git a/data/deprecations/15-0-deprecate-monitor-tracing.yml b/data/deprecations/15-0-deprecate-monitor-tracing.yml
index 448404a5c70..3c1eef177ff 100644
--- a/data/deprecations/15-0-deprecate-monitor-tracing.yml
+++ b/data/deprecations/15-0-deprecate-monitor-tracing.yml
@@ -1,15 +1,15 @@
-- name: "Tracing in GitLab" # The name of the feature to be deprecated
- announcement_milestone: "14.7" # The milestone when this feature was first announced as deprecated.
- announcement_date: "2022-01-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
- removal_milestone: "15.0" # The milestone when this feature is planned to be removed
- removal_date: "2022-05-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
- breaking_change: true # If this deprecation is a breaking change, set this value to true
- body: | # Do not modify this line, instead modify the lines below.
+- name: "Tracing in GitLab" # The name of the feature to be deprecated
+ announcement_milestone: "14.7" # The milestone when this feature was first announced as deprecated.
+ announcement_date: "2022-01-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
+ removal_milestone: "15.0" # The milestone when this feature is planned to be removed
+ removal_date: "2022-05-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
+ breaking_change: true # If this deprecation is a breaking change, set this value to true
+ body: | # Do not modify this line, instead modify the lines below.
Tracing in GitLab is an integration with Jaeger, an open-source end-to-end distributed tracing system. GitLab users can navigate to their Jaeger instance to gain insight into the performance of a deployed application, tracking each function or microservice that handles a given request. Tracing in GitLab is deprecated in GitLab 14.7, and scheduled for removal in 15.0. To track work on a possible replacement, see the issue for [Opstrace integration with GitLab](https://gitlab.com/groups/gitlab-org/-/epics/6976).
# The following items are not published on the docs page, but may be used in the future.
- stage: Monitor # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
- tiers: [Free] # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
- issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/346540 # (optional) This is a link to the deprecation issue in GitLab
- documentation_url: https://docs.gitlab.com/ee/operations/tracing.html#tracing # (optional) This is a link to the current documentation page
- image_url: # (optional) This is a link to a thumbnail image depicting the feature
- video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
+ stage: Monitor # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
+ tiers: [Free] # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
+ issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/346540 # (optional) This is a link to the deprecation issue in GitLab
+ documentation_url: https://docs.gitlab.com/ee/operations/tracing.html#tracing # (optional) This is a link to the current documentation page
+ image_url: # (optional) This is a link to a thumbnail image depicting the feature
+ video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
diff --git a/data/deprecations/15-0-instance-statistics-graphql-node-removal.yml b/data/deprecations/15-0-instance-statistics-graphql-node-removal.yml
index c617a6cc478..113ccdc66ea 100644
--- a/data/deprecations/15-0-instance-statistics-graphql-node-removal.yml
+++ b/data/deprecations/15-0-instance-statistics-graphql-node-removal.yml
@@ -4,7 +4,7 @@
removal_milestone: "15.0"
removal_date: "2022-05-22"
breaking_change: true
- body: | # Do not modify this line, instead modify the lines below.
+ body: | # Do not modify this line, instead modify the lines below.
The `instanceStatisticsMeasurements` GraphQL node has been renamed to `usageTrendsMeasurements` in 13.10 and the old field name has been marked as deprecated. To fix the existing GraphQL queries, replace `instanceStatisticsMeasurements` with `usageTrendsMeasurements`.
# The following items are not published on the docs page, but may be used in the future.
stage: Manage
diff --git a/data/deprecations/15-0-oauth-noexpiry.yml b/data/deprecations/15-0-oauth-noexpiry.yml
index 2e1e4a35f7b..154630c9f16 100644
--- a/data/deprecations/15-0-oauth-noexpiry.yml
+++ b/data/deprecations/15-0-oauth-noexpiry.yml
@@ -1,10 +1,10 @@
-- name: "OAuth tokens without expiration" # The name of the feature to be deprecated
- announcement_milestone: "14.8" # The milestone when this feature was first announced as deprecated.
- announcement_date: "2022-02-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
- removal_milestone: "15.0" # The milestone when this feature is planned to be removed
- removal_date: 2022-05-22 # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
- breaking_change: true # If this deprecation is a breaking change, set this value to true
- body: | # Do not modify this line, instead modify the lines below.
+- name: "OAuth tokens without expiration" # The name of the feature to be deprecated
+ announcement_milestone: "14.8" # The milestone when this feature was first announced as deprecated.
+ announcement_date: "2022-02-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
+ removal_milestone: "15.0" # The milestone when this feature is planned to be removed
+ removal_date: "2022-05-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
+ breaking_change: true # If this deprecation is a breaking change, set this value to true
+ body: | # Do not modify this line, instead modify the lines below.
By default, all new applications expire access tokens after 2 hours. In GitLab 14.2 and earlier, OAuth access tokens
had no expiration. In GitLab 15.0, an expiry will be automatically generated for any existing token that does not
already have one.
@@ -16,9 +16,9 @@
1. Select **Expire access tokens** to enable them. Tokens must be revoked or they don’t expire.
# The following items are not published on the docs page, but may be used in the future.
- stage: # Manage
- tiers: # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
- issue_url: # https://gitlab.com/gitlab-org/gitlab/-/issues/21745
- documentation_url: # (optional) This is a link to the current documentation page
- image_url: # (optional) This is a link to a thumbnail image depicting the feature
- video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
+ stage: # Manage
+ tiers: # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
+ issue_url: # https://gitlab.com/gitlab-org/gitlab/-/issues/21745
+ documentation_url: # (optional) This is a link to the current documentation page
+ image_url: # (optional) This is a link to a thumbnail image depicting the feature
+ video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
diff --git a/data/deprecations/15-0-oauth.yml b/data/deprecations/15-0-oauth.yml
index 5ca30d9f330..98c7c974808 100644
--- a/data/deprecations/15-0-oauth.yml
+++ b/data/deprecations/15-0-oauth.yml
@@ -1,15 +1,15 @@
-- name: "OAuth implicit grant" # The name of the feature to be deprecated
- announcement_milestone: "14.0" # The milestone when this feature was first announced as deprecated.
- announcement_date: "2021-06-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
- removal_milestone: "15.0" # The milestone when this feature is planned to be removed
- removal_date: 2022-05-22 # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
- breaking_change: yes # If this deprecation is a breaking change, set this value to true
- body: | # Do not modify this line, instead modify the lines below.
+- name: "OAuth implicit grant" # The name of the feature to be deprecated
+ announcement_milestone: "14.0" # The milestone when this feature was first announced as deprecated.
+ announcement_date: "2021-06-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
+ removal_milestone: "15.0" # The milestone when this feature is planned to be removed
+ removal_date: "2022-05-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
+ breaking_change: true # If this deprecation is a breaking change, set this value to true
+ body: | # Do not modify this line, instead modify the lines below.
The OAuth implicit grant authorization flow will be removed in our next major release, GitLab 15.0. Any applications that use OAuth implicit grant should switch to alternative [supported OAuth flows](https://docs.gitlab.com/ee/api/oauth2.html).
# The following items are not published on the docs page, but may be used in the future.
- stage: # Manage
- tiers: # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
- issue_url: # https://gitlab.com/gitlab-org/gitlab/-/issues/344609
- documentation_url: # (optional) This is a link to the current documentation page
- image_url: # (optional) This is a link to a thumbnail image depicting the feature
- video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
+ stage: # Manage
+ tiers: # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
+ issue_url: # https://gitlab.com/gitlab-org/gitlab/-/issues/344609
+ documentation_url: # (optional) This is a link to the current documentation page
+ image_url: # (optional) This is a link to a thumbnail image depicting the feature
+ video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
diff --git a/data/deprecations/JTW_v2_update.yml b/data/deprecations/JTW_v2_update.yml
deleted file mode 100644
index 53aa9ca2c19..00000000000
--- a/data/deprecations/JTW_v2_update.yml
+++ /dev/null
@@ -1,28 +0,0 @@
-# This is a template for a feature deprecation
-# A deprecation typically occurs when a feature or capability is planned to be removed in a future release.
-# Deprecations should be announced at least two releases prior to removal. Any breaking changes should only be done in major releases.
-#
-# Below is an example of what a single entry should look like, it's required attributes,
-# and what types we expect those attribute values to be.
-#
-# For more information please refer to the handbook documentation here:
-# https://about.gitlab.com/handbook/marketing/blog/release-posts/#deprecations
-#
-# Please delete this line and above before submitting your merge request.
-
-- name: "Changes to the `CI_JOB_JWT`" # The name of the feature to be deprecated
- announcement_milestone: "14.8" # The milestone when this feature was first announced as deprecated.
- announcement_date: "2022-02-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
- removal_milestone: "15.0" # The milestone when this feature is planned to be removed
- removal_date: # The date of the milestone release when this feature is planned to be removed. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
- breaking_change: true # If this deprecation is a breaking change, set this value to true
- reporter: dhershkovitch # GitLab username of the person reporting the deprecation
- body: | # Do not modify this line, instead modify the lines below.
- The `CI_JOB_JWT` will be updated to support a wider variety of cloud providers. It will be changed to match [`CI_JOB_JWT_V2`](https://docs.gitlab.com/ee/ci/variables/predefined_variables.html), but this change may not be backwards compatible for all users, including Hashicorp Vault users. To maintain the current behavior, users can switch to using `CI_JOB_JWT_V1`, or update their configuration in GitLab 15.0 to use the improved `CI_JOB_JWT`.
-# The following items are not published on the docs page, but may be used in the future.
- stage: # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
- tiers: # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
- issue_url: # (optional) This is a link to the deprecation issue in GitLab
- documentation_url: # (optional) This is a link to the current documentation page
- image_url: # (optional) This is a link to a thumbnail image depicting the feature
- video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
diff --git a/data/deprecations/data/deprecations/14-9-secure-and-protect-analyzer-bump.yml.yml b/data/deprecations/data/deprecations/14-9-secure-and-protect-analyzer-bump.yml.yml
deleted file mode 100644
index 8f1d030f47c..00000000000
--- a/data/deprecations/data/deprecations/14-9-secure-and-protect-analyzer-bump.yml.yml
+++ /dev/null
@@ -1,44 +0,0 @@
-- name: "Secure and Protect analyzer major version update" # The name of the feature to be deprecated
- announcement_milestone: "14.8" # The milestone when this feature was first announced as deprecated.
- announcement_date: "2022-02-22" # The date of the milestone release when this feature was first announced as deprecated. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
- removal_milestone: "15.00" # The milestone when this feature is planned to be removed
- removal_date: # The date of the milestone release when this feature is planned to be removed. This should almost always be the 22nd of a month (YYYY-MM-22), unless you did an out of band blog post.
- breaking_change: true # If this deprecation is a breaking change, set this value to true
- reporter: NicoleSchwartz # GitLab username of the person reporting the deprecation
- body: | # Do not modify this line, instead modify the lines below.
- The Secure and Protect stages will be bumping the major versions of their analyzers in tandem with the GitLab 15.0 release. This major bump will enable a clear delineation for analyzers, between:
-
- - Those released prior to May 22, 2022, which generate reports that _are not_ subject to stringent schema validation.
- - Those released after May 22, 2022, which generate reports that _are_ subject to stringent schema validation.
-
- If you are not using the default inclusion templates, or have pinned your analyzer version(s) you will need to update your CI/CD job definition to either remove the pinned version or to update the latest major version.
- Users of GitLab 12.0-14.10 will continue to experience analyzer updates as normal until the release of GitLab 15.0, following which all newly fixed bugs and newly released features in the new major versions of the analyzers will not be available in the deprecated versions because we do not backport bugs and new features as per our [maintenance policy](https://docs.gitlab.com/ee/policy/maintenance.html). As required security patches will be backported within the latest 3 minor releases.
- Specifically, the following are being deprecated and will no longer be updated after 15.0 GitLab release:
-
- - API Security: version 1
- - Container Scanning: version 4
- - Coverage-guided fuzz testing: version 2
- - Dependency Scanning: version 2
- - Dynamic Application Security Testing (DAST): version 2
- - License Scanning: version 3
- - Secret Detection: version 3
- - Static Application Security Testing (SAST): version 2, except security-code-scan which is version 3
- - `bandit`: version 2
- - `brakeman`: version 2
- - `eslint`: version 2
- - `flawfinder`: version 2
- - `gosec`: version 3
- - `kubesec`: version 2
- - `mobsf`: version 2
- - `nodejs-scan`: version 2
- - `phpcs-security-audit`: version 2
- - `pmd-apex`: version 2
- - `security-code-scan`: version 3
- - `semgrep`: version 2
- - `sobelow`: version 2
- - `spotbugs`: version 2
-# The following items are not published on the docs page, but may be used in the future.
- stage: secure, protect # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth
- tiers: Free, Silver, Gold, Core, Premium, Ultimate # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
- issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/350936 # (optional) This is a link to the deprecation issue in GitLab
- documentation_url: # (optional) This is a link to the current documentation page
diff --git a/data/deprecations/distribution_deprecations_14-4.yml b/data/deprecations/distribution_deprecations_14-4.yml
new file mode 100644
index 00000000000..b8c4e0d817c
--- /dev/null
+++ b/data/deprecations/distribution_deprecations_14-4.yml
@@ -0,0 +1,6 @@
+- name: "Move `custom_hooks_dir` setting from GitLab Shell to Gitaly" # The name of the feature to be deprecated
+ announcement_milestone: "14.9" # The milestone when this feature was first announced as deprecated.
+ announcement_date: "2021-10-22"
+ removal_milestone: "15.0" # the milestone when this feature is planned to be removed
+ body: | # Do not modify this line, instead modify the lines below.
+ The [`custom_hooks_dir`](https://docs.gitlab.com/ee/administration/server_hooks.html#create-a-global-server-hook-for-all-repositories) setting is now configured in Gitaly, and will be removed from GitLab Shell in GitLab 15.0.
diff --git a/data/deprecations/templates/14-9-deprecation-htpassword-authentication-container-registry.yml b/data/deprecations/templates/14-9-deprecation-htpassword-authentication-container-registry.yml
new file mode 100644
index 00000000000..14c6b235a1a
--- /dev/null
+++ b/data/deprecations/templates/14-9-deprecation-htpassword-authentication-container-registry.yml
@@ -0,0 +1,11 @@
+- name: "htpasswd Authentication for the Container Registry"
+ announcement_milestone: "14.9"
+ announcement_date: "2022-03-22"
+ removal_milestone: "15.0"
+ removal_date: "2022-05-22"
+ breaking_change: true
+ reporter: trizzi
+ body: | # Do not modify this line, instead modify the lines below.
+ The Container Registry supports [authentication](https://gitlab.com/gitlab-org/container-registry/-/blob/master/docs/configuration.md#auth) with `htpasswd`. It relies on an [Apache `htpasswd` file](https://httpd.apache.org/docs/2.4/programs/htpasswd.html), with passwords hashed using `bcrypt`.
+
+ Since it isn't used in the context of GitLab (the product), `htpasswd` authentication will be deprecated in GitLab 14.9 and removed in GitLab 15.0.
diff --git a/data/removals/14_0/deprecation_bump_terraform_template_version.yml b/data/removals/14_0/deprecation_bump_terraform_template_version.yml
index 253dd81e9ea..201c2efa8aa 100644
--- a/data/removals/14_0/deprecation_bump_terraform_template_version.yml
+++ b/data/removals/14_0/deprecation_bump_terraform_template_version.yml
@@ -1,6 +1,6 @@
- name: "Terraform template version"
removal_date: "2021-06-22"
- removal_milestone: "14.0" # example
+ removal_milestone: "14.0" # example
issue_url: ""
reporter: nagyv-gitlab
breaking_change: true
@@ -13,7 +13,7 @@
At every major release of GitLab, the "latest version" template becomes the "major version" template, inheriting the "latest template" setup.
As we have added many new features to the Terraform integration, the new setup for the "major version" template can be considered a breaking change.
- The latest template supports the [Terraform Merge Request widget](https://docs.gitlab.com/ee/user/infrastructure/mr_integration.html) and
- doesn't need additional setup to work with the [GitLab managed Terraform state](https://docs.gitlab.com/ee/user/infrastructure/terraform_state.html).
+ The latest template supports the [Terraform Merge Request widget](https://docs.gitlab.com/ee/user/infrastructure/iac/mr_integration.html) and
+ doesn't need additional setup to work with the [GitLab managed Terraform state](https://docs.gitlab.com/ee/user/infrastructure/iac/terraform_state.html).
To check the new changes, see the [new "major version" template](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Terraform.gitlab-ci.yml).
diff --git a/data/removals/14_0/removal-sidekiq_experimental_queue_selector.yml b/data/removals/14_0/removal-sidekiq_experimental_queue_selector.yml
index 9995e5a2b55..d53e7744e3a 100644
--- a/data/removals/14_0/removal-sidekiq_experimental_queue_selector.yml
+++ b/data/removals/14_0/removal-sidekiq_experimental_queue_selector.yml
@@ -7,5 +7,3 @@
GitLab supports a [queue selector](https://docs.gitlab.com/ee/administration/operations/extra_sidekiq_processes.html#queue-selector) to run only a subset of background jobs for a given process. When it was introduced, this option had an 'experimental' prefix (`experimental_queue_selector` in Omnibus, `experimentalQueueSelector` in Helm charts).
As announced in the [13.6 release post](https://about.gitlab.com/releases/2020/11/22/gitlab-13-6-released/#sidekiq-cluster-queue-selector-configuration-option-has-been-renamed), the 'experimental' prefix is no longer supported. Instead, `queue_selector` for Omnibus and `queueSelector` in Helm charts should be used.
-
-
diff --git a/data/removals/14_0/removal_ci_project_config_path.yml b/data/removals/14_0/removal_ci_project_config_path.yml
index 64fe187c505..d71fbbb78f3 100644
--- a/data/removals/14_0/removal_ci_project_config_path.yml
+++ b/data/removals/14_0/removal_ci_project_config_path.yml
@@ -9,4 +9,3 @@
If you are using `CI_PROJECT_CONFIG_PATH` in your pipeline configurations,
please update them to use `CI_CONFIG_PATH` instead.
-
diff --git a/data/removals/14_0/removal_enablement_pg11.yml b/data/removals/14_0/removal_enablement_pg11.yml
index 7c5738b7ff9..6f9c7718268 100644
--- a/data/removals/14_0/removal_enablement_pg11.yml
+++ b/data/removals/14_0/removal_enablement_pg11.yml
@@ -7,5 +7,3 @@
PostgreSQL 12 will be the minimum required version in GitLab 14.0. It offers [significant improvements](https://www.postgresql.org/about/news/postgresql-12-released-1976/) to indexing, partitioning, and general performance benefits.
Starting in GitLab 13.7, all new installations default to version 12. From GitLab 13.8, single-node instances are automatically upgraded as well. If you aren't ready to upgrade, you can [opt out of automatic upgrades](https://docs.gitlab.com/omnibus/settings/database.html#opt-out-of-automatic-postgresql-upgrades).
-
-
diff --git a/data/removals/14_0/removal_enablement_ubuntu_16.yml b/data/removals/14_0/removal_enablement_ubuntu_16.yml
index 593bac720c1..e67829de7ab 100644
--- a/data/removals/14_0/removal_enablement_ubuntu_16.yml
+++ b/data/removals/14_0/removal_enablement_ubuntu_16.yml
@@ -7,6 +7,3 @@
Ubuntu 16.04 [reached end-of-life in April 2021](https://ubuntu.com/about/release-cycle), and no longer receives maintenance updates. We strongly recommend users to upgrade to a newer release, such as 20.04.
GitLab 13.12 will be the last release with Ubuntu 16.04 support.
-
-
-
diff --git a/data/removals/14_0/removal_runner_25555.yml b/data/removals/14_0/removal_runner_25555.yml
index 706614618ce..f775bd977bf 100644
--- a/data/removals/14_0/removal_runner_25555.yml
+++ b/data/removals/14_0/removal_runner_25555.yml
@@ -5,4 +5,3 @@
breaking_change: true
body: |
In GitLab Runner 13.0, [issue #5069](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/5069), we introduced new timing options for the GitLab Docker Machine executor. In GitLab Runner 14.0, we have removed the old configuration option, [off peak time mode](https://docs.gitlab.com/runner/configuration/autoscale.html#off-peak-time-mode-configuration-deprecated).
-
diff --git a/data/removals/14_0/verify-ci-removal-parametertrace.yml b/data/removals/14_0/verify-ci-removal-parametertrace.yml
index 67d52827485..8822abaf357 100644
--- a/data/removals/14_0/verify-ci-removal-parametertrace.yml
+++ b/data/removals/14_0/verify-ci-removal-parametertrace.yml
@@ -5,5 +5,3 @@
breaking_change: true
body: |
GitLab Runner was updated in GitLab 13.4 to internally stop passing the `trace` parameter to the `/api/jobs/:id` endpoint. GitLab 14.0 deprecates the `trace` parameter entirely for all other requests of this endpoint. Make sure your [GitLab Runner version matches your GitLab version](https://docs.gitlab.com/runner/#gitlab-runner-versions) to ensure consistent behavior.
-
-
diff --git a/data/removals/14_2/removal-verify-build-log.yml b/data/removals/14_2/removal-verify-build-log.yml
index 10ffe8b7242..f80971b6f4d 100644
--- a/data/removals/14_2/removal-verify-build-log.yml
+++ b/data/removals/14_2/removal-verify-build-log.yml
@@ -1,7 +1,7 @@
- name: "Max job log file size of 100 MB"
- removal_date: August 22, 2021 # day the removal was released
+ removal_date: August 22, 2021 # day the removal was released
removal_milestone: "14.2"
- reporter: jreporter # GitLab username of the person reporting the removal
+ reporter: jreporter # GitLab username of the person reporting the removal
breaking_change: false
body: |
GitLab values efficiency for all users in our wider community of contributors, so we're always working hard to make sure the application performs at a high level with a lovable UX.
diff --git a/data/removals/14_3/removal-limit-tags-to-50.yml b/data/removals/14_3/removal-limit-tags-to-50.yml
index 3395fc9b6ce..24dcddf6955 100644
--- a/data/removals/14_3/removal-limit-tags-to-50.yml
+++ b/data/removals/14_3/removal-limit-tags-to-50.yml
@@ -1,5 +1,5 @@
- name: "Introduced limit of 50 tags for jobs"
- removal_date: September 22nd, 2021
+ removal_date: September 22nd, 2021
removal_milestone: "14.3"
reporter: jreporter
breaking_change: false
diff --git a/data/removals/14_3/removal-verify-pe-pipelinefindername.yml b/data/removals/14_3/removal-verify-pe-pipelinefindername.yml
index df39a6cec38..e3ad364ce29 100644
--- a/data/removals/14_3/removal-verify-pe-pipelinefindername.yml
+++ b/data/removals/14_3/removal-verify-pe-pipelinefindername.yml
@@ -1,7 +1,7 @@
- name: "List project pipelines API endpoint removes `name` support in 14.3"
- removal_date: September 22, 2021 # day the removal was released
+ removal_date: September 22, 2021 # day the removal was released
removal_milestone: "14.3"
- reporter: jreporter # GitLab username of the person reporting the removal
+ reporter: jreporter # GitLab username of the person reporting the removal
breaking_change: false
body: |
In GitLab 14.3, we will remove the ability to filter by `name` in the [list project pipelines API endpoint](https://docs.gitlab.com/ee/api/pipelines.html#list-project-pipelines) to improve performance. If you currently use this parameter with this endpoint, you must switch to `username`.
diff --git a/data/removals/14_3/removal_legacy_storage_setting.yml b/data/removals/14_3/removal_legacy_storage_setting.yml
index 5241861bf5a..1a635dc9b0a 100644
--- a/data/removals/14_3/removal_legacy_storage_setting.yml
+++ b/data/removals/14_3/removal_legacy_storage_setting.yml
@@ -1,9 +1,9 @@
- name: Use of legacy storage setting
- removal_date: September 22nd, 2021 # day the removal was released
+ removal_date: September 22nd, 2021 # day the removal was released
removal_milestone: "14.3"
- reporter: dorrino # GitLab username of the person reporting the removal
+ reporter: dorrino # GitLab username of the person reporting the removal
breaking_change: false
body: | # example (supports markdown)
The support for [`gitlab_pages['use_legacy_storage']` setting](https://docs.gitlab.com/ee/administration/pages/index.html#domain-source-configuration-before-140) in Omnibus installations has been removed.
-
+
In 14.0 we removed [`domain_config_source`](https://docs.gitlab.com/ee/administration/pages/index.html#domain-source-configuration-before-140) which had been previously deprecated, and allowed users to specify disk storage. In 14.0 we added `use_legacy_storage` as a **temporary** flag to unblock upgrades, and allow us to debug issues with our users and it was deprecated and communicated for removal in 14.3.
diff --git a/data/removals/14_6/limit_trigger_pipelines.yml b/data/removals/14_6/limit_trigger_pipelines.yml
index c69b7feecd2..668d887bb0b 100644
--- a/data/removals/14_6/limit_trigger_pipelines.yml
+++ b/data/removals/14_6/limit_trigger_pipelines.yml
@@ -1,6 +1,6 @@
- name: "Limit the number of triggered pipeline to 25K in free tier"
- removal_date: Dec 22, 2021 # day the removal was released
+ removal_date: Dec 22, 2021 # day the removal was released
removal_milestone: "14.6"
- reporter: dhershkovitch # GitLab username of the person reporting the removal
+ reporter: dhershkovitch # GitLab username of the person reporting the removal
body: |
A large amount of triggered pipelines in a single project impacts the performance of GitLab.com. In GitLab 14.6, we are limiting the number of triggered pipelines in a single project on GitLab.com at any given moment to 25,000. This change applies to projects in the free tier only, Premium and Ultimate are not affected by this change.
diff --git a/data/removals/14_6/removal-release-cli-s3.yml b/data/removals/14_6/removal-release-cli-s3.yml
index b92d8bb60f8..7f37f017431 100644
--- a/data/removals/14_6/removal-release-cli-s3.yml
+++ b/data/removals/14_6/removal-release-cli-s3.yml
@@ -1,6 +1,6 @@
- name: "Release CLI distributed as a generic package"
- removal_date: Dec 22, 2021 # day the removal was released
+ removal_date: Dec 22, 2021 # day the removal was released
removal_milestone: "14.6"
- reporter: kbychu # GitLab username of the person reporting the removal
+ reporter: kbychu # GitLab username of the person reporting the removal
body: |
The [release-cli](https://gitlab.com/gitlab-org/release-cli) will be released as a [generic package](https://gitlab.com/gitlab-org/release-cli/-/packages) starting in GitLab 14.2. We will continue to deploy it as a binary to S3 until GitLab 14.5 and stop distributing it in S3 in GitLab 14.6.
diff --git a/data/removals/14_9/removal_monitor_respond_integrated_error_tracking.yml b/data/removals/14_9/removal_monitor_respond_integrated_error_tracking.yml
new file mode 100644
index 00000000000..a0467a56f4f
--- /dev/null
+++ b/data/removals/14_9/removal_monitor_respond_integrated_error_tracking.yml
@@ -0,0 +1,14 @@
+- name: "Integrated error tracking disabled by default"
+ announcement_milestone: "14.9"
+ announcement_date: "2022-02-23" # This is the date customers were notified about the change in rate limits, making integrated error tracking unusable, see https://gitlab.com/groups/gitlab-org/-/epics/7580#communication-to-rate-limit-impacted-users
+ removal_milestone: "14.9"
+ removal_date: "2022-03-10" # The MR was merged on this date, outside of the normal release cycle, https://gitlab.com/gitlab-org/gitlab/-/merge_requests/81767
+ breaking_change: true
+ reporter: abellucci
+ body: |
+ In GitLab 14.4, GitLab released an integrated error tracking backend that replaces Sentry. This feature caused database performance issues. In GitLab 14.9, integrated error tracking is removed from GitLab.com, and turned off by default in GitLab self-managed. While we explore the future development of this feature, please consider switching to the Sentry backend by [changing your error tracking to Sentry in your project settings](https://docs.gitlab.com/ee/operations/error_tracking.html#sentry-error-tracking).
+
+ For additional background on this removal, please reference [Disable Integrated Error Tracking by Default](https://gitlab.com/groups/gitlab-org/-/epics/7580). If you have feedback please add a comment to [Feedback: Removal of Integrated Error Tracking](https://gitlab.com/gitlab-org/gitlab/-/issues/355493).
+ stage: monitor
+ tiers: [Free, Silver, Gold, Core, Premium, Ultimate]
+ issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/353639
diff --git a/data/whats_new/202011230001_13_06.yml b/data/whats_new/202011230001_13_06.yml
index 53ee394f156..1e47bcca0ec 100644
--- a/data/whats_new/202011230001_13_06.yml
+++ b/data/whats_new/202011230001_13_06.yml
@@ -64,7 +64,7 @@
published_at: 2020-11-22
release: 13.6
- title: Milestone Burnup Charts and historically accurate reporting
- body: |
+ body: |
A milestone or iteration burndown chart helps track completion progress of total scope, but it doesn't provide insight into how the scope changed during the course of the timebox. Neither has it previously retained historical accuracy regarding how much of the initial committed scope of the milestone or iteration was actually completed.
To solve these problems and help teams have better insights into scope creep, milestones and iterations now show a burnup chart that tracks the daily total count and weight of issues added to and completed within a given timebox.
diff --git a/data/whats_new/202101140001_13_08.yml b/data/whats_new/202101140001_13_08.yml
index 3c1f33f1c9c..3a1c0179d84 100644
--- a/data/whats_new/202101140001_13_08.yml
+++ b/data/whats_new/202101140001_13_08.yml
@@ -80,4 +80,3 @@
image_url: https://about.gitlab.com/images/home/kubernetes.png
published_at: 2021-01-22
release: 13.8
-
diff --git a/data/whats_new/202102180001_13_09.yml b/data/whats_new/202102180001_13_09.yml
index d948993994e..5f50a05bef2 100644
--- a/data/whats_new/202102180001_13_09.yml
+++ b/data/whats_new/202102180001_13_09.yml
@@ -120,4 +120,3 @@
image_url: https://about.gitlab.com/images/13_9/deploy_keys.png
published_at: 2021-02-22
release: 13.9
-
diff --git a/data/whats_new/202103220001_13_10.yml b/data/whats_new/202103220001_13_10.yml
index 24928f9609b..a1f456a6c8d 100644
--- a/data/whats_new/202103220001_13_10.yml
+++ b/data/whats_new/202103220001_13_10.yml
@@ -5,8 +5,8 @@
self-managed: true
gitlab-com: true
packages: [Free, Premium, Ultimate]
- url: https://docs.gitlab.com/runner/install/openshift.html
- image_url: https://img.youtube.com/vi/ZNBc_QnDUu4/hqdefault.jpg
+ url: https://docs.gitlab.com/runner/install/openshift.html
+ image_url: https://img.youtube.com/vi/ZNBc_QnDUu4/hqdefault.jpg
published_at: 2021-03-22
release: 13.10
- title: "View epics on a board (MVC)"
@@ -21,7 +21,7 @@
gitlab-com: true
packages: [Premium, Ultimate]
url: https://docs.gitlab.com/ee/user/group/epics/epic_boards.html
- image_url: https://about.gitlab.com/images/13_10/view-epics-on-a-board-mvc-1.png
+ image_url: https://about.gitlab.com/images/13_10/view-epics-on-a-board-mvc-1.png
published_at: 2021-03-22
release: 13.10
- title: "View Jira issue details in GitLab"
@@ -35,8 +35,8 @@
self-managed: true
gitlab-com: true
packages: [Premium, Ultimate]
- url: https://docs.gitlab.com/ee/user/project/integrations/jira.html#view-a-jira-issue
- image_url: https://about.gitlab.com/images/13_10/jira-detail-view.png
+ url: https://docs.gitlab.com/ee/user/project/integrations/jira.html#view-a-jira-issue
+ image_url: https://about.gitlab.com/images/13_10/jira-detail-view.png
published_at: 2021-03-22
release: 13.10
- title: "DORA4-based lead time for changes"
@@ -46,8 +46,8 @@
self-managed: true
gitlab-com: true
packages: [Ultimate]
- url: https://docs.gitlab.com/ee/api/dora4_project_analytics.html#list-project-merge-request-lead-times
- image_url: https://about.gitlab.com/images/13_10/api.png
+ url: https://docs.gitlab.com/ee/api/dora4_project_analytics.html#list-project-merge-request-lead-times
+ image_url: https://about.gitlab.com/images/13_10/api.png
published_at: 2021-03-22
release: 13.10
- title: "Create a release from an existing tag"
@@ -57,8 +57,8 @@
self-managed: true
gitlab-com: true
packages: [Free, Premium, Ultimate]
- url: https://docs.gitlab.com/ee/user/project/releases/#create-a-release
- image_url: https://about.gitlab.com/images/13_10/exiting_tags.png
+ url: https://docs.gitlab.com/ee/user/project/releases/#create-a-release
+ image_url: https://about.gitlab.com/images/13_10/exiting_tags.png
published_at: 2021-03-22
release: 13.10
- title: "Integrate any IT alerting tool with GitLab"
@@ -70,8 +70,8 @@
self-managed: true
gitlab-com: true
packages: [Premium, Ultimate]
- url: https://docs.gitlab.com/ee/operations/incident_management/integrations.html#http-endpoints
- image_url: https://about.gitlab.com/images/13_10/integrate_alerts.png
+ url: https://docs.gitlab.com/ee/operations/incident_management/integrations.html#http-endpoints
+ image_url: https://about.gitlab.com/images/13_10/integrate_alerts.png
published_at: 2021-03-22
release: 13.10
- title: "Merge request test summary usability improvements"
@@ -85,7 +85,7 @@
self-managed: true
gitlab-com: true
packages: [Free, Premium, Ultimate]
- url: https://docs.gitlab.com/ee/ci/unit_test_reports.html
- image_url: https://about.gitlab.com/images/13_10/test_summary_ux_improvements.png
+ url: https://docs.gitlab.com/ee/ci/unit_test_reports.html
+ image_url: https://about.gitlab.com/images/13_10/test_summary_ux_improvements.png
published_at: 2021-03-22
release: 13.10
diff --git a/data/whats_new/202104220001_13_11.yml b/data/whats_new/202104220001_13_11.yml
index 36e1ae3fff0..6453893b6de 100644
--- a/data/whats_new/202104220001_13_11.yml
+++ b/data/whats_new/202104220001_13_11.yml
@@ -38,7 +38,7 @@
gitlab-com: true
packages: [Premium, Ultimate]
url: https://docs.gitlab.com/ee/operations/incident_management/oncall_schedules.html
- image_url: https://img.youtube.com/vi/QXfCQ24-Ufo/hqdefault.jpg
+ image_url: https://img.youtube.com/vi/QXfCQ24-Ufo/hqdefault.jpg
published_at: 2021-04-22
release: 13.11
- title: Use multiple caches in the same job
@@ -49,21 +49,21 @@
gitlab-com: true
packages: [Free, Premium, Ultimate]
url: https://docs.gitlab.com/ee/ci/yaml/index.html#multiple-caches
- image_url: https://about.gitlab.com/images/13_11/cache.png
+ image_url: https://about.gitlab.com/images/13_11/cache.png
published_at: 2021-04-22
release: 13.11
-- title: Group SAML Enforcement for Git activity
+- title: Group SAML Enforcement for Git activity
body: |
GitLab group maintainers can now enhance their group security by enforcing Group SAML for Git activity. Security-minded organizations want all GitLab activity to be protected and governed by their SAML Identity Provider. Currently, SAML SSO enforcement only applies to activity in the GitLab UI. Git CLI operations do not require an active SAML SSO session. When Git Group SAML SSO enforcement is enabled, users must have an active web SAML session to perform Git operations in the CLI.
stage: Manage
self-managed: false
gitlab-com: true
- packages: [Premium, Ultimate]
+ packages: [Premium, Ultimate]
url: https://docs.gitlab.com/ee/user/group/saml_sso/#sso-enforcement
image_url: https://about.gitlab.com/images/sdlc-icons/manage.svg
published_at: 2021-04-22
release: 13.11
-- title: Cherry pick commits from fork to parent
+- title: Cherry pick commits from fork to parent
body: |
With GitLab 13.11, if you are a project member, you can now cherry-pick commits from downstream forks back into your project. We've added a new **Pick into project** section to the cherry-pick dialog, shown when you select **Options > Cherry-pick** on a commit's details page.
@@ -73,9 +73,9 @@
stage: Create
self-managed: true
gitlab-com: true
- packages: [Free, Premium, Ultimate]
+ packages: [Free, Premium, Ultimate]
url: https://docs.gitlab.com/ee/user/project/merge_requests/cherry_pick_changes.html#cherry-pick-into-a-project
- image_url: https://about.gitlab.com/images/13_11/cherry_pick_commits_from_fork_to_parent.png
+ image_url: https://about.gitlab.com/images/13_11/cherry_pick_commits_from_fork_to_parent.png
published_at: 2021-04-22
release: 13.11
- title: Improvements to Jira Connect application configuration
@@ -104,7 +104,7 @@
image_url: https://about.gitlab.com/images/13_11/search-settings.gif
published_at: 2021-04-22
release: 13.11
-- title: Deploy GitLab on OpenShift and Kubernetes with the GitLab Operator (beta)
+- title: Deploy GitLab on OpenShift and Kubernetes with the GitLab Operator (beta)
body: |
GitLab is working to offer full support for OpenShift. To accomplish this, we have released the MVP [GitLab Operator](https://gitlab.com/gitlab-org/gl-openshift/gitlab-operator/-/tree/master/doc). The operator aims to manage the full lifecycle of GitLab instances on Kubernetes and OpenShift container platforms. Currently, this is a [beta release](https://gitlab.com/groups/gitlab-org/-/epics/3444) and it is **not recommended for production use**. The next steps will be to make the operator generally available (GA). In the future the operator will become the recommended installation method for Kubernetes and OpenShift, although the GitLab Helm chart will still be supported. We welcome you to try this operator and [provide feedback on our issue tracker](https://gitlab.com/gitlab-org/gl-openshift/gitlab-operator/-/issues/131).
stage: Enablement
@@ -112,6 +112,6 @@
gitlab-com: true
packages: [Free, Premium, Ultimate]
url: https://gitlab.com/gitlab-org/gl-openshift/gitlab-operator/-/tree/master/doc
- image_url: https://about.gitlab.com/images/13_11/gitlab-operator.png
+ image_url: https://about.gitlab.com/images/13_11/gitlab-operator.png
published_at: 2021-04-22
release: 13.11
diff --git a/data/whats_new/202105220001_13_12.yml b/data/whats_new/202105220001_13_12.yml
index 945a9f8327c..bbe614959a0 100644
--- a/data/whats_new/202105220001_13_12.yml
+++ b/data/whats_new/202105220001_13_12.yml
@@ -1,5 +1,5 @@
- title: On-demand DAST GA launch
- body: |
+ body: |
After months of work, we are pleased to announce that our on-demand DAST scanning has reached a General Availability (GA) maturity level. It is ready for usage by anyone who needs to scan an already-deployed application or API outside of a CI/CD pipeline job. With the 13.11 release, we added to on-demand DAST Site profiles the ability to specify authentication information, exclude URLs, add additional request headers, and switch between scanning web applications and APIs. This is in addition to the ability to save scans for quick reusability that was added in 13.9, and the ability to select the branch that a scan is associated with that was added in 13.10. We believe this feature set meets the needs of a majority of GitLab customers.
As we continue to add features, such as scan scheduling, we expect on-demand DAST scanning to cover an ever-increasing range of use cases. As always, we would love as much feedback about these features as possible. Please let us know how things are working for you by leaving a comment in [issue 327396](https://gitlab.com/gitlab-org/gitlab/-/issues/327396).
@@ -12,7 +12,7 @@
published_at: 2021-05-22
release: 13.12
- title: Filter Project Vulnerability Report by vendor name
- body: |
+ body: |
GitLab strives to play well with others and security is no exception. We provide many security scanners as part of our Secure offering. We also encourage 3rd party vendors to [integrate their scanning tools](https://docs.gitlab.com/ee/development/integrations/secure.html) using our open API and data interchange formats. A benefit of using GitLab is managing vulnerabilities from multiple scanners in a unified experience. While you were already able to filter by scanner type (SAST, DAST), it wasn't possible to drill down by the tool provider.
You now have even more granularity when managing vulnerabilities with the new ability to filter by scanner and vendor. You can look at all results across a single vendor's scanners or gain confidence in findings from one scan type (e.g. SAST) that are confirmed by both GitLab and the 3rd party tool. The new filtering capability is available now in Project Vulnerability Reports.
@@ -25,10 +25,10 @@
published_at: 2021-05-22
release: 13.12
- title: Lock latest pipeline artifact to prevent deletion
- body: |
- GitLab now automatically locks the latest artifact produced from a successful pipeline on any active branch, merge request, or tag to prevent it from being deleted based on expiration if it is still the most recent artifact.
+ body: |
+ GitLab now automatically locks the latest artifact produced from a successful pipeline on any active branch, merge request, or tag to prevent it from being deleted based on expiration if it is still the most recent artifact.
- This makes it easier to set a more aggressive expiration policy to clean up older artifacts, helps reduce disk space consumption, and ensures you have always got a copy of the latest artifact from your pipeline.
+ This makes it easier to set a more aggressive expiration policy to clean up older artifacts, helps reduce disk space consumption, and ensures you have always got a copy of the latest artifact from your pipeline.
Pipeline artifacts, such as those used by the [test coverage visualization feature](https://docs.gitlab.com/ee/user/project/merge_requests/test_coverage_visualization.html), are not explicitly managed by the `.gitlab-ci.yml` definitions.
stage: verify
@@ -40,7 +40,7 @@
published_at: 2021-05-22
release: 13.12
- title: Delete associated package files via API
- body: |
+ body: |
You use the GitLab Package Registry to publish, install, and share your dependencies. You may do this using a variety of package manager formats, such as Maven or npm. If you do this as part of your CI workflow, you may publish many packages to your registry. When you publish a dependency, it generates several files including the package archive.
Prior to GitLab 13.12, GitLab didn't provide a way to delete the files from a package. You could only delete the package itself. These extra files can clutter the user interface or result in someone installing an incorrect or outdated dependency.
@@ -55,7 +55,7 @@
published_at: 2021-05-22
release: 13.12
- title: Configuration tool for Secret Detection
- body: |
+ body: |
Following in the footsteps of the [GitLab SAST configuration tool](https://docs.gitlab.com/ee/user/application_security/sast/index.html#configure-sast-in-the-ui) we are adding support for Secret Detection on the Security Configuration page. We believe that [security is a team effort](https://about.gitlab.com/direction/secure/#security-is-a-team-effort) and this configuration experience makes it easier for non-CI experts to get started with [GitLab Secret Detection](https://docs.gitlab.com/ee/user/application_security/secret_detection/). The tool helps a user create a merge request to enable Secret Detection scanning while leveraging best configuration practices like using the GitLab-managed [`SAST.gitlab-ci.yml` template](https://gitlab.com/gitlab-org/gitlab/blob/master/lib/gitlab/ci/templates/Security/SAST.gitlab-ci.yml). The Configuration tool can create a new `.gitlab-ci.yml` file if one does not exist or update existing simple GitLab CI files, allowing the tool to be used with projects that already have GitLab CI setup.
stage: secure
self-managed: true
@@ -66,8 +66,8 @@
published_at: 2021-05-22
release: 13.12
- title: Code quality violation notices in MR diffs
- body: |
- During code reviews, you may have wanted to highlight Code Quality violations and how to resolve them. Previously, this involved having a browser window open to see the violations on the Merge Request summary and another window reviewing the changes in the MR or your IDE. You may have found switching between them too difficult and given up.
+ body: |
+ During code reviews, you may have wanted to highlight Code Quality violations and how to resolve them. Previously, this involved having a browser window open to see the violations on the Merge Request summary and another window reviewing the changes in the MR or your IDE. You may have found switching between them too difficult and given up.
Now, you can see if the file you are reviewing has new code quality violations that are part of the changes right in the Merge Request diff view. This gives you the necessary context to suggest a fix as part of your normal workflow within GitLab without having to keep additional windows open and context switch back and forth between them.
stage: verify
@@ -79,7 +79,7 @@
published_at: 2021-05-22
release: 13.12
- title: Group-level deployment frequency CI/CD chart
- body: |
+ body: |
As part of our efforts to natively support [DORA4 metrics](https://docs.gitlab.com/ee/user/analytics/ci_cd_analytics.html#devops-research-and-assessment-dora-key-metrics) in GitLab, the group-level deployment frequency chart is now available. This chart will show the aggregated deployment frequency metrics for all the projects that are part of the group, and allow you to get a full picture of the deployment frequency across multiple projects and teams, so that you can comprehend their efficiency more accurately. Monitoring deployment frequency helps you understand the efficiency of your deployments over time, find bottlenecks, and focus on improvement areas that span across your projects and teams.
stage: Release
self-managed: true
@@ -90,8 +90,8 @@
published_at: 2021-05-22
release: 13.12
- title: Enforce delayed project removal for all subgroups
- body: |
- Group owners can now enable and enforce [delayed project removal](https://docs.gitlab.com/ee/user/group/#enable-delayed-project-removal) for all subgroups and projects in their group. Delayed project removal protects your data by placing deleted projects in a read-only state after deletion and can be restored, if required. We plan to expand our settings model and allow more settings to be inherited and enforced in subgroups and projects in future milestones. Our new settings management model gives group owners a way to ensure that their subgroups and projects settings adhere to their organization's security and compliance needs.
+ body: |
+ Group owners can now enable and enforce [delayed project removal](https://docs.gitlab.com/ee/user/group/#enable-delayed-project-removal) for all subgroups and projects in their group. Delayed project removal protects your data by placing deleted projects in a read-only state after deletion and can be restored, if required. We plan to expand our settings model and allow more settings to be inherited and enforced in subgroups and projects in future milestones. Our new settings management model gives group owners a way to ensure that their subgroups and projects settings adhere to their organization's security and compliance needs.
stage: manage
self-managed: true
gitlab-com: true
@@ -101,10 +101,10 @@
published_at: 2021-05-22
release: 13.12
- title: Mobile application binary scanning support
- body: |
- Since GitLab 13.6, we've offered [SAST for Android and iOS mobile projects](https://about.gitlab.com/releases/2020/10/22/gitlab-13-5-released/#sast-support-for-ios-and-android-mobile-apps). Initially our Mobile App SAST supported the automatic detection of Xcode projects and Android manifest files. With this release and contribution from community contributor [@proletarius101](https://gitlab.com/proletarius101), GitLab SAST now also supports the automatic detection of .ipa (iOS) and .apk (Android) binary files enabling the security scanning of fully built mobile application artifacts. This offers mobile teams more flexibility with how they build and scan their mobile projects with GitLab SAST for security vulnerabilities.
- Please note that mobile application scanning is still an experimental feature and [requires enabling the experimental flag](https://docs.gitlab.com/ee/user/application_security/sast/#experimental-features) in your CI template. We will make the mobile application scanner generally available without this flag [in the near future](https://gitlab.com/groups/gitlab-org/-/epics/5977).
- stage: secure
+ body: |
+ Since GitLab 13.6, we've offered [SAST for Android and iOS mobile projects](https://about.gitlab.com/releases/2020/10/22/gitlab-13-5-released/#sast-support-for-ios-and-android-mobile-apps). Initially our Mobile App SAST supported the automatic detection of Xcode projects and Android manifest files. With this release and contribution from community contributor [@proletarius101](https://gitlab.com/proletarius101), GitLab SAST now also supports the automatic detection of .ipa (iOS) and .apk (Android) binary files enabling the security scanning of fully built mobile application artifacts. This offers mobile teams more flexibility with how they build and scan their mobile projects with GitLab SAST for security vulnerabilities.
+ Please note that mobile application scanning is still an experimental feature and [requires enabling the experimental flag](https://docs.gitlab.com/ee/user/application_security/sast/#experimental-features) in your CI template. We will make the mobile application scanner generally available without this flag [in the near future](https://gitlab.com/groups/gitlab-org/-/epics/5977).
+ stage: secure
self-managed: true
gitlab-com: true
packages: [Free, Premium, Ultimate]
@@ -113,9 +113,9 @@
published_at: 2021-05-22
release: 13.12
- title: Instance-level Federated Learning of Cohorts (FLoC) opt-in
- body: |
+ body: |
[Federated Learning of Cohorts (FLoC)](https://en.wikipedia.org/wiki/Federated_Learning_of_Cohorts) is a new type of web tracking, intended to replace the use of third-party cookies. It does this by grouping users into cohorts based on their browsing history, for the primary purpose of interest-based advertising. FLoC is being activated in the Chrome browser in some regions.
-
+
With GitLab 13.12, FLoC will not incorporate GitLab browsing activity by default. If an instance administrator would like their users' GitLab instance usage to contribute to FLoC, they can re-enable in instance settings.
stage: enablement
self-managed: true
diff --git a/data/whats_new/202106220001_14_0.yml b/data/whats_new/202106220001_14_0.yml
index fb3775239d4..a17261e8586 100644
--- a/data/whats_new/202106220001_14_0.yml
+++ b/data/whats_new/202106220001_14_0.yml
@@ -149,7 +149,7 @@
- title: Terraform module registry built into GitLab
body: |
Terraform modules play a central role in building standard infrastructure components throughout an organization. Up to GitLab 13.12, GitLab users had to use either a third-party Terraform module registry, local modules, or Git-based modules. While these options work well, they do not help with the distribution of the modules and they lack proper versioning support, which introduces risks for module users. GitLab 14.0 extends our [Infrastructure-as-Code offerings](https://docs.gitlab.com/ee/user/infrastructure/) with a Terraform module registry. Now, you can use the Terraform module registry built into GitLab to discover Terraform modules with semantic versioning support for upgrades and maintenance. Moreover, you can publish modules easily using GitLab CI/CD.
-
+
While following Terraform's best practices, we recommend developing each Terraform module in a dedicated GitLab project. To simplify the transition to the registry, users can host and publish multiple modules from a single GitLab repository. You can learn more about publishing and consuming a new module [in our documentation](https://docs.gitlab.com/ee/user/packages/terraform_module_registry/index.html).
stage: Configure
self-managed: true
diff --git a/data/whats_new/202107220001_14_1.yml b/data/whats_new/202107220001_14_1.yml
index 5ab4651a43c..3c67d74d3db 100644
--- a/data/whats_new/202107220001_14_1.yml
+++ b/data/whats_new/202107220001_14_1.yml
@@ -27,7 +27,7 @@
With [GitLab Workflow](https://marketplace.visualstudio.com/items?itemName=GitLab.gitlab-workflow) [v3.26.0](https://gitlab.com/gitlab-org/gitlab-vscode-extension/-/blob/main/CHANGELOG.md#3260-2021-07-13) for VS Code you can now create and apply patches directly in your editor. The new `GitLab: Create snippet patch` command creates a patch with the changes in your editor and uploads that patch as a [GitLab snippet](https://docs.gitlab.com/ee/user/snippets.html).
- Anyone can search for patches in the project's snippets and apply them directly in VS Code with the `GitLab: Apply snippet patch` command. The applied changes can then be committed to the MR.
+ Anyone can search for patches in the project's snippets and apply them directly in VS Code with the `GitLab: Apply snippet patch` command. The applied changes can then be committed to the MR.
Sharing and collaborating around patches is a great way to propose more complex suggestions and provide clear improvements. Patches created in VS Code can also be linked to others through snippets and downloaded and applied outside of VS Code for users with different editing tools.
stage: Create
@@ -38,7 +38,7 @@
image_url: https://img.youtube.com/vi/QQxpLoKJULQ/hqdefault.jpg
published_at: 2021-07-22
release: 14.1
-- title: Code coverage merge request approval rule
+- title: Code coverage merge request approval rule
body: |
To keep code test coverage high, you need to ensure that merge requests to your codebase never decrease test coverage. Previously, the only way to enforce this was to [require approvals](https://docs.gitlab.com/ee/user/project/merge_requests/approvals/#required-approvals) from users who would check for test coverage decreases as part of their reviews.
@@ -68,7 +68,7 @@
GitLab already supports a variety of other [package manager formats](https://docs.gitlab.com/ee/user/packages/). Why not also support Helm? That's what community member and [MVP from the 14.0 milestone](https://about.gitlab.com/releases/2021/06/22/gitlab-14-0-released/#mvp) [Mathieu Parent](https://gitlab.com/sathieu) asked several months ago before breaking ground on the new GitLab Helm chart registry. The collaboration between the community and GitLab is part of our [dual flywheel strategy](https://about.gitlab.com/company/strategy/#dual-flywheels) and one of the reasons we love working at GitLab. Chapeau Mathieu!
- Now you can use your GitLab project to publish and share packaged Helm charts. Simply add your project as a remote, authenticating with a personal access, deploy, or CI/CD job token. Once that's done you can use the Helm client or GitLab CI/CD to manage your Helm charts. You can also download the charts using the [API](https://docs.gitlab.com/ee/api/packages.html#get-a-project-package) or the [user interface](https://docs.gitlab.com/ee/user/packages/package_registry/#download-a-package).
+ Now you can use your GitLab project to publish and share packaged Helm charts. Simply add your project as a remote, authenticating with a personal access, deploy, or CI/CD job token. Once that's done you can use the Helm client or GitLab CI/CD to manage your Helm charts. You can also download the charts using the [API](https://docs.gitlab.com/ee/api/packages.html#get-a-project-package) or the [user interface](https://docs.gitlab.com/ee/user/packages/package_registry/#download-a-package).
stage: Package
self-managed: true
gitlab-com: true
@@ -81,7 +81,7 @@
body: |
Being on-call is a stressful, 24/7 job. It's possible to miss a notification despite your best efforts and intentions. Teams that maintain critical systems can't afford to miss alerts for outages or service disruptions. Escalation policies are a safety net for these situations. Escalation policies contain time-boxed steps that automatically page a responder in the next escalation step if the responder in the step before didn't respond. To protect your company from missed critical alerts, create an escalation policy in the GitLab project where you manage on-call schedules.
- In GitLab 14.1, users can create, view, or delete escalation policies.
+ In GitLab 14.1, users can create, view, or delete escalation policies.
stage: Monitor
self-managed: true
gitlab-com: true
@@ -128,7 +128,7 @@
release: 14.1
- title: Pronouns viewable in user profile snapshot
body: |
- You can now see pronouns on the snapshot view of a user profile when you hover over someone's name on an issue or merge request. This helps users better respond to comments using the correct pronouns without needing to navigate to the user's profile.
+ You can now see pronouns on the snapshot view of a user profile when you hover over someone's name on an issue or merge request. This helps users better respond to comments using the correct pronouns without needing to navigate to the user's profile.
stage: Manage
self-managed: true
gitlab-com: true
diff --git a/data/whats_new/2021102000001_14_04.yml b/data/whats_new/2021102000001_14_04.yml
index 146544f6f6b..13caddd2bc5 100644
--- a/data/whats_new/2021102000001_14_04.yml
+++ b/data/whats_new/2021102000001_14_04.yml
@@ -13,7 +13,7 @@
body: |
When working in your editor you may need to refer to another project or upstream library for additional information. When you don't have that project already cloned locally, you're forced to either leave your editor and browse the project on GitLab, or locate and then clone the project so you can browse it in your editor. Both of those tasks break your current context, introduce delays, and can take you to a less familiar interface for working with code.
- [GitLab Workflow](https://marketplace.visualstudio.com/items?itemName=GitLab.gitlab-workflow) version `3.33.0` provides an option to open a remote repository. Open the command palette and use the `GitLab: Open Remote Repository` command to find and then open a project.
+ [GitLab Workflow](https://marketplace.visualstudio.com/items?itemName=GitLab.gitlab-workflow) version `3.33.0` provides an option to open a remote repository. Open the command palette and use the `GitLab: Open Remote Repository` command to find and then open a project.
Opening a remote repository allows you to browse a read-only version of a project in your familiar VS Code environment. You can then quickly find the information you're looking for, compare an implementation, or copy a snippet you need.
stage: Create
@@ -57,4 +57,3 @@
image_url: https://about.gitlab.com/images/14_4/monitor-integrated-error-tracking.png
published_at: 2021-10-22
release: 14.4
-
diff --git a/data/whats_new/202112200001_14_06.yml b/data/whats_new/202112200001_14_06.yml
index 77491629892..178cc4dc019 100644
--- a/data/whats_new/202112200001_14_06.yml
+++ b/data/whats_new/202112200001_14_06.yml
@@ -33,9 +33,9 @@
release: 14.6
- title: Toggle wiki editors seamlessly
body: |
- Editing wiki pages with the new rich Markdown editor makes it easier for everyone to contribute regardless of how well they know Markdown syntax. You may also prefer to write raw Markdown in some situations, but use the WYSIWYG interface for more complex or tedious formatting tasks, like creating tables.
+ Editing wiki pages with the new rich Markdown editor makes it easier for everyone to contribute regardless of how well they know Markdown syntax. You may also prefer to write raw Markdown in some situations, but use the WYSIWYG interface for more complex or tedious formatting tasks, like creating tables.
- Previous versions of GitLab required you to save changes before switching between the rich Markdown editor and the Markdown source, adding more steps and friction to your edits. In GitLab 14.6 you can now seamlessly switch between the two editing experiences without committing your changes, choosing the editor that suits your needs at any given moment.
+ Previous versions of GitLab required you to save changes before switching between the rich Markdown editor and the Markdown source, adding more steps and friction to your edits. In GitLab 14.6 you can now seamlessly switch between the two editing experiences without committing your changes, choosing the editor that suits your needs at any given moment.
stage: Create
self-managed: true
gitlab-com: true
diff --git a/data/whats_new/202201200001_14_07.yml b/data/whats_new/202201200001_14_07.yml
index 4f260ee8a8c..d8c76334775 100644
--- a/data/whats_new/202201200001_14_07.yml
+++ b/data/whats_new/202201200001_14_07.yml
@@ -39,4 +39,3 @@
image_url: https://about.gitlab.com/images/14_7/group_access_token.png
published_at: 2022-01-22
release: 14.7
-
diff --git a/data/whats_new/202202210001_14_08.yml b/data/whats_new/202202210001_14_08.yml
index 116eb889bbe..930535dd4e0 100644
--- a/data/whats_new/202202210001_14_08.yml
+++ b/data/whats_new/202202210001_14_08.yml
@@ -31,7 +31,7 @@
- Multiple rules can be created and chained together to allow for filtering on different severity thresholds for each scanner type.
- A two-step approval process can be enforced for any desired changes to security approval rules.
- A single set of security policies can be applied to multiple development projects to allow for ease in maintaining a single, centralized ruleset.
-
+
Security approval policies can be used alongside the existing Vulnerability-Check feature, as the two policies are additive and don't conflict. However, we encourage users to migrate their Vulnerability-Check rules over to security approval policies. Vulnerability-Check rules are now [deprecated](https://docs.gitlab.com/ee/update/deprecations.html#vulnerability-check), and are scheduled for removal in GitLab 15.0. Self managed users will need to enable the `scan_result_policy` feature flag prior to using this feature. To get started, navigate to **Security & Compliance > Policies** and create a new Scan Result type policy.
stage: protect
self-managed: true
@@ -58,7 +58,7 @@
[user impersonation](https://docs.gitlab.com/ee/user/admin_area/#user-impersonation) starting and stopping. This was previously
only available on a page unavailable to GitLab SaaS customers. We are excited to bring
it to the group page which allows both self-managed and SaaS users to view these events!
-
+
These events are helpful to understand if an administrator impersonated a user in your group and any actions that the
administrator took as the impersonated user. You can correlate:
@@ -80,7 +80,7 @@
body: |
In this release, we have introduced additional progress tracking capabilities to roadmaps. You can now view the percentage of completed epics based on issue count instead of issue weight. This functionality is useful for organizations that are using Kanban or other methodologies that don't require their teams to set a weight on issues.
- You can now also customize the level of milestones to include in your roadmap, allowing you to tailor your view to meet the needs of your audience.
+ You can now also customize the level of milestones to include in your roadmap, allowing you to tailor your view to meet the needs of your audience.
stage: plan
self-managed: true
gitlab-com: true
@@ -89,4 +89,3 @@
image_url: 'https://about.gitlab.com/images/14_8/rp_roadmap_settings.png'
published_at: 2022-02-22
release: 14.8
- \ No newline at end of file
diff --git a/data/whats_new/templates/YYYYMMDD0001_XX_YY.yml b/data/whats_new/templates/YYYYMMDD0001_XX_YY.yml
index f8611da2cff..0e34b37a32b 100644
--- a/data/whats_new/templates/YYYYMMDD0001_XX_YY.yml
+++ b/data/whats_new/templates/YYYYMMDD0001_XX_YY.yml
@@ -9,8 +9,8 @@
#
# Please delete this line and above before submitting your merge request.
-- title: # Match the release post entry
- body: | # Do not modify this line, instead modify the lines below.
+- title: # Match the release post entry
+ body: | # Do not modify this line, instead modify the lines below.
<!-- START OF BODY COMMENT
This area supports markdown.
@@ -22,11 +22,11 @@
Delete this entire comment and replace it with your markdown content.
END OF BODY COMMENT -->
- stage: # String value of the stage that the feature was created in. e.g., Growth
- self-managed: # Boolean value (true or false)
- gitlab-com: # Boolean value (true or false)
- packages: # Array of strings. The Array brackets are required here. e.g., [Core, Starter, Premium, Ultimate]
- url: # This is the documentation URL, but can be a URL to a video if there is one
- image_url: # This should be a full URL, generally taken from the release post content. If a video, use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
- published_at: # YYYY-MM-DD
- release: # XX.Y
+ stage: # String value of the stage that the feature was created in. e.g., Growth
+ self-managed: # Boolean value (true or false)
+ gitlab-com: # Boolean value (true or false)
+ packages: # Array of strings. The Array brackets are required here. e.g., [Core, Starter, Premium, Ultimate]
+ url: # This is the documentation URL, but can be a URL to a video if there is one
+ image_url: # This should be a full URL, generally taken from the release post content. If a video, use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
+ published_at: # YYYY-MM-DD
+ release: # XX.Y
diff --git a/db/fixtures/development/33_triage_ops.rb b/db/fixtures/development/33_triage_ops.rb
new file mode 100644
index 00000000000..f4d74af15ca
--- /dev/null
+++ b/db/fixtures/development/33_triage_ops.rb
@@ -0,0 +1,139 @@
+# frozen_string_literal: true
+
+require './spec/support/sidekiq_middleware'
+require './spec/support/helpers/test_env'
+
+class Gitlab::Seeder::TriageOps
+ WEBHOOK_URL = 'http://0.0.0.0:$PORT$'
+ WEBHOOK_TOKEN = "triage-ops-webhook-token"
+
+ def seed!
+ puts "Updating settings to allow web hooks to localhost"
+ ApplicationSetting.current_without_cache.update!(allow_local_requests_from_web_hooks_and_services: true)
+
+ Sidekiq::Testing.inline! do
+ puts "Ensuring required groups"
+ ensure_group('gitlab-com')
+ ensure_group('gitlab-jh/jh-team')
+ ensure_group('gitlab-org')
+ ensure_group('gitlab-org/gitlab-core-team/community-members')
+ ensure_group('gitlab-org/security')
+ puts "Ensuring required projects"
+ ensure_project('gitlab-org/gitlab')
+ ensure_project('gitlab-org/security/gitlab')
+ puts "Ensuring required bot user"
+ ensure_bot_user
+ puts "Setting up webhooks"
+ ensure_webhook_for('gitlab-com')
+ ensure_webhook_for('gitlab-org')
+ end
+ end
+
+ private
+
+ def ensure_bot_user
+ bot = User.find_by_username('triagebot')
+ bot ||= User.create!(
+ username: 'triagebot',
+ name: 'Triage Bot',
+ email: 'triagebot@example.com',
+ confirmed_at: DateTime.now,
+ password: SecureRandom.hex.slice(0, 16)
+ )
+
+ ensure_group('gitlab-org').add_maintainer(bot)
+ ensure_group('gitlab-com').add_maintainer(bot)
+
+ params = {
+ scopes: ['api'],
+ name: "API Token #{Time.zone.now}"
+ }
+ response = PersonalAccessTokens::CreateService.new(current_user: bot, target_user: bot, params: params).execute
+
+ unless response.success?
+ raise "Can't create Triage Bot access token: #{response.message}"
+ end
+
+ puts "Bot with API_TOKEN=#{response[:personal_access_token].token} is present now."
+
+ bot
+ end
+
+ def ensure_webhook_for(group_path)
+ group = Group.find_by_full_path(group_path)
+
+ hook_params = {
+ enable_ssl_verification: false,
+ token: WEBHOOK_TOKEN,
+ url: WEBHOOK_URL.gsub("$PORT$", ENV.fetch('TRIAGE_OPS_WEBHOOK_PORT', '8091'))
+ }
+ # Subscribe the hook to all possible events.
+ all_group_hook_events = GroupHook.triggers.values
+ all_group_hook_events.each { |value| hook_params[value] = true }
+
+ group.hooks.delete_all
+
+ hook = group.hooks.new(hook_params)
+ hook.save!
+
+ puts "Hook with url '#{hook.url}' and token '#{hook.token}' for '#{group_path}' is present now."
+ end
+
+ def ensure_group(full_path)
+ group = Group.find_by_full_path(full_path)
+
+ return group if group
+
+ parent_path = full_path.split('/')[0..-2].join('/')
+ parent = ensure_group(parent_path) if parent_path.present?
+
+ group_path = full_path.split('/').last
+
+ group = Group.new(
+ name: group_path.titleize,
+ path: group_path,
+ parent_id: parent&.id
+ )
+ group.description = FFaker::Lorem.sentence
+ group.save!
+
+ group.add_owner(User.first)
+ group.create_namespace_settings
+
+ group
+ end
+
+ def ensure_project(project_fullpath)
+ project = Project.find_by_full_path(project_fullpath)
+
+ return project if project
+
+ group_path = project_fullpath.split('/')[0..-2].join('/')
+ project_path = project_fullpath.split('/').last
+
+ group = ensure_group(group_path)
+
+ params = {
+ namespace_id: group.id,
+ name: project_path.titleize,
+ path: project_path,
+ description: FFaker::Lorem.sentence,
+ visibility_level: Gitlab::VisibilityLevel::PRIVATE,
+ skip_disk_validation: true
+ }
+
+ project = ::Projects::CreateService.new(User.first, params).execute
+
+ raise "Can't create project '#{project_fullpath}' : #{project.errors.full_messages}" unless project.persisted?
+
+ project
+ end
+end
+
+if ENV['SEED_TRIAGE_OPS']
+ Gitlab::Seeder.quiet do
+ Gitlab::Seeder::TriageOps.new.seed!
+ end
+else
+ puts "Skipped. Use the `SEED_TRIAGE_OPS` environment variable to enable seeding data for triage ops project."
+end
diff --git a/db/migrate/20211007090229_create_issue_search_table.rb b/db/migrate/20211007090229_create_issue_search_table.rb
new file mode 100644
index 00000000000..1fc15d20bd0
--- /dev/null
+++ b/db/migrate/20211007090229_create_issue_search_table.rb
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+class CreateIssueSearchTable < Gitlab::Database::Migration[1.0]
+ include Gitlab::Database::PartitioningMigrationHelpers::TableManagementHelpers
+
+ def up
+ execute <<~SQL
+ CREATE TABLE issue_search_data (
+ project_id bigint NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
+ issue_id bigint NOT NULL REFERENCES issues(id) ON DELETE CASCADE,
+ created_at timestamp with time zone DEFAULT NOW() NOT NULL,
+ updated_at timestamp with time zone DEFAULT NOW() NOT NULL,
+ search_vector tsvector,
+ PRIMARY KEY (project_id, issue_id)
+ ) PARTITION BY HASH (project_id)
+ SQL
+
+ # rubocop: disable Migration/AddIndex
+ add_index :issue_search_data, :issue_id
+ add_index :issue_search_data, :search_vector, using: :gin, name: 'index_issue_search_data_on_search_vector'
+ # rubocop: enable Migration/AddIndex
+
+ create_hash_partitions :issue_search_data, 64
+ end
+
+ def down
+ drop_table :issue_search_data
+ end
+end
diff --git a/db/migrate/20211021115409_add_color_to_epics.rb b/db/migrate/20211021115409_add_color_to_epics.rb
new file mode 100644
index 00000000000..14b38209f30
--- /dev/null
+++ b/db/migrate/20211021115409_add_color_to_epics.rb
@@ -0,0 +1,10 @@
+# frozen_string_literal: true
+
+class AddColorToEpics < Gitlab::Database::Migration[1.0]
+ # rubocop:disable Migration/AddLimitToTextColumns
+ # limit is added in 20211021124715_add_text_limit_to_epics_color
+ def change
+ add_column :epics, :color, :text, default: '#1068bf'
+ end
+ # rubocop:enable Migration/AddLimitToTextColumns
+end
diff --git a/db/migrate/20211021124715_add_text_limit_to_epics_color.rb b/db/migrate/20211021124715_add_text_limit_to_epics_color.rb
new file mode 100644
index 00000000000..7844575c521
--- /dev/null
+++ b/db/migrate/20211021124715_add_text_limit_to_epics_color.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+class AddTextLimitToEpicsColor < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ def up
+ add_text_limit :epics, :color, 7
+ end
+
+ def down
+ remove_text_limit :epics, :color
+ end
+end
diff --git a/db/migrate/20211203160952_add_updated_state_by_user_id_to_merge_request_reviewers.rb b/db/migrate/20211203160952_add_updated_state_by_user_id_to_merge_request_reviewers.rb
new file mode 100644
index 00000000000..dafd2108b43
--- /dev/null
+++ b/db/migrate/20211203160952_add_updated_state_by_user_id_to_merge_request_reviewers.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 AddUpdatedStateByUserIdToMergeRequestReviewers < Gitlab::Database::Migration[1.0]
+ enable_lock_retries!
+
+ def change
+ add_column :merge_request_reviewers, :updated_state_by_user_id, :bigint
+ end
+end
diff --git a/db/migrate/20211203161149_add_index_to_merge_request_reviewers_updated_state_by_user_id.rb b/db/migrate/20211203161149_add_index_to_merge_request_reviewers_updated_state_by_user_id.rb
new file mode 100644
index 00000000000..6f4ee079015
--- /dev/null
+++ b/db/migrate/20211203161149_add_index_to_merge_request_reviewers_updated_state_by_user_id.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class AddIndexToMergeRequestReviewersUpdatedStateByUserId < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ INDEX_NAME = 'index_on_merge_request_reviewers_updated_state_by_user_id'
+
+ def up
+ add_concurrent_index :merge_request_reviewers, :updated_state_by_user_id, name: INDEX_NAME
+ end
+
+ def down
+ remove_concurrent_index_by_name :merge_request_reviewers, INDEX_NAME
+ end
+end
diff --git a/db/migrate/20211203161840_add_updated_state_by_user_id_to_merge_request_assignees.rb b/db/migrate/20211203161840_add_updated_state_by_user_id_to_merge_request_assignees.rb
new file mode 100644
index 00000000000..1c9e7193630
--- /dev/null
+++ b/db/migrate/20211203161840_add_updated_state_by_user_id_to_merge_request_assignees.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+class AddUpdatedStateByUserIdToMergeRequestAssignees < Gitlab::Database::Migration[1.0]
+ enable_lock_retries!
+
+ def change
+ add_column :merge_request_assignees, :updated_state_by_user_id, :bigint
+ end
+end
diff --git a/db/migrate/20211203161942_add_index_to_merge_request_assignees_updated_state_by_user_id.rb b/db/migrate/20211203161942_add_index_to_merge_request_assignees_updated_state_by_user_id.rb
new file mode 100644
index 00000000000..d052ffdf4d6
--- /dev/null
+++ b/db/migrate/20211203161942_add_index_to_merge_request_assignees_updated_state_by_user_id.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class AddIndexToMergeRequestAssigneesUpdatedStateByUserId < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ INDEX_NAME = 'index_on_merge_request_assignees_updated_state_by_user_id'
+
+ def up
+ add_concurrent_index :merge_request_assignees, :updated_state_by_user_id, name: INDEX_NAME
+ end
+
+ def down
+ remove_concurrent_index_by_name :merge_request_assignees, INDEX_NAME
+ end
+end
diff --git a/db/migrate/20220105152547_add_foreign_key_to_updated_state_by_user_id_to_merge_request_assignees.rb b/db/migrate/20220105152547_add_foreign_key_to_updated_state_by_user_id_to_merge_request_assignees.rb
new file mode 100644
index 00000000000..58411c1dc0f
--- /dev/null
+++ b/db/migrate/20220105152547_add_foreign_key_to_updated_state_by_user_id_to_merge_request_assignees.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class AddForeignKeyToUpdatedStateByUserIdToMergeRequestAssignees < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ def up
+ add_concurrent_foreign_key :merge_request_assignees, :users, column: :updated_state_by_user_id, on_delete: :nullify
+ end
+
+ def down
+ with_lock_retries do
+ remove_foreign_key :merge_request_assignees, column: :updated_state_by_user_id
+ end
+ end
+end
diff --git a/db/migrate/20220105153149_add_foreign_key_to_updated_state_by_user_id_to_merge_request_reviewers.rb b/db/migrate/20220105153149_add_foreign_key_to_updated_state_by_user_id_to_merge_request_reviewers.rb
new file mode 100644
index 00000000000..13e375a5b97
--- /dev/null
+++ b/db/migrate/20220105153149_add_foreign_key_to_updated_state_by_user_id_to_merge_request_reviewers.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class AddForeignKeyToUpdatedStateByUserIdToMergeRequestReviewers < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ def up
+ add_concurrent_foreign_key :merge_request_reviewers, :users, column: :updated_state_by_user_id, on_delete: :nullify
+ end
+
+ def down
+ with_lock_retries do
+ remove_foreign_key :merge_request_reviewers, column: :updated_state_by_user_id
+ end
+ end
+end
diff --git a/db/migrate/20220120211831_temp_index_for_group_namespace_member_backfill.rb b/db/migrate/20220120211831_temp_index_for_group_namespace_member_backfill.rb
new file mode 100644
index 00000000000..527d8783a0f
--- /dev/null
+++ b/db/migrate/20220120211831_temp_index_for_group_namespace_member_backfill.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class TempIndexForGroupNamespaceMemberBackfill < Gitlab::Database::Migration[1.0]
+ INDEX_NAME = 'tmp_index_for_namespace_id_migration_on_group_members'
+
+ disable_ddl_transaction!
+
+ def up
+ # Temporary index to be removed in 14.10
+ # https://gitlab.com/gitlab-org/gitlab/-/issues/353538
+ add_concurrent_index :members, :id, where: "members.member_namespace_id IS NULL and members.type = 'GroupMember'", name: INDEX_NAME
+ end
+
+ def down
+ remove_concurrent_index_by_name :members, INDEX_NAME
+ end
+end
diff --git a/db/migrate/20220124200927_add_index_to_issues.rb b/db/migrate/20220124200927_add_index_to_issues.rb
new file mode 100644
index 00000000000..03cdc3ade2c
--- /dev/null
+++ b/db/migrate/20220124200927_add_index_to_issues.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class AddIndexToIssues < Gitlab::Database::Migration[1.0]
+ DOWNTIME = false
+
+ disable_ddl_transaction!
+
+ INDEX_NAME = 'index_issues_on_id_and_weight'
+
+ def up
+ add_concurrent_index :issues, [:id, :weight], name: INDEX_NAME
+ end
+
+ def down
+ remove_concurrent_index_by_name :issues, INDEX_NAME
+ end
+end
diff --git a/db/migrate/20220203074916_add_topics_lower_name_index.rb b/db/migrate/20220203074916_add_topics_lower_name_index.rb
new file mode 100644
index 00000000000..721abf66c67
--- /dev/null
+++ b/db/migrate/20220203074916_add_topics_lower_name_index.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class AddTopicsLowerNameIndex < Gitlab::Database::Migration[1.0]
+ INDEX_NAME = 'index_topics_on_lower_name'
+
+ disable_ddl_transaction!
+
+ def up
+ add_concurrent_index :topics, 'lower(name)', name: INDEX_NAME
+ end
+
+ def down
+ remove_concurrent_index_by_name :topics, INDEX_NAME
+ end
+end
diff --git a/db/migrate/20220203134942_add_hidden_to_projects.rb b/db/migrate/20220203134942_add_hidden_to_projects.rb
new file mode 100644
index 00000000000..7046d641289
--- /dev/null
+++ b/db/migrate/20220203134942_add_hidden_to_projects.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+class AddHiddenToProjects < Gitlab::Database::Migration[1.0]
+ DOWNTIME = false
+
+ enable_lock_retries!
+
+ def change
+ add_column :projects, :hidden, :boolean, default: false, null: false # rubocop: disable Migration/AddColumnsToWideTables
+ end
+end
diff --git a/db/migrate/20220204093120_create_analytics_cycle_analytics_aggregations.rb b/db/migrate/20220204093120_create_analytics_cycle_analytics_aggregations.rb
new file mode 100644
index 00000000000..0339e16a85b
--- /dev/null
+++ b/db/migrate/20220204093120_create_analytics_cycle_analytics_aggregations.rb
@@ -0,0 +1,43 @@
+# frozen_string_literal: true
+class CreateAnalyticsCycleAnalyticsAggregations < Gitlab::Database::Migration[1.0]
+ enable_lock_retries!
+
+ def up
+ create_table :analytics_cycle_analytics_aggregations, id: false do |t|
+ t.references :group, index: false, null: false, foreign_key: { to_table: :namespaces, on_delete: :cascade }
+ t.integer :incremental_runtimes_in_seconds, array: true, default: [], null: false
+ t.integer :incremental_processed_records, array: true, default: [], null: false
+ t.integer :last_full_run_runtimes_in_seconds, array: true, default: [], null: false
+ t.integer :last_full_run_processed_records, array: true, default: [], null: false
+ t.integer :last_incremental_issues_id
+ t.integer :last_incremental_merge_requests_id
+ t.integer :last_full_run_issues_id
+ t.integer :last_full_run_merge_requests_id
+
+ t.datetime_with_timezone :last_incremental_run_at
+ t.datetime_with_timezone :last_incremental_issues_updated_at
+ t.datetime_with_timezone :last_incremental_merge_requests_updated_at
+ t.datetime_with_timezone :last_full_run_at
+ t.datetime_with_timezone :last_full_run_issues_updated_at
+ t.datetime_with_timezone :last_full_run_mrs_updated_at
+ t.datetime_with_timezone :last_consistency_check_updated_at
+
+ t.boolean :enabled, default: true, null: false
+
+ t.index :last_incremental_run_at, where: 'enabled IS TRUE', name: 'ca_aggregations_last_incremental_run_at', order: { last_incremental_run_at: 'ASC NULLS FIRST' }
+ t.index :last_full_run_at, where: 'enabled IS TRUE', name: 'ca_aggregations_last_full_run_at', order: { last_full_run_at: 'ASC NULLS FIRST' }
+ t.index :last_consistency_check_updated_at, where: 'enabled IS TRUE', name: 'ca_aggregations_last_consistency_check_updated_at', order: { last_consistency_check_updated_at: 'ASC NULLS FIRST' }
+
+ t.check_constraint 'CARDINALITY(incremental_runtimes_in_seconds) <= 10'
+ t.check_constraint 'CARDINALITY(incremental_processed_records) <= 10'
+ t.check_constraint 'CARDINALITY(last_full_run_runtimes_in_seconds) <= 10'
+ t.check_constraint 'CARDINALITY(last_full_run_processed_records) <= 10'
+ end
+
+ execute("ALTER TABLE analytics_cycle_analytics_aggregations ADD PRIMARY KEY (group_id)")
+ end
+
+ def down
+ drop_table :analytics_cycle_analytics_aggregations
+ end
+end
diff --git a/db/migrate/20220204193000_add_integrations_encrypted_properties.rb b/db/migrate/20220204193000_add_integrations_encrypted_properties.rb
new file mode 100644
index 00000000000..7df88b68657
--- /dev/null
+++ b/db/migrate/20220204193000_add_integrations_encrypted_properties.rb
@@ -0,0 +1,8 @@
+# frozen_string_literal: true
+
+class AddIntegrationsEncryptedProperties < Gitlab::Database::Migration[1.0]
+ def change
+ add_column :integrations, :encrypted_properties, :binary
+ add_column :integrations, :encrypted_properties_iv, :binary
+ end
+end
diff --git a/db/migrate/20220211090920_cleanup_populate_topics_non_private_projects_count.rb b/db/migrate/20220211090920_cleanup_populate_topics_non_private_projects_count.rb
new file mode 100644
index 00000000000..5ab8feb2195
--- /dev/null
+++ b/db/migrate/20220211090920_cleanup_populate_topics_non_private_projects_count.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class CleanupPopulateTopicsNonPrivateProjectsCount < Gitlab::Database::Migration[1.0]
+ MIGRATION = 'PopulateTopicsNonPrivateProjectsCount'
+
+ disable_ddl_transaction!
+
+ def up
+ finalize_background_migration(MIGRATION)
+ end
+
+ def down
+ # no-op
+ end
+end
diff --git a/db/migrate/20220211125954_create_related_epic_links.rb b/db/migrate/20220211125954_create_related_epic_links.rb
new file mode 100644
index 00000000000..c06a68a9dd2
--- /dev/null
+++ b/db/migrate/20220211125954_create_related_epic_links.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+class CreateRelatedEpicLinks < Gitlab::Database::Migration[1.0]
+ def up
+ create_table :related_epic_links do |t|
+ t.references :source, index: true, foreign_key: { to_table: :epics, on_delete: :cascade }, null: false
+ t.references :target, index: true, foreign_key: { to_table: :epics, on_delete: :cascade }, null: false
+ t.timestamps_with_timezone null: false
+ t.integer :link_type, null: false, default: 0, limit: 2
+
+ t.index [:source_id, :target_id], unique: true
+ end
+ end
+
+ def down
+ drop_table :related_epic_links
+ end
+end
diff --git a/db/migrate/20220215164709_update_application_settings_container_registry_exp_pol_worker_capacity_default.rb b/db/migrate/20220215164709_update_application_settings_container_registry_exp_pol_worker_capacity_default.rb
new file mode 100644
index 00000000000..4b743f84c4d
--- /dev/null
+++ b/db/migrate/20220215164709_update_application_settings_container_registry_exp_pol_worker_capacity_default.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+class UpdateApplicationSettingsContainerRegistryExpPolWorkerCapacityDefault < Gitlab::Database::Migration[1.0]
+ class Settings < ActiveRecord::Base
+ self.table_name = 'application_settings'
+ end
+
+ def up
+ change_column_default(:application_settings, :container_registry_expiration_policies_worker_capacity, from: 0, to: 4)
+
+ current_settings = Settings.first
+
+ if current_settings&.container_registry_expiration_policies_worker_capacity == 0
+ current_settings.update!(container_registry_expiration_policies_worker_capacity: 4)
+ end
+ end
+
+ def down
+ change_column_default(:application_settings, :container_registry_expiration_policies_worker_capacity, from: 4, to: 0)
+ end
+end
diff --git a/db/migrate/20220216110023_create_saved_replies.rb b/db/migrate/20220216110023_create_saved_replies.rb
new file mode 100644
index 00000000000..e4b6c039dee
--- /dev/null
+++ b/db/migrate/20220216110023_create_saved_replies.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+class CreateSavedReplies < Gitlab::Database::Migration[1.0]
+ enable_lock_retries!
+
+ def up
+ create_table :saved_replies do |t|
+ t.references :user, index: false, null: false, foreign_key: { on_delete: :cascade }
+ t.timestamps_with_timezone null: false
+ t.text :name, null: false, limit: 255
+ t.text :content, null: false, limit: 10000
+
+ t.index [:user_id, :name], name: 'index_saved_replies_on_name_text_pattern_ops', unique: true, opclass: { name: :text_pattern_ops }
+ end
+ end
+
+ def down
+ drop_table :saved_replies, if_exists: true
+ end
+end
diff --git a/db/migrate/20220217100008_add_container_registry_expiration_policies_caching_to_application_settings.rb b/db/migrate/20220217100008_add_container_registry_expiration_policies_caching_to_application_settings.rb
new file mode 100644
index 00000000000..bd5b13ffa1c
--- /dev/null
+++ b/db/migrate/20220217100008_add_container_registry_expiration_policies_caching_to_application_settings.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+class AddContainerRegistryExpirationPoliciesCachingToApplicationSettings < Gitlab::Database::Migration[1.0]
+ enable_lock_retries!
+
+ def up
+ add_column :application_settings, :container_registry_expiration_policies_caching, :boolean, null: false, default: true
+ end
+
+ def down
+ remove_column :application_settings, :container_registry_expiration_policies_caching
+ end
+end
diff --git a/db/migrate/20220217113058_add_status_to_status_check_responses.rb b/db/migrate/20220217113058_add_status_to_status_check_responses.rb
new file mode 100644
index 00000000000..2f118677883
--- /dev/null
+++ b/db/migrate/20220217113058_add_status_to_status_check_responses.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+class AddStatusToStatusCheckResponses < Gitlab::Database::Migration[1.0]
+ def change
+ add_column :status_check_responses, :status, :integer, default: 0, null: false, limit: 2
+ end
+end
diff --git a/db/migrate/20220221102333_change_maintenance_note_limit_in_ci_runner.rb db/migrate/20220221102333_change_maintainer_note_limit_in_ci_runner.rb b/db/migrate/20220221102333_change_maintenance_note_limit_in_ci_runner.rb db/migrate/20220221102333_change_maintainer_note_limit_in_ci_runner.rb
new file mode 100644
index 00000000000..98930691b3b
--- /dev/null
+++ b/db/migrate/20220221102333_change_maintenance_note_limit_in_ci_runner.rb db/migrate/20220221102333_change_maintainer_note_limit_in_ci_runner.rb
@@ -0,0 +1,14 @@
+# frozen_string_literal: true
+
+class ChangeMaintainerNoteLimitInCiRunner < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ def up
+ add_text_limit :ci_runners, :maintainer_note, 1024, constraint_name: check_constraint_name(:ci_runners, :maintainer_note, 'max_length_1MB')
+ remove_text_limit :ci_runners, :maintainer_note, constraint_name: check_constraint_name(:ci_runners, :maintainer_note, 'max_length')
+ end
+
+ def down
+ # no-op: Danger of failing if there are records with length(maintainer_note) > 255
+ end
+end
diff --git a/db/migrate/20220222072536_add_target_access_levels_to_broadcast_messages.rb b/db/migrate/20220222072536_add_target_access_levels_to_broadcast_messages.rb
new file mode 100644
index 00000000000..fd353843878
--- /dev/null
+++ b/db/migrate/20220222072536_add_target_access_levels_to_broadcast_messages.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+class AddTargetAccessLevelsToBroadcastMessages < Gitlab::Database::Migration[1.0]
+ def up
+ add_column :broadcast_messages, :target_access_levels, :integer, if_not_exists: true, array: true, null: false, default: []
+ end
+
+ def down
+ remove_column :broadcast_messages, :target_access_levels, if_exists: true
+ end
+end
diff --git a/db/migrate/20220301002101_add_security_orchestration_policy_configuration_namespace_reference.rb b/db/migrate/20220301002101_add_security_orchestration_policy_configuration_namespace_reference.rb
new file mode 100644
index 00000000000..42828086310
--- /dev/null
+++ b/db/migrate/20220301002101_add_security_orchestration_policy_configuration_namespace_reference.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+class AddSecurityOrchestrationPolicyConfigurationNamespaceReference < Gitlab::Database::Migration[1.0]
+ def up
+ add_column :security_orchestration_policy_configurations, :namespace_id, :bigint
+ end
+
+ def down
+ remove_column :security_orchestration_policy_configurations, :namespace_id
+ end
+end
diff --git a/db/migrate/20220301003502_add_security_orchestration_policy_configuration_namespace_index.rb b/db/migrate/20220301003502_add_security_orchestration_policy_configuration_namespace_index.rb
new file mode 100644
index 00000000000..de6b36faa65
--- /dev/null
+++ b/db/migrate/20220301003502_add_security_orchestration_policy_configuration_namespace_index.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+class AddSecurityOrchestrationPolicyConfigurationNamespaceIndex < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+ INDEX_NAME = 'partial_index_sop_configs_on_namespace_id'
+
+ def up
+ add_concurrent_index :security_orchestration_policy_configurations, :namespace_id, unique: true, name: INDEX_NAME, where: 'namespace_id IS NOT NULL'
+ add_concurrent_foreign_key :security_orchestration_policy_configurations, :namespaces, column: :namespace_id, on_delete: :cascade, reverse_lock_order: true
+
+ add_check_constraint :security_orchestration_policy_configurations,
+ "((project_id IS NULL) != (namespace_id IS NULL))",
+ :cop_configs_project_or_namespace_existence
+ end
+
+ def down
+ exec_query 'DELETE FROM security_orchestration_policy_configurations WHERE namespace_id IS NOT NULL'
+
+ remove_check_constraint :security_orchestration_policy_configurations, :cop_configs_project_or_namespace_existence
+
+ with_lock_retries do
+ remove_foreign_key_if_exists :security_orchestration_policy_configurations, column: :namespace_id
+ end
+
+ remove_concurrent_index_by_name :security_orchestration_policy_configurations, INDEX_NAME
+ end
+end
diff --git a/db/migrate/20220301091503_add_not_null_constraint_to_security_policy_configurations.rb b/db/migrate/20220301091503_add_not_null_constraint_to_security_policy_configurations.rb
new file mode 100644
index 00000000000..79ffcb2cbb3
--- /dev/null
+++ b/db/migrate/20220301091503_add_not_null_constraint_to_security_policy_configurations.rb
@@ -0,0 +1,14 @@
+# frozen_string_literal: true
+
+class AddNotNullConstraintToSecurityPolicyConfigurations < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ def up
+ change_column_null :security_orchestration_policy_configurations, :project_id, true
+ end
+
+ def down
+ exec_query 'DELETE FROM security_orchestration_policy_configurations WHERE project_id IS NULL'
+ change_column_null :security_orchestration_policy_configurations, :project_id, false
+ end
+end
diff --git a/db/migrate/20220301175104_change_security_orchestration_policy_configuration_project_index.rb b/db/migrate/20220301175104_change_security_orchestration_policy_configuration_project_index.rb
new file mode 100644
index 00000000000..53706d46979
--- /dev/null
+++ b/db/migrate/20220301175104_change_security_orchestration_policy_configuration_project_index.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class ChangeSecurityOrchestrationPolicyConfigurationProjectIndex < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+ OLD_INDEX_NAME = 'index_sop_configs_on_project_id'
+ NEW_INDEX_NAME = 'partial_index_sop_configs_on_project_id'
+
+ def up
+ add_concurrent_index :security_orchestration_policy_configurations, :project_id, unique: true, name: NEW_INDEX_NAME, where: 'project_id IS NOT NULL'
+ remove_concurrent_index_by_name :security_orchestration_policy_configurations, OLD_INDEX_NAME
+ end
+
+ def down
+ add_concurrent_index :security_orchestration_policy_configurations, :project_id, unique: true, name: OLD_INDEX_NAME
+ remove_concurrent_index_by_name :security_orchestration_policy_configurations, NEW_INDEX_NAME
+ end
+end
diff --git a/db/migrate/20220301175426_create_project_build_artifacts_size_refresh.rb b/db/migrate/20220301175426_create_project_build_artifacts_size_refresh.rb
new file mode 100644
index 00000000000..fd01437d045
--- /dev/null
+++ b/db/migrate/20220301175426_create_project_build_artifacts_size_refresh.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+class CreateProjectBuildArtifactsSizeRefresh < Gitlab::Database::Migration[1.0]
+ enable_lock_retries!
+
+ CREATED_STATE = 1
+
+ def change
+ create_table :project_build_artifacts_size_refreshes do |t|
+ t.references :project, index: { unique: true }, foreign_key: { on_delete: :cascade }, null: false
+ t.bigint :last_job_artifact_id, null: true
+ t.integer :state, null: false, default: CREATED_STATE, limit: 1
+ t.datetime_with_timezone :refresh_started_at, null: true
+ t.timestamps_with_timezone null: false
+
+ # We will use this index for 2 purposes:
+ # - for finding rows with state = :waiting
+ # - for finding rows with state = :running and updated_at < x.days.ago
+ # which we can use to find jobs that were not able to complete and considered
+ # stale so we can retry
+ t.index [:state, :updated_at], name: 'idx_build_artifacts_size_refreshes_state_updated_at'
+ end
+ end
+end
diff --git a/db/migrate/20220303190555_add_comment_to_deployment_approvals.rb b/db/migrate/20220303190555_add_comment_to_deployment_approvals.rb
new file mode 100644
index 00000000000..56b873c009a
--- /dev/null
+++ b/db/migrate/20220303190555_add_comment_to_deployment_approvals.rb
@@ -0,0 +1,10 @@
+# frozen_string_literal: true
+
+class AddCommentToDeploymentApprovals < Gitlab::Database::Migration[1.0]
+ # rubocop:disable Migration/AddLimitToTextColumns
+ # limit is added in 20220303191047_add_text_limit_to_deployment_approvals_comment
+ def change
+ add_column :deployment_approvals, :comment, :text
+ end
+ # rubocop:enable Migration/AddLimitToTextColumns
+end
diff --git a/db/migrate/20220303191047_add_text_limit_to_deployment_approvals_comment.rb b/db/migrate/20220303191047_add_text_limit_to_deployment_approvals_comment.rb
new file mode 100644
index 00000000000..70c7f5f3a7b
--- /dev/null
+++ b/db/migrate/20220303191047_add_text_limit_to_deployment_approvals_comment.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+class AddTextLimitToDeploymentApprovalsComment < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ def up
+ add_text_limit :deployment_approvals, :comment, 255
+ end
+
+ def down
+ remove_text_limit :deployment_approvals, :comment
+ end
+end
diff --git a/db/migrate/20220304052335_remove_not_null_contraint_on_title_from_sprints.rb b/db/migrate/20220304052335_remove_not_null_contraint_on_title_from_sprints.rb
new file mode 100644
index 00000000000..f429303ab83
--- /dev/null
+++ b/db/migrate/20220304052335_remove_not_null_contraint_on_title_from_sprints.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class RemoveNotNullContraintOnTitleFromSprints < Gitlab::Database::Migration[1.0]
+ enable_lock_retries!
+
+ def up
+ change_column_null :sprints, :title, true
+ end
+
+ def down
+ execute <<~SQL
+ UPDATE sprints SET title = id WHERE title IS NULL
+ SQL
+
+ change_column_null :sprints, :title, false
+ end
+end
diff --git a/db/migrate/20220304061631_remove_unique_index_for_sprints_on_iterations_cadence_id_and_title.rb b/db/migrate/20220304061631_remove_unique_index_for_sprints_on_iterations_cadence_id_and_title.rb
new file mode 100644
index 00000000000..8c223bbce01
--- /dev/null
+++ b/db/migrate/20220304061631_remove_unique_index_for_sprints_on_iterations_cadence_id_and_title.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class RemoveUniqueIndexForSprintsOnIterationsCadenceIdAndTitle < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ INDEX_NAME = 'index_sprints_on_iterations_cadence_id_and_title'
+
+ def up
+ remove_concurrent_index_by_name :sprints, INDEX_NAME
+ end
+
+ def down
+ add_concurrent_index :sprints, [:iterations_cadence_id, :title], name: INDEX_NAME, unique: true
+ end
+end
diff --git a/db/migrate/20220304062107_remove_unique_index_for_sprints_on_project_id_and_title.rb b/db/migrate/20220304062107_remove_unique_index_for_sprints_on_project_id_and_title.rb
new file mode 100644
index 00000000000..34a357bdc5c
--- /dev/null
+++ b/db/migrate/20220304062107_remove_unique_index_for_sprints_on_project_id_and_title.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class RemoveUniqueIndexForSprintsOnProjectIdAndTitle < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ INDEX_NAME = 'index_sprints_on_project_id_and_title'
+
+ def up
+ remove_concurrent_index_by_name :sprints, INDEX_NAME
+ end
+
+ def down
+ add_concurrent_index :sprints, [:project_id, :title], where: "project_id IS NOT NULL", name: INDEX_NAME, unique: true
+ end
+end
diff --git a/db/migrate/20220304152729_add_default_to_required_python_on_packages_pypi_metadata.rb b/db/migrate/20220304152729_add_default_to_required_python_on_packages_pypi_metadata.rb
new file mode 100644
index 00000000000..56297565cb4
--- /dev/null
+++ b/db/migrate/20220304152729_add_default_to_required_python_on_packages_pypi_metadata.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+class AddDefaultToRequiredPythonOnPackagesPypiMetadata < Gitlab::Database::Migration[1.0]
+ def up
+ change_column_default(:packages_pypi_metadata, :required_python, '')
+ end
+
+ def down
+ change_column_default(:packages_pypi_metadata, :required_python, nil)
+ end
+end
diff --git a/db/migrate/20220307203458_rename_user_email_lookup_limit_setting_to_search_settings.rb b/db/migrate/20220307203458_rename_user_email_lookup_limit_setting_to_search_settings.rb
new file mode 100644
index 00000000000..62fe55b22f2
--- /dev/null
+++ b/db/migrate/20220307203458_rename_user_email_lookup_limit_setting_to_search_settings.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+class RenameUserEmailLookupLimitSettingToSearchSettings < Gitlab::Database::Migration[1.0]
+ def up
+ add_column :application_settings, :search_rate_limit, :integer, null: false, default: 30
+ add_column :application_settings, :search_rate_limit_unauthenticated, :integer, null: false, default: 10
+ end
+
+ def down
+ remove_column :application_settings, :search_rate_limit
+ remove_column :application_settings, :search_rate_limit_unauthenticated
+ end
+end
diff --git a/db/migrate/20220309100648_add_time_to_restore_service_dora_metric.rb b/db/migrate/20220309100648_add_time_to_restore_service_dora_metric.rb
new file mode 100644
index 00000000000..5cb49a9899a
--- /dev/null
+++ b/db/migrate/20220309100648_add_time_to_restore_service_dora_metric.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+class AddTimeToRestoreServiceDoraMetric < Gitlab::Database::Migration[1.0]
+ def change
+ add_column :dora_daily_metrics, :time_to_restore_service_in_seconds, :integer
+ end
+end
diff --git a/db/migrate/20220310101118_update_holder_name_limit.rb b/db/migrate/20220310101118_update_holder_name_limit.rb
new file mode 100644
index 00000000000..55eb8f75d70
--- /dev/null
+++ b/db/migrate/20220310101118_update_holder_name_limit.rb
@@ -0,0 +1,28 @@
+# frozen_string_literal: true
+
+# See https://docs.gitlab.com/ee/development/migration_style_guide.html
+# for more information on how to write migrations for GitLab.
+
+class UpdateHolderNameLimit < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ def up
+ add_text_limit :user_credit_card_validations, :holder_name, 50, constraint_name: new_constraint_name
+ remove_text_limit :user_credit_card_validations, :holder_name, constraint_name: old_constraint_name
+ end
+
+ def down
+ add_text_limit :user_credit_card_validations, :holder_name, 26, validate: false, constraint_name: old_constraint_name
+ remove_text_limit :user_credit_card_validations, :holder_name, constraint_name: new_constraint_name
+ end
+
+ private
+
+ def old_constraint_name
+ check_constraint_name(:user_credit_card_validations, :holder_name, 'max_length')
+ end
+
+ def new_constraint_name
+ check_constraint_name(:user_credit_card_validations, :holder_name, 'max_length_50')
+ end
+end
diff --git a/db/migrate/20220314194149_add_project_ci_secure_files_to_plan_limits.rb b/db/migrate/20220314194149_add_project_ci_secure_files_to_plan_limits.rb
new file mode 100644
index 00000000000..fcb7d322ce8
--- /dev/null
+++ b/db/migrate/20220314194149_add_project_ci_secure_files_to_plan_limits.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+class AddProjectCiSecureFilesToPlanLimits < Gitlab::Database::Migration[1.0]
+ def change
+ add_column(:plan_limits, :project_ci_secure_files, :integer, default: 100, null: false)
+ end
+end
diff --git a/db/post_migrate/20210329102724_add_new_trail_plans.rb b/db/post_migrate/20210329102724_add_new_trail_plans.rb
index b142f6385f7..37c64bbd42d 100644
--- a/db/post_migrate/20210329102724_add_new_trail_plans.rb
+++ b/db/post_migrate/20210329102724_add_new_trail_plans.rb
@@ -24,7 +24,7 @@ class AddNewTrailPlans < ActiveRecord::Migration[6.0]
end
def up
- return unless Gitlab.dev_env_or_com?
+ return unless Gitlab.com?
ultimate_trial = Plan.create!(name: 'ultimate_trial', title: 'Ultimate Trial')
premium_trial = Plan.create!(name: 'premium_trial', title: 'Premium Trial')
@@ -34,7 +34,7 @@ class AddNewTrailPlans < ActiveRecord::Migration[6.0]
end
def down
- return unless Gitlab.dev_env_or_com?
+ return unless Gitlab.com?
Plan.where(name: %w(ultimate_trial premium_trial)).delete_all
end
diff --git a/db/post_migrate/20210805192450_update_trial_plans_ci_daily_pipeline_schedule_triggers.rb b/db/post_migrate/20210805192450_update_trial_plans_ci_daily_pipeline_schedule_triggers.rb
index 9552058dd73..f27f61729a3 100644
--- a/db/post_migrate/20210805192450_update_trial_plans_ci_daily_pipeline_schedule_triggers.rb
+++ b/db/post_migrate/20210805192450_update_trial_plans_ci_daily_pipeline_schedule_triggers.rb
@@ -29,7 +29,7 @@ class UpdateTrialPlansCiDailyPipelineScheduleTriggers < ActiveRecord::Migration[
end
def up
- return unless Gitlab.dev_env_or_com?
+ return unless Gitlab.com?
if plan_limits_present?
create_or_update_plan_limit('ci_daily_pipeline_schedule_triggers', PREMIUM_TRIAL, EVERY_5_MINUTES)
@@ -38,7 +38,7 @@ class UpdateTrialPlansCiDailyPipelineScheduleTriggers < ActiveRecord::Migration[
end
def down
- return unless Gitlab.dev_env_or_com?
+ return unless Gitlab.com?
if plan_limits_present?
create_or_update_plan_limit('ci_daily_pipeline_schedule_triggers', PREMIUM_TRIAL, 0)
diff --git a/db/post_migrate/20210812013042_remove_duplicate_project_authorizations.rb b/db/post_migrate/20210812013042_remove_duplicate_project_authorizations.rb
new file mode 100644
index 00000000000..6fdc30d09c6
--- /dev/null
+++ b/db/post_migrate/20210812013042_remove_duplicate_project_authorizations.rb
@@ -0,0 +1,111 @@
+# frozen_string_literal: true
+
+class RemoveDuplicateProjectAuthorizations < ActiveRecord::Migration[6.1]
+ include Gitlab::Database::MigrationHelpers
+
+ BATCH_SIZE = 10_000
+ OLD_INDEX_NAME = 'index_project_authorizations_on_project_id_user_id'
+ INDEX_NAME = 'index_unique_project_authorizations_on_project_id_user_id'
+
+ class ProjectAuthorization < ActiveRecord::Base
+ self.table_name = 'project_authorizations'
+ end
+
+ disable_ddl_transaction!
+
+ def up
+ batch do |first_record, last_record|
+ break if first_record.blank?
+
+ # construct a range query where we filter records between the first and last records
+ rows = ActiveRecord::Base.connection.execute <<~SQL
+ SELECT user_id, project_id
+ FROM project_authorizations
+ WHERE
+ #{start_condition(first_record)}
+ #{end_condition(last_record)}
+ GROUP BY user_id, project_id
+ HAVING COUNT(*) > 1
+ SQL
+
+ rows.each do |row|
+ deduplicate_item(row['project_id'], row['user_id'])
+ end
+ end
+
+ add_concurrent_index :project_authorizations, [:project_id, :user_id], unique: true, name: INDEX_NAME
+ remove_concurrent_index_by_name :project_authorizations, OLD_INDEX_NAME
+ end
+
+ def down
+ add_concurrent_index(:project_authorizations, [:project_id, :user_id], name: OLD_INDEX_NAME)
+ remove_concurrent_index_by_name(:project_authorizations, INDEX_NAME)
+ end
+
+ private
+
+ def start_condition(record)
+ "(user_id, project_id) >= (#{Integer(record.user_id)}, #{Integer(record.project_id)})"
+ end
+
+ def end_condition(record)
+ return "" unless record
+
+ "AND (user_id, project_id) <= (#{Integer(record.user_id)}, #{Integer(record.project_id)})"
+ end
+
+ def batch(&block)
+ order = Gitlab::Pagination::Keyset::Order.build([
+ Gitlab::Pagination::Keyset::ColumnOrderDefinition.new(
+ attribute_name: 'user_id',
+ order_expression: ProjectAuthorization.arel_table[:user_id].asc,
+ nullable: :not_nullable,
+ distinct: false
+ ),
+ Gitlab::Pagination::Keyset::ColumnOrderDefinition.new(
+ attribute_name: 'project_id',
+ order_expression: ProjectAuthorization.arel_table[:project_id].asc,
+ nullable: :not_nullable,
+ distinct: false
+ ),
+ Gitlab::Pagination::Keyset::ColumnOrderDefinition.new(
+ attribute_name: 'access_level',
+ order_expression: ProjectAuthorization.arel_table[:access_level].asc,
+ nullable: :not_nullable,
+ distinct: true
+ )
+ ])
+
+ scope = ProjectAuthorization.order(order)
+ cursor = {}
+ loop do
+ current_scope = scope.dup
+
+ relation = order.apply_cursor_conditions(current_scope, cursor)
+ first_record = relation.take
+ last_record = relation.offset(BATCH_SIZE).take
+
+ yield first_record, last_record
+
+ break if last_record.blank?
+
+ cursor = order.cursor_attributes_for_node(last_record)
+ end
+ end
+
+ def deduplicate_item(project_id, user_id)
+ auth_records = ProjectAuthorization.where(project_id: project_id, user_id: user_id).order(access_level: :desc).to_a
+
+ ActiveRecord::Base.transaction do
+ # Keep the highest access level and destroy the rest.
+ auth_records[1..].each do |record|
+ ProjectAuthorization
+ .where(
+ project_id: record.project_id,
+ user_id: record.user_id,
+ access_level: record.access_level
+ ).delete_all
+ end
+ end
+ end
+end
diff --git a/db/post_migrate/20211026070408_backfill_issue_search_data.rb b/db/post_migrate/20211026070408_backfill_issue_search_data.rb
new file mode 100644
index 00000000000..a840adcb991
--- /dev/null
+++ b/db/post_migrate/20211026070408_backfill_issue_search_data.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+class BackfillIssueSearchData < Gitlab::Database::Migration[1.0]
+ MIGRATION = 'BackfillIssueSearchData'
+
+ def up
+ queue_batched_background_migration(
+ MIGRATION,
+ :issues,
+ :id,
+ batch_size: 100_000,
+ sub_batch_size: 1_000,
+ job_interval: 5.minutes
+ )
+ end
+
+ def down
+ Gitlab::Database::BackgroundMigration::BatchedMigration
+ .for_configuration(MIGRATION, :issues, :id, [])
+ .delete_all
+ end
+end
diff --git a/db/post_migrate/20211028100843_delete_issue_merge_request_taggings_records.rb b/db/post_migrate/20211028100843_delete_issue_merge_request_taggings_records.rb
index 1ceaa1b5aef..a53f5a4fc25 100644
--- a/db/post_migrate/20211028100843_delete_issue_merge_request_taggings_records.rb
+++ b/db/post_migrate/20211028100843_delete_issue_merge_request_taggings_records.rb
@@ -8,8 +8,12 @@ class DeleteIssueMergeRequestTaggingsRecords < Gitlab::Database::Migration[1.0]
BATCH_SIZE = 3_000
TAGGABLE_TYPES = %w(Issue MergeRequest)
+ class Tagging < ActiveRecord::Base
+ self.table_name = "taggings"
+ end
+
def up
- sleep 2 while ActsAsTaggableOn::Tagging.where(taggable_type: TAGGABLE_TYPES).limit(BATCH_SIZE).delete_all > 0
+ sleep 2 while Tagging.where(taggable_type: TAGGABLE_TYPES).limit(BATCH_SIZE).delete_all > 0
remove_concurrent_index_by_name :taggings, INDEX_NAME
end
diff --git a/db/post_migrate/20211029102822_add_open_source_plan.rb b/db/post_migrate/20211029102822_add_open_source_plan.rb
index 00266640f03..bb65637ffca 100644
--- a/db/post_migrate/20211029102822_add_open_source_plan.rb
+++ b/db/post_migrate/20211029102822_add_open_source_plan.rb
@@ -24,7 +24,7 @@ class AddOpenSourcePlan < Gitlab::Database::Migration[1.0]
end
def up
- return unless Gitlab.dev_env_or_com?
+ return unless Gitlab.com?
opensource = Plan.create!(name: 'opensource', title: 'Open Source Program')
@@ -32,7 +32,7 @@ class AddOpenSourcePlan < Gitlab::Database::Migration[1.0]
end
def down
- return unless Gitlab.dev_env_or_com?
+ return unless Gitlab.com?
Plan.where(name: 'opensource').delete_all
end
diff --git a/db/post_migrate/20220120211832_backfill_member_namespace_id_for_group_members.rb b/db/post_migrate/20220120211832_backfill_member_namespace_id_for_group_members.rb
new file mode 100644
index 00000000000..947c0a1edd0
--- /dev/null
+++ b/db/post_migrate/20220120211832_backfill_member_namespace_id_for_group_members.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+class BackfillMemberNamespaceIdForGroupMembers < Gitlab::Database::Migration[1.0]
+ MIGRATION = 'BackfillMemberNamespaceForGroupMembers'
+ INTERVAL = 2.minutes
+ BATCH_SIZE = 1_000
+ MAX_BATCH_SIZE = 2_000
+ SUB_BATCH_SIZE = 100
+
+ def up
+ queue_batched_background_migration(
+ MIGRATION,
+ :members,
+ :id,
+ job_interval: INTERVAL,
+ batch_size: BATCH_SIZE,
+ max_batch_size: MAX_BATCH_SIZE,
+ sub_batch_size: SUB_BATCH_SIZE
+ )
+ end
+
+ def down
+ Gitlab::Database::BackgroundMigration::BatchedMigration
+ .for_configuration(MIGRATION, :members, :id, [])
+ .delete_all
+ end
+end
diff --git a/db/post_migrate/20220131000000_index_job_artifacts_on_trace_type_and_expire_at.rb b/db/post_migrate/20220131000000_index_job_artifacts_on_trace_type_and_expire_at.rb
new file mode 100644
index 00000000000..f47c04dd2ef
--- /dev/null
+++ b/db/post_migrate/20220131000000_index_job_artifacts_on_trace_type_and_expire_at.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+class IndexJobArtifactsOnTraceTypeAndExpireAt < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ INDEX_NAME = 'tmp_index_ci_job_artifacts_on_id_where_trace_and_expire_at'
+ TIMESTAMPS = "'2021-04-22 00:00:00', '2021-05-22 00:00:00', '2021-06-22 00:00:00', '2022-01-22 00:00:00', '2022-02-22 00:00:00', '2022-03-22 00:00:00', '2022-04-22 00:00:00'"
+
+ def up
+ add_concurrent_index :ci_job_artifacts, :id, where: "file_type = 3 AND expire_at IN (#{TIMESTAMPS})", name: INDEX_NAME
+ end
+
+ def down
+ remove_concurrent_index_by_name :ci_job_artifacts, INDEX_NAME
+ end
+end
diff --git a/db/post_migrate/20220131000001_schedule_trace_expiry_removal.rb b/db/post_migrate/20220131000001_schedule_trace_expiry_removal.rb
new file mode 100644
index 00000000000..8e282a9b8c2
--- /dev/null
+++ b/db/post_migrate/20220131000001_schedule_trace_expiry_removal.rb
@@ -0,0 +1,55 @@
+# frozen_string_literal: true
+
+class ScheduleTraceExpiryRemoval < Gitlab::Database::Migration[1.0]
+ MIGRATION = 'RemoveAllTraceExpirationDates'
+ BATCH_SIZE = 100_000
+ DELAY_INTERVAL = 4.minutes
+
+ disable_ddl_transaction!
+
+ # Stubbed class to connect to the CI database
+ # connects_to has to be called in abstract classes.
+ class MultiDbAdaptableClass < ActiveRecord::Base
+ self.abstract_class = true
+
+ if Gitlab::Database.has_config?(:ci)
+ connects_to database: { writing: :ci, reading: :ci }
+ end
+ end
+
+ # Stubbed class to access the ci_job_artifacts table
+ class JobArtifact < MultiDbAdaptableClass
+ include EachBatch
+
+ self.table_name = 'ci_job_artifacts'
+
+ TARGET_TIMESTAMPS = [
+ Date.new(2021, 04, 22).midnight.utc,
+ Date.new(2021, 05, 22).midnight.utc,
+ Date.new(2021, 06, 22).midnight.utc,
+ Date.new(2022, 01, 22).midnight.utc,
+ Date.new(2022, 02, 22).midnight.utc,
+ Date.new(2022, 03, 22).midnight.utc,
+ Date.new(2022, 04, 22).midnight.utc
+ ].freeze
+
+ scope :in_targeted_timestamps, -> { where(expire_at: TARGET_TIMESTAMPS) }
+ scope :traces, -> { where(file_type: 3) }
+ end
+
+ def up
+ return unless Gitlab.com?
+
+ queue_background_migration_jobs_by_range_at_intervals(
+ JobArtifact.traces.in_targeted_timestamps,
+ MIGRATION,
+ DELAY_INTERVAL,
+ batch_size: BATCH_SIZE,
+ track_jobs: true
+ )
+ end
+
+ def down
+ # no-op
+ end
+end
diff --git a/db/post_migrate/20220204110725_backfill_cycle_analytics_aggregations.rb b/db/post_migrate/20220204110725_backfill_cycle_analytics_aggregations.rb
new file mode 100644
index 00000000000..933ad747c5c
--- /dev/null
+++ b/db/post_migrate/20220204110725_backfill_cycle_analytics_aggregations.rb
@@ -0,0 +1,33 @@
+# frozen_string_literal: true
+
+class BackfillCycleAnalyticsAggregations < Gitlab::Database::Migration[1.0]
+ BATCH_SIZE = 50
+
+ def up
+ model = define_batchable_model('analytics_cycle_analytics_group_value_streams')
+
+ model.each_batch(of: BATCH_SIZE) do |relation|
+ execute <<~SQL
+ WITH records_to_be_inserted AS #{Gitlab::Database::AsWithMaterialized.materialized_if_supported} (
+ SELECT root_ancestor.id AS group_id
+ FROM (#{relation.select(:group_id).to_sql}) as value_streams,
+ LATERAL (
+ WITH RECURSIVE "base_and_ancestors" AS (
+ (SELECT "namespaces"."id", "namespaces"."parent_id" FROM "namespaces" WHERE "namespaces"."id" = value_streams.group_id)
+ UNION
+ (SELECT "namespaces"."id", "namespaces"."parent_id" FROM "namespaces", "base_and_ancestors" WHERE "namespaces"."id" = "base_and_ancestors"."parent_id")
+ )
+ SELECT "namespaces"."id" FROM "base_and_ancestors" as "namespaces" WHERE parent_id IS NULL LIMIT 1
+ ) as root_ancestor
+ )
+ INSERT INTO "analytics_cycle_analytics_aggregations"
+ SELECT * FROM "records_to_be_inserted"
+ ON CONFLICT DO NOTHING
+ SQL
+ end
+ end
+
+ def down
+ # no-op
+ end
+end
diff --git a/db/post_migrate/20220204194347_encrypt_integration_properties.rb b/db/post_migrate/20220204194347_encrypt_integration_properties.rb
new file mode 100644
index 00000000000..82dd3a05e1d
--- /dev/null
+++ b/db/post_migrate/20220204194347_encrypt_integration_properties.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+class EncryptIntegrationProperties < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+ MIGRATION = 'EncryptIntegrationProperties'
+ BATCH_SIZE = 1_000
+ INTERVAL = 2.minutes.to_i
+
+ def up
+ queue_background_migration_jobs_by_range_at_intervals(
+ define_batchable_model('integrations').all,
+ MIGRATION,
+ INTERVAL,
+ track_jobs: true,
+ batch_size: BATCH_SIZE
+ )
+ end
+
+ def down
+ # this migration is not reversible
+ end
+end
diff --git a/db/post_migrate/20220207080758_update_api_indexes_for_projects.rb b/db/post_migrate/20220207080758_update_api_indexes_for_projects.rb
new file mode 100644
index 00000000000..3275912b0ab
--- /dev/null
+++ b/db/post_migrate/20220207080758_update_api_indexes_for_projects.rb
@@ -0,0 +1,48 @@
+# frozen_string_literal: true
+
+class UpdateApiIndexesForProjects < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ ARCHIVED_INDEX_NAME = 'idx_projects_api_created_at_id_for_archived'
+ OLD_ARCHIVED_INDEX_NAME = 'index_projects_api_created_at_id_for_archived'
+ PUBLIC_AND_ARCHIVED_INDEX_NAME = 'idx_projects_api_created_at_id_for_archived_vis20'
+ OLD_PUBLIC_AND_ARCHIVED_INDEX_NAME = 'index_projects_api_created_at_id_for_archived_vis20'
+ INTERNAL_PROJECTS_INDEX_NAME = 'idx_projects_api_created_at_id_for_vis10'
+ OLD_INTERNAL_PROJECTS_INDEX_NAME = 'index_projects_api_created_at_id_for_vis10'
+
+ def up
+ add_concurrent_index :projects, [:created_at, :id],
+ where: "archived = true AND pending_delete = false AND hidden = false",
+ name: ARCHIVED_INDEX_NAME
+
+ add_concurrent_index :projects, [:created_at, :id],
+ where: "archived = true AND visibility_level = 20 AND pending_delete = false AND hidden = false",
+ name: PUBLIC_AND_ARCHIVED_INDEX_NAME
+
+ add_concurrent_index :projects, [:created_at, :id],
+ where: "visibility_level = 10 AND pending_delete = false AND hidden = false",
+ name: INTERNAL_PROJECTS_INDEX_NAME
+
+ remove_concurrent_index_by_name :projects, OLD_ARCHIVED_INDEX_NAME
+ remove_concurrent_index_by_name :projects, OLD_PUBLIC_AND_ARCHIVED_INDEX_NAME
+ remove_concurrent_index_by_name :projects, OLD_INTERNAL_PROJECTS_INDEX_NAME
+ end
+
+ def down
+ add_concurrent_index :projects, [:created_at, :id],
+ where: "archived = true AND pending_delete = false",
+ name: OLD_ARCHIVED_INDEX_NAME
+
+ add_concurrent_index :projects, [:created_at, :id],
+ where: "archived = true AND visibility_level = 20 AND pending_delete = false",
+ name: OLD_PUBLIC_AND_ARCHIVED_INDEX_NAME
+
+ add_concurrent_index :projects, [:created_at, :id],
+ where: "visibility_level = 10 AND pending_delete = false",
+ name: OLD_INTERNAL_PROJECTS_INDEX_NAME
+
+ remove_concurrent_index_by_name :projects, ARCHIVED_INDEX_NAME
+ remove_concurrent_index_by_name :projects, PUBLIC_AND_ARCHIVED_INDEX_NAME
+ remove_concurrent_index_by_name :projects, INTERNAL_PROJECTS_INDEX_NAME
+ end
+end
diff --git a/db/post_migrate/20220208080921_schedule_migrate_personal_namespace_project_maintainer_to_owner.rb b/db/post_migrate/20220208080921_schedule_migrate_personal_namespace_project_maintainer_to_owner.rb
new file mode 100644
index 00000000000..633570aeaa0
--- /dev/null
+++ b/db/post_migrate/20220208080921_schedule_migrate_personal_namespace_project_maintainer_to_owner.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+class ScheduleMigratePersonalNamespaceProjectMaintainerToOwner < Gitlab::Database::Migration[1.0]
+ MIGRATION = 'MigratePersonalNamespaceProjectMaintainerToOwner'
+ INTERVAL = 2.minutes
+ BATCH_SIZE = 1_000
+ SUB_BATCH_SIZE = 200
+
+ disable_ddl_transaction!
+
+ def up
+ queue_batched_background_migration(
+ MIGRATION,
+ :members,
+ :id,
+ job_interval: INTERVAL,
+ batch_size: BATCH_SIZE,
+ sub_batch_size: SUB_BATCH_SIZE
+ )
+ end
+
+ def down
+ # no-op
+ end
+end
diff --git a/db/post_migrate/20220215190020_rerun_convert_stringified_raw_metadata_hash_to_json.rb b/db/post_migrate/20220215190020_rerun_convert_stringified_raw_metadata_hash_to_json.rb
new file mode 100644
index 00000000000..1f36132c578
--- /dev/null
+++ b/db/post_migrate/20220215190020_rerun_convert_stringified_raw_metadata_hash_to_json.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+class RerunConvertStringifiedRawMetadataHashToJson < Gitlab::Database::Migration[1.0]
+ MIGRATION_CLASS = Gitlab::BackgroundMigration::FixVulnerabilityOccurrencesWithHashesAsRawMetadata
+ MODEL_CLASS = MIGRATION_CLASS::Finding
+ DELAY_INTERVAL = 2.minutes
+ BATCH_SIZE = 500
+
+ disable_ddl_transaction!
+
+ def up
+ queue_background_migration_jobs_by_range_at_intervals(
+ MODEL_CLASS.by_api_report_types,
+ MIGRATION_CLASS.name.demodulize,
+ DELAY_INTERVAL,
+ batch_size: BATCH_SIZE,
+ track_jobs: true
+ )
+ end
+
+ def down
+ # no-op
+
+ # up fixes invalid data by updating columns in-place.
+ # It is a backwards-compatible change, and reversing it in a downgrade would not be desirable.
+ end
+end
diff --git a/db/post_migrate/20220216201949_remove_package_files_limit_from_application_settings.rb b/db/post_migrate/20220216201949_remove_package_files_limit_from_application_settings.rb
new file mode 100644
index 00000000000..589b75dd918
--- /dev/null
+++ b/db/post_migrate/20220216201949_remove_package_files_limit_from_application_settings.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+class RemovePackageFilesLimitFromApplicationSettings < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ def up
+ return unless column_exists?(:application_settings, :max_package_files_for_package_destruction)
+
+ remove_column :application_settings, :max_package_files_for_package_destruction, :smallint
+ end
+
+ def down
+ add_column :application_settings, :max_package_files_for_package_destruction, :smallint, default: 100, null: false
+ add_check_constraint :application_settings,
+ 'max_package_files_for_package_destruction > 0',
+ 'app_settings_max_package_files_for_package_destruction_positive'
+ end
+end
diff --git a/db/post_migrate/20220217135229_validate_not_null_constraint_on_security_findings_uuid.rb b/db/post_migrate/20220217135229_validate_not_null_constraint_on_security_findings_uuid.rb
new file mode 100644
index 00000000000..9cc04cef757
--- /dev/null
+++ b/db/post_migrate/20220217135229_validate_not_null_constraint_on_security_findings_uuid.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+class ValidateNotNullConstraintOnSecurityFindingsUuid < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ def up
+ validate_not_null_constraint(:security_findings, :uuid)
+ end
+
+ def down
+ # no-op
+ end
+end
diff --git a/db/post_migrate/20220221214928_remove_show_diff_preview_in_email_column.rb b/db/post_migrate/20220221214928_remove_show_diff_preview_in_email_column.rb
new file mode 100644
index 00000000000..41cd3446c7a
--- /dev/null
+++ b/db/post_migrate/20220221214928_remove_show_diff_preview_in_email_column.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+class RemoveShowDiffPreviewInEmailColumn < Gitlab::Database::Migration[1.0]
+ enable_lock_retries!
+
+ def up
+ remove_column :project_settings, :show_diff_preview_in_email, :boolean
+ end
+
+ def down
+ add_column :project_settings, :show_diff_preview_in_email, :boolean, default: true, null: false
+ end
+end
diff --git a/db/post_migrate/20220222191845_remove_not_null_constraint_for_security_scan_succeeded.rb b/db/post_migrate/20220222191845_remove_not_null_constraint_for_security_scan_succeeded.rb
new file mode 100644
index 00000000000..4d4a20b83b3
--- /dev/null
+++ b/db/post_migrate/20220222191845_remove_not_null_constraint_for_security_scan_succeeded.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+class RemoveNotNullConstraintForSecurityScanSucceeded < Gitlab::Database::Migration[1.0]
+ def up
+ change_column_null :analytics_devops_adoption_snapshots, :security_scan_succeeded, true
+ end
+
+ def down
+ # There may now be nulls in the table, so we cannot re-add the constraint here.
+ end
+end
diff --git a/db/post_migrate/20220222192524_create_not_null_constraint_releases_tag.rb b/db/post_migrate/20220222192524_create_not_null_constraint_releases_tag.rb
new file mode 100644
index 00000000000..2bb5ba18743
--- /dev/null
+++ b/db/post_migrate/20220222192524_create_not_null_constraint_releases_tag.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+class CreateNotNullConstraintReleasesTag < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ def up
+ add_not_null_constraint :releases, :tag, constraint_name: 'releases_not_null_tag', validate: false
+ end
+
+ def down
+ remove_not_null_constraint :releases, :tag, constraint_name: 'releases_not_null_tag'
+ end
+end
diff --git a/db/post_migrate/20220222192525_remove_null_releases.rb b/db/post_migrate/20220222192525_remove_null_releases.rb
new file mode 100644
index 00000000000..4efd5393122
--- /dev/null
+++ b/db/post_migrate/20220222192525_remove_null_releases.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+class RemoveNullReleases < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ class Release < ActiveRecord::Base
+ include EachBatch
+
+ self.table_name = 'releases'
+ end
+
+ def up
+ Release.all.each_batch(of: 25000) do |rel|
+ rel.where(tag: nil).delete_all
+ end
+ end
+
+ def down
+ # no-op
+ #
+ # releases with the same tag within a project have been removed
+ # and therefore the duplicate release data is no longer available
+ end
+end
diff --git a/db/post_migrate/20220223112304_schedule_nullify_orphan_runner_id_on_ci_builds.rb b/db/post_migrate/20220223112304_schedule_nullify_orphan_runner_id_on_ci_builds.rb
new file mode 100644
index 00000000000..e4005885c3b
--- /dev/null
+++ b/db/post_migrate/20220223112304_schedule_nullify_orphan_runner_id_on_ci_builds.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+class ScheduleNullifyOrphanRunnerIdOnCiBuilds < Gitlab::Database::Migration[1.0]
+ MIGRATION = 'NullifyOrphanRunnerIdOnCiBuilds'
+ INTERVAL = 2.minutes
+ BATCH_SIZE = 50_000
+ MAX_BATCH_SIZE = 150_000
+ SUB_BATCH_SIZE = 500
+
+ def up
+ queue_batched_background_migration(
+ MIGRATION,
+ :ci_builds,
+ :id,
+ job_interval: INTERVAL,
+ batch_size: BATCH_SIZE,
+ max_batch_size: MAX_BATCH_SIZE,
+ sub_batch_size: SUB_BATCH_SIZE
+ )
+ end
+
+ def down
+ Gitlab::Database::BackgroundMigration::BatchedMigration
+ .for_configuration(MIGRATION, :ci_builds, :id, [])
+ .delete_all
+ end
+end
diff --git a/db/post_migrate/20220224000000_async_build_trace_expire_at_index.rb b/db/post_migrate/20220224000000_async_build_trace_expire_at_index.rb
new file mode 100644
index 00000000000..b22f3e7996f
--- /dev/null
+++ b/db/post_migrate/20220224000000_async_build_trace_expire_at_index.rb
@@ -0,0 +1,14 @@
+# frozen_string_literal: true
+
+class AsyncBuildTraceExpireAtIndex < Gitlab::Database::Migration[1.0]
+ INDEX_NAME = 'tmp_index_ci_job_artifacts_on_id_where_trace_and_expire_at'
+ TIMESTAMPS = "'2021-04-22 00:00:00', '2021-05-22 00:00:00', '2021-06-22 00:00:00', '2022-01-22 00:00:00', '2022-02-22 00:00:00', '2022-03-22 00:00:00', '2022-04-22 00:00:00'"
+
+ def up
+ prepare_async_index :ci_job_artifacts, :id, where: "file_type = 3 AND expire_at IN (#{TIMESTAMPS})", name: INDEX_NAME
+ end
+
+ def down
+ unprepare_async_index :ci_builds, :id, name: INDEX_NAME
+ end
+end
diff --git a/db/post_migrate/20220224204415_recreate_index_security_ci_builds_on_name_and_id_parser_with_new_features.rb b/db/post_migrate/20220224204415_recreate_index_security_ci_builds_on_name_and_id_parser_with_new_features.rb
new file mode 100644
index 00000000000..feb0f2c83ab
--- /dev/null
+++ b/db/post_migrate/20220224204415_recreate_index_security_ci_builds_on_name_and_id_parser_with_new_features.rb
@@ -0,0 +1,31 @@
+# frozen_string_literal: true
+
+class RecreateIndexSecurityCiBuildsOnNameAndIdParserWithNewFeatures < Gitlab::Database::Migration[1.0]
+ TABLE = "ci_builds"
+ OLD_INDEX_NAME = "index_security_ci_builds_on_name_and_id_parser_features"
+ NEW_INDEX_NAME = "index_security_ci_builds_on_name_and_id_parser_features_old"
+ COLUMNS = %i[name id]
+ CONSTRAINTS = "(name::text = ANY (ARRAY['container_scanning'::character varying::text,
+ 'dast'::character varying::text,
+ 'dependency_scanning'::character varying::text,
+ 'license_management'::character varying::text,
+ 'sast'::character varying::text,
+ 'secret_detection'::character varying::text,
+ 'coverage_fuzzing'::character varying::text,
+ 'license_scanning'::character varying::text,
+ 'apifuzzer_fuzz'::character varying::text,
+ 'apifuzzer_fuzz_dnd'::character varying::text])
+ ) AND type::text = 'Ci::Build'::text"
+
+ enable_lock_retries!
+
+ def up
+ rename_index(TABLE, OLD_INDEX_NAME, NEW_INDEX_NAME)
+ prepare_async_index TABLE, COLUMNS, name: OLD_INDEX_NAME, where: CONSTRAINTS
+ end
+
+ def down
+ unprepare_async_index TABLE, COLUMNS, name: OLD_INDEX_NAME
+ rename_index(TABLE, NEW_INDEX_NAME, OLD_INDEX_NAME)
+ end
+end
diff --git a/db/post_migrate/20220225133705_cleanup_backfill_ci_queuing_tables.rb b/db/post_migrate/20220225133705_cleanup_backfill_ci_queuing_tables.rb
new file mode 100644
index 00000000000..4fcf8a28727
--- /dev/null
+++ b/db/post_migrate/20220225133705_cleanup_backfill_ci_queuing_tables.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class CleanupBackfillCiQueuingTables < Gitlab::Database::Migration[1.0]
+ MIGRATION = 'BackfillCiQueuingTables'
+
+ disable_ddl_transaction!
+
+ def up
+ finalize_background_migration(MIGRATION)
+ end
+
+ def down
+ # no-op
+ end
+end
diff --git a/db/post_migrate/20220301093434_backfill_all_project_namespaces.rb b/db/post_migrate/20220301093434_backfill_all_project_namespaces.rb
new file mode 100644
index 00000000000..7071e6241ce
--- /dev/null
+++ b/db/post_migrate/20220301093434_backfill_all_project_namespaces.rb
@@ -0,0 +1,30 @@
+# frozen_string_literal: true
+
+class BackfillAllProjectNamespaces < Gitlab::Database::Migration[1.0]
+ MIGRATION = 'ProjectNamespaces::BackfillProjectNamespaces'
+ DELAY_INTERVAL = 2.minutes
+ BATCH_SIZE = 1_000
+ MAX_BATCH_SIZE = 5_000
+ SUB_BATCH_SIZE = 10
+
+ disable_ddl_transaction!
+
+ def up
+ queue_batched_background_migration(
+ MIGRATION,
+ :projects,
+ :id,
+ nil,
+ 'up',
+ job_interval: DELAY_INTERVAL,
+ batch_size: BATCH_SIZE,
+ max_batch_size: MAX_BATCH_SIZE,
+ sub_batch_size: SUB_BATCH_SIZE
+ )
+ end
+
+ def down
+ Gitlab::Database::BackgroundMigration::BatchedMigration
+ .for_configuration(MIGRATION, :projects, :id, [nil, 'up']).delete_all
+ end
+end
diff --git a/db/post_migrate/20220302203410_create_index_security_ci_builds_on_name_and_id_parser_with_new_features.rb b/db/post_migrate/20220302203410_create_index_security_ci_builds_on_name_and_id_parser_with_new_features.rb
new file mode 100644
index 00000000000..5be6bb00269
--- /dev/null
+++ b/db/post_migrate/20220302203410_create_index_security_ci_builds_on_name_and_id_parser_with_new_features.rb
@@ -0,0 +1,28 @@
+# frozen_string_literal: true
+
+class CreateIndexSecurityCiBuildsOnNameAndIdParserWithNewFeatures < Gitlab::Database::Migration[1.0]
+ TABLE = "ci_builds"
+ COLUMNS = %i[name id]
+ INDEX_NAME = "index_security_ci_builds_on_name_and_id_parser_features"
+ CONSTRAINTS = "(name::text = ANY (ARRAY['container_scanning'::character varying::text,
+ 'dast'::character varying::text,
+ 'dependency_scanning'::character varying::text,
+ 'license_management'::character varying::text,
+ 'sast'::character varying::text,
+ 'secret_detection'::character varying::text,
+ 'coverage_fuzzing'::character varying::text,
+ 'license_scanning'::character varying::text,
+ 'apifuzzer_fuzz'::character varying::text,
+ 'apifuzzer_fuzz_dnd'::character varying::text])
+ ) AND type::text = 'Ci::Build'::text"
+
+ disable_ddl_transaction!
+
+ def up
+ add_concurrent_index(TABLE, COLUMNS, name: INDEX_NAME, where: CONSTRAINTS)
+ end
+
+ def down
+ remove_concurrent_index(TABLE, COLUMNS, name: INDEX_NAME, where: CONSTRAINTS)
+ end
+end
diff --git a/db/post_migrate/20220304165107_drop_partitioned_foreign_keys.rb b/db/post_migrate/20220304165107_drop_partitioned_foreign_keys.rb
new file mode 100644
index 00000000000..43f89b05fa4
--- /dev/null
+++ b/db/post_migrate/20220304165107_drop_partitioned_foreign_keys.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class DropPartitionedForeignKeys < Gitlab::Database::Migration[1.0]
+ def up
+ drop_table :partitioned_foreign_keys
+ end
+
+ def down
+ create_table :partitioned_foreign_keys do |t|
+ t.boolean :cascade_delete, null: false, default: true
+ t.text :from_table, null: false, limit: 63
+ t.text :from_column, null: false, limit: 63
+ t.text :to_table, null: false, limit: 63
+ t.text :to_column, null: false, limit: 63
+
+ t.index [:to_table, :from_table, :from_column], unique: true, name: :index_partitioned_foreign_keys_unique_index
+ end
+ end
+end
diff --git a/db/post_migrate/20220304201847_add_unique_index_on_security_training_providers.rb b/db/post_migrate/20220304201847_add_unique_index_on_security_training_providers.rb
new file mode 100644
index 00000000000..e78b8fd48ca
--- /dev/null
+++ b/db/post_migrate/20220304201847_add_unique_index_on_security_training_providers.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class AddUniqueIndexOnSecurityTrainingProviders < Gitlab::Database::Migration[1.0]
+ INDEX_NAME = 'index_security_training_providers_on_unique_name'
+
+ disable_ddl_transaction!
+
+ def up
+ add_concurrent_index :security_training_providers, :name, unique: true, name: INDEX_NAME
+ end
+
+ def down
+ remove_concurrent_index_by_name :security_training_providers, INDEX_NAME
+ end
+end
diff --git a/db/post_migrate/20220305223212_add_security_training_providers.rb b/db/post_migrate/20220305223212_add_security_training_providers.rb
new file mode 100644
index 00000000000..fbddee0ae99
--- /dev/null
+++ b/db/post_migrate/20220305223212_add_security_training_providers.rb
@@ -0,0 +1,40 @@
+# frozen_string_literal: true
+
+class AddSecurityTrainingProviders < Gitlab::Database::Migration[1.0]
+ KONTRA_DATA = {
+ name: 'Kontra',
+ description: "Kontra Application Security provides interactive developer security education that
+ enables engineers to quickly learn security best practices
+ and fix issues in their code by analysing real-world software security vulnerabilities.",
+ url: "https://application.security/api/webhook/gitlab/exercises/search"
+ }
+
+ SCW_DATA = {
+ name: 'Secure Code Warrior',
+ description: "Resolve vulnerabilities faster and confidently with highly relevant and bite-sized secure coding learning.",
+ url: "https://integration-api.securecodewarrior.com/api/v1/trial"
+ }
+
+ module Security
+ class TrainingProvider < ActiveRecord::Base
+ self.table_name = 'security_training_providers'
+ end
+ end
+
+ def up
+ current_time = Time.current
+ timestamps = { created_at: current_time, updated_at: current_time }
+
+ Security::TrainingProvider.reset_column_information
+
+ # upsert providers
+ Security::TrainingProvider.upsert_all([KONTRA_DATA.merge(timestamps), SCW_DATA.merge(timestamps)])
+ end
+
+ def down
+ Security::TrainingProvider.reset_column_information
+
+ Security::TrainingProvider.find_by(name: KONTRA_DATA[:name])&.destroy
+ Security::TrainingProvider.find_by(name: SCW_DATA[:name])&.destroy
+ end
+end
diff --git a/db/post_migrate/20220307192534_create_index_for_remove_duplicate_project_tag_releases.rb b/db/post_migrate/20220307192534_create_index_for_remove_duplicate_project_tag_releases.rb
new file mode 100644
index 00000000000..3e580c013c3
--- /dev/null
+++ b/db/post_migrate/20220307192534_create_index_for_remove_duplicate_project_tag_releases.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class CreateIndexForRemoveDuplicateProjectTagReleases < Gitlab::Database::Migration[1.0]
+ INDEX_NAME = 'index_releases_on_id_project_id_tag'
+
+ disable_ddl_transaction!
+
+ def up
+ add_concurrent_index :releases,
+ %i[project_id tag id],
+ name: INDEX_NAME
+ end
+
+ def down
+ remove_concurrent_index_by_name :releases, name: INDEX_NAME
+ end
+end
diff --git a/db/post_migrate/20220307192610_remove_duplicate_project_tag_releases.rb b/db/post_migrate/20220307192610_remove_duplicate_project_tag_releases.rb
new file mode 100644
index 00000000000..d8b99380825
--- /dev/null
+++ b/db/post_migrate/20220307192610_remove_duplicate_project_tag_releases.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+class RemoveDuplicateProjectTagReleases < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ class Release < ActiveRecord::Base
+ include EachBatch
+
+ self.table_name = 'releases'
+ end
+
+ def up
+ Release.each_batch(of: 5000) do |relation|
+ relation
+ .where('exists (select 1 from releases r2 where r2.project_id = releases.project_id and r2.tag = releases.tag and r2.id > releases.id)')
+ .delete_all
+ end
+ end
+
+ def down
+ # no-op
+ #
+ # releases with the same tag within a project have been removed
+ # and therefore the duplicate release data is no longer available
+ end
+end
diff --git a/db/post_migrate/20220307192645_remove_index_for_remove_duplicate_project_tag_releases.rb b/db/post_migrate/20220307192645_remove_index_for_remove_duplicate_project_tag_releases.rb
new file mode 100644
index 00000000000..8efb24daff9
--- /dev/null
+++ b/db/post_migrate/20220307192645_remove_index_for_remove_duplicate_project_tag_releases.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class RemoveIndexForRemoveDuplicateProjectTagReleases < Gitlab::Database::Migration[1.0]
+ INDEX_NAME = 'index_releases_on_id_project_id_tag'
+
+ disable_ddl_transaction!
+
+ def up
+ remove_concurrent_index_by_name :releases, name: INDEX_NAME
+ end
+
+ def down
+ add_concurrent_index :releases,
+ %i[project_id tag id],
+ name: INDEX_NAME
+ end
+end
diff --git a/db/post_migrate/20220307192725_create_unique_index_release_tag_project.rb b/db/post_migrate/20220307192725_create_unique_index_release_tag_project.rb
new file mode 100644
index 00000000000..8540f19f079
--- /dev/null
+++ b/db/post_migrate/20220307192725_create_unique_index_release_tag_project.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+class CreateUniqueIndexReleaseTagProject < Gitlab::Database::Migration[1.0]
+ INDEX_NAME = 'index_releases_on_project_tag_unique'
+ OLD_INDEX_NAME = 'index_releases_on_project_id_and_tag'
+
+ disable_ddl_transaction!
+
+ def up
+ add_concurrent_index :releases,
+ %i[project_id tag],
+ unique: true,
+ name: INDEX_NAME
+ remove_concurrent_index_by_name :releases, name: OLD_INDEX_NAME
+ end
+
+ def down
+ remove_concurrent_index_by_name :releases, name: INDEX_NAME
+ add_concurrent_index :releases,
+ %i[project_id tag],
+ name: OLD_INDEX_NAME
+ end
+end
diff --git a/db/post_migrate/20220307203459_rename_user_email_lookup_limit_setting_to_search_settings_cleanup.rb b/db/post_migrate/20220307203459_rename_user_email_lookup_limit_setting_to_search_settings_cleanup.rb
new file mode 100644
index 00000000000..2d01374780d
--- /dev/null
+++ b/db/post_migrate/20220307203459_rename_user_email_lookup_limit_setting_to_search_settings_cleanup.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class RenameUserEmailLookupLimitSettingToSearchSettingsCleanup < Gitlab::Database::Migration[1.0]
+ class ApplicationSetting < ActiveRecord::Base
+ self.table_name = :application_settings
+ end
+
+ def up
+ ApplicationSetting.update_all 'search_rate_limit=user_email_lookup_limit'
+ end
+
+ def down
+ ApplicationSetting.update_all 'user_email_lookup_limit=search_rate_limit'
+ end
+end
diff --git a/db/post_migrate/20220308000205_drop_old_index_security_ci_builds_on_name_and_id_parser_features.rb b/db/post_migrate/20220308000205_drop_old_index_security_ci_builds_on_name_and_id_parser_features.rb
new file mode 100644
index 00000000000..4b895c291d8
--- /dev/null
+++ b/db/post_migrate/20220308000205_drop_old_index_security_ci_builds_on_name_and_id_parser_features.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+class DropOldIndexSecurityCiBuildsOnNameAndIdParserFeatures < Gitlab::Database::Migration[1.0]
+ TABLE = "ci_builds"
+ COLUMNS = %i[name id]
+ INDEX_NAME = "index_security_ci_builds_on_name_and_id_parser_features_old"
+ CONSTRAINTS = "(name::text = ANY (ARRAY['container_scanning'::character varying::text,
+ 'dast'::character varying::text,
+ 'dependency_scanning'::character varying::text,
+ 'license_management'::character varying::text,
+ 'sast'::character varying::text,
+ 'secret_detection'::character varying::text,
+ 'coverage_fuzzing'::character varying::text,
+ 'license_scanning'::character varying::text])
+ ) AND type::text = 'Ci::Build'::text"
+
+ disable_ddl_transaction!
+
+ def up
+ remove_concurrent_index(TABLE, COLUMNS, name: INDEX_NAME, where: CONSTRAINTS)
+ end
+
+ def down
+ add_concurrent_index(TABLE, COLUMNS, name: INDEX_NAME, where: CONSTRAINTS)
+ end
+end
diff --git a/db/post_migrate/20220308115219_schedule_reset_duplicate_ci_runners_token_encrypted_values_on_projects.rb b/db/post_migrate/20220308115219_schedule_reset_duplicate_ci_runners_token_encrypted_values_on_projects.rb
new file mode 100644
index 00000000000..27e7af9a550
--- /dev/null
+++ b/db/post_migrate/20220308115219_schedule_reset_duplicate_ci_runners_token_encrypted_values_on_projects.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+class ScheduleResetDuplicateCiRunnersTokenEncryptedValuesOnProjects < Gitlab::Database::Migration[1.0]
+ MIGRATION = 'ResetDuplicateCiRunnersTokenEncryptedValuesOnProjects'
+ TOKEN_COLUMN_NAME = :runners_token_encrypted
+ TEMP_INDEX_NAME = "tmp_index_projects_on_id_and_#{TOKEN_COLUMN_NAME}"
+ BATCH_SIZE = 10_000
+ DELAY_INTERVAL = 2.minutes
+
+ disable_ddl_transaction!
+
+ def up
+ add_concurrent_index :projects, [:id, TOKEN_COLUMN_NAME], where: "#{TOKEN_COLUMN_NAME} IS NOT NULL", unique: false, name: TEMP_INDEX_NAME
+
+ queue_background_migration_jobs_by_range_at_intervals(
+ Gitlab::BackgroundMigration::ResetDuplicateCiRunnersTokenEncryptedValuesOnProjects::Project.base_query,
+ MIGRATION,
+ DELAY_INTERVAL,
+ batch_size: BATCH_SIZE,
+ track_jobs: true
+ )
+ end
+
+ def down
+ remove_concurrent_index_by_name(:projects, name: TEMP_INDEX_NAME)
+ end
+end
diff --git a/db/post_migrate/20220308115502_schedule_reset_duplicate_ci_runners_token_values_on_projects.rb b/db/post_migrate/20220308115502_schedule_reset_duplicate_ci_runners_token_values_on_projects.rb
new file mode 100644
index 00000000000..f076b0a740e
--- /dev/null
+++ b/db/post_migrate/20220308115502_schedule_reset_duplicate_ci_runners_token_values_on_projects.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+class ScheduleResetDuplicateCiRunnersTokenValuesOnProjects < Gitlab::Database::Migration[1.0]
+ MIGRATION = 'ResetDuplicateCiRunnersTokenValuesOnProjects'
+ TOKEN_COLUMN_NAME = :runners_token
+ TEMP_INDEX_NAME = "tmp_index_projects_on_id_and_#{TOKEN_COLUMN_NAME}"
+ BATCH_SIZE = 10_000
+ DELAY_INTERVAL = 2.minutes
+
+ disable_ddl_transaction!
+
+ def up
+ add_concurrent_index :projects, [:id, TOKEN_COLUMN_NAME], where: "#{TOKEN_COLUMN_NAME} IS NOT NULL", unique: false, name: TEMP_INDEX_NAME
+
+ queue_background_migration_jobs_by_range_at_intervals(
+ Gitlab::BackgroundMigration::ResetDuplicateCiRunnersTokenValuesOnProjects::Project.base_query,
+ MIGRATION,
+ DELAY_INTERVAL,
+ batch_size: BATCH_SIZE,
+ track_jobs: true
+ )
+ end
+
+ def down
+ remove_concurrent_index_by_name(:projects, name: TEMP_INDEX_NAME)
+ end
+end
diff --git a/db/post_migrate/20220309084838_remove_external_pull_request_tracking.rb b/db/post_migrate/20220309084838_remove_external_pull_request_tracking.rb
new file mode 100644
index 00000000000..6159f9d6822
--- /dev/null
+++ b/db/post_migrate/20220309084838_remove_external_pull_request_tracking.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class RemoveExternalPullRequestTracking < Gitlab::Database::Migration[1.0]
+ include Gitlab::Database::MigrationHelpers::LooseForeignKeyHelpers
+
+ enable_lock_retries!
+
+ def up
+ untrack_record_deletions(:external_pull_requests)
+ end
+
+ def down
+ track_record_deletions(:external_pull_requests)
+ end
+end
diff --git a/db/post_migrate/20220309084954_remove_leftover_external_pull_request_deletions.rb b/db/post_migrate/20220309084954_remove_leftover_external_pull_request_deletions.rb
new file mode 100644
index 00000000000..ea9fd6b28c2
--- /dev/null
+++ b/db/post_migrate/20220309084954_remove_leftover_external_pull_request_deletions.rb
@@ -0,0 +1,30 @@
+# frozen_string_literal: true
+
+class RemoveLeftoverExternalPullRequestDeletions < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ def up
+ # Delete all pending record deletions in the public.external_pull_requests until
+ # there are no more rows left.
+ loop do
+ result = execute <<~SQL
+ DELETE FROM "loose_foreign_keys_deleted_records"
+ WHERE
+ ("loose_foreign_keys_deleted_records"."partition", "loose_foreign_keys_deleted_records"."id") IN (
+ SELECT "loose_foreign_keys_deleted_records"."partition", "loose_foreign_keys_deleted_records"."id"
+ FROM "loose_foreign_keys_deleted_records"
+ WHERE
+ "loose_foreign_keys_deleted_records"."fully_qualified_table_name" = 'public.external_pull_requests' AND
+ "loose_foreign_keys_deleted_records"."status" = 1
+ LIMIT 100
+ )
+ SQL
+
+ break if result.cmd_tuples == 0
+ end
+ end
+
+ def down
+ # no-op
+ end
+end
diff --git a/db/post_migrate/20220309154855_add_index_on_issues_closed_incidents.rb b/db/post_migrate/20220309154855_add_index_on_issues_closed_incidents.rb
new file mode 100644
index 00000000000..e9a2c1c85f2
--- /dev/null
+++ b/db/post_migrate/20220309154855_add_index_on_issues_closed_incidents.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class AddIndexOnIssuesClosedIncidents < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ INDEX_NAME = 'index_on_issues_closed_incidents_by_project_id_and_closed_at'
+
+ def up
+ add_concurrent_index :issues, [:project_id, :closed_at], where: "issue_type = 1 AND state_id = 2", name: INDEX_NAME
+ end
+
+ def down
+ remove_concurrent_index_by_name :issues, INDEX_NAME
+ end
+end
diff --git a/db/post_migrate/20220310095341_add_async_index_ci_job_artifacts_project_id_created_at.rb b/db/post_migrate/20220310095341_add_async_index_ci_job_artifacts_project_id_created_at.rb
new file mode 100644
index 00000000000..919e834a783
--- /dev/null
+++ b/db/post_migrate/20220310095341_add_async_index_ci_job_artifacts_project_id_created_at.rb
@@ -0,0 +1,16 @@
+# 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 AddAsyncIndexCiJobArtifactsProjectIdCreatedAt < Gitlab::Database::Migration[1.0]
+ INDEX_NAME = 'index_ci_job_artifacts_on_id_project_id_and_created_at'
+
+ def up
+ prepare_async_index :ci_job_artifacts, [:project_id, :created_at, :id], name: INDEX_NAME
+ end
+
+ def down
+ unprepare_async_index_by_name :ci_job_artifacts, INDEX_NAME
+ end
+end
diff --git a/db/post_migrate/20220310134207_add_index_project_id_and_released_at_and_id_on_releases.rb b/db/post_migrate/20220310134207_add_index_project_id_and_released_at_and_id_on_releases.rb
new file mode 100644
index 00000000000..da928f3ec8f
--- /dev/null
+++ b/db/post_migrate/20220310134207_add_index_project_id_and_released_at_and_id_on_releases.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+class AddIndexProjectIdAndReleasedAtAndIdOnReleases < Gitlab::Database::Migration[1.0]
+ INDEX_NAME = 'index_releases_on_project_id_and_released_at_and_id'
+
+ disable_ddl_transaction!
+
+ def up
+ add_concurrent_index :releases, [:project_id, :released_at, :id],
+ name: INDEX_NAME
+ end
+
+ def down
+ remove_concurrent_index_by_name :releases, INDEX_NAME
+ end
+end
diff --git a/db/post_migrate/20220310141349_remove_dependency_list_usage_data_from_redis.rb b/db/post_migrate/20220310141349_remove_dependency_list_usage_data_from_redis.rb
new file mode 100644
index 00000000000..3c1e6714529
--- /dev/null
+++ b/db/post_migrate/20220310141349_remove_dependency_list_usage_data_from_redis.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+class RemoveDependencyListUsageDataFromRedis < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ def up
+ Gitlab::Redis::SharedState.with { |r| r.del("DEPENDENCY_LIST_USAGE_COUNTER") }
+ end
+
+ def down
+ # no-op
+ end
+end
diff --git a/db/post_migrate/20220314162342_add_index_ci_job_artifacts_project_id_created_at.rb b/db/post_migrate/20220314162342_add_index_ci_job_artifacts_project_id_created_at.rb
new file mode 100644
index 00000000000..7241fd54cb3
--- /dev/null
+++ b/db/post_migrate/20220314162342_add_index_ci_job_artifacts_project_id_created_at.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class AddIndexCiJobArtifactsProjectIdCreatedAt < Gitlab::Database::Migration[1.0]
+ INDEX_NAME = 'index_ci_job_artifacts_on_id_project_id_and_created_at'
+
+ disable_ddl_transaction!
+
+ def up
+ add_concurrent_index :ci_job_artifacts, [:project_id, :created_at, :id], name: INDEX_NAME
+ end
+
+ def down
+ remove_concurrent_index_by_name :ci_job_artifacts, INDEX_NAME
+ end
+end
diff --git a/db/schema_migrations/20210812013042 b/db/schema_migrations/20210812013042
new file mode 100644
index 00000000000..fee1a2b268a
--- /dev/null
+++ b/db/schema_migrations/20210812013042
@@ -0,0 +1 @@
+0af6e6e56967cef9d1160dbfd95456428337843d893307c69505e1a2d3c2074a \ No newline at end of file
diff --git a/db/schema_migrations/20211007090229 b/db/schema_migrations/20211007090229
new file mode 100644
index 00000000000..9302c958709
--- /dev/null
+++ b/db/schema_migrations/20211007090229
@@ -0,0 +1 @@
+9d87052305a552ce380e81a33c690496c44e332eb86869ea6882f5cd4856ab93 \ No newline at end of file
diff --git a/db/schema_migrations/20211021115409 b/db/schema_migrations/20211021115409
new file mode 100644
index 00000000000..bcbed298377
--- /dev/null
+++ b/db/schema_migrations/20211021115409
@@ -0,0 +1 @@
+93960203e6703716f9c513dca340e17041a33792f9233dc4b7e35d1e19614191 \ No newline at end of file
diff --git a/db/schema_migrations/20211021124715 b/db/schema_migrations/20211021124715
new file mode 100644
index 00000000000..2d03c608bac
--- /dev/null
+++ b/db/schema_migrations/20211021124715
@@ -0,0 +1 @@
+406af18458c7f5ee8a4fa3860ed5fb87c358363926fed2830be8e8a55578822b \ No newline at end of file
diff --git a/db/schema_migrations/20211026070408 b/db/schema_migrations/20211026070408
new file mode 100644
index 00000000000..e48db972388
--- /dev/null
+++ b/db/schema_migrations/20211026070408
@@ -0,0 +1 @@
+630899d5a7f833ce0533ae553de89e70bd03fad9b438fd367e3a568261b08b00 \ No newline at end of file
diff --git a/db/schema_migrations/20211203160952 b/db/schema_migrations/20211203160952
new file mode 100644
index 00000000000..10d033ef200
--- /dev/null
+++ b/db/schema_migrations/20211203160952
@@ -0,0 +1 @@
+f25c65dfcb5b7b4a663cc4c792ffd985f6afd3156036485a5a43a791ee799e7b \ No newline at end of file
diff --git a/db/schema_migrations/20211203161149 b/db/schema_migrations/20211203161149
new file mode 100644
index 00000000000..3f58490a89c
--- /dev/null
+++ b/db/schema_migrations/20211203161149
@@ -0,0 +1 @@
+01482a299a7dac9d3f786f0dbe4650c686911bf788467146d3e9a91eafd0fc32 \ No newline at end of file
diff --git a/db/schema_migrations/20211203161840 b/db/schema_migrations/20211203161840
new file mode 100644
index 00000000000..347bd0f7691
--- /dev/null
+++ b/db/schema_migrations/20211203161840
@@ -0,0 +1 @@
+1b895e979ba2f1696559179c46c000e349da2d1ab94c968dd95103f188425103 \ No newline at end of file
diff --git a/db/schema_migrations/20211203161942 b/db/schema_migrations/20211203161942
new file mode 100644
index 00000000000..f43c3733392
--- /dev/null
+++ b/db/schema_migrations/20211203161942
@@ -0,0 +1 @@
+62432b2679cafa381671c9555f503867c254a7b3734e10cf634b34998d5fb5a3 \ No newline at end of file
diff --git a/db/schema_migrations/20220105152547 b/db/schema_migrations/20220105152547
new file mode 100644
index 00000000000..d8c425da736
--- /dev/null
+++ b/db/schema_migrations/20220105152547
@@ -0,0 +1 @@
+0f1ea41fae57710e0e05c9b71a14800394c4c57e37a39e92be49c50120d7d2ee \ No newline at end of file
diff --git a/db/schema_migrations/20220105153149 b/db/schema_migrations/20220105153149
new file mode 100644
index 00000000000..11b71946bc8
--- /dev/null
+++ b/db/schema_migrations/20220105153149
@@ -0,0 +1 @@
+8194c695a809f2eb29e5033f089c1d20874f61731a4289026f2d550854e7097d \ No newline at end of file
diff --git a/db/schema_migrations/20220120211831 b/db/schema_migrations/20220120211831
new file mode 100644
index 00000000000..7601916df62
--- /dev/null
+++ b/db/schema_migrations/20220120211831
@@ -0,0 +1 @@
+68b45f97a2165c934f097ca976fb27ffcb533c57facee95344e3985b5cfd8347 \ No newline at end of file
diff --git a/db/schema_migrations/20220120211832 b/db/schema_migrations/20220120211832
new file mode 100644
index 00000000000..ed7679d4573
--- /dev/null
+++ b/db/schema_migrations/20220120211832
@@ -0,0 +1 @@
+dd3a4209a72b470a14a3acc5d06db1f5fec67cb4f19b20b2e4d7d94b302fe122 \ No newline at end of file
diff --git a/db/schema_migrations/20220124200927 b/db/schema_migrations/20220124200927
new file mode 100644
index 00000000000..ff29cc59538
--- /dev/null
+++ b/db/schema_migrations/20220124200927
@@ -0,0 +1 @@
+688232dde01ea4e8574dca73459094264bde405d799ecaf1a5867adb72576b98 \ No newline at end of file
diff --git a/db/schema_migrations/20220131000000 b/db/schema_migrations/20220131000000
new file mode 100644
index 00000000000..f80ceb97f1c
--- /dev/null
+++ b/db/schema_migrations/20220131000000
@@ -0,0 +1 @@
+08326048e15f368f09bc10ebf5bee3e77e8b43813f66c19d24731497ca6a8485 \ No newline at end of file
diff --git a/db/schema_migrations/20220131000001 b/db/schema_migrations/20220131000001
new file mode 100644
index 00000000000..72dce62bbce
--- /dev/null
+++ b/db/schema_migrations/20220131000001
@@ -0,0 +1 @@
+59fe701bcaa102b7e0c1496198fa4aeea6b2e59132c951d1c9d54562c5e3900e \ No newline at end of file
diff --git a/db/schema_migrations/20220203074916 b/db/schema_migrations/20220203074916
new file mode 100644
index 00000000000..fffd0dcc003
--- /dev/null
+++ b/db/schema_migrations/20220203074916
@@ -0,0 +1 @@
+5bb52cc70aada72e0e569006fd05de0c0d7629559d78bfd361009c91482f02cf \ No newline at end of file
diff --git a/db/schema_migrations/20220203134942 b/db/schema_migrations/20220203134942
new file mode 100644
index 00000000000..7dea7f1f0e7
--- /dev/null
+++ b/db/schema_migrations/20220203134942
@@ -0,0 +1 @@
+02f7a38c7bc19b1a266ac1f1d6631f1922fc135518baeb19ee90bebd7c31c6b9 \ No newline at end of file
diff --git a/db/schema_migrations/20220204093120 b/db/schema_migrations/20220204093120
new file mode 100644
index 00000000000..debd48e3c5f
--- /dev/null
+++ b/db/schema_migrations/20220204093120
@@ -0,0 +1 @@
+e147a8281f98ee397d7d9b652ce21b943e4e87c11fca906b72db839e0e2fa360 \ No newline at end of file
diff --git a/db/schema_migrations/20220204110725 b/db/schema_migrations/20220204110725
new file mode 100644
index 00000000000..804dc8c6d54
--- /dev/null
+++ b/db/schema_migrations/20220204110725
@@ -0,0 +1 @@
+c87ca83f592c6688c31182fcd4cf6fe282c00a3c92ebe245b66455f57b50fc32 \ No newline at end of file
diff --git a/db/schema_migrations/20220204193000 b/db/schema_migrations/20220204193000
new file mode 100644
index 00000000000..f0d16b9671c
--- /dev/null
+++ b/db/schema_migrations/20220204193000
@@ -0,0 +1 @@
+9d98618a1e9fd0474c45ac54420fc64a1d90ad77f36be594337e5b117fccdadb \ No newline at end of file
diff --git a/db/schema_migrations/20220204194347 b/db/schema_migrations/20220204194347
new file mode 100644
index 00000000000..d506497e036
--- /dev/null
+++ b/db/schema_migrations/20220204194347
@@ -0,0 +1 @@
+1593e935601ae1f2ab788109687bb40bad026f3f425339a39c8d13d3e4c7e306 \ No newline at end of file
diff --git a/db/schema_migrations/20220207080758 b/db/schema_migrations/20220207080758
new file mode 100644
index 00000000000..d4adf5ad455
--- /dev/null
+++ b/db/schema_migrations/20220207080758
@@ -0,0 +1 @@
+f63be8bd42cc1856c92f9073fdb39c58c45806b483d38b91db007a8661c49a97 \ No newline at end of file
diff --git a/db/schema_migrations/20220208080921 b/db/schema_migrations/20220208080921
new file mode 100644
index 00000000000..ecf35389390
--- /dev/null
+++ b/db/schema_migrations/20220208080921
@@ -0,0 +1 @@
+84346c2f608792f259ab91dbc2c8aac8397a2997f890f8e077aad809276bb7cd \ No newline at end of file
diff --git a/db/schema_migrations/20220211090920 b/db/schema_migrations/20220211090920
new file mode 100644
index 00000000000..1f08b66e508
--- /dev/null
+++ b/db/schema_migrations/20220211090920
@@ -0,0 +1 @@
+644d38e401ac8179777cb9d3c5fefca2fb55e0c409197bb2d222f7e96e5dd42f \ No newline at end of file
diff --git a/db/schema_migrations/20220211125954 b/db/schema_migrations/20220211125954
new file mode 100644
index 00000000000..5f0bb009254
--- /dev/null
+++ b/db/schema_migrations/20220211125954
@@ -0,0 +1 @@
+73feefe409b9c0f4ea373d0c3f13690df0086fbc4fc212595e959ad65fcc27b1 \ No newline at end of file
diff --git a/db/schema_migrations/20220215164709 b/db/schema_migrations/20220215164709
new file mode 100644
index 00000000000..60179eaeddd
--- /dev/null
+++ b/db/schema_migrations/20220215164709
@@ -0,0 +1 @@
+af6d142b77bc2787a520f8cbc63c287823a7a65a2edb3eb488e4f0f4efde9fa8 \ No newline at end of file
diff --git a/db/schema_migrations/20220215190020 b/db/schema_migrations/20220215190020
new file mode 100644
index 00000000000..1d5be90ca1f
--- /dev/null
+++ b/db/schema_migrations/20220215190020
@@ -0,0 +1 @@
+aa92afc5f74f051132aeb73889d7360bbd6258b27c0aedb4fea6a44ccce597b3 \ No newline at end of file
diff --git a/db/schema_migrations/20220216110023 b/db/schema_migrations/20220216110023
new file mode 100644
index 00000000000..30acd6fdaf2
--- /dev/null
+++ b/db/schema_migrations/20220216110023
@@ -0,0 +1 @@
+5931c4981c89d65c5aaca05dc8375c2c21bb595e28354d6623986d906ece165d \ No newline at end of file
diff --git a/db/schema_migrations/20220216201949 b/db/schema_migrations/20220216201949
new file mode 100644
index 00000000000..466da69ad0e
--- /dev/null
+++ b/db/schema_migrations/20220216201949
@@ -0,0 +1 @@
+481bc7b167ddf46bd11322e4458e48de10483bf34d0e393f7e76a3572c28e09f \ No newline at end of file
diff --git a/db/schema_migrations/20220217100008 b/db/schema_migrations/20220217100008
new file mode 100644
index 00000000000..6347388a5ce
--- /dev/null
+++ b/db/schema_migrations/20220217100008
@@ -0,0 +1 @@
+f52d88262879c40d9ac60a74853b7070036f244fd5f7957c59bbfceb343811d1 \ No newline at end of file
diff --git a/db/schema_migrations/20220217113058 b/db/schema_migrations/20220217113058
new file mode 100644
index 00000000000..ef801a0e269
--- /dev/null
+++ b/db/schema_migrations/20220217113058
@@ -0,0 +1 @@
+d2d236e9ee5fa6e9c1ee97431543e871b78e469b812444bd9386dfecf849947b \ No newline at end of file
diff --git a/db/schema_migrations/20220217135229 b/db/schema_migrations/20220217135229
new file mode 100644
index 00000000000..fb80b77347f
--- /dev/null
+++ b/db/schema_migrations/20220217135229
@@ -0,0 +1 @@
+3223f741799216ee6afb4daafbcebfa09bd722d461dd4d64fcbda7d8700ae235 \ No newline at end of file
diff --git a/db/schema_migrations/20220221102333 b/db/schema_migrations/20220221102333
new file mode 100644
index 00000000000..dfc13fd28a0
--- /dev/null
+++ b/db/schema_migrations/20220221102333
@@ -0,0 +1 @@
+7aa2cf28363e914ad83c61d45321f701a68111122c75abeb54430c4035d56677 \ No newline at end of file
diff --git a/db/schema_migrations/20220221214928 b/db/schema_migrations/20220221214928
new file mode 100644
index 00000000000..5c32b3fbd96
--- /dev/null
+++ b/db/schema_migrations/20220221214928
@@ -0,0 +1 @@
+8c9936d1c0f728c2b40dca536f9edb40f4af94a274ccf1dbec984f218710f695 \ No newline at end of file
diff --git a/db/schema_migrations/20220222072536 b/db/schema_migrations/20220222072536
new file mode 100644
index 00000000000..6a4b4f76dda
--- /dev/null
+++ b/db/schema_migrations/20220222072536
@@ -0,0 +1 @@
+d7ddc369818f0a2403abefea2ac1da5abd1ca41199d3948166f10dfdf9d2fa9d \ No newline at end of file
diff --git a/db/schema_migrations/20220222191845 b/db/schema_migrations/20220222191845
new file mode 100644
index 00000000000..88c15bc87c0
--- /dev/null
+++ b/db/schema_migrations/20220222191845
@@ -0,0 +1 @@
+c528d64cafc072554cd1ef1006a1c359a3135896abae2d5ca20fbbc99ff14f8c \ No newline at end of file
diff --git a/db/schema_migrations/20220222192524 b/db/schema_migrations/20220222192524
new file mode 100644
index 00000000000..c49e45f0d61
--- /dev/null
+++ b/db/schema_migrations/20220222192524
@@ -0,0 +1 @@
+b876119bb369a9831736cddf5326b72a74003ec2e17fe863654cb69497fcf236 \ No newline at end of file
diff --git a/db/schema_migrations/20220222192525 b/db/schema_migrations/20220222192525
new file mode 100644
index 00000000000..6eeec13bbb5
--- /dev/null
+++ b/db/schema_migrations/20220222192525
@@ -0,0 +1 @@
+f512ea4c4a2625c647c3d05765152fee963b56962b674f839180fd77c194ccb0 \ No newline at end of file
diff --git a/db/schema_migrations/20220223112304 b/db/schema_migrations/20220223112304
new file mode 100644
index 00000000000..bfcbf9c1225
--- /dev/null
+++ b/db/schema_migrations/20220223112304
@@ -0,0 +1 @@
+57dc23bb2a9faddefe20c1e30a8879ebb1f6f32f17e3cc381acc1d06ad3b598a \ No newline at end of file
diff --git a/db/schema_migrations/20220224000000 b/db/schema_migrations/20220224000000
new file mode 100644
index 00000000000..e6e9aefbabb
--- /dev/null
+++ b/db/schema_migrations/20220224000000
@@ -0,0 +1 @@
+74b4d572118b7f5da0a80722601a4757ce47ccbdae1af1e84b2304343477d634 \ No newline at end of file
diff --git a/db/schema_migrations/20220224204415 b/db/schema_migrations/20220224204415
new file mode 100644
index 00000000000..e0faa994b54
--- /dev/null
+++ b/db/schema_migrations/20220224204415
@@ -0,0 +1 @@
+1d7105559c8d2da1d86c5625c592edc792d7cd729b8c86c7a2b950c3dd98e975 \ No newline at end of file
diff --git a/db/schema_migrations/20220225133705 b/db/schema_migrations/20220225133705
new file mode 100644
index 00000000000..97f27e748e0
--- /dev/null
+++ b/db/schema_migrations/20220225133705
@@ -0,0 +1 @@
+aa9ab05f6991f06c465fbc4878e0cbc648dc09b1b7912dbbf3dd68887a9cdd1d \ No newline at end of file
diff --git a/db/schema_migrations/20220301002101 b/db/schema_migrations/20220301002101
new file mode 100644
index 00000000000..ab8f76b3bbb
--- /dev/null
+++ b/db/schema_migrations/20220301002101
@@ -0,0 +1 @@
+a19f7f5026fd91cf6f3fcadccd19808920e64005c207b57b46955a0352a68366 \ No newline at end of file
diff --git a/db/schema_migrations/20220301003502 b/db/schema_migrations/20220301003502
new file mode 100644
index 00000000000..5a2a9ee8334
--- /dev/null
+++ b/db/schema_migrations/20220301003502
@@ -0,0 +1 @@
+bbca8df8e60c8d027f672dfdee2b0edef35f4fdc3152ae98450df67633f3998f \ No newline at end of file
diff --git a/db/schema_migrations/20220301091503 b/db/schema_migrations/20220301091503
new file mode 100644
index 00000000000..49184ad4262
--- /dev/null
+++ b/db/schema_migrations/20220301091503
@@ -0,0 +1 @@
+4a05ddbc3d2a52a719c6fda8d834611be6f663fbce97b42655a00583d0e2042a \ No newline at end of file
diff --git a/db/schema_migrations/20220301093434 b/db/schema_migrations/20220301093434
new file mode 100644
index 00000000000..78886cc9df4
--- /dev/null
+++ b/db/schema_migrations/20220301093434
@@ -0,0 +1 @@
+ffdd031395c025ea63ea1adcd63636822e62388a8860c93235f3748918fc30ca \ No newline at end of file
diff --git a/db/schema_migrations/20220301175104 b/db/schema_migrations/20220301175104
new file mode 100644
index 00000000000..2553c957576
--- /dev/null
+++ b/db/schema_migrations/20220301175104
@@ -0,0 +1 @@
+52e172b1ca6e21a6864e82597a7aae6e1c4776507a475a88807ec140b8648966 \ No newline at end of file
diff --git a/db/schema_migrations/20220301175426 b/db/schema_migrations/20220301175426
new file mode 100644
index 00000000000..6a11d9b04b8
--- /dev/null
+++ b/db/schema_migrations/20220301175426
@@ -0,0 +1 @@
+d0a8daf9fb9892fc92b03f13de4d7e470e5c54f03b09f887cdd45bc5eb9a7e37 \ No newline at end of file
diff --git a/db/schema_migrations/20220302203410 b/db/schema_migrations/20220302203410
new file mode 100644
index 00000000000..70326d38a97
--- /dev/null
+++ b/db/schema_migrations/20220302203410
@@ -0,0 +1 @@
+873aac965684e58cfdb6098b20891cbb73614aff833f235d76bfd379498f6fda \ No newline at end of file
diff --git a/db/schema_migrations/20220303190555 b/db/schema_migrations/20220303190555
new file mode 100644
index 00000000000..08db64ca2a4
--- /dev/null
+++ b/db/schema_migrations/20220303190555
@@ -0,0 +1 @@
+f8fa8b83da24bf98c97447a2940c8ca801532c80395b6a65c11f83515f811652 \ No newline at end of file
diff --git a/db/schema_migrations/20220303191047 b/db/schema_migrations/20220303191047
new file mode 100644
index 00000000000..6e933c08f6b
--- /dev/null
+++ b/db/schema_migrations/20220303191047
@@ -0,0 +1 @@
+19566152e16a92263dd5dcfd66299e3b9d8b82acd4edb4bba21f6b9b06fc8070 \ No newline at end of file
diff --git a/db/schema_migrations/20220304052335 b/db/schema_migrations/20220304052335
new file mode 100644
index 00000000000..5716ea07f7d
--- /dev/null
+++ b/db/schema_migrations/20220304052335
@@ -0,0 +1 @@
+ba2bae8d9561eeab907ecf30664a593bdf93ab1041453f93794bf0be4464e92c \ No newline at end of file
diff --git a/db/schema_migrations/20220304061631 b/db/schema_migrations/20220304061631
new file mode 100644
index 00000000000..d7b38b30f9f
--- /dev/null
+++ b/db/schema_migrations/20220304061631
@@ -0,0 +1 @@
+7394be90999876473cfe39c38e72f21c7bb36a5038300d6fe1354f15f3d77e21 \ No newline at end of file
diff --git a/db/schema_migrations/20220304062107 b/db/schema_migrations/20220304062107
new file mode 100644
index 00000000000..9ea552c6a9e
--- /dev/null
+++ b/db/schema_migrations/20220304062107
@@ -0,0 +1 @@
+a9aace14f847412c2af03cc6de61616a0f48d32d0fd24b25f6b1f85513c87139 \ No newline at end of file
diff --git a/db/schema_migrations/20220304152729 b/db/schema_migrations/20220304152729
new file mode 100644
index 00000000000..021d4e5ad27
--- /dev/null
+++ b/db/schema_migrations/20220304152729
@@ -0,0 +1 @@
+483f8299688a6e24fa77867b7dab8a2dad0c2b7ebe43c56c81c02ab1e0dc4674 \ No newline at end of file
diff --git a/db/schema_migrations/20220304165107 b/db/schema_migrations/20220304165107
new file mode 100644
index 00000000000..6db7aee6b0f
--- /dev/null
+++ b/db/schema_migrations/20220304165107
@@ -0,0 +1 @@
+b7090327d2638bbee6646e5ca5a8f8597d97631f10f997698b8a1c1b6329c106 \ No newline at end of file
diff --git a/db/schema_migrations/20220304201847 b/db/schema_migrations/20220304201847
new file mode 100644
index 00000000000..1dafb1b821e
--- /dev/null
+++ b/db/schema_migrations/20220304201847
@@ -0,0 +1 @@
+d60a313ac68b0edfe1ae219690aacbe74c038b90bc4239f67d14f9ced36d67f6 \ No newline at end of file
diff --git a/db/schema_migrations/20220305223212 b/db/schema_migrations/20220305223212
new file mode 100644
index 00000000000..b8adc88a760
--- /dev/null
+++ b/db/schema_migrations/20220305223212
@@ -0,0 +1 @@
+8a0e80b6df1d942e5ec23641c935103cddd96c044e2a960b88bb38284cf4d070 \ No newline at end of file
diff --git a/db/schema_migrations/20220307192534 b/db/schema_migrations/20220307192534
new file mode 100644
index 00000000000..cf6687d88ea
--- /dev/null
+++ b/db/schema_migrations/20220307192534
@@ -0,0 +1 @@
+b8adcc6d7dc76fd18037de9b2b204e7db8803564df19cbd59f928901c8d97b9c \ No newline at end of file
diff --git a/db/schema_migrations/20220307192610 b/db/schema_migrations/20220307192610
new file mode 100644
index 00000000000..17575dc7174
--- /dev/null
+++ b/db/schema_migrations/20220307192610
@@ -0,0 +1 @@
+3dd34a92230e36fe1e9761ce39e4edb2a3289c972ce56347e87d8e36818e46d1 \ No newline at end of file
diff --git a/db/schema_migrations/20220307192645 b/db/schema_migrations/20220307192645
new file mode 100644
index 00000000000..913bbbf5c96
--- /dev/null
+++ b/db/schema_migrations/20220307192645
@@ -0,0 +1 @@
+c31db54f15cff7b21272cc2e9e962419ba4422582c227c5af4131fe56c1fc9f8 \ No newline at end of file
diff --git a/db/schema_migrations/20220307192725 b/db/schema_migrations/20220307192725
new file mode 100644
index 00000000000..1611c196a57
--- /dev/null
+++ b/db/schema_migrations/20220307192725
@@ -0,0 +1 @@
+d1761614c3ac0e8bd33eff58134091ec6c1834ecde3e47290a80da45ab207923 \ No newline at end of file
diff --git a/db/schema_migrations/20220307203458 b/db/schema_migrations/20220307203458
new file mode 100644
index 00000000000..3063be46503
--- /dev/null
+++ b/db/schema_migrations/20220307203458
@@ -0,0 +1 @@
+d4bf5f7c695c9833a07722d724b7a6363f0ebcb7f6d8a15bcf8148bdae5e1b32 \ No newline at end of file
diff --git a/db/schema_migrations/20220307203459 b/db/schema_migrations/20220307203459
new file mode 100644
index 00000000000..2220fd3cb61
--- /dev/null
+++ b/db/schema_migrations/20220307203459
@@ -0,0 +1 @@
+74f6687c0793a2596467338d8b4904bef712e6ff3ad3561e3ab2546eed5cd24d \ No newline at end of file
diff --git a/db/schema_migrations/20220308000205 b/db/schema_migrations/20220308000205
new file mode 100644
index 00000000000..27caf959eb9
--- /dev/null
+++ b/db/schema_migrations/20220308000205
@@ -0,0 +1 @@
+c30b1b36ec83df1b4fdf0c3c28656b158beab4f2188875898182c2dfbd073c80 \ No newline at end of file
diff --git a/db/schema_migrations/20220308115219 b/db/schema_migrations/20220308115219
new file mode 100644
index 00000000000..6e55d2fdabe
--- /dev/null
+++ b/db/schema_migrations/20220308115219
@@ -0,0 +1 @@
+e18ed9e6b2a98c77190ff2ce33f4d2b1984710b438e851d6a526ec8bb1f33c80 \ No newline at end of file
diff --git a/db/schema_migrations/20220308115502 b/db/schema_migrations/20220308115502
new file mode 100644
index 00000000000..c379b67485c
--- /dev/null
+++ b/db/schema_migrations/20220308115502
@@ -0,0 +1 @@
+0aacf46a4a5b430a718336108f52c1c0bed4283846f36c2ab1de80100dcae0b4 \ No newline at end of file
diff --git a/db/schema_migrations/20220309084838 b/db/schema_migrations/20220309084838
new file mode 100644
index 00000000000..ba0ae90a3cf
--- /dev/null
+++ b/db/schema_migrations/20220309084838
@@ -0,0 +1 @@
+d9d17f94f54840eace48f210e3886423a8dc04109f2ebca8d8edb7d53e0b5688 \ No newline at end of file
diff --git a/db/schema_migrations/20220309084954 b/db/schema_migrations/20220309084954
new file mode 100644
index 00000000000..944a1385fe7
--- /dev/null
+++ b/db/schema_migrations/20220309084954
@@ -0,0 +1 @@
+6d9c5454372317955c4e16b5a02dece575221f15af60c33df45fffbca169c08c \ No newline at end of file
diff --git a/db/schema_migrations/20220309100648 b/db/schema_migrations/20220309100648
new file mode 100644
index 00000000000..a0697655d9a
--- /dev/null
+++ b/db/schema_migrations/20220309100648
@@ -0,0 +1 @@
+3385dc0dc2a3d306e01a719b7a21197ea8468976d37abab932beade4780bb4ff \ No newline at end of file
diff --git a/db/schema_migrations/20220309154855 b/db/schema_migrations/20220309154855
new file mode 100644
index 00000000000..01500ce5863
--- /dev/null
+++ b/db/schema_migrations/20220309154855
@@ -0,0 +1 @@
+9e62675366f9c2f0fc159a9748409dbcaea240c813ab19ea26d24c966e5fd6c8 \ No newline at end of file
diff --git a/db/schema_migrations/20220310095341 b/db/schema_migrations/20220310095341
new file mode 100644
index 00000000000..d52763cce63
--- /dev/null
+++ b/db/schema_migrations/20220310095341
@@ -0,0 +1 @@
+56d906eac31954988bd0659eabbc9f1bad1a47dd616fb99e4b90b56b2bf4c6a0 \ No newline at end of file
diff --git a/db/schema_migrations/20220310101118 b/db/schema_migrations/20220310101118
new file mode 100644
index 00000000000..c87f727c8b9
--- /dev/null
+++ b/db/schema_migrations/20220310101118
@@ -0,0 +1 @@
+e4d6111f19f05b42b51e8d066e221205460514cef88ecf15ca99aa59788c4153 \ No newline at end of file
diff --git a/db/schema_migrations/20220310134207 b/db/schema_migrations/20220310134207
new file mode 100644
index 00000000000..3ba08608acc
--- /dev/null
+++ b/db/schema_migrations/20220310134207
@@ -0,0 +1 @@
+951abe39e4735f0f71ac6ad1701ffa8688dfd82a59b0383d6c55cef8f6de8e7f \ No newline at end of file
diff --git a/db/schema_migrations/20220310141349 b/db/schema_migrations/20220310141349
new file mode 100644
index 00000000000..d52b2d997a4
--- /dev/null
+++ b/db/schema_migrations/20220310141349
@@ -0,0 +1 @@
+39785d4140c7345ddbe62417576381654ce22d505ee5c92a84425f0a3f8e4935 \ No newline at end of file
diff --git a/db/schema_migrations/20220314162342 b/db/schema_migrations/20220314162342
new file mode 100644
index 00000000000..8ee5a80c256
--- /dev/null
+++ b/db/schema_migrations/20220314162342
@@ -0,0 +1 @@
+7992448797888fd69d1e5cd4f2602e5a2b49a57052c50b19522f37d711c9f2f2 \ No newline at end of file
diff --git a/db/schema_migrations/20220314194149 b/db/schema_migrations/20220314194149
new file mode 100644
index 00000000000..ce025684084
--- /dev/null
+++ b/db/schema_migrations/20220314194149
@@ -0,0 +1 @@
+2dad53754682d9d4e8338978336807255503746b82795afb812b3b65b7335ca8 \ No newline at end of file
diff --git a/db/structure.sql b/db/structure.sql
index aef55d04486..8d1679b3832 100644
--- a/db/structure.sql
+++ b/db/structure.sql
@@ -1169,6 +1169,591 @@ CREATE TABLE gitlab_partitions_static.analytics_cycle_analytics_merge_request_st
);
ALTER TABLE ONLY analytics_cycle_analytics_merge_request_stage_events ATTACH PARTITION gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_31 FOR VALUES WITH (modulus 32, remainder 31);
+CREATE TABLE issue_search_data (
+ project_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ created_at timestamp with time zone DEFAULT now() NOT NULL,
+ updated_at timestamp with time zone DEFAULT now() NOT NULL,
+ search_vector tsvector
+)
+PARTITION BY HASH (project_id);
+
+CREATE TABLE gitlab_partitions_static.issue_search_data_00 (
+ project_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ created_at timestamp with time zone DEFAULT now() NOT NULL,
+ updated_at timestamp with time zone DEFAULT now() NOT NULL,
+ search_vector tsvector
+);
+ALTER TABLE ONLY issue_search_data ATTACH PARTITION gitlab_partitions_static.issue_search_data_00 FOR VALUES WITH (modulus 64, remainder 0);
+
+CREATE TABLE gitlab_partitions_static.issue_search_data_01 (
+ project_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ created_at timestamp with time zone DEFAULT now() NOT NULL,
+ updated_at timestamp with time zone DEFAULT now() NOT NULL,
+ search_vector tsvector
+);
+ALTER TABLE ONLY issue_search_data ATTACH PARTITION gitlab_partitions_static.issue_search_data_01 FOR VALUES WITH (modulus 64, remainder 1);
+
+CREATE TABLE gitlab_partitions_static.issue_search_data_02 (
+ project_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ created_at timestamp with time zone DEFAULT now() NOT NULL,
+ updated_at timestamp with time zone DEFAULT now() NOT NULL,
+ search_vector tsvector
+);
+ALTER TABLE ONLY issue_search_data ATTACH PARTITION gitlab_partitions_static.issue_search_data_02 FOR VALUES WITH (modulus 64, remainder 2);
+
+CREATE TABLE gitlab_partitions_static.issue_search_data_03 (
+ project_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ created_at timestamp with time zone DEFAULT now() NOT NULL,
+ updated_at timestamp with time zone DEFAULT now() NOT NULL,
+ search_vector tsvector
+);
+ALTER TABLE ONLY issue_search_data ATTACH PARTITION gitlab_partitions_static.issue_search_data_03 FOR VALUES WITH (modulus 64, remainder 3);
+
+CREATE TABLE gitlab_partitions_static.issue_search_data_04 (
+ project_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ created_at timestamp with time zone DEFAULT now() NOT NULL,
+ updated_at timestamp with time zone DEFAULT now() NOT NULL,
+ search_vector tsvector
+);
+ALTER TABLE ONLY issue_search_data ATTACH PARTITION gitlab_partitions_static.issue_search_data_04 FOR VALUES WITH (modulus 64, remainder 4);
+
+CREATE TABLE gitlab_partitions_static.issue_search_data_05 (
+ project_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ created_at timestamp with time zone DEFAULT now() NOT NULL,
+ updated_at timestamp with time zone DEFAULT now() NOT NULL,
+ search_vector tsvector
+);
+ALTER TABLE ONLY issue_search_data ATTACH PARTITION gitlab_partitions_static.issue_search_data_05 FOR VALUES WITH (modulus 64, remainder 5);
+
+CREATE TABLE gitlab_partitions_static.issue_search_data_06 (
+ project_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ created_at timestamp with time zone DEFAULT now() NOT NULL,
+ updated_at timestamp with time zone DEFAULT now() NOT NULL,
+ search_vector tsvector
+);
+ALTER TABLE ONLY issue_search_data ATTACH PARTITION gitlab_partitions_static.issue_search_data_06 FOR VALUES WITH (modulus 64, remainder 6);
+
+CREATE TABLE gitlab_partitions_static.issue_search_data_07 (
+ project_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ created_at timestamp with time zone DEFAULT now() NOT NULL,
+ updated_at timestamp with time zone DEFAULT now() NOT NULL,
+ search_vector tsvector
+);
+ALTER TABLE ONLY issue_search_data ATTACH PARTITION gitlab_partitions_static.issue_search_data_07 FOR VALUES WITH (modulus 64, remainder 7);
+
+CREATE TABLE gitlab_partitions_static.issue_search_data_08 (
+ project_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ created_at timestamp with time zone DEFAULT now() NOT NULL,
+ updated_at timestamp with time zone DEFAULT now() NOT NULL,
+ search_vector tsvector
+);
+ALTER TABLE ONLY issue_search_data ATTACH PARTITION gitlab_partitions_static.issue_search_data_08 FOR VALUES WITH (modulus 64, remainder 8);
+
+CREATE TABLE gitlab_partitions_static.issue_search_data_09 (
+ project_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ created_at timestamp with time zone DEFAULT now() NOT NULL,
+ updated_at timestamp with time zone DEFAULT now() NOT NULL,
+ search_vector tsvector
+);
+ALTER TABLE ONLY issue_search_data ATTACH PARTITION gitlab_partitions_static.issue_search_data_09 FOR VALUES WITH (modulus 64, remainder 9);
+
+CREATE TABLE gitlab_partitions_static.issue_search_data_10 (
+ project_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ created_at timestamp with time zone DEFAULT now() NOT NULL,
+ updated_at timestamp with time zone DEFAULT now() NOT NULL,
+ search_vector tsvector
+);
+ALTER TABLE ONLY issue_search_data ATTACH PARTITION gitlab_partitions_static.issue_search_data_10 FOR VALUES WITH (modulus 64, remainder 10);
+
+CREATE TABLE gitlab_partitions_static.issue_search_data_11 (
+ project_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ created_at timestamp with time zone DEFAULT now() NOT NULL,
+ updated_at timestamp with time zone DEFAULT now() NOT NULL,
+ search_vector tsvector
+);
+ALTER TABLE ONLY issue_search_data ATTACH PARTITION gitlab_partitions_static.issue_search_data_11 FOR VALUES WITH (modulus 64, remainder 11);
+
+CREATE TABLE gitlab_partitions_static.issue_search_data_12 (
+ project_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ created_at timestamp with time zone DEFAULT now() NOT NULL,
+ updated_at timestamp with time zone DEFAULT now() NOT NULL,
+ search_vector tsvector
+);
+ALTER TABLE ONLY issue_search_data ATTACH PARTITION gitlab_partitions_static.issue_search_data_12 FOR VALUES WITH (modulus 64, remainder 12);
+
+CREATE TABLE gitlab_partitions_static.issue_search_data_13 (
+ project_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ created_at timestamp with time zone DEFAULT now() NOT NULL,
+ updated_at timestamp with time zone DEFAULT now() NOT NULL,
+ search_vector tsvector
+);
+ALTER TABLE ONLY issue_search_data ATTACH PARTITION gitlab_partitions_static.issue_search_data_13 FOR VALUES WITH (modulus 64, remainder 13);
+
+CREATE TABLE gitlab_partitions_static.issue_search_data_14 (
+ project_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ created_at timestamp with time zone DEFAULT now() NOT NULL,
+ updated_at timestamp with time zone DEFAULT now() NOT NULL,
+ search_vector tsvector
+);
+ALTER TABLE ONLY issue_search_data ATTACH PARTITION gitlab_partitions_static.issue_search_data_14 FOR VALUES WITH (modulus 64, remainder 14);
+
+CREATE TABLE gitlab_partitions_static.issue_search_data_15 (
+ project_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ created_at timestamp with time zone DEFAULT now() NOT NULL,
+ updated_at timestamp with time zone DEFAULT now() NOT NULL,
+ search_vector tsvector
+);
+ALTER TABLE ONLY issue_search_data ATTACH PARTITION gitlab_partitions_static.issue_search_data_15 FOR VALUES WITH (modulus 64, remainder 15);
+
+CREATE TABLE gitlab_partitions_static.issue_search_data_16 (
+ project_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ created_at timestamp with time zone DEFAULT now() NOT NULL,
+ updated_at timestamp with time zone DEFAULT now() NOT NULL,
+ search_vector tsvector
+);
+ALTER TABLE ONLY issue_search_data ATTACH PARTITION gitlab_partitions_static.issue_search_data_16 FOR VALUES WITH (modulus 64, remainder 16);
+
+CREATE TABLE gitlab_partitions_static.issue_search_data_17 (
+ project_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ created_at timestamp with time zone DEFAULT now() NOT NULL,
+ updated_at timestamp with time zone DEFAULT now() NOT NULL,
+ search_vector tsvector
+);
+ALTER TABLE ONLY issue_search_data ATTACH PARTITION gitlab_partitions_static.issue_search_data_17 FOR VALUES WITH (modulus 64, remainder 17);
+
+CREATE TABLE gitlab_partitions_static.issue_search_data_18 (
+ project_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ created_at timestamp with time zone DEFAULT now() NOT NULL,
+ updated_at timestamp with time zone DEFAULT now() NOT NULL,
+ search_vector tsvector
+);
+ALTER TABLE ONLY issue_search_data ATTACH PARTITION gitlab_partitions_static.issue_search_data_18 FOR VALUES WITH (modulus 64, remainder 18);
+
+CREATE TABLE gitlab_partitions_static.issue_search_data_19 (
+ project_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ created_at timestamp with time zone DEFAULT now() NOT NULL,
+ updated_at timestamp with time zone DEFAULT now() NOT NULL,
+ search_vector tsvector
+);
+ALTER TABLE ONLY issue_search_data ATTACH PARTITION gitlab_partitions_static.issue_search_data_19 FOR VALUES WITH (modulus 64, remainder 19);
+
+CREATE TABLE gitlab_partitions_static.issue_search_data_20 (
+ project_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ created_at timestamp with time zone DEFAULT now() NOT NULL,
+ updated_at timestamp with time zone DEFAULT now() NOT NULL,
+ search_vector tsvector
+);
+ALTER TABLE ONLY issue_search_data ATTACH PARTITION gitlab_partitions_static.issue_search_data_20 FOR VALUES WITH (modulus 64, remainder 20);
+
+CREATE TABLE gitlab_partitions_static.issue_search_data_21 (
+ project_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ created_at timestamp with time zone DEFAULT now() NOT NULL,
+ updated_at timestamp with time zone DEFAULT now() NOT NULL,
+ search_vector tsvector
+);
+ALTER TABLE ONLY issue_search_data ATTACH PARTITION gitlab_partitions_static.issue_search_data_21 FOR VALUES WITH (modulus 64, remainder 21);
+
+CREATE TABLE gitlab_partitions_static.issue_search_data_22 (
+ project_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ created_at timestamp with time zone DEFAULT now() NOT NULL,
+ updated_at timestamp with time zone DEFAULT now() NOT NULL,
+ search_vector tsvector
+);
+ALTER TABLE ONLY issue_search_data ATTACH PARTITION gitlab_partitions_static.issue_search_data_22 FOR VALUES WITH (modulus 64, remainder 22);
+
+CREATE TABLE gitlab_partitions_static.issue_search_data_23 (
+ project_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ created_at timestamp with time zone DEFAULT now() NOT NULL,
+ updated_at timestamp with time zone DEFAULT now() NOT NULL,
+ search_vector tsvector
+);
+ALTER TABLE ONLY issue_search_data ATTACH PARTITION gitlab_partitions_static.issue_search_data_23 FOR VALUES WITH (modulus 64, remainder 23);
+
+CREATE TABLE gitlab_partitions_static.issue_search_data_24 (
+ project_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ created_at timestamp with time zone DEFAULT now() NOT NULL,
+ updated_at timestamp with time zone DEFAULT now() NOT NULL,
+ search_vector tsvector
+);
+ALTER TABLE ONLY issue_search_data ATTACH PARTITION gitlab_partitions_static.issue_search_data_24 FOR VALUES WITH (modulus 64, remainder 24);
+
+CREATE TABLE gitlab_partitions_static.issue_search_data_25 (
+ project_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ created_at timestamp with time zone DEFAULT now() NOT NULL,
+ updated_at timestamp with time zone DEFAULT now() NOT NULL,
+ search_vector tsvector
+);
+ALTER TABLE ONLY issue_search_data ATTACH PARTITION gitlab_partitions_static.issue_search_data_25 FOR VALUES WITH (modulus 64, remainder 25);
+
+CREATE TABLE gitlab_partitions_static.issue_search_data_26 (
+ project_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ created_at timestamp with time zone DEFAULT now() NOT NULL,
+ updated_at timestamp with time zone DEFAULT now() NOT NULL,
+ search_vector tsvector
+);
+ALTER TABLE ONLY issue_search_data ATTACH PARTITION gitlab_partitions_static.issue_search_data_26 FOR VALUES WITH (modulus 64, remainder 26);
+
+CREATE TABLE gitlab_partitions_static.issue_search_data_27 (
+ project_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ created_at timestamp with time zone DEFAULT now() NOT NULL,
+ updated_at timestamp with time zone DEFAULT now() NOT NULL,
+ search_vector tsvector
+);
+ALTER TABLE ONLY issue_search_data ATTACH PARTITION gitlab_partitions_static.issue_search_data_27 FOR VALUES WITH (modulus 64, remainder 27);
+
+CREATE TABLE gitlab_partitions_static.issue_search_data_28 (
+ project_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ created_at timestamp with time zone DEFAULT now() NOT NULL,
+ updated_at timestamp with time zone DEFAULT now() NOT NULL,
+ search_vector tsvector
+);
+ALTER TABLE ONLY issue_search_data ATTACH PARTITION gitlab_partitions_static.issue_search_data_28 FOR VALUES WITH (modulus 64, remainder 28);
+
+CREATE TABLE gitlab_partitions_static.issue_search_data_29 (
+ project_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ created_at timestamp with time zone DEFAULT now() NOT NULL,
+ updated_at timestamp with time zone DEFAULT now() NOT NULL,
+ search_vector tsvector
+);
+ALTER TABLE ONLY issue_search_data ATTACH PARTITION gitlab_partitions_static.issue_search_data_29 FOR VALUES WITH (modulus 64, remainder 29);
+
+CREATE TABLE gitlab_partitions_static.issue_search_data_30 (
+ project_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ created_at timestamp with time zone DEFAULT now() NOT NULL,
+ updated_at timestamp with time zone DEFAULT now() NOT NULL,
+ search_vector tsvector
+);
+ALTER TABLE ONLY issue_search_data ATTACH PARTITION gitlab_partitions_static.issue_search_data_30 FOR VALUES WITH (modulus 64, remainder 30);
+
+CREATE TABLE gitlab_partitions_static.issue_search_data_31 (
+ project_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ created_at timestamp with time zone DEFAULT now() NOT NULL,
+ updated_at timestamp with time zone DEFAULT now() NOT NULL,
+ search_vector tsvector
+);
+ALTER TABLE ONLY issue_search_data ATTACH PARTITION gitlab_partitions_static.issue_search_data_31 FOR VALUES WITH (modulus 64, remainder 31);
+
+CREATE TABLE gitlab_partitions_static.issue_search_data_32 (
+ project_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ created_at timestamp with time zone DEFAULT now() NOT NULL,
+ updated_at timestamp with time zone DEFAULT now() NOT NULL,
+ search_vector tsvector
+);
+ALTER TABLE ONLY issue_search_data ATTACH PARTITION gitlab_partitions_static.issue_search_data_32 FOR VALUES WITH (modulus 64, remainder 32);
+
+CREATE TABLE gitlab_partitions_static.issue_search_data_33 (
+ project_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ created_at timestamp with time zone DEFAULT now() NOT NULL,
+ updated_at timestamp with time zone DEFAULT now() NOT NULL,
+ search_vector tsvector
+);
+ALTER TABLE ONLY issue_search_data ATTACH PARTITION gitlab_partitions_static.issue_search_data_33 FOR VALUES WITH (modulus 64, remainder 33);
+
+CREATE TABLE gitlab_partitions_static.issue_search_data_34 (
+ project_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ created_at timestamp with time zone DEFAULT now() NOT NULL,
+ updated_at timestamp with time zone DEFAULT now() NOT NULL,
+ search_vector tsvector
+);
+ALTER TABLE ONLY issue_search_data ATTACH PARTITION gitlab_partitions_static.issue_search_data_34 FOR VALUES WITH (modulus 64, remainder 34);
+
+CREATE TABLE gitlab_partitions_static.issue_search_data_35 (
+ project_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ created_at timestamp with time zone DEFAULT now() NOT NULL,
+ updated_at timestamp with time zone DEFAULT now() NOT NULL,
+ search_vector tsvector
+);
+ALTER TABLE ONLY issue_search_data ATTACH PARTITION gitlab_partitions_static.issue_search_data_35 FOR VALUES WITH (modulus 64, remainder 35);
+
+CREATE TABLE gitlab_partitions_static.issue_search_data_36 (
+ project_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ created_at timestamp with time zone DEFAULT now() NOT NULL,
+ updated_at timestamp with time zone DEFAULT now() NOT NULL,
+ search_vector tsvector
+);
+ALTER TABLE ONLY issue_search_data ATTACH PARTITION gitlab_partitions_static.issue_search_data_36 FOR VALUES WITH (modulus 64, remainder 36);
+
+CREATE TABLE gitlab_partitions_static.issue_search_data_37 (
+ project_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ created_at timestamp with time zone DEFAULT now() NOT NULL,
+ updated_at timestamp with time zone DEFAULT now() NOT NULL,
+ search_vector tsvector
+);
+ALTER TABLE ONLY issue_search_data ATTACH PARTITION gitlab_partitions_static.issue_search_data_37 FOR VALUES WITH (modulus 64, remainder 37);
+
+CREATE TABLE gitlab_partitions_static.issue_search_data_38 (
+ project_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ created_at timestamp with time zone DEFAULT now() NOT NULL,
+ updated_at timestamp with time zone DEFAULT now() NOT NULL,
+ search_vector tsvector
+);
+ALTER TABLE ONLY issue_search_data ATTACH PARTITION gitlab_partitions_static.issue_search_data_38 FOR VALUES WITH (modulus 64, remainder 38);
+
+CREATE TABLE gitlab_partitions_static.issue_search_data_39 (
+ project_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ created_at timestamp with time zone DEFAULT now() NOT NULL,
+ updated_at timestamp with time zone DEFAULT now() NOT NULL,
+ search_vector tsvector
+);
+ALTER TABLE ONLY issue_search_data ATTACH PARTITION gitlab_partitions_static.issue_search_data_39 FOR VALUES WITH (modulus 64, remainder 39);
+
+CREATE TABLE gitlab_partitions_static.issue_search_data_40 (
+ project_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ created_at timestamp with time zone DEFAULT now() NOT NULL,
+ updated_at timestamp with time zone DEFAULT now() NOT NULL,
+ search_vector tsvector
+);
+ALTER TABLE ONLY issue_search_data ATTACH PARTITION gitlab_partitions_static.issue_search_data_40 FOR VALUES WITH (modulus 64, remainder 40);
+
+CREATE TABLE gitlab_partitions_static.issue_search_data_41 (
+ project_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ created_at timestamp with time zone DEFAULT now() NOT NULL,
+ updated_at timestamp with time zone DEFAULT now() NOT NULL,
+ search_vector tsvector
+);
+ALTER TABLE ONLY issue_search_data ATTACH PARTITION gitlab_partitions_static.issue_search_data_41 FOR VALUES WITH (modulus 64, remainder 41);
+
+CREATE TABLE gitlab_partitions_static.issue_search_data_42 (
+ project_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ created_at timestamp with time zone DEFAULT now() NOT NULL,
+ updated_at timestamp with time zone DEFAULT now() NOT NULL,
+ search_vector tsvector
+);
+ALTER TABLE ONLY issue_search_data ATTACH PARTITION gitlab_partitions_static.issue_search_data_42 FOR VALUES WITH (modulus 64, remainder 42);
+
+CREATE TABLE gitlab_partitions_static.issue_search_data_43 (
+ project_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ created_at timestamp with time zone DEFAULT now() NOT NULL,
+ updated_at timestamp with time zone DEFAULT now() NOT NULL,
+ search_vector tsvector
+);
+ALTER TABLE ONLY issue_search_data ATTACH PARTITION gitlab_partitions_static.issue_search_data_43 FOR VALUES WITH (modulus 64, remainder 43);
+
+CREATE TABLE gitlab_partitions_static.issue_search_data_44 (
+ project_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ created_at timestamp with time zone DEFAULT now() NOT NULL,
+ updated_at timestamp with time zone DEFAULT now() NOT NULL,
+ search_vector tsvector
+);
+ALTER TABLE ONLY issue_search_data ATTACH PARTITION gitlab_partitions_static.issue_search_data_44 FOR VALUES WITH (modulus 64, remainder 44);
+
+CREATE TABLE gitlab_partitions_static.issue_search_data_45 (
+ project_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ created_at timestamp with time zone DEFAULT now() NOT NULL,
+ updated_at timestamp with time zone DEFAULT now() NOT NULL,
+ search_vector tsvector
+);
+ALTER TABLE ONLY issue_search_data ATTACH PARTITION gitlab_partitions_static.issue_search_data_45 FOR VALUES WITH (modulus 64, remainder 45);
+
+CREATE TABLE gitlab_partitions_static.issue_search_data_46 (
+ project_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ created_at timestamp with time zone DEFAULT now() NOT NULL,
+ updated_at timestamp with time zone DEFAULT now() NOT NULL,
+ search_vector tsvector
+);
+ALTER TABLE ONLY issue_search_data ATTACH PARTITION gitlab_partitions_static.issue_search_data_46 FOR VALUES WITH (modulus 64, remainder 46);
+
+CREATE TABLE gitlab_partitions_static.issue_search_data_47 (
+ project_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ created_at timestamp with time zone DEFAULT now() NOT NULL,
+ updated_at timestamp with time zone DEFAULT now() NOT NULL,
+ search_vector tsvector
+);
+ALTER TABLE ONLY issue_search_data ATTACH PARTITION gitlab_partitions_static.issue_search_data_47 FOR VALUES WITH (modulus 64, remainder 47);
+
+CREATE TABLE gitlab_partitions_static.issue_search_data_48 (
+ project_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ created_at timestamp with time zone DEFAULT now() NOT NULL,
+ updated_at timestamp with time zone DEFAULT now() NOT NULL,
+ search_vector tsvector
+);
+ALTER TABLE ONLY issue_search_data ATTACH PARTITION gitlab_partitions_static.issue_search_data_48 FOR VALUES WITH (modulus 64, remainder 48);
+
+CREATE TABLE gitlab_partitions_static.issue_search_data_49 (
+ project_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ created_at timestamp with time zone DEFAULT now() NOT NULL,
+ updated_at timestamp with time zone DEFAULT now() NOT NULL,
+ search_vector tsvector
+);
+ALTER TABLE ONLY issue_search_data ATTACH PARTITION gitlab_partitions_static.issue_search_data_49 FOR VALUES WITH (modulus 64, remainder 49);
+
+CREATE TABLE gitlab_partitions_static.issue_search_data_50 (
+ project_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ created_at timestamp with time zone DEFAULT now() NOT NULL,
+ updated_at timestamp with time zone DEFAULT now() NOT NULL,
+ search_vector tsvector
+);
+ALTER TABLE ONLY issue_search_data ATTACH PARTITION gitlab_partitions_static.issue_search_data_50 FOR VALUES WITH (modulus 64, remainder 50);
+
+CREATE TABLE gitlab_partitions_static.issue_search_data_51 (
+ project_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ created_at timestamp with time zone DEFAULT now() NOT NULL,
+ updated_at timestamp with time zone DEFAULT now() NOT NULL,
+ search_vector tsvector
+);
+ALTER TABLE ONLY issue_search_data ATTACH PARTITION gitlab_partitions_static.issue_search_data_51 FOR VALUES WITH (modulus 64, remainder 51);
+
+CREATE TABLE gitlab_partitions_static.issue_search_data_52 (
+ project_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ created_at timestamp with time zone DEFAULT now() NOT NULL,
+ updated_at timestamp with time zone DEFAULT now() NOT NULL,
+ search_vector tsvector
+);
+ALTER TABLE ONLY issue_search_data ATTACH PARTITION gitlab_partitions_static.issue_search_data_52 FOR VALUES WITH (modulus 64, remainder 52);
+
+CREATE TABLE gitlab_partitions_static.issue_search_data_53 (
+ project_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ created_at timestamp with time zone DEFAULT now() NOT NULL,
+ updated_at timestamp with time zone DEFAULT now() NOT NULL,
+ search_vector tsvector
+);
+ALTER TABLE ONLY issue_search_data ATTACH PARTITION gitlab_partitions_static.issue_search_data_53 FOR VALUES WITH (modulus 64, remainder 53);
+
+CREATE TABLE gitlab_partitions_static.issue_search_data_54 (
+ project_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ created_at timestamp with time zone DEFAULT now() NOT NULL,
+ updated_at timestamp with time zone DEFAULT now() NOT NULL,
+ search_vector tsvector
+);
+ALTER TABLE ONLY issue_search_data ATTACH PARTITION gitlab_partitions_static.issue_search_data_54 FOR VALUES WITH (modulus 64, remainder 54);
+
+CREATE TABLE gitlab_partitions_static.issue_search_data_55 (
+ project_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ created_at timestamp with time zone DEFAULT now() NOT NULL,
+ updated_at timestamp with time zone DEFAULT now() NOT NULL,
+ search_vector tsvector
+);
+ALTER TABLE ONLY issue_search_data ATTACH PARTITION gitlab_partitions_static.issue_search_data_55 FOR VALUES WITH (modulus 64, remainder 55);
+
+CREATE TABLE gitlab_partitions_static.issue_search_data_56 (
+ project_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ created_at timestamp with time zone DEFAULT now() NOT NULL,
+ updated_at timestamp with time zone DEFAULT now() NOT NULL,
+ search_vector tsvector
+);
+ALTER TABLE ONLY issue_search_data ATTACH PARTITION gitlab_partitions_static.issue_search_data_56 FOR VALUES WITH (modulus 64, remainder 56);
+
+CREATE TABLE gitlab_partitions_static.issue_search_data_57 (
+ project_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ created_at timestamp with time zone DEFAULT now() NOT NULL,
+ updated_at timestamp with time zone DEFAULT now() NOT NULL,
+ search_vector tsvector
+);
+ALTER TABLE ONLY issue_search_data ATTACH PARTITION gitlab_partitions_static.issue_search_data_57 FOR VALUES WITH (modulus 64, remainder 57);
+
+CREATE TABLE gitlab_partitions_static.issue_search_data_58 (
+ project_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ created_at timestamp with time zone DEFAULT now() NOT NULL,
+ updated_at timestamp with time zone DEFAULT now() NOT NULL,
+ search_vector tsvector
+);
+ALTER TABLE ONLY issue_search_data ATTACH PARTITION gitlab_partitions_static.issue_search_data_58 FOR VALUES WITH (modulus 64, remainder 58);
+
+CREATE TABLE gitlab_partitions_static.issue_search_data_59 (
+ project_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ created_at timestamp with time zone DEFAULT now() NOT NULL,
+ updated_at timestamp with time zone DEFAULT now() NOT NULL,
+ search_vector tsvector
+);
+ALTER TABLE ONLY issue_search_data ATTACH PARTITION gitlab_partitions_static.issue_search_data_59 FOR VALUES WITH (modulus 64, remainder 59);
+
+CREATE TABLE gitlab_partitions_static.issue_search_data_60 (
+ project_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ created_at timestamp with time zone DEFAULT now() NOT NULL,
+ updated_at timestamp with time zone DEFAULT now() NOT NULL,
+ search_vector tsvector
+);
+ALTER TABLE ONLY issue_search_data ATTACH PARTITION gitlab_partitions_static.issue_search_data_60 FOR VALUES WITH (modulus 64, remainder 60);
+
+CREATE TABLE gitlab_partitions_static.issue_search_data_61 (
+ project_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ created_at timestamp with time zone DEFAULT now() NOT NULL,
+ updated_at timestamp with time zone DEFAULT now() NOT NULL,
+ search_vector tsvector
+);
+ALTER TABLE ONLY issue_search_data ATTACH PARTITION gitlab_partitions_static.issue_search_data_61 FOR VALUES WITH (modulus 64, remainder 61);
+
+CREATE TABLE gitlab_partitions_static.issue_search_data_62 (
+ project_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ created_at timestamp with time zone DEFAULT now() NOT NULL,
+ updated_at timestamp with time zone DEFAULT now() NOT NULL,
+ search_vector tsvector
+);
+ALTER TABLE ONLY issue_search_data ATTACH PARTITION gitlab_partitions_static.issue_search_data_62 FOR VALUES WITH (modulus 64, remainder 62);
+
+CREATE TABLE gitlab_partitions_static.issue_search_data_63 (
+ project_id bigint NOT NULL,
+ issue_id bigint NOT NULL,
+ created_at timestamp with time zone DEFAULT now() NOT NULL,
+ updated_at timestamp with time zone DEFAULT now() NOT NULL,
+ search_vector tsvector
+);
+ALTER TABLE ONLY issue_search_data ATTACH PARTITION gitlab_partitions_static.issue_search_data_63 FOR VALUES WITH (modulus 64, remainder 63);
+
CREATE TABLE product_analytics_events_experimental (
id bigint NOT NULL,
project_id integer NOT NULL,
@@ -10036,6 +10621,30 @@ CREATE SEQUENCE allowed_email_domains_id_seq
ALTER SEQUENCE allowed_email_domains_id_seq OWNED BY allowed_email_domains.id;
+CREATE TABLE analytics_cycle_analytics_aggregations (
+ group_id bigint NOT NULL,
+ incremental_runtimes_in_seconds integer[] DEFAULT '{}'::integer[] NOT NULL,
+ incremental_processed_records integer[] DEFAULT '{}'::integer[] NOT NULL,
+ last_full_run_runtimes_in_seconds integer[] DEFAULT '{}'::integer[] NOT NULL,
+ last_full_run_processed_records integer[] DEFAULT '{}'::integer[] NOT NULL,
+ last_incremental_issues_id integer,
+ last_incremental_merge_requests_id integer,
+ last_full_run_issues_id integer,
+ last_full_run_merge_requests_id integer,
+ last_incremental_run_at timestamp with time zone,
+ last_incremental_issues_updated_at timestamp with time zone,
+ last_incremental_merge_requests_updated_at timestamp with time zone,
+ last_full_run_at timestamp with time zone,
+ last_full_run_issues_updated_at timestamp with time zone,
+ last_full_run_mrs_updated_at timestamp with time zone,
+ last_consistency_check_updated_at timestamp with time zone,
+ enabled boolean DEFAULT true NOT NULL,
+ CONSTRAINT chk_rails_1ef688e577 CHECK ((cardinality(incremental_runtimes_in_seconds) <= 10)),
+ CONSTRAINT chk_rails_7810292ec9 CHECK ((cardinality(last_full_run_processed_records) <= 10)),
+ CONSTRAINT chk_rails_8b9e89687c CHECK ((cardinality(last_full_run_runtimes_in_seconds) <= 10)),
+ CONSTRAINT chk_rails_e16bf3913a CHECK ((cardinality(incremental_processed_records) <= 10))
+);
+
CREATE TABLE analytics_cycle_analytics_group_stages (
id bigint NOT NULL,
created_at timestamp with time zone NOT NULL,
@@ -10167,7 +10776,7 @@ CREATE TABLE analytics_devops_adoption_snapshots (
runner_configured boolean NOT NULL,
pipeline_succeeded boolean NOT NULL,
deploy_succeeded boolean NOT NULL,
- security_scan_succeeded boolean NOT NULL,
+ security_scan_succeeded boolean,
end_time timestamp with time zone NOT NULL,
total_projects_count integer,
code_owners_used_count integer,
@@ -10528,7 +11137,7 @@ CREATE TABLE application_settings (
automatic_purchased_storage_allocation boolean DEFAULT false NOT NULL,
encrypted_ci_jwt_signing_key text,
encrypted_ci_jwt_signing_key_iv text,
- container_registry_expiration_policies_worker_capacity integer DEFAULT 0 NOT NULL,
+ container_registry_expiration_policies_worker_capacity integer DEFAULT 4 NOT NULL,
elasticsearch_analyzers_smartcn_enabled boolean DEFAULT false NOT NULL,
elasticsearch_analyzers_smartcn_search boolean DEFAULT false NOT NULL,
elasticsearch_analyzers_kuromoji_enabled boolean DEFAULT false NOT NULL,
@@ -10634,7 +11243,6 @@ CREATE TABLE application_settings (
container_registry_import_max_step_duration integer DEFAULT 300 NOT NULL,
container_registry_import_target_plan text DEFAULT 'free'::text NOT NULL,
container_registry_import_created_before timestamp with time zone DEFAULT '2022-01-23 00:00:00+00'::timestamp with time zone NOT NULL,
- max_package_files_for_package_destruction smallint DEFAULT 100 NOT NULL,
runner_token_expiration_interval integer,
group_runner_token_expiration_interval integer,
project_runner_token_expiration_interval integer,
@@ -10642,10 +11250,12 @@ CREATE TABLE application_settings (
ed25519_sk_key_restriction integer DEFAULT 0 NOT NULL,
users_get_by_id_limit integer DEFAULT 300 NOT NULL,
users_get_by_id_limit_allowlist text[] DEFAULT '{}'::text[] NOT NULL,
+ container_registry_expiration_policies_caching boolean DEFAULT true NOT NULL,
+ search_rate_limit integer DEFAULT 30 NOT NULL,
+ search_rate_limit_unauthenticated integer DEFAULT 10 NOT NULL,
CONSTRAINT app_settings_container_reg_cleanup_tags_max_list_size_positive CHECK ((container_registry_cleanup_tags_service_max_list_size >= 0)),
CONSTRAINT app_settings_dep_proxy_ttl_policies_worker_capacity_positive CHECK ((dependency_proxy_ttl_group_policy_worker_capacity >= 0)),
CONSTRAINT app_settings_ext_pipeline_validation_service_url_text_limit CHECK ((char_length(external_pipeline_validation_service_url) <= 255)),
- CONSTRAINT app_settings_max_package_files_for_package_destruction_positive CHECK ((max_package_files_for_package_destruction > 0)),
CONSTRAINT app_settings_p_cleanup_package_file_worker_capacity_positive CHECK ((packages_cleanup_package_file_worker_capacity >= 0)),
CONSTRAINT app_settings_registry_exp_policies_worker_capacity_positive CHECK ((container_registry_expiration_policies_worker_capacity >= 0)),
CONSTRAINT app_settings_yaml_max_depth_positive CHECK ((max_yaml_depth > 0)),
@@ -11364,7 +11974,8 @@ CREATE TABLE broadcast_messages (
cached_markdown_version integer,
target_path character varying(255),
broadcast_type smallint DEFAULT 1 NOT NULL,
- dismissable boolean
+ dismissable boolean,
+ target_access_levels integer[] DEFAULT '{}'::integer[] NOT NULL
);
CREATE SEQUENCE broadcast_messages_id_seq
@@ -12376,7 +12987,7 @@ CREATE TABLE ci_runners (
executor_type smallint,
maintainer_note text,
token_expires_at timestamp with time zone,
- CONSTRAINT check_56f5ea8804 CHECK ((char_length(maintainer_note) <= 255))
+ CONSTRAINT check_ce275cee06 CHECK ((char_length(maintainer_note) <= 1024))
);
CREATE SEQUENCE ci_runners_id_seq
@@ -13655,7 +14266,9 @@ CREATE TABLE deployment_approvals (
user_id bigint NOT NULL,
created_at timestamp with time zone NOT NULL,
updated_at timestamp with time zone NOT NULL,
- status smallint NOT NULL
+ status smallint NOT NULL,
+ comment text,
+ CONSTRAINT check_e2eb6a17d8 CHECK ((char_length(comment) <= 255))
);
CREATE SEQUENCE deployment_approvals_id_seq
@@ -13848,6 +14461,7 @@ CREATE TABLE dora_daily_metrics (
date date NOT NULL,
deployment_frequency integer,
lead_time_for_changes_in_seconds integer,
+ time_to_restore_service_in_seconds integer,
CONSTRAINT dora_daily_metrics_deployment_frequency_positive CHECK ((deployment_frequency >= 0)),
CONSTRAINT dora_daily_metrics_lead_time_for_changes_in_seconds_positive CHECK ((lead_time_for_changes_in_seconds >= 0))
);
@@ -14113,6 +14727,8 @@ CREATE TABLE epics (
due_date_sourcing_epic_id integer,
confidential boolean DEFAULT false NOT NULL,
external_key character varying(255),
+ color text DEFAULT '#1068bf'::text,
+ CONSTRAINT check_ca608c40b3 CHECK ((char_length(color) <= 7)),
CONSTRAINT check_fcfb4a93ff CHECK ((lock_version IS NOT NULL))
);
@@ -15484,6 +16100,8 @@ CREATE TABLE integrations (
type_new text,
vulnerability_events boolean DEFAULT false NOT NULL,
archive_trace_events boolean DEFAULT false NOT NULL,
+ encrypted_properties bytea,
+ encrypted_properties_iv bytea,
CONSTRAINT check_a948a0aa7e CHECK ((char_length(type_new) <= 255))
);
@@ -16212,7 +16830,8 @@ CREATE TABLE merge_request_assignees (
user_id integer NOT NULL,
merge_request_id integer NOT NULL,
created_at timestamp with time zone,
- state smallint DEFAULT 0 NOT NULL
+ state smallint DEFAULT 0 NOT NULL,
+ updated_state_by_user_id bigint
);
CREATE SEQUENCE merge_request_assignees_id_seq
@@ -16438,7 +17057,8 @@ CREATE TABLE merge_request_reviewers (
user_id bigint NOT NULL,
merge_request_id bigint NOT NULL,
created_at timestamp with time zone NOT NULL,
- state smallint DEFAULT 0 NOT NULL
+ state smallint DEFAULT 0 NOT NULL,
+ updated_state_by_user_id bigint
);
CREATE SEQUENCE merge_request_reviewers_id_seq
@@ -17708,7 +18328,7 @@ ALTER SEQUENCE packages_packages_id_seq OWNED BY packages_packages.id;
CREATE TABLE packages_pypi_metadata (
package_id bigint NOT NULL,
- required_python text,
+ required_python text DEFAULT ''::text,
CONSTRAINT check_0d9aed55b2 CHECK ((required_python IS NOT NULL)),
CONSTRAINT check_379019d5da CHECK ((char_length(required_python) <= 255))
);
@@ -17880,28 +18500,6 @@ CREATE SEQUENCE pages_domains_id_seq
ALTER SEQUENCE pages_domains_id_seq OWNED BY pages_domains.id;
-CREATE TABLE partitioned_foreign_keys (
- id bigint NOT NULL,
- cascade_delete boolean DEFAULT true NOT NULL,
- from_table text NOT NULL,
- from_column text NOT NULL,
- to_table text NOT NULL,
- to_column text NOT NULL,
- CONSTRAINT check_2c2e02a62b CHECK ((char_length(from_column) <= 63)),
- CONSTRAINT check_40738efb57 CHECK ((char_length(to_table) <= 63)),
- CONSTRAINT check_741676d405 CHECK ((char_length(from_table) <= 63)),
- CONSTRAINT check_7e98be694f CHECK ((char_length(to_column) <= 63))
-);
-
-CREATE SEQUENCE partitioned_foreign_keys_id_seq
- START WITH 1
- INCREMENT BY 1
- NO MINVALUE
- NO MAXVALUE
- CACHE 1;
-
-ALTER SEQUENCE partitioned_foreign_keys_id_seq OWNED BY partitioned_foreign_keys.id;
-
CREATE TABLE path_locks (
id integer NOT NULL,
path character varying NOT NULL,
@@ -18014,7 +18612,8 @@ CREATE TABLE plan_limits (
external_audit_event_destinations integer DEFAULT 5 NOT NULL,
dotenv_variables integer DEFAULT 20 NOT NULL,
dotenv_size integer DEFAULT 5120 NOT NULL,
- pipeline_triggers integer DEFAULT 25000 NOT NULL
+ pipeline_triggers integer DEFAULT 25000 NOT NULL,
+ project_ci_secure_files integer DEFAULT 100 NOT NULL
);
CREATE SEQUENCE plan_limits_id_seq
@@ -18376,6 +18975,25 @@ CREATE SEQUENCE project_auto_devops_id_seq
ALTER SEQUENCE project_auto_devops_id_seq OWNED BY project_auto_devops.id;
+CREATE TABLE project_build_artifacts_size_refreshes (
+ id bigint NOT NULL,
+ project_id bigint NOT NULL,
+ last_job_artifact_id bigint,
+ state smallint DEFAULT 1 NOT NULL,
+ refresh_started_at timestamp with time zone,
+ created_at timestamp with time zone NOT NULL,
+ updated_at timestamp with time zone NOT NULL
+);
+
+CREATE SEQUENCE project_build_artifacts_size_refreshes_id_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+ALTER SEQUENCE project_build_artifacts_size_refreshes_id_seq OWNED BY project_build_artifacts_size_refreshes.id;
+
CREATE TABLE project_ci_cd_settings (
id integer NOT NULL,
project_id integer NOT NULL,
@@ -18742,7 +19360,6 @@ CREATE TABLE project_settings (
merge_commit_template text,
has_shimo boolean DEFAULT false NOT NULL,
squash_commit_template text,
- show_diff_preview_in_email boolean DEFAULT true NOT NULL,
legacy_open_source_license_available boolean DEFAULT true NOT NULL,
CONSTRAINT check_3a03e7557a CHECK ((char_length(previous_default_branch) <= 4096)),
CONSTRAINT check_b09644994b CHECK ((char_length(squash_commit_template) <= 500)),
@@ -18893,7 +19510,8 @@ CREATE TABLE projects (
marked_for_deletion_by_user_id integer,
autoclose_referenced_issues boolean,
suggestion_commit_message character varying(255),
- project_namespace_id bigint
+ project_namespace_id bigint,
+ hidden boolean DEFAULT false NOT NULL
);
CREATE SEQUENCE projects_id_seq
@@ -19217,6 +19835,24 @@ CREATE SEQUENCE redirect_routes_id_seq
ALTER SEQUENCE redirect_routes_id_seq OWNED BY redirect_routes.id;
+CREATE TABLE related_epic_links (
+ id bigint NOT NULL,
+ source_id bigint NOT NULL,
+ target_id bigint NOT NULL,
+ created_at timestamp with time zone NOT NULL,
+ updated_at timestamp with time zone NOT NULL,
+ link_type smallint DEFAULT 0 NOT NULL
+);
+
+CREATE SEQUENCE related_epic_links_id_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+ALTER SEQUENCE related_epic_links_id_seq OWNED BY related_epic_links.id;
+
CREATE TABLE release_links (
id bigint NOT NULL,
release_id integer NOT NULL,
@@ -19540,6 +20176,26 @@ CREATE SEQUENCE saml_providers_id_seq
ALTER SEQUENCE saml_providers_id_seq OWNED BY saml_providers.id;
+CREATE TABLE saved_replies (
+ id bigint NOT NULL,
+ user_id bigint NOT NULL,
+ created_at timestamp with time zone NOT NULL,
+ updated_at timestamp with time zone NOT NULL,
+ name text NOT NULL,
+ content text NOT NULL,
+ CONSTRAINT check_0cb57dc22a CHECK ((char_length(content) <= 10000)),
+ CONSTRAINT check_2eb3366d7f CHECK ((char_length(name) <= 255))
+);
+
+CREATE SEQUENCE saved_replies_id_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+ALTER SEQUENCE saved_replies_id_seq OWNED BY saved_replies.id;
+
CREATE TABLE schema_migrations (
version character varying NOT NULL,
finished_at timestamp with time zone DEFAULT now()
@@ -19591,6 +20247,7 @@ CREATE TABLE security_findings (
deduplicated boolean DEFAULT false NOT NULL,
uuid uuid,
overridden_uuid uuid,
+ CONSTRAINT check_6c2851a8c9 CHECK ((uuid IS NOT NULL)),
CONSTRAINT check_b9508c6df8 CHECK ((char_length(project_fingerprint) <= 40))
);
@@ -19605,11 +20262,13 @@ ALTER SEQUENCE security_findings_id_seq OWNED BY security_findings.id;
CREATE TABLE security_orchestration_policy_configurations (
id bigint NOT NULL,
- project_id bigint NOT NULL,
+ project_id bigint,
security_policy_management_project_id bigint NOT NULL,
created_at timestamp with time zone NOT NULL,
updated_at timestamp with time zone NOT NULL,
- configured_at timestamp with time zone
+ configured_at timestamp with time zone,
+ namespace_id bigint,
+ CONSTRAINT cop_configs_project_or_namespace_existence CHECK (((project_id IS NULL) <> (namespace_id IS NULL)))
);
COMMENT ON TABLE security_orchestration_policy_configurations IS '{"owner":"group::container security","description":"Configuration used to store relationship between project and security policy repository"}';
@@ -19997,7 +20656,7 @@ CREATE TABLE sprints (
group_id bigint,
iid integer NOT NULL,
cached_markdown_version integer,
- title text NOT NULL,
+ title text,
title_html text,
description text,
description_html text,
@@ -20022,7 +20681,8 @@ CREATE TABLE status_check_responses (
merge_request_id bigint NOT NULL,
external_approval_rule_id bigint,
sha bytea NOT NULL,
- external_status_check_id bigint NOT NULL
+ external_status_check_id bigint NOT NULL,
+ status smallint DEFAULT 0 NOT NULL
);
CREATE SEQUENCE status_check_responses_id_seq
@@ -20490,7 +21150,7 @@ CREATE TABLE user_credit_card_validations (
network text,
CONSTRAINT check_1765e2b30f CHECK ((char_length(network) <= 32)),
CONSTRAINT check_3eea080c91 CHECK (((last_digits >= 0) AND (last_digits <= 9999))),
- CONSTRAINT check_eafe45d88b CHECK ((char_length(holder_name) <= 26))
+ CONSTRAINT check_cc0c8dc0fe CHECK ((char_length(holder_name) <= 50))
);
CREATE TABLE user_custom_attributes (
@@ -22206,8 +22866,6 @@ ALTER TABLE ONLY pages_domain_acme_orders ALTER COLUMN id SET DEFAULT nextval('p
ALTER TABLE ONLY pages_domains ALTER COLUMN id SET DEFAULT nextval('pages_domains_id_seq'::regclass);
-ALTER TABLE ONLY partitioned_foreign_keys ALTER COLUMN id SET DEFAULT nextval('partitioned_foreign_keys_id_seq'::regclass);
-
ALTER TABLE ONLY path_locks ALTER COLUMN id SET DEFAULT nextval('path_locks_id_seq'::regclass);
ALTER TABLE ONLY personal_access_tokens ALTER COLUMN id SET DEFAULT nextval('personal_access_tokens_id_seq'::regclass);
@@ -22232,6 +22890,8 @@ ALTER TABLE ONLY project_aliases ALTER COLUMN id SET DEFAULT nextval('project_al
ALTER TABLE ONLY project_auto_devops ALTER COLUMN id SET DEFAULT nextval('project_auto_devops_id_seq'::regclass);
+ALTER TABLE ONLY project_build_artifacts_size_refreshes ALTER COLUMN id SET DEFAULT nextval('project_build_artifacts_size_refreshes_id_seq'::regclass);
+
ALTER TABLE ONLY project_ci_cd_settings ALTER COLUMN id SET DEFAULT nextval('project_ci_cd_settings_id_seq'::regclass);
ALTER TABLE ONLY project_ci_feature_usages ALTER COLUMN id SET DEFAULT nextval('project_ci_feature_usages_id_seq'::regclass);
@@ -22302,6 +22962,8 @@ ALTER TABLE ONLY raw_usage_data ALTER COLUMN id SET DEFAULT nextval('raw_usage_d
ALTER TABLE ONLY redirect_routes ALTER COLUMN id SET DEFAULT nextval('redirect_routes_id_seq'::regclass);
+ALTER TABLE ONLY related_epic_links ALTER COLUMN id SET DEFAULT nextval('related_epic_links_id_seq'::regclass);
+
ALTER TABLE ONLY release_links ALTER COLUMN id SET DEFAULT nextval('release_links_id_seq'::regclass);
ALTER TABLE ONLY releases ALTER COLUMN id SET DEFAULT nextval('releases_id_seq'::regclass);
@@ -22332,6 +22994,8 @@ ALTER TABLE ONLY saml_group_links ALTER COLUMN id SET DEFAULT nextval('saml_grou
ALTER TABLE ONLY saml_providers ALTER COLUMN id SET DEFAULT nextval('saml_providers_id_seq'::regclass);
+ALTER TABLE ONLY saved_replies ALTER COLUMN id SET DEFAULT nextval('saved_replies_id_seq'::regclass);
+
ALTER TABLE ONLY scim_identities ALTER COLUMN id SET DEFAULT nextval('scim_identities_id_seq'::regclass);
ALTER TABLE ONLY scim_oauth_access_tokens ALTER COLUMN id SET DEFAULT nextval('scim_oauth_access_tokens_id_seq'::regclass);
@@ -22702,6 +23366,201 @@ ALTER TABLE ONLY gitlab_partitions_static.analytics_cycle_analytics_merge_reques
ALTER TABLE ONLY gitlab_partitions_static.analytics_cycle_analytics_merge_request_stage_events_31
ADD CONSTRAINT analytics_cycle_analytics_merge_request_stage_events_31_pkey PRIMARY KEY (stage_event_hash_id, merge_request_id);
+ALTER TABLE ONLY issue_search_data
+ ADD CONSTRAINT issue_search_data_pkey PRIMARY KEY (project_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.issue_search_data_00
+ ADD CONSTRAINT issue_search_data_00_pkey PRIMARY KEY (project_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.issue_search_data_01
+ ADD CONSTRAINT issue_search_data_01_pkey PRIMARY KEY (project_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.issue_search_data_02
+ ADD CONSTRAINT issue_search_data_02_pkey PRIMARY KEY (project_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.issue_search_data_03
+ ADD CONSTRAINT issue_search_data_03_pkey PRIMARY KEY (project_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.issue_search_data_04
+ ADD CONSTRAINT issue_search_data_04_pkey PRIMARY KEY (project_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.issue_search_data_05
+ ADD CONSTRAINT issue_search_data_05_pkey PRIMARY KEY (project_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.issue_search_data_06
+ ADD CONSTRAINT issue_search_data_06_pkey PRIMARY KEY (project_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.issue_search_data_07
+ ADD CONSTRAINT issue_search_data_07_pkey PRIMARY KEY (project_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.issue_search_data_08
+ ADD CONSTRAINT issue_search_data_08_pkey PRIMARY KEY (project_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.issue_search_data_09
+ ADD CONSTRAINT issue_search_data_09_pkey PRIMARY KEY (project_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.issue_search_data_10
+ ADD CONSTRAINT issue_search_data_10_pkey PRIMARY KEY (project_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.issue_search_data_11
+ ADD CONSTRAINT issue_search_data_11_pkey PRIMARY KEY (project_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.issue_search_data_12
+ ADD CONSTRAINT issue_search_data_12_pkey PRIMARY KEY (project_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.issue_search_data_13
+ ADD CONSTRAINT issue_search_data_13_pkey PRIMARY KEY (project_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.issue_search_data_14
+ ADD CONSTRAINT issue_search_data_14_pkey PRIMARY KEY (project_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.issue_search_data_15
+ ADD CONSTRAINT issue_search_data_15_pkey PRIMARY KEY (project_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.issue_search_data_16
+ ADD CONSTRAINT issue_search_data_16_pkey PRIMARY KEY (project_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.issue_search_data_17
+ ADD CONSTRAINT issue_search_data_17_pkey PRIMARY KEY (project_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.issue_search_data_18
+ ADD CONSTRAINT issue_search_data_18_pkey PRIMARY KEY (project_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.issue_search_data_19
+ ADD CONSTRAINT issue_search_data_19_pkey PRIMARY KEY (project_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.issue_search_data_20
+ ADD CONSTRAINT issue_search_data_20_pkey PRIMARY KEY (project_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.issue_search_data_21
+ ADD CONSTRAINT issue_search_data_21_pkey PRIMARY KEY (project_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.issue_search_data_22
+ ADD CONSTRAINT issue_search_data_22_pkey PRIMARY KEY (project_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.issue_search_data_23
+ ADD CONSTRAINT issue_search_data_23_pkey PRIMARY KEY (project_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.issue_search_data_24
+ ADD CONSTRAINT issue_search_data_24_pkey PRIMARY KEY (project_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.issue_search_data_25
+ ADD CONSTRAINT issue_search_data_25_pkey PRIMARY KEY (project_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.issue_search_data_26
+ ADD CONSTRAINT issue_search_data_26_pkey PRIMARY KEY (project_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.issue_search_data_27
+ ADD CONSTRAINT issue_search_data_27_pkey PRIMARY KEY (project_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.issue_search_data_28
+ ADD CONSTRAINT issue_search_data_28_pkey PRIMARY KEY (project_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.issue_search_data_29
+ ADD CONSTRAINT issue_search_data_29_pkey PRIMARY KEY (project_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.issue_search_data_30
+ ADD CONSTRAINT issue_search_data_30_pkey PRIMARY KEY (project_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.issue_search_data_31
+ ADD CONSTRAINT issue_search_data_31_pkey PRIMARY KEY (project_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.issue_search_data_32
+ ADD CONSTRAINT issue_search_data_32_pkey PRIMARY KEY (project_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.issue_search_data_33
+ ADD CONSTRAINT issue_search_data_33_pkey PRIMARY KEY (project_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.issue_search_data_34
+ ADD CONSTRAINT issue_search_data_34_pkey PRIMARY KEY (project_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.issue_search_data_35
+ ADD CONSTRAINT issue_search_data_35_pkey PRIMARY KEY (project_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.issue_search_data_36
+ ADD CONSTRAINT issue_search_data_36_pkey PRIMARY KEY (project_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.issue_search_data_37
+ ADD CONSTRAINT issue_search_data_37_pkey PRIMARY KEY (project_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.issue_search_data_38
+ ADD CONSTRAINT issue_search_data_38_pkey PRIMARY KEY (project_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.issue_search_data_39
+ ADD CONSTRAINT issue_search_data_39_pkey PRIMARY KEY (project_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.issue_search_data_40
+ ADD CONSTRAINT issue_search_data_40_pkey PRIMARY KEY (project_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.issue_search_data_41
+ ADD CONSTRAINT issue_search_data_41_pkey PRIMARY KEY (project_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.issue_search_data_42
+ ADD CONSTRAINT issue_search_data_42_pkey PRIMARY KEY (project_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.issue_search_data_43
+ ADD CONSTRAINT issue_search_data_43_pkey PRIMARY KEY (project_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.issue_search_data_44
+ ADD CONSTRAINT issue_search_data_44_pkey PRIMARY KEY (project_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.issue_search_data_45
+ ADD CONSTRAINT issue_search_data_45_pkey PRIMARY KEY (project_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.issue_search_data_46
+ ADD CONSTRAINT issue_search_data_46_pkey PRIMARY KEY (project_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.issue_search_data_47
+ ADD CONSTRAINT issue_search_data_47_pkey PRIMARY KEY (project_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.issue_search_data_48
+ ADD CONSTRAINT issue_search_data_48_pkey PRIMARY KEY (project_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.issue_search_data_49
+ ADD CONSTRAINT issue_search_data_49_pkey PRIMARY KEY (project_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.issue_search_data_50
+ ADD CONSTRAINT issue_search_data_50_pkey PRIMARY KEY (project_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.issue_search_data_51
+ ADD CONSTRAINT issue_search_data_51_pkey PRIMARY KEY (project_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.issue_search_data_52
+ ADD CONSTRAINT issue_search_data_52_pkey PRIMARY KEY (project_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.issue_search_data_53
+ ADD CONSTRAINT issue_search_data_53_pkey PRIMARY KEY (project_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.issue_search_data_54
+ ADD CONSTRAINT issue_search_data_54_pkey PRIMARY KEY (project_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.issue_search_data_55
+ ADD CONSTRAINT issue_search_data_55_pkey PRIMARY KEY (project_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.issue_search_data_56
+ ADD CONSTRAINT issue_search_data_56_pkey PRIMARY KEY (project_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.issue_search_data_57
+ ADD CONSTRAINT issue_search_data_57_pkey PRIMARY KEY (project_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.issue_search_data_58
+ ADD CONSTRAINT issue_search_data_58_pkey PRIMARY KEY (project_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.issue_search_data_59
+ ADD CONSTRAINT issue_search_data_59_pkey PRIMARY KEY (project_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.issue_search_data_60
+ ADD CONSTRAINT issue_search_data_60_pkey PRIMARY KEY (project_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.issue_search_data_61
+ ADD CONSTRAINT issue_search_data_61_pkey PRIMARY KEY (project_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.issue_search_data_62
+ ADD CONSTRAINT issue_search_data_62_pkey PRIMARY KEY (project_id, issue_id);
+
+ALTER TABLE ONLY gitlab_partitions_static.issue_search_data_63
+ ADD CONSTRAINT issue_search_data_63_pkey PRIMARY KEY (project_id, issue_id);
+
ALTER TABLE ONLY product_analytics_events_experimental
ADD CONSTRAINT product_analytics_events_experimental_pkey PRIMARY KEY (id, project_id);
@@ -22927,6 +23786,9 @@ ALTER TABLE ONLY alert_management_http_integrations
ALTER TABLE ONLY allowed_email_domains
ADD CONSTRAINT allowed_email_domains_pkey PRIMARY KEY (id);
+ALTER TABLE ONLY analytics_cycle_analytics_aggregations
+ ADD CONSTRAINT analytics_cycle_analytics_aggregations_pkey PRIMARY KEY (group_id);
+
ALTER TABLE ONLY analytics_cycle_analytics_group_stages
ADD CONSTRAINT analytics_cycle_analytics_group_stages_pkey PRIMARY KEY (id);
@@ -23110,9 +23972,6 @@ ALTER TABLE ONLY chat_teams
ALTER TABLE vulnerability_scanners
ADD CONSTRAINT check_37608c9db5 CHECK ((char_length(vendor) <= 255)) NOT VALID;
-ALTER TABLE security_findings
- ADD CONSTRAINT check_6c2851a8c9 CHECK ((uuid IS NOT NULL)) NOT VALID;
-
ALTER TABLE sprints
ADD CONSTRAINT check_ccd8a1eae0 CHECK ((start_date IS NOT NULL)) NOT VALID;
@@ -24061,9 +24920,6 @@ ALTER TABLE ONLY pages_domain_acme_orders
ALTER TABLE ONLY pages_domains
ADD CONSTRAINT pages_domains_pkey PRIMARY KEY (id);
-ALTER TABLE ONLY partitioned_foreign_keys
- ADD CONSTRAINT partitioned_foreign_keys_pkey PRIMARY KEY (id);
-
ALTER TABLE ONLY path_locks
ADD CONSTRAINT path_locks_pkey PRIMARY KEY (id);
@@ -24106,6 +24962,9 @@ ALTER TABLE ONLY project_authorizations
ALTER TABLE ONLY project_auto_devops
ADD CONSTRAINT project_auto_devops_pkey PRIMARY KEY (id);
+ALTER TABLE ONLY project_build_artifacts_size_refreshes
+ ADD CONSTRAINT project_build_artifacts_size_refreshes_pkey PRIMARY KEY (id);
+
ALTER TABLE ONLY project_ci_cd_settings
ADD CONSTRAINT project_ci_cd_settings_pkey PRIMARY KEY (id);
@@ -24229,9 +25088,15 @@ ALTER TABLE ONLY raw_usage_data
ALTER TABLE ONLY redirect_routes
ADD CONSTRAINT redirect_routes_pkey PRIMARY KEY (id);
+ALTER TABLE ONLY related_epic_links
+ ADD CONSTRAINT related_epic_links_pkey PRIMARY KEY (id);
+
ALTER TABLE ONLY release_links
ADD CONSTRAINT release_links_pkey PRIMARY KEY (id);
+ALTER TABLE releases
+ ADD CONSTRAINT releases_not_null_tag CHECK ((tag IS NOT NULL)) NOT VALID;
+
ALTER TABLE ONLY releases
ADD CONSTRAINT releases_pkey PRIMARY KEY (id);
@@ -24277,6 +25142,9 @@ ALTER TABLE ONLY saml_group_links
ALTER TABLE ONLY saml_providers
ADD CONSTRAINT saml_providers_pkey PRIMARY KEY (id);
+ALTER TABLE ONLY saved_replies
+ ADD CONSTRAINT saved_replies_pkey PRIMARY KEY (id);
+
ALTER TABLE ONLY schema_migrations
ADD CONSTRAINT schema_migrations_pkey PRIMARY KEY (version);
@@ -25099,6 +25967,266 @@ CREATE INDEX index_ff39be5400 ON gitlab_partitions_static.analytics_cycle_analyt
CREATE INDEX index_ff8741d8d7 ON gitlab_partitions_static.analytics_cycle_analytics_issue_stage_events_28 USING btree (stage_event_hash_id, group_id, start_event_timestamp, issue_id) WHERE ((end_event_timestamp IS NULL) AND (state_id = 1));
+CREATE INDEX index_issue_search_data_on_issue_id ON ONLY issue_search_data USING btree (issue_id);
+
+CREATE INDEX issue_search_data_00_issue_id_idx ON gitlab_partitions_static.issue_search_data_00 USING btree (issue_id);
+
+CREATE INDEX index_issue_search_data_on_search_vector ON ONLY issue_search_data USING gin (search_vector);
+
+CREATE INDEX issue_search_data_00_search_vector_idx ON gitlab_partitions_static.issue_search_data_00 USING gin (search_vector);
+
+CREATE INDEX issue_search_data_01_issue_id_idx ON gitlab_partitions_static.issue_search_data_01 USING btree (issue_id);
+
+CREATE INDEX issue_search_data_01_search_vector_idx ON gitlab_partitions_static.issue_search_data_01 USING gin (search_vector);
+
+CREATE INDEX issue_search_data_02_issue_id_idx ON gitlab_partitions_static.issue_search_data_02 USING btree (issue_id);
+
+CREATE INDEX issue_search_data_02_search_vector_idx ON gitlab_partitions_static.issue_search_data_02 USING gin (search_vector);
+
+CREATE INDEX issue_search_data_03_issue_id_idx ON gitlab_partitions_static.issue_search_data_03 USING btree (issue_id);
+
+CREATE INDEX issue_search_data_03_search_vector_idx ON gitlab_partitions_static.issue_search_data_03 USING gin (search_vector);
+
+CREATE INDEX issue_search_data_04_issue_id_idx ON gitlab_partitions_static.issue_search_data_04 USING btree (issue_id);
+
+CREATE INDEX issue_search_data_04_search_vector_idx ON gitlab_partitions_static.issue_search_data_04 USING gin (search_vector);
+
+CREATE INDEX issue_search_data_05_issue_id_idx ON gitlab_partitions_static.issue_search_data_05 USING btree (issue_id);
+
+CREATE INDEX issue_search_data_05_search_vector_idx ON gitlab_partitions_static.issue_search_data_05 USING gin (search_vector);
+
+CREATE INDEX issue_search_data_06_issue_id_idx ON gitlab_partitions_static.issue_search_data_06 USING btree (issue_id);
+
+CREATE INDEX issue_search_data_06_search_vector_idx ON gitlab_partitions_static.issue_search_data_06 USING gin (search_vector);
+
+CREATE INDEX issue_search_data_07_issue_id_idx ON gitlab_partitions_static.issue_search_data_07 USING btree (issue_id);
+
+CREATE INDEX issue_search_data_07_search_vector_idx ON gitlab_partitions_static.issue_search_data_07 USING gin (search_vector);
+
+CREATE INDEX issue_search_data_08_issue_id_idx ON gitlab_partitions_static.issue_search_data_08 USING btree (issue_id);
+
+CREATE INDEX issue_search_data_08_search_vector_idx ON gitlab_partitions_static.issue_search_data_08 USING gin (search_vector);
+
+CREATE INDEX issue_search_data_09_issue_id_idx ON gitlab_partitions_static.issue_search_data_09 USING btree (issue_id);
+
+CREATE INDEX issue_search_data_09_search_vector_idx ON gitlab_partitions_static.issue_search_data_09 USING gin (search_vector);
+
+CREATE INDEX issue_search_data_10_issue_id_idx ON gitlab_partitions_static.issue_search_data_10 USING btree (issue_id);
+
+CREATE INDEX issue_search_data_10_search_vector_idx ON gitlab_partitions_static.issue_search_data_10 USING gin (search_vector);
+
+CREATE INDEX issue_search_data_11_issue_id_idx ON gitlab_partitions_static.issue_search_data_11 USING btree (issue_id);
+
+CREATE INDEX issue_search_data_11_search_vector_idx ON gitlab_partitions_static.issue_search_data_11 USING gin (search_vector);
+
+CREATE INDEX issue_search_data_12_issue_id_idx ON gitlab_partitions_static.issue_search_data_12 USING btree (issue_id);
+
+CREATE INDEX issue_search_data_12_search_vector_idx ON gitlab_partitions_static.issue_search_data_12 USING gin (search_vector);
+
+CREATE INDEX issue_search_data_13_issue_id_idx ON gitlab_partitions_static.issue_search_data_13 USING btree (issue_id);
+
+CREATE INDEX issue_search_data_13_search_vector_idx ON gitlab_partitions_static.issue_search_data_13 USING gin (search_vector);
+
+CREATE INDEX issue_search_data_14_issue_id_idx ON gitlab_partitions_static.issue_search_data_14 USING btree (issue_id);
+
+CREATE INDEX issue_search_data_14_search_vector_idx ON gitlab_partitions_static.issue_search_data_14 USING gin (search_vector);
+
+CREATE INDEX issue_search_data_15_issue_id_idx ON gitlab_partitions_static.issue_search_data_15 USING btree (issue_id);
+
+CREATE INDEX issue_search_data_15_search_vector_idx ON gitlab_partitions_static.issue_search_data_15 USING gin (search_vector);
+
+CREATE INDEX issue_search_data_16_issue_id_idx ON gitlab_partitions_static.issue_search_data_16 USING btree (issue_id);
+
+CREATE INDEX issue_search_data_16_search_vector_idx ON gitlab_partitions_static.issue_search_data_16 USING gin (search_vector);
+
+CREATE INDEX issue_search_data_17_issue_id_idx ON gitlab_partitions_static.issue_search_data_17 USING btree (issue_id);
+
+CREATE INDEX issue_search_data_17_search_vector_idx ON gitlab_partitions_static.issue_search_data_17 USING gin (search_vector);
+
+CREATE INDEX issue_search_data_18_issue_id_idx ON gitlab_partitions_static.issue_search_data_18 USING btree (issue_id);
+
+CREATE INDEX issue_search_data_18_search_vector_idx ON gitlab_partitions_static.issue_search_data_18 USING gin (search_vector);
+
+CREATE INDEX issue_search_data_19_issue_id_idx ON gitlab_partitions_static.issue_search_data_19 USING btree (issue_id);
+
+CREATE INDEX issue_search_data_19_search_vector_idx ON gitlab_partitions_static.issue_search_data_19 USING gin (search_vector);
+
+CREATE INDEX issue_search_data_20_issue_id_idx ON gitlab_partitions_static.issue_search_data_20 USING btree (issue_id);
+
+CREATE INDEX issue_search_data_20_search_vector_idx ON gitlab_partitions_static.issue_search_data_20 USING gin (search_vector);
+
+CREATE INDEX issue_search_data_21_issue_id_idx ON gitlab_partitions_static.issue_search_data_21 USING btree (issue_id);
+
+CREATE INDEX issue_search_data_21_search_vector_idx ON gitlab_partitions_static.issue_search_data_21 USING gin (search_vector);
+
+CREATE INDEX issue_search_data_22_issue_id_idx ON gitlab_partitions_static.issue_search_data_22 USING btree (issue_id);
+
+CREATE INDEX issue_search_data_22_search_vector_idx ON gitlab_partitions_static.issue_search_data_22 USING gin (search_vector);
+
+CREATE INDEX issue_search_data_23_issue_id_idx ON gitlab_partitions_static.issue_search_data_23 USING btree (issue_id);
+
+CREATE INDEX issue_search_data_23_search_vector_idx ON gitlab_partitions_static.issue_search_data_23 USING gin (search_vector);
+
+CREATE INDEX issue_search_data_24_issue_id_idx ON gitlab_partitions_static.issue_search_data_24 USING btree (issue_id);
+
+CREATE INDEX issue_search_data_24_search_vector_idx ON gitlab_partitions_static.issue_search_data_24 USING gin (search_vector);
+
+CREATE INDEX issue_search_data_25_issue_id_idx ON gitlab_partitions_static.issue_search_data_25 USING btree (issue_id);
+
+CREATE INDEX issue_search_data_25_search_vector_idx ON gitlab_partitions_static.issue_search_data_25 USING gin (search_vector);
+
+CREATE INDEX issue_search_data_26_issue_id_idx ON gitlab_partitions_static.issue_search_data_26 USING btree (issue_id);
+
+CREATE INDEX issue_search_data_26_search_vector_idx ON gitlab_partitions_static.issue_search_data_26 USING gin (search_vector);
+
+CREATE INDEX issue_search_data_27_issue_id_idx ON gitlab_partitions_static.issue_search_data_27 USING btree (issue_id);
+
+CREATE INDEX issue_search_data_27_search_vector_idx ON gitlab_partitions_static.issue_search_data_27 USING gin (search_vector);
+
+CREATE INDEX issue_search_data_28_issue_id_idx ON gitlab_partitions_static.issue_search_data_28 USING btree (issue_id);
+
+CREATE INDEX issue_search_data_28_search_vector_idx ON gitlab_partitions_static.issue_search_data_28 USING gin (search_vector);
+
+CREATE INDEX issue_search_data_29_issue_id_idx ON gitlab_partitions_static.issue_search_data_29 USING btree (issue_id);
+
+CREATE INDEX issue_search_data_29_search_vector_idx ON gitlab_partitions_static.issue_search_data_29 USING gin (search_vector);
+
+CREATE INDEX issue_search_data_30_issue_id_idx ON gitlab_partitions_static.issue_search_data_30 USING btree (issue_id);
+
+CREATE INDEX issue_search_data_30_search_vector_idx ON gitlab_partitions_static.issue_search_data_30 USING gin (search_vector);
+
+CREATE INDEX issue_search_data_31_issue_id_idx ON gitlab_partitions_static.issue_search_data_31 USING btree (issue_id);
+
+CREATE INDEX issue_search_data_31_search_vector_idx ON gitlab_partitions_static.issue_search_data_31 USING gin (search_vector);
+
+CREATE INDEX issue_search_data_32_issue_id_idx ON gitlab_partitions_static.issue_search_data_32 USING btree (issue_id);
+
+CREATE INDEX issue_search_data_32_search_vector_idx ON gitlab_partitions_static.issue_search_data_32 USING gin (search_vector);
+
+CREATE INDEX issue_search_data_33_issue_id_idx ON gitlab_partitions_static.issue_search_data_33 USING btree (issue_id);
+
+CREATE INDEX issue_search_data_33_search_vector_idx ON gitlab_partitions_static.issue_search_data_33 USING gin (search_vector);
+
+CREATE INDEX issue_search_data_34_issue_id_idx ON gitlab_partitions_static.issue_search_data_34 USING btree (issue_id);
+
+CREATE INDEX issue_search_data_34_search_vector_idx ON gitlab_partitions_static.issue_search_data_34 USING gin (search_vector);
+
+CREATE INDEX issue_search_data_35_issue_id_idx ON gitlab_partitions_static.issue_search_data_35 USING btree (issue_id);
+
+CREATE INDEX issue_search_data_35_search_vector_idx ON gitlab_partitions_static.issue_search_data_35 USING gin (search_vector);
+
+CREATE INDEX issue_search_data_36_issue_id_idx ON gitlab_partitions_static.issue_search_data_36 USING btree (issue_id);
+
+CREATE INDEX issue_search_data_36_search_vector_idx ON gitlab_partitions_static.issue_search_data_36 USING gin (search_vector);
+
+CREATE INDEX issue_search_data_37_issue_id_idx ON gitlab_partitions_static.issue_search_data_37 USING btree (issue_id);
+
+CREATE INDEX issue_search_data_37_search_vector_idx ON gitlab_partitions_static.issue_search_data_37 USING gin (search_vector);
+
+CREATE INDEX issue_search_data_38_issue_id_idx ON gitlab_partitions_static.issue_search_data_38 USING btree (issue_id);
+
+CREATE INDEX issue_search_data_38_search_vector_idx ON gitlab_partitions_static.issue_search_data_38 USING gin (search_vector);
+
+CREATE INDEX issue_search_data_39_issue_id_idx ON gitlab_partitions_static.issue_search_data_39 USING btree (issue_id);
+
+CREATE INDEX issue_search_data_39_search_vector_idx ON gitlab_partitions_static.issue_search_data_39 USING gin (search_vector);
+
+CREATE INDEX issue_search_data_40_issue_id_idx ON gitlab_partitions_static.issue_search_data_40 USING btree (issue_id);
+
+CREATE INDEX issue_search_data_40_search_vector_idx ON gitlab_partitions_static.issue_search_data_40 USING gin (search_vector);
+
+CREATE INDEX issue_search_data_41_issue_id_idx ON gitlab_partitions_static.issue_search_data_41 USING btree (issue_id);
+
+CREATE INDEX issue_search_data_41_search_vector_idx ON gitlab_partitions_static.issue_search_data_41 USING gin (search_vector);
+
+CREATE INDEX issue_search_data_42_issue_id_idx ON gitlab_partitions_static.issue_search_data_42 USING btree (issue_id);
+
+CREATE INDEX issue_search_data_42_search_vector_idx ON gitlab_partitions_static.issue_search_data_42 USING gin (search_vector);
+
+CREATE INDEX issue_search_data_43_issue_id_idx ON gitlab_partitions_static.issue_search_data_43 USING btree (issue_id);
+
+CREATE INDEX issue_search_data_43_search_vector_idx ON gitlab_partitions_static.issue_search_data_43 USING gin (search_vector);
+
+CREATE INDEX issue_search_data_44_issue_id_idx ON gitlab_partitions_static.issue_search_data_44 USING btree (issue_id);
+
+CREATE INDEX issue_search_data_44_search_vector_idx ON gitlab_partitions_static.issue_search_data_44 USING gin (search_vector);
+
+CREATE INDEX issue_search_data_45_issue_id_idx ON gitlab_partitions_static.issue_search_data_45 USING btree (issue_id);
+
+CREATE INDEX issue_search_data_45_search_vector_idx ON gitlab_partitions_static.issue_search_data_45 USING gin (search_vector);
+
+CREATE INDEX issue_search_data_46_issue_id_idx ON gitlab_partitions_static.issue_search_data_46 USING btree (issue_id);
+
+CREATE INDEX issue_search_data_46_search_vector_idx ON gitlab_partitions_static.issue_search_data_46 USING gin (search_vector);
+
+CREATE INDEX issue_search_data_47_issue_id_idx ON gitlab_partitions_static.issue_search_data_47 USING btree (issue_id);
+
+CREATE INDEX issue_search_data_47_search_vector_idx ON gitlab_partitions_static.issue_search_data_47 USING gin (search_vector);
+
+CREATE INDEX issue_search_data_48_issue_id_idx ON gitlab_partitions_static.issue_search_data_48 USING btree (issue_id);
+
+CREATE INDEX issue_search_data_48_search_vector_idx ON gitlab_partitions_static.issue_search_data_48 USING gin (search_vector);
+
+CREATE INDEX issue_search_data_49_issue_id_idx ON gitlab_partitions_static.issue_search_data_49 USING btree (issue_id);
+
+CREATE INDEX issue_search_data_49_search_vector_idx ON gitlab_partitions_static.issue_search_data_49 USING gin (search_vector);
+
+CREATE INDEX issue_search_data_50_issue_id_idx ON gitlab_partitions_static.issue_search_data_50 USING btree (issue_id);
+
+CREATE INDEX issue_search_data_50_search_vector_idx ON gitlab_partitions_static.issue_search_data_50 USING gin (search_vector);
+
+CREATE INDEX issue_search_data_51_issue_id_idx ON gitlab_partitions_static.issue_search_data_51 USING btree (issue_id);
+
+CREATE INDEX issue_search_data_51_search_vector_idx ON gitlab_partitions_static.issue_search_data_51 USING gin (search_vector);
+
+CREATE INDEX issue_search_data_52_issue_id_idx ON gitlab_partitions_static.issue_search_data_52 USING btree (issue_id);
+
+CREATE INDEX issue_search_data_52_search_vector_idx ON gitlab_partitions_static.issue_search_data_52 USING gin (search_vector);
+
+CREATE INDEX issue_search_data_53_issue_id_idx ON gitlab_partitions_static.issue_search_data_53 USING btree (issue_id);
+
+CREATE INDEX issue_search_data_53_search_vector_idx ON gitlab_partitions_static.issue_search_data_53 USING gin (search_vector);
+
+CREATE INDEX issue_search_data_54_issue_id_idx ON gitlab_partitions_static.issue_search_data_54 USING btree (issue_id);
+
+CREATE INDEX issue_search_data_54_search_vector_idx ON gitlab_partitions_static.issue_search_data_54 USING gin (search_vector);
+
+CREATE INDEX issue_search_data_55_issue_id_idx ON gitlab_partitions_static.issue_search_data_55 USING btree (issue_id);
+
+CREATE INDEX issue_search_data_55_search_vector_idx ON gitlab_partitions_static.issue_search_data_55 USING gin (search_vector);
+
+CREATE INDEX issue_search_data_56_issue_id_idx ON gitlab_partitions_static.issue_search_data_56 USING btree (issue_id);
+
+CREATE INDEX issue_search_data_56_search_vector_idx ON gitlab_partitions_static.issue_search_data_56 USING gin (search_vector);
+
+CREATE INDEX issue_search_data_57_issue_id_idx ON gitlab_partitions_static.issue_search_data_57 USING btree (issue_id);
+
+CREATE INDEX issue_search_data_57_search_vector_idx ON gitlab_partitions_static.issue_search_data_57 USING gin (search_vector);
+
+CREATE INDEX issue_search_data_58_issue_id_idx ON gitlab_partitions_static.issue_search_data_58 USING btree (issue_id);
+
+CREATE INDEX issue_search_data_58_search_vector_idx ON gitlab_partitions_static.issue_search_data_58 USING gin (search_vector);
+
+CREATE INDEX issue_search_data_59_issue_id_idx ON gitlab_partitions_static.issue_search_data_59 USING btree (issue_id);
+
+CREATE INDEX issue_search_data_59_search_vector_idx ON gitlab_partitions_static.issue_search_data_59 USING gin (search_vector);
+
+CREATE INDEX issue_search_data_60_issue_id_idx ON gitlab_partitions_static.issue_search_data_60 USING btree (issue_id);
+
+CREATE INDEX issue_search_data_60_search_vector_idx ON gitlab_partitions_static.issue_search_data_60 USING gin (search_vector);
+
+CREATE INDEX issue_search_data_61_issue_id_idx ON gitlab_partitions_static.issue_search_data_61 USING btree (issue_id);
+
+CREATE INDEX issue_search_data_61_search_vector_idx ON gitlab_partitions_static.issue_search_data_61 USING gin (search_vector);
+
+CREATE INDEX issue_search_data_62_issue_id_idx ON gitlab_partitions_static.issue_search_data_62 USING btree (issue_id);
+
+CREATE INDEX issue_search_data_62_search_vector_idx ON gitlab_partitions_static.issue_search_data_62 USING gin (search_vector);
+
+CREATE INDEX issue_search_data_63_issue_id_idx ON gitlab_partitions_static.issue_search_data_63 USING btree (issue_id);
+
+CREATE INDEX issue_search_data_63_search_vector_idx ON gitlab_partitions_static.issue_search_data_63 USING gin (search_vector);
+
CREATE INDEX index_product_analytics_events_experimental_project_and_time ON ONLY product_analytics_events_experimental USING btree (project_id, collector_tstamp);
CREATE INDEX product_analytics_events_expe_project_id_collector_tstamp_idx10 ON gitlab_partitions_static.product_analytics_events_experimental_10 USING btree (project_id, collector_tstamp);
@@ -25245,6 +26373,12 @@ CREATE INDEX approval_mr_rule_index_merge_request_id ON approval_merge_request_r
CREATE UNIQUE INDEX bulk_import_trackers_uniq_relation_by_entity ON bulk_import_trackers USING btree (bulk_import_entity_id, relation);
+CREATE INDEX ca_aggregations_last_consistency_check_updated_at ON analytics_cycle_analytics_aggregations USING btree (last_consistency_check_updated_at NULLS FIRST) WHERE (enabled IS TRUE);
+
+CREATE INDEX ca_aggregations_last_full_run_at ON analytics_cycle_analytics_aggregations USING btree (last_full_run_at NULLS FIRST) WHERE (enabled IS TRUE);
+
+CREATE INDEX ca_aggregations_last_incremental_run_at ON analytics_cycle_analytics_aggregations USING btree (last_incremental_run_at NULLS FIRST) WHERE (enabled IS TRUE);
+
CREATE INDEX cadence_create_iterations_automation ON iterations_cadences USING btree (automatic, duration_in_weeks, date((COALESCE(last_run_date, '1970-01-01'::date) + ((duration_in_weeks)::double precision * '7 days'::interval)))) WHERE (duration_in_weeks IS NOT NULL);
CREATE INDEX ci_builds_gitlab_monitor_metrics ON ci_builds USING btree (status, created_at, project_id) WHERE ((type)::text = 'Ci::Build'::text);
@@ -25289,6 +26423,8 @@ CREATE INDEX idx_audit_events_part_on_entity_id_desc_author_id_created_at ON ONL
CREATE INDEX idx_award_emoji_on_user_emoji_name_awardable_type_awardable_id ON award_emoji USING btree (user_id, name, awardable_type, awardable_id);
+CREATE INDEX idx_build_artifacts_size_refreshes_state_updated_at ON project_build_artifacts_size_refreshes USING btree (state, updated_at);
+
CREATE INDEX idx_ci_pipelines_artifacts_locked ON ci_pipelines USING btree (ci_ref_id, id) WHERE (locked = 1);
CREATE INDEX idx_container_exp_policies_on_project_id_next_run_at ON container_expiration_policies USING btree (project_id, next_run_at) WHERE (enabled = true);
@@ -25397,6 +26533,12 @@ CREATE UNIQUE INDEX idx_project_id_payload_key_self_managed_prometheus_alert_eve
CREATE INDEX idx_project_repository_check_partial ON projects USING btree (repository_storage, created_at) WHERE (last_repository_check_at IS NULL);
+CREATE INDEX idx_projects_api_created_at_id_for_archived ON projects USING btree (created_at, id) WHERE ((archived = true) AND (pending_delete = false) AND (hidden = false));
+
+CREATE INDEX idx_projects_api_created_at_id_for_archived_vis20 ON projects USING btree (created_at, id) WHERE ((archived = true) AND (visibility_level = 20) AND (pending_delete = false) AND (hidden = false));
+
+CREATE INDEX idx_projects_api_created_at_id_for_vis10 ON projects USING btree (created_at, id) WHERE ((visibility_level = 10) AND (pending_delete = false) AND (hidden = false));
+
CREATE INDEX idx_projects_id_created_at_disable_overriding_approvers_false ON projects USING btree (id, created_at) WHERE ((disable_overriding_approvers_per_merge_request = false) OR (disable_overriding_approvers_per_merge_request IS NULL));
CREATE INDEX idx_projects_id_created_at_disable_overriding_approvers_true ON projects USING btree (id, created_at) WHERE (disable_overriding_approvers_per_merge_request = true);
@@ -25805,6 +26947,8 @@ CREATE INDEX index_ci_job_artifacts_on_file_store ON ci_job_artifacts USING btre
CREATE INDEX index_ci_job_artifacts_on_file_type_for_devops_adoption ON ci_job_artifacts USING btree (file_type, project_id, created_at) WHERE (file_type = ANY (ARRAY[5, 6, 8, 23]));
+CREATE INDEX index_ci_job_artifacts_on_id_project_id_and_created_at ON ci_job_artifacts USING btree (project_id, created_at, id);
+
CREATE INDEX index_ci_job_artifacts_on_id_project_id_and_file_type ON ci_job_artifacts USING btree (project_id, file_type, id);
CREATE UNIQUE INDEX index_ci_job_artifacts_on_job_id_and_file_type ON ci_job_artifacts USING btree (job_id, file_type);
@@ -26751,6 +27895,8 @@ CREATE INDEX index_issues_on_description_trigram ON issues USING gin (descriptio
CREATE INDEX index_issues_on_duplicated_to_id ON issues USING btree (duplicated_to_id) WHERE (duplicated_to_id IS NOT NULL);
+CREATE INDEX index_issues_on_id_and_weight ON issues USING btree (id, weight);
+
CREATE INDEX index_issues_on_incident_issue_type ON issues USING btree (issue_type) WHERE (issue_type = 1);
CREATE INDEX index_issues_on_last_edited_by_id ON issues USING btree (last_edited_by_id);
@@ -27175,12 +28321,18 @@ CREATE INDEX index_on_identities_lower_extern_uid_and_provider ON identities USI
CREATE UNIQUE INDEX index_on_instance_statistics_recorded_at_and_identifier ON analytics_usage_trends_measurements USING btree (identifier, recorded_at);
+CREATE INDEX index_on_issues_closed_incidents_by_project_id_and_closed_at ON issues USING btree (project_id, closed_at) WHERE ((issue_type = 1) AND (state_id = 2));
+
CREATE INDEX index_on_label_links_all_columns ON label_links USING btree (target_id, label_id, target_type);
CREATE INDEX index_on_merge_request_assignees_state ON merge_request_assignees USING btree (state) WHERE (state = 2);
+CREATE INDEX index_on_merge_request_assignees_updated_state_by_user_id ON merge_request_assignees USING btree (updated_state_by_user_id);
+
CREATE INDEX index_on_merge_request_reviewers_state ON merge_request_reviewers USING btree (state) WHERE (state = 2);
+CREATE INDEX index_on_merge_request_reviewers_updated_state_by_user_id ON merge_request_reviewers USING btree (updated_state_by_user_id);
+
CREATE INDEX index_on_merge_requests_for_latest_diffs ON merge_requests USING btree (target_project_id) INCLUDE (id, latest_merge_request_diff_id);
COMMENT ON INDEX index_on_merge_requests_for_latest_diffs IS 'Index used to efficiently obtain the oldest merge request for a commit SHA';
@@ -27367,8 +28519,6 @@ CREATE UNIQUE INDEX index_partial_am_alerts_on_project_id_and_fingerprint ON ale
CREATE INDEX index_partial_ci_builds_on_user_id_name_parser_features ON ci_builds USING btree (user_id, name) WHERE (((type)::text = 'Ci::Build'::text) AND ((name)::text = ANY (ARRAY[('container_scanning'::character varying)::text, ('dast'::character varying)::text, ('dependency_scanning'::character varying)::text, ('license_management'::character varying)::text, ('license_scanning'::character varying)::text, ('sast'::character varying)::text, ('coverage_fuzzing'::character varying)::text, ('secret_detection'::character varying)::text])));
-CREATE UNIQUE INDEX index_partitioned_foreign_keys_unique_index ON partitioned_foreign_keys USING btree (to_table, from_table, from_column);
-
CREATE INDEX index_pat_on_user_id_and_expires_at ON personal_access_tokens USING btree (user_id, expires_at);
CREATE INDEX index_path_locks_on_path ON path_locks USING btree (path);
@@ -27405,10 +28555,10 @@ CREATE UNIQUE INDEX index_project_aliases_on_name ON project_aliases USING btree
CREATE INDEX index_project_aliases_on_project_id ON project_aliases USING btree (project_id);
-CREATE INDEX index_project_authorizations_on_project_id_user_id ON project_authorizations USING btree (project_id, user_id);
-
CREATE UNIQUE INDEX index_project_auto_devops_on_project_id ON project_auto_devops USING btree (project_id);
+CREATE UNIQUE INDEX index_project_build_artifacts_size_refreshes_on_project_id ON project_build_artifacts_size_refreshes USING btree (project_id);
+
CREATE UNIQUE INDEX index_project_ci_cd_settings_on_project_id ON project_ci_cd_settings USING btree (project_id);
CREATE UNIQUE INDEX index_project_ci_feature_usages_unique_columns ON project_ci_feature_usages USING btree (project_id, feature, default_branch);
@@ -27509,12 +28659,6 @@ CREATE INDEX index_projects_aimed_for_deletion ON projects USING btree (marked_f
CREATE INDEX index_projects_api_created_at_id_desc ON projects USING btree (created_at, id DESC);
-CREATE INDEX index_projects_api_created_at_id_for_archived ON projects USING btree (created_at, id) WHERE ((archived = true) AND (pending_delete = false));
-
-CREATE INDEX index_projects_api_created_at_id_for_archived_vis20 ON projects USING btree (created_at, id) WHERE ((archived = true) AND (visibility_level = 20) AND (pending_delete = false));
-
-CREATE INDEX index_projects_api_created_at_id_for_vis10 ON projects USING btree (created_at, id) WHERE ((visibility_level = 10) AND (pending_delete = false));
-
CREATE INDEX index_projects_api_last_activity_at_id_desc ON projects USING btree (last_activity_at, id DESC);
CREATE INDEX index_projects_api_name_id_desc ON projects USING btree (name, id DESC);
@@ -27673,13 +28817,21 @@ CREATE UNIQUE INDEX index_redirect_routes_on_path_unique_text_pattern_ops ON red
CREATE INDEX index_redirect_routes_on_source_type_and_source_id ON redirect_routes USING btree (source_type, source_id);
+CREATE INDEX index_related_epic_links_on_source_id ON related_epic_links USING btree (source_id);
+
+CREATE UNIQUE INDEX index_related_epic_links_on_source_id_and_target_id ON related_epic_links USING btree (source_id, target_id);
+
+CREATE INDEX index_related_epic_links_on_target_id ON related_epic_links USING btree (target_id);
+
CREATE UNIQUE INDEX index_release_links_on_release_id_and_name ON release_links USING btree (release_id, name);
CREATE UNIQUE INDEX index_release_links_on_release_id_and_url ON release_links USING btree (release_id, url);
CREATE INDEX index_releases_on_author_id_id_created_at ON releases USING btree (author_id, id, created_at);
-CREATE INDEX index_releases_on_project_id_and_tag ON releases USING btree (project_id, tag);
+CREATE INDEX index_releases_on_project_id_and_released_at_and_id ON releases USING btree (project_id, released_at, id);
+
+CREATE UNIQUE INDEX index_releases_on_project_tag_unique ON releases USING btree (project_id, tag);
CREATE INDEX index_releases_on_released_at ON releases USING btree (released_at);
@@ -27783,6 +28935,8 @@ CREATE UNIQUE INDEX index_saml_group_links_on_group_id_and_saml_group_name ON sa
CREATE INDEX index_saml_providers_on_group_id ON saml_providers USING btree (group_id);
+CREATE UNIQUE INDEX index_saved_replies_on_name_text_pattern_ops ON saved_replies USING btree (user_id, name text_pattern_ops);
+
CREATE INDEX index_scim_identities_on_group_id ON scim_identities USING btree (group_id);
CREATE UNIQUE INDEX index_scim_identities_on_lower_extern_uid_and_group_id ON scim_identities USING btree (lower((extern_uid)::text), group_id);
@@ -27793,7 +28947,7 @@ CREATE UNIQUE INDEX index_scim_oauth_access_tokens_on_group_id_and_token_encrypt
CREATE INDEX index_secure_ci_builds_on_user_id_name_created_at ON ci_builds USING btree (user_id, name, created_at) WHERE (((type)::text = 'Ci::Build'::text) AND ((name)::text = ANY (ARRAY[('container_scanning'::character varying)::text, ('dast'::character varying)::text, ('dependency_scanning'::character varying)::text, ('license_management'::character varying)::text, ('license_scanning'::character varying)::text, ('sast'::character varying)::text, ('coverage_fuzzing'::character varying)::text, ('apifuzzer_fuzz'::character varying)::text, ('apifuzzer_fuzz_dnd'::character varying)::text, ('secret_detection'::character varying)::text])));
-CREATE INDEX index_security_ci_builds_on_name_and_id_parser_features ON 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, ('coverage_fuzzing'::character varying)::text, ('license_scanning'::character varying)::text])) AND ((type)::text = 'Ci::Build'::text));
+CREATE INDEX index_security_ci_builds_on_name_and_id_parser_features ON 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, ('coverage_fuzzing'::character varying)::text, ('license_scanning'::character varying)::text, ('apifuzzer_fuzz'::character varying)::text, ('apifuzzer_fuzz_dnd'::character varying)::text])) AND ((type)::text = 'Ci::Build'::text));
CREATE INDEX index_security_findings_on_confidence ON security_findings USING btree (confidence);
@@ -27815,6 +28969,8 @@ CREATE INDEX index_security_scans_on_pipeline_id ON security_scans USING btree (
CREATE INDEX index_security_scans_on_project_id ON security_scans USING btree (project_id);
+CREATE UNIQUE INDEX index_security_training_providers_on_unique_name ON security_training_providers USING btree (name);
+
CREATE INDEX index_security_trainings_on_project_id ON security_trainings USING btree (project_id);
CREATE INDEX index_security_trainings_on_provider_id ON security_trainings USING btree (provider_id);
@@ -27901,8 +29057,6 @@ CREATE INDEX index_software_licenses_on_spdx_identifier ON software_licenses USI
CREATE UNIQUE INDEX index_software_licenses_on_unique_name ON software_licenses USING btree (name);
-CREATE UNIQUE INDEX index_sop_configs_on_project_id ON security_orchestration_policy_configurations USING btree (project_id);
-
CREATE INDEX index_sop_configurations_project_id_policy_project_id ON security_orchestration_policy_configurations USING btree (security_policy_management_project_id, project_id);
CREATE INDEX index_sop_schedules_on_sop_configuration_id ON security_orchestration_policy_rule_schedules USING btree (security_orchestration_policy_configuration_id);
@@ -27919,12 +29073,8 @@ CREATE INDEX index_sprints_on_due_date ON sprints USING btree (due_date);
CREATE INDEX index_sprints_on_group_id ON sprints USING btree (group_id);
-CREATE UNIQUE INDEX index_sprints_on_iterations_cadence_id_and_title ON sprints USING btree (iterations_cadence_id, title);
-
CREATE UNIQUE INDEX index_sprints_on_project_id_and_iid ON sprints USING btree (project_id, iid);
-CREATE UNIQUE INDEX index_sprints_on_project_id_and_title ON sprints USING btree (project_id, title) WHERE (project_id IS NOT NULL);
-
CREATE INDEX index_sprints_on_title ON sprints USING btree (title);
CREATE INDEX index_sprints_on_title_trigram ON sprints USING gin (title gin_trgm_ops);
@@ -28025,6 +29175,8 @@ CREATE UNIQUE INDEX index_token_with_ivs_on_hashed_token ON token_with_ivs USING
CREATE INDEX index_topics_non_private_projects_count ON topics USING btree (non_private_projects_count DESC, id);
+CREATE INDEX index_topics_on_lower_name ON topics USING btree (lower(name));
+
CREATE UNIQUE INDEX index_topics_on_name ON topics USING btree (name);
CREATE INDEX index_topics_on_name_trigram ON topics USING gin (name gin_trgm_ops);
@@ -28043,6 +29195,8 @@ CREATE UNIQUE INDEX index_unique_ci_runner_projects_on_runner_id_and_project_id
CREATE UNIQUE INDEX index_unique_issue_metrics_issue_id ON issue_metrics USING btree (issue_id);
+CREATE UNIQUE INDEX index_unique_project_authorizations_on_project_id_user_id ON project_authorizations USING btree (project_id, user_id);
+
CREATE INDEX index_unit_test_failures_failed_at ON ci_unit_test_failures USING btree (failed_at DESC);
CREATE UNIQUE INDEX index_unit_test_failures_unique_columns ON ci_unit_test_failures USING btree (unit_test_id, failed_at DESC, build_id);
@@ -28395,6 +29549,10 @@ CREATE INDEX partial_index_deployments_for_legacy_successful_deployments ON depl
CREATE INDEX partial_index_deployments_for_project_id_and_tag ON deployments USING btree (project_id) WHERE (tag IS TRUE);
+CREATE UNIQUE INDEX partial_index_sop_configs_on_namespace_id ON security_orchestration_policy_configurations USING btree (namespace_id) WHERE (namespace_id IS NOT NULL);
+
+CREATE UNIQUE INDEX partial_index_sop_configs_on_project_id ON security_orchestration_policy_configurations USING btree (project_id) WHERE (project_id IS NOT NULL);
+
CREATE UNIQUE INDEX snippet_user_mentions_on_snippet_id_and_note_id_index ON snippet_user_mentions USING btree (snippet_id, note_id);
CREATE UNIQUE INDEX snippet_user_mentions_on_snippet_id_index ON snippet_user_mentions USING btree (snippet_id) WHERE (note_id IS NULL);
@@ -28409,8 +29567,12 @@ CREATE INDEX tmp_gitlab_subscriptions_max_seats_used_migration_2 ON gitlab_subsc
CREATE INDEX tmp_idx_vulnerability_occurrences_on_id_where_report_type_7_99 ON vulnerability_occurrences USING btree (id) WHERE (report_type = ANY (ARRAY[7, 99]));
+CREATE INDEX tmp_index_ci_job_artifacts_on_id_where_trace_and_expire_at ON ci_job_artifacts USING btree (id) WHERE ((file_type = 3) AND (expire_at = ANY (ARRAY['2021-04-22 00:00:00+00'::timestamp with time zone, '2021-05-22 00:00:00+00'::timestamp with time zone, '2021-06-22 00:00:00+00'::timestamp with time zone, '2022-01-22 00:00:00+00'::timestamp with time zone, '2022-02-22 00:00:00+00'::timestamp with time zone, '2022-03-22 00:00:00+00'::timestamp with time zone, '2022-04-22 00:00:00+00'::timestamp with time zone])));
+
CREATE INDEX tmp_index_container_repositories_on_id_migration_state ON container_repositories USING btree (id, migration_state);
+CREATE INDEX tmp_index_for_namespace_id_migration_on_group_members ON members USING btree (id) WHERE ((member_namespace_id IS NULL) AND ((type)::text = 'GroupMember'::text));
+
CREATE INDEX tmp_index_for_namespace_id_migration_on_routes ON routes USING btree (id) WHERE ((namespace_id IS NULL) AND ((source_type)::text = 'Namespace'::text));
CREATE INDEX tmp_index_members_on_state ON members USING btree (state) WHERE (state = 2);
@@ -28423,6 +29585,10 @@ CREATE UNIQUE INDEX tmp_index_on_tmp_project_id_on_namespaces ON namespaces USIN
CREATE INDEX tmp_index_on_vulnerabilities_non_dismissed ON vulnerabilities USING btree (id) WHERE (state <> 2);
+CREATE INDEX tmp_index_projects_on_id_and_runners_token ON projects USING btree (id, runners_token) WHERE (runners_token IS NOT NULL);
+
+CREATE INDEX tmp_index_projects_on_id_and_runners_token_encrypted ON projects USING btree (id, runners_token_encrypted) WHERE (runners_token_encrypted IS NOT NULL);
+
CREATE UNIQUE INDEX uniq_pkgs_deb_grp_architectures_on_distribution_id_and_name ON packages_debian_group_architectures USING btree (distribution_id, name);
CREATE UNIQUE INDEX uniq_pkgs_deb_grp_components_on_distribution_id_and_name ON packages_debian_group_components USING btree (distribution_id, name);
@@ -29089,6 +30255,390 @@ ALTER INDEX index_issue_stage_events_project_duration ATTACH PARTITION gitlab_pa
ALTER INDEX index_issue_stage_events_group_in_progress_duration ATTACH PARTITION gitlab_partitions_static.index_ff8741d8d7;
+ALTER INDEX index_issue_search_data_on_issue_id ATTACH PARTITION gitlab_partitions_static.issue_search_data_00_issue_id_idx;
+
+ALTER INDEX issue_search_data_pkey ATTACH PARTITION gitlab_partitions_static.issue_search_data_00_pkey;
+
+ALTER INDEX index_issue_search_data_on_search_vector ATTACH PARTITION gitlab_partitions_static.issue_search_data_00_search_vector_idx;
+
+ALTER INDEX index_issue_search_data_on_issue_id ATTACH PARTITION gitlab_partitions_static.issue_search_data_01_issue_id_idx;
+
+ALTER INDEX issue_search_data_pkey ATTACH PARTITION gitlab_partitions_static.issue_search_data_01_pkey;
+
+ALTER INDEX index_issue_search_data_on_search_vector ATTACH PARTITION gitlab_partitions_static.issue_search_data_01_search_vector_idx;
+
+ALTER INDEX index_issue_search_data_on_issue_id ATTACH PARTITION gitlab_partitions_static.issue_search_data_02_issue_id_idx;
+
+ALTER INDEX issue_search_data_pkey ATTACH PARTITION gitlab_partitions_static.issue_search_data_02_pkey;
+
+ALTER INDEX index_issue_search_data_on_search_vector ATTACH PARTITION gitlab_partitions_static.issue_search_data_02_search_vector_idx;
+
+ALTER INDEX index_issue_search_data_on_issue_id ATTACH PARTITION gitlab_partitions_static.issue_search_data_03_issue_id_idx;
+
+ALTER INDEX issue_search_data_pkey ATTACH PARTITION gitlab_partitions_static.issue_search_data_03_pkey;
+
+ALTER INDEX index_issue_search_data_on_search_vector ATTACH PARTITION gitlab_partitions_static.issue_search_data_03_search_vector_idx;
+
+ALTER INDEX index_issue_search_data_on_issue_id ATTACH PARTITION gitlab_partitions_static.issue_search_data_04_issue_id_idx;
+
+ALTER INDEX issue_search_data_pkey ATTACH PARTITION gitlab_partitions_static.issue_search_data_04_pkey;
+
+ALTER INDEX index_issue_search_data_on_search_vector ATTACH PARTITION gitlab_partitions_static.issue_search_data_04_search_vector_idx;
+
+ALTER INDEX index_issue_search_data_on_issue_id ATTACH PARTITION gitlab_partitions_static.issue_search_data_05_issue_id_idx;
+
+ALTER INDEX issue_search_data_pkey ATTACH PARTITION gitlab_partitions_static.issue_search_data_05_pkey;
+
+ALTER INDEX index_issue_search_data_on_search_vector ATTACH PARTITION gitlab_partitions_static.issue_search_data_05_search_vector_idx;
+
+ALTER INDEX index_issue_search_data_on_issue_id ATTACH PARTITION gitlab_partitions_static.issue_search_data_06_issue_id_idx;
+
+ALTER INDEX issue_search_data_pkey ATTACH PARTITION gitlab_partitions_static.issue_search_data_06_pkey;
+
+ALTER INDEX index_issue_search_data_on_search_vector ATTACH PARTITION gitlab_partitions_static.issue_search_data_06_search_vector_idx;
+
+ALTER INDEX index_issue_search_data_on_issue_id ATTACH PARTITION gitlab_partitions_static.issue_search_data_07_issue_id_idx;
+
+ALTER INDEX issue_search_data_pkey ATTACH PARTITION gitlab_partitions_static.issue_search_data_07_pkey;
+
+ALTER INDEX index_issue_search_data_on_search_vector ATTACH PARTITION gitlab_partitions_static.issue_search_data_07_search_vector_idx;
+
+ALTER INDEX index_issue_search_data_on_issue_id ATTACH PARTITION gitlab_partitions_static.issue_search_data_08_issue_id_idx;
+
+ALTER INDEX issue_search_data_pkey ATTACH PARTITION gitlab_partitions_static.issue_search_data_08_pkey;
+
+ALTER INDEX index_issue_search_data_on_search_vector ATTACH PARTITION gitlab_partitions_static.issue_search_data_08_search_vector_idx;
+
+ALTER INDEX index_issue_search_data_on_issue_id ATTACH PARTITION gitlab_partitions_static.issue_search_data_09_issue_id_idx;
+
+ALTER INDEX issue_search_data_pkey ATTACH PARTITION gitlab_partitions_static.issue_search_data_09_pkey;
+
+ALTER INDEX index_issue_search_data_on_search_vector ATTACH PARTITION gitlab_partitions_static.issue_search_data_09_search_vector_idx;
+
+ALTER INDEX index_issue_search_data_on_issue_id ATTACH PARTITION gitlab_partitions_static.issue_search_data_10_issue_id_idx;
+
+ALTER INDEX issue_search_data_pkey ATTACH PARTITION gitlab_partitions_static.issue_search_data_10_pkey;
+
+ALTER INDEX index_issue_search_data_on_search_vector ATTACH PARTITION gitlab_partitions_static.issue_search_data_10_search_vector_idx;
+
+ALTER INDEX index_issue_search_data_on_issue_id ATTACH PARTITION gitlab_partitions_static.issue_search_data_11_issue_id_idx;
+
+ALTER INDEX issue_search_data_pkey ATTACH PARTITION gitlab_partitions_static.issue_search_data_11_pkey;
+
+ALTER INDEX index_issue_search_data_on_search_vector ATTACH PARTITION gitlab_partitions_static.issue_search_data_11_search_vector_idx;
+
+ALTER INDEX index_issue_search_data_on_issue_id ATTACH PARTITION gitlab_partitions_static.issue_search_data_12_issue_id_idx;
+
+ALTER INDEX issue_search_data_pkey ATTACH PARTITION gitlab_partitions_static.issue_search_data_12_pkey;
+
+ALTER INDEX index_issue_search_data_on_search_vector ATTACH PARTITION gitlab_partitions_static.issue_search_data_12_search_vector_idx;
+
+ALTER INDEX index_issue_search_data_on_issue_id ATTACH PARTITION gitlab_partitions_static.issue_search_data_13_issue_id_idx;
+
+ALTER INDEX issue_search_data_pkey ATTACH PARTITION gitlab_partitions_static.issue_search_data_13_pkey;
+
+ALTER INDEX index_issue_search_data_on_search_vector ATTACH PARTITION gitlab_partitions_static.issue_search_data_13_search_vector_idx;
+
+ALTER INDEX index_issue_search_data_on_issue_id ATTACH PARTITION gitlab_partitions_static.issue_search_data_14_issue_id_idx;
+
+ALTER INDEX issue_search_data_pkey ATTACH PARTITION gitlab_partitions_static.issue_search_data_14_pkey;
+
+ALTER INDEX index_issue_search_data_on_search_vector ATTACH PARTITION gitlab_partitions_static.issue_search_data_14_search_vector_idx;
+
+ALTER INDEX index_issue_search_data_on_issue_id ATTACH PARTITION gitlab_partitions_static.issue_search_data_15_issue_id_idx;
+
+ALTER INDEX issue_search_data_pkey ATTACH PARTITION gitlab_partitions_static.issue_search_data_15_pkey;
+
+ALTER INDEX index_issue_search_data_on_search_vector ATTACH PARTITION gitlab_partitions_static.issue_search_data_15_search_vector_idx;
+
+ALTER INDEX index_issue_search_data_on_issue_id ATTACH PARTITION gitlab_partitions_static.issue_search_data_16_issue_id_idx;
+
+ALTER INDEX issue_search_data_pkey ATTACH PARTITION gitlab_partitions_static.issue_search_data_16_pkey;
+
+ALTER INDEX index_issue_search_data_on_search_vector ATTACH PARTITION gitlab_partitions_static.issue_search_data_16_search_vector_idx;
+
+ALTER INDEX index_issue_search_data_on_issue_id ATTACH PARTITION gitlab_partitions_static.issue_search_data_17_issue_id_idx;
+
+ALTER INDEX issue_search_data_pkey ATTACH PARTITION gitlab_partitions_static.issue_search_data_17_pkey;
+
+ALTER INDEX index_issue_search_data_on_search_vector ATTACH PARTITION gitlab_partitions_static.issue_search_data_17_search_vector_idx;
+
+ALTER INDEX index_issue_search_data_on_issue_id ATTACH PARTITION gitlab_partitions_static.issue_search_data_18_issue_id_idx;
+
+ALTER INDEX issue_search_data_pkey ATTACH PARTITION gitlab_partitions_static.issue_search_data_18_pkey;
+
+ALTER INDEX index_issue_search_data_on_search_vector ATTACH PARTITION gitlab_partitions_static.issue_search_data_18_search_vector_idx;
+
+ALTER INDEX index_issue_search_data_on_issue_id ATTACH PARTITION gitlab_partitions_static.issue_search_data_19_issue_id_idx;
+
+ALTER INDEX issue_search_data_pkey ATTACH PARTITION gitlab_partitions_static.issue_search_data_19_pkey;
+
+ALTER INDEX index_issue_search_data_on_search_vector ATTACH PARTITION gitlab_partitions_static.issue_search_data_19_search_vector_idx;
+
+ALTER INDEX index_issue_search_data_on_issue_id ATTACH PARTITION gitlab_partitions_static.issue_search_data_20_issue_id_idx;
+
+ALTER INDEX issue_search_data_pkey ATTACH PARTITION gitlab_partitions_static.issue_search_data_20_pkey;
+
+ALTER INDEX index_issue_search_data_on_search_vector ATTACH PARTITION gitlab_partitions_static.issue_search_data_20_search_vector_idx;
+
+ALTER INDEX index_issue_search_data_on_issue_id ATTACH PARTITION gitlab_partitions_static.issue_search_data_21_issue_id_idx;
+
+ALTER INDEX issue_search_data_pkey ATTACH PARTITION gitlab_partitions_static.issue_search_data_21_pkey;
+
+ALTER INDEX index_issue_search_data_on_search_vector ATTACH PARTITION gitlab_partitions_static.issue_search_data_21_search_vector_idx;
+
+ALTER INDEX index_issue_search_data_on_issue_id ATTACH PARTITION gitlab_partitions_static.issue_search_data_22_issue_id_idx;
+
+ALTER INDEX issue_search_data_pkey ATTACH PARTITION gitlab_partitions_static.issue_search_data_22_pkey;
+
+ALTER INDEX index_issue_search_data_on_search_vector ATTACH PARTITION gitlab_partitions_static.issue_search_data_22_search_vector_idx;
+
+ALTER INDEX index_issue_search_data_on_issue_id ATTACH PARTITION gitlab_partitions_static.issue_search_data_23_issue_id_idx;
+
+ALTER INDEX issue_search_data_pkey ATTACH PARTITION gitlab_partitions_static.issue_search_data_23_pkey;
+
+ALTER INDEX index_issue_search_data_on_search_vector ATTACH PARTITION gitlab_partitions_static.issue_search_data_23_search_vector_idx;
+
+ALTER INDEX index_issue_search_data_on_issue_id ATTACH PARTITION gitlab_partitions_static.issue_search_data_24_issue_id_idx;
+
+ALTER INDEX issue_search_data_pkey ATTACH PARTITION gitlab_partitions_static.issue_search_data_24_pkey;
+
+ALTER INDEX index_issue_search_data_on_search_vector ATTACH PARTITION gitlab_partitions_static.issue_search_data_24_search_vector_idx;
+
+ALTER INDEX index_issue_search_data_on_issue_id ATTACH PARTITION gitlab_partitions_static.issue_search_data_25_issue_id_idx;
+
+ALTER INDEX issue_search_data_pkey ATTACH PARTITION gitlab_partitions_static.issue_search_data_25_pkey;
+
+ALTER INDEX index_issue_search_data_on_search_vector ATTACH PARTITION gitlab_partitions_static.issue_search_data_25_search_vector_idx;
+
+ALTER INDEX index_issue_search_data_on_issue_id ATTACH PARTITION gitlab_partitions_static.issue_search_data_26_issue_id_idx;
+
+ALTER INDEX issue_search_data_pkey ATTACH PARTITION gitlab_partitions_static.issue_search_data_26_pkey;
+
+ALTER INDEX index_issue_search_data_on_search_vector ATTACH PARTITION gitlab_partitions_static.issue_search_data_26_search_vector_idx;
+
+ALTER INDEX index_issue_search_data_on_issue_id ATTACH PARTITION gitlab_partitions_static.issue_search_data_27_issue_id_idx;
+
+ALTER INDEX issue_search_data_pkey ATTACH PARTITION gitlab_partitions_static.issue_search_data_27_pkey;
+
+ALTER INDEX index_issue_search_data_on_search_vector ATTACH PARTITION gitlab_partitions_static.issue_search_data_27_search_vector_idx;
+
+ALTER INDEX index_issue_search_data_on_issue_id ATTACH PARTITION gitlab_partitions_static.issue_search_data_28_issue_id_idx;
+
+ALTER INDEX issue_search_data_pkey ATTACH PARTITION gitlab_partitions_static.issue_search_data_28_pkey;
+
+ALTER INDEX index_issue_search_data_on_search_vector ATTACH PARTITION gitlab_partitions_static.issue_search_data_28_search_vector_idx;
+
+ALTER INDEX index_issue_search_data_on_issue_id ATTACH PARTITION gitlab_partitions_static.issue_search_data_29_issue_id_idx;
+
+ALTER INDEX issue_search_data_pkey ATTACH PARTITION gitlab_partitions_static.issue_search_data_29_pkey;
+
+ALTER INDEX index_issue_search_data_on_search_vector ATTACH PARTITION gitlab_partitions_static.issue_search_data_29_search_vector_idx;
+
+ALTER INDEX index_issue_search_data_on_issue_id ATTACH PARTITION gitlab_partitions_static.issue_search_data_30_issue_id_idx;
+
+ALTER INDEX issue_search_data_pkey ATTACH PARTITION gitlab_partitions_static.issue_search_data_30_pkey;
+
+ALTER INDEX index_issue_search_data_on_search_vector ATTACH PARTITION gitlab_partitions_static.issue_search_data_30_search_vector_idx;
+
+ALTER INDEX index_issue_search_data_on_issue_id ATTACH PARTITION gitlab_partitions_static.issue_search_data_31_issue_id_idx;
+
+ALTER INDEX issue_search_data_pkey ATTACH PARTITION gitlab_partitions_static.issue_search_data_31_pkey;
+
+ALTER INDEX index_issue_search_data_on_search_vector ATTACH PARTITION gitlab_partitions_static.issue_search_data_31_search_vector_idx;
+
+ALTER INDEX index_issue_search_data_on_issue_id ATTACH PARTITION gitlab_partitions_static.issue_search_data_32_issue_id_idx;
+
+ALTER INDEX issue_search_data_pkey ATTACH PARTITION gitlab_partitions_static.issue_search_data_32_pkey;
+
+ALTER INDEX index_issue_search_data_on_search_vector ATTACH PARTITION gitlab_partitions_static.issue_search_data_32_search_vector_idx;
+
+ALTER INDEX index_issue_search_data_on_issue_id ATTACH PARTITION gitlab_partitions_static.issue_search_data_33_issue_id_idx;
+
+ALTER INDEX issue_search_data_pkey ATTACH PARTITION gitlab_partitions_static.issue_search_data_33_pkey;
+
+ALTER INDEX index_issue_search_data_on_search_vector ATTACH PARTITION gitlab_partitions_static.issue_search_data_33_search_vector_idx;
+
+ALTER INDEX index_issue_search_data_on_issue_id ATTACH PARTITION gitlab_partitions_static.issue_search_data_34_issue_id_idx;
+
+ALTER INDEX issue_search_data_pkey ATTACH PARTITION gitlab_partitions_static.issue_search_data_34_pkey;
+
+ALTER INDEX index_issue_search_data_on_search_vector ATTACH PARTITION gitlab_partitions_static.issue_search_data_34_search_vector_idx;
+
+ALTER INDEX index_issue_search_data_on_issue_id ATTACH PARTITION gitlab_partitions_static.issue_search_data_35_issue_id_idx;
+
+ALTER INDEX issue_search_data_pkey ATTACH PARTITION gitlab_partitions_static.issue_search_data_35_pkey;
+
+ALTER INDEX index_issue_search_data_on_search_vector ATTACH PARTITION gitlab_partitions_static.issue_search_data_35_search_vector_idx;
+
+ALTER INDEX index_issue_search_data_on_issue_id ATTACH PARTITION gitlab_partitions_static.issue_search_data_36_issue_id_idx;
+
+ALTER INDEX issue_search_data_pkey ATTACH PARTITION gitlab_partitions_static.issue_search_data_36_pkey;
+
+ALTER INDEX index_issue_search_data_on_search_vector ATTACH PARTITION gitlab_partitions_static.issue_search_data_36_search_vector_idx;
+
+ALTER INDEX index_issue_search_data_on_issue_id ATTACH PARTITION gitlab_partitions_static.issue_search_data_37_issue_id_idx;
+
+ALTER INDEX issue_search_data_pkey ATTACH PARTITION gitlab_partitions_static.issue_search_data_37_pkey;
+
+ALTER INDEX index_issue_search_data_on_search_vector ATTACH PARTITION gitlab_partitions_static.issue_search_data_37_search_vector_idx;
+
+ALTER INDEX index_issue_search_data_on_issue_id ATTACH PARTITION gitlab_partitions_static.issue_search_data_38_issue_id_idx;
+
+ALTER INDEX issue_search_data_pkey ATTACH PARTITION gitlab_partitions_static.issue_search_data_38_pkey;
+
+ALTER INDEX index_issue_search_data_on_search_vector ATTACH PARTITION gitlab_partitions_static.issue_search_data_38_search_vector_idx;
+
+ALTER INDEX index_issue_search_data_on_issue_id ATTACH PARTITION gitlab_partitions_static.issue_search_data_39_issue_id_idx;
+
+ALTER INDEX issue_search_data_pkey ATTACH PARTITION gitlab_partitions_static.issue_search_data_39_pkey;
+
+ALTER INDEX index_issue_search_data_on_search_vector ATTACH PARTITION gitlab_partitions_static.issue_search_data_39_search_vector_idx;
+
+ALTER INDEX index_issue_search_data_on_issue_id ATTACH PARTITION gitlab_partitions_static.issue_search_data_40_issue_id_idx;
+
+ALTER INDEX issue_search_data_pkey ATTACH PARTITION gitlab_partitions_static.issue_search_data_40_pkey;
+
+ALTER INDEX index_issue_search_data_on_search_vector ATTACH PARTITION gitlab_partitions_static.issue_search_data_40_search_vector_idx;
+
+ALTER INDEX index_issue_search_data_on_issue_id ATTACH PARTITION gitlab_partitions_static.issue_search_data_41_issue_id_idx;
+
+ALTER INDEX issue_search_data_pkey ATTACH PARTITION gitlab_partitions_static.issue_search_data_41_pkey;
+
+ALTER INDEX index_issue_search_data_on_search_vector ATTACH PARTITION gitlab_partitions_static.issue_search_data_41_search_vector_idx;
+
+ALTER INDEX index_issue_search_data_on_issue_id ATTACH PARTITION gitlab_partitions_static.issue_search_data_42_issue_id_idx;
+
+ALTER INDEX issue_search_data_pkey ATTACH PARTITION gitlab_partitions_static.issue_search_data_42_pkey;
+
+ALTER INDEX index_issue_search_data_on_search_vector ATTACH PARTITION gitlab_partitions_static.issue_search_data_42_search_vector_idx;
+
+ALTER INDEX index_issue_search_data_on_issue_id ATTACH PARTITION gitlab_partitions_static.issue_search_data_43_issue_id_idx;
+
+ALTER INDEX issue_search_data_pkey ATTACH PARTITION gitlab_partitions_static.issue_search_data_43_pkey;
+
+ALTER INDEX index_issue_search_data_on_search_vector ATTACH PARTITION gitlab_partitions_static.issue_search_data_43_search_vector_idx;
+
+ALTER INDEX index_issue_search_data_on_issue_id ATTACH PARTITION gitlab_partitions_static.issue_search_data_44_issue_id_idx;
+
+ALTER INDEX issue_search_data_pkey ATTACH PARTITION gitlab_partitions_static.issue_search_data_44_pkey;
+
+ALTER INDEX index_issue_search_data_on_search_vector ATTACH PARTITION gitlab_partitions_static.issue_search_data_44_search_vector_idx;
+
+ALTER INDEX index_issue_search_data_on_issue_id ATTACH PARTITION gitlab_partitions_static.issue_search_data_45_issue_id_idx;
+
+ALTER INDEX issue_search_data_pkey ATTACH PARTITION gitlab_partitions_static.issue_search_data_45_pkey;
+
+ALTER INDEX index_issue_search_data_on_search_vector ATTACH PARTITION gitlab_partitions_static.issue_search_data_45_search_vector_idx;
+
+ALTER INDEX index_issue_search_data_on_issue_id ATTACH PARTITION gitlab_partitions_static.issue_search_data_46_issue_id_idx;
+
+ALTER INDEX issue_search_data_pkey ATTACH PARTITION gitlab_partitions_static.issue_search_data_46_pkey;
+
+ALTER INDEX index_issue_search_data_on_search_vector ATTACH PARTITION gitlab_partitions_static.issue_search_data_46_search_vector_idx;
+
+ALTER INDEX index_issue_search_data_on_issue_id ATTACH PARTITION gitlab_partitions_static.issue_search_data_47_issue_id_idx;
+
+ALTER INDEX issue_search_data_pkey ATTACH PARTITION gitlab_partitions_static.issue_search_data_47_pkey;
+
+ALTER INDEX index_issue_search_data_on_search_vector ATTACH PARTITION gitlab_partitions_static.issue_search_data_47_search_vector_idx;
+
+ALTER INDEX index_issue_search_data_on_issue_id ATTACH PARTITION gitlab_partitions_static.issue_search_data_48_issue_id_idx;
+
+ALTER INDEX issue_search_data_pkey ATTACH PARTITION gitlab_partitions_static.issue_search_data_48_pkey;
+
+ALTER INDEX index_issue_search_data_on_search_vector ATTACH PARTITION gitlab_partitions_static.issue_search_data_48_search_vector_idx;
+
+ALTER INDEX index_issue_search_data_on_issue_id ATTACH PARTITION gitlab_partitions_static.issue_search_data_49_issue_id_idx;
+
+ALTER INDEX issue_search_data_pkey ATTACH PARTITION gitlab_partitions_static.issue_search_data_49_pkey;
+
+ALTER INDEX index_issue_search_data_on_search_vector ATTACH PARTITION gitlab_partitions_static.issue_search_data_49_search_vector_idx;
+
+ALTER INDEX index_issue_search_data_on_issue_id ATTACH PARTITION gitlab_partitions_static.issue_search_data_50_issue_id_idx;
+
+ALTER INDEX issue_search_data_pkey ATTACH PARTITION gitlab_partitions_static.issue_search_data_50_pkey;
+
+ALTER INDEX index_issue_search_data_on_search_vector ATTACH PARTITION gitlab_partitions_static.issue_search_data_50_search_vector_idx;
+
+ALTER INDEX index_issue_search_data_on_issue_id ATTACH PARTITION gitlab_partitions_static.issue_search_data_51_issue_id_idx;
+
+ALTER INDEX issue_search_data_pkey ATTACH PARTITION gitlab_partitions_static.issue_search_data_51_pkey;
+
+ALTER INDEX index_issue_search_data_on_search_vector ATTACH PARTITION gitlab_partitions_static.issue_search_data_51_search_vector_idx;
+
+ALTER INDEX index_issue_search_data_on_issue_id ATTACH PARTITION gitlab_partitions_static.issue_search_data_52_issue_id_idx;
+
+ALTER INDEX issue_search_data_pkey ATTACH PARTITION gitlab_partitions_static.issue_search_data_52_pkey;
+
+ALTER INDEX index_issue_search_data_on_search_vector ATTACH PARTITION gitlab_partitions_static.issue_search_data_52_search_vector_idx;
+
+ALTER INDEX index_issue_search_data_on_issue_id ATTACH PARTITION gitlab_partitions_static.issue_search_data_53_issue_id_idx;
+
+ALTER INDEX issue_search_data_pkey ATTACH PARTITION gitlab_partitions_static.issue_search_data_53_pkey;
+
+ALTER INDEX index_issue_search_data_on_search_vector ATTACH PARTITION gitlab_partitions_static.issue_search_data_53_search_vector_idx;
+
+ALTER INDEX index_issue_search_data_on_issue_id ATTACH PARTITION gitlab_partitions_static.issue_search_data_54_issue_id_idx;
+
+ALTER INDEX issue_search_data_pkey ATTACH PARTITION gitlab_partitions_static.issue_search_data_54_pkey;
+
+ALTER INDEX index_issue_search_data_on_search_vector ATTACH PARTITION gitlab_partitions_static.issue_search_data_54_search_vector_idx;
+
+ALTER INDEX index_issue_search_data_on_issue_id ATTACH PARTITION gitlab_partitions_static.issue_search_data_55_issue_id_idx;
+
+ALTER INDEX issue_search_data_pkey ATTACH PARTITION gitlab_partitions_static.issue_search_data_55_pkey;
+
+ALTER INDEX index_issue_search_data_on_search_vector ATTACH PARTITION gitlab_partitions_static.issue_search_data_55_search_vector_idx;
+
+ALTER INDEX index_issue_search_data_on_issue_id ATTACH PARTITION gitlab_partitions_static.issue_search_data_56_issue_id_idx;
+
+ALTER INDEX issue_search_data_pkey ATTACH PARTITION gitlab_partitions_static.issue_search_data_56_pkey;
+
+ALTER INDEX index_issue_search_data_on_search_vector ATTACH PARTITION gitlab_partitions_static.issue_search_data_56_search_vector_idx;
+
+ALTER INDEX index_issue_search_data_on_issue_id ATTACH PARTITION gitlab_partitions_static.issue_search_data_57_issue_id_idx;
+
+ALTER INDEX issue_search_data_pkey ATTACH PARTITION gitlab_partitions_static.issue_search_data_57_pkey;
+
+ALTER INDEX index_issue_search_data_on_search_vector ATTACH PARTITION gitlab_partitions_static.issue_search_data_57_search_vector_idx;
+
+ALTER INDEX index_issue_search_data_on_issue_id ATTACH PARTITION gitlab_partitions_static.issue_search_data_58_issue_id_idx;
+
+ALTER INDEX issue_search_data_pkey ATTACH PARTITION gitlab_partitions_static.issue_search_data_58_pkey;
+
+ALTER INDEX index_issue_search_data_on_search_vector ATTACH PARTITION gitlab_partitions_static.issue_search_data_58_search_vector_idx;
+
+ALTER INDEX index_issue_search_data_on_issue_id ATTACH PARTITION gitlab_partitions_static.issue_search_data_59_issue_id_idx;
+
+ALTER INDEX issue_search_data_pkey ATTACH PARTITION gitlab_partitions_static.issue_search_data_59_pkey;
+
+ALTER INDEX index_issue_search_data_on_search_vector ATTACH PARTITION gitlab_partitions_static.issue_search_data_59_search_vector_idx;
+
+ALTER INDEX index_issue_search_data_on_issue_id ATTACH PARTITION gitlab_partitions_static.issue_search_data_60_issue_id_idx;
+
+ALTER INDEX issue_search_data_pkey ATTACH PARTITION gitlab_partitions_static.issue_search_data_60_pkey;
+
+ALTER INDEX index_issue_search_data_on_search_vector ATTACH PARTITION gitlab_partitions_static.issue_search_data_60_search_vector_idx;
+
+ALTER INDEX index_issue_search_data_on_issue_id ATTACH PARTITION gitlab_partitions_static.issue_search_data_61_issue_id_idx;
+
+ALTER INDEX issue_search_data_pkey ATTACH PARTITION gitlab_partitions_static.issue_search_data_61_pkey;
+
+ALTER INDEX index_issue_search_data_on_search_vector ATTACH PARTITION gitlab_partitions_static.issue_search_data_61_search_vector_idx;
+
+ALTER INDEX index_issue_search_data_on_issue_id ATTACH PARTITION gitlab_partitions_static.issue_search_data_62_issue_id_idx;
+
+ALTER INDEX issue_search_data_pkey ATTACH PARTITION gitlab_partitions_static.issue_search_data_62_pkey;
+
+ALTER INDEX index_issue_search_data_on_search_vector ATTACH PARTITION gitlab_partitions_static.issue_search_data_62_search_vector_idx;
+
+ALTER INDEX index_issue_search_data_on_issue_id ATTACH PARTITION gitlab_partitions_static.issue_search_data_63_issue_id_idx;
+
+ALTER INDEX issue_search_data_pkey ATTACH PARTITION gitlab_partitions_static.issue_search_data_63_pkey;
+
+ALTER INDEX index_issue_search_data_on_search_vector ATTACH PARTITION gitlab_partitions_static.issue_search_data_63_search_vector_idx;
+
ALTER INDEX index_product_analytics_events_experimental_project_and_time ATTACH PARTITION gitlab_partitions_static.product_analytics_events_expe_project_id_collector_tstamp_idx10;
ALTER INDEX index_product_analytics_events_experimental_project_and_time ATTACH PARTITION gitlab_partitions_static.product_analytics_events_expe_project_id_collector_tstamp_idx11;
@@ -29355,8 +30905,6 @@ CREATE TRIGGER ci_pipelines_loose_fk_trigger AFTER DELETE ON ci_pipelines REFERE
CREATE TRIGGER ci_runners_loose_fk_trigger AFTER DELETE ON ci_runners REFERENCING OLD TABLE AS old_table FOR EACH STATEMENT EXECUTE FUNCTION insert_into_loose_foreign_keys_deleted_records();
-CREATE TRIGGER external_pull_requests_loose_fk_trigger AFTER DELETE ON external_pull_requests REFERENCING OLD TABLE AS old_table FOR EACH STATEMENT EXECUTE FUNCTION insert_into_loose_foreign_keys_deleted_records();
-
CREATE TRIGGER merge_requests_loose_fk_trigger AFTER DELETE ON merge_requests REFERENCING OLD TABLE AS old_table FOR EACH STATEMENT EXECUTE FUNCTION insert_into_loose_foreign_keys_deleted_records();
CREATE TRIGGER namespaces_loose_fk_trigger AFTER DELETE ON namespaces REFERENCING OLD TABLE AS old_table FOR EACH STATEMENT EXECUTE FUNCTION insert_into_loose_foreign_keys_deleted_records();
@@ -29617,6 +31165,9 @@ ALTER TABLE ONLY epics
ALTER TABLE ONLY ci_pipelines
ADD CONSTRAINT fk_3d34ab2e06 FOREIGN KEY (pipeline_schedule_id) REFERENCES ci_pipeline_schedules(id) ON DELETE SET NULL;
+ALTER TABLE ONLY merge_request_reviewers
+ ADD CONSTRAINT fk_3d674b9f23 FOREIGN KEY (updated_state_by_user_id) REFERENCES users(id) ON DELETE SET NULL;
+
ALTER TABLE ONLY ci_pipeline_schedule_variables
ADD CONSTRAINT fk_41c35fda51 FOREIGN KEY (pipeline_schedule_id) REFERENCES ci_pipeline_schedules(id) ON DELETE CASCADE;
@@ -29905,6 +31456,9 @@ ALTER TABLE ONLY bulk_import_entities
ALTER TABLE ONLY users
ADD CONSTRAINT fk_a4b8fefe3e FOREIGN KEY (managing_group_id) REFERENCES namespaces(id) ON DELETE SET NULL;
+ALTER TABLE ONLY security_orchestration_policy_configurations
+ ADD CONSTRAINT fk_a50430b375 FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE;
+
ALTER TABLE ONLY lfs_objects_projects
ADD CONSTRAINT fk_a56e02279c FOREIGN KEY (lfs_object_id) REFERENCES lfs_objects(id) ON DELETE RESTRICT NOT VALID;
@@ -29941,6 +31495,9 @@ ALTER TABLE ONLY merge_request_metrics
ALTER TABLE ONLY dast_profile_schedules
ADD CONSTRAINT fk_aef03d62e5 FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE SET NULL;
+ALTER TABLE ONLY merge_request_assignees
+ ADD CONSTRAINT fk_af036e3261 FOREIGN KEY (updated_state_by_user_id) REFERENCES users(id) ON DELETE SET NULL;
+
ALTER TABLE ONLY analytics_cycle_analytics_group_stages
ADD CONSTRAINT fk_analytics_cycle_analytics_group_stages_group_value_stream_id FOREIGN KEY (group_value_stream_id) REFERENCES analytics_cycle_analytics_group_value_streams(id) ON DELETE CASCADE;
@@ -30301,6 +31858,9 @@ ALTER TABLE ONLY packages_debian_group_distributions
ALTER TABLE ONLY packages_conan_file_metadata
ADD CONSTRAINT fk_rails_0afabd9328 FOREIGN KEY (package_file_id) REFERENCES packages_package_files(id) ON DELETE CASCADE;
+ALTER TABLE ONLY related_epic_links
+ ADD CONSTRAINT fk_rails_0b72027748 FOREIGN KEY (target_id) REFERENCES epics(id) ON DELETE CASCADE;
+
ALTER TABLE ONLY ci_build_pending_states
ADD CONSTRAINT fk_rails_0bbbfeaf9d FOREIGN KEY (build_id) REFERENCES ci_builds(id) ON DELETE CASCADE;
@@ -30367,6 +31927,9 @@ ALTER TABLE ONLY bulk_imports
ALTER TABLE ONLY diff_note_positions
ADD CONSTRAINT fk_rails_13c7212859 FOREIGN KEY (note_id) REFERENCES notes(id) ON DELETE CASCADE;
+ALTER TABLE ONLY analytics_cycle_analytics_aggregations
+ ADD CONSTRAINT fk_rails_13c8374c7a FOREIGN KEY (group_id) REFERENCES namespaces(id) ON DELETE CASCADE;
+
ALTER TABLE ONLY users_security_dashboard_projects
ADD CONSTRAINT fk_rails_150cd5682c FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
@@ -31135,6 +32698,9 @@ ALTER TABLE ONLY list_user_preferences
ALTER TABLE ONLY merge_request_cleanup_schedules
ADD CONSTRAINT fk_rails_92dd0e705c FOREIGN KEY (merge_request_id) REFERENCES merge_requests(id) ON DELETE CASCADE;
+ALTER TABLE ONLY project_build_artifacts_size_refreshes
+ ADD CONSTRAINT fk_rails_936db5fc44 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
+
ALTER TABLE ONLY board_labels
ADD CONSTRAINT fk_rails_9374a16edd FOREIGN KEY (board_id) REFERENCES boards(id) ON DELETE CASCADE;
@@ -31276,6 +32842,9 @@ ALTER TABLE ONLY resource_milestone_events
ALTER TABLE ONLY term_agreements
ADD CONSTRAINT fk_rails_a88721bcdf FOREIGN KEY (term_id) REFERENCES application_setting_terms(id);
+ALTER TABLE ONLY saved_replies
+ ADD CONSTRAINT fk_rails_a8bf5bf111 FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
+
ALTER TABLE ONLY ci_pipeline_artifacts
ADD CONSTRAINT fk_rails_a9e811a466 FOREIGN KEY (pipeline_id) REFERENCES ci_pipelines(id) ON DELETE CASCADE;
@@ -31432,6 +33001,9 @@ ALTER TABLE ONLY group_deploy_keys_groups
ALTER TABLE ONLY merge_request_user_mentions
ADD CONSTRAINT fk_rails_c440b9ea31 FOREIGN KEY (note_id) REFERENCES notes(id) ON DELETE CASCADE;
+ALTER TABLE ONLY related_epic_links
+ ADD CONSTRAINT fk_rails_c464534def FOREIGN KEY (source_id) REFERENCES epics(id) ON DELETE CASCADE;
+
ALTER TABLE ONLY boards_epic_board_recent_visits
ADD CONSTRAINT fk_rails_c4dcba4a3e FOREIGN KEY (group_id) REFERENCES namespaces(id) ON DELETE CASCADE;
@@ -31801,6 +33373,12 @@ ALTER TABLE ONLY timelogs
ALTER TABLE ONLY u2f_registrations
ADD CONSTRAINT fk_u2f_registrations_user_id FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
+ALTER TABLE issue_search_data
+ ADD CONSTRAINT issue_search_data_issue_id_fkey FOREIGN KEY (issue_id) REFERENCES issues(id) ON DELETE CASCADE;
+
+ALTER TABLE issue_search_data
+ ADD CONSTRAINT issue_search_data_project_id_fkey FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
+
ALTER TABLE product_analytics_events_experimental
ADD CONSTRAINT product_analytics_events_experimental_project_id_fkey FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
diff --git a/doc/.vale/gitlab/CurrentStatus.yml b/doc/.vale/gitlab/CurrentStatus.yml
index 16a6995843a..040fd3d8a8f 100644
--- a/doc/.vale/gitlab/CurrentStatus.yml
+++ b/doc/.vale/gitlab/CurrentStatus.yml
@@ -5,9 +5,10 @@
#
# For a list of all options, see https://errata-ai.gitbook.io/vale/getting-started/styles
extends: existence
-message: 'Avoid words like "%s" that promise future changes, because documentation is about the current state of the product.'
+message: 'Avoid words like "%s" when you write about future features. Our documentation is about the current state of the product.'
level: suggestion
ignorecase: true
-link: https://docs.gitlab.com/ee/development/documentation/styleguide/index.html#usage-list
+link: https://docs.gitlab.com/ee/development/documentation/styleguide/#promising-features-in-future-versions
tokens:
- currently
+ - yet
diff --git a/doc/.vale/gitlab/HeadingContent.yml b/doc/.vale/gitlab/HeadingContent.yml
new file mode 100644
index 00000000000..a8dc596f2a2
--- /dev/null
+++ b/doc/.vale/gitlab/HeadingContent.yml
@@ -0,0 +1,18 @@
+---
+# Error: gitlab.HeadingContent
+#
+# Checks for generic, unhelpful subheadings.
+#
+# For a list of all options, see https://errata-ai.gitbook.io/vale/getting-started/styles
+extends: existence
+message: 'Rename the subheading "%s", or re-purpose the content elsewhere.'
+level: warning
+scope: heading
+link: https://docs.gitlab.com/ee/development/documentation/styleguide/#headings-1
+ignorecase: false
+tokens:
+ - How it works
+ - Limitations
+ - Overview
+ - Use cases?
+ - Important notes?
diff --git a/doc/.vale/gitlab/SubstitutionWarning.yml b/doc/.vale/gitlab/SubstitutionWarning.yml
index 7ee32e41ade..84d1bab3cc6 100644
--- a/doc/.vale/gitlab/SubstitutionWarning.yml
+++ b/doc/.vale/gitlab/SubstitutionWarning.yml
@@ -14,11 +14,12 @@ swap:
click: select
code base: codebase
config: configuration
+ deselect: clear
+ deselected: cleared
distro: distribution
file name: filename
filesystem: file system
info: information
- need to: must
repo: repository
timezone: time zone
utilize: use
diff --git a/doc/.vale/gitlab/Substitutions.yml b/doc/.vale/gitlab/Substitutions.yml
index 1cc5a60ac91..a0670d75f18 100644
--- a/doc/.vale/gitlab/Substitutions.yml
+++ b/doc/.vale/gitlab/Substitutions.yml
@@ -13,6 +13,7 @@ ignorecase: true
swap:
codequality: code quality
Customer [Pp]ortal: Customers Portal
+ disallow: prevent
frontmatter: front matter
GitLabber: GitLab team member
GitLabbers: GitLab team members
diff --git a/doc/.vale/gitlab/Uppercase.yml b/doc/.vale/gitlab/Uppercase.yml
index c9021dc862e..f1b06e10fe6 100644
--- a/doc/.vale/gitlab/Uppercase.yml
+++ b/doc/.vale/gitlab/Uppercase.yml
@@ -51,6 +51,7 @@ exceptions:
- EKS
- ELB
- EOL
+ - EWM
- EXIF
- FAQ
- FIDO
@@ -144,6 +145,7 @@ exceptions:
- RSA
- RDS
- RSS
+ - RTC
- RVM
- SAAS
- SAML
@@ -171,6 +173,7 @@ exceptions:
- SSH
- SSL
- SSO
+ - STI
- SVG
- SVN
- TCP
diff --git a/doc/.vale/gitlab/Wordy.yml b/doc/.vale/gitlab/Wordy.yml
index 7818ecbb74a..716fdc6c38d 100644
--- a/doc/.vale/gitlab/Wordy.yml
+++ b/doc/.vale/gitlab/Wordy.yml
@@ -5,9 +5,12 @@
#
# For a list of all options, see https://docs.errata.ai/vale/styles
extends: substitution
-message: 'Be concise: "%s" is less wordy than "%s".'
+message: '%s "%s".'
link: https://docs.gitlab.com/ee/development/documentation/styleguide/word_list.html
level: suggestion
ignorecase: true
swap:
- in order to: to
+ in order to: "Be concise: use 'to' rather than"
+ needs? to: "Rewrite the sentence, or use 'must', instead of"
+ note that: "Be concise: rewrite the sentence to not use"
+ please: "Remove this word from the sentence: "
diff --git a/doc/.vale/gitlab/spelling-exceptions.txt b/doc/.vale/gitlab/spelling-exceptions.txt
index 98254c2259b..6dc0704963b 100644
--- a/doc/.vale/gitlab/spelling-exceptions.txt
+++ b/doc/.vale/gitlab/spelling-exceptions.txt
@@ -229,6 +229,7 @@ Gemfile
Gemnasium
Gemojione
Getter
+getters
Getters
gettext
Git
@@ -576,6 +577,7 @@ sharded
sharding
shfmt
Shibboleth
+Shimo
Shopify
Sidekiq
Silverlight
diff --git a/doc/administration/audit_event_streaming.md b/doc/administration/audit_event_streaming.md
index 3bdc67e5a69..ca59dff7ef4 100644
--- a/doc/administration/audit_event_streaming.md
+++ b/doc/administration/audit_event_streaming.md
@@ -25,6 +25,24 @@ GitLab can stream a single event more than once to the same destination. Use the
WARNING:
Event streaming destinations will receive **all** audit event data, which could include sensitive information. Make sure you trust the destination endpoint.
+### Add event streaming destination using GitLab UI
+
+Users with at least the Owner role of a group can add event streaming destinations for it:
+
+1. On the top bar, select **Menu > Groups** and find your group.
+1. On the left sidebar, select **Security & Compliance > Audit events**
+1. On the main area, select **Streams** tab.
+ - When the destination list is empty, select **Add stream** activate edit mode and add a new destination.
+ - When the destination list is not empty, select **{plus}** under the **Streams** tab to activate edit mode.
+1. Enter the endpoint you wish to add and select **Add**.
+
+Event streaming is enabled if:
+
+- No warning is shown.
+- The added endpoint is displayed in the UI.
+
+### Add event streaming destination using the API
+
To enable event streaming, a group owner must add a new event streaming destination using the `externalAuditEventDestinationCreate` mutation
in the GraphQL API.
@@ -34,8 +52,8 @@ mutation {
errors
externalAuditEventDestination {
destinationUrl
- group {
verificationToken
+ group {
name
}
}
@@ -50,7 +68,17 @@ Event streaming is enabled if:
## List currently enabled streaming destinations
-Group owners can view a list of event streaming destinations at any time using the `externalAuditEventDesinations` query type.
+### List currently enabled streaming destination using GitLab UI
+
+Users with at least the Owner role of a group can list event streaming destinations:
+
+1. On the top bar, select **Menu > Groups** and find your group.
+1. On the left sidebar, select **Security & Compliance > Audit events**
+1. On the main area, select **Streams** tab.
+
+### List currently enabled streaming destinations using the API
+
+Group owners can view a list of event streaming destinations at any time using the `externalAuditEventDestinations` query type.
```graphql
query {
@@ -69,6 +97,45 @@ query {
If the resulting list is empty, then audit event streaming is not enabled for that group.
+## Delete currently enabled streaming destination
+
+Group Owners can delete event streaming destinations at any time using the `deleteAuditEventDestinations` mutation type.
+
+### Delete currently enabled streaming using GitLab UI
+
+Uses with at least the Owner role of a group can delete event streaming destination.
+
+1. On the top bar, select **Menu > Groups** and find your group.
+1. On the left sidebar, select **Security & Compliance > Audit events**
+1. On the main area, select **Streams** tab.
+1. Select **{remove}** at the right side of each item.
+
+The external streaming destination is delete when:
+
+- No warning is shown.
+- The deleted endpoint is not displayed in the UI.
+
+### Delete currently enabled streaming using the API
+
+You can delete an event streaming destination by specifying an ID. Get the required ID by [listing the details](audit_event_streaming.md#list-currently-enabled-streaming-destinations-using-the-api) of event streaming destinations.
+
+```graphql
+
+mutation{
+ externalAuditEventDestinationDestroy(input: { id: destination }) {
+ errors
+ }
+}
+
+```
+
+Destination is deleted if:
+
+- The returned `errors` object is empty.
+- The API responds with `200 OK`.
+
+When the last destination is successfully deleted, event streaming is disabled for the group.
+
## Verify event authenticity
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/345424) in GitLab 14.8.
@@ -78,3 +145,228 @@ token is generated when the event destination is created and cannot be changed.
Each streamed event contains a random alphanumeric identifier for the `X-Gitlab-Event-Streaming-Token` HTTP header that can be verified against
the destination's value when [listing streaming destinations](#list-currently-enabled-streaming-destinations).
+
+## Audit event streaming on Git operations
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/332747) in GitLab 14.9 [with a flag](../administration/feature_flags.md) named `audit_event_streaming_git_operations`. Disabled by default.
+
+FLAG:
+On self-managed GitLab, by default this feature is not available. To make it available, ask an administrator to [enable the feature flag](feature_flags.md) named `audit_event_streaming_git_operations`. On GitLab.com, this feature is not available.
+
+Streaming audit events can be sent when signed-in users push or pull a project's remote Git repositories:
+
+- [Using SSH](../ssh/index.md).
+- Using HTTP or HTTPS.
+- Using the **Download** button (**{download}**) in GitLab UI.
+
+Audit events are not captured for users that are not signed in. For example, when downloading a public project.
+
+To configure streaming audit events for Git operations, see [Add a new event streaming destination](#add-a-new-event-streaming-destination).
+
+### Request headers
+
+Request headers are formatted as follows:
+
+```plaintext
+POST /logs HTTP/1.1
+Host: <DESTINATION_HOST>
+Content-Type: application/x-www-form-urlencoded
+X-Gitlab-Event-Streaming-Token: <DESTINATION_TOKEN>
+```
+
+### Example responses for SSH events
+
+Fetch:
+
+```json
+{
+ "id": 1,
+ "author_id": 1,
+ "entity_id": 29,
+ "entity_type": "Project",
+ "details": {
+ "author_name": "Administrator",
+ "target_id": 29,
+ "target_type": "Project",
+ "target_details": "example-project",
+ "custom_message": {
+ "protocol": "ssh",
+ "action": "git-upload-pack"
+ },
+ "ip_address": "127.0.0.1",
+ "entity_path": "example-group/example-project"
+ },
+ "ip_address": "127.0.0.1",
+ "author_name": "Administrator",
+ "entity_path": "example-group/example-project",
+ "target_details": "example-project",
+ "created_at": "2022-02-23T06:21:05.283Z",
+ "target_type": "Project",
+ "target_id": 29
+}
+```
+
+Push:
+
+```json
+{
+ "id": 1,
+ "author_id": 1,
+ "entity_id": 29,
+ "entity_type": "Project",
+ "details": {
+ "author_name": "Administrator",
+ "target_id": 29,
+ "target_type": "Project",
+ "target_details": "example-project",
+ "custom_message": {
+ "protocol": "ssh",
+ "action": "git-receive-pack"
+ },
+ "ip_address": "127.0.0.1",
+ "entity_path": "example-group/example-project"
+ },
+ "ip_address": "127.0.0.1",
+ "author_name": "Administrator",
+ "entity_path": "example-group/example-project",
+ "target_details": "example-project",
+ "created_at": "2022-02-23T06:23:08.746Z",
+ "target_type": "Project",
+ "target_id": 29
+}
+```
+
+### Example responses for HTTP and HTTPS events
+
+Fetch:
+
+```json
+{
+ "id": 1,
+ "author_id": 1,
+ "entity_id": 29,
+ "entity_type": "Project",
+ "details": {
+ "author_name": "Administrator",
+ "target_id": 29,
+ "target_type": "Project",
+ "target_details": "example-project",
+ "custom_message": {
+ "protocol": "http",
+ "action": "git-upload-pack"
+ },
+ "ip_address": "127.0.0.1",
+ "entity_path": "example-group/example-project"
+ },
+ "ip_address": "127.0.0.1",
+ "author_name": "Administrator",
+ "entity_path": "example-group/example-project",
+ "target_details": "example-project",
+ "created_at": "2022-02-23T06:25:43.938Z",
+ "target_type": "Project",
+ "target_id": 29
+}
+```
+
+Push:
+
+```json
+{
+ "id": 1,
+ "author_id": 1,
+ "entity_id": 29,
+ "entity_type": "Project",
+ "details": {
+ "author_name": "Administrator",
+ "target_id": 29,
+ "target_type": "Project",
+ "target_details": "example-project",
+ "custom_message": {
+ "protocol": "http",
+ "action": "git-receive-pack"
+ },
+ "ip_address": "127.0.0.1",
+ "entity_path": "example-group/example-project"
+ },
+ "ip_address": "127.0.0.1",
+ "author_name": "Administrator",
+ "entity_path": "example-group/example-project",
+ "target_details": "example-project",
+ "created_at": "2022-02-23T06:26:29.294Z",
+ "target_type": "Project",
+ "target_id": 29
+}
+```
+
+### Example responses for events from GitLab UI download button
+
+Fetch:
+
+```json
+{
+ "id": 1,
+ "author_id": 99,
+ "entity_id": 29,
+ "entity_type": "Project",
+ "details": {
+ "custom_message": "Repository Download Started",
+ "author_name": "example_username",
+ "target_id": 29,
+ "target_type": "Project",
+ "target_details": "example-group/example-project",
+ "ip_address": "127.0.0.1",
+ "entity_path": "example-group/example-project"
+ },
+ "ip_address": "127.0.0.1",
+ "author_name": "example_username",
+ "entity_path": "example-group/example-project",
+ "target_details": "example-group/example-project",
+ "created_at": "2022-02-23T06:27:17.873Z",
+ "target_type": "Project",
+ "target_id": 29
+}
+```
+
+## Audit event streaming on merge request approval actions
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/271162) in GitLab 14.9.
+
+Stream audit events that relate to merge approval actions performed within a project.
+
+### Request headers
+
+Request headers are formatted as follows:
+
+```plaintext
+POST /logs HTTP/1.1
+Host: <DESTINATION_HOST>
+Content-Type: application/x-www-form-urlencoded
+X-Gitlab-Event-Streaming-Token: <DESTINATION_TOKEN>
+```
+
+### Example request body
+
+```json
+{
+ "id": 1,
+ "author_id": 1,
+ "entity_id": 6,
+ "entity_type": "Project",
+ "details": {
+ "author_name": "example_username",
+ "target_id": 20,
+ "target_type": "MergeRequest",
+ "target_details": "merge request title",
+ "custom_message": "Approved merge request",
+ "ip_address": "127.0.0.1",
+ "entity_path": "example-group/example-project"
+ },
+ "ip_address": "127.0.0.1",
+ "author_name": "example_username",
+ "entity_path": "example-group/example-project",
+ "target_details": "merge request title",
+ "created_at": "2022-03-09T06:53:11.181Z",
+ "target_type": "MergeRequest",
+ "target_id": 20
+}
+```
diff --git a/doc/administration/audit_events.md b/doc/administration/audit_events.md
index d4902a18cac..955f7a6a830 100644
--- a/doc/administration/audit_events.md
+++ b/doc/administration/audit_events.md
@@ -44,17 +44,22 @@ There are two kinds of events logged:
- Instance events scoped to the whole GitLab instance, used by your Compliance team to
perform formal audits.
+NOTE:
+Some events are recorded and available only as [streaming audit events](audit_event_streaming.md).
+
### Impersonation data
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/536) in GitLab 13.0.
When a user is being [impersonated](../user/admin_area/index.md#user-impersonation), their actions are logged as audit events as usual, with two additional details:
-1. Usual audit events include information about the impersonating administrator. These are visible in their respective Audit Event pages depending on their type (Group/Project/User).
-1. Extra audit events are recorded for the start and stop of the administrator's impersonation session. These are visible in
- the:
+1. Usual audit events include information about the impersonating administrator. These audit events are visible in their
+ respective audit event pages depending on their type (group, project, or user).
+1. Extra audit events are recorded for the start and stop of the administrator's impersonation session. These audit events
+ are visible in the:
- Instance audit events.
- - Group audit events for all groups the user belongs to (GitLab 14.8 and later). This is limited to 20 groups for performance reasons.
+ - Group audit events for all groups the user belongs to (GitLab 14.8 and later). For performance reasons, group audit
+ events are limited to the oldest 20 groups to which you belong.
![audit events](img/impersonated_audit_events_v13_8.png)
@@ -107,6 +112,8 @@ From there, you can see the following actions:
- Compliance framework created, updated, or deleted. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/340649) in GitLab 14.5.
- Event streaming destination created, updated, or deleted. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/344664) in GitLab 14.6.
- Instance administrator started or stopped impersonation of a group member. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/300961) in GitLab 14.8.
+- Group deploy token was successfully created, revoked, or deleted. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/353452) in GitLab 14.9.
+- Failed attempt to create a group deploy token. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/353452) in GitLab 14.9.
Group events can also be accessed via the [Group Audit Events API](../api/audit_events.md#group-audit-events)
@@ -158,6 +165,8 @@ From there, you can see the following actions:
- Allowing force push to protected branch changed ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/338873) in GitLab 14.3)
- Code owner approval requirement on merge requests targeting protected branch changed ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/338873) in GitLab 14.3)
- Users and groups allowed to merge and push to protected branch added or removed ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/338873) in GitLab 14.3)
+- Project deploy token was successfully created, revoked or deleted ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/353451) in GitLab 14.9)
+- Failed attempt to create a project deploy token ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/353451) in GitLab 14.9)
Project events can also be accessed via the [Project Audit Events API](../api/audit_events.md#project-audit-events).
diff --git a/doc/administration/auditor_users.md b/doc/administration/auditor_users.md
index 12e222290e7..7c89f34ce61 100644
--- a/doc/administration/auditor_users.md
+++ b/doc/administration/auditor_users.md
@@ -1,6 +1,6 @@
---
-stage: Enablement
-group: Distribution
+stage: Manage
+group: Authentication and Authorization
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
diff --git a/doc/administration/auth/atlassian.md b/doc/administration/auth/atlassian.md
index 7c6aee2c2da..6be53922a5a 100644
--- a/doc/administration/auth/atlassian.md
+++ b/doc/administration/auth/atlassian.md
@@ -13,14 +13,14 @@ To enable the Atlassian OmniAuth provider for passwordless authentication you mu
1. Go to <https://developer.atlassian.com/console/myapps/> and sign-in with the Atlassian
account to administer the application.
-1. Click **Create a new app**.
-1. Choose an App Name, such as 'GitLab', and click **Create**.
+1. Select **Create a new app**.
+1. Choose an App Name, such as 'GitLab', and select **Create**.
1. Note the `Client ID` and `Secret` for the [GitLab configuration](#gitlab-configuration) steps.
-1. On the left sidebar under **APIS AND FEATURES**, click **OAuth 2.0 (3LO)**.
-1. Enter the GitLab callback URL using the format `https://gitlab.example.com/users/auth/atlassian_oauth2/callback` and click **Save changes**.
-1. Click **+ Add** in the left sidebar under **APIS AND FEATURES**.
-1. Click **Add** for **Jira platform REST API** and then **Configure**.
-1. Click **Add** next to the following scopes:
+1. On the left sidebar under **APIS AND FEATURES**, select **OAuth 2.0 (3LO)**.
+1. Enter the GitLab callback URL using the format `https://gitlab.example.com/users/auth/atlassian_oauth2/callback` and select **Save changes**.
+1. Select **+ Add** in the left sidebar under **APIS AND FEATURES**.
+1. Select **Add** for **Jira platform REST API** and then **Configure**.
+1. Select **Add** next to the following scopes:
- **View Jira issue data**
- **View user profiles**
- **Create and manage issues**
@@ -73,6 +73,6 @@ To enable the Atlassian OmniAuth provider for passwordless authentication you mu
1. Save the configuration file.
1. [Reconfigure](../restart_gitlab.md#omnibus-gitlab-reconfigure) or [restart GitLab](../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 Atlassian icon below the regular sign in form. Click the icon to begin the authentication process.
+On the sign-in page there should now be an Atlassian icon below the regular sign in form. Select the icon to begin the authentication process.
If everything goes right, the user is signed in to GitLab using their Atlassian credentials.
diff --git a/doc/administration/auth/ldap/ldap-troubleshooting.md b/doc/administration/auth/ldap/ldap-troubleshooting.md
index 06fe579e101..b8391bec72f 100644
--- a/doc/administration/auth/ldap/ldap-troubleshooting.md
+++ b/doc/administration/auth/ldap/ldap-troubleshooting.md
@@ -89,14 +89,14 @@ 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#configure-ldap).
-- The [configured `user_filter`](index.md#set-up-ldap-user-filter) blocks access to the user(s).
+- The users don't fall under the [configured `base`](index.md#configure-ldap).
+- The [configured `user_filter`](index.md#set-up-ldap-user-filter) blocks access to the users.
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 sign-in
+#### Users cannot sign-in
A user can have trouble signing in for any number of reasons. To get started,
here are some questions to ask yourself:
@@ -284,7 +284,7 @@ If you don't find a particular user's GitLab email in the output, then that
user hasn't signed in with LDAP yet.
Next, GitLab searches its `identities` table for the existing
-link between this user and the configured LDAP provider(s):
+link between this user and the configured LDAP providers:
```sql
Identity Load (0.9ms) SELECT "identities".* FROM "identities" WHERE "identities"."user_id" = 20 AND (provider LIKE 'ldap%') LIMIT 1
@@ -334,7 +334,7 @@ Gitlab::Auth::Ldap::Person.find_by_uid('<uid>', adapter)
### Group memberships **(PREMIUM SELF)**
-#### Membership(s) not granted
+#### Memberships not granted
Sometimes you may think a particular user should be added to a GitLab group via
LDAP group sync, but for some reason it's not happening. You can check several
@@ -348,7 +348,7 @@ things to debug the situation.
1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Overview > Users**.
1. Search for the user.
- 1. Open the user by clicking their name. Do not click **Edit**.
+ 1. Open the user by selecting their name. Do not select **Edit**.
1. Select the **Identities** tab. There should be an LDAP identity with
an LDAP DN as the 'Identifier'. If not, this user hasn't signed in with
LDAP yet and must do so first.
@@ -558,7 +558,7 @@ aren't blocked or unable to access their accounts.
NOTE:
The following script requires that any new accounts with the new
-email address are removed first. This is because emails have to be unique in GitLab.
+email address are removed first. Email addresses must be unique in GitLab.
Go to the [rails console](#rails-console) and then run:
diff --git a/doc/administration/cicd.md b/doc/administration/cicd.md
index a7bd07d5d38..5e061320c5b 100644
--- a/doc/administration/cicd.md
+++ b/doc/administration/cicd.md
@@ -71,6 +71,27 @@ Plan.default.actual_limits.update!(ci_needs_size_limit: 100)
To disable directed acyclic graphs (DAG), set the limit to `0`.
+## Change maximum scheduled pipeline frequency
+
+[Scheduled pipelines](../ci/pipelines/schedules.md) can be configured with any [cron value](../topics/cron/index.md),
+but they do not always run exactly when scheduled. An internal process, called the
+_pipeline schedule worker_, queues all the scheduled pipelines, but does not
+run continuously. The worker runs on its own schedule, and scheduled pipelines that
+are ready to start are only queued the next time the worker runs. Scheduled pipelines
+can't run more frequently than the worker.
+
+The default frequency of the pipeline schedule worker is `3-59/10 * * * *` (every ten minutes,
+starting with `0:03`, `0:13`, `0:23`, and so on). The default frequency for GitLab.com
+is listed in the [GitLab.com settings](../user/gitlab_com/index.md#gitlab-cicd).
+
+To change the frequency of the pipeline schedule worker:
+
+1. Edit the `gitlab_rails['pipeline_schedule_worker_cron']` value in your instance's `gitlab.rb` file.
+1. [Reconfigure GitLab](restart_gitlab.md#omnibus-gitlab-reconfigure) for the changes to take effect.
+
+For example, to set the maximum frequency of pipelines to twice a day, set `pipeline_schedule_worker_cron`
+to a cron value of `0 */12 * * *` (`00:00` and `12:00` every day).
+
<!-- ## Troubleshooting
Include any troubleshooting steps that you can foresee. If you know beforehand what issues
diff --git a/doc/administration/clusters/kas.md b/doc/administration/clusters/kas.md
index 192b636e246..e5c371b9d40 100644
--- a/doc/administration/clusters/kas.md
+++ b/doc/administration/clusters/kas.md
@@ -4,34 +4,33 @@ group: Configure
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
-# Install the GitLab Agent Server for Kubernetes (KAS) **(FREE SELF)**
+# Install the GitLab agent server for Kubernetes (KAS) **(FREE SELF)**
-> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/3834) in GitLab 13.10, the GitLab Agent Server (KAS) became available on GitLab.com under `wss://kas.gitlab.com`.
+> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/3834) in GitLab 13.10, the GitLab agent server (KAS) became available on GitLab.com at `wss://kas.gitlab.com`.
> - [Moved](https://gitlab.com/groups/gitlab-org/-/epics/6290) from GitLab Premium to GitLab Free in 14.5.
-The GitLab Agent Server for Kubernetes is a GitLab backend service dedicated to
-managing the [GitLab Agent for Kubernetes](../../user/clusters/agent/index.md).
+The agent server is a component you install together with GitLab. It is required to
+manage the [GitLab agent for Kubernetes](https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent).
-The KAS acronym refers to the former name, Kubernetes Agent Server.
+The KAS acronym refers to the former name, `Kubernetes agent server`.
-The KAS is already installed and available in GitLab.com under `wss://kas.gitlab.com`.
-This document describes how to install a KAS for GitLab self-managed instances.
+The agent server for Kubernetes is installed and available on GitLab.com at `wss://kas.gitlab.com`.
+If you use self-managed GitLab, you must install an agent server or specify an external installation.
## Installation options
-As a GitLab administrator of self-managed instances, you can install KAS according to your GitLab
-installation method:
+As a GitLab administrator, you can install the agent server:
-- For [Omnibus installations](#install-kas-with-omnibus).
-- For [GitLab Helm Chart installations](#install-kas-with-the-gitlab-helm-chart).
+- For [Omnibus installations](#for-omnibus).
+- For [GitLab Helm Chart installations](#for-gitlab-helm-chart).
-You can also opt to use an [external KAS](#use-an-external-kas-installation).
+Or, you can [use an external agent server](#use-an-external-installation).
-### Install KAS with Omnibus
+### For Omnibus
For [Omnibus](https://docs.gitlab.com/omnibus/) package installations:
-1. Edit `/etc/gitlab/gitlab.rb` to enable the Agent Server:
+1. To enable the agent server, edit `/etc/gitlab/gitlab.rb`:
```ruby
gitlab_kas['enable'] = true
@@ -39,49 +38,49 @@ For [Omnibus](https://docs.gitlab.com/omnibus/) package installations:
1. [Reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure).
-To configure any additional options related to your KAS,
-refer to the **Enable GitLab KAS** section of the
+For additional configuration options, see the **Enable GitLab KAS** section of the
[`gitlab.rb.template`](https://gitlab.com/gitlab-org/omnibus-gitlab/-/blob/master/files/gitlab-config-template/gitlab.rb.template).
-### Install KAS with the GitLab Helm Chart
+### For GitLab Helm Chart
-For GitLab [Helm Chart](https://docs.gitlab.com/charts/)
-installations, you must set `global.kas.enabled` to `true`.
-For example, in a shell with `helm` and `kubectl`
-installed, run:
+For GitLab [Helm Chart](https://docs.gitlab.com/charts/) installations:
-```shell
-helm repo add gitlab https://charts.gitlab.io/
-helm repo update
-helm upgrade --install gitlab gitlab/gitlab \
- --timeout 600s \
- --set global.hosts.domain=<YOUR_DOMAIN> \
- --set global.hosts.externalIP=<YOUR_IP> \
- --set certmanager-issuer.email=<YOUR_EMAIL> \
- --set global.kas.enabled=true # <-- without this, KAS will not be installed
-```
+1. Set `global.kas.enabled` to `true`. For example, in a shell with `helm` and `kubectl`
+ installed, run:
-To configure KAS, use a `gitlab.kas` sub-section in your `values.yaml` file:
+ ```shell
+ helm repo add gitlab https://charts.gitlab.io/
+ helm repo update
+ helm upgrade --install gitlab gitlab/gitlab \
+ --timeout 600s \
+ --set global.hosts.domain=<YOUR_DOMAIN> \
+ --set global.hosts.externalIP=<YOUR_IP> \
+ --set certmanager-issuer.email=<YOUR_EMAIL> \
+ --set global.kas.enabled=true # <-- without this setting, the agent server will not be installed
+ ```
-```yaml
-gitlab:
- kas:
- # put your KAS custom options here
-```
+1. To configure the agent server, use a `gitlab.kas` sub-section in your `values.yaml` file:
+
+ ```yaml
+ gitlab:
+ kas:
+ # put your custom options here
+ ```
For details, see [how to use the GitLab-KAS chart](https://docs.gitlab.com/charts/charts/gitlab/kas/).
-### Use an external KAS installation
+### Use an external installation
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/299850) in GitLab 13.10.
-Besides installing KAS with GitLab, you can opt to configure GitLab to use an external KAS.
+Instead of installing the agent server, you can configure GitLab to use an external agent server.
-For GitLab instances installed through the GitLab Helm Chart, see [how to configure your external KAS](https://docs.gitlab.com/charts/charts/globals.html#external-kas).
+If you used the GitLab Helm Chart to install GitLab, see
+[how to configure your external agent server](https://docs.gitlab.com/charts/charts/globals.html#external-kas).
-For GitLab instances installed through Omnibus packages:
+If you used the Omnibus packages:
-1. Edit `/etc/gitlab/gitlab.rb` adding the paths to your external KAS:
+1. Edit `/etc/gitlab/gitlab.rb` and add the paths to your external agent server:
```ruby
gitlab_kas['enable'] = false
@@ -96,7 +95,7 @@ For GitLab instances installed through Omnibus packages:
## Troubleshooting
-If you have issues while using the GitLab Agent Server for Kubernetes, view the
+If you have issues while using the agent server for Kubernetes, view the
service logs by running the following command:
```shell
@@ -105,9 +104,9 @@ kubectl logs -f -l=app=kas -n <YOUR-GITLAB-NAMESPACE>
In Omnibus GitLab, find the logs in `/var/log/gitlab/gitlab-kas/`.
-You can also [troubleshoot issues with individual Agents](../../user/clusters/agent/troubleshooting.md).
+You can also [troubleshoot issues with individual agents](../../user/clusters/agent/troubleshooting.md).
-### KAS logs - GitOps: failed to get project information
+### GitOps: failed to get project information
If you get the following error message:
@@ -115,11 +114,11 @@ If you get the following error message:
{"level":"warn","time":"2020-10-30T08:37:26.123Z","msg":"GitOps: failed to get project info","agent_id":4,"project_id":"root/kas-manifest001","error":"error kind: 0; status: 404"}
```
-It means that the specified manifest project `root/kas-manifest001`
-doesn't exist or the manifest project is private. To fix it, make sure the project path is correct
-and its visibility is [set to public](../../public_access/public_access.md).
+The project specified by the manifest (`root/kas-manifest001`)
+doesn't exist or the project where the manifest is kept is private. To fix this issue,
+ensure the project path is correct and that the project's visibility is [set to public](../../public_access/public_access.md).
-### KAS logs - Configuration file not found
+### Configuration file not found
If you get the following error message:
@@ -127,29 +126,29 @@ If you get the following error message:
time="2020-10-29T04:44:14Z" level=warning msg="Config: failed to fetch" agent_id=2 error="configuration file not found: \".gitlab/agents/test-agent/config.yaml\
```
-It means that the path to the configuration project is incorrect,
-or the path to `config.yaml` inside the project is not valid.
+The path is incorrect for either:
+
+- The repository where the agent was registered.
+- The agent configuration file.
-To fix this, ensure that the paths to the configuration repository and to the `config.yaml` file
-are correct.
+To fix this issue, ensure that the paths are correct.
-### KAS logs - `dial tcp <GITLAB_INTERNAL_IP>:443: connect: connection refused`
+### `dial tcp <GITLAB_INTERNAL_IP>:443: connect: connection refused`
-If you are running a self-managed GitLab instance and:
+If you are running self-managed GitLab and:
- The instance isn't running behind an SSL-terminating proxy.
- The instance doesn't have HTTPS configured on the GitLab instance itself.
- The instance's hostname resolves locally to its internal IP address.
-You may see the following error when the KAS tries to connect to the GitLab API:
+When the agent server tries to connect to the GitLab API, the following error might occur:
```json
{"level":"error","time":"2021-08-16T14:56:47.289Z","msg":"GetAgentInfo()","correlation_id":"01FD7QE35RXXXX8R47WZFBAXTN","grpc_service":"gitlab.agent.reverse_tunnel.rpc.ReverseTunnel","grpc_method":"Connect","error":"Get \"https://gitlab.example.com/api/v4/internal/kubernetes/agent_info\": dial tcp 172.17.0.4:443: connect: connection refused"}
```
-To fix this for [Omnibus](https://docs.gitlab.com/omnibus/) package installations,
-set the following parameter in `/etc/gitlab/gitlab.rb`
-(replacing `gitlab.example.com` with your GitLab instance's hostname):
+To fix this issue for [Omnibus](https://docs.gitlab.com/omnibus/) package installations,
+set the following parameter in `/etc/gitlab/gitlab.rb`. Replace `gitlab.example.com` with your GitLab instance's hostname:
```ruby
gitlab_kas['gitlab_address'] = 'http://gitlab.example.com'
diff --git a/doc/administration/database_load_balancing.md b/doc/administration/database_load_balancing.md
deleted file mode 100644
index 92b8342f251..00000000000
--- a/doc/administration/database_load_balancing.md
+++ /dev/null
@@ -1,9 +0,0 @@
----
-redirect_to: 'postgresql/database_load_balancing.md'
-remove_date: '2022-02-19'
----
-
-This file was moved to [another location](postgresql/database_load_balancing.md).
-
-<!-- This redirect file can be deleted after <2022-02-19>. -->
-<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/#move-or-rename-a-page -->
diff --git a/doc/administration/docs_self_host.md b/doc/administration/docs_self_host.md
index 3a4511e5aa4..8464c35c3bb 100644
--- a/doc/administration/docs_self_host.md
+++ b/doc/administration/docs_self_host.md
@@ -18,7 +18,7 @@ To host the GitLab product documentation, you can use:
- Your own web server
After you create a website by using one of these methods, you redirect the UI links
-in the product to point to your website.
+in the product to point to your website.
NOTE:
The website you create must be hosted under a subdirectory that matches
diff --git a/doc/administration/encrypted_configuration.md b/doc/administration/encrypted_configuration.md
index 9224def4a5a..baa6e967507 100644
--- a/doc/administration/encrypted_configuration.md
+++ b/doc/administration/encrypted_configuration.md
@@ -1,7 +1,7 @@
---
stage: Enablement
group: Distribution
-info: "To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers"
+info: "To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments"
type: reference
---
diff --git a/doc/administration/feature_flags.md b/doc/administration/feature_flags.md
index 85a7304b5e8..aebd6eb1d4c 100644
--- a/doc/administration/feature_flags.md
+++ b/doc/administration/feature_flags.md
@@ -26,7 +26,7 @@ Features behind flags can be gradually rolled out, typically:
1. The feature becomes enabled by default.
1. The feature flag is removed.
-These features can be enabled and disabled to allow or disallow users to use
+These features can be enabled and disabled to allow or prevent users from using
them. It can be done by GitLab administrators with access to GitLab Rails
console.
diff --git a/doc/administration/geo/disaster_recovery/index.md b/doc/administration/geo/disaster_recovery/index.md
index f7367ef863b..1725c283396 100644
--- a/doc/administration/geo/disaster_recovery/index.md
+++ b/doc/administration/geo/disaster_recovery/index.md
@@ -10,7 +10,7 @@ Geo replicates your database, your Git repositories, and few other assets,
but there are some [limitations](../index.md#limitations).
WARNING:
-Disaster recovery for multi-secondary configurations is in **Alpha**.
+Disaster recovery for multi-secondary configurations is in [**Alpha**](../../../policy/alpha-beta-support.md#alpha-features).
For the latest updates, check the [Disaster Recovery epic for complete maturity](https://gitlab.com/groups/gitlab-org/-/epics/3574).
Multi-secondary configurations require the complete re-synchronization and re-configuration of all non-promoted secondaries and
causes downtime.
diff --git a/doc/administration/geo/disaster_recovery/runbooks/planned_failover_multi_node.md b/doc/administration/geo/disaster_recovery/runbooks/planned_failover_multi_node.md
index b207be47aa1..9b3e0ecb427 100644
--- a/doc/administration/geo/disaster_recovery/runbooks/planned_failover_multi_node.md
+++ b/doc/administration/geo/disaster_recovery/runbooks/planned_failover_multi_node.md
@@ -6,7 +6,7 @@ type: howto
---
WARNING:
-This runbook is in **alpha**. For complete, production-ready documentation, see the
+This runbook is in [**Alpha**](../../../../policy/alpha-beta-support.md#alpha-features). For complete, production-ready documentation, see the
[disaster recovery documentation](../index.md).
# Disaster Recovery (Geo) promotion runbooks **(PREMIUM SELF)**
diff --git a/doc/administration/geo/disaster_recovery/runbooks/planned_failover_single_node.md b/doc/administration/geo/disaster_recovery/runbooks/planned_failover_single_node.md
index 5a6f9eb8be7..fa30b11fe32 100644
--- a/doc/administration/geo/disaster_recovery/runbooks/planned_failover_single_node.md
+++ b/doc/administration/geo/disaster_recovery/runbooks/planned_failover_single_node.md
@@ -6,7 +6,7 @@ type: howto
---
WARNING:
-This runbook is in **alpha**. For complete, production-ready documentation, see the
+This runbook is in [**Alpha**](../../../../policy/alpha-beta-support.md#alpha-features). For complete, production-ready documentation, see the
[disaster recovery documentation](../index.md).
# Disaster Recovery (Geo) promotion runbooks **(PREMIUM SELF)**
diff --git a/doc/administration/geo/index.md b/doc/administration/geo/index.md
index c4164284e97..1b80e91c9c4 100644
--- a/doc/administration/geo/index.md
+++ b/doc/administration/geo/index.md
@@ -23,7 +23,7 @@ to clone and fetch large repositories, speeding up development.
For a video introduction to Geo, see [Introduction to GitLab Geo - GitLab Features](https://www.youtube.com/watch?v=-HDLxSjEh6w).
-To make sure you're using the right version of the documentation, navigate to [the Geo page on GitLab.com](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/administration/geo/index.md) and choose the appropriate release from the **Switch branch/tag** dropdown. For example, [`v13.7.6-ee`](https://gitlab.com/gitlab-org/gitlab/-/blob/v13.7.6-ee/doc/administration/geo/index.md).
+To make sure you're using the right version of the documentation, go to [the Geo page on GitLab.com](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/administration/geo/index.md) and choose the appropriate release from the **Switch branch/tag** dropdown list. For example, [`v13.7.6-ee`](https://gitlab.com/gitlab-org/gitlab/-/blob/v13.7.6-ee/doc/administration/geo/index.md).
Geo uses a set of defined terms that are described in the [Geo Glossary](glossary.md).
Be sure to familiarize yourself with those terms.
@@ -148,14 +148,14 @@ NOTE:
When using HTTP or HTTPS proxying, your load balancer must be configured to pass through the `Connection` and `Upgrade` hop-by-hop headers. See the [web terminal](../integration/terminal.md) integration guide for more details.
NOTE:
-When using HTTPS protocol for port 443, you need to add an SSL certificate to the load balancers.
+When using HTTPS protocol for port 443, you must add an SSL certificate to the load balancers.
If you wish to terminate SSL at the GitLab application server instead, use TCP protocol.
#### Internal URL
HTTP requests from any Geo secondary site to the primary Geo site use the Internal URL of the primary
Geo site. If this is not explicitly defined in the primary Geo site settings in the Admin Area, the
-public URL of the primary site will be used.
+public URL of the primary site is used.
To update the internal URL of the primary Geo site:
@@ -187,7 +187,7 @@ Because the replicated database instance is read-only, we need this additional d
This daemon:
- Reads a log of events replicated by the **primary** site to the **secondary** database instance.
-- Updates the Geo Tracking Database instance with changes that need to be executed.
+- Updates the Geo Tracking Database instance with changes that must be executed.
When something is marked to be updated in the tracking database instance, asynchronous jobs running on the **secondary** site execute the required operations and update the state.
@@ -198,9 +198,9 @@ This new architecture allows GitLab to be resilient to connectivity issues betwe
WARNING:
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** site redirects (for HTTP) or proxies (for SSH) the request to the **primary** site 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** site redirects (for HTTP) or proxies (for SSH) the request to the **primary** site instead of [handling it directly](https://gitlab.com/gitlab-org/gitlab/-/issues/1381), except when using Git over HTTP with credentials embedded in the URI. For example, `https://user:password@secondary.tld`.
- The **primary** site has to be online for OAuth login to happen. Existing sessions and Git are not affected. Support for the **secondary** site 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 installation takes multiple manual steps that together can take about an hour depending on circumstances. Consider using [the GitLab Environment Toolkit](https://gitlab.com/gitlab-org/gitlab-environment-toolkit) to deploy and operate production GitLab instances based on our [Reference Architectures](../reference_architectures/index.md), including automation of common daily tasks. We are planning to [improve Geo's installation even further](https://gitlab.com/groups/gitlab-org/-/epics/1465).
- Real-time updates of issues/merge requests (for example, via long polling) doesn't work on the **secondary** site.
- GitLab Runners cannot register with a **secondary** site. Support for this is [planned for the future](https://gitlab.com/gitlab-org/gitlab/-/issues/3294).
- [Selective synchronization](replication/configuration.md#selective-synchronization) only limits what repositories and files are replicated. The entire PostgreSQL data is still replicated. Selective synchronization is not built to accommodate compliance / export control use cases.
@@ -210,13 +210,25 @@ This list of limitations only reflects the latest version of GitLab. If you are
There is a complete list of all GitLab [data types](replication/datatypes.md) and [existing support for replication and verification](replication/datatypes.md#limitations-on-replicationverification).
+### View replication data on the primary site
+
+If you try to view replication data on the primary site, you receive a warning that this may be inconsistent:
+
+> Viewing projects and designs data from a primary site is not possible when using a unified URL. Visit the secondary site directly.
+
+The only way to view projects replication data for a particular secondary site is to visit that secondary site directly. For example, `https://<IP of your secondary site>/admin/geo/replication/projects`.
+An [epic exists](https://gitlab.com/groups/gitlab-org/-/epics/4623) to fix this limitation.
+
+The only way to view designs replication data for a particular secondary site is to visit that secondary site directly. For example, `https://<IP of your secondary site>/admin/geo/replication/designs`.
+An [epic exists](https://gitlab.com/groups/gitlab-org/-/epics/4624) to fix this limitation.
+
## Setup instructions
For setup instructions, see [Setting up Geo](setup/index.md).
## Post-installation documentation
-After installing GitLab on the **secondary** site(s) and performing the initial configuration, see the following documentation for post-installation information.
+After installing GitLab on the **secondary** sites and performing the initial configuration, see the following documentation for post-installation information.
### Configuring Geo
@@ -224,7 +236,7 @@ For information on configuring Geo, see [Geo configuration](replication/configur
### Updating Geo
-For information on how to update your Geo site(s) to the latest GitLab version, see [Updating the Geo sites](replication/updating_the_geo_sites.md).
+For information on how to update your Geo sites to the latest GitLab version, see [Updating the Geo sites](replication/updating_the_geo_sites.md).
### Pausing and resuming replication
@@ -237,8 +249,8 @@ secondary. If the site is paused, be sure to resume before promoting. This
issue has been fixed in GitLab 13.4 and later.
WARNING:
-Pausing and resuming of replication is currently only supported for Geo installations using an
-Omnibus GitLab-managed database. External databases are currently not supported.
+Pausing and resuming of replication is only supported for Geo installations using an
+Omnibus GitLab-managed database. External databases are not supported.
In some circumstances, like during [upgrades](replication/updating_the_geo_sites.md) or a [planned failover](disaster_recovery/planned_failover.md), it is desirable to pause replication between the primary and secondary.
diff --git a/doc/administration/geo/replication/object_storage.md b/doc/administration/geo/replication/object_storage.md
index 3a10d3bad58..06f25fa15af 100644
--- a/doc/administration/geo/replication/object_storage.md
+++ b/doc/administration/geo/replication/object_storage.md
@@ -35,7 +35,7 @@ To have:
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/10586) in GitLab 12.4.
WARNING:
-This is a [**beta** feature](https://about.gitlab.com/handbook/product/#beta) and is not ready yet for production use at any scale. The main limitations are a lack of testing at scale and no verification of any replicated data.
+This is a [**Beta** feature](../../../policy/alpha-beta-support.md#beta-features) and is not ready yet for production use at any scale. The main limitations are a lack of testing at scale and no verification of any replicated data.
**Secondary** sites can replicate files stored on the **primary** site regardless of
whether they are stored on the local file system or in object storage.
diff --git a/doc/administration/geo/replication/troubleshooting.md b/doc/administration/geo/replication/troubleshooting.md
index 1371e5d84c8..8f55ce99787 100644
--- a/doc/administration/geo/replication/troubleshooting.md
+++ b/doc/administration/geo/replication/troubleshooting.md
@@ -268,7 +268,7 @@ sudo gitlab-rake gitlab:geo:check
GitLab Geo is available ... no
Try fixing it:
- Upload a new license that includes the GitLab Geo feature
+ Add a new license that includes the GitLab Geo feature
For more information see:
https://about.gitlab.com/features/gitlab-geo/
GitLab Geo is enabled ... Exception: PG::UndefinedTable: ERROR: relation "geo_nodes" does not exist
@@ -1043,6 +1043,25 @@ To resolve this issue:
the **primary** node using IPv4 in the `/etc/hosts` file. Alternatively, you should
[enable IPv6 on the **primary** node](https://docs.gitlab.com/omnibus/settings/nginx.html#setting-the-nginx-listen-address-or-addresses).
+### Secondary site returns 502 errors with Geo proxying
+
+When [Geo proxying for secondary sites](../secondary_proxy/index.md) is enabled, and the secondary site user interface returns
+502 errors, it is possible that the response header proxied from the primary site is too large.
+
+Check the NGINX logs for errors similar to this example:
+
+```plaintext
+2022/01/26 00:02:13 [error] 26641#0: *829148 upstream sent too big header while reading response header from upstream, client: 1.2.3.4, server: geo.staging.gitlab.com, request: "POST /users/sign_in HTTP/2.0", upstream: "http://unix:/var/opt/gitlab/gitlab-workhorse/sockets/socket:/users/sign_in", host: "geo.staging.gitlab.com", referrer: "https://geo.staging.gitlab.com/users/sign_in"
+```
+
+To resolve this issue:
+
+1. Set `nginx['proxy_custom_buffer_size'] = '8k'` in `/etc/gitlab.rb` on all web nodes on the secondary site.
+1. Reconfigure the **secondary** using `sudo gitlab-ctl reconfigure`.
+
+If you still get this error, you can further increase the buffer size by repeating the steps above
+and changing the `8k` size, for example by doubling it to `16k`.
+
### Geo Admin Area shows 'Unknown' for health status and 'Request failed with status code 401'
If using a load balancer, ensure that the load balancer's URL is set as the `external_url` in the
diff --git a/doc/administration/geo/replication/using_a_geo_server.md b/doc/administration/geo/replication/using_a_geo_server.md
deleted file mode 100644
index 62562a1149d..00000000000
--- a/doc/administration/geo/replication/using_a_geo_server.md
+++ /dev/null
@@ -1,9 +0,0 @@
----
-redirect_to: '../../geo/replication/usage.md'
-remove_date: '2022-02-01'
----
-
-This document was moved to [another location](../../geo/replication/usage.md).
-
-<!-- This redirect file can be deleted after 2022-02-01 -->
-<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/#move-or-rename-a-page -->
diff --git a/doc/administration/geo/secondary_proxy/index.md b/doc/administration/geo/secondary_proxy/index.md
index c8dcbb81312..768adab9101 100644
--- a/doc/administration/geo/secondary_proxy/index.md
+++ b/doc/administration/geo/secondary_proxy/index.md
@@ -140,6 +140,8 @@ for details.
To use TLS certificates with Let's Encrypt, you can manually point the domain to one of the Geo sites, generate
the certificate, then copy it to all other sites.
+- [Viewing projects and designs data from a primary site is not possible when using a unified URL](../index.md#view-replication-data-on-the-primary-site).
+
## Behavior of secondary sites when the primary Geo site is down
Considering that web traffic is proxied to the primary, the behavior of the secondary sites differs when the primary
diff --git a/doc/administration/geo/setup/database.md b/doc/administration/geo/setup/database.md
index a8bebef8f44..9c917be123e 100644
--- a/doc/administration/geo/setup/database.md
+++ b/doc/administration/geo/setup/database.md
@@ -192,7 +192,7 @@ There is an [issue where support is being discussed](https://gitlab.com/gitlab-o
for more details.
NOTE:
- If you need to use `0.0.0.0` or `*` as the listen_address, you also need to add
+ If you need to use `0.0.0.0` or `*` as the listen_address, you also must add
`127.0.0.1/32` to the `postgresql['md5_auth_cidr_addresses']` setting, to allow Rails to connect through
`127.0.0.1`. For more information, see [omnibus-5258](https://gitlab.com/gitlab-org/omnibus-gitlab/-/issues/5258).
@@ -378,7 +378,7 @@ There is an [issue where support is being discussed](https://gitlab.com/gitlab-o
1. Configure PostgreSQL:
This step is similar to how we configured the **primary** instance.
- We need to enable this, even if using a single node.
+ We must enable this, even if using a single node.
Edit `/etc/gitlab/gitlab.rb` and add the following, replacing the IP
addresses with addresses appropriate to your network configuration:
@@ -407,7 +407,7 @@ There is an [issue where support is being discussed](https://gitlab.com/gitlab-o
```
For external PostgreSQL instances, see [additional instructions](external_database.md).
- If you bring a former **primary** node back online to serve as a **secondary** node, then you also need to remove `roles(['geo_primary_role'])` or `geo_primary_role['enable'] = true`.
+ If you bring a former **primary** node back online to serve as a **secondary** node, then you also must remove `roles(['geo_primary_role'])` or `geo_primary_role['enable'] = true`.
1. Reconfigure GitLab for the changes to take effect:
@@ -472,7 +472,7 @@ data before running `pg_basebackup`.
initial replication to take under an hour.
- Pass `--sslmode=disable` to skip PostgreSQL TLS authentication altogether
(for example, you know the network path is secure, or you are using a site-to-site
- VPN). This is **not** safe over the public Internet!
+ VPN). It is **not** safe over the public Internet!
- You can read more details about each `sslmode` in the
[PostgreSQL documentation](https://www.postgresql.org/docs/12/libpq-ssl.html#LIBPQ-SSL-PROTECTION);
the instructions above are carefully written to ensure protection against
@@ -480,7 +480,7 @@ data before running `pg_basebackup`.
- Change the `--slot-name` to the name of the replication slot
to be used on the **primary** database. The script attempts to create the
replication slot automatically if it does not exist.
- - If you're repurposing an old server into a Geo **secondary** node, you need to
+ - If you're repurposing an old server into a Geo **secondary** node, you must
add `--force` to the command line.
- When not in a production machine you can disable backup step if you
really sure this is what you want by adding `--skip-backup`
@@ -547,7 +547,7 @@ FATAL: could not connect to the primary server: FATAL: password authentication
On all GitLab Geo **secondary** servers:
-1. The first step isn't necessary from a configuration perspective, since the hashed `'sql_replication_password'`
+1. The first step isn't necessary from a configuration perspective, because the hashed `'sql_replication_password'`
is not used on the GitLab Geo **secondary**. However in the event that **secondary** needs to be promoted
to the GitLab Geo **primary**, make sure to match the `'sql_replication_password'` in the secondary
server configuration.
@@ -612,7 +612,7 @@ and other database best practices.
##### Step 1. Configure Patroni permanent replication slot on the primary site
-To set up database replication with Patroni on a secondary node, we need to
+To set up database replication with Patroni on a secondary node, we must
configure a _permanent replication slot_ on the primary node's Patroni cluster,
and ensure password authentication is used.
@@ -678,7 +678,7 @@ Leader instance**:
##### Step 2. Configure the internal load balancer on the primary site
To avoid reconfiguring the Standby Leader on the secondary site whenever a new
-Leader is elected on the primary site, we need to set up a TCP internal load
+Leader is elected on the primary site, we must set up a TCP internal load
balancer which gives a single endpoint for connecting to the Patroni
cluster's Leader.
@@ -860,7 +860,7 @@ For each Patroni instance on the secondary site:
### Migrating from repmgr to Patroni
-1. Before migrating, it is recommended that there is no replication lag between the primary and secondary sites and that replication is paused. In GitLab 13.2 and later, you can pause and resume replication with `gitlab-ctl geo-replication-pause` and `gitlab-ctl geo-replication-resume` on a Geo secondary database node.
+1. Before migrating, we recommend that there is no replication lag between the primary and secondary sites and that replication is paused. In GitLab 13.2 and later, you can pause and resume replication with `gitlab-ctl geo-replication-pause` and `gitlab-ctl geo-replication-resume` on a Geo secondary database node.
1. Follow the [instructions to migrate repmgr to Patroni](../../postgresql/replication_and_failover.md#switching-from-repmgr-to-patroni). When configuring Patroni on each primary site database node, add `patroni['replication_slots'] = { '<slot_name>' => 'physical' }`
to `gitlab.rb` where `<slot_name>` is the name of the replication slot for your Geo secondary. This ensures that Patroni recognizes the replication slot as permanent and not drop it upon restarting.
1. If database replication to the secondary was paused before migration, resume replication once Patroni is confirmed working on the primary.
@@ -869,7 +869,7 @@ to `gitlab.rb` where `<slot_name>` is the name of the replication slot for your
Before the introduction of Patroni, Geo had no Omnibus support for HA setups on the secondary node.
-With Patroni it's now possible to support that. In order to migrate the existing PostgreSQL to Patroni:
+With Patroni it's now possible to support that. To migrate the existing PostgreSQL to Patroni:
1. Make sure you have a Consul cluster setup on the secondary (similar to how you set it up on the primary).
1. [Configure a permanent replication slot](#step-1-configure-patroni-permanent-replication-slot-on-the-primary-site).
@@ -894,7 +894,7 @@ A production-ready and secure setup requires at least three Consul nodes, two
Patroni nodes and one PgBouncer node on the secondary site.
Because of [omnibus-6587](https://gitlab.com/gitlab-org/omnibus-gitlab/-/issues/6587), Consul can't track multiple
-services, so these need to be different than the nodes used for the Standby Cluster database.
+services, so these must be different than the nodes used for the Standby Cluster database.
Be sure to use [password credentials](../../postgresql/replication_and_failover.md#database-authorization-for-patroni)
and other database best practices.
@@ -1037,7 +1037,7 @@ For each node running the `gitlab-rails`, `sidekiq`, and `geo-logcursor` service
sudo -i
```
-1. Edit `/etc/gitlab/gitlab.rb` and add the following attributes. You may have other attributes set, but the following need to be set.
+1. Edit `/etc/gitlab/gitlab.rb` and add the following attributes. You may have other attributes set, but the following must be set.
```ruby
# Tracking database settings
diff --git a/doc/administration/geo/setup/index.md b/doc/administration/geo/setup/index.md
index 7d365f73101..04a341aa822 100644
--- a/doc/administration/geo/setup/index.md
+++ b/doc/administration/geo/setup/index.md
@@ -10,7 +10,7 @@ type: howto
These instructions assume you have a working instance of GitLab. They guide you through:
1. Making your existing instance the **primary** site.
-1. Adding **secondary** site(s).
+1. Adding **secondary** sites.
WARNING:
The steps below should be followed in the order they appear. **Make sure the GitLab version is the same on all sites.**
@@ -19,15 +19,15 @@ The steps below should be followed in the order they appear. **Make sure the Git
If you installed GitLab using the Omnibus packages (highly recommended):
-1. [Install GitLab Enterprise Edition](https://about.gitlab.com/install/) on the node(s) that will serve as the **secondary** site. Do not create an account or log in to the new **secondary** site.
-1. [Upload the GitLab License](../../../user/admin_area/license.md) on the **primary** site to unlock Geo. The license must be for [GitLab Premium](https://about.gitlab.com/pricing/) or higher.
+1. [Install GitLab Enterprise Edition](https://about.gitlab.com/install/) on the nodes that will serve as the **secondary** site. Do not create an account or log in to the new **secondary** site.
+1. [Add the GitLab License](../../../user/admin_area/license.md) on the **primary** site to unlock Geo. The license must be for [GitLab Premium](https://about.gitlab.com/pricing/) or higher.
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** site(s).
-1. [Configure GitLab](../replication/configuration.md) to set the **primary** and **secondary** site(s).
-1. Optional: [Configure a secondary LDAP server](../../auth/ldap/index.md) for the **secondary** site(s). See [notes on LDAP](../index.md#ldap).
+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** sites.
+1. [Configure GitLab](../replication/configuration.md) to set the **primary** and **secondary** sites.
+1. Optional: [Configure a secondary LDAP server](../../auth/ldap/index.md) for the **secondary** sites. See [notes on LDAP](../index.md#ldap).
1. Follow the [Using a Geo Site](../replication/usage.md) guide.
1. [Configure Geo secondary proxying](../secondary_proxy/index.md) to use a single, unified URL for all Geo sites. This step is recommended to accelerate most read requests while transparently proxying writes to the primary Geo site.
## Post-installation documentation
-After installing GitLab on the **secondary** site(s) and performing the initial configuration, see the [following documentation for post-installation information](../index.md#post-installation-documentation).
+After installing GitLab on the **secondary** sites and performing the initial configuration, see the [following documentation for post-installation information](../index.md#post-installation-documentation).
diff --git a/doc/administration/get_started.md b/doc/administration/get_started.md
index f3b4400c8c3..e6a2e833af3 100644
--- a/doc/administration/get_started.md
+++ b/doc/administration/get_started.md
@@ -39,8 +39,8 @@ Get started:
- Create a [project](../user/project/working_with_projects.md#create-a-project).
- Create a [group](../user/group/index.md#create-a-group).
- [Add members](../user/group/index.md#add-users-to-a-group) to the group.
-- Create a [subgroup](../user/group/subgroups/index.md#creating-a-subgroup).
-- [Add members](../user/group/subgroups/index.md#membership) to the subgroup.
+- Create a [subgroup](../user/group/subgroups/index.md#create-a-subgroup).
+- [Add members](../user/group/subgroups/index.md#subgroup-membership) to the subgroup.
- Enable [external authorization control](../user/admin_area/settings/external_authorization.md#configuration).
**More resources**
@@ -49,7 +49,7 @@ Get started:
- Sync group memberships [by using LDAP](../administration/auth/ldap/ldap_synchronization.md#group-sync).
- Manage user access with inherited permissions. Use up to 20 levels of subgroups to organize both teams and projects.
- Learn more about [inherited permissions](../user/project/members/index.md#inherited-membership).
- - View [nested category examples](../user/group/subgroups/index.md#overview).
+ - View an [example](../user/group/subgroups/index.md).
## Import projects
diff --git a/doc/administration/gitaly/index.md b/doc/administration/gitaly/index.md
index ea24e901943..f88a1aa2b4d 100644
--- a/doc/administration/gitaly/index.md
+++ b/doc/administration/gitaly/index.md
@@ -13,7 +13,7 @@ It is used by GitLab to read and write Git data.
Gitaly is present in every GitLab installation and coordinates Git repository
storage and retrieval. Gitaly can be:
-- A simple background service operating on a single instance Omnibus GitLab (all of
+- A background service operating on a single instance Omnibus GitLab (all of
GitLab on one machine).
- Separated onto its own instance and configured in a full cluster configuration,
depending on scaling and availability requirements.
@@ -71,7 +71,7 @@ the current status of these issues, please refer to the referenced issues and ep
| Gitaly Cluster + Geo - Issues retrying failed syncs | If Gitaly Cluster is used on a Geo secondary site, repositories that have failed to sync could continue to fail when Geo tries to resync them. Recovering from this state requires assistance from support to run manual steps. Work is in-progress to update Gitaly Cluster to [identify repositories with a unique and persistent identifier](https://gitlab.com/gitlab-org/gitaly/-/issues/3485), which is expected to resolve the issue. | No known solution at this time. |
| Database inconsistencies due to repository access outside of Gitaly Cluster's control | Operations that write to the repository storage that do not go through normal Gitaly Cluster methods can cause database inconsistencies. These can include (but are not limited to) snapshot restoration for cluster node disks, node upgrades which modify files under Git control, or any other disk operation that may touch repository storage external to GitLab. The Gitaly team is actively working to provide manual commands to [reconcile the Praefect database with the repository storage](https://gitlab.com/groups/gitlab-org/-/epics/6723). | Don't directly change repositories on any Gitaly Cluster node at this time. |
| Praefect unable to insert data into the database due to migrations not being applied after an upgrade | If the database is not kept up to date with completed migrations, then the Praefect node is unable to perform normal operation. | Make sure the Praefect database is up and running with all migrations completed (For example: `/opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml sql-migrate-status` should show a list of all applied migrations). Consider [requesting live upgrade assistance](https://about.gitlab.com/support/scheduling-live-upgrade-assistance.html) so your upgrade plan can be reviewed by support. |
-| Restoring a Gitaly Cluster node from a snapshot in a running cluster | Because the Gitaly Cluster runs with consistent state, introducing a single node that is behind will result in the cluster not being able to reconcile the nodes data and other nodes data | Don't restore a single Gitaly Cluster node from a backup snapshot. If you need to restore from backup, it's best to snapshot all Gitaly Cluster nodes at the same time and take a database dump of the Praefect database. |
+| Restoring a Gitaly Cluster node from a snapshot in a running cluster | Because the Gitaly Cluster runs with consistent state, introducing a single node that is behind will result in the cluster not being able to reconcile the nodes data and other nodes data | Don't restore a single Gitaly Cluster node from a backup snapshot. If you must restore from backup, it's best to snapshot all Gitaly Cluster nodes at the same time and take a database dump of the Praefect database. |
### Snapshot backup and recovery limitations
@@ -179,7 +179,7 @@ In this example:
- Repositories are stored on a virtual storage called `storage-1`.
- Three Gitaly nodes provide `storage-1` access: `gitaly-1`, `gitaly-2`, and `gitaly-3`.
- The three Gitaly nodes share data in three separate hashed storage locations.
-- The [replication factor](#replication-factor) is `3`. There are three copies maintained
+- The [replication factor](#replication-factor) is `3`. Three copies are maintained
of each repository.
The availability objectives for Gitaly clusters assuming a single node failure are:
@@ -237,7 +237,7 @@ Engineering support for NFS for Git repositories is deprecated. Technical suppor
is not well suited to Git workloads which are CPU and IOPS sensitive.
Specifically:
-- Git is sensitive to file system latency. Even simple operations require many
+- Git is sensitive to file system latency. Some operations require many
read operations. Operations that are fast on block storage can become an order of
magnitude slower. This significantly impacts GitLab application performance.
- NFS performance optimizations that prevent the performance gap between
@@ -386,8 +386,7 @@ them back to direct Gitaly storage:
1. Create and configure a new
[Gitaly server](configure_gitaly.md#run-gitaly-on-its-own-server).
1. [Move the repositories](../operations/moving_repositories.md#move-repositories)
- to the newly created storage. There are different possibilities to move them
- by shard or by group, this gives you the opportunity to spread them over
+ to the newly created storage. You can move them by shard or by group, which gives you the opportunity to spread them over
multiple Gitaly servers.
## Monitor Gitaly and Gitaly Cluster
@@ -509,7 +508,7 @@ The following metrics are available from the `/metrics` endpoint:
They reflect configuration defined for this instance of Praefect.
- `gitaly_praefect_replication_latency_bucket`, a histogram measuring the amount of time it takes
- for replication to complete once the replication job starts. Available in GitLab 12.10 and later.
+ for replication to complete after the replication job starts. Available in GitLab 12.10 and later.
- `gitaly_praefect_replication_delay_bucket`, a histogram measuring how much time passes between
when the replication job is created and when it starts. Available in GitLab 12.10 and later.
- `gitaly_praefect_node_latency_bucket`, a histogram measuring the latency in Gitaly returning
@@ -542,7 +541,7 @@ You can also monitor the [Praefect logs](../logs.md#praefect-logs).
The following metrics are available from the `/db_metrics` endpoint:
- `gitaly_praefect_unavailable_repositories`, the number of repositories that have no healthy, up to date replicas.
-- `gitaly_praefect_read_only_repositories`, the number of repositories in read-only mode within a virtual storage.
+- `gitaly_praefect_read_only_repositories`, the number of repositories in read-only mode in a virtual storage.
This metric is available for backwards compatibility reasons. `gitaly_praefect_unavailable_repositories` is more
accurate.
- `gitaly_praefect_replication_queue_depth`, the number of jobs in the replication queue.
diff --git a/doc/administration/gitaly/praefect.md b/doc/administration/gitaly/praefect.md
index 8f17835b8a3..d7a06994b6c 100644
--- a/doc/administration/gitaly/praefect.md
+++ b/doc/administration/gitaly/praefect.md
@@ -616,7 +616,7 @@ Note the following:
- IP address, you must add it as a Subject Alternative Name to the certificate.
- When running Praefect sub-commands such as `dial-nodes` and `list-untracked-repositories` from the command line with
[Gitaly TLS enabled](configure_gitaly.md#enable-tls-support), you must set the `SSL_CERT_DIR` or `SSL_CERT_FILE`
- environment variable so that the Gitaly certificate is trusted. For example:
+ environment variable so that the Gitaly certificate is trusted. For example:
```shell
sudo SSL_CERT_DIR=/etc/gitlab/trusted_certs /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml dial-nodes
@@ -1196,6 +1196,9 @@ You can configure:
current assignments: gitaly-1, gitaly-2
```
+If `default_replication_factor` is unset, the repositories are always replicated on every node defined in `virtual_storages`. If a new
+node is introduced to the virtual storage, both new and existing repositories are replicated to the node automatically.
+
## Automatic failover and primary election strategies
Praefect regularly checks the health of each Gitaly node. This is used to automatically fail over
diff --git a/doc/administration/gitaly/recovery.md b/doc/administration/gitaly/recovery.md
index 9210c8f08d3..a7166f7e62e 100644
--- a/doc/administration/gitaly/recovery.md
+++ b/doc/administration/gitaly/recovery.md
@@ -76,7 +76,7 @@ The following parameters are available:
some assigned copies that are not available.
NOTE:
-`dataloss` is still in beta and the output format is subject to change.
+`dataloss` is still in [Beta](../../policy/alpha-beta-support.md#beta-features) and the output format is subject to change.
To check for repositories with outdated primaries or for unavailable repositories, run:
@@ -377,7 +377,7 @@ sudo /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.t
The `track-repository` Praefect sub-command adds repositories on disk to the Praefect database to be tracked.
```shell
-sudo /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml track-repository -virtual-storage <virtual-storage> -repository <repository> -replicate-immediately
+sudo /opt/gitlab/embedded/bin/praefect -config /var/opt/gitlab/praefect/config.toml track-repository -virtual-storage <virtual-storage> -authoritative-storage <storage-name> -repository <repository> -replicate-immediately
```
- `-virtual-storage` is the virtual storage the repository is located in. Virtual storages are configured in `/etc/gitlab/gitlab.rb` under `praefect['virtual_storages]` and looks like the following:
diff --git a/doc/administration/gitaly/troubleshooting.md b/doc/administration/gitaly/troubleshooting.md
index ff136b44340..516af4ca469 100644
--- a/doc/administration/gitaly/troubleshooting.md
+++ b/doc/administration/gitaly/troubleshooting.md
@@ -554,7 +554,7 @@ Is [some cases](index.md#known-issues) the Praefect database can get out of sync
a given repository is fully synced on all nodes, run the [`gitlab:praefect:replicas` Rake task](../raketasks/praefect.md#replica-checksums)
that checksums the repository on all Gitaly nodes.
-The [Praefect dataloss](recovery.md#check-for-data-loss) command only checks the state of the repo in the Praefect database, and cannot
+The [Praefect dataloss](recovery.md#check-for-data-loss) command only checks the state of the repository in the Praefect database, and cannot
be relied to detect sync problems in this scenario.
### Relation does not exist errors
@@ -610,3 +610,45 @@ Possible solutions:
- Provision larger VMs to gain access to larger network traffic allowances.
- Use your cloud service's monitoring and logging to check that the Praefect nodes are not exhausting their traffic allowances.
+
+## Profiling Gitaly
+
+Gitaly exposes several of Golang's built-in performance profiling tools on the Prometheus listen port. For example, if Prometheus is listening
+on port `9236` of the GitLab server:
+
+- Get a list of running `goroutines` and their backtraces:
+
+ ```shell
+ curl --output goroutines.txt "http://<gitaly_server>:9236/debug/pprof/goroutine?debug=2"
+ ```
+
+- Run a CPU profile for 30 seconds:
+
+ ```shell
+ curl --output cpu.bin "http://<gitaly_server>:9236/debug/pprof/profile"
+ ```
+
+- Profile heap memory usage:
+
+ ```shell
+ curl --output heap.bin "http://<gitaly_server>:9236/debug/pprof/heap"
+ ```
+
+- Record a 5 second execution trace. This will impact Gitaly's performance while running:
+
+ ```shell
+ curl --output trace.bin "http://<gitaly_server>:9236/debug/pprof/trace?seconds=5"
+ ```
+
+On a host with `go` installed, the CPU profile and heap profile can be viewed in a browser:
+
+```shell
+go tool pprof -http=:8001 cpu.bin
+go tool pprof -http=:8001 heap.bin
+```
+
+Execution traces can be viewed by running:
+
+```shell
+go tool trace heap.bin
+```
diff --git a/doc/administration/incoming_email.md b/doc/administration/incoming_email.md
index cd1f39b1295..caade32b7c2 100644
--- a/doc/administration/incoming_email.md
+++ b/doc/administration/incoming_email.md
@@ -68,11 +68,16 @@ this method only supports replies, and not the other features of [incoming email
## Accepted headers
-Email is processed correctly when a configured email address is present in one of the following headers:
+> Accepting `Received` headers [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/81489) in GitLab 14.9 [with a flag](feature_flags.md) named `use_received_header_for_incoming_emails`. Enabled by default.
+
+Email is processed correctly when a configured email address is present in one of the following headers
+(sorted in the order they are checked):
- `To`
+- `References`
- `Delivered-To`
- `Envelope-To` or `X-Envelope-To`
+- `Received`
In GitLab 14.6 and later, [Service Desk](../user/project/service_desk.md)
also checks accepted headers.
@@ -84,6 +89,9 @@ However, it might not include the configured GitLab email address if:
- The address was included when using "Reply all".
- The email was forwarded.
+The `Received` header can contain multiple email addresses. These are checked in the order that they appear.
+The first match is used.
+
## Rejected headers
To prevent unwanted issue creation from automatic email systems, GitLab ignores all incoming email
diff --git a/doc/administration/index.md b/doc/administration/index.md
index bd6549fca80..50dc2bc905a 100644
--- a/doc/administration/index.md
+++ b/doc/administration/index.md
@@ -35,7 +35,7 @@ Learn how to install, configure, update, and maintain your GitLab instance.
- [Installing GitLab on Amazon Web Services (AWS)](../install/aws/index.md): Set up GitLab on Amazon AWS.
- [Geo](geo/index.md): Replicate your GitLab instance to other geographic locations as a read-only fully operational version.
- [Disaster Recovery](geo/disaster_recovery/index.md): Quickly fail-over to a different site with minimal effort in a disaster situation.
-- [Add License](../user/admin_area/license.md): Upload a license at install time to unlock features that are in paid tiers of GitLab.
+- [Add License](../user/admin_area/license.md): Add a license at install time to unlock features that are in paid tiers of GitLab.
### Configuring GitLab
@@ -68,7 +68,7 @@ Learn how to install, configure, update, and maintain your GitLab instance.
- [Elasticsearch](../integration/elasticsearch.md): Enable Elasticsearch to
empower Advanced Search. Use when you deal with a huge amount of data.
- [External Classification Policy Authorization](../user/admin_area/settings/external_authorization.md)
-- [Upload a license](../user/admin_area/license.md): Upload a license to unlock
+- [Add a license](../user/admin_area/license.md): Add a license to unlock
features that are in paid tiers of GitLab.
- [Admin Area](../user/admin_area/index.md): for self-managed instance-wide
configuration and maintenance.
diff --git a/doc/administration/instance_limits.md b/doc/administration/instance_limits.md
index 614ab5278c5..11a34f5b5f8 100644
--- a/doc/administration/instance_limits.md
+++ b/doc/administration/instance_limits.md
@@ -153,6 +153,17 @@ Set the limit to `0` to disable it.
- **Default rate limit**: Disabled (unlimited).
+### Search rate limit
+
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/80631) in GitLab 14.9
+
+This setting limits global search requests.
+
+| Limit | Default (requests per minute) |
+|-------------------------|-------------------------------|
+| Authenticated user | 30 |
+| Unauthenticated user | 10 |
+
## Gitaly concurrency limit
Clone traffic can put a large strain on your Gitaly service. To prevent such workloads from overwhelming your Gitaly server, you can set concurrency limits in Gitaly's configuration file.
@@ -208,13 +219,18 @@ When the number exceeds the limit the page displays an alert and links to a pagi
> [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 limit prevents the accidental creation of pipelines when `git push --all`
-or `git push --mirror` is used.
+When pushing multiple changes with a single Git push, like multiple tags or branches,
+only four tag or branch pipelines can be triggered. This limit prevents the accidental
+creation of a large number of pipelines when using `git push --all` or `git push --mirror`.
+
+[Merge request pipelines](../ci/pipelines/merge_request_pipelines.md) are not limited.
+If the Git push updates multiple merge requests at the same time, a merge request pipeline
+can trigger for every updated merge request.
-This limit does not affect any of the updated merge request pipelines.
-All updated merge requests have a pipeline created when using
-[merge request pipelines](../ci/pipelines/merge_request_pipelines.md).
+To remove the limit so that any number of pipelines can trigger for a single Git push event,
+administrators can enable the `git_push_create_all_pipelines` [feature flag](feature_flags.md).
+Enabling this feature flag is not recommended, as it can cause excessive load on the GitLab
+instance if too many changes are pushed at once and a flood of pipelines are created accidentally.
## Retention of activity history
@@ -558,7 +574,7 @@ Plan.default.actual_limits.update!(ci_max_artifact_size_junit: 10)
### Number of files per GitLab Pages web-site
-The total number of file entries (including directories and symlinks) is limited to `100000` per
+The total number of file entries (including directories and symlinks) is limited to `200,000` per
GitLab Pages website.
This is the default limit for all [GitLab self-managed and SaaS plans](https://about.gitlab.com/pricing/).
@@ -800,7 +816,7 @@ Reports that go over the 20 MB limit aren't loaded. Affected reports:
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/8638) in GitLab 13.3.
You can set a limit on the content of repository files that are indexed in
-Elasticsearch. Any files larger than this limit only index the file name.
+Elasticsearch. Any files larger than this limit only index the filename.
The file content is neither indexed nor searchable.
Setting a limit helps reduce the memory usage of the indexing processes and
@@ -942,3 +958,7 @@ varies by file type:
If a branch is merged while open merge requests still point to it, GitLab can
retarget merge requests pointing to the now-merged branch. To learn more, read
[Branch retargeting on merge](../user/project/merge_requests/getting_started.md#branch-retargeting-on-merge).
+
+## CDN-based limits on GitLab.com
+
+In addition to application-based limits, GitLab.com is configured to use Cloudflare's standard DDoS protection and Spectrum to protect Git over SSH. Cloudflare terminates client TLS connections but is not application aware and cannot be used for limits tied to users or groups. Cloudflare page rules and rate limits are configured with Terraform. These configurations are [not public](https://about.gitlab.com/handbook/communication/#not-public) because they include security and abuse implementations that detect malicious activities and making them public would undermine those operations.
diff --git a/doc/administration/integration/plantuml.md b/doc/administration/integration/plantuml.md
index 94fef89d966..5a9699b3a39 100644
--- a/doc/administration/integration/plantuml.md
+++ b/doc/administration/integration/plantuml.md
@@ -21,7 +21,7 @@ blocks to an HTML image tag, with the source pointing to the PlantUML instance.
diagram delimiters `@startuml`/`@enduml` aren't required, as these are replaced
by the `plantuml` block:
-- **Markdown**
+- **Markdown** files with the extension `.md`:
````markdown
```plantuml
@@ -30,7 +30,10 @@ by the `plantuml` block:
```
````
-- **AsciiDoc**
+ For additional acceptable extensions, review the
+ [`languages.yaml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/vendor/languages.yml#L3174) file.
+
+- **AsciiDoc** files with the extension `.asciidoc`, `.adoc`, or `.asc`:
```plaintext
[plantuml, format="png", id="myDiagram", width="200px"]
@@ -224,6 +227,16 @@ these steps:
gitlab_rails['env'] = { 'PLANTUML_ENCODING' => 'deflate' }
```
+ In GitLab Helm chart, you can set it by adding a variable to the
+ [global.extraEnv](https://gitlab.com/gitlab-org/charts/gitlab/blob/master/doc/charts/globals.md#extraenv)
+ section, like this:
+
+ ```yaml
+ global:
+ extraEnv:
+ PLANTUML_ENCODING: deflate
+ ```
+
- For GitLab versions 13.1 and later, PlantUML integration now
[requires a header prefix in the URL](https://github.com/plantuml/plantuml/issues/117#issuecomment-6235450160)
to distinguish different encoding types.
diff --git a/doc/administration/integration/terminal.md b/doc/administration/integration/terminal.md
index f570c9b559f..792afc6c3d7 100644
--- a/doc/administration/integration/terminal.md
+++ b/doc/administration/integration/terminal.md
@@ -11,6 +11,11 @@ info: To determine the technical writer assigned to the Stage/Group associated w
WARNING:
This feature was [deprecated](https://gitlab.com/groups/gitlab-org/configure/-/epics/8) in GitLab 14.5.
+- Read more about the non-deprecated [Web Terminals accessible through the Web IDE](../../user/project/web_ide/index.md).
+- Read more about the non-deprecated [Web Terminals accessible from a running CI job](../../ci/interactive_web_terminal/index.md).
+
+---
+
With the introduction of the [Kubernetes integration](../../user/infrastructure/clusters/index.md),
GitLab can store and use credentials for a Kubernetes cluster.
GitLab uses these credentials to provide access to
diff --git a/doc/administration/job_artifacts.md b/doc/administration/job_artifacts.md
index 8f824fcefb3..544a5973052 100644
--- a/doc/administration/job_artifacts.md
+++ b/doc/administration/job_artifacts.md
@@ -307,6 +307,33 @@ To migrate back to local storage:
## Expiring artifacts
+> [In GitLab 14.6](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/76504), we improved the performance of removing expired artifacts, introduced [with a flag](feature_flags.md) named `ci_destroy_all_expired_service`. Disabled by default.
+
+FLAG:
+On self-managed GitLab, by default this feature is not available. To make it available, ask an administrator to
+[enable the feature flag](feature_flags.md) named `ci_destroy_all_expired_service`. The feature is not ready for
+production use.
+On GitLab.com, this feature is not available.
+
+### Removing expired job artifacts on GitLab self-managed instances
+
+In the process of migrating old artifacts for our SaaS customers, we are working to resolve any potential unrecoverable data loss for self-managed customers for artifacts that they may not want deleted yet. Before we can use the more performant way of cleaning up expired artifacts, we need to do some remediation to make sure customers don't lose their data, which is part of our effort in [the relevant epic](https://gitlab.com/groups/gitlab-org/-/epics/7097).
+
+Two options are available:
+
+- If you don't need any artifacts created before 2020-06-23, an Administrator can enable the worker for removing expired CI/CD artifacts:
+
+ ```ruby
+ Feature.enable(:ci_destroy_all_expired_service)
+ ```
+
+- If you want to keep any artifacts (including job logs) before 2020-06-23, follow the [progress of the migration effort](https://gitlab.com/groups/gitlab-org/-/epics/7097) where we work on a resolution to have this flag fully enabled in a future release.
+
+Alternatively, Administrators can also run commands in the Rails console to
+[delete artifacts from completed jobs prior to a specific date](#delete-job-artifacts-from-jobs-completed-before-a-specific-date).
+
+### Usage details
+
If [`artifacts:expire_in`](../ci/yaml/index.md#artifactsexpire_in) is used to set
an expiry for the artifacts, they are marked for deletion right after that date passes.
Otherwise, they expire per the [default artifacts expiration setting](../user/admin_area/settings/continuous_integration.md).
@@ -387,6 +414,37 @@ 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 and builds with artifacts with a specific expiration (or no expiration)
+
+Using a [Rails console](operations/rails_console.md), you can find projects that have job artifacts with either:
+
+- No expiration date.
+- An expiration date more than 7 days in the future.
+
+Similar to [deleting artifacts](#delete-job-artifacts-from-jobs-completed-before-a-specific-date), use the following example time frames
+and alter them as needed:
+
+- `7.days.from_now`
+- `10.days.from_now`
+- `2.weeks.from_now`
+- `3.months.from_now`
+
+Each of the following scripts also limits the search to 50 results with `.limit(50)`, but this number can also be changed as needed:
+
+```ruby
+# Find builds & projects with artifacts that never expire
+builds_with_artifacts_that_never_expire = Ci::Build.with_downloadable_artifacts.where(artifacts_expire_at: nil).limit(50)
+builds_with_artifacts_that_never_expire.find_each do |build|
+ puts "Build with id #{build.id} has artifacts that don't expire and belongs to project #{build.project.full_path}"
+end
+
+# Find builds & projects with artifacts that expire after 7 days from today
+builds_with_artifacts_that_expire_in_a_week = Ci::Build.with_downloadable_artifacts.where('artifacts_expire_at > ?', 7.days.from_now).limit(50)
+builds_with_artifacts_that_expire_in_a_week.find_each do |build|
+ puts "Build with id #{build.id} has artifacts that expire at #{build.artifacts_expire_at} and belongs to project #{build.project.full_path}"
+end
+```
+
#### List projects by total size of job artifacts stored
List the top 20 projects, sorted by the total size of job artifacts stored, by
@@ -435,7 +493,7 @@ list = arts.order(size: :desc).limit(50).each do |art|
end
```
-To change the number of projects listed, change the number in `limit(50)`.
+To change the number of job artifacts listed, change the number in `limit(50)`.
#### Delete job artifacts from jobs completed before a specific date
@@ -572,3 +630,15 @@ review:
```
In both cases, you might need to add `region` to the job artifact [object storage configuration](#connection-settings).
+
+### Job artifact upload fails with `500 Internal Server Error (Missing file)`
+
+Bucket names that include folder paths are not supported with [consolidated object storage](object_storage.md#consolidated-object-storage-configuration).
+For example, `bucket/path`. If a bucket name has a path in it, you might receive an error similar to:
+
+```plaintext
+WARNING: Uploading artifacts as "archive" to coordinator... POST https://gitlab.example.com/api/v4/jobs/job_id/artifacts?artifact_format=zip&artifact_type=archive&expire_in=1+day: 500 Internal Server Error (Missing file)
+FATAL: invalid argument
+```
+
+If a job artifact fails to upload with the above error when using consolidated object storage, make sure you are [using separate buckets](object_storage.md#use-separate-buckets) for each data type.
diff --git a/doc/administration/logs.md b/doc/administration/logs.md
index c4e9642d048..22e13270179 100644
--- a/doc/administration/logs.md
+++ b/doc/administration/logs.md
@@ -1049,7 +1049,10 @@ For example:
## Mattermost Logs
-For Omnibus GitLab installations, Mattermost logs are in `/var/log/gitlab/mattermost/mattermost.log`.
+For Omnibus GitLab installations, Mattermost logs are in these locations:
+
+- `/var/log/gitlab/mattermost/mattermost.log`
+- `/var/log/gitlab/mattermost/current`
## Workhorse Logs
@@ -1095,9 +1098,9 @@ For Omnibus GitLab installations, GitLab Monitor logs are in `/var/log/gitlab/gi
For Omnibus GitLab installations, GitLab Exporter logs are in `/var/log/gitlab/gitlab-exporter/`.
-## GitLab Agent Server
+## GitLab agent server
-For Omnibus GitLab installations, GitLab Agent Server logs are
+For Omnibus GitLab installations, GitLab agent server logs are
in `/var/log/gitlab/gitlab-kas/`.
## Praefect Logs
diff --git a/doc/administration/monitoring/gitlab_self_monitoring_project/index.md b/doc/administration/monitoring/gitlab_self_monitoring_project/index.md
index 911d76a89e3..09cef51d14c 100644
--- a/doc/administration/monitoring/gitlab_self_monitoring_project/index.md
+++ b/doc/administration/monitoring/gitlab_self_monitoring_project/index.md
@@ -8,10 +8,11 @@ info: To determine the technical writer assigned to the Stage/Group associated w
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/32351) in GitLab 12.7 [with a flag](../../feature_flags.md) named `self_monitoring_project`. Disabled by default.
> - Generally available in GitLab 12.8. [Feature flag `self_monitoring_project`](https://gitlab.com/gitlab-org/gitlab/-/issues/198511) removed.
-> - [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/348909) in GitLab 14.8.
+> - [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/348909) in GitLab 14.9. Planned for removal in GitLab 15.0.
WARNING:
-This feature was [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/348909) in GitLab 14.8.
+This feature is in its end-of-life process. It is [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/348909)
+for use in GitLab 14.9, and is planned for removal in GitLab 15.0.
GitLab provides administrators insights into the health of their GitLab instance.
diff --git a/doc/administration/monitoring/index.md b/doc/administration/monitoring/index.md
index df655053723..381c807dbc5 100644
--- a/doc/administration/monitoring/index.md
+++ b/doc/administration/monitoring/index.md
@@ -24,6 +24,3 @@ Explore our features to monitor your GitLab instance:
provide health check information when probed.
- [`nginx_status`](https://docs.gitlab.com/omnibus/settings/nginx.html#enablingdisabling-nginx_status):
Monitor your NGINX server status.
-- [Auto Monitoring](../../topics/autodevops/stages.md#auto-monitoring): Automated
- monitoring for your application's server and response metrics, provided by
- [Auto DevOps](../../topics/autodevops/index.md).
diff --git a/doc/administration/monitoring/performance/img/performance_bar_request_selector_warning.png b/doc/administration/monitoring/performance/img/performance_bar_request_selector_warning.png
deleted file mode 100644
index 3872c8b41b2..00000000000
--- a/doc/administration/monitoring/performance/img/performance_bar_request_selector_warning.png
+++ /dev/null
Binary files differ
diff --git a/doc/administration/monitoring/performance/performance_bar.md b/doc/administration/monitoring/performance/performance_bar.md
index e93dbd3a2d6..bc311f73dfe 100644
--- a/doc/administration/monitoring/performance/performance_bar.md
+++ b/doc/administration/monitoring/performance/performance_bar.md
@@ -30,8 +30,7 @@ From left to right, the performance bar displays:
is enabled. It shows which server role was used for the query.
"Primary" means that the query was sent to the read/write primary server.
"Replica" means it was sent to a read-only replica.
- - **Config name**: shows up only when the
- `GITLAB_MULTIPLE_DATABASE_METRICS` environment variable is set. This is
+ - **Configuration name**: this is
used to distinguish between different databases configured for different
GitLab features. The name shown is the same name used to configure database
connections in GitLab.
@@ -48,12 +47,13 @@ From left to right, the performance bar displays:
- **External HTTP calls**: the time taken (in milliseconds) and the total
number of external calls to other systems. Click to display a modal window
with more details.
-- **Load timings** of the page: if your browser supports load timings (Chromium
- and Chrome) several values in milliseconds, separated by slashes.
+- **Load timings** of the page: if your browser supports load timings, several
+ values in milliseconds, separated by slashes.
Click to display a modal window with more details. The values, from left to right:
- **Backend**: time needed for the base page to load.
- [**First Contentful Paint**](https://web.dev/first-contentful-paint/):
- Time until something was visible to the user.
+ Time until something was visible to the user. Displays `NaN` if your browser does not
+ support this feature.
- [**DomContentLoaded**](https://developers.google.com/web/fundamentals/performance/critical-rendering-path/measure-crp) Event.
- **Total number of requests** the page loaded.
- **Memory**: the amount of memory consumed and objects allocated during the selected request.
@@ -64,6 +64,9 @@ From left to right, the performance bar displays:
can be added by its full URL (authenticated as the current user), or by the value of
its `X-Request-Id` header.
- **Download**: a link to download the raw JSON used to generate the Performance Bar reports.
+- **Memory Report**: a link that generates a
+ [memory profiling](../../../development/performance.md#using-memory-profiler)
+ report of the current URL.
- **Flamegraph** with mode: a link to generate a [flamegraph](../../../development/profiling.md#speedscope-flamegraphs)
of the current URL with the selected [Stackprof mode](https://github.com/tmm1/stackprof#sampling):
- The **Wall** mode samples every *interval* of the time on a clock on a wall. The interval is set to `10100` microseconds.
@@ -91,18 +94,14 @@ For non-administrators to display the performance bar, it must be
## Request warnings
+> [Warning icon in the request selector removed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/82187) in GitLab 14.9.
+
Requests that exceed predefined limits display a warning **{warning}** icon and
explanation next to the metric. In this example, the Gitaly call duration
exceeded the threshold.
![Gitaly call duration exceeded threshold](img/performance_bar_gitaly_threshold.png)
-If any requests on the current page generated warnings, the warning icon displays
-next to the **Requests** selector menu. In this selector menu, an exclamation `(!)`
-appears next to requests with warnings.
-
-![Request selector showing two requests with warnings](img/performance_bar_request_selector_warning.png)
-
## Enable the performance bar for non-administrators
The performance bar is disabled by default for non-administrators. To enable it
diff --git a/doc/administration/monitoring/prometheus/index.md b/doc/administration/monitoring/prometheus/index.md
index 9d90c4f3cc7..22f7419be9a 100644
--- a/doc/administration/monitoring/prometheus/index.md
+++ b/doc/administration/monitoring/prometheus/index.md
@@ -301,7 +301,7 @@ Prometheus has several custom flags to configure local storage:
- `storage.tsdb.retention.time`: when to remove old data. Defaults to `15d`. Overrides
`storage.tsdb.retention` if this flag is set to anything other than the default.
-- `storage.tsdb.retention.size`: [EXPERIMENTAL] the maximum number of bytes of storage blocks to
+- `storage.tsdb.retention.size`: (experimental) the maximum number of bytes of storage blocks to
retain. The oldest data is removed first. Defaults to `0` (disabled). This flag is experimental
and may change in future releases. Units supported: `B`, `KB`, `MB`, `GB`, `TB`, `PB`, `EB`. For
example, `512MB`.
diff --git a/doc/administration/object_storage.md b/doc/administration/object_storage.md
index 420f2191ef2..8ea4ad9019e 100644
--- a/doc/administration/object_storage.md
+++ b/doc/administration/object_storage.md
@@ -62,7 +62,7 @@ Using the consolidated object storage configuration has a number of advantages:
- It enables the use of [encrypted S3 buckets](#encrypted-s3-buckets).
- It [uploads files to S3 with proper `Content-MD5` headers](https://gitlab.com/gitlab-org/gitlab-workhorse/-/issues/222).
-Because [direct upload mode](../development/uploads.md#direct-upload)
+Because [direct upload mode](../development/uploads/implementation.md#direct-upload)
must be enabled, only the following providers can be used:
- [Amazon S3-compatible providers](#s3-compatible-connection-settings)
@@ -598,6 +598,7 @@ See the following additional guides:
1. Configure [database lookup of SSH keys](operations/fast_ssh_key_lookup.md)
to eliminate the need for a shared `authorized_keys` file.
1. [Prevent local disk usage for job logs](job_logs.md#prevent-local-disk-usage).
+1. [Disable Pages local storage](pages/index.md#disable-pages-local-storage).
## Warnings, limitations, and known issues
diff --git a/doc/administration/operations/fast_ssh_key_lookup.md b/doc/administration/operations/fast_ssh_key_lookup.md
index dca99879cc3..8877b1266e0 100644
--- a/doc/administration/operations/fast_ssh_key_lookup.md
+++ b/doc/administration/operations/fast_ssh_key_lookup.md
@@ -182,7 +182,7 @@ file for the environment, since it isn't generated dynamically.
## Troubleshooting
If your SSH traffic is [slow](https://github.com/linux-pam/linux-pam/issues/270)
-or causing high CPU load, be sure to check the size of `/var/log/btmp`, and ensure it is rotated on a regular basis.
+or causing high CPU load, be sure to check the size of `/var/log/btmp`, and ensure it is rotated on a regular basis or after reaching a certain size.
If this file is very large, GitLab SSH fast lookup can cause the bottleneck to be hit more frequently, thus decreasing performance even further.
If you are able to, you may consider disabling [`UsePAM` in your `sshd_config`](https://linux.die.net/man/5/sshd_config) to avoid reading `/var/log/btmp` altogether.
diff --git a/doc/administration/operations/puma.md b/doc/administration/operations/puma.md
index c7df8249ae4..9e828b39f46 100644
--- a/doc/administration/operations/puma.md
+++ b/doc/administration/operations/puma.md
@@ -4,45 +4,19 @@ group: Distribution
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
-# Puma **(FREE SELF)**
+# Configure the bundled Puma instance of the GitLab package **(FREE SELF)**
-Puma is a simple, fast, multi-threaded, and highly concurrent HTTP 1.1 server for
-Ruby applications. It's the default GitLab web server since GitLab 13.0
-and has replaced Unicorn. From GitLab 14.0, Unicorn is no longer supported.
+Puma is a fast, multi-threaded, and highly concurrent HTTP 1.1 server for
+Ruby applications. It runs the core Rails application that provides the user-facing
+features of GitLab.
-NOTE:
-Starting with GitLab 13.0, Puma is the default web server and Unicorn has been disabled.
-In GitLab 14.0, Unicorn was removed from the Linux package and only Puma is available.
-
-## Configure Puma
-
-To configure Puma:
-
-1. Determine suitable Puma worker and thread [settings](../../install/requirements.md#puma-settings).
-1. If you're switching from Unicorn, [convert any custom settings to Puma](#convert-unicorn-settings-to-puma).
-1. For multi-node deployments, configure the load balancer to use the
- [readiness check](../load_balancer.md#readiness-check).
-1. Reconfigure GitLab so the above changes take effect:
-
- ```shell
- sudo gitlab-ctl reconfigure
- ```
-
-For Helm-based deployments, see the
-[`webservice` chart documentation](https://docs.gitlab.com/charts/charts/gitlab/webservice/index.html).
-
-For more details about the Puma configuration, see the
-[Puma documentation](https://github.com/puma/puma#configuration).
+## Reducing memory use
-## Puma Worker Killer
+To reduce memory use, Puma forks worker processes. Each time a worker is created,
+it shares memory with the primary process. The worker uses additional memory only
+when it changes or adds to its memory pages.
-Puma forks worker processes as part of a strategy to reduce memory use.
-
-Each time a worker is created, it shares memory with the primary process and
-only uses additional memory when it makes changes or additions to its memory pages.
-
-Memory use by workers therefore increases over time, and Puma Worker Killer is the
-mechanism that recovers this memory.
+Memory use increases over time, but you can use Puma Worker Killer to recover memory.
By default:
@@ -50,6 +24,8 @@ By default:
exceeds a [memory limit](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/cluster/puma_worker_killer_initializer.rb).
- Rolling restarts of Puma workers are performed every 12 hours.
+### Change the memory limit setting
+
To change the memory limit setting:
1. Edit `/etc/gitlab/gitlab.rb`:
@@ -58,26 +34,28 @@ To change the memory limit setting:
puma['per_worker_max_memory_mb'] = 1024
```
-1. Reconfigure GitLab for the changes to take effect:
+1. Reconfigure GitLab:
```shell
sudo gitlab-ctl reconfigure
```
-There are costs associated with killing and replacing workers including
-reduced capacity to run GitLab, and CPU that is consumed
-restarting the workers. `per_worker_max_memory_mb` should be set to a
-higher value if the worker killer is replacing workers too often.
+When workers are killed and replaced, capacity to run GitLab is reduced,
+and CPU is consumed. Set `per_worker_max_memory_mb` to a higher value if the worker killer
+is replacing workers too often.
-Worker count is calculated based on CPU cores, so a small GitLab deployment
+Worker count is calculated based on CPU cores. A small GitLab deployment
with 4-8 workers may experience performance issues if workers are being restarted
-frequently, once or more per minute. This is too often.
+too often (once or more per minute).
A higher value of `1200` or more would be beneficial if the server has free memory.
-The worker killer checks every 20 seconds, and can be monitored using
-[the Puma log](../logs.md#puma_stdoutlog) `/var/log/gitlab/puma/puma_stdout.log`.
-For example, for GitLab 13.5:
+### Monitor worker memory
+
+The worker killer checks memory every 20 seconds.
+
+To monitor the worker killer, use [the Puma log](../logs.md#puma_stdoutlog) `/var/log/gitlab/puma/puma_stdout.log`.
+For example:
```plaintext
PumaWorkerKiller: Out of memory. 4 workers consuming total: 4871.23828125 MB
@@ -88,9 +66,9 @@ From this output:
- The formula that calculates the maximum memory value results in workers
being killed before they reach the `per_worker_max_memory_mb` value.
-- The default values for the formula before GitLab 13.5 were 550MB for the primary
- and `per_worker_max_memory_mb` specified 850MB for each worker.
-- As of GitLab 13.5 the values are primary: 800MB, worker: 1024MB.
+- In GitLab 13.4 and earlier, the default values for the formula were 550MB for the primary
+ and 850MB for each worker.
+- In GitLab 13.5 and later, the values are primary: 800MB, worker: 1024MB.
- The threshold for workers to be killed is set at 98% of the limit:
```plaintext
@@ -102,16 +80,15 @@ From this output:
Increasing the maximum to `1200`, for example, would set a `max: 5488 MB` value.
-Workers use additional memory on top of the shared memory, how much
+Workers use additional memory on top of the shared memory. The amount of memory
depends on a site's use of GitLab.
-## Worker timeout
+## Change the worker timeout
-A [timeout of 60 seconds](https://gitlab.com/gitlab-org/gitlab/-/blob/master/config/initializers/rack_timeout.rb)
-is used when Puma is enabled.
+The default Puma [timeout is 60 seconds](https://gitlab.com/gitlab-org/gitlab/-/blob/master/config/initializers/rack_timeout.rb).
NOTE:
-Unlike Unicorn, the `puma['worker_timeout']` setting does not set the maximum request duration.
+The `puma['worker_timeout']` setting does not set the maximum request duration.
To change the worker timeout to 600 seconds:
@@ -123,26 +100,38 @@ To change the worker timeout to 600 seconds:
}
```
-1. Reconfigure GitLab for the changes to take effect:
+1. Reconfigure GitLab:
```shell
sudo gitlab-ctl reconfigure
```
-## Memory-constrained environments
+## Disable Puma clustered mode in memory-constrained environments
In a memory-constrained environment with less than 4GB of RAM available, consider disabling Puma
-[Clustered mode](https://github.com/puma/puma#clustered-mode).
+[clustered mode](https://github.com/puma/puma#clustered-mode).
-Configuring Puma by setting the amount of `workers` to `0` could reduce memory usage by hundreds of MB.
-For details on Puma worker and thread settings, see the [Puma requirements](../../install/requirements.md#puma-settings).
+Set the number of `workers` to `0` to reduce memory usage by hundreds of MB:
+
+1. Edit `/etc/gitlab/gitlab.rb`:
-Unlike in a Clustered mode, which is set up by default, only a single Puma process would serve the application.
+ ```ruby
+ puma['worker_processes'] = 0
+ ```
-The downside of running Puma with such configuration is the reduced throughput, which could be
-considered as a fair tradeoff in a memory-constraint environment.
+1. Reconfigure GitLab:
-When running Puma in Single mode, some features are not supported:
+ ```shell
+ sudo gitlab-ctl reconfigure
+ ```
+
+Unlike in a clustered mode, which is set up by default, only a single Puma process would serve the application.
+For details on Puma worker and thread settings, see the [Puma requirements](../../install/requirements.md#puma-settings).
+
+The downside of running Puma in this configuration is the reduced throughput, which can be
+considered a fair tradeoff in a memory-constrained environment.
+
+When running Puma in single mode, some features are not supported:
- [Phased restart](https://gitlab.com/gitlab-org/gitlab/-/issues/300665)
- [Puma Worker Killer](https://gitlab.com/gitlab-org/gitlab/-/issues/300664)
@@ -151,22 +140,23 @@ To learn more, visit [epic 5303](https://gitlab.com/groups/gitlab-org/-/epics/53
## Performance caveat when using Puma with Rugged
-For deployments where NFS is used to store Git repository, we allow GitLab to use
-[direct Git access](../gitaly/index.md#direct-access-to-git-in-gitlab) to improve performance using
+For deployments where NFS is used to store Git repositories, GitLab uses
+[direct Git access](../gitaly/index.md#direct-access-to-git-in-gitlab) to improve performance by using
[Rugged](https://github.com/libgit2/rugged).
Rugged usage is automatically enabled if direct Git access
[is available](../gitaly/index.md#how-it-works)
-and Puma is running single threaded, unless it is disabled by
-[feature flags](../../development/gitaly.md#legacy-rugged-code).
+and Puma is running single threaded, unless it is disabled by a
+[feature flag](../../development/gitaly.md#legacy-rugged-code).
-MRI Ruby uses a GVL. This allows MRI Ruby to be multi-threaded, but running at
-most on a single core. Since Rugged can use a thread for long periods of
-time (due to intensive I/O operations of Git access), this can starve other threads
-that might be processing requests. This is not a case for Unicorn or Puma running
-in a single thread mode, as concurrently at most one request is being processed.
+MRI Ruby uses a Global VM Lock (GVL). GVL allows MRI Ruby to be multi-threaded, but running at
+most on a single core.
-We are actively working on removing Rugged usage. Even though performance without Rugged
+Git includes intensive I/O operations. When Rugged uses a thread for a long period of time,
+other threads that might be processing requests can starve. Puma running in single thread mode
+does not have this issue, because concurrently at most one request is being processed.
+
+GitLab is working to remove Rugged usage. Even though performance without Rugged
is acceptable today, in some cases it might be still beneficial to run with it.
Given the caveat of running Rugged with multi-threaded Puma, and acceptable
@@ -177,55 +167,70 @@ This default behavior may not be the optimal configuration in some situations. I
plays an important role in your deployment, we suggest you benchmark to find the
optimal configuration:
-- The safest option is to start with single-threaded Puma. When working with
- Rugged, single-threaded Puma works the same as Unicorn.
-- To force Rugged to be used with multi-threaded Puma, you can use
- [feature flags](../../development/gitaly.md#legacy-rugged-code).
+- The safest option is to start with single-threaded Puma.
+- To force Rugged to be used with multi-threaded Puma, you can use a
+ [feature flag](../../development/gitaly.md#legacy-rugged-code).
-## Convert Unicorn settings to Puma
+## Switch from Unicorn to Puma
NOTE:
-Starting with GitLab 13.0, Puma is the default web server and Unicorn has been
-disabled by default. In GitLab 14.0, Unicorn was removed from the Linux package
-and only Puma is available.
+For Helm-based deployments, see the
+[`webservice` chart documentation](https://docs.gitlab.com/charts/charts/gitlab/webservice/index.html).
+
+Starting with GitLab 13.0, Puma is the default web server and Unicorn has been disabled.
+In GitLab 14.0, [Unicorn was removed](../../update/removals.md#unicorn-in-gitlab-self-managed)
+from the Linux package and is no longer supported.
-Puma has a multi-thread architecture which uses less memory than a multi-process
+Puma has a multi-thread architecture that uses less memory than a multi-process
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.
+consumption. Most Rails application requests normally include a proportion of I/O wait time.
-During I/O wait time MRI Ruby releases the GVL (Global VM Lock) to other threads.
+During I/O wait time, MRI Ruby releases the GVL to other threads.
Multi-threaded Puma can therefore still serve more requests than a single process.
When switching to Puma, any Unicorn server configuration will _not_ carry over
automatically, due to differences between the two application servers.
-The table below summarizes which Unicorn configuration keys correspond to those
-in Puma when using the Linux package, and which ones have no corresponding counterpart.
-
-| Unicorn | Puma |
-| ------------------------------------ | ---------------------------------- |
-| `unicorn['enable']` | `puma['enable']` |
-| `unicorn['worker_timeout']` | `puma['worker_timeout']` |
-| `unicorn['worker_processes']` | `puma['worker_processes']` |
-| n/a | `puma['ha']` |
-| n/a | `puma['min_threads']` |
-| n/a | `puma['max_threads']` |
-| `unicorn['listen']` | `puma['listen']` |
-| `unicorn['port']` | `puma['port']` |
-| `unicorn['socket']` | `puma['socket']` |
-| `unicorn['pidfile']` | `puma['pidfile']` |
-| `unicorn['tcp_nopush']` | n/a |
-| `unicorn['backlog_socket']` | n/a |
-| `unicorn['somaxconn']` | `puma['somaxconn']` |
-| n/a | `puma['state_path']` |
-| `unicorn['log_directory']` | `puma['log_directory']` |
-| `unicorn['worker_memory_limit_min']` | n/a |
-| `unicorn['worker_memory_limit_max']` | `puma['per_worker_max_memory_mb']` |
-| `unicorn['exporter_enabled']` | `puma['exporter_enabled']` |
-| `unicorn['exporter_address']` | `puma['exporter_address']` |
-| `unicorn['exporter_port']` | `puma['exporter_port']` |
-
-## Puma exporter
-
-You can use the Puma exporter to measure various Puma metrics. For more information, see
-[Puma exporter](../monitoring/prometheus/puma_exporter.md).
+To switch from Unicorn to Puma:
+
+1. Determine suitable Puma [worker and thread settings](../../install/requirements.md#puma-settings).
+1. Convert any custom Unicorn settings to Puma.
+
+ The table below summarizes which Unicorn configuration keys correspond to those
+ in Puma when using the Linux package, and which ones have no corresponding counterpart.
+
+ | Unicorn | Puma |
+ | ------------------------------------ | ---------------------------------- |
+ | `unicorn['enable']` | `puma['enable']` |
+ | `unicorn['worker_timeout']` | `puma['worker_timeout']` |
+ | `unicorn['worker_processes']` | `puma['worker_processes']` |
+ | n/a | `puma['ha']` |
+ | n/a | `puma['min_threads']` |
+ | n/a | `puma['max_threads']` |
+ | `unicorn['listen']` | `puma['listen']` |
+ | `unicorn['port']` | `puma['port']` |
+ | `unicorn['socket']` | `puma['socket']` |
+ | `unicorn['pidfile']` | `puma['pidfile']` |
+ | `unicorn['tcp_nopush']` | n/a |
+ | `unicorn['backlog_socket']` | n/a |
+ | `unicorn['somaxconn']` | `puma['somaxconn']` |
+ | n/a | `puma['state_path']` |
+ | `unicorn['log_directory']` | `puma['log_directory']` |
+ | `unicorn['worker_memory_limit_min']` | n/a |
+ | `unicorn['worker_memory_limit_max']` | `puma['per_worker_max_memory_mb']` |
+ | `unicorn['exporter_enabled']` | `puma['exporter_enabled']` |
+ | `unicorn['exporter_address']` | `puma['exporter_address']` |
+ | `unicorn['exporter_port']` | `puma['exporter_port']` |
+
+1. Reconfigure GitLab:
+
+ ```shell
+ sudo gitlab-ctl reconfigure
+ ```
+
+1. Optional. For multi-node deployments, configure the load balancer to use the
+ [readiness check](../load_balancer.md#readiness-check).
+
+## Related topics
+
+- [Use the Puma exporter to measure various Puma metrics](../monitoring/prometheus/puma_exporter.md)
diff --git a/doc/administration/package_information/deprecated_os.md b/doc/administration/package_information/deprecated_os.md
deleted file mode 100644
index 1f6fe0fce5d..00000000000
--- a/doc/administration/package_information/deprecated_os.md
+++ /dev/null
@@ -1,9 +0,0 @@
----
-redirect_to: 'supported_os.md'
-remove_date: '2022-02-18'
----
-
-This document was moved to [another location](supported_os.md).
-
-<!-- This redirect file can be deleted after <2022-02-18>. -->
-<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/#move-or-rename-a-page -->
diff --git a/doc/administration/package_information/index.md b/doc/administration/package_information/index.md
index 2781f789409..c908f526569 100644
--- a/doc/administration/package_information/index.md
+++ b/doc/administration/package_information/index.md
@@ -1,7 +1,7 @@
---
stage: Enablement
group: Distribution
-info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
# Package information **(FREE SELF)**
diff --git a/doc/administration/package_information/licensing.md b/doc/administration/package_information/licensing.md
index 02358c66993..a7bf5c52d7b 100644
--- a/doc/administration/package_information/licensing.md
+++ b/doc/administration/package_information/licensing.md
@@ -1,7 +1,7 @@
---
stage: Enablement
group: Distribution
-info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
# Package Licensing **(FREE SELF)**
diff --git a/doc/administration/package_information/omnibus_packages.md b/doc/administration/package_information/omnibus_packages.md
index 115d6c394ad..21e3f5711ba 100644
--- a/doc/administration/package_information/omnibus_packages.md
+++ b/doc/administration/package_information/omnibus_packages.md
@@ -1,7 +1,7 @@
---
stage: Enablement
group: Distribution
-info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
# Omnibus based packages and images **(FREE SELF)**
diff --git a/doc/administration/package_information/postgresql_versions.md b/doc/administration/package_information/postgresql_versions.md
index 97a35fb29ed..e707cb70187 100644
--- a/doc/administration/package_information/postgresql_versions.md
+++ b/doc/administration/package_information/postgresql_versions.md
@@ -1,7 +1,7 @@
---
stage: Enablement
group: Distribution
-info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
# PostgreSQL versions shipped with Omnibus GitLab **(FREE SELF)**
diff --git a/doc/administration/package_information/signed_packages.md b/doc/administration/package_information/signed_packages.md
index fb605f8d5be..d7bcfa113ff 100644
--- a/doc/administration/package_information/signed_packages.md
+++ b/doc/administration/package_information/signed_packages.md
@@ -1,7 +1,7 @@
---
stage: Enablement
group: Distribution
-info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
# Package Signatures **(FREE SELF)**
diff --git a/doc/administration/package_information/supported_os.md b/doc/administration/package_information/supported_os.md
index 71ebc4d3647..547b8bf8658 100644
--- a/doc/administration/package_information/supported_os.md
+++ b/doc/administration/package_information/supported_os.md
@@ -27,6 +27,7 @@ The following lists the currently supported OSs and their possible EOL dates.
| SLES 12 | GitLab EE 9.0.0 | x86_64 | Oct 2027 | <https://www.suse.com/lifecycle/> |
| Ubuntu 18.04 | GitLab CE / GitLab EE 10.7.0 | amd64 | April 2023 | <https://wiki.ubuntu.com/Releases> |
| Ubuntu 20.04 | GitLab CE / GitLab EE 13.2.0 | amd64, arm64 | April 2025 | <https://wiki.ubuntu.com/Releases> |
+| Amazon Linux 2 | GitLab CE / GitLab EE 14.9.0 | amd64, arm64 | June 2023 | <https://aws.amazon.com/amazon-linux-2/faqs> |
| Raspbian Buster | GitLab CE 12.2.0 | armhf | 2022 | <https://wiki.debian.org/DebianReleases#Production_Releases> |
NOTE:
diff --git a/doc/administration/packages/container_registry.md b/doc/administration/packages/container_registry.md
index 33a5311709f..7bf7362c68b 100644
--- a/doc/administration/packages/container_registry.md
+++ b/doc/administration/packages/container_registry.md
@@ -457,6 +457,22 @@ To configure the `s3` storage driver in Omnibus:
- `pathstyle` should be set to true to use `host/bucket_name/object` style paths instead of
`bucket_name.host/object`. [Set to false for AWS S3](https://aws.amazon.com/blogs/aws/amazon-s3-path-deprecation-plan-the-rest-of-the-story/).
+ You can set a rate limit on connections to S3 to avoid 503 errors from the S3 API. To do this,
+ set `maxrequestspersecond` to a number within the [S3 request rate threshold](https://aws.amazon.com/premiumsupport/knowledge-center/s3-503-within-request-rate-prefix/):
+
+ ```ruby
+ registry['storage'] = {
+ 's3' => {
+ 'accesskey' => 's3-access-key',
+ 'secretkey' => 's3-secret-key-for-access-key',
+ 'bucket' => 'your-s3-bucket',
+ 'region' => 'your-s3-region',
+ 'regionendpoint' => 'your-s3-regionendpoint',
+ 'maxrequestspersecond' => 100
+ }
+ }
+ ```
+
1. Save the file and [reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure) for the changes to take effect.
**Installations from source**
@@ -1704,3 +1720,38 @@ What does this mean? This strongly suggests that the S3 user does not have the r
[permissions to perform a HEAD request](https://docs.aws.amazon.com/AmazonS3/latest/API/API_HeadObject.html).
The solution: check the [IAM permissions again](https://docs.docker.com/registry/storage-drivers/s3/).
Once the right permissions were set, the error goes away.
+
+### Missing `gitlab-registry.key` prevents container repository deletion
+
+If you disable your GitLab instance's Container Registry and try to remove a project that has
+container repositories, the following error occurs:
+
+```plaintext
+Errno::ENOENT: No such file or directory @ rb_sysopen - /var/opt/gitlab/gitlab-rails/etc/gitlab-registry.key
+```
+
+In this case, follow these steps:
+
+1. Temporarily enable the instance-wide setting for the Container Registry in your `gitlab.rb`:
+
+ ```ruby
+ gitlab_rails['registry_enabled'] = true
+ ```
+
+1. Save the file and [reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure)
+ for the changes to take effect.
+1. Try the removal again.
+
+If you still can't remove the repository using the common methods, you can use the
+[GitLab Rails console](../troubleshooting/navigating_gitlab_via_rails_console.md)
+to remove the project by force:
+
+```ruby
+# Path to the project you'd like to remove
+prj = Project.find_by_full_path(<project_path>)
+
+# The following will delete the project's container registry, so be sure to double-check the path beforehand!
+if prj.has_container_registry_tags?
+ prj.container_repositories.each { |p| p.destroy }
+end
+```
diff --git a/doc/administration/pages/index.md b/doc/administration/pages/index.md
index f000824711f..56ccf70d169 100644
--- a/doc/administration/pages/index.md
+++ b/doc/administration/pages/index.md
@@ -547,6 +547,7 @@ archive. You can modify the cache behavior by changing the following configurati
| `zip_cache_cleanup` | The interval at which archives are cleaned from memory if they have already expired. Default is 30s. |
| `zip_cache_refresh` | The time interval in which an archive is extended in memory if accessed before `zip_cache_expiration`. This works together with `zip_cache_expiration` to determine if an archive is extended in memory. See the [example below](#zip-cache-refresh-example) for important details. Default is 30s. |
| `zip_open_timeout` | The maximum time allowed to open a ZIP archive. Increase this time for big archives or slow network connections, as doing so may affect the latency of serving Pages. Default is 30s. |
+| `zip_http_client_timeout` | The maximum time for the ZIP HTTP client. Default is 30m. |
#### ZIP cache refresh example
@@ -1387,15 +1388,20 @@ This can happen if your `gitlab-secrets.json` file is out of date between GitLab
Pages. Follow steps 8-10 of [Running GitLab Pages on a separate server](#running-gitlab-pages-on-a-separate-server),
in all of your GitLab Pages instances.
-### Intermittent 502 errors when using an AWS Network Load Balancer and GitLab Pages is running on multiple application servers
+### Intermittent 502 errors when using an AWS Network Load Balancer and GitLab Pages
Connections will time out when using a Network Load Balancer with client IP preservation enabled and [the request is looped back to the source server](https://docs.aws.amazon.com/elasticloadbalancing/latest/network/load-balancer-troubleshooting.html#loopback-timeout).
This can happen to GitLab instances with multiple servers
-running both the core GitLab application and GitLab Pages.
+running both the core GitLab application and GitLab Pages. This can also happen when a single
+container is running both the core GitLab application and GitLab Pages.
AWS [recommends using an IP target type](https://aws.amazon.com/premiumsupport/knowledge-center/target-connection-fails-load-balancer/)
to resolve this issue.
+Turning off [client IP preservation](https://docs.aws.amazon.com/elasticloadbalancing/latest/network/load-balancer-target-groups.html#client-ip-preservation)
+may resolve this issue when the core GitLab application and GitLab Pages run on the same host or
+container.
+
### 500 error with `securecookie: failed to generate random iv` and `Failed to save the session`
This problem most likely results from an [out-dated operating system](../package_information/supported_os.md#os-versions-that-are-no-longer-supported).
diff --git a/doc/administration/postgresql/external.md b/doc/administration/postgresql/external.md
index 67c5448a8a0..f4e4c7f8bef 100644
--- a/doc/administration/postgresql/external.md
+++ b/doc/administration/postgresql/external.md
@@ -21,7 +21,7 @@ If you use a cloud-managed service, or provide your own PostgreSQL instance:
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.
+ - 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. Azure Database for PostgreSQL - Flexible Server requires [allow-listing extensions before they can be installed](https://docs.microsoft.com/en-us/azure/postgresql/flexible-server/concepts-extensions#how-to-use-postgresql-extensions).
- Google Cloud SQL requires the [`cloudsqlsuperuser`](https://cloud.google.com/sql/docs/postgres/users#default-users) role.
This is for the installation of extensions during installation and upgrades. As an alternative,
diff --git a/doc/administration/raketasks/doctor.md b/doc/administration/raketasks/doctor.md
index bed3cdcbcfe..457077462a6 100644
--- a/doc/administration/raketasks/doctor.md
+++ b/doc/administration/raketasks/doctor.md
@@ -6,4 +6,6 @@ remove_date: '2022-03-04'
This document was moved to [another location](check.md#verify-database-values-can-be-decrypted-using-the-current-secrets).
<!-- This redirect file can be deleted after 2022-03-04. -->
-<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/#move-or-rename-a-page -->
+<!-- Redirects that point to other docs in the same project expire in three months. -->
+<!-- Redirects that point to docs in a different project or site (for example, link is not relative and starts with `https:`) expire in one year. -->
+<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/redirects.html -->
diff --git a/doc/administration/reference_architectures/10k_users.md b/doc/administration/reference_architectures/10k_users.md
index eb1127b5e99..fcce44f62b2 100644
--- a/doc/administration/reference_architectures/10k_users.md
+++ b/doc/administration/reference_architectures/10k_users.md
@@ -1363,6 +1363,7 @@ To configure the Praefect nodes, on each one:
alertmanager['enable'] = false
grafana['enable'] = false
gitlab_exporter['enable'] = false
+ gitlab_kas['enable'] = false
nginx['enable'] = false
# Praefect Configuration
@@ -1503,6 +1504,7 @@ On each node:
alertmanager['enable'] = false
grafana['enable'] = false
gitlab_exporter['enable'] = false
+ gitlab_kas['enable'] = false
nginx['enable'] = false
# Prevent database migrations from running on upgrade automatically
@@ -1524,6 +1526,11 @@ On each node:
# Gitaly Auth Token
# Should be the same as praefect_internal_token
gitaly['auth_token'] = '<praefect_internal_token>'
+
+ # Gitaly Pack-objects cache
+ # Recommended to be enabled for improved performance but can notably increase disk I/O
+ # Refer to https://docs.gitlab.com/ee/administration/gitaly/configure_gitaly.html#pack-objects-cache for more info
+ gitaly['pack_objects_cache_enabled'] = true
```
1. Append the following to `/etc/gitlab/gitlab.rb` for each respective server:
@@ -1631,7 +1638,7 @@ To configure Praefect with TLS:
```ruby
git_data_dirs({
"default" => {
- "gitaly_address" => 'tls://LOAD_BALANCER_SERVER_ADDRESS:2305',
+ "gitaly_address" => 'tls://LOAD_BALANCER_SERVER_ADDRESS:3305',
"gitaly_token" => 'PRAEFECT_EXTERNAL_TOKEN'
}
})
@@ -1675,6 +1682,7 @@ To configure the Sidekiq nodes, on each one:
alertmanager['enable'] = false
grafana['enable'] = false
gitlab_exporter['enable'] = false
+ gitlab_kas['enable'] = false
nginx['enable'] = false
# External URL
diff --git a/doc/administration/reference_architectures/25k_users.md b/doc/administration/reference_architectures/25k_users.md
index 86819024eeb..c08fe985b40 100644
--- a/doc/administration/reference_architectures/25k_users.md
+++ b/doc/administration/reference_architectures/25k_users.md
@@ -1367,6 +1367,7 @@ To configure the Praefect nodes, on each one:
alertmanager['enable'] = false
grafana['enable'] = false
gitlab_exporter['enable'] = false
+ gitlab_kas['enable'] = false
nginx['enable'] = false
# Praefect Configuration
@@ -1507,6 +1508,7 @@ On each node:
alertmanager['enable'] = false
grafana['enable'] = false
gitlab_exporter['enable'] = false
+ gitlab_kas['enable'] = false
nginx['enable'] = false
# Prevent database migrations from running on upgrade automatically
@@ -1528,6 +1530,11 @@ On each node:
# Gitaly Auth Token
# Should be the same as praefect_internal_token
gitaly['auth_token'] = '<praefect_internal_token>'
+
+ # Gitaly Pack-objects cache
+ # Recommended to be enabled for improved performance but can notably increase disk I/O
+ # Refer to https://docs.gitlab.com/ee/administration/gitaly/configure_gitaly.html#pack-objects-cache for more info
+ gitaly['pack_objects_cache_enabled'] = true
```
1. Append the following to `/etc/gitlab/gitlab.rb` for each respective server:
@@ -1635,7 +1642,7 @@ To configure Praefect with TLS:
```ruby
git_data_dirs({
"default" => {
- "gitaly_address" => 'tls://LOAD_BALANCER_SERVER_ADDRESS:2305',
+ "gitaly_address" => 'tls://LOAD_BALANCER_SERVER_ADDRESS:3305',
"gitaly_token" => 'PRAEFECT_EXTERNAL_TOKEN'
}
})
@@ -1679,6 +1686,7 @@ To configure the Sidekiq nodes, on each one:
alertmanager['enable'] = false
grafana['enable'] = false
gitlab_exporter['enable'] = false
+ gitlab_kas['enable'] = false
nginx['enable'] = false
# External URL
diff --git a/doc/administration/reference_architectures/2k_users.md b/doc/administration/reference_architectures/2k_users.md
index f6c484b08b1..6f6c02c309a 100644
--- a/doc/administration/reference_architectures/2k_users.md
+++ b/doc/administration/reference_architectures/2k_users.md
@@ -286,11 +286,6 @@ further configuration steps.
```ruby
# Disable all components except PostgreSQL related ones
roles(['postgres_role'])
- 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'
@@ -365,19 +360,7 @@ Omnibus:
```ruby
## Enable Redis
- redis['enable'] = true
-
- # Avoid running unnecessary services on the Redis server
- gitaly['enable'] = false
- postgresql['enable'] = false
- puma['enable'] = false
- sidekiq['enable'] = false
- gitlab_workhorse['enable'] = false
- prometheus['enable'] = false
- alertmanager['enable'] = false
- grafana['enable'] = false
- gitlab_exporter['enable'] = false
- nginx['enable'] = false
+ roles(["redis_master_role"])
redis['bind'] = '0.0.0.0'
redis['port'] = 6379
@@ -481,6 +464,7 @@ To configure the Gitaly server, on the server node you want to use for Gitaly:
alertmanager['enable'] = false
grafana['enable'] = false
gitlab_exporter['enable'] = false
+ gitlab_kas['enable'] = false
nginx['enable'] = false
# Prevent database migrations from running on upgrade automatically
diff --git a/doc/administration/reference_architectures/3k_users.md b/doc/administration/reference_architectures/3k_users.md
index 587303a1f8f..76f81e65580 100644
--- a/doc/administration/reference_architectures/3k_users.md
+++ b/doc/administration/reference_architectures/3k_users.md
@@ -1307,6 +1307,7 @@ To configure the Praefect nodes, on each one:
alertmanager['enable'] = false
grafana['enable'] = false
gitlab_exporter['enable'] = false
+ gitlab_kas['enable'] = false
nginx['enable'] = false
# Praefect Configuration
@@ -1447,6 +1448,7 @@ On each node:
alertmanager['enable'] = false
grafana['enable'] = false
gitlab_exporter['enable'] = false
+ gitlab_kas['enable'] = false
nginx['enable'] = false
# Prevent database migrations from running on upgrade automatically
@@ -1468,6 +1470,11 @@ On each node:
# Gitaly Auth Token
# Should be the same as praefect_internal_token
gitaly['auth_token'] = '<praefect_internal_token>'
+
+ # Gitaly Pack-objects cache
+ # Recommended to be enabled for improved performance but can notably increase disk I/O
+ # Refer to https://docs.gitlab.com/ee/administration/gitaly/configure_gitaly.html#pack-objects-cache for more info
+ gitaly['pack_objects_cache_enabled'] = true
```
1. Append the following to `/etc/gitlab/gitlab.rb` for each respective server:
@@ -1575,7 +1582,7 @@ To configure Praefect with TLS:
```ruby
git_data_dirs({
"default" => {
- "gitaly_address" => 'tls://LOAD_BALANCER_SERVER_ADDRESS:2305',
+ "gitaly_address" => 'tls://LOAD_BALANCER_SERVER_ADDRESS:3305',
"gitaly_token" => 'PRAEFECT_EXTERNAL_TOKEN'
}
})
@@ -1621,6 +1628,7 @@ To configure the Sidekiq nodes, one each one:
alertmanager['enable'] = false
grafana['enable'] = false
gitlab_exporter['enable'] = false
+ gitlab_kas['enable'] = false
nginx['enable'] = false
# External URL
diff --git a/doc/administration/reference_architectures/50k_users.md b/doc/administration/reference_architectures/50k_users.md
index f4bf232d548..dfa963d1ad0 100644
--- a/doc/administration/reference_architectures/50k_users.md
+++ b/doc/administration/reference_architectures/50k_users.md
@@ -1376,6 +1376,7 @@ To configure the Praefect nodes, on each one:
alertmanager['enable'] = false
grafana['enable'] = false
gitlab_exporter['enable'] = false
+ gitlab_kas['enable'] = false
nginx['enable'] = false
# Praefect Configuration
@@ -1516,6 +1517,7 @@ On each node:
alertmanager['enable'] = false
grafana['enable'] = false
gitlab_exporter['enable'] = false
+ gitlab_kas['enable'] = false
nginx['enable'] = false
# Prevent database migrations from running on upgrade automatically
@@ -1537,6 +1539,11 @@ On each node:
# Gitaly Auth Token
# Should be the same as praefect_internal_token
gitaly['auth_token'] = '<praefect_internal_token>'
+
+ # Gitaly Pack-objects cache
+ # Recommended to be enabled for improved performance but can notably increase disk I/O
+ # Refer to https://docs.gitlab.com/ee/administration/gitaly/configure_gitaly.html#pack-objects-cache for more info
+ gitaly['pack_objects_cache_enabled'] = true
```
1. Append the following to `/etc/gitlab/gitlab.rb` for each respective server:
@@ -1644,7 +1651,7 @@ To configure Praefect with TLS:
```ruby
git_data_dirs({
"default" => {
- "gitaly_address" => 'tls://LOAD_BALANCER_SERVER_ADDRESS:2305',
+ "gitaly_address" => 'tls://LOAD_BALANCER_SERVER_ADDRESS:3305',
"gitaly_token" => 'PRAEFECT_EXTERNAL_TOKEN'
}
})
@@ -1688,6 +1695,7 @@ To configure the Sidekiq nodes, on each one:
alertmanager['enable'] = false
grafana['enable'] = false
gitlab_exporter['enable'] = false
+ gitlab_kas['enable'] = false
nginx['enable'] = false
# External URL
diff --git a/doc/administration/reference_architectures/5k_users.md b/doc/administration/reference_architectures/5k_users.md
index 4014ec04904..f2463afbf3b 100644
--- a/doc/administration/reference_architectures/5k_users.md
+++ b/doc/administration/reference_architectures/5k_users.md
@@ -1305,6 +1305,7 @@ To configure the Praefect nodes, on each one:
alertmanager['enable'] = false
grafana['enable'] = false
gitlab_exporter['enable'] = false
+ gitlab_kas['enable'] = false
nginx['enable'] = false
# Praefect Configuration
@@ -1445,6 +1446,7 @@ On each node:
alertmanager['enable'] = false
grafana['enable'] = false
gitlab_exporter['enable'] = false
+ gitlab_kas['enable'] = false
nginx['enable'] = false
# Prevent database migrations from running on upgrade automatically
@@ -1466,6 +1468,11 @@ On each node:
# Gitaly Auth Token
# Should be the same as praefect_internal_token
gitaly['auth_token'] = '<praefect_internal_token>'
+
+ # Gitaly Pack-objects cache
+ # Recommended to be enabled for improved performance but can notably increase disk I/O
+ # Refer to https://docs.gitlab.com/ee/administration/gitaly/configure_gitaly.html#pack-objects-cache for more info
+ gitaly['pack_objects_cache_enabled'] = true
```
1. Append the following to `/etc/gitlab/gitlab.rb` for each respective server:
@@ -1573,7 +1580,7 @@ To configure Praefect with TLS:
```ruby
git_data_dirs({
"default" => {
- "gitaly_address" => 'tls://LOAD_BALANCER_SERVER_ADDRESS:2305',
+ "gitaly_address" => 'tls://LOAD_BALANCER_SERVER_ADDRESS:3305',
"gitaly_token" => 'PRAEFECT_EXTERNAL_TOKEN'
}
})
@@ -1617,6 +1624,7 @@ To configure the Sidekiq nodes, one each one:
alertmanager['enable'] = false
grafana['enable'] = false
gitlab_exporter['enable'] = false
+ gitlab_kas['enable'] = false
nginx['enable'] = false
# External URL
diff --git a/doc/administration/reference_architectures/index.md b/doc/administration/reference_architectures/index.md
index 815155866e8..3fcd6d7ae4e 100644
--- a/doc/administration/reference_architectures/index.md
+++ b/doc/administration/reference_architectures/index.md
@@ -103,12 +103,14 @@ The following table details the testing done against the reference architectures
<style>
table.test-coverage td {
+ border-top: 1px solid #dbdbdb;
border-left: 1px solid #dbdbdb;
border-right: 1px solid #dbdbdb;
border-bottom: 1px solid #dbdbdb;
}
table.test-coverage th {
+ border-top: 1px solid #dbdbdb;
border-left: 1px solid #dbdbdb;
border-right: 1px solid #dbdbdb;
border-bottom: 1px solid #dbdbdb;
@@ -131,7 +133,6 @@ table.test-coverage th {
<th scope="col">Omnibus</th>
<th scope="col">Cloud Native Hybrid</th>
<th scope="col">Omnibus</th>
- <th scope="col">Cloud Native Hybrid</th>
</tr>
<tr>
<th scope="row">1k</th>
@@ -140,7 +141,6 @@ table.test-coverage th {
<td></td>
<td></td>
<td></td>
- <td></td>
</tr>
<tr>
<th scope="row">2k</th>
@@ -149,7 +149,6 @@ table.test-coverage th {
<td></td>
<td></td>
<td></td>
- <td></td>
</tr>
<tr>
<th scope="row">3k</th>
@@ -158,7 +157,6 @@ table.test-coverage th {
<td></td>
<td></td>
<td></td>
- <td></td>
</tr>
<tr>
<th scope="row">5k</th>
@@ -167,7 +165,6 @@ table.test-coverage th {
<td></td>
<td></td>
<td></td>
- <td></td>
</tr>
<tr>
<th scope="row">10k</th>
@@ -176,7 +173,6 @@ table.test-coverage th {
<td><a href="https://gitlab.com/gitlab-org/quality/performance/-/wikis/Past-Results/10k">Ad-Hoc (inc Cloud Services)</a></td>
<td><a href="https://gitlab.com/gitlab-org/quality/performance/-/wikis/Past-Results/10k-Cloud-Native-Hybrid">Ad-Hoc</a></td>
<td><a href="https://gitlab.com/gitlab-org/quality/performance/-/wikis/Past-Results/10k">Ad-Hoc</a></td>
- <td></td>
</tr>
<tr>
<th scope="row">25k</th>
@@ -185,7 +181,6 @@ table.test-coverage th {
<td></td>
<td></td>
<td><a href="https://gitlab.com/gitlab-org/quality/performance/-/wikis/Past-Results/25k">Ad-Hoc</a></td>
- <td></td>
</tr>
<tr>
<th scope="row">50k</th>
@@ -194,7 +189,6 @@ table.test-coverage th {
<td><a href="https://gitlab.com/gitlab-org/quality/performance/-/wikis/Past-Results/50k">Ad-Hoc (inc Cloud Services)</a></td>
<td></td>
<td></td>
- <td></td>
</tr>
</table>
@@ -218,7 +212,6 @@ The Standard Reference Architectures are designed to be platform agnostic, with
<th scope="col">Omnibus</th>
<th scope="col">Cloud Native Hybrid</th>
<th scope="col">Omnibus</th>
- <th scope="col">Cloud Native Hybrid</th>
</tr>
<tr>
<th scope="row">1k</th>
@@ -227,7 +220,6 @@ The Standard Reference Architectures are designed to be platform agnostic, with
<td></td>
<td></td>
<td></td>
- <td></td>
</tr>
<tr>
<th scope="row">2k</th>
@@ -236,7 +228,6 @@ The Standard Reference Architectures are designed to be platform agnostic, with
<td></td>
<td></td>
<td></td>
- <td></td>
</tr>
<tr>
<th scope="row">3k</th>
@@ -245,7 +236,6 @@ The Standard Reference Architectures are designed to be platform agnostic, with
<td></td>
<td></td>
<td></td>
- <td></td>
</tr>
<tr>
<th scope="row">5k</th>
@@ -254,7 +244,6 @@ The Standard Reference Architectures are designed to be platform agnostic, with
<td></td>
<td></td>
<td></td>
- <td></td>
</tr>
<tr>
<th scope="row">10k</th>
@@ -263,7 +252,6 @@ The Standard Reference Architectures are designed to be platform agnostic, with
<td></td>
<td></td>
<td></td>
- <td></td>
</tr>
<tr>
<th scope="row">25k</th>
@@ -272,7 +260,6 @@ The Standard Reference Architectures are designed to be platform agnostic, with
<td></td>
<td></td>
<td></td>
- <td></td>
</tr>
<tr>
<th scope="row">50k</th>
@@ -281,10 +268,92 @@ The Standard Reference Architectures are designed to be platform agnostic, with
<td></td>
<td></td>
<td></td>
+ </tr>
+</table>
+
+### Recommended cloud providers and services
+
+NOTE:
+The following lists are non exhaustive. Generally, other cloud providers not listed
+here will likely work with the same specs, but this hasn't been validated.
+Additionally, when it comes to other cloud provider services not listed here,
+it's advised to be cautious as each implementation can be notably different
+and should be tested thoroughly before production use.
+
+Through testing and real life usage, the Reference Architectures are validated and supported on the following cloud providers:
+
+<table>
+<thead>
+ <tr>
+ <th>Reference Architecture</th>
+ <th>GCP</th>
+ <th>AWS</th>
+ <th>Azure</th>
+ <th>Bare Metal</th>
+ </tr>
+</thead>
+<tbody>
+ <tr>
+ <td>Omnibus</td>
+ <td>✅</td>
+ <td>✅</td>
+ <td>✅</td>
+ <td>✅</td>
+ </tr>
+ <tr>
+ <td>Cloud Native Hybrid</td>
+ <td>✅</td>
+ <td>✅</td>
+ <td></td>
+ <td></td>
+ </tr>
+</tbody>
+</table>
+
+Additionally, the following cloud provider services are validated and supported for use as part of the Reference Architectures:
+
+<table>
+<thead>
+ <tr>
+ <th>Cloud Service</th>
+ <th>GCP</th>
+ <th>AWS</th>
+ <th>Bare Metal</th>
+ </tr>
+</thead>
+<tbody>
+ <tr>
+ <td>Object Storage</td>
+ <td>✅ &nbsp; <a href="https://cloud.google.com/storage" target="_blank">Cloud Storage</a></td>
+ <td>✅ &nbsp; <a href="https://aws.amazon.com/s3/" target="_blank">S3</a></td>
+ <td>✅ &nbsp; <a href="https://min.io/" target="_blank">MinIO</a></td>
+ </tr>
+ <tr>
+ <td>Database</td>
+ <td>✅ &nbsp; <a href="https://cloud.google.com/sql" target="_blank" rel="noopener noreferrer">Cloud SQL</a></td>
+ <td>✅ &nbsp; <a href="https://aws.amazon.com/rds/" target="_blank" rel="noopener noreferrer">RDS</a></td>
+ <td></td>
+ </tr>
+ <tr>
+ <td>Redis</td>
+ <td></td>
+ <td>✅ &nbsp; <a href="https://aws.amazon.com/elasticache/" target="_blank" rel="noopener noreferrer">Elasticache</a></td>
<td></td>
</tr>
+</tbody>
</table>
+The following specific cloud provider services have been found to have issues in terms of either functionality or performance. As such, they either have caveats that should be considered or are not recommended:
+
+- [Azure Blob Storage](https://azure.microsoft.com/en-gb/services/storage/blobs/) has been found to have performance limits that can impact production use at certain times. For larger Reference Architectures the service may not be sufficient for production use and an alternative is recommended for use instead.
+- [Azure Database for PostgreSQL Server](https://azure.microsoft.com/en-gb/services/postgresql/#overview) (Single / Flexible) is not recommended for use due to notable performance issues or missing functionality.
+- [AWS Aurora Database](https://aws.amazon.com/rds/aurora) is not recommended due to compatibility issues.
+
+NOTE:
+As a general rule we unfortunately don't recommend Azure Services at this time.
+If required, we advise thorough testing is done at your intended scale
+over a sustained period to validate if the service is suitable.
+
## Availability Components
GitLab comes with the following components for your use, listed from least to
diff --git a/doc/administration/reply_by_email.md b/doc/administration/reply_by_email.md
index 055f40ead64..13fa8450996 100644
--- a/doc/administration/reply_by_email.md
+++ b/doc/administration/reply_by_email.md
@@ -47,6 +47,8 @@ following headers, in this order:
1. `References` header
1. `Delivered-To` header
1. `Envelope-To` header
+1. `X-Envelope-To` header
+1. `Received` header
If it finds a reply key, it leaves your reply as a comment on
the entity the notification was about (issue, merge request, commit...).
diff --git a/doc/administration/repository_checks.md b/doc/administration/repository_checks.md
index 0591f5b3c40..6dd8faac65b 100644
--- a/doc/administration/repository_checks.md
+++ b/doc/administration/repository_checks.md
@@ -32,6 +32,12 @@ Instead of checking repositories manually, GitLab can be configured to run the c
When enabled, GitLab periodically runs a repository check on all project repositories and wiki
repositories to detect possible data corruption. A project is checked no more than once per month.
+Administrators can configure the frequency of repository checks. To edit the frequency:
+
+- For Omnibus GitLab installations, edit `gitlab_rails['repository_check_worker_cron']` in
+ `/etc/gitlab/gitlab.rb`.
+- For source-based installations, edit `[gitlab.cron_jobs.repository_check_worker]` in
+ `/home/git/gitlab/config/gitlab.yml`.
If any projects fail their repository checks, all GitLab administrators receive an email
notification of the situation. By default, this notification is sent out once a week at midnight at
diff --git a/doc/administration/restart_gitlab.md b/doc/administration/restart_gitlab.md
index 88909b2b9d8..44bfa153123 100644
--- a/doc/administration/restart_gitlab.md
+++ b/doc/administration/restart_gitlab.md
@@ -9,6 +9,9 @@ info: To determine the technical writer assigned to the Stage/Group associated w
Depending on how you installed GitLab, there are different methods to restart
its services.
+NOTE:
+A short downtime is expected for all methods.
+
## Omnibus installations
If you have used the [Omnibus packages](https://about.gitlab.com/install/) to install GitLab, then
@@ -90,8 +93,8 @@ application that powers Omnibus GitLab, makes sure that all things like director
permissions, and services are in place and in the same shape that they were
initially shipped.
-It also restarts GitLab components where needed, if any of their
-configuration files have changed.
+It also [restarts GitLab components](#how-to-restart-gitlab)
+where needed, if any of their configuration files have changed.
If you manually edit any files in `/var/opt/gitlab` that are managed by Chef,
running reconfigure reverts the changes AND restarts the services that
diff --git a/doc/administration/sidekiq.md b/doc/administration/sidekiq.md
index fea6ac9e554..b6c1c6a704e 100644
--- a/doc/administration/sidekiq.md
+++ b/doc/administration/sidekiq.md
@@ -217,6 +217,73 @@ To enable health checks for Sidekiq:
sudo gitlab-ctl reconfigure
```
+## Configure LDAP and user or group synchronization
+
+If you use LDAP for user and group management, you must add the LDAP configuration to your Sidekiq node as well as the LDAP
+synchronization worker. If the LDAP configuration and LDAP synchronization worker are not applied to your Sidekiq node,
+users and groups are not automatically synchronized.
+
+For more information about configuring LDAP for GitLab, see:
+
+- [GitLab LDAP configuration documentation](auth/ldap/index.md#configure-ldap)
+- [LDAP synchronization documentation](auth/ldap/ldap_synchronization.md#adjust-ldap-user-sync-schedule)
+
+To enable LDAP with the synchronization worker for Sidekiq:
+
+1. Edit `/etc/gitlab/gitlab.rb`:
+
+ ```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',
+ '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,
+
+ # Enterprise Edition only
+ # https://docs.gitlab.com/ee/administration/auth/ldap/ldap_synchronization.html
+ 'group_base' => '',
+ 'admin_group' => '',
+ 'external_groups' => [],
+ 'sync_ssh_keys' => false
+ }
+ }
+ gitlab_rails['ldap_sync_worker_cron'] = "0 */12 * * *"
+ ```
+
+1. Reconfigure GitLab:
+
+ ```shell
+ sudo gitlab-ctl reconfigure
+ ```
+
## Related topics
- [Extra Sidekiq processes](operations/extra_sidekiq_processes.md)
diff --git a/doc/administration/terraform_state.md b/doc/administration/terraform_state.md
index d1113125c4e..5e8f7cb18bb 100644
--- a/doc/administration/terraform_state.md
+++ b/doc/administration/terraform_state.md
@@ -141,10 +141,10 @@ You can optionally track progress and verify that all packages migrated successf
- `sudo gitlab-rails dbconsole` for Omnibus GitLab instances.
- `sudo -u git -H psql -d gitlabhq_production` for source-installed instances.
-Verify `objectstg` below (where `store=2`) has count of all states:
+Verify `objectstg` below (where `file_store=2`) has count of all states:
```shell
-gitlabhq_production=# SELECT count(*) AS total, sum(case when store = '1' then 1 else 0 end) AS filesystem, sum(case when store = '2' then 1 else 0 end) AS objectstg FROM terraform_states;
+gitlabhq_production=# SELECT count(*) AS total, sum(case when file_store = '1' then 1 else 0 end) AS filesystem, sum(case when file_store = '2' then 1 else 0 end) AS objectstg FROM terraform_states;
total | filesystem | objectstg
------+------------+-----------
diff --git a/doc/administration/troubleshooting/debug.md b/doc/administration/troubleshooting/debug.md
index 744e12d4da1..0520ce470cb 100644
--- a/doc/administration/troubleshooting/debug.md
+++ b/doc/administration/troubleshooting/debug.md
@@ -225,7 +225,7 @@ gitlab_rails['env'] = {
```
For source installations, set the environment variable.
-Refer to [Puma Worker timeout](../operations/puma.md#worker-timeout).
+Refer to [Puma Worker timeout](../operations/puma.md#change-the-worker-timeout).
[Reconfigure](../restart_gitlab.md#omnibus-gitlab-reconfigure) GitLab for the changes to take effect.
diff --git a/doc/administration/troubleshooting/gitlab_rails_cheat_sheet.md b/doc/administration/troubleshooting/gitlab_rails_cheat_sheet.md
index 265c5278fd6..1c948771f5b 100644
--- a/doc/administration/troubleshooting/gitlab_rails_cheat_sheet.md
+++ b/doc/administration/troubleshooting/gitlab_rails_cheat_sheet.md
@@ -771,6 +771,26 @@ group.require_two_factor_authentication=false
group.save
```
+### Check and toggle a feature for all projects in a group
+
+```ruby
+projects = Group.find_by_name('_group_name').projects
+projects.each do |p|
+ state = p.<feature-name>?
+
+ if state
+ puts "#{p.name} has <feature-name> already enabled. Skipping..."
+ else
+ puts "#{p.name} didn't have <feature-name> enabled. Enabling..."
+ p.project_feature.update!(builds_access_level: ProjectFeature::PRIVATE)
+ end
+end
+```
+
+To find features that can be toggled, run `pp p.project_feature`.
+Available permission levels are listed in
+[concerns/featurable.rb](https://gitlab.com/gitlab-org/gitlab/blob/master/app/models/concerns/featurable.rb).
+
## Authentication
### Re-enable standard web sign-in form
@@ -1023,7 +1043,7 @@ This is needed for example in a known edge-case with
### Remove licenses
-To clean up the [License History table](../../user/admin_area/license.md#view-license-details-and-history):
+To clean up the [License History table](../../user/admin_area/license_file.md#view-license-details-and-history):
```ruby
TYPE = :trial?
diff --git a/doc/administration/troubleshooting/img/AzureAD-scim_provisioning.png b/doc/administration/troubleshooting/img/AzureAD-scim_provisioning.png
index b8edcfa31c2..b2c385151a6 100644
--- a/doc/administration/troubleshooting/img/AzureAD-scim_provisioning.png
+++ b/doc/administration/troubleshooting/img/AzureAD-scim_provisioning.png
Binary files differ
diff --git a/doc/administration/troubleshooting/linux_cheat_sheet.md b/doc/administration/troubleshooting/linux_cheat_sheet.md
index b66e88a8d60..913437c2d77 100644
--- a/doc/administration/troubleshooting/linux_cheat_sheet.md
+++ b/doc/administration/troubleshooting/linux_cheat_sheet.md
@@ -14,7 +14,7 @@ having an issue with GitLab, you may want to check your [support options](https:
first, before attempting to use this information.
WARNING:
-If you administer GitLab you are expected to know these commands for your distribution
+It is [beyond the scope of GitLab Support to assist in systems administration](https://about.gitlab.com/support/statement-of-support.html#training). GitLab administrators are expected to know these commands for their distribution
of choice. If you are a GitLab Support Engineer, consider this a cross-reference to
translate `yum` -> `apt-get` and the like.
diff --git a/doc/administration/troubleshooting/postgresql.md b/doc/administration/troubleshooting/postgresql.md
index 47fd424b1fd..d0ed3c5c12a 100644
--- a/doc/administration/troubleshooting/postgresql.md
+++ b/doc/administration/troubleshooting/postgresql.md
@@ -107,6 +107,10 @@ This section is for links to information elsewhere in the GitLab documentation.
To fix this, see [Backup and restore a non-packaged PostgreSQL database](https://docs.gitlab.com/omnibus/settings/database.html#backup-and-restore-a-non-packaged-postgresql-database).
+- Deploying PostgreSQL on Azure Database for PostgreSQL - Flexible Server may result in an error stating `extension "btree_gist" is not allow-listed for "azure_pg_admin" users in Azure Database for PostgreSQL`
+
+ To resolve the above error, [allow-list the extension](https://docs.microsoft.com/en-us/azure/postgresql/flexible-server/concepts-extensions#how-to-use-postgresql-extensions) prior to install.
+
## Support topics
### Database deadlocks
diff --git a/doc/administration/uploads.md b/doc/administration/uploads.md
index 55c3f85bfb9..aba7b5fc318 100644
--- a/doc/administration/uploads.md
+++ b/doc/administration/uploads.md
@@ -67,7 +67,7 @@ For source installations the following settings are nested under `uploads:` and
|---------|-------------|---------|
| `enabled` | Enable/disable object storage | `false` |
| `remote_directory` | The bucket name where Uploads will be stored| |
-| `direct_upload` | Set to `true` to remove Puma from the Upload path. Workhorse handles the actual Artifact Upload to Object Storage while Puma does minimal processing to keep track of the upload. There is no need for local shared storage. The option may be removed if support for a single storage type for all files is introduced. Read more on [direct upload](../development/uploads.md#direct-upload). | `false` |
+| `direct_upload` | Set to `true` to remove Puma from the Upload path. Workhorse handles the actual Artifact Upload to Object Storage while Puma does minimal processing to keep track of the upload. There is no need for local shared storage. The option may be removed if support for a single storage type for all files is introduced. Read more on [direct upload](../development/uploads/implementation.md#direct-upload). | `false` |
| `background_upload` | Set to `false` to disable automatic upload. Option may be removed once upload is direct to S3 (if `direct_upload` is set to `true` it will override `background_upload`) | `true` |
| `proxy_download` | Set to `true` to enable proxying all files served. Option allows to reduce egress traffic as this allows clients to download directly from remote storage instead of proxying all data | `false` |
| `connection` | Various connection options described below | |
diff --git a/doc/api/alert_management_alerts.md b/doc/api/alert_management_alerts.md
new file mode 100644
index 00000000000..2323cecfd6a
--- /dev/null
+++ b/doc/api/alert_management_alerts.md
@@ -0,0 +1,129 @@
+---
+stage: Monitor
+group: Respond
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
+---
+
+# Alert Management alerts API **(FREE)**
+
+The Alert Management alerts API is limited to metric images. For more API endpoints, see the
+[GraphQL API](graphql/reference/index.md#alertmanagementalert).
+
+## Upload metric image
+
+```plaintext
+POST /projects/:id/alert_management_alerts/:alert_iid/metric_images
+```
+
+| Attribute | Type | Required | Description |
+|-------------|---------|----------|--------------------------------------|
+| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user. |
+| `alert_iid` | integer | yes | The internal ID of a project's alert. |
+
+```shell
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" --form 'file=@/path/to/file.png' \
+--form 'url=http://example.com' --form 'url_text=Example website' "https://gitlab.example.com/api/v4/projects/5/alert_management_alerts/93/metric_images"
+```
+
+Example response:
+
+```json
+{
+ "id": 17,
+ "created_at": "2020-11-12T20:07:58.156Z",
+ "filename": "sample_2054",
+ "file_path": "/uploads/-/system/alert_metric_image/file/17/sample_2054.png",
+ "url": "example.com/metric",
+ "url_text": "An example metric"
+}
+```
+
+## List metric images
+
+```plaintext
+GET /projects/:id/alert_management_alerts/:alert_iid/metric_images
+```
+
+| Attribute | Type | Required | Description |
+|-------------|---------|----------|--------------------------------------|
+| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user. |
+| `alert_iid` | integer | yes | The internal ID of a project's alert. |
+
+```shell
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/alert_management_alerts/93/metric_images"
+```
+
+Example response:
+
+```json
+[
+ {
+ "id": 17,
+ "created_at": "2020-11-12T20:07:58.156Z",
+ "filename": "sample_2054",
+ "file_path": "/uploads/-/system/alert_metric_image/file/17/sample_2054.png",
+ "url": "example.com/metric",
+ "url_text": "An example metric"
+ },
+ {
+ "id": 18,
+ "created_at": "2020-11-12T20:14:26.441Z",
+ "filename": "sample_2054",
+ "file_path": "/uploads/-/system/alert_metric_image/file/18/sample_2054.png",
+ "url": "example.com/metric",
+ "url_text": "An example metric"
+ }
+]
+```
+
+## Update metric image
+
+```plaintext
+PUT /projects/:id/alert_management_alerts/:alert_iid/metric_image/:image_id
+```
+
+| Attribute | Type | Required | Description |
+|-------------|---------|----------|--------------------------------------|
+| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user. |
+| `alert_iid` | integer | yes | The internal ID of a project's alert. |
+| `image_id` | integer | yes | The ID of the image. |
+| `url` | string | no | The URL to view more metrics information. |
+| `url_text` | string | no | A description of the image or URL. |
+
+```shell
+curl --header "PRIVATE-TOKEN: <your_access_token>" --request PUT --form 'url=http://example.com' --form 'url_text=Example website' "https://gitlab.example.com/api/v4/projects/5/alert_management_alerts/93/metric_images/1"
+```
+
+Example response:
+
+```json
+{
+ "id": 23,
+ "created_at": "2020-11-13T00:06:18.084Z",
+ "filename": "file.png",
+ "file_path": "/uploads/-/system/alert_metric_image/file/23/file.png",
+ "url": "http://example.com",
+ "url_text": "Example website"
+}
+```
+
+## Delete metric image
+
+```plaintext
+DELETE /projects/:id/alert_management_alerts/:alert_iid/metric_images/:image_id
+```
+
+| Attribute | Type | Required | Description |
+|-------------|---------|----------|--------------------------------------|
+| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user. |
+| `alert_iid` | integer | yes | The internal ID of a project's alert. |
+| `image_id` | integer | yes | The ID of the image. |
+
+```shell
+curl --header "PRIVATE-TOKEN: <your_access_token>" --request DELETE "https://gitlab.example.com/api/v4/projects/5/alert_management_alerts/93/metric_images/1"
+```
+
+Can return the following status codes:
+
+- `204 No Content`: if the image was deleted successfully.
+- `422 Unprocessable`: if the image could not be deleted.
diff --git a/doc/api/api_resources.md b/doc/api/api_resources.md
index 3d54402ea0b..eabaa4217b5 100644
--- a/doc/api/api_resources.md
+++ b/doc/api/api_resources.md
@@ -118,6 +118,7 @@ The following API resources are available in the group context:
| [Invitations](invitations.md) | `/groups/:id/invitations` (also available for projects) |
| [Issues](issues.md) | `/groups/:id/issues` (also available for projects and standalone) |
| [Issues Statistics](issues_statistics.md) | `/groups/:id/issues_statistics` (also available for projects and standalone) |
+| [Linked epics](linked_epics.md) | `/groups/:id/epics/.../related_epics` |
| [Members](members.md) | `/groups/:id/members` (also available for projects) |
| [Merge requests](merge_requests.md) | `/groups/:id/merge_requests` (also available for projects and standalone) |
| [Notes](notes.md) (comments) | `/groups/:id/epics/.../notes` (also available for projects) |
diff --git a/doc/api/broadcast_messages.md b/doc/api/broadcast_messages.md
index 5aca0667f31..a14de8dadd3 100644
--- a/doc/api/broadcast_messages.md
+++ b/doc/api/broadcast_messages.md
@@ -6,6 +6,8 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Broadcast Messages API **(FREE SELF)**
+> 'target_access_levels' [introduced](https://gitlab.com/gitlab-org/growth/team-tasks/-/issues/461) in GitLab 14.8 [with a flag](../administration/feature_flags.md) named `role_targeted_broadcast_messages`. Disabled by default.
+
Broadcast messages API operates on [broadcast messages](../user/admin_area/broadcast_messages.md).
As of GitLab 12.8, GET requests do not require authentication. All other broadcast message API endpoints are accessible only to administrators. Non-GET requests by:
@@ -39,6 +41,7 @@ Example response:
"font":"#FFFFFF",
"id":1,
"active": false,
+ "target_access_levels": [10,30],
"target_path": "*/welcome",
"broadcast_type": "banner",
"dismissable": false
@@ -77,6 +80,7 @@ Example response:
"font":"#FFFFFF",
"id":1,
"active":false,
+ "target_access_levels": [10,30],
"target_path": "*/welcome",
"broadcast_type": "banner",
"dismissable": false
@@ -93,21 +97,31 @@ POST /broadcast_messages
Parameters:
-| Attribute | Type | Required | Description |
-|:----------------|:---------|:---------|:------------------------------------------------------|
-| `message` | string | yes | Message to display. |
-| `starts_at` | datetime | no | Starting time (defaults to current time). Expected in ISO 8601 format (`2019-03-15T08:00:00Z`) |
-| `ends_at` | datetime | no | Ending time (defaults to one hour from current time). Expected in ISO 8601 format (`2019-03-15T08:00:00Z`) |
-| `color` | string | no | Background color hex code. |
-| `font` | string | no | Foreground color hex code. |
-| `target_path` | string | no | Target path of the broadcast message. |
-| `broadcast_type`| string | no | Appearance type (defaults to banner) |
-| `dismissable` | boolean | no | Can the user dismiss the message? |
+| Attribute | Type | Required | Description |
+|:-----------------------|:------------------|:---------|:------------------------------------------------------|
+| `message` | string | yes | Message to display. |
+| `starts_at` | datetime | no | Starting time (defaults to current time). Expected in ISO 8601 format (`2019-03-15T08:00:00Z`) |
+| `ends_at` | datetime | no | Ending time (defaults to one hour from current time). Expected in ISO 8601 format (`2019-03-15T08:00:00Z`) |
+| `color` | string | no | Background color hex code. |
+| `font` | string | no | Foreground color hex code. |
+| `target_access_levels` | array of integers | no | Target access levels (roles) of the broadcast message.|
+| `target_path` | string | no | Target path of the broadcast message. |
+| `broadcast_type` | string | no | Appearance type (defaults to banner) |
+| `dismissable` | boolean | no | Can the user dismiss the message? |
+
+The `target_access_levels` are defined in the `Gitlab::Access` module. The
+following levels are valid:
+
+- Guest (`10`)
+- Reporter (`20`)
+- Developer (`30`)
+- Maintainer (`40`)
+- Owner (`50`)
Example request:
```shell
-curl --data "message=Deploy in progress&color=#cecece" \
+curl --data "message=Deploy in progress&color=#cecece&target_access_levels[]=10&target_access_levels[]=30" \
--header "PRIVATE-TOKEN: <your_access_token>" \
"https://gitlab.example.com/api/v4/broadcast_messages"
```
@@ -123,6 +137,7 @@ Example response:
"font":"#FFFFFF",
"id":1,
"active": true,
+ "target_access_levels": [10,30],
"target_path": "*/welcome",
"broadcast_type": "notification",
"dismissable": false
@@ -139,17 +154,27 @@ PUT /broadcast_messages/:id
Parameters:
-| Attribute | Type | Required | Description |
-|:----------------|:---------|:---------|:--------------------------------------|
-| `id` | integer | yes | ID of broadcast message to update. |
-| `message` | string | no | Message to display. |
-| `starts_at` | datetime | no | Starting time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`) |
-| `ends_at` | datetime | no | Ending time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`) |
-| `color` | string | no | Background color hex code. |
-| `font` | string | no | Foreground color hex code. |
-| `target_path` | string | no | Target path of the broadcast message. |
-| `broadcast_type`| string | no | Appearance type (defaults to banner) |
-| `dismissable` | boolean | no | Can the user dismiss the message? |
+| Attribute | Type | Required | Description |
+|:-----------------------|:------------------|:---------|:------------------------------------------------------|
+| `id` | integer | yes | ID of broadcast message to update. |
+| `message` | string | no | Message to display. |
+| `starts_at` | datetime | no | Starting time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`) |
+| `ends_at` | datetime | no | Ending time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`) |
+| `color` | string | no | Background color hex code. |
+| `font` | string | no | Foreground color hex code. |
+| `target_access_levels` | array of integers | no | Target access levels (roles) of the broadcast message.|
+| `target_path` | string | no | Target path of the broadcast message. |
+| `broadcast_type` | string | no | Appearance type (defaults to banner) |
+| `dismissable` | boolean | no | Can the user dismiss the message? |
+
+The `target_access_levels` are defined in the `Gitlab::Access` module. The
+following levels are valid:
+
+- Guest (`10`)
+- Reporter (`20`)
+- Developer (`30`)
+- Maintainer (`40`)
+- Owner (`50`)
Example request:
@@ -169,6 +194,7 @@ Example response:
"font":"#FFFFFF",
"id":1,
"active": true,
+ "target_access_levels": [10,30],
"target_path": "*/welcome",
"broadcast_type": "notification",
"dismissable": false
diff --git a/doc/api/container_registry.md b/doc/api/container_registry.md
index b61ec34b882..eb5a124c40c 100644
--- a/doc/api/container_registry.md
+++ b/doc/api/container_registry.md
@@ -210,10 +210,11 @@ GET /registry/repositories/:id
| `id` | integer/string | yes | The ID of the registry repository accessible by the authenticated user. |
| `tags` | boolean | no | If the parameter is included as `true`, the response includes an array of `"tags"`. |
| `tags_count` | boolean | no | If the parameter is included as `true`, the response includes `"tags_count"`. |
+| `size` | boolean | no | If the parameter is included as `true`, the response includes `"size"`. This is the deduplicated size of all images within the repository. Deduplication eliminates extra copies of identical data. For example, if you upload the same image twice, the Container Registry stores only one copy. This field is only available on GitLab.com for repositories created after `2021-11-04`. |
```shell
curl --header "PRIVATE-TOKEN: <your_access_token>" \
- "https://gitlab.example.com/api/v4/registry/repositories/2?tags=true&tags_count=true"
+ "https://gitlab.example.com/api/v4/registry/repositories/2?tags=true&tags_count=true&size=true"
```
Example response:
@@ -234,7 +235,8 @@ Example response:
"path": "group/project:0.0.1",
"location": "gitlab.example.com:5000/group/project:0.0.1"
}
- ]
+ ],
+ "size": 2818413
}
```
diff --git a/doc/api/dependencies.md b/doc/api/dependencies.md
index 6fb99d11f4f..85ad6085fb2 100644
--- a/doc/api/dependencies.md
+++ b/doc/api/dependencies.md
@@ -7,7 +7,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Dependencies API **(ULTIMATE)**
WARNING:
-This API is in an alpha stage and considered unstable.
+This API is in an [Alpha](../policy/alpha-beta-support.md#alpha-features) stage and considered unstable.
The response payload may be subject to change or breakage
across GitLab releases.
diff --git a/doc/api/deploy_tokens.md b/doc/api/deploy_tokens.md
index 77c2fe5e162..ace7e55f882 100644
--- a/doc/api/deploy_tokens.md
+++ b/doc/api/deploy_tokens.md
@@ -94,6 +94,46 @@ Example response:
]
```
+### Get a project deploy token
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/82467) in GitLab 14.9.
+
+Get a single project's deploy token by ID.
+
+```plaintext
+GET /projects/:id/deploy_tokens/:token_id
+```
+
+Parameters:
+
+| Attribute | Type | Required | Description |
+| ---------- | -------------- | ---------------------- | ----------- |
+| `id` | integer/string | **{check-circle}** Yes | ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user |
+| `token_id` | integer | **{check-circle}** Yes | ID of the deploy token |
+
+Example request:
+
+```shell
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/deploy_tokens/1"
+```
+
+Example response:
+
+```json
+{
+ "id": 1,
+ "name": "MyToken",
+ "username": "gitlab+deploy-token-1",
+ "expires_at": "2020-02-14T00:00:00.000Z",
+ "revoked": false,
+ "expired": false,
+ "scopes": [
+ "read_repository",
+ "read_registry"
+ ]
+}
+```
+
### Create a project deploy token
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/21811) in GitLab 12.9.
@@ -108,7 +148,7 @@ Parameters:
| Attribute | Type | Required | Description |
| ------------ | ---------------- | ---------------------- | ----------- |
-| `id` | integer/string | **{check-circle}** Yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user |
+| `id` | integer/string | **{check-circle}** Yes | ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user |
| `name` | string | **{check-circle}** Yes | New deploy token's name |
| `expires_at` | datetime | **{dotted-circle}** No | Expiration date for the deploy token. Does not expire if no value is provided. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`) |
| `username` | string | **{dotted-circle}** No | Username for deploy token. Default is `gitlab+deploy-token-{n}` |
@@ -153,8 +193,8 @@ Parameters:
| Attribute | Type | Required | Description |
| ---------- | -------------- | ---------------------- | ----------- |
-| `id` | integer/string | **{check-circle}** Yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user |
-| `token_id` | integer | **{check-circle}** Yes | The ID of the deploy token |
+| `id` | integer/string | **{check-circle}** Yes | ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user |
+| `token_id` | integer | **{check-circle}** Yes | ID of the deploy token |
Example request:
@@ -210,6 +250,46 @@ Example response:
]
```
+### Get a group deploy token
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/82467) in GitLab 14.9.
+
+Get a single group's deploy token by ID.
+
+```plaintext
+GET /groups/:id/deploy_tokens/:token_id
+```
+
+Parameters:
+
+| Attribute | Type | Required | Description |
+| ----------- | -------------- | ---------------------- | ----------- |
+| `id` | integer/string | **{check-circle}** Yes | ID or [URL-encoded path of the group](index.md#namespaced-path-encoding) owned by the authenticated user |
+| `token_id` | integer | **{check-circle}** Yes | ID of the deploy token |
+
+Example request:
+
+```shell
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/1/deploy_tokens/1"
+```
+
+Example response:
+
+```json
+{
+ "id": 1,
+ "name": "MyToken",
+ "username": "gitlab+deploy-token-1",
+ "expires_at": "2020-02-14T00:00:00.000Z",
+ "revoked": false,
+ "expired": false,
+ "scopes": [
+ "read_repository",
+ "read_registry"
+ ]
+}
+```
+
### Create a group deploy token
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/21811) in GitLab 12.9.
@@ -224,7 +304,7 @@ Parameters:
| Attribute | Type | Required | Description |
| ------------ | ---- | --------- | ----------- |
-| `id` | integer/string | **{check-circle}** Yes | The ID or [URL-encoded path of the group](index.md#namespaced-path-encoding) owned by the authenticated user |
+| `id` | integer/string | **{check-circle}** Yes | ID or [URL-encoded path of the group](index.md#namespaced-path-encoding) owned by the authenticated user |
| `name` | string | **{check-circle}** Yes | New deploy token's name |
| `expires_at` | datetime | **{dotted-circle}** No | Expiration date for the deploy token. Does not expire if no value is provided. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`) |
| `username` | string | **{dotted-circle}** No | Username for deploy token. Default is `gitlab+deploy-token-{n}` |
@@ -269,8 +349,8 @@ Parameters:
| Attribute | Type | Required | Description |
| ----------- | -------------- | ---------------------- | ----------- |
-| `id` | integer/string | **{check-circle}** Yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user |
-| `token_id` | integer | **{check-circle}** Yes | The ID of the deploy token |
+| `id` | integer/string | **{check-circle}** Yes | ID or [URL-encoded path of the group](index.md#namespaced-path-encoding) owned by the authenticated user |
+| `token_id` | integer | **{check-circle}** Yes | ID of the deploy token |
Example request:
diff --git a/doc/api/deployments.md b/doc/api/deployments.md
index 29f9bd3e2ee..4a09f9a6605 100644
--- a/doc/api/deployments.md
+++ b/doc/api/deployments.md
@@ -281,7 +281,8 @@ Deployments created by users on GitLab Premium or higher include the `approvals`
"avatar_url": "https://www.gravatar.com/avatar/e83ac685f68ea07553ad3054c738c709?s=80&d=identicon",
"web_url": "http://localhost:3000/project_6_bot"
},
- "status": "approved"
+ "status": "approved",
+ "created_at": "2022-02-24T20:22:30.097Z"
}
],
...
@@ -351,7 +352,8 @@ Deployments created by users on GitLab Premium or higher include the `approvals`
"avatar_url": "https://www.gravatar.com/avatar/e83ac685f68ea07553ad3054c738c709?s=80&d=identicon",
"web_url": "http://localhost:3000/project_6_bot"
},
- "status": "approved"
+ "status": "approved",
+ "created_at": "2022-02-24T20:22:30.097Z"
}
],
...
@@ -417,7 +419,8 @@ Deployments created by users on GitLab Premium or higher include the `approvals`
"avatar_url": "https://www.gravatar.com/avatar/e83ac685f68ea07553ad3054c738c709?s=80&d=identicon",
"web_url": "http://localhost:3000/project_6_bot"
},
- "status": "approved"
+ "status": "approved",
+ "created_at": "2022-02-24T20:22:30.097Z"
}
],
...
@@ -462,9 +465,10 @@ POST /projects/:id/deployments/:deployment_id/approval
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user. |
| `deployment_id` | integer | yes | The ID of the deployment. |
| `status` | string | yes | The status of the approval (either `approved` or `rejected`). |
+| `comment` | string | no | A comment to go with the approval |
```shell
-curl --data "status=approved" \
+curl --data "status=approved&comment=Looks good to me" \
--header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/deployments/1/approval"
```
@@ -480,6 +484,8 @@ Example response:
"avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",
"web_url": "http://localhost:3000/root"
},
- "status": "approved"
+ "status": "approved",
+ "created_at": "2022-02-24T20:22:30.097Z",
+ "comment":"Looks good to me"
}
```
diff --git a/doc/api/dora/metrics.md b/doc/api/dora/metrics.md
index 3f078945b0f..afc29f03598 100644
--- a/doc/api/dora/metrics.md
+++ b/doc/api/dora/metrics.md
@@ -9,6 +9,7 @@ type: reference, api
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/279039) in GitLab 13.10.
> - The legacy key/value pair `{ "<date>" => "<value>" }` was removed from the payload in GitLab 14.0.
+> `time_to_restore_service` metric was introduced in GitLab 14.9.
All methods require at least the Reporter role.
@@ -20,14 +21,14 @@ Get project-level DORA metrics.
GET /projects/:id/dora/metrics
```
-| Attribute | Type | Required | Description |
-|-------------- |-------- |----------|----------------------- |
-| `id` | integer/string | yes | The ID or [URL-encoded path of the project](../index.md#namespaced-path-encoding) can be accessed by the authenticated user. |
-| `metric` | string | yes | The [metric name](../../user/analytics/ci_cd_analytics.md#supported-metrics-in-gitlab). One of `deployment_frequency` or `lead_time_for_changes`. |
-| `start_date` | string | no | Date range to start from. ISO 8601 Date format, for example `2021-03-01`. Default is 3 months ago. |
-| `end_date` | string | no | Date range to end at. ISO 8601 Date format, for example `2021-03-01`. Default is the current date. |
-| `interval` | string | no | The bucketing interval. One of `all`, `monthly` or `daily`. Default is `daily`. |
-| `environment_tier` | string | no | The [tier of the environment](../../ci/environments/index.md#deployment-tier-of-environments). Default is `production`. |
+| Attribute | Type | Required | Description |
+|-------------- |-------- |----------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| `id` | integer/string | yes | The ID or [URL-encoded path of the project](../index.md#namespaced-path-encoding) can be accessed by the authenticated user. |
+| `metric` | string | yes | The [metric name](../../user/analytics/ci_cd_analytics.md#supported-metrics-in-gitlab). One of `deployment_frequency`, `lead_time_for_changes` or `time_to_restore_service`.|
+| `start_date` | string | no | Date range to start from. ISO 8601 Date format, for example `2021-03-01`. Default is 3 months ago. |
+| `end_date` | string | no | Date range to end at. ISO 8601 Date format, for example `2021-03-01`. Default is the current date. |
+| `interval` | string | no | The bucketing interval. One of `all`, `monthly` or `daily`. Default is `daily`. |
+| `environment_tier` | string | no | The [tier of the environment](../../ci/environments/index.md#deployment-tier-of-environments). Default is `production`. |
Example request:
@@ -63,7 +64,7 @@ GET /groups/:id/dora/metrics
| Attribute | Type | Required | Description |
|-------------- |-------- |----------|----------------------- |
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](../index.md#namespaced-path-encoding) can be accessed by the authenticated user. |
-| `metric` | string | yes | The [metric name](../../user/analytics/ci_cd_analytics.md#supported-metrics-in-gitlab). One of `deployment_frequency` or `lead_time_for_changes`. |
+| `metric` | string | yes | The [metric name](../../user/analytics/ci_cd_analytics.md#supported-metrics-in-gitlab). One of `deployment_frequency`, `lead_time_for_changes` or `time_to_restore_service`. |
| `start_date` | string | no | Date range to start from. ISO 8601 Date format, for example `2021-03-01`. Default is 3 months ago. |
| `end_date` | string | no | Date range to end at. ISO 8601 Date format, for example `2021-03-01`. Default is the current date. |
| `interval` | string | no | The bucketing interval. One of `all`, `monthly` or `daily`. Default is `daily`. |
@@ -97,6 +98,7 @@ API response has a different meaning depending on the provided `metric` query
parameter:
| `metric` query parameter | Description of `value` in response |
-| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
+| ------------------------ |--------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `deployment_frequency` | The number of successful deployments during the time period. |
| `lead_time_for_changes` | The median number of seconds between the merge of the merge request (MR) and the deployment of the MR's commits for all MRs deployed during the time period. |
+| `time_to_restore_service` | The median number of seconds an incident was open during the time period. Available only for production environment |
diff --git a/doc/api/environments.md b/doc/api/environments.md
index 8188e0e7b85..40d161485ff 100644
--- a/doc/api/environments.md
+++ b/doc/api/environments.md
@@ -35,7 +35,90 @@ Example response:
"name": "review/fix-foo",
"slug": "review-fix-foo-dfjre3",
"external_url": "https://review-fix-foo-dfjre3.gitlab.example.com",
- "state": "available"
+ "state": "available",
+ "created_at": "2019-05-25T18:55:13.252Z",
+ "updated_at": "2019-05-27T18:55:13.252Z",
+ "enable_advanced_logs_querying": false,
+ "logs_api_path": "/project/-/logs/k8s.json?environment_name=review%2Ffix-foo",
+ "last_deployment": {
+ "id": 100,
+ "iid": 34,
+ "ref": "fdroid",
+ "sha": "416d8ea11849050d3d1f5104cf8cf51053e790ab",
+ "created_at": "2019-03-25T18:55:13.252Z",
+ "status": "success",
+ "user": {
+ "id": 1,
+ "name": "Administrator",
+ "state": "active",
+ "username": "root",
+ "avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",
+ "web_url": "http://localhost:3000/root"
+ },
+ "deployable": {
+ "id": 710,
+ "status": "success",
+ "stage": "deploy",
+ "name": "staging",
+ "ref": "fdroid",
+ "tag": false,
+ "coverage": null,
+ "created_at": "2019-03-25T18:55:13.215Z",
+ "started_at": "2019-03-25T12:54:50.082Z",
+ "finished_at": "2019-03-25T18:55:13.216Z",
+ "duration": 21623.13423,
+ "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": null
+ },
+ "commit": {
+ "id": "416d8ea11849050d3d1f5104cf8cf51053e790ab",
+ "short_id": "416d8ea1",
+ "created_at": "2016-01-02T15:39:18.000Z",
+ "parent_ids": [
+ "e9a4449c95c64358840902508fc827f1a2eab7df"
+ ],
+ "title": "Removed fabric to fix #40",
+ "message": "Removed fabric to fix #40\n",
+ "author_name": "Administrator",
+ "author_email": "admin@example.com",
+ "authored_date": "2016-01-02T15:39:18.000Z",
+ "committer_name": "Administrator",
+ "committer_email": "admin@example.com",
+ "committed_date": "2016-01-02T15:39:18.000Z"
+ },
+ "pipeline": {
+ "id": 34,
+ "sha": "416d8ea11849050d3d1f5104cf8cf51053e790ab",
+ "ref": "fdroid",
+ "status": "success",
+ "web_url": "http://localhost:3000/Commit451/lab-coat/pipelines/34"
+ },
+ "web_url": "http://localhost:3000/Commit451/lab-coat/-/jobs/710",
+ "artifacts": [
+ {
+ "file_type": "trace",
+ "size": 1305,
+ "filename": "job.log",
+ "file_format": null
+ }
+ ],
+ "runner": null,
+ "artifacts_expire_at": null
+ }
}
]
```
@@ -66,6 +149,8 @@ Example of response
"state": "available",
"created_at": "2019-05-25T18:55:13.252Z",
"updated_at": "2019-05-27T18:55:13.252Z",
+ "enable_advanced_logs_querying": false,
+ "logs_api_path": "/project/-/logs/k8s.json?environment_name=review%2Ffix-foo",
"last_deployment": {
"id": 100,
"iid": 34,
diff --git a/doc/api/epics.md b/doc/api/epics.md
index deb74cf21e9..de20af08915 100644
--- a/doc/api/epics.md
+++ b/doc/api/epics.md
@@ -131,6 +131,7 @@ Example response:
"labels": [],
"upvotes": 4,
"downvotes": 0,
+ "color": "#1068bf",
"_links":{
"self": "http://gitlab.example.com/api/v4/groups/7/epics/4",
"epic_issues": "http://gitlab.example.com/api/v4/groups/7/epics/4/issues",
@@ -179,6 +180,7 @@ Example response:
"labels": [],
"upvotes": 4,
"downvotes": 0,
+ "color": "#1068bf",
"_links":{
"self": "http://gitlab.example.com/api/v4/groups/17/epics/35",
"epic_issues": "http://gitlab.example.com/api/v4/groups/17/epics/35/issues",
@@ -252,6 +254,7 @@ Example response:
"labels": [],
"upvotes": 4,
"downvotes": 0,
+ "color": "#1068bf",
"subscribed": true,
"_links":{
"self": "http://gitlab.example.com/api/v4/groups/7/epics/5",
@@ -283,6 +286,7 @@ POST /groups/:id/epics
| `title` | string | yes | The title of the epic |
| `labels` | string | no | The comma-separated list of labels |
| `description` | string | no | The description of the epic. Limited to 1,048,576 characters. |
+| `color` | string | no | The color of the epic. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/7641) in GitLab 14.8, behind a feature flag named `epic_highlight_color` (disabled by default) |
| `confidential` | boolean | no | Whether the epic should be confidential |
| `created_at` | string | no | When the epic was created. Date time string, ISO 8601 formatted, for example `2016-03-11T03:45:40Z` . Requires administrator or project/group owner privileges ([available](https://gitlab.com/gitlab-org/gitlab/-/issues/255309) in GitLab 13.5 and later) |
| `start_date_is_fixed` | boolean | no | Whether start date should be sourced from `start_date_fixed` or from milestones (in GitLab 11.3 and later) |
@@ -340,6 +344,7 @@ Example response:
"labels": [],
"upvotes": 4,
"downvotes": 0,
+ "color": "#1068bf",
"_links":{
"self": "http://gitlab.example.com/api/v4/groups/7/epics/6",
"epic_issues": "http://gitlab.example.com/api/v4/groups/7/epics/6/issues",
@@ -381,6 +386,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 (in GitLab 11.4 and later) |
| `title` | string | no | The title of an epic |
| `updated_at` | string | no | When the epic was updated. Date time string, ISO 8601 formatted, for example `2016-03-11T03:45:40Z` . Requires administrator or project/group owner privileges ([available](https://gitlab.com/gitlab-org/gitlab/-/issues/255309) in GitLab 13.5 and later) |
+| `color` | string | no | The color of the epic. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/7641) in GitLab 14.8, behind a feature flag named `epic_highlight_color` (disabled by default) |
```shell
curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/1/epics/5?title=New%20Title&parent_id=29"
@@ -430,7 +436,8 @@ Example response:
"closed_at": "2018-08-18T12:22:05.239Z",
"labels": [],
"upvotes": 4,
- "downvotes": 0
+ "downvotes": 0,
+ "color": "#1068bf"
}
```
diff --git a/doc/api/features.md b/doc/api/features.md
index 30efacb1d00..593e4adedd7 100644
--- a/doc/api/features.md
+++ b/doc/api/features.md
@@ -95,7 +95,7 @@ Example response:
"milestone": "11.8",
"type": "ops",
"group": "group::ecosystem",
- "default_enabled": false
+ "default_enabled": true
},
{
"name": "marginalia",
diff --git a/doc/api/geo_nodes.md b/doc/api/geo_nodes.md
index a152c443902..d2cca1a5856 100644
--- a/doc/api/geo_nodes.md
+++ b/doc/api/geo_nodes.md
@@ -63,7 +63,8 @@ Example response:
"sync_object_storage": false,
"clone_protocol": "http",
"web_edit_url": "https://primary.example.com/admin/geo/sites/3/edit",
- "web_geo_projects_url": "http://secondary.example.com/admin/geo/projects",
+ "web_geo_projects_url": "https://secondary.example.com/admin/geo/projects",
+ "web_geo_replication_details_url": "https://secondary.example.com/admin/geo/sites/3/replication/lfs_objects",
"_links": {
"self": "https://primary.example.com/api/v4/geo_nodes/3",
"status": "https://primary.example.com/api/v4/geo_nodes/3/status",
@@ -72,6 +73,10 @@ Example response:
}
```
+WARNING:
+The `web_geo_projects_url` attribute is in its end-of-life process. It is [deprecated](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/80106)
+for use in GitLab 14.9.
+
## Retrieve configuration about all Geo nodes
```plaintext
@@ -130,6 +135,7 @@ Example response:
"clone_protocol": "http",
"web_edit_url": "https://primary.example.com/admin/geo/sites/2/edit",
"web_geo_projects_url": "https://secondary.example.com/admin/geo/projects",
+ "web_geo_replication_details_url": "https://secondary.example.com/admin/geo/sites/2/replication/lfs_objects",
"_links": {
"self":"https://primary.example.com/api/v4/geo_nodes/2",
"status":"https://primary.example.com/api/v4/geo_nodes/2/status",
@@ -139,6 +145,10 @@ Example response:
]
```
+WARNING:
+The `web_geo_projects_url` attribute is in its end-of-life process. It is [deprecated](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/80106)
+for use in GitLab 14.9.
+
## Retrieve configuration about a specific Geo node
```plaintext
@@ -228,6 +238,7 @@ Example response:
"clone_protocol": "http",
"web_edit_url": "https://primary.example.com/admin/geo/sites/2/edit",
"web_geo_projects_url": "https://secondary.example.com/admin/geo/projects",
+ "web_geo_replication_details_url": "https://secondary.example.com/admin/geo/sites/2/replication/lfs_objects",
"_links": {
"self":"https://primary.example.com/api/v4/geo_nodes/2",
"status":"https://primary.example.com/api/v4/geo_nodes/2/status",
@@ -236,6 +247,10 @@ Example response:
}
```
+WARNING:
+The `web_geo_projects_url` attribute is in its end-of-life process. It is [deprecated](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/80106)
+for use in GitLab 14.9.
+
## Delete a Geo node
Removes the Geo node.
diff --git a/doc/api/graphql/index.md b/doc/api/graphql/index.md
index d0e65b8c4eb..457b083c217 100644
--- a/doc/api/graphql/index.md
+++ b/doc/api/graphql/index.md
@@ -187,55 +187,74 @@ NOTE:
The complexity limits may be revised in future, and additionally, the complexity
of a query may be altered.
-## Spam
-
-GraphQL mutations can be detected as spam. If this happens, a
-[GraphQL top-level error](https://spec.graphql.org/June2018/#sec-Errors) is raised. For example:
-
-```json
-{
- "errors": [
- {
- "message": "Request denied. Spam detected",
- "locations": [ { "line": 6, "column": 7 } ],
- "path": [ "updateSnippet" ],
- "extensions": {
- "spam": true
+## Resolve mutations detected as spam
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/327360) in GitLab 13.11.
+
+GraphQL mutations can be detected as spam. If a mutation is detected as spam and:
+
+- A CAPTCHA service is not configured, a
+ [GraphQL top-level error](https://spec.graphql.org/June2018/#sec-Errors) is raised. For example:
+
+ ```json
+ {
+ "errors": [
+ {
+ "message": "Request denied. Spam detected",
+ "locations": [ { "line": 6, "column": 7 } ],
+ "path": [ "updateSnippet" ],
+ "extensions": {
+ "spam": true
+ }
+ }
+ ],
+ "data": {
+ "updateSnippet": {
+ "snippet": null
}
}
- ],
- "data": {
- "updateSnippet": {
- "snippet": null
+ }
+ ```
+
+- A CAPTCHA service is configured, you receive a response with:
+ - `needsCaptchaResponse` set to `true`.
+ - The `spamLogId` and `captchaSiteKey` fields set.
+
+ For example:
+
+ ```json
+ {
+ "errors": [
+ {
+ "message": "Request denied. Solve CAPTCHA challenge and retry",
+ "locations": [ { "line": 6, "column": 7 } ],
+ "path": [ "updateSnippet" ],
+ "extensions": {
+ "needsCaptchaResponse": true,
+ "captchaSiteKey": "6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI",
+ "spamLogId": 67
+ }
+ }
+ ],
+ "data": {
+ "updateSnippet": {
+ "snippet": null,
+ }
}
}
-}
-```
-
-If a mutation is detected as potential spam and a CAPTCHA service is configured:
+ ```
- Use the `captchaSiteKey` to obtain a CAPTCHA response value using the appropriate CAPTCHA API.
Only [Google reCAPTCHA v2](https://developers.google.com/recaptcha/docs/display) is supported.
- Resubmit the request with the `X-GitLab-Captcha-Response` and `X-GitLab-Spam-Log-Id` headers set.
-
-```json
-{
- "errors": [
- {
- "message": "Request denied. Solve CAPTCHA challenge and retry",
- "locations": [ { "line": 6, "column": 7 } ],
- "path": [ "updateSnippet" ],
- "extensions": {
- "needsCaptchaResponse": true,
- "captchaSiteKey": "6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI",
- "spamLogId": 67
- }
- }
- ],
- "data": {
- "updateSnippet": {
- "snippet": null,
- }
- }
-}
+
+NOTE:
+The GitLab GraphiQL implementation doesn't permit passing of headers, so we must write
+this as a cURL query. `--data-binary` is used to properly handle escaped double quotes
+in the JSON-embedded query.
+
+```shell
+export CAPTCHA_RESPONSE="<CAPTCHA response obtained from CAPTCHA service>"
+export SPAM_LOG_ID="<spam_log_id obtained from initial REST response>"
+curl --header "Authorization: Bearer $PRIVATE_TOKEN" --header "Content-Type: application/json" --header "X-GitLab-Captcha-Response: $CAPTCHA_RESPONSE" --header "X-GitLab-Spam-Log-Id: $SPAM_LOG_ID" --request POST --data-binary '{"query": "mutation {createSnippet(input: {title: \"Title\" visibilityLevel: public blobActions: [ { action: create filePath: \"BlobPath\" content: \"BlobContent\" } ] }) { snippet { id title } errors }}"}' "https://gitlab.example.com/api/graphql"
```
diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md
index 49c0361123e..f6a6504df70 100644
--- a/doc/api/graphql/reference/index.md
+++ b/doc/api/graphql/reference/index.md
@@ -1,7 +1,7 @@
---
stage: Ecosystem
group: Integrations
-info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
<!---
@@ -157,6 +157,12 @@ Returns [`GeoNode`](#geonode).
| ---- | ---- | ----------- |
| <a id="querygeonodename"></a>`name` | [`String`](#string) | Name of the Geo node. Defaults to the current Geo node name. |
+### `Query.gitpodEnabled`
+
+Whether Gitpod is enabled in application settings.
+
+Returns [`Boolean`](#boolean).
+
### `Query.group`
Find a group.
@@ -560,6 +566,18 @@ Returns [`Vulnerability`](#vulnerability).
| ---- | ---- | ----------- |
| <a id="queryvulnerabilityid"></a>`id` | [`VulnerabilityID!`](#vulnerabilityid) | Global ID of the Vulnerability. |
+### `Query.workItem`
+
+Find a work item. Returns `null` if `work_items` feature flag is disabled. The feature is experimental and is subject to change without notice.
+
+Returns [`WorkItem`](#workitem).
+
+#### Arguments
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="queryworkitemid"></a>`id` | [`WorkItemID!`](#workitemid) | Global ID of the work item. |
+
## `Mutation` type
The `Mutation` type contains all the mutations you can execute.
@@ -1143,8 +1161,6 @@ Input type: `ConfigureSecretDetectionInput`
### `Mutation.corpusCreate`
-Available only when feature flag `corpus_management` is enabled. This flag is enabled by default.
-
Input type: `CorpusCreateInput`
#### Arguments
@@ -1354,6 +1370,7 @@ Input type: `CreateEpicInput`
| ---- | ---- | ----------- |
| <a id="mutationcreateepicaddlabelids"></a>`addLabelIds` | [`[ID!]`](#id) | IDs of labels to be added to the epic. |
| <a id="mutationcreateepicclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
+| <a id="mutationcreateepiccolor"></a>`color` | [`String`](#string) | Color of the epic. Available only when feature flag `epic_color_highlight` is enabled. This flag is disabled by default, because the feature is experimental and is subject to change without notice. |
| <a id="mutationcreateepicconfidential"></a>`confidential` | [`Boolean`](#boolean) | Indicates if the epic is confidential. |
| <a id="mutationcreateepicdescription"></a>`description` | [`String`](#string) | Description of the epic. |
| <a id="mutationcreateepicduedatefixed"></a>`dueDateFixed` | [`String`](#string) | End date of the epic. |
@@ -1466,6 +1483,11 @@ Input type: `CreateIterationInput`
### `Mutation.createNote`
+Creates a Note.
+If the body of the Note contains only quick actions,
+the Note will be destroyed during an update, and no Note will be
+returned.
+
Input type: `CreateNoteInput`
#### Arguments
@@ -1476,6 +1498,7 @@ Input type: `CreateNoteInput`
| <a id="mutationcreatenoteclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationcreatenoteconfidential"></a>`confidential` | [`Boolean`](#boolean) | Confidentiality flag of a note. Default is false. |
| <a id="mutationcreatenotediscussionid"></a>`discussionId` | [`DiscussionID`](#discussionid) | Global ID of the discussion this note is in reply to. |
+| <a id="mutationcreatenotemergerequestdiffheadsha"></a>`mergeRequestDiffHeadSha` | [`String`](#string) | SHA of the head commit which is used to ensure that the merge request has not been updated since the request was sent. |
| <a id="mutationcreatenotenoteableid"></a>`noteableId` | [`NoteableID!`](#noteableid) | Global ID of the resource to add a note to. |
#### Fields
@@ -1845,6 +1868,7 @@ Input type: `DastSiteProfileCreateInput`
| <a id="mutationdastsiteprofilecreatefullpath"></a>`fullPath` | [`ID!`](#id) | Project the site profile belongs to. |
| <a id="mutationdastsiteprofilecreateprofilename"></a>`profileName` | [`String!`](#string) | Name of the site profile. |
| <a id="mutationdastsiteprofilecreaterequestheaders"></a>`requestHeaders` | [`String`](#string) | Comma-separated list of request header names and values to be added to every request made by DAST. |
+| <a id="mutationdastsiteprofilecreatescanmethod"></a>`scanMethod` | [`DastScanMethodType`](#dastscanmethodtype) | Scan method by the scanner. Is not saved or updated if `dast_api_scanner` feature flag is disabled. |
| <a id="mutationdastsiteprofilecreatetargettype"></a>`targetType` | [`DastTargetTypeEnum`](#dasttargettypeenum) | Type of target to be scanned. |
| <a id="mutationdastsiteprofilecreatetargeturl"></a>`targetUrl` | [`String`](#string) | URL of the target to be scanned. |
@@ -1890,6 +1914,7 @@ Input type: `DastSiteProfileUpdateInput`
| <a id="mutationdastsiteprofileupdateid"></a>`id` | [`DastSiteProfileID!`](#dastsiteprofileid) | ID of the site profile to be updated. |
| <a id="mutationdastsiteprofileupdateprofilename"></a>`profileName` | [`String!`](#string) | Name of the site profile. |
| <a id="mutationdastsiteprofileupdaterequestheaders"></a>`requestHeaders` | [`String`](#string) | Comma-separated list of request header names and values to be added to every request made by DAST. |
+| <a id="mutationdastsiteprofileupdatescanmethod"></a>`scanMethod` | [`DastScanMethodType`](#dastscanmethodtype) | Scan method by the scanner. Is not saved or updated if `dast_api_scanner` feature flag is disabled. |
| <a id="mutationdastsiteprofileupdatetargettype"></a>`targetType` | [`DastTargetTypeEnum`](#dasttargettypeenum) | Type of target to be scanned. |
| <a id="mutationdastsiteprofileupdatetargeturl"></a>`targetUrl` | [`String`](#string) | URL of the target to be scanned. |
@@ -4218,6 +4243,47 @@ Input type: `RunnersRegistrationTokenResetInput`
| <a id="mutationrunnersregistrationtokenreseterrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
| <a id="mutationrunnersregistrationtokenresettoken"></a>`token` | [`String`](#string) | Runner token after mutation. |
+### `Mutation.savedReplyCreate`
+
+Input type: `SavedReplyCreateInput`
+
+#### Arguments
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mutationsavedreplycreateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
+| <a id="mutationsavedreplycreatecontent"></a>`content` | [`String!`](#string) | Content of the saved reply. |
+| <a id="mutationsavedreplycreatename"></a>`name` | [`String!`](#string) | Name of the saved reply. |
+
+#### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mutationsavedreplycreateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
+| <a id="mutationsavedreplycreateerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
+| <a id="mutationsavedreplycreatesavedreply"></a>`savedReply` | [`SavedReply`](#savedreply) | Updated saved reply. |
+
+### `Mutation.savedReplyUpdate`
+
+Input type: `SavedReplyUpdateInput`
+
+#### Arguments
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mutationsavedreplyupdateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
+| <a id="mutationsavedreplyupdatecontent"></a>`content` | [`String!`](#string) | Content of the saved reply. |
+| <a id="mutationsavedreplyupdateid"></a>`id` | [`UsersSavedReplyID!`](#userssavedreplyid) | Global ID of the saved reply. |
+| <a id="mutationsavedreplyupdatename"></a>`name` | [`String!`](#string) | Name of the saved reply. |
+
+#### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mutationsavedreplyupdateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
+| <a id="mutationsavedreplyupdateerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
+| <a id="mutationsavedreplyupdatesavedreply"></a>`savedReply` | [`SavedReply`](#savedreply) | Updated saved reply. |
+
### `Mutation.scanExecutionPolicyCommit`
Commits the `policy_yaml` content to the assigned security policy project for the given project(`project_path`).
@@ -4420,6 +4486,25 @@ Input type: `TimelineEventDestroyInput`
| <a id="mutationtimelineeventdestroyerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
| <a id="mutationtimelineeventdestroytimelineevent"></a>`timelineEvent` | [`TimelineEventType`](#timelineeventtype) | Timeline event. |
+### `Mutation.timelineEventPromoteFromNote`
+
+Input type: `TimelineEventPromoteFromNoteInput`
+
+#### Arguments
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mutationtimelineeventpromotefromnoteclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
+| <a id="mutationtimelineeventpromotefromnotenoteid"></a>`noteId` | [`NoteID!`](#noteid) | Note ID from which the timeline event promoted. |
+
+#### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mutationtimelineeventpromotefromnoteclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
+| <a id="mutationtimelineeventpromotefromnoteerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
+| <a id="mutationtimelineeventpromotefromnotetimelineevent"></a>`timelineEvent` | [`TimelineEventType`](#timelineeventtype) | Timeline event. |
+
### `Mutation.timelineEventUpdate`
Input type: `TimelineEventUpdateInput`
@@ -4725,6 +4810,7 @@ Input type: `UpdateEpicInput`
| ---- | ---- | ----------- |
| <a id="mutationupdateepicaddlabelids"></a>`addLabelIds` | [`[ID!]`](#id) | IDs of labels to be added to the epic. |
| <a id="mutationupdateepicclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
+| <a id="mutationupdateepiccolor"></a>`color` | [`String`](#string) | Color of the epic. Available only when feature flag `epic_color_highlight` is enabled. This flag is disabled by default, because the feature is experimental and is subject to change without notice. |
| <a id="mutationupdateepicconfidential"></a>`confidential` | [`Boolean`](#boolean) | Indicates if the epic is confidential. |
| <a id="mutationupdateepicdescription"></a>`description` | [`String`](#string) | Description of the epic. |
| <a id="mutationupdateepicduedatefixed"></a>`dueDateFixed` | [`String`](#string) | End date of the epic. |
@@ -4770,7 +4856,7 @@ Input type: `UpdateEpicBoardListInput`
Updates a DiffNote on an image (a `Note` where the `position.positionType` is `"image"`).
If the body of the Note contains only quick actions,
-the Note will be destroyed during the update, and no Note will be
+the Note will be destroyed during an update, and no Note will be
returned.
Input type: `UpdateImageDiffNoteInput`
@@ -4877,7 +4963,7 @@ Input type: `UpdateNamespacePackageSettingsInput`
Updates a Note.
If the body of the Note contains only quick actions,
-the Note will be destroyed during the update, and no Note will be
+the Note will be destroyed during an update, and no Note will be
returned.
Input type: `UpdateNoteInput`
@@ -5178,6 +5264,29 @@ Input type: `WorkItemCreateInput`
| <a id="mutationworkitemcreateerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
| <a id="mutationworkitemcreateworkitem"></a>`workItem` | [`WorkItem`](#workitem) | Created work item. |
+### `Mutation.workItemCreateFromTask`
+
+Creates a work item from a task in another work item's description. Available only when feature flag `work_items` is enabled. This feature is experimental and is subject to change without notice.
+
+Input type: `WorkItemCreateFromTaskInput`
+
+#### Arguments
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mutationworkitemcreatefromtaskclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
+| <a id="mutationworkitemcreatefromtaskid"></a>`id` | [`WorkItemID!`](#workitemid) | Global ID of the work item. |
+| <a id="mutationworkitemcreatefromtaskworkitemdata"></a>`workItemData` | [`WorkItemConvertTaskInput!`](#workitemconverttaskinput) | Arguments necessary to convert a task into a work item. |
+
+#### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mutationworkitemcreatefromtaskclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
+| <a id="mutationworkitemcreatefromtaskerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
+| <a id="mutationworkitemcreatefromtasknewworkitem"></a>`newWorkItem` | [`WorkItem`](#workitem) | New work item created from task. |
+| <a id="mutationworkitemcreatefromtaskworkitem"></a>`workItem` | [`WorkItem`](#workitem) | Updated work item. |
+
### `Mutation.workItemDelete`
Deletes a work item. Available only when feature flag `work_items` is enabled. The feature is experimental and is subject to change without notice.
@@ -5721,6 +5830,7 @@ The edge type for [`CiRunner`](#cirunner).
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="cirunneredgecursor"></a>`cursor` | [`String!`](#string) | A cursor for use in pagination. |
+| <a id="cirunneredgeediturl"></a>`editUrl` | [`String`](#string) | Web URL of the runner edit page. The value depends on where you put this field in the query. You can use it for projects or groups. |
| <a id="cirunneredgenode"></a>`node` | [`CiRunner`](#cirunner) | The item at the end of the edge. |
| <a id="cirunneredgeweburl"></a>`webUrl` | [`String`](#string) | Web URL of the runner. The value depends on where you put this field in the query. You can use it for projects or groups. |
@@ -5912,6 +6022,29 @@ The edge type for [`ComplianceFramework`](#complianceframework).
| <a id="complianceframeworkedgecursor"></a>`cursor` | [`String!`](#string) | A cursor for use in pagination. |
| <a id="complianceframeworkedgenode"></a>`node` | [`ComplianceFramework`](#complianceframework) | The item at the end of the edge. |
+#### `ComplianceViolationConnection`
+
+The connection type for [`ComplianceViolation`](#complianceviolation).
+
+##### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="complianceviolationconnectionedges"></a>`edges` | [`[ComplianceViolationEdge]`](#complianceviolationedge) | A list of edges. |
+| <a id="complianceviolationconnectionnodes"></a>`nodes` | [`[ComplianceViolation]`](#complianceviolation) | A list of nodes. |
+| <a id="complianceviolationconnectionpageinfo"></a>`pageInfo` | [`PageInfo!`](#pageinfo) | Information to aid in pagination. |
+
+#### `ComplianceViolationEdge`
+
+The edge type for [`ComplianceViolation`](#complianceviolation).
+
+##### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="complianceviolationedgecursor"></a>`cursor` | [`String!`](#string) | A cursor for use in pagination. |
+| <a id="complianceviolationedgenode"></a>`node` | [`ComplianceViolation`](#complianceviolation) | The item at the end of the edge. |
+
#### `ConnectedAgentConnection`
The connection type for [`ConnectedAgent`](#connectedagent).
@@ -7001,6 +7134,29 @@ The edge type for [`MergeRequest`](#mergerequest).
| <a id="mergerequestedgecursor"></a>`cursor` | [`String!`](#string) | A cursor for use in pagination. |
| <a id="mergerequestedgenode"></a>`node` | [`MergeRequest`](#mergerequest) | The item at the end of the edge. |
+#### `MergeRequestParticipantConnection`
+
+The connection type for [`MergeRequestParticipant`](#mergerequestparticipant).
+
+##### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mergerequestparticipantconnectionedges"></a>`edges` | [`[MergeRequestParticipantEdge]`](#mergerequestparticipantedge) | A list of edges. |
+| <a id="mergerequestparticipantconnectionnodes"></a>`nodes` | [`[MergeRequestParticipant]`](#mergerequestparticipant) | A list of nodes. |
+| <a id="mergerequestparticipantconnectionpageinfo"></a>`pageInfo` | [`PageInfo!`](#pageinfo) | Information to aid in pagination. |
+
+#### `MergeRequestParticipantEdge`
+
+The edge type for [`MergeRequestParticipant`](#mergerequestparticipant).
+
+##### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mergerequestparticipantedgecursor"></a>`cursor` | [`String!`](#string) | A cursor for use in pagination. |
+| <a id="mergerequestparticipantedgenode"></a>`node` | [`MergeRequestParticipant`](#mergerequestparticipant) | The item at the end of the edge. |
+
#### `MergeRequestReviewerConnection`
The connection type for [`MergeRequestReviewer`](#mergerequestreviewer).
@@ -7694,6 +7850,29 @@ The edge type for [`SastCiConfigurationOptionsEntity`](#sastciconfigurationoptio
| <a id="sastciconfigurationoptionsentityedgecursor"></a>`cursor` | [`String!`](#string) | A cursor for use in pagination. |
| <a id="sastciconfigurationoptionsentityedgenode"></a>`node` | [`SastCiConfigurationOptionsEntity`](#sastciconfigurationoptionsentity) | The item at the end of the edge. |
+#### `SavedReplyConnection`
+
+The connection type for [`SavedReply`](#savedreply).
+
+##### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="savedreplyconnectionedges"></a>`edges` | [`[SavedReplyEdge]`](#savedreplyedge) | A list of edges. |
+| <a id="savedreplyconnectionnodes"></a>`nodes` | [`[SavedReply]`](#savedreply) | A list of nodes. |
+| <a id="savedreplyconnectionpageinfo"></a>`pageInfo` | [`PageInfo!`](#pageinfo) | Information to aid in pagination. |
+
+#### `SavedReplyEdge`
+
+The edge type for [`SavedReply`](#savedreply).
+
+##### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="savedreplyedgecursor"></a>`cursor` | [`String!`](#string) | A cursor for use in pagination. |
+| <a id="savedreplyedgenode"></a>`node` | [`SavedReply`](#savedreply) | The item at the end of the edge. |
+
#### `ScanConnection`
The connection type for [`Scan`](#scan).
@@ -8513,6 +8692,7 @@ Describes an alert from the project's Alert Management.
| <a id="alertmanagementalertstatus"></a>`status` | [`AlertManagementStatus`](#alertmanagementstatus) | Status of the alert. |
| <a id="alertmanagementalerttitle"></a>`title` | [`String`](#string) | Title of the alert. |
| <a id="alertmanagementalertupdatedat"></a>`updatedAt` | [`Time`](#time) | Timestamp the alert was last updated. |
+| <a id="alertmanagementalertweburl"></a>`webUrl` | [`String!`](#string) | URL of the alert. |
#### Fields with arguments
@@ -8691,6 +8871,7 @@ An emoji awarded by a user.
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="baseserviceactive"></a>`active` | [`Boolean`](#boolean) | Indicates if the service is active. |
+| <a id="baseserviceservicetype"></a>`serviceType` | [`ServiceType`](#servicetype) | Type of the service. |
| <a id="baseservicetype"></a>`type` | [`String`](#string) | Class name of the service. |
### `Blob`
@@ -8795,6 +8976,7 @@ Represents an epic on an issue board.
| <a id="boardepicauthor"></a>`author` | [`UserCore!`](#usercore) | Author of the epic. |
| <a id="boardepicawardemoji"></a>`awardEmoji` | [`AwardEmojiConnection`](#awardemojiconnection) | List of award emojis associated with the epic. (see [Connections](#connections)) |
| <a id="boardepicclosedat"></a>`closedAt` | [`Time`](#time) | Timestamp of when the epic was closed. |
+| <a id="boardepiccolor"></a>`color` | [`String!`](#string) | Color of the epic. Available only when feature flag `epic_color_highlight` is enabled. This flag is disabled by default, because the feature is experimental and is subject to change without notice. |
| <a id="boardepicconfidential"></a>`confidential` | [`Boolean`](#boolean) | Indicates if the epic is confidential. |
| <a id="boardepiccreatedat"></a>`createdAt` | [`Time`](#time) | Timestamp of when the epic was created. |
| <a id="boardepicdescendantcounts"></a>`descendantCounts` | [`EpicDescendantCount`](#epicdescendantcount) | Number of open and closed descendant epics and issues. |
@@ -8830,6 +9012,7 @@ Represents an epic on an issue board.
| <a id="boardepicstartdateisfixed"></a>`startDateIsFixed` | [`Boolean`](#boolean) | Indicates if the start date has been manually set. |
| <a id="boardepicstate"></a>`state` | [`EpicState!`](#epicstate) | State of the epic. |
| <a id="boardepicsubscribed"></a>`subscribed` | [`Boolean!`](#boolean) | Indicates the currently logged in user is subscribed to the epic. |
+| <a id="boardepictextcolor"></a>`textColor` | [`String!`](#string) | Text color generated for the epic. Available only when feature flag `epic_color_highlight` is enabled. This flag is disabled by default, because the feature is experimental and is subject to change without notice. |
| <a id="boardepictitle"></a>`title` | [`String`](#string) | Title of the epic. |
| <a id="boardepictitlehtml"></a>`titleHtml` | [`String`](#string) | The GitLab Flavored Markdown rendering of `title`. |
| <a id="boardepicupdatedat"></a>`updatedAt` | [`Time`](#time) | Timestamp of when the epic was updated. |
@@ -9429,6 +9612,9 @@ four standard [pagination arguments](#connection-pagination-arguments):
| <a id="commitpipelinessha"></a>`sha` | [`String`](#string) | Filter pipelines by the sha of the commit they are run for. |
| <a id="commitpipelinessource"></a>`source` | [`String`](#string) | Filter pipelines by their source. |
| <a id="commitpipelinesstatus"></a>`status` | [`PipelineStatusEnum`](#pipelinestatusenum) | Filter pipelines by their status. |
+| <a id="commitpipelinesupdatedafter"></a>`updatedAfter` | [`Time`](#time) | Pipelines updated after this date. |
+| <a id="commitpipelinesupdatedbefore"></a>`updatedBefore` | [`Time`](#time) | Pipelines updated before this date. |
+| <a id="commitpipelinesusername"></a>`username` | [`String`](#string) | Filter pipelines by the user that triggered the pipeline. |
### `ComplianceFramework`
@@ -9444,6 +9630,20 @@ Represents a ComplianceFramework associated with a Project.
| <a id="complianceframeworkname"></a>`name` | [`String!`](#string) | Name of the compliance framework. |
| <a id="complianceframeworkpipelineconfigurationfullpath"></a>`pipelineConfigurationFullPath` | [`String`](#string) | Full path of the compliance pipeline configuration stored in a project repository, such as `.gitlab/.compliance-gitlab-ci.yml@compliance/hipaa` **(ULTIMATE)**. |
+### `ComplianceViolation`
+
+Compliance violation associated with a merged merge request.
+
+#### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="complianceviolationid"></a>`id` | [`ID!`](#id) | Compliance violation ID. |
+| <a id="complianceviolationmergerequest"></a>`mergeRequest` | [`MergeRequest!`](#mergerequest) | Merge request the compliance violation occurred in. |
+| <a id="complianceviolationreason"></a>`reason` | [`ComplianceViolationReason!`](#complianceviolationreason) | Reason the compliance violation occurred. |
+| <a id="complianceviolationseveritylevel"></a>`severityLevel` | [`ComplianceViolationSeverity!`](#complianceviolationseverity) | Severity of the compliance violation. |
+| <a id="complianceviolationviolatinguser"></a>`violatingUser` | [`UserCore!`](#usercore) | User suspected of causing the compliance violation. |
+
### `ComposerMetadata`
Composer metadata.
@@ -9555,6 +9755,7 @@ Details of a container repository.
| <a id="containerrepositorydetailsname"></a>`name` | [`String!`](#string) | Name of the container repository. |
| <a id="containerrepositorydetailspath"></a>`path` | [`String!`](#string) | Path of the container repository. |
| <a id="containerrepositorydetailsproject"></a>`project` | [`Project!`](#project) | Project of the container registry. |
+| <a id="containerrepositorydetailssize"></a>`size` | [`Float`](#float) | Deduplicated size of the image repository in bytes. This is only available on GitLab.com for repositories created after `2021-11-04`. |
| <a id="containerrepositorydetailsstatus"></a>`status` | [`ContainerRepositoryStatus`](#containerrepositorystatus) | Status of the container repository. |
| <a id="containerrepositorydetailstagscount"></a>`tagsCount` | [`Int!`](#int) | Number of tags associated with this image. |
| <a id="containerrepositorydetailsupdatedat"></a>`updatedAt` | [`Time!`](#time) | Timestamp when the container repository was updated. |
@@ -9622,7 +9823,7 @@ Represents the current license.
| <a id="currentlicensecreatedat"></a>`createdAt` | [`Date`](#date) | Date when the license was added. |
| <a id="currentlicenseemail"></a>`email` | [`String`](#string) | Email of the licensee. |
| <a id="currentlicenseexpiresat"></a>`expiresAt` | [`Date`](#date) | Date when the license expires. |
-| <a id="currentlicenseid"></a>`id` | [`ID!`](#id) | ID of the license. |
+| <a id="currentlicenseid"></a>`id` | [`ID!`](#id) | ID of the license extracted from the license data. |
| <a id="currentlicenselastsync"></a>`lastSync` | [`Time`](#time) | Date when the license was last synced. |
| <a id="currentlicensemaximumusercount"></a>`maximumUserCount` | [`Int`](#int) | Highest number of billable users on the system during the term of the current license. |
| <a id="currentlicensename"></a>`name` | [`String`](#string) | Name of the licensee. |
@@ -9763,6 +9964,7 @@ Represents a DAST Site Profile.
| <a id="dastsiteprofileprofilename"></a>`profileName` | [`String`](#string) | Name of the site profile. |
| <a id="dastsiteprofilereferencedinsecuritypolicies"></a>`referencedInSecurityPolicies` | [`[String!]`](#string) | List of security policy names that are referencing given project. |
| <a id="dastsiteprofilerequestheaders"></a>`requestHeaders` | [`String`](#string) | Comma-separated list of request header names and values to be added to every request made by DAST. |
+| <a id="dastsiteprofilescanmethod"></a>`scanMethod` | [`DastScanMethodType`](#dastscanmethodtype) | Scan method used by the scanner. Always returns `null` if `dast_api_scanner` feature flag is disabled. |
| <a id="dastsiteprofiletargettype"></a>`targetType` | [`DastTargetTypeEnum`](#dasttargettypeenum) | Type of target to be scanned. |
| <a id="dastsiteprofiletargeturl"></a>`targetUrl` | [`String`](#string) | URL of the target to be scanned. |
| <a id="dastsiteprofileuserpermissions"></a>`userPermissions` | [`DastSiteProfilePermissions!`](#dastsiteprofilepermissions) | Permissions for the current user on the resource. |
@@ -9889,6 +10091,7 @@ A single design.
| <a id="designnotes"></a>`notes` | [`NoteConnection!`](#noteconnection) | All notes on this noteable. (see [Connections](#connections)) |
| <a id="designnotescount"></a>`notesCount` | [`Int!`](#int) | Total count of user-created notes for this design. |
| <a id="designproject"></a>`project` | [`Project!`](#project) | Project the design belongs to. |
+| <a id="designweburl"></a>`webUrl` | [`String!`](#string) | URL of the design. |
#### Fields with arguments
@@ -10322,6 +10525,7 @@ Represents an epic.
| <a id="epicauthor"></a>`author` | [`UserCore!`](#usercore) | Author of the epic. |
| <a id="epicawardemoji"></a>`awardEmoji` | [`AwardEmojiConnection`](#awardemojiconnection) | List of award emojis associated with the epic. (see [Connections](#connections)) |
| <a id="epicclosedat"></a>`closedAt` | [`Time`](#time) | Timestamp of when the epic was closed. |
+| <a id="epiccolor"></a>`color` | [`String!`](#string) | Color of the epic. Available only when feature flag `epic_color_highlight` is enabled. This flag is disabled by default, because the feature is experimental and is subject to change without notice. |
| <a id="epicconfidential"></a>`confidential` | [`Boolean`](#boolean) | Indicates if the epic is confidential. |
| <a id="epiccreatedat"></a>`createdAt` | [`Time`](#time) | Timestamp of when the epic was created. |
| <a id="epicdescendantcounts"></a>`descendantCounts` | [`EpicDescendantCount`](#epicdescendantcount) | Number of open and closed descendant epics and issues. |
@@ -10357,6 +10561,7 @@ Represents an epic.
| <a id="epicstartdateisfixed"></a>`startDateIsFixed` | [`Boolean`](#boolean) | Indicates if the start date has been manually set. |
| <a id="epicstate"></a>`state` | [`EpicState!`](#epicstate) | State of the epic. |
| <a id="epicsubscribed"></a>`subscribed` | [`Boolean!`](#boolean) | Indicates the currently logged in user is subscribed to the epic. |
+| <a id="epictextcolor"></a>`textColor` | [`String!`](#string) | Text color generated for the epic. Available only when feature flag `epic_color_highlight` is enabled. This flag is disabled by default, because the feature is experimental and is subject to change without notice. |
| <a id="epictitle"></a>`title` | [`String`](#string) | Title of the epic. |
| <a id="epictitlehtml"></a>`titleHtml` | [`String`](#string) | The GitLab Flavored Markdown rendering of `title`. |
| <a id="epicupdatedat"></a>`updatedAt` | [`Time`](#time) | Timestamp of when the epic was updated. |
@@ -10653,10 +10858,11 @@ Represents an epic board list.
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="epiclistcollapsed"></a>`collapsed` | [`Boolean`](#boolean) | Indicates if this list is collapsed for this user. |
-| <a id="epiclistepicscount"></a>`epicsCount` | [`Int`](#int) | Count of epics in the list. |
+| <a id="epiclistepicscount"></a>`epicsCount` **{warning-solid}** | [`Int`](#int) | **Deprecated** in 14.9. This was renamed. Use: `metadata`. |
| <a id="epiclistid"></a>`id` | [`BoardsEpicListID!`](#boardsepiclistid) | Global ID of the board list. |
| <a id="epiclistlabel"></a>`label` | [`Label`](#label) | Label of the list. |
| <a id="epiclistlisttype"></a>`listType` | [`String!`](#string) | Type of the list. |
+| <a id="epiclistmetadata"></a>`metadata` | [`EpicListMetadata`](#epiclistmetadata) | Epic list metatada. |
| <a id="epiclistposition"></a>`position` | [`Int`](#int) | Position of the list within the board. |
| <a id="epiclisttitle"></a>`title` | [`String!`](#string) | Title of the list. |
@@ -10678,6 +10884,17 @@ four standard [pagination arguments](#connection-pagination-arguments):
| ---- | ---- | ----------- |
| <a id="epiclistepicsfilters"></a>`filters` | [`EpicFilters`](#epicfilters) | Filters applied when selecting epics in the board list. |
+### `EpicListMetadata`
+
+Represents epic board list metadata.
+
+#### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="epiclistmetadataepicscount"></a>`epicsCount` | [`Int`](#int) | Count of epics in the list. |
+| <a id="epiclistmetadatatotalweight"></a>`totalWeight` | [`Int`](#int) | Total weight of all issues in the list. Available only when feature flag `epic_board_total_weight` is enabled. This flag is disabled by default, because the feature is experimental and is subject to change without notice. |
+
### `EpicPermissions`
Check permissions for the current user on an epic.
@@ -10807,7 +11024,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
##### `GeoNode.jobArtifactRegistries`
-Find Job Artifact registries on this Geo node Available only when feature flag `geo_job_artifact_replication` is enabled. This flag is disabled by default, because the feature is experimental and is subject to change without notice.
+Find Job Artifact registries on this Geo node.
Returns [`JobArtifactRegistryConnection`](#jobartifactregistryconnection).
@@ -10971,10 +11188,10 @@ four standard [pagination arguments](#connection-pagination-arguments):
| <a id="groupadditionalpurchasedstoragesize"></a>`additionalPurchasedStorageSize` | [`Float`](#float) | Additional storage purchased for the root namespace in bytes. |
| <a id="groupautodevopsenabled"></a>`autoDevopsEnabled` | [`Boolean`](#boolean) | Indicates whether Auto DevOps is enabled for all projects within this group. |
| <a id="groupavatarurl"></a>`avatarUrl` | [`String`](#string) | Avatar URL of the group. |
-| <a id="groupbillablememberscount"></a>`billableMembersCount` | [`Int`](#int) | Number of billable users in the group. |
| <a id="groupcontacts"></a>`contacts` | [`CustomerRelationsContactConnection`](#customerrelationscontactconnection) | Find contacts of this group. (see [Connections](#connections)) |
| <a id="groupcontainerrepositoriescount"></a>`containerRepositoriesCount` | [`Int!`](#int) | Number of container repositories in the group. |
| <a id="groupcontainslockedprojects"></a>`containsLockedProjects` | [`Boolean!`](#boolean) | Includes at least one project where the repository size exceeds the limit. |
+| <a id="groupcrossprojectpipelineavailable"></a>`crossProjectPipelineAvailable` | [`Boolean!`](#boolean) | Indicates if the cross_project_pipeline feature is available for the namespace. |
| <a id="groupcustomemoji"></a>`customEmoji` | [`CustomEmojiConnection`](#customemojiconnection) | Custom emoji within this namespace. Available only when feature flag `custom_emoji` is enabled. This flag is disabled by default, because the feature is experimental and is subject to change without notice. (see [Connections](#connections)) |
| <a id="groupdependencyproxyblobcount"></a>`dependencyProxyBlobCount` | [`Int!`](#int) | Number of dependency proxy blobs cached in the group. |
| <a id="groupdependencyproxyblobs"></a>`dependencyProxyBlobs` | [`DependencyProxyBlobConnection`](#dependencyproxyblobconnection) | Dependency Proxy blobs. (see [Connections](#connections)) |
@@ -11021,10 +11238,21 @@ four standard [pagination arguments](#connection-pagination-arguments):
| <a id="groupvisibility"></a>`visibility` | [`String`](#string) | Visibility of the namespace. |
| <a id="groupvulnerabilityscanners"></a>`vulnerabilityScanners` | [`VulnerabilityScannerConnection`](#vulnerabilityscannerconnection) | Vulnerability scanners reported on the project vulnerabilities of the group and its subgroups. (see [Connections](#connections)) |
| <a id="groupweburl"></a>`webUrl` | [`String!`](#string) | Web URL of the group. |
-| <a id="groupworkitemtypes"></a>`workItemTypes` | [`WorkItemTypeConnection`](#workitemtypeconnection) | Work item types available to the group. Available only when feature flag `work_items` is enabled. This flag is disabled by default, because the feature is experimental and is subject to change without notice. (see [Connections](#connections)) |
#### Fields with arguments
+##### `Group.billableMembersCount`
+
+Number of billable users in the group.
+
+Returns [`Int`](#int).
+
+###### Arguments
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="groupbillablememberscountrequestedhostedplan"></a>`requestedHostedPlan` | [`String`](#string) | Plan from which to get billable members. |
+
##### `Group.board`
A single board of the group.
@@ -11245,6 +11473,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
| <a id="groupissuesepicid"></a>`epicId` | [`String`](#string) | ID of an epic associated with the issues, "none" and "any" values are supported. |
| <a id="groupissuesiid"></a>`iid` | [`String`](#string) | IID of the issue. For example, "1". |
| <a id="groupissuesiids"></a>`iids` | [`[String!]`](#string) | List of IIDs of issues. For example, `["1", "2"]`. |
+| <a id="groupissuesincludearchived"></a>`includeArchived` | [`Boolean`](#boolean) | Return issues from archived projects. |
| <a id="groupissuesincludesubepics"></a>`includeSubepics` | [`Boolean`](#boolean) | Whether to include subepics when filtering issues by epicId. |
| <a id="groupissuesincludesubgroups"></a>`includeSubgroups` | [`Boolean`](#boolean) | Include issues belonging to subgroups. |
| <a id="groupissuesiterationid"></a>`iterationId` | [`[ID]`](#id) | List of iteration Global IDs applied to the issue. |
@@ -11341,6 +11570,23 @@ four standard [pagination arguments](#connection-pagination-arguments):
| <a id="grouplabelsonlygrouplabels"></a>`onlyGroupLabels` | [`Boolean`](#boolean) | Include only group level labels. |
| <a id="grouplabelssearchterm"></a>`searchTerm` | [`String`](#string) | Search term to find labels with. |
+##### `Group.mergeRequestViolations`
+
+Compliance violations reported on merge requests merged within the group.
+
+Returns [`ComplianceViolationConnection`](#complianceviolationconnection).
+
+This field returns a [connection](#connections). It accepts the
+four standard [pagination arguments](#connection-pagination-arguments):
+`before: String`, `after: String`, `first: Int`, `last: Int`.
+
+###### Arguments
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="groupmergerequestviolationsfilters"></a>`filters` | [`ComplianceViolationInput`](#complianceviolationinput) | Filters applied when retrieving compliance violations. |
+| <a id="groupmergerequestviolationssort"></a>`sort` | [`ComplianceViolationSort`](#complianceviolationsort) | List compliance violations by sort order. |
+
##### `Group.mergeRequests`
Merge requests for projects in this group.
@@ -11361,6 +11607,7 @@ four standard [pagination arguments](#connection-pagination-arguments):
| <a id="groupmergerequestscreatedbefore"></a>`createdBefore` | [`Time`](#time) | Merge requests created before this timestamp. |
| <a id="groupmergerequestsdraft"></a>`draft` | [`Boolean`](#boolean) | Limit result to draft merge requests. |
| <a id="groupmergerequestsiids"></a>`iids` | [`[String!]`](#string) | Array of IIDs of merge requests, for example `[1, 2]`. |
+| <a id="groupmergerequestsincludearchived"></a>`includeArchived` | [`Boolean`](#boolean) | Return merge requests from archived projects. |
| <a id="groupmergerequestsincludesubgroups"></a>`includeSubgroups` | [`Boolean`](#boolean) | Include merge requests belonging to subgroups. |
| <a id="groupmergerequestslabels"></a>`labels` | [`[String!]`](#string) | Array of label names. All resolved merge requests will have all of these labels. |
| <a id="groupmergerequestsmergedafter"></a>`mergedAfter` | [`Time`](#time) | Merge requests merged after this date. |
@@ -11561,6 +11808,22 @@ Returns [`VulnerabilitySeveritiesCount`](#vulnerabilityseveritiescount).
| <a id="groupvulnerabilityseveritiescountseverity"></a>`severity` | [`[VulnerabilitySeverity!]`](#vulnerabilityseverity) | Filter vulnerabilities by severity. |
| <a id="groupvulnerabilityseveritiescountstate"></a>`state` | [`[VulnerabilityState!]`](#vulnerabilitystate) | Filter vulnerabilities by state. |
+##### `Group.workItemTypes`
+
+Work item types available to the group. Returns `null` if `work_items` feature flag is disabled. This flag is disabled by default, because the feature is experimental and is subject to change without notice.
+
+Returns [`WorkItemTypeConnection`](#workitemtypeconnection).
+
+This field returns a [connection](#connections). It accepts the
+four standard [pagination arguments](#connection-pagination-arguments):
+`before: String`, `after: String`, `first: Int`, `last: Int`.
+
+###### Arguments
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="groupworkitemtypestaskable"></a>`taskable` | [`Boolean`](#boolean) | If `true`, only taskable work item types will be returned. Argument is experimental and can be removed in the future without notice. |
+
### `GroupMember`
Represents a Group Membership.
@@ -11575,6 +11838,7 @@ Represents a Group Membership.
| <a id="groupmemberexpiresat"></a>`expiresAt` | [`Time`](#time) | Date and time the membership expires. |
| <a id="groupmembergroup"></a>`group` | [`Group`](#group) | Group that a User is a member of. |
| <a id="groupmemberid"></a>`id` | [`ID!`](#id) | ID of the member. |
+| <a id="groupmembernotificationemail"></a>`notificationEmail` | [`String`](#string) | Group notification email for User. Only availble for admins. |
| <a id="groupmemberupdatedat"></a>`updatedAt` | [`Time`](#time) | Date and time the membership was last updated. |
| <a id="groupmemberuser"></a>`user` | [`UserCore`](#usercore) | User that is associated with the member object. |
| <a id="groupmemberuserpermissions"></a>`userPermissions` | [`GroupPermissions!`](#grouppermissions) | Permissions for the current user on the resource. |
@@ -11918,17 +12182,30 @@ Represents an iteration object.
| <a id="iterationid"></a>`id` | [`ID!`](#id) | ID of the iteration. |
| <a id="iterationiid"></a>`iid` | [`ID!`](#id) | Internal ID of the iteration. |
| <a id="iterationiterationcadence"></a>`iterationCadence` | [`IterationCadence!`](#iterationcadence) | Cadence of the iteration. |
-| <a id="iterationreport"></a>`report` | [`TimeboxReport`](#timeboxreport) | Historically accurate report about the timebox. |
| <a id="iterationscopedpath"></a>`scopedPath` | [`String`](#string) | Web path of the iteration, scoped to the query parent. Only valid for Project parents. Returns null in other contexts. |
| <a id="iterationscopedurl"></a>`scopedUrl` | [`String`](#string) | Web URL of the iteration, scoped to the query parent. Only valid for Project parents. Returns null in other contexts. |
| <a id="iterationsequence"></a>`sequence` | [`Int!`](#int) | Sequence number for the iteration when you sort the containing cadence's iterations by the start and end date. The earliest starting and ending iteration is assigned 1. |
| <a id="iterationstartdate"></a>`startDate` | [`Time`](#time) | Timestamp of the iteration start date. |
| <a id="iterationstate"></a>`state` | [`IterationState!`](#iterationstate) | State of the iteration. |
-| <a id="iterationtitle"></a>`title` | [`String!`](#string) | Title of the iteration. |
+| <a id="iterationtitle"></a>`title` | [`String`](#string) | Title of the iteration. Title must be specified unless iteration_cadences feature flag is enabled. |
| <a id="iterationupdatedat"></a>`updatedAt` | [`Time!`](#time) | Timestamp of last iteration update. |
| <a id="iterationwebpath"></a>`webPath` | [`String!`](#string) | Web path of the iteration. |
| <a id="iterationweburl"></a>`webUrl` | [`String!`](#string) | Web URL of the iteration. |
+#### Fields with arguments
+
+##### `Iteration.report`
+
+Historically accurate report about the timebox.
+
+Returns [`TimeboxReport`](#timeboxreport).
+
+###### Arguments
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="iterationreportfullpath"></a>`fullPath` | [`String`](#string) | Full path of the project or group used as a scope for report. For example, `gitlab-org` or `gitlab-org/gitlab`. |
+
### `IterationCadence`
Represents an iteration cadence.
@@ -11978,6 +12255,7 @@ Represents an iteration cadence.
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="jiraserviceactive"></a>`active` | [`Boolean`](#boolean) | Indicates if the service is active. |
+| <a id="jiraserviceservicetype"></a>`serviceType` | [`ServiceType`](#servicetype) | Type of the service. |
| <a id="jiraservicetype"></a>`type` | [`String`](#string) | Class name of the service. |
#### Fields with arguments
@@ -12094,7 +12372,7 @@ Represents an entry from the Cloud License history.
| <a id="licensehistoryentrycreatedat"></a>`createdAt` | [`Date`](#date) | Date when the license was added. |
| <a id="licensehistoryentryemail"></a>`email` | [`String`](#string) | Email of the licensee. |
| <a id="licensehistoryentryexpiresat"></a>`expiresAt` | [`Date`](#date) | Date when the license expires. |
-| <a id="licensehistoryentryid"></a>`id` | [`ID!`](#id) | ID of the license. |
+| <a id="licensehistoryentryid"></a>`id` | [`ID!`](#id) | ID of the license extracted from the license data. |
| <a id="licensehistoryentryname"></a>`name` | [`String`](#string) | Name of the licensee. |
| <a id="licensehistoryentryplan"></a>`plan` | [`String!`](#string) | Name of the subscription plan. |
| <a id="licensehistoryentrystartsat"></a>`startsAt` | [`Date`](#date) | Date when the license started. |
@@ -12130,13 +12408,14 @@ Maven metadata.
| <a id="mergerequestapproved"></a>`approved` | [`Boolean!`](#boolean) | Indicates if the merge request has all the required approvals. Returns true if no required approvals are configured. |
| <a id="mergerequestapprovedby"></a>`approvedBy` | [`UserCoreConnection`](#usercoreconnection) | Users who approved the merge request. (see [Connections](#connections)) |
| <a id="mergerequestassignees"></a>`assignees` | [`MergeRequestAssigneeConnection`](#mergerequestassigneeconnection) | Assignees of the merge request. (see [Connections](#connections)) |
-| <a id="mergerequestauthor"></a>`author` | [`UserCore`](#usercore) | User who created this merge request. |
+| <a id="mergerequestauthor"></a>`author` | [`MergeRequestAuthor`](#mergerequestauthor) | User who created this merge request. |
| <a id="mergerequestautomergeenabled"></a>`autoMergeEnabled` | [`Boolean!`](#boolean) | Indicates if auto merge is enabled for the merge request. |
| <a id="mergerequestautomergestrategy"></a>`autoMergeStrategy` | [`String`](#string) | Selected auto merge strategy. |
| <a id="mergerequestavailableautomergestrategies"></a>`availableAutoMergeStrategies` | [`[String!]`](#string) | Array of available auto merge strategies. |
| <a id="mergerequestcommitcount"></a>`commitCount` | [`Int`](#int) | Number of commits in the merge request. |
| <a id="mergerequestcommits"></a>`commits` | [`CommitConnection`](#commitconnection) | Merge request commits. (see [Connections](#connections)) |
| <a id="mergerequestcommitswithoutmergecommits"></a>`commitsWithoutMergeCommits` | [`CommitConnection`](#commitconnection) | Merge request commits excluding merge commits. (see [Connections](#connections)) |
+| <a id="mergerequestcommitters"></a>`committers` | [`UserCoreConnection`](#usercoreconnection) | Users who have added commits to the merge request. (see [Connections](#connections)) |
| <a id="mergerequestconflicts"></a>`conflicts` | [`Boolean!`](#boolean) | Indicates if the merge request has conflicts. |
| <a id="mergerequestcreatedat"></a>`createdAt` | [`Time!`](#time) | Timestamp of when the merge request was created. |
| <a id="mergerequestdefaultmergecommitmessage"></a>`defaultMergeCommitMessage` | [`String`](#string) | Default merge commit message of the merge request. |
@@ -12175,7 +12454,7 @@ Maven metadata.
| <a id="mergerequestmergedat"></a>`mergedAt` | [`Time`](#time) | Timestamp of when the merge request was merged, null if not merged. |
| <a id="mergerequestmilestone"></a>`milestone` | [`Milestone`](#milestone) | Milestone of the merge request. |
| <a id="mergerequestnotes"></a>`notes` | [`NoteConnection!`](#noteconnection) | All notes on this noteable. (see [Connections](#connections)) |
-| <a id="mergerequestparticipants"></a>`participants` | [`UserCoreConnection`](#usercoreconnection) | Participants in the merge request. This includes the author, assignees, reviewers, and users mentioned in notes. (see [Connections](#connections)) |
+| <a id="mergerequestparticipants"></a>`participants` | [`MergeRequestParticipantConnection`](#mergerequestparticipantconnection) | Participants in the merge request. This includes the author, assignees, reviewers, and users mentioned in notes. (see [Connections](#connections)) |
| <a id="mergerequestproject"></a>`project` | [`Project!`](#project) | Alias for target_project. |
| <a id="mergerequestprojectid"></a>`projectId` | [`Int!`](#int) | ID of the merge request project. |
| <a id="mergerequestrebasecommitsha"></a>`rebaseCommitSha` | [`String`](#string) | Rebase commit SHA of the merge request. |
@@ -12260,6 +12539,9 @@ four standard [pagination arguments](#connection-pagination-arguments):
| <a id="mergerequestpipelinessha"></a>`sha` | [`String`](#string) | Filter pipelines by the sha of the commit they are run for. |
| <a id="mergerequestpipelinessource"></a>`source` | [`String`](#string) | Filter pipelines by their source. |
| <a id="mergerequestpipelinesstatus"></a>`status` | [`PipelineStatusEnum`](#pipelinestatusenum) | Filter pipelines by their status. |
+| <a id="mergerequestpipelinesupdatedafter"></a>`updatedAfter` | [`Time`](#time) | Pipelines updated after this date. |
+| <a id="mergerequestpipelinesupdatedbefore"></a>`updatedBefore` | [`Time`](#time) | Pipelines updated before this date. |
+| <a id="mergerequestpipelinesusername"></a>`username` | [`String`](#string) | Filter pipelines by the user that triggered the pipeline. |
##### `MergeRequest.reference`
@@ -12296,6 +12578,7 @@ A user assigned to a merge request.
| <a id="mergerequestassigneebot"></a>`bot` | [`Boolean!`](#boolean) | Indicates if the user is a bot. |
| <a id="mergerequestassigneecallouts"></a>`callouts` | [`UserCalloutConnection`](#usercalloutconnection) | User callouts that belong to the user. (see [Connections](#connections)) |
| <a id="mergerequestassigneeemail"></a>`email` **{warning-solid}** | [`String`](#string) | **Deprecated** in 13.7. This was renamed. Use: [`User.publicEmail`](#userpublicemail). |
+| <a id="mergerequestassigneegitpodenabled"></a>`gitpodEnabled` | [`Boolean`](#boolean) | Whether Gitpod is enabled at the user level. |
| <a id="mergerequestassigneegroupcount"></a>`groupCount` | [`Int`](#int) | Group count for the user. |
| <a id="mergerequestassigneegroupmemberships"></a>`groupMemberships` | [`GroupMemberConnection`](#groupmemberconnection) | Group memberships of the user. (see [Connections](#connections)) |
| <a id="mergerequestassigneeid"></a>`id` | [`ID!`](#id) | ID of the user. |
@@ -12303,8 +12586,11 @@ A user assigned to a merge request.
| <a id="mergerequestassigneemergerequestinteraction"></a>`mergeRequestInteraction` | [`UserMergeRequestInteraction`](#usermergerequestinteraction) | Details of this user's interactions with the merge request. |
| <a id="mergerequestassigneename"></a>`name` | [`String!`](#string) | Human-readable name of the user. Returns `****` if the user is a project bot and the requester does not have permission to view the project. |
| <a id="mergerequestassigneenamespace"></a>`namespace` | [`Namespace`](#namespace) | Personal namespace of the user. |
+| <a id="mergerequestassigneepreferencesgitpodpath"></a>`preferencesGitpodPath` | [`String`](#string) | Web path to the Gitpod section within user preferences. |
+| <a id="mergerequestassigneeprofileenablegitpodpath"></a>`profileEnableGitpodPath` | [`String`](#string) | Web path to enable Gitpod for the user. |
| <a id="mergerequestassigneeprojectmemberships"></a>`projectMemberships` | [`ProjectMemberConnection`](#projectmemberconnection) | Project memberships of the user. (see [Connections](#connections)) |
| <a id="mergerequestassigneepublicemail"></a>`publicEmail` | [`String`](#string) | User's public email. |
+| <a id="mergerequestassigneesavedreplies"></a>`savedReplies` | [`SavedReplyConnection`](#savedreplyconnection) | Saved replies authored by the user. (see [Connections](#connections)) |
| <a id="mergerequestassigneestate"></a>`state` | [`UserState!`](#userstate) | State of the user. |
| <a id="mergerequestassigneestatus"></a>`status` | [`UserStatus`](#userstatus) | User status. |
| <a id="mergerequestassigneeuserpermissions"></a>`userPermissions` | [`UserPermissions!`](#userpermissions) | Permissions for the current user on the resource. |
@@ -12510,6 +12796,236 @@ four standard [pagination arguments](#connection-pagination-arguments):
| <a id="mergerequestassigneetodosstate"></a>`state` | [`[TodoStateEnum!]`](#todostateenum) | State of the todo. |
| <a id="mergerequestassigneetodostype"></a>`type` | [`[TodoTargetEnum!]`](#todotargetenum) | Type of the todo. |
+### `MergeRequestAuthor`
+
+The author of the merge request.
+
+#### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mergerequestauthoravatarurl"></a>`avatarUrl` | [`String`](#string) | URL of the user's avatar. |
+| <a id="mergerequestauthorbot"></a>`bot` | [`Boolean!`](#boolean) | Indicates if the user is a bot. |
+| <a id="mergerequestauthorcallouts"></a>`callouts` | [`UserCalloutConnection`](#usercalloutconnection) | User callouts that belong to the user. (see [Connections](#connections)) |
+| <a id="mergerequestauthoremail"></a>`email` **{warning-solid}** | [`String`](#string) | **Deprecated** in 13.7. This was renamed. Use: [`User.publicEmail`](#userpublicemail). |
+| <a id="mergerequestauthorgitpodenabled"></a>`gitpodEnabled` | [`Boolean`](#boolean) | Whether Gitpod is enabled at the user level. |
+| <a id="mergerequestauthorgroupcount"></a>`groupCount` | [`Int`](#int) | Group count for the user. |
+| <a id="mergerequestauthorgroupmemberships"></a>`groupMemberships` | [`GroupMemberConnection`](#groupmemberconnection) | Group memberships of the user. (see [Connections](#connections)) |
+| <a id="mergerequestauthorid"></a>`id` | [`ID!`](#id) | ID of the user. |
+| <a id="mergerequestauthorlocation"></a>`location` | [`String`](#string) | Location of the user. |
+| <a id="mergerequestauthormergerequestinteraction"></a>`mergeRequestInteraction` | [`UserMergeRequestInteraction`](#usermergerequestinteraction) | Details of this user's interactions with the merge request. |
+| <a id="mergerequestauthorname"></a>`name` | [`String!`](#string) | Human-readable name of the user. Returns `****` if the user is a project bot and the requester does not have permission to view the project. |
+| <a id="mergerequestauthornamespace"></a>`namespace` | [`Namespace`](#namespace) | Personal namespace of the user. |
+| <a id="mergerequestauthorpreferencesgitpodpath"></a>`preferencesGitpodPath` | [`String`](#string) | Web path to the Gitpod section within user preferences. |
+| <a id="mergerequestauthorprofileenablegitpodpath"></a>`profileEnableGitpodPath` | [`String`](#string) | Web path to enable Gitpod for the user. |
+| <a id="mergerequestauthorprojectmemberships"></a>`projectMemberships` | [`ProjectMemberConnection`](#projectmemberconnection) | Project memberships of the user. (see [Connections](#connections)) |
+| <a id="mergerequestauthorpublicemail"></a>`publicEmail` | [`String`](#string) | User's public email. |
+| <a id="mergerequestauthorsavedreplies"></a>`savedReplies` | [`SavedReplyConnection`](#savedreplyconnection) | Saved replies authored by the user. (see [Connections](#connections)) |
+| <a id="mergerequestauthorstate"></a>`state` | [`UserState!`](#userstate) | State of the user. |
+| <a id="mergerequestauthorstatus"></a>`status` | [`UserStatus`](#userstatus) | User status. |
+| <a id="mergerequestauthoruserpermissions"></a>`userPermissions` | [`UserPermissions!`](#userpermissions) | Permissions for the current user on the resource. |
+| <a id="mergerequestauthorusername"></a>`username` | [`String!`](#string) | Username of the user. Unique within this instance of GitLab. |
+| <a id="mergerequestauthorwebpath"></a>`webPath` | [`String!`](#string) | Web path of the user. |
+| <a id="mergerequestauthorweburl"></a>`webUrl` | [`String!`](#string) | Web URL of the user. |
+
+#### Fields with arguments
+
+##### `MergeRequestAuthor.assignedMergeRequests`
+
+Merge requests assigned to the user.
+
+Returns [`MergeRequestConnection`](#mergerequestconnection).
+
+This field returns a [connection](#connections). It accepts the
+four standard [pagination arguments](#connection-pagination-arguments):
+`before: String`, `after: String`, `first: Int`, `last: Int`.
+
+###### Arguments
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mergerequestauthorassignedmergerequestsauthorusername"></a>`authorUsername` | [`String`](#string) | Username of the author. |
+| <a id="mergerequestauthorassignedmergerequestscreatedafter"></a>`createdAfter` | [`Time`](#time) | Merge requests created after this timestamp. |
+| <a id="mergerequestauthorassignedmergerequestscreatedbefore"></a>`createdBefore` | [`Time`](#time) | Merge requests created before this timestamp. |
+| <a id="mergerequestauthorassignedmergerequestsdraft"></a>`draft` | [`Boolean`](#boolean) | Limit result to draft merge requests. |
+| <a id="mergerequestauthorassignedmergerequestsiids"></a>`iids` | [`[String!]`](#string) | Array of IIDs of merge requests, for example `[1, 2]`. |
+| <a id="mergerequestauthorassignedmergerequestslabels"></a>`labels` | [`[String!]`](#string) | Array of label names. All resolved merge requests will have all of these labels. |
+| <a id="mergerequestauthorassignedmergerequestsmergedafter"></a>`mergedAfter` | [`Time`](#time) | Merge requests merged after this date. |
+| <a id="mergerequestauthorassignedmergerequestsmergedbefore"></a>`mergedBefore` | [`Time`](#time) | Merge requests merged before this date. |
+| <a id="mergerequestauthorassignedmergerequestsmilestonetitle"></a>`milestoneTitle` | [`String`](#string) | Title of the milestone. |
+| <a id="mergerequestauthorassignedmergerequestsnot"></a>`not` | [`MergeRequestsResolverNegatedParams`](#mergerequestsresolvernegatedparams) | List of negated arguments. Warning: this argument is experimental and a subject to change in future. |
+| <a id="mergerequestauthorassignedmergerequestsprojectid"></a>`projectId` | [`ProjectID`](#projectid) | The global ID of the project the authored merge requests should be in. Incompatible with projectPath. |
+| <a id="mergerequestauthorassignedmergerequestsprojectpath"></a>`projectPath` | [`String`](#string) | The full-path of the project the authored merge requests should be in. Incompatible with projectId. |
+| <a id="mergerequestauthorassignedmergerequestsreviewerusername"></a>`reviewerUsername` | [`String`](#string) | Username of the reviewer. |
+| <a id="mergerequestauthorassignedmergerequestssort"></a>`sort` | [`MergeRequestSort`](#mergerequestsort) | Sort merge requests by this criteria. |
+| <a id="mergerequestauthorassignedmergerequestssourcebranches"></a>`sourceBranches` | [`[String!]`](#string) | Array of source branch names. All resolved merge requests will have one of these branches as their source. |
+| <a id="mergerequestauthorassignedmergerequestsstate"></a>`state` | [`MergeRequestState`](#mergerequeststate) | Merge request state. If provided, all resolved merge requests will have this state. |
+| <a id="mergerequestauthorassignedmergerequeststargetbranches"></a>`targetBranches` | [`[String!]`](#string) | Array of target branch names. All resolved merge requests will have one of these branches as their target. |
+| <a id="mergerequestauthorassignedmergerequestsupdatedafter"></a>`updatedAfter` | [`Time`](#time) | Merge requests updated after this timestamp. |
+| <a id="mergerequestauthorassignedmergerequestsupdatedbefore"></a>`updatedBefore` | [`Time`](#time) | Merge requests updated before this timestamp. |
+
+##### `MergeRequestAuthor.authoredMergeRequests`
+
+Merge requests authored by the user.
+
+Returns [`MergeRequestConnection`](#mergerequestconnection).
+
+This field returns a [connection](#connections). It accepts the
+four standard [pagination arguments](#connection-pagination-arguments):
+`before: String`, `after: String`, `first: Int`, `last: Int`.
+
+###### Arguments
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mergerequestauthorauthoredmergerequestsassigneeusername"></a>`assigneeUsername` | [`String`](#string) | Username of the assignee. |
+| <a id="mergerequestauthorauthoredmergerequestscreatedafter"></a>`createdAfter` | [`Time`](#time) | Merge requests created after this timestamp. |
+| <a id="mergerequestauthorauthoredmergerequestscreatedbefore"></a>`createdBefore` | [`Time`](#time) | Merge requests created before this timestamp. |
+| <a id="mergerequestauthorauthoredmergerequestsdraft"></a>`draft` | [`Boolean`](#boolean) | Limit result to draft merge requests. |
+| <a id="mergerequestauthorauthoredmergerequestsiids"></a>`iids` | [`[String!]`](#string) | Array of IIDs of merge requests, for example `[1, 2]`. |
+| <a id="mergerequestauthorauthoredmergerequestslabels"></a>`labels` | [`[String!]`](#string) | Array of label names. All resolved merge requests will have all of these labels. |
+| <a id="mergerequestauthorauthoredmergerequestsmergedafter"></a>`mergedAfter` | [`Time`](#time) | Merge requests merged after this date. |
+| <a id="mergerequestauthorauthoredmergerequestsmergedbefore"></a>`mergedBefore` | [`Time`](#time) | Merge requests merged before this date. |
+| <a id="mergerequestauthorauthoredmergerequestsmilestonetitle"></a>`milestoneTitle` | [`String`](#string) | Title of the milestone. |
+| <a id="mergerequestauthorauthoredmergerequestsnot"></a>`not` | [`MergeRequestsResolverNegatedParams`](#mergerequestsresolvernegatedparams) | List of negated arguments. Warning: this argument is experimental and a subject to change in future. |
+| <a id="mergerequestauthorauthoredmergerequestsprojectid"></a>`projectId` | [`ProjectID`](#projectid) | The global ID of the project the authored merge requests should be in. Incompatible with projectPath. |
+| <a id="mergerequestauthorauthoredmergerequestsprojectpath"></a>`projectPath` | [`String`](#string) | The full-path of the project the authored merge requests should be in. Incompatible with projectId. |
+| <a id="mergerequestauthorauthoredmergerequestsreviewerusername"></a>`reviewerUsername` | [`String`](#string) | Username of the reviewer. |
+| <a id="mergerequestauthorauthoredmergerequestssort"></a>`sort` | [`MergeRequestSort`](#mergerequestsort) | Sort merge requests by this criteria. |
+| <a id="mergerequestauthorauthoredmergerequestssourcebranches"></a>`sourceBranches` | [`[String!]`](#string) | Array of source branch names. All resolved merge requests will have one of these branches as their source. |
+| <a id="mergerequestauthorauthoredmergerequestsstate"></a>`state` | [`MergeRequestState`](#mergerequeststate) | Merge request state. If provided, all resolved merge requests will have this state. |
+| <a id="mergerequestauthorauthoredmergerequeststargetbranches"></a>`targetBranches` | [`[String!]`](#string) | Array of target branch names. All resolved merge requests will have one of these branches as their target. |
+| <a id="mergerequestauthorauthoredmergerequestsupdatedafter"></a>`updatedAfter` | [`Time`](#time) | Merge requests updated after this timestamp. |
+| <a id="mergerequestauthorauthoredmergerequestsupdatedbefore"></a>`updatedBefore` | [`Time`](#time) | Merge requests updated before this timestamp. |
+
+##### `MergeRequestAuthor.groups`
+
+Groups where the user has access.
+
+Returns [`GroupConnection`](#groupconnection).
+
+This field returns a [connection](#connections). It accepts the
+four standard [pagination arguments](#connection-pagination-arguments):
+`before: String`, `after: String`, `first: Int`, `last: Int`.
+
+###### Arguments
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mergerequestauthorgroupspermissionscope"></a>`permissionScope` | [`GroupPermission`](#grouppermission) | Filter by permissions the user has on groups. |
+| <a id="mergerequestauthorgroupssearch"></a>`search` | [`String`](#string) | Search by group name or path. |
+
+##### `MergeRequestAuthor.reviewRequestedMergeRequests`
+
+Merge requests assigned to the user for review.
+
+Returns [`MergeRequestConnection`](#mergerequestconnection).
+
+This field returns a [connection](#connections). It accepts the
+four standard [pagination arguments](#connection-pagination-arguments):
+`before: String`, `after: String`, `first: Int`, `last: Int`.
+
+###### Arguments
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mergerequestauthorreviewrequestedmergerequestsassigneeusername"></a>`assigneeUsername` | [`String`](#string) | Username of the assignee. |
+| <a id="mergerequestauthorreviewrequestedmergerequestsauthorusername"></a>`authorUsername` | [`String`](#string) | Username of the author. |
+| <a id="mergerequestauthorreviewrequestedmergerequestscreatedafter"></a>`createdAfter` | [`Time`](#time) | Merge requests created after this timestamp. |
+| <a id="mergerequestauthorreviewrequestedmergerequestscreatedbefore"></a>`createdBefore` | [`Time`](#time) | Merge requests created before this timestamp. |
+| <a id="mergerequestauthorreviewrequestedmergerequestsdraft"></a>`draft` | [`Boolean`](#boolean) | Limit result to draft merge requests. |
+| <a id="mergerequestauthorreviewrequestedmergerequestsiids"></a>`iids` | [`[String!]`](#string) | Array of IIDs of merge requests, for example `[1, 2]`. |
+| <a id="mergerequestauthorreviewrequestedmergerequestslabels"></a>`labels` | [`[String!]`](#string) | Array of label names. All resolved merge requests will have all of these labels. |
+| <a id="mergerequestauthorreviewrequestedmergerequestsmergedafter"></a>`mergedAfter` | [`Time`](#time) | Merge requests merged after this date. |
+| <a id="mergerequestauthorreviewrequestedmergerequestsmergedbefore"></a>`mergedBefore` | [`Time`](#time) | Merge requests merged before this date. |
+| <a id="mergerequestauthorreviewrequestedmergerequestsmilestonetitle"></a>`milestoneTitle` | [`String`](#string) | Title of the milestone. |
+| <a id="mergerequestauthorreviewrequestedmergerequestsnot"></a>`not` | [`MergeRequestsResolverNegatedParams`](#mergerequestsresolvernegatedparams) | List of negated arguments. Warning: this argument is experimental and a subject to change in future. |
+| <a id="mergerequestauthorreviewrequestedmergerequestsprojectid"></a>`projectId` | [`ProjectID`](#projectid) | The global ID of the project the authored merge requests should be in. Incompatible with projectPath. |
+| <a id="mergerequestauthorreviewrequestedmergerequestsprojectpath"></a>`projectPath` | [`String`](#string) | The full-path of the project the authored merge requests should be in. Incompatible with projectId. |
+| <a id="mergerequestauthorreviewrequestedmergerequestssort"></a>`sort` | [`MergeRequestSort`](#mergerequestsort) | Sort merge requests by this criteria. |
+| <a id="mergerequestauthorreviewrequestedmergerequestssourcebranches"></a>`sourceBranches` | [`[String!]`](#string) | Array of source branch names. All resolved merge requests will have one of these branches as their source. |
+| <a id="mergerequestauthorreviewrequestedmergerequestsstate"></a>`state` | [`MergeRequestState`](#mergerequeststate) | Merge request state. If provided, all resolved merge requests will have this state. |
+| <a id="mergerequestauthorreviewrequestedmergerequeststargetbranches"></a>`targetBranches` | [`[String!]`](#string) | Array of target branch names. All resolved merge requests will have one of these branches as their target. |
+| <a id="mergerequestauthorreviewrequestedmergerequestsupdatedafter"></a>`updatedAfter` | [`Time`](#time) | Merge requests updated after this timestamp. |
+| <a id="mergerequestauthorreviewrequestedmergerequestsupdatedbefore"></a>`updatedBefore` | [`Time`](#time) | Merge requests updated before this timestamp. |
+
+##### `MergeRequestAuthor.snippets`
+
+Snippets authored by the user.
+
+Returns [`SnippetConnection`](#snippetconnection).
+
+This field returns a [connection](#connections). It accepts the
+four standard [pagination arguments](#connection-pagination-arguments):
+`before: String`, `after: String`, `first: Int`, `last: Int`.
+
+###### Arguments
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mergerequestauthorsnippetsids"></a>`ids` | [`[SnippetID!]`](#snippetid) | Array of global snippet IDs. For example, `gid://gitlab/ProjectSnippet/1`. |
+| <a id="mergerequestauthorsnippetstype"></a>`type` | [`TypeEnum`](#typeenum) | Type of snippet. |
+| <a id="mergerequestauthorsnippetsvisibility"></a>`visibility` | [`VisibilityScopesEnum`](#visibilityscopesenum) | Visibility of the snippet. |
+
+##### `MergeRequestAuthor.starredProjects`
+
+Projects starred by the user.
+
+Returns [`ProjectConnection`](#projectconnection).
+
+This field returns a [connection](#connections). It accepts the
+four standard [pagination arguments](#connection-pagination-arguments):
+`before: String`, `after: String`, `first: Int`, `last: Int`.
+
+###### Arguments
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mergerequestauthorstarredprojectssearch"></a>`search` | [`String`](#string) | Search query. |
+
+##### `MergeRequestAuthor.timelogs`
+
+Time logged by the user.
+
+Returns [`TimelogConnection`](#timelogconnection).
+
+This field returns a [connection](#connections). It accepts the
+four standard [pagination arguments](#connection-pagination-arguments):
+`before: String`, `after: String`, `first: Int`, `last: Int`.
+
+###### Arguments
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mergerequestauthortimelogsenddate"></a>`endDate` | [`Time`](#time) | List timelogs within a date range where the logged date is equal to or before endDate. |
+| <a id="mergerequestauthortimelogsendtime"></a>`endTime` | [`Time`](#time) | List timelogs within a time range where the logged time is equal to or before endTime. |
+| <a id="mergerequestauthortimelogsgroupid"></a>`groupId` | [`GroupID`](#groupid) | List timelogs for a group. |
+| <a id="mergerequestauthortimelogsprojectid"></a>`projectId` | [`ProjectID`](#projectid) | List timelogs for a project. |
+| <a id="mergerequestauthortimelogsstartdate"></a>`startDate` | [`Time`](#time) | List timelogs within a date range where the logged date is equal to or after startDate. |
+| <a id="mergerequestauthortimelogsstarttime"></a>`startTime` | [`Time`](#time) | List timelogs within a time range where the logged time is equal to or after startTime. |
+| <a id="mergerequestauthortimelogsusername"></a>`username` | [`String`](#string) | List timelogs for a user. |
+
+##### `MergeRequestAuthor.todos`
+
+To-do items of the user.
+
+Returns [`TodoConnection`](#todoconnection).
+
+This field returns a [connection](#connections). It accepts the
+four standard [pagination arguments](#connection-pagination-arguments):
+`before: String`, `after: String`, `first: Int`, `last: Int`.
+
+###### Arguments
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mergerequestauthortodosaction"></a>`action` | [`[TodoActionEnum!]`](#todoactionenum) | Action to be filtered. |
+| <a id="mergerequestauthortodosauthorid"></a>`authorId` | [`[ID!]`](#id) | ID of an author. |
+| <a id="mergerequestauthortodosgroupid"></a>`groupId` | [`[ID!]`](#id) | ID of a group. |
+| <a id="mergerequestauthortodosprojectid"></a>`projectId` | [`[ID!]`](#id) | ID of a project. |
+| <a id="mergerequestauthortodosstate"></a>`state` | [`[TodoStateEnum!]`](#todostateenum) | State of the todo. |
+| <a id="mergerequestauthortodostype"></a>`type` | [`[TodoTargetEnum!]`](#todotargetenum) | Type of the todo. |
+
### `MergeRequestDiffRegistry`
Represents the Geo sync and verification state of a Merge Request diff.
@@ -12527,6 +13043,236 @@ Represents the Geo sync and verification state of a Merge Request diff.
| <a id="mergerequestdiffregistryretrycount"></a>`retryCount` | [`Int`](#int) | Number of consecutive failed sync attempts of the MergeRequestDiffRegistry. |
| <a id="mergerequestdiffregistrystate"></a>`state` | [`RegistryState`](#registrystate) | Sync state of the MergeRequestDiffRegistry. |
+### `MergeRequestParticipant`
+
+A user participating in a merge request.
+
+#### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mergerequestparticipantavatarurl"></a>`avatarUrl` | [`String`](#string) | URL of the user's avatar. |
+| <a id="mergerequestparticipantbot"></a>`bot` | [`Boolean!`](#boolean) | Indicates if the user is a bot. |
+| <a id="mergerequestparticipantcallouts"></a>`callouts` | [`UserCalloutConnection`](#usercalloutconnection) | User callouts that belong to the user. (see [Connections](#connections)) |
+| <a id="mergerequestparticipantemail"></a>`email` **{warning-solid}** | [`String`](#string) | **Deprecated** in 13.7. This was renamed. Use: [`User.publicEmail`](#userpublicemail). |
+| <a id="mergerequestparticipantgitpodenabled"></a>`gitpodEnabled` | [`Boolean`](#boolean) | Whether Gitpod is enabled at the user level. |
+| <a id="mergerequestparticipantgroupcount"></a>`groupCount` | [`Int`](#int) | Group count for the user. |
+| <a id="mergerequestparticipantgroupmemberships"></a>`groupMemberships` | [`GroupMemberConnection`](#groupmemberconnection) | Group memberships of the user. (see [Connections](#connections)) |
+| <a id="mergerequestparticipantid"></a>`id` | [`ID!`](#id) | ID of the user. |
+| <a id="mergerequestparticipantlocation"></a>`location` | [`String`](#string) | Location of the user. |
+| <a id="mergerequestparticipantmergerequestinteraction"></a>`mergeRequestInteraction` | [`UserMergeRequestInteraction`](#usermergerequestinteraction) | Details of this user's interactions with the merge request. |
+| <a id="mergerequestparticipantname"></a>`name` | [`String!`](#string) | Human-readable name of the user. Returns `****` if the user is a project bot and the requester does not have permission to view the project. |
+| <a id="mergerequestparticipantnamespace"></a>`namespace` | [`Namespace`](#namespace) | Personal namespace of the user. |
+| <a id="mergerequestparticipantpreferencesgitpodpath"></a>`preferencesGitpodPath` | [`String`](#string) | Web path to the Gitpod section within user preferences. |
+| <a id="mergerequestparticipantprofileenablegitpodpath"></a>`profileEnableGitpodPath` | [`String`](#string) | Web path to enable Gitpod for the user. |
+| <a id="mergerequestparticipantprojectmemberships"></a>`projectMemberships` | [`ProjectMemberConnection`](#projectmemberconnection) | Project memberships of the user. (see [Connections](#connections)) |
+| <a id="mergerequestparticipantpublicemail"></a>`publicEmail` | [`String`](#string) | User's public email. |
+| <a id="mergerequestparticipantsavedreplies"></a>`savedReplies` | [`SavedReplyConnection`](#savedreplyconnection) | Saved replies authored by the user. (see [Connections](#connections)) |
+| <a id="mergerequestparticipantstate"></a>`state` | [`UserState!`](#userstate) | State of the user. |
+| <a id="mergerequestparticipantstatus"></a>`status` | [`UserStatus`](#userstatus) | User status. |
+| <a id="mergerequestparticipantuserpermissions"></a>`userPermissions` | [`UserPermissions!`](#userpermissions) | Permissions for the current user on the resource. |
+| <a id="mergerequestparticipantusername"></a>`username` | [`String!`](#string) | Username of the user. Unique within this instance of GitLab. |
+| <a id="mergerequestparticipantwebpath"></a>`webPath` | [`String!`](#string) | Web path of the user. |
+| <a id="mergerequestparticipantweburl"></a>`webUrl` | [`String!`](#string) | Web URL of the user. |
+
+#### Fields with arguments
+
+##### `MergeRequestParticipant.assignedMergeRequests`
+
+Merge requests assigned to the user.
+
+Returns [`MergeRequestConnection`](#mergerequestconnection).
+
+This field returns a [connection](#connections). It accepts the
+four standard [pagination arguments](#connection-pagination-arguments):
+`before: String`, `after: String`, `first: Int`, `last: Int`.
+
+###### Arguments
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mergerequestparticipantassignedmergerequestsauthorusername"></a>`authorUsername` | [`String`](#string) | Username of the author. |
+| <a id="mergerequestparticipantassignedmergerequestscreatedafter"></a>`createdAfter` | [`Time`](#time) | Merge requests created after this timestamp. |
+| <a id="mergerequestparticipantassignedmergerequestscreatedbefore"></a>`createdBefore` | [`Time`](#time) | Merge requests created before this timestamp. |
+| <a id="mergerequestparticipantassignedmergerequestsdraft"></a>`draft` | [`Boolean`](#boolean) | Limit result to draft merge requests. |
+| <a id="mergerequestparticipantassignedmergerequestsiids"></a>`iids` | [`[String!]`](#string) | Array of IIDs of merge requests, for example `[1, 2]`. |
+| <a id="mergerequestparticipantassignedmergerequestslabels"></a>`labels` | [`[String!]`](#string) | Array of label names. All resolved merge requests will have all of these labels. |
+| <a id="mergerequestparticipantassignedmergerequestsmergedafter"></a>`mergedAfter` | [`Time`](#time) | Merge requests merged after this date. |
+| <a id="mergerequestparticipantassignedmergerequestsmergedbefore"></a>`mergedBefore` | [`Time`](#time) | Merge requests merged before this date. |
+| <a id="mergerequestparticipantassignedmergerequestsmilestonetitle"></a>`milestoneTitle` | [`String`](#string) | Title of the milestone. |
+| <a id="mergerequestparticipantassignedmergerequestsnot"></a>`not` | [`MergeRequestsResolverNegatedParams`](#mergerequestsresolvernegatedparams) | List of negated arguments. Warning: this argument is experimental and a subject to change in future. |
+| <a id="mergerequestparticipantassignedmergerequestsprojectid"></a>`projectId` | [`ProjectID`](#projectid) | The global ID of the project the authored merge requests should be in. Incompatible with projectPath. |
+| <a id="mergerequestparticipantassignedmergerequestsprojectpath"></a>`projectPath` | [`String`](#string) | The full-path of the project the authored merge requests should be in. Incompatible with projectId. |
+| <a id="mergerequestparticipantassignedmergerequestsreviewerusername"></a>`reviewerUsername` | [`String`](#string) | Username of the reviewer. |
+| <a id="mergerequestparticipantassignedmergerequestssort"></a>`sort` | [`MergeRequestSort`](#mergerequestsort) | Sort merge requests by this criteria. |
+| <a id="mergerequestparticipantassignedmergerequestssourcebranches"></a>`sourceBranches` | [`[String!]`](#string) | Array of source branch names. All resolved merge requests will have one of these branches as their source. |
+| <a id="mergerequestparticipantassignedmergerequestsstate"></a>`state` | [`MergeRequestState`](#mergerequeststate) | Merge request state. If provided, all resolved merge requests will have this state. |
+| <a id="mergerequestparticipantassignedmergerequeststargetbranches"></a>`targetBranches` | [`[String!]`](#string) | Array of target branch names. All resolved merge requests will have one of these branches as their target. |
+| <a id="mergerequestparticipantassignedmergerequestsupdatedafter"></a>`updatedAfter` | [`Time`](#time) | Merge requests updated after this timestamp. |
+| <a id="mergerequestparticipantassignedmergerequestsupdatedbefore"></a>`updatedBefore` | [`Time`](#time) | Merge requests updated before this timestamp. |
+
+##### `MergeRequestParticipant.authoredMergeRequests`
+
+Merge requests authored by the user.
+
+Returns [`MergeRequestConnection`](#mergerequestconnection).
+
+This field returns a [connection](#connections). It accepts the
+four standard [pagination arguments](#connection-pagination-arguments):
+`before: String`, `after: String`, `first: Int`, `last: Int`.
+
+###### Arguments
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mergerequestparticipantauthoredmergerequestsassigneeusername"></a>`assigneeUsername` | [`String`](#string) | Username of the assignee. |
+| <a id="mergerequestparticipantauthoredmergerequestscreatedafter"></a>`createdAfter` | [`Time`](#time) | Merge requests created after this timestamp. |
+| <a id="mergerequestparticipantauthoredmergerequestscreatedbefore"></a>`createdBefore` | [`Time`](#time) | Merge requests created before this timestamp. |
+| <a id="mergerequestparticipantauthoredmergerequestsdraft"></a>`draft` | [`Boolean`](#boolean) | Limit result to draft merge requests. |
+| <a id="mergerequestparticipantauthoredmergerequestsiids"></a>`iids` | [`[String!]`](#string) | Array of IIDs of merge requests, for example `[1, 2]`. |
+| <a id="mergerequestparticipantauthoredmergerequestslabels"></a>`labels` | [`[String!]`](#string) | Array of label names. All resolved merge requests will have all of these labels. |
+| <a id="mergerequestparticipantauthoredmergerequestsmergedafter"></a>`mergedAfter` | [`Time`](#time) | Merge requests merged after this date. |
+| <a id="mergerequestparticipantauthoredmergerequestsmergedbefore"></a>`mergedBefore` | [`Time`](#time) | Merge requests merged before this date. |
+| <a id="mergerequestparticipantauthoredmergerequestsmilestonetitle"></a>`milestoneTitle` | [`String`](#string) | Title of the milestone. |
+| <a id="mergerequestparticipantauthoredmergerequestsnot"></a>`not` | [`MergeRequestsResolverNegatedParams`](#mergerequestsresolvernegatedparams) | List of negated arguments. Warning: this argument is experimental and a subject to change in future. |
+| <a id="mergerequestparticipantauthoredmergerequestsprojectid"></a>`projectId` | [`ProjectID`](#projectid) | The global ID of the project the authored merge requests should be in. Incompatible with projectPath. |
+| <a id="mergerequestparticipantauthoredmergerequestsprojectpath"></a>`projectPath` | [`String`](#string) | The full-path of the project the authored merge requests should be in. Incompatible with projectId. |
+| <a id="mergerequestparticipantauthoredmergerequestsreviewerusername"></a>`reviewerUsername` | [`String`](#string) | Username of the reviewer. |
+| <a id="mergerequestparticipantauthoredmergerequestssort"></a>`sort` | [`MergeRequestSort`](#mergerequestsort) | Sort merge requests by this criteria. |
+| <a id="mergerequestparticipantauthoredmergerequestssourcebranches"></a>`sourceBranches` | [`[String!]`](#string) | Array of source branch names. All resolved merge requests will have one of these branches as their source. |
+| <a id="mergerequestparticipantauthoredmergerequestsstate"></a>`state` | [`MergeRequestState`](#mergerequeststate) | Merge request state. If provided, all resolved merge requests will have this state. |
+| <a id="mergerequestparticipantauthoredmergerequeststargetbranches"></a>`targetBranches` | [`[String!]`](#string) | Array of target branch names. All resolved merge requests will have one of these branches as their target. |
+| <a id="mergerequestparticipantauthoredmergerequestsupdatedafter"></a>`updatedAfter` | [`Time`](#time) | Merge requests updated after this timestamp. |
+| <a id="mergerequestparticipantauthoredmergerequestsupdatedbefore"></a>`updatedBefore` | [`Time`](#time) | Merge requests updated before this timestamp. |
+
+##### `MergeRequestParticipant.groups`
+
+Groups where the user has access.
+
+Returns [`GroupConnection`](#groupconnection).
+
+This field returns a [connection](#connections). It accepts the
+four standard [pagination arguments](#connection-pagination-arguments):
+`before: String`, `after: String`, `first: Int`, `last: Int`.
+
+###### Arguments
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mergerequestparticipantgroupspermissionscope"></a>`permissionScope` | [`GroupPermission`](#grouppermission) | Filter by permissions the user has on groups. |
+| <a id="mergerequestparticipantgroupssearch"></a>`search` | [`String`](#string) | Search by group name or path. |
+
+##### `MergeRequestParticipant.reviewRequestedMergeRequests`
+
+Merge requests assigned to the user for review.
+
+Returns [`MergeRequestConnection`](#mergerequestconnection).
+
+This field returns a [connection](#connections). It accepts the
+four standard [pagination arguments](#connection-pagination-arguments):
+`before: String`, `after: String`, `first: Int`, `last: Int`.
+
+###### Arguments
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mergerequestparticipantreviewrequestedmergerequestsassigneeusername"></a>`assigneeUsername` | [`String`](#string) | Username of the assignee. |
+| <a id="mergerequestparticipantreviewrequestedmergerequestsauthorusername"></a>`authorUsername` | [`String`](#string) | Username of the author. |
+| <a id="mergerequestparticipantreviewrequestedmergerequestscreatedafter"></a>`createdAfter` | [`Time`](#time) | Merge requests created after this timestamp. |
+| <a id="mergerequestparticipantreviewrequestedmergerequestscreatedbefore"></a>`createdBefore` | [`Time`](#time) | Merge requests created before this timestamp. |
+| <a id="mergerequestparticipantreviewrequestedmergerequestsdraft"></a>`draft` | [`Boolean`](#boolean) | Limit result to draft merge requests. |
+| <a id="mergerequestparticipantreviewrequestedmergerequestsiids"></a>`iids` | [`[String!]`](#string) | Array of IIDs of merge requests, for example `[1, 2]`. |
+| <a id="mergerequestparticipantreviewrequestedmergerequestslabels"></a>`labels` | [`[String!]`](#string) | Array of label names. All resolved merge requests will have all of these labels. |
+| <a id="mergerequestparticipantreviewrequestedmergerequestsmergedafter"></a>`mergedAfter` | [`Time`](#time) | Merge requests merged after this date. |
+| <a id="mergerequestparticipantreviewrequestedmergerequestsmergedbefore"></a>`mergedBefore` | [`Time`](#time) | Merge requests merged before this date. |
+| <a id="mergerequestparticipantreviewrequestedmergerequestsmilestonetitle"></a>`milestoneTitle` | [`String`](#string) | Title of the milestone. |
+| <a id="mergerequestparticipantreviewrequestedmergerequestsnot"></a>`not` | [`MergeRequestsResolverNegatedParams`](#mergerequestsresolvernegatedparams) | List of negated arguments. Warning: this argument is experimental and a subject to change in future. |
+| <a id="mergerequestparticipantreviewrequestedmergerequestsprojectid"></a>`projectId` | [`ProjectID`](#projectid) | The global ID of the project the authored merge requests should be in. Incompatible with projectPath. |
+| <a id="mergerequestparticipantreviewrequestedmergerequestsprojectpath"></a>`projectPath` | [`String`](#string) | The full-path of the project the authored merge requests should be in. Incompatible with projectId. |
+| <a id="mergerequestparticipantreviewrequestedmergerequestssort"></a>`sort` | [`MergeRequestSort`](#mergerequestsort) | Sort merge requests by this criteria. |
+| <a id="mergerequestparticipantreviewrequestedmergerequestssourcebranches"></a>`sourceBranches` | [`[String!]`](#string) | Array of source branch names. All resolved merge requests will have one of these branches as their source. |
+| <a id="mergerequestparticipantreviewrequestedmergerequestsstate"></a>`state` | [`MergeRequestState`](#mergerequeststate) | Merge request state. If provided, all resolved merge requests will have this state. |
+| <a id="mergerequestparticipantreviewrequestedmergerequeststargetbranches"></a>`targetBranches` | [`[String!]`](#string) | Array of target branch names. All resolved merge requests will have one of these branches as their target. |
+| <a id="mergerequestparticipantreviewrequestedmergerequestsupdatedafter"></a>`updatedAfter` | [`Time`](#time) | Merge requests updated after this timestamp. |
+| <a id="mergerequestparticipantreviewrequestedmergerequestsupdatedbefore"></a>`updatedBefore` | [`Time`](#time) | Merge requests updated before this timestamp. |
+
+##### `MergeRequestParticipant.snippets`
+
+Snippets authored by the user.
+
+Returns [`SnippetConnection`](#snippetconnection).
+
+This field returns a [connection](#connections). It accepts the
+four standard [pagination arguments](#connection-pagination-arguments):
+`before: String`, `after: String`, `first: Int`, `last: Int`.
+
+###### Arguments
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mergerequestparticipantsnippetsids"></a>`ids` | [`[SnippetID!]`](#snippetid) | Array of global snippet IDs. For example, `gid://gitlab/ProjectSnippet/1`. |
+| <a id="mergerequestparticipantsnippetstype"></a>`type` | [`TypeEnum`](#typeenum) | Type of snippet. |
+| <a id="mergerequestparticipantsnippetsvisibility"></a>`visibility` | [`VisibilityScopesEnum`](#visibilityscopesenum) | Visibility of the snippet. |
+
+##### `MergeRequestParticipant.starredProjects`
+
+Projects starred by the user.
+
+Returns [`ProjectConnection`](#projectconnection).
+
+This field returns a [connection](#connections). It accepts the
+four standard [pagination arguments](#connection-pagination-arguments):
+`before: String`, `after: String`, `first: Int`, `last: Int`.
+
+###### Arguments
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mergerequestparticipantstarredprojectssearch"></a>`search` | [`String`](#string) | Search query. |
+
+##### `MergeRequestParticipant.timelogs`
+
+Time logged by the user.
+
+Returns [`TimelogConnection`](#timelogconnection).
+
+This field returns a [connection](#connections). It accepts the
+four standard [pagination arguments](#connection-pagination-arguments):
+`before: String`, `after: String`, `first: Int`, `last: Int`.
+
+###### Arguments
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mergerequestparticipanttimelogsenddate"></a>`endDate` | [`Time`](#time) | List timelogs within a date range where the logged date is equal to or before endDate. |
+| <a id="mergerequestparticipanttimelogsendtime"></a>`endTime` | [`Time`](#time) | List timelogs within a time range where the logged time is equal to or before endTime. |
+| <a id="mergerequestparticipanttimelogsgroupid"></a>`groupId` | [`GroupID`](#groupid) | List timelogs for a group. |
+| <a id="mergerequestparticipanttimelogsprojectid"></a>`projectId` | [`ProjectID`](#projectid) | List timelogs for a project. |
+| <a id="mergerequestparticipanttimelogsstartdate"></a>`startDate` | [`Time`](#time) | List timelogs within a date range where the logged date is equal to or after startDate. |
+| <a id="mergerequestparticipanttimelogsstarttime"></a>`startTime` | [`Time`](#time) | List timelogs within a time range where the logged time is equal to or after startTime. |
+| <a id="mergerequestparticipanttimelogsusername"></a>`username` | [`String`](#string) | List timelogs for a user. |
+
+##### `MergeRequestParticipant.todos`
+
+To-do items of the user.
+
+Returns [`TodoConnection`](#todoconnection).
+
+This field returns a [connection](#connections). It accepts the
+four standard [pagination arguments](#connection-pagination-arguments):
+`before: String`, `after: String`, `first: Int`, `last: Int`.
+
+###### Arguments
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="mergerequestparticipanttodosaction"></a>`action` | [`[TodoActionEnum!]`](#todoactionenum) | Action to be filtered. |
+| <a id="mergerequestparticipanttodosauthorid"></a>`authorId` | [`[ID!]`](#id) | ID of an author. |
+| <a id="mergerequestparticipanttodosgroupid"></a>`groupId` | [`[ID!]`](#id) | ID of a group. |
+| <a id="mergerequestparticipanttodosprojectid"></a>`projectId` | [`[ID!]`](#id) | ID of a project. |
+| <a id="mergerequestparticipanttodosstate"></a>`state` | [`[TodoStateEnum!]`](#todostateenum) | State of the todo. |
+| <a id="mergerequestparticipanttodostype"></a>`type` | [`[TodoTargetEnum!]`](#todotargetenum) | Type of the todo. |
+
### `MergeRequestPermissions`
Check permissions for the current user on a merge request.
@@ -12557,6 +13303,7 @@ A user assigned to a merge request as a reviewer.
| <a id="mergerequestreviewerbot"></a>`bot` | [`Boolean!`](#boolean) | Indicates if the user is a bot. |
| <a id="mergerequestreviewercallouts"></a>`callouts` | [`UserCalloutConnection`](#usercalloutconnection) | User callouts that belong to the user. (see [Connections](#connections)) |
| <a id="mergerequestrevieweremail"></a>`email` **{warning-solid}** | [`String`](#string) | **Deprecated** in 13.7. This was renamed. Use: [`User.publicEmail`](#userpublicemail). |
+| <a id="mergerequestreviewergitpodenabled"></a>`gitpodEnabled` | [`Boolean`](#boolean) | Whether Gitpod is enabled at the user level. |
| <a id="mergerequestreviewergroupcount"></a>`groupCount` | [`Int`](#int) | Group count for the user. |
| <a id="mergerequestreviewergroupmemberships"></a>`groupMemberships` | [`GroupMemberConnection`](#groupmemberconnection) | Group memberships of the user. (see [Connections](#connections)) |
| <a id="mergerequestreviewerid"></a>`id` | [`ID!`](#id) | ID of the user. |
@@ -12564,8 +13311,11 @@ A user assigned to a merge request as a reviewer.
| <a id="mergerequestreviewermergerequestinteraction"></a>`mergeRequestInteraction` | [`UserMergeRequestInteraction`](#usermergerequestinteraction) | Details of this user's interactions with the merge request. |
| <a id="mergerequestreviewername"></a>`name` | [`String!`](#string) | Human-readable name of the user. Returns `****` if the user is a project bot and the requester does not have permission to view the project. |
| <a id="mergerequestreviewernamespace"></a>`namespace` | [`Namespace`](#namespace) | Personal namespace of the user. |
+| <a id="mergerequestreviewerpreferencesgitpodpath"></a>`preferencesGitpodPath` | [`String`](#string) | Web path to the Gitpod section within user preferences. |
+| <a id="mergerequestreviewerprofileenablegitpodpath"></a>`profileEnableGitpodPath` | [`String`](#string) | Web path to enable Gitpod for the user. |
| <a id="mergerequestreviewerprojectmemberships"></a>`projectMemberships` | [`ProjectMemberConnection`](#projectmemberconnection) | Project memberships of the user. (see [Connections](#connections)) |
| <a id="mergerequestreviewerpublicemail"></a>`publicEmail` | [`String`](#string) | User's public email. |
+| <a id="mergerequestreviewersavedreplies"></a>`savedReplies` | [`SavedReplyConnection`](#savedreplyconnection) | Saved replies authored by the user. (see [Connections](#connections)) |
| <a id="mergerequestreviewerstate"></a>`state` | [`UserState!`](#userstate) | State of the user. |
| <a id="mergerequestreviewerstatus"></a>`status` | [`UserStatus`](#userstatus) | User status. |
| <a id="mergerequestrevieweruserpermissions"></a>`userPermissions` | [`UserPermissions!`](#userpermissions) | Permissions for the current user on the resource. |
@@ -12851,7 +13601,6 @@ Represents a milestone.
| <a id="milestoneid"></a>`id` | [`ID!`](#id) | ID of the milestone. |
| <a id="milestoneiid"></a>`iid` | [`ID!`](#id) | Internal ID of the milestone. |
| <a id="milestoneprojectmilestone"></a>`projectMilestone` | [`Boolean!`](#boolean) | Indicates if milestone is at project level. |
-| <a id="milestonereport"></a>`report` | [`TimeboxReport`](#timeboxreport) | Historically accurate report about the timebox. |
| <a id="milestonestartdate"></a>`startDate` | [`Time`](#time) | Timestamp of the milestone start date. |
| <a id="milestonestate"></a>`state` | [`MilestoneStateEnum!`](#milestonestateenum) | State of the milestone. |
| <a id="milestonestats"></a>`stats` | [`MilestoneStats`](#milestonestats) | Milestone statistics. |
@@ -12860,6 +13609,20 @@ Represents a milestone.
| <a id="milestoneupdatedat"></a>`updatedAt` | [`Time!`](#time) | Timestamp of last milestone update. |
| <a id="milestonewebpath"></a>`webPath` | [`String!`](#string) | Web path of the milestone. |
+#### Fields with arguments
+
+##### `Milestone.report`
+
+Historically accurate report about the timebox.
+
+Returns [`TimeboxReport`](#timeboxreport).
+
+###### Arguments
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="milestonereportfullpath"></a>`fullPath` | [`String`](#string) | Full path of the project or group used as a scope for report. For example, `gitlab-org` or `gitlab-org/gitlab`. |
+
### `MilestoneStats`
Contains statistics about a milestone.
@@ -12880,6 +13643,7 @@ Contains statistics about a milestone.
| <a id="namespaceactualrepositorysizelimit"></a>`actualRepositorySizeLimit` | [`Float`](#float) | Size limit for repositories in the namespace in bytes. |
| <a id="namespaceadditionalpurchasedstoragesize"></a>`additionalPurchasedStorageSize` | [`Float`](#float) | Additional storage purchased for the root namespace in bytes. |
| <a id="namespacecontainslockedprojects"></a>`containsLockedProjects` | [`Boolean!`](#boolean) | Includes at least one project where the repository size exceeds the limit. |
+| <a id="namespacecrossprojectpipelineavailable"></a>`crossProjectPipelineAvailable` | [`Boolean!`](#boolean) | Indicates if the cross_project_pipeline feature is available for the namespace. |
| <a id="namespacedescription"></a>`description` | [`String`](#string) | Description of the namespace. |
| <a id="namespacedescriptionhtml"></a>`descriptionHtml` | [`String`](#string) | The GitLab Flavored Markdown rendering of `description`. |
| <a id="namespacefullname"></a>`fullName` | [`String!`](#string) | Full name of the namespace. |
@@ -13529,7 +14293,7 @@ Represents vulnerability finding of a security report on the pipeline.
| <a id="projectcontainerexpirationpolicy"></a>`containerExpirationPolicy` | [`ContainerExpirationPolicy`](#containerexpirationpolicy) | Container expiration policy of the project. |
| <a id="projectcontainerregistryenabled"></a>`containerRegistryEnabled` | [`Boolean`](#boolean) | Indicates if Container Registry is enabled for the current user. |
| <a id="projectcontainerrepositoriescount"></a>`containerRepositoriesCount` | [`Int!`](#int) | Number of container repositories in the project. |
-| <a id="projectcorpuses"></a>`corpuses` | [`CoverageFuzzingCorpusConnection`](#coveragefuzzingcorpusconnection) | Find corpuses of the project. Available only when feature flag `corpus_management` is enabled. This flag is enabled by default. (see [Connections](#connections)) |
+| <a id="projectcorpuses"></a>`corpuses` | [`CoverageFuzzingCorpusConnection`](#coveragefuzzingcorpusconnection) | Find corpuses of the project. (see [Connections](#connections)) |
| <a id="projectcreatedat"></a>`createdAt` | [`Time`](#time) | Timestamp of the project creation. |
| <a id="projectdastscannerprofiles"></a>`dastScannerProfiles` | [`DastScannerProfileConnection`](#dastscannerprofileconnection) | DAST scanner profiles associated with the project. (see [Connections](#connections)) |
| <a id="projectdastsiteprofiles"></a>`dastSiteProfiles` | [`DastSiteProfileConnection`](#dastsiteprofileconnection) | DAST Site Profiles associated with the project. (see [Connections](#connections)) |
@@ -13593,7 +14357,6 @@ Represents vulnerability finding of a security report on the pipeline.
| <a id="projectvulnerabilityscanners"></a>`vulnerabilityScanners` | [`VulnerabilityScannerConnection`](#vulnerabilityscannerconnection) | Vulnerability scanners reported on the project vulnerabilities. (see [Connections](#connections)) |
| <a id="projectweburl"></a>`webUrl` | [`String`](#string) | Web URL of the project. |
| <a id="projectwikienabled"></a>`wikiEnabled` | [`Boolean`](#boolean) | Indicates if Wikis are enabled for the current user. |
-| <a id="projectworkitemtypes"></a>`workItemTypes` | [`WorkItemTypeConnection`](#workitemtypeconnection) | Work item types available to the project. Available only when feature flag `work_items` is enabled. This flag is disabled by default, because the feature is experimental and is subject to change without notice. (see [Connections](#connections)) |
#### Fields with arguments
@@ -14209,6 +14972,10 @@ four standard [pagination arguments](#connection-pagination-arguments):
Network Policies of the project.
+WARNING:
+**Deprecated** in 14.8.
+Network policies are deprecated and will be removed in GitLab 15.0.
+
Returns [`NetworkPolicyConnection`](#networkpolicyconnection).
This field returns a [connection](#connections). It accepts the
@@ -14287,6 +15054,9 @@ four standard [pagination arguments](#connection-pagination-arguments):
| <a id="projectpipelinessha"></a>`sha` | [`String`](#string) | Filter pipelines by the sha of the commit they are run for. |
| <a id="projectpipelinessource"></a>`source` | [`String`](#string) | Filter pipelines by their source. |
| <a id="projectpipelinesstatus"></a>`status` | [`PipelineStatusEnum`](#pipelinestatusenum) | Filter pipelines by their status. |
+| <a id="projectpipelinesupdatedafter"></a>`updatedAfter` | [`Time`](#time) | Pipelines updated after this date. |
+| <a id="projectpipelinesupdatedbefore"></a>`updatedBefore` | [`Time`](#time) | Pipelines updated before this date. |
+| <a id="projectpipelinesusername"></a>`username` | [`String`](#string) | Filter pipelines by the user that triggered the pipeline. |
##### `Project.projectMembers`
@@ -14401,6 +15171,18 @@ Returns [`[ProjectSecurityTraining!]`](#projectsecuritytraining).
| ---- | ---- | ----------- |
| <a id="projectsecuritytrainingprovidersonlyenabled"></a>`onlyEnabled` | [`Boolean`](#boolean) | Filter the list by only enabled security trainings. |
+##### `Project.securityTrainingUrls`
+
+Security training URLs for the enabled training providers of the project.
+
+Returns [`[SecurityTrainingUrl!]`](#securitytrainingurl).
+
+###### Arguments
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="projectsecuritytrainingurlsidentifierexternalids"></a>`identifierExternalIds` | [`[String!]!`](#string) | List of external IDs of vulnerability identifiers. |
+
##### `Project.sentryDetailedError`
Detailed version of a Sentry error on the project.
@@ -14544,6 +15326,22 @@ Returns [`VulnerabilitySeveritiesCount`](#vulnerabilityseveritiescount).
| <a id="projectvulnerabilityseveritiescountseverity"></a>`severity` | [`[VulnerabilitySeverity!]`](#vulnerabilityseverity) | Filter vulnerabilities by severity. |
| <a id="projectvulnerabilityseveritiescountstate"></a>`state` | [`[VulnerabilityState!]`](#vulnerabilitystate) | Filter vulnerabilities by state. |
+##### `Project.workItemTypes`
+
+Work item types available to the project. Returns `null` if `work_items` feature flag is disabled. This flag is disabled by default, because the feature is experimental and is subject to change without notice.
+
+Returns [`WorkItemTypeConnection`](#workitemtypeconnection).
+
+This field returns a [connection](#connections). It accepts the
+four standard [pagination arguments](#connection-pagination-arguments):
+`before: String`, `after: String`, `first: Int`, `last: Int`.
+
+###### Arguments
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="projectworkitemtypestaskable"></a>`taskable` | [`Boolean`](#boolean) | If `true`, only taskable work item types will be returned. Argument is experimental and can be removed in the future without notice. |
+
### `ProjectCiCdSetting`
#### Fields
@@ -14896,6 +15694,7 @@ Returns [`Tree`](#tree).
| <a id="repositoryblobblamepath"></a>`blamePath` | [`String`](#string) | Web path to blob blame page. |
| <a id="repositoryblobcancurrentuserpushtobranch"></a>`canCurrentUserPushToBranch` | [`Boolean`](#boolean) | Whether the current user can push to the branch. |
| <a id="repositoryblobcanmodifyblob"></a>`canModifyBlob` | [`Boolean`](#boolean) | Whether the current user can modify the blob. |
+| <a id="repositoryblobcodenavigationpath"></a>`codeNavigationPath` | [`String`](#string) | Web path for code navigation. |
| <a id="repositoryblobcodeowners"></a>`codeOwners` | [`[UserCore!]`](#usercore) | List of code owners for the blob. |
| <a id="repositoryblobeditblobpath"></a>`editBlobPath` | [`String`](#string) | Web path to edit the blob in the old-style editor. |
| <a id="repositoryblobenvironmentexternalurlforroutemap"></a>`environmentExternalUrlForRouteMap` | [`String`](#string) | Web path to blob on an environment. |
@@ -14905,6 +15704,8 @@ Returns [`Tree`](#tree).
| <a id="repositoryblobfiletype"></a>`fileType` | [`String`](#string) | Expected format of the blob based on the extension. |
| <a id="repositoryblobfindfilepath"></a>`findFilePath` | [`String`](#string) | Web path to find file. |
| <a id="repositoryblobforkandeditpath"></a>`forkAndEditPath` | [`String`](#string) | Web path to edit this blob using a forked project. |
+| <a id="repositoryblobforkandviewpath"></a>`forkAndViewPath` | [`String`](#string) | Web path to view this blob using a forked project. |
+| <a id="repositoryblobgitpodbloburl"></a>`gitpodBlobUrl` | [`String`](#string) | URL to the blob within Gitpod. |
| <a id="repositoryblobhistorypath"></a>`historyPath` | [`String`](#string) | Web path to blob history page. |
| <a id="repositoryblobid"></a>`id` | [`ID!`](#id) | ID of the blob. |
| <a id="repositoryblobideeditpath"></a>`ideEditPath` | [`String`](#string) | Web path to edit this blob in the Web IDE. |
@@ -14918,6 +15719,7 @@ Returns [`Tree`](#tree).
| <a id="repositoryblobpermalinkpath"></a>`permalinkPath` | [`String`](#string) | Web path to blob permalink. |
| <a id="repositoryblobpipelineeditorpath"></a>`pipelineEditorPath` | [`String`](#string) | Web path to edit .gitlab-ci.yml file. |
| <a id="repositoryblobplaindata"></a>`plainData` | [`String`](#string) | Blob plain highlighted data. |
+| <a id="repositoryblobprojectblobpathroot"></a>`projectBlobPathRoot` | [`String`](#string) | Web path for the root of the blob. |
| <a id="repositoryblobrawblob"></a>`rawBlob` | [`String`](#string) | Raw content of the blob. |
| <a id="repositoryblobrawpath"></a>`rawPath` | [`String`](#string) | Web path to download the raw blob. |
| <a id="repositoryblobrawsize"></a>`rawSize` | [`Int`](#int) | Size (in bytes) of the blob, or the blob target if stored externally. |
@@ -15104,6 +15906,16 @@ Represents an entity for options in SAST CI configuration.
| <a id="sastciconfigurationoptionsentitylabel"></a>`label` | [`String`](#string) | Label of option entity. |
| <a id="sastciconfigurationoptionsentityvalue"></a>`value` | [`String`](#string) | Value of option entity. |
+### `SavedReply`
+
+#### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="savedreplycontent"></a>`content` | [`String!`](#string) | Content of the saved reply. |
+| <a id="savedreplyid"></a>`id` | [`UsersSavedReplyID!`](#userssavedreplyid) | Global ID of the saved reply. |
+| <a id="savedreplyname"></a>`name` | [`String!`](#string) | Name of the saved reply. |
+
### `Scan`
Represents the security scan information.
@@ -15114,6 +15926,8 @@ Represents the security scan information.
| ---- | ---- | ----------- |
| <a id="scanerrors"></a>`errors` | [`[String!]!`](#string) | List of errors. |
| <a id="scanname"></a>`name` | [`String!`](#string) | Name of the scan. |
+| <a id="scanstatus"></a>`status` | [`ScanStatus!`](#scanstatus) | Indicates the status of the scan. |
+| <a id="scanwarnings"></a>`warnings` | [`[String!]!`](#string) | List of warnings. |
### `ScanExecutionPolicy`
@@ -15198,6 +16012,18 @@ Represents a list of security scanners.
| <a id="securityscannersenabled"></a>`enabled` | [`[SecurityScannerType!]`](#securityscannertype) | List of analyzers which are enabled for the project. |
| <a id="securityscannerspipelinerun"></a>`pipelineRun` | [`[SecurityScannerType!]`](#securityscannertype) | List of analyzers which ran successfully in the latest pipeline. |
+### `SecurityTrainingUrl`
+
+Represents a URL related to a security training.
+
+#### Fields
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="securitytrainingurlname"></a>`name` | [`String`](#string) | Name of the training provider. |
+| <a id="securitytrainingurlstatus"></a>`status` | [`TrainingUrlRequestStatus`](#trainingurlrequeststatus) | Status of the request to training provider. |
+| <a id="securitytrainingurlurl"></a>`url` | [`String`](#string) | URL of the link for security training content. |
+
### `SentryDetailedError`
A Sentry error.
@@ -15764,6 +16590,7 @@ Representing a to-do entry.
| <a id="todoid"></a>`id` | [`ID!`](#id) | ID of the to-do item. |
| <a id="todoproject"></a>`project` | [`Project`](#project) | Project this to-do item is associated with. |
| <a id="todostate"></a>`state` | [`TodoStateEnum!`](#todostateenum) | State of the to-do item. |
+| <a id="todotarget"></a>`target` | [`Todoable!`](#todoable) | Target of the to-do item. |
| <a id="todotargettype"></a>`targetType` | [`TodoTargetEnum!`](#todotargetenum) | Target type of the to-do item. |
### `Topic`
@@ -15856,14 +16683,18 @@ Core represention of a GitLab user.
| <a id="usercorebot"></a>`bot` | [`Boolean!`](#boolean) | Indicates if the user is a bot. |
| <a id="usercorecallouts"></a>`callouts` | [`UserCalloutConnection`](#usercalloutconnection) | User callouts that belong to the user. (see [Connections](#connections)) |
| <a id="usercoreemail"></a>`email` **{warning-solid}** | [`String`](#string) | **Deprecated** in 13.7. This was renamed. Use: [`User.publicEmail`](#userpublicemail). |
+| <a id="usercoregitpodenabled"></a>`gitpodEnabled` | [`Boolean`](#boolean) | Whether Gitpod is enabled at the user level. |
| <a id="usercoregroupcount"></a>`groupCount` | [`Int`](#int) | Group count for the user. |
| <a id="usercoregroupmemberships"></a>`groupMemberships` | [`GroupMemberConnection`](#groupmemberconnection) | Group memberships of the user. (see [Connections](#connections)) |
| <a id="usercoreid"></a>`id` | [`ID!`](#id) | ID of the user. |
| <a id="usercorelocation"></a>`location` | [`String`](#string) | Location of the user. |
| <a id="usercorename"></a>`name` | [`String!`](#string) | Human-readable name of the user. Returns `****` if the user is a project bot and the requester does not have permission to view the project. |
| <a id="usercorenamespace"></a>`namespace` | [`Namespace`](#namespace) | Personal namespace of the user. |
+| <a id="usercorepreferencesgitpodpath"></a>`preferencesGitpodPath` | [`String`](#string) | Web path to the Gitpod section within user preferences. |
+| <a id="usercoreprofileenablegitpodpath"></a>`profileEnableGitpodPath` | [`String`](#string) | Web path to enable Gitpod for the user. |
| <a id="usercoreprojectmemberships"></a>`projectMemberships` | [`ProjectMemberConnection`](#projectmemberconnection) | Project memberships of the user. (see [Connections](#connections)) |
| <a id="usercorepublicemail"></a>`publicEmail` | [`String`](#string) | User's public email. |
+| <a id="usercoresavedreplies"></a>`savedReplies` | [`SavedReplyConnection`](#savedreplyconnection) | Saved replies authored by the user. (see [Connections](#connections)) |
| <a id="usercorestate"></a>`state` | [`UserState!`](#userstate) | State of the user. |
| <a id="usercorestatus"></a>`status` | [`UserStatus`](#userstatus) | User status. |
| <a id="usercoreuserpermissions"></a>`userPermissions` | [`UserPermissions!`](#userpermissions) | Permissions for the current user on the resource. |
@@ -16701,6 +17532,7 @@ Represents vulnerability letter grades with associated projects.
| <a id="workitemdescriptionhtml"></a>`descriptionHtml` | [`String`](#string) | The GitLab Flavored Markdown rendering of `description`. |
| <a id="workitemid"></a>`id` | [`WorkItemID!`](#workitemid) | Global ID of the work item. |
| <a id="workitemiid"></a>`iid` | [`ID!`](#id) | Internal ID of the work item. |
+| <a id="workitemlockversion"></a>`lockVersion` | [`Int!`](#int) | Lock version of the work item. Incremented each time the work item is updated. |
| <a id="workitemstate"></a>`state` | [`WorkItemState!`](#workitemstate) | State of the work item. |
| <a id="workitemtitle"></a>`title` | [`String!`](#string) | Title of the work item. |
| <a id="workitemtitlehtml"></a>`titleHtml` | [`String`](#string) | The GitLab Flavored Markdown rendering of `title`. |
@@ -16990,6 +17822,43 @@ Mode of a commit action.
| <a id="commitencodingbase64"></a>`BASE64` | Base64 encoding. |
| <a id="commitencodingtext"></a>`TEXT` | Text encoding. |
+### `ComplianceViolationReason`
+
+Reason for the compliance violation.
+
+| Value | Description |
+| ----- | ----------- |
+| <a id="complianceviolationreasonapproved_by_committer"></a>`APPROVED_BY_COMMITTER` | Approved by committer. |
+| <a id="complianceviolationreasonapproved_by_insufficient_users"></a>`APPROVED_BY_INSUFFICIENT_USERS` | Approved by insufficient users. |
+| <a id="complianceviolationreasonapproved_by_merge_request_author"></a>`APPROVED_BY_MERGE_REQUEST_AUTHOR` | Approved by merge request author. |
+
+### `ComplianceViolationSeverity`
+
+Severity of the compliance violation.
+
+| Value | Description |
+| ----- | ----------- |
+| <a id="complianceviolationseveritycritical"></a>`CRITICAL` | Critical severity. |
+| <a id="complianceviolationseverityhigh"></a>`HIGH` | High severity. |
+| <a id="complianceviolationseverityinfo"></a>`INFO` | Info severity. |
+| <a id="complianceviolationseveritylow"></a>`LOW` | Low severity. |
+| <a id="complianceviolationseveritymedium"></a>`MEDIUM` | Medium severity. |
+
+### `ComplianceViolationSort`
+
+Compliance violation sort values.
+
+| Value | Description |
+| ----- | ----------- |
+| <a id="complianceviolationsortmerged_at_asc"></a>`MERGED_AT_ASC` | Date merged in ascending order, further sorted by ID in ascending order. |
+| <a id="complianceviolationsortmerged_at_desc"></a>`MERGED_AT_DESC` | Date merged in descending order, further sorted by ID in descending order. |
+| <a id="complianceviolationsortmerge_request_title_asc"></a>`MERGE_REQUEST_TITLE_ASC` | Merge request title in ascending order, further sorted by ID in ascending order. |
+| <a id="complianceviolationsortmerge_request_title_desc"></a>`MERGE_REQUEST_TITLE_DESC` | Merge request title in descending order, further sorted by ID in descending order. |
+| <a id="complianceviolationsortseverity_level_asc"></a>`SEVERITY_LEVEL_ASC` | Severity in ascending order, further sorted by ID in ascending order. |
+| <a id="complianceviolationsortseverity_level_desc"></a>`SEVERITY_LEVEL_DESC` | Severity in descending order, further sorted by ID in descending order. |
+| <a id="complianceviolationsortviolation_reason_asc"></a>`VIOLATION_REASON_ASC` | Violation reason in ascending order, further sorted by ID in ascending order. |
+| <a id="complianceviolationsortviolation_reason_desc"></a>`VIOLATION_REASON_DESC` | Violation reason in descending order, further sorted by ID in descending order. |
+
### `ConanMetadatumFileTypeEnum`
Conan file types.
@@ -17087,6 +17956,17 @@ Unit for the duration of Dast Profile Cadence.
| <a id="dastprofilecadenceunitweek"></a>`WEEK` | DAST Profile Cadence duration in weeks. |
| <a id="dastprofilecadenceunityear"></a>`YEAR` | DAST Profile Cadence duration in years. |
+### `DastScanMethodType`
+
+Scan method to be used by the scanner.
+
+| Value | Description |
+| ----- | ----------- |
+| <a id="dastscanmethodtypehar"></a>`HAR` | HAR scan method. |
+| <a id="dastscanmethodtypeopenapi"></a>`OPENAPI` | OpenAPI scan method. |
+| <a id="dastscanmethodtypepostman_collection"></a>`POSTMAN_COLLECTION` | Postman scan method. |
+| <a id="dastscanmethodtypewebsite"></a>`WEBSITE` | Website scan method. |
+
### `DastScanTypeEnum`
| Value | Description |
@@ -17218,6 +18098,7 @@ All supported DORA metric types.
| ----- | ----------- |
| <a id="dorametrictypedeployment_frequency"></a>`DEPLOYMENT_FREQUENCY` | Deployment frequency. |
| <a id="dorametrictypelead_time_for_changes"></a>`LEAD_TIME_FOR_CHANGES` | Lead time for changes. |
+| <a id="dorametrictypetime_to_restore_service"></a>`TIME_TO_RESTORE_SERVICE` | Time to restore service. |
### `EntryType`
@@ -17934,6 +18815,20 @@ Size of UI component in SAST configuration page.
| <a id="sastuicomponentsizemedium"></a>`MEDIUM` | Size of UI component in SAST configuration page is medium. |
| <a id="sastuicomponentsizesmall"></a>`SMALL` | Size of UI component in SAST configuration page is small. |
+### `ScanStatus`
+
+The status of the security scan.
+
+| Value | Description |
+| ----- | ----------- |
+| <a id="scanstatuscreated"></a>`CREATED` | The scan has been created. |
+| <a id="scanstatusjob_failed"></a>`JOB_FAILED` | The related CI build failed. |
+| <a id="scanstatuspreparation_failed"></a>`PREPARATION_FAILED` | Report couldn't be prepared. |
+| <a id="scanstatuspreparing"></a>`PREPARING` | Preparing the report for the scan. |
+| <a id="scanstatuspurged"></a>`PURGED` | Report for the scan has been removed from the database. |
+| <a id="scanstatusreport_error"></a>`REPORT_ERROR` | The report artifact provided by the CI build couldn't be parsed. |
+| <a id="scanstatussucceeded"></a>`SUCCEEDED` | The report has been successfully prepared. |
+
### `SecurityReportTypeEnum`
| Value | Description |
@@ -17995,7 +18890,9 @@ State of a Sentry error.
| <a id="servicetypeexternal_wiki_service"></a>`EXTERNAL_WIKI_SERVICE` | ExternalWikiService type. |
| <a id="servicetypeflowdock_service"></a>`FLOWDOCK_SERVICE` | FlowdockService type. |
| <a id="servicetypegithub_service"></a>`GITHUB_SERVICE` | GithubService type. |
+| <a id="servicetypegitlab_slack_application_service"></a>`GITLAB_SLACK_APPLICATION_SERVICE` | GitlabSlackApplicationService type (Gitlab.com only). |
| <a id="servicetypehangouts_chat_service"></a>`HANGOUTS_CHAT_SERVICE` | HangoutsChatService type. |
+| <a id="servicetypeharbor_service"></a>`HARBOR_SERVICE` | HarborService type. |
| <a id="servicetypeirker_service"></a>`IRKER_SERVICE` | IrkerService type. |
| <a id="servicetypejenkins_service"></a>`JENKINS_SERVICE` | JenkinsService type. |
| <a id="servicetypejira_service"></a>`JIRA_SERVICE` | JiraService type. |
@@ -18110,6 +19007,15 @@ State of a test report.
| <a id="todotargetenumissue"></a>`ISSUE` | Issue. |
| <a id="todotargetenummergerequest"></a>`MERGEREQUEST` | Merge request. |
+### `TrainingUrlRequestStatus`
+
+Status of the request to the training provider. The URL of a TrainingUrl is calculated asynchronously. When PENDING, the URL of the TrainingUrl will be null. When COMPLETED, the URL of the TrainingUrl will be available.
+
+| Value | Description |
+| ----- | ----------- |
+| <a id="trainingurlrequeststatuscompleted"></a>`COMPLETED` | Completed request. |
+| <a id="trainingurlrequeststatuspending"></a>`PENDING` | Pending request. |
+
### `TypeEnum`
| Value | Description |
@@ -18124,6 +19030,8 @@ Name of the feature that the callout is for.
| Value | Description |
| ----- | ----------- |
| <a id="usercalloutfeaturenameenumactive_user_count_threshold"></a>`ACTIVE_USER_COUNT_THRESHOLD` | Callout feature name for active_user_count_threshold. |
+| <a id="usercalloutfeaturenameenumattention_requests_side_nav"></a>`ATTENTION_REQUESTS_SIDE_NAV` | Callout feature name for attention_requests_side_nav. |
+| <a id="usercalloutfeaturenameenumattention_requests_top_nav"></a>`ATTENTION_REQUESTS_TOP_NAV` | Callout feature name for attention_requests_top_nav. |
| <a id="usercalloutfeaturenameenumbuy_pipeline_minutes_notification_dot"></a>`BUY_PIPELINE_MINUTES_NOTIFICATION_DOT` | Callout feature name for buy_pipeline_minutes_notification_dot. |
| <a id="usercalloutfeaturenameenumcanary_deployment"></a>`CANARY_DEPLOYMENT` | Callout feature name for canary_deployment. |
| <a id="usercalloutfeaturenameenumci_deprecation_warning_for_types_keyword"></a>`CI_DEPRECATION_WARNING_FOR_TYPES_KEYWORD` | Callout feature name for ci_deprecation_warning_for_types_keyword. |
@@ -18146,6 +19054,10 @@ Name of the feature that the callout is for.
| <a id="usercalloutfeaturenameenumsecurity_configuration_upgrade_banner"></a>`SECURITY_CONFIGURATION_UPGRADE_BANNER` | Callout feature name for security_configuration_upgrade_banner. |
| <a id="usercalloutfeaturenameenumsecurity_newsletter_callout"></a>`SECURITY_NEWSLETTER_CALLOUT` | Callout feature name for security_newsletter_callout. |
| <a id="usercalloutfeaturenameenumsecurity_training_feature_promotion"></a>`SECURITY_TRAINING_FEATURE_PROMOTION` | Callout feature name for security_training_feature_promotion. |
+| <a id="usercalloutfeaturenameenumstorage_enforcement_banner_first_enforcement_threshold"></a>`STORAGE_ENFORCEMENT_BANNER_FIRST_ENFORCEMENT_THRESHOLD` | Callout feature name for storage_enforcement_banner_first_enforcement_threshold. |
+| <a id="usercalloutfeaturenameenumstorage_enforcement_banner_fourth_enforcement_threshold"></a>`STORAGE_ENFORCEMENT_BANNER_FOURTH_ENFORCEMENT_THRESHOLD` | Callout feature name for storage_enforcement_banner_fourth_enforcement_threshold. |
+| <a id="usercalloutfeaturenameenumstorage_enforcement_banner_second_enforcement_threshold"></a>`STORAGE_ENFORCEMENT_BANNER_SECOND_ENFORCEMENT_THRESHOLD` | Callout feature name for storage_enforcement_banner_second_enforcement_threshold. |
+| <a id="usercalloutfeaturenameenumstorage_enforcement_banner_third_enforcement_threshold"></a>`STORAGE_ENFORCEMENT_BANNER_THIRD_ENFORCEMENT_THRESHOLD` | Callout feature name for storage_enforcement_banner_third_enforcement_threshold. |
| <a id="usercalloutfeaturenameenumsuggest_pipeline"></a>`SUGGEST_PIPELINE` | Callout feature name for suggest_pipeline. |
| <a id="usercalloutfeaturenameenumsuggest_popover_dismissed"></a>`SUGGEST_POPOVER_DISMISSED` | Callout feature name for suggest_popover_dismissed. |
| <a id="usercalloutfeaturenameenumtabs_position_highlight"></a>`TABS_POSITION_HIGHLIGHT` | Callout feature name for tabs_position_highlight. |
@@ -18863,6 +19775,12 @@ A `UserID` is a global ID. It is encoded as a string.
An example `UserID` is: `"gid://gitlab/User/1"`.
+### `UsersSavedReplyID`
+
+A `UsersSavedReplyID` is a global ID. It is encoded as a string.
+
+An example `UsersSavedReplyID` is: `"gid://gitlab/Users::SavedReply/1"`.
+
### `VulnerabilitiesExternalIssueLinkID`
A `VulnerabilitiesExternalIssueLinkID` is a global ID. It is encoded as a string.
@@ -18893,6 +19811,9 @@ A `WorkItemID` is a global ID. It is encoded as a string.
An example `WorkItemID` is: `"gid://gitlab/WorkItem/1"`.
+While we transition from Issues into Work Items this type will temporarily support
+`IssueID` like: `"gid://gitlab/Issue/1"`. This behavior will be removed without notice in the future.
+
### `WorkItemsTypeID`
A `WorkItemsTypeID` is a global ID. It is encoded as a string.
@@ -19218,6 +20139,7 @@ Implementations:
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="serviceactive"></a>`active` | [`Boolean`](#boolean) | Indicates if the service is active. |
+| <a id="serviceservicetype"></a>`serviceType` | [`ServiceType`](#servicetype) | Type of the service. |
| <a id="servicetype"></a>`type` | [`String`](#string) | Class name of the service. |
#### `TimeboxReportInterface`
@@ -19227,11 +20149,38 @@ Implementations:
- [`Iteration`](#iteration)
- [`Milestone`](#milestone)
+##### Fields with arguments
+
+###### `TimeboxReportInterface.report`
+
+Historically accurate report about the timebox.
+
+Returns [`TimeboxReport`](#timeboxreport).
+
+####### Arguments
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="timeboxreportinterfacereportfullpath"></a>`fullPath` | [`String`](#string) | Full path of the project or group used as a scope for report. For example, `gitlab-org` or `gitlab-org/gitlab`. |
+
+#### `Todoable`
+
+Implementations:
+
+- [`AlertManagementAlert`](#alertmanagementalert)
+- [`BoardEpic`](#boardepic)
+- [`Commit`](#commit)
+- [`Design`](#design)
+- [`Epic`](#epic)
+- [`EpicIssue`](#epicissue)
+- [`Issue`](#issue)
+- [`MergeRequest`](#mergerequest)
+
##### Fields
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="timeboxreportinterfacereport"></a>`report` | [`TimeboxReport`](#timeboxreport) | Historically accurate report about the timebox. |
+| <a id="todoableweburl"></a>`webUrl` | [`String`](#string) | URL of this object. |
#### `User`
@@ -19240,6 +20189,8 @@ Representation of a GitLab user.
Implementations:
- [`MergeRequestAssignee`](#mergerequestassignee)
+- [`MergeRequestAuthor`](#mergerequestauthor)
+- [`MergeRequestParticipant`](#mergerequestparticipant)
- [`MergeRequestReviewer`](#mergerequestreviewer)
- [`UserCore`](#usercore)
@@ -19251,14 +20202,18 @@ Implementations:
| <a id="userbot"></a>`bot` | [`Boolean!`](#boolean) | Indicates if the user is a bot. |
| <a id="usercallouts"></a>`callouts` | [`UserCalloutConnection`](#usercalloutconnection) | User callouts that belong to the user. (see [Connections](#connections)) |
| <a id="useremail"></a>`email` **{warning-solid}** | [`String`](#string) | **Deprecated** in 13.7. This was renamed. Use: [`User.publicEmail`](#userpublicemail). |
+| <a id="usergitpodenabled"></a>`gitpodEnabled` | [`Boolean`](#boolean) | Whether Gitpod is enabled at the user level. |
| <a id="usergroupcount"></a>`groupCount` | [`Int`](#int) | Group count for the user. |
| <a id="usergroupmemberships"></a>`groupMemberships` | [`GroupMemberConnection`](#groupmemberconnection) | Group memberships of the user. (see [Connections](#connections)) |
| <a id="userid"></a>`id` | [`ID!`](#id) | ID of the user. |
| <a id="userlocation"></a>`location` | [`String`](#string) | Location of the user. |
| <a id="username"></a>`name` | [`String!`](#string) | Human-readable name of the user. Returns `****` if the user is a project bot and the requester does not have permission to view the project. |
| <a id="usernamespace"></a>`namespace` | [`Namespace`](#namespace) | Personal namespace of the user. |
+| <a id="userpreferencesgitpodpath"></a>`preferencesGitpodPath` | [`String`](#string) | Web path to the Gitpod section within user preferences. |
+| <a id="userprofileenablegitpodpath"></a>`profileEnableGitpodPath` | [`String`](#string) | Web path to enable Gitpod for the user. |
| <a id="userprojectmemberships"></a>`projectMemberships` | [`ProjectMemberConnection`](#projectmemberconnection) | Project memberships of the user. (see [Connections](#connections)) |
| <a id="userpublicemail"></a>`publicEmail` | [`String`](#string) | User's public email. |
+| <a id="usersavedreplies"></a>`savedReplies` | [`SavedReplyConnection`](#savedreplyconnection) | Saved replies authored by the user. (see [Connections](#connections)) |
| <a id="userstate"></a>`state` | [`UserState!`](#userstate) | State of the user. |
| <a id="userstatus"></a>`status` | [`UserStatus`](#userstatus) | User status. |
| <a id="useruserpermissions"></a>`userPermissions` | [`UserPermissions!`](#userpermissions) | Permissions for the current user on the resource. |
@@ -19538,6 +20493,16 @@ Field that are available while modifying the custom mapping attributes for an HT
| <a id="complianceframeworkinputname"></a>`name` | [`String`](#string) | New name for the compliance framework. |
| <a id="complianceframeworkinputpipelineconfigurationfullpath"></a>`pipelineConfigurationFullPath` | [`String`](#string) | Full path of the compliance pipeline configuration stored in a project repository, such as `.gitlab/.compliance-gitlab-ci.yml@compliance/hipaa` **(ULTIMATE)**. |
+### `ComplianceViolationInput`
+
+#### Arguments
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="complianceviolationinputmergedafter"></a>`mergedAfter` | [`Date`](#date) | Merged date of merge requests merged after a compliance violation was created. |
+| <a id="complianceviolationinputmergedbefore"></a>`mergedBefore` | [`Date`](#date) | Merged date of merge requests merged before a compliance violation was created. |
+| <a id="complianceviolationinputprojectids"></a>`projectIds` | [`[ProjectID!]`](#projectid) | Filter compliance violations by project. |
+
### `DastProfileCadenceInput`
Represents DAST Profile Cadence.
@@ -19609,8 +20574,8 @@ Input type for DastSiteProfile authentication.
| ---- | ---- | ----------- |
| <a id="diffpositioninputbasesha"></a>`baseSha` | [`String`](#string) | Merge base of the branch the comment was made on. |
| <a id="diffpositioninputheadsha"></a>`headSha` | [`String!`](#string) | SHA of the HEAD at the time the comment was made. |
-| <a id="diffpositioninputnewline"></a>`newLine` | [`Int`](#int) | Line on HEAD SHA that was changed. |
-| <a id="diffpositioninputoldline"></a>`oldLine` | [`Int`](#int) | Line on start SHA that was changed. |
+| <a id="diffpositioninputnewline"></a>`newLine` | [`Int`](#int) | Line on HEAD SHA that was changed. Please see the [REST API Documentation](https://docs.gitlab.com/ee/api/discussions.html#create-a-new-thread-in-the-merge-request-diff) for more information on how to use this field. |
+| <a id="diffpositioninputoldline"></a>`oldLine` | [`Int`](#int) | Line on start SHA that was changed. Please see the [REST API Documentation](https://docs.gitlab.com/ee/api/discussions.html#create-a-new-thread-in-the-merge-request-diff) for more information on how to use this field. |
| <a id="diffpositioninputpaths"></a>`paths` | [`DiffPathsInput!`](#diffpathsinput) | The paths of the file that was changed. Both of the properties of this input are optional, but at least one of them is required. |
| <a id="diffpositioninputstartsha"></a>`startSha` | [`String!`](#string) | SHA of the branch being compared against. |
@@ -19902,3 +20867,15 @@ A time-frame defined as a closed inclusive range of two dates.
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="vulnerabilityscannervendorinputname"></a>`name` | [`String!`](#string) | Name of the vendor/maintainer. |
+
+### `WorkItemConvertTaskInput`
+
+#### Arguments
+
+| Name | Type | Description |
+| ---- | ---- | ----------- |
+| <a id="workitemconverttaskinputlinenumberend"></a>`lineNumberEnd` | [`Int!`](#int) | Last line in the Markdown source that defines the list item task. |
+| <a id="workitemconverttaskinputlinenumberstart"></a>`lineNumberStart` | [`Int!`](#int) | First line in the Markdown source that defines the list item task. |
+| <a id="workitemconverttaskinputlockversion"></a>`lockVersion` | [`Int!`](#int) | Current lock version of the work item containing the task in the description. |
+| <a id="workitemconverttaskinputtitle"></a>`title` | [`String!`](#string) | Full string of the task to be replaced. New title for the created work item. |
+| <a id="workitemconverttaskinputworkitemtypeid"></a>`workItemTypeId` | [`WorkItemsTypeID!`](#workitemstypeid) | Global ID of the work item type used to create the new work item. |
diff --git a/doc/api/group_labels.md b/doc/api/group_labels.md
index 96b8a162e34..e0f1b451231 100644
--- a/doc/api/group_labels.md
+++ b/doc/api/group_labels.md
@@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/21368) in GitLab 11.8.
-This API supports managing [group labels](../user/project/labels.md#project-labels-and-group-labels).
+This API supports managing [group labels](../user/project/labels.md#types-of-labels).
It allows users to list, create, update, and delete group labels. Furthermore, users can subscribe to and
unsubscribe from group labels.
diff --git a/doc/api/group_wikis.md b/doc/api/group_wikis.md
index 4af907bd387..a78f989a755 100644
--- a/doc/api/group_wikis.md
+++ b/doc/api/group_wikis.md
@@ -7,7 +7,10 @@ type: reference, api
# Group wikis API **(PREMIUM)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/212199) in GitLab 13.5.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/212199) in GitLab 13.5.
+> - The `encoding` field was [added](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/81150) in GitLab 14.9.
+> - The `render_html` attribute was [added](https://gitlab.com/gitlab-org/gitlab/-/issues/336792) in GitLab 14.9.
+> - The `version` attribute was [added](https://gitlab.com/gitlab-org/gitlab/-/issues/336792) in GitLab 14.9.
The [group wikis](../user/project/wiki/group.md) API is available only in APIv4.
An API for [project wikis](wikis.md) is also available.
@@ -37,18 +40,21 @@ Example response:
"content" : "Here is an instruction how to deploy this project.",
"format" : "markdown",
"slug" : "deploy",
- "title" : "deploy"
+ "title" : "deploy",
+ "encoding": "UTF-8"
},
{
"content" : "Our development process is described here.",
"format" : "markdown",
"slug" : "development",
- "title" : "development"
+ "title" : "development",
+ "encoding": "UTF-8"
},{
"content" : "* [Deploy](deploy)\n* [Development](development)",
"format" : "markdown",
"slug" : "home",
- "title" : "home"
+ "title" : "home",
+ "encoding": "UTF-8"
}
]
```
@@ -65,6 +71,8 @@ GET /groups/:id/wikis/:slug
| --------- | ------- | -------- | --------------------- |
| `id` | integer/string | yes | The ID or [URL-encoded path of the group](index.md#namespaced-path-encoding) |
| `slug` | string | yes | URL-encoded slug (a unique string) of the wiki page, such as `dir%2Fpage_name` |
+| `render_html` | boolean | no | Return the rendered HTML of the wiki page |
+| `version` | string | no | Wiki page version sha |
```shell
curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/1/wikis/home"
@@ -77,7 +85,8 @@ Example response:
"content" : "home page",
"format" : "markdown",
"slug" : "home",
- "title" : "home"
+ "title" : "home",
+ "encoding": "UTF-8"
}
```
@@ -109,7 +118,8 @@ Example response:
"content" : "Hello world",
"format" : "markdown",
"slug" : "Hello",
- "title" : "Hello"
+ "title" : "Hello",
+ "encoding": "UTF-8"
}
```
@@ -142,7 +152,8 @@ Example response:
"content" : "documentation",
"format" : "markdown",
"slug" : "Docs",
- "title" : "Docs"
+ "title" : "Docs",
+ "encoding": "UTF-8"
}
```
diff --git a/doc/api/groups.md b/doc/api/groups.md
index 2e0f9526e16..120090c18a2 100644
--- a/doc/api/groups.md
+++ b/doc/api/groups.md
@@ -443,6 +443,7 @@ Example response:
"builds_access_level":"enabled",
"snippets_access_level":"enabled",
"pages_access_level":"enabled",
+ "security_and_compliance_access_level":"enabled",
"emails_disabled":null,
"shared_runners_enabled":true,
"lfs_enabled":true,
@@ -483,7 +484,9 @@ Example response:
## Details of a group
Get all details of a group. This endpoint can be accessed without authentication
-if the group is publicly accessible. In case the user that requests is administrator of the group, it returns the `runners_token` for the group too.
+if the group is publicly accessible. In case the user that requests is an administrator
+if the group is publicly accessible. With authentication, it returns the `runners_token`
+for the group too, if the user is an administrator or group owner.
```plaintext
GET /groups/:id
@@ -505,6 +508,11 @@ To get the details of all projects within a group, use either the [list a group'
curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/4"
```
+NOTE:
+There is [a known issue](https://gitlab.com/gitlab-org/gitlab/-/issues/345200) that can
+prevent `runners_token` from being returned when the call has the `with_projects=false`
+parameter.
+
This endpoint returns:
- All projects and shared projects in GitLab 12.5 and earlier.
@@ -795,7 +803,7 @@ Parameters:
| `two_factor_grace_period` | integer | no | Time before Two-factor authentication is enforced (in hours). |
| `project_creation_level` | string | no | Determine if developers can create projects in the group. Can be `noone` (No one), `maintainer` (users with the Maintainer role), or `developer` (users with the Developer or Maintainer role). |
| `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](../user/group/subgroups/index.md#creating-a-subgroup). Can be `owner` (Owners), or `maintainer` (users with the Maintainer role). |
+| `subgroup_creation_level` | string | no | Allowed to [create subgroups](../user/group/subgroups/index.md#create-a-subgroup). Can be `owner` (Owners), or `maintainer` (users with the Maintainer role). |
| `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) |
| `mentions_disabled` | boolean | no | Disable the capability of a group from getting mentioned |
@@ -858,7 +866,7 @@ curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" \
Transfer a group to a new parent group or turn a subgroup to a top-level group. Available to administrators and users:
- With the Owner role for the group to transfer.
-- With permission to [create a subgroup](../user/group/subgroups/index.md#creating-a-subgroup) in the new parent group if transferring a group.
+- With permission to [create a subgroup](../user/group/subgroups/index.md#create-a-subgroup) in the new parent group if transferring a group.
- With [permission to create a top-level group](../administration/user_settings.md#prevent-users-from-creating-top-level-groups) if turning a subgroup into a top-level group.
```plaintext
@@ -898,7 +906,7 @@ PUT /groups/:id
| `two_factor_grace_period` | integer | no | Time before Two-factor authentication is enforced (in hours). |
| `project_creation_level` | string | no | Determine if developers can create projects in the group. Can be `noone` (No one), `maintainer` (users with the Maintainer role), or `developer` (users with the Developer or Maintainer role). |
| `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](../user/group/subgroups/index.md#creating-a-subgroup). Can be `owner` (Owners), or `maintainer` (users with the Maintainer role). |
+| `subgroup_creation_level` | string | no | Allowed to [create subgroups](../user/group/subgroups/index.md#create-a-subgroup). Can be `owner` (Owners), or `maintainer` (users with the Maintainer role). |
| `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) |
| `mentions_disabled` | boolean | no | Disable the capability of a group from getting mentioned |
diff --git a/doc/api/index.md b/doc/api/index.md
index 589bc0416a1..178c2f05a6d 100644
--- a/doc/api/index.md
+++ b/doc/api/index.md
@@ -28,7 +28,7 @@ For an introduction and basic steps, see
## SCIM API **(PREMIUM SAAS)**
-GitLab provides an [SCIM API](scim.md) that both implements
+GitLab provides a [SCIM API](scim.md) that both implements
[the RFC7644 protocol](https://tools.ietf.org/html/rfc7644) and provides the
`/Users` endpoint. The base URL is `/api/scim/v2/groups/:group_path/Users/`.
@@ -767,3 +767,35 @@ some API endpoints also support `text/plain`.
In [GitLab 13.10 and later](https://gitlab.com/gitlab-org/gitlab/-/issues/250342),
API endpoints do not support `text/plain` by default, unless it's explicitly documented.
+
+## Resolve requests detected as spam
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/352913) in GitLab 14.9.
+
+REST API requests can be detected as spam. If a request is detected as spam and:
+
+- A CAPTCHA service is not configured, an error response is returned. For example:
+
+ ```json
+ {"message":{"error":"Your snippet has been recognized as spam and has been discarded."}}
+ ```
+
+- A CAPTCHA service is configured, you receive a response with:
+ - `needs_captcha_response` set to `true`.
+ - The `spam_log_id` and `captcha_site_key` fields set.
+
+ For example:
+
+ ```json
+ {"needs_captcha_response":true,"spam_log_id":42,"captcha_site_key":"6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI","message":{"error":"Your snippet has been recognized as spam. Please, change the content or solve the reCAPTCHA to proceed."}}
+ ```
+
+- Use the `captcha_site_key` to obtain a CAPTCHA response value using the appropriate CAPTCHA API.
+ Only [Google reCAPTCHA v2](https://developers.google.com/recaptcha/docs/display) is supported.
+- Resubmit the request with the `X-GitLab-Captcha-Response` and `X-GitLab-Spam-Log-Id` headers set.
+
+```shell
+export CAPTCHA_RESPONSE="<CAPTCHA response obtained from CAPTCHA service>"
+export SPAM_LOG_ID="<spam_log_id obtained from initial REST response>"
+curl --request POST --header "PRIVATE-TOKEN: $PRIVATE_TOKEN" --header "X-GitLab-Captcha-Response: $CAPTCHA_RESPONSE" --header "X-GitLab-Spam-Log-Id: $SPAM_LOG_ID" "https://gitlab.example.com/api/v4/snippets?title=Title&file_name=FileName&content=Content&visibility=public"
+```
diff --git a/doc/api/issues.md b/doc/api/issues.md
index 5801f072062..ef0727e1c13 100644
--- a/doc/api/issues.md
+++ b/doc/api/issues.md
@@ -210,6 +210,28 @@ Issues created by users on GitLab Premium or higher include the `epic` property:
}
```
+Issues created by users on GitLab Premium or higher include the `iteration` property:
+
+```json
+{
+ "iteration": {
+ "id":90,
+ "iid":4,
+ "sequence":2,
+ "group_id":162,
+ "title":null,
+ "description":null,
+ "state":2,
+ "created_at":"2022-03-14T05:21:11.929Z",
+ "updated_at":"2022-03-14T05:21:11.929Z",
+ "start_date":"2022-03-08",
+ "due_date":"2022-03-14",
+ "web_url":"http://gitlab.com/groups/my-group/-/iterations/90"
+ }
+ ...
+}
+```
+
Issues created by users on GitLab Ultimate include the `health_status` property:
```json
diff --git a/doc/api/jobs.md b/doc/api/jobs.md
index 89018548f5f..85cdf7d892a 100644
--- a/doc/api/jobs.md
+++ b/doc/api/jobs.md
@@ -474,7 +474,7 @@ Example of response
}
```
-## Get GitLab Agent by `CI_JOB_TOKEN` **(PREMIUM)**
+## Get GitLab agent by `CI_JOB_TOKEN` **(PREMIUM)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/324269) in GitLab 13.11.
@@ -814,7 +814,7 @@ NOTE:
You can't delete archived jobs with the API, but you can
[delete job artifacts and logs from jobs completed before a specific date](../administration/job_artifacts.md#delete-job-artifacts-and-logs-from-jobs-completed-before-a-specific-date)
-## Play a job
+## Run a job
Triggers a manual action to start a job.
@@ -822,16 +822,38 @@ Triggers a manual action to start a job.
POST /projects/:id/jobs/:job_id/play
```
-| Attribute | Type | Required | Description |
-|-----------|----------------|------------------------|-------------|
-| `id` | integer/string | **{check-circle}** Yes | ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user. |
-| `job_id` | integer | **{check-circle}** Yes | ID of a job. |
+| Attribute | Type | Required | Description |
+|----------------------------|-----------------|------------------------|-------------|
+| `id` | integer/string | **{check-circle}** Yes | ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user. |
+| `job_id` | integer | **{check-circle}** Yes | ID of a job. |
+| `job_variables_attributes` | array of hashes | **{dotted-circle}** No | An array containing the custom variables available to the job. [Introduced in](https://gitlab.com/gitlab-org/gitlab/-/issues/37267) GitLab 14.9. |
+
+Example request:
```shell
-curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/jobs/1/play"
+curl --request POST "https://gitlab.example.com/api/v4/projects/1/jobs/1/play
+ --header "PRIVATE-TOKEN: <your_access_token>"
+ --data @variables.json
```
-Example of response
+`@variables.json` is structured like:
+
+```json
+{
+ "job_variables_attributes": [
+ {
+ "key": "TEST_VAR_1",
+ "value": "test1"
+ },
+ {
+ "key": "TEST_VAR_2",
+ "value": "test2"
+ }
+ ]
+}
+```
+
+Example response:
```json
{
diff --git a/doc/api/linked_epics.md b/doc/api/linked_epics.md
new file mode 100644
index 00000000000..89168c344f3
--- /dev/null
+++ b/doc/api/linked_epics.md
@@ -0,0 +1,90 @@
+---
+stage: Plan
+group: Product Planning
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
+---
+
+# Linked epics API **(ULTIMATE)**
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/352493) in GitLab 14.9 [with a flag](../administration/feature_flags.md) named `related_epics_widget`. Enabled by default.
+
+FLAG:
+On self-managed GitLab, by default this feature is available. To hide the feature, ask an administrator to [disable the feature flag](../administration/feature_flags.md) named `related_epics_widget`. On GitLab.com, this feature is available.
+
+If the Related Epics feature is not available in your GitLab plan, a `403` status code is returned.
+
+## List linked epics
+
+Get a list of a given epic's linked epics filtered according to the user authorizations.
+
+```plaintext
+GET /groups/:id/epics/:epic_iid/related_epics
+```
+
+Supported attributes:
+
+| Attribute | Type | Required | Description |
+| ---------- | -------------- | ---------------------- | ------------------------------------------------------------------------- |
+| `epic_iid` | integer | **{check-circle}** Yes | Internal ID of a group's epic |
+| `id` | integer/string | **{check-circle}** Yes | ID or [URL-encoded path of the group](index.md#namespaced-path-encoding). |
+
+Example request:
+
+```shell
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/:id/epics/:epic_iid/related_epics"
+```
+
+Example response:
+
+```json
+[
+ {
+ "id":2,
+ "iid":2,
+ "color":"#1068bf",
+ "text_color":"#FFFFFF",
+ "group_id":2,
+ "parent_id":null,
+ "parent_iid":null,
+ "title":"My title 2",
+ "description":null,
+ "confidential":false,
+ "author":{
+ "id":3,
+ "username":"user3",
+ "name":"Sidney Jones4",
+ "state":"active",
+ "avatar_url":"https://www.gravatar.com/avatar/82797019f038ab535a84c6591e7bc936?s=80u0026d=identicon",
+ "web_url":"http://localhost/user3"
+ },
+ "start_date":null,
+ "end_date":null,
+ "due_date":null,
+ "state":"opened",
+ "web_url":"http://localhost/groups/group1/-/epics/2",
+ "references":{
+ "short":"u00262",
+ "relative":"u00262",
+ "full":"group1u00262"
+ },
+ "created_at":"2022-03-10T18:35:24.479Z",
+ "updated_at":"2022-03-10T18:35:24.479Z",
+ "closed_at":null,
+ "labels":[
+
+ ],
+ "upvotes":0,
+ "downvotes":0,
+ "_links":{
+ "self":"http://localhost/api/v4/groups/2/epics/2",
+ "epic_issues":"http://localhost/api/v4/groups/2/epics/2/issues",
+ "group":"http://localhost/api/v4/groups/2",
+ "parent":null
+ },
+ "related_epic_link_id":1,
+ "link_type":"relates_to",
+ "link_created_at":"2022-03-10T18:35:24.496+00:00",
+ "link_updated_at":"2022-03-10T18:35:24.496+00:00"
+ }
+]
+```
diff --git a/doc/api/merge_request_approvals.md b/doc/api/merge_request_approvals.md
index 6a0b66ac5dc..e569abd323e 100644
--- a/doc/api/merge_request_approvals.md
+++ b/doc/api/merge_request_approvals.md
@@ -58,9 +58,9 @@ POST /projects/:id/approvals
| `id` | integer or string | yes | The ID or [URL-encoded path of a project](index.md#namespaced-path-encoding) |
| `approvals_before_merge` | integer | no | How many approvals are required before an MR can be merged. Deprecated in 12.0 in favor of Approval Rules API. |
| `reset_approvals_on_push` | boolean | no | Reset approvals on a new push |
-| `disable_overriding_approvers_per_merge_request` | boolean | no | Allow/Disallow overriding approvers per MR |
-| `merge_requests_author_approval` | boolean | no | Allow/Disallow authors from self approving merge requests; `true` means authors can self approve |
-| `merge_requests_disable_committers_approval` | boolean | no | Allow/Disallow committers from self approving merge requests |
+| `disable_overriding_approvers_per_merge_request` | boolean | no | Allow or prevent overriding approvers per MR |
+| `merge_requests_author_approval` | boolean | no | Allow or prevent authors from self approving merge requests; `true` means authors can self approve |
+| `merge_requests_disable_committers_approval` | boolean | no | Allow or prevent committers from self approving merge requests |
| `require_password_to_approve` | boolean | no | Require approver to enter a password to authenticate before adding the approval |
```json
diff --git a/doc/api/merge_requests.md b/doc/api/merge_requests.md
index a54ea33aca8..0c065c0f2f5 100644
--- a/doc/api/merge_requests.md
+++ b/doc/api/merge_requests.md
@@ -609,13 +609,13 @@ GET /projects/:id/merge_requests/:merge_request_iid
Parameters:
-| Attribute | Type | Required | Description |
-|----------------------------------|----------------|----------|------------------------------------------------------------------------------------------------------------------|
+| Attribute | Type | Required | Description |
+|----------------------------------|----------------|----------|-----------------------------------------------------------------------------------------------------------------|
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user. |
-| `merge_request_iid` | integer | yes | The internal ID of the merge request. |
-| `render_html` | boolean | no | If `true` response includes rendered HTML for title and description. |
-| `include_diverged_commits_count` | boolean | no | If `true` response includes the commits behind the target branch. |
-| `include_rebase_in_progress` | boolean | no | If `true` response includes whether a rebase operation is in progress. |
+| `merge_request_iid` | integer | yes | The internal ID of the merge request. |
+| `render_html` | boolean | no | If `true` response includes rendered HTML for title and description. |
+| `include_diverged_commits_count` | boolean | no | If `true` response includes the commits behind the target branch. |
+| `include_rebase_in_progress` | boolean | no | If `true` response includes whether a rebase operation is in progress. |
```json
{
@@ -775,8 +775,8 @@ the `approvals_before_merge` parameter:
### Single merge request response notes
- The `merge_status` field may hold one of the following values:
- - `unchecked`: We have not checked this yet.
- - `checking`: We are currently checking if the merge request can be merged.
+ - `unchecked`: This merge request has not yet been checked.
+ - `checking`: This merge request is currently being checked to see if it can be merged.
- `can_be_merged`: This merge request can be merged without conflict.
- `cannot_be_merged`: There are merge conflicts between the source and target branches.
- `cannot_be_merged_recheck`: Currently unchecked. Before the current changes, there were conflicts.
@@ -803,10 +803,10 @@ GET /projects/:id/merge_requests/:merge_request_iid/participants
Parameters:
-| Attribute | Type | Required | Description |
-|----------------------------------|----------------|----------|------------------------------------------------------------------------------------------------------------------|
-| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user. |
-| `merge_request_iid` | integer | yes | The internal ID of the merge request. |
+| Attribute | Type | Required | Description |
+|---------------------|----------------|----------|-----------------------------------------------------------------------------------------------------------------|
+| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user. |
+| `merge_request_iid` | integer | yes | The internal ID of the merge request. |
```json
[
@@ -839,10 +839,10 @@ GET /projects/:id/merge_requests/:merge_request_iid/commits
Parameters:
-| Attribute | Type | Required | Description |
-|----------------------------------|----------------|----------|------------------------------------------------------------------------------------------------------------------|
-| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user. |
-| `merge_request_iid` | integer | yes | The internal ID of the merge request. |
+| Attribute | Type | Required | Description |
+|---------------------|----------------|----------|-----------------------------------------------------------------------------------------------------------------|
+| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user. |
+| `merge_request_iid` | integer | yes | The internal ID of the merge request. |
```json
[
@@ -886,11 +886,11 @@ GET /projects/:id/merge_requests/:merge_request_iid/changes
Parameters:
-| Attribute | Type | Required | Description |
-|----------------------------------|----------------|----------|------------------------------------------------------------------------------------------------------------------|
-| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user. |
-| `merge_request_iid` | integer | yes | The internal ID of the merge request. |
-| `access_raw_diffs` | boolean | no | Retrieve change diffs via Gitaly. |
+| Attribute | Type | Required | Description |
+|---------------------|----------------|----------|-----------------------------------------------------------------------------------------------------------------|
+| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user. |
+| `merge_request_iid` | integer | yes | The internal ID of the merge request. |
+| `access_raw_diffs` | boolean | no | Retrieve change diffs via Gitaly. |
```json
{
@@ -1008,10 +1008,10 @@ GET /projects/:id/merge_requests/:merge_request_iid/pipelines
Parameters:
-| Attribute | Type | Required | Description |
-|----------------------------------|----------------|----------|------------------------------------------------------------------------------------------------------------------|
-| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user. |
-| `merge_request_iid` | integer | yes | The internal ID of the merge request. |
+| Attribute | Type | Required | Description |
+|---------------------|----------------|----------|-----------------------------------------------------------------------------------------------------------------|
+| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user. |
+| `merge_request_iid` | integer | yes | The internal ID of the merge request. |
```json
[
@@ -1044,10 +1044,10 @@ POST /projects/:id/merge_requests/:merge_request_iid/pipelines
Parameters:
-| Attribute | Type | Required | Description |
-|----------------------------------|----------------|----------|------------------------------------------------------------------------------------------------------------------|
-| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user. |
-| `merge_request_iid` | integer | yes | The internal ID of the merge request. |
+| Attribute | Type | Required | Description |
+|---------------------|----------------|----------|-----------------------------------------------------------------------------------------------------------------|
+| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user. |
+| `merge_request_iid` | integer | yes | The internal ID of the merge request. |
```json
{
@@ -1445,10 +1445,10 @@ Only for administrators and project owners. Deletes the merge request in questio
DELETE /projects/:id/merge_requests/:merge_request_iid
```
-| Attribute | Type | Required | Description |
-| --------- | ---- | -------- | ----------- |
-| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user. |
-| `merge_request_iid` | integer | yes | The internal ID of the merge request. |
+| Attribute | Type | Required | Description |
+|---------------------|----------------|----------|-----------------------------------------------------------------------------------------------------------------|
+| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user. |
+| `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"
@@ -1464,16 +1464,16 @@ PUT /projects/:id/merge_requests/:merge_request_iid/merge
Parameters:
-| Attribute | Type | Required | Description |
-|--------------------------------|----------------|----------|------------------------------------------------------------------------------------------------------------------|
+| Attribute | Type | Required | Description |
+|--------------------------------|----------------|----------|-----------------------------------------------------------------------------------------------------------------|
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user. |
-| `merge_request_iid` | integer | yes | The internal ID of the merge request. |
-| `merge_commit_message` | string | no | Custom merge commit message. |
-| `squash_commit_message` | string | no | Custom squash commit message. |
-| `squash` | boolean | no | If `true` the commits are squashed into a single commit on merge. |
-| `should_remove_source_branch` | boolean | no | If `true` removes the source branch. |
-| `merge_when_pipeline_succeeds` | boolean | no | If `true` the MR is merged when the pipeline succeeds. |
-| `sha` | string | no | If present, then this SHA must match the HEAD of the source branch, otherwise the merge fails. |
+| `merge_request_iid` | integer | yes | The internal ID of the merge request. |
+| `merge_commit_message` | string | no | Custom merge commit message. |
+| `squash_commit_message` | string | no | Custom squash commit message. |
+| `squash` | boolean | no | If `true` the commits are squashed into a single commit on merge. |
+| `should_remove_source_branch` | boolean | no | If `true` removes the source branch. |
+| `merge_when_pipeline_succeeds` | boolean | no | If `true` the MR is merged when the pipeline succeeds. |
+| `sha` | string | no | If present, then this SHA must match the HEAD of the source branch, otherwise the merge fails. |
```json
{
@@ -1625,12 +1625,12 @@ the `approvals_before_merge` parameter:
This API returns specific HTTP status codes on failure:
-| HTTP Status | Message | Reason |
-| :---: | ------- | ------ |
-| `401` | `Unauthorized` | This user does not have permission to accept this merge request. |
-| `405` | `Method Not Allowed` | The merge request cannot be accepted because it is `Draft`, `Closed`, `Pipeline Pending Completion`, or `Failed`. `Success` is required. |
-| `406` | `Branch cannot be merged` | The branch has conflicts and cannot be merged. |
-| `409` | `SHA does not match HEAD of source branch` | The provided `sha` parameter does not match the HEAD of the source. |
+| HTTP Status | Message | Reason |
+|:------------|--------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------|
+| `401` | `Unauthorized` | This user does not have permission to accept this merge request. |
+| `405` | `Method Not Allowed` | The merge request cannot be accepted because it is `Draft`, `Closed`, `Pipeline Pending Completion`, or `Failed`. `Success` is required. |
+| `406` | `Branch cannot be merged` | The branch has conflicts and cannot be merged. |
+| `409` | `SHA does not match HEAD of source branch` | The provided `sha` parameter does not match the HEAD of the source. |
For additional important notes on response data, read [Single merge request response notes](#single-merge-request-response-notes).
@@ -1655,10 +1655,10 @@ GET /projects/:id/merge_requests/:merge_request_iid/merge_ref
Parameters:
-| Attribute | Type | Required | Description |
-|--------------------------------|----------------|----------|------------------------------------------------------------------------------------------------------------------|
-| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user. |
-| `merge_request_iid` | integer | yes | The internal ID of the merge request. |
+| Attribute | Type | Required | Description |
+|---------------------|----------------|----------|-----------------------------------------------------------------------------------------------------------------|
+| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user. |
+| `merge_request_iid` | integer | yes | The internal ID of the merge request. |
```json
{
@@ -1668,9 +1668,13 @@ Parameters:
## Cancel Merge When Pipeline Succeeds
-- If you don't have permissions to accept this merge request - you receive a `HTTP 401 Unauthorized`.
-- If the merge request is already merged or closed - you receive a `HTTP 405 Method Not Allowed` and the error message 'Method Not Allowed'.
-- In case the merge request is not set to be merged when the pipeline succeeds, you also receive a `HTTP 406 Not Acceptable` error.
+This API returns specific HTTP status codes on failure:
+
+| HTTP Status | Message | Reason |
+|-------------|----------------------|-----------------------------------------------------------------------|
+| `401` | `Unauthorized` | This user does not have permission to cancel this merge request. |
+| `405` | `Method Not Allowed` | The merge request is already merged or closed. |
+| `406` | `Not Acceptable` | The merge request is not set to be merged when the pipeline succeeds. |
```plaintext
POST /projects/:id/merge_requests/:merge_request_iid/cancel_merge_when_pipeline_succeeds
@@ -1678,10 +1682,10 @@ POST /projects/:id/merge_requests/:merge_request_iid/cancel_merge_when_pipeline_
Parameters:
-| Attribute | Type | Required | Description |
-|--------------------------------|----------------|----------|------------------------------------------------------------------------------------------------------------------|
-| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user. |
-| `merge_request_iid` | integer | yes | The internal ID of the merge request. |
+| Attribute | Type | Required | Description |
+|---------------------|----------------|----------|-----------------------------------------------------------------------------------------------------------------|
+| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user. |
+| `merge_request_iid` | integer | yes | The internal ID of the merge request. |
```json
{
@@ -1845,11 +1849,11 @@ you receive a `403 Forbidden` response.
PUT /projects/:id/merge_requests/:merge_request_iid/rebase
```
-| Attribute | Type | Required | Description |
-| --------- | ---- | -------- | ----------- |
-| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user. |
-| `merge_request_iid` | integer | yes | The internal ID of the merge request. |
-| `skip_ci` | boolean | no | Set to `true` to skip creating a CI pipeline. |
+| Attribute | Type | Required | Description |
+|---------------------|----------------|----------|-----------------------------------------------------------------------------------------------------------------|
+| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user. |
+| `merge_request_iid` | integer | yes | The internal ID of the merge request. |
+| `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"
@@ -1908,10 +1912,10 @@ Get all the issues that would be closed by merging the provided merge request.
GET /projects/:id/merge_requests/:merge_request_iid/closes_issues
```
-| Attribute | Type | Required | Description |
-| --------- | ---- | -------- | ----------- |
-| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user. |
-| `merge_request_iid` | integer | yes | The internal ID of the merge request. |
+| Attribute | Type | Required | Description |
+|---------------------|----------------|----------|-----------------------------------------------------------------------------------------------------------------|
+| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user. |
+| `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"
@@ -1984,10 +1988,10 @@ status code `HTTP 304 Not Modified` is returned.
POST /projects/:id/merge_requests/:merge_request_iid/subscribe
```
-| Attribute | Type | Required | Description |
-| --------- | ---- | -------- | ----------- |
-| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user. |
-| `merge_request_iid` | integer | yes | The internal ID of the merge request. |
+| Attribute | Type | Required | Description |
+|---------------------|----------------|----------|-----------------------------------------------------------------------------------------------------------------|
+| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user. |
+| `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"
@@ -2154,10 +2158,10 @@ not subscribed to the merge request, the status code `HTTP 304 Not Modified` is
POST /projects/:id/merge_requests/:merge_request_iid/unsubscribe
```
-| Attribute | Type | Required | Description |
-| --------- | ---- | -------- | ----------- |
-| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user. |
-| `merge_request_iid` | integer | yes | The internal ID of the merge request. |
+| Attribute | Type | Required | Description |
+|---------------------|----------------|----------|-----------------------------------------------------------------------------------------------------------------|
+| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user. |
+| `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"
@@ -2324,10 +2328,10 @@ status code `HTTP 304 Not Modified` is returned.
POST /projects/:id/merge_requests/:merge_request_iid/todo
```
-| Attribute | Type | Required | Description |
-| --------- | ---- | -------- | ----------- |
-| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user. |
-| `merge_request_iid` | integer | yes | The internal ID of the merge request. |
+| Attribute | Type | Required | Description |
+|---------------------|----------------|----------|-----------------------------------------------------------------------------------------------------------------|
+| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user. |
+| `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"
@@ -2451,9 +2455,9 @@ read [SHAs in the API response](#shas-in-the-api-response).
GET /projects/:id/merge_requests/:merge_request_iid/versions
```
-| Attribute | Type | Required | Description |
-| --------- | ------- | -------- | --------------------- |
-| `id` | String | yes | The ID of the project. |
+| Attribute | Type | Required | Description |
+|---------------------|---------|----------|---------------------------------------|
+| `id` | String | yes | The ID of the project. |
| `merge_request_iid` | integer | yes | The internal ID of the merge request. |
```shell
@@ -2486,9 +2490,11 @@ Example response:
### SHAs in the API response
-- `head_commit_sha`: The HEAD commit of the source branch.
-- `base_commit_sha`: The merge-base commit SHA between the source branch and the target branches.
-- `start_commit_sha`: The HEAD commit SHA of the target branch when this version of the diff was created.
+| SHA field | Purpose |
+|--------------------|-------------------------------------------------------------------------------------|
+| `head_commit_sha` | The HEAD commit of the source branch. |
+| `base_commit_sha` | The merge-base commit SHA between the source branch and the target branches. |
+| `start_commit_sha` | The HEAD commit SHA of the target branch when this version of the diff was created. |
## Get a single MR diff version
@@ -2499,8 +2505,8 @@ read [SHAs in the API response](#shas-in-the-api-response).
GET /projects/:id/merge_requests/:merge_request_iid/versions/:version_id
```
-| Attribute | Type | Required | Description |
-| --------- | ------- | -------- | --------------------- |
+| Attribute | Type | Required | Description |
+|---------------------|---------|----------|-------------------------------------------|
| `id` | String | yes | The ID of the project. |
| `merge_request_iid` | integer | yes | The internal ID of the merge request. |
| `version_id` | integer | yes | The ID of the merge request diff version. |
@@ -2567,11 +2573,11 @@ Sets an estimated time of work for this merge request.
POST /projects/:id/merge_requests/:merge_request_iid/time_estimate
```
-| Attribute | Type | Required | Description |
-| --------- | ---- | -------- | ----------- |
-| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user. |
-| `merge_request_iid` | integer | yes | The internal ID of the merge request. |
-| `duration` | string | yes | The duration in human format, such as `3h30m`. |
+| Attribute | Type | Required | Description |
+|---------------------|----------------|----------|-----------------------------------------------------------------------------------------------------------------|
+| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user. |
+| `merge_request_iid` | integer | yes | The internal ID of the merge request. |
+| `duration` | string | yes | The duration in human format, such as `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"
@@ -2596,10 +2602,10 @@ Resets the estimated time for this merge request to 0 seconds.
POST /projects/:id/merge_requests/:merge_request_iid/reset_time_estimate
```
-| Attribute | Type | Required | Description |
-| --------- | ---- | -------- | ----------- |
-| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user. |
-| `merge_request_iid` | integer | yes | The internal ID of a project's merge_request. |
+| Attribute | Type | Required | Description |
+|---------------------|----------------|----------|-----------------------------------------------------------------------------------------------------------------|
+| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user. |
+| `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"
@@ -2624,12 +2630,12 @@ Adds spent time for this merge request.
POST /projects/:id/merge_requests/:merge_request_iid/add_spent_time
```
-| Attribute | Type | Required | Description |
-| --------- | ---- | -------- | ----------- |
-| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user. |
-| `merge_request_iid` | integer | yes | The internal ID of the merge request. |
-| `duration` | string | yes | The duration in human format, such as `3h30m` |
-| `summary` | string | no | A summary of how the time was spent. |
+| Attribute | Type | Required | Description |
+|---------------------|----------------|----------|-----------------------------------------------------------------------------------------------------------------|
+| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user. |
+| `merge_request_iid` | integer | yes | The internal ID of the merge request. |
+| `duration` | string | yes | The duration in human format, such as `3h30m` |
+| `summary` | string | no | A summary of how the time was spent. |
```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"
@@ -2654,10 +2660,10 @@ Resets the total spent time for this merge request to 0 seconds.
POST /projects/:id/merge_requests/:merge_request_iid/reset_spent_time
```
-| Attribute | Type | Required | Description |
-| --------- | ---- | -------- | ----------- |
-| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user. |
-| `merge_request_iid` | integer | yes | The internal ID of a project's merge_request. |
+| Attribute | Type | Required | Description |
+|---------------------|----------------|----------|-----------------------------------------------------------------------------------------------------------------|
+| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user. |
+| `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"
@@ -2680,10 +2686,10 @@ Example response:
GET /projects/:id/merge_requests/:merge_request_iid/time_stats
```
-| Attribute | Type | Required | Description |
-| --------- | ---- | -------- | ----------- |
-| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user. |
-| `merge_request_iid` | integer | yes | The internal ID of the merge request. |
+| Attribute | Type | Required | Description |
+|---------------------|----------------|----------|-----------------------------------------------------------------------------------------------------------------|
+| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user. |
+| `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"
diff --git a/doc/api/notes.md b/doc/api/notes.md
index 445940e02fc..83631c70f8a 100644
--- a/doc/api/notes.md
+++ b/doc/api/notes.md
@@ -399,10 +399,11 @@ Parameters:
| Attribute | Type | Required | Description |
|---------------------|----------------|----------|------------------------------------------------------------------------------------------------------------------------------|
-| `id` | integer or string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) |
-| `merge_request_iid` | integer | yes | The IID of a project merge request |
-| `body` | string | yes | The content of a note. Limited to 1,000,000 characters. |
-| `created_at` | string | no | Date time string, ISO 8601 formatted. Example: `2016-03-11T03:45:40Z` (requires administrator or project/group owner rights) |
+| `id` | integer or string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) |
+| `merge_request_iid` | integer | yes | The IID of a project merge request |
+| `body` | string | yes | The content of a note. Limited to 1,000,000 characters. |
+| `created_at` | string | no | Date time string, ISO 8601 formatted. Example: `2016-03-11T03:45:40Z` (requires administrator or project/group owner rights) |
+| `merge_request_diff_sha`| string | no | The SHA of the head commit which is used to ensure that the merge request hasn't been updated since the API request was sent. This is required for the /merge quick action |
### Modify existing merge request note
diff --git a/doc/api/oauth2.md b/doc/api/oauth2.md
index 59a929e30f4..7b38ac39b96 100644
--- a/doc/api/oauth2.md
+++ b/doc/api/oauth2.md
@@ -2,7 +2,7 @@
type: reference, howto
stage: Manage
group: Authentication and Authorization
-info: To determine the 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/#assignments
---
# OAuth 2.0 identity provider API **(FREE)**
@@ -79,7 +79,7 @@ The Authorization code with PKCE flow, PKCE for short, makes it possible to secu
the OAuth exchange of client credentials for access tokens on public clients without
requiring access to the _Client Secret_ at all. This makes the PKCE flow advantageous
for single page JavaScript applications or other client side apps where keeping secrets
-from the user is a technical impossibility.
+from the user is a technical impossibility.
Before starting the flow, generate the `STATE`, the `CODE_VERIFIER` and the `CODE_CHALLENGE`.
diff --git a/doc/api/packages/pypi.md b/doc/api/packages/pypi.md
index 592b976da59..5ed162a3d05 100644
--- a/doc/api/packages/pypi.md
+++ b/doc/api/packages/pypi.md
@@ -175,6 +175,7 @@ PUT projects/:id/packages/pypi
| Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `id` | string | yes | The ID or full path of the project. |
+| `requires_python` | string | no | The PyPI required version. |
```shell
curl --request PUT \
diff --git a/doc/api/project_import_export.md b/doc/api/project_import_export.md
index 218036b1ee0..46fa05d6cbc 100644
--- a/doc/api/project_import_export.md
+++ b/doc/api/project_import_export.md
@@ -246,6 +246,61 @@ curl --request POST \
The `Content-Length` header must return a valid number. The maximum file size is 10 gigabytes.
The `Content-Type` header must be `application/gzip`.
+## Import a file from AWS S3
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/348874) in GitLab 14.9 in [Beta](https://about.gitlab.com/handbook/product/gitlab-the-product/#beta), [with a flag](../administration/feature_flags.md) named `import_project_from_remote_file_s3`. Disabled by default.
+
+FLAG:
+On self-managed GitLab and GitLab.com, by default this feature is not available. To make it available, ask an administrator to [enable the feature flag](../administration/feature_flags.md) named `import_project_from_remote_file_s3`. This feature is not ready for production use.
+
+```plaintext
+POST /projects/remote-import-s3
+```
+
+| Attribute | Type | Required | Description |
+| ------------------- | -------------- | -------- | ---------------------------------------- |
+| `namespace` | integer/string | no | The ID or path of the namespace to import the project to. Defaults to the current user's namespace. |
+| `name` | string | no | The name of the project to import. If not provided, defaults to the path of the project. |
+| `region` | string | yes | [AWS S3 region name where the file is stored.](https://docs.aws.amazon.com/AmazonS3/latest/userguide/Welcome.html#Regions) |
+| `bucket_name` | string | yes | [AWS S3 bucket name where the file is stored.](https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html) |
+| `file_key` | string | yes | [AWS S3 file key to identify the file.](https://docs.aws.amazon.com/AmazonS3/latest/userguide/UsingObjects.html) |
+| `access_key_id` | string | yes | [AWS S3 access key ID.](https://docs.aws.amazon.com/general/latest/gr/aws-sec-cred-types.html#access-keys-and-secret-access-keys). |
+| `secret_access_key` | string | yes | [AWS S3 secret access key.](https://docs.aws.amazon.com/general/latest/gr/aws-sec-cred-types.html#access-keys-and-secret-access-keys) |
+
+The passed override parameters take precedence over all values defined in the export file.
+
+```shell
+curl --request POST \
+ --url "http://localhost:3000/api/v4/projects/remote-import-s3" \
+ --header "PRIVATE-TOKEN: <your gitlab access key>" \
+ --header 'Content-Type: application/json' \
+ --data '{
+ "name": "Sample Project",
+ "path": "sample-project",
+ "region": "<Your S3 region name>",
+ "bucket_name": "<Your S3 bucket name>",
+ "file_key": "<Your S3 file key>",
+ "access_key_id": "<Your AWS access key id>",
+ "secret_access_key": "<Your AWS secret access key>"
+}'
+```
+
+```json
+{
+ "id": 1,
+ "description": null,
+ "name": "Sample project",
+ "name_with_namespace": "Administrator / sample-project",
+ "path": "sample-project",
+ "path_with_namespace": "root/sample-project",
+ "created_at": "2018-02-13T09:05:58.023Z",
+ "import_status": "scheduled",
+ "correlation_id": "mezklWso3Za",
+ "failed_relations": [],
+ "import_error": null
+}
+```
+
## Import status
Get the status of an import.
diff --git a/doc/api/project_snippets.md b/doc/api/project_snippets.md
index efbd8bf9431..90bd2cd6f83 100644
--- a/doc/api/project_snippets.md
+++ b/doc/api/project_snippets.md
@@ -15,7 +15,7 @@ Constants for snippet visibility levels are:
| visibility | Description |
| ---------- | ----------- |
-| `private` | The snippet is visible only to the snippet creator |
+| `private` | The snippet is visible only to project members |
| `internal` | The snippet is visible for any logged in user except [external users](../user/permissions.md#external-users) |
| `public` | The snippet can be accessed without any authentication |
diff --git a/doc/api/projects.md b/doc/api/projects.md
index db8d2361439..ee649377745 100644
--- a/doc/api/projects.md
+++ b/doc/api/projects.md
@@ -151,6 +151,7 @@ When the user is authenticated and `simple` is not set this returns something li
"resolve_outdated_diff_discussions": false,
"container_registry_enabled": false, // deprecated, use container_registry_access_level instead
"container_registry_access_level": "disabled",
+ "security_and_compliance_access_level": "disabled",
"created_at": "2013-09-30T13:46:02Z",
"last_activity_at": "2013-09-30T13:46:02Z",
"creator_id": 3,
@@ -245,6 +246,7 @@ When the user is authenticated and `simple` is not set this returns something li
"resolve_outdated_diff_discussions": false,
"container_registry_enabled": false, // deprecated, use container_registry_access_level instead
"container_registry_access_level": "disabled",
+ "security_and_compliance_access_level": "disabled",
"created_at": "2013-09-30T13:46:02Z",
"last_activity_at": "2013-09-30T13:46:02Z",
"creator_id": 3,
@@ -440,6 +442,7 @@ GET /users/:user_id/projects
"resolve_outdated_diff_discussions": false,
"container_registry_enabled": false, // deprecated, use container_registry_access_level instead
"container_registry_access_level": "disabled",
+ "security_and_compliance_access_level": "disabled",
"created_at": "2013-09-30T13:46:02Z",
"last_activity_at": "2013-09-30T13:46:02Z",
"creator_id": 3,
@@ -534,6 +537,7 @@ GET /users/:user_id/projects
"resolve_outdated_diff_discussions": false,
"container_registry_enabled": false, // deprecated, use container_registry_access_level instead
"container_registry_access_level": "disabled",
+ "security_and_compliance_access_level": "disabled",
"created_at": "2013-09-30T13:46:02Z",
"last_activity_at": "2013-09-30T13:46:02Z",
"creator_id": 3,
@@ -688,6 +692,7 @@ Example response:
"resolve_outdated_diff_discussions": false,
"container_registry_enabled": false, // deprecated, use container_registry_access_level instead
"container_registry_access_level": "disabled",
+ "security_and_compliance_access_level": "disabled",
"created_at": "2013-09-30T13:46:02Z",
"last_activity_at": "2013-09-30T13:46:02Z",
"creator_id": 3,
@@ -777,6 +782,7 @@ Example response:
"resolve_outdated_diff_discussions": false,
"container_registry_enabled": false, // deprecated, use container_registry_access_level instead
"container_registry_access_level": "disabled",
+ "security_and_compliance_access_level": "disabled",
"created_at": "2013-09-30T13:46:02Z",
"last_activity_at": "2013-09-30T13:46:02Z",
"creator_id": 3,
@@ -910,6 +916,7 @@ GET /projects/:id
"resolve_outdated_diff_discussions": false,
"container_registry_enabled": false, // deprecated, use container_registry_access_level instead
"container_registry_access_level": "disabled",
+ "security_and_compliance_access_level": "disabled",
"container_expiration_policy": {
"cadence": "7d",
"enabled": false,
@@ -1207,7 +1214,7 @@ POST /projects
| Attribute | Type | Required | Description |
|-------------------------------------------------------------|---------|------------------------|-------------|
| `name` | string | **{check-circle}** Yes (if path isn't provided) | The name of the new project. Equals path if not provided. |
-| `path` | string | **{check-circle}** Yes (if name isn't provided) | Repository name for new project. Generated based on name if not provided (generated as lowercase with dashes). |
+| `path` | string | **{check-circle}** Yes (if name isn't provided) | Repository name for new project. Generated based on name if not provided (generated as lowercase with dashes). Starting with GitLab 14.9, path must not start or end with a special character and must not contain consecutive special characters. |
| `allow_merge_on_skipped_pipeline` | boolean | **{dotted-circle}** No | Set whether or not merge requests can be merged with skipped jobs. |
| `analytics_access_level` | string | **{dotted-circle}** No | One of `disabled`, `private` or `enabled` |
| `approvals_before_merge` **(PREMIUM)** | integer | **{dotted-circle}** No | How many approvers should approve merge requests by default. To configure approval rules, see [Merge request approvals API](merge_request_approvals.md). |
@@ -1257,6 +1264,7 @@ POST /projects
| `request_access_enabled` | boolean | **{dotted-circle}** No | Allow users to request member access. |
| `requirements_access_level` | string | **{dotted-circle}** No | One of `disabled`, `private` or `enabled` |
| `resolve_outdated_diff_discussions` | boolean | **{dotted-circle}** No | Automatically resolve merge request diffs discussions on lines changed with a push. |
+| `security_and_compliance_access_level` | string | **{dotted-circle}** No | (GitLab 14.9 and later) Security and compliance access level. One of `disabled`, `private`, or `enabled`. |
| `shared_runners_enabled` | boolean | **{dotted-circle}** No | Enable shared runners for this project. |
| `snippets_access_level` | string | **{dotted-circle}** No | One of `disabled`, `private`, or `enabled`. |
| `snippets_enabled` | boolean | **{dotted-circle}** No | _(Deprecated)_ Enable snippets for this project. Use `snippets_access_level` instead. |
@@ -1334,6 +1342,7 @@ POST /projects/user/:user_id
| `request_access_enabled` | boolean | **{dotted-circle}** No | Allow users to request member access. |
| `requirements_access_level` | string | **{dotted-circle}** No | One of `disabled`, `private`, `enabled` or `public` |
| `resolve_outdated_diff_discussions` | boolean | **{dotted-circle}** No | Automatically resolve merge request diffs discussions on lines changed with a push. |
+| `security_and_compliance_access_level` | string | **{dotted-circle}** No | (GitLab 14.9 and later) Security and compliance access level. One of `disabled`, `private`, or `enabled`. |
| `shared_runners_enabled` | boolean | **{dotted-circle}** No | Enable shared runners for this project. |
| `snippets_access_level` | string | **{dotted-circle}** No | One of `disabled`, `private`, or `enabled`. |
| `snippets_enabled` | boolean | **{dotted-circle}** No | _(Deprecated)_ Enable snippets for this project. Use `snippets_access_level` instead. |
@@ -1433,6 +1442,7 @@ Supported attributes:
| `requirements_access_level` | string | **{dotted-circle}** No | One of `disabled`, `private`, `enabled` or `public` |
| `resolve_outdated_diff_discussions` | boolean | **{dotted-circle}** No | Automatically resolve merge request diffs discussions on lines changed with a push. |
| `restrict_user_defined_variables` | boolean | **{dotted-circle}** No | Allow only users with the Maintainer role to pass user-defined variables when triggering a pipeline. For example when the pipeline is triggered in the UI, with the API, or by a trigger token. |
+| `security_and_compliance_access_level` | string | **{dotted-circle}** No | (GitLab 14.9 and later) Security and compliance access level. One of `disabled`, `private`, or `enabled`. |
| `service_desk_enabled` | boolean | **{dotted-circle}** No | Enable or disable Service Desk feature. |
| `shared_runners_enabled` | boolean | **{dotted-circle}** No | Enable shared runners for this project. |
| `snippets_access_level` | string | **{dotted-circle}** No | One of `disabled`, `private`, or `enabled`. |
@@ -1536,6 +1546,7 @@ Example responses:
"resolve_outdated_diff_discussions": false,
"container_registry_enabled": false, // deprecated, use container_registry_access_level instead
"container_registry_access_level": "disabled",
+ "security_and_compliance_access_level": "disabled",
"created_at": "2013-09-30T13:46:02Z",
"last_activity_at": "2013-09-30T13:46:02Z",
"creator_id": 3,
@@ -1630,6 +1641,7 @@ Example response:
"resolve_outdated_diff_discussions": false,
"container_registry_enabled": false, // deprecated, use container_registry_access_level instead
"container_registry_access_level": "disabled",
+ "security_and_compliance_access_level": "disabled",
"created_at": "2013-09-30T13:46:02Z",
"last_activity_at": "2013-09-30T13:46:02Z",
"creator_id": 3,
@@ -1730,6 +1742,7 @@ Example response:
"resolve_outdated_diff_discussions": false,
"container_registry_enabled": false, // deprecated, use container_registry_access_level instead
"container_registry_access_level": "disabled",
+ "security_and_compliance_access_level": "disabled",
"created_at": "2013-09-30T13:46:02Z",
"last_activity_at": "2013-09-30T13:46:02Z",
"creator_id": 3,
@@ -1910,6 +1923,7 @@ Example response:
"resolve_outdated_diff_discussions": false,
"container_registry_enabled": false, // deprecated, use container_registry_access_level instead
"container_registry_access_level": "disabled",
+ "security_and_compliance_access_level": "disabled",
"created_at": "2013-09-30T13:46:02Z",
"last_activity_at": "2013-09-30T13:46:02Z",
"creator_id": 3,
@@ -2031,6 +2045,7 @@ Example response:
"resolve_outdated_diff_discussions": false,
"container_registry_enabled": false, // deprecated, use container_registry_access_level instead
"container_registry_access_level": "disabled",
+ "security_and_compliance_access_level": "disabled",
"created_at": "2013-09-30T13:46:02Z",
"last_activity_at": "2013-09-30T13:46:02Z",
"creator_id": 3,
@@ -2691,6 +2706,7 @@ Example response:
"builds_access_level": "enabled",
"snippets_access_level": "enabled",
"pages_access_level": "enabled",
+ "security_and_compliance_access_level": "enabled",
"emails_disabled": null,
"shared_runners_enabled": true,
"lfs_enabled": true,
@@ -2758,6 +2774,7 @@ with the API scope enabled.
|--------------|---------|------------------------|-------------|
| `import_url` | string | **{check-circle}** Yes | URL of remote repository being mirrored (with `user:token` if needed). |
| `mirror` | boolean | **{check-circle}** Yes | Enables pull mirroring on project when set to `true`. |
+| `mirror_trigger_builds`| boolean | **{dotted-circle}** No | Trigger pipelines for mirror updates when set to `true`. |
| `only_mirror_protected_branches`| boolean | **{dotted-circle}** No | Limits mirroring to only protected branches when set to `true`. |
## Start the pull mirroring process for a Project **(PREMIUM)**
diff --git a/doc/api/resource_access_tokens.md b/doc/api/resource_access_tokens.md
index c77a8f5d0d6..a9c43625193 100644
--- a/doc/api/resource_access_tokens.md
+++ b/doc/api/resource_access_tokens.md
@@ -6,4 +6,6 @@ remove_date: '2022-04-06'
This document was moved to [another location](project_access_tokens.md).
<!-- This redirect file can be deleted after <2022-04-06>. -->
-<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/#move-or-rename-a-page -->
+<!-- Redirects that point to other docs in the same project expire in three months. -->
+<!-- Redirects that point to docs in a different project or site (for example, link is not relative and starts with `https:`) expire in one year. -->
+<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/redirects.html -->
diff --git a/doc/api/runners.md b/doc/api/runners.md
index 3423a02c078..7437860239e 100644
--- a/doc/api/runners.md
+++ b/doc/api/runners.md
@@ -15,7 +15,7 @@ There are two tokens to take into account when connecting a runner with GitLab.
| Token | Description |
| ----- | ----------- |
| Registration token | Token used to [register the runner](https://docs.gitlab.com/runner/register/). It can be [obtained through GitLab](../ci/runners/index.md). |
-| Authentication token | Token used to authenticate the runner with the GitLab instance. It is obtained automatically when you [register a runner](https://docs.gitlab.com/runner/register/) or by the Runner API when you manually [register a runner](#register-a-new-runner) or [reset the authentication token](#reset-runners-authentication-token). |
+| Authentication token | Token used to authenticate the runner with the GitLab instance. It is obtained automatically when you [register a runner](https://docs.gitlab.com/runner/register/) or by the Runner API when you manually [register a runner](#register-a-new-runner) or [reset the authentication token](#reset-runners-authentication-token-by-using-the-runner-id). |
Here's an example of how the two tokens are used in runner registration:
@@ -48,7 +48,7 @@ GET /runners?tag_list=tag1,tag2
|------------|--------------|----------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `scope` | string | no | Deprecated: Use `type` or `status` instead. The scope of specific runners to show, one of: `active`, `paused`, `online` and `offline`; showing all runners if none provided |
| `type` | string | no | The type of runners to show, one of: `instance_type`, `group_type`, `project_type` |
-| `status` | string | no | The status of runners to show, one of: `online` and `offline`. `active` and `paused` are also possible values which were deprecated in GitLab 14.8 and will be removed in GitLab 15.0 |
+| `status` | string | no | The status of runners to show, one of: `online` and `offline`. `active` and `paused` are also possible values which were deprecated in GitLab 14.8 and will be removed in GitLab 16.0 |
| `paused` | boolean | no | Whether to include only runners that are accepting or ignoring new jobs |
| `tag_list` | string array | no | List of the runner's tags |
@@ -58,11 +58,11 @@ curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/a
NOTE:
The `active` and `paused` values in the `status` query parameter were deprecated [in GitLab 14.8](https://gitlab.com/gitlab-org/gitlab/-/issues/347211).
-and will be removed in [GitLab 15.0](https://gitlab.com/gitlab-org/gitlab/-/issues/351109). They are replaced by the `paused` query parameter.
+and will be removed in [GitLab 16.0](https://gitlab.com/gitlab-org/gitlab/-/issues/351109). They are replaced by the `paused` query parameter.
NOTE:
The `active` attribute in the response was deprecated [in GitLab 14.8](https://gitlab.com/gitlab-org/gitlab/-/issues/347211).
-and will be removed in [GitLab 15.0](https://gitlab.com/gitlab-org/gitlab/-/issues/351109). It is replaced by the `paused` attribute.
+and will be removed in [GitLab 16.0](https://gitlab.com/gitlab-org/gitlab/-/issues/351109). It is replaced by the `paused` attribute.
Example response:
@@ -113,7 +113,7 @@ GET /runners/all?tag_list=tag1,tag2
|------------|--------------|----------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `scope` | string | no | Deprecated: Use `type` or `status` instead. The scope of runners to show, one of: `specific`, `shared`, `active`, `paused`, `online` and `offline`; showing all runners if none provided |
| `type` | string | no | The type of runners to show, one of: `instance_type`, `group_type`, `project_type` |
-| `status` | string | no | The status of runners to show, one of: `online` and `offline`. `active` and `paused` are also possible values which were deprecated in GitLab 14.8 and will be removed in GitLab 15.0 |
+| `status` | string | no | The status of runners to show, one of: `online` and `offline`. `active` and `paused` are also possible values which were deprecated in GitLab 14.8 and will be removed in GitLab 16.0 |
| `paused` | boolean | no | Whether to include only runners that are accepting or ignoring new jobs |
| `tag_list` | string array | no | List of the runner's tags |
@@ -123,11 +123,11 @@ curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/a
NOTE:
The `active` and `paused` values in the `status` query parameter were deprecated [in GitLab 14.8](https://gitlab.com/gitlab-org/gitlab/-/issues/347211).
-and will be removed in [GitLab 15.0](https://gitlab.com/gitlab-org/gitlab/-/issues/351109). They are replaced by the `paused` query parameter.
+and will be removed in [GitLab 16.0](https://gitlab.com/gitlab-org/gitlab/-/issues/351109). They are replaced by the `paused` query parameter.
NOTE:
The `active` attribute in the response was deprecated [in GitLab 14.8](https://gitlab.com/gitlab-org/gitlab/-/issues/347211).
-and will be removed in [GitLab 15.0](https://gitlab.com/gitlab-org/gitlab/-/issues/351109). It is replaced by the `paused` attribute.
+and will be removed in [GitLab 16.0](https://gitlab.com/gitlab-org/gitlab/-/issues/351109). It is replaced by the `paused` attribute.
Example response:
@@ -213,7 +213,7 @@ and removed in [GitLab 13.0](https://gitlab.com/gitlab-org/gitlab/-/issues/21432
NOTE:
The `active` attribute in the response was deprecated [in GitLab 14.8](https://gitlab.com/gitlab-org/gitlab/-/issues/347211).
-and will be removed in [GitLab 15.0](https://gitlab.com/gitlab-org/gitlab/-/issues/351109). It is replaced by the `paused` attribute.
+and will be removed in [GitLab 16.0](https://gitlab.com/gitlab-org/gitlab/-/issues/351109). It is replaced by the `paused` attribute.
Example response:
@@ -283,7 +283,7 @@ and [removed](https://gitlab.com/gitlab-org/gitlab/-/issues/214322) in GitLab 13
NOTE:
The `active` query parameter was deprecated [in GitLab 14.8](https://gitlab.com/gitlab-org/gitlab/-/issues/347211).
-and will be removed in [GitLab 15.0](https://gitlab.com/gitlab-org/gitlab/-/issues/351109). It is replaced by the `paused` attribute.
+and will be removed in [GitLab 16.0](https://gitlab.com/gitlab-org/gitlab/-/issues/351109). It is replaced by the `paused` attribute.
Example response:
@@ -353,7 +353,7 @@ curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" \
NOTE:
The `active` form attribute was deprecated [in GitLab 14.8](https://gitlab.com/gitlab-org/gitlab/-/issues/347211).
-and will be removed in [GitLab 15.0](https://gitlab.com/gitlab-org/gitlab/-/issues/351109). It is replaced by the `paused` attribute.
+and will be removed in [GitLab 16.0](https://gitlab.com/gitlab-org/gitlab/-/issues/351109). It is replaced by the `paused` attribute.
## List runner's jobs
@@ -464,7 +464,7 @@ GET /projects/:id/runners?tag_list=tag1,tag2
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user |
| `scope` | string | no | Deprecated: Use `type` or `status` instead. The scope of specific runners to show, one of: `active`, `paused`, `online` and `offline`; showing all runners if none provided |
| `type` | string | no | The type of runners to show, one of: `instance_type`, `group_type`, `project_type` |
-| `status` | string | no | The status of runners to show, one of: `online` and `offline`. `active` and `paused` are also possible values which were deprecated in GitLab 14.8 and will be removed in GitLab 15.0 |
+| `status` | string | no | The status of runners to show, one of: `online` and `offline`. `active` and `paused` are also possible values which were deprecated in GitLab 14.8 and will be removed in GitLab 16.0 |
| `paused` | boolean | no | Whether to include only runners that are accepting or ignoring new jobs |
| `tag_list` | string array | no | List of the runner's tags |
@@ -474,11 +474,11 @@ curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/a
NOTE:
The `active` and `paused` values in the `status` query parameter were deprecated [in GitLab 14.8](https://gitlab.com/gitlab-org/gitlab/-/issues/347211).
-and will be removed in [GitLab 15.0](https://gitlab.com/gitlab-org/gitlab/-/issues/351109). They are replaced by the `paused` query parameter.
+and will be removed in [GitLab 16.0](https://gitlab.com/gitlab-org/gitlab/-/issues/351109). They are replaced by the `paused` query parameter.
NOTE:
The `active` attribute in the response was deprecated [in GitLab 14.8](https://gitlab.com/gitlab-org/gitlab/-/issues/347211).
-and will be removed in [GitLab 15.0](https://gitlab.com/gitlab-org/gitlab/-/issues/351109). It is replaced by the `paused` attribute.
+and will be removed in [GitLab 16.0](https://gitlab.com/gitlab-org/gitlab/-/issues/351109). It is replaced by the `paused` attribute.
Example response:
@@ -580,7 +580,7 @@ GET /groups/:id/runners?tag_list=tag1,tag2
|------------|----------------|----------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `id` | integer | yes | The ID of the group owned by the authenticated user |
| `type` | string | no | The type of runners to show, one of: `instance_type`, `group_type`, `project_type`. The `project_type` value is [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/351466) and will be removed in GitLab 15.0 |
-| `status` | string | no | The status of runners to show, one of: `online` and `offline`. `active` and `paused` are also possible values which were deprecated in GitLab 14.8 and will be removed in GitLab 15.0 |
+| `status` | string | no | The status of runners to show, one of: `online` and `offline`. `active` and `paused` are also possible values which were deprecated in GitLab 14.8 and will be removed in GitLab 16.0 |
| `paused` | boolean | no | Whether to include only runners that are accepting or ignoring new jobs |
| `tag_list` | string array | no | List of the runner's tags |
@@ -590,11 +590,11 @@ curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/a
NOTE:
The `active` and `paused` values in the `status` query parameter were deprecated [in GitLab 14.8](https://gitlab.com/gitlab-org/gitlab/-/issues/347211).
-and will be removed in [GitLab 15.0](https://gitlab.com/gitlab-org/gitlab/-/issues/351109). They are replaced by the `paused` query parameter.
+and will be removed in [GitLab 16.0](https://gitlab.com/gitlab-org/gitlab/-/issues/351109). They are replaced by the `paused` query parameter.
NOTE:
The `active` attribute in the response was deprecated [in GitLab 14.8](https://gitlab.com/gitlab-org/gitlab/-/issues/347211).
-and will be removed in [GitLab 15.0](https://gitlab.com/gitlab-org/gitlab/-/issues/351109). It is replaced by the `paused` attribute.
+and will be removed in [GitLab 16.0](https://gitlab.com/gitlab-org/gitlab/-/issues/351109). It is replaced by the `paused` attribute.
Example response:
@@ -660,7 +660,7 @@ POST /runners
| `access_level` | string | no | The access_level of the runner; `not_protected` or `ref_protected` |
| `maximum_timeout` | integer | no | Maximum timeout set when this runner handles the job |
| `maintainer_note` | string | no | [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/350730), see `maintenance_note` |
-| `maintenance_note` | string | no | Free-form maintenance notes for the runner (255 characters) |
+| `maintenance_note` | string | no | Free-form maintenance notes for the runner (1024 characters) |
```shell
curl --request POST "https://gitlab.example.com/api/v4/runners" \
@@ -799,9 +799,9 @@ curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" \
"https://gitlab.example.com/api/v4/groups/9/runners/reset_registration_token"
```
-## Reset runner's authentication token
+## Reset runner's authentication token by using the runner ID
-Resets the runner's authentication token.
+Resets the runner's authentication token by using its runner ID.
```plaintext
POST /runners/:id/reset_authentication_token
@@ -824,3 +824,29 @@ Example response:
"token_expires_at": "2021-09-27T21:05:03.203Z"
}
```
+
+## Reset runner's authentication token by using the current token
+
+Resets the runner's authentication token by using the current token's value as an input.
+
+```plaintext
+POST /runners/reset_authentication_token
+```
+
+| Attribute | Type | Required | Description |
+|-----------|---------|----------|---------------------------------|
+| `token` | string | yes | The current token of the runner |
+
+```shell
+curl --request POST --form "token=<current token>" \
+ "https://gitlab.example.com/api/v4/runners/reset_authentication_token"
+```
+
+Example response:
+
+```json
+{
+ "token": "6337ff461c94fd3fa32ba3b1ff4125",
+ "token_expires_at": "2021-09-27T21:05:03.203Z"
+}
+```
diff --git a/doc/api/search.md b/doc/api/search.md
index 2969cf439dd..8c681904e98 100644
--- a/doc/api/search.md
+++ b/doc/api/search.md
@@ -27,7 +27,7 @@ GET /search
| `order_by` | string | no | Allowed values are `created_at` only. If this is not set, the results are either sorted by `created_at` in descending order for basic search, or by the most relevant documents when using advanced search.|
| `sort` | string | no | Allowed values are `asc` or `desc` only. If this is not set, the results are either sorted by `created_at` in descending order for basic search, or by the most relevant documents when using advanced search.|
-Search the expression within the specified scope. Currently these scopes are supported: projects, issues, merge_requests, milestones, snippet_titles, users.
+Search the expression in the specified scope. These scopes are supported: projects, issues, merge_requests, milestones, snippet_titles, users.
If Elasticsearch is enabled additional scopes available are blobs, wiki_blobs, notes, and commits. Find more about [the feature](../integration/elasticsearch.md). **(PREMIUM)**
@@ -344,7 +344,7 @@ Filters are available for this scope:
- path
- extension
-to use a filter simply include it in your query like so: `a query filename:some_name*`.
+To use a filter, include it in your query. For example: `a query filename:some_name*`.
You may use wildcards (`*`) to use glob matching.
@@ -432,7 +432,7 @@ Example response:
## Group Search API
-Search within the specified group.
+Search in the specified group.
If a user is not a member of a group and the group is private, a `GET` request on that group results in a `404` status code.
@@ -450,7 +450,7 @@ GET /groups/:id/search
| `order_by` | string | no | Allowed values are `created_at` only. If this is not set, the results are either sorted by `created_at` in descending order for basic search, or by the most relevant documents when using advanced search.|
| `sort` | string | no | Allowed values are `asc` or `desc` only. If this is not set, the results are either sorted by `created_at` in descending order for basic search, or by the most relevant documents when using advanced search.|
-Search the expression within the specified scope. Currently these scopes are supported: projects, issues, merge_requests, milestones, users.
+Search the expression in the specified scope. These scopes are supported: projects, issues, merge_requests, milestones, users.
If Elasticsearch is enabled additional scopes available are blobs, wiki_blobs, notes, and commits. Find more about [the feature](../integration/elasticsearch.md). **(PREMIUM)**
@@ -736,7 +736,7 @@ Filters are available for this scope:
- path
- extension
-to use a filter simply include it in your query like so: `a query filename:some_name*`.
+To use a filter, include it in your query. For example: `a query filename:some_name*`.
You may use wildcards (`*`) to use glob matching.
@@ -824,7 +824,7 @@ Example response:
## Project Search API
-Search within the specified project.
+Search in the specified project.
If a user is not a member of a project and the project is private, a `GET` request on that project results in a `404` status code.
@@ -843,7 +843,7 @@ GET /projects/:id/search
| `order_by` | string | no | Allowed values are `created_at` only. If this is not set, the results are either sorted by `created_at` in descending order for basic search, or by the most relevant documents when using advanced search.|
| `sort` | string | no | Allowed values are `asc` or `desc` only. If this is not set, the results are either sorted by `created_at` in descending order for basic search, or by the most relevant documents when using advanced search.|
-Search the expression within the specified scope. Currently these scopes are supported: issues, merge_requests, milestones, notes, wiki_blobs, commits, blobs, users.
+Search the expression in the specified scope. These scopes are supported: issues, merge_requests, milestones, notes, wiki_blobs, commits, blobs, users.
The response depends on the requested scope.
@@ -1065,7 +1065,7 @@ Filters are available for this scope:
- path
- extension
-To use a filter simply include it in your query like: `a query filename:some_name*`.
+To use a filter, include it in your query. For example: `a query filename:some_name*`.
You may use wildcards (`*`) to use glob matching.
Wiki blobs searches are performed on both filenames and contents. Search
@@ -1148,7 +1148,7 @@ Filters are available for this scope:
- path
- extension
-To use a filter simply include it in your query like: `a query filename:some_name*`.
+To use a filter, include it in your query. For example: `a query filename:some_name*`.
You may use wildcards (`*`) to use glob matching.
Blobs searches are performed on both filenames and contents. Search results:
diff --git a/doc/api/secure_files.md b/doc/api/secure_files.md
new file mode 100644
index 00000000000..96190920a33
--- /dev/null
+++ b/doc/api/secure_files.md
@@ -0,0 +1,171 @@
+---
+stage: Verify
+group: Pipeline Authoring
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
+type: reference, api
+---
+
+# Project-level Secure Files API **(FREE)**
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/78227) in GitLab 14.8. [Deployed behind the `ci_secure_files` flag](../administration/feature_flags.md), disabled by default.
+
+FLAG:
+On self-managed GitLab, by default this feature is not available. To make it available,
+ask an administrator to [enable the feature flag](../administration/feature_flags.md) named `ci_secure_files`.
+The feature is not ready for production use.
+
+## List project secure files
+
+Get list of secure files in a project.
+
+```plaintext
+GET /projects/:project_id/secure_files
+```
+
+Supported attributes:
+
+| Attribute | Type | Required | Description |
+|--------------|----------------|------------------------|-------------|
+| `project_id` | integer/string | **{check-circle}** Yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user. |
+
+Example request:
+
+```shell
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/secure_files"
+```
+
+Example response:
+
+```json
+[
+ {
+ "id": 1,
+ "name": "myfile.jks",
+ "checksum": "16630b189ab34b2e3504f4758e1054d2e478deda510b2b08cc0ef38d12e80aac",
+ "checksum_algorithm": "sha256",
+ "permissions": "read_only",
+ "created_at": "2022-02-22T22:22:22.222Z"
+ },
+ {
+ "id": 2,
+ "name": "myotherfile.jks",
+ "checksum": "16630b189ab34b2e3504f4758e1054d2e478deda510b2b08cc0ef38d12e80aa2",
+ "checksum_algorithm": "sha256",
+ "permissions": "execute",
+ "created_at": "2022-02-22T22:22:22.222Z"
+ }
+]
+```
+
+## Show secure file details
+
+Get the details of a specific secure file in a project.
+
+```plaintext
+GET /projects/:project_id/secure_files/:id
+```
+
+Supported attributes:
+
+| Attribute | Type | Required | Description |
+|--------------|----------------|------------------------|-------------|
+| `project_id` | integer/string | **{check-circle}** Yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user. |
+| `id` | integer | **{check-circle}** Yes | The `id` of a secure file. |
+
+Example request:
+
+```shell
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/secure_files/1"
+```
+
+Example response:
+
+```json
+{
+ "id": 1,
+ "name": "myfile.jks",
+ "checksum": "16630b189ab34b2e3504f4758e1054d2e478deda510b2b08cc0ef38d12e80aac",
+ "checksum_algorithm": "sha256",
+ "permissions": "read_only",
+ "created_at": "2022-02-22T22:22:22.222Z"
+}
+```
+
+## Create secure file
+
+Create a new secure file.
+
+```plaintext
+POST /projects/:project_id/secure_files
+```
+
+Supported attributes:
+
+| Attribute | Type | Required | Description |
+|---------------|----------------|------------------------|-------------|
+| `project_id` | integer/string | **{check-circle}** Yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user. |
+| `name` | string | **{check-circle}** Yes | The `name` of the file being uploaded. |
+| `file` | file | **{check-circle}** Yes | The `file` being uploaded. |
+| `permissions` | string | **{dotted-circle}** No | The file is created with the specified permissions when created in the CI/CD job. Available types are: `read_only` (default), `read_write`, and `execute`. |
+
+Example request:
+
+```shell
+curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" \
+ "https://gitlab.example.com/api/v4/projects/1/secure_files" --form "name=myfile.jks" --form "file=@/path/to/file/myfile.jks"
+```
+
+Example response:
+
+```json
+{
+ "id": 1,
+ "name": "myfile.jks",
+ "checksum": "16630b189ab34b2e3504f4758e1054d2e478deda510b2b08cc0ef38d12e80aac",
+ "checksum_algorithm": "sha256",
+ "permissions": "read_only",
+ "created_at": "2022-02-22T22:22:22.222Z"
+}
+```
+
+## Download secure file
+
+Download the contents of a project's secure file.
+
+```plaintext
+GET /projects/:project_id/download/:id
+```
+
+Supported attributes:
+
+| Attribute | Type | Required | Description |
+|--------------|----------------|------------------------|-------------|
+| `project_id` | integer/string | **{check-circle}** Yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user. |
+| `id` | integer | **{check-circle}** Yes | The `id` of a secure file. |
+
+Example request:
+
+```shell
+curl --request GET --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/1/secure_files/1/download --output myfile.jks
+```
+
+## Remove secure file
+
+Remove a project's secure file.
+
+```plaintext
+DELETE /projects/:project_id/secure_files/:id
+```
+
+Supported attributes:
+
+| Attribute | Type | Required | Description |
+|--------------|----------------|------------------------|-------------|
+| `project_id` | integer/string | **{check-circle}** Yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user. |
+| `id` | integer | **{check-circle}** Yes | The `id` of a secure file. |
+
+Example request:
+
+```shell
+curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/secure_files/1"
+```
diff --git a/doc/api/settings.md b/doc/api/settings.md
index 4246c7a46f1..b9c52ff01fd 100644
--- a/doc/api/settings.md
+++ b/doc/api/settings.md
@@ -53,6 +53,10 @@ Example response:
"gravatar_enabled" : true,
"sign_in_text" : null,
"container_expiration_policies_enable_historic_entries": true,
+ "container_registry_cleanup_tags_service_max_list_size": 200,
+ "container_registry_delete_tags_service_timeout": 250,
+ "container_registry_expiration_policies_caching": true,
+ "container_registry_expiration_policies_worker_capacity": 4,
"container_registry_token_expire_delay": 5,
"repository_storages_weighted": {"default": 100},
"plantuml_enabled": false,
@@ -158,6 +162,11 @@ Example response:
"external_authorization_service_timeout": 0.5,
"user_oauth_applications": true,
"after_sign_out_path": "",
+ "container_expiration_policies_enable_historic_entries": true,
+ "container_registry_cleanup_tags_service_max_list_size": 200,
+ "container_registry_delete_tags_service_timeout": 250,
+ "container_registry_expiration_policies_caching": true,
+ "container_registry_expiration_policies_worker_capacity": 4,
"container_registry_token_expire_delay": 5,
"repository_storages": ["default"],
"plantuml_enabled": false,
@@ -248,6 +257,11 @@ listed in the descriptions of the relevant settings.
| `automatic_purchased_storage_allocation` | boolean | no | Enabling this permits automatic allocation of purchased storage in a namespace. |
| `check_namespace_plan` **(PREMIUM)** | boolean | no | Enabling this makes only licensed EE features available to projects if the project namespace's plan includes the feature or if the project is public. |
| `commit_email_hostname` | string | no | Custom hostname (for private commit emails). |
+| `container_expiration_policies_enable_historic_entries` | boolean | no | Enable [cleanup policies](../user/packages/container_registry/reduce_container_registry_storage.md#enable-the-cleanup-policy) for all projects. |
+| `container_registry_cleanup_tags_service_max_list_size` | integer | no | The maximum number of tags that can be deleted in a single execution of [cleanup policies](../user/packages/container_registry/reduce_container_registry_storage.md#set-cleanup-limits-to-conserve-resources). |
+| `container_registry_delete_tags_service_timeout` | integer | no | The maximum time, in seconds, that the cleanup process can take to delete a batch of tags for [cleanup policies](../user/packages/container_registry/reduce_container_registry_storage.md#set-cleanup-limits-to-conserve-resources). |
+| `container_registry_expiration_policies_caching` | boolean | no | Caching during the execution of [cleanup policies](../user/packages/container_registry/reduce_container_registry_storage.md#set-cleanup-limits-to-conserve-resources). |
+| `container_registry_expiration_policies_worker_capacity` | integer | no | Number of workers for [cleanup policies](../user/packages/container_registry/reduce_container_registry_storage.md#set-cleanup-limits-to-conserve-resources). |
| `container_registry_token_expire_delay` | integer | no | Container Registry token duration in minutes. |
| `deactivate_dormant_users` | boolean | no | Enable [automatic deactivation of dormant users](../user/admin_area/moderate_users.md#automatically-deactivate-dormant-users). |
| `default_artifacts_expire_in` | string | no | Set the default expiration time for each job's artifacts. |
@@ -376,7 +390,9 @@ listed in the descriptions of the relevant settings.
| `push_event_hooks_limit` | integer | no | Number of changes (branches or tags) in a single push to determine whether webhooks and services fire or not. Webhooks and services aren't submitted if it surpasses that value. |
| `rate_limiting_response_text` | string | no | When rate limiting is enabled via the `throttle_*` settings, send this plain text response when a rate limit is exceeded. 'Retry later' is sent if this is blank. |
| `raw_blob_request_limit` | integer | no | Max number of requests per minute for each raw path. Default: 300. To disable throttling set to 0.|
-| `user_email_lookup_limit` | integer | no | Max number of requests per minute for email lookup. Default: 60. To disable throttling set to 0.|
+| `user_email_lookup_limit` | integer | no | **{warning}** **[Removed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/80631/)** in GitLab 14.9. Replaced by `search_rate_limit`. Max number of requests per minute for email lookup. Default: 60. To disable throttling set to 0.|
+| `search_rate_limit` | integer | no | Max number of requests per minute for performing a search while authenticated. Default: 30. To disable throttling set to 0.|
+| `search_rate_limit_unauthenticated` | integer | no | Max number of requests per minute for performing a search while unauthenticated. Default: 10. To disable throttling set to 0.|
| `recaptcha_enabled` | boolean | no | (**If enabled, requires:** `recaptcha_private_key` and `recaptcha_site_key`) Enable reCAPTCHA. |
| `recaptcha_private_key` | string | required by: `recaptcha_enabled` | Private key for reCAPTCHA. |
| `recaptcha_site_key` | string | required by: `recaptcha_enabled` | Site key for reCAPTCHA. |
diff --git a/doc/api/status_checks.md b/doc/api/status_checks.md
index a3a342854dd..3671ddbd138 100644
--- a/doc/api/status_checks.md
+++ b/doc/api/status_checks.md
@@ -44,8 +44,17 @@ GET /projects/:id/merge_requests/:merge_request_iid/status_checks
## Set status of an external status check
+> - Introduced in GitLab 14.9, `passed` status to pass external status checks. Introduced [with a flag](../administration/feature_flags.md) named `status_checks_add_status_field`. Disabled by default.
+> - Introduced in GitLab 14.9, `failed` status to fail external status checks. Introduced [with a flag](../administration/feature_flags.md) named `status_checks_add_status_field`. Disabled by default.
+> - `pass` status to pass checks is [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/339039) in GitLab 14.9. Replaced with `passed`.
+
+FLAG:
+On self-managed GitLab, by default setting `passed` instead of `pass` is unavailable. Also, setting `failed` is unavailable by default. To support
+setting `passed` and `failed` instead of only `pass`, ask an administrator to [enable the feature flag](../administration/feature_flags.md) named
+`status_checks_add_status_field`. On GitLab.com, this feature is not available.
+
For a single merge request, use the API to inform GitLab that a merge request has passed a check by an external service.
-To set the status of an external check, the personal access token used must belong to a user with at least the developer role on the target project of the merge request.
+To set the status of an external check, the personal access token used must belong to a user with at least the Developer role on the target project of the merge request.
Execute this API call as any user with rights to approve the merge request itself.
@@ -55,13 +64,14 @@ POST /projects/:id/merge_requests/:merge_request_iid/status_check_responses
**Parameters:**
-| Attribute | Type | Required | Description |
-| -------------------------- | ------- | -------- | ------------------------------------- |
-| `id` | integer | yes | ID of a project |
-| `merge_request_iid` | integer | yes | IID of a merge request |
-| `sha` | string | yes | SHA at `HEAD` of the source branch |
-| `external_status_check_id` | integer | yes | ID of an external status check |
-| `status` | string | no | Set to `pass` to pass the check |
+| Attribute | Type | Required | Description |
+| -------------------------- | ------- | -------- | ---------------------------------------------------------------------------- |
+| `id` | integer | yes | ID of a project |
+| `merge_request_iid` | integer | yes | IID of a merge request |
+| `sha` | string | yes | SHA at `HEAD` of the source branch |
+| `external_status_check_id` | integer | yes | ID of an external status check |
+| `status` | string | no | Set to `passed` to pass the check or `failed` to fail it (GitLab 14.9 and later with feature flag `status_checks_add_status_field` enabled) |
+| `status` | string | no | Set to `pass` to pass the check (GitLab 14.0 to GitLab 14.8, and GitLab 14.9 and later with feature flag `status_checks_add_status_field` disabled) |
NOTE:
`sha` must be the SHA at the `HEAD` of the merge request's source branch.
diff --git a/doc/api/system_hooks.md b/doc/api/system_hooks.md
index 3587016ac6b..f14f1322184 100644
--- a/doc/api/system_hooks.md
+++ b/doc/api/system_hooks.md
@@ -46,6 +46,43 @@ Example response:
]
```
+## Get system hook
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/81595) in GitLab 14.9.
+
+Get a system hook by its ID.
+
+```plaintext
+GET /hooks/:id
+```
+
+| Attribute | Type | Required | Description |
+| --------- | ---- | -------- | ----------- |
+| `id` | integer | yes | The ID of the hook |
+
+Example request:
+
+```shell
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/hooks/1"
+```
+
+Example response:
+
+```json
+[
+ {
+ "id": 1,
+ "url": "https://gitlab.example.com/hook",
+ "created_at": "2016-10-31T12:32:15.192Z",
+ "push_events": true,
+ "tag_push_events": false,
+ "merge_requests_events": true,
+ "repository_update_events": true,
+ "enable_ssl_verification": true
+ }
+]
+```
+
## Add new system hook
Add a new system hook.
diff --git a/doc/api/topics.md b/doc/api/topics.md
index 538b9af9374..1246e36f2cb 100644
--- a/doc/api/topics.md
+++ b/doc/api/topics.md
@@ -203,3 +203,28 @@ curl --request PUT \
--header "PRIVATE-TOKEN: <your_access_token>" \
"https://gitlab.example.com/api/v4/topics/1"
```
+
+## Delete a project topic
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/80725) in GitLab 14.9.
+
+You must be an administrator to delete a project.
+When you delete a project topic, you also delete the topic assignment for projects.
+
+```plaintext
+DELETE /topics/:id
+```
+
+Supported attributes:
+
+| Attribute | Type | Required | Description |
+| ------------- | ------- | ---------------------- | ------------------- |
+| `id` | integer | **{check-circle}** Yes | ID of project topic |
+
+Example request:
+
+```shell
+curl --request DELETE \
+ --header "PRIVATE-TOKEN: <your_access_token>" \
+ "https://gitlab.example.com/api/v4/topics/1"
+```
diff --git a/doc/api/users.md b/doc/api/users.md
index 925563aeb1f..de9af59de93 100644
--- a/doc/api/users.md
+++ b/doc/api/users.md
@@ -603,7 +603,7 @@ Parameters:
"avatar_url": "http://localhost:3000/uploads/user/avatar/1/index.jpg",
"web_url": "http://localhost:3000/john_smith",
"created_at": "2012-05-23T08:00:58Z",
- "is_admin": false,
+ "is_admin": true,
"bio": "",
"location": null,
"public_email": "john@example.com",
@@ -958,6 +958,32 @@ Parameters:
}
```
+## Single SSH key for given user
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/81790) in GitLab 14.9.
+
+Get a single key for a given user.
+
+```plaintext
+GET /users/:id/keys/:key_id
+```
+
+Parameters:
+
+| Attribute | Type | Required | Description |
+|-----------|---------|----------|----------------------|
+| `id` | integer | yes | ID of specified user |
+| `key_id` | integer | yes | SSH key ID |
+
+```json
+{
+ "id": 1,
+ "title": "Public key",
+ "key": "ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAIEAiPWx6WM4lhHNedGfBpPJNPpZ7yKu+dnn1SJejgt4596k6YjzGGphH2TUxwKzxcKDKKezwkpfnxPkSMkuEspGRt/aZZ9wa++Oi7Qkr8prgHc4soW6NUlfDzpvZK2H5E7eQaSeP3SAwGmQKUFHCddNaP0L+hM7zhFNzjFvpaMgJw0=",
+ "created_at": "2014-08-01T14:47:39.080Z"
+}
+```
+
## Add SSH key
Creates a new key owned by the currently authenticated user.
diff --git a/doc/api/v3_to_v4.md b/doc/api/v3_to_v4.md
index 9c2170e0709..875f4528c0e 100644
--- a/doc/api/v3_to_v4.md
+++ b/doc/api/v3_to_v4.md
@@ -6,4 +6,6 @@ remove_date: '2023-01-31'
This document was moved to [another location](https://gitlab.com/gitlab-org/gitlab-foss/-/blob/11-0-stable/doc/api/v3_to_v4.md).
<!-- This redirect file can be deleted after <2023-01-31>. -->
-<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/#move-or-rename-a-page -->
+<!-- Redirects that point to other docs in the same project expire in three months. -->
+<!-- Redirects that point to docs in a different project or site (for example, link is not relative and starts with `https:`) expire in one year. -->
+<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/redirects.html -->
diff --git a/doc/api/vulnerability_exports.md b/doc/api/vulnerability_exports.md
index 9395a4ee5de..6f6a661dbd5 100644
--- a/doc/api/vulnerability_exports.md
+++ b/doc/api/vulnerability_exports.md
@@ -9,7 +9,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/197494) in GitLab 12.10. [Updated](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/30397) in GitLab 13.0.
WARNING:
-This API is in an alpha stage and considered unstable.
+This API is in an [Alpha](../policy/alpha-beta-support.md#alpha-features) stage and considered unstable.
The response payload may be subject to change or breakage
across GitLab releases.
diff --git a/doc/api/wikis.md b/doc/api/wikis.md
index fb49e9465bc..b7c9d0d6008 100644
--- a/doc/api/wikis.md
+++ b/doc/api/wikis.md
@@ -6,6 +6,10 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Project wikis API **(FREE)**
+> - The `encoding` field was [added](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/81150) in GitLab 14.9.
+> - The `render_html` attribute was [added](https://gitlab.com/gitlab-org/gitlab/-/issues/336792) in GitLab 14.9.
+> - The `version` attribute was [added](https://gitlab.com/gitlab-org/gitlab/-/issues/336792) in GitLab 14.9.
+
The project [wikis](../user/project/wiki/index.md) API is available only in APIv4.
An API for [group wikis](group_wikis.md) is also available.
@@ -34,18 +38,21 @@ Example response:
"content" : "Here is an instruction how to deploy this project.",
"format" : "markdown",
"slug" : "deploy",
- "title" : "deploy"
+ "title" : "deploy",
+ "encoding": "UTF-8"
},
{
"content" : "Our development process is described here.",
"format" : "markdown",
"slug" : "development",
- "title" : "development"
+ "title" : "development",
+ "encoding": "UTF-8"
},{
"content" : "* [Deploy](deploy)\n* [Development](development)",
"format" : "markdown",
"slug" : "home",
- "title" : "home"
+ "title" : "home",
+ "encoding": "UTF-8"
}
]
```
@@ -62,6 +69,8 @@ GET /projects/:id/wikis/:slug
| --------- | ------- | -------- | --------------------- |
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) |
| `slug` | string | yes | URLencoded slug (a unique string) of the wiki page, such as `dir%2Fpage_name` |
+| `render_html` | boolean | no | Return the rendered HTML of the wiki page |
+| `version` | string | no | Wiki page version sha |
```shell
curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/wikis/home"
@@ -74,7 +83,8 @@ Example response:
"content" : "home page",
"format" : "markdown",
"slug" : "home",
- "title" : "home"
+ "title" : "home",
+ "encoding": "UTF-8"
}
```
@@ -105,7 +115,8 @@ Example response:
"content" : "Hello world",
"format" : "markdown",
"slug" : "Hello",
- "title" : "Hello"
+ "title" : "Hello",
+ "encoding": "UTF-8"
}
```
@@ -137,7 +148,8 @@ Example response:
"content" : "documentation",
"format" : "markdown",
"slug" : "Docs",
- "title" : "Docs"
+ "title" : "Docs",
+ "encoding": "UTF-8"
}
```
diff --git a/doc/architecture/blueprints/ci_scale/index.md b/doc/architecture/blueprints/ci_scale/index.md
index 092f8a7119a..be21f824392 100644
--- a/doc/architecture/blueprints/ci_scale/index.md
+++ b/doc/architecture/blueprints/ci_scale/index.md
@@ -174,15 +174,15 @@ Work required to achieve our next CI/CD scaling target is tracked in the
1. ✓ Migrate primary keys to big integers on GitLab.com.
1. ✓ Implement the new architecture of builds queuing on GitLab.com.
-1. Make the new builds queuing architecture generally available.
-1. Partition CI/CD data using time-decay pattern.
+1. [Make the new builds queuing architecture generally available](https://gitlab.com/groups/gitlab-org/-/epics/6954).
+1. [Partition CI/CD data using time-decay pattern](../ci_data_decay/).
## Status
|-------------|--------------|
| Created at | 21.01.2021 |
| Approved at | 26.04.2021 |
-| Updated at | 06.12.2021 |
+| Updated at | 28.02.2022 |
Status: In progress.
diff --git a/doc/architecture/blueprints/composable_codebase_using_rails_engines/index.md b/doc/architecture/blueprints/composable_codebase_using_rails_engines/index.md
index 82529a4c199..5f0f0a7aa63 100644
--- a/doc/architecture/blueprints/composable_codebase_using_rails_engines/index.md
+++ b/doc/architecture/blueprints/composable_codebase_using_rails_engines/index.md
@@ -383,7 +383,7 @@ What was done?
```ruby
# config/engines.rb
# Load only in case we are running web_server or rails console
- if Gitlab::Runtime.web_server? || Gitlab::Runtime.console?
+ if Gitlab::Runtime.puma? || Gitlab::Runtime.console?
require 'web_engine'
end
```
diff --git a/doc/architecture/blueprints/consolidating_groups_and_projects/index.md b/doc/architecture/blueprints/consolidating_groups_and_projects/index.md
index 6040ac1e50f..52e9b48419c 100644
--- a/doc/architecture/blueprints/consolidating_groups_and_projects/index.md
+++ b/doc/architecture/blueprints/consolidating_groups_and_projects/index.md
@@ -173,4 +173,4 @@ DRIs:
## Related topics
-- [Workspaces developer documentation](../../../development/workspaces/index.md)
+- [Workspace developer documentation](../../../development/workspace/index.md)
diff --git a/doc/architecture/blueprints/container_registry_metadata_database/index.md b/doc/architecture/blueprints/container_registry_metadata_database/index.md
index c1aac235085..ba0bee04f35 100644
--- a/doc/architecture/blueprints/container_registry_metadata_database/index.md
+++ b/doc/architecture/blueprints/container_registry_metadata_database/index.md
@@ -1,7 +1,7 @@
---
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
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
comments: false
description: 'Container Registry metadata database'
---
diff --git a/doc/architecture/blueprints/gitlab_to_kubernetes_communication/index.md b/doc/architecture/blueprints/gitlab_to_kubernetes_communication/index.md
index 754988487de..b22636ac1d9 100644
--- a/doc/architecture/blueprints/gitlab_to_kubernetes_communication/index.md
+++ b/doc/architecture/blueprints/gitlab_to_kubernetes_communication/index.md
@@ -1,7 +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
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
comments: false
description: 'GitLab to Kubernetes communication'
---
@@ -9,7 +9,7 @@ description: 'GitLab to Kubernetes communication'
# GitLab to Kubernetes communication **(FREE)**
The goal of this document is to define how GitLab can communicate with Kubernetes
-and in-cluster services through the GitLab Agent.
+and in-cluster services through the GitLab agent.
## Challenges
@@ -48,7 +48,7 @@ are stored on the GitLab side and this is yet another security concern for our c
For more discussion on these issues, read
[issue #212810](https://gitlab.com/gitlab-org/gitlab/-/issues/212810).
-## GitLab Agent epic
+## GitLab agent epic
To address these challenges and provide some new features, the Configure group
is building an active in-cluster component that inverts the
@@ -62,12 +62,12 @@ The customer does not need to provide any credentials to GitLab, and
is in full control of what permissions the agent has.
For more information, visit the
-[GitLab Agent repository](https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent) or
+[GitLab agent repository](https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent) or
[the epic](https://gitlab.com/groups/gitlab-org/-/epics/3329).
### Request routing
-Agents connect to the server-side component called GitLab Agent Server
+Agents connect to the server-side component called GitLab agent server
(`gitlab-kas`) and keep an open connection that waits for commands. The
difficulty with the approach is in routing requests from GitLab to the correct agent.
Each cluster may contain multiple logical agents, and each may be running as multiple
diff --git a/doc/architecture/blueprints/object_storage/index.md b/doc/architecture/blueprints/object_storage/index.md
index 7864c951eca..3420caa325f 100644
--- a/doc/architecture/blueprints/object_storage/index.md
+++ b/doc/architecture/blueprints/object_storage/index.md
@@ -196,7 +196,7 @@ require one bucket.
## Additional reading materials
-- [Uploads development documentation: The problem description](../../../development/uploads.md#the-problem-description).
+- [Uploads development guide](../../../development/uploads/index.md).
- [Speed up the monolith, building a smart reverse proxy in Go](https://archive.fosdem.org/2020/schedule/event/speedupmonolith/): a presentation explaining a bit of workhorse history and the challenge we faced in releasing the first cloud-native installation.
- [Object Storage improvements epic](https://gitlab.com/groups/gitlab-org/-/epics/483).
- We are moving to GraphQL API, but [we do not support direct upload](https://gitlab.com/gitlab-org/gitlab/-/issues/280819).
diff --git a/doc/architecture/blueprints/runner_scaling/gitlab-autoscaling-overview.png b/doc/architecture/blueprints/runner_scaling/gitlab-autoscaling-overview.png
index c3ba615784f..2c8c753cddd 100644
--- a/doc/architecture/blueprints/runner_scaling/gitlab-autoscaling-overview.png
+++ b/doc/architecture/blueprints/runner_scaling/gitlab-autoscaling-overview.png
Binary files differ
diff --git a/doc/ci/cloud_deployment/ecs/quick_start_guide.md b/doc/ci/cloud_deployment/ecs/quick_start_guide.md
index 9cf9d2a1f06..5571c51ef27 100644
--- a/doc/ci/cloud_deployment/ecs/quick_start_guide.md
+++ b/doc/ci/cloud_deployment/ecs/quick_start_guide.md
@@ -40,10 +40,10 @@ For the first step here, you create a demo application from a project template.
Use a GitLab project template to get started. As the name suggests, these projects provide a
bare-bones application built on some well-known frameworks.
-1. In GitLab, click the plus icon (**{plus-square}**) at the top of the navigation bar, and select
+1. In GitLab, select the plus icon (**{plus-square}**) at the top of the navigation bar, and select
**New project**.
-1. Click the **Create from template** button, where you can choose from a Ruby on Rails, Spring, or
+1. Select **Create from template**, where you can choose from a Ruby on Rails, Spring, or
NodeJS Express project. For this guide, use the Ruby on Rails template.
![Select project template](img/rails-template.png)
@@ -52,7 +52,7 @@ bare-bones application built on some well-known frameworks.
take advantage of the features available in the
[GitLab Ultimate plan](https://about.gitlab.com/pricing/).
-1. Click **Create project**.
+1. Select **Create project**.
Now that you created a demo project, you must containerize the application and push it to the
container registry.
@@ -65,7 +65,7 @@ GitLab [Auto Build](../../../topics/autodevops/stages.md#auto-build)
and [Container Registry](../../../user/packages/container_registry/index.md).
1. Go to **ecs-demo** project on GitLab.
-1. Click **Setup up CI/CD**. It brings you to a `.gitlab-ci.yml`
+1. Select **Setup up CI/CD**. It brings you to a `.gitlab-ci.yml`
creation form.
1. Copy and paste the following content into the empty `.gitlab-ci.yml`. This defines
[a pipeline for continuous deployment to ECS](../index.md#deploy-your-application-to-the-aws-elastic-container-service-ecs).
@@ -75,7 +75,7 @@ and [Container Registry](../../../user/packages/container_registry/index.md).
- template: AWS/Deploy-ECS.gitlab-ci.yml
```
-1. Click **Commit Changes**. It automatically triggers a new pipeline. In this pipeline, the `build`
+1. Select **Commit Changes**. It automatically triggers a new pipeline. In this pipeline, the `build`
job containerizes the application and pushes the image to [GitLab Container Registry](../../../user/packages/container_registry/index.md).
![Create project](img/initial-pipeline.png)
@@ -97,14 +97,14 @@ later.
is a specification about how the application image is started by an [ECS service](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs_services.html).
1. Go to **ECS > Task Definitions** on [AWS console](https://aws.amazon.com/).
-1. Click **Create new Task Definition**.
+1. Select **Create new Task Definition**.
![Create project](img/ecs-task-definitions.png)
-1. Choose **EC2** as the launch type. Click **Next Step**.
+1. Choose **EC2** as the launch type. Select **Next Step**.
1. Set `ecs_demo` to **Task Definition Name**.
1. Set `512` to **Task Size > Task memory** and **Task CPU**.
-1. Click **Container Definitions > Add container**. This opens a container registration form.
+1. Select **Container Definitions > Add container**. This opens a container registration form.
1. Set `web` to **Container name**.
1. Set `registry.gitlab.com/<your-namespace>/ecs-demo/master:latest` to **Image**.
Alternatively, you can copy and paste the image path from the [GitLab Container Registry page](#push-a-containerized-application-image-to-gitlab-container-registry).
@@ -115,7 +115,7 @@ is a specification about how the application image is started by an [ECS service
![Create project](img/container-port-mapping.png)
-1. Click **Create**.
+1. Select **Create**.
Now you have the initial task definition. Next, you create an actual infrastructure to run the
application image.
@@ -127,13 +127,13 @@ is a virtual group of [ECS services](https://docs.aws.amazon.com/AmazonECS/lates
It's also associated with EC2 or Fargate as the computation resource.
1. Go to **ECS > Clusters** on [AWS console](https://aws.amazon.com/).
-1. Click **Create Cluster**.
-1. Select **EC2 Linux + Networking** as the cluster template. Click **Next Step**.
+1. Select **Create Cluster**.
+1. Select **EC2 Linux + Networking** as the cluster template. Select **Next Step**.
1. Set `ecs-demo` to **Cluster Name**.
1. Choose the default [VPC](https://aws.amazon.com/vpc/?vpc-blogs.sort-by=item.additionalFields.createdDate&vpc-blogs.sort-order=desc)
in **Networking**. If there are no existing VPCs, you can leave it as-is to create a new one.
1. Set all available subnets of the VPC to **Subnets**.
-1. Click **Create**.
+1. Select **Create**.
1. Make sure that the ECS cluster has been successfully created.
![Create project](img/ecs-launch-status.png)
@@ -154,7 +154,7 @@ Note the following:
is a daemon to create an application container based on the [ECS task definition](#create-an-ecs-task-definition).
1. Go to **ECS > Clusters > ecs-demo > Services** on the [AWS console](https://aws.amazon.com/)
-1. Click **Deploy**. This opens a service creation form.
+1. Select **Deploy**. This opens a service creation form.
1. Select `EC2` in **Launch Type**.
1. Set `ecs_demo` to **Task definition**. This corresponds to [the task definition you created above](#create-an-ecs-task-definition).
1. Set `ecs_demo` to **Service name**.
@@ -162,7 +162,7 @@ is a daemon to create an application container based on the [ECS task definition
![Create project](img/service-parameter.png)
-1. Click **Deploy**.
+1. Select **Deploy**.
1. Make sure that the created service is active.
![Create project](img/service-running.png)
@@ -176,7 +176,7 @@ Now, the demo application is accessible from the internet.
1. Go to **EC2 > Instances** on the [AWS console](https://aws.amazon.com/)
1. Search by `ECS Instance` to find the corresponding EC2 instance that [the ECS cluster created](#create-an-ecs-cluster).
-1. Click the ID of the EC2 instance. This brings you to the instance detail page.
+1. Select the ID of the EC2 instance. This brings you to the instance detail page.
1. Copy **Public IPv4 address** and paste it in the browser. Now you can see the demo application
running.
@@ -195,15 +195,15 @@ For GitLab to access the ECS cluster, service, and task definition that you crea
create a deployer user on AWS:
1. Go to **IAM > Users** on [AWS console](https://aws.amazon.com/).
-1. Click **Add user**.
+1. Select **Add user**.
1. Set `ecs_demo` to **User name**.
-1. Enable **Programmatic access** checkbox. Click **Next: Permissions**.
+1. Enable **Programmatic access** checkbox. Select **Next: Permissions**.
1. Select `Attach existing policies directly` in **Set permissions**.
-1. Select `AmazonECS_FullAccess` from the policy list. Click **Next: Tags** and **Next: Review**.
+1. Select `AmazonECS_FullAccess` from the policy list. Select **Next: Tags** and **Next: Review**.
![Create project](img/ecs-policy.png)
-1. Click **Create user**.
+1. Select **Create user**.
1. Take note of the **Access key ID** and **Secret access key** of the created user.
NOTE:
@@ -216,7 +216,7 @@ These variables are injected into the pipeline jobs and can access the ECS API.
1. Go to **ecs-demo** project on GitLab.
1. Go to **Settings > CI/CD > Variables**.
-1. Click **Add Variable** and set the following key-value pairs.
+1. Select **Add Variable** and set the following key-value pairs.
|Key|Value|Note|
|---|---|---|
@@ -233,9 +233,9 @@ Change a file in the project and see if it's reflected in the demo application o
1. Go to **ecs-demo** project on GitLab.
1. Open the file at **app > views > welcome > `index.html.erb`**.
-1. Click **Edit**.
+1. Select **Edit**.
1. Change the text to `You're on ECS!`.
-1. Click **Commit Changes**. This automatically triggers a new pipeline. Wait until it finishes.
+1. Select **Commit Changes**. This automatically triggers a new pipeline. Wait until it finishes.
1. [Access the running application on the ECS cluster](#view-the-demo-application). You should see
this:
diff --git a/doc/ci/cloud_services/index.md b/doc/ci/cloud_services/index.md
index a80231a04c2..1493a930099 100644
--- a/doc/ci/cloud_services/index.md
+++ b/doc/ci/cloud_services/index.md
@@ -18,6 +18,13 @@ GitLab CI/CD supports [OpenID Connect (OIDC)](https://openid.net/connect/faq/) t
The original implementation of `CI_JOB_JWT` supports [HashiCorp Vault integration](../examples/authenticating-with-hashicorp-vault/). The updated implementation of `CI_JOB_JWT_V2` supports additional cloud providers with OIDC including AWS, GCP, and Vault.
+NOTE:
+Configuring OIDC enables JWT token access to the target environments for all pipelines.
+When you configure OIDC for a pipeline, you should complete a software supply chain security
+review for the pipeline, focusing on the additional access. You can use the [software supply chain security awareness assessment](https://about.gitlab.com/quiz/software-supply-chain-security/)
+as a starting point, and for more information about supply chain attacks, see
+[How a DevOps Platform helps protect against supply chain attacks](https://about.gitlab.com/blog/2021/04/28/devops-platform-supply-chain-attacks/).
+
WARNING:
The `CI_JOB_JWT_V2` variable is under development [(alpha)](../../policy/alpha-beta-support.md#alpha-features) and is not yet suitable for production use.
diff --git a/doc/ci/directed_acyclic_graph/index.md b/doc/ci/directed_acyclic_graph/index.md
index abf43390834..5d0aaf7cc45 100644
--- a/doc/ci/directed_acyclic_graph/index.md
+++ b/doc/ci/directed_acyclic_graph/index.md
@@ -81,7 +81,7 @@ are certain use cases that you may need to work around. For more information, ch
## Needs 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).
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/215517) in GitLab 13.1 as a [Beta feature](../../policy/alpha-beta-support.md#beta-features).
> - It became a [standard feature](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/38517) in 13.3.
> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/52208) in GitLab 13.9.
diff --git a/doc/ci/environments/deployment_approvals.md b/doc/ci/environments/deployment_approvals.md
index e320118c191..45af78aa036 100644
--- a/doc/ci/environments/deployment_approvals.md
+++ b/doc/ci/environments/deployment_approvals.md
@@ -11,7 +11,7 @@ description: Require approvals prior to deploying to a Protected Environment
> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/347342) in GitLab 14.8.
WARNING:
-This feature is in an alpha stage and subject to change without prior notice.
+This feature is in a [Beta](../../policy/alpha-beta-support.md#beta-features) stage and subject to change without prior notice.
It may be useful to require additional approvals before deploying to certain protected environments (for example, production). This pre-deployment approval requirement is useful to accommodate testing, security, or compliance processes that must happen before each deployment.
@@ -79,30 +79,53 @@ Maintainer role.
## Approve or reject a deployment
-NOTE:
-This functionality is currently only available through the API. UI is planned for the near future. See [issue](https://gitlab.com/gitlab-org/gitlab/-/issues/342180/).
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/342180/) in GitLab 14.9
+
+Using either the GitLab UI or the API, you can:
+
+- Approve a deployment to allow it to proceed.
+- Reject a deployment to prevent it.
+
+### Approve or reject a deployment using the UI
+
+Prerequisites:
+
+- Permission to deploy to the protected environment.
+
+To approve or reject a deployment to a protected environment using the UI:
+
+1. On the top bar, select **Menu > Projects** and find your project.
+1. On the left sidebar, select **Deployments > Environments**.
+1. In the deployment's row, select **Approval options** (**{thumb-up}**).
+1. Select **Approve** or **Reject**.
+
+### Approve or reject a deployment using the API
+
+Prerequisites:
-A blocked deployment is enqueued as soon as it receives the required number of approvals. A single rejection causes the deployment to fail. The creator of a deployment cannot approve it, even if they have permission to deploy.
+- Permission to deploy to the protected environment.
-Using the [Deployments API](../../api/deployments.md#approve-or-reject-a-blocked-deployment), users who are allowed to deploy to the protected environment can approve or reject a blocked deployment.
+To approve or reject a deployment to a protected environment using the API, pass the
+required attributes. For more details, see
+[Approve or reject a blocked deployment](../../api/deployments.md#approve-or-reject-a-blocked-deployment).
Example:
```shell
-curl --data "status=approved" \
+curl --data "status=approved&comment=Looks good to me" \
--header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/deployments/1/approval"
```
-### How to see blocked deployments
+## How to see blocked deployments
-#### Using the UI
+### Using the UI
1. On the top bar, select **Menu > Projects** and find your project.
1. On the left sidebar, select **Deployments > Environments**.
1. Select the environment being deployed to.
1. Look for the `blocked` label.
-#### Using the API
+### Using the API
Use the [Deployments API](../../api/deployments.md) to see deployments.
diff --git a/doc/ci/environments/img/environments_list_v14_3.png b/doc/ci/environments/img/environments_list_v14_3.png
deleted file mode 100644
index 8fdb85338e7..00000000000
--- a/doc/ci/environments/img/environments_list_v14_3.png
+++ /dev/null
Binary files differ
diff --git a/doc/ci/environments/img/environments_list_v14_8.png b/doc/ci/environments/img/environments_list_v14_8.png
new file mode 100644
index 00000000000..df439fb96dc
--- /dev/null
+++ b/doc/ci/environments/img/environments_list_v14_8.png
Binary files differ
diff --git a/doc/ci/environments/index.md b/doc/ci/environments/index.md
index 63bdd279927..c2612b6ff16 100644
--- a/doc/ci/environments/index.md
+++ b/doc/ci/environments/index.md
@@ -35,7 +35,7 @@ To view a list of environments and deployments:
1. On the left sidebar, select **Deployments > Environments**.
The environments are displayed.
- ![Environments list](img/environments_list_v14_3.png)
+ ![Environments list](img/environments_list_v14_8.png)
1. To view a list of deployments for an environment, select the environment name,
for example, `staging`.
@@ -440,7 +440,7 @@ stop_review:
when: manual
```
-Both jobs must have the same [`rules`](../yaml/index.md#only--except)
+Both jobs must have the same [`rules`](../yaml/index.md#rules)
or [`only/except`](../yaml/index.md#only--except) configuration. Otherwise,
the `stop_review` job might not be included in all pipelines that include the
`deploy_review` job, and you cannot trigger `action: stop` to stop the environment automatically.
diff --git a/doc/ci/environments/protected_environments.md b/doc/ci/environments/protected_environments.md
index c7d1653aace..adc215c7aa1 100644
--- a/doc/ci/environments/protected_environments.md
+++ b/doc/ci/environments/protected_environments.md
@@ -163,9 +163,8 @@ For more information, see [Deployment safety](deployment_safety.md).
Typically, large enterprise organizations have an explicit permission boundary
between [developers and operators](https://about.gitlab.com/topics/devops/).
Developers build and test their code, and operators deploy and monitor the
-application. With group-level protected environments, the permission of each
-group is carefully configured in order to prevent unauthorized access and
-maintain proper separation of duty. Group-level protected environments
+application. With group-level protected environments, operators can
+restrict access to critical environments from developers. Group-level protected environments
extend the [project-level protected environments](#protecting-environments)
to the group-level.
@@ -194,12 +193,6 @@ and are protected at the same time.
### Configure group-level memberships
-In an enterprise organization, with thousands of projects under a single group,
-ensuring that all of the [project-level protected environments](#protecting-environments)
-are properly configured is not a scalable solution. For example, a developer
-might gain privileged access to a higher environment when they are given the Maintainer role
-for a new project. Group-level protected environments can be a solution in this situation.
-
To maximize the effectiveness of group-level protected environments,
[group-level memberships](../../user/group/index.md) must be correctly
configured:
@@ -237,7 +230,7 @@ Having this configuration in place:
- If a user is about to run a deployment job in a project but disallowed to
deploy to the environment, the deployment job fails with an error message.
-### Protect a group-level environment
+### Protect critical environments under a group
To protect a group-level environment:
diff --git a/doc/ci/examples/authenticating-with-hashicorp-vault/index.md b/doc/ci/examples/authenticating-with-hashicorp-vault/index.md
index edc58684057..5fca3513ff7 100644
--- a/doc/ci/examples/authenticating-with-hashicorp-vault/index.md
+++ b/doc/ci/examples/authenticating-with-hashicorp-vault/index.md
@@ -121,8 +121,8 @@ Then create policies that allow you to read these secrets (one for each secret):
$ vault policy write myproject-staging - <<EOF
# Policy name: myproject-staging
#
-# Read-only permission on 'secret/data/myproject/staging/*' path
-path "secret/data/myproject/staging/*" {
+# Read-only permission on 'secret/myproject/staging/*' path
+path "secret/myproject/staging/*" {
capabilities = [ "read" ]
}
EOF
@@ -131,8 +131,8 @@ Success! Uploaded policy: myproject-staging
$ vault policy write myproject-production - <<EOF
# Policy name: myproject-production
#
-# Read-only permission on 'secret/data/myproject/production/*' path
-path "secret/data/myproject/production/*" {
+# Read-only permission on 'secret/myproject/production/*' path
+path "secret/myproject/production/*" {
capabilities = [ "read" ]
}
EOF
diff --git a/doc/ci/jobs/ci_job_token.md b/doc/ci/jobs/ci_job_token.md
index a62f670cb12..b0002f559ba 100644
--- a/doc/ci/jobs/ci_job_token.md
+++ b/doc/ci/jobs/ci_job_token.md
@@ -23,6 +23,12 @@ You can use a GitLab CI/CD job token to authenticate with specific API endpoints
- [Releases](../../api/releases/index.md).
- [Terraform plan](../../user/infrastructure/index.md).
+NOTE:
+There's an open issue,
+[GitLab-#333444](https://gitlab.com/gitlab-org/gitlab/-/issues/333444),
+which prevents you from using a job token with internal projects. This bug only impacts self-managed
+GitLab instances.
+
The token has the same permissions to access the API as the user that caused the
job to run. A user can cause a job to run by pushing a commit, triggering a manual job,
being the owner of a scheduled pipeline, and so on. Therefore, this user must be assigned to
diff --git a/doc/ci/jobs/index.md b/doc/ci/jobs/index.md
index 39e14d0d20a..4fa251eb3cf 100644
--- a/doc/ci/jobs/index.md
+++ b/doc/ci/jobs/index.md
@@ -103,6 +103,9 @@ Job names must be 255 characters or less. [Introduced](https://gitlab.com/gitlab
in GitLab 14.5, [with a feature flag](../../administration/feature_flags.md) named `ci_validate_job_length`.
Enabled by default. To disable it, ask an administrator to [disable the feature flag](../../administration/feature_flags.md).
+Use unique names for your jobs. If multiple jobs have the same name,
+only one is added to the pipeline, and it's difficult to predict which one is chosen.
+
## Group jobs in a pipeline
If you have many similar jobs, your [pipeline graph](../pipelines/index.md#visualize-pipelines) becomes long and hard
diff --git a/doc/ci/jobs/job_control.md b/doc/ci/jobs/job_control.md
index 6523de0ed1e..3a302cf352b 100644
--- a/doc/ci/jobs/job_control.md
+++ b/doc/ci/jobs/job_control.md
@@ -85,6 +85,28 @@ be triggered by the same event (a push to the source branch for an open merge re
See how to [prevent duplicate pipelines](#avoid-duplicate-pipelines)
for more details.
+#### Run jobs for scheduled pipelines
+
+To configure a job to be executed only when the pipeline has been
+scheduled, use the [`rules`](../yaml/index.md#rules) keyword.
+
+In this example, `make world` runs in scheduled pipelines, and `make build`
+runs in branch and tag pipelines:
+
+```yaml
+job:on-schedule:
+ rules:
+ - if: $CI_PIPELINE_SOURCE == "schedule"
+ script:
+ - make world
+
+job:
+ rules:
+ - if: $CI_PIPELINE_SOURCE == "push"
+ script:
+ - make build
+```
+
### Complex rules
You can use all `rules` keywords, like `if`, `changes`, and `exists`, in the same
@@ -115,7 +137,7 @@ job1:
script:
- echo This rule uses parentheses.
rules:
- if: ($CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH == "develop") && $MY_VARIABLE
+ - if: ($CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH == "develop") && $MY_VARIABLE
```
WARNING:
@@ -727,6 +749,38 @@ deploystacks:
- ${PROVIDER}-${STACK}
```
+#### Fetch artifacts from a `parallel:matrix` job
+
+You can fetch artifacts from a job created with [`parallel:matrix`](../yaml/index.md#parallelmatrix)
+by using the [`dependencies`](../yaml/index.md#dependencies) keyword. Use the job name
+as the value for `dependencies` as a string in the form:
+
+```plaintext
+<job_name> [<matrix argument 1>, <matrix argument 2>, ... <matrix argument N>]
+```
+
+For example, to fetch the artifacts from the job with a `RUBY_VERSION` of `2.7` and
+a `PROVIDER` of `aws`:
+
+```yaml
+ruby:
+ image: ruby:${RUBY_VERSION}
+ parallel:
+ matrix:
+ - RUBY_VERSION: ["2.5", "2.6", "2.7", "3.0", "3.1"]
+ PROVIDER: [aws, gcp]
+ script: bundle install
+
+deploy:
+ image: ruby:2.7
+ stage: deploy
+ dependencies:
+ - "ruby: [2.7, aws]"
+ script: echo hello
+```
+
+Quotes around the `dependencies` entry are required.
+
## Use predefined CI/CD variables to run jobs only in specific pipeline types
You can use [predefined CI/CD variables](../variables/predefined_variables.md) to choose
@@ -812,13 +866,9 @@ due to computational complexity, and some features, like negative lookaheads, be
Only a subset of features provided by [Ruby Regexp](https://ruby-doc.org/core/Regexp.html)
are now supported.
-From GitLab 11.9.7 to GitLab 12.0, GitLab provided a feature flag to
-let you use unsafe regexp syntax. After migrating to safe syntax, you should disable
-this feature flag again:
-
-```ruby
-Feature.enable(:allow_unsafe_ruby_regexp)
-```
+From GitLab 11.9.7 to GitLab 14.9, GitLab provided a feature flag to let you
+use unsafe regexp syntax. We've fully migrated to RE2 now, and that feature
+flag is no longer available.
## CI/CD variable expressions
diff --git a/doc/ci/lint.md b/doc/ci/lint.md
index c0df0b2a439..256e669a66e 100644
--- a/doc/ci/lint.md
+++ b/doc/ci/lint.md
@@ -25,9 +25,8 @@ configuration added with the [`includes` keyword](yaml/index.md#include).
To check CI/CD configuration with the CI lint tool:
1. On the top bar, select **Menu > Projects** and find your project.
-1. On the left sidebar, select one of:
+1. On the left sidebar, select:
- **CI/CD > Pipelines**
- - **CI/CD > Jobs**
1. In the top right, select **CI lint**.
1. Paste a copy of the CI/CD configuration you want to check into the text box.
1. Select **Validate**.
@@ -48,9 +47,8 @@ Prerequisites:
To simulate a pipeline:
1. On the top bar, select **Menu > Projects** and find your project.
-1. On the left sidebar, select one of:
+1. On the left sidebar, select:
- **CI/CD > Pipelines**
- - **CI/CD > Jobs**
1. In the top right, select **CI lint**.
1. Paste a copy of the CI/CD configuration you want to check into the text box.
1. Select **Simulate pipeline creation for the default branch**.
diff --git a/doc/ci/metrics_reports.md b/doc/ci/metrics_reports.md
index 5b472eec7b5..542d55665c7 100644
--- a/doc/ci/metrics_reports.md
+++ b/doc/ci/metrics_reports.md
@@ -55,3 +55,14 @@ An advanced example of an OpenMetrics text file (from the [Prometheus documentat
renders in the merge request widget as:
![Metrics Reports Advanced](img/metrics_reports_advanced_v13_0.png)
+
+## Troubleshooting
+
+### Metrics reports did not change
+
+You can see `Metrics reports did not change` when trying to view metrics reports in merge requests. Reasons for this are:
+
+- The target branch for the merge request doesn't have a baseline metrics report for comparison.
+- You don't have GitLab license at the Premium tier or above.
+
+There is [an issue open](https://gitlab.com/gitlab-org/gitlab/-/issues/343065) to improve this message.
diff --git a/doc/ci/migration/circleci.md b/doc/ci/migration/circleci.md
index efaae873588..d95199a70d0 100644
--- a/doc/ci/migration/circleci.md
+++ b/doc/ci/migration/circleci.md
@@ -169,7 +169,7 @@ job1:
- 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.
+After the pipeline configuration is saved, you configure the cron schedule in the [GitLab UI](../pipelines/schedules.md#add-a-pipeline-schedule), and can enable or disable schedules in the UI as well.
#### Manual run
diff --git a/doc/ci/pipelines/cicd_minutes.md b/doc/ci/pipelines/cicd_minutes.md
index 8b10a74bd78..f9d9a4f738b 100644
--- a/doc/ci/pipelines/cicd_minutes.md
+++ b/doc/ci/pipelines/cicd_minutes.md
@@ -223,3 +223,25 @@ On GitLab SaaS an email notification is sent to the namespace owners when:
- The available CI/CD minutes are below 30% of the quota.
- The available CI/CD minutes are below 5% of the quota.
- All CI/CD minutes have been used.
+
+## Reduce consumption of CI/CD minutes
+
+If your project consumes too many CI/CD minutes, there are some strategies you can
+use to reduce your CI/CD minutes usage:
+
+- If you are using project mirrors, ensure that [pipelines for mirror updates](../../user/project/repository/mirror/pull.md#trigger-pipelines-for-mirror-updates)
+ is disabled.
+- Reduce the frequency of [scheduled pipelines](schedules.md).
+- [Skip pipelines](index.md#skip-a-pipeline) when not needed.
+- Use [interruptible](../yaml/index.md#interruptible) jobs which can be auto-canceled
+ if a new pipeline starts.
+- If a job doesn't have to run in every pipeline, use [`rules`](../jobs/job_control.md)
+ to make it only run when it's needed.
+- [Use private runners](../runners/runners_scope.md#group-runners) for some jobs.
+- If you are working from a fork and you submit a merge request to the parent project,
+ you can ask a maintainer to run a pipeline [in the parent project](merge_request_pipelines.md#run-pipelines-in-the-parent-project).
+
+If you manage an open source project, these improvements can also reduce CI/CD minutes
+consumption for contributor fork projects, enabling more contributions.
+
+See our [pipeline efficiency guide](pipeline_efficiency.md) for more details.
diff --git a/doc/ci/pipelines/img/pipeline_schedule_play.png b/doc/ci/pipelines/img/pipeline_schedule_play.png
deleted file mode 100644
index ec6eb0d156b..00000000000
--- a/doc/ci/pipelines/img/pipeline_schedule_play.png
+++ /dev/null
Binary files differ
diff --git a/doc/ci/pipelines/img/pipeline_schedule_variables.png b/doc/ci/pipelines/img/pipeline_schedule_variables.png
deleted file mode 100644
index ce3c3dc6af1..00000000000
--- a/doc/ci/pipelines/img/pipeline_schedule_variables.png
+++ /dev/null
Binary files differ
diff --git a/doc/ci/pipelines/img/pipeline_schedules_list.png b/doc/ci/pipelines/img/pipeline_schedules_list.png
deleted file mode 100644
index 541fe4f9b1d..00000000000
--- a/doc/ci/pipelines/img/pipeline_schedules_list.png
+++ /dev/null
Binary files differ
diff --git a/doc/ci/pipelines/img/pipeline_schedules_new_form.png b/doc/ci/pipelines/img/pipeline_schedules_new_form.png
deleted file mode 100644
index 993fbf8ca00..00000000000
--- a/doc/ci/pipelines/img/pipeline_schedules_new_form.png
+++ /dev/null
Binary files differ
diff --git a/doc/ci/pipelines/img/pipeline_schedules_ownership.png b/doc/ci/pipelines/img/pipeline_schedules_ownership.png
deleted file mode 100644
index 8fc5c5fbc82..00000000000
--- a/doc/ci/pipelines/img/pipeline_schedules_ownership.png
+++ /dev/null
Binary files differ
diff --git a/doc/ci/pipelines/index.md b/doc/ci/pipelines/index.md
index 5a5fd2b5540..4d1af735b13 100644
--- a/doc/ci/pipelines/index.md
+++ b/doc/ci/pipelines/index.md
@@ -140,7 +140,7 @@ to its **Pipelines** tab.
![Pipelines index page](img/pipelines_index_v13_0.png)
-Click a pipeline to open the **Pipeline Details** page and show
+Select a pipeline to open 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).
@@ -246,7 +246,7 @@ For each `var` or `file_var`, a key and value are required.
[Manual jobs](../jobs/job_control.md#create-a-job-that-must-be-run-manually),
allow you to require manual interaction before moving forward in the pipeline.
-You can do this straight from the pipeline graph. Just click the play button
+You can do this straight from the pipeline graph. Just select the play button
to execute that particular job.
For example, your pipeline can start automatically, but require a manual action to
@@ -259,8 +259,8 @@ In the example below, the `production` stage has a job with a manual action:
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/27188) in GitLab 11.11.
-Multiple manual actions in a single stage can be started at the same time using the "Play all manual" button.
-After you click this button, each individual manual action is triggered and refreshed
+Multiple manual actions in a single stage can be started at the same time using the "Play all manual"
+After you select this action, each individual manual action is triggered and refreshed
to an updated status.
This functionality is only available:
@@ -283,9 +283,9 @@ pipelines.
Users with the Owner role for a project can delete a pipeline
by clicking on the pipeline in the **CI/CD > Pipelines** to get to the **Pipeline Details**
-page, then using the **Delete** button.
+page, then selecting **Delete**.
-![Pipeline Delete Button](img/pipeline-delete.png)
+![Pipeline Delete](img/pipeline-delete.png)
WARNING:
Deleting a pipeline expires all pipeline caches, and deletes all related objects,
@@ -314,7 +314,7 @@ sensitive information like deployment credentials and tokens.
**Runners** marked as **protected** can run jobs only on protected
branches, preventing untrusted code from executing on the protected runner and
preserving deployment keys and other credentials from being unintentionally
-accessed. In order to ensure that jobs intended to be executed on protected
+accessed. To ensure that jobs intended to be executed on protected
runners do not use regular runners, they must be tagged accordingly.
### How pipeline duration is calculated
@@ -385,6 +385,12 @@ You can group the jobs by:
[Multi-project pipeline graphs](multi_project_pipelines.md#multi-project-pipeline-visualization) help
you visualize the entire pipeline, including all cross-project inter-dependencies. **(PREMIUM)**
+If a stage contains more than 100 jobs, only the first 100 jobs are listed in the
+pipeline graph. The remaining jobs still run as normal. To see the jobs:
+
+- Select the pipeline, and the jobs are listed on the right side of the pipeline details page.
+- On the left sidebar, select **CI/CD > Jobs**.
+
### View job dependencies in the pipeline graph
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/298973) in GitLab 13.12.
@@ -428,7 +434,7 @@ fix it.
Pipeline mini graphs only display jobs by stage.
-Stages in pipeline mini graphs are collapsible. Hover your mouse over them and click to expand their jobs.
+Stages in pipeline mini graphs are expandable. Hover your mouse over each stage to see the name and status, and select a stage to expand its jobs list.
| Mini graph | Mini graph expanded |
|:-------------------------------------------------------------|:---------------------------------------------------------------|
diff --git a/doc/ci/pipelines/merge_request_pipelines.md b/doc/ci/pipelines/merge_request_pipelines.md
index dcc3e7e6919..d80b745e6bc 100644
--- a/doc/ci/pipelines/merge_request_pipelines.md
+++ b/doc/ci/pipelines/merge_request_pipelines.md
@@ -41,8 +41,10 @@ Both of these types of pipelines can appear on the **Pipelines** tab of a merge
The three types of merge request pipelines are:
- Merge request pipelines, which run on the changes in the merge request's
- source branch. These pipelines display a `detached` label to indicate that the
+ source branch. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/352939)
+ in GitLab 14.9, these pipelines display a `merge request` label to indicate that the
pipeline ran only on the contents of the source branch, ignoring the target branch.
+ In GitLab 14.8 and earlier, the label is `detached`.
- [Merged results pipelines](merged_results_pipelines.md), which run on
the result of combining the source branch's changes with the target branch.
- [Merge trains](merge_trains.md), which run when merging multiple merge requests
diff --git a/doc/ci/pipelines/merge_trains.md b/doc/ci/pipelines/merge_trains.md
index ffcce06cfbd..12ea3a70536 100644
--- a/doc/ci/pipelines/merge_trains.md
+++ b/doc/ci/pipelines/merge_trains.md
@@ -201,6 +201,10 @@ the merged result is out of date and the pipeline can't be retried.
Instead, you should [add the merge request to the train](#add-a-merge-request-to-a-merge-train)
again, which triggers a new pipeline.
+If a job only fails intermittently, you can try using the [`retry`](../yaml/index.md#retry)
+keyword in the `.gitlab-ci.yml` file to have the job retried before the pipeline completes.
+If it succeeds after a retry, the merge request is not removed from the merge train.
+
### Unable to add to merge train with message "The pipeline for this merge request failed."
Sometimes the **Start/Add to merge train** button is not available and the merge request says,
diff --git a/doc/ci/pipelines/merged_results_pipelines.md b/doc/ci/pipelines/merged_results_pipelines.md
index 4794107cc87..7df9ea3f72f 100644
--- a/doc/ci/pipelines/merged_results_pipelines.md
+++ b/doc/ci/pipelines/merged_results_pipelines.md
@@ -24,7 +24,7 @@ Merged results pipelines can't run when:
- The merge request is a [**Draft** merge request](../../user/project/merge_requests/drafts.md).
In these cases, the pipeline runs as a [merge request pipeline](merge_request_pipelines.md)
-and is labeled as `detached`.
+and [is labeled as `merge request`](merge_request_pipelines.md#types-of-merge-request-pipelines).
## Prerequisites
diff --git a/doc/ci/pipelines/pipelines_for_merged_results.md b/doc/ci/pipelines/pipelines_for_merged_results.md
index 457f5ce9c30..0c3100a51f1 100644
--- a/doc/ci/pipelines/pipelines_for_merged_results.md
+++ b/doc/ci/pipelines/pipelines_for_merged_results.md
@@ -6,4 +6,6 @@ remove_date: '2022-04-27'
This document was moved to [another location](merged_results_pipelines.md).
<!-- This redirect file can be deleted after 2022-04-27. -->
-<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/#move-or-rename-a-page -->
+<!-- Redirects that point to other docs in the same project expire in three months. -->
+<!-- Redirects that point to docs in a different project or site (for example, link is not relative and starts with `https:`) expire in one year. -->
+<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/redirects.html -->
diff --git a/doc/ci/pipelines/schedules.md b/doc/ci/pipelines/schedules.md
index fe9db3306cd..8813f3e1d59 100644
--- a/doc/ci/pipelines/schedules.md
+++ b/doc/ci/pipelines/schedules.md
@@ -6,142 +6,69 @@ disqus_identifier: 'https://docs.gitlab.com/ee/user/project/pipelines/schedules.
type: reference, howto
---
-# Pipeline schedules **(FREE)**
+# Scheduled pipelines **(FREE)**
-Pipelines are normally run based on certain conditions being met. For example, when a branch is pushed to repository.
-
-Pipeline schedules can be used to also run [pipelines](index.md) at specific intervals. For example:
-
-- Every month on the 22nd (cron example: `0 0 22 * *`) for a certain branch.
-- Every month on the 2nd Monday (cron example: `0 0 * * 1#2`).
-- Every other Sunday at 0900 hours (cron example: `0 9 * * sun%2`).
-- Once every day (cron example: `0 0 * * *`).
-
-Schedule timing is configured with [cron notation](../../topics/cron/index.md).
-You can use any cron value, but scheduled pipelines cannot run more frequently
-than the instance's [maximum frequency for scheduled pipelines](#advanced-configuration).
-
-In addition to using the GitLab UI, pipeline schedules can be maintained using the
-[Pipeline schedules API](../../api/pipeline_schedules.md).
+Use scheduled pipelines to run GitLab CI/CD [pipelines](index.md) at regular intervals.
## Prerequisites
-In order for a scheduled pipeline to be created successfully:
-
-- The schedule owner must have [permissions](../../user/permissions.md) to merge into the target branch.
-- The pipeline configuration must be valid.
-
-Otherwise the pipeline is not created.
-
-## Configuring pipeline schedules
-
-To schedule a pipeline for project:
-
-1. Navigate to the project's **CI/CD > Schedules** page.
-1. Click the **New schedule** button.
-1. Fill in the **Schedule a new pipeline** form.
-1. Click the **Save pipeline schedule** button.
-
-![New Schedule Form](img/pipeline_schedules_new_form.png)
-
-NOTE:
-Pipelines execution [timing is dependent](#advanced-configuration) on Sidekiq's own schedule.
-
-In the **Schedules** index page you can see a list of the pipelines that are
-scheduled to run. The next run is automatically calculated by the server GitLab
-is installed on.
-
-![Schedules list](img/pipeline_schedules_list.png)
-
-### Using variables
-
-You can pass any number of arbitrary variables. They are available in
-GitLab CI/CD so that they can be used in your [`.gitlab-ci.yml` file](../../ci/yaml/index.md).
-
-![Scheduled pipeline variables](img/pipeline_schedule_variables.png)
-
-### Using `rules`
-
-To configure a job to be executed only when the pipeline has been
-scheduled, use the [`rules`](../yaml/index.md#rules) keyword.
-
-In this example, `make world` runs in scheduled pipelines, and `make build`
-runs in branch and tag pipelines:
-
-```yaml
-job:on-schedule:
- rules:
- - if: $CI_PIPELINE_SOURCE == "schedule"
- script:
- - make world
-
-job:
- rules:
- - if: $CI_PIPELINE_SOURCE == "push"
- script:
- - make build
-```
-
-### Advanced configuration **(FREE SELF)**
-
-Scheduled pipelines can be configured with any [cron value](../../topics/cron/index.md),
-but they do not always run exactly when scheduled. An internal process, called the
-_pipeline schedule worker_, queues all the scheduled pipelines, but does not
-run continuously. The worker runs on its own schedule, and scheduled pipelines that
-are ready to start are only queued the next time the worker runs. Scheduled pipelines
-can't run more frequently than the worker.
-
-The default frequency of the pipeline schedule worker is `3-59/10 * * * *` (every ten minutes,
-starting with `0:03`, `0:13`, `0:23`, and so on). The default frequency for GitLab.com
-is listed in the [GitLab.com settings](../../user/gitlab_com/index.md#gitlab-cicd).
-
-To change the frequency of the pipeline schedule worker:
-
-1. Edit the `gitlab_rails['pipeline_schedule_worker_cron']` value in your instance's `gitlab.rb` file.
-1. [Reconfigure GitLab](../../administration/restart_gitlab.md#omnibus-gitlab-reconfigure) for the changes to take effect.
-
-For example, to set the maximum frequency of pipelines to twice a day, set `pipeline_schedule_worker_cron`
-to a cron value of `0 */12 * * *` (`00:00` and `12:00` every day).
+For a scheduled pipeline to run:
-## Working with scheduled pipelines
+- The schedule owner must have the Developer role. For pipelines on protected branches,
+ the schedule owner must be [allowed to merge](../../user/project/protected_branches.md#configure-a-protected-branch)
+ to the branch.
+- The [CI/CD configuration](../yaml/index.md) must be valid.
-After configuration, GitLab supports many functions for working with scheduled pipelines.
+Otherwise, the pipeline is not created. No error message is displayed.
-### Running manually
+## Add a pipeline schedule
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/15700) in GitLab 10.4.
+> Scheduled pipelines for tags [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/23292) in GitLab 14.9.
-To trigger a pipeline schedule manually, click the "Play" button:
+To add a pipeline schedule:
-![Play Pipeline Schedule](img/pipeline_schedule_play.png)
+1. On the top bar, select **Menu > Projects** and find your project.
+1. On the left sidebar, select **CI/CD > Schedules**.
+1. Select **New schedule** and fill in the form.
+ - **Interval Pattern**: Select one of the preconfigured intervals, or enter a custom
+ interval in [cron notation](../../topics/cron/index.md). You can use any cron value,
+ but scheduled pipelines cannot run more frequently than the instance's
+ [maximum scheduled pipeline frequency](../../administration/cicd.md#change-maximum-scheduled-pipeline-frequency).
+ - **Target branch or tag**: Select the branch or tag for the pipeline.
+ - **Variables**: Add any number of [CI/CD variables](../variables/index.md) to the schedule.
+ These variables are available only when the scheduled pipeline runs,
+ and not in any other pipeline run.
-This schedules a background job to run the pipeline schedule. A flash
-message provides a link to the CI/CD Pipeline index page.
+## Run manually
-NOTE:
-To help avoid abuse, users are rate limited to triggering a pipeline once per
-minute.
+To trigger a pipeline schedule manually, so that it runs immediately instead of
+the next scheduled time:
-### Taking ownership
+1. On the top bar, select **Menu > Projects** and find your project.
+1. On the left sidebar, select **CI/CD > Schedules**.
+1. On the right of the list, for
+ the pipeline you want to run, select **Play** (**{play}**).
-Pipelines are executed as a user, who owns a schedule. This influences what projects and other resources the pipeline has access to.
+You can manually run scheduled pipelines once per minute.
-If a user does not own a pipeline, you can take ownership by clicking the **Take ownership** button.
-The next time a pipeline is scheduled, your credentials are used.
+## Take ownership
-![Schedules list](img/pipeline_schedules_ownership.png)
+Scheduled pipelines execute with the permissions of the user
+who owns the schedule. The pipeline has access to the same resources as the pipeline owner,
+including [protected environments](../environments/protected_environments.md) and the
+[CI/CD job token](../jobs/ci_job_token.md).
-If the owner of a pipeline schedule cannot create
-pipelines on the target branch, the schedule stops creating new
-pipelines.
+To take ownership of a pipeline created by a different user:
-This can happen if, for example:
+1. On the top bar, select **Menu > Projects** and find your project.
+1. On the left sidebar, select **CI/CD > Schedules**.
+1. On the right of the list, for
+ the pipeline you want to become owner of, select **Take ownership**.
-- The owner is blocked or removed from the project.
-- The target branch or tag is protected.
+## Related topics
-In this case, someone with sufficient privileges must take ownership of the
-schedule.
+- Pipeline schedules can be maintained by using the [Pipeline schedules API](../../api/pipeline_schedules.md).
+- You can [control which jobs are added to scheduled pipelines](../jobs/job_control.md#run-jobs-for-scheduled-pipelines).
<!-- ## Troubleshooting
diff --git a/doc/ci/pipelines/settings.md b/doc/ci/pipelines/settings.md
index e22746dbfa0..7960d0afa85 100644
--- a/doc/ci/pipelines/settings.md
+++ b/doc/ci/pipelines/settings.md
@@ -190,18 +190,13 @@ You can define how long a job can run before it times out.
1. On the left sidebar, select **Settings > CI/CD**.
1. Expand **General pipelines**.
1. In the **Timeout** field, enter the number of minutes, or a human-readable value like `2 hours`.
+ Must be 10 minutes or more, and less than one month. Default is 60 minutes.
Jobs that exceed the timeout are marked as failed.
You can override this value [for individual runners](../runners/configure_runners.md#set-maximum-job-timeout-for-a-runner).
-## Add test coverage results to a merge request (DEPRECATED)
-
-> [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/17633) in GitLab 14.9. Replaced by [`coverage` keyword](../yaml/index.md#coverage).
-
-WARNING:
-This feature is in its end-of-life process. It is [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/17633)
-for use in GitLab 14.9, and is planned for [removal](https://gitlab.com/gitlab-org/gitlab/-/issues/17633) in GitLab 15.0.
+## Merge request test coverage results
If you use test coverage in your code, you can use a regular expression to
find coverage results in the job log. You can then include these results
@@ -215,27 +210,38 @@ averaged.
![Build status coverage](img/pipelines_test_coverage_build.png)
-To define a coverage-parsing regular expression:
+### Add test coverage results using `coverage` keyword
+
+To add test coverage results to a merge request using the project's `.gitlab-ci.yml` file, provide a regular expression
+using the [`coverage`](../yaml/index.md#coverage) keyword.
+
+Setting the regular expression this way takes precedence over project settings.
+
+### Add test coverage results using project settings (DEPRECATED)
+
+> [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/17633) in GitLab 14.9. Replaced by [`coverage` keyword](../yaml/index.md#coverage).
+
+WARNING:
+This feature is in its end-of-life process. It is [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/17633)
+for use in GitLab 14.9, and is planned for [removal](https://gitlab.com/gitlab-org/gitlab/-/issues/17633) in GitLab 15.0.
-- Using the project's `.gitlab-ci.yml`, provide a regular expression using the [`coverage`](../yaml/index.md#coverage)
- keyword. Setting the regular expression this way takes precedence over the project's CI/CD settings.
+You can add test coverage results to merge requests using the Project's CI/CD settings:
-- Using the Project's CI/CD settings:
- - Set using the GitLab UI:
+- Set using the GitLab UI:
- 1. On the top bar, select **Menu > Projects** and find your project.
- 1. On the left sidebar, select **Settings > CI/CD**.
- 1. Expand **General pipelines**.
- 1. In the **Test coverage parsing** field, enter a regular expression. Leave blank to disable this feature.
+ 1. On the top bar, select **Menu > Projects** and find your project.
+ 1. On the left sidebar, select **Settings > CI/CD**.
+ 1. Expand **General pipelines**.
+ 1. In the **Test coverage parsing** field, enter a regular expression. Leave blank to disable this feature.
- - Set when [editing a project](../../api/projects.md#edit-project) or [creating a project](../../api/projects.md#create-project)
- using the GitLab API with the `build_coverage_regex` attribute:
+- Set when [editing a project](../../api/projects.md#edit-project) or [creating a project](../../api/projects.md#create-project)
+ using the GitLab API with the `build_coverage_regex` attribute:
- ```shell
- curl --request PUT --header "PRIVATE-TOKEN: <your-token>" \
- --url 'https://gitlab.com/api/v4/projects/<your-project-ID>' \
- --data "build_coverage_regex=<your-regular-expression>"
- ```
+ ```shell
+ curl --request PUT --header "PRIVATE-TOKEN: <your-token>" \
+ --url 'https://gitlab.com/api/v4/projects/<your-project-ID>' \
+ --data "build_coverage_regex=<your-regular-expression>"
+ ```
You can use <https://rubular.com> to test your regular expression. The regular expression returns the **last**
match found in the output.
@@ -324,7 +330,15 @@ lein cloverage | perl -pe 's/\e\[?.*?[\@-~]//g'
Pipeline badges indicate the pipeline status and a test coverage value
for your project. These badges are determined by the latest successful pipeline.
-### View the code for the pipeline status and coverage reports badges
+## Latest release badge
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/33368) in GitLab 14.8.
+
+A latest release badge indicates the latest release tag name for your project.
+By default, the badge fetches the release sorted using the [`released_at`](../../api/releases/index.md#create-a-release) time.
+Support for [`semver`](https://semver.org/) sorting is tracked [in this issue](https://gitlab.com/gitlab-org/gitlab/-/issues/352945).
+
+### View the code for the pipeline status, coverage reports, and latest release badges
You can view the exact link for your badges. Then you can embed the badge in your HTML
or Markdown pages.
@@ -332,7 +346,7 @@ or Markdown pages.
1. On the top bar, select **Menu > Projects** and find your project.
1. On the left sidebar, select **Settings > CI/CD**.
1. Expand **General pipelines**.
-1. In the **Pipeline status** or **Coverage report** sections, view the URLs for the images.
+1. In the **Pipeline status**, **Coverage report**, or **Latest release** sections, view the URLs for the images.
![Pipelines badges](img/pipelines_settings_badges.png)
@@ -364,9 +378,8 @@ https://gitlab.example.com/<namespace>/<project>/badges/<branch>/pipeline.svg?ig
### Test coverage report badge
-You can define the regular expression for the [coverage report](#add-test-coverage-results-to-a-merge-request-deprecated)
-that each job log is matched against. This means that each job in the
-pipeline can have the test coverage percentage value defined.
+You can define the regular expression for the [coverage report](#merge-request-test-coverage-results) that each job log
+is matched against. This means that each job in the pipeline can have the test coverage percentage value defined.
To access the test coverage badge, use the following link:
@@ -406,6 +419,25 @@ If an invalid boundary is set, GitLab automatically adjusts it to be valid. For
if `min_good` is set `80`, and `min_acceptable` is set to `85` (too high), GitLab automatically
sets `min_acceptable` to `79` (`min_good` - `1`).
+### Latest release badge
+
+When a release exists in your project, it shows the latest release tag name. If there is no release,
+it shows `none`.
+
+You can access a latest release badge image by using the following link:
+
+```plaintext
+https://gitlab.example.com/<namespace>/<project>/-/badges/release.svg
+```
+
+#### Sorting preferences
+
+By default, the latest release badge fetches the release using `release_at` time. The use of the query parameter `?order_by=release_at` is optional, and support for `?order_by=semver` is tracked [in this issue](https://gitlab.com/gitlab-org/gitlab/-/issues/352945):
+
+```plaintext
+https://gitlab.example.com/<namespace>/<project>/-/badges/release.svg?order_by=release_at
+```
+
### Badge styles
Pipeline badges can be rendered in different styles by adding the `style=style_name` parameter to the URL. Two styles are available:
diff --git a/doc/ci/runners/build_cloud/linux_build_cloud.md b/doc/ci/runners/build_cloud/linux_build_cloud.md
deleted file mode 100644
index 2892a30cd2e..00000000000
--- a/doc/ci/runners/build_cloud/linux_build_cloud.md
+++ /dev/null
@@ -1,9 +0,0 @@
----
-redirect_to: '../saas/linux_saas_runner.md'
-remove_date: '2022-02-05'
----
-
-This document was moved to [another location](../saas/linux_saas_runner.md).
-
-<!-- This redirect file can be deleted after 2022-02-05. -->
-<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/#move-or-rename-a-page -->
diff --git a/doc/ci/runners/build_cloud/macos/environment.md b/doc/ci/runners/build_cloud/macos/environment.md
deleted file mode 100644
index a534e87cc34..00000000000
--- a/doc/ci/runners/build_cloud/macos/environment.md
+++ /dev/null
@@ -1,9 +0,0 @@
----
-redirect_to: '../../saas/macos/environment.md'
-remove_date: '2022-02-05'
----
-
-This document was moved to [another location](../../saas/macos/environment.md).
-
-<!-- This redirect file can be deleted after 2022-02-05. -->
-<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/#move-or-rename-a-page -->
diff --git a/doc/ci/runners/build_cloud/macos_build_cloud.md b/doc/ci/runners/build_cloud/macos_build_cloud.md
deleted file mode 100644
index 50b7e0cfb79..00000000000
--- a/doc/ci/runners/build_cloud/macos_build_cloud.md
+++ /dev/null
@@ -1,9 +0,0 @@
----
-redirect_to: '../saas/macos_saas_runner.md'
-remove_date: '2022-02-05'
----
-
-This document was moved to [another location](../saas/macos_saas_runner.md).
-
-<!-- This redirect file can be deleted after 2022-02-05. -->
-<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/#move-or-rename-a-page -->
diff --git a/doc/ci/runners/build_cloud/windows_build_cloud.md b/doc/ci/runners/build_cloud/windows_build_cloud.md
deleted file mode 100644
index fb64938eb9f..00000000000
--- a/doc/ci/runners/build_cloud/windows_build_cloud.md
+++ /dev/null
@@ -1,9 +0,0 @@
----
-redirect_to: '../saas/windows_saas_runner.md'
-remove_date: '2022-02-05'
----
-
-This document was moved to [another location](../saas/windows_saas_runner.md).
-
-<!-- This redirect file can be deleted after 2022-02-05. -->
-<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/#move-or-rename-a-page -->
diff --git a/doc/ci/runners/configure_runners.md b/doc/ci/runners/configure_runners.md
index 60e21653a45..6b14cea51d6 100644
--- a/doc/ci/runners/configure_runners.md
+++ b/doc/ci/runners/configure_runners.md
@@ -23,15 +23,15 @@ if smaller than the [project defined timeout](../pipelines/settings.md#set-a-lim
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, runners do not override the project timeout.
-
On GitLab.com, you cannot override the job timeout for shared runners and must use the [project defined timeout](../pipelines/settings.md#set-a-limit-for-how-long-jobs-can-run).
To set the maximum job timeout:
1. In a project, go to **Settings > CI/CD > Runners**.
1. Select your specific runner to edit the settings.
-1. Enter a value under **Maximum job timeout**.
+1. Enter a value under **Maximum job timeout**. Must be 10 minutes or more. If not
+ defined, the [project's job timeout setting](../pipelines/settings.md#set-a-limit-for-how-long-jobs-can-run)
+ is used.
1. Select **Save changes**.
How this feature works:
@@ -59,7 +59,7 @@ How this feature works:
## Be careful with sensitive information
-With some [runner executors](https://docs.gitlab.com/runner/executors/README.html),
+With some [runner executors](https://docs.gitlab.com/runner/executors/),
if you can run a job on the runner, you can get full access to the file system,
and thus any code it runs as well as the token of the runner. With shared runners, this means that anyone
that runs jobs on the runner, can access anyone else's code that runs on the
@@ -70,7 +70,7 @@ to create a clone of a runner and submit false jobs, for example.
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).
+and using more secure [runner executors](https://docs.gitlab.com/runner/executors/).
### Prevent runners from revealing sensitive information
diff --git a/doc/ci/runners/index.md b/doc/ci/runners/index.md
index 064ad64b79f..257dc02805b 100644
--- a/doc/ci/runners/index.md
+++ b/doc/ci/runners/index.md
@@ -13,9 +13,9 @@ If you are using self-managed GitLab or you use GitLab.com but want to use your
If you are using GitLab SaaS (GitLab.com), your CI jobs automatically run on runners provided by GitLab.
No configuration is required. Your jobs can run on:
-- [Linux runners](build_cloud/linux_build_cloud.md).
-- [Windows runners](build_cloud/windows_build_cloud.md) (beta).
-- [macOS runners](build_cloud/macos_build_cloud.md) (beta).
+- [Linux runners](saas/linux_saas_runner.md).
+- [Windows runners](saas/windows_saas_runner.md) ([Beta](../../policy/alpha-beta-support.md#beta-features)).
+- [macOS runners](saas/macos_saas_runner.md) ([Beta](../../policy/alpha-beta-support.md#beta-features)).
The number of minutes you can use on these runners depends on the
[maximum number of CI/CD minutes](../pipelines/cicd_minutes.md)
diff --git a/doc/ci/runners/runner_cloud/linux_runner_cloud.md b/doc/ci/runners/runner_cloud/linux_runner_cloud.md
deleted file mode 100644
index 2892a30cd2e..00000000000
--- a/doc/ci/runners/runner_cloud/linux_runner_cloud.md
+++ /dev/null
@@ -1,9 +0,0 @@
----
-redirect_to: '../saas/linux_saas_runner.md'
-remove_date: '2022-02-05'
----
-
-This document was moved to [another location](../saas/linux_saas_runner.md).
-
-<!-- This redirect file can be deleted after 2022-02-05. -->
-<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/#move-or-rename-a-page -->
diff --git a/doc/ci/runners/runner_cloud/macos/environment.md b/doc/ci/runners/runner_cloud/macos/environment.md
deleted file mode 100644
index 37ad21c28fc..00000000000
--- a/doc/ci/runners/runner_cloud/macos/environment.md
+++ /dev/null
@@ -1,9 +0,0 @@
----
-redirect_to: '../../saas/macos/environment.md'
-remove_date: '2022-02-05'
----
-
-This document was moved to [another location](../../saas/macos/environment.md).
-
-<!-- This redirect file can be deleted after 2022-02-05. -->
-<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/#move-or-rename-a-page --> \ No newline at end of file
diff --git a/doc/ci/runners/runner_cloud/macos_runner_cloud.md b/doc/ci/runners/runner_cloud/macos_runner_cloud.md
deleted file mode 100644
index 50b7e0cfb79..00000000000
--- a/doc/ci/runners/runner_cloud/macos_runner_cloud.md
+++ /dev/null
@@ -1,9 +0,0 @@
----
-redirect_to: '../saas/macos_saas_runner.md'
-remove_date: '2022-02-05'
----
-
-This document was moved to [another location](../saas/macos_saas_runner.md).
-
-<!-- This redirect file can be deleted after 2022-02-05. -->
-<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/#move-or-rename-a-page -->
diff --git a/doc/ci/runners/runner_cloud/windows_runner_cloud.md b/doc/ci/runners/runner_cloud/windows_runner_cloud.md
deleted file mode 100644
index fb64938eb9f..00000000000
--- a/doc/ci/runners/runner_cloud/windows_runner_cloud.md
+++ /dev/null
@@ -1,9 +0,0 @@
----
-redirect_to: '../saas/windows_saas_runner.md'
-remove_date: '2022-02-05'
----
-
-This document was moved to [another location](../saas/windows_saas_runner.md).
-
-<!-- This redirect file can be deleted after 2022-02-05. -->
-<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/#move-or-rename-a-page -->
diff --git a/doc/ci/runners/runners_scope.md b/doc/ci/runners/runners_scope.md
index 7cfd8e50f6c..aa7e268e800 100644
--- a/doc/ci/runners/runners_scope.md
+++ b/doc/ci/runners/runners_scope.md
@@ -236,6 +236,10 @@ To enable or disable a specific runner for a project:
1. Go to the project's **Settings > CI/CD** and expand the **Runners** section.
1. Click **Enable for this project** or **Disable for this project**.
+You can edit a specific runner from any of the projects it's enabled for.
+The modifications, which include unlocking, editing tags and the description,
+affect all projects that use the runner.
+
### Prevent a specific runner from being enabled for other projects
You can configure a specific runner so it is "locked" and cannot be enabled for other projects.
diff --git a/doc/ci/runners/saas/linux_saas_runner.md b/doc/ci/runners/saas/linux_saas_runner.md
index 4d1e628b8e7..fd3fedbc3f5 100644
--- a/doc/ci/runners/saas/linux_saas_runner.md
+++ b/doc/ci/runners/saas/linux_saas_runner.md
@@ -26,7 +26,7 @@ Jobs handled by shared runners on GitLab.com (`shared-runners-manager-X.gitlab.c
**time out after 3 hours**, regardless of the timeout configured in a
project. Check issue [#4010](https://gitlab.com/gitlab-com/infrastructure/-/issues/4010) and [#4070](https://gitlab.com/gitlab-com/infrastructure/-/issues/4070) for the reference.
-Jobs handled by shared runners on Windows and macOS on GitLab.com **time out after 1 hour** while this service is in the Beta stage.
+Jobs handled by shared runners on Windows and macOS on GitLab.com **time out after 1 hour** while this service is in the [Beta](../../../policy/alpha-beta-support.md#beta-features) stage.
Below are the runners' settings.
diff --git a/doc/ci/runners/saas/macos/environment.md b/doc/ci/runners/saas/macos/environment.md
index 3332eab9b44..d1943a487a7 100644
--- a/doc/ci/runners/saas/macos/environment.md
+++ b/doc/ci/runners/saas/macos/environment.md
@@ -14,7 +14,7 @@ When you use SaaS runners on macOS:
## VM types
The virtual machine where your job runs has `sudo` access with no password.
-For the Beta, there is only one available machine type, `gbc-macos-large`.
+For the [Beta](../../../../policy/alpha-beta-support.md#beta-features), there is only one available machine type, `gbc-macos-large`.
| Instance type | vCPUS | Memory (GB) |
| --------- | --- | ------- |
diff --git a/doc/ci/runners/saas/macos_saas_runner.md b/doc/ci/runners/saas/macos_saas_runner.md
index bfe408f4485..885a76a7b46 100644
--- a/doc/ci/runners/saas/macos_saas_runner.md
+++ b/doc/ci/runners/saas/macos_saas_runner.md
@@ -4,7 +4,10 @@ group: Runner
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
-# SaaS runners on macOS (Beta) **(FREE SAAS)**
+# SaaS runners on macOS (beta) **(FREE SAAS)**
+
+SaaS runners on macOS are in [Beta](../../../policy/alpha-beta-support.md#beta-features)
+and shouldn't be relied upon for mission-critical production jobs.
SaaS runners on macOS provide an on-demand macOS build environment integrated with
GitLab SaaS [CI/CD](../../../ci/index.md).
@@ -12,9 +15,6 @@ Use these runners to build, test, and deploy apps for the Apple ecosystem (macOS
of all the capabilities of the GitLab single DevOps platform and not have to manage or operate a
build environment.
-SaaS runners on macOS are in [Beta](../../../policy/alpha-beta-support.md#beta-features)
-and shouldn't be relied upon for mission-critical production jobs.
-
## Quickstart
To start using SaaS runners on macOS, you must submit an access request [issue](https://gitlab.com/gitlab-com/macos-buildcloud-runners-beta/-/issues/new?issuable_template=beta_access_request). After your
diff --git a/doc/ci/secrets/index.md b/doc/ci/secrets/index.md
index ea0c0d9cc84..5595559b5f0 100644
--- a/doc/ci/secrets/index.md
+++ b/doc/ci/secrets/index.md
@@ -9,6 +9,7 @@ type: concepts, howto
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/218746) in GitLab 13.4 and GitLab Runner 13.4.
> - `file` setting [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/250695) in GitLab 14.1 and GitLab Runner 14.1.
+> - `VAULT_NAMESPACE` setting [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/255619) in GitLab 14.9 and GitLab Runner 14.9.
Secrets represent sensitive information your CI job needs to complete work. This
sensitive information can be items like API tokens, database credentials, or private keys.
@@ -90,6 +91,9 @@ To configure your Vault server:
If no role is specified, Vault uses the [default role](https://www.vaultproject.io/api/auth/jwt#default_role)
specified when the authentication method was configured.
- `VAULT_AUTH_PATH` - Optional. The path where the authentication method is mounted, default is `jwt`.
+ - `VAULT_NAMESPACE` - Optional. The [Vault Enterprise namespace](https://www.vaultproject.io/docs/enterprise/namespaces) to use for reading secrets and authentication.
+ If no namespace is specified, Vault uses the `root` ("`/`") namespace.
+ The setting is ignored by Vault Open Source.
NOTE:
Support for providing these values in the user interface [is tracked in this issue](https://gitlab.com/gitlab-org/gitlab/-/issues/218677).
diff --git a/doc/ci/services/index.md b/doc/ci/services/index.md
index d14027cb1ef..e6406818b4c 100644
--- a/doc/ci/services/index.md
+++ b/doc/ci/services/index.md
@@ -438,3 +438,7 @@ docker rm -f -v build service-mysql service-postgres
This forcefully (`-f`) removes the `build` container, the two service
containers, and all volumes (`-v`) that were created with the container
creation.
+
+## Security when using services containers
+
+Docker privileged mode applies to services. This means that the service image container can access the host system. You should use container images from trusted sources only.
diff --git a/doc/ci/unit_test_reports.md b/doc/ci/unit_test_reports.md
index e2de47c6c62..14350ac884f 100644
--- a/doc/ci/unit_test_reports.md
+++ b/doc/ci/unit_test_reports.md
@@ -231,7 +231,7 @@ The [JunitXML.TestLogger](https://www.nuget.org/packages/JunitXml.TestLogger/) N
package can generate test reports for .Net Framework and .Net Core applications. The following
example expects a solution in the root folder of the repository, with one or more
project files in sub-folders. One result file is produced per test project, and each file
-is placed in a new artifacts folder. This example includes optional formatting arguments, which
+is placed in the artifacts folder. This example includes optional formatting arguments, which
improve the readability of test data in the test widget. A full .Net Core
[example is available](https://gitlab.com/Siphonophora/dot-net-cicd-test-logging-demo).
@@ -353,7 +353,7 @@ displays a list of test suites and cases reported from the XML file.
![Test Reports Widget](img/pipelines_junit_test_report_v13_10.png)
-You can view all the known test suites and click on each of these to see further
+You can view all the known test suites and select each of these to see further
details, including the cases that make up the suite.
You can also retrieve the reports via the [GitLab API](../api/pipelines.md#get-a-pipelines-test-report).
@@ -366,8 +366,7 @@ If parsing JUnit report XML results in an error, an indicator is shown next to t
![Test Reports With Errors](img/pipelines_junit_test_report_with_errors_v13_10.png)
-NOTE:
-GitLab.com has a 500,000 [test case parsing limit](../user/gitlab_com/#gitlab-cicd). Self-managed administrators can manage this setting on their instance.
+For test case parsing limits, see [Max test cases per unit test report](../user/gitlab_com/#gitlab-cicd).
GitLab does not parse very [large nodes](https://nokogiri.org/tutorials/parsing_an_html_xml_document.html#parse-options) of JUnit reports. There is [an issue](https://gitlab.com/gitlab-org/gitlab/-/issues/268035) open to make this optional.
diff --git a/doc/ci/variables/index.md b/doc/ci/variables/index.md
index ba8451110eb..e4e562bb005 100644
--- a/doc/ci/variables/index.md
+++ b/doc/ci/variables/index.md
@@ -653,7 +653,7 @@ The order of precedence for variables is (from highest to lowest):
1. These all have the same (highest) precedence:
- [Trigger variables](../triggers/index.md#pass-cicd-variables-in-the-api-call).
- - [Scheduled pipeline variables](../pipelines/schedules.md#using-variables).
+ - [Scheduled pipeline variables](../pipelines/schedules.md#add-a-pipeline-schedule).
- [Manual pipeline run variables](#override-a-variable-when-running-a-pipeline-manually).
- Variables added when [creating a pipeline with the API](../../api/pipelines.md#create-a-new-pipeline).
1. Project [variables](#custom-cicd-variables).
diff --git a/doc/ci/yaml/gitlab_ci_yaml.md b/doc/ci/yaml/gitlab_ci_yaml.md
index 9bab4a7fc77..f3773fbf143 100644
--- a/doc/ci/yaml/gitlab_ci_yaml.md
+++ b/doc/ci/yaml/gitlab_ci_yaml.md
@@ -1,7 +1,7 @@
---
stage: Verify
group: Pipeline Authoring
-info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#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/#assignments
type: reference
---
diff --git a/doc/ci/yaml/includes.md b/doc/ci/yaml/includes.md
index 34db6c61d0b..e5a543e7130 100644
--- a/doc/ci/yaml/includes.md
+++ b/doc/ci/yaml/includes.md
@@ -302,7 +302,7 @@ In `include` sections in your `.gitlab-ci.yml` file, you can use:
In GitLab 14.5 and later, you can also use:
- [Trigger variables](../triggers/index.md#pass-cicd-variables-in-the-api-call).
-- [Scheduled pipeline variables](../pipelines/schedules.md#using-variables).
+- [Scheduled pipeline variables](../pipelines/schedules.md#add-a-pipeline-schedule).
- [Manual pipeline run variables](../variables/index.md#override-a-variable-when-running-a-pipeline-manually).
- Pipeline [predefined variables](../variables/predefined_variables.md).
@@ -370,6 +370,11 @@ You can only use the following rules with `include` (and only with [certain vari
`rules` keyword `changes` is not supported.
+You cannot use [`needs:`](index.md#needs) to create a job dependency that points to
+a job added with `include:local:rules`. When the configuration is checked for validity,
+GitLab returns `undefined need: <job-name>`. An [issue exists](https://gitlab.com/gitlab-org/gitlab/-/issues/345377)
+to improve this behavior.
+
## Use `include:local` with wildcard file paths
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/25921) in GitLab 13.11.
diff --git a/doc/ci/yaml/index.md b/doc/ci/yaml/index.md
index d9ea5498b63..a3b91da8f08 100644
--- a/doc/ci/yaml/index.md
+++ b/doc/ci/yaml/index.md
@@ -135,7 +135,9 @@ The `include` files are:
- Always evaluated first and then merged with the content of the `.gitlab-ci.yml` file,
regardless of the position of the `include` keyword.
-You can [nest](includes.md#use-nested-includes) up to 100 includes, but you can't have duplicate includes.
+You can [nest](includes.md#use-nested-includes) up to 100 includes. In [GitLab 14.9 and later](https://gitlab.com/gitlab-org/gitlab/-/issues/28987),
+the same file can be included multiple times in nested includes, but duplicates are ignored.
+
In [GitLab 12.4 and later](https://gitlab.com/gitlab-org/gitlab/-/issues/28212),
the time limit to resolve all files is 30 seconds.
@@ -1349,7 +1351,7 @@ In this example:
**Additional details**:
- Coverage regular expressions set in `gitlab-ci.yml` take precedence over coverage regular expression set in the
- [GitLab UI](../pipelines/settings.md#add-test-coverage-results-to-a-merge-request-deprecated).
+ [GitLab UI](../pipelines/settings.md#add-test-coverage-results-using-project-settings-deprecated).
- If there is more than one matched line in the job output, the last line is used
(the first result of reverse search).
- If there are multiple matches in a single line, the last match is searched
@@ -1863,7 +1865,7 @@ image:
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/207484) in GitLab 12.9.
-Use `inherit` to [control inheritance of globally-defined defaults and variables](../jobs/index.md#control-the-inheritance-of-default-keywords-and-global-variables).
+Use `inherit` to [control inheritance of default keywords and variables](../jobs/index.md#control-the-inheritance-of-default-keywords-and-global-variables).
#### `inherit:default`
@@ -3690,6 +3692,61 @@ trigger_job:
In this example, jobs from subsequent stages wait for the triggered pipeline to
successfully complete before starting.
+#### `trigger:forward`
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/213729) in GitLab 14.9 [with a flag](../../administration/feature_flags.md) named `ci_trigger_forward_variables`. Disabled by default.
+
+FLAG:
+On self-managed GitLab, by default this feature is not available. To make it available,
+ask an administrator to [enable the feature flag](../../administration/feature_flags.md) named `ci_trigger_forward_variables`.
+The feature is not ready for production use.
+
+Use `trigger:forward` to specify what to forward to the downstream pipeline. You can control
+what is forwarded to both [parent-child pipelines](../pipelines/parent_child_pipelines.md)
+and [multi-project pipelines](../pipelines/multi_project_pipelines.md).
+
+**Possible inputs**:
+
+- `yaml_variables`: `true` (default), or `false`. When `true`, variables defined
+ in the trigger job are passed to downstream pipelines.
+- `pipeline_variables`: `true` or `false` (default). When `true`, [manual pipeline variables](../variables/index.md#override-a-defined-cicd-variable)
+ are passed to downstream pipelines.
+
+**Example of `trigger:forward`**:
+
+[Run this pipeline manually](../pipelines/index.md#run-a-pipeline-manually), with
+the CI/CD variable `MYVAR = my value`:
+
+```yaml
+variables: # default variables for each job
+ VAR: value
+
+# Default behavior:
+# - VAR is passed to the child
+# - MYVAR is not passed to the child
+child1:
+ trigger:
+ include: .child-pipeline.yml
+
+# Forward pipeline variables:
+# - VAR is passed to the child
+# - MYVAR is passed to the child
+child2:
+ trigger:
+ include: .child-pipeline.yml
+ forward:
+ pipeline_variables: true
+
+# Do not forward YAML variables:
+# - VAR is not passed to the child
+# - MYVAR is not passed to the child
+child3:
+ trigger:
+ include: .child-pipeline.yml
+ forward:
+ yaml_variables: false
+```
+
### `variables`
[CI/CD variables](../variables/index.md) are configurable values that are passed to jobs.
diff --git a/doc/development/adding_database_indexes.md b/doc/development/adding_database_indexes.md
index 0e8e8289464..d263d9b5eb5 100644
--- a/doc/development/adding_database_indexes.md
+++ b/doc/development/adding_database_indexes.md
@@ -275,11 +275,11 @@ You can verify if the MR was deployed to GitLab.com by executing
`/chatops run auto_deploy status <merge_sha>`. To verify existence of
the index, you can:
-- Use a meta-command in #database-lab, such as: `\d <index_name>`
- - Ensure that the index is not [`invalid`](https://www.postgresql.org/docs/12/sql-createindex.html#:~:text=The%20psql%20%5Cd%20command%20will%20report%20such%20an%20index%20as%20INVALID)
-- Ask someone in #database to check if the index exists
+- Use a meta-command in #database-lab, such as: `\d <index_name>`.
+ - Ensure that the index is not [`invalid`](https://www.postgresql.org/docs/12/sql-createindex.html#:~:text=The%20psql%20%5Cd%20command%20will%20report%20such%20an%20index%20as%20INVALID).
+- Ask someone in #database to check if the index exists.
- With proper access, you can also verify directly on production or in a
-production clone
+production clone.
### Add a migration to create the index synchronously
diff --git a/doc/development/agent/gitops.md b/doc/development/agent/gitops.md
deleted file mode 100644
index 7c741408ae6..00000000000
--- a/doc/development/agent/gitops.md
+++ /dev/null
@@ -1,9 +0,0 @@
----
-redirect_to: 'https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent/-/blob/master/doc/gitops.md'
-remove_date: '2022-02-01'
----
-
-This file was moved to [another location](https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent/-/blob/master/doc/gitops.md).
-
-<!-- This redirect file can be deleted after <2022-02-01>. -->
-<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/#move-or-rename-a-page -->
diff --git a/doc/development/agent/identity.md b/doc/development/agent/identity.md
deleted file mode 100644
index 6caf108a32a..00000000000
--- a/doc/development/agent/identity.md
+++ /dev/null
@@ -1,9 +0,0 @@
----
-redirect_to: 'https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent/-/blob/master/doc/identity_and_auth.md'
-remove_date: '2022-02-01'
----
-
-This file was moved to [another location](https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent/-/blob/master/doc/identity_and_auth.md).
-
-<!-- This redirect file can be deleted after <2022-02-01>. -->
-<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/#move-or-rename-a-page -->
diff --git a/doc/development/agent/index.md b/doc/development/agent/index.md
deleted file mode 100644
index 474f8a02933..00000000000
--- a/doc/development/agent/index.md
+++ /dev/null
@@ -1,9 +0,0 @@
----
-redirect_to: 'https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent/-/blob/master/doc/architecture.md'
-remove_date: '2022-02-01'
----
-
-This file was moved to [another location](https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent/-/blob/master/doc/architecture.md).
-
-<!-- This redirect file can be deleted after <2022-02-01>. -->
-<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/#move-or-rename-a-page -->
diff --git a/doc/development/agent/local.md b/doc/development/agent/local.md
deleted file mode 100644
index a4b29bea838..00000000000
--- a/doc/development/agent/local.md
+++ /dev/null
@@ -1,9 +0,0 @@
----
-redirect_to: 'https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent/-/blob/master/doc/local.md'
-remove_date: '2022-02-01'
----
-
-This file was moved to [another location](https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent/-/blob/master/doc/local.md).
-
-<!-- This redirect file can be deleted after <2022-02-01>. -->
-<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/#move-or-rename-a-page -->
diff --git a/doc/development/agent/repository_overview.md b/doc/development/agent/repository_overview.md
deleted file mode 100644
index 8ea9dceb32a..00000000000
--- a/doc/development/agent/repository_overview.md
+++ /dev/null
@@ -1,9 +0,0 @@
----
-redirect_to: 'https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent/-/blob/master/doc/repository_overview.md'
-remove_date: '2022-02-01'
----
-
-This file was moved to [another location](https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent/-/blob/master/doc/repository_overview.md).
-
-<!-- This redirect file can be deleted after <2022-02-01>. -->
-<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/#move-or-rename-a-page -->
diff --git a/doc/development/agent/routing.md b/doc/development/agent/routing.md
deleted file mode 100644
index 364267a45fe..00000000000
--- a/doc/development/agent/routing.md
+++ /dev/null
@@ -1,9 +0,0 @@
----
-redirect_to: 'https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent/-/blob/master/doc/kas_request_routing.md'
-remove_date: '2022-02-01'
----
-
-This file was moved to [another location](https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent/-/blob/master/doc/kas_request_routing.md).
-
-<!-- This redirect file can be deleted after <2022-02-01>. -->
-<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/#move-or-rename-a-page -->
diff --git a/doc/development/agent/user_stories.md b/doc/development/agent/user_stories.md
deleted file mode 100644
index 2ed4bbdc9f6..00000000000
--- a/doc/development/agent/user_stories.md
+++ /dev/null
@@ -1,9 +0,0 @@
----
-redirect_to: 'https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent/-/blob/master/doc/user_stories.md'
-remove_date: '2022-02-01'
----
-
-This file was moved to [another location](https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent/-/blob/master/doc/user_stories.md).
-
-<!-- This redirect file can be deleted after <2022-02-01>. -->
-<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/#move-or-rename-a-page -->
diff --git a/doc/development/api_graphql_styleguide.md b/doc/development/api_graphql_styleguide.md
index afd745533c9..417ccba26a0 100644
--- a/doc/development/api_graphql_styleguide.md
+++ b/doc/development/api_graphql_styleguide.md
@@ -442,10 +442,10 @@ booleans:
```ruby
class MergeRequestPermissionsType < BasePermissionType
- present_using MergeRequestPresenter
-
graphql_name 'MergeRequestPermissions'
+ present_using MergeRequestPresenter
+
abilities :admin_merge_request, :update_merge_request, :create_note
ability_field :resolve_note,
@@ -1329,6 +1329,10 @@ class UserUpdateMutation < BaseMutation
end
```
+Due to changes in the `1.13` version of the `graphql-ruby` gem, `graphql_name` should be the first
+line of the class to ensure that type names are generated correctly. The `Graphql::GraphqlNamePosition` cop enforces this.
+See [issue #27536](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/27536#note_840245581) for further context.
+
Our GraphQL mutation names are historically inconsistent, but new mutation names should follow the
convention `'{Resource}{Action}'` or `'{Resource}{Action}{Attribute}'`.
@@ -1511,9 +1515,9 @@ GraphQL-name of the mutation:
```ruby
module Types
class MutationType < BaseObject
- include Gitlab::Graphql::MountMutation
+ graphql_name 'Mutation'
- graphql_name "Mutation"
+ include Gitlab::Graphql::MountMutation
mount_mutation Mutations::MergeRequests::SetDraft
end
diff --git a/doc/development/architecture.md b/doc/development/architecture.md
index e8d04d68565..dd432dd5e37 100644
--- a/doc/development/architecture.md
+++ b/doc/development/architecture.md
@@ -101,11 +101,11 @@ understand the GitLab architecture.
A complete architecture diagram is available in our
[component diagram](#component-diagram) below.
-![Simplified Component Overview](img/architecture_simplified.png)
+![Simplified Component Overview](img/architecture_simplified_v14_9.png)
<!--
-To update this diagram, GitLab team members can edit this source file:
-https://docs.google.com/drawings/d/1fBzAyklyveF-i-2q-OHUIqDkYfjjxC4mq5shwKSZHLs/edit.
+To update this diagram, use and update this source file:
+https://miro.com/app/board/uXjVOH3lzXo=/
-->
### Component diagram
@@ -151,7 +151,7 @@ graph LR
NGINX -- TCP 8150 --> GitLabKas
NGINX --> Registry
%% inbound from GitLabShell
- GitLabShell --TCP 8080 -->Puma
+ GitLabShell --> GitLabWorkhorse
%% services
Puma["Puma (GitLab Rails)"]
@@ -349,7 +349,7 @@ Component statuses are linked to configuration documentation for each component.
| [GitLab Exporter](#gitlab-exporter) | Generates a variety of GitLab metrics | ✅ | ✅ | ✅ | ✅ | ✅ | ⌠| ⌠| CE & EE |
| [GitLab Geo Node](#gitlab-geo) | Geographically distributed GitLab nodes | ⚙ | ⚙ | ⌠| ⌠| ✅ | ⌠| ⚙ | EE Only |
| [GitLab Pages](#gitlab-pages) | Hosts static websites | ⚙ | ⚙ | ⌠| ⌠| ✅ | ⚙ | ⚙ | CE & EE |
-| [GitLab Agent](#gitlab-agent) | Integrate Kubernetes clusters in a cloud-native way | ⚙ | ⚙ | ⚙ | ⌠| ⌠| ⤓ | ⚙ | EE Only |
+| [GitLab agent](#gitlab-agent) | Integrate Kubernetes clusters in a cloud-native way | ⚙ | ⚙ | ⚙ | ⌠| ⌠| ⤓ | ⚙ | EE Only |
| [GitLab self-monitoring: Alertmanager](#alertmanager) | Deduplicates, groups, and routes alerts from Prometheus | ⚙ | ⚙ | ✅ | ⚙ | ✅ | ⌠| ⌠| CE & EE |
| [GitLab self-monitoring: Grafana](#grafana) | Metrics dashboard | ✅ | ✅ | ⚙ | ⤓ | ✅ | ⌠| ⚙ | CE & EE |
| [GitLab self-monitoring: Jaeger](#jaeger) | View traces generated by the GitLab instance | ⌠| ⚙ | ⚙ | ⌠| ⌠| ⤓ | ⚙ | CE & EE |
@@ -499,14 +499,14 @@ Geo is a premium feature built to help speed up the development of distributed t
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 Agent
+#### GitLab agent
- [Project page](https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent)
- Configuration:
- [Omnibus](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/files/gitlab-config-template/gitlab.rb.template)
- [Charts](https://docs.gitlab.com/charts/charts/gitlab/kas/index.html)
-The [GitLab Agent](../user/clusters/agent/index.md) is an active in-cluster
+The [GitLab agent](../user/clusters/agent/index.md) is an active in-cluster
component for solving GitLab and Kubernetes integration tasks in a secure and
cloud-native way.
diff --git a/doc/development/backend/create_source_code_be/index.md b/doc/development/backend/create_source_code_be/index.md
new file mode 100644
index 00000000000..6421ca3754a
--- /dev/null
+++ b/doc/development/backend/create_source_code_be/index.md
@@ -0,0 +1,143 @@
+---
+stage: Create
+group: Source Code
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
+---
+
+# Create: Source Code Backend
+
+The Create:Source Code BE team focuses on the GitLab suite of Source Code Management
+(SCM) tools. It is responsible for all backend aspects of the product categories
+that fall under the [Source Code group](https://about.gitlab.com/handbook/product/categories/#source-code-group)
+of the [Create stage](https://about.gitlab.com/handbook/product/categories/#create-stage)
+of the [DevOps lifecycle](https://about.gitlab.com/handbook/product/categories/#devops-stages).
+
+We interface with the Gitaly and Code Review teams, and work closely with the
+[Create:Source Code Frontend team](https://about.gitlab.com/handbook/engineering/development/dev/create-source-code-fe). The features
+we work with are listed on the
+[Features by Group Page](https://about.gitlab.com/handbook/product/categories/features/#createsource-code-group).
+
+The team works across three codebases: Workhorse, GitLab Shell and GitLab Rails.
+
+## Workhorse
+
+GitLab Workhorse is a smart reverse proxy for GitLab. It handles "large" HTTP
+requests such as file downloads, file uploads, `git push`, `git pull` and `git` archive downloads.
+
+Workhorse itself is not a feature, but there are several features in GitLab
+that would not work efficiently without Workhorse.
+
+Workhorse documentation is available in the [Workhorse repository](https://gitlab.com/gitlab-org/gitlab/tree/master/workhorse).
+
+## GitLab Shell
+
+GitLab Shell handles Git SSH sessions for GitLab and modifies the list of authorized keys.
+For more information, [refer to the README](https://gitlab.com/gitlab-org/gitlab-shell/-/blob/main/README.md).
+for GitLab Shell.
+
+## GitLab Rails
+
+### Source code API endpoints
+
+| Endpoint | Threshold | Source |
+| -----------------------------------------------------------------------------------|---------------------------------------|--------------------------------------------------------------------------------------|
+| `DELETE /api/:version/projects/:id/protected_branches/:name` | `:low` |[source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/api/protected_branches.rb) |
+| `GET /api/:version/internal/authorized_keys` | `:high` |[source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/api/internal/base.rb) | | |
+| `GET /api/:version/internal/lfs` | `:high` |[source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/api/internal/lfs.rb)|
+| `GET /api/:version/projects/:id/approval_rules` | `:low` | |
+| `GET /api/:version/projects/:id/approval_settings` | default | |
+| `GET /api/:version/projects/:id/approvals` | default | |
+| `GET /api/:version/projects/:id/forks` | `:low` |[source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/api/projects.rb) |
+| `GET /api/:version/projects/:id/groups` | default | [source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/api/projects.rb) |
+| `GET /api/:version/projects/:id/languages` | `:medium` |[source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/api/projects.rb) |
+| `GET /api/:version/projects/:id/merge_request_approval_setting` | `:medium` |[source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/lib/api/merge_request_approval_settings.rb) |
+| `GET /api/:version/projects/:id/merge_requests/:merge_request_iid/approval_rules` | `:low` |[source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/lib/api/merge_request_approval_rules.rb) |
+| `GET /api/:version/projects/:id/merge_requests/:merge_request_iid/approval_settings` | `:low` |[source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/lib/api/project_approval_settings.rb) |
+| `GET /api/:version/projects/:id/merge_requests/:merge_request_iid/approval_state` | `:low` | [source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/api/merge_request_approvals.rb) |
+| `GET /api/:version/projects/:id/merge_requests/:merge_request_iid/approvals` | `:low` |[source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/api/merge_request_approvals.rb) |
+| `GET /api/:version/projects/:id/protected_branches` | default |[source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/api/protected_branches.rb) |
+| `GET /api/:version/projects/:id/protected_branches/:name` | default |[source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/api/protected_branches.rb) |
+| `GET /api/:version/projects/:id/protected_tags` | default | |
+| `GET /api/:version/projects/:id/protected_tags/:name` | default | |
+| `GET /api/:version/projects/:id/push_rule` | default | |
+| `GET /api/:version/projects/:id/remote_mirrors` | default | |
+| `GET /api/:version/projects/:id/repository/archive` | default | |
+| `GET /api/:version/projects/:id/repository/blobs/:sha` | default | |
+| `GET /api/:version/projects/:id/repository/blobs/:sha/raw` | default | |
+| `GET /api/:version/projects/:id/repository/branches` | `:low` |[source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/api/branches.rb) |
+| `GET /api/:version/projects/:id/repository/branches/:branch` | `:low` |[source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/api/branches.rb) |
+| `GET /api/:version/projects/:id/repository/commits` | `:low` |[source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/api/commits.rb)|
+| `GET /api/:version/projects/:id/repository/commits/:sha` | default | [source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/api/commits.rb) |
+| `GET /api/:version/projects/:id/repository/commits/:sha/comments` | default | [source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/api/commits.rb) |
+| `GET /api/:version/projects/:id/repository/commits/:sha/diff` | `:low` |[source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/api/commits.rb) |
+| `GET /api/:version/projects/:id/repository/commits/:sha/merge_requests` | `:low` |[source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/api/commits.rb)|
+| `GET /api/:version/projects/:id/repository/commits/:sha/refs` | `:low` |[source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/api/commits.rb) |
+| `GET /api/:version/projects/:id/repository/compare` | `:low` |[source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/api/repositories.rb) |
+| `GET /api/:version/projects/:id/repository/contributors` | default | |
+| `GET /api/:version/projects/:id/repository/files/:file_path` | default | |
+| `GET /api/:version/projects/:id/repository/files/:file_path/raw` | `:low` |[source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/api/files.rb) |
+| `GET /api/:version/projects/:id/repository/tags` | `:low` |[source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/api/tags.rb) |
+| `GET /api/:version/projects/:id/repository/tree` | `:low` |[source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/api/repositories.rb) |
+| `GET /api/:version/projects/:id/statistics` | default | |
+| `GraphqlController#execute` | default | |
+| `HEAD /api/:version/projects/:id/repository/files/:file_path` | `:low` |[source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/api/files.rb) |
+| `HEAD /api/:version/projects/:id/repository/files/:file_path/raw` | `:low` |[source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/api/files.rb) |
+| `POST /api/:version/internal/allowed` | default | [source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/api/internal/base.rb) |
+| `POST /api/:version/internal/lfs_authenticate` | `:high` |[source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/api/internal/base.rb) |
+| `POST /api/:version/internal/post_receive` | default | [source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/api/internal/base.rb) |
+| `POST /api/:version/internal/pre_receive` | `:high` |[source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/api/internal/base.rb) |
+| `POST /api/:version/projects/:id/approvals` | `:low` |[source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/lib/api/project_approvals.rb) |
+| `POST /api/:version/projects/:id/merge_requests/:merge_request_iid/approvals` | `:low` | [source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/api/merge_request_approvals.rb) |
+| `POST /api/:version/projects/:id/merge_requests/:merge_request_iid/approve` | `:low` |[source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/api/merge_request_approvals.rb) |
+| `POST /api/:version/projects/:id/merge_requests/:merge_request_iid/unapprove` | `:low` |[source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/api/merge_request_approvals.rb)|
+| `POST /api/:version/projects/:id/protected_branches` | `:low` |[source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/api/protected_branches.rb)|
+| `POST /api/:version/projects/:id/repository/commits` | `:low` |[source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/api/commits.rb)|
+| `POST /api/:version/projects/:id/repository/files/:file_path` | `:low` |[source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/api/files.rb) |
+| `PUT /api/:version/projects/:id/push_rule` | default | |
+| `PUT /api/:version/projects/:id/repository/files/:file_path` | `:low` |[source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/api/files.rb) |
+| `Projects::BlameController#show` | `:low` |[source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/controllers/projects/blame_controller.rb) |
+| `Projects::BlobController#create` | `:low` |[source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/controllers/projects/blob_controller.rb) |
+| `Projects::BlobController#diff` | `:low` |[source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/controllers/projects/blob_controller.rb) |
+| `Projects::BlobController#edit` | `:low` |[source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/controllers/projects/blob_controller.rb) |
+| `Projects::BlobController#show` | `:low` |[source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/controllers/projects/blob_controller.rb) |
+| `Projects::BlobController#update` | `:low` |[source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/controllers/projects/blob_controller.rb) |
+| `Projects::BranchesController#create` | `:low` |[source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/controllers/projects/branches_controller.rb) |
+| `Projects::BranchesController#destroy` | `:low` |[source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/controllers/projects/branches_controller.rb) |
+| `Projects::BranchesController#diverging_commit_counts` | `:low` |[source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/controllers/projects/branches_controller.rb) |
+| `Projects::BranchesController#index` | `:low` |[source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/controllers/projects/branches_controller.rb) |
+| `Projects::BranchesController#new` | `:low` |[source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/controllers/projects/branches_controller.rb) |
+| `Projects::CommitController#branches` | `:low` |[source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/controllers/projects/commit_controller.rb) |
+| `Projects::CommitController#merge_requests` | `:low` |[source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/controllers/projects/commit_controller.rb) |
+| `Projects::CommitController#pipelines` | `:low` |[source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/controllers/projects/commit_controller.rb) |
+| `Projects::CommitController#show` | `:low` |[source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/controllers/projects/commit_controller.rb) |
+| `Projects::CommitsController#show` | `:low` |[source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/controllers/projects/commits_controller.rb)|
+| `Projects::CommitsController#signatures` | `:low` |[source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/controllers/projects/commits_controller.rb) |
+| `Projects::CompareController#create` | `:low` |[source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/controllers/projects/commits_controller.rb) |
+| `Projects::CompareController#index` | `:low` |[source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/controllers/projects/compare_controller.rb) |
+| `Projects::CompareController#show` | `:low` |[source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/controllers/projects/compare_controller.rb) |
+| `Projects::CompareController#signatures` | `:low` |[source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/controllers/projects/compare_controller.rb) |
+| `Projects::FindFileController#list` | `:low` |[source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/controllers/projects/find_file_controller.rb) |
+| `Projects::FindFileController#show` | `:low` |[source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/controllers/projects/find_file_controller.rb) |
+| `Projects::ForksController#index` | `:low` |[source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/controllers/projects/forks_controller.rb) |
+| `Projects::GraphsController#show` | `:low` |[source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/controllers/projects/graphs_controller.rb) |
+| `Projects::NetworkController#show` | `:low` |[source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/controllers/projects/network_controller.rb) |
+| `Projects::PathLocksController#index` | `:low` |[source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/app/controllers/projects/path_locks_controller.rb) |
+| `Projects::RawController#show` | default | |
+| `Projects::RefsController#logs_tree` | `:low` |[source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/controllers/projects/refs_controller.rb) |
+| `Projects::RefsController#switch` | `:low` |[source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/controllers/projects/refs_controller.rb) |
+| `Projects::RepositoriesController#archive` | default | |
+| `Projects::Settings::RepositoryController#show` | `:low` |[source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/controllers/projects/settings/repository_controller.rb) |
+| `Projects::TagsController#index` | `:low` |[source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/controllers/projects/tags_controller.rb) |
+| `Projects::TagsController#new` | `:low` |[source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/controllers/projects/tags_controller.rb) |
+| `Projects::TagsController#show` | `:low` |[source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/controllers/projects/tags_controller.rb) |
+| `Projects::TemplatesController#names` | `:low` |[source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/controllers/projects/templates_controller.rb) |
+| `Projects::TreeController#show` | `:low` |[source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/controllers/projects/tree_controller.rb) |
+| `ProjectsController#refs` | `:low` |[source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/controllers/projects_controller.rb) |
+| `Repositories::GitHttpController#git_receive_pack` | default | |
+| `Repositories::GitHttpController#git_upload_pack` | default | |
+| `Repositories::GitHttpController#info_refs` | default | |
+| `Repositories::LfsApiController#batch` | `:medium` |[source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/controllers/repositories/lfs_api_controller.rb) |
+| `Repositories::LfsLocksApiController#verify` | default | |
+| `Repositories::LfsStorageController#download` | `:medium` |[source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/controllers/repositories/lfs_storage_controller.rb) |
+| `Repositories::LfsStorageController#upload_authorize` | `:medium` |[source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/controllers/repositories/lfs_storage_controller.rb) |
+| `Repositories::LfsStorageController#upload_finalize` | `:low` |[source](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/controllers/repositories/lfs_storage_controller.rb) |
diff --git a/doc/development/background_migrations.md b/doc/development/background_migrations.md
index 49835085f96..9fffbd25518 100644
--- a/doc/development/background_migrations.md
+++ b/doc/development/background_migrations.md
@@ -489,7 +489,8 @@ View the production Sidekiq log and filter for:
- `json.class: BackgroundMigrationWorker`
- `json.job_status: fail`
-- `json.meta.caller_id: <MyBackgroundMigrationClassName>`
+- `json.meta.caller_id: <MyBackgroundMigrationSchedulingMigrationClassName>`
+- `json.args: <MyBackgroundMigrationClassName>`
Looking at the `json.error_class`, `json.error_message` and `json.error_backtrace` values may be helpful in understanding why the jobs failed.
diff --git a/doc/development/bulk_import.md b/doc/development/bulk_import.md
index ff0c8a19ca1..a2620faed35 100644
--- a/doc/development/bulk_import.md
+++ b/doc/development/bulk_import.md
@@ -1,7 +1,7 @@
---
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
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
# GitLab Group Migration
diff --git a/doc/development/caching.md b/doc/development/caching.md
index 20847832e37..7c51bd595f7 100644
--- a/doc/development/caching.md
+++ b/doc/development/caching.md
@@ -265,6 +265,13 @@ All the time!
- As the lookup is similar to a cache lookup (in the GitLab implementation), we can use
the same key for both. This is how `Gitlab::Cache.fetch_once` works.
+#### Possible downsides
+
+- Adding new attributes to a cached object using `Gitlab::JsonCache`
+ and `Gitlab::SafeRequestStore`, for example, can lead to stale data issues
+ where the cache data doesn't have the appropriate value for the new attribute
+ (see this past [incident](https://gitlab.com/gitlab-com/gl-infra/production/-/issues/6372)).
+
### When to use SQL caching
Rails uses this automatically for identical queries in a request, so no action is
diff --git a/doc/development/changelog.md b/doc/development/changelog.md
index b51db69c2f7..b98ed6cb109 100644
--- a/doc/development/changelog.md
+++ b/doc/development/changelog.md
@@ -101,6 +101,7 @@ EE: true
- _Any_ contribution from a community member, no matter how small, **may** have
a changelog entry regardless of these guidelines if the contributor wants one.
- Any [GLEX experiment](experiment_guide/gitlab_experiment.md) changes **should not** have a changelog entry.
+- An MR that includes only documentation changes **should not** have a changelog entry.
For more information, see
[how to handle changelog entries with feature flags](feature_flags/index.md#changelog).
diff --git a/doc/development/cicd/index.md b/doc/development/cicd/index.md
index 2779b457fb9..8677d5b08e3 100644
--- a/doc/development/cicd/index.md
+++ b/doc/development/cicd/index.md
@@ -7,9 +7,10 @@ type: index, concepts, howto
# CI/CD development documentation **(FREE)**
-Development guides that are specific to CI/CD are listed here.
+Development guides that are specific to CI/CD are listed here:
-If you are creating new CI/CD templates, please read [the development guide for GitLab CI/CD templates](templates.md).
+- If you are creating new CI/CD templates, please read [the development guide for GitLab CI/CD templates](templates.md).
+- If you are adding a new keyword or changing the CI schema, check the [CI schema guide](schema.md)
See the [CI/CD YAML reference documentation guide](cicd_reference_documentation_guide.md)
to learn how to update the [reference page](../../ci/yaml/index.md).
@@ -29,7 +30,7 @@ On the left side we have the events that can trigger a pipeline based on various
- A user clicking the "Run pipeline" button in the UI.
- When a [merge request is created or updated](../../ci/pipelines/merge_request_pipelines.md).
- When an MR is added to a [Merge Train](../../ci/pipelines/merge_trains.md#merge-trains).
-- A [scheduled pipeline](../../ci/pipelines/schedules.md#pipeline-schedules).
+- A [scheduled pipeline](../../ci/pipelines/schedules.md).
- When project is [subscribed to an upstream project](../../ci/pipelines/multi_project_pipelines.md#trigger-a-pipeline-when-an-upstream-project-is-rebuilt).
- When [Auto DevOps](../../topics/autodevops/index.md) is enabled.
- When GitHub integration is used with [external pull requests](../../ci/ci_cd_for_external_repos/index.md#pipelines-for-external-pull-requests).
diff --git a/doc/development/cicd/schema.md b/doc/development/cicd/schema.md
new file mode 100644
index 00000000000..b63d951b881
--- /dev/null
+++ b/doc/development/cicd/schema.md
@@ -0,0 +1,146 @@
+---
+stage: Verify
+group: Pipeline Authoring
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
+type: index, howto
+---
+
+# Contribute to the CI Schema **(FREE)**
+
+The [pipeline editor](../../ci/pipeline_editor/index.md) uses a CI schema to enhance
+the authoring experience of our CI configuration files. With the CI schema, the editor can:
+
+- Validate the content of the CI configuration file as it is being written in the editor.
+- Provide autocomplete functionality and suggest available keywords.
+- Provide definitions of keywords through annotations.
+
+As the rules and keywords for configuring our CI configuration files change, so too
+should our CI schema.
+
+This feature is behind the [`schema_linting`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/config/feature_flags/development/schema_linting.yml)
+feature flag for self-managed instances, and is enabled for GitLab.com.
+
+## JSON Schemas
+
+The CI schema follows the [JSON Schema Draft-07](https://json-schema.org/draft-07/json-schema-release-notes.html)
+specification. Although the CI configuration file is written in YAML, it is converted
+into JSON by using `monaco-yaml` before it is validated by the CI schema.
+
+If you're new to JSON schemas, consider checking out
+[this guide](https://json-schema.org/learn/getting-started-step-by-step) for
+a step-by-step introduction on how to work with JSON schemas.
+
+## Update Keywords
+
+The CI schema is at [`app/assets/javascripts/editor/schema/ci.json`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/assets/javascripts/editor/schema/ci.json).
+It contains all the keywords available for authoring CI configuration files.
+Check the [keyword reference](../../ci/yaml/index.md) for a comprehensive list of
+all available keywords.
+
+All keywords are defined under `definitions`. We use these definitions as
+[references](https://json-schema.org/learn/getting-started-step-by-step#references)
+to share common data structures across the schema.
+
+For example, this defines the `retry` keyword:
+
+```json
+{
+ "definitions": {
+ "retry": {
+ "description": "Retry a job if it fails. Can be a simple integer or object definition.",
+ "oneOf": [
+ {
+ "$ref": "#/definitions/retry_max"
+ },
+ {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max": {
+ "$ref": "#/definitions/retry_max"
+ },
+ "when": {
+ "description": "Either a single or array of error types to trigger job retry.",
+ "oneOf": [
+ {
+ "$ref": "#/definitions/retry_errors"
+ },
+ {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/retry_errors"
+ }
+ }
+ ]
+ }
+ }
+ }
+ ]
+ }
+ }
+}
+```
+
+With this definition, the `retry` keyword is both a property of
+the `job_template` definition and the `default` global keyword. Global keywords
+that configure pipeline behavior (such as `workflow` and `stages`) are defined
+under the topmost **properties** key.
+
+```json
+{
+ "properties": {
+ "default": {
+ "type": "object",
+ "properties": {
+ "retry": {
+ "$ref": "#/definitions/retry"
+ },
+ }
+ }
+ },
+ "definitions": {
+ "job_template": {
+ "properties": {
+ "retry": {
+ "$ref": "#/definitions/retry"
+ }
+ },
+ }
+ }
+}
+```
+
+## Guidelines for updating the schema
+
+- Keep definitions atomic when possible, to be flexible with
+ referencing keywords. For example, `workflow:rules` uses only a subset of
+ properties in the `rules` definition. The `rules` properties have their
+ own definitions, so we can reference them individually.
+- When adding new keywords, consider adding a `description` with a link to the
+ keyword definition in the documentation. This information shows up in the annotations
+ when the user hovers over the keyword.
+- For each property, consider if a `minimum`, `maximum`, or
+ `default` values are required. Some values might be required, and in others we can set
+ blank. In the blank case, we can add the following to the definition:
+
+```json
+{
+ "keyword": {
+ "oneOf": [
+ {
+ "type": "null"
+ },
+ ...
+ ]
+ }
+}
+```
+
+## Test the schema
+
+For now, the CI schema can only be tested manually. To verify the behavior is correct:
+
+1. Enable the `schema_linting` feature flag.
+1. Go to **CI/CD** > **Editor**.
+1. Write your CI/CD configuration in the editor and verify that the schema validates
+ it correctly.
diff --git a/doc/development/cicd/templates.md b/doc/development/cicd/templates.md
index d7edad842b8..c6f59a7e452 100644
--- a/doc/development/cicd/templates.md
+++ b/doc/development/cicd/templates.md
@@ -96,7 +96,7 @@ Additional points to keep in mind when authoring templates:
|------------------------------------------------------|--------------------|---------------|
| Can use global keywords, including `stages`. | Yes | No |
| Can define jobs. | Yes | Yes |
-| Can be selected in the new file UI | Yes | Yes |
+| Can be selected in the new file UI | Yes | No |
| Can include other job templates with `include` | Yes | No |
| Can include other pipeline templates with `include`. | No | No |
@@ -105,6 +105,16 @@ Additional points to keep in mind when authoring templates:
To make templates easier to follow, templates should all use clear syntax styles,
with a consistent format.
+The `before_script`, `script`, and `after_script` keywords of every job are linted
+using [ShellCheck](https://www.shellcheck.net/) and should follow the
+[Shell scripting standards and style guidelines](../shell_scripting_guide/index.md)
+as much as possible.
+
+ShellCheck assumes that the script is designed to run using [Bash](https://www.gnu.org/software/bash/).
+Templates which use scripts for shells that aren't compatible with the Bash ShellCheck
+rules can be excluded from ShellCheck linting. To exclude a script, add it to the
+`EXCLUDED_TEMPLATES` list in [`scripts/lint_templates_bash.rb`](https://gitlab.com/gitlab-org/gitlab/-/tree/master/scripts/lint_templates_bash.rb).
+
#### Do not hardcode the default branch
Use [`$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH`](../../ci/variables/predefined_variables.md)
@@ -219,6 +229,30 @@ job1:
- echo ${ERROR_MESSAGE}
```
+#### Use all-caps naming for non-local variables
+
+If you are expecting a variable to be provided via the CI/CD settings, or via the
+`variables` keyword, that variable must use all-caps naming with underscores (`_`)
+separating words.
+
+```yaml
+.with_login:
+ before_script:
+ # SECRET_TOKEN should be provided via the project settings
+ - docker login -u my-user -p "$SECRET_TOKEN my-registry
+```
+
+Lower-case naming can optionally be used for variables which are defined locally in
+one of the `script` keywords:
+
+```yaml
+job1:
+ script:
+ - response="$(curl "https://example.com/json")"
+ - message="$(echo "$response" | jq -r .message)"
+ - 'echo "Server responded with: $message"'
+```
+
### Backward compatibility
A template might be dynamically included with the `include:template:` keyword. If
diff --git a/doc/development/code_review.md b/doc/development/code_review.md
index 3664ca7642a..ec913df8e4a 100644
--- a/doc/development/code_review.md
+++ b/doc/development/code_review.md
@@ -74,19 +74,27 @@ It picks reviewers and maintainers from the list at the
page, with these behaviors:
1. It doesn't pick people whose Slack or [GitLab status](../user/profile/index.md#set-your-current-status):
- - contains the string 'OOO', 'PTO', 'Parental Leave', or 'Friends and Family'
- - emoji is `:palm_tree:`, `:beach:`, `:beach_umbrella:`, `:beach_with_umbrella:`, `:ferris_wheel:`, `:thermometer:`, `:face_with_thermometer:`, `:red_circle:`, `:bulb:`, `:sun_with_face:`.
- - GitLab user busy indicator is set to true
+ - Contains the string 'OOO', 'PTO', 'Parental Leave', or 'Friends and Family'.
+ - GitLab user **Busy** indicator is set to `True`.
+ - Emoji is any of:
+ - 🌴 `:palm_tree:`
+ - ðŸ–ï¸ `:beach:`, `:beach_umbrella:`, or `:beach_with_umbrella:`
+ - 🎡 `:ferris_wheel:`
+ - ðŸŒ¡ï¸ `:thermometer:`
+ - 🤒 `:face_with_thermometer:`
+ - 🔴 `:red_circle:`
+ - 💡 `:bulb:`
+ - 🌞 `:sun_with_face:`
1. [Trainee maintainers](https://about.gitlab.com/handbook/engineering/workflow/code-review/#trainee-maintainer)
are three times as likely to be picked as other reviewers.
1. Team members whose Slack or [GitLab status](../user/profile/index.md#set-your-current-status) emoji
is 🔵 `:large_blue_circle:` are more likely to be picked. This applies to both reviewers and trainee maintainers.
- - Reviewers with `:large_blue_circle:` are two times as likely to be picked as other reviewers.
- - Trainee maintainers with `:large_blue_circle:` are four times as likely to be picked as other reviewers.
+ - Reviewers with 🔵 `:large_blue_circle:` are two times as likely to be picked as other reviewers.
+ - Trainee maintainers with 🔵 `:large_blue_circle:` are four times as likely to be picked as other reviewers.
1. People whose [GitLab status](../user/profile/index.md#set-your-current-status) emoji
- is 🔶 `:large_orange_diamond:` are half as likely to be picked. This applies to both reviewers and trainee maintainers.
+ is 🔶 `:large_orange_diamond:` or 🔸 `:small_orange_diamond:` are half as likely to be picked. This applies to both reviewers and trainee maintainers.
1. It always picks the same reviewers and maintainers for the same
- branch name (unless their OOO status changes, as in point 1). It
+ branch name (unless their out-of-office (OOO) status changes, as in point 1). It
removes leading `ce-` and `ee-`, and trailing `-ce` and `-ee`, so
that it can be stable for backport branches.
@@ -624,7 +632,7 @@ Enterprise Edition instance. This has some implications:
[added to Omnibus](https://docs.gitlab.com/omnibus/settings/gitlab.yml#adding-a-new-setting-to-gitlabyml).
1. **File system access** is not possible in a [cloud-native architecture](architecture.md#adapting-existing-and-introducing-new-components).
Ensure that we support object storage for any file storage we need to perform. For more
- information, see the [uploads documentation](uploads.md).
+ information, see the [uploads documentation](uploads/index.md).
### Review turnaround time
diff --git a/doc/development/contributing/design.md b/doc/development/contributing/design.md
index efa8d4b0c41..463a7ee0e0b 100644
--- a/doc/development/contributing/design.md
+++ b/doc/development/contributing/design.md
@@ -35,7 +35,7 @@ Check these aspects both when _designing_ and _reviewing_ UI changes.
- Use clear and consistent [terminology](https://design.gitlab.com/content/terminology/).
- Check grammar and spelling.
- Consider help content and follow its [guidelines](https://design.gitlab.com/usability/helping-users/).
-- Request review from the [appropriate Technical Writer](https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers),
+- Request review from the [appropriate Technical Writer](https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments),
indicating any specific files or lines they should review, and how to preview
or understand the location/context of the text from the user's perspective.
diff --git a/doc/development/contributing/issue_workflow.md b/doc/development/contributing/issue_workflow.md
index ad8403d242c..4db686b9b1e 100644
--- a/doc/development/contributing/issue_workflow.md
+++ b/doc/development/contributing/issue_workflow.md
@@ -45,7 +45,7 @@ scheduling into milestones. Labeling is a task for everyone. (For some projects,
Most issues will have labels for at least one of the following:
-- Type. For example: `~"type::feature"`, `~"type::bug"`, or `~"type::tooling"`.
+- Type. For example: `~"type::feature"`, `~"type::bug"`, or `~"type::maintenance"`.
- Stage. For example: `~"devops::plan"` or `~"devops::create"`.
- Group. For example: `~"group::source code"`, `~"group::knowledge"`, or `~"group::editor"`.
- Category. For example: `~"Category:Code Analytics"`, `~"Category:DevOps Reports"`, or `~"Category:Templates"`.
@@ -72,19 +72,7 @@ labels, you can _always_ add the type, stage, group, and often the category/feat
Type labels are very important. They define what kind of issue this is. Every
issue should have one and only one.
-The current type labels are:
-
-- `~"type::feature"`
- - `~"feature::addition"`
- - `~"feature::enhancement"`
-- `~"type::maintenance"`
-- `~"type::bug"`
-- `~"type::tooling"`
- - `~"tooling::pipelines"`
- - `~"tooling::workflow"`
-- `~"support request"`
-- `~meta`
-- `~documentation`
+The current type labels are [available in the handbook](https://about.gitlab.com/handbook/engineering/metrics/#work-type-classification)
A number of type labels have a priority assigned to them, which automatically
makes them float to the top, depending on their importance.
diff --git a/doc/development/contributing/merge_request_workflow.md b/doc/development/contributing/merge_request_workflow.md
index 02148f2a717..a9b4d13ab06 100644
--- a/doc/development/contributing/merge_request_workflow.md
+++ b/doc/development/contributing/merge_request_workflow.md
@@ -81,7 +81,7 @@ request is as follows:
1. If your MR touches code that executes shell commands, reads or opens files, or
handles paths to files on disk, make sure it adheres to the
[shell command guidelines](../shell_commands.md)
-1. If your code needs to handle file storage, see the [uploads documentation](../uploads.md).
+1. If your code needs to handle file storage, see the [uploads documentation](../uploads/index.md).
1. If your merge request adds one or more migrations, make sure to execute all
migrations on a fresh database before the MR is reviewed. If the review leads
to large changes in the MR, execute the migrations again once the review is complete.
@@ -264,8 +264,11 @@ requirements.
1. Peer member testing is optional but recommended when the risk of a change is high. This includes when the changes are [far-reaching](https://about.gitlab.com/handbook/engineering/development/#reducing-the-impact-of-far-reaching-work) or are for [components critical for security](../code_review.md#security).
1. Regressions and bugs are covered with tests that reduce the risk of the issue happening
again.
+1. Code affected by a feature flag is covered by [automated tests with the feature flag enabled and disabled](../feature_flags/index.md#feature-flags-in-tests), or both
+ states are tested as part of peer member testing or as part of the rollout plan.
1. [Performance guidelines](../merge_request_performance_guidelines.md) have been followed.
1. [Secure coding guidelines](https://gitlab.com/gitlab-com/gl-security/security-guidelines) have been followed.
+1. [Application and rate limit guidelines](../merge_request_application_and_rate_limit_guidelines.md) have been followed.
1. [Documented](../documentation/index.md) in the `/doc` directory.
1. [Changelog entry added](../changelog.md), if necessary.
1. Reviewed by relevant reviewers, and all concerns are addressed for Availability, Regressions, and Security. Documentation reviews should take place as soon as possible, but they should not block a merge request.
diff --git a/doc/development/contributing/style_guides.md b/doc/development/contributing/style_guides.md
index da926005466..7a4ebbdbadf 100644
--- a/doc/development/contributing/style_guides.md
+++ b/doc/development/contributing/style_guides.md
@@ -159,25 +159,22 @@ When the number of RuboCop exceptions exceed the default [`exclude-limit` of 15]
we may want to resolve exceptions over multiple commits. To minimize confusion,
we should track our progress through the exception list.
-When auto-generating the `.rubocop_todo.yml` exception list for a particular Cop,
-and more than 15 files are affected, we should add the exception list to
-a different file in the directory `.rubocop_todo/`. For example, the configuration for the cop
-`Gitlab/NamespacedClass` is in `.rubocop_todo/gitlab/namespaced_class.yml`.
-
-This ensures that our list isn't mistakenly removed by another auto generation of
-the `.rubocop_todo.yml`. This also allows us greater visibility into the exceptions
-which are currently being resolved.
-
-One way to generate the initial list is to run the Rake task `rubocop:todo:generate`:
+The preferred way to [generate the initial list or a list for specific RuboCop rules](../rake_tasks.md#generate-initial-rubocop-todo-list)
+is to run the Rake task `rubocop:todo:generate`:
```shell
+# Initial list
bundle exec rake rubocop:todo:generate
+
+# List for specific RuboCop rules
+bundle exec rake 'rubocop:todo:generate[Gitlab/NamespacedClass,Lint/Syntax]'
```
-You can then move the list from the freshly generated `.rubocop_todo.yml` for the Cop being actively
-resolved and place it in the directory `.rubocop_todo/`. In this scenario, do not commit
-auto-generated changes to the `.rubocop_todo.yml`, as an `exclude limit` that is higher than 15
-makes the `.rubocop_todo.yml` hard to parse.
+This Rake task creates or updates the exception list in `.rubocop_todo/`. For
+example, the configuration for the RuboCop rule `Gitlab/NamespacedClass` is
+located in `.rubocop_todo/gitlab/namespaced_class.yml`.
+
+Make sure to commit any changes in `.rubocop_todo/` after running the Rake task.
### Reveal existing RuboCop exceptions
diff --git a/doc/development/contributing/verify/index.md b/doc/development/contributing/verify/index.md
new file mode 100644
index 00000000000..a2bb0eca733
--- /dev/null
+++ b/doc/development/contributing/verify/index.md
@@ -0,0 +1,236 @@
+---
+type: reference, dev
+stage: none
+group: Verify
+---
+
+# Contribute to Verify stage codebase
+
+## What are we working on in Verify?
+
+Verify stage is working on a comprehensive Continuous Integration platform
+integrated into the GitLab product. Our goal is to empower our users to make
+great technical and business decisions, by delivering a fast, reliable, secure
+platform that verifies assumptions that our users make, and check them against
+the criteria defined in CI/CD configuration. They could be unit tests, end-to-end
+tests, benchmarking, performance validation, code coverage enforcement, and so on.
+
+Feedback delivered by GitLab CI/CD makes it possible for our users to make well
+informed decisions about technological and business choices they need to make
+to succeed. Why is Continuous Integration a mission critical product?
+
+GitLab CI/CD is our platform to deliver feedback to our users and customers.
+
+They contribute their continuous integration configuration files
+`.gitlab-ci.yml` to describe the questions they want to get answers for. Each
+time someone pushes a commit or triggers a pipeline we need to find answers for
+very important questions that have been asked in CI/CD configuration.
+
+Failing to answer these questions or, what might be even worse, providing false
+answers, might result in a user making a wrong decision. Such wrong decisions
+can have very severe consequences.
+
+## Core principles of our CI/CD platform
+
+Data produced by the platform should be:
+
+1. Accurate.
+1. Durable.
+1. Accessible.
+
+The platform itself should be:
+
+1. Reliable.
+1. Secure.
+1. Deterministic.
+1. Trustworthy.
+1. Fast.
+1. Simple.
+
+Since the inception of GitLab CI/CD, we have lived by these principles,
+and they serve us and our users well. Some examples of these principles are that:
+
+- The feedback delivered by GitLab CI/CD and data produced by the platform should be accurate.
+ If a job fails and we notify a user that it was successful, it can have severe negative consequences.
+- Feedback needs to be available when a user needs it and data can not disappear unexpectedly when engineers need it.
+- It all doesn’t matter if the platform is not secure and we
+are leaking credentials or secrets.
+- When a user provides a set of preconditions in a form of CI/CD configuration, the result should be deterministic each time a pipeline runs, because otherwise the platform might not be trustworthy.
+- If it is fast, simple to use and has a great UX it will serve our users well.
+
+## Building things in Verify
+
+### Measure before you optimize, and make data-informed decisions
+
+It is very difficult to optimize something that you can not measure. How would you
+know if you succeeded, or how significant the success was? If you are working on
+a performance or reliability improvement, make sure that you measure things before
+you optimize them.
+
+The best way to measure stuff is to add a Prometheus metric. Counters, gauges, and
+histograms are great ways to quickly get approximated results. Unfortunately this
+is not the best way to measure tail latency. Prometheus metrics, especially histograms,
+are usually approximations.
+
+If you have to measure tail latency, like how slow something could be or how
+large a request payload might be, consider adding custom application logs and
+always use structured logging.
+
+It's useful to use profiling and flamegraphs to understand what the code execution
+path truly looks like!
+
+### Strive for simple solutions, avoid clever solutions
+
+It is sometimes tempting to use a clever solution to deliver something more
+quickly. We want to avoid shipping clever code, because it is usually more
+difficult to understand and maintain in the long term. Instead, we want to
+focus on boring solutions that make it easier to evolve the codebase and keep the
+contribution barrier low. We want to find solutions that are as simple as
+possible.
+
+### Do not confuse boring solutions with easy solutions
+
+Boring solutions are sometimes confused with easy solutions. Very often the
+opposite is true. An easy solution might not be simple - for example, a complex
+new library can be included to add a very small functionality that otherwise
+could be implemented quickly - it is easier to include this library than to
+build this thing, but it would bring a lot of complexity into the product.
+
+On the other hand, it is also possible to over-engineer a solution when a simple,
+well tested, and well maintained library is available. In that case using the
+library might make sense. We recognize that we are constantly balancing simple
+and easy solutions, and that finding the right balance is important.
+
+### "Simple" is not mutually exclusive with "flexible"
+
+Building simple things does not mean that more advanced and flexible solutions
+will not be available. A good example here is an expanding complexity of
+writing `.gitlab-ci.yml` configuration. For example, you can use a simple
+method to define an environment name:
+
+```yaml
+deploy:
+ environment: production
+ script: cap deploy
+```
+
+But the `environment` keyword can be also expanded into another level of
+configuration that can offer more flexibility.
+
+```yaml
+deploy:
+ environment:
+ name: review/$CI_COMMIT_REF_SLUG
+ url: https://prod.example.com
+ script: cap deploy
+```
+
+This kind of approach shields new users from the complexities of the platform,
+but still allows them to go deeper if they need to. This approach can be
+applied to many other technical implementations.
+
+### Make things observable
+
+GitLab is a DevOps platform. We popularize DevOps because it helps companies
+be more efficient and achieve better results. One important component of
+DevOps culture is to take ownership over features and code that you are
+building. It is very difficult to do that when you don’t know how your features
+perform and behave in the production environment.
+
+This is why we want to make our features and code observable. It
+should be written in a way that an author can understand how well or how poorly
+the feature or code behaves in the production environment. We usually accomplish
+that by introducing the proper mix of Prometheus metrics and application
+loggers.
+
+**TODO** document when to use Prometheus metrics, when to use loggers. Write a
+few sentences about histograms and counters. Write a few sentences highlighting
+importance of metrics when doing incremental rollouts.
+
+### Protect customer data
+
+Making data produced by our CI/CD platform durable is important. We recognize that
+data generated in the CI/CD by users and customers is
+something important and we must protect it. This data is not only important
+because it can contain important information, we also do have compliance and
+auditing responsibilities.
+
+Therefore we must take extra care when we are writing migrations
+that permanently removes data from our database, or when we are define
+new retention policies.
+
+As a general rule, when you are writing code that is supposed to remove
+data from the database, file system, or object storage, you should get an extra pair
+of eyes on your changes. When you are defining a new retention policy, you
+should double check with PMs and EMs.
+
+### Get your changes reviewed
+
+When your merge request is ready for reviews you must assign
+reviewers and then maintainers. Depending on the complexity of a change, you
+might want to involve the people that know the most about the codebase area you are
+changing. We do have many domain experts in Verify and it is absolutely acceptable to
+ask them to review your code when you are not certain if a reviewer or
+maintainer assigned by the Reviewer Roulette has enough context about the
+change.
+
+The reviewer roulette offers useful suggestions, but as assigning the right
+reviewers is important it should not be done automatically every time. It might
+not make sense to assign someone who knows nothing about the area you are
+updating, because their feedback might be limited to code style and syntax.
+Depending on the complexity and impact of a change, assigning the right people
+to review your changes might be very important.
+
+If you don’t know who to assign, consult `git blame` or ask in the `#verify`
+Slack channel (GitLab team members only).
+
+### Incremental rollouts
+
+After your merge request is merged by a maintainer, it is time to release it to
+users and the wider community. We usually do this with feature flags.
+While not every merge request needs a feature flag, most merge
+requests in Verify should have feature flags. [**TODO** link to docs about what
+needs a feature flag and what doesn’t].
+
+If you already follow the advice on this page, you probably already have a
+few metrics and perhaps a few loggers added that make your new code observable
+in the production environment. You can now use these metrics to incrementally
+roll out your changes!
+
+A typical scenario involves enabling a few features in a few internal projects
+while observing your metrics or loggers. Be aware that there might be a
+small delay involved in ingesting logs in Elastic or Kibana. After you confirm
+the feature works well with internal projects you can start an
+incremental rollout for other projects.
+
+Avoid using "percent of time" incremental rollouts. These are error prone,
+especially when you are checking feature flags in a few places in the codebase
+and you have not memoized the result of a check in a single place.
+
+### Do not cause our Universe to implode
+
+During one of the first GitLab Contributes events we had a discussion about the importance
+of keeping CI/CD pipeline, stage, and job statuses accurate. We considered a hypothetical
+scenario relating to a software being built by one of our [early customers](https://about.gitlab.com/blog/2016/11/23/gitlab-adoption-growing-at-cern/)
+
+> What happens if software deployed to the [Large Hadron Collider (LHC)](https://en.wikipedia.org/wiki/Large_Hadron_Collider),
+> breaks because of a bug in GitLab CI/CD that showed that a pipeline
+> passed, but this data was not accurate and the software deployed was actually
+> invalid? A problem like this could cause the LHC to malfunction, which
+> could generate a new particle that would then cause the universe to implode.
+
+That would be quite an undesirable outcome of a small bug in GitLab CI/CD status
+processing. Please take extra care when you are working on CI/CD statuses,
+we don’t want to implode our Universe!
+
+This is an extreme and unlikely scenario, but presenting data that is not accurate
+can potentially cause a myriad of problems through the
+[butterfly effect](https://en.wikipedia.org/wiki/Butterfly_effect).
+There are much more likely scenarios that
+can have disastrous consequences. GitLab CI/CD is being used by companies
+building medical, aviation, and automotive software. Continuous Integration is
+a mission critical part of software engineering.
+
+When you are working on a subsystem for pipeline processing and transitioning
+CI/CD statuses, request an additional review from a domain expert and hold
+others accountable for doing the same.
diff --git a/doc/development/dangerbot.md b/doc/development/dangerbot.md
index 8da1f5700e5..9bf0fbe1d78 100644
--- a/doc/development/dangerbot.md
+++ b/doc/development/dangerbot.md
@@ -121,12 +121,13 @@ to revert the change before merging!
#### Adding labels via Danger
NOTE:
-This is currently applicable to the [`gitlab-org/gitlab`](https://gitlab.com/gitlab-org/gitlab)
-project only.
+This is applicable to all the projects that use the [`gitlab-dangerfiles` gem](https://rubygems.org/gems/gitlab-dangerfiles).
Danger is often used to improve MR hygiene by adding labels. Instead of calling the
-API directly in your `Dangerfile`, add the labels to the `project_helper.labels_to_add` array.
-The main `Dangerfile` will then take care of adding the labels to the MR with a single API call.
+API directly in your `Dangerfile`, add the labels to `helper.labels_to_add` array (with `helper.labels_to_add << label`
+or `helper.labels_to_add.concat(array_of_labels)`.
+`gitlab-dangerfiles` will then take care of adding the labels to the MR with a single API call after all the rules
+have had the chance to add to `helper.labels_to_add`.
#### Shared rules and plugins
@@ -135,11 +136,30 @@ upstreaming them to the [`gitlab-dangerfiles`](https://gitlab.com/gitlab-org/rub
#### Enable Danger on a project
-To enable the Dangerfile on another existing GitLab project, run the following
-extra steps:
+To enable the Dangerfile on another existing GitLab project, complete the following steps:
-1. Create a [Project access tokens](../user/project/settings/project_access_tokens.md).
-1. Add the token as a CI/CD project variable named `DANGER_GITLAB_API_TOKEN`.
+1. Add [`gitlab-dangerfiles`](https://rubygems.org/gems/gitlab-dangerfiles) to your `Gemfile`.
+1. Create a `Dangerfile` with the following content:
+
+ ```ruby
+ require_relative "lib/gitlab-dangerfiles"
+
+ Gitlab::Dangerfiles.for_project(self, &:import_defaults)
+ ```
+
+1. Add the following to your CI/CD configuration:
+
+ ```yaml
+ include:
+ - project: 'gitlab-org/quality/pipeline-common'
+ file:
+ - '/ci/danger-review.yml'
+ ```
+
+1. If your project is in the `gitlab-org` group, you don't need to set up any token as the `DANGER_GITLAB_API_TOKEN`
+ variable is available at the group level. If not, follow these last steps:
+ 1. Create a [Project access tokens](../user/project/settings/project_access_tokens.md).
+ 1. Add the token as a CI/CD project variable named `DANGER_GITLAB_API_TOKEN`.
You should add the ~"Danger bot" label to the merge request before sending it
for review.
diff --git a/doc/development/database/database_reviewer_guidelines.md b/doc/development/database/database_reviewer_guidelines.md
index bc18e606f21..9d5e4821c9f 100644
--- a/doc/development/database/database_reviewer_guidelines.md
+++ b/doc/development/database/database_reviewer_guidelines.md
@@ -26,7 +26,7 @@ For more information on the database review process, check the [database review
## How to apply for becoming a database reviewer
-Team members are encouraged to self-identify as database domain experts and add it to their [team profile](https://gitlab.com/gitlab-com/www-gitlab-com/-/blob/master/data/team.yml)
+Team members are encouraged to self-identify as database domain experts, and add it to their profile YAML file:
```yaml
projects:
@@ -34,10 +34,11 @@ projects:
- reviewer database
```
-Assign the MR which adds your expertise to the `team.yml` file to a database maintainer
-or the [Database Team's Engineering Manager](https://about.gitlab.com/handbook/engineering/development/enablement/database/).
+Create the merge request [using the "Database reviewer" template](https://gitlab.com/gitlab-com/www-gitlab-com/-/blob/master/.gitlab/merge_request_templates/Database%20reviewer.md),
+adding your expertise your profile YAML file. Assign to a database maintainer or the
+[Database Team's Engineering Manager](https://about.gitlab.com/handbook/engineering/development/enablement/database/).
-Once the `team.yml` update is merged, the [Reviewer roulette](../code_review.md#reviewer-roulette)
+After the `team.yml` update is merged, the [Reviewer roulette](../code_review.md#reviewer-roulette)
may recommend you as a database reviewer.
## Resources for database reviewers
diff --git a/doc/development/database/loose_foreign_keys.md b/doc/development/database/loose_foreign_keys.md
index d08e90683fe..17a825b4812 100644
--- a/doc/development/database/loose_foreign_keys.md
+++ b/doc/development/database/loose_foreign_keys.md
@@ -50,6 +50,107 @@ we can:
NOTE:
For this procedure to work, we must register which tables to clean up asynchronously.
+## The `scripts/decomposition/generate-loose-foreign-key`
+
+We built an automation tool to aid migration of foreign keys into loose foreign keys as part of
+decomposition effort. It presents existing keys and allows chosen foreign keys to be automatically
+converted into loose foreign keys. This ensures consistency between foreign key and loose foreign
+key definitions, and ensures that they are properly tested.
+
+WARNING:
+We strongly advise you to use the automation script for swapping any foreign key to a loose foreign key.
+
+The tool ensures that all aspects of swapping a foreign key are covered. This includes:
+
+- Creating a migration to remove a foreign key.
+- Updating `db/structure.sql` with the new migration.
+- Updating `lib/gitlab/database/gitlab_loose_foreign_keys.yml` to add the new loose foreign key.
+- Creating or updating a model's specs to ensure that the loose foreign key is properly supported.
+- Creating a new branch, commit, push, and creating a merge request on GitLab.com.
+- Creating a merge request template with all the necessary details to validate the safety of the foreign key removal.
+
+The tool is located at `scripts/decomposition/generate-loose-foreign-key`:
+
+```shell
+$ scripts/decomposition/generate-loose-foreign-key -h
+
+Usage: scripts/decomposition/generate-loose-foreign-key [options] <filters...>
+ -c, --cross-schema Show only cross-schema foreign keys
+ -n, --dry-run Do not execute any commands (dry run)
+ -b, --[no-]branch Create or not a new branch
+ -r, --[no-]rspec Create or not a rspecs automatically
+ -m, --milestone MILESTONE Specify custom milestone (current: 14.8)
+ -h, --help Prints this help
+```
+
+For the migration of cross-schema foreign keys, we use the `-c` modifier to show the foreign keys
+yet to migrate:
+
+```shell
+$ scripts/decomposition/generate-loose-foreign-key -c
+Re-creating current test database
+Dropped database 'gitlabhq_test_ee'
+Dropped database 'gitlabhq_geo_test_ee'
+Created database 'gitlabhq_test_ee'
+Created database 'gitlabhq_geo_test_ee'
+
+Showing cross-schema foreign keys (20):
+ ID | HAS_LFK | FROM | TO | COLUMN | ON_DELETE
+ 0 | N | ci_builds | projects | project_id | cascade
+ 1 | N | ci_job_artifacts | projects | project_id | cascade
+ 2 | N | ci_pipelines | projects | project_id | cascade
+ 3 | Y | ci_pipelines | merge_requests | merge_request_id | cascade
+ 4 | N | external_pull_requests | projects | project_id | cascade
+ 5 | N | ci_sources_pipelines | projects | project_id | cascade
+ 6 | N | ci_stages | projects | project_id | cascade
+ 7 | N | ci_pipeline_schedules | projects | project_id | cascade
+ 8 | N | ci_runner_projects | projects | project_id | cascade
+ 9 | Y | dast_site_profiles_pipelines | ci_pipelines | ci_pipeline_id | cascade
+ 10 | Y | vulnerability_feedback | ci_pipelines | pipeline_id | nullify
+ 11 | N | ci_variables | projects | project_id | cascade
+ 12 | N | ci_refs | projects | project_id | cascade
+ 13 | N | ci_builds_metadata | projects | project_id | cascade
+ 14 | N | ci_subscriptions_projects | projects | downstream_project_id | cascade
+ 15 | N | ci_subscriptions_projects | projects | upstream_project_id | cascade
+ 16 | N | ci_sources_projects | projects | source_project_id | cascade
+ 17 | N | ci_job_token_project_scope_links | projects | source_project_id | cascade
+ 18 | N | ci_job_token_project_scope_links | projects | target_project_id | cascade
+ 19 | N | ci_project_monthly_usages | projects | project_id | cascade
+
+To match FK write one or many filters to match against FROM/TO/COLUMN:
+- scripts/decomposition/generate-loose-foreign-key <filter(s)...>
+- scripts/decomposition/generate-loose-foreign-key ci_job_artifacts project_id
+- scripts/decomposition/generate-loose-foreign-key dast_site_profiles_pipelines
+```
+
+The command accepts a list of filters to match from, to, or column for the purpose of the foreign key generation.
+For example, run this to swap all foreign keys for `ci_job_token_project_scope_links` for the
+decomposed database:
+
+```shell
+scripts/decomposition/generate-loose-foreign-key -c ci_job_token_project_scope_links
+```
+
+To swap only the `source_project_id` of `ci_job_token_project_scope_links` for the decomposed database, run:
+
+```shell
+scripts/decomposition/generate-loose-foreign-key -c ci_job_token_project_scope_links source_project_id
+```
+
+To swap all the foreign keys (all having `_id` appended), but not create a new branch (only commit
+the changes) and not create rspecs, run:
+
+```shell
+scripts/decomposition/generate-loose-foreign-key -c --no-branch --no-rspec _id
+```
+
+To swap all foreign keys referencing `projects`, but not create a new branch (only commit the
+changes), run:
+
+```shell
+scripts/decomposition/generate-loose-foreign-key -c --no-branch projects
+```
+
## Example migration and configuration
### Configure the loose foreign key
@@ -148,6 +249,67 @@ end
At this point, the setup phase is concluded. The deleted `projects` records should be automatically
picked up by the scheduled cleanup worker job.
+### Remove the loose foreign key
+
+When the loose foreign key definition is no longer needed (parent table is removed, or FK is restored),
+we need to remove the definition from the YAML file and ensure that we don't leave pending deleted
+records in the database.
+
+1. Remove the loose foreign key definition from the config (`config/gitlab_loose_foreign_keys.yml`).
+1. Remove the deletion tracking trigger from the parent table (if the parent table is still there).
+1. Remove leftover deleted records from the `loose_foreign_keys_deleted_records` table.
+
+Migration for removing the trigger:
+
+```ruby
+class UnTrackProjectRecordChanges < Gitlab::Database::Migration[1.0]
+ include Gitlab::Database::MigrationHelpers::LooseForeignKeyHelpers
+
+ enable_lock_retries!
+
+ def up
+ untrack_record_deletions(:projects)
+ end
+
+ def down
+ track_record_deletions(:projects)
+ end
+end
+```
+
+With the trigger removal, we prevent further records to be inserted in the `loose_foreign_keys_deleted_records`
+table however, there is still a chance for having leftover pending records in the table. These records
+must be removed with an inline data migration.
+
+```ruby
+class RemoveLeftoverProjectDeletions < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ def up
+ loop do
+ result = execute <<~SQL
+ DELETE FROM "loose_foreign_keys_deleted_records"
+ WHERE
+ ("loose_foreign_keys_deleted_records"."partition", "loose_foreign_keys_deleted_records"."id") IN (
+ SELECT "loose_foreign_keys_deleted_records"."partition", "loose_foreign_keys_deleted_records"."id"
+ FROM "loose_foreign_keys_deleted_records"
+ WHERE
+ "loose_foreign_keys_deleted_records"."fully_qualified_table_name" = 'public.projects' AND
+ "loose_foreign_keys_deleted_records"."status" = 1
+ LIMIT 100
+ )
+ SQL
+
+ break if result.cmd_tuples == 0
+ end
+ end
+
+ def down
+ # no-op
+ end
+end
+```
+
## Testing
The "`it has loose foreign keys`" shared example can be used to test the presence of the `ON DELETE` trigger and the
@@ -234,6 +396,12 @@ We considered using these Rails features as an alternative to foreign keys but t
1. These can lead to severe performance degradation as we load all records from PostgreSQL, loop over them in Ruby, and call individual `DELETE` queries.
1. These can miss data as they only cover the case when the `destroy` method is called directly on the model. There are other cases including `delete_all` and cascading deletes from another parent table that could mean these are missed.
+For non-trivial objects that need to clean up data outside the
+database (for example, object storage) where you might wish to use `dependent: :destroy`,
+see alternatives in
+[Avoid `dependent: :nullify` and `dependent: :destroy` across
+databases](./multiple_databases.md#avoid-dependent-nullify-and-dependent-destroy-across-databases).
+
## Risks of loose foreign keys and possible mitigations
In general, the loose foreign keys architecture is eventually consistent and
diff --git a/doc/development/database/multiple_databases.md b/doc/development/database/multiple_databases.md
index 1338e83070f..c9bbf73be55 100644
--- a/doc/development/database/multiple_databases.md
+++ b/doc/development/database/multiple_databases.md
@@ -32,7 +32,7 @@ If you are using GDK, you can follow the following steps:
1. On the GDK root directory, run:
```shell
- gdk config set gitlab.rails.multiple_databases true
+ gdk config set gitlab.rails.databases.ci.enabled true
```
1. Open your `gdk.yml`, and confirm that it has the following lines:
@@ -40,7 +40,9 @@ If you are using GDK, you can follow the following steps:
```yaml
gitlab:
rails:
- multiple_databases: true
+ databases:
+ ci:
+ enabled: true
```
1. Reconfigure GDK:
@@ -623,10 +625,14 @@ outcomes when we switch to decomposed, because now you have some queries
happening outside the transaction and they may be partially applied while the
outer transaction fails, which could lead to surprising bugs.
-If you need to do some cleanup after a `destroy` you will need to choose
-from some of the options above. If all you need to do is cleanup the child
-records themselves from PostgreSQL then you could consider using ["loose foreign
-keys"](loose_foreign_keys.md).
+For non-trivial objects that need to clean up data outside the
+database (for example, object storage), we recommend the setting
+[`dependent: :restrict_with_error`](https://guides.rubyonrails.org/association_basics.html#options-for-has-one-dependent).
+Such objects should be removed explicitly ahead of time. Using `dependent: :restrict_with_error`
+ensures that we forbid destroying the parent object if something is not cleaned up.
+
+If all you need to do is clean up the child records themselves from PostgreSQL,
+consider using [loose foreign keys](loose_foreign_keys.md).
## `config/database.yml`
diff --git a/doc/development/database/strings_and_the_text_data_type.md b/doc/development/database/strings_and_the_text_data_type.md
index a0dda42fdc7..9674deb4603 100644
--- a/doc/development/database/strings_and_the_text_data_type.md
+++ b/doc/development/database/strings_and_the_text_data_type.md
@@ -253,6 +253,26 @@ class ValidateTextLimitMigration < Gitlab::Database::Migration[1.0]
end
```
+## Increasing a text limit constraint on an existing column
+
+Increasing text limits on existing database columns can be safely achieved by first adding the new limit (with a different name),
+and then dropping the previous limit:
+
+```ruby
+class ChangeMaintainerNoteLimitInCiRunner < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ def up
+ add_text_limit :ci_runners, :maintainer_note, 1024, constraint_name: check_constraint_name(:ci_runners, :maintainer_note, 'max_length_1MB')
+ remove_text_limit :ci_runners, :maintainer_note, constraint_name: check_constraint_name(:ci_runners, :maintainer_note, 'max_length')
+ end
+
+ def down
+ # no-op: Danger of failing if there are records with length(maintainer_note) > 255
+ 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)
diff --git a/doc/development/database_review.md b/doc/development/database_review.md
index 8e217725a17..4b5845992b9 100644
--- a/doc/development/database_review.md
+++ b/doc/development/database_review.md
@@ -203,6 +203,12 @@ Include in the MR description:
- Order columns based on the [Ordering Table Columns](ordering_table_columns.md) guidelines.
- Add foreign keys to any columns pointing to data in other tables, including [an index](migration_style_guide.md#adding-foreign-key-constraints).
- Add indexes for fields that are used in statements such as `WHERE`, `ORDER BY`, `GROUP BY`, and `JOIN`s.
+- New tables and columns are not necessarily risky, but over time some access patterns are inherently
+ difficult to scale. To identify these risky patterns in advance, we need to document expectations for
+ access and size. Include in the MR description answers to these questions:
+ - What is the anticipated growth for the new table over the next 3 months, 6 months, 1 year? What assumptions are these based on?
+ - How many reads and writes per hour would you expect this table to have in 3 months, 6 months, 1 year? Under what circumstances are rows updated? What assumptions are these based on?
+ - Based on the anticipated data volume and access patterns, does the new table pose an availability risk to GitLab.com or self-managed instances? Will the proposed design scale to support the needs of GitLab.com and self-managed customers?
#### Preparation when removing columns, tables, indexes, or other structures
@@ -245,6 +251,10 @@ Include in the MR description:
that post migrations are executed post-deployment in production.
- Check [timing guidelines for migrations](migration_style_guide.md#how-long-a-migration-should-take)
- Check migrations are reversible and implement a `#down` method
+- Check new table migrations:
+ - Are the stated access patterns and volume reasonable? Do the assumptions they're based on seem sound? Do these patterns pose risks to stability?
+ - Are the columns [ordered to conserve space](ordering_table_columns.md)?
+ - Are there foreign keys for references to other tables?
- Check data migrations:
- Establish a time estimate for execution on GitLab.com.
- Depending on timing, data migrations can be placed on regular, post-deploy, or background migrations.
diff --git a/doc/development/documentation/graphql_styleguide.md b/doc/development/documentation/graphql_styleguide.md
index 5acc8bda6a6..ad19a40a3f5 100644
--- a/doc/development/documentation/graphql_styleguide.md
+++ b/doc/development/documentation/graphql_styleguide.md
@@ -6,7 +6,7 @@ info: "See the Technical Writers assigned to Development Guidelines: https://abo
description: "Writing styles, markup, formatting, and other standards for GraphQL API's GitLab Documentation."
---
-# GraphQL API
+# Creating a GraphQL example page
GraphQL APIs are different from [RESTful APIs](restful_api_styleguide.md). Reference
information is generated in our [GraphQL reference](../../api/graphql/reference/index.md).
diff --git a/doc/development/documentation/index.md b/doc/development/documentation/index.md
index 5cf7bb74549..66d6beb821f 100644
--- a/doc/development/documentation/index.md
+++ b/doc/development/documentation/index.md
@@ -7,7 +7,7 @@ description: Learn how to contribute to GitLab Documentation.
# GitLab Documentation guidelines
-The GitLab documentation is [intended as the single source of truth (SSOT)](https://about.gitlab.com/handbook/documentation/) for information about how to configure, use, and troubleshoot GitLab. The documentation contains use cases and usage instructions for every GitLab feature, organized by product area and subject. This includes topics and workflows that span multiple GitLab features, and the use of GitLab with other applications.
+The GitLab documentation is [intended as the single source of truth (SSOT)](https://about.gitlab.com/handbook/documentation/) for information about how to configure, use, and troubleshoot GitLab. The documentation contains use cases and usage instructions for every GitLab feature, organized by product area and subject. This includes topics and workflows that span multiple GitLab features and the use of GitLab with other applications.
In addition to this page, the following resources can help you craft and contribute to documentation:
@@ -55,9 +55,9 @@ docs-only merge requests using the following guide:
[Contributions to GitLab docs](workflow.md) are welcome from the entire GitLab community.
-To ensure that GitLab docs are current, there are special processes and responsibilities for all [feature changes](workflow.md), that is development work that impacts the appearance, usage, or administration of a feature.
+To ensure that the GitLab docs are current, there are special processes and responsibilities for all [feature changes](workflow.md), that is development work that impacts the appearance, usage, or administration of a feature.
-However, anyone can contribute [documentation improvements](workflow.md) that are not associated with a feature change. For example, adding a new doc on how to accomplish a use case that's already possible with GitLab or with third-party tools and GitLab.
+However, anyone can contribute [documentation improvements](workflow.md) that are not associated with a feature change. For example, adding a new document on how to accomplish a use case that's already possible with GitLab or with third-party tools and GitLab.
## Markdown and styles
@@ -87,8 +87,8 @@ belongs to, as well as an information block as described below:
- `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:
+ how to contact the Technical Writer associated with the page's stage and
+ group:
```plaintext
To determine the technical writer assigned to the Stage/Group
@@ -116,7 +116,7 @@ The following metadata should be added when a page is moved to another location:
location to which visitors should be redirected for a moved page.
[Learn more](redirects.md).
- `disqus_identifier`: Identifier for Disqus commenting system. Used to keep
- comments with a page that's been moved to a new URL.
+ comments with a page that has been moved to a new URL.
[Learn more](redirects.md#redirections-for-pages-with-disqus-comments).
### Comments metadata
@@ -192,8 +192,8 @@ For example:
1. The change shows up in the 14.5 self-managed release, due to missing the release cutoff
for 14.4.
-The exact cutoff date for each release is flexible, and can be earlier or later
-than expected due to holidays, weekends, or other events. In general, MRs merged
+The exact cutoff date for each release is flexible, and can be sooner or later
+than expected due to holidays, weekends or other events. In general, MRs merged
by the 17th should be present in the release on the 22nd, though it is not guaranteed.
If it is important that a documentation update is present in that month's release,
merge it as early as possible.
@@ -209,7 +209,7 @@ with the following conventions:
- It's relative to the `doc/` directory in the GitLab repository.
- It omits the `.md` extension.
-- It doesn't end with a slash (`/`).
+- It doesn't end with a forward slash (`/`).
The help text follows the [Pajamas guidelines](https://design.gitlab.com/usability/helping-users/#formatting-help-content).
@@ -316,7 +316,7 @@ process. This is configured in the `Dangerfile` in the GitLab repository under
## Automatic screenshot generator
-You can now set up an automatic screenshot generator to take and compress screenshots, with the
+You can now set up an automatic screenshot generator to take and compress screenshots with the
help of a configuration file known as **screenshot generator**.
### Use the tool
diff --git a/doc/development/documentation/redirects.md b/doc/development/documentation/redirects.md
index 8f13048f663..4c748924c67 100644
--- a/doc/development/documentation/redirects.md
+++ b/doc/development/documentation/redirects.md
@@ -27,7 +27,7 @@ Add a redirect to ensure:
- Users see the new page and can update or delete their bookmark.
- External sites can update their links, especially sites that have automation that
- check for redirecting links.
+ checks for redirected links.
- The documentation site global navigation does not link to a missing page.
The links in the global navigation are already tested in the `gitlab-docs` project.
@@ -38,26 +38,28 @@ Technical Writers can help with any questions and can review your change.
There are two types of redirects:
-- Redirect added into the documentation files themselves, for users who
+- [Redirect added into the documentation files themselves](#add-a-redirect), for users who
view the docs in `/help` on self-managed instances. For example,
- [`/help` on GitLab.com](https://gitlab.com/help).
-- [GitLab Pages redirects](../../user/project/pages/redirects.md),
- for users who view the docs on [`docs.gitlab.com`](https://docs.gitlab.com).
+ [`/help` on GitLab.com](https://gitlab.com/help). These must be added in the same
+ MR that renames or moves a doc. Redirects to internal pages expire after three months
+ and redirects to external pages (starting with `https:`) expire after a year.
+- [GitLab Pages redirects](../../user/project/pages/redirects.md), which are added
+ automatically after redirect files expire. They must not be manually added by
+ contributors and expire after nine months. Redirects pointing to external sites
+ are not added to the GitLab Pages redirects.
- The Technical Writing team manages the [process](https://gitlab.com/gitlab-org/technical-writing/-/blob/main/.gitlab/issue_templates/tw-monthly-tasks.md)
- to regularly update and [clean up the redirects](https://gitlab.com/gitlab-org/gitlab-docs/-/blob/main/doc/raketasks.md#clean-up-redirects).
- If you're a contributor, you may add a new redirect, but you don't need to delete
- the old ones. This process is automatic and handled by the Technical
- Writing team.
+Expired redirect files are removed from the documentation projects by the
+[`clean_redirects` Rake task](https://gitlab.com/gitlab-org/gitlab-docs/-/blob/main/doc/raketasks.md#clean-up-redirects),
+as part of the Technical Writing team's [monthly tasks](https://gitlab.com/gitlab-org/technical-writing/-/blob/main/.gitlab/issue_templates/tw-monthly-tasks.md).
+
+## Add a redirect
NOTE:
-If the old page you're renaming doesn't exist in a stable branch, skip the
-following steps and ask a Technical Writer to add the redirect in
-[`redirects.yaml`](https://gitlab.com/gitlab-org/gitlab-docs/-/blob/main/content/_data/redirects.yaml).
-For example, if you add a new page on the 3rd of the month and then rename it before it gets
-added in the stable branch on the 18th, the old page will never be part of the internal `/help`.
-In that case, you can jump straight to the
-[Pages redirect](https://gitlab.com/gitlab-org/gitlab-docs/-/blob/main/doc/maintenance.md#pages-redirects).
+If the renamed page is new, you can sometimes skip the following steps and ask a
+Technical Writer to manually add the redirect to [`redirects.yaml`](https://gitlab.com/gitlab-org/gitlab-docs/-/blob/main/content/_data/redirects.yaml).
+For example, if you add a new page and then rename it before it's added to a release
+on the 18th. The old page is not in any version's `/help` section, so a technical writer
+can jump straight to the [Pages redirect](https://gitlab.com/gitlab-org/gitlab-docs/-/blob/main/doc/maintenance.md#pages-redirects).
To add a redirect:
@@ -87,20 +89,13 @@ To add a redirect:
bundle exec rake "gitlab:docs:redirect[doc/user/search/old_file.md, https://example.com]"
```
- Alternatively, you can omit the arguments and be asked to enter their values:
-
- ```shell
- bundle exec rake gitlab:docs:redirect
- ```
-
- If you don't want to use the Rake task, you can use the following template.
+ - Alternatively, you can omit the arguments and be prompted to enter the values:
- Replace the value of `redirect_to` with the new file path and `YYYY-MM-DD`
- with the date the file should be removed.
+ ```shell
+ bundle exec rake gitlab:docs:redirect
+ ```
- Redirect files that link to docs in internal documentation projects
- are removed after three months. Redirect files that link to external sites are
- removed after one year:
+ If you don't want to use the Rake task, you can use the following template:
```markdown
---
@@ -111,9 +106,14 @@ To add a redirect:
This document was moved to [another location](../path/to/file/index.md).
<!-- This redirect file can be deleted after <YYYY-MM-DD>. -->
- <!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/#move-or-rename-a-page -->
+ <!-- Redirects that point to other docs in the same project expire in three months. -->
+ <!-- Redirects that point to docs in a different project or site (for example, link is not relative and starts with `https:`) expire in one year. -->
+ <!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/redirects.html -->
```
+ - Replace both instances of `../newpath/to/file/index.md` with the new file path.
+ - Replace `YYYY-MM-DD` with the expiry date, as explained in the template.
+
1. If the documentation page being moved has any Disqus comments, follow the steps
described in [Redirections for pages with Disqus comments](#redirections-for-pages-with-disqus-comments).
1. Open a merge request with your changes. If a documentation page
diff --git a/doc/development/documentation/styleguide/index.md b/doc/development/documentation/styleguide/index.md
index 3e9c0177d48..91e9d0c703d 100644
--- a/doc/development/documentation/styleguide/index.md
+++ b/doc/development/documentation/styleguide/index.md
@@ -655,52 +655,39 @@ This is overridden by the [documentation-specific punctuation rules](#punctuatio
## Headings
-- Add only one H1 in each document, by adding `#` at the beginning of
- it (when using Markdown). The `h1` becomes the document `<title>`.
-- Start with an `h2` (`##`), and respect the order `h2` > `h3` > `h4` > `h5` > `h6`.
- Never skip the hierarchy level, such as `h2` > `h4`
-- Avoid putting numbers in headings. Numbers shift, hence documentation anchor
- 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 characters](https://gitlab.com/gitlab-org/gitlab-docs/-/issues/84)
- in headers. Whenever possible, they should be plain and short text.
-- When possible, avoid including words that might change in the future. Changing
+In the Markdown document:
+
+- Add one H1 (`#`) at the start of the page. The `h1` becomes the document `<title>`.
+- After the H1, follow the order `h2` > `h3` > `h4` > `h5` > `h6`.
+- Do not skip a level. For example: `h2` > `h4`.
+- Leave one blank line before and after the heading.
+
+For the heading text, **do**:
+
+- Be clear and direct. Make every word count.
+- Use active verbs for tasks. For example, `Configure GDK` instead of `Configuring GDK`.
+- Talk about what the product does, realistically but from a positive perspective. Instead of
+ `Limitations`, move the content near other similar information. If you must, you can
+ use the title `Known issues`.
+- Use articles and prepositions.
+- Add the [product badge](#product-tier-badges) that corresponds to the license tier.
+- Follow [capitalization](#capitalization) guidelines.
+
+For the heading text, **do not**:
+
+- Use generic words like `Overview` or `Use cases`. Instead, incorporate
+ the information under a concept heading.
+- Use `How it works`. Incorporate this information under a concept, or use a
+ noun followed by `workflow`. For example, `Merge request workflow`.
+- Use `Important Notes`. Incorporate this information closer to where it belongs.
+- Use numbers to indicate steps. If the numbers change, the anchor links changes,
+ which eventually leads to dead links. If you think you must add numbers in headings,
+ at least discuss it with a writer in the merge request.
+- Use words that might change in the future. Changing
a heading changes its anchor URL, which affects other linked pages.
-- When introducing a new document, be careful for the headings to be
- grammatically and syntactically correct. Mention an [assigned technical writer (TW)](https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments)
- for review, based upon the [product category](https://about.gitlab.com/handbook/product/categories/).
- This is to ensure that no document with wrong heading is going live without an
- audit, thus preventing dead links and redirection issues when corrected.
-- Use the context provided by parent section headings. That is, don't repeat the parent heading's text in each
- subsection's heading.
-- Use articles and prepositions in headings where it would make sense in regular text.
-- Leave exactly one blank line before and after a heading.
-- Do not use links in headings.
-- Add the corresponding [product badge](#product-tier-badges) according to the tier the
- feature belongs.
-- Our documentation site search engine prioritizes words used in headings and
- subheadings. Make your subheading titles clear, descriptive, and complete to help
- users find the right example, as shown in the section on [heading titles](#heading-titles).
-- See [Capitalization](#capitalization) for guidelines on capitalizing headings.
-
-### Heading titles
-
-Keep heading titles clear and direct. Make every word count. To accommodate
-search engine optimization (SEO), use the imperative, where possible.
-
-| Do | Don't |
-|:--------------------------------------|:------------------------------------------------------------|
-| Configure GDK | Configuring GDK |
-| GitLab Release and Maintenance Policy | This section covers the GitLab Release and Maintenance Policy |
-| Backport to older releases | Backporting to older releases |
-| GitLab Pages examples | Examples |
-
-For guidelines on capitalizing headings, see the section on [capitalization](#capitalization).
-
-NOTE:
-If you change an existing title, be careful. In-page [anchor links](#anchor-links),
-links in the GitLab application, and links from external sites can break.
+- Repeat text from earlier headings. For example, instead of `Troubleshooting merge requests`,
+ use `Troubleshooting`.
+- Use links.
### Anchor links
@@ -1130,6 +1117,17 @@ copy of `https://gitlab.com/gitlab-org/gitlab`, run in a terminal:
bin/pngquant compress doc/user/img
```
+### Animated images
+
+Sometimes an image with animation (such as an animated GIF)
+can help the reader understand a complicated interaction with the user interface.
+
+However, you should use them sparingly and avoid them when you can.
+Do not use them to replace written descriptions of processes or the product.
+
+If you include an animated image, follow the same size and naming conventions we use for images. If the animated image loops, add at least a three
+second pause to the end of the loop.
+
## Videos
Adding GitLab YouTube video tutorials to the documentation is highly
diff --git a/doc/development/documentation/styleguide/word_list.md b/doc/development/documentation/styleguide/word_list.md
index 2c435cdc69d..c38c6586c3a 100644
--- a/doc/development/documentation/styleguide/word_list.md
+++ b/doc/development/documentation/styleguide/word_list.md
@@ -89,6 +89,14 @@ For example:
Do not use title case **GitLab Agent** or **GitLab Agent for Kubernetes**.
+## agent access token
+
+The token generated when you create an agent for Kubernetes. Use **agent access token**, not:
+
+- registration token
+- secret token
+- authentication token
+
## allow, enable
Try to avoid **allow** and **enable**, unless you are talking about security-related features.
@@ -174,8 +182,7 @@ See also [contractions](index.md#contractions).
Use one word for **checkbox**. Do not use **check box**.
-You **select** (not **check** or **enable**) and **clear** (not **deselect** or **disable**) checkboxes.
-For example:
+You **select** (not **check** or **enable**) and **clear** (not **deselect** or **disable**) checkboxes. For example:
- Select the **Protect environment** checkbox.
- Clear the **Protect environment** checkbox.
@@ -185,6 +192,8 @@ If you must refer to the checkbox, you can say it is selected or cleared. For ex
- Ensure the **Protect environment** checkbox is cleared.
- Ensure the **Protect environment** checkbox is selected.
+(For `deselect`, [Vale](../testing.md#vale) rule: [`SubstitutionWarning.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/.vale/gitlab/SubstitutionWarning.yml))
+
## checkout, check out
Use **check out** as a verb. For the Git command, use `checkout`.
@@ -201,10 +210,6 @@ CI/CD is always uppercase. No need to spell it out on first use.
Use **CI/CD minutes** instead of **CI minutes**, **pipeline minutes**, **pipeline minutes quota**, or
**CI pipeline minutes**. This decision was made in [this issue](https://gitlab.com/gitlab-org/gitlab/-/issues/342813).
-## CI/CD tunnel
-
-Use lowercase for **tunnel** in **CI/CD tunnel**.
-
## click
Do not use **click**. Instead, use **select** with buttons, links, menu items, and lists.
@@ -256,6 +261,11 @@ Do not use **Developer permissions**. A user who is assigned the Developer role
See [the Microsoft style guide](https://docs.microsoft.com/en-us/style-guide/a-z-word-list-term-collections/d/disable-disabled) for guidance on **disable**.
Use **inactive** or **off** instead. ([Vale](../testing.md#vale) rule: [`InclusionAbleism.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/.vale/gitlab/InclusionAbleism.yml))
+
+## disallow
+
+Use **prevent** instead of **disallow**. ([Vale](../testing.md#vale) rule: [`Substitutions.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/.vale/gitlab/Substitutions.yml))
+
## dropdown list
Use **dropdown list** to refer to the UI element. Do not use **dropdown** without **list** after it.
@@ -667,6 +677,10 @@ Do not use [**roles**](#roles) and **permissions** interchangeably. Each user is
Permissions are not the same as [**access levels**](#access-level).
+## personal access token
+
+Use lowercase for **personal access token**.
+
## please
Do not use **please**. For details, see the [Microsoft style guide](https://docs.microsoft.com/en-us/style-guide/a-z-word-list-term-collections/p/please).
@@ -951,6 +965,17 @@ One exception: You can use **we recommend** instead of **it is recommended** or
Do not use **whitelist**. Another option is **allowlist**. ([Vale](../testing.md#vale) rule: [`InclusionCultural.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/.vale/gitlab/InclusionCultural.yml))
+## yet
+
+Do not use **yet** when talking about the product or its features. The documentation describes the product as it is today.
+
+Sometimes you might need to use **yet** when writing a task. If you use
+**yet**, ensure the surrounding phrases are written
+in present tense, active voice.
+
+[View guidance about how to write about future features](index.md#promising-features-in-future-versions).
+([Vale](../testing.md#vale) rule: [`CurrentStatus.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/.vale/gitlab/CurrentStatus.yml))
+
## you, your, yours
Use **you**, **your**, and **yours** instead of [**the user** and **the user's**](#user-users).
diff --git a/doc/development/documentation/testing.md b/doc/development/documentation/testing.md
index 905b44823c3..49fe0aff3c6 100644
--- a/doc/development/documentation/testing.md
+++ b/doc/development/documentation/testing.md
@@ -128,7 +128,7 @@ and you should make sure your version matches the version used by GitLab.
## Update linter configuration
-[Vale configuration](#vale) and [markdownlint configuration](#markdownlint) is under source control in each
+[Vale configuration](#vale) and [markdownlint configuration](#markdownlint) is under source control in each
project, so updates must be committed to each project individually.
We consider the configuration in the `gitlab` project as the source of truth and that's where all updates should
@@ -213,19 +213,19 @@ You can use Vale:
#### Vale result types
-Vale returns three types of results: `suggestion`, `warning`, and `error`:
+Vale returns three types of results:
-- **Suggestion**-level results are writing tips and aren't displayed in CI
- job output. Suggestions don't break CI. See a list of
- [suggestion-level rules](https://gitlab.com/search?utf8=✓&snippets=false&scope=&repository_ref=master&search=path%3Adoc%2F.vale%2Fgitlab+Suggestion%3A&group_id=9970&project_id=278964).
-- **Warning**-level results are [Style Guide](styleguide/index.md) violations, aren't displayed in CI
- job output, and should contain clear explanations of how to resolve the warning.
- Warnings may be technical debt, or can be future error-level test items
- (after the Technical Writing team completes its cleanup). Warnings don't break CI. See a list of
- [warning-level rules](https://gitlab.com/search?utf8=✓&snippets=false&scope=&repository_ref=master&search=path%3Adoc%2F.vale%2Fgitlab+Warning%3A&group_id=9970&project_id=278964).
-- **Error**-level results are Style Guide violations, and should contain clear explanations
- of how to resolve the error. Errors break CI and are displayed in CI job output. See a list of
- [error-level rules](https://gitlab.com/search?utf8=✓&snippets=false&scope=&repository_ref=master&search=path%3Adoc%2F.vale%2Fgitlab+Error%3A&group_id=9970&project_id=278964).
+- **Error** - For branding and trademark issues, and words or phrases with ambiguous meanings.
+- **Warning** - For Technical Writing team style preferences.
+- **Suggestion** - For basic technical writing tenets and best practices.
+
+The result types have these attributes:
+
+| Result type | Displayed in CI/CD job output | Causes CI/CD jobs to fail | Vale rule link |
+|--------------|-------------------------------|---------------------------|----------------|
+| `error` | **{check-circle}** Yes | **{check-circle}** Yes | [Error-level Vale rules](https://gitlab.com/search?utf8=✓&snippets=false&scope=&repository_ref=master&search=path%3Adoc%2F.vale%2Fgitlab+Error%3A&group_id=9970&project_id=278964) |
+| `warning` | **{dotted-circle}** No | **{dotted-circle}** No | [Warning-level Vale rules](https://gitlab.com/search?utf8=✓&snippets=false&scope=&repository_ref=master&search=path%3Adoc%2F.vale%2Fgitlab+Warning%3A&group_id=9970&project_id=278964) |
+| `suggestion` | **{dotted-circle}** No | **{dotted-circle}** No | [Suggestion-level Vale rules](https://gitlab.com/search?utf8=✓&snippets=false&scope=&repository_ref=master&search=path%3Adoc%2F.vale%2Fgitlab+Suggestion%3A&group_id=9970&project_id=278964) |
#### Vale spelling test
@@ -270,12 +270,10 @@ build pipelines:
[used (see `variables:` section)](https://gitlab.com/gitlab-org/gitlab-docs/-/blob/main/.gitlab-ci.yml) when building
the `image:docs-lint-markdown`.
-1. Install [`vale`](https://github.com/errata-ai/vale/releases). For example, to install using
- `brew` for macOS, run:
+1. Install [`vale`](https://github.com/errata-ai/vale/releases). To install for:
- ```shell
- brew install vale
- ```
+ - macOS using `brew`, run: `brew install vale`.
+ - Linux, use your distribution's package manager or a [released binary](https://github.com/errata-ai/vale/releases).
These tools can be [integrated with your code editor](#configure-editors).
@@ -313,6 +311,9 @@ To configure Vale in your editor, install one of the following as appropriate:
- Visual Studio Code [`errata-ai.vale-server` extension](https://marketplace.visualstudio.com/items?itemName=errata-ai.vale-server).
You can configure the plugin to [display only a subset of alerts](#show-subset-of-vale-alerts).
- Vim [ALE plugin](https://github.com/dense-analysis/ale).
+- Jetbrains IDEs - No plugin exists, but
+ [this issue comment](https://github.com/errata-ai/vale-server/issues/39#issuecomment-751714451)
+ contains tips for configuring an external tool.
- Emacs [Flycheck extension](https://github.com/flycheck/flycheck).
This requires some configuration:
diff --git a/doc/development/ee_features.md b/doc/development/ee_features.md
index 17e35d34ec7..5bd830715f5 100644
--- a/doc/development/ee_features.md
+++ b/doc/development/ee_features.md
@@ -16,6 +16,13 @@ info: To determine the technical writer assigned to the Stage/Group associated w
[EE features list](https://about.gitlab.com/features/).
<!-- markdownlint-enable MD044 -->
+## Act as SaaS
+
+When developing locally, there are times when you need your instance to act like the SaaS version of the product.
+In those instances, you can simulate SaaS by exporting an environment variable as seen below:
+
+`export GITLAB_SIMULATE_SAAS=1`
+
## Act as CE when unlicensed
Since the implementation of
@@ -437,6 +444,69 @@ resolve when you add the indentation to the equation.
EE-specific views should be placed in `ee/app/views/`, using extra
sub-directories if appropriate.
+#### Using `render_if_exists`
+
+Instead of using regular `render`, we should use `render_if_exists`, which
+doesn't render anything if it cannot find the specific partial. We use this
+so that we could put `render_if_exists` in CE, keeping code the same between
+CE and EE.
+
+The advantages of this:
+
+- Very clear hints about where we're extending EE views while reading CE code.
+
+The disadvantage of this:
+
+- If we have typos in the partial name, it would be silently ignored.
+
+##### Caveats
+
+The `render_if_exists` view path argument must be relative to `app/views/` and `ee/app/views`.
+Resolving an EE template path that is relative to the CE view path doesn't work.
+
+```haml
+- # app/views/projects/index.html.haml
+
+= render_if_exists 'button' # Will not render `ee/app/views/projects/_button` and will quietly fail
+= render_if_exists 'projects/button' # Will render `ee/app/views/projects/_button`
+```
+
+#### Using `render_ce`
+
+For `render` and `render_if_exists`, they search for the EE partial first,
+and then CE partial. They would only render a particular partial, not all
+partials with the same name. We could take the advantage of this, so that
+the same partial path (for example, `shared/issuable/form/default_templates`) could
+be referring to the CE partial in CE (that is,
+`app/views/shared/issuable/form/_default_templates.html.haml`), while EE
+partial in EE (that is,
+`ee/app/views/shared/issuable/form/_default_templates.html.haml`). This way,
+we could show different things between CE and EE.
+
+However sometimes we would also want to reuse the CE partial in EE partial
+because we might just want to add something to the existing CE partial. We
+could workaround this by adding another partial with a different name, but it
+would be tedious to do so.
+
+In this case, we could as well just use `render_ce` which would ignore any EE
+partials. One example would be
+`ee/app/views/shared/issuable/form/_default_templates.html.haml`:
+
+```haml
+- if @project.feature_available?(:issuable_default_templates)
+ = render_ce 'shared/issuable/form/default_templates'
+- elsif show_promotions?
+ = render 'shared/promotions/promote_issue_templates'
+```
+
+In the above example, we can't use
+`render 'shared/issuable/form/default_templates'` because it would find the
+same EE partial, causing infinite recursion. Instead, we could use `render_ce`
+so it ignores any partials in `ee/` and then it would render the CE partial
+(that is, `app/views/shared/issuable/form/_default_templates.html.haml`)
+for the same path (that is, `shared/issuable/form/default_templates`). This way
+we could easily wrap around the CE partial.
+
### Code in `lib/gitlab/background_migration/`
When you create EE-only background migrations, you have to plan for users that
@@ -518,69 +588,6 @@ module EE
end
```
-#### Using `render_if_exists`
-
-Instead of using regular `render`, we should use `render_if_exists`, which
-doesn't render anything if it cannot find the specific partial. We use this
-so that we could put `render_if_exists` in CE, keeping code the same between
-CE and EE.
-
-The advantages of this:
-
-- Very clear hints about where we're extending EE views while reading CE code.
-
-The disadvantage of this:
-
-- If we have typos in the partial name, it would be silently ignored.
-
-##### Caveats
-
-The `render_if_exists` view path argument must be relative to `app/views/` and `ee/app/views`.
-Resolving an EE template path that is relative to the CE view path doesn't work.
-
-```haml
-- # app/views/projects/index.html.haml
-
-= render_if_exists 'button' # Will not render `ee/app/views/projects/_button` and will quietly fail
-= render_if_exists 'projects/button' # Will render `ee/app/views/projects/_button`
-```
-
-#### Using `render_ce`
-
-For `render` and `render_if_exists`, they search for the EE partial first,
-and then CE partial. They would only render a particular partial, not all
-partials with the same name. We could take the advantage of this, so that
-the same partial path (for example, `shared/issuable/form/default_templates`) could
-be referring to the CE partial in CE (that is,
-`app/views/shared/issuable/form/_default_templates.html.haml`), while EE
-partial in EE (that is,
-`ee/app/views/shared/issuable/form/_default_templates.html.haml`). This way,
-we could show different things between CE and EE.
-
-However sometimes we would also want to reuse the CE partial in EE partial
-because we might just want to add something to the existing CE partial. We
-could workaround this by adding another partial with a different name, but it
-would be tedious to do so.
-
-In this case, we could as well just use `render_ce` which would ignore any EE
-partials. One example would be
-`ee/app/views/shared/issuable/form/_default_templates.html.haml`:
-
-```haml
-- if @project.feature_available?(:issuable_default_templates)
- = render_ce 'shared/issuable/form/default_templates'
-- elsif show_promotions?
- = render 'shared/promotions/promote_issue_templates'
-```
-
-In the above example, we can't use
-`render 'shared/issuable/form/default_templates'` because it would find the
-same EE partial, causing infinite recursion. Instead, we could use `render_ce`
-so it ignores any partials in `ee/` and then it would render the CE partial
-(that is, `app/views/shared/issuable/form/_default_templates.html.haml`)
-for the same path (that is, `shared/issuable/form/default_templates`). This way
-we could easily wrap around the CE partial.
-
### Code in `lib/`
Place EE-specific logic in the top-level `EE` module namespace. Namespace the
diff --git a/doc/development/emails.md b/doc/development/emails.md
index 5361282334f..b8e390988bd 100644
--- a/doc/development/emails.md
+++ b/doc/development/emails.md
@@ -13,6 +13,9 @@ If a mailer argument needs to be added or removed, it is important to ensure
both backward and forward compatibility. Adhere to the Sidekiq steps for
[changing the arguments for a worker](sidekiq/compatibility_across_updates.md#changing-the-arguments-for-a-worker).
+The same applies to a new mailer method, or a new mailer. If you introduce either,
+follow the steps for [adding new workers](sidekiq/compatibility_across_updates.md#adding-new-workers).
+
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.
diff --git a/doc/development/event_store.md b/doc/development/event_store.md
index c6d553f41cd..b00a824e2eb 100644
--- a/doc/development/event_store.md
+++ b/doc/development/event_store.md
@@ -262,7 +262,7 @@ module Gitlab
end
```
-A worker that is only defined in the EE codebase can subscribe to an event in the same way by
+A worker that is only defined in the EE codebase can subscribe to an event in the same way by
declaring the subscription in `ee/lib/ee/gitlab/event_store.rb`.
Subscriptions are stored in memory when the Rails app is loaded and they are immediately frozen.
diff --git a/doc/development/experiment_guide/experimentation.md b/doc/development/experiment_guide/experimentation.md
index bb782af80cc..28100564555 100644
--- a/doc/development/experiment_guide/experimentation.md
+++ b/doc/development/experiment_guide/experimentation.md
@@ -6,4 +6,6 @@ remove_date: '2022-04-13'
This document was moved to [another location](gitlab_experiment.md).
<!-- This redirect file can be deleted after <2022-04-13>. -->
-<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/#move-or-rename-a-page -->
+<!-- Redirects that point to other docs in the same project expire in three months. -->
+<!-- Redirects that point to docs in a different project or site (for example, link is not relative and starts with `https:`) expire in one year. -->
+<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/redirects.html -->
diff --git a/doc/development/experiment_guide/gitlab_experiment.md b/doc/development/experiment_guide/gitlab_experiment.md
index 369690ba86c..78e1f84d701 100644
--- a/doc/development/experiment_guide/gitlab_experiment.md
+++ b/doc/development/experiment_guide/gitlab_experiment.md
@@ -317,7 +317,7 @@ of tracking an event in Ruby would be:
experiment(:pill_color, actor: current_user).track(:clicked)
```
-When you run an experiment with any of the examples so far, an `:assigned` event
+When you run an experiment with any of the examples so far, an `:assignment` event
is tracked automatically by default. All events that are tracked from an
experiment have a special
[experiment context](https://gitlab.com/gitlab-org/iglu/-/blob/master/public/schemas/com.gitlab/gitlab_experiment/jsonschema/1-0-3)
@@ -448,7 +448,7 @@ The first way is simply by running the experiment. Assuming the experiment has b
The second way doesn't run the experiment and is intended to be used if the experiment only needs to surface in the client layer. To accomplish this we can simply `.publish` the experiment. This won't run any logic, but does surface the experiment details in the client layer so they can be utilized there.
-An example might be to publish an experiment in a `before_action` in a controller. Assuming we've defined the `PillColorExperiment` class, like we have above, we can surface it to the client by publishing it instead of running it:
+An example might be to publish an experiment in a `before_action` in a controller. Assuming we've defined the `PillColorExperiment` class, like we have above, we can surface it to the client by publishing it instead of running it:
```ruby
before_action -> { experiment(:pill_color).publish }, only: [:show]
diff --git a/doc/development/experiment_guide/index.md b/doc/development/experiment_guide/index.md
index 254c136ef79..c34e5eb36dc 100644
--- a/doc/development/experiment_guide/index.md
+++ b/doc/development/experiment_guide/index.md
@@ -64,3 +64,15 @@ We recommend the following workflow:
1. **If the experiment is a success**, designers add the new icon or illustration to the Pajamas UI kit as part of the cleanup process.
Engineers can then add it to the [SVG library](https://gitlab-org.gitlab.io/gitlab-svgs/) and modify the implementation based on the
[Frontend Development Guidelines](../fe_guide/icons.md#usage-in-hamlrails-2).
+
+## Turn off all experiments
+
+When there is a case on GitLab.com (SaaS) that necessitates turning off all experiments, we have this control.
+
+You can toggle experiments on SaaS on and off using the `gitlab_experiment` [feature flag](../feature_flags).
+
+This can be done via chatops:
+
+- [disable](../feature_flags/controls.md#disabling-feature-flags): `/chatops run feature set gitlab_experiment false`
+- [enable](../feature_flags/controls.md#process): `/chatops run feature delete gitlab_experiment`
+ - This allows the `default_enabled` [value of true in the yml](https://gitlab.com/gitlab-org/gitlab/-/blob/016430f6751b0c34abb24f74608c80a1a8268f20/config/feature_flags/ops/gitlab_experiment.yml#L8) to be honored.
diff --git a/doc/development/export_csv.md b/doc/development/export_csv.md
index ff827023a50..998e5b1fb3b 100644
--- a/doc/development/export_csv.md
+++ b/doc/development/export_csv.md
@@ -1,7 +1,7 @@
---
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
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
# Export to CSV
diff --git a/doc/development/fe_guide/content_editor.md b/doc/development/fe_guide/content_editor.md
index 139825655e9..2e64f52651e 100644
--- a/doc/development/fe_guide/content_editor.md
+++ b/doc/development/fe_guide/content_editor.md
@@ -47,7 +47,7 @@ The Content Editor requires two properties:
- `renderMarkdown` is an asynchronous function that returns the response (String) of invoking the
[Markdown API](../../api/markdown.md).
-- `uploadsPath` is a URL that points to a [GitLab upload service](../uploads.md#upload-encodings)
+- `uploadsPath` is a URL that points to a [GitLab upload service](../uploads/implementation.md#upload-encodings)
with `multipart/form-data` support.
See the [`WikiForm.vue`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/assets/javascripts/pages/shared/wikis/components/wiki_form.vue#L207)
diff --git a/doc/development/fe_guide/icons.md b/doc/development/fe_guide/icons.md
index 3f7490b0221..d107af156db 100644
--- a/doc/development/fe_guide/icons.md
+++ b/doc/development/fe_guide/icons.md
@@ -88,50 +88,36 @@ Please use the following function inside JS to render an icon:
### Usage in HAML/Rails
-To insert a loading spinner in HAML or Rails use the `loading_icon` helper:
+To insert a loading spinner in HAML or Rails use the `gl_loading_icon` helper:
```haml
-= loading_icon
+= gl_loading_icon
```
-You can include one or more of the following properties with the `loading_icon` helper, as demonstrated
+You can include one or more of the following properties with the `gl_loading_icon` helper, as demonstrated
by the examples that follow:
-- `container` (optional): wraps the loading icon in a container, which centers the loading icon using the `text-center` CSS property.
-- `color` (optional): either `orange` (default), `light`, or `dark`.
+- `inline` (optional): uses in an inline element if `true`, otherwise, a block element (default), with the spinner centered.
+- `color` (optional): either `dark` (default) or `light`.
- `size` (optional): either `sm` (default), `md`, `lg`, or `xl`.
-- `css_class` (optional): defaults to an empty string, but can be used for utility classes to fine-tune alignment or spacing.
+- `css_class` (optional): defaults to nothing, but can be used for utility classes to fine-tune alignment or spacing.
**Example 1:**
The following HAML expression generates a loading icon's markup and
-centers the icon by wrapping it in a `gl-spinner-container` element.
+centers the icon.
```haml
-= loading_icon(container: true)
-```
-
-**Output from example 1:**
-
-```html
-<div class="gl-spinner-container">
- <span class="gl-spinner gl-spinner-orange gl-spinner-sm" aria-label="Loading"></span>
-</div>
+= gl_loading_icon
```
**Example 2:**
-The following HAML expression generates a loading icon's markup
+The following HAML expression generates an inline loading icon's markup
with a custom size. It also appends a margin utility class.
```haml
-= loading_icon(size: 'lg', css_class: 'gl-mr-2')
-```
-
-**Output from example 2:**
-
-```html
-<span class="gl-spinner gl-spinner-orange gl-spinner-lg gl-mr-2" aria-label="Loading"></span>
+= gl_loading_icon(inline: true, size: 'lg', css_class: 'gl-mr-2')
```
### Usage in Vue
diff --git a/doc/development/fe_guide/style/javascript.md b/doc/development/fe_guide/style/javascript.md
index 4a0923ebe19..d04d1879476 100644
--- a/doc/development/fe_guide/style/javascript.md
+++ b/doc/development/fe_guide/style/javascript.md
@@ -136,7 +136,7 @@ the class name with `js-`.
## ES Module Syntax
-For most JavaScript files, use ES module syntax to import or export from modules.
+For most JavaScript files, use ES module syntax to import or export from modules.
Prefer named exports, as they improve name consistency.
```javascript
diff --git a/doc/development/fe_guide/vue3_migration.md b/doc/development/fe_guide/vue3_migration.md
index 6e994d5e95d..f174408c946 100644
--- a/doc/development/fe_guide/vue3_migration.md
+++ b/doc/development/fe_guide/vue3_migration.md
@@ -6,12 +6,10 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Migration to Vue 3
-Preparations for a Vue 3 migration are tracked in epic [&3174](https://gitlab.com/groups/gitlab-org/-/epics/3174)
+The migration from Vue 2 to 3 is tracked in epic [&6252](https://gitlab.com/groups/gitlab-org/-/epics/6252).
-In order to prepare for the eventual migration to Vue 3.x, we should not use the following deprecated features in the codebase:
-
-NOTE:
-Our linting rules block the use of these deprecated features.
+To ease migration to Vue 3.x, we have added [eslint rules](https://gitlab.com/gitlab-org/frontend/eslint-plugin/-/merge_requests/50)
+that prevent us from using the following deprecated features in the codebase.
## Vue filters
diff --git a/doc/development/feature_flags/controls.md b/doc/development/feature_flags/controls.md
index 6bf5be23ace..f8f03773c12 100644
--- a/doc/development/feature_flags/controls.md
+++ b/doc/development/feature_flags/controls.md
@@ -72,8 +72,8 @@ group.
To enable a feature for 25% of the time, run the following in Slack:
```shell
-/chatops run feature set new_navigation_bar 25 --dev
-/chatops run feature set new_navigation_bar 25 --staging
+/chatops run feature set new_navigation_bar 25 --random --dev
+/chatops run feature set new_navigation_bar 25 --random --staging
```
### Enabling a feature for GitLab.com
@@ -121,7 +121,7 @@ command you make so people can understand the change if they need to.
To enable a feature for 25% of the time, run the following in Slack:
```shell
-/chatops run feature set new_navigation_bar 25
+/chatops run feature set new_navigation_bar 25 --random
```
This sets a feature flag to `true` based on the following formula:
diff --git a/doc/development/feature_flags/index.md b/doc/development/feature_flags/index.md
index af402713f6e..4b417b26381 100644
--- a/doc/development/feature_flags/index.md
+++ b/doc/development/feature_flags/index.md
@@ -530,8 +530,9 @@ Feature.remove(:feature_flag_name)
## Feature flags in tests
Introducing a feature flag into the codebase creates an additional code path that should be tested.
-It is strongly advised to test all code affected by a feature flag, both when **enabled** and **disabled**
-to ensure the feature works properly.
+It is strongly advised to include automated tests for all code affected by a feature flag, both when **enabled** and **disabled**
+to ensure the feature works properly. If automated tests are not included for both states, the functionality associated
+with the untested code path should be manually tested before deployment to production.
When using the testing environment, all feature flags are enabled by default.
diff --git a/doc/development/feature_flags/process.md b/doc/development/feature_flags/process.md
index 3fbb207a12b..f98366beb6b 100644
--- a/doc/development/feature_flags/process.md
+++ b/doc/development/feature_flags/process.md
@@ -6,4 +6,6 @@ remove_date: '2022-03-01'
This document was moved to [another location](https://about.gitlab.com/handbook/product-development-flow/feature-flag-lifecycle/).
<!-- This redirect file can be deleted after 2022-03-01. -->
-<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/#move-or-rename-a-page -->
+<!-- Redirects that point to other docs in the same project expire in three months. -->
+<!-- Redirects that point to docs in a different project or site (for example, link is not relative and starts with `https:`) expire in one year. -->
+<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/redirects.html -->
diff --git a/doc/development/features_inside_dot_gitlab.md b/doc/development/features_inside_dot_gitlab.md
index 283a0d5d5fb..7b11b541b5a 100644
--- a/doc/development/features_inside_dot_gitlab.md
+++ b/doc/development/features_inside_dot_gitlab.md
@@ -12,7 +12,7 @@ When implementing new features, please refer to these existing features to avoid
- [Custom Dashboards](../operations/metrics/dashboards/index.md#add-a-new-dashboard-to-your-project): `.gitlab/dashboards/`.
- [Issue Templates](../user/project/description_templates.md#create-an-issue-template): `.gitlab/issue_templates/`.
- [Merge request Templates](../user/project/description_templates.md#create-a-merge-request-template): `.gitlab/merge_request_templates/`.
-- [GitLab Agent](https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent/-/blob/master/doc/configuration_repository.md#layout): `.gitlab/agents/`.
+- [GitLab agent](https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent/-/blob/master/doc/configuration_repository.md#layout): `.gitlab/agents/`.
- [CODEOWNERS](../user/project/code_owners.md#set-up-code-owners): `.gitlab/CODEOWNERS`.
- [Route Maps](../ci/review_apps/#route-maps): `.gitlab/route-map.yml`.
- [Customize Auto DevOps Helm Values](../topics/autodevops/customize.md#customize-values-for-helm-chart): `.gitlab/auto-deploy-values.yaml`.
diff --git a/doc/development/file_storage.md b/doc/development/file_storage.md
index d161206f44d..04e2f381c97 100644
--- a/doc/development/file_storage.md
+++ b/doc/development/file_storage.md
@@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
We use the [CarrierWave](https://github.com/carrierwaveuploader/carrierwave) gem to handle file upload, store and retrieval.
-File uploads should be accelerated by workhorse, for details please refer to [uploads development documentation](uploads.md).
+File uploads should be accelerated by workhorse, for details please refer to [uploads development documentation](uploads/index.md).
There are many places where file uploading is used, according to contexts:
diff --git a/doc/development/fips_compliance.md b/doc/development/fips_compliance.md
index 0b6d1751668..8fe5af56f9d 100644
--- a/doc/development/fips_compliance.md
+++ b/doc/development/fips_compliance.md
@@ -69,55 +69,10 @@ installation instructions, including the [advanced instructions for RHEL](https:
Note that `asdf` is not used for dependency management because it's essential to
use the RedHat-provided Go compiler and other system dependencies.
-### Working around broken frontend asset compilation
-
-A known bug affects asset compilation with FIPS mode enabled: [issue #322883](https://gitlab.com/gitlab-org/gitlab/-/issues/322883).
-Until this is resolved, working on frontend issues is not feasible. We can still
-work on backend issues by compiling the assets while FIPS is disabled, and
-placing GDK into [static asset mode](https://gitlab.com/gitlab-org/gitlab-development-kit/-/blob/main/doc/configuration.md#webpack-settings):
-
-1. Modify your `gdk.yml` to contain the following:
-
- ```yaml
- webpack:
- host: 127.0.0.1
- port: 3808
- static: true
- ```
-
-1. In the GitLab repository, apply this patch to prevent the assets from being
- automatically deleted whenever GDK is restarted:
-
- ```diff
- diff --git a/scripts/frontend/webpack_dev_server.js b/scripts/frontend/webpack_dev_server.js
- index fbb80c9617d..114720d457c 100755
- --- a/scripts/frontend/webpack_dev_server.js
- +++ b/scripts/frontend/webpack_dev_server.js
- @@ -15,7 +15,7 @@ const baseConfig = {
- // run webpack in compile-once mode and watch for changes
- if (STATIC_MODE) {
- nodemon({
- - exec: `rm -rf public/assets/webpack ; yarn run webpack && exec ruby -run -e httpd public/ -p ${DEV_SERVER_PORT}`,
- + exec: `ruby -run -e httpd public/ -p ${DEV_SERVER_PORT}`,
- watch: [
- 'config/webpack.config.js',
- 'app/assets/javascripts',
- ```
-
-1. Run this command in the GitLab repository to generate the asset files
- to be served:
-
- ```shell
- bin/rails gitlab:assets:compile
- ```
-
-Every time you change a frontend asset, you must re-run this command
-(with FIPS mode disabled) before seeing the changes.
-
### Enable FIPS mode
-After the assets are generated, run this command (as root) and restart the
-virtual machine:
+After GDK and its dependencies are installed, run this command (as
+root) and restart the virtual machine:
```shell
fips-mode-setup --enable
diff --git a/doc/development/foreign_keys.md b/doc/development/foreign_keys.md
index a9edbc68a2e..db8367fe5f5 100644
--- a/doc/development/foreign_keys.md
+++ b/doc/development/foreign_keys.md
@@ -80,6 +80,12 @@ foreign keys to remove the data as this would result in the file system data
being left behind. In such a case you should use a service class instead that
takes care of removing non database data.
+In cases where the relation spans multiple databases you will have even
+further problems using `dependent: :destroy` or the above hooks. You can
+read more about alternatives at [Avoid `dependent: :nullify` and
+`dependent: :destroy` across
+databases](database/multiple_databases.md#avoid-dependent-nullify-and-dependent-destroy-across-databases).
+
## Alternative primary keys with has_one associations
Sometimes a `has_one` association is used to create a one-to-one relationship:
diff --git a/doc/development/geo.md b/doc/development/geo.md
index 9f5fd674d38..f37901754aa 100644
--- a/doc/development/geo.md
+++ b/doc/development/geo.md
@@ -438,3 +438,61 @@ old method:
If you want to add easy Geo replication of a resource you're working
on, check out our [self-service framework](geo/framework.md).
+
+## Geo development workflow
+
+### GET:Geo pipeline
+
+As part of the [package-and-qa](testing_guide/end_to_end/index.md#using-the-package-and-qa-job) pipeline, there is an option to manually trigger a job named `GET:Geo`. This
+pipeline uses [GET](https://gitlab.com/gitlab-org/gitlab-environment-toolkit) to spin up a
+[1k](../administration/reference_architectures/1k_users.md) Geo installation,
+and run the [`gitlab-qa`](https://gitlab.com/gitlab-org/gitlab-qa) Geo scenario against the instance.
+When working on Geo features, it is a good idea to ensure the `qa-geo` job passes in a triggered `GET:Geo pipeline`.
+
+The pipelines that control the provisioning and teardown of the instance are included in The GitLab Environment Toolkit Configs
+[Geo subproject](https://gitlab.com/gitlab-org/quality/gitlab-environment-toolkit-configs/Geo).
+
+When adding new functionality, consider adding new tests to verify the behavior. For steps,
+see the [QA documentation](https://gitlab.com/gitlab-org/gitlab/-/tree/master/qa#writing-tests).
+
+#### Architecture
+
+The pipeline involves the interaction of multiple different projects:
+
+- [GitLab](https://gitlab.com/gitlab-org/gitlab) - The [package-and-qa job](testing_guide/end_to_end/index.md#using-the-package-and-qa-job) is launched from merge requests in this project.
+- [`omnibus-gitlab`](https://gitlab.com/gitlab-org/omnibus-gitlab) - Builds relevant artifacts containing the changes from the triggering merge request pipeline.
+- [GET-Configs/Geo](https://gitlab.com/gitlab-org/quality/gitlab-environment-toolkit-configs/Geo) - Coordinates the lifecycle of a short-lived Geo installation that can be evaluated.
+- [GET](https://gitlab.com/gitlab-org/gitlab-environment-toolkit) - Contains the necessary logic for creating and destroying Geo installations. Used by `GET-Configs/Geo`.
+- [`gitlab-qa`](https://gitlab.com/gitlab-org/gitlab-qa) - Tool for running automated tests against a GitLab instance.
+
+```mermaid
+flowchart TD;
+ GET:Geo-->getcg
+ Provision-->Terraform
+ Configure-->Ansible
+ Geo-->Ansible
+ QA-->gagq
+
+ subgraph "omnibus-gitlab-mirror"
+ GET:Geo
+ end
+
+ subgraph getcg [GitLab-environment-toolkit-configs/Geo]
+ direction LR
+ Generate-terraform-config-->Provision
+ Provision-->Generate-ansible-config
+ Generate-ansible-config-->Configure
+ Configure-->Geo
+ Geo-->QA
+ QA-->Destroy-geo
+ end
+
+ subgraph get [GitLab Environment Toolkit]
+ Terraform
+ Ansible
+ end
+
+ subgraph GitLab QA
+ gagq[GitLab QA Geo Scenario]
+ end
+```
diff --git a/doc/development/gitlab_diagram_overview.odg b/doc/development/gitlab_diagram_overview.odg
deleted file mode 100644
index 9bfc7313ff4..00000000000
--- a/doc/development/gitlab_diagram_overview.odg
+++ /dev/null
Binary files differ
diff --git a/doc/development/go_guide/go_upgrade.md b/doc/development/go_guide/go_upgrade.md
index 889849799bc..a99253b9723 100644
--- a/doc/development/go_guide/go_upgrade.md
+++ b/doc/development/go_guide/go_upgrade.md
@@ -134,7 +134,7 @@ if you need help finding the correct person or labels:
| GitLab Compose Kit | [Issuer Tracker](https://gitlab.com/gitlab-org/gitlab-compose-kit/-/issues) |
| GitLab Container Registry | [Issue Tracker](https://gitlab.com/gitlab-org/container-registry) |
| GitLab Elasticsearch Indexer | [Issue Tracker](https://gitlab.com/gitlab-org/gitlab-elasticsearch-indexer/-/issues) |
-| GitLab Agent Server (KAS) | [Issue Tracker](https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent/-/issues) |
+| GitLab agent server for Kubernetes (KAS) | [Issue Tracker](https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent/-/issues) |
| GitLab Pages | [Issue Tracker](https://gitlab.com/gitlab-org/gitlab-pages/-/issues) |
| GitLab Quality Images | [Issue Tracker](https://gitlab.com/gitlab-org/gitlab-build-images/-/issues) |
| GitLab Shell | [Issue Tracker](https://gitlab.com/gitlab-org/gitlab-shell/-/issues) |
diff --git a/doc/development/gotchas.md b/doc/development/gotchas.md
index fbb6b0219aa..d89dbbcf904 100644
--- a/doc/development/gotchas.md
+++ b/doc/development/gotchas.md
@@ -166,6 +166,18 @@ end
Since Active Record is not calling the `.new` method on model classes to instantiate the objects,
you should use `expect_next_found_instance_of` or `allow_next_found_instance_of` mock helpers to setup mock on objects returned by Active Record query & finder methods._
+It is also possible to set mocks and expectations for multiple instances of the same Active Record model by using the `expect_next_found_(number)_instances_of` and `allow_next_found_(number)_instances_of` helpers, like so;
+
+```ruby
+expect_next_found_2_instances_of(Project) do |project|
+ expect(project).to receive(:add_import_job)
+end
+
+allow_next_found_2_instances_of(Project) do |project|
+ allow(project).to receive(:add_import_job)
+end
+```
+
If we also want to initialize the instance with some particular arguments, we
could also pass it like:
diff --git a/doc/development/i18n/proofreader.md b/doc/development/i18n/proofreader.md
index 76ab00eebfb..7c9777527ef 100644
--- a/doc/development/i18n/proofreader.md
+++ b/doc/development/i18n/proofreader.md
@@ -98,9 +98,11 @@ are very appreciative of the work done by translators and proofreaders!
- Paulo George Gomes Bezerra - [GitLab](https://gitlab.com/paulobezerra), [Crowdin](https://crowdin.com/profile/paulogomes.rep)
- André Gama - [GitLab](https://gitlab.com/andregamma), [Crowdin](https://crowdin.com/profile/ToeOficial)
- Eduardo Addad de Oliveira - [GitLab](https://gitlab.com/eduardoaddad), [Crowdin](https://crowdin.com/profile/eduardoaddad)
+ - Horberlan Brito - [GitLab](https://gitlab.com/horberlan), [Crowdin](https://crowdin.com/profile/horberlan)
- Romanian
- Mircea Pop - [GitLab](https://gitlab.com/eeex), [Crowdin](https://crowdin.com/profile/eex)
- Rareș Pița - [GitLab](https://gitlab.com/dlphin), [Crowdin](https://crowdin.com/profile/dlphin)
+ - Nicolae Liviu - [GitLab](https://gitlab.com/nicklcanada), [Crowdin](https://crowdin.com/profile/nicklcanada)
- Russian
- Nikita Grylov - [GitLab](https://gitlab.com/nixel2007), [Crowdin](https://crowdin.com/profile/nixel2007)
- Alexy Lustin - [GitLab](https://gitlab.com/allustin), [Crowdin](https://crowdin.com/profile/lustin)
@@ -110,6 +112,8 @@ are very appreciative of the work done by translators and proofreaders!
- Iaroslav Postovalov - [GitLab](https://gitlab.com/CMDR_Tvis), [Crowdin](https://crowdin.com/profile/CMDR_Tvis)
- Serbian (Latin and Cyrillic)
- Proofreaders needed.
+- Sinhalese/Sinhala සිංහල
+ - හෙළබස (HelaBasa) - [GitLab](https://gitlab.com/helabasa), [Crowdin](https://crowdin.com/profile/helabasa)
- Slovak
- Proofreaders needed.
- Spanish
diff --git a/doc/development/img/architecture_simplified.png b/doc/development/img/architecture_simplified.png
deleted file mode 100644
index bab673feb4a..00000000000
--- a/doc/development/img/architecture_simplified.png
+++ /dev/null
Binary files differ
diff --git a/doc/development/img/architecture_simplified_v14_9.png b/doc/development/img/architecture_simplified_v14_9.png
new file mode 100644
index 00000000000..dcdb9d7b6ae
--- /dev/null
+++ b/doc/development/img/architecture_simplified_v14_9.png
Binary files differ
diff --git a/doc/development/img/merge_request_reports_v14_7.png b/doc/development/img/merge_request_reports_v14_7.png
new file mode 100644
index 00000000000..282d6f96aa6
--- /dev/null
+++ b/doc/development/img/merge_request_reports_v14_7.png
Binary files differ
diff --git a/doc/development/img/merge_widget_v14_7.png b/doc/development/img/merge_widget_v14_7.png
new file mode 100644
index 00000000000..d5e8ed8df52
--- /dev/null
+++ b/doc/development/img/merge_widget_v14_7.png
Binary files differ
diff --git a/doc/development/import_project.md b/doc/development/import_project.md
index 86e6e04347c..e910983997c 100644
--- a/doc/development/import_project.md
+++ b/doc/development/import_project.md
@@ -127,11 +127,11 @@ A project with that name already exists.
##### `Exception: Error importing repository into (namespace) - No space left on device`
-The disk has insufficient space to complete the import.
+The disk has insufficient space to complete the import.
During import, the tarball is cached in your configured `shared_path` directory. Verify the
disk has enough free space to accommodate both the cached tarball and the unpacked
-project files on disk.
+project files on disk.
### Importing via the Rails console
diff --git a/doc/development/index.md b/doc/development/index.md
index 0501f70b818..048112215fc 100644
--- a/doc/development/index.md
+++ b/doc/development/index.md
@@ -227,7 +227,7 @@ the [reviewer values](https://about.gitlab.com/handbook/engineering/workflow/rev
- [Working with merge request diffs](diffs.md)
- [Approval Rules](approval_rules.md)
- [Repository mirroring](repository_mirroring.md)
-- [File uploads](uploads.md)
+- [Uploads development guide](uploads/index.md)
- [Auto DevOps development guide](auto_devops.md)
- [Renaming features](renaming_features.md)
- [Code Intelligence](code_intelligence/index.md)
@@ -275,6 +275,7 @@ See [database guidelines](database/index.md).
## Integration guides
+- [Integrations development guide](integrations/index.md)
- [Jira Connect app](integrations/jira_connect.md)
- [Security Scanners](integrations/secure.md)
- [Secure Partner Integration](integrations/secure_partner_integration.md)
@@ -329,6 +330,10 @@ See [database guidelines](database/index.md).
- [CI/CD development documentation](cicd/index.md)
- [AppSec development documentation](appsec/index.md)
+## Technical Reference by Group
+
+- [Create: Source Code BE](backend/create_source_code_be/index.md)
+
## Other Development guides
- [Defining relations between files using projections](projections.md)
@@ -338,6 +343,7 @@ See [database guidelines](database/index.md).
- [Dashboards for stage groups](stage_group_dashboards.md)
- [Preventing transient bugs](transient/prevention-patterns.md)
- [GitLab Application SLIs](application_slis/index.md)
+- [Spam protection and CAPTCHA development guide](spam_protection_and_captcha/index.md)
## Other GitLab Development Kit (GDK) guides
diff --git a/doc/development/insert_into_tables_in_batches.md b/doc/development/insert_into_tables_in_batches.md
index cfa0c862471..cd659a3d19b 100644
--- a/doc/development/insert_into_tables_in_batches.md
+++ b/doc/development/insert_into_tables_in_batches.md
@@ -122,7 +122,7 @@ Large parts of ActiveRecord's persistence API are built around the notion of cal
of these callbacks fire in response to model life cycle events such as `save` or `create`.
These callbacks cannot be used with bulk insertions, since they are meant to be called for
every instance that is saved or created. Since these events do not fire when
-records are inserted in bulk, we currently disallow their use.
+records are inserted in bulk, we currently prevent their use.
The specifics around which callbacks are explicitly allowed are defined in
[`BulkInsertSafe`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/models/concerns/bulk_insert_safe.rb).
diff --git a/doc/development/integrations/index.md b/doc/development/integrations/index.md
new file mode 100644
index 00000000000..34ac307c98a
--- /dev/null
+++ b/doc/development/integrations/index.md
@@ -0,0 +1,332 @@
+---
+stage: Ecosystem
+group: Integrations
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
+description: "GitLab's development guidelines for Integrations"
+---
+
+# Integrations development guide **(FREE)**
+
+This page provides development guidelines for implementing [GitLab integrations](../../user/project/integrations/index.md),
+which are part of our [main Rails project](https://gitlab.com/gitlab-org/gitlab).
+
+Also see our [direction page](https://about.gitlab.com/direction/ecosystem/integrations/) for an overview of our strategy around integrations.
+
+This guide is a work in progress. You're welcome to ping `@gitlab-org/ecosystem-stage/integrations`
+if you need clarification or spot any outdated information.
+
+## Add a new integration
+
+### Define the integration
+
+1. Add a new model in `app/models/integrations` extending from `Integration`.
+ - For example, `Integrations::FooBar` in `app/models/integrations/foo_bar.rb`.
+ - For certain types of integrations, you can also build on these base classes:
+ - `Integrations::BaseChatNotification`
+ - `Integrations::BaseIssueTracker`
+ - `Integrations::BaseMonitoring`
+ - `Integrations::BaseSlashCommands`
+ - For integrations that primarily trigger HTTP calls to external services, you can
+ also use the `Integrations::HasWebHook` concern. This reuses the [webhook functionality](../../user/project/integrations/webhooks.md)
+ in GitLab through an associated `ServiceHook` model, and automatically records request logs
+ which can be viewed in the integration settings.
+1. Add the integration's underscored name (`'foo_bar'`) to `Integration::INTEGRATION_NAMES`.
+1. Add the integration as an association on `Project`:
+
+ ```ruby
+ has_one :foo_bar_integration, class_name: 'Integrations::FooBar'
+ ```
+
+1. TEMPORARY: Accommodate the current migration to [rename "services" to "integrations"](#rename-services-to-integrations):
+ - Add the integration's camel-cased name (`'FooBar'`) to `Gitlab::Integrations::StiType::NAMESPACED_INTEGRATIONS`.
+
+### Define properties
+
+Integrations can define arbitrary properties to store their configuration with the class method `Integration.prop_accessor`.
+The values are stored as a serialized JSON hash in the `integrations.properties` column.
+
+For example:
+
+```ruby
+module Integrations
+ class FooBar < Integration
+ prop_accessor :url
+ prop_accessor :tags
+ end
+end
+```
+
+`Integration.prop_accessor` installs accessor methods on the class. Here we would have `#url`, `#url=` and `#url_changed?`, to manage the `url` field. Fields stored in `Integration#properties` should be accessed by these accessors directly on the model, just like other ActiveRecord attributes.
+
+You should always access the properties through their getters, and not interact with the `properties` hash directly.
+You **must not** write to the `properties` hash, you **must** use the generated setter method instead. Direct writes to this
+hash are not persisted.
+
+You should also define validations for all your properties.
+
+Also refer to the section [Customize the frontend form](#customize-the-frontend-form) below to see how these properties
+are exposed in the frontend form for the integration.
+
+There is an alternative approach using `Integration.data_field`, which you may see in other integrations.
+With data fields the values are stored in a separate table per integration. At the moment we don't recommend using this for new integrations.
+
+### Define trigger events
+
+Integrations are triggered by calling their `#execute` method in response to events in GitLab,
+which gets passed a payload hash with details about the event.
+
+The supported events have some overlap with [webhook events](../../user/project/integrations/webhook_events.md),
+and receive the same payload. You can specify the events you're interested in by overriding
+the class method `Integration.supported_events` in your model.
+
+The following events are supported for integrations:
+
+| Event type | Default | Value | Trigger
+|:-----------------------------------------------------------------------------------------------|:--------|:---------------------|:--
+| Alert event | | `alert` | A a new, unique alert is recorded.
+| Commit event | ✓ | `commit` | A commit is created or updated.
+| [Deployment event](../../user/project/integrations/webhook_events.md#deployment-events) | | `deployment` | A deployment starts or finishes.
+| [Issue event](../../user/project/integrations/webhook_events.md#issue-events) | ✓ | `issue` | An issue is created, updated, or closed.
+| [Confidential issue event](../../user/project/integrations/webhook_events.md#issue-events) | ✓ | `confidential_issue` | A confidential issue is created, updated, or closed.
+| [Job event](../../user/project/integrations/webhook_events.md#job-events) | | `job`
+| [Merge request event](../../user/project/integrations/webhook_events.md#merge-request-events) | ✓ | `merge_request` | A merge request is created, updated, or merged.
+| [Comment event](../../user/project/integrations/webhook_events.md#comment-events) | | `comment` | A new comment is added.
+| [Confidential comment event](../../user/project/integrations/webhook_events.md#comment-events) | | `confidential_note` | A new comment on a confidential issue is added.
+| [Pipeline event](../../user/project/integrations/webhook_events.md#pipeline-events) | | `pipeline` | A pipeline status changes.
+| [Push event](../../user/project/integrations/webhook_events.md#push-events) | ✓ | `push` | A push is made to the repository.
+| [Tag push event](../../user/project/integrations/webhook_events.md#tag-events) | ✓ | `tag_push` | New tags are pushed to the repository.
+| Vulnerability event **(ULTIMATE)** | | `vulnerability` | A new, unique vulnerability is recorded.
+| [Wiki page event](../../user/project/integrations/webhook_events.md#wiki-page-events) | ✓ | `wiki_page` | A wiki page is created or updated.
+
+#### Event examples
+
+This example defines an integration that responds to `commit` and `merge_request` events:
+
+```ruby
+module Integrations
+ class FooBar < Integration
+ def self.supported_events
+ %w[commit merge_request]
+ end
+ end
+end
+```
+
+An integration can also not respond to events, and implement custom functionality some other way:
+
+```ruby
+module Integrations
+ class FooBar < Integration
+ def self.supported_events
+ []
+ end
+ end
+end
+```
+
+### Customize the frontend form
+
+The frontend form is generated dynamically based on metadata defined in the model.
+
+By default, the integration form provides:
+
+- A checkbox to enable or disable the integration.
+- Checkboxes for each of the trigger events returned from `Integration#configurable_events`.
+
+You can also add help text at the top of the form by either overriding `Integration#help`,
+or providing a template in `app/views/projects/services/$INTEGRATION_NAME/_help.html.haml`.
+
+To add your custom properties to the form, you can define the metadata for them in `Integration#fields`.
+
+This method should return an array of hashes for each field, where the keys can be:
+
+| Key | Type | Required | Default | Description
+|:---------------|:--------|:---------|:-----------------------------|:--
+| `type:` | string | true | | The type of the form field. Can be `text`, `textarea`, `password`, `checkbox`, or `select`.
+| `name:` | string | true | | The property name for the form field. This must match a `prop_accessor` [defined on the class](#define-properties).
+| `required:` | boolean | false | `false` | Specify if the form field is required or optional.
+| `title:` | string | false | Capitalized value of `name:` | The label for the form field.
+| `placeholder:` | string | false | | A placeholder for the form field.
+| `help:` | string | false | | A help text that displays below the form field.
+
+#### Additional keys for `type: 'checkbox'`
+
+| Key | Type | Required | Default | Description
+|:------------------|:-------|:---------|:------------------|:--
+| `checkbox_label:` | string | false | Value of `title:` | A custom label that displays next to the checkbox.
+
+#### Additional keys for `type: 'select'`
+
+| Key | Type | Required | Default | Description
+|:-----------|:------|:---------|:--------|:--
+| `choices:` | array | true | | A nested array of `[label, value]` tuples.
+
+#### Additional keys for `type: 'password'`
+
+| Key | Type | Required | Default | Description
+|:----------------------------|:-------|:---------|:------------------|:--
+| `non_empty_password_title:` | string | false | Value of `title:` | An alternative label that displays when a value is already stored.
+| `non_empty_password_help:` | string | false | Value of `help:` | An alternative help text that displays when a value is already stored.
+
+#### Frontend form examples
+
+This example defines a required `url` field, and optional `username` and `password` fields:
+
+```ruby
+module Integrations
+ class FooBar < Integration
+ prop_accessor :url, :username, :password
+
+ def fields
+ [
+ {
+ type: 'text',
+ name: 'url',
+ title: s_('FooBarIntegration|Server URL'),
+ placeholder: 'https://example.com/',
+ required: true
+ },
+ {
+ type: 'text',
+ name: 'username',
+ title: s_('FooBarIntegration|Username'),
+ },
+ {
+ type: 'password',
+ name: 'password',
+ title: s_('FoobarIntegration|Password'
+ non_empty_password_title: s_('FooBarIntegration|Enter new password')
+ }
+ ]
+ end
+ end
+end
+```
+
+### Expose the integration in the API
+
+#### REST API
+
+To expose the integration in the [REST API](../../api/integrations.md):
+
+1. Add the integration's class (`::Integrations::FooBar`) to `API::Helpers::IntegrationsHelpers.integration_classes`.
+1. Add all properties that should be exposed to `API::Helpers::IntegrationsHelpers.integrations`.
+1. Update the reference documentation in `doc/api/integrations.md`, add a new section for your integration, and document all properties.
+
+You can also refer to our [REST API style guide](../api_styleguide.md).
+
+#### GraphQL API
+
+Integrations use the `Types::Projects::ServiceType` type by default,
+which only exposes the `type` and `active` properties.
+
+To expose additional properties, you can write a class implementing `ServiceType`:
+
+```ruby
+# in app/graphql/types/project/services/foo_bar_service_type.rb
+module Types
+ module Projects
+ module Services
+ class FooBarServiceType < BaseObject
+ graphql_name 'FooBarService'
+ implements(Types::Projects::ServiceType)
+ authorize :read_project
+
+ field :frobinity,
+ GraphQL::Types::Float,
+ null: true,
+ description: 'The level of frobinity.'
+
+ field :foo_label,
+ GraphQL::Types::String,
+ null: true,
+ description: 'The foo label to apply.'
+ end
+ end
+ end
+end
+```
+
+Each property you want to expose should have a field defined for it. You can also expose any public instance method of the integration.
+
+Contact a member of the Integrations team to discuss the best authorization.
+
+Reference documentation for GraphQL is automatically generated.
+
+You can also refer to our [GraphQL API style guide](../api_graphql_styleguide.md).
+
+## Availability of integrations
+
+By default, integrations are available on the project, group, and instance level.
+Most integrations only act in a project context, but can be still configured
+from the group and instance levels.
+
+For some integrations it can make sense to only make it available on the project level.
+To do that, the integration must be removed from `Integration::INTEGRATION_NAMES` and
+added to `Integration::PROJECT_SPECIFIC_INTEGRATION_NAMES` instead.
+
+When developing a new integration, we also recommend you gate the availability behind a
+[feature flag](../feature_flags/index.md) in `Integration.available_integration_names`.
+
+## Documentation
+
+You can provide help text in the integration form, including links to off-site documentation,
+as described above in [Customize the frontend form](#customize-the-frontend-form). Refer to
+our [usability guidelines](https://design.gitlab.com/usability/helping-users) for help text.
+
+For more detailed documentation, provide a page in `doc/user/project/integrations`,
+and link it from the [Integrations overview](../../user/project/integrations/overview.md).
+
+You can also refer to our general [documentation guidelines](../documentation/index.md).
+
+## Testing
+
+It is often sufficient to add tests for the integration model in `spec/models/integrations`,
+and a factory with example settings in `spec/factories/integrations.rb`.
+
+Each integration is also tested as part of generalized tests. For example, there are feature specs
+that verify that the settings form is rendering correctly for all integrations.
+
+If your integration implements any custom behavior, especially in the frontend, this should be
+covered by additional tests.
+
+You can also refer to our general [testing guidelines](../testing_guide/index.md).
+
+## Internationalization
+
+All UI strings should be prepared for translation by following our [internationalization guidelines](../i18n/externalization.md).
+
+The strings should use the integration name as [namespace](../i18n/externalization.md#namespaces), for example, `s_('FooBarIntegration|My string')`.
+
+## Ongoing migrations and refactorings
+
+The Integrations team is in the process of some larger migrations that developers should be aware of.
+
+### [Rename "services" to "integrations"](https://gitlab.com/groups/gitlab-org/-/epics/2504)
+
+The "integrations" in GitLab were historically called "services", which frequently caused
+confusion with our "service" classes in `app/services`. We sometimes also called
+them "project services" because they were initially only available on projects, which is
+not the case anymore.
+
+We decided to change the naming from "services" and "project services" to "integrations".
+This refactoring is an ongoing effort, and there are still references to the old names in some places.
+
+Developers should be especially aware that we still use the old class names for the STI column
+`integrations.type`. For example, a class `Integrations::FooBar` still stores
+the old name `FooBarService` in the database. This mapping is handled via `Gitlab::Integrations::StiType`
+and should be mostly transparent to the rest of the app.
+
+### [Consolidate integration settings](https://gitlab.com/groups/gitlab-org/-/epics/3955)
+
+We want to unify the way integration properties are defined.
+
+## Integration examples
+
+You can refer to these issues for examples of adding new integrations:
+
+- [Datadog](https://gitlab.com/gitlab-org/gitlab/-/issues/270123): Metrics collector, similar to the Prometheus integration.
+- [EWM/RTC](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/36662): External issue tracker.
+- [Shimo](https://gitlab.com/gitlab-org/gitlab/-/issues/343386): External wiki, similar to the Confluence and External Wiki integrations.
+- [Webex Teams](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/31543): Chat notifications.
+- [ZenTao](https://gitlab.com/gitlab-org/gitlab/-/issues/338178): External issue tracker with custom issue views, similar to the Jira integration.
diff --git a/doc/development/integrations/jira_connect.md b/doc/development/integrations/jira_connect.md
index cfa1fdba699..5391b2c119e 100644
--- a/doc/development/integrations/jira_connect.md
+++ b/doc/development/integrations/jira_connect.md
@@ -65,3 +65,52 @@ If the app install failed, you might need to delete `jira_connect_installations`
1. Open the [database console](https://gitlab.com/gitlab-org/gitlab-development-kit/-/blob/main/doc/howto/postgresql.md#access-postgresql).
1. Run `TRUNCATE TABLE jira_connect_installations CASCADE;`.
+
+#### Not authorized to access the file
+
+If you use Gitpod and you get an error about Jira not being able to access the descriptor file, you might need to make the GDK's port public by following these steps:
+
+1. Open your GitLab workspace in Gitpod.
+1. When the GDK is running, select **Ports** in the bottom-right corner.
+1. On the left sidebar, select the port the GDK is listening to (typically `3000`).
+1. If the port is marked as private, select the lock icon to make it public.
+
+## Test the GitLab OAuth authentication flow
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/81126) in GitLab 14.9 [with a flag](../../administration/feature_flags.md) named `jira_connect_oauth`. Disabled by default.
+
+GitLab for Jira users can authenticate with GitLab using GitLab OAuth.
+
+WARNING:
+This feature is not ready for production use. The feature flag should only be enabled in development.
+
+The following steps describe setting up an environment to test the GitLab OAuth flow:
+
+1. Start a Gitpod session and open the rails console.
+
+ ```shell
+ bundle exec rails console
+ ```
+
+1. Enable the feature flag.
+
+ ```shell
+ Feature.enable(:jira_connect_oauth)
+ ```
+
+1. On your GitLab instance, go to **Admin > Applications**.
+1. Create a new application with the following settings:
+ - Name: `Jira Connect`
+ - Redirect URI: `YOUR_GITPOD_INSTANCE/-/jira_connect/oauth_callbacks`
+ - Scopes: `api`
+ - Trusted: **No**
+ - Confidential: **No**
+1. Copy the Application ID.
+1. Go to [gitpod.io/variables](https://gitpod.io/variables).
+1. Create a new variable named `JIRA_CONNECT_OAUTH_CLIENT_ID`, with a scope of `*/*`, and paste the Application ID as the value.
+
+If you already have an active Gitpod instance, use the following command in the Gitpod terminal to set the environment variable:
+
+```shell
+eval $(gp env -e JIRA_CONNECT_OAUTH_CLIENT_ID=$YOUR_APPLICATION_ID)
+```
diff --git a/doc/development/integrations/secure.md b/doc/development/integrations/secure.md
index 27a166aebf9..11fb06bd128 100644
--- a/doc/development/integrations/secure.md
+++ b/doc/development/integrations/secure.md
@@ -329,18 +329,42 @@ You can find the schemas for these scanners here:
### Enable report validation
-In GitLab 14.10 and later, report validation against the schemas is enabled. To enable report validation for versions earlier than 14.10,
-set [`VALIDATE_SCHEMA`](../../user/application_security/#enable-security-report-validation) to
-`"true"`.
+> [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/354928) in GitLab 14.9, and planned for removal in GitLab 15.0.
+DISCLAIMER:
+This page contains information related to upcoming products, features, and functionality.
+It is important to note that the information presented is for informational purposes only.
+Please do not rely on this information for purchasing or planning purposes.
+As with all projects, the items mentioned on this page are subject to change or delay.
+The development, release, and timing of any products, features, or functionality remain at the
+sole discretion of GitLab Inc.
+In GitLab 15.0 and later, report validation is enabled and enforced. Reports that fail validation
+are not ingested, and an error message displays on the corresponding pipeline.
-Reports that don't pass validation are not ingested by GitLab, and an error message
-displays on the corresponding pipeline.
+In GitLab 14.10 and later, report validation against the schemas is enabled but not enforced.
+Reports that fail validation are ingested but display a warning in the pipeline security tab.
-You should ensure that reports generated by the scanner pass validation against the schema version
-declared in your reports. GitLab uses the
+To enforce report validation for GitLab version 14.10 and earlier, set
+[`VALIDATE_SCHEMA`](../../user/application_security/#enable-security-report-validation) to `"true"`.
+
+### Report validation
+
+You must ensure that reports generated by the scanner pass validation against the schema version
+declared in your reports. Reports that don't pass validation are not ingested by GitLab, and an
+error message displays on the corresponding pipeline.
+
+Reports that use a deprecated version of the secure report schema are ingested but cause a warning
+message to display on the corresponding pipeline. If you see this warning, update your
+analyzer to use the latest available schemas.
+
+After the deprecation period for a schema version, the file is removed from GitLab. Reports that
+declare removed versions are rejected, and an error message displays on the corresponding pipeline.
+
+GitLab uses the
[`json_schemer`](https://www.rubydoc.info/gems/json_schemer) gem to perform validation.
-Ongoing improvements to report validation is tracked [in this epic](https://gitlab.com/groups/gitlab-org/-/epics/6968).
+Ongoing improvements to report validation are tracked [in this epic](https://gitlab.com/groups/gitlab-org/-/epics/6968).
+In the meantime, you can see which versions are supported in the
+[source code](https://gitlab.com/gitlab-org/gitlab/-/blob/08dd756429731a0cca1e27ca9d59eea226398a7d/lib/gitlab/ci/parsers/security/validators/schema_validator.rb#L9-27).
### Report Fields
diff --git a/doc/development/internal_api.md b/doc/development/internal_api.md
deleted file mode 100644
index 7790a5e23e6..00000000000
--- a/doc/development/internal_api.md
+++ /dev/null
@@ -1,9 +0,0 @@
----
-redirect_to: 'internal_api/index.md'
-remove_date: '2022-02-09'
----
-
-This document was moved to [another location](internal_api/index.md).
-
-<!-- This redirect file can be deleted after <2022-02-09>. -->
-<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/#move-or-rename-a-page -->
diff --git a/doc/development/internal_api/index.md b/doc/development/internal_api/index.md
index db978253747..ef58d6c2c44 100644
--- a/doc/development/internal_api/index.md
+++ b/doc/development/internal_api/index.md
@@ -42,7 +42,7 @@ file, and include the token Base64 encoded in a `secret_token` parameter
or in the `Gitlab-Shared-Secret` header.
NOTE:
-The internal API used by GitLab Pages, and GitLab Agent Server (`kas`) uses JSON Web Token (JWT)
+The internal API used by GitLab Pages, and GitLab agent server (`kas`) uses JSON Web Token (JWT)
authentication, which is different from GitLab Shell.
## Git Authentication
@@ -400,25 +400,22 @@ Example response:
}
```
-## GitLab Agent endpoints
+## GitLab agent endpoints
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/41045) in GitLab 13.4.
> - This feature is not deployed on GitLab.com
> - It's not recommended for production use.
-The following endpoints are used by the GitLab Agent Server (`kas`)
+The following endpoints are used by the GitLab agent server (`kas`)
for various purposes.
These endpoints are all authenticated using JWT. The JWT secret is stored in a file
specified in `config/gitlab.yml`. By default, the location is in the root of the
GitLab Rails app in a file called `.gitlab_kas_secret`.
-WARNING:
-The GitLab Agent is under development and is not recommended for production use.
+### GitLab agent information
-### GitLab Agent information
-
-Called from GitLab Agent Server (`kas`) to retrieve agent
+Called from GitLab agent server (`kas`) to retrieve agent
information for the given agent token. This returns the Gitaly connection
information for the agent's project in order for `kas` to fetch and update
the agent's configuration.
@@ -434,9 +431,9 @@ curl --request GET --header "Gitlab-Kas-Api-Request: <JWT token>" \
--header "Authorization: Bearer <agent token>" "http://localhost:3000/api/v4/internal/kubernetes/agent_info"
```
-### GitLab Agent project information
+### GitLab agent project information
-Called from GitLab Agent Server (`kas`) to retrieve project
+Called from GitLab agent server (`kas`) to retrieve project
information for the given agent token. This returns the Gitaly
connection for the requested project. GitLab `kas` uses this to configure
the agent to fetch Kubernetes resources from the project repository to
@@ -460,9 +457,9 @@ curl --request GET --header "Gitlab-Kas-Api-Request: <JWT token>" \
--header "Authorization: Bearer <agent token>" "http://localhost:3000/api/v4/internal/kubernetes/project_info?id=7"
```
-### GitLab Agent usage metrics
+### GitLab agent usage metrics
-Called from GitLab Agent Server (`kas`) to increase the usage
+Called from GitLab agent server (`kas`) to increase the usage
metric counters.
| Attribute | Type | Required | Description |
@@ -481,9 +478,9 @@ curl --request POST --header "Gitlab-Kas-Api-Request: <JWT token>" --header "Con
--data '{"gitops_sync_count":1}' "http://localhost:3000/api/v4/internal/kubernetes/usage_metrics"
```
-### GitLab Agent alert metrics
+### GitLab agent alert metrics
-Called from GitLab Agent Server (KAS) to save alerts derived from Cilium on Kubernetes
+Called from GitLab agent server (KAS) to save alerts derived from Cilium on Kubernetes
Cluster.
| Attribute | Type | Required | Description |
@@ -505,7 +502,7 @@ curl --request POST --header "Gitlab-Kas-Api-Request: <JWT token>" \
### Create Starboard vulnerability
-Called from the GitLab Agent Server (`kas`) to create a security vulnerability
+Called from the GitLab agent server (`kas`) to create a security vulnerability
from a Starboard vulnerability report. This request is idempotent. Multiple requests with the same data
create a single vulnerability. The response contains the UUID of the created vulnerability finding.
@@ -563,7 +560,7 @@ Example response:
### Resolve Starboard vulnerabilities
-Called from the GitLab Agent Server (`kas`) to resolve Starboard security vulnerabilities.
+Called from the GitLab agent server (`kas`) to resolve Starboard security vulnerabilities.
Accepts a list of finding UUIDs and marks all Starboard vulnerabilities not identified by
the list as resolved.
diff --git a/doc/development/internal_users.md b/doc/development/internal_users.md
index 35db2016e1c..95ca593e31e 100644
--- a/doc/development/internal_users.md
+++ b/doc/development/internal_users.md
@@ -42,3 +42,5 @@ Other examples of internal users:
- [Ghost User](../user/profile/account/delete_account.md#associated-records)
- [Support Bot](../user/project/service_desk.md#support-bot-user)
- Visual Review Bot
+- Resource access tokens (including [project access tokens](../user/project/settings/project_access_tokens.md)).
+ These are implemented as `project_bot` users with a `PersonalAccessToken`.
diff --git a/doc/development/kubernetes.md b/doc/development/kubernetes.md
index 45c94019c63..a6d9c754838 100644
--- a/doc/development/kubernetes.md
+++ b/doc/development/kubernetes.md
@@ -136,7 +136,7 @@ Mitigation strategies include:
1. Not allowing redirects to attacker controller resources:
[`Kubeclient::KubeClient`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/kubernetes/kube_client.rb#)
- can be configured to disallow any redirects by passing in
+ can be configured to prevent any redirects by passing in
`http_max_redirects: 0` as an option.
1. Not exposing error messages: by doing so, we
prevent attackers from triggering errors to expose results from
diff --git a/doc/development/licensed_feature_availability.md b/doc/development/licensed_feature_availability.md
index 629d0027ffe..0de3f94cf70 100644
--- a/doc/development/licensed_feature_availability.md
+++ b/doc/development/licensed_feature_availability.md
@@ -17,9 +17,8 @@ feature such as [Related issues](../user/project/issues/related_issues.md) or
[Service Desk](../user/project/service_desk.md),
it should be restricted on namespace scope.
-1. Add the feature symbol on `EES_FEATURES`, `EEP_FEATURES`, or `EEU_FEATURES` constants in
- `ee/app/models/license.rb`. Note that the prefix `EES` signifies Starter, `EEP` signifies
- Premium, and `EEU` signifies Ultimate.
+1. Add the feature symbol on `STARTER_FEATURES`, `PREMIUM_FEATURES`, or `ULTIMATE_FEATURES` constants in
+ `ee/app/models/gitlab_subscriptions/features.rb`.
1. Check using:
```ruby
@@ -33,8 +32,8 @@ However, for features such as [Geo](../administration/geo/index.md) and
to only a subset of projects or namespaces, the check is made directly in
the instance license.
-1. Add the feature symbol on `EES_FEATURES`, `EEP_FEATURES` or `EEU_FEATURES` constants in
- `ee/app/models/license.rb`.
+1. Add the feature symbol to `STARTER_FEATURES`, `PREMIUM_FEATURES` or `ULTIMATE_FEATURES` constants in
+ `ee/app/models/gitlab_subscriptions/features.rb`.
1. Add the same feature symbol to `GLOBAL_FEATURES`.
1. Check using:
diff --git a/doc/development/merge_request_application_and_rate_limit_guidelines.md b/doc/development/merge_request_application_and_rate_limit_guidelines.md
new file mode 100644
index 00000000000..94ae126802a
--- /dev/null
+++ b/doc/development/merge_request_application_and_rate_limit_guidelines.md
@@ -0,0 +1,28 @@
+---
+stage: none
+group: unassigned
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
+---
+
+# Application and rate limit guidelines
+
+GitLab, like most large applications, enforces limits within certain features.
+The absences of limits can affect security, performance, data, or could even
+exhaust the allocated resources for the application.
+
+Every new feature should have safe usage limits included in its implementation.
+Limits are applicable for:
+
+- System-level resource pools such as API requests, SSHD connections, database connections, storage, and so on.
+- Domain-level objects such as CI minutes, groups, sign-in attempts, and so on.
+
+## When limits are required
+
+1. Limits are required if the absence of the limit matches severity 1 - 3 in the severity definitions for [limit-related bugs](https://about.gitlab.com/handbook/engineering/quality/issue-triage/#limit-related-bugs).
+1. [GitLab application limits](../administration/instance_limits.md) documentation must be updated anytime limits are added, removed, or updated.
+
+## Additional reading
+
+- Existing [GitLab application limits](../administration/instance_limits.md)
+- Product processes: [introducing application limits](https://about.gitlab.com/handbook/product/product-processes/#introducing-application-limits)
+- Development docs: [guide for adding application limits](application_limits.md)
diff --git a/doc/development/merge_request_concepts/index.md b/doc/development/merge_request_concepts/index.md
new file mode 100644
index 00000000000..f1dab69543a
--- /dev/null
+++ b/doc/development/merge_request_concepts/index.md
@@ -0,0 +1,62 @@
+---
+type: reference, dev
+stage: create
+group: code_review
+info: "See the Technical Writers assigned to Development Guidelines: https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments-to-development-guidelines"
+---
+
+# Merge Request Concepts
+
+**NOTE**:
+The documentation below is the single source of truth for the merge request terminology and functionality.
+
+## Overview
+
+The merge request is made up of several different key components and ideas that encompass the overall merge request experience. These concepts sometimes have competing and confusing terminology or overlap with other concepts. The concepts this will cover are:
+
+1. Merge widget
+1. Report widgets
+1. Merge checks
+1. Approval rules
+
+### Merge widget
+
+The merge widget is the component of the merge request where the `merge` button exists:
+
+![merge widget](../img/merge_widget_v14_7.png)
+
+This area of the merge request is where all of the options and commit messages are defined prior to merging. It also contains information about what is in the merge request, what issues may be closed, and other important information to the merging process.
+
+### Report widgets
+
+Reports are widgets within the merge request that report information about changes within the merge request. These widgets provide information to better help the author understand the changes and further improvements to the proposed changes.
+
+[Design Documentation](https://design.gitlab.com/regions/merge-request-reports)
+
+![merge request reports](../img/merge_request_reports_v14_7.png)
+
+### Merge checks
+
+Merge checks are statuses that can either pass or fail and conditionally control the availability of the merge button being available within a merge request. The key distinguishing factor in a merge check is that users **do not** interact with the merge checks inside of the merge request, but are able to influence whether or not the check passes or fails. Results from the check are processed as true/false to determine whether or not a merge request can be merged. Examples include:
+
+1. merge conflicts
+1. pipeline success
+1. threads resolution
+1. [external status checks](../../user/project/merge_requests/status_checks.md)
+1. required approvals
+
+When all of the required merge checks are satisfied a merge request becomes mergeable.
+
+### Approvals
+
+Approval rules specify users that are required to or can optionally approve a merge request based on some kind of organizational policy. When approvals are required, they effectively become a required merge check. The key differentiator between merge checks and approval rules is that users **do** interact with approval rules, by deciding to approve the merge request.
+
+Additionally, approval settings provide configuration options to define how those approval rules are applied in a merge request. They can set limitations, add requirements, or modify approvals.
+
+Examples of approval rules and settings include:
+
+1. [merge request approval rules](../../user/project/merge_requests/approvals/rules.md)
+1. [code owner approvals](../../user/project/code_owners.md)
+1. [security approvals](../../user/application_security/index.md#security-approvals-in-merge-requests)
+1. [prevent editing approval rules](../../user/project/merge_requests/approvals/settings.md#prevent-editing-approval-rules-in-merge-requests)]
+1. [remove all approvals when commits are added](../../user/project/merge_requests/approvals/settings.md#remove-all-approvals-when-commits-are-added-to-the-source-branch)
diff --git a/doc/development/merge_request_performance_guidelines.md b/doc/development/merge_request_performance_guidelines.md
index c8e99e8547f..40f02f4fb6f 100644
--- a/doc/development/merge_request_performance_guidelines.md
+++ b/doc/development/merge_request_performance_guidelines.md
@@ -446,49 +446,6 @@ that accepts an upper limit of counting rows.
In some cases it's desired that badge counters are loaded asynchronously.
This can speed up the initial page load and give a better user experience overall.
-## Application/misuse limits
-
-Every new feature should have safe usage quotas introduced.
-The quota should be optimised to a level that we consider the feature to
-be performant and usable for the user, but **not limiting**.
-
-**We want the features to be fully usable for the users.**
-**However, we want to ensure that the feature continues to perform well if used at its limit**
-**and it doesn't cause availability issues.**
-
-Consider that it's always better to start with some kind of limitation,
-instead of later introducing a breaking change that would result in some
-workflows breaking.
-
-The intent is to provide a safe usage pattern for the feature,
-as our implementation decisions are optimised for the given data set.
-Our feature limits should reflect the optimisations that we introduced.
-
-The intent of quotas could be different:
-
-1. We want to provide higher quotas for higher tiers of features:
- we want to provide on GitLab.com more capabilities for different tiers,
-1. We want to prevent misuse of the feature: someone accidentally creates
- 10000 deploy tokens, because of a broken API script,
-1. We want to prevent abuse of the feature: someone purposely creates
- a 10000 pipelines to take advantage of the system.
-
-Examples:
-
-1. Pipeline Schedules: It's very unlikely that user wants to create
- more than 50 schedules.
- In such cases it's rather expected that this is either misuse
- or abuse of the feature. Lack of the upper limit can result
- in service degradation as the system tries to process all schedules
- assigned the project.
-
-1. GitLab CI/CD includes: We started with the limit of maximum of 50 nested includes.
- We understood that performance of the feature was acceptable at that level.
- We received a request from the community that the limit is too small.
- We had a time to understand the customer requirement, and implement an additional
- fail-safe mechanism (time-based one) to increase the limit 100, and if needed increase it
- further without negative impact on availability of the feature and GitLab.
-
## Usage of feature flags
Each feature that has performance critical elements or has a known performance deficiency
@@ -569,7 +526,7 @@ end
The usage of shared temporary storage is required if your intent
is to persistent file for a disk-based storage, and not Object Storage.
-[Workhorse direct_upload](uploads.md#direct-upload) when accepting file
+[Workhorse direct_upload](uploads/implementation.md#direct-upload) when accepting file
can write it to shared storage, and later GitLab Rails can perform a move operation.
The move operation on the same destination is instantaneous.
The system instead of performing `copy` operation just re-attaches file into a new place.
@@ -593,7 +550,7 @@ that implements a seamless support for Shared and Object Storage-based persisten
#### Data access
Each feature that accepts data uploads or allows to download them needs to use
-[Workhorse direct_upload](uploads.md#direct-upload). It means that uploads needs to be
+[Workhorse direct_upload](uploads/implementation.md#direct-upload). It means that uploads needs to be
saved directly to Object Storage by Workhorse, and all downloads needs to be served
by Workhorse.
@@ -605,5 +562,5 @@ can time out, which is especially problematic for slow clients. If clients take
to upload/download the processing slot might be killed due to request processing
timeout (usually between 30s-60s).
-For the above reasons it is required that [Workhorse direct_upload](uploads.md#direct-upload) is implemented
+For the above reasons it is required that [Workhorse direct_upload](uploads/implementation.md#direct-upload) is implemented
for all file uploads and downloads.
diff --git a/doc/development/new_fe_guide/modules/widget_extensions.md b/doc/development/new_fe_guide/modules/widget_extensions.md
index 37712cb2cec..d3cd839464d 100644
--- a/doc/development/new_fe_guide/modules/widget_extensions.md
+++ b/doc/development/new_fe_guide/modules/widget_extensions.md
@@ -128,6 +128,7 @@ mentioned below:
variant: '', // Optional: GitLab UI badge variant, defaults to info
},
actions: [], // Optional: Action button for row
+ children: [], // Optional: Child content to render, structure matches the same structure
}
```
diff --git a/doc/development/packages.md b/doc/development/packages.md
index 38c1b941eaf..35a93c77c7f 100644
--- a/doc/development/packages.md
+++ b/doc/development/packages.md
@@ -151,7 +151,7 @@ During this phase, the idea is to collect as much information as possible about
1. Empty file structure (API file, base service for this package)
1. Authentication system for "logging in" to the package manager
1. Identify metadata and create applicable tables
- 1. Workhorse route for [object storage direct upload](uploads.md#direct-upload)
+ 1. Workhorse route for [object storage direct upload](uploads/implementation.md#direct-upload)
1. Endpoints required for upload/publish
1. Endpoints required for install/download
1. Endpoints required for required actions
@@ -210,7 +210,7 @@ File uploads should be handled by GitLab Workhorse using object accelerated uplo
the workhorse proxy that checks all incoming requests to GitLab intercept the upload request,
upload the file, and forward a request to the main GitLab codebase only containing the metadata
and file location rather than the file itself. An overview of this process can be found in the
-[development documentation](uploads.md#direct-upload).
+[development documentation](uploads/implementation.md#direct-upload).
In terms of code, this means a route must be added to the
[GitLab Workhorse project](https://gitlab.com/gitlab-org/gitlab-workhorse) for each upload endpoint being added
@@ -272,7 +272,7 @@ features must be implemented when the feature flag is removed.
- File format guards (only accept valid file formats for the package type)
- Name regex with validation
- Version regex with validation
-- Workhorse route for [accelerated](uploads.md#how-to-add-a-new-upload-route) uploads
+- Workhorse route for [accelerated](uploads/working_with_uploads.md) uploads
- Background workers for extracting package metadata (if applicable)
- Documentation (how to use the feature)
- API Documentation (individual endpoints with curl examples)
diff --git a/doc/development/performance.md b/doc/development/performance.md
index b5294c8359d..1e3e0570206 100644
--- a/doc/development/performance.md
+++ b/doc/development/performance.md
@@ -7,7 +7,38 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Performance Guidelines
This document describes various guidelines to follow to ensure good and
-consistent performance of GitLab.
+consistent performance of GitLab. Refer to the [Index](#performance-documentation) section below to navigate to Performance-related pages.
+
+## Performance Documentation
+
+- General:
+ - [Solving performance issues](#workflow)
+ - [Handbook performance page](https://about.gitlab.com/handbook/engineering/performance/)
+ - [Merge request performance guidelines](../development/merge_request_performance_guidelines.md)
+- Backend:
+ - [Tooling](#tooling)
+ - Database:
+ - [Query performance guidelines](../development/query_performance.md)
+ - [Pagination performance guidelines](../development/database/pagination_performance_guidelines.md)
+ - [Keyset pagination performance](../development/database/keyset_pagination.md#performance)
+ - [Troubleshooting import/export performance issues](../development/import_export.md#troubleshooting-performance-issues)
+ - [Pipelines performance in the `gitlab` project](../development/pipelines.md#performance)
+- Frontend:
+ - [Performance guidelines](../development/fe_guide/performance.md)
+ - [Performance dashboards and monitoring guidelines](../development/new_fe_guide/development/performance.md)
+ - [Browser performance testing guidelines](../user/project/merge_requests/browser_performance_testing.md)
+ - [`gdk measure` and `gdk measure-workflow`](https://gitlab.com/gitlab-org/gitlab-development-kit/-/blob/main/doc/gdk_commands.md#measure-performance)
+- QA:
+ - [Load performance testing](../user/project/merge_requests/load_performance_testing.md)
+ - [GitLab Performance Tool project](https://gitlab.com/gitlab-org/quality/performance)
+ - [Review apps performance metrics](../development/testing_guide/review_apps.md#performance-metrics)
+- Monitoring & Overview:
+ - [GitLab performance monitoring](../administration/monitoring/performance/index.md)
+ - [Development department performance indicators](https://about.gitlab.com/handbook/engineering/development/performance-indicators/)
+ - [Service measurement](../development/service_measurement.md)
+- Self-managed administration and customer-focused:
+ - [File system performance benchmarking](../administration/operations/filesystem_benchmarking.md)
+ - [Sidekiq performance troubleshooting](../administration/troubleshooting/sidekiq.md)
## Workflow
@@ -95,8 +126,13 @@ end
This however leads to the question: how many iterations should we run to get
meaningful statistics?
-The benchmark-ips Gem basically takes care of all this and much more, and as a
-result of this should be used instead of the `Benchmark` module.
+The [`benchmark-ips`](https://github.com/evanphx/benchmark-ips)
+gem takes care of all this and much more. You should therefore use it instead of the `Benchmark`
+module.
+
+The GitLab Gemfile also contains the [`benchmark-memory`](https://github.com/michaelherold/benchmark-memory)
+gem, which works similarly to the `benchmark` and `benchmark-ips` gems. However, `benchmark-memory`
+instead returns the memory size, objects, and strings allocated and retained during the benchmark.
In short:
@@ -110,7 +146,7 @@ In short:
- If you must write a benchmark use the benchmark-ips Gem instead of Ruby's
`Benchmark` module.
-## Profiling
+## Profiling with Stackprof
By collecting snapshots of process state at regular intervals, profiling allows
you to see where time is spent in a process. The
@@ -124,15 +160,36 @@ frequency (for example, 100hz, that is 100 stacks per second). This type of prof
has quite a low (albeit non-zero) overhead and is generally considered to be
safe for production.
-### Development
-
A profiler can be a very useful tool during development, even if it does run *in
an unrepresentative environment*. In particular, a method is not necessarily
troublesome just because it's executed many times, or takes a long time to
execute. Profiles are tools you can use to better understand what is happening
in an application - using that information wisely is up to you!
-Keeping that in mind, to create a profile, identify (or create) a spec that
+There are multiple ways to create a profile with Stackprof.
+
+### Wrapping a code block
+
+To profile a specific code block, you can wrap that block in a `Stackprof.run` call:
+
+```ruby
+StackProf.run(mode: :wall, out: 'tmp/stackprof-profiling.dump') do
+ #...
+end
+```
+
+This creates a `.dump` file that you can [read](#reading-a-stackprof-profile).
+For all available options, see the [Stackprof documentation](https://github.com/tmm1/stackprof#all-options).
+
+### Performance bar
+
+With the [Performance bar](../administration/monitoring/performance/performance_bar.md),
+you have the option to profile a request using Stackprof and immediately output the results to a
+[Speedscope flamegraph](profiling.md#speedscope-flamegraphs).
+
+### RSpec profiling with Stackprof
+
+To create a profile from a spec, identify (or create) a spec that
exercises the troublesome code path, then run it using the `bin/rspec-stackprof`
helper, for example:
@@ -161,89 +218,10 @@ Finished in 18.19 seconds (files took 4.8 seconds to load)
187 (1.1%) 187 (1.1%) block (4 levels) in class_attribute
```
-You can limit the specs that are run by passing any arguments `rspec` would
+You can limit the specs that are run by passing any arguments `RSpec` would
normally take.
-The output is sorted by the `Samples` column by default. This is the number of
-samples taken where the method is the one currently being executed. The `Total`
-column shows the number of samples taken where the method, or any of the methods
-it calls, were being executed.
-
-To create a graphical view of the call stack:
-
-```shell
-stackprof tmp/project_policy_spec.rb.dump --graphviz > project_policy_spec.dot
-dot -Tsvg project_policy_spec.dot > project_policy_spec.svg
-```
-
-To load the profile in [KCachegrind](https://kcachegrind.github.io/):
-
-```shell
-stackprof tmp/project_policy_spec.rb.dump --callgrind > project_policy_spec.callgrind
-kcachegrind project_policy_spec.callgrind # Linux
-qcachegrind project_policy_spec.callgrind # Mac
-```
-
-For flame graphs, enable raw collection first. Note that raw
-collection can generate a very large file, so increase the `INTERVAL`, or
-run on a smaller number of specs for smaller file size:
-
-```shell
-RAW=true bin/rspec-stackprof spec/policies/group_member_policy_spec.rb
-```
-
-You can then generate, and view the resultant flame graph. It might take a
-while to generate based on the output file size:
-
-```shell
-# Generate
-stackprof --flamegraph tmp/group_member_policy_spec.rb.dump > group_member_policy_spec.flame
-
-# View
-stackprof --flamegraph-viewer=group_member_policy_spec.flame
-```
-
-It may be useful to zoom in on a specific method, for example:
-
-```shell
-$ stackprof tmp/project_policy_spec.rb.dump --method warm_asset_cache
-
-TestEnv#warm_asset_cache (/Users/lupine/dev/gitlab.com/gitlab-org/gitlab-development-kit/gitlab/spec/support/test_env.rb:164)
- samples: 0 self (0.0%) / 6288 total (36.9%)
- callers:
- 6288 ( 100.0%) block (2 levels) in <top (required)>
- callees (6288 total):
- 6288 ( 100.0%) Capybara::RackTest::Driver#visit
- code:
- | 164 | def warm_asset_cache
- | 165 | return if warm_asset_cache?
- | 166 | return unless defined?(Capybara)
- | 167 |
- 6288 (36.9%) | 168 | Capybara.current_session.driver.visit '/'
- | 169 | end
-$ stackprof tmp/project_policy_spec.rb.dump --method BasePolicy#abilities
-BasePolicy#abilities (/Users/lupine/dev/gitlab.com/gitlab-org/gitlab-development-kit/gitlab/app/policies/base_policy.rb:79)
- samples: 0 self (0.0%) / 50 total (0.3%)
- callers:
- 25 ( 50.0%) BasePolicy.abilities
- 25 ( 50.0%) BasePolicy#collect_rules
- callees (50 total):
- 25 ( 50.0%) ProjectPolicy#rules
- 25 ( 50.0%) BasePolicy#collect_rules
- code:
- | 79 | def abilities
- | 80 | return RuleSet.empty if @user && @user.blocked?
- | 81 | return anonymous_abilities if @user.nil?
- 50 (0.3%) | 82 | collect_rules { rules }
- | 83 | end
-```
-
-Since the profile includes the work done by the test suite as well as the
-application code, these profiles can be used to investigate slow tests as well.
-However, for smaller runs (like this example), this means that the cost of
-setting up the test suite tends to dominate.
-
-### Production
+### Using Stackprof in production
Stackprof can also be used to profile production workloads.
@@ -274,8 +252,8 @@ the timeout.
Once profiling stops, the profile is written out to disk at
`$STACKPROF_FILE_PREFIX/stackprof.$PID.$RAND.profile`. It can then be inspected
-further via the `stackprof` command line tool, as described in the previous
-section.
+further through the `stackprof` command line tool, as described in the
+[Reading a Stackprof profile section](#reading-a-stackprof-profile).
Currently supported profiling targets are:
@@ -295,14 +273,85 @@ For Sidekiq, the signal can be sent to the `sidekiq-cluster` process via `pkill
-USR2 bin/sidekiq-cluster`, which forwards the signal to all Sidekiq
children. Alternatively, you can also select a specific PID of interest.
-Production profiles can be especially noisy. It can be helpful to visualize them
-as a [flame graph](https://github.com/brendangregg/FlameGraph). This can be done
-via:
+### Reading a Stackprof profile
+
+The output is sorted by the `Samples` column by default. This is the number of samples taken where
+the method is the one currently executed. The `Total` column shows the number of samples taken where
+the method (or any of the methods it calls) is executed.
+
+To create a graphical view of the call stack:
```shell
-bundle exec stackprof --stackcollapse /tmp/stackprof.55769.c6c3906452.profile | flamegraph.pl > flamegraph.svg
+stackprof tmp/project_policy_spec.rb.dump --graphviz > project_policy_spec.dot
+dot -Tsvg project_policy_spec.dot > project_policy_spec.svg
```
+To load the profile in [KCachegrind](https://kcachegrind.github.io/):
+
+```shell
+stackprof tmp/project_policy_spec.rb.dump --callgrind > project_policy_spec.callgrind
+kcachegrind project_policy_spec.callgrind # Linux
+qcachegrind project_policy_spec.callgrind # Mac
+```
+
+You can also generate and view the resultant flame graph. To view a flame graph that
+`bin/rspec-stackprof` creates, you must set the `RAW` environment variable to `true` when running
+`bin/rspec-stackprof`.
+
+It might take a while to generate based on the output file size:
+
+```shell
+# Generate
+stackprof --flamegraph tmp/group_member_policy_spec.rb.dump > group_member_policy_spec.flame
+
+# View
+stackprof --flamegraph-viewer=group_member_policy_spec.flame
+```
+
+To export the flame graph to an SVG file, use [Brendan Gregg's FlameGraph tool](https://github.com/brendangregg/FlameGraph):
+
+```shell
+stackprof --stackcollapse /tmp/group_member_policy_spec.rb.dump | flamegraph.pl > flamegraph.svg
+```
+
+It's also possible to view flame graphs through [speedscope](https://github.com/jlfwong/speedscope).
+You can do this when using the [performance bar](profiling.md#speedscope-flamegraphs)
+and when [profiling code blocks](https://github.com/jlfwong/speedscope/wiki/Importing-from-stackprof-(ruby)).
+This option isn't supported by `bin/rspec-stackprof`.
+
+You can profile speciific methods by using `--method method_name`:
+
+```shell
+$ stackprof tmp/project_policy_spec.rb.dump --method access_allowed_to
+
+ProjectPolicy#access_allowed_to? (/Users/royzwambag/work/gitlab-development-kit/gitlab/app/policies/project_policy.rb:793)
+ samples: 0 self (0.0%) / 578 total (0.7%)
+ callers:
+ 397 ( 68.7%) block (2 levels) in <class:ProjectPolicy>
+ 95 ( 16.4%) block in <class:ProjectPolicy>
+ 86 ( 14.9%) block in <class:ProjectPolicy>
+ callees (578 total):
+ 399 ( 69.0%) ProjectPolicy#team_access_level
+ 141 ( 24.4%) Project::GeneratedAssociationMethods#project_feature
+ 30 ( 5.2%) DeclarativePolicy::Base#can?
+ 8 ( 1.4%) Featurable#access_level
+ code:
+ | 793 | def access_allowed_to?(feature)
+ 141 (0.2%) | 794 | return false unless project.project_feature
+ | 795 |
+ 8 (0.0%) | 796 | case project.project_feature.access_level(feature)
+ | 797 | when ProjectFeature::DISABLED
+ | 798 | false
+ | 799 | when ProjectFeature::PRIVATE
+ 429 (0.5%) | 800 | can?(:read_all_resources) || team_access_level >= ProjectFeature.required_minimum_access_level(feature)
+ | 801 | else
+```
+
+When using Stackprof to profile specs, the profile includes the work done by the test suite and the
+application code. You can therefore use these profiles to investigate slow tests as well. However,
+for smaller runs (like this example), this means that the cost of setting up the test suite tends to
+dominate.
+
## RSpec profiling
The GitLab development environment also includes the
@@ -459,11 +508,14 @@ The `mem_*` values represent different aspects of how objects and memory are all
We can use `memory_profiler` for profiling.
-The [`memory_profiler`](https://github.com/SamSaffron/memory_profiler) gem is already present in the GitLab `Gemfile`,
-you just need to require it:
+The [`memory_profiler`](https://github.com/SamSaffron/memory_profiler)
+gem is already present in the GitLab `Gemfile`. It's also available in the [performance bar](../administration/monitoring/performance/performance_bar.md)
+for the current URL.
+
+To use the memory profiler directly in your code, use `require` to add it:
```ruby
-require 'sidekiq/testing'
+require 'memory_profiler'
report = MemoryProfiler.report do
# Code you want to profile
@@ -473,10 +525,17 @@ output = File.open('/tmp/profile.txt','w')
report.pretty_print(output)
```
-The report breaks down 2 key concepts:
+The report shows the retained and allocated memory grouped by gem, file, location, and class. The
+memory profiler also performs a string analysis that shows how often a string is allocated and
+retained.
-- Retained: long lived memory use and object count retained due to the execution of the code block.
-- Allocated: all object allocation and memory allocation during code block.
+#### Retained versus allocated
+
+- Retained memory: long-lived memory use and object count retained due to the execution of the code
+ block. This has a direct impact on memory and the garbage collector.
+- Allocated memory: all object allocation and memory allocation during the code block. This might
+ have minimal impact on memory, but substantial impact on performance. The more objects you
+ allocate, the more work is being done and the slower the application is.
As a general rule, **retained** is always smaller than or equal to **allocated**.
@@ -512,6 +571,32 @@ Fragmented Ruby heap snapshot could look like this:
Memory fragmentation could be reduced by tuning GC parameters [as described in this post](https://www.speedshop.co/2017/12/04/malloc-doubles-ruby-memory.html). This should be considered as a tradeoff, as it may affect overall performance of memory allocation and GC cycles.
+### Derailed Benchmarks
+
+`derailed_benchmarks` is a [gem](https://github.com/zombocom/derailed_benchmarks)
+described as "A series of things you can use to benchmark a Rails or Ruby app."
+We include `derailed_benchmarks` in our `Gemfile`.
+
+We run `derailed exec perf:mem` in every pipeline with a `test` stage, in a job
+called `memory-on-boot`. ([Read an example job.](https://gitlab.com/gitlab-org/gitlab/-/jobs/2144695684).)
+You may find the results:
+
+- On the merge request **Overview** tab, in the merge request reports area, in the
+ **Metrics Reports** [dropdown list](../ci/metrics_reports.md).
+- In the `memory-on-boot` artifacts for a full report and a dependency breakdown.
+
+`derailed_benchmarks` also provides other methods to investigate memory. To learn more,
+refer to the [gem documentation](https://github.com/zombocom/derailed_benchmarks#running-derailed-exec).
+Most of the methods (`derailed exec perf:*`) attempt to boot your Rails app in a
+`production` environment and run benchmarks against it.
+It is possible both in GDK and GCK:
+
+- For GDK, follow the
+ [the instructions](https://github.com/zombocom/derailed_benchmarks#running-in-production-locally)
+ on the gem page. You must do similar for Redis configurations to avoid errors.
+- GCK includes `production` configuration sections
+ [out of the box](https://gitlab.com/gitlab-org/gitlab-compose-kit#running-production-like).
+
## Importance of Changes
When working on performance improvements, it's important to always ask yourself
@@ -612,7 +697,7 @@ end
## String Freezing
-In recent Ruby versions calling `freeze` on a String leads to it being allocated
+In recent Ruby versions calling `.freeze` on a String leads to it being allocated
only once and re-used. For example, on Ruby 2.3 or later this only allocates the
"foo" String once:
@@ -626,6 +711,12 @@ Depending on the size of the String and how frequently it would be allocated
(before the `.freeze` call was added), this _may_ make things faster, but
this isn't guaranteed.
+Freezing strings saves memory, as every allocated string uses at least one `RVALUE_SIZE` bytes (40
+bytes on x64) of memory.
+
+You can use the [memory profiler](#using-memory-profiler)
+to see which strings are allocated often and could potentially benefit from a `.freeze`.
+
Strings are frozen by default in Ruby 3.0. To prepare our codebase for
this eventuality, we are adding the following header to all Ruby files:
diff --git a/doc/development/permissions.md b/doc/development/permissions.md
index a5d211a5d2e..47aebc2f4d2 100644
--- a/doc/development/permissions.md
+++ b/doc/development/permissions.md
@@ -9,6 +9,23 @@ info: To determine the technical writer assigned to the Stage/Group associated w
There are multiple types of permissions across GitLab, and when implementing
anything that deals with permissions, all of them should be considered.
+## Instance
+
+### User types
+
+Each user can be one of the following types:
+
+- Regular.
+- External - access to groups and projects only if direct member.
+- [Internal users](internal_users.md) - system created.
+- [Auditor](https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/app/policies/ee/base_policy.rb#L9):
+ - No access to projects or groups settings menu.
+ - No access to Admin Area.
+ - Read-only access to everything else.
+- [Administrator](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/policies/base_policy.rb#L6) - read-write access.
+
+See the [permissions page](../user/permissions.md) for details on how each user type is used.
+
## Groups and Projects
### General permissions
@@ -38,7 +55,7 @@ Additionally, the following project features can have different visibility level
- Issues
- Repository
- - Merge Request
+ - Merge request
- Forks
- Pipelines
- Analytics
@@ -124,9 +141,9 @@ into different features like Merge Requests and CI flow.
| 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 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 | 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 |
| View | License Compliance page | Project | Can access License information|
diff --git a/doc/development/pipelines.md b/doc/development/pipelines.md
index f3a4f47eb22..2aef0e10314 100644
--- a/doc/development/pipelines.md
+++ b/doc/development/pipelines.md
@@ -37,7 +37,7 @@ flowchart LR
subgraph backend
be["Backend code"]--tested with-->rspec
end
-
+
be--generates-->fixtures["frontend fixtures"]
fixtures--used in-->jest
```
@@ -69,7 +69,7 @@ In addition, there are a few circumstances where we would always run the full RS
- when the `pipeline:run-all-rspec` label is set on the merge request
- when the merge request is created by an automation (e.g. Gitaly update or MR targeting a stable branch)
- when the merge request is created in a security mirror
-- when any CI config file is changed (i.e. `.gitlab-ci.yml` or `.gitlab/ci/**/*`)
+- when any CI configuration file is changed (i.e. `.gitlab-ci.yml` or `.gitlab/ci/**/*`)
### Jest minimal jobs
@@ -85,7 +85,7 @@ In addition, there are a few circumstances where we would always run the full Je
- when the `pipeline:run-all-jest` label is set on the merge request
- when the merge request is created by an automation (e.g. Gitaly update or MR targeting a stable branch)
- when the merge request is created in a security mirror
-- when any CI config file is changed (i.e. `.gitlab-ci.yml` or `.gitlab/ci/**/*`)
+- when any CI configuration file is changed (i.e. `.gitlab-ci.yml` or `.gitlab/ci/**/*`)
- when any frontend "core" file is changed (i.e. `package.json`, `yarn.lock`, `babel.config.js`, `jest.config.*.js`, `config/helpers/**/*.js`)
- when any vendored JavaScript file is changed (i.e. `vendor/assets/javascripts/**/*`)
- when any backend file is changed ([see the patterns list for details](https://gitlab.com/gitlab-org/gitlab/-/blob/3616946936c1adbd9e754c1bd06f86ba670796d8/.gitlab/ci/rules.gitlab-ci.yml#L205-216))
@@ -194,6 +194,14 @@ We keep track of retried tests in the `$RETRIED_TESTS_REPORT_FILE` file saved as
See the [experiment issue](https://gitlab.com/gitlab-org/quality/team-tasks/-/issues/1148).
+### Single database testing
+
+By default, all tests run with [multiple databases](database/multiple_databases.md).
+
+We also run tests with a single database in nightly scheduled pipelines, and in merge requests that touch database-related files.
+
+If you want to force tests to run with a single database, you can add the `pipeline:run-single-db` label to the merge request.
+
### Monitoring
The GitLab test suite is [monitored](performance.md#rspec-profiling) for the `main` branch, and any branch
@@ -218,7 +226,7 @@ of `gitlab-org/gitlab-foss`. These jobs are only created in the following cases:
- when the `pipeline:run-as-if-foss` label is set on the merge request
- when the merge request is created in the `gitlab-org/security/gitlab` project
-- when any CI config file is changed (i.e. `.gitlab-ci.yml` or `.gitlab/ci/**/*`)
+- when any CI configuration file is changed (i.e. `.gitlab-ci.yml` or `.gitlab/ci/**/*`)
The `* as-if-foss` jobs are run in addition to the regular EE-context jobs. They have the `FOSS_ONLY='1'` variable
set and get the `ee/` folder removed before the tests start running.
@@ -247,7 +255,7 @@ appending `-jh` to the branch name. If a corresponding JH branch is found,
rather than from the default branch.
NOTE:
-For now, CI will try to fetch the branch on the [GitLab JH mirror](https://gitlab.com/gitlab-org/gitlab-jh/gitlab), so it might take some time for the new JH branch to propagate to the mirror.
+For now, CI will try to fetch the branch on the [GitLab JH mirror](https://gitlab.com/gitlab-org/gitlab-jh-mirrors/gitlab), so it might take some time for the new JH branch to propagate to the mirror.
## `undercover` RSpec test
@@ -263,6 +271,16 @@ In the event of an emergency, or false positive from this job, add the
`pipeline:skip-undercoverage` label to the merge request to allow this job to
fail.
+You can disable the `undercover` code coverage check by wrapping the desired block of code in `# :nocov:` lines:
+
+```ruby
+# :nocov:
+def some_method
+ # code coverage for this method will be skipped
+end
+# :nocov:
+```
+
## PostgreSQL versions testing
Our test suite runs against PG12 as GitLab.com runs on PG12 and
@@ -291,6 +309,21 @@ We follow the [PostgreSQL versions shipped with Omnibus GitLab](../administratio
| PG11 | `nightly` | `nightly` | `nightly` | `nightly` | `nightly` | `nightly` |
| PG13 | `nightly` | `nightly` | `nightly` | `nightly` | `nightly` | `nightly` |
+## Redis versions testing
+
+Our test suite runs against Redis 6 as GitLab.com runs on Redis 6 and
+[Omnibus defaults to Redis 6 for new installs and upgrades](https://gitlab.com/gitlab-org/omnibus-gitlab/-/blob/master/config/software/redis.rb).
+
+We do run our test suite against Redis 5 on `nightly` scheduled pipelines, specifically when running backward-compatible and forward-compatible PostgreSQL jobs.
+
+### Current versions testing
+
+| Where? | Redis version |
+| ------ | ------------------ |
+| MRs | 6 |
+| `default branch` (non-scheduled pipelines) | 6 |
+| `nightly` scheduled pipelines | 5 |
+
## Pipelines types for merge requests
In general, pipelines for an MR fall into one of the following types (from shorter to longer), depending on the changes made in the MR:
@@ -531,6 +564,8 @@ that are scoped to a single [configuration keyword](../ci/yaml/index.md#job-keyw
| `.use-pg11-ee` | Same as `.use-pg11` but also use an `elasticsearch` service (see [`.gitlab/ci/global.gitlab-ci.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/.gitlab/ci/global.gitlab-ci.yml) for the specific version of the service). |
| `.use-pg12` | Allows a job to use the `postgres` 12 and `redis` services (see [`.gitlab/ci/global.gitlab-ci.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/.gitlab/ci/global.gitlab-ci.yml) for the specific versions of the services). |
| `.use-pg12-ee` | Same as `.use-pg12` but also use an `elasticsearch` service (see [`.gitlab/ci/global.gitlab-ci.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/.gitlab/ci/global.gitlab-ci.yml) for the specific version of the service). |
+| `.use-pg13` | Allows a job to use the `postgres` 13 and `redis` services (see [`.gitlab/ci/global.gitlab-ci.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/.gitlab/ci/global.gitlab-ci.yml) for the specific versions of the services). |
+| `.use-pg13-ee` | Same as `.use-pg13` but also use an `elasticsearch` service (see [`.gitlab/ci/global.gitlab-ci.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/.gitlab/ci/global.gitlab-ci.yml) for the specific version of the service). |
| `.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'` CI/CD variable. |
| `.use-docker-in-docker` | Allows a job to use Docker in Docker. |
@@ -614,6 +649,20 @@ 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.
+### Git fetch caching
+
+Because GitLab.com uses the [pack-objects cache](../administration/gitaly/configure_gitaly.md#pack-objects-cache),
+concurrent Git fetches of the same pipeline ref are deduplicated on
+the Gitaly server (always) and served from cache (when available).
+
+This works well for the following reasons:
+
+- The pack-objects cache is enabled on all Gitaly servers on GitLab.com.
+- The CI/CD [Git strategy setting](../ci/pipelines/settings.md#choose-the-default-git-strategy) for `gitlab-org/gitlab` is **Git clone**,
+ causing all jobs to fetch the same data, which maximizes the cache hit ratio.
+- We use [shallow clone](../ci/pipelines/settings.md#limit-the-number-of-changes-fetched-during-clone) to avoid downloading the full Git
+ history for every job.
+
### Caching strategy
1. All jobs must only pull caches by default.
@@ -647,19 +696,31 @@ request, be sure to start the `dont-interrupt-me` job before pushing.
We limit the artifacts that are saved and retrieved by jobs to the minimum in order to reduce the upload/download time and costs, as well as the artifacts storage.
-### Git fetch caching
+### Components caching
-Because GitLab.com uses the [pack-objects cache](../administration/gitaly/configure_gitaly.md#pack-objects-cache),
-concurrent Git fetches of the same pipeline ref are deduplicated on
-the Gitaly server (always) and served from cache (when available).
+Some external components (currently only GitLab Workhorse) of GitLab need to be built from source as a preliminary step for running tests.
-This works well for the following reasons:
+In [this MR](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/79766), we introduced a new `build-components` job that:
-- The pack-objects cache is enabled on all Gitaly servers on GitLab.com.
-- The CI/CD [Git strategy setting](../ci/pipelines/settings.md#choose-the-default-git-strategy) for `gitlab-org/gitlab` is **Git clone**,
- causing all jobs to fetch the same data, which maximizes the cache hit ratio.
-- We use [shallow clone](../ci/pipelines/settings.md#limit-the-number-of-changes-fetched-during-clone) to avoid downloading the full Git
- history for every job.
+- runs automatically for all GitLab.com `gitlab-org/gitlab` scheduled pipelines
+- runs automatically for any `master` commit that touches the `workhorse/` folder
+- is manual for GitLab.com's `gitlab-org`'s MRs
+
+This job tries to download a generic package that contains GitLab Workhorse binaries needed in the GitLab test suite (under `tmp/tests/gitlab-workhorse`).
+
+- If the package URL returns a 404:
+ 1. It runs `scripts/setup-test-env`, so that the GitLab Workhorse binaries are built.
+ 1. It then creates an archive which contains the binaries and upload it [as a generic package](https://gitlab.com/gitlab-org/gitlab/-/packages/).
+- Otherwise, if the package already exists, it exit the job successfully.
+
+We also changed the `setup-test-env` job to:
+
+1. First download the GitLab Workhorse generic package build and uploaded by `build-components`.
+1. If the package is retrieved successfully, its content is placed in the right folder (i.e. `tmp/tests/gitlab-workhorse`), preventing the building of the binaries when `scripts/setup-test-env` is run later on.
+1. If the package URL returns a 404, the behavior doesn't change compared to the current one: the GitLab Workhorse binaries are built as part of `scripts/setup-test-env`.
+
+NOTE:
+The version of the package is the workhorse tree SHA (i.e. `git rev-parse HEAD:workhorse`).
### Pre-clone step
diff --git a/doc/development/product_qualified_lead_guide/index.md b/doc/development/product_qualified_lead_guide/index.md
index f9d18bacecd..6943f931d79 100644
--- a/doc/development/product_qualified_lead_guide/index.md
+++ b/doc/development/product_qualified_lead_guide/index.md
@@ -35,6 +35,7 @@ The hand-raise lead form accepts the following parameters via provide or inject.
```javascript
provide: {
+ small,
user: {
namespaceId,
userName,
@@ -43,9 +44,18 @@ The hand-raise lead form accepts the following parameters via provide or inject.
companyName,
glmContent,
},
+ ctaTracking: {
+ action,
+ label,
+ property,
+ value,
+ experiment,
+ },
},
```
+The `ctaTracking` parameters follow [the `data-track` attributes](../snowplow/implementation.md#data-track-attributes) for implementing Snowplow tracking. The provided tracking attributes are attached to the button inside the `HandRaiseLeadButton` component, which triggers the hand-raise lead modal when selected.
+
### Monitor the lead location
When embedding a new hand raise form, use a unique `glmContent` or `glm_content` field that is different to any existing values.
@@ -82,13 +92,80 @@ The flow of a PQL lead is as follows:
1. Marketo does scoring and sends the form to Salesforce.
1. Our Sales team uses Salesforce to connect to the leads.
+### Trial lead flow
+
+#### Trial lead flow on GitLab.com
+
+```mermaid
+sequenceDiagram
+ Trial Frontend Forms ->>TrialsController#create_lead: GitLab.com frontend sends [lead] to backend
+ TrialsController#create_lead->>CreateLeadService: [lead]
+ TrialsController#create_lead->>ApplyTrialService: [lead] Apply the trial
+ CreateLeadService->>SubscriptionPortalClient#generate_trial(sync_to_gl=false): [lead] Creates customer account on CustomersDot
+ ApplyTrialService->>SubscriptionPortalClient#generate_trial(sync_to_gl=true): [lead] Asks CustomersDot to apply the trial on namespace
+ SubscriptionPortalClient#generate_trial(sync_to_gl=false)->>CustomersDot|TrialsController#create(sync_to_gl=false): GitLab.com sends [lead] to CustomersDot
+ SubscriptionPortalClient#generate_trial(sync_to_gl=true)->>CustomersDot|TrialsController#create(sync_to_gl=true): GitLab.com asks CustomersDot to apply the trial
+
+
+```
+
+#### Trial lead flow on CustomersDot (sync_to_gl)
+
+```mermaid
+sequenceDiagram
+ CustomersDot|TrialsController#create->>HostedPlans|CreateTrialService#execute: Save [lead] to leads table for monitoring purposes
+ HostedPlans|CreateTrialService#execute->>BaseTrialService#create_account: Creates a customer record in customers table
+ HostedPlans|CreateTrialService#create_platypus_lead->>PlatypusLogLeadService: Creates a platypus lead
+ HostedPlans|CreateTrialService#create_platypus_lead->>Platypus|CreateLeadWorker: Async worker to submit [lead] to Platypus
+ Platypus|CreateLeadWorker->>Platypus|CreateLeadService: [lead]
+ Platypus|CreateLeadService->>PlatypusApp#post: [lead]
+ PlatypusApp#post->>Platypus: [lead] is sent to Platypus
+```
+
+#### Applying the trial to a namespace on CustomersDot
+
+```mermaid
+sequenceDiagram
+ HostedPlans|CreateTrialService->load_namespace#Gitlab api/namespaces: Load namespace details
+ HostedPlans|CreateTrialService->create_order#: Creates an order in orders table
+ HostedPlans|CreateTrialService->create_trial_history#: Creates a record in trial_histories table
+```
+
+### Hand raise lead flow
+
+#### Hand raise flow on GitLab.com
+
+```mermaid
+sequenceDiagram
+ HandRaiseForm Vue Component->>TrialsController#create_hand_raise_lead: GitLab.com frontend sends [lead] to backend
+ TrialsController#create_hand_raise_lead->>CreateHandRaiseLeadService: [lead]
+ CreateHandRaiseLeadService->>SubscriptionPortalClient: [lead]
+ SubscriptionPortalClient->>CustomersDot|TrialsController#create_hand_raise_lead: GitLab.com sends [lead] to CustomersDot
+```
+
+#### Hand raise flow on CustomersDot
+
+```mermaid
+sequenceDiagram
+ CustomersDot|TrialsController#create_hand_raise_lead->>PlatypusLogLeadService: Save [lead] to leads table for monitoring purposes
+ CustomersDot|TrialsController#create_hand_raise_lead->>Platypus|CreateLeadWorker: Async worker to submit [lead] to Platypus
+ Platypus|CreateLeadWorker->>Platypus|CreateLeadService: [lead]
+ Platypus|CreateLeadService->>PlatypusApp#post: [lead]
+ PlatypusApp#post->>Platypus: [lead] is sent to Platypus
+```
+
+### PQL flow after Platypus for all lead types
+
+```mermaid
+sequenceDiagram
+ Platypus->>Workato: [lead]
+ Workato->>Marketo: [lead]
+ Marketo->>Salesforce(SFDC): [lead]
+```
+
## Monitor and manually test leads
- Check the application and Sidekiq logs on `gitlab.com` and CustomersDot to monitor leads.
- Check the `leads` table in CustomersDot.
- Set up staging credentials for Platypus, and track the leads on the [Platypus Dashboard](https://staging.ci.nexus.gitlabenvironment.cloud/admin/queues/queue/new-lead-queue).
- Ask for access to the Marketo Sandbox and validate the leads there.
-
-## Trials
-
-Trials follow the same flow as the PQL leads.
diff --git a/doc/development/profiling.md b/doc/development/profiling.md
index deb743569c5..a3142b06e12 100644
--- a/doc/development/profiling.md
+++ b/doc/development/profiling.md
@@ -91,6 +91,73 @@ printer = RubyProf::CallStackPrinter.new(result)
printer.print(File.open('/tmp/profile.html', 'w'))
```
+### Stackprof support
+
+By default, `Gitlab::Profiler.profile` uses a tracing profiler called [`ruby-prof`](https://ruby-prof.github.io/). However, sampling profilers
+[run faster and use less memory](https://jvns.ca/blog/2017/12/17/how-do-ruby---python-profilers-work-/), so they might be preferred.
+
+You can switch to [Stackprof](https://github.com/tmm1/stackprof) (a sampling profiler) to generate a profile by passing `sampling_mode: true`.
+Pass in a `profiler_options` hash to configure the output file (`out`) of the sampling data. For example:
+
+```ruby
+Gitlab::Profiler.profile('/gitlab-org/gitlab-test', user: User.first, sampling_mode: true, profiler_options: { out: 'tmp/profile.dump' })
+```
+
+You can get a summary of where time was spent by running Stackprof against the sampling data. For example:
+
+```shell
+stackprof tmp/profile.dump
+```
+
+Example sampling data:
+
+```plaintext
+==================================
+ Mode: wall(1000)
+ Samples: 8745 (6.92% miss rate)
+ GC: 1399 (16.00%)
+==================================
+ TOTAL (pct) SAMPLES (pct) FRAME
+ 1022 (11.7%) 1022 (11.7%) Sprockets::PathUtils#stat
+ 957 (10.9%) 957 (10.9%) (marking)
+ 493 (5.6%) 493 (5.6%) Sprockets::PathUtils#entries
+ 576 (6.6%) 471 (5.4%) Mustermann::AST::Translator#decorator_for
+ 439 (5.0%) 439 (5.0%) (sweeping)
+ 630 (7.2%) 241 (2.8%) Sprockets::Cache::FileStore#get
+ 208 (2.4%) 208 (2.4%) ActiveSupport::FileUpdateChecker#watched
+ 206 (2.4%) 206 (2.4%) Digest::Instance#file
+ 544 (6.2%) 176 (2.0%) Sprockets::Cache::FileStore#safe_open
+ 176 (2.0%) 176 (2.0%) ActiveSupport::FileUpdateChecker#max_mtime
+ 268 (3.1%) 147 (1.7%) ActiveRecord::ConnectionAdapters::PostgreSQLAdapter#exec_no_cache
+ 140 (1.6%) 140 (1.6%) ActiveSupport::BacktraceCleaner#add_gem_filter
+ 116 (1.3%) 116 (1.3%) Bootsnap::CompileCache::ISeq.storage_to_output
+ 160 (1.8%) 113 (1.3%) Gem::Version#<=>
+ 109 (1.2%) 109 (1.2%) block in <main>
+ 108 (1.2%) 108 (1.2%) Gem::Version.new
+ 131 (1.5%) 105 (1.2%) Sprockets::EncodingUtils#unmarshaled_deflated
+ 1166 (13.3%) 82 (0.9%) Mustermann::RegexpBased#initialize
+ 82 (0.9%) 78 (0.9%) FileUtils.touch
+ 72 (0.8%) 72 (0.8%) Sprockets::Manifest.compile_match_filter
+ 71 (0.8%) 70 (0.8%) Grape::Router#compile!
+ 91 (1.0%) 65 (0.7%) ActiveRecord::ConnectionAdapters::PostgreSQL::DatabaseStatements#query
+ 93 (1.1%) 64 (0.7%) ActionDispatch::Journey::Path::Pattern::AnchoredRegexp#accept
+ 59 (0.7%) 59 (0.7%) Mustermann::AST::Translator.dispatch_table
+ 62 (0.7%) 59 (0.7%) Rails::BacktraceCleaner#initialize
+ 2492 (28.5%) 49 (0.6%) Sprockets::PathUtils#stat_directory
+ 242 (2.8%) 49 (0.6%) Gitlab::Instrumentation::RedisBase.add_call_details
+ 47 (0.5%) 47 (0.5%) URI::RFC2396_Parser#escape
+ 46 (0.5%) 46 (0.5%) #<Class:0x00000001090c2e70>#__setobj__
+ 44 (0.5%) 44 (0.5%) Sprockets::Base#normalize_logical_path
+```
+
+You can also generate flamegraphs:
+
+```shell
+stackprof --d3-flamegraph tmp/profile.dump > flamegraph.html
+```
+
+See [the Stackprof documentation](https://github.com/tmm1/stackprof) for more details.
+
## Speedscope flamegraphs
You can generate a flamegraph for a particular URL by selecting a flamegraph sampling mode button in the performance bar or by adding the `performance_bar=flamegraph` parameter to the request.
diff --git a/doc/development/rake_tasks.md b/doc/development/rake_tasks.md
index 5c8e2d5fc55..1e9367ecee4 100644
--- a/doc/development/rake_tasks.md
+++ b/doc/development/rake_tasks.md
@@ -196,6 +196,16 @@ One way to generate the initial list is to run the Rake task `rubocop:todo:gener
bundle exec rake rubocop:todo:generate
```
+To generate TODO list for specific RuboCop rules, pass them comma-seperated as
+argument to the Rake task:
+
+```shell
+bundle exec rake 'rubocop:todo:generate[Gitlab/NamespacedClass,Lint/Syntax]'
+bundle exec rake rubocop:todo:generate\[Gitlab/NamespacedClass,Lint/Syntax\]
+```
+
+Some shells require brackets to be escaped or quoted.
+
See [Resolving RuboCop exceptions](contributing/style_guides.md#resolving-rubocop-exceptions)
on how to proceed from here.
@@ -219,14 +229,14 @@ To update the Emoji aliases file (used for Emoji autocomplete), run the
following:
```shell
-bundle exec rake gemojione:aliases
+bundle exec rake tanuki_emoji:aliases
```
To update the Emoji digests file (used for Emoji autocomplete), run the
following:
```shell
-bundle exec rake gemojione:digests
+bundle exec rake tanuki_emoji:digests
```
This updates the file `fixtures/emojis/digests.json` based on the currently
@@ -235,7 +245,7 @@ available Emoji.
To generate a sprite file containing all the Emoji, run:
```shell
-bundle exec rake gemojione:sprite
+bundle exec rake tanuki_emoji:sprite
```
If new emoji are added, the sprite sheet may change size. To compensate for
diff --git a/doc/development/redis/new_redis_instance.md b/doc/development/redis/new_redis_instance.md
index dcd79be0e5c..96f860f3890 100644
--- a/doc/development/redis/new_redis_instance.md
+++ b/doc/development/redis/new_redis_instance.md
@@ -112,7 +112,7 @@ while and there are no issues, we can proceed.
### Proposed solution: Migrate data by using MultiStore with the fallback strategy
-We need a way to migrate users to a new Redis store without causing any inconveniences from UX perspective.
+We need a way to migrate users to a new Redis store without causing any inconveniences from UX perspective.
We also want the ability to fall back to the "old" Redis instance if something goes wrong with the new instance.
Migration Requirements:
@@ -129,13 +129,13 @@ We need to write data into both Redis instances (old + new).
We read from the new instance, but we need to fall back to the old instance when pre-fetching from the new dedicated Redis instance that failed.
We need to log any issues or exceptions with a new instance, but still fall back to the old instance.
-The proposed migration strategy is to implement and use the [MultiStore](https://gitlab.com/gitlab-org/gitlab/-/blob/fcc42e80ed261a862ee6ca46b182eee293ae60b6/lib/gitlab/redis/multi_store.rb).
-We used this approach with [adding new dedicated Redis instance for session keys](https://gitlab.com/groups/gitlab-com/gl-infra/-/epics/579).
+The proposed migration strategy is to implement and use the [MultiStore](https://gitlab.com/gitlab-org/gitlab/-/blob/fcc42e80ed261a862ee6ca46b182eee293ae60b6/lib/gitlab/redis/multi_store.rb).
+We used this approach with [adding new dedicated Redis instance for session keys](https://gitlab.com/groups/gitlab-com/gl-infra/-/epics/579).
Also MultiStore comes with corresponding [specs](https://gitlab.com/gitlab-org/gitlab/-/blob/master/spec/lib/gitlab/redis/multi_store_spec.rb).
The MultiStore looks like a `redis-rb ::Redis` instance.
-In the new Redis instance class you added in [Step 1](#step-1-support-configuring-the-new-instance),
+In the new Redis instance class you added in [Step 1](#step-1-support-configuring-the-new-instance),
override the [Redis](https://gitlab.com/gitlab-org/gitlab/-/blob/fcc42e80ed261a862ee6ca46b182eee293ae60b6/lib/gitlab/redis/sessions.rb#L20-28) method from the `::Gitlab::Redis::Wrapper`
```ruby
@@ -177,7 +177,7 @@ bin/feature-flag use_primary_store_as_default_for_foo
```
By enabling `use_primary_and_secondary_stores_for_foo` feature flag, our `Gitlab::Redis::Foo` will use `MultiStore` to write to both new Redis instance
-and the [old (fallback-instance)](#fallback-instance).
+and the [old (fallback-instance)](#fallback-instance).
If we fail to fetch data from the new instance, we will fallback and read from the old Redis instance.
We can monitor logs for `Gitlab::Redis::MultiStore::ReadFromPrimaryError`, and also the Prometheus counter `gitlab_redis_multi_store_read_fallback_total`.
@@ -218,7 +218,7 @@ When a command outside of the supported list is used, `method_missing` will pass
This ensures that anything unexpected behaves like it would before.
NOTE:
-By tracking `gitlab_redis_multi_store_method_missing_total` counter and `Gitlab::Redis::MultiStore::MethodMissingError`,
+By tracking `gitlab_redis_multi_store_method_missing_total` counter and `Gitlab::Redis::MultiStore::MethodMissingError`,
a developer will need to add an implementation for missing Redis commands before proceeding with the migration.
##### Errors
diff --git a/doc/development/secure_coding_guidelines.md b/doc/development/secure_coding_guidelines.md
index d34b12c6361..10f6c22e54a 100644
--- a/doc/development/secure_coding_guidelines.md
+++ b/doc/development/secure_coding_guidelines.md
@@ -253,12 +253,27 @@ the mitigations for a new feature.
- [More details](https://dev.gitlab.org/gitlab/gitlabhq/-/merge_requests/2530/diffs)
-#### Feature-specific mitigations
+#### URL blocker & validation libraries
+
+[`Gitlab::UrlBlocker`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/url_blocker.rb) can be used to validate that a
+provided URL meets a set of constraints. Importantly, when `dns_rebind_protection` is `true`, the method returns a known-safe URI where the hostname
+has been replaced with an IP address. This prevents DNS rebinding attacks, because the DNS record has been resolved. However, if we ignore this returned
+value, we **will not** be protected against DNS rebinding.
-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.
+This is the case with validators such as the `AddressableUrlValidator` (called with `validates :url, addressable_url: {opts}` or `public_url: {opts}`).
+Validation errors are only raised when validations are called, for example when a record is created or saved. If we ignore the value returned by the validation
+when persisting the record, **we need to recheck** its validity before using it. You can learn more about [Time of Check to Time of Use bugs](#time-of-check-to-time-of-use-bugs) in a later section
+of these guidelines.
+
+#### Feature-specific mitigations
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.
+For situations in which you can't use an allowlist or GitLab:HTTP, you must implement mitigations
+directly in the feature. It's best to validate the destination IP addresses themselves, not just
+domain names, as the attacker can control DNS. Below is a list of mitigations that you should
+implement.
+
- Block connections to all localhost addresses
- `127.0.0.1/8` (IPv4 - note the subnet mask)
- `::1` (IPv6)
@@ -270,9 +285,36 @@ There are many tricks to bypass common SSRF validations. If feature-specific mit
- `169.254.0.0/16`
- In particular, for GCP: `metadata.google.internal` -> `169.254.169.254`
- For HTTP connections: Disable redirects or validate the redirect destination
-- To mitigate DNS rebinding attacks, validate and use the first IP address received
+- 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 [time of check to time of use bugs](#time-of-check-to-time-of-use-bugs) to learn more about DNS rebinding's class of bug.
-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
+Don't rely on methods like `.start_with?` when validating a URL, or make assumptions about which
+part of a string maps to which part of a URL. Use the `URI` class to parse the string, and validate
+each component (scheme, host, port, path, and so on). Attackers can create valid URLs which look
+safe, but lead to malicious locations.
+
+```ruby
+user_supplied_url = "https://my-safe-site.com@my-evil-site.com" # Content before an @ in a URL is usually for basic authentication
+user_supplied_url.start_with?("https://my-safe-site.com") # Don't trust with start_with? for URLs!
+=> true
+URI.parse(user_supplied_url).host
+=> "my-evil-site.com"
+
+user_supplied_url = "https://my-safe-site.com-my-evil-site.com"
+user_supplied_url.start_with?("https://my-safe-site.com") # Don't trust with start_with? for URLs!
+=> true
+URI.parse(user_supplied_url).host
+=> "my-safe-site.com-my-evil-site.com"
+
+# Here's an example where we unsafely attempt to validate a host while allowing for
+# subdomains
+user_supplied_url = "https://my-evil-site-my-safe-site.com"
+user_supplied_host = URI.parse(user_supplied_url).host
+=> "my-evil-site-my-safe-site.com"
+user_supplied_host.end_with?("my-safe-site.com") # Don't trust with end_with?
+=> true
+```
## XSS guidelines
@@ -448,8 +490,7 @@ parameter when using `check_allowed_absolute_path!()`.
To use a combination of both checks, follow the example below:
```ruby
-path = Gitlab::Utils.check_path_traversal!(path)
-Gitlab::Utils.check_allowed_absolute_path!(path, path_allowlist)
+Gitlab::Utils.check_allowed_absolute_path_and_path_traversal!(path, path_allowlist)
```
In the REST API, we have the [`FilePath`](https://gitlab.com/gitlab-org/security/gitlab/-/blob/master/lib/api/validations/validators/file_path.rb)
@@ -1120,3 +1161,52 @@ func printZipContents(src string) error {
return nil
}
```
+
+## Time of check to time of use bugs
+
+Time of check to time of use, or TOCTOU, is a class of error which occur when the state of something changes unexpectedly partway during a process.
+More specifically, it's when the property you checked and validated has changed when you finally get around to using that property.
+
+These types of bugs are often seen in environments which allow multi-threading and concurrency, like filesystems and distributed web applications; these are a type of race condition. TOCTOU also occurs when state is checked and stored, then after a period of time that state is relied on without re-checking its accuracy and/or validity.
+
+### Examples
+
+**Example 1:** you have a model which accepts a URL as input. When the model is created you verify that the URL's host resolves to a public IP address, to prevent attackers making internal network calls. But DNS records can change ([DNS rebinding](#server-side-request-forgery-ssrf)]). An attacker updates the DNS record to `127.0.0.1`, and when your code resolves those URL's host it results in sending a potentially malicious request to a server on the internal network. The property was valid at the "time of check", but invalid and malicious at "time of use".
+
+GitLab-specific example can be found in [this issue](https://gitlab.com/gitlab-org/gitlab/-/issues/214401) where, although `Gitlab::UrlBlocker.validate!` was called, the returned value was not used. This made it vulnerable to TOCTOU bug and SSRF protection bypass through [DNS rebinding](#server-side-request-forgery-ssrf). The fix was to [use the validated IP address](https://gitlab.com/gitlab-org/gitlab/-/commit/7af8abd4df9a98f7a1ae7c4ec9840d0a7a8c684d).
+
+**Example 2:** you have a feature which schedules jobs. When the user schedules the job, they have permission to do so. But imagine if, between the time they schedule the job and the time it is run, their permissions are restricted. Unless you re-check permissions at time of use, you could inadvertently allow unauthorized activity.
+
+**Example 3:** you need to fetch a remote file, and perform a `HEAD` request to get and validate the content length and content type. When you subsequently make a `GET` request, though, the file delivered is a different size or different file type. (This is stretching the definition of TOCTOU, but things _have_ changed between time of check and time of use).
+
+**Example 4:** you allow users to upvote a comment if they haven't already. The server is multi-threaded, and you aren't using transactions or an applicable database index. By repeatedly clicking upvote in quick succession a malicious user is able to add multiple upvotes: the requests arrive at the same time, the checks run in parallel and confirm that no upvote exists yet, and so each upvote is written to the database.
+
+Here's some pseudocode showing an example of a potential TOCTOU bug:
+
+```ruby
+def upvote(comment, user)
+ # The time between calling .exists? and .create can lead to TOCTOU,
+ # particularly if .create is a slow method, or runs in a background job
+ if Upvote.exists?(comment: comment, user: user)
+ return
+ else
+ Upvote.create(comment: comment, user: user)
+ end
+end
+```
+
+### Prevention & defense
+
+- Assume values will change between the time you validate them and the time you use them.
+- Perform checks as close to execution time as possible.
+- Perform checks after your operation completes.
+- Use your framework's validations and database features to impose constraints and atomic reads and writes.
+- Read about [Server Side Request Forgery (SSRF) and DNS rebinding](#server-side-request-forgery-ssrf)
+
+An example of well implemented `Gitlab::UrlBlocker.validate!` call that prevents TOCTOU bug:
+
+1. [Preventing DNS rebinding in Gitea importer](https://gitlab.com/gitlab-org/gitlab/-/commit/7af8abd4df9a98f7a1ae7c4ec9840d0a7a8c684d)
+
+### Resources
+
+- [CWE-367: Time-of-check Time-of-use (TOCTOU) Race Condition](https://cwe.mitre.org/data/definitions/367.html)
diff --git a/doc/development/service_ping/implement.md b/doc/development/service_ping/implement.md
index 3a1e4c6d87b..25e841e113b 100644
--- a/doc/development/service_ping/implement.md
+++ b/doc/development/service_ping/implement.md
@@ -16,7 +16,7 @@ Service Ping consists of two kinds of data:
To implement a new metric in Service Ping, follow these steps:
1. [Implement the required counter](#types-of-counters)
-1. [Name and place the metric](#name-and-place-the-metric)
+1. [Name and place the metric](metrics_dictionary.md#metric-key_path)
1. [Test counters manually using your Rails console](#test-counters-manually-using-your-rails-console)
1. [Generate the SQL query](#generate-the-sql-query)
1. [Optimize queries with `#database-lab`](#optimize-queries-with-database-lab)
@@ -26,13 +26,12 @@ To implement a new metric in Service Ping, follow these steps:
1. [Verify your metric](#verify-your-metric)
1. [Set up and test Service Ping locally](#set-up-and-test-service-ping-locally)
-NOTE:
-When you add or change a Service Metric, you must migrate metrics to [instrumentation classes](metrics_instrumentation.md).
-For information about the progress on migrating Service ping metrics, see this [epic](https://gitlab.com/groups/gitlab-org/-/epics/5547).
-
## Instrumentation classes
-We recommend you use [instrumentation classes](metrics_instrumentation.md) in `usage_data.rb` where possible.
+NOTE:
+Implementing metrics directly in `usage_data.rb` is deprecated.
+When you add or change a Service Ping Metric, you must migrate metrics to [instrumentation classes](metrics_instrumentation.md).
+For information about the progress on migrating Service Ping metrics, see this [epic](https://gitlab.com/groups/gitlab-org/-/epics/5547).
For example, we have the following instrumentation class:
`lib/gitlab/usage/metrics/instrumentations/count_boards_metric.rb`.
@@ -45,7 +44,7 @@ boards: add_metric('CountBoardsMetric', time_frame: 'all'),
## Types of counters
-There are several types of counters in `usage_data.rb`:
+There are several types of counters for metrics:
- **[Batch counters](#batch-counters)**: Used for counts and sums.
- **[Redis counters](#redis-counters):** Used for in-memory counts.
@@ -72,64 +71,39 @@ you must add a specialized index on the columns involved in a counter.
#### Ordinary batch counters
-Simple count of a given `ActiveRecord_Relation`, does a non-distinct batch count, smartly reduces `batch_size`, and handles errors.
-Handles the `ActiveRecord::StatementInvalid` error.
+Create a new [database metrics](metrics_instrumentation.md#database-metrics) instrumentation class with `count` operation for a given `ActiveRecord_Relation`
Method:
```ruby
-count(relation, column = nil, batch: true, start: nil, finish: nil)
+add_metric('CountIssuesMetric', time_frame: 'all')
```
-Arguments:
-
-- `relation` the ActiveRecord_Relation to perform the count
-- `column` the column to perform the count on, by default is the primary key
-- `batch`: default `true` to use batch counting
-- `start`: custom start of the batch counting to avoid complex min calculations
-- `end`: custom end of the batch counting to avoid complex min calculations
-
Examples:
-```ruby
-count(User.active)
-count(::Clusters::Cluster.aws_installed.enabled, :cluster_id)
-count(::Clusters::Cluster.aws_installed.enabled, :cluster_id, start: ::Clusters::Cluster.minimum(:id), finish: ::Clusters::Cluster.maximum(:id))
-```
+Examples using `usage_data.rb` have been [deprecated](usage_data.md). We recommend to use [instrumentation classes](metrics_instrumentation.md).
#### Distinct batch counters
-Distinct count of a given `ActiveRecord_Relation` on given column, a distinct batch count, smartly reduces `batch_size`, and handles errors.
-Handles the `ActiveRecord::StatementInvalid` error.
+Create a new [database metrics](metrics_instrumentation.md#database-metrics) instrumentation class with `distinct_count` operation for a given `ActiveRecord_Relation`.
Method:
```ruby
-distinct_count(relation, column = nil, batch: true, batch_size: nil, start: nil, finish: nil)
+add_metric('CountUsersAssociatingMilestonesToReleasesMetric', time_frame: 'all')
```
-Arguments:
-
-- `relation`: the ActiveRecord_Relation to perform the count
-- `column`: the column to perform the distinct count, by default is the primary key
-- `batch`: default `true` to use batch counting
-- `batch_size`: if none set it uses default value 10000 from `Gitlab::Database::BatchCounter`
-- `start`: custom start of the batch counting to avoid complex min calculations
-- `end`: custom end of the batch counting to avoid complex min calculations
-
WARNING:
Counting over non-unique columns can lead to performance issues. For more information, see the [iterating tables in batches](../iterating_tables_in_batches.md) guide.
Examples:
-```ruby
-distinct_count(::Project, :creator_id)
-distinct_count(::Note.with_suggestions.where(time_period), :author_id, start: ::User.minimum(:id), finish: ::User.maximum(:id))
-distinct_count(::Clusters::Applications::CertManager.where(time_period).available.joins(:cluster), 'clusters.user_id')
-```
+Examples using `usage_data.rb` have been [deprecated](usage_data.md). We recommend to use [instrumentation classes](metrics_instrumentation.md).
#### Sum batch operation
+There is no support for `sum` for database metrics.
+
Sum the values of a given ActiveRecord_Relation on given column and handles errors.
Handles the `ActiveRecord::StatementInvalid` error
@@ -686,29 +660,6 @@ We return fallback values in these cases:
| Timeouts, general failures | -1 |
| Standard errors in counters | -2 |
-## Name and place the metric
-
-Add the metric in one of the top-level keys:
-
-- `settings`: for settings related metrics.
-- `counts_weekly`: for counters that have data for the most recent 7 days.
-- `counts_monthly`: for counters that have data for the most recent 28 days.
-- `counts`: for counters that have data for all time.
-
-### How to get a metric name suggestion
-
-The metric YAML generator can suggest a metric name for you.
-To generate a metric name suggestion, first instrument the metric at the provided `key_path`.
-Then, generate the metric's YAML definition and
-return to the instrumentation and update it.
-
-1. Add the metric instrumentation to `lib/gitlab/usage_data.rb` inside one
- of the [top-level keys](#name-and-place-the-metric), using any name you choose.
-1. Run the [metrics YAML generator](metrics_dictionary.md#metrics-definition-and-validation).
-1. Use the metric name suggestion to select a suitable metric name.
-1. Update the instrumentation you created in the first step and change the metric name to the suggested name.
-1. Update the metric's YAML definition with the correct `key_path`.
-
## Test counters manually using your Rails console
```ruby
diff --git a/doc/development/service_ping/index.md b/doc/development/service_ping/index.md
index 86e70cc8bbc..6878fd1bf28 100644
--- a/doc/development/service_ping/index.md
+++ b/doc/development/service_ping/index.md
@@ -6,7 +6,8 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Service Ping Guide **(FREE SELF)**
-> Introduced in GitLab Ultimate 11.2, more statistics.
+> - Introduced in GitLab Ultimate 11.2, more statistics.
+> - In GitLab 14.1, [renamed from Usage Ping to Service Ping](https://gitlab.com/groups/gitlab-org/-/epics/5990). In 14.0 and earlier, use the Usage Ping documentation for the Rails commands appropriate to your version.
Service Ping is a GitLab process that collects and sends a weekly payload to GitLab.
The payload provides important high-level data that helps our product, support,
@@ -68,7 +69,10 @@ Because of these limitations we recommend you:
> Introduced in GitLab 14.1.
-In GitLab versions 14.1 and later, free self-managed users running [GitLab EE](../ee_features.md) can receive paid features by registering with GitLab and sending us activity data through Service Ping. Features introduced here do not remove the feature from its paid tier. Users can continue to access the features in a paid tier without sharing usage data.
+In GitLab versions 14.1 and later, GitLab Free customers with a self-managed instance running
+[GitLab EE](../ee_features.md) can receive paid features by registering with GitLab and sending us
+activity data through Service Ping. Features introduced here do not remove the feature from its paid
+tier. Users can continue to access the features in a paid tier without sharing usage data.
#### Features available in 14.1 and later
@@ -209,17 +213,17 @@ sequenceDiagram
- `uuid` - GitLab instance unique identifier
- `hostname` - GitLab instance hostname
-- `version` - GitLab instance current versions
+- `version` - GitLab instance current versions
- `elapsed` - Amount of time which passed since Service Ping report process started and moment of error occurrence
- `message` - Error message
<pre>
<code>
{
- "uuid"=>"02333324-1cd7-4c3b-a45b-a4993f05fb1d",
- "hostname"=>"127.0.0.1",
- "version"=>"14.7.0-pre",
- "elapsed"=>0.006946,
+ "uuid"=>"02333324-1cd7-4c3b-a45b-a4993f05fb1d",
+ "hostname"=>"127.0.0.1",
+ "version"=>"14.7.0-pre",
+ "elapsed"=>0.006946,
"message"=>'PG::UndefinedColumn: ERROR: column \"non_existent_attribute\" does not exist\nLINE 1: SELECT COUNT(non_existent_attribute) FROM \"issues\" /*applica...'
}
</code>
@@ -576,7 +580,7 @@ skip_db_write:
ServicePing::SubmitService.new(skip_db_write: true).execute
```
-## Manually upload Service Ping payload
+## Manually upload Service Ping payload
> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/7388) in GitLab 14.8 with a flag named `admin_application_settings_service_usage_data_center`. Disabled by default.
@@ -596,7 +600,7 @@ To upload payload manually:
## Monitoring
-Service Ping reporting process state is monitored with [internal SiSense dashboard](https://app.periscopedata.com/app/gitlab/968489/Product-Intelligence---Service-Ping-Health).
+Service Ping reporting process state is monitored with [internal SiSense dashboard](https://app.periscopedata.com/app/gitlab/968489/Product-Intelligence---Service-Ping-Health).
## Troubleshooting
diff --git a/doc/development/service_ping/metrics_dictionary.md b/doc/development/service_ping/metrics_dictionary.md
index 93eec4efabd..6884844da3f 100644
--- a/doc/development/service_ping/metrics_dictionary.md
+++ b/doc/development/service_ping/metrics_dictionary.md
@@ -47,13 +47,58 @@ Each metric is defined in a separate YAML file consisting of a number of fields:
| `distribution` | yes | `array`; may be set to one of `ce, ee` or `ee`. The [distribution](https://about.gitlab.com/handbook/marketing/strategic-marketing/tiers/#definitions) where the tracked feature is available. |
| `performance_indicator_type` | no | `array`; may be set to one of [`gmau`, `smau`, `paid_gmau`, or `umau`](https://about.gitlab.com/handbook/business-technology/data-team/data-catalog/xmau-analysis/). |
| `tier` | yes | `array`; may contain one or a combination of `free`, `premium` or `ultimate`. The [tier]( https://about.gitlab.com/handbook/marketing/strategic-marketing/tiers/) where the tracked feature is available. This should be verbose and contain all tiers where a metric is available. |
-| `milestone` | no | The milestone when the metric is introduced. |
+| `milestone` | no | The milestone when the metric is introduced and when it's available to self-managed instances with the official GitLab release. |
| `milestone_removed` | no | The milestone when the metric is removed. |
-| `introduced_by_url` | no | The URL to the merge request that introduced the metric. |
+| `introduced_by_url` | no | The URL to the merge request that introduced the metric to be available for self-managed instances. |
| `repair_issue_url` | no | The URL of the issue that was created to repair a metric with a `broken` status. |
| `options` | no | `object`: options information needed to calculate the metric value. |
| `skip_validation` | no | This should **not** be set. [Used for imported metrics until we review, update and make them valid](https://gitlab.com/groups/gitlab-org/-/epics/5425). |
+### Metric key_path
+
+The `key_path` of the metric is the location in the JSON Service Ping payload.
+
+The `key_path` could be composed from multiple parts separated by `.` and it must be unique.
+
+We recommend to add the metric in one of the top-level keys:
+
+- `settings`: for settings related metrics.
+- `counts_weekly`: for counters that have data for the most recent 7 days.
+- `counts_monthly`: for counters that have data for the most recent 28 days.
+- `counts`: for counters that have data for all time.
+
+NOTE:
+We can't control what the metric's `key_path` is, because some of them are generated dynamically in `usage_data.rb`.
+For example, see [Redis HLL metrics](implement.md#redis-hll-counters).
+
+### Metric name
+
+To improve metric discoverability by a wider audience, each metric with
+instrumentation added at an appointed `key_path` receives a `name` attribute
+filled with the name suggestion, corresponding to the metric `data_source` and instrumentation.
+Metric name suggestions can contain two types of elements:
+
+1. **User input prompts**: enclosed by angle brackets (`< >`), these pieces should be replaced or
+ removed when you create a metrics YAML file.
+1. **Fixed suggestion**: plaintext parts generated according to well-defined algorithms.
+ They are based on underlying instrumentation, and must not be changed.
+
+For a metric name to be valid, it must not include any prompt, and fixed suggestions
+must not be changed.
+
+#### Generate a metric name suggestion
+
+The metric YAML generator can suggest a metric name for you.
+To generate a metric name suggestion, first instrument the metric at the provided `key_path`.
+Then, generate the metric's YAML definition and
+return to the instrumentation and update it.
+
+1. Add the metric instrumentation class to `lib/gitlab/usage/metrics/instrumentations/`.
+1. Add the metric logic in the instrumentation class.
+1. Run the [metrics YAML generator](metrics_dictionary.md#metrics-definition-and-validation).
+1. Use the metric name suggestion to select a suitable metric name.
+1. Update the metric's YAML definition with the correct `key_path`.
+
### Metric statuses
Metric definitions can have one of the following statuses:
@@ -81,21 +126,6 @@ which has a related schema in `/config/metrics/objects_schemas/topology_schema.j
- `all`: The metric data applies for the whole time the metric has been active (all-time interval). For example, the following metric counts all users that create issues: `/config/metrics/counts_all/20210216181115_issues.yml`.
- `none`: The metric collects a type of data that's not tracked over time, such as settings and configuration information. Therefore, a time interval is not applicable. For example, `uuid` has no time interval applicable: `config/metrics/license/20210201124933_uuid.yml`.
-### Metric name
-
-To improve metric discoverability by a wider audience, each metric with
-instrumentation added at an appointed `key_path` receives a `name` attribute
-filled with the name suggestion, corresponding to the metric `data_source` and instrumentation.
-Metric name suggestions can contain two types of elements:
-
-1. **User input prompts**: Enclosed by `<>`, these pieces should be replaced or
- removed when you create a metrics YAML file.
-1. **Fixed suggestion**: Plaintext parts generated according to well-defined algorithms.
- They are based on underlying instrumentation, and should not be changed.
-
-For a metric name to be valid, it must not include any prompt, and no fixed suggestions
-should be changed.
-
### Data category
We use the following categories to classify a metric:
diff --git a/doc/development/service_ping/metrics_instrumentation.md b/doc/development/service_ping/metrics_instrumentation.md
index c98b0df92aa..c684d9d12ef 100644
--- a/doc/development/service_ping/metrics_instrumentation.md
+++ b/doc/development/service_ping/metrics_instrumentation.md
@@ -57,6 +57,50 @@ module Gitlab
end
```
+### Ordinary batch counters Example
+
+```ruby
+module Gitlab
+ module Usage
+ module Metrics
+ module Instrumentations
+ class CountIssuesMetric < DatabaseMetric
+ operation :count
+
+ start { Issue.minimum(:id) }
+ finish { Issue.maximum(:id) }
+
+ relation { Issue }
+ end
+ end
+ end
+ end
+end
+```
+
+### Distinct batch counters Example
+
+```ruby
+# frozen_string_literal: true
+
+module Gitlab
+ module Usage
+ module Metrics
+ module Instrumentations
+ class CountUsersAssociatingMilestonesToReleasesMetric < DatabaseMetric
+ operation :distinct_count, column: :author_id
+
+ relation { Release.with_milestones }
+
+ start { Release.minimum(:author_id) }
+ finish { Release.maximum(:author_id) }
+ end
+ end
+ end
+ end
+end
+```
+
## Redis metrics
[Example of a merge request that adds a `Redis` metric](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/66582).
diff --git a/doc/development/service_ping/review_guidelines.md b/doc/development/service_ping/review_guidelines.md
index 137e11608cf..ee2d8f4f4a1 100644
--- a/doc/development/service_ping/review_guidelines.md
+++ b/doc/development/service_ping/review_guidelines.md
@@ -51,12 +51,13 @@ are regular backend changes.
#### The Product Intelligence **reviewer** should
- Perform a first-pass review on the merge request and suggest improvements to the author.
-- Check the [metrics location](implement.md#name-and-place-the-metric) in
+- Check the [metrics location](metrics_dictionary.md#metric-key_path) in
the Service Ping JSON payload.
-- Suggest that the author checks the [naming suggestion](implement.md#how-to-get-a-metric-name-suggestion) while
+- Suggest that the author checks the [naming suggestion](metrics_dictionary.md#generate-a-metric-name-suggestion) while
generating the metric's YAML definition.
- Add the `~database` label and ask for a [database review](../database_review.md) for
metrics that are based on Database.
+- Add `~Data Warehouse::Impact Check` for any database metric that has a query change. Changes in queries can affect [data operations](https://about.gitlab.com/handbook/business-technology/data-team/how-we-work/triage/#gitlabcom-db-structure-changes).
- For tracking using Redis HLL (HyperLogLog):
- Check the Redis slot.
- Check if a [feature flag is needed](implement.md#recommendations).
diff --git a/doc/development/service_ping/usage_data.md b/doc/development/service_ping/usage_data.md
new file mode 100644
index 00000000000..a25ad5f62be
--- /dev/null
+++ b/doc/development/service_ping/usage_data.md
@@ -0,0 +1,70 @@
+---
+stage: Growth
+group: Product Intelligence
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
+---
+
+# Usage Data Metrics guide
+
+This guide describes deprecated usage for metrics in `usage_data.rb`.
+
+NOTE:
+Implementing metrics direct in `usage_data.rb` is deprecated, We recommend you use [instrumentation classes](metrics_instrumentation.md).
+
+## Ordinary batch counters
+
+Simple count of a given `ActiveRecord_Relation`, does a non-distinct batch count, smartly reduces `batch_size`, and handles errors.
+Handles the `ActiveRecord::StatementInvalid` error.
+
+Method:
+
+```ruby
+count(relation, column = nil, batch: true, start: nil, finish: nil)
+```
+
+Arguments:
+
+- `relation` the ActiveRecord_Relation to perform the count
+- `column` the column to perform the count on, by default is the primary key
+- `batch`: default `true` to use batch counting
+- `start`: custom start of the batch counting to avoid complex min calculations
+- `end`: custom end of the batch counting to avoid complex min calculations
+
+Examples:
+
+```ruby
+count(User.active)
+count(::Clusters::Cluster.aws_installed.enabled, :cluster_id)
+count(::Clusters::Cluster.aws_installed.enabled, :cluster_id, start: ::Clusters::Cluster.minimum(:id), finish: ::Clusters::Cluster.maximum(:id))
+```
+
+## Distinct batch counters
+
+Distinct count of a given `ActiveRecord_Relation` on given column, a distinct batch count, smartly reduces `batch_size`, and handles errors.
+Handles the `ActiveRecord::StatementInvalid` error.
+
+Method:
+
+```ruby
+distinct_count(relation, column = nil, batch: true, batch_size: nil, start: nil, finish: nil)
+```
+
+Arguments:
+
+- `relation`: the ActiveRecord_Relation to perform the count
+- `column`: the column to perform the distinct count, by default is the primary key
+- `batch`: default `true` to use batch counting
+- `batch_size`: if none set it uses default value 10000 from `Gitlab::Database::BatchCounter`
+- `start`: custom start of the batch counting to avoid complex min calculations
+- `end`: custom end of the batch counting to avoid complex min calculations
+
+WARNING:
+Counting over non-unique columns can lead to performance issues. For more information, see the [iterating tables in batches](../iterating_tables_in_batches.md) guide.
+
+Examples:
+
+```ruby
+distinct_count(::Project, :creator_id)
+distinct_count(::Note.with_suggestions.where(time_period), :author_id, start: ::User.minimum(:id), finish: ::User.maximum(:id))
+distinct_count(::Clusters::Applications::CertManager.where(time_period).available.joins(:cluster), 'clusters.user_id')
+```
diff --git a/doc/development/shared_files.md b/doc/development/shared_files.md
index e26464a5d80..4f13bb80761 100644
--- a/doc/development/shared_files.md
+++ b/doc/development/shared_files.md
@@ -11,5 +11,5 @@ servers in `shared/`, using a shared storage solution like NFS. Although this is
some GitLab installations, it must not be the only file storage option for a given feature. This is
because [cloud-native GitLab installations do not support it](architecture.md#adapting-existing-and-introducing-new-components).
-Our [uploads documentation](uploads.md) describes how to handle file storage in
+Our [uploads documentation](uploads/index.md) describes how to handle file storage in
such a way that it supports both options: direct disk access and object storage.
diff --git a/doc/development/sidekiq/idempotent_jobs.md b/doc/development/sidekiq/idempotent_jobs.md
index 4b201e22ca9..38db22f8467 100644
--- a/doc/development/sidekiq/idempotent_jobs.md
+++ b/doc/development/sidekiq/idempotent_jobs.md
@@ -75,7 +75,7 @@ job executed, the first job would do nothing.
GitLab supports two deduplication strategies:
-- `until_executing`
+- `until_executing`, which is the default strategy
- `until_executed`
More [deduplication strategies have been
@@ -190,6 +190,7 @@ that can tolerate some duplication.
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/69372) in GitLab 14.3.
> - [Enabled on GitLab.com](https://gitlab.com/gitlab-org/gitlab/-/issues/338350) in GitLab 14.4.
> - [Enabled on self-managed](https://gitlab.com/gitlab-org/gitlab/-/issues/338350) in GitLab 14.6.
+> - [Generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/346598) in GitLab 14.9. [Feature flag preserve_latest_wal_locations_for_idempotent_jobs](https://gitlab.com/gitlab-org/gitlab/-/issues/346598) removed.
The deduplication always take into account the latest binary replication pointer, not the first one.
This happens because we drop the same job scheduled for the second time and the Write-Ahead Log (WAL) is lost.
@@ -199,10 +200,3 @@ To support both deduplication and maintaining data consistency with load balanci
we are preserving the latest WAL location for idempotent jobs in Redis.
This way we are always comparing the latest binary replication pointer,
making sure that we read from the replica that is fully caught up.
-
-FLAG:
-On self-managed GitLab, by default this feature is available. To hide the feature, ask an administrator to
-[disable the feature flag](../../administration/feature_flags.md) named `preserve_latest_wal_locations_for_idempotent_jobs`.
-
-This feature flag is related to GitLab development and is not intended to be used by GitLab administrators, though.
-On GitLab.com, this feature is available.
diff --git a/doc/development/sidekiq/worker_attributes.md b/doc/development/sidekiq/worker_attributes.md
index d681e17a053..3bd6d313e2c 100644
--- a/doc/development/sidekiq/worker_attributes.md
+++ b/doc/development/sidekiq/worker_attributes.md
@@ -259,7 +259,7 @@ these scenarios, since `:always` should be considered the exception, not the rul
To allow for reads to be served from replicas, we added two additional consistency modes: `:sticky` and `:delayed`.
When you declare either `:sticky` or `:delayed` consistency, workers become eligible for database
-load-balancing.
+load-balancing.
In both cases, if the replica is not up-to-date and the time from scheduling the job was less than the minimum delay interval,
the jobs sleep up to the minimum delay interval (0.8 seconds). This gives the replication process time to finish.
diff --git a/doc/development/sidekiq_style_guide.md b/doc/development/sidekiq_style_guide.md
index 3756dd6b598..1b5e7addf29 100644
--- a/doc/development/sidekiq_style_guide.md
+++ b/doc/development/sidekiq_style_guide.md
@@ -6,4 +6,6 @@ remove_date: '2022-04-13'
This document was moved to [another location](sidekiq/index.md).
<!-- This redirect file can be deleted after <2022-04-13>. -->
-<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/#move-or-rename-a-page -->
+<!-- Redirects that point to other docs in the same project expire in three months. -->
+<!-- Redirects that point to docs in a different project or site (for example, link is not relative and starts with `https:`) expire in one year. -->
+<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/redirects.html -->
diff --git a/doc/development/snowplow/implementation.md b/doc/development/snowplow/implementation.md
index d35413cfd5f..6061a1d4cd2 100644
--- a/doc/development/snowplow/implementation.md
+++ b/doc/development/snowplow/implementation.md
@@ -47,10 +47,7 @@ To implement tracking for HAML or Vue templates, add a [`data-track` attribute](
The following example shows `data-track-*` attributes assigned to a button:
```haml
-%button.btn{ data: { track: { action: "click_button", label: "template_preview", property: "my-template" } } }
-
-// or
-// %button.btn{ data: { track_action: "click_button", track_label: "template_preview", track_property: "my-template" } }
+%button.btn{ data: { track_action: "click_button", track_label: "template_preview", track_property: "my-template" } }
```
```html
@@ -69,7 +66,7 @@ The following example shows `data-track-*` attributes assigned to a button:
| `data-track-action` | true | Action the user is taking. Clicks must be prepended with `click` and activations must be prepended with `activate`. For example, focusing a form field is `activate_form_input` and clicking a button is `click_button`. Replaces `data-track-event`, which was [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/290962) in GitLab 13.11. |
| `data-track-label` | false | The specific element or object to act on. This can be: the label of the element, for example, a tab labeled 'Create from template' for `create_from_template`; a unique identifier if no text is available, for example, `groups_dropdown_close` for closing the Groups dropdown in the top bar; or the name or title attribute of a record being created. |
| `data-track-property` | false | Any additional property of the element, or object being acted on. |
-| `data-track-value` | false | Describes a numeric value (decimal) directly related to the event. This could be the value of an input. For example, `10` when clicking `internal` visibility. If omitted, this is the element's `value` property or `undefined`. For checkboxes, the default value is the element's checked attribute or `0` when unchecked. |
+| `data-track-value` | false | Describes a numeric value (decimal) directly related to the event. This could be the value of an input. For example, `10` when clicking `internal` visibility. If omitted, this is the element's `value` property or `undefined`. For checkboxes, the default value is the element's checked attribute or `0` when unchecked. The value is parsed as numeric before sendind the event. |
| `data-track-extra` | false | A key-value pair object passed as a valid JSON string. This attribute is added to the `extra` property in our [`gitlab_standard`](schemas.md#gitlab_standard) schema. |
| `data-track-context` | false | To append a custom context object, passed as a valid JSON string. |
@@ -520,7 +517,7 @@ To install and run Snowplow Micro, complete these steps to modify the
### Troubleshoot
To control content security policy warnings when using an external host, modify `config/gitlab.yml`
-to allow or disallow them. To allow them, add the relevant host for `connect_src`. For example, for
+to allow or prevent them. To allow them, add the relevant host for `connect_src`. For example, for
`https://snowplow.trx.gitlab.net`:
```yaml
diff --git a/doc/development/spam_protection_and_captcha/exploratory_testing.md b/doc/development/spam_protection_and_captcha/exploratory_testing.md
new file mode 100644
index 00000000000..e508265cf83
--- /dev/null
+++ b/doc/development/spam_protection_and_captcha/exploratory_testing.md
@@ -0,0 +1,360 @@
+---
+stage: Manage
+group: Authentication and Authorization
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
+---
+
+# Exploratory testing of CAPTCHAs
+
+You can reliably test CAPTCHA on review apps, and in your local development environment (GDK).
+You can always:
+
+- Force a reCAPTCHA to appear where it is supported.
+- Force a checkbox to display, instead of street sign images to find and select.
+
+To set up testing, follow the configuration on this page.
+
+## Use appropriate test data
+
+Make sure you are testing a scenario which has spam/CAPTCHA enabled. For example:
+make sure you are editing a _public_ snippet, as only public snippets are checked for spam.
+
+## Enable feature flags
+
+Enable any relevant feature flag, if the spam/CAPTCHA support is behind a feature flag.
+
+## Set up Akismet and reCAPTCHA
+
+1. To set up reCAPTCHA:
+ 1. Review the [GitLab reCAPTCHA documentation](../../integration/recaptcha.md).
+ 1. Get Google's official test reCAPTCHA credentials using the instructions from
+ [Google's reCAPTCHA documentation](https://developers.google.com/recaptcha/docs/faq#id-like-to-run-automated-tests-with-recaptcha.-what-should-i-do).
+ 1. For **Site key**, use: `6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI`
+ 1. For **Secret key**, use: `6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe`
+ 1. Go to **Admin -> Settings -> Reporting** settings: `http://gdk.test:3000/admin/application_settings/reporting#js-spam-settings`
+ 1. Select **Enable reCAPTCHA**. Enabling for login is not required unless you are testing that feature.
+ 1. Enter the **Site key** and **Secret key**.
+1. To set up Akismet:
+ 1. Review the [GitLab documentation on Akismet](../../integration/akismet.md).
+ 1. Get an Akismet API key. You can sign up for [a testing key from Akismet](https://akismet.com).
+ You must enter your local host (such as`gdk.test`) and email when signing up.
+ 1. Go to GitLab Akismet settings page, for example:
+ `http://gdk.test:3000/admin/application_settings/reporting#js-spam-settings`
+ 1. Enable Akismet and enter your Akismet **API key**.
+1. To force an Akismet false-positive spam check, refer to the
+ [Akismet API documentation](https://akismet.com/development/api/#comment-check) and
+ [Akismet Getting Started documentation](https://docs.akismet.com/getting-started/confirm/) for more details:
+ 1. You can use `akismet-guaranteed-spam@example.com` as the author email to force spam using the following steps:
+ 1. Go to user email settings: `http://gdk.test:3000/-/profile/emails`
+ 1. Add `akismet-guaranteed-spam@example.com` as a secondary email for the administrator user.
+ 1. Confirm it in the Rails console: `bin/rails c` -> `User.find_by_username('root').emails.last.confirm`
+ 1. Switch this verified email to be your primary email:
+ 1. Go to **Avatar dropdown list -> Edit Profile -> Main Settings**.
+ 1. For **Email**, enter `akismet-guaranteed-spam@example.com` to replace `admin@example.com`.
+ 1. Select **Update Profile Settings** to save your changes.
+
+## Test in the web UI
+
+After you have all the above configuration in place, you can test CAPTCHAs. Test
+in an area of the application which already has CAPTCHA support, such as:
+
+- Creating or editing an issue.
+- Creating or editing a public snippet. Only **public** snippets are checked for spam.
+
+## Test in a development environment
+
+After you force Spam Flagging + CAPTCHA using the steps above, you can test the
+behavior with any spam-protected model/controller action.
+
+### Test with CAPTCHA enabled (CONDITIONAL_ALLOW verdict)
+
+If CAPTCHA is enabled in these areas, you must solve the CAPTCHA popup modal before you can resubmit the form:
+
+- **Admin -> Settings -> Reporting -> Spam**
+- **Anti-bot Protection -> Enable reCAPTCHA**
+
+<!-- vale gitlab.Substitutions = NO -->
+
+### Testing with CAPTCHA disabled ("DISALLOW" verdict)
+
+<!-- vale gitlab.Substitutions = YES -->
+
+If CAPTCHA is disabled in **Admin -> Settings -> Reporting -> Spam** and **Anti-bot Protection -> Enable reCAPTCHA**,
+no CAPTCHA popup displays. You are prevented from submitting the form at all.
+
+### HTML page to render reCAPTCHA
+
+NOTE:
+If you use **Google's official test reCAPTCHA credentials** listed in
+[Set up Akismet and reCAPTCHA](#set-up-akismet-and-recaptcha), the
+CAPTCHA response string does not matter. It can be any string. If you use a
+real, valid key pair, you must solve the CAPTCHA to obtain a
+valid CAPTCHA response to use. You can do this once only, and only before it expires.
+
+To directly test the GraphQL API via [GraphQL Explorer](http://gdk.test:3000/-/graphql-explorer),
+get a reCAPTCHA response string via this form: `public/recaptcha.html` (`http://gdk.test:3000/recaptcha.html`):
+
+```html
+<html>
+<head>
+ <title>reCAPTCHA demo: Explicit render after an onload callback</title>
+ <script type="text/javascript">
+ var onloadCallback = function() {
+ grecaptcha.render('html_element', {
+ 'sitekey' : '6Ld05AsaAAAAAMsm1yTUp4qsdFARN15rQJPPqv6i'
+ });
+ };
+ function onSubmit() {
+ window.document.getElementById('recaptchaResponse').innerHTML = grecaptcha.getResponse();
+ return false;
+ }
+ </script>
+</head>
+<body>
+<form onsubmit="return onSubmit()">
+ <div id="html_element"></div>
+ <br>
+ <input type="submit" value="Submit">
+</form>
+<div>
+ <h1>recaptchaResponse:</h1>
+ <div id="recaptchaResponse"></div>
+</div>
+<script src="https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit"
+ async defer>
+</script>
+</body>
+</html>
+```
+
+## Spam/CAPTCHA API exploratory testing examples
+
+These sections describe the steps needed to perform manual exploratory testing of
+various scenarios of the Spam and CAPTCHA behavior for the REST and GraphQL APIs.
+
+For the prerequisites, you must:
+
+1. Perform all the steps listed above to enable Spam and CAPTCHA in the development environment,
+ and force form submissions to require a CAPTCHA.
+1. Ensure you have created an HTML page to render CAPTCHA under the `/public` directory,
+ with a page that contains a form to manually generate a valid CAPTCHA response string.
+ If you use **Google's official test reCAPTCHA credentials** listed in
+ [Set up Akismet and reCAPTCHA](#set-up-akismet-and-recaptcha), the contents of the
+ CAPTCHA response string don't matter.
+1. Go to **Admin -> Settings -> Reporting -> Spam and Anti-bot protection**.
+1. Select or clear **Enable reCAPTCHA** and **Enable Akismet** according to your
+ scenario's needs.
+
+The following examples use snippet creation as an example. You could also use
+snippet updates, issue creation, or issue updates. Issues and snippets are the
+only models with full Spam and CAPTCHA support.
+
+### Initial setup
+
+1. Create an API token.
+1. Export it in your terminal for the REST commands: `export PRIVATE_TOKEN=<your_api_token>`
+1. Ensure you are logged into GitLab development environment at `localhost:3000` before using GraphiQL explorer,
+ because it uses your logged-in user as authorization for running GraphQL queries.
+1. For the GraphQL examples, use the GraphiQL explorer at `http://localhost:3000/-/graphql-explorer`.
+1. Use the `--include` (`-i`) option to `curl` to print the HTTP response headers, including the status code.
+
+### Scenario: Akismet and CAPTCHA enabled
+
+In this example, Akismet and CAPTCHA are enabled:
+
+1. [Initial request](#initial-request).
+
+<!-- TODO in future edit
+
+Some example videos:
+
+- REST API:
+
+![CAPTCHA REST API](/uploads/b148cbe45496e6f4a4f63d00bb9fbd8a/captcha_rest_api.mov)
+
+GraphQL API:
+
+![CAPTCHA GraphQL API](/uploads/3c7ef0fad0b84bd588572bae51519463/captcha_graphql_api.mov)
+
+-->
+
+#### Initial request
+
+This initial request fails because no CAPTCHA response is provided.
+
+REST request:
+
+```shell
+curl --request POST --header "PRIVATE-TOKEN: $PRIVATE_TOKEN" "http://localhost:3000/api/v4/snippets?title=Title&file_name=FileName&content=Content&visibility=public"
+```
+
+REST response:
+
+```shell
+{"needs_captcha_response":true,"spam_log_id":42,"captcha_site_key":"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX","message":{"error":"Your snippet has been recognized as spam. Please, change the content or solve the reCAPTCHA to proceed."}}
+```
+
+GraphQL request:
+
+```graphql
+mutation {
+ createSnippet(input: {
+ title: "Title"
+ visibilityLevel: public
+ blobActions: [
+ {
+ action: create
+ filePath: "BlobPath"
+ content: "BlobContent"
+ }
+ ]
+ }) {
+ snippet {
+ id
+ title
+ }
+ errors
+ }
+}
+```
+
+GraphQL response:
+
+```json
+{
+ "data": {
+ "createSnippet": null
+ },
+ "errors": [
+ {
+ "message": "Request denied. Solve CAPTCHA challenge and retry",
+ "locations": [
+ {
+ "line": 22,
+ "column": 5
+ }
+ ],
+ "path": [
+ "createSnippet"
+ ],
+ "extensions": {
+ "needs_captcha_response": true,
+ "spam_log_id": 140,
+ "captcha_site_key": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
+ }
+ }
+ ]
+}
+```
+
+#### Second request
+
+This request succeeds because a CAPTCHA response is provided.
+
+REST request:
+
+```shell
+export CAPTCHA_RESPONSE="<CAPTCHA response obtained from HTML page to render CAPTCHA>"
+export SPAM_LOG_ID="<spam_log_id obtained from initial REST response>"
+curl --request POST --header "PRIVATE-TOKEN: $PRIVATE_TOKEN" --header "X-GitLab-Captcha-Response: $CAPTCHA_RESPONSE" --header "X-GitLab-Spam-Log-Id: $SPAM_LOG_ID" "http://localhost:3000/api/v4/snippets?title=Title&file_name=FileName&content=Content&visibility=public"
+```
+
+REST response:
+
+```shell
+{"id":42,"title":"Title","description":null,"visibility":"public", "other_fields": "..."}
+```
+
+GraphQL request:
+
+NOTE:
+The GitLab GraphiQL implementation doesn't allow passing of headers, so we must write
+this as a `curl` query. Here, `--data-binary` is used to properly handle escaped double quotes
+in the JSON-embedded query.
+
+```shell
+export CAPTCHA_RESPONSE="<CAPTCHA response obtained from HTML page to render CAPTCHA>"
+export SPAM_LOG_ID="<spam_log_id obtained from initial REST response>"
+curl --include "http://localhost:3000/api/graphql" --header "Authorization: Bearer $PRIVATE_TOKEN" --header "Content-Type: application/json" --header "X-GitLab-Captcha-Response: $CAPTCHA_RESPONSE" --header "X-GitLab-Spam-Log-Id: $SPAM_LOG_ID" --request POST --data-binary '{"query": "mutation {createSnippet(input: {title: \"Title\" visibilityLevel: public blobActions: [ { action: create filePath: \"BlobPath\" content: \"BlobContent\" } ] }) { snippet { id title } errors }}"}'
+```
+
+GraphQL response:
+
+```json
+{"data":{"createSnippet":{"snippet":{"id":"gid://gitlab/PersonalSnippet/42","title":"Title"},"errors":[]}}}
+```
+
+### Scenario: Akismet enabled, CAPTCHA disabled
+
+For this scenario, ensure you clear **Enable reCAPTCHA** in the Admin Area settings as described above.
+If CAPTCHA is not enabled, any request flagged as potential spam fails with no chance to resubmit,
+even if it could otherwise be resubmitted if CAPTCHA were enabled and successfully solved.
+
+The REST request is the same as if CAPTCHA was enabled:
+
+```shell
+curl --request POST --header "PRIVATE-TOKEN: $PRIVATE_TOKEN" "http://localhost:3000/api/v4/snippets?title=Title&file_name=FileName&content=Content&visibility=public"
+```
+
+REST response:
+
+```shell
+{"message":{"error":"Your snippet has been recognized as spam and has been discarded."}}
+```
+
+GraphQL request:
+
+```graphql
+mutation {
+ createSnippet(input: {
+ title: "Title"
+ visibilityLevel: public
+ blobActions: [
+ {
+ action: create
+ filePath: "BlobPath"
+ content: "BlobContent"
+ }
+ ]
+ }) {
+ snippet {
+ id
+ title
+ }
+ errors
+ }
+}
+```
+
+GraphQL response:
+
+```json
+{
+ "data": {
+ "createSnippet": null
+ },
+ "errors": [
+ {
+ "message": "Request denied. Spam detected",
+ "locations": [
+ {
+ "line": 22,
+ "column": 5
+ }
+ ],
+ "path": [
+ "createSnippet"
+ ],
+ "extensions": {
+ "spam": true
+ }
+ }
+ ]
+}
+```
+
+### Scenario: allow_possible_spam feature flag enabled
+
+With the `allow_possible_spam` feature flag enabled, the API returns a 200 response. Any
+valid request is successful and no CAPTCHA is presented, even if the request is considered
+spam.
diff --git a/doc/development/spam_protection_and_captcha/graphql_api.md b/doc/development/spam_protection_and_captcha/graphql_api.md
new file mode 100644
index 00000000000..b47e3f84320
--- /dev/null
+++ b/doc/development/spam_protection_and_captcha/graphql_api.md
@@ -0,0 +1,66 @@
+---
+stage: Manage
+group: Authentication and Authorization
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
+---
+
+# GraphQL API spam protection and CAPTCHA support
+
+If the model can be modified via the GraphQL API, you must also add support to all of the
+relevant GraphQL mutations which may modify spammable or spam-related attributes. This
+definitely includes the `Create` and `Update` mutations, but may also include others, such as those
+related to changing a model's confidential/public flag.
+
+## Add support to the GraphQL mutations
+
+This implementation is very similar to the controller implementation. You create a `spam_params`
+instance based on the request, and pass it to the relevant Service class constructor.
+
+The three main differences from the controller implementation are:
+
+1. Use `include Mutations::SpamProtection` instead of `...JsonFormatActionsSupport`.
+1. Obtain the request from the context via `context[:request]` when creating the `SpamParams`
+ instance.
+1. After you create or updated the `Spammable` model instance, call `#check_spam_action_response!`
+ and pass it the model instance. This call will:
+ 1. Perform the necessary spam checks on the model.
+ 1. If spam is detected:
+ - Raise a `GraphQL::ExecutionError` exception.
+ - Include the relevant information added as error fields to the response via the `extensions:` parameter.
+ For more details on these fields, refer to the section on
+ [Spam and CAPTCHA support in the GraphQL API](../../api/graphql/index.md#resolve-mutations-detected-as-spam).
+
+ NOTE:
+ If you use the standard ApolloLink or Axios interceptor CAPTCHA support described
+ above, the field details are unimportant. They become important if you
+ attempt to use the GraphQL API directly to process a failed check for potential spam, and
+ resubmit the request with a solved CAPTCHA response.
+
+For example:
+
+```ruby
+module Mutations
+ module Widgets
+ class Create < BaseMutation
+ include Mutations::SpamProtection
+
+ def resolve(args)
+ spam_params = ::Spam::SpamParams.new_from_request(request: context[:request])
+
+ service_response = ::Widgets::CreateService.new(
+ project: project,
+ current_user: current_user,
+ params: args,
+ spam_params: spam_params
+ ).execute
+
+ widget = service_response.payload[:widget]
+ check_spam_action_response!(widget)
+
+ # If possible spam wasdetected, an exception would have been thrown by
+ # `#check_spam_action_response!`, so the normal resolve return logic can follow below.
+ end
+ end
+ end
+end
+```
diff --git a/doc/development/spam_protection_and_captcha/index.md b/doc/development/spam_protection_and_captcha/index.md
new file mode 100644
index 00000000000..9b195df536d
--- /dev/null
+++ b/doc/development/spam_protection_and_captcha/index.md
@@ -0,0 +1,53 @@
+---
+stage: Manage
+group: Authentication and Authorization
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
+---
+
+# Spam protection and CAPTCHA
+
+This guide provides an overview of how to add spam protection and CAPTCHA support to new areas of the
+GitLab application.
+
+## Add spam protection and CAPTCHA support to a new area
+
+To add this support, you must implement the following areas as applicable:
+
+1. [Model and Services](model_and_services.md): The basic prerequisite
+ changes to the backend code which are required to add spam or CAPTCHA API and UI support
+ for a feature which does not yet have support.
+1. REST API (Supported, documentation coming soon): The changes needed to add
+ spam or CAPTCHA support to Grape REST API endpoints. Refer to the related
+ [REST API documentation](../../api/index.md#resolve-requests-detected-as-spam).
+1. [GraphQL API](graphql_api.md): The changes needed to add spam or CAPTCHA support to GraphQL
+ mutations. Refer to the related
+ [GraphQL API documentation](../../api/graphql/index.md#resolve-mutations-detected-as-spam).
+1. [Web UI](web_ui.md): The various possible scenarios encountered when adding
+ spam/CAPTCHA support to the web UI, depending on whether the UI is JavaScript API-based (Vue or
+ plain JavaScript) or HTML-form (HAML) based.
+
+You should also perform manual exploratory testing of the new feature. Refer to
+[Exploratory testing](exploratory_testing.md) for more information.
+
+## Spam-related model and API fields
+
+Multiple levels of spam flagging determine how spam is handled. These levels are referenced in
+[`Spam::SpamConstants`](https://gitlab.com/gitlab-org/gitlab/blob/master/app/services/spam/spam_constants.rb#L4-4),
+and used various places in the application, such as
+[`Spam::SpamActionService#perform_spam_service_check`](https://gitlab.com/gitlab-org/gitlab/blob/d7585b56c9e7dc69414af306d82906e28befe7da/app/services/spam/spam_action_service.rb#L61-61).
+
+The possible values include:
+
+- `BLOCK_USER`
+- `DISALLOW`
+- `CONDITIONAL_ALLOW`
+- `OVERRIDE_VIA_ALLOW_POSSIBLE_SPAM`
+- `ALLOW`
+- `NOOP`
+
+## Related topics
+
+- [Spam and CAPTCHA support in the GraphQL API](../../api/graphql/index.md#resolve-mutations-detected-as-spam)
+- [Spam and CAPTCHA support in the REST API](../../api/index.md#resolve-requests-detected-as-spam)
+- [reCAPTCHA Spam and Anti-bot Protection](../../integration/recaptcha.md)
+- [Akismet and Spam Logs](../../integration/akismet.md)
diff --git a/doc/development/spam_protection_and_captcha/model_and_services.md b/doc/development/spam_protection_and_captcha/model_and_services.md
new file mode 100644
index 00000000000..d0519cba68f
--- /dev/null
+++ b/doc/development/spam_protection_and_captcha/model_and_services.md
@@ -0,0 +1,155 @@
+---
+stage: Manage
+group: Authentication and Authorization
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
+---
+
+# Model and services spam protection and CAPTCHA support
+
+Before adding any spam or CAPTCHA support to the REST API, GraphQL API, or Web UI, you must
+first add the necessary support to:
+
+1. The backend ActiveRecord models.
+1. The services layer.
+
+All or most of the following changes are required, regardless of the type of spam or CAPTCHA request
+implementation you are supporting. Some newer features which are completely based on the GraphQL API
+may not have any controllers, and don't require you to add the `mark_as_spam` action to the controller.
+
+To do this:
+
+1. [Add `Spammable` support to the ActiveRecord model](#add-spammable-support-to-the-activerecord-model).
+1. [Add support for the `mark_as_spam` action to the controller](#add-support-for-the-mark_as_spam-action-to-the-controller).
+1. [Add a call to SpamActionService to the execute method of services](#add-a-call-to-spamactionservice-to-the-execute-method-of-services).
+
+## Add `Spammable` support to the ActiveRecord model
+
+1. Include the `Spammable` module in the model class:
+
+ ```ruby
+ include Spammable
+ ```
+
+1. Add: `attr_spammable` to indicate which fields can be checked for spam. Up to
+ two fields per model are supported: a "`title`" and a "`description`". You can
+ designate which fields to consider the "`title`" or "`description`". For example,
+ this line designates the `content` field as the `description`:
+
+ ```ruby
+ attr_spammable :content, spam_description: true
+ ```
+
+1. Add a `#check_for_spam?` method implementation:
+
+ ```ruby
+ def check_for_spam?(user:)
+ # Return a boolean result based on various applicable checks, which may include
+ # which attributes have changed, the type of user, whether the data is publicly
+ # visible, and other criteria. This may vary based on the type of model, and
+ # may change over time as spam checking requirements evolve.
+ end
+ ```
+
+ Refer to other existing `Spammable` models'
+ implementations of this method for examples of the required logic checks.
+
+## Add support for the `mark_as_spam` action to the controller
+
+The `SpammableActions::AkismetMarkAsSpamAction` module adds support for a `#mark_as_spam` action
+to a controller. This controller allows administrators to manage spam for the associated
+`Spammable` model in the [Spam Log section](../../integration/akismet.md) of the Admin Area page.
+
+1. Include the `SpammableActions::AkismetMarkAsSpamAction` module in the controller.
+
+ ```ruby
+ include SpammableActions::AkismetMarkAsSpamAction
+ ```
+
+1. Add a `#spammable_path` method implementation. The spam administration page redirects
+ to this page after edits. Refer to other existing controllers' implementations
+ of this method for examples of the type of path logic required. In general, it should
+ be the `#show` action for the `Spammable` model's controller.
+
+ ```ruby
+ def spammable_path
+ widget_path(widget)
+ end
+ ```
+
+NOTE:
+There may be other changes needed to controllers, depending on how the feature is
+implemented. See [Web UI](web_ui.md) for more details.
+
+## Add a call to SpamActionService to the execute method of services
+
+This approach applies to any service which can persist spammable attributes:
+
+1. In the relevant Create or Update service under `app/services`, pass in a populated
+ `Spam::SpamParams` instance. (Refer to instructions later on in this page.)
+1. Use it and the `Spammable` model instance to execute a `Spam::SpamActionService` instance.
+1. If the spam check fails:
+ - An error is added to the model, which causes it to be invalid and prevents it from being saved.
+ - The `needs_recaptcha` property is set to `true`.
+
+ These changes to the model enable it for handling by the subsequent backend and frontend CAPTCHA logic.
+
+Make these changes to each relevant service:
+
+1. Change the constructor to take a `spam_params:` argument as a required named argument.
+
+ Using named arguments for the constructor helps you identify all the calls to
+ the constructor that need changing. It's less risky because the interpreter raises
+ type errors unless the caller is changed to pass the `spam_params` argument.
+ If you use an IDE (such as RubyMine) which supports this, your
+ IDE flags it as an error in the editor.
+
+1. In the constructor, set the `@spam_params` instance variable from the `spam_params` constructor
+ argument. Add an `attr_reader: :spam_params` in the `private` section of the class.
+
+1. In the `execute` method, add a call to execute the `Spam::SpamActionService`.
+ (You can also use `before_create` or `before_update`, if the service
+ uses that pattern.) This method uses named arguments, so its usage is clear if
+ you refer to existing examples. However, two important considerations exist:
+ 1. The `SpamActionService` must be executed _after_ all necessary changes are made to
+ the unsaved (and dirty) `Spammable` model instance. This ordering ensures
+ spammable attributes exist to be spam-checked.
+ 1. The `SpamActionService` must be executed _before_ the model is checked for errors and
+ attempting a `save`. If potential spam is detected in the model's changed attributes, we must prevent a save.
+
+```ruby
+module Widget
+ class CreateService < ::Widget::BaseService
+ # NOTE: We require the spam_params and do not default it to nil, because
+ # spam_checking is likely to be necessary. However, if there is not a request available in scope
+ # in the caller (for example, a note created via email) and the required arguments to the
+ # SpamParams constructor are not otherwise available, spam_params: must be explicitly passed as nil.
+ def initialize(project:, current_user: nil, params: {}, spam_params:)
+ super(project: project, current_user: current_user, params: params)
+
+ @spam_params = spam_params
+ end
+
+ def execute
+ widget = Widget::BuildService.new(project, current_user, params).execute
+
+ # More code that may manipulate dirty model before it is spam checked.
+
+ # NOTE: do this AFTER the spammable model is instantiated, but BEFORE
+ # it is validated or saved.
+ Spam::SpamActionService.new(
+ spammable: widget,
+ spam_params: spam_params,
+ user: current_user,
+ # Or `action: :update` for a UpdateService or service for an existing model.
+ action: :create
+ ).execute
+
+ # Possibly more code related to saving model, but should not change any attributes.
+
+ widget.save
+ end
+
+ private
+
+ attr_reader :spam_params
+```
diff --git a/doc/development/spam_protection_and_captcha/web_ui.md b/doc/development/spam_protection_and_captcha/web_ui.md
new file mode 100644
index 00000000000..6aa01f401bd
--- /dev/null
+++ b/doc/development/spam_protection_and_captcha/web_ui.md
@@ -0,0 +1,196 @@
+---
+stage: Manage
+group: Authentication and Authorization
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
+---
+
+# Web UI spam protection and CAPTCHA support
+
+The approach for adding spam protection and CAPTCHA support to a new UI area of the GitLab application
+depends upon how the existing code is implemented.
+
+## Supported scenarios of request submissions
+
+Three different scenarios are supported. Two are used with JavaScript XHR/Fetch requests
+for either Apollo or Axios, and one is used only with standard HTML form requests:
+
+1. A JavaScript-based submission (possibly via Vue)
+ 1. Using Apollo (GraphQL API via Fetch/XHR request)
+ 1. Using Axios (REST API via Fetch/XHR request)
+1. A standard HTML form submission (HTML request)
+
+Some parts of the implementation depend upon which of these scenarios you must support.
+
+## Implementation tasks specific to JavaScript XHR/Fetch requests
+
+Two approaches are fully supported:
+
+1. Apollo, using the GraphQL API.
+1. Axios, using either the GraphQL API.
+
+The spam and CAPTCHA-related data communication between the frontend and backend requires no
+additional fields being added to the models. Instead, communication is handled:
+
+- Through custom header values in the request.
+- Through top-level JSON fields in the response.
+
+The spam and CAPTCHA-related logic is also cleanly abstracted into reusable modules and helper methods
+which can wrap existing logic, and only alter the existing flow if potential spam
+is detected or a CAPTCHA display is needed. This approach allows the spam and CAPTCHA
+support to be easily added to new areas of the application with minimal changes to
+existing logic. In the case of the frontend, potentially **zero** changes are needed!
+
+On the frontend, this is handled abstractly and transparently using `ApolloLink` for Apollo, and an
+Axios interceptor for Axios. The CAPTCHA display is handled by a standard GitLab UI / Pajamas modal
+component. You can find all the relevant frontend code under `app/assets/javascripts/captcha`.
+
+However, even though the actual handling of the request interception and
+modal is transparent, without any mandatory changes to the involved JavaScript or Vue components
+for the form or page, changes in request or error handling may be required. Changes are needed
+because the existing behavior may not work correctly: for example, if a failed or cancelled
+CAPTCHA display interrupts the normal request flow or UI updates.
+Careful exploratory testing of all scenarios is important to uncover any potential
+problems.
+
+This sequence diagram illustrates the normal CAPTCHA flow for JavaScript XHR/Fetch requests
+on the frontend:
+
+```mermaid
+sequenceDiagram
+ participant U as User
+ participant V as Vue/JS Application
+ participant A as ApolloLink or Axios Interceptor
+ participant G as GitLab API
+ U->>V: Save model
+ V->>A: Request
+ A->>G: Request
+ G--xA: Response with error and spam/CAPTCHA related fields
+ A->>U: CAPTCHA presented in modal
+ U->>A: CAPTCHA solved to obtain valid CAPTCHA response
+ A->>G: Request with valid CAPTCHA response and SpamLog ID in headers
+ G-->>A: Response with success
+ A-->>V: Response with success
+```
+
+The backend is also cleanly abstracted via mixin modules and helper methods. The three main
+changes required to the relevant backend controller actions (normally just `create`/`update`) are:
+
+1. Create a `SpamParams` parameter object instance based on the request, using the simple static
+ `#new_from_request` factory method. This method takes a request, and returns a `SpamParams` instance.
+1. Pass the created `SpamParams` instance as the `spam_params` named argument to the
+ Service class constructor, which you should have already added. If the spam check indicates
+ the changes to the model are possibly spam, then:
+ - An error is added to the model.
+ - The `needs_recaptcha` property on the model is set to true.
+1. Wrap the existing controller action return value (rendering or redirecting) in a block passed to
+ a `#with_captcha_check_json_format` helper method, which transparently handles:
+ 1. Check if CAPTCHA is enabled, and if so, proceeding with the next step.
+ 1. Checking if there the model contains an error, and the `needs_recaptcha` flag is true.
+ - If yes: Add the appropriate spam or CAPTCHA fields to the JSON response, and return
+ a `409 - Conflict` HTTP status code.
+ - If no (if CAPTCHA is disabled or if no spam was detected): The normal request return
+ logic passed in the block is run.
+
+Thanks to the abstractions, it's more straightforward to implement than it is to explain it.
+You don't have to worry much about the hidden details!
+
+Make these changes:
+
+## Add support to the controller actions
+
+If the feature's frontend submits directly to controller actions, and does not only use the GraphQL
+API, then you must add support to the appropriate controllers.
+
+The action methods may be directly in the controller class, or they may be abstracted
+to a module included in the controller class. Our example uses a module. The
+only difference when directly modifying the controller:
+`extend ActiveSupport::Concern` is not required.
+
+```ruby
+module WidgetsActions
+ # NOTE: This `extend` probably already exists, but it MUST be moved to occur BEFORE all
+ # `include` statements. Otherwise, confusing bugs may occur in which the methods
+ # in the included modules cannot be found.
+ extend ActiveSupport::Concern
+
+ include SpammableActions::CaptchaCheck::JsonFormatActionsSupport
+
+ def create
+ spam_params = ::Spam::SpamParams.new_from_request(request: request)
+ widget = ::Widgets::CreateService.new(
+ project: project,
+ current_user: current_user,
+ params: params,
+ spam_params: spam_params
+ ).execute
+
+ respond_to do |format|
+ format.json do
+ with_captcha_check_json_format do
+ # The action's existing `render json: ...` (or wrapper method) and related logic. Possibly
+ # including different rendering cases if the model is valid or not. It's all wrapped here
+ # within the `with_captcha_check_json_format` block. For example:
+ if widget.valid?
+ render json: serializer.represent(widget)
+ else
+ render json: { errors: widget.errors.full_messages }, status: :unprocessable_entity
+ end
+ end
+ end
+ end
+ end
+end
+```
+
+## Implementation tasks specific to HTML form requests
+
+Some areas of the application have not been converted to use the GraphQL API via
+a JavaScript client, but instead rely on standard Rails HAML form submissions via an
+`HTML` MIME type request. In these areas, the action returns a pre-rendered HTML (HAML) page
+as the response body. Unfortunately, in this case
+[it is not possible](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/66427#note_636989204)
+to use any of the JavaScript-based frontend support as described above. Instead we must use an
+alternate approach which handles the rendering of the CAPTCHA form via a HAML template.
+
+Everything is still cleanly abstracted, and the implementation in the backend
+controllers is virtually identical to the JavaScript/JSON based approach. Replace the
+word `JSON` with `HTML` (using the appropriate case) in the module names and helper methods.
+
+The action methods might be directly in the controller, or they
+might be in a module. In this example, they are directly in the
+controller, and we also do an `update` method instead of `create`:
+
+```ruby
+class WidgetsController < ApplicationController
+ include SpammableActions::CaptchaCheck::HtmlFormatActionsSupport
+
+ def update
+ # Existing logic to find the `widget` model instance...
+
+ spam_params = ::Spam::SpamParams.new_from_request(request: request)
+ ::Widgets::UpdateService.new(
+ project: project,
+ current_user: current_user,
+ params: params,
+ spam_params: spam_params
+ ).execute(widget)
+
+ respond_to do |format|
+ format.html do
+ if widget.valid?
+ # NOTE: `spammable_path` is required by the `SpammableActions::AkismetMarkAsSpamAction`
+ # module, and it should have already been implemented on this controller according to
+ # the instructions above. It is reused here to avoid duplicating the route helper call.
+ redirect_to spammable_path
+ else
+ # If we got here, there were errors on the model instance - from a failed spam check
+ # and/or other validation errors on the model. Either way, we'll re-render the form,
+ # and if a CAPTCHA render is necessary, it will be automatically handled by
+ # `with_captcha_check_html_format`
+ with_captcha_check_html_format { render :edit }
+ end
+ end
+ end
+ end
+end
+```
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 405ff40ef6a..e0f6cbe632d 100644
--- a/doc/development/testing_guide/end_to_end/best_practices.md
+++ b/doc/development/testing_guide/end_to_end/best_practices.md
@@ -17,13 +17,16 @@ In case custom inflection logic is needed, custom inflectors are added in the [q
## Link a test to its test case
Every test should have a corresponding test case in the [GitLab project Test Cases](https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases) as well as a results issue in the [Quality Test Cases project](https://gitlab.com/gitlab-org/quality/testcases/-/issues).
-It's recommended that you reuse the issue created to plan the test as the results issue. If a test case or results issue does not already exist you
-can create them yourself. Alternatively, you can run the test in a pipeline that has reporting
-enabled and the test-case reporter will automatically create a new test case and/or results issue and link the results issue to it's corresponding test case.
+If a test case issue does not yet exist you can create one yourself. To do so, create a new
+issue in the [Test Cases](https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases) GitLab project
+with a placeholder title. After the test case URL is linked to a test in the code, when the test is
+run in a pipeline that has reporting enabled, the `report-results` script automatically updates the
+test case and the results issue.
+If a results issue does not yet exist, the `report-results` script automatically creates one and
+links it to its corresponding test case.
-Whether you create a new test case or one is created automatically, you will need to manually add
-a `testcase` RSpec metadata tag. In most cases, a single test will be associated with a single test case
- ([see below for exceptions](#exceptions)).
+To link a test case to a test in the code, you must manually add a `testcase` RSpec metadata tag.
+In most cases, a single test is associated with a single test case.
For example:
@@ -41,7 +44,7 @@ RSpec.describe 'Stage' do
end
```
-### Exceptions
+### For shared tests
Most tests are defined by a single line of a `spec` file, which is why those tests can be linked to a
single test case via the `testcase` tag.
@@ -54,24 +57,19 @@ multiple tests, including:
- Templated tests.
- Tests in shared examples that include more than one example.
-In those and similar cases we can't assign a single `testcase` tag and so we rely on the test-case
-reporter to programmatically determine the correct test case based on the name and description of
-the test. In such cases, the test-case reporter will automatically create a test case and/or results issue
-the first time the test runs, if none exist already.
+In those and similar cases we need to include the test case link by other means.
-In such a case, if you create the test case or results issue yourself or want to reuse an existing issue,
-you must use this [end-to-end test issue template](https://gitlab.com/gitlab-org/quality/testcases/-/blob/master/.gitlab/issue_templates/End-to-end%20Test.md)
-to format the issue description. (Note you must copy/paste this for test cases as templates aren't currently available.)
-
-To illustrate, there are two tests in the shared examples in [`qa/specs/features/ee/browser_ui/3_create/repository/restrict_push_protected_branch_spec.rb`](https://gitlab.com/gitlab-org/gitlab/-/blob/47b17db82c38ab704a23b5ba5d296ea0c6a732c8/qa/qa/specs/features/ee/browser_ui/3_create/repository/restrict_push_protected_branch_spec.rb):
+To illustrate, there are two tests in the shared examples in [`qa/specs/features/ee/browser_ui/3_create/repository/restrict_push_protected_branch_spec.rb`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/qa/qa/specs/features/ee/browser_ui/3_create/repository/restrict_push_protected_branch_spec.rb):
```ruby
-shared_examples 'only user with access pushes and merges' do
- it 'unselected maintainer user fails to push' do
+shared_examples 'unselected maintainer' do |testcase|
+ it 'user fails to push', testcase: testcase do
...
end
+end
- it 'selected developer user pushes and merges' do
+shared_examples 'selected developer' do |testcase|
+ it 'user pushes and merges', testcase: testcase do
...
end
end
@@ -84,112 +82,22 @@ RSpec.describe 'Create' do
describe 'Restricted protected branch push and merge' do
context 'when only one user is allowed to merge and push to a protected branch' do
...
- it_behaves_like 'only user with access pushes and merges'
- end
- end
-end
-```
-
-There would be two associated test cases, one for each shared example, with the following content:
-
-[Test 1 Test Case](https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347774):
-
-````markdown
-```markdown
-Title: browser_ui/3_create/repository/restrict_push_protected_branch_spec.rb | Create Restricted
-protected branch push and merge when only one user is allowed to merge and push to a protected
-branch behaves like only user with access pushes and merges selecte...
-
-Description:
-### Full description
-
-Create Restricted protected branch push and merge when only one user is allowed to merge and push
-to a protected branch behaves like only user with access pushes and merges selected developer user
-pushes and merges
-
-### File path
-
-./qa/specs/features/ee/browser_ui/3_create/repository/restrict_push_protected_branch_spec.rb
-
-### DO NOT EDIT BELOW THIS LINE
-
-Active and historical test results:
-
-https://gitlab.com/gitlab-org/quality/testcases/-/issues/2177
-
-```
-````
-
-[Test 1 Results Issue](https://gitlab.com/gitlab-org/quality/testcases/-/issues/2177):
-
-````markdown
-```markdown
-Title: browser_ui/3_create/repository/restrict_push_protected_branch_spec.rb | Create Restricted
-protected branch push and merge when only one user is allowed to merge and push to a protected
-branch behaves like only user with access pushes and merges selecte...
-
-Description:
-### Full description
-
-Create Restricted protected branch push and merge when only one user is allowed to merge and push
-to a protected branch behaves like only user with access pushes and merges selected developer user
-pushes and merges
-
-### File path
-
-./qa/specs/features/ee/browser_ui/3_create/repository/restrict_push_protected_branch_spec.rb
-```
-````
-
-[Test 2 Test Case](https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347775):
-
-````markdown
-```markdown
-Title: browser_ui/3_create/repository/restrict_push_protected_branch_spec.rb | Create Restricted
-protected branch push and merge when only one user is allowed to merge and push to a protected
-branch behaves like only user with access pushes and merges unselec...
-
-Description:
-### Full description
-
-Create Restricted protected branch push and merge when only one user is allowed to merge and push
-to a protected branch behaves like only user with access pushes and merges unselected maintainer
-user fails to push
-
-### File path
-
-./qa/specs/features/ee/browser_ui/3_create/repository/restrict_push_protected_branch_spec.rb
-
-### DO NOT EDIT BELOW THIS LINE
-
-Active and historical test results:
+ it_behaves_like 'unselected maintainer', 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347775'
+ it_behaves_like 'selected developer', 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347774'
+ end
-https://gitlab.com/gitlab-org/quality/testcases/-/issues/2176
+ context 'when only one group is allowed to merge and push to a protected branch' do
+ ...
+ it_behaves_like 'unselected maintainer', 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347772'
+ it_behaves_like 'selected developer', 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347773'
+ end
+ end
+end
```
-````
-
-[Test 2 Results Issue](https://gitlab.com/gitlab-org/quality/testcases/-/issues/2176):
-
-````markdown
-```markdown
-Title: browser_ui/3_create/repository/restrict_push_protected_branch_spec.rb | Create Restricted
-protected branch push and merge when only one user is allowed to merge and push to a protected
-branch behaves like only user with access pushes and merges unselec...
-
-Description:
-### Full description
-
-Create Restricted protected branch push and merge when only one user is allowed to merge and push
-to a protected branch behaves like only user with access pushes and merges unselected maintainer
-user fails to push
-### File path
-
-./qa/specs/features/ee/browser_ui/3_create/repository/restrict_push_protected_branch_spec.rb
-```
-````
+We recommend creating four associated test cases, two for each shared example.
## Prefer API over UI
@@ -518,3 +426,12 @@ Neither problem is present if we create a custom negatable matcher because the `
would be used, which would wait only as long as necessary for the job to disappear.
Lastly, negatable matchers are preferred over using matchers of the form `have_no_*` because it's a common and familiar practice to negate matchers using `not_to`. If we facilitate that practice by adding negatable matchers, we make it easier for subsequent test authors to write efficient tests.
+
+## Use logger over puts
+
+We currently use Rails `logger` to handle logs in both GitLab QA application and end-to-end tests.
+This provides additional functionalities when compared with `puts`, such as:
+
+- Ability to specify the logging level.
+- Ability to tag similar logs.
+- Auto-formatting log messages.
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 238b1ccd8f9..c3e3f117c2b 100644
--- a/doc/development/testing_guide/end_to_end/feature_flags.md
+++ b/doc/development/testing_guide/end_to_end/feature_flags.md
@@ -130,7 +130,7 @@ You can set this variable inside the `fabricate_via_api` call. For a consistent
- Add the word `activated` to the end of a variable's name.
- Inside the `initialize` method, set the variable's default value.
-For example:
+For example:
```ruby
def initialize
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 07f7e9582ee..f9b505a8271 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
@@ -20,7 +20,7 @@ This is a partial list of the [RSpec metadata](https://relishapp.com/rspec/rspec
| `:github` | The test requires a GitHub personal access token. |
| `:group_saml` | The test requires a GitLab instance that has SAML SSO enabled at the group level. Interacts with an external SAML identity provider. Paired with the `:orchestrated` tag. |
| `:instance_saml` | The test requires a GitLab instance that has SAML SSO enabled at the instance level. Interacts with an external SAML identity provider. Paired with the `:orchestrated` tag. |
-| `:integrations` | This aims to test the available [integrations](../../../user/project/integrations/overview.md#integrations-listing). The test requires Docker to be installed in the run context. It will provision the containers and can be run against a local instance or using the `gitlab-qa` scenario `Test::Integration::Integrations` |
+| `:integrations` | This aims to test the available [integrations](../../../user/project/integrations/overview.md#integrations-listing). The test requires Docker to be installed in the run context. It will provision the containers and can be run against a local instance or using the `gitlab-qa` scenario `Test::Integration::Integrations` |
| `:service_ping_disabled` | The test interacts with the GitLab configuration service ping at the instance level to turn admin setting service ping checkbox on or off. This tag will have the test run only in the `service_ping_disabled` job and must be paired with the `:orchestrated` and `:requires_admin` tags. |
| `:jira` | The test requires a Jira Server. [GitLab-QA](https://gitlab.com/gitlab-org/gitlab-qa) provisions the Jira Server in a Docker container when the `Test::Integration::Jira` test scenario is run.
| `:kubernetes` | The test includes a GitLab instance that is configured to be run behind an SSH tunnel, allowing a TLS-accessible GitLab. This test also includes provisioning of at least one Kubernetes cluster to test against. _This tag is often be paired with `:orchestrated`._ |
@@ -42,6 +42,7 @@ This is a partial list of the [RSpec metadata](https://relishapp.com/rspec/rspec
| `:requires_praefect` | The test requires that the GitLab instance uses [Gitaly Cluster](../../../administration/gitaly/praefect.md) (a.k.a. Praefect) as the repository storage . It's assumed to be used by default but if not the test can be skipped by setting `QA_CAN_TEST_PRAEFECT` to `false`. |
| `:runner` | The test depends on and sets up a GitLab Runner instance, typically to run a pipeline. |
| `:skip_live_env` | The test is excluded when run against live deployed environments such as Staging, Canary, and Production. |
+| `:skip_fips_env` | The test is excluded when run against an environment in FIPS mode. |
| `:skip_signup_disabled` | The test uses UI to sign up a new user and is skipped in any environment that does not allow new user registration via the UI. |
| `:smoke` | The test belongs to the test suite which verifies basic functionality of a GitLab instance.|
| `:smtp` | The test requires a GitLab instance to be configured to use an SMTP server. Tests SMTP notification email delivery from GitLab by using MailHog. |
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 7fb95769fc2..49a9124253d 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
@@ -169,135 +169,6 @@ docker run \
Where `interface_ip_address` is your local network's interface IP, which you can find with the `ifconfig` command.
The same would apply to GDK running with the instance address as `localhost` too.
-## Guide to run and debug Monitor tests
-
-### How to set up
-
-To run the Monitor tests locally, against the GDK, please follow the preparation steps below:
-
-1. Complete the [Prerequisites](https://gitlab.com/gitlab-org/gitlab-development-kit/-/blob/main/doc/howto/auto_devops/index.md#prerequisites-for-gitlab-team-members-only), at least through step 5. Note that the monitor tests do not require permissions to work with GKE because they use [k3s as a Kubernetes cluster provider](https://github.com/rancher/k3s).
-1. The test setup deploys the app in a Kubernetes cluster, using the Auto DevOps deployment strategy.
-To enable Auto DevOps in GDK, follow the [associated setup](https://gitlab.com/gitlab-org/gitlab-development-kit/-/blob/main/doc/howto/auto_devops/index.md#setup) instructions. If you have problems, review the [troubleshooting guide](https://gitlab.com/gitlab-org/gitlab-development-kit/-/blob/main/doc/howto/auto_devops/tips_and_troubleshooting.md) or reach out to the `#gdk` channel in the internal GitLab Slack.
-1. Do [secure your GitLab instance](https://gitlab.com/gitlab-org/gitlab-development-kit/-/blob/main/doc/howto/auto_devops/index.md#secure-your-gitlab-instance) since it is now publicly accessible on `https://[YOUR-PORT].qa-tunnel.gitlab.info`.
-1. Install the Kubernetes command line tool known as `kubectl`. Use the [official installation instructions](https://kubernetes.io/docs/tasks/tools/).
-
-You might see NGINX issues when you run `gdk start` or `gdk restart`. In that case, run `sft login` to revalidate your credentials and regain access the QA Tunnel.
-
-### How to run
-
-Navigate to the folder in `/your-gdk/gitlab/qa` and issue the command:
-
-```shell
-QA_DEBUG=true WEBDRIVER_HEADLESS=false GITLAB_ADMIN_USERNAME=rootusername GITLAB_ADMIN_PASSWORD=rootpassword GITLAB_QA_ACCESS_TOKEN=your_token_here GITLAB_QA_ADMIN_ACCESS_TOKEN=your_token_here CLUSTER_API_URL=https://kubernetes.docker.internal:6443 bundle exec bin/qa Test::Instance::All https://[YOUR-PORT].qa-tunnel.gitlab.info/ -- qa/specs/features/browser_ui/8_monitor/all_monitor_core_features_spec.rb --tag kubernetes --tag orchestrated --tag requires_admin
-```
-
-The following includes more information on the command:
-
-- `QA_DEBUG` - Set to `true` to verbosely log page object actions.
-- `WEBDRIVER_HEADLESS` - When running locally, set to `false` to allow browser tests to be visible - watch your tests being run.
-- `GITLAB_ADMIN_USERNAME` - Administrator username to use when adding a license.
-- `GITLAB_ADMIN_PASSWORD` - Administrator password to use when adding a license.
-- `GITLAB_QA_ACCESS_TOKEN` and `GITLAB_QA_ADMIN_ACCESS_TOKEN` - A valid personal access token with the `api` scope. This is used for API access during tests, and is used in the version that staging is currently running. The `ADMIN_ACCESS_TOKEN` is from a user with administrator access. Used for API access as an administrator during tests.
-- `CLUSTER_API_URL` - Use the address `https://kubernetes.docker.internal:6443` . This address is used to enable the cluster to be network accessible while deploying using Auto DevOps.
-- `https://[YOUR-PORT].qa-tunnel.gitlab.info/` - The address of your local GDK
-- `qa/specs/features/browser_ui/8_monitor/all_monitor_core_features_spec.rb` - The path to the monitor core specs
-- `--tag` - the meta-tags used to filter the specs correctly
-
-At the moment of this writing, there are two specs which run monitor tests:
-
-- `qa/specs/features/browser_ui/8_monitor/all_monitor_core_features_spec.rb` - has the specs of features in GitLab Free
-- `qa/specs/features/ee/browser_ui/8_monitor/all_monitor_features_spec.rb` - has the specs of features for paid GitLab (Enterprise Edition)
-
-### How to debug
-
-The monitor tests follow this setup flow:
-
-1. Creates a k3s cluster on your local machine.
-1. Creates a project that has Auto DevOps enabled and uses an Express template (NodeJS) for the app to be deployed.
-1. Associates the created cluster to the project and installs GitLab Runner, Prometheus and Ingress which are the needed components for a successful deployment.
-1. Creates a CI pipeline with 2 jobs (`build` and `production`) to deploy the app on the Kubernetes cluster.
-1. Goes to Operation > Metrics menu to verify data is being received and the app is being monitored successfully.
-
-The test requires a number of components. The setup requires time to collect the metrics of a real deployment.
-The complexity of the setup may lead to problems unrelated to the app. The following sections include common strategies to debug possible issues.
-
-#### Deployment with Auto DevOps
-
-When debugging issues in the CI or locally in the CLI, open the Kubernetes job in the pipeline.
-In the job log window, click on the top right icon labeled as *"Show complete raw"* to reveal raw job logs.
-You can now search through the logs for *Job log*, which matches delimited sections like this one:
-
-```shell
-------- Job log: -------
-```
-
-A Job log is a subsection within these logs, related to app deployment. We use two jobs: `build` and `production`.
-You can find the root causes of deployment failures in these logs, which can compromise the entire test.
-If a `build` job fails, the `production` job doesn't run, and the test fails.
-
-The long test setup does not take screenshots of failures, which is a known [issue](https://gitlab.com/gitlab-org/quality/team-tasks/-/issues/270).
-However, if the spec fails (after a successful deployment) then you should be able to find screenshots which display the feature failure.
-To access them in CI, go to the main job log window, look on the left side panel's Job artifacts section, and click Browse.
-
-#### Common issues
-
-**Container Registry**
-
-When enabling Auto DevOps in the GDK, you may see issues with the Container Registry, which stores
-images of the app to be deployed.
-
-You can access the Registry is available by opening an existing project. On the left hand menu,
-select `Packages & Registries > Container Registries`. If the Registry is available, this page should load normally.
-
-Also, the Registry should be running in Docker:
-
-```shell
-$ docker ps
-
-CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
-f035f339506c registry.gitlab.com/gitlab-org/build/cng/gitlab-container-registry:v2.9.1-gitlab "/bin/sh -c 'exec /b…" 3 hours ago Up 3 hours 0.0.0.0:5000->5000/tcp jovial_proskuriakova
-```
-
-The `gdk status` command shows if the registry is running:
-
-```shell
-run: ./services/registry: (pid 2662) 10875s, normally down; run: log: (pid 65148) 177993s
-run: ./services/tunnel_gitlab: (pid 2650) 10875s, normally down; run: log: (pid 65154) 177993s
-run: ./services/tunnel_registry: (pid 2651) 10875s, normally down; run: log: (pid 65155) 177993s
-```
-
-Also, restarting Docker and then, on the Terminal, issue the command
-`docker login https://[YOUR-REGISTRY-PORT].qa-tunnel.gitlab.info:443` and use
-the GDK credentials to sign in. Note that the Registry port and GDK port aren't
-the same. When configuring Auto DevOps in GDK, the `gdk reconfigure` command
-outputs the port of the Registry:
-
-```shell
-*********************************************
-Tunnel URLs
-
-GitLab: https://[PORT].qa-tunnel.gitlab.info
-Registry: https://[PORT].qa-tunnel.gitlab.info
-*********************************************
-```
-
-These Tunnel URLs are used by the QA SSH Tunnel generated when enabling Auto DevOps on the GDK.
-
-**Pod Eviction**
-
-Pod eviction happens when a node in a Kubernetes cluster is running out of memory or disk. After many local deployments this issue can happen. The UI shows that installing Prometheus, GitLab Runner and Ingress failed. How to be sure it is an Eviction? While the test is running, open another Terminal window and debug the current Kubernetes cluster by `kubectl get pods --all-namespaces`. If you observe that Pods have *Evicted status* such as the install-runner here:
-
-```shell
-$ kubectl get pods --all-namespaces
-
-NAMESPACE NAME READY STATUS RESTARTS AGE
-gitlab-managed-apps install-ingress 0/1 Pending 0 25s
-gitlab-managed-apps install-prometheus 0/1 Pending 0 12s
-gitlab-managed-apps install-runner 0/1 Evicted 0 75s
-```
-
-You can free some memory with either of the following commands: `docker prune system` or `docker prune volume`.
-
## Geo tests
Geo end-to-end tests can run locally against a [Geo GDK setup](https://gitlab.com/gitlab-org/gitlab-development-kit/-/blob/main/doc/howto/geo.md) or on Geo spun up in Docker containers.
diff --git a/doc/development/testing_guide/flaky_tests.md b/doc/development/testing_guide/flaky_tests.md
index 09fc8f4d33e..3c8df7d3416 100644
--- a/doc/development/testing_guide/flaky_tests.md
+++ b/doc/development/testing_guide/flaky_tests.md
@@ -117,14 +117,17 @@ reproduction.
- [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
-
-- Memory is through the roof! (Load images but block images requests!): <https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/12003>
-
#### Capybara expectation times out
- [Test imports a project (via Sidekiq) that is growing over time, leading to timeouts when the import takes longer than 60 seconds](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/22599)
+### Hanging specs
+
+If a spec hangs, it might be caused by a [bug in Rails](https://github.com/rails/rails/issues/34310):
+
+- <https://gitlab.com/gitlab-org/gitlab/-/merge_requests/81112>
+- <https://gitlab.com/gitlab-org/gitlab/-/issues/337039>
+
## Resources
- [Flaky Tests: Are You Sure You Want to Rerun Them?](https://semaphoreci.com/blog/2017/04/20/flaky-tests.html)
diff --git a/doc/development/uploads.md b/doc/development/uploads.md
index 14ecf38e21c..1860f898a26 100644
--- a/doc/development/uploads.md
+++ b/doc/development/uploads.md
@@ -1,430 +1,9 @@
---
-stage: none
-group: unassigned
-info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
+redirect_to: 'uploads/index.md'
+remove_date: '2022-04-30'
---
-# Uploads development documentation
+This document was moved to [another location](uploads/index.md).
-[GitLab Workhorse](https://gitlab.com/gitlab-org/gitlab-workhorse) has special rules for handling uploads.
-We process the upload in Workhorse to prevent occupying a Ruby process on I/O operations and because it is cheaper.
-This process can also directly upload to object storage.
-
-## The problem description
-
-The following graph explains machine boundaries in a scalable GitLab installation. Without any Workhorse optimization in place, we can expect incoming requests to follow the numbers on the arrows.
-
-```mermaid
-graph TB
- subgraph "load balancers"
- LB(Proxy)
- end
-
- subgraph "Shared storage"
- nfs(NFS)
- end
-
- subgraph "redis cluster"
- r(persisted redis)
- end
- LB-- 1 -->Workhorse
-
- subgraph "web or API fleet"
- Workhorse-- 2 -->rails
- end
- rails-- "3 (write files)" -->nfs
- rails-- "4 (schedule a job)" -->r
-
- subgraph sidekiq
- s(sidekiq)
- end
- s-- "5 (fetch a job)" -->r
- s-- "6 (read files)" -->nfs
-```
-
-We have three challenges here: performance, availability, and scalability.
-
-### Performance
-
-Rails process are expensive in terms of both CPU and memory. Ruby [global interpreter lock](https://en.wikipedia.org/wiki/Global_interpreter_lock) adds to cost too because the Ruby process spends time on I/O operations on step 3 causing incoming requests to pile up.
-
-In order to improve this, [disk buffered upload](#disk-buffered-upload) was implemented. With this, Rails no longer deals with writing uploaded files to disk.
-
-```mermaid
-graph TB
- subgraph "load balancers"
- LB(HA Proxy)
- end
-
- subgraph "Shared storage"
- nfs(NFS)
- end
-
- subgraph "redis cluster"
- r(persisted redis)
- end
- LB-- 1 -->Workhorse
-
- subgraph "web or API fleet"
- Workhorse-- "3 (without files)" -->rails
- end
- Workhorse -- "2 (write files)" -->nfs
- rails-- "4 (schedule a job)" -->r
-
- subgraph sidekiq
- s(sidekiq)
- end
- s-- "5 (fetch a job)" -->r
- s-- "6 (read files)" -->nfs
-```
-
-### Availability
-
-There's also an availability problem in this setup, NFS is a [single point of failure](https://en.wikipedia.org/wiki/Single_point_of_failure).
-
-To address this problem an HA object storage can be used and it's supported by [direct upload](#direct-upload)
-
-### Scalability
-
-Scaling NFS is outside of our support scope, and NFS is not a part of cloud native installations.
-
-All features that require Sidekiq and do not use direct upload doesn't work without NFS. In Kubernetes, machine boundaries translate to PODs, and in this case the uploaded file is written into the POD private disk. Since Sidekiq POD cannot reach into other pods, the operation fails to read it.
-
-## How to select the proper level of acceleration?
-
-Selecting the proper acceleration is a tradeoff between speed of development and operational costs.
-
-We can identify three major use-cases for an upload:
-
-1. **storage:** if we are uploading for storing a file (like artifacts, packages, or 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:** 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).
-
-### Handling repository uploads
-
-Some features involves Git repository uploads without using a regular Git client.
-Some examples are uploading a repository file from the web interface and [design management](../user/project/issues/design_management.md).
-
-Those uploads requires the rails controller to act as a Git client in lieu of the user.
-Those operation falls into _in-controller/synchronous processing_ category, but we have no warranties on the file size.
-
-In case of a LFS upload, the file pointer is committed synchronously, but file upload to object storage is performed asynchronously with Sidekiq.
-
-## Upload encodings
-
-By upload encoding we mean how the file is included within the incoming request.
-
-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 APIs upload files as base64-encoded strings. This requires a change to GitLab Workhorse,
- which is tracked [in this issue](https://gitlab.com/gitlab-org/gitlab/-/issues/325068).
-
-## Uploading technologies
-
-By uploading technologies we mean how all the involved services interact with each other.
-
-GitLab supports 3 kinds of uploading technologies, here follows a brief description with a sequence diagram for each one. Diagrams are not meant to be exhaustive.
-
-### Rack Multipart upload
-
-This is the default kind of upload, and it's the most expensive in terms of resources.
-
-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 temporary files in `/tmp` and uses valuable Ruby process time to copy files around.
-
-```mermaid
-sequenceDiagram
- participant c as Client
- participant w as Workhorse
- participant r as Rails
-
- activate c
- c ->>+w: POST /some/url/upload
- w->>+r: POST /some/url/upload
-
- r->>r: save the incoming file on /tmp
- r->>r: read the file for processing
-
- r-->>-c: request result
- deactivate c
- deactivate w
-```
-
-### Disk buffered upload
-
-This kind of upload avoids wasting resources caused by handling upload writes to `/tmp` in rails.
-
-This optimization is not active by default on REST API requests.
-
-When enabled, Workhorse looks for files in multipart MIME requests, uploading
-any it finds to a temporary file on shared storage. The MIME data in the request
-is replaced with the path to the corresponding file before it is forwarded to
-Rails.
-
-To prevent abuse of this feature, Workhorse signs the modified request with a
-special header, stating which entries it modified. Rails ignores any
-unsigned path entries.
-
-```mermaid
-sequenceDiagram
- participant c as Client
- participant w as Workhorse
- participant r as Rails
- participant s as NFS
-
- activate c
- c ->>+w: POST /some/url/upload
-
- w->>+s: save the incoming file on a temporary location
- s-->>-w: request result
-
- w->>+r: POST /some/url/upload
- Note over w,r: file was replaced with its location<br>and other metadata
-
- opt requires async processing
- r->>+redis: schedule a job
- redis-->>-r: job is scheduled
- end
-
- r-->>-c: request result
- deactivate c
- w->>-w: cleanup
-
- opt requires async processing
- activate sidekiq
- sidekiq->>+redis: fetch a job
- redis-->>-sidekiq: job
-
- sidekiq->>+s: read file
- s-->>-sidekiq: file
-
- sidekiq->>sidekiq: process file
-
- deactivate sidekiq
- end
-```
-
-### Direct upload
-
-This is the more advanced acceleration technique we have in place.
-
-Workhorse asks Rails for temporary pre-signed object storage URLs and directly uploads to object storage.
-
-In this setup, an extra Rails route must be implemented in order to handle authorization. Examples of this can be found in:
-
-- [`Projects::LfsStorageController`](https://gitlab.com/gitlab-org/gitlab/-/blob/cc723071ad337573e0360a879cbf99bc4fb7adb9/app/controllers/projects/lfs_storage_controller.rb)
- and [its routes](https://gitlab.com/gitlab-org/gitlab/-/blob/cc723071ad337573e0360a879cbf99bc4fb7adb9/config/routes/git_http.rb#L31-32).
-- [API endpoints for uploading packages](packages.md#file-uploads).
-
-Direct upload falls back to _disk buffered upload_ when `direct_upload` is disabled inside the [object storage setting](../administration/uploads.md#object-storage-settings).
-The answer to the `/authorize` call contains only a file system path.
-
-```mermaid
-sequenceDiagram
- participant c as Client
- participant w as Workhorse
- participant r as Rails
- participant os as Object Storage
-
- activate c
- c ->>+w: POST /some/url/upload
-
- w ->>+r: POST /some/url/upload/authorize
- Note over w,r: this request has an empty body
- r-->>-w: presigned OS URL
-
- w->>+os: PUT file
- Note over w,os: file is stored on a temporary location. Rails select the destination
- os-->>-w: request result
-
- w->>+r: POST /some/url/upload
- Note over w,r: file was replaced with its location<br>and other metadata
-
- r->>+os: move object to final destination
- os-->>-r: request result
-
- opt requires async processing
- r->>+redis: schedule a job
- redis-->>-r: job is scheduled
- end
-
- r-->>-c: request result
- deactivate c
- w->>-w: cleanup
-
- opt requires async processing
- activate sidekiq
- sidekiq->>+redis: fetch a job
- redis-->>-sidekiq: job
-
- sidekiq->>+os: get object
- os-->>-sidekiq: file
-
- sidekiq->>sidekiq: process file
-
- deactivate sidekiq
- end
-```
-
-## How to add a new upload route
-
-In this section, we describe how to add a new upload route [accelerated](#uploading-technologies) by Workhorse for [body and multipart](#upload-encodings) encoded uploads.
-
-Upload routes belong to one of these categories:
-
-1. Rails controllers: uploads handled by Rails controllers.
-1. Grape API: uploads handled by a Grape API endpoint.
-1. GraphQL API: uploads handled by a GraphQL resolve function.
-
-WARNING:
-GraphQL uploads do not support [direct upload](#direct-upload) yet. Depending on the use case, the feature may not work on installations without NFS (like GitLab.com or Kubernetes installations). Uploading to object storage inside the GraphQL resolve function may result in timeout errors. For more details please follow [issue #280819](https://gitlab.com/gitlab-org/gitlab/-/issues/280819).
-
-### Update Workhorse for the new route
-
-For both the Rails controller and Grape API uploads, Workhorse has to be updated in order to get the
-support for the new upload route.
-
-1. Open a new issue in the [Workhorse tracker](https://gitlab.com/gitlab-org/gitlab-workhorse/-/issues/new) describing precisely the new upload route:
- - The route's URL.
- - The [upload encoding](#upload-encodings).
- - If possible, provide a dump of the upload request.
-1. Implement and get the MR merged for this issue above.
-1. Ask the Maintainers of [Workhorse](https://gitlab.com/gitlab-org/gitlab-workhorse) to create a new release. You can do that in the MR
- directly during the maintainer review or ask for it in the `#workhorse` Slack channel.
-1. Bump the [Workhorse version file](https://gitlab.com/gitlab-org/gitlab/-/blob/master/GITLAB_WORKHORSE_VERSION)
- to the version you have from the previous points, or bump it in the same merge request that contains
- the Rails changes (see [Implementing the new route with a Rails controller](#implementing-the-new-route-with-a-rails-controller) or [Implementing the new route with a Grape API endpoint](#implementing-the-new-route-with-a-grape-api-endpoint) below).
-
-### Implementing the new route with a Rails controller
-
-For a Rails controller upload, we usually have a [multipart](#upload-encodings) upload and there are a
-few things to do:
-
-1. The upload is available under the parameter name you're using. For example, it could be an `artifact`
- or a nested parameter such as `user[avatar]`. Let's say that we have the upload under the
- `file` parameter, reading `params[:file]` should get you an [`UploadedFile`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/uploaded_file.rb) instance.
-1. Generally speaking, it's a good idea to check if the instance is from the [`UploadedFile`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/uploaded_file.rb) class. For example, see how we checked
-[that the parameter is indeed an `UploadedFile`](https://gitlab.com/gitlab-org/gitlab/-/commit/ea30fe8a71bf16ba07f1050ab4820607b5658719#51c0cc7a17b7f12c32bc41cfab3649ff2739b0eb_79_77).
-
-WARNING:
-**Do not** call `UploadedFile#from_params` directly! Do not build an [`UploadedFile`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/uploaded_file.rb)
-instance using `UploadedFile#from_params`! This method can be unsafe to use depending on the `params`
-passed. Instead, use the [`UploadedFile`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/uploaded_file.rb)
-instance that [`multipart.rb`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/middleware/multipart.rb)
-builds automatically for you.
-
-### Implementing the new route with a Grape API endpoint
-
-For a Grape API upload, we can have [body or a multipart](#upload-encodings) upload. Things are slightly more complicated: two endpoints are needed. One for the
-Workhorse pre-upload authorization and one for accepting the upload metadata from Workhorse:
-
-1. Implement an endpoint with the URL + `/authorize` suffix that will:
- - Check that the request is coming from Workhorse with the `require_gitlab_workhorse!` from the [API helpers](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/api/helpers.rb).
- - Check user permissions.
- - Set the status to `200` with `status 200`.
- - Set the content type with `content_type Gitlab::Workhorse::INTERNAL_API_CONTENT_TYPE`.
- - Use your dedicated `Uploader` class (let's say that it's `FileUploader`) to build the response with `FileUploader.workhorse_authorize(params)`.
-1. Implement the endpoint for the upload request that will:
- - Require all the `UploadedFile` objects as parameters.
- - For example, if we expect a single parameter `file` to be an [`UploadedFile`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/uploaded_file.rb) instance,
-use `requires :file, type: ::API::Validations::Types::WorkhorseFile`.
- - Body upload requests have their upload available under the parameter `file`.
- - Check that the request is coming from Workhorse with the `require_gitlab_workhorse!` from the
-[API helpers](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/api/helpers.rb).
- - Check the user permissions.
- - The remaining code of the processing. This is where the code must be reading the parameter (for
-our example, it would be `params[:file]`).
-
-WARNING:
-**Do not** call `UploadedFile#from_params` directly! Do not build an [`UploadedFile`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/uploaded_file.rb)
-object using `UploadedFile#from_params`! This method can be unsafe to use depending on the `params`
-passed. Instead, use the [`UploadedFile`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/uploaded_file.rb)
-object that [`multipart.rb`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/middleware/multipart.rb)
-builds automatically for you.
-
-### Document Object Storage buckets and CarrierWave integration
-
-When using Object Storage, GitLab expects each kind of upload to maintain its own bucket in the respective
-Object Storage destination. Moreover, the integration with CarrierWave is not used all the time.
-The [Object Storage Working Group](https://about.gitlab.com/company/team/structure/working-groups/object-storage/)
-is investigating an approach that unifies Object Storage buckets into a single one and removes CarrierWave
-so as to simplify implementation and administration of uploads.
-
-Therefore, document new uploads here by slotting them into the following tables:
-
-- [Feature bucket details](#feature-bucket-details)
-- [CarrierWave integration](#carrierwave-integration)
-
-#### Feature bucket details
-
-| Feature | Upload technology | Uploader | Bucket structure |
-|------------------------------------------|-------------------|-----------------------|-----------------------------------------------------------------------------------------------------------|
-| Job artifacts | `direct upload` | `workhorse` | `/artifacts/<proj_id_hash>/<date>/<job_id>/<artifact_id>` |
-| Pipeline artifacts | `carrierwave` | `sidekiq` | `/artifacts/<proj_id_hash>/pipelines/<pipeline_id>/artifacts/<artifact_id>` |
-| Live job traces | `fog` | `sidekiq` | `/artifacts/tmp/builds/<job_id>/chunks/<chunk_index>.log` |
-| Job traces archive | `carrierwave` | `sidekiq` | `/artifacts/<proj_id_hash>/<date>/<job_id>/<artifact_id>/job.log` |
-| Autoscale runner caching | N/A | `gitlab-runner` | `/gitlab-com-[platform-]runners-cache/???` |
-| Backups | N/A | `s3cmd`, `awscli`, or `gcs` | `/gitlab-backups/???` |
-| Git LFS | `direct upload` | `workhorse` | `/lsf-objects/<lfs_obj_oid[0:2]>/<lfs_obj_oid[2:2]>` |
-| Design management files | `disk buffering` | `rails controller` | `/lsf-objects/<lfs_obj_oid[0:2]>/<lfs_obj_oid[2:2]>` |
-| Design management thumbnails | `carrierwave` | `sidekiq` | `/uploads/design_management/action/image_v432x230/<model_id>` |
-| Generic file uploads | `direct upload` | `workhorse` | `/uploads/@hashed/[0:2]/[2:4]/<hash1>/<hash2>/file` |
-| Generic file uploads - personal snippets | `direct upload` | `workhorse` | `/uploads/personal_snippet/<snippet_id>/<filename>` |
-| Global appearance settings | `disk buffering` | `rails controller` | `/uploads/appearance/...` |
-| Topics | `disk buffering` | `rails controller` | `/uploads/projects/topic/...` |
-| Avatar images | `direct upload` | `workhorse` | `/uploads/[user,group,project]/avatar/<model_id>` |
-| Import/export | `direct upload` | `workhorse` | `/uploads/import_export_upload/???` |
-| GitLab Migration | `carrierwave` | `sidekiq` | `/uploads/bulk_imports/???` |
-| MR diffs | `carrierwave` | `sidekiq` | `/external-diffs/merge_request_diffs/mr-<mr_id>/diff-<diff_id>` |
-| Package manager archives | `direct upload` | `sidekiq` | `/packages/<proj_id_hash>/packages/<pkg_segment>/files/<pkg_file_id>` |
-| Package manager archives | `direct upload` | `sidekiq` | `/packages/<container_id_hash>/debian_*_component_file/<component_file_id>` |
-| Package manager archives | `direct upload` | `sidekiq` | `/packages/<container_id_hash>/debian_*_distribution/<distribution_file_id>` |
-| Container image cache (?) | `direct upload` | `workhorse` | `/dependency-proxy/<group_id_hash>/dependency_proxy/<group_id>/files/<proxy_id>/<blob_id or manifest_id>` |
-| Terraform state files | `carrierwave` | `rails controller` | `/terraform/<proj_id_hash>/<terraform_state_id>` |
-| Pages content archives | `carrierwave` | `sidekiq` | `/gitlab-gprd-pages/<proj_id_hash>/pages_deployments/<deployment_id>/` |
-| Secure Files | `carrierwave` | `sidekiq` | `/ci-secure-files/<proj_id_hash>/secure_files/<secure_file_id>/` |
-
-#### CarrierWave integration
-
-| File | Carrierwave usage | Categorized |
-|---------------------------------------------------------|----------------------------------------------------------------------------------|---------------------|
-| `app/models/project.rb` | `include Avatarable` | :white_check_mark: |
-| `app/models/projects/topic.rb` | `include Avatarable` | :white_check_mark: |
-| `app/models/group.rb` | `include Avatarable` | :white_check_mark: |
-| `app/models/user.rb` | `include Avatarable` | :white_check_mark: |
-| `app/models/terraform/state_version.rb` | `include FileStoreMounter` | :white_check_mark: |
-| `app/models/ci/job_artifact.rb` | `include FileStoreMounter` | :white_check_mark: |
-| `app/models/ci/pipeline_artifact.rb` | `include FileStoreMounter` | :white_check_mark: |
-| `app/models/pages_deployment.rb` | `include FileStoreMounter` | :white_check_mark: |
-| `app/models/lfs_object.rb` | `include FileStoreMounter` | :white_check_mark: |
-| `app/models/dependency_proxy/blob.rb` | `include FileStoreMounter` | :white_check_mark: |
-| `app/models/dependency_proxy/manifest.rb` | `include FileStoreMounter` | :white_check_mark: |
-| `app/models/packages/composer/cache_file.rb` | `include FileStoreMounter` | :white_check_mark: |
-| `app/models/packages/package_file.rb` | `include FileStoreMounter` | :white_check_mark: |
-| `app/models/concerns/packages/debian/component_file.rb` | `include FileStoreMounter` | :white_check_mark: |
-| `ee/app/models/issuable_metric_image.rb` | `include FileStoreMounter` | |
-| `ee/app/models/vulnerabilities/remediation.rb` | `include FileStoreMounter` | |
-| `ee/app/models/vulnerabilities/export.rb` | `include FileStoreMounter` | |
-| `app/models/packages/debian/project_distribution.rb` | `include Packages::Debian::Distribution` | :white_check_mark: |
-| `app/models/packages/debian/group_distribution.rb` | `include Packages::Debian::Distribution` | :white_check_mark: |
-| `app/models/packages/debian/project_component_file.rb` | `include Packages::Debian::ComponentFile` | :white_check_mark: |
-| `app/models/packages/debian/group_component_file.rb` | `include Packages::Debian::ComponentFile` | :white_check_mark: |
-| `app/models/merge_request_diff.rb` | `mount_uploader :external_diff, ExternalDiffUploader` | :white_check_mark: |
-| `app/models/note.rb` | `mount_uploader :attachment, AttachmentUploader` | :white_check_mark: |
-| `app/models/appearance.rb` | `mount_uploader :logo, AttachmentUploader` | :white_check_mark: |
-| `app/models/appearance.rb` | `mount_uploader :header_logo, AttachmentUploader` | :white_check_mark: |
-| `app/models/appearance.rb` | `mount_uploader :favicon, FaviconUploader` | :white_check_mark: |
-| `app/models/project.rb` | `mount_uploader :bfg_object_map, AttachmentUploader` | |
-| `app/models/import_export_upload.rb` | `mount_uploader :import_file, ImportExportUploader` | :white_check_mark: |
-| `app/models/import_export_upload.rb` | `mount_uploader :export_file, ImportExportUploader` | :white_check_mark: |
-| `app/models/ci/deleted_object.rb` | `mount_uploader :file, DeletedObjectUploader` | |
-| `app/models/design_management/action.rb` | `mount_uploader :image_v432x230, DesignManagement::DesignV432x230Uploader` | :white_check_mark: |
-| `app/models/concerns/packages/debian/distribution.rb` | `mount_uploader :signed_file, Packages::Debian::DistributionReleaseFileUploader` | :white_check_mark: |
-| `app/models/bulk_imports/export_upload.rb` | `mount_uploader :export_file, ExportUploader` | :white_check_mark: |
-| `ee/app/models/user_permission_export_upload.rb` | `mount_uploader :file, AttachmentUploader` | |
-| `app/models/ci/secure_file.rb` | `include FileStoreMounter` | |
+<!-- This redirect file can be deleted after 2022-04-30. -->
+<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/#move-or-rename-a-page -->
diff --git a/doc/development/uploads/background.md b/doc/development/uploads/background.md
new file mode 100644
index 00000000000..e68e4127b57
--- /dev/null
+++ b/doc/development/uploads/background.md
@@ -0,0 +1,154 @@
+---
+stage: none
+group: unassigned
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
+---
+
+# Uploads guide: Why GitLab uses custom upload logic
+
+This page is for developers trying to better understand the history behind GitLab uploads and the
+technical challenges associated with uploads.
+
+## Problem description
+
+GitLab and [GitLab Workhorse](https://gitlab.com/gitlab-org/gitlab-workhorse) use special rules for handling file uploads,
+because in an ordinary Rails application file uploads can become expensive as files grow in size.
+Rails often sacrifices performance to provide a better developer experience, including how it handles
+`multipart/form-post` uploads. In any Rack server, Rails applications included, when such a request arrives at the application server,
+several things happen:
+
+1. A [Rack middleware](https://github.com/rack/rack/blob/main/lib/rack/multipart.rb) intercepts the request and parses the request body.
+1. The middleware writes each file in the multipart request to a temporary directory on disk.
+1. A `params` hash is constructed with entries pointing to the respective files on disk.
+1. A Rails controller acts on the file contents.
+
+While this is convenient for developers, it is costly for the Ruby server process to buffer large files on disk.
+Because of Ruby's [global interpreter lock](https://en.wikipedia.org/wiki/Global_interpreter_lock),
+only a single thread of execution of a given Ruby process can be on CPU. This means the amount of CPU
+time spent doing this is not available to other worker threads serving user requests.
+Buffering files to disk also means spending more time in I/O routines and mode switches, which are expensive operations.
+
+The following diagram shows how GitLab handled such a request prior to putting optimizations in place.
+
+```mermaid
+graph TB
+ subgraph "load balancers"
+ LB(Proxy)
+ end
+
+ subgraph "Shared storage"
+ nfs(NFS)
+ end
+
+ subgraph "redis cluster"
+ r(persisted redis)
+ end
+ LB-- 1 -->Workhorse
+
+ subgraph "web or API fleet"
+ Workhorse-- 2 -->rails
+ end
+ rails-- "3 (write files)" -->nfs
+ rails-- "4 (schedule a job)" -->r
+
+ subgraph sidekiq
+ s(sidekiq)
+ end
+ s-- "5 (fetch a job)" -->r
+ s-- "6 (read files)" -->nfs
+```
+
+We went through two major iterations of our uploads architecture to improve on these problems:
+
+1. [Moving disk buffering to Workhorse.](#moving-disk-buffering-to-workhorse)
+1. [Uploading to Object Storage from Workhorse.](#moving-to-object-storage-and-direct-uploads)
+
+### Moving disk buffering to Workhorse
+
+To address the performance issues resulting from buffering files in Ruby, we moved this logic to Workhorse instead,
+our reverse proxy fronting the GitLab Rails application.
+Workhorse is written in Go, and is much better at dealing with stream processing and I/O than Rails.
+
+There are two parts to this implementation:
+
+1. In Workhorse, a request handler detects `multipart/form-data` content in an incoming user request.
+ If such a request is detected, Workhorse hijacks the request body before forwarding it to Rails.
+ Workhorse writes all files to disk, rewrites the multipart form fields to point to the new locations, signs the
+ request, then forwards it to Rails.
+1. In Rails, a [custom multipart Rack middleware](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/middleware/multipart.rb)
+ identifies any signed multipart requests coming from Workhorse and prepares the `params` hash Rails
+ would expect, now pointing to the files cached by Workhorse. This makes it a drop-in replacement for `Rack::Multipart`.
+
+The diagram below shows how GitLab handles such a request today:
+
+```mermaid
+graph TB
+ subgraph "load balancers"
+ LB(HA Proxy)
+ end
+
+ subgraph "Shared storage"
+ nfs(NFS)
+ end
+
+ subgraph "redis cluster"
+ r(persisted redis)
+ end
+ LB-- 1 -->Workhorse
+
+ subgraph "web or API fleet"
+ Workhorse-- "3 (without files)" -->rails
+ end
+ Workhorse -- "2 (write files)" -->nfs
+ rails-- "4 (schedule a job)" -->r
+
+ subgraph sidekiq
+ s(sidekiq)
+ end
+ s-- "5 (fetch a job)" -->r
+ s-- "6 (read files)" -->nfs
+```
+
+While this "one-size-fits-all" solution greatly improves performance for multipart uploads without compromising
+developer ergonomics, it severely limits GitLab [availability](#availability-challenges)
+and [scalability](#scalability-challenges).
+
+#### Availability challenges
+
+Moving file buffering to Workhorse addresses the immediate performance problems stemming from Ruby not being good at
+handling large file uploads. However, a remaining issue of this solution is its reliance on attached storage,
+whether via ordinary hard drives or network attached storage like NFS.
+NFS is a [single point of failure](https://en.wikipedia.org/wiki/Single_point_of_failure), and is unsuitable for
+deploying GitLab in highly available, cloud native environments.
+
+#### Scalability challenges
+
+NFS is not a part of cloud native installations, such as those running in Kubernetes.
+In Kubernetes, machine boundaries translate to pods, and without network-attached storage, disk-buffered uploads
+must be written directly to the pod's file system.
+
+Using disk buffering presents us with a scalability challenge here. If Workhorse can only
+write files to a pod's private file system, then these files are inaccessible outside of this particular pod.
+With disk buffering, a Rails controller will accept a file upload and enqueue it for upload in a Sidekiq
+background job. Therefore, Sidekiq requires access to these files.
+However, in a cloud native environment all Sidekiq instances run on separate pods, so they are
+not able to access files buffered to disk on a web server pod.
+
+Therefore, all features that involve Sidekiq uploading disk-buffered files severely limit the scalability of GitLab.
+
+## Moving to object storage and direct uploads
+
+To address these availability and scalability problems,
+instead of buffering files to disk, we have added support for uploading files directly
+from Workhorse to a given destination. While it remains possible to upload to local or network-attached storage
+this way, you should use a highly available
+[object store](https://en.wikipedia.org/wiki/Object_storage),
+such as AWS S3, Google GCS, or Azure, for scalability reasons.
+
+With direct uploads, Workhorse does not buffer files to disk. Instead, it first authorizes the request with
+the Rails application to find out where to upload it, then streams the file directly to its ultimate destination.
+
+To learn more about how disk buffering and direct uploads are implemented, see:
+
+- [How uploads work technically](implementation.md)
+- [Adding new uploads](working_with_uploads.md)
diff --git a/doc/development/uploads/implementation.md b/doc/development/uploads/implementation.md
new file mode 100644
index 00000000000..13a875cd1af
--- /dev/null
+++ b/doc/development/uploads/implementation.md
@@ -0,0 +1,190 @@
+---
+stage: none
+group: unassigned
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
+---
+
+# Uploads guide: How uploads work technically
+
+This page is for developers trying to better understand what kinds of uploads exist in GitLab and how they are implemented.
+
+## Kinds of uploads and how to choose between them
+
+We can identify three major use-cases for an upload:
+
+1. **storage:** if we are uploading for storing a file (like artifacts, packages, or 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:** 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.
+
+Selecting the proper acceleration is a tradeoff between speed of development and operational costs.
+
+For more details about currently broken feature see [epic &1802](https://gitlab.com/groups/gitlab-org/-/epics/1802).
+
+### Handling repository uploads
+
+Some features involves Git repository uploads without using a regular Git client.
+Some examples are uploading a repository file from the web interface and [design management](../../user/project/issues/design_management.md).
+
+Those uploads requires the rails controller to act as a Git client in lieu of the user.
+Those operation falls into _in-controller/synchronous processing_ category, but we have no warranties on the file size.
+
+In case of a LFS upload, the file pointer is committed synchronously, but file upload to object storage is performed asynchronously with Sidekiq.
+
+## Upload encodings
+
+By upload encoding we mean how the file is included within the incoming request.
+
+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 APIs upload files as base64-encoded strings. This requires a change to GitLab Workhorse,
+ which is tracked [in this issue](https://gitlab.com/gitlab-org/gitlab/-/issues/325068).
+
+## Uploading technologies
+
+By uploading technologies we mean how all the involved services interact with each other.
+
+GitLab supports 3 kinds of uploading technologies, here follows a brief description with a sequence diagram for each one. Diagrams are not meant to be exhaustive.
+
+### Rack Multipart upload
+
+This is the default kind of upload, and it's the most expensive in terms of resources.
+
+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 temporary files in `/tmp` and uses valuable Ruby process time to copy files around.
+
+```mermaid
+sequenceDiagram
+ participant c as Client
+ participant w as Workhorse
+ participant r as Rails
+
+ activate c
+ c ->>+w: POST /some/url/upload
+ w->>+r: POST /some/url/upload
+
+ r->>r: save the incoming file on /tmp
+ r->>r: read the file for processing
+
+ r-->>-c: request result
+ deactivate c
+ deactivate w
+```
+
+### Disk buffered upload
+
+This kind of upload avoids wasting resources caused by handling upload writes to `/tmp` in rails.
+
+This optimization is not active by default on REST API requests.
+
+When enabled, Workhorse looks for files in multipart MIME requests, uploading
+any it finds to a temporary file on shared storage. The MIME data in the request
+is replaced with the path to the corresponding file before it is forwarded to
+Rails.
+
+To prevent abuse of this feature, Workhorse signs the modified request with a
+special header, stating which entries it modified. Rails ignores any
+unsigned path entries.
+
+```mermaid
+sequenceDiagram
+ participant c as Client
+ participant w as Workhorse
+ participant r as Rails
+ participant s as NFS
+
+ activate c
+ c ->>+w: POST /some/url/upload
+
+ w->>+s: save the incoming file on a temporary location
+ s-->>-w: request result
+
+ w->>+r: POST /some/url/upload
+ Note over w,r: file was replaced with its location<br>and other metadata
+
+ opt requires async processing
+ r->>+redis: schedule a job
+ redis-->>-r: job is scheduled
+ end
+
+ r-->>-c: request result
+ deactivate c
+ w->>-w: cleanup
+
+ opt requires async processing
+ activate sidekiq
+ sidekiq->>+redis: fetch a job
+ redis-->>-sidekiq: job
+
+ sidekiq->>+s: read file
+ s-->>-sidekiq: file
+
+ sidekiq->>sidekiq: process file
+
+ deactivate sidekiq
+ end
+```
+
+### Direct upload
+
+This is the more advanced acceleration technique we have in place.
+
+Workhorse asks Rails for temporary pre-signed object storage URLs and directly uploads to object storage.
+
+In this setup, an extra Rails route must be implemented in order to handle authorization. Examples of this can be found in:
+
+- [`Projects::LfsStorageController`](https://gitlab.com/gitlab-org/gitlab/-/blob/cc723071ad337573e0360a879cbf99bc4fb7adb9/app/controllers/projects/lfs_storage_controller.rb)
+ and [its routes](https://gitlab.com/gitlab-org/gitlab/-/blob/cc723071ad337573e0360a879cbf99bc4fb7adb9/config/routes/git_http.rb#L31-32).
+- [API endpoints for uploading packages](../packages.md#file-uploads).
+
+Direct upload falls back to _disk buffered upload_ when `direct_upload` is disabled inside the [object storage setting](../../administration/uploads.md#object-storage-settings).
+The answer to the `/authorize` call contains only a file system path.
+
+```mermaid
+sequenceDiagram
+ participant c as Client
+ participant w as Workhorse
+ participant r as Rails
+ participant os as Object Storage
+
+ activate c
+ c ->>+w: POST /some/url/upload
+
+ w ->>+r: POST /some/url/upload/authorize
+ Note over w,r: this request has an empty body
+ r-->>-w: presigned OS URL
+
+ w->>+os: PUT file
+ Note over w,os: file is stored on a temporary location. Rails select the destination
+ os-->>-w: request result
+
+ w->>+r: POST /some/url/upload
+ Note over w,r: file was replaced with its location<br>and other metadata
+
+ r->>+os: move object to final destination
+ os-->>-r: request result
+
+ opt requires async processing
+ r->>+redis: schedule a job
+ redis-->>-r: job is scheduled
+ end
+
+ r-->>-c: request result
+ deactivate c
+ w->>-w: cleanup
+
+ opt requires async processing
+ activate sidekiq
+ sidekiq->>+redis: fetch a job
+ redis-->>-sidekiq: job
+
+ sidekiq->>+os: get object
+ os-->>-sidekiq: file
+
+ sidekiq->>sidekiq: process file
+
+ deactivate sidekiq
+ end
+```
diff --git a/doc/development/uploads/index.md b/doc/development/uploads/index.md
new file mode 100644
index 00000000000..c486f2d3689
--- /dev/null
+++ b/doc/development/uploads/index.md
@@ -0,0 +1,14 @@
+---
+stage: none
+group: unassigned
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
+---
+
+# Uploads development guide
+
+Uploads are an integral part of many GitLab features. To understand how GitLab handles uploads, refer to
+the following pages:
+
+- [Why GitLab uses custom upload logic.](background.md)
+- [How uploads work technically.](implementation.md)
+- [How to add new uploads.](working_with_uploads.md)
diff --git a/doc/development/uploads/working_with_uploads.md b/doc/development/uploads/working_with_uploads.md
new file mode 100644
index 00000000000..99c04888804
--- /dev/null
+++ b/doc/development/uploads/working_with_uploads.md
@@ -0,0 +1,163 @@
+---
+stage: none
+group: unassigned
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
+---
+
+# Uploads guide: Adding new uploads
+
+In this section, we describe how to add a new upload route [accelerated](implementation.md#uploading-technologies) by Workhorse for [body and multipart](implementation.md#upload-encodings) encoded uploads.
+
+Upload routes belong to one of these categories:
+
+1. Rails controllers: uploads handled by Rails controllers.
+1. Grape API: uploads handled by a Grape API endpoint.
+1. GraphQL API: uploads handled by a GraphQL resolve function.
+
+WARNING:
+GraphQL uploads do not support [direct upload](implementation.md#direct-upload) yet. Depending on the use case, the feature may not work on installations without NFS (like GitLab.com or Kubernetes installations). Uploading to object storage inside the GraphQL resolve function may result in timeout errors. For more details please follow [issue #280819](https://gitlab.com/gitlab-org/gitlab/-/issues/280819).
+
+## Update Workhorse for the new route
+
+For both the Rails controller and Grape API uploads, Workhorse has to be updated in order to get the
+support for the new upload route.
+
+1. Open a new issue in the [Workhorse tracker](https://gitlab.com/gitlab-org/gitlab-workhorse/-/issues/new) describing precisely the new upload route:
+ - The route's URL.
+ - The [upload encoding](implementation.md#upload-encodings).
+ - If possible, provide a dump of the upload request.
+1. Implement and get the MR merged for this issue above.
+1. Ask the Maintainers of [Workhorse](https://gitlab.com/gitlab-org/gitlab-workhorse) to create a new release. You can do that in the MR
+ directly during the maintainer review or ask for it in the `#workhorse` Slack channel.
+1. Bump the [Workhorse version file](https://gitlab.com/gitlab-org/gitlab/-/blob/master/GITLAB_WORKHORSE_VERSION)
+ to the version you have from the previous points, or bump it in the same merge request that contains
+ the Rails changes (see [Implementing the new route with a Rails controller](#implementing-the-new-route-with-a-rails-controller) or [Implementing the new route with a Grape API endpoint](#implementing-the-new-route-with-a-grape-api-endpoint) below).
+
+## Implementing the new route with a Rails controller
+
+For a Rails controller upload, we usually have a [multipart](implementation.md#upload-encodings) upload and there are a
+few things to do:
+
+1. The upload is available under the parameter name you're using. For example, it could be an `artifact`
+ or a nested parameter such as `user[avatar]`. Let's say that we have the upload under the
+ `file` parameter, reading `params[:file]` should get you an [`UploadedFile`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/uploaded_file.rb) instance.
+1. Generally speaking, it's a good idea to check if the instance is from the [`UploadedFile`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/uploaded_file.rb) class. For example, see how we checked
+[that the parameter is indeed an `UploadedFile`](https://gitlab.com/gitlab-org/gitlab/-/commit/ea30fe8a71bf16ba07f1050ab4820607b5658719#51c0cc7a17b7f12c32bc41cfab3649ff2739b0eb_79_77).
+
+WARNING:
+**Do not** call `UploadedFile#from_params` directly! Do not build an [`UploadedFile`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/uploaded_file.rb)
+instance using `UploadedFile#from_params`! This method can be unsafe to use depending on the `params`
+passed. Instead, use the [`UploadedFile`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/uploaded_file.rb)
+instance that [`multipart.rb`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/middleware/multipart.rb)
+builds automatically for you.
+
+## Implementing the new route with a Grape API endpoint
+
+For a Grape API upload, we can have [body or a multipart](implementation.md#upload-encodings) upload. Things are slightly more complicated: two endpoints are needed. One for the
+Workhorse pre-upload authorization and one for accepting the upload metadata from Workhorse:
+
+1. Implement an endpoint with the URL + `/authorize` suffix that will:
+ - Check that the request is coming from Workhorse with the `require_gitlab_workhorse!` from the [API helpers](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/api/helpers.rb).
+ - Check user permissions.
+ - Set the status to `200` with `status 200`.
+ - Set the content type with `content_type Gitlab::Workhorse::INTERNAL_API_CONTENT_TYPE`.
+ - Use your dedicated `Uploader` class (let's say that it's `FileUploader`) to build the response with `FileUploader.workhorse_authorize(params)`.
+1. Implement the endpoint for the upload request that will:
+ - Require all the `UploadedFile` objects as parameters.
+ - For example, if we expect a single parameter `file` to be an [`UploadedFile`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/uploaded_file.rb) instance,
+use `requires :file, type: ::API::Validations::Types::WorkhorseFile`.
+ - Body upload requests have their upload available under the parameter `file`.
+ - Check that the request is coming from Workhorse with the `require_gitlab_workhorse!` from the
+[API helpers](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/api/helpers.rb).
+ - Check the user permissions.
+ - The remaining code of the processing. This is where the code must be reading the parameter (for
+our example, it would be `params[:file]`).
+
+WARNING:
+**Do not** call `UploadedFile#from_params` directly! Do not build an [`UploadedFile`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/uploaded_file.rb)
+object using `UploadedFile#from_params`! This method can be unsafe to use depending on the `params`
+passed. Instead, use the [`UploadedFile`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/uploaded_file.rb)
+object that [`multipart.rb`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/middleware/multipart.rb)
+builds automatically for you.
+
+## Document Object Storage buckets and CarrierWave integration
+
+When using Object Storage, GitLab expects each kind of upload to maintain its own bucket in the respective
+Object Storage destination. Moreover, the integration with CarrierWave is not used all the time.
+The [Object Storage Working Group](https://about.gitlab.com/company/team/structure/working-groups/object-storage/)
+is investigating an approach that unifies Object Storage buckets into a single one and removes CarrierWave
+so as to simplify implementation and administration of uploads.
+
+Therefore, document new uploads here by slotting them into the following tables:
+
+- [Feature bucket details](#feature-bucket-details)
+- [CarrierWave integration](#carrierwave-integration)
+
+### Feature bucket details
+
+| Feature | Upload technology | Uploader | Bucket structure |
+|------------------------------------------|-------------------|-----------------------|-----------------------------------------------------------------------------------------------------------|
+| Job artifacts | `direct upload` | `workhorse` | `/artifacts/<proj_id_hash>/<date>/<job_id>/<artifact_id>` |
+| Pipeline artifacts | `carrierwave` | `sidekiq` | `/artifacts/<proj_id_hash>/pipelines/<pipeline_id>/artifacts/<artifact_id>` |
+| Live job traces | `fog` | `sidekiq` | `/artifacts/tmp/builds/<job_id>/chunks/<chunk_index>.log` |
+| Job traces archive | `carrierwave` | `sidekiq` | `/artifacts/<proj_id_hash>/<date>/<job_id>/<artifact_id>/job.log` |
+| Autoscale runner caching | N/A | `gitlab-runner` | `/gitlab-com-[platform-]runners-cache/???` |
+| Backups | N/A | `s3cmd`, `awscli`, or `gcs` | `/gitlab-backups/???` |
+| Git LFS | `direct upload` | `workhorse` | `/lsf-objects/<lfs_obj_oid[0:2]>/<lfs_obj_oid[2:2]>` |
+| Design management files | `disk buffering` | `rails controller` | `/lsf-objects/<lfs_obj_oid[0:2]>/<lfs_obj_oid[2:2]>` |
+| Design management thumbnails | `carrierwave` | `sidekiq` | `/uploads/design_management/action/image_v432x230/<model_id>` |
+| Generic file uploads | `direct upload` | `workhorse` | `/uploads/@hashed/[0:2]/[2:4]/<hash1>/<hash2>/file` |
+| Generic file uploads - personal snippets | `direct upload` | `workhorse` | `/uploads/personal_snippet/<snippet_id>/<filename>` |
+| Global appearance settings | `disk buffering` | `rails controller` | `/uploads/appearance/...` |
+| Topics | `disk buffering` | `rails controller` | `/uploads/projects/topic/...` |
+| Avatar images | `direct upload` | `workhorse` | `/uploads/[user,group,project]/avatar/<model_id>` |
+| Import/export | `direct upload` | `workhorse` | `/uploads/import_export_upload/???` |
+| GitLab Migration | `carrierwave` | `sidekiq` | `/uploads/bulk_imports/???` |
+| MR diffs | `carrierwave` | `sidekiq` | `/external-diffs/merge_request_diffs/mr-<mr_id>/diff-<diff_id>` |
+| Package manager archives | `direct upload` | `sidekiq` | `/packages/<proj_id_hash>/packages/<pkg_segment>/files/<pkg_file_id>` |
+| Package manager archives | `direct upload` | `sidekiq` | `/packages/<container_id_hash>/debian_*_component_file/<component_file_id>` |
+| Package manager archives | `direct upload` | `sidekiq` | `/packages/<container_id_hash>/debian_*_distribution/<distribution_file_id>` |
+| Container image cache (?) | `direct upload` | `workhorse` | `/dependency-proxy/<group_id_hash>/dependency_proxy/<group_id>/files/<proxy_id>/<blob_id or manifest_id>` |
+| Terraform state files | `carrierwave` | `rails controller` | `/terraform/<proj_id_hash>/<terraform_state_id>` |
+| Pages content archives | `carrierwave` | `sidekiq` | `/gitlab-gprd-pages/<proj_id_hash>/pages_deployments/<deployment_id>/` |
+| Secure Files | `carrierwave` | `sidekiq` | `/ci-secure-files/<proj_id_hash>/secure_files/<secure_file_id>/` |
+
+### CarrierWave integration
+
+| File | Carrierwave usage | Categorized |
+|---------------------------------------------------------|----------------------------------------------------------------------------------|---------------------|
+| `app/models/project.rb` | `include Avatarable` | :white_check_mark: |
+| `app/models/projects/topic.rb` | `include Avatarable` | :white_check_mark: |
+| `app/models/group.rb` | `include Avatarable` | :white_check_mark: |
+| `app/models/user.rb` | `include Avatarable` | :white_check_mark: |
+| `app/models/terraform/state_version.rb` | `include FileStoreMounter` | :white_check_mark: |
+| `app/models/ci/job_artifact.rb` | `include FileStoreMounter` | :white_check_mark: |
+| `app/models/ci/pipeline_artifact.rb` | `include FileStoreMounter` | :white_check_mark: |
+| `app/models/pages_deployment.rb` | `include FileStoreMounter` | :white_check_mark: |
+| `app/models/lfs_object.rb` | `include FileStoreMounter` | :white_check_mark: |
+| `app/models/dependency_proxy/blob.rb` | `include FileStoreMounter` | :white_check_mark: |
+| `app/models/dependency_proxy/manifest.rb` | `include FileStoreMounter` | :white_check_mark: |
+| `app/models/packages/composer/cache_file.rb` | `include FileStoreMounter` | :white_check_mark: |
+| `app/models/packages/package_file.rb` | `include FileStoreMounter` | :white_check_mark: |
+| `app/models/concerns/packages/debian/component_file.rb` | `include FileStoreMounter` | :white_check_mark: |
+| `ee/app/models/issuable_metric_image.rb` | `include FileStoreMounter` | |
+| `ee/app/models/vulnerabilities/remediation.rb` | `include FileStoreMounter` | |
+| `ee/app/models/vulnerabilities/export.rb` | `include FileStoreMounter` | |
+| `app/models/packages/debian/project_distribution.rb` | `include Packages::Debian::Distribution` | :white_check_mark: |
+| `app/models/packages/debian/group_distribution.rb` | `include Packages::Debian::Distribution` | :white_check_mark: |
+| `app/models/packages/debian/project_component_file.rb` | `include Packages::Debian::ComponentFile` | :white_check_mark: |
+| `app/models/packages/debian/group_component_file.rb` | `include Packages::Debian::ComponentFile` | :white_check_mark: |
+| `app/models/merge_request_diff.rb` | `mount_uploader :external_diff, ExternalDiffUploader` | :white_check_mark: |
+| `app/models/note.rb` | `mount_uploader :attachment, AttachmentUploader` | :white_check_mark: |
+| `app/models/appearance.rb` | `mount_uploader :logo, AttachmentUploader` | :white_check_mark: |
+| `app/models/appearance.rb` | `mount_uploader :header_logo, AttachmentUploader` | :white_check_mark: |
+| `app/models/appearance.rb` | `mount_uploader :favicon, FaviconUploader` | :white_check_mark: |
+| `app/models/project.rb` | `mount_uploader :bfg_object_map, AttachmentUploader` | |
+| `app/models/import_export_upload.rb` | `mount_uploader :import_file, ImportExportUploader` | :white_check_mark: |
+| `app/models/import_export_upload.rb` | `mount_uploader :export_file, ImportExportUploader` | :white_check_mark: |
+| `app/models/ci/deleted_object.rb` | `mount_uploader :file, DeletedObjectUploader` | |
+| `app/models/design_management/action.rb` | `mount_uploader :image_v432x230, DesignManagement::DesignV432x230Uploader` | :white_check_mark: |
+| `app/models/concerns/packages/debian/distribution.rb` | `mount_uploader :signed_file, Packages::Debian::DistributionReleaseFileUploader` | :white_check_mark: |
+| `app/models/bulk_imports/export_upload.rb` | `mount_uploader :export_file, ExportUploader` | :white_check_mark: |
+| `ee/app/models/user_permission_export_upload.rb` | `mount_uploader :file, AttachmentUploader` | |
+| `app/models/ci/secure_file.rb` | `include FileStoreMounter` | |
diff --git a/doc/development/value_stream_analytics/img/object_hierarchy_example_V14_10.png b/doc/development/value_stream_analytics/img/object_hierarchy_example_V14_10.png
index 0e3c760fa3c..9c4d4ae7718 100644
--- a/doc/development/value_stream_analytics/img/object_hierarchy_example_V14_10.png
+++ b/doc/development/value_stream_analytics/img/object_hierarchy_example_V14_10.png
Binary files differ
diff --git a/doc/development/workspace/index.md b/doc/development/workspace/index.md
new file mode 100644
index 00000000000..b01a7826b3d
--- /dev/null
+++ b/doc/development/workspace/index.md
@@ -0,0 +1,120 @@
+---
+comments: false
+type: index, dev
+stage: none
+group: Development
+info: "See the Technical Writers assigned to Development Guidelines: https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments-to-development-guidelines"
+description: "Development Guidelines: learn about workspace when developing GitLab."
+---
+
+# Workspace
+
+The [Workspace initiative](../../user/workspace/index.md) focuses on reaching feature parity between
+SaaS and self-managed installations.
+
+## Consolidate groups and projects
+
+- [Architecture blueprint](../../architecture/blueprints/consolidating_groups_and_projects/index.md)
+
+One facet of the workspace initiative is to consolidate groups and projects,
+addressing the feature disparity between them. Some features, such as epics, are
+only available at the group level. Some features, such as issues, are only available
+at the project level. Other features, such as milestones, are available to both groups
+and projects.
+
+We receive many requests to add features either to the group or project level.
+Moving features around to different levels is problematic on multiple levels:
+
+- It requires engineering time to move the features.
+- It requires UX overhead to maintain mental models of feature availability.
+- It creates redundant code.
+
+When features are copied from one level (project, group, or instance) to another,
+the copies often have small, nuanced differences between them. These nuances cause
+extra engineering time when fixes are needed, because the fix must be copied to
+several locations. These nuances also create different user experiences when the
+feature is used in different places.
+
+A solution for this problem is to consolidate groups and projects into a single
+entity, `namespace`. The work on this solution is split into several phases and
+is tracked in [epic 6473](https://gitlab.com/groups/gitlab-org/-/epics/6473).
+
+### Phase 1
+
+- [Phase 1 epic](https://gitlab.com/groups/gitlab-org/-/epics/6697).
+- **Goals**:
+ 1. Ensure every project receives a corresponding record in the `namespaces`
+ table with `type='Project'`.
+ 1. For user namespaces, the type changes from `NULL` to `User`.
+
+We should make sure that projects, and the project namespace, are equivalent:
+
+- **Create project:** use Rails callbacks to ensure a new project namespace is
+ created for each project. Project namespace records should contain `created_at` and
+ `updated_at` attributes equal to the project's `created_at`/`updated_at` attributes.
+- **Update project:** use the `after_save` callback in Rails to ensure some
+ attributes are kept in sync between project and project namespaces.
+ Read [`project#after_save`](https://gitlab.com/gitlab-org/gitlab/blob/6d26634e864d7b748dda0e283eb2477362263bc3/app/models/project.rb#L101-L101)
+ for more information.
+- **Delete project:** use FKs cascade delete or Rails callbacks to ensure when a `Project`
+ or its `ProjectNamespace` is removed, its corresponding `ProjectNamespace` or `Project`
+ is also removed.
+- **Transfer project to a different group:** make sure that when a project is transferred,
+ its corresponding project namespace is transferred to the same group.
+- **Transfer group:** make sure when transferring a group that all of its sub-projects,
+ either direct or through descendant groups, have their corresponding project
+ namespaces transferred correctly as well.
+- **Export or import project**
+ - **Export project** continues to export only the project, and not its project namespace,
+ in this phase. The project namespace does not contain any specific information
+ to export at this point. Eventually we want the project namespace to be exported as well.
+ - **Import project** creates a new project, so the project namespace is created through
+ Rails `after_save` callback on the project model.
+- **Export or import group:** when importing or exporting a `Group`, projects are not
+ included in the operation. If that feature is changed to include `Project` when its group is
+ imported or exported, the logic must include their corresponding project namespaces
+ in the import or export.
+
+After ensuring these points, run a database migration to create a `ProjectNamespace`
+record for every `Project`. Project namespace records created during the migration
+should have `created_at` and `updated_at` attributes set to the migration runtime.
+The project namespaces' `created_at` and `updated_at` attributes would not match
+their corresponding project's `created_at` and `updated_at` attributes. We want
+the different dates to help audit any of the created project namespaces, in case we need it.
+After this work completes, we must migrate data as described in
+[Backfill `ProjectNamespace` for every Project](https://gitlab.com/gitlab-org/gitlab/-/issues/337100).
+
+### Phase 2
+
+- [Phase 2 epic](https://gitlab.com/groups/gitlab-org/-/epics/6768).
+- **Goal**: Make `ProjectNamespace` the front entity to interact with instead of `Project`.
+
+In this phase:
+
+- Communicate the changes company-wide at the engineering level. We want to make
+ engineers aware of the upcoming changes, even though teams are not expected to
+ collaborate actively until phase 3.
+- Raise awareness to avoid regressions, and conflicting or duplicate work that
+ can be dealt with before phase 3.
+
+Problems to solve as part of this phase:
+
+- Routes handling through `ProjectNamespace` rather than `Project`.
+- Memberships handling.
+- Policies handling.
+- Import and export.
+- Other interactions between project namespace and project models.
+
+### Phase 3
+
+- [Phase 3 epic](https://gitlab.com/groups/gitlab-org/-/epics/6585).
+- **Goal**: Feature parity between the namespace types.
+
+Phase 3 is when the active migration of features from `Project` to `ProjectNamespace`,
+or directly to `Namespace`, happens.
+
+## Related topics
+
+- [Consolidating groups and projects](../../architecture/blueprints/consolidating_groups_and_projects/index.md)
+ architecture documentation
+- [Workspace user documentation](../../user/workspace/index.md)
diff --git a/doc/development/workspaces/index.md b/doc/development/workspaces/index.md
deleted file mode 100644
index b36c79e84d7..00000000000
--- a/doc/development/workspaces/index.md
+++ /dev/null
@@ -1,120 +0,0 @@
----
-comments: false
-type: index, dev
-stage: none
-group: Development
-info: "See the Technical Writers assigned to Development Guidelines: https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments-to-development-guidelines"
-description: "Development Guidelines: learn about workspaces when developing GitLab."
----
-
-# Workspaces
-
-The [Workspaces initiative](../../user/workspace/index.md) focuses on reaching feature parity between
-SaaS and self-managed installations.
-
-## Consolidate groups and projects
-
-- [Architecture blueprint](../../architecture/blueprints/consolidating_groups_and_projects/index.md)
-
-One facet of the workspaces initiative is to consolidate groups and projects,
-addressing the feature disparity between them. Some features, such as epics, are
-only available at the group level. Some features, such as issues, are only available
-at the project level. Other features, such as milestones, are available to both groups
-and projects.
-
-We receive many requests to add features either to the group or project level.
-Moving features around to different levels is problematic on multiple levels:
-
-- It requires engineering time to move the features.
-- It requires UX overhead to maintain mental models of feature availability.
-- It creates redundant code.
-
-When features are copied from one level (project, group, or instance) to another,
-the copies often have small, nuanced differences between them. These nuances cause
-extra engineering time when fixes are needed, because the fix must be copied to
-several locations. These nuances also create different user experiences when the
-feature is used in different places.
-
-A solution for this problem is to consolidate groups and projects into a single
-entity, `namespace`. The work on this solution is split into several phases and
-is tracked in [epic 6473](https://gitlab.com/groups/gitlab-org/-/epics/6473).
-
-### Phase 1
-
-- [Phase 1 epic](https://gitlab.com/groups/gitlab-org/-/epics/6697).
-- **Goals**:
- 1. Ensure every project receives a corresponding record in the `namespaces`
- table with `type='Project'`.
- 1. For user namespaces, the type changes from `NULL` to `User`.
-
-We should make sure that projects, and the project namespace, are equivalent:
-
-- **Create project:** use Rails callbacks to ensure a new project namespace is
- created for each project. Project namespace records should contain `created_at` and
- `updated_at` attributes equal to the project's `created_at`/`updated_at` attributes.
-- **Update project:** use the `after_save` callback in Rails to ensure some
- attributes are kept in sync between project and project namespaces.
- Read [`project#after_save`](https://gitlab.com/gitlab-org/gitlab/blob/6d26634e864d7b748dda0e283eb2477362263bc3/app/models/project.rb#L101-L101)
- for more information.
-- **Delete project:** use FKs cascade delete or Rails callbacks to ensure when a `Project`
- or its `ProjectNamespace` is removed, its corresponding `ProjectNamespace` or `Project`
- is also removed.
-- **Transfer project to a different group:** make sure that when a project is transferred,
- its corresponding project namespace is transferred to the same group.
-- **Transfer group:** make sure when transferring a group that all of its sub-projects,
- either direct or through descendant groups, have their corresponding project
- namespaces transferred correctly as well.
-- **Export or import project**
- - **Export project** continues to export only the project, and not its project namespace,
- in this phase. The project namespace does not contain any specific information
- to export at this point. Eventually we want the project namespace to be exported as well.
- - **Import project** creates a new project, so the project namespace is created through
- Rails `after_save` callback on the project model.
-- **Export or import group:** when importing or exporting a `Group`, projects are not
- included in the operation. If that feature is changed to include `Project` when its group is
- imported or exported, the logic must include their corresponding project namespaces
- in the import or export.
-
-After ensuring these points, run a database migration to create a `ProjectNamespace`
-record for every `Project`. Project namespace records created during the migration
-should have `created_at` and `updated_at` attributes set to the migration runtime.
-The project namespaces' `created_at` and `updated_at` attributes would not match
-their corresponding project's `created_at` and `updated_at` attributes. We want
-the different dates to help audit any of the created project namespaces, in case we need it.
-After this work completes, we must migrate data as described in
-[Backfill `ProjectNamespace` for every Project](https://gitlab.com/gitlab-org/gitlab/-/issues/337100).
-
-### Phase 2
-
-- [Phase 2 epic](https://gitlab.com/groups/gitlab-org/-/epics/6768).
-- **Goal**: Make `ProjectNamespace` the front entity to interact with instead of `Project`.
-
-In this phase:
-
-- Communicate the changes company-wide at the engineering level. We want to make
- engineers aware of the upcoming changes, even though teams are not expected to
- collaborate actively until phase 3.
-- Raise awareness to avoid regressions, and conflicting or duplicate work that
- can be dealt with before phase 3.
-
-Problems to solve as part of this phase:
-
-- Routes handling through `ProjectNamespace` rather than `Project`.
-- Memberships handling.
-- Policies handling.
-- Import and export.
-- Other interactions between project namespace and project models.
-
-### Phase 3
-
-- [Phase 3 epic](https://gitlab.com/groups/gitlab-org/-/epics/6585).
-- **Goal**: Feature parity between the namespace types.
-
-Phase 3 is when the active migration of features from `Project` to `ProjectNamespace`,
-or directly to `Namespace`, happens.
-
-## Related topics
-
-- [Consolidating groups and projects](../../architecture/blueprints/consolidating_groups_and_projects/index.md)
- architecture documentation
-- [Workspace user documentation](../../user/workspace/index.md)
diff --git a/doc/install/aws/manual_install_aws.md b/doc/install/aws/manual_install_aws.md
index 26d93ea06b7..b0e71cbc77e 100644
--- a/doc/install/aws/manual_install_aws.md
+++ b/doc/install/aws/manual_install_aws.md
@@ -390,7 +390,7 @@ persistence and is used to store session data, temporary cache information, and
chance to deploy Redis in multiple availability zones.
1. In the settings section:
1. Give the cluster a name (`gitlab-redis`) and a description.
- 1. For the version, select the latest of the `5.0` series (for example, `5.0.6`).
+ 1. For the version, select the latest.
1. Leave the port as `6379` since this is what we used in our Redis security group above.
1. Select the node type (at least `cache.t3.medium`, but adjust to your needs) and the number of replicas.
1. In the advanced settings section:
@@ -827,7 +827,7 @@ to request additional material:
Geo is the solution for widely distributed development teams.
- [Omnibus GitLab](https://docs.gitlab.com/omnibus/) - Everything you need to know
about administering your GitLab instance.
-- [Upload a license](../../user/admin_area/license.md):
+- [Add a license](../../user/admin_area/license.md):
Activate all GitLab Enterprise Edition functionality with a license.
- [Pricing](https://about.gitlab.com/pricing/): Pricing for the different tiers.
diff --git a/doc/install/docker.md b/doc/install/docker.md
index ed5e1dda5d5..a25ed629681 100644
--- a/doc/install/docker.md
+++ b/doc/install/docker.md
@@ -189,7 +189,7 @@ services:
external_url 'http://gitlab.example.com:8929'
gitlab_rails['gitlab_shell_ssh_port'] = 2224
ports:
- - '8929:8929'
+ - '8929:80'
- '2224:22'
volumes:
- '$GITLAB_HOME/config:/etc/gitlab'
@@ -198,7 +198,7 @@ services:
shm_size: '256m'
```
-This is the same as using `--publish 8929:8929 --publish 2224:22`.
+This is the same as using `--publish 8929:80 --publish 2224:22`.
### Install GitLab using Docker swarm mode
@@ -513,6 +513,22 @@ To update GitLab that was [installed using Docker Compose](#install-gitlab-using
If you have used [tags](#use-tagged-versions-of-gitlab) instead, you'll need
to first edit `docker-compose.yml`.
+### Convert Community Edition to Enterprise Edition
+
+You can convert an existing Docker-based GitLab Community Edition (CE) container
+to a GitLab [Enterprise Edition](https://about.gitlab.com/pricing/) (EE) container
+using the same approach as [updating the version](#update).
+
+We recommend you convert from the same version of CE to EE (for example, CE 14.1 to EE 14.1).
+This is not explicitly necessary, and any standard upgrade (for example, CE 14.0 to EE 14.1) should work.
+The following steps assume that you are upgrading the same version.
+
+1. Take a [backup](#back-up-gitlab).
+1. Stop the current CE container, and remove or rename it.
+1. To create a new container with GitLab EE,
+ replace `ce` with `ee` in your `docker run` command or `docker-compose.yml` file.
+ However, reuse the CE container name, port and file mappings, and version.
+
## Back up GitLab
You can create a GitLab backup with:
diff --git a/doc/install/google_cloud_platform/index.md b/doc/install/google_cloud_platform/index.md
index b3d0863f6a3..76c1da74108 100644
--- a/doc/install/google_cloud_platform/index.md
+++ b/doc/install/google_cloud_platform/index.md
@@ -7,7 +7,7 @@ description: 'Learn how to install a GitLab instance on Google Cloud Platform.'
# Installing GitLab on Google Cloud Platform **(FREE SELF)**
-This guide will help you install GitLab on a [Google Cloud Platform (GCP)](https://cloud.google.com/) using the official GitLab Linux package. You should customize it to accommodate your needs.
+You can install GitLab on a [Google Cloud Platform (GCP)](https://cloud.google.com/) using the official GitLab Linux package. You should customize it to accommodate your needs.
NOTE:
To deploy production-ready GitLab on
@@ -19,20 +19,20 @@ the [Cloud native GitLab Helm chart](https://docs.gitlab.com/charts/).
## Prerequisites
-There are only two prerequisites in order to install GitLab on GCP:
+There are two prerequisites to install GitLab on GCP:
-1. You need to have a Google account.
-1. You need to sign up for the GCP program. If this is your first time, Google
+1. You must have a Google account.
+1. You must sign up for the GCP program. If this is your first time, Google
gives you [$300 credit for free](https://console.cloud.google.com/freetrial) to consume over a 60-day period.
-Once you have performed those two steps, you can [create a VM](#creating-the-vm).
+After you have performed those two steps, you can [create a VM](#creating-the-vm).
## Creating the VM
-To deploy GitLab on GCP you first need to create a virtual machine:
+To deploy GitLab on GCP you must create a virtual machine:
1. Go to <https://console.cloud.google.com/compute/instances> and log in with your Google credentials.
-1. Click on **Create**
+1. Select **Create**
![Search for GitLab](img/launch_vm.png)
@@ -43,9 +43,9 @@ To deploy GitLab on GCP you first need to create a virtual machine:
![Launch on Compute Engine](img/vm_details.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.
+ select **Change** under `Boot disk`. select **Select** when finished.
-1. As a last step allow HTTP and HTTPS traffic, then click **Create**. The process finishes in a few seconds.
+1. As a last step allow HTTP and HTTPS traffic, then select **Create**. The process finishes in a few seconds.
## Installing GitLab
@@ -54,7 +54,7 @@ After a few seconds, the instance is created and available to log in. The next s
![Deploy settings](img/vm_created.png)
1. Make a note of the external IP address of the instance, as you will need that in a later step. <!-- using future tense is okay here -->
-1. Click on the SSH button to connect to the instance.
+1. Select **SSH** under the connect column to connect to the instance.
1. A new window appears, with you logged into the instance.
![GitLab first sign in](img/ssh_terminal.png)
@@ -84,7 +84,7 @@ Assuming you have a domain name in your possession and you have correctly
set up DNS to point to the static IP you configured in the previous step,
here's how you configure GitLab to be aware of the change:
-1. SSH into the VM. You can easily use the **SSH** button in the Google console
+1. SSH into the VM. You can select **SSH** in the Google console
and a new window pops up.
![SSH button](img/vm_created.png)
@@ -122,7 +122,7 @@ certificate. Follow the steps in the [Omnibus documentation](https://docs.gitlab
### Configuring the email SMTP settings
-You need to configure the email SMTP settings correctly otherwise GitLab cannot send notification emails, like comments, and password changes.
+You must configure the email SMTP settings correctly otherwise GitLab cannot send notification emails, like comments, and password changes.
Check the [Omnibus documentation](https://docs.gitlab.com/omnibus/settings/smtp.html#smtp-settings) how to do so.
## Further reading
diff --git a/doc/install/index.md b/doc/install/index.md
index 9ffed87fd61..b27d3683cd5 100644
--- a/doc/install/index.md
+++ b/doc/install/index.md
@@ -27,8 +27,8 @@ install GitLab:
| Installation method | Description | When to choose |
|----------------------------------------------------------------|-------------|----------------|
-| [Linux package](https://docs.gitlab.com/omnibus/installation/) | The official deb/rpm packages (also known as Omnibus GitLab) that contains a bundle of GitLab and the components it depends on, including PostgreSQL, Redis, and Sidekiq. | This is the recommended method for getting started. The Linux packages are mature, scalable, and are used today on GitLab.com. If you need additional flexibility and resilience, we recommend deploying GitLab as described in the [reference architecture documentation](../administration/reference_architectures/index.md). |
-| [Helm charts](https://docs.gitlab.com/charts/) | The cloud native Helm chart for installing GitLab and all of its components on Kubernetes. | When installing GitLab on Kubernetes, there are some trade-offs that you need to be aware of: <br/>- Administration and troubleshooting requires Kubernetes knowledge.<br/>- It can be more expensive for smaller installations. The default installation requires more resources than a single node Linux package deployment, as most services are deployed in a redundant fashion.<br/>- There are some feature [limitations to be aware of](https://docs.gitlab.com/charts/#limitations).<br/><br/> Use this method if your infrastructure is built on Kubernetes and you're familiar with how it works. The methods for management, observability, and some concepts are different than traditional deployments. |
+| [Linux package](https://docs.gitlab.com/omnibus/installation/) | The official deb/rpm packages (also known as Omnibus GitLab) that contains a bundle of GitLab and the components it depends on, including PostgreSQL, Redis, and Sidekiq. | This method is recommended for getting started. The Linux packages are mature, scalable, and are used today on GitLab.com. If you need additional flexibility and resilience, we recommend deploying GitLab as described in the [reference architecture documentation](../administration/reference_architectures/index.md). |
+| [Helm charts](https://docs.gitlab.com/charts/) | The cloud native Helm chart for installing GitLab and all of its components on Kubernetes. | When installing GitLab on Kubernetes, there are some trade-offs that you need to be aware of: <br/>- Administration and troubleshooting requires Kubernetes knowledge.<br/>- It can be more expensive for smaller installations. The default installation requires more resources than a single node Linux package deployment, as most services are deployed in a redundant fashion.<br/><br/> Use this method if your infrastructure is built on Kubernetes and you're familiar with how it works. The methods for management, observability, and some concepts are different than traditional deployments. |
| [Docker](https://docs.gitlab.com/omnibus/docker/) | The GitLab packages, Dockerized. | Use this method if you're familiar with Docker. |
| [Source](installation.md) | Install GitLab and all of its components from scratch. | Use this method if none of the previous methods are available for your platform. Useful for unsupported systems like \*BSD.|
| [GitLab Environment Toolkit (GET)](https://gitlab.com/gitlab-org/gitlab-environment-toolkit#documentation) | The GitLab Environment toolkit provides a set of automation tools to deploy a [reference architecture](../administration/reference_architectures/index.md) on most major cloud providers. | Customers are very welcome to trial and evaluate GET today, however be aware of [key limitations](https://gitlab.com/gitlab-org/gitlab-environment-toolkit#missing-features-to-be-aware-of) of the current iteration. For production environments further manual setup will be required based on your specific requirements. |
diff --git a/doc/install/next_steps.md b/doc/install/next_steps.md
index 1db2bf9b7b6..2fc60c3af53 100644
--- a/doc/install/next_steps.md
+++ b/doc/install/next_steps.md
@@ -50,7 +50,7 @@ installation.
## License
-- [Upload a license](../user/admin_area/license.md) or [start a free trial](https://about.gitlab.com/free-trial/):
+- [Add a license](../user/admin_area/license.md) or [start a free trial](https://about.gitlab.com/free-trial/):
Activate all GitLab Enterprise Edition functionality with a license.
- [Pricing](https://about.gitlab.com/pricing/): Pricing for the different tiers.
diff --git a/doc/install/openshift_and_gitlab/index.md b/doc/install/openshift_and_gitlab/index.md
index e102235c4f0..364c27f089f 100644
--- a/doc/install/openshift_and_gitlab/index.md
+++ b/doc/install/openshift_and_gitlab/index.md
@@ -20,7 +20,7 @@ Some components (documented on the GitLab Operator doc) are not supported yet.
## Deploy to and integrate with OpenShift from GitLab
-Deploying custom or COTS applications on top of OpenShift from GitLab is supported using [the GitLab Agent](../../user/clusters/agent/index.md).
+Deploying custom or COTS applications on top of OpenShift from GitLab is supported using [the GitLab agent](../../user/clusters/agent/index.md).
## Use OpenShift to run a GitLab Runner Fleet
@@ -29,6 +29,12 @@ The GitLab Operator does not include the GitLab Runner. To install and manage a
## Unsupported GitLab features
+### Secure and Protect
+
+- License Compliance
+- Code Quality scanning
+- Cluster Image Scanning
+
### Docker-in-Docker
When using OpenShift to run a GitLab Runner Fleet, we do not support some GitLab features given OpenShift's security model.
diff --git a/doc/install/pivotal/index.md b/doc/install/pivotal/index.md
index ee379a3c95f..56dde411884 100644
--- a/doc/install/pivotal/index.md
+++ b/doc/install/pivotal/index.md
@@ -6,4 +6,6 @@ remove_date: '2022-03-08'
This document was removed. For information about installing GitLab, see [this page](../index.md).
<!-- This redirect file can be deleted after <2022-03-08>. -->
-<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/#move-or-rename-a-page -->
+<!-- Redirects that point to other docs in the same project expire in three months. -->
+<!-- Redirects that point to docs in a different project or site (for example, link is not relative and starts with `https:`) expire in one year. -->
+<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/redirects.html -->
diff --git a/doc/install/relative_url.md b/doc/install/relative_url.md
index 43f2414e8f9..831e33870bd 100644
--- a/doc/install/relative_url.md
+++ b/doc/install/relative_url.md
@@ -6,7 +6,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Install GitLab under a relative URL **(FREE SELF)**
-While it is recommended to install GitLab on its own (sub)domain, sometimes
+While we recommend to install GitLab on its own (sub)domain, sometimes
this is not possible due to a variety of reasons. In that case, GitLab can also
be installed under a relative URL, for example `https://example.com/gitlab`.
@@ -19,8 +19,8 @@ first time.
There is no limit to how deeply nested the relative URL can be. For example you
could serve GitLab under `/foo/bar/gitlab/git` without any issues.
-Note that by changing the URL on an existing GitLab installation, all remote
-URLs will change, so you'll have to manually edit them in any local repository
+Changing the URL on an existing GitLab installation, changes all remote
+URLs, so you have to manually edit them in any local repository
that points to your GitLab instance.
The list of configuration files you must change to serve GitLab from a
@@ -32,7 +32,7 @@ relative URL is:
- `/home/git/gitlab-shell/config.yml`
- `/etc/default/gitlab`
-After all the changes you need to recompile the assets and [restart GitLab](../administration/restart_gitlab.md#installations-from-source).
+After all the changes, you must recompile the assets and [restart GitLab](../administration/restart_gitlab.md#installations-from-source).
## Relative URL requirements
diff --git a/doc/install/requirements.md b/doc/install/requirements.md
index bce9702b032..11f623641c1 100644
--- a/doc/install/requirements.md
+++ b/doc/install/requirements.md
@@ -258,7 +258,7 @@ works.
### Puma per worker maximum memory
By default, each Puma worker will be limited to 1024 MB of memory.
-This setting [can be adjusted](../administration/operations/puma.md#puma-worker-killer) and should be considered
+This setting [can be adjusted](../administration/operations/puma.md#change-the-memory-limit-setting) and should be considered
if you need to increase the number of Puma workers.
## Redis and Sidekiq
@@ -303,7 +303,7 @@ The GitLab Runner server requirements depend on:
Since the nature of the jobs varies for each use case, you need to experiment by adjusting the job concurrency to get the optimum setting.
-For reference, the [SaaS runners on Linux](../ci/runners/build_cloud/linux_build_cloud.md)
+For reference, the [SaaS runners on Linux](../ci/runners/saas/linux_saas_runner.md)
are configured so that a **single job** runs in a **single instance** with:
- 1 vCPU.
diff --git a/doc/integration/azure.md b/doc/integration/azure.md
index 8d69881699b..5749e638164 100644
--- a/doc/integration/azure.md
+++ b/doc/integration/azure.md
@@ -4,135 +4,45 @@ group: Integrations
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
-# Microsoft Azure OAuth 2.0 OmniAuth Provider **(FREE SELF)**
+# Use Microsoft Azure as an authentication provider **(FREE SELF)**
-NOTE:
-Per Microsoft, this provider uses the [older Azure Active Directory v1.0 endpoint](https://docs.microsoft.com/en-us/azure/active-directory/azuread-dev/v1-protocols-oauth-code).
-Microsoft documentation suggests that you should use the [OpenID Connect protocol to use the v2 endpoints](../administration/auth/oidc.md#microsoft-azure) for new projects.
-To use v2 endpoints via OmniAuth, please follow [Microsoft Azure OAuth 2.0 OmniAuth Provider v2 instructions](#microsoft-azure-oauth-20-omniauth-provider-v2).
-
-To enable the Microsoft Azure OAuth 2.0 OmniAuth provider, you must register
-your application with Azure. Azure generates a client ID and secret key for you
-to use.
-
-Sign in to the [Azure Portal](https://portal.azure.com), and follow the
-instructions in the [Microsoft Quickstart documentation](https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-register-app).
-
-As you go through the Microsoft procedure, keep the following in mind:
-
-- If you have multiple instances of Azure Active Directory, you can switch to the desired tenant.
-- You're setting up a Web application.
-- The redirect URI requires the URL of the Azure OAuth callback of your GitLab
- installation. For example, `https://gitlab.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.0. In some Microsoft documentation,
- the terms may be listed as `Application ID` and `Application Secret`.
-- If you have to generate a new client secret, follow the Microsoft documentation
- for [creating a new application secret](https://docs.microsoft.com/en-us/azure/active-directory/develop/howto-create-service-principal-portal#create-a-new-application-secret).
-- Save the client ID and client secret for your new app, as the client secret is only
- displayed one time.
-
-1. On your GitLab server, open the configuration file.
-
- For Omnibus GitLab:
-
- ```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. Refer to [Configure initial settings](omniauth.md#configure-initial-settings)
- for initial settings.
-
-1. Add the provider configuration:
-
- For Omnibus GitLab:
-
- ```ruby
- gitlab_rails['omniauth_providers'] = [
- {
- name: "azure_oauth2",
- # label: "Provider name", # optional label for login button, defaults to "Azure AD"
- args: {
- client_id: "CLIENT ID",
- client_secret: "CLIENT SECRET",
- tenant_id: "TENANT ID",
- }
- }
- ]
- ```
-
- For installations from source:
+You can enable the Microsoft Azure OAuth 2.0 OmniAuth provider and sign in to
+GitLab with your Microsoft Azure credentials. You can configure the provider that uses
+[the earlier Azure Active Directory v1.0 endpoint](https://docs.microsoft.com/en-us/azure/active-directory/azuread-dev/v1-protocols-oauth-code),
+or the provider that uses the v2.0 endpoint.
- ```yaml
- - { name: 'azure_oauth2',
- # label: 'Provider name', # optional label for login button, defaults to "Azure AD"
- args: { client_id: 'CLIENT ID',
- client_secret: 'CLIENT SECRET',
- tenant_id: 'TENANT ID' } }
- ```
-
- The `base_azure_url` is optional and can be added for different locales;
- such as `base_azure_url: "https://login.microsoftonline.de"`.
-
-1. Replace `CLIENT ID`, `CLIENT SECRET` and `TENANT ID` with the values you got above.
-
-1. Save the configuration file.
-
-1. Reconfigure or restart GitLab, depending on your installation method:
-
- - *If you installed from Omnibus GitLab,*
- [reconfigure](../administration/restart_gitlab.md#omnibus-gitlab-reconfigure) GitLab.
- - *If you installed from source,*
- [restart GitLab](../administration/restart_gitlab.md#installations-from-source).
-
-On the sign-in page, you should now see a Microsoft icon below the regular
-sign-in form. Click the icon to begin the authentication process. Microsoft then
-asks you to sign in and authorize the GitLab application. If successful, you are
-returned to GitLab and signed in.
-
-Read [Enable OmniAuth for an Existing User](omniauth.md#enable-omniauth-for-an-existing-user)
-for information on how existing GitLab users can connect to their newly-available Azure AD accounts.
-
-## Microsoft Azure OAuth 2.0 OmniAuth Provider v2
-
-To use v2 endpoints provided by Microsoft Azure Active Directory you must to
-configure it via Azure OAuth 2.0 OmniAuth Provider v2.
+NOTE:
+For new projects, Microsoft suggests you use the
+[OpenID Connect protocol](../administration/auth/oidc.md#microsoft-azure),
+which uses the Microsoft identity platform (v2.0) endpoint.
-### Registering an Azure application
+## Register an Azure application
To enable the Microsoft Azure OAuth 2.0 OmniAuth provider, you must register
-your application with Azure. Azure generates a client ID and secret key for you
-to use.
+an Azure application and get a client ID and secret key.
-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. Sign in to the [Azure portal](https://portal.azure.com).
+1. If you have multiple Azure Active Directory tenants, switch to the desired tenant.
+1. [Register an application](https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-register-app)
+ and provide the following information:
+ - The redirect URI, which requires the URL of the Azure OAuth callback of your GitLab
+ installation. For example:
+ - For the v1.0 endpoint: `https://gitlab.example.com/users/auth/azure_oauth2/callback`.
+ - For the v2.0 endpoint: `https://gitlab.example.com/users/auth/azure_activedirectory_v2/callback`.
+ - The application type, which must be set to **Web**.
+1. Save the client ID and client secret. The client secret is only
+ displayed once.
-As you go through the Microsoft procedure, keep the following in mind:
+ If required, you can [create a new application secret](https://docs.microsoft.com/en-us/azure/active-directory/develop/howto-create-service-principal-portal#option-2-create-a-new-application-secret).
-- If you have multiple instances of Azure Active Directory, you can switch to
- the desired tenant.
-- You're setting up a Web application.
-- The redirect URI requires the URL of the Azure OAuth callback of your GitLab
- installation. For example, `https://gitlab.example.com/users/auth/azure_activedirectory_v2/callback`.
- The type dropdown should be set to **Web**.
-- The `client ID` and `client secret` are terms associated with OAuth 2.0. In some Microsoft documentation,
- the terms may be listed as `Application ID` and `Application Secret`.
-- If you have to generate a new client secret, follow the Microsoft documentation
- for [creating a new application secret](https://docs.microsoft.com/en-us/azure/active-directory/develop/howto-create-service-principal-portal#create-a-new-application-secret).
-- Save the client ID and client secret for your new app, as the client secret is only
- displayed one time.
+`client ID` and `client secret` are terms associated with OAuth 2.0.
+In some Microsoft documentation, the terms are named `Application ID` and
+`Application Secret`.
-### Adding API permissions (scopes)
+## Add API permissions (scopes)
-After you have created an application, follow the [Microsoft Quickstart documentation to expose a web API](https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-configure-app-expose-web-apis). Be sure to add the following delegated permissions under the Microsoft Graph API:
+If you're using the v2.0 endpoint, after you create the application, [configure it to expose a web API](https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-configure-app-expose-web-apis).
+Add the following delegated permissions under the Microsoft Graph API:
- `email`
- `openid`
@@ -140,75 +50,100 @@ After you have created an application, follow the [Microsoft Quickstart document
Alternatively, add the `User.Read.All` application permission.
-### Configuring GitLab
+## Enable Microsoft OAuth in GitLab
1. On your GitLab server, open the configuration file.
- For Omnibus GitLab:
+ - **For Omnibus installations**
+
+ ```shell
+ sudo editor /etc/gitlab/gitlab.rb
+ ```
- ```shell
- sudo editor /etc/gitlab/gitlab.rb
- ```
+ - **For installations from source**
- For installations from source:
+ ```shell
+ cd /home/git/gitlab
- ```shell
- cd /home/git/gitlab
+ sudo -u git -H editor config/gitlab.yml
+ ```
- sudo -u git -H editor config/gitlab.yml
- ```
+1. [Configure the initial settings](omniauth.md#configure-initial-settings).
-1. Refer to [Configure initial settings](omniauth.md#configure-initial-settings)
- for initial settings.
+1. Add the provider configuration. Replace `CLIENT ID`, `CLIENT SECRET`, and `TENANT ID`
+ with the values you got when you registered the Azure application.
-1. Add the provider configuration:
+ - **For Omnibus installations**
- For Omnibus GitLab:
+ For the v1.0 endpoint:
- ```ruby
- gitlab_rails['omniauth_providers'] = [
- {
- "name" => "azure_activedirectory_v2",
- "label" => "Provider name", # optional label for login button, defaults to "Azure AD v2"
- "args" => {
- "client_id" => "CLIENT ID",
- "client_secret" => "CLIENT SECRET",
- "tenant_id" => "TENANT ID",
+ ```ruby
+ gitlab_rails['omniauth_providers'] = [
+ {
+ name: "azure_oauth2",
+ # label: "Provider name", # optional label for login button, defaults to "Azure AD"
+ args: {
+ client_id: "CLIENT ID",
+ client_secret: "CLIENT SECRET",
+ tenant_id: "TENANT ID",
+ }
}
- }
- ]
- ```
+ ]
+ ```
+
+ For the v2.0 endpoint:
+
+ ```ruby
+ gitlab_rails['omniauth_providers'] = [
+ {
+ "name" => "azure_activedirectory_v2",
+ "label" => "Provider name", # optional label for login button, defaults to "Azure AD v2"
+ "args" => {
+ "client_id" => "CLIENT ID",
+ "client_secret" => "CLIENT SECRET",
+ "tenant_id" => "TENANT ID",
+ }
+ }
+ ]
+ ```
+
+ - **For installations from source**
- For installations from source:
+ For the v1.0 endpoint:
- ```yaml
- - { name: 'azure_activedirectory_v2',
- label: 'Provider name', # optional label for login button, defaults to "Azure AD v2"
- args: { client_id: "CLIENT ID",
- client_secret: "CLIENT SECRET",
- tenant_id: "TENANT ID" } }
- ```
+ ```yaml
+ - { name: 'azure_oauth2',
+ # label: 'Provider name', # optional label for login button, defaults to "Azure AD"
+ args: { client_id: 'CLIENT ID',
+ client_secret: 'CLIENT SECRET',
+ tenant_id: 'TENANT ID' } }
+ ```
- The `base_azure_url` is optional and can be added for different locales;
- such as `base_azure_url: "https://login.microsoftonline.de"`.
+ For the v2.0 endpoint:
+
+ ```yaml
+ - { name: 'azure_activedirectory_v2',
+ label: 'Provider name', # optional label for login button, defaults to "Azure AD v2"
+ args: { client_id: "CLIENT ID",
+ client_secret: "CLIENT SECRET",
+ tenant_id: "TENANT ID" } }
+ ```
- The `scope` parameter is optional and can be added to `args`. Default `scope` is: `openid profile email`.
+ You can optionally add the following parameters:
-1. Replace `CLIENT ID`, `CLIENT SECRET`, and `TENANT ID` with the values you got
- above.
+ - `base_azure_url` for different locales. For example, `base_azure_url: "https://login.microsoftonline.de"`.
+ - `scope`, which you add to `args`. The default is `openid profile email`.
1. Save the configuration file.
-1. Reconfigure or restart GitLab, depending on your installation method:
+1. [Reconfigure GitLab](../administration/restart_gitlab.md#omnibus-gitlab-reconfigure)
+ if you installed using Omnibus, or [restart GitLab](../administration/restart_gitlab.md#installations-from-source)
+ if you installed from source.
- - *If you installed from Omnibus GitLab,*
- [reconfigure](../administration/restart_gitlab.md#omnibus-gitlab-reconfigure) GitLab.
- - *If you installed from source,*
- [restart GitLab](../administration/restart_gitlab.md#installations-from-source).
+1. Refresh the GitLab sign-in page. A Microsoft icon should display below the
+ sign-in form.
-On the sign-in page, you should now see a Microsoft icon below the regular sign-in form.
-Select the icon to begin the authentication process. Microsoft then asks you to
-sign in and authorize the GitLab application. If successful, you are returned to GitLab and signed in.
+1. Select the icon. Sign in to Microsoft and authorize the GitLab application.
-Read [Enable OmniAuth for an Existing User](omniauth.md#enable-omniauth-for-an-existing-user)
-for information on how existing GitLab users can connect to their newly available Azure AD accounts.
+Read [Enable OmniAuth for an existing user](omniauth.md#enable-omniauth-for-an-existing-user)
+for information on how existing GitLab users can connect to their new Azure AD accounts.
diff --git a/doc/integration/elasticsearch.md b/doc/integration/elasticsearch.md
index 4976f7c2664..5265a24d299 100644
--- a/doc/integration/elasticsearch.md
+++ b/doc/integration/elasticsearch.md
@@ -58,6 +58,9 @@ source. You must [install it separately](https://www.elastic.co/guide/en/elastic
You can install Elasticsearch yourself, or use a cloud hosted offering such as [Elasticsearch Service](https://www.elastic.co/elasticsearch/service) (available on AWS, GCP, or Azure) or the [Amazon OpenSearch](https://docs.aws.amazon.com/opensearch-service/latest/developerguide/gsg.html)
service.
+
+If using the Amazon OpenSearch service, ensure that you select `Elasticsearch 7.10` when configuring Deployment type. As noted in [Versions not supported](#versions-not-supported), Amazon's non-Elasticsearch versions are not yet supported.
+
You should install Elasticsearch on a separate server. Running Elasticsearch on the same server as GitLab is not recommended and can cause a degradation in GitLab instance performance.
For a single node Elasticsearch cluster, the functional cluster health status is always yellow due to the allocation of the primary shard. Elasticsearch cannot assign replica shards to the same node as primary shards.
@@ -206,7 +209,7 @@ The following Elasticsearch settings are available:
| Parameter | Description |
|-------------------------------------------------------|-------------|
-| `Elasticsearch indexing` | Enables or disables Elasticsearch indexing and creates an empty index if one does not already exist. 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 the background indexer which tracks data changes and ensures new data is indexed. |
+| `Elasticsearch indexing` | Enables or disables Elasticsearch indexing and creates an empty index if one does not already exist. You may want to enable indexing but disable search 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 the background indexer which tracks data changes and ensures new data is indexed. |
| `Pause Elasticsearch indexing` | Enables or 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 resumed. |
| `Search with Elasticsearch enabled` | Enables or disables using Elasticsearch in search. |
| `URL` | The URL of your Elasticsearch instance. Use a comma-separated list to support clustering (for example, `http://host1, https://host2:9200`). If your Elasticsearch instance is password-protected, use the `Username` and `Password` fields described below. Alternatively, use inline credentials such as `http://<username>:<password>@<elastic_host>:9200/`. |
@@ -221,8 +224,8 @@ The following Elasticsearch settings are available:
| `AWS Secret Access Key` | The AWS secret access key. |
| `Maximum file size indexed` | See [the explanation in instance limits.](../administration/instance_limits.md#maximum-file-size-indexed). |
| `Maximum field length` | See [the explanation in instance limits.](../administration/instance_limits.md#maximum-field-length). |
-| `Maximum bulk request size (MiB)` | The Maximum Bulk Request size is used by the GitLab Golang-based indexer processes and indicates how much data it ought to collect (and store in memory) in a given indexing process before submitting the payload to Elasticsearch's Bulk API. This setting should be used with the Bulk request concurrency setting (see below) and needs to accommodate the resource constraints of both the Elasticsearch host(s) and the host(s) running the GitLab Golang-based indexer either from the `gitlab-rake` command or the Sidekiq tasks. |
-| `Bulk request concurrency` | The Bulk request concurrency indicates how many of the GitLab Golang-based indexer processes (or threads) can run in parallel to collect data to subsequently submit to Elasticsearch's Bulk API. This increases indexing performance, but fills the Elasticsearch bulk requests queue faster. This setting should be used together with the Maximum bulk request size setting (see above) and needs to accommodate the resource constraints of both the Elasticsearch host(s) and the host(s) running the GitLab Golang-based indexer either from the `gitlab-rake` command or the Sidekiq tasks. |
+| `Maximum bulk request size (MiB)` | The Maximum Bulk Request size is used by the GitLab Golang-based indexer processes and indicates how much data it ought to collect (and store in memory) in a given indexing process before submitting the payload to Elasticsearch's Bulk API. This setting should be used with the Bulk request concurrency setting (see below) and needs to accommodate the resource constraints of both the Elasticsearch hosts and the hosts running the GitLab Golang-based indexer either from the `gitlab-rake` command or the Sidekiq tasks. |
+| `Bulk request concurrency` | The Bulk request concurrency indicates how many of the GitLab Golang-based indexer processes (or threads) can run in parallel to collect data to subsequently submit to Elasticsearch's Bulk API. This increases indexing performance, but fills the Elasticsearch bulk requests queue faster. This setting should be used together with the Maximum bulk request size setting (see above) and needs to accommodate the resource constraints of both the Elasticsearch hosts and the hosts running the GitLab Golang-based indexer either from the `gitlab-rake` command or the Sidekiq tasks. |
| `Client request timeout` | Elasticsearch HTTP client request timeout value in seconds. `0` means using the system default timeout value, which depends on the libraries that GitLab application is built upon. |
WARNING:
@@ -259,16 +262,16 @@ from the Elasticsearch index as expected.
You can improve the language support for Chinese and Japanese languages by utilizing [`smartcn`](https://www.elastic.co/guide/en/elasticsearch/plugins/current/analysis-smartcn.html) and/or [`kuromoji`](https://www.elastic.co/guide/en/elasticsearch/plugins/current/analysis-kuromoji.html) analysis plugins from Elastic.
-To enable language(s) support:
+To enable languages support:
-1. Install the desired plugin(s), please refer to [Elasticsearch documentation](https://www.elastic.co/guide/en/elasticsearch/plugins/7.9/installation.html) for plugins installation instructions. The plugin(s) must be installed on every node in the cluster, and each node must be restarted after installation. For a list of plugins, see the table later in this section.
+1. Install the desired plugins, please refer to [Elasticsearch documentation](https://www.elastic.co/guide/en/elasticsearch/plugins/7.9/installation.html) for plugins installation instructions. The plugins must be installed on every node in the cluster, and each node must be restarted after installation. For a list of plugins, see the table later in this section.
1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Settings > Advanced Search**.
1. Locate **Custom analyzers: language support**.
-1. Enable plugin(s) support for **Indexing**.
+1. Enable plugins support for **Indexing**.
1. Click **Save changes** for the changes to take effect.
1. Trigger [Zero downtime reindexing](#zero-downtime-reindexing) or reindex everything from scratch to create a new index with updated mappings.
-1. Enable plugin(s) support for **Searching** after the previous step is completed.
+1. Enable plugins support for **Searching** after the previous step is completed.
For guidance on what to install, see the following Elasticsearch language plugin options:
@@ -662,7 +665,7 @@ Sidekiq processes](../administration/operations/extra_sidekiq_processes.md).
```
You can also use the `gitlab:elastic:clear_index_status` Rake task to force the
- indexer to "forget" all progress, so it will retry the indexing process from the
+ indexer to "forget" all progress, so it retries the indexing process from the
start.
1. Personal snippets are not associated with a project and need to be indexed separately:
@@ -831,9 +834,9 @@ for the changes to take effect.
## Reverting to Basic Search
Sometimes there may be issues with your Elasticsearch index data and as such
-GitLab will allow you to revert to "basic search" when there are no search
+GitLab allows you to revert to "basic search" when there are no search
results and assuming that basic search is supported in that scope. This "basic
-search" will behave as though you don't have Advanced Search enabled at all for
+search" behaves as though you don't have Advanced Search enabled at all for
your instance and search using other data sources (such as PostgreSQL data and Git
data).
@@ -847,7 +850,7 @@ the Elasticsearch data store is ever corrupted for whatever reason, you can rein
## Troubleshooting
One of the most valuable tools for identifying issues with the Elasticsearch
-integration will be logs. The most relevant logs for this integration are:
+integration are logs. The most relevant logs for this integration are:
1. [`sidekiq.log`](../administration/logs.md#sidekiqlog) - All of the
indexing happens in Sidekiq, so much of the relevant logs for the
@@ -863,7 +866,7 @@ Here are some common pitfalls and how to overcome them.
There are a couple of ways to achieve that:
-- Whenever you perform a search there will be a link on the search results page
+- Whenever you perform a search there is a link on the search results page
in the top right hand corner saying "Advanced search functionality is enabled".
This is always correctly identifying whether the current project/namespace
being searched is using Elasticsearch.
@@ -923,7 +926,7 @@ See [Elasticsearch Index Scopes](#advanced-search-index-scopes) for more informa
### I indexed all the repositories but then switched Elasticsearch servers and now I can't find anything
-You will need to re-run all the Rake tasks to reindex the database, repositories, and wikis.
+You must re-run all the Rake tasks to reindex the database, repositories, and wikis.
### The indexing process is taking a very long time
@@ -938,7 +941,7 @@ You can run `sudo gitlab-rake gitlab:elastic:projects_not_indexed` to display pr
NOTE:
This was [fixed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/35936) in GitLab 13.2 and the Rake task is not available for versions greater than that.
-When performing the initial indexing of blobs, we lock all projects until the project finishes indexing. It could happen that an error during the process causes one or multiple projects to remain locked. In order to unlock them, run:
+When performing the initial indexing of blobs, we lock all projects until the project finishes indexing. It could happen that an error during the process causes one or multiple projects to remain locked. To unlock them, run:
```shell
sudo gitlab-rake gitlab:elastic:clear_locked_projects
@@ -946,8 +949,8 @@ sudo gitlab-rake gitlab:elastic:clear_locked_projects
### `Can't specify parent if no parent field has been configured` error
-If you enabled Elasticsearch before GitLab 8.12 and have not rebuilt indexes you will get
-exception in lots of different cases:
+If you enabled Elasticsearch before GitLab 8.12 and have not rebuilt indexes, you get
+exceptions in lots of different cases:
```plaintext
Elasticsearch::Transport::Transport::Errors::BadRequest([400] {
@@ -983,12 +986,12 @@ AWS has [fixed limits](https://docs.aws.amazon.com/opensearch-service/latest/dev
### My single node Elasticsearch cluster status never goes from `yellow` to `green` even though everything seems to be running properly
-**For a single node Elasticsearch cluster the functional cluster health status will be yellow** (never green) because the primary shard is allocated but replicas cannot be as there is no other node to which Elasticsearch can assign a replica. This also applies if you are using the [Amazon OpenSearch](https://docs.aws.amazon.com/opensearch-service/latest/developerguide/aes-handling-errors.html#aes-handling-errors-yellow-cluster-status) service.
+**For a single node Elasticsearch cluster the functional cluster health status is yellow** (never green) because the primary shard is allocated but replicas cannot be as there is no other node to which Elasticsearch can assign a replica. This also applies if you are using the [Amazon OpenSearch](https://docs.aws.amazon.com/opensearch-service/latest/developerguide/aes-handling-errors.html#aes-handling-errors-yellow-cluster-status) service.
WARNING:
-Setting the number of replicas to `0` is discouraged (this is not allowed in the GitLab Elasticsearch Integration menu). If you are planning to add more Elasticsearch nodes (for a total of more than 1 Elasticsearch) the number of replicas will need to be set to an integer value larger than `0`. Failure to do so will result in lack of redundancy (losing one node will corrupt the index).
+Setting the number of replicas to `0` is discouraged (this is not allowed in the GitLab Elasticsearch Integration menu). If you are planning to add more Elasticsearch nodes (for a total of more than 1 Elasticsearch) the number of replicas needs to be set to an integer value larger than `0`. Failure to do so results in lack of redundancy (losing one node corrupts the index).
-If you have a **hard requirement to have a green status for your single node Elasticsearch cluster**, please make sure you understand the risks outlined in the previous paragraph and then run the following query to set the number of replicas to `0`(the cluster will no longer try to create any shard replicas):
+If you have a **hard requirement to have a green status for your single node Elasticsearch cluster**, please make sure you understand the risks outlined in the previous paragraph and then run the following query to set the number of replicas to `0`(the cluster no longer tries to create any shard replicas):
```shell
curl --request PUT localhost:9200/gitlab-production/_settings --header 'Content-Type: application/json' \
@@ -1008,7 +1011,7 @@ Gitlab::Elastic::Indexer::Error: time="2020-01-23T09:13:00Z" level=fatal msg="he
```
You probably have not used either `http://` or `https://` as part of your value in the **"URL"** field of the Elasticsearch Integration Menu. Please make sure you are using either `http://` or `https://` in this field as the [Elasticsearch client for Go](https://github.com/olivere/elastic) that we are using [needs the prefix for the URL to be accepted as valid](https://github.com/olivere/elastic/commit/a80af35aa41856dc2c986204e2b64eab81ccac3a).
-Once you have corrected the formatting of the URL, delete the index (via the [dedicated Rake task](#gitlab-advanced-search-rake-tasks)) and [reindex the content of your instance](#enable-advanced-search).
+After you have corrected the formatting of the URL, delete the index (via the [dedicated Rake task](#gitlab-advanced-search-rake-tasks)) and [reindex the content of your instance](#enable-advanced-search).
### My Elasticsearch cluster has a plugin and the integration is not working
@@ -1041,8 +1044,8 @@ using the above [troubleshooting](#troubleshooting) steps.
If there are no other options, then you always have the option of recreating the
entire index from scratch. If you have a small GitLab installation, this can
sometimes be a quick way to resolve a problem, but if you have a large GitLab
-installation, then this will likely take a very long time to complete. Until the
-index is fully recreated, your index will not be serving correct search results,
+installation, then this might take a very long time to complete. Until the
+index is fully recreated, your index does not serve correct search results,
so you may want to disable **Search with Elasticsearch** while it is running.
If you are sure you've read the above caveats and want to proceed, then you
@@ -1065,9 +1068,9 @@ sudo -u git -H bundle exec rake gitlab:elastic:index
### How does Advanced Search handle private projects?
-Advanced Search will store all the projects in the same Elasticsearch indexes,
-however searches will only surface results that can be viewed by the user.
-Advanced Search will honor all permission checks in the application by
+Advanced Search stores all the projects in the same Elasticsearch indexes,
+however, searches only surface results that can be viewed by the user.
+Advanced Search honors all permission checks in the application by
filtering out projects that a user does not have access to at search time.
### Indexing fails with `error: elastic: Error 429 (Too Many Requests)`
diff --git a/doc/integration/external-issue-tracker.md b/doc/integration/external-issue-tracker.md
index 19f789832b9..ac470291c27 100644
--- a/doc/integration/external-issue-tracker.md
+++ b/doc/integration/external-issue-tracker.md
@@ -6,27 +6,26 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# External issue tracker **(FREE)**
-GitLab has a great [issue tracker](../user/project/issues/index.md) but you can also use an external
-one. External issue trackers are configurable per GitLab project.
+GitLab has an [issue tracker](../user/project/issues/index.md), but you can
+configure an external issue tracker per GitLab project.
-Once configured, you can reference external issues using the format `CODE-123`, where:
+After you configure the external tracker, you can reference external issues
+in GitLab merge requests, commits, and comments
+using the format `CODE-123`, where:
- `CODE` is a unique code for the tracker.
- `123` is the issue number in the tracker.
-These references in GitLab merge requests, commits, or comments are automatically converted to links to the issues.
+The references are automatically converted to links to the issues.
You can keep the GitLab issue tracker enabled in parallel or disable it. When enabled, the **Issues** link in the
GitLab menu always opens the internal issue tracker. When disabled, the link is not visible in the menu.
-## Configuration
+## Configure an external issue tracker
-The configuration is done via a project's **Settings > Integrations**.
+To enable an external issue tracker, you must configure the appropriate [integration](../user/project/integrations/index.md).
-### Integration
-
-To enable an external issue tracker you must configure the appropriate **Integration**.
-Visit the links below for details:
+The following external issue tracker integrations are available:
- [Bugzilla](../user/project/integrations/bugzilla.md)
- [Custom Issue Tracker](../user/project/integrations/custom_issue_tracker.md)
@@ -34,3 +33,4 @@ Visit the links below for details:
- [Jira](../integration/jira/index.md)
- [Redmine](../user/project/integrations/redmine.md)
- [YouTrack](../user/project/integrations/youtrack.md)
+- [ZenTao](../user/project/integrations/zentao.md)
diff --git a/doc/integration/gitlab.md b/doc/integration/gitlab.md
index 74ae9bb1998..132006ab996 100644
--- a/doc/integration/gitlab.md
+++ b/doc/integration/gitlab.md
@@ -62,9 +62,7 @@ GitLab.com generates an application ID and secret key for you to use.
# label: "Provider name", # optional label for login button, defaults to "GitLab.com"
app_id: "YOUR_APP_ID",
app_secret: "YOUR_APP_SECRET",
- args: { scope: "read_user" # optional: defaults to the scopes of the application
- , client_options: { site: "https://gitlab.example.com/api/v4" }
- }
+ args: { scope: "read_user" } # optional: defaults to the scopes of the application
}
]
```
@@ -91,7 +89,6 @@ GitLab.com generates an application ID and secret key for you to use.
# label: 'Provider name', # optional label for login button, defaults to "GitLab.com"
app_id: 'YOUR_APP_ID',
app_secret: 'YOUR_APP_SECRET',
- args: { "client_options": { "site": 'https://gitlab.example.com/api/v4' } }
```
Or, for installations from source to authenticate against a different GitLab instance:
@@ -125,7 +122,7 @@ signed in.
FLAG:
On self-managed GitLab, by default this feature is not available. To make it available, ask an administrator to [enable the feature flag](../administration/feature_flags.md) named `omniauth_login_minimal_scopes`. On GitLab.com, this feature is not available.
-If you use a GitLab instance for authentication, you can reduce access rights when an OAuth application is used for sign in.
+If you use a GitLab instance for authentication, you can reduce access rights when an OAuth application is used for sign in.
Any OAuth application can advertise the purpose of the application with the
authorization parameter: `gl_auth_type=login`. If the application is
diff --git a/doc/integration/jenkins.md b/doc/integration/jenkins.md
index b86643c7279..54d235b5357 100644
--- a/doc/integration/jenkins.md
+++ b/doc/integration/jenkins.md
@@ -45,7 +45,7 @@ Grant a GitLab user access to the relevant GitLab projects.
If you're integrating Jenkins with many GitLab projects, consider granting the
user administrator access. Otherwise, add the user to each project
- and grant the Developer role.
+ and grant the Maintainer role.
## Grant Jenkins access to the GitLab API
@@ -242,7 +242,7 @@ To enable job logs in Jenkins:
1. Go to **Dashboard > Manage Jenkins > System Log**.
1. Select **Add new log recorder**.
1. Enter a name for the log recorder.
-1. On the next screen, select **Add** and enter `org.jenkinsci.plugins.workflow.job`.
+1. On the next screen, select **Add** and enter `com.dabsquared.gitlabjenkins`.
1. Make sure that the Log Level is **All** and select **Save**.
To view your logs:
diff --git a/doc/integration/jira/configure.md b/doc/integration/jira/configure.md
index 979d8a52fb8..2033ddbad6f 100644
--- a/doc/integration/jira/configure.md
+++ b/doc/integration/jira/configure.md
@@ -50,7 +50,7 @@ To configure your project:
If you enable Jira issues with this setting, all users with access to this GitLab project
can view all issues from the specified Jira project.
-1. To enable [issue creation for vulnerabilities](../../user/application_security/vulnerabilities/index.md#create-a-jira-issue-for-a-vulnerability), select **Enable Jira issues creation from vulnerabilities**.
+1. To enable [issue creation for vulnerabilities](../../user/application_security/vulnerabilities/index.md#create-a-jira-issue-for-a-vulnerability), select **Enable Jira issue creation from vulnerabilities**.
1. Select the **Jira issue type**. If the dropdown is empty, select refresh (**{retry}**) and try again.
1. To verify the Jira connection is working, select **Test settings**.
1. Select **Save changes**.
diff --git a/doc/integration/jira/connect-app.md b/doc/integration/jira/connect-app.md
index ebe8a0f1af4..59cdba93543 100644
--- a/doc/integration/jira/connect-app.md
+++ b/doc/integration/jira/connect-app.md
@@ -101,7 +101,7 @@ from outside the Marketplace, which allows you to install the application:
![Button labeled "upload app"](img/jira-upload-app_v13_11.png)
1. For **App descriptor URL**, provide the full URL to your manifest file, based
- on your instance configuration. For example: `https://your.domain/your-path/-/jira_connect/app_descriptor.json`.
+ on your instance configuration. By default, your manifest file is located at `/-/jira_connect/app_descriptor.json`. For example, if your GitLab self-managed instance domain is `app.pet-store.cloud`, your manifest file is located at `https://app.pet-store.cloud/-/jira_connect/app_descriptor.json`.
1. Select **Upload**. Jira fetches the content of your `app_descriptor` file and installs
it.
1. If the upload is successful, Jira displays a modal panel: **Installed and ready to go!**
diff --git a/doc/integration/jira/development_panel.md b/doc/integration/jira/development_panel.md
index 8f66edcffa8..66810945d19 100644
--- a/doc/integration/jira/development_panel.md
+++ b/doc/integration/jira/development_panel.md
@@ -20,7 +20,7 @@ The information displayed in the Jira Development panel depends on where you men
| Your mention of Jira issue ID in GitLab context | Automated effect in Jira issue |
|---------------------------------------------------|--------------------------------------------------------------------------------------------------------|
-| In a merge request | Link to the MR is displayed in Development panel. |
+| In a merge request title or description | Link to the MR is displayed in Development panel. |
| In a branch name | Link to the branch is displayed in Development panel. |
| In a commit message | Link to the commit is displayed in Development panel. |
| In a commit message with Jira [Smart Commits](https://confluence.atlassian.com/fisheye/using-smart-commits-960155400.html) | Displays your custom comment or logged time spent and/or performs specified issue transition on merge. |
diff --git a/doc/integration/omniauth.md b/doc/integration/omniauth.md
index 4c05f94148c..7a4bcba25e4 100644
--- a/doc/integration/omniauth.md
+++ b/doc/integration/omniauth.md
@@ -26,7 +26,7 @@ GitLab supports the following OmniAuth providers.
| [Auth0](auth0.md) | `auth0` |
| [Authentiq](../administration/auth/authentiq.md) | `authentiq` |
| [AWS Cognito](../administration/auth/cognito.md) | `cognito` |
-| [Azure v2](azure.md#microsoft-azure-oauth-20-omniauth-provider-v2) | `azure_activedirectory_v2` |
+| [Azure v2](azure.md) | `azure_activedirectory_v2` |
| [Azure v1](azure.md) | `azure_oauth2` |
| [Bitbucket Cloud](bitbucket.md) | `bitbucket` |
| [CAS](cas.md) | `cas3` |
@@ -326,7 +326,7 @@ configuration to redirect login requests to your OmniAuth provider for
authentication. This removes the need to select the provider before signing in.
For example, to enable automatic sign-in for the
-[Azure v2 integration](azure.md#microsoft-azure-oauth-20-omniauth-provider-v2):
+[Azure v2 integration](azure.md):
- **For Omnibus package**
diff --git a/doc/integration/security_partners/index.md b/doc/integration/security_partners/index.md
index 2c7641124a0..50a7b3b717b 100644
--- a/doc/integration/security_partners/index.md
+++ b/doc/integration/security_partners/index.md
@@ -1,7 +1,7 @@
---
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
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
type: index
---
@@ -12,16 +12,16 @@ each security partner:
<!-- vale gitlab.Spelling = NO -->
-- [Accurics](https://readme.accurics.com/1409/)
- [Anchore](https://docs.anchore.com/current/docs/using/integration/ci_cd/gitlab/)
- [Bridgecrew](https://docs.bridgecrew.io/docs/integrate-with-gitlab-self-managed)
- [Checkmarx](https://checkmarx.atlassian.net/wiki/spaces/SD/pages/1929937052/GitLab+Integration)
- [Deepfactor](https://docs.deepfactor.io/hc/en-us/articles/1500008981941)
- [GrammaTech](https://www.grammatech.com/codesonar-gitlab-integration)
-- [Indeni](https://cloudrail.app/doc/integrate-with-ci-cd/gitlab-instructions/)
+- [Indeni](https://docs.cloudrail.app/#/integrations/gitlab)
- [JScrambler](https://docs.jscrambler.com/code-integrity/documentation/gitlab-ci-integration)
- [Semgrep](https://semgrep.dev/for/gitlab)
- [StackHawk](https://docs.stackhawk.com/continuous-integration/gitlab.html)
+- [Tenable](https://docs.tenable.com/tenableio/Content/ContainerSecurity/GetStarted.htm)
- [Venafi](https://marketplace.venafi.com/details/gitlab-ci-cd/)
- [Veracode](https://community.veracode.com/s/knowledgeitem/gitlab-ci-MCEKSYPRWL35BRTGOVI55SK5RI4A)
- [WhiteSource](https://www.whitesourcesoftware.com/gitlab/)
diff --git a/doc/integration/twitter.md b/doc/integration/twitter.md
index e1f67df76c3..3aba6b70b94 100644
--- a/doc/integration/twitter.md
+++ b/doc/integration/twitter.md
@@ -9,9 +9,9 @@ info: To determine the technical writer assigned to the Stage/Group associated w
To enable the Twitter OmniAuth provider you must register your application with
Twitter. Twitter generates a client ID and secret key for you to use.
-1. Sign in to [Twitter Application Management](https://developer.twitter.com/apps).
+1. Sign in to [Twitter Application Management](https://apps.twitter.com).
-1. Select "Create new app"
+1. Select "Create new app".
1. Fill in the application details.
- Name: This can be anything. Consider something like `<Organization>'s GitLab` or `<Your Name>'s GitLab` or
diff --git a/doc/operations/error_tracking.md b/doc/operations/error_tracking.md
index 6f97f002a32..907c59adacb 100644
--- a/doc/operations/error_tracking.md
+++ b/doc/operations/error_tracking.md
@@ -41,8 +41,10 @@ least Maintainer [permissions](../user/permissions.md) to enable the Sentry inte
1. Sign up to Sentry.io or [deploy your own](#deploying-sentry) Sentry instance.
1. [Create](https://docs.sentry.io/product/sentry-basics/guides/integrate-frontend/create-new-project/) a new Sentry project. For each GitLab project that you want to integrate, we recommend that you create a new Sentry project.
-1. [Find or generate](https://docs.sentry.io/api/auth/) a Sentry auth token for your Sentry project.
- Make sure to give the token at least the following scopes: `event:read`, `project:read`, and `event:write` (for resolving events).
+1. Find or generate a [Sentry auth token](https://docs.sentry.io/api/auth/#auth-tokens).
+ For the SaaS version of Sentry, you can find or generate the auth token at [https://sentry.io/api/](https://sentry.io/api/).
+ Make sure to give the token at least the following scopes: `project:read`, `event:read`, and
+ `event:write` (for resolving events).
1. In GitLab, enable error tracking:
1. On the top bar, select **Menu > Projects** and find your project.
1. On the left sidebar, select **Monitor > Error Tracking**.
@@ -127,7 +129,17 @@ If another event occurs, the error reverts to unresolved.
## Integrated error tracking
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/329596) in GitLab 14.4.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/329596) in GitLab 14.4.
+> - [Disabled](https://gitlab.com/gitlab-org/gitlab/-/issues/353639) in GitLab 14.9 [with a flag](../administration/feature_flags.md) named `integrated_error_tracking`. Disabled by default.
+
+FLAG:
+By default this feature is not available. To make it available on self-managed GitLab, ask an
+administrator to [enable the feature flag](../administration/feature_flags.md)
+named `integrated_error_tracking`. The feature is not ready for production use.
+On GitLab.com, this feature is not available.
+
+WARNING:
+Turning on integrated error tracking may impact performance, depending on your error rates.
Integrated error tracking is a lightweight alternative to Sentry backend.
You still use Sentry SDK with your application. But you don't need to deploy Sentry
diff --git a/doc/operations/feature_flags.md b/doc/operations/feature_flags.md
index 8903e99ab3b..e7d78beb0b9 100644
--- a/doc/operations/feature_flags.md
+++ b/doc/operations/feature_flags.md
@@ -43,12 +43,7 @@ To create and enable a feature flag:
1. Enter a name that starts with a letter and contains only lowercase letters, digits, underscores (`_`),
or dashes (`-`), and does not end with a dash (`-`) or underscore (`_`).
1. Optional. Enter a description (255 characters maximum).
-1. Enter details about how the flag should be applied:
- - In GitLab 13.0 and earlier, add **Environment specs**. For each environment,
- include the **Status** (default enabled) and [**Rollout strategy**](#rollout-strategy-legacy)
- (defaults to **All users**).
- - In GitLab 13.1 and later, add Feature Flag [**Strategies**](#feature-flag-strategies).
- For each strategy, include the **Type** (defaults to [**All users**](#all-users))
+1. Add Feature Flag [**Strategies**](#feature-flag-strategies) to define how the flag should be applied. For each strategy, include the **Type** (defaults to [**All users**](#all-users))
and **Environments** (defaults to all environments).
1. Select **Create feature flag**.
@@ -163,21 +158,6 @@ WARNING:
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.
-## Search for Code References **(PREMIUM)**
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/300299) in GitLab 14.4.
-
-Search your project and find any references of a feature flag in your
-code so that you can clean it up when it's time to remove the feature flag.
-
-To search for code references of a feature flag:
-
-1. On the top bar, select **Menu > Projects** and find your project.
-1. On the left sidebar, select **Deployments > Feature Flags**.
-1. Edit the feature flag you want to remove.
-1. Select **More actions** (**{ellipsis_v}**).
-1. Select **Search code references**.
-
### User List
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/35930) in GitLab 13.1.
@@ -235,34 +215,20 @@ To remove users from a user list:
1. Select **Edit** (**{pencil}**) next to the list you want to change.
1. Select **Remove** (**{remove}**) next to the ID you want to remove.
-## Rollout strategy (legacy)
-
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/8240) in GitLab 12.2.
-> - [Made read-only](https://gitlab.com/gitlab-org/gitlab/-/issues/220228) in GitLab 13.4.
-
-In GitLab 13.0 and earlier, the **Rollout strategy** setting affects which users experience
-the feature as enabled. Choose the percentage of users that the feature is enabled
-for. The rollout strategy has no effect if the environment spec is disabled.
-
-It can be set to:
-
-- All users
-- [Percent of users](#percent-of-users)
- - Optionally, you can click the **Include additional user IDs** checkbox and add a list
- of specific users IDs to enable the feature for.
-- [User IDs](#user-ids)
+## Search for Code References **(PREMIUM)**
-## Legacy feature flag migration
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/300299) in GitLab 14.4.
-Legacy feature flags became read-only in GitLab 13.4. GitLab 14.0 removes support for legacy feature
-flags. You must migrate your legacy feature flags to the new version. To do so, follow these steps:
+Search your project and find any references of a feature flag in your
+code so that you can clean it up when it's time to remove the feature flag.
-1. Take a screenshot of the legacy flag for tracking.
-1. Delete the flag through the API or UI (you don't need to alter the code).
-1. Create a new feature flag with the same name as the legacy flag you deleted. Make sure the
- strategies and environments match the deleted flag.
+To search for code references of a feature flag:
-See [this video tutorial](https://www.youtube.com/watch?v=CAJY2IGep7Y) for help with this migration.
+1. On the top bar, select **Menu > Projects** and find your project.
+1. On the left sidebar, select **Deployments > Feature Flags**.
+1. Edit the feature flag you want to remove.
+1. Select **More actions** (**{ellipsis_v}**).
+1. Select **Search code references**.
## Disable a feature flag for a specific environment
@@ -441,3 +407,49 @@ click the `+` button and input the issue reference number or the full URL of the
The issues then appear in the related feature flag and the other way round.
This feature is similar to the [linked issues](../user/project/issues/related_issues.md) feature.
+
+## Performance factors
+
+In general, GitLab Feature Flags can be used in any applications,
+however, if it's a large application, it could require an additional configuration in advance.
+This section explains the performance factors to help your organization to identify
+what's needed to be done before using the feature.
+Please read [How it works](#how-it-works) section before diving into the details.
+
+### Maximum supported clients in application nodes
+
+GitLab accepts client requests as much as possible until it hits the [rate limiting](../security/rate_limits.md).
+At the moment, the Feature Flag API falls into **Unauthenticated traffic (from a given IP address)**
+in the [GitLab.com specific limits](../user/gitlab_com/index.md),
+so it's **500 requests per minute**.
+
+Please note that the polling rate is configurable in SDKs. Provided that all clients are requesting from the same IP:
+
+- Request once per minute ... 500 clients can be supported.
+- Request once per 15 sec ... 125 clients can be supported.
+
+For applications looking for more scalable solution, we recommend to use [Unleash Proxy](#unleash-proxy-example).
+This proxy server sits between the server and clients. It requests to the server as a behalf of the client groups,
+so the nubmer of outbound requests can be greatly reduced.
+
+There is also an [issue](https://gitlab.com/gitlab-org/gitlab/-/issues/295472) to give more
+capacity to the current rate limit.
+
+### Recovering from network errors
+
+In general, [Unleash clients](https://github.com/Unleash/unleash#unleash-sdks) have
+a fall-back mechanism when the server returns an error code.
+For example, `unleash-ruby-client` reads flag data from the local backup so that
+application can keep running in the current state.
+
+Please reads the documentation in a SDK project for more information.
+
+### Self-managed GitLab
+
+Functionality-wise, there are no differences. Both SaaS and self-managed behave the same.
+
+In terms of scalability, it's up to the spec of the GitLab instance.
+For example, GitLab.com runs on HA architecture so that it can handle a lot of requests concurrently,
+however, a self-managed instance runs on a low spec machine can't expect the same result.
+Please see [Reference architectures](../administration/reference_architectures/index.md)
+for more information.
diff --git a/doc/operations/incident_management/alerts.md b/doc/operations/incident_management/alerts.md
index b03955edf87..0ad2b5ecf3b 100644
--- a/doc/operations/incident_management/alerts.md
+++ b/doc/operations/incident_management/alerts.md
@@ -144,6 +144,7 @@ The following actions result in a system note:
- [Updating the status of an alert](#update-an-alerts-status)
- [Creating an incident based on an alert](#create-an-incident-from-an-alert)
- [Assignment of an alert to a user](#assign-an-alert)
+- [Escalation of an alert to on-call responders](paging.md#escalating-an-alert)
![Alert Details Activity Feed](img/alert_detail_activity_feed_v13_5.png)
@@ -153,8 +154,26 @@ There are different actions available in GitLab to help triage and respond to al
### Update an alert's status
-The Alert detail view enables you to update the Alert Status.
-See [Create and manage alerts in GitLab](alerts.md) for more details.
+**Triggered** is the default status for new alerts. For users with the Developer role or higher, the
+alert status can be updated from these locations:
+
+- [Alert list](#alert-list): select the status dropdown corresponding to an alert, then select an
+ alternate status.
+- [Alert details page](#alert-details-page): select **Edit** in the right-hand side bar, then select
+ an alternate status.
+
+To stop email notifications for alert reoccurrences in projects with [email notifications enabled](paging.md#email-notifications-for-alerts),
+[change the alert's status](alerts.md#update-an-alerts-status) away from **Triggered**.
+
+In projects with GitLab Premium, on-call responders can respond to [alert pages](paging.md#escalating-an-alert)
+by changing the status. Setting the status to:
+
+- **Resolved** silences all on-call pages for the alert.
+- **Acknowledged** limits on-call pages based on the project's [escalation policy](escalation_policies.md).
+- **Triggered** from **Resolved** restarts the alert escalating from the beginning.
+
+For [alerts with an associated incident](alerts.md#create-an-incident-from-an-alert),
+updating the alert status also updates the incident status.
### Create an incident from an alert
@@ -165,8 +184,10 @@ description populated from an alert. To create the issue,
select the **Create Issue** button. You can then view the issue from the
alert by selecting the **View Issue** button.
-Closing a GitLab issue associated with an alert changes the alert's status to
-Resolved. See [Create and manage alerts in GitLab](alerts.md) for more details
+You can also [create incidents for alerts automatically](incidents.md#create-incidents-automatically).
+
+Closing a GitLab issue associated with an alert [changes the alert's status](#update-an-alerts-status) to
+**Resolved**. See [Alert List](#alert-list) for more details
about alert statuses.
### Assign an alert
@@ -196,7 +217,7 @@ To assign an alert:
After completing their portion of investigating or fixing the alert, users can
unassign themselves from the alert. To remove an assignee, select **Edit** next to the **Assignee** dropdown menu
-and deselect the user from the list of assignees, or select **Unassigned**.
+and clear the user from the list of assignees, or select **Unassigned**.
### Create a to-do item from an alert
@@ -217,13 +238,3 @@ add a to-do item:
![Alert Details Add a to do](img/alert_detail_add_todo_v13_9.png)
To view your To-Do List, on the top bar, select **To-Do List** (**{todo-done}**).
-
-## View the environment that generated the alert
-
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/232492) in GitLab 13.5 behind a feature flag, disabled by default.
-> - [Enabled by default](https://gitlab.com/gitlab-org/gitlab/-/issues/232492) in GitLab 13.6.
-
-WARNING:
-This feature might not be available to you. Check the **version history** note above for details.
-
-The environment information and the link are displayed in the [Alert Details tab](#alert-details-tab).
diff --git a/doc/operations/incident_management/img/incident_list_v14_9.png b/doc/operations/incident_management/img/incident_list_v14_9.png
new file mode 100644
index 00000000000..4cf6f0e6522
--- /dev/null
+++ b/doc/operations/incident_management/img/incident_list_v14_9.png
Binary files differ
diff --git a/doc/operations/incident_management/img/incident_metrics_tab_text_link_modal_v14_9.png b/doc/operations/incident_management/img/incident_metrics_tab_text_link_modal_v14_9.png
new file mode 100644
index 00000000000..1b045a13fc5
--- /dev/null
+++ b/doc/operations/incident_management/img/incident_metrics_tab_text_link_modal_v14_9.png
Binary files differ
diff --git a/doc/operations/incident_management/img/metric_image_url_dialog_v13_8.png b/doc/operations/incident_management/img/metric_image_url_dialog_v13_8.png
deleted file mode 100644
index 732921bbb9f..00000000000
--- a/doc/operations/incident_management/img/metric_image_url_dialog_v13_8.png
+++ /dev/null
Binary files differ
diff --git a/doc/operations/incident_management/incidents.md b/doc/operations/incident_management/incidents.md
index e142d060d87..c7ed386f505 100644
--- a/doc/operations/incident_management/incidents.md
+++ b/doc/operations/incident_management/incidents.md
@@ -54,7 +54,7 @@ GitLab to create incident automatically whenever an alert is triggered:
1. Check the **Create an incident** checkbox.
1. To customize the incident, select an
[issue template](../../user/project/description_templates.md#create-an-issue-template).
-1. To send [an email notification](paging.md#email-notifications) to users
+1. To send [an email notification](paging.md#email-notifications-for-alerts) to users
with the Developer role, select
**Send a separate email notification to Developers**. Email notifications are
also sent to users with the **Maintainer** and **Owner** roles.
@@ -89,9 +89,9 @@ For users with at least Guest [permissions](../../user/permissions.md), the
Incident list is available at **Monitor > Incidents**
in your project's sidebar. The list contains the following metrics:
-![Incident List](img/incident_list_v13_5.png)
+![Incident List](img/incident_list_v14_9.png)
-- **Status** - To filter incidents by their status, click **Open**, **Closed**,
+- **State** - To filter incidents by their state, select **Open**, **Closed**,
or **All** above the incident list.
- **Search** - The Incident list supports a simple free text search, which filters
on the **Title** and **Incident** fields.
@@ -108,6 +108,13 @@ in your project's sidebar. The list contains the following metrics:
- **Incident** - The description of the incident, which attempts to capture the
most meaningful data.
+- **Status** - The status of the incident, which can be one of the following values:
+ - **Triggered**
+ - **Acknowledged**
+ - **Resolved**
+
+ In GitLab Premium, this field is also linked to [on-call escalation](paging.md#escalating-an-incident) for the incident.
+
- **Date created** - How long ago the incident was created. This field uses the
standard GitLab pattern of `X time ago`, but is supported by a granular date/time
tooltip depending on the user's locale.
@@ -173,9 +180,11 @@ charts in the **Metrics** tab:
![Incident Metrics tab](img/incident_metrics_tab_v13_8.png)
-When you upload an image, you can associate it with a URL to the original graph. Users can access the original graph by clicking the image:
+When you upload an image, you can associate the image with text or a link to the original graph.
-![Metric image URL dialog](img/metric_image_url_dialog_v13_8.png)
+![Text link modal](img/incident_metrics_tab_text_link_modal_v14_9.png)
+
+If you add a link, you can access the original graph by clicking the hyperlink above the uploaded image.
### Alert details
@@ -226,7 +235,7 @@ There are different actions available to help triage and respond to incidents.
### Assign incidents
Assign incidents to users that are actively responding. Select **Edit** in the
-right-hand side bar to select or deselect assignees.
+right-hand side bar to select or clear assignees.
### Associate a milestone
@@ -244,6 +253,40 @@ You can also change the severity using the [`/severity` quick action](../../user
Add a to-do for incidents that you want to track in your to-do list. Click the
**Add a to do** button at the top of the right-hand side bar to add a to-do item.
+### Change incident status
+
+> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/5716) in GitLab 14.9.
+
+For users with the Developer role or higher, select **Edit** in the **Status** section of the
+right-hand side bar of an incident, then select a status. **Triggered** is the default status for
+new incidents.
+
+In projects with GitLab Premium, on-call responders can respond to [incident pages](paging.md#escalating-an-incident)
+by changing the status. Setting the status to:
+
+- **Resolved** silences on-call pages for the alert.
+- **Acknowledged** limits on-call pages based on the selected [escalation policy](#change-escalation-policy).
+- **Triggered** from **Resolved** restarts the incident escalating from the beginning.
+
+For [incidents created from alerts](alerts.md#create-an-incident-from-an-alert),
+updating the incident status also updates the alert status.
+
+## Change escalation policy **(PREMIUM)**
+
+> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/5716) in GitLab 14.9.
+
+For users with the Developer role or higher, select **Edit** in the **Escalation policy** section of
+the right-hand side bar of an incident, then select a policy. By default, new incidents do not have
+an escalation policy selected.
+
+Selecting an escalation policy updates the incident status to **Triggered** and begins
+[escalating the incident to on-call responders](paging.md#escalating-an-incident).
+Deselecting an escalation policy halts escalation. Refer to the [incident status](#change-incident-status)
+to manage on-call paging once escalation has begun.
+
+For [incidents created from alerts](alerts.md#create-an-incident-from-an-alert),
+the incident's escalation policy reflects the alert's escalation policy and cannot be changed.
+
### Manage incidents from Slack
Slack slash commands allow you to control GitLab and view GitLab content without leaving Slack.
diff --git a/doc/operations/incident_management/oncall_schedules.md b/doc/operations/incident_management/oncall_schedules.md
index 84ab5da77df..9b2e9159429 100644
--- a/doc/operations/incident_management/oncall_schedules.md
+++ b/doc/operations/incident_management/oncall_schedules.md
@@ -10,8 +10,8 @@ info: To determine the technical writer assigned to the Stage/Group associated w
Use on-call schedule management to create schedules for responders to rotate on-call
responsibilities. Maintain the availability of your software services by putting your teams on-call.
-With an on-call schedule, your team is notified immediately when things go wrong so they can quickly
-respond to service outages and disruptions.
+With [escalation policies](escalation_policies.md) and on-call schedules, your team is notified immediately
+when things go wrong so they can quickly respond to service outages and disruptions.
To use on-call schedules:
@@ -111,9 +111,7 @@ Hover over any rotation shift participants in the schedule to view their individ
## Page an on-call responder
-When an alert is created in a project, GitLab sends an email to the on-call responder(s) in the
-on-call schedule for that project. If there is no schedule or no one on-call in that schedule at the
-time the alert is triggered, no email is sent.
+See [Paging](paging.md#paging) for more details.
## Removal or deletion of on-call user
diff --git a/doc/operations/incident_management/paging.md b/doc/operations/incident_management/paging.md
index b6f77de3b4f..27854a9e201 100644
--- a/doc/operations/incident_management/paging.md
+++ b/doc/operations/incident_management/paging.md
@@ -21,7 +21,7 @@ receive a **single** page via Slack. To set up Slack notifications on your mobil
device, make sure to enable notifications for the Slack app on your phone so
you never miss a page.
-## Email notifications
+## Email notifications for alerts
Email notifications are available in projects for triggered alerts. Project
members with the **Owner** or **Maintainer** roles have the option to receive
@@ -34,8 +34,30 @@ a single email notification for new alerts.
**Send a single email notification to Owners and Maintainers for new alerts** checkbox.
1. Select **Save changes**.
+[Update the alert's status](alerts.md#update-an-alerts-status) to manage email notifications for an alert.
+
## Paging **(PREMIUM)**
-In projects that have an [on-call schedule](oncall_schedules.md) configured, on-call responders are
-paged through email for triggered alerts. The on-call responder(s) receive one email for triggered
-alerts.
+In projects that have an [escalation policy](escalation_policies.md) configured, on-call responder(s)
+can be automatically paged about critical problems through email.
+
+### Escalating an alert
+
+When an alert is triggered, it begins escalating to the on-call responders immediately.
+For each escalation rule in the project's escalation policy, the designated on-call
+responders receive one email when the rule fires. You can respond to a page
+or stop alert escalations by [updating the alert's status](alerts.md#update-an-alerts-status).
+
+### Escalating an incident
+
+> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/5716) in GitLab 14.9.
+
+For incidents, paging on-call responders is optional for each individual incident.
+To begin escalating the incident, [set the incident's escalation policy](incidents.md#change-escalation-policy).
+For each escalation rule, the designated on-call responders receive one email when
+the rule fires. You can respond to a page or stop incident escalations by
+[updating the incident's status](incidents.md#change-incident-status) or, if applicable,
+[unsetting the incident's escalation policy](incidents.md#change-escalation-policy).
+
+To avoid duplicate pages, [incidents created from alerts](alerts.md#create-an-incident-from-an-alert) do not support independent escalation.
+Instead, the status and escalation policy fields are synced between the alert and the incident.
diff --git a/doc/operations/metrics/dashboards/panel_types.md b/doc/operations/metrics/dashboards/panel_types.md
index 09e969e8af6..734b560bf13 100644
--- a/doc/operations/metrics/dashboards/panel_types.md
+++ b/doc/operations/metrics/dashboards/panel_types.md
@@ -234,7 +234,7 @@ For example, if you have a query value of `53.6`, adding `%` as the unit results
## Gauge
WARNING:
-This panel type is an _alpha_ feature, and is subject to change at any time
+This panel type is an [Alpha](../../../policy/alpha-beta-support.md#alpha-features) feature, and is subject to change at any time
without prior notice!
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/207044) in GitLab 13.3.
diff --git a/doc/operations/metrics/dashboards/templating_variables.md b/doc/operations/metrics/dashboards/templating_variables.md
index 531693d032f..d751a96f379 100644
--- a/doc/operations/metrics/dashboards/templating_variables.md
+++ b/doc/operations/metrics/dashboards/templating_variables.md
@@ -27,7 +27,7 @@ described [in Using Variables](variables.md).
## `text` variable type
WARNING:
-This variable type is an _alpha_ feature, and is subject to change at any time
+This variable type is an [Alpha](../../../policy/alpha-beta-support.md#alpha-features) feature, and is subject to change at any time
without prior notice!
For each `text` variable defined in the dashboard YAML, a free text field displays
@@ -64,7 +64,7 @@ templating:
## `custom` variable type
WARNING:
-This variable type is an _alpha_ feature, and is subject to change at any time
+This variable type is an [Alpha](../../../policy/alpha-beta-support.md#alpha-features) feature, and is subject to change at any time
without prior notice!
Each `custom` variable defined in the dashboard YAML creates a dropdown
@@ -112,7 +112,7 @@ templating:
## `metric_label_values` variable type
WARNING:
-This variable type is an _alpha_ feature, and is subject to change at any time
+This variable type is an [Alpha](../../../policy/alpha-beta-support.md#alpha-features) feature, and is subject to change at any time
without prior notice!
### Full syntax
diff --git a/doc/push_rules/push_rules.md b/doc/push_rules/push_rules.md
index 3c4b0e10bf9..ab87cba9da3 100644
--- a/doc/push_rules/push_rules.md
+++ b/doc/push_rules/push_rules.md
@@ -6,4 +6,6 @@ remove_date: '2022-05-10'
This document was moved to [another location](../user/project/repository/push_rules.md).
<!-- This redirect file can be deleted after <2022-05-10>. -->
-<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/#move-or-rename-a-page -->
+<!-- Redirects that point to other docs in the same project expire in three months. -->
+<!-- Redirects that point to docs in a different project or site (for example, link is not relative and starts with `https:`) expire in one year. -->
+<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/redirects.html -->
diff --git a/doc/raketasks/backup_restore.md b/doc/raketasks/backup_restore.md
index 30cd0f8f511..cef52cc61d7 100644
--- a/doc/raketasks/backup_restore.md
+++ b/doc/raketasks/backup_restore.md
@@ -434,7 +434,7 @@ gitlab_rails['backup_upload_storage_options'] = {
###### SSE-KMS
To enable SSE-KMS, you'll need the [KMS key via its Amazon Resource Name (ARN)
-in the `arn:aws:kms:region:acct-id:key/key-id` format](https://docs.aws.amazon.com/AmazonS3/latest/userguide/UsingKMSEncryption.html). Under the `backup_upload_storage_options` config setting, set:
+in the `arn:aws:kms:region:acct-id:key/key-id` format](https://docs.aws.amazon.com/AmazonS3/latest/userguide/UsingKMSEncryption.html). Under the `backup_upload_storage_options` configuration setting, set:
- `server_side_encryption` to `aws:kms`.
- `server_side_encryption_kms_key_id` to the ARN of the key.
@@ -1191,7 +1191,7 @@ has a longer discussion explaining the potential problems.
To prevent writes to the Git repository data, there are two possible approaches:
-- Use [maintenance mode](../administration/maintenance_mode/index.md) **(PREMIUM SELF)** to place GitLab in a read-only state.
+- Use [maintenance mode](../administration/maintenance_mode/index.md) to place GitLab in a read-only state.
- Create explicit downtime by stopping all Gitaly services before backing up the repositories:
```shell
@@ -1354,15 +1354,13 @@ To prepare the new server:
```shell
sudo rm -f /var/opt/gitlab/redis/dump.rdb
- sudo chown <your-linux-username> /var/opt/gitlab/redis
- sudo mkdir /var/opt/gitlab/backups
- sudo chown <your-linux-username> /var/opt/gitlab/backups
+ sudo chown <your-linux-username> /var/opt/gitlab/redis /var/opt/gitlab/backups
```
### Prepare and transfer content from the old server
1. Ensure you have an up-to-date system-level backup or snapshot of the old server.
-1. Enable [maintenance mode](../administration/maintenance_mode/index.md) **(PREMIUM SELF)**,
+1. Enable [maintenance mode](../administration/maintenance_mode/index.md),
if supported by your GitLab edition.
1. Block new CI/CD jobs from starting:
1. Edit `/etc/gitlab/gitlab.rb`, and set the following:
@@ -1461,11 +1459,11 @@ To prepare the new server:
1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Monitoring > Background Jobs**.
1. Under the Sidekiq dashboard, verify that the numbers
- match with what was shown on the old server.
+ match with what was shown on the old server.
1. While still under the Sidekiq dashboard, select **Cron** and then **Enable All**
to re-enable periodic background jobs.
1. Test that read-only operations on the GitLab instance work as expected. For example, browse through project repository files, merge requests, and issues.
-1. Disable [Maintenance Mode](../administration/maintenance_mode/index.md) **(PREMIUM SELF)**, if previously enabled.
+1. Disable [Maintenance Mode](../administration/maintenance_mode/index.md), if previously enabled.
1. Test that the GitLab instance is working as expected.
1. If applicable, re-enable [incoming email](../administration/incoming_email.md) and test it is working as expected.
1. Update your DNS or load balancer to point at the new server.
@@ -1856,3 +1854,22 @@ To enable it:
```ruby
Feature.enable(:gitaly_backup)
```
+
+### Incremental repository backups
+
+> Introduced in GitLab 14.9 [with a flag](../administration/feature_flags.md) named `incremental_repository_backup`. Disabled by default.
+
+FLAG:
+On self-managed GitLab, by default this feature is not available. To make it available, ask an administrator to [enable the feature flag](../administration/feature_flags.md) named `incremental_repository_backup`.
+On GitLab.com, this feature is not available.
+This feature is not ready for production use.
+
+Incremental backups can be faster than full backups because they only pack changes since the last backup into the backup
+bundle for each repository. Because incremental backups require access to the previous backup, you can't use incremental
+backups with tar files.
+
+To create an incremental backup, run:
+
+```shell
+sudo gitlab-backup create SKIP=tar INCREMENTAL=yes
+```
diff --git a/doc/raketasks/features.md b/doc/raketasks/features.md
index 3248f7370e8..e2554c1c18d 100644
--- a/doc/raketasks/features.md
+++ b/doc/raketasks/features.md
@@ -1,34 +1,9 @@
---
-stage: Enablement
-group: Distribution
-info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
+redirect_to: 'index.md'
+remove_date: '2022-05-24'
---
-# Namespaces **(FREE SELF)**
+This document was moved to [another location](index.md).
-This Rake task enables [namespaces](../user/group/index.md#namespaces) for projects.
-
-## Enable usernames and namespaces for user projects
-
-This command enables the namespaces feature. It moves every project in its
-namespace folder.
-
-The **repository location changes as part of this task**, so you must **update all your Git URLs** to
-point to the new location.
-
-To change your username:
-
-1. In the top-right corner, select your avatar.
-1. Select **Edit profile**.
-1. On the left sidebar, select **Account**.
-1. In the **Change username** section, type the new username.
-1. Select **Update username**.
-
-For example:
-
-- Old path: `git@example.org:myrepo.git`.
-- New path: `git@example.org:username/myrepo.git` or `git@example.org:groupname/myrepo.git`.
-
-```shell
-bundle exec rake gitlab:enable_namespaces RAILS_ENV=production
-```
+<!-- This redirect file can be deleted after <2022-05-24>. -->
+<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/#move-or-rename-a-page -->
diff --git a/doc/raketasks/list_repos.md b/doc/raketasks/list_repos.md
index 35c5e1e3357..57020491197 100644
--- a/doc/raketasks/list_repos.md
+++ b/doc/raketasks/list_repos.md
@@ -24,7 +24,7 @@ The results use the default ordering of the GitLab Rails application.
## Limit search results
To list only projects with recent activity, pass a date with the `SINCE` environment variable. The
-time you specify is parsed by the Rails [TimeZone#parse function](https://api.rubyonrails.org/classes/ActiveSupport/TimeZone.html#method-i-parse).
+time you specify is parsed by the Rails [`TimeZone#parse` function](https://api.rubyonrails.org/classes/ActiveSupport/TimeZone.html#method-i-parse).
```shell
# Omnibus
diff --git a/doc/security/rate_limits.md b/doc/security/rate_limits.md
index a9b066631e7..cdf99e8377d 100644
--- a/doc/security/rate_limits.md
+++ b/doc/security/rate_limits.md
@@ -93,7 +93,7 @@ The **rate limit** is 5 requests per minute per user.
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/339151) in GitLab 14.7.
There is a rate limit per IP address on the `/users/sign_up` endpoint. This is to mitigate attempts to misuse the endpoint. For example, to mass
-discover usernames or email addresses in use.
+discover usernames or email addresses in use.
The **rate limit** is 20 calls per minute per IP address.
@@ -113,7 +113,7 @@ The **rate limit** is 10 calls per minute per signed-in user.
There is a rate limit for the internal endpoint `/users/:username/exists`, used upon sign up to check if a chosen username has already been taken.
This is to mitigate the risk of misuses, such as mass discovery of usernames in use.
-The **rate limit** is 20 calls per minute per IP address.
+The **rate limit** is 20 calls per minute per IP address.
## Troubleshooting
diff --git a/doc/security/two_factor_authentication.md b/doc/security/two_factor_authentication.md
index e8bb627ccbd..cab9f6a957e 100644
--- a/doc/security/two_factor_authentication.md
+++ b/doc/security/two_factor_authentication.md
@@ -33,10 +33,10 @@ To enable 2FA for all users:
If you want 2FA enforcement to take effect during the next sign-in attempt,
change the grace period to `0`.
-## Disable 2FA enforcement through rails console
+## Disable 2FA enforcement through Rails console
-Using the [rails console](../administration/operations/rails_console.md), enforcing 2FA for
-all user can be disabled. Connect to the rails console and run:
+Using the [Rails console](../administration/operations/rails_console.md), enforcing 2FA for
+all user can be disabled. Connect to the Rails console and run:
```ruby
Gitlab::CurrentSettings.update!('require_two_factor_authentication': false)
@@ -74,7 +74,7 @@ The following are important notes about 2FA:
2FA enabled, 2FA is **not** required for those individually added members.
- If there are multiple 2FA requirements (for example, group + all users, or multiple
groups) the shortest grace period is used.
-- It is possible to disallow subgroups from setting up their own 2FA requirements:
+- It is possible to prevent subgroups from setting up their own 2FA requirements:
1. Go to the top-level group's **Settings > General**.
1. Expand the **Permissions and group features** section.
1. Uncheck the **Allow subgroups to set up their own two-factor authentication rule** field.
@@ -108,13 +108,10 @@ reactivate 2FA from scratch if they want to use it again.
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/270554) in GitLab 13.7.
> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/299088) from GitLab Free to GitLab Premium in 13.9.
-> - It's [deployed behind a feature flag](../user/feature_flags.md), disabled by default.
-> - It's disabled on GitLab.com.
-> - It's not recommended for production use.
-> - To use it in GitLab self-managed instances, ask a GitLab administrator to [enable it](#enable-or-disable-2fa-for-git-operations).
+> - It's deployed behind a feature flag, disabled by default.
-WARNING:
-This feature might not be available to you. Check the **version history** note above for details.
+FLAG:
+On self-managed GitLab, by default this feature is not available. To make it available, ask an administrator to [enable the feature flag](../administration/feature_flags.md) named `two_factor_for_cli`. On GitLab.com, this feature is not available. The feature is not ready for production use. This feature flag also affects [session duration for Git Operations when 2FA is enabled](../user/admin_area/settings/account_and_limit_settings.md#customize-session-duration-for-git-operations-when-2fa-is-enabled).
Two-factor authentication can be enforced for Git over SSH operations. However, we recommend using
[ED25519_SK](../ssh/index.md#ed25519_sk-ssh-keys) or [ECDSA_SK](../ssh/index.md#ecdsa_sk-ssh-keys) SSH keys instead.
@@ -135,30 +132,6 @@ After the OTP is verified, Git over SSH operations can be used for a session dur
Once an OTP is verified, anyone can run Git over SSH with that private SSH key for
the configured [session duration](../user/admin_area/settings/account_and_limit_settings.md#customize-session-duration-for-git-operations-when-2fa-is-enabled).
-### Enable or disable 2FA for Git operations
-
-2FA for Git operations is under development and not
-ready for production use. It is deployed behind a feature flag that is
-**disabled by default**. [GitLab administrators with access to the GitLab Rails console](../administration/feature_flags.md)
-can enable it.
-
-To enable it:
-
-```ruby
-Feature.enable(:two_factor_for_cli)
-```
-
-To disable it:
-
-```ruby
-Feature.disable(:two_factor_for_cli)
-```
-
-The feature flag affects these features:
-
-- [Two-factor Authentication (2FA) for Git over SSH operations](#2fa-for-git-over-ssh-operations).
-- [Customize session duration for Git Operations when 2FA is enabled](../user/admin_area/settings/account_and_limit_settings.md#customize-session-duration-for-git-operations-when-2fa-is-enabled).
-
<!-- ## Troubleshooting
Include any troubleshooting steps that you can foresee. If you know beforehand what issues
diff --git a/doc/ssh/index.md b/doc/ssh/index.md
index 35ca9a23179..846e5c369bb 100644
--- a/doc/ssh/index.md
+++ b/doc/ssh/index.md
@@ -408,7 +408,7 @@ If you are using [EGit](https://www.eclipse.org/egit/), you can [add your SSH ke
## Use SSH on Microsoft Windows
If you're running Windows 10, you can either use the [Windows Subsystem for Linux (WSL)](https://docs.microsoft.com/en-us/windows/wsl/install)
-with [WSL 2](https://docs.microsoft.com/en-us/windows/wsl/install-win10#update-to-wsl-2) which
+with [WSL 2](https://docs.microsoft.com/en-us/windows/wsl/install#update-to-wsl-2) which
has both `git` and `ssh` preinstalled, or install [Git for Windows](https://gitforwindows.org) to
use SSH through Powershell.
@@ -479,3 +479,19 @@ ssh: Could not resolve hostname gitlab.example.com: nodename nor servname provid
```
If you receive this error, restart your terminal and try the command again.
+
+### `Key enrollment failed: invalid format` error
+
+You may receive the following error when [generating an SSH key pair for a FIDO/U2F hardware security key](#generate-an-ssh-key-pair-for-a-fidou2f-hardware-security-key):
+
+```shell
+Key enrollment failed: invalid format
+```
+
+You can troubleshoot this by trying the following:
+
+- Run the `ssh-keygen` command using `sudo`.
+- Verify your IDO/U2F hardware security key supports
+ the key type provided.
+- Verify the version of OpenSSH is 8.2 or greater by
+ running `ssh -v`.
diff --git a/doc/subscriptions/index.md b/doc/subscriptions/index.md
index 3f9a1898505..6c5543edb58 100644
--- a/doc/subscriptions/index.md
+++ b/doc/subscriptions/index.md
@@ -154,7 +154,7 @@ To change the namespace linked to a subscription:
for that group.
1. Select **Proceed to checkout**.
-Subscription charges are calculated based on the total number of users in a group, including its subgroups and nested projects. If the [total number of users](gitlab_com/index.md#view-seat-usage) exceeds the number of seats in your subscription, your account is charged for the additional users and you need to pay for the overage before you can change the linked namespace.
+Subscription charges are calculated based on the total number of users in a group, including its subgroups and nested projects. If the [total number of users](gitlab_com/index.md#view-seat-usage) exceeds the number of seats in your subscription, your account is charged for the additional users and you need to pay for the overage before you can change the linked namespace.
Only one namespace can be linked to a subscription.
diff --git a/doc/subscriptions/self_managed/index.md b/doc/subscriptions/self_managed/index.md
index cb9db3673ac..d38b56bb1f8 100644
--- a/doc/subscriptions/self_managed/index.md
+++ b/doc/subscriptions/self_managed/index.md
@@ -153,13 +153,13 @@ See the [quarterly subscription reconciliation section](../quarterly_reconciliat
### How cloud licensing works
-#### Activate your license
+#### Add your license
1. When you purchase a GitLab self-managed plan, an activation code is generated.
This activation code is sent to the email address associated with the Customers Portal account.
1. In GitLab, on the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Subscription** and paste the activation code in the text field.
-1. Select **Activate**.
+1. Select **Add license**.
The page displays the details of the subscription.
@@ -255,8 +255,8 @@ to IP address `104.18.26.123:443` (`customers.gitlab.com`).
To subscribe to GitLab through a GitLab self-managed installation:
1. Go to the [Customers Portal](https://customers.gitlab.com/) and purchase a GitLab self-managed plan.
-1. After purchase, a license file is sent to the email address associated to the Customers Portal account,
- which must be [uploaded to your GitLab instance](../../user/admin_area/license.md#upload-your-license).
+1. After purchase, an activation code is sent to the email address associated with the Customers Portal account.
+ You must [add this code to your GitLab instance](../../user/admin_area/license.md).
NOTE:
If you're purchasing a subscription for an existing **Free** GitLab self-managed
@@ -380,7 +380,7 @@ To add seats to a subscription:
The following items are emailed to you:
- A payment receipt. You can also access this information in the Customers Portal under [**View invoices**](https://customers.gitlab.com/receipts).
-- A new license. [Upload this license](../../user/admin_area/license.md#upload-your-license) to your instance to use it.
+- An activation code. [Add this code](../../user/admin_area/license.md) to your instance to use it.
### Renew a subscription
@@ -388,7 +388,7 @@ Starting 30 days before a subscription expires, GitLab notifies administrators o
We recommend following these steps during renewal:
-1. Prune any inactive or unwanted users by [blocking them](../../user/admin_area/moderate_users.md#block-a-user).
+1. Prior to the renewal date, prune any inactive or unwanted users by [blocking them](../../user/admin_area/moderate_users.md#block-a-user).
1. Determine if you have a need for user growth in the upcoming subscription.
1. Log in to the [Customers Portal](https://customers.gitlab.com/customers/sign_in) and select the **Renew** button beneath your existing subscription.
The **Renew** button remains disabled (grayed-out) until 15 days before a subscription expires.
@@ -400,8 +400,8 @@ You can hover your mouse on the **Renew** button to see the date when it will be
1. In the first box, enter the total number of user licenses you'll need for the upcoming year. Be sure this number is at least **equal to, or greater than** the number of billable users in the system at the time of performing the renewal.
1. Enter the number of [users over license](#users-over-license) in the second box for the user overage incurred in your previous subscription term.
1. Review your renewal details and complete the payment process.
-1. A license for the renewal term is available for download on the [Manage Purchases](https://customers.gitlab.com/subscriptions) page on the relevant subscription card. Select **Copy license to clipboard** or **Download license** to get a copy.
-1. [Upload](../../user/admin_area/license.md#upload-your-license) your new license to your instance.
+1. An activation code for the renewal term is available on the [Manage Purchases](https://customers.gitlab.com/subscriptions) page on the relevant subscription card. Select **Copy activation code** to get a copy.
+1. [Add the activation code](../../user/admin_area/license.md) to your instance.
An invoice is generated for the renewal and available for viewing or download on the [View invoices](https://customers.gitlab.com/receipts) page. If you have difficulty during the renewal process, contact our [support team](https://support.gitlab.com/hc/en-us/requests/new?ticket_form_id=360000071293) for assistance.
@@ -421,10 +421,10 @@ The following is emailed to you:
- A payment receipt. You can also access this information in the Customers Portal under
[**View invoices**](https://customers.gitlab.com/receipts).
-- A new license.
+- A new activation code for your license.
-[Upload the new license](../../user/admin_area/license.md#upload-your-license) to your instance.
-The new tier takes effect when the new license is uploaded.
+[Add the activation code](../../user/admin_area/license.md) to your instance.
+The new tier takes effect when the new license is activated.
## Add or change the contacts for your subscription
@@ -447,7 +447,7 @@ an expiration message is displayed to all administrators.
For GitLab self-managed instances, you have a 14-day grace period
before this occurs.
-- To resume functionality, upload a new license.
+- To resume functionality, acticate a new license.
- To fall back to Free features, delete the expired license.
## Contact Support
diff --git a/doc/topics/autodevops/customize.md b/doc/topics/autodevops/customize.md
index 089f9f8e7cc..503774ef6b5 100644
--- a/doc/topics/autodevops/customize.md
+++ b/doc/topics/autodevops/customize.md
@@ -26,7 +26,7 @@ used for the build.
Specify either:
-- The CI/CD variable `BUILDPACK_URL` according to [`pack`'s specifications](https://buildpacks.io/docs/app-developer-guide/specific-buildpacks/).
+- The CI/CD variable `BUILDPACK_URL` according to [`pack`'s specifications](https://buildpacks.io/docs/app-developer-guide/specify-buildpacks/).
- A [`project.toml` project descriptor](https://buildpacks.io/docs/app-developer-guide/using-project-descriptor/) with the buildpacks you would like to include.
### Custom buildpacks with Herokuish
@@ -190,7 +190,7 @@ You can override the default values in the `values.yaml` file in the
`HELM_UPGRADE_VALUES_FILE` [CI/CD variable](#cicd-variables) with
the path and name.
-Some values can not be overridden with the options above. Settings like `replicaCount` should instead be overridden with the `REPLICAS`
+Some values can not be overridden with the options above. Settings like `replicaCount` should instead be overridden with the `REPLICAS`
[build and deployment](#build-and-deployment) CI/CD variable. Follow [this issue](https://gitlab.com/gitlab-org/cluster-integration/auto-deploy-image/-/issues/31) for more information.
NOTE:
@@ -431,7 +431,7 @@ applications.
| `HELM_UPGRADE_EXTRA_ARGS` | Allows extra options in `helm upgrade` commands when deploying the application. Note that using quotes doesn't prevent word splitting. |
| `INCREMENTAL_ROLLOUT_MODE` | If present, can be used to enable an [incremental rollout](#incremental-rollout-to-production) of your application for the production environment. Set to `manual` for manual deployment jobs or `timed` for automatic rollout deployments with a 5 minute delay each one. |
| `K8S_SECRET_*` | Any variable prefixed with [`K8S_SECRET_`](#application-secret-variables) is made available by Auto DevOps as environment variables to the deployed application. |
-| `KUBE_CONTEXT` | From GitLab 14.5, can be used to select which context to use from `KUBECONFIG`. When `KUBE_CONTEXT` is blank, the default context in `KUBECONFIG` (if any) will be used. A context must be selected when using the [CI/CD tunnel](../../user/clusters/agent/ci_cd_tunnel.md). |
+| `KUBE_CONTEXT` | From GitLab 14.5, can be used to select a context to use from `KUBECONFIG`. When `KUBE_CONTEXT` is blank, the default context in `KUBECONFIG` (if any) is used. A context must be selected when used [with the agent for Kubernetes](../../user/clusters/agent/ci_cd_tunnel.md). |
| `KUBE_INGRESS_BASE_DOMAIN` | Can be used to set a domain per cluster. See [cluster domains](../../user/project/clusters/gitlab_managed_clusters.md#base-domain) for more information. |
| `KUBE_NAMESPACE` | The namespace used for deployments. When using certificate-based clusters, [this value should not be overwritten directly](../../user/project/clusters/deploy_to_cluster.md#custom-namespace). |
| `KUBECONFIG` | The kubeconfig to use for deployments. User-provided values take priority over GitLab-provided values. |
diff --git a/doc/topics/autodevops/index.md b/doc/topics/autodevops/index.md
index 585d484d3be..c8efc40a4cd 100644
--- a/doc/topics/autodevops/index.md
+++ b/doc/topics/autodevops/index.md
@@ -7,7 +7,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Auto DevOps **(FREE)**
> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/38366) in GitLab 11.0.
-> - Support for the GitLab Agent was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/299350) in GitLab 14.5.
+> - Support for the GitLab agent was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/299350) in GitLab 14.5.
GitLab Auto DevOps is a collection of pre-configured features and integrations
that work together to support your software delivery process.
@@ -172,7 +172,7 @@ To disable it, follow the same process and clear the
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/52447) in GitLab 11.10.
When you enable Auto DevOps at group level, the subgroups and projects in that
-group inherit the configuration. This saves you time by batch-enabling it
+group inherit the configuration. This saves you some time by batch-enabling it
rather than enabling individually for each subgroup or project.
When enabled for a group, you can still disable Auto DevOps
@@ -207,7 +207,7 @@ instance become enabled. This is convenient when you want to run Auto DevOps by
default for all projects. You can still disable Auto DevOps individually for
the groups and projects where you don't want to run it.
-Only GitLab administrators can enable or disable Auto DevOps in the instance
+Only GitLab administrators can enable or disable Auto DevOps at the instance
level.
Even when disabled for an instance, group owners and project maintainers
@@ -234,7 +234,7 @@ and clear the **Default to Auto DevOps pipeline** checkbox.
### Quick start
-To guide your through the process of setting up Auto DevOps to deploy to a Kubernetes cluster on
+To guide you through the process of setting up Auto DevOps to deploy to a Kubernetes cluster on
Google Kubernetes Engine (GKE), see the [quick start guide](quick_start_guide.md).
You can also follow the quick start for the general steps, but deploy to
diff --git a/doc/topics/autodevops/quick_start_guide.md b/doc/topics/autodevops/quick_start_guide.md
index 1fc2bd7c2c0..13d831aa00d 100644
--- a/doc/topics/autodevops/quick_start_guide.md
+++ b/doc/topics/autodevops/quick_start_guide.md
@@ -76,17 +76,18 @@ to deploy this project to.
![Project landing page](img/guide_project_landing_page_v12_10.png)
-1. On the **Add a Kubernetes cluster integration** page, select the **Create new cluster** tab,
- then select **Google GKE**.
+1. On the **Kubernetes clusters** page, select the **Create a new cluster** option from the **Actions** dropdown menu.
+
+1. On the **Connect a Kubernetes cluster** page, select **Google GKE**.
1. Connect with your Google account, and select **Allow** to allow access to your
Google account. (This authorization request is only displayed the first time
you connect GitLab with your Google account.)
- After authorizing access, the **Add a Kubernetes cluster integration** page
+ After authorizing access, the **Connect a Kubernetes cluster** page
is displayed.
-1. In the **Enter the details for your Kubernetes cluster** section, provide
+1. In the **Enter your Kubernetes cluster certificate details** section, provide
details about your cluster:
- **Kubernetes cluster name**
diff --git a/doc/topics/autodevops/stages.md b/doc/topics/autodevops/stages.md
index 8b3966526ec..790b46b6310 100644
--- a/doc/topics/autodevops/stages.md
+++ b/doc/topics/autodevops/stages.md
@@ -112,7 +112,7 @@ Herokuish, with the following caveats:
converted to a Cloud Native Buildpack using Heroku's
[`cnb-shim`](https://github.com/heroku/cnb-shim).
- `BUILDPACK_URL` must be in a format
- [supported by `pack`](https://buildpacks.io/docs/app-developer-guide/specific-buildpacks/).
+ [supported by `pack`](https://buildpacks.io/docs/app-developer-guide/specify-buildpacks/).
- The `/bin/herokuish` command is not present in the built image, and prefixing
commands with `/bin/herokuish procfile exec` is no longer required (nor possible).
Instead, custom commands should be prefixed with `/cnb/lifecycle/launcher`
@@ -659,7 +659,7 @@ ciliumNetworkPolicy:
#### Enabling Alerts
You can also enable alerts. Network policies with alerts are considered only if
-[Agent](../../user/clusters/agent/index.md)
+the [agent](../../user/clusters/agent/index.md)
has been integrated.
You can enable alerts as follows:
diff --git a/doc/topics/autodevops/upgrading_auto_deploy_dependencies.md b/doc/topics/autodevops/upgrading_auto_deploy_dependencies.md
index 8c460247734..b0814ac5076 100644
--- a/doc/topics/autodevops/upgrading_auto_deploy_dependencies.md
+++ b/doc/topics/autodevops/upgrading_auto_deploy_dependencies.md
@@ -180,7 +180,7 @@ used the `v0.17.0` chart, add `AUTO_DEVOPS_FORCE_DEPLOY_V2`.
## Early adopters
-If you want to use the latest beta or unstable version of `auto-deploy-image`, include
+If you want to use the latest [Beta](../../policy/alpha-beta-support.md#beta-features) or unstable version of `auto-deploy-image`, include
the latest Auto Deploy template into your `.gitlab-ci.yml`:
```yaml
@@ -190,7 +190,7 @@ include:
```
WARNING:
-Using a beta or unstable `auto-deploy-image` could cause unrecoverable damage to
+Using a [Beta](../../policy/alpha-beta-support.md#beta-features) or unstable `auto-deploy-image` could cause unrecoverable damage to
your environments. Do not test it with important projects or environments.
The next stable template update is [planned for GitLab v14.0](https://gitlab.com/gitlab-org/gitlab/-/issues/232788).
diff --git a/doc/topics/cron/index.md b/doc/topics/cron/index.md
index affd746f66f..34a51d3d535 100644
--- a/doc/topics/cron/index.md
+++ b/doc/topics/cron/index.md
@@ -38,7 +38,10 @@ are valid:
- Run once a day at midnight: `0 0 * * *`
- Run once a week at midnight on Sunday morning: `0 0 * * 0`
- Run once a month at midnight of the first day of the month: `0 0 1 * *`
+- Run once a month on the 22nd: `0 0 22 * *`)
+- Run once a month on the 2nd Monday: `0 0 * * 1#2`
- Run once a year at midnight of 1 January: `0 0 1 1 *`
+- Run every other Sunday at 0900 hours: `0 9 * * sun%2`
For complete cron documentation, refer to the
[crontab(5) — Linux manual page](https://man7.org/linux/man-pages/man5/crontab.5.html).
diff --git a/doc/topics/git/tags.md b/doc/topics/git/tags.md
index 6e0622273bb..8576bcd09ed 100644
--- a/doc/topics/git/tags.md
+++ b/doc/topics/git/tags.md
@@ -36,6 +36,6 @@ git tag
git push origin --tags
```
-## Additional resources
+## Related topics
- [Tagging](https://git-scm.com/book/en/v2/Git-Basics-Tagging) Git reference page
diff --git a/doc/topics/gitlab_flow.md b/doc/topics/gitlab_flow.md
index 3bca33b32b7..d35eba0d782 100644
--- a/doc/topics/gitlab_flow.md
+++ b/doc/topics/gitlab_flow.md
@@ -190,7 +190,7 @@ By doing this, you minimize the length of time during which you have to apply bu
After announcing a release branch, only add serious bug fixes to the branch.
If possible, first merge these bug fixes into `main`, and then cherry-pick them into the release branch.
If you start by merging into the release branch, you might forget to cherry-pick them into `main`, and then you'd encounter the same bug in subsequent releases.
-Merging into `main` and then cherry-picking into release is called an "upstream first" policy, which is also practiced by [Google](https://www.chromium.org/chromium-os/chromiumos-design-docs/upstream-first) and [Red Hat](https://www.redhat.com/en/blog/a-community-for-using-openstack-with-red-hat-rdo).
+Merging into `main` and then cherry-picking into release is called an "upstream first" policy, which is also practiced by [Google](https://www.chromium.org/chromium-os/chromiumos-design-docs/upstream-first/) and [Red Hat](https://www.redhat.com/en/blog/a-community-for-using-openstack-with-red-hat-rdo).
Every time you include a bug fix in a release branch, increase the patch version (to comply with [Semantic Versioning](https://semver.org/)) by setting a new tag.
Some projects also have a stable branch that points to the same commit as the latest released branch.
In this flow, it is not common to have a production branch (or Git flow `main` branch).
diff --git a/doc/topics/index.md b/doc/topics/index.md
deleted file mode 100644
index 6d2c839430b..00000000000
--- a/doc/topics/index.md
+++ /dev/null
@@ -1,9 +0,0 @@
----
-redirect_to: '../index.md'
-remove_date: '2022-02-03'
----
-
-This document was moved to [another location](../index.md).
-
-<!-- This redirect file can be deleted after <2022-02-03>. -->
-<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/#move-or-rename-a-page -->
diff --git a/doc/topics/offline/quick_start_guide.md b/doc/topics/offline/quick_start_guide.md
index 09fae2b1fd5..d1be775268f 100644
--- a/doc/topics/offline/quick_start_guide.md
+++ b/doc/topics/offline/quick_start_guide.md
@@ -12,12 +12,49 @@ instance entirely offline.
## Installation
NOTE:
-This guide assumes the server is Ubuntu 18.04. Instructions for other servers may vary.
-This guide also assumes the server host resolves as `my-host`, which you should replace with your
-server's name.
+This guide assumes the server is Ubuntu 20.04 using the [Omnibus installation method](https://docs.gitlab.com/omnibus/) and will be running GitLab [Enterprise Edition](https://about.gitlab.com/install/ce-or-ee/). Instructions for other servers may vary.
+This guide also assumes the server host resolves as `my-host.internal`, which you should replace with your
+server's FQDN, and that you have access to a different server with Internet access to download the required package files.
-Follow the installation instructions [as outlined in the omnibus install
-guide](https://about.gitlab.com/install/#ubuntu), but make sure to specify an `http`
+<i class="fa fa-youtube-play youtube" aria-hidden="true"></i>
+For a video walkthrough of this process, see [Offline GitLab Installation: Downloading & Installing](https://www.youtube.com/watch?v=TJaq4ua2Prw).
+
+### Download the GitLab package
+
+You should [manually download the GitLab package](../../update/package/index.md#upgrade-using-a-manually-downloaded-package) and relevant dependencies using a server of the same operating system type that has access to the Internet.
+
+If your offline environment has no local network access, you must manually transport across the relevant package files through physical media, such as a USB drive or writable DVD.
+
+In Ubuntu, this can be performed on a server with Internet access using the following commands:
+
+```shell
+# Download the bash script to prepare the repository
+curl --silent "https://packages.gitlab.com/install/repositories/gitlab/gitlab-ee/script.deb.sh" | sudo bash
+
+# Download the gitlab-ee package and dependencies to /var/cache/apt/archives
+sudo apt-get install --download-only gitlab-ee
+
+# Copy the contents of the apt download folder to a mounted media device
+sudo cp /var/cache/apt/archives/*.deb /path/to/mount
+```
+
+### Install the GitLab package
+
+Prerequisites:
+
+- Before installing the GitLab package on your offline environment, ensure that you have installed all required dependencies first.
+
+If you are using Ubuntu, you can install the dependency `.deb` packages you copied across with `dpkg`. Do not install the GitLab package yet.
+
+```shell
+# Navigate to the physical media device
+sudo cd /path/to/mount
+
+# Install the dependency packages
+sudo dpkg -i <package_name>.deb
+```
+
+[Use the relevant commands for your operating system to install the package](../../update/package/index.md#upgrade-using-a-manually-downloaded-package) but make sure to specify an `http`
URL for the `EXTERNAL_URL` installation step. Once installed, we can manually
configure the SSL ourselves.
@@ -25,8 +62,10 @@ 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 makes long-term resolution simpler.
+The following example for Ubuntu specifies the `EXTERNAL_URL` using HTTP and installs the GitLab package:
+
```shell
-sudo EXTERNAL_URL="http://my-host.internal" apt-get install gitlab-ee
+sudo EXTERNAL_URL="http://my-host.internal" dpkg -i <gitlab_package_name>.deb
```
## Enabling SSL
@@ -38,7 +77,7 @@ Follow these steps to enable SSL for your fresh instance. Note that these steps
```ruby
# Update external_url from "http" to "https"
- external_url "https://gitlab.example.com"
+ external_url "https://my-host.internal"
# Set Let's Encrypt to false
letsencrypt['enable'] = false
@@ -159,3 +198,11 @@ If all goes well, this is what you should see:
Running hooks in /etc/ca-certificates/update.d...
done.
```
+
+### Disable Version Check and Service Ping
+
+The Version Check and Service Ping services improve the GitLab user experience and ensure that
+users are on the most up-to-date instances of GitLab. These two services can be turned off for air-gapped
+environments so that they do not attempt and fail to reach out to GitLab services.
+
+Learn more about [disabling usage statistics](../../user/admin_area/settings/usage_statistics.md#enable-or-disable-usage-statistics).
diff --git a/doc/topics/release_your_application.md b/doc/topics/release_your_application.md
index 64decba33ad..7ed227adcac 100644
--- a/doc/topics/release_your_application.md
+++ b/doc/topics/release_your_application.md
@@ -26,18 +26,18 @@ deployment using GitLab CI/CD.
### Deploy applications to Kubernetes clusters
With the extensive integration between GitLab and Kubernetes, you can safely deploy your applications
-to Kubernetes clusters using the [GitLab Agent](../user/clusters/agent/install/index.md).
+to Kubernetes clusters using the [GitLab agent](../user/clusters/agent/install/index.md).
#### GitOps deployments **(PREMIUM)**
-With the [GitLab Agent](../user/clusters/agent/install/index.md), you can perform [pull-based
-deployments of Kubernetes manifests](../user/clusters/agent/repository.md#synchronize-manifest-projects). This provides a scalable, secure, and cloud-native
+With the [GitLab agent for Kubernetes](../user/clusters/agent/install/index.md), you can perform [pull-based
+deployments of Kubernetes manifests](../user/clusters/agent/gitops.md). This provides a scalable, secure, and cloud-native
approach to manage Kubernetes deployments.
-#### Deploy to Kubernetes with the CI/CD Tunnel
+#### Deploy to Kubernetes from GitLab CI/CD
-With the [GitLab Agent](../user/clusters/agent/install/index.md), you can perform push-based
-deployments with the [CI/CD Tunnel](../user/clusters/agent/ci_cd_tunnel.md). It provides
+With the [GitLab agent for Kubernetes](../user/clusters/agent/install/index.md), you can perform [push-based
+deployments](../user/clusters/agent/ci_cd_tunnel.md) from GitLab CI/CD. The agent provides
a secure and reliable connection between GitLab and your Kubernetes cluster.
### Deploy to AWS with GitLab CI/CD
diff --git a/doc/topics/use_gitlab.md b/doc/topics/use_gitlab.md
index a7189284fe6..59a933b1441 100644
--- a/doc/topics/use_gitlab.md
+++ b/doc/topics/use_gitlab.md
@@ -14,7 +14,7 @@ organize your work, create and secure your application, and analyze its performa
- [Plan and track work](plan_and_track.md)
- [Build your application](build_your_application.md)
- [Secure your application](../user/application_security/index.md)
-- [Release your application](release_your_application.md)
+- [Deploy and release your application](release_your_application.md)
- [Monitor application performance](../operations/index.md)
- [Monitor runner performance](https://docs.gitlab.com/runner/monitoring/index.html)
- [Manage your infrastructure](../user/infrastructure/index.md)
diff --git a/doc/tutorials/index.md b/doc/tutorials/index.md
index ac05b9945db..91913813256 100644
--- a/doc/tutorials/index.md
+++ b/doc/tutorials/index.md
@@ -15,6 +15,7 @@ and running quickly.
| Topic | Description | Good for beginners |
|-------|-------------|--------------------|
+| <i class="fa fa-youtube-play youtube" aria-hidden="true"></i> [Introduction to GitLab](https://youtu.be/_4SmIyQ5eis?t=90) (59m 51s) | Walk through recommended processes and example workflows for using GitLab. | **{star}** |
| [GitLab 101](https://gitlab.edcast.com/pathways/copy-of-gitlab-certification) | Learn the basics of GitLab in this certification course. | **{star}** |
| <i class="fa fa-youtube-play youtube" aria-hidden="true"></i> [Use GitLab for DevOps](https://www.youtube.com/watch?v=7q9Y1Cv-ib0) (12m 34s) | Use GitLab through the entire DevOps lifecycle, from planning to monitoring. | **{star}** |
| [Use Markdown at GitLab](../user/markdown.md) | GitLab Flavored Markdown (GFM) is used in many areas of GitLab, for example, in merge requests. | **{star}** |
diff --git a/doc/update/deprecations.md b/doc/update/deprecations.md
index 2f5146b8161..e89c45c522c 100644
--- a/doc/update/deprecations.md
+++ b/doc/update/deprecations.md
@@ -36,9 +36,15 @@ For deprecation reviewers (Technical Writers only):
https://about.gitlab.com/handbook/marketing/blog/release-posts/#update-the-deprecations-doc
-->
-## 14.0
+## 14.9
-### NFS for Git repository storage
+### GitLab Pages running as daemon
+
+In 15.0, support for daemon mode for GitLab Pages will be removed.
+
+**Planned removal milestone: 15.0 (2022-05-22)**
+
+### GitLab self-monitoring
WARNING:
This feature will be changed or removed in 15.0
@@ -46,19 +52,11 @@ as a [breaking change](https://docs.gitlab.com/ee/development/contributing/#brea
Before updating GitLab, review the details carefully to determine if you need to make any
changes to your code, settings, or workflow.
-With the general availability of Gitaly Cluster ([introduced in GitLab 13.0](https://about.gitlab.com/releases/2020/05/22/gitlab-13-0-released/)), we have deprecated development (bugfixes, performance improvements, etc) for NFS for Git repository storage in GitLab 14.0. We will continue to provide technical support for NFS for Git repositories throughout 14.x, but we will remove all support for NFS in GitLab 15.0. Please see our official [Statement of Support](https://about.gitlab.com/support/statement-of-support.html#gitaly-and-nfs) for further information.
-
-Gitaly Cluster offers tremendous benefits for our customers such as:
-
-- [Variable replication factors](https://docs.gitlab.com/ee/administration/gitaly/index.html#replication-factor).
-- [Strong consistency](https://docs.gitlab.com/ee/administration/gitaly/index.html#strong-consistency).
-- [Distributed read capabilities](https://docs.gitlab.com/ee/administration/gitaly/index.html#distributed-reads).
-
-We encourage customers currently using NFS for Git repositories to plan their migration by reviewing our documentation on [migrating to Gitaly Cluster](https://docs.gitlab.com/ee/administration/gitaly/index.html#migrate-to-gitaly-cluster).
+GitLab self-monitoring gives administrators of self-hosted GitLab instances the tools to monitor the health of their instances. This feature is deprecated in GitLab 14.9, and is scheduled for removal in 15.0.
**Planned removal milestone: 15.0 (2022-05-22)**
-### OAuth implicit grant
+### GraphQL permissions change for Package settings
WARNING:
This feature will be changed or removed in 15.0
@@ -66,29 +64,38 @@ as a [breaking change](https://docs.gitlab.com/ee/development/contributing/#brea
Before updating GitLab, review the details carefully to determine if you need to make any
changes to your code, settings, or workflow.
-The OAuth implicit grant authorization flow will be removed in our next major release, GitLab 15.0. Any applications that use OAuth implicit grant should switch to alternative [supported OAuth flows](https://docs.gitlab.com/ee/api/oauth2.html).
+The GitLab Package stage offers a Package Registry, Container Registry, and Dependency Proxy to help you manage all of your dependencies using GitLab. Each of these product categories has a variety of settings that can be adjusted using the API.
-**Planned removal milestone: 15.0 (2022-05-22)**
+The permissions model for GraphQL is being updated. After 15.0, users with the Guest, Reporter, and Developer role can no longer update these settings:
-## 14.2
+- [Package Registry settings](https://docs.gitlab.com/ee/api/graphql/reference/#packagesettings)
+- [Container Registry cleanup policy](https://docs.gitlab.com/ee/api/graphql/reference/#containerexpirationpolicy)
+- [Dependency Proxy time-to-live policy](https://docs.gitlab.com/ee/api/graphql/reference/#dependencyproxyimagettlgrouppolicy)
+- [Enabling the Dependency Proxy for your group](https://docs.gitlab.com/ee/api/graphql/reference/#dependencyproxysetting)
-### Release CLI distributed as a generic package
+**Planned removal milestone: 15.0 (2022-05-22)**
-The [release-cli](https://gitlab.com/gitlab-org/release-cli) will be released as a [generic package](https://gitlab.com/gitlab-org/release-cli/-/packages) starting in GitLab 14.2. We will continue to deploy it as a binary to S3 until GitLab 14.5 and stop distributing it in S3 in GitLab 14.6.
+### Move `custom_hooks_dir` setting from GitLab Shell to Gitaly
-**Planned removal milestone: 14.6 (2021-12-22)**
+The [`custom_hooks_dir`](https://docs.gitlab.com/ee/administration/server_hooks.html#create-a-global-server-hook-for-all-repositories) setting is now configured in Gitaly, and will be removed from GitLab Shell in GitLab 15.0.
-### Rename Task Runner pod to Toolbox
+**Planned removal milestone: 15.0 ()**
-The Task Runner pod is used to execute periodic housekeeping tasks within the GitLab application and is often confused with the GitLab Runner. Thus, [Task Runner will be renamed to Toolbox](https://gitlab.com/groups/gitlab-org/charts/-/epics/25).
+### Permissions change for downloading Composer dependencies
-This will result in the rename of the sub-chart: `gitlab/task-runner` to `gitlab/toolbox`. Resulting pods will be named along the lines of `{{ .Release.Name }}-toolbox`, which will often be `gitlab-toolbox`. They will be locatable with the label `app=toolbox`.
+WARNING:
+This feature will be changed or removed in 15.0
+as a [breaking change](https://docs.gitlab.com/ee/development/contributing/#breaking-changes).
+Before updating GitLab, review the details carefully to determine if you need to make any
+changes to your code, settings, or workflow.
-**Planned removal milestone: 14.5 (2021-11-22)**
+The GitLab Composer repository can be used to push, search, fetch metadata about, and download PHP dependencies. All these actions require authentication, except for downloading dependencies.
-## 14.3
+Downloading Composer dependencies without authentication is deprecated in GitLab 14.9, and will be removed in GitLab 15.0. Starting with GitLab 15.0, you must authenticate to download Composer dependencies.
-### Audit events for repository push events
+**Planned removal milestone: 15.0 (2022-05-22)**
+
+### htpasswd Authentication for the Container Registry
WARNING:
This feature will be changed or removed in 15.0
@@ -96,15 +103,15 @@ as a [breaking change](https://docs.gitlab.com/ee/development/contributing/#brea
Before updating GitLab, review the details carefully to determine if you need to make any
changes to your code, settings, or workflow.
-Audit events for [repository events](https://docs.gitlab.com/ee/administration/audit_events.html#repository-push-deprecated) are now deprecated and will be removed in GitLab 15.0.
+The Container Registry supports [authentication](https://gitlab.com/gitlab-org/container-registry/-/blob/master/docs/configuration.md#auth) with `htpasswd`. It relies on an [Apache `htpasswd` file](https://httpd.apache.org/docs/2.4/programs/htpasswd.html), with passwords hashed using `bcrypt`.
-These events have always been disabled by default and had to be manually enabled with a
-feature flag. Enabling them can cause too many events to be generated which can
-dramatically slow down GitLab instances. For this reason, they are being removed.
+Since it isn't used in the context of GitLab (the product), `htpasswd` authentication will be deprecated in GitLab 14.9 and removed in GitLab 15.0.
**Planned removal milestone: 15.0 (2022-05-22)**
-### GitLab Serverless
+## 14.8
+
+### Changes to the `CI_JOB_JWT`
WARNING:
This feature will be changed or removed in 15.0
@@ -112,13 +119,20 @@ as a [breaking change](https://docs.gitlab.com/ee/development/contributing/#brea
Before updating GitLab, review the details carefully to determine if you need to make any
changes to your code, settings, or workflow.
-[GitLab Serverless](https://docs.gitlab.com/ee/user/project/clusters/serverless/) is a feature set to support Knative-based serverless development with automatic deployments and monitoring.
-
-We decided to remove the GitLab Serverless features as they never really resonated with our users. Besides, given the continuous development of Kubernetes and Knative, our current implementations do not even work with recent versions.
+The `CI_JOB_JWT` will be updated to support a wider variety of cloud providers. It will be changed to match [`CI_JOB_JWT_V2`](https://docs.gitlab.com/ee/ci/variables/predefined_variables.html), but this change may not be backwards compatible for all users, including Hashicorp Vault users. To maintain the current behavior, users can switch to using `CI_JOB_JWT_V1`, or update their configuration in GitLab 15.0 to use the improved `CI_JOB_JWT`.
**Planned removal milestone: 15.0 (2022-05-22)**
-### Legacy database configuration
+### Configurable Gitaly `per_repository` election strategy
+
+Configuring the `per_repository` Gitaly election strategy is [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/352612).
+`per_repository` has been the only option since GitLab 14.0.
+
+This change is part of regular maintenance to keep our codebase clean.
+
+**Planned removal milestone: 14.9 (2022-03-22)**
+
+### Container Network and Host Security
WARNING:
This feature will be changed or removed in 15.0
@@ -126,15 +140,20 @@ as a [breaking change](https://docs.gitlab.com/ee/development/contributing/#brea
Before updating GitLab, review the details carefully to determine if you need to make any
changes to your code, settings, or workflow.
-The syntax of [GitLabs database](https://docs.gitlab.com/omnibus/settings/database.html)
-configuration located in `database.yml` is changing and the legacy format is deprecated. The legacy format
-supported using a single PostgreSQL adapter, whereas the new format is changing to support multiple databases. The `main:` database needs to be defined as a first configuration item.
+All functionality related to GitLab's Container Network Security and Container Host Security categories is deprecated in GitLab 14.8 and scheduled for removal in GitLab 15.0. Users who need a replacement for this functionality are encouraged to evaluate the following open source projects as potential solutions that can be installed and managed outside of GitLab: [AppArmor](https://gitlab.com/apparmor/apparmor), [Cilium](https://github.com/cilium/cilium), [Falco](https://github.com/falcosecurity/falco), [FluentD](https://github.com/fluent/fluentd), [Pod Security Admission](https://kubernetes.io/docs/concepts/security/pod-security-admission/). To integrate these technologies into GitLab, add the desired Helm charts into your copy of the [Cluster Management Project Template](https://docs.gitlab.com/ee/user/clusters/management_project_template.html). Deploy these Helm charts in production by calling commands through the GitLab [Secure CI/CD Tunnel](https://docs.gitlab.com/ee/user/clusters/agent/repository.html#run-kubectl-commands-using-the-cicd-tunnel).
-This deprecation mainly impacts users compiling GitLab from source because Omnibus will handle this configuration automatically.
+As part of this change, the following specific capabilities within GitLab are now deprecated, and are scheduled for removal in GitLab 15.0:
+
+- The **Security & Compliance > Threat Monitoring** page.
+- The `Network Policy` security policy type, as found on the **Security & Compliance > Policies** page.
+- The ability to manage integrations with the following technologies through GitLab: AppArmor, Cilium, Falco, FluentD, and Pod Security Policies.
+- All APIs related to the above functionality.
+
+For additional context, or to provide feedback regarding this change, please reference our open [deprecation issue](https://gitlab.com/groups/gitlab-org/-/epics/7476).
**Planned removal milestone: 15.0 (2022-05-22)**
-### OmniAuth Kerberos gem
+### Dependency Scanning Python 3.9 and 3.6 image deprecation
WARNING:
This feature will be changed or removed in 15.0
@@ -142,41 +161,88 @@ as a [breaking change](https://docs.gitlab.com/ee/development/contributing/#brea
Before updating GitLab, review the details carefully to determine if you need to make any
changes to your code, settings, or workflow.
-The `omniauth-kerberos` gem will be removed in our next major release, GitLab 15.0.
+For those using Dependency Scanning for Python projects, we are deprecating the default `gemnasium-python:2` image which uses Python 3.6 as well as the custom `gemnasium-python:2-python-3.9` image which uses Python 3.9. The new default image as of GitLab 15.0 will be for Python 3.9 as it is a [supported version](https://endoflife.date/python) and 3.6 [is no longer supported](https://endoflife.date/python).
-This gem has not been maintained and has very little usage. We therefore plan to remove support for this authentication method and recommend using the Kerberos [SPNEGO](https://en.wikipedia.org/wiki/SPNEGO) integration instead. You can follow the [upgrade instructions](https://docs.gitlab.com/ee/integration/kerberos.html#upgrading-from-password-based-to-ticket-based-kerberos-sign-ins) to upgrade from the `omniauth-kerberos` integration to the supported one.
+For users using Python 3.9 or 3.9-compatible projects, you should not need to take action and dependency scanning should begin to work in GitLab 15.0. If you wish to test the new container now please run a test pipeline in your project with this container (which will be removed in 15.0). Use the Python 3.9 image:
-Note that we are not deprecating the Kerberos SPNEGO integration, only the old password-based Kerberos integration.
+```yaml
+gemnasium-python-dependency_scanning:
+ image:
+ name: registry.gitlab.com/gitlab-org/security-products/analyzers/gemnasium-python:2-python-3.9
+```
+
+For users using Python 3.6, as of GitLab 15.0 you will no longer be able to use the default template for dependency scanning. You will need to switch to use the deprecated `gemnasium-python:2` analyzer image. If you are impacted by this please comment in [this issue](https://gitlab.com/gitlab-org/gitlab/-/issues/351503) so we can extend the removal if needed.
+
+For users using the 3.9 special exception image, you must instead use the default value and no longer override your container. To verify if you are using the 3.9 special exception image, check your `.gitlab-ci.yml` file for the following reference:
+
+```yaml
+gemnasium-python-dependency_scanning:
+ image:
+ name: registry.gitlab.com/gitlab-org/security-products/analyzers/gemnasium-python:2-python-3.9
+```
+
+**Planned removal milestone: 15.0 (2021-05-22)**
+
+### Deprecate Geo Admin UI Routes
+
+In GitLab 13.0, we introduced new project and design replication details routes in the Geo Admin UI. These routes are `/admin/geo/replication/projects` and `/admin/geo/replication/designs`. We kept the legacy routes and redirected them to the new routes. In GitLab 15.0, we will remove support for the legacy routes `/admin/geo/projects` and `/admin/geo/designs`. Please update any bookmarks or scripts that may use the legacy routes.
**Planned removal milestone: 15.0 (2022-05-22)**
-## 14.5
+### Deprecate custom Geo:db:* Rake tasks
-### Certificate-based integration with Kubernetes
+In GitLab 14.8, we are [replacing the `geo:db:*` Rake tasks with built-in tasks](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/77269/diffs) that are now possible after [switching the Geo tracking database to use Rails' 6 support of multiple databases](https://gitlab.com/groups/gitlab-org/-/epics/6458).
+The following `geo:db:*` tasks will be replaced with their corresponding `db:*:geo` tasks:
+
+- `geo:db:drop` -> `db:drop:geo`
+- `geo:db:create` -> `db:create:geo`
+- `geo:db:setup` -> `db:setup:geo`
+- `geo:db:migrate` -> `db:migrate:geo`
+- `geo:db:rollback` -> `db:rollback:geo`
+- `geo:db:version` -> `db:version:geo`
+- `geo:db:reset` -> `db:reset:geo`
+- `geo:db:seed` -> `db:seed:geo`
+- `geo:schema:load:geo` -> `db:schema:load:geo`
+- `geo:db:schema:dump` -> `db:schema:dump:geo`
+- `geo:db:migrate:up` -> `db:migrate:up:geo`
+- `geo:db:migrate:down` -> `db:migrate:down:geo`
+- `geo:db:migrate:redo` -> `db:migrate:redo:geo`
+- `geo:db:migrate:status` -> `db:migrate:status:geo`
+- `geo:db:test:prepare` -> `db:test:prepare:geo`
+- `geo:db:test:load` -> `db:test:load:geo`
+- `geo:db:test:purge` -> `db:test:purge:geo`
+
+**Planned removal milestone: 15.0 (2022-05-22)**
+
+### Deprecate feature flag PUSH_RULES_SUPERSEDE_CODE_OWNERS
WARNING:
-This feature will be changed or removed in 15.6
+This feature will be changed or removed in 15.0
as a [breaking change](https://docs.gitlab.com/ee/development/contributing/#breaking-changes).
Before updating GitLab, review the details carefully to determine if you need to make any
changes to your code, settings, or workflow.
-[We are deprecating the certificate-based integration with Kubernetes](https://about.gitlab.com/blog/2021/11/15/deprecating-the-cert-based-kubernetes-integration/).
-The timeline of removal of the integration from the product is planned to happen in two steps, starting with milestone 15.0 and finishing in GitLab version 15.6.
+The feature flag `PUSH_RULES_SUPERSEDE_CODE_OWNERS` is being removed in GitLab 15.0. Upon its removal, push rules will supersede CODEOWNERS. The CODEOWNERS feature will no longer be available for access control.
-In 15.0, we plan to introduce a feature flag that will allow GitLab Self-Managed customers to keep the certificate-based integration enabled, it will be disabled by default. We plan to remove this feature flag together with the underlying code in GitLab version 15.6.
-The certificate-based integration will continue to receive security and
-critical fixes, and features built on the integration will continue to work with supported Kubernetes
-versions until the final removal in 15.6.
+**Planned removal milestone: 15.0 (2022-05-22)**
-For a more robust, secure, forthcoming, and reliable integration with Kubernetes, we recommend the use of the
-[Kubernetes Agent](https://docs.gitlab.com/ee/user/clusters/agent/) to connect Kubernetes clusters with GitLab.
-We provide [migration plans](https://docs.gitlab.com/ee/user/infrastructure/clusters/migrate_to_gitlab_agent.html) in the documentation.
+### Deprecate legacy Gitaly configuration methods
-For updates and details around this deprecation, follow this [epic](https://gitlab.com/groups/gitlab-org/configure/-/epics/8).
+WARNING:
+This feature will be changed or removed in 15.0
+as a [breaking change](https://docs.gitlab.com/ee/development/contributing/#breaking-changes).
+Before updating GitLab, review the details carefully to determine if you need to make any
+changes to your code, settings, or workflow.
-**Planned removal milestone: 15.6 (2022-11-22)**
+Using environment variables `GIT_CONFIG_SYSTEM` and `GIT_CONFIG_GLOBAL` to configure Gitaly is [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/352609).
+These variables are being replaced with standard [`config.toml` Gitaly configuration](https://docs.gitlab.com/ee/administration/gitaly/reference.html).
-### Converting an instance (shared) runner to a project (specific) runner
+GitLab instances that use `GIT_CONFIG_SYSTEM` and `GIT_CONFIG_GLOBAL` to configure Gitaly should switch to configuring using
+`config.toml`.
+
+**Planned removal milestone: 15.0 (2022-05-22)**
+
+### Elasticsearch 6.8
WARNING:
This feature will be changed or removed in 15.0
@@ -184,11 +250,15 @@ as a [breaking change](https://docs.gitlab.com/ee/development/contributing/#brea
Before updating GitLab, review the details carefully to determine if you need to make any
changes to your code, settings, or workflow.
-In GitLab 15.0, we will remove the feature that enables you to convert an instance (shared) runner to a project (specific) runner. Users who need to add a runner to only a particular project can register a runner to the project directly.
+Elasticsearch 6.8 is deprecated in GitLab 14.8 and scheduled for removal in GitLab 15.0.
+Customers using Elasticsearch 6.8 need to upgrade their Elasticsearch version to 7.x prior to upgrading to GitLab 15.0.
+We recommend using the latest version of Elasticsearch 7 to benefit from all Elasticsearch improvements.
+
+Elasticsearch 6.8 is also incompatible with Amazon OpenSearch, which we [plan to support in GitLab 15.0](https://gitlab.com/gitlab-org/gitlab/-/issues/327560).
**Planned removal milestone: 15.0 (2022-05-22)**
-### Known host required for GitLab Runner SSH executor
+### External status check API breaking changes
WARNING:
This feature will be changed or removed in 15.0
@@ -196,13 +266,25 @@ as a [breaking change](https://docs.gitlab.com/ee/development/contributing/#brea
Before updating GitLab, review the details carefully to determine if you need to make any
changes to your code, settings, or workflow.
-In [GitLab 14.3](https://gitlab.com/gitlab-org/gitlab-runner/-/merge_requests/3074), we added a configuration setting in the GitLab Runner `config.toml` file. This setting, [`[runners.ssh.disable_strict_host_key_checking]`](https://docs.gitlab.com/runner/executors/ssh.html#security), controls whether or not to use strict host key checking with the SSH executor.
+The [external status check API](https://docs.gitlab.com/ee/api/status_checks.html) was originally implemented to
+support pass-by-default requests to mark a status check as passing. Pass-by-default requests are now deprecated.
+Specifically, the following are deprecated:
-In GitLab 15.0 and later, the default value for this configuration option will change from `true` to `false`. This means that strict host key checking will be enforced when using the GitLab Runner SSH executor.
+- Requests that do not contain the `status` field.
+- Requests that have the `status` field set to `approved`.
+
+Beginning in GitLab 15.0, status checks will only be updated to a passing state if the `status` field is both present
+and set to `pass`. Requests that:
+
+- Do not contain the `status` field will be rejected with a `422` error. For more information, see [the relevant issue](https://gitlab.com/gitlab-org/gitlab/-/issues/338827).
+- Contain any value other than `pass` will cause the status check to fail. For more information, see [the relevant issue](https://gitlab.com/gitlab-org/gitlab/-/issues/339039).
+
+To align with this change, API calls to list external status checks will also return the value of `pass` rather than
+`approved` for status checks that have passed.
**Planned removal milestone: 15.0 (2022-05-22)**
-### Must explicitly assign `AuthenticationType` for `[runners.cache.s3]`
+### GraphQL ID and GlobalID compatibility
WARNING:
This feature will be changed or removed in 15.0
@@ -210,13 +292,61 @@ as a [breaking change](https://docs.gitlab.com/ee/development/contributing/#brea
Before updating GitLab, review the details carefully to determine if you need to make any
changes to your code, settings, or workflow.
-In GitLab 15.0 and later, to access the AWS S3 cache, you must specify the `AuthenticationType` for [`[runners.cache.s3]`](https://docs.gitlab.com/runner/configuration/advanced-configuration.html#the-runnerscaches3-section). The `AuthenticationType` must be `IAM` or `credentials`.
+We are removing a non-standard extension to our GraphQL processor, which we added for backwards compatibility. This extension modifies the validation of GraphQL queries, allowing the use of the `ID` type for arguments where it would normally be rejected.
+Some arguments originally had the type `ID`. These were changed to specific
+kinds of `ID`. This change may be a breaking change if you:
-Prior to 14.5, if you did not define the `AuthenticationType`, GitLab Runner chose a type for you.
+- Use GraphQL.
+- Use the `ID` type for any argument in your query signatures.
-**Planned removal milestone: 15.0 (2022-05-22)**
+Some field arguments still have the `ID` type. These are typically for
+IID values, or namespace paths. An example is `Query.project(fullPath: ID!)`.
-### Package pipelines in API payload is paginated
+For a list of affected and unaffected field arguments,
+see the [deprecation issue](https://gitlab.com/gitlab-org/gitlab/-/issues/352832).
+
+You can test if this change affects you by validating
+your queries locally, using schema data fetched from a GitLab server.
+You can do this by using the GraphQL explorer tool for the relevant GitLab
+instance. For example: `https://gitlab.com/-/graphql-explorer`.
+
+For example, the following query illustrates the breaking change:
+
+```graphql
+# a query using the deprecated type of Query.issue(id:)
+# WARNING: This will not work after GitLab 15.0
+query($id: ID!) {
+ deprecated: issue(id: $id) {
+ title, description
+ }
+}
+```
+
+The query above will not work after GitLab 15.0 is released, because the type
+of `Query.issue(id:)` is actually `IssueID!`.
+
+Instead, you should use one of the following two forms:
+
+```graphql
+# This will continue to work
+query($id: IssueID!) {
+ a: issue(id: $id) {
+ title, description
+ }
+ b: issue(id: "gid://gitlab/Issue/12345") {
+ title, description
+ }
+}
+```
+
+This query works now, and will continue to work after GitLab 15.0.
+You should convert any queries in the first form (using `ID` as a named type in the signature)
+to one of the other two forms (using the correct appropriate type in the signature, or using
+an inline argument expression).
+
+**Planned removal milestone: 15.0 (2022-04-22)**
+
+### OAuth tokens without expiration
WARNING:
This feature will be changed or removed in 15.0
@@ -224,13 +354,19 @@ as a [breaking change](https://docs.gitlab.com/ee/development/contributing/#brea
Before updating GitLab, review the details carefully to determine if you need to make any
changes to your code, settings, or workflow.
-A request to the API for `/api/v4/projects/:id/packages` returns a paginated result of packages. Each package lists all of its pipelines in this response. This is a performance concern, as it's possible for a package to have hundreds or thousands of associated pipelines.
+By default, all new applications expire access tokens after 2 hours. In GitLab 14.2 and earlier, OAuth access tokens
+had no expiration. In GitLab 15.0, an expiry will be automatically generated for any existing token that does not
+already have one.
-In milestone 15.0, we will remove the `pipelines` attribute from the API response.
+You should [opt in](https://docs.gitlab.com/ee/integration/oauth_provider.html#expiring-access-tokens) to expiring
+tokens before GitLab 15.0 is released:
+
+1. Edit the application.
+1. Select **Expire access tokens** to enable them. Tokens must be revoked or they don’t expire.
**Planned removal milestone: 15.0 (2022-05-22)**
-### REST and GraphQL API Runner status will not return `paused`
+### Optional enforcement of PAT expiration
WARNING:
This feature will be changed or removed in 15.0
@@ -238,17 +374,13 @@ as a [breaking change](https://docs.gitlab.com/ee/development/contributing/#brea
Before updating GitLab, review the details carefully to determine if you need to make any
changes to your code, settings, or workflow.
-The GitLab Runner REST and GraphQL API endpoints will not return `paused` or `active` as a status in GitLab 15.0.
-
-A runner's status will only relate to runner contact status, such as:
-`online`, `offline`, or `not_connected`. Status `paused` or `active` will no longer appear.
-
-When checking if a runner is `paused`, API users are advised to check the boolean attribute
-`paused` to be `true` instead. When checking if a runner is `active`, check if `paused` is `false`.
+The feature to disable enforcement of PAT expiration is unusual from a security perspective.
+We have become concerned that this unusual feature could create unexpected behavior for users.
+Unexpected behavior in a security feature is inherently dangerous, so we have decided to remove this feature.
**Planned removal milestone: 15.0 (2022-05-22)**
-### Support for SLES 12 SP2
+### Optional enforcement of SSH expiration
WARNING:
This feature will be changed or removed in 15.0
@@ -256,11 +388,13 @@ as a [breaking change](https://docs.gitlab.com/ee/development/contributing/#brea
Before updating GitLab, review the details carefully to determine if you need to make any
changes to your code, settings, or workflow.
-Long term service and support (LTSS) for SUSE Linux Enterprise Server (SLES) 12 SP2 [ended on March 31, 2021](https://www.suse.com/lifecycle/). The CA certificates on SP2 include the expired DST root certificate, and it's not getting new CA certificate package updates. We have implemented some [workarounds](https://gitlab.com/gitlab-org/gitlab-omnibus-builder/-/merge_requests/191), but we will not be able to continue to keep the build running properly.
+The feature to disable enforcement of SSH expiration is unusual from a security perspective.
+We have become concerned that this unusual feature could create unexpected behavior for users.
+Unexpected behavior in a security feature is inherently dangerous, so we have decided to remove this feature.
**Planned removal milestone: 15.0 (2022-05-22)**
-### Update to the Container Registry group-level API
+### Out-of-the-box SAST support for Java 8
WARNING:
This feature will be changed or removed in 15.0
@@ -268,13 +402,22 @@ as a [breaking change](https://docs.gitlab.com/ee/development/contributing/#brea
Before updating GitLab, review the details carefully to determine if you need to make any
changes to your code, settings, or workflow.
-In milestone 15.0, support for the `tags` and `tags_count` parameters will be removed from the Container Registry API that [gets registry repositories from a group](../api/container_registry.md#within-a-group).
+The [GitLab SAST SpotBugs analyzer](https://gitlab.com/gitlab-org/security-products/analyzers/spotbugs) scans [Java, Scala, Groovy, and Kotlin code](https://docs.gitlab.com/ee/user/application_security/sast/#supported-languages-and-frameworks) for security vulnerabilities.
+For technical reasons, the analyzer must first compile the code before scanning.
+Unless you use the [pre-compilation strategy](https://docs.gitlab.com/ee/user/application_security/sast/#pre-compilation), the analyzer attempts to automatically compile your project's code.
-The `GET /groups/:id/registry/repositories` endpoint will remain, but won't return any info about tags. To get the info about tags, you can use the existing `GET /registry/repositories/:id` endpoint, which will continue to support the `tags` and `tag_count` options as it does today. The latter must be called once per image repository.
+In GitLab versions prior to 15.0, the analyzer image includes Java 8 and Java 11 runtimes to facilitate compilation.
+
+In GitLab 15.0, we will:
+
+- Remove Java 8 from the analyzer image to reduce the size of the image.
+- Add Java 17 to the analyzer image to make it easier to compile with Java 17.
+
+If you rely on Java 8 being present in the analyzer environment, you must take action as detailed in the [deprecation issue for this change](https://gitlab.com/gitlab-org/gitlab/-/issues/352549#breaking-change).
**Planned removal milestone: 15.0 (2022-05-22)**
-### Value Stream Analytics filtering calculation change
+### Querying Usage Trends via the `instanceStatisticsMeasurements` GraphQL node
WARNING:
This feature will be changed or removed in 15.0
@@ -282,13 +425,71 @@ as a [breaking change](https://docs.gitlab.com/ee/development/contributing/#brea
Before updating GitLab, review the details carefully to determine if you need to make any
changes to your code, settings, or workflow.
-We are changing how the date filter works in Value Stream Analytics. Instead of filtering by the time that the issue or merge request was created, the date filter will filter by the end event time of the given stage. This will result in completely different figures after this change has rolled out.
-
-If you monitor Value Stream Analytics metrics and rely on the date filter, to avoid losing data, you must save the data prior to this change.
+The `instanceStatisticsMeasurements` GraphQL node has been renamed to `usageTrendsMeasurements` in 13.10 and the old field name has been marked as deprecated. To fix the existing GraphQL queries, replace `instanceStatisticsMeasurements` with `usageTrendsMeasurements`.
**Planned removal milestone: 15.0 (2022-05-22)**
-### `Versions` on base `PackageType`
+### REST API Runner will not accept `status` filter values of `active` or `paused`
+
+WARNING:
+This feature will be changed or removed in 16.0
+as a [breaking change](https://docs.gitlab.com/ee/development/contributing/#breaking-changes).
+Before updating GitLab, review the details carefully to determine if you need to make any
+changes to your code, settings, or workflow.
+
+The GitLab Runner REST endpoints will stop accepting `paused` or `active` as a status value in GitLab 16.0.
+
+A runner's status will only relate to runner contact status, such as: `online`, `offline`.
+Status values `paused` or `active` will no longer be accepted and will be replaced by the `paused` query parameter.
+
+When checking for paused runners, API users are advised to specify `paused=true` as the query parameter.
+When checking for active runners, specify `paused=false`.
+
+**Planned removal milestone: 16.0 (2023-04-22)**
+
+### REST API endpoint to list group runners no longer accepts `project_type` value for `type` argument
+
+WARNING:
+This feature will be changed or removed in 16.0
+as a [breaking change](https://docs.gitlab.com/ee/development/contributing/#breaking-changes).
+Before updating GitLab, review the details carefully to determine if you need to make any
+changes to your code, settings, or workflow.
+
+The `GET /groups/:id/runners?type=project_type` endpoint will be removed in GitLab 16.0. The endpoint always returned an empty collection.
+
+**Planned removal milestone: 16.0 (2023-04-22)**
+
+### REST and GraphQL API Runner usage of `active` replaced by `paused`
+
+WARNING:
+This feature will be changed or removed in 16.0
+as a [breaking change](https://docs.gitlab.com/ee/development/contributing/#breaking-changes).
+Before updating GitLab, review the details carefully to determine if you need to make any
+changes to your code, settings, or workflow.
+
+Occurrences of the `active` identifier in the GitLab Runner REST and GraphQL API endpoints will be
+renamed to `paused` in GitLab 16.0, namely:
+
+- GraphQL API:
+ - the `CiRunner` property;
+ - the `RunnerUpdateInput` input type for the `runnerUpdate` mutation;
+ - the `runners` and `Group.runners` queries.
+- REST API:
+ - endpoints taking or returning `active` properties, such as:
+ - `GET /runners`
+ - `GET /runners/all`
+ - `GET /runners/:id` / `PUT /runners/:id`
+ - `PUT --form "active=false" /runners/:runner_id`
+ - `GET /projects/:id/runners` / `POST /projects/:id/runners`
+ - `GET /groups/:id/runners`
+
+The 16.0 release of the GitLab Runner will start using the `paused` property when registering runners, and therefore
+will only be compatible with GitLab 16.0 and later. Until 16.0, GitLab will accept the deprecated `active` flag from
+existing runners.
+
+**Planned removal milestone: 16.0 (2023-04-22)**
+
+### Reminder: support for NFS repository storage
WARNING:
This feature will be changed or removed in 15.0
@@ -296,13 +497,22 @@ as a [breaking change](https://docs.gitlab.com/ee/development/contributing/#brea
Before updating GitLab, review the details carefully to determine if you need to make any
changes to your code, settings, or workflow.
-As part of the work to create a [Package Registry GraphQL API](https://gitlab.com/groups/gitlab-org/-/epics/6318), the Package group deprecated the `Version` type for the basic `PackageType` type and moved it to [`PackageDetailsType`](https://docs.gitlab.com/ee/api/graphql/reference/index.html#packagedetailstype).
+As [announced](https://about.gitlab.com/releases/2021/06/22/gitlab-14-0-released/#nfs-for-git-repository-storage-deprecated) at the
+release of GitLab 14.0, technical support for NFS storage for Git repositories is being removed. Please see our official
+[Statement of Support](https://about.gitlab.com/support/statement-of-support.html#gitaly-and-nfs) for additional information.
-In milestone 15.0, we will completely remove `Version` from `PackageType`.
+We encourage customers currently using NFS for Git repositories to plan their migration by reviewing our documentation on
+[migrating to Gitaly Cluster](https://docs.gitlab.com/ee/administration/gitaly/#migrating-to-gitaly-cluster).
+
+Gitaly Cluster offers tremendous benefits for our customers such as:
+
+- [Variable replication factors](https://docs.gitlab.com/ee/administration/gitaly/praefect.html#configure-replication-factor)
+- [Strong consistency](https://docs.gitlab.com/ee/administration/gitaly/#strong-consistency)
+- [Distributed read capabilities](https://docs.gitlab.com/ee/administration/gitaly/#distributed-reads)
**Planned removal milestone: 15.0 (2022-05-22)**
-### `defaultMergeCommitMessageWithDescription` GraphQL API field
+### Request profiling
WARNING:
This feature will be changed or removed in 15.0
@@ -310,11 +520,17 @@ as a [breaking change](https://docs.gitlab.com/ee/development/contributing/#brea
Before updating GitLab, review the details carefully to determine if you need to make any
changes to your code, settings, or workflow.
-The GraphQL API field `defaultMergeCommitMessageWithDescription` has been deprecated and will be removed in GitLab 15.0. For projects with a commit message template set, it will ignore the template.
+[Request profiling](https://docs.gitlab.com/ee/administration/monitoring/performance/request_profiling.html) is deprecated in GitLab 14.8 and scheduled for removal in GitLab 15.0.
+
+We're working on [consolidating our profiling tools](https://gitlab.com/groups/gitlab-org/-/epics/7327) and making them more easily accessible.
+We [evaluated](https://gitlab.com/gitlab-org/gitlab/-/issues/350152) the use of this feature and we found that it is not widely used.
+It also depends on a few third-party gems that are not actively maintained anymore, have not been updated for the latest version of Ruby, or crash frequently when profiling heavy page loads.
+
+For more information, check the [summary section of the deprecation issue](https://gitlab.com/gitlab-org/gitlab/-/issues/352488#deprecation-summary).
**Planned removal milestone: 15.0 (2022-05-22)**
-### `dependency_proxy_for_private_groups` feature flag
+### Required pipeline configurations in Premium tier
WARNING:
This feature will be changed or removed in 15.0
@@ -322,13 +538,16 @@ as a [breaking change](https://docs.gitlab.com/ee/development/contributing/#brea
Before updating GitLab, review the details carefully to determine if you need to make any
changes to your code, settings, or workflow.
-We added a feature flag because [GitLab-#11582](https://gitlab.com/gitlab-org/gitlab/-/issues/11582) changed how public groups use the Dependency Proxy. Prior to this change, you could use the Dependency Proxy without authentication. The change requires authentication to use the Dependency Proxy.
+The [required pipeline configuration](https://docs.gitlab.com/ee/user/admin_area/settings/continuous_integration.html#required-pipeline-configuration) feature is deprecated in GitLab 14.8 for Premium customers and is scheduled for removal in GitLab 15.0. This feature is not deprecated for GitLab Ultimate customers.
-In milestone 15.0, we will remove the feature flag entirely. Moving forward, you must authenticate when using the Dependency Proxy.
+This change to move the feature to GitLab's Ultimate tier is intended to help our features better align with our [pricing philosophy](https://about.gitlab.com/company/pricing/#three-tiers) as we see demand for this feature originating primarily from executives.
+
+This change will also help GitLab remain consistent in its tiering strategy with the other related Ultimate-tier features of:
+[Security policies](https://docs.gitlab.com/ee/user/application_security/policies/) and [compliance framework pipelines](https://docs.gitlab.com/ee/user/project/settings/index.html#compliance-pipeline-configuration).
**Planned removal milestone: 15.0 (2022-05-22)**
-### `pipelines` field from the `version` field
+### Retire-JS Dependency Scanning tool
WARNING:
This feature will be changed or removed in 15.0
@@ -336,16 +555,13 @@ as a [breaking change](https://docs.gitlab.com/ee/development/contributing/#brea
Before updating GitLab, review the details carefully to determine if you need to make any
changes to your code, settings, or workflow.
-In GraphQL, there are two `pipelines` fields that you can use in a [`PackageDetailsType`](https://docs.gitlab.com/ee/api/graphql/reference/#packagedetailstype) to get the pipelines for package versions:
-
-- The `versions` field's `pipelines` field. This returns all the pipelines associated with all the package's versions, which can pull an unbounded number of objects in memory and create performance concerns.
-- The `pipelines` field of a specific `version`. This returns only the pipelines associated with that single package version.
+As of 14.8 the retire.js job is being deprecated from Dependency Scanning. It will continue to be included in our CI/CD template while deprecated. We are removing retire.js from Dependency Scanning on May 22, 2022 in GitLab 15.0. JavaScript scanning functionality will not be affected as it is still being covered by Gemnasium.
-To mitigate possible performance problems, we will remove the `versions` field's `pipelines` field in milestone 15.0. Although you will no longer be able to get all pipelines for all versions of a package, you can still get the pipelines of a single version through the remaining `pipelines` field for that version.
+If you have explicitly excluded retire.js using DS_EXCLUDED_ANALYZERS you will need to clean up (remove the reference) in 15.0. If you have customized your pipeline's Dependency Scanning configuration related to the `retire-js-dependency_scanning` job you will want to switch to gemnasium-dependency_scanning before the removal in 15.0, to prevent your pipeline from failing. If you have not used the DS_EXCLUDED_ANALYZERS to reference retire.js, or customized your template specifically for retire.js, you will not need to take action.
**Planned removal milestone: 15.0 (2022-05-22)**
-### `promote-db` command from `gitlab-ctl`
+### SAST analyzer consolidation and CI/CD template changes
WARNING:
This feature will be changed or removed in 15.0
@@ -353,11 +569,30 @@ as a [breaking change](https://docs.gitlab.com/ee/development/contributing/#brea
Before updating GitLab, review the details carefully to determine if you need to make any
changes to your code, settings, or workflow.
-In GitLab 14.5, we introduced the command `gitlab-ctl promote` to promote any Geo secondary node to a primary during a failover. This command replaces `gitlab-ctl promote-db` which is used to promote database nodes in multi-node Geo secondary sites. `gitlab-ctl promote-db` will continue to function as-is and be available until GitLab 15.0. We recommend that Geo customers begin testing the new `gitlab-ctl promote` command in their staging environments and incorporating the new command in their failover procedures.
+GitLab SAST uses various [analyzers](https://docs.gitlab.com/ee/user/application_security/sast/analyzers/) to scan code for vulnerabilities.
+
+We are reducing the number of analyzers used in GitLab SAST as part of our long-term strategy to deliver a better and more consistent user experience.
+Streamlining the set of analyzers will also enable faster [iteration](https://about.gitlab.com/handbook/values/#iteration), better [results](https://about.gitlab.com/handbook/values/#results), and greater [efficiency](https://about.gitlab.com/handbook/values/#results) (including a reduction in CI runner usage in most cases).
+
+In GitLab 15.0, GitLab SAST will no longer use the following analyzers:
+
+- [ESLint](https://gitlab.com/gitlab-org/security-products/analyzers/eslint) (JavaScript, TypeScript, React)
+- [Gosec](https://gitlab.com/gitlab-org/security-products/analyzers/gosec) (Go)
+- [Bandit](https://gitlab.com/gitlab-org/security-products/analyzers/bandit) (Python)
+
+These analyzers will be removed from the [GitLab-managed SAST CI/CD template](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Security/SAST.gitlab-ci.yml) and replaced with the [Semgrep-based analyzer](https://gitlab.com/gitlab-org/security-products/analyzers/semgrep).
+They will no longer receive routine updates, except for security issues.
+We will not delete container images previously published for these analyzers; any such change would be announced as a [deprecation, removal, or breaking change announcement](https://about.gitlab.com/handbook/marketing/blog/release-posts/#deprecations-removals-and-breaking-changes).
+
+We will also remove Java from the scope of the [SpotBugs](https://gitlab.com/gitlab-org/security-products/analyzers/spotbugs) analyzer and replace it with the [Semgrep-based analyzer](https://gitlab.com/gitlab-org/security-products/analyzers/semgrep).
+This change will make it simpler to scan Java code; compilation will no longer be required.
+This change will be reflected in the automatic language detection portion of the [GitLab-managed SAST CI/CD template](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Security/SAST.gitlab-ci.yml).
+
+If you applied customizations to any of the affected analyzers, you must take action as detailed in the [deprecation issue for this change](https://gitlab.com/gitlab-org/gitlab/-/issues/352554#breaking-change).
**Planned removal milestone: 15.0 (2022-05-22)**
-### `promote-to-primary-node` command from `gitlab-ctl`
+### SAST support for .NET 2.1
WARNING:
This feature will be changed or removed in 15.0
@@ -365,21 +600,50 @@ as a [breaking change](https://docs.gitlab.com/ee/development/contributing/#brea
Before updating GitLab, review the details carefully to determine if you need to make any
changes to your code, settings, or workflow.
-In GitLab 14.5, we introduced the command `gitlab-ctl promote` to promote any Geo secondary node to a primary during a failover. This command replaces `gitlab-ctl promote-to-primary-node` which was only usable for single-node Geo sites. `gitlab-ctl promote-to-primary-node` will continue to function as-is and be available until GitLab 15.0. We recommend that Geo customers begin testing the new `gitlab-ctl promote` command in their staging environments and incorporating the new command in their failover procedures.
+The GitLab SAST Security Code Scan analyzer scans .NET code for security vulnerabilities.
+For technical reasons, the analyzer must first build the code to scan it.
+
+In GitLab versions prior to 15.0, the default analyzer image (version 2) includes support for:
+
+- .NET 2.1
+- .NET 3.0 and .NET Core 3.0
+- .NET Core 3.1
+- .NET 5.0
+
+In GitLab 15.0, we will change the default major version for this analyzer from version 2 to version 3. This change:
+
+- Adds [severity values for vulnerabilities](https://gitlab.com/gitlab-org/gitlab/-/issues/350408) along with [other new features and improvements](https://gitlab.com/gitlab-org/security-products/analyzers/security-code-scan/-/blob/master/CHANGELOG.md).
+- Removes .NET 2.1 support.
+- Adds support for .NET 6.0, Visual Studio 2019, and Visual Studio 2022.
+
+Version 3 was [announced in GitLab 14.6](https://about.gitlab.com/releases/2021/12/22/gitlab-14-6-released/#sast-support-for-net-6) and made available as an optional upgrade.
+
+If you rely on .NET 2.1 support being present in the analyzer image by default, you must take action as detailed in the [deprecation issue for this change](https://gitlab.com/gitlab-org/gitlab/-/issues/352553#breaking-change).
**Planned removal milestone: 15.0 (2022-05-22)**
-### openSUSE Leap 15.2 packages
+### Secret Detection configuration variables deprecated
-Distribution support and security updates for openSUSE Leap 15.2 are [ending December 2021](https://en.opensuse.org/Lifetime#openSUSE_Leap).
+To make it simpler and more reliable to [customize GitLab Secret Detection](https://docs.gitlab.com/ee/user/application_security/secret_detection/#customizing-settings), we're deprecating some of the variables that you could previously set in your CI/CD configuration.
-Starting in 14.5 we are providing packages for openSUSE Leap 15.3, and will stop providing packages for openSUSE Leap 15.2 in the 14.8 milestone.
+The following variables currently allow you to customize the options for historical scanning, but interact poorly with the [GitLab-managed CI/CD template](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Security/Secret-Detection.gitlab-ci.yml) and are now deprecated:
-**Planned removal milestone: 14.8 (2022-02-22)**
+- `SECRET_DETECTION_COMMIT_FROM`
+- `SECRET_DETECTION_COMMIT_TO`
+- `SECRET_DETECTION_COMMITS`
+- `SECRET_DETECTION_COMMITS_FILE`
-## 14.6
+The `SECRET_DETECTION_ENTROPY_LEVEL` previously allowed you to configure rules that only considered the entropy level of strings in your codebase, and is now deprecated.
+This type of entropy-only rule created an unacceptable number of incorrect results (false positives) and is no longer supported.
-### API: `stale` status returned instead of `offline` or `not_connected`
+In GitLab 15.0, we'll update the Secret Detection [analyzer](https://docs.gitlab.com/ee/user/application_security/terminology/#analyzer) to ignore these deprecated options.
+You'll still be able to configure historical scanning of your commit history by setting the [`SECRET_DETECTION_HISTORIC_SCAN` CI/CD variable](https://docs.gitlab.com/ee/user/application_security/secret_detection/#available-cicd-variables).
+
+For further details, see [the deprecation issue for this change](https://gitlab.com/gitlab-org/gitlab/-/issues/352565).
+
+**Planned removal milestone: 15.0 (2022-05-22)**
+
+### Secure and Protect analyzer images published in new location
WARNING:
This feature will be changed or removed in 15.0
@@ -387,13 +651,25 @@ as a [breaking change](https://docs.gitlab.com/ee/development/contributing/#brea
Before updating GitLab, review the details carefully to determine if you need to make any
changes to your code, settings, or workflow.
-A breaking change will occur for the Runner [API](https://docs.gitlab.com/ee/api/runners.html#runners-api) endpoints in 15.0.
+GitLab uses various [analyzers](https://docs.gitlab.com/ee/user/application_security/terminology/#analyzer) to [scan for security vulnerabilities](https://docs.gitlab.com/ee/user/application_security/).
+Each analyzer is distributed as a container image.
-Instead of the GitLab Runner API endpoints returning `offline` and `not_connected` for runners that have not contacted the GitLab instance in the past three months, the API endpoints will return the `stale` value, which was introduced in 14.6.
+Starting in GitLab 14.8, new versions of GitLab Secure and Protect analyzers are published to a new registry location under `registry.gitlab.com/security-products`.
+
+We will update the default value of [GitLab-managed CI/CD templates](https://gitlab.com/gitlab-org/gitlab/-/tree/master/lib/gitlab/ci/templates/Security) to reflect this change:
+
+- For all analyzers except Container Scanning, we will update the variable `SECURE_ANALYZERS_PREFIX` to the new image registry location.
+- For Container Scanning, the default image address is already updated. There is no `SECURE_ANALYZERS_PREFIX` variable for Container Scanning.
+
+In a future release, we will stop publishing images to `registry.gitlab.com/gitlab-org/security-products/analyzers`.
+Once this happens, you must take action if you manually pull images and push them into a separate registry. This is commonly the case for [offline deployments](https://docs.gitlab.com/ee/user/application_security/offline_deployments/index.html).
+Otherwise, you won't receive further updates.
+
+See the [deprecation issue](https://gitlab.com/gitlab-org/gitlab/-/issues/352564) for more details.
**Planned removal milestone: 15.0 (2022-05-22)**
-### CI/CD job name length limit
+### Secure and Protect analyzer major version update
WARNING:
This feature will be changed or removed in 15.0
@@ -401,11 +677,42 @@ as a [breaking change](https://docs.gitlab.com/ee/development/contributing/#brea
Before updating GitLab, review the details carefully to determine if you need to make any
changes to your code, settings, or workflow.
-In GitLab 15.0 we are going to limit the number of characters in CI/CD job names to 255. Any pipeline with job names that exceed the 255 character limit will stop working after the 15.0 release.
+The Secure and Protect stages will be bumping the major versions of their analyzers in tandem with the GitLab 15.0 release. This major bump will enable a clear delineation for analyzers, between:
+
+- Those released prior to May 22, 2022, which generate reports that _are not_ subject to stringent schema validation.
+- Those released after May 22, 2022, which generate reports that _are_ subject to stringent schema validation.
+
+If you are not using the default inclusion templates, or have pinned your analyzer version(s) you will need to update your CI/CD job definition to either remove the pinned version or to update the latest major version.
+Users of GitLab 12.0-14.10 will continue to experience analyzer updates as normal until the release of GitLab 15.0, following which all newly fixed bugs and newly released features in the new major versions of the analyzers will not be available in the deprecated versions because we do not backport bugs and new features as per our [maintenance policy](https://docs.gitlab.com/ee/policy/maintenance.html). As required security patches will be backported within the latest 3 minor releases.
+Specifically, the following are being deprecated and will no longer be updated after 15.0 GitLab release:
+
+- API Security: version 1
+- Container Scanning: version 4
+- Coverage-guided fuzz testing: version 2
+- Dependency Scanning: version 2
+- Dynamic Application Security Testing (DAST): version 2
+- Infrastructure as Code (IaC) Scanning: version 1
+- License Scanning: version 3
+- Secret Detection: version 3
+- Static Application Security Testing (SAST): version 2 of [all analyzers](https://docs.gitlab.com/ee/user/application_security/sast/#supported-languages-and-frameworks), except `gosec` which is currently at version 3
+ - `bandit`: version 2
+ - `brakeman`: version 2
+ - `eslint`: version 2
+ - `flawfinder`: version 2
+ - `gosec`: version 3
+ - `kubesec`: version 2
+ - `mobsf`: version 2
+ - `nodejs-scan`: version 2
+ - `phpcs-security-audit`: version 2
+ - `pmd-apex`: version 2
+ - `security-code-scan`: version 2
+ - `semgrep`: version 2
+ - `sobelow`: version 2
+ - `spotbugs`: version 2
**Planned removal milestone: 15.0 (2022-05-22)**
-### Legacy approval status names from License Compliance API
+### Support for gRPC-aware proxy deployed between Gitaly and rest of GitLab
WARNING:
This feature will be changed or removed in 15.0
@@ -413,13 +720,21 @@ as a [breaking change](https://docs.gitlab.com/ee/development/contributing/#brea
Before updating GitLab, review the details carefully to determine if you need to make any
changes to your code, settings, or workflow.
-We deprecated legacy names for approval status of license policy (blacklisted, approved) in the `managed_licenses` API but they are still used in our API queries and responses. They will be removed in 15.0.
+Although not recommended or documented, it was possible to deploy a gRPC-aware proxy between Gitaly and
+the rest of GitLab. For example, NGINX and Envoy. The ability to deploy a gRPC-aware proxy is
+[deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/352517). If you currently use a gRPC-aware proxy for
+Gitaly connections, you should change your proxy configuration to use TCP or TLS proxying (OSI layer 4) instead.
-If you are using our License Compliance API you should stop using the `approved` and `blacklisted` query parameters, they are now `allowed` and `denied`. In 15.0 the responses will also stop using `approved` and `blacklisted` so you need to adjust any of your custom tools to use the old and new values so they do not break with the 15.0 release.
+Gitaly Cluster became incompatible with gRPC-aware proxies in GitLab 13.12. Now all GitLab installations will be incompatible with
+gRPC-aware proxies, even without Gitaly Cluster.
+
+By sending some of our internal RPC traffic through a custom protocol (instead of gRPC) we
+increase throughput and reduce Go garbage collection latency. For more information, see
+the [relevant epic](https://gitlab.com/groups/gitlab-com/gl-infra/-/epics/463).
**Planned removal milestone: 15.0 (2022-05-22)**
-### Runner status `not_connected` API value
+### Test coverage project CI/CD setting
WARNING:
This feature will be changed or removed in 15.0
@@ -427,14 +742,16 @@ as a [breaking change](https://docs.gitlab.com/ee/development/contributing/#brea
Before updating GitLab, review the details carefully to determine if you need to make any
changes to your code, settings, or workflow.
-The GitLab Runner REST and GraphQL [API](https://docs.gitlab.com/ee/api/runners.html#runners-api) endpoints
-will return `never_contacted` instead of `not_connected` as the status values in 15.0.
+To simplify setting a test coverage pattern, in GitLab 15.0 the
+[project setting for test coverage parsing](https://docs.gitlab.com/ee/ci/pipelines/settings.html#add-test-coverage-results-using-project-settings-deprecated)
+is being removed.
-Runners that have never contacted the GitLab instance will also return `stale` if created more than 3 months ago.
+Instead, using the project’s `.gitlab-ci.yml`, provide a regular expression with the `coverage` keyword to set
+testing coverage results in merge requests.
**Planned removal milestone: 15.0 (2022-05-22)**
-### `pipelines` fields in the Package GraphQL types
+### Vulnerability Check
WARNING:
This feature will be changed or removed in 15.0
@@ -442,13 +759,18 @@ as a [breaking change](https://docs.gitlab.com/ee/development/contributing/#brea
Before updating GitLab, review the details carefully to determine if you need to make any
changes to your code, settings, or workflow.
-As part of the work to create a [Package Registry GraphQL API](https://gitlab.com/groups/gitlab-org/-/epics/6318), the Package group deprecated the `pipelines` fields in all Package-related GraphQL types. As of GitLab 14.6, the `pipelines` field is deprecated in [`Package`](https://docs.gitlab.com/ee/api/graphql/reference/index.html#package) and [`PackageDetailsType`](https://docs.gitlab.com/ee/api/graphql/reference/index.html#packagedetailstype) due to scalability and performance concerns.
+The vulnerability check feature is deprecated in GitLab 14.8 and scheduled for removal in GitLab 15.0. We encourage you to migrate to the new security approvals feature instead. You can do so by navigating to **Security & Compliance > Policies** and creating a new Scan Result Policy.
-In milestone 15.0, we will completely remove `pipelines` from `Package` and `PackageDetailsType`. You can follow and contribute to work on a replacement in the epic [GitLab-#7214](https://gitlab.com/groups/gitlab-org/-/epics/7214).
+The new security approvals feature is similar to vulnerability check. For example, both can require approvals for MRs that contain security vulnerabilities. However, security approvals improve the previous experience in several ways:
+
+- Users can choose who is allowed to edit security approval rules. An independent security or compliance team can therefore manage rules in a way that prevents development project maintainers from modifying the rules.
+- Multiple rules can be created and chained together to allow for filtering on different severity thresholds for each scanner type.
+- A two-step approval process can be enforced for any desired changes to security approval rules.
+- A single set of security policies can be applied to multiple development projects to allow for ease in maintaining a single, centralized ruleset.
**Planned removal milestone: 15.0 (2022-05-22)**
-### `type` and `types` keyword in CI/CD configuration
+### `CI_BUILD_*` predefined variables
WARNING:
This feature will be changed or removed in 15.0
@@ -456,11 +778,23 @@ as a [breaking change](https://docs.gitlab.com/ee/development/contributing/#brea
Before updating GitLab, review the details carefully to determine if you need to make any
changes to your code, settings, or workflow.
-The `type` and `types` CI/CD keywords will be removed in GitLab 15.0. Pipelines that use these keywords will stop working, so you must switch to `stage` and `stages`, which have the same behavior.
+The predefined CI/CD variables that start with `CI_BUILD_*` were deprecated in GitLab 9.0, and will be removed in GitLab 15.0. If you still use these variables, be sure to change to the current [`CI_JOB_*` predefined variables](https://docs.gitlab.com/ee/ci/variables/predefined_variables.html) which are identical (except for the updated name).
**Planned removal milestone: 15.0 (2022-05-22)**
-### apiFuzzingCiConfigurationCreate GraphQL mutation
+### `fixup!` commit messages setting draft status of associated Merge Request
+
+The use of `fixup!` as a commit message to trigger draft status
+of the associated Merge Request is generally unused, and can cause
+confusion with other uses of the term. "Draft" is the preferred
+and supported trigger for triggering draft status from commit
+messages, as part of our streamlining of the feature.
+Support for `fixup!` is now considered deprecated, and will be
+removed in GitLab 15.0.
+
+**Planned removal milestone: 15.0 (2022-06-22)**
+
+### `projectFingerprint` in `PipelineSecurityReportFinding` GraphQL
WARNING:
This feature will be changed or removed in 15.0
@@ -468,13 +802,14 @@ as a [breaking change](https://docs.gitlab.com/ee/development/contributing/#brea
Before updating GitLab, review the details carefully to determine if you need to make any
changes to your code, settings, or workflow.
-The API Fuzzing configuration snippet is now being generated client-side and does not require an
-API request anymore. We are therefore deprecating the `apiFuzzingCiConfigurationCreate` mutation
-which isn't being used in GitLab anymore.
+The `projectFingerprint` field in the [PipelineSecurityReportFinding](https://docs.gitlab.com/ee/api/graphql/reference/index.html#pipelinesecurityreportfinding)
+GraphQL object is being deprecated. This field contains a "fingerprint" of security findings used to determine uniqueness.
+The method for calculating fingerprints has changed, resulting in different values. Going forward, the new values will be
+exposed in the UUID field. Data previously available in the projectFingerprint field will eventually be removed entirely.
**Planned removal milestone: 15.0 (2022-05-22)**
-### bundler-audit Dependency Scanning tool
+### `started` iterations API field
WARNING:
This feature will be changed or removed in 15.0
@@ -482,9 +817,7 @@ as a [breaking change](https://docs.gitlab.com/ee/development/contributing/#brea
Before updating GitLab, review the details carefully to determine if you need to make any
changes to your code, settings, or workflow.
-As of 14.6 bundler-audit is being deprecated from Dependency Scanning. It will continue to be in our CI/CD template while deprecated. We are removing bundler-audit from Dependency Scanning on May 22, 2022 in 15.0. After this removal Ruby scanning functionality will not be affected as it is still being covered by Gemnasium.
-
-If you have explicitly excluded bundler-audit using DS_EXCLUDED_ANALYZERS you will need to clean up (remove the reference) in 15.0. If you have customized your pipeline's Dependency Scanning configuration, for example to edit the `bundler-audit-dependency_scanning` job, you will want to switch to gemnasium-dependency_scanning before removal in 15.0, to prevent your pipeline from failing. If you have not used the DS_EXCLUDED_ANALYZERS to reference bundler-audit, or customized your template specifically for bundler-audit, you will not need to take action.
+The `started` field in the [iterations API](https://docs.gitlab.com/ee/api/iterations.html#list-project-iterations) is being deprecated and will be removed in GitLab 15.0. This field is being replaced with the `current` field (already available) which aligns with the naming for other time-based entities, such as milestones.
**Planned removal milestone: 15.0 (2022-05-22)**
@@ -725,9 +1058,9 @@ The `merged_by` field in the [merge request API](https://docs.gitlab.com/ee/api/
**Planned removal milestone: 15.0 (2022-05-22)**
-## 14.8
+## 14.6
-### Changes to the `CI_JOB_JWT`
+### API: `stale` status returned instead of `offline` or `not_connected`
WARNING:
This feature will be changed or removed in 15.0
@@ -735,20 +1068,13 @@ as a [breaking change](https://docs.gitlab.com/ee/development/contributing/#brea
Before updating GitLab, review the details carefully to determine if you need to make any
changes to your code, settings, or workflow.
-The `CI_JOB_JWT` will be updated to support a wider variety of cloud providers. It will be changed to match [`CI_JOB_JWT_V2`](https://docs.gitlab.com/ee/ci/variables/predefined_variables.html), but this change may not be backwards compatible for all users, including Hashicorp Vault users. To maintain the current behavior, users can switch to using `CI_JOB_JWT_V1`, or update their configuration in GitLab 15.0 to use the improved `CI_JOB_JWT`.
-
-**Planned removal milestone: 15.0 ()**
-
-### Configurable Gitaly `per_repository` election strategy
-
-Configuring the `per_repository` Gitaly election strategy is [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/352612).
-`per_repository` has been the only option since GitLab 14.0.
+A breaking change will occur for the Runner [API](https://docs.gitlab.com/ee/api/runners.html#runners-api) endpoints in 15.0.
-This change is part of regular maintenance to keep our codebase clean.
+Instead of the GitLab Runner API endpoints returning `offline` and `not_connected` for runners that have not contacted the GitLab instance in the past three months, the API endpoints will return the `stale` value, which was introduced in 14.6.
-**Planned removal milestone: 14.9 (2022-03-22)**
+**Planned removal milestone: 15.0 (2022-05-22)**
-### Container Network and Host Security
+### CI/CD job name length limit
WARNING:
This feature will be changed or removed in 15.0
@@ -756,20 +1082,11 @@ as a [breaking change](https://docs.gitlab.com/ee/development/contributing/#brea
Before updating GitLab, review the details carefully to determine if you need to make any
changes to your code, settings, or workflow.
-All functionality related to GitLab's Container Network Security and Container Host Security categories is deprecated in GitLab 14.8 and scheduled for removal in GitLab 15.0. Users who need a replacement for this functionality are encouraged to evaluate the following open source projects as potential solutions that can be installed and managed outside of GitLab: [AppArmor](https://gitlab.com/apparmor/apparmor), [Cilium](https://github.com/cilium/cilium), [Falco](https://github.com/falcosecurity/falco), [FluentD](https://github.com/fluent/fluentd), [Pod Security Admission](https://kubernetes.io/docs/concepts/security/pod-security-admission/). To integrate these technologies into GitLab, add the desired Helm charts into your copy of the [Cluster Management Project Template](https://docs.gitlab.com/ee/user/clusters/management_project_template.html). Deploy these Helm charts in production by calling commands through the GitLab [Secure CI/CD Tunnel](https://docs.gitlab.com/ee/user/clusters/agent/repository.html#run-kubectl-commands-using-the-cicd-tunnel).
-
-As part of this change, the following specific capabilities within GitLab are now deprecated, and are scheduled for removal in GitLab 15.0:
-
-- The **Security & Compliance > Threat Monitoring** page.
-- The `Network Policy` security policy type, as found on the **Security & Compliance > Policies** page.
-- The ability to manage integrations with the following technologies through GitLab: AppArmor, Cilium, Falco, FluentD, and Pod Security Policies.
-- All APIs related to the above functionality.
-
-For additional context, or to provide feedback regarding this change, please reference our open [deprecation issue](https://gitlab.com/groups/gitlab-org/-/epics/7476).
+In GitLab 15.0 we are going to limit the number of characters in CI/CD job names to 255. Any pipeline with job names that exceed the 255 character limit will stop working after the 15.0 release.
**Planned removal milestone: 15.0 (2022-05-22)**
-### Dependency Scanning Python 3.9 and 3.6 image deprecation
+### Legacy approval status names from License Compliance API
WARNING:
This feature will be changed or removed in 15.0
@@ -777,60 +1094,13 @@ as a [breaking change](https://docs.gitlab.com/ee/development/contributing/#brea
Before updating GitLab, review the details carefully to determine if you need to make any
changes to your code, settings, or workflow.
-For those using Dependency Scanning for Python projects, we are deprecating the default `gemnasium-python:2` image which uses Python 3.6 as well as the custom `gemnasium-python:2-python-3.9` image which uses Python 3.9. The new default image as of GitLab 15.0 will be for Python 3.9 as it is a [supported version](https://endoflife.date/python) and 3.6 [is no longer supported](https://endoflife.date/python).
-
-For users using Python 3.9 or 3.9-compatible projects, you should not need to take action and dependency scanning should begin to work in GitLab 15.0. If you wish to test the new container now please run a test pipeline in your project with this container (which will be removed in 15.0). Use the Python 3.9 image:
-
-```yaml
-gemnasium-python-dependency_scanning:
- image:
- name: registry.gitlab.com/gitlab-org/security-products/analyzers/gemnasium-python:2-python-3.9
-```
-
-For users using Python 3.6, as of GitLab 15.0 you will no longer be able to use the default template for dependency scanning. You will need to switch to use the deprecated `gemnasium-python:2` analyzer image. If you are impacted by this please comment in [this issue](https://gitlab.com/gitlab-org/gitlab/-/issues/351503) so we can extend the removal if needed.
-
-For users using the 3.9 special exception image, you must instead use the default value and no longer override your container. To verify if you are using the 3.9 special exception image, check your `.gitlab-ci.yml` file for the following reference:
-
-```yaml
-gemnasium-python-dependency_scanning:
- image:
- name: registry.gitlab.com/gitlab-org/security-products/analyzers/gemnasium-python:2-python-3.9
-```
-
-**Planned removal milestone: 15.0 (2021-05-22)**
-
-### Deprecate Geo Admin UI Routes
-
-In GitLab 13.0, we introduced new project and design replication details routes in the Geo Admin UI. These routes are `/admin/geo/replication/projects` and `/admin/geo/replication/designs`. We kept the legacy routes and redirected them to the new routes. In GitLab 15.0, we will remove support for the legacy routes `/admin/geo/projects` and `/admin/geo/designs`. Please update any bookmarks or scripts that may use the legacy routes.
-
-**Planned removal milestone: 15.0 (2022-05-22)**
-
-### Deprecate custom Geo:db:* Rake tasks
-
-In GitLab 14.8, we are [replacing the `geo:db:*` Rake tasks with built-in tasks](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/77269/diffs) that are now possible after [switching the Geo tracking database to use Rails' 6 support of multiple databases](https://gitlab.com/groups/gitlab-org/-/epics/6458).
-The following `geo:db:*` tasks will be replaced with their corresponding `db:*:geo` tasks:
+We deprecated legacy names for approval status of license policy (blacklisted, approved) in the `managed_licenses` API but they are still used in our API queries and responses. They will be removed in 15.0.
-- `geo:db:drop` -> `db:drop:geo`
-- `geo:db:create` -> `db:create:geo`
-- `geo:db:setup` -> `db:setup:geo`
-- `geo:db:migrate` -> `db:migrate:geo`
-- `geo:db:rollback` -> `db:rollback:geo`
-- `geo:db:version` -> `db:version:geo`
-- `geo:db:reset` -> `db:reset:geo`
-- `geo:db:seed` -> `db:seed:geo`
-- `geo:schema:load:geo` -> `db:schema:load:geo`
-- `geo:db:schema:dump` -> `db:schema:dump:geo`
-- `geo:db:migrate:up` -> `db:migrate:up:geo`
-- `geo:db:migrate:down` -> `db:migrate:down:geo`
-- `geo:db:migrate:redo` -> `db:migrate:redo:geo`
-- `geo:db:migrate:status` -> `db:migrate:status:geo`
-- `geo:db:test:prepare` -> `db:test:prepare:geo`
-- `geo:db:test:load` -> `db:test:load:geo`
-- `geo:db:test:purge` -> `db:test:purge:geo`
+If you are using our License Compliance API you should stop using the `approved` and `blacklisted` query parameters, they are now `allowed` and `denied`. In 15.0 the responses will also stop using `approved` and `blacklisted` so you need to adjust any of your custom tools to use the old and new values so they do not break with the 15.0 release.
**Planned removal milestone: 15.0 (2022-05-22)**
-### Deprecate feature flag PUSH_RULES_SUPERSEDE_CODE_OWNERS
+### Runner status `not_connected` API value
WARNING:
This feature will be changed or removed in 15.0
@@ -838,11 +1108,14 @@ as a [breaking change](https://docs.gitlab.com/ee/development/contributing/#brea
Before updating GitLab, review the details carefully to determine if you need to make any
changes to your code, settings, or workflow.
-The feature flag `PUSH_RULES_SUPERSEDE_CODE_OWNERS` is being removed in GitLab 15.0. Upon its removal, push rules will supersede CODEOWNERS. The CODEOWNERS feature will no longer be available for access control.
+The GitLab Runner REST and GraphQL [API](https://docs.gitlab.com/ee/api/runners.html#runners-api) endpoints
+will return `never_contacted` instead of `not_connected` as the status values in 15.0.
+
+Runners that have never contacted the GitLab instance will also return `stale` if created more than 3 months ago.
**Planned removal milestone: 15.0 (2022-05-22)**
-### Deprecate legacy Gitaly configuration methods
+### `pipelines` fields in the Package GraphQL types
WARNING:
This feature will be changed or removed in 15.0
@@ -850,15 +1123,13 @@ as a [breaking change](https://docs.gitlab.com/ee/development/contributing/#brea
Before updating GitLab, review the details carefully to determine if you need to make any
changes to your code, settings, or workflow.
-Using environment variables `GIT_CONFIG_SYSTEM` and `GIT_CONFIG_GLOBAL` to configure Gitaly is [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/352609).
-These variables are being replaced with standard [`config.toml` Gitaly configuration](https://docs.gitlab.com/ee/administration/gitaly/reference.html).
+As part of the work to create a [Package Registry GraphQL API](https://gitlab.com/groups/gitlab-org/-/epics/6318), the Package group deprecated the `pipelines` fields in all Package-related GraphQL types. As of GitLab 14.6, the `pipelines` field is deprecated in [`Package`](https://docs.gitlab.com/ee/api/graphql/reference/index.html#package) and [`PackageDetailsType`](https://docs.gitlab.com/ee/api/graphql/reference/index.html#packagedetailstype) due to scalability and performance concerns.
-GitLab instances that use `GIT_CONFIG_SYSTEM` and `GIT_CONFIG_GLOBAL` to configure Gitaly should switch to configuring using
-`config.toml`.
+In milestone 15.0, we will completely remove `pipelines` from `Package` and `PackageDetailsType`. You can follow and contribute to work on a replacement in the epic [GitLab-#7214](https://gitlab.com/groups/gitlab-org/-/epics/7214).
**Planned removal milestone: 15.0 (2022-05-22)**
-### Elasticsearch 6.8
+### `type` and `types` keyword in CI/CD configuration
WARNING:
This feature will be changed or removed in 15.0
@@ -866,15 +1137,11 @@ as a [breaking change](https://docs.gitlab.com/ee/development/contributing/#brea
Before updating GitLab, review the details carefully to determine if you need to make any
changes to your code, settings, or workflow.
-Elasticsearch 6.8 is deprecated in GitLab 14.8 and scheduled for removal in GitLab 15.0.
-Customers using Elasticsearch 6.8 need to upgrade their Elasticsearch version to 7.x prior to upgrading to GitLab 15.0.
-We recommend using the latest version of Elasticsearch 7 to benefit from all Elasticsearch improvements.
-
-Elasticsearch 6.8 is also incompatible with Amazon OpenSearch, which we [plan to support in GitLab 15.0](https://gitlab.com/gitlab-org/gitlab/-/issues/327560).
+The `type` and `types` CI/CD keywords will be removed in GitLab 15.0. Pipelines that use these keywords will stop working, so you must switch to `stage` and `stages`, which have the same behavior.
**Planned removal milestone: 15.0 (2022-05-22)**
-### External status check API breaking changes
+### apiFuzzingCiConfigurationCreate GraphQL mutation
WARNING:
This feature will be changed or removed in 15.0
@@ -882,25 +1149,13 @@ as a [breaking change](https://docs.gitlab.com/ee/development/contributing/#brea
Before updating GitLab, review the details carefully to determine if you need to make any
changes to your code, settings, or workflow.
-The [external status check API](https://docs.gitlab.com/ee/api/status_checks.html) was originally implemented to
-support pass-by-default requests to mark a status check as passing. Pass-by-default requests are now deprecated.
-Specifically, the following are deprecated:
-
-- Requests that do not contain the `status` field.
-- Requests that have the `status` field set to `approved`.
-
-Beginning in GitLab 15.0, status checks will only be updated to a passing state if the `status` field is both present
-and set to `pass`. Requests that:
-
-- Do not contain the `status` field will be rejected with a `422` error. For more information, see [the relevant issue](https://gitlab.com/gitlab-org/gitlab/-/issues/338827).
-- Contain any value other than `pass` will cause the status check to fail. For more information, see [the relevant issue](https://gitlab.com/gitlab-org/gitlab/-/issues/339039).
-
-To align with this change, API calls to list external status checks will also return the value of `pass` rather than
-`approved` for status checks that have passed.
+The API Fuzzing configuration snippet is now being generated client-side and does not require an
+API request anymore. We are therefore deprecating the `apiFuzzingCiConfigurationCreate` mutation
+which isn't being used in GitLab anymore.
**Planned removal milestone: 15.0 (2022-05-22)**
-### GraphQL ID and GlobalID compatibility
+### bundler-audit Dependency Scanning tool
WARNING:
This feature will be changed or removed in 15.0
@@ -908,81 +1163,42 @@ as a [breaking change](https://docs.gitlab.com/ee/development/contributing/#brea
Before updating GitLab, review the details carefully to determine if you need to make any
changes to your code, settings, or workflow.
-We are removing a non-standard extension to our GraphQL processor, which we added for backwards compatibility. This extension modifies the validation of GraphQL queries, allowing the use of the `ID` type for arguments where it would normally be rejected.
-Some arguments originally had the type `ID`. These were changed to specific
-kinds of `ID`. This change may be a breaking change if you:
-
-- Use GraphQL.
-- Use the `ID` type for any argument in your query signatures.
-
-Some field arguments still have the `ID` type. These are typically for
-IID values, or namespace paths. An example is `Query.project(fullPath: ID!)`.
-
-For a list of affected and unaffected field arguments,
-see the [deprecation issue](https://gitlab.com/gitlab-org/gitlab/-/issues/352832).
-
-You can test if this change affects you by validating
-your queries locally, using schema data fetched from a GitLab server.
-You can do this by using the GraphQL explorer tool for the relevant GitLab
-instance. For example: `https://gitlab.com/-/graphql-explorer`.
-
-For example, the following query illustrates the breaking change:
-
-```graphql
-# a query using the deprecated type of Query.issue(id:)
-# WARNING: This will not work after GitLab 15.0
-query($id: ID!) {
- deprecated: issue(id: $id) {
- title, description
- }
-}
-```
-
-The query above will not work after GitLab 15.0 is released, because the type
-of `Query.issue(id:)` is actually `IssueID!`.
-
-Instead, you should use one of the following two forms:
+As of 14.6 bundler-audit is being deprecated from Dependency Scanning. It will continue to be in our CI/CD template while deprecated. We are removing bundler-audit from Dependency Scanning on May 22, 2022 in 15.0. After this removal Ruby scanning functionality will not be affected as it is still being covered by Gemnasium.
-```graphql
-# This will continue to work
-query($id: IssueID!) {
- a: issue(id: $id) {
- title, description
- }
- b: issue(id: "gid://gitlab/Issue/12345") {
- title, description
- }
-}
-```
+If you have explicitly excluded bundler-audit using DS_EXCLUDED_ANALYZERS you will need to clean up (remove the reference) in 15.0. If you have customized your pipeline's Dependency Scanning configuration, for example to edit the `bundler-audit-dependency_scanning` job, you will want to switch to gemnasium-dependency_scanning before removal in 15.0, to prevent your pipeline from failing. If you have not used the DS_EXCLUDED_ANALYZERS to reference bundler-audit, or customized your template specifically for bundler-audit, you will not need to take action.
-This query works now, and will continue to work after GitLab 15.0.
-You should convert any queries in the first form (using `ID` as a named type in the signature)
-to one of the other two forms (using the correct appropriate type in the signature, or using
-an inline argument expression).
+**Planned removal milestone: 15.0 (2022-05-22)**
-**Planned removal milestone: 15.0 (2022-04-22)**
+## 14.5
-### OAuth tokens without expiration
+### Certificate-based integration with Kubernetes
WARNING:
-This feature will be changed or removed in 15.0
+This feature will be changed or removed in 15.6
as a [breaking change](https://docs.gitlab.com/ee/development/contributing/#breaking-changes).
Before updating GitLab, review the details carefully to determine if you need to make any
changes to your code, settings, or workflow.
-By default, all new applications expire access tokens after 2 hours. In GitLab 14.2 and earlier, OAuth access tokens
-had no expiration. In GitLab 15.0, an expiry will be automatically generated for any existing token that does not
-already have one.
+[The certificate-based integration with Kubernetes will be deprecated and removed](https://about.gitlab.com/blog/2021/11/15/deprecating-the-cert-based-kubernetes-integration/).
-You should [opt in](https://docs.gitlab.com/ee/integration/oauth_provider.html#expiring-access-tokens) to expiring
-tokens before GitLab 15.0 is released:
+If you are a self-managed customer, in GitLab 15.0, a feature flag will be introduced so you can keep
+certificate-based integration enabled. The flag will be disabled by default.
+The flag and the related code will be removed in GitLab 15.6.
-1. Edit the application.
-1. Select **Expire access tokens** to enable them. Tokens must be revoked or they don’t expire.
+Until the final removal in 15.6, features built on the integration will continue to work, and
+GitLab will continue to fix security and critical issues.
-**Planned removal milestone: 15.0 (2022-05-22)**
+If you use GitLab.com, certificate-based integrations will cease functioning in 15.0.
-### Optional enforcement of PAT expiration
+For a more robust, secure, forthcoming, and reliable integration with Kubernetes, we recommend you use the
+[agent for Kubernetes](https://docs.gitlab.com/ee/user/clusters/agent/) to connect Kubernetes clusters with GitLab.
+See the documentation for [how to migrate](https://docs.gitlab.com/ee/user/infrastructure/clusters/migrate_to_gitlab_agent.html).
+
+For updates and details about this deprecation, follow [this epic](https://gitlab.com/groups/gitlab-org/configure/-/epics/8).
+
+**Planned removal milestone: 15.6 (2022-11-22)**
+
+### Converting an instance (shared) runner to a project (specific) runner
WARNING:
This feature will be changed or removed in 15.0
@@ -990,13 +1206,11 @@ as a [breaking change](https://docs.gitlab.com/ee/development/contributing/#brea
Before updating GitLab, review the details carefully to determine if you need to make any
changes to your code, settings, or workflow.
-The feature to disable enforcement of PAT expiration is unusual from a security perspective.
-We have become concerned that this unusual feature could create unexpected behavior for users.
-Unexpected behavior in a security feature is inherently dangerous, so we have decided to remove this feature.
+In GitLab 15.0, we will remove the feature that enables you to convert an instance (shared) runner to a project (specific) runner. Users who need to add a runner to only a particular project can register a runner to the project directly.
**Planned removal milestone: 15.0 (2022-05-22)**
-### Optional enforcement of SSH expiration
+### Known host required for GitLab Runner SSH executor
WARNING:
This feature will be changed or removed in 15.0
@@ -1004,13 +1218,13 @@ as a [breaking change](https://docs.gitlab.com/ee/development/contributing/#brea
Before updating GitLab, review the details carefully to determine if you need to make any
changes to your code, settings, or workflow.
-The feature to disable enforcement of SSH expiration is unusual from a security perspective.
-We have become concerned that this unusual feature could create unexpected behavior for users.
-Unexpected behavior in a security feature is inherently dangerous, so we have decided to remove this feature.
+In [GitLab 14.3](https://gitlab.com/gitlab-org/gitlab-runner/-/merge_requests/3074), we added a configuration setting in the GitLab Runner `config.toml` file. This setting, [`[runners.ssh.disable_strict_host_key_checking]`](https://docs.gitlab.com/runner/executors/ssh.html#security), controls whether or not to use strict host key checking with the SSH executor.
+
+In GitLab 15.0 and later, the default value for this configuration option will change from `true` to `false`. This means that strict host key checking will be enforced when using the GitLab Runner SSH executor.
**Planned removal milestone: 15.0 (2022-05-22)**
-### Out-of-the-box SAST support for Java 8
+### Must explicitly assign `AuthenticationType` for `[runners.cache.s3]`
WARNING:
This feature will be changed or removed in 15.0
@@ -1018,22 +1232,13 @@ as a [breaking change](https://docs.gitlab.com/ee/development/contributing/#brea
Before updating GitLab, review the details carefully to determine if you need to make any
changes to your code, settings, or workflow.
-The [GitLab SAST SpotBugs analyzer](https://gitlab.com/gitlab-org/security-products/analyzers/spotbugs) scans [Java, Scala, Groovy, and Kotlin code](https://docs.gitlab.com/ee/user/application_security/sast/#supported-languages-and-frameworks) for security vulnerabilities.
-For technical reasons, the analyzer must first compile the code before scanning.
-Unless you use the [pre-compilation strategy](https://docs.gitlab.com/ee/user/application_security/sast/#pre-compilation), the analyzer attempts to automatically compile your project's code.
-
-In GitLab versions prior to 15.0, the analyzer image includes Java 8 and Java 11 runtimes to facilitate compilation.
-
-In GitLab 15.0, we will:
-
-- Remove Java 8 from the analyzer image to reduce the size of the image.
-- Add Java 17 to the analyzer image to make it easier to compile with Java 17.
+In GitLab 15.0 and later, to access the AWS S3 cache, you must specify the `AuthenticationType` for [`[runners.cache.s3]`](https://docs.gitlab.com/runner/configuration/advanced-configuration.html#the-runnerscaches3-section). The `AuthenticationType` must be `IAM` or `credentials`.
-If you rely on Java 8 being present in the analyzer environment, you must take action as detailed in the [deprecation issue for this change](https://gitlab.com/gitlab-org/gitlab/-/issues/352549#breaking-change).
+Prior to 14.5, if you did not define the `AuthenticationType`, GitLab Runner chose a type for you.
**Planned removal milestone: 15.0 (2022-05-22)**
-### Querying Usage Trends via the `instanceStatisticsMeasurements` GraphQL node
+### Package pipelines in API payload is paginated
WARNING:
This feature will be changed or removed in 15.0
@@ -1041,71 +1246,57 @@ as a [breaking change](https://docs.gitlab.com/ee/development/contributing/#brea
Before updating GitLab, review the details carefully to determine if you need to make any
changes to your code, settings, or workflow.
-The `instanceStatisticsMeasurements` GraphQL node has been renamed to `usageTrendsMeasurements` in 13.10 and the old field name has been marked as deprecated. To fix the existing GraphQL queries, replace `instanceStatisticsMeasurements` with `usageTrendsMeasurements`.
+A request to the API for `/api/v4/projects/:id/packages` returns a paginated result of packages. Each package lists all of its pipelines in this response. This is a performance concern, as it's possible for a package to have hundreds or thousands of associated pipelines.
+
+In milestone 15.0, we will remove the `pipelines` attribute from the API response.
**Planned removal milestone: 15.0 (2022-05-22)**
-### REST API Runner will not accept `status` filter values of `active` or `paused`
+### REST and GraphQL API Runner status will not return `paused`
WARNING:
-This feature will be changed or removed in 16.0
+This feature will be changed or removed in 15.0
as a [breaking change](https://docs.gitlab.com/ee/development/contributing/#breaking-changes).
Before updating GitLab, review the details carefully to determine if you need to make any
changes to your code, settings, or workflow.
-The GitLab Runner REST endpoints will stop accepting `paused` or `active` as a status value in GitLab 16.0.
+The GitLab Runner REST and GraphQL API endpoints will not return `paused` or `active` as a status in GitLab 15.0.
-A runner's status will only relate to runner contact status, such as: `online`, `offline`.
-Status values `paused` or `active` will no longer be accepted and will be replaced by the `paused` query parameter.
+A runner's status will only relate to runner contact status, such as:
+`online`, `offline`, or `not_connected`. Status `paused` or `active` will no longer appear.
-When checking for paused runners, API users are advised to specify `paused=true` as the query parameter.
-When checking for active runners, specify `paused=false`.
+When checking if a runner is `paused`, API users are advised to check the boolean attribute
+`paused` to be `true` instead. When checking if a runner is `active`, check if `paused` is `false`.
-**Planned removal milestone: 16.0 (2023-04-22)**
+**Planned removal milestone: 15.0 (2022-05-22)**
-### REST API endpoint to list group runners no longer accepts `project_type` value for `type` argument
+### Support for SLES 12 SP2
WARNING:
-This feature will be changed or removed in 16.0
+This feature will be changed or removed in 15.0
as a [breaking change](https://docs.gitlab.com/ee/development/contributing/#breaking-changes).
Before updating GitLab, review the details carefully to determine if you need to make any
changes to your code, settings, or workflow.
-The `GET /groups/:id/runners?type=project_type` endpoint will be removed in GitLab 16.0. The endpoint always returned an empty collection.
+Long term service and support (LTSS) for SUSE Linux Enterprise Server (SLES) 12 SP2 [ended on March 31, 2021](https://www.suse.com/lifecycle/). The CA certificates on SP2 include the expired DST root certificate, and it's not getting new CA certificate package updates. We have implemented some [workarounds](https://gitlab.com/gitlab-org/gitlab-omnibus-builder/-/merge_requests/191), but we will not be able to continue to keep the build running properly.
-**Planned removal milestone: 16.0 (2023-04-22)**
+**Planned removal milestone: 15.0 (2022-05-22)**
-### REST and GraphQL API Runner usage of `active` replaced by `paused`
+### Update to the Container Registry group-level API
WARNING:
-This feature will be changed or removed in 16.0
+This feature will be changed or removed in 15.0
as a [breaking change](https://docs.gitlab.com/ee/development/contributing/#breaking-changes).
Before updating GitLab, review the details carefully to determine if you need to make any
changes to your code, settings, or workflow.
-Occurrences of the `active` identifier in the GitLab Runner REST and GraphQL API endpoints will be
-renamed to `paused` in GitLab 16.0, namely:
-
-- GraphQL API:
- - the `CiRunner` property;
- - the `RunnerUpdateInput` input type for the `runnerUpdate` mutation;
- - the `runners` and `Group.runners` queries.
-- REST API:
- - endpoints taking or returning `active` properties, such as:
- - `GET /runners`
- - `GET /runners/all`
- - `GET /runners/:id` / `PUT /runners/:id`
- - `PUT --form "active=false" /runners/:runner_id`
- - `GET /projects/:id/runners` / `POST /projects/:id/runners`
- - `GET /groups/:id/runners`
+In milestone 15.0, support for the `tags` and `tags_count` parameters will be removed from the Container Registry API that [gets registry repositories from a group](../api/container_registry.md#within-a-group).
-The 16.0 release of the GitLab Runner will start using the `paused` property when registering runners, and therefore
-will only be compatible with GitLab 16.0 and later. Until 16.0, GitLab will accept the deprecated `active` flag from
-existing runners.
+The `GET /groups/:id/registry/repositories` endpoint will remain, but won't return any info about tags. To get the info about tags, you can use the existing `GET /registry/repositories/:id` endpoint, which will continue to support the `tags` and `tag_count` options as it does today. The latter must be called once per image repository.
-**Planned removal milestone: 16.0 (2023-04-22)**
+**Planned removal milestone: 15.0 (2022-05-22)**
-### Reminder: support for NFS repository storage
+### Value Stream Analytics filtering calculation change
WARNING:
This feature will be changed or removed in 15.0
@@ -1113,22 +1304,13 @@ as a [breaking change](https://docs.gitlab.com/ee/development/contributing/#brea
Before updating GitLab, review the details carefully to determine if you need to make any
changes to your code, settings, or workflow.
-As [announced](https://about.gitlab.com/releases/2021/06/22/gitlab-14-0-released/#nfs-for-git-repository-storage-deprecated) at the
-release of GitLab 14.0, technical support for NFS storage for Git repositories is being removed. Please see our official
-[Statement of Support](https://about.gitlab.com/support/statement-of-support.html#gitaly-and-nfs) for additional information.
-
-We encourage customers currently using NFS for Git repositories to plan their migration by reviewing our documentation on
-[migrating to Gitaly Cluster](https://docs.gitlab.com/ee/administration/gitaly/#migrating-to-gitaly-cluster).
-
-Gitaly Cluster offers tremendous benefits for our customers such as:
+We are changing how the date filter works in Value Stream Analytics. Instead of filtering by the time that the issue or merge request was created, the date filter will filter by the end event time of the given stage. This will result in completely different figures after this change has rolled out.
-- [Variable replication factors](https://docs.gitlab.com/ee/administration/gitaly/praefect.html#configure-replication-factor)
-- [Strong consistency](https://docs.gitlab.com/ee/administration/gitaly/#strong-consistency)
-- [Distributed read capabilities](https://docs.gitlab.com/ee/administration/gitaly/#distributed-reads)
+If you monitor Value Stream Analytics metrics and rely on the date filter, to avoid losing data, you must save the data prior to this change.
**Planned removal milestone: 15.0 (2022-05-22)**
-### Request profiling
+### `Versions` on base `PackageType`
WARNING:
This feature will be changed or removed in 15.0
@@ -1136,17 +1318,13 @@ as a [breaking change](https://docs.gitlab.com/ee/development/contributing/#brea
Before updating GitLab, review the details carefully to determine if you need to make any
changes to your code, settings, or workflow.
-[Request profiling](https://docs.gitlab.com/ee/administration/monitoring/performance/request_profiling.html) is deprecated in GitLab 14.8 and scheduled for removal in GitLab 15.0.
-
-We're working on [consolidating our profiling tools](https://gitlab.com/groups/gitlab-org/-/epics/7327) and making them more easily accessible.
-We [evaluated](https://gitlab.com/gitlab-org/gitlab/-/issues/350152) the use of this feature and we found that it is not widely used.
-It also depends on a few third-party gems that are not actively maintained anymore, have not been updated for the latest version of Ruby, or crash frequently when profiling heavy page loads.
+As part of the work to create a [Package Registry GraphQL API](https://gitlab.com/groups/gitlab-org/-/epics/6318), the Package group deprecated the `Version` type for the basic `PackageType` type and moved it to [`PackageDetailsType`](https://docs.gitlab.com/ee/api/graphql/reference/index.html#packagedetailstype).
-For more information, check the [summary section of the deprecation issue](https://gitlab.com/gitlab-org/gitlab/-/issues/352488#deprecation-summary).
+In milestone 15.0, we will completely remove `Version` from `PackageType`.
**Planned removal milestone: 15.0 (2022-05-22)**
-### Required pipeline configurations in Premium tier
+### `defaultMergeCommitMessageWithDescription` GraphQL API field
WARNING:
This feature will be changed or removed in 15.0
@@ -1154,16 +1332,11 @@ as a [breaking change](https://docs.gitlab.com/ee/development/contributing/#brea
Before updating GitLab, review the details carefully to determine if you need to make any
changes to your code, settings, or workflow.
-The [required pipeline configuration](https://docs.gitlab.com/ee/user/admin_area/settings/continuous_integration.html#required-pipeline-configuration) feature is deprecated in GitLab 14.8 for Premium customers and is scheduled for removal in GitLab 15.0. This feature is not deprecated for GitLab Ultimate customers.
-
-This change to move the feature to GitLab's Ultimate tier is intended to help our features better align with our [pricing philosophy](https://about.gitlab.com/company/pricing/#three-tiers) as we see demand for this feature originating primarily from executives.
-
-This change will also help GitLab remain consistent in its tiering strategy with the other related Ultimate-tier features of:
-[Security policies](https://docs.gitlab.com/ee/user/application_security/policies/) and [compliance framework pipelines](https://docs.gitlab.com/ee/user/project/settings/index.html#compliance-pipeline-configuration).
+The GraphQL API field `defaultMergeCommitMessageWithDescription` has been deprecated and will be removed in GitLab 15.0. For projects with a commit message template set, it will ignore the template.
**Planned removal milestone: 15.0 (2022-05-22)**
-### Retire-JS Dependency Scanning tool
+### `dependency_proxy_for_private_groups` feature flag
WARNING:
This feature will be changed or removed in 15.0
@@ -1171,13 +1344,13 @@ as a [breaking change](https://docs.gitlab.com/ee/development/contributing/#brea
Before updating GitLab, review the details carefully to determine if you need to make any
changes to your code, settings, or workflow.
-As of 14.8 the retire.js job is being deprecated from Dependency Scanning. It will continue to be included in our CI/CD template while deprecated. We are removing retire.js from Dependency Scanning on May 22, 2022 in GitLab 15.0. JavaScript scanning functionality will not be affected as it is still being covered by Gemnasium.
+We added a feature flag because [GitLab-#11582](https://gitlab.com/gitlab-org/gitlab/-/issues/11582) changed how public groups use the Dependency Proxy. Prior to this change, you could use the Dependency Proxy without authentication. The change requires authentication to use the Dependency Proxy.
-If you have explicitly excluded retire.js using DS_EXCLUDED_ANALYZERS you will need to clean up (remove the reference) in 15.0. If you have customized your pipeline's Dependency Scanning configuration related to the `retire-js-dependency_scanning` job you will want to switch to gemnasium-dependency_scanning before the removal in 15.0, to prevent your pipeline from failing. If you have not used the DS_EXCLUDED_ANALYZERS to reference retire.js, or customized your template specifically for retire.js, you will not need to take action.
+In milestone 15.0, we will remove the feature flag entirely. Moving forward, you must authenticate when using the Dependency Proxy.
**Planned removal milestone: 15.0 (2022-05-22)**
-### SAST analyzer consolidation and CI/CD template changes
+### `pipelines` field from the `version` field
WARNING:
This feature will be changed or removed in 15.0
@@ -1185,30 +1358,16 @@ as a [breaking change](https://docs.gitlab.com/ee/development/contributing/#brea
Before updating GitLab, review the details carefully to determine if you need to make any
changes to your code, settings, or workflow.
-GitLab SAST uses various [analyzers](https://docs.gitlab.com/ee/user/application_security/sast/analyzers/) to scan code for vulnerabilities.
-
-We are reducing the number of analyzers used in GitLab SAST as part of our long-term strategy to deliver a better and more consistent user experience.
-Streamlining the set of analyzers will also enable faster [iteration](https://about.gitlab.com/handbook/values/#iteration), better [results](https://about.gitlab.com/handbook/values/#results), and greater [efficiency](https://about.gitlab.com/handbook/values/#results) (including a reduction in CI runner usage in most cases).
-
-In GitLab 15.0, GitLab SAST will no longer use the following analyzers:
-
-- [ESLint](https://gitlab.com/gitlab-org/security-products/analyzers/eslint) (JavaScript, TypeScript, React)
-- [Gosec](https://gitlab.com/gitlab-org/security-products/analyzers/gosec) (Go)
-- [Bandit](https://gitlab.com/gitlab-org/security-products/analyzers/bandit) (Python)
-
-These analyzers will be removed from the [GitLab-managed SAST CI/CD template](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Security/SAST.gitlab-ci.yml) and replaced with the [Semgrep-based analyzer](https://gitlab.com/gitlab-org/security-products/analyzers/semgrep).
-They will no longer receive routine updates, except for security issues.
-We will not delete container images previously published for these analyzers; any such change would be announced as a [deprecation, removal, or breaking change announcement](https://about.gitlab.com/handbook/marketing/blog/release-posts/#deprecations-removals-and-breaking-changes).
+In GraphQL, there are two `pipelines` fields that you can use in a [`PackageDetailsType`](https://docs.gitlab.com/ee/api/graphql/reference/#packagedetailstype) to get the pipelines for package versions:
-We will also remove Java from the scope of the [SpotBugs](https://gitlab.com/gitlab-org/security-products/analyzers/spotbugs) analyzer and replace it with the [Semgrep-based analyzer](https://gitlab.com/gitlab-org/security-products/analyzers/semgrep).
-This change will make it simpler to scan Java code; compilation will no longer be required.
-This change will be reflected in the automatic language detection portion of the [GitLab-managed SAST CI/CD template](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Security/SAST.gitlab-ci.yml).
+- The `versions` field's `pipelines` field. This returns all the pipelines associated with all the package's versions, which can pull an unbounded number of objects in memory and create performance concerns.
+- The `pipelines` field of a specific `version`. This returns only the pipelines associated with that single package version.
-If you applied customizations to any of the affected analyzers, you must take action as detailed in the [deprecation issue for this change](https://gitlab.com/gitlab-org/gitlab/-/issues/352554#breaking-change).
+To mitigate possible performance problems, we will remove the `versions` field's `pipelines` field in milestone 15.0. Although you will no longer be able to get all pipelines for all versions of a package, you can still get the pipelines of a single version through the remaining `pipelines` field for that version.
**Planned removal milestone: 15.0 (2022-05-22)**
-### SAST support for .NET 2.1
+### `promote-db` command from `gitlab-ctl`
WARNING:
This feature will be changed or removed in 15.0
@@ -1216,50 +1375,11 @@ as a [breaking change](https://docs.gitlab.com/ee/development/contributing/#brea
Before updating GitLab, review the details carefully to determine if you need to make any
changes to your code, settings, or workflow.
-The GitLab SAST Security Code Scan analyzer scans .NET code for security vulnerabilities.
-For technical reasons, the analyzer must first build the code to scan it.
-
-In GitLab versions prior to 15.0, the default analyzer image (version 2) includes support for:
-
-- .NET 2.1
-- .NET 3.0 and .NET Core 3.0
-- .NET Core 3.1
-- .NET 5.0
-
-In GitLab 15.0, we will change the default major version for this analyzer from version 2 to version 3. This change:
-
-- Adds [severity values for vulnerabilities](https://gitlab.com/gitlab-org/gitlab/-/issues/350408) along with [other new features and improvements](https://gitlab.com/gitlab-org/security-products/analyzers/security-code-scan/-/blob/master/CHANGELOG.md).
-- Removes .NET 2.1 support.
-- Adds support for .NET 6.0, Visual Studio 2019, and Visual Studio 2022.
-
-Version 3 was [announced in GitLab 14.6](https://about.gitlab.com/releases/2021/12/22/gitlab-14-6-released/#sast-support-for-net-6) and made available as an optional upgrade.
-
-If you rely on .NET 2.1 support being present in the analyzer image by default, you must take action as detailed in the [deprecation issue for this change](https://gitlab.com/gitlab-org/gitlab/-/issues/352553#breaking-change).
-
-**Planned removal milestone: 15.0 (2022-05-22)**
-
-### Secret Detection configuration variables deprecated
-
-To make it simpler and more reliable to [customize GitLab Secret Detection](https://docs.gitlab.com/ee/user/application_security/secret_detection/#customizing-settings), we're deprecating some of the variables that you could previously set in your CI/CD configuration.
-
-The following variables currently allow you to customize the options for historical scanning, but interact poorly with the [GitLab-managed CI/CD template](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Security/Secret-Detection.gitlab-ci.yml) and are now deprecated:
-
-- `SECRET_DETECTION_COMMIT_FROM`
-- `SECRET_DETECTION_COMMIT_TO`
-- `SECRET_DETECTION_COMMITS`
-- `SECRET_DETECTION_COMMITS_FILE`
-
-The `SECRET_DETECTION_ENTROPY_LEVEL` previously allowed you to configure rules that only considered the entropy level of strings in your codebase, and is now deprecated.
-This type of entropy-only rule created an unacceptable number of incorrect results (false positives) and is no longer supported.
-
-In GitLab 15.0, we'll update the Secret Detection [analyzer](https://docs.gitlab.com/ee/user/application_security/terminology/#analyzer) to ignore these deprecated options.
-You'll still be able to configure historical scanning of your commit history by setting the [`SECRET_DETECTION_HISTORIC_SCAN` CI/CD variable](https://docs.gitlab.com/ee/user/application_security/secret_detection/#available-cicd-variables).
-
-For further details, see [the deprecation issue for this change](https://gitlab.com/gitlab-org/gitlab/-/issues/352565).
+In GitLab 14.5, we introduced the command `gitlab-ctl promote` to promote any Geo secondary node to a primary during a failover. This command replaces `gitlab-ctl promote-db` which is used to promote database nodes in multi-node Geo secondary sites. `gitlab-ctl promote-db` will continue to function as-is and be available until GitLab 15.0. We recommend that Geo customers begin testing the new `gitlab-ctl promote` command in their staging environments and incorporating the new command in their failover procedures.
**Planned removal milestone: 15.0 (2022-05-22)**
-### Secure and Protect analyzer images published in new location
+### `promote-to-primary-node` command from `gitlab-ctl`
WARNING:
This feature will be changed or removed in 15.0
@@ -1267,67 +1387,37 @@ as a [breaking change](https://docs.gitlab.com/ee/development/contributing/#brea
Before updating GitLab, review the details carefully to determine if you need to make any
changes to your code, settings, or workflow.
-GitLab uses various [analyzers](https://docs.gitlab.com/ee/user/application_security/terminology/#analyzer) to [scan for security vulnerabilities](https://docs.gitlab.com/ee/user/application_security/).
-Each analyzer is distributed as a container image.
+In GitLab 14.5, we introduced the command `gitlab-ctl promote` to promote any Geo secondary node to a primary during a failover. This command replaces `gitlab-ctl promote-to-primary-node` which was only usable for single-node Geo sites. `gitlab-ctl promote-to-primary-node` will continue to function as-is and be available until GitLab 15.0. We recommend that Geo customers begin testing the new `gitlab-ctl promote` command in their staging environments and incorporating the new command in their failover procedures.
-Starting in GitLab 14.8, new versions of GitLab Secure and Protect analyzers are published to a new registry location under `registry.gitlab.com/security-products`.
+**Planned removal milestone: 15.0 (2022-05-22)**
-We will update the default value of [GitLab-managed CI/CD templates](https://gitlab.com/gitlab-org/gitlab/-/tree/master/lib/gitlab/ci/templates/Security) to reflect this change:
-
-- For all analyzers except Container Scanning, we will update the variable `SECURE_ANALYZERS_PREFIX` to the new image registry location.
-- For Container Scanning, the default image address is already updated. There is no `SECURE_ANALYZERS_PREFIX` variable for Container Scanning.
+### openSUSE Leap 15.2 packages
-In a future release, we will stop publishing images to `registry.gitlab.com/gitlab-org/security-products/analyzers`.
-Once this happens, you must take action if you manually pull images and push them into a separate registry. This is commonly the case for [offline deployments](https://docs.gitlab.com/ee/user/application_security/offline_deployments/index.html).
-Otherwise, you won't receive further updates.
+Distribution support and security updates for openSUSE Leap 15.2 are [ending December 2021](https://en.opensuse.org/Lifetime#openSUSE_Leap).
-See the [deprecation issue](https://gitlab.com/gitlab-org/gitlab/-/issues/352564) for more details.
+Starting in 14.5 we are providing packages for openSUSE Leap 15.3, and will stop providing packages for openSUSE Leap 15.2 in the 14.8 milestone.
-**Planned removal milestone: 15.0 (2022-05-22)**
+**Planned removal milestone: 14.8 (2022-02-22)**
-### Secure and Protect analyzer major version update
+## 14.3
+
+### Audit events for repository push events
WARNING:
-This feature will be changed or removed in 15.00
+This feature will be changed or removed in 15.0
as a [breaking change](https://docs.gitlab.com/ee/development/contributing/#breaking-changes).
Before updating GitLab, review the details carefully to determine if you need to make any
changes to your code, settings, or workflow.
-The Secure and Protect stages will be bumping the major versions of their analyzers in tandem with the GitLab 15.0 release. This major bump will enable a clear delineation for analyzers, between:
-
-- Those released prior to May 22, 2022, which generate reports that _are not_ subject to stringent schema validation.
-- Those released after May 22, 2022, which generate reports that _are_ subject to stringent schema validation.
-
-If you are not using the default inclusion templates, or have pinned your analyzer version(s) you will need to update your CI/CD job definition to either remove the pinned version or to update the latest major version.
-Users of GitLab 12.0-14.10 will continue to experience analyzer updates as normal until the release of GitLab 15.0, following which all newly fixed bugs and newly released features in the new major versions of the analyzers will not be available in the deprecated versions because we do not backport bugs and new features as per our [maintenance policy](https://docs.gitlab.com/ee/policy/maintenance.html). As required security patches will be backported within the latest 3 minor releases.
-Specifically, the following are being deprecated and will no longer be updated after 15.0 GitLab release:
+Audit events for [repository events](https://docs.gitlab.com/ee/administration/audit_events.html#repository-push-deprecated) are now deprecated and will be removed in GitLab 15.0.
-- API Security: version 1
-- Container Scanning: version 4
-- Coverage-guided fuzz testing: version 2
-- Dependency Scanning: version 2
-- Dynamic Application Security Testing (DAST): version 2
-- License Scanning: version 3
-- Secret Detection: version 3
-- Static Application Security Testing (SAST): version 2, except security-code-scan which is version 3
- - `bandit`: version 2
- - `brakeman`: version 2
- - `eslint`: version 2
- - `flawfinder`: version 2
- - `gosec`: version 3
- - `kubesec`: version 2
- - `mobsf`: version 2
- - `nodejs-scan`: version 2
- - `phpcs-security-audit`: version 2
- - `pmd-apex`: version 2
- - `security-code-scan`: version 3
- - `semgrep`: version 2
- - `sobelow`: version 2
- - `spotbugs`: version 2
+These events have always been disabled by default and had to be manually enabled with a
+feature flag. Enabling them can cause too many events to be generated which can
+dramatically slow down GitLab instances. For this reason, they are being removed.
-**Planned removal milestone: 15.00 ()**
+**Planned removal milestone: 15.0 (2022-05-22)**
-### Support for gRPC-aware proxy deployed between Gitaly and rest of GitLab
+### GitLab Serverless
WARNING:
This feature will be changed or removed in 15.0
@@ -1335,21 +1425,13 @@ as a [breaking change](https://docs.gitlab.com/ee/development/contributing/#brea
Before updating GitLab, review the details carefully to determine if you need to make any
changes to your code, settings, or workflow.
-Although not recommended or documented, it was possible to deploy a gRPC-aware proxy between Gitaly and
-the rest of GitLab. For example, NGINX and Envoy. The ability to deploy a gRPC-aware proxy is
-[deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/352517). If you currently use a gRPC-aware proxy for
-Gitaly connections, you should change your proxy configuration to use TCP or TLS proxying (OSI layer 4) instead.
-
-Gitaly Cluster became incompatible with gRPC-aware proxies in GitLab 13.12. Now all GitLab installations will be incompatible with
-gRPC-aware proxies, even without Gitaly Cluster.
+[GitLab Serverless](https://docs.gitlab.com/ee/user/project/clusters/serverless/) is a feature set to support Knative-based serverless development with automatic deployments and monitoring.
-By sending some of our internal RPC traffic through a custom protocol (instead of gRPC) we
-increase throughput and reduce Go garbage collection latency. For more information, see
-the [relevant epic](https://gitlab.com/groups/gitlab-com/gl-infra/-/epics/463).
+We decided to remove the GitLab Serverless features as they never really resonated with our users. Besides, given the continuous development of Kubernetes and Knative, our current implementations do not even work with recent versions.
**Planned removal milestone: 15.0 (2022-05-22)**
-### Test coverage project CI/CD setting
+### Legacy database configuration
WARNING:
This feature will be changed or removed in 15.0
@@ -1357,16 +1439,15 @@ as a [breaking change](https://docs.gitlab.com/ee/development/contributing/#brea
Before updating GitLab, review the details carefully to determine if you need to make any
changes to your code, settings, or workflow.
-To simplify setting a test coverage pattern, in GitLab 15.0 the
-[project setting for test coverage parsing](https://docs.gitlab.com/ee/ci/pipelines/settings.html#add-test-coverage-results-to-a-merge-request-deprecated)
-is being removed.
+The syntax of [GitLabs database](https://docs.gitlab.com/omnibus/settings/database.html)
+configuration located in `database.yml` is changing and the legacy format is deprecated. The legacy format
+supported using a single PostgreSQL adapter, whereas the new format is changing to support multiple databases. The `main:` database needs to be defined as a first configuration item.
-Instead, using the project’s `.gitlab-ci.yml`, provide a regular expression with the `coverage` keyword to set
-testing coverage results in merge requests.
+This deprecation mainly impacts users compiling GitLab from source because Omnibus will handle this configuration automatically.
**Planned removal milestone: 15.0 (2022-05-22)**
-### Vulnerability Check
+### OmniAuth Kerberos gem
WARNING:
This feature will be changed or removed in 15.0
@@ -1374,42 +1455,33 @@ as a [breaking change](https://docs.gitlab.com/ee/development/contributing/#brea
Before updating GitLab, review the details carefully to determine if you need to make any
changes to your code, settings, or workflow.
-The vulnerability check feature is deprecated in GitLab 14.8 and scheduled for removal in GitLab 15.0. We encourage you to migrate to the new security approvals feature instead. You can do so by navigating to **Security & Compliance > Policies** and creating a new Scan Result Policy.
+The `omniauth-kerberos` gem will be removed in our next major release, GitLab 15.0.
-The new security approvals feature is similar to vulnerability check. For example, both can require approvals for MRs that contain security vulnerabilities. However, security approvals improve the previous experience in several ways:
+This gem has not been maintained and has very little usage. We therefore plan to remove support for this authentication method and recommend using the Kerberos [SPNEGO](https://en.wikipedia.org/wiki/SPNEGO) integration instead. You can follow the [upgrade instructions](https://docs.gitlab.com/ee/integration/kerberos.html#upgrading-from-password-based-to-ticket-based-kerberos-sign-ins) to upgrade from the `omniauth-kerberos` integration to the supported one.
-- Users can choose who is allowed to edit security approval rules. An independent security or compliance team can therefore manage rules in a way that prevents development project maintainers from modifying the rules.
-- Multiple rules can be created and chained together to allow for filtering on different severity thresholds for each scanner type.
-- A two-step approval process can be enforced for any desired changes to security approval rules.
-- A single set of security policies can be applied to multiple development projects to allow for ease in maintaining a single, centralized ruleset.
+Note that we are not deprecating the Kerberos SPNEGO integration, only the old password-based Kerberos integration.
**Planned removal milestone: 15.0 (2022-05-22)**
-### `CI_BUILD_*` predefined variables
+## 14.2
-WARNING:
-This feature will be changed or removed in 15.0
-as a [breaking change](https://docs.gitlab.com/ee/development/contributing/#breaking-changes).
-Before updating GitLab, review the details carefully to determine if you need to make any
-changes to your code, settings, or workflow.
+### Release CLI distributed as a generic package
-The predefined CI/CD variables that start with `CI_BUILD_*` were deprecated in GitLab 9.0, and will be removed in GitLab 15.0. If you still use these variables, be sure to change to the current [`CI_JOB_*` predefined variables](https://docs.gitlab.com/ee/ci/variables/predefined_variables.html) which are identical (except for the updated name).
+The [release-cli](https://gitlab.com/gitlab-org/release-cli) will be released as a [generic package](https://gitlab.com/gitlab-org/release-cli/-/packages) starting in GitLab 14.2. We will continue to deploy it as a binary to S3 until GitLab 14.5 and stop distributing it in S3 in GitLab 14.6.
-**Planned removal milestone: 15.0 (2022-05-22)**
+**Planned removal milestone: 14.6 (2021-12-22)**
-### `fixup!` commit messages setting draft status of associated Merge Request
+### Rename Task Runner pod to Toolbox
-The use of `fixup!` as a commit message to trigger draft status
-of the associated Merge Request is generally unused, and can cause
-confusion with other uses of the term. "Draft" is the preferred
-and supported trigger for triggering draft status from commit
-messages, as part of our streamlining of the feature.
-Support for `fixup!` is now considered deprecated, and will be
-removed in GitLab 15.0.
+The Task Runner pod is used to execute periodic housekeeping tasks within the GitLab application and is often confused with the GitLab Runner. Thus, [Task Runner will be renamed to Toolbox](https://gitlab.com/groups/gitlab-org/charts/-/epics/25).
-**Planned removal milestone: 15.0 (2022-06-22)**
+This will result in the rename of the sub-chart: `gitlab/task-runner` to `gitlab/toolbox`. Resulting pods will be named along the lines of `{{ .Release.Name }}-toolbox`, which will often be `gitlab-toolbox`. They will be locatable with the label `app=toolbox`.
-### `projectFingerprint` in `PipelineSecurityReportFinding` GraphQL
+**Planned removal milestone: 14.5 (2021-11-22)**
+
+## 14.0
+
+### NFS for Git repository storage
WARNING:
This feature will be changed or removed in 15.0
@@ -1417,14 +1489,19 @@ as a [breaking change](https://docs.gitlab.com/ee/development/contributing/#brea
Before updating GitLab, review the details carefully to determine if you need to make any
changes to your code, settings, or workflow.
-The `projectFingerprint` field in the [PipelineSecurityReportFinding](https://docs.gitlab.com/ee/api/graphql/reference/index.html#pipelinesecurityreportfinding)
-GraphQL object is being deprecated. This field contains a "fingerprint" of security findings used to determine uniqueness.
-The method for calculating fingerprints has changed, resulting in different values. Going forward, the new values will be
-exposed in the UUID field. Data previously available in the projectFingerprint field will eventually be removed entirely.
+With the general availability of Gitaly Cluster ([introduced in GitLab 13.0](https://about.gitlab.com/releases/2020/05/22/gitlab-13-0-released/)), we have deprecated development (bugfixes, performance improvements, etc) for NFS for Git repository storage in GitLab 14.0. We will continue to provide technical support for NFS for Git repositories throughout 14.x, but we will remove all support for NFS in GitLab 15.0. Please see our official [Statement of Support](https://about.gitlab.com/support/statement-of-support.html#gitaly-and-nfs) for further information.
+
+Gitaly Cluster offers tremendous benefits for our customers such as:
+
+- [Variable replication factors](https://docs.gitlab.com/ee/administration/gitaly/index.html#replication-factor).
+- [Strong consistency](https://docs.gitlab.com/ee/administration/gitaly/index.html#strong-consistency).
+- [Distributed read capabilities](https://docs.gitlab.com/ee/administration/gitaly/index.html#distributed-reads).
+
+We encourage customers currently using NFS for Git repositories to plan their migration by reviewing our documentation on [migrating to Gitaly Cluster](https://docs.gitlab.com/ee/administration/gitaly/index.html#migrate-to-gitaly-cluster).
**Planned removal milestone: 15.0 (2022-05-22)**
-### `started` iterations API field
+### OAuth implicit grant
WARNING:
This feature will be changed or removed in 15.0
@@ -1432,6 +1509,6 @@ as a [breaking change](https://docs.gitlab.com/ee/development/contributing/#brea
Before updating GitLab, review the details carefully to determine if you need to make any
changes to your code, settings, or workflow.
-The `started` field in the [iterations API](https://docs.gitlab.com/ee/api/iterations.html#list-project-iterations) is being deprecated and will be removed in GitLab 15.0. This field is being replaced with the `current` field (already available) which aligns with the naming for other time-based entities, such as milestones.
+The OAuth implicit grant authorization flow will be removed in our next major release, GitLab 15.0. Any applications that use OAuth implicit grant should switch to alternative [supported OAuth flows](https://docs.gitlab.com/ee/api/oauth2.html).
**Planned removal milestone: 15.0 (2022-05-22)**
diff --git a/doc/update/index.md b/doc/update/index.md
index 45b5f36bc5a..5a00a728535 100644
--- a/doc/update/index.md
+++ b/doc/update/index.md
@@ -148,9 +148,22 @@ If you get this error, [check the batched background migration options](../user/
### What do I do if my background migrations are stuck?
WARNING:
-The following operations can disrupt your GitLab performance.
+The following operations can disrupt your GitLab performance. They run a number of Sidekiq jobs that perform various database or file updates.
-It is safe to re-execute these commands, especially if you have 1000+ pending jobs which would likely overflow your runtime memory.
+#### Background migrations remain in the Sidekiq queue
+
+Run the following check. If it returns non-zero and the count does not decrease over time, follow the rest of the steps in this section.
+
+```shell
+# For Omnibus installations:
+sudo gitlab-rails runner -e production 'puts Gitlab::BackgroundMigration.remaining'
+
+# For installations from source:
+cd /home/git/gitlab
+sudo -u git -H bundle exec rails runner -e production 'puts Gitlab::BackgroundMigration.remaining'
+```
+
+It is safe to re-execute the following commands, especially if you have 1000+ pending jobs which would likely overflow your runtime memory.
**For Omnibus installations**
@@ -176,7 +189,52 @@ pending_job_classes = scheduled_queue.select { |job| job["class"] == "Background
pending_job_classes.each { |job_class| Gitlab::BackgroundMigration.steal(job_class) }
```
-**Batched migrations (GitLab 14.0 and newer):**
+#### Background migrations stuck in 'pending' state
+
+GitLab 13.6 introduced an issue where a background migration named `BackfillJiraTrackerDeploymentType2` can be permanently stuck in a **pending** state across upgrades. To clean up this stuck migration, see the [13.6.0 version-specific instructions](#1360).
+
+For other background migrations stuck in pending, run the following check. If it returns non-zero and the count does not decrease over time, follow the rest of the steps in this section.
+
+```shell
+# For Omnibus installations:
+sudo gitlab-rails runner -e production 'puts Gitlab::Database::BackgroundMigrationJob.pending.count'
+
+# For installations from source:
+cd /home/git/gitlab
+sudo -u git -H bundle exec rails runner -e production 'puts Gitlab::Database::BackgroundMigrationJob.pending.count'
+```
+
+It is safe to re-attempt these migrations to clear them out from a pending status:
+
+**For Omnibus installations**
+
+```shell
+# Start the rails console
+sudo gitlab-rails c
+
+# Execute the following in the rails console
+Gitlab::Database::BackgroundMigrationJob.pending.find_each do |job|
+ puts "Running pending job '#{job.class_name}' with arguments #{job.arguments}"
+ result = Gitlab::BackgroundMigration.perform(job.class_name, job.arguments)
+ puts "Result: #{result}"
+end
+```
+
+**For installations from source**
+
+```shell
+# Start the rails console
+sudo -u git -H bundle exec rails RAILS_ENV=production
+
+# Execute the following in the rails console
+Gitlab::Database::BackgroundMigrationJob.pending.find_each do |job|
+ puts "Running pending job '#{job.class_name}' with arguments #{job.arguments}"
+ result = Gitlab::BackgroundMigration.perform(job.class_name, job.arguments)
+ puts "Result: #{result}"
+end
+```
+
+#### Batched migrations (GitLab 14.0 and later)
See [troubleshooting batched background migrations](../user/admin_area/monitoring/background_migrations.md#troubleshooting).
@@ -192,6 +250,8 @@ To address the above two scenario's, it is advised to do the following prior to
1. Pause your runners.
1. Wait until all jobs are finished.
1. Upgrade GitLab.
+1. [Update GitLab Runner](https://docs.gitlab.com/runner/install/index.html) to the same version
+ as your GitLab version. Both versions [should be the same](https://docs.gitlab.com/runner/#gitlab-runner-versions).
## Checking for pending Advanced Search migrations **(PREMIUM SELF)**
@@ -230,14 +290,12 @@ Backward-incompatible changes and migrations are reserved for major versions.
Follow the directions carefully as we
cannot guarantee that upgrading between major versions is seamless.
-It is required to follow the following upgrade steps to ensure a successful *major* version upgrade:
+A *major* upgrade requires the following steps:
+1. Start by identifying a [supported upgrade path](#upgrade-paths). This is essential for a successful *major* version upgrade.
1. Upgrade to the latest minor version of the preceding major version.
-1. Upgrade to the next major version (`X.0.Z`).
-1. Upgrade to its first minor version (`X.1.Z`).
-1. Proceed with upgrading to a newer releases of that major version.
-
-Identify a [supported upgrade path](#upgrade-paths).
+1. Upgrade to the "dot zero" release of the next major version (`X.0.Z`).
+1. Optional. Follow the [upgrade path](#upgrade-paths), and proceed with upgrading to newer releases of that major version.
It's also important to ensure that any [background migrations have been fully completed](#checking-for-background-migrations-before-upgrading)
before upgrading to a new major version.
@@ -261,7 +319,7 @@ Find where your version sits in the upgrade path below, and upgrade GitLab
accordingly, while also consulting the
[version-specific upgrade instructions](#version-specific-upgrading-instructions):
-`8.11.Z` -> `8.12.0` -> `8.17.7` -> `9.5.10` -> `10.8.7` -> [`11.11.8`](#1200) -> `12.0.12` -> [`12.1.17`](#1210) -> `12.10.14` -> `13.0.14` -> [`13.1.11`](#1310) -> [`13.8.8`](#1388) -> [latest `13.12.Z`](https://about.gitlab.com/releases/categories/releases/) -> [latest `14.0.Z`](#1400) -> [latest `14.1.Z`](#1410) -> [latest `14.Y.Z`](https://about.gitlab.com/releases/categories/releases/)
+`8.11.Z` -> `8.12.0` -> `8.17.7` -> `9.5.10` -> `10.8.7` -> [`11.11.8`](#1200) -> `12.0.12` -> [`12.1.17`](#1210) -> `12.10.14` -> `13.0.14` -> [`13.1.11`](#1310) -> [`13.8.8`](#1388) -> [`13.12.15`](#13120) -> [`14.0.12`](#1400) -> [latest `14.Y.Z`](https://gitlab.com/gitlab-org/gitlab/-/releases)
The following table, while not exhaustive, shows some examples of the supported
upgrade paths.
@@ -269,8 +327,8 @@ Additional steps between the mentioned versions are possible. We list the minima
| Target version | Your version | Supported upgrade path | Note |
| -------------- | ------------ | ---------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
-| `14.2.6` | `13.10.2` | `13.10.2` -> `13.12.15` -> `14.0.11` -> `14.1.8` -> `14.2.6` | Three intermediate versions are required: `13.12`, `14.0`, and `14.1`, then `14.2.6`. |
-| `14.1.8` | `13.9.2` | `13.9.2` -> `13.12.15` -> `14.0.11` -> `14.1.8` | Two intermediate versions are required: `13.12` and `14.0`, then `14.1.8`. |
+| `14.6.2` | `13.10.2` | `13.10.2` -> `13.12.15` -> `14.0.12` -> `14.6.2` | Two intermediate versions are required: `13.12` and `14.0`, then `14.6.2`. |
+| `14.1.8` | `13.9.2` | `13.9.2` -> `13.12.15` -> `14.0.12` -> `14.1.8` | Two intermediate versions are required: `13.12` and `14.0`, then `14.1.8`. |
| `13.12.15` | `12.9.2` | `12.9.2` -> `12.10.14` -> `13.0.14` -> `13.1.11` -> `13.8.8` -> `13.12.15` | Four intermediate versions are required: `12.10`, `13.0`, `13.1` and `13.8.8`, then `13.12.15`. |
| `13.2.10` | `11.5.0` | `11.5.0` -> `11.11.8` -> `12.0.12` -> `12.1.17` -> `12.10.14` -> `13.0.14` -> `13.1.11` -> `13.2.10` | Six intermediate versions are required: `11.11`, `12.0`, `12.1`, `12.10`, `13.0` and `13.1`, then `13.2.10`. |
| `12.10.14` | `11.3.4` | `11.3.4` -> `11.11.8` -> `12.0.12` -> `12.1.17` -> `12.10.14` | Three intermediate versions are required: `11.11`, `12.0` and `12.1`, then `12.10.14`. |
@@ -300,6 +358,8 @@ Edition, follow the guides below based on the installation method:
script, start the application and check its status.
- [Omnibus CE to EE](package/convert_to_ee.md) - Follow this guide to update your Omnibus
GitLab Community Edition to the Enterprise Edition.
+- [Docker CE to EE](../install/docker.md#convert-community-edition-to-enterprise-edition) -
+ Follow this guide to update your GitLab Community Edition container to an Enterprise Edition container.
### Enterprise to Community Edition
@@ -336,6 +396,36 @@ NOTE:
Specific information that follow related to Ruby and Git versions do not apply to [Omnibus installations](https://docs.gitlab.com/omnibus/)
and [Helm Chart deployments](https://docs.gitlab.com/charts/). They come with appropriate Ruby and Git versions and are not using system binaries for Ruby and Git. There is no need to install Ruby or Git when utilizing these two approaches.
+### 14.8.0
+
+- The agent server for Kubernetes [is enabled by default](https://about.gitlab.com/releases/2022/02/22/gitlab-14-8-released/#the-agent-server-for-kubernetes-is-enabled-by-default)
+ on Omnibus installations. If you run GitLab at scale,
+ such as [the reference architectures](../administration/reference_architectures/index.md),
+ you must disable the agent on the following server types, **if the agent is not required**.
+
+ - Praefect
+ - Gitaly
+ - Sidekiq
+ - Redis (if configured using `redis['enable'] = true` and not via `roles`)
+ - Container registry
+ - Any other server types based on `roles(['application_role'])`, such as the GitLab Rails nodes
+
+ [The reference architectures](../administration/reference_architectures/index.md) have been updated
+ with this configuration change and a specific role for standalone Redis servers.
+
+ Steps to disable the agent:
+
+ 1. Add `gitlab_kas['enable'] = false` to `gitlab.rb`.
+ 1. If the server is already upgraded to 14.8, run `gitlab-ctl reconfigure`.
+
+### 14.7.0
+
+- See [LFS objects import and mirror issue in GitLab 14.6.0 to 14.7.2](#lfs-objects-import-and-mirror-issue-in-gitlab-1460-to-1472).
+
+### 14.6.0
+
+- See [LFS objects import and mirror issue in GitLab 14.6.0 to 14.7.2](#lfs-objects-import-and-mirror-issue-in-gitlab-1460-to-1472).
+
### 14.5.0
- When `make` is run, Gitaly builds are now created in `_build/bin` and no longer in the root directory of the source directory. If you
@@ -364,6 +454,15 @@ or [init scripts](upgrading_from_source.md#configure-sysv-init-script) by [follo
For more information, refer to [this issue](https://gitlab.com/gitlab-org/gitlab/-/issues/331823).
+### 14.4.4
+
+- For [zero-downtime upgrades](zero_downtime.md) on a GitLab cluster with separate Web and API nodes, you need to enable the `paginated_tree_graphql_query` [feature flag](../administration/feature_flags.md#enable-or-disable-the-feature) _before_ upgrading GitLab Web nodes to 14.4.
+ This is because we [enabled `paginated_tree_graphql_query by default in 14.4](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/70913/diffs), so if GitLab UI is on 14.4 and its API is on 14.3, the frontend will have this feature enabled but the backend will have it disabled. This will result in the following error:
+
+ ```shell
+ bundle.esm.js:63 Uncaught (in promise) Error: GraphQL error: Field 'paginatedTree' doesn't exist on type 'Repository'
+ ```
+
### 14.4.0
- Git 2.33.x and later is required. We recommend you use the
@@ -585,6 +684,19 @@ Ruby 2.7.2 is required. GitLab does not start with Ruby 2.6.6 or older versions.
The required Git version is Git v2.29 or higher.
+GitLab 13.6 includes a
+[background migration `BackfillJiraTrackerDeploymentType2`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/46368)
+that may remain stuck permanently in a **pending** state despite completion of work
+due to a bug.
+
+To clean up this stuck job, run the following in the [GitLab Rails Console](../administration/operations/rails_console.md):
+
+```ruby
+Gitlab::Database::BackgroundMigrationJob.pending.where(class_name: "BackfillJiraTrackerDeploymentType2").find_each do |job|
+ puts Gitlab::Database::BackgroundMigrationJob.mark_all_as_succeeded("BackfillJiraTrackerDeploymentType2", job.arguments)
+end
+```
+
### 13.4.0
GitLab 13.4.0 includes a background migration to [move all remaining repositories in legacy storage to hashed storage](../administration/raketasks/storage.md#migrate-to-hashed-storage). There are [known issues with this migration](https://gitlab.com/gitlab-org/gitlab/-/issues/259605) which are fixed in GitLab 13.5.4 and later. If possible, skip 13.4.0 and upgrade to 13.5.4 or higher instead. Note that the migration can take quite a while to run, depending on how many repositories must be moved. Be sure to check that all background migrations have completed before upgrading further.
@@ -684,6 +796,12 @@ Users who were signed in before Maintenance mode was enabled will continue to be
[This bug](https://gitlab.com/gitlab-org/gitlab/-/issues/329261) was fixed in GitLab 14.5.0 and backported into 14.4.3 and 14.3.5.
+### LFS objects import and mirror issue in GitLab 14.6.0 to 14.7.2
+
+When Geo is enabled, LFS objects fail to be saved for imported or mirrored projects.
+
+[This bug](https://gitlab.com/gitlab-org/gitlab/-/issues/352368) was fixed in GitLab 14.8.0 and backported into 14.7.3.
+
## Miscellaneous
- [MySQL to PostgreSQL](mysql_to_postgresql.md) guides you through migrating
diff --git a/doc/update/package/convert_to_ee.md b/doc/update/package/convert_to_ee.md
index 2cc54e2c8cf..d5a71ba3e80 100644
--- a/doc/update/package/convert_to_ee.md
+++ b/doc/update/package/convert_to_ee.md
@@ -1,7 +1,7 @@
---
stage: Enablement
group: Distribution
-info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
# Convert Community Edition to Enterprise Edition **(FREE SELF)**
@@ -91,8 +91,8 @@ The steps can be summed up to:
sudo gitlab-ctl reconfigure
```
-1. Now go to the GitLab admin panel of your server (`/admin/license/new`) and
- upload your license file.
+1. Now go to the GitLab admin panel of your server (`/admin/subscription`) and
+ [add your license](../../user/admin_area/license.md).
1. After you confirm that GitLab is working as expected, you may remove the old
Community Edition repository:
diff --git a/doc/update/package/downgrade.md b/doc/update/package/downgrade.md
index 96b17a7632b..81f7d089bea 100644
--- a/doc/update/package/downgrade.md
+++ b/doc/update/package/downgrade.md
@@ -1,7 +1,7 @@
---
stage: Enablement
group: Distribution
-info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
# Downgrade **(FREE SELF)**
diff --git a/doc/update/package/index.md b/doc/update/package/index.md
index d7c18f15e44..b6417e10917 100644
--- a/doc/update/package/index.md
+++ b/doc/update/package/index.md
@@ -1,7 +1,7 @@
---
stage: Enablement
group: Distribution
-info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
# Upgrade GitLab by using the GitLab package **(FREE SELF)**
diff --git a/doc/update/plan_your_upgrade.md b/doc/update/plan_your_upgrade.md
index 665d2f6783e..6eebfd1b278 100644
--- a/doc/update/plan_your_upgrade.md
+++ b/doc/update/plan_your_upgrade.md
@@ -94,6 +94,8 @@ to roll back GitLab to a working state if there's a problem with the upgrade:
### Restore GitLab
+If you have a test environment that mimics your production one, we recommend testing the restoration to ensure that everything works as you expect.
+
To restore your GitLab backup:
- Before restoring, make sure to read about the
diff --git a/doc/update/removals.md b/doc/update/removals.md
index 9a28adf1f96..7e2b4f84fa1 100644
--- a/doc/update/removals.md
+++ b/doc/update/removals.md
@@ -28,6 +28,79 @@ For removal reviewers (Technical Writers only):
https://about.gitlab.com/handbook/marketing/blog/release-posts/#update-the-removals-doc
-->
+## 14.9
+
+### Integrated error tracking disabled by default
+
+WARNING:
+This feature was changed or removed in 14.9
+as a [breaking change](https://docs.gitlab.com/ee/development/contributing/#breaking-changes).
+Before updating GitLab, review the details carefully to determine if you need to make any
+changes to your code, settings, or workflow.
+
+In GitLab 14.4, GitLab released an integrated error tracking backend that replaces Sentry. This feature caused database performance issues. In GitLab 14.9, integrated error tracking is removed from GitLab.com, and turned off by default in GitLab self-managed. While we explore the future development of this feature, please consider switching to the Sentry backend by [changing your error tracking to Sentry in your project settings](https://docs.gitlab.com/ee/operations/error_tracking.html#sentry-error-tracking).
+
+For additional background on this removal, please reference [Disable Integrated Error Tracking by Default](https://gitlab.com/groups/gitlab-org/-/epics/7580). If you have feedback please add a comment to [Feedback: Removal of Integrated Error Tracking](https://gitlab.com/gitlab-org/gitlab/-/issues/355493).
+
+## 14.6
+
+### Limit the number of triggered pipeline to 25K in free tier
+
+A large amount of triggered pipelines in a single project impacts the performance of GitLab.com. In GitLab 14.6, we are limiting the number of triggered pipelines in a single project on GitLab.com at any given moment to 25,000. This change applies to projects in the free tier only, Premium and Ultimate are not affected by this change.
+
+### Release CLI distributed as a generic package
+
+The [release-cli](https://gitlab.com/gitlab-org/release-cli) will be released as a [generic package](https://gitlab.com/gitlab-org/release-cli/-/packages) starting in GitLab 14.2. We will continue to deploy it as a binary to S3 until GitLab 14.5 and stop distributing it in S3 in GitLab 14.6.
+
+## 14.3
+
+### Introduced limit of 50 tags for jobs
+
+GitLab values efficiency and is prioritizing reliability for [GitLab.com in FY22](https://about.gitlab.com/direction/#gitlab-hosted-first). In 14.3, GitLab CI/CD jobs must have less than 50 [tags](https://docs.gitlab.com/ee/ci/yaml/index.html#tags). If a pipeline contains a job with 50 or more tags, you will receive an error and the pipeline will not be created.
+
+### List project pipelines API endpoint removes `name` support in 14.3
+
+In GitLab 14.3, we will remove the ability to filter by `name` in the [list project pipelines API endpoint](https://docs.gitlab.com/ee/api/pipelines.html#list-project-pipelines) to improve performance. If you currently use this parameter with this endpoint, you must switch to `username`.
+
+### Use of legacy storage setting
+
+The support for [`gitlab_pages['use_legacy_storage']` setting](https://docs.gitlab.com/ee/administration/pages/index.html#domain-source-configuration-before-140) in Omnibus installations has been removed.
+
+In 14.0 we removed [`domain_config_source`](https://docs.gitlab.com/ee/administration/pages/index.html#domain-source-configuration-before-140) which had been previously deprecated, and allowed users to specify disk storage. In 14.0 we added `use_legacy_storage` as a **temporary** flag to unblock upgrades, and allow us to debug issues with our users and it was deprecated and communicated for removal in 14.3.
+
+## 14.2
+
+### Max job log file size of 100 MB
+
+GitLab values efficiency for all users in our wider community of contributors, so we're always working hard to make sure the application performs at a high level with a lovable UX.
+ In GitLab 14.2, we have introduced a [job log file size limit](https://docs.gitlab.com/ee/administration/instance_limits.html#maximum-file-size-for-job-logs), set to 100 megabytes by default. Administrators of self-managed GitLab instances can customize this to any value. All jobs that exceed this limit are dropped and marked as failed, helping prevent performance impacts or over-use of resources. This ensures that everyone using GitLab has the best possible experience.
+
+## 14.1
+
+### Remove support for `prometheus.listen_address` and `prometheus.enable`
+
+The support for `prometheus.listen_address` and `prometheus.enable` has been removed from `gitlab.yml`. Use `prometheus.enabled` and `prometheus.server_address` to set up Prometheus server that GitLab instance connects to. Refer to [our documentation](https://docs.gitlab.com/ee/install/installation.html#prometheus-server-setup) for details.
+
+This only affects new installations from source where users might use the old configurations.
+
+### Remove support for older browsers
+
+In GitLab 14.1, we are cleaning up and [removing old code](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/63994) that was specific for browsers that we no longer support. This has no impact on users when one of our [supported web browsers](https://docs.gitlab.com/ee/install/requirements.html#supported-web-browsers) is used.
+
+Most notably, support for the following browsers has been removed:
+
+- Apple Safari 13 and older.
+- Mozilla Firefox 68.
+- Pre-Chromium Microsoft Edge.
+
+The minimum supported browser versions are:
+
+- Apple Safari 13.1.
+- Mozilla Firefox 78.
+- Google Chrome 84.
+- Chromium 84.
+- Microsoft Edge 84.
+
## 14.0
### Auto Deploy CI template v1
@@ -510,8 +583,8 @@ As we continuously [develop GitLab's Terraform integrations](https://gitlab.com/
At every major release of GitLab, the "latest version" template becomes the "major version" template, inheriting the "latest template" setup.
As we have added many new features to the Terraform integration, the new setup for the "major version" template can be considered a breaking change.
-The latest template supports the [Terraform Merge Request widget](https://docs.gitlab.com/ee/user/infrastructure/mr_integration.html) and
-doesn't need additional setup to work with the [GitLab managed Terraform state](https://docs.gitlab.com/ee/user/infrastructure/terraform_state.html).
+The latest template supports the [Terraform Merge Request widget](https://docs.gitlab.com/ee/user/infrastructure/iac/mr_integration.html) and
+doesn't need additional setup to work with the [GitLab managed Terraform state](https://docs.gitlab.com/ee/user/infrastructure/iac/terraform_state.html).
To check the new changes, see the [new "major version" template](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Terraform.gitlab-ci.yml).
@@ -671,62 +744,3 @@ Before updating GitLab, review the details carefully to determine if you need to
changes to your code, settings, or workflow.
GitLab Runner was updated in GitLab 13.4 to internally stop passing the `trace` parameter to the `/api/jobs/:id` endpoint. GitLab 14.0 deprecates the `trace` parameter entirely for all other requests of this endpoint. Make sure your [GitLab Runner version matches your GitLab version](https://docs.gitlab.com/runner/#gitlab-runner-versions) to ensure consistent behavior.
-
-## 14.1
-
-### Remove support for `prometheus.listen_address` and `prometheus.enable`
-
-The support for `prometheus.listen_address` and `prometheus.enable` has been removed from `gitlab.yml`. Use `prometheus.enabled` and `prometheus.server_address` to set up Prometheus server that GitLab instance connects to. Refer to [our documentation](https://docs.gitlab.com/ee/install/installation.html#prometheus-server-setup) for details.
-
-This only affects new installations from source where users might use the old configurations.
-
-### Remove support for older browsers
-
-In GitLab 14.1, we are cleaning up and [removing old code](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/63994) that was specific for browsers that we no longer support. This has no impact on users when one of our [supported web browsers](https://docs.gitlab.com/ee/install/requirements.html#supported-web-browsers) is used.
-
-Most notably, support for the following browsers has been removed:
-
-- Apple Safari 13 and older.
-- Mozilla Firefox 68.
-- Pre-Chromium Microsoft Edge.
-
-The minimum supported browser versions are:
-
-- Apple Safari 13.1.
-- Mozilla Firefox 78.
-- Google Chrome 84.
-- Chromium 84.
-- Microsoft Edge 84.
-
-## 14.2
-
-### Max job log file size of 100 MB
-
-GitLab values efficiency for all users in our wider community of contributors, so we're always working hard to make sure the application performs at a high level with a lovable UX.
- In GitLab 14.2, we have introduced a [job log file size limit](https://docs.gitlab.com/ee/administration/instance_limits.html#maximum-file-size-for-job-logs), set to 100 megabytes by default. Administrators of self-managed GitLab instances can customize this to any value. All jobs that exceed this limit are dropped and marked as failed, helping prevent performance impacts or over-use of resources. This ensures that everyone using GitLab has the best possible experience.
-
-## 14.3
-
-### Introduced limit of 50 tags for jobs
-
-GitLab values efficiency and is prioritizing reliability for [GitLab.com in FY22](https://about.gitlab.com/direction/#gitlab-hosted-first). In 14.3, GitLab CI/CD jobs must have less than 50 [tags](https://docs.gitlab.com/ee/ci/yaml/index.html#tags). If a pipeline contains a job with 50 or more tags, you will receive an error and the pipeline will not be created.
-
-### List project pipelines API endpoint removes `name` support in 14.3
-
-In GitLab 14.3, we will remove the ability to filter by `name` in the [list project pipelines API endpoint](https://docs.gitlab.com/ee/api/pipelines.html#list-project-pipelines) to improve performance. If you currently use this parameter with this endpoint, you must switch to `username`.
-
-### Use of legacy storage setting
-
-The support for [`gitlab_pages['use_legacy_storage']` setting](https://docs.gitlab.com/ee/administration/pages/index.html#domain-source-configuration-before-140) in Omnibus installations has been removed.
-
-In 14.0 we removed [`domain_config_source`](https://docs.gitlab.com/ee/administration/pages/index.html#domain-source-configuration-before-140) which had been previously deprecated, and allowed users to specify disk storage. In 14.0 we added `use_legacy_storage` as a **temporary** flag to unblock upgrades, and allow us to debug issues with our users and it was deprecated and communicated for removal in 14.3.
-
-## 14.6
-
-### Limit the number of triggered pipeline to 25K in free tier
-
-A large amount of triggered pipelines in a single project impacts the performance of GitLab.com. In GitLab 14.6, we are limiting the number of triggered pipelines in a single project on GitLab.com at any given moment to 25,000. This change applies to projects in the free tier only, Premium and Ultimate are not affected by this change.
-
-### Release CLI distributed as a generic package
-
-The [release-cli](https://gitlab.com/gitlab-org/release-cli) will be released as a [generic package](https://gitlab.com/gitlab-org/release-cli/-/packages) starting in GitLab 14.2. We will continue to deploy it as a binary to S3 until GitLab 14.5 and stop distributing it in S3 in GitLab 14.6.
diff --git a/doc/update/zero_downtime.md b/doc/update/zero_downtime.md
index 050c5909934..d69d60fe73d 100644
--- a/doc/update/zero_downtime.md
+++ b/doc/update/zero_downtime.md
@@ -41,6 +41,8 @@ you check the release posts of any releases between your current and target
version just in case they include any migrations that may require you to upgrade
one release at a time.
+We also recommend you verify the [version specific upgrading instructions](index.md#version-specific-upgrading-instructions) relevant to your [upgrade path](index.md#upgrade-paths).
+
Some releases may also include so called "background migrations". These
migrations are performed in the background by Sidekiq and are often used for
migrating data. Background migrations are only added in the monthly releases.
diff --git a/doc/user/admin_area/analytics/usage_trends.md b/doc/user/admin_area/analytics/usage_trends.md
index a9c5adcf838..5f46908adb0 100644
--- a/doc/user/admin_area/analytics/usage_trends.md
+++ b/doc/user/admin_area/analytics/usage_trends.md
@@ -12,9 +12,6 @@ info: To determine the technical writer assigned to the Stage/Group associated w
> - It's enabled on GitLab.com.
> - It's recommended for production use.
-WARNING:
-This feature might not be available to you. Check the **version history** note above for details.
-
Usage Trends gives you an overview of how much data your instance contains, and how quickly this volume is changing over time.
Usage Trends data refreshes daily.
diff --git a/doc/user/admin_area/broadcast_messages.md b/doc/user/admin_area/broadcast_messages.md
index 987d7444ae0..69cb2f04c4d 100644
--- a/doc/user/admin_area/broadcast_messages.md
+++ b/doc/user/admin_area/broadcast_messages.md
@@ -7,7 +7,9 @@ type: reference, howto
# Broadcast messages **(FREE SELF)**
-GitLab can display broadcast messages to all users of a GitLab instance. There are two types of broadcast messages:
+> Target roles [introduced](https://gitlab.com/gitlab-org/growth/team-tasks/-/issues/461) in GitLab 14.8 [with a flag](../../administration/feature_flags.md) named `role_targeted_broadcast_messages`. Disabled by default.
+
+GitLab can display broadcast messages to users of a GitLab instance. There are two types of broadcast messages:
- Banners
- Notifications
@@ -66,6 +68,7 @@ To add a broadcast message:
- `text-decoration`
1. Select one of the suggested background colors, or add the hex code of a different color. The default color is orange.
1. Select the **Dismissable** checkbox to enable users to dismiss the broadcast message.
+1. Optional. Select **Target roles** to only show the broadcast message to users with the selected roles. The message displays on group, subgroup, and project pages, and does not display in Git remote responses.
1. If required, add a **Target Path** to only show the broadcast message on URLs matching that path. You can use the wildcard character `*` to match multiple URLs, for example `mygroup/myproject*`.
1. Select a date for the message to start and end.
1. Select **Add broadcast message**.
diff --git a/doc/user/admin_area/credentials_inventory.md b/doc/user/admin_area/credentials_inventory.md
index 437a72da767..21ac0f720ec 100644
--- a/doc/user/admin_area/credentials_inventory.md
+++ b/doc/user/admin_area/credentials_inventory.md
@@ -7,7 +7,8 @@ type: howto
# Credentials inventory **(ULTIMATE SELF)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/20912) in GitLab 12.6.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/20912) in GitLab 12.6.
+> - [Bot-created access tokens not displayed in personal access token list](https://gitlab.com/gitlab-org/gitlab/-/issues/351759) in GitLab 14.9.
GitLab administrators are responsible for the overall security of their instance. To assist, GitLab
provides a Credentials inventory to keep track of all the credentials that can be used to access
@@ -50,6 +51,8 @@ If you see a **Revoke** button, you can revoke that user's PAT. Whether you see
When a PAT is revoked from the credentials inventory, the instance notifies the user by email.
+![Credentials inventory page - Personal access tokens](img/credentials_inventory_personal_access_tokens_v14_9.png)
+
## Revoke a user's project access token
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/243833) in GitLab 14.8.
@@ -59,6 +62,8 @@ The **Revoke** button next to a project access token can be selected to revoke t
- Revoke the token project access token.
- Enqueue a background worker to delete the project bot user.
+![Credentials inventory page - Project access tokens](img/credentials_inventory_project_access_tokens_v14_9.png)
+
## Delete a user's SSH key
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/225248) in GitLab 13.5.
@@ -66,7 +71,7 @@ The **Revoke** button next to a project access token can be selected to revoke t
You can **Delete** a user's SSH key by navigating to the credentials inventory's SSH Keys tab.
The instance then notifies the user.
-![Credentials inventory page - SSH keys](img/credentials_inventory_ssh_keys_v13_5.png)
+![Credentials inventory page - SSH keys](img/credentials_inventory_ssh_keys_v14_9.png)
## Review existing GPG keys
@@ -80,4 +85,4 @@ credentials inventory GPG Keys tab, as well as the following properties:
- The ID of the GPG key.
- Whether the GPG key is [verified or unverified](../project/repository/gpg_signed_commits/index.md)
-![Credentials inventory page - GPG keys](img/credentials_inventory_gpg_keys_v13_10.png)
+![Credentials inventory page - GPG keys](img/credentials_inventory_gpg_keys_v14_9.png)
diff --git a/doc/user/admin_area/img/credentials_inventory_gpg_keys_v13_10.png b/doc/user/admin_area/img/credentials_inventory_gpg_keys_v13_10.png
deleted file mode 100644
index a88d80a72b6..00000000000
--- a/doc/user/admin_area/img/credentials_inventory_gpg_keys_v13_10.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/admin_area/img/credentials_inventory_gpg_keys_v14_9.png b/doc/user/admin_area/img/credentials_inventory_gpg_keys_v14_9.png
new file mode 100644
index 00000000000..6c4c8f30df6
--- /dev/null
+++ b/doc/user/admin_area/img/credentials_inventory_gpg_keys_v14_9.png
Binary files differ
diff --git a/doc/user/admin_area/img/credentials_inventory_personal_access_tokens_v14_9.png b/doc/user/admin_area/img/credentials_inventory_personal_access_tokens_v14_9.png
new file mode 100644
index 00000000000..254d520d538
--- /dev/null
+++ b/doc/user/admin_area/img/credentials_inventory_personal_access_tokens_v14_9.png
Binary files differ
diff --git a/doc/user/admin_area/img/credentials_inventory_project_access_tokens_v14_9.png b/doc/user/admin_area/img/credentials_inventory_project_access_tokens_v14_9.png
new file mode 100644
index 00000000000..ae204ac09ef
--- /dev/null
+++ b/doc/user/admin_area/img/credentials_inventory_project_access_tokens_v14_9.png
Binary files differ
diff --git a/doc/user/admin_area/img/credentials_inventory_ssh_keys_v13_5.png b/doc/user/admin_area/img/credentials_inventory_ssh_keys_v13_5.png
deleted file mode 100644
index f5edf513bbf..00000000000
--- a/doc/user/admin_area/img/credentials_inventory_ssh_keys_v13_5.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/admin_area/img/credentials_inventory_ssh_keys_v14_9.png b/doc/user/admin_area/img/credentials_inventory_ssh_keys_v14_9.png
new file mode 100644
index 00000000000..8f2f11515eb
--- /dev/null
+++ b/doc/user/admin_area/img/credentials_inventory_ssh_keys_v14_9.png
Binary files differ
diff --git a/doc/user/admin_area/index.md b/doc/user/admin_area/index.md
index 57a4a746ff0..4a334c28496 100644
--- a/doc/user/admin_area/index.md
+++ b/doc/user/admin_area/index.md
@@ -30,7 +30,7 @@ The Admin Area is made up of the following sections:
| **{hook}** System Hooks | Configure [system hooks](../../system_hooks/system_hooks.md) for many events. |
| **{applications}** Applications | Create system [OAuth applications](../../integration/oauth_provider.md) for integrations with other services. |
| **{slight-frown}** Abuse Reports | Manage [abuse reports](review_abuse_reports.md) submitted by your users. |
-| **{license}** License | Upload, display, and remove [licenses](license.md). |
+| **{license}** License | Add, display, and remove [licenses](license.md). |
| **{cloud-gear}** Kubernetes | Create and manage instance-level [Kubernetes clusters](../instance/clusters/index.md). |
| **{push-rules}** Push rules | Configure pre-defined Git [push rules](../project/repository/push_rules.md) for projects. Also, configure [merge requests approvers rules](merge_requests_approvals.md). |
| **{location-dot}** Geo | Configure and maintain [Geo nodes](geo_nodes.md). |
@@ -218,6 +218,17 @@ You must be an administrator to manually add emails to users:
The [Cohorts](user_cohorts.md) tab displays the monthly cohorts of new users and their activities over time.
+### Prevent a user from creating groups
+
+By default, users can create groups. To prevent a user from creating groups:
+
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Overview > Users** (`/admin/users`).
+1. Locate the user and select them.
+1. Select **Edit**.
+1. Clear the **Can create group** checkbox.
+1. Select **Save changes**.
+
### Administering Groups
You can administer all groups in the GitLab instance from the Admin Area's Groups page.
diff --git a/doc/user/admin_area/license.md b/doc/user/admin_area/license.md
index 22133e30aa0..bee784e850b 100644
--- a/doc/user/admin_area/license.md
+++ b/doc/user/admin_area/license.md
@@ -1,183 +1,57 @@
---
-stage: Growth
-group: Conversion
+stage: Fulfillment
+group: License
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
# Activate GitLab Enterprise Edition (EE) **(PREMIUM SELF)**
-When you install a new GitLab instance without a license, it only has the Free features
-enabled. To enable all features of GitLab Enterprise Edition (EE), activate
-your instance with an activation code or a license file. When [the license expires](#what-happens-when-your-license-expires),
-some functionality is locked.
-
-## Verify your GitLab edition
+When you install a new GitLab instance without a license, only Free features
+are enabled. To enable more features in GitLab Enterprise Edition (EE), activate
+your instance with an activation code.
-To activate your instance, make sure you are running GitLab Enterprise Edition (EE).
+## Activate GitLab EE
-To verify the edition, sign in to GitLab and select
-**Help** (**{question-o}**) > **Help**. The GitLab edition and version are listed
-at the top of the page.
-
-If you are running GitLab Community Edition (CE), upgrade your installation to GitLab
-EE. For more details, see [Upgrading between editions](../../update/index.md#upgrading-between-editions).
-If you have questions or need assistance upgrading from GitLab CE to EE,
-[contact GitLab Support](https://about.gitlab.com/support/#contact-support).
+In GitLab Enterprise Edition 14.1 and later, you need an activation code to activate
+your instance.
-## Activate GitLab EE with an activation code
+Prerequisite:
-In GitLab Enterprise Edition 14.1 and later, you need an activation code to activate
-your instance. To get an activation code you have to [purchase a license](https://about.gitlab.com/pricing/).
-The activation code is a 24-character alphanumeric string you receive in a confirmation email.
-You can also sign in to the [Customers Portal](https://customers.gitlab.com/customers/sign_in)
-to copy the activation code to your clipboard.
+- You must [purchase a subscription](https://about.gitlab.com/pricing/).
+- You must be running GitLab Enterprise Edition (EE).
+- You must have GitLab 14.1 or later.
+- Your instance must be connected to the internet.
To activate your instance with an activation code:
+1. Copy the activation code, a 24-character alphanumeric string, from either:
+ - Your subscription confirmation email.
+ - The [Customers Portal](https://customers.gitlab.com/customers/sign_in), on the **Manage Purchases** page.
1. Sign in to your GitLab self-managed instance.
1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Subscription**.
-1. Enter the activation code in **Activation code**.
+1. Paste the activation code in **Activation code**.
1. Read and accept the terms of service.
1. Select **Activate**.
-## Activate GitLab EE with a license file
-
-If you receive a license file from GitLab (for example, for a trial), you can
-upload it to your instance or add it during installation. The license file is
-a base64-encoded ASCII text file with a `.gitlab-license` extension.
+The subscription is activated.
-## Upload your license
-
-The first time you sign in to your GitLab instance, a note with a
-link to the **Upload license** page should be displayed.
-
-Otherwise, to upload your license:
-
-1. Sign in to GitLab as an administrator.
-1. On the top bar, select **Menu > Admin**.
-1. On the left sidebar, select **Settings**.
-1. In the **License file** area, select **Upload a license**.
-1. Upload a license:
- - For a file, either:
- - Select **Upload `.gitlab-license` file**, then **Choose File** and
- select the license file from your local machine.
- - Drag and drop the license file to the **Drag your license file here** area.
- - For plain text, select **Enter license key** and paste the contents in
- **License key**.
-1. Select the **Terms of Service** checkbox.
-1. Select **Upload License**.
-
-## Add your license during installation
-
-You can import a license file when you install GitLab.
-
-- **For installations from source**
- - Place the `Gitlab.gitlab-license` file in the `config/` directory.
- - To specify a custom location and filename for the license, set the
- `GITLAB_LICENSE_FILE` environment variable with the path to the file:
-
- ```shell
- export GITLAB_LICENSE_FILE="/path/to/license/file"
- ```
-
-- **For Omnibus package**
- - Place the `Gitlab.gitlab-license` file in the `/etc/gitlab/` directory.
- - To specify a custom location and filename for the license, add this entry to `gitlab.rb`:
-
- ```ruby
- gitlab_rails['initial_license_file'] = "/path/to/license/file"
- ```
-
-WARNING:
-These methods only add a license at the time of installation. To renew or upgrade
-a license, upload the license in the **Admin Area** in the web user interface.
-
-## What happens when your license expires
-
-Fifteen days before the license expires, a notification banner with the upcoming expiration
-date displays to GitLab administrators.
-
-When your license expires, GitLab locks features, like Git pushes
-and issue creation. Your instance becomes read-only and
-an expiration message displays to all administrators. You have a 14-day grace period
-before this occurs.
-
-To resume functionality, [upload a new license](#upload-your-license).
-
-To go back to Free features, [delete all expired licenses](#remove-a-license-file).
-
-## Remove a license file
-
-To remove a license file from a self-managed instance:
-
-1. On the top bar, select **Menu > Admin**.
-1. On the left sidebar, select **Subscription**.
-1. Select **Remove license**.
-
-Repeat these steps to remove all licenses, including those applied in the past.
-
-## View license details and history
-
-To view your license details:
-
-1. On the top bar, select **Menu > Admin**.
-1. On the left sidebar, select **Subscription**.
-
-You can upload and view more than one license, but only the latest license in
-the current date range is the active license.
-
-When you upload a future-dated license, it doesn't take effect until its applicable date.
-You can view all active subscriptions in the **Subscription history** table.
-
-You can also [export](../../subscriptions/self_managed/index.md) your license usage information to a CSV file.
-
-NOTE:
-In GitLab 13.6 and earlier, a banner about an expiring license may continue to display
-when you upload a new license. This happens when the start date of the new license
-is in the future and the expiring one is still active.
-The banner disappears after the new license becomes active.
-
-## Troubleshooting
-
-### No Subscription area in the Admin Area
-
-You cannot upload your license because there is no **Subscription** area.
-This issue might occur if:
-
-- You're running GitLab Community Edition. Before you upload your license, you
- must [upgrade to Enterprise Edition](../../update/index.md#community-to-enterprise-edition).
-- You're using GitLab.com. You cannot upload a self-managed license to GitLab.com.
- To use paid features on GitLab.com, [purchase a separate subscription](../../subscriptions/gitlab_com/index.md).
-
-### Users exceed license limit upon renewal
-
-GitLab displays a message prompting you to purchase
-additional users. This issue occurs if you upload a license that does not have enough
-users to cover the number of users in your instance.
-
-To fix this issue, purchase additional seats to cover those users.
-For more information, read the [licensing FAQ](https://about.gitlab.com/pricing/licensing-faq/).
-
-In GitLab 14.2 and later, for instances that use a license file, the following
-rules apply:
-
-- If the users over license are less than or equal to 10% of the users in the license
- file, the license is applied and you pay the overage in the next renewal.
-- If the users over license are more than 10% of the users in the license file,
- you cannot apply the license without purchasing more users.
+If you have an offline or airgapped environment,
+[activate GitLab EE with a license file or key](license_file.md) instead.
-For example, if you purchase a license for 100 users, you can have 110 users when you activate
-your license. However, if you have 111 users, you must purchase more users before you can activate
-the license.
+If you have questions or need assistance activating your instance,
+[contact GitLab Support](https://about.gitlab.com/support/#contact-support).
-### Cannot activate instance due to connectivity error
+When [the license expires](license_file.md#what-happens-when-your-license-expires),
+some functionality is locked.
-In GitLab 14.1 and later, to activate your subscription with an activation code,
-your GitLab instance must be connected to the internet.
+## Verify your GitLab edition
-If you have an offline or airgapped environment,
-[upload a license file](license.md#activate-gitlab-ee-with-a-license-file) instead.
+To verify the edition, sign in to GitLab and select
+**Help** (**{question-o}**) > **Help**. The GitLab edition and version are listed
+at the top of the page.
-If you have questions or need assistance activating your instance,
+If you are running GitLab Community Edition (CE), you can upgrade your installation to GitLab
+EE. For more details, see [Upgrading between editions](../../update/index.md#upgrading-between-editions).
+If you have questions or need assistance upgrading from GitLab CE to EE,
[contact GitLab Support](https://about.gitlab.com/support/#contact-support).
diff --git a/doc/user/admin_area/license_file.md b/doc/user/admin_area/license_file.md
new file mode 100644
index 00000000000..e0332e70681
--- /dev/null
+++ b/doc/user/admin_area/license_file.md
@@ -0,0 +1,127 @@
+---
+stage: Fulfillment
+group: License
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
+---
+
+# Activate GitLab EE with a license file or key
+
+If you receive a license file from GitLab (for example, for a trial), you can
+upload it to your instance or add it during installation. The license file is
+a base64-encoded ASCII text file with a `.gitlab-license` extension.
+
+The first time you sign in to your GitLab instance, a note with a
+link to the **Add license** page should be displayed.
+
+Otherwise, to add your license:
+
+1. Sign in to GitLab as an administrator.
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Settings > General**.
+1. In the **License file** area, select **Add a license**.
+1. Add a license by either uploading the file or pasting the key.
+1. Select the **Terms of Service** checkbox.
+1. Select **Add license**.
+
+## Add your license during installation
+
+You can import a license file when you install GitLab.
+
+- **For installations from source**
+ - Place the `Gitlab.gitlab-license` file in the `config/` directory.
+ - To specify a custom location and filename for the license, set the
+ `GITLAB_LICENSE_FILE` environment variable with the path to the file:
+
+ ```shell
+ export GITLAB_LICENSE_FILE="/path/to/license/file"
+ ```
+
+- **For Omnibus package**
+ - Place the `Gitlab.gitlab-license` file in the `/etc/gitlab/` directory.
+ - To specify a custom location and filename for the license, add this entry to `gitlab.rb`:
+
+ ```ruby
+ gitlab_rails['initial_license_file'] = "/path/to/license/file"
+ ```
+
+WARNING:
+These methods only add a license at the time of installation. To renew or upgrade
+a license, add the license in the **Admin Area** in the web user interface.
+
+## What happens when your license expires
+
+Fifteen days before the license expires, a notification banner with the upcoming expiration
+date displays to GitLab administrators.
+
+When your license expires, GitLab locks features, like Git pushes
+and issue creation. Your instance becomes read-only and
+an expiration message displays to all administrators. You have a 14-day grace period
+before this occurs.
+
+To resume functionality, activate a new subscription.
+
+To go back to Free features, [delete all expired licenses](#remove-a-license).
+
+## Remove a license
+
+To remove a license from a self-managed instance:
+
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Subscription**.
+1. Select **Remove license**.
+
+Repeat these steps to remove all licenses, including those applied in the past.
+
+## View license details and history
+
+To view your license details:
+
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Subscription**.
+
+You can add and view more than one license, but only the latest license in
+the current date range is the active license.
+
+When you add a future-dated license, it doesn't take effect until its applicable date.
+You can view all active subscriptions in the **Subscription history** table.
+
+You can also [export](../../subscriptions/self_managed/index.md) your license usage information to a CSV file.
+
+NOTE:
+In GitLab 13.6 and earlier, a banner about an expiring license may continue to display
+when you add a new license. This happens when the start date of the new license
+is in the future and the expiring one is still active.
+The banner disappears after the new license becomes active.
+
+## Troubleshooting
+
+### No Subscription area in the Admin Area
+
+You cannot add your license because there is no **Subscription** area.
+This issue might occur if:
+
+- You're running GitLab Community Edition. Before you add your license, you
+ must [upgrade to Enterprise Edition](../../update/index.md#community-to-enterprise-edition).
+- You're using GitLab.com. You cannot add a self-managed license to GitLab.com.
+ To use paid features on GitLab.com, [purchase a separate subscription](../../subscriptions/gitlab_com/index.md).
+
+### Users exceed license limit upon renewal
+
+GitLab displays a message prompting you to purchase
+additional users. This issue occurs if you add a license that does not have enough
+users to cover the number of users in your instance.
+
+To fix this issue, purchase additional seats to cover those users.
+For more information, read the [licensing FAQ](https://about.gitlab.com/pricing/licensing-faq/).
+
+In GitLab 14.2 and later, for instances that use a license file, the following
+rules apply:
+
+- If the users over license are less than or equal to 10% of the users in the license
+ file, the license is applied and you pay the overage in the next renewal.
+- If the users over license are more than 10% of the users in the license file,
+ you cannot apply the license without purchasing more users.
+
+For example, if you purchase a license for 100 users, you can have 110 users when you add
+your license. However, if you have 111 users, you must purchase more users before you can add
+the license.
diff --git a/doc/user/admin_area/reporting/spamcheck.md b/doc/user/admin_area/reporting/spamcheck.md
index 02d7cd01139..559235fe322 100644
--- a/doc/user/admin_area/reporting/spamcheck.md
+++ b/doc/user/admin_area/reporting/spamcheck.md
@@ -1,13 +1,16 @@
---
stage: Enablement
group: Distribution
-info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
-# Spamcheck anti-spam service **(PREMIUM SELF)**
+# Spamcheck anti-spam service **(FREE SELF)**
> [Introduced](https://gitlab.com/gitlab-org/omnibus-gitlab/-/issues/6259) in GitLab 14.8.
+WARNING:
+Spamcheck is available to all tiers, but only on instances using GitLab Enterprise Edition (EE). For [licensing reasons](https://gitlab.com/gitlab-org/omnibus-gitlab/-/issues/6259#note_726605397), it is not included in the GitLab Community Edition (CE) package. You can [migrate from CE to EE](../../../update/package/convert_to_ee.md).
+
[Spamcheck](https://gitlab.com/gitlab-org/spamcheck) is an anti-spam engine
developed by GitLab originally to combat rising amount of spam in GitLab.com,
and later made public to be used in self-managed GitLab instances.
@@ -47,7 +50,7 @@ Spamcheck is only available for package-based installations:
1. Select **Save changes**.
NOTE:
-In single-node instances, Spamcehck runs over `localhost`, and hence is running
+In single-node instances, Spamcheck runs over `localhost`, and hence is running
in an unauthenticated mode. If on multi-node instances where GitLab runs on one
server and Spamcheck runs on another server listening over a public endpoint, it
is recommended to enforce some sort of authentication using a reverse proxy in
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 1d982196228..2f30298644a 100644
--- a/doc/user/admin_area/settings/account_and_limit_settings.md
+++ b/doc/user/admin_area/settings/account_and_limit_settings.md
@@ -178,14 +178,9 @@ nginx['client_max_body_size'] = "200m"
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/296669) in GitLab 13.9.
> - It's deployed behind a feature flag, disabled by default.
-> - It's disabled on GitLab.com.
-> - It's not recommended for production use.
-> - To use it in GitLab self-managed instances, ask a GitLab administrator to [enable it](../../../security/two_factor_authentication.md#enable-or-disable-2fa-for-git-operations).
-NOTE:
-This feature is under development and not ready for production use. It is deployed
-behind a feature flag that is **disabled by default**. To use it in GitLab
-self-managed instances, ask a GitLab administrator to [enable it](../../../security/two_factor_authentication.md#enable-or-disable-2fa-for-git-operations).
+FLAG:
+On self-managed GitLab, by default this feature is not available. To make it available, ask an administrator to [enable the feature flag](../../../administration/feature_flags.md) named `two_factor_for_cli`. On GitLab.com, this feature is not available. This feature is not ready for production use. This feature flag also affects [2FA for Git over SSH operations](../../../security/two_factor_authentication.md#2fa-for-git-over-ssh-operations).
GitLab administrators can choose to customize the session duration (in minutes) for Git operations when 2FA is enabled. The default is 15 and this can be set to a value between 1 and 10080.
diff --git a/doc/user/admin_area/settings/continuous_integration.md b/doc/user/admin_area/settings/continuous_integration.md
index 18379471bcf..0330d89aedc 100644
--- a/doc/user/admin_area/settings/continuous_integration.md
+++ b/doc/user/admin_area/settings/continuous_integration.md
@@ -55,31 +55,28 @@ can be set at:
- The instance level.
- [From GitLab 12.4](https://gitlab.com/gitlab-org/gitlab/-/issues/21688), the project and group level.
-The value is:
+For the setting on GitLab.com, see [Artifacts maximum size](../../gitlab_com/index.md#gitlab-cicd).
-- In *MB* and the default is 100MB per job.
-- [Set to 1G](../../gitlab_com/index.md#gitlab-cicd) on GitLab.com.
-
-To change it at the:
+The value is in MB and the default is 100MB per job. To change it at the:
- Instance level:
1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Settings > CI/CD**.
1. Change the value of maximum artifacts size (in MB).
- 1. Click **Save changes** for the changes to take effect.
+ 1. Select **Save changes** for the changes to take effect.
- Group level (this overrides the instance setting):
1. Go to the group's **Settings > CI/CD > General Pipelines**.
1. Change the value of **maximum artifacts size (in MB)**.
- 1. Click **Save changes** for the changes to take effect.
+ 1. Select **Save changes** for the changes to take effect.
- Project level (this overrides the instance and group settings):
1. Go to the project's **Settings > CI/CD > General Pipelines**.
1. Change the value of **maximum artifacts size (in MB)**.
- 1. Click **Save changes** for the changes to take effect.
+ 1. Select **Save changes** for the changes to take effect.
NOTE:
The setting at all levels is only available to GitLab administrators.
@@ -94,7 +91,7 @@ and the default value is `30 days`.
1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Settings > CI/CD**.
1. Change the value of default expiration time.
-1. Click **Save changes** for the changes to take effect.
+1. Select **Save changes** for the changes to take effect.
This setting is set per job and can be overridden in
[`.gitlab-ci.yml`](../../../ci/yaml/index.md#artifactsexpire_in).
@@ -126,7 +123,7 @@ To disable the setting:
1. On the left sidebar, select **Settings > CI/CD**.
1. Expand **Continuous Integration and Deployment**.
1. Clear the **Keep the latest artifacts for all jobs in the latest successful pipelines** checkbox.
-1. Click **Save changes**
+1. Select **Save changes**
When you disable the feature, the latest artifacts do not immediately expire.
A new pipeline must run before the latest artifacts can expire and be deleted.
@@ -156,7 +153,7 @@ After that time passes, the jobs are 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>.
-As of June 22, 2020 the [value is set](../../gitlab_com/index.md#gitlab-cicd) to 3 months on GitLab.com. Jobs created before that date were archived after September 22, 2020.
+For the value set for GitLab.com, see [Scheduled job archiving](../../gitlab_com/index.md#gitlab-cicd).
## Protect CI/CD variables by default
@@ -233,7 +230,7 @@ To select a CI/CD template for the required pipeline configuration:
1. On the left sidebar, select **Settings > CI/CD**.
1. Expand the **Required pipeline configuration** section.
1. Select a CI/CD template from the dropdown.
-1. Click **Save changes**.
+1. Select **Save changes**.
## Package Registry configuration
@@ -272,7 +269,7 @@ To set the maximum file size:
1. Expand the **Package Registry** section.
1. Find the package type you would like to adjust.
1. Enter the maximum file size, in bytes.
-1. Click **Save size limits**.
+1. Select **Save size limits**.
## Prevent users from registering runners
diff --git a/doc/user/admin_area/settings/gitaly_timeouts.md b/doc/user/admin_area/settings/gitaly_timeouts.md
index fac23cb48af..42e0c9faf9f 100644
--- a/doc/user/admin_area/settings/gitaly_timeouts.md
+++ b/doc/user/admin_area/settings/gitaly_timeouts.md
@@ -22,6 +22,6 @@ The following timeouts are available.
| Timeout | Default | Description |
|:--------|:-----------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| Default | 55 seconds | Timeout for most Gitaly calls (not enforced for `git` `fetch` and `push` operations, or Sidekiq jobs). For example, checking if a repository exists on disk. Makes sure that Gitaly calls made within a web request cannot exceed the entire request timeout. It should be shorter than the [worker timeout](../../../administration/operations/puma.md#worker-timeout) that can be configured for [Puma](../../../install/requirements.md#puma-settings). If a Gitaly call timeout exceeds the worker timeout, the remaining time from the worker timeout is used to avoid having to terminate the worker. |
+| Default | 55 seconds | Timeout for most Gitaly calls (not enforced for `git` `fetch` and `push` operations, or Sidekiq jobs). For example, checking if a repository exists on disk. Makes sure that Gitaly calls made within a web request cannot exceed the entire request timeout. It should be shorter than the [worker timeout](../../../administration/operations/puma.md#change-the-worker-timeout) that can be configured for [Puma](../../../install/requirements.md#puma-settings). If a Gitaly call timeout exceeds the worker timeout, the remaining time from the worker timeout is used to avoid having to terminate the worker. |
| Fast | 10 seconds | Timeout for fast Gitaly operations used within requests, sometimes multiple times. For example, checking if a repository exists on disk. If fast operations exceed this threshold, there may be a problem with a storage shard. Failing fast can help maintain the stability of the GitLab instance. |
| Medium | 30 seconds | Timeout for Gitaly operations that should be fast (possibly within requests) but preferably not used multiple times within a request. For example, loading blobs. Timeout that should be set between Default and Fast. |
diff --git a/doc/user/admin_area/settings/index.md b/doc/user/admin_area/settings/index.md
index a581fd4aebc..052b6e26c07 100644
--- a/doc/user/admin_area/settings/index.md
+++ b/doc/user/admin_area/settings/index.md
@@ -130,6 +130,7 @@ The **Network** settings contain:
Git LFS requests that supersede the user and IP rate limits.
- [Files API Rate Limits](files_api_rate_limits.md) - Configure specific limits for
Files API requests that supersede the user and IP rate limits.
+ - [Search rate limits](../../../administration/instance_limits.md#search-rate-limit) - Configure global search request rate limits for authenticated and unauthenticated users.
- [Deprecated API Rate Limits](deprecated_api_rate_limits.md) - Configure specific limits
for deprecated API requests that supersede the user and IP rate limits.
- [Outbound requests](../../../security/webhooks.md) - Allow requests to the local network from hooks and services.
@@ -170,6 +171,8 @@ The **Repository** settings contain:
- [Repository's custom initial branch name](../../project/repository/branches/default.md#instance-level-custom-initial-branch-name) -
Set a custom branch name for new repositories created in your instance.
+- [Repository's initial default branch protection](../../project/repository/branches/default.md#instance-level-default-branch-protection) -
+ Configure the branch protections to apply to every repository's default branch.
- [Repository mirror](visibility_and_access_controls.md#enable-project-mirroring) -
Configure repository mirroring.
- [Repository storage](../../../administration/repository_storage_types.md) - Configure storage path settings.
diff --git a/doc/user/admin_area/settings/user_and_ip_rate_limits.md b/doc/user/admin_area/settings/user_and_ip_rate_limits.md
index 88be73c3215..56e240a8d39 100644
--- a/doc/user/admin_area/settings/user_and_ip_rate_limits.md
+++ b/doc/user/admin_area/settings/user_and_ip_rate_limits.md
@@ -107,7 +107,7 @@ attached into the response headers.
| `RateLimit-Limit` | `60` | The request quota for the client **each minute**. If the rate limit period set in the admin area is different from 1 minute, the value of this header is adjusted to approximately the nearest 60-minute period. |
| `RateLimit-Name` | `throttle_authenticated_web` | Name of the throttle blocking the requests. |
| `RateLimit-Observed` | `67` | Number of requests associated to the client in the time window. |
-| `RateLimit-Remaining` | `0` | Remaining quota in the time window. The result of `RateLimit-Limit` - `RateLimit-Remaining`. |
+| `RateLimit-Remaining` | `0` | Remaining quota in the time window. The result of `RateLimit-Limit` - `RateLimit-Observed`. |
| `RateLimit-Reset` | `1609844400` | [Unix time](https://en.wikipedia.org/wiki/Unix_time)-formatted time when the request quota is reset. |
| `RateLimit-ResetTime` | `Tue, 05 Jan 2021 11:00:00 GMT` | [RFC2616](https://tools.ietf.org/html/rfc2616#section-3.3.1)-formatted date and time when the request quota is reset. |
| `Retry-After` | `30` | Remaining duration **in seconds** until the quota is reset. This is a [standard HTTP header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After). |
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 c38b2455a8d..2165dc54899 100644
--- a/doc/user/admin_area/settings/visibility_and_access_controls.md
+++ b/doc/user/admin_area/settings/visibility_and_access_controls.md
@@ -17,54 +17,6 @@ To access the visibility and access control options:
1. On the left sidebar, select **Settings > General**.
1. Expand the **Visibility and access controls** section.
-## Protect default branches
-
-With this option, you can define [branch protections](../../project/protected_branches.md)
-to apply to every repository's [default branch](../../project/repository/branches/default.md).
-These protections specify the user roles with permission to push to default branches.
-
-This setting applies only to each repository's default branch. To protect other branches,
-you must configure [branch protection in the repository](../../project/protected_branches.md),
-or configure [branch protection for groups](../../group/index.md#change-the-default-branch-protection-of-a-group).
-
-To change the default branch protection for the entire instance:
-
-1. Sign in to GitLab as a user with Administrator access level.
-1. On the top bar, select **Menu > Admin**.
-1. On the left sidebar, select **Settings > General**.
-1. Expand the **Visibility and access controls** section.
-1. Select a **Default branch protection**:
- - **Not protected** - Both developers and maintainers can push new commits
- and force push.
- - **Protected against pushes** - Developers cannot push new commits, but are
- allowed to accept merge requests to the branch. Maintainers can push to the branch.
- - **Partially protected** - Both developers and maintainers can push new commits,
- but cannot force push.
- - **Fully protected** - Developers cannot push new commits, but maintainers can.
- No one can force push.
-1. To allow group owners to override the instance's default branch protection, select
- [**Allow owners to manage default branch protection per group**](#prevent-overrides-of-default-branch-protection).
-1. Select **Save changes**.
-
-### Prevent overrides of default branch protection **(PREMIUM SELF)**
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/211944) in GitLab 13.0.
-
-Instance-level protections for [default branch](../../project/repository/branches/default.md)
-can be overridden on a per-group basis by the group's owner. In
-[GitLab Premium or higher](https://about.gitlab.com/pricing/), GitLab administrators can
-disable this privilege for group owners, enforcing the instance-level protection rule:
-
-1. Sign in to GitLab as a user with Administrator access level.
-1. On the top bar, select **Menu > Admin**.
-1. On the left sidebar, select **Settings > General**.
-1. Expand the **Visibility and access controls** section.
-1. Deselect the **Allow owners to manage default branch protection per group** checkbox.
-1. Select **Save changes**.
-
-NOTE:
-GitLab administrators can still update the default branch protection of a group.
-
## Define which roles can create projects
Instance-level protections for project creation define which roles can
diff --git a/doc/user/analytics/ci_cd_analytics.md b/doc/user/analytics/ci_cd_analytics.md
index 1bc0c2b8fb0..8e231d18f41 100644
--- a/doc/user/analytics/ci_cd_analytics.md
+++ b/doc/user/analytics/ci_cd_analytics.md
@@ -4,13 +4,13 @@ group: Release
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
-# CI/CD Analytics **(FREE)**
+# CI/CD analytics **(FREE)**
## Pipeline success and duration charts
> [Renamed](https://gitlab.com/gitlab-org/gitlab/-/issues/38318) to CI/CD Analytics in GitLab 12.8.
-CI/CD Analytics shows the history of your pipeline successes and failures, as well as how long each pipeline
+CI/CD analytics shows the history of your pipeline successes and failures, as well as how long each pipeline
ran.
View successful pipelines:
@@ -39,21 +39,14 @@ To view CI/CD analytics:
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/275991) in GitLab 13.7.
> - [Added support](https://gitlab.com/gitlab-org/gitlab/-/issues/291746) for lead time for changes in GitLab 13.10.
-Customer experience is a key metric. Users want to measure platform stability and other
-post-deployment performance KPIs, and set targets for customer behavior, experience, and financial
-impact. Tracking and measuring these indicators solves an important pain point. Similarly, creating
-views that manage products, not projects or repositories, provides users with a more relevant data set.
-Since GitLab is a tool for the entire DevOps life-cycle, information from different workflows is
-integrated and can be used to measure the success of the teams.
-
The DevOps Research and Assessment ([DORA](https://cloud.google.com/blog/products/devops-sre/the-2019-accelerate-state-of-devops-elite-performance-productivity-and-scaling))
-team developed four key metrics that the industry has widely adopted. You can use these metrics as
-performance indicators for software development teams:
+team developed several key metrics that you can use as performance indicators for software development
+teams:
- Deployment frequency: How often an organization successfully releases to production.
- Lead time for changes: The amount of time it takes for code to reach production.
- Change failure rate: The percentage of deployments that cause a failure in production.
-- Time to restore service: How long it takes an organization to recover from a failure in
+- Time to restore service: How long it takes for an organization to recover from a failure in
production.
### Supported metrics in GitLab
@@ -62,39 +55,48 @@ The following table shows the supported metrics, at which level they are support
| Metric | Level | API version | Chart (UI) version | Comments |
|---------------------------|---------------------|--------------------------------------|---------------------------------------|-----------|
-| `deployment_frequency` | Project-level | [13.7+](../../api/dora/metrics.md) | [13.8+](#deployment-frequency-charts) | The [old API endpoint](../../api/dora4_project_analytics.md) was [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/323713) in 13.10. |
-| `deployment_frequency` | Group-level | [13.10+](../../api/dora/metrics.md) | [13.12+](#deployment-frequency-charts) | |
-| `lead_time_for_changes` | Project-level | [13.10+](../../api/dora/metrics.md) | [13.11+](#lead-time-charts) | Unit in seconds. Aggregation method is median. |
-| `lead_time_for_changes` | Group-level | [13.10+](../../api/dora/metrics.md) | [14.0+](#lead-time-charts) | Unit in seconds. Aggregation method is median. |
+| `deployment_frequency` | Project-level | [13.7+](../../api/dora/metrics.md) | [13.8+](#view-deployment-frequency-chart) | The [old API endpoint](../../api/dora4_project_analytics.md) was [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/323713) in 13.10. |
+| `deployment_frequency` | Group-level | [13.10+](../../api/dora/metrics.md) | [13.12+](#view-deployment-frequency-chart) | |
+| `lead_time_for_changes` | Project-level | [13.10+](../../api/dora/metrics.md) | [13.11+](#view-lead-time-for-changes-chart) | Unit in seconds. Aggregation method is median. |
+| `lead_time_for_changes` | Group-level | [13.10+](../../api/dora/metrics.md) | [14.0+](#view-lead-time-for-changes-chart) | Unit in seconds. Aggregation method is median. |
| `change_failure_rate` | Project/Group-level | To be supported | To be supported | |
| `time_to_restore_service` | Project/Group-level | To be supported | To be supported | |
-### Deployment frequency charts
+## View deployment frequency chart **(ULTIMATE)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/275991) in GitLab 13.8.
-The **Analytics > CI/CD Analytics** page shows information about the deployment
+The deployment frequency charts show information about the deployment
frequency to the `production` environment. The environment must be part of the
[production deployment tier](../../ci/environments/index.md#deployment-tier-of-environments)
for its deployment information to appear on the graphs.
-![Deployment frequency](img/deployment_frequency_charts_v13_12.png)
+The deployment frequency chart is available for groups and projects.
+
+To view the deployment frequency chart:
-These charts are available for both groups and projects.
+1. On the top bar, select **Menu > Projects** and find your project.
+1. On the left sidebar, select **Analytics > CI/CD Analytics**.
+1. Select the **Deployment frequency** tab.
-### Lead time charts
+![Deployment frequency](img/deployment_frequency_charts_v13_12.png)
+
+## View lead time for changes chart **(ULTIMATE)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/250329) in GitLab 13.11.
-The charts in the **Lead Time** tab show information about how long it takes
-merge requests to be deployed to a production environment.
+The lead time for changes chart shows information about how long it takes for
+merge requests to be deployed to a production environment. This chart is available for groups and projects.
-![Lead time](img/lead_time_chart_v13_11.png)
+- Small lead times indicate fast, efficient deployment
+ processes.
+- For time periods in which no merge requests were deployed, the charts render a
+ red, dashed line.
-Smaller values are better. Small lead times indicate fast, efficient deployment
-processes.
+To view the lead time for changes chart:
-For time periods in which no merge requests were deployed, the charts render a
-red, dashed line.
+1. On the top bar, select **Menu > Projects** and find your project.
+1. On the left sidebar, select **Analytics > CI/CD Analytics**.
+1. Select the **Lead time** tab.
-These charts are available for both groups and projects.
+![Lead time](img/lead_time_chart_v13_11.png)
diff --git a/doc/user/analytics/code_review_analytics.md b/doc/user/analytics/code_review_analytics.md
index 18a6ca20bc7..dc02512702a 100644
--- a/doc/user/analytics/code_review_analytics.md
+++ b/doc/user/analytics/code_review_analytics.md
@@ -40,7 +40,7 @@ To view Code Review Analytics:
## Use cases
-This feature is designed for [development team leaders](https://about.gitlab.com/handbook/marketing/strategic-marketing/roles-personas/#delaney-development-team-lead)
+This feature is designed for [development team leaders](https://about.gitlab.com/handbook/product/personas/#delaney-development-team-lead)
and others who want to understand broad code review dynamics, and identify patterns to explain them.
You can use Code Review Analytics to:
diff --git a/doc/user/analytics/img/mr_throughput_chart_v13_3.png b/doc/user/analytics/img/mr_throughput_chart_v13_3.png
deleted file mode 100644
index 100c9a8557c..00000000000
--- a/doc/user/analytics/img/mr_throughput_chart_v13_3.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/analytics/img/project_vsa_filter_v14_3.png b/doc/user/analytics/img/project_vsa_filter_v14_3.png
deleted file mode 100644
index d3fcad31909..00000000000
--- a/doc/user/analytics/img/project_vsa_filter_v14_3.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/analytics/img/project_vsa_stage_table_v14_4.png b/doc/user/analytics/img/project_vsa_stage_table_v14_4.png
deleted file mode 100644
index e65296062f6..00000000000
--- a/doc/user/analytics/img/project_vsa_stage_table_v14_4.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/analytics/merge_request_analytics.md b/doc/user/analytics/merge_request_analytics.md
index f9ca06c0ef9..06774c3f16a 100644
--- a/doc/user/analytics/merge_request_analytics.md
+++ b/doc/user/analytics/merge_request_analytics.md
@@ -40,7 +40,7 @@ To view the number of merge requests merged per month:
1. On the top bar, select **Menu > Projects** and find your project.
1. On the left sidebar, select **Analytics > Merge request**.
-1. Optional. Filter results:
+1. Optional. Filter results:
1. Select the filter bar.
1. Select a parameter.
1. Select a value or enter text to refine the results.
diff --git a/doc/user/analytics/value_stream_analytics.md b/doc/user/analytics/value_stream_analytics.md
index 6bad374c371..92c4d447ed9 100644
--- a/doc/user/analytics/value_stream_analytics.md
+++ b/doc/user/analytics/value_stream_analytics.md
@@ -10,215 +10,197 @@ info: To determine the technical writer assigned to the Stage/Group associated w
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/12077) in GitLab Premium 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
-[idea to production](https://about.gitlab.com/blog/2016/08/05/continuous-integration-delivery-and-deployment-with-gitlab/#from-idea-to-production-with-gitlab)
-(also known as cycle time) for each of your projects or groups. Value stream analytics displays the median time
-spent in each stage defined in the process.
+Value stream analytics provides metrics about each stage of your software development process.
-You can use value stream analytics to determine the velocity of a given
-project. It points to bottlenecks in the development process, enabling management
-to uncover, triage, and identify the root cause of slowdowns in the software development life cycle.
+Use value stream analytics to identify:
-For information about how to contribute to the development of value stream analytics, see our [contributor documentation](../../development/value_stream_analytics.md).
+- The amount of time it takes to go from an idea to production.
+- The velocity of a given project.
+- Bottlenecks in the development process.
+- Factors that cause your software development lifecycle to slow down.
-To access value stream analytics for a project:
+Value stream analytics is also available for [groups](../group/value_stream_analytics).
-1. On the top bar, select **Menu > Projects** and find your project.
-1. On the left sidebar, select **Analytics > Value stream**.
-
-NOTE:
-[Value stream analytics for groups](../group/value_stream_analytics) is also available.
-
-## Default stages
+## View value stream analytics
-The stages tracked by value stream analytics by default represent the [GitLab flow](../../topics/gitlab_flow.md). You can customize these stages in value stream analytics for groups.
+> - Filtering [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/326701) in GitLab 14.3
+> - Sorting [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/335974) in GitLab 14.4.
-- **Issue** (Tracker)
- - Time to schedule an issue (by milestone or by adding it to an issue board)
-- **Plan** (Board)
- - Time to first commit
-- **Code** (IDE)
- - Time to create a merge request
-- **Test** (CI)
- - Time it takes GitLab CI/CD to test your code
-- **Review** (Merge request)
- - Time spent on code review
-- **Staging** (Continuous Deployment)
- - Time between merging and deploying to production
+To view value stream analytics for your project:
-## Filter value stream analytics data
+1. On the top bar, select **Menu > Projects** and find your project.
+1. On the left sidebar, select **Analytics > Value stream**.
+1. To view metrics for each stage, above the **Filter results** text box, select a stage.
+1. Optional. Filter the results:
+ 1. Select the **Filter results** text box.
+ 1. Select a parameter.
+ 1. Select a value or enter text to refine the results.
+ 1. To adjust the date range:
+ - In the **From** field, select a start date.
+ - In the **To** field, select an end date.
+1. Optional. Sort results by ascending or descending:
+ - To sort by most recent or oldest workflow item, select the **Merge requests** or **Issues**
+ header. The header name differs based on the stage you select.
+ - To sort by most or least amount of time spent in each stage, select the **Time** header.
+
+The table shows a list of related workflow items for the selected stage. Based on the stage you choose, this can be:
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/326701) in GitLab 14.3
+- CI/CD jobs
+- Issues
+- Merge requests
+- Pipelines
-You can filter analytics based on the following parameters:
+A badge next to the workflow items table header shows the number of workflow items that completed the selected stage.
-- Milestones (Group level)
-- Labels (Group level)
-- Author
-- Assignees
+## View time spent in each development stage
-To filter results:
+Value stream analytics shows the median time spent by issues or merge requests in each development stage.
-1. Select the **Filter results** text box.
-1. Select a parameter.
-1. Select a value. To find a value in the list, enter the value name.
+To view the median time spent in each stage:
-![Value stream analytics filter bar](img/project_vsa_filter_v14_3.png "Active filter bar for a project's value stream analytics")
+1. On the top bar, select **Menu > Projects** and find your project.
+1. On the left sidebar, select **Analytics > Value stream**.
+1. Optional. Filter the results:
+ 1. Select the **Filter results** text box.
+ 1. Select a parameter.
+ 1. Select a value or enter text to refine the results.
+ 1. To adjust the date range:
+ - In the **From** field, select a start date.
+ - In the **To** field, select an end date.
+1. To view the median time for each stage, above the **Filter results** text box, point to a stage.
-### Date ranges
+## View the lead time and cycle time for issues
-To filter analytics results based on a date range,
-select different **From** and **To** days
-from the date picker (default: last 30 days).
+Value stream analytics shows the lead time and cycle time for issues in your project:
-### Stage table
+- Lead time: Median time from when the issue was created to when it was closed.
+- Cycle time: Median time from first commit to issue closed. Commits are associated with issues when users [cross-link them in the commit message](../project/issues/crosslinking_issues.md#from-commit-messages).
-> Sorting the stage table [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/335974) in GitLab 14.4.
+To view the lead time and cycle time for issues:
-![Value stream analytics stage table](img/project_vsa_stage_table_v14_4.png "Project VSA stage table")
+1. On the top bar, select **Menu > Projects** and find your project.
+1. On the left sidebar, select **Analytics > Value stream**.
+1. Optional. Filter the results:
+ 1. Select the **Filter results** text box.
+ 1. Select a parameter.
+ 1. Select a value or enter text to refine the results.
+ 1. To adjust the date range:
+ - In the **From** field, select a start date.
+ - In the **To** field, select an end date.
-The stage table shows a list of related workflow items for the selected stage. This can include:
+The **Lead Time** and **Cycle Time** metrics display below the **Filter results** text box.
-- CI/CD jobs
-- Issues
-- Merge requests
-- Pipelines
+## View lead time for changes for merge requests **(ULTIMATE)**
-A little badge next to the workflow items table header shows the number of workflow items that
-completed the selected stage.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/340150) in GitLab 14.5.
-The stage table also includes the **Time** column, which shows how long it takes each item to pass
-through the selected value stream stage.
+Lead time for changes is the median duration between when a merge request is merged and when it's deployed to production.
-To sort the stage table by a table column, select the table header.
-You can sort in ascending or descending order. To find items that spent the most time in a stage,
-potentially causing bottlenecks in your value stream, sort the table by the **Time** column.
-From there, select individual items to drill in and investigate how delays are happening.
-To see which items most recently exited the stage, sort by the work item column on the left.
+To view the lead time for changes for merge requests in your project:
-The table displays 20 items per page. If there are more than 20 items, you can use the
-**Prev** and **Next** buttons to navigate through the pages.
+1. On the top bar, select **Menu > Projects** and find your project.
+1. On the left sidebar, select **Analytics > Value stream**.
+1. Optional. Filter the results:
+ 1. Select the **Filter results** text box.
+ 1. Select a parameter.
+ 1. Select a value or enter text to refine the results.
+ 1. To adjust the date range:
+ - In the **From** field, select a start date.
+ - In the **To** field, select an end date.
-## How Time metrics are measured
+The **Lead Time for Changes** metrics display below the **Filter results** text box.
-The **Time** metrics near the top of the page are measured as follows:
+## View number of successful deployments **(PREMIUM)**
-- **Lead time**: Median time from issue created to issue closed.
-- **Cycle time**: Median time from first commit to issue closed. (You can associate a commit with an issue by [crosslinking in the commit message](../project/issues/crosslinking_issues.md#from-commit-messages).)
-- **Lead Time for Changes**: median duration between merge request merge and deployment to a production environment for all MRs deployed in the given time period. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/340150) in GitLab 14.5 (Ultimate only).
+To view deployment metrics, you must have a
+[production environment configured](../../ci/environments/index.md#deployment-tier-of-environments).
-## Deployment metrics (**PREMIUM**)
+Value stream analytics shows the following deployment metrics for your project:
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/337256) in GitLab 11.3.
+- Deploys: The number of successful deployments in the date range.
+- Deployment Frequency: The average number of successful deployments per day in the date range.
-Value stream analytics exposes two deployment related metrics near the top of the page:
+To view deployment metrics for your project:
-- **Deploys:** The number of successful deployments in the date range.
-- **Deployment Frequency:** The average number of successful deployments.
+1. On the top bar, select **Menu > Projects** and find your project.
+1. On the left sidebar, select **Analytics > Value stream**.
+1. Optional. Filter the results:
+ 1. Select the **Filter results** text box.
+ 1. Select a parameter.
+ 1. Select a value or enter text to refine the results.
+ 1. To adjust the date range:
+ - In the **From** field, select a start date.
+ - In the **To** field, select an end date.
-The deployment metrics calculation uses the same method as the
-[value stream analytics for groups](../group/value_stream_analytics/index.md#how-metrics-are-measured).
-Both of them are based on the [DORA API](../../api/dora/metrics.md#devops-research-and-assessment-dora-key-metrics-api).
+The **Deploys** and **Deployment Frequency** metrics display below the **Filter results** text box.
-## How the stages are measured
+Deployment metrics are calculated based on data from the
+[DORA API](../../api/dora/metrics.md#devops-research-and-assessment-dora-key-metrics-api).
-Value stream analytics uses start events and end events to measure the time that an issue or merge request spends in each stage.
-For example, a stage might start when one label is added to an issue and end when another label is added.
-Items aren't included in the stage time calculation if they have not reached the end event.
+NOTE:
+In GitLab 13.9 and later, metrics are calculated based on when the deployment was finished.
+In GitLab 13.8 and earlier, metrics are calculated based on when the deployment was created.
-| Stage | Description |
-|---------|---------------|
-| Issue | Measures the median time between creating an issue and taking action to solve it, by either labeling it or adding it to a milestone, whichever comes first. The label is tracked only if it already includes an [issue board list](../project/issue_board.md) created for it. |
-| Plan | Measures the median time between the action you took for the previous stage, and pushing the first commit to the branch. That first branch commit triggers the separation between **Plan** and **Code**, and at least one of the commits in the branch must include the related issue number (such as `#42`). If the issue number is *not* included in a commit, that data is not included in the measurement time of the stage. |
-| Code | Measures the median time between pushing a first commit (previous stage) and creating a merge request (MR). The process is tracked with the [issue closing pattern](../project/issues/managing_issues.md#closing-issues-automatically) in the description of the merge request. For example, if the issue is closed with `Closes #xxx`, it's assumed that `xxx` is issue number for the merge request). If there is no closing pattern, the start time is set to the create time of the first commit. |
-| Test | Essentially the start to finish time for all pipelines. Measures the median time to run the entire pipeline for that project. Related to the time required by GitLab CI/CD to run every job for the commits pushed to that merge request, as defined in the previous stage. |
-| Review | Measures the median time taken to review merge requests with a closing issue pattern, from creation to merge. |
-| Staging | Measures the median time between merging the merge request (with a closing issue pattern) to the first deployment to a [production environment](#how-the-production-environment-is-identified). Data not collected without a production environment. |
+## Access permissions for value stream analytics
-How this works:
+Access permissions for value stream analytics depend on the project type.
-1. Issues and merge requests are grouped in pairs, where the merge request has the
- [closing pattern](../project/issues/managing_issues.md#closing-issues-automatically)
- for the corresponding issue. Issue and merge request pairs without closing patterns are
- not included.
-1. Issue and merge request pairs are filtered by the last XX days, specified through the UI
- (default is `90` days). Pairs outside the filtered range are not included.
-1. For the remaining pairs, review information needed for stages, including
- issue creation date and merge request merge time.
+| Project type | Permissions |
+|--------------|----------------------------------------|
+| Public | Anyone can access. |
+| Internal | Any authenticated user can access. |
+| Private | Any member Guest and above can access. |
-In short, the value stream analytics dashboard tracks data related to [GitLab flow](../../topics/gitlab_flow.md). It does not include data for:
+## How value stream analytics measures each stage
-- Merge requests that do not close an issue.
-- Issues that do not include labels present in the issue board.
-- Issues without a milestone.
-- Staging stages, in projects without a [production environment](#how-the-production-environment-is-identified).
+Value stream analytics uses start and end events to measure the time that an issue or merge request
+spends in each stage.
-## How the production environment is identified
+For example, a stage might start when a user adds a label to an issue, and ends when they add another label.
+Items aren't included in the stage time calculation if they have not reached the end event.
-Value stream analytics identifies production environments based on the
-[deployment tier of environments](../../ci/environments/index.md#deployment-tier-of-environments).
+| Stage | Measurement method |
+|---------|----------------------|
+| Issue | The median time between creating an issue and taking action to solve it, by either labeling it or adding it to a milestone. The label is tracked only if it already includes an [issue board list](../project/issue_board.md) that has been created for the label. |
+| Plan | The median time between the action you took for the previous stage, and when you push the first commit to the branch. The first branch commit triggers the transition from **Plan** to **Code**, and at least one of the commits in the branch must include the related issue number (such as `#42`). If the issue number is not included in a commit, that data is not included in the measurement time of the stage. |
+| Code | The median time between pushing a first commit (previous stage) and creating a merge request. The process is tracked with the [issue closing pattern](../project/issues/managing_issues.md#closing-issues-automatically) in the description of the merge request. For example, if the issue is closed with `Closes #xxx`, `xxx` is the issue number for the merge request. If there is no closing pattern, the start time is set to the create time of the first commit. |
+| Test | The time from start to finish for all pipelines. Measures the median time to run the entire pipeline for that project. Related to the time required by GitLab CI/CD to run every job for the commits pushed to that merge request, as defined in the previous stage. |
+| Review | The median time taken to review merge requests with a closing issue pattern, from creation to merge. |
+| Staging | The median time between merging the merge request (with a closing issue pattern) to the first deployment to a [production environment](../../ci/environments/index.md#deployment-tier-of-environments). Data is not collected without a production environment. |
## Example workflow
-Here's a fictional workflow of a single cycle that happens in a
-single day, passing through all seven stages. If a stage doesn't have
-a start and a stop mark, it isn't measured and hence isn't calculated in the median
-time. It's assumed that milestones are created, and CI for testing and setting
-environments is configured.
-
-1. Issue is created at 09:00 (start of **Issue** stage).
-1. Issue is added to a milestone at 11:00 (stop of **Issue** stage and start of
- **Plan** stage).
-1. Start working on the issue, create a branch locally, and make one commit at
- 12:00.
-1. Make a second commit to the branch that mentions the issue number at 12:30
- (stop of **Plan** stage and start of **Code** stage).
-1. Push branch, and create a merge request that contains the [issue closing pattern](../project/issues/managing_issues.md#closing-issues-automatically)
- in its description at 14:00 (stop of **Code** stage and start of **Test** and
- **Review** stages).
-1. The CI starts running your scripts defined in [`.gitlab-ci.yml`](../../ci/yaml/index.md) and
- takes 5 minutes (stop of **Test** stage).
-1. Review merge request, ensure that everything is okay, and then merge the merge
- request at 19:00 (stop of **Review** stage and start of **Staging** stage).
-1. The merge request is merged, and a deployment to the `production`
- environment starts and finishes at 19:30 (stop of **Staging** stage).
-
-From the previous example we see the time used for each stage:
-
-- **Issue**: 2 hrs (09:00 to 11:00)
-- **Plan**: 1 hr (11:00 to 12:00)
-- **Code**: 2 hrs (12:00 to 14:00)
+This example shows a workflow through all seven stages in one day. In this
+example, milestones have been created and CI for testing and setting environments is configured.
+
+- 09:00: Create issue. **Issue** stage starts.
+- 11:00: Add issue to a milestone, start work on the issue, and create a branch locally.
+**Issue** stage stops and **Plan** stage starts.
+- 12:00: Make the first commit.
+- 12:30: Make the second commit to the branch that mentions the issue number. **Plan** stage stops and **Code** stage starts.
+- 14:00: Push branch and create a merge request that contains the [issue closing pattern](../project/issues/managing_issues.md#closing-issues-automatically). **Code** stage stops and **Test** and **Review** stages start.
+- The CI takes 5 minutes to run scripts defined in [`.gitlab-ci.yml`](../../ci/yaml/index.md).
+**Test** stage stops.
+- Review merge request.
+- 19:00: Merge the merge request. **Review** stage stops and **Staging** stage starts.
+- 19:30: Deployment to the `production` environment starts and finishes. **Staging** stops.
+
+Value stream analytics records the following times for each stage:
+
+- **Issue**: 09:00 to 11:00: 2 hrs
+- **Plan**: 11:00 to 12:00: 1 hr
+- **Code**: 12:00 to 14:00: 2 hrs
- **Test**: 5 minutes
-- **Review**: 5 hrs (14:00 to 19:00)
-- **Staging**: 30 minutes (19:00 to 19:30)
-
-More information:
-
-- Although the previous example specifies the issue number in a later commit, the process
- still collects analytics data for the issue.
-- The time required in the **Test** stage isn't included in the overall time of
- the cycle. The time is included in the **Review** process, as every merge request should be
- tested.
-- The previous example illustrates only one cycle of the multiple stages. Value
- stream analytics, on its dashboard, shows the calculated median elapsed time
- for these issues.
-
-## Permissions
-
-The permissions for the value stream analytics for projects dashboard include:
-
-| Project type | Permissions |
-|--------------|---------------------------------------|
-| Public | Anyone can access |
-| Internal | Any authenticated user can access |
-| Private | Any member Guest and above can access |
-
-You can [read more about permissions](../../user/permissions.md) in general.
-
-## More resources
-
-Learn more about value stream analytics with the following resources:
-
-- [Value stream analytics feature page](https://about.gitlab.com/stages-devops-lifecycle/value-stream-analytics/).
-- [Value stream analytics feature preview](https://about.gitlab.com/blog/2016/09/16/feature-preview-introducing-cycle-analytics/).
-- [Value stream analytics feature highlight](https://about.gitlab.com/blog/2016/09/21/cycle-analytics-feature-highlight/).
+- **Review**: 14:00 to 19:00: 5 hrs
+- **Staging**: 19:00 to 19:30: 30 minutes
+
+There are some additional considerations for this example:
+
+- Although this example specifies the issue number in a later commit, the process
+still collects analytics data for the issue.
+- The time required in the **Test** stage is included in the **Review** process,
+as every merge request should be tested.
+- This example illustrates only one cycle of multiple stages. The value
+stream analytics dashboard shows the calculated median elapsed time for these issues.
+- Value stream analytics identifies production environments based on the
+[deployment tier of environments](../../ci/environments/index.md#deployment-tier-of-environments).
diff --git a/doc/user/application_security/api_fuzzing/create_har_files.md b/doc/user/application_security/api_fuzzing/create_har_files.md
index db0b2a32bcf..1ba19359fde 100644
--- a/doc/user/application_security/api_fuzzing/create_har_files.md
+++ b/doc/user/application_security/api_fuzzing/create_har_files.md
@@ -1,7 +1,7 @@
---
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
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
type: howto
---
diff --git a/doc/user/application_security/api_fuzzing/index.md b/doc/user/application_security/api_fuzzing/index.md
index 4eb721f8832..5413c28912a 100644
--- a/doc/user/application_security/api_fuzzing/index.md
+++ b/doc/user/application_security/api_fuzzing/index.md
@@ -87,9 +87,6 @@ In GitLab 14.0 and later, API fuzzing configuration files must be in your reposi
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/299234) in GitLab 13.10.
-WARNING:
-This feature might not be available to you. Check the **version history** note above for details.
-
The API fuzzing configuration form helps you create or modify your project's API fuzzing
configuration. The form lets you choose values for the most common API fuzzing options and builds
a YAML snippet that you can paste in your GitLab CI/CD configuration.
@@ -804,7 +801,7 @@ variables:
If the value must be generated or regenerated on expiration, you can provide a program or script for
the API fuzzer to execute on a specified interval. The provided script runs in an Alpine Linux
-container that has Python 3 and Bash installed.
+container that has Python 3 and Bash installed.
You have to set the environment variable `FUZZAPI_OVERRIDES_CMD` to the program or script you would like
to execute. The provided command creates the overrides JSON file as defined previously.
@@ -813,7 +810,7 @@ You might want to install other scripting runtimes like NodeJS or Ruby, or maybe
your overrides command. In this case, we recommend setting the `FUZZAPI_PRE_SCRIPT` to the file path of a script which
provides those prerequisites. The script provided by `FUZZAPI_PRE_SCRIPT` is executed once, before the analyzer starts.
-See the [Alpine Linux package management](https://wiki.alpinelinux.org/wiki/Alpine_Linux_package_management)
+See the [Alpine Linux package management](https://wiki.alpinelinux.org/wiki/Alpine_Linux_package_management)
page for information about installing Alpine Linux packages.
You must provide three CI/CD variables, each set for correct operation:
diff --git a/doc/user/application_security/cluster_image_scanning/index.md b/doc/user/application_security/cluster_image_scanning/index.md
index 0db9af7a0d3..293645b8de6 100644
--- a/doc/user/application_security/cluster_image_scanning/index.md
+++ b/doc/user/application_security/cluster_image_scanning/index.md
@@ -29,7 +29,7 @@ To integrate GitLab with security scanners other than those listed here, see
You can use cluster image scanning through the following methods:
- [The cluster image scanning analyzer](#use-the-cluster-image-scanning-analyzer)
-- [The GitLab Agent](#cluster-image-scanning-with-the-gitlab-agent)
+- [The GitLab agent](#cluster-image-scanning-with-the-gitlab-agent)
## Use the cluster image scanning analyzer
@@ -46,7 +46,7 @@ To enable cluster image 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.
+ executor on Linux/amd64.
- Docker `18.09.03` or later installed on the same computer as the runner. If you're using the
shared runners on GitLab.com, then this is already the case.
- [Starboard Operator](https://aquasecurity.github.io/starboard/v0.10.3/operator/installation/kubectl/)
@@ -277,22 +277,22 @@ Here's an example cluster image scanning report:
}
```
-## Cluster image scanning with the GitLab Agent
+## Cluster image scanning with the GitLab agent
-You can use the [GitLab Agent](../../clusters/agent/index.md) to
+You can use the [GitLab agent](../../clusters/agent/index.md) to
scan images from within your Kubernetes cluster and record the vulnerabilities in GitLab.
### Prerequisites
- [Starboard Operator](https://aquasecurity.github.io/starboard/v0.10.3/operator/installation/kubectl/)
installed and configured in your cluster.
-- [GitLab Agent](../../clusters/agent/install/index.md)
+- [GitLab agent](../../clusters/agent/install/index.md)
set up in GitLab, installed in your cluster, and configured using a configuration repository.
### Configuration
-The Agent runs the cluster image scanning once the `cluster_image_scanning`
-directive is added to your [Agent's configuration repository](../../clusters/agent/repository.md#scan-your-container-images-for-vulnerabilities).
+The agent runs the cluster image scanning once the `cluster_image_scanning`
+directive is added to your [agent's configuration repository](../../clusters/agent/vulnerabilities.md).
## Security Dashboard
@@ -302,7 +302,7 @@ the security vulnerabilities in your groups, projects, and pipelines.
## Interacting with the vulnerabilities
After you find a vulnerability, you can address it in the [vulnerability report](../vulnerabilities/index.md)
-or the [GitLab Agent's](../../clusters/agent/install/index.md#view-vulnerabilities-in-cluster-images)
+or the [GitLab agent's](../../clusters/agent/vulnerabilities.md)
details section.
## Troubleshooting
diff --git a/doc/user/application_security/configuration/index.md b/doc/user/application_security/configuration/index.md
index 430f8e1a2a2..61a2121b9c6 100644
--- a/doc/user/application_security/configuration/index.md
+++ b/doc/user/application_security/configuration/index.md
@@ -49,7 +49,9 @@ You can configure the following security controls:
- Select **Configure with a merge request** to create a merge request with the changes required to
enable Dependency Scanning. For more details, see [Enable Dependency Scanning via an automatic merge request](../dependency_scanning/index.md#enable-dependency-scanning-via-an-automatic-merge-request).
- [Container Scanning](../container_scanning/index.md)
- - Can be configured with `.gitlab-ci.yml`. For more details, read [Container Scanning](../../../user/application_security/container_scanning/index.md#configuration).
+ - Select **Configure with a merge request** to create a merge request with the changes required to
+ enable Container Scanning. For more details, see
+ [Enable Container Scanning through an automatic merge request](../container_scanning/index.md#enable-container-scanning-through-an-automatic-merge-request).
- [Cluster Image Scanning](../cluster_image_scanning/index.md)
- Can be configured with `.gitlab-ci.yml`. For more details, read [Cluster Image Scanning](../../../user/application_security/cluster_image_scanning/#configuration).
- [Secret Detection](../secret_detection/index.md)
@@ -66,3 +68,6 @@ You can configure the following security controls:
- [License Compliance](../../../user/compliance/license_compliance/index.md)
- Can be configured with `.gitlab-ci.yml`. For more details, read [License Compliance](../../../user/compliance/license_compliance/index.md#enable-license-compliance).
+
+- [Security Training](../../../user/application_security/vulnerabilities/index.md#enable-security-training-for-vulnerabilities)
+ - Enable **Security training** for the current project. For more details, read [security training](../../../user/application_security/vulnerabilities/index.md#enable-security-training-for-vulnerabilities).
diff --git a/doc/user/application_security/container_scanning/index.md b/doc/user/application_security/container_scanning/index.md
index 08a8c46cc72..f2d6cef669d 100644
--- a/doc/user/application_security/container_scanning/index.md
+++ b/doc/user/application_security/container_scanning/index.md
@@ -50,7 +50,7 @@ To enable container scanning in your pipeline, you need the following:
- Container Scanning runs in the `test` stage, which is available by default. If you redefine the stages in the `.gitlab-ci.yml` file, the `test` stage is required.
- [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.
+ or [`kubernetes`](https://docs.gitlab.com/runner/install/kubernetes.html) executor on Linux/amd64.
- 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.
- An image matching the [supported distributions](#supported-distributions).
@@ -145,7 +145,7 @@ For example, to scan an image from AWS Elastic Container Registry:
```yaml
container_scanning:
before_script:
- - curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" --output "awscliv2.zip"
+ - ruby -r open-uri -e "IO.copy_stream(URI.open('https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip'), 'awscliv2.zip')"
- unzip awscliv2.zip
- ./aws/install
- aws --version
@@ -253,6 +253,24 @@ images. To configure the images, set the `CS_ANALYZER_IMAGE` variable to the sta
| Grype | `registry.gitlab.com/security-products/container-scanning/grype:4-ubi` |
| Trivy | `registry.gitlab.com/security-products/container-scanning/trivy:4-ubi` |
+### Enable Container Scanning through an automatic merge request
+
+> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/6334) in GitLab 14.9.
+
+To enable Container Scanning in a project, create a merge request from the Security Configuration
+page:
+
+1. In the project where you want to enable Container Scanning, go to
+ **Security & Compliance > Configuration**.
+1. In the **Container Scanning** row, select **Configure with a merge request**.
+
+This automatically creates a merge request with the changes necessary to enable Container Scanning.
+To complete the configuration, review and merge this merge request.
+
+The configuration tool works best with no existing `.gitlab-ci.yml` file, or with a minimal
+configuration file. If you have a complex GitLab configuration file, it may not be parsed
+successfully and an error may occur.
+
### Overriding the container scanning template
If you want to override the job definition (for example, to change properties like `variables`), you
diff --git a/doc/user/application_security/coverage_fuzzing/index.md b/doc/user/application_security/coverage_fuzzing/index.md
index 290d4a06dcc..14e98766f0f 100644
--- a/doc/user/application_security/coverage_fuzzing/index.md
+++ b/doc/user/application_security/coverage_fuzzing/index.md
@@ -121,7 +121,7 @@ Use the following variables to configure coverage-guided fuzz testing in your CI
| `COVFUZZ_URL_PREFIX` | Path to the `gitlab-cov-fuzz` repository cloned for use with an offline environment. You should only change this value when using an offline environment. Default: `https://gitlab.com/gitlab-org/security-products/analyzers/gitlab-cov-fuzz/-/raw`. |
| `COVFUZZ_USE_REGISTRY` | Set to `true` to have the corpus stored in the GitLab corpus registry. The variables `COVFUZZ_CORPUS_NAME` and `COVFUZZ_GITLAB_TOKEN` are required if this variable is set to `true`. Default: `false`. [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/5017) in GitLab 14.8. |
| `COVFUZZ_CORPUS_NAME` | Name of the corpus to be used in the job. [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/5017) in GitLab 14.8. |
-| `COVFUZZ_GITLAB_TOKEN` | Environment variable configured with [Personal Access Token](../../../user/profile/personal_access_tokens.md#create-a-personal-access-token) with API read/write access. [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/5017) in GitLab 14.8. |
+| `COVFUZZ_GITLAB_TOKEN` | Environment variable configured with [Personal Access Token](../../../user/profile/personal_access_tokens.md#create-a-personal-access-token) or [Project Access Token](../../../user/project/settings/project_access_tokens.md#create-a-project-access-token) with API read/write access. [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/5017) in GitLab 14.8. |
#### Seed corpus
@@ -144,12 +144,8 @@ You can download the JSON report file from the CI/CD pipelines page. For more in
## Corpus registry
-> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/5017) in GitLab 14.8.
-
-FLAG:
-On self-managed GitLab, by default this feature is available. To hide the feature, ask an
-administrator to [disable the feature flags](../../../administration/feature_flags.md) named
-`corpus_management` and `corpus_management_ui`. On GitLab.com, this feature is available.
+> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/5017) in GitLab 14.8.
+> - [Generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/347187) in GitLab 14.9. [Feature flags `corpus_management` and `corpus_management_ui`](https://gitlab.com/gitlab-org/gitlab/-/issues/328418) removed.
The corpus registry is a library of corpuses. Corpuses in a project's registry are available to
all jobs in that project. A project-wide registry is a more efficient way to manage corpuses than
diff --git a/doc/user/application_security/dast/checks/200.1.md b/doc/user/application_security/dast/checks/200.1.md
index 98a482b4a0f..9795ad11b0b 100644
--- a/doc/user/application_security/dast/checks/200.1.md
+++ b/doc/user/application_security/dast/checks/200.1.md
@@ -8,13 +8,13 @@ info: To determine the technical writer assigned to the Stage/Group associated w
## Description
-A private RFC 1918 was identified in the target application. Public facing websites should not be issuing
-requests to private IP Addresses. Attackers attempting to execute subsequent attacks, such as Server-Side
+A private RFC 1918 was identified in the target application. Public facing websites should not be issuing
+requests to private IP Addresses. Attackers attempting to execute subsequent attacks, such as Server-Side
Request Forgery (SSRF), may be able to use this information to identify additional internal targets.
## Remediation
-Identify the resource that is incorrectly specifying an internal IP address and replace it with it's public
+Identify the resource that is incorrectly specifying an internal IP address and replace it with it's public
facing version, or remove the reference from the target application.
## Details
diff --git a/doc/user/application_security/dast/checks/548.1.md b/doc/user/application_security/dast/checks/548.1.md
index 94f747739c5..d6371c5491d 100644
--- a/doc/user/application_security/dast/checks/548.1.md
+++ b/doc/user/application_security/dast/checks/548.1.md
@@ -8,8 +8,8 @@ info: To determine the technical writer assigned to the Stage/Group associated w
## Description
-The target web server is configured to list the contents of directories that do not contain an index file
-such as `index.html`. This could lead to accidental exposure of sensitive information, or give an attacker
+The target web server is configured to list the contents of directories that do not contain an index file
+such as `index.html`. This could lead to accidental exposure of sensitive information, or give an attacker
details on how filenames and directories are structured and stored.
## Remediation
@@ -17,11 +17,11 @@ details on how filenames and directories are structured and stored.
Directory indexing should be disabled.
Apache:
-For Apache based web sites, ensure all `<Directory>` definitions have `Options -Indexes` configured in the
+For Apache based web sites, ensure all `<Directory>` definitions have `Options -Indexes` configured in the
`apache2.conf` or `httpd.conf` configuration file.
NGINX:
-For NGINX based websites, ensure all `location` definitions have the `autoindex off` directive set in the
+For NGINX based websites, ensure all `location` definitions have the `autoindex off` directive set in the
`nginx.conf` file.
IIS:
diff --git a/doc/user/application_security/dast/checks/598.1.md b/doc/user/application_security/dast/checks/598.1.md
new file mode 100644
index 00000000000..817e20ec413
--- /dev/null
+++ b/doc/user/application_security/dast/checks/598.1.md
@@ -0,0 +1,31 @@
+---
+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/#assignments
+---
+
+# Use of GET request method with sensitive query strings (session ID)
+
+## Description
+
+A session ID was identified in the request URL as well as a cookie value. Session
+IDs should not be sent in GET requests as they maybe captured by proxy systems, stored in
+browser history, or stored in log files. If an attacker were to get access to the session
+ID they would potentially be able to gain access to the target account.
+
+## Remediation
+
+As request headers are rarely logged or captured by third party systems, ensure session ID
+values are only sent in cookies (assigned via `Set-Cookie` response headers) and never sent
+in the request URL.
+
+## Details
+
+| ID | Aggregated | CWE | Type | Risk |
+|:---|:--------|:--------|:--------|:--------|
+| 598.1 | true | 598 | Passive | Medium |
+
+## Links
+
+- [OWASP](https://owasp.org/www-community/vulnerabilities/Information_exposure_through_query_strings_in_url)
+- [CWE](https://cwe.mitre.org/data/definitions/598.html)
diff --git a/doc/user/application_security/dast/checks/index.md b/doc/user/application_security/dast/checks/index.md
index 97224554723..435bc28c4aa 100644
--- a/doc/user/application_security/dast/checks/index.md
+++ b/doc/user/application_security/dast/checks/index.md
@@ -19,5 +19,6 @@ The [DAST browser-based crawler](../browser_based.md) provides a number of vulne
| [16.6](16.6.md) | AspNetMvc header exposes version information | Low | Passive |
| [200.1](200.1.md) | Exposure of sensitive information to an unauthorized actor (private IP address) | Low | Passive |
| [548.1](548.1.md) | Exposure of information through directory listing | Low | Passive |
+| [598.1](598.1.md) | Use of GET request method with sensitive query strings (session ID) | Medium | Passive |
| [614.1](614.1.md) | Sensitive cookie without Secure attribute | Low | Passive |
| [693.1](693.1.md) | Missing X-Content-Type-Options: nosniff | Low | Passive |
diff --git a/doc/user/application_security/dast/index.md b/doc/user/application_security/dast/index.md
index 0865cc10691..fd6c39ffbf1 100644
--- a/doc/user/application_security/dast/index.md
+++ b/doc/user/application_security/dast/index.md
@@ -51,7 +51,7 @@ results. On failure, the analyzer outputs an
## Prerequisites
- [GitLab Runner](../../../ci/runners/index.md) available, with the
-[`docker` executor](https://docs.gitlab.com/runner/executors/docker.html).
+[`docker` executor](https://docs.gitlab.com/runner/executors/docker.html) on Linux/amd64.
- Target application deployed. For more details, read [Deployment options](#deployment-options).
- DAST runs in the `dast` stage, which must be added manually to your `.gitlab-ci.yml`.
@@ -105,7 +105,7 @@ services: # use services to link your app container to the dast job
variables:
DAST_FULL_SCAN_ENABLED: "true" # do a full scan
- DAST_ZAP_USE_AJAX_SPIDER: "true" # use the ajax spider
+ DAST_BROWSER_SCAN: "true" # use the browser-based GitLab DAST crawler
```
Most applications depend on multiple services such as databases or caching services. By default, services defined in the services fields cannot communicate
@@ -314,6 +314,7 @@ include:
variables:
DAST_FULL_SCAN_ENABLED: "true"
+ DAST_BROWSER_SCAN: "true" # use the browser-based GitLab DAST crawler
```
If your DAST job exceeds the job timeout and you need to reduce the scan duration, we shared some
@@ -455,6 +456,7 @@ include:
variables:
GIT_STRATEGY: fetch
DAST_PATHS_FILE: url_file.txt # url_file.txt lives in the root directory of the project
+ DAST_BROWSER_SCAN: "true" # use the browser-based GitLab DAST crawler
```
##### Use `DAST_PATHS` CI/CD variable
@@ -470,6 +472,7 @@ include:
variables:
DAST_PATHS: "/page1.html,/category1/page1.html,/page3.html"
+ DAST_BROWSER_SCAN: "true" # use the browser-based GitLab DAST crawler
```
When using `DAST_PATHS` and `DAST_PATHS_FILE`, note the following:
@@ -547,6 +550,7 @@ include:
variables:
DAST_WEBSITE: https://example.com
DAST_SPIDER_MINS: 120
+ DAST_BROWSER_SCAN: "true" # use the browser-based GitLab DAST crawler
```
Because the template is [evaluated before](../../../ci/yaml/index.md#include) the pipeline
@@ -628,7 +632,7 @@ These CI/CD variables are specific to DAST. They can be used to customize the be
| `DAST_AUTH_VERIFICATION_SELECTOR` <sup>2</sup> | selector | Verifies successful authentication by checking for presence of a selector once the login form has been submitted. Example: `css:.user-photo`. |
| `DAST_AUTH_VERIFICATION_URL` <sup>1,2</sup> | URL | A URL only accessible to logged in users that DAST can use to confirm successful authentication. If provided, DAST exits if it cannot access the URL. Example: `"http://example.com/loggedin_page"`. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/207335) in GitLab 13.8. |
| `DAST_AUTO_UPDATE_ADDONS` | boolean | ZAP add-ons are pinned to specific versions in the DAST Docker image. Set to `true` to download the latest versions when the scan starts. Default: `false`. |
-| `DAST_BROWSER_PATH_TO_LOGIN_FORM` <sup>1,2</sup> | selector | Comma-separated list of selectors that will be clicked on prior to attempting to enter `DAST_USERNAME` and `DAST_PASSWORD` into the login form. Example: `"css:.navigation-menu,css:.login-menu-item"`. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/326633) in GitLab 14.1. |
+| `DAST_BROWSER_PATH_TO_LOGIN_FORM` <sup>1,2</sup> | selector | Comma-separated list of selectors that are clicked on prior to attempting to enter `DAST_USERNAME` and `DAST_PASSWORD` into the login form. Example: `"css:.navigation-menu,css:.login-menu-item"`. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/326633) in GitLab 14.1. |
| `DAST_DEBUG` <sup>1</sup> | boolean | Enable debug message output. Default: `false`. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/12652) in GitLab 13.1. |
| `DAST_EXCLUDE_RULES` | string | Set to a comma-separated list of Vulnerability Rule IDs to exclude them from running during the scan. Rule IDs are numbers and can be found from the DAST log or on the [ZAP project](https://www.zaproxy.org/docs/alerts/). For example, `HTTP Parameter Override` has a rule ID of `10026`. Cannot be used when `DAST_ONLY_INCLUDE_RULES` is set. **Note:** In earlier versions of GitLab the excluded rules were executed but vulnerabilities they generated were suppressed. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/118641) in GitLab 12.10. |
| `DAST_EXCLUDE_URLS` <sup>1,2</sup> | URLs | The URLs to skip during the authenticated scan; comma-separated. Regular expression syntax can be used to match multiple URLs. For example, `.*` matches an arbitrary character sequence. Not supported for API scans. Example, `http://example.com/sign-out`. |
@@ -737,7 +741,7 @@ Only run an authenticated scan against a test server.
### Log in using automatic detection of the login form
-By providing a `DAST_USERNAME`, `DAST_PASSWORD`, and `DAST_AUTH_URL`, DAST will attempt to authenticate to the
+By providing a `DAST_USERNAME`, `DAST_PASSWORD`, and `DAST_AUTH_URL`, DAST attempts to authenticate to the
target application by locating the login form based on a determination about whether or not the form contains username or password fields.
Automatic detection is "best-effort", and depending on the application being scanned may provide either a resilient login experience or one that fails to authenticate the user.
@@ -753,8 +757,8 @@ Login process:
### Log in using explicit selection of the login form
By providing a `DAST_USERNAME_FIELD`, `DAST_PASSWORD_FIELD`, and `DAST_SUBMIT_FIELD`, in addition to the fields required for automatic login,
-DAST will attempt to authenticate to the target application by locating the login form based on the selectors provided.
-Most applications will benefit from this approach to authentication.
+DAST attempts to authenticate to the target application by locating the login form based on the selectors provided.
+Most applications benefit from this approach to authentication.
Login process:
@@ -790,6 +794,7 @@ include:
dast:
variables:
DAST_WEBSITE: "https://example.com"
+ DAST_BROWSER_SCAN: "true" # use the browser-based GitLab DAST crawler
...
DAST_AUTH_VERIFICATION_URL: "https://example.com/user/welcome"
```
@@ -808,6 +813,7 @@ include:
dast:
variables:
DAST_WEBSITE: "https://example.com"
+ DAST_BROWSER_SCAN: "true" # use the browser-based GitLab DAST crawler
...
DAST_AUTH_VERIFICATION_SELECTOR: "css:.welcome-user"
```
@@ -826,6 +832,7 @@ include:
dast:
variables:
DAST_WEBSITE: "https://example.com"
+ DAST_BROWSER_SCAN: "true" # use the browser-based GitLab DAST crawler
...
DAST_AUTH_VERIFICATION_LOGIN_FORM: "true"
```
@@ -847,6 +854,7 @@ include:
dast:
variables:
DAST_WEBSITE: "https://my.site.com"
+ DAST_BROWSER_SCAN: "true" # use the browser-based GitLab DAST crawler
...
DAST_AUTH_URL: "https://my.site.com/admin"
DAST_BROWSER_PATH_TO_LOGIN_FORM: "css:.navigation-menu,css:.login-menu-item"
@@ -875,6 +883,7 @@ An example configuration where the authentication debug report is exported may l
dast:
variables:
DAST_WEBSITE: "https://example.com"
+ DAST_BROWSER_SCAN: "true" # use the browser-based GitLab DAST crawler
...
DAST_AUTH_REPORT: "true"
artifacts:
@@ -885,7 +894,7 @@ dast:
### Selectors
Selectors are used by CI/CD variables to specify the location of an element displayed on a page in a browser.
-Selectors have the format `type`:`search string`. The crawler will search for the selector using the search string based on the type.
+Selectors have the format `type`:`search string`. The crawler searches for the selector using the search string based on the type.
| Selector type | Example | Description |
| ------------- | ---------------------------------- | ----------- |
diff --git a/doc/user/application_security/dast_api/index.md b/doc/user/application_security/dast_api/index.md
index cc20b49764f..839833d9d98 100644
--- a/doc/user/application_security/dast_api/index.md
+++ b/doc/user/application_security/dast_api/index.md
@@ -479,8 +479,8 @@ Follow these steps to provide the bearer token with `DAST_API_OVERRIDES_ENV`:
`{"headers":{"Authorization":"Bearer dXNlcm5hbWU6cGFzc3dvcmQ="}}` (substitute your token). You
can create CI/CD variables from the GitLab projects page at **Settings > CI/CD**, in the
**Variables** section.
- Due to the format of `TEST_API_BEARERAUTH` it's not possible to mask the variable.
- To mask the token's value, you can create a second variable with the token value's, and define
+ Due to the format of `TEST_API_BEARERAUTH` it's not possible to mask the variable.
+ To mask the token's value, you can create a second variable with the token value's, and define
`TEST_API_BEARERAUTH` with the value `{"headers":{"Authorization":"Bearer $MASKED_VARIABLE"}}`.
1. In your `.gitlab-ci.yml` file, set `DAST_API_OVERRIDES_ENV` to the variable you just created:
@@ -876,7 +876,7 @@ variables:
If the value must be generated or regenerated on expiration, you can provide a program or script for
the DAST API scanner to execute on a specified interval. The provided command runs in an Alpine Linux
-container that has Python 3 and Bash installed.
+container that has Python 3 and Bash installed.
You have to set the environment variable `DAST_API_OVERRIDES_CMD` to the program or script you would like
to execute. The provided command creates the overrides JSON file as defined previously.
@@ -885,7 +885,7 @@ You might want to install other scripting runtimes like NodeJS or Ruby, or maybe
your overrides command. In this case, we recommend setting the `DAST_API_PRE_SCRIPT` to the file path of a script which
provides those prerequisites. The script provided by `DAST_API_PRE_SCRIPT` is executed once, before the analyzer starts.
-See the [Alpine Linux package management](https://wiki.alpinelinux.org/wiki/Alpine_Linux_package_management)
+See the [Alpine Linux package management](https://wiki.alpinelinux.org/wiki/Alpine_Linux_package_management)
page for information about installing Alpine Linux packages.
You must provide three CI/CD variables, each set for correct operation:
diff --git a/doc/user/application_security/dependency_list/index.md b/doc/user/application_security/dependency_list/index.md
index baafdcda6e0..78de740c96d 100644
--- a/doc/user/application_security/dependency_list/index.md
+++ b/doc/user/application_security/dependency_list/index.md
@@ -15,7 +15,7 @@ details about those dependencies, including their known vulnerabilities. It is a
To see the dependency list, go to your project and select **Security & Compliance > Dependency List**.
-This information is sometimes referred to as a Software Bill of Materials or SBoM / BOM.
+This information is sometimes referred to as a Software Bill of Materials, SBOM, or BOM.
The dependency list only shows the results of the last successful pipeline to run on the default branch. This is why we recommend not changing the default behavior of allowing the secure jobs to fail.
diff --git a/doc/user/application_security/dependency_scanning/analyzers.md b/doc/user/application_security/dependency_scanning/analyzers.md
index 551488c0dc0..665d29c4017 100644
--- a/doc/user/application_security/dependency_scanning/analyzers.md
+++ b/doc/user/application_security/dependency_scanning/analyzers.md
@@ -50,7 +50,7 @@ Any custom change to the official analyzers can be achieved by using a
You can switch to a custom Docker registry that provides the official analyzer
images under a different prefix. For instance, the following instructs Dependency
Scanning to pull `my-docker-registry/gl-images/gemnasium`
-instead of `registry.gitlab.com/gitlab-org/security-products/analyzers/gemnasium`.
+instead of `registry.gitlab.com/security-products/gemnasium`.
In `.gitlab-ci.yml` define:
```yaml
diff --git a/doc/user/application_security/dependency_scanning/index.md b/doc/user/application_security/dependency_scanning/index.md
index a169b78a193..a4a7e6703ab 100644
--- a/doc/user/application_security/dependency_scanning/index.md
+++ b/doc/user/application_security/dependency_scanning/index.md
@@ -69,7 +69,8 @@ stages in the `.gitlab-ci.yml` file, the `test` stage is required.
To run dependency scanning 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.
+If you're using the shared runners on GitLab.com, this is enabled by default. The analyzer images
+provided are for the Linux/amd64 architecture.
WARNING:
If you use your own runners, make sure your installed version of Docker
@@ -181,7 +182,7 @@ table.supported-languages ul {
</tr>
<tr>
<td rowspan="2">Java</td>
- <td rowspan="2">8, 11, 13, 14, 15, or 16</td>
+ <td rowspan="2">8, 11, 13, 14, 15, 16, or 17</td>
<td><a href="https://gradle.org/">Gradle</a><sup><b><a href="#notes-regarding-supported-languages-and-package-managers-1">1</a></b></sup></td>
<td>
<ul>
@@ -335,27 +336,61 @@ To support the following package managers, the GitLab analyzers proceed in two s
1. Execute the package manager or a specific task, to export the dependency information.
1. Parse the exported dependency information.
-| Package Manager | Preinstalled Versions | Tested Versions |
-| ------ | ------ | ------ |
-| Bundler | [2.1.4](https://gitlab.com/gitlab-org/security-products/analyzers/bundler-audit/-/blob/v2.11.3/Dockerfile#L15)<sup><b><a href="#exported-dependency-information-notes-1">1</a></b></sup> | [1.17.3](https://gitlab.com/gitlab-org/security-products/tests/ruby-bundler/-/blob/master/Gemfile.lock#L118), [2.1.4](https://gitlab.com/gitlab-org/security-products/tests/ruby-bundler/-/blob/bundler2-FREEZE/Gemfile.lock#L118) |
-| sbt | [1.6.1](https://gitlab.com/gitlab-org/security-products/analyzers/gemnasium-maven/-/blob/v2.24.6/config/.tool-versions#L4) | [1.0.4](https://gitlab.com/gitlab-org/security-products/analyzers/gemnasium-maven/-/blob/v2.24.6/.gitlab-ci.yml#L330), [1.1.4](https://gitlab.com/gitlab-org/security-products/tests/scala-sbt-multiproject/-/blob/main/project/build.properties#L1), [1.1.6](https://gitlab.com/gitlab-org/security-products/analyzers/gemnasium-maven/-/blob/v2.24.6/.gitlab-ci.yml#L339), [1.2.8](https://gitlab.com/gitlab-org/security-products/analyzers/gemnasium-maven/-/blob/v2.24.6/.gitlab-ci.yml#L348), [1.3.12](https://gitlab.com/gitlab-org/security-products/analyzers/gemnasium-maven/-/blob/v2.24.6/.gitlab-ci.yml#L357), [1.4.6](https://gitlab.com/gitlab-org/security-products/analyzers/gemnasium-maven/-/blob/v2.24.6/.gitlab-ci.yml#L366), [1.6.1](https://gitlab.com/gitlab-org/security-products/analyzers/gemnasium-maven/-/blob/v2.24.6/.gitlab-ci.yml#L384) |
-| Maven | [3.6.3](https://gitlab.com/gitlab-org/security-products/analyzers/gemnasium-maven/-/blob/v2.23.0/config/.tool-versions#L3) | [3.6.3](https://gitlab.com/gitlab-org/security-products/tests/java-maven/-/blob/master/pom.xml#L3) |
-| Gradle | [6.7.1](https://gitlab.com/gitlab-org/security-products/analyzers/gemnasium-maven/-/blob/v2.23.0/config/.tool-versions#L5) | [5.6.4](https://gitlab.com/gitlab-org/security-products/tests/java-gradle/-/blob/master/gradle/wrapper/gradle-wrapper.properties#L3), [6.5](https://gitlab.com/gitlab-org/security-products/tests/java-gradle/-/blob/java-14/gradle/wrapper/gradle-wrapper.properties#L3), [6.7-rc-1](https://gitlab.com/gitlab-org/security-products/tests/java-gradle/-/blob/java-15/gradle/wrapper/gradle-wrapper.properties#L3), [6.9](https://gitlab.com/gitlab-org/security-products/tests/java-gradle/-/blob/java-14-gradle-6-9/gradle/wrapper/gradle-wrapper.properties#L3), [7.0-rc-2](https://gitlab.com/gitlab-org/security-products/tests/java-gradle/-/blob/java-16/gradle/wrapper/gradle-wrapper.properties#L3) |
-| setuptools | [50.3.2](https://gitlab.com/gitlab-org/security-products/analyzers/gemnasium/-/blob/v2.29.9/Dockerfile#L27) | [57.5.0](https://gitlab.com/gitlab-org/security-products/tests/python-setuptools/-/blob/main/setup.py) |
-| pip | [20.2.4](https://gitlab.com/gitlab-org/security-products/analyzers/gemnasium/-/blob/v2.29.9/Dockerfile#L26) | [20.x](https://gitlab.com/gitlab-org/security-products/tests/python-pip/-/blob/master/requirements.txt) |
-| Pipenv | [2018.11.26](https://gitlab.com/gitlab-org/security-products/analyzers/gemnasium-python/-/blob/v2.18.4/requirements.txt#L13) | [2018.11.26](https://gitlab.com/gitlab-org/security-products/tests/python-pipenv/-/blob/pipfile-lock-FREEZE/Pipfile.lock#L6)<sup><b><a href="#exported-dependency-information-notes-2">2</a></b></sup>, [2018.11.26](https://gitlab.com/gitlab-org/security-products/tests/python-pipenv/-/blob/master/Pipfile) |
+| Package Manager | Pre-installed Versions | Tested Versions |
+| ------ | ------ | ------ |
+| Bundler | [2.1.4](https://gitlab.com/gitlab-org/security-products/analyzers/bundler-audit/-/blob/v2.11.3/Dockerfile#L15)<sup><b><a href="#exported-dependency-information-notes-1">1</a></b></sup> | [1.17.3](https://gitlab.com/gitlab-org/security-products/tests/ruby-bundler/-/blob/master/Gemfile.lock#L118), [2.1.4](https://gitlab.com/gitlab-org/security-products/tests/ruby-bundler/-/blob/bundler2-FREEZE/Gemfile.lock#L118) |
+| sbt | [1.6.1](https://gitlab.com/gitlab-org/security-products/analyzers/gemnasium-maven/-/blob/v2.24.6/config/.tool-versions#L4) | [1.0.4](https://gitlab.com/gitlab-org/security-products/analyzers/gemnasium-maven/-/blob/v2.24.6/.gitlab-ci.yml#L330), [1.1.4](https://gitlab.com/gitlab-org/security-products/tests/scala-sbt-multiproject/-/blob/main/project/build.properties#L1), [1.1.6](https://gitlab.com/gitlab-org/security-products/analyzers/gemnasium-maven/-/blob/v2.24.6/.gitlab-ci.yml#L339), [1.2.8](https://gitlab.com/gitlab-org/security-products/analyzers/gemnasium-maven/-/blob/v2.24.6/.gitlab-ci.yml#L348), [1.3.12](https://gitlab.com/gitlab-org/security-products/analyzers/gemnasium-maven/-/blob/v2.24.6/.gitlab-ci.yml#L357), [1.4.6](https://gitlab.com/gitlab-org/security-products/analyzers/gemnasium-maven/-/blob/v2.24.6/.gitlab-ci.yml#L366), [1.6.1](https://gitlab.com/gitlab-org/security-products/analyzers/gemnasium-maven/-/blob/v2.24.6/.gitlab-ci.yml#L384) |
+| Maven | [3.6.3](https://gitlab.com/gitlab-org/security-products/analyzers/gemnasium-maven/-/blob/v2.23.0/config/.tool-versions#L3) | [3.6.3](https://gitlab.com/gitlab-org/security-products/tests/java-maven/-/blob/master/pom.xml#L3) |
+| Gradle | [6.7.1](https://gitlab.com/gitlab-org/security-products/analyzers/gemnasium-maven/-/blob/v2.23.0/config/.tool-versions#L5)<sup><b><a href="#exported-dependency-information-notes-2">2</a></b></sup>, [7.3.3](https://gitlab.com/gitlab-org/security-products/analyzers/gemnasium-maven/-/blob/v2.26.0/config/.tool-versions#L5)<sup><b><a href="#exported-dependency-information-notes-2">2</a></b></sup> | [5.6.4](https://gitlab.com/gitlab-org/security-products/tests/java-gradle/-/blob/master/gradle/wrapper/gradle-wrapper.properties#L3), [6.5](https://gitlab.com/gitlab-org/security-products/tests/java-gradle/-/blob/java-14/gradle/wrapper/gradle-wrapper.properties#L3), [6.7-rc-1](https://gitlab.com/gitlab-org/security-products/tests/java-gradle/-/blob/java-15/gradle/wrapper/gradle-wrapper.properties#L3), [6.7.1](https://gitlab.com/gitlab-org/security-products/analyzers/gemnasium-maven/-/blob/v2.27.1/.gitlab-ci.yml#L289-297)<sup><b><a href="#exported-dependency-information-notes-3">3</a></b></sup>, [6.9](https://gitlab.com/gitlab-org/security-products/tests/java-gradle/-/blob/java-14-gradle-6-9/gradle/wrapper/gradle-wrapper.properties#L3), [7.0-rc-2](https://gitlab.com/gitlab-org/security-products/tests/java-gradle/-/blob/java-16/gradle/wrapper/gradle-wrapper.properties#L3), [7.3](https://gitlab.com/gitlab-org/security-products/tests/java-gradle/-/blob/java-14-gradle-7-3/gradle/wrapper/gradle-wrapper.properties#L3), [7.3.3](https://gitlab.com/gitlab-org/security-products/analyzers/gemnasium-maven/-/blob/v2.27.1/.gitlab-ci.yml#L299-317)<sup><b><a href="#exported-dependency-information-notes-3">3</a></b></sup> |
+| setuptools | [50.3.2](https://gitlab.com/gitlab-org/security-products/analyzers/gemnasium/-/blob/v2.29.9/Dockerfile#L27) | [57.5.0](https://gitlab.com/gitlab-org/security-products/tests/python-setuptools/-/blob/main/setup.py) |
+| pip | [20.2.4](https://gitlab.com/gitlab-org/security-products/analyzers/gemnasium/-/blob/v2.29.9/Dockerfile#L26) | [20.x](https://gitlab.com/gitlab-org/security-products/tests/python-pip/-/blob/master/requirements.txt) |
+| Pipenv | [2018.11.26](https://gitlab.com/gitlab-org/security-products/analyzers/gemnasium-python/-/blob/v2.18.4/requirements.txt#L13) | [2018.11.26](https://gitlab.com/gitlab-org/security-products/tests/python-pipenv/-/blob/pipfile-lock-FREEZE/Pipfile.lock#L6)<sup><b><a href="#exported-dependency-information-notes-4">4</a></b></sup>, [2018.11.26](https://gitlab.com/gitlab-org/security-products/tests/python-pipenv/-/blob/master/Pipfile) |
<!-- markdownlint-disable MD044 -->
<ol>
<li>
<a id="exported-dependency-information-notes-1"></a>
<p>
- The installed version of <code>Bundler</code> is only used for the <a href="https://gitlab.com/gitlab-org/security-products/analyzers/bundler-audit">bundler-audit</a> analyzer, and is not used for <a href="https://gitlab.com/gitlab-org/security-products/analyzers/gemnasium">gemnasium</a>
+ The pre-installed version of <code>Bundler</code> is only used for the <a href="https://gitlab.com/gitlab-org/security-products/analyzers/bundler-audit">bundler-audit</a> analyzer, and is not used for <a href="https://gitlab.com/gitlab-org/security-products/analyzers/gemnasium">gemnasium</a>.
</p>
</li>
<li>
<a id="exported-dependency-information-notes-2"></a>
<p>
+ Different versions of Java require different versions of Gradle. The versions of Gradle listed in the above table are pre-installed
+ in the analyzer image. The version of Gradle used by the analyzer depends on whether your project uses a <code>gradlew</code>
+ (Gradle wrapper) file or not:
+ </p>
+ <ul>
+ <li>
+ <p>
+ If your project <i>does not use</i> a <code>gradlew</code> file, then the analyzer automatically switches to one of the
+ pre-installed Gradle versions, based on the version of Java specified by the
+ <a href="#configuring-specific-analyzers-used-by-dependency-scanning"><code>DS_JAVA_VERSION</code></a> variable.
+ </p>
+ <p>You can view the
+ <a href="https://docs.gradle.org/current/userguide/compatibility.html#java">Gradle Java compatibility matrix</a> to see which version
+ of Gradle is selected for each Java version. Note that we only support switching to one of these pre-installed Gradle versions
+ for Java versions 13 to 17.
+ </p>
+ </li>
+ <li>
+ <p>
+ If your project <i>does use</i> a <code>gradlew</code> file, then the version of Gradle pre-installed in the analyzer image is
+ ignored, and the version specified in your <code>gradlew</code> file is used instead.
+ </p>
+ </li>
+ </ul>
+ </li>
+ <li>
+ <a id="exported-dependency-information-notes-3"></a>
+ <p>
+ These tests confirm that if a <code>gradlew</code> file does not exist, the version of <code>Gradle</code> pre-installed in the analyzer image is used.
+ </p>
+ </li>
+ <li>
+ <a id="exported-dependency-information-notes-4"></a>
+ <p>
This test confirms that if a <code>Pipfile.lock</code> file is found, it will be used by <a href="https://gitlab.com/gitlab-org/security-products/analyzers/gemnasium">Gemnasium</a> to scan the exact package versions listed in this file.
</p>
</li>
@@ -563,7 +598,7 @@ The following variables are used for configuring specific analyzers (used for a
| `GEMNASIUM_DB_REF_NAME` | `gemnasium` | `master` | Branch name for remote repository database. `GEMNASIUM_DB_REMOTE_URL` is required. |
| `DS_REMEDIATE` | `gemnasium` | `"true"` | Enable automatic remediation of vulnerable dependencies. |
| `GEMNASIUM_LIBRARY_SCAN_ENABLED` | `gemnasium` | `"true"` | Enable detecting vulnerabilities in vendored JavaScript libraries. For now, `gemnasium` leverages [`Retire.js`](https://github.com/RetireJS/retire.js) to do this job. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/350512) in GitLab 14.8. |
-| `DS_JAVA_VERSION` | `gemnasium-maven` | `11` | Version of Java. Available versions: `8`, `11`, `13`, `14`, `15`, `16`. |
+| `DS_JAVA_VERSION` | `gemnasium-maven` | `11` | Version of Java. Available versions: `8`, `11`, `13`, `14`, `15`, `16`, `17`. |
| `MAVEN_CLI_OPTS` | `gemnasium-maven` | `"-DskipTests --batch-mode"` | List of command line arguments that are passed to `maven` by the analyzer. See an example for [using private repositories](../index.md#using-private-maven-repositories). |
| `GRADLE_CLI_OPTS` | `gemnasium-maven` | | List of command line arguments that are passed to `gradle` by the analyzer. |
| `SBT_CLI_OPTS` | `gemnasium-maven` | | List of command-line arguments that the analyzer passes to `sbt`. |
@@ -767,13 +802,13 @@ Here's an example dependency scanning report:
}
```
-### CycloneDX reports
+### CycloneDX Software Bill of Materials
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/350509) in GitLab 14.8 in [Beta](../../../policy/alpha-beta-support.md#beta-features).
In addition to the [JSON report file](#reports-json-format), the [Gemnasium](https://gitlab.com/gitlab-org/security-products/analyzers/gemnasium)
-Dependency Scanning tool outputs a [CycloneDX](https://cyclonedx.org/) report for
-each supported lock or build file it detects. These CycloneDX reports are named
+Dependency Scanning tool outputs a [CycloneDX](https://cyclonedx.org/) Software Bill of Materials (SBOM) for
+each supported lock or build file it detects. These CycloneDX SBOMs are named
`cyclonedx-<package-type>-<package-manager>.json`, and are saved in the same directory
as the detected lock or build files.
@@ -791,7 +826,7 @@ For example, if your project has the following structure:
└── go.sum
```
-Then the Gemnasium scanner generates the following CycloneDX reports:
+Then the Gemnasium scanner generates the following CycloneDX SBOMs:
```plaintext
.
@@ -809,23 +844,23 @@ Then the Gemnasium scanner generates the following CycloneDX reports:
└── cyclonedx-go-go.json
```
-The CycloneDX reports can be downloaded [the same way as other job artifacts](../../../ci/pipelines/job_artifacts.md#download-job-artifacts).
+The CycloneDX SBOMs can be downloaded [the same way as other job artifacts](../../../ci/pipelines/job_artifacts.md#download-job-artifacts).
-### Merging multiple CycloneDX Reports
+### Merging multiple CycloneDX SBOMs
-You can use a CI/CD job to merge multiple CycloneDX Reports into a single report.
+You can use a CI/CD job to merge multiple CycloneDX SBOMs into a single SBOM.
For example:
```yaml
stages:
- test
- - merge-cyclonedx-reports
+ - merge-cyclonedx-sboms
include:
- template: Security/Dependency-Scanning.gitlab-ci.yml
-merge cyclonedx reports:
- stage: merge-cyclonedx-reports
+merge cyclonedx sboms:
+ stage: merge-cyclonedx-sboms
image: alpine:latest
script:
- wget https://github.com/CycloneDX/cyclonedx-cli/releases/download/v0.22.0/cyclonedx-linux-musl-x64 -O /usr/local/bin/cyclonedx-cli
@@ -838,14 +873,14 @@ merge cyclonedx reports:
```
GitLab uses [CycloneDX Properties](https://cyclonedx.org/use-cases/#properties--name-value-store)
-to store implementation-specific details in the metadata of each CycloneDX report,
-such as the location of build and lock files. If multiple CycloneDX reports are merged together,
+to store implementation-specific details in the metadata of each CycloneDX SBOM,
+such as the location of build and lock files. If multiple CycloneDX SBOMs are merged together,
this information is removed from the resulting merged file.
NOTE:
-CycloneDX reports are a [Beta](../../../policy/alpha-beta-support.md#beta-features) feature,
+CycloneDX SBOMs are a [Beta](../../../policy/alpha-beta-support.md#beta-features) feature,
and the reports are subject to change during the beta period. Do not build integrations
-that rely on the format of these reports staying consistent, as the format might change
+that rely on the format of these SBOMs staying consistent, as the format might change
before the feature is made generally available.
## Versioning and release process
@@ -892,11 +927,11 @@ import the following default dependency scanning analyzer images from `registry.
your [local Docker container registry](../../packages/container_registry/index.md):
```plaintext
-registry.gitlab.com/gitlab-org/security-products/analyzers/gemnasium:2
-registry.gitlab.com/gitlab-org/security-products/analyzers/gemnasium-maven:2
-registry.gitlab.com/gitlab-org/security-products/analyzers/gemnasium-python:2
-registry.gitlab.com/gitlab-org/security-products/analyzers/retire.js:2
-registry.gitlab.com/gitlab-org/security-products/analyzers/bundler-audit:2
+registry.gitlab.com/security-products/gemnasium:2
+registry.gitlab.com/security-products/gemnasium-maven:2
+registry.gitlab.com/security-products/gemnasium-python:2
+registry.gitlab.com/security-products/retire.js:2
+registry.gitlab.com/security-products/bundler-audit:2
```
The process for importing Docker images into a local offline Docker registry depends on
@@ -961,7 +996,13 @@ BUNDLER_AUDIT_ADVISORY_DB_REF_NAME: "master"
BUNDLER_AUDIT_ADVISORY_DB_URL: "gitlab.example.com/ruby-advisory-db.git"
```
-#### Python (setup tools)
+#### Python (pip)
+
+If you need to install Python packages before the analyzer runs, you should use `pip install --user` in the `before_script` of the scanning job. The `--user` flag causes project dependencies to be installed in the user directory. If you do not pass the `--user` option, packages are installed globally, and they are not scanned and don't show up when listing project dependencies.
+
+#### Python (setuptools)
+
+If you need to install Python packages before the analyzer runs, you should use `python setup.py install --user` in the `before_script` of the scanning job. The `--user` flag causes project dependencies to be installed in the user directory. If you do not pass the `--user` option, packages are installed globally, and they are not scanned and don't show up when listing project dependencies.
When using self-signed certificates for your private PyPi repository, no extra job configuration (aside
from the template `.gitlab-ci.yml` above) is needed. However, you must update your `setup.py` to
diff --git a/doc/user/application_security/iac_scanning/index.md b/doc/user/application_security/iac_scanning/index.md
index 89d3531bccd..b72f54b4493 100644
--- a/doc/user/application_security/iac_scanning/index.md
+++ b/doc/user/application_security/iac_scanning/index.md
@@ -22,7 +22,7 @@ To run IaC scanning jobs, by default, you need GitLab Runner with the
If you're using the shared runners on GitLab.com, this is enabled by default.
WARNING:
-Our IaC scanning jobs require a Linux container type. Windows containers are not yet supported.
+Our IaC scanning jobs require a Linux/amd64 container type. Windows containers are not yet supported.
WARNING:
If you use your own runners, make sure the Docker version installed
@@ -58,7 +58,7 @@ as shown in the following table:
|:---------------------------------------------------------------------------------------|:--------------------|:-------------------|
| [Configure IaC Scanners](#configuration) | **{check-circle}** | **{check-circle}** |
| View [JSON Report](#reports-json-format) | **{check-circle}** | **{check-circle}** |
-| Presentation of JSON Report in Merge Request | **{dotted-circle}** | **{check-circle}** |
+| Presentation of JSON Report in merge request | **{dotted-circle}** | **{check-circle}** |
| [Address vulnerabilities](../../application_security/vulnerabilities/index.md) | **{dotted-circle}** | **{check-circle}** |
| [Access to Security Dashboard](../../application_security/security_dashboard/index.md) | **{dotted-circle}** | **{check-circle}** |
@@ -76,7 +76,12 @@ To configure IaC Scanning for a project you can:
### Configure IaC Scanning manually
To enable IaC Scanning you must [include](../../../ci/yaml/index.md#includetemplate) the
-[`SAST-IaC.latest.gitlab-ci.yml template`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Security/SAST-IaC.latest.gitlab-ci.yml) provided as part of your GitLab installation.
+[`SAST-IaC.latest.gitlab-ci.yml template`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Security/SAST-IaC.latest.gitlab-ci.yml) provided as part of your GitLab installation. Here is an example of how to include it:
+
+```yaml
+include:
+ - template: Security/SAST-IaC.latest.gitlab-ci.yml
+```
The included template creates IaC scanning jobs in your CI/CD pipeline and scans
your project's configuration files for possible vulnerabilities.
diff --git a/doc/user/application_security/index.md b/doc/user/application_security/index.md
index 6a0b81335fd..ff548f1d29f 100644
--- a/doc/user/application_security/index.md
+++ b/doc/user/application_security/index.md
@@ -110,11 +110,9 @@ For more details about each of the security scanning tools, see their respective
### Override the default registry base address
-By default, GitLab security scanners use `registry.gitlab.com/gitlab-org/security-products/analyzers` as the
+By default, GitLab security scanners use `registry.gitlab.com/security-products` as the
base address for Docker images. You can override this globally by setting the CI/CD variable
-`SECURE_ANALYZERS_PREFIX` to another location. Note that this affects all scanners at once, except
-the container-scanning analyzer which uses
-`registry.gitlab.com/security-products/container-scanning` as its registry.
+`SECURE_ANALYZERS_PREFIX` to another location. Note that this affects all scanners at once.
### Use security scanning tools with merge request pipelines
@@ -221,7 +219,7 @@ security issues:
WARNING:
This feature is in its end-of-life process. It is [deprecated](../../update/deprecations.md#vulnerability-check)
for use in GitLab 14.8, and is planned for removal in GitLab 15.0. Users should migrate to the new
-[Security Approval Policies](policies/#scan-result-policy-editor).
+[Security Approval Policies](policies/scan-result-policies.md).
To prevent a merge request introducing a security vulnerability in a project, enable the
Vulnerability-Check rule. While this rule is enabled, additional merge request approval by
@@ -397,6 +395,8 @@ any report artifacts that failed validation.
### Enable security report validation
+> [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/354928) in GitLab 14.9, and planned for removal in GitLab 15.0.
+
To enable report artifacts validation, set the `VALIDATE_SCHEMA` environment variable to `"true"`
for the desired jobs in the `.gitlab-ci.yml` file.
diff --git a/doc/user/application_security/offline_deployments/index.md b/doc/user/application_security/offline_deployments/index.md
index 915e43d0fa5..7aeb094093c 100644
--- a/doc/user/application_security/offline_deployments/index.md
+++ b/doc/user/application_security/offline_deployments/index.md
@@ -179,7 +179,7 @@ set -ux
# Specify needed analyzer images
analyzers=${SAST_ANALYZERS:-"bandit eslint gosec"}
-gitlab=registry.gitlab.com/gitlab-org/security-products/analyzers/
+gitlab=registry.gitlab.com/security-products/
for i in "${analyzers[@]}"
do
diff --git a/doc/user/application_security/policies/img/container_policy_rule_mode_v14_3.png b/doc/user/application_security/policies/img/container_policy_rule_mode_v14_3.png
deleted file mode 100644
index b21d0330b2f..00000000000
--- a/doc/user/application_security/policies/img/container_policy_rule_mode_v14_3.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/application_security/policies/img/container_policy_yaml_mode_v14_3.png b/doc/user/application_security/policies/img/container_policy_yaml_mode_v14_3.png
deleted file mode 100644
index 31d5eb57228..00000000000
--- a/doc/user/application_security/policies/img/container_policy_yaml_mode_v14_3.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/application_security/policies/img/policy_rule_mode_v14_9.png b/doc/user/application_security/policies/img/policy_rule_mode_v14_9.png
new file mode 100644
index 00000000000..8ca7547a33c
--- /dev/null
+++ b/doc/user/application_security/policies/img/policy_rule_mode_v14_9.png
Binary files differ
diff --git a/doc/user/application_security/policies/img/policy_yaml_mode_v14_9.png b/doc/user/application_security/policies/img/policy_yaml_mode_v14_9.png
new file mode 100644
index 00000000000..1d71e8684e9
--- /dev/null
+++ b/doc/user/application_security/policies/img/policy_yaml_mode_v14_9.png
Binary files differ
diff --git a/doc/user/application_security/policies/img/scan_result_policy_yaml_mode_v14_6.png b/doc/user/application_security/policies/img/scan_result_policy_yaml_mode_v14_6.png
deleted file mode 100644
index 57649c58d8b..00000000000
--- a/doc/user/application_security/policies/img/scan_result_policy_yaml_mode_v14_6.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/application_security/policies/index.md b/doc/user/application_security/policies/index.md
index 803f3983b96..8a39220da35 100644
--- a/doc/user/application_security/policies/index.md
+++ b/doc/user/application_security/policies/index.md
@@ -64,13 +64,13 @@ The policy editor has two modes:
- The visual _Rule_ mode allows you to construct and preview policy
rules using rule blocks and related controls.
- ![Policy Editor Rule Mode](img/container_policy_rule_mode_v14_3.png)
+ ![Policy Editor Rule Mode](img/policy_rule_mode_v14_9.png)
- YAML mode allows you to enter a policy definition in `.yaml` format
and is aimed at expert users and cases that the Rule mode doesn't
support.
- ![Policy Editor YAML Mode](img/container_policy_yaml_mode_v14_3.png)
+ ![Policy Editor YAML Mode](img/policy_yaml_mode_v14_9.png)
You can use both modes interchangeably and switch between them at any
time. If a YAML resource is incorrect or contains data not supported
diff --git a/doc/user/application_security/policies/scan-execution-policies.md b/doc/user/application_security/policies/scan-execution-policies.md
index 4e44162d5c5..c3778ac97de 100644
--- a/doc/user/application_security/policies/scan-execution-policies.md
+++ b/doc/user/application_security/policies/scan-execution-policies.md
@@ -8,14 +8,20 @@ info: To determine the technical writer assigned to the Stage/Group associated w
Project owners can use scan execution policies to require that security scans run on a specified
schedule or with the project pipeline. Required scans are injected into the CI pipeline as new jobs
-with a long, random job name. In the unlikely event of a job name collision, the security policy job
-overwrites any pre-existing job in the pipeline.
+with a long, random job name. In the unlikely event of a job name collision, the security policy job overwrites
+any pre-existing job in the pipeline.
This feature has some overlap with [compliance framework pipelines](../../project/settings/#compliance-pipeline-configuration),
as we have not [unified the user experience for these two features](https://gitlab.com/groups/gitlab-org/-/epics/7312).
For details on the similarities and differences between these features, see
[Enforce scan execution](../#enforce-scan-execution).
+NOTE:
+Policy jobs are created in the `test` stage of the pipeline. If you modify the default pipeline
+[`stages`](../../../ci/yaml/index.md#stages),
+you must ensure that the `test` stage exists in the list. Otherwise, the pipeline fails to run and
+an error appears that states `chosen stage does not exist`.
+
## Scan execution policy editor
NOTE:
diff --git a/doc/user/application_security/policies/scan-result-policies.md b/doc/user/application_security/policies/scan-result-policies.md
index 7857de8c780..8215316bcab 100644
--- a/doc/user/application_security/policies/scan-result-policies.md
+++ b/doc/user/application_security/policies/scan-result-policies.md
@@ -13,7 +13,7 @@ job is fully executed.
## Scan result policy editor
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/77814) in GitLab 14.8 with a flag named `scan_result_policy`. Disabled by default.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/77814) in GitLab 14.8.
NOTE:
Only project Owners have the [permissions](../../permissions.md#project-members-permissions)
@@ -28,10 +28,7 @@ the bottom of the editor.
All scan result policy changes are applied through a background job that runs once every 10 minutes.
Allow up to 10 minutes for any policy changes committed to this project to take effect.
-The policy editor only supports YAML mode. To follow work on Rule mode, see the epic
-[Allow Users to Edit Rule-mode scan result policies in the Policy UI](https://gitlab.com/groups/gitlab-org/-/epics/5363).
-
-![Scan Result Policy Editor YAML Mode](img/scan_result_policy_yaml_mode_v14_6.png)
+The [policy editor](index.md#policy-editor) supports YAML mode and rule mode.
## Scan result policies schema
diff --git a/doc/user/application_security/sast/index.md b/doc/user/application_security/sast/index.md
index 3c0a2caf114..d3a79410eea 100644
--- a/doc/user/application_security/sast/index.md
+++ b/doc/user/application_security/sast/index.md
@@ -57,7 +57,7 @@ To run SAST jobs, by default, you need GitLab Runner with the
If you're using the shared runners on GitLab.com, this is enabled by default.
WARNING:
-Our SAST jobs require a Linux container type. Windows containers are not yet supported.
+Our SAST jobs require a Linux/amd64 container type. Windows containers are not yet supported.
WARNING:
If you use your own runners, make sure the Docker version installed
@@ -315,7 +315,6 @@ To disable analyzer rules:
1. In one or more `ruleset.identifier` sub sections, list the rules that you want disabled. Every `ruleset.identifier` section has:
- a `type` field, to name the predefined rule identifier that the targeted analyzer uses.
-
- a `value` field, to name the rule to be disabled.
##### Example: Disable predefined rules of SAST analyzers
@@ -345,6 +344,9 @@ and `sobelow` by matching the `type` and `value` of identifiers:
value = "sql_injection"
```
+Those vulnerabilities containing the provided type and value are now disabled, meaning
+they won't be displayed in Merge Request nor the Vulnerability Report.
+
#### Override predefined analyzer rules
To override analyzer rules:
@@ -365,30 +367,40 @@ To override analyzer rules:
##### Example: Override predefined rules of SAST analyzers
-In the following example, rules from `eslint`
-and `gosec` are matched by the `type` and `value` of identifiers and
-then overridden:
+Before adding a ruleset, we verify which vulnerability will be overwritten by viewing the [`gl-sast-report.json`](#reports-json-format):
+
+```json
+"identifiers": [
+ {
+ "type": "gosec_rule_id",
+ "name": "Gosec Rule ID G307",
+ "value": "G307"
+ },
+ {
+ "type": "CWE",
+ "name": "CWE-703",
+ "value": "703",
+ "url": "https://cwe.mitre.org/data/definitions/703.html"
+ }
+ ]
+```
+
+In the following example, rules from `gosec` are matched by the `type`
+and `value` of identifiers and then overridden:
```toml
-[eslint]
- [[eslint.ruleset]]
- [eslint.ruleset.identifier]
- type = "eslint_rule_id"
- value = "security/detect-object-injection"
- [eslint.ruleset.override]
- description = "OVERRIDDEN description"
- message = "OVERRIDDEN message"
- name = "OVERRIDDEN name"
- severity = "Critical"
[gosec]
[[gosec.ruleset]]
[gosec.ruleset.identifier]
type = "CWE"
- value = "CWE-79"
+ value = "703"
[gosec.ruleset.override]
severity = "Critical"
```
+If a vulnerability is found with a type `CWE` with a value of `703` then
+the vulnerability severity is overwritten to `Critical`.
+
#### Synthesize a custom configuration
To create a custom configuration, you can use passthrough chains.
@@ -661,6 +673,25 @@ repositories and thus require credentials like username and password to download
Depending on the analyzer, such credentials can be provided to
it via [custom CI/CD variables](#custom-cicd-variables).
+#### Using a CI/CD variable to pass username and password to a private Go repository
+
+If your Go project depends on private modules, see
+[Fetch modules from private projects](../../packages/go_proxy/index.md#fetch-modules-from-private-projects)
+for how to provide authentication over HTTPS.
+
+To specify credentials via `~/.netrc` provide a `before_script` containing the following:
+
+```yaml
+gosec-sast:
+ before_script:
+ - |
+ cat <<EOF > ~/.netrc
+ machine gitlab.com
+ login $CI_DEPLOY_USER
+ password $CI_DEPLOY_PASSWORD
+ EOF
+```
+
#### Using a CI/CD variable to pass username and password to a private Maven repository
If your private Maven repository requires login credentials,
@@ -878,12 +909,12 @@ variables:
## Reports JSON format
-SAST outputs a report file in JSON format. The report file contains details of all found vulnerabilities.
-To download the report file, you can either:
+SAST outputs a report file in JSON format. The report file contains details of all found vulnerabilities.
+To download the report file, you can either:
- Download the file from the CI/CD pipelines page.
-- In the pipelines tab on merge requests, set [`artifacts: paths`](../../../ci/yaml/index.md#artifactspaths) to `gl-sast-report.json`.
-
+- In the pipelines tab on merge requests, set [`artifacts: paths`](../../../ci/yaml/index.md#artifactspaths) to `gl-sast-report.json`.
+
For information, see [Download job artifacts](../../../ci/pipelines/job_artifacts.md#download-job-artifacts).
For details of the report file's schema, see
diff --git a/doc/user/application_security/secret_detection/index.md b/doc/user/application_security/secret_detection/index.md
index 2ce2d59898f..582497eb465 100644
--- a/doc/user/application_security/secret_detection/index.md
+++ b/doc/user/application_security/secret_detection/index.md
@@ -42,7 +42,7 @@ To run Secret Detection jobs, by default, you need GitLab Runner with the
If you're using the shared runners on GitLab.com, this is enabled by default.
WARNING:
-Our Secret Detection jobs expect a Linux container type. Windows containers are not supported.
+Our Secret Detection jobs expect a Linux/amd64 container type. Windows containers are not supported.
WARNING:
If you use your own runners, make sure the Docker version installed
@@ -328,14 +328,6 @@ as part of your normal job definition.
A new configuration variable ([`SECRET_DETECTION_HISTORIC_SCAN`](#available-cicd-variables))
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 detection scan.
-<div class="video-fallback">
- See the video: <a href="https://www.youtube.com/watch?v=wDtc_K00Y0A">Walkthrough of historical secret detection scan</a>.
-</div>
-<figure class="video-container">
- <iframe src="https://www.youtube.com/embed/wDtc_K00Y0A" frameborder="0" allowfullscreen="true"> </iframe>
-</figure>
-
## Running Secret Detection in an offline environment
For self-managed GitLab instances in an environment with limited, restricted, or intermittent access
@@ -450,9 +442,9 @@ secret_detection:
### `secret-detection` job fails with `ERR fatal: ambiguous argument` message
-Your `secret-detection` job can fail with `ERR fatal: ambiguous argument` error if your
-repository's default branch is unrelated to the branch the job was triggered for.
+Your `secret-detection` job can fail with `ERR fatal: ambiguous argument` error if your
+repository's default branch is unrelated to the branch the job was triggered for.
See issue [!352014](https://gitlab.com/gitlab-org/gitlab/-/issues/352014) for more details.
-To resolve the issue, make sure to correctly [set your default branch](../../project/repository/branches/default.md#change-the-default-branch-name-for-a-project) on your repository. You should set it to a branch
-that has related history with the branch you run the `secret-detection` job on.
+To resolve the issue, make sure to correctly [set your default branch](../../project/repository/branches/default.md#change-the-default-branch-name-for-a-project) on your repository. You should set it to a branch
+that has related history with the branch you run the `secret-detection` job on.
diff --git a/doc/user/application_security/secret_detection/post_processing.md b/doc/user/application_security/secret_detection/post_processing.md
index 972558c3b95..643da47d876 100644
--- a/doc/user/application_security/secret_detection/post_processing.md
+++ b/doc/user/application_security/secret_detection/post_processing.md
@@ -56,7 +56,7 @@ A vendor revocation receiver service integrates with a GitLab instance to receiv
a web notification and respond to leaked token requests.
To implement a receiver service to revoke leaked tokens:
-
+
1. Create a publicly accessible HTTP service matching the corresponding API contract
below. Your service should be idempotent and rate-limited.
1. When a pipeline corresponding to its revocable token type (in the example, `my_api_token`)
diff --git a/doc/user/application_security/vulnerabilities/index.md b/doc/user/application_security/vulnerabilities/index.md
index 7b39002bac3..0b27760b4bb 100644
--- a/doc/user/application_security/vulnerabilities/index.md
+++ b/doc/user/application_security/vulnerabilities/index.md
@@ -27,8 +27,9 @@ On the vulnerability's page, you can:
- [Change the vulnerability's status](#change-vulnerability-status).
- [Create an issue](#create-an-issue-for-a-vulnerability).
- [Link issues to the vulnerability](#linked-issues).
-- [Resolve a vulnerability](#resolve-a-vulnerability), if a solution is
- available.
+- [Resolve a vulnerability](#resolve-a-vulnerability) if a solution is
+ available.
+- [View security training specific to the detected vulnerability](#view-security-training-for-a-vulnerability).
## Vulnerability status values
@@ -80,7 +81,7 @@ The issue is then opened so you can take further action.
Prerequisites:
- [Enable Jira integration](../../../integration/jira/index.md).
- The **Enable Jira issues creation from vulnerabilities** option must be selected as part of the configuration.
+ The **Enable Jira issue creation from vulnerabilities** option must be selected as part of the configuration.
- Each user must have a personal Jira user account with permission to create issues in the target project.
To create a Jira issue for a vulnerability:
@@ -159,3 +160,29 @@ To manually apply the patch that GitLab generated for a vulnerability:
1. Ensure your local project has the same commit checked out that was used to generate the patch.
1. Run `git apply remediation.patch`.
1. Verify and commit the changes to your branch.
+
+## Enable security training for vulnerabilities
+
+> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/6176) in GitLab 14.9.
+
+Security training helps your developers learn how to fix vulnerabilities. Developers can view security training from selected educational providers, relevant to the detected vulnerability.
+
+To enable security training for vulnerabilities in your project:
+
+1. On the top bar, select **Menu > Projects** and find your project.
+1. On the left sidebar, select **Security & Compliance > Configuration**.
+1. On the tab bar, select **Vulnerability Management**.
+1. To enable a security training provider, turn on the toggle.
+
+## View security training for a vulnerability
+
+> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/6176) in GitLab 14.9.
+
+If security training is enabled, the vulnerability page includes a training link relevant to the detected vulnerability.
+
+To view the security training for a vulnerability:
+
+1. On the top bar, select **Menu > Projects** and find your project.
+1. On the left sidebar, select **Security & Compliance > Vulnerability report**.
+1. Select the vulnerability for which you want to view security training.
+1. Select **View training**.
diff --git a/doc/user/application_security/vulnerability_report/index.md b/doc/user/application_security/vulnerability_report/index.md
index ba1455ab70a..eb59c289700 100644
--- a/doc/user/application_security/vulnerability_report/index.md
+++ b/doc/user/application_security/vulnerability_report/index.md
@@ -7,7 +7,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Vulnerability Report **(ULTIMATE)**
-The Vulnerability Report provides information about vulnerabilities from scans of the default branch. It contains cumulative results of all successful jobs, regardless of whether the pipeline was successful.
+The Vulnerability Report provides information about vulnerabilities from scans of the default branch. It contains cumulative results of all successful jobs, regardless of whether the pipeline was successful.
The scan results from a pipeline are only ingested after all the jobs in the pipeline complete. Partial results for a pipeline with jobs in progress can be seen in the pipeline security tab.
@@ -52,6 +52,7 @@ From the Vulnerability Report you can:
- [View an issue raised for a vulnerability](#view-issues-raised-for-a-vulnerability).
- [Change the status of vulnerabilities](#change-status-of-vulnerabilities).
- [Export details of vulnerabilities](#export-vulnerability-details).
+- [Manually add a vulnerability finding](#manually-add-a-vulnerability-finding).
## Vulnerability Report filters
@@ -219,6 +220,25 @@ You can dismiss a vulnerability for the entire project:
To undo this action, select a different status from the same menu.
+## Manually add a vulnerability finding
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/301003) in GitLab 14.9. Disabled by default.
+
+FLAG:
+This feature is not enabled by default. To make it available, ask an administrator to
+[enable the feature flag](../../feature_flags.md) named `new_vulnerability_form`.
+On GitLab.com, this feature is not yet available.
+
+To add a new vulnerability finding from your project level Vulnerability Report page:
+
+1. On the top bar, select **Menu > Projects** and find your project.
+1. On the left sidebar, select **Security & Compliance > Vulnerability Report**.
+1. Click on **Submit Vulnerability**.
+1. Complete the fields and submit the form.
+
+You will be brought to the newly created vulnerability's detail page. Manually created records appear in the
+Group, Project, and Security Center Vulnerability Reports. To filter them, use the Generic Tool filter.
+
## Operational vulnerabilities
> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/6345) in GitLab 14.6.
diff --git a/doc/user/clusters/agent/ci_cd_tunnel.md b/doc/user/clusters/agent/ci_cd_tunnel.md
index 5fe772d9686..73a8470e025 100644
--- a/doc/user/clusters/agent/ci_cd_tunnel.md
+++ b/doc/user/clusters/agent/ci_cd_tunnel.md
@@ -4,60 +4,254 @@ group: Configure
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
-# CI/CD Tunnel **(FREE)**
+# Using a GitLab CI/CD workflow for Kubernetes **(FREE)**
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/327409) in GitLab 14.1.
> - The pre-configured `KUBECONFIG` was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/324275) in GitLab 14.2.
> - The ability to authorize groups was [introduced](https://gitlab.com/groups/gitlab-org/-/epics/5784) in GitLab 14.3.
> - [Moved](https://gitlab.com/groups/gitlab-org/-/epics/6290) to GitLab Free in 14.5.
> - Support for Omnibus installations was [introduced](https://gitlab.com/gitlab-org/omnibus-gitlab/-/merge_requests/5686) in GitLab 14.5.
+> - The ability to switch between certificate-based clusters and agents was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/335089) in GitLab 14.9. The certificate-based cluster context is always called `gitlab-deploy`.
-To use GitLab CI/CD to safely deploy your application to a cluster, you can use the CI/CD Tunnel.
+You can use a GitLab CI/CD workflow to safely deploy to and update your Kubernetes clusters.
-You can authorize multiple projects to access the same cluster, so you
-can keep your application's codebase in one repository and configure
-your cluster in another. This method is scalable and can save you resources.
+To do so, you must first [install an agent in your cluster](install/index.md). When done, you have a Kubernetes context and can
+run Kubernetes API commands in your GitLab CI/CD pipeline.
-To ensure access to your cluster is safe, only the projects you
-authorize can access your Agent through the CI/CD Tunnel.
+To ensure access to your cluster is safe:
-## Prerequisites
+- Each agent has a separate context (`kubecontext`).
+- Only the project where the agent is configured, and any additional projects you authorize, can access the agent in your cluster.
-To use the CI/CD Tunnel, you need an existing Kubernetes cluster connected to GitLab through the
-[GitLab Agent](install/index.md#install-the-agent-onto-the-cluster).
+You do not need to have a runner in the cluster with the agent.
-To run your CI/CD jobs using the CI/CD Tunnel, you do not need to have a runner in the same cluster.
+## GitLab CI/CD workflow steps
-## How the CI/CD Tunnel works
+To update a Kubernetes cluster by using GitLab CI/CD, complete the following steps.
-When you authorize a project to use an Agent, the Tunnel automatically
-injects a `KUBECONFIG` variable into its CI/CD jobs. This way, you can
-run `kubectl` commands from GitLab CI/CD scripts that belong to the
-authorized project.
+1. Ensure you have a working Kubernetes cluster and the manifests are in a GitLab project.
+1. In the same GitLab project, [register and install the GitLab agent](install/index.md).
+1. [Update your `.gitlab-ci.yml` file](#update-your-gitlab-ciyml-file-to-run-kubectl-commands) to
+ select the agent's Kubernetes context and run the Kubernetes API commands.
+1. Run your pipeline to deploy to or update the cluster.
-When you authorize a group, all the projects that belong to that group
-become authorized to access the selected Agent.
+If you have multiple GitLab projects that contain Kubernetes manifests:
-An Agent can only authorize projects or groups in the same group
-hierarchy as the Agent's configuration project. You can authorize
-up to 100 projects and 100 groups per Agent.
+1. [Install the GitLab agent](install/index.md) in its own project, or in one of the
+ GitLab projects where you keep Kubernetes manifests.
+1. [Authorize the agent](#authorize-the-agent) to access your GitLab projects.
+1. Optional. For added security, [use impersonation](#use-impersonation-to-restrict-project-and-group-access).
+1. [Update your `.gitlab-ci.yml` file](#update-your-gitlab-ciyml-file-to-run-kubectl-commands) to
+ select the agent's Kubernetes context and run the Kubernetes API commands.
+1. Run your pipeline to deploy to or update the cluster.
-Also, each Agent has a separate context (`kubecontext`).
-The Tunnel uses this information to safely allow access to the cluster from
-jobs running in the projects you authorized.
+## Authorize the agent
-### `~/.kube/cache` permissions
-
-`kubectl` and other tools based on the same libraries (such as Helm, `kpt`, and `kustomize`) cache information about
+You must authorize the agent to access the project where you keep your Kubernetes manifests.
+You can authorize the agent to access individual projects, or authorize a group or subgroup,
+so all projects within have access. For added security, you can also
+[use impersonation](#use-impersonation-to-restrict-project-and-group-access).
+
+### Authorize the agent to access your projects
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/327850) in GitLab 14.4.
+
+To authorize the agent to access the GitLab project where you keep Kubernetes manifests:
+
+1. On the top bar, select **Menu > Projects** and find the project that contains the agent configuration file (`config.yaml`).
+1. Edit the file. Under the `ci_access` keyword, add the `projects` attribute.
+1. For the `id`, add the path:
+
+ ```yaml
+ ci_access:
+ projects:
+ - id: path/to/project
+ ```
+
+ - The Kubernetes projects must be in the same group hierarchy as the project where the agent's configuration is.
+ - You can authorize up to 100 projects.
+
+All CI/CD jobs now include a `KUBECONFIG` with contexts for every shared agent connection.
+Choose the context to run `kubectl` commands from your CI/CD scripts.
+
+### Authorize the agent to access projects in your groups
+
+> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/5784) in GitLab 14.3.
+
+To authorize the agent to access all of the GitLab projects in a group or subgroup:
+
+1. On the top bar, select **Menu > Projects** and find the project that contains the agent configuration file (`config.yaml`).
+1. Edit the file. Under the `ci_access` keyword, add the `groups` attribute.
+1. For the `id`, add the path:
+
+ ```yaml
+ ci_access:
+ groups:
+ - id: path/to/group/subgroup
+ ```
+
+ - The Kubernetes projects must be in the same group hierarchy as the project where the agent's configuration is.
+ - You can authorize up to 100 groups.
+
+All the projects that belong to the group are now authorized to access the agent.
+All CI/CD jobs now include a `KUBECONFIG` with contexts for every shared agent connection.
+Choose the context to run `kubectl` commands from your CI/CD scripts.
+
+## Update your `.gitlab-ci.yml` file to run `kubectl` commands
+
+In the project where you want to run Kubernetes commands, edit your project's `.gitlab-ci.yml` file.
+
+In the first command under the `script` keyword, set your agent's context.
+Use the format `path/to/agent/repository:agent-name`. For example:
+
+```yaml
+ deploy:
+ image:
+ name: bitnami/kubectl:latest
+ entrypoint: [""]
+ script:
+ - kubectl config get-contexts
+ - kubectl config use-context path/to/agent/repository:agent-name
+ - kubectl get pods
+```
+
+If you are not sure what your agent's context is, open a terminal and connect to your cluster.
+Run `kubectl config get-contexts`.
+
+### Environments with both certificate-based and agent-based connections
+
+When you deploy to an environment that has both a [certificate-based
+cluster](../../infrastructure/clusters/index.md) (deprecated) and an agent connection:
+
+- The certificate-based cluster's context is called `gitlab-deploy`. This context
+ is always selected by default.
+- In GitLab 14.9 and later, agent contexts are included in the
+ `KUBECONFIG`. You can select them by using `kubectl config use-context
+ path/to/agent/repository:agent-name`.
+- In GitLab 14.8 and earlier, you can still use agent connections, but for environments that
+ already have a certificate-based cluster, the agent connections are not included in the `KUBECONFIG`.
+
+To use an agent connection when certificate-based connections are present, you can manually configure a new `kubectl`
+configuration context. For example:
+
+ ```yaml
+ deploy:
+ variables:
+ KUBE_CONTEXT: my-context # The name to use for the new context
+ AGENT_ID: 1234 # replace with your agent's numeric ID
+ K8S_PROXY_URL: wss://kas.gitlab.com/k8s-proxy/ # replace with your agent server (KAS) Kubernetes proxy URL
+ # ... any other variables you have configured
+ before_script:
+ - kubectl config set-credentials agent:$AGENT_ID --token="ci:${AGENT_ID}:${CI_JOB_TOKEN}"
+ - kubectl config set-cluster gitlab --server="${K8S_PROXY_URL}"
+ - kubectl config set-context "$KUBE_CONTEXT" --cluster=gitlab --user="agent:${AGENT_ID}"
+ - kubectl config use-context "$KUBE_CONTEXT"
+ # ... rest of your job configuration
+ ```
+
+## Use impersonation to restrict project and group access **(PREMIUM)**
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/345014) in GitLab 14.5.
+
+By default, your CI/CD job inherits all the permissions from the service account used to install the
+agent in the cluster.
+To restrict access to your cluster, you can use [impersonation](https://kubernetes.io/docs/reference/access-authn-authz/authentication/#user-impersonation).
+
+To specify impersonations, use the `access_as` attribute in your agent configuration file and use Kubernetes RBAC rules to manage impersonated account permissions.
+
+You can impersonate:
+
+- The agent itself (default).
+- The CI/CD job that accesses the cluster.
+- A specific user or system account defined within the cluster.
+
+### Impersonate the agent
+
+The agent is impersonated by default. You don't need to do anything to impersonate it.
+
+### Impersonate the CI/CD job that accesses the cluster
+
+To impersonate the CI/CD job that accesses the cluster, under the `access_as` key, add the `ci_job: {}` key-value.
+
+When the agent makes the request to the actual Kubernetes API, it sets the
+impersonation credentials in the following way:
+
+- `UserName` is set to `gitlab:ci_job:<job id>`. Example: `gitlab:ci_job:1074499489`.
+- `Groups` is set to:
+ - `gitlab:ci_job` to identify all requests coming from CI jobs.
+ - The list of IDs of groups the project is in.
+ - The project ID.
+ - The slug of the environment this job belongs to.
+
+ Example: for a CI job in `group1/group1-1/project1` where:
+
+ - Group `group1` has ID 23.
+ - Group `group1/group1-1` has ID 25.
+ - Project `group1/group1-1/project1` has ID 150.
+ - Job running in a prod environment.
+
+ Group list would be `[gitlab:ci_job, gitlab:group:23, gitlab:group:25, gitlab:project:150, gitlab:project_env:150:prod]`.
+
+- `Extra` carries extra information about the request. The following properties are set on the impersonated identity:
+
+| Property | Description |
+| -------- | ----------- |
+| `agent.gitlab.com/id` | Contains the agent ID. |
+| `agent.gitlab.com/config_project_id` | Contains the agent's configuration project ID. |
+| `agent.gitlab.com/project_id` | Contains the CI project ID. |
+| `agent.gitlab.com/ci_pipeline_id` | Contains the CI pipeline ID. |
+| `agent.gitlab.com/ci_job_id` | Contains the CI job ID. |
+| `agent.gitlab.com/username` | Contains the username of the user the CI job is running as. |
+| `agent.gitlab.com/environment_slug` | Contains the slug of the environment. Only set if running in an environment. |
+
+Example to restrict access by the CI/CD job's identity:
+
+```yaml
+ci_access:
+ projects:
+ - id: path/to/project
+ access_as:
+ ci_job: {}
+```
+
+### Impersonate a static identity
+
+For a given connection, you can use a static identity for the impersonation.
+
+Under the `access_as` key, add the `impersonate` key to make the request using the provided identity.
+
+The identity can be specified with the following keys:
+
+- `username` (required)
+- `uid`
+- `groups`
+- `extra`
+
+See the [official Kubernetes documentation for details](https://kubernetes.io/docs/reference/access-authn-authz/authentication/#user-impersonation).
+
+## Troubleshooting
+
+### `kubectl` commands not supported
+
+The commands `kubectl exec`, `kubectl cp`, and `kubectl attach` are not supported.
+Anything that uses these API endpoints does not work, because they use the deprecated
+SPDY protocol.
+[An issue exists](https://gitlab.com/gitlab-org/gitlab/-/issues/346248) to add support for these commands.
+
+### Grant write permissions to `~/.kube/cache`
+
+Tools like `kubectl`, Helm, `kpt`, and `kustomize` cache information about
the cluster in `~/.kube/cache`. If this directory is not writable, the tool fetches information on each invocation,
-making interactions slower and creating unnecessary load on the cluster. Make sure that this directory in the container image
-you use is writable for the best experience.
+making interactions slower and creating unnecessary load on the cluster. For the best experience, in the
+image you use in your .`gitlab-ci.yml` file, ensure this directory is writable.
+
+### Enable TLS
-## Configure the CI/CD Tunnel
+If you are on a self-managed GitLab instance, ensure your instance is configured with Transport Layer Security (TLS).
-The CI/CD Tunnel is configured directly through the
-Agent's configuration file ([`config.yaml`](repository.md)) to:
+If you attempt to use `kubectl` without TLS, you might get an error like:
-- Authorize [projects](repository.md#authorize-projects-to-use-an-agent) and [groups](repository.md#authorize-groups-to-use-an-agent) to use the same Agent.
-- [Run `kubectl` commands using the CI/CD Tunnel](repository.md#run-kubectl-commands-using-the-cicd-tunnel).
-- [Restrict access of authorized projects and groups through impersonation strategies](repository.md#use-impersonation-to-restrict-project-and-group-access).
+```shell
+$ kubectl get pods
+error: You must be logged in to the server (the server has asked for the client to provide credentials)
+```
diff --git a/doc/user/clusters/agent/gitops.md b/doc/user/clusters/agent/gitops.md
new file mode 100644
index 00000000000..8f0e2255121
--- /dev/null
+++ b/doc/user/clusters/agent/gitops.md
@@ -0,0 +1,140 @@
+---
+stage: Configure
+group: Configure
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
+---
+
+# Using a GitOps workflow for Kubernetes **(PREMIUM)**
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/259669) in GitLab 13.7.
+
+With GitOps, you can manage containerized clusters and applications from a Git repository that:
+
+- Is the single source of truth of your system.
+- Is the single place where you operate your system.
+
+By combining GitLab, Kubernetes, and GitOps, you can have:
+
+- GitLab as the GitOps operator.
+- Kubernetes as the automation and convergence system.
+- GitLab CI/CD for Continuous Integration and the agent for Continuous Deployment.
+
+This diagram shows the repositories and main actors in a GitOps deployment:
+
+```mermaid
+sequenceDiagram
+ participant D as Developer
+ participant A as Application code repository
+ participant M as Manifest repository
+ participant K as GitLab agent
+ participant C as Agent configuration repository
+ loop Regularly
+ K-->>C: Grab the configuration
+ end
+ D->>+A: Pushing code changes
+ A->>M: Updating manifest
+ loop Regularly
+ K-->>M: Watching changes
+ M-->>K: Pulling and applying changes
+ end
+```
+
+For details, view the [architecture documentation](https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent/-/blob/master/doc/architecture.md#high-level-architecture).
+
+## GitOps workflow steps
+
+To update a Kubernetes cluster by using GitOps, complete the following steps.
+
+1. Ensure you have a working Kubernetes cluster, and that the manifests are in a GitLab project.
+1. In the same project, [register and install the GitLab agent](install/index.md).
+1. Configure the agent configuration file so that the agent monitors the project for changes to the Kubernetes manifests.
+ Use the [GitOps configuration reference](#gitops-configuration-reference) for guidance.
+
+Any time you commit updates to your Kubernetes manifests, the agent updates the cluster.
+
+## GitOps configuration reference
+
+The following snippet shows an example of the possible keys and values for the GitOps section of an agent configuration file.
+
+```yaml
+gitops:
+ manifest_projects:
+ - id: gitlab-org/cluster-integration/gitlab-agent
+ default_namespace: my-ns
+ paths:
+ # Read all YAML files from this directory.
+ - glob: '/team1/app1/*.yaml'
+ # Read all .yaml files from team2/apps and all subdirectories.
+ - glob: '/team2/apps/**/*.yaml'
+ # If 'paths' is not specified or is an empty list, the configuration below is used.
+ - glob: '/**/*.{yaml,yml,json}'
+ reconcile_timeout: 3600s
+ dry_run_strategy: none
+ prune: true
+ prune_timeout: 3600s
+ prune_propagation_policy: foreground
+ inventory_policy: must_match
+```
+
+| Keyword | Description |
+|--|--|
+| `manifest_projects` | Projects where your Kubernetes manifests are stored. The agent monitors the files in the repositories in these projects. When manifest files change, the agent deploys the changes to the cluster. |
+| `id` | Required. Path to a Git repository that has Kubernetes manifests in YAML or JSON format. No authentication mechanisms are currently supported. |
+| `default_namespace` | Namespace to use if not set explicitly in object manifest. Also used for inventory `ConfigMap` objects. |
+| `paths` | Repository paths to scan for manifest files. Directories with names that start with a dot `(.)` are ignored. |
+| `paths[].glob` | Required. See [doublestar](https://github.com/bmatcuk/doublestar#about) and [the match function](https://pkg.go.dev/github.com/bmatcuk/doublestar/v2#Match) for globbing rules. |
+| `reconcile_timeout` | Determines whether the applier should wait until all applied resources have been reconciled, and if so, how long to wait. Default is 3600 seconds (1 hour). |
+| `dry_run_strategy` | Determines whether changes [should be performed](https://github.com/kubernetes-sigs/cli-utils/blob/d6968048dcd80b1c7b55d9e4f31fc25f71c9b490/pkg/common/common.go#L68-L89). Can be: `none`, `client`, or `server`. Default is `none`.|
+| `prune` | Determines whether pruning of previously applied objects should happen after apply. Default is `true`. |
+| `prune_timeout` | Determines whether to wait for all resources to be fully deleted after pruning, and if so, how long to wait. Default is 3600 seconds (1 hour). |
+| `prune_propagation_policy` | The deletion propagation policy that [should be used for pruning](https://github.com/kubernetes/apimachinery/blob/44113beed5d39f1b261a12ec398a356e02358307/pkg/apis/meta/v1/types.go#L456-L470). Can be: `orphan`, `background`, or `foreground`. Default is `foreground`. |
+| `inventory_policy` | Determines whether an inventory object can take over objects that belong to another inventory object or don't belong to any inventory object. This is done by determining if the apply/prune operation can go through for a resource based on comparison of the `inventory-id` value in the package and the `owning-inventory` annotation (`config.k8s.io/owning-inventory`) [in the live object](https://github.com/kubernetes-sigs/cli-utils/blob/d6968048dcd80b1c7b55d9e4f31fc25f71c9b490/pkg/inventory/policy.go#L12-L66). Can be: `must_match`, `adopt_if_no_inventory`, or `adopt_all`. Default is `must_match`. |
+
+## Additional resources
+
+The following documentation and examples can help you get started with a GitOps workflow.
+
+- [Managing Kubernetes secrets in a GitOps workflow](gitops/secrets_management.md)
+- [Application and manifest repository example](https://gitlab.com/gitlab-examples/ops/gitops-demo/hello-world-service-gitops)
+
+## Troubleshooting
+
+### Avoiding conflicts when you have multiple projects
+
+The agent watches each glob pattern set under a project's `paths` section independently, and makes updates to the cluster concurrently.
+If changes are found at multiple paths, when the agent attempts to update the cluster,
+a conflict can occur.
+
+To prevent this from happening, consider storing a logical group of manifests in a single place and reference them only once to avoid overlapping globs.
+
+For example, both of these globs match `*.yaml` files in the root directory
+and could cause conflicts:
+
+```yaml
+gitops:
+ manifest_projects:
+ - id: project1
+ paths:
+ - glob: '/**/*.yaml'
+ - glob: '/*.yaml'
+```
+
+Instead, specify a single glob that matches all `*.yaml` files recursively:
+
+```yaml
+gitops:
+ manifest_projects:
+ - id: project1
+ paths:
+ - glob: '/**/*.yaml'
+```
+
+### Use multiple agents or projects
+
+If you store your Kubernetes manifests in separate GitLab projects,
+update your agent configuration file with the location of these projects.
+
+WARNING:
+The project with the agent's
+configuration file can be private or public. Other projects with Kubernetes manifests must be public. Support for private manifest projects is tracked
+in [this issue](https://gitlab.com/gitlab-org/gitlab/-/issues/283885).
diff --git a/doc/user/clusters/agent/gitops/secrets_management.md b/doc/user/clusters/agent/gitops/secrets_management.md
new file mode 100644
index 00000000000..cf520c881bf
--- /dev/null
+++ b/doc/user/clusters/agent/gitops/secrets_management.md
@@ -0,0 +1,61 @@
+---
+stage: Configure
+group: Configure
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
+---
+
+# Managing Kubernetes secrets in a GitOps workflow
+
+You should never store Kubernetes secrets in unencrypted form in a `git` repository. If you use a GitOps workflow, you can follow these steps to securely manage your secrets.
+
+1. Set up the Sealed Secrets controller to manage secrets.
+1. Deploy Docker credentials so the cluster can pull images from the GitLab Container Registry.
+
+## Prerequisites
+
+This setup requires:
+
+- A [GitLab agent for Kubernetes configured for the GitOps workflow](../gitops.md).
+- Access to the cluster to finish the setup.
+
+## Set up the Sealed Secrets controller to manage secrets
+
+You can use the [Sealed Secrets controller](https://github.com/bitnami-labs/sealed-secrets) to store encrypted secrets securely in a `git` repository. The controller decrypts the secret into a standard Kubernetes `Secret` kind resource.
+
+1. Go to [the Sealed Secrets release page](https://github.com/bitnami-labs/sealed-secrets/releases) and download the most recent `controller.yaml` file.
+1. In GitLab, go to the project that contains your Kubernetes manifests and upload the `controller.yaml` file.
+1. Open the agent configuration file (`config.yaml`) and if needed, update the `paths.glob` pattern to match the Sealed Secrets manifest.
+1. Commit and push the changes to GitLab.
+1. Confirm that the Sealed Secrets controller was installed successfully:
+
+ ```shell
+ kubectl get pods -lname=sealed-secrets-controller -n kube-system
+ ```
+
+1. Install the `kubeseal` command line utility by following [the Sealed Secrets instructions](https://github.com/bitnami-labs/sealed-secrets#homebrew).
+1. Get the public key you need to encrypt secrets without direct access to the cluster:
+
+ ```shell
+ kubeseal --fetch-cert > public.pem
+ ```
+
+1. Commit the public key to the repository.
+
+For more details on how the Sealed Secrets controller works, view [the usage instructions](https://github.com/bitnami-labs/sealed-secrets/blob/main/README.md#usage).
+
+## Deploy Docker credentials
+
+To deploy containers from the GitLab Container Registry, you must configure the cluster with the proper Docker registry credentials. You can achieve this by deploying a `docker-registry` type secret.
+
+1. Generate a GitLab token with at least `read-registry` rights. The token can be either a Personal or a Project Access Token.
+1. Create a Kubernetes secret manifest YAML file. Update the values as needed:
+
+ ```shell
+ kubectl create secret docker-registry gitlab-credentials --docker-server=registry.gitlab.example.com --docker-username=<gitlab-username> --docker-password=<gitlab-token> --docker-email=<gitlab-user-email> -n <namespace> --dry-run=client -o yaml > gitlab-credentials.yaml
+ ```
+
+1. Encrypt the secret into a `SealedSecret` manifest:
+
+ ```shell
+ kubeseal --format=yaml --cert=public.pem < gitlab-credentials.yaml > gitlab-credentials.sealed.yaml
+ ```
diff --git a/doc/user/clusters/agent/index.md b/doc/user/clusters/agent/index.md
index 3fb141e402f..a8ad19df2e1 100644
--- a/doc/user/clusters/agent/index.md
+++ b/doc/user/clusters/agent/index.md
@@ -8,23 +8,36 @@ info: To determine the technical writer assigned to the Stage/Group associated w
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/223061) in GitLab 13.4.
> - Support for `grpcs` [introduced](https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent/-/issues/7) in GitLab 13.6.
-> - Agent Server [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/300960) on GitLab.com under `wss://kas.gitlab.com` through an Early Adopter Program in GitLab 13.10.
+> - Agent server [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/300960) on GitLab.com under `wss://kas.gitlab.com` through an Early Adopter Program in GitLab 13.10.
> - The agent became available to every project on GitLab.com in GitLab 13.11.
> - [Moved](https://gitlab.com/groups/gitlab-org/-/epics/6290) from GitLab Premium to GitLab Free in 14.5.
> - [Renamed](https://gitlab.com/groups/gitlab-org/-/epics/7167) from "GitLab Kubernetes Agent" to "GitLab agent for Kubernetes" in GitLab 14.6.
You can connect your Kubernetes cluster with GitLab to deploy, manage,
-and monitor your cloud-native solutions. You can choose from two primary workflows.
+and monitor your cloud-native solutions.
-In a **GitOps workflow**, you keep your Kubernetes manifests in GitLab. You install a GitLab agent in your cluster, and
+To connect a Kubernetes cluster to GitLab, you must first [install an agent in your cluster](install/index.md).
+
+The agent runs in the cluster, and you can use it to:
+
+- Communicate with a cluster, which is behind a firewall or NAT.
+- Access API endpoints in a cluster in real time.
+- Push information about events happening in the cluster.
+- Enable a cache of Kubernetes objects, which are kept up-to-date with very low latency.
+
+For more details about the agent's purpose and architecture, see the [architecture documentation](https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent/-/blob/master/doc/architecture.md).
+
+## Workflows
+
+You can choose from two primary workflows.
+
+In a [**GitOps** workflow](gitops.md), you keep your Kubernetes manifests in GitLab. You install a GitLab agent in your cluster, and
any time you update your manifests, the agent updates the cluster. This workflow is fully driven with Git and is considered pull-based,
because the cluster is pulling updates from your GitLab repository.
-In a **CI/CD** workflow, you use GitLab CI/CD to query and update your cluster by using the Kubernetes API.
+In a [**CI/CD** workflow](ci_cd_tunnel.md), you use GitLab CI/CD to query and update your cluster by using the Kubernetes API.
This workflow is considered push-based, because GitLab is pushing requests from GitLab CI/CD to your cluster.
-Both of these workflows require you to [install an agent in your cluster](install/index.md).
-
## Supported cluster versions
GitLab supports the following Kubernetes versions. You can upgrade your
@@ -32,8 +45,6 @@ Kubernetes version to a supported version at any time:
- 1.20 (support ends on July 22, 2022)
- 1.19 (support ends on February 22, 2022)
-- 1.18 (support ends on November 22, 2021)
-- 1.17 (support ends on September 22, 2021)
GitLab supports at least two production-ready Kubernetes minor
versions at any given time. GitLab regularly reviews the supported versions and
@@ -47,174 +58,15 @@ version. The list of supported versions is based on:
Some GitLab features might work on versions not listed here.
-## Using Kubernetes with GitOps **(PREMIUM)**
-
-With GitOps, you can manage containerized clusters and applications from a Git repository that:
-
-- Is the single source of truth of your system.
-- Is the single place where you operate your system.
-
-By combining GitLab, Kubernetes, and GitOps, you can have:
-
-- GitLab as the GitOps operator.
-- Kubernetes as the automation and convergence system.
-- GitLab CI/CD for Continuous Integration and the agent for Continuous Deployment.
-
-Beyond that, you can use all the features offered by GitLab as
-the all-in-one DevOps platform for your product and your team.
-
-### GitOps workflow **(PREMIUM)**
-
-The agent uses multiple GitLab projects to provide a flexible workflow
-that can suit various needs. This diagram shows these repositories and the main
-The agent uses multiple GitLab projects to provide a flexible workflow.
-This diagram shows these repositories and the main
-actors involved in a deployment:
-
-```mermaid
-sequenceDiagram
- participant D as Developer
- participant A as Application code repository
- participant M as Manifest repository
- participant K as GitLab agent
- participant C as Agent configuration repository
- loop Regularly
- K-->>C: Grab the configuration
- end
- D->>+A: Pushing code changes
- A->>M: Updating manifest
- loop Regularly
- K-->>M: Watching changes
- M-->>K: Pulling and applying changes
- end
-```
-
-For details, view the [architecture documentation](https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent/-/blob/master/doc/architecture.md#high-level-architecture).
-
-To perform GitOps deployments, you need:
-
-- A properly-configured Kubernetes cluster where the GitLab agent is running.
-- A project that contains the agent's configuration file (`config.yaml`) in the repository.
- This file tells the agent which repositories to synchronize with the cluster.
-- A project that contains Kubernetes manifests. Any changes to manifests are applied to the cluster.
-
-You can keep the agent's configuration file and Kubernetes manifests in one project, or you can use multiple.
-
-- One GitLab project (recommended): When you use one project for both the Kubernetes manifests
- and the agent's configuration file, the projects can be either private or public.
-- Two GitLab projects: When you use two different GitLab projects (one for Kubernetes
- manifests and another for the agent's configuration file), the project with Kubernetes manifests must
- be public. The project with the agent's configuration file can be either private or public.
-
-Support for separate private projects is tracked in [this issue](https://gitlab.com/gitlab-org/gitlab/-/issues/283885).
-
-## Remove an agent
-
-You can remove an agent by using the [GitLab UI](#remove-an-agent-through-the-gitlab-ui) or the [GraphQL API](#remove-an-agent-with-the-gitlab-graphql-api).
-
-### Remove an agent through the GitLab UI
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/323055) in GitLab 14.7.
-
-To remove an agent from the UI:
-
-1. On the top bar, select **Menu > Projects** and find the project that contains the agent's configuration file.
-1. From the left sidebar, select **Infrastructure > Kubernetes clusters**.
-1. In the table, in the row for your agent, in the **Options** column, select the vertical ellipsis (**{ellipsis_v}**).
-1. Select **Delete agent**.
-
-### Remove an agent with the GitLab GraphQL API
-
-1. Get the `<cluster-agent-token-id>` from a query in the interactive GraphQL explorer.
- - For GitLab.com, go to <https://gitlab.com/-/graphql-explorer> to open GraphQL Explorer.
- - For self-managed GitLab, go to `https://gitlab.example.com/-/graphql-explorer`, replacing `gitlab.example.com` with your instance's URL.
-
- ```graphql
- query{
- project(fullPath: "<full-path-to-agent-configuration-project>") {
- clusterAgent(name: "<agent-name>") {
- id
- tokens {
- edges {
- node {
- id
- }
- }
- }
- }
- }
- }
- ```
-
-1. Remove an agent record with GraphQL by deleting the `clusterAgentToken`.
-
- ```graphql
- mutation deleteAgent {
- clusterAgentDelete(input: { id: "<cluster-agent-id>" } ) {
- errors
- }
- }
-
- mutation deleteToken {
- clusterAgentTokenDelete(input: { id: "<cluster-agent-token-id>" }) {
- errors
- }
- }
- ```
-
-1. Verify whether the removal occurred successfully. If the output in the Pod logs includes `unauthenticated`, it means that the agent was successfully removed:
-
- ```json
- {
- "level": "warn",
- "time": "2021-04-29T23:44:07.598Z",
- "msg": "GetConfiguration.Recv failed",
- "error": "rpc error: code = Unauthenticated desc = unauthenticated"
- }
- ```
-
-1. Delete the agent in your cluster:
-
- ```shell
- kubectl delete -n gitlab-kubernetes-agent -f ./resources.yml
- ```
-
-## Migrating to the agent from the legacy certificate-based integration
-
-Find out how to [migrate to the agent for Kubernetes](../../infrastructure/clusters/migrate_to_gitlab_agent.md) from the certificate-based integration.
-
-## Kubernetes network security alerts **(ULTIMATE)**
-
-> [Deprecated](https://gitlab.com/groups/gitlab-org/-/epics/7476) in GitLab 14.8, and planned for [removal](https://gitlab.com/groups/gitlab-org/-/epics/7477) in GitLab 15.0.
-
-WARNING:
-Cilium integration is in its end-of-life process. It's [deprecated](https://gitlab.com/groups/gitlab-org/-/epics/7476)
-for use in GitLab 14.8, and planned for [removal](https://gitlab.com/groups/gitlab-org/-/epics/7477)
-in GitLab 15.0.
-
-The agent for Kubernetes also provides an integration with Cilium. This integration provides a simple way to
-generate network policy-related alerts and to surface those alerts in GitLab.
-
-Several components work in concert for the agent to generate the alerts:
-
-- A working Kubernetes cluster.
-- Cilium integration through either of these options:
- - Installation through [cluster management template](../../project/clusters/protect/container_network_security/quick_start_guide.md#use-the-cluster-management-template-to-install-cilium).
- - Enablement of [hubble-relay](https://docs.cilium.io/en/v1.8/concepts/overview/#hubble) on an
- existing installation.
-- One or more network policies through any of these options:
- - Use the [Container Network Policy editor](../../application_security/policies/index.md#container-network-policy-editor) to create and manage policies.
- - Use an [AutoDevOps](../../application_security/policies/index.md#container-network-policy) configuration.
- - Add the required labels and annotations to existing network policies.
-- A configuration repository with [Cilium configured in `config.yaml`](repository.md#surface-network-security-alerts-from-cluster-to-gitlab)
+## Migrate to the agent from the legacy certificate-based integration
-The setup process follows the same [agent's installation steps](install/index.md),
-with the following differences:
-
-- When you define a configuration repository, you must do so with [Cilium settings](repository.md#surface-network-security-alerts-from-cluster-to-gitlab).
-- You do not need to specify the `gitops` configuration section.
+Read about how to [migrate to the agent for Kubernetes](../../infrastructure/clusters/migrate_to_gitlab_agent.md) from the certificate-based integration.
## Related topics
+- [GitOps workflow](gitops.md)
+- [GitLab CI/CD workflow](ci_cd_tunnel.md)
+- [Install the agent](install/index.md)
+- [Work with the agent](repository.md)
- [Troubleshooting](troubleshooting.md)
-- [Contribute to the GitLab agent's development](https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent/-/tree/master/doc)
+- [Contribute to the agent's development](https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent/-/tree/master/doc)
diff --git a/doc/user/clusters/agent/install/index.md b/doc/user/clusters/agent/install/index.md
index 4d196e57f8f..fca80a4a291 100644
--- a/doc/user/clusters/agent/install/index.md
+++ b/doc/user/clusters/agent/install/index.md
@@ -4,92 +4,94 @@ group: Configure
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
-# Install the GitLab Agent **(FREE)**
+# Installing the agent for Kubernetes **(FREE)**
> - [Moved](https://gitlab.com/groups/gitlab-org/-/epics/6290) from GitLab Premium to GitLab Free in 14.5.
> - [Introduced](https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent/-/merge_requests/594) multi-arch images in GitLab 14.8. The first multi-arch release is `v14.8.1`. It supports AMD64 and ARM64 architectures.
+> - [Introduced](https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent/-/merge_requests/603) ARM architecture support in GitLab 14.9.
-To connect a cluster to GitLab, you need to install the GitLab Agent
-onto your cluster.
+To connect a Kubernetes cluster to GitLab, you must install an agent in your cluster.
## Prerequisites
-- An existing Kubernetes cluster. If you don't have a cluster yet, you can create a new cluster on cloud providers, such as:
+Before you can install the agent in your cluster, you need:
+
+- An existing Kubernetes cluster. If you don't have a cluster, you can create one on a cloud provider, like:
- [Google Kubernetes Engine (GKE)](https://cloud.google.com/kubernetes-engine/docs/quickstart)
- [Amazon Elastic Kubernetes Service (EKS)](https://docs.aws.amazon.com/eks/latest/userguide/getting-started.html)
- [Digital Ocean](https://docs.digitalocean.com/products/kubernetes/quickstart/)
-- On self-managed GitLab instances, a GitLab administrator needs to set up the [GitLab Agent Server (KAS)](../../../../administration/clusters/kas.md).
+- On self-managed GitLab instances, a GitLab administrator must set up the [agent server](../../../../administration/clusters/kas.md).
+ On GitLab.com, the agent server is available at `wss://kas.gitlab.com`.
## Installation steps
-To install the GitLab Agent on your cluster:
+To install the agent in your cluster:
-1. [Define a configuration repository](#define-a-configuration-repository).
-1. [Register the Agent with GitLab](#register-the-agent-with-gitlab).
-1. [Install the Agent onto the cluster](#install-the-agent-onto-the-cluster).
+1. [Register the agent with GitLab](#register-the-agent-with-gitlab).
+1. [Install the agent in your cluster](#install-the-agent-in-the-cluster).
-<i class="fa fa-youtube-play youtube" aria-hidden="true"></i> Watch a GitLab 14.2 [walking-through video](https://www.youtube.com/watch?v=XuBpKtsgGkE) with this process.
+<i class="fa fa-youtube-play youtube" aria-hidden="true"></i> Watch a GitLab 14.2 [walk-through of this process](https://www.youtube.com/watch?v=XuBpKtsgGkE).
-When you complete the installation process, you can
-[view your Agent's status and activity information](#view-your-agents).
-You can also [configure](#configure-the-agent) it to your needs.
+### Register the agent with GitLab
-### Define a configuration repository
+> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/5786) in GitLab 14.1, you can create a new agent record directly from the GitLab UI.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/347240) in GitLab 14.9, the agent can be registered without creating an agent configuration file.
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/259669) in GitLab 13.7, the Agent manifest configuration can be added to multiple directories (or subdirectories) of its repository.
-> - Group authorization was [introduced](https://gitlab.com/groups/gitlab-org/-/epics/5784) in GitLab 14.3.
+You must register an agent with GitLab.
-To create an Agent, you need a GitLab repository to hold its
-configuration file. If you already have a repository holding your
-cluster's manifest files, you can use it to store your
-Agent's configuration file and sync them with no further steps.
+Prerequisites:
-#### Create the Agent's configuration file
+- For a [GitLab CI/CD workflow](../ci_cd_tunnel.md), ensure that
+ [GitLab CI/CD is enabled](../../../../ci/enable_or_disable_ci.md#enable-cicd-in-a-project).
-To create an Agent, go to the repository where you want to store
-it and add the Agent's configuration file under:
+To register an agent with GitLab:
-```plaintext
-.gitlab/agents/<agent-name>/config.yaml
-```
+1. On the top bar, select **Menu > Projects** and find your project.
+1. From the left sidebar, select **Infrastructure > Kubernetes clusters**.
+1. Select **Actions**.
+1. From the **Select an agent** dropdown list:
+ - If you want to create a configuration with CI/CD defaults, type a name for the agent.
+ - If you already have an [agent configuration file](#create-an-agent-configuration-file), select it from the list.
+1. Select **Register an agent**.
+1. GitLab generates an access token for the agent. Securely store this token. You need it to install the agent in your cluster and to [update the agent](#update-the-agent-version) to another version.
+1. Copy the command under **Recommended installation method**. You need it when you use the one-liner installation method to install the agent in your cluster.
-You **don't have to add any content** to this file at the moment you
-create it. The fact that the file exists tells GitLab that this is
-an Agent. You can edit it later to [configure the Agent](#configure-the-agent).
+### Create an agent configuration file
-When creating this file, pay special attention to:
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/259669) in GitLab 13.7, the agent configuration file can be added to multiple directories (or subdirectories) of the repository.
+> - Group authorization was [introduced](https://gitlab.com/groups/gitlab-org/-/epics/5784) in GitLab 14.3.
-- The [Agent's naming format](https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent/-/blob/master/doc/identity_and_auth.md#agent-identity-and-name).
-- The file extension: use the `.yaml` extension (`config.yaml`). The `.yml` extension is **not** recognized.
+You can use an agent configuration file to specify details about your implementation.
+Creating a file is optional but is needed if:
-### Register the Agent with GitLab
+- You use [a GitOps workflow](../gitops.md#gitops-configuration-reference) and you want a more advanced configuration.
+- You use a GitLab CI/CD workflow. In that workflow, you must [authorize the agent](../ci_cd_tunnel.md#authorize-the-agent).
-> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/5786) in GitLab 14.1, you can create a new Agent record directly from the GitLab UI.
+To create an agent configuration file, go to the GitLab project. In the repository, create a file called `config.yaml` at this path:
-Now that you've created your Agent's configuration file, register it
-with GitLab.
-When you register the Agent, GitLab generates a token that you need for
-installing the Agent onto your cluster.
+```plaintext
+.gitlab/agents/<agent-name>/config.yaml
+```
-In GitLab, go to the project where you added your Agent's configuration
-file and:
+- Ensure the agent name follows the [naming convention](https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent/-/blob/master/doc/identity_and_auth.md#agent-identity-and-name).
+- Ensure the filename has the `.yaml` file extension (`config.yaml`). The `.yml` extension is not accepted.
+- Add content to the `config.yaml` file:
+ - For a GitOps workflow, view [the configuration reference](../gitops.md#gitops-configuration-reference) for details.
+ - For a GitLab CI/CD workflow, you can leave the file blank for now.
-1. Ensure that [GitLab CI/CD is enabled in your project](../../../../ci/enable_or_disable_ci.md#enable-cicd-in-a-project).
-1. From your project's sidebar, select **Infrastructure > Kubernetes clusters**.
-1. Select **Actions**.
-1. From the **Select an Agent** dropdown list, select the Agent you want to register and select **Register an Agent**.
-1. GitLab generates a registration token for this Agent. Securely store this secret token, as you need it to install the Agent onto your cluster and to [update the Agent](#update-the-agent-version) to another version.
-1. Copy the command under **Recommended installation method**. You need it to install the Agent onto your cluster through the one-liner installation method.
+The agent bootstraps with the GitLab installation URL and an access token,
+and you provide the rest of the configuration in your repository, following
+Infrastructure as Code (IaaC) best practices.
-### Install the Agent onto the cluster
+### Install the agent in the cluster
-To connect your cluster to GitLab, install the registered Agent
-onto your cluster. To install it, you can use either:
+To connect your cluster to GitLab, install the registered agent
+in your cluster. To install it, you can use either:
- [The one-liner installation method](#one-liner-installation).
- [The advanced installation method](#advanced-installation).
-You can use the one-liner installation for trying to use the Agent for the first time, to do internal setups with
+You can use the one-liner installation for trying to use the agent for the first time, to do internal setups with
high trust, and to quickly get started. For long-term production usage, you may want to use the advanced installation
method to benefit from more configuration options.
@@ -99,35 +101,45 @@ The one-liner installation is the simplest process, but you need
Docker installed locally. If you don't have it, you can either install
it or opt to the [advanced installation method](#advanced-installation).
-To install the Agent on your cluster using the one-liner installation:
+To install the agent on your cluster using the one-liner installation:
-1. In your computer, open the terminal and connect to your cluster.
+1. In your computer, open a terminal and [connect to your cluster](https://kubernetes.io/docs/tasks/access-application-cluster/access-cluster/).
1. Run the command you copied when registering your cluster in the previous step.
Optionally, you can [customize the one-liner installation command](#customize-the-one-liner-installation).
##### Customize the one-liner installation
-The one-liner command generated by GitLab:
+By default, the one-liner command generated by GitLab:
-- Creates a namespace for the deployment (`gitlab-kubernetes-agent`).
+- Creates a namespace for the deployment (`gitlab-agent`).
- Sets up a service account with `cluster-admin` rights (see [how to restrict this service account](#customize-the-permissions-for-the-agentk-service-account)).
-- Creates a `Secret` resource for the Agent's registration token.
+- Creates a `Secret` resource for the agent's access token.
- Creates a `Deployment` resource for the `agentk` pod.
-You can edit these parameters according to your needs to customize the
-one-liner installation command at the command line. To find all available
-options, run in your terminal:
+You can edit these parameters to customize the one-liner installation command.
+To view all available options, open a terminal and run this command:
```shell
docker run --pull=always --rm registry.gitlab.com/gitlab-org/cluster-integration/gitlab-agent/cli:stable generate --help
+
+Usage:
+ cli generate [flags]
+
+Flags:
+ --agent-token string Access token registered for agent
+ --agent-version string Version of the agentk image to use (default "v14.8.1")
+ -h, --help help for generate
+ --kas-address string GitLab agent server for Kubernetes address
+ --name-prefix string The prefix to use for names of Kubernetes objects
+ --namespace string Kubernetes namespace to create resources in (default "gitlab-agent")
+ --no-rbac Do not include corresponding Roles and RoleBindings for the agent service account
```
WARNING:
-`--agent-version stable` can be used to refer to the latest stable
-release at the time when the command runs. It's fine for testing
-purposes but for production please make sure to specify a matching
-version explicitly.
+Use `--agent-version stable` to refer to the latest stable
+release at the time when the command runs. For production, however,
+you should explicitly specify a matching version.
#### Advanced installation
@@ -135,105 +147,76 @@ For advanced installation options, use [the `kpt` installation method](https://g
##### Customize the permissions for the `agentk` service account
-The GitLab Agent allows you to fully own your cluster and grant GitLab
-the permissions you want. Still, to facilitate the process, by default the
-generated manifests provide `cluster-admin` rights to the Agent.
+You own your cluster and can grant GitLab the permissions you want.
+By default, however, the generated manifests provide `cluster-admin` rights to the agent.
-You can restrict the Agent's access rights using Kustomize overlays. [An example is commented out](https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent/-/blob/master/build/deployment/gitlab-agent/cluster/kustomization.yaml) in the `kpt` package you retrieved as part of the installation.
+You can restrict the agent's access rights by using Kustomize overlays. [An example is commented out](https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent/-/blob/master/build/deployment/gitlab-agent/cluster/kustomization.yaml) in the `kpt` package you retrieved as part of the installation.
-To create restricted permissions:
+To restrict permissions:
1. Copy the `cluster` directory.
1. Edit the `kustomization.yaml` and `components/*` files based on your requirements.
1. Run `kustomize build <your copied directory> | kubectl apply -f -` to apply your configuration.
-The above setup allows you to regularly update from the upstream package using `kpt pkg update gitlab-agent --strategy resource-merge` and maintain your customizations at the same time.
+#### Update the advanced installation base layer
-## Configure the Agent
+Now you can update from the upstream package by using `kpt pkg update gitlab-agent --strategy resource-merge`.
+When the advanced installation setup changes, you will not need to change your custom overlays.
-When successfully installed, you can [configure the Agent](../repository.md)
-by editing its configuration file.
-When you update the configuration file, GitLab transmits the
-information to the cluster automatically without downtime.
+## Install multiple agents in your cluster
-## View your Agents
+For total separation between teams, you might need to run multiple `agentk` instances in your cluster.
+You might want multiple agents so you can restrict RBAC for every `agentk` deployment.
-> The version of installed `agentk` shown on the Agent tab [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/340882) in GitLab 14.8.
-If you have at least the Developer role, you can access the Agent's
-configuration repository and view the Agent's list:
+To install multiple agents, follow the
+[advanced installation steps](https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent/-/tree/master/build/deployment/gitlab-agent)
+a second time and:
-1. On the left sidebar, select **Infrastructure > Kubernetes clusters**.
-1. Select **Agent** tab to view clusters connected to GitLab through the Agent.
+1. Change the agent name and create a new configuration file.
+1. Register the new agent. You receive a new access token. Each token should be used only with one agent.
+1. Change the namespace or prefix you use for the installation.
-On this page, you can view:
+You should also change the RBAC for the installed `agentk`.
-- All the registered Agents for the current project.
-- The connection status.
-- The version of `agentk` installed on your cluster.
-- The path to each Agent's configuration file.
-
-Furthermore, if you select one of the Agents on your list, you can view its
-[activity information](#view-the-agents-activity-information).
-
-### View the Agent's activity information
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/277323) in GitLab 14.6.
-
-The activity logs help you to identify problems and get the information
-you need for troubleshooting. You can see events from a week before the
-current date. To access an Agent's activity:
-
-1. In your Agent's repository, go to the Agents list as described [above](#view-your-agents).
-1. Select the Agent you want to see the activity.
-
-The activity list includes:
-
-- Agent registration events: when a new token is **created**.
-- Connection events: when an Agent is successfully **connected** to a cluster.
-
-Note that the connection status is logged when you connect an Agent for
-the first time or after more than an hour of inactivity.
-
-To check what else is planned for the Agent's UI and provide feedback,
-see the [related epic](https://gitlab.com/groups/gitlab-org/-/epics/4739).
+## Example projects
-### View vulnerabilities in cluster images **(ULTIMATE)**
+The following example projects can help you get started with the agent.
-> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/6346) in GitLab 14.8 [with a flag](../../../../administration/feature_flags.md) named `cluster_vulnerabilities`. Enabled by default.
+- [Configuration repository with minimal manifests](https://gitlab.com/gitlab-examples/ops/gitops-demo/k8s-agents)
+- [Distinct application and manifest repository example](https://gitlab.com/gitlab-examples/ops/gitops-demo/hello-world-service-gitops)
+- [Auto DevOps setup that uses the CI/CD workflow](https://gitlab.com/gitlab-examples/ops/gitops-demo/hello-world-service)
+- [Cluster management project template example that uses the CI/CD workflow](https://gitlab.com/gitlab-examples/ops/gitops-demo/cluster-management)
-Users with at least the [Developer role](../../../permissions.md)
-can view cluster vulnerabilities. You can access them through the [vulnerability report](../../../application_security/vulnerabilities/index.md)
-or in your cluster's image through the following process:
+## Upgrades and version compatibility
-1. Configure [cluster image scanning](../../../application_security/cluster_image_scanning/index.md)
- to your build process.
-1. Go to your Agent's configuration repository.
-1. On the left sidebar, select **Infrastructure > Kubernetes clusters**.
-1. Select the **Agent** tab.
-1. Select the Agent you want to see the vulnerabilities for.
+The agent has two major components: `agentk` and `kas`.
+GitLab provides `kas` installers built into the various GitLab installation methods.
+The required `kas` version corresponds to the GitLab `major.minor` (X.Y) versions.
-![Cluster Agent security tab UI](../../img/cluster_agent_security_tab_v14_8.png)
+At the same time, `agentk` and `kas` can differ by 1 minor version in either direction. For example,
+`agentk` 14.4 supports `kas` 14.3, 14.4, and 14.5 (regardless of the patch).
-## Create multiple Agents
+A feature introduced in a given GitLab minor version might work with other `agentk` or `kas` versions.
+To ensure it works, use at least the same `agentk` and `kas` minor version. For example,
+if your GitLab version is 14.2, use at least `agentk` 14.2 and `kas` 14.2.
-You can create and install multiple Agents using the same process
-documented above. Give each Agent's configuration file a unique name
-and you're good to go. You can create multiple Agents, for example:
+We recommend upgrading your `kas` installations together with GitLab instances' upgrades, and to
+[upgrade the `agentk` installations](#update-the-agent-version) after upgrading GitLab.
-- To reach your cluster from different projects.
-- To connect multiple clusters to GitLab.
+The available `agentk` and `kas` versions are available in
+[the Container Registry](https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent/container_registry/).
-## Update the Agent version
+### Update the agent version
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/340882) in GitLab 14.8, GitLab warns you on the Agent's list page to update the Agent version installed on your cluster.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/340882) in GitLab 14.8, GitLab warns you on the agent's list page to update the agent version installed on your cluster.
-To update the Agent's version on your cluster, you need to re-run the [installation command](#install-the-agent-onto-the-cluster)
+To update the agent's version, re-run the [installation command](#install-the-agent-in-the-cluster)
with a newer `--agent-version`. Make sure to specify the other required parameters: `--kas-address`, `--namespace`, and `--agent-token`.
-You can find the available `agentk` versions in [the container registry](https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent/container_registry/1223205?sort=desc).
+The available `agentk` versions are in [the Container Registry](https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent/container_registry/1223205?sort=desc).
-If you don't have access to your Agent's token, you can retrieve it from your cluster:
+If you don't have access to your agent's access token, you can retrieve it from your cluster:
-1. On your computer, open the terminal and connect to your cluster.
+1. Open a terminal and connect to your cluster.
1. To retrieve the namespace, run:
```shell
@@ -246,33 +229,8 @@ If you don't have access to your Agent's token, you can retrieve it from your cl
kubectl -n <namespace> get secrets
```
-1. To retrieve the token, run:
+1. To retrieve the access token, run:
```shell
kubectl -n <namespace> get secret <secret-name> --template={{.data.token}} | base64 --decode
```
-
-## Example projects
-
-The following example projects can help you get started with the Agent.
-
-- [Configuration repository](https://gitlab.com/gitlab-org/configure/examples/kubernetes-agent)
-- This basic GitOps example deploys NGINX: [Manifest repository](https://gitlab.com/gitlab-org/configure/examples/gitops-project)
-
-## Upgrades and version compatibility
-
-The Agent is comprised of two major components: `agentk` and `kas`.
-As we provide `kas` installers built into the various GitLab installation methods, the required `kas` version corresponds to the GitLab `major.minor` (X.Y) versions.
-
-At the same time, `agentk` and `kas` can differ by 1 minor version in either direction. For example,
-`agentk` 14.4 supports `kas` 14.3, 14.4, and 14.5 (regardless of the patch).
-
-A feature introduced in a given GitLab minor version might work with other `agentk` or `kas` versions.
-To make sure that it works, use at least the same `agentk` and `kas` minor version. For example,
-if your GitLab version is 14.2, use at least `agentk` 14.2 and `kas` 14.2.
-
-We recommend upgrading your `kas` installations together with GitLab instances' upgrades, and to
-[upgrade the `agentk` installations](#update-the-agent-version) after upgrading GitLab.
-
-The available `agentk` and `kas` versions can be found in
-[the container registry](https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent/container_registry/).
diff --git a/doc/user/clusters/agent/repository.md b/doc/user/clusters/agent/repository.md
index a9d9fd1c13d..3f743d34e0a 100644
--- a/doc/user/clusters/agent/repository.md
+++ b/doc/user/clusters/agent/repository.md
@@ -1,335 +1,169 @@
---
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
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
-# Agent configuration repository **(FREE)**
+# Working with the agent for Kubernetes **(FREE)**
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/259669) in GitLab 13.7.
-> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/3834) in GitLab 13.11, the GitLab Agent became available on GitLab.com.
+> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/3834) in GitLab 13.11, the GitLab agent became available on GitLab.com.
> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/5784) the `ci_access` attribute in GitLab 14.3.
> - [Moved](https://gitlab.com/groups/gitlab-org/-/epics/6290) from GitLab Premium to GitLab Free in 14.5.
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/332227) in GitLab 14.0, the `resource_inclusions` and `resource_exclusions` attributes were removed and `reconcile_timeout`, `dry_run_strategy`, `prune`, `prune_timeout`, `prune_propagation_policy`, and `inventory_policy` attributes were added.
-The [GitLab Agent](index.md) supports hosting your configuration for
-multiple agents in a single repository. These agents can be running
-in the same cluster or in multiple clusters, and potentially with more than one agent per cluster.
+## View your agents
-The Agent bootstraps with the GitLab installation URL and an authentication token,
-and you provide the rest of the configuration in your repository, following
-Infrastructure as Code (IaaC) best practices.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/340882) in GitLab 14.8, the installed `agentk` version is displayed on the **Agent** tab.
-A minimal repository layout looks like this, with `my-agent-1` as the name
-of your Agent:
+Prerequisite:
-```plaintext
-|- .gitlab
- |- agents
- |- my-agent-1
- |- config.yaml
-```
-
-Make sure that `<agent-name>` conforms to the [Agent's naming format](https://gitlab.com/gitlab-org/cluster-integration/gitlab-agent/-/blob/master/doc/identity_and_auth.md#agent-identity-and-name).
+- You must have at least the Developer role.
-## Synchronize manifest projects **(PREMIUM)**
+To view the list of agents:
-Your `config.yaml` file contains a `gitops` section, which contains a `manifest_projects`
-section. Each `id` in the `manifest_projects` section is the path to a Git repository
-with Kubernetes resource definitions in YAML or JSON format. The Agent monitors
-each project you declare, and when the project changes, GitLab deploys the changes
-using the Agent.
+1. On the top bar, select **Menu > Projects** and find the project that contains your agent configuration file.
+1. On the left sidebar, select **Infrastructure > Kubernetes clusters**.
+1. Select **Agent** tab to view clusters connected to GitLab through the agent.
-WARNING:
-When using separate GitLab projects for manifest files and configuration repository, the manifests project must be public.
+On this page, you can view:
-To use multiple YAML files, specify a `paths` attribute in the `gitops.manifest_projects` section.
+- All the registered agents for the current project.
+- The connection status.
+- The version of `agentk` installed on your cluster.
+- The path to each agent configuration file.
-```yaml
-gitops:
- # Manifest projects are watched by the agent. Whenever a project changes,
- # GitLab deploys the changes using the agent.
- manifest_projects:
- # No authentication mechanisms are currently supported.
- # The `id` is a path to a Git repository with Kubernetes resource definitions
- # in YAML or JSON format.
- - id: gitlab-org/cluster-integration/gitlab-agent
- # Namespace to use if not set explicitly in object manifest.
- # Also used for inventory ConfigMap objects.
- default_namespace: my-ns
- # Paths inside of the repository to scan for manifest files.
- # Directories with names starting with a dot are ignored.
- paths:
- # Read all .yaml files from team1/app1 directory.
- # See https://github.com/bmatcuk/doublestar#about and
- # https://pkg.go.dev/github.com/bmatcuk/doublestar/v2#Match for globbing rules.
- - glob: '/team1/app1/*.yaml'
- # Read all .yaml files from team2/apps and all subdirectories
- - glob: '/team2/apps/**/*.yaml'
- # If 'paths' is not specified or is an empty list, the configuration below is used
- - glob: '/**/*.{yaml,yml,json}'
- # Reconcile timeout defines whether the applier should wait
- # until all applied resources have been reconciled, and if so,
- # how long to wait.
- reconcile_timeout: 3600s # 1 hour by default
- # Dry run strategy defines whether changes should actually be performed,
- # or if it is just talk and no action.
- # https://github.com/kubernetes-sigs/cli-utils/blob/d6968048dcd80b1c7b55d9e4f31fc25f71c9b490/pkg/common/common.go#L68-L89
- # Can be: none, client, server
- dry_run_strategy: none # 'none' by default
- # Prune defines whether pruning of previously applied
- # objects should happen after apply.
- prune: true # enabled by default
- # Prune timeout defines whether we should wait for all resources
- # to be fully deleted after pruning, and if so, how long we should
- # wait.
- prune_timeout: 3600s # 1 hour by default
- # Prune propagation policy defines the deletion propagation policy
- # that should be used for pruning.
- # https://github.com/kubernetes/apimachinery/blob/44113beed5d39f1b261a12ec398a356e02358307/pkg/apis/meta/v1/types.go#L456-L470
- # Can be: orphan, background, foreground
- prune_propagation_policy: foreground # 'foreground' by default
- # Inventory policy defines if an inventory object can take over
- # objects that belong to another inventory object or don't
- # belong to any inventory object.
- # This is done by determining if the apply/prune operation
- # can go through for a resource based on the comparison
- # the inventory-id value in the package and the owning-inventory
- # annotation (config.k8s.io/owning-inventory) in the live object.
- # https://github.com/kubernetes-sigs/cli-utils/blob/d6968048dcd80b1c7b55d9e4f31fc25f71c9b490/pkg/inventory/policy.go#L12-L66
- # Can be: must_match, adopt_if_no_inventory, adopt_all
- inventory_policy: must_match # 'must_match' by default
-```
+## View an agent's activity information
-### Using multiple manifest projects
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/277323) in GitLab 14.6.
-Storing Kubernetes manifests in more than one repository can be handy, for example:
+The activity logs help you to identify problems and get the information
+you need for troubleshooting. You can see events from a week before the
+current date. To view an agent's activity:
-- You may store manifests for different applications in separate repositories.
-- Different teams can work on manifests of independent projects in separate repositories.
+1. On the top bar, select **Menu > Projects** and find the project that contains your agent configuration file.
+1. On the left sidebar, select **Infrastructure > Kubernetes clusters**.
+1. Select the agent you want to see activity for.
-To use multiple repositories as the source of Kubernetes manifests, specify them in the list of
-`manifest_projects` in your `config.yaml`:
+The activity list includes:
-```yaml
-gitops:
- manifest_projects:
- - id: group1/project1
- - id: group2/project2
-```
+- Agent registration events: When a new token is **created**.
+- Connection events: When an agent is successfully **connected** to a cluster.
-Note that repositories are synchronized **concurrently** and **independently** from each other,
-which means that, ideally, there should **not** be any dependencies shared by these repositories.
-Storing a logical group of manifests in a single repository may work better than distributing it across several
-repositories.
+The connection status is logged when you connect an agent for
+the first time or after more than an hour of inactivity.
-You cannot use a single repository as a source for multiple concurrent synchronization
-operations. If such functionality is needed, you may use multiple agents reading
-manifests from the same repository.
+View and provide feedback about the UI in [this epic](https://gitlab.com/groups/gitlab-org/-/epics/4739).
-Ensure not to specify "overlapping" globs to avoid synchronizing the same files more than once.
-This is detected by the Agent and leads to an error.
+## Debug the agent
-INCORRECT - both globs match `*.yaml` files in the root directory:
+To debug the cluster-side component (`agentk`) of the agent, set the log
+level according to the available options:
-```yaml
-gitops:
- manifest_projects:
- - id: project1
- paths:
- - glob: '/**/*.yaml'
- - glob: '/*.yaml'
-```
+- `off`
+- `warning`
+- `error`
+- `info`
+- `debug`
-CORRECT - single globs matches all `*.yaml` files recursively:
+The log level defaults to `info`. You can change it by using a top-level `observability`
+section in the configuration file, for example:
```yaml
-gitops:
- manifest_projects:
- - id: project1
- paths:
- - glob: '/**/*.yaml'
+observability:
+ logging:
+ level: debug
```
-## Authorize projects and groups to use an Agent
-
-With the [CI/CD Tunnel](ci_cd_tunnel.md), you can authorize [projects](#authorize-projects-to-use-an-agent)
-and [groups](#authorize-groups-to-use-an-agent) to use an Agent.
-
-Then, you can reach your cluster from authorized projects and [run Kubernetes commands from GitLab CI/CD scripts](#run-kubectl-commands-using-the-cicd-tunnel)
-in these projects.
-
-### Authorize projects to use an Agent
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/327850) in GitLab 14.4.
-
-To grant projects access to the Agent through the CI/CD Tunnel:
-
-1. Go to your Agent's configuration repository.
-1. Edit the Agent's configuration file (`config.yaml`).
-1. Add the `projects` attribute into `ci_access`.
-1. Identify the project through its path:
-
- ```yaml
- ci_access:
- projects:
- - id: path/to/project
+## Reset the agent token
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/327152) in GitLab 14.9.
+
+To reset the agent token without downtime:
+
+1. Create a new token:
+ 1. On the top bar, select **Menu > Projects** and find your project.
+ 1. On the left sidebar, select **Infrastructure > Kubernetes clusters**.
+ 1. Select the agent you want to create a token for.
+ 1. On the **Tokens** tab, select **Create token**.
+ 1. Enter token's name and description (optional) and select **Create token**.
+1. Securely store the generated token.
+1. Use the token to [install the agent in your cluster](install/index.md#install-the-agent-in-the-cluster) and to [update the agent](install/index.md#update-the-agent-version) to another version.
+1. Delete the token you're no longer using.
+
+## Remove an agent
+
+You can remove an agent by using the [GitLab UI](#remove-an-agent-through-the-gitlab-ui) or the
+[GraphQL API](#remove-an-agent-with-the-gitlab-graphql-api). The agent and any associated tokens
+are removed from GitLab, but no changes are made in your Kubernetes cluster. You must
+clean up those resources manually.
+
+### Remove an agent through the GitLab UI
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/323055) in GitLab 14.7.
+
+To remove an agent from the UI:
+
+1. On the top bar, select **Menu > Projects** and find the project that contains the agent configuration file.
+1. From the left sidebar, select **Infrastructure > Kubernetes clusters**.
+1. In the table, in the row for your agent, in the **Options** column, select the vertical ellipsis (**{ellipsis_v}**).
+1. Select **Delete agent**.
+
+### Remove an agent with the GitLab GraphQL API
+
+1. Get the `<cluster-agent-token-id>` from a query in the interactive GraphQL explorer.
+ - For GitLab.com, go to <https://gitlab.com/-/graphql-explorer> to open GraphQL Explorer.
+ - For self-managed GitLab, go to `https://gitlab.example.com/-/graphql-explorer`, replacing `gitlab.example.com` with your instance's URL.
+
+ ```graphql
+ query{
+ project(fullPath: "<full-path-to-agent-configuration-project>") {
+ clusterAgent(name: "<agent-name>") {
+ id
+ tokens {
+ edges {
+ node {
+ id
+ }
+ }
+ }
+ }
+ }
+ }
```
-### Authorize groups to use an Agent
+1. Remove an agent record with GraphQL by deleting the `clusterAgentToken`.
-> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/5784) in GitLab 14.3.
+ ```graphql
+ mutation deleteAgent {
+ clusterAgentDelete(input: { id: "<cluster-agent-id>" } ) {
+ errors
+ }
+ }
-To grant access to all projects within a group:
-
-1. Go to your Agent's configuration repository.
-1. Edit the Agent's configuration file (`config.yaml`).
-1. Add the `groups` attribute into `ci_access`.
-1. Identify the group or subgroup through its path:
-
- ```yaml
- ci_access:
- groups:
- - id: path/to/group/subgroup
+ mutation deleteToken {
+ clusterAgentTokenDelete(input: { id: "<cluster-agent-token-id>" }) {
+ errors
+ }
+ }
```
-## Run `kubectl` commands using the CI/CD Tunnel
-
-After you authorize your project or group to use the Agent, you need to
-configure the project's `.gitlab-ci.yaml` file to access the Agent.
-This makes it possible to deploy applications to your cluster and run
-any Kubernetes-specific commands from the authorized project.
-
-First, configure your Agent:
-
-1. Go to your Agent's configuration repository.
-1. Edit your Agent's `config.yaml` file authorizing the [project](#authorize-projects-to-use-an-agent) or [group](#authorize-groups-to-use-an-agent) you want to run Kubernetes commands from.
-
-Then, configure the other project:
-
-1. Go to the project where you want to run Kubernetes commands from.
-1. Edit your project's `.gitlab-ci.yml` file.
-1. Set your Agent's context in the first command of the script with the format `path/to/agent/repository:agent-name`.
-1. Run Kubernetes commands.
-
-For example:
-
-```yaml
- deploy:
- image:
- name: bitnami/kubectl:latest
- entrypoint: [""]
- script:
- - kubectl config use-context path/to/agent/repository:agent-name
- - kubectl get pods
-```
-
-When you use the Agent, KubeContexts are named as `path/to/agent/repository:agent-name`.
-
-To get the list of available contexts:
-
-1. Open your terminal and connect to your cluster.
-1. Run `kubectl config get-contexts`.
-
-### `kubectl` commands not supported
-
-The commands `kubectl exec`, `kubectl cp`, and `kubectl attach` are not supported by the CI/CD tunnel.
-Anything else that uses the same API endpoints does not work either as they use the deprecated
-SPDY protocol.
-We [plan to add support for these features](https://gitlab.com/gitlab-org/gitlab/-/issues/346248)
-in a future version of GitLab.
-
-### `kubectl` requires TLS
-
-`kubectl` would never send credentials over an unencrypted connection. Self-managed users should ensure that their
-GitLab instance is configured with TLS for the CI/CD tunnel feature to work. Trying to use it without TLS
-would produce errors:
-
-```shell
-$ kubectl get pods
-error: You must be logged in to the server (the server has asked for the client to provide credentials)
-```
-
-## Use impersonation to restrict project and group access **(PREMIUM)**
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/345014) in GitLab 14.5.
-
-By default, the [CI/CD Tunnel](ci_cd_tunnel.md) inherits all the permissions from the service account used to install the
-Agent in the cluster.
-To restrict access to your cluster, you can use [impersonation](https://kubernetes.io/docs/reference/access-authn-authz/authentication/#user-impersonation).
-
-To specify impersonations, use the `access_as` attribute in your Agent's configuration file and use Kubernetes RBAC rules to manage impersonated account permissions.
-
-You can impersonate:
-
-- The Agent itself (default).
-- The CI job that accesses the cluster.
-- A specific user or system account defined within the cluster.
-
-### Impersonate the Agent
-
-The Agent is impersonated by default. You don't need to do anything to impersonate it.
-
-### Impersonate the CI job that accesses the cluster
-
-To impersonate the CI job that accesses the cluster, add the `ci_job: {}` key-value
-under the `access_as` key.
-
-When the agent makes the request to the actual Kubernetes API, it sets the
-impersonation credentials in the following way:
-
-- `UserName` is set to `gitlab:ci_job:<job id>`. Example: `gitlab:ci_job:1074499489`.
-- `Groups` is set to:
- - `gitlab:ci_job` to identify all requests coming from CI jobs.
- - The list of IDs of groups the project is in.
- - The project ID.
- - The slug of the environment this job belongs to.
+1. Verify whether the removal occurred successfully. If the output in the Pod logs includes `unauthenticated`, it means that the agent was successfully removed:
- Example: for a CI job in `group1/group1-1/project1` where:
-
- - Group `group1` has ID 23.
- - Group `group1/group1-1` has ID 25.
- - Project `group1/group1-1/project1` has ID 150.
- - Job running in a prod environment.
-
- Group list would be `[gitlab:ci_job, gitlab:group:23, gitlab:group:25, gitlab:project:150, gitlab:project_env:150:prod]`.
-
-- `Extra` carries extra information about the request. The following properties are set on the impersonated identity:
-
-| Property | Description |
-| -------- | ----------- |
-| `agent.gitlab.com/id` | Contains the agent ID. |
-| `agent.gitlab.com/config_project_id` | Contains the agent's configuration project ID. |
-| `agent.gitlab.com/project_id` | Contains the CI project ID. |
-| `agent.gitlab.com/ci_pipeline_id` | Contains the CI pipeline ID. |
-| `agent.gitlab.com/ci_job_id` | Contains the CI job ID. |
-| `agent.gitlab.com/username` | Contains the username of the user the CI job is running as. |
-| `agent.gitlab.com/environment_slug` | Contains the slug of the environment. Only set if running in an environment. |
-
-Example to restrict access by the CI job's identity:
-
-```yaml
-ci_access:
- projects:
- - id: path/to/project
- access_as:
- ci_job: {}
-```
-
-### Impersonate a static identity
-
-For the given CI/CD Tunnel connection, you can use a static identity for the impersonation.
-
-Add the `impersonate` key under the `access_as` key to make the request using the provided identity.
-
-The identity can be specified with the following keys:
+ ```json
+ {
+ "level": "warn",
+ "time": "2021-04-29T23:44:07.598Z",
+ "msg": "GetConfiguration.Recv failed",
+ "error": "rpc error: code = Unauthenticated desc = unauthenticated"
+ }
+ ```
-- `username` (required)
-- `uid`
-- `groups`
-- `extra`
+1. Delete the agent in your cluster:
-See the [official Kubernetes documentation for more details](https://kubernetes.io/docs/reference/access-authn-authz/authentication/#user-impersonation) on the usage of these keys.
+ ```shell
+ kubectl delete -n gitlab-kubernetes-agent -f ./resources.yml
+ ```
## Surface network security alerts from cluster to GitLab **(ULTIMATE)**
@@ -340,7 +174,28 @@ Cilium integration is in its end-of-life process. It's [deprecated](https://gitl
for use in GitLab 14.8, and planned for [removal](https://gitlab.com/groups/gitlab-org/-/epics/7477)
in GitLab 15.0.
-The GitLab Agent provides an [integration with Cilium](index.md#kubernetes-network-security-alerts).
+The agent for Kubernetes also provides an integration with Cilium. This integration provides a simple way to
+generate network policy-related alerts and to surface those alerts in GitLab.
+
+Several components work in concert for the agent to generate the alerts:
+
+- A working Kubernetes cluster.
+- Cilium integration through either of these options:
+ - Installation through [cluster management template](../../project/clusters/protect/container_network_security/quick_start_guide.md#use-the-cluster-management-template-to-install-cilium).
+ - Enablement of [hubble-relay](https://docs.cilium.io/en/v1.8/concepts/overview/#hubble) on an
+ existing installation.
+- One or more network policies through any of these options:
+ - Use the [Container Network Policy editor](../../application_security/policies/index.md#container-network-policy-editor) to create and manage policies.
+ - Use an [AutoDevOps](../../application_security/policies/index.md#container-network-policy) configuration.
+ - Add the required labels and annotations to existing network policies.
+- A configuration repository with [Cilium configured in `config.yaml`](repository.md#surface-network-security-alerts-from-cluster-to-gitlab)
+
+The setup process follows the same [agent's installation steps](install/index.md),
+with the following differences:
+
+- When you define a configuration repository, you must do so with [Cilium settings](repository.md#surface-network-security-alerts-from-cluster-to-gitlab).
+- You do not need to specify the `gitops` configuration section.
+
To integrate, add a top-level `cilium` section to your `config.yml` file. Currently, the
only configuration option is the Hubble relay address:
@@ -357,107 +212,3 @@ you can use `hubble-relay.gitlab-managed-apps.svc.cluster.local:80` as the addre
cilium:
hubble_relay_address: "hubble-relay.gitlab-managed-apps.svc.cluster.local:80"
```
-
-## Scan your container images for vulnerabilities **(ULTIMATE)**
-
-You can use [cluster image scanning](../../application_security/cluster_image_scanning/index.md)
-to scan container images in your cluster for security vulnerabilities.
-
-To begin scanning all resources in your cluster, add a `starboard`
-configuration block to your agent's `config.yaml` with no `filters`:
-
-```yaml
-starboard:
- vulnerability_report:
- filters: []
-```
-
-The namespaces that are able to be scanned depend on the [Starboard Operator install mode](https://aquasecurity.github.io/starboard/latest/operator/configuration/#install-modes).
-By default, the Starboard Operator only scans resources in the `default` namespace. To change this
-behavior, edit the `STARBOARD_OPERATOR` environment variable in the `starboard-operator` deployment
-definition.
-
-By adding filters, you can limit scans by:
-
-- Resource name
-- Kind
-- Container name
-- Namespace
-
-```yaml
-starboard:
- vulnerability_report:
- filters:
- - namespaces:
- - staging
- - production
- kinds:
- - Deployment
- - DaemonSet
- containers:
- - ruby
- - postgres
- - nginx
- resources:
- - my-app-name
- - postgres
- - ingress-nginx
-```
-
-A resource is scanned if the resource matches any of the given names and all of the given filter
-types (`namespaces`, `kinds`, `containers`, `resources`). If a filter type is omitted, then all
-names are scanned. In this example, a resource isn't scanned unless it has a container named `ruby`,
-`postgres`, or `nginx`, and it's a `Deployment`:
-
-```yaml
-starboard:
- vulnerability_report:
- filters:
- - kinds:
- - Deployment
- containers:
- - ruby
- - postgres
- - nginx
-```
-
-There is also a global `namespaces` field that applies to all filters:
-
-```yaml
-starboard:
- vulnerability_report:
- namespaces:
- - production
- filters:
- - kinds:
- - Deployment
- - kinds:
- - DaemonSet
- resources:
- - log-collector
-```
-
-In this example, the following resources are scanned:
-
-- All deployments (`Deployment`) in the `production` namespace
-- All daemon sets (`DaemonSet`) named `log-collector` in the `production` namespace
-
-## Debugging
-
-To debug the cluster-side component (`agentk`) of the Agent, set the log
-level according to the available options:
-
-- `off`
-- `warning`
-- `error`
-- `info`
-- `debug`
-
-The log level defaults to `info`. You can change it by using a top-level `observability`
-section in the configuration file, for example:
-
-```yaml
-observability:
- logging:
- level: debug
-```
diff --git a/doc/user/clusters/agent/runner.md b/doc/user/clusters/agent/runner.md
deleted file mode 100644
index c40733bd7a5..00000000000
--- a/doc/user/clusters/agent/runner.md
+++ /dev/null
@@ -1,9 +0,0 @@
----
-redirect_to: 'https://docs.gitlab.com/runner/install/kubernetes-agent.html'
-remove_date: '2022-02-01'
----
-
-This document was moved to [another location](https://docs.gitlab.com/runner/install/kubernetes-agent.html).
-
-<!-- This redirect file can be deleted after <2022-02-01>. -->
-<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/#move-or-rename-a-page --> \ No newline at end of file
diff --git a/doc/user/clusters/agent/troubleshooting.md b/doc/user/clusters/agent/troubleshooting.md
index 2c9f98b7c45..a5e568837ad 100644
--- a/doc/user/clusters/agent/troubleshooting.md
+++ b/doc/user/clusters/agent/troubleshooting.md
@@ -4,9 +4,9 @@ group: Configure
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
-# Troubleshooting the GitLab Agent for Kubernetes
+# Troubleshooting the GitLab agent for Kubernetes
-When you are using the GitLab Agent for Kubernetes, you might experience issues you need to troubleshoot.
+When you are using the GitLab agent for Kubernetes, you might experience issues you need to troubleshoot.
You can start by viewing the service logs:
@@ -14,7 +14,7 @@ You can start by viewing the service logs:
kubectl logs -f -l=app=gitlab-agent -n gitlab-kubernetes-agent
```
-If you are a GitLab administrator, you can also view the [GitLab Agent Server logs](../../../administration/clusters/kas.md#troubleshooting).
+If you are a GitLab administrator, you can also view the [GitLab agent server logs](../../../administration/clusters/kas.md#troubleshooting).
## Transport: Error while dialing failed to WebSocket dial
@@ -28,7 +28,7 @@ If you are a GitLab administrator, you can also view the [GitLab Agent Server lo
```
This error is shown if there are some connectivity issues between the address
-specified as `kas-address`, and your Agent pod. To fix it, make sure that you
+specified as `kas-address`, and your agent pod. To fix it, make sure that you
specified the `kas-address` correctly.
```json
@@ -188,6 +188,5 @@ Alternatively, you can mount the certificate file at a different location and in
}
```
-This error is shown if the manifest project is not public. To fix it,
-[make sure your manifest project is public](repository.md#synchronize-manifest-projects) or your manifest files
-are stored in the Agent's configuration repository.
+This error is shown if the manifest project is not public. To fix it, make sure your manifest project is public or your manifest files
+are stored in the agent's configuration repository.
diff --git a/doc/user/clusters/agent/vulnerabilities.md b/doc/user/clusters/agent/vulnerabilities.md
new file mode 100644
index 00000000000..480b09ff2ab
--- /dev/null
+++ b/doc/user/clusters/agent/vulnerabilities.md
@@ -0,0 +1,113 @@
+---
+stage: Configure
+group: Configure
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
+---
+
+# Container vulnerability scanning **(ULTIMATE)**
+
+> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/6346) in GitLab 14.8.
+
+To view cluster vulnerabilities, you can view the [vulnerability report](../../application_security/vulnerabilities/index.md).
+You can also configure your agent so the vulnerabilities are displayed with other agent information in GitLab.
+
+## View cluster vulnerabilities
+
+Prerequisite:
+
+- You must have at least the Developer role.
+- [Cluster image scanning](../../application_security/cluster_image_scanning/index.md)
+ must be part of your build process.
+
+To view vulnerability information in GitLab:
+
+1. On the top bar, select **Menu > Projects** and find the project that contains the agent configuration file.
+1. On the left sidebar, select **Infrastructure > Kubernetes clusters**.
+1. Select the **Agent** tab.
+1. Select the agent you want to see the vulnerabilities for.
+
+![Cluster agent security tab UI](../img/cluster_agent_security_tab_v14_8.png)
+
+## Enable cluster vulnerability scanning **(ULTIMATE)**
+
+You can use [cluster image scanning](../../application_security/cluster_image_scanning/index.md)
+to scan container images in your cluster for security vulnerabilities.
+
+To begin scanning all resources in your cluster, add a `starboard`
+configuration block to your agent configuration file with no `filters`:
+
+```yaml
+starboard:
+ vulnerability_report:
+ filters: []
+```
+
+The namespaces that are able to be scanned depend on the [Starboard Operator install mode](https://aquasecurity.github.io/starboard/latest/operator/configuration/#install-modes).
+By default, the Starboard Operator only scans resources in the `default` namespace. To change this
+behavior, edit the `STARBOARD_OPERATOR` environment variable in the `starboard-operator` deployment
+definition.
+
+By adding filters, you can limit scans by:
+
+- Resource name
+- Kind
+- Container name
+- Namespace
+
+```yaml
+starboard:
+ vulnerability_report:
+ filters:
+ - namespaces:
+ - staging
+ - production
+ kinds:
+ - Deployment
+ - DaemonSet
+ containers:
+ - ruby
+ - postgres
+ - nginx
+ resources:
+ - my-app-name
+ - postgres
+ - ingress-nginx
+```
+
+A resource is scanned if the resource matches any of the given names and all of the given filter
+types (`namespaces`, `kinds`, `containers`, `resources`). If a filter type is omitted, then all
+names are scanned. In this example, a resource isn't scanned unless it has a container named `ruby`,
+`postgres`, or `nginx`, and it's a `Deployment`:
+
+```yaml
+starboard:
+ vulnerability_report:
+ filters:
+ - kinds:
+ - Deployment
+ containers:
+ - ruby
+ - postgres
+ - nginx
+```
+
+There is also a global `namespaces` field that applies to all filters:
+
+```yaml
+starboard:
+ vulnerability_report:
+ namespaces:
+ - production
+ filters:
+ - kinds:
+ - Deployment
+ - kinds:
+ - DaemonSet
+ resources:
+ - log-collector
+```
+
+In this example, the following resources are scanned:
+
+- All deployments (`Deployment`) in the `production` namespace.
+- All daemon sets (`DaemonSet`) named `log-collector` in the `production` namespace.
diff --git a/doc/user/clusters/applications.md b/doc/user/clusters/applications.md
index f880e603133..2bcfea50ee3 100644
--- a/doc/user/clusters/applications.md
+++ b/doc/user/clusters/applications.md
@@ -980,7 +980,7 @@ podAnnotations:
The only information to be changed here is the profile name which is `profile-one`
in this example. Refer to the
-[AppArmor tutorial](https://kubernetes.io/docs/tutorials/clusters/apparmor/#securing-a-pod)
+[AppArmor tutorial](https://kubernetes.io/docs/tutorials/security/apparmor/#securing-a-pod)
for more information on how AppArmor is integrated in Kubernetes.
#### Using PodSecurityPolicy in your deployments
@@ -1017,7 +1017,7 @@ securityPolicies:
```
This example creates a single policy named `example` with the provided specification,
-and enables [AppArmor annotations](https://kubernetes.io/docs/tutorials/clusters/apparmor/#podsecuritypolicy-annotations) on it.
+and enables [AppArmor annotations](https://kubernetes.io/docs/tutorials/security/apparmor/#podsecuritypolicy-annotations) on it.
Support for installing the AppArmor managed application is provided by the
GitLab Container Security group. If you run into unknown issues,
diff --git a/doc/user/clusters/create/index.md b/doc/user/clusters/create/index.md
new file mode 100644
index 00000000000..bee622ac50a
--- /dev/null
+++ b/doc/user/clusters/create/index.md
@@ -0,0 +1,13 @@
+---
+stage: Configure
+group: Configure
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
+---
+
+# Create Kubernetes clusters
+
+You can use Infrastructure as Code (IaC) to create clusters on cloud providers.
+You connect the clusters to GitLab by using the agent for Kubernetes.
+
+- [Create a cluster on Google GKE](../../infrastructure/clusters/connect/new_gke_cluster.md)
+- [Create a cluster on Amazon EKS](../../infrastructure/clusters/connect/new_eks_cluster.md)
diff --git a/doc/user/clusters/crossplane.md b/doc/user/clusters/crossplane.md
index e6540e68f71..9e4c672ac45 100644
--- a/doc/user/clusters/crossplane.md
+++ b/doc/user/clusters/crossplane.md
@@ -80,7 +80,7 @@ provided can manage resources in the `database.crossplane.io` API group:
## Configure Crossplane with a cloud provider
-See [Configure Your Cloud Provider Account](https://crossplane.github.io/docs/v0.4/cloud-providers.html)
+See [Configure Your Cloud Provider Account](https://crossplane.github.io/docs/v1.6/)
to configure the installed cloud provider stack with a user account.
The Secret, and the Provider resource referencing the Secret, must be
diff --git a/doc/user/clusters/img/kubernetes-agent-ui-list_v14_8.png b/doc/user/clusters/img/kubernetes-agent-ui-list_v14_8.png
deleted file mode 100644
index 5b5ba3a9804..00000000000
--- a/doc/user/clusters/img/kubernetes-agent-ui-list_v14_8.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/clusters/integrations.md b/doc/user/clusters/integrations.md
index ee7452537fd..74f6ec283ea 100644
--- a/doc/user/clusters/integrations.md
+++ b/doc/user/clusters/integrations.md
@@ -32,9 +32,9 @@ to automate this step.
Prometheus and Elastic Stack cluster integrations can only be enabled for clusters [connected through cluster certificates](../project/clusters/add_existing_cluster.md).
-To enable Prometheus for your cluster connected through the [GitLab Agent](agent/index.md), you can [integrate it manually](../project/integrations/prometheus.md#manual-configuration-of-prometheus).
+To enable Prometheus for your cluster connected through the [GitLab agent](agent/index.md), you can [integrate it manually](../project/integrations/prometheus.md#manual-configuration-of-prometheus).
-There is no option to enable Elastic Stack for your cluster if it is connected with the GitLab Agent.
+There is no option to enable Elastic Stack for your cluster if it is connected with the GitLab agent.
Follow this [issue](https://gitlab.com/gitlab-org/gitlab/-/issues/300230) for updates.
## Prometheus cluster integration
@@ -44,7 +44,7 @@ Follow this [issue](https://gitlab.com/gitlab-org/gitlab/-/issues/300230) for up
WARNING:
This feature was [deprecated](https://gitlab.com/groups/gitlab-org/configure/-/epics/8) in GitLab 14.5. However, you can **still use** Prometheus
for Kubernetes clusters connected to GitLab through the
-[Agent](agent/index.md) by [enabling Prometheus manually](../project/integrations/prometheus.md#manual-configuration-of-prometheus).
+[agent](agent/index.md) by [enabling Prometheus manually](../project/integrations/prometheus.md#manual-configuration-of-prometheus).
You can integrate your Kubernetes cluster with
[Prometheus](https://prometheus.io/) for monitoring key metrics of your
@@ -113,9 +113,9 @@ To use this integration:
`gitlab-managed-apps` namespace.
1. The `Service` resource must be called `elastic-stack-elasticsearch-master`
and expose the Elasticsearch API on port `9200`.
-1. The logs are expected to be [Filebeat container logs](https://www.elastic.co/guide/en/beats/filebeat/7.x/filebeat-input-container.html)
- following the [7.x log structure](https://www.elastic.co/guide/en/beats/filebeat/7.x/exported-fields-log.html)
- and include [Kubernetes metadata](https://www.elastic.co/guide/en/beats/filebeat/7.x/add-kubernetes-metadata.html).
+1. The logs are expected to be [Filebeat container logs](https://www.elastic.co/guide/en/beats/filebeat/7.16/filebeat-input-container.html)
+ following the [7.x log structure](https://www.elastic.co/guide/en/beats/filebeat/7.16/exported-fields-log.html)
+ and include [Kubernetes metadata](https://www.elastic.co/guide/en/beats/filebeat/7.16/add-kubernetes-metadata.html).
You can manage your Elastic Stack however you like, but as an example, you can
use [this Elastic Stack chart](https://gitlab.com/gitlab-org/charts/elastic-stack) to get up and
diff --git a/doc/user/clusters/management_project.md b/doc/user/clusters/management_project.md
index e28f9275b50..7658bc41dd9 100644
--- a/doc/user/clusters/management_project.md
+++ b/doc/user/clusters/management_project.md
@@ -11,7 +11,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
WARNING:
The cluster management project was [deprecated](https://gitlab.com/groups/gitlab-org/configure/-/epics/8) in GitLab 14.5.
-To manage cluster applications, use the [GitLab Agent](agent/index.md)
+To manage cluster applications, use the [GitLab agent](agent/index.md)
with the [Cluster Management Project Template](management_project_template.md).
A project can be designated as the management project for a cluster.
diff --git a/doc/user/clusters/management_project_template.md b/doc/user/clusters/management_project_template.md
index 2d7e89ef765..ab17e462c6a 100644
--- a/doc/user/clusters/management_project_template.md
+++ b/doc/user/clusters/management_project_template.md
@@ -8,89 +8,53 @@ info: To determine the technical writer assigned to the Stage/Group associated w
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/25318) in GitLab 12.10 with Helmfile support via Helm v2.
> - Helm v2 support was [dropped](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/63577) in GitLab 14.0. Use Helm v3 instead.
-> - [Migrated](https://gitlab.com/gitlab-org/project-templates/cluster-management/-/merge_requests/24) to the GitLab Agent in GitLab 14.5.
+> - [Migrated](https://gitlab.com/gitlab-org/project-templates/cluster-management/-/merge_requests/24) to the GitLab agent in GitLab 14.5.
-Use a repository to install, manage, and deploy clusters applications through code.
+GitLab provides a cluster management project template, which you use
+to create a project. The project includes cluster applications that integrate with GitLab
+and extend GitLab functionality. You can use the pattern shown in the project to extend
+your custom cluster applications.
-## Cluster Management Project Template
+## Use one project for the agent and your manifests
-The Cluster Management Project Template provides you a baseline to get
-started and flexibility to customize your project to your cluster's needs.
-For instance, you can:
+If you **have not yet** used the agent to connect your cluster with GitLab:
-- Extend the CI/CD configuration.
-- Configure the built-in cluster applications.
-- Remove the built-in cluster applications you don't need.
-- Add other cluster applications using the same structure as the ones already available.
+1. [Create a project from the cluster management project template](#create-a-project-based-on-the-cluster-management-project-template).
+1. [Configure the project for the agent](agent/install/index.md).
+1. In your project's settings, create an
+ [environment variable](../../ci/variables/index.md#add-a-cicd-variable-to-a-project) named `$KUBE_CONTEXT`
+ and set the value to `path/to/agent-configuration-project:your-agent-name`.
+1. [Configure the files](#configure-the-project) as needed.
-The template contains the following [components](#configure-the-available-components):
+## Use separate projects for the agent and your manifests
-- A pre-configured GitLab CI/CD file so that you can configure CI/CD pipelines using the [CI/CD Tunnel](agent/ci_cd_tunnel.md).
-- A pre-configured [Helmfile](https://github.com/roboll/helmfile) so that
-you can manage cluster applications with [Helm v3](https://helm.sh/).
-- An `applications` directory with a `helmfile.yaml` configured for each
-application available in the template.
+If you have already configured the agent and connected a cluster with GitLab:
-## Use the Agent with the Cluster Management Project Template
+1. [Create a project from the cluster management project template](#create-a-project-based-on-the-cluster-management-project-template).
+1. In the project where you configured your agent,
+ [grant the agent access to the new project](agent/ci_cd_tunnel.md#authorize-the-agent).
+1. In the new project, create an
+ [environment variable](../../ci/variables/index.md#add-a-cicd-variable-to-a-project) named `$KUBE_CONTEXT`
+ and set the value to `path/to/agent-configuration-project:your-agent-name`.
+1. In the new project, [configure the files](#configure-the-project) as needed.
-To use a new project created from the Cluster Management Project Template
-with a cluster connected to GitLab through the [GitLab Agent](agent/index.md),
-you have two options:
+## Create a project based on the cluster management project template
-- [Use one single project](#single-project) to configure the Agent and manage cluster applications.
-- [Use separate projects](#separate-projects) - one to configure the Agent and another to manage cluster applications.
+To create a project from the cluster management project template:
-### Single project
+1. On the top bar, select **Menu > Projects > Create new project**.
+1. Select **Create from template**.
+1. From the list of templates, next to **GitLab Cluster Management**, select **Use template**.
+1. Enter the project details.
+1. Select **Create project**.
-This setup is particularly useful when you haven't connected your cluster
-to GitLab through the Agent yet and you want to use the Cluster Management
-Project Template to manage cluster applications.
+If you use self-managed GitLab, your instance might not include the latest version of the template.
+In that case, select **Import project**, **Repo by URL** and for the **Git repository URL**, enter
+`https://gitlab.com/gitlab-org/project-templates/cluster-management.git`.
-To use one single project to configure the Agent and to manage cluster applications:
+## Configure the project
-1. [Create a new project from the Cluster Management Project Template](#create-a-new-project-based-on-the-cluster-management-template).
-1. Configure the new project as the [Agent's configuration repository](agent/repository.md)
-(where the Agent is registered and its `config.yaml` is stored).
-1. From your project's settings, add a [new environment variable](../../ci/variables/index.md#add-a-cicd-variable-to-a-project) `$KUBE_CONTEXT` and set it to `path/to/agent-configuration-project:your-agent-name`.
-1. [Configure the components](#configure-the-available-components) inherited from the template.
-
-### Separate projects
-
-This setup is particularly useful **when you already have a cluster** connected
-to GitLab through the Agent and want to use the Cluster Management
-Project Template to manage cluster applications.
-
-To use one project to configure the Agent ("project A") and another project to
-manage cluster applications ("project B"), follow the steps below.
-
-We assume that you already have a cluster connected through the Agent and
-[configured through the Agent's configuration repository](agent/repository.md)
-("project A").
-
-1. [Create a new project from the Cluster Management Project Template](#create-a-new-project-based-on-the-cluster-management-template).
-This new project is "project B".
-1. In your "project A", [grant the Agent access to the new project (B) through the CI/CD Tunnel](agent/repository.md#authorize-projects-to-use-an-agent).
-1. From the "project's B" settings, add a [new environment variable](../../ci/variables/index.md#add-a-cicd-variable-to-a-project) `$KUBE_CONTEXT` and set it to `path/to/agent-configuration-project:your-agent-name`.
-1. In "project B", [configure the components](#configure-the-available-components) inherited from the template.
-
-## Create a new project based on the Cluster Management Template
-
-To get started, create a new project based on the Cluster Management
-project template to use as a cluster management project.
-
-You can either create the new project from the template or import the
-project from the URL. Importing the project is useful if you are using
-a GitLab self-managed instance that may not have the latest version of
-the template.
-
-To [create the new project](../project/working_with_projects.md#create-a-project):
-
-- From the template: select the **GitLab Cluster Management** project template.
-- Importing from the URL: use `https://gitlab.com/gitlab-org/project-templates/cluster-management.git`.
-
-## Configure the available components
-
-Use the available components to configure your cluster applications:
+After you use the cluster management template to create a project, you can configure:
- [The `.gitlab-ci.yml` file](#the-gitlab-ciyml-file).
- [The main `helmfile.yml` file](#the-main-helmfileyml-file).
@@ -98,22 +62,22 @@ Use the available components to configure your cluster applications:
### The `.gitlab-ci.yml` file
-The base image used in your pipeline is built by the [cluster-applications](https://gitlab.com/gitlab-org/cluster-integration/cluster-applications)
-project. This image consists of a set of Bash utility scripts to support [Helm v3 releases](https://helm.sh/docs/intro/using_helm/#three-big-concepts):
+The `.gitlab-ci.yml` file:
-- `gl-fail-if-helm2-releases-exist {namespace}`: It tries to detect whether you have apps deployed through Helm v2
- releases for a given namespace. If so, it will fail the pipeline and ask you to manually
- [migrate your Helm v2 releases to Helm v3](https://helm.sh/docs/topics/v2_v3_migration/).
-- `gl-ensure-namespace {namespace}`: It creates the given namespace if it does not exist and adds the necessary label
- for the [Cilium](https://github.com/cilium/cilium/) app network policies to work.
-- `gl-adopt-resource-with-helm-v3 {arguments}`: Used only internally in the [cert-manager's](https://cert-manager.io/) Helmfile to
- facilitate the GitLab Managed Apps adoption.
-- `gl-adopt-crds-with-helm-v3 {arguments}`: Used only internally in the [cert-manager's](https://cert-manager.io/) Helmfile to
- facilitate the GitLab Managed Apps adoption.
-- `gl-helmfile {arguments}`: A thin wrapper that triggers the [Helmfile](https://github.com/roboll/helmfile) command.
+- Ensures you are on Helm version 3.
+- Deploys the enabled applications from the project.
+
+You can edit and extend the pipeline definitions.
+
+The base image used in the pipeline is built by the
+[cluster-applications](https://gitlab.com/gitlab-org/cluster-integration/cluster-applications) project.
+This image contains a set of Bash utility scripts to support [Helm v3 releases](https://helm.sh/docs/intro/using_helm/#three-big-concepts).
### The main `helmfile.yml` file
+The template contains a [Helmfile](https://github.com/roboll/helmfile) you can use to manage
+cluster applications with [Helm v3](https://helm.sh/).
+
This file has a list of paths to other Helmfiles for each app. They're all commented out by default, so you must uncomment
the paths for the apps that you would like to use in your cluster.
@@ -124,6 +88,9 @@ from your cluster. [Read more](https://github.com/roboll/helmfile) about how Hel
### Built-in applications
+The template contains an `applications` directory with a `helmfile.yaml` configured for each
+application in the template.
+
The [built-in supported applications](https://gitlab.com/gitlab-org/project-templates/cluster-management/-/tree/master/applications) are:
- [Apparmor](../infrastructure/clusters/manage/management_project_applications/apparmor.md)
@@ -138,8 +105,8 @@ The [built-in supported applications](https://gitlab.com/gitlab-org/project-temp
- [Sentry](../infrastructure/clusters/manage/management_project_applications/sentry.md)
- [Vault](../infrastructure/clusters/manage/management_project_applications/vault.md)
-#### Customize your applications
+Each application has an `applications/{app}/values.yaml` file.
+For GitLab Runner, the file is `applications/{app}/values.yaml.gotmpl`.
-Each app has an `applications/{app}/values.yaml` file (`applications/{app}/values.yaml.gotmpl` in case of GitLab Runner). This is the
-place where you can define default values for your app's Helm chart. Some apps already have defaults
-pre-defined by GitLab.
+In this file, you can define default values for your app's Helm chart.
+Some apps already have defaults defined.
diff --git a/doc/user/clusters/migrating_from_gma_to_project_template.md b/doc/user/clusters/migrating_from_gma_to_project_template.md
index b2ba1bef338..09453262fbb 100644
--- a/doc/user/clusters/migrating_from_gma_to_project_template.md
+++ b/doc/user/clusters/migrating_from_gma_to_project_template.md
@@ -20,7 +20,7 @@ To migrate from GitLab Managed Apps to a Cluster Management Project,
follow the steps below.
See also [video walk-throughs](#video-walk-throughs) with examples.
-1. Create a new project based on the [Cluster Management Project template](management_project_template.md#create-a-new-project-based-on-the-cluster-management-template).
+1. Create a new project based on the [Cluster Management Project template](management_project_template.md#create-a-project-based-on-the-cluster-management-project-template).
1. [Associate your new Cluster Management Project with your cluster](management_project.md#associate-the-cluster-management-project-with-the-cluster).
1. Detect apps deployed through Helm v2 releases by using the pre-configured [`.gitlab-ci.yml`](management_project_template.md#the-gitlab-ciyml-file) file:
- In case you had overwritten the default GitLab Managed Apps namespace, edit `.gitlab-ci.yml`,
@@ -120,7 +120,7 @@ you want to manage with the Cluster Management Project.
## Backup and uninstall cert-manager v0.10
-1. Follow the [official docs](https://docs.cert-manager.io/en/release-0.10/tasks/backup-restore-crds.html) on how to
+1. Follow the [official docs](https://cert-manager.io/docs/tutorials/backup/) on how to
backup your cert-manager v0.10 data.
1. Uninstall cert-manager by editing the setting all the occurrences of `installed: true` to `installed: false` in the
`applications/cert-manager/helmfile.yaml` file.
diff --git a/doc/user/compliance/compliance_report/index.md b/doc/user/compliance/compliance_report/index.md
index d98a0a145f2..27783a063da 100644
--- a/doc/user/compliance/compliance_report/index.md
+++ b/doc/user/compliance/compliance_report/index.md
@@ -105,3 +105,64 @@ You can generate a commit-specific Chain of Custody report for a given commit SH
NOTE:
The Chain of Custody report download is a CSV file, with a maximum size of 15 MB.
The remaining records are truncated when this limit is reached.
+
+## Merge request violations
+
+> - Introduced in GitLab 14.6. [Deployed behind the `compliance_violations_report` flag](../../../administration/feature_flags.md). Disabled by default.
+> - GraphQL API [introduced](https://gitlab.com/groups/gitlab-org/-/epics/7222) in GitLab 14.9.
+
+FLAG:
+On self-managed GitLab, by default this feature is not available. To make it available,
+ask an administrator to [enable the feature flag](../../../administration/feature_flags.md) named `compliance_violations_report`.
+On GitLab.com, this feature is not available. This feature is not ready for production use.
+
+Merge request violations provide a view of all the [separation of duties](#approval-status-and-separation-of-duties) compliance violations
+that exist in projects in a specific group. For each separation of duties compliance violation, you can see:
+
+- A list of compliance violations.
+- The severity of each compliance violation.
+- Reason for the compliance violation.
+- A link to the merge request that caused the compliance violation.
+
+Merge request violations can be accessed:
+
+- In the GitLab UI.
+- Using the [GraphQL API](../../../api/graphql/reference/index.md#complianceviolation) (GitLab 14.9 and later).
+
+### View merge request violations
+
+To view merge request violations:
+
+1. On the top bar, select **Menu > Groups** and find your group.
+1. On the left sidebar, select **Security & Compliance > Compliance report**.
+
+### Severity levels scale
+
+The following is a list of available violation severity levels, ranked from most to least severe:
+
+| Icon | Severity level |
+|:----------------------------------------------|:---------------|
+| **{severity-critical, 18, gl-fill-red-800}** | Critical |
+| **{severity-high, 18, gl-fill-red-600}** | High |
+| **{severity-medium, 18, gl-fill-orange-400}** | Medium |
+| **{severity-low, 18, gl-fill-orange-300}** | Low |
+| **{severity-info, 18, gl-fill-blue-400}** | Info |
+
+### Violation types
+
+The following is a list of violations that are either:
+
+- Already available.
+- Aren't available, but which we are tracking in issues.
+
+| Violation | Severity level | Category | Description | Availability |
+|:-------------------------------------|:----------------|:----------------------------------------------------------------------------------------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:--------------------------------------------------------------------|
+| Author approved merge request | High | [Separation of duties](#approval-status-and-separation-of-duties) | The author of the merge request approved their own merge request. [Learn more](../../project/merge_requests/approvals/settings.md#prevent-approval-by-author). | [Unavailable](https://gitlab.com/groups/gitlab-org/-/epics/6870) |
+| Committers approved merge request | High | [Separation of duties](#approval-status-and-separation-of-duties) | The committers of the merge request approved the merge request they contributed to. [Learn more](../../project/merge_requests/approvals/settings.md#prevent-approvals-by-users-who-add-commits). | [Unavailable](https://gitlab.com/groups/gitlab-org/-/epics/6870) |
+| Fewer than two approvals | High | [Separation of duties](#approval-status-and-separation-of-duties) | The merge request was merged with fewer than two approvals. [Learn more](../../project/merge_requests/approvals/rules.md). | [Unavailable](https://gitlab.com/groups/gitlab-org/-/epics/6870) |
+| Pipeline failed | Medium | [Pipeline results](../../../ci/pipelines/index.md) | The merge requests pipeline failed and was merged. | [Unavailable](https://gitlab.com/gitlab-org/gitlab/-/issues/346011) |
+| Pipeline passed with warnings | Info | [Pipeline results](../../../ci/pipelines/index.md) | The merge request pipeline passed with warnings and was merged. | [Unavailable](https://gitlab.com/gitlab-org/gitlab/-/issues/346011) |
+| Code coverage down more than 10% | High | [Code coverage](../../../ci/pipelines/settings.md#merge-request-test-coverage-results) | The code coverage report for the merge request indicates a reduction in coverage of more than 10%. | [Unavailable](https://gitlab.com/gitlab-org/gitlab/-/issues/346011) |
+| Code coverage down between 5% to 10% | Medium | [Code coverage](../../../ci/pipelines/settings.md#merge-request-test-coverage-results) | The code coverage report for the merge request indicates a reduction in coverage of between 5% to 10%. | [Unavailable](https://gitlab.com/gitlab-org/gitlab/-/issues/346011) |
+| Code coverage down between 1% to 5% | Low | [Code coverage](../../../ci/pipelines/settings.md#merge-request-test-coverage-results) | The code coverage report for the merge request indicates a reduction in coverage of between 1% to 5%. | [Unavailable](https://gitlab.com/gitlab-org/gitlab/-/issues/346011) |
+| Code coverage down less than 1% | Info | [Code coverage](../../../ci/pipelines/settings.md#merge-request-test-coverage-results) | The code coverage report for the merge request indicates a reduction in coverage of less than 1%. | [Unavailable](https://gitlab.com/gitlab-org/gitlab/-/issues/346011) |
diff --git a/doc/user/compliance/license_compliance/index.md b/doc/user/compliance/license_compliance/index.md
index 18de33ea03b..a2172b72572 100644
--- a/doc/user/compliance/license_compliance/index.md
+++ b/doc/user/compliance/license_compliance/index.md
@@ -55,7 +55,7 @@ You can view and modify existing policies from the [policies](#policies) tab.
## License expressions
-GitLab has limited support for [composite licenses](https://spdx.github.io/spdx-spec/appendix-IV-SPDX-license-expressions/).
+GitLab has limited support for [composite licenses](https://spdx.github.io/spdx-spec/SPDX-license-expressions/).
License compliance can read multiple licenses, but always considers them combined using the `AND` operator. For example,
if a dependency has two licenses, and one of them is allowed and the other is denied by the project [policy](#policies),
GitLab evaluates the composite license as _denied_, as this is the safer option.
@@ -90,7 +90,7 @@ The reported licenses might be incomplete or inaccurate.
| Objective-C, Swift | [Carthage](https://github.com/Carthage/Carthage), [CocoaPods](https://cocoapods.org/) v0.39 and below |
| Elixir | [Mix](https://elixir-lang.org/getting-started/mix-otp/introduction-to-mix.html) |
| C++/C | [Conan](https://conan.io/) |
-| Rust | [Cargo](https://crates.io) |
+| Rust | [Cargo](https://crates.io/) |
| PHP | [Composer](https://getcomposer.org/) |
## Enable License Compliance
@@ -219,7 +219,7 @@ license_scanning:
MAVEN_CLI_OPTS: --debug
```
-`mvn install` runs through all of the [build life cycle](http://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html)
+`mvn install` runs through all of the [build life cycle](https://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html)
stages prior to `install`, including `test`. Running unit tests is not directly
necessary for the license scanning purposes and consumes time, so it's skipped
by having the default value of `MAVEN_CLI_OPTS` as `-DskipTests`. If you want
@@ -249,7 +249,7 @@ license_scanning:
Alternatively, you can use a Java key store to verify the TLS connection. For instructions on how to
generate a key store file, see the
-[Maven Guide to Remote repository access through authenticated HTTPS](http://maven.apache.org/guides/mini/guide-repository-ssl.html).
+[Maven Guide to Remote repository access through authenticated HTTPS](https://maven.apache.org/guides/mini/guide-repository-ssl.html).
### Selecting the version of Java
@@ -650,7 +650,7 @@ import the following default License Compliance analyzer images from `registry.g
offline [local Docker container registry](../../packages/container_registry/index.md):
```plaintext
-registry.gitlab.com/gitlab-org/security-products/analyzers/license-finder:latest
+registry.gitlab.com/security-products/license-finder:latest
```
The process for importing Docker images into a local offline Docker registry depends on
@@ -734,7 +734,7 @@ Note, the merge request is not able to be merged until the `denied` license is r
You may add a [`License-Check` approval rule](#enabling-license-approvals-within-a-project),
which enables a designated approver that can approve and then merge a merge request with `denied` license.
-![Merge Request with denied licenses](img/denied_licenses_v13_3.png)
+![Merge request with denied licenses](img/denied_licenses_v13_3.png)
The **Policies** tab in the project's license compliance section displays your project's license
policies. Project maintainers can specify policies in this section.
@@ -853,7 +853,7 @@ A full list of variables can be found in [CI/CD variables](#available-cicd-varia
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'
+$ docker run --entrypoint='' registry.gitlab.com/security-products/license-finder:3 /bin/bash -lc 'asdf list'
golang
1.14
gradle
@@ -880,7 +880,7 @@ sbt
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
+$ docker run -it --entrypoint='' registry.gitlab.com/security-products/license-finder:3 /bin/bash -l
root@6abb70e9f193:~#
```
diff --git a/doc/user/crm/index.md b/doc/user/crm/index.md
index 305cca33dd5..1fb628cf505 100644
--- a/doc/user/crm/index.md
+++ b/doc/user/crm/index.md
@@ -6,15 +6,18 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Customer relations management (CRM) **(FREE)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/2256) in GitLab 14.6 [with a flag](../../administration/feature_flags.md) named `customer_relations`. Disabled by default.
-
FLAG:
On self-managed GitLab, by default this feature is not available. To make it available, ask an administrator to [enable the feature flag](../../administration/feature_flags.md) named `customer_relations`.
On GitLab.com, this feature is not available.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/2256) in GitLab 14.6 [with a flag](../../administration/feature_flags.md) named `customer_relations`. Disabled by default.
+> - In GitLab 14.8 and later, you can [create contacts and organizations only in root groups](https://gitlab.com/gitlab-org/gitlab/-/issues/350634).
+
With customer relations management (CRM) you can create a record of contacts
(individuals) and organizations (companies) and relate them to issues.
+Contacts and organizations can only be created for root groups.
+
You can use contacts and organizations to tie work to customers for billing and reporting purposes.
To read more about what is planned for the future, see [issue 2256](https://gitlab.com/gitlab-org/gitlab/-/issues/2256).
diff --git a/doc/user/discussions/index.md b/doc/user/discussions/index.md
index 37047e9f8d0..a6343e0d1cf 100644
--- a/doc/user/discussions/index.md
+++ b/doc/user/discussions/index.md
@@ -36,10 +36,9 @@ Each object can have as many as 5,000 comments.
## Mentions
-You can mention a user or a group present in your GitLab instance with `@username` or
-`@groupname`. All mentioned users are notified with to-do items and emails.
-Users can change this setting for themselves in the
-[notification settings](../profile/notifications.md).
+You can mention a user or a group (including [subgroups](../group/subgroups/index.md#mention-subgroups)) in your GitLab
+instance with `@username` or `@groupname`. All mentioned users are notified with to-do items and emails.
+Users can change this setting for themselves in the [notification settings](../profile/notifications.md).
You can quickly see which comments involve you, because
mentions for yourself (the user currently signed in) are highlighted
@@ -47,6 +46,8 @@ in a different color.
Avoid mentioning `@all` in issues and merge requests, because it sends an email notification
to all the members of that project's group. This might be interpreted as spam.
+Notifications and mentions can be disabled in
+[a group's settings](../group/index.md#disable-email-notifications).
## Add a comment to a merge request diff
diff --git a/doc/user/gitlab_com/index.md b/doc/user/gitlab_com/index.md
index 80ee8d23a35..5cf6a505bee 100644
--- a/doc/user/gitlab_com/index.md
+++ b/doc/user/gitlab_com/index.md
@@ -85,7 +85,10 @@ are included when cloning.
Top-level groups created after August 12, 2021 have delayed project deletion enabled by default.
Projects are permanently deleted after a seven-day delay.
-You can disable this by changing the [group setting](../group/index.md#enable-delayed-project-deletion).
+If you are on:
+
+- Premium tier and above, you can disable this by changing the [group setting](../group/index.md#enable-delayed-project-deletion).
+- Free tier, you cannot disable this setting or restore projects.
## Alternative SSH port
@@ -130,20 +133,20 @@ Below are the current settings regarding [GitLab CI/CD](../../ci/index.md).
Any settings or feature limits not listed here are using the defaults listed in
the related documentation.
-| Setting | GitLab.com | Default |
-|-------------------------------------|-------------|---------|
-| Artifacts maximum size (compressed) | 1 GB | 100 MB |
-| Artifacts [expiry time](../../ci/yaml/index.md#artifactsexpire_in) | From June 22, 2020, deleted after 30 days unless otherwise specified (artifacts created before that date have no expiry). | deleted after 30 days unless otherwise specified |
-| Scheduled Pipeline Cron | `*/5 * * * *` | `3-59/10 * * * *` |
-| [Max jobs in active pipelines](../../administration/instance_limits.md#number-of-jobs-in-active-pipelines) | `500` for Free tier, unlimited otherwise | Unlimited |
-| [Max CI/CD subscriptions to a project](../../administration/instance_limits.md#number-of-cicd-subscriptions-to-a-project) | `2` | Unlimited |
-| [Max number of pipeline triggers in a project](../../administration/instance_limits.md#limit-the-number-of-pipeline-triggers) | `25000` for Free tier, Unlimited for all paid tiers | Unlimited |
-| [Max pipeline schedules in projects](../../administration/instance_limits.md#number-of-pipeline-schedules) | `10` for Free tier, `50` for all paid tiers | Unlimited |
-| [Max pipelines per schedule](../../administration/instance_limits.md#limit-the-number-of-pipelines-created-by-a-pipeline-schedule-per-day) | `24` for Free tier, `288` for all paid tiers | Unlimited |
-| [Scheduled Job Archival](../../user/admin_area/settings/continuous_integration.md#archive-jobs) | 3 months | Never |
-| Max test cases per [unit test report](../../ci/unit_test_reports.md) | `500_000` | Unlimited |
-| [Max registered runners](../../administration/instance_limits.md#number-of-registered-runners-per-scope) | Free tier: `50` per-group / `50` per-project <br/> All paid tiers: `1_000` per-group / `1_000` per-project | `1_000` per-group / `1_000` per-project |
-| [Limit dotenv variables](../../administration/instance_limits.md#limit-dotenv-variables) | Free tier: `50` / Premium tier: `100` / Ultimate tier: `150` | 150 |
+| Setting | GitLab.com | Default (self-managed) |
+|:-------------------------------------------------------------------------|:--------------------------------------------------------------------------------------------------------------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| Artifacts maximum size (compressed) | 1 GB | See [Maximum artifacts size](../../user/admin_area/settings/continuous_integration.md#maximum-artifacts-size) |
+| Artifacts [expiry time](../../ci/yaml/index.md#artifactsexpire_in) | From June 22, 2020, deleted after 30 days unless otherwise specified (artifacts created before that date have no expiry). | See [Default artifacts expiration](../admin_area/settings/continuous_integration.md#default-artifacts-expiration) |
+| Scheduled Pipeline Cron | `*/5 * * * *` | See [Pipeline schedules advanced configuration](../../administration/cicd.md#change-maximum-scheduled-pipeline-frequency) |
+| Maximum jobs in active pipelines | `500` for Free tier, unlimited otherwise | See [Number of jobs in active pipelines](../../administration/instance_limits.md#number-of-jobs-in-active-pipelines) |
+| Maximum CI/CD subscriptions to a project | `2` | See [Number of CI/CD subscriptions to a project](../../administration/instance_limits.md#number-of-cicd-subscriptions-to-a-project) |
+| Maximum number of pipeline triggers in a project | `25000` for Free tier, Unlimited for all paid tiers | See [Limit the number of pipeline triggers](../../administration/instance_limits.md#limit-the-number-of-pipeline-triggers) |
+| Maximum pipeline schedules in projects | `10` for Free tier, `50` for all paid tiers | See [Number of pipeline schedules](../../administration/instance_limits.md#number-of-pipeline-schedules) |
+| Maximum pipelines per schedule | `24` for Free tier, `288` for all paid tiers | See [Limit the number of pipelines created by a pipeline schedule per day](../../administration/instance_limits.md#limit-the-number-of-pipelines-created-by-a-pipeline-schedule-per-day) |
+| Scheduled job archiving | 3 months (from June 22, 2020). Jobs created before that date were archived after September 22, 2020. | Never |
+| Maximum test cases per [unit test report](../../ci/unit_test_reports.md) | `500000` | Unlimited |
+| Maximum registered runners | Free tier: `50` per-group / `50` per-project<br/>All paid tiers: `1000` per-group / `1000` per-project | See [Number of registered runners per scope](../../administration/instance_limits.md#number-of-registered-runners-per-scope) |
+| Limit of dotenv variables | Free tier: `50` / Premium tier: `100` / Ultimate tier: `150` | See [Limit dotenv variables](../../administration/instance_limits.md#limit-dotenv-variables) |
## Package registry limits
@@ -188,7 +191,7 @@ GitLab.com uses the IP ranges `34.74.90.64/28` and `34.74.226.0/24` for traffic
fleet. This whole range is solely allocated to GitLab. You can expect connections from webhooks or repository mirroring to come
from those IPs and allow them.
-GitLab.com is fronted by Cloudflare. For incoming connections to GitLab.com, you might need to allow CIDR blocks of Cloudflare ([IPv4](https://www.cloudflare.com/ips-v4) and [IPv6](https://www.cloudflare.com/ips-v6)).
+GitLab.com is fronted by Cloudflare. For incoming connections to GitLab.com, you might need to allow CIDR blocks of Cloudflare ([IPv4](https://www.cloudflare.com/ips-v4/) and [IPv6](https://www.cloudflare.com/ips-v6/)).
For outgoing connections from CI/CD runners, we are not providing static IP
addresses. All GitLab.com shared runners are deployed into Google Cloud Platform (GCP). Any
@@ -296,7 +299,7 @@ for `shared_buffers` is quite high, and we are
## Puma
-GitLab.com uses the default of 60 seconds for [Puma request timeouts](../../administration/operations/puma.md#worker-timeout).
+GitLab.com uses the default of 60 seconds for [Puma request timeouts](../../administration/operations/puma.md#change-the-worker-timeout).
## GitLab.com-specific rate limits
diff --git a/doc/user/group/clusters/index.md b/doc/user/group/clusters/index.md
index b2b16321488..0da7eaa4d55 100644
--- a/doc/user/group/clusters/index.md
+++ b/doc/user/group/clusters/index.md
@@ -12,7 +12,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
WARNING:
This feature was [deprecated](https://gitlab.com/groups/gitlab-org/configure/-/epics/8) in GitLab 14.5. To connect clusters to GitLab,
-use the [GitLab Agent](../../clusters/agent/index.md).
+use the [GitLab agent](../../clusters/agent/index.md).
Similar to [project-level](../../project/clusters/index.md) and
[instance-level](../../instance/clusters/index.md) Kubernetes clusters,
diff --git a/doc/user/group/epics/img/related_epic_block_v14_9.png b/doc/user/group/epics/img/related_epic_block_v14_9.png
new file mode 100644
index 00000000000..7b5824b84d1
--- /dev/null
+++ b/doc/user/group/epics/img/related_epic_block_v14_9.png
Binary files differ
diff --git a/doc/user/group/epics/img/related_epics_add_v14_9.png b/doc/user/group/epics/img/related_epics_add_v14_9.png
new file mode 100644
index 00000000000..3da6eeaff43
--- /dev/null
+++ b/doc/user/group/epics/img/related_epics_add_v14_9.png
Binary files differ
diff --git a/doc/user/group/epics/img/related_epics_remove_v14_9.png b/doc/user/group/epics/img/related_epics_remove_v14_9.png
new file mode 100644
index 00000000000..2cdded5965f
--- /dev/null
+++ b/doc/user/group/epics/img/related_epics_remove_v14_9.png
Binary files differ
diff --git a/doc/user/group/epics/index.md b/doc/user/group/epics/index.md
index d6f87a026b8..149c5362ac9 100644
--- a/doc/user/group/epics/index.md
+++ b/doc/user/group/epics/index.md
@@ -62,6 +62,7 @@ You can also consult the [group permissions table](../../permissions.md#group-me
## Related topics
- [Manage epics](manage_epics.md) and multi-level child epics.
+- Link [related epics](linked_epics.md) based on a type of relationship.
- Create workflows with [epic boards](epic_boards.md).
- [Turn on notifications](../../profile/notifications.md) for about epic events.
- [Award an emoji](../../award_emojis.md) to an epic or its comments.
diff --git a/doc/user/group/epics/linked_epics.md b/doc/user/group/epics/linked_epics.md
new file mode 100644
index 00000000000..b695bae39e4
--- /dev/null
+++ b/doc/user/group/epics/linked_epics.md
@@ -0,0 +1,79 @@
+---
+stage: Plan
+group: Product Planning
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
+---
+
+# Linked epics **(ULTIMATE)**
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/353473) in GitLab 14.9 [with a flag](../../../administration/feature_flags.md) named `related_epics_widget`. Enabled by default.
+
+FLAG:
+On self-managed GitLab, by default this feature is available. To hide the feature,
+ask an administrator to [disable the feature flag](../../../administration/feature_flags.md)
+named `related_epics_widget`. On GitLab.com, this feature is available.
+
+Linked epics are a bi-directional relationship between any two epics and appear in a block below
+the epic description. You can link epics in different groups.
+
+The relationship only shows up in the UI if the user can see both epics. When you try to close an
+epic that has open blockers, a warning is displayed.
+
+NOTE:
+To manage linked epics through our API, visit the [epic links API documentation](../../../api/linked_epics.md).
+
+## Add a linked epic
+
+Prerequisites:
+
+- You must have at least the Reporter role for both groups.
+- For GitLab SaaS: the epic that you're editing must be in a group on GitLab Ultimate.
+ The epics you're linking can be in a group on a lower tier.
+
+To link one epic to another:
+
+1. In the **Linked epics** section of an epic,
+ select the add linked epic button (**{plus}**).
+1. Select the relationship between the two epics. Either:
+ - **relates to**
+ - **[blocks](#blocking-epics)**
+ - **[is blocked by](#blocking-epics)**
+1. Enter the epic number or paste in the full URL of the epic.
+
+ ![Adding a related epic](img/related_epics_add_v14_9.png)
+
+ Epics of the same group can be specified just by the reference number.
+ Epics from a different group require additional information like the
+ group name. For example:
+
+ - The same group: `&44`
+ - Different group: `group&44`
+
+ Valid references are added to a temporary list that you can review.
+
+1. Select **Add**.
+
+The linked epics are then displayed on the epic grouped by relationship.
+
+![Related epic block](img/related_epic_block_v14_9.png)
+
+## Remove a linked epic
+
+Prerequisites:
+
+- You must have at least the Reporter role for the epic's group.
+
+To remove a linked epic, in the **Linked epics** section of an epic,
+select **Remove** (**{close}**) next to
+each epic.
+
+The relationship is removed from both epics.
+
+![Removing a related epic](img/related_epics_remove_v14_9.png)
+
+## Blocking epics
+
+When you [add a linked epic](#add-a-linked-epic), you can show that it **blocks** or
+**is blocked by** another epic.
+
+If you try to close a blocked epic using the "Close epic" button, a confirmation message appears.
diff --git a/doc/user/group/import/img/import_panel_v14_1.png b/doc/user/group/import/img/import_panel_v14_1.png
deleted file mode 100644
index 52791a82c3c..00000000000
--- a/doc/user/group/import/img/import_panel_v14_1.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/group/import/img/new_group_navigation_v13_8.png b/doc/user/group/import/img/new_group_navigation_v13_8.png
deleted file mode 100644
index 40be3dd41d2..00000000000
--- a/doc/user/group/import/img/new_group_navigation_v13_8.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/group/import/index.md b/doc/user/group/import/index.md
index cdc3fe02a53..0c16b535ed1 100644
--- a/doc/user/group/import/index.md
+++ b/doc/user/group/import/index.md
@@ -132,3 +132,25 @@ migrated:
- image URL
- Boards
- Board Lists
+
+## Troubleshooting Group Migration
+
+In a [rails console session](../../../administration/operations/rails_console.md#starting-a-rails-console-session),
+you can find the failure or error messages for the group import attempt using:
+
+```shell
+# Get relevant import records
+import = BulkImports::Entity.where(namespace_id: Group.id).bulk_import
+
+# Alternative lookup by user
+import = BulkImport.where(user_id: User.find(...)).last
+
+# Get list of import entities. Each entity represents either a group or a project
+entities = import.entities
+
+# Get a list of entity failures
+entities.map(&:failures).flatten
+
+# Alternative failure lookup by status
+entities.where(status: [-1]).pluck(:destination_name, :destination_namespace, :status)
+```
diff --git a/doc/user/group/index.md b/doc/user/group/index.md
index ec76dc52516..4b9ff7f64e8 100644
--- a/doc/user/group/index.md
+++ b/doc/user/group/index.md
@@ -46,19 +46,16 @@ the immediate parent group.
### Namespaces
-In GitLab, a namespace is a unique name and URL for a user, a group, or subgroup.
-
-- `http://gitlab.example.com/username`
-- `http://gitlab.example.com/groupname`
-- `http://gitlab.example.com/groupname/subgroup_name`
+In GitLab, a namespace is a unique name for a user, a group, or subgroup under
+which a project can be created.
For example, consider a user named Alex:
-1. Alex creates an account with the username `alex`: `https://gitlab.example.com/alex`
-1. Alex creates a group for their team with the group name `alex-team`.
- The group and its projects are available at: `https://gitlab.example.com/alex-team`
-1. Alex creates a subgroup of `alex-team` with the subgroup name `marketing`.
- The subgroup and its projects are available at: `https://gitlab.example.com/alex-team/marketing`
+| GitLab URL | Namespace |
+| ---------- | --------- |
+| Alex creates an account with the username `alex`: `https://gitlab.example.com/alex`. | The namespace in this case is `alex`. |
+| Alex creates a group for their team with the group name `alex-team`. The group and its projects are available at: `https://gitlab.example.com/alex-team`. | The namespace in this cases is `alex-team`. |
+| Alex creates a subgroup of `alex-team` with the subgroup name `marketing`. The subgroup and its projects are available at: `https://gitlab.example.com/alex-team/marketing`. | The namespace in this case is `alex-team/marketing`. |
## Create a group
@@ -87,6 +84,7 @@ You can give a user access to all projects in a group.
1. On the top bar, select **Menu > Groups** and find your group.
1. On the left sidebar, select **Group information > Members**.
+1. Select **Invite members**.
1. Fill in the fields.
- The role applies to all projects in the group. [Learn more about permissions](../permissions.md).
- On the **Access expiration date**, the user can no longer access projects in the group.
@@ -174,6 +172,7 @@ Filter a group to find members. By default, all members in the group and subgrou
- To view members in the group only, select **Membership = Direct**.
- To view members of the group and its subgroups, select **Membership = Inherited**.
- To view members with two-factor authentication enabled or disabled, select **2FA = Enabled** or **Disabled**.
+ - [In GitLab 14.0 and later](https://gitlab.com/gitlab-org/gitlab/-/issues/349887), to view GitLab users created by [SAML SSO](saml_sso/index.md) or [SCIM provisioning](saml_sso/scim_setup.md) select **Enterprise = true**.
### Search a group
@@ -207,31 +206,24 @@ A to-do item is created for all the group and subgroup members.
## Change 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.
+> - [Settings moved and renamed](https://gitlab.com/gitlab-org/gitlab/-/issues/340403) in GitLab 14.9.
By default, every group inherits the branch protection set at the global level.
-To change this setting for a specific group:
-
-1. On the top bar, select **Menu > Groups**.
-1. Select **Your Groups**.
-1. Find the group and select it.
-1. From the left menu, select **Settings > General**.
-1. Expand the **Permissions and group features** section.
-1. Select the desired option in the **Default branch protection** dropdown list.
-1. Select **Save changes**.
+To change this setting for a specific group, see [group level default branch protection](../project/repository/branches/default.md#group-level-default-branch-protection).
-To change this setting globally, see [Default branch protection](../admin_area/settings/visibility_and_access_controls.md#protect-default-branches).
+To change this setting globally, see [initial default branch protection](../project/repository/branches/default.md#instance-level-default-branch-protection).
NOTE:
-In [GitLab Premium or higher](https://about.gitlab.com/pricing/), GitLab administrators can choose to [disable group owners from updating the default branch protection](../admin_area/settings/visibility_and_access_controls.md#prevent-overrides-of-default-branch-protection).
+In [GitLab Premium or higher](https://about.gitlab.com/pricing/), GitLab administrators can choose to [disable group owners from updating the default branch protection](../project/repository/branches/default.md#prevent-overrides-of-default-branch-protection).
## Add projects to a group
There are two different ways to add a new project to a group:
-- Select a group, and then click **New project**. You can then continue [creating your project](../../user/project/working_with_projects.md#create-a-project).
-- While you are creating a project, select a group from the dropdown menu.
+- Select a group, and then select **New project**. You can then continue [creating your project](../../user/project/working_with_projects.md#create-a-project).
+- While you are creating a project, select a group from the dropdown list.
![Select group](img/select_group_dropdown_13_10.png)
@@ -256,7 +248,7 @@ To change this setting globally, see [Default project creation protection](../ad
## Group activity analytics **(PREMIUM)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/207164) in GitLab 12.10 as a [beta feature](https://about.gitlab.com/handbook/product/#beta).
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/207164) in GitLab 12.10 as a [Beta feature](../../policy/alpha-beta-support.md#beta-features).
For a group, you can view how many merge requests, issues, and members were created in the last 90 days.
@@ -283,12 +275,8 @@ To view the activity feed in Atom format, select the
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/18328) in GitLab 12.7.
> - [Changed](https://gitlab.com/gitlab-org/gitlab/-/issues/247208) in GitLab 13.11 from a form to a modal window [with a flag](../feature_flags.md). Disabled by default.
> - Modal window [enabled on GitLab.com and self-managed](https://gitlab.com/gitlab-org/gitlab/-/issues/247208) in GitLab 14.8.
-
-FLAG:
-On self-managed GitLab, by default the modal window feature is available.
-To hide the feature, ask an administrator to [disable the feature flag](../../administration/feature_flags.md)
-named `invite_members_group_modal`.
-On GitLab.com, this feature is available.
+> - [Generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/352526) in GitLab 14.9.
+ [Feature flag `invite_members_group_modal`](https://gitlab.com/gitlab-org/gitlab/-/issues/352526) removed.
Similar to how you [share a project with a group](../project/members/share_project_with_groups.md),
you can share a group with another group. Members get direct access
@@ -308,7 +296,7 @@ All the members of the `Engineering` group are added to the `Frontend` group.
## Manage group memberships via LDAP **(PREMIUM SELF)**
-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 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 are associated with GitLab groups.
Group links can be created by using either a CN or a filter. To create these group links, go to the group's **Settings > LDAP Synchronization** page. After configuring the link, it may take more than an hour for the users to sync with the GitLab group.
@@ -325,9 +313,9 @@ To create group links via CN:
1. Select the **LDAP Server** for the link.
1. As the **Sync method**, select `LDAP Group cn`.
-1. In the **LDAP Group cn** field, begin typing the CN of the group. There is a dropdown menu with matching CNs in the configured `group_base`. Select your CN from this list.
+1. In the **LDAP Group cn** field, begin typing the CN of the group. There is a dropdown list with matching CNs in 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. Select the **Add Synchronization** button.
+1. Select **Add Synchronization**.
<!-- vale gitlab.Spelling = YES -->
@@ -339,7 +327,7 @@ To create group links via filter:
1. As the **Sync method**, select `LDAP user filter`.
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).
1. In the **LDAP Access** section, select the [permission level](../permissions.md) for users synced in this group.
-1. Select the **Add Synchronization** button.
+1. Select **Add Synchronization**.
### Override user permissions **(PREMIUM SELF)**
@@ -347,7 +335,7 @@ LDAP user permissions can be manually overridden by an administrator. To overrid
1. Go to your group's **Group information > Members** page.
1. In the row for the user you are editing, select the pencil (**{pencil}**) icon.
-1. Select the brown **Edit permissions** button in the modal.
+1. Select **Edit permissions** in the modal.
Now you can edit the user's permissions from the **Members** page.
@@ -375,7 +363,7 @@ Changing a group's path (group URL) can have unintended side effects. Read
before you proceed.
If you are changing the path so it can be claimed by another group or user,
-you may need to rename the group too. Both names and paths must
+you must rename the group too. Both names and paths must
be unique.
To retain ownership of the original namespace and protect the URL redirects,
@@ -384,7 +372,7 @@ create a new group and transfer projects to it instead.
To change your group path (group URL):
1. Go to your group's **Settings > General** page.
-1. Expand the **Path, transfer, remove** section.
+1. Expand the **Advanced** section.
1. Under **Change group URL**, enter a new name.
1. Select **Change group URL**.
@@ -467,7 +455,7 @@ To restore a group that is marked for deletion:
This setting is only available on top-level groups. It affects all subgroups.
-When checked, any group within the top-level group hierarchy can be shared only with other groups within the hierarchy.
+When checked, any group in the top-level group hierarchy can be shared only with other groups in the hierarchy.
For example, with these groups:
@@ -496,7 +484,7 @@ To prevent a project from being shared with other groups:
1. Go to the group's **Settings > General** page.
1. Expand the **Permissions and group features** section.
-1. Select **Prevent sharing a project within `<group_name>` with other groups**.
+1. Select **Prevent sharing a project in `<group_name>` with other groups**.
1. Select **Save changes**.
This setting applies to all subgroups unless overridden by a group owner. Groups already
@@ -559,6 +547,8 @@ Decreasing the user cap does not approve pending members.
When the number of billable users reaches the user cap, any new member is put in a pending state
and must be approved.
+Pending members do not count as billable. Members count as billable only after they have been approved and are no longer in a pending state.
+
Prerequisite:
- You must be assigned the Owner role) for the group.
@@ -586,7 +576,7 @@ To prevent members from being added to projects in a group:
1. Go to the group's **Settings > General** page.
1. Expand the **Permissions and group features** section.
-1. Under **Member lock**, select **Prevent adding new members to project membership within this group**.
+1. Under **Membership**, select **Prevent adding new members to projects within this group**.
1. Select **Save changes**.
All users who previously had permissions can no longer add members to a group.
@@ -601,7 +591,7 @@ You can export a list of members in a group or subgroup as a CSV.
1. Go to your group or subgroup and select either **Group information > Members** or **Subgroup information > Members**.
1. Select **Export as CSV**.
-1. Once the CSV file has been generated, it is emailed as an attachment to the user that requested it.
+1. After the CSV file has been generated, it is emailed as an attachment to the user that requested it.
## Restrict group access by IP address **(PREMIUM)**
@@ -646,7 +636,7 @@ To restrict group access by IP address:
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/7297) in GitLab 12.2.
> - Support for specifying multiple email domains [added](https://gitlab.com/gitlab-org/gitlab/-/issues/33143) in GitLab 13.1.
-> - Support for restricting access to projects within the group [added](https://gitlab.com/gitlab-org/gitlab/-/issues/14004) in GitLab 14.1.2.
+> - Support for restricting access to projects in the group [added](https://gitlab.com/gitlab-org/gitlab/-/issues/14004) in GitLab 14.1.2.
You can prevent users with email addresses in specific domains from being added to a group and its projects.
@@ -663,7 +653,7 @@ Any time you attempt to add a new user, the user's [primary email](../profile/in
Only users with a [primary email](../profile/index.md#change-your-primary-email) that matches any of the configured email domain restrictions
can be added to the group.
-Some domains cannot be restricted. These are the most popular public email domains, such as:
+The most popular public email domains cannot be restricted, such as:
- `gmail.com`, `yahoo.com`, `aol.com`, `icloud.com`
- `hotmail.com`, `hotmail.co.uk`, `hotmail.fr`
@@ -718,9 +708,10 @@ To disable email notifications:
> [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.
+anyone [mentions a group](../discussions/index.md#mentions)
+in which those users are members.
-Groups with disabled mentions are visualized accordingly in the autocompletion dropdown.
+Groups with disabled mentions are visualized accordingly in the autocompletion dropdown list.
This is particularly helpful for groups with a large number of users.
@@ -806,9 +797,7 @@ The group's new subgroups have push rules set for them based on either:
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/285458) in GitLab 13.9. [Deployed behind the `group_merge_request_approval_settings_feature_flag` flag](../../administration/feature_flags.md), disabled by default.
> - [Enabled by default](https://gitlab.com/gitlab-org/gitlab/-/issues/285410) in GitLab 14.5.
-
-FLAG:
-On self-managed GitLab, by default this feature is available. To hide the feature per group, ask an administrator to [disable the feature flag](../../administration/feature_flags.md) named `group_merge_request_approval_settings_feature_flag`. On GitLab.com, this feature is available.
+> - [Feature flag `group_merge_request_approval_settings_feature_flag`](https://gitlab.com/gitlab-org/gitlab/-/issues/343872) removed in GitLab 14.9.
Group approval rules manage [project merge request approval rules](../project/merge_requests/approvals/index.md)
at the top-level group level. These rules [cascade to all projects](../project/merge_requests/approvals/settings.md#settings-cascading)
diff --git a/doc/user/group/iterations/index.md b/doc/user/group/iterations/index.md
index c0bd6f1a672..b5912a0b40e 100644
--- a/doc/user/group/iterations/index.md
+++ b/doc/user/group/iterations/index.md
@@ -142,6 +142,7 @@ To view an iteration report, go to the iterations list page and select an iterat
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/222750) in GitLab 13.6.
> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/269972) in GitLab 13.7.
+> - Scoped burnup and burndown charts in subgroups and projects [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/326029) in GitLab 14.9.
The iteration report includes [burndown and burnup charts](../../project/milestones/burndown_and_burnup_charts.md),
similar to how they appear when viewing a [milestone](../../project/milestones/index.md).
@@ -149,6 +150,33 @@ similar to how they appear when viewing a [milestone](../../project/milestones/i
Burndown charts help track completion progress of total scope, and burnup charts track the daily
total count and weight of issues added to and completed in a given timebox.
+#### Iteration charts scoped to subgroups or projects
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/326029) in GitLab 14.9.
+
+You can view burndown and burnup charts for iterations created for a group in any of its
+subgroups or projects.
+When you do this, the charts only count the issues that belong to the subgroup or project.
+
+For example, suppose a group has two projects named `Project 1` and `Project 2`.
+Each project has a single issue assigned to the same iteration from the group.
+
+An iteration report generated for the group shows issue counts for all the group's projects:
+
+- Completed: 0 of 2
+- Incomplete: 0 of 2
+- Unstarted: 2 of 2
+- Burndown chart total issues: 2
+- Burnup chart total issues: 2
+
+An iteration report generated for `Project 1` shows only issues that belong to this project:
+
+- Completed: 0 of 1
+- Incomplete: 0 of 1
+- Unstarted: 1 of 1
+- Burndown chart total issues: 1
+- Burnup chart total issues: 1
+
### Group issues by label
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/225500) in GitLab 13.8.
diff --git a/doc/user/group/planning_hierarchy/img/epic-view-ancestors-in-sidebar_v14_6.png b/doc/user/group/planning_hierarchy/img/epic-view-ancestors-in-sidebar_v14_6.png
index 373b861239b..d4ba8acf9b9 100644
--- a/doc/user/group/planning_hierarchy/img/epic-view-ancestors-in-sidebar_v14_6.png
+++ b/doc/user/group/planning_hierarchy/img/epic-view-ancestors-in-sidebar_v14_6.png
Binary files differ
diff --git a/doc/user/group/planning_hierarchy/img/issue-view-parent-epic-in-sidebar_v14_6.png b/doc/user/group/planning_hierarchy/img/issue-view-parent-epic-in-sidebar_v14_6.png
index 95a5777674a..f3b6a80ea66 100644
--- a/doc/user/group/planning_hierarchy/img/issue-view-parent-epic-in-sidebar_v14_6.png
+++ b/doc/user/group/planning_hierarchy/img/issue-view-parent-epic-in-sidebar_v14_6.png
Binary files differ
diff --git a/doc/user/group/planning_hierarchy/img/view-project-work-item-hierarchy_v14_8.png b/doc/user/group/planning_hierarchy/img/view-project-work-item-hierarchy_v14_8.png
deleted file mode 100644
index 2ddd551ee46..00000000000
--- a/doc/user/group/planning_hierarchy/img/view-project-work-item-hierarchy_v14_8.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/group/planning_hierarchy/index.md b/doc/user/group/planning_hierarchy/index.md
index 934421e8a9a..6ffc47923f2 100644
--- a/doc/user/group/planning_hierarchy/index.md
+++ b/doc/user/group/planning_hierarchy/index.md
@@ -5,7 +5,7 @@ group: Product Planning
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
-# Planning hierarchies **(FREE)**
+# Planning hierarchies **(PREMIUM)**
Planning hierarchies are an integral part of breaking down your work in GitLab.
To understand how you can use epics and issues together in hierarchies, remember the following:
@@ -20,21 +20,7 @@ To learn about hierarchies in general, common frameworks, and using GitLab for
portfolio management, see
[How to use GitLab for Agile portfolio planning and project management](https://about.gitlab.com/blog/2020/11/11/gitlab-for-agile-portfolio-planning-project-management/).
-## View planning hierarchies
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/340844/) in GitLab 14.8.
-
-To view the planning hierarchy in a project:
-
-1. On the top bar, select **Menu > Projects** and find your project.
-1. On the left sidebar, select **Project information > Planning hierarchy**.
-
-Under **Current structure**, you can see a hierarchy diagram that matches your current planning hierarchy.
-The work items outside your subscription plan show up below **Unavailable structure**.
-
-![Screenshot showing hierarchy page](img/view-project-work-item-hierarchy_v14_8.png)
-
-## Hierarchies with epics **(PREMIUM)**
+## Hierarchies with epics
With epics, you can achieve the following hierarchy:
@@ -74,7 +60,7 @@ In an issue, you can view the parented epic above the issue in the right sidebar
![epics state dropdown](img/issue-view-parent-epic-in-sidebar_v14_6.png)
-## View ancestry of an epic **(PREMIUM)**
+## View ancestry of an epic
In an epic, you can view the ancestors as parents in the right sidebar under **Ancestors**.
diff --git a/doc/user/group/roadmap/img/epics_state_dropdown_v14_3.png b/doc/user/group/roadmap/img/epics_state_dropdown_v14_3.png
deleted file mode 100644
index 171876e34a9..00000000000
--- a/doc/user/group/roadmap/img/epics_state_dropdown_v14_3.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/group/roadmap/index.md b/doc/user/group/roadmap/index.md
index f10dc3bc22a..89c5c6ed466 100644
--- a/doc/user/group/roadmap/index.md
+++ b/doc/user/group/roadmap/index.md
@@ -24,12 +24,12 @@ When you hover over an epic bar, a popover appears with the epic's title, start
weight completed.
You can expand epics that contain child epics to show their child epics in the roadmap.
-You can click the chevron (**{chevron-down}**) next to the epic title to expand and collapse the
+You can select the chevron (**{chevron-down}**) next to the epic title to expand and collapse the
child epics.
On top of the milestone bars, you can see their title.
When you hover over a milestone bar or title, a popover appears with its title, start date, and due
-date. You can also click the chevron (**{chevron-down}**) next to the **Milestones** heading to
+date. You can also select the chevron (**{chevron-down}**) next to the **Milestones** heading to
toggle the list of the milestone bars.
![roadmap view](img/roadmap_view_v14_3.png)
@@ -47,10 +47,6 @@ Filtering roadmaps by milestone might not be available to you. Check the **versi
When you want to explore a roadmap, there are several ways to make it easier by sorting epics or
filtering them by what's important for you.
-A dropdown menu lets you show only open or closed epics. By default, all epics are shown.
-
-![epics state dropdown](img/epics_state_dropdown_v14_3.png)
-
You can sort epics in the Roadmap view by:
- Start date
@@ -74,18 +70,15 @@ Roadmaps can also be [visualized inside an epic](../epics/index.md#roadmap-in-ep
### Roadmap settings
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/345158) in GitLab 14.8 [with a flag](../../../administration/feature_flags.md) named `roadmap_settings`. Enabled by default.
-
-FLAG:
-On self-managed GitLab, by default this feature is not available. To make it available, ask an administrator to [enable the feature flag](../../../administration/feature_flags.md) named `roadmap_settings`.
-On GitLab.com, this feature is available but can be configured by GitLab.com administrators only.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/345158) in GitLab 14.8 [with a flag](../../../administration/feature_flags.md) named `roadmap_settings`. Enabled by default.
+> - [Generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/350830) in GitLab 14.9. Feature flag `roadmap_settings`removed.
When you enable the roadmap settings sidebar, you can use it to refine epics shown in the roadmap.
You can configure the following:
- Select date range.
-- Turn milestones on or off and select whether to show all, group, sub-group, or project milestones.
+- Turn milestones on or off and select whether to show all, group, subgroup, or project milestones.
- Show all, open, or closed epics.
- Turn progress tracking for child issues on or off and select whether
to use issue weights or counts.
diff --git a/doc/user/group/saml_sso/group_managed_accounts.md b/doc/user/group/saml_sso/group_managed_accounts.md
index aeb7db923a9..bffaef40800 100644
--- a/doc/user/group/saml_sso/group_managed_accounts.md
+++ b/doc/user/group/saml_sso/group_managed_accounts.md
@@ -65,7 +65,7 @@ This restriction also applies to projects forked from or to those groups.
> [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.
+Groups with group-managed accounts can prevent forking of projects to destinations outside the group.
To do so, enable the "Prohibit outer forks" option in **Settings > SAML SSO**.
When enabled **at the parent group level**, projects within the group can be forked
only to other destinations within the group (including its subgroups).
diff --git a/doc/user/group/saml_sso/index.md b/doc/user/group/saml_sso/index.md
index 14c4447c5c6..8ebcd9f62d0 100644
--- a/doc/user/group/saml_sso/index.md
+++ b/doc/user/group/saml_sso/index.md
@@ -176,7 +176,7 @@ See the [troubleshooting page](../../../administration/troubleshooting/group_sam
### Okta setup notes
-Please follow the Okta documentation on [setting up a SAML application in Okta](https://developer.okta.com/docs/guides/build-sso-integration/saml2/overview/) with the notes below for consideration.
+Please follow the Okta documentation on [setting up a SAML application in Okta](https://developer.okta.com/docs/guides/build-sso-integration/saml2/main/) with the notes below for consideration.
<i class="fa fa-youtube-play youtube" aria-hidden="true"></i>
For a demo of the Okta SAML setup including SCIM, see [Demo: Okta Group SAML & SCIM setup](https://youtu.be/0ES9HsZq0AQ).
@@ -214,6 +214,35 @@ we recommend the ["Use the OneLogin SAML Test Connector" documentation](https://
Recommended `NameID` value: `OneLogin ID`.
+### Change the SAML app
+
+To change the SAML app used for sign in:
+
+- If the NameID is not identical in both the existing and new SAML apps, users must:
+ 1. [Unlink the current SAML identity](#unlinking-accounts).
+ 1. [Link their identity](#user-access-and-management) to the new SAML app.
+- If the NameID is identical, no change is required.
+
+### Migrate to a different SAML provider
+
+You can migrate to a different SAML provider. During the migration process users will not be able to access any of the SAML groups.
+To mitigate this, you can disable [SSO enforcement](#sso-enforcement).
+
+To migrate SAML providers:
+
+1. [Configure](#configure-your-identity-provider) the group with the new identity provider SAML app.
+1. Ask users to [unlink their account from the group](#unlinking-accounts).
+1. Ask users to [link their account to the new SAML app](#linking-saml-to-your-existing-gitlabcom-account).
+
+### Change email domains
+
+To migrate users to a new email domain, users must:
+
+1. Add their new email as the primary email to their accounts and verify it.
+1. [Unlink their account from the group](#unlinking-accounts).
+1. [Link their account to the group](#linking-saml-to-your-existing-gitlabcom-account).
+1. (Optional) Remove their old email from the account.
+
## User access and management
> [Improved](https://gitlab.com/gitlab-org/gitlab/-/issues/268142) in GitLab 13.7.
@@ -610,12 +639,6 @@ Alternatively, when users need to [link SAML to their existing GitLab.com accoun
| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| As mentioned in the [NameID](#nameid) section, if the NameID changes for any user, the user can be locked out. This is a common problem when an email address is used as the identifier. | Follow the steps outlined in the ["SAML authentication failed: User has already been taken"](#message-saml-authentication-failed-user-has-already-been-taken) section. |
-### I need to change my SAML app
-
-If the NameID is identical in both SAML apps, then no change is required.
-
-Otherwise, to change the SAML app used for sign in, users need to [unlink the current SAML identity](#unlinking-accounts) and then [link their identity](#user-access-and-management) to the new SAML app.
-
### I need additional information to configure my identity provider
Many SAML terms can vary between providers. It is possible that the information you are looking for is listed under another name.
diff --git a/doc/user/group/saml_sso/scim_setup.md b/doc/user/group/saml_sso/scim_setup.md
index d1e9ba29378..331288e33a1 100644
--- a/doc/user/group/saml_sso/scim_setup.md
+++ b/doc/user/group/saml_sso/scim_setup.md
@@ -51,7 +51,7 @@ Once [Group Single Sign-On](index.md) has been configured, we can:
The SAML application that was created during [Single sign-on](index.md) setup for [Azure](https://docs.microsoft.com/en-us/azure/active-directory/manage-apps/view-applications-portal) now needs to be set up for SCIM. You can refer to [Azure SCIM setup documentation](https://docs.microsoft.com/en-us/azure/active-directory/app-provisioning/use-scim-to-provision-users-and-groups#getting-started).
-1. In your app, go to the Provisioning tab, and set the **Provisioning Mode** to **Automatic**.
+1. In your app, go to the Provisioning tab, and set the **Provisioning Mode** to **Automatic**.
Then fill in the **Admin Credentials**, and save. The **Tenant URL** and **secret token** are the items
retrieved in the [previous step](#gitlab-configuration).
@@ -60,7 +60,7 @@ The SAML application that was created during [Single sign-on](index.md) setup fo
- **Settings**: We recommend setting a notification email and selecting the **Send an email notification when a failure occurs** checkbox.
You also control what is actually synced by selecting the **Scope**. For example, **Sync only assigned users and groups** only syncs the users and groups assigned to the application. Otherwise, it syncs the whole Active Directory.
- - **Mappings**: We recommend keeping **Provision Azure Active Directory Users** enabled, and disable **Provision Azure Active Directory Groups**.
+ - **Mappings**: We recommend keeping **Provision Azure Active Directory Users** enabled, and disable **Provision Azure Active Directory Groups**.
Leaving **Provision Azure Active Directory Groups** enabled does not break the SCIM user provisioning, but it causes errors in Azure AD that may be confusing and misleading.
1. You can then test the connection by selecting **Test Connection**. If the connection is successful, save your configuration before moving on. See below for [troubleshooting](#troubleshooting).
@@ -100,12 +100,14 @@ Once synchronized, changing the field mapped to `id` and `externalId` may cause
### Okta configuration steps
-Before you start this section, complete the [GitLab configuration](#gitlab-configuration) process.
-Make sure that you've also set up a SAML application for [Okta](https://developer.okta.com/docs/guides/build-sso-integration/saml2/overview/),
-as described in the [Okta setup notes](index.md#okta-setup-notes)
+Before you start this section:
-Make sure that the Okta setup matches our documentation exactly, especially the NameID
-configuration. Otherwise, the Okta SCIM app may not work properly.
+- Check that you are using Okta [Lifecycle Management](https://www.okta.com/products/lifecycle-management/) product. This product tier is required to use SCIM on Okta. To check which Okta product you are using, check your signed Okta contract, contact your Okta AE, CSM, or Okta support.
+- Complete the [GitLab configuration](#gitlab-configuration) process.
+- Complete the setup for SAML application for [Okta](https://developer.okta.com/docs/guides/build-sso-integration/saml2/overview/), as described in the [Okta setup notes](index.md#okta-setup-notes).
+- Check that your Okta SAML setup matches our documentation exactly, especially the NameID configuration. Otherwise, the Okta SCIM app may not work properly.
+
+After the above steps are complete:
1. Sign in to Okta.
1. Ensure you are in the Admin section by selecting the **Admin** button located in the top right. The admin button is not visible from the admin page.
@@ -169,7 +171,7 @@ We recommend users do this prior to turning on sync, because while synchronizati
New users and existing users on subsequent visits can access the group through the identify provider's dashboard or by visiting links directly.
-[In GitLab 14.0 and later](https://gitlab.com/gitlab-org/gitlab/-/issues/325712), GitLab users created with a SCIM identity display with an **Enterprise** badge in the **Members** view.
+[In GitLab 14.0 and later](https://gitlab.com/gitlab-org/gitlab/-/issues/325712), GitLab users created by [SAML SSO](index.md#user-access-and-management) or SCIM provisioning display with an **Enterprise** badge in the **Members** view.
![Enterprise badge for users created with a SCIM identity](img/member_enterprise_badge_v14_0.png)
@@ -244,7 +246,7 @@ It is important not to update these to incorrect values, since this causes users
### I need to change my SCIM app
-Individual users can follow the instructions in the ["SAML authentication failed: User has already been taken"](index.md#i-need-to-change-my-saml-app) section.
+Individual users can follow the instructions in the ["SAML authentication failed: User has already been taken"](index.md#change-the-saml-app) section.
Alternatively, users can be removed from the SCIM app which de-links all removed users. Sync can then be turned on for the new SCIM app to [link existing users](#user-access-and-linking-setup).
diff --git a/doc/user/group/settings/group_access_tokens.md b/doc/user/group/settings/group_access_tokens.md
index 769943cd5d8..6b20f1763d4 100644
--- a/doc/user/group/settings/group_access_tokens.md
+++ b/doc/user/group/settings/group_access_tokens.md
@@ -44,7 +44,7 @@ To create a group access token:
1. On the top bar, select **Menu > Groups** and find your group.
1. On the left sidebar, select **Settings > Access Tokens**.
-1. Enter a name.
+1. Enter a name. The token name is visible to any user with permissions to view the group.
1. Optional. Enter an expiry date for the token. The token will expire on that date at midnight UTC.
1. Select a role for the token.
1. Select the [desired scopes](#scopes-for-a-group-access-token).
diff --git a/doc/user/group/subgroups/img/mention_subgroups.png b/doc/user/group/subgroups/img/mention_subgroups.png
deleted file mode 100644
index ec370add4f9..00000000000
--- a/doc/user/group/subgroups/img/mention_subgroups.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/group/subgroups/index.md b/doc/user/group/subgroups/index.md
index 46dea81ae9f..a98f213bb3f 100644
--- a/doc/user/group/subgroups/index.md
+++ b/doc/user/group/subgroups/index.md
@@ -2,189 +2,176 @@
stage: Manage
group: Authentication and Authorization
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
-type: reference, howto, concepts
---
# Subgroups **(FREE)**
> [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.
-
-By using subgroups you can do the following:
-
-- **Separate internal / external organizations.** Since every group
- can have its own visibility level ([public, internal, or private](../../../development/permissions.md#general-permissions)),
- you're able to host groups for different purposes under the same umbrella.
-- **Organize large projects.** For large projects, subgroups makes it
- potentially easier to separate permissions on parts of the source code.
-- **Make it easier to manage people and control visibility.** Give people
- different [permissions](../../permissions.md#group-members-permissions) depending on their group [membership](#membership).
-
-For more information on allowed permissions in groups and projects, see
-[visibility levels](../../../development/permissions.md#general-permissions).
-
-## Overview
-
-A group can have many subgroups inside it, and at the same time a group can have
-only one immediate parent group. It resembles a directory behavior or a nested items list:
-
-- Group 1
- - Group 1.1
- - Group 1.2
- - Group 1.2.1
- - Group 1.2.2
- - Group 1.2.2.1
-
-In a real world example, imagine maintaining a GNU/Linux distribution with the
-first group being the name of the distribution, and subsequent groups split as follows:
-
-- Organization Group - GNU/Linux distro
- - Category Subgroup - Packages
- - (project) Package01
- - (project) Package02
- - Category Subgroup - Software
- - (project) Core
- - (project) CLI
- - (project) Android app
- - (project) iOS app
- - Category Subgroup - Infra tools
- - (project) Ansible playbooks
-
-Another example of GitLab as a company would be the following:
-
-- Organization Group - GitLab
- - Category Subgroup - Marketing
- - (project) Design
- - (project) General
- - Category Subgroup - Software
- - (project) GitLab CE
- - (project) GitLab EE
- - (project) Omnibus GitLab
- - (project) GitLab Runner
- - (project) GitLab Pages daemon
- - Category Subgroup - Infra tools
- - (project) Chef cookbooks
- - Category Subgroup - Executive team
-
-When performing actions such as transferring or importing a project between
-subgroups, the behavior is the same as when performing these actions at the
-`group/project` level.
-
-## Creating a subgroup
-
-Users can create subgroups if they are explicitly added as an Owner (or
-Maintainer, if that setting is enabled) to an immediate parent group, even if group
-creation is disabled by an administrator in their settings.
+You can organize GitLab [groups](../index.md) into subgroups. You can use subgroups to:
+
+- Separate internal and external organizations. Because every subgroup can have its own
+ [visibility level](../../../development/permissions.md#general-permissions), you can host groups for different
+ purposes under the same parent group.
+- Organize large projects. You can use subgroups to give different access to parts of
+ the source code.
+- Manage people and control visibility. Give a user a different
+ [role](../../permissions.md#group-members-permissions) for each group they're [a member of](#subgroup-membership).
+
+Subgroups can:
+
+- Belong to one immediate parent group.
+- Have many subgroups.
+- Be nested up to 20 levels.
+- Use [runners](../../../ci/runners/index.md) registered to parent groups:
+ - Secrets configured for the parent group are available to subgroup jobs.
+ - Users with the Maintainer role in projects that belong to subgroups can see the details of runners registered to
+ parent groups.
+
+For example:
+
+```mermaid
+graph TD
+ subgraph "Parent group"
+ subgraph "Subgroup A"
+ subgraph "Subgroup A1"
+ G["Project E"]
+ end
+ C["Project A"]
+ D["Project B"]
+ E["Project C"]
+ end
+ subgraph "Subgroup B"
+ F["Project D"]
+ end
+ end
+```
+
+## Create a subgroup
+
+Users with the at least the Maintainer role on a group can create subgroups immediately below the group, unless
+[configured otherwise](#change-who-can-create-subgroups). These users can create subgroups even if group creation is
+[disabled by an Administrator](../../admin_area/index.md#prevent-a-user-from-creating-groups) in the user's settings.
To create a subgroup:
-1. On the top bar, select **Menu > Groups** and find the parent group.
-1. In the top right, select **New subgroup**.
+1. On the top bar, select **Menu > Groups** and find and select the parent group to add a subgroup to.
+1. On the parent group's overview page, in the top right, select **New subgroup**.
1. Select **Create group**.
-1. Fill in the fields. View a list of [reserved names](../../reserved_names.md)
- that cannot be used as group names.
+1. Fill in the fields. View a list of [reserved names](../../reserved_names.md) that cannot be used as group names.
1. Select **Create group**.
### Change who can create subgroups
-To create a subgroup you must either be an Owner or a Maintainer of the
-group, depending on the group's setting.
+To create a subgroup, you must have at least the Maintainer role on the group, depending on the group's setting. By
+default:
-By default:
+- In GitLab 12.2 or later, users with at least the Maintainer role can create subgroups.
+- In GitLab 12.1 or earlier, only users with the Owner role can create subgroups.
-- In GitLab 12.2 or later, both Owners and Maintainers can create subgroups.
-- In GitLab 12.1 or earlier, only Owners can create subgroups.
+To change who can create subgroups on a group:
-You can change this setting:
-
-- As group owner:
- 1. Select the group.
+- As a user with the Owner role on the group:
+ 1. On the top bar, select **Menu > Groups** and find the group.
1. On the left sidebar, select **Settings > General**.
1. Expand **Permissions and group features**.
+ 1. Select a role from the **Allowed to create subgroups** dropdown.
- As an administrator:
1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Overview > Groups**.
1. Select the group, and select **Edit**.
+ 1. Select a role from the **Allowed to create subgroups** dropdown.
For more information, view the [permissions table](../../permissions.md#group-members-permissions).
-## Membership
-
-When you add a member to a group, that member is also added to all subgroups.
-Permission level is inherited from the group's parent. This model allows access to
-subgroups if you have membership in one of its parents.
+## Subgroup membership
-Jobs for pipelines in subgroups can use [runners](../../../ci/runners/index.md) registered to the parent group(s).
-This means secrets configured for the parent group are available to subgroup jobs.
+When you add a member to a group, that member is also added to all subgroups. The user's permissions are inherited from
+the group's parent.
-In addition, maintainers of projects that belong to subgroups can see the details of runners registered to parent group(s).
+Subgroup members can:
-The group permissions for a member can be changed only by Owners, and only on
-the **Members** page of the group the member was added.
+1. Be [direct members](../../project/members/index.md#add-users-to-a-project) of the subgroup.
+1. [Inherit membership](../../project/members/index.md#inherited-membership) of the subgroup from the subgroup's parent group.
+1. Be a member of a group that was [shared with the subgroup's top-level group](../index.md#share-a-group-with-another-group).
-You can tell if a member has inherited the permissions from a parent group by
-looking at the group's **Members** page.
+```mermaid
+flowchart RL
+ subgraph Group A
+ A(Direct member)
+ B{{Shared member}}
+ subgraph Subgroup A
+ H(1. Direct member)
+ C{{2. Inherited member}}
+ D{{Inherited member}}
+ E{{3. Shared member}}
+ end
+ A-->|Direct membership of Group A\nInherited membership of Subgroup A|C
+ end
+ subgraph Group C
+ G(Direct member)
+ end
+ subgraph Group B
+ F(Direct member)
+ end
+ F-->|Group B\nshared with\nGroup A|B
+ B-->|Inherited membership of Subgroup A|D
+ G-->|Group C shared with Subgroup A|E
+```
-![Group members page](img/group_members_v14_4.png)
+Group permissions for a member can be changed only by:
-From the image above, we can deduce the following things:
+- Users with the Owner role on the group.
+- Changing the configuration of the group the member was added to.
-- There are 5 members that have access to the group `four`.
-- User 0 is a Reporter and has inherited their permissions from group `one`
- which is above the hierarchy of group `four`.
-- User 1 is a Developer and has inherited their permissions from group
- `one/two` which is above the hierarchy of group `four`.
-- User 2 is a Developer and has inherited their permissions from group
- `one/two/three` which is above the hierarchy of group `four`.
-- For User 3 the **Source** column indicates **Direct member**, therefore they belong to
- group `four`, the one we're inspecting.
-- Administrator is the Owner and member of **all** subgroups and for that reason,
- as with User 3, the **Source** column indicates **Direct member**.
+### Determine membership inheritance
-Members can be [filtered by inherited or direct membership](../index.md#filter-a-group).
+To see if a member has inherited the permissions from a parent group:
-### Overriding the ancestor group membership
+1. On the top bar, select **Menu > Groups** and find the group.
+1. Select **Group information > Members**.
-NOTE:
-You must be an Owner of a group to be able to add members to it.
+Members list for an example subgroup _Four_:
-NOTE:
-A user's permissions in a subgroup cannot be lower than in any of its ancestor groups.
-Therefore, you cannot reduce a user's permissions in a subgroup with respect to its ancestor groups.
+![Group members page](img/group_members_v14_4.png)
-To override a user's membership of an ancestor group (the first group they were
-added to), add the user to the new subgroup again with a higher set of permissions.
+In the screenshot above:
+
+- Five members have access to group _Four_.
+- User 0 has the Reporter role on group _Four_, and has inherited their permissions from group _One_:
+ - User 0 is a direct member of group _One_.
+ - Group _One_ is above group _Four_ in the hierarchy.
+- User 1 has the Developer role on group _Four_ and inherited their permissions from group _Two_:
+ - User 0 is a direct member of group _Two_, which is a subgroup of group _One_.
+ - Groups _One / Two_ are above group _Four_ in the hierarchy.
+- User 2 has the Developer role on group _Four_ and has inherited their permissions from group _Three_:
+ - User 0 is a direct member of group _Three_, which is a subgroup of group _Two_. Group _Two_ is a subgroup of group
+ _One_.
+ - Groups _One / Two / Three_ are above group _Four_ the hierarchy.
+- User 3 is a direct member of group _Four_. This means they get their Maintainer role directly from group _Four_.
+- Administrator has the Owner role on group _Four_ and is a member of all subgroups. For that reason, as with User 3,
+ the **Source** column indicates they are a direct member.
-For example, if User 1 was first added to group `one/two` with Developer
-permissions, then they inherit those permissions in every other subgroup
-of `one/two`. To give them the Maintainer role for group `one/two/three/four`,
-you would add them again in that group as Maintainer. Removing them from that group,
-the permissions fall back to those of the ancestor group.
+Members can be [filtered by inherited or direct membership](../index.md#filter-a-group).
-## Mentioning subgroups
+### Override ancestor group membership
-Mentioning groups (`@group`) in issues, commits and merge requests, would
-notify all members of that group. Now with subgroups, there is more granular
-support if you want to split your group's structure. Mentioning works as before
-and you can choose the group of people to be notified.
+Users with the Owner role on a subgroup can add members to it.
-![Mentioning subgroups](img/mention_subgroups.png)
+You can't give a user a role on a subgroup that's lower than the roles they have on ancestor groups. To override a user's
+role on an ancestor group, add the user to the subgroup again with a higher role. For example:
-## Limitations
+- If User 1 is added to group _Two_ with the Developer role, they inherit that role in every subgroup of group _Two_.
+- To give User 1 the Maintainer role on group _Four_ (under _One / Two / Three_), add them again to group _Four_ with
+ the Maintainer role.
+- If User 1 is removed from group _Four_, their role falls back to their role on group _Two_. They have the Developer
+ role on group _Four_ again.
-Here's a list of what you can't do with subgroups:
+## Mention subgroups
-- [GitLab Pages](../../project/pages/index.md) supports projects hosted under
- a subgroup, but not subgroup websites.
- That means that only the highest-level group supports
- [group websites](../../project/pages/getting_started_part_one.md#gitlab-pages-default-domain-names),
- although you can have project websites under a subgroup.
-- It is not possible to share a project with a group that's an ancestor of
- the group the project is in. That means you can only share as you walk down
- the hierarchy. For example, `group/subgroup01/project` **cannot** be shared
- with `group`, but can be shared with `group/subgroup02` or
- `group/subgroup01/subgroup03`.
+Mentioning subgroups ([`@<subgroup_name>`](../../discussions/index.md#mentions)) in issues, commits, and merge requests
+notifies all members of that group. Mentioning works the same as for projects and groups, and you can choose the group
+of people to be notified.
<!-- ## Troubleshooting
diff --git a/doc/user/group/value_stream_analytics/img/vsa_stage_table_v14_7.png b/doc/user/group/value_stream_analytics/img/vsa_stage_table_v14_7.png
index c9074cbb5ea..7c3305792bb 100644
--- a/doc/user/group/value_stream_analytics/img/vsa_stage_table_v14_7.png
+++ b/doc/user/group/value_stream_analytics/img/vsa_stage_table_v14_7.png
Binary files differ
diff --git a/doc/user/group/value_stream_analytics/index.md b/doc/user/group/value_stream_analytics/index.md
index ccf77f79fd9..5ea8512ed5a 100644
--- a/doc/user/group/value_stream_analytics/index.md
+++ b/doc/user/group/value_stream_analytics/index.md
@@ -2,84 +2,155 @@
type: reference
stage: Manage
group: Optimize
-info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#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/#assignments
---
# Value stream analytics for groups **(PREMIUM)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/196455) in GitLab 12.9 for groups.
-Value stream analytics measures the time spent to go from an
-[idea to production](https://about.gitlab.com/blog/2016/08/05/continuous-integration-delivery-and-deployment-with-gitlab/#from-idea-to-production-with-gitlab)
-(also known as cycle time) for each of your projects or groups. Value stream analytics displays the median time
-spent in each stage defined in the process.
+Value stream analytics provides metrics about each stage of your software development process.
-Value stream analytics can help you quickly determine the velocity of a given
-group. It points to bottlenecks in the development process, enabling management
-to uncover, triage, and identify the root cause of slowdowns in the software development life cycle.
+Use value stream analytics to identify:
-For information on how to contribute to the development of value stream analytics, see our [contributor documentation](../../../development/value_stream_analytics.md).
+- The amount of time it takes to go from an idea to production.
+- The velocity of a given project.
+- Bottlenecks in the development process.
+- Factors that cause your software development lifecycle to slow down.
-To view value stream analytics for groups:
+Value stream analytics is also available for [projects](../../analytics/value_stream_analytics.md).
+
+## View value stream analytics
+
+> - Date range filter [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/13216) in GitLab 12.4
+> - Filtering [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/13216) in GitLab 13.3
+> - Horizontal stage path [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/12196) in 13.0 and [feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/323982) in 13.12
+
+You must have at least the Reporter role to view value stream analytics for groups.
+
+To view value stream analytics for your group:
1. On the top bar, select **Menu > Groups** and find your group.
1. On the left sidebar, select **Analytics > Value stream**.
+1. To view metrics for each stage, above the **Filter results** text box, select a stage.
+1. Optional. Filter the results:
+ 1. Select the **Filter results** text box.
+ 1. Select a parameter.
+ 1. Select a value or enter text to refine the results.
+ 1. To adjust the date range:
+ - In the **From** field, select a start date.
+ - In the **To** field, select an end date. The charts and list show workflow items created
+ during the date range.
+1. Optional. Sort results by ascending or descending:
+ - To sort by most recent or oldest workflow item, select the **Merge requests** or **Issues**
+ header. The header name differs based on the stage you select.
+ - To sort by most or least amount of time spent in each stage, select the **Time** header.
+
+A badge next to the workflow items table header shows the number of workflow items that
+completed during the selected stage.
+
+The table shows a list of related workflow items for the selected stage. Based on the stage you select, this can be:
+
+- CI/CD jobs
+- Issues
+- Merge requests
+- Pipelines
-Value stream analytics at the group level includes data for the selected group and its subgroups.
+## View metrics for each development stage
-NOTE:
-[Value stream analytics for projects](../../analytics/value_stream_analytics.md) is also available.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/210315) in GitLab 13.0.
+> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/323982) in GitLab 13.12.
+
+Value stream analytics shows the median time spent by issues or merge requests in each development stage.
+
+To view the median time spent in each stage by a group:
+
+1. On the top bar, select **Menu > Groups** and find your group.
+1. On the left sidebar, select **Analytics > Value stream**.
+1. Optional. Filter the results:
+ 1. Select the **Filter results** text box.
+ 1. Select a parameter.
+ 1. Select a value or enter text to refine the results.
+ 1. To adjust the date range:
+ - In the **From** field, select a start date.
+ - In the **To** field, select an end date.
+1. To view the metrics for each stage, above the **Filter results** text box, hover over a stage.
+
+## View the lead time and cycle time for issues
+
+Value stream analytics shows the lead time and cycle time for issues in your groups:
+
+- Lead time: Median time from when the issue was created to when it was closed.
+- Cycle time: Median time from first commit to issue closed. Commits are associated with issues when users [cross-link them in the commit message](../../project/issues/crosslinking_issues.md#from-commit-messages).
+
+To view the lead time and cycle time for issues:
+
+1. On the top bar, select **Menu > Groups** and find your group.
+1. On the left sidebar, select **Analytics > Value stream**.
+1. Optional. Filter the results:
+ 1. Select the **Filter results** text box.
+ 1. Select a parameter.
+ 1. Select a value or enter text to refine the results.
+ 1. To adjust the date range:
+ - In the **From** field, select a start date.
+ - In the **To** field, select an end date.
+
+The **Lead Time** and **Cycle Time** metrics display below the **Filter results** text box.
+
+## View lead time for changes for merge requests **(ULTIMATE)**
-## Default stages
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/340150) in GitLab 14.5.
-The stages tracked by value stream analytics by default represent the [GitLab flow](../../../topics/gitlab_flow.md).
-These stages can be customized in value stream analytics for groups.
+Lead time for changes is the median duration between when a merge request is merged and when it's deployed to production.
-- **Issue** (Tracker)
- - Time to schedule an issue (by milestone or by adding it to an issue board)
-- **Plan** (Board)
- - Time to first commit
-- **Code** (IDE)
- - Time to create a merge request
-- **Test** (CI)
- - Time it takes GitLab CI/CD to test your code
-- **Review** (Merge Request/MR)
- - Time spent on code review
-- **Staging** (Continuous Deployment)
- - Time between merging and deploying to production
+To view the lead time for changes for merge requests in your group:
-## Filter the analytics data
+1. On the top bar, select **Menu > Groups** and find your group.
+1. On the left sidebar, select **Analytics > Value stream**.
+1. Optional. Filter the results:
+ 1. Select the **Filter results** text box.
+ 1. Select a parameter.
+ 1. Select a value or enter text to refine the results.
+ 1. To adjust the date range:
+ - In the **From** field, select a start date.
+ - In the **To** field, select an end date.
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/13216) in GitLab 13.3
+The **Lead Time for Changes** metrics display below the **Filter results** text box.
-GitLab provides the ability to filter analytics based on the following parameters:
+## View number of successful deployments **(PREMIUM)**
-- Milestones (Group level)
-- Labels (Group level)
-- Author
-- Assignees
+> DORA API-based deployment metrics for value stream analytics for groups were [moved](https://gitlab.com/gitlab-org/gitlab/-/issues/337256) from GitLab Ultimate to GitLab Premium in 14.3.
-To filter results:
+To view deployment metrics, you must have a
+[production environment configured](../../../ci/environments/index.md#deployment-tier-of-environments).
-1. Select a group.
-1. Click on the filter bar.
-1. Select a parameter to filter by.
-1. Select a value from the autocompleted results, or type to refine the results.
+Value stream analytics shows the following deployment metrics for your group:
+
+- Deploys: The number of successful deployments in the date range.
+- Deployment Frequency: The average number of successful deployments per day in the date range.
-![Value stream analytics filter bar](img/vsa_filter_bar_v13_12.png "Active filter bar for value stream analytics")
+To view deployment metrics for your group:
-### Date ranges
+1. On the top bar, select **Menu > Groups** and find your group.
+1. On the left sidebar, select **Analytics > Value stream**.
+1. Optional. Filter the results:
+ 1. Select the **Filter results** text box.
+ 1. Select a parameter.
+ 1. Select a value or enter text to refine the results.
+ 1. To adjust the date range:
+ - In the **From** field, select a start date.
+ - In the **To** field, select an end date.
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/13216) in GitLab 12.4.
+The **Deploys** and **Deployment Frequency** metrics display below the **Filter results** text box.
-GitLab provides the ability to filter analytics based on a date range.
-Data is shown for workflow items created during the selected date range. To filter results:
+Deployment metrics are calculated based on data from the
+[DORA API](../../../api/dora/metrics.md#devops-research-and-assessment-dora-key-metrics-api).
-1. Select a group.
-1. Optionally select a project.
-1. Select a date range using the available date pickers.
+NOTE:
+In GitLab 13.9 and later, metrics are calculated based on when the deployment was finished.
+In GitLab 13.8 and earlier, metrics are calculated based on when the deployment was created.
-### Upcoming date filter change
+## Upcoming date filter change
In the [epics](https://gitlab.com/groups/gitlab-org/-/epics/6046), we plan to alter
the date filter behavior to filter the end event time of the currently selected stage.
@@ -92,82 +163,72 @@ If you were to look at the metrics for the last three months, this issue would n
the stage metrics. With the new date filter, this item would be included.
DISCLAIMER:
-This page contains information related to upcoming products, features, and functionality.
+This section contains information related to upcoming products, features, and functionality.
It is important to note that the information presented is for informational purposes only.
Please do not rely on this information for purchasing or planning purposes.
As with all projects, the items mentioned on this page are subject to change or delay.
The development, release, and timing of any products, features, or functionality remain at the
sole discretion of GitLab Inc.
-## How metrics are measured
-
-> DORA API-based deployment metrics for value stream analytics for groups were [moved](https://gitlab.com/gitlab-org/gitlab/-/issues/337256) from GitLab Ultimate to GitLab Premium in 14.3.
-
-The "Time" metrics near the top of the page are measured as follows:
+## How value stream analytics measures stages
-- **Lead time**: median time from issue created to issue closed.
-- **Cycle time**: median time from first commit to issue closed. (You can associate a commit with an
- issue by [crosslinking in the commit message](../../project/issues/crosslinking_issues.md#from-commit-messages).)
-- **Lead Time for Changes**: median time between when a merge request is merged and deployed to a
-production environment for all merge requests deployed in the given time period.
-[Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/340150) in GitLab 14.5.
-
-- **Lead Time for Changes**: median duration between merge request merge and deployment to a production environment for all MRs deployed in the given time period. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/340150) in GitLab 14.5.
-
-The "Recent Activity" metrics near the top of the page are measured as follows:
-
-- **New Issues:** the number of issues created in the date range.
-- **Deploys:** the number of deployments to production in the date range.
-- **Deployment Frequency:** the average number of deployments to production
- per day in the date range.
-
-To see deployment metrics, you must have a [production environment configured](../../../ci/environments/index.md#deployment-tier-of-environments).
+Value stream analytics measures each stage from its start event to its end event.
-NOTE:
-In GitLab 13.9 and later, deployment metrics are calculated based on when the deployment was finished.
-In GitLab 13.8 and earlier, deployment metrics are calculated based on when the deployment was created.
+For example, a stage might start when a user adds a label to an issue, and ends when they add another label.
+Items aren't included in the stage time calculation if they have not reached the end event.
-You can learn more about these metrics in our [analytics definitions](../../analytics/index.md).
+Each stage of value stream analytics is further described in the table below.
-![Value stream analytics time metrics](img/vsa_time_metrics_v13_12.png "Time metrics for value stream analytics")
+| Stage | Measurement method |
+| ------- | -------------------- |
+| Issue | The median time between creating an issue and taking action to solve it, by either labeling it or adding it to a milestone, whichever comes first. The label is tracked only if it already has an [issue board list](../../project/issue_board.md) created for it. |
+| Plan | The median time between the action you took for the previous stage, and pushing the first commit to the branch. The first commit on the branch triggers the separation between **Plan** and **Code**. At least one of the commits in the branch must contain the related issue number (for example, `#42`). If none of the commits in the branch mention the related issue number, it is not considered in the measurement time of the stage. |
+| Code | The median time between pushing a first commit (previous stage) and creating a merge request (MR) related to that commit. The key to keep the process tracked is to include the [issue closing pattern](../../project/issues/managing_issues.md#default-closing-pattern) in the description of the merge request. For example, `Closes #xxx`, where `xxx` is the number of the issue related to this merge request. If the closing pattern is not present, then the calculation uses the creation time of the first commit in the merge request as the start time. |
+| Test | 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. It is basically the start->finish time for all pipelines. |
+| Review | The median time taken to review a merge request that has a closing issue pattern, between its creation and until it's merged. |
+| Staging | The median time between merging a merge request that has a closing issue pattern until the very first deployment to a [production environment](#how-value-stream-analytics-identifies-the-production-environment). If there isn't a production environment, this is not tracked. |
-## How the stages are measured
+## Example workflow
-Value stream analytics measures each stage from its start event to its end event.
-For example, a stage might start when one label is added to an issue, and end when another label is added.
-Value stream analytics excludes work in progress, meaning it ignores any items that have not reached the end event.
+This example shows a workflow through all seven stages in one day.
-Each stage of value stream analytics is further described in the table below.
+If a stage does not include a start and a stop time, its data is not included in the median time.
+In this example, milestones have been created and CI/CD for testing and setting environments is configured.
-| **Stage** | **Description** |
-| --------- | --------------- |
-| Issue | Measures the median time between creating an issue and taking action to solve it, by either labeling it or adding it to a milestone, whatever comes first. The label is tracked only if it already has an [issue board list](../../project/issue_board.md) created for it. |
-| Plan | Measures the median time between the action you took for the previous stage, and pushing the first commit to the branch. The very first commit of the branch is the one that triggers the separation between **Plan** and **Code**, and at least one of the commits in the branch needs to contain the related issue number (for example, `#42`). If none of the commits in the branch mention the related issue number, it is not considered to the measurement time of the stage. |
-| Code | Measures the median time between pushing a first commit (previous stage) and creating a merge request (MR) related to that commit. The key to keep the process tracked is to include the [issue closing pattern](../../project/issues/managing_issues.md#closing-issues-automatically) to the description of the merge request (for example, `Closes #xxx`, where `xxx` is the number of the issue related to this merge request). If the closing pattern is not present, then the calculation takes the creation time of the first commit in the merge request as the start time. |
-| Test | Measures the median time to run the entire pipeline for that project. It's related to the time GitLab CI/CD takes to run every job for the commits pushed to that merge request defined in the previous stage. It is basically the start->finish time for all pipelines. |
-| 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 a [production environment](#how-the-production-environment-is-identified). If there isn't a production environment, this is not tracked. |
+- 09:00: Create issue. **Issue** stage starts.
+- 11:00: Add issue to a milestone, start work on the issue, and create a branch locally.
+ **Issue** stage stops and **Plan** stage starts.
+- 12:00: Make the first commit.
+- 12:30: Make the second commit to the branch that mentions the issue number.
+ **Plan** stage stops and **Code** stage starts.
+- 14:00: Push branch and create a merge request that contains the
+ [issue closing pattern](../../project/issues/managing_issues.md#closing-issues-automatically).
+ **Code** stage stops and **Test** and **Review** stages start.
+- GitLab CI/CD takes 5 minutes to run scripts defined in [`.gitlab-ci.yml`](../../../ci/yaml/index.md).
+- 19:00: Merge the merge request. **Review** stage stops and **Staging** stage starts.
+- 19:30: Deployment to the `production` environment finishes. **Staging** stops.
-How this works, behind the scenes:
+Value stream analytics records the following times for each stage:
-1. Issues and merge requests are grouped together in pairs, such that for each
- `<issue, merge request>` pair, the merge request has the [issue closing pattern](../../project/issues/managing_issues.md#closing-issues-automatically)
- for the corresponding issue. All other issues and merge requests are **not**
- considered.
-1. Then the `<issue, merge request>` pairs are filtered out by last XX days (specified
- by the UI - default is 90 days). So it prohibits these pairs from being considered.
-1. For the remaining `<issue, merge request>` pairs, we check the information that
- we need for the stages, like issue creation date, merge request merge time,
- and so on.
+- **Issue**: 09:00 to 11:00: 2 hrs
+- **Plan**: 11:00 to 12:00: 1 hr
+- **Code**: 12:00 to 14:00: 2 hrs
+- **Test**: 5 minutes
+- **Review**: 14:00 to 19:00: 5 hrs
+- **Staging**: 19:00 to 19:30: 30 minutes
-To sum up, anything that doesn't follow [GitLab flow](../../../topics/gitlab_flow.md) is not tracked and the
-value stream analytics dashboard does not present any data for:
+There are some additional considerations for this example:
-- Merge requests that do not close an issue.
-- Issues not labeled with a label present in the issue board or for issues not assigned a milestone.
-- Staging stage, if the project has no [production environment](#how-the-production-environment-is-identified).
+- This example demonstrates that it doesn't matter if your first
+ commit doesn't mention the issue number, you can do this later in any commit
+ on the branch you are working on.
+- The **Test** stage is used in the calculation for the overall time of
+ the cycle. It is included in the **Review** process, as every MR should be
+ tested.
+- This example illustrates only **one cycle** of the seven stages. The value stream analytics dashboard
+ shows the median time for multiple cycles.
-## How the production environment is identified
+## How value stream analytics identifies the production environment
Value stream analytics identifies production environments by looking for project
[environments](../../../ci/yaml/index.md#environment) with a name matching any of these patterns:
@@ -179,149 +240,22 @@ These patterns are not case-sensitive.
You can change the name of a project environment in your GitLab CI/CD configuration.
-## Example workflow
-
-Below is an example workflow of a single cycle that happens in a
-single day through all noted stages. Note that if a stage does not include a start
-and a stop time, its data is not included in the median time. It is assumed that
-milestones are created and a CI for testing and setting environments is configured.
-a start and a stop mark, it is not measured and hence not calculated in the median
-time. It is assumed that milestones are created and CI for testing and setting
-environments is configured.
-
-1. Issue is created at 09:00 (start of **Issue** stage).
-1. Issue is added to a milestone at 11:00 (stop of **Issue** stage / start of
- **Plan** stage).
-1. Start working on the issue, create a branch locally and make one commit at
- 12:00.
-1. Make a second commit to the branch which mentions the issue number at 12.30
- (stop of **Plan** stage / start of **Code** stage).
-1. Push branch and create a merge request that contains the
- [issue closing pattern](../../project/issues/managing_issues.md#closing-issues-automatically)
- in its description at 14:00 (stop of **Code** stage / start of **Test** and
- **Review** stages).
-1. The CI starts running your scripts defined in [`.gitlab-ci.yml`](../../../ci/yaml/index.md) and
- takes 5min (stop of **Test** stage).
-1. Review merge request, ensure that everything is OK and merge the merge
- request at 19:00. (stop of **Review** stage / start of **Staging** stage).
-1. Now that the merge request is merged, a deployment to the `production`
- environment starts and finishes at 19:30 (stop of **Staging** stage).
-
-From the above example you can conclude the time it took each stage to complete
-as long as their total time:
-
-- **Issue**: 2h (11:00 - 09:00)
-- **Plan**: 1h (12:00 - 11:00)
-- **Code**: 2h (14:00 - 12:00)
-- **Test**: 5min
-- **Review**: 5h (19:00 - 14:00)
-- **Staging**: 30min (19:30 - 19:00)
-
-A few notes:
-
-- In the above example we demonstrated that it doesn't matter if your first
- commit doesn't mention the issue number, you can do this later in any commit
- of the branch you are working on.
-- You can see that the **Test** stage is not calculated to the overall time of
- the cycle, because it is included in the **Review** process (every MR should be
- tested).
-- The example above was just **one cycle** of the seven stages. Add multiple
- cycles, calculate their median time and the result is what the dashboard of
- value stream analytics is showing.
-
## Custom value streams
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/12196) in GitLab 12.9.
-The default stages are designed to work straight out of the box, but they might not be suitable for
-all teams. Different teams use different approaches to building software, so some teams might want
-to customize their value stream analytics.
-
-GitLab allows users to create multiple value streams, hide default stages and create custom stages
-that align better to their development workflow.
-
-### Stage path
-
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/210315) in GitLab 13.0.
-> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/323982) in GitLab 13.12.
-
-![Value stream path navigation](img/vsa_path_nav_v13_11.png "Value stream path navigation")
-
-Stages are visually depicted as a horizontal process flow. Selecting a stage updates the content
-below the value stream.
-
-The stage time is displayed next to the name of each stage, in the following format:
-
-| Symbol | Description |
-|--------|-------------|
-| `m` | Minutes |
-| `h` | Hours |
-| `d` | Days |
-| `w` | Weeks |
-| `M` | Months |
-
-Hovering over a stage item displays a popover with the following information:
-
-- Start event description for the given stage
-- End event description
-- Median time items took to complete the stage
-- Number of items that completed the stage
-
-### Stream overview
-
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/321438) in GitLab 13.11.
-
-![Value stream analytics overview](img/vsa_overview_stage_v13_11.png "VSA overview")
-
-The stream overview provides access to key metrics and charts summarizing all the stages in the value stream
-based on selected filters.
-
-Shown metrics and charts includes:
-
-- [Lead time](#how-metrics-are-measured)
-- [Cycle time](#how-metrics-are-measured)
-- [Days to completion chart](#days-to-completion-chart)
-- [Tasks by type chart](#type-of-work---tasks-by-type-chart)
-
-### Stage table
-
-> Sorting the stage table [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/301082) in GitLab 13.12.
+Use custom value streams to create custom stages that align with your own development processes,
+and hide default stages. The dashboard depicts stages as a horizontal process
+flow.
-![Value stream analytics stage table](img/vsa_stage_table_v14_7.png "VSA stage table")
-
-The stage table shows a list of related workflow items for the selected stage. This can include:
-
-- CI/CD jobs
-- Issues
-- Merge requests
-- Pipelines
-
-A little badge next to the workflow items table header shows the number of workflow items that
-completed the selected stage.
-
-The stage table also includes the **Time** column, which shows how long it takes each item to pass
-through the selected value stream stage.
-
-The stage table is not displayed on the stream [Overview](#stream-overview).
-The workflow item column (first column) is ordered by end event.
-
-To sort the stage table by a table column, select the table header.
-You can sort in ascending or descending order. To find items that spent the most time in a stage,
-potentially causing bottlenecks in your value stream, sort the table by the **Time** column.
-From there, select individual items to drill in and investigate how delays are happening.
-To see which items most recently exited the stage, sort by the work item column on the left.
-
-The table displays 20 items per page. If there are more than 20 items, you can use the
-**Prev** and **Next** buttons to navigate through the pages.
-
-### Creating a value stream
+### Create a value stream
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/221202) in GitLab 13.3
A default value stream is readily available for each group. You can create additional value streams
based on the different areas of work that you would like to measure.
-Once created, a new value stream includes the [seven stages](#default-stages) that follow
+Once created, a new value stream includes the stages that follow
[GitLab workflow](../../../topics/gitlab_flow.md)
best practices. You can customize this flow by adding, hiding or re-ordering stages.
@@ -331,20 +265,17 @@ To create a value stream:
1. On the left sidebar, select **Analytics > Value Stream**.
1. In the top right, select the dropdown list and then **Create new Value Stream**.
1. Enter a name for the new Value Stream.
- - You can [customize the stages](#creating-a-value-stream-with-stages).
+ - You can [customize the stages](#create-a-value-stream-with-stages).
1. Select **Create Value Stream**.
![New value stream](img/new_value_stream_v13_12.png "Creating a new value stream")
-#### Creating a value stream with stages
+### Create a value stream with stages
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/50229) in GitLab 13.7.
> - [Enabled by default](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/55572) in GitLab 13.10.
> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/294190) in GitLab 13.11.
-WARNING:
-This feature might not be available to you. Check the **version history** note above for details.
-
You can create value streams with stages, starting with a default or a blank template. You can
add stages as desired.
@@ -364,7 +295,7 @@ To create a value stream with stages:
![Custom stage actions](img/vsa_custom_stage_v13_10.png "Custom stage actions")
1. Select **Create Value Stream**.
-#### Label-based stages
+### Label-based stages
The pre-defined start and end events can cover many use cases involving both issues and merge requests.
@@ -379,7 +310,7 @@ In this example, we'd like to measure times for deployment from a staging enviro
![Label-based value stream analytics stage](img/vsa_label_based_stage_v14_0.png "Creating a label-based value stream analytics stage")
-### Editing a value stream
+### Edit a value stream
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/267537) in GitLab 13.10.
@@ -388,7 +319,7 @@ After you create a value stream, you can customize it to suit your purposes. To
1. On the top bar, select **Menu > Groups** and find your group.
1. On the left sidebar, select **Analytics > Value Stream**.
1. In the top right, select the dropdown list and then select the relevant value stream.
-1. Next to the value stream dropdown, select **Edit**.
+1. Next to the value stream dropdown list, select **Edit**.
The edit form is populated with the value stream details.
1. Optional:
- Rename the value stream.
@@ -399,7 +330,7 @@ After you create a value stream, you can customize it to suit your purposes. To
1. Optional. To undo any modifications, select **Restore value stream defaults**.
1. Select **Save Value Stream**.
-### Deleting a value stream
+### Delete a value stream
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/221205) in GitLab 13.4.
@@ -413,19 +344,27 @@ To delete a custom value stream:
![Delete value stream](img/delete_value_stream_v13_12.png "Deleting a custom value stream")
-## Days to completion chart
+## View number of days for a cycle to complete
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/21631) in GitLab 12.6.
> - Chart median line [removed](https://gitlab.com/gitlab-org/gitlab/-/issues/235455) in GitLab 13.4.
> - Totals [replaced](https://gitlab.com/gitlab-org/gitlab/-/issues/262070) with averages in GitLab 13.12.
-This chart visually depicts the average number of days it takes for cycles to be completed.
-
-This chart uses the global page filters for displaying data based on the selected
-group, projects, and time frame. In addition, specific stages can be selected
-from the chart itself.
+The **Total time chart** shows the average number of days it takes for development cycles to complete.
+The chart shows data for the last 500 workflow items.
-The chart data is limited to the last 500 items.
+1. On the top bar, select **Menu > Groups** and find your group.
+1. On the left sidebar, select **Analytics > Value stream**.
+1. Above the **Filter results** box, select a stage:
+ - To view a summary of the cycle time for all stages, select **Overview**.
+ - To view the cycle time for specific stage, select a stage.
+1. Optional. Filter the results:
+ 1. Select the **Filter results** text box.
+ 1. Select a parameter.
+ 1. Select a value or enter text to refine the results.
+ 1. To adjust the date range:
+ - In the **From** field, select a start date.
+ - In the **To** field, select an end date.
## Type of work - Tasks by type chart
@@ -439,17 +378,3 @@ toggled to show data for merge requests and further refined for specific group-l
By default the top group-level labels (max. 10) are pre-selected, with the ability to
select up to a total of 15 labels.
-
-## Permissions
-
-To access value stream analytics for groups, users must have at least the Reporter role.
-
-You can [read more about permissions](../../permissions.md) in general.
-
-## More resources
-
-Learn more about value stream analytics in the following resources:
-
-- [Value stream analytics feature page](https://about.gitlab.com/stages-devops-lifecycle/value-stream-analytics/).
-- [Value stream analytics feature preview](https://about.gitlab.com/blog/2016/09/16/feature-preview-introducing-cycle-analytics/).
-- [Value stream analytics feature highlight](https://about.gitlab.com/blog/2016/09/21/cycle-analytics-feature-highlight/).
diff --git a/doc/user/index.md b/doc/user/index.md
index f4a7cd6a5d9..4ce46c5b46f 100644
--- a/doc/user/index.md
+++ b/doc/user/index.md
@@ -47,6 +47,8 @@ GitLab is a Git-based platform that integrates a great number of essential tools
- Reviewing code in [merge requests](project/merge_requests/index.md) with live-preview changes per
branch with [Review Apps](../ci/review_apps/index.md).
- Building, testing, and deploying with built-in [Continuous Integration](../ci/index.md).
+- View the current health and status of each CI environment running on Kubernetes with [deploy boards](project/deploy_boards.md).
+- Leverage continuous delivery method with [Canary Deployments](project/canary_deployments.md).
- Deploying personal and professional static websites with [GitLab Pages](project/pages/index.md).
- Integrating with Docker by using [GitLab Container Registry](packages/container_registry/index.md).
- Tracking the development lifecycle by using [GitLab Value Stream Analytics](analytics/value_stream_analytics.md).
@@ -66,8 +68,6 @@ With GitLab Enterprise Edition, you can also:
- [Mirror a repository](project/repository/mirror/index.md) from elsewhere on your local server.
- View your entire CI/CD pipeline involving more than one project with [Multiple-Project Pipelines](../ci/pipelines/multi_project_pipelines.md).
- [Lock files](project/file_lock.md) to prevent conflicts.
-- View the current health and status of each CI environment running on Kubernetes with [deploy boards](project/deploy_boards.md).
-- Leverage continuous delivery method with [Canary Deployments](project/canary_deployments.md).
- Scan your code for vulnerabilities and [display them in merge requests](application_security/sast/index.md).
You can also [integrate](project/integrations/overview.md) GitLab with numerous third-party applications, such as Mattermost, Microsoft Teams, Trello, Slack, Bamboo CI, Jira, and a lot more.
@@ -76,12 +76,15 @@ You can also [integrate](project/integrations/overview.md) GitLab with numerous
There are several types of users in GitLab:
-- Regular users and GitLab.com users. <!-- Note: further description TBA -->
-- [Groups](group/index.md) of users.
-- GitLab [administrator area](admin_area/index.md) user.
+- Regular users.
+- [Internal users](../development/internal_users.md) often referred to as bot or system users.
+- [Auditor](permissions.md#auditor-users) with read access to self-managed instances.
- [GitLab Administrator](../administration/index.md) with full access to
- self-managed instances' features and settings.
-- [Internal users](../development/internal_users.md).
+ self-managed instances including settings and the [Admin Area](admin_area/index.md).
+
+Each user can be a member in a [group](group/index.md).
+
+See the [permissions page](permissions.md) for details on how each user type is used.
## User activity
@@ -159,8 +162,7 @@ it all at once, from one single project.
## Account
-There is a lot you can customize and configure
-to enjoy the best of GitLab.
+There is a lot you can customize and configure to enjoy the best of GitLab.
- [Settings](profile/index.md): Manage your user settings to change your personal information,
personal access tokens, authorized applications, etc.
@@ -209,8 +211,7 @@ requests you're assigned to.
## Snippets
[Snippets](snippets.md) are code blocks that you want to store in GitLab, from which
-you have quick access to. You can also gather feedback on them through
-[Discussions](#discussions).
+you have quick access to. You can also gather feedback on them through [Discussions](#discussions).
## GitLab CI/CD
@@ -228,8 +229,7 @@ pages and accomplish tasks faster.
## Integrations
-[Integrate GitLab](../integration/index.md) with your preferred tool,
-such as Trello, Jira, etc.
+[Integrate GitLab](../integration/index.md) with your preferred tool, such as Trello, Jira, etc.
## Webhooks
@@ -251,5 +251,4 @@ See [various statistics](admin_area/analytics/index.md) of your GitLab instance.
## Operations Dashboard
-See [Operations Dashboard](operations_dashboard/index.md) for a summary of each
-project's operational health.
+See [Operations Dashboard](operations_dashboard/index.md) for a summary of each project's operational health.
diff --git a/doc/user/infrastructure/clusters/connect/index.md b/doc/user/infrastructure/clusters/connect/index.md
index 06d1307984d..004f4409919 100644
--- a/doc/user/infrastructure/clusters/connect/index.md
+++ b/doc/user/infrastructure/clusters/connect/index.md
@@ -8,10 +8,10 @@ info: To determine the technical writer assigned to the Stage/Group associated w
The [certificate-based Kubernetes integration with GitLab](../index.md)
was [deprecated](https://gitlab.com/groups/gitlab-org/configure/-/epics/8)
-in GitLab 14.5. To connect your clusters, use the [GitLab Agent](../../../clusters/agent/index.md).
+in GitLab 14.5. To connect your clusters, use the [GitLab agent](../../../clusters/agent/index.md).
<!-- TBA: (We need to resolve https://gitlab.com/gitlab-org/gitlab/-/issues/343660 before adding this line)
-If you don't have a cluster yet, create one and connect it to GitLab through the Agent.
+If you don't have a cluster yet, create one and connect it to GitLab through the agent.
You can also create a new cluster from GitLab using [Infrastructure as Code](../../iac/index.md#create-a-new-cluster-through-iac).
-->
diff --git a/doc/user/infrastructure/clusters/connect/new_eks_cluster.md b/doc/user/infrastructure/clusters/connect/new_eks_cluster.md
new file mode 100644
index 00000000000..87b8f510289
--- /dev/null
+++ b/doc/user/infrastructure/clusters/connect/new_eks_cluster.md
@@ -0,0 +1,132 @@
+---
+stage: Configure
+group: Configure
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
+---
+
+# Create an Amazon EKS cluster
+
+You can create a cluster on Amazon Elastic Kubernetes Service (EKS) through
+[Infrastructure as Code (IaC)](../../index.md). This process uses the AWS and
+Kubernetes Terraform providers to create EKS clusters. You connect the clusters to GitLab
+by using the GitLab agent for Kubernetes.
+
+**Prerequisites:**
+
+- An Amazon Web Services (AWS) account, with a set of configured
+ [security credentials](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-prereqs.html).
+- [A runner](https://docs.gitlab.com/runner/install/) you can use to run the GitLab CI/CD pipeline.
+
+**Steps:**
+
+1. [Import the example project](#import-the-example-project).
+1. [Register the agent for Kubernetes](#register-the-agent).
+1. [Configure your project](#configure-your-project).
+1. [Provision your cluster](#provision-your-cluster).
+
+## Import the example project
+
+To create a cluster from GitLab using Infrastructure as Code, you must
+create a project to manage the cluster from. In this tutorial, you start with
+a sample project and modify it according to your needs.
+
+Start by [importing the example project by URL](../../../project/import/repo_by_url.md).
+
+To import the project:
+
+1. On the top bar, select **Menu > Create new project**.
+1. Select **Import project**.
+1. Select **Repo by URL**.
+1. For the **Git repository URL**, enter `https://gitlab.com/gitlab-org/configure/examples/gitlab-terraform-eks.git`.
+1. Complete the fields and select **Create project**.
+
+This project provides you with:
+
+- An Amazon [Virtual Private Cloud (VPC)](https://gitlab.com/gitlab-org/configure/examples/gitlab-terraform-eks/-/blob/main/vpc.tf).
+- An Amazon [Elastic Kubernetes Service (EKS)](https://gitlab.com/gitlab-org/configure/examples/gitlab-terraform-eks/-/blob/main/eks.tf) cluster.
+- The [GitLab agent for Kubernetes](https://gitlab.com/gitlab-org/configure/examples/gitlab-terraform-eks/-/blob/main/agent.tf) installed in the cluster.
+
+## Register the agent
+
+To create a GitLab agent for Kubernetes:
+
+1. On the left sidebar, select **Infrastructure > Kubernetes clusters**.
+1. Select **Actions**.
+1. From the **Select an agent** dropdown list, select `eks-agent` and select **Register an agent**.
+1. GitLab generates a registration token for the agent. Securely store this secret token, as you will need it later.
+1. GitLab provides an address for the agent server (KAS), which you will also need later.
+
+## Configure your project
+
+Use CI/CD environment variables to configure your project.
+
+**Required configuration:**
+
+1. On the left sidebar, select **Settings > CI/CD**.
+1. Expand **Variables**.
+1. Set the variable `AWS_ACCESS_KEY_ID` to your AWS access key ID.
+1. Set the variable `AWS_SECRET_ACCESS_KEY` to your AWS secret access key.
+1. Set the variable `TF_VAR_agent_token` to the agent token displayed in the previous task.
+1. Set the variable `TF_VAR_kas_address` to the agent server address displayed in the previous task.
+
+**Optional configuration:**
+
+The file [`variables.tf`](https://gitlab.com/gitlab-org/configure/examples/gitlab-terraform-eks/-/blob/main/variables.tf)
+contains other variables that you can override according to your needs:
+
+- `TF_VAR_region`: Set your cluster's region.
+- `TF_VAR_cluster_name`: Set your cluster's name.
+- `TF_VAR_cluster_version`: Set the version of Kubernetes.
+- `TF_VAR_instance_type`: Set the instance type for the Kubernetes nodes.
+- `TF_VAR_instance_count`: Set the number of Kubernetes nodes.
+- `TF_VAR_agent_version`: Set the version of the GitLab agent.
+- `TF_VAR_agent_namespace`: Set the Kubernetes namespace for the GitLab agent.
+
+View the [AWS Terraform provider](https://registry.terraform.io/providers/hashicorp/aws/latest/docs) and the [Kubernetes Terraform provider](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs) documentation for further resource options.
+
+## Provision your cluster
+
+After configuring your project, manually trigger the provisioning of your cluster. In GitLab:
+
+1. On the left sidebar, go to **CI/CD > Pipelines**.
+1. Next to **Play** (**{play}**), select the dropdown icon (**{angle-down}**).
+1. Select **Deploy** to manually trigger the deployment job.
+
+When the pipeline finishes successfully, you can view the new cluster:
+
+- In AWS: From the [EKS console](https://console.aws.amazon.com/eks/home), select **Amazon EKS > Clusters**.
+- In GitLab: On the left sidebar, select **Infrastructure > Kubernetes clusters**.
+
+## Use your cluster
+
+After you provision the cluster, it is connected to GitLab and is ready for deployments. To check the connection:
+
+1. On the left sidebar, select **Infrastructure > Kubernetes clusters**.
+1. In the list, view the **Connection status** column.
+
+For more information about the capabilities of the connection, see [the GitLab agent for Kubernetes documentation](../index.md).
+
+## Remove the cluster
+
+A cleanup job is not included in your pipeline by default. To remove all created resources, you
+must modify your GitLab CI/CD template before running the cleanup job.
+
+To remove all resources:
+
+1. Add the following to your `.gitlab-ci.yml` file:
+
+ ```yaml
+ stages:
+ - init
+ - validate
+ - build
+ - deploy
+ - cleanup
+
+ destroy:
+ extends: .destroy
+ needs: []
+ ```
+
+1. On the left sidebar, select **CI/CD > Pipelines** and select the most recent pipeline.
+1. For the `destroy` job, select **Play** (**{play}**).
diff --git a/doc/user/infrastructure/clusters/connect/new_gke_cluster.md b/doc/user/infrastructure/clusters/connect/new_gke_cluster.md
index d1e3bd47b89..1ed8b0ef350 100644
--- a/doc/user/infrastructure/clusters/connect/new_gke_cluster.md
+++ b/doc/user/infrastructure/clusters/connect/new_gke_cluster.md
@@ -4,65 +4,59 @@ group: Configure
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
-# New GKE cluster through IaC (DEPRECATED)
-
-> [Deprecated](https://gitlab.com/groups/gitlab-org/configure/-/epics/8) in GitLab 14.5.
-
-WARNING:
-The process described on this page uses cluster certificates to connect the
-new cluster to GitLab, [deprecated](https://gitlab.com/groups/gitlab-org/configure/-/epics/8) in GitLab 14.5.
-You can still create a cluster and then connect it to GitLab through the [Agent](../index.md).
-[An issue exists](https://gitlab.com/gitlab-org/gitlab/-/issues/343660)
-to migrate this functionality to the [Agent](../index.md).
+# Create a Google GKE cluster
Learn how to create a new cluster on Google Kubernetes Engine (GKE) through
-[Infrastructure as Code (IaC)](../../index.md).
-
-This process combines the GitLab Terraform and Google Terraform providers
-with Kubernetes to help you create GKE clusters and deploy them through
-GitLab.
-
-This document describes how to set up a [group-level cluster](../../../group/clusters/index.md) on GKE by importing an example project to get you started.
-You can then modify the project files according to your needs.
+[Infrastructure as Code (IaC)](../../index.md). This process uses the Google
+and Kubernetes Terraform providers create GKE clusters. You connect the clusters to GitLab
+by using the GitLab agent for Kubernetes.
**Prerequisites:**
-- A GitLab group.
-- A GitLab user with the Maintainer role in the group.
-- A [GitLab personal access token](../../../profile/personal_access_tokens.md) with `api` access, created by a user with at least the Maintainer role in the group.
- A [Google Cloud Platform (GCP) service account](https://cloud.google.com/docs/authentication/getting-started).
+- [A runner](https://docs.gitlab.com/runner/install/) you can use to run the GitLab CI/CD pipeline.
**Steps:**
1. [Import the example project](#import-the-example-project).
-1. [Create your GCP and GitLab credentials](#create-your-gcp-and-gitlab-credentials).
+1. [Register the agent for Kubernetes](#register-the-agent).
+1. [Create your GCP credentials](#create-your-gcp-credentials).
1. [Configure your project](#configure-your-project).
-1. [Deploy your cluster](#deploy-your-cluster).
+1. [Provision your cluster](#provision-your-cluster).
## Import the example project
-To create a new group-level cluster from GitLab using Infrastructure as Code, it is necessary
-to create a project to manage the cluster from. In this tutorial, we import a pre-configured
-sample project to help you get started.
+To create a cluster from GitLab using Infrastructure as Code, you must
+create a project to manage the cluster from. In this tutorial, you start with
+a sample project and modify it according to your needs.
-Start by [importing the example project by URL](../../../project/import/repo_by_url.md). Use `https://gitlab.com/gitlab-org/configure/examples/gitlab-terraform-gke.git` as URL.
+Start by [importing the example project by URL](../../../project/import/repo_by_url.md).
-This project provides you with the following resources:
+To import the project:
+
+1. On the top bar, select **Menu > Create new project**.
+1. Select **Import project**.
+1. Select **Repo by URL**.
+1. For the **Git repository URL**, enter `https://gitlab.com/gitlab-org/configure/examples/gitlab-terraform-gke.git`.
+1. Complete the fields and select **Create project**.
+
+This project provides you with:
- A [cluster on Google Cloud Platform (GCP)](https://gitlab.com/gitlab-org/configure/examples/gitlab-terraform-gke/-/blob/master/gke.tf)
with defaults for name, location, node count, and Kubernetes version.
-- A [`gitlab-admin` K8s service account](https://gitlab.com/gitlab-org/configure/examples/gitlab-terraform-gke/-/blob/master/gitlab-admin.tf) with `cluster-admin` privileges.
-- The new group-level cluster connected to GitLab.
-- Pre-configures Terraform files:
-
- ```plaintext
- ├── backend.tf # State file Location Configuration
- ├── gke.tf # Google GKE Configuration
- ├── gitlab-admin.tf # Adding kubernetes service account
- └── group_cluster.tf # Registering kubernetes cluster to GitLab `apps` Group
- ```
+- The [GitLab agent for Kubernetes](https://gitlab.com/gitlab-org/configure/examples/gitlab-terraform-gke/-/blob/master/agent.tf) installed in the cluster.
-## Create your GCP and GitLab credentials
+## Register the agent
+
+To create a GitLab agent for Kubernetes:
+
+1. On the left sidebar, select **Infrastructure > Kubernetes clusters**.
+1. Select **Actions**.
+1. From the **Select an agent** dropdown list, select `gke-agent` and select **Register an agent**.
+1. GitLab generates a registration token for the agent. Securely store this secret token, as you will need it later.
+1. GitLab provides an address for the agent server (KAS), which you will also need later.
+
+## Create your GCP credentials
To set up your project to communicate to GCP and the GitLab API:
@@ -85,18 +79,14 @@ The Admin role creates a service account in the `kube-system` namespace.
## Configure your project
-**Required configuration:**
-
-Use CI/CD environment variables to configure your project as detailed below.
+Use CI/CD environment variables to configure your project.
**Required configuration:**
1. On the left sidebar, select **Settings > CI/CD**.
1. Expand **Variables**.
-1. Set the variable `TF_VAR_gitlab_token` to the GitLab personal access token you just created.
1. Set the variable `BASE64_GOOGLE_CREDENTIALS` to the `base64` encoded JSON file you just created.
1. Set the variable `TF_VAR_gcp_project` to your GCP's `project` name.
-1. Set the variable `TF_VAR_gitlab_group` to the name of the group you want to connect your cluster to. If your group's URL is `https://gitlab.example.com/my-example-group`, `my-example-group` is your group's name.
**Optional configuration:**
@@ -105,22 +95,57 @@ contains other variables that you can override according to your needs:
- `TF_VAR_gcp_region`: Set your cluster's region.
- `TF_VAR_cluster_name`: Set your cluster's name.
-- `TF_VAR_machine_type`: Set the machine type for the Kubernetes nodes.
- `TF_VAR_cluster_description`: Set a description for the cluster. We recommend setting this to `$CI_PROJECT_URL` to create a reference to your GitLab project on your GCP cluster detail page. This way you know which project was responsible for provisioning the cluster you see on the GCP dashboard.
-- `TF_VAR_base_domain`: Set to the base domain to provision resources under.
-- `TF_VAR_environment_scope`: Set to the environment scope for your cluster.
+- `TF_VAR_machine_type`: Set the machine type for the Kubernetes nodes.
+- `TF_VAR_node_count`: Set the number of Kubernetes nodes.
+- `TF_VAR_agent_version`: Set the version of the GitLab agent.
+- `TF_VAR_agent_namespace`: Set the Kubernetes namespace for the GitLab agent.
-Refer to the [GitLab Terraform provider](https://registry.terraform.io/providers/gitlabhq/gitlab/latest/docs) and the [Google Terraform provider](https://registry.terraform.io/providers/hashicorp/google/latest/docs/guides/provider_reference) documentation for further resource options.
+Refer to the [Google Terraform provider](https://registry.terraform.io/providers/hashicorp/google/latest/docs/guides/provider_reference) and the [Kubernetes Terraform provider](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs) documentation for further resource options.
-## Deploy your cluster
+## Provision your cluster
-After configuring your project, manually trigger the deployment of your cluster. In GitLab:
+After configuring your project, manually trigger the provisioning of your cluster. In GitLab:
-1. From your project's sidebar, go to **CI/CD > Pipelines**.
-1. Select the dropdown icon (**{angle-down}**) next to the play icon (**{play}**).
-1. Select **deploy** to manually trigger the deployment job.
+1. On the left sidebar, go to **CI/CD > Pipelines**.
+1. Next to **Play** (**{play}**), select the dropdown icon (**{angle-down}**).
+1. Select **Deploy** to manually trigger the deployment job.
When the pipeline finishes successfully, you can see your new cluster:
- In GCP: on your [GCP console's Kubernetes list](https://console.cloud.google.com/kubernetes/list).
- In GitLab: from your project's sidebar, select **Infrastructure > Kubernetes clusters**.
+
+## Use your cluster
+
+After you provision the cluster, it is connected to GitLab and is ready for deployments. To check the connection:
+
+1. On the left sidebar, select **Infrastructure > Kubernetes clusters**.
+1. In the list, view the **Connection status** column.
+
+For more information about the capabilities of the connection, see [the GitLab agent for Kubernetes documentation](../index.md).
+
+## Remove the cluster
+
+A cleanup job is not included in your pipeline by default. To remove all created resources, you
+must modify your GitLab CI/CD template before running the cleanup job.
+
+To remove all resources:
+
+1. Add the following to your `.gitlab-ci.yml` file:
+
+ ```yaml
+ stages:
+ - init
+ - validate
+ - build
+ - deploy
+ - cleanup
+
+ destroy:
+ extends: .destroy
+ needs: []
+ ```
+
+1. On the left sidebar, select **CI/CD > Pipelines** and select the most recent pipeline.
+1. For the `destroy` job, select **Play** (**{play}**).
diff --git a/doc/user/infrastructure/clusters/deploy/inventory_object.md b/doc/user/infrastructure/clusters/deploy/inventory_object.md
index 47063dcae96..d76ef0b9359 100644
--- a/doc/user/infrastructure/clusters/deploy/inventory_object.md
+++ b/doc/user/infrastructure/clusters/deploy/inventory_object.md
@@ -4,66 +4,74 @@ group: Configure
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
-# Inventory object **(PREMIUM)**
+# Tracking cluster resources managed by GitLab **(PREMIUM)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/332227) in GitLab 14.0.
-An inventory object is a `ConfigMap` object for keeping track of the set of objects applied to a cluster.
-When you remove objects from a manifest repository, the Agent uses a corresponding inventory object to
-prune (delete) objects from the cluster.
+GitLab uses an inventory object to track the resources you deploy to your cluster.
+The inventory object is a `ConfigMap` that contains a list of controlled objects.
+The managed resources use the `cli-utils.sigs.k8s.io/inventory-id` annotation.
-The Agent creates an inventory object for each manifest project specified in the
-`gitops.manifest_projects` configuration section. The inventory object has to be stored somewhere in the cluster.
-The default behavior is:
+## Default location of the inventory object
-- The `namespace` used comes from `gitops.manifest_projects[].default_namespace`. If you don't specify this parameter
- explicitly, the inventory object is stored in the `default` namespace.
-- The `name` is generated from the numeric project ID of the manifest project and the numeric agent ID.
+In the agent configuration file, you specify a list of projects. For example:
- This way the Agent constructs the name and local where the inventory object is
- stored in the cluster.
+```yaml
+gitops:
+ manifest_projects:
+ - id: gitlab-org/cluster-integration/gitlab-agent
+ default_namespace: my-ns
+```
-The Agent cannot locate the existing inventory object if you:
+The agent creates an inventory object for every item in the `manifest_projects` list.
+The inventory object is stored in the namespace you specify for `default_namespace`.
-- Change `gitops.manifest_projects[].default_namespace` parameter.
-- Move manifests into another project.
+The name and location of the inventory object is based on:
-## Inventory object template
+- The `default_namespace`. If you don't specify this parameter,
+ the inventory object is stored in the `default` namespace.
+- The `name`, which is the ID of the project with the manifest and the ID of the agent.
-The inventory object template is a `ConfigMap` object that allows you to configure the namespace and the name of the inventory
-object. Store this template with manifest files in a single group.
+WARNING:
+The agent cannot locate the existing inventory object if you change
+the `default_namespace` parameter or move manifests to another project.
-Example inventory object template:
+## Change the location of the inventory object
-```yaml
-apiVersion: v1
-kind: ConfigMap
-metadata:
- name: unique-name-for-the-inventory
- namespace: my-project-namespace
- labels:
- cli-utils.sigs.k8s.io/inventory-id: unique-name-for-the-inventory
-```
+You can configure the namespace and the name of the inventory object.
+This action changes the location of the object in the cluster.
+
+1. Create an inventory object template, which is a `ConfigMap` object.
+ For example:
+
+ ```yaml
+ apiVersion: v1
+ kind: ConfigMap
+ metadata:
+ name: unique-name-for-the-inventory
+ namespace: my-project-namespace
+ labels:
+ cli-utils.sigs.k8s.io/inventory-id: unique-name-for-the-inventory
+ ```
+
+1. Specify a `namespace` and `name`. Ensure that the `name` is unique so it doesn't conflict with other
+ inventory objects in the same namespace in the future.
+1. Ensure the value for `cli-utils.sigs.k8s.io/inventory-id` is unique. This value is used for objects
+ tracked by this inventory object. Their `config.k8s.io/owning-inventory` annotation is set to this value.
+
+ The value doesn't have to match the `name` but it's convenient to set them to the same value.
+
+1. Save the file with the manifest files as a single logical group.
-- The `namespace` and `name` fields configure where the real inventory object is created.
-- The `cli-utils.sigs.k8s.io/inventory-id` label with its corresponding value is set on the inventory object, created
- from this template. Make sure that the value is unique (for example, a string of random characters) and doesn't clash
- with any existing or future inventory object templates.
-- Objects tracked by this inventory object have the `config.k8s.io/owning-inventory` annotation set to the value of
- the `cli-utils.sigs.k8s.io/inventory-id` label.
-- The label's value doesn't have to match the `name` but it's convenient to have them set to the same value.
-- Make sure that the `name` is unique so that it doesn't conflict with another inventory object in the same
- namespace in the future.
+## `inventory_policy` options
-## Using GitOps with pre-existing Kubernetes objects
+Sometimes your manifest changes affect resources that aren't tracked by the GitLab inventory object.
-The Agent treats manifest files in the manifest repository as the source of truth. When it applies
-objects from the files to the cluster, it tracks them in an inventory object. If an object already exists,
-The Agent behaves differently based on the `gitops.manifest_projects[].inventory_policy` configuration.
-Check the table below with the available options and when to use them.
+To change how the agent behaves when it overwrites existing and previously untracked resources,
+change the `inventory_policy` value.
`inventory_policy` value | Description |
------------------------ | ------------------------------------------------------------------------------------------- |
-`must_match` | This is the default policy. A live object must have the `config.k8s.io/owning-inventory` annotation set to the same value as the `cli-utils.sigs.k8s.io/inventory-id` label on the corresponding inventory object to be updated. Object is not updated and an error is reported if the values don't match or the object doesn't have the annotation. |
-`adopt_if_no_inventory` | This mode allows to "adopt" an object if it doesn't have the `config.k8s.io/owning-inventory` annotation. Use this mode if you want to start managing existing objects using the GitOps feature. Once all objects have been "adopted", we recommend you to put the setting back into the default `must_match` mode to avoid any unexpected adoptions. |
-`adopt_all` | This mode allows to "adopt" an object even if it has the `config.k8s.io/owning-inventory` annotation set to a different value. This mode can be useful if you want to migrate a set of objects from one agent to another one or from some other tool to the Agent. Once all objects have been "adopted", we recommend you to put the setting back into the default `must_match` mode to avoid any unexpected adoptions. |
+`must_match` | The default policy. To be updated, a live object must have the `config.k8s.io/owning-inventory` annotation set to the same value as the `cli-utils.sigs.k8s.io/inventory-id` label on the corresponding inventory object. If the values don't match or the object doesn't have the annotation, the object is not updated and an error is reported. |
+`adopt_if_no_inventory` | Adopt an object if it doesn't have the `config.k8s.io/owning-inventory` annotation. Use this mode if you want to start managing existing objects by using the GitOps feature. To avoid unexpected adoptions, after all objects have been adopted, put the setting back to the default `must_match` mode. |
+`adopt_all` | Adopt an object even if it has the `config.k8s.io/owning-inventory` annotation set to a different value. Use this mode if you want to migrate a set of objects from one agent to another, or from some other tool to the agent. To avoid unexpected adoptions, after all objects have been adopted, put the setting back to the default `must_match` mode. |
diff --git a/doc/user/infrastructure/clusters/index.md b/doc/user/infrastructure/clusters/index.md
index 144a8cd2d31..cd7c5feb284 100644
--- a/doc/user/infrastructure/clusters/index.md
+++ b/doc/user/infrastructure/clusters/index.md
@@ -6,7 +6,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Kubernetes clusters **(FREE)**
-To connect clusters to GitLab, use the [GitLab Agent](../../clusters/agent/index.md).
+To connect clusters to GitLab, use the [GitLab agent](../../clusters/agent/index.md).
## Certificate-based Kubernetes integration (DEPRECATED)
@@ -24,7 +24,7 @@ It had the following issues:
- Users were constantly reporting issues with features based on this model.
For this reason, we started to build features based on a new model, the
-[GitLab Agent](../../clusters/agent/index.md).
+[GitLab agent](../../clusters/agent/index.md).
Maintaining both methods in parallel caused a lot of confusion
and significantly increased the complexity to use, develop, maintain, and
document them. For this reason, we decided to deprecate them to focus on the
@@ -38,7 +38,7 @@ Follow this [epic](https://gitlab.com/groups/gitlab-org/configure/-/epics/8)
for updates.
You can find technical information about why we moved away from cluster certificates into
-the GitLab Agent model on the [Agent's blueprint documentation](../../../architecture/blueprints/gitlab_to_kubernetes_communication/index.md).
+the GitLab agent model on the [agent's blueprint documentation](../../../architecture/blueprints/gitlab_to_kubernetes_communication/index.md).
## Deprecated features
@@ -67,6 +67,5 @@ The concept of [project-level](../../project/clusters/index.md),
[instance-level](../../instance/clusters/index.md) clusters becomes
extinct in the new model, although the functionality remains to some extent.
-The Agent is always configured in a single GitLab project, but you can use the CI/CD Tunnel to
-[authorize other projects and groups to use the same Agent](../../clusters/agent/repository.md#authorize-projects-and-groups-to-use-an-agent).
+The agent is always configured in a single GitLab project and you can expose the cluster connection to other projects and groups to [access it from GitLab CI/CD](../../clusters/agent/ci_cd_tunnel.md).
By doing so, you are granting these projects and groups access to the same cluster, which is similar to group-level clusters' use case.
diff --git a/doc/user/infrastructure/clusters/manage/management_project_applications/runner.md b/doc/user/infrastructure/clusters/manage/management_project_applications/runner.md
index 841f2af7863..4faf5f46418 100644
--- a/doc/user/infrastructure/clusters/manage/management_project_applications/runner.md
+++ b/doc/user/infrastructure/clusters/manage/management_project_applications/runner.md
@@ -4,7 +4,7 @@ group: Runner
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
-# Install GitLab Runner with a cluster management project
+# Install GitLab Runner with a cluster management project **(FREE)**
> [Introduced](https://gitlab.com/gitlab-org/project-templates/cluster-management/-/merge_requests/5) in GitLab 14.0.
diff --git a/doc/user/infrastructure/clusters/migrate_to_gitlab_agent.md b/doc/user/infrastructure/clusters/migrate_to_gitlab_agent.md
index 1dd1c760bcc..01530422e4a 100644
--- a/doc/user/infrastructure/clusters/migrate_to_gitlab_agent.md
+++ b/doc/user/infrastructure/clusters/migrate_to_gitlab_agent.md
@@ -4,85 +4,78 @@ group: Configure
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
-# Migrate to the GitLab Agent for Kubernetes **(FREE)**
+# Migrate to the GitLab agent for Kubernetes **(FREE)**
-The first integration between GitLab and Kubernetes used cluster certificates
-to connect the cluster to GitLab.
-This method was [deprecated](https://about.gitlab.com/blog/2021/11/15/deprecating-the-cert-based-kubernetes-integration/)
-in GitLab 14.5 in favor of the [GitLab Agent for Kubernetes](../../clusters/agent/index.md).
+To connect your Kubernetes cluster with GitLab, you can use:
-To make sure your clusters connected to GitLab do not break in the future,
-we recommend you migrate to the GitLab Agent as soon as possible by following
-the processes described in this document.
+- [A GitOps workflow](../../clusters/agent/gitops.md).
+- [A GitLab CI/CD workflow](../../clusters/agent/ci_cd_tunnel.md).
+- [A certificate-based integration](index.md).
-The certificate-based integration was used for some popular GitLab features such as,
-GitLab Managed Apps, GitLab-managed clusters, and Auto DevOps.
+The certificate-based integration is
+[**deprecated**](https://about.gitlab.com/blog/2021/11/15/deprecating-the-cert-based-kubernetes-integration/)
+in GitLab 14.5. It is expected to be
+[turned off by default in 15.0](../../../update/deprecations.md#certificate-based-integration-with-kubernetes)
+and removed in GitLab 15.6.
+
+If you are using the certificate-based integration, you should move to another workflow as soon as possible.
-As a general rule, migrating clusters that rely on GitLab CI/CD can be
-achieved using the [CI/CD Tunnel](../../clusters/agent/ci_cd_tunnel.md)
-provided by the Agent.
+As a general rule, to migrate clusters that rely on GitLab CI/CD,
+you can use the [CI/CD workflow](../../clusters/agent/ci_cd_tunnel.md).
+This workflow uses an agent to connect to your cluster. The agent:
+
+- Is not exposed to the internet.
+- Does not require full cluster-admin access to GitLab.
NOTE:
-The GitLab Agent for Kubernetes does not intend to provide feature parity with the
-certificate-based cluster integrations. As a result, the Agent doesn't support
-all the features available to clusters connected through certificates.
+The certificate-based integration was used for popular GitLab features like
+GitLab Managed Apps, GitLab-managed clusters, and Auto DevOps.
+Some features are currently available only when using certificate-based integration.
## Migrate cluster application deployments
### Migrate from GitLab-managed clusters
With GitLab-managed clusters, GitLab creates separate service accounts and namespaces
-for every branch and deploys using these resources.
+for every branch and deploys by using these resources.
-To achieve a similar result with the GitLab Agent, you can use [impersonation](../../clusters/agent/repository.md#use-impersonation-to-restrict-project-and-group-access)
+The GitLab agent uses [impersonation](../../clusters/agent/ci_cd_tunnel.md#use-impersonation-to-restrict-project-and-group-access)
strategies to deploy to your cluster with restricted account access. To do so:
1. Choose the impersonation strategy that suits your needs.
1. Use Kubernetes RBAC rules to manage impersonated account permissions in Kubernetes.
-1. Use the `access_as` attribute in your Agent’s configuration file to define the impersonation.
+1. Use the `access_as` attribute in your agent configuration file to define the impersonation.
### Migrate from Auto DevOps
-To configure your Auto DevOps project to use the GitLab Agent:
+To configure your Auto DevOps project to use the GitLab agent:
-1. Follow the steps to [install an agent](../../clusters/agent/install/index.md) on your cluster.
-1. Go to the project in which you use Auto DevOps.
-1. From the sidebar, select **Settings > CI/CD** and expand **Variables**.
+1. Follow the steps to [install an agent](../../clusters/agent/install/index.md) in your cluster.
+1. Go to the project where you use Auto DevOps.
+1. On the left sidebar, select **Settings > CI/CD** and expand **Variables**.
1. Select **Add new variable**.
1. Add `KUBE_CONTEXT` as the key, `path/to/agent/project:agent-name` as the value, and select the environment scope of your choice.
1. Select **Add variable**.
1. Repeat the process to add another variable, `KUBE_NAMESPACE`, setting the value for the Kubernetes namespace you want your deployments to target, and set the same environment scope from the previous step.
-1. From the sidebar, select **Infrastructure > Kubernetes clusters**.
+1. On the left sidebar, select **Infrastructure > Kubernetes clusters**.
1. From the certificate-based clusters section, open the cluster that serves the same environment scope.
1. Select the **Details** tab and disable the cluster.
-1. To activate the changes, from the project's sidebar, select **CI/CD > Variables > Run pipeline**.
+1. To activate the changes, on the left sidebar, select **CI/CD > Variables > Run pipeline**.
-### Migrate generic deployments
-
-When you use Kubernetes contexts to reach the cluster from GitLab, you can use the [CI/CD Tunnel](../../clusters/agent/ci_cd_tunnel.md)
-directly. It injects the available contexts into your CI environment automatically:
+For an example, [view this project](https://gitlab.com/gitlab-examples/ops/gitops-demo/hello-world-service).
-1. Follow the steps to [install an agent](../../clusters/agent/install/index.md) on your cluster.
-1. Go to the project in which you use Auto DevOps.
-1. From the sidebar, select **Settings > CI/CD** and expand **Variables**.
-1. Select **Add new variable**.
-1. Add `KUBE_CONTEXT` as the key, `path/to/agent-configuration-project:your-agent-name` as the value, and select the environment scope of your choice.
-1. Edit your `.gitlab-ci.yml` file and set the Kubernetes context to the `KUBE_CONTEXT` you defined in the previous step:
+### Migrate generic deployments
- ```yaml
- <your job name>:
- script:
- - kubectl config use-context $KUBE_CONTEXT
- ```
+Follow the process for the [CI/CD workflow](../../clusters/agent/ci_cd_tunnel.md).
-## Migrate from GitLab Managed Applications
+## Migrate from GitLab Managed applications
-Follow the process to [migrate from GitLab Managed Apps to the Cluster Management Project](../../clusters/migrating_from_gma_to_project_template.md).
+Follow the process to [migrate from GitLab Managed Apps to the cluster management project](../../clusters/migrating_from_gma_to_project_template.md).
-## Migrating a Cluster Management project
+## Migrate a cluster management project
-See [how to use a cluster management project with the GitLab Agent](../../clusters/management_project_template.md#use-the-agent-with-the-cluster-management-project-template).
+See [how to use a cluster management project with the GitLab agent](../../clusters/management_project_template.md).
## Migrate cluster monitoring features
-Cluster monitoring features are not supported by the GitLab Agent for Kubernetes yet.
+Cluster monitoring features are not yet supported by the GitLab agent for Kubernetes.
diff --git a/doc/user/infrastructure/iac/index.md b/doc/user/infrastructure/iac/index.md
index 6fef1aa7879..3bc7495d4be 100644
--- a/doc/user/infrastructure/iac/index.md
+++ b/doc/user/infrastructure/iac/index.md
@@ -60,9 +60,9 @@ This video from January 2021 walks you through all the GitLab Terraform integrat
## GitLab-managed Terraform state
-[Terraform remote backends](https://www.terraform.io/docs/language/settings/backends/index.html)
+[Terraform remote backends](https://www.terraform.io/language/settings/backends)
enable you to store the state file in a remote, shared store. GitLab uses the
-[Terraform HTTP backend](https://www.terraform.io/docs/language/settings/backends/http.html)
+[Terraform HTTP backend](https://www.terraform.io/language/settings/backends/http)
to securely store the state files in local storage (the default) or
[the remote store of your choice](../../../administration/terraform_state.md).
@@ -105,16 +105,10 @@ owned by GitLab, where everyone can contribute.
The [documentation of the provider](https://registry.terraform.io/providers/gitlabhq/gitlab/latest/docs)
is available as part of the official Terraform provider documentation.
-## Create a new cluster through IaC (DEPRECATED)
+## Create a new cluster through IaC
-Learn how to [create a new cluster on Google Kubernetes Engine (GKE)](../clusters/connect/new_gke_cluster.md).
-
-NOTE:
-The linked tutorial connects the cluster to GitLab through cluster certificates,
-and this method was [deprecated](https://gitlab.com/groups/gitlab-org/configure/-/epics/8)
-in GitLab 14.5. You can still create a cluster through IaC and then connect it to GitLab
-through the [agent](../../clusters/agent/index.md), the default and fully supported
-method to connect clusters to GitLab.
+- Learn how to [create a new cluster on Amazon Elastic Kubernetes Service (EKS)](../clusters/connect/new_eks_cluster.md).
+- Learn how to [create a new cluster on Google Kubernetes Engine (GKE)](../clusters/connect/new_gke_cluster.md).
## Troubleshooting
diff --git a/doc/user/infrastructure/iac/mr_integration.md b/doc/user/infrastructure/iac/mr_integration.md
index 8c135f18bc1..bcad5c9279a 100644
--- a/doc/user/infrastructure/iac/mr_integration.md
+++ b/doc/user/infrastructure/iac/mr_integration.md
@@ -151,8 +151,8 @@ apply:
### Multiple Terraform Plan reports
-Starting with GitLab version 13.2, you can display multiple reports on a merge request.
-The reports also display the `artifacts: name:`. See example below for a suggested setup.
+Starting with GitLab version 13.2, you can display multiple reports on the merge request
+page. The reports also display the `artifacts: name:`. See example below for a suggested setup.
```yaml
default:
diff --git a/doc/user/infrastructure/iac/terraform_state.md b/doc/user/infrastructure/iac/terraform_state.md
index 8fd38215b04..39a57b60787 100644
--- a/doc/user/infrastructure/iac/terraform_state.md
+++ b/doc/user/infrastructure/iac/terraform_state.md
@@ -8,9 +8,9 @@ info: To determine the technical writer assigned to the Stage/Group associated w
> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/2673) in GitLab 13.0.
-[Terraform remote backends](https://www.terraform.io/docs/language/settings/backends/index.html)
+[Terraform remote backends](https://www.terraform.io/language/settings/backends)
enable you to store the state file in a remote, shared store. GitLab uses the
-[Terraform HTTP backend](https://www.terraform.io/docs/language/settings/backends/http.html)
+[Terraform HTTP backend](https://www.terraform.io/language/settings/backends/http)
to securely store the state files in local storage (the default) or
[the remote store of your choice](../../../administration/terraform_state.md).
@@ -222,9 +222,9 @@ See [this reference project](https://gitlab.com/gitlab-org/configure/examples/gi
## Using a GitLab-managed Terraform state backend as a remote data source
You can use a GitLab-managed Terraform state as a
-[Terraform data source](https://www.terraform.io/docs/language/state/remote-state-data.html).
+[Terraform data source](https://www.terraform.io/language/state/remote-state-data).
To use your existing Terraform state backend as a data source, provide the following details
-as [Terraform input variables](https://www.terraform.io/docs/language/values/variables.html):
+as [Terraform input variables](https://www.terraform.io/language/values/variables):
- **address**: The URL of the remote state backend you want to use as a data source.
For example, `https://gitlab.com/api/v4/projects/<TARGET-PROJECT-ID>/terraform/state/<TARGET-STATE-NAME>`.
diff --git a/doc/user/infrastructure/index.md b/doc/user/infrastructure/index.md
index d8e75928675..73e57ea3d59 100644
--- a/doc/user/infrastructure/index.md
+++ b/doc/user/infrastructure/index.md
@@ -30,11 +30,11 @@ Learn more about how GitLab can help you run [Infrastructure as Code](iac/index.
## Integrated Kubernetes management
The GitLab integration with Kubernetes helps you to install, configure, manage, deploy, and troubleshoot
-cluster applications. With the GitLab Agent, you can connect clusters behind a firewall,
+cluster applications. With the GitLab agent, you can connect clusters behind a firewall,
have real-time access to API endpoints, perform pull-based or push-based deployments for production
and non-production environments, and much more.
-Learn more about the [GitLab Agent](../clusters/agent/index.md).
+Learn more about the [GitLab agent](../clusters/agent/index.md).
## Runbooks in GitLab
diff --git a/doc/user/instance/clusters/index.md b/doc/user/instance/clusters/index.md
index a184f00f6f6..a5c1402b9ec 100644
--- a/doc/user/instance/clusters/index.md
+++ b/doc/user/instance/clusters/index.md
@@ -11,7 +11,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
WARNING:
This feature was [deprecated](https://gitlab.com/groups/gitlab-org/configure/-/epics/8) in GitLab 14.5. To connect clusters to GitLab,
-use the [GitLab Agent](../../clusters/agent/index.md).
+use the [GitLab agent](../../clusters/agent/index.md).
Similar to [project-level](../../project/clusters/index.md)
and [group-level](../../group/clusters/index.md) Kubernetes clusters,
diff --git a/doc/user/markdown.md b/doc/user/markdown.md
index a16f8fd39b1..c81fdc275d9 100644
--- a/doc/user/markdown.md
+++ b/doc/user/markdown.md
@@ -30,7 +30,7 @@ and the [main GitLab website](https://about.gitlab.com) use [Kramdown](https://k
You should not view this page in the documentation, but instead [view these styles as they appear on GitLab](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/user/markdown.md).
GitLab Flavored Markdown extends the [CommonMark specification](https://spec.commonmark.org/current/).
-It was inspired by [GitHub Flavored Markdown](https://docs.github.com/en/github/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax).
+It was inspired by [GitHub Flavored Markdown](https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax).
## Where you can use GitLab Flavored Markdown
@@ -67,15 +67,15 @@ Features not found in standard Markdown:
Features [extended from standard Markdown](#features-extended-from-standard-markdown):
-| Standard Markdown | Extended Markdown in GitLab |
-| ------------------------------------- | ------------------------- |
-| [blockquotes](#blockquotes) | [multi-line blockquotes](#multiline-blockquote) |
-| [code blocks](#code-spans-and-blocks) | [colored code and syntax highlighting](#colored-code-and-syntax-highlighting) |
-| [emphasis](#emphasis) | [multiple underscores in words](#multiple-underscores-in-words-and-mid-word-emphasis)
-| [headers](#headers) | [linkable Header IDs](#header-ids-and-links) |
-| [images](#images) | [embedded videos](#videos) and [audio](#audio) |
-| [line breaks](#line-breaks) | [more line break control](#newlines) |
-| [links](#links) | [automatically linking URLs](#url-auto-linking) |
+| Standard Markdown | Extended Markdown in GitLab |
+|---------------------------------------|---------------------------------------------------------------------------------------|
+| [blockquotes](#blockquotes) | [multi-line blockquotes](#multiline-blockquote) |
+| [code blocks](#code-spans-and-blocks) | [colored code and syntax highlighting](#colored-code-and-syntax-highlighting) |
+| [emphasis](#emphasis) | [multiple underscores in words](#multiple-underscores-in-words-and-mid-word-emphasis) |
+| [headers](#headers) | [linkable Header IDs](#header-ids-and-links) |
+| [images](#images) | [embedded videos](#videos) and [audio](#audio) |
+| [line breaks](#line-breaks) | [more line break control](#newlines) |
+| [links](#links) | [automatically linking URLs](#url-auto-linking) |
## Features not found in standard Markdown
@@ -262,7 +262,7 @@ The following delimiters are supported:
---
title: About Front Matter
example:
- language: yaml
+ language: yaml
---
```
@@ -515,31 +515,31 @@ version to reference other projects from the same namespace.
GitLab Flavored Markdown recognizes the following:
-| references | input | cross-project reference | shortcut inside same namespace |
-| :--------------------------------------------------- | :---------------------------- | :----------------------------------------- | :------------------------------- |
-| specific user | `@user_name` | | |
-| specific group | `@group_name` | | |
-| entire team | `@all` | | |
-| project | `namespace/project>` | | |
-| issue | ``#123`` | `namespace/project#123` | `project#123` |
-| merge request | `!123` | `namespace/project!123` | `project!123` |
-| snippet | `$123` | `namespace/project$123` | `project$123` |
-| [epic](group/epics/index.md) | `&123` | `group1/subgroup&123` | |
-| vulnerability **(ULTIMATE)** <sup>1</sup> | `[vulnerability:123]` | `[vulnerability:namespace/project/123]` | `[vulnerability:project/123]` |
-| feature flag | `[feature_flag:123]` | `[feature_flag:namespace/project/123]` | `[feature_flag:project/123]` |
-| label by ID | `~123` | `namespace/project~123` | `project~123` |
-| one-word label by name | `~bug` | `namespace/project~bug` | `project~bug` |
-| multi-word label by name | `~"feature request"` | `namespace/project~"feature request"` | `project~"feature request"` |
-| scoped label by name | `~"priority::high"` | `namespace/project~"priority::high"` | `project~"priority::high"` |
-| project milestone by ID | `%123` | `namespace/project%123` | `project%123` |
-| one-word milestone by name | `%v1.23` | `namespace/project%v1.23` | `project%v1.23` |
-| multi-word milestone by name | `%"release candidate"` | `namespace/project%"release candidate"` | `project%"release candidate"` |
-| specific commit | `9ba12248` | `namespace/project@9ba12248` | `project@9ba12248` |
-| commit range comparison | `9ba12248...b19a04f5` | `namespace/project@9ba12248...b19a04f5` | `project@9ba12248...b19a04f5` |
-| repository file references | `[README](doc/README.md)` | | |
-| repository file line references | `[README](doc/README.md#L13)` | | |
-| [alert](../operations/incident_management/alerts.md) | `^alert#123` | `namespace/project^alert#123` | `project^alert#123` |
-| contact | `[contact:test@example.com]` | | |
+| references | input | cross-project reference | shortcut inside same namespace |
+|:----------------------------------------------------------------------------|:------------------------------|:----------------------------------------|:-------------------------------|
+| specific user | `@user_name` | | |
+| specific group | `@group_name` | | |
+| entire team | `@all` | | |
+| project | `namespace/project>` | | |
+| issue | ``#123`` | `namespace/project#123` | `project#123` |
+| merge request | `!123` | `namespace/project!123` | `project!123` |
+| snippet | `$123` | `namespace/project$123` | `project$123` |
+| [epic](group/epics/index.md) | `&123` | `group1/subgroup&123` | |
+| [vulnerability](application_security/vulnerabilities/index.md) <sup>1</sup> | `[vulnerability:123]` | `[vulnerability:namespace/project/123]` | `[vulnerability:project/123]` |
+| feature flag | `[feature_flag:123]` | `[feature_flag:namespace/project/123]` | `[feature_flag:project/123]` |
+| label by ID | `~123` | `namespace/project~123` | `project~123` |
+| one-word label by name | `~bug` | `namespace/project~bug` | `project~bug` |
+| multi-word label by name | `~"feature request"` | `namespace/project~"feature request"` | `project~"feature request"` |
+| scoped label by name | `~"priority::high"` | `namespace/project~"priority::high"` | `project~"priority::high"` |
+| project milestone by ID | `%123` | `namespace/project%123` | `project%123` |
+| one-word milestone by name | `%v1.23` | `namespace/project%v1.23` | `project%v1.23` |
+| multi-word milestone by name | `%"release candidate"` | `namespace/project%"release candidate"` | `project%"release candidate"` |
+| specific commit | `9ba12248` | `namespace/project@9ba12248` | `project@9ba12248` |
+| commit range comparison | `9ba12248...b19a04f5` | `namespace/project@9ba12248...b19a04f5` | `project@9ba12248...b19a04f5` |
+| repository file references | `[README](doc/README.md)` | | |
+| repository file line references | `[README](doc/README.md#L13)` | | |
+| [alert](../operations/incident_management/alerts.md) | `^alert#123` | `namespace/project^alert#123` | `project^alert#123` |
+| contact | `[contact:test@example.com]` | | |
1. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/222483) in GitLab 13.7.
@@ -1486,7 +1486,7 @@ but they do not render properly on `docs.gitlab.com`:
#### 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), GitLab creates a Markdown table when you copy-and-paste
diff --git a/doc/user/packages/composer_repository/index.md b/doc/user/packages/composer_repository/index.md
index 5cfb4278a2c..ea12b225717 100644
--- a/doc/user/packages/composer_repository/index.md
+++ b/doc/user/packages/composer_repository/index.md
@@ -22,6 +22,9 @@ Then, install the packages whenever you need to use them as a dependency.
For documentation of the specific API endpoints that the Composer
client uses, see the [Composer API documentation](../../../api/packages/composer.md).
+Composer v2.0 is recommended. Composer v1.0 is supported, but it has lower performance when working
+in groups with very large numbers of packages.
+
## Create a Composer package
If you do not have a Composer package, create one and check it in to
diff --git a/doc/user/packages/container_registry/index.md b/doc/user/packages/container_registry/index.md
index b28f0cbfb35..5b6c71d4dd2 100644
--- a/doc/user/packages/container_registry/index.md
+++ b/doc/user/packages/container_registry/index.md
@@ -553,13 +553,6 @@ this setting. However, disabling the Container Registry disables all Container R
| Private project with Container Registry visibility <br/> set to **Only Project Members** (UI) or `private` (API) | View Container Registry <br/> and pull images | No | No | Yes |
| Any project with Container Registry `disabled` | All operations on Container Registry | No | No | No |
-## Manifest lists and garbage collection
-
-Manifest lists are commonly used for creating multi-architecture images. If you rely on manifest
-lists, you should tag all the individual manifests referenced by a list in their respective
-repositories, and not just the manifest list itself. This ensures that those manifests aren't
-garbage collected, as long as they have at least one tag pointing to them.
-
## Troubleshooting the GitLab Container Registry
### Docker connection error
@@ -702,3 +695,10 @@ There may be some errors not properly cached. Follow these steps to investigate
Once adjusted, trigger another tag deletion. You should be able to successfully delete tags.
Follow [this issue](https://gitlab.com/gitlab-org/container-registry/-/issues/551) for details.
+
+### Tags temporarily cannot be marked for deletion
+
+GitLab is [migrating to the next generation of the Container Registry](https://gitlab.com/groups/gitlab-org/-/epics/5523).
+During the migration, you may encounter difficulty deleting tags.
+If you encounter an error, it's likely that your image repository is in the process of being migrated.
+Please wait a few minutes and try again.
diff --git a/doc/user/packages/container_registry/reduce_container_registry_storage.md b/doc/user/packages/container_registry/reduce_container_registry_storage.md
index a2a22f138e3..7e8b2865b6e 100644
--- a/doc/user/packages/container_registry/reduce_container_registry_storage.md
+++ b/doc/user/packages/container_registry/reduce_container_registry_storage.md
@@ -49,20 +49,6 @@ Cleanup policies can be run on all projects, with these exceptions:
There are performance risks with enabling it for all projects, especially if you
are using an [external registry](#use-with-external-container-registries).
-- For self-managed GitLab instances, you can enable or disable the cleanup policy for a specific
- project.
-
- To enable it:
-
- ```ruby
- Feature.enable(:container_expiration_policies_historic_entry, Project.find(<project id>))
- ```
-
- To disable it:
-
- ```ruby
- Feature.disable(:container_expiration_policies_historic_entry, Project.find(<project id>))
- ```
WARNING:
For performance reasons, enabled cleanup policies are automatically disabled for projects on
@@ -171,22 +157,32 @@ Here are examples of regex patterns you may want to use:
### Set cleanup limits to conserve resources
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/288812) in GitLab 13.9.
-> - It's [deployed behind a feature flag](../../feature_flags.md), disabled by default.
-> - It's enabled on GitLab.com.
-> - It's not recommended for production use.
-> - To use it in GitLab self-managed instances, ask a GitLab administrator to [enable it](#enable-or-disable-cleanup-policy-limits).
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/288812) in GitLab 13.9 [with a flag](../../../administration/feature_flags.md) named `container_registry_expiration_policies_throttling`. Disabled by default.
+> - [Enabled by default](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/80815) in GitLab 14.9.
+
+FLAG:
+By default this feature is available in GitLab 14.9. To disable the feature, an administrator can
+[disable the feature flag](../../../administration/feature_flags.md)
+named `container_registry_expiration_policies_throttling`.
Cleanup policies are executed as a background process. This process is complex, and depending on the number of tags to delete,
the process can take time to finish.
To prevent server resource starvation, the following application settings are available:
-- `container_registry_expiration_policies_worker_capacity`. The maximum number of cleanup workers running concurrently. This must be greater than `1`.
- We recommend starting with a low number and increasing it after monitoring the resources used by the background workers.
-- `container_registry_delete_tags_service_timeout`. The maximum time, in seconds, that the cleanup process can take to delete a batch of tags.
-- `container_registry_cleanup_tags_service_max_list_size`. The maximum number of tags that can be deleted in a single execution. Additional tags must be deleted in another execution.
- We recommend starting with a low number, like `100`, and increasing it after monitoring that container images are properly deleted.
+- `container_registry_expiration_policies_worker_capacity`: the maximum number of cleanup workers
+ running concurrently. This must be greater than or equal to `0`. We recommend starting with a low
+ number and increasing it after monitoring the resources used by the background workers. To remove
+ all workers and not execute the cleanup policies, set this to `0`. The default value is `4`.
+- `container_registry_delete_tags_service_timeout`: the maximum time (in seconds) that the cleanup
+ process can take to delete a batch of tags. The default value is `250`.
+- `container_registry_cleanup_tags_service_max_list_size`: the maximum number of tags that can be
+ deleted in a single execution. Additional tags must be deleted in another execution. We recommend
+ starting with a low number and increasing it after monitoring that container images are properly
+ deleted. The default value is `200`.
+- `container_registry_expiration_policies_caching`: enable or disable tag creation timestamp caching
+ during execution of policies. Cached timestamps are stored in [Redis](../../../development/architecture.md#redis).
+ Enabled by default.
For self-managed instances, those settings can be updated in the [Rails console](../../../administration/operations/rails_console.md#starting-a-rails-console-session):
@@ -194,31 +190,11 @@ For self-managed instances, those settings can be updated in the [Rails console]
ApplicationSetting.last.update(container_registry_expiration_policies_worker_capacity: 3)
```
-Alternatively, once the limits are [enabled](#enable-or-disable-cleanup-policy-limits),
-they are available in the [administrator area](../../admin_area/index.md):
+They are also available in the [administrator area](../../admin_area/index.md):
1. On the top bar, select **Menu > Admin**.
1. Go to **Settings > CI/CD > Container Registry**.
-#### Enable or disable cleanup policy limits
-
-The cleanup policies limits are under development and not ready for production use. They are
-deployed behind a feature flag that is **disabled by default**.
-[GitLab administrators with access to the GitLab Rails console](../../../administration/feature_flags.md)
-can enable it.
-
-To enable it:
-
-```ruby
-Feature.enable(:container_registry_expiration_policies_throttling)
-```
-
-To disable it:
-
-```ruby
-Feature.disable(:container_registry_expiration_policies_throttling)
-```
-
### Use the cleanup policy API
You can set, update, and disable the cleanup policies using the GitLab API.
diff --git a/doc/user/packages/dependency_proxy/index.md b/doc/user/packages/dependency_proxy/index.md
index 925a1b3e8e6..e431d4d7de3 100644
--- a/doc/user/packages/dependency_proxy/index.md
+++ b/doc/user/packages/dependency_proxy/index.md
@@ -312,3 +312,14 @@ services:
- name: ${CI_DEPENDENCY_PROXY_GROUP_IMAGE_PREFIX}/docker:18.09.7-dind
alias: docker
```
+
+### "Not Found" error when pulling image
+
+Docker errors similar to the following may indicate that the user running the build job doesn't have
+a minimum of the Guest role in the specified Dependency Proxy group:
+
+```plaintext
+ERROR: gitlab.example.com:443/group1/dependency_proxy/containers/alpine:latest: not found
+
+failed to solve with frontend dockerfile.v0: failed to create LLB definition: gitlab.example.com:443/group1/dependency_proxy/containers/alpine:latest: not found
+```
diff --git a/doc/user/packages/generic_packages/index.md b/doc/user/packages/generic_packages/index.md
index ada6f033288..9dc859a37e2 100644
--- a/doc/user/packages/generic_packages/index.md
+++ b/doc/user/packages/generic_packages/index.md
@@ -6,12 +6,8 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# GitLab Generic Packages Repository **(FREE)**
-> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/4209) in GitLab 13.5.
-> - It's [deployed behind a feature flag](../../../user/feature_flags.md), enabled by default.
-> - It's enabled on GitLab.com.
-> - It's 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](#enable-or-disable-generic-packages-in-the-package-registry).
+> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/4209) in GitLab 13.5 [with a flag](../../../administration/feature_flags.md) named `generic_packages`. Enabled by default.
+> - [Feature flag `generic_packages`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/80886) removed in GitLab 14.8.
Publish generic files, like release binaries, in your project's Package Registry. Then, install the packages whenever you need to use them as a dependency.
@@ -194,31 +190,6 @@ upload:
- Invoke-RestMethod -Headers @{ "JOB-TOKEN"="$CI_JOB_TOKEN" } -InFile path/to/file.txt -uri "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/my_package/0.0.1/file.txt" -Method put
```
-### Enable or disable generic packages in the Package Registry
-
-Support for generic packages is under development but ready for production use.
-It is deployed behind a feature flag that is **enabled by default**.
-[GitLab administrators with access to the GitLab Rails console](../../../administration/feature_flags.md)
-can opt to disable it.
-
-To enable it:
-
-```ruby
-# For the instance
-Feature.enable(:generic_packages)
-# For a single project
-Feature.enable(:generic_packages, Project.find(<project id>))
-```
-
-To disable it:
-
-```ruby
-# For the instance
-Feature.disable(:generic_packages)
-# For a single project
-Feature.disable(:generic_packages, Project.find(<project id>))
-```
-
### Generic package sample project
The [Write CI-CD Variables in Pipeline](https://gitlab.com/guided-explorations/cfg-data/write-ci-cd-variables-in-pipeline) project contains a working example you can use to create, upload, and download generic packages in GitLab CI/CD.
diff --git a/doc/user/packages/package_registry/index.md b/doc/user/packages/package_registry/index.md
index a2228148447..b980f6a5694 100644
--- a/doc/user/packages/package_registry/index.md
+++ b/doc/user/packages/package_registry/index.md
@@ -60,6 +60,12 @@ For most package types, the following credential types are valid:
allows access to packages in the project running the job for the users running the pipeline.
Access to other external projects can be configured.
+ NOTE:
+ There's an open issue,
+ [GitLab-#333444](https://gitlab.com/gitlab-org/gitlab/-/issues/333444),
+ which prevents you from using a job token with internal projects. This bug only impacts self-managed
+ GitLab instances.
+
## Use GitLab CI/CD to build packages
You can use [GitLab CI/CD](../../../ci/index.md) to build packages.
diff --git a/doc/user/packages/package_registry/reduce_package_registry_storage.md b/doc/user/packages/package_registry/reduce_package_registry_storage.md
index c2e4cd8d889..f8a1e63a228 100644
--- a/doc/user/packages/package_registry/reduce_package_registry_storage.md
+++ b/doc/user/packages/package_registry/reduce_package_registry_storage.md
@@ -16,7 +16,7 @@ We recommend deleting unnecessary packages and files. This page offers examples
## Check Package Registry Storage Use
-The Usage Quotas page (**Settings > Usage Quotas > Storage**) displays storage usage for Packages.
+The Usage Quotas page (**Settings > Usage Quotas > Storage**) displays storage usage for Packages.
## Delete a package
diff --git a/doc/user/packages/pypi_repository/index.md b/doc/user/packages/pypi_repository/index.md
index bf007572ac7..4d46032d229 100644
--- a/doc/user/packages/pypi_repository/index.md
+++ b/doc/user/packages/pypi_repository/index.md
@@ -254,7 +254,9 @@ Prerequisites:
- The maximum allowed package size is 5 GB.
- You can't upload the same version of a package multiple times. If you try,
you receive the error `400 Bad Request`.
-- You cannot publish PyPI packages to a group, only to a project.
+- PyPI packages are published using your projectID.
+- If your project is in a group, PyPI packages published to your project registry are also available
+ at the group-level registry (see [Install from the group level](#install-from-the-group-level)).
You can then [publish a package by using twine](#publish-a-pypi-package-by-using-twine).
diff --git a/doc/user/packages/terraform_module_registry/index.md b/doc/user/packages/terraform_module_registry/index.md
index 6fc47a23373..a107d06a63c 100644
--- a/doc/user/packages/terraform_module_registry/index.md
+++ b/doc/user/packages/terraform_module_registry/index.md
@@ -36,7 +36,7 @@ PUT /projects/:id/packages/terraform/modules/:module-name/:module-system/:module
| -------------------| --------------- | ---------| -------------------------------------------------------------------------------------------------------------------------------- |
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](../../../api/index.md#namespaced-path-encoding). |
| `module-name` | string | yes | The package name. It can contain only lowercase letters (`a-z`), uppercase letter (`A-Z`), numbers (`0-9`), or hyphens (`-`) and cannot exceed 64 characters.
-| `module-system` | string | yes | The package system. It can contain only lowercase letters (`a-z`) and numbers (`0-9`), and cannot exceed 64 characters.
+| `module-system` | string | yes | The package system. It can contain only lowercase letters (`a-z`) and numbers (`0-9`), and cannot exceed 64 characters. More information can be found in the [Terraform Module Registry Protocol documentation](https://www.terraform.io/internals/module-registry-protocol).
| `module-version` | string | yes | The package version. It must be valid according to the [Semantic Versioning Specification](https://semver.org/).
Provide the file content in the request body.
@@ -93,7 +93,7 @@ credentials "gitlab.com" {
Where `gitlab.com` can be replaced with the hostname of your self-managed GitLab instance.
-You can then reference your Terraform Module from a downstream Terraform project:
+You can then refer to your Terraform Module from a downstream Terraform project:
```plaintext
module "<module>" {
@@ -101,6 +101,8 @@ module "<module>" {
}
```
+Where `<namespace>` is the [namespace](../../../user/group/index.md#namespaces) of the Terraform module registry.
+
## Publish a Terraform module by using CI/CD
To work with Terraform modules in [GitLab CI/CD](../../../ci/index.md), you can use
diff --git a/doc/user/permissions.md b/doc/user/permissions.md
index 4476b0dd75b..c90f575e83a 100644
--- a/doc/user/permissions.md
+++ b/doc/user/permissions.md
@@ -4,7 +4,7 @@ group: Authentication and Authorization
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
-# Permissions and roles
+# Permissions and roles **(FREE)**
Users have different abilities depending on the role they have in a
particular group or project. If a user is both in a project's group and the
@@ -33,168 +33,176 @@ usernames. A GitLab administrator can configure the GitLab instance to
## Project members permissions
+- [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/219299) in GitLab 14.8, personal namespace owners appear with Owner role in new projects in their namespace. Introduced [with a flag](../administration/feature_flags.md) named `personal_project_owner_with_owner_access`. Disabled by default.
+- [Generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/351919) in GitLab 14.9. Feature flag `personal_project_owner_with_owner_access` [removed](https://gitlab.com/gitlab-org/gitlab/-/issues/219299).
+
A user's role determines what permissions they have on a project. The Owner role provides all permissions but is
available only:
- For group owners. The role is inherited for a group's projects.
- For Administrators.
-Personal namespace owners have the same permissions as an Owner, but are displayed with the Maintainer role on projects created in their personal namespace.
-For more information, see [projects members documentation](project/members/index.md).
+Personal [namespace](group/index.md#namespaces) owners:
+
+- Are displayed as having the Maintainer role on projects in the namespace, but have the same permissions as a user with the Owner role.
+- In GitLab 14.9 and later, for new projects in the namespace, are displayed as having the Owner role.
+
+For more information about how to manage project members, see
+[members of a project](project/members/index.md).
The following table lists project permissions available for each role:
<!-- Keep this table sorted: By topic first, then by minimum role, then alphabetically. -->
-| Action | Guest | Reporter | Developer | Maintainer | Owner |
-|--------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------|----------|-----------|------------|-------|
-| [Analytics](analytics/index.md):<br>View issue analytics **(PREMIUM)** | ✓ | ✓ | ✓ | ✓ | ✓ |
-| [Analytics](analytics/index.md):<br>View [merge request analytics](analytics/merge_request_analytics.md) **(PREMIUM)** | ✓ | ✓ | ✓ | ✓ | ✓ |
-| [Analytics](analytics/index.md):<br>View value stream analytics | ✓ | ✓ | ✓ | ✓ | ✓ |
-| [Analytics](analytics/index.md):<br>View [DORA metrics](analytics/ci_cd_analytics.md) | | ✓ | ✓ | ✓ | ✓ |
-| [Analytics](analytics/index.md):<br>View [CI/CD analytics](analytics/ci_cd_analytics.md) | | ✓ | ✓ | ✓ | ✓ |
-| [Analytics](analytics/index.md):<br>View [code review analytics](analytics/code_review_analytics.md) **(PREMIUM)** | | ✓ | ✓ | ✓ | ✓ |
-| [Analytics](analytics/index.md):<br>View [repository analytics](analytics/repository_analytics.md) | | ✓ | ✓ | ✓ | ✓ |
-| [Application security](application_security/index.md):<br>View licenses in [dependency list](application_security/dependency_list/index.md) **(ULTIMATE)** | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ |
-| [Application security](application_security/index.md):<br>Create and run [on-demand DAST scans](application_security/dast/index.md#on-demand-scans) **(ULTIMATE)** | | | ✓ | ✓ | ✓ |
-| [Application security](application_security/index.md):<br>Manage [security policy](application_security/policies/index.md) **(ULTIMATE)** | | | ✓ | ✓ | ✓ |
-| [Application security](application_security/index.md):<br>View [dependency list](application_security/dependency_list/index.md) **(ULTIMATE)** | | | ✓ | ✓ | ✓ |
-| [Application security](application_security/index.md):<br>View [threats list](application_security/threat_monitoring/index.md#threat-monitoring) **(ULTIMATE)** | | | ✓ | ✓ | ✓ |
-| [Application security](application_security/index.md):<br>Create a [CVE ID Request](application_security/cve_id_request.md) **(FREE SAAS)** | | | | ✓ | ✓ |
-| [Application security](application_security/index.md):<br>Create or assign [security policy project](application_security/policies/index.md) **(ULTIMATE)** | | | | | ✓ |
-| [Clusters](infrastructure/clusters/index.md):<br>View [pod logs](project/clusters/kubernetes_pod_logs.md) | | | ✓ | ✓ | ✓ |
-| [Clusters](infrastructure/clusters/index.md):<br>View clusters | | | ✓ | ✓ | ✓ |
-| [Clusters](infrastructure/clusters/index.md):<br>Manage clusters | | | | ✓ | ✓ |
-| [Container Registry](packages/container_registry/index.md):<br>Create, edit, delete cleanup policies | | | ✓ | ✓ | ✓ |
-| [Container Registry](packages/container_registry/index.md):<br>Push an image to the Container Registry | | | ✓ | ✓ | ✓ |
-| [Container Registry](packages/container_registry/index.md):<br>Pull an image from the Container Registry | ✓ (*20*) | ✓ (*20*) | ✓ | ✓ | ✓ |
-| [Container Registry](packages/container_registry/index.md):<br>Remove a Container Registry image | | | ✓ | ✓ | ✓ |
-| [GitLab Pages](project/pages/index.md):<br>View Pages protected by [access control](project/pages/introduction.md#gitlab-pages-access-control) | ✓ | ✓ | ✓ | ✓ | ✓ |
-| [GitLab Pages](project/pages/index.md):<br>Manage | | | | ✓ | ✓ |
-| [GitLab Pages](project/pages/index.md):<br>Manage GitLab Pages domains and certificates | | | | ✓ | ✓ |
-| [GitLab Pages](project/pages/index.md):<br>Remove GitLab Pages | | | | ✓ | ✓ |
-| [Incident Management](../operations/incident_management/index.md):<br>View [alerts](../operations/incident_management/alerts.md) | | ✓ | ✓ | ✓ | ✓ |
-| [Incident Management](../operations/incident_management/index.md):<br>Assign an alert | ✓ | ✓ | ✓ | ✓ | ✓ |
-| [Incident Management](../operations/incident_management/index.md):<br>View [incident](../operations/incident_management/incidents.md) | ✓ | ✓ | ✓ | ✓ | ✓ |
-| [Incident Management](../operations/incident_management/index.md):<br>Create [incident](../operations/incident_management/incidents.md) | (*16*) | ✓ | ✓ | ✓ | ✓ |
-| [Incident Management](../operations/incident_management/index.md):<br>View [on-call schedules](../operations/incident_management/oncall_schedules.md) | | ✓ | ✓ | ✓ | ✓ |
-| [Incident Management](../operations/incident_management/index.md):<br>Participate in on-call rotation | ✓ | ✓ | ✓ | ✓ | ✓ |
-| [Incident Management](../operations/incident_management/index.md):<br>View [escalation policies](../operations/incident_management/escalation_policies.md) | | ✓ | ✓ | ✓ | ✓ |
-| [Incident Management](../operations/incident_management/index.md):<br>Manage [on-call schedules](../operations/incident_management/oncall_schedules.md) | | | | ✓ | ✓ |
-| [Incident Management](../operations/incident_management/index.md):<br>Manage [escalation policies](../operations/incident_management/escalation_policies.md) | | | | ✓ | ✓ |
-| [Issues](project/issues/index.md):<br>Add Labels | ✓ (*15*) | ✓ | ✓ | ✓ | ✓ |
-| [Issues](project/issues/index.md):<br>Assign | ✓ (*15*) | ✓ | ✓ | ✓ | ✓ |
-| [Issues](project/issues/index.md):<br>Create (*18*) | ✓ | ✓ | ✓ | ✓ | ✓ |
-| [Issues](project/issues/index.md):<br>Create [confidential issues](project/issues/confidential_issues.md) | ✓ | ✓ | ✓ | ✓ | ✓ |
-| [Issues](project/issues/index.md):<br>View [Design Management](project/issues/design_management.md) pages | ✓ | ✓ | ✓ | ✓ | ✓ |
-| [Issues](project/issues/index.md):<br>View related issues | ✓ | ✓ | ✓ | ✓ | ✓ |
-| [Issues](project/issues/index.md):<br>Set weight | ✓ (*15*) | ✓ | ✓ | ✓ | ✓ |
-| [Issues](project/issues/index.md):<br>View [confidential issues](project/issues/confidential_issues.md) | (*2*) | ✓ | ✓ | ✓ | ✓ |
-| [Issues](project/issues/index.md):<br>Close / reopen (*19*) | | ✓ | ✓ | ✓ | ✓ |
-| [Issues](project/issues/index.md):<br>Lock threads | | ✓ | ✓ | ✓ | ✓ |
-| [Issues](project/issues/index.md):<br>Manage related issues | | ✓ | ✓ | ✓ | ✓ |
-| [Issues](project/issues/index.md):<br>Manage tracker | | ✓ | ✓ | ✓ | ✓ |
-| [Issues](project/issues/index.md):<br>Move issues (*14*) | | ✓ | ✓ | ✓ | ✓ |
-| [Issues](project/issues/index.md):<br>Set issue [time tracking](project/time_tracking.md) estimate and time spent | | ✓ | ✓ | ✓ | ✓ |
-| [Issues](project/issues/index.md):<br>Upload [Design Management](project/issues/design_management.md) files | | | ✓ | ✓ | ✓ |
-| [Issues](project/issues/index.md):<br>Delete | | | | | ✓ |
-| [License Compliance](compliance/license_compliance/index.md):<br>View allowed and denied licenses **(ULTIMATE)** | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ |
-| [License Compliance](compliance/license_compliance/index.md):<br>View License Compliance reports **(ULTIMATE)** | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ |
-| [License Compliance](compliance/license_compliance/index.md):<br>View License list **(ULTIMATE)** | | ✓ | ✓ | ✓ | ✓ |
-| [License Compliance](compliance/license_compliance/index.md):<br>Manage license policy **(ULTIMATE)** | | | | ✓ | ✓ |
-| [Merge requests](project/merge_requests/index.md):<br>Assign reviewer | | ✓ | ✓ | ✓ | ✓ |
-| [Merge requests](project/merge_requests/index.md):<br>See list | | ✓ | ✓ | ✓ | ✓ |
-| [Merge requests](project/merge_requests/index.md):<br>Apply code change suggestions | | | ✓ | ✓ | ✓ |
-| [Merge requests](project/merge_requests/index.md):<br>Approve (*8*) | | | ✓ | ✓ | ✓ |
-| [Merge requests](project/merge_requests/index.md):<br>Assign | | | ✓ | ✓ | ✓ |
-| [Merge requests](project/merge_requests/index.md):<br>Create (*17*) | | | ✓ | ✓ | ✓ |
-| [Merge requests](project/merge_requests/index.md):<br>Add labels | | | ✓ | ✓ | ✓ |
-| [Merge requests](project/merge_requests/index.md):<br>Lock threads | | | ✓ | ✓ | ✓ |
-| [Merge requests](project/merge_requests/index.md):<br>Manage or accept | | | ✓ | ✓ | ✓ |
-| [Merge requests](project/merge_requests/index.md):<br>Manage merge approval rules (project settings) | | | | ✓ | ✓ |
-| [Merge requests](project/merge_requests/index.md):<br>Delete | | | | | ✓ |
-| [Metrics dashboards](../operations/metrics/dashboards/index.md):<br>Manage user-starred metrics dashboards (*6*) | ✓ | ✓ | ✓ | ✓ | ✓ |
-| [Metrics dashboards](../operations/metrics/dashboards/index.md):<br>View metrics dashboard annotations | | ✓ | ✓ | ✓ | ✓ |
-| [Metrics dashboards](../operations/metrics/dashboards/index.md):<br>Create/edit/delete metrics dashboard annotations | | | ✓ | ✓ | ✓ |
-| [Package registry](packages/index.md):<br>Pull a package | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ |
-| [Package registry](packages/index.md):<br>Publish a package | | | ✓ | ✓ | ✓ |
-| [Package registry](packages/index.md):<br>Delete a package | | | | ✓ | ✓ |
-| [Package registry](packages/index.md):<br>Delete a file associated with a package | | | | ✓ | ✓ |
-| [Project operations](../operations/index.md):<br>View [Error Tracking](../operations/error_tracking.md) list | | ✓ | ✓ | ✓ | ✓ |
-| [Project operations](../operations/index.md):<br>Manage [Feature Flags](../operations/feature_flags.md) **(PREMIUM)** | | | ✓ | ✓ | ✓ |
-| [Project operations](../operations/index.md):<br>Manage [Error Tracking](../operations/error_tracking.md) | | | | ✓ | ✓ |
-| [Projects](project/index.md):<br>Download project | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ |
-| [Projects](project/index.md):<br>Leave comments | ✓ | ✓ | ✓ | ✓ | ✓ |
-| [Projects](project/index.md):<br>Reposition comments on images (posted by any user) | ✓ (*9*) | ✓ (*9*) | ✓ (*9*) | ✓ | ✓ |
-| [Projects](project/index.md):<br>View Insights **(ULTIMATE)** | ✓ | ✓ | ✓ | ✓ | ✓ |
-| [Projects](project/index.md):<br>View [releases](project/releases/index.md) | ✓ (*5*) | ✓ | ✓ | ✓ | ✓ |
-| [Projects](project/index.md):<br>View Requirements **(ULTIMATE)** | ✓ | ✓ | ✓ | ✓ | ✓ |
-| [Projects](project/index.md):<br>View [time tracking](project/time_tracking.md) reports | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ |
-| [Projects](project/index.md):<br>View [wiki](project/wiki/index.md) pages | ✓ | ✓ | ✓ | ✓ | ✓ |
-| [Projects](project/index.md):<br>Create [snippets](snippets.md) | | ✓ | ✓ | ✓ | ✓ |
-| [Projects](project/index.md):<br>Manage labels | | ✓ | ✓ | ✓ | ✓ |
-| [Projects](project/index.md):<br>View [project traffic statistics](../api/project_statistics.md) | | ✓ | ✓ | ✓ | ✓ |
-| [Projects](project/index.md):<br>Create, edit, delete [milestones](project/milestones/index.md). | | | ✓ | ✓ | ✓ |
-| [Projects](project/index.md):<br>Create, edit, delete [releases](project/releases/index.md) | | | ✓ (*12*) | ✓ (*12*) | ✓ (*12*) |
-| [Projects](project/index.md):<br>Create, edit [wiki](project/wiki/index.md) pages | | | ✓ | ✓ | ✓ |
-| [Projects](project/index.md):<br>Enable Review Apps | | | ✓ | ✓ | ✓ |
-| [Projects](project/index.md):<br>View project [Audit Events](../administration/audit_events.md) | | | ✓ (*10*) | ✓ | ✓ |
-| [Projects](project/index.md):<br>Add deploy keys | | | | ✓ | ✓ |
-| [Projects](project/index.md):<br>Add new team members | | | | ✓ | ✓ |
-| [Projects](project/index.md):<br>Change [project features visibility](../public_access/public_access.md) level | | | | ✓ (*13*) | ✓ |
-| [Projects](project/index.md):<br>Configure [webhooks](project/integrations/webhooks.md) | | | | ✓ | ✓ |
-| [Projects](project/index.md):<br>Delete [wiki](project/wiki/index.md) pages | | | ✓ | ✓ | ✓ |
-| [Projects](project/index.md):<br>Edit comments (posted by any user) | | | | ✓ | ✓ |
-| [Projects](project/index.md):<br>Edit project badges | | | | ✓ | ✓ |
-| [Projects](project/index.md):<br>Edit project settings | | | | ✓ | ✓ |
-| [Projects](project/index.md):<br>Export project | | | | ✓ | ✓ |
-| [Projects](project/index.md):<br>Manage [project access tokens](project/settings/project_access_tokens.md) **(FREE SELF)** **(PREMIUM SAAS)** (*11*) | | | | ✓ | ✓ |
-| [Projects](project/index.md):<br>Manage [Project Operations](../operations/index.md) | | | | ✓ | ✓ |
-| [Projects](project/index.md):<br>Rename project | | | | ✓ | ✓ |
-| [Projects](project/index.md):<br>Share (invite) projects with groups | | | | ✓ (*7*) | ✓ (*7*) |
-| [Projects](project/index.md):<br>View 2FA status of members | | | | ✓ | ✓ |
-| [Projects](project/index.md):<br>Administer project compliance frameworks | | | | | ✓ |
-| [Projects](project/index.md):<br>Archive project | | | | | ✓ |
-| [Projects](project/index.md):<br>Change project visibility level | | | | | ✓ |
-| [Projects](project/index.md):<br>Delete project | | | | | ✓ |
-| [Projects](project/index.md):<br>Disable notification emails | | | | | ✓ |
-| [Projects](project/index.md):<br>Transfer project to another namespace | | | | | ✓ |
-| [Repository](project/repository/index.md):<br>Pull project code | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ |
-| [Repository](project/repository/index.md):<br>View project code | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ |
-| [Repository](project/repository/index.md):<br>View a commit status | | ✓ | ✓ | ✓ | ✓ |
-| [Repository](project/repository/index.md):<br>Add tags | | | ✓ | ✓ | ✓ |
-| [Repository](project/repository/index.md):<br>Create new branches | | | ✓ | ✓ | ✓ |
-| [Repository](project/repository/index.md):<br>Create or update commit status | | | ✓ (*4*) | ✓ | ✓ |
-| [Repository](project/repository/index.md):<br>Force push to non-protected branches | | | ✓ | ✓ | ✓ |
-| [Repository](project/repository/index.md):<br>Push to non-protected branches | | | ✓ | ✓ | ✓ |
-| [Repository](project/repository/index.md):<br>Remove non-protected branches | | | ✓ | ✓ | ✓ |
-| [Repository](project/repository/index.md):<br>Rewrite or remove Git tags | | | ✓ | ✓ | ✓ |
-| [Repository](project/repository/index.md):<br>Enable or disable branch protection | | | | ✓ | ✓ |
-| [Repository](project/repository/index.md):<br>Enable or disable tag protection | | | | ✓ | ✓ |
-| [Repository](project/repository/index.md):<br>Manage [push rules](project/repository/push_rules.md) | | | | ✓ | ✓ |
-| [Repository](project/repository/index.md):<br>Push to protected branches (*4*) | | | | ✓ | ✓ |
-| [Repository](project/repository/index.md):<br>Turn on or off protected branch push for developers | | | | ✓ | ✓ |
-| [Repository](project/repository/index.md):<br>Remove fork relationship | | | | | ✓ |
-| [Repository](project/repository/index.md):<br>Force push to protected branches (*3*) | | | | | |
-| [Repository](project/repository/index.md):<br>Remove protected branches (*3*) | | | | | |
-| [Requirements Management](project/requirements/index.md):<br>Archive / reopen **(ULTIMATE)** | | ✓ | ✓ | ✓ | ✓ |
-| [Requirements Management](project/requirements/index.md):<br>Create / edit **(ULTIMATE)** | | ✓ | ✓ | ✓ | ✓ |
-| [Requirements Management](project/requirements/index.md):<br>Import / export **(ULTIMATE)** | | ✓ | ✓ | ✓ | ✓ |
-| [Security dashboard](application_security/security_dashboard/index.md):<br>Create issue from vulnerability finding **(ULTIMATE)** | | | ✓ | ✓ | ✓ |
-| [Security dashboard](application_security/security_dashboard/index.md):<br>Create vulnerability from vulnerability finding **(ULTIMATE)** | | | ✓ | ✓ | ✓ |
-| [Security dashboard](application_security/security_dashboard/index.md):<br>Dismiss vulnerability **(ULTIMATE)** | | | ✓ | ✓ | ✓ |
-| [Security dashboard](application_security/security_dashboard/index.md):<br>Dismiss vulnerability finding **(ULTIMATE)** | | | ✓ | ✓ | ✓ |
-| [Security dashboard](application_security/security_dashboard/index.md):<br>Resolve vulnerability **(ULTIMATE)** | | | ✓ | ✓ | ✓ |
-| [Security dashboard](application_security/security_dashboard/index.md):<br>Revert vulnerability to detected state **(ULTIMATE)** | | | ✓ | ✓ | ✓ |
-| [Security dashboard](application_security/security_dashboard/index.md):<br>Use security dashboard **(ULTIMATE)** | | | ✓ | ✓ | ✓ |
-| [Security dashboard](application_security/security_dashboard/index.md):<br>View vulnerability **(ULTIMATE)** | | | ✓ | ✓ | ✓ |
-| [Security dashboard](application_security/security_dashboard/index.md):<br>View vulnerability findings in [dependency list](application_security/dependency_list/index.md) **(ULTIMATE)** | | | ✓ | ✓ | ✓ |
-| [Terraform](infrastructure/index.md):<br>Read Terraform state | | | ✓ | ✓ | ✓ |
-| [Terraform](infrastructure/index.md):<br>Manage Terraform state | | | | ✓ | ✓ |
-| [Test cases](../ci/test_cases/index.md):<br>Archive | | ✓ | ✓ | ✓ | ✓ |
-| [Test cases](../ci/test_cases/index.md):<br>Create | | ✓ | ✓ | ✓ | ✓ |
-| [Test cases](../ci/test_cases/index.md):<br>Move | | ✓ | ✓ | ✓ | ✓ |
-| [Test cases](../ci/test_cases/index.md):<br>Reopen | | ✓ | ✓ | ✓ | ✓ |
+| Action | Guest | Reporter | Developer | Maintainer | Owner |
+|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------|----------|-----------|------------|----------|
+| [Analytics](analytics/index.md):<br>View issue analytics | ✓ | ✓ | ✓ | ✓ | ✓ |
+| [Analytics](analytics/index.md):<br>View [merge request analytics](analytics/merge_request_analytics.md) | ✓ | ✓ | ✓ | ✓ | ✓ |
+| [Analytics](analytics/index.md):<br>View value stream analytics | ✓ | ✓ | ✓ | ✓ | ✓ |
+| [Analytics](analytics/index.md):<br>View [DORA metrics](analytics/ci_cd_analytics.md) | | ✓ | ✓ | ✓ | ✓ |
+| [Analytics](analytics/index.md):<br>View [CI/CD analytics](analytics/ci_cd_analytics.md) | | ✓ | ✓ | ✓ | ✓ |
+| [Analytics](analytics/index.md):<br>View [code review analytics](analytics/code_review_analytics.md) | | ✓ | ✓ | ✓ | ✓ |
+| [Analytics](analytics/index.md):<br>View [repository analytics](analytics/repository_analytics.md) | | ✓ | ✓ | ✓ | ✓ |
+| [Application security](application_security/index.md):<br>View licenses in [dependency list](application_security/dependency_list/index.md) | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ |
+| [Application security](application_security/index.md):<br>Create and run [on-demand DAST scans](application_security/dast/index.md#on-demand-scans) | | | ✓ | ✓ | ✓ |
+| [Application security](application_security/index.md):<br>Manage [security policy](application_security/policies/index.md) | | | ✓ | ✓ | ✓ |
+| [Application security](application_security/index.md):<br>View [dependency list](application_security/dependency_list/index.md) | | | ✓ | ✓ | ✓ |
+| [Application security](application_security/index.md):<br>View [threats list](application_security/threat_monitoring/index.md#threat-monitoring) | | | ✓ | ✓ | ✓ |
+| [Application security](application_security/index.md):<br>Create a [CVE ID Request](application_security/cve_id_request.md) | | | | ✓ | ✓ |
+| [Application security](application_security/index.md):<br>Create or assign [security policy project](application_security/policies/index.md) | | | | | ✓ |
+| [Clusters](infrastructure/clusters/index.md):<br>View [pod logs](project/clusters/kubernetes_pod_logs.md) | | | ✓ | ✓ | ✓ |
+| [Clusters](infrastructure/clusters/index.md):<br>View clusters | | | ✓ | ✓ | ✓ |
+| [Clusters](infrastructure/clusters/index.md):<br>Manage clusters | | | | ✓ | ✓ |
+| [Container Registry](packages/container_registry/index.md):<br>Create, edit, delete cleanup policies | | | ✓ | ✓ | ✓ |
+| [Container Registry](packages/container_registry/index.md):<br>Push an image to the Container Registry | | | ✓ | ✓ | ✓ |
+| [Container Registry](packages/container_registry/index.md):<br>Pull an image from the Container Registry | ✓ (*20*) | ✓ (*20*) | ✓ | ✓ | ✓ |
+| [Container Registry](packages/container_registry/index.md):<br>Remove a Container Registry image | | | ✓ | ✓ | ✓ |
+| [GitLab Pages](project/pages/index.md):<br>View Pages protected by [access control](project/pages/introduction.md#gitlab-pages-access-control) | ✓ | ✓ | ✓ | ✓ | ✓ |
+| [GitLab Pages](project/pages/index.md):<br>Manage | | | | ✓ | ✓ |
+| [GitLab Pages](project/pages/index.md):<br>Manage GitLab Pages domains and certificates | | | | ✓ | ✓ |
+| [GitLab Pages](project/pages/index.md):<br>Remove GitLab Pages | | | | ✓ | ✓ |
+| [Incident Management](../operations/incident_management/index.md):<br>View [alerts](../operations/incident_management/alerts.md) | | ✓ | ✓ | ✓ | ✓ |
+| [Incident Management](../operations/incident_management/index.md):<br>Assign an alert | ✓ | ✓ | ✓ | ✓ | ✓ |
+| [Incident Management](../operations/incident_management/index.md):<br>View [incident](../operations/incident_management/incidents.md) | ✓ | ✓ | ✓ | ✓ | ✓ |
+| [Incident Management](../operations/incident_management/index.md):<br>Create [incident](../operations/incident_management/incidents.md) | (*16*) | ✓ | ✓ | ✓ | ✓ |
+| [Incident Management](../operations/incident_management/index.md):<br>View [on-call schedules](../operations/incident_management/oncall_schedules.md) | | ✓ | ✓ | ✓ | ✓ |
+| [Incident Management](../operations/incident_management/index.md):<br>Participate in on-call rotation | ✓ | ✓ | ✓ | ✓ | ✓ |
+| [Incident Management](../operations/incident_management/index.md):<br>View [escalation policies](../operations/incident_management/escalation_policies.md) | | ✓ | ✓ | ✓ | ✓ |
+| [Incident Management](../operations/incident_management/index.md):<br>Manage [on-call schedules](../operations/incident_management/oncall_schedules.md) | | | | ✓ | ✓ |
+| [Incident Management](../operations/incident_management/index.md):<br>Manage [escalation policies](../operations/incident_management/escalation_policies.md) | | | | ✓ | ✓ |
+| [Issues](project/issues/index.md):<br>Add Labels | ✓ (*15*) | ✓ | ✓ | ✓ | ✓ |
+| [Issues](project/issues/index.md):<br>Assign | ✓ (*15*) | ✓ | ✓ | ✓ | ✓ |
+| [Issues](project/issues/index.md):<br>Create (*18*) | ✓ | ✓ | ✓ | ✓ | ✓ |
+| [Issues](project/issues/index.md):<br>Create [confidential issues](project/issues/confidential_issues.md) | ✓ | ✓ | ✓ | ✓ | ✓ |
+| [Issues](project/issues/index.md):<br>View [Design Management](project/issues/design_management.md) pages | ✓ | ✓ | ✓ | ✓ | ✓ |
+| [Issues](project/issues/index.md):<br>View related issues | ✓ | ✓ | ✓ | ✓ | ✓ |
+| [Issues](project/issues/index.md):<br>Set weight | ✓ (*15*) | ✓ | ✓ | ✓ | ✓ |
+| [Issues](project/issues/index.md):<br>View [confidential issues](project/issues/confidential_issues.md) | (*2*) | ✓ | ✓ | ✓ | ✓ |
+| [Issues](project/issues/index.md):<br>Close / reopen (*19*) | | ✓ | ✓ | ✓ | ✓ |
+| [Issues](project/issues/index.md):<br>Lock threads | | ✓ | ✓ | ✓ | ✓ |
+| [Issues](project/issues/index.md):<br>Manage related issues | | ✓ | ✓ | ✓ | ✓ |
+| [Issues](project/issues/index.md):<br>Manage tracker | | ✓ | ✓ | ✓ | ✓ |
+| [Issues](project/issues/index.md):<br>Move issues (*14*) | | ✓ | ✓ | ✓ | ✓ |
+| [Issues](project/issues/index.md):<br>Set issue [time tracking](project/time_tracking.md) estimate and time spent | | ✓ | ✓ | ✓ | ✓ |
+| [Issues](project/issues/index.md):<br>Upload [Design Management](project/issues/design_management.md) files | | | ✓ | ✓ | ✓ |
+| [Issues](project/issues/index.md):<br>Delete | | | | | ✓ |
+| [License Compliance](compliance/license_compliance/index.md):<br>View allowed and denied licenses | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ |
+| [License Compliance](compliance/license_compliance/index.md):<br>View License Compliance reports | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ |
+| [License Compliance](compliance/license_compliance/index.md):<br>View License list | | ✓ | ✓ | ✓ | ✓ |
+| [License Compliance](compliance/license_compliance/index.md):<br>Manage license policy | | | | ✓ | ✓ |
+| [Merge requests](project/merge_requests/index.md):<br>Assign reviewer | | ✓ | ✓ | ✓ | ✓ |
+| [Merge requests](project/merge_requests/index.md):<br>See list | | ✓ | ✓ | ✓ | ✓ |
+| [Merge requests](project/merge_requests/index.md):<br>Apply code change suggestions | | | ✓ | ✓ | ✓ |
+| [Merge requests](project/merge_requests/index.md):<br>Approve (*8*) | | | ✓ | ✓ | ✓ |
+| [Merge requests](project/merge_requests/index.md):<br>Assign | | | ✓ | ✓ | ✓ |
+| [Merge requests](project/merge_requests/index.md):<br>Create (*17*) | | | ✓ | ✓ | ✓ |
+| [Merge requests](project/merge_requests/index.md):<br>Add labels | | | ✓ | ✓ | ✓ |
+| [Merge requests](project/merge_requests/index.md):<br>Lock threads | | | ✓ | ✓ | ✓ |
+| [Merge requests](project/merge_requests/index.md):<br>Manage or accept | | | ✓ | ✓ | ✓ |
+| [Merge requests](project/merge_requests/index.md):<br>Manage merge approval rules (project settings) | | | | ✓ | ✓ |
+| [Merge requests](project/merge_requests/index.md):<br>Delete | | | | | ✓ |
+| [Metrics dashboards](../operations/metrics/dashboards/index.md):<br>Manage user-starred metrics dashboards (*6*) | ✓ | ✓ | ✓ | ✓ | ✓ |
+| [Metrics dashboards](../operations/metrics/dashboards/index.md):<br>View metrics dashboard annotations | | ✓ | ✓ | ✓ | ✓ |
+| [Metrics dashboards](../operations/metrics/dashboards/index.md):<br>Create/edit/delete metrics dashboard annotations | | | ✓ | ✓ | ✓ |
+| [Package registry](packages/index.md):<br>Pull a package | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ |
+| [Package registry](packages/index.md):<br>Publish a package | | | ✓ | ✓ | ✓ |
+| [Package registry](packages/index.md):<br>Delete a package | | | | ✓ | ✓ |
+| [Package registry](packages/index.md):<br>Delete a file associated with a package | | | | ✓ | ✓ |
+| [Project operations](../operations/index.md):<br>View [Error Tracking](../operations/error_tracking.md) list | | ✓ | ✓ | ✓ | ✓ |
+| [Project operations](../operations/index.md):<br>Manage [Feature Flags](../operations/feature_flags.md) | | | ✓ | ✓ | ✓ |
+| [Project operations](../operations/index.md):<br>Manage [Error Tracking](../operations/error_tracking.md) | | | | ✓ | ✓ |
+| [Projects](project/index.md):<br>Download project | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ |
+| [Projects](project/index.md):<br>Leave comments | ✓ | ✓ | ✓ | ✓ | ✓ |
+| [Projects](project/index.md):<br>Reposition comments on images (posted by any user) | ✓ (*9*) | ✓ (*9*) | ✓ (*9*) | ✓ | ✓ |
+| [Projects](project/index.md):<br>View Insights | ✓ | ✓ | ✓ | ✓ | ✓ |
+| [Projects](project/index.md):<br>View [releases](project/releases/index.md) | ✓ (*5*) | ✓ | ✓ | ✓ | ✓ |
+| [Projects](project/index.md):<br>View Requirements | ✓ | ✓ | ✓ | ✓ | ✓ |
+| [Projects](project/index.md):<br>View [time tracking](project/time_tracking.md) reports | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ |
+| [Projects](project/index.md):<br>View [wiki](project/wiki/index.md) pages | ✓ | ✓ | ✓ | ✓ | ✓ |
+| [Projects](project/index.md):<br>Create [snippets](snippets.md) | | ✓ | ✓ | ✓ | ✓ |
+| [Projects](project/index.md):<br>Manage labels | | ✓ | ✓ | ✓ | ✓ |
+| [Projects](project/index.md):<br>View [project traffic statistics](../api/project_statistics.md) | | ✓ | ✓ | ✓ | ✓ |
+| [Projects](project/index.md):<br>Create, edit, delete [milestones](project/milestones/index.md). | | | ✓ | ✓ | ✓ |
+| [Projects](project/index.md):<br>Create, edit, delete [releases](project/releases/index.md) | | | ✓ (*12*) | ✓ (*12*) | ✓ (*12*) |
+| [Projects](project/index.md):<br>Create, edit [wiki](project/wiki/index.md) pages | | | ✓ | ✓ | ✓ |
+| [Projects](project/index.md):<br>Enable Review Apps | | | ✓ | ✓ | ✓ |
+| [Projects](project/index.md):<br>View project [Audit Events](../administration/audit_events.md) | | | ✓ (*10*) | ✓ | ✓ |
+| [Projects](project/index.md):<br>Add deploy keys | | | | ✓ | ✓ |
+| [Projects](project/index.md):<br>Add new team members | | | | ✓ | ✓ |
+| [Projects](project/index.md):<br>Change [project features visibility](../public_access/public_access.md) level | | | | ✓ (*13*) | ✓ |
+| [Projects](project/index.md):<br>Configure [webhooks](project/integrations/webhooks.md) | | | | ✓ | ✓ |
+| [Projects](project/index.md):<br>Delete [wiki](project/wiki/index.md) pages | | | ✓ | ✓ | ✓ |
+| [Projects](project/index.md):<br>Edit comments (posted by any user) | | | | ✓ | ✓ |
+| [Projects](project/index.md):<br>Edit project badges | | | | ✓ | ✓ |
+| [Projects](project/index.md):<br>Edit project settings | | | | ✓ | ✓ |
+| [Projects](project/index.md):<br>Export project | | | | ✓ | ✓ |
+| [Projects](project/index.md):<br>Manage [project access tokens](project/settings/project_access_tokens.md) (*11*) | | | | ✓ | ✓ |
+| [Projects](project/index.md):<br>Manage [Project Operations](../operations/index.md) | | | | ✓ | ✓ |
+| [Projects](project/index.md):<br>Rename project | | | | ✓ | ✓ |
+| [Projects](project/index.md):<br>Share (invite) projects with groups | | | | ✓ (*7*) | ✓ (*7*) |
+| [Projects](project/index.md):<br>View 2FA status of members | | | | ✓ | ✓ |
+| [Projects](project/index.md):<br>Administer project compliance frameworks | | | | | ✓ |
+| [Projects](project/index.md):<br>Archive project | | | | | ✓ |
+| [Projects](project/index.md):<br>Change project visibility level | | | | | ✓ |
+| [Projects](project/index.md):<br>Delete project | | | | | ✓ |
+| [Projects](project/index.md):<br>Disable notification emails | | | | | ✓ |
+| [Projects](project/index.md):<br>Transfer project to another namespace | | | | | ✓ |
+| [Repository](project/repository/index.md):<br>Pull project code | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ |
+| [Repository](project/repository/index.md):<br>View project code | ✓ (*1*) | ✓ | ✓ | ✓ | ✓ |
+| [Repository](project/repository/index.md):<br>View a commit status | | ✓ | ✓ | ✓ | ✓ |
+| [Repository](project/repository/index.md):<br>Add tags | | | ✓ | ✓ | ✓ |
+| [Repository](project/repository/index.md):<br>Create new branches | | | ✓ | ✓ | ✓ |
+| [Repository](project/repository/index.md):<br>Create or update commit status | | | ✓ (*4*) | ✓ | ✓ |
+| [Repository](project/repository/index.md):<br>Force push to non-protected branches | | | ✓ | ✓ | ✓ |
+| [Repository](project/repository/index.md):<br>Push to non-protected branches | | | ✓ | ✓ | ✓ |
+| [Repository](project/repository/index.md):<br>Remove non-protected branches | | | ✓ | ✓ | ✓ |
+| [Repository](project/repository/index.md):<br>Rewrite or remove Git tags | | | ✓ | ✓ | ✓ |
+| [Repository](project/repository/index.md):<br>Enable or disable branch protection | | | | ✓ | ✓ |
+| [Repository](project/repository/index.md):<br>Enable or disable tag protection | | | | ✓ | ✓ |
+| [Repository](project/repository/index.md):<br>Manage [push rules](project/repository/push_rules.md) | | | | ✓ | ✓ |
+| [Repository](project/repository/index.md):<br>Push to protected branches (*4*) | | | | ✓ | ✓ |
+| [Repository](project/repository/index.md):<br>Turn on or off protected branch push for developers | | | | ✓ | ✓ |
+| [Repository](project/repository/index.md):<br>Remove fork relationship | | | | | ✓ |
+| [Repository](project/repository/index.md):<br>Force push to protected branches (*3*) | | | | | |
+| [Repository](project/repository/index.md):<br>Remove protected branches (*3*) | | | | | |
+| [Requirements Management](project/requirements/index.md):<br>Archive / reopen | | ✓ | ✓ | ✓ | ✓ |
+| [Requirements Management](project/requirements/index.md):<br>Create / edit | | ✓ | ✓ | ✓ | ✓ |
+| [Requirements Management](project/requirements/index.md):<br>Import / export | | ✓ | ✓ | ✓ | ✓ |
+| [Security dashboard](application_security/security_dashboard/index.md):<br>Create issue from vulnerability finding | | | ✓ | ✓ | ✓ |
+| [Security dashboard](application_security/security_dashboard/index.md):<br>Create vulnerability from vulnerability finding | | | ✓ | ✓ | ✓ |
+| [Security dashboard](application_security/security_dashboard/index.md):<br>Dismiss vulnerability | | | ✓ | ✓ | ✓ |
+| [Security dashboard](application_security/security_dashboard/index.md):<br>Dismiss vulnerability finding | | | ✓ | ✓ | ✓ |
+| [Security dashboard](application_security/security_dashboard/index.md):<br>Resolve vulnerability | | | ✓ | ✓ | ✓ |
+| [Security dashboard](application_security/security_dashboard/index.md):<br>Revert vulnerability to detected state | | | ✓ | ✓ | ✓ |
+| [Security dashboard](application_security/security_dashboard/index.md):<br>Use security dashboard | | | ✓ | ✓ | ✓ |
+| [Security dashboard](application_security/security_dashboard/index.md):<br>View vulnerability | | | ✓ | ✓ | ✓ |
+| [Security dashboard](application_security/security_dashboard/index.md):<br>View vulnerability findings in [dependency list](application_security/dependency_list/index.md) | | | ✓ | ✓ | ✓ |
+| [Terraform](infrastructure/index.md):<br>Read Terraform state | | | ✓ | ✓ | ✓ |
+| [Terraform](infrastructure/index.md):<br>Manage Terraform state | | | | ✓ | ✓ |
+| [Test cases](../ci/test_cases/index.md):<br>Archive | | ✓ | ✓ | ✓ | ✓ |
+| [Test cases](../ci/test_cases/index.md):<br>Create | | ✓ | ✓ | ✓ | ✓ |
+| [Test cases](../ci/test_cases/index.md):<br>Move | | ✓ | ✓ | ✓ | ✓ |
+| [Test cases](../ci/test_cases/index.md):<br>Reopen | | ✓ | ✓ | ✓ | ✓ |
<!-- markdownlint-disable MD029 -->
@@ -243,33 +251,33 @@ More details about the permissions for some project-level features follow.
- [Pipeline visibility](../ci/enable_or_disable_ci.md#enable-cicd-in-a-project): When set to **Everyone with Access**,
gives access to certain CI/CD "view" features to *non-project* members.
-| Action | Non-member | Guest | Reporter | Developer | Maintainer | Owner |
-|-----------------------------------------------------------------------------------|------------|---------|----------|-----------|------------|-------|
-| See that artifacts exist | ✓ (*3*) | ✓ (*3*) | ✓ | ✓ | ✓ | ✓ |
-| View a list of jobs | ✓ (*1*) | ✓ (*2*) | ✓ | ✓ | ✓ | ✓ |
-| View and download artifacts | ✓ (*1*) | ✓ (*2*) | ✓ | ✓ | ✓ | ✓ |
-| View [environments](../ci/environments/index.md) | ✓ (*3*) | ✓ (*3*) | ✓ | ✓ | ✓ | ✓ |
-| View job logs and job details page | ✓ (*1*) | ✓ (*2*) | ✓ | ✓ | ✓ | ✓ |
-| View pipeline details page | ✓ (*1*) | ✓ (*2*) | ✓ | ✓ | ✓ | ✓ |
-| View pipelines page | ✓ (*1*) | ✓ (*2*) | ✓ | ✓ | ✓ | ✓ |
-| View pipelines tab in MR | ✓ (*3*) | ✓ (*3*) | ✓ | ✓ | ✓ | ✓ |
-| [View vulnerabilities in a pipeline](application_security/security_dashboard/index.md#view-vulnerabilities-in-a-pipeline) | | ✓ (*2*) | ✓ | ✓ | ✓ | ✓ |
-| Cancel and retry jobs | | | | ✓ | ✓ | ✓ |
-| Create new [environments](../ci/environments/index.md) | | | | ✓ | ✓ | ✓ |
-| Delete job logs or job artifacts | | | | ✓ (*4*) | ✓ | ✓ |
-| Run CI/CD pipeline for a protected branch | | | | ✓ (*5*) | ✓ (*5*) | ✓ |
-| Stop [environments](../ci/environments/index.md) | | | | ✓ | ✓ | ✓ |
-| View a job with [debug logging](../ci/variables/index.md#debug-logging) | | | | ✓ | ✓ | ✓ |
-| Use pipeline editor | | | | ✓ | ✓ | ✓ |
-| Add specific runners to project | | | | | ✓ | ✓ |
-| Clear runner caches manually | | | | | ✓ | ✓ |
-| Enable shared runners in project | | | | | ✓ | ✓ |
-| Manage CI/CD settings | | | | | ✓ | ✓ |
-| Manage job triggers | | | | | ✓ | ✓ |
-| Manage project-level CI/CD variables | | | | | ✓ | ✓ |
-| Run [interactive web terminals](../ci/interactive_web_terminal/index.md) | | | | | ✓ | ✓ |
-| Use [environment terminals](../ci/environments/index.md#web-terminals-deprecated) | | | | | ✓ | ✓ |
-| Delete pipelines | | | | | | ✓ |
+| Action | Non-member | Guest | Reporter | Developer | Maintainer | Owner |
+|---------------------------------------------------------------------------------------------------------------------------|------------|---------|----------|-----------|------------|-------|
+| See that artifacts exist | ✓ (*3*) | ✓ (*3*) | ✓ | ✓ | ✓ | ✓ |
+| View a list of jobs | ✓ (*1*) | ✓ (*2*) | ✓ | ✓ | ✓ | ✓ |
+| View and download artifacts | ✓ (*1*) | ✓ (*2*) | ✓ | ✓ | ✓ | ✓ |
+| View [environments](../ci/environments/index.md) | ✓ (*3*) | ✓ (*3*) | ✓ | ✓ | ✓ | ✓ |
+| View job logs and job details page | ✓ (*1*) | ✓ (*2*) | ✓ | ✓ | ✓ | ✓ |
+| View pipeline details page | ✓ (*1*) | ✓ (*2*) | ✓ | ✓ | ✓ | ✓ |
+| View pipelines page | ✓ (*1*) | ✓ (*2*) | ✓ | ✓ | ✓ | ✓ |
+| View pipelines tab in MR | ✓ (*3*) | ✓ (*3*) | ✓ | ✓ | ✓ | ✓ |
+| [View vulnerabilities in a pipeline](application_security/security_dashboard/index.md#view-vulnerabilities-in-a-pipeline) | | ✓ (*2*) | ✓ | ✓ | ✓ | ✓ |
+| Cancel and retry jobs | | | | ✓ | ✓ | ✓ |
+| Create new [environments](../ci/environments/index.md) | | | | ✓ | ✓ | ✓ |
+| Delete job logs or job artifacts | | | | ✓ (*4*) | ✓ | ✓ |
+| Run CI/CD pipeline for a protected branch | | | | ✓ (*5*) | ✓ (*5*) | ✓ |
+| Stop [environments](../ci/environments/index.md) | | | | ✓ | ✓ | ✓ |
+| View a job with [debug logging](../ci/variables/index.md#debug-logging) | | | | ✓ | ✓ | ✓ |
+| Use pipeline editor | | | | ✓ | ✓ | ✓ |
+| Run [interactive web terminals](../ci/interactive_web_terminal/index.md) | | | | ✓ | ✓ | ✓ |
+| Add specific runners to project | | | | | ✓ | ✓ |
+| Clear runner caches manually | | | | | ✓ | ✓ |
+| Enable shared runners in project | | | | | ✓ | ✓ |
+| Manage CI/CD settings | | | | | ✓ | ✓ |
+| Manage job triggers | | | | | ✓ | ✓ |
+| Manage project-level CI/CD variables | | | | | ✓ | ✓ |
+| Use [environment terminals](../ci/environments/index.md#web-terminals-deprecated) | | | | | ✓ | ✓ |
+| Delete pipelines | | | | | | ✓ |
<!-- markdownlint-disable MD029 -->
@@ -288,20 +296,20 @@ More details about the permissions for some project-level features follow.
This table shows granted privileges for jobs triggered by specific types of users:
-| Action | Guest, Reporter | Developer | Maintainer| Administrator |
-|---------------------------------------------|-----------------|-----------|-----------|---------------|
-| Run CI job | | ✓ | ✓ | ✓ |
-| Clone source and LFS from current project | | ✓ | ✓ | ✓ |
-| Clone source and LFS from public projects | | ✓ | ✓ | ✓ |
-| Clone source and LFS from internal projects | | ✓ (*1*) | ✓ (*1*) | ✓ |
-| Clone source and LFS from private projects | | ✓ (*2*) | ✓ (*2*) | ✓ (*2*) |
-| Pull container images from current project | | ✓ | ✓ | ✓ |
-| Pull container images from public projects | | ✓ | ✓ | ✓ |
-| Pull container images from internal projects| | ✓ (*1*) | ✓ (*1*) | ✓ |
-| Pull container images from private projects | | ✓ (*2*) | ✓ (*2*) | ✓ (*2*) |
-| Push container images to current project | | ✓ | ✓ | ✓ |
-| Push container images to other projects | | | | |
-| Push source and LFS | | | | |
+| Action | Guest, Reporter | Developer | Maintainer | Administrator |
+|----------------------------------------------|-----------------|-----------|------------|---------------|
+| Run CI job | | ✓ | ✓ | ✓ |
+| Clone source and LFS from current project | | ✓ | ✓ | ✓ |
+| Clone source and LFS from public projects | | ✓ | ✓ | ✓ |
+| Clone source and LFS from internal projects | | ✓ (*1*) | ✓ (*1*) | ✓ |
+| Clone source and LFS from private projects | | ✓ (*2*) | ✓ (*2*) | ✓ (*2*) |
+| Pull container images from current project | | ✓ | ✓ | ✓ |
+| Pull container images from public projects | | ✓ | ✓ | ✓ |
+| Pull container images from internal projects | | ✓ (*1*) | ✓ (*1*) | ✓ |
+| Pull container images from private projects | | ✓ (*2*) | ✓ (*2*) | ✓ (*2*) |
+| Push container images to current project | | ✓ | ✓ | ✓ |
+| Push container images to other projects | | | | |
+| Push source and LFS | | | | |
1. Only if the triggering user is not an external one.
1. Only if the triggering user is a member of the project.
@@ -327,7 +335,7 @@ to learn more.
### Value stream analytics permissions
Find the current permissions on the value stream analytics dashboard, as described in
-[related documentation](analytics/value_stream_analytics.md#permissions).
+[related documentation](analytics/value_stream_analytics.md#access-permissions-for-value-stream-analytics).
### Issue board permissions
@@ -361,64 +369,64 @@ The following table lists group permissions available for each role:
<!-- Keep this table sorted: first, by minimum role, then alphabetically. -->
-| Action | Guest | Reporter | Developer | Maintainer | Owner |
-|--------------------------------------------------------------------------|-------|----------|-----------|------------|-------|
-| Browse group | ✓ | ✓ | ✓ | ✓ | ✓ |
-| Pull a container image using the dependency proxy | ✓ | ✓ | ✓ | ✓ | ✓ |
-| View Contribution analytics | ✓ | ✓ | ✓ | ✓ | ✓ |
-| View group epic **(PREMIUM)** | ✓ | ✓ | ✓ | ✓ | ✓ |
-| View group wiki pages **(PREMIUM)** | ✓ (6) | ✓ | ✓ | ✓ | ✓ |
-| View Insights **(ULTIMATE)** | ✓ | ✓ | ✓ | ✓ | ✓ |
-| View Insights charts **(ULTIMATE)** | ✓ | ✓ | ✓ | ✓ | ✓ |
-| View Issue analytics **(PREMIUM)** | ✓ | ✓ | ✓ | ✓ | ✓ |
-| View value stream analytics | ✓ | ✓ | ✓ | ✓ | ✓ |
-| Create/edit group epic **(PREMIUM)** | | ✓ | ✓ | ✓ | ✓ |
-| Create/edit/delete epic boards **(PREMIUM)** | | ✓ | ✓ | ✓ | ✓ |
-| Manage group labels | | ✓ | ✓ | ✓ | ✓ |
-| Publish [packages](packages/index.md) | | | ✓ | ✓ | ✓ |
-| Pull [packages](packages/index.md) | | ✓ | ✓ | ✓ | ✓ |
-| Delete [packages](packages/index.md | | | | ✓ | ✓ |
-| Pull a Container Registry image | ✓ (7) | ✓ | ✓ | ✓ | ✓ |
-| Remove a Container Registry image | | | ✓ | ✓ | ✓ |
-| View Group DevOps Adoption **(ULTIMATE)** | | ✓ | ✓ | ✓ | ✓ |
-| View metrics dashboard annotations | | ✓ | ✓ | ✓ | ✓ |
-| View Productivity analytics **(PREMIUM)** | | ✓ | ✓ | ✓ | ✓ |
-| Create and edit group wiki pages **(PREMIUM)** | | | ✓ | ✓ | ✓ |
-| Create project in group | | | ✓ (3)(5) | ✓ (3) | ✓ (3) |
-| Create/edit/delete group milestones | | | ✓ | ✓ | ✓ |
-| Create/edit/delete iterations | | | ✓ | ✓ | ✓ |
-| Create/edit/delete metrics dashboard annotations | | | ✓ | ✓ | ✓ |
-| Enable/disable a dependency proxy | | | ✓ | ✓ | ✓ |
-| Purge the dependency proxy for a group | | | | | ✓ |
-| Use security dashboard **(ULTIMATE)** | | | ✓ | ✓ | ✓ |
-| View group Audit Events | | | ✓ (7) | ✓ (7) | ✓ |
-| Create subgroup | | | | ✓ (1) | ✓ |
-| Delete group wiki pages **(PREMIUM)** | | | ✓ | ✓ | ✓ |
-| Edit epic comments (posted by any user) **(ULTIMATE)** | | | | ✓ (2) | ✓ (2) |
-| List group deploy tokens | | | | ✓ | ✓ |
-| Manage [group push rules](group/index.md#group-push-rules) **(PREMIUM)** | | | | ✓ | ✓ |
-| View/manage group-level Kubernetes cluster | | | | ✓ | ✓ |
-| Administer project compliance frameworks | | | | | ✓ |
-| Create/Delete group deploy tokens | | | | | ✓ |
-| Change group visibility level | | | | | ✓ |
-| Delete group | | | | | ✓ |
-| Delete group epic **(PREMIUM)** | | | | | ✓ |
-| Disable notification emails | | | | | ✓ |
-| Edit group settings | | | | | ✓ |
-| Edit SAML SSO **(PREMIUM SAAS)** | | | | | ✓ (4) |
-| Filter members by 2FA status | | | | | ✓ |
-| Manage group level CI/CD variables | | | | | ✓ |
-| Manage group members | | | | | ✓ |
-| Share (invite) groups with groups | | | | | ✓ |
-| View 2FA status of members | | | | | ✓ |
-| View Billing **(FREE SAAS)** | | | | | ✓ (4) |
-| View Usage Quotas **(FREE SAAS)** | | | | | ✓ (4) |
-| Manage runners | | | | | ✓ |
+| Action | Guest | Reporter | Developer | Maintainer | Owner |
+|-----------------------------------------------------------------------------------------|-------|----------|-----------|------------|-------|
+| Browse group | ✓ | ✓ | ✓ | ✓ | ✓ |
+| Pull a container image using the dependency proxy | ✓ | ✓ | ✓ | ✓ | ✓ |
+| View Contribution analytics | ✓ | ✓ | ✓ | ✓ | ✓ |
+| View group [epic](group/epics/index.md) | ✓ | ✓ | ✓ | ✓ | ✓ |
+| View [group wiki](project/wiki/group.md) pages | ✓ (6) | ✓ | ✓ | ✓ | ✓ |
+| View [Insights](project/insights/index.md) | ✓ | ✓ | ✓ | ✓ | ✓ |
+| View [Insights](project/insights/index.md) charts | ✓ | ✓ | ✓ | ✓ | ✓ |
+| View [Issue analytics](analytics/issue_analytics.md) | ✓ | ✓ | ✓ | ✓ | ✓ |
+| View value stream analytics | ✓ | ✓ | ✓ | ✓ | ✓ |
+| Create/edit group [epic](group/epics/index.md) | | ✓ | ✓ | ✓ | ✓ |
+| Create/edit/delete [epic boards](group/epics/epic_boards.md) | | ✓ | ✓ | ✓ | ✓ |
+| Manage group labels | | ✓ | ✓ | ✓ | ✓ |
+| Publish [packages](packages/index.md) | | | ✓ | ✓ | ✓ |
+| Pull [packages](packages/index.md) | | ✓ | ✓ | ✓ | ✓ |
+| Delete [packages](packages/index.md) | | | | ✓ | ✓ |
+| Pull a Container Registry image | ✓ (7) | ✓ | ✓ | ✓ | ✓ |
+| Remove a Container Registry image | | | ✓ | ✓ | ✓ |
+| View [Group DevOps Adoption](group/devops_adoption/index.md) | | ✓ | ✓ | ✓ | ✓ |
+| View metrics dashboard annotations | | ✓ | ✓ | ✓ | ✓ |
+| View [Productivity analytics](analytics/productivity_analytics.md) | | ✓ | ✓ | ✓ | ✓ |
+| View Usage quota data | | ✓ | ✓ | ✓ | ✓ |
+| Create and edit [group wiki](project/wiki/group.md) pages | | | ✓ | ✓ | ✓ |
+| Create project in group | | | ✓ (3)(5) | ✓ (3) | ✓ (3) |
+| Create/edit/delete group milestones | | | ✓ | ✓ | ✓ |
+| Create/edit/delete iterations | | | ✓ | ✓ | ✓ |
+| Create/edit/delete metrics dashboard annotations | | | ✓ | ✓ | ✓ |
+| Enable/disable a dependency proxy | | | ✓ | ✓ | ✓ |
+| Purge the dependency proxy for a group | | | | | ✓ |
+| Use [security dashboard](application_security/security_dashboard/index.md) | | | ✓ | ✓ | ✓ |
+| View group Audit Events | | | ✓ (7) | ✓ (7) | ✓ |
+| Create subgroup | | | | ✓ (1) | ✓ |
+| Delete [group wiki](project/wiki/group.md) pages | | | ✓ | ✓ | ✓ |
+| Edit [epic](group/epics/index.md) comments (posted by any user) | | | | ✓ (2) | ✓ (2) |
+| List group deploy tokens | | | | ✓ | ✓ |
+| Manage [group push rules](group/index.md#group-push-rules) | | | | ✓ | ✓ |
+| View/manage group-level Kubernetes cluster | | | | ✓ | ✓ |
+| Administer project compliance frameworks | | | | | ✓ |
+| Create/Delete group deploy tokens | | | | | ✓ |
+| Change group visibility level | | | | | ✓ |
+| Delete group | | | | | ✓ |
+| Delete group [epic](group/epics/index.md) | | | | | ✓ |
+| Disable notification emails | | | | | ✓ |
+| Edit group settings | | | | | ✓ |
+| Edit [SAML SSO](group/saml_sso/index.md) | | | | | ✓ (4) |
+| Filter members by 2FA status | | | | | ✓ |
+| Manage group level CI/CD variables | | | | | ✓ |
+| Manage group members | | | | | ✓ |
+| Share (invite) groups with groups | | | | | ✓ |
+| View 2FA status of members | | | | | ✓ |
+| View [Billing](../subscriptions/gitlab_com/index.md#view-your-gitlab-saas-subscription) | | | | | ✓ (4) |
+| View [Usage Quotas](usage_quotas.md) Page | | | | ✓ | ✓ (4) |
+| Manage runners | | | | | ✓ |
<!-- markdownlint-disable MD029 -->
-1. Groups can be set to [allow either Owners or Owners and
- Maintainers to create subgroups](group/subgroups/index.md#creating-a-subgroup)
+1. Groups can be set to allow either Owners, or Owners and users with the Maintainer role, to [create subgroups](group/subgroups/index.md#create-a-subgroup).
2. Introduced in GitLab 12.2.
3. Default project creation role can be changed at:
- The [instance level](admin_area/settings/visibility_and_access_controls.md#define-which-roles-can-create-projects).
@@ -437,7 +445,7 @@ permission level from the parent group(s). This model allows access to
nested groups if you have membership in one of its parents.
To learn more, read through the documentation on
-[subgroups memberships](group/subgroups/index.md#membership).
+[subgroups memberships](group/subgroups/index.md#subgroup-membership).
## External users **(FREE SELF)**
@@ -478,7 +486,7 @@ An administrator can flag a user as external by either of the following methods:
1. On the left sidebar, select **Overview > Users** to create a new user or edit an existing one.
There, you can find the option to flag the user as external.
-Additionally users can be set as external users using:
+Additionally, users can be set as external users using:
- [SAML groups](../integration/saml.md#external-groups).
- [LDAP groups](../administration/auth/ldap/ldap_synchronization.md#external-groups).
@@ -543,7 +551,7 @@ with the permissions described on the documentation on [auditor users permission
## Users with minimal access **(PREMIUM)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/40942) in [GitLab Premium](https://about.gitlab.com/pricing/) 13.4.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/40942) in GitLab 13.4.
Owners can add members with a "minimal access" role to a parent group. Such users don't automatically have access to
projects and subgroups underneath. Owners must explicitly add these "minimal access" users to the specific subgroups and
diff --git a/doc/user/profile/account/delete_account.md b/doc/user/profile/account/delete_account.md
index c116b1fc00d..3f5554b80ac 100644
--- a/doc/user/profile/account/delete_account.md
+++ b/doc/user/profile/account/delete_account.md
@@ -5,7 +5,7 @@ group: Authentication and Authorization
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
-# Deleting a User account **(FREE)**
+# Deleting a user account **(FREE)**
Users can be deleted from a GitLab instance, either by:
@@ -15,7 +15,7 @@ Users can be deleted from a GitLab instance, either by:
NOTE:
Deleting a user deletes all projects in that user namespace.
-## As a user
+## Delete your own account
As a user, to delete your own account:
@@ -24,7 +24,7 @@ As a user, to delete your own account:
1. On the left sidebar, select **Account**.
1. Select **Delete account**.
-## As an administrator **(FREE SELF)**
+## Delete users and user contributions **(FREE SELF)**
As an administrator, to delete a user account:
@@ -32,55 +32,40 @@ As an administrator, to delete a user account:
1. On the left sidebar, select **Overview > Users**.
1. Select a user.
1. Under the **Account** tab, select:
- - **Delete user** to delete only the user but maintain their
- [associated records](#associated-records).
- - **Delete user and contributions** to delete the user and
- their associated records.
+ - **Delete user** to delete only the user but maintain their [associated records](#associated-records). You can't use this option if
+ the selected user is the sole owner of any groups.
+ - **Delete user and contributions** to delete the user and their associated records. This option also removes all groups (and
+ projects within these groups) where the user is the sole direct Owner of a group. Inherited ownership doesn't apply.
WARNING:
-Using the **Delete user and contributions** option may result
-in removing more data than intended. Please see [associated records](#associated-records)
-below for additional details.
+Using the **Delete user and contributions** option may result in removing more data than intended. See
+[associated records](#associated-records) for additional details.
### Associated records
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/7393) for issues in GitLab 9.0.
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/10467) for merge requests, award emoji, notes, and abuse reports in GitLab 9.1.
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/10273) hard deletion from abuse reports and spam logs in GitLab 9.1.
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/11853) hard deletion from the API in GitLab 9.3.
-
-There are two options for deleting users:
-
-- **Delete user**
-- **Delete user and contributions**
-
-When using the **Delete user** option, not all associated records are deleted with the user.
-Here's a list of things created by the user that are **not** deleted:
-
-- Abuse reports
-- Award emoji
-- Epics
-- Issues
-- Merge requests
-- Notes
-
-Instead of being deleted, these records are moved to a system-wide
-user with the username Ghost User, whose sole purpose is to act as a container
-for such records. Any commits made by a deleted user still display the
-username of the original user.
-
-When using the **Delete user and contributions** option, **all** associated records
-are removed. This includes all of the items mentioned above including issues,
-merge requests, notes/comments, and more. Consider
-[blocking a user](../../admin_area/moderate_users.md#block-a-user)
-or using the **Delete user** option instead.
-
-When a user is deleted from an [abuse report](../../admin_area/review_abuse_reports.md)
-or spam log, these associated
-records are not ghosted and are removed, along with any groups the user
-is a sole owner of. Administrators can also request this behavior when
-deleting users from the [API](../../../api/users.md#user-deletion) or the
-Admin Area.
+When deleting users, you can either:
+
+- Delete just the user. Not all associated records are deleted with the user. Instead of being deleted, these records
+ are moved to a system-wide user with the username Ghost User. The Ghost User's purpose is to act as a container for
+ such records. Any commits made by a deleted user still display the username of the original user.
+- Delete the user and their contributions, including:
+ - Abuse reports.
+ - Award emojis.
+ - Epics.
+ - Groups of which the user is the only user with the Owner role.
+ - Issues.
+ - Merge requests.
+ - Notes and comments.
+ - Personal access tokens.
+ - Snippets.
+
+An alternative to deleting is [blocking a user](../../admin_area/moderate_users.md#block-a-user).
+
+When a user is deleted from an [abuse report](../../admin_area/review_abuse_reports.md) or spam log, these associated
+records are always removed.
+
+The deleting associated records option can be requested in the [API](../../../api/users.md#user-deletion) as well as
+the Admin Area.
## Troubleshooting
diff --git a/doc/user/profile/img/personal_readme_setup_v14_5.png b/doc/user/profile/img/personal_readme_setup_v14_5.png
index 92d8e0ec936..6a776506ac6 100644
--- a/doc/user/profile/img/personal_readme_setup_v14_5.png
+++ b/doc/user/profile/img/personal_readme_setup_v14_5.png
Binary files differ
diff --git a/doc/user/profile/notifications.md b/doc/user/profile/notifications.md
index acbaf62579f..4c9622810b2 100644
--- a/doc/user/profile/notifications.md
+++ b/doc/user/profile/notifications.md
@@ -184,6 +184,7 @@ Users are notified of the following events:
| Password changed | User | Security email, always sent when user changes their own password. |
| Password changed by administrator | User | Security email, always sent when an administrator changes the password of another user. |
| Personal access tokens expiring soon | User | Security email, always sent. |
+| Personal access tokens have been created | User | Security email, always sent. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/337591) in GitLab 14.9. |
| Personal access tokens have expired | User | Security email, always sent. |
| Project access level changed | User | Sent when user project access level is changed. |
| SSH key has expired | User | Security email, always sent. _[Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/322637) in GitLab 13.12._ |
diff --git a/doc/user/profile/personal_access_tokens.md b/doc/user/profile/personal_access_tokens.md
index 10d718fdf1a..1fbbe438370 100644
--- a/doc/user/profile/personal_access_tokens.md
+++ b/doc/user/profile/personal_access_tokens.md
@@ -25,8 +25,8 @@ Personal access tokens are:
- Used with a GitLab username to authenticate with GitLab features that require usernames. For example,
[GitLab managed Terraform state backend](../infrastructure/iac/terraform_state.md#using-a-gitlab-managed-terraform-state-backend-as-a-remote-data-source)
and [Docker container registry](../packages/container_registry/index.md#authenticate-with-the-container-registry),
-- Similar to [project access tokens](../project/settings/project_access_tokens.md), but are attached
- to a user rather than a project.
+- Similar to [project access tokens](../project/settings/project_access_tokens.md) and [group access tokens](../group/settings/group_access_tokens.md), but are attached
+ to a user rather than a project or group.
NOTE:
Though required, GitLab usernames are ignored when authenticating with a personal access token.
diff --git a/doc/user/profile/preferences.md b/doc/user/profile/preferences.md
index 52baf5189e1..48160bb97ac 100644
--- a/doc/user/profile/preferences.md
+++ b/doc/user/profile/preferences.md
@@ -39,7 +39,7 @@ The default theme is Indigo. You can choose between 10 themes:
## Dark mode
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/28252) in GitLab 13.1 as an Alpha release.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/28252) in GitLab 13.1 as an [Alpha](../../policy/alpha-beta-support.md#alpha-features) 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
diff --git a/doc/user/project/badges.md b/doc/user/project/badges.md
index 79d395d51c3..2f9e04fb828 100644
--- a/doc/user/project/badges.md
+++ b/doc/user/project/badges.md
@@ -9,7 +9,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
Badges are a unified way to present condensed pieces of information about your
projects. They consist of a small image and a URL that the image
points to. Examples for badges can be the [pipeline status](../../ci/pipelines/settings.md#pipeline-status-badge),
-[test coverage](../../ci/pipelines/settings.md#test-coverage-report-badge), or ways to contact the
+[test coverage](../../ci/pipelines/settings.md#test-coverage-report-badge), [latest release](../../ci/pipelines/settings.md#latest-release-badge), or ways to contact the
project maintainers.
![Badges on Project information page](img/project_overview_badges_v13_10.png)
diff --git a/doc/user/project/canary_deployments.md b/doc/user/project/canary_deployments.md
index 77cf04cc7eb..344caed7449 100644
--- a/doc/user/project/canary_deployments.md
+++ b/doc/user/project/canary_deployments.md
@@ -6,8 +6,8 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Canary Deployments **(FREE)**
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/1659) in [GitLab Premium](https://about.gitlab.com/pricing/) 9.1.
-> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/212320) to GitLab Free in 13.8.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/1659) in GitLab 9.1.
+> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/212320) from GitLab Premium to GitLab Free in 13.8.
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
@@ -35,7 +35,7 @@ your pods fleet and watch their behavior as a percentage of your user base
visits the temporarily deployed feature. If all works well, you can deploy the
feature to production knowing that it shouldn't cause any problems.
-Canary deployments are also especially useful for backend refactors, performance
+Canary deployments are also especially required for backend refactors, performance
improvements, or other changes where the user interface doesn't change, but you
want to make sure the performance stays the same, or improves. Developers need
to be careful when using canaries with user-facing changes, because by default,
@@ -50,7 +50,7 @@ this document.
Canary deployments require that you properly configure deploy boards:
1. Follow the steps to [enable deploy boards](deploy_boards.md#enabling-deploy-boards).
-1. To track canary deployments you need to label your Kubernetes deployments and
+1. To track canary deployments you must label your Kubernetes deployments and
pods with `track: canary`. To get started quickly, you can use the [Auto Deploy](../../topics/autodevops/stages.md#auto-deploy)
template for canary deployments that GitLab provides.
@@ -60,19 +60,19 @@ Any other track label is considered `canary` (temporary).
This allows GitLab to discover whether a deployment is stable or canary (temporary).
Once all of the above are set up and the pipeline has run at least once,
-navigate to the environments page under **Pipelines > Environments**.
+Go to the environments page under **Pipelines > Environments**.
As the pipeline executes, deploy boards clearly mark canary pods, enabling
-quick and easy insight into the status of each environment and deployment.
+quick and clear insight into the status of each environment and deployment.
Canary deployments are marked with a yellow dot in the deploy board so that you
-can easily notice them.
+can quickly notice them.
![Canary deployments on deploy board](img/deploy_boards_canary_deployments.png)
### Advanced traffic control with Canary Ingress (DEPRECATED)
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/215501) in [GitLab Premium](https://about.gitlab.com/pricing/) 13.6.
-> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/212320) to Free in GitLab 13.8.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/215501) in GitLab 13.6.
+> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/212320) from GitLab Premium to GitLab Free in 13.8.
> - [Deprecated](https://gitlab.com/groups/gitlab-org/configure/-/epics/8) in GitLab 14.5.
WARNING:
@@ -82,7 +82,7 @@ Canary deployments can be more strategic with [Canary Ingress](https://kubernete
which is an advanced traffic routing service that controls incoming HTTP
requests between stable and canary deployments based on factors such as weight, sessions, cookies,
and others. GitLab uses this service in its [Auto Deploy architecture](../../topics/autodevops/upgrading_auto_deploy_dependencies.md#v2-chart-resource-architecture)
-to let users easily and safely roll out their new deployments.
+to let users quickly and safely roll out their new deployments.
#### How to set up a Canary Ingress in a canary deployment
@@ -115,13 +115,13 @@ Here's an example setup flow from scratch:
#### How to change the traffic weight on a Canary Ingress
-You can change the traffic weight within your environment's deploy board by using [GraphiQL](../../api/graphql/getting_started.md#graphiql),
+You can change the traffic weight in your environment's deploy board by using [GraphiQL](../../api/graphql/getting_started.md#graphiql),
or by sending requests to the [GraphQL API](../../api/graphql/getting_started.md#command-line).
To use your [deploy board](../../user/project/deploy_boards.md):
-1. Navigate to **Deployments > Environments** for your project.
-1. Set the new weight with the dropdown on the right side.
+1. Go to **Deployments > Environments** for your project.
+1. Set the new weight with the dropdown list on the right side.
1. Confirm your selection.
Here's an example using [GraphiQL](../../api/graphql/getting_started.md#graphiql):
diff --git a/doc/user/project/clusters/add_eks_clusters.md b/doc/user/project/clusters/add_eks_clusters.md
index e14a71a7e10..82106c9d1a9 100644
--- a/doc/user/project/clusters/add_eks_clusters.md
+++ b/doc/user/project/clusters/add_eks_clusters.md
@@ -10,7 +10,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
> - [Deprecated](https://gitlab.com/groups/gitlab-org/configure/-/epics/8) in GitLab 14.5.
WARNING:
-This feature was deprecated in GitLab 14.5. Use [Infrastructure as Code](../../infrastructure/iac/index.md#create-a-new-cluster-through-iac-deprecated)
+This feature was deprecated in GitLab 14.5. Use [Infrastructure as Code](../../infrastructure/iac/index.md#create-a-new-cluster-through-iac)
to create new clusters.
Through GitLab, you can create new clusters and add existing clusters hosted on Amazon Elastic
@@ -19,11 +19,11 @@ Kubernetes Service (EKS).
## Connect an existing EKS cluster
If you already have an EKS cluster and want to connect it to GitLab,
-use the [GitLab Agent](../../clusters/agent/index.md).
+use the [GitLab agent](../../clusters/agent/index.md).
## Create a new EKS cluster
-To create a new cluster from GitLab, use [Infrastructure as Code](../../infrastructure/iac/index.md#create-a-new-cluster-through-iac-deprecated).
+To create a new cluster from GitLab, use [Infrastructure as Code](../../infrastructure/iac/index.md#create-a-new-cluster-through-iac).
### How to create a new cluster on EKS through cluster certificates (DEPRECATED)
diff --git a/doc/user/project/clusters/add_existing_cluster.md b/doc/user/project/clusters/add_existing_cluster.md
index 0c3827bcbb1..f2d537513b7 100644
--- a/doc/user/project/clusters/add_existing_cluster.md
+++ b/doc/user/project/clusters/add_existing_cluster.md
@@ -10,7 +10,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
WARNING:
This feature was [deprecated](https://gitlab.com/groups/gitlab-org/configure/-/epics/8) in GitLab 14.5.
-To connect your cluster to GitLab, use the [GitLab Agent](../../clusters/agent/index.md)
+To connect your cluster to GitLab, use the [GitLab agent](../../clusters/agent/index.md)
instead.
If you have an existing Kubernetes cluster, you can add it to a project, group,
@@ -69,8 +69,8 @@ To add a Kubernetes cluster to your project, group, or instance:
1. Project's **{cloud-gear}** **Infrastructure > Kubernetes clusters** page, for a project-level cluster.
1. Group's **{cloud-gear}** **Kubernetes** page, for a group-level cluster.
1. **Menu > Admin > Kubernetes** page, for an instance-level cluster.
-1. Click **Add Kubernetes cluster**.
-1. Click the **Add existing cluster** tab and fill in the details:
+1. On the **Kubernetes clusters** page, select the **Connect with a certificate** option from the **Actions** dropdown menu.
+1. On the **Connect a cluster** page, fill in the details:
1. **Kubernetes cluster name** (required) - The name you wish to give the cluster.
1. **Environment scope** (required) - The
[associated environment](multiple_kubernetes_clusters.md#setting-the-environment-scope) to this cluster.
diff --git a/doc/user/project/clusters/add_gke_clusters.md b/doc/user/project/clusters/add_gke_clusters.md
index 99edddeb3e9..cb8d04e0e28 100644
--- a/doc/user/project/clusters/add_gke_clusters.md
+++ b/doc/user/project/clusters/add_gke_clusters.md
@@ -19,7 +19,7 @@ hosted on Google Kubernetes Engine (GKE).
## Connect an existing GKE cluster
If you already have a GKE cluster and want to connect it to GitLab,
-use the [GitLab Agent](../../clusters/agent/index.md).
+use the [GitLab agent](../../clusters/agent/index.md).
## Create a new GKE cluster from GitLab
diff --git a/doc/user/project/clusters/add_remove_clusters.md b/doc/user/project/clusters/add_remove_clusters.md
index a0fca517f2e..a4f6dc325c8 100644
--- a/doc/user/project/clusters/add_remove_clusters.md
+++ b/doc/user/project/clusters/add_remove_clusters.md
@@ -10,7 +10,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
WARNING:
This feature was [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/327908) in GitLab 14.0.
-To create a new cluster use [Infrastructure as Code](../../infrastructure/iac/index.md#create-a-new-cluster-through-iac-deprecated).
+To create a new cluster use [Infrastructure as Code](../../infrastructure/iac/index.md#create-a-new-cluster-through-iac).
NOTE:
Every new Google Cloud Platform (GCP) account receives
@@ -29,7 +29,7 @@ in a few clicks.
> [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/327908) in GitLab 14.0.
-As of GitLab 14.0, use [Infrastructure as Code](../../infrastructure/iac/index.md#create-a-new-cluster-through-iac-deprecated)
+As of GitLab 14.0, use [Infrastructure as Code](../../infrastructure/iac/index.md#create-a-new-cluster-through-iac)
to **safely create new clusters from GitLab**.
Creating clusters from GitLab using cluster certificates is still available on the
@@ -49,7 +49,7 @@ supports connecting existing clusters using the certificate-based connection met
## Add existing cluster
-As of GitLab 14.0, use the [GitLab Agent](../../clusters/agent/index.md)
+As of GitLab 14.0, use the [GitLab agent](../../clusters/agent/index.md)
to connect your cluster to GitLab.
Alternatively, you can [add an existing cluster](add_existing_cluster.md)
@@ -57,7 +57,7 @@ through the certificate-based method, but we don't recommend using this method f
## Configure your cluster
-As of GitLab 14.0, use the [GitLab Agent](../../clusters/agent/index.md)
+As of GitLab 14.0, use the [GitLab agent](../../clusters/agent/index.md)
to configure your cluster.
## Disable a cluster
diff --git a/doc/user/project/clusters/cluster_access.md b/doc/user/project/clusters/cluster_access.md
index 4e00ae0dd07..8ff0a275649 100644
--- a/doc/user/project/clusters/cluster_access.md
+++ b/doc/user/project/clusters/cluster_access.md
@@ -11,7 +11,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
WARNING:
This feature was [deprecated](https://gitlab.com/groups/gitlab-org/configure/-/epics/8) in GitLab 14.5.
-To connect your cluster to GitLab, use the [GitLab Agent](../../clusters/agent/index.md)
+To connect your cluster to GitLab, use the [GitLab agent](../../clusters/agent/index.md)
instead.
When creating a cluster in GitLab, you are asked if you would like to create either:
diff --git a/doc/user/project/clusters/deploy_to_cluster.md b/doc/user/project/clusters/deploy_to_cluster.md
index e89ce12b35e..c1cdf754c11 100644
--- a/doc/user/project/clusters/deploy_to_cluster.md
+++ b/doc/user/project/clusters/deploy_to_cluster.md
@@ -10,8 +10,8 @@ info: To determine the technical writer assigned to the Stage/Group associated w
WARNING:
This feature was [deprecated](https://gitlab.com/groups/gitlab-org/configure/-/epics/8) in GitLab 14.5.
-To connect your cluster to GitLab, use the [GitLab Agent](../../clusters/agent/index.md).
-To deploy with the Agent, use the [CI/CD Tunnel](../../clusters/agent/ci_cd_tunnel.md).
+To connect your cluster to GitLab, use the [GitLab agent](../../clusters/agent/index.md).
+To deploy with the agent, use the [CI/CD workflow](../../clusters/agent/ci_cd_tunnel.md).
A Kubernetes cluster can be the destination for a deployment job. If
@@ -143,6 +143,6 @@ Reasons for failure include:
NOTE:
Project-level clusters upgraded from GitLab 12.0 or older may be configured
-in a way that causes this error. Ensure you deselect the
+in a way that causes this error. Ensure you clear the
[GitLab-managed cluster](gitlab_managed_clusters.md) option if you want to manage
namespaces and service accounts yourself.
diff --git a/doc/user/project/clusters/gitlab_managed_clusters.md b/doc/user/project/clusters/gitlab_managed_clusters.md
index 686b3026b2c..9c5cc14f720 100644
--- a/doc/user/project/clusters/gitlab_managed_clusters.md
+++ b/doc/user/project/clusters/gitlab_managed_clusters.md
@@ -12,7 +12,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
WARNING:
This feature was [deprecated](https://gitlab.com/groups/gitlab-org/configure/-/epics/8) in GitLab 14.5.
-To connect your cluster to GitLab, use the [GitLab Agent](../../../user/clusters/agent/index.md).
+To connect your cluster to GitLab, use the [GitLab agent](../../../user/clusters/agent/index.md).
To manage applications, use the [Cluster Project Management Template](../../../user/clusters/management_project_template.md).
You can choose to allow GitLab to manage your cluster for you. If your cluster
diff --git a/doc/user/project/clusters/index.md b/doc/user/project/clusters/index.md
index dc37060593c..f89d863e83b 100644
--- a/doc/user/project/clusters/index.md
+++ b/doc/user/project/clusters/index.md
@@ -12,7 +12,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
WARNING:
This feature was [deprecated](https://gitlab.com/groups/gitlab-org/configure/-/epics/8)
in GitLab 14.5. To connect clusters to GitLab, use the
-[GitLab Agent](../../clusters/agent/index.md).
+[GitLab agent](../../clusters/agent/index.md).
[Project-level](../../infrastructure/clusters/connect/index.md#cluster-levels-deprecated) Kubernetes clusters
allow you to connect a Kubernetes cluster to a project in GitLab.
diff --git a/doc/user/project/clusters/multiple_kubernetes_clusters.md b/doc/user/project/clusters/multiple_kubernetes_clusters.md
index a56eaa9b953..149df5248c8 100644
--- a/doc/user/project/clusters/multiple_kubernetes_clusters.md
+++ b/doc/user/project/clusters/multiple_kubernetes_clusters.md
@@ -13,7 +13,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
WARNING:
Using multiple Kubernetes clusters for a single project **with cluster
certificates** was [deprecated](https://gitlab.com/groups/gitlab-org/configure/-/epics/8) in GitLab 14.5.
-To connect clusters to GitLab, use the [GitLab Agent](../../../user/clusters/agent/index.md).
+To connect clusters to GitLab, use the [GitLab agent](../../../user/clusters/agent/index.md).
You can associate more than one Kubernetes cluster to your
project. That way you can have different clusters for different environments,
diff --git a/doc/user/project/clusters/protect/container_host_security/index.md b/doc/user/project/clusters/protect/container_host_security/index.md
index a0297a7a86f..f6f31ee8f36 100644
--- a/doc/user/project/clusters/protect/container_host_security/index.md
+++ b/doc/user/project/clusters/protect/container_host_security/index.md
@@ -1,7 +1,7 @@
---
stage: Protect
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
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
# Container Host Security **(FREE)**
diff --git a/doc/user/project/clusters/protect/container_host_security/quick_start_guide.md b/doc/user/project/clusters/protect/container_host_security/quick_start_guide.md
index 4e56b7e5140..25e2f6ddb91 100644
--- a/doc/user/project/clusters/protect/container_host_security/quick_start_guide.md
+++ b/doc/user/project/clusters/protect/container_host_security/quick_start_guide.md
@@ -1,7 +1,7 @@
---
stage: Protect
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
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
# Getting started with Container Host Security **(FREE)**
diff --git a/doc/user/project/clusters/protect/container_network_security/index.md b/doc/user/project/clusters/protect/container_network_security/index.md
index 7176a1cf1b9..eeaf7e82ef4 100644
--- a/doc/user/project/clusters/protect/container_network_security/index.md
+++ b/doc/user/project/clusters/protect/container_network_security/index.md
@@ -1,7 +1,7 @@
---
stage: Protect
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
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
# Container Network Security **(FREE)**
diff --git a/doc/user/project/clusters/protect/container_network_security/quick_start_guide.md b/doc/user/project/clusters/protect/container_network_security/quick_start_guide.md
index e6c91302d7b..43f4ea6c326 100644
--- a/doc/user/project/clusters/protect/container_network_security/quick_start_guide.md
+++ b/doc/user/project/clusters/protect/container_network_security/quick_start_guide.md
@@ -1,7 +1,7 @@
---
stage: Protect
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
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
# Getting started with Container Network Security **(FREE)**
diff --git a/doc/user/project/clusters/protect/index.md b/doc/user/project/clusters/protect/index.md
index 473195f4c17..3a80132fb50 100644
--- a/doc/user/project/clusters/protect/index.md
+++ b/doc/user/project/clusters/protect/index.md
@@ -1,7 +1,7 @@
---
stage: Protect
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
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
# Protecting your deployed applications **(FREE)**
diff --git a/doc/user/project/code_owners.md b/doc/user/project/code_owners.md
index eb18834cc6b..fefc27063a6 100644
--- a/doc/user/project/code_owners.md
+++ b/doc/user/project/code_owners.md
@@ -124,7 +124,7 @@ Only one CODEOWNERS pattern can match per file path.
### Organize Code Owners by putting them into sections
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/12137) in GitLab Premium 13.2 behind a feature flag, enabled by default.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/12137) in GitLab 13.2 behind a feature flag, enabled by default.
> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/42389) in GitLab 13.4.
You can organize Code Owners by putting them into named sections.
@@ -170,7 +170,7 @@ entries under **Database**. The entries defined under the sections **Documentati
### Make a Code Owners section optional
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/232995) in GitLab Premium 13.8.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/232995) in GitLab 13.8.
You can designate optional sections in your Code Owners file. Prepend the
section name with the caret `^` character to treat the entire section as optional.
diff --git a/doc/user/project/deploy_boards.md b/doc/user/project/deploy_boards.md
index 15490ab0b94..567c15c7d5f 100644
--- a/doc/user/project/deploy_boards.md
+++ b/doc/user/project/deploy_boards.md
@@ -7,8 +7,8 @@ type: howto, reference
# Deploy boards (DEPRECATED) **(FREE)**
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/1589) in [GitLab Premium](https://about.gitlab.com/pricing/) 9.0.
-> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/212320) to GitLab Free in 13.8.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/1589) in GitLab 9.0.
+> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/212320) from GitLab Premium to GitLab Free in 13.8.
> - In GitLab 13.5 and earlier, apps that consist of multiple deployments are shown as
> duplicates on the deploy board. This is [fixed](https://gitlab.com/gitlab-org/gitlab/-/issues/8463)
> in GitLab 13.6.
@@ -20,7 +20,7 @@ type: howto, reference
WARNING:
This feature was [deprecated](https://gitlab.com/groups/gitlab-org/configure/-/epics/8) in GitLab 14.5.
[An epic exists](https://gitlab.com/groups/gitlab-org/-/epics/2493)
-to add this functionality to the [Agent](../index.md).
+to add this functionality to the [agent](../index.md).
GitLab deploy boards offer a consolidated view of the current health and
status of each CI [environment](../../ci/environments/index.md) running on [Kubernetes](https://kubernetes.io), displaying the status
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
deleted file mode 100644
index 2f708555af1..00000000000
--- a/doc/user/project/deploy_keys/img/public_deploy_key_v13_0.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/project/deploy_keys/index.md b/doc/user/project/deploy_keys/index.md
index 57f6efa3092..b7674be2fa0 100644
--- a/doc/user/project/deploy_keys/index.md
+++ b/doc/user/project/deploy_keys/index.md
@@ -2,186 +2,145 @@
stage: Release
group: Release
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
-type: howto, reference
---
# Deploy keys **(FREE)**
-Deploy keys allow read-only or read-write access to your
-repositories by importing an SSH public key into your GitLab instance.
+Use deploy keys to access repositories that are hosted in GitLab. In most cases, you use deploy keys
+to access a repository from an external host, like a build server or Continuous Integration (CI) server.
-Deploy keys streamline interactions between your GitLab repository and another
-machine. For example, setting up a deploy key allows secure cloning of your
-repositories to a Continuous Integration (CI) server without setting up a fake
-user account.
+Depending on your needs, you might want to use a [deploy token](../deploy_tokens/) to access a repository instead.
-There are two types of deploy keys:
+| Attribute | Deploy key | Deploy token |
+|------------------|-------------|--------------|
+| Sharing | Shareable between multiple projects, even those in different groups. | Belong to a project or group. |
+| Source | Public SSH key generated on an external host. | Generated on your GitLab instance, and is provided to users only at creation time. |
+| Validity | Valid as long as it's registered and enabled. | Can be given an expiration date. |
+| Registry access | Cannot access a package registry. | Can read from and write to a package registry. |
-- [Project deploy keys](#project-deploy-keys)
-- [Public deploy keys](#public-deploy-keys)
+## Scope
-## Key details on deploy keys
+A deploy key has a defined scope when it is created:
-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.
+- **Project deploy key:** Access is limited to the selected project.
+- **Public deploy key:** Access can be granted to _any_ project in a GitLab instance. Access to each
+ project must be [granted](#grant-project-access-to-a-public-deploy-key) by a user with at least
+ the Maintainer role.
-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 provide access only to trusted users,
-and make sure that the allowed users have at least the Maintainer role
-in the GitLab project.
+You cannot change a deploy key's scope after creating it.
-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.
+## Permissions
-## Deploy keys permissions
+A deploy key is given a permission level when it is created:
-You can choose the access level of a deploy key when you enable it on a project:
+- **Read-only:** A read-only deploy key can only read from the repository.
+- **Read-write:** A read-write deploy key can read from, and write to, the repository.
-- `read-only`: The deploy key can read a repository.
-- `read-write`: The deploy key can read a repository and write to it.
+You can change a deploy key's permission level after creating it. Changing a project deploy key's
+permissions only applies for the current project.
-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 read-write deploy key is used to push a commit, GitLab checks if the creator of the
+deploy key has permission to access the resource.
-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:
+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.
+ 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 pipeline, the _creator_ of the
+ deploy key must have access to the CI/CD resources, including protected environments and secret
+ variables.
-## Differences between deploy keys and deploy tokens
+## View deploy keys
-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 generate on the **remote machine**. A deploy
- token, on the other hand, 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:
+To view the deploy keys available to a project:
1. On the top bar, select **Menu > Projects** and find your project.
1. On the left sidebar, select **Settings > Repository**.
1. Expand **Deploy keys**.
-1. Specify a title for the new deploy key and paste your public SSH key.
-1. Optional. To allow `read-write` access, select the **Grant write permissions to this key** checkbox. Leave it unchecked for `read-only` access.
-There are three lists of project deploy keys:
+The deploy keys available are listed:
-- Enabled deploy keys
-- Privately accessible deploy keys
-- Public accessible deploy keys
+- **Enabled deploy keys:** Deploy keys that have access to the project.
+- **Privately accessible deploy keys:** Project deploy keys that don't have access to the project.
+- **Public accessible deploy keys:** Public deploy keys that don't have access to the project.
-![Deploy keys section](img/deploy_keys_v13_0.png)
+## Create a project deploy key
-After you add a key, it's enabled for this project by default and it appears
-in the **Enabled deploy keys** tab.
+Prerequisites:
-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:
+- You must have at least the Maintainer role for the project.
+- [Generate an SSH key pair](../../../ssh/index.md#generate-an-ssh-key-pair). Put the private SSH
+ key on the host that requires access to the repository.
-- 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).
+1. On the top bar, select **Menu > Projects** and find your project.
+1. On the left sidebar, select **Settings > Repository**.
+1. Expand **Deploy keys**.
+1. Complete the fields.
+1. Optional. To grant `read-write` permission, select the **Grant write permissions to this key**
+ checkbox.
-After a key is added, you can edit it to update its title, or switch between `read-only`
-and `read-write` access.
+A project deploy key is enabled when it is created. You can modify only a project deploy key's
+name and permissions.
-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 is only for the **current project**.
+## Create a public deploy key
-### Public deploy keys
+Prerequisites:
-Public deploy keys allow `read-only` or `read-write` access to any repository in
-your GitLab instance. This allows for the integration of your repositories to
-secure, shared services, such as CI/CD.
+- You must have administrator access.
+- [Generate an SSH key pair](../../../ssh/index.md#generate-an-ssh-key-pair). Put the private SSH
+ key on the host that requires access to the repository.
-Instance administrators can add public deploy keys:
+To create a public deploy key:
1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Deploy Keys**.
1. Select **New deploy key**.
+1. Complete the fields.
+ - Use a meaningful description for **Name**. For example, include the name of the external host
+ or application that will use the public deploy key.
-Make sure your new key has a meaningful title. This title is the primary
-way for project maintainers and owners to identify the correct public deploy key
-to add to a repository or project. For example, the key you set up might be
-intended to give access to a SaaS CI/CD instance. In this case use the name of
-that service in the key title if that is all the key is used for.
+You can modify only a public deploy key's name.
-![Public deploy keys section](img/public_deploy_key_v13_0.png)
+## Grant project access to a public deploy key
-After adding a key, it's available to any shared system. Users with a maintainer role or
-higher can [authorize a public deploy key](#project-deploy-keys) to start using
-it with the project.
+Prerequisites:
-NOTE:
-The **Publicly accessible deploy keys** tab in a Project's CI/CD
-settings only appears if there is at least one Public deploy key configured.
+- You must have at least the Maintainer role for the project.
-Public deploy keys can provide greater security compared to project deploy keys.
-This is because the administrator of the target integrated system is the only
-entity who needs to know or configure the key value.
+To grant a public deploy key access to a project:
-When creating a Public deploy key, consider what scope and permissions are
-required for it across the entire GitLab instance. For very narrow usage, such
-as a single specific service, a `read-only` deploy key tied to this service is
-best. If the service entails broader usage across the instance, a
-deploy key with full `read-write` access is more appropriate.
+1. On the top bar, select **Menu > Projects** and find your project.
+1. On the left sidebar, select **Settings > Repository**.
+1. Expand **Deploy keys**.
+1. Select **Publicly accessible deploy keys**.
+1. In the key's row, select **Enable**.
+1. To grant read-write permission to the public deploy key:
+ 1. In the key's row, select **Edit** (**{pencil}**).
+ 1. Select the **Grant write permissions to this key** checkbox.
+
+## Revoke project access of a deploy key
-WARNING:
-Adding a public deploy key **does not** immediately expose any repository
-to the remote machine. Access to a project is only given when a project
-maintainer chooses to make use of a deploy key in the project's
-configuration.
+To revoke a deploy key's access to a project, you can disable it. Any service that relies on
+a deploy key stops working when the key is disabled.
-## How to disable deploy keys
+Prerequisites:
-[Project maintainers and owners](../../permissions.md#project-members-permissions)
-can remove or disable a deploy key for a project repository:
+- You must have at least the Maintainer role for the project.
+
+To disable a deploy key:
1. On the top bar, select **Menu > Projects** and find your project.
1. On the left sidebar, select **Settings > Repository**.
1. Expand **Deploy keys**.
1. Select **Disable** (**{cancel}**).
-NOTE:
-Any service that relies on a deploy key stops working after that key is removed.
-
-If the key is **publicly accessible**, it is removed from the project, but can
-still be found under **Publicly accessible deploy keys**.
-
-If the key is **privately accessible** and only in use by this project, it is
-deleted entirely from GitLab on removal.
+What happens to the deploy key when it is disabled depends on the following:
-If the key is **privately accessible** and also in use by other projects, it is
-removed from the project, but still available under **Privately accessible
-deploy keys**.
+- If the key is publicly accessible, it is removed from the project but still available in the
+ **Publicly accessible deploy keys** tab.
+- If the key is privately accessible and only in use by this project, it is deleted.
+- If the key is privately accessible and also in use by other projects, it is removed from the
+ project, but still available in the **Privately accessible deploy keys** tab.
## Troubleshooting
@@ -192,7 +151,7 @@ branch](../protected_branches.md).
- The owner associated to a deploy key does not have access to the protected branch.
- The owner associated to a deploy key does not have [membership](../members/index.md) to the project of the protected branch.
-- **No one** is selected in [the "Allowed to push" section](../protected_branches.md#configure-a-protected-branch) of the protected branch.
+- **No one** is selected in [the **Allowed to push** section](../protected_branches.md#configure-a-protected-branch) of the protected branch.
All deploy keys are associated to an account. Since the permissions for an account can change, this might lead to scenarios where a deploy key that was working is suddenly unable to push to a protected branch.
diff --git a/doc/user/project/file_lock.md b/doc/user/project/file_lock.md
index 9911c90863d..4810fb96ed3 100644
--- a/doc/user/project/file_lock.md
+++ b/doc/user/project/file_lock.md
@@ -25,10 +25,10 @@ GitLab supports two different modes of file locking:
- [Exclusive file locks](#exclusive-file-locks) for binary files: done **through
the command line** with Git LFS and `.gitattributes`, it prevents locked
- files from being modified on any branch. **(FREE)**
+ files from being modified on any branch.
- [Default branch locks](#default-branch-file-and-directory-locks): done
**through the GitLab UI**, it prevents locked files and directories being
- modified on the default branch. **(PREMIUM)**
+ modified on the default branch.
## Permissions
@@ -40,7 +40,7 @@ users are prevented from modifying locked files by pushing, merging,
or any other means, and are shown an error like: `The path '.gitignore' is
locked by Administrator`.
-## Exclusive file locks **(FREE)**
+## Exclusive file locks
This process allows you to lock single files or file extensions and it is
done through the command line. It doesn't require GitLab paid subscriptions.
@@ -192,7 +192,7 @@ Suggested workflow for shared projects:
## Default branch file and directory locks **(PREMIUM)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/440) in GitLab Enterprise Edition 8.9. Available in [GitLab Premium](https://about.gitlab.com/pricing/).
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/440) in GitLab 8.9.
This process allows you to lock one file at a time through the GitLab UI and
requires access to [GitLab Premium](https://about.gitlab.com/pricing/)
diff --git a/doc/user/project/highlighting.md b/doc/user/project/highlighting.md
index 728f51a8062..ef0c787b9d3 100644
--- a/doc/user/project/highlighting.md
+++ b/doc/user/project/highlighting.md
@@ -7,61 +7,67 @@ type: reference
# Syntax Highlighting **(FREE)**
-GitLab provides syntax highlighting on all files through the [Rouge](https://rubygems.org/gems/rouge) Ruby gem. It attempts to guess what language to use based on the file extension, which most of the time is sufficient.
+GitLab provides syntax highlighting on all files through the
+[Rouge](https://rubygems.org/gems/rouge) Ruby gem. It attempts to guess what language
+to use based on the file extension, which most of the time is sufficient.
+
+The paths here are Git's built-in [`.gitattributes` interface](https://git-scm.com/docs/gitattributes).
NOTE:
The [Web IDE](web_ide/index.md) and [Snippets](../snippets.md) use [Monaco Editor](https://microsoft.github.io/monaco-editor/)
for text editing, which internally uses the [Monarch](https://microsoft.github.io/monaco-editor/monarch.html)
library for syntax highlighting.
-<!-- vale gitlab.Spelling = NO -->
-
-If GitLab is guessing wrong, you can override its choice of language using the
-`gitlab-language` attribute in `.gitattributes`. For example, if you are working in a Prolog
-project and using the `.pl` file extension (which would normally be highlighted as Perl),
-you can add the following to your `.gitattributes` file:
+## Override syntax highlighting for a file type
-<!-- vale gitlab.Spelling = YES -->
-
-``` conf
-*.pl gitlab-language=prolog
-```
+NOTE:
+The Web IDE [does not support `.gitattribute` files](https://gitlab.com/gitlab-org/gitlab/-/issues/22014).
-<!-- vale gitlab.Spelling = NO -->
+To override syntax highlighting for a file type:
-When you check in and push that change, all `*.pl` files in your project are highlighted as Prolog.
+1. If a `.gitattributes` file does not exist in the root directory of your project,
+ create a blank file with this name.
+1. For each file type you want to modify, add a line to the `.gitattributes` file
+ declaring the file extension and your desired highlighting language:
-<!-- vale gitlab.Spelling = YES -->
+ ```conf
+ # This extension would normally receive Perl syntax highlighting
+ # but if we also use Prolog, we may want to override highlighting for
+ # files with this extension:
+ *.pl gitlab-language=prolog
+ ```
-The paths here are Git's built-in [`.gitattributes` interface](https://git-scm.com/docs/gitattributes). So, if you were to invent a file format called a `Nicefile` at the root of your project that used Ruby syntax, all you need is:
+1. Commit, push, and merge your changes into your default branch.
-``` conf
-/Nicefile gitlab-language=ruby
-```
+After the changes merge into your [default branch](repository/branches/default.md),
+all `*.pl` files in your project are highlighted in your preferred language.
-To disable highlighting entirely, use `gitlab-language=text`. Lots more fun shenanigans are available through common gateway interface (CGI) options, such as:
+You can also extend the highlighting with common gateway interface (CGI) options, such as:
``` conf
-# json with erb in it
+# JSON file with .erb in it
/my-cool-file gitlab-language=erb?parent=json
-# an entire file of highlighting errors!
+# An entire file of highlighting errors!
/other-file gitlab-language=text?token=Error
```
-These configurations only take effect when the `.gitattributes`
-file is in your [default branch](repository/branches/default.md).
+## Disable syntax highlighting for a file type
-NOTE:
-The Web IDE does not support `.gitattribute` files, but it's [planned for a future release](https://gitlab.com/gitlab-org/gitlab/-/issues/22014).
+To disable highlighting entirely for a file type, follow the instructions for overriding
+the highlighting for a file type, and use `gitlab-language=text`:
-## Configure maximum file size for highlighting
+```conf
+# Disable syntax highlighting for this file type
+*.module gitlab-language=text
+```
-You can configure the maximum size of the file to be highlighted.
+## Configure maximum file size for highlighting
-The file size is measured in kilobytes, and is set to a default of `512 KB`. Any file _over_ the file size is rendered in plain text.
+By default, GitLab renders any file larger than 512 KB in plain text. To change this value:
-1. Open the [`gitlab.yml`](https://gitlab.com/gitlab-org/gitlab-foss/blob/master/config/gitlab.yml.example) configuration file.
+1. Open the [`gitlab.yml`](https://gitlab.com/gitlab-org/gitlab-foss/blob/master/config/gitlab.yml.example)
+ configuration file for your project.
1. Add this section, replacing `maximum_text_highlight_size_kilobytes` with the value you want.
@@ -72,3 +78,5 @@ The file size is measured in kilobytes, and is set to a default of `512 KB`. Any
## https://docs.gitlab.com/ee/user/project/highlighting.html
maximum_text_highlight_size_kilobytes: 512
```
+
+1. Commit, push, and merge your changes into your default branch.
diff --git a/doc/user/project/img/labels_sort_label_priority.png b/doc/user/project/img/labels_sort_label_priority.png
deleted file mode 100644
index faf629ac61d..00000000000
--- a/doc/user/project/img/labels_sort_label_priority.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/project/img/labels_sort_priority.png b/doc/user/project/img/labels_sort_priority.png
deleted file mode 100644
index a6b5fca26f4..00000000000
--- a/doc/user/project/img/labels_sort_priority.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/project/img/labels_subscriptions_v13_5.png b/doc/user/project/img/labels_subscriptions_v13_5.png
deleted file mode 100644
index a2a4e9e50cc..00000000000
--- a/doc/user/project/img/labels_subscriptions_v13_5.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/project/import/bitbucket.md b/doc/user/project/import/bitbucket.md
index 62495872659..8c0d9fc422b 100644
--- a/doc/user/project/import/bitbucket.md
+++ b/doc/user/project/import/bitbucket.md
@@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Import your project from Bitbucket Cloud to GitLab **(FREE)**
NOTE:
-The Bitbucket Cloud importer works only with Bitbucket.org, not with Bitbucket
+The Bitbucket Cloud importer works only with [Bitbucket.org](https://bitbucket.org/), not with Bitbucket
Server (aka Stash). If you are trying to import projects from Bitbucket Server, use
[the Bitbucket Server importer](bitbucket_server.md).
@@ -31,25 +31,37 @@ When importing:
- Repository public access is retained. If a repository is private in Bitbucket, it's created as
private in GitLab as well.
-## Requirements
+## Prerequisite for GitLab self-managed
To import your projects from Bitbucket Cloud, the [Bitbucket Cloud integration](../../../integration/bitbucket.md)
-must be enabled. Ask your GitLab administrator to enable this if it isn't already enabled.
+must be enabled. If it isn't enabled, ask your GitLab administrator to enable it. By default it's
+enabled on GitLab.com.
## How it works
-When issues/pull requests are being imported, the Bitbucket importer tries to find
-the Bitbucket author/assignee in the GitLab database using the Bitbucket `nickname`.
-For this to work, the Bitbucket author/assignee should have signed in beforehand in GitLab
-and **associated their Bitbucket account**. Their `nickname` must also match their Bitbucket
-`username`. If the user is not found in the GitLab database, the project creator
-(most of the times the current user that started the import process) is set as the author,
-but a reference on the issue about the original Bitbucket author is kept.
+When issues/pull requests are being imported, the Bitbucket importer uses the Bitbucket nickname of
+the author/assignee and tries to find the same Bitbucket identity in GitLab. If they don't match or
+the user is not found in the GitLab database, the project creator (most of the times the current
+user that started the import process) is set as the author, but a reference on the issue about the
+original Bitbucket author is kept.
The importer will create any new namespaces (groups) if they don't exist or in
the case the namespace is taken, the repository will be imported under the user's
namespace that started the import process.
+## Requirements for user-mapped contributions
+
+For user contributions to be mapped, each user must complete the following before the project import:
+
+1. Verify that the username in the [Bitbucket account settings](https://bitbucket.org/account/settings/)
+ matches the public name in the [Atlassian account settings](https://id.atlassian.com/manage-profile/profile-and-visibility).
+ If they don't match, modify the public name in the Atlassian account settings to match the
+ username in the Bitbucket account settings.
+
+1. Connect your Bitbucket account in [GitLab profile social sign-in](https://gitlab.com/-/profile/account).
+
+1. [Set your public email](../../profile/index.md#set-your-public-email).
+
## Import your Bitbucket repositories
1. Sign in to GitLab.
@@ -69,9 +81,35 @@ namespace that started the import process.
## Troubleshooting
-If you have more than one Bitbucket account, be sure to sign in to the correct account.
+### If you have more than one Bitbucket account
+
+Be sure to sign in to the correct account.
+
If you've accidentally started the import process with the wrong account, follow these steps:
1. Revoke GitLab access to your Bitbucket account, essentially reversing the process in the following procedure: [Import your Bitbucket repositories](#import-your-bitbucket-repositories).
1. Sign out of the Bitbucket account. Follow the procedure linked from the previous step.
+
+### User mapping fails despite matching names
+
+[For user mapping to work](#requirements-for-user-mapped-contributions),
+the username in the Bitbucket account settings must match the public name in the Atlassian account
+settings. If these names match but user mapping still fails, the user may have modified their
+Bitbucket username after connecting their Bitbucket account in the
+[GitLab profile social sign-in](https://gitlab.com/-/profile/account).
+
+To fix this, the user must verify that their Bitbucket external UID in the GitLab database matches their
+current Bitbucket public name, and reconnect if there's a mismatch:
+
+1. [Use the API to get the currently authenticated user](../../../api/users.md#list-current-user-for-normal-users).
+
+1. In the API's response, the `identities` attribute contains the Bitbucket account that exists in
+ the GitLab database. If the `extern_uid` doesn't match the current Bitbucket public name, the
+ user should reconnect their Bitbucket account in the [GitLab profile social sign-in](https://gitlab.com/-/profile/account).
+
+1. Following reconnection, the user should use the API again to verify that their `extern_uid` in
+ the GitLab database now matches their current Bitbucket public name.
+
+The importer must then [delete the imported project](../../project/working_with_projects.md#delete-a-project)
+and import again.
diff --git a/doc/user/project/import/clearcase.md b/doc/user/project/import/clearcase.md
index 120c64e00f2..867477c83b2 100644
--- a/doc/user/project/import/clearcase.md
+++ b/doc/user/project/import/clearcase.md
@@ -51,4 +51,4 @@ are some useful links to get you started:
- [ClearCase to Git](https://therub.org/2013/07/19/clearcase-to-git/)
- [Dual syncing ClearCase to Git](https://therub.org/2013/10/22/dual-syncing-clearcase-and-git/)
- [Moving to Git from ClearCase](https://sateeshkumarb.wordpress.com/2011/01/15/moving-to-git-from-clearcase/)
-- [ClearCase to Git webinar](https://www.brighttalk.com/webcast/11817/162473/clearcase-to-git)
+- [ClearCase to Git webinar](https://www.brighttalk.com/webcast/11817/162473)
diff --git a/doc/user/project/import/cvs.md b/doc/user/project/import/cvs.md
index 55c5feff1f0..8bb716d8122 100644
--- a/doc/user/project/import/cvs.md
+++ b/doc/user/project/import/cvs.md
@@ -71,6 +71,6 @@ Here's a few links to get you started with the migration:
- [Migrate using the `cvs-fast-export` tool](https://gitlab.com/esr/cvs-fast-export)
- [Stack Overflow post on importing the CVS repository](https://stackoverflow.com/a/11490134/974710)
-- [Convert a CVS repository to Git](https://www.techrepublic.com/blog/linux-and-open-source/convert-cvs-repositories-to-git/)
+- [Convert a CVS repository to Git](http://www.techrepublic.com/article/convert-cvs-repositories-to-git/)
- [Man page of the `git-cvsimport` tool](https://mirrors.edge.kernel.org/pub/software/scm/git/docs/git-cvsimport.html)
- [Migrate using `reposurgeon`](http://www.catb.org/~esr/reposurgeon/repository-editing.html#conversion)
diff --git a/doc/user/project/import/gitlab_com.md b/doc/user/project/import/gitlab_com.md
index bcbc6e09f1b..6913cda0cd5 100644
--- a/doc/user/project/import/gitlab_com.md
+++ b/doc/user/project/import/gitlab_com.md
@@ -14,7 +14,7 @@ mind that it is possible only if GitLab.com integration is enabled on your GitLa
To get to the importer page you need to go to "New project" page.
NOTE:
-If you are interested in importing Wiki and Merge Request data to your new instance,
+If you are interested in importing Wiki and merge request data to your new instance,
you'll need to follow the instructions for [exporting a project](../settings/import_export.md#export-a-project-and-its-data)
![New project page](img/gitlab_new_project_page_v12_2.png)
diff --git a/doc/user/project/import/jira.md b/doc/user/project/import/jira.md
index 5f7475eac36..a44669e738e 100644
--- a/doc/user/project/import/jira.md
+++ b/doc/user/project/import/jira.md
@@ -32,8 +32,7 @@ imported into the GitLab issue's description as plain text.
Our parser for converting text in Jira issues to GitLab Flavored Markdown is only compatible with
Jira V3 REST API.
-There is an [epic](https://gitlab.com/groups/gitlab-org/-/epics/2738) tracking the addition of
-items, such as issue assignees, comments, and much more. These are included in the future
+There is an [epic](https://gitlab.com/groups/gitlab-org/-/epics/2738) tracking the addition of issue assignees, comments, and much more in the future
iterations of the GitLab Jira importer.
## Prerequisites
@@ -60,7 +59,7 @@ Importing large projects may take several minutes depending on the size of the i
To import Jira issues to a GitLab project:
-1. On the **{issues}** **Issues** page, click **Import Issues** (**{import}**) **> Import from Jira**.
+1. On the **{issues}** **Issues** page, select **Import Issues** (**{import}**) **> Import from Jira**.
![Import issues from Jira button](img/jira/import_issues_from_jira_button_v12_10.png)
@@ -68,20 +67,20 @@ To import Jira issues to a GitLab project:
The following form appears.
If you've previously set up the [Jira integration](../../../integration/jira/index.md), you can now see
- the Jira projects that you have access to in the dropdown.
+ the Jira projects that you have access to in the dropdown list.
![Import issues from Jira form](img/jira/import_issues_from_jira_form_v13_2.png)
-1. Click the **Import from** dropdown and select the Jira project that you wish to import issues from.
+1. Click the **Import from** dropdown list and select the Jira project that you wish to import issues from.
In the **Jira-GitLab user mapping template** section, the table shows to which GitLab users your Jira
users are mapped.
- When the form appears, the dropdown defaults to the user conducting the import.
+ When the form appears, the dropdown list defaults to the user conducting the import.
-1. To change any of the mappings, click the dropdown in the **GitLab username** column and
+1. To change any of the mappings, click the dropdown list in the **GitLab username** column and
select the user you want to map to each Jira user.
- The dropdown may not show all the users, so use the search bar to find a specific
+ The dropdown list may not show all the users, so use the search bar to find a specific
user in this GitLab project.
1. Click **Continue**. You're presented with a confirmation that import has started.
diff --git a/doc/user/project/integrations/custom_issue_tracker.md b/doc/user/project/integrations/custom_issue_tracker.md
index d155f91e40b..71ca9f4f640 100644
--- a/doc/user/project/integrations/custom_issue_tracker.md
+++ b/doc/user/project/integrations/custom_issue_tracker.md
@@ -8,7 +8,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
You can integrate an [external issue tracker](../../../integration/external-issue-tracker.md)
with GitLab. If your preferred issue tracker is not listed in the
-[integrations list](../../../integration/external-issue-tracker.md#integration),
+[integrations list](../../../integration/external-issue-tracker.md#configure-an-external-issue-tracker),
you can enable a custom issue tracker.
After you enable the custom issue tracker, a link to the issue tracker displays
diff --git a/doc/user/project/integrations/gitlab_slack_application.md b/doc/user/project/integrations/gitlab_slack_application.md
index 0a685ad0efb..7e8de776619 100644
--- a/doc/user/project/integrations/gitlab_slack_application.md
+++ b/doc/user/project/integrations/gitlab_slack_application.md
@@ -32,15 +32,15 @@ where you can select a project to enable the GitLab Slack application for.
Alternatively, you can configure the Slack application with a project's
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 workspace](https://slack.com/help/articles/202035138-Add-apps-to-your-Slack-workspace).
+Keep in mind that you must have the appropriate permissions for your Slack
+team to be able to install a new application, read more in Slack's
+documentation on [Adding an app to your workspace](https://slack.com/help/articles/202035138-Add-apps-to-your-Slack-workspace).
To enable the GitLab service for your Slack team:
1. Go to your project's **Settings > Integration > Slack application** (only
visible on GitLab.com).
-1. Click **Add to Slack**.
+1. Select **Add to Slack**.
That's all! You can now start using the Slack slash commands.
@@ -49,11 +49,11 @@ That's all! You can now start using the Slack slash commands.
To create a project alias on GitLab.com for Slack integration:
1. Go to your project's home page.
-1. Navigate to **Settings > Integrations** (only visible on GitLab.com)
-1. On the **Integrations** page, click **Slack application**.
+1. Go to **Settings > Integrations** (only visible on GitLab.com)
+1. On the **Integrations** page, select **Slack application**.
1. The current **Project Alias**, if any, is displayed. To edit this value,
- click **Edit**.
-1. Enter your desired alias, and click **Save changes**.
+ select **Edit**.
+1. Enter your desired alias, and select **Save changes**.
Some Slack commands require a project alias, and fail with the following error
if the project alias is incorrect or missing from the command:
diff --git a/doc/user/project/integrations/harbor.md b/doc/user/project/integrations/harbor.md
new file mode 100644
index 00000000000..d66e2222538
--- /dev/null
+++ b/doc/user/project/integrations/harbor.md
@@ -0,0 +1,50 @@
+---
+stage: Ecosystem
+group: Integrations
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
+---
+
+# Harbor container registry integration **(FREE)**
+
+Use Harbor as the container registry for your GitLab project.
+
+[Harbor](https://goharbor.io/) is an open source registry that can help you manage artifacts across cloud native compute platforms, like Kubernetes and Docker.
+
+This integration can help you if you need GitLab CI/CD and a container image repository.
+
+## Prerequisites
+
+In the Harbor instance, ensure that:
+
+- The project to be integrated has been created.
+- The signed-in user has permission to pull, push, and edit images in the Harbor project.
+
+## Configure GitLab
+
+GitLab supports integrating Harbor projects at the group or project level. Complete these steps in GitLab:
+
+1. On the top bar, select **Menu > Projects** and find your project.
+1. On the left sidebar, select **Settings > Integrations**.
+1. Select **Harbor**.
+1. Turn on the **Active** toggle under **Enable Integration**.
+1. Provide the Harbor configuration information:
+ - **Harbor URL**: The base URL of Harbor instance which is being linked to this GitLab project. For example, `https://harbor.example.net`.
+ - **Harbor project name**: The project name in the Harbor instance. For example, `testproject`.
+ - **Username**: Your username in the Harbor instance, which should meet the requirements in [prerequisites](#prerequisites).
+ - **Password**: Password of your username.
+
+1. Select **Save changes**.
+
+After the Harbor integration is activated:
+
+- The global variables `$HARBOR_USER`, `$HARBOR_PASSWORD`, `$HARBOR_URL`, and `$HARBOR_PROJECT` are created for CI/CD use.
+- The project-level integration settings override the group-level integration settings.
+
+## Secure your requests to the Harbor APIs
+
+For each API request through the Harbor integration, the credentials for your connection to the Harbor API use
+the `username:password` combination. The following are suggestions for safe use:
+
+- Use TLS on the Harbor APIs you connect to.
+- Follow the principle of least privilege (for access on Harbor) with your credentials.
+- Have a rotation policy on your credentials.
diff --git a/doc/user/project/integrations/img/failed_badges.png b/doc/user/project/integrations/img/failed_badges.png
new file mode 100644
index 00000000000..d44415a8687
--- /dev/null
+++ b/doc/user/project/integrations/img/failed_badges.png
Binary files differ
diff --git a/doc/user/project/integrations/img/failed_banner.png b/doc/user/project/integrations/img/failed_banner.png
new file mode 100644
index 00000000000..ba40c1301d6
--- /dev/null
+++ b/doc/user/project/integrations/img/failed_banner.png
Binary files differ
diff --git a/doc/user/project/integrations/img/failed_banner_error.png b/doc/user/project/integrations/img/failed_banner_error.png
new file mode 100644
index 00000000000..8f4dabbf8c2
--- /dev/null
+++ b/doc/user/project/integrations/img/failed_banner_error.png
Binary files differ
diff --git a/doc/user/project/integrations/mattermost_slash_commands.md b/doc/user/project/integrations/mattermost_slash_commands.md
index b317e65bdf2..768acb02ee6 100644
--- a/doc/user/project/integrations/mattermost_slash_commands.md
+++ b/doc/user/project/integrations/mattermost_slash_commands.md
@@ -32,7 +32,7 @@ on your configuration:
If Mattermost is installed on the same server as GitLab, the configuration process can be
done for you by GitLab.
-Go to the Mattermost Slash Command service on your project and click **Add to Mattermost** button.
+Go to the Mattermost Slash Command service on your project and select **Add to Mattermost**.
## Manual configuration
@@ -52,13 +52,13 @@ installations from source.
To enable custom slash commands from the Mattermost administrator console:
1. Sign in to Mattermost as a user with administrator privileges.
-1. Next to your username, click the **{ellipsis_v}** **Settings** icon, and
+1. Next to your username, select the **{ellipsis_v}** **Settings** icon, and
select **System Console**.
1. Select **Integration Management**, and set these values to `TRUE`:
- **Enable Custom Slash Commands**
- **Enable integrations to override usernames**
- **Enable integrations to override profile picture icons**
-1. Click **Save**, but do not close this browser tab, because you need it in
+1. Select **Save**, but do not close this browser tab, because you need it in
a later step.
### Get configuration values from GitLab
@@ -85,9 +85,9 @@ the previous step:
1. In the Mattermost tab you left open when you
[enabled custom slash commands](#enable-custom-slash-commands), go to your
team page.
-1. Click the **{ellipsis_v}** **Settings** icon, and select **Integrations**.
+1. Select the **{ellipsis_v}** **Settings** icon, and select **Integrations**.
1. In the left menu, select **Slash commands**.
-1. Click **Add Slash Command**:
+1. Select **Add Slash Command**:
![Mattermost add command](img/mattermost_add_slash_command.png)
1. Provide a **Display Name** and **Description** for your new command.
@@ -101,7 +101,7 @@ the previous step:
[viewed configuration values](#get-configuration-values-from-gitlab).
1. For all other values, you may use the suggestions from GitLab or use your
preferred values.
-1. Copy the **Token** value, as you need it in a later step, and click **Done**.
+1. Copy the **Token** value, as you need it in a later step, and select **Done**.
### Provide the Mattermost token to GitLab
@@ -116,7 +116,7 @@ provide to GitLab:
![Mattermost copy token to GitLab](img/mattermost_gitlab_token.png)
-1. Click **Save changes** for the changes to take effect.
+1. Select **Save changes** for the changes to take effect.
Your slash command can now communicate with your GitLab project.
@@ -165,4 +165,4 @@ different types of notifications. All events are sent to the specified channel.
## Further reading
- [Mattermost slash commands documentation](https://docs.mattermost.com/developer/slash-commands.html)
-- [Omnibus GitLab Mattermost](https://docs.gitlab.com/omnibus/gitlab-mattermost/)
+- [Omnibus GitLab Mattermost](../../../integration/mattermost/)
diff --git a/doc/user/project/integrations/overview.md b/doc/user/project/integrations/overview.md
index 8ecc16050be..2cb62b8924e 100644
--- a/doc/user/project/integrations/overview.md
+++ b/doc/user/project/integrations/overview.md
@@ -43,6 +43,7 @@ Click on the service links to see further configuration instructions and details
| [Flowdock](../../../api/integrations.md#flowdock) | Send notifications from GitLab to Flowdock flows. | **{dotted-circle}** No |
| [GitHub](github.md) | Obtain statuses for commits and pull requests. | **{dotted-circle}** No |
| [Google Chat](hangouts_chat.md) | Send notifications from your GitLab project to a room in Google Chat.| **{dotted-circle}** No |
+| [Harbor](harbor.md) | Use Harbor as the container registry. | **{dotted-circle}** No |
| [irker (IRC gateway)](irker.md) | Send IRC messages. | **{dotted-circle}** No |
| [Jenkins](../../../integration/jenkins.md) | Run CI/CD pipelines with Jenkins. | **{check-circle}** Yes |
| JetBrains TeamCity CI | Run CI/CD pipelines with TeamCity. | **{check-circle}** Yes |
diff --git a/doc/user/project/integrations/webhook_events.md b/doc/user/project/integrations/webhook_events.md
index 9d8b98edba1..d37196ec114 100644
--- a/doc/user/project/integrations/webhook_events.md
+++ b/doc/user/project/integrations/webhook_events.md
@@ -202,6 +202,10 @@ The available values for `object_attributes.action` in the payload are:
The `assignee` and `assignee_id` keys are deprecated
and contain the first assignee only.
+The `escalation_status` and `escalation_policy` fields are
+only available for issue types which support escalations,
+such as incidents.
+
Request header:
```plaintext
@@ -271,6 +275,12 @@ Payload example:
"url": "http://example.com/diaspora/issues/23",
"state": "opened",
"action": "open",
+ "severity": "high",
+ "escalation_status": "triggered",
+ "escalation_policy": {
+ "id": 18,
+ "name": "Engineering On-call"
+ },
"labels": [{
"id": 206,
"title": "API",
@@ -771,7 +781,8 @@ Payload example:
Merge request events are triggered when:
- A new merge request is created.
-- An existing merge request is updated, approved, unapproved, merged, or closed.
+- An existing merge request is updated, approved (by all required approvers), unapproved, merged, or closed.
+- An individual user adds or removes their approval to an existing merge request.
- A commit is added in the source branch.
- All threads are resolved on the merge request.
@@ -783,6 +794,8 @@ The available values for `object_attributes.action` in the payload are:
- `update`
- `approved`
- `unapproved`
+- `approval`
+- `unapproval`
- `merge`
Request header:
@@ -1294,7 +1307,7 @@ Payload example:
"id": 3,
"name": "User",
"email": "user@gitlab.com",
- "avatar_url": "http://www.gravatar.com/avatar/e32bd13e2add097461cb96824b7a829c?s=80\u0026d=identicon",
+ "avatar_url": "http://www.gravatar.com/avatar/e32bd13e2add097461cb96824b7a829c?s=80\u0026d=identicon"
},
"commit": {
"id": 2366,
diff --git a/doc/user/project/integrations/webhooks.md b/doc/user/project/integrations/webhooks.md
index ace5783c852..e823391401d 100644
--- a/doc/user/project/integrations/webhooks.md
+++ b/doc/user/project/integrations/webhooks.md
@@ -62,7 +62,8 @@ You can configure a webhook for a group or a project.
## Test a webhook
-You can trigger a webhook manually, to ensure it's working properly.
+You can trigger a webhook manually, to ensure it's working properly. You can also send
+a test request to re-enable a [disabled webhook](#re-enable-disabled-webhooks).
For example, to test `push events`, your project should have at least one commit. The webhook uses this commit in the webhook.
@@ -72,6 +73,8 @@ To test a webhook:
1. Scroll down to the list of configured webhooks.
1. From the **Test** dropdown list, select the type of event to test.
+You can also test a webhook from its edit page.
+
![Webhook testing](img/webhook_testing.png)
## Create an example webhook receiver
@@ -143,7 +146,32 @@ GitLab webhooks, keep in mind the following:
GitLab assumes the hook failed and retries it.
Most HTTP libraries take care of the response for you automatically but if
you are writing a low-level hook, this is important to remember.
-- GitLab ignores the HTTP status code returned by your endpoint.
+- GitLab usually ignores the HTTP status code returned by your endpoint,
+ unless the [`web_hooks_disable_failed` feature flag is set](#failing-webhooks).
+
+### Failing webhooks
+
+> - Introduced in GitLab 13.12 [with a flag](../../../administration/feature_flags.md) named `web_hooks_disable_failed`. Disabled by default.
+> - [Enabled on GitLab.com](https://gitlab.com/gitlab-org/gitlab/-/issues/329849) in GitLab 14.9.
+
+FLAG:
+On self-managed GitLab, by default this feature is not available. To make it available,
+ask an administrator to [enable the feature flag](../../../administration/feature_flags.md) named `web_hooks_disable_failed`.
+The feature is not ready for production use.
+
+If a webhook fails repeatedly, it may be disabled automatically.
+
+Webhooks that return response codes in the `5xx` range are understood to be failing
+intermittently, and are temporarily disabled. This lasts initially
+for 10 minutes. If the hook continues to fail, the back-off period is
+extended on each retry, up to a maximum disabled period of 24 hours.
+
+Webhooks that return failure codes in the `4xx` range are understood to be
+misconfigured, and these are disabled until you manually re-enable
+them. These webhooks are not automatically retried.
+
+See [troubleshooting](#troubleshoot-webhooks) for information on
+how to see if a webhook is disabled, and how to re-enable it.
## How image URLs are displayed in the webhook body
@@ -186,6 +214,13 @@ To view the table:
1. In your project, on the left sidebar, select **Settings > Webhooks**.
1. Scroll down to the webhooks.
+1. Each [failing webhook](#failing-webhooks) has a badge listing it as:
+
+ - **Failed to connect** if it is misconfigured, and needs manual intervention to re-enable it.
+ - **Fails to connect** if it is temporarily disabled and will retry later.
+
+ ![Badges on failing webhooks](img/failed_badges.png)
+
1. Select **Edit** for the webhook you want to view.
The table includes the following details about each request:
@@ -216,8 +251,8 @@ If the endpoint doesn't send an HTTP response in those 10 seconds,
GitLab may assume the webhook failed and retry it.
If your webhooks are failing or you are receiving multiple requests,
-you can try changing the default timeout value.
-In your `/etc/gitlab/gitlab.rb` file, uncomment or add the following setting:
+an administrator can try changing the default timeout value
+by uncommenting or adding the following setting in `/etc/gitlab/gitlab.rb`:
```ruby
gitlab_rails['webhook_timeout'] = 10
@@ -233,3 +268,17 @@ determined by [CAcert.org](http://www.cacert.org/).
If that is not the case, consider using [SSL Checker](https://www.sslshopper.com/ssl-checker.html) to identify faults.
Missing intermediate certificates are common causes of verification failure.
+
+### Re-enable disabled webhooks
+
+If a webhook is failing, a banner displays at the top of the edit page explaining
+why it is disabled, and when it will be automatically re-enabled. For example:
+
+![A banner for a failing webhook, warning it failed to connect and will retry in 60 minutes](img/failed_banner.png)
+
+In the case of a failed webhook, an error banner is displayed:
+
+![A banner for a failed webhook, showing an error state, and explaining how to re-enable it](img/failed_banner_error.png)
+
+To re-enable a failing or failed webhook, [send a test request](#test-a-webhook). If the test
+request succeeds, the webhook is re-enabled.
diff --git a/doc/user/project/issue_board.md b/doc/user/project/issue_board.md
index 71440298d85..d731ceb5aca 100644
--- a/doc/user/project/issue_board.md
+++ b/doc/user/project/issue_board.md
@@ -53,7 +53,7 @@ the issue board feature.
> - Multiple issue boards per project [moved](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/53811) to GitLab Free in 12.1.
> - Multiple issue boards per group are available in GitLab Premium.
-Multiple issue boards allow for more than one issue board for a given project **(FREE)** or group **(PREMIUM)**.
+Multiple issue boards allow for more than one issue board for a given project in GitLab Free or group in GitLab Premium and higher tiers.
This is great for large projects with more than one team or when a repository hosts the code of multiple products.
Using the search box at the top of the menu, you can filter the listed boards.
@@ -275,7 +275,7 @@ Users on GitLab Free can use a single group issue board.
### 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 11.0.
As in a regular list showing all issues with a chosen label, you can add
an assignee list that shows all issues assigned to a user.
@@ -295,7 +295,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 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:
@@ -333,7 +333,7 @@ to and from a iteration list to manipulate the iteration of the dragged issues.
### Group issues in swimlanes **(PREMIUM)**
-> - Grouping by epic [introduced](https://gitlab.com/groups/gitlab-org/-/epics/3352) in [GitLab Premium](https://about.gitlab.com/pricing/) 13.6.
+> - Grouping by epic [introduced](https://gitlab.com/groups/gitlab-org/-/epics/3352) in GitLab 13.6.
> - Editing issue titles in the issue sidebar [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/232745) in GitLab 13.8.
> - Editing iteration in the issue sidebar [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/290232) in GitLab 13.9.
@@ -356,7 +356,7 @@ appears on the right. There you can see and edit the issue's:
- Title
- Assignees
-- Epic **(PREMIUM)**
+- [Epic](../group/epics/index.md)
- Milestone
- Time tracking value (view only)
- Due date
@@ -506,14 +506,14 @@ You can filter by the following:
- Assignee
- Author
-- Epic
-- Iteration
+- [Epic](../group/epics/index.md)
+- [Iteration](../group/iterations/index.md)
- Label
- Milestone
- My Reaction
- Release
- Type (issue/incident)
-- Weight
+- [Weight](issues/issue_weight.md)
#### Filtering issues in a group board
@@ -536,7 +536,7 @@ changing a label.
A typical workflow of using an issue board would be:
-1. You have [created](labels.md#label-management) and [prioritized](labels.md#label-priority)
+1. You [create](labels.md#create-a-label) and [prioritize](labels.md#set-label-priority)
labels to categorize your issues.
1. You have a bunch of issues (ideally labeled).
1. You visit the issue board and start [creating lists](#create-a-new-list) to
diff --git a/doc/user/project/issues/csv_export.md b/doc/user/project/issues/csv_export.md
index 947fbdcc2d1..e5d698fa97a 100644
--- a/doc/user/project/issues/csv_export.md
+++ b/doc/user/project/issues/csv_export.md
@@ -52,7 +52,7 @@ export, after which the email is prepared.
## Sorting
-Exported issues are always sorted by `Issue ID`.
+Exported issues are always sorted by `Title`.
## Format
@@ -63,11 +63,11 @@ the values:
| Column | Description |
|------------------------------------------|-----------------------------------------------------------|
+| Title | Issue `title` |
+| Description | Issue `description` |
| Issue ID | Issue `iid` |
| URL | A link to the issue on GitLab |
-| Title | Issue `title` |
| State | `Open` or `Closed` |
-| Description | Issue `description` |
| Author | Full name of the issue author |
| Author Username | Username of the author, with the `@` symbol omitted |
| Assignee | Full name of the issue assignee |
@@ -85,6 +85,10 @@ the values:
| [Epic](../../group/epics/index.md) ID | ID of the parent epic, introduced in 12.7 |
| [Epic](../../group/epics/index.md) Title | Title of the parent epic, introduced in 12.7 |
+In GitLab 14.7 and earlier, the first two columns were `Issue ID` and `URL`,
+which [caused an issue](https://gitlab.com/gitlab-org/gitlab/-/issues/34769)
+when importing back into GitLab.
+
## Limitations
- Export Issues to CSV is not available at the Group's Issues List.
diff --git a/doc/user/project/issues/issue_data_and_actions.md b/doc/user/project/issues/issue_data_and_actions.md
index 66ca29c094e..e9f3f4be1c3 100644
--- a/doc/user/project/issues/issue_data_and_actions.md
+++ b/doc/user/project/issues/issue_data_and_actions.md
@@ -6,4 +6,6 @@ remove_date: '2022-02-24'
This file was moved to [another location](index.md).
<!-- This redirect file can be deleted after <2022-02-24>. -->
-<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/#move-or-rename-a-page -->
+<!-- Redirects that point to other docs in the same project expire in three months. -->
+<!-- Redirects that point to docs in a different project or site (for example, link is not relative and starts with `https:`) expire in one year. -->
+<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/redirects.html -->
diff --git a/doc/user/project/issues/managing_issues.md b/doc/user/project/issues/managing_issues.md
index 155d6260a5c..58591129d97 100644
--- a/doc/user/project/issues/managing_issues.md
+++ b/doc/user/project/issues/managing_issues.md
@@ -19,7 +19,7 @@ You can create an issue in many ways in GitLab:
- [From a project](#from-a-project)
- [From a group](#from-a-group)
-- [From another issue](#from-another-issue)
+- [From another issue or incident](#from-another-issue-or-incident)
- [From an issue board](#from-an-issue-board)
- [By sending an email](#by-sending-an-email)
- [Using a URL with prefilled values](#using-a-url-with-prefilled-values)
@@ -70,9 +70,10 @@ The newly created issue opens.
The project you selected most recently becomes the default for your next visit.
This can save you a lot of time and clicks, if you mostly create issues for the same project.
-### From another issue
+### From another issue or incident
-> New issue becoming linked to the issue of origin [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68226) in GitLab 14.3.
+> - New issue becoming linked to the issue of origin [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68226) in GitLab 14.3.
+> - **Relate to…** checkbox [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/198494) in GitLab 14.9.
You can create a new issue from an existing one. The two issues can then be marked as related.
@@ -83,10 +84,10 @@ Prerequisites:
To create an issue from another issue:
1. In an existing issue, select the vertical ellipsis (**{ellipsis_v}**).
-1. Select **New issue**.
+1. Select **New related issue**.
1. Complete the [fields](#fields-in-the-new-issue-form).
- The new issue's description is prefilled with `Related to #123`, where `123` is the ID of the
- issue of origin. If you keep this mention in the description, the two issues become
+ The new issue form has a **Relate to issue #123** checkbox, where `123` is the ID of the
+ issue of origin. If you keep this checkbox checked, the two issues become
[linked](related_issues.md).
1. Select **Create issue**.
@@ -160,6 +161,9 @@ To regenerate the email address:
### Using a URL with prefilled values
+> - Ability to use both `issuable_template` and `issue[description]` in the same URL [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/80554) in GitLab 14.9.
+> - Ability to specify `add_related_issue` [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/198494) in GitLab 14.9.
+
To link directly to the new issue page with prefilled fields, use query
string parameters in a URL. You can embed a URL in an external
HTML page to create issues with certain fields prefilled.
@@ -168,9 +172,10 @@ HTML page to create issues with certain fields prefilled.
| -------------------- | --------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
| Title | `issue[title]` | Must be [URL-encoded](../../../api/index.md#namespaced-path-encoding). |
| Issue type | `issue[issue_type]` | Either `incident` or `issue`. |
-| Description template | `issuable_template` | Cannot be used at the same time as `issue[description]`. Must be [URL-encoded](../../../api/index.md#namespaced-path-encoding). |
-| Description | `issue[description]` | Cannot be used at the same time as `issuable_template`. Must be [URL-encoded](../../../api/index.md#namespaced-path-encoding). |
+| Description template | `issuable_template` | Must be [URL-encoded](../../../api/index.md#namespaced-path-encoding). |
+| Description | `issue[description]` | Must be [URL-encoded](../../../api/index.md#namespaced-path-encoding). If used in combination with `issuable_template` or a [default issue template](../description_templates.md#set-a-default-template-for-merge-requests-and-issues), the `issue[description]` value is appended to the template. |
| Confidential | `issue[confidential]` | If `true`, the issue is marked as confidential. |
+| Relate to… | `add_related_issue` | A numeric issue ID. If present, the issue form shows a [**Relate to…** checkbox](#from-another-issue-or-incident) to optionally link the new issue to the specified existing issue. |
Adapt these examples to form your new issue URL with prefilled fields.
To create an issue in the GitLab project:
@@ -264,7 +269,7 @@ When bulk editing issues in a project, you can edit the following attributes:
- [Notification](../../profile/notifications.md) subscription
- [Iteration](../../group/iterations/index.md)
-### Bulk edit issues from a group
+### Bulk edit issues from a group **(PREMIUM)**
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/7249) in GitLab 12.1.
> - Assigning epic [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/210470) in GitLab 13.2.
@@ -573,13 +578,11 @@ To copy the issue's email address:
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/17589) in GitLab 13.3. Disabled by default.
> - [Enabled on GitLab.com](https://gitlab.com/gitlab-com/gl-infra/production/-/issues/3413) in GitLab 13.9.
> - [Enabled on self-managed](https://gitlab.com/gitlab-org/gitlab/-/issues/17589) in GitLab 14.5.
-
-FLAG:
-On self-managed GitLab, by default this feature is available. To hide the feature per project or for your entire instance, ask an administrator to
-[disable the feature flags](../../../administration/feature_flags.md) named `real_time_issue_sidebar` and `broadcast_issue_updates`.
-On GitLab.com, this feature is available.
+> - [Generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/17589) in GitLab 14.9. Feature flags `real_time_issue_sidebar` and `broadcast_issue_updates` removed.
Assignees in the sidebar are updated in real time.
+When you're viewing an issue and somebody changes its assignee,
+you can see the change without having to refresh the page.
## Assignee
diff --git a/doc/user/project/issues/multiple_assignees_for_issues.md b/doc/user/project/issues/multiple_assignees_for_issues.md
index f957d701a3b..279f297d016 100644
--- a/doc/user/project/issues/multiple_assignees_for_issues.md
+++ b/doc/user/project/issues/multiple_assignees_for_issues.md
@@ -39,4 +39,4 @@ to assign the issue to.
![adding multiple assignees](img/multiple_assignees.gif)
-To remove an assignee, deselect them from the same dropdown menu.
+To remove an assignee, clear them from the same dropdown menu.
diff --git a/doc/user/project/issues/related_issues.md b/doc/user/project/issues/related_issues.md
index f83ebc5e8a8..b8151ac873a 100644
--- a/doc/user/project/issues/related_issues.md
+++ b/doc/user/project/issues/related_issues.md
@@ -75,4 +75,9 @@ Access our [permissions](../../permissions.md) page for more information.
When you [add a linked issue](#add-a-linked-issue), you can show that it **blocks** or
**is blocked by** another issue.
-Issues that block other issues have an icon (**{issue-block}**) shown in the issue lists and [boards](../issue_board.md).
+Issues that block other issues have an icon (**{issue-block}**) next to their title, shown in the
+issue lists and [boards](../issue_board.md).
+The icon disappears when the blocking issue is closed or their relationship is changed or
+[removed](#remove-a-linked-issue).
+
+If you try to close a blocked issue using the "Close issue" button, a confirmation message appears.
diff --git a/doc/user/project/issues/sorting_issue_lists.md b/doc/user/project/issues/sorting_issue_lists.md
index 329f65bfacd..9311ef590df 100644
--- a/doc/user/project/issues/sorting_issue_lists.md
+++ b/doc/user/project/issues/sorting_issue_lists.md
@@ -49,7 +49,7 @@ Ties are broken arbitrarily. Only the highest prioritized label is checked,
and labels with a lower priority are ignored.
For more information, see [issue 14523](https://gitlab.com/gitlab-org/gitlab/-/issues/14523).
-To learn more about priority labels, read the [Labels](../labels.md#label-priority) documentation.
+To learn how to change label priority, see [Label priority](../labels.md#set-label-priority).
## Sorting by last updated
@@ -98,7 +98,9 @@ When you sort by **Priority**, the issue order changes to sort in this order:
1. Issues with a higher priority label.
1. Issues without a prioritized label.
-To learn more about priority, read the [Labels](../labels.md#label-priority) documentation.
+Ties are broken arbitrarily.
+
+To learn how to change label priority, see [Label priority](../labels.md#set-label-priority).
## Sorting by title
diff --git a/doc/user/project/labels.md b/doc/user/project/labels.md
index 7ccc39eeb8b..18197cd860f 100644
--- a/doc/user/project/labels.md
+++ b/doc/user/project/labels.md
@@ -6,145 +6,270 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Labels **(FREE)**
-As your count of issues, merge requests, and epics grows in GitLab, it's more and more challenging
+As your count of issues, merge requests, and epics grows in GitLab, it gets more challenging
to keep track of those items. Especially as your organization grows from just a few people to
-hundreds or thousands. This is where labels come in. They help you organize and tag your work
-so you can track and find the work items you're interested in.
+hundreds or thousands. With labels, you can organize and tag your work, and track the work items
+you're interested in.
Labels are a key part of [issue boards](issue_board.md). With labels you can:
-- Categorize epics, issues, and merge requests using colors and descriptive titles like
+- Categorize [epics](../group/epics/index.md), issues, and merge requests using colors and descriptive titles like
`bug`, `feature request`, or `docs`.
-- Dynamically filter and manage epics, issues, and merge requests.
+- Dynamically filter and manage [epics](../group/epics/index.md), issues, and merge requests.
- [Search lists of issues, merge requests, and epics](../search/index.md#search-issues-and-merge-requests),
as well as [issue boards](../search/index.md#issue-boards).
-## Project labels and group labels
+## Types of labels
-There are two types of labels in GitLab:
+You can use two types of labels in GitLab:
- **Project labels** can be assigned to issues and merge requests in that project only.
-- **Group labels** can be assigned to issues and merge requests in any project in
- the selected group or its subgroups.
- - They can also be assigned to epics in the selected group or its subgroups.**(ULTIMATE)**
+- **Group labels** can be assigned to issues, merge requests, and [epics](../group/epics/index.md)
+ in any project in the selected group or its subgroups.
## Assign and unassign labels
> Unassigning labels with the **X** button [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/216881) in GitLab 13.5.
-Every issue, merge request, and epic can be assigned any number of labels. The labels are
-managed in the right sidebar, where you can assign or unassign labels as needed.
+You can assign labels to any issue, merge request, or epic.
To assign or unassign a label:
-1. In the **Labels** section of the sidebar, click **Edit**.
+1. In the **Labels** section of the sidebar, select **Edit**.
1. In the **Assign labels** list, search for labels by typing their names.
You can search repeatedly to add more labels.
The selected labels are marked with a checkmark.
-1. Click the labels you want to assign or unassign.
+1. Select the labels you want to assign or unassign.
1. To apply your changes to labels, select **X** next to **Assign labels** or select any area
outside the label section.
-Alternatively, to unassign a label, click the **X** on the label you want to unassign.
+Alternatively, to unassign a label, select the **X** on the label you want to unassign.
-You can also assign a label with the `/label` [quick action](quick_actions.md),
-remove labels with `/unlabel`, and reassign labels (remove all and assign new ones) with `/relabel`.
+You can also assign and unassign labels with [quick actions](quick_actions.md):
-## Label management
+- Assign labels with `/label`.
+- Remove labels with `/unlabel`.
+- Remove all labels and assign new ones with `/relabel`.
-Users with a [permission level](../permissions.md) of Reporter or higher are able to create
-and edit labels.
+## View available labels
-### Project labels
+### View project labels
-> Showing all inherited labels [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/241990) in GitLab 13.5.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/241990) in GitLab 13.5: the label list in a project also shows all inherited labels.
-To view a project's available labels, in the project, go to **Project information > Labels**.
-Its list of labels includes both the labels defined at the project level, and
-all labels defined by its ancestor groups. For each label, you can see the
-project or group path from where it was created. You can filter the list by
-entering a search query in the **Filter** field, and then clicking its search
-icon (**{search}**).
+To view the **project's labels**:
-To create a new project label:
+1. On the top bar, select **Menu > Projects** and find your project.
+1. On the left sidebar, select **Project information > Labels**.
-1. In your project, go to **Project information > Labels**.
-1. Select the **New label** button.
+Or:
+
+1. View an issue or merge request.
+1. On the right sidebar, in the **Labels** section, select **Edit**.
+1. Select **Manage project labels**.
+
+The list of labels includes both the labels created in the project and
+all labels created in the project's ancestor groups. For each label, you can see the
+project or group path where it was created.
+
+### View group labels
+
+To view the **group's labels**:
+
+1. On the top bar, select **Menu > Groups** and find your group.
+1. On the left sidebar, select **Group information > Labels**.
+
+Or:
+
+1. View an epic.
+1. On the right sidebar, in the **Labels** section, select **Edit**.
+1. Select **Manage group labels**.
+
+The list includes all labels created only in the group. It does not list any labels created in
+the group's projects.
+
+## Create a label
+
+Prerequisites:
+
+- You must have at least the Reporter role for the project or group.
+
+### Create a project label
+
+To create a project label:
+
+1. On the top bar, select **Menu > Projects** and find your project.
+1. On the left sidebar, select **Project information > Labels**.
+1. Select **New label**.
+1. In the **Title** field, enter a short, descriptive name for the label. You
+ can also use this field to create [scoped, mutually exclusive labels](#scoped-labels).
+1. Optional. In the **Description** field, enter additional
+ information about how and when to use this label.
+1. Optional. Select a color by selecting from the available colors, or enter a hex color value for
+ a specific color in the **Background color** field.
+1. Select **Create label**.
+
+### Create a project label from an issue or merge request
+
+You can also create a new project label from an issue or merge request.
+Labels you create this way belong to the same project as the issue or merge request.
+
+Prerequisites:
+
+- You must have at least the Reporter role for the project.
+
+To do so:
+
+1. View an issue or merge request.
+1. On the right sidebar, in the **Labels** section, select **Edit**.
+1. Select **Create project label**.
+1. Fill in the name field. You can't specify a description if creating a label this way.
+ You can add a description later by [editing the label](#edit-a-label).
+1. Optional. Select a color by selecting from the available colors, or enter a hex color value for
+ a specific color.
+1. Select **Create**.
+
+### Create a group label
+
+To create a group label:
+
+1. On the top bar, select **Menu > Groups** and find your group.
+1. On the left sidebar, select **Group information > Labels**.
+1. Select **New label**.
1. In the **Title** field, enter a short, descriptive name for the label. You
can also use this field to create [scoped, mutually exclusive labels](#scoped-labels).
-1. Optional. In the **Description** field, you can enter additional
+1. Optional. In the **Description** field, enter additional
information about how and when to use this label.
-1. Optional. Select a background color for the label by selecting one of the
- available colors, or by entering a hex color value in the **Background color**
- field.
+1. Optional. Select a color by selecting from the available colors, or enter a hex color value for
+ a specific color in the **Background color** field.
1. Select **Create label**.
-You can also create a new project label from within an issue or merge request. In the
-label section of the right sidebar of an issue or a merge request:
+### Create a group label from an epic **(PREMIUM)**
+
+You can also create a new group label from an epic.
+Labels you create this way belong to the same group as the epic.
+
+Prerequisites:
+
+- You must have at least the Reporter role for the group.
-1. Click **Edit**.
-1. Click **Create project label**.
- - Fill in the name field. Note that you can't specify a description if creating a label
- this way. You can add a description later by editing the label (see below).
- - Optional. Select a color by clicking on the available colors, or input a hex
- color value for a specific color.
-1. Click **Create**.
+To do so:
-To edit a label after you create it, select (**{pencil}**).
+1. View an epic.
+1. On the right sidebar, in the **Labels** section, select **Edit**.
+1. Select **Create group label**.
+1. Fill in the name field. You can't specify a description if creating a label this way.
+ You can add a description later by [editing the label](#edit-a-label).
+1. Optional. Select a color by selecting from the available colors,enter input a hex color value
+ for a specific color.
+1. Select **Create**.
-To delete a project label, select (**{ellipsis_v}**) next to the **Subscribe** button
-and select **Delete** or select **Delete** when you edit a label.
+## Edit a label
+
+Prerequisites:
+
+- You must have at least the Reporter role for the project or group.
+
+### Edit a project label
+
+To edit a **project** label:
+
+1. On the top bar, select **Menu > Projects** and find your project.
+1. On the left sidebar, select **Project information > Labels**.
+1. Next to the label you want to edit, select **Edit** (**{pencil}**).
+
+### Edit a group label
+
+To edit a **group** label:
+
+1. On the top bar, select **Menu > Groups** and find your group.
+1. On the left sidebar, select **Group information > Labels**.
+1. Next to the label you want to edit, select **Edit** (**{pencil}**).
+
+## Delete a label
WARNING:
-If you delete a label, it is permanently deleted. All references to the label are removed from the system and you cannot undo the deletion.
+If you delete a label, it is permanently deleted. All references to the label are removed from the
+system and you cannot undo the deletion.
+
+Prerequisites:
-#### Promote a project label to a group label
+- You must have at least the Reporter role for the project.
+
+### Delete a project label
+
+To delete a **project** label:
+
+1. On the top bar, select **Menu > Projects** and find your project.
+1. On the left sidebar, select **Project information > Labels**.
+1. Either:
+
+ - Next to the **Subscribe** button, select (**{ellipsis_v}**).
+ - Next to the label you want to edit, select **Edit** (**{pencil}**).
+
+1. Select **Delete**.
+
+### Delete a group label
+
+To delete a **group** label:
+
+1. On the top bar, select **Menu > Groups** and find your group.
+1. On the left sidebar, select **Group information > Labels**.
+1. Either:
+
+ - Next to the **Subscribe** button, select (**{ellipsis_v}**).
+ - Next to the label you want to edit, select **Edit** (**{pencil}**).
+
+1. Select **Delete**.
+
+## Promote a project label to a group label
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/231472) in GitLab 13.6: promoting a project label keeps that label's ID and changes it into a group label. Previously, promoting a project label created a new group label with a new ID and deleted the old label.
-If you previously created a project label and now want to make it available for other
-projects within the same group, you can promote it to a group label.
+You might want to make a project label available for other
+projects in the same group. Then, you can promote the label to a group label.
If other projects in the same group have a label with the same title, they are all
merged with the new group label. If a group label with the same title exists, it is
also merged.
-All issues, merge requests, issue board lists, issue board filters, and label subscriptions
-with the old labels are assigned to the new group label.
+WARNING:
+Promoting a label is a permanent action and cannot be reversed.
-The new group label has the same ID as the previous project label.
+Prerequisites:
-WARNING:
-Promoting a label is a permanent action, and cannot be reversed.
+- You must have at least the Reporter role for the project.
+- You must have at least the Reporter role for the project's parent group.
To promote a project label to a group label:
-1. Navigate to **Project information > Labels** in the project.
-1. Click on the three dots (**{ellipsis_v}**) next to the **Subscribe** button and
+1. On the top bar, select **Menu > Projects** and find your project.
+1. On the left sidebar, select **Project information > Labels**.
+1. Next to the **Subscribe** button, select the three dots (**{ellipsis_v}**) and
select **Promote to group label**.
-### Group labels
+All issues, merge requests, issue board lists, issue board filters, and label subscriptions
+with the old labels are assigned to the new group label.
+
+The new group label has the same ID as the previous project label.
-To view the group labels list, navigate to the group and click **Group information > Labels**.
-The list includes all labels that are defined at the group level only. It does not
-list any labels that are defined in projects. You can filter the list by entering
-a search query at the top and clicking search (**{search}**).
+## Generate default project labels
-To create a **group label**, navigate to **Group information > Labels** in the group and
-follow the same process as [creating a project label](#project-labels).
+If a project or its parent group has no labels, you can generate a default set of project
+labels from the label list page.
-#### Create group labels from epics **(ULTIMATE)**
+Prerequisites:
-You can create group labels from the epic sidebar. The labels you create
-belong to the immediate group to which the epic belongs. The process is the same as
-creating a [project label from an issue or merge request](#project-labels).
+- You must have at least the Reporter role for the project.
+- The project must have no labels present.
-### Generate default labels
+To add the default labels to the project:
-If a project or group has no labels, you can generate a default set of project or group
-labels from the label list page. The page shows a **Generate a default set of labels**
-button if the list is empty. Select the button to add the following default labels
-to the project:
+1. On the top bar, select **Menu > Projects** and find your project.
+1. On the left sidebar, select **Project information > Labels**.
+1. Select **Generate a default set of labels**.
+
+The following labels are created:
- `bug`
- `confirmed`
@@ -157,131 +282,143 @@ to the project:
## Scoped labels **(PREMIUM)**
-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
-by preventing certain labels from being used together.
-
-A label is scoped when it uses a special double-colon (`::`) syntax in the label's
-title, for example:
+Teams can use scoped labels to annotate issues, merge requests, and epics with mutually exclusive
+labels. By preventing certain labels from being used together, you can create more complex workflows.
![Scoped labels](img/labels_key_value_v13_5.png)
-An issue, merge request or epic cannot have two scoped labels, of the form `key::value`,
-with the same `key`. Adding a new label with the same `key`, but a different `value`
-causes the previous `key` label to be replaced with the new label.
+A scoped label uses a double-colon (`::`) syntax in its title, for example: `workflow::in-review`.
-For example:
+An issue, merge request, or epic cannot have two scoped labels, of the form `key::value`,
+with the same `key`. If you add a new label with the same `key` but a different `value`,
+the previous `key` label is replaced with the new label.
-1. An issue is identified as being low priority, and a `priority::low` project
- label is added to it.
-1. After more review the issue priority is increased, and a `priority::high` label is
- added.
-1. GitLab automatically removes the `priority::low` label, as an issue should not
- have two priority labels at the same time.
+<i class="fa fa-youtube-play youtube" aria-hidden="true"></i>
+For a video overview, see [Scoped Labels Speed Run](https://www.youtube.com/watch?v=ebyCiKMFODg).
### Filter by scoped labels
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/12285) in GitLab 14.4.
-To filter issue, merge request, or epic lists for ones with labels that belong to a given scope, enter
+To filter issue, merge request, or epic lists by a given scope, enter
`<scope>::*` in the searched label name.
For example, filtering by the `platform::*` label returns issues that have `platform::iOS`,
`platform::Android`, or `platform::Linux` labels.
NOTE:
-This is not available on the [issues or merge requests dashboard pages](../search/index.md#search-issues-and-merge-requests).
+Filtering by scoped labels not available on the [issues or merge requests dashboard pages](../search/index.md#search-issues-and-merge-requests).
+
+### Scoped labels examples
+
+**Example 1.** Updating issue priority:
+
+1. You decide that an issue is of low priority, and assign it the `priority::low` label.
+1. After more review, you realize the issue's priority is higher increased, and you assign it the
+ `priority::high` label.
+1. Because an issue shouldn't have two priority labels at the same time, GitLab removes the
+ `priority::low` label.
+
+**Example 2.** You want a custom field in issues to track the operating system platform
+that your features target, where each issue should only target one platform.
+
+You create three labels:
+
+- `platform::iOS`
+- `platform::Android`
+- `platform::Linux`
+
+If you assign any of these labels to an issue automatically removes any other existing label that
+starts with `platform::`.
+
+**Example 3.** You can use scoped labels to represent the workflow states of your teams.
-### Workflows with scoped labels
+Suppose you have the following labels:
-Suppose you wanted a custom field in issues to track the operating system platform
-that your features target, where each issue should only target one platform. You
-would then create three labels `platform::iOS`, `platform::Android`, `platform::Linux`.
-Applying any one of these labels on a given issue would automatically remove any other
-existing label that starts with `platform::`.
+- `workflow::development`
+- `workflow::review`
+- `workflow::deployed`
-The same pattern could be applied to represent the workflow states of your teams.
-Suppose you have the labels `workflow::development`, `workflow::review`, and
-`workflow::deployed`. If an issue already has the label `workflow::development`
-applied, and a developer wanted to advance the issue to `workflow::review`, they
-would simply apply that label, and the `workflow::development` label would
-automatically be removed. This behavior already exists when you move issues
-across label lists in an [issue board](issue_board.md#create-workflows), but
-now, team members who may not be working in an issue board directly would still
-be able to advance workflow states consistently in issues themselves.
+If an issue already has the label `workflow::development` and a developer wants to show that the
+issue is now under review, they assign the `workflow::review`, and the `workflow::development` label
+is removed.
-This functionality is demonstrated in a video regarding
-[using scoped labels for custom fields and workflows](https://www.youtube.com/watch?v=4BCBby6du3c).
+The same happens when you move issues across label lists in an
+[issue board](issue_board.md#create-workflows). With scoped labels, team members not working in an
+issue board can also advance workflow states consistently in issues themselves.
-### Scoped labels with nested scopes
+For a video explanation, see:
+
+<div class="video-fallback">
+ See the video: <a href="https://www.youtube.com/watch?v=4BCBby6du3c">Use scoped labels for custom fields and custom workflows</a>.
+</div>
+<figure class="video-container">
+ <iframe src="https://www.youtube.com/embed/4BCBby6du3c" frameborder="0" allowfullscreen="true"> </iframe>
+</figure>
+
+### Nested scopes
You can create a label with a nested scope by using multiple double colons `::` when creating
it. In this case, everything before the last `::` is the scope.
-For example, `workflow::backend::review` and `workflow::backend::development` are valid
-scoped labels, but they **can't** exist on the same issue at the same time, as they
-both share the same scope, `workflow::backend`.
+For example, if your project has these labels:
-Additionally, `workflow::backend::review` and `workflow::frontend::review` are valid
-scoped labels, and they **can** exist on the same issue at the same time, as they
-both have different scopes, `workflow::frontend` and `workflow::backend`.
+- `workflow::backend::review`
+- `workflow::backend::development`
+- `workflow::frontend::review`
-## Subscribing to labels
+An issue **can't** have both `workflow::backend::review` and `workflow::backend::development`
+labels at the same time, because they both share the same scope: `workflow::backend`.
-From the project label list page and the group label list page, you can click **Subscribe**
-to the right of any label to enable [notifications](../profile/notifications.md) for that
-label. You are notified whenever the label is assigned to an epic,
-issue, or merge request.
+On the other hand, an issue **can** have both `workflow::backend::review` and `workflow::frontend::review`
+labels at the same time, because they both have different scopes: `workflow::frontend` and `workflow::backend`.
-If you are subscribing to a group label from within a project, you can select to subscribe
-to label notifications for the project only, or the whole group.
+## Receive notifications when a label is used
-![Labels subscriptions](img/labels_subscriptions_v13_5.png)
+You can subscribe to a label to [receive notifications](../profile/notifications.md) whenever the
+label is assigned to an issue, merge request, or epic.
-## Label priority
+To subscribe to a label:
-Labels can have relative priorities, which are used in the **Label priority** and
-**Priority** sort orders of issues and merge request list pages. Prioritization
-for both group and project labels happens at the project level, and cannot be done
-from the group label list.
+1. [View the label list page.](#view-available-labels)
+1. To the right of any label, select **Subscribe**.
+1. Optional. If you are subscribing to a group label from a project, select either:
+ - **Subscribe at project level** to be notified about events in this project.
+ - **Subscribe at group level**: to be notified about events in the whole group.
-NOTE:
-Priority sorting is based on the highest priority label only. [This discussion](https://gitlab.com/gitlab-org/gitlab/-/issues/14523) considers changing this.
+## Set label priority
-From the project label list page, star a label to indicate that it has a priority.
-
-![Labels prioritized](img/labels_prioritized_v13_5.png)
+Labels can have relative priorities, which are used when you sort issue and merge request lists
+by [label priority](issues/sorting_issue_lists.md#sorting-by-label-priority) and [priority](issues/sorting_issue_lists.md#sorting-by-priority).
-Drag starred labels up and down the list to change their priority, where higher in the list
-means higher priority.
+When prioritizing labels, you must do it from a project.
+It's not possible to do it from the group label list.
-![Drag to change label priority](img/labels_drag_priority_v12_1.gif)
+NOTE:
+Priority sorting is based on the highest priority label only.
+[This discussion](https://gitlab.com/gitlab-org/gitlab/-/issues/14523) considers changing this.
-On the merge request and issue list pages (for both groups and projects) you
-can sort by `Label priority` or `Priority`.
+Prerequisites:
-If you sort by `Label priority`, GitLab uses this sort comparison order:
+- You must have at least the Reporter role for the project.
-1. Items with a higher priority label.
-1. Items without a prioritized label.
+To prioritize a 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)
-for more information.
+1. On the top bar, select **Menu > Projects** and find your project.
+1. On the left sidebar, select **Project information > Labels**.
+1. Next to a label you want to prioritize, select the star (**{star-o}**).
-![Labels sort label priority](img/labels_sort_label_priority.png)
+![Labels prioritized](img/labels_prioritized_v13_5.png)
-If you sort by `Priority`, GitLab uses this sort comparison order:
+This label now appears at the top of the label list, under **Prioritized Labels**.
-1. Items with milestones that have due dates, where the soonest assigned [milestone](milestones/index.md)
- is listed first.
-1. Items with milestones with no due dates.
-1. Items with a higher priority label.
-1. Items without a prioritized label.
+To change the relative priority of these labels, drag them up and down the list.
+The labels higher in the list get higher priority.
-Ties are broken arbitrarily.
+![Drag to change label priority](img/labels_drag_priority_v12_1.gif)
-![Labels sort priority](img/labels_sort_priority.png)
+To learn what happens when you sort by priority or label priority, see
+[Sorting and ordering issue lists](issues/sorting_issue_lists.md).
## Troubleshooting
diff --git a/doc/user/project/members/index.md b/doc/user/project/members/index.md
index 8be2ade3f2f..c3d5dca0675 100644
--- a/doc/user/project/members/index.md
+++ b/doc/user/project/members/index.md
@@ -10,16 +10,43 @@ Members are the users and groups who have access to your project.
Each member gets a role, which determines what they can do in the project.
+Project members can:
+
+1. Be [direct members](#add-users-to-a-project) of the project.
+1. [Inherit membership](#inherited-membership) of the project from the project's group.
+1. Be a member of a group that was [shared](share_project_with_groups.md) with the project.
+1. Be a member of a group that was [shared with the project's group](../../group/index.md#share-a-group-with-another-group).
+
+```mermaid
+flowchart RL
+ subgraph Group A
+ A(Direct member)
+ B{{Shared member}}
+ subgraph Project A
+ H(1. Direct member)
+ C{{2. Inherited member}}
+ D{{4. Inherited member}}
+ E{{3. Shared member}}
+ end
+ A-->|Direct membership of Group A\nInherited membership of Project A|C
+ end
+ subgraph Group C
+ G(Direct member)
+ end
+ subgraph Group B
+ F(Direct member)
+ end
+ F-->|Group B\nshared with\nGroup A|B
+ B-->|Inherited membership of Project A|D
+ G-->|Group C shared with Project A|E
+```
+
## Add users to a project
> - [Changed](https://gitlab.com/gitlab-org/gitlab/-/issues/247208) in GitLab 13.11 from a form to a modal window [with a flag](../../feature_flags.md). Disabled by default.
> - Modal window [enabled on GitLab.com and self-managed](https://gitlab.com/gitlab-org/gitlab/-/issues/247208) in GitLab 14.8.
-
-FLAG:
-On self-managed GitLab, by default the modal window feature is available.
-To hide the feature, ask an administrator to [disable the feature flag](../../../administration/feature_flags.md)
-named `invite_members_group_modal`.
-On GitLab.com, this feature is available.
+> - [Generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/352526) in GitLab 14.9.
+ [Feature flag `invite_members_group_modal`](https://gitlab.com/gitlab-org/gitlab/-/issues/352526) removed.
Add users to a project so they become members and have permission
to perform actions.
@@ -52,12 +79,8 @@ using the email address the invitation was sent to.
> - [Changed](https://gitlab.com/gitlab-org/gitlab/-/issues/247208) in GitLab 13.11 from a form to a modal window [with a flag](../../feature_flags.md). Disabled by default.
> - Modal window [enabled on GitLab.com and self-managed](https://gitlab.com/gitlab-org/gitlab/-/issues/247208) in GitLab 14.8.
-
-FLAG:
-On self-managed GitLab, by default the modal window feature is available.
-To hide the feature, ask an administrator to [disable the feature flag](../../../administration/feature_flags.md)
-named `invite_members_group_modal`.
-On GitLab.com, this feature is available.
+> - [Generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/352526) in GitLab 14.9.
+ [Feature flag `invite_members_group_modal`](https://gitlab.com/gitlab-org/gitlab/-/issues/352526) removed.
When you add a group to a project, each user in the group gets access to the project.
Each user's access is based on:
@@ -68,6 +91,7 @@ Each user's access is based on:
Prerequisite:
- You must have the Maintainer or Owner role.
+- Sharing the project with other groups must not be [prevented](../../group/index.md#prevent-a-project-from-being-shared-with-groups).
To add groups to a project:
@@ -98,11 +122,11 @@ To import users:
1. On the top bar, select **Menu > Projects** and find your project.
1. On the left sidebar, select **Project information > Members**.
-1. On the **Invite member** tab, at the bottom of the panel, select **Import**.
+1. Select **Import from a project**.
1. Select the project. You can view only the projects for which you're a maintainer.
1. Select **Import project members**.
-A success message is displayed and the new members are now displayed in the list.
+After the success message displays, refresh the page to view the new members.
## Inherited membership
@@ -139,7 +163,7 @@ To remove a member from a project:
1. On the top bar, select **Menu > Projects** and find your project.
1. On the left sidebar, select **Project information > Members**.
-1. Next to the project member you want to remove, select **Remove member** **{remove}**.
+1. Next to the project member you want to remove, select **Remove member**.
1. Optional. In the confirmation box, select the
**Also unassign this user from related issues and merge requests** checkbox.
1. To prevent leaks of sensitive information from private projects, verify the
diff --git a/doc/user/project/members/share_project_with_groups.md b/doc/user/project/members/share_project_with_groups.md
index 4e3bae2dc30..02a9b76ce38 100644
--- a/doc/user/project/members/share_project_with_groups.md
+++ b/doc/user/project/members/share_project_with_groups.md
@@ -15,10 +15,14 @@ Groups are used primarily to [create collections of projects](../../group/index.
take advantage of the fact that groups define collections of _users_, namely the group
members.
-## Sharing a project with a group of users
+## Share a project with a group of users
-NOTE:
-In GitLab 13.11, you can [replace this form with a modal window](#share-a-project-modal-window).
+> - [Changed](https://gitlab.com/gitlab-org/gitlab/-/issues/247208) in GitLab 13.11 from a form to a modal
+ window [with a flag](../../feature_flags.md). Disabled by default.
+> - Modal window [enabled on GitLab.com and self-managed](https://gitlab.com/gitlab-org/gitlab/-/issues/247208)
+ in GitLab 14.8.
+> - [Generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/352526) in GitLab 14.9.
+ [Feature flag `invite_members_group_modal`](https://gitlab.com/gitlab-org/gitlab/-/issues/352526) removed.
The primary mechanism to give a group of users, say 'Engineering', access to a project,
say 'Project Acme', in GitLab is to make the 'Engineering' group the owner of 'Project
@@ -28,9 +32,9 @@ 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 **Project information > Members**.
-1. Select the **Invite group** tab.
+1. Select **Invite a group**.
1. Add the 'Engineering' group with the maximum access level of your choice.
-1. Optional. Select an expiration date.
+1. Optional. Select an **Access expiration date**.
1. Select **Invite**.
After sharing 'Project Acme' with 'Engineering':
@@ -45,51 +49,19 @@ You can share a project only with:
Administrators can share projects with any group in the system.
-### Share a project modal window
-
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/247208) in GitLab 13.11.
-> - [Deployed behind a feature flag](../../feature_flags.md), disabled by default.
-> - Enabled on GitLab.com.
-> - Recommended for production use.
-> - Replaces the existing form with buttons to open a modal window.
-> - To use in GitLab self-managed instances, ask a GitLab administrator to [enable it](#enable-or-disable-modal-window).
-
-WARNING:
-This feature might not be available to you. Check the **version history** note above for details.
-
-In GitLab 13.11, you can optionally replace the sharing form with a modal window.
-To share a project after enabling this feature:
-
-1. Go to your project's page.
-1. On the left sidebar, go to **Project information > Members**, and then select **Invite a group**.
-1. Select a group, and select a **Max role**.
-1. Optional. Select an **Access expiration date**.
-1. Select **Invite**.
-
-### Enable or disable modal window **(FREE SELF)**
-
-The modal window for sharing a project is under development and is ready for production use. It is
-deployed behind a feature flag that is **disabled by default**.
-[GitLab administrators with access to the GitLab Rails console](../../../administration/feature_flags.md)
-can enable it.
-
-To enable it:
-
-```ruby
-Feature.enable(:invite_members_group_modal)
-```
+## Maximum access level
-To disable it:
+In the example above, the maximum access level of 'Developer' for members from 'Engineering' means that users with higher access levels in 'Engineering' ('Maintainer' or 'Owner') only have 'Developer' access to 'Project Acme'.
-```ruby
-Feature.disable(:invite_members_group_modal)
-```
+### Share a project with a subgroup
-## Maximum access level
+You can't share a project with a group that's an ancestor of a [subgroup](../../group/subgroups/index.md) the project is
+in. That means you can only share down the hierarchy. For example, `group/subgroup01/project`:
-In the example above, the maximum access level of 'Developer' for members from 'Engineering' means that users with higher access levels in 'Engineering' ('Maintainer' or 'Owner') only have 'Developer' access to 'Project Acme'.
+- Can not be shared with `group`.
+- Can be shared with `group/subgroup02` or `group/subgroup01/subgroup03`.
-## Sharing public project with private group
+## Share public project with private group
When sharing a public project with a private group, owners and maintainers of the project see the name of the group in the `members` page. Owners also have the possibility to see members of the private group they don't have access to when mentioning them in the issue or merge request.
diff --git a/doc/user/project/merge_requests/approvals/rules.md b/doc/user/project/merge_requests/approvals/rules.md
index fa447ea35af..01772e59127 100644
--- a/doc/user/project/merge_requests/approvals/rules.md
+++ b/doc/user/project/merge_requests/approvals/rules.md
@@ -175,7 +175,7 @@ granting them push access:
1. [Create a new group](../../../group/index.md#create-a-group).
1. [Add the user to the group](../../../group/index.md#add-users-to-a-group),
and select the Reporter role for the user.
-1. [Share the project with your group](../../members/share_project_with_groups.md#sharing-a-project-with-a-group-of-users),
+1. [Share the project with your group](../../members/share_project_with_groups.md#share-a-project-with-a-group-of-users),
based on the Reporter role.
1. Go to your project and select **Settings > General**.
1. Expand **Merge request (MR) approvals**.
diff --git a/doc/user/project/merge_requests/approvals/settings.md b/doc/user/project/merge_requests/approvals/settings.md
index 1e1c8ccb241..0a7fbc9ee95 100644
--- a/doc/user/project/merge_requests/approvals/settings.md
+++ b/doc/user/project/merge_requests/approvals/settings.md
@@ -140,9 +140,7 @@ To learn more, see [Coverage check approval rule](../../../../ci/pipelines/setti
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/285410) in GitLab 14.4. [Deployed behind the `group_merge_request_approval_settings_feature_flag` flag](../../../../administration/feature_flags.md), disabled by default.
> - [Enabled by default](https://gitlab.com/gitlab-org/gitlab/-/issues/285410) in GitLab 14.5.
-
-FLAG:
-On self-managed GitLab, by default this feature is available. To hide the feature per group, ask an administrator to [disable the feature flag](../../../../administration/feature_flags.md) named `group_merge_request_approval_settings_feature_flag`. On GitLab.com, this feature is available.
+> - [Feature flag `group_merge_request_approval_settings_feature_flag`](https://gitlab.com/gitlab-org/gitlab/-/issues/343872) removed in GitLab 14.9.
You can also enforce merge request approval settings:
diff --git a/doc/user/project/merge_requests/cherry_pick_changes.md b/doc/user/project/merge_requests/cherry_pick_changes.md
index 15ba6e9de98..fb41ec3eff6 100644
--- a/doc/user/project/merge_requests/cherry_pick_changes.md
+++ b/doc/user/project/merge_requests/cherry_pick_changes.md
@@ -66,11 +66,8 @@ git cherry-pick -m 2 7a39eb0
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/21268) in GitLab 13.11 behind a [feature flag](../../feature_flags.md), disabled by default.
> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/324154) in GitLab 14.0.
-WARNING:
-This feature might not be available to you. Check the **version history** note above for details.
-
-You can use the GitLab UI to cherry-pick merge requests into a project, even if the
-merge request is from a fork:
+You can cherry-pick merge requests from the same project, or forks of the same
+project, from the GitLab user interface:
1. In the merge request's secondary menu, click **Commits** to display the commit details page.
1. Click on the **Options** dropdown and select **Cherry-pick** to show the cherry-pick modal.
diff --git a/doc/user/project/merge_requests/code_quality.md b/doc/user/project/merge_requests/code_quality.md
index d735ce0ef91..10fc778d5ae 100644
--- a/doc/user/project/merge_requests/code_quality.md
+++ b/doc/user/project/merge_requests/code_quality.md
@@ -592,17 +592,17 @@ plugins:
If your merge requests do not show any code quality changes when using a custom tool,
ensure that the line property is an `integer`.
-### Code Quality CI job with Code Climate plugins enabled fails with error "engine <plugin_name> ran for 900 seconds and was killed"
+### Code Quality CI job with Code Climate plugins enabled fails with error
-If you enabled any of the Code Climate plugins, and the Code Quality CI job fails with the error below,
-it's likely the job takes longer than the default timeout of 900 seconds.
+If you enabled any of the Code Climate plugins, and the Code Quality CI job fails with the error
+below, it's likely the job takes longer than the default timeout of 900 seconds:
```shell
error: (CC::CLI::Analyze::EngineFailure) engine pmd ran for 900 seconds and was killed
Could not analyze code quality for the repository at /code
```
-To work around this problem, set `TIMEOUT_SECONDS` to a higher value in your `.gitlab.-ci.yml` file.
+To work around this problem, set `TIMEOUT_SECONDS` to a higher value in your `.gitlab.-ci.yml` file.
For example:
diff --git a/doc/user/project/merge_requests/commit_templates.md b/doc/user/project/merge_requests/commit_templates.md
index 0cc18d2117b..b9b65d759dc 100644
--- a/doc/user/project/merge_requests/commit_templates.md
+++ b/doc/user/project/merge_requests/commit_templates.md
@@ -69,6 +69,7 @@ GitLab creates a squash commit message with this template:
> - [Added](https://gitlab.com/gitlab-org/gitlab/-/issues/346805) `first_commit` and `first_multiline_commit` variables in GitLab 14.6.
> - [Added](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/75639) `url`, `approved_by`, and `merged_by` variables in GitLab 14.7.
> - [Added](https://gitlab.com/gitlab-org/gitlab/-/issues/20421) `co_authored_by` variable in GitLab 14.7.
+> - [Added](https://gitlab.com/gitlab-org/gitlab/-/issues/26303) `all_commits` variable in GitLab 14.9.
Commit message templates support these variables:
@@ -81,15 +82,20 @@ Commit message templates support these variables:
| `%{description}` | Description of the merge request. | `Merge request description.`<br>`Can be multiline.` |
| `%{reference}` | Reference to the merge request. | `group-name/project-name!72359` |
| `%{first_commit}` | Full message of the first commit in merge request diff. | `Update README.md` |
-| `%{first_multiline_commit}` | Full message of the first commit that's not a merge commit and has more than one line in message body. Merge Request title if all commits aren't multiline. | `Update README.md`<br><br>`Improved project description in readme file.` |
+| `%{first_multiline_commit}` | Full message of the first commit that's not a merge commit and has more than one line in message body. Merge request title if all commits aren't multiline. | `Update README.md`<br><br>`Improved project description in readme file.` |
| `%{url}` | Full URL to the merge request. | `https://gitlab.com/gitlab-org/gitlab/-/merge_requests/1` |
-| `%{approved_by}` | Line-separated list of the merge request approvers. This value is not updated until the first page refresh after an approval. | `Approved-by: Sidney Jones <sjones@example.com>` <br> `Approved-by: Zhang Wei <zwei@example.com>` |
+| `%{approved_by}` | Line-separated list of the merge request approvers. | `Approved-by: Sidney Jones <sjones@example.com>` <br> `Approved-by: Zhang Wei <zwei@example.com>` |
| `%{merged_by}` | User who merged the merge request. | `Alex Garcia <agarcia@example.com>` |
| `%{co_authored_by}` | Names and emails of commit authors in a `Co-authored-by` Git commit trailer format. Limited to authors of 100 most recent commits in merge request. | `Co-authored-by: Zane Doe <zdoe@example.com>` <br> `Co-authored-by: Blake Smith <bsmith@example.com>` |
+| `%{all_commits}` | Messages from all commits in the merge request. Limited to 100 most recent commits. Skips commit bodies exceeding 100KiB and merge commit messages. | `* Feature introduced` <br><br> `This commit implements feature` <br> `Changelog:added` <br><br> `* Bug fixed` <br><br> `* Documentation improved` <br><br>`This commit introduced better docs.`|
Any line containing only an empty variable is removed. If the line to be removed is both
preceded and followed by an empty line, the preceding empty line is also removed.
+After you edit a commit message on an open merge request, GitLab will
+not automatically update the commit message again.
+To restore the commit message to the project template, reload the page.
+
## Related topics
- [Squash and merge](squash_and_merge.md).
diff --git a/doc/user/project/merge_requests/commits.md b/doc/user/project/merge_requests/commits.md
index 0014c1ba994..20e0d3a1f5b 100644
--- a/doc/user/project/merge_requests/commits.md
+++ b/doc/user/project/merge_requests/commits.md
@@ -31,15 +31,7 @@ To seamlessly navigate among commits in a merge request:
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/29274) in GitLab 13.12 [with a flag](../../../administration/feature_flags.md) named `context_commits`. Enabled by default.
> - [Enabled on GitLab.com](https://gitlab.com/gitlab-org/gitlab/-/issues/320757) in GitLab 14.8.
-
-WARNING:
-This feature is in [beta](../../../policy/alpha-beta-support.md#beta-features)
-and is [incomplete](https://gitlab.com/groups/gitlab-org/-/epics/1192).
-
-FLAG:
-On self-managed GitLab, by default this feature is available. To hide the feature,
-ask an administrator to [disable the feature flag](../../../administration/feature_flags.md) named `context_commits`.
-On GitLab.com, this feature is available.
+> - [Generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/320757) in GitLab 14.9. [Feature flag `context_commits`](https://gitlab.com/gitlab-org/gitlab/-/issues/320757) removed.
When reviewing a merge request, it helps to have more context about the changes
made. That includes unchanged lines in unchanged files, and previous commits
diff --git a/doc/user/project/merge_requests/csv_export.md b/doc/user/project/merge_requests/csv_export.md
index 6dbbab316a0..df527ec6ebf 100644
--- a/doc/user/project/merge_requests/csv_export.md
+++ b/doc/user/project/merge_requests/csv_export.md
@@ -18,11 +18,11 @@ The following table shows what attributes will be present in the CSV.
| Column | Description |
|--------------------|--------------------------------------------------------------|
+| Title | Merge request title |
+| Description | Merge request description |
| MR ID | MR `iid` |
| URL | A link to the merge request on GitLab |
-| Title | Merge request title |
| State | Opened, Closed, Locked, or Merged |
-| Description | Merge request description |
| Source Branch | Source branch |
| Target Branch | Target branch |
| Source Project ID | ID of the source project |
@@ -39,6 +39,10 @@ The following table shows what attributes will be present in the CSV.
| Created At (UTC) | Formatted as `YYYY-MM-DD HH:MM:SS` |
| Updated At (UTC) | Formatted as `YYYY-MM-DD HH:MM:SS` |
+In GitLab 14.7 and earlier, the first two columns were `MR ID` and `URL`,
+which [caused an issue](https://gitlab.com/gitlab-org/gitlab/-/issues/34769)
+when importing back into GitLab.
+
## Limitations
- Export merge requests to CSV is not available at the Group's merge request list.
diff --git a/doc/user/project/merge_requests/fast_forward_merge.md b/doc/user/project/merge_requests/fast_forward_merge.md
index cd65fe20e66..dc13b270f17 100644
--- a/doc/user/project/merge_requests/fast_forward_merge.md
+++ b/doc/user/project/merge_requests/fast_forward_merge.md
@@ -43,7 +43,7 @@ You can also rebase without running a CI/CD pipeline.
The rebase action is also available as a [quick action command: `/rebase`](../../../topics/git/git_rebase.md#rebase-from-the-gitlab-ui).
-![Fast forward merge request](img/ff_merge_rebase_v14_7.png)
+![Fast forward merge request](img/ff_merge_rebase_v14_9.png)
If the target branch is ahead of the source branch and a conflict free rebase is
not possible, you need to rebase the
diff --git a/doc/user/project/merge_requests/getting_started.md b/doc/user/project/merge_requests/getting_started.md
index 8699a42dd5d..fd1751585d5 100644
--- a/doc/user/project/merge_requests/getting_started.md
+++ b/doc/user/project/merge_requests/getting_started.md
@@ -7,7 +7,7 @@ description: "Getting started with merge requests."
# Getting started with merge requests **(FREE)**
-A merge request (**MR**) is the basis of GitLab as a code
+A merge request (**MR**) is the basis of GitLab as a tool for code
collaboration and version control.
When working in a Git-based platform, you can use branching
@@ -161,7 +161,7 @@ enabled by default for all new merge requests, enable it in the
[project's settings](../settings/index.md#merge-request-settings).
This option is also visible in an existing merge request next to
-the merge request button and can be selected or deselected before merging.
+the merge request button and can be selected or cleared before merging.
It is only visible to users with the Maintainer role
in the source project.
diff --git a/doc/user/project/merge_requests/img/ff_merge_rebase_v14_7.png b/doc/user/project/merge_requests/img/ff_merge_rebase_v14_7.png
deleted file mode 100644
index 3c845d277e4..00000000000
--- a/doc/user/project/merge_requests/img/ff_merge_rebase_v14_7.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/project/merge_requests/img/ff_merge_rebase_v14_9.png b/doc/user/project/merge_requests/img/ff_merge_rebase_v14_9.png
new file mode 100644
index 00000000000..f4330549a57
--- /dev/null
+++ b/doc/user/project/merge_requests/img/ff_merge_rebase_v14_9.png
Binary files differ
diff --git a/doc/user/project/merge_requests/img/merge_request_diff_v12_2.png b/doc/user/project/merge_requests/img/merge_request_diff_v12_2.png
deleted file mode 100644
index 7e23b7db309..00000000000
--- a/doc/user/project/merge_requests/img/merge_request_diff_v12_2.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/project/merge_requests/load_performance_testing.md b/doc/user/project/merge_requests/load_performance_testing.md
index cc4ad186771..7861e1e28fc 100644
--- a/doc/user/project/merge_requests/load_performance_testing.md
+++ b/doc/user/project/merge_requests/load_performance_testing.md
@@ -92,7 +92,7 @@ template that is included with GitLab.
NOTE:
For large scale k6 tests you need to ensure the GitLab Runner instance performing the actual
test is able to handle running the test. Refer to [k6's guidance](https://k6.io/docs/testing-guides/running-large-tests#hardware-considerations)
-for spec details. The [default shared GitLab.com runners](../../../ci/runners/build_cloud/linux_build_cloud.md)
+for spec details. The [default shared GitLab.com runners](../../../ci/runners/saas/linux_saas_runner.md)
likely have insufficient specs to handle most large k6 tests.
This template runs the
diff --git a/doc/user/project/merge_requests/resolve_conflicts.md b/doc/user/project/merge_requests/resolve_conflicts.md
deleted file mode 100644
index 611f37a949b..00000000000
--- a/doc/user/project/merge_requests/resolve_conflicts.md
+++ /dev/null
@@ -1,9 +0,0 @@
----
-redirect_to: 'conflicts.md'
-remove_date: '2022-01-26'
----
-
-This document was moved to [another location](conflicts.md).
-
-<!-- This redirect file can be deleted after <2022-01-26>. -->
-<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/#move-or-rename-a-page -->
diff --git a/doc/user/project/merge_requests/squash_and_merge.md b/doc/user/project/merge_requests/squash_and_merge.md
index f90296e9626..a1d6959b75e 100644
--- a/doc/user/project/merge_requests/squash_and_merge.md
+++ b/doc/user/project/merge_requests/squash_and_merge.md
@@ -65,7 +65,7 @@ To configure the default squashing behavior for all merge requests in your proje
1. Expand **Merge requests**.
1. In the **Squash commits when merging** section, select your desired behavior:
- **Do not allow**: Squashing is never performed, and the option is not displayed.
- - **Allow**: Squashing is allowed, but deselected by default.
+ - **Allow**: Squashing is allowed, but cleared by default.
- **Encourage**: Squashing is allowed and selected by default, but can be disabled.
- **Require**: Squashing is always performed. While merge requests display the option
to squash, users cannot change it.
diff --git a/doc/user/project/merge_requests/test_coverage_visualization.md b/doc/user/project/merge_requests/test_coverage_visualization.md
index bd54eda42f5..d7177208a6e 100644
--- a/doc/user/project/merge_requests/test_coverage_visualization.md
+++ b/doc/user/project/merge_requests/test_coverage_visualization.md
@@ -52,7 +52,12 @@ from any job in any stage in the pipeline. The coverage displays for each line:
Hovering over the coverage bar provides further information, such as the number
of times the line was checked by tests.
-Uploading a test coverage report does not enable [test coverage results in Merge Requests](../../../ci/pipelines/settings.md#add-test-coverage-results-to-a-merge-request-deprecated) or [code coverage history](../../../ci/pipelines/settings.md#view-code-coverage-history). You must configure these separately.
+Uploading a test coverage report does not enable:
+
+- [Test coverage results in merge requests](../../../ci/pipelines/settings.md#merge-request-test-coverage-results).
+- [Code coverage history](../../../ci/pipelines/settings.md#view-code-coverage-history).
+
+You must configure these separately.
### Limits
diff --git a/doc/user/project/pages/custom_domains_ssl_tls_certification/dns_concepts.md b/doc/user/project/pages/custom_domains_ssl_tls_certification/dns_concepts.md
index 165131d50a4..3491346f7d9 100644
--- a/doc/user/project/pages/custom_domains_ssl_tls_certification/dns_concepts.md
+++ b/doc/user/project/pages/custom_domains_ssl_tls_certification/dns_concepts.md
@@ -37,7 +37,7 @@ for the most popular hosting services:
- [Cloudflare](https://support.cloudflare.com/hc/en-us/articles/201720164-Creating-a-Cloudflare-account-and-adding-a-website)
- [cPanel](https://documentation.cpanel.net/display/84Docs/Edit+DNS+Zone)
- [DigitalOcean](https://docs.digitalocean.com/products/networking/dns/how-to/manage-records/)
-- [DreamHost](https://help.dreamhost.com/hc/en-us/articles/215414867-How-do-I-add-custom-DNS-records-)
+- [DreamHost](https://help.dreamhost.com/hc/en-us/articles/360035516812)
- [Gandi](https://docs.gandi.net/en/domain_names/faq/dns_records.html)
- [Go Daddy](https://www.godaddy.com/help/add-an-a-record-19238)
- [Hostgator](https://www.hostgator.com/help/article/changing-dns-records)
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 ec66dce41f9..4d8919090a2 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
@@ -315,7 +315,7 @@ To enable this setting:
1. Tick the checkbox **Force HTTPS (requires valid certificates)**.
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).
+`full` instead of `flexible`. For more details, see the [Cloudflare CDN directions](https://developers.cloudflare.com/ssl/origin-configuration/ssl-modes#h_4e0d1a7c-eb71-4204-9e22-9d3ef9ef7fef).
<!-- ## Troubleshooting
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 75fc407ce3f..f09aea3b02a 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
@@ -79,6 +79,8 @@ If you get an error **Something went wrong while obtaining the Let's Encrypt cer
1. Make sure [your domain is verified](index.md#1-add-a-custom-domain-to-pages).
1. Go to step 1.
+Another possible cause of this error is the `_redirects` file because the current implementation relies on an HTTP ACME challenge. If you redirect the `.acme-challenge/` endpoint Let's Encrypt cannot validate the domain. Make sure you don't have a wildcard (`*`) redirect either as that too breaks validation. The problem with wildcard redirects is tracked in the [Wildcard redirects break Let's Encrypt integration](https://gitlab.com/gitlab-org/gitlab-pages/-/issues/649) issue.
+
### Message "GitLab is obtaining a Let's Encrypt SSL certificate for this domain. This process can take some time. Please try again later." hangs for more than an hour
If you've enabled Let's Encrypt integration, but a certificate is absent after an hour and you see the message, "GitLab is obtaining a Let's Encrypt SSL certificate for this domain. This process can take some time. Please try again later.", try to remove and add the domain for GitLab Pages again by following these steps:
diff --git a/doc/user/project/pages/getting_started_part_one.md b/doc/user/project/pages/getting_started_part_one.md
index 32826346eab..5773dd1f2c0 100644
--- a/doc/user/project/pages/getting_started_part_one.md
+++ b/doc/user/project/pages/getting_started_part_one.md
@@ -34,7 +34,7 @@ Pages domains are `*.gitlab.io`.
| Project pages owned by a subgroup | `subgroup/projectname` | `http(s)://groupname.example.io/subgroup/projectname`|
WARNING:
-There are some known [limitations](introduction.md#limitations)
+There are some known [limitations](introduction.md#subdomains-of-subdomains)
regarding namespaces served under the general domain name and HTTPS.
Make sure to read that section.
diff --git a/doc/user/project/pages/introduction.md b/doc/user/project/pages/introduction.md
index 65e1579001b..e4bc58854ef 100644
--- a/doc/user/project/pages/introduction.md
+++ b/doc/user/project/pages/introduction.md
@@ -76,17 +76,21 @@ website.
![Remove pages](img/remove_pages.png)
-## Limitations
+## Subdomains of subdomains
-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 or group name contains a dot, for example `foo.bar`, the domain
-`https://foo.bar.example.io` does _not_ work. This is a limitation of the
-[HTTP Over TLS protocol](https://tools.ietf.org/html/rfc2818#section-3.1).
-HTTP pages continue to work provided you don't redirect HTTP to HTTPS.
+When using Pages under the top-level domain of a GitLab instance (`*.example.io`), you can't use HTTPS with subdomains
+of subdomains. If your namespace or group name contains a dot (for example, `foo.bar`) the domain
+`https://foo.bar.example.io` does _not_ work.
-GitLab Pages [does **not** support group websites for subgroups](../../group/subgroups/index.md#limitations).
-You can only create the highest-level group website.
+This limitation is because of the [HTTP Over TLS protocol](https://tools.ietf.org/html/rfc2818#section-3.1). HTTP pages
+work as long as you don't redirect HTTP to HTTPS.
+
+## GitLab Pages and subgroups
+
+You must host your GitLab Pages website in a project. This project can belong to a [group](../../group/index.md) or
+[subgroup](../../group/subgroups/index.md). For
+[group websites](../../project/pages/getting_started_part_one.md#gitlab-pages-default-domain-names), the group must be
+at the top level and not a subgroup.
## Specific configuration options for Pages
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 1f60aafe71b..7779f87b459 100644
--- a/doc/user/project/pages/lets_encrypt_for_gitlab_pages.md
+++ b/doc/user/project/pages/lets_encrypt_for_gitlab_pages.md
@@ -6,4 +6,6 @@ remove_date: '2022-03-14'
This file was moved to [another location](custom_domains_ssl_tls_certification/lets_encrypt_integration.md).
<!-- This redirect file can be deleted after <2022-03-14>. -->
-<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/#move-or-rename-a-page -->
+<!-- Redirects that point to other docs in the same project expire in three months. -->
+<!-- Redirects that point to docs in a different project or site (for example, link is not relative and starts with `https:`) expire in one year. -->
+<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/redirects.html -->
diff --git a/doc/user/project/pages/redirects.md b/doc/user/project/pages/redirects.md
index beafbc86cb5..cdae1d2f837 100644
--- a/doc/user/project/pages/redirects.md
+++ b/doc/user/project/pages/redirects.md
@@ -163,6 +163,12 @@ Splats also match empty strings, so the previous rule redirects
### Rewrite all requests to a root `index.html`
+NOTE:
+If you are using [GitLab Pages integration with Let’s Encrypt](custom_domains_ssl_tls_certification/lets_encrypt_integration.md),
+you must enable it before adding this rule. Otherwise, the redirection breaks the Let's Encrypt
+integration. For more details, see
+[GitLab Pages issue 649](https://gitlab.com/gitlab-org/gitlab-pages/-/issues/649).
+
Single page applications (SPAs) often perform their own routing using
client-side routes. For these applications, it's important that _all_ requests
are rewritten to the root `index.html` so that the routing logic can be handled
@@ -180,7 +186,7 @@ rule like:
Use placeholders in rules to match portions of the requested URL and use these
matches when rewriting or redirecting to a new URL.
-A placehold is formatted as a `:` character followed by a string of letters
+A placeholder is formatted as a `:` character followed by a string of letters
(`[a-zA-Z]+`) in both the `from` and `to` paths:
```plaintext
diff --git a/doc/user/project/protected_branches.md b/doc/user/project/protected_branches.md
index 8bb18905222..292530e6c9c 100644
--- a/doc/user/project/protected_branches.md
+++ b/doc/user/project/protected_branches.md
@@ -29,7 +29,7 @@ When a branch is protected, the default behavior enforces these restrictions on
### Set the default branch protection level
Administrators can set a default branch protection level in the
-[Admin Area](../admin_area/settings/visibility_and_access_controls.md#protect-default-branches).
+[Admin Area](../project/repository/branches/default.md#instance-level-default-branch-protection).
## Configure a protected branch
@@ -41,7 +41,7 @@ To protect a branch:
1. Go to your project and select **Settings > Repository**.
1. Expand **Protected branches**.
-1. From the **Branch** dropdown menu, select the branch you want to protect.
+1. From the **Branch** dropdown list, select the branch you want to protect.
1. From the **Allowed to merge** list, select a role, or group that can merge into this branch. In GitLab Premium, you can also add users.
1. From the **Allowed to push** list, select a role, group, or user that can push to this branch. In GitLab Premium, you can also add users.
1. Select **Protect**.
@@ -58,7 +58,7 @@ To protect multiple branches at the same time:
1. Go to your project and select **Settings > Repository**.
1. Expand **Protected branches**.
-1. From the **Branch** dropdown menu, type the branch name and a wildcard.
+1. From the **Branch** dropdown list, type the branch name and a wildcard.
For example:
| Wildcard protected branch | Matching branches |
@@ -101,7 +101,7 @@ to a protected branch. This is compatible with workflows like the [GitLab workfl
1. Go to your project and select **Settings > Repository**.
1. Expand **Protected branches**.
-1. From the **Branch** dropdown menu, select the branch you want to protect.
+1. From the **Branch** dropdown list, select the branch you want to protect.
1. From the **Allowed to merge** list, select **Developers + Maintainers**.
1. From the **Allowed to push** list, select **No one**.
1. Select **Protect**.
@@ -112,7 +112,7 @@ You can allow everyone with write access to push to the protected branch.
1. Go to your project and select **Settings > Repository**.
1. Expand **Protected branches**.
-1. From the **Branch** dropdown menu, select the branch you want to protect.
+1. From the **Branch** dropdown list, select the branch you want to protect.
1. From the **Allowed to push** list, select **Developers + Maintainers**.
1. Select **Protect**.
@@ -128,27 +128,28 @@ key must have at least read access to the project.
Prerequisites:
-- The deploy key must be [enabled for your project](deploy_keys/index.md#how-to-enable-deploy-keys).
-- The deploy key must have [write access](deploy_keys/index.md#deploy-keys-permissions) to your project repository.
+- The deploy key must be enabled for your project. A project deploy key is enabled by default when
+ it is created. However, a public deploy key must be
+ [granted](deploy_keys/index.md#grant-project-access-to-a-public-deploy-key) access to the
+ project.
+- The deploy key must have [write access](deploy_keys/index.md#permissions) to your project
+ repository.
To allow a deploy key to push to a protected branch:
1. Go to your project and select **Settings > Repository**.
1. Expand **Protected branches**.
-1. From the **Branch** dropdown menu, select the branch you want to protect.
+1. From the **Branch** dropdown list, select the branch you want to protect.
1. From the **Allowed to push** list, select the deploy key.
1. Select **Protect**.
-Deploy keys are not available in the **Allowed to merge** dropdown.
+Deploy keys are not available in the **Allowed to merge** dropdown list.
## Allow force push on a protected branch
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/15611) in GitLab 13.10 behind a disabled feature flag.
> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/323431) in GitLab 14.0.
-WARNING:
-This feature might not be available to you. Check the **version history** note above for details.
-
You can allow [force pushes](../../topics/git/git_rebase.md#force-push) to
protected branches.
@@ -156,7 +157,7 @@ To protect a new branch and enable force push:
1. Go to your project and select **Settings > Repository**.
1. Expand **Protected branches**.
-1. From the **Branch** dropdown menu, select the branch you want to protect.
+1. From the **Branch** dropdown list, select the branch you want to protect.
1. From the **Allowed to push** and **Allowed to merge** lists, select the settings you want.
1. To allow all users with push access to force push, turn on the **Allowed to force push** toggle.
1. To reject code pushes that change files listed in the `CODEOWNERS` file, turn on the
@@ -169,12 +170,12 @@ To enable force pushes on branches that are already protected:
1. Expand **Protected branches**.
1. In the list of protected branches, next to the branch, turn on the **Allowed to force push** toggle.
-When enabled, members who are can push to this branch can also force push.
+Members who can push to this branch can now also force push.
## Require Code Owner approval on a protected branch **(PREMIUM)**
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/13251) in GitLab Premium 12.4.
-> - [In](https://gitlab.com/gitlab-org/gitlab/-/issues/35097) in [GitLab Premium](https://about.gitlab.com/pricing/) 13.5 and later, users and groups who can push to protected branches do not have to use a merge request to merge their feature branches. This means they can skip merge request approval rules.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/13251) in GitLab 12.4.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/35097) in GitLab 13.5, users and groups who can push to protected branches do not have to use a merge request to merge their feature branches. This means they can skip merge request approval rules.
For a protected branch, you can require at least one approval by a [Code Owner](code_owners.md).
@@ -182,7 +183,7 @@ To protect a new branch and enable Code Owner's approval:
1. Go to your project and select **Settings > Repository**.
1. Expand **Protected branches**.
-1. From the **Branch** dropdown menu, select the branch you want to protect.
+1. From the **Branch** dropdown list, select the branch you want to protect.
1. From the **Allowed to push** and **Allowed to merge** lists, select the settings you want.
1. Turn on the **Require approval from code owners** toggle.
1. Select **Protect**.
@@ -221,7 +222,7 @@ Users with at least the Maintainer role can manually delete protected
branches by using the GitLab web interface:
1. Go to **Repository > Branches**.
-1. Next to the branch you want to delete, select the **Delete** button (**{remove}**).
+1. Next to the branch you want to delete, select **Delete** (**{remove}**).
1. On the confirmation dialog, type the branch name and select **Delete protected branch**.
Protected branches can only be deleted by using GitLab either from the UI or API.
diff --git a/doc/user/project/protected_tags.md b/doc/user/project/protected_tags.md
index 7d071a45d63..5df34fcdcc4 100644
--- a/doc/user/project/protected_tags.md
+++ b/doc/user/project/protected_tags.md
@@ -27,18 +27,18 @@ By default:
## Configuring protected tags
-To protect a tag, you need to have at least the Maintainer role.
+To protect a tag, you must have at least the Maintainer role.
1. Go to the project's **Settings > Repository**.
-1. From the **Tag** dropdown menu, select the tag you want to protect or type and click **Create wildcard**. In the screenshot below, we chose to protect all tags matching `v*`:
+1. From the **Tag** dropdown list, select the tag you want to protect or type and click **Create wildcard**. In the screenshot below, we chose to protect all tags matching `v*`:
![Protected tags page](img/protected_tags_page_v12_3.png)
-1. From the **Allowed to create** dropdown, select users with permission to create
- matching tags, and click **Protect**:
+1. From the **Allowed to create** dropdown list, select users with permission to create
+ matching tags, and select **Protect**:
- ![Allowed to create tags dropdown](img/protected_tags_permissions_dropdown_v12_3.png)
+ ![Allowed to create tags dropdown list](img/protected_tags_permissions_dropdown_v12_3.png)
1. After done, the protected tag displays in the **Protected tags** list:
@@ -61,7 +61,7 @@ Two different wildcards can potentially match the same tag. For example,
In that case, if _any_ of these protected tags have a setting like
**Allowed to create**, then `production-stable` also inherit this setting.
-If you click on a protected tag's name, GitLab displays a list of
+If you select a protected tag's name, GitLab displays a list of
all matching tags:
![Protected tag matches](img/protected_tag_matches.png)
diff --git a/doc/user/project/quick_actions.md b/doc/user/project/quick_actions.md
index 8070c37db78..ae42d90af06 100644
--- a/doc/user/project/quick_actions.md
+++ b/doc/user/project/quick_actions.md
@@ -7,11 +7,11 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# GitLab quick actions **(FREE)**
-> - Introduced in [GitLab 12.1](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/26672):
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/26672) in GitLab 12.1:
> once an action is executed, an alert appears when a quick action is successfully applied.
-> - Introduced in [GitLab 13.2](https://gitlab.com/gitlab-org/gitlab/-/issues/16877): you can use
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/16877) in GitLab 13.2: you can use
> quick actions when updating the description of issues, epics, and merge requests.
-> - Introduced in [GitLab 13.8](https://gitlab.com/gitlab-org/gitlab/-/issues/292393): when you enter
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/292393) in GitLab 13.8: when you enter
> `/` into a description or comment field, all available quick actions are displayed in a scrollable list.
> - The rebase quick action was [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/49800) in GitLab 13.8.
@@ -49,15 +49,15 @@ threads. Some quick actions might not be available to all subscription tiers.
| Command | Issue | Merge request | Epic | Action |
|:-------------------------------------------------------------------------------------------------|:-----------------------|:-----------------------|:-----------------------|:----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| `/add_contacts [contact:email1@example.com] [contact:email2@example.com]` | **{check-circle}** Yes | **{dotted-circle}** No | **{dotted-circle}** No | Add one or more [CRM contacts](../crm/index.md) ([introduced in GitLab 14.6](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/73413)). |
+| `/add_contacts [contact:email1@example.com] [contact:email2@example.com]` | **{check-circle}** Yes | **{dotted-circle}** No | **{dotted-circle}** No | Add one or more [CRM contacts](../crm/index.md) ([introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/73413) in GitLab 14.6). |
| `/approve` | **{dotted-circle}** No | **{check-circle}** Yes | **{dotted-circle}** No | Approve the merge request. |
| `/assign @user1 @user2` | **{check-circle}** Yes | **{check-circle}** Yes | **{dotted-circle}** No | Assign one or more users. |
| `/assign me` | **{check-circle}** Yes | **{check-circle}** Yes | **{dotted-circle}** No | Assign yourself. |
| `/assign_reviewer @user1 @user2` or `/reviewer @user1 @user2` or `/request_review @user1 @user2` | **{dotted-circle}** No | **{check-circle}** Yes | **{dotted-circle}** No | Assign one or more users as reviewers. |
| `/assign_reviewer me` or `/reviewer me` or `/request_review me` | **{dotted-circle}** No | **{check-circle}** Yes | **{dotted-circle}** No | Assign yourself as a reviewer. |
| `/award :emoji:` | **{check-circle}** Yes | **{check-circle}** Yes | **{check-circle}** Yes | Toggle emoji award. |
-| `/child_epic <epic>` | **{dotted-circle}** No | **{dotted-circle}** No | **{check-circle}** Yes | 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)). |
-| `/clear_health_status` | **{check-circle}** Yes | **{dotted-circle}** No | **{dotted-circle}** No | Clear [health status](issues/managing_issues.md#health-status) ([introduced in GitLab 14.7](https://gitlab.com/gitlab-org/gitlab/-/issues/213814)). |
+| `/child_epic <epic>` | **{dotted-circle}** No | **{dotted-circle}** No | **{check-circle}** Yes | Add child epic to `<epic>`. The `<epic>` value should be in the format of `&epic`, `group&epic`, or a URL to an epic ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/7330) in GitLab 12.0). |
+| `/clear_health_status` | **{check-circle}** Yes | **{dotted-circle}** No | **{dotted-circle}** No | Clear [health status](issues/managing_issues.md#health-status) ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/213814) in GitLab 14.7). |
| `/clear_weight` | **{check-circle}** Yes | **{dotted-circle}** No | **{dotted-circle}** No | Clear weight. |
| `/clone <path/to/project> [--with_notes]` | **{check-circle}** Yes | **{dotted-circle}** No | **{dotted-circle}** No | Clone the issue to given project, or the current one if no arguments are given ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/9421) in GitLab 13.7). Copies as much data as possible as long as the target project contains equivalent labels, milestones, and so on. Does not copy comments or system notes unless `--with_notes` is provided as an argument. |
| `/close` | **{check-circle}** Yes | **{check-circle}** Yes | **{check-circle}** Yes | Close. |
@@ -68,47 +68,48 @@ threads. Some quick actions might not be available to all subscription tiers.
| `/done` | **{check-circle}** Yes | **{check-circle}** Yes | **{check-circle}** Yes | Mark to do as done. |
| `/draft` | **{dotted-circle}** No | **{check-circle}** Yes | **{dotted-circle}** No | Toggle the draft status. |
| `/due <date>` | **{check-circle}** Yes | **{dotted-circle}** No | **{dotted-circle}** No | Set due date. Examples of valid `<date>` include `in 2 days`, `this Friday` and `December 31st`. |
-| `/duplicate <#issue>` | **{check-circle}** Yes | **{dotted-circle}** No | **{dotted-circle}** No | Close this issue and mark as a duplicate of another issue. **(FREE)** Also, mark both as related. |
+| `/duplicate <#issue>` | **{check-circle}** Yes | **{dotted-circle}** No | **{dotted-circle}** No | Close this issue and mark as a duplicate of another issue. Also, mark both as related. |
| `/epic <epic>` | **{check-circle}** Yes | **{dotted-circle}** No | **{dotted-circle}** No | Add to epic `<epic>`. The `<epic>` value should be in the format of `&epic`, `group&epic`, or a URL to an epic. |
| `/estimate <time>` | **{check-circle}** Yes | **{check-circle}** Yes | **{dotted-circle}** No | Set time estimate. For example, `/estimate 1mo 2w 3d 4h 5m`. Learn more about [time tracking](time_tracking.md). |
-| `/health_status <value>` | **{check-circle}** Yes | **{dotted-circle}** No | **{dotted-circle}** No | Set [health status](issues/managing_issues.md#health-status). Valid options for `<value>` are `on_track`, `needs_attention`, and `at_risk` ([introduced in GitLab 14.7](https://gitlab.com/gitlab-org/gitlab/-/issues/213814)). |
+| `/health_status <value>` | **{check-circle}** Yes | **{dotted-circle}** No | **{dotted-circle}** No | Set [health status](issues/managing_issues.md#health-status). Valid options for `<value>` are `on_track`, `needs_attention`, and `at_risk` ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/213814) in GitLab 14.7). |
| `/invite_email email1 email2` | **{check-circle}** Yes | **{dotted-circle}** No | **{dotted-circle}** No | Add up to six email participants. This action is behind feature flag `issue_email_participants` and is not yet supported in issue templates. |
-| `/iteration *iteration:"iteration name"` | **{check-circle}** Yes | **{dotted-circle}** No | **{dotted-circle}** No | Set iteration. For example, to set the `Late in July` iteration: `/iteration *iteration:"Late in July"` ([introduced in GitLab 13.1](https://gitlab.com/gitlab-org/gitlab/-/issues/196795)). |
+| `/iteration *iteration:"iteration name"` | **{check-circle}** Yes | **{dotted-circle}** No | **{dotted-circle}** No | Set iteration. For example, to set the `Late in July` iteration: `/iteration *iteration:"Late in July"` ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/196795) in GitLab 13.1). |
| `/label ~label1 ~label2` | **{check-circle}** Yes | **{check-circle}** Yes | **{check-circle}** Yes | Add one or more labels. Label names can also start without a tilde (`~`), but mixed syntax is not supported. |
| `/lock` | **{check-circle}** Yes | **{check-circle}** Yes | **{dotted-circle}** No | Lock the discussions. |
| `/merge` | **{dotted-circle}** No | **{check-circle}** Yes | **{dotted-circle}** No | Merge changes. Depending on the project setting, this may be [when the pipeline succeeds](merge_requests/merge_when_pipeline_succeeds.md), or adding to a [Merge Train](../../ci/pipelines/merge_trains.md). |
| `/milestone %milestone` | **{check-circle}** Yes | **{check-circle}** Yes | **{dotted-circle}** No | Set milestone. |
-| `/move <path/to/project>` | **{check-circle}** Yes | **{dotted-circle}** No | **{dotted-circle}** No | Move this issue to another project. Be careful when moving an issue to a project with different access rules. Before moving the issue, make sure it does not contain sensitive data. |
-| `/parent_epic <epic>` | **{dotted-circle}** No | **{dotted-circle}** No | **{check-circle}** Yes | 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)). |
+| `/move <path/to/project>` | **{check-circle}** Yes | **{dotted-circle}** No | **{dotted-circle}** No | Move this issue to another project. Be careful when moving an issue to a project with different access rules. Before moving the issue, make sure it does not contain sensitive data. |
+| `/parent_epic <epic>` | **{dotted-circle}** No | **{dotted-circle}** No | **{check-circle}** Yes | Set parent epic to `<epic>`. The `<epic>` value should be in the format of `&epic`, `group&epic`, or a URL to an epic ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/10556) in GitLab 12.1). |
| `/promote` | **{check-circle}** Yes | **{dotted-circle}** No | **{dotted-circle}** No | Promote issue to epic. |
-| `/promote_to_incident` | **{check-circle}** Yes | **{dotted-circle}** No | **{dotted-circle}** No | Promote issue to incident ([introduced in GitLab 14.5](https://gitlab.com/gitlab-org/gitlab/-/issues/296787)). |
-| `/publish` | **{check-circle}** Yes | **{dotted-circle}** No | **{dotted-circle}** No | Publish issue to an associated [Status Page](../../operations/incident_management/status_page.md) ([Introduced in GitLab 13.0](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/30906)) |
+| `/promote_to_incident` | **{check-circle}** Yes | **{dotted-circle}** No | **{dotted-circle}** No | Promote issue to incident ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/296787) in GitLab 14.5). |
+| `/page <policy name>` | **{check-circle}** Yes | **{dotted-circle}** No | **{dotted-circle}** No | Start escalations for the incident ([introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/79977) in GitLab 14.9). |
+| `/publish` | **{check-circle}** Yes | **{dotted-circle}** No | **{dotted-circle}** No | Publish issue to an associated [Status Page](../../operations/incident_management/status_page.md) ([Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/30906) in GitLab 13.0) |
| `/reassign @user1 @user2` | **{check-circle}** Yes | **{check-circle}** Yes | **{dotted-circle}** No | Replace current assignees with those specified. |
| `/reassign_reviewer @user1 @user2` | **{dotted-circle}** No | **{check-circle}** Yes | **{dotted-circle}** No | Replace current reviewers with those specified. |
| `/rebase` | **{dotted-circle}** No | **{check-circle}** Yes | **{dotted-circle}** No | Rebase source branch. This schedules a background task that attempts to rebase the changes in the source branch on the latest commit of the target branch. If `/rebase` is used, `/merge` is ignored to avoid a race condition where the source branch is merged or deleted before it is rebased. If there are merge conflicts, GitLab displays a message that a rebase cannot be scheduled. Rebase failures are displayed with the merge request status. |
| `/relabel ~label1 ~label2` | **{check-circle}** Yes | **{check-circle}** Yes | **{check-circle}** Yes | Replace current labels with those specified. |
| `/relate #issue1 #issue2` | **{check-circle}** Yes | **{dotted-circle}** No | **{dotted-circle}** No | Mark issues as related. |
-| `/remove_child_epic <epic>` | **{dotted-circle}** No | **{dotted-circle}** No | **{check-circle}** Yes | 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)). |
-| `/remove_contacts [contact:email1@example.com] [contact:email2@example.com]` | **{check-circle}** Yes | **{dotted-circle}** No | **{dotted-circle}** No | Remove one or more [CRM contacts](../crm/index.md) ([introduced in GitLab 14.6](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/73413)). |
+| `/remove_child_epic <epic>` | **{dotted-circle}** No | **{dotted-circle}** No | **{check-circle}** Yes | Remove child epic from `<epic>`. The `<epic>` value should be in the format of `&epic`, `group&epic`, or a URL to an epic ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/7330) in GitLab 12.0). |
+| `/remove_contacts [contact:email1@example.com] [contact:email2@example.com]` | **{check-circle}** Yes | **{dotted-circle}** No | **{dotted-circle}** No | Remove one or more [CRM contacts](../crm/index.md) ([introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/73413) in GitLab 14.6). |
| `/remove_due_date` | **{check-circle}** Yes | **{dotted-circle}** No | **{dotted-circle}** No | Remove due date. |
| `/remove_epic` | **{check-circle}** Yes | **{dotted-circle}** No | **{dotted-circle}** No | Remove from epic. |
| `/remove_estimate` | **{check-circle}** Yes | **{check-circle}** Yes | **{dotted-circle}** No | Remove time estimate. |
-| `/remove_iteration` | **{check-circle}** Yes | **{dotted-circle}** No | **{dotted-circle}** No | Remove iteration ([introduced in GitLab 13.1](https://gitlab.com/gitlab-org/gitlab/-/issues/196795)). |
+| `/remove_iteration` | **{check-circle}** Yes | **{dotted-circle}** No | **{dotted-circle}** No | Remove iteration ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/196795) in GitLab 13.1). |
| `/remove_milestone` | **{check-circle}** Yes | **{check-circle}** Yes | **{dotted-circle}** No | Remove milestone. |
-| `/remove_parent_epic` | **{dotted-circle}** No | **{dotted-circle}** No | **{check-circle}** Yes | Remove parent epic from epic ([introduced in GitLab 12.1](https://gitlab.com/gitlab-org/gitlab/-/issues/10556)). |
+| `/remove_parent_epic` | **{dotted-circle}** No | **{dotted-circle}** No | **{check-circle}** Yes | Remove parent epic from epic ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/10556) in GitLab 12.1). |
| `/remove_time_spent` | **{check-circle}** Yes | **{check-circle}** Yes | **{dotted-circle}** No | Remove time spent. |
-| `/remove_zoom` | **{check-circle}** Yes | **{dotted-circle}** No | **{dotted-circle}** No | Remove Zoom meeting from this issue ([introduced in GitLab 12.4](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/16609)). |
+| `/remove_zoom` | **{check-circle}** Yes | **{dotted-circle}** No | **{dotted-circle}** No | Remove Zoom meeting from this issue ([introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/16609) in GitLab 12.4). |
| `/reopen` | **{check-circle}** Yes | **{check-circle}** Yes | **{check-circle}** Yes | Reopen. |
-| `/severity <severity>` | **{check-circle}** Yes | **{check-circle}** No | **{check-circle}** No | Set the severity. Options for `<severity>` are `S1` ... `S4`, `critical`, `high`, `medium`, `low`, `unknown`. [Introduced in GitLab 14.2](https://gitlab.com/gitlab-org/gitlab/-/issues/334045). |
+| `/severity <severity>` | **{check-circle}** Yes | **{check-circle}** No | **{check-circle}** No | Set the severity. Options for `<severity>` are `S1` ... `S4`, `critical`, `high`, `medium`, `low`, `unknown`. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/334045) in GitLab 14.2. |
| `/shrug <comment>` | **{check-circle}** Yes | **{check-circle}** Yes | **{check-circle}** Yes | Append the comment with `¯\_(ツ)_/¯`. |
| `/spend <time> [<date>]` | **{check-circle}** Yes | **{check-circle}** Yes | **{dotted-circle}** No | Add or subtract spent time. Optionally, specify the date that time was spent on. For example, `/spend 1mo 2w 3d 4h 5m 2018-08-26` or `/spend -1h 30m`. Learn more about [time tracking](time_tracking.md). |
-| `/submit_review` | **{dotted-circle}** No | **{check-circle}** Yes | **{dotted-circle}** No | Submit a pending review ([introduced in GitLab 12.7](https://gitlab.com/gitlab-org/gitlab/-/issues/8041)). |
+| `/submit_review` | **{dotted-circle}** No | **{check-circle}** Yes | **{dotted-circle}** No | Submit a pending review ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/8041) in GitLab 12.7). |
| `/subscribe` | **{check-circle}** Yes | **{check-circle}** Yes | **{check-circle}** Yes | Subscribe to notifications. |
| `/tableflip <comment>` | **{check-circle}** Yes | **{check-circle}** Yes | **{check-circle}** Yes | Append the comment with `(╯°□°)╯︵ â”»â”â”»`. |
| `/target_branch <local branch name>` | **{dotted-circle}** No | **{check-circle}** Yes | **{dotted-circle}** No | Set target branch. |
| `/title <new title>` | **{check-circle}** Yes | **{check-circle}** Yes | **{check-circle}** Yes | Change title. |
| `/todo` | **{check-circle}** Yes | **{check-circle}** Yes | **{check-circle}** Yes | Add a to-do item. |
-| `/unapprove` | **{dotted-circle}** No | **{check-circle}** Yes | **{dotted-circle}** No | Unapprove the merge request. ([introduced in GitLab 14.3](https://gitlab.com/gitlab-org/gitlab/-/issues/8103) |
+| `/unapprove` | **{dotted-circle}** No | **{check-circle}** Yes | **{dotted-circle}** No | Unapprove the merge request. ([introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/8103) in GitLab 14.3 |
| `/unassign @user1 @user2` | **{check-circle}** Yes | **{check-circle}** Yes | **{dotted-circle}** No | Remove specific assignees. |
| `/unassign` | **{dotted-circle}** No | **{check-circle}** Yes | **{dotted-circle}** No | Remove all assignees. |
| `/unassign_reviewer @user1 @user2` or `/remove_reviewer @user1 @user2` | **{dotted-circle}** No | **{check-circle}** Yes | **{dotted-circle}** No | Remove specific reviewers. |
@@ -118,7 +119,7 @@ threads. Some quick actions might not be available to all subscription tiers.
| `/unlock` | **{check-circle}** Yes | **{check-circle}** Yes | **{dotted-circle}** No | Unlock the discussions. |
| `/unsubscribe` | **{check-circle}** Yes | **{check-circle}** Yes | **{check-circle}** Yes | Unsubscribe from notifications. |
| `/weight <value>` | **{check-circle}** Yes | **{dotted-circle}** No | **{dotted-circle}** No | Set weight. Valid options for `<value>` include `0`, `1`, `2`, and so on. |
-| `/zoom <Zoom URL>` | **{check-circle}** Yes | **{dotted-circle}** No | **{dotted-circle}** No | Add Zoom meeting to this issue ([introduced in GitLab 12.4](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/16609)). |
+| `/zoom <Zoom URL>` | **{check-circle}** Yes | **{dotted-circle}** No | **{dotted-circle}** No | Add Zoom meeting to this issue ([introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/16609) in GitLab 12.4). |
## Commit messages
diff --git a/doc/user/project/releases/index.md b/doc/user/project/releases/index.md
index 8049ee9726d..26b36198bde 100644
--- a/doc/user/project/releases/index.md
+++ b/doc/user/project/releases/index.md
@@ -42,7 +42,7 @@ To view a list of releases:
- On the left sidebar, select **Deployments > Releases**, or
-- On the project's overview page, if at least one release exists, click the number of releases.
+- On the project's overview page, if at least one release exists, select the number of releases.
![Number of Releases](img/releases_count_v13_2.png "Incremental counter of Releases")
@@ -52,10 +52,10 @@ To view a list of releases:
### Sort releases
-To sort releases by **Released date** or **Created date**, select from the sort order dropdown. To
+To sort releases by **Released date** or **Created date**, select from the sort order dropdown list. To
switch between ascending or descending order, select **Sort order**.
-![Sort releases dropdown button](img/releases_sort_v13_6.png)
+![Sort releases dropdown list options](img/releases_sort_v13_6.png)
## Create a release
@@ -307,9 +307,9 @@ Read more about [Release permissions](#release-permissions).
To edit the details of a release:
1. On the left sidebar, select **Deployments > Releases**.
-1. In the top-right corner of the release you want to modify, click **Edit this release** (the pencil icon).
+1. In the top-right corner of the release you want to modify, select **Edit this release** (the pencil icon).
1. On the **Edit Release** page, change the release's details.
-1. Click **Save changes**.
+1. Select **Save changes**.
You can edit the release title, notes, associated milestones, and asset links.
To change the release date use the
@@ -330,16 +330,16 @@ the [Releases API](../../../api/releases/index.md#create-a-release).
In the user interface, to associate milestones to a release:
1. On the left sidebar, select **Deployments > Releases**.
-1. In the top-right corner of the release you want to modify, click **Edit this release** (the pencil icon).
+1. In the top-right corner of the release you want to modify, select **Edit this release** (the pencil icon).
1. From the **Milestones** list, select each milestone you want to associate. You can select multiple milestones.
-1. Click **Save changes**.
+1. Select **Save changes**.
On the **Deployments > Releases** page, the **Milestone** is listed in the top
section, along with statistics about the issues in the milestones.
![A Release with one associated milestone](img/release_with_milestone_v12_9.png)
-Releases are also visible on the **Issues > Milestones** page, and when you click a milestone
+Releases are also visible on the **Issues > Milestones** page, and when you select a milestone
on this page.
Here is an example of milestones with no releases, one release, and two releases, respectively.
@@ -360,8 +360,8 @@ You can be notified by email when a new release is created for your project.
To subscribe to notifications for releases:
1. On the left sidebar, select **Project information**.
-1. Click **Notification setting** (the bell icon).
-1. In the list, click **Custom**.
+1. Select **Notification setting** (the bell icon).
+1. In the list, select **Custom**.
1. Select the **New release** checkbox.
1. Close the dialog box to save.
@@ -395,12 +395,12 @@ To set a deploy freeze window in the UI, complete these steps:
1. Sign in to GitLab as a user with the Maintainer role.
1. On the left sidebar, select **Project information**.
-1. In the left navigation menu, navigate to **Settings > CI/CD**.
+1. In the left navigation menu, go to **Settings > CI/CD**.
1. Scroll to **Deploy freezes**.
-1. Click **Expand** to see the deploy freeze table.
-1. Click **Add deploy freeze** to open the deploy freeze modal.
+1. Select **Expand** to see the deploy freeze table.
+1. Select **Add deploy freeze** to open the deploy freeze modal.
1. Enter the start time, end time, and time zone of the desired deploy freeze period.
-1. Click **Add deploy freeze** in the modal.
+1. Select **Add deploy freeze** in the modal.
1. After the deploy freeze is saved, you can edit it by selecting the edit button (**{pencil}**) and remove it by selecting the delete button (**{remove}**).
![Deploy freeze modal for setting a deploy freeze period](img/deploy_freeze_v14_3.png)
@@ -468,6 +468,28 @@ Each link as an asset has the following attributes:
| `filepath` | The redirect link to the `url`. See [this section](#permanent-links-to-release-assets) for more information. | No |
| `link_type` | The content kind of what users can download via `url`. See [this section](#link-types) for more information. | No |
+##### Permanent link to latest release
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/16821) in GitLab 14.9.
+
+Latest release page is accessible through a permanent URL.
+GitLab will redirect to the latest release page URL when it is visited.
+
+The format of the URL is:
+
+```plaintext
+https://host/namespace/project/-/releases/permalink/latest
+```
+
+We also support, suffix path carry forward on the redirect to the latest release.
+Example if release `v14.8.0-ee` is the latest release and has a readable link `https://host/namespace/project/-/releases/v14.8.0-ee#release` then it can be addressed as `https://host/namespace/project/-/releases/permalink/latest#release`.
+
+Refer [permanent links to latest release assets](#permanent-links-to-latest-release-assets) section to understand more about the suffix path carry forward usage.
+
+###### Sorting preferences
+
+By default, GitLab fetches the release using `released_at` time. The use of the query parameter `?order_by=released_at` is optional, and support for `?order_by=semver` is tracked [in this issue](https://gitlab.com/gitlab-org/gitlab/-/issues/352945).
+
##### Permanent links to release assets
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/27300) in GitLab 12.9.
@@ -475,7 +497,7 @@ Each link as an asset has the following attributes:
The assets associated with a release are accessible through a permanent URL.
GitLab always redirects this URL to the actual asset
location, so even if the assets move to a different location, you can continue
-to use the same URL. This is defined during [link creation](../../../api/releases/links.md#create-a-link) or [updating](../../../api/releases/links.md#update-a-link).
+to use the same URL. This is defined during [link creation](../../../api/releases/links.md#create-a-link) or [updating](../../../api/releases/links.md#update-a-link) using the `filepath` API attribute.
The format of the URL is:
@@ -503,6 +525,36 @@ https://gitlab.com/gitlab-org/gitlab-runner/-/releases/v11.9.0-rc2/downloads/bin
The physical location of the asset can change at any time and the direct link remains unchanged.
+##### Permanent links to latest release assets
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/16821) in GitLab 14.9.
+
+The `filepath` from [permanent links to release assets](#permanent-links-to-release-assets) can be used in combination with [permanent link to the latest release](#permanent-link-to-latest-release). It is useful when we want to link a permanant URL to download an asset from the *latest release*.
+
+The format of the URL is:
+
+```plaintext
+https://host/namespace/project/-/releases/permalink/latest/downloads/:filepath
+```
+
+If you have an asset with [`filepath`](../../../api/releases/links.md#create-a-link) for the `v11.9.0-rc2` latest release in the `gitlab-org`
+namespace and `gitlab-runner` project on `gitlab.com`, for example:
+
+```json
+{
+ "name": "linux amd64",
+ "filepath": "/binaries/gitlab-runner-linux-amd64",
+ "url": "https://gitlab-runner-downloads.s3.amazonaws.com/v11.9.0-rc2/binaries/gitlab-runner-linux-amd64",
+ "link_type": "other"
+}
+```
+
+This asset has a direct link of:
+
+```plaintext
+https://gitlab.com/gitlab-org/gitlab-runner/-/releases/permalink/latest/downloads/binaries/gitlab-runner-linux-amd64
+```
+
##### Link Types
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/207257) in GitLab 13.1.
@@ -611,7 +663,7 @@ On [GitLab.com](https://gitlab.com/gitlab-org/gitlab/-/releases), you can view t
![Feature count](img/feature_count_v14_6.png "Number of features in a release")
The totals are displayed on [shields](https://shields.io/) and are generated per release by
-[a Rake task in the `www-gitlab-com` repo](https://gitlab.com/gitlab-com/www-gitlab-com/-/blob/master/lib/tasks/update_gitlab_project_releases_page.rake).
+[a Rake task in the `www-gitlab-com` repository](https://gitlab.com/gitlab-com/www-gitlab-com/-/blob/master/lib/tasks/update_gitlab_project_releases_page.rake).
| Item | Formula |
| ------ | ------ |
@@ -634,7 +686,7 @@ This data is saved in a JSON file and called *release evidence*. The feature
includes test artifacts and linked milestones to facilitate
internal processes, like external audits.
-To access the release evidence, on the Releases page, click the link to the JSON file that's listed
+To access the release evidence, on the Releases page, select the link to the JSON file that's listed
under the **Evidence collection** heading.
You can also [use the API](../../../api/releases/index.md#collect-release-evidence) to
@@ -720,7 +772,7 @@ When you create a release, if [job artifacts](../../../ci/yaml/index.md#artifact
Although job artifacts normally expire, artifacts included in release evidence do not expire.
-To enable job artifact collection you need to specify both:
+To enable job artifact collection you must specify both:
1. [`artifacts:paths`](../../../ci/yaml/index.md#artifactspaths)
1. [`artifacts:reports`](../../../ci/yaml/index.md#artifactsreports)
diff --git a/doc/user/project/repository/branches/default.md b/doc/user/project/repository/branches/default.md
index d706a0e8f8a..f9fd1a48b9a 100644
--- a/doc/user/project/repository/branches/default.md
+++ b/doc/user/project/repository/branches/default.md
@@ -26,7 +26,7 @@ using the GitLab default only if no customizations are set:
1. A [project-specific](#change-the-default-branch-name-for-a-project) custom default branch name.
1. A [subgroup-level](#group-level-custom-initial-branch-name) custom default branch name.
1. A [group-level](#group-level-custom-initial-branch-name) custom default branch name.
-1. An [instance-level](#instance-level-custom-initial-branch-name) custom default branch name. **(FREE SELF)**
+1. An [instance-level](#instance-level-custom-initial-branch-name) custom default branch name.
1. If no custom default branch name is set at any level, GitLab defaults to:
- `main`: Projects created with GitLab 14.0 or later.
- `master`: Projects created before GitLab 14.0.
@@ -81,13 +81,83 @@ overrides it.
Users with at least the Owner role of groups and subgroups can configure the default branch name for a group:
1. Go to the group **Settings > Repository**.
-1. Expand **Default initial branch name**.
+1. Expand **Default branch**.
1. Change the default initial branch to a custom name of your choice.
1. Select **Save changes**.
Projects created in this group after you change the setting use the custom branch name,
unless a subgroup configuration overrides it.
+## Protect initial default branches **(FREE SELF)**
+
+GitLab administrators and group owners can define [branch protections](../../../project/protected_branches.md)
+to apply to every repository's [default branch](#default-branch)
+at the [instance level](#instance-level-default-branch-protection) and
+[group level](#group-level-default-branch-protection) with one of the following options:
+
+- **Not protected** - Both developers and maintainers can push new commits
+ and force push.
+- **Protected against pushes** - Developers cannot push new commits, but are
+ allowed to accept merge requests to the branch. Maintainers can push to the branch.
+- **Partially protected** - Both developers and maintainers can push new commits,
+ but cannot force push.
+- **Fully protected** - Developers cannot push new commits, but maintainers can.
+ No one can force push.
+
+### Instance-level default branch protection **(FREE SELF)**
+
+This setting applies only to each repository's default branch. To protect other branches,
+you must either:
+
+- Configure [branch protection in the repository](../../../project/protected_branches.md).
+- Configure [branch protection for groups](../../../group/index.md#change-the-default-branch-protection-of-a-group).
+
+Administrators of self-managed instances can customize the initial default branch protection for projects hosted on that instance. Individual
+groups and subgroups can override this instance-wide setting for their projects.
+
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Settings > Repository**.
+1. Expand **Default branch**.
+1. Select [**Initial default branch protection**](#protect-initial-default-branches).
+1. To allow group owners to override the instance's default branch protection, select
+ [**Allow owners to manage default branch protection per group**](#prevent-overrides-of-default-branch-protection).
+1. Select **Save changes**.
+
+#### Prevent overrides of default branch protection **(PREMIUM SELF)**
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/211944) in GitLab 13.0.
+
+Instance-level protections for default branches
+can be overridden on a per-group basis by the group's owner. In
+[GitLab Premium or higher](https://about.gitlab.com/pricing/), GitLab administrators can
+disable this privilege for group owners, enforcing the instance-level protection rule:
+
+1. On the top bar, select **Menu > Admin**.
+1. On the left sidebar, select **Settings > Repository**.
+1. Expand the **Default branch** section.
+1. Clear the **Allow owners to manage default branch protection per group** checkbox.
+1. Select **Save changes**.
+
+NOTE:
+GitLab administrators can still update the default branch protection of a group.
+
+### Group-level default branch protection **(PREMIUM)**
+
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/7583) in GitLab 12.9.
+> - [Settings moved and renamed](https://gitlab.com/gitlab-org/gitlab/-/issues/340403) in GitLab 14.9.
+
+Instance-level protections for [default branch](#default-branch)
+can be overridden on a per-group basis by the group's owner. In
+[GitLab Premium or higher](https://about.gitlab.com/pricing/), GitLab administrators can
+[enforce protection of initial default branches](#prevent-overrides-of-default-branch-protection)
+which locks this setting for group owners.
+
+1. On the top bar, select **Menu > Groups** and find your group.
+1. On the left sidebar, select **Settings > Repository**.
+1. Expand **Default branch**.
+1. Select [**Initial default branch protection**](#protect-initial-default-branches).
+1. Select **Save changes**.
+
## Update the default branch name in your repository
WARNING:
diff --git a/doc/user/project/repository/forking_workflow.md b/doc/user/project/repository/forking_workflow.md
index b085372c8f2..ddeef65a6b5 100644
--- a/doc/user/project/repository/forking_workflow.md
+++ b/doc/user/project/repository/forking_workflow.md
@@ -18,36 +18,24 @@ submit them through a merge request to the repository you don't have access to.
## Creating a fork
-To fork an existing project in GitLab:
-
-1. On the project's home page, in the top right, click **{fork}** **Fork**.
-
- ![Fork button](img/forking_workflow_fork_button_v13_10.png)
-
-1. Select the project to fork to:
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/15013) a new form in GitLab 13.11 [with a flag](../../../user/feature_flags.md) named `fork_project_form`. Disabled by default.
+> - [Enabled on GitLab.com and self-managed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/77181) in GitLab 14.8. Feature flag `fork_project_form` removed.
- - Recommended method. Below **Select a namespace to fork the project**, identify
- the project you want to fork to, and click **Select**. Only namespaces where you have
- at least the Developer role for are shown.
-
- ![Choose namespace](img/forking_workflow_choose_namespace_v13_10.png)
-
- - Experimental method. If your GitLab administrator has
- enabled the experimental fork project form, read
- [Create a fork with the fork project form](#create-a-fork-with-the-fork-project-form).
- Only namespaces where you have at least the Developer role for are shown.
-
- NOTE:
- The project path must be unique in the namespace.
+To fork an existing project in GitLab:
-GitLab creates your fork, and redirects you to the project page for your new fork.
-The permissions you have in the namespace are your permissions in the fork.
+1. On the project's home page, in the top right, select **{fork}** **Fork**:
+ ![Fork this project](img/forking_workflow_fork_button_v13_10.png)
+1. Optional. Edit the **Project name**.
+1. For **Project URL**, select the [namespace](../../group/index.md#namespaces)
+ your fork should belong to.
+1. Add a **Project slug**. This value becomes part of the URL to your fork.
+ It must be unique in the namespace.
+1. Optional. Add a **Project description**.
+1. Select the **Visibility level** for your fork. For more information about
+ visibility levels, read [Project and group visibility](../../../public_access/public_access.md).
+1. Select **Fork project**.
-WARNING:
-When a public project with the repository feature set to **Members Only**
-is forked, the repository is public in the fork. The owner
-of the fork must manually change the visibility. Issue
-[#36662](https://gitlab.com/gitlab-org/gitlab/-/issues/36662) exists for this issue.
+GitLab creates your fork, and redirects you to the new fork's page.
## Repository mirroring
@@ -59,7 +47,7 @@ Without mirroring, to work locally you must use `git pull` to update your local
with the upstream project, then push the changes back to your fork to update it.
WARNING:
-With mirroring, before approving a merge request, you are asked to sync. Because of this, automating it is recommended.
+With mirroring, before approving a merge request, you are asked to sync. We recommend you automate it.
Read more about [How to keep your fork up to date with its origin](https://about.gitlab.com/blog/2016/12/01/how-to-keep-your-fork-up-to-date-with-its-origin/).
@@ -75,30 +63,9 @@ When creating a merge request, if the forked project's visibility is more restri
![Selecting branches](img/forking_workflow_branch_select.png)
Then you can add labels, a milestone, and assign the merge request to someone who can review
-your changes. Then click **Submit merge request** to conclude the process. When successfully merged, your
+your changes. Then select **Submit merge request** to conclude the process. When successfully merged, your
changes are added to the repository and branch you're merging into.
## Removing a fork relationship
You can unlink your fork from its upstream project in the [advanced settings](../settings/index.md#removing-a-fork-relationship).
-
-## Create a fork with the fork project form **(FREE SELF)**
-
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/15013) in GitLab 13.11 [with a flag](../../../administration/feature_flags.md) named `fork_project_form`. Disabled by default.
-> - [Enabled on self-managed and GitLab.com](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/64967) in GitLab 13.8.
-
-FLAG:
-On self-managed GitLab, by default this feature is available. To hide the feature, ask an administrator to [disable the feature flag](../../../administration/feature_flags.md) named `fork_project_form`.
-On GitLab.com, this feature is available.
-
-This version of the fork project form is experimental:
-
-![Choose namespace](img/fork_form_v13_10.png)
-
-To use it, follow the instructions at [Creating a fork](#creating-a-fork) and provide:
-
-- The project name.
-- The project URL.
-- The project slug.
-- Optional. The project description.
-- The visibility level for your fork.
diff --git a/doc/user/project/repository/gpg_signed_commits/img/profile_settings_gpg_keys_paste_pub.png b/doc/user/project/repository/gpg_signed_commits/img/profile_settings_gpg_keys_paste_pub.png
deleted file mode 100644
index 6e2ff33eebb..00000000000
--- a/doc/user/project/repository/gpg_signed_commits/img/profile_settings_gpg_keys_paste_pub.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/project/repository/gpg_signed_commits/index.md b/doc/user/project/repository/gpg_signed_commits/index.md
index f5cea8a8075..00998c9a227 100644
--- a/doc/user/project/repository/gpg_signed_commits/index.md
+++ b/doc/user/project/repository/gpg_signed_commits/index.md
@@ -6,129 +6,96 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Signing commits with GPG **(FREE)**
-You can use a GPG key to sign Git commits made in a GitLab repository. Signed
-commits are labeled **Verified** if the identity of the committer can be
-verified. To verify the identity of a committer, GitLab requires their public
-GPG key.
+You can sign the commits you make in a GitLab repository with a
+GPG ([GNU Privacy Guard](https://gnupg.org/)) key. When you add a cryptographic
+signature to your commit, you provide extra assurance that a commit
+originated from you, rather than an impersonator. If GitLab can verify a commit
+author's identity with a public GPG key, the commit is marked **Verified** in the
+GitLab UI. You can then configure [push rules](../push_rules.md#enabling-push-rules)
+for your project to reject individual commits not signed with GPG, or reject all
+commits from unverified users.
NOTE:
-The term GPG is used for all OpenPGP/PGP/GPG related material and
+GitLab uses the term GPG for all OpenPGP, PGP, and GPG-related material and
implementations.
-To view a user's public GPG key, you can:
-
-- Go to `https://gitlab.example.com/<username>.gpg`.
-- Select **View public GPG keys** (**{key}**) in the top right of the user's profile.
-
-GPG verified tags are not supported yet.
-
-See the [further reading](#further-reading) section for more details on GPG.
-
-## How GitLab handles GPG
-
-GitLab uses its own keyring to verify the GPG signature. It does not access any
-public key server.
-
-For a commit to be verified by GitLab:
+For GitLab to consider a commit verified:
- The committer must have a GPG public/private key pair.
-- The committer's public key must have been uploaded to their GitLab
- account.
-- One of the emails in the GPG key must match a **verified** email address
- used by the committer in GitLab. This address will be part of the public key.
- If you want to keep this address private, use the automatically generated
+- The committer's public key must be uploaded to their GitLab account.
+- One of the email addresses in the GPG public key must match a **verified** email address
+ used by the committer in GitLab. To keep this address private, use the automatically generated
[private commit email address](../../../profile/index.md#use-an-automatically-generated-private-commit-email)
GitLab provides in your profile.
- The committer's email address must match the verified email address from the
GPG key.
-## Generating a GPG key
-
-If you don't already have a GPG key, the following steps can help you get
-started:
-
-1. [Install GPG](https://www.gnupg.org/download/index.html) for your operating system.
- If your operating system has `gpg2` installed, replace `gpg` with `gpg2` in
- the following commands.
-1. Generate the private/public key pair with the command appropriate for your version
- of `gpg`. This command spawns a series of questions:
-
- ```shell
- # Use this command for the default version of gpg, including
- # Gpg4win on Windows, and most macOS versions:
- gpg --gen-key
+GitLab uses its own keyring to verify the GPG signature. It does not access any
+public key server.
- # Use this command for versions of GPG later than 2.1.17:
- gpg --full-gen-key
- ```
+GPG verified tags are not supported.
-1. The first question is which algorithm can be used. Select the kind you want
- or press <kbd>Enter</kbd> to choose the default (RSA and RSA):
+For more details about GPG, refer to the [related topics list](#related-topics).
- ```plaintext
- Please select what kind of key you want:
- (1) RSA and RSA (default)
- (2) DSA and Elgamal
- (3) DSA (sign only)
- (4) RSA (sign only)
- Your selection? 1
- ```
+## View a user's public GPG key
-1. The next question is key length. We recommend you choose `4096`:
+To view a user's public GPG key, you can either:
- ```plaintext
- RSA keys may be between 1024 and 4096 bits long.
- What keysize do you want? (2048) 4096
- Requested keysize is 4096 bits
- ```
+- Go to `https://gitlab.example.com/<USERNAME>.gpg`. GitLab displays the GPG key,
+ if the user has configured one, or a blank page for users without a configured GPG key.
+- Go to the user's profile (such as `https://gitlab.example.com/<USERNAME>`). In the top right
+ of the user's profile, select **View public GPG keys** (**{key}**).
-1. Specify the validity period of your key. This is something
- subjective, and you can use the default value, which is to never expire:
+## Configure commit signing
- ```plaintext
- Please specify how long the key should be valid.
- 0 = key does not expire
- <n> = key expires in n days
- <n>w = key expires in n weeks
- <n>m = key expires in n months
- <n>y = key expires in n years
- Key is valid for? (0) 0
- Key does not expire at all
- ```
+To sign commits, you must configure both your local machine and your GitLab account:
-1. Confirm that the answers you gave were correct by typing `y`:
+1. [Create a GPG key](#create-a-gpg-key).
+1. [Add a GPG key to your account](#add-a-gpg-key-to-your-account).
+1. [Associate your GPG key with Git](#associate-your-gpg-key-with-git).
+1. [Sign your Git commits](#sign-your-git-commits).
- ```plaintext
- Is this correct? (y/N) y
- ```
+### Create a GPG key
-1. Enter your real name, the email address to be associated with this key
- (should match a verified email address you use in GitLab) and an optional
- comment (press <kbd>Enter</kbd> to skip):
+If you don't already have a GPG key, create one:
- ```plaintext
- GnuPG needs to construct a user ID to identify your key.
+1. [Install GPG](https://www.gnupg.org/download/) for your operating system.
+ If your operating system has `gpg2` installed, replace `gpg` with `gpg2` in
+ the commands on this page.
+1. To generate your key pair, run the command appropriate for your version of `gpg`:
- Real name: Mr. Robot
- Email address: <your_email>
- Comment:
- You selected this USER-ID:
- "Mr. Robot <your_email>"
+ ```shell
+ # Use this command for the default version of GPG, including
+ # Gpg4win on Windows, and most macOS versions:
+ gpg --gen-key
- Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O
+ # Use this command for versions of GPG later than 2.1.17:
+ gpg --full-gen-key
```
-1. Pick a strong password when asked and type it twice to confirm.
-1. Use the following command to list the private GPG key you just created:
+1. Select the algorithm your key should use, or press <kbd>Enter</kbd> to select
+ the default option, `RSA and RSA`.
+1. Select the key length, in bits. GitLab recommends 4096-bit keys.
+1. Specify the validity period of your key. This value is subjective, and the
+ default value is no expiration.
+1. To confirm your answers, enter `y`.
+1. Enter your name.
+1. Enter your email address. It must match a
+ [verified email address](../../../profile/index.md#change-the-email-displayed-on-your-commits)
+ in your GitLab account.
+1. Optional. Enter a comment to display in parentheses after your name.
+1. GPG displays the information you've entered so far. Edit the information or press
+ <kbd>O</kbd> (for `Okay`) to continue.
+1. Enter a strong password, then enter it again to confirm it.
+1. To list your private GPG key, run this command, replacing
+ `<EMAIL>` with the email address you used when you generated the key:
```shell
- gpg --list-secret-keys --keyid-format LONG <your_email>
+ gpg --list-secret-keys --keyid-format LONG <EMAIL>
```
- Replace `<your_email>` with the email address you entered above.
-
-1. Copy the GPG key ID that starts with `sec`. In the following example, that's
- `30F2B65B9246B6CA`:
+1. In the output, identify the `sec` line, and copy the GPG key ID. It begins after
+ the `/` character. In this example, the key ID is `30F2B65B9246B6CA`:
```plaintext
sec rsa4096/30F2B65B9246B6CA 2017-08-18 [SC]
@@ -137,49 +104,46 @@ started:
ssb rsa4096/B7ABC0813E4028C0 2017-08-18 [E]
```
-1. Export the public key of that ID (replace your key ID from the previous step):
+1. To show the associated public key, run this command, replacing `<ID>` with the
+ GPG key ID from the previous step:
```shell
- gpg --armor --export 30F2B65B9246B6CA
+ gpg --armor --export <ID>
```
-1. Finally, copy the public key and [add it in your user settings](#adding-a-gpg-key-to-your-account)
+1. Copy the public key, including the `BEGIN PGP PUBLIC KEY BLOCK` and
+ `END PGP PUBLIC KEY BLOCK` lines. You need this key in the next step.
-## Adding a GPG key to your account
+### Add a GPG key to your account
-NOTE:
-After you add a key, you cannot edit it, only remove it. In case the paste
-didn't work, you have to remove the offending key and re-add it.
-
-You can add a GPG key in your user settings:
+To add a GPG key to your user settings:
+1. Sign in to GitLab.
1. In the top-right corner, select your avatar.
1. Select **Edit profile**.
-1. On the left sidebar, select **GPG Keys**.
-1. Paste your _public_ key in the **Key** text box.
-
- ![Paste GPG public key](img/profile_settings_gpg_keys_paste_pub.png)
-
-1. Select **Add key** to add it to GitLab. You can see the key's fingerprint, the corresponding
- email address, and creation date.
+1. On the left sidebar, select **GPG Keys** (**{key}**).
+1. In **Key**, paste your _public_ key.
+1. To add the key to your account, select **Add key**. GitLab shows the key's
+ fingerprint, email address, and creation date:
![GPG key single page](img/profile_settings_gpg_keys_single_key.png)
-## Associating your GPG key with Git
+After you add a key, you cannot edit it. Instead, remove the offending key and re-add it.
-After you have [created your GPG key](#generating-a-gpg-key) and [added it to
-your account](#adding-a-gpg-key-to-your-account), it's time to tell Git which
-key to use.
+### Associate your GPG key with Git
-1. Use the following command to list the private GPG key you just created:
+After you [create your GPG key](#create-a-gpg-key) and
+[add it to your account](#add-a-gpg-key-to-your-account), you must configure Git
+to use this key:
+
+1. Run this command to list the private GPG key you just created,
+ replacing `<EMAIL>` with the email address for your key:
```shell
- gpg --list-secret-keys --keyid-format LONG <your_email>
+ gpg --list-secret-keys --keyid-format LONG <EMAIL>
```
- Replace `<your_email>` with the email address you entered above.
-
-1. Copy the GPG key ID that starts with `sec`. In the following example, that's
+1. Copy the GPG private key ID that starts with `sec`. In this example, the private key ID is
`30F2B65B9246B6CA`:
```plaintext
@@ -189,114 +153,103 @@ key to use.
ssb rsa4096/B7ABC0813E4028C0 2017-08-18 [E]
```
-1. Tell Git to use that key to sign the commits:
+1. Run this command to configure Git to sign your commits with your key,
+ replacing `<KEY ID>` with your GPG key ID:
```shell
- git config --global user.signingkey 30F2B65B9246B6CA
+ git config --global user.signingkey <KEY ID>
```
- Replace `30F2B65B9246B6CA` with your GPG key ID.
-
-1. Optional. If Git is using `gpg` and you get errors like `secret key not available`
- or `gpg: signing failed: secret key not available`, run the following command to
- change to `gpg2`:
+1. Optional. If Git uses `gpg` and you get errors like `secret key not available`
+ or `gpg: signing failed: secret key not available`, run this command to
+ use `gpg2` instead:
```shell
git config --global gpg.program gpg2
```
-## Signing commits
+### Sign your Git commits
-After you have [created your GPG key](#generating-a-gpg-key) and [added it to
-your account](#adding-a-gpg-key-to-your-account), you can start signing your
-commits:
+After you [add your public key to your account](#add-a-gpg-key-to-your-account),
+you can sign individual commits manually, or configure Git to default to signed commits:
-1. Commit like you used to, the only difference is the addition of the `-S` flag:
+- Sign individual Git commits manually:
+ 1. Add `-S` flag to any commit you want to sign:
- ```shell
- git commit -S -m "My commit msg"
- ```
+ ```shell
+ git commit -S -m "My commit message"
+ ```
-1. Enter the passphrase of your GPG key when asked.
-1. Push to GitLab and check that your commits [are verified](#verifying-commits).
+ 1. Enter the passphrase of your GPG key when asked.
+ 1. Push to GitLab and check that your commits [are verified](#verify-commits).
+- Sign all Git commits by default by running this command:
-If you don't want to type the `-S` flag every time you commit, you can tell Git
-to sign your commits automatically:
+ ```shell
+ git config --global commit.gpgsign true
+ ```
-```shell
-git config --global commit.gpgsign true
-```
+## Verify commits
-## Verifying commits
+You can review commits for a merge request, or for an entire project:
-1. Within a project or [merge request](../../merge_requests/index.md), navigate to
- the **Commits** tab. Signed commits show a badge containing either
- **Verified** or **Unverified**, depending on the verification status of the GPG
- signature.
+1. To review commits for a project:
+ 1. On the top bar, select **Menu > Projects** and find your project.
+ 1. On the left sidebar, select **Repository > Commits**.
+1. To review commits for a merge request:
+ 1. On the top bar, select **Menu > Projects** and find your project.
+ 1. On the left sidebar, select **Merge requests**, then select your merge request.
+ 1. Select **Commits**.
+1. Identify the commit you want to review. Signed commits show either a **Verified**
+ or **Unverified** badge, depending on the verification status of the GPG
+ signature. Unsigned commits do not display a badge:
![Signed and unsigned commits](img/project_signed_and_unsigned_commits.png)
-1. By clicking on the GPG badge, details of the signature are displayed.
+1. To display the signature details for a commit, select the GPG badge:
![Signed commit with verified signature](img/project_signed_commit_verified_signature.png)
- ![Signed commit with verified signature](img/project_signed_commit_unverified_signature.png)
+ ![Signed commit with unverified signature](img/project_signed_commit_unverified_signature.png)
-## Revoking a GPG key
+## Revoke a GPG key
-Revoking a key **unverifies** already signed commits. Commits that were
-verified by using this key changes to an unverified state. Future commits
-stay unverified after you revoke this key. This action should be used
-in case your key has been compromised.
+If a GPG key becomes compromised, revoke it. Revoking a key changes both future and past commits:
+
+- Past commits signed by this key are marked as unverified.
+- Future commits signed by this key are marked as unverified.
To revoke a GPG key:
1. In the top-right corner, select your avatar.
1. Select **Edit profile**.
-1. On the left sidebar, select **GPG Keys**.
+1. On the left sidebar, select **GPG Keys** (**{key}**).
1. Select **Revoke** next to the GPG key you want to delete.
-## Removing a GPG key
+## Remove a GPG key
+
+When you remove a GPG key from your GitLab account:
-Removing a key **does not unverify** already signed commits. Commits that were
-verified by using this key stay verified. Only unpushed commits stay
-unverified after you remove this key. To unverify already signed commits, you need
-to [revoke the associated GPG key](#revoking-a-gpg-key) from your account.
+- Previous commits signed with this key remain verified.
+- Future commits (including any commits created but not yet pushed) that attempt
+ to use this key are unverified.
To remove a GPG key from your account:
1. In the top-right corner, select your avatar.
1. Select **Edit profile**.
-1. On the left sidebar, select **GPG Keys**.
-1. Select the trash icon (**{remove}**) next to the GPG key you want to delete.
-
-## Rejecting commits that are not signed **(PREMIUM)**
-
-You can configure your project to reject commits that aren't GPG-signed
-via [push rules](../push_rules.md).
-
-## GPG signing API
-
-Learn how to [get the GPG signature from a commit via API](../../../../api/commits.md#get-gpg-signature-of-a-commit).
-
-## Further reading
-
-For more details about GPG, see:
-
-- [Git Tools - Signing Your Work](https://git-scm.com/book/en/v2/Git-Tools-Signing-Your-Work)
-- [Managing OpenPGP Keys](https://riseup.net/en/security/message-security/openpgp/gpg-keys)
-- [OpenPGP Best Practices](https://riseup.net/en/security/message-security/openpgp/best-practices)
-- [Creating a new GPG key with subkeys](https://www.void.gr/kargig/blog/2013/12/02/creating-a-new-gpg-key-with-subkeys/) (advanced)
-- [Review existing GPG keys in your instance](../../../admin_area/credentials_inventory.md#review-existing-gpg-keys)
-
-<!-- ## 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. -->
+1. On the left sidebar, select **GPG Keys** (**{key}**).
+1. Select **Remove** (**{remove}**) next to the GPG key you want to delete.
+
+If you must unverify both future and past commits,
+[revoke the associated GPG key](#revoke-a-gpg-key) instead.
+
+## Related topics
+
+- [Sign commits and tags with X.509 certificates](../x509_signed_commits/index.md)
+- [Commits API](../../../../api/commits.md)
+- GPG resources:
+ - [Git Tools - Signing Your Work](https://git-scm.com/book/en/v2/Git-Tools-Signing-Your-Work)
+ - [Managing OpenPGP Keys](https://riseup.net/en/security/message-security/openpgp/gpg-keys)
+ - [OpenPGP Best Practices](https://riseup.net/en/security/message-security/openpgp/best-practices)
+ - [Creating a new GPG key with subkeys](https://www.void.gr/kargig/blog/2013/12/02/creating-a-new-gpg-key-with-subkeys/) (advanced)
+ - [Review existing GPG keys in your instance](../../../admin_area/credentials_inventory.md#review-existing-gpg-keys)
diff --git a/doc/user/project/repository/img/fork_form_v13_10.png b/doc/user/project/repository/img/fork_form_v13_10.png
deleted file mode 100644
index 00c2f89a844..00000000000
--- a/doc/user/project/repository/img/fork_form_v13_10.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/project/repository/img/forking_workflow_choose_namespace_v13_10.png b/doc/user/project/repository/img/forking_workflow_choose_namespace_v13_10.png
deleted file mode 100644
index 74f65cb663d..00000000000
--- a/doc/user/project/repository/img/forking_workflow_choose_namespace_v13_10.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/project/repository/jupyter_notebooks/index.md b/doc/user/project/repository/jupyter_notebooks/index.md
index 5646f478d9f..cd0c6679d8d 100644
--- a/doc/user/project/repository/jupyter_notebooks/index.md
+++ b/doc/user/project/repository/jupyter_notebooks/index.md
@@ -25,11 +25,8 @@ GitLab.
## Cleaner diffs
-> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/6589) in GitLab 14.5 [with a flag](../../../../administration/feature_flags.md) named `jupyter_clean_diffs`. Enabled by default.
-
-FLAG:
-On self-managed GitLab, by default this feature is available. To hide the feature, ask an administrator to [disable the feature flag](../../../../administration/feature_flags.md) named `jupyter_clean_diffs`.
-On GitLab.com, this feature is available.
+> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/6589) in GitLab 14.5 [with a flag](../../../../administration/feature_flags.md) named `jupyter_clean_diffs`. Enabled by default.
+> - [Generally available](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/75500) in GitLab 14.9. Feature flag `jupyter_clean_diffs` removed.
When commits include changes to Jupyter Notebook files, GitLab:
diff --git a/doc/user/project/repository/mirror/index.md b/doc/user/project/repository/mirror/index.md
index cddbc6fd891..c9fa30e39a8 100644
--- a/doc/user/project/repository/mirror/index.md
+++ b/doc/user/project/repository/mirror/index.md
@@ -96,9 +96,7 @@ Prerequisite:
1. Select **Update now** (**{retry}**):
![Repository mirroring force update user interface](img/repository_mirroring_force_update.png)
-## Mirror only protected branches **(PREMIUM)**
-
-> Moved to GitLab Premium in 13.9.
+## Mirror only protected branches
You can choose to mirror only the
[protected branches](../../protected_branches.md) in the mirroring project,
diff --git a/doc/user/project/repository/mirror/push.md b/doc/user/project/repository/mirror/push.md
index 221616bd41c..ebc4430ac53 100644
--- a/doc/user/project/repository/mirror/push.md
+++ b/doc/user/project/repository/mirror/push.md
@@ -76,7 +76,7 @@ through the [remote mirrors API](../../../../api/remote_mirrors.md).
To configure a mirror from GitLab to GitHub:
-1. Create a [GitHub personal access token](https://docs.github.com/en/github/authenticating-to-github/keeping-your-account-and-data-secure/creating-a-personal-access-token)
+1. Create a [GitHub personal access token](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token)
with `public_repo` selected.
1. Enter a **Git repository URL** with this format:
`https://<your_access_token>@github.com/<github_group>/<github_project>.git`.
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 37b16d90d93..83fafd409e8 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
@@ -13,8 +13,6 @@ Git repositories become larger over time. When large files are added to a Git re
- They take up a large amount of storage space on the server.
- Git repository storage limits [can be reached](#storage-limits).
-Such problems can be detected with [git-sizer](https://github.com/github/git-sizer#getting-started).
-
Rewriting a repository can remove unwanted history to make the repository smaller.
We **recommend [`git filter-repo`](https://github.com/newren/git-filter-repo/blob/main/README.md)**
over [`git filter-branch`](https://git-scm.com/docs/git-filter-branch) and
@@ -40,7 +38,8 @@ These refs are not automatically downloaded and hidden refs are not advertised,
To purge files from a GitLab repository:
-1. [Install `git filter-repo`](https://github.com/newren/git-filter-repo/blob/main/INSTALL.md)
+1. Install either [`git filter-repo`](https://github.com/newren/git-filter-repo/blob/main/INSTALL.md) or
+ [`git-sizer`](https://github.com/github/git-sizer#getting-started)
using a supported package manager or from source.
1. Generate a fresh [export from the
@@ -63,31 +62,43 @@ To purge files from a GitLab repository:
git clone --bare --mirror /path/to/project.bundle
```
-1. Navigate to the `project.git` directory:
+1. Go to the `project.git` directory:
```shell
cd project.git
```
-1. Using `git filter-repo`, purge any files from the history of your repository. Because we are
+1. Using either `git filter-repo` or `git-sizer`, analyze your repository
+ and review the results to determine which items you want to purge:
+
+ ```shell
+ # Using git filter-repo
+ git filter-repo --analyze
+ head .git/filter-repo/analysis/*-{all,deleted}-sizes.txt
+
+ # Using git-sizer
+ git-sizer
+ ```
+
+1. Proceed to purging any files from the history of your repository. Because we are
trying to remove internal refs, we rely on the `commit-map` produced by each run to tell us
which internal refs to remove.
NOTE:
- `git filter-repo` creates a new `commit-map` file every run, and overwrite the `commit-map` from
+ `git filter-repo` creates a new `commit-map` file every run, and overwrites the `commit-map` from
the previous run. You need this file from **every** run. Do the next step every time you run
`git filter-repo`.
- To purge all files larger than 10M, the `--strip-blobs-bigger-than` option can be used:
+ To purge specific files, the `--path` and `--invert-paths` options can be combined:
```shell
- git filter-repo --strip-blobs-bigger-than 10M
+ git filter-repo --path path/to/file.ext --invert-paths
```
- To purge specific large files by path, the `--path` and `--invert-paths` options can be combined.
+ To generally purge all files larger than 10M, the `--strip-blobs-bigger-than` option can be used:
```shell
- git filter-repo --path path/to/big/file.m4v --invert-paths
+ git filter-repo --strip-blobs-bigger-than 10M
```
See the
@@ -148,7 +159,7 @@ operations before continuing.
To clean up a repository:
1. Go to the project for the repository.
-1. Navigate to **Settings > Repository**.
+1. Go to **Settings > Repository**.
1. Upload a list of objects. For example, a `commit-map` file created by `git filter-repo` which is located in the
`filter-repo` directory.
@@ -158,7 +169,7 @@ To clean up a repository:
split -l 3000 filter-repo/commit-map filter-repo/commit-map-
```
-1. Click **Start cleanup**.
+1. Select **Start cleanup**.
This:
@@ -229,7 +240,7 @@ Until `git gc` runs on the GitLab side, the "removed" commits and blobs still ex
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
+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:
diff --git a/doc/user/project/repository/x509_signed_commits/index.md b/doc/user/project/repository/x509_signed_commits/index.md
index 27ef14d31c5..c9cddad1a91 100644
--- a/doc/user/project/repository/x509_signed_commits/index.md
+++ b/doc/user/project/repository/x509_signed_commits/index.md
@@ -20,15 +20,15 @@ The main difference is the way GitLab determines whether or not the developer's
(A trust store is a repository of trusted security certificates.) Combined with
any required intermediate certificates in the signature, the developer's certificate
can be chained back to a trusted root certificate.
-- For GPG, developers [add their GPG key](../gpg_signed_commits/index.md#adding-a-gpg-key-to-your-account)
+- For GPG, developers [add their GPG key](../gpg_signed_commits/index.md#add-a-gpg-key-to-your-account)
to their account.
GitLab uses its own certificate store and therefore defines the
-[trust chain](https://www.ssl.com/faqs/what-is-a-chain-of-trust/).
+[trust chain](https://www.ssl.com/faqs/what-is-a-certificate-authority/).
For a commit or tag to be *verified* by GitLab:
- The signing certificate email must match a verified email address in GitLab.
-- The GitLab instance must be able to establish a full [trust chain](https://www.ssl.com/faqs/what-is-a-chain-of-trust/)
+- The GitLab instance must be able to establish a full trust chain
from the certificate in the signature to a trusted certificate in the GitLab certificate store.
This chain may include intermediate certificates supplied in the signature. You may
need to add certificates, such as Certificate Authority root certificates,
diff --git a/doc/user/project/requirements/index.md b/doc/user/project/requirements/index.md
index d549a22910a..6abe9c08d28 100644
--- a/doc/user/project/requirements/index.md
+++ b/doc/user/project/requirements/index.md
@@ -10,8 +10,8 @@ info: To determine the technical writer assigned to the Stage/Group associated w
NOTE:
In 14.4, Requirements was moved under **Issues**.
-> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/2703) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 12.10.
-> - The ability to add and edit a requirement's long description [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/224622) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 13.5.
+> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/2703) in GitLab 12.10.
+> - The ability to add and edit a requirement's long description [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/224622) in GitLab 13.5.
> - [Moved under Issues](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/70748) in 14.4
With requirements, you can set criteria to check your products against. They can be based on users,
@@ -64,7 +64,7 @@ next to the requirement title.
## Edit a requirement
-> The ability to mark a requirement as Satisfied [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/218607) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 13.5.
+> The ability to mark a requirement as Satisfied [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/218607) in GitLab 13.5.
You can edit a requirement from the requirements list page.
@@ -108,7 +108,7 @@ As soon as a requirement is reopened, it no longer appears in the **Archived** t
## Search for a requirement
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/212543) in [GitLab Ultimate](https://about.gitlab.com/pricing/) 13.1.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/212543) in GitLab 13.1.
> - Searching by status [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/224614) in GitLab 13.10.
You can search for a requirement from the requirements list page based on the following criteria:
@@ -131,8 +131,8 @@ You can also sort the requirements list by:
## 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.
-> - [Added](https://gitlab.com/gitlab-org/gitlab/-/issues/215514) ability to specify individual requirements and their statuses in [GitLab Ultimate](https://about.gitlab.com/pricing/) 13.2.
+> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/2859) in GitLab 13.1.
+> - [Added](https://gitlab.com/gitlab-org/gitlab/-/issues/215514) ability to specify individual requirements and their statuses in GitLab 13.2.
GitLab supports [requirements test reports](../../../ci/yaml/artifacts_reports.md#artifactsreportsrequirements) now.
You can add a job to your CI pipeline that, when triggered, marks all existing
diff --git a/doc/user/project/service_desk.md b/doc/user/project/service_desk.md
index 1e5b818c99d..90732ba4fe2 100644
--- a/doc/user/project/service_desk.md
+++ b/doc/user/project/service_desk.md
@@ -41,7 +41,7 @@ Here's how Service Desk works for you:
1. You provide a project-specific email address to your paying customers, who can email you directly
from the application.
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
+1. Your team members go 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.
@@ -93,8 +93,8 @@ displayed in the information note.
### Using customized email templates
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/2460) in GitLab Premium 12.7.
-> - Moved to GitLab Free in 13.2.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/2460) in GitLab 12.7.
+> - Moved from GitLab Premium to GitLab Free in 13.2.
An email is sent to the author when:
@@ -153,7 +153,7 @@ To use a custom description template with Service Desk:
1. On the top bar, select **Menu > Projects** and find your project.
1. [Create a description template](description_templates.md#create-an-issue-template).
1. On the left sidebar, select **Settings > General > Service Desk**.
-1. From the dropdown **Template to append to all Service Desk issues**, search or select your template.
+1. From the dropdown list **Template to append to all Service Desk issues**, search or select your template.
### Using a custom email display name
@@ -171,7 +171,7 @@ To edit the custom email display name:
### Using a custom email address **(FREE SELF)**
-> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/2201) in GitLab Premium 13.0.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/2201) in GitLab 13.0.
> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/284656) in GitLab 13.8.
It is possible to customize the email address used by Service Desk. To do this, you must configure
@@ -190,13 +190,13 @@ you can customize the mailbox used by Service Desk. This allows you to have
a separate email address for Service Desk by also configuring a [custom suffix](#configuring-a-custom-email-address-suffix)
in project settings.
-The `address` must include the `+%{key}` placeholder within the 'user'
-portion of the address, before the `@`. This is used to identify the project
+The `address` must include the `+%{key}` placeholder in the 'user'
+portion of the address, before the `@`. The placeholder is used to identify the project
where the issue should be created.
NOTE:
When configuring a custom mailbox, the `service_desk_email` and `incoming_email`
-configurations must always use separate mailboxes. This is important, because
+configurations must always use separate mailboxes. It's important, because
emails picked from `service_desk_email` mailbox are processed by a different
worker and it would not recognize `incoming_email` emails.
@@ -241,7 +241,7 @@ The configuration options are the same as for configuring
##### Microsoft Graph
-> Introduced in [GitLab 13.11](https://gitlab.com/gitlab-org/gitlab/-/issues/214900)
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/214900) in GitLab 13.11.
Service Desk can be configured to read Microsoft Exchange Online mailboxes with the Microsoft
Graph API instead of IMAP. Follow the [documentation in the incoming email section for setting up an OAuth2 application for Microsoft Graph](../../administration/incoming_email.md#microsoft-graph).
@@ -267,7 +267,7 @@ The Microsoft Graph API is not yet supported in source installations. See [this
#### Configuring a custom email address suffix
-You can set a custom suffix in your project's Service Desk settings once you have configured a [custom mailbox](#configuring-a-custom-mailbox).
+You can set a custom suffix in your project's Service Desk settings after you have configured a [custom mailbox](#configuring-a-custom-mailbox).
It can contain only lowercase letters (`a-z`), numbers (`0-9`), or underscores (`_`).
When configured, the custom suffix creates a new Service Desk email address, consisting of the
@@ -281,7 +281,7 @@ For example, suppose the `mygroup/myproject` project Service Desk settings has t
The Service Desk email address for this project is: `contact+mygroup-myproject-support@example.com`.
The [incoming email](../../administration/incoming_email.md) address still works.
-If you don't configure the custom suffix, the default project identification will be used for identifying the project. You can see that email address in the project settings.
+If you don't configure the custom suffix, the default project identification is used for identifying the project. You can see that email address in the project settings.
## Using Service Desk
@@ -292,6 +292,7 @@ In these issues, you can also see our friendly neighborhood [Support Bot](#suppo
> Support for additional email headers [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/346600) in GitLab 14.6.
> In earlier versions, the Service Desk email address had to be in the "To" field.
+
To create a Service Desk issue, an end user does not need to know anything about
the GitLab instance. They just send an email to the address they are given, and
receive an email back confirming receipt:
@@ -327,7 +328,28 @@ You can read and write comments as you normally do in GitLab:
Note that:
- The project's visibility (private, internal, public) does not affect Service Desk.
-- The path to the project, including its group or namespace, are shown in emails.
+- The path to the project, including its group or namespace, is shown in emails.
+
+#### Issues created on someone's behalf
+
+To allow third party applications and ticketing systems to interface with Service Desk,
+when the email contains the `Reply-To` email header, this email address is used as the address of the
+issue author.
+
+Because the `Reply-To` header can be set to arbitrary values, do not blindly trust that an issue
+created on behalf of `someone@example.com` was indeed created by the real owner of such email address.
+
+For example, an email with headers `To: support@example.com` and `Reply-To:someone@example.com`
+creates an issue with the following note:
+
+> Created (…) by `support@example.com` (reply to: `someone@example.com`) (…)
+
+#### Privacy considerations
+
+Service Desk issues are confidential, but the project owner can
+[make an issue public](issues/confidential_issues.md#modify-issue-confidentiality).
+When a Service Desk issue becomes public, the issue creator's email address is disclosed
+to everyone who can view the project.
### Support Bot user
diff --git a/doc/user/project/settings/import_export.md b/doc/user/project/settings/import_export.md
index 8cee567ae93..ae3decb8079 100644
--- a/doc/user/project/settings/import_export.md
+++ b/doc/user/project/settings/import_export.md
@@ -229,7 +229,7 @@ and the exports between them are compatible.
## Related topics
- [Project import/export API](../../../api/project_import_export.md)
-- [Project import/export administration Rake tasks](../../../administration/raketasks/project_import_export.md) **(FREE SELF)**
+- [Project import/export administration Rake tasks](../../../administration/raketasks/project_import_export.md)
- [Group import/export](../../group/settings/import_export.md)
- [Group import/export API](../../../api/group_import_export.md)
@@ -305,6 +305,9 @@ reduce the repository size for another import attempt:
#### Workaround option 2
+NOTE:
+This workaround requires access to the rails console, which isn't available to end-users on GitLab.com.
+
Rather than attempting to push all changes at once, this workaround:
- Separates the project import from the Git Repository import
@@ -351,32 +354,32 @@ Rather than attempting to push all changes at once, this workaround:
git push -u origin ${COMMIT_SHA}:refs/heads/main
done
git push -u origin main
- git push -u origin -—all
- git push -u origin -—tags
+ git push -u origin --all
+ git push -u origin --tags
```
### Manually execute export steps
Exports sometimes fail without giving enough information to troubleshoot. In these cases, it can be
-helpful to [execute the export process manually within rails](https://gitlab.com/gitlab-com/runbooks/-/blob/master/docs/uncategorized/project-export.md#export-a-project-via-rails-console).
+helpful to [open a rails console session](../../../administration/operations/rails_console.md#starting-a-rails-console-session)
+and loop through [all the defined exporters](https://gitlab.com/gitlab-org/gitlab/-/blob/b67a5b5a12498d57cd877023b7385f7251e57de8/app/services/projects/import_export/export_service.rb#L65).
Execute each line individually, rather than pasting the entire block at once, so you can see any
errors each command returns.
```shell
+# User needs to have permission to export
u = User.find_by_username('someuser')
p = Project.find_by_full_path('some/project')
e = Projects::ImportExport::ExportService.new(p,u)
e.send(:version_saver).send(:save)
-e.send(:avatar_saver).send(:save)
-e.send(:project_tree_saver).send(:save)
-e.send(:uploads_saver).send(:save)
-e.send(:wiki_repo_saver).send(:save)
-e.send(:lfs_saver).send(:save)
-e.send(:snippets_repo_saver).send(:save)
-e.send(:design_repo_saver).send(:save)
+e.send(:repo_saver).send(:save)
+## continue using `e.send(:exporter_name).send(:save)` going through the list of exporters
+# The following line should show you the export_path similar to /var/opt/gitlab/gitlab-rails/shared/tmp/gitlab_exports/@hashed/49/94/4994....
s = Gitlab::ImportExport::Saver.new(exportable: p, shared:p.import_export_shared)
+
+# To try and upload use:
s.send(:compress_and_save)
s.send(:save_upload)
```
diff --git a/doc/user/project/settings/index.md b/doc/user/project/settings/index.md
index 12d75551aac..342b8d80bcf 100644
--- a/doc/user/project/settings/index.md
+++ b/doc/user/project/settings/index.md
@@ -541,7 +541,7 @@ Configure [alert integrations](../../../operations/incident_management/integrati
#### Alert integration
-Automatically [create](../../../operations/incident_management/incidents.md#create-incidents-automatically), [notify on](../../../operations/incident_management/paging.md#email-notifications), and [resolve](../../../operations/incident_management/incidents.md#automatically-close-incidents-via-recovery-alerts) incidents based on GitLab alerts.
+Automatically [create](../../../operations/incident_management/incidents.md#create-incidents-automatically), [notify on](../../../operations/incident_management/paging.md#email-notifications-for-alerts), and [resolve](../../../operations/incident_management/incidents.md#automatically-close-incidents-via-recovery-alerts) incidents based on GitLab alerts.
#### PagerDuty integration
@@ -555,11 +555,11 @@ Automatically [create](../../../operations/incident_management/incidents.md#crea
Configure Error Tracking to discover and view [Sentry errors within GitLab](../../../operations/error_tracking.md).
-### Jaeger tracing **(ULTIMATE)**
+### Jaeger tracing
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
+### Status Page **(ULTIMATE)**
[Add Storage credentials](../../../operations/incident_management/status_page.md#sync-incidents-to-the-status-page)
to enable the syncing of public Issues to a [deployed status page](../../../operations/incident_management/status_page.md#create-a-status-page-project).
diff --git a/doc/user/project/settings/project_access_tokens.md b/doc/user/project/settings/project_access_tokens.md
index aa30c576c7c..a78226ac2f8 100644
--- a/doc/user/project/settings/project_access_tokens.md
+++ b/doc/user/project/settings/project_access_tokens.md
@@ -24,6 +24,8 @@ Project access tokens are similar to [group access tokens](../../group/settings/
and [personal access tokens](../../profile/personal_access_tokens.md), except they are
associated with a project rather than a group or user.
+In self-managed instances, project access tokens are subject to the same [maximum lifetime limits](../../admin_area/settings/account_and_limit_settings.md#limit-the-lifetime-of-personal-access-tokens) as personal access tokens if the limit is set.
+
You can use project access tokens:
- On GitLab SaaS if you have the Premium license tier or higher. Project access tokens are not available with a [trial license](https://about.gitlab.com/free-trial/).
@@ -43,7 +45,8 @@ To create a project access token:
1. On the top bar, select **Menu > Projects** and find your project.
1. On the left sidebar, select **Settings > Access Tokens**.
1. Enter a name. The token name is visible to any user with permissions to view the project.
-1. Optional. Enter an expiry date for the token. The token will expire on that date at midnight UTC.
+1. Optional. Enter an expiry date for the token. The token expires on that date at midnight UTC. An instance-wide [maximum lifetime](../../admin_area/settings/account_and_limit_settings.md#limit-the-lifetime-of-personal-access-tokens) setting can limit the maximum allowable lifetime in self-managed instances.
+
1. Select a role for the token.
1. Select the [desired scopes](#scopes-for-a-project-access-token).
1. Select **Create project access token**.
diff --git a/doc/user/project/static_site_editor/index.md b/doc/user/project/static_site_editor/index.md
index 072f5bf1927..7c74a625b92 100644
--- a/doc/user/project/static_site_editor/index.md
+++ b/doc/user/project/static_site_editor/index.md
@@ -18,18 +18,13 @@ WARNING:
This feature is in its end-of-life process. It is
[deprecated](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/77246)
for use in GitLab 14.7, and is planned for
-[removal](https://gitlab.com/groups/gitlab-org/-/epics/7351) in GitLab 15.0.
-Users should instead use the [Web Editor](../repository/web_editor.md) or [Web IDE](../web_ide/index.md).
+[removal](https://gitlab.com/groups/gitlab-org/-/epics/7351) in GitLab 14.10.
+Users should instead use the [Web Editor](../repository/web_editor.md) or [Web IDE](../web_ide/index.md). [Removal instructions](#remove-the-static-site-editor) for existing projects are included on this page.
Static Site Editor (SSE) enables users to edit content on static websites without
prior knowledge of the underlying templating language, site architecture, or
Git commands. A contributor to your project can quickly edit a Markdown page
-and submit the changes for review.
-
-## Use cases
-
-The Static Site Editor allows collaborators to submit changes to static site
-files seamlessly. For example:
+and submit the changes for review. For example:
- Non-technical collaborators can edit a page directly from the browser.
They don't need to know Git and the details of your project to contribute.
@@ -37,6 +32,43 @@ files seamlessly. For example:
- Temporary collaborators can jump from project to project and quickly edit pages instead
of having to clone or fork every single project they need to submit changes to.
+## Remove the Static Site Editor
+
+The Static Site Editor itself isn't part of your project. To remove the Static Site Editor
+from an existing project, remove links that point back to the editor:
+
+1. Remove any links that use `edit_page_url` in your project. If you used the
+ **Middleman - Static Site Editor** project template, the only instance of this
+ helper is located in `/source/layouts/layout.erb`. Remove this line entirely:
+
+ ```ruby
+ <%= link_to('Edit this page', edit_page_url(data.config.repository, current_page.file_descriptor.relative_path), id: 'edit-page-link') %>
+ ```
+
+1. In `/data/config.yml`, delete the `repository` key / value pair:
+
+ ```yaml
+ repository: https://gitlab.com/<username>/<myproject>
+ ```
+
+ - If `repository` is the only value stored in `/data/config.yml`, you can delete the entire file.
+1. In `/helpers/custom_helpers.rb`, delete `edit_page_url()` and `endcode_path()`:
+
+ ```ruby
+ def edit_page_url(base_url, relative_path)
+ "#{base_url}/-/sse/#{encode_path(relative_path)}/"
+ end
+
+ def encode_path(relative_path)
+ ERB::Util.url_encode("master/source/#{relative_path}")
+ end
+ ```
+
+ - If `edit_page_url()` and `encode_path()` are the only helpers, you may delete
+ `/helpers/custom_helpers.rb` entirely.
+1. Clean up any extraneous configuration files.
+1. Commit and push your changes.
+
## Requirements
- In order use the Static Site Editor feature, your project needs to be
diff --git a/doc/user/project/web_ide/index.md b/doc/user/project/web_ide/index.md
index 4565b5f1c91..ff8a076465d 100644
--- a/doc/user/project/web_ide/index.md
+++ b/doc/user/project/web_ide/index.md
@@ -17,16 +17,16 @@ You can also open the Web IDE when viewing a file, from the repository file list
and from merge requests:
- *When viewing a file, or the repository file list* -
- 1. In the upper right corner of the page, select **Edit in Web IDE** if it is visible.
- 1. If **Edit in Web IDE** is not visible:
+ 1. In the upper right corner of the page, select **Open in Web IDE** if it is visible.
+ 1. If **Open in Web IDE** is not visible:
1. Select the **(angle-down)** next to **Edit** or **Gitpod**, depending on your configuration.
- 1. Select **Edit in Web IDE** from the list to display it as the editing option.
- 1. Select **Edit in Web IDE** to open the editor.
+ 1. Select **Open in Web IDE** from the list to display it as the editing option.
+ 1. Select **Open in Web IDE** to open the editor.
- *When viewing a merge request* -
1. Go to your merge request, and select the **Overview** tab.
1. Scroll to the widgets section, after the merge request description.
- 1. Select **Edit in Web IDE** if it is visible.
- 1. If **Edit in Web IDE** is not visible:
+ 1. Select **Open in Web IDE** if it is visible.
+ 1. If **Open in Web IDE** is not visible:
1. Select the **(angle-down)** next to **Open in Gitpod**.
1. Select **Open in Web IDE** from the list to display it as the editing option.
1. Select **Open in Web IDE** to open the editor.
@@ -145,7 +145,7 @@ Each schema entry supports two properties:
## Configure the Web IDE
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/23352) in GitLab Free 13.1.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/23352) in GitLab 13.1.
The Web IDE supports configuration of certain editor settings by using
[`.editorconfig` files](https://editorconfig.org/). When opening a file, the
@@ -164,8 +164,8 @@ The Web IDE currently supports the following `.editorconfig` settings:
## Commit changes
-> - Starting with [GitLab 12.7](https://gitlab.com/gitlab-org/gitlab/-/issues/33441), files are automatically staged.
-> - In [GitLab 12.9](https://gitlab.com/gitlab-org/gitlab/-/issues/196609), support for staging files was removed to prevent loss of unstaged data. All of your current changes must be committed or discarded.
+> - [Starting](https://gitlab.com/gitlab-org/gitlab/-/issues/33441) with GitLab 12.7, files are automatically staged.
+> - In GitLab 12.9, support for staging files was [removed](https://gitlab.com/gitlab-org/gitlab/-/issues/196609) to prevent loss of unstaged data. All of your current changes must be committed or discarded.
After making your changes, select **Commit** on the bottom-left to
review the list of changed files.
@@ -215,13 +215,13 @@ different branch.
## Markdown editing
-> - Support for pasting images [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/22822) in GitLab Free 13.1.
-> - Side-by-side Markdown preview [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68274) in GitLab Free 14.3.
+> - Support for pasting images [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/22822) in GitLab 13.1.
+> - Side-by-side Markdown preview [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68274) in GitLab 14.3.
To edit Markdown files in the Web IDE:
1. Go to your repository, and navigate to the Markdown page you want to edit.
-1. Select **Edit in Web IDE**, and GitLab loads the page in a tab in the editor.
+1. Select **Open in Web IDE**, and GitLab loads the page in a tab in the editor.
1. Make your changes to the file. GitLab supports [GitLab Flavored Markdown](../../markdown.md#gitlab-flavored-markdown).
1. When your changes are complete, select **Commit** in the left sidebar.
1. Add a commit message, select the branch you want to commit to, and select **Commit**.
@@ -286,10 +286,10 @@ An example `package.json`:
## Interactive Web Terminals for the Web IDE
-> [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/211685) to GitLab Free in 13.1.
+> [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/211685) from GitLab Ultimate to GitLab Free in 13.1.
WARNING:
-Interactive Web Terminals for the Web IDE is currently in **Beta**.
+Interactive Web Terminals for the Web IDE is currently in [**Beta**](../../../policy/alpha-beta-support.md#beta-features).
GitLab.com shared runners [do not yet support Interactive Web Terminals](https://gitlab.com/gitlab-org/gitlab/-/issues/24674),
so you must use your own private runner to make use of this feature.
@@ -308,7 +308,7 @@ to work:
This section requires at least a `session_timeout` value (which defaults to 1800
seconds) and a `listen_address` value. If `advertise_address` is not defined, `listen_address` is used.
- If you are using a reverse proxy with your GitLab instance, web terminals must be
- [enabled](../../../administration/integration/terminal.md#enabling-and-disabling-terminal-support). **(ULTIMATE SELF)**
+ [enabled](../../../administration/integration/terminal.md#enabling-and-disabling-terminal-support).
If you have the terminal open and the job has finished with its tasks, the
terminal blocks the job from finishing for the duration configured in
@@ -391,7 +391,7 @@ 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 12.0.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/5276) in GitLab 12.0.
> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/211686) from GitLab Ultimate to GitLab Free in 13.1.
File changes in the Web IDE can be synced to a running web terminal.
diff --git a/doc/user/project/wiki/group.md b/doc/user/project/wiki/group.md
index 2c499af123c..37f2ef8fc6a 100644
--- a/doc/user/project/wiki/group.md
+++ b/doc/user/project/wiki/group.md
@@ -7,7 +7,7 @@ type: reference, how-to
# Group wikis **(PREMIUM)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/13195) in [GitLab Premium](https://about.gitlab.com/pricing/) 13.5.
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/13195) in GitLab 13.5.
If you use GitLab groups to manage multiple projects, some of your documentation
might span multiple groups. You can create group wikis, instead of [project wikis](index.md),
@@ -17,7 +17,7 @@ Group wikis are similar to [project wikis](index.md), with a few limitations:
- [Git LFS](../../../topics/git/lfs/index.md) is not supported.
- Group wikis are not included in [global search](../../search/advanced_search.md).
- Changes to group wikis don't show up in the [group's activity feed](../../group/index.md#group-activity-analytics).
-- Group wikis are enabled by default for **(PREMIUM)** and higher tiers.
+- Group wikis are enabled by default for GitLab Premium and higher tiers.
You [can't turn them off from the GitLab user interface](https://gitlab.com/gitlab-org/gitlab/-/issues/208413).
For updates, follow [the epic that tracks feature parity with project wikis](https://gitlab.com/groups/gitlab-org/-/epics/2782).
@@ -38,7 +38,7 @@ To access a group wiki:
## Export a group wiki
-> Introduced in [GitLab 13.9](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/53247).
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/53247) in GitLab 13.9.
Users with the Owner role in a group can
[import and export group wikis](../../group/settings/import_export.md) when importing
diff --git a/doc/user/project/working_with_projects.md b/doc/user/project/working_with_projects.md
index 9cfcaf4ee81..19e77d18aca 100644
--- a/doc/user/project/working_with_projects.md
+++ b/doc/user/project/working_with_projects.md
@@ -68,9 +68,8 @@ If you're an instance administrator, you can administer all project topics from
To create a project in GitLab:
-1. On the top bar, select **Menu > Project**.
-1. Select **Create new project**.
-1. On the **New project** page, choose if you want to:
+1. On the top bar, select **Menu > Project > Create new project**.
+1. On the **Create new project** page, choose if you want to:
- Create a [blank project](#create-a-blank-project).
- Create a project from a:
- [built-in template](#create-a-project-from-a-built-in-template).
@@ -80,21 +79,20 @@ To create a project in GitLab:
from a different repository. Contact your GitLab administrator if this option is not available.
- [Connect an external repository to GitLab CI/CD](../../ci/ci_cd_for_external_repos/index.md).
-NOTE:
-For a list of words that can't be used as project names see
+- For a list of words that you cannot use as project names, see
[reserved project and group names](../../user/reserved_names.md).
+- For a list of characters that you cannot use in project and group names, see
+[limitations on project and group names](../../user/reserved_names.md#limitations-on-project-and-group-names).
## Create a blank project
To create a blank project:
-1. On the top bar, select **Menu > Project**.
-1. Select **Create new project**.
+1. On the top bar, select **Menu > Projects > Create new project**.
1. Select **Create blank project**.
1. Enter the project details:
- - In the **Project name** field, enter the name of your project. You can use spaces, hyphens,
- underscores, and emoji. You cannot use special characters. After you enter the name,
- the **Project slug** populates.
+ - In the **Project name** field, enter the name of your project. You cannot use special characters at
+ the start or end of a project name.
- In the **Project slug** field, enter the path to your project. The GitLab instance uses the
slug as the URL path to the project. To change the slug, first enter the project name,
then change the slug.
@@ -121,17 +119,15 @@ Anyone can contribute a built-in template by following [these steps](https://abo
To create a project from a built-in template:
-1. On the top bar, select **Menu > Project**.
-1. Select **Create new project**.
+1. On the top bar, select **Menu > Projects > Create new project**.
1. Select **Create from template**.
1. Select the **Built-in** tab.
1. From the list of templates:
- To view a preview of the template, select **Preview**.
- To use a template for the project, select **Use template**.
1. Enter the project details:
- - In the **Project name** field, enter the name of your project. You can use spaces, hyphens,
- underscores, and emoji. You cannot use special characters. After you enter the name,
- the **Project slug** populates.
+ - In the **Project name** field, enter the name of your project. You cannot use special characters at
+ the start or end of a project name.
- In the **Project slug** field, enter the path to your project. The GitLab instance uses the
slug as the URL path to the project. To change the slug, first enter the project name,
then change the slug.
@@ -149,17 +145,15 @@ Custom project templates are available at:
- The [instance-level](../../user/admin_area/custom_project_templates.md)
- The [group-level](../../user/group/custom_project_templates.md)
-1. On the top bar, select **Menu > Project**.
-1. Select **Create new project**.
+1. On the top bar, select **Menu > Projects > Create new project**.
1. Select **Create from template**.
1. Select the **Instance** or **Group** tab.
1. From the list of templates:
- To view a preview of the template, select **Preview**.
- To use a template for the project, select **Use template**.
1. Enter the project details:
- - In the **Project name** field, enter the name of your project. You can use spaces, hyphens,
- underscores, and emoji. You cannot use special characters. After you enter the name,
- the **Project slug** populates.
+ - In the **Project name** field, enter the name of your project. You cannot use special characters at
+ the start or end of a project name.
- In the **Project slug** field, enter the path to your project. The GitLab instance uses the
slug as the URL path to the project. To change the slug, first enter the project name,
then change the slug.
@@ -177,17 +171,15 @@ HIPAA Audit Protocol published by the U.S Department of Health and Human Service
To create a project from the HIPAA Audit Protocol template:
-1. On the top bar, select **Menu > Project**.
-1. Select **Create new project**.
+1. On the top bar, select **Menu > Projects > Create new project**.
1. Select **Create from template**.
1. Select the **Built-in** tab.
1. Locate the **HIPAA Audit Protocol** template:
- To view a preview of the template, select **Preview**.
- To use the template for the project, select **Use template**.
1. Enter the project details:
- - In the **Project name** field, enter the name of your project. You can use spaces, hyphens,
- underscores, and emoji. You cannot use special characters. After you enter the name,
- the **Project slug** populates.
+ - In the **Project name** field, enter the name of your project. You cannot use special characters at
+ the start or end of a project name.
- In the **Project slug** field, enter the path to your project. The GitLab instance uses the
slug as the URL path to the project. To change the slug, first enter the project name,
then change the slug.
@@ -196,7 +188,7 @@ To create a project from the HIPAA Audit Protocol template:
change the **Visibility Level**.
1. Select **Create project**.
-## Push to create a new project
+## Create a new project with Git push
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/26388) in GitLab 10.5.
@@ -218,7 +210,7 @@ Prerequisites:
[added to your GitLab account](../../ssh/index.md#add-an-ssh-key-to-your-gitlab-account).
- You must have permission to add new projects to a namespace. To check if you have permission:
- 1. On the top bar, select **Menu > Project**.
+ 1. On the top bar, select **Menu > Projects**.
1. Select **Groups**.
1. Select a group.
1. Confirm that **New project** is visible in the upper right
@@ -266,14 +258,14 @@ You can add a star to projects you use frequently to make them easier to find.
To add a star to a project:
-1. On the top bar, select **Menu > Project**.
+1. On the top bar, select **Menu > Projects**.
1. Select **Your projects** or **Explore projects**.
1. Select a project.
1. In the upper right corner of the page, select **Star**.
## View starred projects
-1. On the top bar, select **Menu > Project**.
+1. On the top bar, select **Menu > Projects**.
1. Select **Starred projects**.
1. GitLab displays information about your starred projects, including:
@@ -290,33 +282,33 @@ you can [enable delayed project removal](../group/index.md#enable-delayed-projec
To delete a project:
-1. On the top bar, select **Menu > Project**.
+1. On the top bar, select **Menu > Projects**.
1. Select **Your projects** or **Explore projects**.
1. Select a project.
1. Select **Settings > General**.
1. Expand the **Advanced** section.
1. Scroll down to the **Delete project** section.
-1. Select **Delete project**
+1. Select **Delete project**.
1. Confirm this action by completing the field.
-## Projects pending deletion **(PREMIUM)**
+## View projects pending deletion **(PREMIUM)**
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/37014) in GitLab 13.3 for Administrators.
> - [Tab renamed](https://gitlab.com/gitlab-org/gitlab/-/issues/347468) from **Deleted projects** in GitLab 14.6.
> - [Available to all users](https://gitlab.com/gitlab-org/gitlab/-/issues/346976) in GitLab 14.8 [with a flag](../../administration/feature_flags.md) named `project_owners_list_project_pending_deletion`. Enabled by default.
-
-FLAG:
-On self-managed GitLab, by default this feature is available to all users. To make it available for administrators only,
-ask an administrator to [disable the feature flag](../../administration/feature_flags.md) named `project_owners_list_project_pending_deletion`.
-On GitLab.com, this feature is available to all users.
+> - [Generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/351556) in GitLab 14.9. [Feature flag `project_owners_list_project_pending_deletion`](https://gitlab.com/gitlab-org/gitlab/-/issues/351556) removed.
When delayed project deletion is [enabled for a group](../group/index.md#enable-delayed-project-deletion),
-projects within that group are not deleted immediately, but only after a delay. To access a list of all projects that are pending deletion:
+projects within that group are not deleted immediately, but only after a delay.
+
+To view a list of all projects that are pending deletion:
1. On the top bar, select **Menu > Projects > Explore projects**.
-1. Select the **Pending deletion** tab (in GitLab 14.6 and later) or the **Deleted projects** tab (GitLab 14.5 and earlier).
+1. Based on your GitLab version:
+ - GitLab 14.6 and later: select the **Pending deletion** tab.
+ - GitLab 14.5 and earlier: select the **Deleted projects** tab.
-Listed for each project is:
+Each project in the list shows:
- The time the project was marked for deletion.
- The time the project is scheduled for final deletion.
@@ -326,7 +318,7 @@ Listed for each project is:
To view the activity of a project:
-1. On the top bar, select **Menu > Project**.
+1. On the top bar, select **Menu > Projects**.
1. Select **Your projects** or **Explore projects**.
1. Select a project.
1. On the left sidebar, select **Project information > Activity**.
@@ -334,12 +326,12 @@ To view the activity of a project:
## Leave a project
-If you leave a project you are no longer a project
+If you leave a project, you are no longer a project
member and cannot contribute.
To leave a project:
-1. On the top bar, select **Menu > Project**.
+1. On the top bar, select **Menu > Projects**.
1. Select **Your projects** or **Explore projects**.
1. Select a project.
1. Select **Leave project**. The **Leave project** option only displays
@@ -481,3 +473,4 @@ download starts, the `insteadOf` configuration sends the traffic to the secondar
- [Connect an external repository to GitLab CI/CD](../../ci/ci_cd_for_external_repos/index.md).
- [Fork a project](repository/forking_workflow.md#creating-a-fork).
- [Adjust project visibility and access levels](settings/index.md#sharing-and-permissions).
+- [Limitations on project and group names](../../user/reserved_names.md#limitations-on-project-and-group-names)
diff --git a/doc/user/reserved_names.md b/doc/user/reserved_names.md
index 203b1c9e93a..33ecf252e43 100644
--- a/doc/user/reserved_names.md
+++ b/doc/user/reserved_names.md
@@ -4,7 +4,7 @@ group: Workspace
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
-# Reserved project and group names
+# Reserved project and group names **(FREE)**
Not all project & group names are allowed because they would conflict with
existing routes used by GitLab.
@@ -17,6 +17,13 @@ under the `TOP_LEVEL_ROUTES`, `PROJECT_WILDCARD_ROUTES` and `GROUP_ROUTES` lists
- `PROJECT_WILDCARD_ROUTES`: are names that are reserved for child groups or projects.
- `GROUP_ROUTES`: are names that are reserved for all groups or projects.
+## Limitations on project and group names
+
+- Special characters are not permitted at the start or end of project or group names. They are permitted in any other location of the name.
+- Project or group names cannot end in `.git` or `.atom`.
+- Project or group names can only contain letters, digits, emojis, "_", ".", "+", dashes, or spaces.
+- Paths can only contain letters, digits, "_", "-", and "."
+
## Reserved project names
It is currently not possible to create a project with the following names:
@@ -45,7 +52,7 @@ It is currently not possible to create a project with the following names:
## Reserved group names
-Currently the following names are reserved as top level groups:
+Currently, the following names are reserved as top level groups:
- `\-`
- `.well-known`
diff --git a/doc/user/search/advanced_search.md b/doc/user/search/advanced_search.md
index 05579696d35..cb272b3feed 100644
--- a/doc/user/search/advanced_search.md
+++ b/doc/user/search/advanced_search.md
@@ -7,7 +7,7 @@ type: reference
# GitLab Advanced Search **(PREMIUM)**
-> - Moved to GitLab Premium in 13.9.
+> Moved to GitLab Premium in 13.9.
NOTE:
This is the user documentation. To configure the Advanced Search,
@@ -147,8 +147,8 @@ its performance:
FLAG:
On self-managed GitLab, by default this feature is not available. To make it available,
- ask an administrator to [enable the feature flag](../../administration/feature_flags.md) named `prevent_abusive_searches`.
- The feature is not ready for production use.
+ask an administrator to [enable the feature flag](../../administration/feature_flags.md) named `prevent_abusive_searches`.
+The feature is not ready for production use.
To prevent abusive searches, such as searches that may result in a Distributed Denial of Service (DDoS), Global Search ignores, logs, and
doesn't return any results for searches considered abusive according to the following criteria, if `prevent_abusive_searches` feature flag is enabled:
diff --git a/doc/user/search/img/code_search.png b/doc/user/search/img/code_search.png
deleted file mode 100644
index 7c62bb6921b..00000000000
--- a/doc/user/search/img/code_search.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/search/img/code_search_git_blame_v14_9.png b/doc/user/search/img/code_search_git_blame_v14_9.png
new file mode 100644
index 00000000000..33d4e77e3f5
--- /dev/null
+++ b/doc/user/search/img/code_search_git_blame_v14_9.png
Binary files differ
diff --git a/doc/user/search/index.md b/doc/user/search/index.md
index 0a799843d3c..44327af380e 100644
--- a/doc/user/search/index.md
+++ b/doc/user/search/index.md
@@ -34,14 +34,15 @@ in the search field in the upper right corner:
> - Filtering by epics was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/195704) in GitLab 12.9.
> - Filtering by child epics was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/9029) in GitLab 13.0.
-> - Filtering by iterations was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/118742) in GitLab 13.6. Moved from GitLab Ultimate to Premium in 13.9.
+> - Filtering by iterations was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/118742) in GitLab 13.6.
+> - Filtering by iterations was moved from GitLab Ultimate to GitLab Premium in 13.9.
> - Filtering by type was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/322755) in GitLab 13.10 [with a flag](../../administration/feature_flags.md) named `vue_issues_list`. Disabled by default.
Follow these steps to filter the **Issues** and **Merge requests** list pages in projects and
groups:
-1. Click in the field **Search or filter results...**.
-1. In the dropdown menu that appears, select the attribute you wish to filter by:
+1. Select **Search or filter results...**.
+1. In the dropdown list that appears, select the attribute you wish to filter by:
- Assignee
- Author
- Confidential
@@ -112,8 +113,8 @@ You can filter the **Issues** list to individual instances by their ID. For exam
> Moved to GitLab Premium in 13.9.
-To filter merge requests by an individual approver, you can type (or select from
-the dropdown) **Approver** and select the user.
+To filter merge requests by an individual eligible approver ([Codeowner](../project/code_owners.md)), you can type (or select from
+the dropdown list) **Approver** and select the user.
![Filter MRs by an approver](img/filter_approver_merge_requests_v14_6.png)
@@ -123,29 +124,29 @@ the dropdown) **Approver** and select the user.
> - Moved to GitLab Premium in 13.9.
To filter merge requests already approved by a specific individual, you can type (or select from
-the dropdown) **Approved-By** and select the user.
+the dropdown list) **Approved-By** and select the user.
![Filter MRs by approved by](img/filter_approved_by_merge_requests_v14_6.png)
-### Filtering merge requests by reviewer **(FREE)**
+### Filtering merge requests by reviewer
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/47605) in GitLab 13.7.
To filter review requested merge requests for a specific individual, you can type (or select from
-the dropdown) **Reviewer** and select the user.
+the dropdown list) **Reviewer** and select the user.
-### Filtering merge requests by environment or deployment date **(FREE)**
+### Filtering merge requests by environment or deployment date
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/44041) in GitLab 13.6.
To filter merge requests by deployment data, such as the environment or a date,
-you can type (or select from the dropdown) the following:
+you can type (or select from the dropdown list) the following:
- Environment
- Deployed-before
- Deployed-after
-When filtering by an environment, a dropdown presents all environments that
+When filtering by an environment, a dropdown list presents all environments that
you can choose from:
![Filter MRs by their environment](img/filtering_merge_requests_by_environment_v14_6.png)
@@ -174,7 +175,7 @@ you must type at least `Sim` before autocomplete displays results.
Search history is available for issues and merge requests, and is stored locally
in your browser. To run a search from history:
-1. In the top menu, click **Issues** or **Merge requests**.
+1. In the top menu, select **Issues** or **Merge requests**.
1. To the left of the search bar, click **Recent searches**, and select a search from the list.
## Removing search filters
@@ -193,7 +194,7 @@ Some filters can be added multiple times. These include but are not limited to a
You can search your [To-Do List](../todos.md) by "to do" and "done".
You can filter to-do items per project, author, type, and action.
-Also, you can sort them by [**Label priority**](../../user/project/labels.md#label-priority),
+Also, you can sort them by [**Label priority**](../../user/project/labels.md#set-label-priority),
**Last created**, and **Oldest created**.
## Projects
@@ -227,7 +228,7 @@ and sort them by **Last created**, **Oldest created**, **Last updated**, or **Ol
From an [issue board](../../user/project/issue_board.md), you can filter issues by **Author**, **Assignee**, **Milestone**, and **Labels**.
You can also filter them by name (issue title), from the field **Filter by name**, which is loaded as you type.
-To search for issues to add to lists present in your issue board, click
+To search for issues to add to lists present in your issue board, select
the button **Add issues** on the top-right of your screen, opening a modal window from which
you can, besides filtering them by **Name**, **Author**, **Assignee**, **Milestone**,
and **Labels**, select multiple issues to add to a list of your choice:
@@ -281,13 +282,13 @@ To search through code or other documents in a single project, you can use
the search field on the top-right of your screen while the project page is open.
Code search shows only the first result in the file.
-#### Git blame from code search **(PREMIUM)**
+#### Git blame from code search **(FREE)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/327052) in GitLab 14.7.
You can access Git blame from any line that returned a result from the code search:
-![code search results](img/code_search.png)
+![code search results](img/code_search_git_blame_v14_9.png)
### SHA search
@@ -307,7 +308,7 @@ GitLab instance.
## Search settings
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/292941) in GitLab 13.8 [with a flag](../../administration/feature_flags.md) named `search_settings_in_page`. Disabled by default.
-> - [Added to Group, Administrator, and User settings](https://gitlab.com/groups/gitlab-org/-/epics/4842) in GitLab 13.9.
+> - [Added](https://gitlab.com/groups/gitlab-org/-/epics/4842) to Group, Administrator, and User settings in GitLab 13.9.
> - [Feature flag `search_settings_in_page` removed](https://gitlab.com/gitlab-org/gitlab/-/issues/294025) in GitLab 13.11.
> - [Generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/294025) in GitLab 13.11.
diff --git a/doc/user/shortcuts.md b/doc/user/shortcuts.md
index ebaa5da8e05..e807f251da1 100644
--- a/doc/user/shortcuts.md
+++ b/doc/user/shortcuts.md
@@ -17,10 +17,6 @@ following methods:
- Press <kbd>?</kbd>.
- In the Help menu in the top right of the application, select **Keyboard shortcuts**.
-In [GitLab 12.8 and later](https://gitlab.com/gitlab-org/gitlab/-/issues/22113),
-you can disable keyboard shortcuts by using the **Keyboard shortcuts** toggle
-at the top of the keyboard shortcut window.
-
Although [global shortcuts](#global-shortcuts) work from any area of GitLab,
you must be in specific pages for the other shortcuts to be available, as
explained in each section.
@@ -41,21 +37,22 @@ These shortcuts are available in most areas of GitLab:
| <kbd>Shift</kbd> + <kbd>i</kbd> | Go to your Issues page. |
| <kbd>Shift</kbd> + <kbd>m</kbd> | Go to your [Merge requests](project/merge_requests/index.md) page. |
| <kbd>Shift</kbd> + <kbd>t</kbd> | Go to your To-Do List page. |
-| <kbd>p</kbd> + <kbd>b</kbd> | Show or hide the Performance Bar. |
-| <kbd>g</kbd> + <kbd>x</kbd> | Toggle between [GitLab](https://gitlab.com/) and [GitLab Next](https://next.gitlab.com/) (GitLab SaaS only). |
-| <kbd>.</kbd> | Open the [Web IDE](project/web_ide/index.md). |
+| <kbd>p</kbd> then <kbd>b</kbd> | Show or hide the Performance Bar. |
+| <kbd>g</kbd> then <kbd>x</kbd> | Toggle between [GitLab](https://gitlab.com/) and [GitLab Next](https://next.gitlab.com/) (GitLab SaaS only). |
+| <kbd>.</kbd> | Open the [Web IDE](project/web_ide/index.md). |
Additionally, the following shortcuts are available when editing text in text
fields (for example, comments, replies, issue descriptions, and merge request
descriptions):
-| Keyboard shortcut | Description |
-|---------------------------------------------------------------------------|-------------|
-| <kbd>↑</kbd> | Edit your last comment. You must be in a blank text field below a thread, and you must already have at least one comment in the thread. |
-| <kbd>⌘</kbd> (Mac) / <kbd>Control</kbd> + <kbd>Shift</kbd> + <kbd>p</kbd> | Toggle Markdown preview when editing text in a text field that has **Write** and **Preview** tabs at the top. |
-| <kbd>⌘</kbd> (Mac) / <kbd>Control</kbd> + <kbd>b</kbd> | Bold the selected text (surround it with `**`). |
-| <kbd>⌘</kbd> (Mac) / <kbd>Control</kbd> + <kbd>i</kbd> | Italicize the selected text (surround it with `_`). |
-| <kbd>⌘</kbd> (Mac) / <kbd>Control</kbd> + <kbd>k</kbd> | Add a link (surround the selected text with `[]()`). |
+| macOS shortcut | Windows shortcut | Description |
+|----------------|------------------|-------------|
+| <kbd>↑</kbd> | <kbd>↑</kbd> | Edit your last comment. You must be in a blank text field below a thread, and you must already have at least one comment in the thread. |
+| <kbd>Command</kbd> + <kbd>Shift</kbd> + <kbd>p</kbd> | <kbd>Control</kbd> + <kbd>Shift</kbd> + <kbd>p</kbd> | Toggle Markdown preview when editing text in a text field that has **Write** and **Preview** tabs at the top. |
+| <kbd>Command</kbd> + <kbd>b</kbd> | <kbd>Control</kbd> + <kbd>b</kbd> | Bold the selected text (surround it with `**`). |
+| <kbd>Command</kbd> + <kbd>i</kbd> | <kbd>Control</kbd> + <kbd>i</kbd> | Italicize the selected text (surround it with `_`). |
+| <kbd>Command</kbd> + <kbd>Shift</kbd> + <kbd>s</kbd> | <kbd>Control</kbd> + <kbd>Shift</kbd> + <kbd>s</kbd> | Strike through the selected text (surround it with `~~`). |
+| <kbd>Command</kbd> + <kbd>k</kbd> | <kbd>Control</kbd> + <kbd>k</kbd> | Add a link (surround the selected text with `[]()`). |
The shortcuts for editing in text fields are always enabled, even if other
keyboard shortcuts are disabled.
@@ -102,7 +99,7 @@ These shortcuts are available when viewing issues and [merge requests](project/m
| <kbd>]</kbd> or <kbd>j</kbd> | Move to next file (merge requests only). |
| <kbd>[</kbd> or <kbd>k</kbd> | Move to previous file (merge requests only). |
| <kbd>b</kbd> | Copy source branch name (merge requests only). |
-| <kbd>.</kbd> | Open the [Web IDE](project/web_ide/index.md). |
+| <kbd>.</kbd> | Open the [Web IDE](project/web_ide/index.md). |
### Project files
@@ -113,7 +110,7 @@ These shortcuts are available when browsing the files in a project (go to
|-------------------|-------------|
| <kbd>↑</kbd> | Move selection up. |
| <kbd>↓</kbd> | Move selection down. |
-| <kbd>enter</kbd> | Open selection. |
+| <kbd>Enter</kbd> | Open selection. |
| <kbd>Escape</kbd> | Go back to file list screen (only while searching for files, **Repository > Files**, then select **Find File**). |
| <kbd>y</kbd> | Go to file permalink (only while viewing a file). |
| <kbd>.</kbd> | Open the [Web IDE](project/web_ide/index.md). |
@@ -122,15 +119,15 @@ These shortcuts are available when browsing the files in a project (go to
These shortcuts are available when editing a file with the [Web IDE](project/web_ide/index.md):
-| Keyboard shortcut | Description |
-|------------------------------------------------------------|-------------|
-| <kbd>⌘</kbd> (Mac) / <kbd>Control</kbd> + <kbd>p</kbd> | Search for, and then open another file for editing. |
-| <kbd>⌘</kbd> (Mac) / <kbd>Control</kbd> + <kbd>Enter</kbd> | Commit (when editing the commit message). |
+| macOS shortcut | Windows shortcut | Description |
+|---------------------------------|---------------------|-------------|
+| <kbd>Command</kbd> + <kbd>p</kbd> | <kbd>Control</kbd> + <kbd>p</kbd> | Search for, and then open another file for editing. |
+| <kbd>Command</kbd> + <kbd>Enter</kbd> | <kbd>Control</kbd> + <kbd>Enter</kbd> | Commit (when editing the commit message). |
### Repository graph
These shortcuts are available when viewing the project [repository graph](project/repository/index.md#repository-history-graph)
-page (navigate to **Repository > Graph**):
+page (go to **Repository > Graph**):
| Keyboard shortcut | Description |
|--------------------------------------------------------------------|-------------|
@@ -151,63 +148,64 @@ This shortcut is available when viewing a [wiki page](project/wiki/index.md):
### Content editor
-These shortcuts are available when editing a file with the [Content Editor](https://about.gitlab.com/direction/create/editor/content_editor/):
+These shortcuts are available when editing a file with the
+[Content Editor](https://about.gitlab.com/direction/create/editor/content_editor/):
-| Keyboard shortcut | Description |
-|-------------------|-------------|
-| <kbd>⌘</kbd> + <kbd>C</kbd> (Mac) / <kbd>Control</kbd> + <kbd>C</kbd> | Copy |
-| <kbd>⌘</kbd> + <kbd>X</kbd> (Mac) / <kbd>Control</kbd> + <kbd>X</kbd> | Cut |
-| <kbd>⌘</kbd> + <kbd>V</kbd> (Mac) / <kbd>Control</kbd> + <kbd>V</kbd> | Paste |
-| <kbd>⌘</kbd> + <kbd>Shift</kbd> + <kbd>V</kbd> (Mac) / <kbd>Control</kbd> + <kbd>Shift</kbd> + <kbd>V</kbd> | Paste without formatting |
-| <kbd>⌘</kbd> + <kbd>Z</kbd> (Mac) / <kbd>Control</kbd> + <kbd>Z</kbd> | Undo |
-| <kbd>⌘</kbd> + <kbd>Shift</kbd> + <kbd>V</kbd> (Mac) / <kbd>Control</kbd> + <kbd>Shift</kbd> + <kbd>V</kbd> | Redo |
-| <kbd>Shift</kbd> + <kbd>Enter</kbd> | Add a line break |
+| macOS shortcut | Windows shortcut | Description |
+|----------------|------------------|-------------|
+| <kbd>Command</kbd> + <kbd>C</kbd> | <kbd>Control</kbd> + <kbd>C</kbd> | Copy |
+| <kbd>Command</kbd> + <kbd>X</kbd> | <kbd>Control</kbd> + <kbd>X</kbd> | Cut |
+| <kbd>Command</kbd> + <kbd>V</kbd> | <kbd>Control</kbd> + <kbd>V</kbd> | Paste |
+| <kbd>Command</kbd> + <kbd>Shift</kbd> + <kbd>V</kbd> | <kbd>Control</kbd> + <kbd>Shift</kbd> + <kbd>V</kbd> | Paste without formatting |
+| <kbd>Command</kbd> + <kbd>Z</kbd> | <kbd>Control</kbd> + <kbd>Z</kbd> | Undo |
+| <kbd>Command</kbd> + <kbd>Shift</kbd> + <kbd>V</kbd> | <kbd>Control</kbd> + <kbd>Shift</kbd> + <kbd>V</kbd> | Redo |
+| <kbd>Shift</kbd> + <kbd>Enter</kbd> | <kbd>Shift</kbd> + <kbd>Enter</kbd> | Add a line break |
#### Formatting
-| Mac | Windows/Linux | Description |
-|-----|---------------|-------------|
-| <kbd>⌘</kbd> + <kbd>b</kbd> | <kbd>Control</kbd> + <kbd>b</kbd> | Bold |
-| <kbd>⌘</kbd> + <kbd>i</kbd> | <kbd>Control</kbd> + <kbd>i</kbd> | Italic |
-| <kbd>⌘</kbd> + <kbd>Shift</kbd> + <kbd>s</kbd> | <kbd>Control</kbd> + <kbd>Shift</kbd> + <kbd>s</kbd> | Strikethrough |
-| <kbd>⌘</kbd> + <kbd>e</kbd> | <kbd>Control</kbd> + <kbd>e</kbd> | Code |
-| <kbd>⌘</kbd> + <kbd>Alt</kbd> + <kbd>0</kbd> | <kbd>Control</kbd> + <kbd>Alt</kbd> + <kbd>0</kbd> | Apply normal text style |
-| <kbd>⌘</kbd> + <kbd>Alt</kbd> + <kbd>1</kbd> | <kbd>Control</kbd> + <kbd>Alt</kbd> + <kbd>1</kbd> | Apply heading style 1 |
-| <kbd>⌘</kbd> + <kbd>Alt</kbd> + <kbd>2</kbd> | <kbd>Control</kbd> + <kbd>Alt</kbd> + <kbd>2</kbd> | Apply heading style 2 |
-| <kbd>⌘</kbd> + <kbd>Alt</kbd> + <kbd>3</kbd> | <kbd>Control</kbd> + <kbd>Alt</kbd> + <kbd>3</kbd> | Apply heading style 3 |
-| <kbd>⌘</kbd> + <kbd>Alt</kbd> + <kbd>4</kbd> | <kbd>Control</kbd> + <kbd>Alt</kbd> + <kbd>4</kbd> | Apply heading style 4 |
-| <kbd>⌘</kbd> + <kbd>Alt</kbd> + <kbd>5</kbd> | <kbd>Control</kbd> + <kbd>Alt</kbd> + <kbd>5</kbd> | Apply heading style 5 |
-| <kbd>⌘</kbd> + <kbd>Alt</kbd> + <kbd>6</kbd> | <kbd>Control</kbd> + <kbd>Alt</kbd> + <kbd>6</kbd> | Apply heading style 6 |
-| <kbd>⌘</kbd> + <kbd>Shift</kbd> + <kbd>7</kbd> | <kbd>Control</kbd> + <kbd>Shift</kbd> + <kbd>7</kbd> | Ordered list |
-| <kbd>⌘</kbd> + <kbd>Shift</kbd> + <kbd>8</kbd> | <kbd>Control</kbd> + <kbd>Shift</kbd> + <kbd>7</kbd> | Bullet list |
-| <kbd>⌘</kbd> + <kbd>Shift</kbd> + <kbd>9</kbd> | <kbd>Control</kbd> + <kbd>Shift</kbd> + <kbd>7</kbd> | Task list |
-| <kbd>⌘</kbd> + <kbd>Shift</kbd> + <kbd>b</kbd> | <kbd>Control</kbd> + <kbd>Shift</kbd> + <kbd>b</kbd> | Blockquote |
-| <kbd>⌘</kbd> + <kbd>Alt</kbd> + <kbd>c</kbd> | <kbd>Control</kbd> + <kbd>Shift</kbd> + <kbd>c</kbd> | Code block |
-| <kbd>⌘</kbd> + <kbd>,</kbd> | <kbd>Control</kbd> + <kbd>,</kbd> | Subscript |
-| <kbd>⌘</kbd> + <kbd>.</kbd> | <kbd>Control</kbd> + <kbd>,</kbd> | Superscript |
-| <kbd>Tab</kbd> | | Indent list |
-| <kbd>Shift</kbd> + <kbd>Tab</kbd> | | Outdent list |
+| macOS shortcut | Windows/Linux shortcut | Description |
+|----------------|------------------------|-------------|
+| <kbd>Command</kbd> + <kbd>b</kbd> | <kbd>Control</kbd> + <kbd>b</kbd> | Bold |
+| <kbd>Command</kbd> + <kbd>i</kbd> | <kbd>Control</kbd> + <kbd>i</kbd> | Italic |
+| <kbd>Command</kbd> + <kbd>Shift</kbd> + <kbd>x</kbd> | <kbd>Control</kbd> + <kbd>Shift</kbd> + <kbd>x</kbd> | Strikethrough |
+| <kbd>Command</kbd> + <kbd>e</kbd> | <kbd>Control</kbd> + <kbd>e</kbd> | Code |
+| <kbd>Command</kbd> + <kbd>Alt</kbd> + <kbd>0</kbd> | <kbd>Control</kbd> + <kbd>Alt</kbd> + <kbd>0</kbd> | Apply normal text style |
+| <kbd>Command</kbd> + <kbd>Alt</kbd> + <kbd>1</kbd> | <kbd>Control</kbd> + <kbd>Alt</kbd> + <kbd>1</kbd> | Apply heading style 1 |
+| <kbd>Command</kbd> + <kbd>Alt</kbd> + <kbd>2</kbd> | <kbd>Control</kbd> + <kbd>Alt</kbd> + <kbd>2</kbd> | Apply heading style 2 |
+| <kbd>Command</kbd> + <kbd>Alt</kbd> + <kbd>3</kbd> | <kbd>Control</kbd> + <kbd>Alt</kbd> + <kbd>3</kbd> | Apply heading style 3 |
+| <kbd>Command</kbd> + <kbd>Alt</kbd> + <kbd>4</kbd> | <kbd>Control</kbd> + <kbd>Alt</kbd> + <kbd>4</kbd> | Apply heading style 4 |
+| <kbd>Command</kbd> + <kbd>Alt</kbd> + <kbd>5</kbd> | <kbd>Control</kbd> + <kbd>Alt</kbd> + <kbd>5</kbd> | Apply heading style 5 |
+| <kbd>Command</kbd> + <kbd>Alt</kbd> + <kbd>6</kbd> | <kbd>Control</kbd> + <kbd>Alt</kbd> + <kbd>6</kbd> | Apply heading style 6 |
+| <kbd>Command</kbd> + <kbd>Shift</kbd> + <kbd>7</kbd> | <kbd>Control</kbd> + <kbd>Shift</kbd> + <kbd>7</kbd> | Ordered list |
+| <kbd>Command</kbd> + <kbd>Shift</kbd> + <kbd>8</kbd> | <kbd>Control</kbd> + <kbd>Shift</kbd> + <kbd>8</kbd> | Bullet list |
+| <kbd>Command</kbd> + <kbd>Shift</kbd> + <kbd>9</kbd> | <kbd>Control</kbd> + <kbd>Shift</kbd> + <kbd>9</kbd> | Task list |
+| <kbd>Command</kbd> + <kbd>Shift</kbd> + <kbd>b</kbd> | <kbd>Control</kbd> + <kbd>Shift</kbd> + <kbd>b</kbd> | Blockquote |
+| <kbd>Command</kbd> + <kbd>Alt</kbd> + <kbd>c</kbd> | <kbd>Control</kbd> + <kbd>Shift</kbd> + <kbd>c</kbd> | Code block |
+| <kbd>Command</kbd> + <kbd>,</kbd> | <kbd>Control</kbd> + <kbd>,</kbd> | Subscript |
+| <kbd>Command</kbd> + <kbd>.</kbd> | <kbd>Control</kbd> + <kbd>.</kbd> | Superscript |
+| <kbd>Tab</kbd> | <kbd>Tab</kbd> | Indent list |
+| <kbd>Shift</kbd> + <kbd>Tab</kbd> | <kbd>Shift</kbd> + <kbd>Tab</kbd> | Outdent list |
#### Text selection
-| Keyboard shortcut | Description |
-|-------------------|-------------|
-| <kbd>⌘</kbd> + <kbd>a</kbd> (Mac) / <kbd>Control</kbd> + <kbd>a</kbd> | Select all |
-| <kbd>Shift</kbd> + <kbd>â†</kbd> | Extend selection one character to left |
-| <kbd>Shift</kbd> + <kbd>→</kbd> | Extend selection one character to right |
-| <kbd>Shift</kbd> + <kbd>↑</kbd> | Extend selection one line up |
-| <kbd>Shift</kbd> + <kbd>↓</kbd> | Extend selection one line down |
-| <kbd>⌘</kbd> + <kbd>Shift</kbd> + <kbd>↑</kbd> (Mac) / <kbd>Control</kbd> + <kbd>Shift</kbd> + <kbd>↑</kbd> | Extend selection to the beginning of the document |
-| <kbd>⌘</kbd> + <kbd>Shift</kbd> + <kbd>↓</kbd> (Mac) / <kbd>Control</kbd> + <kbd>Shift</kbd> + <kbd>↓</kbd> | Extend selection to the end of the document |
+| macOS shortcut | Windows shortcut | Description |
+|----------------|------------------|-------------|
+| <kbd>Command</kbd> + <kbd>a</kbd> | <kbd>Control</kbd> + <kbd>a</kbd> | Select all |
+| <kbd>Shift</kbd> + <kbd>â†</kbd> | <kbd>Shift</kbd> + <kbd>â†</kbd> | Extend selection one character to left |
+| <kbd>Shift</kbd> + <kbd>→</kbd> | <kbd>Shift</kbd> + <kbd>→</kbd> | Extend selection one character to right |
+| <kbd>Shift</kbd> + <kbd>↑</kbd> | <kbd>Shift</kbd> + <kbd>↑</kbd> | Extend selection one line up |
+| <kbd>Shift</kbd> + <kbd>↓</kbd> | <kbd>Shift</kbd> + <kbd>↓</kbd> | Extend selection one line down |
+| <kbd>Command</kbd> + <kbd>Shift</kbd> + <kbd>↑</kbd> | <kbd>Control</kbd> + <kbd>Shift</kbd> + <kbd>↑</kbd> | Extend selection to the beginning of the document |
+| <kbd>Command</kbd> + <kbd>Shift</kbd> + <kbd>↓</kbd> | <kbd>Control</kbd> + <kbd>Shift</kbd> + <kbd>↓</kbd> | Extend selection to the end of the document |
### Filtered search
These shortcuts are available when using a [filtered search input](search/index.md):
-| Keyboard shortcut | Description |
-|--------------------------------------------------------|-------------|
-| <kbd>⌘</kbd> (Mac) + <kbd>⌫</kbd> | Clear entire search filter. |
-| <kbd>⌥</kbd> (Mac) / <kbd>Control</kbd> + <kbd>⌫</kbd> | Clear one token at a time. |
+| macOS shortcut | Windows shortcut | Description |
+|----------------------|----------------------------------------|-------------|
+| <kbd>Command</kbd> | <kbd>Delete</kbd> | Clear entire search filter. |
+| <kbd>Option</kbd> | <kbd>Control</kbd> + <kbd>Delete</kbd> | Clear one token at a time. |
## Epics **(PREMIUM)**
@@ -218,3 +216,13 @@ These shortcuts are available when viewing [epics](group/epics/index.md):
| <kbd>r</kbd> | Start writing a comment. Pre-selected text is quoted in the comment. Can't be used to reply in a thread. |
| <kbd>e</kbd> | Edit description. |
| <kbd>l</kbd> | Change label. |
+
+## Disable keyboard shortcuts
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/22113) in GitLab 12.8.
+
+To disable keyboard shortcuts:
+
+1. While viewing a page that supports keyboard shortcuts, and outside a text box,
+press <kbd>?</kbd> to display the list of shortcuts.
+1. Select **Toggle shortcuts**.
diff --git a/doc/user/snippets.md b/doc/user/snippets.md
index dc3ab35067e..1750e2c8d10 100644
--- a/doc/user/snippets.md
+++ b/doc/user/snippets.md
@@ -33,20 +33,18 @@ You can create snippets in multiple ways, depending on whether you want to creat
1. Select the kind of snippet you want to create:
- **To create a personal snippet**: On the
- [Snippets dashboard](https://gitlab.com/dashboard/snippets), click
+ [Snippets dashboard](https://gitlab.com/dashboard/snippets), select
**New snippet**, or:
- *If you're on a project's page,* select the plus icon (**{plus-square-o}**)
in the top navigation bar, and then select **New snippet** from the
- **GitLab** (GitLab SaaS) or **Your Instance** (self-managed) section
- of the same dropdown menu.
+ **GitLab** section of the same dropdown list.
- *For all other pages,* select the plus icon (**{plus-square-o}**)
- in the top navigation bar, then select **New snippet** from the dropdown
- menu.
+ in the top navigation bar, then select **New snippet** from the dropdown list.
- If you installed the [GitLab Workflow VS Code extension](project/repository/vscode.md),
use the [`Gitlab: Create snippet` command](https://marketplace.visualstudio.com/items?itemName=GitLab.gitlab-workflow#create-snippet).
- **To create a project snippet**: Go to your project's page. Select the
plus icon (**{plus-square-o}**), and then select **New snippet** from the
- **This project** section of the dropdown menu.
+ **This project** section of the dropdown list.
1. Add a **Title** and **Description**.
1. Name your **File** with an appropriate extension, such as `example.rb` or `index.html`.
Filenames with appropriate extensions display [syntax highlighting](#filenames).
@@ -154,15 +152,14 @@ To delete a file from your snippet through the GitLab UI:
1. Go to your snippet in the GitLab UI.
1. Select **Edit** in the top right corner.
-1. Select **Delete file** alongside the filename of each file
-you wish to delete.
+1. Select **Delete file** alongside the filename of each file you wish to delete.
1. Select **Save changes**.
## Clone snippets
Instead of copying a snippet to a local file, you may want to clone a snippet to
preserve its relationship with the repository, so you can receive or make updates
-as needed. Select the **Clone** button on a snippet to display the URLs to clone with SSH or HTTPS:
+as needed. Select **Clone** on a snippet to display the URLs to clone with SSH or HTTPS:
![Clone snippet](img/snippet_clone_button_v13_0.png)
@@ -202,7 +199,7 @@ For example:
## Download snippets
You can download the raw content of a snippet. By default, they download with Linux-style line endings (`LF`). If
-you want to preserve the original line endings you need to add a parameter `line_ending=raw`
+you want to preserve the original line endings you must add a parameter `line_ending=raw`
(For example: `https://gitlab.com/snippets/SNIPPET_ID/raw?line_ending=raw`). In case a
snippet was created using the GitLab web interface the original line ending is Windows-like (`CRLF`).
diff --git a/doc/user/tasks.md b/doc/user/tasks.md
index 5fde64e3578..8be7fbca213 100644
--- a/doc/user/tasks.md
+++ b/doc/user/tasks.md
@@ -9,7 +9,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/334812) in GitLab 14.5 [with a flag](../administration/feature_flags.md) named `work_items`. Disabled by default.
WARNING:
-Tasks are in **Alpha**. Current implementation does not have any API requests and works with mocked data.
+Tasks are in [**Alpha**](../policy/alpha-beta-support.md#alpha-features). Current implementation does not have any API requests and works with mocked data.
For the latest updates, check the [Tasks Roadmap](https://gitlab.com/groups/gitlab-org/-/epics/7103).
FLAG:
diff --git a/doc/user/todos.md b/doc/user/todos.md
index 2486db813ff..ec316d8ebe4 100644
--- a/doc/user/todos.md
+++ b/doc/user/todos.md
@@ -45,9 +45,30 @@ A to-do item is added to your To-Do List when:
When several actions occur for the same user on the same object,
GitLab displays the first action as a single to-do item.
+To change this behavior, enable
+[multiple to-do items per object](#multiple-to-do-items-per-object).
To-do items aren't affected by [GitLab notification email settings](profile/notifications.md).
+### Multiple to-do items per object **(FREE SELF)**
+
+<!-- When the feature flag is removed, integrate this topic into the one above. -->
+
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/28355) in GitLab 13.8 [with a flag](../administration/feature_flags.md) named `multiple_todos`. Disabled by default.
+> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/82470) in GitLab 14.9: only mentions create multiple to-do items.
+
+FLAG:
+On self-managed GitLab, by default this feature is not available. To make it available per user,
+ask an administrator to [enable the feature flag](../administration/feature_flags.md) named `multiple_todos`.
+On GitLab.com, this feature is not available.
+The feature is not ready for production use.
+
+When you enable this feature:
+
+- Every time you're mentioned, GitLab creates a new to-do item for you.
+- Other [actions that create to-do items](#actions-that-create-to-do-items)
+ create one to-do item per action type on the issue, MR, and so on.
+
## Create a to-do item
You can manually add an item to your To-Do List.
@@ -73,9 +94,7 @@ For example, in the following comment:
- @carol can you please have a look?
->>>
-@dan what do you think?
->>>
+> @dan what do you think?
@erin @frank thank you!
```
diff --git a/doc/user/usage_quotas.md b/doc/user/usage_quotas.md
index 75d10084328..84a2449f481 100644
--- a/doc/user/usage_quotas.md
+++ b/doc/user/usage_quotas.md
@@ -2,7 +2,7 @@
type: howto
stage: Fulfillment
group: Utilization
-info: To determine the 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/#assignments
---
# Storage usage quota **(FREE)**
@@ -10,6 +10,9 @@ info: To determine the technical writer assigned to the Stage/Group associated w
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/13294) in GitLab 12.0.
> - Moved to GitLab Free.
+NOTE:
+Free tier namespaces on GitLab SaaS have a 5GB storage limit. This limit is not visible on the storage quota page nor currently enforced for users who exceed the limit. To learn more, visit our [pricing page](https://about.gitlab.com/pricing/).
+
A project's repository has a free storage quota of 10 GB. When a project's repository reaches
the quota it is locked. You cannot push changes to a locked project. To monitor the size of each
repository in a namespace, including a breakdown for each project, you can
@@ -39,7 +42,7 @@ namespace to recalculate the storage.
> - Enabled on self-managed in GitLab 14.5.
> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/71270) in GitLab 14.5.
-The following storage usage statistics are available to an owner:
+The following storage usage statistics are available to a maintainer:
- Total namespace storage used: Total amount of storage used across projects in this namespace.
- Total excess storage used: Total amount of storage used that exceeds their allocated storage.
diff --git a/doc/user/workspace/index.md b/doc/user/workspace/index.md
index 0befcbe25d2..0ef3eb8b6fe 100644
--- a/doc/user/workspace/index.md
+++ b/doc/user/workspace/index.md
@@ -39,4 +39,4 @@ For a video introduction to the new hierarchy concept for groups and projects fo
## Related topics
-- [Workspaces developer documentation](../../development/workspaces/index.md)
+- [Workspace developer documentation](../../development/workspace/index.md)
diff --git a/docker/README.md b/docker/README.md
deleted file mode 100644
index cb6f99a6482..00000000000
--- a/docker/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# GitLab Docker images
-
-This content has been moved to [our documentation site](https://docs.gitlab.com/ee/install/docker.html).
diff --git a/fixtures/emojis/aliases.json b/fixtures/emojis/aliases.json
index c054e5e9f43..3d2894c1e00 100644
--- a/fixtures/emojis/aliases.json
+++ b/fixtures/emojis/aliases.json
@@ -1,6 +1,4 @@
{
- ":) ":"smile",
- ":( ":"disappointed",
"small_airplane":"airplane_small",
"right_anger_bubble":"anger_right",
"keycap_asterisk":"asterisk",
@@ -54,6 +52,7 @@
"passenger_ship":"cruise_ship",
"dagger_knife":"dagger",
"desktop_computer":"desktop",
+ ":( ":"disappointed",
"card_index_dividers":"dividers",
"dove_of_peace":"dove",
"drool":"drooling_face",
@@ -488,6 +487,7 @@
"skull_and_crossbones":"skull_crossbones",
"slightly_frowning_face":"slight_frown",
"slightly_smiling_face":"slight_smile",
+ ":) ":"smile",
"sneeze":"sneezing_face",
"speaking_head_in_silhouette":"speaking_head",
"left_speech_bubble":"speech_left",
diff --git a/jest.config.base.js b/jest.config.base.js
index f2a7422303d..0eab5caffb0 100644
--- a/jest.config.base.js
+++ b/jest.config.base.js
@@ -130,7 +130,7 @@ module.exports = (path, options = {}) => {
'^.+\\.(md|zip|png)$': 'jest-raw-loader',
},
transformIgnorePatterns: [
- 'node_modules/(?!(@gitlab/ui|@gitlab/favicon-overlay|bootstrap-vue|three|monaco-editor|monaco-yaml|fast-mersenne-twister|prosemirror-markdown|dateformat)/)',
+ 'node_modules/(?!(@gitlab/ui|@gitlab/favicon-overlay|bootstrap-vue|three|monaco-editor|monaco-yaml|fast-mersenne-twister|prosemirror-markdown|dateformat|lowlight|fault)/)',
],
timers: 'fake',
testEnvironment: '<rootDir>/spec/frontend/environment.js',
diff --git a/lefthook.yml b/lefthook.yml
index ce4aa14ea69..b21db70a385 100644
--- a/lefthook.yml
+++ b/lefthook.yml
@@ -2,7 +2,7 @@ pre-push:
parallel: true
commands:
danger:
- run: bundle exec danger dry_run
+ run: CI_PROJECT_DIR=. bundle exec danger dry_run
eslint:
tags: frontend style
files: git diff --name-only --diff-filter=d $(git merge-base origin/master HEAD)..HEAD
@@ -42,7 +42,7 @@ pre-push:
tags: documentation style
files: git diff --name-only --diff-filter=d $(git merge-base origin/master HEAD)..HEAD
glob: 'doc/*.md'
- run: if command -v vale 2> /dev/null; then vale --config .vale.ini --minAlertLevel error {files}; else echo "Vale not found. Install Vale"; fi
+ run: 'if command -v vale > /dev/null 2>&1; then if ! vale --config .vale.ini --minAlertLevel error {files}; then echo "ERROR: Fix any linting errors and make sure you are using the latest version of Vale."; exit 1; fi; else echo "ERROR: Vale not found. For more information, see https://docs.errata.ai/vale/install."; exit 1; fi'
gettext:
skip: true # This is disabled by default. You can enable this check by adding skip: false in lefhook-local.yml https://github.com/evilmartians/lefthook/blob/master/docs/full_guide.md#skipping-commands
tags: backend frontend view haml
diff --git a/lib/api/admin/instance_clusters.rb b/lib/api/admin/instance_clusters.rb
index b724d3a38dc..4aebd9c0d40 100644
--- a/lib/api/admin/instance_clusters.rb
+++ b/lib/api/admin/instance_clusters.rb
@@ -9,6 +9,7 @@ module API
before do
authenticated_as_admin!
+ ensure_feature_enabled!
end
namespace 'admin' do
@@ -133,6 +134,10 @@ module API
def update_cluster_params
declared_params(include_missing: false).without(:cluster_id)
end
+
+ def ensure_feature_enabled!
+ not_found! unless Feature.enabled?(:certificate_based_clusters, clusterable_instance, default_enabled: :yaml, type: :ops)
+ end
end
end
end
diff --git a/lib/api/broadcast_messages.rb b/lib/api/broadcast_messages.rb
index 0762c276aad..e081265b418 100644
--- a/lib/api/broadcast_messages.rb
+++ b/lib/api/broadcast_messages.rb
@@ -36,6 +36,8 @@ module API
optional :ends_at, type: DateTime, desc: 'Ending time', default: -> { 1.hour.from_now }
optional :color, type: String, desc: 'Background color'
optional :font, type: String, desc: 'Foreground color'
+ optional :target_access_levels, type: Array[Integer], coerce_with: Validations::Types::CommaSeparatedToIntegerArray.coerce,
+ values: BroadcastMessage::ALLOWED_TARGET_ACCESS_LEVELS, desc: 'Target user roles'
optional :target_path, type: String, desc: 'Target path'
optional :broadcast_type, type: String, values: BroadcastMessage.broadcast_types.keys, desc: 'Broadcast type. Defaults to banner', default: -> { 'banner' }
optional :dismissable, type: Boolean, desc: 'Is dismissable'
@@ -76,6 +78,8 @@ module API
optional :ends_at, type: DateTime, desc: 'Ending time'
optional :color, type: String, desc: 'Background color'
optional :font, type: String, desc: 'Foreground color'
+ optional :target_access_levels, type: Array[Integer], coerce_with: Validations::Types::CommaSeparatedToIntegerArray.coerce,
+ values: BroadcastMessage::ALLOWED_TARGET_ACCESS_LEVELS, desc: 'Target user roles'
optional :target_path, type: String, desc: 'Target path'
optional :broadcast_type, type: String, values: BroadcastMessage.broadcast_types.keys, desc: 'Broadcast Type'
optional :dismissable, type: Boolean, desc: 'Is dismissable'
diff --git a/lib/api/ci/jobs.rb b/lib/api/ci/jobs.rb
index 30ce1454419..d9d0da2e4d1 100644
--- a/lib/api/ci/jobs.rb
+++ b/lib/api/ci/jobs.rb
@@ -38,7 +38,7 @@ module API
use :pagination
end
# rubocop: disable CodeReuse/ActiveRecord
- get ':id/jobs', feature_category: :continuous_integration do
+ get ':id/jobs', urgency: :low, feature_category: :continuous_integration do
authorize_read_builds!
builds = user_project.builds.order('id DESC')
@@ -55,7 +55,7 @@ module API
params do
requires :job_id, type: Integer, desc: 'The ID of a job'
end
- get ':id/jobs/:job_id', feature_category: :continuous_integration do
+ get ':id/jobs/:job_id', urgency: :low, feature_category: :continuous_integration do
authorize_read_builds!
build = find_build!(params[:job_id])
@@ -70,7 +70,7 @@ module API
params do
requires :job_id, type: Integer, desc: 'The ID of a job'
end
- get ':id/jobs/:job_id/trace', feature_category: :continuous_integration do
+ get ':id/jobs/:job_id/trace', urgency: :low, feature_category: :continuous_integration do
authorize_read_builds!
build = find_build!(params[:job_id])
@@ -92,7 +92,7 @@ module API
params do
requires :job_id, type: Integer, desc: 'The ID of a job'
end
- post ':id/jobs/:job_id/cancel', feature_category: :continuous_integration do
+ post ':id/jobs/:job_id/cancel', urgency: :low, feature_category: :continuous_integration do
authorize_update_builds!
build = find_build!(params[:job_id])
@@ -109,7 +109,7 @@ module API
params do
requires :job_id, type: Integer, desc: 'The ID of a build'
end
- post ':id/jobs/:job_id/retry', feature_category: :continuous_integration do
+ post ':id/jobs/:job_id/retry', urgency: :low, feature_category: :continuous_integration do
authorize_update_builds!
build = find_build!(params[:job_id])
@@ -127,7 +127,7 @@ module API
params do
requires :job_id, type: Integer, desc: 'The ID of a build'
end
- post ':id/jobs/:job_id/erase', feature_category: :continuous_integration do
+ post ':id/jobs/:job_id/erase', urgency: :low, feature_category: :continuous_integration do
authorize_update_builds!
build = find_build!(params[:job_id])
@@ -144,9 +144,14 @@ module API
end
params do
requires :job_id, type: Integer, desc: 'The ID of a Job'
+ optional :job_variables_attributes, type: Array,
+ desc: 'User defined variables that will be included when running the job' do
+ requires :key, type: String, desc: 'The name of the variable'
+ requires :value, type: String, desc: 'The value of the variable'
+ end
end
- post ":id/jobs/:job_id/play", feature_category: :continuous_integration do
+ post ':id/jobs/:job_id/play', urgency: :low, feature_category: :continuous_integration do
authorize_read_builds!
job = find_job!(params[:job_id])
@@ -155,7 +160,7 @@ module API
bad_request!("Unplayable Job") unless job.playable?
- job.play(current_user)
+ job.play(current_user, params[:job_variables_attributes])
status 200
@@ -168,11 +173,11 @@ module API
end
resource :job do
- desc 'Get current project using job token' do
+ desc 'Get current job using job token' do
success Entities::Ci::Job
end
route_setting :authentication, job_token_allowed: true
- get '', feature_category: :continuous_integration do
+ get '', feature_category: :continuous_integration, urgency: :low do
validate_current_authenticated_job
present current_authenticated_job, with: Entities::Ci::Job
diff --git a/lib/api/ci/pipelines.rb b/lib/api/ci/pipelines.rb
index e0086f624a8..2d7a437ca08 100644
--- a/lib/api/ci/pipelines.rb
+++ b/lib/api/ci/pipelines.rb
@@ -123,7 +123,7 @@ module API
use :pagination
end
- get ':id/pipelines/:pipeline_id/jobs', feature_category: :continuous_integration do
+ get ':id/pipelines/:pipeline_id/jobs', urgency: :low, feature_category: :continuous_integration do
authorize!(:read_pipeline, user_project)
pipeline = user_project.all_pipelines.find(params[:pipeline_id])
@@ -223,9 +223,13 @@ module API
post ':id/pipelines/:pipeline_id/retry', feature_category: :continuous_integration do
authorize! :update_pipeline, pipeline
- pipeline.retry_failed(current_user)
+ response = pipeline.retry_failed(current_user)
- present pipeline, with: Entities::Ci::Pipeline
+ if response.success?
+ present pipeline, with: Entities::Ci::Pipeline
+ else
+ render_api_error!(response.errors.join(', '), response.http_status)
+ end
end
desc 'Cancel all builds in the pipeline' do
diff --git a/lib/api/ci/runner.rb b/lib/api/ci/runner.rb
index 4df9600322c..0e3b295396b 100644
--- a/lib/api/ci/runner.rb
+++ b/lib/api/ci/runner.rb
@@ -38,7 +38,7 @@ module API
attributes[:maintenance_note] ||= deprecated_note if deprecated_note
attributes[:active] = !attributes.delete(:paused) if attributes.include?(:paused)
- @runner = ::Ci::RegisterRunnerService.new.execute(params[:token], attributes)
+ @runner = ::Ci::Runners::RegisterRunnerService.new.execute(params[:token], attributes)
forbidden! unless @runner
if @runner.persisted?
@@ -57,7 +57,7 @@ module API
delete '/', feature_category: :runner do
authenticate_runner!
- destroy_conditionally!(current_runner) { ::Ci::UnregisterRunnerService.new(current_runner).execute }
+ destroy_conditionally!(current_runner) { ::Ci::Runners::UnregisterRunnerService.new(current_runner, params[:token]).execute }
end
desc 'Validates authentication credentials' do
@@ -71,6 +71,19 @@ module API
status 200
body "200"
end
+
+ desc 'Reset runner authentication token with current token' do
+ success Entities::Ci::ResetTokenResult
+ end
+ params do
+ requires :token, type: String, desc: 'The current authentication token of the runner'
+ end
+ post '/reset_authentication_token', feature_category: :runner do
+ authenticate_runner!
+
+ current_runner.reset_token!
+ present current_runner.token_with_expiration, with: Entities::Ci::ResetTokenResult
+ end
end
resource :jobs do
@@ -118,7 +131,7 @@ module API
formatter :build_json, ->(object, _) { object }
parser :build_json, ::Grape::Parser::Json
- post '/request', feature_category: :continuous_integration do
+ post '/request', urgency: :low, feature_category: :continuous_integration do
authenticate_runner!
unless current_runner.active?
@@ -172,7 +185,7 @@ module API
end
optional :exit_code, type: Integer, desc: %q(Job's exit code)
end
- put '/:id', feature_category: :continuous_integration do
+ put '/:id', urgency: :low, feature_category: :continuous_integration do
job = authenticate_job!(heartbeat_runner: true)
Gitlab::Metrics.add_event(:update_build)
@@ -199,7 +212,7 @@ module API
requires :id, type: Integer, desc: %q(Job's ID)
optional :token, type: String, desc: %q(Job's authentication token)
end
- patch '/:id/trace', feature_category: :continuous_integration do
+ patch '/:id/trace', urgency: :default, feature_category: :continuous_integration do
job = authenticate_job!(heartbeat_runner: true)
error!('400 Missing header Content-Range', 400) unless request.headers.key?('Content-Range')
diff --git a/lib/api/ci/runners.rb b/lib/api/ci/runners.rb
index 8a7ffab97dd..3c9e887e751 100644
--- a/lib/api/ci/runners.rb
+++ b/lib/api/ci/runners.rb
@@ -90,7 +90,7 @@ module API
runner = get_runner(params.delete(:id))
authenticate_update_runner!(runner)
params[:active] = !params.delete(:paused) if params.include?(:paused)
- update_service = ::Ci::UpdateRunnerService.new(runner)
+ update_service = ::Ci::Runners::UpdateRunnerService.new(runner)
if update_service.update(declared_params(include_missing: false))
present runner, with: Entities::Ci::RunnerDetails, current_user: current_user
@@ -110,7 +110,7 @@ module API
authenticate_delete_runner!(runner)
- destroy_conditionally!(runner) { ::Ci::UnregisterRunnerService.new(runner).execute }
+ destroy_conditionally!(runner) { ::Ci::Runners::UnregisterRunnerService.new(runner, current_user).execute }
end
desc 'List jobs running on a runner' do
@@ -187,7 +187,7 @@ module API
runner = get_runner(params[:runner_id])
authenticate_enable_runner!(runner)
- if runner.assign_to(user_project)
+ if ::Ci::Runners::AssignRunnerService.new(runner, user_project, current_user).execute
present runner, with: Entities::Ci::Runner
else
render_validation_error!(runner)
@@ -246,9 +246,9 @@ module API
success Entities::Ci::ResetTokenResult
end
post 'reset_registration_token' do
- authorize! :update_runners_registration_token
+ authorize! :update_runners_registration_token, ApplicationSetting.current
- ApplicationSetting.current.reset_runners_registration_token!
+ ::Ci::Runners::ResetRegistrationTokenService.new(ApplicationSetting.current, current_user).execute
present ApplicationSetting.current_without_cache.runners_registration_token_with_expiration, with: Entities::Ci::ResetTokenResult
end
end
diff --git a/lib/api/ci/secure_files.rb b/lib/api/ci/secure_files.rb
index 715a8b37fae..d5b21e2ef29 100644
--- a/lib/api/ci/secure_files.rb
+++ b/lib/api/ci/secure_files.rb
@@ -7,8 +7,8 @@ module API
before do
authenticate!
- authorize! :admin_build, user_project
feature_flag_enabled?
+ authorize! :read_secure_files, user_project
end
feature_category :pipeline_authoring
@@ -52,39 +52,44 @@ module API
body secure_file.file.read
end
- desc 'Upload a Secure File'
- params do
- requires :name, type: String, desc: 'The name of the file'
- requires :file, types: [Rack::Multipart::UploadedFile, ::API::Validations::Types::WorkhorseFile], desc: 'The secure file to be uploaded'
- optional :permissions, type: String, desc: 'The file permissions', default: 'read_only', values: %w[read_only read_write execute]
- end
-
- route_setting :authentication, basic_auth_personal_access_token: true, job_token_allowed: true
- post ':id/secure_files' do
- secure_file = user_project.secure_files.new(
- name: params[:name],
- permissions: params[:permissions] || :read_only
- )
-
- secure_file.file = params[:file]
-
- file_too_large! unless secure_file.file.size < ::Ci::SecureFile::FILE_SIZE_LIMIT.to_i
+ resource do
+ before do
+ authorize! :admin_secure_files, user_project
+ end
- if secure_file.save
- present secure_file, with: Entities::Ci::SecureFile
- else
- render_validation_error!(secure_file)
+ desc 'Upload a Secure File'
+ params do
+ requires :name, type: String, desc: 'The name of the file'
+ requires :file, types: [Rack::Multipart::UploadedFile, ::API::Validations::Types::WorkhorseFile], desc: 'The secure file to be uploaded'
+ optional :permissions, type: String, desc: 'The file permissions', default: 'read_only', values: %w[read_only read_write execute]
+ end
+ route_setting :authentication, basic_auth_personal_access_token: true, job_token_allowed: true
+ post ':id/secure_files' do
+ secure_file = user_project.secure_files.new(
+ name: params[:name],
+ permissions: params[:permissions] || :read_only
+ )
+
+ secure_file.file = params[:file]
+
+ file_too_large! unless secure_file.file.size < ::Ci::SecureFile::FILE_SIZE_LIMIT.to_i
+
+ if secure_file.save
+ present secure_file, with: Entities::Ci::SecureFile
+ else
+ render_validation_error!(secure_file)
+ end
end
- end
- desc 'Delete an individual Secure File'
- route_setting :authentication, basic_auth_personal_access_token: true, job_token_allowed: true
- delete ':id/secure_files/:secure_file_id' do
- secure_file = user_project.secure_files.find(params[:secure_file_id])
+ desc 'Delete an individual Secure File'
+ route_setting :authentication, basic_auth_personal_access_token: true, job_token_allowed: true
+ delete ':id/secure_files/:secure_file_id' do
+ secure_file = user_project.secure_files.find(params[:secure_file_id])
- secure_file.destroy!
+ ::Ci::DestroySecureFileService.new(user_project, current_user).execute(secure_file)
- no_content!
+ no_content!
+ end
end
end
diff --git a/lib/api/commits.rb b/lib/api/commits.rb
index 8b8d8192524..dedda82091f 100644
--- a/lib/api/commits.rb
+++ b/lib/api/commits.rb
@@ -44,6 +44,8 @@ module API
use :pagination
end
get ':id/repository/commits', urgency: :low do
+ not_found! 'Repository' unless user_project.repository_exists?
+
path = params[:path]
before = params[:until]
after = params[:since]
diff --git a/lib/api/concerns/packages/conan_endpoints.rb b/lib/api/concerns/packages/conan_endpoints.rb
index edf20b6aebe..e241633fa8b 100644
--- a/lib/api/concerns/packages/conan_endpoints.rb
+++ b/lib/api/concerns/packages/conan_endpoints.rb
@@ -38,6 +38,10 @@ module API
helpers ::API::Helpers::Packages::Conan::ApiHelpers
helpers ::API::Helpers::RelatedResourcesHelpers
+ rescue_from ActiveRecord::RecordInvalid do |e|
+ render_api_error!(e.message, 400)
+ end
+
before do
require_packages_enabled!
@@ -285,6 +289,7 @@ module API
params do
requires :file_name, type: String, desc: 'Package file name', values: CONAN_FILES
end
+
namespace 'export/:file_name', requirements: FILE_NAME_REQUIREMENTS do
desc 'Download recipe files' do
detail 'This feature was introduced in GitLab 12.6'
diff --git a/lib/api/container_repositories.rb b/lib/api/container_repositories.rb
index 9cd3e449687..17d667fb6df 100644
--- a/lib/api/container_repositories.rb
+++ b/lib/api/container_repositories.rb
@@ -23,11 +23,17 @@ module API
params do
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'
+ optional :size, type: Boolean, default: false, desc: 'Determines if the size should be included'
end
get ':id' do
authorize!(:read_container_image, repository)
- present repository, with: Entities::ContainerRegistry::Repository, tags: params[:tags], tags_count: params[:tags_count], user: current_user
+ present repository,
+ with: Entities::ContainerRegistry::Repository,
+ tags: params[:tags],
+ tags_count: params[:tags_count],
+ size: params[:size],
+ user: current_user
end
end
end
diff --git a/lib/api/deploy_tokens.rb b/lib/api/deploy_tokens.rb
index e9beeb18d62..074c307e881 100644
--- a/lib/api/deploy_tokens.rb
+++ b/lib/api/deploy_tokens.rb
@@ -93,6 +93,21 @@ module API
end
end
+ desc 'Get a project deploy token' do
+ detail 'This feature was introduced in GitLab 14.9'
+ success Entities::DeployToken
+ end
+ params do
+ requires :token_id, type: Integer, desc: 'The deploy token ID'
+ end
+ get ':id/deploy_tokens/:token_id' do
+ authorize!(:read_deploy_token, user_project)
+
+ deploy_token = user_project.deploy_tokens.find(params[:token_id])
+
+ present deploy_token, with: Entities::DeployToken
+ end
+
desc 'Delete a project deploy token' do
detail 'This feature was introduced in GitLab 12.9'
end
@@ -159,6 +174,21 @@ module API
end
end
+ desc 'Get a group deploy token' do
+ detail 'This feature was introduced in GitLab 14.9'
+ success Entities::DeployToken
+ end
+ params do
+ requires :token_id, type: Integer, desc: 'The deploy token ID'
+ end
+ get ':id/deploy_tokens/:token_id' do
+ authorize!(:read_deploy_token, user_group)
+
+ deploy_token = user_group.deploy_tokens.find(params[:token_id])
+
+ present deploy_token, with: Entities::DeployToken
+ end
+
desc 'Delete a group deploy token' do
detail 'This feature was introduced in GitLab 12.9'
end
diff --git a/lib/api/entities/broadcast_message.rb b/lib/api/entities/broadcast_message.rb
index e42b110adbe..5a31d64fd86 100644
--- a/lib/api/entities/broadcast_message.rb
+++ b/lib/api/entities/broadcast_message.rb
@@ -3,7 +3,7 @@
module API
module Entities
class BroadcastMessage < Grape::Entity
- expose :id, :message, :starts_at, :ends_at, :color, :font, :target_path, :broadcast_type, :dismissable
+ expose :id, :message, :starts_at, :ends_at, :color, :font, :target_access_levels, :target_path, :broadcast_type, :dismissable
expose :active?, as: :active
end
end
diff --git a/lib/api/entities/ci/runner.rb b/lib/api/entities/ci/runner.rb
index a6944b8c925..e29d55771f2 100644
--- a/lib/api/entities/ci/runner.rb
+++ b/lib/api/entities/ci/runner.rb
@@ -7,7 +7,7 @@ module API
expose :id
expose :description
expose :ip_address
- expose :active # TODO Remove in %15.0 in favor of `paused` for REST calls, see https://gitlab.com/gitlab-org/gitlab/-/issues/351109
+ expose :active # TODO Remove in %16.0 in favor of `paused` for REST calls, see https://gitlab.com/gitlab-org/gitlab/-/issues/351109
expose :paused do |runner|
!runner.active
end
@@ -16,7 +16,7 @@ module API
expose :name
expose :online?, as: :online
# DEPRECATED
- # TODO Remove in %15.0 in favor of `status` for REST calls, see https://gitlab.com/gitlab-org/gitlab/-/issues/344648
+ # TODO Remove in %16.0 in favor of `status` for REST calls, see https://gitlab.com/gitlab-org/gitlab/-/issues/344648
expose :deprecated_rest_status, as: :status
end
end
diff --git a/lib/api/entities/ci/secure_file.rb b/lib/api/entities/ci/secure_file.rb
index 041c864156b..b60a1a6ac90 100644
--- a/lib/api/entities/ci/secure_file.rb
+++ b/lib/api/entities/ci/secure_file.rb
@@ -9,6 +9,7 @@ module API
expose :permissions
expose :checksum
expose :checksum_algorithm
+ expose :created_at
end
end
end
diff --git a/lib/api/entities/container_registry.rb b/lib/api/entities/container_registry.rb
index c9c2c5156cc..2fdfac40c32 100644
--- a/lib/api/entities/container_registry.rb
+++ b/lib/api/entities/container_registry.rb
@@ -22,6 +22,7 @@ module API
expose :tags_count, if: -> (_, options) { options[:tags_count] }
expose :tags, using: Tag, if: -> (_, options) { options[:tags] }
expose :delete_api_path, if: ->(object, options) { Ability.allowed?(options[:user], :admin_container_image, object) }
+ expose :size, if: -> (_, options) { options[:size] }
private
diff --git a/lib/api/entities/error_tracking.rb b/lib/api/entities/error_tracking.rb
index b55cba05ea0..163bda92680 100644
--- a/lib/api/entities/error_tracking.rb
+++ b/lib/api/entities/error_tracking.rb
@@ -9,6 +9,12 @@ module API
expose :sentry_external_url
expose :api_url
expose :integrated
+
+ def integrated
+ return false unless ::Feature.enabled?(:integrated_error_tracking, object.project)
+
+ object.integrated_client?
+ end
end
class ClientKey < Grape::Entity
diff --git a/lib/api/entities/issuable_time_stats.rb b/lib/api/entities/issuable_time_stats.rb
index 7c3452a10a1..f93b4651b1f 100644
--- a/lib/api/entities/issuable_time_stats.rb
+++ b/lib/api/entities/issuable_time_stats.rb
@@ -18,7 +18,7 @@ module API
# rubocop: disable CodeReuse/ActiveRecord
def total_time_spent
# Avoids an N+1 query since timelogs are preloaded
- object.timelogs.map(&:time_spent).sum
+ object.timelogs.sum(&:time_spent)
end
# rubocop: enable CodeReuse/ActiveRecord
end
diff --git a/lib/api/entities/label_basic.rb b/lib/api/entities/label_basic.rb
index ed52688638e..7c846180558 100644
--- a/lib/api/entities/label_basic.rb
+++ b/lib/api/entities/label_basic.rb
@@ -3,7 +3,11 @@
module API
module Entities
class LabelBasic < Grape::Entity
- expose :id, :name, :color, :description, :description_html, :text_color
+ expose :id, :name, :description, :description_html, :text_color
+
+ expose :color do |label, options|
+ label.color.to_s
+ end
end
end
end
diff --git a/lib/api/entities/project.rb b/lib/api/entities/project.rb
index 74097dc2883..8f9a8add938 100644
--- a/lib/api/entities/project.rb
+++ b/lib/api/entities/project.rb
@@ -74,6 +74,7 @@ module API
expose(:operations_access_level) { |project, options| project.project_feature.string_access_level(:operations) }
expose(:analytics_access_level) { |project, options| project.project_feature.string_access_level(:analytics) }
expose(:container_registry_access_level) { |project, options| project.project_feature.string_access_level(:container_registry) }
+ expose(:security_and_compliance_access_level) { |project, options| project.project_feature.string_access_level(:security_and_compliance) }
expose :emails_disabled
expose :shared_runners_enabled
diff --git a/lib/api/entities/project_integration.rb b/lib/api/entities/project_integration.rb
index 649e4d015b8..155136d2f80 100644
--- a/lib/api/entities/project_integration.rb
+++ b/lib/api/entities/project_integration.rb
@@ -5,19 +5,8 @@ module API
class ProjectIntegration < Entities::ProjectIntegrationBasic
# Expose serialized properties
expose :properties do |integration, options|
- # TODO: Simplify as part of https://gitlab.com/gitlab-org/gitlab/issues/29404
-
- attributes =
- if integration.data_fields_present?
- integration.data_fields.as_json.keys
- else
- integration.properties.keys
- end
-
- attributes &= integration.api_field_names
-
- attributes.each_with_object({}) do |attribute, hash|
- hash[attribute] = integration.public_send(attribute) # rubocop:disable GitlabSecurity/PublicSend
+ integration.api_field_names.to_h do |name|
+ [name, integration.public_send(name)] # rubocop:disable GitlabSecurity/PublicSend
end
end
end
diff --git a/lib/api/entities/user_safe.rb b/lib/api/entities/user_safe.rb
index c7349026a88..fb99c2e960d 100644
--- a/lib/api/entities/user_safe.rb
+++ b/lib/api/entities/user_safe.rb
@@ -5,14 +5,7 @@ module API
class UserSafe < Grape::Entity
expose :id, :username
expose :name do |user|
- next user.name unless user.project_bot?
-
- next user.name if options[:current_user]&.can?(:read_project, user.projects.first)
-
- # If the requester does not have permission to read the project bot name,
- # the API returns an arbitrary string. UI changes will be addressed in a follow up issue:
- # https://gitlab.com/gitlab-org/gitlab/-/issues/346058
- '****'
+ user.redacted_name(options[:current_user])
end
end
end
diff --git a/lib/api/entities/wiki_page.rb b/lib/api/entities/wiki_page.rb
index a8ef0bd857c..43af6a336d2 100644
--- a/lib/api/entities/wiki_page.rb
+++ b/lib/api/entities/wiki_page.rb
@@ -3,7 +3,15 @@
module API
module Entities
class WikiPage < WikiPageBasic
- expose :content
+ include ::MarkupHelper
+
+ expose :content do |wiki_page, options|
+ options[:render_html] ? render_wiki_content(wiki_page, ref: wiki_page.version.id) : wiki_page.content
+ end
+
+ expose :encoding do |wiki_page|
+ wiki_page.content.encoding.name
+ end
end
end
end
diff --git a/lib/api/error_tracking/collector.rb b/lib/api/error_tracking/collector.rb
index 13fda356257..22a4e04a91c 100644
--- a/lib/api/error_tracking/collector.rb
+++ b/lib/api/error_tracking/collector.rb
@@ -28,8 +28,8 @@ module API
end
def feature_enabled?
- project.error_tracking_setting&.enabled? &&
- project.error_tracking_setting&.integrated_client?
+ Feature.enabled?(:integrated_error_tracking, project) &&
+ project.error_tracking_setting&.integrated_enabled?
end
def find_client_key(public_key)
diff --git a/lib/api/generic_packages.rb b/lib/api/generic_packages.rb
index 8cca3378eec..97230976482 100644
--- a/lib/api/generic_packages.rb
+++ b/lib/api/generic_packages.rb
@@ -14,8 +14,6 @@ module API
before do
require_packages_enabled!
authenticate_non_get!
-
- require_generic_packages_available!
end
params do
@@ -113,10 +111,6 @@ module API
include ::API::Helpers::PackagesHelpers
include ::API::Helpers::Packages::BasicAuthHelpers
- def require_generic_packages_available!
- not_found! unless Feature.enabled?(:generic_packages, project, default_enabled: true)
- end
-
def project
authorized_user_project
end
diff --git a/lib/api/group_clusters.rb b/lib/api/group_clusters.rb
index 81944a653c8..a5a60ce8741 100644
--- a/lib/api/group_clusters.rb
+++ b/lib/api/group_clusters.rb
@@ -4,7 +4,10 @@ module API
class GroupClusters < ::API::Base
include PaginationParams
- before { authenticate! }
+ before do
+ authenticate!
+ ensure_feature_enabled!
+ end
feature_category :kubernetes_management
@@ -133,6 +136,10 @@ module API
def update_cluster_params
declared_params(include_missing: false).without(:cluster_id)
end
+
+ def ensure_feature_enabled!
+ not_found! unless Feature.enabled?(:certificate_based_clusters, user_group, default_enabled: :yaml, type: :ops)
+ end
end
end
end
diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb
index 184fe7868a5..de9d42bdce7 100644
--- a/lib/api/helpers.rb
+++ b/lib/api/helpers.rb
@@ -119,7 +119,7 @@ module API
def find_project(id)
return unless id
- projects = Project.without_deleted
+ projects = Project.without_deleted.not_hidden
if id.is_a?(Integer) || id =~ /^\d+$/
projects.find_by(id: id)
@@ -474,17 +474,22 @@ module API
model.errors.messages
end
- def render_spam_error!
- render_api_error!({ error: 'Spam detected' }, 400)
+ def render_api_error!(message, status)
+ render_structured_api_error!({ 'message' => message }, status)
end
- def render_api_error!(message, status)
+ def render_structured_api_error!(hash, status)
+ # Use this method instead of `render_api_error!` when you have additional top-level
+ # hash entries in addition to 'message' which need to be passed to `#error!`
+ set_status_code_in_env(status)
+ error!(hash, status, header)
+ end
+
+ def set_status_code_in_env(status)
# grape-logging doesn't pass the status code, so this is a
# workaround for getting that information in the loggers:
# https://github.com/aserafin/grape_logging/issues/71
env[API_RESPONSE_STATUS_CODE] = Rack::Utils.status_code(status)
-
- error!({ 'message' => message }, status, header)
end
def handle_api_exception(exception)
diff --git a/lib/api/helpers/integrations_helpers.rb b/lib/api/helpers/integrations_helpers.rb
index 86dedc12fca..0fbd0e6be44 100644
--- a/lib/api/helpers/integrations_helpers.rb
+++ b/lib/api/helpers/integrations_helpers.rb
@@ -440,6 +440,32 @@ module API
},
chat_notification_events
].flatten,
+ 'harbor' => [
+ {
+ required: true,
+ name: :url,
+ type: String,
+ desc: 'The base URL to the Harbor instance which is being linked to this GitLab project. For example, https://demo.goharbor.io.'
+ },
+ {
+ required: true,
+ name: :project_name,
+ type: String,
+ desc: 'The Project name to the Harbor instance. For example, testproject.'
+ },
+ {
+ required: true,
+ name: :username,
+ type: String,
+ desc: 'The username created from Harbor interface.'
+ },
+ {
+ required: true,
+ name: :password,
+ type: String,
+ desc: 'The password of the user.'
+ }
+ ],
'irker' => [
{
required: true,
@@ -856,6 +882,7 @@ module API
::Integrations::ExternalWiki,
::Integrations::Flowdock,
::Integrations::HangoutsChat,
+ ::Integrations::Harbor,
::Integrations::Irker,
::Integrations::Jenkins,
::Integrations::Jira,
diff --git a/lib/api/helpers/projects_helpers.rb b/lib/api/helpers/projects_helpers.rb
index 00f745067e7..f1125899f8c 100644
--- a/lib/api/helpers/projects_helpers.rb
+++ b/lib/api/helpers/projects_helpers.rb
@@ -36,6 +36,7 @@ module API
optional :operations_access_level, type: String, values: %w(disabled private enabled), desc: 'Operations access level. One of `disabled`, `private` or `enabled`'
optional :analytics_access_level, type: String, values: %w(disabled private enabled), desc: 'Analytics access level. One of `disabled`, `private` or `enabled`'
optional :container_registry_access_level, type: String, values: %w(disabled private enabled), desc: 'Controls visibility of the container registry. One of `disabled`, `private` or `enabled`. `private` will make the container registry accessible only to project members (reporter role and above). `enabled` will make the container registry accessible to everyone who has access to the project. `disabled` will disable the container registry'
+ optional :security_and_compliance_access_level, type: String, values: %w(disabled private enabled), desc: 'Security and compliance access level. One of `disabled`, `private` or `enabled`'
optional :emails_disabled, type: Boolean, desc: 'Disable email notifications'
optional :show_default_award_emojis, type: Boolean, desc: 'Show default award emojis'
@@ -118,6 +119,7 @@ module API
def self.update_params_at_least_one_of
[
:allow_merge_on_skipped_pipeline,
+ :analytics_access_level,
:autoclose_referenced_issues,
:auto_devops_enabled,
:auto_devops_deploy_strategy,
@@ -145,6 +147,7 @@ module API
:name,
:only_allow_merge_if_all_discussions_are_resolved,
:only_allow_merge_if_pipeline_succeeds,
+ :operations_access_level,
:pages_access_level,
:path,
:printing_merge_request_link_enabled,
@@ -154,6 +157,7 @@ module API
:request_access_enabled,
:resolve_outdated_diff_discussions,
:restrict_user_defined_variables,
+ :security_and_compliance_access_level,
:squash_option,
:shared_runners_enabled,
:snippets_access_level,
diff --git a/lib/api/helpers/wikis_helpers.rb b/lib/api/helpers/wikis_helpers.rb
index 4a14dc1f40a..a9cd0e2919d 100644
--- a/lib/api/helpers/wikis_helpers.rb
+++ b/lib/api/helpers/wikis_helpers.rb
@@ -13,8 +13,8 @@ module API
raise "Unknown wiki container #{kind}"
end
- def wiki_page
- Wiki.for_container(container, current_user).find_page(params[:slug]) || not_found!('Wiki Page')
+ def wiki_page(version = nil)
+ Wiki.for_container(container, current_user).find_page(params[:slug], version.presence) || not_found!('Wiki Page')
end
def commit_params(attrs)
diff --git a/lib/api/internal/base.rb b/lib/api/internal/base.rb
index 48157a91477..9c527f28d44 100644
--- a/lib/api/internal/base.rb
+++ b/lib/api/internal/base.rb
@@ -92,6 +92,8 @@ module API
payload[:git_config_options] << "receive.maxInputSize=#{receive_max_input_size.megabytes}"
end
+ send_git_audit_streaming_event(protocol: params[:protocol], action: params[:action])
+
response_with_status(**payload)
when ::Gitlab::GitAccessResult::CustomAction
response_with_status(code: 300, payload: check_result.payload, gl_console_messages: check_result.console_messages)
@@ -100,6 +102,10 @@ module API
end
end
+ def send_git_audit_streaming_event(msg)
+ # Defined in EE
+ end
+
def access_check!(actor, params)
access_checker = access_checker_for(actor, params[:protocol])
access_checker.check(params[:action], params[:changes]).tap do |result|
diff --git a/lib/api/internal/kubernetes.rb b/lib/api/internal/kubernetes.rb
index 3977da4bda4..df887a83c4f 100644
--- a/lib/api/internal/kubernetes.rb
+++ b/lib/api/internal/kubernetes.rb
@@ -39,6 +39,7 @@ module API
def gitaly_repository(project)
{
+ default_branch: project.default_branch_or_main,
storage_name: project.repository_storage,
relative_path: project.disk_path + '.git',
gl_repository: repo_type.identifier_for_container(project),
diff --git a/lib/api/issues.rb b/lib/api/issues.rb
index a5d6a6d7cf3..e9bb9fe7a97 100644
--- a/lib/api/issues.rb
+++ b/lib/api/issues.rb
@@ -4,6 +4,7 @@ module API
class Issues < ::API::Base
include PaginationParams
helpers Helpers::IssuesHelpers
+ helpers SpammableActions::CaptchaCheck::RestApiActionsSupport
before { authenticate_non_get! }
@@ -262,8 +263,6 @@ module API
post ':id/issues' do
Gitlab::QueryLimiting.disable!('https://gitlab.com/gitlab-org/gitlab/-/issues/21140')
- check_rate_limit!(:issues_create, scope: current_user) if Feature.disabled?("rate_limited_service_issues_create", user_project, default_enabled: :yaml)
-
authorize! :create_issue, user_project
issue_params = declared_params(include_missing: false)
@@ -277,14 +276,12 @@ module API
params: issue_params,
spam_params: spam_params).execute
- if issue.spam?
- render_api_error!({ error: 'Spam detected' }, 400)
- end
-
if issue.valid?
present issue, with: Entities::Issue, current_user: current_user, project: user_project
else
- render_validation_error!(issue)
+ with_captcha_check_rest_api(spammable: issue) do
+ render_validation_error!(issue)
+ end
end
rescue ::ActiveRecord::RecordNotUnique
render_api_error!('Duplicated issue', 409)
@@ -322,12 +319,12 @@ module API
params: update_params,
spam_params: spam_params).execute(issue)
- render_spam_error! if issue.spam?
-
if issue.valid?
present issue, with: Entities::Issue, current_user: current_user, project: user_project
else
- render_validation_error!(issue)
+ with_captcha_check_rest_api(spammable: issue) do
+ render_validation_error!(issue)
+ end
end
end
# rubocop: enable CodeReuse/ActiveRecord
diff --git a/lib/api/merge_requests.rb b/lib/api/merge_requests.rb
index f7df8d33418..de9a2a198d9 100644
--- a/lib/api/merge_requests.rb
+++ b/lib/api/merge_requests.rb
@@ -304,10 +304,6 @@ module API
end
get ':id/merge_requests/:merge_request_iid/context_commits', feature_category: :code_review, urgency: :high do
merge_request = find_merge_request_with_access(params[:merge_request_iid])
- project = merge_request.project
-
- not_found! unless project.context_commits_enabled?
-
context_commits =
paginate(merge_request.merge_request_context_commits).map(&:to_commit)
@@ -328,9 +324,6 @@ module API
end
merge_request = find_merge_request_with_access(params[:merge_request_iid])
- project = merge_request.project
-
- not_found! unless project.context_commits_enabled?
authorize!(:update_merge_request, merge_request)
@@ -351,9 +344,6 @@ module API
delete ':id/merge_requests/:merge_request_iid/context_commits', feature_category: :code_review do
commit_ids = params[:commits]
merge_request = find_merge_request_with_access(params[:merge_request_iid])
- project = merge_request.project
-
- not_found! unless project.context_commits_enabled?
authorize!(:destroy_merge_request, merge_request)
project = merge_request.target_project
diff --git a/lib/api/notes.rb b/lib/api/notes.rb
index 93ef77d5a62..b260f5289b3 100644
--- a/lib/api/notes.rb
+++ b/lib/api/notes.rb
@@ -75,6 +75,7 @@ module API
requires :body, type: String, desc: 'The content of a note'
optional :confidential, type: Boolean, desc: 'Confidentiality note flag, default is false'
optional :created_at, type: String, desc: 'The creation date of the note'
+ optional :merge_request_diff_head_sha, type: String, desc: 'The SHA of the head commit'
end
post ":id/#{noteables_str}/:noteable_id/notes", feature_category: feature_category do
allowlist =
@@ -87,7 +88,8 @@ module API
noteable_type: noteables_str.classify,
noteable_id: noteable.id,
confidential: params[:confidential],
- created_at: params[:created_at]
+ created_at: params[:created_at],
+ merge_request_diff_head_sha: params[:merge_request_diff_head_sha]
}
note = create_note(noteable, opts)
diff --git a/lib/api/package_files.rb b/lib/api/package_files.rb
index e80355e80c7..4861c0c740e 100644
--- a/lib/api/package_files.rb
+++ b/lib/api/package_files.rb
@@ -29,7 +29,7 @@ module API
.new(user_project, params[:package_id]).execute
package_files = package.installable_package_files
- .preload_pipelines
+ .preload_pipelines.order_id_asc
present paginate(package_files), with: ::API::Entities::PackageFile
end
diff --git a/lib/api/project_clusters.rb b/lib/api/project_clusters.rb
index 6785b28ddef..8bba67a53af 100644
--- a/lib/api/project_clusters.rb
+++ b/lib/api/project_clusters.rb
@@ -4,7 +4,10 @@ module API
class ProjectClusters < ::API::Base
include PaginationParams
- before { authenticate! }
+ before do
+ authenticate!
+ ensure_feature_enabled!
+ end
feature_category :kubernetes_management
@@ -138,6 +141,10 @@ module API
def update_cluster_params
declared_params(include_missing: false).without(:cluster_id)
end
+
+ def ensure_feature_enabled!
+ not_found! unless Feature.enabled?(:certificate_based_clusters, user_project, default_enabled: :yaml, type: :ops)
+ end
end
end
end
diff --git a/lib/api/project_import.rb b/lib/api/project_import.rb
index a3d76e571a9..fae170d638b 100644
--- a/lib/api/project_import.rb
+++ b/lib/api/project_import.rb
@@ -87,14 +87,16 @@ module API
validate_file!
- response = ::Import::GitlabProjects::CreateProjectFromUploadedFileService.new(
+ response = ::Import::GitlabProjects::CreateProjectService.new(
current_user,
- path: import_params[:path],
- namespace: namespace_from(import_params, current_user),
- name: import_params[:name],
- file: import_params[:file],
- overwrite: import_params[:overwrite],
- override: filtered_override_params(import_params)
+ params: {
+ path: import_params[:path],
+ namespace: namespace_from(import_params, current_user),
+ name: import_params[:name],
+ file: import_params[:file],
+ overwrite: import_params[:overwrite],
+ override: filtered_override_params(import_params)
+ }
).execute
if response.success?
@@ -137,14 +139,66 @@ module API
check_rate_limit! :project_import, scope: [current_user, :project_import]
- response = ::Import::GitlabProjects::CreateProjectFromRemoteFileService.new(
+ response = ::Import::GitlabProjects::CreateProjectService.new(
current_user,
- path: import_params[:path],
- namespace: namespace_from(import_params, current_user),
- name: import_params[:name],
- remote_import_url: import_params[:url],
- overwrite: import_params[:overwrite],
- override: filtered_override_params(import_params)
+ params: {
+ path: import_params[:path],
+ namespace: namespace_from(import_params, current_user),
+ name: import_params[:name],
+ remote_import_url: import_params[:url],
+ overwrite: import_params[:overwrite],
+ override: filtered_override_params(import_params)
+ },
+ file_acquisition_strategy: ::Import::GitlabProjects::FileAcquisitionStrategies::RemoteFile
+ ).execute
+
+ if response.success?
+ present(response.payload, with: Entities::ProjectImportStatus)
+ else
+ render_api_error!(response.message, response.http_status)
+ end
+ end
+
+ params do
+ requires :region, type: String, desc: 'AWS region'
+ requires :bucket_name, type: String, desc: 'Bucket name'
+ requires :file_key, type: String, desc: 'File key'
+ requires :access_key_id, type: String, desc: 'Access key id'
+ requires :secret_access_key, type: String, desc: 'Secret access key'
+ requires :path, type: String, desc: 'The new project path and name'
+ optional :name, type: String, desc: 'The name of the project to be imported. Defaults to the path of the project if not provided.'
+ optional :namespace, type: String, desc: "The ID or name of the namespace that the project will be imported into. Defaults to the current user's namespace."
+ optional :overwrite, type: Boolean, default: false, desc: 'If there is a project in the same namespace and with the same name overwrite it'
+ optional :override_params,
+ type: Hash,
+ desc: 'New project params to override values in the export' do
+ use :optional_project_params
+ end
+ end
+ desc 'Create a new project import using a file from AWS S3' do
+ detail 'This feature was introduced in GitLab 14.9.'
+ success Entities::ProjectImportStatus
+ end
+ post 'remote-import-s3' do
+ not_found! unless ::Feature.enabled?(:import_project_from_remote_file_s3, default_enabled: :yaml)
+
+ check_rate_limit! :project_import, scope: [current_user, :project_import]
+
+ response = ::Import::GitlabProjects::CreateProjectService.new(
+ current_user,
+ params: {
+ path: import_params[:path],
+ namespace: namespace_from(import_params, current_user),
+ name: import_params[:name],
+ overwrite: import_params[:overwrite],
+ override: filtered_override_params(import_params),
+ region: import_params[:region],
+ bucket_name: import_params[:bucket_name],
+ file_key: import_params[:file_key],
+ access_key_id: import_params[:access_key_id],
+ secret_access_key: import_params[:secret_access_key]
+ },
+ file_acquisition_strategy: ::Import::GitlabProjects::FileAcquisitionStrategies::RemoteFileS3
).execute
if response.success?
diff --git a/lib/api/project_snippets.rb b/lib/api/project_snippets.rb
index fdbfdf1f7a9..a80e45637dc 100644
--- a/lib/api/project_snippets.rb
+++ b/lib/api/project_snippets.rb
@@ -13,6 +13,7 @@ module API
end
resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
helpers Helpers::SnippetsHelpers
+ helpers SpammableActions::CaptchaCheck::RestApiActionsSupport
helpers do
def check_snippets_enabled
forbidden! unless user_project.feature_available?(:snippets, current_user)
@@ -82,9 +83,9 @@ module API
if service_response.success?
present snippet, with: Entities::ProjectSnippet, current_user: current_user
else
- render_spam_error! if snippet.spam?
-
- render_api_error!({ error: service_response.message }, service_response.http_status)
+ with_captcha_check_rest_api(spammable: snippet) do
+ render_api_error!({ error: service_response.message }, service_response.http_status)
+ end
end
end
@@ -124,9 +125,9 @@ module API
if service_response.success?
present snippet, with: Entities::ProjectSnippet, current_user: current_user
else
- render_spam_error! if snippet.spam?
-
- render_api_error!({ error: service_response.message }, service_response.http_status)
+ with_captcha_check_rest_api(spammable: snippet) do
+ render_api_error!({ error: service_response.message }, service_response.http_status)
+ end
end
end
# rubocop: enable CodeReuse/ActiveRecord
diff --git a/lib/api/pypi_packages.rb b/lib/api/pypi_packages.rb
index 706c0702fce..86f36d4fc00 100644
--- a/lib/api/pypi_packages.rb
+++ b/lib/api/pypi_packages.rb
@@ -170,9 +170,9 @@ module API
params do
requires :content, type: ::API::Validations::Types::WorkhorseFile, desc: 'The package file to be published (generated by Multipart middleware)'
- requires :requires_python, type: String
requires :name, type: String
requires :version, type: String
+ optional :requires_python, type: String
optional :md5_digest, type: String
optional :sha256_digest, type: String
end
diff --git a/lib/api/repositories.rb b/lib/api/repositories.rb
index c3632c812f3..2e21f591667 100644
--- a/lib/api/repositories.rb
+++ b/lib/api/repositories.rb
@@ -248,6 +248,8 @@ module API
changelog = service.execute(commit_to_changelog: false)
present changelog, with: Entities::Changelog
+ rescue Gitlab::Changelog::Error => ex
+ render_api_error!("Failed to generate the changelog: #{ex.message}", 422)
end
desc 'Generates a changelog section for a release and commits it in a changelog file' do
diff --git a/lib/api/search.rb b/lib/api/search.rb
index 60a7e944b43..4ef8fef329c 100644
--- a/lib/api/search.rb
+++ b/lib/api/search.rb
@@ -7,7 +7,7 @@ module API
before do
authenticate!
- check_rate_limit!(:user_email_lookup, scope: [current_user]) if search_service.params.email_lookup?
+ check_rate_limit!(:search_rate_limit, scope: [current_user])
end
feature_category :global_search
diff --git a/lib/api/snippets.rb b/lib/api/snippets.rb
index c4b17a62b59..9a3c68bc854 100644
--- a/lib/api/snippets.rb
+++ b/lib/api/snippets.rb
@@ -9,6 +9,7 @@ module API
resource :snippets do
helpers Helpers::SnippetsHelpers
+ helpers SpammableActions::CaptchaCheck::RestApiActionsSupport
helpers do
def snippets_for_current_user
SnippetsFinder.new(current_user, author: current_user).execute
@@ -91,9 +92,9 @@ module API
if service_response.success?
present snippet, with: Entities::PersonalSnippet, current_user: current_user
else
- render_spam_error! if snippet.spam?
-
- render_api_error!({ error: service_response.message }, service_response.http_status)
+ with_captcha_check_rest_api(spammable: snippet) do
+ render_api_error!({ error: service_response.message }, service_response.http_status)
+ end
end
end
@@ -135,9 +136,9 @@ module API
if service_response.success?
present snippet, with: Entities::PersonalSnippet, current_user: current_user
else
- render_spam_error! if snippet.spam?
-
- render_api_error!({ error: service_response.message }, service_response.http_status)
+ with_captcha_check_rest_api(spammable: snippet) do
+ render_api_error!({ error: service_response.message }, service_response.http_status)
+ end
end
end
diff --git a/lib/api/statistics.rb b/lib/api/statistics.rb
index 6818c04fd2e..a12a2ed08d7 100644
--- a/lib/api/statistics.rb
+++ b/lib/api/statistics.rb
@@ -12,7 +12,7 @@ module API
desc 'Get the current application statistics' do
success Entities::ApplicationStatistics
end
- get "application/statistics" do
+ get "application/statistics", urgency: :low do
counts = Gitlab::Database::Count.approximate_counts(COUNTED_ITEMS)
present counts, with: Entities::ApplicationStatistics
end
diff --git a/lib/api/system_hooks.rb b/lib/api/system_hooks.rb
index e4133713c1f..7c91fbd36d9 100644
--- a/lib/api/system_hooks.rb
+++ b/lib/api/system_hooks.rb
@@ -22,6 +22,18 @@ module API
present paginate(SystemHook.all), with: Entities::Hook
end
+ desc 'Get a hook' do
+ success Entities::Hook
+ end
+ params do
+ requires :id, type: Integer, desc: 'The ID of the system hook'
+ end
+ get ":id" do
+ hook = SystemHook.find(params[:id])
+
+ present hook, with: Entities::Hook
+ end
+
desc 'Create a new system hook' do
success Entities::Hook
end
diff --git a/lib/api/topics.rb b/lib/api/topics.rb
index b9c2bcc2da8..e4a1fa2367e 100644
--- a/lib/api/topics.rb
+++ b/lib/api/topics.rb
@@ -77,5 +77,19 @@ module API
render_validation_error!(topic)
end
end
+
+ desc 'Delete a topic' do
+ detail 'This feature was introduced in GitLab 14.9.'
+ end
+ params do
+ requires :id, type: Integer, desc: 'ID of project topic'
+ end
+ delete 'topics/:id' do
+ authenticated_as_admin!
+
+ topic = ::Projects::Topic.find(params[:id])
+
+ destroy_conditionally!(topic)
+ end
end
end
diff --git a/lib/api/user_counts.rb b/lib/api/user_counts.rb
index 634dd0f2179..e5dfac3b1a1 100644
--- a/lib/api/user_counts.rb
+++ b/lib/api/user_counts.rb
@@ -11,13 +11,19 @@ module API
get do
unauthorized! unless current_user
- {
+ counts = {
merge_requests: current_user.assigned_open_merge_requests_count, # @deprecated
assigned_issues: current_user.assigned_open_issues_count,
assigned_merge_requests: current_user.assigned_open_merge_requests_count,
review_requested_merge_requests: current_user.review_requested_open_merge_requests_count,
todos: current_user.todos_pending_count
}
+
+ if Feature.enabled?(:mr_attention_requests, default_enabled: :yaml)
+ counts[:attention_requests] = current_user.attention_requested_open_merge_requests_count
+ end
+
+ counts
end
end
end
diff --git a/lib/api/users.rb b/lib/api/users.rb
index 6d4f12d80f8..0f710e0a307 100644
--- a/lib/api/users.rb
+++ b/lib/api/users.rb
@@ -142,13 +142,11 @@ module API
get ":id", feature_category: :users do
forbidden!('Not authorized!') unless current_user
- if Feature.enabled?(:rate_limit_user_by_id_endpoint, type: :development)
- unless current_user.admin?
- check_rate_limit!(:users_get_by_id,
- scope: current_user,
- users_allowlist: Gitlab::CurrentSettings.current_application_settings.users_get_by_id_limit_allowlist
- )
- end
+ unless current_user.admin?
+ check_rate_limit!(:users_get_by_id,
+ scope: current_user,
+ users_allowlist: Gitlab::CurrentSettings.current_application_settings.users_get_by_id_limit_allowlist
+ )
end
user = User.find_by(id: params[:id])
@@ -383,6 +381,23 @@ module API
present paginate(keys), with: Entities::SSHKey
end
+ desc 'Get a SSH key of a specified user.' do
+ success Entities::SSHKey
+ end
+ params do
+ requires :id, type: Integer, desc: 'The ID of the user'
+ requires :key_id, type: Integer, desc: 'The ID of the SSH key'
+ end
+ get ':id/keys/:key_id', requirements: API::USER_REQUIREMENTS, feature_category: :authentication_and_authorization do
+ user = find_user(params[:id])
+ not_found!('User') unless user && can?(current_user, :read_user, user)
+
+ key = user.keys.find_by(id: params[:key_id]) # rubocop: disable CodeReuse/ActiveRecord
+ not_found!('Key') unless key
+
+ present key, with: Entities::SSHKey
+ end
+
desc 'Delete an existing SSH key from a specified user. Available only for admins.' do
success Entities::SSHKey
end
@@ -687,6 +702,8 @@ module API
if user.ldap_blocked?
forbidden!('LDAP blocked users cannot be modified by the API')
+ elsif current_user == user
+ forbidden!('The API initiating user cannot be blocked by the API')
end
break if user.blocked?
diff --git a/lib/api/validations/validators/file_path.rb b/lib/api/validations/validators/file_path.rb
index 246c445658f..268ddc29d4e 100644
--- a/lib/api/validations/validators/file_path.rb
+++ b/lib/api/validations/validators/file_path.rb
@@ -8,8 +8,7 @@ module API
options = @option.is_a?(Hash) ? @option : {}
path_allowlist = options.fetch(:allowlist, [])
path = params[attr_name]
- path = Gitlab::Utils.check_path_traversal!(path)
- Gitlab::Utils.check_allowed_absolute_path!(path, path_allowlist)
+ Gitlab::Utils.check_allowed_absolute_path_and_path_traversal!(path, path_allowlist)
rescue StandardError
raise Grape::Exceptions::Validation.new(
params: [@scope.full_name(attr_name)],
diff --git a/lib/api/wikis.rb b/lib/api/wikis.rb
index fdce3c5ce18..e90d88940a5 100644
--- a/lib/api/wikis.rb
+++ b/lib/api/wikis.rb
@@ -45,11 +45,13 @@ module API
end
params do
requires :slug, type: String, desc: 'The slug of a wiki page'
+ optional :version, type: String, desc: 'The version hash of a wiki page'
+ optional :render_html, type: Boolean, default: false, desc: 'Render content to HTML'
end
get ':id/wikis/:slug' do
authorize! :read_wiki, container
- present wiki_page, with: Entities::WikiPage
+ present wiki_page(params[:version]), with: Entities::WikiPage, render_html: params[:render_html]
end
desc 'Create a wiki page' do
diff --git a/lib/atlassian/jira_connect.rb b/lib/atlassian/jira_connect.rb
index 7f693eff59b..595cf0ac465 100644
--- a/lib/atlassian/jira_connect.rb
+++ b/lib/atlassian/jira_connect.rb
@@ -8,7 +8,10 @@ module Atlassian
end
def app_key
- "gitlab-jira-connect-#{gitlab_host}"
+ # App key must be <= 64 characters.
+ # See: https://developer.atlassian.com/cloud/jira/platform/connect-app-descriptor/#app-descriptor-structure
+
+ "gitlab-jira-connect-#{gitlab_host}"[..63]
end
private
diff --git a/lib/atlassian/jira_connect/client.rb b/lib/atlassian/jira_connect/client.rb
index dc37465744b..b8aa2cc8ea0 100644
--- a/lib/atlassian/jira_connect/client.rb
+++ b/lib/atlassian/jira_connect/client.rb
@@ -127,16 +127,21 @@ module Atlassian
def handle_response(response, name, &block)
data = response.parsed_response
- case response.code
- when 200 then yield data
- when 400 then { 'errorMessages' => data.map { |e| e['message'] } }
- when 401 then { 'errorMessages' => ['Invalid JWT'] }
- when 403 then { 'errorMessages' => ["App does not support #{name}"] }
- when 413 then { 'errorMessages' => ['Data too large'] + data.map { |e| e['message'] } }
- when 429 then { 'errorMessages' => ['Rate limit exceeded'] }
- when 503 then { 'errorMessages' => ['Service unavailable'] }
+ if [200, 202].include?(response.code)
+ yield data
else
- { 'errorMessages' => ['Unknown error'], 'response' => data }
+ message = case response.code
+ when 400 then { 'errorMessages' => data.map { |e| e['message'] } }
+ when 401 then { 'errorMessages' => ['Invalid JWT'] }
+ when 403 then { 'errorMessages' => ["App does not support #{name}"] }
+ when 413 then { 'errorMessages' => ['Data too large'] + data.map { |e| e['message'] } }
+ when 429 then { 'errorMessages' => ['Rate limit exceeded'] }
+ when 503 then { 'errorMessages' => ['Service unavailable'] }
+ else
+ { 'errorMessages' => ['Unknown error'], 'response' => data }
+ end
+
+ message.merge('responseCode' => response.code)
end
end
diff --git a/lib/atlassian/jira_connect/serializers/build_entity.rb b/lib/atlassian/jira_connect/serializers/build_entity.rb
index a3434c529a4..10e4bb0e709 100644
--- a/lib/atlassian/jira_connect/serializers/build_entity.rb
+++ b/lib/atlassian/jira_connect/serializers/build_entity.rb
@@ -26,7 +26,7 @@ module Atlassian
# merge request title.
@issue_keys ||= begin
pipeline.all_merge_requests.flat_map do |mr|
- src = "#{mr.source_branch} #{mr.title}"
+ src = "#{mr.source_branch} #{mr.title} #{mr.description}"
JiraIssueKeyExtractor.new(src).issue_keys
end.uniq
end
diff --git a/lib/atlassian/jira_connect/serializers/environment_entity.rb b/lib/atlassian/jira_connect/serializers/environment_entity.rb
index b6b5db40ba6..67ac93473c3 100644
--- a/lib/atlassian/jira_connect/serializers/environment_entity.rb
+++ b/lib/atlassian/jira_connect/serializers/environment_entity.rb
@@ -20,18 +20,7 @@ module Atlassian
end
def type
- case environment.name
- when /\A(.*[^a-z0-9])?(staging|stage|stg|preprod|pre-prod|model|internal)([^a-z0-9].*)?\z/i
- 'staging'
- when /\A(.*[^a-z0-9])?(prod|production|prd|live)([^a-z0-9].*)?\z/i
- 'production'
- when /\A(.*[^a-z0-9])?(test|testing|tests|tst|integration|integ|intg|int|acceptance|accept|acpt|qa|qc|control|quality)([^a-z0-9].*)?\z/i
- 'testing'
- when /\A(.*[^a-z0-9])?(dev|review|development)([^a-z0-9].*)?\z/i
- 'development'
- else
- 'unmapped'
- end
+ environment.tier == 'other' ? 'unmapped' : environment.tier
end
end
end
diff --git a/lib/backup/artifacts.rb b/lib/backup/artifacts.rb
index 163446998e9..4ef76b0aaf3 100644
--- a/lib/backup/artifacts.rb
+++ b/lib/backup/artifacts.rb
@@ -2,14 +2,11 @@
module Backup
class Artifacts < Backup::Files
- attr_reader :progress
-
def initialize(progress)
- @progress = progress
-
- super('artifacts', JobArtifactUploader.root, excludes: ['tmp'])
+ super(progress, 'artifacts', JobArtifactUploader.root, excludes: ['tmp'])
end
+ override :human_name
def human_name
_('artifacts')
end
diff --git a/lib/backup/builds.rb b/lib/backup/builds.rb
index 51a68ca933d..fbf932e3f6b 100644
--- a/lib/backup/builds.rb
+++ b/lib/backup/builds.rb
@@ -2,14 +2,11 @@
module Backup
class Builds < Backup::Files
- attr_reader :progress
-
def initialize(progress)
- @progress = progress
-
- super('builds', Settings.gitlab_ci.builds_path)
+ super(progress, 'builds', Settings.gitlab_ci.builds_path)
end
+ override :human_name
def human_name
_('builds')
end
diff --git a/lib/backup/database.rb b/lib/backup/database.rb
index de26dbab038..afc84a4b913 100644
--- a/lib/backup/database.rb
+++ b/lib/backup/database.rb
@@ -3,10 +3,10 @@
require 'yaml'
module Backup
- class Database
+ class Database < Task
+ extend ::Gitlab::Utils::Override
include Backup::Helper
- attr_reader :progress
- attr_reader :config, :db_file_name
+ attr_reader :force, :config
IGNORED_ERRORS = [
# Ignore warnings
@@ -18,13 +18,14 @@ module Backup
].freeze
IGNORED_ERRORS_REGEXP = Regexp.union(IGNORED_ERRORS).freeze
- def initialize(progress, filename: nil)
- @progress = progress
+ def initialize(progress, force:)
+ super(progress)
@config = ActiveRecord::Base.configurations.find_db_config(Rails.env).configuration_hash
- @db_file_name = filename || File.join(Gitlab.config.backup.path, 'db', 'database.sql.gz')
+ @force = force
end
- def dump
+ override :dump
+ def dump(db_file_name)
FileUtils.mkdir_p(File.dirname(db_file_name))
FileUtils.rm_f(db_file_name)
compress_rd, compress_wr = IO.pipe
@@ -64,12 +65,24 @@ module Backup
raise DatabaseBackupError.new(config, db_file_name) unless success
end
- def restore
+ override :restore
+ def restore(db_file_name)
+ unless force
+ progress.puts 'Removing all tables. Press `Ctrl-C` within 5 seconds to abort'.color(:yellow)
+ sleep(5)
+ end
+
+ # Drop all tables Load the schema to ensure we don't have any newer tables
+ # hanging out from a failed upgrade
+ puts_time 'Cleaning the database ... '.color(:blue)
+ Rake::Task['gitlab:db:drop_tables'].invoke
+ puts_time 'done'.color(:green)
+
decompress_rd, decompress_wr = IO.pipe
decompress_pid = spawn(*%w(gzip -cd), out: decompress_wr, in: db_file_name)
decompress_wr.close
- status, errors =
+ status, @errors =
case config[:adapter]
when "postgresql" then
progress.print "Restoring PostgreSQL database #{database} ... "
@@ -81,33 +94,47 @@ module Backup
Process.waitpid(decompress_pid)
success = $?.success? && status.success?
- if errors.present?
+ if @errors.present?
progress.print "------ BEGIN ERRORS -----\n".color(:yellow)
- progress.print errors.join.color(:yellow)
+ progress.print @errors.join.color(:yellow)
progress.print "------ END ERRORS -------\n".color(:yellow)
end
report_success(success)
raise Backup::Error, 'Restore failed' unless success
+ end
- if errors.present?
- warning = <<~MSG
- There were errors in restoring the schema. This may cause
- issues if this results in missing indexes, constraints, or
- columns. Please record the errors above and contact GitLab
- Support if you have questions:
- https://about.gitlab.com/support/
- MSG
-
- warn warning.color(:red)
- Gitlab::TaskHelpers.ask_to_continue
- end
+ override :pre_restore_warning
+ def pre_restore_warning
+ return if force
+
+ <<-MSG.strip_heredoc
+ Be sure to stop Puma, Sidekiq, and any other process that
+ connects to the database before proceeding. For Omnibus
+ installs, see the following link for more information:
+ https://docs.gitlab.com/ee/raketasks/backup_restore.html#restore-for-omnibus-gitlab-installations
+
+ Before restoring the database, we will remove all existing
+ tables to avoid future upgrade problems. Be aware that if you have
+ custom tables in the GitLab database these tables and all data will be
+ removed.
+ MSG
end
- def enabled
- true
+ override :post_restore_warning
+ def post_restore_warning
+ return unless @errors.present?
+
+ <<-MSG.strip_heredoc
+ There were errors in restoring the schema. This may cause
+ issues if this results in missing indexes, constraints, or
+ columns. Please record the errors above and contact GitLab
+ Support if you have questions:
+ https://about.gitlab.com/support/
+ MSG
end
+ override :human_name
def human_name
_('database')
end
diff --git a/lib/backup/files.rb b/lib/backup/files.rb
index db6278360a3..7fa07e40cee 100644
--- a/lib/backup/files.rb
+++ b/lib/backup/files.rb
@@ -1,25 +1,27 @@
# frozen_string_literal: true
require 'open3'
-require_relative 'helper'
module Backup
- class Files
+ class Files < Task
+ extend ::Gitlab::Utils::Override
include Backup::Helper
DEFAULT_EXCLUDE = 'lost+found'
- attr_reader :name, :backup_tarball, :excludes
+ attr_reader :name, :excludes
+
+ def initialize(progress, name, app_files_dir, excludes: [])
+ super(progress)
- def initialize(name, app_files_dir, excludes: [])
@name = name
@app_files_dir = app_files_dir
- @backup_tarball = File.join(Gitlab.config.backup.path, name + '.tar.gz')
@excludes = [DEFAULT_EXCLUDE].concat(excludes)
end
# Copy files from public/files to backup/files
- def dump
+ override :dump
+ def dump(backup_tarball)
FileUtils.mkdir_p(Gitlab.config.backup.path)
FileUtils.rm_f(backup_tarball)
@@ -35,7 +37,7 @@ module Backup
unless status == 0
puts output
- raise_custom_error
+ raise_custom_error(backup_tarball)
end
tar_cmd = [tar, exclude_dirs(:tar), %W[-C #{backup_files_realpath} -cf - .]].flatten
@@ -47,11 +49,12 @@ module Backup
end
unless pipeline_succeeded?(tar_status: status_list[0], gzip_status: status_list[1], output: output)
- raise_custom_error
+ raise_custom_error(backup_tarball)
end
end
- def restore
+ override :restore
+ def restore(backup_tarball)
backup_existing_files_dir
cmd_list = [%w[gzip -cd], %W[#{tar} --unlink-first --recursive-unlink -C #{app_files_realpath} -xf -]]
@@ -61,10 +64,6 @@ module Backup
end
end
- def enabled
- true
- end
-
def tar
if system(*%w[gtar --version], out: '/dev/null')
# It looks like we can get GNU tar by running 'gtar'
@@ -146,7 +145,7 @@ module Backup
end
end
- def raise_custom_error
+ def raise_custom_error(backup_tarball)
raise FileBackupError.new(app_files_realpath, backup_tarball)
end
diff --git a/lib/backup/gitaly_backup.rb b/lib/backup/gitaly_backup.rb
index 8ac09e94004..b688ff7f13b 100644
--- a/lib/backup/gitaly_backup.rb
+++ b/lib/backup/gitaly_backup.rb
@@ -9,13 +9,16 @@ module Backup
# @param [StringIO] progress IO interface to output progress
# @param [Integer] max_parallelism max parallelism when running backups
# @param [Integer] storage_parallelism max parallelism per storage (is affected by max_parallelism)
- def initialize(progress, max_parallelism: nil, storage_parallelism: nil)
+ # @param [String] backup_id unique identifier for the backup
+ def initialize(progress, max_parallelism: nil, storage_parallelism: nil, incremental: false, backup_id: nil)
@progress = progress
@max_parallelism = max_parallelism
@storage_parallelism = storage_parallelism
+ @incremental = incremental
+ @backup_id = backup_id
end
- def start(type)
+ def start(type, backup_repos_path)
raise Error, 'already started' if started?
command = case type
@@ -30,6 +33,13 @@ module Backup
args = []
args += ['-parallel', @max_parallelism.to_s] if @max_parallelism
args += ['-parallel-storage', @storage_parallelism.to_s] if @storage_parallelism
+ if Feature.enabled?(:incremental_repository_backup, default_enabled: :yaml)
+ args += ['-layout', 'pointer']
+ if type == :create
+ args += ['-incremental'] if @incremental
+ args += ['-id', @backup_id] if @backup_id
+ end
+ end
@input_stream, stdout, @thread = Open3.popen2(build_env, bin_path, command, '-path', backup_repos_path, *args)
@@ -93,10 +103,6 @@ module Backup
@thread.present?
end
- def backup_repos_path
- File.absolute_path(File.join(Gitlab.config.backup.path, 'repositories'))
- end
-
def bin_path
File.absolute_path(Gitlab.config.backup.gitaly_backup_path)
end
diff --git a/lib/backup/gitaly_rpc_backup.rb b/lib/backup/gitaly_rpc_backup.rb
index bbd83cd2157..89ed27cfa13 100644
--- a/lib/backup/gitaly_rpc_backup.rb
+++ b/lib/backup/gitaly_rpc_backup.rb
@@ -7,10 +7,11 @@ module Backup
@progress = progress
end
- def start(type)
+ def start(type, backup_repos_path)
raise Error, 'already started' if @type
@type = type
+ @backup_repos_path = backup_repos_path
case type
when :create
FileUtils.rm_rf(backup_repos_path)
@@ -31,7 +32,7 @@ module Backup
backup_restore = BackupRestore.new(
progress,
repository_type.repository_for(container),
- backup_repos_path
+ @backup_repos_path
)
case @type
@@ -52,10 +53,6 @@ module Backup
attr_reader :progress
- def backup_repos_path
- @backup_repos_path ||= File.join(Gitlab.config.backup.path, 'repositories')
- end
-
class BackupRestore
attr_accessor :progress, :repository, :backup_repos_path
diff --git a/lib/backup/lfs.rb b/lib/backup/lfs.rb
index 17f7b8bf8b0..e92f235a2d7 100644
--- a/lib/backup/lfs.rb
+++ b/lib/backup/lfs.rb
@@ -2,14 +2,11 @@
module Backup
class Lfs < Backup::Files
- attr_reader :progress
-
def initialize(progress)
- @progress = progress
-
- super('lfs', Settings.lfs.storage_path)
+ super(progress, 'lfs', Settings.lfs.storage_path)
end
+ override :human_name
def human_name
_('lfs objects')
end
diff --git a/lib/backup/manager.rb b/lib/backup/manager.rb
index 5b393cf9477..6e90824fce2 100644
--- a/lib/backup/manager.rb
+++ b/lib/backup/manager.rb
@@ -2,43 +2,84 @@
module Backup
class Manager
- ARCHIVES_TO_BACKUP = %w[uploads builds artifacts pages lfs terraform_state registry packages].freeze
- FOLDERS_TO_BACKUP = %w[repositories db].freeze
FILE_NAME_SUFFIX = '_gitlab_backup.tar'
+ MANIFEST_NAME = 'backup_information.yml'
+
+ TaskDefinition = Struct.new(
+ :destination_path, # Where the task should put its backup file/dir.
+ :destination_optional, # `true` if the destination might not exist on a successful backup.
+ :cleanup_path, # Path to remove after a successful backup. Uses `destination_path` when not specified.
+ :task,
+ keyword_init: true
+ )
attr_reader :progress
- def initialize(progress)
+ def initialize(progress, definitions: nil)
@progress = progress
max_concurrency = ENV.fetch('GITLAB_BACKUP_MAX_CONCURRENCY', 1).to_i
max_storage_concurrency = ENV.fetch('GITLAB_BACKUP_MAX_STORAGE_CONCURRENCY', 1).to_i
-
- @tasks = {
- 'db' => Database.new(progress),
- 'repositories' => Repositories.new(progress,
- strategy: repository_backup_strategy,
- max_concurrency: max_concurrency,
- max_storage_concurrency: max_storage_concurrency),
- 'uploads' => Uploads.new(progress),
- 'builds' => Builds.new(progress),
- 'artifacts' => Artifacts.new(progress),
- 'pages' => Pages.new(progress),
- 'lfs' => Lfs.new(progress),
- 'terraform_state' => TerraformState.new(progress),
- 'registry' => Registry.new(progress),
- 'packages' => Packages.new(progress)
+ force = ENV['force'] == 'yes'
+ incremental = Gitlab::Utils.to_boolean(ENV['INCREMENTAL'], default: false)
+
+ @definitions = definitions || {
+ 'db' => TaskDefinition.new(
+ destination_path: 'db/database.sql.gz',
+ cleanup_path: 'db',
+ task: Database.new(progress, force: force)
+ ),
+ 'repositories' => TaskDefinition.new(
+ destination_path: 'repositories',
+ destination_optional: true,
+ task: Repositories.new(progress,
+ strategy: repository_backup_strategy(incremental),
+ max_concurrency: max_concurrency,
+ max_storage_concurrency: max_storage_concurrency)
+ ),
+ 'uploads' => TaskDefinition.new(
+ destination_path: 'uploads.tar.gz',
+ task: Uploads.new(progress)
+ ),
+ 'builds' => TaskDefinition.new(
+ destination_path: 'builds.tar.gz',
+ task: Builds.new(progress)
+ ),
+ 'artifacts' => TaskDefinition.new(
+ destination_path: 'artifacts.tar.gz',
+ task: Artifacts.new(progress)
+ ),
+ 'pages' => TaskDefinition.new(
+ destination_path: 'pages.tar.gz',
+ task: Pages.new(progress)
+ ),
+ 'lfs' => TaskDefinition.new(
+ destination_path: 'lfs.tar.gz',
+ task: Lfs.new(progress)
+ ),
+ 'terraform_state' => TaskDefinition.new(
+ destination_path: 'terraform_state.tar.gz',
+ task: TerraformState.new(progress)
+ ),
+ 'registry' => TaskDefinition.new(
+ destination_path: 'registry.tar.gz',
+ task: Registry.new(progress)
+ ),
+ 'packages' => TaskDefinition.new(
+ destination_path: 'packages.tar.gz',
+ task: Packages.new(progress)
+ )
}.freeze
end
def create
- @tasks.keys.each do |task_name|
+ @definitions.keys.each do |task_name|
run_create_task(task_name)
end
- write_info
+ write_backup_information
- if ENV['SKIP'] && ENV['SKIP'].include?('tar')
+ if skipped?('tar')
upload
else
pack
@@ -54,21 +95,23 @@ module Backup
end
def run_create_task(task_name)
- task = @tasks[task_name]
+ definition = @definitions[task_name]
- puts_time "Dumping #{task.human_name} ... ".color(:blue)
+ build_backup_information
+ puts_time "Dumping #{definition.task.human_name} ... ".color(:blue)
- unless task.enabled
+ unless definition.task.enabled
puts_time "[DISABLED]".color(:cyan)
return
end
- if ENV["SKIP"] && ENV["SKIP"].include?(task_name)
+ if skipped?(task_name)
puts_time "[SKIPPED]".color(:cyan)
return
end
- task.dump
+ definition.task.dump(File.join(Gitlab.config.backup.path, definition.destination_path))
+
puts_time "done".color(:green)
rescue Backup::DatabaseBackupError, Backup::FileBackupError => e
@@ -77,42 +120,11 @@ module Backup
def restore
cleanup_required = unpack
+ read_backup_information
verify_backup_version
- unless skipped?('db')
- begin
- unless ENV['force'] == 'yes'
- warning = <<-MSG.strip_heredoc
- Be sure to stop Puma, Sidekiq, and any other process that
- connects to the database before proceeding. For Omnibus
- installs, see the following link for more information:
- https://docs.gitlab.com/ee/raketasks/backup_restore.html#restore-for-omnibus-gitlab-installations
-
- Before restoring the database, we will remove all existing
- tables to avoid future upgrade problems. Be aware that if you have
- custom tables in the GitLab database these tables and all data will be
- removed.
- MSG
- puts warning.color(:red)
- Gitlab::TaskHelpers.ask_to_continue
- puts 'Removing all tables. Press `Ctrl-C` within 5 seconds to abort'.color(:yellow)
- sleep(5)
- end
-
- # Drop all tables Load the schema to ensure we don't have any newer tables
- # hanging out from a failed upgrade
- puts_time 'Cleaning the database ... '.color(:blue)
- Rake::Task['gitlab:db:drop_tables'].invoke
- puts_time 'done'.color(:green)
- run_restore_task('db')
- rescue Gitlab::TaskAbortedByUserError
- puts "Quitting...".color(:red)
- exit 1
- end
- end
-
- @tasks.except('db').keys.each do |task_name|
- run_restore_task(task_name) unless skipped?(task_name)
+ @definitions.keys.each do |task_name|
+ run_restore_task(task_name) if !skipped?(task_name) && enabled_task?(task_name)
end
Rake::Task['gitlab:shell:setup'].invoke
@@ -130,30 +142,71 @@ module Backup
end
def run_restore_task(task_name)
- task = @tasks[task_name]
+ definition = @definitions[task_name]
- puts_time "Restoring #{task.human_name} ... ".color(:blue)
+ read_backup_information
+ puts_time "Restoring #{definition.task.human_name} ... ".color(:blue)
- unless task.enabled
+ unless definition.task.enabled
puts_time "[DISABLED]".color(:cyan)
return
end
- task.restore
+ warning = definition.task.pre_restore_warning
+ if warning.present?
+ puts_time warning.color(:red)
+ Gitlab::TaskHelpers.ask_to_continue
+ end
+
+ definition.task.restore(File.join(Gitlab.config.backup.path, definition.destination_path))
+
puts_time "done".color(:green)
+
+ warning = definition.task.post_restore_warning
+ if warning.present?
+ puts_time warning.color(:red)
+ Gitlab::TaskHelpers.ask_to_continue
+ end
+
+ rescue Gitlab::TaskAbortedByUserError
+ puts_time "Quitting...".color(:red)
+ exit 1
end
- def write_info
+ private
+
+ def read_backup_information
+ @backup_information ||= YAML.load_file(File.join(backup_path, MANIFEST_NAME))
+ end
+
+ def write_backup_information
# Make sure there is a connection
ActiveRecord::Base.connection.reconnect!
Dir.chdir(backup_path) do
- File.open("#{backup_path}/backup_information.yml", "w+") do |file|
+ File.open("#{backup_path}/#{MANIFEST_NAME}", "w+") do |file|
file << backup_information.to_yaml.gsub(/^---\n/, '')
end
end
end
+ def build_backup_information
+ @backup_information ||= {
+ db_version: ActiveRecord::Migrator.current_version.to_s,
+ backup_created_at: Time.now,
+ gitlab_version: Gitlab::VERSION,
+ tar_version: tar_version,
+ installation_type: Gitlab::INSTALLATION_TYPE,
+ skipped: ENV["SKIP"]
+ }
+ end
+
+ def backup_information
+ raise Backup::Error, "#{MANIFEST_NAME} not yet loaded" unless @backup_information
+
+ @backup_information
+ end
+
def pack
Dir.chdir(backup_path) do
# create archive
@@ -182,8 +235,11 @@ module Backup
upload = directory.files.create(create_attributes)
if upload
- progress.puts "done".color(:green)
- upload
+ if upload.respond_to?(:encryption) && upload.encryption
+ progress.puts "done (encrypted with #{upload.encryption})".color(:green)
+ else
+ progress.puts "done".color(:green)
+ end
else
puts "uploading backup to #{remote_directory} failed".color(:red)
raise Backup::Error, 'Backup failed'
@@ -193,18 +249,19 @@ module Backup
def cleanup
progress.print "Deleting tmp directories ... "
- backup_contents.each do |dir|
- next unless File.exist?(File.join(backup_path, dir))
-
- if FileUtils.rm_rf(File.join(backup_path, dir))
- progress.puts "done".color(:green)
- else
- puts "deleting tmp directory '#{dir}' failed".color(:red)
- raise Backup::Error, 'Backup failed'
- end
+ remove_backup_path(MANIFEST_NAME)
+ @definitions.each do |_, definition|
+ remove_backup_path(definition.cleanup_path || definition.destination_path)
end
end
+ def remove_backup_path(path)
+ return unless File.exist?(File.join(backup_path, path))
+
+ FileUtils.rm_rf(File.join(backup_path, path))
+ progress.puts "done".color(:green)
+ end
+
def remove_tmp
# delete tmp inside backups
progress.print "Deleting backups/tmp ... "
@@ -255,15 +312,15 @@ module Backup
def verify_backup_version
Dir.chdir(backup_path) do
# restoring mismatching backups can lead to unexpected problems
- if settings[:gitlab_version] != Gitlab::VERSION
+ if backup_information[:gitlab_version] != Gitlab::VERSION
progress.puts(<<~HEREDOC.color(:red))
GitLab version mismatch:
Your current GitLab version (#{Gitlab::VERSION}) differs from the GitLab version in the backup!
Please switch to the following version and try again:
- version: #{settings[:gitlab_version]}
+ version: #{backup_information[:gitlab_version]}
HEREDOC
progress.puts
- progress.puts "Hint: git checkout v#{settings[:gitlab_version]}"
+ progress.puts "Hint: git checkout v#{backup_information[:gitlab_version]}"
exit 1
end
end
@@ -319,13 +376,11 @@ module Backup
end
def skipped?(item)
- settings[:skipped] && settings[:skipped].include?(item) || !enabled_task?(item)
+ backup_information[:skipped] && backup_information[:skipped].include?(item)
end
- private
-
def enabled_task?(task_name)
- @tasks[task_name].enabled
+ @definitions[task_name].task.enabled
end
def backup_file?(file)
@@ -333,7 +388,7 @@ module Backup
end
def non_tarred_backup?
- File.exist?(File.join(backup_path, 'backup_information.yml'))
+ File.exist?(File.join(backup_path, MANIFEST_NAME))
end
def backup_path
@@ -380,19 +435,10 @@ module Backup
end
def backup_contents
- folders_to_backup + archives_to_backup + ["backup_information.yml"]
- end
-
- def archives_to_backup
- ARCHIVES_TO_BACKUP.map { |name| (name + ".tar.gz") unless skipped?(name) }.compact
- end
-
- def folders_to_backup
- FOLDERS_TO_BACKUP.select { |name| !skipped?(name) && Dir.exist?(File.join(backup_path, name)) }
- end
-
- def settings
- @settings ||= YAML.load_file("backup_information.yml")
+ [MANIFEST_NAME] + @definitions.reject do |name, definition|
+ skipped?(name) || !enabled_task?(name) ||
+ (definition.destination_optional && !File.exist?(File.join(backup_path, definition.destination_path)))
+ end.values.map(&:destination_path)
end
def tar_file
@@ -403,17 +449,6 @@ module Backup
end
end
- def backup_information
- @backup_information ||= {
- db_version: ActiveRecord::Migrator.current_version.to_s,
- backup_created_at: Time.now,
- gitlab_version: Gitlab::VERSION,
- tar_version: tar_version,
- installation_type: Gitlab::INSTALLATION_TYPE,
- skipped: ENV["SKIP"]
- }
- end
-
def create_attributes
attrs = {
key: remote_target,
@@ -447,11 +482,11 @@ module Backup
Gitlab.config.backup.upload.connection&.provider&.downcase == 'google'
end
- def repository_backup_strategy
+ def repository_backup_strategy(incremental)
if Feature.enabled?(:gitaly_backup, default_enabled: :yaml)
max_concurrency = ENV['GITLAB_BACKUP_MAX_CONCURRENCY'].presence
max_storage_concurrency = ENV['GITLAB_BACKUP_MAX_STORAGE_CONCURRENCY'].presence
- Backup::GitalyBackup.new(progress, max_parallelism: max_concurrency, storage_parallelism: max_storage_concurrency)
+ Backup::GitalyBackup.new(progress, incremental: incremental, max_parallelism: max_concurrency, storage_parallelism: max_storage_concurrency)
else
Backup::GitalyRpcBackup.new(progress)
end
diff --git a/lib/backup/packages.rb b/lib/backup/packages.rb
index 037ff31fd9b..9384e007162 100644
--- a/lib/backup/packages.rb
+++ b/lib/backup/packages.rb
@@ -2,14 +2,11 @@
module Backup
class Packages < Backup::Files
- attr_reader :progress
-
def initialize(progress)
- @progress = progress
-
- super('packages', Settings.packages.storage_path, excludes: ['tmp'])
+ super(progress, 'packages', Settings.packages.storage_path, excludes: ['tmp'])
end
+ override :human_name
def human_name
_('packages')
end
diff --git a/lib/backup/pages.rb b/lib/backup/pages.rb
index 724972d212d..ebed6820724 100644
--- a/lib/backup/pages.rb
+++ b/lib/backup/pages.rb
@@ -6,14 +6,11 @@ module Backup
# if some of these files are still there, we don't need them in the backup
LEGACY_PAGES_TMP_PATH = '@pages.tmp'
- attr_reader :progress
-
def initialize(progress)
- @progress = progress
-
- super('pages', Gitlab.config.pages.path, excludes: [LEGACY_PAGES_TMP_PATH])
+ super(progress, 'pages', Gitlab.config.pages.path, excludes: [LEGACY_PAGES_TMP_PATH])
end
+ override :human_name
def human_name
_('pages')
end
diff --git a/lib/backup/registry.rb b/lib/backup/registry.rb
index 7ba3a9e9c60..68ea635034d 100644
--- a/lib/backup/registry.rb
+++ b/lib/backup/registry.rb
@@ -2,18 +2,16 @@
module Backup
class Registry < Backup::Files
- attr_reader :progress
-
def initialize(progress)
- @progress = progress
-
- super('registry', Settings.registry.path)
+ super(progress, 'registry', Settings.registry.path)
end
+ override :human_name
def human_name
_('container registry images')
end
+ override :enabled
def enabled
Gitlab.config.registry.enabled
end
diff --git a/lib/backup/repositories.rb b/lib/backup/repositories.rb
index e7c3e869928..3633ebd661e 100644
--- a/lib/backup/repositories.rb
+++ b/lib/backup/repositories.rb
@@ -3,16 +3,20 @@
require 'yaml'
module Backup
- class Repositories
+ class Repositories < Task
+ extend ::Gitlab::Utils::Override
+
def initialize(progress, strategy:, max_concurrency: 1, max_storage_concurrency: 1)
- @progress = progress
+ super(progress)
+
@strategy = strategy
@max_concurrency = max_concurrency
@max_storage_concurrency = max_storage_concurrency
end
- def dump
- strategy.start(:create)
+ override :dump
+ def dump(path)
+ strategy.start(:create, path)
# gitaly-backup is designed to handle concurrency on its own. So we want
# to avoid entering the buggy concurrency code here when gitaly-backup
@@ -50,8 +54,9 @@ module Backup
strategy.finish!
end
- def restore
- strategy.start(:restore)
+ override :restore
+ def restore(path)
+ strategy.start(:restore, path)
enqueue_consecutive
ensure
@@ -61,17 +66,14 @@ module Backup
restore_object_pools
end
- def enabled
- true
- end
-
+ override :human_name
def human_name
_('repositories')
end
private
- attr_reader :progress, :strategy, :max_concurrency, :max_storage_concurrency
+ attr_reader :strategy, :max_concurrency, :max_storage_concurrency
def check_valid_storages!
repository_storage_klasses.each do |klass|
diff --git a/lib/backup/task.rb b/lib/backup/task.rb
new file mode 100644
index 00000000000..15cd2aa64d3
--- /dev/null
+++ b/lib/backup/task.rb
@@ -0,0 +1,46 @@
+# frozen_string_literal: true
+
+module Backup
+ class Task
+ def initialize(progress)
+ @progress = progress
+ end
+
+ # human readable task name used for logging
+ def human_name
+ raise NotImplementedError
+ end
+
+ # dump task backup to `path`
+ def dump(path)
+ raise NotImplementedError
+ end
+
+ # restore task backup from `path`
+ def restore(path)
+ raise NotImplementedError
+ end
+
+ # a string returned here will be displayed to the user before calling #restore
+ def pre_restore_warning
+ end
+
+ # a string returned here will be displayed to the user after calling #restore
+ def post_restore_warning
+ end
+
+ # returns `true` when the task should be used
+ def enabled
+ true
+ end
+
+ private
+
+ attr_reader :progress
+
+ def puts_time(msg)
+ progress.puts "#{Time.zone.now} -- #{msg}"
+ Gitlab::BackupLogger.info(message: "#{Rainbow.uncolor(msg)}")
+ end
+ end
+end
diff --git a/lib/backup/terraform_state.rb b/lib/backup/terraform_state.rb
index be82793fe03..05f61d248be 100644
--- a/lib/backup/terraform_state.rb
+++ b/lib/backup/terraform_state.rb
@@ -2,14 +2,11 @@
module Backup
class TerraformState < Backup::Files
- attr_reader :progress
-
def initialize(progress)
- @progress = progress
-
- super('terraform_state', Settings.terraform_state.storage_path, excludes: ['tmp'])
+ super(progress, 'terraform_state', Settings.terraform_state.storage_path, excludes: ['tmp'])
end
+ override :human_name
def human_name
_('terraform states')
end
diff --git a/lib/backup/uploads.rb b/lib/backup/uploads.rb
index 7048a9a8ff5..700f2af4415 100644
--- a/lib/backup/uploads.rb
+++ b/lib/backup/uploads.rb
@@ -2,14 +2,11 @@
module Backup
class Uploads < Backup::Files
- attr_reader :progress
-
def initialize(progress)
- @progress = progress
-
- super('uploads', File.join(Gitlab.config.uploads.storage_path, "uploads"), excludes: ['tmp'])
+ super(progress, 'uploads', File.join(Gitlab.config.uploads.storage_path, "uploads"), excludes: ['tmp'])
end
+ override :human_name
def human_name
_('uploads')
end
diff --git a/lib/banzai/filter/front_matter_filter.rb b/lib/banzai/filter/front_matter_filter.rb
index 705400a5497..c788137e122 100644
--- a/lib/banzai/filter/front_matter_filter.rb
+++ b/lib/banzai/filter/front_matter_filter.rb
@@ -9,7 +9,10 @@ module Banzai
html.sub(Gitlab::FrontMatter::PATTERN) do |_match|
lang = $~[:lang].presence || lang_mapping[$~[:delim]]
- ["```#{lang}:frontmatter", $~[:front_matter].strip!, "```", "\n"].join("\n")
+ before = $~[:before]
+ before = "\n#{before}" if $~[:encoding].presence
+
+ "#{before}```#{lang}:frontmatter\n#{$~[:front_matter]}```\n"
end
end
end
diff --git a/lib/banzai/filter/image_link_filter.rb b/lib/banzai/filter/image_link_filter.rb
index ed0a01e6277..44acc7805b4 100644
--- a/lib/banzai/filter/image_link_filter.rb
+++ b/lib/banzai/filter/image_link_filter.rb
@@ -8,11 +8,17 @@ module Banzai
# Find every image that isn't already wrapped in an `a` tag, create
# a new node (a link to the image source), copy the image as a child
# of the anchor, and then replace the img with the link-wrapped version.
+ #
+ # If `link_replaces_image` context parameter is provided, the image is going
+ # to be replaced with a link to an image.
def call
doc.xpath('descendant-or-self::img[not(ancestor::a)]').each do |img|
+ link_replaces_image = !!context[:link_replaces_image]
+ html_class = link_replaces_image ? 'with-attachment-icon' : 'no-attachment-icon'
+
link = doc.document.create_element(
'a',
- class: 'no-attachment-icon',
+ class: html_class,
href: img['data-src'] || img['src'],
target: '_blank',
rel: 'noopener noreferrer'
@@ -21,7 +27,11 @@ module Banzai
# make sure the original non-proxied src carries over to the link
link['data-canonical-src'] = img['data-canonical-src'] if img['data-canonical-src']
- link.children = img.clone
+ link.children = if link_replaces_image
+ img['alt'] || img['data-src'] || img['src']
+ else
+ img.clone
+ end
img.replace(link)
end
diff --git a/lib/banzai/filter/task_list_filter.rb b/lib/banzai/filter/task_list_filter.rb
index c6b402575cb..896f67cb875 100644
--- a/lib/banzai/filter/task_list_filter.rb
+++ b/lib/banzai/filter/task_list_filter.rb
@@ -9,6 +9,9 @@ require 'task_list/filter'
module Banzai
module Filter
class TaskListFilter < TaskList::Filter
+ def render_item_checkbox(item)
+ "<task-button></task-button>#{super}"
+ end
end
end
end
diff --git a/lib/bulk_imports/clients/http.rb b/lib/bulk_imports/clients/http.rb
index eb3d551d1d7..037da5e0816 100644
--- a/lib/bulk_imports/clients/http.rb
+++ b/lib/bulk_imports/clients/http.rb
@@ -123,7 +123,7 @@ module BulkImports
def with_error_handling
response = yield
- raise ::BulkImports::NetworkError.new("Unsuccessful response #{response.code} from #{response.request.path.path}", response: response) unless response.success?
+ raise ::BulkImports::NetworkError.new("Unsuccessful response #{response.code} from #{response.request.path.path}. Body: #{response.parsed_response}", response: response) unless response.success?
response
rescue *Gitlab::HTTP::HTTP_ERRORS => e
diff --git a/lib/container_registry/client.rb b/lib/container_registry/client.rb
index add238350dd..4b2250d089d 100644
--- a/lib/container_registry/client.rb
+++ b/lib/container_registry/client.rb
@@ -10,6 +10,21 @@ module ContainerRegistry
REGISTRY_FEATURES_HEADER = 'gitlab-container-registry-features'
REGISTRY_TAG_DELETE_FEATURE = 'tag_delete'
+ ALLOWED_REDIRECT_SCHEMES = %w[http https].freeze
+ REDIRECT_OPTIONS = {
+ clear_authorization_header: true,
+ limit: 3,
+ cookies: [],
+ callback: -> (response_env, request_env) do
+ request_env.request_headers.delete(::FaradayMiddleware::FollowRedirects::AUTH_HEADER)
+
+ redirect_to = request_env.url
+ unless redirect_to.scheme.in?(ALLOWED_REDIRECT_SCHEMES)
+ raise ArgumentError, "Invalid scheme for #{redirect_to}"
+ end
+ end
+ }.freeze
+
def self.supports_tag_delete?
with_dummy_client(return_value_if_disabled: false) do |client|
client.supports_tag_delete?
@@ -136,6 +151,10 @@ module ContainerRegistry
def faraday_blob
@faraday_blob ||= faraday_base do |conn|
initialize_connection(conn, @options)
+
+ if Feature.enabled?(:container_registry_follow_redirects_middleware, default_enabled: :yaml)
+ conn.use ::FaradayMiddleware::FollowRedirects, REDIRECT_OPTIONS
+ end
end
end
end
diff --git a/lib/container_registry/gitlab_api_client.rb b/lib/container_registry/gitlab_api_client.rb
index 20b8e1d419b..3cd7003d1f8 100644
--- a/lib/container_registry/gitlab_api_client.rb
+++ b/lib/container_registry/gitlab_api_client.rb
@@ -31,8 +31,10 @@ module ContainerRegistry
registry_features = Gitlab::CurrentSettings.container_registry_features || []
next true if ::Gitlab.com? && registry_features.include?(REGISTRY_GITLAB_V1_API_FEATURE)
- response = faraday.get('/gitlab/v1/')
- response.success? || response.status == 401
+ with_token_faraday do |faraday_client|
+ response = faraday_client.get('/gitlab/v1/')
+ response.success? || response.status == 401
+ end
end
end
@@ -50,15 +52,46 @@ module ContainerRegistry
# https://gitlab.com/gitlab-org/container-registry/-/blob/master/docs-gitlab/api.md#get-repository-import-status
def import_status(path)
- body_hash = response_body(faraday.get(import_url_for(path)))
- body_hash['status'] || 'error'
+ with_import_token_faraday do |faraday_client|
+ body_hash = response_body(faraday_client.get(import_url_for(path)))
+ body_hash['status'] || 'error'
+ end
+ end
+
+ def repository_details(path, with_size: false)
+ with_token_faraday do |faraday_client|
+ req = faraday_client.get("/gitlab/v1/repositories/#{path}/") do |req|
+ req.params['size'] = 'self' if with_size
+ end
+
+ break {} unless req.success?
+
+ response_body(req)
+ end
end
private
def start_import_for(path, pre:)
- faraday.put(import_url_for(path)) do |req|
- req.params['pre'] = pre.to_s
+ with_import_token_faraday do |faraday_client|
+ faraday_client.put(import_url_for(path)) do |req|
+ req.params['import_type'] = pre ? 'pre' : 'final'
+ end
+ end
+ end
+
+ def with_token_faraday
+ yield faraday
+ end
+
+ def with_import_token_faraday
+ yield faraday_with_import_token
+ end
+
+ def faraday_with_import_token(timeout_enabled: true)
+ @faraday_with_import_token ||= faraday_base(timeout_enabled: timeout_enabled) do |conn|
+ # initialize the connection with the :import_token instead of :token
+ initialize_connection(conn, @options.merge(token: @options[:import_token]), &method(:configure_connection))
end
end
diff --git a/lib/container_registry/registry.rb b/lib/container_registry/registry.rb
index 710f8169a00..b377f7d0ac3 100644
--- a/lib/container_registry/registry.rb
+++ b/lib/container_registry/registry.rb
@@ -2,26 +2,16 @@
module ContainerRegistry
class Registry
- include Gitlab::Utils::StrongMemoize
-
- attr_reader :uri, :client, :path
+ attr_reader :uri, :client, :gitlab_api_client, :path
def initialize(uri, options = {})
@uri = uri
@options = options
@path = @options[:path] || default_path
@client = ContainerRegistry::Client.new(@uri, @options)
- end
-
- def gitlab_api_client
- strong_memoize(:gitlab_api_client) do
- token = Auth::ContainerRegistryAuthenticationService.import_access_token
-
- url = Gitlab.config.registry.api_url
- host_port = Gitlab.config.registry.host_port
- ContainerRegistry::GitlabApiClient.new(url, token: token, path: host_port)
- end
+ import_token = Auth::ContainerRegistryAuthenticationService.import_access_token
+ @gitlab_api_client = ContainerRegistry::GitlabApiClient.new(@uri, @options.merge(import_token: import_token))
end
private
diff --git a/lib/container_registry/tag.rb b/lib/container_registry/tag.rb
index 2a32f950457..04a8e1d2e8f 100644
--- a/lib/container_registry/tag.rb
+++ b/lib/container_registry/tag.rb
@@ -104,7 +104,7 @@ module ContainerRegistry
def total_size
return unless layers
- layers.map(&:size).sum if v2?
+ layers.sum(&:size) if v2?
end
# rubocop: enable CodeReuse/ActiveRecord
diff --git a/lib/gitlab.rb b/lib/gitlab.rb
index 2449554d3c0..d33120575a2 100644
--- a/lib/gitlab.rb
+++ b/lib/gitlab.rb
@@ -49,9 +49,15 @@ module Gitlab
INSTALLATION_TYPE = File.read(root.join("INSTALLATION_TYPE")).strip.freeze
HTTP_PROXY_ENV_VARS = %w(http_proxy https_proxy HTTP_PROXY HTTPS_PROXY).freeze
+ def self.simulate_com?
+ return false unless Rails.env.development?
+
+ Gitlab::Utils.to_boolean(ENV['GITLAB_SIMULATE_SAAS'])
+ end
+
def self.com?
# Check `gl_subdomain?` as well to keep parity with gitlab.com
- Gitlab.config.gitlab.url == Gitlab::Saas.com_url || gl_subdomain?
+ simulate_com? || Gitlab.config.gitlab.url == Gitlab::Saas.com_url || gl_subdomain?
end
def self.com
@@ -82,12 +88,8 @@ module Gitlab
Gitlab::Saas.subdomain_regex === Gitlab.config.gitlab.url
end
- def self.dev_env_org_or_com?
- dev_env_or_com? || org?
- end
-
- def self.dev_env_or_com?
- Rails.env.development? || com?
+ def self.org_or_com?
+ org? || com?
end
def self.dev_or_test_env?
diff --git a/lib/gitlab/analytics/cycle_analytics/request_params.rb b/lib/gitlab/analytics/cycle_analytics/request_params.rb
index bc9d94ef09c..af695c5cfa4 100644
--- a/lib/gitlab/analytics/cycle_analytics/request_params.rb
+++ b/lib/gitlab/analytics/cycle_analytics/request_params.rb
@@ -80,12 +80,13 @@ module Gitlab
direction: direction&.to_sym,
page: page,
end_event_filter: end_event_filter.to_sym,
- use_aggregated_data_collector: Feature.enabled?(:use_vsa_aggregated_tables, group || project, default_enabled: :yaml)
+ use_aggregated_data_collector: use_aggregated_backend?
}.merge(attributes.symbolize_keys.slice(*FINDER_PARAM_NAMES))
end
def to_data_attributes
{}.tap do |attrs|
+ attrs[:aggregation] = aggregation_attributes if group
attrs[:group] = group_data_attributes if group
attrs[:value_stream] = value_stream_data_attributes.to_json if value_stream
attrs[:created_after] = created_after.to_date.iso8601
@@ -103,6 +104,24 @@ module Gitlab
private
+ def use_aggregated_backend?
+ group.present? && # for now it's only available on the group-level
+ aggregation.enabled &&
+ Feature.enabled?(:use_vsa_aggregated_tables, group, default_enabled: :yaml)
+ end
+
+ def aggregation_attributes
+ {
+ enabled: aggregation.enabled.to_s,
+ last_run_at: aggregation.last_incremental_run_at&.iso8601,
+ next_run_at: aggregation.estimated_next_run_at&.iso8601
+ }
+ end
+
+ def aggregation
+ @aggregation ||= ::Analytics::CycleAnalytics::Aggregation.safe_create_for_group(group)
+ end
+
def group_data_attributes
{
id: group.id,
diff --git a/lib/gitlab/application_rate_limiter.rb b/lib/gitlab/application_rate_limiter.rb
index d2a31938e89..0b0aaacbaff 100644
--- a/lib/gitlab/application_rate_limiter.rb
+++ b/lib/gitlab/application_rate_limiter.rb
@@ -39,7 +39,8 @@ module Gitlab
profile_update_username: { threshold: 10, interval: 1.minute },
update_environment_canary_ingress: { threshold: 1, interval: 1.minute },
auto_rollback_deployment: { threshold: 1, interval: 3.minutes },
- user_email_lookup: { threshold: -> { application_settings.user_email_lookup_limit }, interval: 1.minute },
+ search_rate_limit: { threshold: -> { application_settings.search_rate_limit }, interval: 1.minute },
+ search_rate_limit_unauthenticated: { threshold: -> { application_settings.search_rate_limit_unauthenticated }, interval: 1.minute },
gitlab_shell_operation: { threshold: 600, interval: 1.minute }
}.freeze
end
diff --git a/lib/gitlab/auth/auth_finders.rb b/lib/gitlab/auth/auth_finders.rb
index ecda96af403..7adaaef86e4 100644
--- a/lib/gitlab/auth/auth_finders.rb
+++ b/lib/gitlab/auth/auth_finders.rb
@@ -12,6 +12,7 @@ module Gitlab
class InsufficientScopeError < AuthenticationError
attr_reader :scopes
+
def initialize(scopes)
@scopes = scopes.map { |s| s.try(:name) || s }
end
diff --git a/lib/gitlab/auth/ldap/user.rb b/lib/gitlab/auth/ldap/user.rb
index d134350775d..56c2af1910e 100644
--- a/lib/gitlab/auth/ldap/user.rb
+++ b/lib/gitlab/auth/ldap/user.rb
@@ -11,9 +11,6 @@ module Gitlab
module Ldap
class User < Gitlab::Auth::OAuth::User
extend ::Gitlab::Utils::Override
- def save
- super('LDAP')
- end
# instance methods
def find_user
@@ -44,6 +41,10 @@ module Gitlab
def auth_hash=(auth_hash)
@auth_hash = Gitlab::Auth::Ldap::AuthHash.new(auth_hash)
end
+
+ def protocol_name
+ 'LDAP'
+ end
end
end
end
diff --git a/lib/gitlab/auth/o_auth/auth_hash.rb b/lib/gitlab/auth/o_auth/auth_hash.rb
index 2ec75669d24..a45778159c7 100644
--- a/lib/gitlab/auth/o_auth/auth_hash.rb
+++ b/lib/gitlab/auth/o_auth/auth_hash.rb
@@ -7,6 +7,7 @@ module Gitlab
module OAuth
class AuthHash
attr_reader :auth_hash
+
def initialize(auth_hash)
@auth_hash = auth_hash
end
diff --git a/lib/gitlab/auth/o_auth/user.rb b/lib/gitlab/auth/o_auth/user.rb
index 9f142727ebb..200f1a843e6 100644
--- a/lib/gitlab/auth/o_auth/user.rb
+++ b/lib/gitlab/auth/o_auth/user.rb
@@ -46,7 +46,7 @@ module Gitlab
valid? && persisted?
end
- def save(provider = 'OAuth')
+ def save(provider = protocol_name)
raise SigninDisabledForProviderError if oauth_provider_disabled?
raise SignupDisabledError unless gl_user
@@ -55,6 +55,7 @@ module Gitlab
Users::UpdateService.new(gl_user, user: gl_user).execute!
gl_user.block_pending_approval if block_after_save
+ activate_user_if_user_cap_not_reached
log.info "(#{provider}) saving user #{auth_hash.email} from login with admin => #{gl_user.admin}, extern_uid => #{auth_hash.uid}"
gl_user
@@ -96,8 +97,16 @@ module Gitlab
end
end
+ def protocol_name
+ 'OAuth'
+ end
+
protected
+ def activate_user_if_user_cap_not_reached
+ nil
+ end
+
def should_save?
true
end
diff --git a/lib/gitlab/auth/request_authenticator.rb b/lib/gitlab/auth/request_authenticator.rb
index b6ed6bbf2df..0948663b4b3 100644
--- a/lib/gitlab/auth/request_authenticator.rb
+++ b/lib/gitlab/auth/request_authenticator.rb
@@ -42,6 +42,10 @@ module Gitlab
nil
end
+ def can_sign_in_bot?(user)
+ user&.project_bot? && api_request?
+ end
+
# To prevent Rack Attack from incorrectly rate limiting
# authenticated Git activity, we need to authenticate the user
# from other means (e.g. HTTP Basic Authentication) only if the
diff --git a/lib/gitlab/auth/saml/user.rb b/lib/gitlab/auth/saml/user.rb
index 205d5fe0015..d14da41deb6 100644
--- a/lib/gitlab/auth/saml/user.rb
+++ b/lib/gitlab/auth/saml/user.rb
@@ -11,10 +11,6 @@ module Gitlab
class User < Gitlab::Auth::OAuth::User
extend ::Gitlab::Utils::Override
- def save
- super('SAML')
- end
-
def find_user
user = find_by_uid_and_provider
@@ -40,6 +36,10 @@ module Gitlab
saml_config.upstream_two_factor_authn_contexts&.include?(auth_hash.authn_context)
end
+ def protocol_name
+ 'SAML'
+ end
+
protected
def saml_config
diff --git a/lib/gitlab/background_migration/backfill_issue_search_data.rb b/lib/gitlab/background_migration/backfill_issue_search_data.rb
new file mode 100644
index 00000000000..ec206cbfd41
--- /dev/null
+++ b/lib/gitlab/background_migration/backfill_issue_search_data.rb
@@ -0,0 +1,63 @@
+# frozen_string_literal: true
+# rubocop:disable Style/Documentation
+
+module Gitlab
+ module BackgroundMigration
+ # Backfills the new `issue_search_data` table, which contains
+ # the tsvector from the issue title and description.
+ class BackfillIssueSearchData
+ include Gitlab::Database::DynamicModelHelpers
+
+ def perform(start_id, stop_id, batch_table, batch_column, sub_batch_size, pause_ms)
+ define_batchable_model(batch_table, connection: ActiveRecord::Base.connection).where(batch_column => start_id..stop_id).each_batch(of: sub_batch_size) do |sub_batch|
+ update_search_data(sub_batch)
+
+ sleep(pause_ms * 0.001)
+ rescue ActiveRecord::StatementInvalid => e
+ raise unless e.cause.is_a?(PG::ProgramLimitExceeded) && e.message.include?('string is too long for tsvector')
+
+ update_search_data_individually(sub_batch, pause_ms)
+ end
+ end
+
+ private
+
+ def update_search_data(relation)
+ relation.klass.connection.execute(
+ <<~SQL
+ INSERT INTO issue_search_data (project_id, issue_id, search_vector, created_at, updated_at)
+ SELECT
+ project_id,
+ id,
+ setweight(to_tsvector('english', LEFT(title, 255)), 'A') || setweight(to_tsvector('english', LEFT(REGEXP_REPLACE(description, '[A-Za-z0-9+/@]{50,}', ' ', 'g'), 1048576)), 'B'),
+ NOW(),
+ NOW()
+ FROM issues
+ WHERE issues.id IN (#{relation.select(:id).to_sql})
+ ON CONFLICT DO NOTHING
+ SQL
+ )
+ end
+
+ def update_search_data_individually(relation, pause_ms)
+ relation.pluck(:id).each do |issue_id|
+ update_search_data(relation.klass.where(id: issue_id))
+
+ sleep(pause_ms * 0.001)
+ rescue ActiveRecord::StatementInvalid => e
+ raise unless e.cause.is_a?(PG::ProgramLimitExceeded) && e.message.include?('string is too long for tsvector')
+
+ logger.error(
+ message: 'Error updating search data: string is too long for tsvector',
+ class: relation.klass.name,
+ model_id: issue_id
+ )
+ end
+ end
+
+ def logger
+ @logger ||= Gitlab::BackgroundMigration::Logger.build
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/background_migration/backfill_jira_tracker_deployment_type2.rb b/lib/gitlab/background_migration/backfill_jira_tracker_deployment_type2.rb
index 61145f6a445..669e5338dd1 100644
--- a/lib/gitlab/background_migration/backfill_jira_tracker_deployment_type2.rb
+++ b/lib/gitlab/background_migration/backfill_jira_tracker_deployment_type2.rb
@@ -79,7 +79,7 @@ module Gitlab
end
def mark_jobs_as_succeeded(*arguments)
- Gitlab::Database::BackgroundMigrationJob.mark_all_as_succeeded(self.class.name, arguments)
+ Gitlab::Database::BackgroundMigrationJob.mark_all_as_succeeded(self.class.name.demodulize, arguments)
end
end
end
diff --git a/lib/gitlab/background_migration/backfill_member_namespace_for_group_members.rb b/lib/gitlab/background_migration/backfill_member_namespace_for_group_members.rb
new file mode 100644
index 00000000000..1ed147d67c7
--- /dev/null
+++ b/lib/gitlab/background_migration/backfill_member_namespace_for_group_members.rb
@@ -0,0 +1,38 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module BackgroundMigration
+ # Backfills the `members.member_namespace_id` column for `type=GroupMember`
+ class BackfillMemberNamespaceForGroupMembers
+ include Gitlab::Database::DynamicModelHelpers
+
+ def perform(start_id, end_id, batch_table, batch_column, sub_batch_size, pause_ms)
+ parent_batch_relation = relation_scoped_to_range(batch_table, batch_column, start_id, end_id)
+
+ parent_batch_relation.each_batch(column: batch_column, of: sub_batch_size) do |sub_batch|
+ batch_metrics.time_operation(:update_all) do
+ sub_batch.update_all('member_namespace_id=source_id')
+ end
+
+ pause_ms = [0, pause_ms].max
+ sleep(pause_ms * 0.001)
+ end
+ end
+
+ def batch_metrics
+ @batch_metrics ||= Gitlab::Database::BackgroundMigration::BatchMetrics.new
+ end
+
+ private
+
+ def relation_scoped_to_range(source_table, source_key_column, start_id, stop_id)
+ define_batchable_model(source_table, connection: ActiveRecord::Base.connection)
+ .joins('INNER JOIN namespaces ON members.source_id = namespaces.id')
+ .where(source_key_column => start_id..stop_id)
+ .where(type: 'GroupMember')
+ .where(source_type: 'Namespace')
+ .where(member_namespace_id: nil)
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/background_migration/batching_strategies/base_strategy.rb b/lib/gitlab/background_migration/batching_strategies/base_strategy.rb
new file mode 100644
index 00000000000..37bddea4f61
--- /dev/null
+++ b/lib/gitlab/background_migration/batching_strategies/base_strategy.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module BackgroundMigration
+ module BatchingStrategies
+ # Simple base class for batching strategy job classes.
+ #
+ # Any strategy class that inherits from the base class will have connection to the tracking database set on
+ # initialization.
+ class BaseStrategy
+ def initialize(connection:)
+ @connection = connection
+ end
+
+ def next_batch(*arguments)
+ raise NotImplementedError,
+ "#{self.class} does not implement #{__method__}"
+ end
+
+ private
+
+ attr_reader :connection
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/background_migration/batching_strategies/primary_key_batching_strategy.rb b/lib/gitlab/background_migration/batching_strategies/primary_key_batching_strategy.rb
index 09700438d47..5569bac0e19 100644
--- a/lib/gitlab/background_migration/batching_strategies/primary_key_batching_strategy.rb
+++ b/lib/gitlab/background_migration/batching_strategies/primary_key_batching_strategy.rb
@@ -8,7 +8,7 @@ module Gitlab
# values for the next batch as an array.
#
# If no more batches exist in the table, returns nil.
- class PrimaryKeyBatchingStrategy
+ class PrimaryKeyBatchingStrategy < BaseStrategy
include Gitlab::Database::DynamicModelHelpers
# Finds and returns the next batch in the table.
@@ -19,7 +19,7 @@ module Gitlab
# batch_size - The size of the next batch
# job_arguments - The migration job arguments
def next_batch(table_name, column_name, batch_min_value:, batch_size:, job_arguments:)
- model_class = define_batchable_model(table_name, connection: ActiveRecord::Base.connection)
+ model_class = define_batchable_model(table_name, connection: connection)
quoted_column_name = model_class.connection.quote_column_name(column_name)
relation = model_class.where("#{quoted_column_name} >= ?", batch_min_value)
diff --git a/lib/gitlab/background_migration/encrypt_integration_properties.rb b/lib/gitlab/background_migration/encrypt_integration_properties.rb
new file mode 100644
index 00000000000..3843356af69
--- /dev/null
+++ b/lib/gitlab/background_migration/encrypt_integration_properties.rb
@@ -0,0 +1,84 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module BackgroundMigration
+ # Migrates the integration.properties column from plaintext to encrypted text.
+ class EncryptIntegrationProperties
+ # The Integration model, with just the relevant bits.
+ class Integration < ActiveRecord::Base
+ include EachBatch
+
+ ALGORITHM = 'aes-256-gcm'
+
+ self.table_name = 'integrations'
+ self.inheritance_column = :_type_disabled
+
+ scope :with_properties, -> { where.not(properties: nil) }
+ scope :not_already_encrypted, -> { where(encrypted_properties: nil) }
+ scope :for_batch, ->(range) { where(id: range) }
+
+ attr_encrypted :encrypted_properties_tmp,
+ attribute: :encrypted_properties,
+ mode: :per_attribute_iv,
+ key: ::Settings.attr_encrypted_db_key_base_32,
+ algorithm: ALGORITHM,
+ marshal: true,
+ marshaler: ::Gitlab::Json,
+ encode: false,
+ encode_iv: false
+
+ # See 'Integration#reencrypt_properties'
+ def encrypt_properties
+ data = ::Gitlab::Json.parse(properties)
+ iv = generate_iv(ALGORITHM)
+ ep = self.class.encrypt(:encrypted_properties_tmp, data, { iv: iv })
+
+ [ep, iv]
+ end
+ end
+
+ def perform(start_id, stop_id)
+ batch_query = Integration.with_properties.not_already_encrypted.for_batch(start_id..stop_id)
+ encrypt_batch(batch_query)
+ mark_job_as_succeeded(start_id, stop_id)
+ end
+
+ private
+
+ def mark_job_as_succeeded(*arguments)
+ Gitlab::Database::BackgroundMigrationJob.mark_all_as_succeeded(
+ self.class.name.demodulize,
+ arguments
+ )
+ end
+
+ # represent binary string as a PSQL binary literal:
+ # https://www.postgresql.org/docs/9.4/datatype-binary.html
+ def bytea(value)
+ "'\\x#{value.unpack1('H*')}'::bytea"
+ end
+
+ def encrypt_batch(batch_query)
+ values = batch_query.select(:id, :properties).map do |record|
+ encrypted_properties, encrypted_properties_iv = record.encrypt_properties
+ "(#{record.id}, #{bytea(encrypted_properties)}, #{bytea(encrypted_properties_iv)})"
+ end
+
+ return if values.empty?
+
+ Integration.connection.execute(<<~SQL.squish)
+ WITH cte(cte_id, cte_encrypted_properties, cte_encrypted_properties_iv)
+ AS #{::Gitlab::Database::AsWithMaterialized.materialized_if_supported} (
+ SELECT *
+ FROM (VALUES #{values.join(',')}) AS t (id, encrypted_properties, encrypted_properties_iv)
+ )
+ UPDATE #{Integration.table_name}
+ SET encrypted_properties = cte_encrypted_properties
+ , encrypted_properties_iv = cte_encrypted_properties_iv
+ FROM cte
+ WHERE cte_id = id
+ SQL
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/background_migration/fix_vulnerability_occurrences_with_hashes_as_raw_metadata.rb b/lib/gitlab/background_migration/fix_vulnerability_occurrences_with_hashes_as_raw_metadata.rb
index 2b049ea2d2f..a34e923545c 100644
--- a/lib/gitlab/background_migration/fix_vulnerability_occurrences_with_hashes_as_raw_metadata.rb
+++ b/lib/gitlab/background_migration/fix_vulnerability_occurrences_with_hashes_as_raw_metadata.rb
@@ -59,7 +59,7 @@ module Gitlab
private
def mark_job_as_succeeded(*arguments)
- Gitlab::Database::BackgroundMigrationJob.mark_all_as_succeeded(
+ ::Gitlab::Database::BackgroundMigrationJob.mark_all_as_succeeded(
'FixVulnerabilityOccurrencesWithHashesAsRawMetadata',
arguments
)
diff --git a/lib/gitlab/background_migration/job_coordinator.rb b/lib/gitlab/background_migration/job_coordinator.rb
index b7d47c389df..acbb5f76ad8 100644
--- a/lib/gitlab/background_migration/job_coordinator.rb
+++ b/lib/gitlab/background_migration/job_coordinator.rb
@@ -50,34 +50,41 @@ module Gitlab
Gitlab::Database::SharedModel.using_connection(connection, &block)
end
- def steal(steal_class, retry_dead_jobs: false)
- with_shared_connection do
+ def pending_jobs(include_dead_jobs: false)
+ Enumerator.new do |y|
queues = [
Sidekiq::ScheduledSet.new,
Sidekiq::Queue.new(self.queue)
]
- if retry_dead_jobs
+ if include_dead_jobs
queues << Sidekiq::RetrySet.new
queues << Sidekiq::DeadSet.new
end
queues.each do |queue|
queue.each do |job|
- migration_class, migration_args = job.args
+ y << job if job.klass == worker_class.name
+ end
+ end
+ end
+ end
+
+ def steal(steal_class, retry_dead_jobs: false)
+ with_shared_connection do
+ pending_jobs(include_dead_jobs: retry_dead_jobs).each do |job|
+ migration_class, migration_args = job.args
- next unless job.klass == worker_class.name
- next unless migration_class == steal_class
- next if block_given? && !(yield job)
+ next unless migration_class == steal_class
+ next if block_given? && !(yield job)
- begin
- perform(migration_class, migration_args) if job.delete
- rescue Exception # rubocop:disable Lint/RescueException
- worker_class # enqueue this migration again
- .perform_async(migration_class, migration_args)
+ begin
+ perform(migration_class, migration_args) if job.delete
+ rescue Exception # rubocop:disable Lint/RescueException
+ worker_class # enqueue this migration again
+ .perform_async(migration_class, migration_args)
- raise
- end
+ raise
end
end
end
diff --git a/lib/gitlab/background_migration/migrate_personal_namespace_project_maintainer_to_owner.rb b/lib/gitlab/background_migration/migrate_personal_namespace_project_maintainer_to_owner.rb
new file mode 100644
index 00000000000..49eff6e2771
--- /dev/null
+++ b/lib/gitlab/background_migration/migrate_personal_namespace_project_maintainer_to_owner.rb
@@ -0,0 +1,45 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module BackgroundMigration
+ # Migrates personal namespace project `maintainer` memberships (for the associated user only) to OWNER
+ # Does not create any missing records, simply migrates existing ones
+ class MigratePersonalNamespaceProjectMaintainerToOwner
+ include Gitlab::Database::DynamicModelHelpers
+
+ def perform(start_id, end_id, batch_table, batch_column, sub_batch_size, pause_ms)
+ parent_batch_relation = relation_scoped_to_range(batch_table, batch_column, start_id, end_id)
+
+ parent_batch_relation.each_batch(column: batch_column, of: sub_batch_size) do |sub_batch|
+ batch_metrics.time_operation(:update_all) do
+ sub_batch.update_all('access_level = 50')
+ end
+
+ pause_ms = 0 if pause_ms < 0
+ sleep(pause_ms * 0.001)
+ end
+ end
+
+ def batch_metrics
+ @batch_metrics ||= Gitlab::Database::BackgroundMigration::BatchMetrics.new
+ end
+
+ private
+
+ def relation_scoped_to_range(source_table, source_key_column, start_id, stop_id)
+ # members of projects within their own personal namespace
+
+ # rubocop: disable CodeReuse/ActiveRecord
+ define_batchable_model(:members, connection: ApplicationRecord.connection)
+ .where(source_key_column => start_id..stop_id)
+ .joins("INNER JOIN projects ON members.source_id = projects.id")
+ .joins("INNER JOIN namespaces ON projects.namespace_id = namespaces.id")
+ .where(type: 'ProjectMember')
+ .where("namespaces.type = 'User'")
+ .where('members.access_level < 50')
+ .where('namespaces.owner_id = members.user_id')
+ end
+ end
+ # rubocop: enable CodeReuse/ActiveRecord
+ end
+end
diff --git a/lib/gitlab/background_migration/nullify_orphan_runner_id_on_ci_builds.rb b/lib/gitlab/background_migration/nullify_orphan_runner_id_on_ci_builds.rb
new file mode 100644
index 00000000000..78e897d9ae1
--- /dev/null
+++ b/lib/gitlab/background_migration/nullify_orphan_runner_id_on_ci_builds.rb
@@ -0,0 +1,40 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module BackgroundMigration
+ # A job to nullify orphan runner_id on ci_builds table
+ class NullifyOrphanRunnerIdOnCiBuilds
+ include Gitlab::Database::DynamicModelHelpers
+
+ def perform(start_id, end_id, batch_table, batch_column, sub_batch_size, pause_ms)
+ pause_ms = 0 if pause_ms < 0
+
+ batch_relation = relation_scoped_to_range(batch_table, batch_column, start_id, end_id)
+ batch_relation.each_batch(column: batch_column, of: sub_batch_size, order_hint: :type) do |sub_batch|
+ batch_metrics.time_operation(:update_all) do
+ sub_batch.update_all(runner_id: nil)
+ end
+
+ sleep(pause_ms * 0.001)
+ end
+ end
+
+ def batch_metrics
+ @batch_metrics ||= Gitlab::Database::BackgroundMigration::BatchMetrics.new
+ end
+
+ private
+
+ def connection
+ ActiveRecord::Base.connection
+ end
+
+ def relation_scoped_to_range(source_table, source_key_column, start_id, stop_id)
+ define_batchable_model(source_table, connection: connection)
+ .joins('LEFT OUTER JOIN ci_runners ON ci_runners.id = ci_builds.runner_id')
+ .where('ci_builds.runner_id IS NOT NULL AND ci_runners.id IS NULL')
+ .where(source_key_column => start_id..stop_id)
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/background_migration/project_namespaces/backfill_project_namespaces.rb b/lib/gitlab/background_migration/project_namespaces/backfill_project_namespaces.rb
index ba3f7c47047..c34cc57ce60 100644
--- a/lib/gitlab/background_migration/project_namespaces/backfill_project_namespaces.rb
+++ b/lib/gitlab/background_migration/project_namespaces/backfill_project_namespaces.rb
@@ -34,8 +34,11 @@ module Gitlab
def backfill_project_namespaces(namespace_id)
project_ids.each_slice(sub_batch_size) do |project_ids|
- ActiveRecord::Base.connection.execute("select gin_clean_pending_list('index_namespaces_on_name_trigram')")
- ActiveRecord::Base.connection.execute("select gin_clean_pending_list('index_namespaces_on_path_trigram')")
+ # cleanup gin indexes on namespaces table
+ cleanup_gin_index('namespaces')
+
+ # cleanup gin indexes on projects table
+ cleanup_gin_index('projects')
# We need to lock these project records for the period when we create project namespaces
# and link them to projects so that if a project is modified in the time between creating
@@ -53,6 +56,14 @@ module Gitlab
end
end
+ def cleanup_gin_index(table_name)
+ index_names = ActiveRecord::Base.connection.select_values("select indexname::text from pg_indexes where tablename = '#{table_name}' and indexdef ilike '%gin%'")
+
+ index_names.each do |index_name|
+ ActiveRecord::Base.connection.execute("select gin_clean_pending_list('#{index_name}')")
+ end
+ end
+
def cleanup_backfilled_project_namespaces(namespace_id)
project_ids.each_slice(sub_batch_size) do |project_ids|
# IMPORTANT: first nullify project_namespace_id in projects table to avoid removing projects when records
diff --git a/lib/gitlab/background_migration/remove_all_trace_expiration_dates.rb b/lib/gitlab/background_migration/remove_all_trace_expiration_dates.rb
new file mode 100644
index 00000000000..d47aa76f24b
--- /dev/null
+++ b/lib/gitlab/background_migration/remove_all_trace_expiration_dates.rb
@@ -0,0 +1,53 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module BackgroundMigration
+ # Removing expire_at timestamps that shouldn't have
+ # been written to traces on gitlab.com.
+ class RemoveAllTraceExpirationDates
+ include Gitlab::Database::MigrationHelpers
+
+ BATCH_SIZE = 1_000
+
+ # Stubbed class to connect to the CI database
+ # connects_to has to be called in abstract classes.
+ class MultiDbAdaptableClass < ActiveRecord::Base
+ self.abstract_class = true
+
+ if Gitlab::Database.has_config?(:ci)
+ connects_to database: { writing: :ci, reading: :ci }
+ end
+ end
+
+ # Stubbed class to access the ci_job_artifacts table
+ class JobArtifact < MultiDbAdaptableClass
+ include EachBatch
+
+ self.table_name = 'ci_job_artifacts'
+
+ TARGET_TIMESTAMPS = [
+ Date.new(2021, 04, 22).midnight.utc,
+ Date.new(2021, 05, 22).midnight.utc,
+ Date.new(2021, 06, 22).midnight.utc,
+ Date.new(2022, 01, 22).midnight.utc,
+ Date.new(2022, 02, 22).midnight.utc,
+ Date.new(2022, 03, 22).midnight.utc,
+ Date.new(2022, 04, 22).midnight.utc
+ ].freeze
+
+ scope :traces, -> { where(file_type: 3) }
+ scope :between, -> (start_id, end_id) { where(id: start_id..end_id) }
+ scope :in_targeted_timestamps, -> { where(expire_at: TARGET_TIMESTAMPS) }
+ end
+
+ def perform(start_id, end_id)
+ return unless Gitlab.com?
+
+ JobArtifact.traces
+ .between(start_id, end_id)
+ .in_targeted_timestamps
+ .each_batch(of: BATCH_SIZE) { |batch| batch.update_all(expire_at: nil) }
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/background_migration/reset_duplicate_ci_runners_token_encrypted_values_on_projects.rb b/lib/gitlab/background_migration/reset_duplicate_ci_runners_token_encrypted_values_on_projects.rb
new file mode 100644
index 00000000000..80ca76ef37f
--- /dev/null
+++ b/lib/gitlab/background_migration/reset_duplicate_ci_runners_token_encrypted_values_on_projects.rb
@@ -0,0 +1,37 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module BackgroundMigration
+ # A job to nullify duplicate runners_token_encrypted values in projects table in batches
+ class ResetDuplicateCiRunnersTokenEncryptedValuesOnProjects
+ class Project < ActiveRecord::Base # rubocop:disable Style/Documentation
+ include ::EachBatch
+
+ self.table_name = 'projects'
+
+ scope :base_query, -> do
+ where.not(runners_token_encrypted: nil)
+ end
+ end
+
+ def perform(start_id, end_id)
+ # Reset duplicate runner tokens that would prevent creating an unique index.
+ duplicate_tokens = Project.base_query
+ .where(id: start_id..end_id)
+ .group(:runners_token_encrypted)
+ .having('COUNT(*) > 1')
+ .pluck(:runners_token_encrypted)
+
+ Project.where(runners_token_encrypted: duplicate_tokens).update_all(runners_token_encrypted: nil) if duplicate_tokens.any?
+
+ mark_job_as_succeeded(start_id, end_id)
+ end
+
+ private
+
+ def mark_job_as_succeeded(*arguments)
+ Gitlab::Database::BackgroundMigrationJob.mark_all_as_succeeded('ResetDuplicateCiRunnersTokenEncryptedValuesOnProjects', arguments)
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/background_migration/reset_duplicate_ci_runners_token_values_on_projects.rb b/lib/gitlab/background_migration/reset_duplicate_ci_runners_token_values_on_projects.rb
new file mode 100644
index 00000000000..d87ce6c88d3
--- /dev/null
+++ b/lib/gitlab/background_migration/reset_duplicate_ci_runners_token_values_on_projects.rb
@@ -0,0 +1,37 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module BackgroundMigration
+ # A job to nullify duplicate ci_runners_token values in projects table in batches
+ class ResetDuplicateCiRunnersTokenValuesOnProjects
+ class Project < ActiveRecord::Base # rubocop:disable Style/Documentation
+ include ::EachBatch
+
+ self.table_name = 'projects'
+
+ scope :base_query, -> do
+ where.not(runners_token: nil)
+ end
+ end
+
+ def perform(start_id, end_id)
+ # Reset duplicate runner tokens that would prevent creating an unique index.
+ duplicate_tokens = Project.base_query
+ .where(id: start_id..end_id)
+ .group(:runners_token)
+ .having('COUNT(*) > 1')
+ .pluck(:runners_token)
+
+ Project.where(runners_token: duplicate_tokens).update_all(runners_token: nil) if duplicate_tokens.any?
+
+ mark_job_as_succeeded(start_id, end_id)
+ end
+
+ private
+
+ def mark_job_as_succeeded(*arguments)
+ Gitlab::Database::BackgroundMigrationJob.mark_all_as_succeeded('ResetDuplicateCiRunnerValuesTokensOnProjects', arguments)
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/checks/base_bulk_checker.rb b/lib/gitlab/checks/base_bulk_checker.rb
index 46a68fdf485..e2a016a9907 100644
--- a/lib/gitlab/checks/base_bulk_checker.rb
+++ b/lib/gitlab/checks/base_bulk_checker.rb
@@ -4,6 +4,7 @@ module Gitlab
module Checks
class BaseBulkChecker < BaseChecker
attr_reader :changes_access
+
delegate(*ChangesAccess::ATTRIBUTES, to: :changes_access)
def initialize(changes_access)
diff --git a/lib/gitlab/checks/base_single_checker.rb b/lib/gitlab/checks/base_single_checker.rb
index 06519833d7c..435f4ccf5ba 100644
--- a/lib/gitlab/checks/base_single_checker.rb
+++ b/lib/gitlab/checks/base_single_checker.rb
@@ -4,6 +4,7 @@ module Gitlab
module Checks
class BaseSingleChecker < BaseChecker
attr_reader :change_access
+
delegate(*SingleChangeAccess::ATTRIBUTES, to: :change_access)
def initialize(change_access)
diff --git a/lib/gitlab/ci/build/policy/refs.rb b/lib/gitlab/ci/build/policy/refs.rb
index 7ade9ca5085..2e5f6611e73 100644
--- a/lib/gitlab/ci/build/policy/refs.rb
+++ b/lib/gitlab/ci/build/policy/refs.rb
@@ -36,7 +36,7 @@ module Gitlab
# the pattern matching does not work for merge requests pipelines
if pipeline.branch? || pipeline.tag?
regexp = Gitlab::UntrustedRegexp::RubySyntax
- .fabricate(pattern, fallback: true, project: pipeline.project)
+ .fabricate(pattern, project: pipeline.project)
if regexp
regexp.match?(pipeline.ref)
diff --git a/lib/gitlab/ci/config/entry/job.rb b/lib/gitlab/ci/config/entry/job.rb
index 8dd1f686132..06c81fd65dd 100644
--- a/lib/gitlab/ci/config/entry/job.rb
+++ b/lib/gitlab/ci/config/entry/job.rb
@@ -37,10 +37,12 @@ module Gitlab
next unless dependencies.present?
next unless needs_value.present?
- missing_needs = dependencies - needs_value[:job].pluck(:name) # rubocop:disable CodeReuse/ActiveRecord (Array#pluck)
+ if needs_value[:job].nil? && needs_value[:cross_dependency].present?
+ errors.add(:needs, "corresponding to dependencies must be from the same pipeline")
+ else
+ missing_needs = dependencies - needs_value[:job].pluck(:name) # rubocop:disable CodeReuse/ActiveRecord (Array#pluck)
- if missing_needs.any?
- errors.add(:dependencies, "the #{missing_needs.join(", ")} should be part of needs")
+ errors.add(:dependencies, "the #{missing_needs.join(", ")} should be part of needs") if missing_needs.any?
end
end
end
diff --git a/lib/gitlab/ci/config/entry/policy.rb b/lib/gitlab/ci/config/entry/policy.rb
index 7b14218d3ea..adc3660d950 100644
--- a/lib/gitlab/ci/config/entry/policy.rb
+++ b/lib/gitlab/ci/config/entry/policy.rb
@@ -17,7 +17,7 @@ module Gitlab
include ::Gitlab::Config::Entry::Validatable
validations do
- validates :config, array_of_strings_or_regexps_with_fallback: true
+ validates :config, array_of_strings_or_regexps: true
end
def value
@@ -38,7 +38,7 @@ module Gitlab
validate :variables_expressions_syntax
with_options allow_nil: true do
- validates :refs, array_of_strings_or_regexps_with_fallback: true
+ validates :refs, array_of_strings_or_regexps: true
validates :kubernetes, allowed_values: %w[active]
validates :variables, array_of_strings: true
validates :changes, array_of_strings: true
diff --git a/lib/gitlab/ci/config/entry/reports.rb b/lib/gitlab/ci/config/entry/reports.rb
index e45dbfa243f..f8fce1abc06 100644
--- a/lib/gitlab/ci/config/entry/reports.rb
+++ b/lib/gitlab/ci/config/entry/reports.rb
@@ -8,6 +8,7 @@ module Gitlab
# Entry that represents a configuration of job artifacts.
#
class Reports < ::Gitlab::Config::Entry::Node
+ include ::Gitlab::Config::Entry::Configurable
include ::Gitlab::Config::Entry::Validatable
include ::Gitlab::Config::Entry::Attributable
@@ -15,10 +16,13 @@ module Gitlab
%i[junit codequality sast secret_detection dependency_scanning container_scanning
dast performance browser_performance load_performance license_scanning metrics lsif
dotenv cobertura terraform accessibility cluster_applications
- requirements coverage_fuzzing api_fuzzing cluster_image_scanning].freeze
+ requirements coverage_fuzzing api_fuzzing cluster_image_scanning
+ coverage_report].freeze
attributes ALLOWED_KEYS
+ entry :coverage_report, Reports::CoverageReport, description: 'Coverage report configuration.'
+
validations do
validates :config, type: Hash
validates :config, allowed_keys: ALLOWED_KEYS
@@ -47,10 +51,18 @@ module Gitlab
validates :cluster_applications, array_of_strings_or_string: true # DEPRECATED: https://gitlab.com/gitlab-org/gitlab/-/issues/333441
validates :requirements, array_of_strings_or_string: true
end
+
+ validates :config, mutually_exclusive_keys: [:coverage_report, :cobertura]
end
def value
- @config.transform_values { |v| Array(v) }
+ @config.transform_values do |value|
+ if value.is_a?(Hash)
+ value
+ else
+ Array(value)
+ end
+ end
end
end
end
diff --git a/lib/gitlab/ci/config/entry/reports/coverage_report.rb b/lib/gitlab/ci/config/entry/reports/coverage_report.rb
new file mode 100644
index 00000000000..98119c7fd53
--- /dev/null
+++ b/lib/gitlab/ci/config/entry/reports/coverage_report.rb
@@ -0,0 +1,31 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Ci
+ class Config
+ module Entry
+ class Reports
+ class CoverageReport < ::Gitlab::Config::Entry::Node
+ include ::Gitlab::Config::Entry::Validatable
+ include ::Gitlab::Config::Entry::Attributable
+
+ ALLOWED_KEYS = %i[coverage_format path].freeze
+ SUPPORTED_COVERAGE = %w[cobertura].freeze
+
+ attributes ALLOWED_KEYS
+
+ validations do
+ validates :config, type: Hash
+ validates :config, allowed_keys: ALLOWED_KEYS
+
+ with_options(presence: true) do
+ validates :coverage_format, inclusion: { in: SUPPORTED_COVERAGE, message: "must be one of supported formats: #{SUPPORTED_COVERAGE.join(', ')}." }
+ validates :path, type: String
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/ci/config/entry/rules/rule.rb b/lib/gitlab/ci/config/entry/rules/rule.rb
index 840f2d6f31a..4722f2e9a61 100644
--- a/lib/gitlab/ci/config/entry/rules/rule.rb
+++ b/lib/gitlab/ci/config/entry/rules/rule.rb
@@ -24,7 +24,7 @@ module Gitlab
validates :config, allowed_keys: ALLOWED_KEYS
validates :config, disallowed_keys: %i[start_in], unless: :specifies_delay?
validates :start_in, presence: true, if: :specifies_delay?
- validates :start_in, duration: { limit: '1 day' }, if: :specifies_delay?
+ validates :start_in, duration: { limit: '1 week' }, if: :specifies_delay?
with_options allow_nil: true do
validates :if, expression: true
diff --git a/lib/gitlab/ci/config/entry/trigger.rb b/lib/gitlab/ci/config/entry/trigger.rb
index c6ba53adfd7..0f94b3f94fe 100644
--- a/lib/gitlab/ci/config/entry/trigger.rb
+++ b/lib/gitlab/ci/config/entry/trigger.rb
@@ -5,12 +5,13 @@ module Gitlab
class Config
module Entry
##
- # Entry that represents a cross-project downstream trigger.
+ # Entry that represents a parent-child or cross-project downstream trigger.
#
class Trigger < ::Gitlab::Config::Entry::Simplifiable
strategy :SimpleTrigger, if: -> (config) { config.is_a?(String) }
strategy :ComplexTrigger, if: -> (config) { config.is_a?(Hash) }
+ # cross-project
class SimpleTrigger < ::Gitlab::Config::Entry::Node
include ::Gitlab::Config::Entry::Validatable
@@ -28,11 +29,13 @@ module Gitlab
config.key?(:include)
end
+ # cross-project
class CrossProjectTrigger < ::Gitlab::Config::Entry::Node
include ::Gitlab::Config::Entry::Validatable
include ::Gitlab::Config::Entry::Attributable
+ include ::Gitlab::Config::Entry::Configurable
- ALLOWED_KEYS = %i[project branch strategy].freeze
+ ALLOWED_KEYS = %i[project branch strategy forward].freeze
attributes :project, :branch, :strategy
validations do
@@ -42,15 +45,26 @@ module Gitlab
validates :branch, type: String, allow_nil: true
validates :strategy, type: String, inclusion: { in: %w[depend], message: 'should be depend' }, allow_nil: true
end
+
+ entry :forward, ::Gitlab::Ci::Config::Entry::Trigger::Forward,
+ description: 'List what to forward to downstream pipelines'
+
+ def value
+ { project: project,
+ branch: branch,
+ strategy: strategy,
+ forward: forward_value }.compact
+ end
end
+ # parent-child
class SameProjectTrigger < ::Gitlab::Config::Entry::Node
include ::Gitlab::Config::Entry::Validatable
include ::Gitlab::Config::Entry::Attributable
include ::Gitlab::Config::Entry::Configurable
INCLUDE_MAX_SIZE = 3
- ALLOWED_KEYS = %i[strategy include].freeze
+ ALLOWED_KEYS = %i[strategy include forward].freeze
attributes :strategy
validations do
@@ -64,8 +78,13 @@ module Gitlab
reserved: true,
metadata: { max_size: INCLUDE_MAX_SIZE }
+ entry :forward, ::Gitlab::Ci::Config::Entry::Trigger::Forward,
+ description: 'List what to forward to downstream pipelines'
+
def value
- @config
+ { include: @config[:include],
+ strategy: strategy,
+ forward: forward_value }.compact
end
end
diff --git a/lib/gitlab/ci/config/entry/trigger/forward.rb b/lib/gitlab/ci/config/entry/trigger/forward.rb
new file mode 100644
index 00000000000..f80f018f149
--- /dev/null
+++ b/lib/gitlab/ci/config/entry/trigger/forward.rb
@@ -0,0 +1,32 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Ci
+ class Config
+ module Entry
+ ##
+ # Entry that represents the configuration for passing attributes to the downstream pipeline
+ #
+ class Trigger
+ class Forward < ::Gitlab::Config::Entry::Node
+ include ::Gitlab::Config::Entry::Validatable
+ include ::Gitlab::Config::Entry::Attributable
+
+ ALLOWED_KEYS = %i[yaml_variables pipeline_variables].freeze
+
+ attributes ALLOWED_KEYS
+
+ validations do
+ validates :config, allowed_keys: ALLOWED_KEYS
+
+ with_options allow_nil: true do
+ validates :yaml_variables, boolean: true
+ validates :pipeline_variables, boolean: true
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/ci/config/external/file/local.rb b/lib/gitlab/ci/config/external/file/local.rb
index fdb3e1b00f9..3839c43bd53 100644
--- a/lib/gitlab/ci/config/external/file/local.rb
+++ b/lib/gitlab/ci/config/external/file/local.rb
@@ -33,6 +33,10 @@ module Gitlab
def fetch_local_content
context.project.repository.blob_data_at(context.sha, location)
+ rescue GRPC::InvalidArgument
+ errors.push("Sha #{context.sha} is not valid!")
+
+ nil
end
override :expand_context_attrs
diff --git a/lib/gitlab/ci/config/yaml/tags/reference.rb b/lib/gitlab/ci/config/yaml/tags/reference.rb
index 22822614b67..45787077c91 100644
--- a/lib/gitlab/ci/config/yaml/tags/reference.rb
+++ b/lib/gitlab/ci/config/yaml/tags/reference.rb
@@ -27,7 +27,7 @@ module Gitlab
override :_resolve
def _resolve(resolver)
- object = resolver.config.dig(*location)
+ object = config_at_location(resolver)
value = resolver.deep_resolve(object)
raise MissingReferenceError, missing_ref_error_message unless value
@@ -35,6 +35,12 @@ module Gitlab
value
end
+ def config_at_location(resolver)
+ resolver.config.dig(*location)
+ rescue TypeError
+ raise MissingReferenceError, missing_ref_error_message
+ end
+
def missing_ref_error_message
"#{data[:tag]} #{data[:seq].inspect} could not be found"
end
diff --git a/lib/gitlab/ci/parsers/coverage/cobertura.rb b/lib/gitlab/ci/parsers/coverage/cobertura.rb
index d6b3af674a6..6041907ef78 100644
--- a/lib/gitlab/ci/parsers/coverage/cobertura.rb
+++ b/lib/gitlab/ci/parsers/coverage/cobertura.rb
@@ -8,140 +8,8 @@ module Gitlab
InvalidXMLError = Class.new(Gitlab::Ci::Parsers::ParserError)
InvalidLineInformationError = Class.new(Gitlab::Ci::Parsers::ParserError)
- GO_SOURCE_PATTERN = '/usr/local/go/src'
- MAX_SOURCES = 100
-
def parse!(xml_data, coverage_report, project_path: nil, worktree_paths: nil)
- root = Hash.from_xml(xml_data)
-
- context = {
- project_path: project_path,
- paths: worktree_paths&.to_set,
- sources: []
- }
-
- parse_all(root, coverage_report, context)
- rescue Nokogiri::XML::SyntaxError
- raise InvalidXMLError, "XML parsing failed"
- end
-
- private
-
- def parse_all(root, coverage_report, context)
- return unless root.present?
-
- root.each do |key, value|
- parse_node(key, value, coverage_report, context)
- end
- end
-
- def parse_node(key, value, coverage_report, context)
- if key == 'sources' && value && value['source'].present?
- parse_sources(value['source'], context)
- elsif key == 'package'
- Array.wrap(value).each do |item|
- parse_package(item, coverage_report, context)
- end
- elsif key == 'class'
- # This means the cobertura XML does not have classes within package nodes.
- # This is possible in some cases like in simple JS project structures
- # running Jest.
- Array.wrap(value).each do |item|
- parse_class(item, coverage_report, context)
- end
- elsif value.is_a?(Hash)
- parse_all(value, coverage_report, context)
- elsif value.is_a?(Array)
- value.each do |item|
- parse_all(item, coverage_report, context)
- end
- end
- end
-
- def parse_sources(sources, context)
- return unless context[:project_path] && context[:paths]
-
- sources = Array.wrap(sources)
-
- # TODO: Go cobertura has a different format with how their packages
- # are included in the filename. So we can't rely on the sources.
- # We'll deal with this later.
- return if sources.include?(GO_SOURCE_PATTERN)
-
- sources.each do |source|
- source = build_source_path(source, context)
- context[:sources] << source if source.present?
- end
- end
-
- def build_source_path(source, context)
- # | raw source | extracted |
- # |-----------------------------|------------|
- # | /builds/foo/test/SampleLib/ | SampleLib/ |
- # | /builds/foo/test/something | something |
- # | /builds/foo/test/ | nil |
- # | /builds/foo/test | nil |
- source.split("#{context[:project_path]}/", 2)[1]
- end
-
- def parse_package(package, coverage_report, context)
- classes = package.dig('classes', 'class')
- return unless classes.present?
-
- matched_filenames = Array.wrap(classes).map do |item|
- parse_class(item, coverage_report, context)
- end
-
- # Remove these filenames from the paths to avoid conflict
- # with other packages that may contain the same class filenames
- remove_matched_filenames(matched_filenames, context)
- end
-
- def remove_matched_filenames(filenames, context)
- return unless context[:paths]
-
- filenames.each { |f| context[:paths].delete(f) }
- end
-
- def parse_class(file, coverage_report, context)
- return unless file["filename"].present? && file["lines"].present?
-
- parsed_lines = parse_lines(file["lines"])
- filename = determine_filename(file["filename"], context)
-
- coverage_report.add_file(filename, Hash[parsed_lines]) if filename
-
- filename
- end
-
- def parse_lines(lines)
- line_array = Array.wrap(lines["line"])
-
- line_array.map do |line|
- # Using `Integer()` here to raise exception on invalid values
- [Integer(line["number"]), Integer(line["hits"])]
- end
- rescue StandardError
- raise InvalidLineInformationError, "Line information had invalid values"
- end
-
- def determine_filename(filename, context)
- return filename unless context[:sources].any?
-
- full_filename = nil
-
- context[:sources].each_with_index do |source, index|
- break if index >= MAX_SOURCES
- break if full_filename = check_source(source, filename, context)
- end
-
- full_filename
- end
-
- def check_source(source, filename, context)
- full_path = File.join(source, filename)
-
- return full_path if context[:paths].include?(full_path)
+ Nokogiri::XML::SAX::Parser.new(SaxDocument.new(coverage_report, project_path, worktree_paths)).parse(xml_data)
end
end
end
diff --git a/lib/gitlab/ci/parsers/coverage/sax_document.rb b/lib/gitlab/ci/parsers/coverage/sax_document.rb
new file mode 100644
index 00000000000..27cce0e3a3b
--- /dev/null
+++ b/lib/gitlab/ci/parsers/coverage/sax_document.rb
@@ -0,0 +1,110 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Ci
+ module Parsers
+ module Coverage
+ class SaxDocument < Nokogiri::XML::SAX::Document
+ GO_SOURCE_PATTERN = '/usr/local/go/src'
+ MAX_SOURCES = 100
+
+ def initialize(coverage_report, project_path, worktree_paths)
+ @coverage_report = coverage_report
+ @project_path = project_path
+ @paths = worktree_paths&.to_set
+
+ @matched_filenames = []
+ @parsed_lines = []
+ @sources = []
+ end
+
+ def error(error)
+ raise Cobertura::InvalidXMLError, "XML parsing failed with error: #{error}"
+ end
+
+ def start_element(node_name, attrs = [])
+ return unless node_name
+
+ self.node_name = node_name
+ node_attrs = Hash[attrs]
+
+ if node_name == 'class' && node_attrs["filename"].present?
+ self.filename = determine_filename(node_attrs["filename"])
+ self.matched_filenames << filename if filename
+ elsif node_name == 'line'
+ self.parsed_lines << parse_line(node_attrs)
+ end
+ end
+
+ def characters(node_content)
+ if node_name == 'source'
+ parse_source(node_content)
+ end
+ end
+
+ def end_element(node_name)
+ if node_name == "package"
+ remove_matched_filenames
+ elsif node_name == "class" && filename && parsed_lines.present?
+ coverage_report.add_file(filename, Hash[parsed_lines])
+ self.filename = nil
+ self.parsed_lines = []
+ end
+ end
+
+ private
+
+ attr_accessor :coverage_report, :project_path, :paths, :sources, :node_name, :filename, :parsed_lines, :matched_filenames
+
+ def parse_line(line)
+ [Integer(line["number"]), Integer(line["hits"])]
+ rescue StandardError
+ raise Cobertura::InvalidLineInformationError, "Line information had invalid values"
+ end
+
+ def parse_source(node)
+ return unless project_path && paths && !node.include?(GO_SOURCE_PATTERN)
+
+ source = build_source_path(node)
+ self.sources << source if source.present?
+ end
+
+ def build_source_path(node)
+ # | raw source | extracted |
+ # |-----------------------------|------------|
+ # | /builds/foo/test/SampleLib/ | SampleLib/ |
+ # | /builds/foo/test/something | something |
+ # | /builds/foo/test/ | nil |
+ # | /builds/foo/test | nil |
+ node.split("#{project_path}/", 2)[1]
+ end
+
+ def remove_matched_filenames
+ return unless paths
+
+ matched_filenames.each { |f| paths.delete(f) }
+ end
+
+ def determine_filename(filename)
+ return filename unless sources.any?
+
+ full_filename = nil
+
+ sources.each_with_index do |source, index|
+ break if index >= MAX_SOURCES
+ break if full_filename = check_source(source, filename)
+ end
+
+ full_filename
+ end
+
+ def check_source(source, filename)
+ full_path = File.join(source, filename)
+
+ return full_path if paths.include?(full_path)
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/ci/parsers/security/common.rb b/lib/gitlab/ci/parsers/security/common.rb
index 9aec615d012..7baae2f53d7 100644
--- a/lib/gitlab/ci/parsers/security/common.rb
+++ b/lib/gitlab/ci/parsers/security/common.rb
@@ -19,6 +19,8 @@ module Gitlab
end
def parse!
+ set_report_version
+
return report_data unless valid?
raise SecurityReportParserError, "Invalid report format" unless report_data.is_a?(Hash)
@@ -26,7 +28,6 @@ module Gitlab
create_scanner
create_scan
create_analyzer
- set_report_version
create_findings
@@ -42,14 +43,19 @@ module Gitlab
attr_reader :json_data, :report, :validate
def valid?
- if Feature.enabled?(:enforce_security_report_validation)
- if !validate || schema_validator.valid?
- report.schema_validation_status = :valid_schema
- true
+ if Feature.enabled?(:show_report_validation_warnings, default_enabled: :yaml)
+ # We want validation to happen regardless of VALIDATE_SCHEMA CI variable
+ schema_validation_passed = schema_validator.valid?
+
+ if validate
+ schema_validator.errors.each { |error| report.add_error('Schema', error) } unless schema_validation_passed
+
+ schema_validation_passed
else
- report.schema_validation_status = :invalid_schema
- schema_validator.errors.each { |error| report.add_error('Schema', error) }
- false
+ # We treat all schema validation errors as warnings
+ schema_validator.errors.each { |error| report.add_warning('Schema', error) }
+
+ true
end
else
return true if !validate || schema_validator.valid?
@@ -61,7 +67,7 @@ module Gitlab
end
def schema_validator
- @schema_validator ||= ::Gitlab::Ci::Parsers::Security::Validators::SchemaValidator.new(report.type, report_data)
+ @schema_validator ||= ::Gitlab::Ci::Parsers::Security::Validators::SchemaValidator.new(report.type, report_data, report.version)
end
def report_data
@@ -99,6 +105,7 @@ module Gitlab
flags = create_flags(data['flags'])
links = create_links(data['links'])
location = create_location(data['location'] || {})
+ evidence = create_evidence(data['evidence'])
signatures = create_signatures(tracking_data(data))
if @vulnerability_finding_signatures_enabled && !signatures.empty?
@@ -117,6 +124,7 @@ module Gitlab
name: finding_name(data, identifiers, location),
compare_key: data['cve'] || '',
location: location,
+ evidence: evidence,
severity: parse_severity_level(data['severity']),
confidence: parse_confidence_level(data['confidence']),
scanner: create_scanner(data['scanner']),
@@ -253,6 +261,12 @@ module Gitlab
raise NotImplementedError
end
+ def create_evidence(evidence_data)
+ return unless evidence_data.is_a?(Hash)
+
+ ::Gitlab::Ci::Reports::Security::Evidence.new(data: evidence_data)
+ end
+
def finding_name(data, identifiers, location)
return data['message'] if data['message'].present?
return data['name'] if data['name'].present?
diff --git a/lib/gitlab/ci/parsers/security/validators/schema_validator.rb b/lib/gitlab/ci/parsers/security/validators/schema_validator.rb
index 651ed23eb25..0ab1a128052 100644
--- a/lib/gitlab/ci/parsers/security/validators/schema_validator.rb
+++ b/lib/gitlab/ci/parsers/security/validators/schema_validator.rb
@@ -6,20 +6,56 @@ module Gitlab
module Security
module Validators
class SchemaValidator
+ # https://docs.gitlab.com/ee/update/deprecations.html#147
+ SUPPORTED_VERSIONS = {
+ cluster_image_scanning: %w[14.0.4 14.0.5 14.0.6 14.1.0],
+ container_scanning: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0],
+ coverage_fuzzing: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0],
+ dast: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0],
+ api_fuzzing: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0],
+ dependency_scanning: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0],
+ sast: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0],
+ secret_detection: %w[14.0.0 14.0.1 14.0.2 14.0.3 14.0.4 14.0.5 14.0.6 14.1.0]
+ }.freeze
+
+ # https://gitlab.com/gitlab-org/security-products/security-report-schemas/-/tags
+ PREVIOUS_RELEASES = %w[10.0.0 12.0.0 12.1.0 13.0.0
+ 13.1.0 2.3.0-rc1 2.3.0-rc1 2.3.1-rc1 2.3.2-rc1 2.3.3-rc1
+ 2.4.0-rc1 3.0.0 3.0.0-rc1 3.1.0-rc1 4.0.0-rc1 5.0.0-rc1
+ 5.0.1-rc1 6.0.0-rc1 6.0.1-rc1 6.1.0-rc1 7.0.0-rc1 7.0.1-rc1
+ 8.0.0-rc1 8.0.1-rc1 8.1.0-rc1 9.0.0-rc1].freeze
+
+ # These come from https://app.periscopedata.com/app/gitlab/895813/Secure-Scan-metrics?widget=12248944&udv=1385516
+ KNOWN_VERSIONS_TO_DEPRECATE = %w[0.1 1.0 1.0.0 1.2 1.3 10.0.0 12.1.0 13.1.0 2.0 2.1 2.1.0 2.3 2.3.0 2.4 3.0 3.0.0 3.0.6 3.13.2 V2.7.0].freeze
+
+ VERSIONS_TO_DEPRECATE_IN_15_0 = (PREVIOUS_RELEASES + KNOWN_VERSIONS_TO_DEPRECATE).freeze
+
+ DEPRECATED_VERSIONS = {
+ cluster_image_scanning: VERSIONS_TO_DEPRECATE_IN_15_0,
+ container_scanning: VERSIONS_TO_DEPRECATE_IN_15_0,
+ coverage_fuzzing: VERSIONS_TO_DEPRECATE_IN_15_0,
+ dast: VERSIONS_TO_DEPRECATE_IN_15_0,
+ api_fuzzing: VERSIONS_TO_DEPRECATE_IN_15_0,
+ dependency_scanning: VERSIONS_TO_DEPRECATE_IN_15_0,
+ sast: VERSIONS_TO_DEPRECATE_IN_15_0,
+ secret_detection: VERSIONS_TO_DEPRECATE_IN_15_0
+ }.freeze
+
class Schema
def root_path
File.join(__dir__, 'schemas')
end
- def initialize(report_type)
+ def initialize(report_type, report_version)
@report_type = report_type.to_sym
+ @report_version = report_version.to_s
end
delegate :validate, to: :schemer
private
- attr_reader :report_type
+ attr_reader :report_type, :report_version
def schemer
JSONSchemer.schema(pathname)
@@ -30,7 +66,19 @@ module Gitlab
end
def schema_path
- File.join(root_path, file_name)
+ # We can't exactly error out here pre-15.0.
+ # If the report itself doesn't specify the schema version,
+ # it will be considered invalid post-15.0 but for now we will
+ # validate against earliest supported version.
+ # https://gitlab.com/gitlab-org/gitlab/-/issues/335789#note_801479803
+ # describes the indended behavior in detail
+ # TODO: After 15.0 - pass report_type and report_data here and
+ # error out if no version.
+ report_declared_version = File.join(root_path, report_version, file_name)
+ return report_declared_version if File.file?(report_declared_version)
+
+ earliest_supported_version = SUPPORTED_VERSIONS[report_type].min
+ File.join(root_path, earliest_supported_version, file_name)
end
def file_name
@@ -38,9 +86,10 @@ module Gitlab
end
end
- def initialize(report_type, report_data)
+ def initialize(report_type, report_data, report_version = nil)
@report_type = report_type
@report_data = report_data
+ @report_version = report_version
end
def valid?
@@ -53,10 +102,10 @@ module Gitlab
private
- attr_reader :report_type, :report_data
+ attr_reader :report_type, :report_data, :report_version
def schema
- Schema.new(report_type)
+ Schema.new(report_type, report_version)
end
end
end
diff --git a/lib/gitlab/ci/pipeline/chain/create.rb b/lib/gitlab/ci/pipeline/chain/create.rb
index 54b54bd0514..71dfc1a676c 100644
--- a/lib/gitlab/ci/pipeline/chain/create.rb
+++ b/lib/gitlab/ci/pipeline/chain/create.rb
@@ -14,7 +14,7 @@ module Gitlab
with_bulk_insert_tags do
pipeline.transaction do
pipeline.save!
- CommitStatus.bulk_insert_tags!(statuses) if bulk_insert_tags?
+ CommitStatus.bulk_insert_tags!(statuses)
end
end
end
@@ -29,15 +29,9 @@ module Gitlab
private
- def bulk_insert_tags?
- strong_memoize(:bulk_insert_tags) do
- ::Feature.enabled?(:ci_bulk_insert_tags, project, default_enabled: :yaml)
- end
- end
-
def with_bulk_insert_tags
previous = Thread.current['ci_bulk_insert_tags']
- Thread.current['ci_bulk_insert_tags'] = bulk_insert_tags?
+ Thread.current['ci_bulk_insert_tags'] = true
yield
ensure
Thread.current['ci_bulk_insert_tags'] = previous
diff --git a/lib/gitlab/ci/pipeline/logger.rb b/lib/gitlab/ci/pipeline/logger.rb
index 10c0fe295f8..ee6c3898592 100644
--- a/lib/gitlab/ci/pipeline/logger.rb
+++ b/lib/gitlab/ci/pipeline/logger.rb
@@ -94,6 +94,7 @@ module Gitlab
private
attr_reader :project, :destination, :started_at, :log_conditions
+
delegate :current_monotonic_time, to: :class
def age
diff --git a/lib/gitlab/ci/reports/security/evidence.rb b/lib/gitlab/ci/reports/security/evidence.rb
new file mode 100644
index 00000000000..a19f52f7195
--- /dev/null
+++ b/lib/gitlab/ci/reports/security/evidence.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Ci
+ module Reports
+ module Security
+ class Evidence
+ attr_reader :data
+
+ def initialize(data:)
+ @data = data
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/ci/reports/security/finding.rb b/lib/gitlab/ci/reports/security/finding.rb
index 69fb8474cde..911a7f5d358 100644
--- a/lib/gitlab/ci/reports/security/finding.rb
+++ b/lib/gitlab/ci/reports/security/finding.rb
@@ -13,6 +13,7 @@ module Gitlab
attr_reader :flags
attr_reader :links
attr_reader :location
+ attr_reader :evidence
attr_reader :metadata_version
attr_reader :name
attr_reader :old_location
@@ -33,13 +34,14 @@ module Gitlab
alias_method :cve, :compare_key
- def initialize(compare_key:, identifiers:, flags: [], links: [], remediations: [], location:, metadata_version:, name:, original_data:, report_type:, scanner:, scan:, uuid:, confidence: nil, severity: nil, details: {}, signatures: [], project_id: nil, vulnerability_finding_signatures_enabled: false) # rubocop:disable Metrics/ParameterLists
+ def initialize(compare_key:, identifiers:, flags: [], links: [], remediations: [], location:, evidence:, metadata_version:, name:, original_data:, report_type:, scanner:, scan:, uuid:, confidence: nil, severity: nil, details: {}, signatures: [], project_id: nil, vulnerability_finding_signatures_enabled: false) # rubocop:disable Metrics/ParameterLists
@compare_key = compare_key
@confidence = confidence
@identifiers = identifiers
@flags = flags
@links = links
@location = location
+ @evidence = evidence
@metadata_version = metadata_version
@name = name
@original_data = original_data
@@ -65,6 +67,7 @@ module Gitlab
flags
links
location
+ evidence
metadata_version
name
project_fingerprint
diff --git a/lib/gitlab/ci/reports/security/report.rb b/lib/gitlab/ci/reports/security/report.rb
index fbf8c81ac36..8c528056d0c 100644
--- a/lib/gitlab/ci/reports/security/report.rb
+++ b/lib/gitlab/ci/reports/security/report.rb
@@ -6,7 +6,7 @@ module Gitlab
module Security
class Report
attr_reader :created_at, :type, :pipeline, :findings, :scanners, :identifiers
- attr_accessor :scan, :scanned_resources, :errors, :analyzer, :version, :schema_validation_status
+ attr_accessor :scan, :scanned_resources, :errors, :analyzer, :version, :schema_validation_status, :warnings
delegate :project_id, to: :pipeline
@@ -19,6 +19,7 @@ module Gitlab
@identifiers = {}
@scanned_resources = []
@errors = []
+ @warnings = []
end
def commit_sha
@@ -29,6 +30,10 @@ module Gitlab
errors << { type: type, message: message }
end
+ def add_warning(type, message)
+ warnings << { type: type, message: message }
+ end
+
def errored?
errors.present?
end
diff --git a/lib/gitlab/ci/reports/test_suite_comparer.rb b/lib/gitlab/ci/reports/test_suite_comparer.rb
index 287a03cefe2..7fa744d047c 100644
--- a/lib/gitlab/ci/reports/test_suite_comparer.rb
+++ b/lib/gitlab/ci/reports/test_suite_comparer.rb
@@ -106,7 +106,7 @@ module Gitlab
private
def max_tests(*used)
- [DEFAULT_MAX_TESTS - used.map(&:count).sum, DEFAULT_MIN_TESTS].max
+ [DEFAULT_MAX_TESTS - used.sum(&:count), DEFAULT_MIN_TESTS].max
end
end
end
diff --git a/lib/gitlab/ci/status/build/waiting_for_approval.rb b/lib/gitlab/ci/status/build/waiting_for_approval.rb
index 59869a947a9..ac3f5838d26 100644
--- a/lib/gitlab/ci/status/build/waiting_for_approval.rb
+++ b/lib/gitlab/ci/status/build/waiting_for_approval.rb
@@ -9,11 +9,35 @@ module Gitlab
{
image: 'illustrations/manual_action.svg',
size: 'svg-394',
- title: 'Waiting for approval',
- content: "This job deploys to the protected environment \"#{subject.deployment&.environment&.name}\" which requires approvals. Use the Deployments API to approve or reject the deployment."
+ title: _('Waiting for approval'),
+ content: _("This job deploys to the protected environment \"%{environment}\" which requires approvals.") % { environment: subject.deployment&.environment&.name }
}
end
+ def has_action?
+ true
+ end
+
+ def action_icon
+ nil
+ end
+
+ def action_title
+ nil
+ end
+
+ def action_button_title
+ _('Go to environments page to approve or reject')
+ end
+
+ def action_path
+ project_environments_path(subject.project)
+ end
+
+ def action_method
+ :get
+ end
+
def self.matches?(build, user)
build.waiting_for_deployment_approval?
end
diff --git a/lib/gitlab/ci/templates/Android-Fastlane.gitlab-ci.yml b/lib/gitlab/ci/templates/Android-Fastlane.gitlab-ci.yml
index 64e3b695e27..bbe1b0a4b82 100644
--- a/lib/gitlab/ci/templates/Android-Fastlane.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Android-Fastlane.gitlab-ci.yml
@@ -4,8 +4,14 @@
# https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Android-Fastlane.gitlab-ci.yml
# Read more about how to use this script on this blog post https://about.gitlab.com/2019/01/28/android-publishing-with-gitlab-and-fastlane/
-# You will also need to configure your build.gradle, Dockerfile, and fastlane configuration to make this work.
# If you are looking for a simpler template that does not publish, see the Android template.
+# You will also need to configure your build.gradle, Dockerfile, and fastlane configuration to make this work.
+
+# The following environment variables also need to be defined via the CI/CD settings:
+#
+# - $signing_jks_file_hex: A hex-encoded Java keystore file containing your signing keys.
+# To encode this file, use `xxd -p <your-keystore-file>.jks` and save the output as `$signing_jks_file_hex`
+# - $google_play_service_account_api_key_json: Your Google Play service account credentials - https://docs.fastlane.tools/getting-started/android/setup/#collect-your-google-credentials
stages:
- environment
@@ -41,20 +47,21 @@ ensureContainer:
before_script:
- "mkdir -p ~/.docker && echo '{\"experimental\": \"enabled\"}' > ~/.docker/config.json"
- docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY
- # Skip update container `script` if the container already exists
- # via https://gitlab.com/gitlab-org/gitlab-foss/issues/26866#note_97609397 -> https://stackoverflow.com/a/52077071/796832
- - docker manifest inspect $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG > /dev/null && exit || true
-
+ - |
+ if docker manifest inspect $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG > /dev/null; then
+ echo 'Skipping job since there is already an image with this tag'
+ exit 0
+ fi
.build_job:
image: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG
stage: build
before_script:
- # We store this binary file in a variable as hex with this command: `xxd -p android-app.jks`
+ # We store this binary file in a project variable as hex with this command: `xxd -p android-app.jks`
# Then we convert the hex back to a binary file
- echo "$signing_jks_file_hex" | xxd -r -p - > android-signing-keystore.jks
- - "export VERSION_CODE=$CI_PIPELINE_IID && echo $VERSION_CODE"
- - "export VERSION_SHA=`echo ${CI_COMMIT_SHA:0:8}` && echo $VERSION_SHA"
+ - export VERSION_CODE="$CI_PIPELINE_IID" && echo "$VERSION_CODE"
+ - export VERSION_SHA="${CI_COMMIT_SHA:0:8}" && echo "$VERSION_SHA"
after_script:
- rm -f android-signing-keystore.jks || true
artifacts:
diff --git a/lib/gitlab/ci/templates/Dart.gitlab-ci.yml b/lib/gitlab/ci/templates/Dart.gitlab-ci.yml
index a50e722f18a..6354db38f58 100644
--- a/lib/gitlab/ci/templates/Dart.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Dart.gitlab-ci.yml
@@ -18,7 +18,7 @@ cache:
- .pub-cache/global_packages
before_script:
- - export PATH="$PATH":"~/.pub-cache/bin"
+ - export PATH="$PATH:$HOME/.pub-cache/bin"
- pub get --no-precompile
test:
diff --git a/lib/gitlab/ci/templates/Flutter.gitlab-ci.yml b/lib/gitlab/ci/templates/Flutter.gitlab-ci.yml
index d176ce19299..a5c261e367a 100644
--- a/lib/gitlab/ci/templates/Flutter.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Flutter.gitlab-ci.yml
@@ -8,7 +8,7 @@ code_quality:
image: "cirrusci/flutter:1.22.5"
before_script:
- pub global activate dart_code_metrics
- - export PATH="$PATH":"$HOME/.pub-cache/bin"
+ - export PATH="$PATH:$HOME/.pub-cache/bin"
script:
- metrics lib -r codeclimate > gl-code-quality-report.json
artifacts:
@@ -20,7 +20,7 @@ test:
image: "cirrusci/flutter:1.22.5"
before_script:
- pub global activate junitreport
- - export PATH="$PATH":"$HOME/.pub-cache/bin"
+ - export PATH="$PATH:$HOME/.pub-cache/bin"
script:
- flutter test --machine --coverage | tojunit -o report.xml
- lcov --summary coverage/lcov.info
diff --git a/lib/gitlab/ci/templates/Go.gitlab-ci.yml b/lib/gitlab/ci/templates/Go.gitlab-ci.yml
index b5dd0005013..19e4ffdbe1e 100644
--- a/lib/gitlab/ci/templates/Go.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Go.gitlab-ci.yml
@@ -16,9 +16,9 @@ variables:
# repository in /go/src/gitlab.com/namespace/project
# Thus, making a symbolic link corrects this.
before_script:
- - mkdir -p $GOPATH/src/$(dirname $REPO_NAME)
- - ln -svf $CI_PROJECT_DIR $GOPATH/src/$REPO_NAME
- - cd $GOPATH/src/$REPO_NAME
+ - mkdir -p "$GOPATH/src/$(dirname $REPO_NAME)"
+ - ln -svf "$CI_PROJECT_DIR" "$GOPATH/src/$REPO_NAME"
+ - cd "$GOPATH/src/$REPO_NAME"
stages:
- test
diff --git a/lib/gitlab/ci/templates/Gradle.gitlab-ci.yml b/lib/gitlab/ci/templates/Gradle.gitlab-ci.yml
index 76f0c9f8427..08dc10d34b7 100644
--- a/lib/gitlab/ci/templates/Gradle.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Gradle.gitlab-ci.yml
@@ -17,7 +17,8 @@ variables:
GRADLE_OPTS: "-Dorg.gradle.daemon=false"
before_script:
- - export GRADLE_USER_HOME=`pwd`/.gradle
+ - GRADLE_USER_HOME="$(pwd)/.gradle"
+ - export GRADLE_USER_HOME
build:
stage: build
diff --git a/lib/gitlab/ci/templates/Grails.gitlab-ci.yml b/lib/gitlab/ci/templates/Grails.gitlab-ci.yml
index 3c514d7b0c6..7e59354c4a1 100644
--- a/lib/gitlab/ci/templates/Grails.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Grails.gitlab-ci.yml
@@ -23,8 +23,8 @@ variables:
before_script:
- apt-get update -qq && apt-get install -y -qq unzip
- curl -sSL https://get.sdkman.io | bash
- - echo sdkman_auto_answer=true > /root/.sdkman/etc/config
- - source /root/.sdkman/bin/sdkman-init.sh
+ - echo sdkman_auto_answer=true > ~/.sdkman/etc/config
+ - source ~/.sdkman/bin/sdkman-init.sh
- sdk install gradle $GRADLE_VERSION < /dev/null
- sdk use gradle $GRADLE_VERSION
# As it's not a good idea to version gradle.properties feel free to add your
@@ -36,7 +36,7 @@ before_script:
# Be aware that if you are using Angular profile,
# Bower cannot be run as root if you don't allow it before.
# Feel free to remove next line if you are not using Bower
- - echo {\"allow_root\":true} > /root/.bowerrc
+ - echo '{"allow_root":true}' > ~/.bowerrc
# This build job does the full grails pipeline
# (compile, test, integrationTest, war, assemble).
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 99fd9870b1d..d1018f1e769 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
@@ -2,7 +2,7 @@
browser_performance:
stage: performance
- image: docker:19.03.12
+ image: docker:20.10.12
allow_failure: true
variables:
DOCKER_TLS_CERTDIR: ""
@@ -10,19 +10,21 @@ browser_performance:
SITESPEED_VERSION: 14.1.0
SITESPEED_OPTIONS: ''
services:
- - docker:19.03.12-dind
+ - name: 'docker:20.10.12-dind'
+ command: ['--tls=false', '--host=tcp://0.0.0.0:2375']
script:
- |
if ! docker info &>/dev/null; then
- if [ -z "$DOCKER_HOST" -a "$KUBERNETES_PORT" ]; then
+ if [ -z "$DOCKER_HOST" ] && [ -n "$KUBERNETES_PORT" ]; then
export DOCKER_HOST='tcp://localhost:2375'
fi
fi
- - export CI_ENVIRONMENT_URL=$(cat environment_url.txt)
+ - CI_ENVIRONMENT_URL="$(cat environment_url.txt)"
+ - export CI_ENVIRONMENT_URL
- mkdir gitlab-exporter
# Busybox wget does not support proxied HTTPS, get the real thing.
# See https://gitlab.com/gitlab-org/gitlab/-/issues/287611.
- - (env | grep -i _proxy= 2>&1 >/dev/null) && apk --no-cache add wget
+ - (env | grep -i _proxy= >/dev/null 2>&1) && apk --no-cache add wget
- wget -O gitlab-exporter/index.js https://gitlab.com/gitlab-org/gl-performance/raw/1.1.0/index.js
- mkdir sitespeed-results
- |
diff --git a/lib/gitlab/ci/templates/Jobs/Browser-Performance-Testing.latest.gitlab-ci.yml b/lib/gitlab/ci/templates/Jobs/Browser-Performance-Testing.latest.gitlab-ci.yml
index 99fd9870b1d..bb7e020b159 100644
--- a/lib/gitlab/ci/templates/Jobs/Browser-Performance-Testing.latest.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Jobs/Browser-Performance-Testing.latest.gitlab-ci.yml
@@ -2,7 +2,7 @@
browser_performance:
stage: performance
- image: docker:19.03.12
+ image: docker:20.10.12
allow_failure: true
variables:
DOCKER_TLS_CERTDIR: ""
@@ -10,11 +10,12 @@ browser_performance:
SITESPEED_VERSION: 14.1.0
SITESPEED_OPTIONS: ''
services:
- - docker:19.03.12-dind
+ - name: 'docker:20.10.12-dind'
+ command: ['--tls=false', '--host=tcp://0.0.0.0:2375']
script:
- |
if ! docker info &>/dev/null; then
- if [ -z "$DOCKER_HOST" -a "$KUBERNETES_PORT" ]; then
+ if [ -z "$DOCKER_HOST" ] && [ -n "$KUBERNETES_PORT" ]; then
export DOCKER_HOST='tcp://localhost:2375'
fi
fi
@@ -22,7 +23,7 @@ browser_performance:
- mkdir gitlab-exporter
# Busybox wget does not support proxied HTTPS, get the real thing.
# See https://gitlab.com/gitlab-org/gitlab/-/issues/287611.
- - (env | grep -i _proxy= 2>&1 >/dev/null) && apk --no-cache add wget
+ - (env | grep -i _proxy= >/dev/null 2>&1) && apk --no-cache add wget
- wget -O gitlab-exporter/index.js https://gitlab.com/gitlab-org/gl-performance/raw/1.1.0/index.js
- mkdir sitespeed-results
- |
diff --git a/lib/gitlab/ci/templates/Jobs/Build.gitlab-ci.yml b/lib/gitlab/ci/templates/Jobs/Build.gitlab-ci.yml
index d5ca93a0a3b..f3d2e293c86 100644
--- a/lib/gitlab/ci/templates/Jobs/Build.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Jobs/Build.gitlab-ci.yml
@@ -1,5 +1,5 @@
variables:
- AUTO_BUILD_IMAGE_VERSION: 'v1.5.0'
+ AUTO_BUILD_IMAGE_VERSION: 'v1.9.1'
build:
stage: build
@@ -7,7 +7,7 @@ build:
variables:
DOCKER_TLS_CERTDIR: ''
services:
- - name: 'docker:20.10.6-dind'
+ - name: 'docker:20.10.12-dind'
command: ['--tls=false', '--host=tcp://0.0.0.0:2375']
script:
- |
diff --git a/lib/gitlab/ci/templates/Jobs/Build.latest.gitlab-ci.yml b/lib/gitlab/ci/templates/Jobs/Build.latest.gitlab-ci.yml
index d5ca93a0a3b..f3d2e293c86 100644
--- a/lib/gitlab/ci/templates/Jobs/Build.latest.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Jobs/Build.latest.gitlab-ci.yml
@@ -1,5 +1,5 @@
variables:
- AUTO_BUILD_IMAGE_VERSION: 'v1.5.0'
+ AUTO_BUILD_IMAGE_VERSION: 'v1.9.1'
build:
stage: build
@@ -7,7 +7,7 @@ build:
variables:
DOCKER_TLS_CERTDIR: ''
services:
- - name: 'docker:20.10.6-dind'
+ - name: 'docker:20.10.12-dind'
command: ['--tls=false', '--host=tcp://0.0.0.0:2375']
script:
- |
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 6942631a97f..6a95d042842 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,10 @@
code_quality:
stage: test
- image: docker:19.03.12
+ image: docker:20.10.12
allow_failure: true
services:
- - docker:19.03.12-dind
+ - name: 'docker:20.10.12-dind'
+ command: ['--tls=false', '--host=tcp://0.0.0.0:2375']
variables:
DOCKER_DRIVER: overlay2
DOCKER_TLS_CERTDIR: ""
@@ -13,7 +14,7 @@ code_quality:
- export SOURCE_CODE=$PWD
- |
if ! docker info &>/dev/null; then
- if [ -z "$DOCKER_HOST" -a "$KUBERNETES_PORT" ]; then
+ if [ -z "$DOCKER_HOST" ] && [ -n "$KUBERNETES_PORT" ]; then
export DOCKER_HOST='tcp://localhost:2375'
fi
fi
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 28ac627f103..cc204207f84 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 @@
variables:
- DAST_AUTO_DEPLOY_IMAGE_VERSION: 'v2.17.0'
+ DAST_AUTO_DEPLOY_IMAGE_VERSION: 'v2.22.0'
.dast-auto-deploy:
image: "registry.gitlab.com/gitlab-org/cluster-integration/auto-deploy-image:${DAST_AUTO_DEPLOY_IMAGE_VERSION}"
diff --git a/lib/gitlab/ci/templates/Jobs/Dependency-Scanning.gitlab-ci.yml b/lib/gitlab/ci/templates/Jobs/Dependency-Scanning.gitlab-ci.yml
index 65c9232f3b9..1a99db67441 100644
--- a/lib/gitlab/ci/templates/Jobs/Dependency-Scanning.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Jobs/Dependency-Scanning.gitlab-ci.yml
@@ -11,7 +11,7 @@
variables:
# Setting this variable will affect all Security templates
# (SAST, Dependency Scanning, ...)
- SECURE_ANALYZERS_PREFIX: "registry.gitlab.com/gitlab-org/security-products/analyzers"
+ SECURE_ANALYZERS_PREFIX: "registry.gitlab.com/security-products"
DS_DEFAULT_ANALYZERS: "bundler-audit, retire.js, gemnasium, gemnasium-maven, gemnasium-python"
DS_EXCLUDED_ANALYZERS: ""
DS_EXCLUDED_PATHS: "spec, test, tests, tmp"
diff --git a/lib/gitlab/ci/templates/Jobs/Deploy.gitlab-ci.yml b/lib/gitlab/ci/templates/Jobs/Deploy.gitlab-ci.yml
index 075e13e87f0..bc4f2099d94 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 @@
variables:
- AUTO_DEPLOY_IMAGE_VERSION: 'v2.18.1'
+ AUTO_DEPLOY_IMAGE_VERSION: 'v2.22.0'
.auto-deploy:
image: "registry.gitlab.com/gitlab-org/cluster-integration/auto-deploy-image:${AUTO_DEPLOY_IMAGE_VERSION}"
diff --git a/lib/gitlab/ci/templates/Jobs/Deploy.latest.gitlab-ci.yml b/lib/gitlab/ci/templates/Jobs/Deploy.latest.gitlab-ci.yml
index e9c5d970c21..ce584091eab 100644
--- a/lib/gitlab/ci/templates/Jobs/Deploy.latest.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Jobs/Deploy.latest.gitlab-ci.yml
@@ -1,5 +1,5 @@
variables:
- AUTO_DEPLOY_IMAGE_VERSION: 'v2.18.1'
+ AUTO_DEPLOY_IMAGE_VERSION: 'v2.22.0'
.auto-deploy:
image: "registry.gitlab.com/gitlab-org/cluster-integration/auto-deploy-image:${AUTO_DEPLOY_IMAGE_VERSION}"
diff --git a/lib/gitlab/ci/templates/Jobs/License-Scanning.gitlab-ci.yml b/lib/gitlab/ci/templates/Jobs/License-Scanning.gitlab-ci.yml
index fc51f5adb3c..89a44eddefd 100644
--- a/lib/gitlab/ci/templates/Jobs/License-Scanning.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Jobs/License-Scanning.gitlab-ci.yml
@@ -11,7 +11,7 @@
variables:
# Setting this variable will affect all Security templates
# (SAST, Dependency Scanning, ...)
- SECURE_ANALYZERS_PREFIX: "registry.gitlab.com/gitlab-org/security-products/analyzers"
+ SECURE_ANALYZERS_PREFIX: "registry.gitlab.com/security-products"
LICENSE_MANAGEMENT_SETUP_CMD: '' # If needed, specify a command to setup your environment with a custom package manager.
LICENSE_MANAGEMENT_VERSION: 3
diff --git a/lib/gitlab/ci/templates/Jobs/Load-Performance-Testing.gitlab-ci.yml b/lib/gitlab/ci/templates/Jobs/Load-Performance-Testing.gitlab-ci.yml
index 8e34388893a..eea1c397108 100644
--- a/lib/gitlab/ci/templates/Jobs/Load-Performance-Testing.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Jobs/Load-Performance-Testing.gitlab-ci.yml
@@ -1,6 +1,6 @@
load_performance:
stage: performance
- image: docker:19.03.11
+ image: docker:20.10.12
allow_failure: true
variables:
DOCKER_TLS_CERTDIR: ""
@@ -10,11 +10,12 @@ load_performance:
K6_OPTIONS: ''
K6_DOCKER_OPTIONS: ''
services:
- - docker:19.03.11-dind
+ - name: 'docker:20.10.12-dind'
+ command: ['--tls=false', '--host=tcp://0.0.0.0:2375']
script:
- |
if ! docker info &>/dev/null; then
- if [ -z "$DOCKER_HOST" -a "$KUBERNETES_PORT" ]; then
+ if [ -z "$DOCKER_HOST" ] && [ -n "$KUBERNETES_PORT" ]; then
export DOCKER_HOST='tcp://localhost:2375'
fi
fi
diff --git a/lib/gitlab/ci/templates/Jobs/SAST-IaC.latest.gitlab-ci.yml b/lib/gitlab/ci/templates/Jobs/SAST-IaC.latest.gitlab-ci.yml
index fa7f6ffa2b7..5ddfb2a54be 100644
--- a/lib/gitlab/ci/templates/Jobs/SAST-IaC.latest.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Jobs/SAST-IaC.latest.gitlab-ci.yml
@@ -1,7 +1,7 @@
variables:
# Setting this variable will affect all Security templates
# (SAST, Dependency Scanning, ...)
- SECURE_ANALYZERS_PREFIX: "registry.gitlab.com/gitlab-org/security-products/analyzers"
+ SECURE_ANALYZERS_PREFIX: "registry.gitlab.com/security-products"
SAST_EXCLUDED_PATHS: "spec, test, tests, tmp"
iac-sast:
diff --git a/lib/gitlab/ci/templates/Jobs/SAST.gitlab-ci.yml b/lib/gitlab/ci/templates/Jobs/SAST.gitlab-ci.yml
index 25d20563010..8cc9ea0200c 100644
--- a/lib/gitlab/ci/templates/Jobs/SAST.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Jobs/SAST.gitlab-ci.yml
@@ -6,7 +6,7 @@
variables:
# Setting this variable will affect all Security templates
# (SAST, Dependency Scanning, ...)
- SECURE_ANALYZERS_PREFIX: "registry.gitlab.com/gitlab-org/security-products/analyzers"
+ SECURE_ANALYZERS_PREFIX: "registry.gitlab.com/security-products"
SAST_EXCLUDED_ANALYZERS: ""
SAST_EXCLUDED_PATHS: "spec, test, tests, tmp"
diff --git a/lib/gitlab/ci/templates/Jobs/Secret-Detection.gitlab-ci.yml b/lib/gitlab/ci/templates/Jobs/Secret-Detection.gitlab-ci.yml
index 4e4f96bc7c7..0ef6f63bb94 100644
--- a/lib/gitlab/ci/templates/Jobs/Secret-Detection.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Jobs/Secret-Detection.gitlab-ci.yml
@@ -5,7 +5,7 @@
# How to set: https://docs.gitlab.com/ee/ci/yaml/#variables
variables:
- SECURE_ANALYZERS_PREFIX: "registry.gitlab.com/gitlab-org/security-products/analyzers"
+ SECURE_ANALYZERS_PREFIX: "registry.gitlab.com/security-products"
SECRETS_ANALYZER_VERSION: "3"
SECRET_DETECTION_EXCLUDED_PATHS: ""
@@ -30,24 +30,43 @@ secret_detection:
- if: $CI_COMMIT_BRANCH
script:
- if [ -n "$CI_COMMIT_TAG" ]; then echo "Skipping Secret Detection for tags. No code changes have occurred."; exit 0; fi
- - if [ "$CI_COMMIT_BRANCH" = "$CI_DEFAULT_BRANCH" ]; then echo "Running Secret Detection on default branch."; /analyzer run; exit 0; fi
+ # Historic scan
- |
- # we don't need the whole history when excluding in the next `git fetch` line,
- # so git depth=1
- git fetch origin --depth=1 $CI_DEFAULT_BRANCH
- # shallow clone $CI_COMMIT_REF_NAME to get commits associated with MR or push
- git fetch --shallow-exclude=${CI_DEFAULT_BRANCH} origin $CI_COMMIT_REF_NAME
- # determine what commits we need to scan using "git log A..B"
- git log --no-merges --pretty=format:"%H" refs/remotes/origin/${CI_DEFAULT_BRANCH}..refs/remotes/origin/${CI_COMMIT_REF_NAME} >${CI_COMMIT_SHA}_commit_list.txt
-
- # we need to extend the git fetch depth to the number of commits + 2 for the following reasons:
- # because busybox wc only counts \n and there is no trailing \n (+1)
- # include the parent commit of the base commit in this MR/Push event. This is needed because
- # `git diff -p` needs something to compare changes in that commit against (+1)
- git fetch --depth=$(($(wc -l <${CI_COMMIT_SHA}_commit_list.txt) + 2)) origin $CI_COMMIT_REF_NAME
+ if [ "$SECRET_DETECTION_HISTORIC_SCAN" == "true" ]
+ then
+ echo "historic scan"
+ git fetch --unshallow origin $CI_COMMIT_REF_NAME
+ /analyzer run
+ exit
+ fi
+ # Default branch scan
+ - if [ "$CI_COMMIT_BRANCH" == "$CI_DEFAULT_BRANCH" ]; then echo "Running Secret Detection on default branch."; /analyzer run; exit; fi
+ # Push event
+ - |
+ if [ "$CI_COMMIT_BEFORE_SHA" == "0000000000000000000000000000000000000000" ];
+ then
+ # first commit on a new branch
+ echo ${CI_COMMIT_SHA} >${CI_COMMIT_SHA}_commit_list.txt
+ git fetch --depth=2 origin $CI_COMMIT_REF_NAME
+ else
+ # determine commit range so that we can fetch the appropriate depth
+ # check the exit code to determine if we need to limit the commit_list.txt to CI_COMMIT_SHA.
+ if ! git log --pretty=format:"%H" ${CI_COMMIT_BEFORE_SHA}..${CI_COMMIT_SHA} >${CI_COMMIT_SHA}_commit_list.txt;
+ then
+ echo "unable to determine commit range, limiting to ${CI_COMMIT_SHA}"
+ echo ${CI_COMMIT_SHA} >${CI_COMMIT_SHA}_commit_list.txt
+ else
+ # append newline to to list since `git log` does not end with a
+ # newline, this is to keep the log messages consistent
+ echo >> ${CI_COMMIT_SHA}_commit_list.txt
+ fi
- # +1 because busybox wc only counts \n and there is no trailing \n
- echo "scanning $(($(wc -l <${CI_COMMIT_SHA}_commit_list.txt) + 1)) commits"
+ # we need to extend the git fetch depth to the number of commits + 1 for the following reasons:
+ # to include the parent commit of the base commit in this MR/Push event. This is needed because
+ # `git diff -p` needs something to compare changes in that commit against
+ git fetch --depth=$(($(wc -l <${CI_COMMIT_SHA}_commit_list.txt) + 1)) origin $CI_COMMIT_REF_NAME
+ fi
+ echo "scanning $(($(wc -l <${CI_COMMIT_SHA}_commit_list.txt))) commits for a push event"
export SECRET_DETECTION_COMMITS_FILE=${CI_COMMIT_SHA}_commit_list.txt
- /analyzer run
- rm "$CI_COMMIT_SHA"_commit_list.txt
diff --git a/lib/gitlab/ci/templates/Pages/HTML.gitlab-ci.yml b/lib/gitlab/ci/templates/Pages/HTML.gitlab-ci.yml
index d32444833fb..85f90984045 100644
--- a/lib/gitlab/ci/templates/Pages/HTML.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Pages/HTML.gitlab-ci.yml
@@ -8,7 +8,7 @@ pages:
stage: deploy
script:
- mkdir .public
- - cp -r * .public
+ - cp -r ./* .public
- rm -rf public
- mv .public public
artifacts:
diff --git a/lib/gitlab/ci/templates/Python.gitlab-ci.yml b/lib/gitlab/ci/templates/Python.gitlab-ci.yml
index 4917abf6ae9..6ed5e05ed4c 100644
--- a/lib/gitlab/ci/templates/Python.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Python.gitlab-ci.yml
@@ -47,7 +47,8 @@ run:
pages:
script:
- pip install sphinx sphinx-rtd-theme
- - cd doc ; make html
+ - cd doc
+ - make html
- mv build/html/ ../public/
artifacts:
paths:
diff --git a/lib/gitlab/ci/templates/Ruby.gitlab-ci.yml b/lib/gitlab/ci/templates/Ruby.gitlab-ci.yml
index 1660a9250e3..33c0928db6f 100644
--- a/lib/gitlab/ci/templates/Ruby.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Ruby.gitlab-ci.yml
@@ -52,7 +52,7 @@ rails:
# This deploy job uses a simple deploy flow to Heroku, other providers, e.g. AWS Elastic Beanstalk
# are supported too: https://github.com/travis-ci/dpl
deploy:
- type: deploy
+ stage: deploy
environment: production
script:
- gem install dpl
diff --git a/lib/gitlab/ci/templates/Security/API-Fuzzing.gitlab-ci.yml b/lib/gitlab/ci/templates/Security/API-Fuzzing.gitlab-ci.yml
index 009061ce844..aff8b6cb7fa 100644
--- a/lib/gitlab/ci/templates/Security/API-Fuzzing.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Security/API-Fuzzing.gitlab-ci.yml
@@ -10,7 +10,7 @@
variables:
FUZZAPI_VERSION: "1"
- SECURE_ANALYZERS_PREFIX: "registry.gitlab.com/gitlab-org/security-products/analyzers"
+ SECURE_ANALYZERS_PREFIX: "registry.gitlab.com/security-products"
FUZZAPI_IMAGE: ${SECURE_ANALYZERS_PREFIX}/api-fuzzing:${FUZZAPI_VERSION}
apifuzzer_fuzz:
diff --git a/lib/gitlab/ci/templates/Security/API-Fuzzing.latest.gitlab-ci.yml b/lib/gitlab/ci/templates/Security/API-Fuzzing.latest.gitlab-ci.yml
index 01041f4f056..bd8ba71effe 100644
--- a/lib/gitlab/ci/templates/Security/API-Fuzzing.latest.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Security/API-Fuzzing.latest.gitlab-ci.yml
@@ -10,7 +10,7 @@
variables:
FUZZAPI_VERSION: "1"
- SECURE_ANALYZERS_PREFIX: "registry.gitlab.com/gitlab-org/security-products/analyzers"
+ SECURE_ANALYZERS_PREFIX: "registry.gitlab.com/security-products"
FUZZAPI_IMAGE: api-fuzzing
apifuzzer_fuzz:
diff --git a/lib/gitlab/ci/templates/Security/DAST-API.gitlab-ci.yml b/lib/gitlab/ci/templates/Security/DAST-API.gitlab-ci.yml
index a2933085d4e..d82f9f06f8d 100644
--- a/lib/gitlab/ci/templates/Security/DAST-API.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Security/DAST-API.gitlab-ci.yml
@@ -24,7 +24,7 @@
variables:
# Setting this variable affects all Security templates
# (SAST, Dependency Scanning, ...)
- SECURE_ANALYZERS_PREFIX: "registry.gitlab.com/gitlab-org/security-products/analyzers"
+ SECURE_ANALYZERS_PREFIX: "registry.gitlab.com/security-products"
#
DAST_API_VERSION: "1"
DAST_API_IMAGE: $SECURE_ANALYZERS_PREFIX/api-fuzzing:$DAST_API_VERSION
diff --git a/lib/gitlab/ci/templates/Security/DAST-API.latest.gitlab-ci.yml b/lib/gitlab/ci/templates/Security/DAST-API.latest.gitlab-ci.yml
index 57f1993921d..0e0afa489a3 100644
--- a/lib/gitlab/ci/templates/Security/DAST-API.latest.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Security/DAST-API.latest.gitlab-ci.yml
@@ -24,7 +24,7 @@
variables:
# Setting this variable affects all Security templates
# (SAST, Dependency Scanning, ...)
- SECURE_ANALYZERS_PREFIX: "registry.gitlab.com/gitlab-org/security-products/analyzers"
+ SECURE_ANALYZERS_PREFIX: "registry.gitlab.com/security-products"
#
DAST_API_VERSION: "1"
DAST_API_IMAGE: api-fuzzing
diff --git a/lib/gitlab/ci/templates/Security/DAST-On-Demand-API-Scan.gitlab-ci.yml b/lib/gitlab/ci/templates/Security/DAST-On-Demand-API-Scan.gitlab-ci.yml
index 7ffec7d2e6b..3f9c87b7abf 100644
--- a/lib/gitlab/ci/templates/Security/DAST-On-Demand-API-Scan.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Security/DAST-On-Demand-API-Scan.gitlab-ci.yml
@@ -5,7 +5,7 @@ stages:
- dast
variables:
- SECURE_ANALYZERS_PREFIX: "registry.gitlab.com/gitlab-org/security-products/analyzers"
+ SECURE_ANALYZERS_PREFIX: "registry.gitlab.com/security-products"
DAST_API_VERSION: "1"
DAST_API_IMAGE: $SECURE_ANALYZERS_PREFIX/api-fuzzing:$DAST_API_VERSION
diff --git a/lib/gitlab/ci/templates/Security/DAST-On-Demand-Scan.gitlab-ci.yml b/lib/gitlab/ci/templates/Security/DAST-On-Demand-Scan.gitlab-ci.yml
index 3e7ab9b5c3b..998425aa141 100644
--- a/lib/gitlab/ci/templates/Security/DAST-On-Demand-Scan.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Security/DAST-On-Demand-Scan.gitlab-ci.yml
@@ -13,7 +13,7 @@ variables:
DAST_VERSION: 2
# Setting this variable will affect all Security templates
# (SAST, Dependency Scanning, ...)
- SECURE_ANALYZERS_PREFIX: "registry.gitlab.com/gitlab-org/security-products/analyzers"
+ SECURE_ANALYZERS_PREFIX: "registry.gitlab.com/security-products"
dast:
stage: dast
diff --git a/lib/gitlab/ci/templates/Security/DAST.gitlab-ci.yml b/lib/gitlab/ci/templates/Security/DAST.gitlab-ci.yml
index 0ecbe5e14b8..e8e7fe62e70 100644
--- a/lib/gitlab/ci/templates/Security/DAST.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Security/DAST.gitlab-ci.yml
@@ -25,7 +25,7 @@ variables:
DAST_VERSION: 2
# Setting this variable will affect all Security templates
# (SAST, Dependency Scanning, ...)
- SECURE_ANALYZERS_PREFIX: "registry.gitlab.com/gitlab-org/security-products/analyzers"
+ SECURE_ANALYZERS_PREFIX: "registry.gitlab.com/security-products"
dast:
stage: dast
diff --git a/lib/gitlab/ci/templates/Security/DAST.latest.gitlab-ci.yml b/lib/gitlab/ci/templates/Security/DAST.latest.gitlab-ci.yml
index 3d07674c377..c755211ec11 100644
--- a/lib/gitlab/ci/templates/Security/DAST.latest.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Security/DAST.latest.gitlab-ci.yml
@@ -25,7 +25,7 @@ variables:
DAST_VERSION: 2
# Setting this variable will affect all Security templates
# (SAST, Dependency Scanning, ...)
- SECURE_ANALYZERS_PREFIX: "registry.gitlab.com/gitlab-org/security-products/analyzers"
+ SECURE_ANALYZERS_PREFIX: "registry.gitlab.com/security-products"
dast:
stage: dast
diff --git a/lib/gitlab/ci/templates/Security/Secure-Binaries.gitlab-ci.yml b/lib/gitlab/ci/templates/Security/Secure-Binaries.gitlab-ci.yml
index 82c7bfd0620..a6fd070ec34 100644
--- a/lib/gitlab/ci/templates/Security/Secure-Binaries.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Security/Secure-Binaries.gitlab-ci.yml
@@ -14,8 +14,11 @@
# Docs: https://docs.gitlab.com/ee/topics/airgap/
variables:
+ # Setting this variable will affect all Security templates
+ # (SAST, Dependency Scanning, ...)
+ SECURE_ANALYZERS_PREFIX: "registry.gitlab.com/security-products"
SECURE_BINARIES_ANALYZERS: >-
- bandit, brakeman, gosec, spotbugs, flawfinder, phpcs-security-audit, security-code-scan, nodejs-scan, eslint, secrets, sobelow, pmd-apex, kubesec, semgrep,
+ bandit, brakeman, gosec, spotbugs, flawfinder, phpcs-security-audit, security-code-scan, nodejs-scan, eslint, secrets, sobelow, pmd-apex, kics, kubesec, semgrep,
bundler-audit, retire.js, gemnasium, gemnasium-maven, gemnasium-python,
license-finder,
dast, dast-runner-validation, api-fuzzing
@@ -40,7 +43,7 @@ variables:
script:
- docker info
- env
- - if [ -z "$SECURE_BINARIES_IMAGE" ]; then export SECURE_BINARIES_IMAGE=${SECURE_BINARIES_IMAGE:-"registry.gitlab.com/gitlab-org/security-products/analyzers/${CI_JOB_NAME}:${SECURE_BINARIES_ANALYZER_VERSION}"}; fi
+ - if [ -z "$SECURE_BINARIES_IMAGE" ]; then export SECURE_BINARIES_IMAGE=${SECURE_BINARIES_IMAGE:-"${SECURE_ANALYZERS_PREFIX}/${CI_JOB_NAME}:${SECURE_BINARIES_ANALYZER_VERSION}"}; fi
- docker pull --quiet ${SECURE_BINARIES_IMAGE}
- mkdir -p output/$(dirname ${CI_JOB_NAME})
- |
diff --git a/lib/gitlab/ci/templates/Terraform/Base.gitlab-ci.yml b/lib/gitlab/ci/templates/Terraform/Base.gitlab-ci.yml
index e696c75253e..84a962e1541 100644
--- a/lib/gitlab/ci/templates/Terraform/Base.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Terraform/Base.gitlab-ci.yml
@@ -24,19 +24,19 @@ cache:
.init: &init
stage: init
script:
- - cd ${TF_ROOT}
+ - cd "${TF_ROOT}"
- gitlab-terraform init
.validate: &validate
stage: validate
script:
- - cd ${TF_ROOT}
+ - cd "${TF_ROOT}"
- gitlab-terraform validate
.build: &build
stage: build
script:
- - cd ${TF_ROOT}
+ - cd "${TF_ROOT}"
- gitlab-terraform plan
- gitlab-terraform plan-json
artifacts:
@@ -48,7 +48,7 @@ cache:
.deploy: &deploy
stage: deploy
script:
- - cd ${TF_ROOT}
+ - cd "${TF_ROOT}"
- gitlab-terraform apply
when: manual
only:
@@ -58,6 +58,6 @@ cache:
.destroy: &destroy
stage: cleanup
script:
- - cd ${TF_ROOT}
+ - cd "${TF_ROOT}"
- gitlab-terraform destroy
when: manual
diff --git a/lib/gitlab/ci/templates/Verify/Accessibility.gitlab-ci.yml b/lib/gitlab/ci/templates/Verify/Accessibility.gitlab-ci.yml
index 8f4a836441d..5ea2bc07ffa 100644
--- a/lib/gitlab/ci/templates/Verify/Accessibility.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Verify/Accessibility.gitlab-ci.yml
@@ -14,7 +14,8 @@ stages:
a11y:
stage: accessibility
image: registry.gitlab.com/gitlab-org/ci-cd/accessibility:6.1.1
- script: /gitlab-accessibility.sh $a11y_urls
+ script:
+ - /gitlab-accessibility.sh "$a11y_urls"
allow_failure: true
artifacts:
when: always
diff --git a/lib/gitlab/ci/templates/Verify/Browser-Performance.gitlab-ci.yml b/lib/gitlab/ci/templates/Verify/Browser-Performance.gitlab-ci.yml
index e0df9799917..2349c37c130 100644
--- a/lib/gitlab/ci/templates/Verify/Browser-Performance.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Verify/Browser-Performance.gitlab-ci.yml
@@ -25,7 +25,7 @@ browser_performance:
- mkdir gitlab-exporter
# Busybox wget does not support proxied HTTPS, get the real thing.
# See https://gitlab.com/gitlab-org/gitlab/-/issues/287611.
- - (env | grep -i _proxy= 2>&1 >/dev/null) && apk --no-cache add wget
+ - (env | grep -i _proxy= >/dev/null 2>&1) && apk --no-cache add wget
- wget -O ./gitlab-exporter/index.js https://gitlab.com/gitlab-org/gl-performance/raw/1.1.0/index.js
- mkdir sitespeed-results
- |
diff --git a/lib/gitlab/ci/templates/Verify/Browser-Performance.latest.gitlab-ci.yml b/lib/gitlab/ci/templates/Verify/Browser-Performance.latest.gitlab-ci.yml
index ad24ebae8d4..73ab5fcbe44 100644
--- a/lib/gitlab/ci/templates/Verify/Browser-Performance.latest.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Verify/Browser-Performance.latest.gitlab-ci.yml
@@ -25,7 +25,7 @@ browser_performance:
- mkdir gitlab-exporter
# Busybox wget does not support proxied HTTPS, get the real thing.
# See https://gitlab.com/gitlab-org/gitlab/-/issues/287611.
- - (env | grep -i _proxy= 2>&1 >/dev/null) && apk --no-cache add wget
+ - (env | grep -i _proxy= >/dev/null 2>&1) && apk --no-cache add wget
- wget -O ./gitlab-exporter/index.js https://gitlab.com/gitlab-org/gl-performance/raw/1.1.0/index.js
- mkdir sitespeed-results
- |
diff --git a/lib/gitlab/ci/trace/remote_checksum.rb b/lib/gitlab/ci/trace/remote_checksum.rb
index 7f43d91e6d7..eaa9be9dd15 100644
--- a/lib/gitlab/ci/trace/remote_checksum.rb
+++ b/lib/gitlab/ci/trace/remote_checksum.rb
@@ -23,6 +23,7 @@ module Gitlab
private
attr_reader :trace_artifact
+
delegate :aws?, :google?, to: :object_store_config, prefix: :provider
def fetch_md5_checksum
diff --git a/lib/gitlab/ci/variables/builder.rb b/lib/gitlab/ci/variables/builder.rb
index 9ef6e7f5fa9..bfcf67693e7 100644
--- a/lib/gitlab/ci/variables/builder.rb
+++ b/lib/gitlab/ci/variables/builder.rb
@@ -10,6 +10,7 @@ module Gitlab
@pipeline = pipeline
@instance_variables_builder = Builder::Instance.new
@project_variables_builder = Builder::Project.new(project)
+ @group_variables_builder = Builder::Group.new(project.group)
end
def scoped_variables(job, environment:, dependencies:)
@@ -18,8 +19,7 @@ module Gitlab
variables.concat(project.predefined_variables)
variables.concat(pipeline.predefined_variables)
variables.concat(job.runner.predefined_variables) if job.runnable? && job.runner
- variables.concat(kubernetes_variables(job))
- variables.concat(deployment_variables(environment: environment, job: job))
+ variables.concat(kubernetes_variables(environment: environment, job: job))
variables.concat(job.yaml_variables)
variables.concat(user_variables(job.user))
variables.concat(job.dependency_variables) if dependencies
@@ -32,11 +32,15 @@ module Gitlab
end
end
- def kubernetes_variables(job)
+ def kubernetes_variables(environment:, job:)
::Gitlab::Ci::Variables::Collection.new.tap do |collection|
- # Should get merged with the cluster kubeconfig in deployment_variables, see
- # https://gitlab.com/gitlab-org/gitlab/-/issues/335089
+ # NOTE: deployment_variables will be removed as part of cleanup for
+ # https://gitlab.com/groups/gitlab-org/configure/-/epics/8
+ # Until then, we need to make both the old and the new KUBECONFIG contexts available
+ collection.concat(deployment_variables(environment: environment, job: job))
template = ::Ci::GenerateKubeconfigService.new(job).execute
+ kubeconfig_yaml = collection['KUBECONFIG']&.value
+ template.merge_yaml(kubeconfig_yaml) if kubeconfig_yaml.present?
if template.valid?
collection.append(key: 'KUBECONFIG', value: template.to_yaml, public: false, file: true)
@@ -72,9 +76,13 @@ module Gitlab
end
def secret_group_variables(environment:, ref:)
- return [] unless project.group
+ if memoize_secret_variables?
+ memoized_secret_group_variables(environment: environment)
+ else
+ return [] unless project.group
- project.group.ci_variables_for(ref, project, environment: environment)
+ project.group.ci_variables_for(ref, project, environment: environment)
+ end
end
def secret_project_variables(environment:, ref:)
@@ -90,6 +98,8 @@ module Gitlab
attr_reader :pipeline
attr_reader :instance_variables_builder
attr_reader :project_variables_builder
+ attr_reader :group_variables_builder
+
delegate :project, to: :pipeline
def predefined_variables(job)
@@ -119,6 +129,15 @@ module Gitlab
end
end
+ def memoized_secret_group_variables(environment:)
+ strong_memoize_with(:secret_group_variables, environment) do
+ group_variables_builder
+ .secret_variables(
+ environment: environment,
+ protected_ref: protected_ref?)
+ end
+ end
+
def ci_node_total_value(job)
parallel = job.options&.dig(:parallel)
parallel = parallel.dig(:total) if parallel.is_a?(Hash)
diff --git a/lib/gitlab/ci/variables/builder/group.rb b/lib/gitlab/ci/variables/builder/group.rb
new file mode 100644
index 00000000000..3f3e04038df
--- /dev/null
+++ b/lib/gitlab/ci/variables/builder/group.rb
@@ -0,0 +1,48 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Ci
+ module Variables
+ class Builder
+ class Group
+ include Gitlab::Utils::StrongMemoize
+
+ def initialize(group)
+ @group = group
+ end
+
+ def secret_variables(environment:, protected_ref: false)
+ return [] unless group
+
+ variables = base_scope
+ variables = variables.unprotected unless protected_ref
+ variables = variables.for_environment(environment)
+ variables = variables.group_by(&:group_id)
+ variables = list_of_ids.reverse.flat_map { |group| variables[group.id] }.compact
+ Gitlab::Ci::Variables::Collection.new(variables)
+ end
+
+ private
+
+ attr_reader :group
+
+ def base_scope
+ strong_memoize(:base_scope) do
+ ::Ci::GroupVariable.for_groups(list_of_ids)
+ end
+ end
+
+ def list_of_ids
+ strong_memoize(:list_of_ids) do
+ if group.root_ancestor.use_traversal_ids?
+ [group] + group.ancestors(hierarchy_order: :asc)
+ else
+ [group] + group.ancestors
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/ci/yaml_processor.rb b/lib/gitlab/ci/yaml_processor.rb
index 553508c8638..15ebd506055 100644
--- a/lib/gitlab/ci/yaml_processor.rb
+++ b/lib/gitlab/ci/yaml_processor.rb
@@ -45,7 +45,7 @@ module Gitlab
validate_job!(name, job)
end
- YamlProcessor::Dag.check_circular_dependencies!(@jobs)
+ check_circular_dependencies
end
def validate_job!(name, job)
@@ -146,6 +146,17 @@ module Gitlab
end
end
+ def check_circular_dependencies
+ jobs = @jobs.values.to_h do |job|
+ name = job[:name].to_s
+ needs = job.dig(:needs, :job).to_a
+
+ [name, needs.map { |need| need[:name].to_s }]
+ end
+
+ Dag.check_circular_dependencies!(jobs)
+ end
+
def error!(message)
raise ValidationError, message
end
diff --git a/lib/gitlab/ci/yaml_processor/dag.rb b/lib/gitlab/ci/yaml_processor/dag.rb
index 8ab9573dd20..4a122c73e80 100644
--- a/lib/gitlab/ci/yaml_processor/dag.rb
+++ b/lib/gitlab/ci/yaml_processor/dag.rb
@@ -7,28 +7,22 @@ module Gitlab
class Dag
include TSort
- MissingNodeError = Class.new(StandardError)
-
def initialize(nodes)
@nodes = nodes
end
- def self.check_circular_dependencies!(jobs)
- nodes = jobs.values.to_h do |job|
- name = job[:name].to_s
- needs = job.dig(:needs, :job).to_a
-
- [name, needs.map { |need| need[:name].to_s }]
- end
+ def self.order(jobs)
+ new(jobs).tsort
+ end
- new(nodes).tsort
+ def self.check_circular_dependencies!(jobs)
+ new(jobs).tsort
rescue TSort::Cyclic
raise ValidationError, 'The pipeline has circular dependencies'
- rescue MissingNodeError
end
def tsort_each_child(node, &block)
- raise MissingNodeError, "node #{node} is missing" unless @nodes[node]
+ return unless @nodes[node]
@nodes[node].each(&block)
end
diff --git a/lib/gitlab/color.rb b/lib/gitlab/color.rb
new file mode 100644
index 00000000000..e0caabb0ec6
--- /dev/null
+++ b/lib/gitlab/color.rb
@@ -0,0 +1,222 @@
+# frozen_string_literal: true
+
+module Gitlab
+ class Color
+ PATTERN = /\A\#(?:[0-9A-Fa-f]{3}){1,2}\Z/.freeze
+
+ def initialize(value)
+ @value = value&.strip&.freeze
+ end
+
+ module Constants
+ DARK = Color.new('#333333')
+ LIGHT = Color.new('#FFFFFF')
+
+ COLOR_NAME_TO_HEX = {
+ black: '#000000',
+ silver: '#C0C0C0',
+ gray: '#808080',
+ white: '#FFFFFF',
+ maroon: '#800000',
+ red: '#FF0000',
+ purple: '#800080',
+ fuchsia: '#FF00FF',
+ green: '#008000',
+ lime: '#00FF00',
+ olive: '#808000',
+ yellow: '#FFFF00',
+ navy: '#000080',
+ blue: '#0000FF',
+ teal: '#008080',
+ aqua: '#00FFFF',
+ orange: '#FFA500',
+ aliceblue: '#F0F8FF',
+ antiquewhite: '#FAEBD7',
+ aquamarine: '#7FFFD4',
+ azure: '#F0FFFF',
+ beige: '#F5F5DC',
+ bisque: '#FFE4C4',
+ blanchedalmond: '#FFEBCD',
+ blueviolet: '#8A2BE2',
+ brown: '#A52A2A',
+ burlywood: '#DEB887',
+ cadetblue: '#5F9EA0',
+ chartreuse: '#7FFF00',
+ chocolate: '#D2691E',
+ coral: '#FF7F50',
+ cornflowerblue: '#6495ED',
+ cornsilk: '#FFF8DC',
+ crimson: '#DC143C',
+ darkblue: '#00008B',
+ darkcyan: '#008B8B',
+ darkgoldenrod: '#B8860B',
+ darkgray: '#A9A9A9',
+ darkgreen: '#006400',
+ darkgrey: '#A9A9A9',
+ darkkhaki: '#BDB76B',
+ darkmagenta: '#8B008B',
+ darkolivegreen: '#556B2F',
+ darkorange: '#FF8C00',
+ darkorchid: '#9932CC',
+ darkred: '#8B0000',
+ darksalmon: '#E9967A',
+ darkseagreen: '#8FBC8F',
+ darkslateblue: '#483D8B',
+ darkslategray: '#2F4F4F',
+ darkslategrey: '#2F4F4F',
+ darkturquoise: '#00CED1',
+ darkviolet: '#9400D3',
+ deeppink: '#FF1493',
+ deepskyblue: '#00BFFF',
+ dimgray: '#696969',
+ dimgrey: '#696969',
+ dodgerblue: '#1E90FF',
+ firebrick: '#B22222',
+ floralwhite: '#FFFAF0',
+ forestgreen: '#228B22',
+ gainsboro: '#DCDCDC',
+ ghostwhite: '#F8F8FF',
+ gold: '#FFD700',
+ goldenrod: '#DAA520',
+ greenyellow: '#ADFF2F',
+ grey: '#808080',
+ honeydew: '#F0FFF0',
+ hotpink: '#FF69B4',
+ indianred: '#CD5C5C',
+ indigo: '#4B0082',
+ ivory: '#FFFFF0',
+ khaki: '#F0E68C',
+ lavender: '#E6E6FA',
+ lavenderblush: '#FFF0F5',
+ lawngreen: '#7CFC00',
+ lemonchiffon: '#FFFACD',
+ lightblue: '#ADD8E6',
+ lightcoral: '#F08080',
+ lightcyan: '#E0FFFF',
+ lightgoldenrodyellow: '#FAFAD2',
+ lightgray: '#D3D3D3',
+ lightgreen: '#90EE90',
+ lightgrey: '#D3D3D3',
+ lightpink: '#FFB6C1',
+ lightsalmon: '#FFA07A',
+ lightseagreen: '#20B2AA',
+ lightskyblue: '#87CEFA',
+ lightslategray: '#778899',
+ lightslategrey: '#778899',
+ lightsteelblue: '#B0C4DE',
+ lightyellow: '#FFFFE0',
+ limegreen: '#32CD32',
+ linen: '#FAF0E6',
+ mediumaquamarine: '#66CDAA',
+ mediumblue: '#0000CD',
+ mediumorchid: '#BA55D3',
+ mediumpurple: '#9370DB',
+ mediumseagreen: '#3CB371',
+ mediumslateblue: '#7B68EE',
+ mediumspringgreen: '#00FA9A',
+ mediumturquoise: '#48D1CC',
+ mediumvioletred: '#C71585',
+ midnightblue: '#191970',
+ mintcream: '#F5FFFA',
+ mistyrose: '#FFE4E1',
+ moccasin: '#FFE4B5',
+ navajowhite: '#FFDEAD',
+ oldlace: '#FDF5E6',
+ olivedrab: '#6B8E23',
+ orangered: '#FF4500',
+ orchid: '#DA70D6',
+ palegoldenrod: '#EEE8AA',
+ palegreen: '#98FB98',
+ paleturquoise: '#AFEEEE',
+ palevioletred: '#DB7093',
+ papayawhip: '#FFEFD5',
+ peachpuff: '#FFDAB9',
+ peru: '#CD853F',
+ pink: '#FFC0CB',
+ plum: '#DDA0DD',
+ powderblue: '#B0E0E6',
+ rosybrown: '#BC8F8F',
+ royalblue: '#4169E1',
+ saddlebrown: '#8B4513',
+ salmon: '#FA8072',
+ sandybrown: '#F4A460',
+ seagreen: '#2E8B57',
+ seashell: '#FFF5EE',
+ sienna: '#A0522D',
+ skyblue: '#87CEEB',
+ slateblue: '#6A5ACD',
+ slategray: '#708090',
+ slategrey: '#708090',
+ snow: '#FFFAFA',
+ springgreen: '#00FF7F',
+ steelblue: '#4682B4',
+ tan: '#D2B48C',
+ thistle: '#D8BFD8',
+ tomato: '#FF6347',
+ turquoise: '#40E0D0',
+ violet: '#EE82EE',
+ wheat: '#F5DEB3',
+ whitesmoke: '#F5F5F5',
+ yellowgreen: '#9ACD32',
+ rebeccapurple: '#663399'
+ }.stringify_keys.transform_values { Color.new(_1) }.freeze
+ end
+
+ def self.of(color)
+ raise ArgumentError, 'No color spec' unless color
+ return color if color.is_a?(self)
+
+ color = color.to_s.strip
+ Constants::COLOR_NAME_TO_HEX[color.downcase] || new(color)
+ end
+
+ def to_s
+ @value.to_s
+ end
+
+ def as_json(_options = nil)
+ to_s
+ end
+
+ def eql(other)
+ return false unless other.is_a?(self.class)
+
+ to_s == other.to_s
+ end
+ alias_method :==, :eql
+
+ def valid?
+ PATTERN.match?(@value)
+ end
+
+ def light?
+ valid? && rgb.sum > 500
+ end
+
+ def luminosity
+ return :light if light?
+
+ :dark
+ end
+
+ def contrast
+ return Constants::DARK if light?
+
+ Constants::LIGHT
+ end
+
+ private
+
+ def rgb
+ return [] unless valid?
+
+ @rgb ||= begin
+ if @value.length == 4
+ @value[1, 4].scan(/./).map { |v| (v * 2).hex }
+ else
+ @value[1, 7].scan(/.{2}/).map(&:hex)
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/config/entry/validators.rb b/lib/gitlab/config/entry/validators.rb
index b2bc56f46ee..cc24ae837f3 100644
--- a/lib/gitlab/config/entry/validators.rb
+++ b/lib/gitlab/config/entry/validators.rb
@@ -39,6 +39,17 @@ module Gitlab
end
end
+ class MutuallyExclusiveKeysValidator < ActiveModel::EachValidator
+ def validate_each(record, attribute, value)
+ mutually_exclusive_keys = value.try(:keys).to_a & options[:in]
+
+ if mutually_exclusive_keys.length > 1
+ record.errors.add(attribute, "please use only one the following keys: " +
+ mutually_exclusive_keys.join(', '))
+ end
+ end
+ end
+
class AllowedValuesValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
unless options[:in].include?(value.to_s)
@@ -217,12 +228,6 @@ module Gitlab
end
end
- protected
-
- def fallback
- false
- end
-
private
def matches_syntax?(value)
@@ -231,7 +236,7 @@ module Gitlab
def validate_regexp(value)
matches_syntax?(value) &&
- Gitlab::UntrustedRegexp::RubySyntax.valid?(value, fallback: fallback)
+ Gitlab::UntrustedRegexp::RubySyntax.valid?(value)
end
end
@@ -260,27 +265,6 @@ module Gitlab
end
end
- class ArrayOfStringsOrRegexpsWithFallbackValidator < ArrayOfStringsOrRegexpsValidator
- protected
-
- # TODO
- #
- # Remove ArrayOfStringsOrRegexpsWithFallbackValidator class too when
- # you are removing the `:allow_unsafe_ruby_regexp` feature flag.
- #
- def validation_message
- if ::Feature.enabled?(:allow_unsafe_ruby_regexp, default_enabled: :yaml)
- 'should be an array of strings or regular expressions'
- else
- super
- end
- end
-
- def fallback
- true
- end
- end
-
class ArrayOfStringsOrStringValidator < RegexpValidator
def validate_each(record, attribute, value)
unless validate_array_of_strings_or_string(value)
diff --git a/lib/gitlab/content_security_policy/config_loader.rb b/lib/gitlab/content_security_policy/config_loader.rb
index 78ba0916808..0d4b913b7a0 100644
--- a/lib/gitlab/content_security_policy/config_loader.rb
+++ b/lib/gitlab/content_security_policy/config_loader.rb
@@ -15,7 +15,7 @@ module Gitlab
directives = {
'default_src' => "'self'",
'base_uri' => "'self'",
- 'connect_src' => "'self'",
+ 'connect_src' => ContentSecurityPolicy::Directives.connect_src,
'font_src' => "'self'",
'form_action' => "'self' https: http:",
'frame_ancestors' => "'self'",
diff --git a/lib/gitlab/content_security_policy/directives.rb b/lib/gitlab/content_security_policy/directives.rb
index 3b958f8c92e..4ad420f9e2f 100644
--- a/lib/gitlab/content_security_policy/directives.rb
+++ b/lib/gitlab/content_security_policy/directives.rb
@@ -7,6 +7,10 @@
module Gitlab
module ContentSecurityPolicy
module Directives
+ def self.connect_src
+ "'self'"
+ end
+
def self.frame_src
"https://www.google.com/recaptcha/ https://www.recaptcha.net/ https://content.googleapis.com https://content-compute.googleapis.com https://content-cloudbilling.googleapis.com https://content-cloudresourcemanager.googleapis.com https://www.googletagmanager.com/ns.html"
end
diff --git a/lib/gitlab/current_settings.rb b/lib/gitlab/current_settings.rb
index 0d6767ad564..8ef4977177a 100644
--- a/lib/gitlab/current_settings.rb
+++ b/lib/gitlab/current_settings.rb
@@ -70,6 +70,8 @@ module Gitlab
else
::ApplicationSetting.create_from_defaults
end
+ rescue ::ApplicationSetting::Recursion
+ in_memory_application_settings
end
def fake_application_settings(attributes = {})
diff --git a/lib/gitlab/cycle_analytics/summary/base.rb b/lib/gitlab/cycle_analytics/summary/base.rb
index f867dbd4d68..5605d48c543 100644
--- a/lib/gitlab/cycle_analytics/summary/base.rb
+++ b/lib/gitlab/cycle_analytics/summary/base.rb
@@ -4,27 +4,13 @@ module Gitlab
module CycleAnalytics
module Summary
class Base
+ include Gitlab::CycleAnalytics::Summary::Defaults
+
def initialize(project:, options:)
@project = project
@options = options
end
- def identifier
- self.class.name.demodulize.underscore.to_sym
- end
-
- def title
- raise NotImplementedError, "Expected #{self.name} to implement title"
- end
-
- def value
- raise NotImplementedError, "Expected #{self.name} to implement value"
- end
-
- def links
- []
- end
-
private
attr_reader :project, :options
diff --git a/lib/gitlab/cycle_analytics/summary/defaults.rb b/lib/gitlab/cycle_analytics/summary/defaults.rb
new file mode 100644
index 00000000000..468494a8ab8
--- /dev/null
+++ b/lib/gitlab/cycle_analytics/summary/defaults.rb
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module CycleAnalytics
+ module Summary
+ module Defaults
+ def identifier
+ self.class.name.demodulize.underscore.to_sym
+ end
+
+ # :nocov: the class including this concern is expected to test this method.
+ def title
+ raise NotImplementedError, "Expected #{self.name} to implement title"
+ end
+ # :nocov:
+
+ # :nocov: the class including this concern is expected to test this method.
+ def value
+ raise NotImplementedError, "Expected #{self.name} to implement value"
+ end
+ # :nocov:
+
+ def links
+ []
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/database.rb b/lib/gitlab/database.rb
index 9b32d285ec0..1b16873f737 100644
--- a/lib/gitlab/database.rb
+++ b/lib/gitlab/database.rb
@@ -195,6 +195,16 @@ module Gitlab
MAX_TIMESTAMP_VALUE > timestamp ? timestamp : MAX_TIMESTAMP_VALUE.dup
end
+ def self.all_uncached(&block)
+ # Calls to #uncached only disable caching for the current connection. Since the load balancer
+ # can potentially upgrade from read to read-write mode (using a different connection), we specify
+ # up-front that we'll explicitly use the primary for the duration of the operation.
+ Gitlab::Database::LoadBalancing::Session.current.use_primary do
+ base_models = database_base_models.values
+ base_models.reduce(block) { |blk, model| -> { model.uncached(&blk) } }.call
+ end
+ end
+
def self.allow_cross_joins_across_databases(url:)
# this method is implemented in:
# spec/support/database/prevent_cross_joins.rb
@@ -221,12 +231,26 @@ module Gitlab
::ActiveRecord::Base.configurations.configs_for(env_name: Rails.env).map(&:name)
end
+ # This returns all matching schemas that a given connection can use
+ # Since the `ActiveRecord::Base` might change the connection (from main to ci)
+ # This does not look at literal connection names, but rather compares
+ # models that are holders for a given db_config_name
+ def self.gitlab_schemas_for_connection(connection)
+ connection_name = self.db_config_name(connection)
+ primary_model = self.database_base_models.fetch(connection_name)
+
+ self.schemas_to_base_models
+ .select { |_, models| models.include?(primary_model) }
+ .keys
+ .map!(&:to_sym)
+ end
+
def self.db_config_for_connection(connection)
return unless connection
- # The LB connection proxy does not have a direct db_config
- # that can be referenced
- return if connection.is_a?(::Gitlab::Database::LoadBalancing::ConnectionProxy)
+ if connection.is_a?(::Gitlab::Database::LoadBalancing::ConnectionProxy)
+ return connection.load_balancer.configuration.primary_db_config
+ end
# During application init we might receive `NullPool`
return unless connection.respond_to?(:pool) &&
diff --git a/lib/gitlab/database/async_indexes/migration_helpers.rb b/lib/gitlab/database/async_indexes/migration_helpers.rb
index 2f990aba2fb..e9846dd4e85 100644
--- a/lib/gitlab/database/async_indexes/migration_helpers.rb
+++ b/lib/gitlab/database/async_indexes/migration_helpers.rb
@@ -5,6 +5,8 @@ module Gitlab
module AsyncIndexes
module MigrationHelpers
def unprepare_async_index(table_name, column_name, **options)
+ Gitlab::Database::QueryAnalyzers::RestrictAllowedSchemas.require_ddl_mode!
+
return unless async_index_creation_available?
index_name = options[:name] || index_name(table_name, column_name)
@@ -15,6 +17,8 @@ module Gitlab
end
def unprepare_async_index_by_name(table_name, index_name, **options)
+ Gitlab::Database::QueryAnalyzers::RestrictAllowedSchemas.require_ddl_mode!
+
return unless async_index_creation_available?
PostgresAsyncIndex.find_by(name: index_name).try do |async_index|
@@ -32,6 +36,8 @@ module Gitlab
# If the requested index has already been created, it is not stored in the table for
# asynchronous creation.
def prepare_async_index(table_name, column_name, **options)
+ Gitlab::Database::QueryAnalyzers::RestrictAllowedSchemas.require_ddl_mode!
+
return unless async_index_creation_available?
index_name = options[:name] || index_name(table_name, column_name)
@@ -72,8 +78,7 @@ module Gitlab
end
def async_index_creation_available?
- ApplicationRecord.connection.table_exists?(:postgres_async_indexes) &&
- Feature.enabled?(:database_async_index_creation, type: :ops)
+ connection.table_exists?(:postgres_async_indexes)
end
end
end
diff --git a/lib/gitlab/database/background_migration/batched_job.rb b/lib/gitlab/database/background_migration/batched_job.rb
index 185b6d9629f..f3160679d64 100644
--- a/lib/gitlab/database/background_migration/batched_job.rb
+++ b/lib/gitlab/database/background_migration/batched_job.rb
@@ -3,7 +3,9 @@
module Gitlab
module Database
module BackgroundMigration
- class BatchedJob < ActiveRecord::Base # rubocop:disable Rails/ApplicationRecord
+ SplitAndRetryError = Class.new(StandardError)
+
+ class BatchedJob < SharedModel
include EachBatch
include FromUnion
@@ -11,6 +13,8 @@ module Gitlab
MAX_ATTEMPTS = 3
STUCK_JOBS_TIMEOUT = 1.hour.freeze
+ TIMEOUT_EXCEPTIONS = [ActiveRecord::StatementTimeout, ActiveRecord::ConnectionTimeoutError,
+ ActiveRecord::AdapterTimeout, ActiveRecord::LockWaitTimeout].freeze
belongs_to :batched_migration, foreign_key: :batched_background_migration_id
has_many :batched_job_transition_logs, foreign_key: :batched_background_migration_job_id
@@ -51,6 +55,16 @@ module Gitlab
job.metrics = {}
end
+ after_transition any => :failed do |job, transition|
+ error_hash = transition.args.find { |arg| arg[:error].present? }
+
+ exception = error_hash&.fetch(:error)
+
+ job.split_and_retry! if job.can_split?(exception)
+ rescue SplitAndRetryError => error
+ Gitlab::AppLogger.error(message: error.message, batched_job_id: job.id)
+ end
+
after_transition do |job, transition|
error_hash = transition.args.find { |arg| arg[:error].present? }
@@ -79,20 +93,25 @@ module Gitlab
duration.to_f / batched_migration.interval
end
+ def can_split?(exception)
+ attempts >= MAX_ATTEMPTS && TIMEOUT_EXCEPTIONS.include?(exception&.class) && batch_size > sub_batch_size
+ end
+
def split_and_retry!
with_lock do
- raise 'Only failed jobs can be split' unless failed?
+ raise SplitAndRetryError, 'Only failed jobs can be split' unless failed?
new_batch_size = batch_size / 2
- raise 'Job cannot be split further' if new_batch_size < 1
+ raise SplitAndRetryError, 'Job cannot be split further' if new_batch_size < 1
- batching_strategy = batched_migration.batch_class.new
+ batching_strategy = batched_migration.batch_class.new(connection: self.class.connection)
next_batch_bounds = batching_strategy.next_batch(
batched_migration.table_name,
batched_migration.column_name,
batch_min_value: min_value,
- batch_size: new_batch_size
+ batch_size: new_batch_size,
+ job_arguments: batched_migration.job_arguments
)
midpoint = next_batch_bounds.last
diff --git a/lib/gitlab/database/background_migration/batched_job_transition_log.rb b/lib/gitlab/database/background_migration/batched_job_transition_log.rb
index 418bf1a101f..55a391005a2 100644
--- a/lib/gitlab/database/background_migration/batched_job_transition_log.rb
+++ b/lib/gitlab/database/background_migration/batched_job_transition_log.rb
@@ -3,7 +3,7 @@
module Gitlab
module Database
module BackgroundMigration
- class BatchedJobTransitionLog < ApplicationRecord
+ class BatchedJobTransitionLog < SharedModel
include PartitionedTable
self.table_name = :batched_background_migration_job_transition_logs
diff --git a/lib/gitlab/database/background_migration/batched_migration.rb b/lib/gitlab/database/background_migration/batched_migration.rb
index 1f8ca982ed5..65c15795de6 100644
--- a/lib/gitlab/database/background_migration/batched_migration.rb
+++ b/lib/gitlab/database/background_migration/batched_migration.rb
@@ -3,7 +3,7 @@
module Gitlab
module Database
module BackgroundMigration
- class BatchedMigration < ActiveRecord::Base # rubocop:disable Rails/ApplicationRecord
+ class BatchedMigration < SharedModel
JOB_CLASS_MODULE = 'Gitlab::BackgroundMigration'
BATCH_CLASS_MODULE = "#{JOB_CLASS_MODULE}::BatchingStrategies"
diff --git a/lib/gitlab/database/background_migration/batched_migration_runner.rb b/lib/gitlab/database/background_migration/batched_migration_runner.rb
index 9308bae20cf..06cd40f1e06 100644
--- a/lib/gitlab/database/background_migration/batched_migration_runner.rb
+++ b/lib/gitlab/database/background_migration/batched_migration_runner.rb
@@ -6,12 +6,13 @@ module Gitlab
class BatchedMigrationRunner
FailedToFinalize = Class.new(RuntimeError)
- def self.finalize(job_class_name, table_name, column_name, job_arguments)
- new.finalize(job_class_name, table_name, column_name, job_arguments)
+ def self.finalize(job_class_name, table_name, column_name, job_arguments, connection: ApplicationRecord.connection)
+ new(connection: connection).finalize(job_class_name, table_name, column_name, job_arguments)
end
- def initialize(migration_wrapper = BatchedMigrationWrapper.new)
+ def initialize(migration_wrapper = BatchedMigrationWrapper.new, connection: ApplicationRecord.connection)
@migration_wrapper = migration_wrapper
+ @connection = connection
end
# Runs the next batched_job for a batched_background_migration.
@@ -77,7 +78,7 @@ module Gitlab
private
- attr_reader :migration_wrapper
+ attr_reader :migration_wrapper, :connection
def find_or_create_next_batched_job(active_migration)
if next_batch_range = find_next_batch_range(active_migration)
@@ -88,7 +89,7 @@ module Gitlab
end
def find_next_batch_range(active_migration)
- batching_strategy = active_migration.batch_class.new
+ batching_strategy = active_migration.batch_class.new(connection: connection)
batch_min_value = active_migration.next_min_value
next_batch_bounds = batching_strategy.next_batch(
diff --git a/lib/gitlab/database/count/exact_count_strategy.rb b/lib/gitlab/database/count/exact_count_strategy.rb
index 0b8fe640bf8..345c7e44b05 100644
--- a/lib/gitlab/database/count/exact_count_strategy.rb
+++ b/lib/gitlab/database/count/exact_count_strategy.rb
@@ -12,6 +12,7 @@ module Gitlab
# Note that for very large tables, this may even timeout.
class ExactCountStrategy
attr_reader :models
+
def initialize(models)
@models = models
end
diff --git a/lib/gitlab/database/count/reltuples_count_strategy.rb b/lib/gitlab/database/count/reltuples_count_strategy.rb
index 68a0c15480a..0f89c500688 100644
--- a/lib/gitlab/database/count/reltuples_count_strategy.rb
+++ b/lib/gitlab/database/count/reltuples_count_strategy.rb
@@ -14,6 +14,7 @@ module Gitlab
# however is guaranteed to be "fast", because it only looks up statistics.
class ReltuplesCountStrategy
attr_reader :models
+
def initialize(models)
@models = models
end
@@ -46,7 +47,7 @@ module Gitlab
end
def table_to_model_mapping
- @table_to_model_mapping ||= models.each_with_object({}) { |model, h| h[model.table_name] = model }
+ @table_to_model_mapping ||= models.index_by(&:table_name)
end
def table_to_model(table_name)
diff --git a/lib/gitlab/database/each_database.rb b/lib/gitlab/database/each_database.rb
index c3eea0515d4..cccd4b48723 100644
--- a/lib/gitlab/database/each_database.rb
+++ b/lib/gitlab/database/each_database.rb
@@ -4,8 +4,11 @@ module Gitlab
module Database
module EachDatabase
class << self
- def each_database_connection
- Gitlab::Database.database_base_models.each_pair do |connection_name, model|
+ def each_database_connection(only: nil)
+ selected_names = Array.wrap(only)
+ base_models = select_base_models(selected_names)
+
+ base_models.each_pair do |connection_name, model|
connection = model.connection
with_shared_connection(connection, connection_name) do
@@ -14,34 +17,52 @@ module Gitlab
end
end
- def each_model_connection(models, &blk)
+ def each_model_connection(models, only_on: nil, &blk)
+ selected_databases = Array.wrap(only_on).map(&:to_sym)
+
models.each do |model|
# If model is shared, iterate all available base connections
# Example: `LooseForeignKeys::DeletedRecord`
if model < ::Gitlab::Database::SharedModel
- with_shared_model_connections(model, &blk)
+ with_shared_model_connections(model, selected_databases, &blk)
else
- with_model_connection(model, &blk)
+ with_model_connection(model, selected_databases, &blk)
end
end
end
private
- def with_shared_model_connections(shared_model, &blk)
+ def select_base_models(names)
+ base_models = Gitlab::Database.database_base_models
+
+ return base_models if names.empty?
+
+ names.each_with_object(HashWithIndifferentAccess.new) do |name, hash|
+ raise ArgumentError, "#{name} is not a valid database name" unless base_models.key?(name)
+
+ hash[name] = base_models[name]
+ end
+ end
+
+ def with_shared_model_connections(shared_model, selected_databases, &blk)
Gitlab::Database.database_base_models.each_pair do |connection_name, connection_model|
if shared_model.limit_connection_names
next unless shared_model.limit_connection_names.include?(connection_name.to_sym)
end
+ next if selected_databases.present? && !selected_databases.include?(connection_name.to_sym)
+
with_shared_connection(connection_model.connection, connection_name) do
yield shared_model, connection_name
end
end
end
- def with_model_connection(model, &blk)
- connection_name = model.connection.pool.db_config.name
+ def with_model_connection(model, selected_databases, &blk)
+ connection_name = model.connection_db_config.name
+
+ return if selected_databases.present? && !selected_databases.include?(connection_name.to_sym)
with_shared_connection(model.connection, connection_name) do
yield model, connection_name
diff --git a/lib/gitlab/database/gitlab_schema.rb b/lib/gitlab/database/gitlab_schema.rb
index 7adf6ba6afb..d7ea614e2af 100644
--- a/lib/gitlab/database/gitlab_schema.rb
+++ b/lib/gitlab/database/gitlab_schema.rb
@@ -95,6 +95,10 @@ module Gitlab
def self.tables_to_schema
@tables_to_schema ||= YAML.load_file(Rails.root.join('lib/gitlab/database/gitlab_schemas.yml'))
end
+
+ def self.schema_names
+ @schema_names ||= self.tables_to_schema.values.to_set
+ end
end
end
end
diff --git a/lib/gitlab/database/gitlab_schemas.yml b/lib/gitlab/database/gitlab_schemas.yml
index 93cd75ce5a7..dcd78bfd84f 100644
--- a/lib/gitlab/database/gitlab_schemas.yml
+++ b/lib/gitlab/database/gitlab_schemas.yml
@@ -8,6 +8,7 @@ alert_management_alert_metric_images: :gitlab_main
alert_management_alert_user_mentions: :gitlab_main
alert_management_http_integrations: :gitlab_main
allowed_email_domains: :gitlab_main
+analytics_cycle_analytics_aggregations: :gitlab_main
analytics_cycle_analytics_group_stages: :gitlab_main
analytics_cycle_analytics_group_value_streams: :gitlab_main
analytics_cycle_analytics_issue_stage_events: :gitlab_main
@@ -273,6 +274,7 @@ issue_emails: :gitlab_main
issue_email_participants: :gitlab_main
issue_links: :gitlab_main
issue_metrics: :gitlab_main
+issue_search_data: :gitlab_main
issues: :gitlab_main
issues_prometheus_alert_events: :gitlab_main
issues_self_managed_prometheus_alert_events: :gitlab_main
@@ -379,7 +381,6 @@ pages_deployments: :gitlab_main
pages_deployment_states: :gitlab_main
pages_domain_acme_orders: :gitlab_main
pages_domains: :gitlab_main
-partitioned_foreign_keys: :gitlab_main
path_locks: :gitlab_main
personal_access_tokens: :gitlab_main
plan_limits: :gitlab_main
@@ -400,6 +401,7 @@ project_alerting_settings: :gitlab_main
project_aliases: :gitlab_main
project_authorizations: :gitlab_main
project_auto_devops: :gitlab_main
+project_build_artifacts_size_refreshes: :gitlab_main
project_ci_cd_settings: :gitlab_main
project_ci_feature_usages: :gitlab_main
project_compliance_framework_settings: :gitlab_main
@@ -441,6 +443,7 @@ push_event_payloads: :gitlab_main
push_rules: :gitlab_main
raw_usage_data: :gitlab_main
redirect_routes: :gitlab_main
+related_epic_links: :gitlab_main
release_links: :gitlab_main
releases: :gitlab_main
remote_mirrors: :gitlab_main
@@ -457,6 +460,7 @@ reviews: :gitlab_main
routes: :gitlab_main
saml_group_links: :gitlab_main
saml_providers: :gitlab_main
+saved_replies: :gitlab_main
schema_migrations: :gitlab_shared
scim_identities: :gitlab_main
scim_oauth_access_tokens: :gitlab_main
diff --git a/lib/gitlab/database/load_balancing.rb b/lib/gitlab/database/load_balancing.rb
index e16db5af8ce..6517923d23e 100644
--- a/lib/gitlab/database/load_balancing.rb
+++ b/lib/gitlab/database/load_balancing.rb
@@ -47,6 +47,8 @@ module Gitlab
# Returns the role (primary/replica) of the database the connection is
# connecting to.
def self.db_role_for_connection(connection)
+ return ROLE_UNKNOWN if connection.is_a?(::Gitlab::Database::LoadBalancing::ConnectionProxy)
+
db_config = Database.db_config_for_connection(connection)
return ROLE_UNKNOWN unless db_config
diff --git a/lib/gitlab/database/load_balancing/configuration.rb b/lib/gitlab/database/load_balancing/configuration.rb
index 63444ebe169..86b3afaa47b 100644
--- a/lib/gitlab/database/load_balancing/configuration.rb
+++ b/lib/gitlab/database/load_balancing/configuration.rb
@@ -94,6 +94,10 @@ module Gitlab
end
end
+ def primary_db_config
+ primary_model_or_model_if_enabled.connection_db_config
+ end
+
def replica_db_config
@model.connection_db_config
end
diff --git a/lib/gitlab/database/load_balancing/setup.rb b/lib/gitlab/database/load_balancing/setup.rb
index 126c8bb2aa6..6d667e8ecf0 100644
--- a/lib/gitlab/database/load_balancing/setup.rb
+++ b/lib/gitlab/database/load_balancing/setup.rb
@@ -90,7 +90,8 @@ module Gitlab
def use_model_load_balancing?
# Cache environment variable and return env variable first if defined
- use_model_load_balancing_env = Gitlab::Utils.to_boolean(ENV["GITLAB_USE_MODEL_LOAD_BALANCING"])
+ default_use_model_load_balancing_env = Gitlab.dev_or_test_env? || nil
+ use_model_load_balancing_env = Gitlab::Utils.to_boolean(ENV.fetch('GITLAB_USE_MODEL_LOAD_BALANCING', default_use_model_load_balancing_env))
unless use_model_load_balancing_env.nil?
return use_model_load_balancing_env
diff --git a/lib/gitlab/database/migration_helpers/restrict_gitlab_schema.rb b/lib/gitlab/database/migration_helpers/restrict_gitlab_schema.rb
new file mode 100644
index 00000000000..b4e31565c60
--- /dev/null
+++ b/lib/gitlab/database/migration_helpers/restrict_gitlab_schema.rb
@@ -0,0 +1,58 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Database
+ module MigrationHelpers
+ module RestrictGitlabSchema
+ extend ActiveSupport::Concern
+
+ MigrationSkippedError = Class.new(StandardError)
+
+ included do
+ class_attribute :allowed_gitlab_schemas
+ end
+
+ class_methods do
+ def restrict_gitlab_migration(gitlab_schema:)
+ unless Gitlab::Database::GitlabSchema.schema_names.include?(gitlab_schema)
+ raise "Unknown 'gitlab_schema: #{gitlab_schema}' specified. It needs to be one of: " \
+ "#{Gitlab::Database::GitlabSchema.schema_names.to_a}"
+ end
+
+ self.allowed_gitlab_schemas = [gitlab_schema]
+ end
+ end
+
+ def migrate(direction)
+ if unmatched_schemas.any?
+ # TODO: Today skipping migration would raise an exception.
+ # Ideally, skipped migration should be ignored (not loaded), or softly ignored.
+ # Read more in: https://gitlab.com/gitlab-org/gitlab/-/issues/355014
+ raise MigrationSkippedError, "Current migration is skipped since it modifies "\
+ "'#{self.class.allowed_gitlab_schemas}' which is outside of '#{allowed_schemas_for_connection}'"
+ end
+
+ Gitlab::Database::QueryAnalyzer.instance.within([validator_class]) do
+ validator_class.allowed_gitlab_schemas = self.allowed_gitlab_schemas
+
+ super
+ end
+ end
+
+ private
+
+ def validator_class
+ Gitlab::Database::QueryAnalyzers::RestrictAllowedSchemas
+ end
+
+ def unmatched_schemas
+ (self.allowed_gitlab_schemas || []) - allowed_schemas_for_connection
+ end
+
+ def allowed_schemas_for_connection
+ Gitlab::Database.gitlab_schemas_for_connection(connection)
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/database/migrations/background_migration_helpers.rb b/lib/gitlab/database/migrations/background_migration_helpers.rb
index 4f1b490cc8f..7e5c002d072 100644
--- a/lib/gitlab/database/migrations/background_migration_helpers.rb
+++ b/lib/gitlab/database/migrations/background_migration_helpers.rb
@@ -42,7 +42,7 @@ module Gitlab
# end
def queue_background_migration_jobs_by_range_at_intervals(model_class, job_class_name, delay_interval, batch_size: BATCH_SIZE, other_job_arguments: [], initial_delay: 0, track_jobs: false, primary_column_name: :id)
raise "#{model_class} does not have an ID column of #{primary_column_name} to use for batch ranges" unless model_class.column_names.include?(primary_column_name.to_s)
- raise "#{primary_column_name} is not an integer column" unless model_class.columns_hash[primary_column_name.to_s].type == :integer
+ raise "#{primary_column_name} is not an integer or string column" unless [:integer, :string].include?(model_class.columns_hash[primary_column_name.to_s].type)
job_coordinator = coordinator_for_tracking_database
diff --git a/lib/gitlab/database/migrations/instrumentation.rb b/lib/gitlab/database/migrations/instrumentation.rb
index 7f34768350b..9d28db6b886 100644
--- a/lib/gitlab/database/migrations/instrumentation.rb
+++ b/lib/gitlab/database/migrations/instrumentation.rb
@@ -17,7 +17,11 @@ module Gitlab
def observe(version:, name:, connection:, &block)
observation = Observation.new(version: version, name: name, success: false)
- observers = observer_classes.map { |c| c.new(observation, @result_dir, connection) }
+ per_migration_result_dir = File.join(@result_dir, name)
+
+ FileUtils.mkdir_p(per_migration_result_dir)
+
+ observers = observer_classes.map { |c| c.new(observation, per_migration_result_dir, connection) }
on_each_observer(observers) { |observer| observer.before }
diff --git a/lib/gitlab/database/migrations/observers/query_details.rb b/lib/gitlab/database/migrations/observers/query_details.rb
index 8f4406e79a5..1549f5bf626 100644
--- a/lib/gitlab/database/migrations/observers/query_details.rb
+++ b/lib/gitlab/database/migrations/observers/query_details.rb
@@ -6,7 +6,7 @@ module Gitlab
module Observers
class QueryDetails < MigrationObserver
def before
- file_path = File.join(output_dir, "#{observation.version}_#{observation.name}-query-details.json")
+ file_path = File.join(output_dir, "query-details.json")
@file = File.open(file_path, 'wb')
@writer = Oj::StreamWriter.new(@file, {})
@writer.push_array
diff --git a/lib/gitlab/database/migrations/observers/query_log.rb b/lib/gitlab/database/migrations/observers/query_log.rb
index c42fd8bd23d..8ca57bb7df9 100644
--- a/lib/gitlab/database/migrations/observers/query_log.rb
+++ b/lib/gitlab/database/migrations/observers/query_log.rb
@@ -7,7 +7,7 @@ module Gitlab
class QueryLog < MigrationObserver
def before
@logger_was = ActiveRecord::Base.logger
- file_path = File.join(output_dir, "#{observation.version}_#{observation.name}.log")
+ file_path = File.join(output_dir, "migration.log")
@logger = Logger.new(file_path)
ActiveRecord::Base.logger = @logger
end
diff --git a/lib/gitlab/database/migrations/observers/transaction_duration.rb b/lib/gitlab/database/migrations/observers/transaction_duration.rb
index a96b94334cf..182aeb10fda 100644
--- a/lib/gitlab/database/migrations/observers/transaction_duration.rb
+++ b/lib/gitlab/database/migrations/observers/transaction_duration.rb
@@ -6,7 +6,7 @@ module Gitlab
module Observers
class TransactionDuration < MigrationObserver
def before
- file_path = File.join(output_dir, "#{observation.version}_#{observation.name}-transaction-duration.json")
+ file_path = File.join(output_dir, "transaction-duration.json")
@file = File.open(file_path, 'wb')
@writer = Oj::StreamWriter.new(@file, {})
@writer.push_array
diff --git a/lib/gitlab/database/migrations/runner.rb b/lib/gitlab/database/migrations/runner.rb
index f0bac594119..02645a0d452 100644
--- a/lib/gitlab/database/migrations/runner.rb
+++ b/lib/gitlab/database/migrations/runner.rb
@@ -5,6 +5,8 @@ module Gitlab
module Migrations
class Runner
BASE_RESULT_DIR = Rails.root.join('tmp', 'migration-testing').freeze
+ METADATA_FILENAME = 'metadata.json'
+ SCHEMA_VERSION = 2 # Version of the output format produced by the runner
class << self
def up
@@ -75,9 +77,11 @@ module Gitlab
end
ensure
if instrumentation
- File.open(File.join(result_dir, Gitlab::Database::Migrations::Instrumentation::STATS_FILENAME), 'wb+') do |io|
- io << instrumentation.observations.to_json
- end
+ stats_filename = File.join(result_dir, Gitlab::Database::Migrations::Instrumentation::STATS_FILENAME)
+ File.write(stats_filename, instrumentation.observations.to_json)
+
+ metadata_filename = File.join(result_dir, METADATA_FILENAME)
+ File.write(metadata_filename, { version: SCHEMA_VERSION }.to_json)
end
# We clear the cache here to mirror the cache clearing that happens at the end of `db:migrate` tasks
diff --git a/lib/gitlab/database/migrations/test_background_runner.rb b/lib/gitlab/database/migrations/test_background_runner.rb
new file mode 100644
index 00000000000..821d68c06c9
--- /dev/null
+++ b/lib/gitlab/database/migrations/test_background_runner.rb
@@ -0,0 +1,49 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Database
+ module Migrations
+ class TestBackgroundRunner
+ # TODO - build a rake task to call this method, and support it in the gitlab-com-database-testing project.
+ # Until then, we will inject a migration with a very high timestamp during database testing
+ # that calls this class to run jobs
+ # See https://gitlab.com/gitlab-org/database-team/gitlab-com-database-testing/-/issues/41 for details
+
+ def initialize
+ @job_coordinator = Gitlab::BackgroundMigration.coordinator_for_database(Gitlab::Database::MAIN_DATABASE_NAME)
+ end
+
+ def traditional_background_migrations
+ @job_coordinator.pending_jobs
+ end
+
+ def run_jobs(for_duration:)
+ jobs_to_run = traditional_background_migrations.group_by { |j| class_name_for_job(j) }
+ return if jobs_to_run.empty?
+
+ # without .to_f, we do integer division
+ # For example, 3.minutes / 2 == 1.minute whereas 3.minutes / 2.to_f == (1.minute + 30.seconds)
+ duration_per_migration_type = for_duration / jobs_to_run.count.to_f
+ jobs_to_run.each do |_migration_name, jobs|
+ run_until = duration_per_migration_type.from_now
+ jobs.shuffle.each do |j|
+ break if run_until <= Time.current
+
+ run_job(j)
+ end
+ end
+ end
+
+ private
+
+ def run_job(job)
+ Gitlab::BackgroundMigration.perform(job.args[0], job.args[1])
+ end
+
+ def class_name_for_job(job)
+ job.args[0]
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/database/partitioning.rb b/lib/gitlab/database/partitioning.rb
index c7d8bdf30bc..92825d41599 100644
--- a/lib/gitlab/database/partitioning.rb
+++ b/lib/gitlab/database/partitioning.rb
@@ -26,10 +26,10 @@ module Gitlab
# ignore - happens when Rake tasks yet have to create a database, e.g. for testing
end
- def sync_partitions(models_to_sync = registered_for_sync)
+ def sync_partitions(models_to_sync = registered_for_sync, only_on: nil)
Gitlab::AppLogger.info(message: 'Syncing dynamic postgres partitions')
- Gitlab::Database::EachDatabase.each_model_connection(models_to_sync) do |model|
+ Gitlab::Database::EachDatabase.each_model_connection(models_to_sync, only_on: only_on) do |model|
PartitionManager.new(model).sync_partitions
end
diff --git a/lib/gitlab/database/partitioning/partition_manager.rb b/lib/gitlab/database/partitioning/partition_manager.rb
index ab414f91169..3ee9a193b45 100644
--- a/lib/gitlab/database/partitioning/partition_manager.rb
+++ b/lib/gitlab/database/partitioning/partition_manager.rb
@@ -46,6 +46,7 @@ module Gitlab
private
attr_reader :model
+
delegate :connection, to: :model
def missing_partitions
diff --git a/lib/gitlab/database/partitioning/replace_table.rb b/lib/gitlab/database/partitioning/replace_table.rb
index a7686e97553..21a175a660d 100644
--- a/lib/gitlab/database/partitioning/replace_table.rb
+++ b/lib/gitlab/database/partitioning/replace_table.rb
@@ -31,6 +31,7 @@ module Gitlab
private
attr_reader :connection
+
delegate :execute, :quote_table_name, :quote_column_name, to: :connection
def default_sequence(table, column)
diff --git a/lib/gitlab/database/query_analyzer.rb b/lib/gitlab/database/query_analyzer.rb
index 2736f9d18dc..0c78dda734c 100644
--- a/lib/gitlab/database/query_analyzer.rb
+++ b/lib/gitlab/database/query_analyzer.rb
@@ -30,13 +30,17 @@ module Gitlab
end
end
- def within
+ def within(user_analyzers = nil)
# Due to singleton nature of analyzers
# only an outer invocation of the `.within`
# is allowed to initialize them
- return yield if already_within?
+ if already_within?
+ raise 'Query analyzers are already defined, cannot re-define them.' if user_analyzers
- begin!
+ return yield
+ end
+
+ begin!(user_analyzers || all_analyzers)
begin
yield
@@ -61,21 +65,21 @@ module Gitlab
next if analyzer.suppressed? && !analyzer.requires_tracking?(parsed)
analyzer.analyze(parsed)
- rescue StandardError, QueryAnalyzers::Base::QueryAnalyzerError => e
+ rescue StandardError, ::Gitlab::Database::QueryAnalyzers::Base::QueryAnalyzerError => e
# We catch all standard errors to prevent validation errors to introduce fatal errors in production
Gitlab::ErrorTracking.track_and_raise_for_dev_exception(e)
end
end
# Enable query analyzers
- def begin!
- analyzers = all_analyzers.select do |analyzer|
+ def begin!(analyzers = all_analyzers)
+ analyzers = analyzers.select do |analyzer|
if analyzer.enabled?
analyzer.begin!
true
end
- rescue StandardError, QueryAnalyzers::Base::QueryAnalyzerError => e
+ rescue StandardError, ::Gitlab::Database::QueryAnalyzers::Base::QueryAnalyzerError => e
Gitlab::ErrorTracking.track_and_raise_for_dev_exception(e)
false
@@ -88,7 +92,7 @@ module Gitlab
def end!
enabled_analyzers.select do |analyzer|
analyzer.end!
- rescue StandardError, QueryAnalyzers::Base::QueryAnalyzerError => e
+ rescue StandardError, ::Gitlab::Database::QueryAnalyzers::Base::QueryAnalyzerError => e
Gitlab::ErrorTracking.track_and_raise_for_dev_exception(e)
end
diff --git a/lib/gitlab/database/query_analyzers/prevent_cross_database_modification.rb b/lib/gitlab/database/query_analyzers/prevent_cross_database_modification.rb
index a604f79dc41..a53da514df2 100644
--- a/lib/gitlab/database/query_analyzers/prevent_cross_database_modification.rb
+++ b/lib/gitlab/database/query_analyzers/prevent_cross_database_modification.rb
@@ -94,7 +94,7 @@ module Gitlab
if schemas.many?
message = "Cross-database data modification of '#{schemas.to_a.join(", ")}' were detected within " \
- "a transaction modifying the '#{all_tables.to_a.join(", ")}' tables." \
+ "a transaction modifying the '#{all_tables.to_a.join(", ")}' tables. " \
"Please refer to https://docs.gitlab.com/ee/development/database/multiple_databases.html#removing-cross-database-transactions for details on how to resolve this exception."
if schemas.any? { |s| s.to_s.start_with?("undefined") }
diff --git a/lib/gitlab/database/query_analyzers/restrict_allowed_schemas.rb b/lib/gitlab/database/query_analyzers/restrict_allowed_schemas.rb
new file mode 100644
index 00000000000..ab40ba5d59b
--- /dev/null
+++ b/lib/gitlab/database/query_analyzers/restrict_allowed_schemas.rb
@@ -0,0 +1,106 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Database
+ module QueryAnalyzers
+ class RestrictAllowedSchemas < Base
+ UnsupportedSchemaError = Class.new(QueryAnalyzerError)
+ DDLNotAllowedError = Class.new(UnsupportedSchemaError)
+ DMLNotAllowedError = Class.new(UnsupportedSchemaError)
+ DMLAccessDeniedError = Class.new(UnsupportedSchemaError)
+
+ IGNORED_SCHEMAS = %i[gitlab_shared].freeze
+
+ class << self
+ def enabled?
+ true
+ end
+
+ def allowed_gitlab_schemas
+ self.context[:allowed_gitlab_schemas]
+ end
+
+ def allowed_gitlab_schemas=(value)
+ self.context[:allowed_gitlab_schemas] = value
+ end
+
+ def analyze(parsed)
+ # If list of schemas is empty, we allow only DDL changes
+ if self.dml_mode?
+ self.restrict_to_dml_only(parsed)
+ else
+ self.restrict_to_ddl_only(parsed)
+ end
+ end
+
+ def require_ddl_mode!(message = "")
+ return unless self.context
+
+ self.raise_dml_not_allowed_error(message) if self.dml_mode?
+ end
+
+ def require_dml_mode!(message = "")
+ return unless self.context
+
+ self.raise_ddl_not_allowed_error(message) if self.ddl_mode?
+ end
+
+ private
+
+ def restrict_to_ddl_only(parsed)
+ tables = self.dml_tables(parsed)
+ schemas = self.dml_schemas(tables)
+
+ if schemas.any?
+ self.raise_dml_not_allowed_error("Modifying of '#{tables}' (#{schemas.to_a}) with '#{parsed.sql}'")
+ end
+ end
+
+ def restrict_to_dml_only(parsed)
+ if parsed.pg.ddl_tables.any?
+ self.raise_ddl_not_allowed_error("Modifying of '#{parsed.pg.ddl_tables}' with '#{parsed.sql}'")
+ end
+
+ if parsed.pg.ddl_functions.any?
+ self.raise_ddl_not_allowed_error("Modifying of '#{parsed.pg.ddl_functions}' with '#{parsed.sql}'")
+ end
+
+ tables = self.dml_tables(parsed)
+ schemas = self.dml_schemas(tables)
+
+ if (schemas - self.allowed_gitlab_schemas).any?
+ raise DMLAccessDeniedError, "Select/DML queries (SELECT/UPDATE/DELETE) do access '#{tables}' (#{schemas.to_a}) " \
+ "which is outside of list of allowed schemas: '#{self.allowed_gitlab_schemas}'."
+ end
+ end
+
+ def dml_mode?
+ self.allowed_gitlab_schemas&.any?
+ end
+
+ def ddl_mode?
+ !self.dml_mode?
+ end
+
+ def dml_tables(parsed)
+ parsed.pg.select_tables + parsed.pg.dml_tables
+ end
+
+ def dml_schemas(tables)
+ extra_schemas = ::Gitlab::Database::GitlabSchema.table_schemas(tables)
+ extra_schemas.subtract(IGNORED_SCHEMAS)
+ extra_schemas
+ end
+
+ def raise_dml_not_allowed_error(message)
+ raise DMLNotAllowedError, "Select/DML queries (SELECT/UPDATE/DELETE) are disallowed in the DDL (structure) mode. #{message}"
+ end
+
+ def raise_ddl_not_allowed_error(message)
+ raise DDLNotAllowedError, "DDL queries (structure) are disallowed in the Select/DML (SELECT/UPDATE/DELETE) mode. #{message}"
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/database/transaction/context.rb b/lib/gitlab/database/transaction/context.rb
index a902537f02e..6defe9ae443 100644
--- a/lib/gitlab/database/transaction/context.rb
+++ b/lib/gitlab/database/transaction/context.rb
@@ -6,8 +6,10 @@ module Gitlab
class Context
attr_reader :context
- LOG_SAVEPOINTS_THRESHOLD = 1 # 1 `SAVEPOINT` created in a transaction
- LOG_DURATION_S_THRESHOLD = 120 # transaction that is running for 2 minutes or longer
+ LOG_SAVEPOINTS_THRESHOLD = 1 # 1 `SAVEPOINT` created in a transaction
+ LOG_DURATION_S_THRESHOLD = 120 # transaction that is running for 2 minutes or longer
+ LOG_EXTERNAL_HTTP_COUNT_THRESHOLD = 50 # 50 external HTTP requests executed within transaction
+ LOG_EXTERNAL_HTTP_DURATION_S_THRESHOLD = 1 # 1 second spent in HTTP requests in total within transaction
LOG_THROTTLE_DURATION = 1
def initialize
@@ -43,6 +45,11 @@ module Gitlab
(@context[:backtraces] ||= []).push(cleaned_backtrace)
end
+ def initialize_external_http_tracking
+ @context[:external_http_count_start] = external_http_requests_count_total
+ @context[:external_http_duration_start] = external_http_requests_duration_total
+ end
+
def duration
return unless @context[:start_time].present?
@@ -57,10 +64,16 @@ module Gitlab
duration.to_i >= LOG_DURATION_S_THRESHOLD
end
+ def external_http_requests_threshold_exceeded?
+ external_http_requests_count >= LOG_EXTERNAL_HTTP_COUNT_THRESHOLD ||
+ external_http_requests_duration >= LOG_EXTERNAL_HTTP_DURATION_S_THRESHOLD
+ end
+
def should_log?
return false if logged_already?
- savepoints_threshold_exceeded? || duration_threshold_exceeded?
+ savepoints_threshold_exceeded? || duration_threshold_exceeded? ||
+ external_http_requests_threshold_exceeded?
end
def commit
@@ -75,6 +88,14 @@ module Gitlab
@context[:backtraces].to_a
end
+ def external_http_requests_count
+ @requests_count ||= external_http_requests_count_total - @context[:external_http_count_start].to_i
+ end
+
+ def external_http_requests_duration
+ @requests_duration ||= external_http_requests_duration_total - @context[:external_http_duration_start].to_f
+ end
+
private
def queries
@@ -108,6 +129,8 @@ module Gitlab
savepoints_count: @context[:savepoints].to_i,
rollbacks_count: @context[:rollbacks].to_i,
releases_count: @context[:releases].to_i,
+ external_http_requests_count: external_http_requests_count,
+ external_http_requests_duration: external_http_requests_duration,
sql: queries,
savepoint_backtraces: backtraces
}
@@ -118,6 +141,14 @@ module Gitlab
def application_info(attributes)
Gitlab::AppJsonLogger.info(attributes)
end
+
+ def external_http_requests_count_total
+ ::Gitlab::Metrics::Subscribers::ExternalHttp.request_count.to_i
+ end
+
+ def external_http_requests_duration_total
+ ::Gitlab::Metrics::Subscribers::ExternalHttp.duration.to_f
+ end
end
end
end
diff --git a/lib/gitlab/database/transaction/observer.rb b/lib/gitlab/database/transaction/observer.rb
index ad6886a3d52..87e76257c24 100644
--- a/lib/gitlab/database/transaction/observer.rb
+++ b/lib/gitlab/database/transaction/observer.rb
@@ -21,6 +21,7 @@ module Gitlab
context.set_start_time
context.set_depth(0)
context.track_sql(event.payload[:sql])
+ context.initialize_external_http_tracking
elsif cmd.start_with?('SAVEPOINT', 'EXCEPTION')
context.set_depth(manager.open_transactions)
context.increment_savepoints
diff --git a/lib/gitlab/database/type/color.rb b/lib/gitlab/database/type/color.rb
new file mode 100644
index 00000000000..32ea33a42f3
--- /dev/null
+++ b/lib/gitlab/database/type/color.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Database
+ module Type
+ class Color < ActiveModel::Type::Value
+ def serialize(value)
+ value.to_s if value
+ end
+
+ def serializable?(value)
+ value.nil? || value.is_a?(::String) || value.is_a?(::Gitlab::Color)
+ end
+
+ def cast_value(value)
+ ::Gitlab::Color.new(value.to_s)
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/diff/custom_diff.rb b/lib/gitlab/diff/custom_diff.rb
index 3928ece9281..af1fd8fb03e 100644
--- a/lib/gitlab/diff/custom_diff.rb
+++ b/lib/gitlab/diff/custom_diff.rb
@@ -10,16 +10,16 @@ module Gitlab
transformed_for_diff(new_blob, old_blob)
Gitlab::AppLogger.info({ message: 'IPYNB_DIFF_GENERATED' })
end
- rescue IpynbDiff::InvalidNotebookError => e
+ rescue IpynbDiff::InvalidNotebookError, IpynbDiff::InvalidTokenError => e
Gitlab::ErrorTracking.log_exception(e)
nil
end
def transformed_diff(before, after)
transformed_diff = IpynbDiff.diff(before, after,
- diff_opts: { context: 5, include_diff_info: true },
- transform_options: { cell_decorator: :percent },
- raise_if_invalid_notebook: true)
+ raise_if_invalid_nb: true,
+ diffy_opts: { include_diff_info: true }).to_s(:text)
+
strip_diff_frontmatter(transformed_diff)
end
@@ -29,9 +29,7 @@ module Gitlab
def transformed_blob_data(blob)
if transformed_for_diff?(blob)
- IpynbDiff.transform(blob.data,
- raise_errors: true,
- options: { include_metadata: false, cell_decorator: :percent })
+ IpynbDiff.transform(blob.data, raise_errors: true, include_frontmatter: false)
end
end
diff --git a/lib/gitlab/diff/file.rb b/lib/gitlab/diff/file.rb
index d9860d9fb86..89822af2455 100644
--- a/lib/gitlab/diff/file.rb
+++ b/lib/gitlab/diff/file.rb
@@ -44,11 +44,15 @@ module Gitlab
new_blob_lazy
old_blob_lazy
- diff.diff = Gitlab::Diff::CustomDiff.preprocess_before_diff(diff.new_path, old_blob_lazy, new_blob_lazy) || diff.diff if use_custom_diff?
+ diff.diff = Gitlab::Diff::CustomDiff.preprocess_before_diff(diff.new_path, old_blob_lazy, new_blob_lazy) || diff.diff unless use_renderable_diff?
end
- def use_custom_diff?
- strong_memoize(:_custom_diff_enabled) { Feature.enabled?(:jupyter_clean_diffs, repository.project, default_enabled: true) }
+ def use_renderable_diff?
+ strong_memoize(:_renderable_diff_enabled) { Feature.enabled?(:rendered_diffs_viewer, repository.project, default_enabled: :yaml) }
+ end
+
+ def has_renderable?
+ rendered&.has_renderable?
end
def position(position_marker, position_type: :text)
@@ -292,13 +296,13 @@ module Gitlab
# rubocop: disable CodeReuse/ActiveRecord
def size
- valid_blobs.map(&:size).sum
+ valid_blobs.sum(&:size)
end
# rubocop: enable CodeReuse/ActiveRecord
# rubocop: disable CodeReuse/ActiveRecord
def raw_size
- valid_blobs.map(&:raw_size).sum
+ valid_blobs.sum(&:raw_size)
end
# rubocop: enable CodeReuse/ActiveRecord
@@ -370,10 +374,16 @@ module Gitlab
lines.none? { |line| line.type.to_s == 'match' }
end
+ def rendered
+ return unless use_renderable_diff? && ipynb?
+
+ strong_memoize(:rendered) { Rendered::Notebook::DiffFile.new(self) }
+ end
+
private
def diffable_by_attribute?
- repository.attributes(file_path).fetch('diff') { true }
+ repository.attributes(file_path).fetch('diff', true)
end
# NOTE: Files with unsupported encodings (e.g. UTF-16) are treated as binary by git, but they are recognized as text files during encoding detection. These files have `Binary files a/filename and b/filename differ' as their raw diff content which cannot be used. We need to handle this special case and avoid displaying incorrect diff.
@@ -399,6 +409,10 @@ module Gitlab
new_file? || deleted_file? || content_changed?
end
+ def ipynb?
+ modified_file? && file_path.ends_with?('.ipynb')
+ end
+
# We can't use Object#try because Blob doesn't inherit from Object, but
# from BasicObject (via SimpleDelegator).
def try_blobs(meth)
diff --git a/lib/gitlab/diff/file_collection/base.rb b/lib/gitlab/diff/file_collection/base.rb
index f73e060be7f..7fa1bd6b5ec 100644
--- a/lib/gitlab/diff/file_collection/base.rb
+++ b/lib/gitlab/diff/file_collection/base.rb
@@ -11,7 +11,7 @@ module Gitlab
delegate :count, :size, :real_size, to: :raw_diff_files
def self.default_options
- ::Commit.max_diff_options.merge(ignore_whitespace_change: false, expanded: false, include_stats: true)
+ ::Commit.max_diff_options.merge(ignore_whitespace_change: false, expanded: false, include_stats: true, use_extra_viewer_as_main: false)
end
def initialize(diffable, project:, diff_options: nil, diff_refs: nil, fallback_diff_refs: nil)
@@ -25,6 +25,7 @@ module Gitlab
@diff_refs = diff_refs
@fallback_diff_refs = fallback_diff_refs
@repository = project.repository
+ @use_extra_viewer_as_main = diff_options.delete(:use_extra_viewer_as_main)
end
def diffs
@@ -120,11 +121,17 @@ module Gitlab
stats = diff_stats_collection&.find_by_path(diff.new_path)
- Gitlab::Diff::File.new(diff,
+ diff_file = Gitlab::Diff::File.new(diff,
repository: project.repository,
diff_refs: diff_refs,
fallback_diff_refs: fallback_diff_refs,
stats: stats)
+
+ if @use_extra_viewer_as_main && diff_file.has_renderable?
+ diff_file.rendered
+ else
+ diff_file
+ end
end
def sort_diffs(diffs)
diff --git a/lib/gitlab/diff/file_collection/merge_request_diff_base.rb b/lib/gitlab/diff/file_collection/merge_request_diff_base.rb
index b459e3f6619..c6ab56e783a 100644
--- a/lib/gitlab/diff/file_collection/merge_request_diff_base.rb
+++ b/lib/gitlab/diff/file_collection/merge_request_diff_base.rb
@@ -12,10 +12,11 @@ module Gitlab
@merge_request_diff = merge_request_diff
super(merge_request_diff,
- project: merge_request_diff.project,
- diff_options: diff_options,
- diff_refs: merge_request_diff.diff_refs,
- fallback_diff_refs: merge_request_diff.fallback_diff_refs)
+ project: merge_request_diff.project,
+ diff_options: diff_options,
+ diff_refs: merge_request_diff.diff_refs,
+ fallback_diff_refs: merge_request_diff.fallback_diff_refs
+ )
end
def diff_files(sorted: false)
diff --git a/lib/gitlab/diff/line.rb b/lib/gitlab/diff/line.rb
index 6cf414e29cc..c2b834c71b5 100644
--- a/lib/gitlab/diff/line.rb
+++ b/lib/gitlab/diff/line.rb
@@ -8,9 +8,9 @@ module Gitlab
#
SERIALIZE_KEYS = %i(line_code rich_text text type index old_pos new_pos).freeze
- attr_reader :line_code, :marker_ranges
- attr_writer :text, :rich_text
- attr_accessor :index, :type, :old_pos, :new_pos
+ attr_reader :marker_ranges
+ attr_writer :text, :rich_text, :discussable
+ attr_accessor :index, :type, :old_pos, :new_pos, :line_code
def initialize(text, type, index, old_pos, new_pos, parent_file: nil, line_code: nil, rich_text: nil)
@text = text
@@ -26,6 +26,7 @@ module Gitlab
@line_code = line_code || calculate_line_code
@marker_ranges = []
+ @discussable = true
end
def self.init_from_hash(hash)
@@ -96,7 +97,7 @@ module Gitlab
end
def discussable?
- !meta?
+ @discussable && !meta?
end
def suggestible?
diff --git a/lib/gitlab/diff/rendered/notebook/diff_file.rb b/lib/gitlab/diff/rendered/notebook/diff_file.rb
new file mode 100644
index 00000000000..e700e730f20
--- /dev/null
+++ b/lib/gitlab/diff/rendered/notebook/diff_file.rb
@@ -0,0 +1,126 @@
+# frozen_string_literal: true
+module Gitlab
+ module Diff
+ module Rendered
+ module Notebook
+ include Gitlab::Utils::StrongMemoize
+
+ class DiffFile < Gitlab::Diff::File
+ attr_reader :source_diff
+
+ delegate :repository, :diff_refs, :fallback_diff_refs, :unfolded, :unique_identifier,
+ to: :source_diff
+
+ def initialize(diff_file)
+ @source_diff = diff_file
+ end
+
+ def old_blob
+ return unless notebook_diff
+
+ strong_memoize(:old_blob) { ::Blobs::Notebook.decorate(source_diff.old_blob, notebook_diff.from.as_text) }
+ end
+
+ def new_blob
+ return unless notebook_diff
+
+ strong_memoize(:new_blob) { ::Blobs::Notebook.decorate(source_diff.new_blob, notebook_diff.to.as_text) }
+ end
+
+ def diff
+ strong_memoize(:diff) { transformed_diff }
+ end
+
+ def has_renderable?
+ !notebook_diff.nil? && diff.diff.present?
+ end
+
+ def rendered
+ self
+ end
+
+ def highlighted_diff_lines
+ @highlighted_diff_lines ||= begin
+ removal_line_maps, addition_line_maps = compute_end_start_map
+ Gitlab::Diff::Highlight.new(self, repository: self.repository).highlight.map do |line|
+ mutate_line(line, addition_line_maps, removal_line_maps)
+ end
+ end
+ end
+
+ private
+
+ def notebook_diff
+ strong_memoize(:notebook_diff) do
+ Gitlab::AppLogger.info({ message: 'IPYNB_DIFF_GENERATED' })
+
+ IpynbDiff.diff(source_diff.old_blob&.data, source_diff.new_blob&.data,
+ raise_if_invalid_nb: true,
+ diffy_opts: { include_diff_info: true })
+ rescue IpynbDiff::InvalidNotebookError, IpynbDiff::InvalidTokenError => e
+ Gitlab::ErrorTracking.log_exception(e)
+ nil
+ end
+ end
+
+ def transformed_diff
+ return unless notebook_diff
+
+ diff = source_diff.diff.clone
+ diff.diff = strip_diff_frontmatter(notebook_diff.to_s(:text))
+ diff
+ end
+
+ def strip_diff_frontmatter(diff_content)
+ diff_content.scan(/.*\n/)[2..]&.join('') if diff_content.present?
+ end
+
+ def transformed_line_to_source(transformed_line, transformed_blocks)
+ transformed_blocks.empty? ? 0 : ( transformed_blocks[transformed_line - 1][:source_line] || -1 ) + 1
+ end
+
+ def mutate_line(line, addition_line_maps, removal_line_maps)
+ line.new_pos = transformed_line_to_source(line.new_pos, notebook_diff.to.blocks)
+ line.old_pos = transformed_line_to_source(line.old_pos, notebook_diff.from.blocks)
+
+ line.old_pos = addition_line_maps[line.new_pos] if line.old_pos == 0 && line.new_pos != 0
+ line.new_pos = removal_line_maps[line.old_pos] if line.new_pos == 0 && line.old_pos != 0
+
+ # Lines that do not appear on the original diff should not be commentable
+
+ unless addition_line_maps[line.new_pos] || removal_line_maps[line.old_pos]
+ line.discussable = false
+ end
+
+ line.line_code = line_code(line)
+ line
+ end
+
+ def compute_end_start_map
+ # line_codes are used for assigning notes to diffs, and these depend on the line on the new version and the
+ # line that would have been that one in the previous version. However, since we do a transformation on the
+ # file, that map gets lost. To overcome this, we look at the original source lines and build two maps:
+ # - For additions, we look at the latest line change for that line and pick the old line for that id
+ # - For removals, we look at the first line in the old version, and pick the first line on the new version
+ #
+ #
+ # The caveat here is that we can't have notes on lines that are not a translation of a line in the source
+ # diff
+ #
+ # (gitlab/diff/file.rb:75)
+
+ removals = {}
+ additions = {}
+
+ source_diff.highlighted_diff_lines.each do |line|
+ removals[line.old_pos] = line.new_pos
+ additions[line.new_pos] = line.old_pos
+ end
+
+ [removals, additions]
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/email/attachment_uploader.rb b/lib/gitlab/email/attachment_uploader.rb
index e213adbfcfd..b67ca8d8a7d 100644
--- a/lib/gitlab/email/attachment_uploader.rb
+++ b/lib/gitlab/email/attachment_uploader.rb
@@ -15,7 +15,9 @@ module Gitlab
filter_signature_attachments(message).each do |attachment|
tmp = Tempfile.new("gitlab-email-attachment")
begin
- File.open(tmp.path, "w+b") { |f| f.write attachment.body.decoded }
+ content = attachment.body.decoded
+ File.open(tmp.path, "w+b") { |f| f.write content }
+ sanitize_exif_if_needed(content, tmp.path)
file = {
tempfile: tmp,
@@ -55,6 +57,12 @@ module Gitlab
def normalize_mime(content_type)
MIME::Type.simplified(content_type, remove_x_prefix: true)
end
+
+ # https://gitlab.com/gitlab-org/gitlab/-/issues/239343
+ def sanitize_exif_if_needed(content, path)
+ exif_sanitizer = Gitlab::Sanitizers::Exif.new
+ exif_sanitizer.clean_existing_path(path, content: content, skip_unallowed_types: true)
+ end
end
end
end
diff --git a/lib/gitlab/email/handler/service_desk_handler.rb b/lib/gitlab/email/handler/service_desk_handler.rb
index 71b1d4ed8f9..bb57494c729 100644
--- a/lib/gitlab/email/handler/service_desk_handler.rb
+++ b/lib/gitlab/email/handler/service_desk_handler.rb
@@ -34,7 +34,7 @@ module Gitlab
create_issue_or_note
- if from_address
+ if issue_creator_address
add_email_participant
send_thank_you_email unless reply_email?
end
@@ -98,7 +98,7 @@ module Gitlab
title: mail.subject,
description: message_including_template,
confidential: true,
- external_author: from_address
+ external_author: external_author
},
spam_params: nil
).execute
@@ -176,8 +176,22 @@ module Gitlab
).execute
end
+ def issue_creator_address
+ reply_to_address || from_address
+ end
+
def from_address
- (mail.reply_to || []).first || mail.from.first || mail.sender
+ mail.from.first || mail.sender
+ end
+
+ def reply_to_address
+ (mail.reply_to || []).first
+ end
+
+ def external_author
+ return issue_creator_address unless reply_to_address && from_address
+
+ _("%{from_address} (reply to: %{reply_to_address})") % { from_address: from_address, reply_to_address: reply_to_address }
end
def can_handle_legacy_format?
@@ -191,7 +205,7 @@ module Gitlab
def add_email_participant
return if reply_email? && !Feature.enabled?(:issue_email_participants, @issue.project)
- @issue.issue_email_participants.create(email: from_address)
+ @issue.issue_email_participants.create(email: issue_creator_address)
end
end
end
diff --git a/lib/gitlab/email/html_parser.rb b/lib/gitlab/email/html_parser.rb
index 77f299bcade..27ba5d2a314 100644
--- a/lib/gitlab/email/html_parser.rb
+++ b/lib/gitlab/email/html_parser.rb
@@ -8,6 +8,7 @@ module Gitlab
end
attr_reader :raw_body
+
def initialize(raw_body)
@raw_body = raw_body
end
diff --git a/lib/gitlab/email/receiver.rb b/lib/gitlab/email/receiver.rb
index 5b2bbfbe66b..58e7b2f1b44 100644
--- a/lib/gitlab/email/receiver.rb
+++ b/lib/gitlab/email/receiver.rb
@@ -8,6 +8,8 @@ module Gitlab
class Receiver
include Gitlab::Utils::StrongMemoize
+ RECEIVED_HEADER_REGEX = /for\s+\<(.+)\>/.freeze
+
def initialize(raw)
@raw = raw
end
@@ -37,6 +39,8 @@ module Gitlab
delivered_to: delivered_to.map(&:value),
envelope_to: envelope_to.map(&:value),
x_envelope_to: x_envelope_to.map(&:value),
+ # reduced down to what looks like an email in the received headers
+ received_recipients: recipients_from_received_headers,
meta: {
client_id: "email/#{mail.from.first}",
project: handler&.project&.full_path
@@ -82,7 +86,8 @@ module Gitlab
find_key_from_references ||
find_key_from_delivered_to_header ||
find_key_from_envelope_to_header ||
- find_key_from_x_envelope_to_header
+ find_key_from_x_envelope_to_header ||
+ find_first_key_from_received_headers
end
def ensure_references_array(references)
@@ -117,6 +122,10 @@ module Gitlab
Array(mail[:x_envelope_to])
end
+ def received
+ Array(mail[:received])
+ end
+
def find_key_from_delivered_to_header
delivered_to.find do |header|
key = email_class.key_from_address(header.value)
@@ -138,6 +147,21 @@ module Gitlab
end
end
+ def find_first_key_from_received_headers
+ return unless ::Feature.enabled?(:use_received_header_for_incoming_emails, default_enabled: :yaml)
+
+ recipients_from_received_headers.find do |email|
+ key = email_class.key_from_address(email)
+ break key if key
+ end
+ end
+
+ def recipients_from_received_headers
+ strong_memoize :emails_from_received_headers do
+ received.map { |header| header.value[RECEIVED_HEADER_REGEX, 1] }.compact
+ end
+ end
+
def ignore_auto_reply!
if auto_submitted? || auto_replied?
raise AutoGeneratedEmailError
diff --git a/lib/gitlab/error_tracking.rb b/lib/gitlab/error_tracking.rb
index 6a637306225..259b430a73c 100644
--- a/lib/gitlab/error_tracking.rb
+++ b/lib/gitlab/error_tracking.rb
@@ -23,7 +23,12 @@ module Gitlab
].freeze
class << self
- def configure
+ def configure(&block)
+ configure_raven(&block)
+ configure_sentry(&block)
+ end
+
+ def configure_raven
Raven.configure do |config|
config.dsn = sentry_dsn
config.release = Gitlab.revision
@@ -34,7 +39,20 @@ module Gitlab
# Sanitize authentication headers
config.sanitize_http_headers = %w[Authorization Private-Token]
- config.before_send = method(:before_send)
+ config.before_send = method(:before_send_raven)
+
+ yield config if block_given?
+ end
+ end
+
+ def configure_sentry
+ Sentry.init do |config|
+ config.dsn = new_sentry_dsn
+ config.release = Gitlab.revision
+ config.environment = new_sentry_environment
+ config.before_send = method(:before_send_sentry)
+ config.background_worker_threads = 0
+ config.send_default_pii = true
yield config if block_given?
end
@@ -96,6 +114,18 @@ module Gitlab
private
+ def before_send_raven(event, hint)
+ return unless Feature.enabled?(:enable_old_sentry_integration, default_enabled: :yaml)
+
+ before_send(event, hint)
+ end
+
+ def before_send_sentry(event, hint)
+ return unless Feature.enabled?(:enable_new_sentry_integration, default_enabled: :yaml)
+
+ before_send(event, hint)
+ end
+
def before_send(event, hint)
inject_context_for_exception(event, hint[:exception])
custom_fingerprinting(event, hint[:exception])
@@ -112,6 +142,13 @@ module Gitlab
Raven.capture_exception(exception, **context_payload)
end
+ # There is a possibility that this method is called before Sentry is
+ # configured. Since Sentry 4.0, some methods of Sentry are forwarded to
+ # to `nil`, hence we have to check the client as well.
+ if sentry && ::Sentry.get_current_client && ::Sentry.configuration.dsn
+ ::Sentry.capture_exception(exception, **context_payload)
+ end
+
if logging
formatter = Gitlab::ErrorTracking::LogFormatter.new
log_hash = formatter.generate_log(exception, context_payload)
@@ -121,12 +158,30 @@ module Gitlab
end
def sentry_dsn
- return unless Rails.env.production? || Rails.env.development?
+ return unless sentry_configurable?
return unless Gitlab.config.sentry.enabled
Gitlab.config.sentry.dsn
end
+ def new_sentry_dsn
+ return unless sentry_configurable?
+ return unless Gitlab::CurrentSettings.respond_to?(:sentry_enabled?)
+ return unless Gitlab::CurrentSettings.sentry_enabled?
+
+ Gitlab::CurrentSettings.sentry_dsn
+ end
+
+ def new_sentry_environment
+ return unless Gitlab::CurrentSettings.respond_to?(:sentry_environment)
+
+ Gitlab::CurrentSettings.sentry_environment
+ end
+
+ def sentry_configurable?
+ Rails.env.production? || Rails.env.development?
+ end
+
def should_raise_for_dev?
Rails.env.development? || Rails.env.test?
end
diff --git a/lib/gitlab/error_tracking/processor/grpc_error_processor.rb b/lib/gitlab/error_tracking/processor/grpc_error_processor.rb
index e835deeea2c..045a18f4110 100644
--- a/lib/gitlab/error_tracking/processor/grpc_error_processor.rb
+++ b/lib/gitlab/error_tracking/processor/grpc_error_processor.rb
@@ -18,7 +18,7 @@ module Gitlab
# only the first one since that's what is used for grouping.
def process_first_exception_value(event)
# Better in new version, will be event.exception.values
- exceptions = event.instance_variable_get(:@interfaces)[:exception]&.values
+ exceptions = extract_exceptions_from(event)
return unless exceptions.is_a?(Array)
@@ -37,7 +37,13 @@ module Gitlab
# instance variable
if message.present?
exceptions.each do |exception|
- exception.value = message if valid_exception?(exception)
+ next unless valid_exception?(exception)
+
+ if exception.respond_to?(:value=)
+ exception.value = message
+ else
+ exception.instance_variable_set(:@value, message)
+ end
end
end
@@ -55,6 +61,14 @@ module Gitlab
private
+ def extract_exceptions_from(event)
+ if event.is_a?(Raven::Event)
+ event.instance_variable_get(:@interfaces)[:exception]&.values
+ else
+ event.exception&.instance_variable_get(:@values)
+ end
+ end
+
def custom_grpc_fingerprint?(fingerprint)
fingerprint.is_a?(Array) && fingerprint.length == 2 && fingerprint[0].start_with?('GRPC::')
end
@@ -71,7 +85,7 @@ module Gitlab
def valid_exception?(exception)
case exception
- when Raven::SingleExceptionInterface
+ when Raven::SingleExceptionInterface, Sentry::SingleExceptionInterface
exception&.value
else
false
diff --git a/lib/gitlab/etag_caching/middleware.rb b/lib/gitlab/etag_caching/middleware.rb
index d5bf0cffb1e..a1918ee6ad5 100644
--- a/lib/gitlab/etag_caching/middleware.rb
+++ b/lib/gitlab/etag_caching/middleware.rb
@@ -67,7 +67,10 @@ module Gitlab
add_instrument_for_cache_hit(status_code, route, request)
- Gitlab::ApplicationContext.push(feature_category: route.feature_category)
+ Gitlab::ApplicationContext.push(
+ feature_category: route.feature_category,
+ caller_id: route.caller_id
+ )
new_headers = {
'ETag' => etag,
diff --git a/lib/gitlab/etag_caching/router.rb b/lib/gitlab/etag_caching/router.rb
index 742b72ecde9..684afc6762a 100644
--- a/lib/gitlab/etag_caching/router.rb
+++ b/lib/gitlab/etag_caching/router.rb
@@ -3,22 +3,33 @@
module Gitlab
module EtagCaching
module Router
- Route = Struct.new(:regexp, :name, :feature_category, :router) do
+ Route = Struct.new(:router, :regexp, :name, :feature_category, :caller_id) do
delegate :match, to: :regexp
delegate :cache_key, to: :router
end
module Helpers
def build_route(attrs)
- EtagCaching::Router::Route.new(*attrs, self)
+ EtagCaching::Router::Route.new(self, *attrs)
+ end
+
+ def build_rails_route(attrs)
+ regexp, name, controller, action_name = *attrs
+ EtagCaching::Router::Route.new(
+ self,
+ regexp,
+ name,
+ controller.feature_category_for_action(action_name).to_s,
+ controller.endpoint_id_for_action(action_name).to_s
+ )
end
end
- # Performing RESTful routing match before GraphQL would be more expensive
+ # Performing Rails routing match before GraphQL would be more expensive
# for the GraphQL requests because we need to traverse all of the RESTful
# route definitions before falling back to GraphQL.
def self.match(request)
- Router::Graphql.match(request) || Router::Restful.match(request)
+ Router::Graphql.match(request) || Router::Rails.match(request)
end
end
end
diff --git a/lib/gitlab/etag_caching/router/rails.rb b/lib/gitlab/etag_caching/router/rails.rb
new file mode 100644
index 00000000000..d80c003fe53
--- /dev/null
+++ b/lib/gitlab/etag_caching/router/rails.rb
@@ -0,0 +1,126 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module EtagCaching
+ module Router
+ class Rails
+ extend EtagCaching::Router::Helpers
+
+ # We enable an ETag for every request matching the regex.
+ # To match a regex the path needs to match the following:
+ # - Don't contain a reserved word (expect for the words used in the
+ # regex itself)
+ # - Ending in `noteable/issue/<id>/notes` for the `issue_notes` route
+ # - Ending in `issues/id`/realtime_changes` for the `issue_title` route
+ USED_IN_ROUTES = %w[noteable issue notes issues realtime_changes
+ commit pipelines merge_requests builds
+ new environments].freeze
+ RESERVED_WORDS = Gitlab::PathRegex::ILLEGAL_PROJECT_PATH_WORDS - USED_IN_ROUTES
+ RESERVED_WORDS_REGEX = Regexp.union(*RESERVED_WORDS.map(&Regexp.method(:escape)))
+ RESERVED_WORDS_PREFIX = %Q(^(?!.*\/(#{RESERVED_WORDS_REGEX})\/).*)
+
+ ROUTES = [
+ [
+ %r(#{RESERVED_WORDS_PREFIX}/noteable/issue/\d+/notes\z),
+ 'issue_notes',
+ ::Projects::NotesController,
+ :index
+ ],
+ [
+ %r(#{RESERVED_WORDS_PREFIX}/noteable/merge_request/\d+/notes\z),
+ 'merge_request_notes',
+ ::Projects::NotesController,
+ :index
+ ],
+ [
+ %r(#{RESERVED_WORDS_PREFIX}/issues/\d+/realtime_changes\z),
+ 'issue_title',
+ ::Projects::IssuesController,
+ :realtime_changes
+ ],
+ [
+ %r(#{RESERVED_WORDS_PREFIX}/commit/\S+/pipelines\.json\z),
+ 'commit_pipelines',
+ ::Projects::CommitController,
+ :pipelines
+ ],
+ [
+ %r(#{RESERVED_WORDS_PREFIX}/merge_requests/new\.json\z),
+ 'new_merge_request_pipelines',
+ ::Projects::MergeRequests::CreationsController,
+ :new
+ ],
+ [
+ %r(#{RESERVED_WORDS_PREFIX}/merge_requests/\d+/pipelines\.json\z),
+ 'merge_request_pipelines',
+ ::Projects::MergeRequestsController,
+ :pipelines
+ ],
+ [
+ %r(#{RESERVED_WORDS_PREFIX}/pipelines\.json\z),
+ 'project_pipelines',
+ ::Projects::PipelinesController,
+ :index
+ ],
+ [
+ %r(#{RESERVED_WORDS_PREFIX}/pipelines/\d+\.json\z),
+ 'project_pipeline',
+ ::Projects::PipelinesController,
+ :show
+ ],
+ [
+ %r(#{RESERVED_WORDS_PREFIX}/builds/\d+\.json\z),
+ 'project_build',
+ ::Projects::BuildsController,
+ :show
+ ],
+ [
+ %r(#{RESERVED_WORDS_PREFIX}/clusters/\d+/environments\z),
+ 'cluster_environments',
+ ::Groups::ClustersController,
+ :environments
+ ],
+ [
+ %r(#{RESERVED_WORDS_PREFIX}/-/environments\.json\z),
+ 'environments',
+ ::Projects::EnvironmentsController,
+ :index
+ ],
+ [
+ %r(#{RESERVED_WORDS_PREFIX}/import/github/realtime_changes\.json\z),
+ 'realtime_changes_import_github',
+ ::Import::GithubController,
+ :realtime_changes
+ ],
+ [
+ %r(#{RESERVED_WORDS_PREFIX}/import/gitea/realtime_changes\.json\z),
+ 'realtime_changes_import_gitea',
+ ::Import::GiteaController,
+ :realtime_changes
+ ],
+ [
+ %r(#{RESERVED_WORDS_PREFIX}/merge_requests/\d+/cached_widget\.json\z),
+ 'merge_request_widget',
+ ::Projects::MergeRequests::ContentController,
+ :cached_widget
+ ]
+ ].map(&method(:build_rails_route)).freeze
+
+ # Overridden in EE to add more routes
+ def self.all_routes
+ ROUTES
+ end
+
+ def self.match(request)
+ all_routes.find { |route| route.match(request.path_info) }
+ end
+
+ def self.cache_key(request)
+ request.path
+ end
+ end
+ end
+ end
+end
+
+Gitlab::EtagCaching::Router::Rails.prepend_mod_with('Gitlab::EtagCaching::Router::Rails')
diff --git a/lib/gitlab/etag_caching/router/restful.rb b/lib/gitlab/etag_caching/router/restful.rb
deleted file mode 100644
index 176676bd6ba..00000000000
--- a/lib/gitlab/etag_caching/router/restful.rb
+++ /dev/null
@@ -1,112 +0,0 @@
-# frozen_string_literal: true
-
-module Gitlab
- module EtagCaching
- module Router
- class Restful
- extend EtagCaching::Router::Helpers
-
- # We enable an ETag for every request matching the regex.
- # To match a regex the path needs to match the following:
- # - Don't contain a reserved word (expect for the words used in the
- # regex itself)
- # - Ending in `noteable/issue/<id>/notes` for the `issue_notes` route
- # - Ending in `issues/id`/realtime_changes` for the `issue_title` route
- USED_IN_ROUTES = %w[noteable issue notes issues realtime_changes
- commit pipelines merge_requests builds
- new environments].freeze
- RESERVED_WORDS = Gitlab::PathRegex::ILLEGAL_PROJECT_PATH_WORDS - USED_IN_ROUTES
- RESERVED_WORDS_REGEX = Regexp.union(*RESERVED_WORDS.map(&Regexp.method(:escape)))
- RESERVED_WORDS_PREFIX = %Q(^(?!.*\/(#{RESERVED_WORDS_REGEX})\/).*)
-
- ROUTES = [
- [
- %r(#{RESERVED_WORDS_PREFIX}/noteable/issue/\d+/notes\z),
- 'issue_notes',
- 'team_planning'
- ],
- [
- %r(#{RESERVED_WORDS_PREFIX}/noteable/merge_request/\d+/notes\z),
- 'merge_request_notes',
- 'code_review'
- ],
- [
- %r(#{RESERVED_WORDS_PREFIX}/issues/\d+/realtime_changes\z),
- 'issue_title',
- 'team_planning'
- ],
- [
- %r(#{RESERVED_WORDS_PREFIX}/commit/\S+/pipelines\.json\z),
- 'commit_pipelines',
- 'continuous_integration'
- ],
- [
- %r(#{RESERVED_WORDS_PREFIX}/merge_requests/new\.json\z),
- 'new_merge_request_pipelines',
- 'continuous_integration'
- ],
- [
- %r(#{RESERVED_WORDS_PREFIX}/merge_requests/\d+/pipelines\.json\z),
- 'merge_request_pipelines',
- 'continuous_integration'
- ],
- [
- %r(#{RESERVED_WORDS_PREFIX}/pipelines\.json\z),
- 'project_pipelines',
- 'continuous_integration'
- ],
- [
- %r(#{RESERVED_WORDS_PREFIX}/pipelines/\d+\.json\z),
- 'project_pipeline',
- 'continuous_integration'
- ],
- [
- %r(#{RESERVED_WORDS_PREFIX}/builds/\d+\.json\z),
- 'project_build',
- 'continuous_integration'
- ],
- [
- %r(#{RESERVED_WORDS_PREFIX}/clusters/\d+/environments\z),
- 'cluster_environments',
- 'continuous_delivery'
- ],
- [
- %r(#{RESERVED_WORDS_PREFIX}/-/environments\.json\z),
- 'environments',
- 'continuous_delivery'
- ],
- [
- %r(#{RESERVED_WORDS_PREFIX}/import/github/realtime_changes\.json\z),
- 'realtime_changes_import_github',
- 'importers'
- ],
- [
- %r(#{RESERVED_WORDS_PREFIX}/import/gitea/realtime_changes\.json\z),
- 'realtime_changes_import_gitea',
- 'importers'
- ],
- [
- %r(#{RESERVED_WORDS_PREFIX}/merge_requests/\d+/cached_widget\.json\z),
- 'merge_request_widget',
- 'code_review'
- ]
- ].map(&method(:build_route)).freeze
-
- # Overridden in EE to add more routes
- def self.all_routes
- ROUTES
- end
-
- def self.match(request)
- all_routes.find { |route| route.match(request.path_info) }
- end
-
- def self.cache_key(request)
- request.path
- end
- end
- end
- end
-end
-
-Gitlab::EtagCaching::Router::Restful.prepend_mod_with('Gitlab::EtagCaching::Router::Restful')
diff --git a/lib/gitlab/experiment/rollout/feature.rb b/lib/gitlab/experiment/rollout/feature.rb
index 5a14e3c272e..70c363877b1 100644
--- a/lib/gitlab/experiment/rollout/feature.rb
+++ b/lib/gitlab/experiment/rollout/feature.rb
@@ -12,10 +12,11 @@ module Gitlab
# - not have rolled out the feature flag at all (no percent of actors,
# no inclusions, etc.)
def enabled?
- return false if ::Feature::Definition.get(feature_flag_name).nil?
- return false unless Gitlab.dev_env_or_com?
+ return false unless feature_flag_defined?
+ return false unless Gitlab.com?
+ return false unless ::Feature.enabled?(:gitlab_experiment, type: :ops, default_enabled: :yaml)
- ::Feature.get(feature_flag_name).state != :off # rubocop:disable Gitlab/AvoidFeatureGet
+ feature_flag_instance.state != :off
end
# For assignment we first check to see if our feature flag is enabled
@@ -58,6 +59,14 @@ module Gitlab
private
+ def feature_flag_instance
+ ::Feature.get(feature_flag_name) # rubocop:disable Gitlab/AvoidFeatureGet
+ end
+
+ def feature_flag_defined?
+ ::Feature::Definition.get(feature_flag_name).present?
+ end
+
def feature_flag_name
experiment.name.tr('/', '_')
end
diff --git a/lib/gitlab/experimentation.rb b/lib/gitlab/experimentation.rb
index 7edda290204..8a5432025d8 100644
--- a/lib/gitlab/experimentation.rb
+++ b/lib/gitlab/experimentation.rb
@@ -10,9 +10,9 @@
# The experiment is controlled by a Feature Flag (https://docs.gitlab.com/ee/development/feature_flags/controls.html),
# which is named "#{experiment_key}_experiment_percentage" and *must* be set with a percentage and not be used for other purposes.
#
-# To enable the experiment for 10% of the users:
+# To enable the experiment for 10% of the time:
#
-# chatops: `/chatops run feature set experiment_key_experiment_percentage 10`
+# chatops: `/chatops run feature set experiment_key_experiment_percentage 10 --random`
# console: `Feature.enable_percentage_of_time(:experiment_key_experiment_percentage, 10)`
#
# To disable the experiment:
diff --git a/lib/gitlab/experimentation/controller_concern.rb b/lib/gitlab/experimentation/controller_concern.rb
index 303d952381f..a68e2db4dac 100644
--- a/lib/gitlab/experimentation/controller_concern.rb
+++ b/lib/gitlab/experimentation/controller_concern.rb
@@ -20,7 +20,7 @@ module Gitlab
end
def set_experimentation_subject_id_cookie
- if Gitlab.dev_env_or_com?
+ if Gitlab.com?
return if cookies[:experimentation_subject_id].present?
cookies.permanent.signed[:experimentation_subject_id] = {
diff --git a/lib/gitlab/experimentation/experiment.rb b/lib/gitlab/experimentation/experiment.rb
index 8ba95520638..b13f55e7969 100644
--- a/lib/gitlab/experimentation/experiment.rb
+++ b/lib/gitlab/experimentation/experiment.rb
@@ -18,7 +18,7 @@ module Gitlab
# Temporary change, we will change `experiment_percentage` in future to `Feature.enabled?
Feature.enabled?(feature_flag_name, type: :experiment, default_enabled: :yaml)
- ::Gitlab.dev_env_or_com? && experiment_percentage > 0
+ ::Gitlab.com? && experiment_percentage > 0
end
def enabled_for_index?(index)
diff --git a/lib/gitlab/fips.rb b/lib/gitlab/fips.rb
new file mode 100644
index 00000000000..1dd363ceb17
--- /dev/null
+++ b/lib/gitlab/fips.rb
@@ -0,0 +1,25 @@
+# rubocop: disable Naming/FileName
+# frozen_string_literal: true
+
+module Gitlab
+ class FIPS
+ # A simple utility class for FIPS-related helpers
+
+ class << self
+ # Returns whether we should be running in FIPS mode or not
+ #
+ # @return [Boolean]
+ def enabled?
+ # Attempt to auto-detect FIPS mode from OpenSSL
+ return true if OpenSSL.fips_mode
+
+ # Otherwise allow it to be set manually via the env vars
+ return true if ENV["FIPS_MODE"] == "true"
+
+ false
+ end
+ end
+ end
+end
+
+# rubocop: enable Naming/FileName
diff --git a/lib/gitlab/form_builders/gitlab_ui_form_builder.rb b/lib/gitlab/form_builders/gitlab_ui_form_builder.rb
index 3f9053d4e0c..e8e87a864cc 100644
--- a/lib/gitlab/form_builders/gitlab_ui_form_builder.rb
+++ b/lib/gitlab/form_builders/gitlab_ui_form_builder.rb
@@ -16,13 +16,15 @@ module Gitlab
:div,
class: 'gl-form-checkbox custom-control custom-checkbox'
) do
+ value = checkbox_options[:multiple] ? checked_value : nil
+
@template.check_box(
@object_name,
method,
format_options(checkbox_options, ['custom-control-input']),
checked_value,
unchecked_value
- ) + generic_label(method, label, label_options, help_text: help_text)
+ ) + generic_label(method, label, label_options, help_text: help_text, value: value)
end
end
diff --git a/lib/gitlab/front_matter.rb b/lib/gitlab/front_matter.rb
index 5c5c74ca1a0..093501e860b 100644
--- a/lib/gitlab/front_matter.rb
+++ b/lib/gitlab/front_matter.rb
@@ -11,12 +11,12 @@ module Gitlab
DELIM = Regexp.union(DELIM_LANG.keys)
PATTERN = %r{
- \A(?:[^\r\n]*coding:[^\r\n]*\R)? # optional encoding line
- \s*
+ \A(?<encoding>[^\r\n]*coding:[^\r\n]*\R)? # optional encoding line
+ (?<before>\s*)
^(?<delim>#{DELIM})[ \t]*(?<lang>\S*)\R # opening front matter marker (optional language specifier)
(?<front_matter>.*?) # front matter block content (not greedy)
^(\k<delim> | \.{3}) # closing front matter marker
- \s*
+ [^\S\r\n]*(\R|\z)
}mx.freeze
end
end
diff --git a/lib/gitlab/git/blame.rb b/lib/gitlab/git/blame.rb
index a5b1b7d914b..5669a65cbd9 100644
--- a/lib/gitlab/git/blame.rb
+++ b/lib/gitlab/git/blame.rb
@@ -63,6 +63,7 @@ module Gitlab
class BlameLine
attr_accessor :lineno, :oldlineno, :commit, :line
+
def initialize(lineno, oldlineno, commit, line)
@lineno = lineno
@oldlineno = oldlineno
diff --git a/lib/gitlab/git/repository.rb b/lib/gitlab/git/repository.rb
index c3ee5b97379..1492ea1ce76 100644
--- a/lib/gitlab/git/repository.rb
+++ b/lib/gitlab/git/repository.rb
@@ -99,9 +99,9 @@ module Gitlab
gitaly_repository_client.exists?
end
- def create_repository
+ def create_repository(default_branch = nil)
wrapped_gitaly_errors do
- gitaly_repository_client.create_repository
+ gitaly_repository_client.create_repository(default_branch)
rescue GRPC::AlreadyExists => e
raise RepositoryExists, e.message
end
diff --git a/lib/gitlab/git/wiki.rb b/lib/gitlab/git/wiki.rb
index 194f5da0a5c..4bab94968d7 100644
--- a/lib/gitlab/git/wiki.rb
+++ b/lib/gitlab/git/wiki.rb
@@ -93,9 +93,9 @@ module Gitlab
end
end
- def page(title:, version: nil, dir: nil)
+ def page(title:, version: nil, dir: nil, load_content: true)
wrapped_gitaly_errors do
- gitaly_find_page(title: title, version: version, dir: dir)
+ gitaly_find_page(title: title, version: version, dir: dir, load_content: load_content)
end
end
@@ -121,10 +121,10 @@ module Gitlab
gitaly_wiki_client.update_page(page_path, title, format, content, commit_details)
end
- def gitaly_find_page(title:, version: nil, dir: nil)
+ def gitaly_find_page(title:, version: nil, dir: nil, load_content: true)
return unless title.present?
- wiki_page, version = gitaly_wiki_client.find_page(title: title, version: version, dir: dir)
+ wiki_page, version = gitaly_wiki_client.find_page(title: title, version: version, dir: dir, load_content: load_content)
return unless wiki_page
Gitlab::Git::WikiPage.new(wiki_page, version)
diff --git a/lib/gitlab/git_access_snippet.rb b/lib/gitlab/git_access_snippet.rb
index 4d87b91764a..5ae17dbbb91 100644
--- a/lib/gitlab/git_access_snippet.rb
+++ b/lib/gitlab/git_access_snippet.rb
@@ -30,10 +30,7 @@ module Gitlab
def check(cmd, changes)
check_snippet_accessibility!
- super.tap do |_|
- # Ensure HEAD points to the default branch in case it is not master
- snippet.change_head_to_default_branch
- end
+ super
end
override :download_ability
diff --git a/lib/gitlab/gitaly_client.rb b/lib/gitlab/gitaly_client.rb
index a824f97e197..f376dbce177 100644
--- a/lib/gitlab/gitaly_client.rb
+++ b/lib/gitlab/gitaly_client.rb
@@ -390,7 +390,7 @@ module Gitlab
end
def self.long_timeout
- if Gitlab::Runtime.web_server?
+ if Gitlab::Runtime.puma?
default_timeout
else
6.hours
diff --git a/lib/gitlab/gitaly_client/commit_service.rb b/lib/gitlab/gitaly_client/commit_service.rb
index c2b4182f609..0e3f9c2598d 100644
--- a/lib/gitlab/gitaly_client/commit_service.rb
+++ b/lib/gitlab/gitaly_client/commit_service.rb
@@ -212,7 +212,7 @@ module Gitlab
)
response = GitalyClient.call(@repository.storage, :diff_service, :diff_stats, request, timeout: GitalyClient.medium_timeout)
- response.flat_map(&:stats)
+ response.flat_map { |rsp| rsp.stats.to_a }
end
def find_changed_paths(commits)
diff --git a/lib/gitlab/gitaly_client/operation_service.rb b/lib/gitlab/gitaly_client/operation_service.rb
index adbf07de1b9..4637bf2e3ff 100644
--- a/lib/gitlab/gitaly_client/operation_service.rb
+++ b/lib/gitlab/gitaly_client/operation_service.rb
@@ -119,10 +119,6 @@ module Gitlab
response = GitalyClient.call(@repository.storage, :operation_service,
:user_merge_to_ref, request, timeout: GitalyClient.long_timeout)
- if pre_receive_error = response.pre_receive_error.presence
- raise Gitlab::Git::PreReceiveError, pre_receive_error
- end
-
response.commit_id
end
@@ -153,10 +149,6 @@ module Gitlab
second_response = response_enum.next
- if second_response.pre_receive_error.present?
- raise Gitlab::Git::PreReceiveError, second_response.pre_receive_error
- end
-
branch_update = second_response.branch_update
return if branch_update.nil?
raise Gitlab::Git::CommitError, 'failed to apply merge to branch' unless branch_update.commit_id.present?
@@ -164,16 +156,20 @@ module Gitlab
Gitlab::Git::OperationService::BranchUpdate.from_gitaly(branch_update)
rescue GRPC::BadStatus => e
- decoded_error = decode_detailed_error(e)
-
- raise unless decoded_error.present?
-
- # We simply ignore any reference update errors which are typically an
- # indicator of multiple RPC calls trying to update the same reference
- # at the same point in time.
- return if decoded_error.is_a?(Gitlab::Git::ReferenceUpdateError)
+ detailed_error = decode_detailed_error(e)
- raise decoded_error
+ case detailed_error&.error
+ when :access_check
+ access_check_error = detailed_error.access_check
+ # These messages were returned from internal/allowed API calls
+ raise Gitlab::Git::PreReceiveError.new(fallback_message: access_check_error.error_message)
+ when :reference_update
+ # We simply ignore any reference update errors which are typically an
+ # indicator of multiple RPC calls trying to update the same reference
+ # at the same point in time.
+ else
+ raise
+ end
ensure
request_enum.close
end
@@ -267,6 +263,19 @@ module Gitlab
perform_next_gitaly_rebase_request(response_enum)
rebase_sha
+ rescue GRPC::BadStatus => e
+ detailed_error = decode_detailed_error(e)
+
+ case detailed_error&.error
+ when :access_check
+ access_check_error = detailed_error.access_check
+ # These messages were returned from internal/allowed API calls
+ raise Gitlab::Git::PreReceiveError.new(fallback_message: access_check_error.error_message)
+ when :rebase_conflict
+ raise Gitlab::Git::Repository::GitError, e.details
+ else
+ raise e
+ end
ensure
request_enum.close
end
@@ -295,6 +304,26 @@ module Gitlab
end
response.squash_sha
+ rescue GRPC::BadStatus => e
+ detailed_error = decode_detailed_error(e)
+
+ case detailed_error&.error
+ when :resolve_revision, :rebase_conflict
+ # Theoretically, we could now raise specific errors based on the type
+ # of the detailed error. Most importantly, we get error details when
+ # Gitaly was not able to resolve the `start_sha` or `end_sha` via a
+ # ResolveRevisionError, and we get information about which files are
+ # conflicting via a MergeConflictError.
+ #
+ # We don't do this now though such that we can maintain backwards
+ # compatibility with the minimum required set of changes during the
+ # transitory period where we're migrating UserSquash to use
+ # structured errors. We thus continue to just return a GitError, like
+ # we previously did.
+ raise Gitlab::Git::Repository::GitError, e.details
+ else
+ raise
+ end
end
def user_update_submodule(user:, submodule:, commit_sha:, branch:, message:)
@@ -492,23 +521,7 @@ module Gitlab
prefix = %r{type\.googleapis\.com\/gitaly\.(?<error_type>.+)}
error_type = prefix.match(detailed_error.type_url)[:error_type]
- detailed_error = Gitaly.const_get(error_type, false).decode(detailed_error.value)
-
- case detailed_error.error
- when :access_check
- access_check_error = detailed_error.access_check
- # These messages were returned from internal/allowed API calls
- Gitlab::Git::PreReceiveError.new(fallback_message: access_check_error.error_message)
- when :reference_update
- reference_update_error = detailed_error.reference_update
- Gitlab::Git::ReferenceUpdateError.new(err.details,
- reference_update_error.reference_name,
- reference_update_error.old_oid,
- reference_update_error.new_oid)
- else
- # We're handling access_check only for now, but we'll add more detailed error types
- nil
- end
+ Gitaly.const_get(error_type, false).decode(detailed_error.value)
rescue NameError, NoMethodError
# Error Class might not be known to ruby yet
nil
diff --git a/lib/gitlab/gitaly_client/repository_service.rb b/lib/gitlab/gitaly_client/repository_service.rb
index 73848dfff5d..5c447dfd417 100644
--- a/lib/gitlab/gitaly_client/repository_service.rb
+++ b/lib/gitlab/gitaly_client/repository_service.rb
@@ -21,6 +21,16 @@ module Gitlab
response.exists
end
+ def optimize_repository
+ request = Gitaly::OptimizeRepositoryRequest.new(repository: @gitaly_repo)
+ GitalyClient.call(@storage, :repository_service, :optimize_repository, request, timeout: GitalyClient.long_timeout)
+ end
+
+ def prune_unreachable_objects
+ request = Gitaly::PruneUnreachableObjectsRequest.new(repository: @gitaly_repo)
+ GitalyClient.call(@storage, :repository_service, :prune_unreachable_objects, request, timeout: GitalyClient.long_timeout)
+ end
+
def garbage_collect(create_bitmap, prune:)
request = Gitaly::GarbageCollectRequest.new(repository: @gitaly_repo, create_bitmap: create_bitmap, prune: prune)
GitalyClient.call(@storage, :repository_service, :garbage_collect, request, timeout: GitalyClient.long_timeout)
@@ -97,8 +107,8 @@ module Gitlab
end
# rubocop: enable Metrics/ParameterLists
- def create_repository
- request = Gitaly::CreateRepositoryRequest.new(repository: @gitaly_repo)
+ def create_repository(default_branch = nil)
+ request = Gitaly::CreateRepositoryRequest.new(repository: @gitaly_repo, default_branch: default_branch)
GitalyClient.call(@storage, :repository_service, :create_repository, request, timeout: GitalyClient.fast_timeout)
end
diff --git a/lib/gitlab/gitaly_client/wiki_service.rb b/lib/gitlab/gitaly_client/wiki_service.rb
index 3613cd01122..ca839b232cf 100644
--- a/lib/gitlab/gitaly_client/wiki_service.rb
+++ b/lib/gitlab/gitaly_client/wiki_service.rb
@@ -64,12 +64,13 @@ module Gitlab
GitalyClient.call(@repository.storage, :wiki_service, :wiki_update_page, enum, timeout: GitalyClient.medium_timeout)
end
- def find_page(title:, version: nil, dir: nil)
+ def find_page(title:, version: nil, dir: nil, load_content: true)
request = Gitaly::WikiFindPageRequest.new(
repository: @gitaly_repo,
title: encode_binary(title),
revision: encode_binary(version),
- directory: encode_binary(dir)
+ directory: encode_binary(dir),
+ skip_content: !load_content
)
response = GitalyClient.call(@repository.storage, :wiki_service, :wiki_find_page, request, timeout: GitalyClient.fast_timeout)
diff --git a/lib/gitlab/github_import/importer/diff_note_importer.rb b/lib/gitlab/github_import/importer/diff_note_importer.rb
index 02b582190b6..a9f8483d8c3 100644
--- a/lib/gitlab/github_import/importer/diff_note_importer.rb
+++ b/lib/gitlab/github_import/importer/diff_note_importer.rb
@@ -4,6 +4,8 @@ module Gitlab
module GithubImport
module Importer
class DiffNoteImporter
+ DiffNoteCreationError = Class.new(ActiveRecord::RecordInvalid)
+
# note - An instance of `Gitlab::GithubImport::Representation::DiffNote`
# project - An instance of `Project`
# client - An instance of `Gitlab::GithubImport::Client`
@@ -31,7 +33,7 @@ module Gitlab
else
import_with_legacy_diff_note
end
- rescue ::DiffNote::NoteDiffFileCreationError => e
+ rescue ::DiffNote::NoteDiffFileCreationError, DiffNoteCreationError => e
Logger.warn(message: e.message, 'error.class': e.class.name)
import_with_legacy_diff_note
@@ -84,7 +86,7 @@ module Gitlab
def import_with_diff_note
log_diff_note_creation('DiffNote')
- ::Import::Github::Notes::CreateService.new(project, author, {
+ record = ::Import::Github::Notes::CreateService.new(project, author, {
noteable_type: note.noteable_type,
system: false,
type: 'DiffNote',
@@ -97,6 +99,8 @@ module Gitlab
updated_at: note.updated_at,
position: note.diff_position
}).execute
+
+ raise DiffNoteCreationError, record unless record.persisted?
end
def note_body
diff --git a/lib/gitlab/github_import/importer/pull_requests_importer.rb b/lib/gitlab/github_import/importer/pull_requests_importer.rb
index fc0c099b71c..5d291d9d723 100644
--- a/lib/gitlab/github_import/importer/pull_requests_importer.rb
+++ b/lib/gitlab/github_import/importer/pull_requests_importer.rb
@@ -74,6 +74,10 @@ module Gitlab
{ state: 'all', sort: 'created', direction: 'asc' }
end
+ def parallel_import_batch
+ { size: 200, delay: 1.minute }
+ end
+
def repository_updates_counter
@repository_updates_counter ||= Gitlab::Metrics.counter(
:github_importer_repository_updates,
diff --git a/lib/gitlab/github_import/parallel_scheduling.rb b/lib/gitlab/github_import/parallel_scheduling.rb
index a8e006ea082..4dec9543a13 100644
--- a/lib/gitlab/github_import/parallel_scheduling.rb
+++ b/lib/gitlab/github_import/parallel_scheduling.rb
@@ -72,6 +72,14 @@ module Gitlab
# Imports all objects in parallel by scheduling a Sidekiq job for every
# individual object.
def parallel_import
+ if Feature.enabled?(:spread_parallel_import, default_enabled: :yaml) && parallel_import_batch.present?
+ spread_parallel_import
+ else
+ parallel_import_deprecated
+ end
+ end
+
+ def parallel_import_deprecated
waiter = JobWaiter.new
each_object_to_import do |object|
@@ -86,6 +94,33 @@ module Gitlab
waiter
end
+ def spread_parallel_import
+ waiter = JobWaiter.new
+
+ import_arguments = []
+
+ each_object_to_import do |object|
+ repr = representation_class.from_api_response(object)
+
+ import_arguments << [project.id, repr.to_hash, waiter.key]
+
+ waiter.jobs_remaining += 1
+ end
+
+ # rubocop:disable Scalability/BulkPerformWithContext
+ Gitlab::ApplicationContext.with_context(project: project) do
+ sidekiq_worker_class.bulk_perform_in(
+ 1.second,
+ import_arguments,
+ batch_size: parallel_import_batch[:size],
+ batch_delay: parallel_import_batch[:delay]
+ )
+ end
+ # rubocop:enable Scalability/BulkPerformWithContext
+
+ waiter
+ end
+
# The method that will be called for traversing through all the objects to
# import, yielding them to the supplied block.
def each_object_to_import
@@ -171,6 +206,12 @@ module Gitlab
raise NotImplementedError
end
+ # Default batch settings for parallel import (can be redefined in Importer classes)
+ # Example: { size: 100, delay: 1.minute }
+ def parallel_import_batch
+ {}
+ end
+
def abort_on_failure
false
end
diff --git a/lib/gitlab/gon_helper.rb b/lib/gitlab/gon_helper.rb
index 2bd59415771..9f18513f066 100644
--- a/lib/gitlab/gon_helper.rb
+++ b/lib/gitlab/gon_helper.rb
@@ -40,7 +40,6 @@ module Gitlab
gon.ee = Gitlab.ee?
gon.jh = Gitlab.jh?
gon.dot_com = Gitlab.com?
- gon.dev_env_or_com = Gitlab.dev_env_or_com?
if current_user
gon.current_user_id = current_user.id
@@ -52,13 +51,15 @@ module Gitlab
# Initialize gon.features with any flags that should be
# made globally available to the frontend
- push_frontend_feature_flag(:snippets_binary_blob, default_enabled: false)
push_frontend_feature_flag(:usage_data_api, type: :ops, default_enabled: :yaml)
push_frontend_feature_flag(:security_auto_fix, default_enabled: false)
push_frontend_feature_flag(:improved_emoji_picker, default_enabled: :yaml)
push_frontend_feature_flag(:new_header_search, default_enabled: :yaml)
push_frontend_feature_flag(:bootstrap_confirmation_modals, default_enabled: :yaml)
push_frontend_feature_flag(:sandboxed_mermaid, default_enabled: :yaml)
+ push_frontend_feature_flag(:source_editor_toolbar, default_enabled: :yaml)
+ push_frontend_feature_flag(:gl_avatar_for_all_user_avatars, default_enabled: :yaml)
+ push_frontend_feature_flag(:mr_attention_requests, default_enabled: :yaml)
end
# Exposes the state of a feature flag to the frontend code.
diff --git a/lib/gitlab/graphql/batch_key.rb b/lib/gitlab/graphql/batch_key.rb
index 51203af5a43..553e0573c63 100644
--- a/lib/gitlab/graphql/batch_key.rb
+++ b/lib/gitlab/graphql/batch_key.rb
@@ -4,6 +4,7 @@ module Gitlab
module Graphql
class BatchKey
attr_reader :object
+
delegate :hash, to: :object
def initialize(object, lookahead = nil, object_name: nil)
diff --git a/lib/gitlab/graphql/loaders/batch_commit_loader.rb b/lib/gitlab/graphql/loaders/batch_commit_loader.rb
new file mode 100644
index 00000000000..26c1f61c567
--- /dev/null
+++ b/lib/gitlab/graphql/loaders/batch_commit_loader.rb
@@ -0,0 +1,40 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Graphql
+ module Loaders
+ class BatchCommitLoader
+ def initialize(container_class:, container_id:, oid:)
+ @container_class = container_class
+ @container_id = container_id
+ @oid = oid
+ end
+
+ def find
+ Gitlab::Graphql::Lazy.with_value(find_containers) do |container|
+ BatchLoader::GraphQL.for(oid).batch(key: container) do |oids, loader, args|
+ container = args[:key]
+
+ container.repository.commits_by(oids: oids).each do |commit|
+ loader.call(commit.id, commit) if commit
+ end
+ end
+ end
+ end
+
+ private
+
+ def find_containers
+ BatchLoader::GraphQL.for(container_id.to_i).batch(key: container_class) do |ids, loader, args|
+ model = args[:key]
+ results = model.includes(:route).id_in(ids) # rubocop: disable CodeReuse/ActiveRecord
+
+ results.each { |record| loader.call(record.id, record) }
+ end
+ end
+
+ attr_reader :container_class, :container_id, :oid
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/graphql/pagination/keyset/generic_keyset_pagination.rb b/lib/gitlab/graphql/pagination/keyset/generic_keyset_pagination.rb
index 15f95edd318..e8335a3c79c 100644
--- a/lib/gitlab/graphql/pagination/keyset/generic_keyset_pagination.rb
+++ b/lib/gitlab/graphql/pagination/keyset/generic_keyset_pagination.rb
@@ -17,21 +17,13 @@ module Gitlab
strong_memoize(:generic_keyset_pagination_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
case sliced_nodes
when Array
sliced_nodes.size > limit_value
else
- # 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
sliced_nodes.limit(1).offset(limit_value).exists?
- # replacing relation count
- # relation_count(set_limit(sliced_nodes, limit_value + 1)) == limit_value + 1
end
else
false
diff --git a/lib/gitlab/harbor/client.rb b/lib/gitlab/harbor/client.rb
new file mode 100644
index 00000000000..06142ae2b40
--- /dev/null
+++ b/lib/gitlab/harbor/client.rb
@@ -0,0 +1,43 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Harbor
+ class Client
+ Error = Class.new(StandardError)
+ ConfigError = Class.new(Error)
+
+ attr_reader :integration
+
+ def initialize(integration)
+ raise ConfigError, 'Please check your integration configuration.' unless integration
+
+ @integration = integration
+ end
+
+ def ping
+ options = { headers: headers.merge!('Accept': 'text/plain') }
+ response = Gitlab::HTTP.get(url('ping'), options)
+
+ { success: response.success? }
+ end
+
+ private
+
+ def url(path)
+ Gitlab::Utils.append_path(base_url, path)
+ end
+
+ def base_url
+ Gitlab::Utils.append_path(integration.url, '/api/v2.0/')
+ end
+
+ def headers
+ auth = Base64.strict_encode64("#{integration.username}:#{integration.password}")
+ {
+ 'Content-Type': 'application/json',
+ 'Authorization': "Basic #{auth}"
+ }
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/health_checks/db_check.rb b/lib/gitlab/health_checks/db_check.rb
index ec4b97eaca4..3df312af1bc 100644
--- a/lib/gitlab/health_checks/db_check.rb
+++ b/lib/gitlab/health_checks/db_check.rb
@@ -13,12 +13,14 @@ module Gitlab
end
def successful?(result)
- result == '1'
+ result == Gitlab::Database.database_base_models.size
end
def check
catch_timeout 10.seconds do
- ActiveRecord::Base.connection.execute('SELECT 1 as ping')&.first&.[]('ping')&.to_s
+ Gitlab::Database.database_base_models.sum do |_, base|
+ base.connection.select_value('SELECT 1')
+ end
end
end
end
diff --git a/lib/gitlab/highlight.rb b/lib/gitlab/highlight.rb
index 49712548960..758a594036b 100644
--- a/lib/gitlab/highlight.rb
+++ b/lib/gitlab/highlight.rb
@@ -11,11 +11,7 @@ module Gitlab
end
def self.too_large?(size)
- return false unless size.to_i > self.file_size_limit
-
- over_highlight_size_limit.increment(source: "file size: #{self.file_size_limit}") if Feature.enabled?(:track_file_size_over_highlight_limit)
-
- true
+ size.to_i > self.file_size_limit
end
attr_reader :blob_name
@@ -74,14 +70,10 @@ module Gitlab
end
def highlight_rich(text, continue: true)
- add_highlight_attempt_metric
-
tag = lexer.tag
tokens = lexer.lex(text, continue: continue)
Timeout.timeout(timeout_time) { @formatter.format(tokens, **context, tag: tag).html_safe }
rescue Timeout::Error => e
- add_highlight_timeout_metric
-
Gitlab::ErrorTracking.track_and_raise_for_dev_exception(e)
highlight_plain(text)
rescue StandardError
@@ -95,38 +87,5 @@ module Gitlab
def link_dependencies(text, highlighted_text)
Gitlab::DependencyLinker.link(blob_name, text, highlighted_text)
end
-
- def add_highlight_attempt_metric
- return unless Feature.enabled?(:track_highlight_timeouts)
-
- highlighting_attempt.increment(source: (@language || "undefined"))
- end
-
- def add_highlight_timeout_metric
- return unless Feature.enabled?(:track_highlight_timeouts)
-
- highlight_timeout.increment(source: Gitlab::Runtime.sidekiq? ? "background" : "foreground")
- end
-
- def highlighting_attempt
- @highlight_attempt ||= Gitlab::Metrics.counter(
- :file_highlighting_attempt,
- 'Counts the times highlighting has been attempted on a file'
- )
- end
-
- def highlight_timeout
- @highlight_timeout ||= Gitlab::Metrics.counter(
- :highlight_timeout,
- 'Counts the times highlights have timed out'
- )
- end
-
- def self.over_highlight_size_limit
- @over_highlight_size_limit ||= Gitlab::Metrics.counter(
- :over_highlight_size_limit,
- 'Count the times files have been over the highlight size limit'
- )
- end
end
end
diff --git a/lib/gitlab/hook_data/issuable_builder.rb b/lib/gitlab/hook_data/issuable_builder.rb
index b8da6731081..5c8aa5050ed 100644
--- a/lib/gitlab/hook_data/issuable_builder.rb
+++ b/lib/gitlab/hook_data/issuable_builder.rb
@@ -26,7 +26,7 @@ module Gitlab
end
def safe_keys
- issuable_builder.safe_hook_attributes + issuable_builder::SAFE_HOOK_RELATIONS
+ issuable_builder.safe_hook_attributes + issuable_builder.safe_hook_relations
end
private
diff --git a/lib/gitlab/hook_data/issue_builder.rb b/lib/gitlab/hook_data/issue_builder.rb
index 181ce447b52..bd0603c5e5b 100644
--- a/lib/gitlab/hook_data/issue_builder.rb
+++ b/lib/gitlab/hook_data/issue_builder.rb
@@ -3,13 +3,16 @@
module Gitlab
module HookData
class IssueBuilder < BaseBuilder
- SAFE_HOOK_RELATIONS = %i[
- assignees
- labels
- total_time_spent
- time_change
- severity
- ].freeze
+ def self.safe_hook_relations
+ %i[
+ assignees
+ labels
+ total_time_spent
+ time_change
+ severity
+ escalation_status
+ ].freeze
+ end
def self.safe_hook_attributes
%i[
@@ -56,6 +59,10 @@ module Gitlab
severity: issue.severity
}
+ if issue.supports_escalation? && issue.escalation_status
+ attrs[:escalation_status] = issue.escalation_status.status_name
+ end
+
issue.attributes.with_indifferent_access.slice(*self.class.safe_hook_attributes)
.merge!(attrs)
end
diff --git a/lib/gitlab/hook_data/merge_request_builder.rb b/lib/gitlab/hook_data/merge_request_builder.rb
index 0e787a77a25..aaca16d8d7c 100644
--- a/lib/gitlab/hook_data/merge_request_builder.rb
+++ b/lib/gitlab/hook_data/merge_request_builder.rb
@@ -34,12 +34,14 @@ module Gitlab
].freeze
end
- SAFE_HOOK_RELATIONS = %i[
- assignees
- labels
- total_time_spent
- time_change
- ].freeze
+ def self.safe_hook_relations
+ %i[
+ assignees
+ labels
+ total_time_spent
+ time_change
+ ].freeze
+ end
alias_method :merge_request, :object
diff --git a/lib/gitlab/http_connection_adapter.rb b/lib/gitlab/http_connection_adapter.rb
index dfecf3a669e..002708beb3c 100644
--- a/lib/gitlab/http_connection_adapter.rb
+++ b/lib/gitlab/http_connection_adapter.rb
@@ -29,7 +29,7 @@ module Gitlab
http = super
http.hostname_override = hostname if hostname
- if Feature.enabled?(:header_read_timeout_buffered_io)
+ if Feature.enabled?(:header_read_timeout_buffered_io, default_enabled: :yaml)
gitlab_http = Gitlab::NetHttpAdapter.new(http.address, http.port)
http.instance_variables.each do |variable|
@@ -47,6 +47,7 @@ module Gitlab
def validate_url!(url)
Gitlab::UrlBlocker.validate!(url, allow_local_network: allow_local_requests?,
allow_localhost: allow_local_requests?,
+ allow_object_storage: allow_object_storage?,
dns_rebind_protection: dns_rebind_protection?)
rescue Gitlab::UrlBlocker::BlockedUrlError => e
raise Gitlab::HTTP::BlockedUrlError, "URL '#{url}' is blocked: #{e.message}"
@@ -56,6 +57,10 @@ module Gitlab
options.fetch(:allow_local_requests, allow_settings_local_requests?)
end
+ def allow_object_storage?
+ options.fetch(:allow_object_storage, false)
+ end
+
def dns_rebind_protection?
return false if Gitlab.http_proxy_env?
diff --git a/lib/gitlab/i18n.rb b/lib/gitlab/i18n.rb
index 584f7d4aeaf..d01f7d0074f 100644
--- a/lib/gitlab/i18n.rb
+++ b/lib/gitlab/i18n.rb
@@ -43,27 +43,27 @@ module Gitlab
TRANSLATION_LEVELS = {
'bg' => 0,
'cs_CZ' => 0,
- 'da_DK' => 48,
+ 'da_DK' => 46,
'de' => 15,
'en' => 100,
'eo' => 0,
- 'es' => 39,
+ 'es' => 40,
'fil_PH' => 0,
'fr' => 11,
'gl_ES' => 0,
'id_ID' => 0,
'it' => 2,
- 'ja' => 35,
- 'ko' => 13,
- 'nb_NO' => 31,
+ 'ja' => 34,
+ 'ko' => 12,
+ 'nb_NO' => 30,
'nl_NL' => 0,
'pl_PL' => 4,
- 'pt_BR' => 50,
+ 'pt_BR' => 49,
'ro_RO' => 22,
'ru' => 32,
'tr_TR' => 14,
- 'uk' => 44,
- 'zh_CN' => 96,
+ 'uk' => 48,
+ 'zh_CN' => 95,
'zh_HK' => 2,
'zh_TW' => 2
}.freeze
diff --git a/lib/gitlab/import_export/base/relation_factory.rb b/lib/gitlab/import_export/base/relation_factory.rb
index 8a8c74c302d..53dd6f8cd55 100644
--- a/lib/gitlab/import_export/base/relation_factory.rb
+++ b/lib/gitlab/import_export/base/relation_factory.rb
@@ -300,7 +300,7 @@ module Gitlab
return cache[table_name] if cache.has_key?(table_name)
index_exists =
- ActiveRecord::Base.connection.index_exists?(
+ relation_class.connection.index_exists?(
relation_class.table_name,
importable_foreign_key,
unique: true)
diff --git a/lib/gitlab/import_export/base/relation_object_saver.rb b/lib/gitlab/import_export/base/relation_object_saver.rb
new file mode 100644
index 00000000000..d0fae2cbb95
--- /dev/null
+++ b/lib/gitlab/import_export/base/relation_object_saver.rb
@@ -0,0 +1,109 @@
+# frozen_string_literal: true
+
+# RelationObjectSaver allows for an alternative approach to persisting
+# objects during Project/Group Import which persists object's
+# nested collection subrelations separately, in batches.
+#
+# Instead of the regular `relation_object.save!` that opens one db
+# transaction for the object itself and all of its subrelations we
+# separate collection subrelations from the object and save them
+# in batches in smaller more frequent db transactions.
+module Gitlab
+ module ImportExport
+ module Base
+ class RelationObjectSaver
+ include Gitlab::Utils::StrongMemoize
+
+ BATCH_SIZE = 100
+ MIN_RECORDS_SIZE = 5
+
+ # @param relation_object [Object] Object of a project/group, e.g. an issue
+ # @param relation_key [String] Name of the object association to group/project, e.g. :issues
+ # @param relation_definition [Hash] Object subrelations as defined in import_export.yml
+ # @param importable [Project|Group] Project or group where relation object is getting saved to
+ #
+ # @example
+ # Gitlab::ImportExport::Base::RelationObjectSaver.new(
+ # relation_key: 'merge_requests',
+ # relation_object: #<MergeRequest id: root/mrs!1, notes: [#<Note id: nil, note: 'test', ...>, #<Note id: nil, noteL 'another note'>]>,
+ # relation_definition: {"metrics"=>{}, "award_emoji"=>{}, "notes"=>{"author"=>{}, ... }}
+ # importable: @importable
+ # ).execute
+ def initialize(relation_object:, relation_key:, relation_definition:, importable:)
+ @relation_object = relation_object
+ @relation_key = relation_key
+ @relation_definition = relation_definition
+ @importable = importable
+ @invalid_subrelations = []
+ end
+
+ def execute
+ move_subrelations
+
+ relation_object.save!
+
+ save_subrelations
+ ensure
+ log_invalid_subrelations
+ end
+
+ private
+
+ attr_reader :relation_object, :relation_key, :relation_definition,
+ :importable, :collection_subrelations, :invalid_subrelations
+
+ # rubocop:disable GitlabSecurity/PublicSend
+ def save_subrelations
+ collection_subrelations.each_pair do |relation_name, records|
+ records.each_slice(BATCH_SIZE) do |batch|
+ valid_records, invalid_records = batch.partition { |record| record.valid? }
+
+ invalid_subrelations << invalid_records
+ relation_object.public_send(relation_name) << valid_records
+ end
+ end
+ end
+
+ def move_subrelations
+ strong_memoize(:collection_subrelations) do
+ relation_definition.each_key.each_with_object({}) do |definition, collection_subrelations|
+ subrelation = relation_object.public_send(definition)
+ association = relation_object.class.reflect_on_association(definition)
+
+ if association&.collection? && subrelation.size > MIN_RECORDS_SIZE
+ collection_subrelations[definition] = subrelation.records
+
+ subrelation.clear
+ end
+ end
+ end
+ end
+ # rubocop:enable GitlabSecurity/PublicSend
+
+ def log_invalid_subrelations
+ invalid_subrelations.flatten.each do |record|
+ Gitlab::Import::Logger.info(
+ message: '[Project/Group Import] Invalid subrelation',
+ importable_column_name => importable.id,
+ relation_key: relation_key,
+ error_messages: record.errors.full_messages.to_sentence
+ )
+
+ ImportFailure.create(
+ source: 'RelationObjectSaver#save!',
+ relation_key: relation_key,
+ exception_class: 'RecordInvalid',
+ exception_message: record.errors.full_messages.to_sentence,
+ correlation_id_value: Labkit::Correlation::CorrelationId.current_or_new_id,
+ importable_column_name => importable.id
+ )
+ end
+ end
+
+ def importable_column_name
+ @column_name ||= importable.class.reflect_on_association(:import_failures).foreign_key.to_sym
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/import_export/command_line_util.rb b/lib/gitlab/import_export/command_line_util.rb
index e520cade517..2b0467d8779 100644
--- a/lib/gitlab/import_export/command_line_util.rb
+++ b/lib/gitlab/import_export/command_line_util.rb
@@ -6,6 +6,8 @@ module Gitlab
UNTAR_MASK = 'u+rwX,go+rX,go-w'
DEFAULT_DIR_MODE = 0700
+ FileOversizedError = Class.new(StandardError)
+
def tar_czf(archive:, dir:)
tar_with_options(archive: archive, dir: dir, options: 'czf')
end
@@ -51,19 +53,34 @@ module Gitlab
private
- def download_or_copy_upload(uploader, upload_path)
+ def download_or_copy_upload(uploader, upload_path, size_limit: nil)
if uploader.upload.local?
copy_files(uploader.path, upload_path)
else
- download(uploader.url, upload_path)
+ download(uploader.url, upload_path, size_limit: size_limit)
end
end
- def download(url, upload_path)
- File.open(upload_path, 'w') do |file|
- # Download (stream) file from the uploader's location
- IO.copy_stream(URI.parse(url).open, file)
+ def download(url, upload_path, size_limit: nil)
+ File.open(upload_path, 'wb') do |file|
+ current_size = 0
+
+ Gitlab::HTTP.get(url, stream_body: true, allow_object_storage: true) do |fragment|
+ if [301, 302, 307].include?(fragment.code)
+ Gitlab::Import::Logger.warn(message: "received redirect fragment", fragment_code: fragment.code)
+ elsif fragment.code == 200
+ current_size += fragment.bytesize
+
+ raise FileOversizedError if size_limit.present? && current_size > size_limit
+
+ file.write(fragment)
+ else
+ raise Gitlab::ImportExport::Error, "unsupported response downloading fragment #{fragment.code}"
+ end
+ end
end
+ rescue FileOversizedError
+ nil
end
def tar_with_options(archive:, dir:, options:)
diff --git a/lib/gitlab/import_export/file_importer.rb b/lib/gitlab/import_export/file_importer.rb
index 5274fcec43e..829b3771518 100644
--- a/lib/gitlab/import_export/file_importer.rb
+++ b/lib/gitlab/import_export/file_importer.rb
@@ -72,9 +72,17 @@ module Gitlab
import_export_upload = @importable.import_export_upload
if import_export_upload.remote_import_url.present?
- download(import_export_upload.remote_import_url, @archive_file)
+ download(
+ import_export_upload.remote_import_url,
+ @archive_file,
+ size_limit: ::Import::GitlabProjects::RemoteFileValidator::FILE_SIZE_LIMIT
+ )
else
- download_or_copy_upload(import_export_upload.import_file, @archive_file)
+ download_or_copy_upload(
+ import_export_upload.import_file,
+ @archive_file,
+ size_limit: ::Import::GitlabProjects::RemoteFileValidator::FILE_SIZE_LIMIT
+ )
end
end
diff --git a/lib/gitlab/import_export/group/object_builder.rb b/lib/gitlab/import_export/group/object_builder.rb
index 43cc7a78a61..e26f37c3347 100644
--- a/lib/gitlab/import_export/group/object_builder.rb
+++ b/lib/gitlab/import_export/group/object_builder.rb
@@ -13,21 +13,12 @@ module Gitlab
super
@group = @attributes['group']
-
- update_description
end
private
attr_reader :group
- # Convert description empty string to nil
- # due to existing object being saved with description: nil
- # Which makes object lookup to fail since nil != ''
- def update_description
- attributes['description'] = nil if attributes['description'] == ''
- end
-
def where_clauses
[
where_clause_base,
diff --git a/lib/gitlab/import_export/group/relation_tree_restorer.rb b/lib/gitlab/import_export/group/relation_tree_restorer.rb
index c2cbd2fdf47..b44874f598c 100644
--- a/lib/gitlab/import_export/group/relation_tree_restorer.rb
+++ b/lib/gitlab/import_export/group/relation_tree_restorer.rb
@@ -29,7 +29,7 @@ module Gitlab
end
def restore
- ActiveRecord::Base.uncached do
+ Gitlab::Database.all_uncached do
ActiveRecord::Base.no_touching do
update_params!
@@ -79,10 +79,7 @@ module Gitlab
relation_object.assign_attributes(importable_class_sym => @importable)
- import_failure_service.with_retry(action: 'relation_object.save!', relation_key: relation_key, relation_index: relation_index) do
- relation_object.save!
- log_relation_creation(@importable, relation_key, relation_object)
- end
+ save_relation_object(relation_object, relation_key, relation_definition, relation_index)
rescue StandardError => e
import_failure_service.log_import_failure(
source: 'process_relation_item!',
@@ -91,6 +88,23 @@ module Gitlab
exception: e)
end
+ def save_relation_object(relation_object, relation_key, relation_definition, relation_index)
+ if Feature.enabled?(:import_relation_object_persistence, default_enabled: :yaml) && relation_object.new_record?
+ Gitlab::ImportExport::Base::RelationObjectSaver.new(
+ relation_object: relation_object,
+ relation_key: relation_key,
+ relation_definition: relation_definition,
+ importable: @importable
+ ).execute
+ else
+ import_failure_service.with_retry(action: 'relation_object.save!', relation_key: relation_key, relation_index: relation_index) do
+ relation_object.save!
+ end
+ end
+
+ log_relation_creation(@importable, relation_key, relation_object)
+ end
+
def import_failure_service
@import_failure_service ||= ImportFailureService.new(@importable)
end
diff --git a/lib/gitlab/import_export/json/streaming_serializer.rb b/lib/gitlab/import_export/json/streaming_serializer.rb
index d893c8dfaa3..55b8c1d4531 100644
--- a/lib/gitlab/import_export/json/streaming_serializer.rb
+++ b/lib/gitlab/import_export/json/streaming_serializer.rb
@@ -166,8 +166,6 @@ module Gitlab
end
def read_from_replica_if_available(&block)
- return yield unless ::Feature.enabled?(:load_balancing_for_export_workers, type: :development, default_enabled: :yaml)
-
::Gitlab::Database::LoadBalancing::Session.current.use_replicas_for_read_queries(&block)
end
end
diff --git a/lib/gitlab/import_export/project/import_export.yml b/lib/gitlab/import_export/project/import_export.yml
index 059f6bd42e3..fc05cc1a79c 100644
--- a/lib/gitlab/import_export/project/import_export.yml
+++ b/lib/gitlab/import_export/project/import_export.yml
@@ -370,6 +370,7 @@ included_attributes:
- :name
- :email
events:
+ - :project_id
- :target_type
- :action
- :author_id
diff --git a/lib/gitlab/insecure_key_fingerprint.rb b/lib/gitlab/insecure_key_fingerprint.rb
index 7b1cf5e7931..ef342f3819f 100644
--- a/lib/gitlab/insecure_key_fingerprint.rb
+++ b/lib/gitlab/insecure_key_fingerprint.rb
@@ -10,6 +10,7 @@ module Gitlab
#
class InsecureKeyFingerprint
attr_accessor :key
+
alias_attribute :fingerprint_md5, :fingerprint
#
diff --git a/lib/gitlab/integrations/sti_type.rb b/lib/gitlab/integrations/sti_type.rb
index 1350d75b216..82c2b3297c1 100644
--- a/lib/gitlab/integrations/sti_type.rb
+++ b/lib/gitlab/integrations/sti_type.rb
@@ -5,7 +5,7 @@ module Gitlab
class StiType < ActiveRecord::Type::String
NAMESPACED_INTEGRATIONS = Set.new(%w(
Asana Assembla Bamboo Bugzilla Buildkite Campfire Confluence CustomIssueTracker Datadog
- Discord DroneCi EmailsOnPush Ewm ExternalWiki Flowdock HangoutsChat Irker Jenkins Jira Mattermost
+ Discord DroneCi EmailsOnPush Ewm ExternalWiki Flowdock HangoutsChat Harbor Irker Jenkins Jira Mattermost
MattermostSlashCommands MicrosoftTeams MockCi MockMonitoring Packagist PipelinesEmail Pivotaltracker
Prometheus Pushover Redmine Shimo Slack SlackSlashCommands Teamcity UnifyCircuit WebexTeams Youtrack Zentao
)).freeze
diff --git a/lib/gitlab/json.rb b/lib/gitlab/json.rb
index 368b621bdfb..9824b46554f 100644
--- a/lib/gitlab/json.rb
+++ b/lib/gitlab/json.rb
@@ -16,6 +16,9 @@ module Gitlab
# @return [Boolean, String, Array, Hash]
# @raise [JSON::ParserError] raised if parsing fails
def parse(string, opts = {})
+ # Parse nil as nil
+ return if string.nil?
+
# First we should ensure this really is a string, not some other
# type which purports to be a string. This handles some legacy
# usage of the JSON class.
@@ -30,6 +33,7 @@ module Gitlab
end
alias_method :parse!, :parse
+ alias_method :load, :parse
# Restricted method for converting a Ruby object to JSON. If you
# need to pass options to this, you should use `.generate` instead,
@@ -67,6 +71,14 @@ module Gitlab
::JSON.pretty_generate(object, opts)
end
+ # The standard parser error we should be returning. Defined in a method
+ # so we can potentially override it later.
+ #
+ # @return [JSON::ParserError]
+ def parser_error
+ ::JSON::ParserError
+ end
+
private
# Convert JSON string into Ruby through toggleable adapters.
@@ -134,14 +146,6 @@ module Gitlab
opts
end
- # The standard parser error we should be returning. Defined in a method
- # so we can potentially override it later.
- #
- # @return [JSON::ParserError]
- def parser_error
- ::JSON::ParserError
- end
-
# @param [Nil, Boolean] an extracted :legacy_mode key from the opts hash
# @return [Boolean]
def legacy_mode_enabled?(arg_value)
diff --git a/lib/gitlab/json_cache.rb b/lib/gitlab/json_cache.rb
index 41c18f82a4b..d5c018cfc68 100644
--- a/lib/gitlab/json_cache.rb
+++ b/lib/gitlab/json_cache.rb
@@ -2,12 +2,17 @@
module Gitlab
class JsonCache
- attr_reader :backend, :cache_key_with_version, :namespace
+ attr_reader :backend, :namespace
+
+ STRATEGY_KEY_COMPONENTS = {
+ revision: Gitlab.revision,
+ version: [Gitlab::VERSION, Rails.version]
+ }.freeze
def initialize(options = {})
@backend = options.fetch(:backend, Rails.cache)
@namespace = options.fetch(:namespace, nil)
- @cache_key_with_version = options.fetch(:cache_key_with_version, true)
+ @cache_key_strategy = options.fetch(:cache_key_strategy, :revision)
end
def active?
@@ -19,13 +24,12 @@ module Gitlab
end
def cache_key(key)
- expanded_cache_key = [namespace, key].compact
-
- if cache_key_with_version
- expanded_cache_key << [Gitlab::VERSION, Rails.version]
- end
+ expanded_cache_key = [namespace, key, *strategy_key_component].compact
+ expanded_cache_key.join(':').freeze
+ end
- expanded_cache_key.flatten.join(':').freeze
+ def strategy_key_component
+ STRATEGY_KEY_COMPONENTS.fetch(@cache_key_strategy)
end
def expire(key)
@@ -39,7 +43,9 @@ module Gitlab
end
def write(key, value, options = nil)
- backend.write(cache_key(key), value.to_json, options)
+ # As we use json as the serialization format, return everything from
+ # ActiveModel objects included encrypted values.
+ backend.write(cache_key(key), value.to_json(unsafe_serialization_hash: true), options)
end
def fetch(key, options = {}, &block)
diff --git a/lib/gitlab/kubernetes/kubeconfig/template.rb b/lib/gitlab/kubernetes/kubeconfig/template.rb
index da0861ee86a..d40b9ce117e 100644
--- a/lib/gitlab/kubernetes/kubeconfig/template.rb
+++ b/lib/gitlab/kubernetes/kubeconfig/template.rb
@@ -14,6 +14,7 @@ module Gitlab
@clusters = []
@users = []
@contexts = []
+ @current_context = nil
end
def valid?
@@ -32,14 +33,45 @@ module Gitlab
contexts << new_entry(:context, **args)
end
+ def merge_yaml(kubeconfig_yaml)
+ return unless kubeconfig_yaml
+
+ kubeconfig_yaml = YAML.safe_load(kubeconfig_yaml, symbolize_names: true)
+ kubeconfig_yaml[:users].each do |user|
+ add_user(
+ name: user[:name],
+ token: user.dig(:user, :token)
+ )
+ end
+ kubeconfig_yaml[:clusters].each do |cluster|
+ ca_pem = cluster.dig(:cluster, :'certificate-authority-data')&.yield_self do |data|
+ Base64.strict_decode64(data)
+ end
+
+ add_cluster(
+ name: cluster[:name],
+ url: cluster.dig(:cluster, :server),
+ ca_pem: ca_pem
+ )
+ end
+ kubeconfig_yaml[:contexts].each do |context|
+ add_context(
+ name: context[:name],
+ **context[:context]&.slice(:cluster, :user, :namespace)
+ )
+ end
+ @current_context = kubeconfig_yaml[:'current-context']
+ end
+
def to_h
{
apiVersion: 'v1',
kind: 'Config',
clusters: clusters.map(&:to_h),
users: users.map(&:to_h),
- contexts: contexts.map(&:to_h)
- }
+ contexts: contexts.map(&:to_h),
+ 'current-context': current_context
+ }.compact
end
def to_yaml
@@ -48,7 +80,7 @@ module Gitlab
private
- attr_reader :clusters, :users, :contexts
+ attr_reader :clusters, :users, :contexts, :current_context
def new_entry(entry, **args)
ENTRIES.fetch(entry).new(**args)
diff --git a/lib/gitlab/language_detection.rb b/lib/gitlab/language_detection.rb
index 6f7fa9fe03b..b259f58350b 100644
--- a/lib/gitlab/language_detection.rb
+++ b/lib/gitlab/language_detection.rb
@@ -63,7 +63,7 @@ module Gitlab
@repository
.languages
.first(MAX_LANGUAGES)
- .to_h { |l| [l[:label], l] }
+ .index_by { |l| l[:label] }
end
end
end
diff --git a/lib/gitlab/mail_room.rb b/lib/gitlab/mail_room.rb
index e93a297cee4..ef5ca56a13b 100644
--- a/lib/gitlab/mail_room.rb
+++ b/lib/gitlab/mail_room.rb
@@ -12,6 +12,11 @@ module Gitlab
module MailRoom
RAILS_ROOT_DIR = Pathname.new('../..').expand_path(__dir__).freeze
+ DELIVERY_METHOD_SIDEKIQ = 'sidekiq'
+ DELIVERY_METHOD_WEBHOOK = 'webhook'
+ INTERNAL_API_REQUEST_HEADER = 'Gitlab-Mailroom-Api-Request'
+ INTERNAL_API_REQUEST_JWT_ISSUER = 'gitlab-mailroom'
+
DEFAULT_CONFIG = {
enabled: false,
port: 143,
@@ -20,7 +25,8 @@ module Gitlab
mailbox: 'inbox',
idle_timeout: 60,
log_path: RAILS_ROOT_DIR.join('log', 'mail_room_json.log'),
- expunge_deleted: false
+ expunge_deleted: false,
+ delivery_method: DELIVERY_METHOD_SIDEKIQ
}.freeze
# Email specific configuration which is merged with configuration
@@ -63,7 +69,9 @@ module Gitlab
return {} unless File.exist?(config_file)
config = merged_configs(config_key)
+
config.merge!(redis_config) if enabled?(config)
+
config[:log_path] = File.expand_path(config[:log_path], RAILS_ROOT_DIR)
config
diff --git a/lib/gitlab/mail_room/authenticator.rb b/lib/gitlab/mail_room/authenticator.rb
index 26ebdca8beb..ca583d4cddb 100644
--- a/lib/gitlab/mail_room/authenticator.rb
+++ b/lib/gitlab/mail_room/authenticator.rb
@@ -6,8 +6,6 @@ module Gitlab
include JwtAuthenticatable
SecretConfigurationError = Class.new(StandardError)
- INTERNAL_API_REQUEST_HEADER = 'Gitlab-Mailroom-Api-Request'
- INTERNAL_API_REQUEST_JWT_ISSUER = 'gitlab-mailroom'
# Only allow token generated within the last 5 minutes
EXPIRATION = 5.minutes
@@ -18,9 +16,10 @@ module Gitlab
return false if enabled_configs[mailbox_type].blank?
decode_jwt(
- request_headers[INTERNAL_API_REQUEST_HEADER],
+ request_headers[Gitlab::MailRoom::INTERNAL_API_REQUEST_HEADER],
secret(mailbox_type),
- issuer: INTERNAL_API_REQUEST_JWT_ISSUER, iat_after: Time.current - EXPIRATION
+ issuer: Gitlab::MailRoom::INTERNAL_API_REQUEST_JWT_ISSUER,
+ iat_after: Time.current - EXPIRATION
)
rescue JWT::DecodeError => e
::Gitlab::AppLogger.warn("Fail to decode MailRoom JWT token: #{e.message}") if Rails.env.development?
diff --git a/lib/gitlab/merge_requests/commit_message_generator.rb b/lib/gitlab/merge_requests/commit_message_generator.rb
index 0515c17fe5d..ef5c63925c2 100644
--- a/lib/gitlab/merge_requests/commit_message_generator.rb
+++ b/lib/gitlab/merge_requests/commit_message_generator.rb
@@ -50,6 +50,19 @@ module Gitlab
.except(commit_author&.commit_email_or_default)
.map { |author_email, author_name| "Co-authored-by: #{author_name} <#{author_email}>" }
.join("\n")
+ end,
+ 'all_commits' => -> (merge_request, _, _) do
+ merge_request
+ .recent_commits
+ .without_merge_commits
+ .map do |commit|
+ if commit.safe_message&.bytesize&.>(100.kilobytes)
+ "* #{commit.title}\n\n-- Skipped commit body exceeding 100KiB in size."
+ else
+ "* #{commit.safe_message&.strip}"
+ end
+ end
+ .join("\n\n")
end
}.freeze
diff --git a/lib/gitlab/merge_requests/mergeability/check_result.rb b/lib/gitlab/merge_requests/mergeability/check_result.rb
index d0788c7d7c7..5284d20d423 100644
--- a/lib/gitlab/merge_requests/mergeability/check_result.rb
+++ b/lib/gitlab/merge_requests/mergeability/check_result.rb
@@ -22,8 +22,8 @@ module Gitlab
def self.from_hash(data)
new(
- status: data.fetch(:status),
- payload: data.fetch(:payload))
+ status: data.fetch('status').to_sym,
+ payload: data.fetch('payload'))
end
def initialize(status:, payload: {})
diff --git a/lib/gitlab/merge_requests/mergeability/results_store.rb b/lib/gitlab/merge_requests/mergeability/results_store.rb
index bb6489f8526..2f7b8888b2f 100644
--- a/lib/gitlab/merge_requests/mergeability/results_store.rb
+++ b/lib/gitlab/merge_requests/mergeability/results_store.rb
@@ -9,7 +9,11 @@ module Gitlab
end
def read(merge_check:)
- interface.retrieve_check(merge_check: merge_check)
+ result_hash = interface.retrieve_check(merge_check: merge_check)
+
+ return if result_hash.blank?
+
+ CheckResult.from_hash(result_hash)
end
def write(merge_check:, result_hash:)
diff --git a/lib/gitlab/metrics/dashboard/stages/cluster_endpoint_inserter.rb b/lib/gitlab/metrics/dashboard/stages/cluster_endpoint_inserter.rb
index 2c17982d299..31d75225972 100644
--- a/lib/gitlab/metrics/dashboard/stages/cluster_endpoint_inserter.rb
+++ b/lib/gitlab/metrics/dashboard/stages/cluster_endpoint_inserter.rb
@@ -74,7 +74,7 @@ module Gitlab
def verify_params
raise Errors::DashboardProcessingError, _('Cluster is required for Stages::ClusterEndpointInserter') unless params[:cluster]
- raise Errors::DashboardProcessingError, _('Cluster type must be specificed for Stages::ClusterEndpointInserter') unless params[:cluster_type]
+ raise Errors::DashboardProcessingError, _('Cluster type must be specified for Stages::ClusterEndpointInserter') unless params[:cluster_type]
end
end
end
diff --git a/lib/gitlab/metrics/subscribers/active_record.rb b/lib/gitlab/metrics/subscribers/active_record.rb
index 715dd86d93c..12576cabb19 100644
--- a/lib/gitlab/metrics/subscribers/active_record.rb
+++ b/lib/gitlab/metrics/subscribers/active_record.rb
@@ -134,11 +134,7 @@ module Gitlab
:"gitlab_transaction_db_#{counter}_total"
end
- if ENV['GITLAB_MULTIPLE_DATABASE_METRICS']
- current_transaction&.increment(prometheus_key, 1, { db_config_name: db_config_name })
- else
- current_transaction&.increment(prometheus_key, 1)
- end
+ current_transaction&.increment(prometheus_key, 1, { db_config_name: db_config_name })
Gitlab::SafeRequestStore[log_key] = Gitlab::SafeRequestStore[log_key].to_i + 1
@@ -154,11 +150,7 @@ module Gitlab
def observe(histogram, event, &block)
db_config_name = db_config_name(event.payload)
- if ENV['GITLAB_MULTIPLE_DATABASE_METRICS']
- current_transaction&.observe(histogram, event.duration / 1000.0, { db_config_name: db_config_name }, &block)
- else
- current_transaction&.observe(histogram, event.duration / 1000.0, &block)
- end
+ current_transaction&.observe(histogram, event.duration / 1000.0, { db_config_name: db_config_name }, &block)
end
def current_transaction
@@ -193,11 +185,9 @@ module Gitlab
counters << compose_metric_key(metric, role)
end
- if ENV['GITLAB_MULTIPLE_DATABASE_METRICS']
- ::Gitlab::Database.db_config_names.each do |config_name|
- counters << compose_metric_key(metric, nil, config_name) # main
- counters << compose_metric_key(metric, nil, config_name + ::Gitlab::Database::LoadBalancing::LoadBalancer::REPLICA_SUFFIX) # main_replica
- end
+ ::Gitlab::Database.db_config_names.each do |config_name|
+ counters << compose_metric_key(metric, nil, config_name) # main
+ counters << compose_metric_key(metric, nil, config_name + ::Gitlab::Database::LoadBalancing::LoadBalancer::REPLICA_SUFFIX) # main_replica
end
end
diff --git a/lib/gitlab/omniauth_initializer.rb b/lib/gitlab/omniauth_initializer.rb
index a9ff186c7cb..f4984e11c14 100644
--- a/lib/gitlab/omniauth_initializer.rb
+++ b/lib/gitlab/omniauth_initializer.rb
@@ -3,6 +3,7 @@
module Gitlab
class OmniauthInitializer
OAUTH2_TIMEOUT_SECONDS = 10
+ ConfigurationError = Class.new(StandardError)
def initialize(devise_config)
@devise_config = devise_config
@@ -75,16 +76,29 @@ module Gitlab
provider_arguments << provider[argument] if provider[argument]
end
- case provider['args']
+ arguments = provider.fetch('args', {})
+ defaults = provider_defaults(provider)
+
+ case arguments
when Array
- # An Array from the configuration will be expanded.
- provider_arguments.concat provider['args']
+ # An Array from the configuration will be expanded
+ provider_arguments.concat arguments
+ provider_arguments << defaults unless defaults.empty?
when Hash
- defaults = provider_defaults(provider)
- hash_arguments = provider['args'].deep_symbolize_keys.deep_merge(defaults)
+ hash_arguments = arguments.deep_symbolize_keys.deep_merge(defaults)
+ normalized = normalize_hash_arguments(hash_arguments)
# A Hash from the configuration will be passed as is.
- provider_arguments << normalize_hash_arguments(hash_arguments)
+ provider_arguments << normalized unless normalized.empty?
+ else
+ # this will prevent the application from starting in development mode.
+ # we still set defaults, and let the application start in prod.
+ Gitlab::ErrorTracking.track_and_raise_for_dev_exception(
+ ConfigurationError.new("Arguments were provided for #{provider['name']}, but not as an array or a hash"),
+ provider_name: provider['name'],
+ arguments_type: arguments.class.name
+ )
+ provider_arguments << defaults unless defaults.empty?
end
provider_arguments
diff --git a/lib/gitlab/pages/settings.rb b/lib/gitlab/pages/settings.rb
index b35683c9dec..7ada15cfe9a 100644
--- a/lib/gitlab/pages/settings.rb
+++ b/lib/gitlab/pages/settings.rb
@@ -16,7 +16,7 @@ module Gitlab
def disk_access_denied?
return true unless ::Settings.pages.local_store&.enabled
- ::Gitlab::Runtime.web_server? && !::Gitlab::Runtime.test_suite?
+ ::Gitlab::Runtime.puma? && !::Gitlab::Runtime.test_suite?
end
def report_denied_disk_access
diff --git a/lib/gitlab/pagination/gitaly_keyset_pager.rb b/lib/gitlab/pagination/gitaly_keyset_pager.rb
index 99a3145104a..e76cab688cc 100644
--- a/lib/gitlab/pagination/gitaly_keyset_pager.rb
+++ b/lib/gitlab/pagination/gitaly_keyset_pager.rb
@@ -4,6 +4,7 @@ module Gitlab
module Pagination
class GitalyKeysetPager
attr_reader :request_context, :project
+
delegate :params, to: :request_context
def initialize(request_context, project)
diff --git a/lib/gitlab/pagination/keyset/cursor_based_request_context.rb b/lib/gitlab/pagination/keyset/cursor_based_request_context.rb
index 18390f5b59d..e06d7e48ca3 100644
--- a/lib/gitlab/pagination/keyset/cursor_based_request_context.rb
+++ b/lib/gitlab/pagination/keyset/cursor_based_request_context.rb
@@ -6,6 +6,7 @@ module Gitlab
class CursorBasedRequestContext
DEFAULT_SORT_DIRECTION = :desc
attr_reader :request_context
+
delegate :params, to: :request_context
def initialize(request_context)
diff --git a/lib/gitlab/pagination/keyset/header_builder.rb b/lib/gitlab/pagination/keyset/header_builder.rb
index 888d93d5fe3..1036916e665 100644
--- a/lib/gitlab/pagination/keyset/header_builder.rb
+++ b/lib/gitlab/pagination/keyset/header_builder.rb
@@ -5,6 +5,7 @@ module Gitlab
module Keyset
class HeaderBuilder
attr_reader :request_context
+
delegate :params, :header, :request, to: :request_context
def initialize(request_context)
diff --git a/lib/gitlab/pagination/offset_pagination.rb b/lib/gitlab/pagination/offset_pagination.rb
index 4f8a6ffb2cc..fca75d1fe01 100644
--- a/lib/gitlab/pagination/offset_pagination.rb
+++ b/lib/gitlab/pagination/offset_pagination.rb
@@ -4,6 +4,7 @@ module Gitlab
module Pagination
class OffsetPagination < Base
attr_reader :request_context
+
delegate :params, :header, :request, to: :request_context
def initialize(request_context)
@@ -26,7 +27,7 @@ module Gitlab
end
return pagination_data unless pagination_data.is_a?(ActiveRecord::Relation)
- return pagination_data unless Feature.enabled?(:api_kaminari_count_with_limit, type: :ops)
+ return pagination_data unless Feature.enabled?(:api_kaminari_count_with_limit, type: :ops, default_enabled: :yaml)
limited_total_count = pagination_data.total_count_with_limit
if limited_total_count > Kaminari::ActiveRecordRelationMethods::MAX_COUNT_LIMIT
diff --git a/lib/gitlab/patch/action_cable_redis_listener.rb b/lib/gitlab/patch/action_cable_redis_listener.rb
new file mode 100644
index 00000000000..b21bee45991
--- /dev/null
+++ b/lib/gitlab/patch/action_cable_redis_listener.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+# Modifies https://github.com/rails/rails/blob/v6.1.4.6/actioncable/lib/action_cable/subscription_adapter/redis.rb
+# so that it is resilient to Redis connection errors.
+# See https://github.com/rails/rails/issues/27659.
+
+# rubocop:disable Gitlab/ModuleWithInstanceVariables
+module Gitlab
+ module Patch
+ module ActionCableRedisListener
+ private
+
+ def ensure_listener_running
+ @thread ||= Thread.new do
+ Thread.current.abort_on_exception = true
+
+ conn = @adapter.redis_connection_for_subscriptions
+ listen conn
+ rescue ::Redis::BaseConnectionError
+ @thread = @raw_client = nil
+ ::ActionCable.server.restart
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/path_regex.rb b/lib/gitlab/path_regex.rb
index 06a26c4830f..6f497c6376d 100644
--- a/lib/gitlab/path_regex.rb
+++ b/lib/gitlab/path_regex.rb
@@ -255,7 +255,7 @@ module Gitlab
end
def container_image_regex
- @container_image_regex ||= %r{([\w\.-]+\/){0,1}[\w\.-]+}.freeze
+ @container_image_regex ||= %r{([\w\.-]+\/){0,4}[\w\.-]+}.freeze
end
def container_image_blob_sha_regex
diff --git a/lib/gitlab/performance_bar/stats.rb b/lib/gitlab/performance_bar/stats.rb
index cf524e69454..8743772eef6 100644
--- a/lib/gitlab/performance_bar/stats.rb
+++ b/lib/gitlab/performance_bar/stats.rb
@@ -25,8 +25,8 @@ module Gitlab
log_queries(id, data, 'active-record')
log_queries(id, data, 'gitaly')
log_queries(id, data, 'redis')
- rescue StandardError => err
- logger.error(message: "failed to process request id #{id}: #{err.message}")
+ rescue StandardError => e
+ logger.error(message: "failed to process request id #{id}: #{e.message}")
end
private
@@ -34,6 +34,8 @@ module Gitlab
def request(id)
# Peek gem stores request data under peek:requests:request_id key
json_data = @redis.get("peek:requests:#{id}")
+ raise "No data for #{id}" if json_data.nil?
+
Gitlab::Json.parse(json_data)
end
diff --git a/lib/gitlab/process_supervisor.rb b/lib/gitlab/process_supervisor.rb
new file mode 100644
index 00000000000..18fd24aa582
--- /dev/null
+++ b/lib/gitlab/process_supervisor.rb
@@ -0,0 +1,149 @@
+# frozen_string_literal: true
+
+module Gitlab
+ # Given a set of process IDs, the supervisor can monitor processes
+ # for being alive and invoke a callback if some or all should go away.
+ # The receiver of the callback can then act on this event, for instance
+ # by restarting those processes or performing clean-up work.
+ #
+ # The supervisor will also trap termination signals if provided and
+ # propagate those to the supervised processes. Any supervised processes
+ # that do not terminate within a specified grace period will be killed.
+ class ProcessSupervisor < Gitlab::Daemon
+ DEFAULT_HEALTH_CHECK_INTERVAL_SECONDS = 5
+ DEFAULT_TERMINATE_INTERVAL_SECONDS = 1
+ DEFAULT_TERMINATE_TIMEOUT_SECONDS = 10
+
+ attr_reader :alive
+
+ def initialize(
+ health_check_interval_seconds: DEFAULT_HEALTH_CHECK_INTERVAL_SECONDS,
+ check_terminate_interval_seconds: DEFAULT_TERMINATE_INTERVAL_SECONDS,
+ terminate_timeout_seconds: DEFAULT_TERMINATE_TIMEOUT_SECONDS,
+ term_signals: %i(INT TERM),
+ forwarded_signals: [],
+ **options)
+ super(**options)
+
+ @term_signals = term_signals
+ @forwarded_signals = forwarded_signals
+ @health_check_interval_seconds = health_check_interval_seconds
+ @check_terminate_interval_seconds = check_terminate_interval_seconds
+ @terminate_timeout_seconds = terminate_timeout_seconds
+
+ @pids = []
+ @alive = false
+ end
+
+ # Starts a supervision loop for the given process ID(s).
+ #
+ # If any or all processes go away, the IDs of any dead processes will
+ # be yielded to the given block, so callers can act on them.
+ #
+ # If the block returns a non-empty list of IDs, the supervisor will
+ # start observing those processes instead. Otherwise it will shut down.
+ def supervise(pid_or_pids, &on_process_death)
+ @pids = Array(pid_or_pids)
+ @on_process_death = on_process_death
+
+ trap_signals!
+
+ start
+ end
+
+ # Shuts down the supervisor and all supervised processes with the given signal.
+ def shutdown(signal = :TERM)
+ return unless @alive
+
+ stop_processes(signal)
+ stop
+ end
+
+ def supervised_pids
+ @pids
+ end
+
+ private
+
+ def start_working
+ @alive = true
+ end
+
+ def stop_working
+ @alive = false
+ end
+
+ def run_thread
+ while @alive
+ sleep(@health_check_interval_seconds)
+
+ check_process_health
+ end
+ end
+
+ def check_process_health
+ unless all_alive?
+ existing_pids = live_pids # Capture this value for the duration of the block.
+ dead_pids = @pids - existing_pids
+ new_pids = Array(@on_process_death.call(dead_pids))
+ @pids = existing_pids + new_pids
+ @alive = @pids.any?
+ end
+ end
+
+ def stop_processes(signal)
+ # Set this prior to shutting down so that shutdown hooks which read `alive`
+ # know the supervisor is about to shut down.
+ @alive = false
+
+ # Shut down supervised processes.
+ signal_all(signal)
+ wait_for_termination
+ end
+
+ def trap_signals!
+ ProcessManagement.trap_signals(@term_signals) do |signal|
+ stop_processes(signal)
+ end
+
+ ProcessManagement.trap_signals(@forwarded_signals) do |signal|
+ signal_all(signal)
+ end
+ end
+
+ def wait_for_termination
+ deadline = monotonic_time + @terminate_timeout_seconds
+ sleep(@check_terminate_interval_seconds) while continue_waiting?(deadline)
+
+ hard_stop_stuck_pids
+ end
+
+ def monotonic_time
+ Process.clock_gettime(Process::CLOCK_MONOTONIC, :float_second)
+ end
+
+ def continue_waiting?(deadline)
+ any_alive? && monotonic_time < deadline
+ end
+
+ def signal_all(signal)
+ ProcessManagement.signal_processes(@pids, signal)
+ end
+
+ def hard_stop_stuck_pids
+ ProcessManagement.signal_processes(live_pids, "-KILL")
+ end
+
+ def any_alive?
+ ProcessManagement.any_alive?(@pids)
+ end
+
+ def all_alive?
+ ProcessManagement.all_alive?(@pids)
+ end
+
+ def live_pids
+ ProcessManagement.pids_alive(@pids)
+ end
+ end
+end
diff --git a/lib/gitlab/profiler.rb b/lib/gitlab/profiler.rb
index b2179d80a18..3a5f1a1d480 100644
--- a/lib/gitlab/profiler.rb
+++ b/lib/gitlab/profiler.rb
@@ -28,7 +28,7 @@ module Gitlab
].freeze
# Takes a URL to profile (can be a fully-qualified URL, or an absolute path)
- # and returns the ruby-prof profile result. Formatting that result is the
+ # and returns the profiler result. Formatting that result is the
# caller's responsibility. Requests are GET requests unless post_data is
# passed.
#
@@ -43,7 +43,13 @@ module Gitlab
#
# - private_token: instead of providing a user instance, the token can be
# given as a string. Takes precedence over the user option.
- def self.profile(url, logger: nil, post_data: nil, user: nil, private_token: nil)
+ #
+ # - sampling_mode: When true, uses a sampling profiler (StackProf) instead of a tracing profiler (RubyProf).
+ #
+ # - profiler_options: A keyword Hash of arguments passed to the profiler. Defaults by profiler type:
+ # RubyProf - {}
+ # StackProf - { mode: :wall, out: <some temporary file>, interval: 1000, raw: true }
+ def self.profile(url, logger: nil, post_data: nil, user: nil, private_token: nil, sampling_mode: false, profiler_options: {})
app = ActionDispatch::Integration::Session.new(Rails.application)
verb = :get
headers = {}
@@ -75,7 +81,9 @@ module Gitlab
with_custom_logger(logger) do
with_user(user) do
- RubyProf.profile { app.public_send(verb, url, params: post_data, headers: headers) } # rubocop:disable GitlabSecurity/PublicSend
+ with_profiler(sampling_mode, profiler_options) do
+ app.public_send(verb, url, params: post_data, headers: headers) # rubocop:disable GitlabSecurity/PublicSend
+ end
end
end
end
@@ -172,5 +180,16 @@ module Gitlab
RubyProf::FlatPrinter.new(result).print($stdout, default_options.merge(options))
end
+
+ def self.with_profiler(sampling_mode, profiler_options)
+ if sampling_mode
+ require 'stackprof'
+ args = { mode: :wall, interval: 1000, raw: true }.merge!(profiler_options)
+ args[:out] ||= ::Tempfile.new(["profile-#{Time.now.to_i}-", ".dump"]).path
+ ::StackProf.run(**args) { yield }
+ else
+ RubyProf.profile(**profiler_options) { yield }
+ end
+ end
end
end
diff --git a/lib/gitlab/project_authorizations.rb b/lib/gitlab/project_authorizations.rb
index 121626ced56..1d7b179baf0 100644
--- a/lib/gitlab/project_authorizations.rb
+++ b/lib/gitlab/project_authorizations.rb
@@ -22,7 +22,7 @@ module Gitlab
user.projects_with_active_memberships.select_for_project_authorization,
# The personal projects of the user.
- user.personal_projects.select_as_maintainer_for_project_authorization,
+ user.personal_projects.select_project_owner_for_project_authorization,
# Projects that belong directly to any of the groups the user has
# access to.
diff --git a/lib/gitlab/prometheus/queries/base_query.rb b/lib/gitlab/prometheus/queries/base_query.rb
index 9ff414d5236..eabac6128b5 100644
--- a/lib/gitlab/prometheus/queries/base_query.rb
+++ b/lib/gitlab/prometheus/queries/base_query.rb
@@ -5,6 +5,7 @@ module Gitlab
module Queries
class BaseQuery
attr_accessor :client
+
delegate :query_range, :query, :label_values, :series, to: :client, prefix: true
def raw_memory_usage_query(environment_slug)
diff --git a/lib/gitlab/quick_actions/issue_actions.rb b/lib/gitlab/quick_actions/issue_actions.rb
index b44b47eca37..2f89774a257 100644
--- a/lib/gitlab/quick_actions/issue_actions.rb
+++ b/lib/gitlab/quick_actions/issue_actions.rb
@@ -291,7 +291,7 @@ module Gitlab
types Issue
condition do
current_user.can?(:set_issue_crm_contacts, quick_action_target) &&
- CustomerRelations::Contact.exists_for_group?(quick_action_target.project.group)
+ CustomerRelations::Contact.exists_for_group?(quick_action_target.project.root_ancestor)
end
execution_message do
_('One or more contacts were successfully added.')
@@ -306,7 +306,7 @@ module Gitlab
types Issue
condition do
current_user.can?(:set_issue_crm_contacts, quick_action_target) &&
- CustomerRelations::Contact.exists_for_group?(quick_action_target.project.group)
+ CustomerRelations::Contact.exists_for_group?(quick_action_target.project.root_ancestor)
end
execution_message do
_('One or more contacts were successfully removed.')
diff --git a/lib/gitlab/quick_actions/merge_request_actions.rb b/lib/gitlab/quick_actions/merge_request_actions.rb
index 842d4ef482b..e6a73c71e85 100644
--- a/lib/gitlab/quick_actions/merge_request_actions.rb
+++ b/lib/gitlab/quick_actions/merge_request_actions.rb
@@ -23,7 +23,11 @@ module Gitlab
end
end
execution_message do
- if preferred_strategy = preferred_auto_merge_strategy(quick_action_target)
+ if params[:merge_request_diff_head_sha].blank?
+ _("Merge request diff sha parameter is required for the merge quick action.")
+ elsif params[:merge_request_diff_head_sha] != quick_action_target.diff_head_sha
+ _("Branch has been updated since the merge was requested.")
+ elsif preferred_strategy = preferred_auto_merge_strategy(quick_action_target)
_("Scheduled to merge this merge request (%{strategy}).") % { strategy: preferred_strategy.humanize }
else
_('Merged this merge request.')
@@ -35,6 +39,10 @@ module Gitlab
merge_orchestration_service.can_merge?(quick_action_target)
end
command :merge do
+ next unless params[:merge_request_diff_head_sha].present?
+
+ next unless params[:merge_request_diff_head_sha] == quick_action_target.diff_head_sha
+
@updates[:merge] = params[:merge_request_diff_head_sha]
end
diff --git a/lib/gitlab/regex.rb b/lib/gitlab/regex.rb
index a6491d23bf5..c9202c6c54c 100644
--- a/lib/gitlab/regex.rb
+++ b/lib/gitlab/regex.rb
@@ -259,6 +259,15 @@ module Gitlab
"It must start with a letter, digit, emoji, or '_'."
end
+ # Project path must conform to this regex. See https://gitlab.com/gitlab-org/gitlab/-/issues/27483
+ def oci_repository_path_regex
+ @oci_repository_path_regex ||= %r{\A[a-zA-Z0-9]+([._-][a-zA-Z0-9]+)*\z}.freeze
+ end
+
+ def oci_repository_path_regex_message
+ 'must not start or end with a special character and must not contain consecutive special characters.'
+ end
+
def group_name_regex
@group_name_regex ||= /\A#{group_name_regex_chars}\z/.freeze
end
@@ -459,6 +468,15 @@ module Gitlab
"can contain only lowercase letters, digits, '_' and '-'. " \
"Must start with a letter, and cannot end with '-' or '_'"
end
+
+ def saved_reply_name_regex
+ @saved_reply_name_regex ||= /\A[a-z]([a-z0-9\-_]*[a-z0-9])?\z/.freeze
+ end
+
+ def saved_reply_name_regex_message
+ "can contain only lowercase letters, digits, '_' and '-'. " \
+ "Must start with a letter, and cannot end with '-' or '_'"
+ end
end
end
diff --git a/lib/gitlab/runtime.rb b/lib/gitlab/runtime.rb
index 574e05658bc..5b1341207fd 100644
--- a/lib/gitlab/runtime.rb
+++ b/lib/gitlab/runtime.rb
@@ -65,12 +65,15 @@ module Gitlab
!!defined?(::Rails::Command::RunnerCommand)
end
- def web_server?
- puma?
+ # Whether we are executing in an actual application context i.e. Puma or Sidekiq.
+ def application?
+ puma? || sidekiq?
end
+ # Whether we are executing in a multi-threaded environment. For now this is equivalent
+ # to meaning Puma or Sidekiq, but this could change in the future.
def multi_threaded?
- puma? || sidekiq?
+ application?
end
def puma_in_clustered_mode?
@@ -94,7 +97,7 @@ module Gitlab
threads += Sidekiq.options[:concurrency] + 2
end
- if web_server?
+ if puma?
threads += Gitlab::ActionCable::Config.worker_pool_size
end
diff --git a/lib/gitlab/safe_request_loader.rb b/lib/gitlab/safe_request_loader.rb
new file mode 100644
index 00000000000..89eca16c272
--- /dev/null
+++ b/lib/gitlab/safe_request_loader.rb
@@ -0,0 +1,55 @@
+# frozen_string_literal: true
+
+module Gitlab
+ class SafeRequestLoader
+ def self.execute(args, &block)
+ new(**args).execute(&block)
+ end
+
+ def initialize(resource_key:, resource_ids:, default_value: nil)
+ @resource_key = resource_key
+ @resource_ids = resource_ids.uniq
+ @default_value = default_value
+ @resource_data = {}
+ end
+
+ def execute(&block)
+ raise ArgumentError, 'Block is mandatory' unless block_given?
+
+ load_resource_data
+ remove_loaded_resource_ids
+
+ update_resource_data(&block)
+
+ resource_data
+ end
+
+ private
+
+ attr_reader :resource_key, :resource_ids, :default_value, :resource_data, :missing_resource_ids
+
+ def load_resource_data
+ @resource_data = Gitlab::SafeRequestStore.fetch(resource_key) { resource_data }
+ end
+
+ def remove_loaded_resource_ids
+ # Look up only the IDs we need
+ @missing_resource_ids = resource_ids - resource_data.keys
+ end
+
+ def update_resource_data(&block)
+ return if missing_resource_ids.blank?
+
+ reloaded_resource_data = yield(missing_resource_ids)
+
+ @resource_data.merge!(reloaded_resource_data)
+
+ mark_absent_values
+ end
+
+ def mark_absent_values
+ absent = (missing_resource_ids - resource_data.keys).to_h { [_1, default_value] }
+ @resource_data.merge!(absent)
+ end
+ end
+end
diff --git a/lib/gitlab/sanitizers/exif.rb b/lib/gitlab/sanitizers/exif.rb
index f607aff9d29..e302729df66 100644
--- a/lib/gitlab/sanitizers/exif.rb
+++ b/lib/gitlab/sanitizers/exif.rb
@@ -97,6 +97,28 @@ module Gitlab
end
end
+ def clean_existing_path(src_path, dry_run: false, content: nil, skip_unallowed_types: false)
+ content ||= File.read(src_path)
+
+ if skip_unallowed_types
+ return unless check_for_allowed_types(content, raise_error: false)
+ else
+ check_for_allowed_types(content)
+ end
+
+ to_remove = extra_tags(src_path)
+
+ if to_remove.empty?
+ logger.info "#{src_path}: only whitelisted tags present, skipping"
+ return
+ end
+
+ logger.info "#{src_path}: found exif tags to remove: #{to_remove}"
+ return if dry_run
+
+ exec_remove_exif!(src_path)
+ end
+
private
def extra_tags(path)
@@ -146,12 +168,15 @@ module Gitlab
filename
end
- def check_for_allowed_types(contents)
+ def check_for_allowed_types(contents, raise_error: true)
mime_type = Gitlab::Utils::MimeType.from_string(contents)
- unless ALLOWED_MIME_TYPES.include?(mime_type)
+ allowed = ALLOWED_MIME_TYPES.include?(mime_type)
+ if !allowed && raise_error
raise "File type #{mime_type} not supported. Only supports #{ALLOWED_MIME_TYPES.join(", ")}."
end
+
+ allowed
end
def upload_ref(upload)
diff --git a/lib/gitlab/seeder.rb b/lib/gitlab/seeder.rb
index 5671fce481f..e2df60c46f1 100644
--- a/lib/gitlab/seeder.rb
+++ b/lib/gitlab/seeder.rb
@@ -62,10 +62,6 @@ module Gitlab
end
def self.quiet
- # Disable database insertion logs so speed isn't limited by ability to print to console
- old_logger = ActiveRecord::Base.logger
- ActiveRecord::Base.logger = nil
-
# Additional seed logic for models.
Project.include(ProjectSeed)
User.include(UserSeed)
@@ -75,9 +71,11 @@ module Gitlab
SeedFu.quiet = true
- without_statement_timeout do
- without_new_note_notifications do
- yield
+ without_database_logging do
+ without_statement_timeout do
+ without_new_note_notifications do
+ yield
+ end
end
end
@@ -85,7 +83,6 @@ module Gitlab
ensure
SeedFu.quiet = false
ActionMailer::Base.perform_deliveries = old_perform_deliveries
- ActiveRecord::Base.logger = old_logger
end
def self.without_gitaly_timeout
@@ -112,10 +109,30 @@ module Gitlab
end
def self.without_statement_timeout
- ActiveRecord::Base.connection.execute('SET statement_timeout=0')
+ Gitlab::Database::EachDatabase.each_database_connection do |connection|
+ connection.execute('SET statement_timeout=0')
+ end
+ yield
+ ensure
+ Gitlab::Database::EachDatabase.each_database_connection do |connection|
+ connection.execute('RESET statement_timeout')
+ end
+ end
+
+ def self.without_database_logging
+ old_loggers = Gitlab::Database.database_base_models.transform_values do |model|
+ model.logger
+ end
+
+ Gitlab::Database.database_base_models.each do |_, model|
+ model.logger = nil
+ end
+
yield
ensure
- ActiveRecord::Base.connection.execute('RESET statement_timeout')
+ Gitlab::Database.database_base_models.each do |connection_name, model|
+ model.logger = old_loggers[connection_name]
+ end
end
end
end
diff --git a/lib/gitlab/sidekiq_middleware.rb b/lib/gitlab/sidekiq_middleware.rb
index 69802fd6217..fd3a5f715e8 100644
--- a/lib/gitlab/sidekiq_middleware.rb
+++ b/lib/gitlab/sidekiq_middleware.rb
@@ -33,7 +33,7 @@ module Gitlab
chain.add ::Gitlab::SidekiqMiddleware::BatchLoader
chain.add ::Gitlab::SidekiqMiddleware::InstrumentationLogger
chain.add ::Gitlab::SidekiqMiddleware::AdminMode::Server
- chain.add ::Gitlab::SidekiqMiddleware::QueryAnalyzer if Gitlab.dev_or_test_env? || Gitlab::Utils.to_boolean(ENV['GITLAB_ENABLE_QUERY_ANALYZERS'], default: false)
+ chain.add ::Gitlab::SidekiqMiddleware::QueryAnalyzer
chain.add ::Gitlab::SidekiqVersioning::Middleware
chain.add ::Gitlab::SidekiqStatus::ServerMiddleware
chain.add ::Gitlab::SidekiqMiddleware::WorkerContext::Server
diff --git a/lib/gitlab/sidekiq_middleware/duplicate_jobs/duplicate_job.rb b/lib/gitlab/sidekiq_middleware/duplicate_jobs/duplicate_job.rb
index f31262bfcc9..601c8d1c3cf 100644
--- a/lib/gitlab/sidekiq_middleware/duplicate_jobs/duplicate_job.rb
+++ b/lib/gitlab/sidekiq_middleware/duplicate_jobs/duplicate_job.rb
@@ -167,7 +167,6 @@ module Gitlab
def idempotent?
return false unless worker_klass
return false unless worker_klass.respond_to?(:idempotent?)
- return false unless preserve_wal_location? || !worker_klass.utilizes_load_balancing_capabilities?
worker_klass.idempotent?
end
@@ -206,8 +205,6 @@ module Gitlab
end
def job_wal_locations
- return {} unless preserve_wal_location?
-
job['wal_locations'] || {}
end
@@ -272,10 +269,6 @@ module Gitlab
@existing_wal_locations ||= {}
end
- def preserve_wal_location?
- Feature.enabled?(:preserve_latest_wal_locations_for_idempotent_jobs, default_enabled: :yaml)
- end
-
def reschedulable?
!scheduled? && options[:if_deduplicated] == :reschedule_once
end
diff --git a/lib/gitlab/sidekiq_middleware/server_metrics.rb b/lib/gitlab/sidekiq_middleware/server_metrics.rb
index bea98403997..f3e1d0af2aa 100644
--- a/lib/gitlab/sidekiq_middleware/server_metrics.rb
+++ b/lib/gitlab/sidekiq_middleware/server_metrics.rb
@@ -7,18 +7,26 @@ module Gitlab
# SIDEKIQ_LATENCY_BUCKETS are latency histogram buckets better suited to Sidekiq
# timeframes than the DEFAULT_BUCKET definition. Defined in seconds.
- SIDEKIQ_LATENCY_BUCKETS = [0.1, 0.25, 0.5, 1, 2.5, 5, 10, 60, 300, 600].freeze
+ # This information is better viewed in logs, but these buckets cover
+ # most of the durations for cpu, gitaly, db and elasticsearch
+ SIDEKIQ_LATENCY_BUCKETS = [0.1, 0.5, 1, 2.5].freeze
+
+ # These are the buckets we currently use for alerting, we will likely
+ # replace these histograms with Application SLIs
+ # https://gitlab.com/gitlab-com/gl-infra/scalability/-/issues/1313
+ SIDEKIQ_JOB_DURATION_BUCKETS = [10, 300].freeze
+ SIDEKIQ_QUEUE_DURATION_BUCKETS = [10, 60].freeze
class << self
include ::Gitlab::SidekiqMiddleware::MetricsHelper
def 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_cpu_seconds: ::Gitlab::Metrics.histogram(:sidekiq_jobs_cpu_seconds, 'Seconds this Sidekiq job spent on the CPU', {}, SIDEKIQ_LATENCY_BUCKETS),
+ sidekiq_jobs_completion_seconds: ::Gitlab::Metrics.histogram(:sidekiq_jobs_completion_seconds, 'Seconds to complete Sidekiq job', {}, SIDEKIQ_JOB_DURATION_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_queue_duration_seconds: ::Gitlab::Metrics.histogram(:sidekiq_jobs_queue_duration_seconds, 'Duration in seconds that a Sidekiq job was queued before being executed', {}, SIDEKIQ_QUEUE_DURATION_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'),
diff --git a/lib/gitlab/sidekiq_middleware/size_limiter/validator.rb b/lib/gitlab/sidekiq_middleware/size_limiter/validator.rb
index 3de6c8df8aa..acc3e1712ab 100644
--- a/lib/gitlab/sidekiq_middleware/size_limiter/validator.rb
+++ b/lib/gitlab/sidekiq_middleware/size_limiter/validator.rb
@@ -29,7 +29,12 @@ module Gitlab
# The worker classes aren't constants here, because that would force
# Application Settings to be loaded earlier causing failures loading
# the environment in rake tasks
- EXEMPT_WORKER_NAMES = %w[BackgroundMigrationWorker BackgroundMigration::CiDatabaseWorker Database::BatchedBackgroundMigrationWorker].to_set
+
+ EXEMPT_WORKER_NAMES = %w[BackgroundMigrationWorker
+ BackgroundMigration::CiDatabaseWorker
+ Database::BatchedBackgroundMigrationWorker
+ Database::BatchedBackgroundMigration::CiDatabaseWorker].to_set
+
JOB_STATUS_KEY = 'size_limiter'
class << self
diff --git a/lib/gitlab/untrusted_regexp.rb b/lib/gitlab/untrusted_regexp.rb
index 09236a7f1f0..c0730e7bd59 100644
--- a/lib/gitlab/untrusted_regexp.rb
+++ b/lib/gitlab/untrusted_regexp.rb
@@ -61,6 +61,16 @@ module Gitlab
def self.with_fallback(pattern, multiline: false)
UntrustedRegexp.new(pattern, multiline: multiline)
rescue RegexpError
+ raise if Feature.enabled?(:disable_unsafe_regexp, default_enabled: :yaml)
+
+ if Feature.enabled?(:ci_unsafe_regexp_logger, type: :ops, default_enabled: :yaml)
+ Gitlab::AppJsonLogger.info(
+ class: self.name,
+ regexp: pattern.to_s,
+ fabricated: 'unsafe ruby regexp'
+ )
+ end
+
Regexp.new(pattern)
end
diff --git a/lib/gitlab/untrusted_regexp/ruby_syntax.rb b/lib/gitlab/untrusted_regexp/ruby_syntax.rb
index 5176a6f6273..1f1da592ce0 100644
--- a/lib/gitlab/untrusted_regexp/ruby_syntax.rb
+++ b/lib/gitlab/untrusted_regexp/ruby_syntax.rb
@@ -16,40 +16,23 @@ module Gitlab
# The regexp can match the pattern `/.../`, but may not be fabricatable:
# it can be invalid or incomplete: `/match ( string/`
- def self.valid?(pattern, fallback: false)
- !!self.fabricate(pattern, fallback: fallback)
+ def self.valid?(pattern)
+ !!self.fabricate(pattern)
end
- def self.fabricate(pattern, fallback: false, project: nil)
- self.fabricate!(pattern, fallback: fallback, project: project)
+ def self.fabricate(pattern, project: nil)
+ self.fabricate!(pattern, project: project)
rescue RegexpError
nil
end
- def self.fabricate!(pattern, fallback: false, project: nil)
+ def self.fabricate!(pattern, project: nil)
raise RegexpError, 'Pattern is not string!' unless pattern.is_a?(String)
matches = pattern.match(PATTERN)
raise RegexpError, 'Invalid regular expression!' if matches.nil?
- begin
- create_untrusted_regexp(matches[:regexp], matches[:flags])
- rescue RegexpError
- raise unless fallback &&
- Feature.enabled?(:allow_unsafe_ruby_regexp, default_enabled: :yaml)
-
- if Feature.enabled?(:ci_unsafe_regexp_logger, type: :ops, default_enabled: :yaml)
- Gitlab::AppJsonLogger.info(
- class: self.name,
- regexp: pattern.to_s,
- fabricated: 'unsafe ruby regexp',
- project_id: project&.id,
- project_path: project&.full_path
- )
- end
-
- create_ruby_regexp(matches[:regexp], matches[:flags])
- end
+ create_untrusted_regexp(matches[:regexp], matches[:flags])
end
def self.create_untrusted_regexp(pattern, flags)
@@ -58,15 +41,6 @@ module Gitlab
UntrustedRegexp.new(pattern, multiline: false)
end
private_class_method :create_untrusted_regexp
-
- def self.create_ruby_regexp(pattern, flags)
- options = 0
- options += Regexp::IGNORECASE if flags&.include?('i')
- options += Regexp::MULTILINE if flags&.include?('m')
-
- Regexp.new(pattern, options)
- end
- private_class_method :create_ruby_regexp
end
end
end
diff --git a/lib/gitlab/url_blocker.rb b/lib/gitlab/url_blocker.rb
index 48228ede684..fe8c2227659 100644
--- a/lib/gitlab/url_blocker.rb
+++ b/lib/gitlab/url_blocker.rb
@@ -13,6 +13,7 @@ module Gitlab
# ports - Raises error if the given URL port does is not between given ports.
# allow_localhost - Raises error if URL resolves to a localhost IP address and argument is false.
# allow_local_network - Raises error if URL resolves to a link-local address and argument is false.
+ # allow_object_storage - Avoid raising an error if URL resolves to an object storage endpoint and argument is true.
# ascii_only - Raises error if URL has unicode characters and argument is true.
# enforce_user - Raises error if URL user doesn't start with alphanumeric characters and argument is true.
# enforce_sanitization - Raises error if URL includes any HTML/CSS/JS tags and argument is true.
@@ -25,6 +26,7 @@ module Gitlab
schemes: [],
allow_localhost: false,
allow_local_network: true,
+ allow_object_storage: false,
ascii_only: false,
enforce_user: false,
enforce_sanitization: false,
@@ -58,6 +60,8 @@ module Gitlab
# Allow url from the GitLab instance itself but only for the configured hostname and ports
return protected_uri_with_hostname if internal?(uri)
+ return protected_uri_with_hostname if allow_object_storage && object_storage_endpoint?(uri)
+
validate_local_request(
address_info: address_info,
allow_localhost: allow_localhost,
@@ -149,6 +153,7 @@ module Gitlab
validate_local_network(address_info)
validate_link_local(address_info)
validate_shared_address(address_info)
+ validate_limited_broadcast_address(address_info)
end
end
@@ -253,6 +258,17 @@ module Gitlab
raise BlockedUrlError, "Requests to the link local network are not allowed"
end
+ # Raises a BlockedUrlError if any IP in `addrs_info` is the limited
+ # broadcast address.
+ # https://datatracker.ietf.org/doc/html/rfc919#section-7
+ def validate_limited_broadcast_address(addrs_info)
+ blocked_ips = ["255.255.255.255"]
+
+ return if (blocked_ips & addrs_info.map(&:ip_address)).empty?
+
+ raise BlockedUrlError, "Requests to the limited broadcast address are not allowed"
+ end
+
def internal?(uri)
internal_web?(uri) || internal_shell?(uri)
end
@@ -269,6 +285,30 @@ module Gitlab
get_port(uri) == config.gitlab_shell.ssh_port
end
+ def enabled_object_storage_endpoints
+ ObjectStoreSettings::SUPPORTED_TYPES.collect do |type|
+ section_setting = config.try(type)
+
+ next unless section_setting
+
+ object_store_setting = section_setting['object_store']
+
+ next unless object_store_setting && object_store_setting['enabled']
+
+ object_store_setting.dig('connection', 'endpoint')
+ end.compact.uniq
+ end
+
+ def object_storage_endpoint?(uri)
+ enabled_object_storage_endpoints.any? do |endpoint|
+ endpoint_uri = URI(endpoint)
+
+ uri.scheme == endpoint_uri.scheme &&
+ uri.hostname == endpoint_uri.hostname &&
+ get_port(uri) == get_port(endpoint_uri)
+ end
+ end
+
def domain_allowed?(uri)
Gitlab::UrlBlockers::UrlAllowlist.domain_allowed?(uri.normalized_host, port: get_port(uri))
end
diff --git a/lib/gitlab/usage/metric_definition.rb b/lib/gitlab/usage/metric_definition.rb
index 6e5196ecdbd..1031f38792b 100644
--- a/lib/gitlab/usage/metric_definition.rb
+++ b/lib/gitlab/usage/metric_definition.rb
@@ -80,6 +80,10 @@ module Gitlab
@all ||= definitions.map { |_key_path, definition| definition }
end
+ def not_removed
+ all.select { |definition| definition.attributes[:status] != 'removed' }.index_by(&:key_path)
+ end
+
def with_instrumentation_class
all.select { |definition| definition.attributes[:instrumentation_class].present? && definition.available? }
end
diff --git a/lib/gitlab/usage/metrics/instrumentations/cert_based_clusters_ff_metric.rb b/lib/gitlab/usage/metrics/instrumentations/cert_based_clusters_ff_metric.rb
new file mode 100644
index 00000000000..6df6fef5d3a
--- /dev/null
+++ b/lib/gitlab/usage/metrics/instrumentations/cert_based_clusters_ff_metric.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Usage
+ module Metrics
+ module Instrumentations
+ class CertBasedClustersFfMetric < GenericMetric
+ value do
+ Feature.enabled?(:certificate_based_clusters, default_enabled: :yaml, type: :ops)
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/usage/metrics/instrumentations/database_metric.rb b/lib/gitlab/usage/metrics/instrumentations/database_metric.rb
index d7fc798ebe2..34a8bfd08b5 100644
--- a/lib/gitlab/usage/metrics/instrumentations/database_metric.rb
+++ b/lib/gitlab/usage/metrics/instrumentations/database_metric.rb
@@ -33,6 +33,12 @@ module Gitlab
@metric_relation = block
end
+ def metric_options(&block)
+ return @metric_options&.call.to_h unless block_given?
+
+ @metric_options = block
+ end
+
def operation(symbol, column: nil, &block)
@metric_operation = symbol
@column = column
@@ -54,6 +60,7 @@ module Gitlab
self.class.column,
start: start,
finish: finish,
+ **self.class.metric_options,
&self.class.metric_operation_block)
end
diff --git a/lib/gitlab/usage/service_ping/instrumented_payload.rb b/lib/gitlab/usage/service_ping/instrumented_payload.rb
new file mode 100644
index 00000000000..e04e2e589b2
--- /dev/null
+++ b/lib/gitlab/usage/service_ping/instrumented_payload.rb
@@ -0,0 +1,41 @@
+# frozen_string_literal: true
+
+# Service Ping payload build using the instrumentation classes
+# for given metrics key_paths and output method
+module Gitlab
+ module Usage
+ module ServicePing
+ class InstrumentedPayload
+ attr_reader :metrics_key_paths
+ attr_reader :output_method
+
+ def initialize(metrics_key_paths, output_method)
+ @metrics_key_paths = metrics_key_paths
+ @output_method = output_method
+ end
+
+ def build
+ metrics_key_paths.map do |key_path|
+ compute_instrumental_value(key_path, output_method)
+ end.reduce({}, :deep_merge)
+ end
+
+ private
+
+ # Not all metrics defintions have instrumentation classes
+ # The value can be computed only for those that have it
+ def instrumented_metrics_defintions
+ Gitlab::Usage::MetricDefinition.with_instrumentation_class
+ end
+
+ def compute_instrumental_value(key_path, output_method)
+ definition = instrumented_metrics_defintions.find { |df| df.key_path == key_path }
+
+ return {} unless definition.present?
+
+ Gitlab::Usage::Metric.new(definition).method(output_method).call
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/usage/service_ping/payload_keys_processor.rb b/lib/gitlab/usage/service_ping/payload_keys_processor.rb
new file mode 100644
index 00000000000..ea2043ffb83
--- /dev/null
+++ b/lib/gitlab/usage/service_ping/payload_keys_processor.rb
@@ -0,0 +1,54 @@
+# frozen_string_literal: true
+
+# Process the UsageData payload to get the keys that have a metric defintion
+# Get the missing keys from the payload
+module Gitlab
+ module Usage
+ module ServicePing
+ class PayloadKeysProcessor
+ attr_reader :old_payload
+
+ def initialize(old_payload)
+ @old_payload = old_payload
+ end
+
+ def key_paths
+ @key_paths ||= payload_keys.to_a.flatten.compact
+ end
+
+ def missing_instrumented_metrics_key_paths
+ @missing_key_paths ||= metrics_with_instrumentation.map(&:key) - key_paths
+ end
+
+ private
+
+ def payload_keys(payload = old_payload, parents = [])
+ return unless payload.is_a?(Hash)
+
+ payload.map do |key, value|
+ if has_metric_definition?(key, parents)
+ parents.dup.append(key).join('.')
+ else
+ payload_keys(value, parents.dup << key) if value.is_a?(Hash)
+ end
+ end
+ end
+
+ def has_metric_definition?(key, parent_keys)
+ key_path = parent_keys.dup.append(key).join('.')
+ metric_definitions.key?(key_path)
+ end
+
+ def metric_definitions
+ ::Gitlab::Usage::MetricDefinition.not_removed
+ end
+
+ def metrics_with_instrumentation
+ ::Gitlab::Usage::MetricDefinition.with_instrumentation_class
+ end
+ end
+ end
+ end
+end
+
+Gitlab::Usage::ServicePing::PayloadKeysProcessor.prepend_mod_with('Gitlab::Usage::ServicePing::PayloadKeysProcessor')
diff --git a/lib/gitlab/usage/service_ping_report.rb b/lib/gitlab/usage/service_ping_report.rb
index d9e30c46498..794f3373043 100644
--- a/lib/gitlab/usage/service_ping_report.rb
+++ b/lib/gitlab/usage/service_ping_report.rb
@@ -7,16 +7,29 @@ module Gitlab
def for(output:, cached: false)
case output.to_sym
when :all_metrics_values
- all_metrics_values(cached)
+ with_instrumentation_classes(all_metrics_values(cached), :with_value)
when :metrics_queries
- metrics_queries
+ with_instrumentation_classes(metrics_queries, :with_instrumentation)
when :non_sql_metrics_values
- non_sql_metrics_values
+ with_instrumentation_classes(non_sql_metrics_values, :with_instrumentation)
end
end
private
+ def with_instrumentation_classes(old_payload, output_method)
+ if Feature.enabled?(:merge_service_ping_instrumented_metrics, default_enabled: :yaml)
+
+ instrumented_metrics_key_paths = Gitlab::Usage::ServicePing::PayloadKeysProcessor.new(old_payload).missing_instrumented_metrics_key_paths
+
+ instrumented_payload = Gitlab::Usage::ServicePing::InstrumentedPayload.new(instrumented_metrics_key_paths, output_method).build
+
+ old_payload.deep_merge(instrumented_payload)
+ else
+ old_payload
+ end
+ end
+
def all_metrics_values(cached)
Rails.cache.fetch('usage_data', force: !cached, expires_in: 2.weeks) do
Gitlab::UsageData.data
diff --git a/lib/gitlab/usage_data.rb b/lib/gitlab/usage_data.rb
index e66a565246b..951ec5ea5c3 100644
--- a/lib/gitlab/usage_data.rb
+++ b/lib/gitlab/usage_data.rb
@@ -70,10 +70,9 @@ module Gitlab
def system_usage_data
issues_created_manually_from_alerts = count(Issue.with_alert_management_alerts.not_authored_by(::User.alert_bot), start: minimum_id(Issue), finish: maximum_id(Issue))
- {
+ counts = {
counts: {
assignee_lists: count(List.assignee),
- boards: add_metric('CountBoardsMetric', time_frame: 'all'),
ci_builds: count(::Ci::Build),
ci_internal_pipelines: count(::Ci::Pipeline.internal),
ci_external_pipelines: count(::Ci::Pipeline.external),
@@ -167,6 +166,12 @@ module Gitlab
data[:snippets] = add(data[:personal_snippets], data[:project_snippets])
end
}
+
+ if Feature.disabled?(:merge_service_ping_instrumented_metrics, default_enabled: :yaml)
+ counts[:counts][:boards] = add_metric('CountBoardsMetric', time_frame: 'all')
+ end
+
+ counts
end
# rubocop: enable Metrics/AbcSize
@@ -219,7 +224,8 @@ module Gitlab
collected_data_categories: add_metric('CollectedDataCategoriesMetric', time_frame: 'none'),
service_ping_features_enabled: add_metric('ServicePingFeaturesMetric', time_frame: 'none'),
snowplow_enabled: add_metric('SnowplowEnabledMetric', time_frame: 'none'),
- snowplow_configured_to_gitlab_collector: add_metric('SnowplowConfiguredToGitlabCollectorMetric', time_frame: 'none')
+ snowplow_configured_to_gitlab_collector: add_metric('SnowplowConfiguredToGitlabCollectorMetric', time_frame: 'none'),
+ certificate_based_clusters_ff: add_metric('CertBasedClustersFfMetric')
}
}
end
diff --git a/lib/gitlab/usage_data_counters.rb b/lib/gitlab/usage_data_counters.rb
index cecc24a38d5..cdcad8fdc7b 100644
--- a/lib/gitlab/usage_data_counters.rb
+++ b/lib/gitlab/usage_data_counters.rb
@@ -16,7 +16,8 @@ module Gitlab
DesignsCounter,
KubernetesAgentCounter,
StaticSiteEditorCounter,
- DiffsCounter
+ DiffsCounter,
+ ServiceUsageDataCounter
].freeze
UsageDataCounterError = Class.new(StandardError)
diff --git a/lib/gitlab/usage_data_counters/hll_redis_counter.rb b/lib/gitlab/usage_data_counters/hll_redis_counter.rb
index c6e9db6a314..474ab9a4dd9 100644
--- a/lib/gitlab/usage_data_counters/hll_redis_counter.rb
+++ b/lib/gitlab/usage_data_counters/hll_redis_counter.rb
@@ -26,6 +26,7 @@ module Gitlab
ecosystem
epic_boards_usage
epics_usage
+ error_tracking
ide_edit
incident_management
issues_edit
diff --git a/lib/gitlab/usage_data_counters/known_events/ci_users.yml b/lib/gitlab/usage_data_counters/known_events/ci_users.yml
new file mode 100644
index 00000000000..63498a35858
--- /dev/null
+++ b/lib/gitlab/usage_data_counters/known_events/ci_users.yml
@@ -0,0 +1,5 @@
+- name: ci_users_executing_deployment_job
+ category: ci_users
+ redis_slot: ci_users
+ aggregation: weekly
+ feature_flag: job_deployment_count
diff --git a/lib/gitlab/usage_data_counters/known_events/common.yml b/lib/gitlab/usage_data_counters/known_events/common.yml
index 96755db8439..fdf4bc58525 100644
--- a/lib/gitlab/usage_data_counters/known_events/common.yml
+++ b/lib/gitlab/usage_data_counters/known_events/common.yml
@@ -324,7 +324,6 @@
category: snippets
redis_slot: snippets
aggregation: weekly
- feature_flag: usage_data_i_snippets_show
# Terraform
- name: p_terraform_state_api_unique_users
category: terraform
diff --git a/lib/gitlab/usage_data_counters/known_events/error_tracking.yml b/lib/gitlab/usage_data_counters/known_events/error_tracking.yml
new file mode 100644
index 00000000000..a56e0a6d370
--- /dev/null
+++ b/lib/gitlab/usage_data_counters/known_events/error_tracking.yml
@@ -0,0 +1,11 @@
+---
+- name: error_tracking_view_details
+ category: error_tracking
+ redis_slot: error_tracking
+ aggregation: weekly
+ feature_flag: track_error_tracking_activity
+- name: error_tracking_view_list
+ category: error_tracking
+ redis_slot: error_tracking
+ aggregation: weekly
+ feature_flag: track_error_tracking_activity
diff --git a/lib/gitlab/usage_data_counters/known_events/quickactions.yml b/lib/gitlab/usage_data_counters/known_events/quickactions.yml
index 49891080b03..4ba7ea2d407 100644
--- a/lib/gitlab/usage_data_counters/known_events/quickactions.yml
+++ b/lib/gitlab/usage_data_counters/known_events/quickactions.yml
@@ -127,6 +127,10 @@
category: quickactions
redis_slot: quickactions
aggregation: weekly
+- name: i_quickactions_page
+ category: quickactions
+ redis_slot: quickactions
+ aggregation: weekly
- name: i_quickactions_publish
category: quickactions
redis_slot: quickactions
diff --git a/lib/gitlab/usage_data_counters/known_events/work_items.yml b/lib/gitlab/usage_data_counters/known_events/work_items.yml
new file mode 100644
index 00000000000..0c9c6026c46
--- /dev/null
+++ b/lib/gitlab/usage_data_counters/known_events/work_items.yml
@@ -0,0 +1,11 @@
+---
+- name: users_updating_work_item_title
+ category: work_items
+ redis_slot: users
+ aggregation: weekly
+ feature_flag: track_work_items_activity
+- name: users_creating_work_items
+ category: work_items
+ redis_slot: users
+ aggregation: weekly
+ feature_flag: track_work_items_activity
diff --git a/lib/gitlab/usage_data_counters/service_usage_data_counter.rb b/lib/gitlab/usage_data_counters/service_usage_data_counter.rb
new file mode 100644
index 00000000000..aa1d9583ea5
--- /dev/null
+++ b/lib/gitlab/usage_data_counters/service_usage_data_counter.rb
@@ -0,0 +1,8 @@
+# frozen_string_literal: true
+
+module Gitlab::UsageDataCounters
+ class ServiceUsageDataCounter < BaseCounter
+ KNOWN_EVENTS = %w[download_payload_click].freeze
+ PREFIX = 'service_usage_data'
+ end
+end
diff --git a/lib/gitlab/usage_data_counters/work_item_activity_unique_counter.rb b/lib/gitlab/usage_data_counters/work_item_activity_unique_counter.rb
new file mode 100644
index 00000000000..6f5300405c7
--- /dev/null
+++ b/lib/gitlab/usage_data_counters/work_item_activity_unique_counter.rb
@@ -0,0 +1,28 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module UsageDataCounters
+ module WorkItemActivityUniqueCounter
+ WORK_ITEM_CREATED = 'users_creating_work_items'
+ WORK_ITEM_TITLE_CHANGED = 'users_updating_work_item_title'
+
+ class << self
+ def track_work_item_created_action(author:)
+ track_unique_action(WORK_ITEM_CREATED, author)
+ end
+
+ def track_work_item_title_changed_action(author:)
+ track_unique_action(WORK_ITEM_TITLE_CHANGED, author)
+ end
+
+ private
+
+ def track_unique_action(action, author)
+ return unless author
+
+ Gitlab::UsageDataCounters::HLLRedisCounter.track_event(action, values: author.id)
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/usage_data_queries.rb b/lib/gitlab/usage_data_queries.rb
index c6490ba7374..d40ac71afc6 100644
--- a/lib/gitlab/usage_data_queries.rb
+++ b/lib/gitlab/usage_data_queries.rb
@@ -41,9 +41,19 @@ module Gitlab
end
def maximum_id(model, column = nil)
+ # no-op: shadowing super for performance reasons
end
def minimum_id(model, column = nil)
+ # no-op: shadowing super for performance reasons
+ end
+
+ def alt_usage_data(value = nil, fallback: FALLBACK, &block)
+ if block_given?
+ { alt_usage_data_block: block.to_s }
+ else
+ { alt_usage_data_value: value }
+ end
end
def redis_usage_data(counter = nil, &block)
diff --git a/lib/gitlab/utils.rb b/lib/gitlab/utils.rb
index 608545baf74..816ede4136a 100644
--- a/lib/gitlab/utils.rb
+++ b/lib/gitlab/utils.rb
@@ -5,6 +5,10 @@ module Gitlab
extend self
PathTraversalAttackError ||= Class.new(StandardError)
+ private_class_method def logger
+ @logger ||= Gitlab::AppLogger
+ end
+
# 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.
# Also see https://gitlab.com/gitlab-org/gitlab/-/merge_requests/24223#note_284122580
@@ -16,6 +20,7 @@ module Gitlab
path_regex = %r{(\A(\.{1,2})\z|\A\.\.[/\\]|[/\\]\.\.\z|[/\\]\.\.[/\\]|\n)}
if path.match?(path_regex)
+ logger.warn(message: "Potential path traversal attempt detected", path: "#{path}")
raise PathTraversalAttackError, 'Invalid path'
end
@@ -37,6 +42,13 @@ module Gitlab
raise StandardError, "path #{path} is not allowed"
end
+ def check_allowed_absolute_path_and_path_traversal!(path, path_allowlist)
+ traversal_path = check_path_traversal!(path)
+ raise StandardError, "path is not a string!" unless traversal_path.is_a?(String)
+
+ check_allowed_absolute_path!(traversal_path, path_allowlist)
+ end
+
def decode_path(encoded_path)
decoded = CGI.unescape(encoded_path)
if decoded != CGI.unescape(decoded)
diff --git a/lib/gitlab/utils/strong_memoize.rb b/lib/gitlab/utils/strong_memoize.rb
index 255fa0169bf..3c954f817a7 100644
--- a/lib/gitlab/utils/strong_memoize.rb
+++ b/lib/gitlab/utils/strong_memoize.rb
@@ -22,10 +22,12 @@ module Gitlab
# end
#
def strong_memoize(name)
- if strong_memoized?(name)
- instance_variable_get(ivar(name))
+ key = ivar(name)
+
+ if instance_variable_defined?(key)
+ instance_variable_get(key)
else
- instance_variable_set(ivar(name), yield)
+ instance_variable_set(key, yield)
end
end
@@ -34,13 +36,23 @@ module Gitlab
end
def clear_memoization(name)
- remove_instance_variable(ivar(name)) if instance_variable_defined?(ivar(name))
+ key = ivar(name)
+ remove_instance_variable(key) if instance_variable_defined?(key)
end
private
+ # Convert `"name"`/`:name` into `:@name`
+ #
+ # Depending on a type ensure that there's a single memory allocation
def ivar(name)
- "@#{name}"
+ if name.is_a?(Symbol)
+ name.to_s.prepend("@").to_sym
+ elsif name.is_a?(String)
+ :"@#{name}"
+ else
+ raise ArgumentError, "Invalid type of '#{name}'"
+ end
end
end
end
diff --git a/lib/gitlab/wiki_pages/front_matter_parser.rb b/lib/gitlab/wiki_pages/front_matter_parser.rb
index 0ceec39782c..ee30fa907f4 100644
--- a/lib/gitlab/wiki_pages/front_matter_parser.rb
+++ b/lib/gitlab/wiki_pages/front_matter_parser.rb
@@ -3,8 +3,6 @@
module Gitlab
module WikiPages
class FrontMatterParser
- FEATURE_FLAG = :wiki_front_matter
-
# We limit the maximum length of text we are prepared to parse as YAML, to
# avoid exploitations and attempts to consume memory and CPU. We allow for:
# - a title line
@@ -30,18 +28,12 @@ module Gitlab
end
# @param [String] wiki_content
- # @param [FeatureGate] feature_gate The scope for feature availability
- def initialize(wiki_content, feature_gate)
+ def initialize(wiki_content)
@wiki_content = wiki_content
- @feature_gate = feature_gate
- end
-
- def self.enabled?(gate = nil)
- Feature.enabled?(FEATURE_FLAG, gate)
end
def parse
- return empty_result unless enabled? && wiki_content.present?
+ return empty_result unless wiki_content.present?
return empty_result(block.error) unless block.valid?
Result.new(front_matter: block.data, content: strip_front_matter_block)
@@ -94,22 +86,18 @@ module Gitlab
private
- attr_reader :wiki_content, :feature_gate
+ attr_reader :wiki_content
def empty_result(reason = nil, error = nil)
Result.new(content: wiki_content, reason: reason, error: error)
end
- def enabled?
- self.class.enabled?(feature_gate)
- end
-
def block
@block ||= parse_front_matter_block
end
def parse_front_matter_block
- wiki_content.match(Gitlab::FrontMatter::PATTERN) { |m| Block.new(*m.captures) } || Block.new
+ wiki_content.match(Gitlab::FrontMatter::PATTERN) { |m| Block.new(m[:delim], m[:lang], m[:front_matter]) } || Block.new
end
def strip_front_matter_block
diff --git a/lib/google_api/cloud_platform/client.rb b/lib/google_api/cloud_platform/client.rb
index 43a2480d5b7..360c9a6c52f 100644
--- a/lib/google_api/cloud_platform/client.rb
+++ b/lib/google_api/cloud_platform/client.rb
@@ -22,6 +22,7 @@ module GoogleApi
"https://www.googleapis.com/auth/monitoring"
].freeze
ROLES_LIST = %w[roles/iam.serviceAccountUser roles/artifactregistry.admin roles/cloudbuild.builds.builder roles/run.admin roles/storage.admin roles/cloudsql.admin roles/browser].freeze
+ REVOKE_URL = 'https://oauth2.googleapis.com/revoke'
class << self
def session_key_for_token
@@ -146,6 +147,11 @@ module GoogleApi
enable_service(gcp_project_id, 'cloudbuild.googleapis.com')
end
+ def revoke_authorizations
+ uri = URI(REVOKE_URL)
+ Gitlab::HTTP.post(uri, body: { 'token' => access_token })
+ end
+
private
def enable_service(gcp_project_id, service_name)
@@ -211,7 +217,7 @@ module GoogleApi
end
def cloud_resource_manager_service
- @gpc_service ||= Google::Apis::CloudresourcemanagerV1::CloudResourceManagerService.new.tap { |s| s. authorization = access_token }
+ @gpc_service ||= Google::Apis::CloudresourcemanagerV1::CloudResourceManagerService.new.tap { |s| s.authorization = access_token }
end
end
end
diff --git a/lib/learn_gitlab/onboarding.rb b/lib/learn_gitlab/onboarding.rb
index 38ffa9eb2e6..42415aacbee 100644
--- a/lib/learn_gitlab/onboarding.rb
+++ b/lib/learn_gitlab/onboarding.rb
@@ -5,19 +5,19 @@ module LearnGitlab
include Gitlab::Utils::StrongMemoize
ACTION_ISSUE_IDS = {
- issue_created: 4,
- git_write: 6,
pipeline_created: 7,
- merge_request_created: 9,
- user_added: 8,
trial_started: 2,
required_mr_approvals_enabled: 11,
code_owners_enabled: 10
}.freeze
- ACTION_DOC_URLS = {
- security_scan_enabled: 'https://docs.gitlab.com/ee/user/application_security/security_dashboard/#gitlab-security-dashboard-security-center-and-vulnerability-reports'
- }.freeze
+ ACTION_PATHS = [
+ :issue_created,
+ :git_write,
+ :merge_request_created,
+ :user_added,
+ :security_scan_enabled
+ ].freeze
def initialize(namespace)
@namespace = namespace
@@ -49,7 +49,7 @@ module LearnGitlab
end
def tracked_actions
- ACTION_ISSUE_IDS.keys + ACTION_DOC_URLS.keys
+ ACTION_ISSUE_IDS.keys + ACTION_PATHS
end
attr_reader :namespace
diff --git a/lib/peek/views/active_record.rb b/lib/peek/views/active_record.rb
index 6a41de8f0b0..75346626255 100644
--- a/lib/peek/views/active_record.rb
+++ b/lib/peek/views/active_record.rb
@@ -75,14 +75,6 @@ module Peek
"Role: #{role.to_s.capitalize}"
end
-
- def format_call_details(call)
- if ENV['GITLAB_MULTIPLE_DATABASE_METRICS']
- super
- else
- super.except(:db_config_name)
- end
- end
end
end
end
diff --git a/lib/peek/views/detailed_view.rb b/lib/peek/views/detailed_view.rb
index 4cc2e85c7bb..1301c6aa6fd 100644
--- a/lib/peek/views/detailed_view.rb
+++ b/lib/peek/views/detailed_view.rb
@@ -23,7 +23,7 @@ module Peek
private
def duration
- detail_store.map { |entry| entry[:duration] }.sum * 1000
+ detail_store.sum { |entry| entry[:duration] } * 1000
end
def calls
diff --git a/lib/security/ci_configuration/base_build_action.rb b/lib/security/ci_configuration/base_build_action.rb
index 6012067fb53..8f0765a35c2 100644
--- a/lib/security/ci_configuration/base_build_action.rb
+++ b/lib/security/ci_configuration/base_build_action.rb
@@ -3,9 +3,10 @@
module Security
module CiConfiguration
class BaseBuildAction
- def initialize(auto_devops_enabled, existing_gitlab_ci_content)
+ def initialize(auto_devops_enabled, existing_gitlab_ci_content, ci_config_path = ::Ci::Pipeline::DEFAULT_CONFIG_PATH)
@auto_devops_enabled = auto_devops_enabled
@existing_gitlab_ci_content = existing_gitlab_ci_content || {}
+ @ci_config_path = ci_config_path.presence || ::Ci::Pipeline::DEFAULT_CONFIG_PATH
end
def generate
@@ -13,7 +14,7 @@ module Security
update_existing_content!
- { action: action, file_path: '.gitlab-ci.yml', content: prepare_existing_content, default_values_overwritten: @default_values_overwritten }
+ { action: action, file_path: @ci_config_path, content: prepare_existing_content, default_values_overwritten: @default_values_overwritten }
end
private
diff --git a/lib/security/ci_configuration/sast_build_action.rb b/lib/security/ci_configuration/sast_build_action.rb
index 3fa5e9c7177..63f16a1bebe 100644
--- a/lib/security/ci_configuration/sast_build_action.rb
+++ b/lib/security/ci_configuration/sast_build_action.rb
@@ -3,8 +3,8 @@
module Security
module CiConfiguration
class SastBuildAction < BaseBuildAction
- def initialize(auto_devops_enabled, params, existing_gitlab_ci_content)
- super(auto_devops_enabled, existing_gitlab_ci_content)
+ def initialize(auto_devops_enabled, params, existing_gitlab_ci_content, ci_config_path = ::Ci::Pipeline::DEFAULT_CONFIG_PATH)
+ super(auto_devops_enabled, existing_gitlab_ci_content, ci_config_path)
@variables = variables(params)
@default_sast_values = default_sast_values(params)
@default_values_overwritten = false
diff --git a/lib/serializers/unsafe_json.rb b/lib/serializers/unsafe_json.rb
new file mode 100644
index 00000000000..25ec52e4581
--- /dev/null
+++ b/lib/serializers/unsafe_json.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+module Serializers
+ class UnsafeJson
+ class << self
+ def dump(obj)
+ obj.to_json(unsafe: true)
+ end
+
+ delegate :load, to: :JSON
+ end
+ end
+end
diff --git a/lib/sidebars/concerns/work_item_hierarchy.rb b/lib/sidebars/concerns/work_item_hierarchy.rb
deleted file mode 100644
index a4153bb5120..00000000000
--- a/lib/sidebars/concerns/work_item_hierarchy.rb
+++ /dev/null
@@ -1,26 +0,0 @@
-# frozen_string_literal: true
-
-# This module has the necessary methods to render
-# work items hierarchy menu
-module Sidebars
- module Concerns
- module WorkItemHierarchy
- def hierarchy_menu_item(container, url, path)
- unless show_hierarachy_menu_item?(container)
- return ::Sidebars::NilMenuItem.new(item_id: :hierarchy)
- end
-
- ::Sidebars::MenuItem.new(
- title: _('Planning hierarchy'),
- link: url,
- active_routes: { path: path },
- item_id: :hierarchy
- )
- end
-
- def show_hierarachy_menu_item?(container)
- can?(context.current_user, :read_planning_hierarchy, container)
- end
- end
- end
-end
diff --git a/lib/sidebars/groups/menus/ci_cd_menu.rb b/lib/sidebars/groups/menus/ci_cd_menu.rb
index a1f98b918e6..c1d80458f49 100644
--- a/lib/sidebars/groups/menus/ci_cd_menu.rb
+++ b/lib/sidebars/groups/menus/ci_cd_menu.rb
@@ -29,7 +29,7 @@ module Sidebars
::Sidebars::MenuItem.new(
title: _('Runners'),
link: group_runners_path(context.group),
- active_routes: { path: 'groups/runners#index' },
+ active_routes: { controller: 'groups/runners' },
item_id: :runners
)
end
diff --git a/lib/sidebars/groups/menus/customer_relations_menu.rb b/lib/sidebars/groups/menus/customer_relations_menu.rb
index 002197965d1..0aaa6ec45f1 100644
--- a/lib/sidebars/groups/menus/customer_relations_menu.rb
+++ b/lib/sidebars/groups/menus/customer_relations_menu.rb
@@ -24,6 +24,8 @@ module Sidebars
override :render?
def render?
+ return false unless context.group.root?
+
can_read_contact? || can_read_organization?
end
diff --git a/lib/sidebars/groups/menus/kubernetes_menu.rb b/lib/sidebars/groups/menus/kubernetes_menu.rb
index 4ea294a4837..98ca7865995 100644
--- a/lib/sidebars/groups/menus/kubernetes_menu.rb
+++ b/lib/sidebars/groups/menus/kubernetes_menu.rb
@@ -21,7 +21,10 @@ module Sidebars
override :render?
def render?
- can?(context.current_user, :read_cluster, context.group)
+ clusterable = context.group
+
+ Feature.enabled?(:certificate_based_clusters, clusterable, default_enabled: :yaml, type: :ops) &&
+ can?(context.current_user, :read_cluster, clusterable)
end
override :extra_container_html_options
diff --git a/lib/sidebars/groups/menus/packages_registries_menu.rb b/lib/sidebars/groups/menus/packages_registries_menu.rb
index 60d91c8fd10..4c21845ef18 100644
--- a/lib/sidebars/groups/menus/packages_registries_menu.rb
+++ b/lib/sidebars/groups/menus/packages_registries_menu.rb
@@ -8,8 +8,8 @@ module Sidebars
def configure_menu_items
add_item(packages_registry_menu_item)
add_item(container_registry_menu_item)
+ add_item(harbor_registry__menu_item)
add_item(dependency_proxy_menu_item)
-
true
end
@@ -49,6 +49,17 @@ module Sidebars
)
end
+ def harbor_registry__menu_item
+ return nil_menu_item(:harbor_registry) if Feature.disabled?(:harbor_registry_integration)
+
+ ::Sidebars::MenuItem.new(
+ title: _('Harbor Registry'),
+ link: group_harbor_registries_path(context.group),
+ active_routes: { controller: 'groups/harbor/repositories' },
+ item_id: :harbor_registry
+ )
+ end
+
def dependency_proxy_menu_item
setting_does_not_exist_or_is_enabled = !context.group.dependency_proxy_setting ||
context.group.dependency_proxy_setting.enabled
diff --git a/lib/sidebars/groups/menus/settings_menu.rb b/lib/sidebars/groups/menus/settings_menu.rb
index 810b467ed2d..09226256476 100644
--- a/lib/sidebars/groups/menus/settings_menu.rb
+++ b/lib/sidebars/groups/menus/settings_menu.rb
@@ -89,10 +89,16 @@ module Sidebars
end
def ci_cd_menu_item
+ active_routes_path = if Feature.enabled?(:runner_list_group_view_vue_ui, context.group, default_enabled: :yaml)
+ 'ci_cd#show'
+ else
+ %w[ci_cd#show groups/runners#show groups/runners#edit]
+ end
+
::Sidebars::MenuItem.new(
title: _('CI/CD'),
link: group_settings_ci_cd_path(context.group),
- active_routes: { path: %w[ci_cd#show groups/runners#show groups/runners#edit] },
+ active_routes: { path: active_routes_path },
item_id: :ci_cd
)
end
diff --git a/lib/sidebars/menu.rb b/lib/sidebars/menu.rb
index 1af3d024291..d9d294ff982 100644
--- a/lib/sidebars/menu.rb
+++ b/lib/sidebars/menu.rb
@@ -15,6 +15,7 @@ module Sidebars
include ::Sidebars::Concerns::HasPartial
attr_reader :context
+
delegate :current_user, :container, to: :@context
def initialize(context)
diff --git a/lib/sidebars/projects/menus/infrastructure_menu.rb b/lib/sidebars/projects/menus/infrastructure_menu.rb
index 060a5be5f57..c012b3bb627 100644
--- a/lib/sidebars/projects/menus/infrastructure_menu.rb
+++ b/lib/sidebars/projects/menus/infrastructure_menu.rb
@@ -64,7 +64,7 @@ module Sidebars
end
def serverless_menu_item
- unless can?(context.current_user, :read_cluster, context.project)
+ unless Feature.enabled?(:deprecated_serverless, context.project, default_enabled: :yaml, type: :ops) && can?(context.current_user, :read_cluster, context.project)
return ::Sidebars::NilMenuItem.new(item_id: :serverless)
end
@@ -100,7 +100,7 @@ module Sidebars
::Sidebars::MenuItem.new(
title: _('Google Cloud'),
link: project_google_cloud_index_path(context.project),
- active_routes: { controller: [:google_cloud, :service_accounts, :deployments] },
+ active_routes: { controller: [:google_cloud, :service_accounts, :deployments, :gcp_regions] },
item_id: :google_cloud
)
end
diff --git a/lib/sidebars/projects/menus/packages_registries_menu.rb b/lib/sidebars/projects/menus/packages_registries_menu.rb
index f5f0da2992e..77f09986b19 100644
--- a/lib/sidebars/projects/menus/packages_registries_menu.rb
+++ b/lib/sidebars/projects/menus/packages_registries_menu.rb
@@ -9,7 +9,7 @@ module Sidebars
add_item(packages_registry_menu_item)
add_item(container_registry_menu_item)
add_item(infrastructure_registry_menu_item)
-
+ add_item(harbor_registry__menu_item)
true
end
@@ -65,6 +65,17 @@ module Sidebars
)
end
+ def harbor_registry__menu_item
+ return ::Sidebars::NilMenuItem.new(item_id: :harbor_registry) if Feature.disabled?(:harbor_registry_integration)
+
+ ::Sidebars::MenuItem.new(
+ title: _('Harbor Registry'),
+ link: project_harbor_registry_index_path(context.project),
+ active_routes: { controller: :harbor_registry },
+ item_id: :harbor_registry
+ )
+ end
+
def packages_registry_disabled?
!::Gitlab.config.packages.enabled || !can?(context.current_user, :read_package, context.project)
end
diff --git a/lib/sidebars/projects/menus/project_information_menu.rb b/lib/sidebars/projects/menus/project_information_menu.rb
index 4056d50d324..44b94ee3522 100644
--- a/lib/sidebars/projects/menus/project_information_menu.rb
+++ b/lib/sidebars/projects/menus/project_information_menu.rb
@@ -4,13 +4,10 @@ module Sidebars
module Projects
module Menus
class ProjectInformationMenu < ::Sidebars::Menu
- include ::Sidebars::Concerns::WorkItemHierarchy
-
override :configure_menu_items
def configure_menu_items
add_item(activity_menu_item)
add_item(labels_menu_item)
- add_item(hierarchy_menu_item(context.project, project_planning_hierarchy_path(context.project), 'projects#planning_hierarchy'))
add_item(members_menu_item)
true
diff --git a/lib/spam/concerns/has_spam_action_response_fields.rb b/lib/spam/concerns/has_spam_action_response_fields.rb
index 6688ae56cb0..b33c922f7e6 100644
--- a/lib/spam/concerns/has_spam_action_response_fields.rb
+++ b/lib/spam/concerns/has_spam_action_response_fields.rb
@@ -7,7 +7,7 @@ module Spam
module HasSpamActionResponseFields
extend ActiveSupport::Concern
- # spam_action_response_fields(spammable) -> hash
+ # spam_action_response_fields(spammable) -> hash
#
# Takes a Spammable as an argument and returns response fields necessary to display a CAPTCHA on
# the client.
diff --git a/lib/tasks/ci/build_artifacts.rake b/lib/tasks/ci/build_artifacts.rake
new file mode 100644
index 00000000000..4f4faef5a62
--- /dev/null
+++ b/lib/tasks/ci/build_artifacts.rake
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+require 'httparty'
+require 'csv'
+
+namespace :ci do
+ namespace :build_artifacts do
+ desc "GitLab | CI | Fetch projects with incorrect artifact size on GitLab.com"
+ task :project_with_incorrect_artifact_size do
+ csv_url = ENV['SISENSE_PROJECT_IDS_WITH_INCORRECT_ARTIFACTS_URL']
+
+ # rubocop: disable Gitlab/HTTParty
+ body = HTTParty.get(csv_url)
+ # rubocop: enable Gitlab/HTTParty
+
+ table = CSV.parse(body.parsed_response, headers: true)
+ puts table['PROJECT_ID'].join(' ')
+ end
+ end
+end
diff --git a/lib/tasks/dev.rake b/lib/tasks/dev.rake
index cb01f229cd3..99ffeb4ec0b 100644
--- a/lib/tasks/dev.rake
+++ b/lib/tasks/dev.rake
@@ -8,8 +8,10 @@ namespace :dev do
ENV['force'] = 'yes'
Rake::Task["gitlab:setup"].invoke
- # Make sure DB statistics are up to date.
- ActiveRecord::Base.connection.execute('ANALYZE')
+ Gitlab::Database::EachDatabase.each_database_connection do |connection|
+ # Make sure DB statistics are up to date.
+ connection.execute('ANALYZE')
+ end
Rake::Task["gitlab:shell:setup"].invoke
end
diff --git a/lib/tasks/gitlab/background_migrations.rake b/lib/tasks/gitlab/background_migrations.rake
index c7f3d003f9f..033427fa799 100644
--- a/lib/tasks/gitlab/background_migrations.rake
+++ b/lib/tasks/gitlab/background_migrations.rake
@@ -1,41 +1,110 @@
# frozen_string_literal: true
+databases = ActiveRecord::Tasks::DatabaseTasks.setup_initial_database_yaml
+
namespace :gitlab do
namespace :background_migrations do
desc 'Synchronously finish executing a batched background migration'
task :finalize, [:job_class_name, :table_name, :column_name, :job_arguments] => :environment do |_, args|
- [:job_class_name, :table_name, :column_name, :job_arguments].each do |argument|
- unless args[argument]
- puts "Must specify #{argument} as an argument".color(:red)
- exit 1
- end
+ if Gitlab::Database.db_config_names.size > 1
+ puts "Please specify the database".color(:red)
+ exit 1
end
- Gitlab::Database::BackgroundMigration::BatchedMigrationRunner.finalize(
+ validate_finalization_arguments!(args)
+
+ main_model = Gitlab::Database.database_base_models[:main]
+
+ finalize_migration(
args[:job_class_name],
args[:table_name],
args[:column_name],
- Gitlab::Json.parse(args[:job_arguments])
+ Gitlab::Json.parse(args[:job_arguments]),
+ connection: main_model.connection
)
+ end
- puts "Done.".color(:green)
+ namespace :finalize do
+ ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name|
+ next if name.to_s == 'geo'
+
+ desc "Gitlab | DB | Synchronously finish executing a batched background migration on #{name} database"
+ task name, [:job_class_name, :table_name, :column_name, :job_arguments] => :environment do |_, args|
+ validate_finalization_arguments!(args)
+
+ model = Gitlab::Database.database_base_models[name]
+
+ finalize_migration(
+ args[:job_class_name],
+ args[:table_name],
+ args[:column_name],
+ Gitlab::Json.parse(args[:job_arguments]),
+ connection: model.connection
+ )
+ end
+ end
end
desc 'Display the status of batched background migrations'
- task status: :environment do
- statuses = Gitlab::Database::BackgroundMigration::BatchedMigration.statuses
- max_status_length = statuses.keys.map(&:length).max
- format_string = "%-#{max_status_length}s | %s\n"
-
- Gitlab::Database::BackgroundMigration::BatchedMigration.find_each(batch_size: 100) do |migration|
- identification_fields = [
- migration.job_class_name,
- migration.table_name,
- migration.column_name,
- migration.job_arguments.to_json
- ].join(',')
-
- printf(format_string, migration.status, identification_fields)
+ task status: :environment do |_, args|
+ Gitlab::Database.database_base_models.each do |name, model|
+ display_migration_status(name, model.connection)
+ end
+ end
+
+ namespace :status do
+ ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name|
+ next if name.to_s == 'geo'
+
+ desc "Gitlab | DB | Display the status of batched background migrations on #{name} database"
+ task name => :environment do |_, args|
+ model = Gitlab::Database.database_base_models[name]
+ display_migration_status(name, model.connection)
+ end
+ end
+ end
+
+ private
+
+ def finalize_migration(class_name, table_name, column_name, job_arguments, connection:)
+ Gitlab::Database::BackgroundMigration::BatchedMigrationRunner.finalize(
+ class_name,
+ table_name,
+ column_name,
+ Gitlab::Json.parse(job_arguments),
+ connection: connection
+ )
+
+ puts "Done.".color(:green)
+ end
+
+ def display_migration_status(database_name, connection)
+ Gitlab::Database::SharedModel.using_connection(connection) do
+ statuses = Gitlab::Database::BackgroundMigration::BatchedMigration.statuses
+ max_status_length = statuses.keys.map(&:length).max
+ format_string = "%-#{max_status_length}s | %s\n"
+
+ puts "Database: #{database_name}\n"
+
+ Gitlab::Database::BackgroundMigration::BatchedMigration.find_each(batch_size: 100) do |migration|
+ identification_fields = [
+ migration.job_class_name,
+ migration.table_name,
+ migration.column_name,
+ migration.job_arguments.to_json
+ ].join(',')
+
+ printf(format_string, migration.status, identification_fields)
+ end
+ end
+ end
+
+ def validate_finalization_arguments!(args)
+ [:job_class_name, :table_name, :column_name, :job_arguments].each do |argument|
+ unless args[argument]
+ puts "Must specify #{argument} as an argument".color(:red)
+ exit 1
+ end
end
end
end
diff --git a/lib/tasks/gitlab/db.rake b/lib/tasks/gitlab/db.rake
index 6d4af9d166f..50ceb11581e 100644
--- a/lib/tasks/gitlab/db.rake
+++ b/lib/tasks/gitlab/db.rake
@@ -4,30 +4,28 @@ databases = ActiveRecord::Tasks::DatabaseTasks.setup_initial_database_yaml
namespace :gitlab do
namespace :db do
- desc 'GitLab | DB | Manually insert schema migration version'
+ desc 'GitLab | DB | Manually insert schema migration version on all configured databases'
task :mark_migration_complete, [:version] => :environment do |_, args|
mark_migration_complete(args[:version])
end
namespace :mark_migration_complete do
- ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name|
- desc "Gitlab | DB | Manually insert schema migration version on #{name} database"
- task name, [:version] => :environment do |_, args|
- mark_migration_complete(args[:version], database: name)
+ ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |database|
+ desc "Gitlab | DB | Manually insert schema migration version on #{database} database"
+ task database, [:version] => :environment do |_, args|
+ mark_migration_complete(args[:version], only_on: database)
end
end
end
- def mark_migration_complete(version, database: nil)
+ def mark_migration_complete(version, only_on: nil)
if version.to_i == 0
puts 'Must give a version argument that is a non-zero integer'.color(:red)
exit 1
end
- Gitlab::Database.database_base_models.each do |name, model|
- next if database && database.to_s != name
-
- model.connection.execute("INSERT INTO schema_migrations (version) VALUES (#{model.connection.quote(version)})")
+ Gitlab::Database::EachDatabase.each_database_connection(only: only_on) do |connection, name|
+ connection.execute("INSERT INTO schema_migrations (version) VALUES (#{connection.quote(version)})")
puts "Successfully marked '#{version}' as complete on database #{name}".color(:green)
rescue ActiveRecord::RecordNotUnique
@@ -35,32 +33,44 @@ namespace :gitlab do
end
end
- desc 'GitLab | DB | Drop all tables'
+ desc 'GitLab | DB | Drop all tables on all configured databases'
task drop_tables: :environment do
- connection = ActiveRecord::Base.connection
+ drop_tables
+ end
- # In PostgreSQLAdapter, data_sources returns both views and tables, so use
- # #tables instead
- tables = connection.tables
+ namespace :drop_tables do
+ ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |database|
+ desc "GitLab | DB | Drop all tables on the #{database} database"
+ task database => :environment do
+ drop_tables(only_on: database)
+ end
+ end
+ end
- # Removes the entry from the array
- tables.delete 'schema_migrations'
- # Truncate schema_migrations to ensure migrations re-run
- connection.execute('TRUNCATE schema_migrations') if connection.table_exists? 'schema_migrations'
+ def drop_tables(only_on: nil)
+ Gitlab::Database::EachDatabase.each_database_connection(only: only_on) do |connection, name|
+ # In PostgreSQLAdapter, data_sources returns both views and tables, so use tables instead
+ tables = connection.tables
- # Drop any views
- connection.views.each do |view|
- connection.execute("DROP VIEW IF EXISTS #{connection.quote_table_name(view)} CASCADE")
- end
+ # Removes the entry from the array
+ tables.delete 'schema_migrations'
+ # Truncate schema_migrations to ensure migrations re-run
+ connection.execute('TRUNCATE schema_migrations') if connection.table_exists? 'schema_migrations'
- # Drop tables with cascade to avoid dependent table errors
- # PG: http://www.postgresql.org/docs/current/static/ddl-depend.html
- # Add `IF EXISTS` because cascade could have already deleted a table.
- tables.each { |t| connection.execute("DROP TABLE IF EXISTS #{connection.quote_table_name(t)} CASCADE") }
+ # Drop any views
+ connection.views.each do |view|
+ connection.execute("DROP VIEW IF EXISTS #{connection.quote_table_name(view)} CASCADE")
+ end
- # Drop all extra schema objects GitLab owns
- Gitlab::Database::EXTRA_SCHEMAS.each do |schema|
- connection.execute("DROP SCHEMA IF EXISTS #{connection.quote_table_name(schema)} CASCADE")
+ # Drop tables with cascade to avoid dependent table errors
+ # PG: http://www.postgresql.org/docs/current/static/ddl-depend.html
+ # Add `IF EXISTS` because cascade could have already deleted a table.
+ tables.each { |t| connection.execute("DROP TABLE IF EXISTS #{connection.quote_table_name(t)} CASCADE") }
+
+ # Drop all extra schema objects GitLab owns
+ Gitlab::Database::EXTRA_SCHEMAS.each do |schema|
+ connection.execute("DROP SCHEMA IF EXISTS #{connection.quote_table_name(schema)} CASCADE")
+ end
end
end
@@ -152,6 +162,17 @@ namespace :gitlab do
Rake::Task['gitlab:db:create_dynamic_partitions'].invoke
end
+ ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name|
+ # We'll temporarily skip this enhancement for geo, since in some situations we
+ # wish to setup the geo database before the other databases have been setup,
+ # and partition management attempts to connect to the main database.
+ next if name == 'geo'
+
+ Rake::Task["db:migrate:#{name}"].enhance do
+ Rake::Task['gitlab:db:create_dynamic_partitions'].invoke
+ end
+ end
+
# When we load the database schema from db/structure.sql
# we don't have any dynamic partitions created. We don't really need to
# because application initializers/sidekiq take care of that, too.
@@ -160,16 +181,29 @@ namespace :gitlab do
#
# Other than that it's helpful to create partitions early when bootstrapping
# a new installation.
- #
- # Rails 6.1 deprecates db:structure:load in favor of db:schema:load
- Rake::Task['db:structure:load'].enhance do
+ Rake::Task['db:schema:load'].enhance do
Rake::Task['gitlab:db:create_dynamic_partitions'].invoke
end
- Rake::Task['db:schema:load'].enhance do
- Rake::Task['gitlab:db:create_dynamic_partitions'].invoke
+ ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name|
+ # We'll temporarily skip this enhancement for geo, since in some situations we
+ # wish to setup the geo database before the other databases have been setup,
+ # and partition management attempts to connect to the main database.
+ next if name == 'geo'
+
+ Rake::Task["db:schema:load:#{name}"].enhance do
+ Rake::Task['gitlab:db:create_dynamic_partitions'].invoke
+ end
+ end
+
+ desc "Clear all connections"
+ task :clear_all_connections do
+ ActiveRecord::Base.clear_all_connections!
end
+ Rake::Task['db:test:purge'].enhance(['gitlab:db:clear_all_connections'])
+ Rake::Task['db:drop'].enhance(['gitlab:db:clear_all_connections'])
+
# During testing, db:test:load restores the database schema from scratch
# which does not include dynamic partitions. We cannot rely on application
# initializers here as the application can continue to run while
@@ -195,8 +229,6 @@ namespace :gitlab do
end
namespace :reindex do
- databases = ActiveRecord::Tasks::DatabaseTasks.setup_initial_database_yaml
-
ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |database_name|
desc "Reindex #{database_name} database without downtime to eliminate bloat"
task database_name => :environment do
diff --git a/lib/tasks/gitlab/docs/redirect.rake b/lib/tasks/gitlab/docs/redirect.rake
index e7ece9e0fdd..2d234fcdb36 100644
--- a/lib/tasks/gitlab/docs/redirect.rake
+++ b/lib/tasks/gitlab/docs/redirect.rake
@@ -54,7 +54,9 @@ namespace :gitlab do
post.puts "This document was moved to [another location](#{new_path})."
post.puts
post.puts "<!-- This redirect file can be deleted after <#{date}>. -->"
- post.puts "<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/#move-or-rename-a-page -->"
+ post.puts "<!-- Redirects that point to other docs in the same project expire in three months. -->"
+ post.puts "<!-- Redirects that point to docs in a different project or site (link is not relative and starts with `https:`) expire in one year. -->"
+ post.puts "<!-- Before deletion, see: https://docs.gitlab.com/ee/development/documentation/redirects.html -->"
end
end
end
diff --git a/lib/tasks/gitlab/refresh_project_statistics_build_artifacts_size.rake b/lib/tasks/gitlab/refresh_project_statistics_build_artifacts_size.rake
new file mode 100644
index 00000000000..1cc18d14d78
--- /dev/null
+++ b/lib/tasks/gitlab/refresh_project_statistics_build_artifacts_size.rake
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+namespace :gitlab do
+ desc "GitLab | Refresh build artifacts size project statistics for given project IDs"
+
+ BUILD_ARTIFACTS_SIZE_REFRESH_ENQUEUE_BATCH_SIZE = 500
+
+ task :refresh_project_statistics_build_artifacts_size, [:project_ids] => :environment do |_t, args|
+ project_ids = []
+ project_ids = $stdin.read.split unless $stdin.tty?
+ project_ids = args.project_ids.to_s.split unless project_ids.any?
+
+ if project_ids.any?
+ project_ids.in_groups_of(BUILD_ARTIFACTS_SIZE_REFRESH_ENQUEUE_BATCH_SIZE) do |ids|
+ projects = Project.where(id: ids)
+ Projects::BuildArtifactsSizeRefresh.enqueue_refresh(projects)
+ end
+ puts 'Done.'.green
+ else
+ puts 'Please provide a string of space-separated project IDs as the argument or through the STDIN'.red
+ end
+ end
+end
diff --git a/lib/tasks/gitlab/setup.rake b/lib/tasks/gitlab/setup.rake
index 705519d1741..a5289476378 100644
--- a/lib/tasks/gitlab/setup.rake
+++ b/lib/tasks/gitlab/setup.rake
@@ -47,13 +47,15 @@ namespace :gitlab do
# will work.
def self.terminate_all_connections
cmd = <<~SQL
- SELECT pg_terminate_backend(pg_stat_activity.pid)
- FROM pg_stat_activity
- WHERE datname = current_database()
+ SELECT pg_terminate_backend(pg_stat_activity.pid)
+ FROM pg_stat_activity
+ WHERE datname = current_database()
AND pid <> pg_backend_pid();
SQL
- ActiveRecord::Base.connection.execute(cmd)&.result_status == PG::PGRES_TUPLES_OK
- rescue ActiveRecord::NoDatabaseError
+ Gitlab::Database::EachDatabase.each_database_connection do |connection|
+ connection.execute(cmd)
+ rescue ActiveRecord::NoDatabaseError
+ end
end
end
diff --git a/lib/tasks/gitlab/tw/codeowners.rake b/lib/tasks/gitlab/tw/codeowners.rake
index 43fd4f8685a..358bc6c31eb 100644
--- a/lib/tasks/gitlab/tw/codeowners.rake
+++ b/lib/tasks/gitlab/tw/codeowners.rake
@@ -22,7 +22,7 @@ namespace :tw do
CodeOwnerRule.new('Container Security', '@ngaskill'),
CodeOwnerRule.new('Contributor Experience', '@eread'),
CodeOwnerRule.new('Conversion', '@kpaizee'),
- CodeOwnerRule.new('Database', '@marcia'),
+ CodeOwnerRule.new('Database', '@aqualls'),
CodeOwnerRule.new('Development', '@marcia'),
CodeOwnerRule.new('Distribution', '@axil'),
CodeOwnerRule.new('Distribution (Charts)', '@axil'),
diff --git a/lib/tasks/rubocop.rake b/lib/tasks/rubocop.rake
index 8c5edb5de8a..6eabdf51dcd 100644
--- a/lib/tasks/rubocop.rake
+++ b/lib/tasks/rubocop.rake
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+# rubocop:disable Rails/RakeEnvironment
unless Rails.env.production?
require 'rubocop/rake_task'
@@ -8,18 +9,59 @@ unless Rails.env.production?
namespace :rubocop do
namespace :todo do
desc 'Generate RuboCop todos'
- task :generate do # rubocop:disable Rails/RakeEnvironment
+ task :generate do |_task, args|
require 'rubocop'
+ require 'active_support/inflector/inflections'
+ require_relative '../../rubocop/todo_dir'
+ require_relative '../../rubocop/formatter/todo_formatter'
+
+ # Reveal all pending TODOs so RuboCop can pick them up and report
+ # during scan.
+ ENV['REVEAL_RUBOCOP_TODO'] = '1'
+
+ # Save cop configuration like `RSpec/ContextWording` into
+ # `rspec/context_wording.yml` and not into
+ # `r_spec/context_wording.yml`.
+ ActiveSupport::Inflector.inflections(:en) do |inflect|
+ inflect.acronym 'RSpec'
+ inflect.acronym 'GraphQL'
+ end
options = %w[
- --auto-gen-config
- --auto-gen-only-exclude
- --exclude-limit=100000
- --no-offense-counts
+ --parallel
+ --format RuboCop::Formatter::TodoFormatter
]
+ # Convert from Rake::TaskArguments into an Array to make `any?` work as
+ # expected.
+ cop_names = args.to_a
+
+ todo_dir = RuboCop::TodoDir.new(RuboCop::TodoDir::DEFAULT_TODO_DIR)
+
+ if cop_names.any?
+ # We are sorting the cop names to benefit from RuboCop cache which
+ # also takes passed parameters into account.
+ list = cop_names.sort.join(',')
+ options.concat ['--only', list]
+
+ cop_names.each { |cop_name| todo_dir.inspect(cop_name) }
+ else
+ todo_dir.inspect_all
+ end
+
+ puts <<~MSG
+ Generating RuboCop TODOs with:
+ rubocop #{options.join(' ')}
+
+ This might take a while...
+ MSG
+
RuboCop::CLI.new.run(options)
+
+ todo_dir.delete_inspected
end
end
end
end
+
+# rubocop:enable Rails/RakeEnvironment
diff --git a/lib/tasks/tanuki_emoji.rake b/lib/tasks/tanuki_emoji.rake
index 98d3920c07f..0dc7dd4e701 100644
--- a/lib/tasks/tanuki_emoji.rake
+++ b/lib/tasks/tanuki_emoji.rake
@@ -3,12 +3,20 @@
namespace :tanuki_emoji do
desc 'Generates Emoji aliases fixtures'
task aliases: :environment do
+ ALLOWED_ALIASES = [':)', ':('].freeze
aliases = {}
TanukiEmoji.index.all.each do |emoji|
emoji.aliases.each do |emoji_alias|
aliases[TanukiEmoji::Character.format_name(emoji_alias)] = emoji.name
end
+
+ emoji.ascii_aliases.intersection(ALLOWED_ALIASES).each do |ascii_alias|
+ # We add an extra space at the end so that when a user types ":) "
+ # we'd still match this alias and not show "cocos (keeling) islands" as the first result.
+ # The initial ":" is ignored when matching because it's our emoji prefix in Markdown.
+ aliases[ascii_alias + ' '] = emoji.name
+ end
end
aliases_json_file = File.join(Rails.root, 'fixtures', 'emojis', 'aliases.json')
diff --git a/locale/am_ET/gitlab.po b/locale/am_ET/gitlab.po
index a96ae55e27c..5a3b5b11f8d 100644
--- a/locale/am_ET/gitlab.po
+++ b/locale/am_ET/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: am\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2022-02-02 15:47\n"
+"PO-Revision-Date: 2022-03-01 20:40\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -146,6 +146,11 @@ msgid_plural "%d approvers (you've approved)"
msgstr[0] ""
msgstr[1] ""
+msgid "%d assigned issue"
+msgid_plural "%d assigned issues"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -421,8 +426,23 @@ msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
msgstr[1] ""
-msgid "%d vulnerability updated"
-msgid_plural "%d vulnerabilities updated"
+msgid "%d vulnerability set to confirmed"
+msgid_plural "%d vulnerabilities set to confirmed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to dismissed"
+msgid_plural "%d vulnerabilities set to dismissed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to needs triage"
+msgid_plural "%d vulnerabilities set to needs triage"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to resolved"
+msgid_plural "%d vulnerabilities set to resolved"
msgstr[0] ""
msgstr[1] ""
@@ -510,6 +530,12 @@ msgstr[1] ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{completed} of %{total} issues closed"
+msgstr ""
+
+msgid "%{completed} of %{total} weight completed"
+msgstr ""
+
msgid "%{cores} cores"
msgstr "%{cores} ኮሮች"
@@ -858,6 +884,9 @@ msgstr ""
msgid "%{openedIssues} open, %{closedIssues} closed"
msgstr ""
+msgid "%{percentage}%% issues closed"
+msgstr ""
+
msgid "%{percentage}%% weight completed"
msgstr ""
@@ -1287,6 +1316,9 @@ msgid_plural "- Users"
msgstr[0] ""
msgstr[1] ""
+msgid "- of - issues closed"
+msgstr ""
+
msgid "- of - weight completed"
msgstr ""
@@ -1429,7 +1461,7 @@ msgstr ""
msgid "1000+"
msgstr ""
-msgid "192.168.0.0/24"
+msgid "192.168.0.0/24 or 2001:0DB8:1234::/48"
msgstr ""
msgid "1st contribution!"
@@ -1741,13 +1773,13 @@ msgstr ""
msgid "AWS Access Key"
msgstr ""
-msgid "AWS Access Key. Only required if not using role instance credentials"
+msgid "AWS Secret Access Key"
msgstr ""
-msgid "AWS Secret Access Key"
+msgid "AWS access key ID (Optional)"
msgstr ""
-msgid "AWS Secret Access Key. Only required if not using role instance credentials"
+msgid "AWS secret access key (Optional)"
msgstr ""
msgid "AWS service error: %{error}"
@@ -1807,9 +1839,6 @@ msgstr ""
msgid "Access granted"
msgstr ""
-msgid "Access key ID"
-msgstr ""
-
msgid "Access requests"
msgstr ""
@@ -1984,7 +2013,7 @@ msgstr ""
msgid "Activity"
msgstr ""
-msgid "Activity|An error occured while retrieving activity. Reload the page to try again."
+msgid "Activity|An error occurred while retrieving activity. Reload the page to try again."
msgstr ""
msgid "Add"
@@ -2023,6 +2052,9 @@ msgstr ""
msgid "Add a %{type}"
msgstr ""
+msgid "Add a GCP region"
+msgstr ""
+
msgid "Add a GPG key"
msgstr ""
@@ -2074,6 +2106,9 @@ msgstr ""
msgid "Add a numbered list"
msgstr ""
+msgid "Add a related epic"
+msgstr ""
+
msgid "Add a related issue"
msgstr ""
@@ -2188,6 +2223,9 @@ msgstr ""
msgid "Add or subtract spent time"
msgstr ""
+msgid "Add people"
+msgstr ""
+
msgid "Add previously merged commits"
msgstr ""
@@ -2254,6 +2292,9 @@ msgstr ""
msgid "Add webhook"
msgstr ""
+msgid "Add your team members and others to GitLab."
+msgstr ""
+
msgid "Add/remove"
msgstr ""
@@ -3076,12 +3117,6 @@ msgstr ""
msgid "AdvancedSearch|Reindex required"
msgstr ""
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. Permanently deleting this project will %{strongStart}immediately delete%{strongEnd} its repositories and %{strongStart}all related resources%{strongEnd}, including issues, merge requests etc."
-msgstr ""
-
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. You will lose this project's repository and %{strongStart}all related resources%{strongEnd}, including issues and merge requests."
-msgstr ""
-
msgid "After a successful password update you will be redirected to login screen."
msgstr ""
@@ -3112,6 +3147,9 @@ msgstr ""
msgid "Akismet helps prevent the creation of spam issues in public projects."
msgstr ""
+msgid "Alert"
+msgstr ""
+
msgid "AlertManagement|Acknowledged"
msgstr ""
@@ -3484,9 +3522,6 @@ msgstr ""
msgid "All environments"
msgstr ""
-msgid "All epics"
-msgstr ""
-
msgid "All groups and projects"
msgstr ""
@@ -4223,12 +4258,15 @@ msgstr ""
msgid "ApplicationSettings|Approve users in the pending approval status?"
msgstr ""
-msgid "ApplicationSettings|By making this change, you will automatically approve %d user with the pending approval status."
-msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users with the pending approval status."
+msgid "ApplicationSettings|Approve users who are pending approval?"
+msgstr ""
+
+msgid "ApplicationSettings|By making this change, you will automatically approve %d user who is pending approval."
+msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users who are pending approval."
msgstr[0] ""
msgstr[1] ""
-msgid "ApplicationSettings|By making this change, you will automatically approve all users in pending approval status."
+msgid "ApplicationSettings|By making this change, you will automatically approve all users who are pending approval."
msgstr ""
msgid "ApplicationSettings|Denied domains for sign-ups"
@@ -4634,10 +4672,10 @@ msgstr ""
msgid "Archiving the project will make it entirely read-only. It is hidden from the dashboard and doesn't show up in searches. %{strong_start}The repository cannot be committed to, and no issues, comments, or other entities can be created.%{strong_end} %{link_start}Learn more.%{link_end}"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to delete this project?"
+msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
+msgid "Are you absolutely sure?"
msgstr ""
msgid "Are you sure that you want to archive this project?"
@@ -4673,12 +4711,18 @@ msgstr ""
msgid "Are you sure you want to delete this SSH key?"
msgstr ""
+msgid "Are you sure you want to delete this comment?"
+msgstr ""
+
msgid "Are you sure you want to delete this deploy key?"
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 label?"
+msgstr ""
+
msgid "Are you sure you want to delete this pipeline schedule?"
msgstr ""
@@ -4694,9 +4738,6 @@ msgstr ""
msgid "Are you sure you want to discard your changes?"
msgstr ""
-msgid "Are you sure you want to erase this build?"
-msgstr ""
-
msgid "Are you sure you want to import %d repository?"
msgid_plural "Are you sure you want to import %d repositories?"
msgstr[0] ""
@@ -4744,6 +4785,9 @@ msgstr ""
msgid "Are you sure you want to remove this list?"
msgstr ""
+msgid "Are you sure you want to remove this nickname?"
+msgstr ""
+
msgid "Are you sure you want to reset the health check token?"
msgstr ""
@@ -4756,10 +4800,10 @@ 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?"
+msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
msgstr ""
-msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
+msgid "Are you sure you want to revoke this project access token? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to stop this environment?"
@@ -4906,9 +4950,6 @@ msgstr ""
msgid "Assigned to %{assignee_name}"
msgstr ""
-msgid "Assigned to %{name}"
-msgstr ""
-
msgid "Assigned to me"
msgstr ""
@@ -4973,6 +5014,9 @@ msgstr[1] ""
msgid "Attaching the file failed."
msgstr ""
+msgid "Attention"
+msgstr ""
+
msgid "Audit Events"
msgstr ""
@@ -5135,6 +5179,12 @@ msgstr ""
msgid "Authorized applications (%{size})"
msgstr ""
+msgid "AuthorizedApplication|Are you sure you want to revoke this application?"
+msgstr ""
+
+msgid "AuthorizedApplication|Revoke application"
+msgstr ""
+
msgid "Authors: %{authors}"
msgstr ""
@@ -6328,6 +6378,9 @@ msgstr ""
msgid "CICDAnalytics|Shared Runners Usage"
msgstr ""
+msgid "CICDAnalytics|Shared runner pipeline minute duration by month"
+msgstr ""
+
msgid "CICDAnalytics|Shared runner usage"
msgstr ""
@@ -6469,6 +6522,9 @@ msgstr ""
msgid "Can create groups:"
msgstr ""
+msgid "Can not delete primary training"
+msgstr ""
+
msgid "Can't apply as the source branch was deleted."
msgstr ""
@@ -6802,9 +6858,6 @@ msgstr ""
msgid "Changing any setting here requires an application restart"
msgstr ""
-msgid "Changing group URL can have unintended side effects."
-msgstr ""
-
msgid "Charts can't be displayed as the request for data has timed out. %{documentationLink}"
msgstr ""
@@ -6892,9 +6945,6 @@ msgstr ""
msgid "Checking branch availability..."
msgstr ""
-msgid "Checking group URL availability..."
-msgstr ""
-
msgid "Checking group path availability..."
msgstr ""
@@ -7388,6 +7438,9 @@ msgstr ""
msgid "Clear recent searches"
msgstr ""
+msgid "Clear repository checks"
+msgstr ""
+
msgid "Clear search"
msgstr ""
@@ -7520,9 +7573,6 @@ msgstr ""
msgid "Closed MRs"
msgstr ""
-msgid "Closed epics"
-msgstr ""
-
msgid "Closed issues"
msgstr ""
@@ -7559,13 +7609,13 @@ msgstr ""
msgid "Cluster level"
msgstr ""
-msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
+msgid "Cluster type must be specified for Stages::ClusterEndpointInserter"
msgstr ""
msgid "ClusterAgents|%{name} successfully deleted"
msgstr ""
-msgid "ClusterAgents|%{number} of %{total} Agents"
+msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
@@ -7607,6 +7657,15 @@ msgstr ""
msgid "ClusterAgents|Agent never connected to GitLab"
msgstr ""
+msgid "ClusterAgents|Agent version mismatch"
+msgstr ""
+
+msgid "ClusterAgents|Agent version mismatch and update"
+msgstr ""
+
+msgid "ClusterAgents|Agent version update required"
+msgstr ""
+
msgid "ClusterAgents|All"
msgstr ""
@@ -7631,7 +7690,7 @@ msgstr ""
msgid "ClusterAgents|Configuration"
msgstr ""
-msgid "ClusterAgents|Connect a cluster through the Agent"
+msgid "ClusterAgents|Connect a cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connect existing cluster"
@@ -7640,13 +7699,13 @@ msgstr ""
msgid "ClusterAgents|Connect with a certificate"
msgstr ""
-msgid "ClusterAgents|Connect with agent"
+msgid "ClusterAgents|Connect with an agent"
msgstr ""
msgid "ClusterAgents|Connect with the GitLab Agent"
msgstr ""
-msgid "ClusterAgents|Connect your cluster through the Agent"
+msgid "ClusterAgents|Connect your cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connected"
@@ -7706,7 +7765,10 @@ msgstr ""
msgid "ClusterAgents|How to register an agent?"
msgstr ""
-msgid "ClusterAgents|Install new Agent"
+msgid "ClusterAgents|How to update an agent?"
+msgstr ""
+
+msgid "ClusterAgents|Install a new agent"
msgstr ""
msgid "ClusterAgents|Last connected %{timeAgo}."
@@ -7733,7 +7795,7 @@ msgstr ""
msgid "ClusterAgents|Never connected"
msgstr ""
-msgid "ClusterAgents|No Agents"
+msgid "ClusterAgents|No agents"
msgstr ""
msgid "ClusterAgents|No clusters connected through cluster certificates"
@@ -7793,6 +7855,9 @@ msgstr ""
msgid "ClusterAgents|The agent has not been connected in a long time. There might be a connectivity issue. Last contact was %{timeAgo}."
msgstr ""
+msgid "ClusterAgents|The agent version do not match each other across your cluster's pods. This can happen when a new agent version was just deployed and Kubernetes is shutting down the old pods."
+msgstr ""
+
msgid "ClusterAgents|The recommended installation method includes the token. If you want to follow the advanced installation method provided in the docs, make sure you save the token value before you close this window."
msgstr ""
@@ -7840,6 +7905,9 @@ msgstr ""
msgid "ClusterAgents|You will need to create a token to connect to your agent"
msgstr ""
+msgid "ClusterAgents|Your agent version is out of sync with your GitLab version (v%{version}), which might cause compatibility problems. Update the agent installed on your cluster to the most recent version."
+msgstr ""
+
msgid "ClusterAgents|Your instance doesn't have the %{linkStart}GitLab Agent Server (KAS)%{linkEnd} set up. Ask a GitLab Administrator to install it."
msgstr ""
@@ -8716,9 +8784,6 @@ msgstr ""
msgid "Comma-separated list of email addresses."
msgstr ""
-msgid "Comma-separated list of users allowed to exceed the rate limit."
-msgstr ""
-
msgid "Comma-separated, e.g. '1.1.1.1, 2.2.2.0/24'"
msgstr ""
@@ -9045,6 +9110,12 @@ msgstr ""
msgid "Confidential"
msgstr ""
+msgid "Confidential issue"
+msgstr ""
+
+msgid "Confidential note"
+msgstr ""
+
msgid "Confidentiality"
msgstr ""
@@ -9078,6 +9149,9 @@ msgstr ""
msgid "Configure Dependency Scanning in `.gitlab-ci.yml`, creating this file if it does not already exist"
msgstr ""
+msgid "Configure GitLab"
+msgstr ""
+
msgid "Configure GitLab runners to start using the Web Terminal. %{helpStart}Learn more.%{helpEnd}"
msgstr ""
@@ -9126,6 +9200,15 @@ msgstr ""
msgid "Configure pipelines to deploy web apps, backend services, APIs and static resources to Google Cloud"
msgstr ""
+msgid "Configure region"
+msgstr ""
+
+msgid "Configure region for environment"
+msgstr ""
+
+msgid "Configure regions"
+msgstr ""
+
msgid "Configure repository mirroring."
msgstr ""
@@ -9159,6 +9242,9 @@ msgstr ""
msgid "Configure which lists are shown for anyone who visits this board"
msgstr ""
+msgid "Configure your environments to be deployed to specific geographical regions"
+msgstr ""
+
msgid "Confirm"
msgstr ""
@@ -9861,10 +9947,10 @@ msgstr ""
msgid "CorpusManagement|Actions"
msgstr ""
-msgid "CorpusManagement|Corpus are used in fuzz testing as mutation source to Improve future testing."
+msgid "CorpusManagement|Corpus file"
msgstr ""
-msgid "CorpusManagement|Corpus file"
+msgid "CorpusManagement|Corpus files are used in coverage-guided fuzz testing as seed inputs to improve testing."
msgstr ""
msgid "CorpusManagement|Corpus files must be in *.zip format. Maximum 5 GB"
@@ -9918,6 +10004,9 @@ msgstr ""
msgid "Could not apply %{name} command."
msgstr ""
+msgid "Could not apply %{name} command. %{message}."
+msgstr ""
+
msgid "Could not authorize chat nickname. Try again!"
msgstr ""
@@ -10068,6 +10157,9 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
+msgid "Create a group"
+msgstr ""
+
msgid "Create a merge request"
msgstr ""
@@ -10092,6 +10184,9 @@ msgstr ""
msgid "Create a personal access token on your account to pull or push via %{protocol}."
msgstr ""
+msgid "Create a project"
+msgstr ""
+
msgid "Create an account using:"
msgstr ""
@@ -10455,6 +10550,9 @@ msgstr ""
msgid "Creation date"
msgstr ""
+msgid "Creator"
+msgstr ""
+
msgid "Credentials"
msgstr ""
@@ -10467,9 +10565,15 @@ msgstr ""
msgid "CredentialsInventory|Personal Access Tokens"
msgstr ""
+msgid "CredentialsInventory|Project Access Tokens"
+msgstr ""
+
msgid "CredentialsInventory|SSH Keys"
msgstr ""
+msgid "Credit card required to be on file in order to create a pipeline"
+msgstr ""
+
msgid "Credit card:"
msgstr ""
@@ -10653,9 +10757,6 @@ msgstr ""
msgid "Customer relations"
msgstr ""
-msgid "Customizable by an administrator."
-msgstr ""
-
msgid "Customizable by owners."
msgstr ""
@@ -10785,30 +10886,18 @@ msgstr ""
msgid "CycleAnalytics|%{selectedLabelsCount} selected (%{maxLabels} max)"
msgstr ""
-msgid "CycleAnalytics|%{stageCount} stages selected"
-msgstr ""
-
-msgid "CycleAnalytics|All stages"
-msgstr ""
-
-msgid "CycleAnalytics|Average days to completion"
+msgid "CycleAnalytics|Average time to completion"
msgstr ""
msgid "CycleAnalytics|Date"
msgstr ""
-msgid "CycleAnalytics|Days to completion"
-msgstr ""
-
msgid "CycleAnalytics|Display chart filters"
msgstr ""
msgid "CycleAnalytics|Lead Time for Changes"
msgstr ""
-msgid "CycleAnalytics|No stages selected"
-msgstr ""
-
msgid "CycleAnalytics|Number of tasks"
msgstr ""
@@ -10837,18 +10926,30 @@ msgstr ""
msgid "CycleAnalytics|Showing data for group '%{groupName}' from %{createdAfter} to %{createdBefore}"
msgstr ""
-msgid "CycleAnalytics|Stages"
+msgid "CycleAnalytics|Stage time: %{title}"
msgstr ""
msgid "CycleAnalytics|Tasks by type"
msgstr ""
-msgid "CycleAnalytics|The average time spent in the selected stage for the items that were completed on each date. Data limited to the last 500 items."
+msgid "CycleAnalytics|The average time items spent in this stage. Data limited to items completed within this date range."
msgstr ""
msgid "CycleAnalytics|The given date range is larger than 180 days"
msgstr ""
+msgid "CycleAnalytics|The total time items spent across each value stream stage. Data limited to items completed within this date range."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Stage time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Total time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|Total time"
+msgstr ""
+
msgid "CycleAnalytics|Type of work"
msgstr ""
@@ -10861,9 +10962,6 @@ msgstr ""
msgid "CycleAnalytics|project dropdown filter"
msgstr ""
-msgid "CycleAnalytics|stage dropdown"
-msgstr ""
-
msgid "DAG visualization requires at least 3 dependent jobs."
msgstr ""
@@ -10963,10 +11061,16 @@ msgstr ""
msgid "DastProfiles|AJAX spider"
msgstr ""
+msgid "DastProfiles|API"
+msgstr ""
+
+msgid "DastProfiles|API endpoint URL"
+msgstr ""
+
msgid "DastProfiles|Active"
msgstr ""
-msgid "DastProfiles|Additional request headers (Optional)"
+msgid "DastProfiles|Additional request headers (optional)"
msgstr ""
msgid "DastProfiles|Are you sure you want to delete this profile?"
@@ -10981,6 +11085,9 @@ msgstr ""
msgid "DastProfiles|Branch missing"
msgstr ""
+msgid "DastProfiles|Choose a scan method"
+msgstr ""
+
msgid "DastProfiles|Could not create the scanner profile. Please try again."
msgstr ""
@@ -11050,7 +11157,13 @@ msgstr ""
msgid "DastProfiles|Excluded URLs"
msgstr ""
-msgid "DastProfiles|Excluded URLs (Optional)"
+msgid "DastProfiles|Excluded URLs (optional)"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths (optional)"
msgstr ""
msgid "DastProfiles|Hide debug messages"
@@ -11107,9 +11220,6 @@ msgstr ""
msgid "DastProfiles|Request headers"
msgstr ""
-msgid "DastProfiles|Rest API"
-msgstr ""
-
msgid "DastProfiles|Run the AJAX spider, in addition to the traditional spider, to crawl the target site."
msgstr ""
@@ -11119,6 +11229,9 @@ msgstr ""
msgid "DastProfiles|Save profile"
msgstr ""
+msgid "DastProfiles|Scan method"
+msgstr ""
+
msgid "DastProfiles|Scan mode"
msgstr ""
@@ -11197,12 +11310,24 @@ msgstr ""
msgid "DastProfiles|Website"
msgstr ""
+msgid "DastProfiles|What does each method do?"
+msgstr ""
+
msgid "DastProfiles|You can either choose a passive scan or validate the target site from the site profile management page. %{docsLinkStart}Learn more about site validation.%{docsLinkEnd}"
msgstr ""
msgid "DastProfiles|You cannot run an active scan against an unvalidated site."
msgstr ""
+msgid "DastProfiles|folder/dast_example.har or https://example.com/dast_example.har"
+msgstr ""
+
+msgid "DastProfiles|folder/example.postman_collection.json or https://example.com/"
+msgstr ""
+
+msgid "DastProfiles|folder/openapi.json or https://example.com/openapi.json"
+msgstr ""
+
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
@@ -11310,6 +11435,9 @@ msgstr ""
msgid "DatadogIntegration|API URL"
msgstr ""
+msgid "DatadogIntegration|Custom tags in Datadog. Enter one tag per line in the %{codeOpen}key:value%{codeClose} format. %{linkOpen}How do I use tags?%{linkClose}"
+msgstr ""
+
msgid "DatadogIntegration|Environment"
msgstr ""
@@ -11328,12 +11456,18 @@ msgstr ""
msgid "DatadogIntegration|Tag all data from this GitLab instance in Datadog. Useful when managing several self-managed deployments."
msgstr ""
+msgid "DatadogIntegration|Tags"
+msgstr ""
+
msgid "DatadogIntegration|The Datadog site to send data to. To send data to the EU site, use %{codeOpen}datadoghq.eu%{codeClose}."
msgstr ""
msgid "DatadogIntegration|Trace your GitLab pipelines with Datadog."
msgstr ""
+msgid "DatadogIntegration|have an invalid format"
+msgstr ""
+
msgid "Datasource name not found"
msgstr ""
@@ -11343,9 +11477,6 @@ msgstr ""
msgid "Date merged"
msgstr ""
-msgid "Date picker"
-msgstr ""
-
msgid "Date range"
msgstr ""
@@ -11499,9 +11630,6 @@ msgstr ""
msgid "Definition"
msgstr ""
-msgid "Delayed Project Deletion (%{adjourned_deletion})"
-msgstr ""
-
msgid "DelayedJobs|Are you sure you want to run %{jobName} immediately? Otherwise this job will run automatically after its timer finishes."
msgstr ""
@@ -11580,10 +11708,10 @@ msgstr ""
msgid "Delete pipeline"
msgstr ""
-msgid "Delete project"
+msgid "Delete pipeline schedule"
msgstr ""
-msgid "Delete project. Are you ABSOLUTELY SURE?"
+msgid "Delete project"
msgstr ""
msgid "Delete row"
@@ -11613,6 +11741,9 @@ msgstr ""
msgid "Delete this epic and all descendants?"
msgstr ""
+msgid "Delete this project"
+msgstr ""
+
msgid "Delete user list"
msgstr ""
@@ -11871,6 +12002,12 @@ msgstr ""
msgid "Deploy to..."
msgstr ""
+msgid "DeployBoards|To see deployment progress for your environments, make sure you are deploying to %{codeStart}$KUBE_NAMESPACE%{codeEnd} and annotating with %{codeStart}app.gitlab.com/app=$CI_PROJECT_PATH_SLUG%{codeEnd} and %{codeStart}app.gitlab.com/env=$CI_ENVIRONMENT_SLUG%{codeEnd}."
+msgstr ""
+
+msgid "DeployBoard|Kubernetes Pods"
+msgstr ""
+
msgid "DeployFreeze|Add a freeze period to prevent unintended releases during a period of time for a given environment. You must update the deployment jobs in %{filename} according to the deploy freezes added here. %{freeze_period_link_start}Learn more.%{freeze_period_link_end}"
msgstr ""
@@ -11955,9 +12092,6 @@ msgstr ""
msgid "DeployTokens|Active Deploy Tokens (%{active_tokens})"
msgstr ""
-msgid "DeployTokens|Allows read and write access to registry images."
-msgstr ""
-
msgid "DeployTokens|Allows read and write access to the package registry."
msgstr ""
@@ -11970,6 +12104,9 @@ msgstr ""
msgid "DeployTokens|Allows read-only access to the repository."
msgstr ""
+msgid "DeployTokens|Allows write access to registry images."
+msgstr ""
+
msgid "DeployTokens|Copy deploy token"
msgstr ""
@@ -12063,12 +12200,57 @@ msgstr ""
msgid "Deploying to AWS is easy with GitLab"
msgstr ""
+msgid "Deployment"
+msgstr ""
+
msgid "Deployment Frequency"
msgstr ""
+msgid "Deployment Target|Project deployment target (optional)"
+msgstr ""
+
+msgid "Deployment Target|Select the deployment target"
+msgstr ""
+
msgid "Deployment frequency"
msgstr ""
+msgid "DeploymentTarget|GitLab Pages"
+msgstr ""
+
+msgid "DeploymentTarget|Heroku"
+msgstr ""
+
+msgid "DeploymentTarget|Infrastructure provider (Terraform, Cloudformation, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Kubernetes (GKE, EKS, OpenShift, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Managed container runtime (Fargate, Cloud Run, DigitalOcean App)"
+msgstr ""
+
+msgid "DeploymentTarget|Mobile app store"
+msgstr ""
+
+msgid "DeploymentTarget|No deployment planned"
+msgstr ""
+
+msgid "DeploymentTarget|Other hosting service"
+msgstr ""
+
+msgid "DeploymentTarget|Registry (package or container)"
+msgstr ""
+
+msgid "DeploymentTarget|Self-managed container runtime (Podman, Docker Swarm, Docker Compose)"
+msgstr ""
+
+msgid "DeploymentTarget|Serverless backend (Lambda, Cloud functions)"
+msgstr ""
+
+msgid "DeploymentTarget|Virtual machine (for example, EC2)"
+msgstr ""
+
msgid "Deployments"
msgstr ""
@@ -12107,6 +12289,9 @@ msgstr ""
msgid "Deployment|This deployment was created using the API"
msgstr ""
+msgid "Deployment|Triggerer"
+msgstr ""
+
msgid "Deployment|Waiting"
msgstr ""
@@ -12134,6 +12319,18 @@ msgstr ""
msgid "Deprecated API rate limits"
msgstr ""
+msgid "Deprecations|Feature deprecation and removal"
+msgstr ""
+
+msgid "Deprecations|For information on a possible replacement %{epicStart} learn more about Opstrace %{epicEnd}."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7 and are %{epicStart} scheduled for removal %{epicEnd} in GitLab 15.0."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7, and are %{removal_link_start} scheduled for removal %{link_end} in GitLab 15.0. For information on a possible replacement, %{opstrace_link_start} learn more about Opstrace %{link_end}."
+msgstr ""
+
msgid "Deprioritize label"
msgstr ""
@@ -12379,10 +12576,10 @@ msgstr ""
msgid "DevopsAdoption|At least one deploy"
msgstr ""
-msgid "DevopsAdoption|At least one issue opened"
+msgid "DevopsAdoption|At least one issue created"
msgstr ""
-msgid "DevopsAdoption|At least one merge request opened"
+msgid "DevopsAdoption|At least one merge request created"
msgstr ""
msgid "DevopsAdoption|At least one pipeline successfully run"
@@ -12583,6 +12780,9 @@ msgstr ""
msgid "Direct member"
msgstr ""
+msgid "Direct members"
+msgstr ""
+
msgid "Direct non-authenticated users to this page."
msgstr ""
@@ -12699,6 +12899,9 @@ msgid_plural "Dismiss %d selected vulnerabilities as"
msgstr[0] ""
msgstr[1] ""
+msgid "Dismiss Alert"
+msgstr ""
+
msgid "Dismiss merge request promotion"
msgstr ""
@@ -12726,9 +12929,15 @@ msgstr ""
msgid "Display alerts from all configured monitoring tools."
msgstr ""
+msgid "Display milestones"
+msgstr ""
+
msgid "Display name"
msgstr ""
+msgid "Display progress of child issues"
+msgstr ""
+
msgid "Display rendered file"
msgstr ""
@@ -12834,6 +13043,9 @@ msgstr ""
msgid "Download image"
msgstr ""
+msgid "Download payload"
+msgstr ""
+
msgid "Download raw data (.csv)"
msgstr ""
@@ -13011,6 +13223,9 @@ msgstr ""
msgid "Edit in Web IDE"
msgstr ""
+msgid "Edit in pipeline editor"
+msgstr ""
+
msgid "Edit in single-file editor"
msgstr ""
@@ -13053,6 +13268,9 @@ msgstr ""
msgid "Edit your most recent comment in a thread (from an empty textarea)"
msgstr ""
+msgid "Edit, lint, and visualize your pipeline."
+msgstr ""
+
msgid "Edited"
msgstr ""
@@ -13494,6 +13712,9 @@ msgstr ""
msgid "Enforce two-factor authentication for all user sign-ins."
msgstr ""
+msgid "Enhance security by storing service account keys in secret managers - learn more about %{docLinkStart}secret management with GitLab%{docLinkEnd}"
+msgstr ""
+
msgid "Ensure connectivity is available from the GitLab server to the Prometheus server"
msgstr ""
@@ -13554,6 +13775,9 @@ 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 following to confirm:"
+msgstr ""
+
msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
@@ -14084,9 +14308,6 @@ 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 ""
@@ -14222,6 +14443,9 @@ msgstr ""
msgid "Errors:"
msgstr ""
+msgid "Escalate this incident"
+msgstr ""
+
msgid "Escalation Policies"
msgstr ""
@@ -14234,6 +14458,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy"
+msgstr ""
+
msgid "Escalation policy:"
msgstr ""
@@ -14485,6 +14712,9 @@ msgstr ""
msgid "Existing sign in methods may be removed"
msgstr ""
+msgid "Exit."
+msgstr ""
+
msgid "Expand"
msgstr ""
@@ -14581,6 +14811,9 @@ msgstr ""
msgid "Explore public groups"
msgstr ""
+msgid "Explore public projects"
+msgstr ""
+
msgid "Explore snippets"
msgstr ""
@@ -14742,7 +14975,7 @@ msgid_plural "Failed to archive designs. Please try again."
msgstr[0] ""
msgstr[1] ""
-msgid "Failed to assign a reviewer because no user was found."
+msgid "Failed to assign a reviewer because no user was specified."
msgstr ""
msgid "Failed to assign a user because no user was found."
@@ -14808,10 +15041,10 @@ msgstr ""
msgid "Failed to find import label for Jira import."
msgstr ""
-msgid "Failed to generate export, please try again later."
+msgid "Failed to find users for %{missing}"
msgstr ""
-msgid "Failed to generate report, please try again after sometime"
+msgid "Failed to generate export, please try again later."
msgstr ""
msgid "Failed to get ref."
@@ -14910,6 +15143,9 @@ msgstr ""
msgid "Failed to remove a to-do item for the design."
msgstr ""
+msgid "Failed to remove attention because no user was found."
+msgstr ""
+
msgid "Failed to remove mirror."
msgstr ""
@@ -14922,6 +15158,9 @@ msgstr ""
msgid "Failed to remove user key."
msgstr ""
+msgid "Failed to request attention because no user was found."
+msgstr ""
+
msgid "Failed to reset key. Please try again."
msgstr ""
@@ -15003,6 +15242,9 @@ msgstr ""
msgid "Feature Flags"
msgstr ""
+msgid "Feature deprecation and removal"
+msgstr ""
+
msgid "Feature flag status"
msgstr ""
@@ -15500,7 +15742,7 @@ msgstr ""
msgid "For each job, re-use the project workspace. If the workspace doesn't exist, use %{code_open}git clone%{code_close}."
msgstr ""
-msgid "For example, the application using the token or the purpose of the token."
+msgid "For example, the application using the token or the purpose of the token. Do not give sensitive information for the name of the token, as it will be visible to all %{resource_type} members."
msgstr ""
msgid "For files larger than this limit, only index the file name. The file content is neither indexed nor searchable."
@@ -15584,9 +15826,6 @@ msgstr ""
msgid "ForkProject|Select a namespace"
msgstr ""
-msgid "ForkProject|Select a namespace to fork the project"
-msgstr ""
-
msgid "ForkProject|The project can be accessed by any logged in user."
msgstr ""
@@ -15683,6 +15922,9 @@ msgstr ""
msgid "Full name"
msgstr ""
+msgid "GCP region configured"
+msgstr ""
+
msgid "GPG Key ID:"
msgstr ""
@@ -15863,6 +16105,9 @@ msgstr ""
msgid "Geo|Failed"
msgstr ""
+msgid "Geo|Filter Geo sites"
+msgstr ""
+
msgid "Geo|Filter by name"
msgstr ""
@@ -16274,6 +16519,12 @@ msgstr ""
msgid "GitLab Issue"
msgstr ""
+msgid "GitLab KAS"
+msgstr ""
+
+msgid "GitLab Memberships CSV Export"
+msgstr ""
+
msgid "GitLab Pages"
msgstr ""
@@ -16322,6 +16573,9 @@ 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 free to use. Many features for larger teams are part of our %{link_start}paid products%{link_end}. You can try Ultimate for free without any obligation or payment details."
+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 ""
@@ -16448,7 +16702,7 @@ msgstr ""
msgid "GitLabPages|When enabled, all attempts to visit your website through HTTP are automatically redirected to HTTPS using a response with status code 301. Requires a valid certificate for all domains. %{docs_link_start}Learn more.%{link_end}"
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. %{docs_link_start}Learn more.%{link_end}"
+msgid "GitLabPages|When using Pages under the general domain of a GitLab instance (%{pages_host}), you cannot use HTTPS with subdomains of subdomains. If your namespace or groupname contains a dot, it does not work. This is a limitation of the HTTP Over TLS protocol. HTTP pages work if you don't redirect HTTP to HTTPS. %{docs_link_start}Learn more.%{link_end}"
msgstr ""
msgid "GitLabPages|With GitLab Pages you can host your static website directly from your GitLab repository. %{docs_link_start}Learn more.%{link_end}"
@@ -16625,9 +16879,6 @@ msgstr ""
msgid "Go to find file"
msgstr ""
-msgid "Go to fork"
-msgstr ""
-
msgid "Go to issue boards"
msgstr ""
@@ -16835,9 +17086,6 @@ msgstr ""
msgid "Group Hooks"
msgstr ""
-msgid "Group ID"
-msgstr ""
-
msgid "Group Owner must have signed in with SAML before enabling Group Managed Accounts"
msgstr ""
@@ -16865,9 +17113,6 @@ msgstr ""
msgid "Group by"
msgstr ""
-msgid "Group description"
-msgstr ""
-
msgid "Group description (optional)"
msgstr ""
@@ -16982,7 +17227,7 @@ msgstr ""
msgid "Group: %{name}"
msgstr ""
-msgid "GroupActivityMetrics|Issues opened"
+msgid "GroupActivityMetrics|Issues created"
msgstr ""
msgid "GroupActivityMetrics|Last 90 days"
@@ -16991,7 +17236,7 @@ msgstr ""
msgid "GroupActivityMetrics|Members added"
msgstr ""
-msgid "GroupActivityMetrics|Merge Requests opened"
+msgid "GroupActivityMetrics|Merge Requests created"
msgstr ""
msgid "GroupActivityMetrics|Recent activity"
@@ -17282,6 +17527,9 @@ msgstr ""
msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
+msgid "GroupSettings|Choose a group path that does not start with a dash or end with a period. It can also contain alphanumeric characters and underscores."
+msgstr ""
+
msgid "GroupSettings|Compliance frameworks"
msgstr ""
@@ -17315,7 +17563,7 @@ msgstr ""
msgid "GroupSettings|If not specified at the group or instance level, the default is %{default_initial_branch_name}. Does not affect existing repositories."
msgstr ""
-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."
+msgid "GroupSettings|If the parent group's visibility is lower than the group's current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility."
msgstr ""
msgid "GroupSettings|New runners registration token has been generated!"
@@ -17432,7 +17680,10 @@ msgstr ""
msgid "Groups and projects"
msgstr ""
-msgid "Groups and subgroups"
+msgid "Groups are a great way to organize projects and people."
+msgstr ""
+
+msgid "Groups are the best way to manage projects and members."
msgstr ""
msgid "Groups to synchronize"
@@ -17543,13 +17794,16 @@ msgstr ""
msgid "GroupsTree|Are you sure you want to leave the \"%{fullName}\" group?"
msgstr ""
-msgid "GroupsTree|Edit group"
+msgid "GroupsTree|Delete"
+msgstr ""
+
+msgid "GroupsTree|Edit"
msgstr ""
msgid "GroupsTree|Failed to leave the group. Please make sure you are not the only owner."
msgstr ""
-msgid "GroupsTree|Leave this group"
+msgid "GroupsTree|Leave group"
msgstr ""
msgid "GroupsTree|Loading groups"
@@ -17561,9 +17815,57 @@ msgstr ""
msgid "GroupsTree|No groups or projects matched your search"
msgstr ""
+msgid "GroupsTree|Options"
+msgstr ""
+
msgid "GroupsTree|Search by name"
msgstr ""
+msgid "Groups|Avatar will be removed. Are you sure?"
+msgstr ""
+
+msgid "Groups|Changing group URL can have unintended side effects."
+msgstr ""
+
+msgid "Groups|Checking group URL availability..."
+msgstr ""
+
+msgid "Groups|Enter a descriptive name for your group."
+msgstr ""
+
+msgid "Groups|Group ID"
+msgstr ""
+
+msgid "Groups|Group URL"
+msgstr ""
+
+msgid "Groups|Group avatar"
+msgstr ""
+
+msgid "Groups|Group description (optional)"
+msgstr ""
+
+msgid "Groups|Group name"
+msgstr ""
+
+msgid "Groups|Group path is available."
+msgstr ""
+
+msgid "Groups|Group path is unavailable. Path has been replaced with a suggested available path."
+msgstr ""
+
+msgid "Groups|Learn more"
+msgstr ""
+
+msgid "Groups|Must start with letter, digit, emoji, or underscore. Can also contain periods, dashes, spaces, and parentheses."
+msgstr ""
+
+msgid "Groups|Remove avatar"
+msgstr ""
+
+msgid "Groups|Save changes"
+msgstr ""
+
msgid "Guideline"
msgstr ""
@@ -17573,6 +17875,9 @@ msgstr ""
msgid "HAR file path or URL"
msgstr ""
+msgid "HTTP Archive (HAR)"
+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 ""
@@ -17973,6 +18278,9 @@ msgstr ""
msgid "INFO: Your SSH key is expiring soon. Please generate a new key."
msgstr ""
+msgid "IP"
+msgstr ""
+
msgid "IP Address"
msgstr ""
@@ -18009,6 +18317,9 @@ msgstr ""
msgid "IdentityVerification|Verify your identity"
msgstr ""
+msgid "IdentityVerification|You can always verify your account at a later time to create a group."
+msgstr ""
+
msgid "If any indexed field exceeds this limit, it is truncated to this number of characters. The rest of the content is neither indexed nor searchable. This does not apply to repository and wiki indexing. For unlimited characters, set this to 0."
msgstr ""
@@ -18066,6 +18377,9 @@ msgstr ""
msgid "If you add %{codeStart}needs%{codeEnd} to jobs in your pipeline you'll be able to view the %{codeStart}needs%{codeEnd} relationships between jobs in this tab as a %{linkStart}Directed Acyclic Graph (DAG)%{linkEnd}."
msgstr ""
+msgid "If you are added to a project, it will be displayed here."
+msgstr ""
+
msgid "If you did not initiate these sign-in attempts, please reach out to your administrator or enable two-factor authentication (2FA) on your account."
msgstr ""
@@ -18372,12 +18686,24 @@ msgstr ""
msgid "InProductMarketing|3 ways to dive into GitLab CI/CD"
msgstr ""
+msgid "InProductMarketing|A single application eliminates complex integrations, data chokepoints, and toolchain maintenance, resulting in greater productivity and lower cost."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features, build more efficiently, strengthen security and compliance."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features."
+msgstr ""
+
msgid "InProductMarketing|Actually, GitLab makes the team work (better)"
msgstr ""
msgid "InProductMarketing|And finally %{deploy_link} a Python application."
msgstr ""
+msgid "InProductMarketing|And many more..."
+msgstr ""
+
msgid "InProductMarketing|Are your runners ready?"
msgstr ""
@@ -18396,15 +18722,33 @@ msgstr ""
msgid "InProductMarketing|Blog"
msgstr ""
+msgid "InProductMarketing|Break down silos to coordinate seamlessly across development, operations, and security with a consistent experience across the development lifecycle."
+msgstr ""
+
+msgid "InProductMarketing|Burn up/down charts"
+msgstr ""
+
msgid "InProductMarketing|By enabling code owners and required merge approvals the right person will review the right MR. This is a win-win: cleaner code and a more efficient review process."
msgstr ""
msgid "InProductMarketing|Click on the number below that corresponds with your answer — 1 being very difficult, 5 being very easy."
msgstr ""
+msgid "InProductMarketing|Code owners"
+msgstr ""
+
msgid "InProductMarketing|Code owners and required merge approvals are part of the paid tiers of GitLab. You can start a free 30-day trial of GitLab Ultimate and enable these features in less than 5 minutes with no credit card required."
msgstr ""
+msgid "InProductMarketing|Code review analytics"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration across stages in GitLab"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration made easy"
+msgstr ""
+
msgid "InProductMarketing|Create a custom CI runner with just a few clicks"
msgstr ""
@@ -18414,12 +18758,21 @@ msgstr ""
msgid "InProductMarketing|Create a project in GitLab in 5 minutes"
msgstr ""
+msgid "InProductMarketing|Create well-defined workflows by using scoped labels on issues, merge requests, and epics. Labels with the same scope cannot be used together, which prevents conflicts."
+msgstr ""
+
msgid "InProductMarketing|Create your first project!"
msgstr ""
+msgid "InProductMarketing|Define who owns specific files or directories, so the right reviewers are suggested when a merge request introduces changes to those files."
+msgstr ""
+
msgid "InProductMarketing|Deliver Better Products Faster"
msgstr ""
+msgid "InProductMarketing|Dependency scanning"
+msgstr ""
+
msgid "InProductMarketing|Did you know teams that use GitLab are far more efficient?"
msgstr ""
@@ -18429,15 +18782,27 @@ msgstr ""
msgid "InProductMarketing|Dig in and create a project and a repo"
msgstr ""
+msgid "InProductMarketing|Discover Premium & Ultimate"
+msgstr ""
+
+msgid "InProductMarketing|Discover Premium & Ultimate."
+msgstr ""
+
msgid "InProductMarketing|Do you have a minute?"
msgstr ""
msgid "InProductMarketing|Do you have a teammate who would be perfect for this task?"
msgstr ""
+msgid "InProductMarketing|Dynamic application security testing"
+msgstr ""
+
msgid "InProductMarketing|Easy"
msgstr ""
+msgid "InProductMarketing|Epics"
+msgstr ""
+
msgid "InProductMarketing|Expand your DevOps journey with a free GitLab trial"
msgstr ""
@@ -18459,9 +18824,15 @@ msgstr ""
msgid "InProductMarketing|Feel the need for speed?"
msgstr ""
+msgid "InProductMarketing|Find and fix bottlenecks in your code review process by understanding how long open merge requests have been in review."
+msgstr ""
+
msgid "InProductMarketing|Find out how your teams are really doing"
msgstr ""
+msgid "InProductMarketing|Find out if your external libraries are safe. Run dependency scanning jobs that check for known vulnerabilities in your external libraries."
+msgstr ""
+
msgid "InProductMarketing|Follow our steps"
msgstr ""
@@ -18498,6 +18869,9 @@ msgstr ""
msgid "InProductMarketing|GitLab is better with teammates to help out!"
msgstr ""
+msgid "InProductMarketing|GitLab is infrastructure agnostic (supporting GCP, AWS, Azure, OpenShift, VMWare, On Prem, Bare Metal, and more), offering a consistent workflow experience – irrespective of the environment."
+msgstr ""
+
msgid "InProductMarketing|GitLab provides static application security testing (SAST), dynamic application security testing (DAST), container scanning, and dependency scanning to help you deliver secure applications along with license compliance."
msgstr ""
@@ -18588,21 +18962,36 @@ msgstr ""
msgid "InProductMarketing|It's also possible to simply %{external_repo_link} in order to take advantage of GitLab's CI/CD."
msgstr ""
+msgid "InProductMarketing|Keep your code quality high by defining who should approve merge requests and how many approvals are required."
+msgstr ""
+
msgid "InProductMarketing|Launch GitLab CI/CD in 20 minutes or less"
msgstr ""
+msgid "InProductMarketing|Lower cost of development"
+msgstr ""
+
+msgid "InProductMarketing|Make it easier to collaborate on high-level ideas by grouping related issues in an epic."
+msgstr ""
+
msgid "InProductMarketing|Making the switch? It's easier than you think to import your projects into GitLab. Move %{github_link}, or import something %{bitbucket_link}."
msgstr ""
msgid "InProductMarketing|Master the art of importing!"
msgstr ""
+msgid "InProductMarketing|Merge request approval rule"
+msgstr ""
+
msgid "InProductMarketing|Move on to easily creating a Pages website %{ci_template_link}"
msgstr ""
msgid "InProductMarketing|Multiple owners, confusing workstreams? We've got you covered"
msgstr ""
+msgid "InProductMarketing|Multiple required approvers"
+msgstr ""
+
msgid "InProductMarketing|Need an alternative to importing?"
msgstr ""
@@ -18615,18 +19004,33 @@ msgstr ""
msgid "InProductMarketing|Our tool brings all the things together"
msgstr ""
+msgid "InProductMarketing|Protect your web application by using DAST to examine for vulnerabilities in deployed environments."
+msgstr ""
+
msgid "InProductMarketing|Rapid development, simplified"
msgstr ""
msgid "InProductMarketing|Reduce Security & Compliance Risk"
msgstr ""
+msgid "InProductMarketing|Require multiple approvers on a merge request, so you know it's in good shape before it's merged."
+msgstr ""
+
+msgid "InProductMarketing|Roadmaps"
+msgstr ""
+
+msgid "InProductMarketing|Scoped labels"
+msgstr ""
+
msgid "InProductMarketing|Security that's integrated into your development lifecycle"
msgstr ""
msgid "InProductMarketing|Sometimes you're not ready to make a full transition to a new tool. If you're not ready to fully commit, %{mirroring_link} gives you a safe way to try out GitLab in parallel with your current tool."
msgstr ""
+msgid "InProductMarketing|Speed. Efficiency. Trust."
+msgstr ""
+
msgid "InProductMarketing|Spin up an autoscaling runner in GitLab"
msgstr ""
@@ -18636,6 +19040,9 @@ msgstr ""
msgid "InProductMarketing|Start a Self-Managed trial"
msgstr ""
+msgid "InProductMarketing|Start a free trial"
+msgstr ""
+
msgid "InProductMarketing|Start a free trial of GitLab Ultimate – no credit card required"
msgstr ""
@@ -18702,6 +19109,9 @@ msgstr ""
msgid "InProductMarketing|To understand and get the most out of GitLab, start at the beginning and %{project_link}. In GitLab, repositories are part of a project, so after you've created your project you can go ahead and %{repo_link}."
msgstr ""
+msgid "InProductMarketing|Track completed issues in a chart, so you can see how a milestone is progressing at a glance."
+msgstr ""
+
msgid "InProductMarketing|Try GitLab Ultimate for free"
msgstr ""
@@ -18738,6 +19148,9 @@ msgstr ""
msgid "InProductMarketing|Very easy"
msgstr ""
+msgid "InProductMarketing|Visualize your epics and milestones in a timeline."
+msgstr ""
+
msgid "InProductMarketing|Want to host GitLab on your servers?"
msgstr ""
@@ -18759,6 +19172,9 @@ msgstr ""
msgid "InProductMarketing|YouTube"
msgstr ""
+msgid "InProductMarketing|Your software, deployed your way"
+msgstr ""
+
msgid "InProductMarketing|Your teams can be more efficient"
msgstr ""
@@ -18879,9 +19295,18 @@ msgstr ""
msgid "IncidentManagement|No incidents to display."
msgstr ""
+msgid "IncidentManagement|None"
+msgstr ""
+
msgid "IncidentManagement|Open"
msgstr ""
+msgid "IncidentManagement|Page your team with escalation policies"
+msgstr ""
+
+msgid "IncidentManagement|Paged"
+msgstr ""
+
msgid "IncidentManagement|Published"
msgstr ""
@@ -18891,6 +19316,9 @@ msgstr ""
msgid "IncidentManagement|Severity"
msgstr ""
+msgid "IncidentManagement|Status"
+msgstr ""
+
msgid "IncidentManagement|There are no closed incidents"
msgstr ""
@@ -18909,6 +19337,9 @@ msgstr ""
msgid "IncidentManagement|Unpublished"
msgstr ""
+msgid "IncidentManagement|Use escalation policies to automatically page your team when incidents are created."
+msgstr ""
+
msgid "IncidentSettings|Activate \"time to SLA\" countdown timer"
msgstr ""
@@ -18954,7 +19385,10 @@ msgstr ""
msgid "Incidents"
msgstr ""
-msgid "Incidents|Add a URL"
+msgid "Incidents|Add image details"
+msgstr ""
+
+msgid "Incidents|Add text or a link to display with your image. If you don't add either, the file name displays instead."
msgstr ""
msgid "Incidents|Drop or %{linkStart}upload%{linkEnd} a metric screenshot to attach it to the incident"
@@ -18969,10 +19403,10 @@ msgstr ""
msgid "Incidents|There was an issue loading metric images."
msgstr ""
-msgid "Incidents|There was an issue uploading your image."
+msgid "Incidents|There was an issue updating your image."
msgstr ""
-msgid "Incidents|You can optionally add a URL to link users to the original graph."
+msgid "Incidents|There was an issue uploading your image."
msgstr ""
msgid "Incident|Alert details"
@@ -18981,9 +19415,18 @@ msgstr ""
msgid "Incident|Are you sure you wish to delete this image?"
msgstr ""
+msgid "Incident|Delete image"
+msgstr ""
+
msgid "Incident|Deleting %{filename}"
msgstr ""
+msgid "Incident|Edit image text or link"
+msgstr ""
+
+msgid "Incident|Editing %{filename}"
+msgstr ""
+
msgid "Incident|Metrics"
msgstr ""
@@ -19253,12 +19696,18 @@ msgstr ""
msgid "Integrations|Branches for which notifications are to be sent"
msgstr ""
+msgid "Integrations|Clear if using a self-signed certificate."
+msgstr ""
+
msgid "Integrations|Comment detail:"
msgstr ""
msgid "Integrations|Comment settings:"
msgstr ""
+msgid "Integrations|Connection details"
+msgstr ""
+
msgid "Integrations|Connection failed. Please check your settings."
msgstr ""
@@ -19283,6 +19732,9 @@ msgstr ""
msgid "Integrations|Enable GitLab.com slash commands in a Slack workspace."
msgstr ""
+msgid "Integrations|Enable SSL verification"
+msgstr ""
+
msgid "Integrations|Enable comments"
msgstr ""
@@ -19361,6 +19813,9 @@ msgstr ""
msgid "Integrations|Return to GitLab for Jira"
msgstr ""
+msgid "Integrations|SSL verification"
+msgstr ""
+
msgid "Integrations|Save settings?"
msgstr ""
@@ -19406,9 +19861,6 @@ msgstr ""
msgid "Integrations|Use default settings"
msgstr ""
-msgid "Integrations|When you mention a Jira issue in a commit or merge request, GitLab creates a remote link and comment (if enabled)."
-msgstr ""
-
msgid "Integrations|You can now close this window and return to the GitLab for Jira application."
msgstr ""
@@ -19433,9 +19885,6 @@ msgstr ""
msgid "Integrations|can't exceed %{recipients_limit}"
msgstr ""
-msgid "Interactive developer security education."
-msgstr ""
-
msgid "Interactive mode"
msgstr ""
@@ -19925,6 +20374,9 @@ msgstr ""
msgid "IssueAnalytics|Assignees"
msgstr ""
+msgid "IssueAnalytics|Created by"
+msgstr ""
+
msgid "IssueAnalytics|Due date"
msgstr ""
@@ -19937,9 +20389,6 @@ msgstr ""
msgid "IssueAnalytics|Milestone"
msgstr ""
-msgid "IssueAnalytics|Opened by"
-msgstr ""
-
msgid "IssueAnalytics|Status"
msgstr ""
@@ -20063,10 +20512,10 @@ msgstr ""
msgid "IssuesAnalytics|Avg/Month:"
msgstr ""
-msgid "IssuesAnalytics|Issues opened"
+msgid "IssuesAnalytics|Issues created"
msgstr ""
-msgid "IssuesAnalytics|Issues opened per month"
+msgid "IssuesAnalytics|Issues created per month"
msgstr ""
msgid "IssuesAnalytics|Last 12 months"
@@ -20093,6 +20542,9 @@ msgstr ""
msgid "It looks like you have some draft commits in this branch."
msgstr ""
+msgid "It looks like you're attempting to activate your subscription. Use %{a_start}the Subscription page%{a_end} instead."
+msgstr ""
+
msgid "It may be several days before you see feature usage data."
msgstr ""
@@ -20321,6 +20773,9 @@ msgstr ""
msgid "JiraConnect|You can now close this window and return to Jira."
msgstr ""
+msgid "JiraConnect|You don't have permission to create branches for this project. Select a different project or contact the project owner for access. %{linkStart}Learn more.%{linkEnd}"
+msgstr ""
+
msgid "JiraRequest|A connection error occurred while connecting to Jira. Try your request again."
msgstr ""
@@ -20369,13 +20824,13 @@ msgstr ""
msgid "JiraService|Define the type of Jira issue to create from a vulnerability."
msgstr ""
-msgid "JiraService|Displaying Jira issues while leaving the GitLab issue functionality enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
+msgid "JiraService|Displaying Jira issues while leaving GitLab issues also enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
msgstr ""
-msgid "JiraService|Enable Jira issues"
+msgid "JiraService|Enable Jira issue creation from vulnerabilities"
msgstr ""
-msgid "JiraService|Enable Jira issues creation from vulnerabilities"
+msgid "JiraService|Enable Jira issues"
msgstr ""
msgid "JiraService|Enable Jira transitions"
@@ -20492,16 +20947,19 @@ msgstr ""
msgid "JiraService|View Jira issues in GitLab"
msgstr ""
-msgid "JiraService|Warning: All GitLab users that have access to this GitLab project are able to view all issues from the Jira project specified below."
+msgid "JiraService|Warning: All GitLab users with access to this GitLab project can view all issues from the Jira project you select."
msgstr ""
msgid "JiraService|Web URL"
msgstr ""
-msgid "JiraService|Work on Jira issues without leaving GitLab. Adds a Jira menu to access your list of Jira issues and view any issue as read-only."
+msgid "JiraService|When a Jira issue is mentioned in a commit or merge request, a remote link and comment (if enabled) will be created."
+msgstr ""
+
+msgid "JiraService|Work on Jira issues without leaving GitLab. Add a Jira menu to access a read-only list of your Jira issues."
msgstr ""
-msgid "JiraService|You need to configure Jira before enabling this integration. For more details, read the %{jira_doc_link_start}Jira integration documentation%{link_end}."
+msgid "JiraService|You must configure Jira before enabling this integration. %{jira_doc_link_start}Learn more.%{link_end}"
msgstr ""
msgid "Job"
@@ -20513,9 +20971,6 @@ msgstr ""
msgid "Job Failed #%{build_id}"
msgstr ""
-msgid "Job ID"
-msgstr ""
-
msgid "Job artifact"
msgstr ""
@@ -20582,9 +21037,27 @@ msgstr ""
msgid "Jobs|You're about to retry a job that failed because it attempted to deploy code that is older than the latest deployment. Retrying this job could result in overwriting the environment with the older source code."
msgstr ""
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source} into %{target}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{ref}"
+msgstr ""
+
+msgid "Job|Are you sure you want to erase this job log and artifacts?"
+msgstr ""
+
msgid "Job|Browse"
msgstr ""
+msgid "Job|Cancel"
+msgstr ""
+
msgid "Job|Complete Raw"
msgstr ""
@@ -20594,6 +21067,9 @@ msgstr ""
msgid "Job|Erase job log and artifacts"
msgstr ""
+msgid "Job|Finished at"
+msgstr ""
+
msgid "Job|Job artifacts"
msgstr ""
@@ -20606,7 +21082,7 @@ msgstr ""
msgid "Job|Keep"
msgstr ""
-msgid "Job|Pipeline"
+msgid "Job|Retry"
msgstr ""
msgid "Job|Scroll to bottom"
@@ -20618,6 +21094,9 @@ msgstr ""
msgid "Job|Show complete raw"
msgstr ""
+msgid "Job|Status"
+msgstr ""
+
msgid "Job|The artifacts were removed"
msgstr ""
@@ -20645,21 +21124,12 @@ msgstr ""
msgid "Job|delayed"
msgstr ""
-msgid "Job|for"
-msgstr ""
-
-msgid "Job|into"
-msgstr ""
-
msgid "Job|manual"
msgstr ""
msgid "Job|triggered"
msgstr ""
-msgid "Job|with"
-msgstr ""
-
msgid "Join Zoom meeting"
msgstr ""
@@ -20762,9 +21232,6 @@ msgstr ""
msgid "Ki"
msgstr ""
-msgid "Kontra"
-msgstr ""
-
msgid "Kroki"
msgstr ""
@@ -21088,6 +21555,9 @@ msgstr ""
msgid "Learn more about Auto DevOps"
msgstr ""
+msgid "Learn more about GitLab"
+msgstr ""
+
msgid "Learn more about Needs relationships"
msgstr ""
@@ -21415,9 +21885,18 @@ msgstr ""
msgid "Licenses|Displays licenses detected in the project, based on the %{linkStart}latest successful%{linkEnd} scan"
msgstr ""
+msgid "Licenses|Drag your license file here or %{linkStart}click to upload%{linkEnd}."
+msgstr ""
+
+msgid "Licenses|Drop your license file to start the upload."
+msgstr ""
+
msgid "Licenses|Error fetching the license list. Please check your network connection and try again."
msgstr ""
+msgid "Licenses|Error: You are trying to upload something other than a file"
+msgstr ""
+
msgid "Licenses|License Compliance"
msgstr ""
@@ -21436,6 +21915,9 @@ msgstr ""
msgid "Licenses|Specified policies in this project"
msgstr ""
+msgid "Licenses|The file could not be uploaded."
+msgstr ""
+
msgid "Licenses|The license list details information about the licenses used within your project."
msgstr ""
@@ -21469,11 +21951,6 @@ msgstr ""
msgid "Limit the size of Sidekiq jobs stored in Redis."
msgstr ""
-msgid "Limited to showing %d event at most"
-msgid_plural "Limited to showing %d events at most"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Limiting mode"
msgstr ""
@@ -21483,6 +21960,9 @@ msgstr ""
msgid "Link"
msgstr ""
+msgid "Link (optional)"
+msgstr ""
+
msgid "Link Prometheus monitoring to GitLab."
msgstr ""
@@ -21519,6 +21999,9 @@ msgstr ""
msgid "Linked emails (%{email_count})"
msgstr ""
+msgid "Linked epics"
+msgstr ""
+
msgid "Linked issues"
msgstr ""
@@ -21546,6 +22029,15 @@ msgstr ""
msgid "List of all merge commits"
msgstr ""
+msgid "List of environments for this project"
+msgstr ""
+
+msgid "List of suitable GCP locations"
+msgstr ""
+
+msgid "List of users allowed to exceed the rate limit."
+msgstr ""
+
msgid "List options"
msgstr ""
@@ -21765,6 +22257,9 @@ msgstr ""
msgid "Maintenance mode"
msgstr ""
+msgid "Make adjustments to how your GitLab instance is set up."
+msgstr ""
+
msgid "Make and review changes in the browser with the Web IDE"
msgstr ""
@@ -21909,6 +22404,12 @@ msgstr ""
msgid "MarkdownEditor|Add italic text (%{modifier_key}I)"
msgstr ""
+msgid "MarkdownEditor|Add strikethrough text (%{modifierKey}⇧X)"
+msgstr ""
+
+msgid "MarkdownEditor|Add strikethrough text (%{modifier_key}⇧X)"
+msgstr ""
+
msgid "Marked For Deletion At - %{deletion_time}"
msgstr ""
@@ -22170,6 +22671,9 @@ msgstr ""
msgid "Maximum push size (MB)"
msgstr ""
+msgid "Maximum requests per 10 minutes per user"
+msgstr ""
+
msgid "Maximum requests per minute"
msgstr ""
@@ -22260,6 +22764,19 @@ msgstr ""
msgid "Members of a group may only view projects they have permission to access"
msgstr ""
+msgid "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seat in use and will be billed for the overage."
+msgid_plural "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seats in use and will be billed for the overage."
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "MembersOverage|You are about to incur additional charges"
+msgstr ""
+
+msgid "MembersOverage|Your subscription includes %d seat."
+msgid_plural "MembersOverage|Your subscription includes %d seats."
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Membership"
msgstr ""
@@ -22464,9 +22981,6 @@ msgstr ""
msgid "Merge request not merged"
msgstr ""
-msgid "Merge request pipelines 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 merge request pipelines."
-msgstr ""
-
msgid "Merge request reports"
msgstr ""
@@ -22563,13 +23077,13 @@ msgstr ""
msgid "MergeRequests|Create issue to resolve thread"
msgstr ""
-msgid "MergeRequests|Failed to squash. Should be done manually."
+msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Saving the comment failed"
+msgid "MergeRequests|Squashing failed: Squash the commits locally, resolve any conflicts, then push the branch."
msgstr ""
-msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
+msgid "MergeRequests|Squashing not allowed: This project doesn't allow you to squash commits when merging."
msgstr ""
msgid "MergeRequests|Thread stays resolved"
@@ -23410,6 +23924,18 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "MrList|Assigned to %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from assignee %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from reviewer %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Review requested from %{name}, go to their profile."
+msgstr ""
+
msgid "Multi-project"
msgstr ""
@@ -23443,7 +23969,7 @@ msgstr ""
msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "My Awesome Group"
+msgid "My awesome group"
msgstr ""
msgid "My company or team"
@@ -24065,9 +24591,6 @@ msgstr ""
msgid "No available branches"
msgstr ""
-msgid "No available groups to fork the project."
-msgstr ""
-
msgid "No branches found"
msgstr ""
@@ -24278,6 +24801,9 @@ msgstr ""
msgid "No ref selected"
msgstr ""
+msgid "No regions configured"
+msgstr ""
+
msgid "No related merge requests found."
msgstr ""
@@ -25082,6 +25608,9 @@ msgstr ""
msgid "Only reCAPTCHA v2 is supported:"
msgstr ""
+msgid "Only required if not using role instance credentials."
+msgstr ""
+
msgid "Only use lowercase letters, numbers, and underscores."
msgstr ""
@@ -25106,9 +25635,6 @@ msgstr ""
msgid "Open a CLI and connect to the cluster you want to install the agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
-msgid "Open epics"
-msgstr ""
-
msgid "Open errors"
msgstr ""
@@ -25148,7 +25674,7 @@ msgstr ""
msgid "Opened issues"
msgstr ""
-msgid "OpenedNDaysAgo|Opened"
+msgid "OpenedNDaysAgo|Created"
msgstr ""
msgid "Opens in a new window"
@@ -25193,9 +25719,6 @@ msgstr ""
msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
-msgid "Optional."
-msgstr ""
-
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
msgstr ""
@@ -25984,6 +26507,9 @@ msgstr ""
msgid "PerformanceBar|Memory"
msgstr ""
+msgid "PerformanceBar|Memory report"
+msgstr ""
+
msgid "PerformanceBar|Redis calls"
msgstr ""
@@ -26017,18 +26543,12 @@ msgstr ""
msgid "PerformanceBar|wall"
msgstr ""
-msgid "Performs a rebase but skips triggering a new pipeline"
-msgstr ""
-
msgid "Period in seconds"
msgstr ""
msgid "Permalink"
msgstr ""
-msgid "Permanently delete project"
-msgstr ""
-
msgid "Permanently remove group"
msgstr ""
@@ -26299,6 +26819,51 @@ msgstr ""
msgid "PipelineStatusTooltip|Pipeline: %{ci_status}"
msgstr ""
+msgid "PipelineWizardDefaultCommitMessage|Add %{filename}"
+msgstr ""
+
+msgid "PipelineWizardDefaultCommitMessage|Update %{filename}"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|At least one entry is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This field is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This value is not valid"
+msgstr ""
+
+msgid "PipelineWizardListWidget|add another step"
+msgstr ""
+
+msgid "PipelineWizardListWidget|remove step"
+msgstr ""
+
+msgid "PipelineWizard|Commit"
+msgstr ""
+
+msgid "PipelineWizard|Commit Message"
+msgstr ""
+
+msgid "PipelineWizard|Commit changes to your file"
+msgstr ""
+
+msgid "PipelineWizard|Commit file to Branch"
+msgstr ""
+
+msgid "PipelineWizard|Commit your new file"
+msgstr ""
+
+msgid "PipelineWizard|The file has been committed."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem committing the changes."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem while checking whether your file already exists in the specified branch."
+msgstr ""
+
msgid "Pipelines"
msgstr ""
@@ -26413,7 +26978,7 @@ msgstr ""
msgid "Pipelines|Project cache successfully reset."
msgstr ""
-msgid "Pipelines|Revoke"
+msgid "Pipelines|Revoke trigger"
msgstr ""
msgid "Pipelines|Something went wrong while cleaning runners cache."
@@ -26458,6 +27023,12 @@ msgstr ""
msgid "Pipelines|This is a child pipeline within the parent pipeline"
msgstr ""
+msgid "Pipelines|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipelines|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipelines|This pipeline will run code originating from a forked project merge request. This means that the code can potentially have security considerations like exposing CI variables."
msgstr ""
@@ -26500,9 +27071,6 @@ msgstr ""
msgid "Pipelines|Your changes have been successfully committed. Now redirecting to the new merge request page."
msgstr ""
-msgid "Pipelines|detached"
-msgstr ""
-
msgid "Pipelines|error"
msgstr ""
@@ -26512,10 +27080,13 @@ msgstr ""
msgid "Pipelines|latest"
msgstr ""
-msgid "Pipelines|stuck"
+msgid "Pipelines|merge request"
msgstr ""
-msgid "Pipelines|train"
+msgid "Pipelines|merge train"
+msgstr ""
+
+msgid "Pipelines|stuck"
msgstr ""
msgid "Pipelines|yaml invalid"
@@ -26647,6 +27218,12 @@ msgstr ""
msgid "Pipeline|This change will not change the overall test coverage if merged."
msgstr ""
+msgid "Pipeline|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipeline|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipeline|Trigger author"
msgstr ""
@@ -26671,6 +27248,12 @@ msgstr ""
msgid "Pipeline|for"
msgstr ""
+msgid "Pipeline|merge request"
+msgstr ""
+
+msgid "Pipeline|merge train"
+msgstr ""
+
msgid "Pipeline|on"
msgstr ""
@@ -26809,9 +27392,6 @@ msgstr ""
msgid "Please enter a valid time interval"
msgstr ""
-msgid "Please enter or upload a valid license."
-msgstr ""
-
msgid "Please enter your current password."
msgstr ""
@@ -26920,9 +27500,6 @@ msgstr ""
msgid "Please type %{phrase_code} to proceed or close this modal to cancel."
msgstr ""
-msgid "Please type the following to confirm:"
-msgstr ""
-
msgid "Please use this form to report to the admin users who create spam issues, comments or behave inappropriately."
msgstr ""
@@ -26950,12 +27527,27 @@ msgstr ""
msgid "Policies"
msgstr ""
+msgid "Policy '%{escalation_policy_name}' does not exist."
+msgstr ""
+
msgid "Policy management project does have any policies in %{policy_path}"
msgstr ""
msgid "Policy project doesn't exist"
msgstr ""
+msgid "PolicyRuleMultiSelect|%{firstLabel} +%{numberOfAdditionalLabels} more"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|All %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select all"
+msgstr ""
+
msgid "Polling interval multiplier"
msgstr ""
@@ -27184,6 +27776,9 @@ msgstr ""
msgid "Private projects can be created in your personal namespace with:"
msgstr ""
+msgid "Problem with %{name} command: %{message}."
+msgstr ""
+
msgid "Proceed"
msgstr ""
@@ -27658,6 +28253,9 @@ msgstr ""
msgid "Progress"
msgstr ""
+msgid "Progress tracking"
+msgstr ""
+
msgid "Project"
msgstr ""
@@ -27889,6 +28487,9 @@ msgstr ""
msgid "ProjectQualitySummary|Failure"
msgstr ""
+msgid "ProjectQualitySummary|Get insight into the overall percentage of tests in your project that succeed, fail and are skipped."
+msgstr ""
+
msgid "ProjectQualitySummary|Latest pipeline results"
msgstr ""
@@ -27907,6 +28508,12 @@ msgstr ""
msgid "ProjectQualitySummary|See project Code Coverage Statistics"
msgstr ""
+msgid "ProjectQualitySummary|Set up test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|Set up test runs (opens in a new tab)"
+msgstr ""
+
msgid "ProjectQualitySummary|Skipped"
msgstr ""
@@ -28183,13 +28790,19 @@ msgstr ""
msgid "ProjectSettings|LFS objects from this repository are available to forks. %{linkStart}How do I remove them?%{linkEnd}"
msgstr ""
+msgid "ProjectSettings|Learn about commit history."
+msgstr ""
+
+msgid "ProjectSettings|Leave empty to use default template."
+msgstr ""
+
msgid "ProjectSettings|Manage who can see the project in the public access directory."
msgstr ""
msgid "ProjectSettings|Manages large files such as audio, video, and graphics files."
msgstr ""
-msgid "ProjectSettings|Maximum 500 characters."
+msgid "ProjectSettings|Maximum %{maxLength} characters."
msgstr ""
msgid "ProjectSettings|Merge checks"
@@ -28330,6 +28943,9 @@ msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
msgstr ""
+msgid "ProjectSettings|The default template will be applied on save."
+msgstr ""
+
msgid "ProjectSettings|These checks must pass before merge requests can be merged."
msgstr ""
@@ -28384,6 +29000,9 @@ msgstr ""
msgid "ProjectSettings|What are badges?"
msgstr ""
+msgid "ProjectSettings|What are merge trains?"
+msgstr ""
+
msgid "ProjectSettings|When merge request pipelines are enabled in the CI/CD configuration file, pipelines validate the combined results of the source and target branches. %{link_start}How to configure merge request pipelines?%{link_end}"
msgstr ""
@@ -28501,6 +29120,9 @@ msgstr ""
msgid "Projects are organized into groups"
msgstr ""
+msgid "Projects are where you store your code, access issues, wiki and other features of GitLab."
+msgstr ""
+
msgid "Projects contributed to"
msgstr ""
@@ -28516,12 +29138,6 @@ msgstr ""
msgid "Projects to index"
msgstr ""
-msgid "Projects will be permanently deleted after a %{waiting_period}-day waiting period."
-msgstr ""
-
-msgid "Projects will be permanently deleted immediately."
-msgstr ""
-
msgid "Projects with critical vulnerabilities"
msgstr ""
@@ -28606,6 +29222,9 @@ msgstr ""
msgid "ProjectsNew|Import project"
msgstr ""
+msgid "ProjectsNew|Include a Getting Started README"
+msgstr ""
+
msgid "ProjectsNew|Initialize repository with a README"
msgstr ""
@@ -28621,6 +29240,9 @@ msgstr ""
msgid "ProjectsNew|Project description %{tag_start}(optional)%{tag_end}"
msgstr ""
+msgid "ProjectsNew|Recommended if you're new to GitLab"
+msgstr ""
+
msgid "ProjectsNew|Run CI/CD for external repository"
msgstr ""
@@ -29038,6 +29660,9 @@ msgstr ""
msgid "ProtectedBranch|Unprotect"
msgstr ""
+msgid "ProtectedBranch|Unprotect branch"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
@@ -29065,6 +29690,9 @@ msgstr ""
msgid "ProtectedEnvironment|Protected Environment (%{protected_environments_count})"
msgstr ""
+msgid "ProtectedEnvironment|Required approvals"
+msgstr ""
+
msgid "ProtectedEnvironment|Select an environment"
msgstr ""
@@ -29086,10 +29714,13 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|Unprotect tag"
+msgstr ""
+
msgid "ProtectedTags|default"
msgstr ""
-msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
+msgid "ProtectedTag|By default, protected tags restrict who can modify the tag."
msgstr ""
msgid "ProtectedTag|Learn more."
@@ -29152,6 +29783,9 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Public projects are an easy way to allow everyone to have read-only access."
+msgstr ""
+
msgid "Publish to status page"
msgstr ""
@@ -29308,9 +29942,6 @@ msgstr ""
msgid "QualitySummary|Project quality"
msgstr ""
-msgid "Quarters"
-msgstr ""
-
msgid "Query"
msgstr ""
@@ -29395,6 +30026,9 @@ msgstr ""
msgid "Read more about project permissions %{help_link_open}here%{help_link_close}"
msgstr ""
+msgid "Read more about related epics"
+msgstr ""
+
msgid "Read more about related issues"
msgstr ""
@@ -29425,10 +30059,7 @@ msgstr ""
msgid "Rebase source branch on the target branch."
msgstr ""
-msgid "Rebase without CI"
-msgstr ""
-
-msgid "Rebases and triggers a pipeline"
+msgid "Rebase without pipeline"
msgstr ""
msgid "Recaptcha verified?"
@@ -29479,9 +30110,6 @@ msgstr ""
msgid "Reconfigure"
msgstr ""
-msgid "Recovering projects"
-msgstr ""
-
msgid "Recovery Codes"
msgstr ""
@@ -29541,6 +30169,12 @@ msgstr ""
msgid "Regex pattern"
msgstr ""
+msgid "Region"
+msgstr ""
+
+msgid "Regions"
+msgstr ""
+
msgid "Register"
msgstr ""
@@ -29771,9 +30405,6 @@ msgstr ""
msgid "Remove all or specific reviewer(s)"
msgstr ""
-msgid "Remove approver"
-msgstr ""
-
msgid "Remove approvers"
msgstr ""
@@ -29789,6 +30420,9 @@ msgstr ""
msgid "Remove attention request"
msgstr ""
+msgid "Remove attention request(s)"
+msgstr ""
+
msgid "Remove avatar"
msgstr ""
@@ -29927,6 +30561,9 @@ msgstr ""
msgid "Removed an issue from an epic."
msgstr ""
+msgid "Removed attention from %{users_sentence}."
+msgstr ""
+
msgid "Removed attention request from @%{username}"
msgstr ""
@@ -29978,6 +30615,9 @@ msgstr ""
msgid "Removes an issue from an epic."
msgstr ""
+msgid "Removes attention from %{users_sentence}."
+msgstr ""
+
msgid "Removes parent epic %{epic_ref}."
msgstr ""
@@ -30089,6 +30729,9 @@ msgstr ""
msgid "Report abuse to admin"
msgstr ""
+msgid "Report is generating and will be sent to your email address."
+msgstr ""
+
msgid "Reported %{timeAgo} by %{reportedBy}"
msgstr ""
@@ -30378,6 +31021,15 @@ msgstr ""
msgid "Request attention"
msgstr ""
+msgid "Request attention from %{users_sentence}."
+msgstr ""
+
+msgid "Request attention from assignee or reviewer"
+msgstr ""
+
+msgid "Request attention from assignee(s) or reviewer(s)"
+msgstr ""
+
msgid "Request attention to review"
msgstr ""
@@ -30402,6 +31054,9 @@ msgstr ""
msgid "Requested %{time_ago}"
msgstr ""
+msgid "Requested attention from %{users_sentence}."
+msgstr ""
+
msgid "Requested attention from @%{username}"
msgstr ""
@@ -30616,6 +31271,9 @@ msgstr ""
msgid "Restore project"
msgstr ""
+msgid "Restoring projects"
+msgstr ""
+
msgid "Restoring the group will prevent the group, its subgroups and projects from being removed on this date."
msgstr ""
@@ -30646,6 +31304,9 @@ msgstr ""
msgid "Retry"
msgstr ""
+msgid "Retry failed jobs"
+msgstr ""
+
msgid "Retry job"
msgstr ""
@@ -30693,9 +31354,6 @@ msgstr ""
msgid "Review changes"
msgstr ""
-msgid "Review requested from %{name}"
-msgstr ""
-
msgid "Review requests for you"
msgstr ""
@@ -30860,6 +31518,9 @@ msgstr ""
msgid "Runners|Assigned Group"
msgstr ""
+msgid "Runners|Assigned Projects (%{projectCount})"
+msgstr ""
+
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30929,6 +31590,9 @@ msgstr ""
msgid "Runners|Instance"
msgstr ""
+msgid "Runners|Jobs"
+msgstr ""
+
msgid "Runners|Last contact"
msgstr ""
@@ -31022,9 +31686,6 @@ msgstr ""
msgid "Runners|Runner %{name} was deleted"
msgstr ""
-msgid "Runners|Runner ID"
-msgstr ""
-
msgid "Runners|Runner assigned to project."
msgstr ""
@@ -31172,6 +31833,9 @@ msgstr ""
msgid "Runners|stale"
msgstr ""
+msgid "Runner|This runner has not run any jobs."
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -31286,6 +31950,24 @@ msgstr ""
msgid "Saving project."
msgstr ""
+msgid "ScanResultPolicy|%{ifLabelStart}if%{ifLabelEnd} %{scanners} scan in an open merge request targeting the %{branches} branch(es) finds %{vulnerabilitiesAllowed} or more %{severities} vulnerabilities that are %{vulnerabilityStates}"
+msgstr ""
+
+msgid "ScanResultPolicy|%{thenLabelStart}Then%{thenLabelEnd} Require approval from %{approvalsRequired} of the following approvers: %{approvers}"
+msgstr ""
+
+msgid "ScanResultPolicy|add an approver"
+msgstr ""
+
+msgid "ScanResultPolicy|scanners"
+msgstr ""
+
+msgid "ScanResultPolicy|severity levels"
+msgstr ""
+
+msgid "ScanResultPolicy|vulnerability states"
+msgstr ""
+
msgid "Scanner"
msgstr ""
@@ -31418,6 +32100,9 @@ msgstr ""
msgid "Search for a user"
msgstr ""
+msgid "Search for an emoji"
+msgstr ""
+
msgid "Search for projects, issues, etc."
msgstr ""
@@ -31605,18 +32290,12 @@ msgstr ""
msgid "Secret Detection"
msgstr ""
-msgid "Secret access key"
-msgstr ""
-
msgid "Secret token"
msgstr ""
msgid "Secure token that identifies an external storage request."
msgstr ""
-msgid "SecureCodeWarrior"
-msgstr ""
-
msgid "Security"
msgstr ""
@@ -31641,9 +32320,6 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "Security training with guide and learning pathways."
-msgstr ""
-
msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
@@ -31746,7 +32422,7 @@ msgstr ""
msgid "SecurityConfiguration|Manage corpus"
msgstr ""
-msgid "SecurityConfiguration|Manage corpus files used as mutation sources in coverage fuzzing."
+msgid "SecurityConfiguration|Manage corpus files used as seed inputs with coverage-guided fuzzing."
msgstr ""
msgid "SecurityConfiguration|Manage profiles for use by DAST scans."
@@ -31812,15 +32488,15 @@ msgstr ""
msgid "SecurityOrchestration|.yaml preview"
msgstr ""
-msgid "SecurityOrchestration|Action"
-msgstr ""
-
msgid "SecurityOrchestration|Actions"
msgstr ""
msgid "SecurityOrchestration|Add rule"
msgstr ""
+msgid "SecurityOrchestration|After dismissing the alert, the information will never be shown again."
+msgstr ""
+
msgid "SecurityOrchestration|All policies"
msgstr ""
@@ -31836,7 +32512,7 @@ msgstr ""
msgid "SecurityOrchestration|Description"
msgstr ""
-msgid "SecurityOrchestration|Disabled"
+msgid "SecurityOrchestration|Don't show the alert anymore"
msgstr ""
msgid "SecurityOrchestration|Edit policy"
@@ -31845,13 +32521,13 @@ msgstr ""
msgid "SecurityOrchestration|Edit policy project"
msgstr ""
-msgid "SecurityOrchestration|Enabled"
+msgid "SecurityOrchestration|Empty policy name"
msgstr ""
-msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Enabled"
msgstr ""
-msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
msgstr ""
msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
@@ -31860,7 +32536,7 @@ msgstr ""
msgid "SecurityOrchestration|Invalid policy type"
msgstr ""
-msgid "SecurityOrchestration|Latest scan"
+msgid "SecurityOrchestration|Latest scan run against %{agent}"
msgstr ""
msgid "SecurityOrchestration|Network"
@@ -31869,15 +32545,27 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No actions defined - policy will not run."
+msgstr ""
+
+msgid "SecurityOrchestration|No description"
+msgstr ""
+
msgid "SecurityOrchestration|No rules defined - policy will not run."
msgstr ""
+msgid "SecurityOrchestration|Not enabled"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
msgid "SecurityOrchestration|Policies"
msgstr ""
+msgid "SecurityOrchestration|Policy Type"
+msgstr ""
+
msgid "SecurityOrchestration|Policy cannot be enabled for non-existing branches (%{branches})"
msgstr ""
@@ -31902,10 +32590,13 @@ msgstr ""
msgid "SecurityOrchestration|Require %{approvals} %{plural} from %{approvers} if any of the following occur:"
msgstr ""
-msgid "SecurityOrchestration|Rule"
+msgid "SecurityOrchestration|Rules"
msgstr ""
-msgid "SecurityOrchestration|Rules"
+msgid "SecurityOrchestration|Runs %{actions} and %{lastAction} scans"
+msgstr ""
+
+msgid "SecurityOrchestration|Runs a %{action} scan"
msgstr ""
msgid "SecurityOrchestration|Scan Execution"
@@ -31965,6 +32656,9 @@ msgstr ""
msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
+msgid "SecurityOrchestration|This view only shows scan results for the agent %{agent}. You can view scan results for all agents in the %{linkStart}Operational Vulnerabilities tab of the vulnerability report%{linkEnd}."
+msgstr ""
+
msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
@@ -32019,9 +32713,6 @@ msgstr ""
msgid "SecurityOrchestration|users with ids"
msgstr ""
-msgid "SecurityOrchestration|view results"
-msgstr ""
-
msgid "SecurityOrchestration|vulnerabilities"
msgstr ""
@@ -32691,22 +33382,19 @@ 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|In order to start using functions as a service, you must first install Knative on your Kubernetes cluster. %{linkStart}More information%{linkEnd}"
-msgstr ""
-
msgid "Serverless|Learn more about Serverless"
msgstr ""
msgid "Serverless|No functions available"
msgstr ""
-msgid "Serverless|Sign up for First Look"
+msgid "Serverless|Serverless was %{linkStart}deprecated%{linkEnd} in GitLab 14.3."
+msgstr ""
+
+msgid "Serverless|Serverless was %{postLinkStart}deprecated%{postLinkEnd}. But if you opt to use it, you must install Knative in your Kubernetes cluster first. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "Serverless|The deploy job has not finished."
@@ -32718,9 +33406,6 @@ 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 ""
@@ -32736,9 +33421,6 @@ msgstr ""
msgid "Service Account Key"
msgstr ""
-msgid "Service Accounts"
-msgstr ""
-
msgid "Service Accounts keys authorize GitLab to deploy your Google Cloud project"
msgstr ""
@@ -32748,10 +33430,10 @@ msgstr ""
msgid "Service Desk allows people to create issues in your GitLab instance without their own user account. It provides a unique email address for end users to create issues in a project. Replies can be sent either through the GitLab interface or by email. End users only see threads through email."
msgstr ""
-msgid "Service Usage Data"
+msgid "Service account generated successfully"
msgstr ""
-msgid "Service account generated successfully"
+msgid "Service accounts"
msgstr ""
msgid "Service ping is disabled in your configuration file, and cannot be enabled through this form."
@@ -32895,6 +33577,9 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
+msgid "Set the per-user rate limit for getting a user by ID via the API."
+msgstr ""
+
msgid "Set the per-user rate limit for notes created by web or API requests."
msgstr ""
@@ -33074,6 +33759,9 @@ msgstr ""
msgid "Shared runners details"
msgstr ""
+msgid "Shared runners enabled cannot be enabled until a valid credit card is on file"
+msgstr ""
+
msgid "Shared runners help link"
msgstr ""
@@ -33131,6 +33819,9 @@ msgstr ""
msgid "Show all issues."
msgstr ""
+msgid "Show all milestones"
+msgstr ""
+
msgid "Show all test cases."
msgstr ""
@@ -33167,6 +33858,9 @@ msgstr ""
msgid "Show file contents"
msgstr ""
+msgid "Show group milestones"
+msgstr ""
+
msgid "Show labels"
msgstr ""
@@ -33182,6 +33876,12 @@ msgstr ""
msgid "Show open epics"
msgstr ""
+msgid "Show project milestones"
+msgstr ""
+
+msgid "Show sub-group milestones"
+msgstr ""
+
msgid "Show the Closed list"
msgstr ""
@@ -33191,11 +33891,6 @@ msgstr ""
msgid "Show whitespace changes"
msgstr ""
-msgid "Showing %d event"
-msgid_plural "Showing %d events"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Showing %{conflict} between %{sourceBranch} and %{targetBranch}"
msgstr ""
@@ -33255,12 +33950,6 @@ msgstr ""
msgid "Sidebar|None"
msgstr ""
-msgid "Sidebar|Only numeral characters allowed"
-msgstr ""
-
-msgid "Sidebar|Weight"
-msgstr ""
-
msgid "Sidekiq job compression threshold (bytes)"
msgstr ""
@@ -33423,6 +34112,9 @@ msgstr ""
msgid "Slack logo"
msgstr ""
+msgid "SlackIntegration|Are you sure you want to remove this project from the Slack application?"
+msgstr ""
+
msgid "SlackIntegration|GitLab for Slack"
msgstr ""
@@ -33432,6 +34124,9 @@ msgstr ""
msgid "SlackIntegration|Project alias"
msgstr ""
+msgid "SlackIntegration|Remove project"
+msgstr ""
+
msgid "SlackIntegration|Select a GitLab project to link with your Slack workspace."
msgstr ""
@@ -33576,9 +34271,6 @@ msgstr ""
msgid "Something went wrong trying to load issue contacts."
msgstr ""
-msgid "Something went wrong when creating a work item. Please try again"
-msgstr ""
-
msgid "Something went wrong when reordering designs. Please try again"
msgstr ""
@@ -33672,9 +34364,6 @@ msgstr ""
msgid "Something went wrong while inserting your image. Please try again."
msgstr ""
-msgid "Something went wrong while merging this merge request. Please try again."
-msgstr ""
-
msgid "Something went wrong while obtaining the Let's Encrypt certificate."
msgstr ""
@@ -33996,10 +34685,10 @@ 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."
+msgid "SourcegraphAdmin|Learn more."
msgstr ""
-msgid "SourcegraphAdmin|More information"
+msgid "SourcegraphAdmin|Only public projects have code intelligence enabled and communicate with Sourcegraph."
msgstr ""
msgid "SourcegraphAdmin|Save changes"
@@ -34008,7 +34697,7 @@ msgstr ""
msgid "SourcegraphAdmin|Sourcegraph URL"
msgstr ""
-msgid "SourcegraphAdmin|e.g. https://sourcegraph.example.com"
+msgid "SourcegraphAdmin|https://sourcegraph.example.com"
msgstr ""
msgid "SourcegraphPreferences|This feature is experimental and currently limited to certain projects."
@@ -34143,6 +34832,9 @@ msgstr ""
msgid "Start date"
msgstr ""
+msgid "Start free trial"
+msgstr ""
+
msgid "Start merge train"
msgstr ""
@@ -34173,6 +34865,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started escalation for this incident."
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -34185,6 +34880,9 @@ msgstr ""
msgid "Starts at (UTC)"
msgstr ""
+msgid "Starts escalations for this incident"
+msgstr ""
+
msgid "Starts on"
msgstr ""
@@ -34446,6 +35144,9 @@ msgstr ""
msgid "Strikethrough"
msgstr ""
+msgid "Strikethrough text"
+msgstr ""
+
msgid "Subgroup information"
msgstr ""
@@ -34680,6 +35381,21 @@ msgstr ""
msgid "Subscriptions"
msgstr ""
+msgid "Subscriptions|Chat with sales"
+msgstr ""
+
+msgid "Subscriptions|Close"
+msgstr ""
+
+msgid "Subscriptions|Not ready to buy yet?"
+msgstr ""
+
+msgid "Subscriptions|Start a free trial"
+msgstr ""
+
+msgid "Subscriptions|We understand. Maybe you have some questions for our sales team, or maybe you'd like to try some of the paid features first. What would you like to do?"
+msgstr ""
+
msgid "Subscription|Your subscription for %{strong}%{namespace_name}%{strong_close} has expired and you are now on %{pricing_link_start}the GitLab Free tier%{pricing_link_end}. Don't worry, your data is safe. Get in touch with our support team (%{support_email}). They'll gladly help with your subscription renewal."
msgstr ""
@@ -34890,6 +35606,9 @@ msgstr ""
msgid "SuperSonics|Maximum users"
msgstr ""
+msgid "SuperSonics|Offline cloud"
+msgstr ""
+
msgid "SuperSonics|Paste your activation code"
msgstr ""
@@ -34956,6 +35675,12 @@ msgstr ""
msgid "SuperSonics|You do not have an active subscription"
msgstr ""
+msgid "SuperSonics|You have a future dated license"
+msgstr ""
+
+msgid "SuperSonics|You have added a license that activates on %{date}. Please see the subscription history table below for more details."
+msgstr ""
+
msgid "SuperSonics|You have successfully added a license that activates on %{date}. Please see the subscription history table below for more details."
msgstr ""
@@ -35115,6 +35840,9 @@ msgstr ""
msgid "Tag name is required"
msgstr ""
+msgid "Tag push"
+msgstr ""
+
msgid "Tag push events"
msgstr ""
@@ -35217,6 +35945,9 @@ msgstr ""
msgid "TagsPage|protected"
msgstr ""
+msgid "Take a look at the documentation to discover all of GitLab’s capabilities."
+msgstr ""
+
msgid "Target Branch"
msgstr ""
@@ -35619,6 +36350,9 @@ msgstr ""
msgid "Tests"
msgstr ""
+msgid "Text (optional)"
+msgstr ""
+
msgid "Text added to the body of all email messages. %{character_limit} character limit"
msgstr ""
@@ -35669,6 +36403,9 @@ msgstr ""
msgid "The CSV export will be created in the background. Once finished, it will be sent to %{email} in an attachment."
msgstr ""
+msgid "The CSV export you requested of all user memberships is attached to this email."
+msgstr ""
+
msgid "The GitLab subscription service (customers.gitlab.com) is currently experiencing an outage. You can monitor the status and get updates at %{linkStart}status.gitlab.com%{linkEnd}."
msgstr ""
@@ -35744,6 +36481,9 @@ 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 epic"
+msgstr ""
+
msgid "The current issue"
msgstr ""
@@ -35905,6 +36645,9 @@ msgstr ""
msgid "The latest pipeline for this merge request has failed."
msgstr ""
+msgid "The license key is invalid."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -35920,6 +36663,9 @@ msgstr ""
msgid "The license was successfully uploaded and will be active from %{starts_at}. You can see the details below."
msgstr ""
+msgid "The license you uploaded is invalid. If the issue persists, contact support at %{link}."
+msgstr ""
+
msgid "The list creation wizard is already open"
msgstr ""
@@ -36541,10 +37287,13 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} and everything this project contains. %{strongOpen}There is no going back%{strongClose}"
+msgstr ""
+
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains."
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}on %{date}%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains. %{strongOpen}There is no going back.%{strongClose}"
msgstr ""
msgid "This action will %{strongOpen}permanently remove%{strongClose} %{codeOpen}%{group}%{codeClose} %{strongOpen}immediately%{strongClose}."
@@ -36673,9 +37422,6 @@ msgstr ""
msgid "This file was modified for readability, and can't accept suggestions. Edit it directly."
msgstr ""
-msgid "This forked project has the following:"
-msgstr ""
-
msgid "This form is disabled in preview"
msgstr ""
@@ -36688,7 +37434,7 @@ msgstr ""
msgid "This group can't be removed because it is linked to a subscription. To remove this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
-msgid "This group can't be transfered because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
+msgid "This group can't be transferred because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
msgid "This group cannot be invited to a project inside a group with enforced SSO"
@@ -36715,6 +37461,9 @@ 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 incident is already escalated with '%{escalation_policy_name}'."
+msgstr ""
+
msgid "This invitation was sent to %{mail_to_invite_email}, but you are signed in as %{link_to_current_user} with email %{mail_to_current_user}."
msgstr ""
@@ -36733,9 +37482,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 merge train pipeline"
-msgstr ""
-
msgid "This is a private email address %{helpIcon} generated just for you. Anyone who has it can create issues or merge requests as if they were you. If that happens, %{resetLinkStart}reset this token%{resetLinkEnd}."
msgstr ""
@@ -36757,6 +37503,12 @@ msgstr ""
msgid "This is your current session"
msgstr ""
+msgid "This issue cannot be assigned to a confidential epic because it is public."
+msgstr ""
+
+msgid "This issue cannot be made public because it belongs to a confidential epic."
+msgstr ""
+
msgid "This issue is confidential and should only be visible to team members with at least Reporter access."
msgstr ""
@@ -36874,6 +37626,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 branch is protected from force push."
+msgstr ""
+
msgid "This merge request cannot be rebased while there are conflicts."
msgstr ""
@@ -36925,9 +37680,15 @@ msgstr ""
msgid "This pipeline was triggered by a schedule."
msgstr ""
+msgid "This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project"
msgstr ""
+msgid "This project can be restored until %{date}."
+msgstr ""
+
msgid "This project cannot be %{visibilityLevel} because the visibility of %{openShowLink}%{name}%{closeShowLink} is %{visibility}. To make this project %{visibilityLevel}, you must first %{openEditLink}change the visibility%{closeEditLink} of the parent group."
msgstr ""
@@ -36946,6 +37707,9 @@ msgstr ""
msgid "This project is %{strongStart}NOT%{strongEnd} a fork, and has the following:"
msgstr ""
+msgid "This project is %{strongStart}NOT%{strongEnd} a fork. This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -37637,6 +38401,9 @@ msgstr ""
msgid "Today"
msgstr ""
+msgid "Todos count"
+msgstr ""
+
msgid "Todos|Are you looking for things to do? Take a look at %{strongStart}%{openIssuesLinkStart}open issues%{openIssuesLinkEnd}%{strongEnd}, contribute to %{strongStart}%{mergeRequestLinkStart}a merge request%{mergeRequestLinkEnd}%{mergeRequestLinkEnd}%{strongEnd}, or mention someone in a comment to automatically assign them a new to-do item."
msgstr ""
@@ -37910,10 +38677,8 @@ msgstr ""
msgid "Trending"
msgstr ""
-msgid "Trials|%{planName} Trial %{enDash} %{num} day left"
-msgid_plural "Trials|%{planName} Trial %{enDash} %{num} days left"
-msgstr[0] ""
-msgstr[1] ""
+msgid "Trials|%{planName} Trial"
+msgstr ""
msgid "Trials|Compare all plans"
msgstr ""
@@ -37921,6 +38686,9 @@ msgstr ""
msgid "Trials|Create a new group to start your GitLab Ultimate trial."
msgstr ""
+msgid "Trials|Day %{daysUsed}/%{duration}"
+msgstr ""
+
msgid "Trials|Go back to GitLab"
msgstr ""
@@ -38170,7 +38938,7 @@ msgstr ""
msgid "URL is triggered when repository is updated"
msgstr ""
-msgid "URL must be percent-encoded if neccessary."
+msgid "URL must be percent-encoded if necessary."
msgstr ""
msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
@@ -38389,6 +39157,9 @@ msgstr ""
msgid "Unlock account"
msgstr ""
+msgid "Unlock more features with GitLab Ultimate"
+msgstr ""
+
msgid "Unlock the discussion"
msgstr ""
@@ -38452,6 +39223,9 @@ msgstr ""
msgid "Unsubscribes from this %{quick_action_target}."
msgstr ""
+msgid "Unsupported sort value."
+msgstr ""
+
msgid "Unsupported todo type passed. Supported todo types are: %{todo_types}"
msgstr ""
@@ -38680,6 +39454,9 @@ msgstr ""
msgid "UsageQuota|File attachments and smaller design graphics."
msgstr ""
+msgid "UsageQuota|From %{storage_enforcement_date} storage limits will apply to this namespace. View and manage your usage in %{strong_start}Group Settings &gt; Usage quotas%{strong_end}."
+msgstr ""
+
msgid "UsageQuota|Git repository."
msgstr ""
@@ -38740,6 +39517,9 @@ msgstr ""
msgid "UsageQuota|Storage type"
msgstr ""
+msgid "UsageQuota|Storage used"
+msgstr ""
+
msgid "UsageQuota|This is the total amount of storage used across your projects within this namespace."
msgstr ""
@@ -38935,6 +39715,12 @@ msgstr ""
msgid "Use hashed storage paths for newly created and renamed repositories. Always enabled since 13.0."
msgstr ""
+msgid "Use issue count"
+msgstr ""
+
+msgid "Use issue weight"
+msgstr ""
+
msgid "Use one line per URI"
msgstr ""
@@ -39316,6 +40102,9 @@ msgstr ""
msgid "Users"
msgstr ""
+msgid "Users API rate limit"
+msgstr ""
+
msgid "Users can launch a development environment from a GitLab browser tab when the %{linkStart}Gitpod%{linkEnd} integration is enabled."
msgstr ""
@@ -39641,6 +40430,9 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View group pipeline usage quota"
+msgstr ""
+
msgid "View incident details at"
msgstr ""
@@ -39793,6 +40585,9 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
+msgid "Vulnerability"
+msgstr ""
+
msgid "Vulnerability Report"
msgstr ""
@@ -39844,6 +40639,9 @@ msgstr ""
msgid "VulnerabilityManagement|An unverified non-confirmed finding"
msgstr ""
+msgid "VulnerabilityManagement|At least one identifier is required"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -39853,12 +40651,24 @@ msgstr ""
msgid "VulnerabilityManagement|Create Jira issue"
msgstr ""
+msgid "VulnerabilityManagement|Enter a name"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE code"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE identifier URL"
+msgstr ""
+
msgid "VulnerabilityManagement|Fetching linked Jira issues"
msgstr ""
msgid "VulnerabilityManagement|Manually add a vulnerability entry into the vulnerability report."
msgstr ""
+msgid "VulnerabilityManagement|Name is a required field"
+msgstr ""
+
msgid "VulnerabilityManagement|Needs triage"
msgstr ""
@@ -39874,6 +40684,18 @@ msgstr ""
msgid "VulnerabilityManagement|Select a method"
msgstr ""
+msgid "VulnerabilityManagement|Select a severity level"
+msgstr ""
+
+msgid "VulnerabilityManagement|Select a status"
+msgstr ""
+
+msgid "VulnerabilityManagement|Severity is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Something went wrong while creating vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -39898,6 +40720,12 @@ msgstr ""
msgid "VulnerabilityManagement|Something went wrong, could not update vulnerability state."
msgstr ""
+msgid "VulnerabilityManagement|Status is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Submit vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Summary, detailed description, steps to reproduce, etc."
msgstr ""
@@ -40093,6 +40921,9 @@ msgstr ""
msgid "WARNING:"
msgstr ""
+msgid "WARNING: This snippet contains hidden files which might be used to mask malicious behavior. Exercise caution if cloning and executing code from this snippet."
+msgstr ""
+
msgid "Wait for the file to load to copy its contents"
msgstr ""
@@ -40312,6 +41143,15 @@ msgstr ""
msgid "Webhooks|An issue is created, updated, closed, or reopened."
msgstr ""
+msgid "Webhooks|Are you sure you want to delete this group hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this project hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this webhook?"
+msgstr ""
+
msgid "Webhooks|Comments"
msgstr ""
@@ -40321,6 +41161,9 @@ msgstr ""
msgid "Webhooks|Confidential issues events"
msgstr ""
+msgid "Webhooks|Delete webhook"
+msgstr ""
+
msgid "Webhooks|Deployment events"
msgstr ""
@@ -40554,6 +41397,9 @@ msgstr ""
msgid "Wiki"
msgstr ""
+msgid "Wiki page"
+msgstr ""
+
msgid "Wiki page was successfully created."
msgstr ""
@@ -40659,7 +41505,7 @@ msgstr ""
msgid "WikiPageConflictMessage|Someone edited the page the same time you did. Please check out %{wikiLinkStart}the page%{wikiLinkEnd} and make sure your changes will not unintentionally remove theirs."
msgstr ""
-msgid "WikiPage|An error occured while trying to render the content editor. Please try again later."
+msgid "WikiPage|An error occurred while trying to render the content editor. Please try again later."
msgstr ""
msgid "WikiPage|Are you sure you want to switch back to the classic editor?"
@@ -40818,6 +41664,18 @@ msgstr ""
msgid "WorkItem|New Task"
msgstr ""
+msgid "WorkItem|Something went wrong when creating a work item. Please try again"
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching the work item. Please try again."
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching work item types. Please try again"
+msgstr ""
+
+msgid "WorkItem|Type"
+msgstr ""
+
msgid "WorkItem|Work Items"
msgstr ""
@@ -40884,7 +41742,10 @@ msgstr ""
msgid "You are about to add %{usersTag} people to the discussion. They will all receive a notification."
msgstr ""
-msgid "You are about to permanently delete this project"
+msgid "You are about to delete this forked project containing:"
+msgstr ""
+
+msgid "You are about to delete this project containing:"
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."
@@ -40905,6 +41766,9 @@ msgstr ""
msgid "You are attempting to update a file that has changed since you started editing it."
msgstr ""
+msgid "You are billed if you exceed this number. %{qsrOverageLinkStart}How does billing work?%{qsrOverageLinkEnd}"
+msgstr ""
+
msgid "You are connected to the Prometheus server, but there is currently no data to display."
msgstr ""
@@ -40962,6 +41826,9 @@ msgstr ""
msgid "You are not authorized to update this scanner profile"
msgstr ""
+msgid "You are not authorized to upload metric images"
+msgstr ""
+
msgid "You are now impersonating %{username}"
msgstr ""
@@ -41115,9 +41982,6 @@ msgstr ""
msgid "You can only upload one design when dropping onto an existing design."
msgstr ""
-msgid "You can recover this project until %{date}"
-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 ""
@@ -41166,9 +42030,6 @@ msgstr ""
msgid "You cannot write to this read-only GitLab instance."
msgstr ""
-msgid "You can’t %{tag_start}edit%{tag_end} files directly in this project. Fork this project and submit a merge request with your changes."
-msgstr ""
-
msgid "You can’t edit files directly in this project. Fork this project and submit a merge request with your changes."
msgstr ""
@@ -41321,9 +42182,6 @@ 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 set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
@@ -41354,12 +42212,6 @@ msgstr ""
msgid "You must have maintainer access to force delete a lock"
msgstr ""
-msgid "You must have permission to create a project in a group before forking."
-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 ""
@@ -41765,7 +42617,7 @@ msgstr ""
msgid "Your public email will be displayed on your public profile."
msgstr ""
-msgid "Your request for access could not be processed: %{error_meesage}"
+msgid "Your request for access could not be processed: %{error_message}"
msgstr ""
msgid "Your request for access has been queued for review."
@@ -41948,6 +42800,9 @@ msgstr ""
msgid "archived:"
msgstr ""
+msgid "artifacts"
+msgstr ""
+
msgid "assign yourself"
msgstr ""
@@ -41977,6 +42832,9 @@ msgstr[1] ""
msgid "branch name"
msgstr ""
+msgid "builds"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -42400,6 +43258,9 @@ msgstr ""
msgid "contact with same email already exists in group hierarchy"
msgstr ""
+msgid "container registry images"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -42439,6 +43300,9 @@ msgstr ""
msgid "data"
msgstr ""
+msgid "database"
+msgstr ""
+
msgid "date must not be after 9999-12-31"
msgstr ""
@@ -42462,9 +43326,6 @@ msgstr ""
msgid "design"
msgstr ""
-msgid "detached"
-msgstr ""
-
msgid "disabled"
msgstr ""
@@ -42713,7 +43574,7 @@ msgstr ""
msgid "is not a valid X509 certificate."
msgstr ""
-msgid "is not allowed for sign-up."
+msgid "is not allowed for sign-up. Please use your regular email address."
msgstr ""
msgid "is not allowed for this group."
@@ -42725,7 +43586,7 @@ msgstr ""
msgid "is not allowed since the group is not top-level group."
msgstr ""
-msgid "is not allowed."
+msgid "is not allowed. Please use your regular email address."
msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
@@ -42812,6 +43673,9 @@ msgstr ""
msgid "level: %{level}"
msgstr ""
+msgid "lfs objects"
+msgstr ""
+
msgid "limit of %{project_limit} reached"
msgstr ""
@@ -43031,6 +43895,9 @@ msgstr ""
msgid "mrWidget|Merge blocked: pipeline must succeed. It's waiting for a manual action to continue."
msgstr ""
+msgid "mrWidget|Merge blocked: pipeline must succeed. Push a commit that fixes the failure, or %{linkStart}learn about other solutions.%{linkEnd}"
+msgstr ""
+
msgid "mrWidget|Merge blocked: this merge request must be approved."
msgstr ""
@@ -43148,9 +44015,6 @@ msgstr ""
msgid "mrWidget|The changes were not merged into"
msgstr ""
-msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -43298,9 +44162,6 @@ msgstr ""
msgid "open issue"
msgstr ""
-msgid "opened %{timeAgo}"
-msgstr ""
-
msgid "or"
msgstr ""
@@ -43312,6 +44173,12 @@ msgid_plural "out of %d total tests"
msgstr[0] ""
msgstr[1] ""
+msgid "packages"
+msgstr ""
+
+msgid "pages"
+msgstr ""
+
msgid "parent"
msgid_plural "parents"
msgstr[0] ""
@@ -43461,6 +44328,9 @@ msgid_plural "replies"
msgstr[0] ""
msgstr[1] ""
+msgid "repositories"
+msgstr ""
+
msgid "repository:"
msgstr ""
@@ -43581,12 +44451,18 @@ msgstr ""
msgid "tag name"
msgstr ""
+msgid "terraform states"
+msgstr ""
+
msgid "the correct format."
msgstr ""
msgid "the file"
msgstr ""
+msgid "the following epic(s)"
+msgstr ""
+
msgid "the following issue(s)"
msgstr ""
@@ -43599,21 +44475,12 @@ msgstr ""
msgid "this document"
msgstr ""
-msgid "this issue cannot be assigned to a confidential epic since it is public"
-msgstr ""
-
-msgid "this issue cannot be made public since it belongs to a confidential epic"
-msgstr ""
-
msgid "time summary"
msgstr ""
msgid "toggle collapse"
msgstr ""
-msgid "train"
-msgstr ""
-
msgid "triggered"
msgstr ""
@@ -43742,3 +44609,6 @@ msgstr ""
msgid "{project}"
msgstr ""
+msgid "✔"
+msgstr ""
+
diff --git a/locale/ar_SA/gitlab.po b/locale/ar_SA/gitlab.po
index 5ae1000ef86..bf798585eb2 100644
--- a/locale/ar_SA/gitlab.po
+++ b/locale/ar_SA/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: ar\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2022-02-02 15:44\n"
+"PO-Revision-Date: 2022-03-01 20:38\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -202,6 +202,15 @@ msgstr[3] ""
msgstr[4] ""
msgstr[5] ""
+msgid "%d assigned issue"
+msgid_plural "%d assigned issues"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+msgstr[4] ""
+msgstr[5] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -697,8 +706,35 @@ msgstr[3] ""
msgstr[4] ""
msgstr[5] ""
-msgid "%d vulnerability updated"
-msgid_plural "%d vulnerabilities updated"
+msgid "%d vulnerability set to confirmed"
+msgid_plural "%d vulnerabilities set to confirmed"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+msgstr[4] ""
+msgstr[5] ""
+
+msgid "%d vulnerability set to dismissed"
+msgid_plural "%d vulnerabilities set to dismissed"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+msgstr[4] ""
+msgstr[5] ""
+
+msgid "%d vulnerability set to needs triage"
+msgid_plural "%d vulnerabilities set to needs triage"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+msgstr[4] ""
+msgstr[5] ""
+
+msgid "%d vulnerability set to resolved"
+msgid_plural "%d vulnerabilities set to resolved"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
@@ -814,6 +850,12 @@ msgstr[5] ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{completed} of %{total} issues closed"
+msgstr ""
+
+msgid "%{completed} of %{total} weight completed"
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -1186,6 +1228,9 @@ msgstr ""
msgid "%{openedIssues} open, %{closedIssues} closed"
msgstr ""
+msgid "%{percentage}%% issues closed"
+msgstr ""
+
msgid "%{percentage}%% weight completed"
msgstr ""
@@ -1675,6 +1720,9 @@ msgstr[3] ""
msgstr[4] ""
msgstr[5] ""
+msgid "- of - issues closed"
+msgstr ""
+
msgid "- of - weight completed"
msgstr ""
@@ -1909,7 +1957,7 @@ msgstr ""
msgid "1000+"
msgstr ""
-msgid "192.168.0.0/24"
+msgid "192.168.0.0/24 or 2001:0DB8:1234::/48"
msgstr ""
msgid "1st contribution!"
@@ -2221,13 +2269,13 @@ msgstr ""
msgid "AWS Access Key"
msgstr ""
-msgid "AWS Access Key. Only required if not using role instance credentials"
+msgid "AWS Secret Access Key"
msgstr ""
-msgid "AWS Secret Access Key"
+msgid "AWS access key ID (Optional)"
msgstr ""
-msgid "AWS Secret Access Key. Only required if not using role instance credentials"
+msgid "AWS secret access key (Optional)"
msgstr ""
msgid "AWS service error: %{error}"
@@ -2287,9 +2335,6 @@ msgstr ""
msgid "Access granted"
msgstr ""
-msgid "Access key ID"
-msgstr ""
-
msgid "Access requests"
msgstr ""
@@ -2464,7 +2509,7 @@ msgstr ""
msgid "Activity"
msgstr ""
-msgid "Activity|An error occured while retrieving activity. Reload the page to try again."
+msgid "Activity|An error occurred while retrieving activity. Reload the page to try again."
msgstr ""
msgid "Add"
@@ -2503,6 +2548,9 @@ msgstr ""
msgid "Add a %{type}"
msgstr ""
+msgid "Add a GCP region"
+msgstr ""
+
msgid "Add a GPG key"
msgstr ""
@@ -2554,6 +2602,9 @@ msgstr ""
msgid "Add a numbered list"
msgstr ""
+msgid "Add a related epic"
+msgstr ""
+
msgid "Add a related issue"
msgstr ""
@@ -2668,6 +2719,9 @@ msgstr ""
msgid "Add or subtract spent time"
msgstr ""
+msgid "Add people"
+msgstr ""
+
msgid "Add previously merged commits"
msgstr ""
@@ -2734,6 +2788,9 @@ msgstr ""
msgid "Add webhook"
msgstr ""
+msgid "Add your team members and others to GitLab."
+msgstr ""
+
msgid "Add/remove"
msgstr ""
@@ -3556,12 +3613,6 @@ msgstr ""
msgid "AdvancedSearch|Reindex required"
msgstr ""
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. Permanently deleting this project will %{strongStart}immediately delete%{strongEnd} its repositories and %{strongStart}all related resources%{strongEnd}, including issues, merge requests etc."
-msgstr ""
-
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. You will lose this project's repository and %{strongStart}all related resources%{strongEnd}, including issues and merge requests."
-msgstr ""
-
msgid "After a successful password update you will be redirected to login screen."
msgstr ""
@@ -3592,6 +3643,9 @@ msgstr ""
msgid "Akismet helps prevent the creation of spam issues in public projects."
msgstr ""
+msgid "Alert"
+msgstr ""
+
msgid "AlertManagement|Acknowledged"
msgstr ""
@@ -3964,9 +4018,6 @@ msgstr ""
msgid "All environments"
msgstr ""
-msgid "All epics"
-msgstr ""
-
msgid "All groups and projects"
msgstr ""
@@ -4711,8 +4762,11 @@ msgstr ""
msgid "ApplicationSettings|Approve users in the pending approval status?"
msgstr ""
-msgid "ApplicationSettings|By making this change, you will automatically approve %d user with the pending approval status."
-msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users with the pending approval status."
+msgid "ApplicationSettings|Approve users who are pending approval?"
+msgstr ""
+
+msgid "ApplicationSettings|By making this change, you will automatically approve %d user who is pending approval."
+msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users who are pending approval."
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
@@ -4720,7 +4774,7 @@ msgstr[3] ""
msgstr[4] ""
msgstr[5] ""
-msgid "ApplicationSettings|By making this change, you will automatically approve all users in pending approval status."
+msgid "ApplicationSettings|By making this change, you will automatically approve all users who are pending approval."
msgstr ""
msgid "ApplicationSettings|Denied domains for sign-ups"
@@ -5146,10 +5200,10 @@ msgstr ""
msgid "Archiving the project will make it entirely read-only. It is hidden from the dashboard and doesn't show up in searches. %{strong_start}The repository cannot be committed to, and no issues, comments, or other entities can be created.%{strong_end} %{link_start}Learn more.%{link_end}"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to delete this project?"
+msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
+msgid "Are you absolutely sure?"
msgstr ""
msgid "Are you sure that you want to archive this project?"
@@ -5185,12 +5239,18 @@ msgstr ""
msgid "Are you sure you want to delete this SSH key?"
msgstr ""
+msgid "Are you sure you want to delete this comment?"
+msgstr ""
+
msgid "Are you sure you want to delete this deploy key?"
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 label?"
+msgstr ""
+
msgid "Are you sure you want to delete this pipeline schedule?"
msgstr ""
@@ -5206,9 +5266,6 @@ msgstr ""
msgid "Are you sure you want to discard your changes?"
msgstr ""
-msgid "Are you sure you want to erase this build?"
-msgstr ""
-
msgid "Are you sure you want to import %d repository?"
msgid_plural "Are you sure you want to import %d repositories?"
msgstr[0] ""
@@ -5260,6 +5317,9 @@ msgstr ""
msgid "Are you sure you want to remove this list?"
msgstr ""
+msgid "Are you sure you want to remove this nickname?"
+msgstr ""
+
msgid "Are you sure you want to reset the health check token?"
msgstr ""
@@ -5272,10 +5332,10 @@ 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?"
+msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
msgstr ""
-msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
+msgid "Are you sure you want to revoke this project access token? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to stop this environment?"
@@ -5422,9 +5482,6 @@ msgstr ""
msgid "Assigned to %{assignee_name}"
msgstr ""
-msgid "Assigned to %{name}"
-msgstr ""
-
msgid "Assigned to me"
msgstr ""
@@ -5497,6 +5554,9 @@ msgstr[5] ""
msgid "Attaching the file failed."
msgstr ""
+msgid "Attention"
+msgstr ""
+
msgid "Audit Events"
msgstr ""
@@ -5659,6 +5719,12 @@ msgstr ""
msgid "Authorized applications (%{size})"
msgstr ""
+msgid "AuthorizedApplication|Are you sure you want to revoke this application?"
+msgstr ""
+
+msgid "AuthorizedApplication|Revoke application"
+msgstr ""
+
msgid "Authors: %{authors}"
msgstr ""
@@ -6868,6 +6934,9 @@ msgstr ""
msgid "CICDAnalytics|Shared Runners Usage"
msgstr ""
+msgid "CICDAnalytics|Shared runner pipeline minute duration by month"
+msgstr ""
+
msgid "CICDAnalytics|Shared runner usage"
msgstr ""
@@ -7009,6 +7078,9 @@ msgstr ""
msgid "Can create groups:"
msgstr ""
+msgid "Can not delete primary training"
+msgstr ""
+
msgid "Can't apply as the source branch was deleted."
msgstr ""
@@ -7342,9 +7414,6 @@ msgstr ""
msgid "Changing any setting here requires an application restart"
msgstr ""
-msgid "Changing group URL can have unintended side effects."
-msgstr ""
-
msgid "Charts can't be displayed as the request for data has timed out. %{documentationLink}"
msgstr ""
@@ -7432,9 +7501,6 @@ msgstr ""
msgid "Checking branch availability..."
msgstr ""
-msgid "Checking group URL availability..."
-msgstr ""
-
msgid "Checking group path availability..."
msgstr ""
@@ -7936,6 +8002,9 @@ msgstr ""
msgid "Clear recent searches"
msgstr ""
+msgid "Clear repository checks"
+msgstr ""
+
msgid "Clear search"
msgstr ""
@@ -8068,9 +8137,6 @@ msgstr ""
msgid "Closed MRs"
msgstr ""
-msgid "Closed epics"
-msgstr ""
-
msgid "Closed issues"
msgstr ""
@@ -8107,13 +8173,13 @@ msgstr ""
msgid "Cluster level"
msgstr ""
-msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
+msgid "Cluster type must be specified for Stages::ClusterEndpointInserter"
msgstr ""
msgid "ClusterAgents|%{name} successfully deleted"
msgstr ""
-msgid "ClusterAgents|%{number} of %{total} Agents"
+msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
@@ -8155,6 +8221,15 @@ msgstr ""
msgid "ClusterAgents|Agent never connected to GitLab"
msgstr ""
+msgid "ClusterAgents|Agent version mismatch"
+msgstr ""
+
+msgid "ClusterAgents|Agent version mismatch and update"
+msgstr ""
+
+msgid "ClusterAgents|Agent version update required"
+msgstr ""
+
msgid "ClusterAgents|All"
msgstr ""
@@ -8179,7 +8254,7 @@ msgstr ""
msgid "ClusterAgents|Configuration"
msgstr ""
-msgid "ClusterAgents|Connect a cluster through the Agent"
+msgid "ClusterAgents|Connect a cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connect existing cluster"
@@ -8188,13 +8263,13 @@ msgstr ""
msgid "ClusterAgents|Connect with a certificate"
msgstr ""
-msgid "ClusterAgents|Connect with agent"
+msgid "ClusterAgents|Connect with an agent"
msgstr ""
msgid "ClusterAgents|Connect with the GitLab Agent"
msgstr ""
-msgid "ClusterAgents|Connect your cluster through the Agent"
+msgid "ClusterAgents|Connect your cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connected"
@@ -8254,7 +8329,10 @@ msgstr ""
msgid "ClusterAgents|How to register an agent?"
msgstr ""
-msgid "ClusterAgents|Install new Agent"
+msgid "ClusterAgents|How to update an agent?"
+msgstr ""
+
+msgid "ClusterAgents|Install a new agent"
msgstr ""
msgid "ClusterAgents|Last connected %{timeAgo}."
@@ -8281,7 +8359,7 @@ msgstr ""
msgid "ClusterAgents|Never connected"
msgstr ""
-msgid "ClusterAgents|No Agents"
+msgid "ClusterAgents|No agents"
msgstr ""
msgid "ClusterAgents|No clusters connected through cluster certificates"
@@ -8341,6 +8419,9 @@ msgstr ""
msgid "ClusterAgents|The agent has not been connected in a long time. There might be a connectivity issue. Last contact was %{timeAgo}."
msgstr ""
+msgid "ClusterAgents|The agent version do not match each other across your cluster's pods. This can happen when a new agent version was just deployed and Kubernetes is shutting down the old pods."
+msgstr ""
+
msgid "ClusterAgents|The recommended installation method includes the token. If you want to follow the advanced installation method provided in the docs, make sure you save the token value before you close this window."
msgstr ""
@@ -8392,6 +8473,9 @@ msgstr ""
msgid "ClusterAgents|You will need to create a token to connect to your agent"
msgstr ""
+msgid "ClusterAgents|Your agent version is out of sync with your GitLab version (v%{version}), which might cause compatibility problems. Update the agent installed on your cluster to the most recent version."
+msgstr ""
+
msgid "ClusterAgents|Your instance doesn't have the %{linkStart}GitLab Agent Server (KAS)%{linkEnd} set up. Ask a GitLab Administrator to install it."
msgstr ""
@@ -9268,9 +9352,6 @@ msgstr ""
msgid "Comma-separated list of email addresses."
msgstr ""
-msgid "Comma-separated list of users allowed to exceed the rate limit."
-msgstr ""
-
msgid "Comma-separated, e.g. '1.1.1.1, 2.2.2.0/24'"
msgstr ""
@@ -9601,6 +9682,12 @@ msgstr ""
msgid "Confidential"
msgstr ""
+msgid "Confidential issue"
+msgstr ""
+
+msgid "Confidential note"
+msgstr ""
+
msgid "Confidentiality"
msgstr ""
@@ -9634,6 +9721,9 @@ msgstr ""
msgid "Configure Dependency Scanning in `.gitlab-ci.yml`, creating this file if it does not already exist"
msgstr ""
+msgid "Configure GitLab"
+msgstr ""
+
msgid "Configure GitLab runners to start using the Web Terminal. %{helpStart}Learn more.%{helpEnd}"
msgstr ""
@@ -9682,6 +9772,15 @@ msgstr ""
msgid "Configure pipelines to deploy web apps, backend services, APIs and static resources to Google Cloud"
msgstr ""
+msgid "Configure region"
+msgstr ""
+
+msgid "Configure region for environment"
+msgstr ""
+
+msgid "Configure regions"
+msgstr ""
+
msgid "Configure repository mirroring."
msgstr ""
@@ -9715,6 +9814,9 @@ msgstr ""
msgid "Configure which lists are shown for anyone who visits this board"
msgstr ""
+msgid "Configure your environments to be deployed to specific geographical regions"
+msgstr ""
+
msgid "Confirm"
msgstr ""
@@ -10429,10 +10531,10 @@ msgstr ""
msgid "CorpusManagement|Actions"
msgstr ""
-msgid "CorpusManagement|Corpus are used in fuzz testing as mutation source to Improve future testing."
+msgid "CorpusManagement|Corpus file"
msgstr ""
-msgid "CorpusManagement|Corpus file"
+msgid "CorpusManagement|Corpus files are used in coverage-guided fuzz testing as seed inputs to improve testing."
msgstr ""
msgid "CorpusManagement|Corpus files must be in *.zip format. Maximum 5 GB"
@@ -10486,6 +10588,9 @@ msgstr ""
msgid "Could not apply %{name} command."
msgstr ""
+msgid "Could not apply %{name} command. %{message}."
+msgstr ""
+
msgid "Could not authorize chat nickname. Try again!"
msgstr ""
@@ -10636,6 +10741,9 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
+msgid "Create a group"
+msgstr ""
+
msgid "Create a merge request"
msgstr ""
@@ -10660,6 +10768,9 @@ msgstr ""
msgid "Create a personal access token on your account to pull or push via %{protocol}."
msgstr ""
+msgid "Create a project"
+msgstr ""
+
msgid "Create an account using:"
msgstr ""
@@ -11023,6 +11134,9 @@ msgstr ""
msgid "Creation date"
msgstr ""
+msgid "Creator"
+msgstr ""
+
msgid "Credentials"
msgstr ""
@@ -11035,9 +11149,15 @@ msgstr ""
msgid "CredentialsInventory|Personal Access Tokens"
msgstr ""
+msgid "CredentialsInventory|Project Access Tokens"
+msgstr ""
+
msgid "CredentialsInventory|SSH Keys"
msgstr ""
+msgid "Credit card required to be on file in order to create a pipeline"
+msgstr ""
+
msgid "Credit card:"
msgstr ""
@@ -11221,9 +11341,6 @@ msgstr ""
msgid "Customer relations"
msgstr ""
-msgid "Customizable by an administrator."
-msgstr ""
-
msgid "Customizable by owners."
msgstr ""
@@ -11353,30 +11470,18 @@ msgstr ""
msgid "CycleAnalytics|%{selectedLabelsCount} selected (%{maxLabels} max)"
msgstr ""
-msgid "CycleAnalytics|%{stageCount} stages selected"
-msgstr ""
-
-msgid "CycleAnalytics|All stages"
-msgstr ""
-
-msgid "CycleAnalytics|Average days to completion"
+msgid "CycleAnalytics|Average time to completion"
msgstr ""
msgid "CycleAnalytics|Date"
msgstr ""
-msgid "CycleAnalytics|Days to completion"
-msgstr ""
-
msgid "CycleAnalytics|Display chart filters"
msgstr ""
msgid "CycleAnalytics|Lead Time for Changes"
msgstr ""
-msgid "CycleAnalytics|No stages selected"
-msgstr ""
-
msgid "CycleAnalytics|Number of tasks"
msgstr ""
@@ -11413,18 +11518,30 @@ msgstr ""
msgid "CycleAnalytics|Showing data for group '%{groupName}' from %{createdAfter} to %{createdBefore}"
msgstr ""
-msgid "CycleAnalytics|Stages"
+msgid "CycleAnalytics|Stage time: %{title}"
msgstr ""
msgid "CycleAnalytics|Tasks by type"
msgstr ""
-msgid "CycleAnalytics|The average time spent in the selected stage for the items that were completed on each date. Data limited to the last 500 items."
+msgid "CycleAnalytics|The average time items spent in this stage. Data limited to items completed within this date range."
msgstr ""
msgid "CycleAnalytics|The given date range is larger than 180 days"
msgstr ""
+msgid "CycleAnalytics|The total time items spent across each value stream stage. Data limited to items completed within this date range."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Stage time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Total time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|Total time"
+msgstr ""
+
msgid "CycleAnalytics|Type of work"
msgstr ""
@@ -11437,9 +11554,6 @@ msgstr ""
msgid "CycleAnalytics|project dropdown filter"
msgstr ""
-msgid "CycleAnalytics|stage dropdown"
-msgstr ""
-
msgid "DAG visualization requires at least 3 dependent jobs."
msgstr ""
@@ -11539,10 +11653,16 @@ msgstr ""
msgid "DastProfiles|AJAX spider"
msgstr ""
+msgid "DastProfiles|API"
+msgstr ""
+
+msgid "DastProfiles|API endpoint URL"
+msgstr ""
+
msgid "DastProfiles|Active"
msgstr ""
-msgid "DastProfiles|Additional request headers (Optional)"
+msgid "DastProfiles|Additional request headers (optional)"
msgstr ""
msgid "DastProfiles|Are you sure you want to delete this profile?"
@@ -11557,6 +11677,9 @@ msgstr ""
msgid "DastProfiles|Branch missing"
msgstr ""
+msgid "DastProfiles|Choose a scan method"
+msgstr ""
+
msgid "DastProfiles|Could not create the scanner profile. Please try again."
msgstr ""
@@ -11626,7 +11749,13 @@ msgstr ""
msgid "DastProfiles|Excluded URLs"
msgstr ""
-msgid "DastProfiles|Excluded URLs (Optional)"
+msgid "DastProfiles|Excluded URLs (optional)"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths (optional)"
msgstr ""
msgid "DastProfiles|Hide debug messages"
@@ -11683,9 +11812,6 @@ msgstr ""
msgid "DastProfiles|Request headers"
msgstr ""
-msgid "DastProfiles|Rest API"
-msgstr ""
-
msgid "DastProfiles|Run the AJAX spider, in addition to the traditional spider, to crawl the target site."
msgstr ""
@@ -11695,6 +11821,9 @@ msgstr ""
msgid "DastProfiles|Save profile"
msgstr ""
+msgid "DastProfiles|Scan method"
+msgstr ""
+
msgid "DastProfiles|Scan mode"
msgstr ""
@@ -11773,12 +11902,24 @@ msgstr ""
msgid "DastProfiles|Website"
msgstr ""
+msgid "DastProfiles|What does each method do?"
+msgstr ""
+
msgid "DastProfiles|You can either choose a passive scan or validate the target site from the site profile management page. %{docsLinkStart}Learn more about site validation.%{docsLinkEnd}"
msgstr ""
msgid "DastProfiles|You cannot run an active scan against an unvalidated site."
msgstr ""
+msgid "DastProfiles|folder/dast_example.har or https://example.com/dast_example.har"
+msgstr ""
+
+msgid "DastProfiles|folder/example.postman_collection.json or https://example.com/"
+msgstr ""
+
+msgid "DastProfiles|folder/openapi.json or https://example.com/openapi.json"
+msgstr ""
+
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
@@ -11890,6 +12031,9 @@ msgstr ""
msgid "DatadogIntegration|API URL"
msgstr ""
+msgid "DatadogIntegration|Custom tags in Datadog. Enter one tag per line in the %{codeOpen}key:value%{codeClose} format. %{linkOpen}How do I use tags?%{linkClose}"
+msgstr ""
+
msgid "DatadogIntegration|Environment"
msgstr ""
@@ -11908,12 +12052,18 @@ msgstr ""
msgid "DatadogIntegration|Tag all data from this GitLab instance in Datadog. Useful when managing several self-managed deployments."
msgstr ""
+msgid "DatadogIntegration|Tags"
+msgstr ""
+
msgid "DatadogIntegration|The Datadog site to send data to. To send data to the EU site, use %{codeOpen}datadoghq.eu%{codeClose}."
msgstr ""
msgid "DatadogIntegration|Trace your GitLab pipelines with Datadog."
msgstr ""
+msgid "DatadogIntegration|have an invalid format"
+msgstr ""
+
msgid "Datasource name not found"
msgstr ""
@@ -11923,9 +12073,6 @@ msgstr ""
msgid "Date merged"
msgstr ""
-msgid "Date picker"
-msgstr ""
-
msgid "Date range"
msgstr ""
@@ -12079,9 +12226,6 @@ msgstr ""
msgid "Definition"
msgstr ""
-msgid "Delayed Project Deletion (%{adjourned_deletion})"
-msgstr ""
-
msgid "DelayedJobs|Are you sure you want to run %{jobName} immediately? Otherwise this job will run automatically after its timer finishes."
msgstr ""
@@ -12160,10 +12304,10 @@ msgstr ""
msgid "Delete pipeline"
msgstr ""
-msgid "Delete project"
+msgid "Delete pipeline schedule"
msgstr ""
-msgid "Delete project. Are you ABSOLUTELY SURE?"
+msgid "Delete project"
msgstr ""
msgid "Delete row"
@@ -12193,6 +12337,9 @@ msgstr ""
msgid "Delete this epic and all descendants?"
msgstr ""
+msgid "Delete this project"
+msgstr ""
+
msgid "Delete user list"
msgstr ""
@@ -12475,6 +12622,12 @@ msgstr ""
msgid "Deploy to..."
msgstr ""
+msgid "DeployBoards|To see deployment progress for your environments, make sure you are deploying to %{codeStart}$KUBE_NAMESPACE%{codeEnd} and annotating with %{codeStart}app.gitlab.com/app=$CI_PROJECT_PATH_SLUG%{codeEnd} and %{codeStart}app.gitlab.com/env=$CI_ENVIRONMENT_SLUG%{codeEnd}."
+msgstr ""
+
+msgid "DeployBoard|Kubernetes Pods"
+msgstr ""
+
msgid "DeployFreeze|Add a freeze period to prevent unintended releases during a period of time for a given environment. You must update the deployment jobs in %{filename} according to the deploy freezes added here. %{freeze_period_link_start}Learn more.%{freeze_period_link_end}"
msgstr ""
@@ -12559,9 +12712,6 @@ msgstr ""
msgid "DeployTokens|Active Deploy Tokens (%{active_tokens})"
msgstr ""
-msgid "DeployTokens|Allows read and write access to registry images."
-msgstr ""
-
msgid "DeployTokens|Allows read and write access to the package registry."
msgstr ""
@@ -12574,6 +12724,9 @@ msgstr ""
msgid "DeployTokens|Allows read-only access to the repository."
msgstr ""
+msgid "DeployTokens|Allows write access to registry images."
+msgstr ""
+
msgid "DeployTokens|Copy deploy token"
msgstr ""
@@ -12667,12 +12820,57 @@ msgstr ""
msgid "Deploying to AWS is easy with GitLab"
msgstr ""
+msgid "Deployment"
+msgstr ""
+
msgid "Deployment Frequency"
msgstr ""
+msgid "Deployment Target|Project deployment target (optional)"
+msgstr ""
+
+msgid "Deployment Target|Select the deployment target"
+msgstr ""
+
msgid "Deployment frequency"
msgstr ""
+msgid "DeploymentTarget|GitLab Pages"
+msgstr ""
+
+msgid "DeploymentTarget|Heroku"
+msgstr ""
+
+msgid "DeploymentTarget|Infrastructure provider (Terraform, Cloudformation, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Kubernetes (GKE, EKS, OpenShift, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Managed container runtime (Fargate, Cloud Run, DigitalOcean App)"
+msgstr ""
+
+msgid "DeploymentTarget|Mobile app store"
+msgstr ""
+
+msgid "DeploymentTarget|No deployment planned"
+msgstr ""
+
+msgid "DeploymentTarget|Other hosting service"
+msgstr ""
+
+msgid "DeploymentTarget|Registry (package or container)"
+msgstr ""
+
+msgid "DeploymentTarget|Self-managed container runtime (Podman, Docker Swarm, Docker Compose)"
+msgstr ""
+
+msgid "DeploymentTarget|Serverless backend (Lambda, Cloud functions)"
+msgstr ""
+
+msgid "DeploymentTarget|Virtual machine (for example, EC2)"
+msgstr ""
+
msgid "Deployments"
msgstr ""
@@ -12715,6 +12913,9 @@ msgstr ""
msgid "Deployment|This deployment was created using the API"
msgstr ""
+msgid "Deployment|Triggerer"
+msgstr ""
+
msgid "Deployment|Waiting"
msgstr ""
@@ -12742,6 +12943,18 @@ msgstr ""
msgid "Deprecated API rate limits"
msgstr ""
+msgid "Deprecations|Feature deprecation and removal"
+msgstr ""
+
+msgid "Deprecations|For information on a possible replacement %{epicStart} learn more about Opstrace %{epicEnd}."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7 and are %{epicStart} scheduled for removal %{epicEnd} in GitLab 15.0."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7, and are %{removal_link_start} scheduled for removal %{link_end} in GitLab 15.0. For information on a possible replacement, %{opstrace_link_start} learn more about Opstrace %{link_end}."
+msgstr ""
+
msgid "Deprioritize label"
msgstr ""
@@ -12991,10 +13204,10 @@ msgstr ""
msgid "DevopsAdoption|At least one deploy"
msgstr ""
-msgid "DevopsAdoption|At least one issue opened"
+msgid "DevopsAdoption|At least one issue created"
msgstr ""
-msgid "DevopsAdoption|At least one merge request opened"
+msgid "DevopsAdoption|At least one merge request created"
msgstr ""
msgid "DevopsAdoption|At least one pipeline successfully run"
@@ -13207,6 +13420,9 @@ msgstr ""
msgid "Direct member"
msgstr ""
+msgid "Direct members"
+msgstr ""
+
msgid "Direct non-authenticated users to this page."
msgstr ""
@@ -13327,6 +13543,9 @@ msgstr[3] ""
msgstr[4] ""
msgstr[5] ""
+msgid "Dismiss Alert"
+msgstr ""
+
msgid "Dismiss merge request promotion"
msgstr ""
@@ -13354,9 +13573,15 @@ msgstr ""
msgid "Display alerts from all configured monitoring tools."
msgstr ""
+msgid "Display milestones"
+msgstr ""
+
msgid "Display name"
msgstr ""
+msgid "Display progress of child issues"
+msgstr ""
+
msgid "Display rendered file"
msgstr ""
@@ -13462,6 +13687,9 @@ msgstr ""
msgid "Download image"
msgstr ""
+msgid "Download payload"
+msgstr ""
+
msgid "Download raw data (.csv)"
msgstr ""
@@ -13639,6 +13867,9 @@ msgstr ""
msgid "Edit in Web IDE"
msgstr ""
+msgid "Edit in pipeline editor"
+msgstr ""
+
msgid "Edit in single-file editor"
msgstr ""
@@ -13681,6 +13912,9 @@ msgstr ""
msgid "Edit your most recent comment in a thread (from an empty textarea)"
msgstr ""
+msgid "Edit, lint, and visualize your pipeline."
+msgstr ""
+
msgid "Edited"
msgstr ""
@@ -14122,6 +14356,9 @@ msgstr ""
msgid "Enforce two-factor authentication for all user sign-ins."
msgstr ""
+msgid "Enhance security by storing service account keys in secret managers - learn more about %{docLinkStart}secret management with GitLab%{docLinkEnd}"
+msgstr ""
+
msgid "Ensure connectivity is available from the GitLab server to the Prometheus server"
msgstr ""
@@ -14182,6 +14419,9 @@ 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 following to confirm:"
+msgstr ""
+
msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
@@ -14716,9 +14956,6 @@ 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 ""
@@ -14854,6 +15091,9 @@ msgstr ""
msgid "Errors:"
msgstr ""
+msgid "Escalate this incident"
+msgstr ""
+
msgid "Escalation Policies"
msgstr ""
@@ -14866,6 +15106,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy"
+msgstr ""
+
msgid "Escalation policy:"
msgstr ""
@@ -15121,6 +15364,9 @@ msgstr ""
msgid "Existing sign in methods may be removed"
msgstr ""
+msgid "Exit."
+msgstr ""
+
msgid "Expand"
msgstr ""
@@ -15217,6 +15463,9 @@ msgstr ""
msgid "Explore public groups"
msgstr ""
+msgid "Explore public projects"
+msgstr ""
+
msgid "Explore snippets"
msgstr ""
@@ -15382,7 +15631,7 @@ msgstr[3] ""
msgstr[4] ""
msgstr[5] ""
-msgid "Failed to assign a reviewer because no user was found."
+msgid "Failed to assign a reviewer because no user was specified."
msgstr ""
msgid "Failed to assign a user because no user was found."
@@ -15448,10 +15697,10 @@ msgstr ""
msgid "Failed to find import label for Jira import."
msgstr ""
-msgid "Failed to generate export, please try again later."
+msgid "Failed to find users for %{missing}"
msgstr ""
-msgid "Failed to generate report, please try again after sometime"
+msgid "Failed to generate export, please try again later."
msgstr ""
msgid "Failed to get ref."
@@ -15550,6 +15799,9 @@ msgstr ""
msgid "Failed to remove a to-do item for the design."
msgstr ""
+msgid "Failed to remove attention because no user was found."
+msgstr ""
+
msgid "Failed to remove mirror."
msgstr ""
@@ -15562,6 +15814,9 @@ msgstr ""
msgid "Failed to remove user key."
msgstr ""
+msgid "Failed to request attention because no user was found."
+msgstr ""
+
msgid "Failed to reset key. Please try again."
msgstr ""
@@ -15643,6 +15898,9 @@ msgstr ""
msgid "Feature Flags"
msgstr ""
+msgid "Feature deprecation and removal"
+msgstr ""
+
msgid "Feature flag status"
msgstr ""
@@ -16144,7 +16402,7 @@ msgstr ""
msgid "For each job, re-use the project workspace. If the workspace doesn't exist, use %{code_open}git clone%{code_close}."
msgstr ""
-msgid "For example, the application using the token or the purpose of the token."
+msgid "For example, the application using the token or the purpose of the token. Do not give sensitive information for the name of the token, as it will be visible to all %{resource_type} members."
msgstr ""
msgid "For files larger than this limit, only index the file name. The file content is neither indexed nor searchable."
@@ -16228,9 +16486,6 @@ msgstr ""
msgid "ForkProject|Select a namespace"
msgstr ""
-msgid "ForkProject|Select a namespace to fork the project"
-msgstr ""
-
msgid "ForkProject|The project can be accessed by any logged in user."
msgstr ""
@@ -16327,6 +16582,9 @@ msgstr ""
msgid "Full name"
msgstr ""
+msgid "GCP region configured"
+msgstr ""
+
msgid "GPG Key ID:"
msgstr ""
@@ -16507,6 +16765,9 @@ msgstr ""
msgid "Geo|Failed"
msgstr ""
+msgid "Geo|Filter Geo sites"
+msgstr ""
+
msgid "Geo|Filter by name"
msgstr ""
@@ -16918,6 +17179,12 @@ msgstr ""
msgid "GitLab Issue"
msgstr ""
+msgid "GitLab KAS"
+msgstr ""
+
+msgid "GitLab Memberships CSV Export"
+msgstr ""
+
msgid "GitLab Pages"
msgstr ""
@@ -16966,6 +17233,9 @@ 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 free to use. Many features for larger teams are part of our %{link_start}paid products%{link_end}. You can try Ultimate for free without any obligation or payment details."
+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 ""
@@ -17092,7 +17362,7 @@ msgstr ""
msgid "GitLabPages|When enabled, all attempts to visit your website through HTTP are automatically redirected to HTTPS using a response with status code 301. Requires a valid certificate for all domains. %{docs_link_start}Learn more.%{link_end}"
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. %{docs_link_start}Learn more.%{link_end}"
+msgid "GitLabPages|When using Pages under the general domain of a GitLab instance (%{pages_host}), you cannot use HTTPS with subdomains of subdomains. If your namespace or groupname contains a dot, it does not work. This is a limitation of the HTTP Over TLS protocol. HTTP pages work if you don't redirect HTTP to HTTPS. %{docs_link_start}Learn more.%{link_end}"
msgstr ""
msgid "GitLabPages|With GitLab Pages you can host your static website directly from your GitLab repository. %{docs_link_start}Learn more.%{link_end}"
@@ -17269,9 +17539,6 @@ msgstr ""
msgid "Go to find file"
msgstr ""
-msgid "Go to fork"
-msgstr ""
-
msgid "Go to issue boards"
msgstr ""
@@ -17479,9 +17746,6 @@ msgstr ""
msgid "Group Hooks"
msgstr ""
-msgid "Group ID"
-msgstr ""
-
msgid "Group Owner must have signed in with SAML before enabling Group Managed Accounts"
msgstr ""
@@ -17509,9 +17773,6 @@ msgstr ""
msgid "Group by"
msgstr ""
-msgid "Group description"
-msgstr ""
-
msgid "Group description (optional)"
msgstr ""
@@ -17626,7 +17887,7 @@ msgstr ""
msgid "Group: %{name}"
msgstr ""
-msgid "GroupActivityMetrics|Issues opened"
+msgid "GroupActivityMetrics|Issues created"
msgstr ""
msgid "GroupActivityMetrics|Last 90 days"
@@ -17635,7 +17896,7 @@ msgstr ""
msgid "GroupActivityMetrics|Members added"
msgstr ""
-msgid "GroupActivityMetrics|Merge Requests opened"
+msgid "GroupActivityMetrics|Merge Requests created"
msgstr ""
msgid "GroupActivityMetrics|Recent activity"
@@ -17926,6 +18187,9 @@ msgstr ""
msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
+msgid "GroupSettings|Choose a group path that does not start with a dash or end with a period. It can also contain alphanumeric characters and underscores."
+msgstr ""
+
msgid "GroupSettings|Compliance frameworks"
msgstr ""
@@ -17959,7 +18223,7 @@ msgstr ""
msgid "GroupSettings|If not specified at the group or instance level, the default is %{default_initial_branch_name}. Does not affect existing repositories."
msgstr ""
-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."
+msgid "GroupSettings|If the parent group's visibility is lower than the group's current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility."
msgstr ""
msgid "GroupSettings|New runners registration token has been generated!"
@@ -18076,7 +18340,10 @@ msgstr ""
msgid "Groups and projects"
msgstr ""
-msgid "Groups and subgroups"
+msgid "Groups are a great way to organize projects and people."
+msgstr ""
+
+msgid "Groups are the best way to manage projects and members."
msgstr ""
msgid "Groups to synchronize"
@@ -18187,13 +18454,16 @@ msgstr ""
msgid "GroupsTree|Are you sure you want to leave the \"%{fullName}\" group?"
msgstr ""
-msgid "GroupsTree|Edit group"
+msgid "GroupsTree|Delete"
+msgstr ""
+
+msgid "GroupsTree|Edit"
msgstr ""
msgid "GroupsTree|Failed to leave the group. Please make sure you are not the only owner."
msgstr ""
-msgid "GroupsTree|Leave this group"
+msgid "GroupsTree|Leave group"
msgstr ""
msgid "GroupsTree|Loading groups"
@@ -18205,9 +18475,57 @@ msgstr ""
msgid "GroupsTree|No groups or projects matched your search"
msgstr ""
+msgid "GroupsTree|Options"
+msgstr ""
+
msgid "GroupsTree|Search by name"
msgstr ""
+msgid "Groups|Avatar will be removed. Are you sure?"
+msgstr ""
+
+msgid "Groups|Changing group URL can have unintended side effects."
+msgstr ""
+
+msgid "Groups|Checking group URL availability..."
+msgstr ""
+
+msgid "Groups|Enter a descriptive name for your group."
+msgstr ""
+
+msgid "Groups|Group ID"
+msgstr ""
+
+msgid "Groups|Group URL"
+msgstr ""
+
+msgid "Groups|Group avatar"
+msgstr ""
+
+msgid "Groups|Group description (optional)"
+msgstr ""
+
+msgid "Groups|Group name"
+msgstr ""
+
+msgid "Groups|Group path is available."
+msgstr ""
+
+msgid "Groups|Group path is unavailable. Path has been replaced with a suggested available path."
+msgstr ""
+
+msgid "Groups|Learn more"
+msgstr ""
+
+msgid "Groups|Must start with letter, digit, emoji, or underscore. Can also contain periods, dashes, spaces, and parentheses."
+msgstr ""
+
+msgid "Groups|Remove avatar"
+msgstr ""
+
+msgid "Groups|Save changes"
+msgstr ""
+
msgid "Guideline"
msgstr ""
@@ -18217,6 +18535,9 @@ msgstr ""
msgid "HAR file path or URL"
msgstr ""
+msgid "HTTP Archive (HAR)"
+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 ""
@@ -18625,6 +18946,9 @@ msgstr ""
msgid "INFO: Your SSH key is expiring soon. Please generate a new key."
msgstr ""
+msgid "IP"
+msgstr ""
+
msgid "IP Address"
msgstr ""
@@ -18661,6 +18985,9 @@ msgstr ""
msgid "IdentityVerification|Verify your identity"
msgstr ""
+msgid "IdentityVerification|You can always verify your account at a later time to create a group."
+msgstr ""
+
msgid "If any indexed field exceeds this limit, it is truncated to this number of characters. The rest of the content is neither indexed nor searchable. This does not apply to repository and wiki indexing. For unlimited characters, set this to 0."
msgstr ""
@@ -18718,6 +19045,9 @@ msgstr ""
msgid "If you add %{codeStart}needs%{codeEnd} to jobs in your pipeline you'll be able to view the %{codeStart}needs%{codeEnd} relationships between jobs in this tab as a %{linkStart}Directed Acyclic Graph (DAG)%{linkEnd}."
msgstr ""
+msgid "If you are added to a project, it will be displayed here."
+msgstr ""
+
msgid "If you did not initiate these sign-in attempts, please reach out to your administrator or enable two-factor authentication (2FA) on your account."
msgstr ""
@@ -19036,12 +19366,24 @@ msgstr ""
msgid "InProductMarketing|3 ways to dive into GitLab CI/CD"
msgstr ""
+msgid "InProductMarketing|A single application eliminates complex integrations, data chokepoints, and toolchain maintenance, resulting in greater productivity and lower cost."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features, build more efficiently, strengthen security and compliance."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features."
+msgstr ""
+
msgid "InProductMarketing|Actually, GitLab makes the team work (better)"
msgstr ""
msgid "InProductMarketing|And finally %{deploy_link} a Python application."
msgstr ""
+msgid "InProductMarketing|And many more..."
+msgstr ""
+
msgid "InProductMarketing|Are your runners ready?"
msgstr ""
@@ -19060,15 +19402,33 @@ msgstr ""
msgid "InProductMarketing|Blog"
msgstr ""
+msgid "InProductMarketing|Break down silos to coordinate seamlessly across development, operations, and security with a consistent experience across the development lifecycle."
+msgstr ""
+
+msgid "InProductMarketing|Burn up/down charts"
+msgstr ""
+
msgid "InProductMarketing|By enabling code owners and required merge approvals the right person will review the right MR. This is a win-win: cleaner code and a more efficient review process."
msgstr ""
msgid "InProductMarketing|Click on the number below that corresponds with your answer — 1 being very difficult, 5 being very easy."
msgstr ""
+msgid "InProductMarketing|Code owners"
+msgstr ""
+
msgid "InProductMarketing|Code owners and required merge approvals are part of the paid tiers of GitLab. You can start a free 30-day trial of GitLab Ultimate and enable these features in less than 5 minutes with no credit card required."
msgstr ""
+msgid "InProductMarketing|Code review analytics"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration across stages in GitLab"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration made easy"
+msgstr ""
+
msgid "InProductMarketing|Create a custom CI runner with just a few clicks"
msgstr ""
@@ -19078,12 +19438,21 @@ msgstr ""
msgid "InProductMarketing|Create a project in GitLab in 5 minutes"
msgstr ""
+msgid "InProductMarketing|Create well-defined workflows by using scoped labels on issues, merge requests, and epics. Labels with the same scope cannot be used together, which prevents conflicts."
+msgstr ""
+
msgid "InProductMarketing|Create your first project!"
msgstr ""
+msgid "InProductMarketing|Define who owns specific files or directories, so the right reviewers are suggested when a merge request introduces changes to those files."
+msgstr ""
+
msgid "InProductMarketing|Deliver Better Products Faster"
msgstr ""
+msgid "InProductMarketing|Dependency scanning"
+msgstr ""
+
msgid "InProductMarketing|Did you know teams that use GitLab are far more efficient?"
msgstr ""
@@ -19093,15 +19462,27 @@ msgstr ""
msgid "InProductMarketing|Dig in and create a project and a repo"
msgstr ""
+msgid "InProductMarketing|Discover Premium & Ultimate"
+msgstr ""
+
+msgid "InProductMarketing|Discover Premium & Ultimate."
+msgstr ""
+
msgid "InProductMarketing|Do you have a minute?"
msgstr ""
msgid "InProductMarketing|Do you have a teammate who would be perfect for this task?"
msgstr ""
+msgid "InProductMarketing|Dynamic application security testing"
+msgstr ""
+
msgid "InProductMarketing|Easy"
msgstr ""
+msgid "InProductMarketing|Epics"
+msgstr ""
+
msgid "InProductMarketing|Expand your DevOps journey with a free GitLab trial"
msgstr ""
@@ -19123,9 +19504,15 @@ msgstr ""
msgid "InProductMarketing|Feel the need for speed?"
msgstr ""
+msgid "InProductMarketing|Find and fix bottlenecks in your code review process by understanding how long open merge requests have been in review."
+msgstr ""
+
msgid "InProductMarketing|Find out how your teams are really doing"
msgstr ""
+msgid "InProductMarketing|Find out if your external libraries are safe. Run dependency scanning jobs that check for known vulnerabilities in your external libraries."
+msgstr ""
+
msgid "InProductMarketing|Follow our steps"
msgstr ""
@@ -19162,6 +19549,9 @@ msgstr ""
msgid "InProductMarketing|GitLab is better with teammates to help out!"
msgstr ""
+msgid "InProductMarketing|GitLab is infrastructure agnostic (supporting GCP, AWS, Azure, OpenShift, VMWare, On Prem, Bare Metal, and more), offering a consistent workflow experience – irrespective of the environment."
+msgstr ""
+
msgid "InProductMarketing|GitLab provides static application security testing (SAST), dynamic application security testing (DAST), container scanning, and dependency scanning to help you deliver secure applications along with license compliance."
msgstr ""
@@ -19252,21 +19642,36 @@ msgstr ""
msgid "InProductMarketing|It's also possible to simply %{external_repo_link} in order to take advantage of GitLab's CI/CD."
msgstr ""
+msgid "InProductMarketing|Keep your code quality high by defining who should approve merge requests and how many approvals are required."
+msgstr ""
+
msgid "InProductMarketing|Launch GitLab CI/CD in 20 minutes or less"
msgstr ""
+msgid "InProductMarketing|Lower cost of development"
+msgstr ""
+
+msgid "InProductMarketing|Make it easier to collaborate on high-level ideas by grouping related issues in an epic."
+msgstr ""
+
msgid "InProductMarketing|Making the switch? It's easier than you think to import your projects into GitLab. Move %{github_link}, or import something %{bitbucket_link}."
msgstr ""
msgid "InProductMarketing|Master the art of importing!"
msgstr ""
+msgid "InProductMarketing|Merge request approval rule"
+msgstr ""
+
msgid "InProductMarketing|Move on to easily creating a Pages website %{ci_template_link}"
msgstr ""
msgid "InProductMarketing|Multiple owners, confusing workstreams? We've got you covered"
msgstr ""
+msgid "InProductMarketing|Multiple required approvers"
+msgstr ""
+
msgid "InProductMarketing|Need an alternative to importing?"
msgstr ""
@@ -19279,18 +19684,33 @@ msgstr ""
msgid "InProductMarketing|Our tool brings all the things together"
msgstr ""
+msgid "InProductMarketing|Protect your web application by using DAST to examine for vulnerabilities in deployed environments."
+msgstr ""
+
msgid "InProductMarketing|Rapid development, simplified"
msgstr ""
msgid "InProductMarketing|Reduce Security & Compliance Risk"
msgstr ""
+msgid "InProductMarketing|Require multiple approvers on a merge request, so you know it's in good shape before it's merged."
+msgstr ""
+
+msgid "InProductMarketing|Roadmaps"
+msgstr ""
+
+msgid "InProductMarketing|Scoped labels"
+msgstr ""
+
msgid "InProductMarketing|Security that's integrated into your development lifecycle"
msgstr ""
msgid "InProductMarketing|Sometimes you're not ready to make a full transition to a new tool. If you're not ready to fully commit, %{mirroring_link} gives you a safe way to try out GitLab in parallel with your current tool."
msgstr ""
+msgid "InProductMarketing|Speed. Efficiency. Trust."
+msgstr ""
+
msgid "InProductMarketing|Spin up an autoscaling runner in GitLab"
msgstr ""
@@ -19300,6 +19720,9 @@ msgstr ""
msgid "InProductMarketing|Start a Self-Managed trial"
msgstr ""
+msgid "InProductMarketing|Start a free trial"
+msgstr ""
+
msgid "InProductMarketing|Start a free trial of GitLab Ultimate – no credit card required"
msgstr ""
@@ -19366,6 +19789,9 @@ msgstr ""
msgid "InProductMarketing|To understand and get the most out of GitLab, start at the beginning and %{project_link}. In GitLab, repositories are part of a project, so after you've created your project you can go ahead and %{repo_link}."
msgstr ""
+msgid "InProductMarketing|Track completed issues in a chart, so you can see how a milestone is progressing at a glance."
+msgstr ""
+
msgid "InProductMarketing|Try GitLab Ultimate for free"
msgstr ""
@@ -19402,6 +19828,9 @@ msgstr ""
msgid "InProductMarketing|Very easy"
msgstr ""
+msgid "InProductMarketing|Visualize your epics and milestones in a timeline."
+msgstr ""
+
msgid "InProductMarketing|Want to host GitLab on your servers?"
msgstr ""
@@ -19423,6 +19852,9 @@ msgstr ""
msgid "InProductMarketing|YouTube"
msgstr ""
+msgid "InProductMarketing|Your software, deployed your way"
+msgstr ""
+
msgid "InProductMarketing|Your teams can be more efficient"
msgstr ""
@@ -19543,9 +19975,18 @@ msgstr ""
msgid "IncidentManagement|No incidents to display."
msgstr ""
+msgid "IncidentManagement|None"
+msgstr ""
+
msgid "IncidentManagement|Open"
msgstr ""
+msgid "IncidentManagement|Page your team with escalation policies"
+msgstr ""
+
+msgid "IncidentManagement|Paged"
+msgstr ""
+
msgid "IncidentManagement|Published"
msgstr ""
@@ -19555,6 +19996,9 @@ msgstr ""
msgid "IncidentManagement|Severity"
msgstr ""
+msgid "IncidentManagement|Status"
+msgstr ""
+
msgid "IncidentManagement|There are no closed incidents"
msgstr ""
@@ -19573,6 +20017,9 @@ msgstr ""
msgid "IncidentManagement|Unpublished"
msgstr ""
+msgid "IncidentManagement|Use escalation policies to automatically page your team when incidents are created."
+msgstr ""
+
msgid "IncidentSettings|Activate \"time to SLA\" countdown timer"
msgstr ""
@@ -19618,7 +20065,10 @@ msgstr ""
msgid "Incidents"
msgstr ""
-msgid "Incidents|Add a URL"
+msgid "Incidents|Add image details"
+msgstr ""
+
+msgid "Incidents|Add text or a link to display with your image. If you don't add either, the file name displays instead."
msgstr ""
msgid "Incidents|Drop or %{linkStart}upload%{linkEnd} a metric screenshot to attach it to the incident"
@@ -19633,10 +20083,10 @@ msgstr ""
msgid "Incidents|There was an issue loading metric images."
msgstr ""
-msgid "Incidents|There was an issue uploading your image."
+msgid "Incidents|There was an issue updating your image."
msgstr ""
-msgid "Incidents|You can optionally add a URL to link users to the original graph."
+msgid "Incidents|There was an issue uploading your image."
msgstr ""
msgid "Incident|Alert details"
@@ -19645,9 +20095,18 @@ msgstr ""
msgid "Incident|Are you sure you wish to delete this image?"
msgstr ""
+msgid "Incident|Delete image"
+msgstr ""
+
msgid "Incident|Deleting %{filename}"
msgstr ""
+msgid "Incident|Edit image text or link"
+msgstr ""
+
+msgid "Incident|Editing %{filename}"
+msgstr ""
+
msgid "Incident|Metrics"
msgstr ""
@@ -19921,12 +20380,18 @@ msgstr ""
msgid "Integrations|Branches for which notifications are to be sent"
msgstr ""
+msgid "Integrations|Clear if using a self-signed certificate."
+msgstr ""
+
msgid "Integrations|Comment detail:"
msgstr ""
msgid "Integrations|Comment settings:"
msgstr ""
+msgid "Integrations|Connection details"
+msgstr ""
+
msgid "Integrations|Connection failed. Please check your settings."
msgstr ""
@@ -19951,6 +20416,9 @@ msgstr ""
msgid "Integrations|Enable GitLab.com slash commands in a Slack workspace."
msgstr ""
+msgid "Integrations|Enable SSL verification"
+msgstr ""
+
msgid "Integrations|Enable comments"
msgstr ""
@@ -20029,6 +20497,9 @@ msgstr ""
msgid "Integrations|Return to GitLab for Jira"
msgstr ""
+msgid "Integrations|SSL verification"
+msgstr ""
+
msgid "Integrations|Save settings?"
msgstr ""
@@ -20074,9 +20545,6 @@ msgstr ""
msgid "Integrations|Use default settings"
msgstr ""
-msgid "Integrations|When you mention a Jira issue in a commit or merge request, GitLab creates a remote link and comment (if enabled)."
-msgstr ""
-
msgid "Integrations|You can now close this window and return to the GitLab for Jira application."
msgstr ""
@@ -20101,9 +20569,6 @@ msgstr ""
msgid "Integrations|can't exceed %{recipients_limit}"
msgstr ""
-msgid "Interactive developer security education."
-msgstr ""
-
msgid "Interactive mode"
msgstr ""
@@ -20593,6 +21058,9 @@ msgstr ""
msgid "IssueAnalytics|Assignees"
msgstr ""
+msgid "IssueAnalytics|Created by"
+msgstr ""
+
msgid "IssueAnalytics|Due date"
msgstr ""
@@ -20605,9 +21073,6 @@ msgstr ""
msgid "IssueAnalytics|Milestone"
msgstr ""
-msgid "IssueAnalytics|Opened by"
-msgstr ""
-
msgid "IssueAnalytics|Status"
msgstr ""
@@ -20731,10 +21196,10 @@ msgstr ""
msgid "IssuesAnalytics|Avg/Month:"
msgstr ""
-msgid "IssuesAnalytics|Issues opened"
+msgid "IssuesAnalytics|Issues created"
msgstr ""
-msgid "IssuesAnalytics|Issues opened per month"
+msgid "IssuesAnalytics|Issues created per month"
msgstr ""
msgid "IssuesAnalytics|Last 12 months"
@@ -20761,6 +21226,9 @@ msgstr ""
msgid "It looks like you have some draft commits in this branch."
msgstr ""
+msgid "It looks like you're attempting to activate your subscription. Use %{a_start}the Subscription page%{a_end} instead."
+msgstr ""
+
msgid "It may be several days before you see feature usage data."
msgstr ""
@@ -20989,6 +21457,9 @@ msgstr ""
msgid "JiraConnect|You can now close this window and return to Jira."
msgstr ""
+msgid "JiraConnect|You don't have permission to create branches for this project. Select a different project or contact the project owner for access. %{linkStart}Learn more.%{linkEnd}"
+msgstr ""
+
msgid "JiraRequest|A connection error occurred while connecting to Jira. Try your request again."
msgstr ""
@@ -21037,13 +21508,13 @@ msgstr ""
msgid "JiraService|Define the type of Jira issue to create from a vulnerability."
msgstr ""
-msgid "JiraService|Displaying Jira issues while leaving the GitLab issue functionality enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
+msgid "JiraService|Displaying Jira issues while leaving GitLab issues also enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
msgstr ""
-msgid "JiraService|Enable Jira issues"
+msgid "JiraService|Enable Jira issue creation from vulnerabilities"
msgstr ""
-msgid "JiraService|Enable Jira issues creation from vulnerabilities"
+msgid "JiraService|Enable Jira issues"
msgstr ""
msgid "JiraService|Enable Jira transitions"
@@ -21160,16 +21631,19 @@ msgstr ""
msgid "JiraService|View Jira issues in GitLab"
msgstr ""
-msgid "JiraService|Warning: All GitLab users that have access to this GitLab project are able to view all issues from the Jira project specified below."
+msgid "JiraService|Warning: All GitLab users with access to this GitLab project can view all issues from the Jira project you select."
msgstr ""
msgid "JiraService|Web URL"
msgstr ""
-msgid "JiraService|Work on Jira issues without leaving GitLab. Adds a Jira menu to access your list of Jira issues and view any issue as read-only."
+msgid "JiraService|When a Jira issue is mentioned in a commit or merge request, a remote link and comment (if enabled) will be created."
+msgstr ""
+
+msgid "JiraService|Work on Jira issues without leaving GitLab. Add a Jira menu to access a read-only list of your Jira issues."
msgstr ""
-msgid "JiraService|You need to configure Jira before enabling this integration. For more details, read the %{jira_doc_link_start}Jira integration documentation%{link_end}."
+msgid "JiraService|You must configure Jira before enabling this integration. %{jira_doc_link_start}Learn more.%{link_end}"
msgstr ""
msgid "Job"
@@ -21181,9 +21655,6 @@ msgstr ""
msgid "Job Failed #%{build_id}"
msgstr ""
-msgid "Job ID"
-msgstr ""
-
msgid "Job artifact"
msgstr ""
@@ -21250,9 +21721,27 @@ msgstr ""
msgid "Jobs|You're about to retry a job that failed because it attempted to deploy code that is older than the latest deployment. Retrying this job could result in overwriting the environment with the older source code."
msgstr ""
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source} into %{target}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{ref}"
+msgstr ""
+
+msgid "Job|Are you sure you want to erase this job log and artifacts?"
+msgstr ""
+
msgid "Job|Browse"
msgstr ""
+msgid "Job|Cancel"
+msgstr ""
+
msgid "Job|Complete Raw"
msgstr ""
@@ -21262,6 +21751,9 @@ msgstr ""
msgid "Job|Erase job log and artifacts"
msgstr ""
+msgid "Job|Finished at"
+msgstr ""
+
msgid "Job|Job artifacts"
msgstr ""
@@ -21274,7 +21766,7 @@ msgstr ""
msgid "Job|Keep"
msgstr ""
-msgid "Job|Pipeline"
+msgid "Job|Retry"
msgstr ""
msgid "Job|Scroll to bottom"
@@ -21286,6 +21778,9 @@ msgstr ""
msgid "Job|Show complete raw"
msgstr ""
+msgid "Job|Status"
+msgstr ""
+
msgid "Job|The artifacts were removed"
msgstr ""
@@ -21313,21 +21808,12 @@ msgstr ""
msgid "Job|delayed"
msgstr ""
-msgid "Job|for"
-msgstr ""
-
-msgid "Job|into"
-msgstr ""
-
msgid "Job|manual"
msgstr ""
msgid "Job|triggered"
msgstr ""
-msgid "Job|with"
-msgstr ""
-
msgid "Join Zoom meeting"
msgstr ""
@@ -21430,9 +21916,6 @@ msgstr ""
msgid "Ki"
msgstr ""
-msgid "Kontra"
-msgstr ""
-
msgid "Kroki"
msgstr ""
@@ -21760,6 +22243,9 @@ msgstr ""
msgid "Learn more about Auto DevOps"
msgstr ""
+msgid "Learn more about GitLab"
+msgstr ""
+
msgid "Learn more about Needs relationships"
msgstr ""
@@ -22111,9 +22597,18 @@ msgstr ""
msgid "Licenses|Displays licenses detected in the project, based on the %{linkStart}latest successful%{linkEnd} scan"
msgstr ""
+msgid "Licenses|Drag your license file here or %{linkStart}click to upload%{linkEnd}."
+msgstr ""
+
+msgid "Licenses|Drop your license file to start the upload."
+msgstr ""
+
msgid "Licenses|Error fetching the license list. Please check your network connection and try again."
msgstr ""
+msgid "Licenses|Error: You are trying to upload something other than a file"
+msgstr ""
+
msgid "Licenses|License Compliance"
msgstr ""
@@ -22132,6 +22627,9 @@ msgstr ""
msgid "Licenses|Specified policies in this project"
msgstr ""
+msgid "Licenses|The file could not be uploaded."
+msgstr ""
+
msgid "Licenses|The license list details information about the licenses used within your project."
msgstr ""
@@ -22165,15 +22663,6 @@ msgstr ""
msgid "Limit the size of Sidekiq jobs stored in Redis."
msgstr ""
-msgid "Limited to showing %d event at most"
-msgid_plural "Limited to showing %d events at most"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-msgstr[3] ""
-msgstr[4] ""
-msgstr[5] ""
-
msgid "Limiting mode"
msgstr ""
@@ -22183,6 +22672,9 @@ msgstr ""
msgid "Link"
msgstr ""
+msgid "Link (optional)"
+msgstr ""
+
msgid "Link Prometheus monitoring to GitLab."
msgstr ""
@@ -22219,6 +22711,9 @@ msgstr ""
msgid "Linked emails (%{email_count})"
msgstr ""
+msgid "Linked epics"
+msgstr ""
+
msgid "Linked issues"
msgstr ""
@@ -22246,6 +22741,15 @@ msgstr ""
msgid "List of all merge commits"
msgstr ""
+msgid "List of environments for this project"
+msgstr ""
+
+msgid "List of suitable GCP locations"
+msgstr ""
+
+msgid "List of users allowed to exceed the rate limit."
+msgstr ""
+
msgid "List options"
msgstr ""
@@ -22465,6 +22969,9 @@ msgstr ""
msgid "Maintenance mode"
msgstr ""
+msgid "Make adjustments to how your GitLab instance is set up."
+msgstr ""
+
msgid "Make and review changes in the browser with the Web IDE"
msgstr ""
@@ -22609,6 +23116,12 @@ msgstr ""
msgid "MarkdownEditor|Add italic text (%{modifier_key}I)"
msgstr ""
+msgid "MarkdownEditor|Add strikethrough text (%{modifierKey}⇧X)"
+msgstr ""
+
+msgid "MarkdownEditor|Add strikethrough text (%{modifier_key}⇧X)"
+msgstr ""
+
msgid "Marked For Deletion At - %{deletion_time}"
msgstr ""
@@ -22870,6 +23383,9 @@ msgstr ""
msgid "Maximum push size (MB)"
msgstr ""
+msgid "Maximum requests per 10 minutes per user"
+msgstr ""
+
msgid "Maximum requests per minute"
msgstr ""
@@ -22960,6 +23476,27 @@ msgstr ""
msgid "Members of a group may only view projects they have permission to access"
msgstr ""
+msgid "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seat in use and will be billed for the overage."
+msgid_plural "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seats in use and will be billed for the overage."
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+msgstr[4] ""
+msgstr[5] ""
+
+msgid "MembersOverage|You are about to incur additional charges"
+msgstr ""
+
+msgid "MembersOverage|Your subscription includes %d seat."
+msgid_plural "MembersOverage|Your subscription includes %d seats."
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+msgstr[4] ""
+msgstr[5] ""
+
msgid "Membership"
msgstr ""
@@ -23164,9 +23701,6 @@ msgstr ""
msgid "Merge request not merged"
msgstr ""
-msgid "Merge request pipelines 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 merge request pipelines."
-msgstr ""
-
msgid "Merge request reports"
msgstr ""
@@ -23263,13 +23797,13 @@ msgstr ""
msgid "MergeRequests|Create issue to resolve thread"
msgstr ""
-msgid "MergeRequests|Failed to squash. Should be done manually."
+msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Saving the comment failed"
+msgid "MergeRequests|Squashing failed: Squash the commits locally, resolve any conflicts, then push the branch."
msgstr ""
-msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
+msgid "MergeRequests|Squashing not allowed: This project doesn't allow you to squash commits when merging."
msgstr ""
msgid "MergeRequests|Thread stays resolved"
@@ -24118,6 +24652,18 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "MrList|Assigned to %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from assignee %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from reviewer %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Review requested from %{name}, go to their profile."
+msgstr ""
+
msgid "Multi-project"
msgstr ""
@@ -24151,7 +24697,7 @@ msgstr ""
msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "My Awesome Group"
+msgid "My awesome group"
msgstr ""
msgid "My company or team"
@@ -24781,9 +25327,6 @@ msgstr ""
msgid "No available branches"
msgstr ""
-msgid "No available groups to fork the project."
-msgstr ""
-
msgid "No branches found"
msgstr ""
@@ -24994,6 +25537,9 @@ msgstr ""
msgid "No ref selected"
msgstr ""
+msgid "No regions configured"
+msgstr ""
+
msgid "No related merge requests found."
msgstr ""
@@ -25822,6 +26368,9 @@ msgstr ""
msgid "Only reCAPTCHA v2 is supported:"
msgstr ""
+msgid "Only required if not using role instance credentials."
+msgstr ""
+
msgid "Only use lowercase letters, numbers, and underscores."
msgstr ""
@@ -25846,9 +26395,6 @@ msgstr ""
msgid "Open a CLI and connect to the cluster you want to install the agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
-msgid "Open epics"
-msgstr ""
-
msgid "Open errors"
msgstr ""
@@ -25888,7 +26434,7 @@ msgstr ""
msgid "Opened issues"
msgstr ""
-msgid "OpenedNDaysAgo|Opened"
+msgid "OpenedNDaysAgo|Created"
msgstr ""
msgid "Opens in a new window"
@@ -25933,9 +26479,6 @@ msgstr ""
msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
-msgid "Optional."
-msgstr ""
-
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
msgstr ""
@@ -26728,6 +27271,9 @@ msgstr ""
msgid "PerformanceBar|Memory"
msgstr ""
+msgid "PerformanceBar|Memory report"
+msgstr ""
+
msgid "PerformanceBar|Redis calls"
msgstr ""
@@ -26761,18 +27307,12 @@ msgstr ""
msgid "PerformanceBar|wall"
msgstr ""
-msgid "Performs a rebase but skips triggering a new pipeline"
-msgstr ""
-
msgid "Period in seconds"
msgstr ""
msgid "Permalink"
msgstr ""
-msgid "Permanently delete project"
-msgstr ""
-
msgid "Permanently remove group"
msgstr ""
@@ -27043,6 +27583,51 @@ msgstr ""
msgid "PipelineStatusTooltip|Pipeline: %{ci_status}"
msgstr ""
+msgid "PipelineWizardDefaultCommitMessage|Add %{filename}"
+msgstr ""
+
+msgid "PipelineWizardDefaultCommitMessage|Update %{filename}"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|At least one entry is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This field is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This value is not valid"
+msgstr ""
+
+msgid "PipelineWizardListWidget|add another step"
+msgstr ""
+
+msgid "PipelineWizardListWidget|remove step"
+msgstr ""
+
+msgid "PipelineWizard|Commit"
+msgstr ""
+
+msgid "PipelineWizard|Commit Message"
+msgstr ""
+
+msgid "PipelineWizard|Commit changes to your file"
+msgstr ""
+
+msgid "PipelineWizard|Commit file to Branch"
+msgstr ""
+
+msgid "PipelineWizard|Commit your new file"
+msgstr ""
+
+msgid "PipelineWizard|The file has been committed."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem committing the changes."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem while checking whether your file already exists in the specified branch."
+msgstr ""
+
msgid "Pipelines"
msgstr ""
@@ -27157,7 +27742,7 @@ msgstr ""
msgid "Pipelines|Project cache successfully reset."
msgstr ""
-msgid "Pipelines|Revoke"
+msgid "Pipelines|Revoke trigger"
msgstr ""
msgid "Pipelines|Something went wrong while cleaning runners cache."
@@ -27202,6 +27787,12 @@ msgstr ""
msgid "Pipelines|This is a child pipeline within the parent pipeline"
msgstr ""
+msgid "Pipelines|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipelines|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipelines|This pipeline will run code originating from a forked project merge request. This means that the code can potentially have security considerations like exposing CI variables."
msgstr ""
@@ -27244,9 +27835,6 @@ msgstr ""
msgid "Pipelines|Your changes have been successfully committed. Now redirecting to the new merge request page."
msgstr ""
-msgid "Pipelines|detached"
-msgstr ""
-
msgid "Pipelines|error"
msgstr ""
@@ -27256,10 +27844,13 @@ msgstr ""
msgid "Pipelines|latest"
msgstr ""
-msgid "Pipelines|stuck"
+msgid "Pipelines|merge request"
+msgstr ""
+
+msgid "Pipelines|merge train"
msgstr ""
-msgid "Pipelines|train"
+msgid "Pipelines|stuck"
msgstr ""
msgid "Pipelines|yaml invalid"
@@ -27391,6 +27982,12 @@ msgstr ""
msgid "Pipeline|This change will not change the overall test coverage if merged."
msgstr ""
+msgid "Pipeline|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipeline|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipeline|Trigger author"
msgstr ""
@@ -27415,6 +28012,12 @@ msgstr ""
msgid "Pipeline|for"
msgstr ""
+msgid "Pipeline|merge request"
+msgstr ""
+
+msgid "Pipeline|merge train"
+msgstr ""
+
msgid "Pipeline|on"
msgstr ""
@@ -27553,9 +28156,6 @@ msgstr ""
msgid "Please enter a valid time interval"
msgstr ""
-msgid "Please enter or upload a valid license."
-msgstr ""
-
msgid "Please enter your current password."
msgstr ""
@@ -27664,9 +28264,6 @@ msgstr ""
msgid "Please type %{phrase_code} to proceed or close this modal to cancel."
msgstr ""
-msgid "Please type the following to confirm:"
-msgstr ""
-
msgid "Please use this form to report to the admin users who create spam issues, comments or behave inappropriately."
msgstr ""
@@ -27694,12 +28291,27 @@ msgstr ""
msgid "Policies"
msgstr ""
+msgid "Policy '%{escalation_policy_name}' does not exist."
+msgstr ""
+
msgid "Policy management project does have any policies in %{policy_path}"
msgstr ""
msgid "Policy project doesn't exist"
msgstr ""
+msgid "PolicyRuleMultiSelect|%{firstLabel} +%{numberOfAdditionalLabels} more"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|All %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select all"
+msgstr ""
+
msgid "Polling interval multiplier"
msgstr ""
@@ -27928,6 +28540,9 @@ msgstr ""
msgid "Private projects can be created in your personal namespace with:"
msgstr ""
+msgid "Problem with %{name} command: %{message}."
+msgstr ""
+
msgid "Proceed"
msgstr ""
@@ -28402,6 +29017,9 @@ msgstr ""
msgid "Progress"
msgstr ""
+msgid "Progress tracking"
+msgstr ""
+
msgid "Project"
msgstr ""
@@ -28633,6 +29251,9 @@ msgstr ""
msgid "ProjectQualitySummary|Failure"
msgstr ""
+msgid "ProjectQualitySummary|Get insight into the overall percentage of tests in your project that succeed, fail and are skipped."
+msgstr ""
+
msgid "ProjectQualitySummary|Latest pipeline results"
msgstr ""
@@ -28651,6 +29272,12 @@ msgstr ""
msgid "ProjectQualitySummary|See project Code Coverage Statistics"
msgstr ""
+msgid "ProjectQualitySummary|Set up test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|Set up test runs (opens in a new tab)"
+msgstr ""
+
msgid "ProjectQualitySummary|Skipped"
msgstr ""
@@ -28927,13 +29554,19 @@ msgstr ""
msgid "ProjectSettings|LFS objects from this repository are available to forks. %{linkStart}How do I remove them?%{linkEnd}"
msgstr ""
+msgid "ProjectSettings|Learn about commit history."
+msgstr ""
+
+msgid "ProjectSettings|Leave empty to use default template."
+msgstr ""
+
msgid "ProjectSettings|Manage who can see the project in the public access directory."
msgstr ""
msgid "ProjectSettings|Manages large files such as audio, video, and graphics files."
msgstr ""
-msgid "ProjectSettings|Maximum 500 characters."
+msgid "ProjectSettings|Maximum %{maxLength} characters."
msgstr ""
msgid "ProjectSettings|Merge checks"
@@ -29074,6 +29707,9 @@ msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
msgstr ""
+msgid "ProjectSettings|The default template will be applied on save."
+msgstr ""
+
msgid "ProjectSettings|These checks must pass before merge requests can be merged."
msgstr ""
@@ -29128,6 +29764,9 @@ msgstr ""
msgid "ProjectSettings|What are badges?"
msgstr ""
+msgid "ProjectSettings|What are merge trains?"
+msgstr ""
+
msgid "ProjectSettings|When merge request pipelines are enabled in the CI/CD configuration file, pipelines validate the combined results of the source and target branches. %{link_start}How to configure merge request pipelines?%{link_end}"
msgstr ""
@@ -29245,6 +29884,9 @@ msgstr ""
msgid "Projects are organized into groups"
msgstr ""
+msgid "Projects are where you store your code, access issues, wiki and other features of GitLab."
+msgstr ""
+
msgid "Projects contributed to"
msgstr ""
@@ -29260,12 +29902,6 @@ msgstr ""
msgid "Projects to index"
msgstr ""
-msgid "Projects will be permanently deleted after a %{waiting_period}-day waiting period."
-msgstr ""
-
-msgid "Projects will be permanently deleted immediately."
-msgstr ""
-
msgid "Projects with critical vulnerabilities"
msgstr ""
@@ -29350,6 +29986,9 @@ msgstr ""
msgid "ProjectsNew|Import project"
msgstr ""
+msgid "ProjectsNew|Include a Getting Started README"
+msgstr ""
+
msgid "ProjectsNew|Initialize repository with a README"
msgstr ""
@@ -29365,6 +30004,9 @@ msgstr ""
msgid "ProjectsNew|Project description %{tag_start}(optional)%{tag_end}"
msgstr ""
+msgid "ProjectsNew|Recommended if you're new to GitLab"
+msgstr ""
+
msgid "ProjectsNew|Run CI/CD for external repository"
msgstr ""
@@ -29782,6 +30424,9 @@ msgstr ""
msgid "ProtectedBranch|Unprotect"
msgstr ""
+msgid "ProtectedBranch|Unprotect branch"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
@@ -29809,6 +30454,9 @@ msgstr ""
msgid "ProtectedEnvironment|Protected Environment (%{protected_environments_count})"
msgstr ""
+msgid "ProtectedEnvironment|Required approvals"
+msgstr ""
+
msgid "ProtectedEnvironment|Select an environment"
msgstr ""
@@ -29830,10 +30478,13 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|Unprotect tag"
+msgstr ""
+
msgid "ProtectedTags|default"
msgstr ""
-msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
+msgid "ProtectedTag|By default, protected tags restrict who can modify the tag."
msgstr ""
msgid "ProtectedTag|Learn more."
@@ -29896,6 +30547,9 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Public projects are an easy way to allow everyone to have read-only access."
+msgstr ""
+
msgid "Publish to status page"
msgstr ""
@@ -30052,9 +30706,6 @@ msgstr ""
msgid "QualitySummary|Project quality"
msgstr ""
-msgid "Quarters"
-msgstr ""
-
msgid "Query"
msgstr ""
@@ -30139,6 +30790,9 @@ msgstr ""
msgid "Read more about project permissions %{help_link_open}here%{help_link_close}"
msgstr ""
+msgid "Read more about related epics"
+msgstr ""
+
msgid "Read more about related issues"
msgstr ""
@@ -30169,10 +30823,7 @@ msgstr ""
msgid "Rebase source branch on the target branch."
msgstr ""
-msgid "Rebase without CI"
-msgstr ""
-
-msgid "Rebases and triggers a pipeline"
+msgid "Rebase without pipeline"
msgstr ""
msgid "Recaptcha verified?"
@@ -30223,9 +30874,6 @@ msgstr ""
msgid "Reconfigure"
msgstr ""
-msgid "Recovering projects"
-msgstr ""
-
msgid "Recovery Codes"
msgstr ""
@@ -30289,6 +30937,12 @@ msgstr ""
msgid "Regex pattern"
msgstr ""
+msgid "Region"
+msgstr ""
+
+msgid "Regions"
+msgstr ""
+
msgid "Register"
msgstr ""
@@ -30523,9 +31177,6 @@ msgstr ""
msgid "Remove all or specific reviewer(s)"
msgstr ""
-msgid "Remove approver"
-msgstr ""
-
msgid "Remove approvers"
msgstr ""
@@ -30541,6 +31192,9 @@ msgstr ""
msgid "Remove attention request"
msgstr ""
+msgid "Remove attention request(s)"
+msgstr ""
+
msgid "Remove avatar"
msgstr ""
@@ -30679,6 +31333,9 @@ msgstr ""
msgid "Removed an issue from an epic."
msgstr ""
+msgid "Removed attention from %{users_sentence}."
+msgstr ""
+
msgid "Removed attention request from @%{username}"
msgstr ""
@@ -30730,6 +31387,9 @@ msgstr ""
msgid "Removes an issue from an epic."
msgstr ""
+msgid "Removes attention from %{users_sentence}."
+msgstr ""
+
msgid "Removes parent epic %{epic_ref}."
msgstr ""
@@ -30841,6 +31501,9 @@ msgstr ""
msgid "Report abuse to admin"
msgstr ""
+msgid "Report is generating and will be sent to your email address."
+msgstr ""
+
msgid "Reported %{timeAgo} by %{reportedBy}"
msgstr ""
@@ -31150,6 +31813,15 @@ msgstr ""
msgid "Request attention"
msgstr ""
+msgid "Request attention from %{users_sentence}."
+msgstr ""
+
+msgid "Request attention from assignee or reviewer"
+msgstr ""
+
+msgid "Request attention from assignee(s) or reviewer(s)"
+msgstr ""
+
msgid "Request attention to review"
msgstr ""
@@ -31174,6 +31846,9 @@ msgstr ""
msgid "Requested %{time_ago}"
msgstr ""
+msgid "Requested attention from %{users_sentence}."
+msgstr ""
+
msgid "Requested attention from @%{username}"
msgstr ""
@@ -31396,6 +32071,9 @@ msgstr ""
msgid "Restore project"
msgstr ""
+msgid "Restoring projects"
+msgstr ""
+
msgid "Restoring the group will prevent the group, its subgroups and projects from being removed on this date."
msgstr ""
@@ -31426,6 +32104,9 @@ msgstr ""
msgid "Retry"
msgstr ""
+msgid "Retry failed jobs"
+msgstr ""
+
msgid "Retry job"
msgstr ""
@@ -31477,9 +32158,6 @@ msgstr ""
msgid "Review changes"
msgstr ""
-msgid "Review requested from %{name}"
-msgstr ""
-
msgid "Review requests for you"
msgstr ""
@@ -31648,6 +32326,9 @@ msgstr ""
msgid "Runners|Assigned Group"
msgstr ""
+msgid "Runners|Assigned Projects (%{projectCount})"
+msgstr ""
+
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -31717,6 +32398,9 @@ msgstr ""
msgid "Runners|Instance"
msgstr ""
+msgid "Runners|Jobs"
+msgstr ""
+
msgid "Runners|Last contact"
msgstr ""
@@ -31810,9 +32494,6 @@ msgstr ""
msgid "Runners|Runner %{name} was deleted"
msgstr ""
-msgid "Runners|Runner ID"
-msgstr ""
-
msgid "Runners|Runner assigned to project."
msgstr ""
@@ -31960,6 +32641,9 @@ msgstr ""
msgid "Runners|stale"
msgstr ""
+msgid "Runner|This runner has not run any jobs."
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -32074,6 +32758,24 @@ msgstr ""
msgid "Saving project."
msgstr ""
+msgid "ScanResultPolicy|%{ifLabelStart}if%{ifLabelEnd} %{scanners} scan in an open merge request targeting the %{branches} branch(es) finds %{vulnerabilitiesAllowed} or more %{severities} vulnerabilities that are %{vulnerabilityStates}"
+msgstr ""
+
+msgid "ScanResultPolicy|%{thenLabelStart}Then%{thenLabelEnd} Require approval from %{approvalsRequired} of the following approvers: %{approvers}"
+msgstr ""
+
+msgid "ScanResultPolicy|add an approver"
+msgstr ""
+
+msgid "ScanResultPolicy|scanners"
+msgstr ""
+
+msgid "ScanResultPolicy|severity levels"
+msgstr ""
+
+msgid "ScanResultPolicy|vulnerability states"
+msgstr ""
+
msgid "Scanner"
msgstr ""
@@ -32206,6 +32908,9 @@ msgstr ""
msgid "Search for a user"
msgstr ""
+msgid "Search for an emoji"
+msgstr ""
+
msgid "Search for projects, issues, etc."
msgstr ""
@@ -32437,18 +33142,12 @@ msgstr ""
msgid "Secret Detection"
msgstr ""
-msgid "Secret access key"
-msgstr ""
-
msgid "Secret token"
msgstr ""
msgid "Secure token that identifies an external storage request."
msgstr ""
-msgid "SecureCodeWarrior"
-msgstr ""
-
msgid "Security"
msgstr ""
@@ -32473,9 +33172,6 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "Security training with guide and learning pathways."
-msgstr ""
-
msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
@@ -32578,7 +33274,7 @@ msgstr ""
msgid "SecurityConfiguration|Manage corpus"
msgstr ""
-msgid "SecurityConfiguration|Manage corpus files used as mutation sources in coverage fuzzing."
+msgid "SecurityConfiguration|Manage corpus files used as seed inputs with coverage-guided fuzzing."
msgstr ""
msgid "SecurityConfiguration|Manage profiles for use by DAST scans."
@@ -32644,15 +33340,15 @@ msgstr ""
msgid "SecurityOrchestration|.yaml preview"
msgstr ""
-msgid "SecurityOrchestration|Action"
-msgstr ""
-
msgid "SecurityOrchestration|Actions"
msgstr ""
msgid "SecurityOrchestration|Add rule"
msgstr ""
+msgid "SecurityOrchestration|After dismissing the alert, the information will never be shown again."
+msgstr ""
+
msgid "SecurityOrchestration|All policies"
msgstr ""
@@ -32668,7 +33364,7 @@ msgstr ""
msgid "SecurityOrchestration|Description"
msgstr ""
-msgid "SecurityOrchestration|Disabled"
+msgid "SecurityOrchestration|Don't show the alert anymore"
msgstr ""
msgid "SecurityOrchestration|Edit policy"
@@ -32677,13 +33373,13 @@ msgstr ""
msgid "SecurityOrchestration|Edit policy project"
msgstr ""
-msgid "SecurityOrchestration|Enabled"
+msgid "SecurityOrchestration|Empty policy name"
msgstr ""
-msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Enabled"
msgstr ""
-msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
msgstr ""
msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
@@ -32692,7 +33388,7 @@ msgstr ""
msgid "SecurityOrchestration|Invalid policy type"
msgstr ""
-msgid "SecurityOrchestration|Latest scan"
+msgid "SecurityOrchestration|Latest scan run against %{agent}"
msgstr ""
msgid "SecurityOrchestration|Network"
@@ -32701,15 +33397,27 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No actions defined - policy will not run."
+msgstr ""
+
+msgid "SecurityOrchestration|No description"
+msgstr ""
+
msgid "SecurityOrchestration|No rules defined - policy will not run."
msgstr ""
+msgid "SecurityOrchestration|Not enabled"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
msgid "SecurityOrchestration|Policies"
msgstr ""
+msgid "SecurityOrchestration|Policy Type"
+msgstr ""
+
msgid "SecurityOrchestration|Policy cannot be enabled for non-existing branches (%{branches})"
msgstr ""
@@ -32734,10 +33442,13 @@ msgstr ""
msgid "SecurityOrchestration|Require %{approvals} %{plural} from %{approvers} if any of the following occur:"
msgstr ""
-msgid "SecurityOrchestration|Rule"
+msgid "SecurityOrchestration|Rules"
msgstr ""
-msgid "SecurityOrchestration|Rules"
+msgid "SecurityOrchestration|Runs %{actions} and %{lastAction} scans"
+msgstr ""
+
+msgid "SecurityOrchestration|Runs a %{action} scan"
msgstr ""
msgid "SecurityOrchestration|Scan Execution"
@@ -32797,6 +33508,9 @@ msgstr ""
msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
+msgid "SecurityOrchestration|This view only shows scan results for the agent %{agent}. You can view scan results for all agents in the %{linkStart}Operational Vulnerabilities tab of the vulnerability report%{linkEnd}."
+msgstr ""
+
msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
@@ -32851,9 +33565,6 @@ msgstr ""
msgid "SecurityOrchestration|users with ids"
msgstr ""
-msgid "SecurityOrchestration|view results"
-msgstr ""
-
msgid "SecurityOrchestration|vulnerabilities"
msgstr ""
@@ -33523,22 +34234,19 @@ 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|In order to start using functions as a service, you must first install Knative on your Kubernetes cluster. %{linkStart}More information%{linkEnd}"
-msgstr ""
-
msgid "Serverless|Learn more about Serverless"
msgstr ""
msgid "Serverless|No functions available"
msgstr ""
-msgid "Serverless|Sign up for First Look"
+msgid "Serverless|Serverless was %{linkStart}deprecated%{linkEnd} in GitLab 14.3."
+msgstr ""
+
+msgid "Serverless|Serverless was %{postLinkStart}deprecated%{postLinkEnd}. But if you opt to use it, you must install Knative in your Kubernetes cluster first. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "Serverless|The deploy job has not finished."
@@ -33550,9 +34258,6 @@ 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 ""
@@ -33568,9 +34273,6 @@ msgstr ""
msgid "Service Account Key"
msgstr ""
-msgid "Service Accounts"
-msgstr ""
-
msgid "Service Accounts keys authorize GitLab to deploy your Google Cloud project"
msgstr ""
@@ -33580,10 +34282,10 @@ msgstr ""
msgid "Service Desk allows people to create issues in your GitLab instance without their own user account. It provides a unique email address for end users to create issues in a project. Replies can be sent either through the GitLab interface or by email. End users only see threads through email."
msgstr ""
-msgid "Service Usage Data"
+msgid "Service account generated successfully"
msgstr ""
-msgid "Service account generated successfully"
+msgid "Service accounts"
msgstr ""
msgid "Service ping is disabled in your configuration file, and cannot be enabled through this form."
@@ -33727,6 +34429,9 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
+msgid "Set the per-user rate limit for getting a user by ID via the API."
+msgstr ""
+
msgid "Set the per-user rate limit for notes created by web or API requests."
msgstr ""
@@ -33910,6 +34615,9 @@ msgstr ""
msgid "Shared runners details"
msgstr ""
+msgid "Shared runners enabled cannot be enabled until a valid credit card is on file"
+msgstr ""
+
msgid "Shared runners help link"
msgstr ""
@@ -33967,6 +34675,9 @@ msgstr ""
msgid "Show all issues."
msgstr ""
+msgid "Show all milestones"
+msgstr ""
+
msgid "Show all test cases."
msgstr ""
@@ -34003,6 +34714,9 @@ msgstr ""
msgid "Show file contents"
msgstr ""
+msgid "Show group milestones"
+msgstr ""
+
msgid "Show labels"
msgstr ""
@@ -34018,6 +34732,12 @@ msgstr ""
msgid "Show open epics"
msgstr ""
+msgid "Show project milestones"
+msgstr ""
+
+msgid "Show sub-group milestones"
+msgstr ""
+
msgid "Show the Closed list"
msgstr ""
@@ -34027,15 +34747,6 @@ msgstr ""
msgid "Show whitespace changes"
msgstr ""
-msgid "Showing %d event"
-msgid_plural "Showing %d events"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-msgstr[3] ""
-msgstr[4] ""
-msgstr[5] ""
-
msgid "Showing %{conflict} between %{sourceBranch} and %{targetBranch}"
msgstr ""
@@ -34099,12 +34810,6 @@ msgstr ""
msgid "Sidebar|None"
msgstr ""
-msgid "Sidebar|Only numeral characters allowed"
-msgstr ""
-
-msgid "Sidebar|Weight"
-msgstr ""
-
msgid "Sidekiq job compression threshold (bytes)"
msgstr ""
@@ -34267,6 +34972,9 @@ msgstr ""
msgid "Slack logo"
msgstr ""
+msgid "SlackIntegration|Are you sure you want to remove this project from the Slack application?"
+msgstr ""
+
msgid "SlackIntegration|GitLab for Slack"
msgstr ""
@@ -34276,6 +34984,9 @@ msgstr ""
msgid "SlackIntegration|Project alias"
msgstr ""
+msgid "SlackIntegration|Remove project"
+msgstr ""
+
msgid "SlackIntegration|Select a GitLab project to link with your Slack workspace."
msgstr ""
@@ -34420,9 +35131,6 @@ msgstr ""
msgid "Something went wrong trying to load issue contacts."
msgstr ""
-msgid "Something went wrong when creating a work item. Please try again"
-msgstr ""
-
msgid "Something went wrong when reordering designs. Please try again"
msgstr ""
@@ -34516,9 +35224,6 @@ msgstr ""
msgid "Something went wrong while inserting your image. Please try again."
msgstr ""
-msgid "Something went wrong while merging this merge request. Please try again."
-msgstr ""
-
msgid "Something went wrong while obtaining the Let's Encrypt certificate."
msgstr ""
@@ -34840,10 +35545,10 @@ 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."
+msgid "SourcegraphAdmin|Learn more."
msgstr ""
-msgid "SourcegraphAdmin|More information"
+msgid "SourcegraphAdmin|Only public projects have code intelligence enabled and communicate with Sourcegraph."
msgstr ""
msgid "SourcegraphAdmin|Save changes"
@@ -34852,7 +35557,7 @@ msgstr ""
msgid "SourcegraphAdmin|Sourcegraph URL"
msgstr ""
-msgid "SourcegraphAdmin|e.g. https://sourcegraph.example.com"
+msgid "SourcegraphAdmin|https://sourcegraph.example.com"
msgstr ""
msgid "SourcegraphPreferences|This feature is experimental and currently limited to certain projects."
@@ -34987,6 +35692,9 @@ msgstr ""
msgid "Start date"
msgstr ""
+msgid "Start free trial"
+msgstr ""
+
msgid "Start merge train"
msgstr ""
@@ -35017,6 +35725,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started escalation for this incident."
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -35029,6 +35740,9 @@ msgstr ""
msgid "Starts at (UTC)"
msgstr ""
+msgid "Starts escalations for this incident"
+msgstr ""
+
msgid "Starts on"
msgstr ""
@@ -35290,6 +36004,9 @@ msgstr ""
msgid "Strikethrough"
msgstr ""
+msgid "Strikethrough text"
+msgstr ""
+
msgid "Subgroup information"
msgstr ""
@@ -35524,6 +36241,21 @@ msgstr ""
msgid "Subscriptions"
msgstr ""
+msgid "Subscriptions|Chat with sales"
+msgstr ""
+
+msgid "Subscriptions|Close"
+msgstr ""
+
+msgid "Subscriptions|Not ready to buy yet?"
+msgstr ""
+
+msgid "Subscriptions|Start a free trial"
+msgstr ""
+
+msgid "Subscriptions|We understand. Maybe you have some questions for our sales team, or maybe you'd like to try some of the paid features first. What would you like to do?"
+msgstr ""
+
msgid "Subscription|Your subscription for %{strong}%{namespace_name}%{strong_close} has expired and you are now on %{pricing_link_start}the GitLab Free tier%{pricing_link_end}. Don't worry, your data is safe. Get in touch with our support team (%{support_email}). They'll gladly help with your subscription renewal."
msgstr ""
@@ -35734,6 +36466,9 @@ msgstr ""
msgid "SuperSonics|Maximum users"
msgstr ""
+msgid "SuperSonics|Offline cloud"
+msgstr ""
+
msgid "SuperSonics|Paste your activation code"
msgstr ""
@@ -35800,6 +36535,12 @@ msgstr ""
msgid "SuperSonics|You do not have an active subscription"
msgstr ""
+msgid "SuperSonics|You have a future dated license"
+msgstr ""
+
+msgid "SuperSonics|You have added a license that activates on %{date}. Please see the subscription history table below for more details."
+msgstr ""
+
msgid "SuperSonics|You have successfully added a license that activates on %{date}. Please see the subscription history table below for more details."
msgstr ""
@@ -35959,6 +36700,9 @@ msgstr ""
msgid "Tag name is required"
msgstr ""
+msgid "Tag push"
+msgstr ""
+
msgid "Tag push events"
msgstr ""
@@ -36061,6 +36805,9 @@ msgstr ""
msgid "TagsPage|protected"
msgstr ""
+msgid "Take a look at the documentation to discover all of GitLab’s capabilities."
+msgstr ""
+
msgid "Target Branch"
msgstr ""
@@ -36487,6 +37234,9 @@ msgstr ""
msgid "Tests"
msgstr ""
+msgid "Text (optional)"
+msgstr ""
+
msgid "Text added to the body of all email messages. %{character_limit} character limit"
msgstr ""
@@ -36541,6 +37291,9 @@ msgstr ""
msgid "The CSV export will be created in the background. Once finished, it will be sent to %{email} in an attachment."
msgstr ""
+msgid "The CSV export you requested of all user memberships is attached to this email."
+msgstr ""
+
msgid "The GitLab subscription service (customers.gitlab.com) is currently experiencing an outage. You can monitor the status and get updates at %{linkStart}status.gitlab.com%{linkEnd}."
msgstr ""
@@ -36616,6 +37369,9 @@ 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 epic"
+msgstr ""
+
msgid "The current issue"
msgstr ""
@@ -36781,6 +37537,9 @@ msgstr ""
msgid "The latest pipeline for this merge request has failed."
msgstr ""
+msgid "The license key is invalid."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -36796,6 +37555,9 @@ msgstr ""
msgid "The license was successfully uploaded and will be active from %{starts_at}. You can see the details below."
msgstr ""
+msgid "The license you uploaded is invalid. If the issue persists, contact support at %{link}."
+msgstr ""
+
msgid "The list creation wizard is already open"
msgstr ""
@@ -37417,10 +38179,13 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} and everything this project contains. %{strongOpen}There is no going back%{strongClose}"
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}on %{date}%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains."
+msgstr ""
+
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains. %{strongOpen}There is no going back.%{strongClose}"
msgstr ""
msgid "This action will %{strongOpen}permanently remove%{strongClose} %{codeOpen}%{group}%{codeClose} %{strongOpen}immediately%{strongClose}."
@@ -37549,9 +38314,6 @@ msgstr ""
msgid "This file was modified for readability, and can't accept suggestions. Edit it directly."
msgstr ""
-msgid "This forked project has the following:"
-msgstr ""
-
msgid "This form is disabled in preview"
msgstr ""
@@ -37564,7 +38326,7 @@ msgstr ""
msgid "This group can't be removed because it is linked to a subscription. To remove this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
-msgid "This group can't be transfered because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
+msgid "This group can't be transferred because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
msgid "This group cannot be invited to a project inside a group with enforced SSO"
@@ -37591,6 +38353,9 @@ 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 incident is already escalated with '%{escalation_policy_name}'."
+msgstr ""
+
msgid "This invitation was sent to %{mail_to_invite_email}, but you are signed in as %{link_to_current_user} with email %{mail_to_current_user}."
msgstr ""
@@ -37609,9 +38374,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 merge train pipeline"
-msgstr ""
-
msgid "This is a private email address %{helpIcon} generated just for you. Anyone who has it can create issues or merge requests as if they were you. If that happens, %{resetLinkStart}reset this token%{resetLinkEnd}."
msgstr ""
@@ -37633,6 +38395,12 @@ msgstr ""
msgid "This is your current session"
msgstr ""
+msgid "This issue cannot be assigned to a confidential epic because it is public."
+msgstr ""
+
+msgid "This issue cannot be made public because it belongs to a confidential epic."
+msgstr ""
+
msgid "This issue is confidential and should only be visible to team members with at least Reporter access."
msgstr ""
@@ -37750,6 +38518,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 branch is protected from force push."
+msgstr ""
+
msgid "This merge request cannot be rebased while there are conflicts."
msgstr ""
@@ -37801,9 +38572,15 @@ msgstr ""
msgid "This pipeline was triggered by a schedule."
msgstr ""
+msgid "This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project"
msgstr ""
+msgid "This project can be restored until %{date}."
+msgstr ""
+
msgid "This project cannot be %{visibilityLevel} because the visibility of %{openShowLink}%{name}%{closeShowLink} is %{visibility}. To make this project %{visibilityLevel}, you must first %{openEditLink}change the visibility%{closeEditLink} of the parent group."
msgstr ""
@@ -37822,6 +38599,9 @@ msgstr ""
msgid "This project is %{strongStart}NOT%{strongEnd} a fork, and has the following:"
msgstr ""
+msgid "This project is %{strongStart}NOT%{strongEnd} a fork. This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -38521,6 +39301,9 @@ msgstr ""
msgid "Today"
msgstr ""
+msgid "Todos count"
+msgstr ""
+
msgid "Todos|Are you looking for things to do? Take a look at %{strongStart}%{openIssuesLinkStart}open issues%{openIssuesLinkEnd}%{strongEnd}, contribute to %{strongStart}%{mergeRequestLinkStart}a merge request%{mergeRequestLinkEnd}%{mergeRequestLinkEnd}%{strongEnd}, or mention someone in a comment to automatically assign them a new to-do item."
msgstr ""
@@ -38794,14 +39577,8 @@ msgstr ""
msgid "Trending"
msgstr ""
-msgid "Trials|%{planName} Trial %{enDash} %{num} day left"
-msgid_plural "Trials|%{planName} Trial %{enDash} %{num} days left"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-msgstr[3] ""
-msgstr[4] ""
-msgstr[5] ""
+msgid "Trials|%{planName} Trial"
+msgstr ""
msgid "Trials|Compare all plans"
msgstr ""
@@ -38809,6 +39586,9 @@ msgstr ""
msgid "Trials|Create a new group to start your GitLab Ultimate trial."
msgstr ""
+msgid "Trials|Day %{daysUsed}/%{duration}"
+msgstr ""
+
msgid "Trials|Go back to GitLab"
msgstr ""
@@ -39058,7 +39838,7 @@ msgstr ""
msgid "URL is triggered when repository is updated"
msgstr ""
-msgid "URL must be percent-encoded if neccessary."
+msgid "URL must be percent-encoded if necessary."
msgstr ""
msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
@@ -39277,6 +40057,9 @@ msgstr ""
msgid "Unlock account"
msgstr ""
+msgid "Unlock more features with GitLab Ultimate"
+msgstr ""
+
msgid "Unlock the discussion"
msgstr ""
@@ -39340,6 +40123,9 @@ msgstr ""
msgid "Unsubscribes from this %{quick_action_target}."
msgstr ""
+msgid "Unsupported sort value."
+msgstr ""
+
msgid "Unsupported todo type passed. Supported todo types are: %{todo_types}"
msgstr ""
@@ -39568,6 +40354,9 @@ msgstr ""
msgid "UsageQuota|File attachments and smaller design graphics."
msgstr ""
+msgid "UsageQuota|From %{storage_enforcement_date} storage limits will apply to this namespace. View and manage your usage in %{strong_start}Group Settings &gt; Usage quotas%{strong_end}."
+msgstr ""
+
msgid "UsageQuota|Git repository."
msgstr ""
@@ -39628,6 +40417,9 @@ msgstr ""
msgid "UsageQuota|Storage type"
msgstr ""
+msgid "UsageQuota|Storage used"
+msgstr ""
+
msgid "UsageQuota|This is the total amount of storage used across your projects within this namespace."
msgstr ""
@@ -39823,6 +40615,12 @@ msgstr ""
msgid "Use hashed storage paths for newly created and renamed repositories. Always enabled since 13.0."
msgstr ""
+msgid "Use issue count"
+msgstr ""
+
+msgid "Use issue weight"
+msgstr ""
+
msgid "Use one line per URI"
msgstr ""
@@ -40204,6 +41002,9 @@ msgstr ""
msgid "Users"
msgstr ""
+msgid "Users API rate limit"
+msgstr ""
+
msgid "Users can launch a development environment from a GitLab browser tab when the %{linkStart}Gitpod%{linkEnd} integration is enabled."
msgstr ""
@@ -40537,6 +41338,9 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View group pipeline usage quota"
+msgstr ""
+
msgid "View incident details at"
msgstr ""
@@ -40693,6 +41497,9 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
+msgid "Vulnerability"
+msgstr ""
+
msgid "Vulnerability Report"
msgstr ""
@@ -40744,6 +41551,9 @@ msgstr ""
msgid "VulnerabilityManagement|An unverified non-confirmed finding"
msgstr ""
+msgid "VulnerabilityManagement|At least one identifier is required"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -40753,12 +41563,24 @@ msgstr ""
msgid "VulnerabilityManagement|Create Jira issue"
msgstr ""
+msgid "VulnerabilityManagement|Enter a name"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE code"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE identifier URL"
+msgstr ""
+
msgid "VulnerabilityManagement|Fetching linked Jira issues"
msgstr ""
msgid "VulnerabilityManagement|Manually add a vulnerability entry into the vulnerability report."
msgstr ""
+msgid "VulnerabilityManagement|Name is a required field"
+msgstr ""
+
msgid "VulnerabilityManagement|Needs triage"
msgstr ""
@@ -40774,6 +41596,18 @@ msgstr ""
msgid "VulnerabilityManagement|Select a method"
msgstr ""
+msgid "VulnerabilityManagement|Select a severity level"
+msgstr ""
+
+msgid "VulnerabilityManagement|Select a status"
+msgstr ""
+
+msgid "VulnerabilityManagement|Severity is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Something went wrong while creating vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -40798,6 +41632,12 @@ msgstr ""
msgid "VulnerabilityManagement|Something went wrong, could not update vulnerability state."
msgstr ""
+msgid "VulnerabilityManagement|Status is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Submit vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Summary, detailed description, steps to reproduce, etc."
msgstr ""
@@ -40993,6 +41833,9 @@ msgstr ""
msgid "WARNING:"
msgstr ""
+msgid "WARNING: This snippet contains hidden files which might be used to mask malicious behavior. Exercise caution if cloning and executing code from this snippet."
+msgstr ""
+
msgid "Wait for the file to load to copy its contents"
msgstr ""
@@ -41212,6 +42055,15 @@ msgstr ""
msgid "Webhooks|An issue is created, updated, closed, or reopened."
msgstr ""
+msgid "Webhooks|Are you sure you want to delete this group hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this project hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this webhook?"
+msgstr ""
+
msgid "Webhooks|Comments"
msgstr ""
@@ -41221,6 +42073,9 @@ msgstr ""
msgid "Webhooks|Confidential issues events"
msgstr ""
+msgid "Webhooks|Delete webhook"
+msgstr ""
+
msgid "Webhooks|Deployment events"
msgstr ""
@@ -41458,6 +42313,9 @@ msgstr ""
msgid "Wiki"
msgstr ""
+msgid "Wiki page"
+msgstr ""
+
msgid "Wiki page was successfully created."
msgstr ""
@@ -41563,7 +42421,7 @@ msgstr ""
msgid "WikiPageConflictMessage|Someone edited the page the same time you did. Please check out %{wikiLinkStart}the page%{wikiLinkEnd} and make sure your changes will not unintentionally remove theirs."
msgstr ""
-msgid "WikiPage|An error occured while trying to render the content editor. Please try again later."
+msgid "WikiPage|An error occurred while trying to render the content editor. Please try again later."
msgstr ""
msgid "WikiPage|Are you sure you want to switch back to the classic editor?"
@@ -41722,6 +42580,18 @@ msgstr ""
msgid "WorkItem|New Task"
msgstr ""
+msgid "WorkItem|Something went wrong when creating a work item. Please try again"
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching the work item. Please try again."
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching work item types. Please try again"
+msgstr ""
+
+msgid "WorkItem|Type"
+msgstr ""
+
msgid "WorkItem|Work Items"
msgstr ""
@@ -41788,7 +42658,10 @@ msgstr ""
msgid "You are about to add %{usersTag} people to the discussion. They will all receive a notification."
msgstr ""
-msgid "You are about to permanently delete this project"
+msgid "You are about to delete this forked project containing:"
+msgstr ""
+
+msgid "You are about to delete this project containing:"
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."
@@ -41809,6 +42682,9 @@ msgstr ""
msgid "You are attempting to update a file that has changed since you started editing it."
msgstr ""
+msgid "You are billed if you exceed this number. %{qsrOverageLinkStart}How does billing work?%{qsrOverageLinkEnd}"
+msgstr ""
+
msgid "You are connected to the Prometheus server, but there is currently no data to display."
msgstr ""
@@ -41866,6 +42742,9 @@ msgstr ""
msgid "You are not authorized to update this scanner profile"
msgstr ""
+msgid "You are not authorized to upload metric images"
+msgstr ""
+
msgid "You are now impersonating %{username}"
msgstr ""
@@ -42019,9 +42898,6 @@ msgstr ""
msgid "You can only upload one design when dropping onto an existing design."
msgstr ""
-msgid "You can recover this project until %{date}"
-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 ""
@@ -42070,9 +42946,6 @@ msgstr ""
msgid "You cannot write to this read-only GitLab instance."
msgstr ""
-msgid "You can’t %{tag_start}edit%{tag_end} files directly in this project. Fork this project and submit a merge request with your changes."
-msgstr ""
-
msgid "You can’t edit files directly in this project. Fork this project and submit a merge request with your changes."
msgstr ""
@@ -42229,9 +43102,6 @@ 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 set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
@@ -42262,12 +43132,6 @@ msgstr ""
msgid "You must have maintainer access to force delete a lock"
msgstr ""
-msgid "You must have permission to create a project in a group before forking."
-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 ""
@@ -42673,7 +43537,7 @@ msgstr ""
msgid "Your public email will be displayed on your public profile."
msgstr ""
-msgid "Your request for access could not be processed: %{error_meesage}"
+msgid "Your request for access could not be processed: %{error_message}"
msgstr ""
msgid "Your request for access has been queued for review."
@@ -42868,6 +43732,9 @@ msgstr ""
msgid "archived:"
msgstr ""
+msgid "artifacts"
+msgstr ""
+
msgid "assign yourself"
msgstr ""
@@ -42901,6 +43768,9 @@ msgstr[5] ""
msgid "branch name"
msgstr ""
+msgid "builds"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -43336,6 +44206,9 @@ msgstr ""
msgid "contact with same email already exists in group hierarchy"
msgstr ""
+msgid "container registry images"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -43375,6 +44248,9 @@ msgstr ""
msgid "data"
msgstr ""
+msgid "database"
+msgstr ""
+
msgid "date must not be after 9999-12-31"
msgstr ""
@@ -43402,9 +44278,6 @@ msgstr ""
msgid "design"
msgstr ""
-msgid "detached"
-msgstr ""
-
msgid "disabled"
msgstr ""
@@ -43669,7 +44542,7 @@ msgstr ""
msgid "is not a valid X509 certificate."
msgstr ""
-msgid "is not allowed for sign-up."
+msgid "is not allowed for sign-up. Please use your regular email address."
msgstr ""
msgid "is not allowed for this group."
@@ -43681,7 +44554,7 @@ msgstr ""
msgid "is not allowed since the group is not top-level group."
msgstr ""
-msgid "is not allowed."
+msgid "is not allowed. Please use your regular email address."
msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
@@ -43768,6 +44641,9 @@ msgstr ""
msgid "level: %{level}"
msgstr ""
+msgid "lfs objects"
+msgstr ""
+
msgid "limit of %{project_limit} reached"
msgstr ""
@@ -43999,6 +44875,9 @@ msgstr ""
msgid "mrWidget|Merge blocked: pipeline must succeed. It's waiting for a manual action to continue."
msgstr ""
+msgid "mrWidget|Merge blocked: pipeline must succeed. Push a commit that fixes the failure, or %{linkStart}learn about other solutions.%{linkEnd}"
+msgstr ""
+
msgid "mrWidget|Merge blocked: this merge request must be approved."
msgstr ""
@@ -44116,9 +44995,6 @@ msgstr ""
msgid "mrWidget|The changes were not merged into"
msgstr ""
-msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -44266,9 +45142,6 @@ msgstr ""
msgid "open issue"
msgstr ""
-msgid "opened %{timeAgo}"
-msgstr ""
-
msgid "or"
msgstr ""
@@ -44284,6 +45157,12 @@ msgstr[3] ""
msgstr[4] ""
msgstr[5] ""
+msgid "packages"
+msgstr ""
+
+msgid "pages"
+msgstr ""
+
msgid "parent"
msgid_plural "parents"
msgstr[0] ""
@@ -44449,6 +45328,9 @@ msgstr[3] ""
msgstr[4] ""
msgstr[5] ""
+msgid "repositories"
+msgstr ""
+
msgid "repository:"
msgstr ""
@@ -44569,12 +45451,18 @@ msgstr ""
msgid "tag name"
msgstr ""
+msgid "terraform states"
+msgstr ""
+
msgid "the correct format."
msgstr ""
msgid "the file"
msgstr ""
+msgid "the following epic(s)"
+msgstr ""
+
msgid "the following issue(s)"
msgstr ""
@@ -44587,21 +45475,12 @@ msgstr ""
msgid "this document"
msgstr ""
-msgid "this issue cannot be assigned to a confidential epic since it is public"
-msgstr ""
-
-msgid "this issue cannot be made public since it belongs to a confidential epic"
-msgstr ""
-
msgid "time summary"
msgstr ""
msgid "toggle collapse"
msgstr ""
-msgid "train"
-msgstr ""
-
msgid "triggered"
msgstr ""
@@ -44734,3 +45613,6 @@ msgstr ""
msgid "{project}"
msgstr ""
+msgid "✔"
+msgstr ""
+
diff --git a/locale/as_IN/gitlab.po b/locale/as_IN/gitlab.po
index 3a0fbc6d102..bed62d97885 100644
--- a/locale/as_IN/gitlab.po
+++ b/locale/as_IN/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: as\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2022-02-02 15:48\n"
+"PO-Revision-Date: 2022-03-01 20:41\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -146,6 +146,11 @@ msgid_plural "%d approvers (you've approved)"
msgstr[0] ""
msgstr[1] ""
+msgid "%d assigned issue"
+msgid_plural "%d assigned issues"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -421,8 +426,23 @@ msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
msgstr[1] ""
-msgid "%d vulnerability updated"
-msgid_plural "%d vulnerabilities updated"
+msgid "%d vulnerability set to confirmed"
+msgid_plural "%d vulnerabilities set to confirmed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to dismissed"
+msgid_plural "%d vulnerabilities set to dismissed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to needs triage"
+msgid_plural "%d vulnerabilities set to needs triage"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to resolved"
+msgid_plural "%d vulnerabilities set to resolved"
msgstr[0] ""
msgstr[1] ""
@@ -510,6 +530,12 @@ msgstr[1] ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{completed} of %{total} issues closed"
+msgstr ""
+
+msgid "%{completed} of %{total} weight completed"
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -858,6 +884,9 @@ msgstr ""
msgid "%{openedIssues} open, %{closedIssues} closed"
msgstr ""
+msgid "%{percentage}%% issues closed"
+msgstr ""
+
msgid "%{percentage}%% weight completed"
msgstr ""
@@ -1287,6 +1316,9 @@ msgid_plural "- Users"
msgstr[0] ""
msgstr[1] ""
+msgid "- of - issues closed"
+msgstr ""
+
msgid "- of - weight completed"
msgstr ""
@@ -1429,7 +1461,7 @@ msgstr ""
msgid "1000+"
msgstr ""
-msgid "192.168.0.0/24"
+msgid "192.168.0.0/24 or 2001:0DB8:1234::/48"
msgstr ""
msgid "1st contribution!"
@@ -1741,13 +1773,13 @@ msgstr ""
msgid "AWS Access Key"
msgstr ""
-msgid "AWS Access Key. Only required if not using role instance credentials"
+msgid "AWS Secret Access Key"
msgstr ""
-msgid "AWS Secret Access Key"
+msgid "AWS access key ID (Optional)"
msgstr ""
-msgid "AWS Secret Access Key. Only required if not using role instance credentials"
+msgid "AWS secret access key (Optional)"
msgstr ""
msgid "AWS service error: %{error}"
@@ -1807,9 +1839,6 @@ msgstr ""
msgid "Access granted"
msgstr ""
-msgid "Access key ID"
-msgstr ""
-
msgid "Access requests"
msgstr ""
@@ -1984,7 +2013,7 @@ msgstr ""
msgid "Activity"
msgstr ""
-msgid "Activity|An error occured while retrieving activity. Reload the page to try again."
+msgid "Activity|An error occurred while retrieving activity. Reload the page to try again."
msgstr ""
msgid "Add"
@@ -2023,6 +2052,9 @@ msgstr ""
msgid "Add a %{type}"
msgstr ""
+msgid "Add a GCP region"
+msgstr ""
+
msgid "Add a GPG key"
msgstr ""
@@ -2074,6 +2106,9 @@ msgstr ""
msgid "Add a numbered list"
msgstr ""
+msgid "Add a related epic"
+msgstr ""
+
msgid "Add a related issue"
msgstr ""
@@ -2188,6 +2223,9 @@ msgstr ""
msgid "Add or subtract spent time"
msgstr ""
+msgid "Add people"
+msgstr ""
+
msgid "Add previously merged commits"
msgstr ""
@@ -2254,6 +2292,9 @@ msgstr ""
msgid "Add webhook"
msgstr ""
+msgid "Add your team members and others to GitLab."
+msgstr ""
+
msgid "Add/remove"
msgstr ""
@@ -3076,12 +3117,6 @@ msgstr ""
msgid "AdvancedSearch|Reindex required"
msgstr ""
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. Permanently deleting this project will %{strongStart}immediately delete%{strongEnd} its repositories and %{strongStart}all related resources%{strongEnd}, including issues, merge requests etc."
-msgstr ""
-
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. You will lose this project's repository and %{strongStart}all related resources%{strongEnd}, including issues and merge requests."
-msgstr ""
-
msgid "After a successful password update you will be redirected to login screen."
msgstr ""
@@ -3112,6 +3147,9 @@ msgstr ""
msgid "Akismet helps prevent the creation of spam issues in public projects."
msgstr ""
+msgid "Alert"
+msgstr ""
+
msgid "AlertManagement|Acknowledged"
msgstr ""
@@ -3484,9 +3522,6 @@ msgstr ""
msgid "All environments"
msgstr ""
-msgid "All epics"
-msgstr ""
-
msgid "All groups and projects"
msgstr ""
@@ -4223,12 +4258,15 @@ msgstr ""
msgid "ApplicationSettings|Approve users in the pending approval status?"
msgstr ""
-msgid "ApplicationSettings|By making this change, you will automatically approve %d user with the pending approval status."
-msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users with the pending approval status."
+msgid "ApplicationSettings|Approve users who are pending approval?"
+msgstr ""
+
+msgid "ApplicationSettings|By making this change, you will automatically approve %d user who is pending approval."
+msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users who are pending approval."
msgstr[0] ""
msgstr[1] ""
-msgid "ApplicationSettings|By making this change, you will automatically approve all users in pending approval status."
+msgid "ApplicationSettings|By making this change, you will automatically approve all users who are pending approval."
msgstr ""
msgid "ApplicationSettings|Denied domains for sign-ups"
@@ -4634,10 +4672,10 @@ msgstr ""
msgid "Archiving the project will make it entirely read-only. It is hidden from the dashboard and doesn't show up in searches. %{strong_start}The repository cannot be committed to, and no issues, comments, or other entities can be created.%{strong_end} %{link_start}Learn more.%{link_end}"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to delete this project?"
+msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
+msgid "Are you absolutely sure?"
msgstr ""
msgid "Are you sure that you want to archive this project?"
@@ -4673,12 +4711,18 @@ msgstr ""
msgid "Are you sure you want to delete this SSH key?"
msgstr ""
+msgid "Are you sure you want to delete this comment?"
+msgstr ""
+
msgid "Are you sure you want to delete this deploy key?"
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 label?"
+msgstr ""
+
msgid "Are you sure you want to delete this pipeline schedule?"
msgstr ""
@@ -4694,9 +4738,6 @@ msgstr ""
msgid "Are you sure you want to discard your changes?"
msgstr ""
-msgid "Are you sure you want to erase this build?"
-msgstr ""
-
msgid "Are you sure you want to import %d repository?"
msgid_plural "Are you sure you want to import %d repositories?"
msgstr[0] ""
@@ -4744,6 +4785,9 @@ msgstr ""
msgid "Are you sure you want to remove this list?"
msgstr ""
+msgid "Are you sure you want to remove this nickname?"
+msgstr ""
+
msgid "Are you sure you want to reset the health check token?"
msgstr ""
@@ -4756,10 +4800,10 @@ 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?"
+msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
msgstr ""
-msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
+msgid "Are you sure you want to revoke this project access token? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to stop this environment?"
@@ -4906,9 +4950,6 @@ msgstr ""
msgid "Assigned to %{assignee_name}"
msgstr ""
-msgid "Assigned to %{name}"
-msgstr ""
-
msgid "Assigned to me"
msgstr ""
@@ -4973,6 +5014,9 @@ msgstr[1] ""
msgid "Attaching the file failed."
msgstr ""
+msgid "Attention"
+msgstr ""
+
msgid "Audit Events"
msgstr ""
@@ -5135,6 +5179,12 @@ msgstr ""
msgid "Authorized applications (%{size})"
msgstr ""
+msgid "AuthorizedApplication|Are you sure you want to revoke this application?"
+msgstr ""
+
+msgid "AuthorizedApplication|Revoke application"
+msgstr ""
+
msgid "Authors: %{authors}"
msgstr ""
@@ -6328,6 +6378,9 @@ msgstr ""
msgid "CICDAnalytics|Shared Runners Usage"
msgstr ""
+msgid "CICDAnalytics|Shared runner pipeline minute duration by month"
+msgstr ""
+
msgid "CICDAnalytics|Shared runner usage"
msgstr ""
@@ -6469,6 +6522,9 @@ msgstr ""
msgid "Can create groups:"
msgstr ""
+msgid "Can not delete primary training"
+msgstr ""
+
msgid "Can't apply as the source branch was deleted."
msgstr ""
@@ -6802,9 +6858,6 @@ msgstr ""
msgid "Changing any setting here requires an application restart"
msgstr ""
-msgid "Changing group URL can have unintended side effects."
-msgstr ""
-
msgid "Charts can't be displayed as the request for data has timed out. %{documentationLink}"
msgstr ""
@@ -6892,9 +6945,6 @@ msgstr ""
msgid "Checking branch availability..."
msgstr ""
-msgid "Checking group URL availability..."
-msgstr ""
-
msgid "Checking group path availability..."
msgstr ""
@@ -7388,6 +7438,9 @@ msgstr ""
msgid "Clear recent searches"
msgstr ""
+msgid "Clear repository checks"
+msgstr ""
+
msgid "Clear search"
msgstr ""
@@ -7520,9 +7573,6 @@ msgstr ""
msgid "Closed MRs"
msgstr ""
-msgid "Closed epics"
-msgstr ""
-
msgid "Closed issues"
msgstr ""
@@ -7559,13 +7609,13 @@ msgstr ""
msgid "Cluster level"
msgstr ""
-msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
+msgid "Cluster type must be specified for Stages::ClusterEndpointInserter"
msgstr ""
msgid "ClusterAgents|%{name} successfully deleted"
msgstr ""
-msgid "ClusterAgents|%{number} of %{total} Agents"
+msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
@@ -7607,6 +7657,15 @@ msgstr ""
msgid "ClusterAgents|Agent never connected to GitLab"
msgstr ""
+msgid "ClusterAgents|Agent version mismatch"
+msgstr ""
+
+msgid "ClusterAgents|Agent version mismatch and update"
+msgstr ""
+
+msgid "ClusterAgents|Agent version update required"
+msgstr ""
+
msgid "ClusterAgents|All"
msgstr ""
@@ -7631,7 +7690,7 @@ msgstr ""
msgid "ClusterAgents|Configuration"
msgstr ""
-msgid "ClusterAgents|Connect a cluster through the Agent"
+msgid "ClusterAgents|Connect a cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connect existing cluster"
@@ -7640,13 +7699,13 @@ msgstr ""
msgid "ClusterAgents|Connect with a certificate"
msgstr ""
-msgid "ClusterAgents|Connect with agent"
+msgid "ClusterAgents|Connect with an agent"
msgstr ""
msgid "ClusterAgents|Connect with the GitLab Agent"
msgstr ""
-msgid "ClusterAgents|Connect your cluster through the Agent"
+msgid "ClusterAgents|Connect your cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connected"
@@ -7706,7 +7765,10 @@ msgstr ""
msgid "ClusterAgents|How to register an agent?"
msgstr ""
-msgid "ClusterAgents|Install new Agent"
+msgid "ClusterAgents|How to update an agent?"
+msgstr ""
+
+msgid "ClusterAgents|Install a new agent"
msgstr ""
msgid "ClusterAgents|Last connected %{timeAgo}."
@@ -7733,7 +7795,7 @@ msgstr ""
msgid "ClusterAgents|Never connected"
msgstr ""
-msgid "ClusterAgents|No Agents"
+msgid "ClusterAgents|No agents"
msgstr ""
msgid "ClusterAgents|No clusters connected through cluster certificates"
@@ -7793,6 +7855,9 @@ msgstr ""
msgid "ClusterAgents|The agent has not been connected in a long time. There might be a connectivity issue. Last contact was %{timeAgo}."
msgstr ""
+msgid "ClusterAgents|The agent version do not match each other across your cluster's pods. This can happen when a new agent version was just deployed and Kubernetes is shutting down the old pods."
+msgstr ""
+
msgid "ClusterAgents|The recommended installation method includes the token. If you want to follow the advanced installation method provided in the docs, make sure you save the token value before you close this window."
msgstr ""
@@ -7840,6 +7905,9 @@ msgstr ""
msgid "ClusterAgents|You will need to create a token to connect to your agent"
msgstr ""
+msgid "ClusterAgents|Your agent version is out of sync with your GitLab version (v%{version}), which might cause compatibility problems. Update the agent installed on your cluster to the most recent version."
+msgstr ""
+
msgid "ClusterAgents|Your instance doesn't have the %{linkStart}GitLab Agent Server (KAS)%{linkEnd} set up. Ask a GitLab Administrator to install it."
msgstr ""
@@ -8716,9 +8784,6 @@ msgstr ""
msgid "Comma-separated list of email addresses."
msgstr ""
-msgid "Comma-separated list of users allowed to exceed the rate limit."
-msgstr ""
-
msgid "Comma-separated, e.g. '1.1.1.1, 2.2.2.0/24'"
msgstr ""
@@ -9045,6 +9110,12 @@ msgstr ""
msgid "Confidential"
msgstr ""
+msgid "Confidential issue"
+msgstr ""
+
+msgid "Confidential note"
+msgstr ""
+
msgid "Confidentiality"
msgstr ""
@@ -9078,6 +9149,9 @@ msgstr ""
msgid "Configure Dependency Scanning in `.gitlab-ci.yml`, creating this file if it does not already exist"
msgstr ""
+msgid "Configure GitLab"
+msgstr ""
+
msgid "Configure GitLab runners to start using the Web Terminal. %{helpStart}Learn more.%{helpEnd}"
msgstr ""
@@ -9126,6 +9200,15 @@ msgstr ""
msgid "Configure pipelines to deploy web apps, backend services, APIs and static resources to Google Cloud"
msgstr ""
+msgid "Configure region"
+msgstr ""
+
+msgid "Configure region for environment"
+msgstr ""
+
+msgid "Configure regions"
+msgstr ""
+
msgid "Configure repository mirroring."
msgstr ""
@@ -9159,6 +9242,9 @@ msgstr ""
msgid "Configure which lists are shown for anyone who visits this board"
msgstr ""
+msgid "Configure your environments to be deployed to specific geographical regions"
+msgstr ""
+
msgid "Confirm"
msgstr ""
@@ -9861,10 +9947,10 @@ msgstr ""
msgid "CorpusManagement|Actions"
msgstr ""
-msgid "CorpusManagement|Corpus are used in fuzz testing as mutation source to Improve future testing."
+msgid "CorpusManagement|Corpus file"
msgstr ""
-msgid "CorpusManagement|Corpus file"
+msgid "CorpusManagement|Corpus files are used in coverage-guided fuzz testing as seed inputs to improve testing."
msgstr ""
msgid "CorpusManagement|Corpus files must be in *.zip format. Maximum 5 GB"
@@ -9918,6 +10004,9 @@ msgstr ""
msgid "Could not apply %{name} command."
msgstr ""
+msgid "Could not apply %{name} command. %{message}."
+msgstr ""
+
msgid "Could not authorize chat nickname. Try again!"
msgstr ""
@@ -10068,6 +10157,9 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
+msgid "Create a group"
+msgstr ""
+
msgid "Create a merge request"
msgstr ""
@@ -10092,6 +10184,9 @@ msgstr ""
msgid "Create a personal access token on your account to pull or push via %{protocol}."
msgstr ""
+msgid "Create a project"
+msgstr ""
+
msgid "Create an account using:"
msgstr ""
@@ -10455,6 +10550,9 @@ msgstr ""
msgid "Creation date"
msgstr ""
+msgid "Creator"
+msgstr ""
+
msgid "Credentials"
msgstr ""
@@ -10467,9 +10565,15 @@ msgstr ""
msgid "CredentialsInventory|Personal Access Tokens"
msgstr ""
+msgid "CredentialsInventory|Project Access Tokens"
+msgstr ""
+
msgid "CredentialsInventory|SSH Keys"
msgstr ""
+msgid "Credit card required to be on file in order to create a pipeline"
+msgstr ""
+
msgid "Credit card:"
msgstr ""
@@ -10653,9 +10757,6 @@ msgstr ""
msgid "Customer relations"
msgstr ""
-msgid "Customizable by an administrator."
-msgstr ""
-
msgid "Customizable by owners."
msgstr ""
@@ -10785,30 +10886,18 @@ msgstr ""
msgid "CycleAnalytics|%{selectedLabelsCount} selected (%{maxLabels} max)"
msgstr ""
-msgid "CycleAnalytics|%{stageCount} stages selected"
-msgstr ""
-
-msgid "CycleAnalytics|All stages"
-msgstr ""
-
-msgid "CycleAnalytics|Average days to completion"
+msgid "CycleAnalytics|Average time to completion"
msgstr ""
msgid "CycleAnalytics|Date"
msgstr ""
-msgid "CycleAnalytics|Days to completion"
-msgstr ""
-
msgid "CycleAnalytics|Display chart filters"
msgstr ""
msgid "CycleAnalytics|Lead Time for Changes"
msgstr ""
-msgid "CycleAnalytics|No stages selected"
-msgstr ""
-
msgid "CycleAnalytics|Number of tasks"
msgstr ""
@@ -10837,18 +10926,30 @@ msgstr ""
msgid "CycleAnalytics|Showing data for group '%{groupName}' from %{createdAfter} to %{createdBefore}"
msgstr ""
-msgid "CycleAnalytics|Stages"
+msgid "CycleAnalytics|Stage time: %{title}"
msgstr ""
msgid "CycleAnalytics|Tasks by type"
msgstr ""
-msgid "CycleAnalytics|The average time spent in the selected stage for the items that were completed on each date. Data limited to the last 500 items."
+msgid "CycleAnalytics|The average time items spent in this stage. Data limited to items completed within this date range."
msgstr ""
msgid "CycleAnalytics|The given date range is larger than 180 days"
msgstr ""
+msgid "CycleAnalytics|The total time items spent across each value stream stage. Data limited to items completed within this date range."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Stage time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Total time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|Total time"
+msgstr ""
+
msgid "CycleAnalytics|Type of work"
msgstr ""
@@ -10861,9 +10962,6 @@ msgstr ""
msgid "CycleAnalytics|project dropdown filter"
msgstr ""
-msgid "CycleAnalytics|stage dropdown"
-msgstr ""
-
msgid "DAG visualization requires at least 3 dependent jobs."
msgstr ""
@@ -10963,10 +11061,16 @@ msgstr ""
msgid "DastProfiles|AJAX spider"
msgstr ""
+msgid "DastProfiles|API"
+msgstr ""
+
+msgid "DastProfiles|API endpoint URL"
+msgstr ""
+
msgid "DastProfiles|Active"
msgstr ""
-msgid "DastProfiles|Additional request headers (Optional)"
+msgid "DastProfiles|Additional request headers (optional)"
msgstr ""
msgid "DastProfiles|Are you sure you want to delete this profile?"
@@ -10981,6 +11085,9 @@ msgstr ""
msgid "DastProfiles|Branch missing"
msgstr ""
+msgid "DastProfiles|Choose a scan method"
+msgstr ""
+
msgid "DastProfiles|Could not create the scanner profile. Please try again."
msgstr ""
@@ -11050,7 +11157,13 @@ msgstr ""
msgid "DastProfiles|Excluded URLs"
msgstr ""
-msgid "DastProfiles|Excluded URLs (Optional)"
+msgid "DastProfiles|Excluded URLs (optional)"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths (optional)"
msgstr ""
msgid "DastProfiles|Hide debug messages"
@@ -11107,9 +11220,6 @@ msgstr ""
msgid "DastProfiles|Request headers"
msgstr ""
-msgid "DastProfiles|Rest API"
-msgstr ""
-
msgid "DastProfiles|Run the AJAX spider, in addition to the traditional spider, to crawl the target site."
msgstr ""
@@ -11119,6 +11229,9 @@ msgstr ""
msgid "DastProfiles|Save profile"
msgstr ""
+msgid "DastProfiles|Scan method"
+msgstr ""
+
msgid "DastProfiles|Scan mode"
msgstr ""
@@ -11197,12 +11310,24 @@ msgstr ""
msgid "DastProfiles|Website"
msgstr ""
+msgid "DastProfiles|What does each method do?"
+msgstr ""
+
msgid "DastProfiles|You can either choose a passive scan or validate the target site from the site profile management page. %{docsLinkStart}Learn more about site validation.%{docsLinkEnd}"
msgstr ""
msgid "DastProfiles|You cannot run an active scan against an unvalidated site."
msgstr ""
+msgid "DastProfiles|folder/dast_example.har or https://example.com/dast_example.har"
+msgstr ""
+
+msgid "DastProfiles|folder/example.postman_collection.json or https://example.com/"
+msgstr ""
+
+msgid "DastProfiles|folder/openapi.json or https://example.com/openapi.json"
+msgstr ""
+
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
@@ -11310,6 +11435,9 @@ msgstr ""
msgid "DatadogIntegration|API URL"
msgstr ""
+msgid "DatadogIntegration|Custom tags in Datadog. Enter one tag per line in the %{codeOpen}key:value%{codeClose} format. %{linkOpen}How do I use tags?%{linkClose}"
+msgstr ""
+
msgid "DatadogIntegration|Environment"
msgstr ""
@@ -11328,12 +11456,18 @@ msgstr ""
msgid "DatadogIntegration|Tag all data from this GitLab instance in Datadog. Useful when managing several self-managed deployments."
msgstr ""
+msgid "DatadogIntegration|Tags"
+msgstr ""
+
msgid "DatadogIntegration|The Datadog site to send data to. To send data to the EU site, use %{codeOpen}datadoghq.eu%{codeClose}."
msgstr ""
msgid "DatadogIntegration|Trace your GitLab pipelines with Datadog."
msgstr ""
+msgid "DatadogIntegration|have an invalid format"
+msgstr ""
+
msgid "Datasource name not found"
msgstr ""
@@ -11343,9 +11477,6 @@ msgstr ""
msgid "Date merged"
msgstr ""
-msgid "Date picker"
-msgstr ""
-
msgid "Date range"
msgstr ""
@@ -11499,9 +11630,6 @@ msgstr ""
msgid "Definition"
msgstr ""
-msgid "Delayed Project Deletion (%{adjourned_deletion})"
-msgstr ""
-
msgid "DelayedJobs|Are you sure you want to run %{jobName} immediately? Otherwise this job will run automatically after its timer finishes."
msgstr ""
@@ -11580,10 +11708,10 @@ msgstr ""
msgid "Delete pipeline"
msgstr ""
-msgid "Delete project"
+msgid "Delete pipeline schedule"
msgstr ""
-msgid "Delete project. Are you ABSOLUTELY SURE?"
+msgid "Delete project"
msgstr ""
msgid "Delete row"
@@ -11613,6 +11741,9 @@ msgstr ""
msgid "Delete this epic and all descendants?"
msgstr ""
+msgid "Delete this project"
+msgstr ""
+
msgid "Delete user list"
msgstr ""
@@ -11871,6 +12002,12 @@ msgstr ""
msgid "Deploy to..."
msgstr ""
+msgid "DeployBoards|To see deployment progress for your environments, make sure you are deploying to %{codeStart}$KUBE_NAMESPACE%{codeEnd} and annotating with %{codeStart}app.gitlab.com/app=$CI_PROJECT_PATH_SLUG%{codeEnd} and %{codeStart}app.gitlab.com/env=$CI_ENVIRONMENT_SLUG%{codeEnd}."
+msgstr ""
+
+msgid "DeployBoard|Kubernetes Pods"
+msgstr ""
+
msgid "DeployFreeze|Add a freeze period to prevent unintended releases during a period of time for a given environment. You must update the deployment jobs in %{filename} according to the deploy freezes added here. %{freeze_period_link_start}Learn more.%{freeze_period_link_end}"
msgstr ""
@@ -11955,9 +12092,6 @@ msgstr ""
msgid "DeployTokens|Active Deploy Tokens (%{active_tokens})"
msgstr ""
-msgid "DeployTokens|Allows read and write access to registry images."
-msgstr ""
-
msgid "DeployTokens|Allows read and write access to the package registry."
msgstr ""
@@ -11970,6 +12104,9 @@ msgstr ""
msgid "DeployTokens|Allows read-only access to the repository."
msgstr ""
+msgid "DeployTokens|Allows write access to registry images."
+msgstr ""
+
msgid "DeployTokens|Copy deploy token"
msgstr ""
@@ -12063,12 +12200,57 @@ msgstr ""
msgid "Deploying to AWS is easy with GitLab"
msgstr ""
+msgid "Deployment"
+msgstr ""
+
msgid "Deployment Frequency"
msgstr ""
+msgid "Deployment Target|Project deployment target (optional)"
+msgstr ""
+
+msgid "Deployment Target|Select the deployment target"
+msgstr ""
+
msgid "Deployment frequency"
msgstr ""
+msgid "DeploymentTarget|GitLab Pages"
+msgstr ""
+
+msgid "DeploymentTarget|Heroku"
+msgstr ""
+
+msgid "DeploymentTarget|Infrastructure provider (Terraform, Cloudformation, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Kubernetes (GKE, EKS, OpenShift, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Managed container runtime (Fargate, Cloud Run, DigitalOcean App)"
+msgstr ""
+
+msgid "DeploymentTarget|Mobile app store"
+msgstr ""
+
+msgid "DeploymentTarget|No deployment planned"
+msgstr ""
+
+msgid "DeploymentTarget|Other hosting service"
+msgstr ""
+
+msgid "DeploymentTarget|Registry (package or container)"
+msgstr ""
+
+msgid "DeploymentTarget|Self-managed container runtime (Podman, Docker Swarm, Docker Compose)"
+msgstr ""
+
+msgid "DeploymentTarget|Serverless backend (Lambda, Cloud functions)"
+msgstr ""
+
+msgid "DeploymentTarget|Virtual machine (for example, EC2)"
+msgstr ""
+
msgid "Deployments"
msgstr ""
@@ -12107,6 +12289,9 @@ msgstr ""
msgid "Deployment|This deployment was created using the API"
msgstr ""
+msgid "Deployment|Triggerer"
+msgstr ""
+
msgid "Deployment|Waiting"
msgstr ""
@@ -12134,6 +12319,18 @@ msgstr ""
msgid "Deprecated API rate limits"
msgstr ""
+msgid "Deprecations|Feature deprecation and removal"
+msgstr ""
+
+msgid "Deprecations|For information on a possible replacement %{epicStart} learn more about Opstrace %{epicEnd}."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7 and are %{epicStart} scheduled for removal %{epicEnd} in GitLab 15.0."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7, and are %{removal_link_start} scheduled for removal %{link_end} in GitLab 15.0. For information on a possible replacement, %{opstrace_link_start} learn more about Opstrace %{link_end}."
+msgstr ""
+
msgid "Deprioritize label"
msgstr ""
@@ -12379,10 +12576,10 @@ msgstr ""
msgid "DevopsAdoption|At least one deploy"
msgstr ""
-msgid "DevopsAdoption|At least one issue opened"
+msgid "DevopsAdoption|At least one issue created"
msgstr ""
-msgid "DevopsAdoption|At least one merge request opened"
+msgid "DevopsAdoption|At least one merge request created"
msgstr ""
msgid "DevopsAdoption|At least one pipeline successfully run"
@@ -12583,6 +12780,9 @@ msgstr ""
msgid "Direct member"
msgstr ""
+msgid "Direct members"
+msgstr ""
+
msgid "Direct non-authenticated users to this page."
msgstr ""
@@ -12699,6 +12899,9 @@ msgid_plural "Dismiss %d selected vulnerabilities as"
msgstr[0] ""
msgstr[1] ""
+msgid "Dismiss Alert"
+msgstr ""
+
msgid "Dismiss merge request promotion"
msgstr ""
@@ -12726,9 +12929,15 @@ msgstr ""
msgid "Display alerts from all configured monitoring tools."
msgstr ""
+msgid "Display milestones"
+msgstr ""
+
msgid "Display name"
msgstr ""
+msgid "Display progress of child issues"
+msgstr ""
+
msgid "Display rendered file"
msgstr ""
@@ -12834,6 +13043,9 @@ msgstr ""
msgid "Download image"
msgstr ""
+msgid "Download payload"
+msgstr ""
+
msgid "Download raw data (.csv)"
msgstr ""
@@ -13011,6 +13223,9 @@ msgstr ""
msgid "Edit in Web IDE"
msgstr ""
+msgid "Edit in pipeline editor"
+msgstr ""
+
msgid "Edit in single-file editor"
msgstr ""
@@ -13053,6 +13268,9 @@ msgstr ""
msgid "Edit your most recent comment in a thread (from an empty textarea)"
msgstr ""
+msgid "Edit, lint, and visualize your pipeline."
+msgstr ""
+
msgid "Edited"
msgstr ""
@@ -13494,6 +13712,9 @@ msgstr ""
msgid "Enforce two-factor authentication for all user sign-ins."
msgstr ""
+msgid "Enhance security by storing service account keys in secret managers - learn more about %{docLinkStart}secret management with GitLab%{docLinkEnd}"
+msgstr ""
+
msgid "Ensure connectivity is available from the GitLab server to the Prometheus server"
msgstr ""
@@ -13554,6 +13775,9 @@ 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 following to confirm:"
+msgstr ""
+
msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
@@ -14084,9 +14308,6 @@ 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 ""
@@ -14222,6 +14443,9 @@ msgstr ""
msgid "Errors:"
msgstr ""
+msgid "Escalate this incident"
+msgstr ""
+
msgid "Escalation Policies"
msgstr ""
@@ -14234,6 +14458,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy"
+msgstr ""
+
msgid "Escalation policy:"
msgstr ""
@@ -14485,6 +14712,9 @@ msgstr ""
msgid "Existing sign in methods may be removed"
msgstr ""
+msgid "Exit."
+msgstr ""
+
msgid "Expand"
msgstr ""
@@ -14581,6 +14811,9 @@ msgstr ""
msgid "Explore public groups"
msgstr ""
+msgid "Explore public projects"
+msgstr ""
+
msgid "Explore snippets"
msgstr ""
@@ -14742,7 +14975,7 @@ msgid_plural "Failed to archive designs. Please try again."
msgstr[0] ""
msgstr[1] ""
-msgid "Failed to assign a reviewer because no user was found."
+msgid "Failed to assign a reviewer because no user was specified."
msgstr ""
msgid "Failed to assign a user because no user was found."
@@ -14808,10 +15041,10 @@ msgstr ""
msgid "Failed to find import label for Jira import."
msgstr ""
-msgid "Failed to generate export, please try again later."
+msgid "Failed to find users for %{missing}"
msgstr ""
-msgid "Failed to generate report, please try again after sometime"
+msgid "Failed to generate export, please try again later."
msgstr ""
msgid "Failed to get ref."
@@ -14910,6 +15143,9 @@ msgstr ""
msgid "Failed to remove a to-do item for the design."
msgstr ""
+msgid "Failed to remove attention because no user was found."
+msgstr ""
+
msgid "Failed to remove mirror."
msgstr ""
@@ -14922,6 +15158,9 @@ msgstr ""
msgid "Failed to remove user key."
msgstr ""
+msgid "Failed to request attention because no user was found."
+msgstr ""
+
msgid "Failed to reset key. Please try again."
msgstr ""
@@ -15003,6 +15242,9 @@ msgstr ""
msgid "Feature Flags"
msgstr ""
+msgid "Feature deprecation and removal"
+msgstr ""
+
msgid "Feature flag status"
msgstr ""
@@ -15500,7 +15742,7 @@ msgstr ""
msgid "For each job, re-use the project workspace. If the workspace doesn't exist, use %{code_open}git clone%{code_close}."
msgstr ""
-msgid "For example, the application using the token or the purpose of the token."
+msgid "For example, the application using the token or the purpose of the token. Do not give sensitive information for the name of the token, as it will be visible to all %{resource_type} members."
msgstr ""
msgid "For files larger than this limit, only index the file name. The file content is neither indexed nor searchable."
@@ -15584,9 +15826,6 @@ msgstr ""
msgid "ForkProject|Select a namespace"
msgstr ""
-msgid "ForkProject|Select a namespace to fork the project"
-msgstr ""
-
msgid "ForkProject|The project can be accessed by any logged in user."
msgstr ""
@@ -15683,6 +15922,9 @@ msgstr ""
msgid "Full name"
msgstr ""
+msgid "GCP region configured"
+msgstr ""
+
msgid "GPG Key ID:"
msgstr ""
@@ -15863,6 +16105,9 @@ msgstr ""
msgid "Geo|Failed"
msgstr ""
+msgid "Geo|Filter Geo sites"
+msgstr ""
+
msgid "Geo|Filter by name"
msgstr ""
@@ -16274,6 +16519,12 @@ msgstr ""
msgid "GitLab Issue"
msgstr ""
+msgid "GitLab KAS"
+msgstr ""
+
+msgid "GitLab Memberships CSV Export"
+msgstr ""
+
msgid "GitLab Pages"
msgstr ""
@@ -16322,6 +16573,9 @@ 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 free to use. Many features for larger teams are part of our %{link_start}paid products%{link_end}. You can try Ultimate for free without any obligation or payment details."
+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 ""
@@ -16448,7 +16702,7 @@ msgstr ""
msgid "GitLabPages|When enabled, all attempts to visit your website through HTTP are automatically redirected to HTTPS using a response with status code 301. Requires a valid certificate for all domains. %{docs_link_start}Learn more.%{link_end}"
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. %{docs_link_start}Learn more.%{link_end}"
+msgid "GitLabPages|When using Pages under the general domain of a GitLab instance (%{pages_host}), you cannot use HTTPS with subdomains of subdomains. If your namespace or groupname contains a dot, it does not work. This is a limitation of the HTTP Over TLS protocol. HTTP pages work if you don't redirect HTTP to HTTPS. %{docs_link_start}Learn more.%{link_end}"
msgstr ""
msgid "GitLabPages|With GitLab Pages you can host your static website directly from your GitLab repository. %{docs_link_start}Learn more.%{link_end}"
@@ -16625,9 +16879,6 @@ msgstr ""
msgid "Go to find file"
msgstr ""
-msgid "Go to fork"
-msgstr ""
-
msgid "Go to issue boards"
msgstr ""
@@ -16835,9 +17086,6 @@ msgstr ""
msgid "Group Hooks"
msgstr ""
-msgid "Group ID"
-msgstr ""
-
msgid "Group Owner must have signed in with SAML before enabling Group Managed Accounts"
msgstr ""
@@ -16865,9 +17113,6 @@ msgstr ""
msgid "Group by"
msgstr ""
-msgid "Group description"
-msgstr ""
-
msgid "Group description (optional)"
msgstr ""
@@ -16982,7 +17227,7 @@ msgstr ""
msgid "Group: %{name}"
msgstr ""
-msgid "GroupActivityMetrics|Issues opened"
+msgid "GroupActivityMetrics|Issues created"
msgstr ""
msgid "GroupActivityMetrics|Last 90 days"
@@ -16991,7 +17236,7 @@ msgstr ""
msgid "GroupActivityMetrics|Members added"
msgstr ""
-msgid "GroupActivityMetrics|Merge Requests opened"
+msgid "GroupActivityMetrics|Merge Requests created"
msgstr ""
msgid "GroupActivityMetrics|Recent activity"
@@ -17282,6 +17527,9 @@ msgstr ""
msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
+msgid "GroupSettings|Choose a group path that does not start with a dash or end with a period. It can also contain alphanumeric characters and underscores."
+msgstr ""
+
msgid "GroupSettings|Compliance frameworks"
msgstr ""
@@ -17315,7 +17563,7 @@ msgstr ""
msgid "GroupSettings|If not specified at the group or instance level, the default is %{default_initial_branch_name}. Does not affect existing repositories."
msgstr ""
-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."
+msgid "GroupSettings|If the parent group's visibility is lower than the group's current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility."
msgstr ""
msgid "GroupSettings|New runners registration token has been generated!"
@@ -17432,7 +17680,10 @@ msgstr ""
msgid "Groups and projects"
msgstr ""
-msgid "Groups and subgroups"
+msgid "Groups are a great way to organize projects and people."
+msgstr ""
+
+msgid "Groups are the best way to manage projects and members."
msgstr ""
msgid "Groups to synchronize"
@@ -17543,13 +17794,16 @@ msgstr ""
msgid "GroupsTree|Are you sure you want to leave the \"%{fullName}\" group?"
msgstr ""
-msgid "GroupsTree|Edit group"
+msgid "GroupsTree|Delete"
+msgstr ""
+
+msgid "GroupsTree|Edit"
msgstr ""
msgid "GroupsTree|Failed to leave the group. Please make sure you are not the only owner."
msgstr ""
-msgid "GroupsTree|Leave this group"
+msgid "GroupsTree|Leave group"
msgstr ""
msgid "GroupsTree|Loading groups"
@@ -17561,9 +17815,57 @@ msgstr ""
msgid "GroupsTree|No groups or projects matched your search"
msgstr ""
+msgid "GroupsTree|Options"
+msgstr ""
+
msgid "GroupsTree|Search by name"
msgstr ""
+msgid "Groups|Avatar will be removed. Are you sure?"
+msgstr ""
+
+msgid "Groups|Changing group URL can have unintended side effects."
+msgstr ""
+
+msgid "Groups|Checking group URL availability..."
+msgstr ""
+
+msgid "Groups|Enter a descriptive name for your group."
+msgstr ""
+
+msgid "Groups|Group ID"
+msgstr ""
+
+msgid "Groups|Group URL"
+msgstr ""
+
+msgid "Groups|Group avatar"
+msgstr ""
+
+msgid "Groups|Group description (optional)"
+msgstr ""
+
+msgid "Groups|Group name"
+msgstr ""
+
+msgid "Groups|Group path is available."
+msgstr ""
+
+msgid "Groups|Group path is unavailable. Path has been replaced with a suggested available path."
+msgstr ""
+
+msgid "Groups|Learn more"
+msgstr ""
+
+msgid "Groups|Must start with letter, digit, emoji, or underscore. Can also contain periods, dashes, spaces, and parentheses."
+msgstr ""
+
+msgid "Groups|Remove avatar"
+msgstr ""
+
+msgid "Groups|Save changes"
+msgstr ""
+
msgid "Guideline"
msgstr ""
@@ -17573,6 +17875,9 @@ msgstr ""
msgid "HAR file path or URL"
msgstr ""
+msgid "HTTP Archive (HAR)"
+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 ""
@@ -17973,6 +18278,9 @@ msgstr ""
msgid "INFO: Your SSH key is expiring soon. Please generate a new key."
msgstr ""
+msgid "IP"
+msgstr ""
+
msgid "IP Address"
msgstr ""
@@ -18009,6 +18317,9 @@ msgstr ""
msgid "IdentityVerification|Verify your identity"
msgstr ""
+msgid "IdentityVerification|You can always verify your account at a later time to create a group."
+msgstr ""
+
msgid "If any indexed field exceeds this limit, it is truncated to this number of characters. The rest of the content is neither indexed nor searchable. This does not apply to repository and wiki indexing. For unlimited characters, set this to 0."
msgstr ""
@@ -18066,6 +18377,9 @@ msgstr ""
msgid "If you add %{codeStart}needs%{codeEnd} to jobs in your pipeline you'll be able to view the %{codeStart}needs%{codeEnd} relationships between jobs in this tab as a %{linkStart}Directed Acyclic Graph (DAG)%{linkEnd}."
msgstr ""
+msgid "If you are added to a project, it will be displayed here."
+msgstr ""
+
msgid "If you did not initiate these sign-in attempts, please reach out to your administrator or enable two-factor authentication (2FA) on your account."
msgstr ""
@@ -18372,12 +18686,24 @@ msgstr ""
msgid "InProductMarketing|3 ways to dive into GitLab CI/CD"
msgstr ""
+msgid "InProductMarketing|A single application eliminates complex integrations, data chokepoints, and toolchain maintenance, resulting in greater productivity and lower cost."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features, build more efficiently, strengthen security and compliance."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features."
+msgstr ""
+
msgid "InProductMarketing|Actually, GitLab makes the team work (better)"
msgstr ""
msgid "InProductMarketing|And finally %{deploy_link} a Python application."
msgstr ""
+msgid "InProductMarketing|And many more..."
+msgstr ""
+
msgid "InProductMarketing|Are your runners ready?"
msgstr ""
@@ -18396,15 +18722,33 @@ msgstr ""
msgid "InProductMarketing|Blog"
msgstr ""
+msgid "InProductMarketing|Break down silos to coordinate seamlessly across development, operations, and security with a consistent experience across the development lifecycle."
+msgstr ""
+
+msgid "InProductMarketing|Burn up/down charts"
+msgstr ""
+
msgid "InProductMarketing|By enabling code owners and required merge approvals the right person will review the right MR. This is a win-win: cleaner code and a more efficient review process."
msgstr ""
msgid "InProductMarketing|Click on the number below that corresponds with your answer — 1 being very difficult, 5 being very easy."
msgstr ""
+msgid "InProductMarketing|Code owners"
+msgstr ""
+
msgid "InProductMarketing|Code owners and required merge approvals are part of the paid tiers of GitLab. You can start a free 30-day trial of GitLab Ultimate and enable these features in less than 5 minutes with no credit card required."
msgstr ""
+msgid "InProductMarketing|Code review analytics"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration across stages in GitLab"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration made easy"
+msgstr ""
+
msgid "InProductMarketing|Create a custom CI runner with just a few clicks"
msgstr ""
@@ -18414,12 +18758,21 @@ msgstr ""
msgid "InProductMarketing|Create a project in GitLab in 5 minutes"
msgstr ""
+msgid "InProductMarketing|Create well-defined workflows by using scoped labels on issues, merge requests, and epics. Labels with the same scope cannot be used together, which prevents conflicts."
+msgstr ""
+
msgid "InProductMarketing|Create your first project!"
msgstr ""
+msgid "InProductMarketing|Define who owns specific files or directories, so the right reviewers are suggested when a merge request introduces changes to those files."
+msgstr ""
+
msgid "InProductMarketing|Deliver Better Products Faster"
msgstr ""
+msgid "InProductMarketing|Dependency scanning"
+msgstr ""
+
msgid "InProductMarketing|Did you know teams that use GitLab are far more efficient?"
msgstr ""
@@ -18429,15 +18782,27 @@ msgstr ""
msgid "InProductMarketing|Dig in and create a project and a repo"
msgstr ""
+msgid "InProductMarketing|Discover Premium & Ultimate"
+msgstr ""
+
+msgid "InProductMarketing|Discover Premium & Ultimate."
+msgstr ""
+
msgid "InProductMarketing|Do you have a minute?"
msgstr ""
msgid "InProductMarketing|Do you have a teammate who would be perfect for this task?"
msgstr ""
+msgid "InProductMarketing|Dynamic application security testing"
+msgstr ""
+
msgid "InProductMarketing|Easy"
msgstr ""
+msgid "InProductMarketing|Epics"
+msgstr ""
+
msgid "InProductMarketing|Expand your DevOps journey with a free GitLab trial"
msgstr ""
@@ -18459,9 +18824,15 @@ msgstr ""
msgid "InProductMarketing|Feel the need for speed?"
msgstr ""
+msgid "InProductMarketing|Find and fix bottlenecks in your code review process by understanding how long open merge requests have been in review."
+msgstr ""
+
msgid "InProductMarketing|Find out how your teams are really doing"
msgstr ""
+msgid "InProductMarketing|Find out if your external libraries are safe. Run dependency scanning jobs that check for known vulnerabilities in your external libraries."
+msgstr ""
+
msgid "InProductMarketing|Follow our steps"
msgstr ""
@@ -18498,6 +18869,9 @@ msgstr ""
msgid "InProductMarketing|GitLab is better with teammates to help out!"
msgstr ""
+msgid "InProductMarketing|GitLab is infrastructure agnostic (supporting GCP, AWS, Azure, OpenShift, VMWare, On Prem, Bare Metal, and more), offering a consistent workflow experience – irrespective of the environment."
+msgstr ""
+
msgid "InProductMarketing|GitLab provides static application security testing (SAST), dynamic application security testing (DAST), container scanning, and dependency scanning to help you deliver secure applications along with license compliance."
msgstr ""
@@ -18588,21 +18962,36 @@ msgstr ""
msgid "InProductMarketing|It's also possible to simply %{external_repo_link} in order to take advantage of GitLab's CI/CD."
msgstr ""
+msgid "InProductMarketing|Keep your code quality high by defining who should approve merge requests and how many approvals are required."
+msgstr ""
+
msgid "InProductMarketing|Launch GitLab CI/CD in 20 minutes or less"
msgstr ""
+msgid "InProductMarketing|Lower cost of development"
+msgstr ""
+
+msgid "InProductMarketing|Make it easier to collaborate on high-level ideas by grouping related issues in an epic."
+msgstr ""
+
msgid "InProductMarketing|Making the switch? It's easier than you think to import your projects into GitLab. Move %{github_link}, or import something %{bitbucket_link}."
msgstr ""
msgid "InProductMarketing|Master the art of importing!"
msgstr ""
+msgid "InProductMarketing|Merge request approval rule"
+msgstr ""
+
msgid "InProductMarketing|Move on to easily creating a Pages website %{ci_template_link}"
msgstr ""
msgid "InProductMarketing|Multiple owners, confusing workstreams? We've got you covered"
msgstr ""
+msgid "InProductMarketing|Multiple required approvers"
+msgstr ""
+
msgid "InProductMarketing|Need an alternative to importing?"
msgstr ""
@@ -18615,18 +19004,33 @@ msgstr ""
msgid "InProductMarketing|Our tool brings all the things together"
msgstr ""
+msgid "InProductMarketing|Protect your web application by using DAST to examine for vulnerabilities in deployed environments."
+msgstr ""
+
msgid "InProductMarketing|Rapid development, simplified"
msgstr ""
msgid "InProductMarketing|Reduce Security & Compliance Risk"
msgstr ""
+msgid "InProductMarketing|Require multiple approvers on a merge request, so you know it's in good shape before it's merged."
+msgstr ""
+
+msgid "InProductMarketing|Roadmaps"
+msgstr ""
+
+msgid "InProductMarketing|Scoped labels"
+msgstr ""
+
msgid "InProductMarketing|Security that's integrated into your development lifecycle"
msgstr ""
msgid "InProductMarketing|Sometimes you're not ready to make a full transition to a new tool. If you're not ready to fully commit, %{mirroring_link} gives you a safe way to try out GitLab in parallel with your current tool."
msgstr ""
+msgid "InProductMarketing|Speed. Efficiency. Trust."
+msgstr ""
+
msgid "InProductMarketing|Spin up an autoscaling runner in GitLab"
msgstr ""
@@ -18636,6 +19040,9 @@ msgstr ""
msgid "InProductMarketing|Start a Self-Managed trial"
msgstr ""
+msgid "InProductMarketing|Start a free trial"
+msgstr ""
+
msgid "InProductMarketing|Start a free trial of GitLab Ultimate – no credit card required"
msgstr ""
@@ -18702,6 +19109,9 @@ msgstr ""
msgid "InProductMarketing|To understand and get the most out of GitLab, start at the beginning and %{project_link}. In GitLab, repositories are part of a project, so after you've created your project you can go ahead and %{repo_link}."
msgstr ""
+msgid "InProductMarketing|Track completed issues in a chart, so you can see how a milestone is progressing at a glance."
+msgstr ""
+
msgid "InProductMarketing|Try GitLab Ultimate for free"
msgstr ""
@@ -18738,6 +19148,9 @@ msgstr ""
msgid "InProductMarketing|Very easy"
msgstr ""
+msgid "InProductMarketing|Visualize your epics and milestones in a timeline."
+msgstr ""
+
msgid "InProductMarketing|Want to host GitLab on your servers?"
msgstr ""
@@ -18759,6 +19172,9 @@ msgstr ""
msgid "InProductMarketing|YouTube"
msgstr ""
+msgid "InProductMarketing|Your software, deployed your way"
+msgstr ""
+
msgid "InProductMarketing|Your teams can be more efficient"
msgstr ""
@@ -18879,9 +19295,18 @@ msgstr ""
msgid "IncidentManagement|No incidents to display."
msgstr ""
+msgid "IncidentManagement|None"
+msgstr ""
+
msgid "IncidentManagement|Open"
msgstr ""
+msgid "IncidentManagement|Page your team with escalation policies"
+msgstr ""
+
+msgid "IncidentManagement|Paged"
+msgstr ""
+
msgid "IncidentManagement|Published"
msgstr ""
@@ -18891,6 +19316,9 @@ msgstr ""
msgid "IncidentManagement|Severity"
msgstr ""
+msgid "IncidentManagement|Status"
+msgstr ""
+
msgid "IncidentManagement|There are no closed incidents"
msgstr ""
@@ -18909,6 +19337,9 @@ msgstr ""
msgid "IncidentManagement|Unpublished"
msgstr ""
+msgid "IncidentManagement|Use escalation policies to automatically page your team when incidents are created."
+msgstr ""
+
msgid "IncidentSettings|Activate \"time to SLA\" countdown timer"
msgstr ""
@@ -18954,7 +19385,10 @@ msgstr ""
msgid "Incidents"
msgstr ""
-msgid "Incidents|Add a URL"
+msgid "Incidents|Add image details"
+msgstr ""
+
+msgid "Incidents|Add text or a link to display with your image. If you don't add either, the file name displays instead."
msgstr ""
msgid "Incidents|Drop or %{linkStart}upload%{linkEnd} a metric screenshot to attach it to the incident"
@@ -18969,10 +19403,10 @@ msgstr ""
msgid "Incidents|There was an issue loading metric images."
msgstr ""
-msgid "Incidents|There was an issue uploading your image."
+msgid "Incidents|There was an issue updating your image."
msgstr ""
-msgid "Incidents|You can optionally add a URL to link users to the original graph."
+msgid "Incidents|There was an issue uploading your image."
msgstr ""
msgid "Incident|Alert details"
@@ -18981,9 +19415,18 @@ msgstr ""
msgid "Incident|Are you sure you wish to delete this image?"
msgstr ""
+msgid "Incident|Delete image"
+msgstr ""
+
msgid "Incident|Deleting %{filename}"
msgstr ""
+msgid "Incident|Edit image text or link"
+msgstr ""
+
+msgid "Incident|Editing %{filename}"
+msgstr ""
+
msgid "Incident|Metrics"
msgstr ""
@@ -19253,12 +19696,18 @@ msgstr ""
msgid "Integrations|Branches for which notifications are to be sent"
msgstr ""
+msgid "Integrations|Clear if using a self-signed certificate."
+msgstr ""
+
msgid "Integrations|Comment detail:"
msgstr ""
msgid "Integrations|Comment settings:"
msgstr ""
+msgid "Integrations|Connection details"
+msgstr ""
+
msgid "Integrations|Connection failed. Please check your settings."
msgstr ""
@@ -19283,6 +19732,9 @@ msgstr ""
msgid "Integrations|Enable GitLab.com slash commands in a Slack workspace."
msgstr ""
+msgid "Integrations|Enable SSL verification"
+msgstr ""
+
msgid "Integrations|Enable comments"
msgstr ""
@@ -19361,6 +19813,9 @@ msgstr ""
msgid "Integrations|Return to GitLab for Jira"
msgstr ""
+msgid "Integrations|SSL verification"
+msgstr ""
+
msgid "Integrations|Save settings?"
msgstr ""
@@ -19406,9 +19861,6 @@ msgstr ""
msgid "Integrations|Use default settings"
msgstr ""
-msgid "Integrations|When you mention a Jira issue in a commit or merge request, GitLab creates a remote link and comment (if enabled)."
-msgstr ""
-
msgid "Integrations|You can now close this window and return to the GitLab for Jira application."
msgstr ""
@@ -19433,9 +19885,6 @@ msgstr ""
msgid "Integrations|can't exceed %{recipients_limit}"
msgstr ""
-msgid "Interactive developer security education."
-msgstr ""
-
msgid "Interactive mode"
msgstr ""
@@ -19925,6 +20374,9 @@ msgstr ""
msgid "IssueAnalytics|Assignees"
msgstr ""
+msgid "IssueAnalytics|Created by"
+msgstr ""
+
msgid "IssueAnalytics|Due date"
msgstr ""
@@ -19937,9 +20389,6 @@ msgstr ""
msgid "IssueAnalytics|Milestone"
msgstr ""
-msgid "IssueAnalytics|Opened by"
-msgstr ""
-
msgid "IssueAnalytics|Status"
msgstr ""
@@ -20063,10 +20512,10 @@ msgstr ""
msgid "IssuesAnalytics|Avg/Month:"
msgstr ""
-msgid "IssuesAnalytics|Issues opened"
+msgid "IssuesAnalytics|Issues created"
msgstr ""
-msgid "IssuesAnalytics|Issues opened per month"
+msgid "IssuesAnalytics|Issues created per month"
msgstr ""
msgid "IssuesAnalytics|Last 12 months"
@@ -20093,6 +20542,9 @@ msgstr ""
msgid "It looks like you have some draft commits in this branch."
msgstr ""
+msgid "It looks like you're attempting to activate your subscription. Use %{a_start}the Subscription page%{a_end} instead."
+msgstr ""
+
msgid "It may be several days before you see feature usage data."
msgstr ""
@@ -20321,6 +20773,9 @@ msgstr ""
msgid "JiraConnect|You can now close this window and return to Jira."
msgstr ""
+msgid "JiraConnect|You don't have permission to create branches for this project. Select a different project or contact the project owner for access. %{linkStart}Learn more.%{linkEnd}"
+msgstr ""
+
msgid "JiraRequest|A connection error occurred while connecting to Jira. Try your request again."
msgstr ""
@@ -20369,13 +20824,13 @@ msgstr ""
msgid "JiraService|Define the type of Jira issue to create from a vulnerability."
msgstr ""
-msgid "JiraService|Displaying Jira issues while leaving the GitLab issue functionality enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
+msgid "JiraService|Displaying Jira issues while leaving GitLab issues also enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
msgstr ""
-msgid "JiraService|Enable Jira issues"
+msgid "JiraService|Enable Jira issue creation from vulnerabilities"
msgstr ""
-msgid "JiraService|Enable Jira issues creation from vulnerabilities"
+msgid "JiraService|Enable Jira issues"
msgstr ""
msgid "JiraService|Enable Jira transitions"
@@ -20492,16 +20947,19 @@ msgstr ""
msgid "JiraService|View Jira issues in GitLab"
msgstr ""
-msgid "JiraService|Warning: All GitLab users that have access to this GitLab project are able to view all issues from the Jira project specified below."
+msgid "JiraService|Warning: All GitLab users with access to this GitLab project can view all issues from the Jira project you select."
msgstr ""
msgid "JiraService|Web URL"
msgstr ""
-msgid "JiraService|Work on Jira issues without leaving GitLab. Adds a Jira menu to access your list of Jira issues and view any issue as read-only."
+msgid "JiraService|When a Jira issue is mentioned in a commit or merge request, a remote link and comment (if enabled) will be created."
+msgstr ""
+
+msgid "JiraService|Work on Jira issues without leaving GitLab. Add a Jira menu to access a read-only list of your Jira issues."
msgstr ""
-msgid "JiraService|You need to configure Jira before enabling this integration. For more details, read the %{jira_doc_link_start}Jira integration documentation%{link_end}."
+msgid "JiraService|You must configure Jira before enabling this integration. %{jira_doc_link_start}Learn more.%{link_end}"
msgstr ""
msgid "Job"
@@ -20513,9 +20971,6 @@ msgstr ""
msgid "Job Failed #%{build_id}"
msgstr ""
-msgid "Job ID"
-msgstr ""
-
msgid "Job artifact"
msgstr ""
@@ -20582,9 +21037,27 @@ msgstr ""
msgid "Jobs|You're about to retry a job that failed because it attempted to deploy code that is older than the latest deployment. Retrying this job could result in overwriting the environment with the older source code."
msgstr ""
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source} into %{target}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{ref}"
+msgstr ""
+
+msgid "Job|Are you sure you want to erase this job log and artifacts?"
+msgstr ""
+
msgid "Job|Browse"
msgstr ""
+msgid "Job|Cancel"
+msgstr ""
+
msgid "Job|Complete Raw"
msgstr ""
@@ -20594,6 +21067,9 @@ msgstr ""
msgid "Job|Erase job log and artifacts"
msgstr ""
+msgid "Job|Finished at"
+msgstr ""
+
msgid "Job|Job artifacts"
msgstr ""
@@ -20606,7 +21082,7 @@ msgstr ""
msgid "Job|Keep"
msgstr ""
-msgid "Job|Pipeline"
+msgid "Job|Retry"
msgstr ""
msgid "Job|Scroll to bottom"
@@ -20618,6 +21094,9 @@ msgstr ""
msgid "Job|Show complete raw"
msgstr ""
+msgid "Job|Status"
+msgstr ""
+
msgid "Job|The artifacts were removed"
msgstr ""
@@ -20645,21 +21124,12 @@ msgstr ""
msgid "Job|delayed"
msgstr ""
-msgid "Job|for"
-msgstr ""
-
-msgid "Job|into"
-msgstr ""
-
msgid "Job|manual"
msgstr ""
msgid "Job|triggered"
msgstr ""
-msgid "Job|with"
-msgstr ""
-
msgid "Join Zoom meeting"
msgstr ""
@@ -20762,9 +21232,6 @@ msgstr ""
msgid "Ki"
msgstr ""
-msgid "Kontra"
-msgstr ""
-
msgid "Kroki"
msgstr ""
@@ -21088,6 +21555,9 @@ msgstr ""
msgid "Learn more about Auto DevOps"
msgstr ""
+msgid "Learn more about GitLab"
+msgstr ""
+
msgid "Learn more about Needs relationships"
msgstr ""
@@ -21415,9 +21885,18 @@ msgstr ""
msgid "Licenses|Displays licenses detected in the project, based on the %{linkStart}latest successful%{linkEnd} scan"
msgstr ""
+msgid "Licenses|Drag your license file here or %{linkStart}click to upload%{linkEnd}."
+msgstr ""
+
+msgid "Licenses|Drop your license file to start the upload."
+msgstr ""
+
msgid "Licenses|Error fetching the license list. Please check your network connection and try again."
msgstr ""
+msgid "Licenses|Error: You are trying to upload something other than a file"
+msgstr ""
+
msgid "Licenses|License Compliance"
msgstr ""
@@ -21436,6 +21915,9 @@ msgstr ""
msgid "Licenses|Specified policies in this project"
msgstr ""
+msgid "Licenses|The file could not be uploaded."
+msgstr ""
+
msgid "Licenses|The license list details information about the licenses used within your project."
msgstr ""
@@ -21469,11 +21951,6 @@ msgstr ""
msgid "Limit the size of Sidekiq jobs stored in Redis."
msgstr ""
-msgid "Limited to showing %d event at most"
-msgid_plural "Limited to showing %d events at most"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Limiting mode"
msgstr ""
@@ -21483,6 +21960,9 @@ msgstr ""
msgid "Link"
msgstr ""
+msgid "Link (optional)"
+msgstr ""
+
msgid "Link Prometheus monitoring to GitLab."
msgstr ""
@@ -21519,6 +21999,9 @@ msgstr ""
msgid "Linked emails (%{email_count})"
msgstr ""
+msgid "Linked epics"
+msgstr ""
+
msgid "Linked issues"
msgstr ""
@@ -21546,6 +22029,15 @@ msgstr ""
msgid "List of all merge commits"
msgstr ""
+msgid "List of environments for this project"
+msgstr ""
+
+msgid "List of suitable GCP locations"
+msgstr ""
+
+msgid "List of users allowed to exceed the rate limit."
+msgstr ""
+
msgid "List options"
msgstr ""
@@ -21765,6 +22257,9 @@ msgstr ""
msgid "Maintenance mode"
msgstr ""
+msgid "Make adjustments to how your GitLab instance is set up."
+msgstr ""
+
msgid "Make and review changes in the browser with the Web IDE"
msgstr ""
@@ -21909,6 +22404,12 @@ msgstr ""
msgid "MarkdownEditor|Add italic text (%{modifier_key}I)"
msgstr ""
+msgid "MarkdownEditor|Add strikethrough text (%{modifierKey}⇧X)"
+msgstr ""
+
+msgid "MarkdownEditor|Add strikethrough text (%{modifier_key}⇧X)"
+msgstr ""
+
msgid "Marked For Deletion At - %{deletion_time}"
msgstr ""
@@ -22170,6 +22671,9 @@ msgstr ""
msgid "Maximum push size (MB)"
msgstr ""
+msgid "Maximum requests per 10 minutes per user"
+msgstr ""
+
msgid "Maximum requests per minute"
msgstr ""
@@ -22260,6 +22764,19 @@ msgstr ""
msgid "Members of a group may only view projects they have permission to access"
msgstr ""
+msgid "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seat in use and will be billed for the overage."
+msgid_plural "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seats in use and will be billed for the overage."
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "MembersOverage|You are about to incur additional charges"
+msgstr ""
+
+msgid "MembersOverage|Your subscription includes %d seat."
+msgid_plural "MembersOverage|Your subscription includes %d seats."
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Membership"
msgstr ""
@@ -22464,9 +22981,6 @@ msgstr ""
msgid "Merge request not merged"
msgstr ""
-msgid "Merge request pipelines 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 merge request pipelines."
-msgstr ""
-
msgid "Merge request reports"
msgstr ""
@@ -22563,13 +23077,13 @@ msgstr ""
msgid "MergeRequests|Create issue to resolve thread"
msgstr ""
-msgid "MergeRequests|Failed to squash. Should be done manually."
+msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Saving the comment failed"
+msgid "MergeRequests|Squashing failed: Squash the commits locally, resolve any conflicts, then push the branch."
msgstr ""
-msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
+msgid "MergeRequests|Squashing not allowed: This project doesn't allow you to squash commits when merging."
msgstr ""
msgid "MergeRequests|Thread stays resolved"
@@ -23410,6 +23924,18 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "MrList|Assigned to %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from assignee %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from reviewer %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Review requested from %{name}, go to their profile."
+msgstr ""
+
msgid "Multi-project"
msgstr ""
@@ -23443,7 +23969,7 @@ msgstr ""
msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "My Awesome Group"
+msgid "My awesome group"
msgstr ""
msgid "My company or team"
@@ -24065,9 +24591,6 @@ msgstr ""
msgid "No available branches"
msgstr ""
-msgid "No available groups to fork the project."
-msgstr ""
-
msgid "No branches found"
msgstr ""
@@ -24278,6 +24801,9 @@ msgstr ""
msgid "No ref selected"
msgstr ""
+msgid "No regions configured"
+msgstr ""
+
msgid "No related merge requests found."
msgstr ""
@@ -25082,6 +25608,9 @@ msgstr ""
msgid "Only reCAPTCHA v2 is supported:"
msgstr ""
+msgid "Only required if not using role instance credentials."
+msgstr ""
+
msgid "Only use lowercase letters, numbers, and underscores."
msgstr ""
@@ -25106,9 +25635,6 @@ msgstr ""
msgid "Open a CLI and connect to the cluster you want to install the agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
-msgid "Open epics"
-msgstr ""
-
msgid "Open errors"
msgstr ""
@@ -25148,7 +25674,7 @@ msgstr ""
msgid "Opened issues"
msgstr ""
-msgid "OpenedNDaysAgo|Opened"
+msgid "OpenedNDaysAgo|Created"
msgstr ""
msgid "Opens in a new window"
@@ -25193,9 +25719,6 @@ msgstr ""
msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
-msgid "Optional."
-msgstr ""
-
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
msgstr ""
@@ -25984,6 +26507,9 @@ msgstr ""
msgid "PerformanceBar|Memory"
msgstr ""
+msgid "PerformanceBar|Memory report"
+msgstr ""
+
msgid "PerformanceBar|Redis calls"
msgstr ""
@@ -26017,18 +26543,12 @@ msgstr ""
msgid "PerformanceBar|wall"
msgstr ""
-msgid "Performs a rebase but skips triggering a new pipeline"
-msgstr ""
-
msgid "Period in seconds"
msgstr ""
msgid "Permalink"
msgstr ""
-msgid "Permanently delete project"
-msgstr ""
-
msgid "Permanently remove group"
msgstr ""
@@ -26299,6 +26819,51 @@ msgstr ""
msgid "PipelineStatusTooltip|Pipeline: %{ci_status}"
msgstr ""
+msgid "PipelineWizardDefaultCommitMessage|Add %{filename}"
+msgstr ""
+
+msgid "PipelineWizardDefaultCommitMessage|Update %{filename}"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|At least one entry is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This field is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This value is not valid"
+msgstr ""
+
+msgid "PipelineWizardListWidget|add another step"
+msgstr ""
+
+msgid "PipelineWizardListWidget|remove step"
+msgstr ""
+
+msgid "PipelineWizard|Commit"
+msgstr ""
+
+msgid "PipelineWizard|Commit Message"
+msgstr ""
+
+msgid "PipelineWizard|Commit changes to your file"
+msgstr ""
+
+msgid "PipelineWizard|Commit file to Branch"
+msgstr ""
+
+msgid "PipelineWizard|Commit your new file"
+msgstr ""
+
+msgid "PipelineWizard|The file has been committed."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem committing the changes."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem while checking whether your file already exists in the specified branch."
+msgstr ""
+
msgid "Pipelines"
msgstr ""
@@ -26413,7 +26978,7 @@ msgstr ""
msgid "Pipelines|Project cache successfully reset."
msgstr ""
-msgid "Pipelines|Revoke"
+msgid "Pipelines|Revoke trigger"
msgstr ""
msgid "Pipelines|Something went wrong while cleaning runners cache."
@@ -26458,6 +27023,12 @@ msgstr ""
msgid "Pipelines|This is a child pipeline within the parent pipeline"
msgstr ""
+msgid "Pipelines|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipelines|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipelines|This pipeline will run code originating from a forked project merge request. This means that the code can potentially have security considerations like exposing CI variables."
msgstr ""
@@ -26500,9 +27071,6 @@ msgstr ""
msgid "Pipelines|Your changes have been successfully committed. Now redirecting to the new merge request page."
msgstr ""
-msgid "Pipelines|detached"
-msgstr ""
-
msgid "Pipelines|error"
msgstr ""
@@ -26512,10 +27080,13 @@ msgstr ""
msgid "Pipelines|latest"
msgstr ""
-msgid "Pipelines|stuck"
+msgid "Pipelines|merge request"
msgstr ""
-msgid "Pipelines|train"
+msgid "Pipelines|merge train"
+msgstr ""
+
+msgid "Pipelines|stuck"
msgstr ""
msgid "Pipelines|yaml invalid"
@@ -26647,6 +27218,12 @@ msgstr ""
msgid "Pipeline|This change will not change the overall test coverage if merged."
msgstr ""
+msgid "Pipeline|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipeline|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipeline|Trigger author"
msgstr ""
@@ -26671,6 +27248,12 @@ msgstr ""
msgid "Pipeline|for"
msgstr ""
+msgid "Pipeline|merge request"
+msgstr ""
+
+msgid "Pipeline|merge train"
+msgstr ""
+
msgid "Pipeline|on"
msgstr ""
@@ -26809,9 +27392,6 @@ msgstr ""
msgid "Please enter a valid time interval"
msgstr ""
-msgid "Please enter or upload a valid license."
-msgstr ""
-
msgid "Please enter your current password."
msgstr ""
@@ -26920,9 +27500,6 @@ msgstr ""
msgid "Please type %{phrase_code} to proceed or close this modal to cancel."
msgstr ""
-msgid "Please type the following to confirm:"
-msgstr ""
-
msgid "Please use this form to report to the admin users who create spam issues, comments or behave inappropriately."
msgstr ""
@@ -26950,12 +27527,27 @@ msgstr ""
msgid "Policies"
msgstr ""
+msgid "Policy '%{escalation_policy_name}' does not exist."
+msgstr ""
+
msgid "Policy management project does have any policies in %{policy_path}"
msgstr ""
msgid "Policy project doesn't exist"
msgstr ""
+msgid "PolicyRuleMultiSelect|%{firstLabel} +%{numberOfAdditionalLabels} more"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|All %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select all"
+msgstr ""
+
msgid "Polling interval multiplier"
msgstr ""
@@ -27184,6 +27776,9 @@ msgstr ""
msgid "Private projects can be created in your personal namespace with:"
msgstr ""
+msgid "Problem with %{name} command: %{message}."
+msgstr ""
+
msgid "Proceed"
msgstr ""
@@ -27658,6 +28253,9 @@ msgstr ""
msgid "Progress"
msgstr ""
+msgid "Progress tracking"
+msgstr ""
+
msgid "Project"
msgstr ""
@@ -27889,6 +28487,9 @@ msgstr ""
msgid "ProjectQualitySummary|Failure"
msgstr ""
+msgid "ProjectQualitySummary|Get insight into the overall percentage of tests in your project that succeed, fail and are skipped."
+msgstr ""
+
msgid "ProjectQualitySummary|Latest pipeline results"
msgstr ""
@@ -27907,6 +28508,12 @@ msgstr ""
msgid "ProjectQualitySummary|See project Code Coverage Statistics"
msgstr ""
+msgid "ProjectQualitySummary|Set up test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|Set up test runs (opens in a new tab)"
+msgstr ""
+
msgid "ProjectQualitySummary|Skipped"
msgstr ""
@@ -28183,13 +28790,19 @@ msgstr ""
msgid "ProjectSettings|LFS objects from this repository are available to forks. %{linkStart}How do I remove them?%{linkEnd}"
msgstr ""
+msgid "ProjectSettings|Learn about commit history."
+msgstr ""
+
+msgid "ProjectSettings|Leave empty to use default template."
+msgstr ""
+
msgid "ProjectSettings|Manage who can see the project in the public access directory."
msgstr ""
msgid "ProjectSettings|Manages large files such as audio, video, and graphics files."
msgstr ""
-msgid "ProjectSettings|Maximum 500 characters."
+msgid "ProjectSettings|Maximum %{maxLength} characters."
msgstr ""
msgid "ProjectSettings|Merge checks"
@@ -28330,6 +28943,9 @@ msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
msgstr ""
+msgid "ProjectSettings|The default template will be applied on save."
+msgstr ""
+
msgid "ProjectSettings|These checks must pass before merge requests can be merged."
msgstr ""
@@ -28384,6 +29000,9 @@ msgstr ""
msgid "ProjectSettings|What are badges?"
msgstr ""
+msgid "ProjectSettings|What are merge trains?"
+msgstr ""
+
msgid "ProjectSettings|When merge request pipelines are enabled in the CI/CD configuration file, pipelines validate the combined results of the source and target branches. %{link_start}How to configure merge request pipelines?%{link_end}"
msgstr ""
@@ -28501,6 +29120,9 @@ msgstr ""
msgid "Projects are organized into groups"
msgstr ""
+msgid "Projects are where you store your code, access issues, wiki and other features of GitLab."
+msgstr ""
+
msgid "Projects contributed to"
msgstr ""
@@ -28516,12 +29138,6 @@ msgstr ""
msgid "Projects to index"
msgstr ""
-msgid "Projects will be permanently deleted after a %{waiting_period}-day waiting period."
-msgstr ""
-
-msgid "Projects will be permanently deleted immediately."
-msgstr ""
-
msgid "Projects with critical vulnerabilities"
msgstr ""
@@ -28606,6 +29222,9 @@ msgstr ""
msgid "ProjectsNew|Import project"
msgstr ""
+msgid "ProjectsNew|Include a Getting Started README"
+msgstr ""
+
msgid "ProjectsNew|Initialize repository with a README"
msgstr ""
@@ -28621,6 +29240,9 @@ msgstr ""
msgid "ProjectsNew|Project description %{tag_start}(optional)%{tag_end}"
msgstr ""
+msgid "ProjectsNew|Recommended if you're new to GitLab"
+msgstr ""
+
msgid "ProjectsNew|Run CI/CD for external repository"
msgstr ""
@@ -29038,6 +29660,9 @@ msgstr ""
msgid "ProtectedBranch|Unprotect"
msgstr ""
+msgid "ProtectedBranch|Unprotect branch"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
@@ -29065,6 +29690,9 @@ msgstr ""
msgid "ProtectedEnvironment|Protected Environment (%{protected_environments_count})"
msgstr ""
+msgid "ProtectedEnvironment|Required approvals"
+msgstr ""
+
msgid "ProtectedEnvironment|Select an environment"
msgstr ""
@@ -29086,10 +29714,13 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|Unprotect tag"
+msgstr ""
+
msgid "ProtectedTags|default"
msgstr ""
-msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
+msgid "ProtectedTag|By default, protected tags restrict who can modify the tag."
msgstr ""
msgid "ProtectedTag|Learn more."
@@ -29152,6 +29783,9 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Public projects are an easy way to allow everyone to have read-only access."
+msgstr ""
+
msgid "Publish to status page"
msgstr ""
@@ -29308,9 +29942,6 @@ msgstr ""
msgid "QualitySummary|Project quality"
msgstr ""
-msgid "Quarters"
-msgstr ""
-
msgid "Query"
msgstr ""
@@ -29395,6 +30026,9 @@ msgstr ""
msgid "Read more about project permissions %{help_link_open}here%{help_link_close}"
msgstr ""
+msgid "Read more about related epics"
+msgstr ""
+
msgid "Read more about related issues"
msgstr ""
@@ -29425,10 +30059,7 @@ msgstr ""
msgid "Rebase source branch on the target branch."
msgstr ""
-msgid "Rebase without CI"
-msgstr ""
-
-msgid "Rebases and triggers a pipeline"
+msgid "Rebase without pipeline"
msgstr ""
msgid "Recaptcha verified?"
@@ -29479,9 +30110,6 @@ msgstr ""
msgid "Reconfigure"
msgstr ""
-msgid "Recovering projects"
-msgstr ""
-
msgid "Recovery Codes"
msgstr ""
@@ -29541,6 +30169,12 @@ msgstr ""
msgid "Regex pattern"
msgstr ""
+msgid "Region"
+msgstr ""
+
+msgid "Regions"
+msgstr ""
+
msgid "Register"
msgstr ""
@@ -29771,9 +30405,6 @@ msgstr ""
msgid "Remove all or specific reviewer(s)"
msgstr ""
-msgid "Remove approver"
-msgstr ""
-
msgid "Remove approvers"
msgstr ""
@@ -29789,6 +30420,9 @@ msgstr ""
msgid "Remove attention request"
msgstr ""
+msgid "Remove attention request(s)"
+msgstr ""
+
msgid "Remove avatar"
msgstr ""
@@ -29927,6 +30561,9 @@ msgstr ""
msgid "Removed an issue from an epic."
msgstr ""
+msgid "Removed attention from %{users_sentence}."
+msgstr ""
+
msgid "Removed attention request from @%{username}"
msgstr ""
@@ -29978,6 +30615,9 @@ msgstr ""
msgid "Removes an issue from an epic."
msgstr ""
+msgid "Removes attention from %{users_sentence}."
+msgstr ""
+
msgid "Removes parent epic %{epic_ref}."
msgstr ""
@@ -30089,6 +30729,9 @@ msgstr ""
msgid "Report abuse to admin"
msgstr ""
+msgid "Report is generating and will be sent to your email address."
+msgstr ""
+
msgid "Reported %{timeAgo} by %{reportedBy}"
msgstr ""
@@ -30378,6 +31021,15 @@ msgstr ""
msgid "Request attention"
msgstr ""
+msgid "Request attention from %{users_sentence}."
+msgstr ""
+
+msgid "Request attention from assignee or reviewer"
+msgstr ""
+
+msgid "Request attention from assignee(s) or reviewer(s)"
+msgstr ""
+
msgid "Request attention to review"
msgstr ""
@@ -30402,6 +31054,9 @@ msgstr ""
msgid "Requested %{time_ago}"
msgstr ""
+msgid "Requested attention from %{users_sentence}."
+msgstr ""
+
msgid "Requested attention from @%{username}"
msgstr ""
@@ -30616,6 +31271,9 @@ msgstr ""
msgid "Restore project"
msgstr ""
+msgid "Restoring projects"
+msgstr ""
+
msgid "Restoring the group will prevent the group, its subgroups and projects from being removed on this date."
msgstr ""
@@ -30646,6 +31304,9 @@ msgstr ""
msgid "Retry"
msgstr ""
+msgid "Retry failed jobs"
+msgstr ""
+
msgid "Retry job"
msgstr ""
@@ -30693,9 +31354,6 @@ msgstr ""
msgid "Review changes"
msgstr ""
-msgid "Review requested from %{name}"
-msgstr ""
-
msgid "Review requests for you"
msgstr ""
@@ -30860,6 +31518,9 @@ msgstr ""
msgid "Runners|Assigned Group"
msgstr ""
+msgid "Runners|Assigned Projects (%{projectCount})"
+msgstr ""
+
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30929,6 +31590,9 @@ msgstr ""
msgid "Runners|Instance"
msgstr ""
+msgid "Runners|Jobs"
+msgstr ""
+
msgid "Runners|Last contact"
msgstr ""
@@ -31022,9 +31686,6 @@ msgstr ""
msgid "Runners|Runner %{name} was deleted"
msgstr ""
-msgid "Runners|Runner ID"
-msgstr ""
-
msgid "Runners|Runner assigned to project."
msgstr ""
@@ -31172,6 +31833,9 @@ msgstr ""
msgid "Runners|stale"
msgstr ""
+msgid "Runner|This runner has not run any jobs."
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -31286,6 +31950,24 @@ msgstr ""
msgid "Saving project."
msgstr ""
+msgid "ScanResultPolicy|%{ifLabelStart}if%{ifLabelEnd} %{scanners} scan in an open merge request targeting the %{branches} branch(es) finds %{vulnerabilitiesAllowed} or more %{severities} vulnerabilities that are %{vulnerabilityStates}"
+msgstr ""
+
+msgid "ScanResultPolicy|%{thenLabelStart}Then%{thenLabelEnd} Require approval from %{approvalsRequired} of the following approvers: %{approvers}"
+msgstr ""
+
+msgid "ScanResultPolicy|add an approver"
+msgstr ""
+
+msgid "ScanResultPolicy|scanners"
+msgstr ""
+
+msgid "ScanResultPolicy|severity levels"
+msgstr ""
+
+msgid "ScanResultPolicy|vulnerability states"
+msgstr ""
+
msgid "Scanner"
msgstr ""
@@ -31418,6 +32100,9 @@ msgstr ""
msgid "Search for a user"
msgstr ""
+msgid "Search for an emoji"
+msgstr ""
+
msgid "Search for projects, issues, etc."
msgstr ""
@@ -31605,18 +32290,12 @@ msgstr ""
msgid "Secret Detection"
msgstr ""
-msgid "Secret access key"
-msgstr ""
-
msgid "Secret token"
msgstr ""
msgid "Secure token that identifies an external storage request."
msgstr ""
-msgid "SecureCodeWarrior"
-msgstr ""
-
msgid "Security"
msgstr ""
@@ -31641,9 +32320,6 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "Security training with guide and learning pathways."
-msgstr ""
-
msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
@@ -31746,7 +32422,7 @@ msgstr ""
msgid "SecurityConfiguration|Manage corpus"
msgstr ""
-msgid "SecurityConfiguration|Manage corpus files used as mutation sources in coverage fuzzing."
+msgid "SecurityConfiguration|Manage corpus files used as seed inputs with coverage-guided fuzzing."
msgstr ""
msgid "SecurityConfiguration|Manage profiles for use by DAST scans."
@@ -31812,15 +32488,15 @@ msgstr ""
msgid "SecurityOrchestration|.yaml preview"
msgstr ""
-msgid "SecurityOrchestration|Action"
-msgstr ""
-
msgid "SecurityOrchestration|Actions"
msgstr ""
msgid "SecurityOrchestration|Add rule"
msgstr ""
+msgid "SecurityOrchestration|After dismissing the alert, the information will never be shown again."
+msgstr ""
+
msgid "SecurityOrchestration|All policies"
msgstr ""
@@ -31836,7 +32512,7 @@ msgstr ""
msgid "SecurityOrchestration|Description"
msgstr ""
-msgid "SecurityOrchestration|Disabled"
+msgid "SecurityOrchestration|Don't show the alert anymore"
msgstr ""
msgid "SecurityOrchestration|Edit policy"
@@ -31845,13 +32521,13 @@ msgstr ""
msgid "SecurityOrchestration|Edit policy project"
msgstr ""
-msgid "SecurityOrchestration|Enabled"
+msgid "SecurityOrchestration|Empty policy name"
msgstr ""
-msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Enabled"
msgstr ""
-msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
msgstr ""
msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
@@ -31860,7 +32536,7 @@ msgstr ""
msgid "SecurityOrchestration|Invalid policy type"
msgstr ""
-msgid "SecurityOrchestration|Latest scan"
+msgid "SecurityOrchestration|Latest scan run against %{agent}"
msgstr ""
msgid "SecurityOrchestration|Network"
@@ -31869,15 +32545,27 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No actions defined - policy will not run."
+msgstr ""
+
+msgid "SecurityOrchestration|No description"
+msgstr ""
+
msgid "SecurityOrchestration|No rules defined - policy will not run."
msgstr ""
+msgid "SecurityOrchestration|Not enabled"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
msgid "SecurityOrchestration|Policies"
msgstr ""
+msgid "SecurityOrchestration|Policy Type"
+msgstr ""
+
msgid "SecurityOrchestration|Policy cannot be enabled for non-existing branches (%{branches})"
msgstr ""
@@ -31902,10 +32590,13 @@ msgstr ""
msgid "SecurityOrchestration|Require %{approvals} %{plural} from %{approvers} if any of the following occur:"
msgstr ""
-msgid "SecurityOrchestration|Rule"
+msgid "SecurityOrchestration|Rules"
msgstr ""
-msgid "SecurityOrchestration|Rules"
+msgid "SecurityOrchestration|Runs %{actions} and %{lastAction} scans"
+msgstr ""
+
+msgid "SecurityOrchestration|Runs a %{action} scan"
msgstr ""
msgid "SecurityOrchestration|Scan Execution"
@@ -31965,6 +32656,9 @@ msgstr ""
msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
+msgid "SecurityOrchestration|This view only shows scan results for the agent %{agent}. You can view scan results for all agents in the %{linkStart}Operational Vulnerabilities tab of the vulnerability report%{linkEnd}."
+msgstr ""
+
msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
@@ -32019,9 +32713,6 @@ msgstr ""
msgid "SecurityOrchestration|users with ids"
msgstr ""
-msgid "SecurityOrchestration|view results"
-msgstr ""
-
msgid "SecurityOrchestration|vulnerabilities"
msgstr ""
@@ -32691,22 +33382,19 @@ 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|In order to start using functions as a service, you must first install Knative on your Kubernetes cluster. %{linkStart}More information%{linkEnd}"
-msgstr ""
-
msgid "Serverless|Learn more about Serverless"
msgstr ""
msgid "Serverless|No functions available"
msgstr ""
-msgid "Serverless|Sign up for First Look"
+msgid "Serverless|Serverless was %{linkStart}deprecated%{linkEnd} in GitLab 14.3."
+msgstr ""
+
+msgid "Serverless|Serverless was %{postLinkStart}deprecated%{postLinkEnd}. But if you opt to use it, you must install Knative in your Kubernetes cluster first. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "Serverless|The deploy job has not finished."
@@ -32718,9 +33406,6 @@ 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 ""
@@ -32736,9 +33421,6 @@ msgstr ""
msgid "Service Account Key"
msgstr ""
-msgid "Service Accounts"
-msgstr ""
-
msgid "Service Accounts keys authorize GitLab to deploy your Google Cloud project"
msgstr ""
@@ -32748,10 +33430,10 @@ msgstr ""
msgid "Service Desk allows people to create issues in your GitLab instance without their own user account. It provides a unique email address for end users to create issues in a project. Replies can be sent either through the GitLab interface or by email. End users only see threads through email."
msgstr ""
-msgid "Service Usage Data"
+msgid "Service account generated successfully"
msgstr ""
-msgid "Service account generated successfully"
+msgid "Service accounts"
msgstr ""
msgid "Service ping is disabled in your configuration file, and cannot be enabled through this form."
@@ -32895,6 +33577,9 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
+msgid "Set the per-user rate limit for getting a user by ID via the API."
+msgstr ""
+
msgid "Set the per-user rate limit for notes created by web or API requests."
msgstr ""
@@ -33074,6 +33759,9 @@ msgstr ""
msgid "Shared runners details"
msgstr ""
+msgid "Shared runners enabled cannot be enabled until a valid credit card is on file"
+msgstr ""
+
msgid "Shared runners help link"
msgstr ""
@@ -33131,6 +33819,9 @@ msgstr ""
msgid "Show all issues."
msgstr ""
+msgid "Show all milestones"
+msgstr ""
+
msgid "Show all test cases."
msgstr ""
@@ -33167,6 +33858,9 @@ msgstr ""
msgid "Show file contents"
msgstr ""
+msgid "Show group milestones"
+msgstr ""
+
msgid "Show labels"
msgstr ""
@@ -33182,6 +33876,12 @@ msgstr ""
msgid "Show open epics"
msgstr ""
+msgid "Show project milestones"
+msgstr ""
+
+msgid "Show sub-group milestones"
+msgstr ""
+
msgid "Show the Closed list"
msgstr ""
@@ -33191,11 +33891,6 @@ msgstr ""
msgid "Show whitespace changes"
msgstr ""
-msgid "Showing %d event"
-msgid_plural "Showing %d events"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Showing %{conflict} between %{sourceBranch} and %{targetBranch}"
msgstr ""
@@ -33255,12 +33950,6 @@ msgstr ""
msgid "Sidebar|None"
msgstr ""
-msgid "Sidebar|Only numeral characters allowed"
-msgstr ""
-
-msgid "Sidebar|Weight"
-msgstr ""
-
msgid "Sidekiq job compression threshold (bytes)"
msgstr ""
@@ -33423,6 +34112,9 @@ msgstr ""
msgid "Slack logo"
msgstr ""
+msgid "SlackIntegration|Are you sure you want to remove this project from the Slack application?"
+msgstr ""
+
msgid "SlackIntegration|GitLab for Slack"
msgstr ""
@@ -33432,6 +34124,9 @@ msgstr ""
msgid "SlackIntegration|Project alias"
msgstr ""
+msgid "SlackIntegration|Remove project"
+msgstr ""
+
msgid "SlackIntegration|Select a GitLab project to link with your Slack workspace."
msgstr ""
@@ -33576,9 +34271,6 @@ msgstr ""
msgid "Something went wrong trying to load issue contacts."
msgstr ""
-msgid "Something went wrong when creating a work item. Please try again"
-msgstr ""
-
msgid "Something went wrong when reordering designs. Please try again"
msgstr ""
@@ -33672,9 +34364,6 @@ msgstr ""
msgid "Something went wrong while inserting your image. Please try again."
msgstr ""
-msgid "Something went wrong while merging this merge request. Please try again."
-msgstr ""
-
msgid "Something went wrong while obtaining the Let's Encrypt certificate."
msgstr ""
@@ -33996,10 +34685,10 @@ 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."
+msgid "SourcegraphAdmin|Learn more."
msgstr ""
-msgid "SourcegraphAdmin|More information"
+msgid "SourcegraphAdmin|Only public projects have code intelligence enabled and communicate with Sourcegraph."
msgstr ""
msgid "SourcegraphAdmin|Save changes"
@@ -34008,7 +34697,7 @@ msgstr ""
msgid "SourcegraphAdmin|Sourcegraph URL"
msgstr ""
-msgid "SourcegraphAdmin|e.g. https://sourcegraph.example.com"
+msgid "SourcegraphAdmin|https://sourcegraph.example.com"
msgstr ""
msgid "SourcegraphPreferences|This feature is experimental and currently limited to certain projects."
@@ -34143,6 +34832,9 @@ msgstr ""
msgid "Start date"
msgstr ""
+msgid "Start free trial"
+msgstr ""
+
msgid "Start merge train"
msgstr ""
@@ -34173,6 +34865,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started escalation for this incident."
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -34185,6 +34880,9 @@ msgstr ""
msgid "Starts at (UTC)"
msgstr ""
+msgid "Starts escalations for this incident"
+msgstr ""
+
msgid "Starts on"
msgstr ""
@@ -34446,6 +35144,9 @@ msgstr ""
msgid "Strikethrough"
msgstr ""
+msgid "Strikethrough text"
+msgstr ""
+
msgid "Subgroup information"
msgstr ""
@@ -34680,6 +35381,21 @@ msgstr ""
msgid "Subscriptions"
msgstr ""
+msgid "Subscriptions|Chat with sales"
+msgstr ""
+
+msgid "Subscriptions|Close"
+msgstr ""
+
+msgid "Subscriptions|Not ready to buy yet?"
+msgstr ""
+
+msgid "Subscriptions|Start a free trial"
+msgstr ""
+
+msgid "Subscriptions|We understand. Maybe you have some questions for our sales team, or maybe you'd like to try some of the paid features first. What would you like to do?"
+msgstr ""
+
msgid "Subscription|Your subscription for %{strong}%{namespace_name}%{strong_close} has expired and you are now on %{pricing_link_start}the GitLab Free tier%{pricing_link_end}. Don't worry, your data is safe. Get in touch with our support team (%{support_email}). They'll gladly help with your subscription renewal."
msgstr ""
@@ -34890,6 +35606,9 @@ msgstr ""
msgid "SuperSonics|Maximum users"
msgstr ""
+msgid "SuperSonics|Offline cloud"
+msgstr ""
+
msgid "SuperSonics|Paste your activation code"
msgstr ""
@@ -34956,6 +35675,12 @@ msgstr ""
msgid "SuperSonics|You do not have an active subscription"
msgstr ""
+msgid "SuperSonics|You have a future dated license"
+msgstr ""
+
+msgid "SuperSonics|You have added a license that activates on %{date}. Please see the subscription history table below for more details."
+msgstr ""
+
msgid "SuperSonics|You have successfully added a license that activates on %{date}. Please see the subscription history table below for more details."
msgstr ""
@@ -35115,6 +35840,9 @@ msgstr ""
msgid "Tag name is required"
msgstr ""
+msgid "Tag push"
+msgstr ""
+
msgid "Tag push events"
msgstr ""
@@ -35217,6 +35945,9 @@ msgstr ""
msgid "TagsPage|protected"
msgstr ""
+msgid "Take a look at the documentation to discover all of GitLab’s capabilities."
+msgstr ""
+
msgid "Target Branch"
msgstr ""
@@ -35619,6 +36350,9 @@ msgstr ""
msgid "Tests"
msgstr ""
+msgid "Text (optional)"
+msgstr ""
+
msgid "Text added to the body of all email messages. %{character_limit} character limit"
msgstr ""
@@ -35669,6 +36403,9 @@ msgstr ""
msgid "The CSV export will be created in the background. Once finished, it will be sent to %{email} in an attachment."
msgstr ""
+msgid "The CSV export you requested of all user memberships is attached to this email."
+msgstr ""
+
msgid "The GitLab subscription service (customers.gitlab.com) is currently experiencing an outage. You can monitor the status and get updates at %{linkStart}status.gitlab.com%{linkEnd}."
msgstr ""
@@ -35744,6 +36481,9 @@ 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 epic"
+msgstr ""
+
msgid "The current issue"
msgstr ""
@@ -35905,6 +36645,9 @@ msgstr ""
msgid "The latest pipeline for this merge request has failed."
msgstr ""
+msgid "The license key is invalid."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -35920,6 +36663,9 @@ msgstr ""
msgid "The license was successfully uploaded and will be active from %{starts_at}. You can see the details below."
msgstr ""
+msgid "The license you uploaded is invalid. If the issue persists, contact support at %{link}."
+msgstr ""
+
msgid "The list creation wizard is already open"
msgstr ""
@@ -36541,10 +37287,13 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} and everything this project contains. %{strongOpen}There is no going back%{strongClose}"
+msgstr ""
+
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains."
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}on %{date}%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains. %{strongOpen}There is no going back.%{strongClose}"
msgstr ""
msgid "This action will %{strongOpen}permanently remove%{strongClose} %{codeOpen}%{group}%{codeClose} %{strongOpen}immediately%{strongClose}."
@@ -36673,9 +37422,6 @@ msgstr ""
msgid "This file was modified for readability, and can't accept suggestions. Edit it directly."
msgstr ""
-msgid "This forked project has the following:"
-msgstr ""
-
msgid "This form is disabled in preview"
msgstr ""
@@ -36688,7 +37434,7 @@ msgstr ""
msgid "This group can't be removed because it is linked to a subscription. To remove this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
-msgid "This group can't be transfered because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
+msgid "This group can't be transferred because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
msgid "This group cannot be invited to a project inside a group with enforced SSO"
@@ -36715,6 +37461,9 @@ 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 incident is already escalated with '%{escalation_policy_name}'."
+msgstr ""
+
msgid "This invitation was sent to %{mail_to_invite_email}, but you are signed in as %{link_to_current_user} with email %{mail_to_current_user}."
msgstr ""
@@ -36733,9 +37482,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 merge train pipeline"
-msgstr ""
-
msgid "This is a private email address %{helpIcon} generated just for you. Anyone who has it can create issues or merge requests as if they were you. If that happens, %{resetLinkStart}reset this token%{resetLinkEnd}."
msgstr ""
@@ -36757,6 +37503,12 @@ msgstr ""
msgid "This is your current session"
msgstr ""
+msgid "This issue cannot be assigned to a confidential epic because it is public."
+msgstr ""
+
+msgid "This issue cannot be made public because it belongs to a confidential epic."
+msgstr ""
+
msgid "This issue is confidential and should only be visible to team members with at least Reporter access."
msgstr ""
@@ -36874,6 +37626,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 branch is protected from force push."
+msgstr ""
+
msgid "This merge request cannot be rebased while there are conflicts."
msgstr ""
@@ -36925,9 +37680,15 @@ msgstr ""
msgid "This pipeline was triggered by a schedule."
msgstr ""
+msgid "This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project"
msgstr ""
+msgid "This project can be restored until %{date}."
+msgstr ""
+
msgid "This project cannot be %{visibilityLevel} because the visibility of %{openShowLink}%{name}%{closeShowLink} is %{visibility}. To make this project %{visibilityLevel}, you must first %{openEditLink}change the visibility%{closeEditLink} of the parent group."
msgstr ""
@@ -36946,6 +37707,9 @@ msgstr ""
msgid "This project is %{strongStart}NOT%{strongEnd} a fork, and has the following:"
msgstr ""
+msgid "This project is %{strongStart}NOT%{strongEnd} a fork. This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -37637,6 +38401,9 @@ msgstr ""
msgid "Today"
msgstr ""
+msgid "Todos count"
+msgstr ""
+
msgid "Todos|Are you looking for things to do? Take a look at %{strongStart}%{openIssuesLinkStart}open issues%{openIssuesLinkEnd}%{strongEnd}, contribute to %{strongStart}%{mergeRequestLinkStart}a merge request%{mergeRequestLinkEnd}%{mergeRequestLinkEnd}%{strongEnd}, or mention someone in a comment to automatically assign them a new to-do item."
msgstr ""
@@ -37910,10 +38677,8 @@ msgstr ""
msgid "Trending"
msgstr ""
-msgid "Trials|%{planName} Trial %{enDash} %{num} day left"
-msgid_plural "Trials|%{planName} Trial %{enDash} %{num} days left"
-msgstr[0] ""
-msgstr[1] ""
+msgid "Trials|%{planName} Trial"
+msgstr ""
msgid "Trials|Compare all plans"
msgstr ""
@@ -37921,6 +38686,9 @@ msgstr ""
msgid "Trials|Create a new group to start your GitLab Ultimate trial."
msgstr ""
+msgid "Trials|Day %{daysUsed}/%{duration}"
+msgstr ""
+
msgid "Trials|Go back to GitLab"
msgstr ""
@@ -38170,7 +38938,7 @@ msgstr ""
msgid "URL is triggered when repository is updated"
msgstr ""
-msgid "URL must be percent-encoded if neccessary."
+msgid "URL must be percent-encoded if necessary."
msgstr ""
msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
@@ -38389,6 +39157,9 @@ msgstr ""
msgid "Unlock account"
msgstr ""
+msgid "Unlock more features with GitLab Ultimate"
+msgstr ""
+
msgid "Unlock the discussion"
msgstr ""
@@ -38452,6 +39223,9 @@ msgstr ""
msgid "Unsubscribes from this %{quick_action_target}."
msgstr ""
+msgid "Unsupported sort value."
+msgstr ""
+
msgid "Unsupported todo type passed. Supported todo types are: %{todo_types}"
msgstr ""
@@ -38680,6 +39454,9 @@ msgstr ""
msgid "UsageQuota|File attachments and smaller design graphics."
msgstr ""
+msgid "UsageQuota|From %{storage_enforcement_date} storage limits will apply to this namespace. View and manage your usage in %{strong_start}Group Settings &gt; Usage quotas%{strong_end}."
+msgstr ""
+
msgid "UsageQuota|Git repository."
msgstr ""
@@ -38740,6 +39517,9 @@ msgstr ""
msgid "UsageQuota|Storage type"
msgstr ""
+msgid "UsageQuota|Storage used"
+msgstr ""
+
msgid "UsageQuota|This is the total amount of storage used across your projects within this namespace."
msgstr ""
@@ -38935,6 +39715,12 @@ msgstr ""
msgid "Use hashed storage paths for newly created and renamed repositories. Always enabled since 13.0."
msgstr ""
+msgid "Use issue count"
+msgstr ""
+
+msgid "Use issue weight"
+msgstr ""
+
msgid "Use one line per URI"
msgstr ""
@@ -39316,6 +40102,9 @@ msgstr ""
msgid "Users"
msgstr ""
+msgid "Users API rate limit"
+msgstr ""
+
msgid "Users can launch a development environment from a GitLab browser tab when the %{linkStart}Gitpod%{linkEnd} integration is enabled."
msgstr ""
@@ -39641,6 +40430,9 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View group pipeline usage quota"
+msgstr ""
+
msgid "View incident details at"
msgstr ""
@@ -39793,6 +40585,9 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
+msgid "Vulnerability"
+msgstr ""
+
msgid "Vulnerability Report"
msgstr ""
@@ -39844,6 +40639,9 @@ msgstr ""
msgid "VulnerabilityManagement|An unverified non-confirmed finding"
msgstr ""
+msgid "VulnerabilityManagement|At least one identifier is required"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -39853,12 +40651,24 @@ msgstr ""
msgid "VulnerabilityManagement|Create Jira issue"
msgstr ""
+msgid "VulnerabilityManagement|Enter a name"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE code"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE identifier URL"
+msgstr ""
+
msgid "VulnerabilityManagement|Fetching linked Jira issues"
msgstr ""
msgid "VulnerabilityManagement|Manually add a vulnerability entry into the vulnerability report."
msgstr ""
+msgid "VulnerabilityManagement|Name is a required field"
+msgstr ""
+
msgid "VulnerabilityManagement|Needs triage"
msgstr ""
@@ -39874,6 +40684,18 @@ msgstr ""
msgid "VulnerabilityManagement|Select a method"
msgstr ""
+msgid "VulnerabilityManagement|Select a severity level"
+msgstr ""
+
+msgid "VulnerabilityManagement|Select a status"
+msgstr ""
+
+msgid "VulnerabilityManagement|Severity is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Something went wrong while creating vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -39898,6 +40720,12 @@ msgstr ""
msgid "VulnerabilityManagement|Something went wrong, could not update vulnerability state."
msgstr ""
+msgid "VulnerabilityManagement|Status is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Submit vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Summary, detailed description, steps to reproduce, etc."
msgstr ""
@@ -40093,6 +40921,9 @@ msgstr ""
msgid "WARNING:"
msgstr ""
+msgid "WARNING: This snippet contains hidden files which might be used to mask malicious behavior. Exercise caution if cloning and executing code from this snippet."
+msgstr ""
+
msgid "Wait for the file to load to copy its contents"
msgstr ""
@@ -40312,6 +41143,15 @@ msgstr ""
msgid "Webhooks|An issue is created, updated, closed, or reopened."
msgstr ""
+msgid "Webhooks|Are you sure you want to delete this group hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this project hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this webhook?"
+msgstr ""
+
msgid "Webhooks|Comments"
msgstr ""
@@ -40321,6 +41161,9 @@ msgstr ""
msgid "Webhooks|Confidential issues events"
msgstr ""
+msgid "Webhooks|Delete webhook"
+msgstr ""
+
msgid "Webhooks|Deployment events"
msgstr ""
@@ -40554,6 +41397,9 @@ msgstr ""
msgid "Wiki"
msgstr ""
+msgid "Wiki page"
+msgstr ""
+
msgid "Wiki page was successfully created."
msgstr ""
@@ -40659,7 +41505,7 @@ msgstr ""
msgid "WikiPageConflictMessage|Someone edited the page the same time you did. Please check out %{wikiLinkStart}the page%{wikiLinkEnd} and make sure your changes will not unintentionally remove theirs."
msgstr ""
-msgid "WikiPage|An error occured while trying to render the content editor. Please try again later."
+msgid "WikiPage|An error occurred while trying to render the content editor. Please try again later."
msgstr ""
msgid "WikiPage|Are you sure you want to switch back to the classic editor?"
@@ -40818,6 +41664,18 @@ msgstr ""
msgid "WorkItem|New Task"
msgstr ""
+msgid "WorkItem|Something went wrong when creating a work item. Please try again"
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching the work item. Please try again."
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching work item types. Please try again"
+msgstr ""
+
+msgid "WorkItem|Type"
+msgstr ""
+
msgid "WorkItem|Work Items"
msgstr ""
@@ -40884,7 +41742,10 @@ msgstr ""
msgid "You are about to add %{usersTag} people to the discussion. They will all receive a notification."
msgstr ""
-msgid "You are about to permanently delete this project"
+msgid "You are about to delete this forked project containing:"
+msgstr ""
+
+msgid "You are about to delete this project containing:"
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."
@@ -40905,6 +41766,9 @@ msgstr ""
msgid "You are attempting to update a file that has changed since you started editing it."
msgstr ""
+msgid "You are billed if you exceed this number. %{qsrOverageLinkStart}How does billing work?%{qsrOverageLinkEnd}"
+msgstr ""
+
msgid "You are connected to the Prometheus server, but there is currently no data to display."
msgstr ""
@@ -40962,6 +41826,9 @@ msgstr ""
msgid "You are not authorized to update this scanner profile"
msgstr ""
+msgid "You are not authorized to upload metric images"
+msgstr ""
+
msgid "You are now impersonating %{username}"
msgstr ""
@@ -41115,9 +41982,6 @@ msgstr ""
msgid "You can only upload one design when dropping onto an existing design."
msgstr ""
-msgid "You can recover this project until %{date}"
-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 ""
@@ -41166,9 +42030,6 @@ msgstr ""
msgid "You cannot write to this read-only GitLab instance."
msgstr ""
-msgid "You can’t %{tag_start}edit%{tag_end} files directly in this project. Fork this project and submit a merge request with your changes."
-msgstr ""
-
msgid "You can’t edit files directly in this project. Fork this project and submit a merge request with your changes."
msgstr ""
@@ -41321,9 +42182,6 @@ 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 set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
@@ -41354,12 +42212,6 @@ msgstr ""
msgid "You must have maintainer access to force delete a lock"
msgstr ""
-msgid "You must have permission to create a project in a group before forking."
-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 ""
@@ -41765,7 +42617,7 @@ msgstr ""
msgid "Your public email will be displayed on your public profile."
msgstr ""
-msgid "Your request for access could not be processed: %{error_meesage}"
+msgid "Your request for access could not be processed: %{error_message}"
msgstr ""
msgid "Your request for access has been queued for review."
@@ -41948,6 +42800,9 @@ msgstr ""
msgid "archived:"
msgstr ""
+msgid "artifacts"
+msgstr ""
+
msgid "assign yourself"
msgstr ""
@@ -41977,6 +42832,9 @@ msgstr[1] ""
msgid "branch name"
msgstr ""
+msgid "builds"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -42400,6 +43258,9 @@ msgstr ""
msgid "contact with same email already exists in group hierarchy"
msgstr ""
+msgid "container registry images"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -42439,6 +43300,9 @@ msgstr ""
msgid "data"
msgstr ""
+msgid "database"
+msgstr ""
+
msgid "date must not be after 9999-12-31"
msgstr ""
@@ -42462,9 +43326,6 @@ msgstr ""
msgid "design"
msgstr ""
-msgid "detached"
-msgstr ""
-
msgid "disabled"
msgstr ""
@@ -42713,7 +43574,7 @@ msgstr ""
msgid "is not a valid X509 certificate."
msgstr ""
-msgid "is not allowed for sign-up."
+msgid "is not allowed for sign-up. Please use your regular email address."
msgstr ""
msgid "is not allowed for this group."
@@ -42725,7 +43586,7 @@ msgstr ""
msgid "is not allowed since the group is not top-level group."
msgstr ""
-msgid "is not allowed."
+msgid "is not allowed. Please use your regular email address."
msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
@@ -42812,6 +43673,9 @@ msgstr ""
msgid "level: %{level}"
msgstr ""
+msgid "lfs objects"
+msgstr ""
+
msgid "limit of %{project_limit} reached"
msgstr ""
@@ -43031,6 +43895,9 @@ msgstr ""
msgid "mrWidget|Merge blocked: pipeline must succeed. It's waiting for a manual action to continue."
msgstr ""
+msgid "mrWidget|Merge blocked: pipeline must succeed. Push a commit that fixes the failure, or %{linkStart}learn about other solutions.%{linkEnd}"
+msgstr ""
+
msgid "mrWidget|Merge blocked: this merge request must be approved."
msgstr ""
@@ -43148,9 +44015,6 @@ msgstr ""
msgid "mrWidget|The changes were not merged into"
msgstr ""
-msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -43298,9 +44162,6 @@ msgstr ""
msgid "open issue"
msgstr ""
-msgid "opened %{timeAgo}"
-msgstr ""
-
msgid "or"
msgstr ""
@@ -43312,6 +44173,12 @@ msgid_plural "out of %d total tests"
msgstr[0] ""
msgstr[1] ""
+msgid "packages"
+msgstr ""
+
+msgid "pages"
+msgstr ""
+
msgid "parent"
msgid_plural "parents"
msgstr[0] ""
@@ -43461,6 +44328,9 @@ msgid_plural "replies"
msgstr[0] ""
msgstr[1] ""
+msgid "repositories"
+msgstr ""
+
msgid "repository:"
msgstr ""
@@ -43581,12 +44451,18 @@ msgstr ""
msgid "tag name"
msgstr ""
+msgid "terraform states"
+msgstr ""
+
msgid "the correct format."
msgstr ""
msgid "the file"
msgstr ""
+msgid "the following epic(s)"
+msgstr ""
+
msgid "the following issue(s)"
msgstr ""
@@ -43599,21 +44475,12 @@ msgstr ""
msgid "this document"
msgstr ""
-msgid "this issue cannot be assigned to a confidential epic since it is public"
-msgstr ""
-
-msgid "this issue cannot be made public since it belongs to a confidential epic"
-msgstr ""
-
msgid "time summary"
msgstr ""
msgid "toggle collapse"
msgstr ""
-msgid "train"
-msgstr ""
-
msgid "triggered"
msgstr ""
@@ -43742,3 +44609,6 @@ msgstr ""
msgid "{project}"
msgstr ""
+msgid "✔"
+msgstr ""
+
diff --git a/locale/az_AZ/gitlab.po b/locale/az_AZ/gitlab.po
index d84a094fa86..9ac97ca2078 100644
--- a/locale/az_AZ/gitlab.po
+++ b/locale/az_AZ/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: az\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2022-02-02 15:44\n"
+"PO-Revision-Date: 2022-03-01 20:37\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -146,6 +146,11 @@ msgid_plural "%d approvers (you've approved)"
msgstr[0] ""
msgstr[1] ""
+msgid "%d assigned issue"
+msgid_plural "%d assigned issues"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -421,8 +426,23 @@ msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
msgstr[1] ""
-msgid "%d vulnerability updated"
-msgid_plural "%d vulnerabilities updated"
+msgid "%d vulnerability set to confirmed"
+msgid_plural "%d vulnerabilities set to confirmed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to dismissed"
+msgid_plural "%d vulnerabilities set to dismissed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to needs triage"
+msgid_plural "%d vulnerabilities set to needs triage"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to resolved"
+msgid_plural "%d vulnerabilities set to resolved"
msgstr[0] ""
msgstr[1] ""
@@ -510,6 +530,12 @@ msgstr[1] ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{completed} of %{total} issues closed"
+msgstr ""
+
+msgid "%{completed} of %{total} weight completed"
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -858,6 +884,9 @@ msgstr ""
msgid "%{openedIssues} open, %{closedIssues} closed"
msgstr ""
+msgid "%{percentage}%% issues closed"
+msgstr ""
+
msgid "%{percentage}%% weight completed"
msgstr ""
@@ -1287,6 +1316,9 @@ msgid_plural "- Users"
msgstr[0] ""
msgstr[1] ""
+msgid "- of - issues closed"
+msgstr ""
+
msgid "- of - weight completed"
msgstr ""
@@ -1429,7 +1461,7 @@ msgstr ""
msgid "1000+"
msgstr ""
-msgid "192.168.0.0/24"
+msgid "192.168.0.0/24 or 2001:0DB8:1234::/48"
msgstr ""
msgid "1st contribution!"
@@ -1741,13 +1773,13 @@ msgstr ""
msgid "AWS Access Key"
msgstr ""
-msgid "AWS Access Key. Only required if not using role instance credentials"
+msgid "AWS Secret Access Key"
msgstr ""
-msgid "AWS Secret Access Key"
+msgid "AWS access key ID (Optional)"
msgstr ""
-msgid "AWS Secret Access Key. Only required if not using role instance credentials"
+msgid "AWS secret access key (Optional)"
msgstr ""
msgid "AWS service error: %{error}"
@@ -1807,9 +1839,6 @@ msgstr ""
msgid "Access granted"
msgstr ""
-msgid "Access key ID"
-msgstr ""
-
msgid "Access requests"
msgstr ""
@@ -1984,7 +2013,7 @@ msgstr ""
msgid "Activity"
msgstr ""
-msgid "Activity|An error occured while retrieving activity. Reload the page to try again."
+msgid "Activity|An error occurred while retrieving activity. Reload the page to try again."
msgstr ""
msgid "Add"
@@ -2023,6 +2052,9 @@ msgstr ""
msgid "Add a %{type}"
msgstr ""
+msgid "Add a GCP region"
+msgstr ""
+
msgid "Add a GPG key"
msgstr ""
@@ -2074,6 +2106,9 @@ msgstr ""
msgid "Add a numbered list"
msgstr ""
+msgid "Add a related epic"
+msgstr ""
+
msgid "Add a related issue"
msgstr ""
@@ -2188,6 +2223,9 @@ msgstr ""
msgid "Add or subtract spent time"
msgstr ""
+msgid "Add people"
+msgstr ""
+
msgid "Add previously merged commits"
msgstr ""
@@ -2254,6 +2292,9 @@ msgstr ""
msgid "Add webhook"
msgstr ""
+msgid "Add your team members and others to GitLab."
+msgstr ""
+
msgid "Add/remove"
msgstr ""
@@ -3076,12 +3117,6 @@ msgstr ""
msgid "AdvancedSearch|Reindex required"
msgstr ""
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. Permanently deleting this project will %{strongStart}immediately delete%{strongEnd} its repositories and %{strongStart}all related resources%{strongEnd}, including issues, merge requests etc."
-msgstr ""
-
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. You will lose this project's repository and %{strongStart}all related resources%{strongEnd}, including issues and merge requests."
-msgstr ""
-
msgid "After a successful password update you will be redirected to login screen."
msgstr ""
@@ -3112,6 +3147,9 @@ msgstr ""
msgid "Akismet helps prevent the creation of spam issues in public projects."
msgstr ""
+msgid "Alert"
+msgstr ""
+
msgid "AlertManagement|Acknowledged"
msgstr ""
@@ -3484,9 +3522,6 @@ msgstr ""
msgid "All environments"
msgstr ""
-msgid "All epics"
-msgstr ""
-
msgid "All groups and projects"
msgstr ""
@@ -4223,12 +4258,15 @@ msgstr ""
msgid "ApplicationSettings|Approve users in the pending approval status?"
msgstr ""
-msgid "ApplicationSettings|By making this change, you will automatically approve %d user with the pending approval status."
-msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users with the pending approval status."
+msgid "ApplicationSettings|Approve users who are pending approval?"
+msgstr ""
+
+msgid "ApplicationSettings|By making this change, you will automatically approve %d user who is pending approval."
+msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users who are pending approval."
msgstr[0] ""
msgstr[1] ""
-msgid "ApplicationSettings|By making this change, you will automatically approve all users in pending approval status."
+msgid "ApplicationSettings|By making this change, you will automatically approve all users who are pending approval."
msgstr ""
msgid "ApplicationSettings|Denied domains for sign-ups"
@@ -4634,10 +4672,10 @@ msgstr ""
msgid "Archiving the project will make it entirely read-only. It is hidden from the dashboard and doesn't show up in searches. %{strong_start}The repository cannot be committed to, and no issues, comments, or other entities can be created.%{strong_end} %{link_start}Learn more.%{link_end}"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to delete this project?"
+msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
+msgid "Are you absolutely sure?"
msgstr ""
msgid "Are you sure that you want to archive this project?"
@@ -4673,12 +4711,18 @@ msgstr ""
msgid "Are you sure you want to delete this SSH key?"
msgstr ""
+msgid "Are you sure you want to delete this comment?"
+msgstr ""
+
msgid "Are you sure you want to delete this deploy key?"
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 label?"
+msgstr ""
+
msgid "Are you sure you want to delete this pipeline schedule?"
msgstr ""
@@ -4694,9 +4738,6 @@ msgstr ""
msgid "Are you sure you want to discard your changes?"
msgstr ""
-msgid "Are you sure you want to erase this build?"
-msgstr ""
-
msgid "Are you sure you want to import %d repository?"
msgid_plural "Are you sure you want to import %d repositories?"
msgstr[0] ""
@@ -4744,6 +4785,9 @@ msgstr ""
msgid "Are you sure you want to remove this list?"
msgstr ""
+msgid "Are you sure you want to remove this nickname?"
+msgstr ""
+
msgid "Are you sure you want to reset the health check token?"
msgstr ""
@@ -4756,10 +4800,10 @@ 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?"
+msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
msgstr ""
-msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
+msgid "Are you sure you want to revoke this project access token? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to stop this environment?"
@@ -4906,9 +4950,6 @@ msgstr ""
msgid "Assigned to %{assignee_name}"
msgstr ""
-msgid "Assigned to %{name}"
-msgstr ""
-
msgid "Assigned to me"
msgstr ""
@@ -4973,6 +5014,9 @@ msgstr[1] ""
msgid "Attaching the file failed."
msgstr ""
+msgid "Attention"
+msgstr ""
+
msgid "Audit Events"
msgstr ""
@@ -5135,6 +5179,12 @@ msgstr ""
msgid "Authorized applications (%{size})"
msgstr ""
+msgid "AuthorizedApplication|Are you sure you want to revoke this application?"
+msgstr ""
+
+msgid "AuthorizedApplication|Revoke application"
+msgstr ""
+
msgid "Authors: %{authors}"
msgstr ""
@@ -6328,6 +6378,9 @@ msgstr ""
msgid "CICDAnalytics|Shared Runners Usage"
msgstr ""
+msgid "CICDAnalytics|Shared runner pipeline minute duration by month"
+msgstr ""
+
msgid "CICDAnalytics|Shared runner usage"
msgstr ""
@@ -6469,6 +6522,9 @@ msgstr ""
msgid "Can create groups:"
msgstr ""
+msgid "Can not delete primary training"
+msgstr ""
+
msgid "Can't apply as the source branch was deleted."
msgstr ""
@@ -6802,9 +6858,6 @@ msgstr ""
msgid "Changing any setting here requires an application restart"
msgstr ""
-msgid "Changing group URL can have unintended side effects."
-msgstr ""
-
msgid "Charts can't be displayed as the request for data has timed out. %{documentationLink}"
msgstr ""
@@ -6892,9 +6945,6 @@ msgstr ""
msgid "Checking branch availability..."
msgstr ""
-msgid "Checking group URL availability..."
-msgstr ""
-
msgid "Checking group path availability..."
msgstr ""
@@ -7388,6 +7438,9 @@ msgstr ""
msgid "Clear recent searches"
msgstr ""
+msgid "Clear repository checks"
+msgstr ""
+
msgid "Clear search"
msgstr ""
@@ -7520,9 +7573,6 @@ msgstr ""
msgid "Closed MRs"
msgstr ""
-msgid "Closed epics"
-msgstr ""
-
msgid "Closed issues"
msgstr ""
@@ -7559,13 +7609,13 @@ msgstr ""
msgid "Cluster level"
msgstr ""
-msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
+msgid "Cluster type must be specified for Stages::ClusterEndpointInserter"
msgstr ""
msgid "ClusterAgents|%{name} successfully deleted"
msgstr ""
-msgid "ClusterAgents|%{number} of %{total} Agents"
+msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
@@ -7607,6 +7657,15 @@ msgstr ""
msgid "ClusterAgents|Agent never connected to GitLab"
msgstr ""
+msgid "ClusterAgents|Agent version mismatch"
+msgstr ""
+
+msgid "ClusterAgents|Agent version mismatch and update"
+msgstr ""
+
+msgid "ClusterAgents|Agent version update required"
+msgstr ""
+
msgid "ClusterAgents|All"
msgstr ""
@@ -7631,7 +7690,7 @@ msgstr ""
msgid "ClusterAgents|Configuration"
msgstr ""
-msgid "ClusterAgents|Connect a cluster through the Agent"
+msgid "ClusterAgents|Connect a cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connect existing cluster"
@@ -7640,13 +7699,13 @@ msgstr ""
msgid "ClusterAgents|Connect with a certificate"
msgstr ""
-msgid "ClusterAgents|Connect with agent"
+msgid "ClusterAgents|Connect with an agent"
msgstr ""
msgid "ClusterAgents|Connect with the GitLab Agent"
msgstr ""
-msgid "ClusterAgents|Connect your cluster through the Agent"
+msgid "ClusterAgents|Connect your cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connected"
@@ -7706,7 +7765,10 @@ msgstr ""
msgid "ClusterAgents|How to register an agent?"
msgstr ""
-msgid "ClusterAgents|Install new Agent"
+msgid "ClusterAgents|How to update an agent?"
+msgstr ""
+
+msgid "ClusterAgents|Install a new agent"
msgstr ""
msgid "ClusterAgents|Last connected %{timeAgo}."
@@ -7733,7 +7795,7 @@ msgstr ""
msgid "ClusterAgents|Never connected"
msgstr ""
-msgid "ClusterAgents|No Agents"
+msgid "ClusterAgents|No agents"
msgstr ""
msgid "ClusterAgents|No clusters connected through cluster certificates"
@@ -7793,6 +7855,9 @@ msgstr ""
msgid "ClusterAgents|The agent has not been connected in a long time. There might be a connectivity issue. Last contact was %{timeAgo}."
msgstr ""
+msgid "ClusterAgents|The agent version do not match each other across your cluster's pods. This can happen when a new agent version was just deployed and Kubernetes is shutting down the old pods."
+msgstr ""
+
msgid "ClusterAgents|The recommended installation method includes the token. If you want to follow the advanced installation method provided in the docs, make sure you save the token value before you close this window."
msgstr ""
@@ -7840,6 +7905,9 @@ msgstr ""
msgid "ClusterAgents|You will need to create a token to connect to your agent"
msgstr ""
+msgid "ClusterAgents|Your agent version is out of sync with your GitLab version (v%{version}), which might cause compatibility problems. Update the agent installed on your cluster to the most recent version."
+msgstr ""
+
msgid "ClusterAgents|Your instance doesn't have the %{linkStart}GitLab Agent Server (KAS)%{linkEnd} set up. Ask a GitLab Administrator to install it."
msgstr ""
@@ -8716,9 +8784,6 @@ msgstr ""
msgid "Comma-separated list of email addresses."
msgstr ""
-msgid "Comma-separated list of users allowed to exceed the rate limit."
-msgstr ""
-
msgid "Comma-separated, e.g. '1.1.1.1, 2.2.2.0/24'"
msgstr ""
@@ -9045,6 +9110,12 @@ msgstr ""
msgid "Confidential"
msgstr ""
+msgid "Confidential issue"
+msgstr ""
+
+msgid "Confidential note"
+msgstr ""
+
msgid "Confidentiality"
msgstr ""
@@ -9078,6 +9149,9 @@ msgstr ""
msgid "Configure Dependency Scanning in `.gitlab-ci.yml`, creating this file if it does not already exist"
msgstr ""
+msgid "Configure GitLab"
+msgstr ""
+
msgid "Configure GitLab runners to start using the Web Terminal. %{helpStart}Learn more.%{helpEnd}"
msgstr ""
@@ -9126,6 +9200,15 @@ msgstr ""
msgid "Configure pipelines to deploy web apps, backend services, APIs and static resources to Google Cloud"
msgstr ""
+msgid "Configure region"
+msgstr ""
+
+msgid "Configure region for environment"
+msgstr ""
+
+msgid "Configure regions"
+msgstr ""
+
msgid "Configure repository mirroring."
msgstr ""
@@ -9159,6 +9242,9 @@ msgstr ""
msgid "Configure which lists are shown for anyone who visits this board"
msgstr ""
+msgid "Configure your environments to be deployed to specific geographical regions"
+msgstr ""
+
msgid "Confirm"
msgstr ""
@@ -9861,10 +9947,10 @@ msgstr ""
msgid "CorpusManagement|Actions"
msgstr ""
-msgid "CorpusManagement|Corpus are used in fuzz testing as mutation source to Improve future testing."
+msgid "CorpusManagement|Corpus file"
msgstr ""
-msgid "CorpusManagement|Corpus file"
+msgid "CorpusManagement|Corpus files are used in coverage-guided fuzz testing as seed inputs to improve testing."
msgstr ""
msgid "CorpusManagement|Corpus files must be in *.zip format. Maximum 5 GB"
@@ -9918,6 +10004,9 @@ msgstr ""
msgid "Could not apply %{name} command."
msgstr ""
+msgid "Could not apply %{name} command. %{message}."
+msgstr ""
+
msgid "Could not authorize chat nickname. Try again!"
msgstr ""
@@ -10068,6 +10157,9 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
+msgid "Create a group"
+msgstr ""
+
msgid "Create a merge request"
msgstr ""
@@ -10092,6 +10184,9 @@ msgstr ""
msgid "Create a personal access token on your account to pull or push via %{protocol}."
msgstr ""
+msgid "Create a project"
+msgstr ""
+
msgid "Create an account using:"
msgstr ""
@@ -10455,6 +10550,9 @@ msgstr ""
msgid "Creation date"
msgstr ""
+msgid "Creator"
+msgstr ""
+
msgid "Credentials"
msgstr ""
@@ -10467,9 +10565,15 @@ msgstr ""
msgid "CredentialsInventory|Personal Access Tokens"
msgstr ""
+msgid "CredentialsInventory|Project Access Tokens"
+msgstr ""
+
msgid "CredentialsInventory|SSH Keys"
msgstr ""
+msgid "Credit card required to be on file in order to create a pipeline"
+msgstr ""
+
msgid "Credit card:"
msgstr ""
@@ -10653,9 +10757,6 @@ msgstr ""
msgid "Customer relations"
msgstr ""
-msgid "Customizable by an administrator."
-msgstr ""
-
msgid "Customizable by owners."
msgstr ""
@@ -10785,30 +10886,18 @@ msgstr ""
msgid "CycleAnalytics|%{selectedLabelsCount} selected (%{maxLabels} max)"
msgstr ""
-msgid "CycleAnalytics|%{stageCount} stages selected"
-msgstr ""
-
-msgid "CycleAnalytics|All stages"
-msgstr ""
-
-msgid "CycleAnalytics|Average days to completion"
+msgid "CycleAnalytics|Average time to completion"
msgstr ""
msgid "CycleAnalytics|Date"
msgstr ""
-msgid "CycleAnalytics|Days to completion"
-msgstr ""
-
msgid "CycleAnalytics|Display chart filters"
msgstr ""
msgid "CycleAnalytics|Lead Time for Changes"
msgstr ""
-msgid "CycleAnalytics|No stages selected"
-msgstr ""
-
msgid "CycleAnalytics|Number of tasks"
msgstr ""
@@ -10837,18 +10926,30 @@ msgstr ""
msgid "CycleAnalytics|Showing data for group '%{groupName}' from %{createdAfter} to %{createdBefore}"
msgstr ""
-msgid "CycleAnalytics|Stages"
+msgid "CycleAnalytics|Stage time: %{title}"
msgstr ""
msgid "CycleAnalytics|Tasks by type"
msgstr ""
-msgid "CycleAnalytics|The average time spent in the selected stage for the items that were completed on each date. Data limited to the last 500 items."
+msgid "CycleAnalytics|The average time items spent in this stage. Data limited to items completed within this date range."
msgstr ""
msgid "CycleAnalytics|The given date range is larger than 180 days"
msgstr ""
+msgid "CycleAnalytics|The total time items spent across each value stream stage. Data limited to items completed within this date range."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Stage time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Total time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|Total time"
+msgstr ""
+
msgid "CycleAnalytics|Type of work"
msgstr ""
@@ -10861,9 +10962,6 @@ msgstr ""
msgid "CycleAnalytics|project dropdown filter"
msgstr ""
-msgid "CycleAnalytics|stage dropdown"
-msgstr ""
-
msgid "DAG visualization requires at least 3 dependent jobs."
msgstr ""
@@ -10963,10 +11061,16 @@ msgstr ""
msgid "DastProfiles|AJAX spider"
msgstr ""
+msgid "DastProfiles|API"
+msgstr ""
+
+msgid "DastProfiles|API endpoint URL"
+msgstr ""
+
msgid "DastProfiles|Active"
msgstr ""
-msgid "DastProfiles|Additional request headers (Optional)"
+msgid "DastProfiles|Additional request headers (optional)"
msgstr ""
msgid "DastProfiles|Are you sure you want to delete this profile?"
@@ -10981,6 +11085,9 @@ msgstr ""
msgid "DastProfiles|Branch missing"
msgstr ""
+msgid "DastProfiles|Choose a scan method"
+msgstr ""
+
msgid "DastProfiles|Could not create the scanner profile. Please try again."
msgstr ""
@@ -11050,7 +11157,13 @@ msgstr ""
msgid "DastProfiles|Excluded URLs"
msgstr ""
-msgid "DastProfiles|Excluded URLs (Optional)"
+msgid "DastProfiles|Excluded URLs (optional)"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths (optional)"
msgstr ""
msgid "DastProfiles|Hide debug messages"
@@ -11107,9 +11220,6 @@ msgstr ""
msgid "DastProfiles|Request headers"
msgstr ""
-msgid "DastProfiles|Rest API"
-msgstr ""
-
msgid "DastProfiles|Run the AJAX spider, in addition to the traditional spider, to crawl the target site."
msgstr ""
@@ -11119,6 +11229,9 @@ msgstr ""
msgid "DastProfiles|Save profile"
msgstr ""
+msgid "DastProfiles|Scan method"
+msgstr ""
+
msgid "DastProfiles|Scan mode"
msgstr ""
@@ -11197,12 +11310,24 @@ msgstr ""
msgid "DastProfiles|Website"
msgstr ""
+msgid "DastProfiles|What does each method do?"
+msgstr ""
+
msgid "DastProfiles|You can either choose a passive scan or validate the target site from the site profile management page. %{docsLinkStart}Learn more about site validation.%{docsLinkEnd}"
msgstr ""
msgid "DastProfiles|You cannot run an active scan against an unvalidated site."
msgstr ""
+msgid "DastProfiles|folder/dast_example.har or https://example.com/dast_example.har"
+msgstr ""
+
+msgid "DastProfiles|folder/example.postman_collection.json or https://example.com/"
+msgstr ""
+
+msgid "DastProfiles|folder/openapi.json or https://example.com/openapi.json"
+msgstr ""
+
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
@@ -11310,6 +11435,9 @@ msgstr ""
msgid "DatadogIntegration|API URL"
msgstr ""
+msgid "DatadogIntegration|Custom tags in Datadog. Enter one tag per line in the %{codeOpen}key:value%{codeClose} format. %{linkOpen}How do I use tags?%{linkClose}"
+msgstr ""
+
msgid "DatadogIntegration|Environment"
msgstr ""
@@ -11328,12 +11456,18 @@ msgstr ""
msgid "DatadogIntegration|Tag all data from this GitLab instance in Datadog. Useful when managing several self-managed deployments."
msgstr ""
+msgid "DatadogIntegration|Tags"
+msgstr ""
+
msgid "DatadogIntegration|The Datadog site to send data to. To send data to the EU site, use %{codeOpen}datadoghq.eu%{codeClose}."
msgstr ""
msgid "DatadogIntegration|Trace your GitLab pipelines with Datadog."
msgstr ""
+msgid "DatadogIntegration|have an invalid format"
+msgstr ""
+
msgid "Datasource name not found"
msgstr ""
@@ -11343,9 +11477,6 @@ msgstr ""
msgid "Date merged"
msgstr ""
-msgid "Date picker"
-msgstr ""
-
msgid "Date range"
msgstr ""
@@ -11499,9 +11630,6 @@ msgstr ""
msgid "Definition"
msgstr ""
-msgid "Delayed Project Deletion (%{adjourned_deletion})"
-msgstr ""
-
msgid "DelayedJobs|Are you sure you want to run %{jobName} immediately? Otherwise this job will run automatically after its timer finishes."
msgstr ""
@@ -11580,10 +11708,10 @@ msgstr ""
msgid "Delete pipeline"
msgstr ""
-msgid "Delete project"
+msgid "Delete pipeline schedule"
msgstr ""
-msgid "Delete project. Are you ABSOLUTELY SURE?"
+msgid "Delete project"
msgstr ""
msgid "Delete row"
@@ -11613,6 +11741,9 @@ msgstr ""
msgid "Delete this epic and all descendants?"
msgstr ""
+msgid "Delete this project"
+msgstr ""
+
msgid "Delete user list"
msgstr ""
@@ -11871,6 +12002,12 @@ msgstr ""
msgid "Deploy to..."
msgstr ""
+msgid "DeployBoards|To see deployment progress for your environments, make sure you are deploying to %{codeStart}$KUBE_NAMESPACE%{codeEnd} and annotating with %{codeStart}app.gitlab.com/app=$CI_PROJECT_PATH_SLUG%{codeEnd} and %{codeStart}app.gitlab.com/env=$CI_ENVIRONMENT_SLUG%{codeEnd}."
+msgstr ""
+
+msgid "DeployBoard|Kubernetes Pods"
+msgstr ""
+
msgid "DeployFreeze|Add a freeze period to prevent unintended releases during a period of time for a given environment. You must update the deployment jobs in %{filename} according to the deploy freezes added here. %{freeze_period_link_start}Learn more.%{freeze_period_link_end}"
msgstr ""
@@ -11955,9 +12092,6 @@ msgstr ""
msgid "DeployTokens|Active Deploy Tokens (%{active_tokens})"
msgstr ""
-msgid "DeployTokens|Allows read and write access to registry images."
-msgstr ""
-
msgid "DeployTokens|Allows read and write access to the package registry."
msgstr ""
@@ -11970,6 +12104,9 @@ msgstr ""
msgid "DeployTokens|Allows read-only access to the repository."
msgstr ""
+msgid "DeployTokens|Allows write access to registry images."
+msgstr ""
+
msgid "DeployTokens|Copy deploy token"
msgstr ""
@@ -12063,12 +12200,57 @@ msgstr ""
msgid "Deploying to AWS is easy with GitLab"
msgstr ""
+msgid "Deployment"
+msgstr ""
+
msgid "Deployment Frequency"
msgstr ""
+msgid "Deployment Target|Project deployment target (optional)"
+msgstr ""
+
+msgid "Deployment Target|Select the deployment target"
+msgstr ""
+
msgid "Deployment frequency"
msgstr ""
+msgid "DeploymentTarget|GitLab Pages"
+msgstr ""
+
+msgid "DeploymentTarget|Heroku"
+msgstr ""
+
+msgid "DeploymentTarget|Infrastructure provider (Terraform, Cloudformation, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Kubernetes (GKE, EKS, OpenShift, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Managed container runtime (Fargate, Cloud Run, DigitalOcean App)"
+msgstr ""
+
+msgid "DeploymentTarget|Mobile app store"
+msgstr ""
+
+msgid "DeploymentTarget|No deployment planned"
+msgstr ""
+
+msgid "DeploymentTarget|Other hosting service"
+msgstr ""
+
+msgid "DeploymentTarget|Registry (package or container)"
+msgstr ""
+
+msgid "DeploymentTarget|Self-managed container runtime (Podman, Docker Swarm, Docker Compose)"
+msgstr ""
+
+msgid "DeploymentTarget|Serverless backend (Lambda, Cloud functions)"
+msgstr ""
+
+msgid "DeploymentTarget|Virtual machine (for example, EC2)"
+msgstr ""
+
msgid "Deployments"
msgstr ""
@@ -12107,6 +12289,9 @@ msgstr ""
msgid "Deployment|This deployment was created using the API"
msgstr ""
+msgid "Deployment|Triggerer"
+msgstr ""
+
msgid "Deployment|Waiting"
msgstr ""
@@ -12134,6 +12319,18 @@ msgstr ""
msgid "Deprecated API rate limits"
msgstr ""
+msgid "Deprecations|Feature deprecation and removal"
+msgstr ""
+
+msgid "Deprecations|For information on a possible replacement %{epicStart} learn more about Opstrace %{epicEnd}."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7 and are %{epicStart} scheduled for removal %{epicEnd} in GitLab 15.0."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7, and are %{removal_link_start} scheduled for removal %{link_end} in GitLab 15.0. For information on a possible replacement, %{opstrace_link_start} learn more about Opstrace %{link_end}."
+msgstr ""
+
msgid "Deprioritize label"
msgstr ""
@@ -12379,10 +12576,10 @@ msgstr ""
msgid "DevopsAdoption|At least one deploy"
msgstr ""
-msgid "DevopsAdoption|At least one issue opened"
+msgid "DevopsAdoption|At least one issue created"
msgstr ""
-msgid "DevopsAdoption|At least one merge request opened"
+msgid "DevopsAdoption|At least one merge request created"
msgstr ""
msgid "DevopsAdoption|At least one pipeline successfully run"
@@ -12583,6 +12780,9 @@ msgstr ""
msgid "Direct member"
msgstr ""
+msgid "Direct members"
+msgstr ""
+
msgid "Direct non-authenticated users to this page."
msgstr ""
@@ -12699,6 +12899,9 @@ msgid_plural "Dismiss %d selected vulnerabilities as"
msgstr[0] ""
msgstr[1] ""
+msgid "Dismiss Alert"
+msgstr ""
+
msgid "Dismiss merge request promotion"
msgstr ""
@@ -12726,9 +12929,15 @@ msgstr ""
msgid "Display alerts from all configured monitoring tools."
msgstr ""
+msgid "Display milestones"
+msgstr ""
+
msgid "Display name"
msgstr ""
+msgid "Display progress of child issues"
+msgstr ""
+
msgid "Display rendered file"
msgstr ""
@@ -12834,6 +13043,9 @@ msgstr ""
msgid "Download image"
msgstr ""
+msgid "Download payload"
+msgstr ""
+
msgid "Download raw data (.csv)"
msgstr ""
@@ -13011,6 +13223,9 @@ msgstr ""
msgid "Edit in Web IDE"
msgstr ""
+msgid "Edit in pipeline editor"
+msgstr ""
+
msgid "Edit in single-file editor"
msgstr ""
@@ -13053,6 +13268,9 @@ msgstr ""
msgid "Edit your most recent comment in a thread (from an empty textarea)"
msgstr ""
+msgid "Edit, lint, and visualize your pipeline."
+msgstr ""
+
msgid "Edited"
msgstr ""
@@ -13494,6 +13712,9 @@ msgstr ""
msgid "Enforce two-factor authentication for all user sign-ins."
msgstr ""
+msgid "Enhance security by storing service account keys in secret managers - learn more about %{docLinkStart}secret management with GitLab%{docLinkEnd}"
+msgstr ""
+
msgid "Ensure connectivity is available from the GitLab server to the Prometheus server"
msgstr ""
@@ -13554,6 +13775,9 @@ 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 following to confirm:"
+msgstr ""
+
msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
@@ -14084,9 +14308,6 @@ 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 ""
@@ -14222,6 +14443,9 @@ msgstr ""
msgid "Errors:"
msgstr ""
+msgid "Escalate this incident"
+msgstr ""
+
msgid "Escalation Policies"
msgstr ""
@@ -14234,6 +14458,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy"
+msgstr ""
+
msgid "Escalation policy:"
msgstr ""
@@ -14485,6 +14712,9 @@ msgstr ""
msgid "Existing sign in methods may be removed"
msgstr ""
+msgid "Exit."
+msgstr ""
+
msgid "Expand"
msgstr ""
@@ -14581,6 +14811,9 @@ msgstr ""
msgid "Explore public groups"
msgstr ""
+msgid "Explore public projects"
+msgstr ""
+
msgid "Explore snippets"
msgstr ""
@@ -14742,7 +14975,7 @@ msgid_plural "Failed to archive designs. Please try again."
msgstr[0] ""
msgstr[1] ""
-msgid "Failed to assign a reviewer because no user was found."
+msgid "Failed to assign a reviewer because no user was specified."
msgstr ""
msgid "Failed to assign a user because no user was found."
@@ -14808,10 +15041,10 @@ msgstr ""
msgid "Failed to find import label for Jira import."
msgstr ""
-msgid "Failed to generate export, please try again later."
+msgid "Failed to find users for %{missing}"
msgstr ""
-msgid "Failed to generate report, please try again after sometime"
+msgid "Failed to generate export, please try again later."
msgstr ""
msgid "Failed to get ref."
@@ -14910,6 +15143,9 @@ msgstr ""
msgid "Failed to remove a to-do item for the design."
msgstr ""
+msgid "Failed to remove attention because no user was found."
+msgstr ""
+
msgid "Failed to remove mirror."
msgstr ""
@@ -14922,6 +15158,9 @@ msgstr ""
msgid "Failed to remove user key."
msgstr ""
+msgid "Failed to request attention because no user was found."
+msgstr ""
+
msgid "Failed to reset key. Please try again."
msgstr ""
@@ -15003,6 +15242,9 @@ msgstr ""
msgid "Feature Flags"
msgstr ""
+msgid "Feature deprecation and removal"
+msgstr ""
+
msgid "Feature flag status"
msgstr ""
@@ -15500,7 +15742,7 @@ msgstr ""
msgid "For each job, re-use the project workspace. If the workspace doesn't exist, use %{code_open}git clone%{code_close}."
msgstr ""
-msgid "For example, the application using the token or the purpose of the token."
+msgid "For example, the application using the token or the purpose of the token. Do not give sensitive information for the name of the token, as it will be visible to all %{resource_type} members."
msgstr ""
msgid "For files larger than this limit, only index the file name. The file content is neither indexed nor searchable."
@@ -15584,9 +15826,6 @@ msgstr ""
msgid "ForkProject|Select a namespace"
msgstr ""
-msgid "ForkProject|Select a namespace to fork the project"
-msgstr ""
-
msgid "ForkProject|The project can be accessed by any logged in user."
msgstr ""
@@ -15683,6 +15922,9 @@ msgstr ""
msgid "Full name"
msgstr ""
+msgid "GCP region configured"
+msgstr ""
+
msgid "GPG Key ID:"
msgstr ""
@@ -15863,6 +16105,9 @@ msgstr ""
msgid "Geo|Failed"
msgstr ""
+msgid "Geo|Filter Geo sites"
+msgstr ""
+
msgid "Geo|Filter by name"
msgstr ""
@@ -16274,6 +16519,12 @@ msgstr ""
msgid "GitLab Issue"
msgstr ""
+msgid "GitLab KAS"
+msgstr ""
+
+msgid "GitLab Memberships CSV Export"
+msgstr ""
+
msgid "GitLab Pages"
msgstr ""
@@ -16322,6 +16573,9 @@ 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 free to use. Many features for larger teams are part of our %{link_start}paid products%{link_end}. You can try Ultimate for free without any obligation or payment details."
+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 ""
@@ -16448,7 +16702,7 @@ msgstr ""
msgid "GitLabPages|When enabled, all attempts to visit your website through HTTP are automatically redirected to HTTPS using a response with status code 301. Requires a valid certificate for all domains. %{docs_link_start}Learn more.%{link_end}"
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. %{docs_link_start}Learn more.%{link_end}"
+msgid "GitLabPages|When using Pages under the general domain of a GitLab instance (%{pages_host}), you cannot use HTTPS with subdomains of subdomains. If your namespace or groupname contains a dot, it does not work. This is a limitation of the HTTP Over TLS protocol. HTTP pages work if you don't redirect HTTP to HTTPS. %{docs_link_start}Learn more.%{link_end}"
msgstr ""
msgid "GitLabPages|With GitLab Pages you can host your static website directly from your GitLab repository. %{docs_link_start}Learn more.%{link_end}"
@@ -16625,9 +16879,6 @@ msgstr ""
msgid "Go to find file"
msgstr ""
-msgid "Go to fork"
-msgstr ""
-
msgid "Go to issue boards"
msgstr ""
@@ -16835,9 +17086,6 @@ msgstr ""
msgid "Group Hooks"
msgstr ""
-msgid "Group ID"
-msgstr ""
-
msgid "Group Owner must have signed in with SAML before enabling Group Managed Accounts"
msgstr ""
@@ -16865,9 +17113,6 @@ msgstr ""
msgid "Group by"
msgstr ""
-msgid "Group description"
-msgstr ""
-
msgid "Group description (optional)"
msgstr ""
@@ -16982,7 +17227,7 @@ msgstr ""
msgid "Group: %{name}"
msgstr ""
-msgid "GroupActivityMetrics|Issues opened"
+msgid "GroupActivityMetrics|Issues created"
msgstr ""
msgid "GroupActivityMetrics|Last 90 days"
@@ -16991,7 +17236,7 @@ msgstr ""
msgid "GroupActivityMetrics|Members added"
msgstr ""
-msgid "GroupActivityMetrics|Merge Requests opened"
+msgid "GroupActivityMetrics|Merge Requests created"
msgstr ""
msgid "GroupActivityMetrics|Recent activity"
@@ -17282,6 +17527,9 @@ msgstr ""
msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
+msgid "GroupSettings|Choose a group path that does not start with a dash or end with a period. It can also contain alphanumeric characters and underscores."
+msgstr ""
+
msgid "GroupSettings|Compliance frameworks"
msgstr ""
@@ -17315,7 +17563,7 @@ msgstr ""
msgid "GroupSettings|If not specified at the group or instance level, the default is %{default_initial_branch_name}. Does not affect existing repositories."
msgstr ""
-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."
+msgid "GroupSettings|If the parent group's visibility is lower than the group's current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility."
msgstr ""
msgid "GroupSettings|New runners registration token has been generated!"
@@ -17432,7 +17680,10 @@ msgstr ""
msgid "Groups and projects"
msgstr ""
-msgid "Groups and subgroups"
+msgid "Groups are a great way to organize projects and people."
+msgstr ""
+
+msgid "Groups are the best way to manage projects and members."
msgstr ""
msgid "Groups to synchronize"
@@ -17543,13 +17794,16 @@ msgstr ""
msgid "GroupsTree|Are you sure you want to leave the \"%{fullName}\" group?"
msgstr ""
-msgid "GroupsTree|Edit group"
+msgid "GroupsTree|Delete"
+msgstr ""
+
+msgid "GroupsTree|Edit"
msgstr ""
msgid "GroupsTree|Failed to leave the group. Please make sure you are not the only owner."
msgstr ""
-msgid "GroupsTree|Leave this group"
+msgid "GroupsTree|Leave group"
msgstr ""
msgid "GroupsTree|Loading groups"
@@ -17561,9 +17815,57 @@ msgstr ""
msgid "GroupsTree|No groups or projects matched your search"
msgstr ""
+msgid "GroupsTree|Options"
+msgstr ""
+
msgid "GroupsTree|Search by name"
msgstr ""
+msgid "Groups|Avatar will be removed. Are you sure?"
+msgstr ""
+
+msgid "Groups|Changing group URL can have unintended side effects."
+msgstr ""
+
+msgid "Groups|Checking group URL availability..."
+msgstr ""
+
+msgid "Groups|Enter a descriptive name for your group."
+msgstr ""
+
+msgid "Groups|Group ID"
+msgstr ""
+
+msgid "Groups|Group URL"
+msgstr ""
+
+msgid "Groups|Group avatar"
+msgstr ""
+
+msgid "Groups|Group description (optional)"
+msgstr ""
+
+msgid "Groups|Group name"
+msgstr ""
+
+msgid "Groups|Group path is available."
+msgstr ""
+
+msgid "Groups|Group path is unavailable. Path has been replaced with a suggested available path."
+msgstr ""
+
+msgid "Groups|Learn more"
+msgstr ""
+
+msgid "Groups|Must start with letter, digit, emoji, or underscore. Can also contain periods, dashes, spaces, and parentheses."
+msgstr ""
+
+msgid "Groups|Remove avatar"
+msgstr ""
+
+msgid "Groups|Save changes"
+msgstr ""
+
msgid "Guideline"
msgstr ""
@@ -17573,6 +17875,9 @@ msgstr ""
msgid "HAR file path or URL"
msgstr ""
+msgid "HTTP Archive (HAR)"
+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 ""
@@ -17973,6 +18278,9 @@ msgstr ""
msgid "INFO: Your SSH key is expiring soon. Please generate a new key."
msgstr ""
+msgid "IP"
+msgstr ""
+
msgid "IP Address"
msgstr ""
@@ -18009,6 +18317,9 @@ msgstr ""
msgid "IdentityVerification|Verify your identity"
msgstr ""
+msgid "IdentityVerification|You can always verify your account at a later time to create a group."
+msgstr ""
+
msgid "If any indexed field exceeds this limit, it is truncated to this number of characters. The rest of the content is neither indexed nor searchable. This does not apply to repository and wiki indexing. For unlimited characters, set this to 0."
msgstr ""
@@ -18066,6 +18377,9 @@ msgstr ""
msgid "If you add %{codeStart}needs%{codeEnd} to jobs in your pipeline you'll be able to view the %{codeStart}needs%{codeEnd} relationships between jobs in this tab as a %{linkStart}Directed Acyclic Graph (DAG)%{linkEnd}."
msgstr ""
+msgid "If you are added to a project, it will be displayed here."
+msgstr ""
+
msgid "If you did not initiate these sign-in attempts, please reach out to your administrator or enable two-factor authentication (2FA) on your account."
msgstr ""
@@ -18372,12 +18686,24 @@ msgstr ""
msgid "InProductMarketing|3 ways to dive into GitLab CI/CD"
msgstr ""
+msgid "InProductMarketing|A single application eliminates complex integrations, data chokepoints, and toolchain maintenance, resulting in greater productivity and lower cost."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features, build more efficiently, strengthen security and compliance."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features."
+msgstr ""
+
msgid "InProductMarketing|Actually, GitLab makes the team work (better)"
msgstr ""
msgid "InProductMarketing|And finally %{deploy_link} a Python application."
msgstr ""
+msgid "InProductMarketing|And many more..."
+msgstr ""
+
msgid "InProductMarketing|Are your runners ready?"
msgstr ""
@@ -18396,15 +18722,33 @@ msgstr ""
msgid "InProductMarketing|Blog"
msgstr ""
+msgid "InProductMarketing|Break down silos to coordinate seamlessly across development, operations, and security with a consistent experience across the development lifecycle."
+msgstr ""
+
+msgid "InProductMarketing|Burn up/down charts"
+msgstr ""
+
msgid "InProductMarketing|By enabling code owners and required merge approvals the right person will review the right MR. This is a win-win: cleaner code and a more efficient review process."
msgstr ""
msgid "InProductMarketing|Click on the number below that corresponds with your answer — 1 being very difficult, 5 being very easy."
msgstr ""
+msgid "InProductMarketing|Code owners"
+msgstr ""
+
msgid "InProductMarketing|Code owners and required merge approvals are part of the paid tiers of GitLab. You can start a free 30-day trial of GitLab Ultimate and enable these features in less than 5 minutes with no credit card required."
msgstr ""
+msgid "InProductMarketing|Code review analytics"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration across stages in GitLab"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration made easy"
+msgstr ""
+
msgid "InProductMarketing|Create a custom CI runner with just a few clicks"
msgstr ""
@@ -18414,12 +18758,21 @@ msgstr ""
msgid "InProductMarketing|Create a project in GitLab in 5 minutes"
msgstr ""
+msgid "InProductMarketing|Create well-defined workflows by using scoped labels on issues, merge requests, and epics. Labels with the same scope cannot be used together, which prevents conflicts."
+msgstr ""
+
msgid "InProductMarketing|Create your first project!"
msgstr ""
+msgid "InProductMarketing|Define who owns specific files or directories, so the right reviewers are suggested when a merge request introduces changes to those files."
+msgstr ""
+
msgid "InProductMarketing|Deliver Better Products Faster"
msgstr ""
+msgid "InProductMarketing|Dependency scanning"
+msgstr ""
+
msgid "InProductMarketing|Did you know teams that use GitLab are far more efficient?"
msgstr ""
@@ -18429,15 +18782,27 @@ msgstr ""
msgid "InProductMarketing|Dig in and create a project and a repo"
msgstr ""
+msgid "InProductMarketing|Discover Premium & Ultimate"
+msgstr ""
+
+msgid "InProductMarketing|Discover Premium & Ultimate."
+msgstr ""
+
msgid "InProductMarketing|Do you have a minute?"
msgstr ""
msgid "InProductMarketing|Do you have a teammate who would be perfect for this task?"
msgstr ""
+msgid "InProductMarketing|Dynamic application security testing"
+msgstr ""
+
msgid "InProductMarketing|Easy"
msgstr ""
+msgid "InProductMarketing|Epics"
+msgstr ""
+
msgid "InProductMarketing|Expand your DevOps journey with a free GitLab trial"
msgstr ""
@@ -18459,9 +18824,15 @@ msgstr ""
msgid "InProductMarketing|Feel the need for speed?"
msgstr ""
+msgid "InProductMarketing|Find and fix bottlenecks in your code review process by understanding how long open merge requests have been in review."
+msgstr ""
+
msgid "InProductMarketing|Find out how your teams are really doing"
msgstr ""
+msgid "InProductMarketing|Find out if your external libraries are safe. Run dependency scanning jobs that check for known vulnerabilities in your external libraries."
+msgstr ""
+
msgid "InProductMarketing|Follow our steps"
msgstr ""
@@ -18498,6 +18869,9 @@ msgstr ""
msgid "InProductMarketing|GitLab is better with teammates to help out!"
msgstr ""
+msgid "InProductMarketing|GitLab is infrastructure agnostic (supporting GCP, AWS, Azure, OpenShift, VMWare, On Prem, Bare Metal, and more), offering a consistent workflow experience – irrespective of the environment."
+msgstr ""
+
msgid "InProductMarketing|GitLab provides static application security testing (SAST), dynamic application security testing (DAST), container scanning, and dependency scanning to help you deliver secure applications along with license compliance."
msgstr ""
@@ -18588,21 +18962,36 @@ msgstr ""
msgid "InProductMarketing|It's also possible to simply %{external_repo_link} in order to take advantage of GitLab's CI/CD."
msgstr ""
+msgid "InProductMarketing|Keep your code quality high by defining who should approve merge requests and how many approvals are required."
+msgstr ""
+
msgid "InProductMarketing|Launch GitLab CI/CD in 20 minutes or less"
msgstr ""
+msgid "InProductMarketing|Lower cost of development"
+msgstr ""
+
+msgid "InProductMarketing|Make it easier to collaborate on high-level ideas by grouping related issues in an epic."
+msgstr ""
+
msgid "InProductMarketing|Making the switch? It's easier than you think to import your projects into GitLab. Move %{github_link}, or import something %{bitbucket_link}."
msgstr ""
msgid "InProductMarketing|Master the art of importing!"
msgstr ""
+msgid "InProductMarketing|Merge request approval rule"
+msgstr ""
+
msgid "InProductMarketing|Move on to easily creating a Pages website %{ci_template_link}"
msgstr ""
msgid "InProductMarketing|Multiple owners, confusing workstreams? We've got you covered"
msgstr ""
+msgid "InProductMarketing|Multiple required approvers"
+msgstr ""
+
msgid "InProductMarketing|Need an alternative to importing?"
msgstr ""
@@ -18615,18 +19004,33 @@ msgstr ""
msgid "InProductMarketing|Our tool brings all the things together"
msgstr ""
+msgid "InProductMarketing|Protect your web application by using DAST to examine for vulnerabilities in deployed environments."
+msgstr ""
+
msgid "InProductMarketing|Rapid development, simplified"
msgstr ""
msgid "InProductMarketing|Reduce Security & Compliance Risk"
msgstr ""
+msgid "InProductMarketing|Require multiple approvers on a merge request, so you know it's in good shape before it's merged."
+msgstr ""
+
+msgid "InProductMarketing|Roadmaps"
+msgstr ""
+
+msgid "InProductMarketing|Scoped labels"
+msgstr ""
+
msgid "InProductMarketing|Security that's integrated into your development lifecycle"
msgstr ""
msgid "InProductMarketing|Sometimes you're not ready to make a full transition to a new tool. If you're not ready to fully commit, %{mirroring_link} gives you a safe way to try out GitLab in parallel with your current tool."
msgstr ""
+msgid "InProductMarketing|Speed. Efficiency. Trust."
+msgstr ""
+
msgid "InProductMarketing|Spin up an autoscaling runner in GitLab"
msgstr ""
@@ -18636,6 +19040,9 @@ msgstr ""
msgid "InProductMarketing|Start a Self-Managed trial"
msgstr ""
+msgid "InProductMarketing|Start a free trial"
+msgstr ""
+
msgid "InProductMarketing|Start a free trial of GitLab Ultimate – no credit card required"
msgstr ""
@@ -18702,6 +19109,9 @@ msgstr ""
msgid "InProductMarketing|To understand and get the most out of GitLab, start at the beginning and %{project_link}. In GitLab, repositories are part of a project, so after you've created your project you can go ahead and %{repo_link}."
msgstr ""
+msgid "InProductMarketing|Track completed issues in a chart, so you can see how a milestone is progressing at a glance."
+msgstr ""
+
msgid "InProductMarketing|Try GitLab Ultimate for free"
msgstr ""
@@ -18738,6 +19148,9 @@ msgstr ""
msgid "InProductMarketing|Very easy"
msgstr ""
+msgid "InProductMarketing|Visualize your epics and milestones in a timeline."
+msgstr ""
+
msgid "InProductMarketing|Want to host GitLab on your servers?"
msgstr ""
@@ -18759,6 +19172,9 @@ msgstr ""
msgid "InProductMarketing|YouTube"
msgstr ""
+msgid "InProductMarketing|Your software, deployed your way"
+msgstr ""
+
msgid "InProductMarketing|Your teams can be more efficient"
msgstr ""
@@ -18879,9 +19295,18 @@ msgstr ""
msgid "IncidentManagement|No incidents to display."
msgstr ""
+msgid "IncidentManagement|None"
+msgstr ""
+
msgid "IncidentManagement|Open"
msgstr ""
+msgid "IncidentManagement|Page your team with escalation policies"
+msgstr ""
+
+msgid "IncidentManagement|Paged"
+msgstr ""
+
msgid "IncidentManagement|Published"
msgstr ""
@@ -18891,6 +19316,9 @@ msgstr ""
msgid "IncidentManagement|Severity"
msgstr ""
+msgid "IncidentManagement|Status"
+msgstr ""
+
msgid "IncidentManagement|There are no closed incidents"
msgstr ""
@@ -18909,6 +19337,9 @@ msgstr ""
msgid "IncidentManagement|Unpublished"
msgstr ""
+msgid "IncidentManagement|Use escalation policies to automatically page your team when incidents are created."
+msgstr ""
+
msgid "IncidentSettings|Activate \"time to SLA\" countdown timer"
msgstr ""
@@ -18954,7 +19385,10 @@ msgstr ""
msgid "Incidents"
msgstr ""
-msgid "Incidents|Add a URL"
+msgid "Incidents|Add image details"
+msgstr ""
+
+msgid "Incidents|Add text or a link to display with your image. If you don't add either, the file name displays instead."
msgstr ""
msgid "Incidents|Drop or %{linkStart}upload%{linkEnd} a metric screenshot to attach it to the incident"
@@ -18969,10 +19403,10 @@ msgstr ""
msgid "Incidents|There was an issue loading metric images."
msgstr ""
-msgid "Incidents|There was an issue uploading your image."
+msgid "Incidents|There was an issue updating your image."
msgstr ""
-msgid "Incidents|You can optionally add a URL to link users to the original graph."
+msgid "Incidents|There was an issue uploading your image."
msgstr ""
msgid "Incident|Alert details"
@@ -18981,9 +19415,18 @@ msgstr ""
msgid "Incident|Are you sure you wish to delete this image?"
msgstr ""
+msgid "Incident|Delete image"
+msgstr ""
+
msgid "Incident|Deleting %{filename}"
msgstr ""
+msgid "Incident|Edit image text or link"
+msgstr ""
+
+msgid "Incident|Editing %{filename}"
+msgstr ""
+
msgid "Incident|Metrics"
msgstr ""
@@ -19253,12 +19696,18 @@ msgstr ""
msgid "Integrations|Branches for which notifications are to be sent"
msgstr ""
+msgid "Integrations|Clear if using a self-signed certificate."
+msgstr ""
+
msgid "Integrations|Comment detail:"
msgstr ""
msgid "Integrations|Comment settings:"
msgstr ""
+msgid "Integrations|Connection details"
+msgstr ""
+
msgid "Integrations|Connection failed. Please check your settings."
msgstr ""
@@ -19283,6 +19732,9 @@ msgstr ""
msgid "Integrations|Enable GitLab.com slash commands in a Slack workspace."
msgstr ""
+msgid "Integrations|Enable SSL verification"
+msgstr ""
+
msgid "Integrations|Enable comments"
msgstr ""
@@ -19361,6 +19813,9 @@ msgstr ""
msgid "Integrations|Return to GitLab for Jira"
msgstr ""
+msgid "Integrations|SSL verification"
+msgstr ""
+
msgid "Integrations|Save settings?"
msgstr ""
@@ -19406,9 +19861,6 @@ msgstr ""
msgid "Integrations|Use default settings"
msgstr ""
-msgid "Integrations|When you mention a Jira issue in a commit or merge request, GitLab creates a remote link and comment (if enabled)."
-msgstr ""
-
msgid "Integrations|You can now close this window and return to the GitLab for Jira application."
msgstr ""
@@ -19433,9 +19885,6 @@ msgstr ""
msgid "Integrations|can't exceed %{recipients_limit}"
msgstr ""
-msgid "Interactive developer security education."
-msgstr ""
-
msgid "Interactive mode"
msgstr ""
@@ -19925,6 +20374,9 @@ msgstr ""
msgid "IssueAnalytics|Assignees"
msgstr ""
+msgid "IssueAnalytics|Created by"
+msgstr ""
+
msgid "IssueAnalytics|Due date"
msgstr ""
@@ -19937,9 +20389,6 @@ msgstr ""
msgid "IssueAnalytics|Milestone"
msgstr ""
-msgid "IssueAnalytics|Opened by"
-msgstr ""
-
msgid "IssueAnalytics|Status"
msgstr ""
@@ -20063,10 +20512,10 @@ msgstr ""
msgid "IssuesAnalytics|Avg/Month:"
msgstr ""
-msgid "IssuesAnalytics|Issues opened"
+msgid "IssuesAnalytics|Issues created"
msgstr ""
-msgid "IssuesAnalytics|Issues opened per month"
+msgid "IssuesAnalytics|Issues created per month"
msgstr ""
msgid "IssuesAnalytics|Last 12 months"
@@ -20093,6 +20542,9 @@ msgstr ""
msgid "It looks like you have some draft commits in this branch."
msgstr ""
+msgid "It looks like you're attempting to activate your subscription. Use %{a_start}the Subscription page%{a_end} instead."
+msgstr ""
+
msgid "It may be several days before you see feature usage data."
msgstr ""
@@ -20321,6 +20773,9 @@ msgstr ""
msgid "JiraConnect|You can now close this window and return to Jira."
msgstr ""
+msgid "JiraConnect|You don't have permission to create branches for this project. Select a different project or contact the project owner for access. %{linkStart}Learn more.%{linkEnd}"
+msgstr ""
+
msgid "JiraRequest|A connection error occurred while connecting to Jira. Try your request again."
msgstr ""
@@ -20369,13 +20824,13 @@ msgstr ""
msgid "JiraService|Define the type of Jira issue to create from a vulnerability."
msgstr ""
-msgid "JiraService|Displaying Jira issues while leaving the GitLab issue functionality enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
+msgid "JiraService|Displaying Jira issues while leaving GitLab issues also enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
msgstr ""
-msgid "JiraService|Enable Jira issues"
+msgid "JiraService|Enable Jira issue creation from vulnerabilities"
msgstr ""
-msgid "JiraService|Enable Jira issues creation from vulnerabilities"
+msgid "JiraService|Enable Jira issues"
msgstr ""
msgid "JiraService|Enable Jira transitions"
@@ -20492,16 +20947,19 @@ msgstr ""
msgid "JiraService|View Jira issues in GitLab"
msgstr ""
-msgid "JiraService|Warning: All GitLab users that have access to this GitLab project are able to view all issues from the Jira project specified below."
+msgid "JiraService|Warning: All GitLab users with access to this GitLab project can view all issues from the Jira project you select."
msgstr ""
msgid "JiraService|Web URL"
msgstr ""
-msgid "JiraService|Work on Jira issues without leaving GitLab. Adds a Jira menu to access your list of Jira issues and view any issue as read-only."
+msgid "JiraService|When a Jira issue is mentioned in a commit or merge request, a remote link and comment (if enabled) will be created."
+msgstr ""
+
+msgid "JiraService|Work on Jira issues without leaving GitLab. Add a Jira menu to access a read-only list of your Jira issues."
msgstr ""
-msgid "JiraService|You need to configure Jira before enabling this integration. For more details, read the %{jira_doc_link_start}Jira integration documentation%{link_end}."
+msgid "JiraService|You must configure Jira before enabling this integration. %{jira_doc_link_start}Learn more.%{link_end}"
msgstr ""
msgid "Job"
@@ -20513,9 +20971,6 @@ msgstr ""
msgid "Job Failed #%{build_id}"
msgstr ""
-msgid "Job ID"
-msgstr ""
-
msgid "Job artifact"
msgstr ""
@@ -20582,9 +21037,27 @@ msgstr ""
msgid "Jobs|You're about to retry a job that failed because it attempted to deploy code that is older than the latest deployment. Retrying this job could result in overwriting the environment with the older source code."
msgstr ""
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source} into %{target}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{ref}"
+msgstr ""
+
+msgid "Job|Are you sure you want to erase this job log and artifacts?"
+msgstr ""
+
msgid "Job|Browse"
msgstr ""
+msgid "Job|Cancel"
+msgstr ""
+
msgid "Job|Complete Raw"
msgstr ""
@@ -20594,6 +21067,9 @@ msgstr ""
msgid "Job|Erase job log and artifacts"
msgstr ""
+msgid "Job|Finished at"
+msgstr ""
+
msgid "Job|Job artifacts"
msgstr ""
@@ -20606,7 +21082,7 @@ msgstr ""
msgid "Job|Keep"
msgstr ""
-msgid "Job|Pipeline"
+msgid "Job|Retry"
msgstr ""
msgid "Job|Scroll to bottom"
@@ -20618,6 +21094,9 @@ msgstr ""
msgid "Job|Show complete raw"
msgstr ""
+msgid "Job|Status"
+msgstr ""
+
msgid "Job|The artifacts were removed"
msgstr ""
@@ -20645,21 +21124,12 @@ msgstr ""
msgid "Job|delayed"
msgstr ""
-msgid "Job|for"
-msgstr ""
-
-msgid "Job|into"
-msgstr ""
-
msgid "Job|manual"
msgstr ""
msgid "Job|triggered"
msgstr ""
-msgid "Job|with"
-msgstr ""
-
msgid "Join Zoom meeting"
msgstr ""
@@ -20762,9 +21232,6 @@ msgstr ""
msgid "Ki"
msgstr ""
-msgid "Kontra"
-msgstr ""
-
msgid "Kroki"
msgstr ""
@@ -21088,6 +21555,9 @@ msgstr ""
msgid "Learn more about Auto DevOps"
msgstr ""
+msgid "Learn more about GitLab"
+msgstr ""
+
msgid "Learn more about Needs relationships"
msgstr ""
@@ -21415,9 +21885,18 @@ msgstr ""
msgid "Licenses|Displays licenses detected in the project, based on the %{linkStart}latest successful%{linkEnd} scan"
msgstr ""
+msgid "Licenses|Drag your license file here or %{linkStart}click to upload%{linkEnd}."
+msgstr ""
+
+msgid "Licenses|Drop your license file to start the upload."
+msgstr ""
+
msgid "Licenses|Error fetching the license list. Please check your network connection and try again."
msgstr ""
+msgid "Licenses|Error: You are trying to upload something other than a file"
+msgstr ""
+
msgid "Licenses|License Compliance"
msgstr ""
@@ -21436,6 +21915,9 @@ msgstr ""
msgid "Licenses|Specified policies in this project"
msgstr ""
+msgid "Licenses|The file could not be uploaded."
+msgstr ""
+
msgid "Licenses|The license list details information about the licenses used within your project."
msgstr ""
@@ -21469,11 +21951,6 @@ msgstr ""
msgid "Limit the size of Sidekiq jobs stored in Redis."
msgstr ""
-msgid "Limited to showing %d event at most"
-msgid_plural "Limited to showing %d events at most"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Limiting mode"
msgstr ""
@@ -21483,6 +21960,9 @@ msgstr ""
msgid "Link"
msgstr ""
+msgid "Link (optional)"
+msgstr ""
+
msgid "Link Prometheus monitoring to GitLab."
msgstr ""
@@ -21519,6 +21999,9 @@ msgstr ""
msgid "Linked emails (%{email_count})"
msgstr ""
+msgid "Linked epics"
+msgstr ""
+
msgid "Linked issues"
msgstr ""
@@ -21546,6 +22029,15 @@ msgstr ""
msgid "List of all merge commits"
msgstr ""
+msgid "List of environments for this project"
+msgstr ""
+
+msgid "List of suitable GCP locations"
+msgstr ""
+
+msgid "List of users allowed to exceed the rate limit."
+msgstr ""
+
msgid "List options"
msgstr ""
@@ -21765,6 +22257,9 @@ msgstr ""
msgid "Maintenance mode"
msgstr ""
+msgid "Make adjustments to how your GitLab instance is set up."
+msgstr ""
+
msgid "Make and review changes in the browser with the Web IDE"
msgstr ""
@@ -21909,6 +22404,12 @@ msgstr ""
msgid "MarkdownEditor|Add italic text (%{modifier_key}I)"
msgstr ""
+msgid "MarkdownEditor|Add strikethrough text (%{modifierKey}⇧X)"
+msgstr ""
+
+msgid "MarkdownEditor|Add strikethrough text (%{modifier_key}⇧X)"
+msgstr ""
+
msgid "Marked For Deletion At - %{deletion_time}"
msgstr ""
@@ -22170,6 +22671,9 @@ msgstr ""
msgid "Maximum push size (MB)"
msgstr ""
+msgid "Maximum requests per 10 minutes per user"
+msgstr ""
+
msgid "Maximum requests per minute"
msgstr ""
@@ -22260,6 +22764,19 @@ msgstr ""
msgid "Members of a group may only view projects they have permission to access"
msgstr ""
+msgid "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seat in use and will be billed for the overage."
+msgid_plural "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seats in use and will be billed for the overage."
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "MembersOverage|You are about to incur additional charges"
+msgstr ""
+
+msgid "MembersOverage|Your subscription includes %d seat."
+msgid_plural "MembersOverage|Your subscription includes %d seats."
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Membership"
msgstr ""
@@ -22464,9 +22981,6 @@ msgstr ""
msgid "Merge request not merged"
msgstr ""
-msgid "Merge request pipelines 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 merge request pipelines."
-msgstr ""
-
msgid "Merge request reports"
msgstr ""
@@ -22563,13 +23077,13 @@ msgstr ""
msgid "MergeRequests|Create issue to resolve thread"
msgstr ""
-msgid "MergeRequests|Failed to squash. Should be done manually."
+msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Saving the comment failed"
+msgid "MergeRequests|Squashing failed: Squash the commits locally, resolve any conflicts, then push the branch."
msgstr ""
-msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
+msgid "MergeRequests|Squashing not allowed: This project doesn't allow you to squash commits when merging."
msgstr ""
msgid "MergeRequests|Thread stays resolved"
@@ -23410,6 +23924,18 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "MrList|Assigned to %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from assignee %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from reviewer %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Review requested from %{name}, go to their profile."
+msgstr ""
+
msgid "Multi-project"
msgstr ""
@@ -23443,7 +23969,7 @@ msgstr ""
msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "My Awesome Group"
+msgid "My awesome group"
msgstr ""
msgid "My company or team"
@@ -24065,9 +24591,6 @@ msgstr ""
msgid "No available branches"
msgstr ""
-msgid "No available groups to fork the project."
-msgstr ""
-
msgid "No branches found"
msgstr ""
@@ -24278,6 +24801,9 @@ msgstr ""
msgid "No ref selected"
msgstr ""
+msgid "No regions configured"
+msgstr ""
+
msgid "No related merge requests found."
msgstr ""
@@ -25082,6 +25608,9 @@ msgstr ""
msgid "Only reCAPTCHA v2 is supported:"
msgstr ""
+msgid "Only required if not using role instance credentials."
+msgstr ""
+
msgid "Only use lowercase letters, numbers, and underscores."
msgstr ""
@@ -25106,9 +25635,6 @@ msgstr ""
msgid "Open a CLI and connect to the cluster you want to install the agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
-msgid "Open epics"
-msgstr ""
-
msgid "Open errors"
msgstr ""
@@ -25148,7 +25674,7 @@ msgstr ""
msgid "Opened issues"
msgstr ""
-msgid "OpenedNDaysAgo|Opened"
+msgid "OpenedNDaysAgo|Created"
msgstr ""
msgid "Opens in a new window"
@@ -25193,9 +25719,6 @@ msgstr ""
msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
-msgid "Optional."
-msgstr ""
-
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
msgstr ""
@@ -25984,6 +26507,9 @@ msgstr ""
msgid "PerformanceBar|Memory"
msgstr ""
+msgid "PerformanceBar|Memory report"
+msgstr ""
+
msgid "PerformanceBar|Redis calls"
msgstr ""
@@ -26017,18 +26543,12 @@ msgstr ""
msgid "PerformanceBar|wall"
msgstr ""
-msgid "Performs a rebase but skips triggering a new pipeline"
-msgstr ""
-
msgid "Period in seconds"
msgstr ""
msgid "Permalink"
msgstr ""
-msgid "Permanently delete project"
-msgstr ""
-
msgid "Permanently remove group"
msgstr ""
@@ -26299,6 +26819,51 @@ msgstr ""
msgid "PipelineStatusTooltip|Pipeline: %{ci_status}"
msgstr ""
+msgid "PipelineWizardDefaultCommitMessage|Add %{filename}"
+msgstr ""
+
+msgid "PipelineWizardDefaultCommitMessage|Update %{filename}"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|At least one entry is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This field is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This value is not valid"
+msgstr ""
+
+msgid "PipelineWizardListWidget|add another step"
+msgstr ""
+
+msgid "PipelineWizardListWidget|remove step"
+msgstr ""
+
+msgid "PipelineWizard|Commit"
+msgstr ""
+
+msgid "PipelineWizard|Commit Message"
+msgstr ""
+
+msgid "PipelineWizard|Commit changes to your file"
+msgstr ""
+
+msgid "PipelineWizard|Commit file to Branch"
+msgstr ""
+
+msgid "PipelineWizard|Commit your new file"
+msgstr ""
+
+msgid "PipelineWizard|The file has been committed."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem committing the changes."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem while checking whether your file already exists in the specified branch."
+msgstr ""
+
msgid "Pipelines"
msgstr ""
@@ -26413,7 +26978,7 @@ msgstr ""
msgid "Pipelines|Project cache successfully reset."
msgstr ""
-msgid "Pipelines|Revoke"
+msgid "Pipelines|Revoke trigger"
msgstr ""
msgid "Pipelines|Something went wrong while cleaning runners cache."
@@ -26458,6 +27023,12 @@ msgstr ""
msgid "Pipelines|This is a child pipeline within the parent pipeline"
msgstr ""
+msgid "Pipelines|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipelines|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipelines|This pipeline will run code originating from a forked project merge request. This means that the code can potentially have security considerations like exposing CI variables."
msgstr ""
@@ -26500,9 +27071,6 @@ msgstr ""
msgid "Pipelines|Your changes have been successfully committed. Now redirecting to the new merge request page."
msgstr ""
-msgid "Pipelines|detached"
-msgstr ""
-
msgid "Pipelines|error"
msgstr ""
@@ -26512,10 +27080,13 @@ msgstr ""
msgid "Pipelines|latest"
msgstr ""
-msgid "Pipelines|stuck"
+msgid "Pipelines|merge request"
msgstr ""
-msgid "Pipelines|train"
+msgid "Pipelines|merge train"
+msgstr ""
+
+msgid "Pipelines|stuck"
msgstr ""
msgid "Pipelines|yaml invalid"
@@ -26647,6 +27218,12 @@ msgstr ""
msgid "Pipeline|This change will not change the overall test coverage if merged."
msgstr ""
+msgid "Pipeline|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipeline|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipeline|Trigger author"
msgstr ""
@@ -26671,6 +27248,12 @@ msgstr ""
msgid "Pipeline|for"
msgstr ""
+msgid "Pipeline|merge request"
+msgstr ""
+
+msgid "Pipeline|merge train"
+msgstr ""
+
msgid "Pipeline|on"
msgstr ""
@@ -26809,9 +27392,6 @@ msgstr ""
msgid "Please enter a valid time interval"
msgstr ""
-msgid "Please enter or upload a valid license."
-msgstr ""
-
msgid "Please enter your current password."
msgstr ""
@@ -26920,9 +27500,6 @@ msgstr ""
msgid "Please type %{phrase_code} to proceed or close this modal to cancel."
msgstr ""
-msgid "Please type the following to confirm:"
-msgstr ""
-
msgid "Please use this form to report to the admin users who create spam issues, comments or behave inappropriately."
msgstr ""
@@ -26950,12 +27527,27 @@ msgstr ""
msgid "Policies"
msgstr ""
+msgid "Policy '%{escalation_policy_name}' does not exist."
+msgstr ""
+
msgid "Policy management project does have any policies in %{policy_path}"
msgstr ""
msgid "Policy project doesn't exist"
msgstr ""
+msgid "PolicyRuleMultiSelect|%{firstLabel} +%{numberOfAdditionalLabels} more"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|All %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select all"
+msgstr ""
+
msgid "Polling interval multiplier"
msgstr ""
@@ -27184,6 +27776,9 @@ msgstr ""
msgid "Private projects can be created in your personal namespace with:"
msgstr ""
+msgid "Problem with %{name} command: %{message}."
+msgstr ""
+
msgid "Proceed"
msgstr ""
@@ -27658,6 +28253,9 @@ msgstr ""
msgid "Progress"
msgstr ""
+msgid "Progress tracking"
+msgstr ""
+
msgid "Project"
msgstr ""
@@ -27889,6 +28487,9 @@ msgstr ""
msgid "ProjectQualitySummary|Failure"
msgstr ""
+msgid "ProjectQualitySummary|Get insight into the overall percentage of tests in your project that succeed, fail and are skipped."
+msgstr ""
+
msgid "ProjectQualitySummary|Latest pipeline results"
msgstr ""
@@ -27907,6 +28508,12 @@ msgstr ""
msgid "ProjectQualitySummary|See project Code Coverage Statistics"
msgstr ""
+msgid "ProjectQualitySummary|Set up test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|Set up test runs (opens in a new tab)"
+msgstr ""
+
msgid "ProjectQualitySummary|Skipped"
msgstr ""
@@ -28183,13 +28790,19 @@ msgstr ""
msgid "ProjectSettings|LFS objects from this repository are available to forks. %{linkStart}How do I remove them?%{linkEnd}"
msgstr ""
+msgid "ProjectSettings|Learn about commit history."
+msgstr ""
+
+msgid "ProjectSettings|Leave empty to use default template."
+msgstr ""
+
msgid "ProjectSettings|Manage who can see the project in the public access directory."
msgstr ""
msgid "ProjectSettings|Manages large files such as audio, video, and graphics files."
msgstr ""
-msgid "ProjectSettings|Maximum 500 characters."
+msgid "ProjectSettings|Maximum %{maxLength} characters."
msgstr ""
msgid "ProjectSettings|Merge checks"
@@ -28330,6 +28943,9 @@ msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
msgstr ""
+msgid "ProjectSettings|The default template will be applied on save."
+msgstr ""
+
msgid "ProjectSettings|These checks must pass before merge requests can be merged."
msgstr ""
@@ -28384,6 +29000,9 @@ msgstr ""
msgid "ProjectSettings|What are badges?"
msgstr ""
+msgid "ProjectSettings|What are merge trains?"
+msgstr ""
+
msgid "ProjectSettings|When merge request pipelines are enabled in the CI/CD configuration file, pipelines validate the combined results of the source and target branches. %{link_start}How to configure merge request pipelines?%{link_end}"
msgstr ""
@@ -28501,6 +29120,9 @@ msgstr ""
msgid "Projects are organized into groups"
msgstr ""
+msgid "Projects are where you store your code, access issues, wiki and other features of GitLab."
+msgstr ""
+
msgid "Projects contributed to"
msgstr ""
@@ -28516,12 +29138,6 @@ msgstr ""
msgid "Projects to index"
msgstr ""
-msgid "Projects will be permanently deleted after a %{waiting_period}-day waiting period."
-msgstr ""
-
-msgid "Projects will be permanently deleted immediately."
-msgstr ""
-
msgid "Projects with critical vulnerabilities"
msgstr ""
@@ -28606,6 +29222,9 @@ msgstr ""
msgid "ProjectsNew|Import project"
msgstr ""
+msgid "ProjectsNew|Include a Getting Started README"
+msgstr ""
+
msgid "ProjectsNew|Initialize repository with a README"
msgstr ""
@@ -28621,6 +29240,9 @@ msgstr ""
msgid "ProjectsNew|Project description %{tag_start}(optional)%{tag_end}"
msgstr ""
+msgid "ProjectsNew|Recommended if you're new to GitLab"
+msgstr ""
+
msgid "ProjectsNew|Run CI/CD for external repository"
msgstr ""
@@ -29038,6 +29660,9 @@ msgstr ""
msgid "ProtectedBranch|Unprotect"
msgstr ""
+msgid "ProtectedBranch|Unprotect branch"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
@@ -29065,6 +29690,9 @@ msgstr ""
msgid "ProtectedEnvironment|Protected Environment (%{protected_environments_count})"
msgstr ""
+msgid "ProtectedEnvironment|Required approvals"
+msgstr ""
+
msgid "ProtectedEnvironment|Select an environment"
msgstr ""
@@ -29086,10 +29714,13 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|Unprotect tag"
+msgstr ""
+
msgid "ProtectedTags|default"
msgstr ""
-msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
+msgid "ProtectedTag|By default, protected tags restrict who can modify the tag."
msgstr ""
msgid "ProtectedTag|Learn more."
@@ -29152,6 +29783,9 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Public projects are an easy way to allow everyone to have read-only access."
+msgstr ""
+
msgid "Publish to status page"
msgstr ""
@@ -29308,9 +29942,6 @@ msgstr ""
msgid "QualitySummary|Project quality"
msgstr ""
-msgid "Quarters"
-msgstr ""
-
msgid "Query"
msgstr ""
@@ -29395,6 +30026,9 @@ msgstr ""
msgid "Read more about project permissions %{help_link_open}here%{help_link_close}"
msgstr ""
+msgid "Read more about related epics"
+msgstr ""
+
msgid "Read more about related issues"
msgstr ""
@@ -29425,10 +30059,7 @@ msgstr ""
msgid "Rebase source branch on the target branch."
msgstr ""
-msgid "Rebase without CI"
-msgstr ""
-
-msgid "Rebases and triggers a pipeline"
+msgid "Rebase without pipeline"
msgstr ""
msgid "Recaptcha verified?"
@@ -29479,9 +30110,6 @@ msgstr ""
msgid "Reconfigure"
msgstr ""
-msgid "Recovering projects"
-msgstr ""
-
msgid "Recovery Codes"
msgstr ""
@@ -29541,6 +30169,12 @@ msgstr ""
msgid "Regex pattern"
msgstr ""
+msgid "Region"
+msgstr ""
+
+msgid "Regions"
+msgstr ""
+
msgid "Register"
msgstr ""
@@ -29771,9 +30405,6 @@ msgstr ""
msgid "Remove all or specific reviewer(s)"
msgstr ""
-msgid "Remove approver"
-msgstr ""
-
msgid "Remove approvers"
msgstr ""
@@ -29789,6 +30420,9 @@ msgstr ""
msgid "Remove attention request"
msgstr ""
+msgid "Remove attention request(s)"
+msgstr ""
+
msgid "Remove avatar"
msgstr ""
@@ -29927,6 +30561,9 @@ msgstr ""
msgid "Removed an issue from an epic."
msgstr ""
+msgid "Removed attention from %{users_sentence}."
+msgstr ""
+
msgid "Removed attention request from @%{username}"
msgstr ""
@@ -29978,6 +30615,9 @@ msgstr ""
msgid "Removes an issue from an epic."
msgstr ""
+msgid "Removes attention from %{users_sentence}."
+msgstr ""
+
msgid "Removes parent epic %{epic_ref}."
msgstr ""
@@ -30089,6 +30729,9 @@ msgstr ""
msgid "Report abuse to admin"
msgstr ""
+msgid "Report is generating and will be sent to your email address."
+msgstr ""
+
msgid "Reported %{timeAgo} by %{reportedBy}"
msgstr ""
@@ -30378,6 +31021,15 @@ msgstr ""
msgid "Request attention"
msgstr ""
+msgid "Request attention from %{users_sentence}."
+msgstr ""
+
+msgid "Request attention from assignee or reviewer"
+msgstr ""
+
+msgid "Request attention from assignee(s) or reviewer(s)"
+msgstr ""
+
msgid "Request attention to review"
msgstr ""
@@ -30402,6 +31054,9 @@ msgstr ""
msgid "Requested %{time_ago}"
msgstr ""
+msgid "Requested attention from %{users_sentence}."
+msgstr ""
+
msgid "Requested attention from @%{username}"
msgstr ""
@@ -30616,6 +31271,9 @@ msgstr ""
msgid "Restore project"
msgstr ""
+msgid "Restoring projects"
+msgstr ""
+
msgid "Restoring the group will prevent the group, its subgroups and projects from being removed on this date."
msgstr ""
@@ -30646,6 +31304,9 @@ msgstr ""
msgid "Retry"
msgstr ""
+msgid "Retry failed jobs"
+msgstr ""
+
msgid "Retry job"
msgstr ""
@@ -30693,9 +31354,6 @@ msgstr ""
msgid "Review changes"
msgstr ""
-msgid "Review requested from %{name}"
-msgstr ""
-
msgid "Review requests for you"
msgstr ""
@@ -30860,6 +31518,9 @@ msgstr ""
msgid "Runners|Assigned Group"
msgstr ""
+msgid "Runners|Assigned Projects (%{projectCount})"
+msgstr ""
+
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30929,6 +31590,9 @@ msgstr ""
msgid "Runners|Instance"
msgstr ""
+msgid "Runners|Jobs"
+msgstr ""
+
msgid "Runners|Last contact"
msgstr ""
@@ -31022,9 +31686,6 @@ msgstr ""
msgid "Runners|Runner %{name} was deleted"
msgstr ""
-msgid "Runners|Runner ID"
-msgstr ""
-
msgid "Runners|Runner assigned to project."
msgstr ""
@@ -31172,6 +31833,9 @@ msgstr ""
msgid "Runners|stale"
msgstr ""
+msgid "Runner|This runner has not run any jobs."
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -31286,6 +31950,24 @@ msgstr ""
msgid "Saving project."
msgstr ""
+msgid "ScanResultPolicy|%{ifLabelStart}if%{ifLabelEnd} %{scanners} scan in an open merge request targeting the %{branches} branch(es) finds %{vulnerabilitiesAllowed} or more %{severities} vulnerabilities that are %{vulnerabilityStates}"
+msgstr ""
+
+msgid "ScanResultPolicy|%{thenLabelStart}Then%{thenLabelEnd} Require approval from %{approvalsRequired} of the following approvers: %{approvers}"
+msgstr ""
+
+msgid "ScanResultPolicy|add an approver"
+msgstr ""
+
+msgid "ScanResultPolicy|scanners"
+msgstr ""
+
+msgid "ScanResultPolicy|severity levels"
+msgstr ""
+
+msgid "ScanResultPolicy|vulnerability states"
+msgstr ""
+
msgid "Scanner"
msgstr ""
@@ -31418,6 +32100,9 @@ msgstr ""
msgid "Search for a user"
msgstr ""
+msgid "Search for an emoji"
+msgstr ""
+
msgid "Search for projects, issues, etc."
msgstr ""
@@ -31605,18 +32290,12 @@ msgstr ""
msgid "Secret Detection"
msgstr ""
-msgid "Secret access key"
-msgstr ""
-
msgid "Secret token"
msgstr ""
msgid "Secure token that identifies an external storage request."
msgstr ""
-msgid "SecureCodeWarrior"
-msgstr ""
-
msgid "Security"
msgstr ""
@@ -31641,9 +32320,6 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "Security training with guide and learning pathways."
-msgstr ""
-
msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
@@ -31746,7 +32422,7 @@ msgstr ""
msgid "SecurityConfiguration|Manage corpus"
msgstr ""
-msgid "SecurityConfiguration|Manage corpus files used as mutation sources in coverage fuzzing."
+msgid "SecurityConfiguration|Manage corpus files used as seed inputs with coverage-guided fuzzing."
msgstr ""
msgid "SecurityConfiguration|Manage profiles for use by DAST scans."
@@ -31812,15 +32488,15 @@ msgstr ""
msgid "SecurityOrchestration|.yaml preview"
msgstr ""
-msgid "SecurityOrchestration|Action"
-msgstr ""
-
msgid "SecurityOrchestration|Actions"
msgstr ""
msgid "SecurityOrchestration|Add rule"
msgstr ""
+msgid "SecurityOrchestration|After dismissing the alert, the information will never be shown again."
+msgstr ""
+
msgid "SecurityOrchestration|All policies"
msgstr ""
@@ -31836,7 +32512,7 @@ msgstr ""
msgid "SecurityOrchestration|Description"
msgstr ""
-msgid "SecurityOrchestration|Disabled"
+msgid "SecurityOrchestration|Don't show the alert anymore"
msgstr ""
msgid "SecurityOrchestration|Edit policy"
@@ -31845,13 +32521,13 @@ msgstr ""
msgid "SecurityOrchestration|Edit policy project"
msgstr ""
-msgid "SecurityOrchestration|Enabled"
+msgid "SecurityOrchestration|Empty policy name"
msgstr ""
-msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Enabled"
msgstr ""
-msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
msgstr ""
msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
@@ -31860,7 +32536,7 @@ msgstr ""
msgid "SecurityOrchestration|Invalid policy type"
msgstr ""
-msgid "SecurityOrchestration|Latest scan"
+msgid "SecurityOrchestration|Latest scan run against %{agent}"
msgstr ""
msgid "SecurityOrchestration|Network"
@@ -31869,15 +32545,27 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No actions defined - policy will not run."
+msgstr ""
+
+msgid "SecurityOrchestration|No description"
+msgstr ""
+
msgid "SecurityOrchestration|No rules defined - policy will not run."
msgstr ""
+msgid "SecurityOrchestration|Not enabled"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
msgid "SecurityOrchestration|Policies"
msgstr ""
+msgid "SecurityOrchestration|Policy Type"
+msgstr ""
+
msgid "SecurityOrchestration|Policy cannot be enabled for non-existing branches (%{branches})"
msgstr ""
@@ -31902,10 +32590,13 @@ msgstr ""
msgid "SecurityOrchestration|Require %{approvals} %{plural} from %{approvers} if any of the following occur:"
msgstr ""
-msgid "SecurityOrchestration|Rule"
+msgid "SecurityOrchestration|Rules"
msgstr ""
-msgid "SecurityOrchestration|Rules"
+msgid "SecurityOrchestration|Runs %{actions} and %{lastAction} scans"
+msgstr ""
+
+msgid "SecurityOrchestration|Runs a %{action} scan"
msgstr ""
msgid "SecurityOrchestration|Scan Execution"
@@ -31965,6 +32656,9 @@ msgstr ""
msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
+msgid "SecurityOrchestration|This view only shows scan results for the agent %{agent}. You can view scan results for all agents in the %{linkStart}Operational Vulnerabilities tab of the vulnerability report%{linkEnd}."
+msgstr ""
+
msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
@@ -32019,9 +32713,6 @@ msgstr ""
msgid "SecurityOrchestration|users with ids"
msgstr ""
-msgid "SecurityOrchestration|view results"
-msgstr ""
-
msgid "SecurityOrchestration|vulnerabilities"
msgstr ""
@@ -32691,22 +33382,19 @@ 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|In order to start using functions as a service, you must first install Knative on your Kubernetes cluster. %{linkStart}More information%{linkEnd}"
-msgstr ""
-
msgid "Serverless|Learn more about Serverless"
msgstr ""
msgid "Serverless|No functions available"
msgstr ""
-msgid "Serverless|Sign up for First Look"
+msgid "Serverless|Serverless was %{linkStart}deprecated%{linkEnd} in GitLab 14.3."
+msgstr ""
+
+msgid "Serverless|Serverless was %{postLinkStart}deprecated%{postLinkEnd}. But if you opt to use it, you must install Knative in your Kubernetes cluster first. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "Serverless|The deploy job has not finished."
@@ -32718,9 +33406,6 @@ 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 ""
@@ -32736,9 +33421,6 @@ msgstr ""
msgid "Service Account Key"
msgstr ""
-msgid "Service Accounts"
-msgstr ""
-
msgid "Service Accounts keys authorize GitLab to deploy your Google Cloud project"
msgstr ""
@@ -32748,10 +33430,10 @@ msgstr ""
msgid "Service Desk allows people to create issues in your GitLab instance without their own user account. It provides a unique email address for end users to create issues in a project. Replies can be sent either through the GitLab interface or by email. End users only see threads through email."
msgstr ""
-msgid "Service Usage Data"
+msgid "Service account generated successfully"
msgstr ""
-msgid "Service account generated successfully"
+msgid "Service accounts"
msgstr ""
msgid "Service ping is disabled in your configuration file, and cannot be enabled through this form."
@@ -32895,6 +33577,9 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
+msgid "Set the per-user rate limit for getting a user by ID via the API."
+msgstr ""
+
msgid "Set the per-user rate limit for notes created by web or API requests."
msgstr ""
@@ -33074,6 +33759,9 @@ msgstr ""
msgid "Shared runners details"
msgstr ""
+msgid "Shared runners enabled cannot be enabled until a valid credit card is on file"
+msgstr ""
+
msgid "Shared runners help link"
msgstr ""
@@ -33131,6 +33819,9 @@ msgstr ""
msgid "Show all issues."
msgstr ""
+msgid "Show all milestones"
+msgstr ""
+
msgid "Show all test cases."
msgstr ""
@@ -33167,6 +33858,9 @@ msgstr ""
msgid "Show file contents"
msgstr ""
+msgid "Show group milestones"
+msgstr ""
+
msgid "Show labels"
msgstr ""
@@ -33182,6 +33876,12 @@ msgstr ""
msgid "Show open epics"
msgstr ""
+msgid "Show project milestones"
+msgstr ""
+
+msgid "Show sub-group milestones"
+msgstr ""
+
msgid "Show the Closed list"
msgstr ""
@@ -33191,11 +33891,6 @@ msgstr ""
msgid "Show whitespace changes"
msgstr ""
-msgid "Showing %d event"
-msgid_plural "Showing %d events"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Showing %{conflict} between %{sourceBranch} and %{targetBranch}"
msgstr ""
@@ -33255,12 +33950,6 @@ msgstr ""
msgid "Sidebar|None"
msgstr ""
-msgid "Sidebar|Only numeral characters allowed"
-msgstr ""
-
-msgid "Sidebar|Weight"
-msgstr ""
-
msgid "Sidekiq job compression threshold (bytes)"
msgstr ""
@@ -33423,6 +34112,9 @@ msgstr ""
msgid "Slack logo"
msgstr ""
+msgid "SlackIntegration|Are you sure you want to remove this project from the Slack application?"
+msgstr ""
+
msgid "SlackIntegration|GitLab for Slack"
msgstr ""
@@ -33432,6 +34124,9 @@ msgstr ""
msgid "SlackIntegration|Project alias"
msgstr ""
+msgid "SlackIntegration|Remove project"
+msgstr ""
+
msgid "SlackIntegration|Select a GitLab project to link with your Slack workspace."
msgstr ""
@@ -33576,9 +34271,6 @@ msgstr ""
msgid "Something went wrong trying to load issue contacts."
msgstr ""
-msgid "Something went wrong when creating a work item. Please try again"
-msgstr ""
-
msgid "Something went wrong when reordering designs. Please try again"
msgstr ""
@@ -33672,9 +34364,6 @@ msgstr ""
msgid "Something went wrong while inserting your image. Please try again."
msgstr ""
-msgid "Something went wrong while merging this merge request. Please try again."
-msgstr ""
-
msgid "Something went wrong while obtaining the Let's Encrypt certificate."
msgstr ""
@@ -33996,10 +34685,10 @@ 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."
+msgid "SourcegraphAdmin|Learn more."
msgstr ""
-msgid "SourcegraphAdmin|More information"
+msgid "SourcegraphAdmin|Only public projects have code intelligence enabled and communicate with Sourcegraph."
msgstr ""
msgid "SourcegraphAdmin|Save changes"
@@ -34008,7 +34697,7 @@ msgstr ""
msgid "SourcegraphAdmin|Sourcegraph URL"
msgstr ""
-msgid "SourcegraphAdmin|e.g. https://sourcegraph.example.com"
+msgid "SourcegraphAdmin|https://sourcegraph.example.com"
msgstr ""
msgid "SourcegraphPreferences|This feature is experimental and currently limited to certain projects."
@@ -34143,6 +34832,9 @@ msgstr ""
msgid "Start date"
msgstr ""
+msgid "Start free trial"
+msgstr ""
+
msgid "Start merge train"
msgstr ""
@@ -34173,6 +34865,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started escalation for this incident."
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -34185,6 +34880,9 @@ msgstr ""
msgid "Starts at (UTC)"
msgstr ""
+msgid "Starts escalations for this incident"
+msgstr ""
+
msgid "Starts on"
msgstr ""
@@ -34446,6 +35144,9 @@ msgstr ""
msgid "Strikethrough"
msgstr ""
+msgid "Strikethrough text"
+msgstr ""
+
msgid "Subgroup information"
msgstr ""
@@ -34680,6 +35381,21 @@ msgstr ""
msgid "Subscriptions"
msgstr ""
+msgid "Subscriptions|Chat with sales"
+msgstr ""
+
+msgid "Subscriptions|Close"
+msgstr ""
+
+msgid "Subscriptions|Not ready to buy yet?"
+msgstr ""
+
+msgid "Subscriptions|Start a free trial"
+msgstr ""
+
+msgid "Subscriptions|We understand. Maybe you have some questions for our sales team, or maybe you'd like to try some of the paid features first. What would you like to do?"
+msgstr ""
+
msgid "Subscription|Your subscription for %{strong}%{namespace_name}%{strong_close} has expired and you are now on %{pricing_link_start}the GitLab Free tier%{pricing_link_end}. Don't worry, your data is safe. Get in touch with our support team (%{support_email}). They'll gladly help with your subscription renewal."
msgstr ""
@@ -34890,6 +35606,9 @@ msgstr ""
msgid "SuperSonics|Maximum users"
msgstr ""
+msgid "SuperSonics|Offline cloud"
+msgstr ""
+
msgid "SuperSonics|Paste your activation code"
msgstr ""
@@ -34956,6 +35675,12 @@ msgstr ""
msgid "SuperSonics|You do not have an active subscription"
msgstr ""
+msgid "SuperSonics|You have a future dated license"
+msgstr ""
+
+msgid "SuperSonics|You have added a license that activates on %{date}. Please see the subscription history table below for more details."
+msgstr ""
+
msgid "SuperSonics|You have successfully added a license that activates on %{date}. Please see the subscription history table below for more details."
msgstr ""
@@ -35115,6 +35840,9 @@ msgstr ""
msgid "Tag name is required"
msgstr ""
+msgid "Tag push"
+msgstr ""
+
msgid "Tag push events"
msgstr ""
@@ -35217,6 +35945,9 @@ msgstr ""
msgid "TagsPage|protected"
msgstr ""
+msgid "Take a look at the documentation to discover all of GitLab’s capabilities."
+msgstr ""
+
msgid "Target Branch"
msgstr ""
@@ -35619,6 +36350,9 @@ msgstr ""
msgid "Tests"
msgstr ""
+msgid "Text (optional)"
+msgstr ""
+
msgid "Text added to the body of all email messages. %{character_limit} character limit"
msgstr ""
@@ -35669,6 +36403,9 @@ msgstr ""
msgid "The CSV export will be created in the background. Once finished, it will be sent to %{email} in an attachment."
msgstr ""
+msgid "The CSV export you requested of all user memberships is attached to this email."
+msgstr ""
+
msgid "The GitLab subscription service (customers.gitlab.com) is currently experiencing an outage. You can monitor the status and get updates at %{linkStart}status.gitlab.com%{linkEnd}."
msgstr ""
@@ -35744,6 +36481,9 @@ 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 epic"
+msgstr ""
+
msgid "The current issue"
msgstr ""
@@ -35905,6 +36645,9 @@ msgstr ""
msgid "The latest pipeline for this merge request has failed."
msgstr ""
+msgid "The license key is invalid."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -35920,6 +36663,9 @@ msgstr ""
msgid "The license was successfully uploaded and will be active from %{starts_at}. You can see the details below."
msgstr ""
+msgid "The license you uploaded is invalid. If the issue persists, contact support at %{link}."
+msgstr ""
+
msgid "The list creation wizard is already open"
msgstr ""
@@ -36541,10 +37287,13 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} and everything this project contains. %{strongOpen}There is no going back%{strongClose}"
+msgstr ""
+
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains."
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}on %{date}%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains. %{strongOpen}There is no going back.%{strongClose}"
msgstr ""
msgid "This action will %{strongOpen}permanently remove%{strongClose} %{codeOpen}%{group}%{codeClose} %{strongOpen}immediately%{strongClose}."
@@ -36673,9 +37422,6 @@ msgstr ""
msgid "This file was modified for readability, and can't accept suggestions. Edit it directly."
msgstr ""
-msgid "This forked project has the following:"
-msgstr ""
-
msgid "This form is disabled in preview"
msgstr ""
@@ -36688,7 +37434,7 @@ msgstr ""
msgid "This group can't be removed because it is linked to a subscription. To remove this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
-msgid "This group can't be transfered because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
+msgid "This group can't be transferred because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
msgid "This group cannot be invited to a project inside a group with enforced SSO"
@@ -36715,6 +37461,9 @@ 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 incident is already escalated with '%{escalation_policy_name}'."
+msgstr ""
+
msgid "This invitation was sent to %{mail_to_invite_email}, but you are signed in as %{link_to_current_user} with email %{mail_to_current_user}."
msgstr ""
@@ -36733,9 +37482,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 merge train pipeline"
-msgstr ""
-
msgid "This is a private email address %{helpIcon} generated just for you. Anyone who has it can create issues or merge requests as if they were you. If that happens, %{resetLinkStart}reset this token%{resetLinkEnd}."
msgstr ""
@@ -36757,6 +37503,12 @@ msgstr ""
msgid "This is your current session"
msgstr ""
+msgid "This issue cannot be assigned to a confidential epic because it is public."
+msgstr ""
+
+msgid "This issue cannot be made public because it belongs to a confidential epic."
+msgstr ""
+
msgid "This issue is confidential and should only be visible to team members with at least Reporter access."
msgstr ""
@@ -36874,6 +37626,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 branch is protected from force push."
+msgstr ""
+
msgid "This merge request cannot be rebased while there are conflicts."
msgstr ""
@@ -36925,9 +37680,15 @@ msgstr ""
msgid "This pipeline was triggered by a schedule."
msgstr ""
+msgid "This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project"
msgstr ""
+msgid "This project can be restored until %{date}."
+msgstr ""
+
msgid "This project cannot be %{visibilityLevel} because the visibility of %{openShowLink}%{name}%{closeShowLink} is %{visibility}. To make this project %{visibilityLevel}, you must first %{openEditLink}change the visibility%{closeEditLink} of the parent group."
msgstr ""
@@ -36946,6 +37707,9 @@ msgstr ""
msgid "This project is %{strongStart}NOT%{strongEnd} a fork, and has the following:"
msgstr ""
+msgid "This project is %{strongStart}NOT%{strongEnd} a fork. This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -37637,6 +38401,9 @@ msgstr ""
msgid "Today"
msgstr ""
+msgid "Todos count"
+msgstr ""
+
msgid "Todos|Are you looking for things to do? Take a look at %{strongStart}%{openIssuesLinkStart}open issues%{openIssuesLinkEnd}%{strongEnd}, contribute to %{strongStart}%{mergeRequestLinkStart}a merge request%{mergeRequestLinkEnd}%{mergeRequestLinkEnd}%{strongEnd}, or mention someone in a comment to automatically assign them a new to-do item."
msgstr ""
@@ -37910,10 +38677,8 @@ msgstr ""
msgid "Trending"
msgstr ""
-msgid "Trials|%{planName} Trial %{enDash} %{num} day left"
-msgid_plural "Trials|%{planName} Trial %{enDash} %{num} days left"
-msgstr[0] ""
-msgstr[1] ""
+msgid "Trials|%{planName} Trial"
+msgstr ""
msgid "Trials|Compare all plans"
msgstr ""
@@ -37921,6 +38686,9 @@ msgstr ""
msgid "Trials|Create a new group to start your GitLab Ultimate trial."
msgstr ""
+msgid "Trials|Day %{daysUsed}/%{duration}"
+msgstr ""
+
msgid "Trials|Go back to GitLab"
msgstr ""
@@ -38170,7 +38938,7 @@ msgstr ""
msgid "URL is triggered when repository is updated"
msgstr ""
-msgid "URL must be percent-encoded if neccessary."
+msgid "URL must be percent-encoded if necessary."
msgstr ""
msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
@@ -38389,6 +39157,9 @@ msgstr ""
msgid "Unlock account"
msgstr ""
+msgid "Unlock more features with GitLab Ultimate"
+msgstr ""
+
msgid "Unlock the discussion"
msgstr ""
@@ -38452,6 +39223,9 @@ msgstr ""
msgid "Unsubscribes from this %{quick_action_target}."
msgstr ""
+msgid "Unsupported sort value."
+msgstr ""
+
msgid "Unsupported todo type passed. Supported todo types are: %{todo_types}"
msgstr ""
@@ -38680,6 +39454,9 @@ msgstr ""
msgid "UsageQuota|File attachments and smaller design graphics."
msgstr ""
+msgid "UsageQuota|From %{storage_enforcement_date} storage limits will apply to this namespace. View and manage your usage in %{strong_start}Group Settings &gt; Usage quotas%{strong_end}."
+msgstr ""
+
msgid "UsageQuota|Git repository."
msgstr ""
@@ -38740,6 +39517,9 @@ msgstr ""
msgid "UsageQuota|Storage type"
msgstr ""
+msgid "UsageQuota|Storage used"
+msgstr ""
+
msgid "UsageQuota|This is the total amount of storage used across your projects within this namespace."
msgstr ""
@@ -38935,6 +39715,12 @@ msgstr ""
msgid "Use hashed storage paths for newly created and renamed repositories. Always enabled since 13.0."
msgstr ""
+msgid "Use issue count"
+msgstr ""
+
+msgid "Use issue weight"
+msgstr ""
+
msgid "Use one line per URI"
msgstr ""
@@ -39316,6 +40102,9 @@ msgstr ""
msgid "Users"
msgstr ""
+msgid "Users API rate limit"
+msgstr ""
+
msgid "Users can launch a development environment from a GitLab browser tab when the %{linkStart}Gitpod%{linkEnd} integration is enabled."
msgstr ""
@@ -39641,6 +40430,9 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View group pipeline usage quota"
+msgstr ""
+
msgid "View incident details at"
msgstr ""
@@ -39793,6 +40585,9 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
+msgid "Vulnerability"
+msgstr ""
+
msgid "Vulnerability Report"
msgstr ""
@@ -39844,6 +40639,9 @@ msgstr ""
msgid "VulnerabilityManagement|An unverified non-confirmed finding"
msgstr ""
+msgid "VulnerabilityManagement|At least one identifier is required"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -39853,12 +40651,24 @@ msgstr ""
msgid "VulnerabilityManagement|Create Jira issue"
msgstr ""
+msgid "VulnerabilityManagement|Enter a name"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE code"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE identifier URL"
+msgstr ""
+
msgid "VulnerabilityManagement|Fetching linked Jira issues"
msgstr ""
msgid "VulnerabilityManagement|Manually add a vulnerability entry into the vulnerability report."
msgstr ""
+msgid "VulnerabilityManagement|Name is a required field"
+msgstr ""
+
msgid "VulnerabilityManagement|Needs triage"
msgstr ""
@@ -39874,6 +40684,18 @@ msgstr ""
msgid "VulnerabilityManagement|Select a method"
msgstr ""
+msgid "VulnerabilityManagement|Select a severity level"
+msgstr ""
+
+msgid "VulnerabilityManagement|Select a status"
+msgstr ""
+
+msgid "VulnerabilityManagement|Severity is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Something went wrong while creating vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -39898,6 +40720,12 @@ msgstr ""
msgid "VulnerabilityManagement|Something went wrong, could not update vulnerability state."
msgstr ""
+msgid "VulnerabilityManagement|Status is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Submit vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Summary, detailed description, steps to reproduce, etc."
msgstr ""
@@ -40093,6 +40921,9 @@ msgstr ""
msgid "WARNING:"
msgstr ""
+msgid "WARNING: This snippet contains hidden files which might be used to mask malicious behavior. Exercise caution if cloning and executing code from this snippet."
+msgstr ""
+
msgid "Wait for the file to load to copy its contents"
msgstr ""
@@ -40312,6 +41143,15 @@ msgstr ""
msgid "Webhooks|An issue is created, updated, closed, or reopened."
msgstr ""
+msgid "Webhooks|Are you sure you want to delete this group hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this project hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this webhook?"
+msgstr ""
+
msgid "Webhooks|Comments"
msgstr ""
@@ -40321,6 +41161,9 @@ msgstr ""
msgid "Webhooks|Confidential issues events"
msgstr ""
+msgid "Webhooks|Delete webhook"
+msgstr ""
+
msgid "Webhooks|Deployment events"
msgstr ""
@@ -40554,6 +41397,9 @@ msgstr ""
msgid "Wiki"
msgstr ""
+msgid "Wiki page"
+msgstr ""
+
msgid "Wiki page was successfully created."
msgstr ""
@@ -40659,7 +41505,7 @@ msgstr ""
msgid "WikiPageConflictMessage|Someone edited the page the same time you did. Please check out %{wikiLinkStart}the page%{wikiLinkEnd} and make sure your changes will not unintentionally remove theirs."
msgstr ""
-msgid "WikiPage|An error occured while trying to render the content editor. Please try again later."
+msgid "WikiPage|An error occurred while trying to render the content editor. Please try again later."
msgstr ""
msgid "WikiPage|Are you sure you want to switch back to the classic editor?"
@@ -40818,6 +41664,18 @@ msgstr ""
msgid "WorkItem|New Task"
msgstr ""
+msgid "WorkItem|Something went wrong when creating a work item. Please try again"
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching the work item. Please try again."
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching work item types. Please try again"
+msgstr ""
+
+msgid "WorkItem|Type"
+msgstr ""
+
msgid "WorkItem|Work Items"
msgstr ""
@@ -40884,7 +41742,10 @@ msgstr ""
msgid "You are about to add %{usersTag} people to the discussion. They will all receive a notification."
msgstr ""
-msgid "You are about to permanently delete this project"
+msgid "You are about to delete this forked project containing:"
+msgstr ""
+
+msgid "You are about to delete this project containing:"
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."
@@ -40905,6 +41766,9 @@ msgstr ""
msgid "You are attempting to update a file that has changed since you started editing it."
msgstr ""
+msgid "You are billed if you exceed this number. %{qsrOverageLinkStart}How does billing work?%{qsrOverageLinkEnd}"
+msgstr ""
+
msgid "You are connected to the Prometheus server, but there is currently no data to display."
msgstr ""
@@ -40962,6 +41826,9 @@ msgstr ""
msgid "You are not authorized to update this scanner profile"
msgstr ""
+msgid "You are not authorized to upload metric images"
+msgstr ""
+
msgid "You are now impersonating %{username}"
msgstr ""
@@ -41115,9 +41982,6 @@ msgstr ""
msgid "You can only upload one design when dropping onto an existing design."
msgstr ""
-msgid "You can recover this project until %{date}"
-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 ""
@@ -41166,9 +42030,6 @@ msgstr ""
msgid "You cannot write to this read-only GitLab instance."
msgstr ""
-msgid "You can’t %{tag_start}edit%{tag_end} files directly in this project. Fork this project and submit a merge request with your changes."
-msgstr ""
-
msgid "You can’t edit files directly in this project. Fork this project and submit a merge request with your changes."
msgstr ""
@@ -41321,9 +42182,6 @@ 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 set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
@@ -41354,12 +42212,6 @@ msgstr ""
msgid "You must have maintainer access to force delete a lock"
msgstr ""
-msgid "You must have permission to create a project in a group before forking."
-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 ""
@@ -41765,7 +42617,7 @@ msgstr ""
msgid "Your public email will be displayed on your public profile."
msgstr ""
-msgid "Your request for access could not be processed: %{error_meesage}"
+msgid "Your request for access could not be processed: %{error_message}"
msgstr ""
msgid "Your request for access has been queued for review."
@@ -41948,6 +42800,9 @@ msgstr ""
msgid "archived:"
msgstr ""
+msgid "artifacts"
+msgstr ""
+
msgid "assign yourself"
msgstr ""
@@ -41977,6 +42832,9 @@ msgstr[1] ""
msgid "branch name"
msgstr ""
+msgid "builds"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -42400,6 +43258,9 @@ msgstr ""
msgid "contact with same email already exists in group hierarchy"
msgstr ""
+msgid "container registry images"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -42439,6 +43300,9 @@ msgstr ""
msgid "data"
msgstr ""
+msgid "database"
+msgstr ""
+
msgid "date must not be after 9999-12-31"
msgstr ""
@@ -42462,9 +43326,6 @@ msgstr ""
msgid "design"
msgstr ""
-msgid "detached"
-msgstr ""
-
msgid "disabled"
msgstr ""
@@ -42713,7 +43574,7 @@ msgstr ""
msgid "is not a valid X509 certificate."
msgstr ""
-msgid "is not allowed for sign-up."
+msgid "is not allowed for sign-up. Please use your regular email address."
msgstr ""
msgid "is not allowed for this group."
@@ -42725,7 +43586,7 @@ msgstr ""
msgid "is not allowed since the group is not top-level group."
msgstr ""
-msgid "is not allowed."
+msgid "is not allowed. Please use your regular email address."
msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
@@ -42812,6 +43673,9 @@ msgstr ""
msgid "level: %{level}"
msgstr ""
+msgid "lfs objects"
+msgstr ""
+
msgid "limit of %{project_limit} reached"
msgstr ""
@@ -43031,6 +43895,9 @@ msgstr ""
msgid "mrWidget|Merge blocked: pipeline must succeed. It's waiting for a manual action to continue."
msgstr ""
+msgid "mrWidget|Merge blocked: pipeline must succeed. Push a commit that fixes the failure, or %{linkStart}learn about other solutions.%{linkEnd}"
+msgstr ""
+
msgid "mrWidget|Merge blocked: this merge request must be approved."
msgstr ""
@@ -43148,9 +44015,6 @@ msgstr ""
msgid "mrWidget|The changes were not merged into"
msgstr ""
-msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -43298,9 +44162,6 @@ msgstr ""
msgid "open issue"
msgstr ""
-msgid "opened %{timeAgo}"
-msgstr ""
-
msgid "or"
msgstr ""
@@ -43312,6 +44173,12 @@ msgid_plural "out of %d total tests"
msgstr[0] ""
msgstr[1] ""
+msgid "packages"
+msgstr ""
+
+msgid "pages"
+msgstr ""
+
msgid "parent"
msgid_plural "parents"
msgstr[0] ""
@@ -43461,6 +44328,9 @@ msgid_plural "replies"
msgstr[0] ""
msgstr[1] ""
+msgid "repositories"
+msgstr ""
+
msgid "repository:"
msgstr ""
@@ -43581,12 +44451,18 @@ msgstr ""
msgid "tag name"
msgstr ""
+msgid "terraform states"
+msgstr ""
+
msgid "the correct format."
msgstr ""
msgid "the file"
msgstr ""
+msgid "the following epic(s)"
+msgstr ""
+
msgid "the following issue(s)"
msgstr ""
@@ -43599,21 +44475,12 @@ msgstr ""
msgid "this document"
msgstr ""
-msgid "this issue cannot be assigned to a confidential epic since it is public"
-msgstr ""
-
-msgid "this issue cannot be made public since it belongs to a confidential epic"
-msgstr ""
-
msgid "time summary"
msgstr ""
msgid "toggle collapse"
msgstr ""
-msgid "train"
-msgstr ""
-
msgid "triggered"
msgstr ""
@@ -43742,3 +44609,6 @@ msgstr ""
msgid "{project}"
msgstr ""
+msgid "✔"
+msgstr ""
+
diff --git a/locale/ba_RU/gitlab.po b/locale/ba_RU/gitlab.po
index 6fbbcb217a2..5a88c7ef364 100644
--- a/locale/ba_RU/gitlab.po
+++ b/locale/ba_RU/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: ba\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2022-02-02 15:47\n"
+"PO-Revision-Date: 2022-03-01 20:40\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -132,6 +132,10 @@ msgid "%d approver (you've approved)"
msgid_plural "%d approvers (you've approved)"
msgstr[0] ""
+msgid "%d assigned issue"
+msgid_plural "%d assigned issues"
+msgstr[0] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -352,8 +356,20 @@ msgid "%d vulnerability dismissed"
msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
-msgid "%d vulnerability updated"
-msgid_plural "%d vulnerabilities updated"
+msgid "%d vulnerability set to confirmed"
+msgid_plural "%d vulnerabilities set to confirmed"
+msgstr[0] ""
+
+msgid "%d vulnerability set to dismissed"
+msgid_plural "%d vulnerabilities set to dismissed"
+msgstr[0] ""
+
+msgid "%d vulnerability set to needs triage"
+msgid_plural "%d vulnerabilities set to needs triage"
+msgstr[0] ""
+
+msgid "%d vulnerability set to resolved"
+msgid_plural "%d vulnerabilities set to resolved"
msgstr[0] ""
msgid "%d warning found:"
@@ -434,6 +450,12 @@ msgstr[0] ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{completed} of %{total} issues closed"
+msgstr ""
+
+msgid "%{completed} of %{total} weight completed"
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -776,6 +798,9 @@ msgstr ""
msgid "%{openedIssues} open, %{closedIssues} closed"
msgstr ""
+msgid "%{percentage}%% issues closed"
+msgstr ""
+
msgid "%{percentage}%% weight completed"
msgstr ""
@@ -1190,6 +1215,9 @@ msgid "- User"
msgid_plural "- Users"
msgstr[0] ""
+msgid "- of - issues closed"
+msgstr ""
+
msgid "- of - weight completed"
msgstr ""
@@ -1309,7 +1337,7 @@ msgstr ""
msgid "1000+"
msgstr ""
-msgid "192.168.0.0/24"
+msgid "192.168.0.0/24 or 2001:0DB8:1234::/48"
msgstr ""
msgid "1st contribution!"
@@ -1621,13 +1649,13 @@ msgstr ""
msgid "AWS Access Key"
msgstr ""
-msgid "AWS Access Key. Only required if not using role instance credentials"
+msgid "AWS Secret Access Key"
msgstr ""
-msgid "AWS Secret Access Key"
+msgid "AWS access key ID (Optional)"
msgstr ""
-msgid "AWS Secret Access Key. Only required if not using role instance credentials"
+msgid "AWS secret access key (Optional)"
msgstr ""
msgid "AWS service error: %{error}"
@@ -1687,9 +1715,6 @@ msgstr ""
msgid "Access granted"
msgstr ""
-msgid "Access key ID"
-msgstr ""
-
msgid "Access requests"
msgstr ""
@@ -1864,7 +1889,7 @@ msgstr ""
msgid "Activity"
msgstr ""
-msgid "Activity|An error occured while retrieving activity. Reload the page to try again."
+msgid "Activity|An error occurred while retrieving activity. Reload the page to try again."
msgstr ""
msgid "Add"
@@ -1903,6 +1928,9 @@ msgstr ""
msgid "Add a %{type}"
msgstr ""
+msgid "Add a GCP region"
+msgstr ""
+
msgid "Add a GPG key"
msgstr ""
@@ -1954,6 +1982,9 @@ msgstr ""
msgid "Add a numbered list"
msgstr ""
+msgid "Add a related epic"
+msgstr ""
+
msgid "Add a related issue"
msgstr ""
@@ -2068,6 +2099,9 @@ msgstr ""
msgid "Add or subtract spent time"
msgstr ""
+msgid "Add people"
+msgstr ""
+
msgid "Add previously merged commits"
msgstr ""
@@ -2134,6 +2168,9 @@ msgstr ""
msgid "Add webhook"
msgstr ""
+msgid "Add your team members and others to GitLab."
+msgstr ""
+
msgid "Add/remove"
msgstr ""
@@ -2956,12 +2993,6 @@ msgstr ""
msgid "AdvancedSearch|Reindex required"
msgstr ""
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. Permanently deleting this project will %{strongStart}immediately delete%{strongEnd} its repositories and %{strongStart}all related resources%{strongEnd}, including issues, merge requests etc."
-msgstr ""
-
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. You will lose this project's repository and %{strongStart}all related resources%{strongEnd}, including issues and merge requests."
-msgstr ""
-
msgid "After a successful password update you will be redirected to login screen."
msgstr ""
@@ -2992,6 +3023,9 @@ msgstr ""
msgid "Akismet helps prevent the creation of spam issues in public projects."
msgstr ""
+msgid "Alert"
+msgstr ""
+
msgid "AlertManagement|Acknowledged"
msgstr ""
@@ -3364,9 +3398,6 @@ msgstr ""
msgid "All environments"
msgstr ""
-msgid "All epics"
-msgstr ""
-
msgid "All groups and projects"
msgstr ""
@@ -4101,11 +4132,14 @@ msgstr ""
msgid "ApplicationSettings|Approve users in the pending approval status?"
msgstr ""
-msgid "ApplicationSettings|By making this change, you will automatically approve %d user with the pending approval status."
-msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users with the pending approval status."
+msgid "ApplicationSettings|Approve users who are pending approval?"
+msgstr ""
+
+msgid "ApplicationSettings|By making this change, you will automatically approve %d user who is pending approval."
+msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users who are pending approval."
msgstr[0] ""
-msgid "ApplicationSettings|By making this change, you will automatically approve all users in pending approval status."
+msgid "ApplicationSettings|By making this change, you will automatically approve all users who are pending approval."
msgstr ""
msgid "ApplicationSettings|Denied domains for sign-ups"
@@ -4506,10 +4540,10 @@ msgstr ""
msgid "Archiving the project will make it entirely read-only. It is hidden from the dashboard and doesn't show up in searches. %{strong_start}The repository cannot be committed to, and no issues, comments, or other entities can be created.%{strong_end} %{link_start}Learn more.%{link_end}"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to delete this project?"
+msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
+msgid "Are you absolutely sure?"
msgstr ""
msgid "Are you sure that you want to archive this project?"
@@ -4545,12 +4579,18 @@ msgstr ""
msgid "Are you sure you want to delete this SSH key?"
msgstr ""
+msgid "Are you sure you want to delete this comment?"
+msgstr ""
+
msgid "Are you sure you want to delete this deploy key?"
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 label?"
+msgstr ""
+
msgid "Are you sure you want to delete this pipeline schedule?"
msgstr ""
@@ -4566,9 +4606,6 @@ msgstr ""
msgid "Are you sure you want to discard your changes?"
msgstr ""
-msgid "Are you sure you want to erase this build?"
-msgstr ""
-
msgid "Are you sure you want to import %d repository?"
msgid_plural "Are you sure you want to import %d repositories?"
msgstr[0] ""
@@ -4615,6 +4652,9 @@ msgstr ""
msgid "Are you sure you want to remove this list?"
msgstr ""
+msgid "Are you sure you want to remove this nickname?"
+msgstr ""
+
msgid "Are you sure you want to reset the health check token?"
msgstr ""
@@ -4627,10 +4667,10 @@ 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?"
+msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
msgstr ""
-msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
+msgid "Are you sure you want to revoke this project access token? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to stop this environment?"
@@ -4777,9 +4817,6 @@ msgstr ""
msgid "Assigned to %{assignee_name}"
msgstr ""
-msgid "Assigned to %{name}"
-msgstr ""
-
msgid "Assigned to me"
msgstr ""
@@ -4842,6 +4879,9 @@ msgstr[0] ""
msgid "Attaching the file failed."
msgstr ""
+msgid "Attention"
+msgstr ""
+
msgid "Audit Events"
msgstr ""
@@ -5004,6 +5044,12 @@ msgstr ""
msgid "Authorized applications (%{size})"
msgstr ""
+msgid "AuthorizedApplication|Are you sure you want to revoke this application?"
+msgstr ""
+
+msgid "AuthorizedApplication|Revoke application"
+msgstr ""
+
msgid "Authors: %{authors}"
msgstr ""
@@ -6193,6 +6239,9 @@ msgstr ""
msgid "CICDAnalytics|Shared Runners Usage"
msgstr ""
+msgid "CICDAnalytics|Shared runner pipeline minute duration by month"
+msgstr ""
+
msgid "CICDAnalytics|Shared runner usage"
msgstr ""
@@ -6334,6 +6383,9 @@ msgstr ""
msgid "Can create groups:"
msgstr ""
+msgid "Can not delete primary training"
+msgstr ""
+
msgid "Can't apply as the source branch was deleted."
msgstr ""
@@ -6667,9 +6719,6 @@ msgstr ""
msgid "Changing any setting here requires an application restart"
msgstr ""
-msgid "Changing group URL can have unintended side effects."
-msgstr ""
-
msgid "Charts can't be displayed as the request for data has timed out. %{documentationLink}"
msgstr ""
@@ -6757,9 +6806,6 @@ msgstr ""
msgid "Checking branch availability..."
msgstr ""
-msgid "Checking group URL availability..."
-msgstr ""
-
msgid "Checking group path availability..."
msgstr ""
@@ -7251,6 +7297,9 @@ msgstr ""
msgid "Clear recent searches"
msgstr ""
+msgid "Clear repository checks"
+msgstr ""
+
msgid "Clear search"
msgstr ""
@@ -7383,9 +7432,6 @@ msgstr ""
msgid "Closed MRs"
msgstr ""
-msgid "Closed epics"
-msgstr ""
-
msgid "Closed issues"
msgstr ""
@@ -7422,13 +7468,13 @@ msgstr ""
msgid "Cluster level"
msgstr ""
-msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
+msgid "Cluster type must be specified for Stages::ClusterEndpointInserter"
msgstr ""
msgid "ClusterAgents|%{name} successfully deleted"
msgstr ""
-msgid "ClusterAgents|%{number} of %{total} Agents"
+msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
@@ -7470,6 +7516,15 @@ msgstr ""
msgid "ClusterAgents|Agent never connected to GitLab"
msgstr ""
+msgid "ClusterAgents|Agent version mismatch"
+msgstr ""
+
+msgid "ClusterAgents|Agent version mismatch and update"
+msgstr ""
+
+msgid "ClusterAgents|Agent version update required"
+msgstr ""
+
msgid "ClusterAgents|All"
msgstr ""
@@ -7494,7 +7549,7 @@ msgstr ""
msgid "ClusterAgents|Configuration"
msgstr ""
-msgid "ClusterAgents|Connect a cluster through the Agent"
+msgid "ClusterAgents|Connect a cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connect existing cluster"
@@ -7503,13 +7558,13 @@ msgstr ""
msgid "ClusterAgents|Connect with a certificate"
msgstr ""
-msgid "ClusterAgents|Connect with agent"
+msgid "ClusterAgents|Connect with an agent"
msgstr ""
msgid "ClusterAgents|Connect with the GitLab Agent"
msgstr ""
-msgid "ClusterAgents|Connect your cluster through the Agent"
+msgid "ClusterAgents|Connect your cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connected"
@@ -7569,7 +7624,10 @@ msgstr ""
msgid "ClusterAgents|How to register an agent?"
msgstr ""
-msgid "ClusterAgents|Install new Agent"
+msgid "ClusterAgents|How to update an agent?"
+msgstr ""
+
+msgid "ClusterAgents|Install a new agent"
msgstr ""
msgid "ClusterAgents|Last connected %{timeAgo}."
@@ -7596,7 +7654,7 @@ msgstr ""
msgid "ClusterAgents|Never connected"
msgstr ""
-msgid "ClusterAgents|No Agents"
+msgid "ClusterAgents|No agents"
msgstr ""
msgid "ClusterAgents|No clusters connected through cluster certificates"
@@ -7656,6 +7714,9 @@ msgstr ""
msgid "ClusterAgents|The agent has not been connected in a long time. There might be a connectivity issue. Last contact was %{timeAgo}."
msgstr ""
+msgid "ClusterAgents|The agent version do not match each other across your cluster's pods. This can happen when a new agent version was just deployed and Kubernetes is shutting down the old pods."
+msgstr ""
+
msgid "ClusterAgents|The recommended installation method includes the token. If you want to follow the advanced installation method provided in the docs, make sure you save the token value before you close this window."
msgstr ""
@@ -7702,6 +7763,9 @@ msgstr ""
msgid "ClusterAgents|You will need to create a token to connect to your agent"
msgstr ""
+msgid "ClusterAgents|Your agent version is out of sync with your GitLab version (v%{version}), which might cause compatibility problems. Update the agent installed on your cluster to the most recent version."
+msgstr ""
+
msgid "ClusterAgents|Your instance doesn't have the %{linkStart}GitLab Agent Server (KAS)%{linkEnd} set up. Ask a GitLab Administrator to install it."
msgstr ""
@@ -8578,9 +8642,6 @@ msgstr ""
msgid "Comma-separated list of email addresses."
msgstr ""
-msgid "Comma-separated list of users allowed to exceed the rate limit."
-msgstr ""
-
msgid "Comma-separated, e.g. '1.1.1.1, 2.2.2.0/24'"
msgstr ""
@@ -8906,6 +8967,12 @@ msgstr ""
msgid "Confidential"
msgstr ""
+msgid "Confidential issue"
+msgstr ""
+
+msgid "Confidential note"
+msgstr ""
+
msgid "Confidentiality"
msgstr ""
@@ -8939,6 +9006,9 @@ msgstr ""
msgid "Configure Dependency Scanning in `.gitlab-ci.yml`, creating this file if it does not already exist"
msgstr ""
+msgid "Configure GitLab"
+msgstr ""
+
msgid "Configure GitLab runners to start using the Web Terminal. %{helpStart}Learn more.%{helpEnd}"
msgstr ""
@@ -8987,6 +9057,15 @@ msgstr ""
msgid "Configure pipelines to deploy web apps, backend services, APIs and static resources to Google Cloud"
msgstr ""
+msgid "Configure region"
+msgstr ""
+
+msgid "Configure region for environment"
+msgstr ""
+
+msgid "Configure regions"
+msgstr ""
+
msgid "Configure repository mirroring."
msgstr ""
@@ -9020,6 +9099,9 @@ msgstr ""
msgid "Configure which lists are shown for anyone who visits this board"
msgstr ""
+msgid "Configure your environments to be deployed to specific geographical regions"
+msgstr ""
+
msgid "Confirm"
msgstr ""
@@ -9719,10 +9801,10 @@ msgstr ""
msgid "CorpusManagement|Actions"
msgstr ""
-msgid "CorpusManagement|Corpus are used in fuzz testing as mutation source to Improve future testing."
+msgid "CorpusManagement|Corpus file"
msgstr ""
-msgid "CorpusManagement|Corpus file"
+msgid "CorpusManagement|Corpus files are used in coverage-guided fuzz testing as seed inputs to improve testing."
msgstr ""
msgid "CorpusManagement|Corpus files must be in *.zip format. Maximum 5 GB"
@@ -9776,6 +9858,9 @@ msgstr ""
msgid "Could not apply %{name} command."
msgstr ""
+msgid "Could not apply %{name} command. %{message}."
+msgstr ""
+
msgid "Could not authorize chat nickname. Try again!"
msgstr ""
@@ -9926,6 +10011,9 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
+msgid "Create a group"
+msgstr ""
+
msgid "Create a merge request"
msgstr ""
@@ -9950,6 +10038,9 @@ msgstr ""
msgid "Create a personal access token on your account to pull or push via %{protocol}."
msgstr ""
+msgid "Create a project"
+msgstr ""
+
msgid "Create an account using:"
msgstr ""
@@ -10313,6 +10404,9 @@ msgstr ""
msgid "Creation date"
msgstr ""
+msgid "Creator"
+msgstr ""
+
msgid "Credentials"
msgstr ""
@@ -10325,9 +10419,15 @@ msgstr ""
msgid "CredentialsInventory|Personal Access Tokens"
msgstr ""
+msgid "CredentialsInventory|Project Access Tokens"
+msgstr ""
+
msgid "CredentialsInventory|SSH Keys"
msgstr ""
+msgid "Credit card required to be on file in order to create a pipeline"
+msgstr ""
+
msgid "Credit card:"
msgstr ""
@@ -10511,9 +10611,6 @@ msgstr ""
msgid "Customer relations"
msgstr ""
-msgid "Customizable by an administrator."
-msgstr ""
-
msgid "Customizable by owners."
msgstr ""
@@ -10643,30 +10740,18 @@ msgstr ""
msgid "CycleAnalytics|%{selectedLabelsCount} selected (%{maxLabels} max)"
msgstr ""
-msgid "CycleAnalytics|%{stageCount} stages selected"
-msgstr ""
-
-msgid "CycleAnalytics|All stages"
-msgstr ""
-
-msgid "CycleAnalytics|Average days to completion"
+msgid "CycleAnalytics|Average time to completion"
msgstr ""
msgid "CycleAnalytics|Date"
msgstr ""
-msgid "CycleAnalytics|Days to completion"
-msgstr ""
-
msgid "CycleAnalytics|Display chart filters"
msgstr ""
msgid "CycleAnalytics|Lead Time for Changes"
msgstr ""
-msgid "CycleAnalytics|No stages selected"
-msgstr ""
-
msgid "CycleAnalytics|Number of tasks"
msgstr ""
@@ -10693,18 +10778,30 @@ msgstr ""
msgid "CycleAnalytics|Showing data for group '%{groupName}' from %{createdAfter} to %{createdBefore}"
msgstr ""
-msgid "CycleAnalytics|Stages"
+msgid "CycleAnalytics|Stage time: %{title}"
msgstr ""
msgid "CycleAnalytics|Tasks by type"
msgstr ""
-msgid "CycleAnalytics|The average time spent in the selected stage for the items that were completed on each date. Data limited to the last 500 items."
+msgid "CycleAnalytics|The average time items spent in this stage. Data limited to items completed within this date range."
msgstr ""
msgid "CycleAnalytics|The given date range is larger than 180 days"
msgstr ""
+msgid "CycleAnalytics|The total time items spent across each value stream stage. Data limited to items completed within this date range."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Stage time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Total time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|Total time"
+msgstr ""
+
msgid "CycleAnalytics|Type of work"
msgstr ""
@@ -10717,9 +10814,6 @@ msgstr ""
msgid "CycleAnalytics|project dropdown filter"
msgstr ""
-msgid "CycleAnalytics|stage dropdown"
-msgstr ""
-
msgid "DAG visualization requires at least 3 dependent jobs."
msgstr ""
@@ -10819,10 +10913,16 @@ msgstr ""
msgid "DastProfiles|AJAX spider"
msgstr ""
+msgid "DastProfiles|API"
+msgstr ""
+
+msgid "DastProfiles|API endpoint URL"
+msgstr ""
+
msgid "DastProfiles|Active"
msgstr ""
-msgid "DastProfiles|Additional request headers (Optional)"
+msgid "DastProfiles|Additional request headers (optional)"
msgstr ""
msgid "DastProfiles|Are you sure you want to delete this profile?"
@@ -10837,6 +10937,9 @@ msgstr ""
msgid "DastProfiles|Branch missing"
msgstr ""
+msgid "DastProfiles|Choose a scan method"
+msgstr ""
+
msgid "DastProfiles|Could not create the scanner profile. Please try again."
msgstr ""
@@ -10906,7 +11009,13 @@ msgstr ""
msgid "DastProfiles|Excluded URLs"
msgstr ""
-msgid "DastProfiles|Excluded URLs (Optional)"
+msgid "DastProfiles|Excluded URLs (optional)"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths (optional)"
msgstr ""
msgid "DastProfiles|Hide debug messages"
@@ -10963,9 +11072,6 @@ msgstr ""
msgid "DastProfiles|Request headers"
msgstr ""
-msgid "DastProfiles|Rest API"
-msgstr ""
-
msgid "DastProfiles|Run the AJAX spider, in addition to the traditional spider, to crawl the target site."
msgstr ""
@@ -10975,6 +11081,9 @@ msgstr ""
msgid "DastProfiles|Save profile"
msgstr ""
+msgid "DastProfiles|Scan method"
+msgstr ""
+
msgid "DastProfiles|Scan mode"
msgstr ""
@@ -11053,12 +11162,24 @@ msgstr ""
msgid "DastProfiles|Website"
msgstr ""
+msgid "DastProfiles|What does each method do?"
+msgstr ""
+
msgid "DastProfiles|You can either choose a passive scan or validate the target site from the site profile management page. %{docsLinkStart}Learn more about site validation.%{docsLinkEnd}"
msgstr ""
msgid "DastProfiles|You cannot run an active scan against an unvalidated site."
msgstr ""
+msgid "DastProfiles|folder/dast_example.har or https://example.com/dast_example.har"
+msgstr ""
+
+msgid "DastProfiles|folder/example.postman_collection.json or https://example.com/"
+msgstr ""
+
+msgid "DastProfiles|folder/openapi.json or https://example.com/openapi.json"
+msgstr ""
+
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
@@ -11165,6 +11286,9 @@ msgstr ""
msgid "DatadogIntegration|API URL"
msgstr ""
+msgid "DatadogIntegration|Custom tags in Datadog. Enter one tag per line in the %{codeOpen}key:value%{codeClose} format. %{linkOpen}How do I use tags?%{linkClose}"
+msgstr ""
+
msgid "DatadogIntegration|Environment"
msgstr ""
@@ -11183,12 +11307,18 @@ msgstr ""
msgid "DatadogIntegration|Tag all data from this GitLab instance in Datadog. Useful when managing several self-managed deployments."
msgstr ""
+msgid "DatadogIntegration|Tags"
+msgstr ""
+
msgid "DatadogIntegration|The Datadog site to send data to. To send data to the EU site, use %{codeOpen}datadoghq.eu%{codeClose}."
msgstr ""
msgid "DatadogIntegration|Trace your GitLab pipelines with Datadog."
msgstr ""
+msgid "DatadogIntegration|have an invalid format"
+msgstr ""
+
msgid "Datasource name not found"
msgstr ""
@@ -11198,9 +11328,6 @@ msgstr ""
msgid "Date merged"
msgstr ""
-msgid "Date picker"
-msgstr ""
-
msgid "Date range"
msgstr ""
@@ -11354,9 +11481,6 @@ msgstr ""
msgid "Definition"
msgstr ""
-msgid "Delayed Project Deletion (%{adjourned_deletion})"
-msgstr ""
-
msgid "DelayedJobs|Are you sure you want to run %{jobName} immediately? Otherwise this job will run automatically after its timer finishes."
msgstr ""
@@ -11435,10 +11559,10 @@ msgstr ""
msgid "Delete pipeline"
msgstr ""
-msgid "Delete project"
+msgid "Delete pipeline schedule"
msgstr ""
-msgid "Delete project. Are you ABSOLUTELY SURE?"
+msgid "Delete project"
msgstr ""
msgid "Delete row"
@@ -11468,6 +11592,9 @@ msgstr ""
msgid "Delete this epic and all descendants?"
msgstr ""
+msgid "Delete this project"
+msgstr ""
+
msgid "Delete user list"
msgstr ""
@@ -11720,6 +11847,12 @@ msgstr ""
msgid "Deploy to..."
msgstr ""
+msgid "DeployBoards|To see deployment progress for your environments, make sure you are deploying to %{codeStart}$KUBE_NAMESPACE%{codeEnd} and annotating with %{codeStart}app.gitlab.com/app=$CI_PROJECT_PATH_SLUG%{codeEnd} and %{codeStart}app.gitlab.com/env=$CI_ENVIRONMENT_SLUG%{codeEnd}."
+msgstr ""
+
+msgid "DeployBoard|Kubernetes Pods"
+msgstr ""
+
msgid "DeployFreeze|Add a freeze period to prevent unintended releases during a period of time for a given environment. You must update the deployment jobs in %{filename} according to the deploy freezes added here. %{freeze_period_link_start}Learn more.%{freeze_period_link_end}"
msgstr ""
@@ -11804,9 +11937,6 @@ msgstr ""
msgid "DeployTokens|Active Deploy Tokens (%{active_tokens})"
msgstr ""
-msgid "DeployTokens|Allows read and write access to registry images."
-msgstr ""
-
msgid "DeployTokens|Allows read and write access to the package registry."
msgstr ""
@@ -11819,6 +11949,9 @@ msgstr ""
msgid "DeployTokens|Allows read-only access to the repository."
msgstr ""
+msgid "DeployTokens|Allows write access to registry images."
+msgstr ""
+
msgid "DeployTokens|Copy deploy token"
msgstr ""
@@ -11912,12 +12045,57 @@ msgstr ""
msgid "Deploying to AWS is easy with GitLab"
msgstr ""
+msgid "Deployment"
+msgstr ""
+
msgid "Deployment Frequency"
msgstr ""
+msgid "Deployment Target|Project deployment target (optional)"
+msgstr ""
+
+msgid "Deployment Target|Select the deployment target"
+msgstr ""
+
msgid "Deployment frequency"
msgstr ""
+msgid "DeploymentTarget|GitLab Pages"
+msgstr ""
+
+msgid "DeploymentTarget|Heroku"
+msgstr ""
+
+msgid "DeploymentTarget|Infrastructure provider (Terraform, Cloudformation, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Kubernetes (GKE, EKS, OpenShift, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Managed container runtime (Fargate, Cloud Run, DigitalOcean App)"
+msgstr ""
+
+msgid "DeploymentTarget|Mobile app store"
+msgstr ""
+
+msgid "DeploymentTarget|No deployment planned"
+msgstr ""
+
+msgid "DeploymentTarget|Other hosting service"
+msgstr ""
+
+msgid "DeploymentTarget|Registry (package or container)"
+msgstr ""
+
+msgid "DeploymentTarget|Self-managed container runtime (Podman, Docker Swarm, Docker Compose)"
+msgstr ""
+
+msgid "DeploymentTarget|Serverless backend (Lambda, Cloud functions)"
+msgstr ""
+
+msgid "DeploymentTarget|Virtual machine (for example, EC2)"
+msgstr ""
+
msgid "Deployments"
msgstr ""
@@ -11955,6 +12133,9 @@ msgstr ""
msgid "Deployment|This deployment was created using the API"
msgstr ""
+msgid "Deployment|Triggerer"
+msgstr ""
+
msgid "Deployment|Waiting"
msgstr ""
@@ -11982,6 +12163,18 @@ msgstr ""
msgid "Deprecated API rate limits"
msgstr ""
+msgid "Deprecations|Feature deprecation and removal"
+msgstr ""
+
+msgid "Deprecations|For information on a possible replacement %{epicStart} learn more about Opstrace %{epicEnd}."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7 and are %{epicStart} scheduled for removal %{epicEnd} in GitLab 15.0."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7, and are %{removal_link_start} scheduled for removal %{link_end} in GitLab 15.0. For information on a possible replacement, %{opstrace_link_start} learn more about Opstrace %{link_end}."
+msgstr ""
+
msgid "Deprioritize label"
msgstr ""
@@ -12226,10 +12419,10 @@ msgstr ""
msgid "DevopsAdoption|At least one deploy"
msgstr ""
-msgid "DevopsAdoption|At least one issue opened"
+msgid "DevopsAdoption|At least one issue created"
msgstr ""
-msgid "DevopsAdoption|At least one merge request opened"
+msgid "DevopsAdoption|At least one merge request created"
msgstr ""
msgid "DevopsAdoption|At least one pipeline successfully run"
@@ -12427,6 +12620,9 @@ msgstr ""
msgid "Direct member"
msgstr ""
+msgid "Direct members"
+msgstr ""
+
msgid "Direct non-authenticated users to this page."
msgstr ""
@@ -12542,6 +12738,9 @@ msgid "Dismiss %d selected vulnerability as"
msgid_plural "Dismiss %d selected vulnerabilities as"
msgstr[0] ""
+msgid "Dismiss Alert"
+msgstr ""
+
msgid "Dismiss merge request promotion"
msgstr ""
@@ -12569,9 +12768,15 @@ msgstr ""
msgid "Display alerts from all configured monitoring tools."
msgstr ""
+msgid "Display milestones"
+msgstr ""
+
msgid "Display name"
msgstr ""
+msgid "Display progress of child issues"
+msgstr ""
+
msgid "Display rendered file"
msgstr ""
@@ -12677,6 +12882,9 @@ msgstr ""
msgid "Download image"
msgstr ""
+msgid "Download payload"
+msgstr ""
+
msgid "Download raw data (.csv)"
msgstr ""
@@ -12854,6 +13062,9 @@ msgstr ""
msgid "Edit in Web IDE"
msgstr ""
+msgid "Edit in pipeline editor"
+msgstr ""
+
msgid "Edit in single-file editor"
msgstr ""
@@ -12896,6 +13107,9 @@ msgstr ""
msgid "Edit your most recent comment in a thread (from an empty textarea)"
msgstr ""
+msgid "Edit, lint, and visualize your pipeline."
+msgstr ""
+
msgid "Edited"
msgstr ""
@@ -13337,6 +13551,9 @@ msgstr ""
msgid "Enforce two-factor authentication for all user sign-ins."
msgstr ""
+msgid "Enhance security by storing service account keys in secret managers - learn more about %{docLinkStart}secret management with GitLab%{docLinkEnd}"
+msgstr ""
+
msgid "Ensure connectivity is available from the GitLab server to the Prometheus server"
msgstr ""
@@ -13397,6 +13614,9 @@ 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 following to confirm:"
+msgstr ""
+
msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
@@ -13926,9 +14146,6 @@ 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 ""
@@ -14064,6 +14281,9 @@ msgstr ""
msgid "Errors:"
msgstr ""
+msgid "Escalate this incident"
+msgstr ""
+
msgid "Escalation Policies"
msgstr ""
@@ -14076,6 +14296,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy"
+msgstr ""
+
msgid "Escalation policy:"
msgstr ""
@@ -14326,6 +14549,9 @@ msgstr ""
msgid "Existing sign in methods may be removed"
msgstr ""
+msgid "Exit."
+msgstr ""
+
msgid "Expand"
msgstr ""
@@ -14422,6 +14648,9 @@ msgstr ""
msgid "Explore public groups"
msgstr ""
+msgid "Explore public projects"
+msgstr ""
+
msgid "Explore snippets"
msgstr ""
@@ -14582,7 +14811,7 @@ msgid "Failed to archive a design. Please try again."
msgid_plural "Failed to archive designs. Please try again."
msgstr[0] ""
-msgid "Failed to assign a reviewer because no user was found."
+msgid "Failed to assign a reviewer because no user was specified."
msgstr ""
msgid "Failed to assign a user because no user was found."
@@ -14648,10 +14877,10 @@ msgstr ""
msgid "Failed to find import label for Jira import."
msgstr ""
-msgid "Failed to generate export, please try again later."
+msgid "Failed to find users for %{missing}"
msgstr ""
-msgid "Failed to generate report, please try again after sometime"
+msgid "Failed to generate export, please try again later."
msgstr ""
msgid "Failed to get ref."
@@ -14750,6 +14979,9 @@ msgstr ""
msgid "Failed to remove a to-do item for the design."
msgstr ""
+msgid "Failed to remove attention because no user was found."
+msgstr ""
+
msgid "Failed to remove mirror."
msgstr ""
@@ -14762,6 +14994,9 @@ msgstr ""
msgid "Failed to remove user key."
msgstr ""
+msgid "Failed to request attention because no user was found."
+msgstr ""
+
msgid "Failed to reset key. Please try again."
msgstr ""
@@ -14843,6 +15078,9 @@ msgstr ""
msgid "Feature Flags"
msgstr ""
+msgid "Feature deprecation and removal"
+msgstr ""
+
msgid "Feature flag status"
msgstr ""
@@ -15339,7 +15577,7 @@ msgstr ""
msgid "For each job, re-use the project workspace. If the workspace doesn't exist, use %{code_open}git clone%{code_close}."
msgstr ""
-msgid "For example, the application using the token or the purpose of the token."
+msgid "For example, the application using the token or the purpose of the token. Do not give sensitive information for the name of the token, as it will be visible to all %{resource_type} members."
msgstr ""
msgid "For files larger than this limit, only index the file name. The file content is neither indexed nor searchable."
@@ -15423,9 +15661,6 @@ msgstr ""
msgid "ForkProject|Select a namespace"
msgstr ""
-msgid "ForkProject|Select a namespace to fork the project"
-msgstr ""
-
msgid "ForkProject|The project can be accessed by any logged in user."
msgstr ""
@@ -15522,6 +15757,9 @@ msgstr ""
msgid "Full name"
msgstr ""
+msgid "GCP region configured"
+msgstr ""
+
msgid "GPG Key ID:"
msgstr ""
@@ -15702,6 +15940,9 @@ msgstr ""
msgid "Geo|Failed"
msgstr ""
+msgid "Geo|Filter Geo sites"
+msgstr ""
+
msgid "Geo|Filter by name"
msgstr ""
@@ -16113,6 +16354,12 @@ msgstr ""
msgid "GitLab Issue"
msgstr ""
+msgid "GitLab KAS"
+msgstr ""
+
+msgid "GitLab Memberships CSV Export"
+msgstr ""
+
msgid "GitLab Pages"
msgstr ""
@@ -16161,6 +16408,9 @@ 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 free to use. Many features for larger teams are part of our %{link_start}paid products%{link_end}. You can try Ultimate for free without any obligation or payment details."
+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 ""
@@ -16287,7 +16537,7 @@ msgstr ""
msgid "GitLabPages|When enabled, all attempts to visit your website through HTTP are automatically redirected to HTTPS using a response with status code 301. Requires a valid certificate for all domains. %{docs_link_start}Learn more.%{link_end}"
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. %{docs_link_start}Learn more.%{link_end}"
+msgid "GitLabPages|When using Pages under the general domain of a GitLab instance (%{pages_host}), you cannot use HTTPS with subdomains of subdomains. If your namespace or groupname contains a dot, it does not work. This is a limitation of the HTTP Over TLS protocol. HTTP pages work if you don't redirect HTTP to HTTPS. %{docs_link_start}Learn more.%{link_end}"
msgstr ""
msgid "GitLabPages|With GitLab Pages you can host your static website directly from your GitLab repository. %{docs_link_start}Learn more.%{link_end}"
@@ -16464,9 +16714,6 @@ msgstr ""
msgid "Go to find file"
msgstr ""
-msgid "Go to fork"
-msgstr ""
-
msgid "Go to issue boards"
msgstr ""
@@ -16674,9 +16921,6 @@ msgstr ""
msgid "Group Hooks"
msgstr ""
-msgid "Group ID"
-msgstr ""
-
msgid "Group Owner must have signed in with SAML before enabling Group Managed Accounts"
msgstr ""
@@ -16704,9 +16948,6 @@ msgstr ""
msgid "Group by"
msgstr ""
-msgid "Group description"
-msgstr ""
-
msgid "Group description (optional)"
msgstr ""
@@ -16821,7 +17062,7 @@ msgstr ""
msgid "Group: %{name}"
msgstr ""
-msgid "GroupActivityMetrics|Issues opened"
+msgid "GroupActivityMetrics|Issues created"
msgstr ""
msgid "GroupActivityMetrics|Last 90 days"
@@ -16830,7 +17071,7 @@ msgstr ""
msgid "GroupActivityMetrics|Members added"
msgstr ""
-msgid "GroupActivityMetrics|Merge Requests opened"
+msgid "GroupActivityMetrics|Merge Requests created"
msgstr ""
msgid "GroupActivityMetrics|Recent activity"
@@ -17121,6 +17362,9 @@ msgstr ""
msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
+msgid "GroupSettings|Choose a group path that does not start with a dash or end with a period. It can also contain alphanumeric characters and underscores."
+msgstr ""
+
msgid "GroupSettings|Compliance frameworks"
msgstr ""
@@ -17154,7 +17398,7 @@ msgstr ""
msgid "GroupSettings|If not specified at the group or instance level, the default is %{default_initial_branch_name}. Does not affect existing repositories."
msgstr ""
-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."
+msgid "GroupSettings|If the parent group's visibility is lower than the group's current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility."
msgstr ""
msgid "GroupSettings|New runners registration token has been generated!"
@@ -17271,7 +17515,10 @@ msgstr ""
msgid "Groups and projects"
msgstr ""
-msgid "Groups and subgroups"
+msgid "Groups are a great way to organize projects and people."
+msgstr ""
+
+msgid "Groups are the best way to manage projects and members."
msgstr ""
msgid "Groups to synchronize"
@@ -17382,13 +17629,16 @@ msgstr ""
msgid "GroupsTree|Are you sure you want to leave the \"%{fullName}\" group?"
msgstr ""
-msgid "GroupsTree|Edit group"
+msgid "GroupsTree|Delete"
+msgstr ""
+
+msgid "GroupsTree|Edit"
msgstr ""
msgid "GroupsTree|Failed to leave the group. Please make sure you are not the only owner."
msgstr ""
-msgid "GroupsTree|Leave this group"
+msgid "GroupsTree|Leave group"
msgstr ""
msgid "GroupsTree|Loading groups"
@@ -17400,9 +17650,57 @@ msgstr ""
msgid "GroupsTree|No groups or projects matched your search"
msgstr ""
+msgid "GroupsTree|Options"
+msgstr ""
+
msgid "GroupsTree|Search by name"
msgstr ""
+msgid "Groups|Avatar will be removed. Are you sure?"
+msgstr ""
+
+msgid "Groups|Changing group URL can have unintended side effects."
+msgstr ""
+
+msgid "Groups|Checking group URL availability..."
+msgstr ""
+
+msgid "Groups|Enter a descriptive name for your group."
+msgstr ""
+
+msgid "Groups|Group ID"
+msgstr ""
+
+msgid "Groups|Group URL"
+msgstr ""
+
+msgid "Groups|Group avatar"
+msgstr ""
+
+msgid "Groups|Group description (optional)"
+msgstr ""
+
+msgid "Groups|Group name"
+msgstr ""
+
+msgid "Groups|Group path is available."
+msgstr ""
+
+msgid "Groups|Group path is unavailable. Path has been replaced with a suggested available path."
+msgstr ""
+
+msgid "Groups|Learn more"
+msgstr ""
+
+msgid "Groups|Must start with letter, digit, emoji, or underscore. Can also contain periods, dashes, spaces, and parentheses."
+msgstr ""
+
+msgid "Groups|Remove avatar"
+msgstr ""
+
+msgid "Groups|Save changes"
+msgstr ""
+
msgid "Guideline"
msgstr ""
@@ -17412,6 +17710,9 @@ msgstr ""
msgid "HAR file path or URL"
msgstr ""
+msgid "HTTP Archive (HAR)"
+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 ""
@@ -17810,6 +18111,9 @@ msgstr ""
msgid "INFO: Your SSH key is expiring soon. Please generate a new key."
msgstr ""
+msgid "IP"
+msgstr ""
+
msgid "IP Address"
msgstr ""
@@ -17846,6 +18150,9 @@ msgstr ""
msgid "IdentityVerification|Verify your identity"
msgstr ""
+msgid "IdentityVerification|You can always verify your account at a later time to create a group."
+msgstr ""
+
msgid "If any indexed field exceeds this limit, it is truncated to this number of characters. The rest of the content is neither indexed nor searchable. This does not apply to repository and wiki indexing. For unlimited characters, set this to 0."
msgstr ""
@@ -17903,6 +18210,9 @@ msgstr ""
msgid "If you add %{codeStart}needs%{codeEnd} to jobs in your pipeline you'll be able to view the %{codeStart}needs%{codeEnd} relationships between jobs in this tab as a %{linkStart}Directed Acyclic Graph (DAG)%{linkEnd}."
msgstr ""
+msgid "If you are added to a project, it will be displayed here."
+msgstr ""
+
msgid "If you did not initiate these sign-in attempts, please reach out to your administrator or enable two-factor authentication (2FA) on your account."
msgstr ""
@@ -18206,12 +18516,24 @@ msgstr ""
msgid "InProductMarketing|3 ways to dive into GitLab CI/CD"
msgstr ""
+msgid "InProductMarketing|A single application eliminates complex integrations, data chokepoints, and toolchain maintenance, resulting in greater productivity and lower cost."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features, build more efficiently, strengthen security and compliance."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features."
+msgstr ""
+
msgid "InProductMarketing|Actually, GitLab makes the team work (better)"
msgstr ""
msgid "InProductMarketing|And finally %{deploy_link} a Python application."
msgstr ""
+msgid "InProductMarketing|And many more..."
+msgstr ""
+
msgid "InProductMarketing|Are your runners ready?"
msgstr ""
@@ -18230,15 +18552,33 @@ msgstr ""
msgid "InProductMarketing|Blog"
msgstr ""
+msgid "InProductMarketing|Break down silos to coordinate seamlessly across development, operations, and security with a consistent experience across the development lifecycle."
+msgstr ""
+
+msgid "InProductMarketing|Burn up/down charts"
+msgstr ""
+
msgid "InProductMarketing|By enabling code owners and required merge approvals the right person will review the right MR. This is a win-win: cleaner code and a more efficient review process."
msgstr ""
msgid "InProductMarketing|Click on the number below that corresponds with your answer — 1 being very difficult, 5 being very easy."
msgstr ""
+msgid "InProductMarketing|Code owners"
+msgstr ""
+
msgid "InProductMarketing|Code owners and required merge approvals are part of the paid tiers of GitLab. You can start a free 30-day trial of GitLab Ultimate and enable these features in less than 5 minutes with no credit card required."
msgstr ""
+msgid "InProductMarketing|Code review analytics"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration across stages in GitLab"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration made easy"
+msgstr ""
+
msgid "InProductMarketing|Create a custom CI runner with just a few clicks"
msgstr ""
@@ -18248,12 +18588,21 @@ msgstr ""
msgid "InProductMarketing|Create a project in GitLab in 5 minutes"
msgstr ""
+msgid "InProductMarketing|Create well-defined workflows by using scoped labels on issues, merge requests, and epics. Labels with the same scope cannot be used together, which prevents conflicts."
+msgstr ""
+
msgid "InProductMarketing|Create your first project!"
msgstr ""
+msgid "InProductMarketing|Define who owns specific files or directories, so the right reviewers are suggested when a merge request introduces changes to those files."
+msgstr ""
+
msgid "InProductMarketing|Deliver Better Products Faster"
msgstr ""
+msgid "InProductMarketing|Dependency scanning"
+msgstr ""
+
msgid "InProductMarketing|Did you know teams that use GitLab are far more efficient?"
msgstr ""
@@ -18263,15 +18612,27 @@ msgstr ""
msgid "InProductMarketing|Dig in and create a project and a repo"
msgstr ""
+msgid "InProductMarketing|Discover Premium & Ultimate"
+msgstr ""
+
+msgid "InProductMarketing|Discover Premium & Ultimate."
+msgstr ""
+
msgid "InProductMarketing|Do you have a minute?"
msgstr ""
msgid "InProductMarketing|Do you have a teammate who would be perfect for this task?"
msgstr ""
+msgid "InProductMarketing|Dynamic application security testing"
+msgstr ""
+
msgid "InProductMarketing|Easy"
msgstr ""
+msgid "InProductMarketing|Epics"
+msgstr ""
+
msgid "InProductMarketing|Expand your DevOps journey with a free GitLab trial"
msgstr ""
@@ -18293,9 +18654,15 @@ msgstr ""
msgid "InProductMarketing|Feel the need for speed?"
msgstr ""
+msgid "InProductMarketing|Find and fix bottlenecks in your code review process by understanding how long open merge requests have been in review."
+msgstr ""
+
msgid "InProductMarketing|Find out how your teams are really doing"
msgstr ""
+msgid "InProductMarketing|Find out if your external libraries are safe. Run dependency scanning jobs that check for known vulnerabilities in your external libraries."
+msgstr ""
+
msgid "InProductMarketing|Follow our steps"
msgstr ""
@@ -18332,6 +18699,9 @@ msgstr ""
msgid "InProductMarketing|GitLab is better with teammates to help out!"
msgstr ""
+msgid "InProductMarketing|GitLab is infrastructure agnostic (supporting GCP, AWS, Azure, OpenShift, VMWare, On Prem, Bare Metal, and more), offering a consistent workflow experience – irrespective of the environment."
+msgstr ""
+
msgid "InProductMarketing|GitLab provides static application security testing (SAST), dynamic application security testing (DAST), container scanning, and dependency scanning to help you deliver secure applications along with license compliance."
msgstr ""
@@ -18422,21 +18792,36 @@ msgstr ""
msgid "InProductMarketing|It's also possible to simply %{external_repo_link} in order to take advantage of GitLab's CI/CD."
msgstr ""
+msgid "InProductMarketing|Keep your code quality high by defining who should approve merge requests and how many approvals are required."
+msgstr ""
+
msgid "InProductMarketing|Launch GitLab CI/CD in 20 minutes or less"
msgstr ""
+msgid "InProductMarketing|Lower cost of development"
+msgstr ""
+
+msgid "InProductMarketing|Make it easier to collaborate on high-level ideas by grouping related issues in an epic."
+msgstr ""
+
msgid "InProductMarketing|Making the switch? It's easier than you think to import your projects into GitLab. Move %{github_link}, or import something %{bitbucket_link}."
msgstr ""
msgid "InProductMarketing|Master the art of importing!"
msgstr ""
+msgid "InProductMarketing|Merge request approval rule"
+msgstr ""
+
msgid "InProductMarketing|Move on to easily creating a Pages website %{ci_template_link}"
msgstr ""
msgid "InProductMarketing|Multiple owners, confusing workstreams? We've got you covered"
msgstr ""
+msgid "InProductMarketing|Multiple required approvers"
+msgstr ""
+
msgid "InProductMarketing|Need an alternative to importing?"
msgstr ""
@@ -18449,18 +18834,33 @@ msgstr ""
msgid "InProductMarketing|Our tool brings all the things together"
msgstr ""
+msgid "InProductMarketing|Protect your web application by using DAST to examine for vulnerabilities in deployed environments."
+msgstr ""
+
msgid "InProductMarketing|Rapid development, simplified"
msgstr ""
msgid "InProductMarketing|Reduce Security & Compliance Risk"
msgstr ""
+msgid "InProductMarketing|Require multiple approvers on a merge request, so you know it's in good shape before it's merged."
+msgstr ""
+
+msgid "InProductMarketing|Roadmaps"
+msgstr ""
+
+msgid "InProductMarketing|Scoped labels"
+msgstr ""
+
msgid "InProductMarketing|Security that's integrated into your development lifecycle"
msgstr ""
msgid "InProductMarketing|Sometimes you're not ready to make a full transition to a new tool. If you're not ready to fully commit, %{mirroring_link} gives you a safe way to try out GitLab in parallel with your current tool."
msgstr ""
+msgid "InProductMarketing|Speed. Efficiency. Trust."
+msgstr ""
+
msgid "InProductMarketing|Spin up an autoscaling runner in GitLab"
msgstr ""
@@ -18470,6 +18870,9 @@ msgstr ""
msgid "InProductMarketing|Start a Self-Managed trial"
msgstr ""
+msgid "InProductMarketing|Start a free trial"
+msgstr ""
+
msgid "InProductMarketing|Start a free trial of GitLab Ultimate – no credit card required"
msgstr ""
@@ -18536,6 +18939,9 @@ msgstr ""
msgid "InProductMarketing|To understand and get the most out of GitLab, start at the beginning and %{project_link}. In GitLab, repositories are part of a project, so after you've created your project you can go ahead and %{repo_link}."
msgstr ""
+msgid "InProductMarketing|Track completed issues in a chart, so you can see how a milestone is progressing at a glance."
+msgstr ""
+
msgid "InProductMarketing|Try GitLab Ultimate for free"
msgstr ""
@@ -18572,6 +18978,9 @@ msgstr ""
msgid "InProductMarketing|Very easy"
msgstr ""
+msgid "InProductMarketing|Visualize your epics and milestones in a timeline."
+msgstr ""
+
msgid "InProductMarketing|Want to host GitLab on your servers?"
msgstr ""
@@ -18593,6 +19002,9 @@ msgstr ""
msgid "InProductMarketing|YouTube"
msgstr ""
+msgid "InProductMarketing|Your software, deployed your way"
+msgstr ""
+
msgid "InProductMarketing|Your teams can be more efficient"
msgstr ""
@@ -18713,9 +19125,18 @@ msgstr ""
msgid "IncidentManagement|No incidents to display."
msgstr ""
+msgid "IncidentManagement|None"
+msgstr ""
+
msgid "IncidentManagement|Open"
msgstr ""
+msgid "IncidentManagement|Page your team with escalation policies"
+msgstr ""
+
+msgid "IncidentManagement|Paged"
+msgstr ""
+
msgid "IncidentManagement|Published"
msgstr ""
@@ -18725,6 +19146,9 @@ msgstr ""
msgid "IncidentManagement|Severity"
msgstr ""
+msgid "IncidentManagement|Status"
+msgstr ""
+
msgid "IncidentManagement|There are no closed incidents"
msgstr ""
@@ -18743,6 +19167,9 @@ msgstr ""
msgid "IncidentManagement|Unpublished"
msgstr ""
+msgid "IncidentManagement|Use escalation policies to automatically page your team when incidents are created."
+msgstr ""
+
msgid "IncidentSettings|Activate \"time to SLA\" countdown timer"
msgstr ""
@@ -18788,7 +19215,10 @@ msgstr ""
msgid "Incidents"
msgstr ""
-msgid "Incidents|Add a URL"
+msgid "Incidents|Add image details"
+msgstr ""
+
+msgid "Incidents|Add text or a link to display with your image. If you don't add either, the file name displays instead."
msgstr ""
msgid "Incidents|Drop or %{linkStart}upload%{linkEnd} a metric screenshot to attach it to the incident"
@@ -18803,10 +19233,10 @@ msgstr ""
msgid "Incidents|There was an issue loading metric images."
msgstr ""
-msgid "Incidents|There was an issue uploading your image."
+msgid "Incidents|There was an issue updating your image."
msgstr ""
-msgid "Incidents|You can optionally add a URL to link users to the original graph."
+msgid "Incidents|There was an issue uploading your image."
msgstr ""
msgid "Incident|Alert details"
@@ -18815,9 +19245,18 @@ msgstr ""
msgid "Incident|Are you sure you wish to delete this image?"
msgstr ""
+msgid "Incident|Delete image"
+msgstr ""
+
msgid "Incident|Deleting %{filename}"
msgstr ""
+msgid "Incident|Edit image text or link"
+msgstr ""
+
+msgid "Incident|Editing %{filename}"
+msgstr ""
+
msgid "Incident|Metrics"
msgstr ""
@@ -19086,12 +19525,18 @@ msgstr ""
msgid "Integrations|Branches for which notifications are to be sent"
msgstr ""
+msgid "Integrations|Clear if using a self-signed certificate."
+msgstr ""
+
msgid "Integrations|Comment detail:"
msgstr ""
msgid "Integrations|Comment settings:"
msgstr ""
+msgid "Integrations|Connection details"
+msgstr ""
+
msgid "Integrations|Connection failed. Please check your settings."
msgstr ""
@@ -19116,6 +19561,9 @@ msgstr ""
msgid "Integrations|Enable GitLab.com slash commands in a Slack workspace."
msgstr ""
+msgid "Integrations|Enable SSL verification"
+msgstr ""
+
msgid "Integrations|Enable comments"
msgstr ""
@@ -19194,6 +19642,9 @@ msgstr ""
msgid "Integrations|Return to GitLab for Jira"
msgstr ""
+msgid "Integrations|SSL verification"
+msgstr ""
+
msgid "Integrations|Save settings?"
msgstr ""
@@ -19239,9 +19690,6 @@ msgstr ""
msgid "Integrations|Use default settings"
msgstr ""
-msgid "Integrations|When you mention a Jira issue in a commit or merge request, GitLab creates a remote link and comment (if enabled)."
-msgstr ""
-
msgid "Integrations|You can now close this window and return to the GitLab for Jira application."
msgstr ""
@@ -19266,9 +19714,6 @@ msgstr ""
msgid "Integrations|can't exceed %{recipients_limit}"
msgstr ""
-msgid "Interactive developer security education."
-msgstr ""
-
msgid "Interactive mode"
msgstr ""
@@ -19758,6 +20203,9 @@ msgstr ""
msgid "IssueAnalytics|Assignees"
msgstr ""
+msgid "IssueAnalytics|Created by"
+msgstr ""
+
msgid "IssueAnalytics|Due date"
msgstr ""
@@ -19770,9 +20218,6 @@ msgstr ""
msgid "IssueAnalytics|Milestone"
msgstr ""
-msgid "IssueAnalytics|Opened by"
-msgstr ""
-
msgid "IssueAnalytics|Status"
msgstr ""
@@ -19896,10 +20341,10 @@ msgstr ""
msgid "IssuesAnalytics|Avg/Month:"
msgstr ""
-msgid "IssuesAnalytics|Issues opened"
+msgid "IssuesAnalytics|Issues created"
msgstr ""
-msgid "IssuesAnalytics|Issues opened per month"
+msgid "IssuesAnalytics|Issues created per month"
msgstr ""
msgid "IssuesAnalytics|Last 12 months"
@@ -19926,6 +20371,9 @@ msgstr ""
msgid "It looks like you have some draft commits in this branch."
msgstr ""
+msgid "It looks like you're attempting to activate your subscription. Use %{a_start}the Subscription page%{a_end} instead."
+msgstr ""
+
msgid "It may be several days before you see feature usage data."
msgstr ""
@@ -20154,6 +20602,9 @@ msgstr ""
msgid "JiraConnect|You can now close this window and return to Jira."
msgstr ""
+msgid "JiraConnect|You don't have permission to create branches for this project. Select a different project or contact the project owner for access. %{linkStart}Learn more.%{linkEnd}"
+msgstr ""
+
msgid "JiraRequest|A connection error occurred while connecting to Jira. Try your request again."
msgstr ""
@@ -20202,13 +20653,13 @@ msgstr ""
msgid "JiraService|Define the type of Jira issue to create from a vulnerability."
msgstr ""
-msgid "JiraService|Displaying Jira issues while leaving the GitLab issue functionality enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
+msgid "JiraService|Displaying Jira issues while leaving GitLab issues also enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
msgstr ""
-msgid "JiraService|Enable Jira issues"
+msgid "JiraService|Enable Jira issue creation from vulnerabilities"
msgstr ""
-msgid "JiraService|Enable Jira issues creation from vulnerabilities"
+msgid "JiraService|Enable Jira issues"
msgstr ""
msgid "JiraService|Enable Jira transitions"
@@ -20325,16 +20776,19 @@ msgstr ""
msgid "JiraService|View Jira issues in GitLab"
msgstr ""
-msgid "JiraService|Warning: All GitLab users that have access to this GitLab project are able to view all issues from the Jira project specified below."
+msgid "JiraService|Warning: All GitLab users with access to this GitLab project can view all issues from the Jira project you select."
msgstr ""
msgid "JiraService|Web URL"
msgstr ""
-msgid "JiraService|Work on Jira issues without leaving GitLab. Adds a Jira menu to access your list of Jira issues and view any issue as read-only."
+msgid "JiraService|When a Jira issue is mentioned in a commit or merge request, a remote link and comment (if enabled) will be created."
+msgstr ""
+
+msgid "JiraService|Work on Jira issues without leaving GitLab. Add a Jira menu to access a read-only list of your Jira issues."
msgstr ""
-msgid "JiraService|You need to configure Jira before enabling this integration. For more details, read the %{jira_doc_link_start}Jira integration documentation%{link_end}."
+msgid "JiraService|You must configure Jira before enabling this integration. %{jira_doc_link_start}Learn more.%{link_end}"
msgstr ""
msgid "Job"
@@ -20346,9 +20800,6 @@ msgstr ""
msgid "Job Failed #%{build_id}"
msgstr ""
-msgid "Job ID"
-msgstr ""
-
msgid "Job artifact"
msgstr ""
@@ -20415,9 +20866,27 @@ msgstr ""
msgid "Jobs|You're about to retry a job that failed because it attempted to deploy code that is older than the latest deployment. Retrying this job could result in overwriting the environment with the older source code."
msgstr ""
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source} into %{target}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{ref}"
+msgstr ""
+
+msgid "Job|Are you sure you want to erase this job log and artifacts?"
+msgstr ""
+
msgid "Job|Browse"
msgstr ""
+msgid "Job|Cancel"
+msgstr ""
+
msgid "Job|Complete Raw"
msgstr ""
@@ -20427,6 +20896,9 @@ msgstr ""
msgid "Job|Erase job log and artifacts"
msgstr ""
+msgid "Job|Finished at"
+msgstr ""
+
msgid "Job|Job artifacts"
msgstr ""
@@ -20439,7 +20911,7 @@ msgstr ""
msgid "Job|Keep"
msgstr ""
-msgid "Job|Pipeline"
+msgid "Job|Retry"
msgstr ""
msgid "Job|Scroll to bottom"
@@ -20451,6 +20923,9 @@ msgstr ""
msgid "Job|Show complete raw"
msgstr ""
+msgid "Job|Status"
+msgstr ""
+
msgid "Job|The artifacts were removed"
msgstr ""
@@ -20478,21 +20953,12 @@ msgstr ""
msgid "Job|delayed"
msgstr ""
-msgid "Job|for"
-msgstr ""
-
-msgid "Job|into"
-msgstr ""
-
msgid "Job|manual"
msgstr ""
msgid "Job|triggered"
msgstr ""
-msgid "Job|with"
-msgstr ""
-
msgid "Join Zoom meeting"
msgstr ""
@@ -20595,9 +21061,6 @@ msgstr ""
msgid "Ki"
msgstr ""
-msgid "Kontra"
-msgstr ""
-
msgid "Kroki"
msgstr ""
@@ -20920,6 +21383,9 @@ msgstr ""
msgid "Learn more about Auto DevOps"
msgstr ""
+msgid "Learn more about GitLab"
+msgstr ""
+
msgid "Learn more about Needs relationships"
msgstr ""
@@ -21241,9 +21707,18 @@ msgstr ""
msgid "Licenses|Displays licenses detected in the project, based on the %{linkStart}latest successful%{linkEnd} scan"
msgstr ""
+msgid "Licenses|Drag your license file here or %{linkStart}click to upload%{linkEnd}."
+msgstr ""
+
+msgid "Licenses|Drop your license file to start the upload."
+msgstr ""
+
msgid "Licenses|Error fetching the license list. Please check your network connection and try again."
msgstr ""
+msgid "Licenses|Error: You are trying to upload something other than a file"
+msgstr ""
+
msgid "Licenses|License Compliance"
msgstr ""
@@ -21262,6 +21737,9 @@ msgstr ""
msgid "Licenses|Specified policies in this project"
msgstr ""
+msgid "Licenses|The file could not be uploaded."
+msgstr ""
+
msgid "Licenses|The license list details information about the licenses used within your project."
msgstr ""
@@ -21295,10 +21773,6 @@ msgstr ""
msgid "Limit the size of Sidekiq jobs stored in Redis."
msgstr ""
-msgid "Limited to showing %d event at most"
-msgid_plural "Limited to showing %d events at most"
-msgstr[0] ""
-
msgid "Limiting mode"
msgstr ""
@@ -21308,6 +21782,9 @@ msgstr ""
msgid "Link"
msgstr ""
+msgid "Link (optional)"
+msgstr ""
+
msgid "Link Prometheus monitoring to GitLab."
msgstr ""
@@ -21344,6 +21821,9 @@ msgstr ""
msgid "Linked emails (%{email_count})"
msgstr ""
+msgid "Linked epics"
+msgstr ""
+
msgid "Linked issues"
msgstr ""
@@ -21371,6 +21851,15 @@ msgstr ""
msgid "List of all merge commits"
msgstr ""
+msgid "List of environments for this project"
+msgstr ""
+
+msgid "List of suitable GCP locations"
+msgstr ""
+
+msgid "List of users allowed to exceed the rate limit."
+msgstr ""
+
msgid "List options"
msgstr ""
@@ -21590,6 +22079,9 @@ msgstr ""
msgid "Maintenance mode"
msgstr ""
+msgid "Make adjustments to how your GitLab instance is set up."
+msgstr ""
+
msgid "Make and review changes in the browser with the Web IDE"
msgstr ""
@@ -21734,6 +22226,12 @@ msgstr ""
msgid "MarkdownEditor|Add italic text (%{modifier_key}I)"
msgstr ""
+msgid "MarkdownEditor|Add strikethrough text (%{modifierKey}⇧X)"
+msgstr ""
+
+msgid "MarkdownEditor|Add strikethrough text (%{modifier_key}⇧X)"
+msgstr ""
+
msgid "Marked For Deletion At - %{deletion_time}"
msgstr ""
@@ -21995,6 +22493,9 @@ msgstr ""
msgid "Maximum push size (MB)"
msgstr ""
+msgid "Maximum requests per 10 minutes per user"
+msgstr ""
+
msgid "Maximum requests per minute"
msgstr ""
@@ -22085,6 +22586,17 @@ msgstr ""
msgid "Members of a group may only view projects they have permission to access"
msgstr ""
+msgid "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seat in use and will be billed for the overage."
+msgid_plural "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seats in use and will be billed for the overage."
+msgstr[0] ""
+
+msgid "MembersOverage|You are about to incur additional charges"
+msgstr ""
+
+msgid "MembersOverage|Your subscription includes %d seat."
+msgid_plural "MembersOverage|Your subscription includes %d seats."
+msgstr[0] ""
+
msgid "Membership"
msgstr ""
@@ -22289,9 +22801,6 @@ msgstr ""
msgid "Merge request not merged"
msgstr ""
-msgid "Merge request pipelines 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 merge request pipelines."
-msgstr ""
-
msgid "Merge request reports"
msgstr ""
@@ -22388,13 +22897,13 @@ msgstr ""
msgid "MergeRequests|Create issue to resolve thread"
msgstr ""
-msgid "MergeRequests|Failed to squash. Should be done manually."
+msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Saving the comment failed"
+msgid "MergeRequests|Squashing failed: Squash the commits locally, resolve any conflicts, then push the branch."
msgstr ""
-msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
+msgid "MergeRequests|Squashing not allowed: This project doesn't allow you to squash commits when merging."
msgstr ""
msgid "MergeRequests|Thread stays resolved"
@@ -23233,6 +23742,18 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "MrList|Assigned to %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from assignee %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from reviewer %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Review requested from %{name}, go to their profile."
+msgstr ""
+
msgid "Multi-project"
msgstr ""
@@ -23266,7 +23787,7 @@ msgstr ""
msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "My Awesome Group"
+msgid "My awesome group"
msgstr ""
msgid "My company or team"
@@ -23886,9 +24407,6 @@ msgstr ""
msgid "No available branches"
msgstr ""
-msgid "No available groups to fork the project."
-msgstr ""
-
msgid "No branches found"
msgstr ""
@@ -24099,6 +24617,9 @@ msgstr ""
msgid "No ref selected"
msgstr ""
+msgid "No regions configured"
+msgstr ""
+
msgid "No related merge requests found."
msgstr ""
@@ -24897,6 +25418,9 @@ msgstr ""
msgid "Only reCAPTCHA v2 is supported:"
msgstr ""
+msgid "Only required if not using role instance credentials."
+msgstr ""
+
msgid "Only use lowercase letters, numbers, and underscores."
msgstr ""
@@ -24921,9 +25445,6 @@ msgstr ""
msgid "Open a CLI and connect to the cluster you want to install the agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
-msgid "Open epics"
-msgstr ""
-
msgid "Open errors"
msgstr ""
@@ -24963,7 +25484,7 @@ msgstr ""
msgid "Opened issues"
msgstr ""
-msgid "OpenedNDaysAgo|Opened"
+msgid "OpenedNDaysAgo|Created"
msgstr ""
msgid "Opens in a new window"
@@ -25008,9 +25529,6 @@ msgstr ""
msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
-msgid "Optional."
-msgstr ""
-
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
msgstr ""
@@ -25798,6 +26316,9 @@ msgstr ""
msgid "PerformanceBar|Memory"
msgstr ""
+msgid "PerformanceBar|Memory report"
+msgstr ""
+
msgid "PerformanceBar|Redis calls"
msgstr ""
@@ -25831,18 +26352,12 @@ msgstr ""
msgid "PerformanceBar|wall"
msgstr ""
-msgid "Performs a rebase but skips triggering a new pipeline"
-msgstr ""
-
msgid "Period in seconds"
msgstr ""
msgid "Permalink"
msgstr ""
-msgid "Permanently delete project"
-msgstr ""
-
msgid "Permanently remove group"
msgstr ""
@@ -26113,6 +26628,51 @@ msgstr ""
msgid "PipelineStatusTooltip|Pipeline: %{ci_status}"
msgstr ""
+msgid "PipelineWizardDefaultCommitMessage|Add %{filename}"
+msgstr ""
+
+msgid "PipelineWizardDefaultCommitMessage|Update %{filename}"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|At least one entry is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This field is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This value is not valid"
+msgstr ""
+
+msgid "PipelineWizardListWidget|add another step"
+msgstr ""
+
+msgid "PipelineWizardListWidget|remove step"
+msgstr ""
+
+msgid "PipelineWizard|Commit"
+msgstr ""
+
+msgid "PipelineWizard|Commit Message"
+msgstr ""
+
+msgid "PipelineWizard|Commit changes to your file"
+msgstr ""
+
+msgid "PipelineWizard|Commit file to Branch"
+msgstr ""
+
+msgid "PipelineWizard|Commit your new file"
+msgstr ""
+
+msgid "PipelineWizard|The file has been committed."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem committing the changes."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem while checking whether your file already exists in the specified branch."
+msgstr ""
+
msgid "Pipelines"
msgstr ""
@@ -26227,7 +26787,7 @@ msgstr ""
msgid "Pipelines|Project cache successfully reset."
msgstr ""
-msgid "Pipelines|Revoke"
+msgid "Pipelines|Revoke trigger"
msgstr ""
msgid "Pipelines|Something went wrong while cleaning runners cache."
@@ -26272,6 +26832,12 @@ msgstr ""
msgid "Pipelines|This is a child pipeline within the parent pipeline"
msgstr ""
+msgid "Pipelines|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipelines|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipelines|This pipeline will run code originating from a forked project merge request. This means that the code can potentially have security considerations like exposing CI variables."
msgstr ""
@@ -26314,9 +26880,6 @@ msgstr ""
msgid "Pipelines|Your changes have been successfully committed. Now redirecting to the new merge request page."
msgstr ""
-msgid "Pipelines|detached"
-msgstr ""
-
msgid "Pipelines|error"
msgstr ""
@@ -26326,10 +26889,13 @@ msgstr ""
msgid "Pipelines|latest"
msgstr ""
-msgid "Pipelines|stuck"
+msgid "Pipelines|merge request"
msgstr ""
-msgid "Pipelines|train"
+msgid "Pipelines|merge train"
+msgstr ""
+
+msgid "Pipelines|stuck"
msgstr ""
msgid "Pipelines|yaml invalid"
@@ -26461,6 +27027,12 @@ msgstr ""
msgid "Pipeline|This change will not change the overall test coverage if merged."
msgstr ""
+msgid "Pipeline|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipeline|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipeline|Trigger author"
msgstr ""
@@ -26485,6 +27057,12 @@ msgstr ""
msgid "Pipeline|for"
msgstr ""
+msgid "Pipeline|merge request"
+msgstr ""
+
+msgid "Pipeline|merge train"
+msgstr ""
+
msgid "Pipeline|on"
msgstr ""
@@ -26623,9 +27201,6 @@ msgstr ""
msgid "Please enter a valid time interval"
msgstr ""
-msgid "Please enter or upload a valid license."
-msgstr ""
-
msgid "Please enter your current password."
msgstr ""
@@ -26734,9 +27309,6 @@ msgstr ""
msgid "Please type %{phrase_code} to proceed or close this modal to cancel."
msgstr ""
-msgid "Please type the following to confirm:"
-msgstr ""
-
msgid "Please use this form to report to the admin users who create spam issues, comments or behave inappropriately."
msgstr ""
@@ -26764,12 +27336,27 @@ msgstr ""
msgid "Policies"
msgstr ""
+msgid "Policy '%{escalation_policy_name}' does not exist."
+msgstr ""
+
msgid "Policy management project does have any policies in %{policy_path}"
msgstr ""
msgid "Policy project doesn't exist"
msgstr ""
+msgid "PolicyRuleMultiSelect|%{firstLabel} +%{numberOfAdditionalLabels} more"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|All %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select all"
+msgstr ""
+
msgid "Polling interval multiplier"
msgstr ""
@@ -26998,6 +27585,9 @@ msgstr ""
msgid "Private projects can be created in your personal namespace with:"
msgstr ""
+msgid "Problem with %{name} command: %{message}."
+msgstr ""
+
msgid "Proceed"
msgstr ""
@@ -27472,6 +28062,9 @@ msgstr ""
msgid "Progress"
msgstr ""
+msgid "Progress tracking"
+msgstr ""
+
msgid "Project"
msgstr ""
@@ -27703,6 +28296,9 @@ msgstr ""
msgid "ProjectQualitySummary|Failure"
msgstr ""
+msgid "ProjectQualitySummary|Get insight into the overall percentage of tests in your project that succeed, fail and are skipped."
+msgstr ""
+
msgid "ProjectQualitySummary|Latest pipeline results"
msgstr ""
@@ -27721,6 +28317,12 @@ msgstr ""
msgid "ProjectQualitySummary|See project Code Coverage Statistics"
msgstr ""
+msgid "ProjectQualitySummary|Set up test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|Set up test runs (opens in a new tab)"
+msgstr ""
+
msgid "ProjectQualitySummary|Skipped"
msgstr ""
@@ -27997,13 +28599,19 @@ msgstr ""
msgid "ProjectSettings|LFS objects from this repository are available to forks. %{linkStart}How do I remove them?%{linkEnd}"
msgstr ""
+msgid "ProjectSettings|Learn about commit history."
+msgstr ""
+
+msgid "ProjectSettings|Leave empty to use default template."
+msgstr ""
+
msgid "ProjectSettings|Manage who can see the project in the public access directory."
msgstr ""
msgid "ProjectSettings|Manages large files such as audio, video, and graphics files."
msgstr ""
-msgid "ProjectSettings|Maximum 500 characters."
+msgid "ProjectSettings|Maximum %{maxLength} characters."
msgstr ""
msgid "ProjectSettings|Merge checks"
@@ -28144,6 +28752,9 @@ msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
msgstr ""
+msgid "ProjectSettings|The default template will be applied on save."
+msgstr ""
+
msgid "ProjectSettings|These checks must pass before merge requests can be merged."
msgstr ""
@@ -28198,6 +28809,9 @@ msgstr ""
msgid "ProjectSettings|What are badges?"
msgstr ""
+msgid "ProjectSettings|What are merge trains?"
+msgstr ""
+
msgid "ProjectSettings|When merge request pipelines are enabled in the CI/CD configuration file, pipelines validate the combined results of the source and target branches. %{link_start}How to configure merge request pipelines?%{link_end}"
msgstr ""
@@ -28315,6 +28929,9 @@ msgstr ""
msgid "Projects are organized into groups"
msgstr ""
+msgid "Projects are where you store your code, access issues, wiki and other features of GitLab."
+msgstr ""
+
msgid "Projects contributed to"
msgstr ""
@@ -28330,12 +28947,6 @@ msgstr ""
msgid "Projects to index"
msgstr ""
-msgid "Projects will be permanently deleted after a %{waiting_period}-day waiting period."
-msgstr ""
-
-msgid "Projects will be permanently deleted immediately."
-msgstr ""
-
msgid "Projects with critical vulnerabilities"
msgstr ""
@@ -28420,6 +29031,9 @@ msgstr ""
msgid "ProjectsNew|Import project"
msgstr ""
+msgid "ProjectsNew|Include a Getting Started README"
+msgstr ""
+
msgid "ProjectsNew|Initialize repository with a README"
msgstr ""
@@ -28435,6 +29049,9 @@ msgstr ""
msgid "ProjectsNew|Project description %{tag_start}(optional)%{tag_end}"
msgstr ""
+msgid "ProjectsNew|Recommended if you're new to GitLab"
+msgstr ""
+
msgid "ProjectsNew|Run CI/CD for external repository"
msgstr ""
@@ -28852,6 +29469,9 @@ msgstr ""
msgid "ProtectedBranch|Unprotect"
msgstr ""
+msgid "ProtectedBranch|Unprotect branch"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
@@ -28879,6 +29499,9 @@ msgstr ""
msgid "ProtectedEnvironment|Protected Environment (%{protected_environments_count})"
msgstr ""
+msgid "ProtectedEnvironment|Required approvals"
+msgstr ""
+
msgid "ProtectedEnvironment|Select an environment"
msgstr ""
@@ -28900,10 +29523,13 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|Unprotect tag"
+msgstr ""
+
msgid "ProtectedTags|default"
msgstr ""
-msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
+msgid "ProtectedTag|By default, protected tags restrict who can modify the tag."
msgstr ""
msgid "ProtectedTag|Learn more."
@@ -28966,6 +29592,9 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Public projects are an easy way to allow everyone to have read-only access."
+msgstr ""
+
msgid "Publish to status page"
msgstr ""
@@ -29122,9 +29751,6 @@ msgstr ""
msgid "QualitySummary|Project quality"
msgstr ""
-msgid "Quarters"
-msgstr ""
-
msgid "Query"
msgstr ""
@@ -29209,6 +29835,9 @@ msgstr ""
msgid "Read more about project permissions %{help_link_open}here%{help_link_close}"
msgstr ""
+msgid "Read more about related epics"
+msgstr ""
+
msgid "Read more about related issues"
msgstr ""
@@ -29239,10 +29868,7 @@ msgstr ""
msgid "Rebase source branch on the target branch."
msgstr ""
-msgid "Rebase without CI"
-msgstr ""
-
-msgid "Rebases and triggers a pipeline"
+msgid "Rebase without pipeline"
msgstr ""
msgid "Recaptcha verified?"
@@ -29293,9 +29919,6 @@ msgstr ""
msgid "Reconfigure"
msgstr ""
-msgid "Recovering projects"
-msgstr ""
-
msgid "Recovery Codes"
msgstr ""
@@ -29354,6 +29977,12 @@ msgstr ""
msgid "Regex pattern"
msgstr ""
+msgid "Region"
+msgstr ""
+
+msgid "Regions"
+msgstr ""
+
msgid "Register"
msgstr ""
@@ -29583,9 +30212,6 @@ msgstr ""
msgid "Remove all or specific reviewer(s)"
msgstr ""
-msgid "Remove approver"
-msgstr ""
-
msgid "Remove approvers"
msgstr ""
@@ -29601,6 +30227,9 @@ msgstr ""
msgid "Remove attention request"
msgstr ""
+msgid "Remove attention request(s)"
+msgstr ""
+
msgid "Remove avatar"
msgstr ""
@@ -29739,6 +30368,9 @@ msgstr ""
msgid "Removed an issue from an epic."
msgstr ""
+msgid "Removed attention from %{users_sentence}."
+msgstr ""
+
msgid "Removed attention request from @%{username}"
msgstr ""
@@ -29790,6 +30422,9 @@ msgstr ""
msgid "Removes an issue from an epic."
msgstr ""
+msgid "Removes attention from %{users_sentence}."
+msgstr ""
+
msgid "Removes parent epic %{epic_ref}."
msgstr ""
@@ -29901,6 +30536,9 @@ msgstr ""
msgid "Report abuse to admin"
msgstr ""
+msgid "Report is generating and will be sent to your email address."
+msgstr ""
+
msgid "Reported %{timeAgo} by %{reportedBy}"
msgstr ""
@@ -30185,6 +30823,15 @@ msgstr ""
msgid "Request attention"
msgstr ""
+msgid "Request attention from %{users_sentence}."
+msgstr ""
+
+msgid "Request attention from assignee or reviewer"
+msgstr ""
+
+msgid "Request attention from assignee(s) or reviewer(s)"
+msgstr ""
+
msgid "Request attention to review"
msgstr ""
@@ -30209,6 +30856,9 @@ msgstr ""
msgid "Requested %{time_ago}"
msgstr ""
+msgid "Requested attention from %{users_sentence}."
+msgstr ""
+
msgid "Requested attention from @%{username}"
msgstr ""
@@ -30421,6 +31071,9 @@ msgstr ""
msgid "Restore project"
msgstr ""
+msgid "Restoring projects"
+msgstr ""
+
msgid "Restoring the group will prevent the group, its subgroups and projects from being removed on this date."
msgstr ""
@@ -30451,6 +31104,9 @@ msgstr ""
msgid "Retry"
msgstr ""
+msgid "Retry failed jobs"
+msgstr ""
+
msgid "Retry job"
msgstr ""
@@ -30497,9 +31153,6 @@ msgstr ""
msgid "Review changes"
msgstr ""
-msgid "Review requested from %{name}"
-msgstr ""
-
msgid "Review requests for you"
msgstr ""
@@ -30663,6 +31316,9 @@ msgstr ""
msgid "Runners|Assigned Group"
msgstr ""
+msgid "Runners|Assigned Projects (%{projectCount})"
+msgstr ""
+
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30732,6 +31388,9 @@ msgstr ""
msgid "Runners|Instance"
msgstr ""
+msgid "Runners|Jobs"
+msgstr ""
+
msgid "Runners|Last contact"
msgstr ""
@@ -30825,9 +31484,6 @@ msgstr ""
msgid "Runners|Runner %{name} was deleted"
msgstr ""
-msgid "Runners|Runner ID"
-msgstr ""
-
msgid "Runners|Runner assigned to project."
msgstr ""
@@ -30975,6 +31631,9 @@ msgstr ""
msgid "Runners|stale"
msgstr ""
+msgid "Runner|This runner has not run any jobs."
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -31089,6 +31748,24 @@ msgstr ""
msgid "Saving project."
msgstr ""
+msgid "ScanResultPolicy|%{ifLabelStart}if%{ifLabelEnd} %{scanners} scan in an open merge request targeting the %{branches} branch(es) finds %{vulnerabilitiesAllowed} or more %{severities} vulnerabilities that are %{vulnerabilityStates}"
+msgstr ""
+
+msgid "ScanResultPolicy|%{thenLabelStart}Then%{thenLabelEnd} Require approval from %{approvalsRequired} of the following approvers: %{approvers}"
+msgstr ""
+
+msgid "ScanResultPolicy|add an approver"
+msgstr ""
+
+msgid "ScanResultPolicy|scanners"
+msgstr ""
+
+msgid "ScanResultPolicy|severity levels"
+msgstr ""
+
+msgid "ScanResultPolicy|vulnerability states"
+msgstr ""
+
msgid "Scanner"
msgstr ""
@@ -31221,6 +31898,9 @@ msgstr ""
msgid "Search for a user"
msgstr ""
+msgid "Search for an emoji"
+msgstr ""
+
msgid "Search for projects, issues, etc."
msgstr ""
@@ -31397,18 +32077,12 @@ msgstr ""
msgid "Secret Detection"
msgstr ""
-msgid "Secret access key"
-msgstr ""
-
msgid "Secret token"
msgstr ""
msgid "Secure token that identifies an external storage request."
msgstr ""
-msgid "SecureCodeWarrior"
-msgstr ""
-
msgid "Security"
msgstr ""
@@ -31433,9 +32107,6 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "Security training with guide and learning pathways."
-msgstr ""
-
msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
@@ -31538,7 +32209,7 @@ msgstr ""
msgid "SecurityConfiguration|Manage corpus"
msgstr ""
-msgid "SecurityConfiguration|Manage corpus files used as mutation sources in coverage fuzzing."
+msgid "SecurityConfiguration|Manage corpus files used as seed inputs with coverage-guided fuzzing."
msgstr ""
msgid "SecurityConfiguration|Manage profiles for use by DAST scans."
@@ -31604,15 +32275,15 @@ msgstr ""
msgid "SecurityOrchestration|.yaml preview"
msgstr ""
-msgid "SecurityOrchestration|Action"
-msgstr ""
-
msgid "SecurityOrchestration|Actions"
msgstr ""
msgid "SecurityOrchestration|Add rule"
msgstr ""
+msgid "SecurityOrchestration|After dismissing the alert, the information will never be shown again."
+msgstr ""
+
msgid "SecurityOrchestration|All policies"
msgstr ""
@@ -31628,7 +32299,7 @@ msgstr ""
msgid "SecurityOrchestration|Description"
msgstr ""
-msgid "SecurityOrchestration|Disabled"
+msgid "SecurityOrchestration|Don't show the alert anymore"
msgstr ""
msgid "SecurityOrchestration|Edit policy"
@@ -31637,13 +32308,13 @@ msgstr ""
msgid "SecurityOrchestration|Edit policy project"
msgstr ""
-msgid "SecurityOrchestration|Enabled"
+msgid "SecurityOrchestration|Empty policy name"
msgstr ""
-msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Enabled"
msgstr ""
-msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
msgstr ""
msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
@@ -31652,7 +32323,7 @@ msgstr ""
msgid "SecurityOrchestration|Invalid policy type"
msgstr ""
-msgid "SecurityOrchestration|Latest scan"
+msgid "SecurityOrchestration|Latest scan run against %{agent}"
msgstr ""
msgid "SecurityOrchestration|Network"
@@ -31661,15 +32332,27 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No actions defined - policy will not run."
+msgstr ""
+
+msgid "SecurityOrchestration|No description"
+msgstr ""
+
msgid "SecurityOrchestration|No rules defined - policy will not run."
msgstr ""
+msgid "SecurityOrchestration|Not enabled"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
msgid "SecurityOrchestration|Policies"
msgstr ""
+msgid "SecurityOrchestration|Policy Type"
+msgstr ""
+
msgid "SecurityOrchestration|Policy cannot be enabled for non-existing branches (%{branches})"
msgstr ""
@@ -31694,10 +32377,13 @@ msgstr ""
msgid "SecurityOrchestration|Require %{approvals} %{plural} from %{approvers} if any of the following occur:"
msgstr ""
-msgid "SecurityOrchestration|Rule"
+msgid "SecurityOrchestration|Rules"
msgstr ""
-msgid "SecurityOrchestration|Rules"
+msgid "SecurityOrchestration|Runs %{actions} and %{lastAction} scans"
+msgstr ""
+
+msgid "SecurityOrchestration|Runs a %{action} scan"
msgstr ""
msgid "SecurityOrchestration|Scan Execution"
@@ -31757,6 +32443,9 @@ msgstr ""
msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
+msgid "SecurityOrchestration|This view only shows scan results for the agent %{agent}. You can view scan results for all agents in the %{linkStart}Operational Vulnerabilities tab of the vulnerability report%{linkEnd}."
+msgstr ""
+
msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
@@ -31811,9 +32500,6 @@ msgstr ""
msgid "SecurityOrchestration|users with ids"
msgstr ""
-msgid "SecurityOrchestration|view results"
-msgstr ""
-
msgid "SecurityOrchestration|vulnerabilities"
msgstr ""
@@ -32483,22 +33169,19 @@ 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|In order to start using functions as a service, you must first install Knative on your Kubernetes cluster. %{linkStart}More information%{linkEnd}"
-msgstr ""
-
msgid "Serverless|Learn more about Serverless"
msgstr ""
msgid "Serverless|No functions available"
msgstr ""
-msgid "Serverless|Sign up for First Look"
+msgid "Serverless|Serverless was %{linkStart}deprecated%{linkEnd} in GitLab 14.3."
+msgstr ""
+
+msgid "Serverless|Serverless was %{postLinkStart}deprecated%{postLinkEnd}. But if you opt to use it, you must install Knative in your Kubernetes cluster first. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "Serverless|The deploy job has not finished."
@@ -32510,9 +33193,6 @@ 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 ""
@@ -32528,9 +33208,6 @@ msgstr ""
msgid "Service Account Key"
msgstr ""
-msgid "Service Accounts"
-msgstr ""
-
msgid "Service Accounts keys authorize GitLab to deploy your Google Cloud project"
msgstr ""
@@ -32540,10 +33217,10 @@ msgstr ""
msgid "Service Desk allows people to create issues in your GitLab instance without their own user account. It provides a unique email address for end users to create issues in a project. Replies can be sent either through the GitLab interface or by email. End users only see threads through email."
msgstr ""
-msgid "Service Usage Data"
+msgid "Service account generated successfully"
msgstr ""
-msgid "Service account generated successfully"
+msgid "Service accounts"
msgstr ""
msgid "Service ping is disabled in your configuration file, and cannot be enabled through this form."
@@ -32687,6 +33364,9 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
+msgid "Set the per-user rate limit for getting a user by ID via the API."
+msgstr ""
+
msgid "Set the per-user rate limit for notes created by web or API requests."
msgstr ""
@@ -32865,6 +33545,9 @@ msgstr ""
msgid "Shared runners details"
msgstr ""
+msgid "Shared runners enabled cannot be enabled until a valid credit card is on file"
+msgstr ""
+
msgid "Shared runners help link"
msgstr ""
@@ -32922,6 +33605,9 @@ msgstr ""
msgid "Show all issues."
msgstr ""
+msgid "Show all milestones"
+msgstr ""
+
msgid "Show all test cases."
msgstr ""
@@ -32958,6 +33644,9 @@ msgstr ""
msgid "Show file contents"
msgstr ""
+msgid "Show group milestones"
+msgstr ""
+
msgid "Show labels"
msgstr ""
@@ -32973,6 +33662,12 @@ msgstr ""
msgid "Show open epics"
msgstr ""
+msgid "Show project milestones"
+msgstr ""
+
+msgid "Show sub-group milestones"
+msgstr ""
+
msgid "Show the Closed list"
msgstr ""
@@ -32982,10 +33677,6 @@ msgstr ""
msgid "Show whitespace changes"
msgstr ""
-msgid "Showing %d event"
-msgid_plural "Showing %d events"
-msgstr[0] ""
-
msgid "Showing %{conflict} between %{sourceBranch} and %{targetBranch}"
msgstr ""
@@ -33044,12 +33735,6 @@ msgstr ""
msgid "Sidebar|None"
msgstr ""
-msgid "Sidebar|Only numeral characters allowed"
-msgstr ""
-
-msgid "Sidebar|Weight"
-msgstr ""
-
msgid "Sidekiq job compression threshold (bytes)"
msgstr ""
@@ -33212,6 +33897,9 @@ msgstr ""
msgid "Slack logo"
msgstr ""
+msgid "SlackIntegration|Are you sure you want to remove this project from the Slack application?"
+msgstr ""
+
msgid "SlackIntegration|GitLab for Slack"
msgstr ""
@@ -33221,6 +33909,9 @@ msgstr ""
msgid "SlackIntegration|Project alias"
msgstr ""
+msgid "SlackIntegration|Remove project"
+msgstr ""
+
msgid "SlackIntegration|Select a GitLab project to link with your Slack workspace."
msgstr ""
@@ -33365,9 +34056,6 @@ msgstr ""
msgid "Something went wrong trying to load issue contacts."
msgstr ""
-msgid "Something went wrong when creating a work item. Please try again"
-msgstr ""
-
msgid "Something went wrong when reordering designs. Please try again"
msgstr ""
@@ -33461,9 +34149,6 @@ msgstr ""
msgid "Something went wrong while inserting your image. Please try again."
msgstr ""
-msgid "Something went wrong while merging this merge request. Please try again."
-msgstr ""
-
msgid "Something went wrong while obtaining the Let's Encrypt certificate."
msgstr ""
@@ -33785,10 +34470,10 @@ 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."
+msgid "SourcegraphAdmin|Learn more."
msgstr ""
-msgid "SourcegraphAdmin|More information"
+msgid "SourcegraphAdmin|Only public projects have code intelligence enabled and communicate with Sourcegraph."
msgstr ""
msgid "SourcegraphAdmin|Save changes"
@@ -33797,7 +34482,7 @@ msgstr ""
msgid "SourcegraphAdmin|Sourcegraph URL"
msgstr ""
-msgid "SourcegraphAdmin|e.g. https://sourcegraph.example.com"
+msgid "SourcegraphAdmin|https://sourcegraph.example.com"
msgstr ""
msgid "SourcegraphPreferences|This feature is experimental and currently limited to certain projects."
@@ -33932,6 +34617,9 @@ msgstr ""
msgid "Start date"
msgstr ""
+msgid "Start free trial"
+msgstr ""
+
msgid "Start merge train"
msgstr ""
@@ -33962,6 +34650,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started escalation for this incident."
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -33974,6 +34665,9 @@ msgstr ""
msgid "Starts at (UTC)"
msgstr ""
+msgid "Starts escalations for this incident"
+msgstr ""
+
msgid "Starts on"
msgstr ""
@@ -34235,6 +34929,9 @@ msgstr ""
msgid "Strikethrough"
msgstr ""
+msgid "Strikethrough text"
+msgstr ""
+
msgid "Subgroup information"
msgstr ""
@@ -34469,6 +35166,21 @@ msgstr ""
msgid "Subscriptions"
msgstr ""
+msgid "Subscriptions|Chat with sales"
+msgstr ""
+
+msgid "Subscriptions|Close"
+msgstr ""
+
+msgid "Subscriptions|Not ready to buy yet?"
+msgstr ""
+
+msgid "Subscriptions|Start a free trial"
+msgstr ""
+
+msgid "Subscriptions|We understand. Maybe you have some questions for our sales team, or maybe you'd like to try some of the paid features first. What would you like to do?"
+msgstr ""
+
msgid "Subscription|Your subscription for %{strong}%{namespace_name}%{strong_close} has expired and you are now on %{pricing_link_start}the GitLab Free tier%{pricing_link_end}. Don't worry, your data is safe. Get in touch with our support team (%{support_email}). They'll gladly help with your subscription renewal."
msgstr ""
@@ -34679,6 +35391,9 @@ msgstr ""
msgid "SuperSonics|Maximum users"
msgstr ""
+msgid "SuperSonics|Offline cloud"
+msgstr ""
+
msgid "SuperSonics|Paste your activation code"
msgstr ""
@@ -34745,6 +35460,12 @@ msgstr ""
msgid "SuperSonics|You do not have an active subscription"
msgstr ""
+msgid "SuperSonics|You have a future dated license"
+msgstr ""
+
+msgid "SuperSonics|You have added a license that activates on %{date}. Please see the subscription history table below for more details."
+msgstr ""
+
msgid "SuperSonics|You have successfully added a license that activates on %{date}. Please see the subscription history table below for more details."
msgstr ""
@@ -34904,6 +35625,9 @@ msgstr ""
msgid "Tag name is required"
msgstr ""
+msgid "Tag push"
+msgstr ""
+
msgid "Tag push events"
msgstr ""
@@ -35006,6 +35730,9 @@ msgstr ""
msgid "TagsPage|protected"
msgstr ""
+msgid "Take a look at the documentation to discover all of GitLab’s capabilities."
+msgstr ""
+
msgid "Target Branch"
msgstr ""
@@ -35402,6 +36129,9 @@ msgstr ""
msgid "Tests"
msgstr ""
+msgid "Text (optional)"
+msgstr ""
+
msgid "Text added to the body of all email messages. %{character_limit} character limit"
msgstr ""
@@ -35451,6 +36181,9 @@ msgstr ""
msgid "The CSV export will be created in the background. Once finished, it will be sent to %{email} in an attachment."
msgstr ""
+msgid "The CSV export you requested of all user memberships is attached to this email."
+msgstr ""
+
msgid "The GitLab subscription service (customers.gitlab.com) is currently experiencing an outage. You can monitor the status and get updates at %{linkStart}status.gitlab.com%{linkEnd}."
msgstr ""
@@ -35526,6 +36259,9 @@ 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 epic"
+msgstr ""
+
msgid "The current issue"
msgstr ""
@@ -35686,6 +36422,9 @@ msgstr ""
msgid "The latest pipeline for this merge request has failed."
msgstr ""
+msgid "The license key is invalid."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -35701,6 +36440,9 @@ msgstr ""
msgid "The license was successfully uploaded and will be active from %{starts_at}. You can see the details below."
msgstr ""
+msgid "The license you uploaded is invalid. If the issue persists, contact support at %{link}."
+msgstr ""
+
msgid "The list creation wizard is already open"
msgstr ""
@@ -36322,10 +37064,13 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} and everything this project contains. %{strongOpen}There is no going back%{strongClose}"
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}on %{date}%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains."
+msgstr ""
+
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains. %{strongOpen}There is no going back.%{strongClose}"
msgstr ""
msgid "This action will %{strongOpen}permanently remove%{strongClose} %{codeOpen}%{group}%{codeClose} %{strongOpen}immediately%{strongClose}."
@@ -36454,9 +37199,6 @@ msgstr ""
msgid "This file was modified for readability, and can't accept suggestions. Edit it directly."
msgstr ""
-msgid "This forked project has the following:"
-msgstr ""
-
msgid "This form is disabled in preview"
msgstr ""
@@ -36469,7 +37211,7 @@ msgstr ""
msgid "This group can't be removed because it is linked to a subscription. To remove this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
-msgid "This group can't be transfered because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
+msgid "This group can't be transferred because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
msgid "This group cannot be invited to a project inside a group with enforced SSO"
@@ -36496,6 +37238,9 @@ 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 incident is already escalated with '%{escalation_policy_name}'."
+msgstr ""
+
msgid "This invitation was sent to %{mail_to_invite_email}, but you are signed in as %{link_to_current_user} with email %{mail_to_current_user}."
msgstr ""
@@ -36514,9 +37259,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 merge train pipeline"
-msgstr ""
-
msgid "This is a private email address %{helpIcon} generated just for you. Anyone who has it can create issues or merge requests as if they were you. If that happens, %{resetLinkStart}reset this token%{resetLinkEnd}."
msgstr ""
@@ -36538,6 +37280,12 @@ msgstr ""
msgid "This is your current session"
msgstr ""
+msgid "This issue cannot be assigned to a confidential epic because it is public."
+msgstr ""
+
+msgid "This issue cannot be made public because it belongs to a confidential epic."
+msgstr ""
+
msgid "This issue is confidential and should only be visible to team members with at least Reporter access."
msgstr ""
@@ -36655,6 +37403,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 branch is protected from force push."
+msgstr ""
+
msgid "This merge request cannot be rebased while there are conflicts."
msgstr ""
@@ -36706,9 +37457,15 @@ msgstr ""
msgid "This pipeline was triggered by a schedule."
msgstr ""
+msgid "This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project"
msgstr ""
+msgid "This project can be restored until %{date}."
+msgstr ""
+
msgid "This project cannot be %{visibilityLevel} because the visibility of %{openShowLink}%{name}%{closeShowLink} is %{visibility}. To make this project %{visibilityLevel}, you must first %{openEditLink}change the visibility%{closeEditLink} of the parent group."
msgstr ""
@@ -36727,6 +37484,9 @@ msgstr ""
msgid "This project is %{strongStart}NOT%{strongEnd} a fork, and has the following:"
msgstr ""
+msgid "This project is %{strongStart}NOT%{strongEnd} a fork. This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -37416,6 +38176,9 @@ msgstr ""
msgid "Today"
msgstr ""
+msgid "Todos count"
+msgstr ""
+
msgid "Todos|Are you looking for things to do? Take a look at %{strongStart}%{openIssuesLinkStart}open issues%{openIssuesLinkEnd}%{strongEnd}, contribute to %{strongStart}%{mergeRequestLinkStart}a merge request%{mergeRequestLinkEnd}%{mergeRequestLinkEnd}%{strongEnd}, or mention someone in a comment to automatically assign them a new to-do item."
msgstr ""
@@ -37689,9 +38452,8 @@ msgstr ""
msgid "Trending"
msgstr ""
-msgid "Trials|%{planName} Trial %{enDash} %{num} day left"
-msgid_plural "Trials|%{planName} Trial %{enDash} %{num} days left"
-msgstr[0] ""
+msgid "Trials|%{planName} Trial"
+msgstr ""
msgid "Trials|Compare all plans"
msgstr ""
@@ -37699,6 +38461,9 @@ msgstr ""
msgid "Trials|Create a new group to start your GitLab Ultimate trial."
msgstr ""
+msgid "Trials|Day %{daysUsed}/%{duration}"
+msgstr ""
+
msgid "Trials|Go back to GitLab"
msgstr ""
@@ -37948,7 +38713,7 @@ msgstr ""
msgid "URL is triggered when repository is updated"
msgstr ""
-msgid "URL must be percent-encoded if neccessary."
+msgid "URL must be percent-encoded if necessary."
msgstr ""
msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
@@ -38167,6 +38932,9 @@ msgstr ""
msgid "Unlock account"
msgstr ""
+msgid "Unlock more features with GitLab Ultimate"
+msgstr ""
+
msgid "Unlock the discussion"
msgstr ""
@@ -38230,6 +38998,9 @@ msgstr ""
msgid "Unsubscribes from this %{quick_action_target}."
msgstr ""
+msgid "Unsupported sort value."
+msgstr ""
+
msgid "Unsupported todo type passed. Supported todo types are: %{todo_types}"
msgstr ""
@@ -38458,6 +39229,9 @@ msgstr ""
msgid "UsageQuota|File attachments and smaller design graphics."
msgstr ""
+msgid "UsageQuota|From %{storage_enforcement_date} storage limits will apply to this namespace. View and manage your usage in %{strong_start}Group Settings &gt; Usage quotas%{strong_end}."
+msgstr ""
+
msgid "UsageQuota|Git repository."
msgstr ""
@@ -38518,6 +39292,9 @@ msgstr ""
msgid "UsageQuota|Storage type"
msgstr ""
+msgid "UsageQuota|Storage used"
+msgstr ""
+
msgid "UsageQuota|This is the total amount of storage used across your projects within this namespace."
msgstr ""
@@ -38713,6 +39490,12 @@ msgstr ""
msgid "Use hashed storage paths for newly created and renamed repositories. Always enabled since 13.0."
msgstr ""
+msgid "Use issue count"
+msgstr ""
+
+msgid "Use issue weight"
+msgstr ""
+
msgid "Use one line per URI"
msgstr ""
@@ -39094,6 +39877,9 @@ msgstr ""
msgid "Users"
msgstr ""
+msgid "Users API rate limit"
+msgstr ""
+
msgid "Users can launch a development environment from a GitLab browser tab when the %{linkStart}Gitpod%{linkEnd} integration is enabled."
msgstr ""
@@ -39417,6 +40203,9 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View group pipeline usage quota"
+msgstr ""
+
msgid "View incident details at"
msgstr ""
@@ -39568,6 +40357,9 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
+msgid "Vulnerability"
+msgstr ""
+
msgid "Vulnerability Report"
msgstr ""
@@ -39619,6 +40411,9 @@ msgstr ""
msgid "VulnerabilityManagement|An unverified non-confirmed finding"
msgstr ""
+msgid "VulnerabilityManagement|At least one identifier is required"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -39628,12 +40423,24 @@ msgstr ""
msgid "VulnerabilityManagement|Create Jira issue"
msgstr ""
+msgid "VulnerabilityManagement|Enter a name"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE code"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE identifier URL"
+msgstr ""
+
msgid "VulnerabilityManagement|Fetching linked Jira issues"
msgstr ""
msgid "VulnerabilityManagement|Manually add a vulnerability entry into the vulnerability report."
msgstr ""
+msgid "VulnerabilityManagement|Name is a required field"
+msgstr ""
+
msgid "VulnerabilityManagement|Needs triage"
msgstr ""
@@ -39649,6 +40456,18 @@ msgstr ""
msgid "VulnerabilityManagement|Select a method"
msgstr ""
+msgid "VulnerabilityManagement|Select a severity level"
+msgstr ""
+
+msgid "VulnerabilityManagement|Select a status"
+msgstr ""
+
+msgid "VulnerabilityManagement|Severity is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Something went wrong while creating vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -39673,6 +40492,12 @@ msgstr ""
msgid "VulnerabilityManagement|Something went wrong, could not update vulnerability state."
msgstr ""
+msgid "VulnerabilityManagement|Status is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Submit vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Summary, detailed description, steps to reproduce, etc."
msgstr ""
@@ -39868,6 +40693,9 @@ msgstr ""
msgid "WARNING:"
msgstr ""
+msgid "WARNING: This snippet contains hidden files which might be used to mask malicious behavior. Exercise caution if cloning and executing code from this snippet."
+msgstr ""
+
msgid "Wait for the file to load to copy its contents"
msgstr ""
@@ -40087,6 +40915,15 @@ msgstr ""
msgid "Webhooks|An issue is created, updated, closed, or reopened."
msgstr ""
+msgid "Webhooks|Are you sure you want to delete this group hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this project hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this webhook?"
+msgstr ""
+
msgid "Webhooks|Comments"
msgstr ""
@@ -40096,6 +40933,9 @@ msgstr ""
msgid "Webhooks|Confidential issues events"
msgstr ""
+msgid "Webhooks|Delete webhook"
+msgstr ""
+
msgid "Webhooks|Deployment events"
msgstr ""
@@ -40328,6 +41168,9 @@ msgstr ""
msgid "Wiki"
msgstr ""
+msgid "Wiki page"
+msgstr ""
+
msgid "Wiki page was successfully created."
msgstr ""
@@ -40433,7 +41276,7 @@ msgstr ""
msgid "WikiPageConflictMessage|Someone edited the page the same time you did. Please check out %{wikiLinkStart}the page%{wikiLinkEnd} and make sure your changes will not unintentionally remove theirs."
msgstr ""
-msgid "WikiPage|An error occured while trying to render the content editor. Please try again later."
+msgid "WikiPage|An error occurred while trying to render the content editor. Please try again later."
msgstr ""
msgid "WikiPage|Are you sure you want to switch back to the classic editor?"
@@ -40592,6 +41435,18 @@ msgstr ""
msgid "WorkItem|New Task"
msgstr ""
+msgid "WorkItem|Something went wrong when creating a work item. Please try again"
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching the work item. Please try again."
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching work item types. Please try again"
+msgstr ""
+
+msgid "WorkItem|Type"
+msgstr ""
+
msgid "WorkItem|Work Items"
msgstr ""
@@ -40658,7 +41513,10 @@ msgstr ""
msgid "You are about to add %{usersTag} people to the discussion. They will all receive a notification."
msgstr ""
-msgid "You are about to permanently delete this project"
+msgid "You are about to delete this forked project containing:"
+msgstr ""
+
+msgid "You are about to delete this project containing:"
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."
@@ -40679,6 +41537,9 @@ msgstr ""
msgid "You are attempting to update a file that has changed since you started editing it."
msgstr ""
+msgid "You are billed if you exceed this number. %{qsrOverageLinkStart}How does billing work?%{qsrOverageLinkEnd}"
+msgstr ""
+
msgid "You are connected to the Prometheus server, but there is currently no data to display."
msgstr ""
@@ -40736,6 +41597,9 @@ msgstr ""
msgid "You are not authorized to update this scanner profile"
msgstr ""
+msgid "You are not authorized to upload metric images"
+msgstr ""
+
msgid "You are now impersonating %{username}"
msgstr ""
@@ -40889,9 +41753,6 @@ msgstr ""
msgid "You can only upload one design when dropping onto an existing design."
msgstr ""
-msgid "You can recover this project until %{date}"
-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 ""
@@ -40940,9 +41801,6 @@ msgstr ""
msgid "You cannot write to this read-only GitLab instance."
msgstr ""
-msgid "You can’t %{tag_start}edit%{tag_end} files directly in this project. Fork this project and submit a merge request with your changes."
-msgstr ""
-
msgid "You can’t edit files directly in this project. Fork this project and submit a merge request with your changes."
msgstr ""
@@ -41094,9 +41952,6 @@ 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 set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
@@ -41127,12 +41982,6 @@ msgstr ""
msgid "You must have maintainer access to force delete a lock"
msgstr ""
-msgid "You must have permission to create a project in a group before forking."
-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 ""
@@ -41538,7 +42387,7 @@ msgstr ""
msgid "Your public email will be displayed on your public profile."
msgstr ""
-msgid "Your request for access could not be processed: %{error_meesage}"
+msgid "Your request for access could not be processed: %{error_message}"
msgstr ""
msgid "Your request for access has been queued for review."
@@ -41718,6 +42567,9 @@ msgstr ""
msgid "archived:"
msgstr ""
+msgid "artifacts"
+msgstr ""
+
msgid "assign yourself"
msgstr ""
@@ -41746,6 +42598,9 @@ msgstr[0] ""
msgid "branch name"
msgstr ""
+msgid "builds"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -42166,6 +43021,9 @@ msgstr ""
msgid "contact with same email already exists in group hierarchy"
msgstr ""
+msgid "container registry images"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -42205,6 +43063,9 @@ msgstr ""
msgid "data"
msgstr ""
+msgid "database"
+msgstr ""
+
msgid "date must not be after 9999-12-31"
msgstr ""
@@ -42227,9 +43088,6 @@ msgstr ""
msgid "design"
msgstr ""
-msgid "detached"
-msgstr ""
-
msgid "disabled"
msgstr ""
@@ -42474,7 +43332,7 @@ msgstr ""
msgid "is not a valid X509 certificate."
msgstr ""
-msgid "is not allowed for sign-up."
+msgid "is not allowed for sign-up. Please use your regular email address."
msgstr ""
msgid "is not allowed for this group."
@@ -42486,7 +43344,7 @@ msgstr ""
msgid "is not allowed since the group is not top-level group."
msgstr ""
-msgid "is not allowed."
+msgid "is not allowed. Please use your regular email address."
msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
@@ -42573,6 +43431,9 @@ msgstr ""
msgid "level: %{level}"
msgstr ""
+msgid "lfs objects"
+msgstr ""
+
msgid "limit of %{project_limit} reached"
msgstr ""
@@ -42789,6 +43650,9 @@ msgstr ""
msgid "mrWidget|Merge blocked: pipeline must succeed. It's waiting for a manual action to continue."
msgstr ""
+msgid "mrWidget|Merge blocked: pipeline must succeed. Push a commit that fixes the failure, or %{linkStart}learn about other solutions.%{linkEnd}"
+msgstr ""
+
msgid "mrWidget|Merge blocked: this merge request must be approved."
msgstr ""
@@ -42906,9 +43770,6 @@ msgstr ""
msgid "mrWidget|The changes were not merged into"
msgstr ""
-msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -43056,9 +43917,6 @@ msgstr ""
msgid "open issue"
msgstr ""
-msgid "opened %{timeAgo}"
-msgstr ""
-
msgid "or"
msgstr ""
@@ -43069,6 +43927,12 @@ msgid "out of %d total test"
msgid_plural "out of %d total tests"
msgstr[0] ""
+msgid "packages"
+msgstr ""
+
+msgid "pages"
+msgstr ""
+
msgid "parent"
msgid_plural "parents"
msgstr[0] ""
@@ -43214,6 +44078,9 @@ msgid "reply"
msgid_plural "replies"
msgstr[0] ""
+msgid "repositories"
+msgstr ""
+
msgid "repository:"
msgstr ""
@@ -43334,12 +44201,18 @@ msgstr ""
msgid "tag name"
msgstr ""
+msgid "terraform states"
+msgstr ""
+
msgid "the correct format."
msgstr ""
msgid "the file"
msgstr ""
+msgid "the following epic(s)"
+msgstr ""
+
msgid "the following issue(s)"
msgstr ""
@@ -43352,21 +44225,12 @@ msgstr ""
msgid "this document"
msgstr ""
-msgid "this issue cannot be assigned to a confidential epic since it is public"
-msgstr ""
-
-msgid "this issue cannot be made public since it belongs to a confidential epic"
-msgstr ""
-
msgid "time summary"
msgstr ""
msgid "toggle collapse"
msgstr ""
-msgid "train"
-msgstr ""
-
msgid "triggered"
msgstr ""
@@ -43494,3 +44358,6 @@ msgstr ""
msgid "{project}"
msgstr ""
+msgid "✔"
+msgstr ""
+
diff --git a/locale/bg/gitlab.po b/locale/bg/gitlab.po
index f746f965631..bd00e57f63f 100644
--- a/locale/bg/gitlab.po
+++ b/locale/bg/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: bg\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2022-02-02 15:44\n"
+"PO-Revision-Date: 2022-03-01 20:38\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -146,6 +146,11 @@ msgid_plural "%d approvers (you've approved)"
msgstr[0] ""
msgstr[1] ""
+msgid "%d assigned issue"
+msgid_plural "%d assigned issues"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -421,8 +426,23 @@ msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
msgstr[1] ""
-msgid "%d vulnerability updated"
-msgid_plural "%d vulnerabilities updated"
+msgid "%d vulnerability set to confirmed"
+msgid_plural "%d vulnerabilities set to confirmed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to dismissed"
+msgid_plural "%d vulnerabilities set to dismissed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to needs triage"
+msgid_plural "%d vulnerabilities set to needs triage"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to resolved"
+msgid_plural "%d vulnerabilities set to resolved"
msgstr[0] ""
msgstr[1] ""
@@ -510,6 +530,12 @@ msgstr[1] ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{completed} of %{total} issues closed"
+msgstr ""
+
+msgid "%{completed} of %{total} weight completed"
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -858,6 +884,9 @@ msgstr ""
msgid "%{openedIssues} open, %{closedIssues} closed"
msgstr ""
+msgid "%{percentage}%% issues closed"
+msgstr ""
+
msgid "%{percentage}%% weight completed"
msgstr ""
@@ -1287,6 +1316,9 @@ msgid_plural "- Users"
msgstr[0] ""
msgstr[1] ""
+msgid "- of - issues closed"
+msgstr ""
+
msgid "- of - weight completed"
msgstr ""
@@ -1429,7 +1461,7 @@ msgstr ""
msgid "1000+"
msgstr ""
-msgid "192.168.0.0/24"
+msgid "192.168.0.0/24 or 2001:0DB8:1234::/48"
msgstr ""
msgid "1st contribution!"
@@ -1741,13 +1773,13 @@ msgstr ""
msgid "AWS Access Key"
msgstr ""
-msgid "AWS Access Key. Only required if not using role instance credentials"
+msgid "AWS Secret Access Key"
msgstr ""
-msgid "AWS Secret Access Key"
+msgid "AWS access key ID (Optional)"
msgstr ""
-msgid "AWS Secret Access Key. Only required if not using role instance credentials"
+msgid "AWS secret access key (Optional)"
msgstr ""
msgid "AWS service error: %{error}"
@@ -1807,9 +1839,6 @@ msgstr ""
msgid "Access granted"
msgstr ""
-msgid "Access key ID"
-msgstr ""
-
msgid "Access requests"
msgstr ""
@@ -1984,7 +2013,7 @@ msgstr ""
msgid "Activity"
msgstr "ДейноÑÑ‚"
-msgid "Activity|An error occured while retrieving activity. Reload the page to try again."
+msgid "Activity|An error occurred while retrieving activity. Reload the page to try again."
msgstr ""
msgid "Add"
@@ -2023,6 +2052,9 @@ msgstr ""
msgid "Add a %{type}"
msgstr ""
+msgid "Add a GCP region"
+msgstr ""
+
msgid "Add a GPG key"
msgstr ""
@@ -2074,6 +2106,9 @@ msgstr ""
msgid "Add a numbered list"
msgstr ""
+msgid "Add a related epic"
+msgstr ""
+
msgid "Add a related issue"
msgstr ""
@@ -2188,6 +2223,9 @@ msgstr ""
msgid "Add or subtract spent time"
msgstr ""
+msgid "Add people"
+msgstr ""
+
msgid "Add previously merged commits"
msgstr ""
@@ -2254,6 +2292,9 @@ msgstr ""
msgid "Add webhook"
msgstr ""
+msgid "Add your team members and others to GitLab."
+msgstr ""
+
msgid "Add/remove"
msgstr ""
@@ -3076,12 +3117,6 @@ msgstr ""
msgid "AdvancedSearch|Reindex required"
msgstr ""
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. Permanently deleting this project will %{strongStart}immediately delete%{strongEnd} its repositories and %{strongStart}all related resources%{strongEnd}, including issues, merge requests etc."
-msgstr ""
-
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. You will lose this project's repository and %{strongStart}all related resources%{strongEnd}, including issues and merge requests."
-msgstr ""
-
msgid "After a successful password update you will be redirected to login screen."
msgstr ""
@@ -3112,6 +3147,9 @@ msgstr ""
msgid "Akismet helps prevent the creation of spam issues in public projects."
msgstr ""
+msgid "Alert"
+msgstr ""
+
msgid "AlertManagement|Acknowledged"
msgstr ""
@@ -3484,9 +3522,6 @@ msgstr ""
msgid "All environments"
msgstr ""
-msgid "All epics"
-msgstr ""
-
msgid "All groups and projects"
msgstr ""
@@ -4223,12 +4258,15 @@ msgstr ""
msgid "ApplicationSettings|Approve users in the pending approval status?"
msgstr ""
-msgid "ApplicationSettings|By making this change, you will automatically approve %d user with the pending approval status."
-msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users with the pending approval status."
+msgid "ApplicationSettings|Approve users who are pending approval?"
+msgstr ""
+
+msgid "ApplicationSettings|By making this change, you will automatically approve %d user who is pending approval."
+msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users who are pending approval."
msgstr[0] ""
msgstr[1] ""
-msgid "ApplicationSettings|By making this change, you will automatically approve all users in pending approval status."
+msgid "ApplicationSettings|By making this change, you will automatically approve all users who are pending approval."
msgstr ""
msgid "ApplicationSettings|Denied domains for sign-ups"
@@ -4634,10 +4672,10 @@ msgstr ""
msgid "Archiving the project will make it entirely read-only. It is hidden from the dashboard and doesn't show up in searches. %{strong_start}The repository cannot be committed to, and no issues, comments, or other entities can be created.%{strong_end} %{link_start}Learn more.%{link_end}"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to delete this project?"
+msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
+msgid "Are you absolutely sure?"
msgstr ""
msgid "Are you sure that you want to archive this project?"
@@ -4673,12 +4711,18 @@ msgstr ""
msgid "Are you sure you want to delete this SSH key?"
msgstr ""
+msgid "Are you sure you want to delete this comment?"
+msgstr ""
+
msgid "Are you sure you want to delete this deploy key?"
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 label?"
+msgstr ""
+
msgid "Are you sure you want to delete this pipeline schedule?"
msgstr "ÐаиÑтина ли иÑкате да изтриете този план за Ñхема?"
@@ -4694,9 +4738,6 @@ msgstr ""
msgid "Are you sure you want to discard your changes?"
msgstr ""
-msgid "Are you sure you want to erase this build?"
-msgstr ""
-
msgid "Are you sure you want to import %d repository?"
msgid_plural "Are you sure you want to import %d repositories?"
msgstr[0] ""
@@ -4744,6 +4785,9 @@ msgstr ""
msgid "Are you sure you want to remove this list?"
msgstr ""
+msgid "Are you sure you want to remove this nickname?"
+msgstr ""
+
msgid "Are you sure you want to reset the health check token?"
msgstr ""
@@ -4756,10 +4800,10 @@ 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?"
+msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
msgstr ""
-msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
+msgid "Are you sure you want to revoke this project access token? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to stop this environment?"
@@ -4906,9 +4950,6 @@ msgstr ""
msgid "Assigned to %{assignee_name}"
msgstr ""
-msgid "Assigned to %{name}"
-msgstr ""
-
msgid "Assigned to me"
msgstr ""
@@ -4973,6 +5014,9 @@ msgstr[1] ""
msgid "Attaching the file failed."
msgstr ""
+msgid "Attention"
+msgstr ""
+
msgid "Audit Events"
msgstr ""
@@ -5135,6 +5179,12 @@ msgstr ""
msgid "Authorized applications (%{size})"
msgstr ""
+msgid "AuthorizedApplication|Are you sure you want to revoke this application?"
+msgstr ""
+
+msgid "AuthorizedApplication|Revoke application"
+msgstr ""
+
msgid "Authors: %{authors}"
msgstr ""
@@ -6328,6 +6378,9 @@ msgstr ""
msgid "CICDAnalytics|Shared Runners Usage"
msgstr ""
+msgid "CICDAnalytics|Shared runner pipeline minute duration by month"
+msgstr ""
+
msgid "CICDAnalytics|Shared runner usage"
msgstr ""
@@ -6469,6 +6522,9 @@ msgstr ""
msgid "Can create groups:"
msgstr ""
+msgid "Can not delete primary training"
+msgstr ""
+
msgid "Can't apply as the source branch was deleted."
msgstr ""
@@ -6802,9 +6858,6 @@ msgstr ""
msgid "Changing any setting here requires an application restart"
msgstr ""
-msgid "Changing group URL can have unintended side effects."
-msgstr ""
-
msgid "Charts can't be displayed as the request for data has timed out. %{documentationLink}"
msgstr ""
@@ -6892,9 +6945,6 @@ msgstr ""
msgid "Checking branch availability..."
msgstr ""
-msgid "Checking group URL availability..."
-msgstr ""
-
msgid "Checking group path availability..."
msgstr ""
@@ -7388,6 +7438,9 @@ msgstr ""
msgid "Clear recent searches"
msgstr ""
+msgid "Clear repository checks"
+msgstr ""
+
msgid "Clear search"
msgstr ""
@@ -7520,9 +7573,6 @@ msgstr ""
msgid "Closed MRs"
msgstr ""
-msgid "Closed epics"
-msgstr ""
-
msgid "Closed issues"
msgstr ""
@@ -7559,13 +7609,13 @@ msgstr ""
msgid "Cluster level"
msgstr ""
-msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
+msgid "Cluster type must be specified for Stages::ClusterEndpointInserter"
msgstr ""
msgid "ClusterAgents|%{name} successfully deleted"
msgstr ""
-msgid "ClusterAgents|%{number} of %{total} Agents"
+msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
@@ -7607,6 +7657,15 @@ msgstr ""
msgid "ClusterAgents|Agent never connected to GitLab"
msgstr ""
+msgid "ClusterAgents|Agent version mismatch"
+msgstr ""
+
+msgid "ClusterAgents|Agent version mismatch and update"
+msgstr ""
+
+msgid "ClusterAgents|Agent version update required"
+msgstr ""
+
msgid "ClusterAgents|All"
msgstr ""
@@ -7631,7 +7690,7 @@ msgstr ""
msgid "ClusterAgents|Configuration"
msgstr ""
-msgid "ClusterAgents|Connect a cluster through the Agent"
+msgid "ClusterAgents|Connect a cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connect existing cluster"
@@ -7640,13 +7699,13 @@ msgstr ""
msgid "ClusterAgents|Connect with a certificate"
msgstr ""
-msgid "ClusterAgents|Connect with agent"
+msgid "ClusterAgents|Connect with an agent"
msgstr ""
msgid "ClusterAgents|Connect with the GitLab Agent"
msgstr ""
-msgid "ClusterAgents|Connect your cluster through the Agent"
+msgid "ClusterAgents|Connect your cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connected"
@@ -7706,7 +7765,10 @@ msgstr ""
msgid "ClusterAgents|How to register an agent?"
msgstr ""
-msgid "ClusterAgents|Install new Agent"
+msgid "ClusterAgents|How to update an agent?"
+msgstr ""
+
+msgid "ClusterAgents|Install a new agent"
msgstr ""
msgid "ClusterAgents|Last connected %{timeAgo}."
@@ -7733,7 +7795,7 @@ msgstr ""
msgid "ClusterAgents|Never connected"
msgstr ""
-msgid "ClusterAgents|No Agents"
+msgid "ClusterAgents|No agents"
msgstr ""
msgid "ClusterAgents|No clusters connected through cluster certificates"
@@ -7793,6 +7855,9 @@ msgstr ""
msgid "ClusterAgents|The agent has not been connected in a long time. There might be a connectivity issue. Last contact was %{timeAgo}."
msgstr ""
+msgid "ClusterAgents|The agent version do not match each other across your cluster's pods. This can happen when a new agent version was just deployed and Kubernetes is shutting down the old pods."
+msgstr ""
+
msgid "ClusterAgents|The recommended installation method includes the token. If you want to follow the advanced installation method provided in the docs, make sure you save the token value before you close this window."
msgstr ""
@@ -7840,6 +7905,9 @@ msgstr ""
msgid "ClusterAgents|You will need to create a token to connect to your agent"
msgstr ""
+msgid "ClusterAgents|Your agent version is out of sync with your GitLab version (v%{version}), which might cause compatibility problems. Update the agent installed on your cluster to the most recent version."
+msgstr ""
+
msgid "ClusterAgents|Your instance doesn't have the %{linkStart}GitLab Agent Server (KAS)%{linkEnd} set up. Ask a GitLab Administrator to install it."
msgstr ""
@@ -8716,9 +8784,6 @@ msgstr ""
msgid "Comma-separated list of email addresses."
msgstr ""
-msgid "Comma-separated list of users allowed to exceed the rate limit."
-msgstr ""
-
msgid "Comma-separated, e.g. '1.1.1.1, 2.2.2.0/24'"
msgstr ""
@@ -9045,6 +9110,12 @@ msgstr ""
msgid "Confidential"
msgstr ""
+msgid "Confidential issue"
+msgstr ""
+
+msgid "Confidential note"
+msgstr ""
+
msgid "Confidentiality"
msgstr ""
@@ -9078,6 +9149,9 @@ msgstr ""
msgid "Configure Dependency Scanning in `.gitlab-ci.yml`, creating this file if it does not already exist"
msgstr ""
+msgid "Configure GitLab"
+msgstr ""
+
msgid "Configure GitLab runners to start using the Web Terminal. %{helpStart}Learn more.%{helpEnd}"
msgstr ""
@@ -9126,6 +9200,15 @@ msgstr ""
msgid "Configure pipelines to deploy web apps, backend services, APIs and static resources to Google Cloud"
msgstr ""
+msgid "Configure region"
+msgstr ""
+
+msgid "Configure region for environment"
+msgstr ""
+
+msgid "Configure regions"
+msgstr ""
+
msgid "Configure repository mirroring."
msgstr ""
@@ -9159,6 +9242,9 @@ msgstr ""
msgid "Configure which lists are shown for anyone who visits this board"
msgstr ""
+msgid "Configure your environments to be deployed to specific geographical regions"
+msgstr ""
+
msgid "Confirm"
msgstr ""
@@ -9861,10 +9947,10 @@ msgstr ""
msgid "CorpusManagement|Actions"
msgstr ""
-msgid "CorpusManagement|Corpus are used in fuzz testing as mutation source to Improve future testing."
+msgid "CorpusManagement|Corpus file"
msgstr ""
-msgid "CorpusManagement|Corpus file"
+msgid "CorpusManagement|Corpus files are used in coverage-guided fuzz testing as seed inputs to improve testing."
msgstr ""
msgid "CorpusManagement|Corpus files must be in *.zip format. Maximum 5 GB"
@@ -9918,6 +10004,9 @@ msgstr ""
msgid "Could not apply %{name} command."
msgstr ""
+msgid "Could not apply %{name} command. %{message}."
+msgstr ""
+
msgid "Could not authorize chat nickname. Try again!"
msgstr ""
@@ -10068,6 +10157,9 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
+msgid "Create a group"
+msgstr ""
+
msgid "Create a merge request"
msgstr ""
@@ -10092,6 +10184,9 @@ msgstr ""
msgid "Create a personal access token on your account to pull or push via %{protocol}."
msgstr "Създайте Ñи личен жетон за доÑтъп в акаунта Ñи, за да можете да изтеглÑте и изпращате промени чрез %{protocol}."
+msgid "Create a project"
+msgstr ""
+
msgid "Create an account using:"
msgstr ""
@@ -10455,6 +10550,9 @@ msgstr ""
msgid "Creation date"
msgstr ""
+msgid "Creator"
+msgstr ""
+
msgid "Credentials"
msgstr ""
@@ -10467,9 +10565,15 @@ msgstr ""
msgid "CredentialsInventory|Personal Access Tokens"
msgstr ""
+msgid "CredentialsInventory|Project Access Tokens"
+msgstr ""
+
msgid "CredentialsInventory|SSH Keys"
msgstr ""
+msgid "Credit card required to be on file in order to create a pipeline"
+msgstr ""
+
msgid "Credit card:"
msgstr ""
@@ -10653,9 +10757,6 @@ msgstr ""
msgid "Customer relations"
msgstr ""
-msgid "Customizable by an administrator."
-msgstr ""
-
msgid "Customizable by owners."
msgstr ""
@@ -10785,30 +10886,18 @@ msgstr ""
msgid "CycleAnalytics|%{selectedLabelsCount} selected (%{maxLabels} max)"
msgstr ""
-msgid "CycleAnalytics|%{stageCount} stages selected"
-msgstr ""
-
-msgid "CycleAnalytics|All stages"
-msgstr ""
-
-msgid "CycleAnalytics|Average days to completion"
+msgid "CycleAnalytics|Average time to completion"
msgstr ""
msgid "CycleAnalytics|Date"
msgstr ""
-msgid "CycleAnalytics|Days to completion"
-msgstr ""
-
msgid "CycleAnalytics|Display chart filters"
msgstr ""
msgid "CycleAnalytics|Lead Time for Changes"
msgstr ""
-msgid "CycleAnalytics|No stages selected"
-msgstr ""
-
msgid "CycleAnalytics|Number of tasks"
msgstr ""
@@ -10837,18 +10926,30 @@ msgstr ""
msgid "CycleAnalytics|Showing data for group '%{groupName}' from %{createdAfter} to %{createdBefore}"
msgstr ""
-msgid "CycleAnalytics|Stages"
+msgid "CycleAnalytics|Stage time: %{title}"
msgstr ""
msgid "CycleAnalytics|Tasks by type"
msgstr ""
-msgid "CycleAnalytics|The average time spent in the selected stage for the items that were completed on each date. Data limited to the last 500 items."
+msgid "CycleAnalytics|The average time items spent in this stage. Data limited to items completed within this date range."
msgstr ""
msgid "CycleAnalytics|The given date range is larger than 180 days"
msgstr ""
+msgid "CycleAnalytics|The total time items spent across each value stream stage. Data limited to items completed within this date range."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Stage time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Total time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|Total time"
+msgstr ""
+
msgid "CycleAnalytics|Type of work"
msgstr ""
@@ -10861,9 +10962,6 @@ msgstr ""
msgid "CycleAnalytics|project dropdown filter"
msgstr ""
-msgid "CycleAnalytics|stage dropdown"
-msgstr ""
-
msgid "DAG visualization requires at least 3 dependent jobs."
msgstr ""
@@ -10963,10 +11061,16 @@ msgstr ""
msgid "DastProfiles|AJAX spider"
msgstr ""
+msgid "DastProfiles|API"
+msgstr ""
+
+msgid "DastProfiles|API endpoint URL"
+msgstr ""
+
msgid "DastProfiles|Active"
msgstr ""
-msgid "DastProfiles|Additional request headers (Optional)"
+msgid "DastProfiles|Additional request headers (optional)"
msgstr ""
msgid "DastProfiles|Are you sure you want to delete this profile?"
@@ -10981,6 +11085,9 @@ msgstr ""
msgid "DastProfiles|Branch missing"
msgstr ""
+msgid "DastProfiles|Choose a scan method"
+msgstr ""
+
msgid "DastProfiles|Could not create the scanner profile. Please try again."
msgstr ""
@@ -11050,7 +11157,13 @@ msgstr ""
msgid "DastProfiles|Excluded URLs"
msgstr ""
-msgid "DastProfiles|Excluded URLs (Optional)"
+msgid "DastProfiles|Excluded URLs (optional)"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths (optional)"
msgstr ""
msgid "DastProfiles|Hide debug messages"
@@ -11107,9 +11220,6 @@ msgstr ""
msgid "DastProfiles|Request headers"
msgstr ""
-msgid "DastProfiles|Rest API"
-msgstr ""
-
msgid "DastProfiles|Run the AJAX spider, in addition to the traditional spider, to crawl the target site."
msgstr ""
@@ -11119,6 +11229,9 @@ msgstr ""
msgid "DastProfiles|Save profile"
msgstr ""
+msgid "DastProfiles|Scan method"
+msgstr ""
+
msgid "DastProfiles|Scan mode"
msgstr ""
@@ -11197,12 +11310,24 @@ msgstr ""
msgid "DastProfiles|Website"
msgstr ""
+msgid "DastProfiles|What does each method do?"
+msgstr ""
+
msgid "DastProfiles|You can either choose a passive scan or validate the target site from the site profile management page. %{docsLinkStart}Learn more about site validation.%{docsLinkEnd}"
msgstr ""
msgid "DastProfiles|You cannot run an active scan against an unvalidated site."
msgstr ""
+msgid "DastProfiles|folder/dast_example.har or https://example.com/dast_example.har"
+msgstr ""
+
+msgid "DastProfiles|folder/example.postman_collection.json or https://example.com/"
+msgstr ""
+
+msgid "DastProfiles|folder/openapi.json or https://example.com/openapi.json"
+msgstr ""
+
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
@@ -11310,6 +11435,9 @@ msgstr ""
msgid "DatadogIntegration|API URL"
msgstr ""
+msgid "DatadogIntegration|Custom tags in Datadog. Enter one tag per line in the %{codeOpen}key:value%{codeClose} format. %{linkOpen}How do I use tags?%{linkClose}"
+msgstr ""
+
msgid "DatadogIntegration|Environment"
msgstr ""
@@ -11328,12 +11456,18 @@ msgstr ""
msgid "DatadogIntegration|Tag all data from this GitLab instance in Datadog. Useful when managing several self-managed deployments."
msgstr ""
+msgid "DatadogIntegration|Tags"
+msgstr ""
+
msgid "DatadogIntegration|The Datadog site to send data to. To send data to the EU site, use %{codeOpen}datadoghq.eu%{codeClose}."
msgstr ""
msgid "DatadogIntegration|Trace your GitLab pipelines with Datadog."
msgstr ""
+msgid "DatadogIntegration|have an invalid format"
+msgstr ""
+
msgid "Datasource name not found"
msgstr ""
@@ -11343,9 +11477,6 @@ msgstr ""
msgid "Date merged"
msgstr ""
-msgid "Date picker"
-msgstr ""
-
msgid "Date range"
msgstr ""
@@ -11499,9 +11630,6 @@ msgstr ""
msgid "Definition"
msgstr ""
-msgid "Delayed Project Deletion (%{adjourned_deletion})"
-msgstr ""
-
msgid "DelayedJobs|Are you sure you want to run %{jobName} immediately? Otherwise this job will run automatically after its timer finishes."
msgstr ""
@@ -11580,10 +11708,10 @@ msgstr ""
msgid "Delete pipeline"
msgstr ""
-msgid "Delete project"
+msgid "Delete pipeline schedule"
msgstr ""
-msgid "Delete project. Are you ABSOLUTELY SURE?"
+msgid "Delete project"
msgstr ""
msgid "Delete row"
@@ -11613,6 +11741,9 @@ msgstr ""
msgid "Delete this epic and all descendants?"
msgstr ""
+msgid "Delete this project"
+msgstr ""
+
msgid "Delete user list"
msgstr ""
@@ -11871,6 +12002,12 @@ msgstr ""
msgid "Deploy to..."
msgstr ""
+msgid "DeployBoards|To see deployment progress for your environments, make sure you are deploying to %{codeStart}$KUBE_NAMESPACE%{codeEnd} and annotating with %{codeStart}app.gitlab.com/app=$CI_PROJECT_PATH_SLUG%{codeEnd} and %{codeStart}app.gitlab.com/env=$CI_ENVIRONMENT_SLUG%{codeEnd}."
+msgstr ""
+
+msgid "DeployBoard|Kubernetes Pods"
+msgstr ""
+
msgid "DeployFreeze|Add a freeze period to prevent unintended releases during a period of time for a given environment. You must update the deployment jobs in %{filename} according to the deploy freezes added here. %{freeze_period_link_start}Learn more.%{freeze_period_link_end}"
msgstr ""
@@ -11955,9 +12092,6 @@ msgstr ""
msgid "DeployTokens|Active Deploy Tokens (%{active_tokens})"
msgstr ""
-msgid "DeployTokens|Allows read and write access to registry images."
-msgstr ""
-
msgid "DeployTokens|Allows read and write access to the package registry."
msgstr ""
@@ -11970,6 +12104,9 @@ msgstr ""
msgid "DeployTokens|Allows read-only access to the repository."
msgstr ""
+msgid "DeployTokens|Allows write access to registry images."
+msgstr ""
+
msgid "DeployTokens|Copy deploy token"
msgstr ""
@@ -12063,12 +12200,57 @@ msgstr ""
msgid "Deploying to AWS is easy with GitLab"
msgstr ""
+msgid "Deployment"
+msgstr ""
+
msgid "Deployment Frequency"
msgstr ""
+msgid "Deployment Target|Project deployment target (optional)"
+msgstr ""
+
+msgid "Deployment Target|Select the deployment target"
+msgstr ""
+
msgid "Deployment frequency"
msgstr ""
+msgid "DeploymentTarget|GitLab Pages"
+msgstr ""
+
+msgid "DeploymentTarget|Heroku"
+msgstr ""
+
+msgid "DeploymentTarget|Infrastructure provider (Terraform, Cloudformation, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Kubernetes (GKE, EKS, OpenShift, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Managed container runtime (Fargate, Cloud Run, DigitalOcean App)"
+msgstr ""
+
+msgid "DeploymentTarget|Mobile app store"
+msgstr ""
+
+msgid "DeploymentTarget|No deployment planned"
+msgstr ""
+
+msgid "DeploymentTarget|Other hosting service"
+msgstr ""
+
+msgid "DeploymentTarget|Registry (package or container)"
+msgstr ""
+
+msgid "DeploymentTarget|Self-managed container runtime (Podman, Docker Swarm, Docker Compose)"
+msgstr ""
+
+msgid "DeploymentTarget|Serverless backend (Lambda, Cloud functions)"
+msgstr ""
+
+msgid "DeploymentTarget|Virtual machine (for example, EC2)"
+msgstr ""
+
msgid "Deployments"
msgstr ""
@@ -12107,6 +12289,9 @@ msgstr ""
msgid "Deployment|This deployment was created using the API"
msgstr ""
+msgid "Deployment|Triggerer"
+msgstr ""
+
msgid "Deployment|Waiting"
msgstr ""
@@ -12134,6 +12319,18 @@ msgstr ""
msgid "Deprecated API rate limits"
msgstr ""
+msgid "Deprecations|Feature deprecation and removal"
+msgstr ""
+
+msgid "Deprecations|For information on a possible replacement %{epicStart} learn more about Opstrace %{epicEnd}."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7 and are %{epicStart} scheduled for removal %{epicEnd} in GitLab 15.0."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7, and are %{removal_link_start} scheduled for removal %{link_end} in GitLab 15.0. For information on a possible replacement, %{opstrace_link_start} learn more about Opstrace %{link_end}."
+msgstr ""
+
msgid "Deprioritize label"
msgstr ""
@@ -12379,10 +12576,10 @@ msgstr ""
msgid "DevopsAdoption|At least one deploy"
msgstr ""
-msgid "DevopsAdoption|At least one issue opened"
+msgid "DevopsAdoption|At least one issue created"
msgstr ""
-msgid "DevopsAdoption|At least one merge request opened"
+msgid "DevopsAdoption|At least one merge request created"
msgstr ""
msgid "DevopsAdoption|At least one pipeline successfully run"
@@ -12583,6 +12780,9 @@ msgstr ""
msgid "Direct member"
msgstr ""
+msgid "Direct members"
+msgstr ""
+
msgid "Direct non-authenticated users to this page."
msgstr ""
@@ -12699,6 +12899,9 @@ msgid_plural "Dismiss %d selected vulnerabilities as"
msgstr[0] ""
msgstr[1] ""
+msgid "Dismiss Alert"
+msgstr ""
+
msgid "Dismiss merge request promotion"
msgstr ""
@@ -12726,9 +12929,15 @@ msgstr ""
msgid "Display alerts from all configured monitoring tools."
msgstr ""
+msgid "Display milestones"
+msgstr ""
+
msgid "Display name"
msgstr ""
+msgid "Display progress of child issues"
+msgstr ""
+
msgid "Display rendered file"
msgstr ""
@@ -12834,6 +13043,9 @@ msgstr ""
msgid "Download image"
msgstr ""
+msgid "Download payload"
+msgstr ""
+
msgid "Download raw data (.csv)"
msgstr ""
@@ -13011,6 +13223,9 @@ msgstr ""
msgid "Edit in Web IDE"
msgstr ""
+msgid "Edit in pipeline editor"
+msgstr ""
+
msgid "Edit in single-file editor"
msgstr ""
@@ -13053,6 +13268,9 @@ msgstr ""
msgid "Edit your most recent comment in a thread (from an empty textarea)"
msgstr ""
+msgid "Edit, lint, and visualize your pipeline."
+msgstr ""
+
msgid "Edited"
msgstr ""
@@ -13494,6 +13712,9 @@ msgstr ""
msgid "Enforce two-factor authentication for all user sign-ins."
msgstr ""
+msgid "Enhance security by storing service account keys in secret managers - learn more about %{docLinkStart}secret management with GitLab%{docLinkEnd}"
+msgstr ""
+
msgid "Ensure connectivity is available from the GitLab server to the Prometheus server"
msgstr ""
@@ -13554,6 +13775,9 @@ 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 following to confirm:"
+msgstr ""
+
msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
@@ -14084,9 +14308,6 @@ 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 ""
@@ -14222,6 +14443,9 @@ msgstr ""
msgid "Errors:"
msgstr ""
+msgid "Escalate this incident"
+msgstr ""
+
msgid "Escalation Policies"
msgstr ""
@@ -14234,6 +14458,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy"
+msgstr ""
+
msgid "Escalation policy:"
msgstr ""
@@ -14485,6 +14712,9 @@ msgstr ""
msgid "Existing sign in methods may be removed"
msgstr ""
+msgid "Exit."
+msgstr ""
+
msgid "Expand"
msgstr ""
@@ -14581,6 +14811,9 @@ msgstr ""
msgid "Explore public groups"
msgstr ""
+msgid "Explore public projects"
+msgstr ""
+
msgid "Explore snippets"
msgstr ""
@@ -14742,7 +14975,7 @@ msgid_plural "Failed to archive designs. Please try again."
msgstr[0] ""
msgstr[1] ""
-msgid "Failed to assign a reviewer because no user was found."
+msgid "Failed to assign a reviewer because no user was specified."
msgstr ""
msgid "Failed to assign a user because no user was found."
@@ -14808,10 +15041,10 @@ msgstr ""
msgid "Failed to find import label for Jira import."
msgstr ""
-msgid "Failed to generate export, please try again later."
+msgid "Failed to find users for %{missing}"
msgstr ""
-msgid "Failed to generate report, please try again after sometime"
+msgid "Failed to generate export, please try again later."
msgstr ""
msgid "Failed to get ref."
@@ -14910,6 +15143,9 @@ msgstr ""
msgid "Failed to remove a to-do item for the design."
msgstr ""
+msgid "Failed to remove attention because no user was found."
+msgstr ""
+
msgid "Failed to remove mirror."
msgstr ""
@@ -14922,6 +15158,9 @@ msgstr ""
msgid "Failed to remove user key."
msgstr ""
+msgid "Failed to request attention because no user was found."
+msgstr ""
+
msgid "Failed to reset key. Please try again."
msgstr ""
@@ -15003,6 +15242,9 @@ msgstr ""
msgid "Feature Flags"
msgstr ""
+msgid "Feature deprecation and removal"
+msgstr ""
+
msgid "Feature flag status"
msgstr ""
@@ -15500,7 +15742,7 @@ msgstr ""
msgid "For each job, re-use the project workspace. If the workspace doesn't exist, use %{code_open}git clone%{code_close}."
msgstr ""
-msgid "For example, the application using the token or the purpose of the token."
+msgid "For example, the application using the token or the purpose of the token. Do not give sensitive information for the name of the token, as it will be visible to all %{resource_type} members."
msgstr ""
msgid "For files larger than this limit, only index the file name. The file content is neither indexed nor searchable."
@@ -15584,9 +15826,6 @@ msgstr ""
msgid "ForkProject|Select a namespace"
msgstr ""
-msgid "ForkProject|Select a namespace to fork the project"
-msgstr ""
-
msgid "ForkProject|The project can be accessed by any logged in user."
msgstr ""
@@ -15683,6 +15922,9 @@ msgstr ""
msgid "Full name"
msgstr ""
+msgid "GCP region configured"
+msgstr ""
+
msgid "GPG Key ID:"
msgstr ""
@@ -15863,6 +16105,9 @@ msgstr ""
msgid "Geo|Failed"
msgstr ""
+msgid "Geo|Filter Geo sites"
+msgstr ""
+
msgid "Geo|Filter by name"
msgstr ""
@@ -16274,6 +16519,12 @@ msgstr ""
msgid "GitLab Issue"
msgstr ""
+msgid "GitLab KAS"
+msgstr ""
+
+msgid "GitLab Memberships CSV Export"
+msgstr ""
+
msgid "GitLab Pages"
msgstr ""
@@ -16322,6 +16573,9 @@ 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 free to use. Many features for larger teams are part of our %{link_start}paid products%{link_end}. You can try Ultimate for free without any obligation or payment details."
+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 ""
@@ -16448,7 +16702,7 @@ msgstr ""
msgid "GitLabPages|When enabled, all attempts to visit your website through HTTP are automatically redirected to HTTPS using a response with status code 301. Requires a valid certificate for all domains. %{docs_link_start}Learn more.%{link_end}"
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. %{docs_link_start}Learn more.%{link_end}"
+msgid "GitLabPages|When using Pages under the general domain of a GitLab instance (%{pages_host}), you cannot use HTTPS with subdomains of subdomains. If your namespace or groupname contains a dot, it does not work. This is a limitation of the HTTP Over TLS protocol. HTTP pages work if you don't redirect HTTP to HTTPS. %{docs_link_start}Learn more.%{link_end}"
msgstr ""
msgid "GitLabPages|With GitLab Pages you can host your static website directly from your GitLab repository. %{docs_link_start}Learn more.%{link_end}"
@@ -16625,9 +16879,6 @@ msgstr ""
msgid "Go to find file"
msgstr ""
-msgid "Go to fork"
-msgstr ""
-
msgid "Go to issue boards"
msgstr ""
@@ -16835,9 +17086,6 @@ msgstr ""
msgid "Group Hooks"
msgstr ""
-msgid "Group ID"
-msgstr ""
-
msgid "Group Owner must have signed in with SAML before enabling Group Managed Accounts"
msgstr ""
@@ -16865,9 +17113,6 @@ msgstr ""
msgid "Group by"
msgstr ""
-msgid "Group description"
-msgstr ""
-
msgid "Group description (optional)"
msgstr ""
@@ -16982,7 +17227,7 @@ msgstr ""
msgid "Group: %{name}"
msgstr ""
-msgid "GroupActivityMetrics|Issues opened"
+msgid "GroupActivityMetrics|Issues created"
msgstr ""
msgid "GroupActivityMetrics|Last 90 days"
@@ -16991,7 +17236,7 @@ msgstr ""
msgid "GroupActivityMetrics|Members added"
msgstr ""
-msgid "GroupActivityMetrics|Merge Requests opened"
+msgid "GroupActivityMetrics|Merge Requests created"
msgstr ""
msgid "GroupActivityMetrics|Recent activity"
@@ -17282,6 +17527,9 @@ msgstr ""
msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
+msgid "GroupSettings|Choose a group path that does not start with a dash or end with a period. It can also contain alphanumeric characters and underscores."
+msgstr ""
+
msgid "GroupSettings|Compliance frameworks"
msgstr ""
@@ -17315,7 +17563,7 @@ msgstr ""
msgid "GroupSettings|If not specified at the group or instance level, the default is %{default_initial_branch_name}. Does not affect existing repositories."
msgstr ""
-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."
+msgid "GroupSettings|If the parent group's visibility is lower than the group's current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility."
msgstr ""
msgid "GroupSettings|New runners registration token has been generated!"
@@ -17432,7 +17680,10 @@ msgstr ""
msgid "Groups and projects"
msgstr ""
-msgid "Groups and subgroups"
+msgid "Groups are a great way to organize projects and people."
+msgstr ""
+
+msgid "Groups are the best way to manage projects and members."
msgstr ""
msgid "Groups to synchronize"
@@ -17543,13 +17794,16 @@ msgstr ""
msgid "GroupsTree|Are you sure you want to leave the \"%{fullName}\" group?"
msgstr ""
-msgid "GroupsTree|Edit group"
+msgid "GroupsTree|Delete"
+msgstr ""
+
+msgid "GroupsTree|Edit"
msgstr ""
msgid "GroupsTree|Failed to leave the group. Please make sure you are not the only owner."
msgstr ""
-msgid "GroupsTree|Leave this group"
+msgid "GroupsTree|Leave group"
msgstr ""
msgid "GroupsTree|Loading groups"
@@ -17561,9 +17815,57 @@ msgstr ""
msgid "GroupsTree|No groups or projects matched your search"
msgstr ""
+msgid "GroupsTree|Options"
+msgstr ""
+
msgid "GroupsTree|Search by name"
msgstr ""
+msgid "Groups|Avatar will be removed. Are you sure?"
+msgstr ""
+
+msgid "Groups|Changing group URL can have unintended side effects."
+msgstr ""
+
+msgid "Groups|Checking group URL availability..."
+msgstr ""
+
+msgid "Groups|Enter a descriptive name for your group."
+msgstr ""
+
+msgid "Groups|Group ID"
+msgstr ""
+
+msgid "Groups|Group URL"
+msgstr ""
+
+msgid "Groups|Group avatar"
+msgstr ""
+
+msgid "Groups|Group description (optional)"
+msgstr ""
+
+msgid "Groups|Group name"
+msgstr ""
+
+msgid "Groups|Group path is available."
+msgstr ""
+
+msgid "Groups|Group path is unavailable. Path has been replaced with a suggested available path."
+msgstr ""
+
+msgid "Groups|Learn more"
+msgstr ""
+
+msgid "Groups|Must start with letter, digit, emoji, or underscore. Can also contain periods, dashes, spaces, and parentheses."
+msgstr ""
+
+msgid "Groups|Remove avatar"
+msgstr ""
+
+msgid "Groups|Save changes"
+msgstr ""
+
msgid "Guideline"
msgstr ""
@@ -17573,6 +17875,9 @@ msgstr ""
msgid "HAR file path or URL"
msgstr ""
+msgid "HTTP Archive (HAR)"
+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 ""
@@ -17973,6 +18278,9 @@ msgstr ""
msgid "INFO: Your SSH key is expiring soon. Please generate a new key."
msgstr ""
+msgid "IP"
+msgstr ""
+
msgid "IP Address"
msgstr ""
@@ -18009,6 +18317,9 @@ msgstr ""
msgid "IdentityVerification|Verify your identity"
msgstr ""
+msgid "IdentityVerification|You can always verify your account at a later time to create a group."
+msgstr ""
+
msgid "If any indexed field exceeds this limit, it is truncated to this number of characters. The rest of the content is neither indexed nor searchable. This does not apply to repository and wiki indexing. For unlimited characters, set this to 0."
msgstr ""
@@ -18066,6 +18377,9 @@ msgstr ""
msgid "If you add %{codeStart}needs%{codeEnd} to jobs in your pipeline you'll be able to view the %{codeStart}needs%{codeEnd} relationships between jobs in this tab as a %{linkStart}Directed Acyclic Graph (DAG)%{linkEnd}."
msgstr ""
+msgid "If you are added to a project, it will be displayed here."
+msgstr ""
+
msgid "If you did not initiate these sign-in attempts, please reach out to your administrator or enable two-factor authentication (2FA) on your account."
msgstr ""
@@ -18372,12 +18686,24 @@ msgstr ""
msgid "InProductMarketing|3 ways to dive into GitLab CI/CD"
msgstr ""
+msgid "InProductMarketing|A single application eliminates complex integrations, data chokepoints, and toolchain maintenance, resulting in greater productivity and lower cost."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features, build more efficiently, strengthen security and compliance."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features."
+msgstr ""
+
msgid "InProductMarketing|Actually, GitLab makes the team work (better)"
msgstr ""
msgid "InProductMarketing|And finally %{deploy_link} a Python application."
msgstr ""
+msgid "InProductMarketing|And many more..."
+msgstr ""
+
msgid "InProductMarketing|Are your runners ready?"
msgstr ""
@@ -18396,15 +18722,33 @@ msgstr ""
msgid "InProductMarketing|Blog"
msgstr ""
+msgid "InProductMarketing|Break down silos to coordinate seamlessly across development, operations, and security with a consistent experience across the development lifecycle."
+msgstr ""
+
+msgid "InProductMarketing|Burn up/down charts"
+msgstr ""
+
msgid "InProductMarketing|By enabling code owners and required merge approvals the right person will review the right MR. This is a win-win: cleaner code and a more efficient review process."
msgstr ""
msgid "InProductMarketing|Click on the number below that corresponds with your answer — 1 being very difficult, 5 being very easy."
msgstr ""
+msgid "InProductMarketing|Code owners"
+msgstr ""
+
msgid "InProductMarketing|Code owners and required merge approvals are part of the paid tiers of GitLab. You can start a free 30-day trial of GitLab Ultimate and enable these features in less than 5 minutes with no credit card required."
msgstr ""
+msgid "InProductMarketing|Code review analytics"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration across stages in GitLab"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration made easy"
+msgstr ""
+
msgid "InProductMarketing|Create a custom CI runner with just a few clicks"
msgstr ""
@@ -18414,12 +18758,21 @@ msgstr ""
msgid "InProductMarketing|Create a project in GitLab in 5 minutes"
msgstr ""
+msgid "InProductMarketing|Create well-defined workflows by using scoped labels on issues, merge requests, and epics. Labels with the same scope cannot be used together, which prevents conflicts."
+msgstr ""
+
msgid "InProductMarketing|Create your first project!"
msgstr ""
+msgid "InProductMarketing|Define who owns specific files or directories, so the right reviewers are suggested when a merge request introduces changes to those files."
+msgstr ""
+
msgid "InProductMarketing|Deliver Better Products Faster"
msgstr ""
+msgid "InProductMarketing|Dependency scanning"
+msgstr ""
+
msgid "InProductMarketing|Did you know teams that use GitLab are far more efficient?"
msgstr ""
@@ -18429,15 +18782,27 @@ msgstr ""
msgid "InProductMarketing|Dig in and create a project and a repo"
msgstr ""
+msgid "InProductMarketing|Discover Premium & Ultimate"
+msgstr ""
+
+msgid "InProductMarketing|Discover Premium & Ultimate."
+msgstr ""
+
msgid "InProductMarketing|Do you have a minute?"
msgstr ""
msgid "InProductMarketing|Do you have a teammate who would be perfect for this task?"
msgstr ""
+msgid "InProductMarketing|Dynamic application security testing"
+msgstr ""
+
msgid "InProductMarketing|Easy"
msgstr ""
+msgid "InProductMarketing|Epics"
+msgstr ""
+
msgid "InProductMarketing|Expand your DevOps journey with a free GitLab trial"
msgstr ""
@@ -18459,9 +18824,15 @@ msgstr ""
msgid "InProductMarketing|Feel the need for speed?"
msgstr ""
+msgid "InProductMarketing|Find and fix bottlenecks in your code review process by understanding how long open merge requests have been in review."
+msgstr ""
+
msgid "InProductMarketing|Find out how your teams are really doing"
msgstr ""
+msgid "InProductMarketing|Find out if your external libraries are safe. Run dependency scanning jobs that check for known vulnerabilities in your external libraries."
+msgstr ""
+
msgid "InProductMarketing|Follow our steps"
msgstr ""
@@ -18498,6 +18869,9 @@ msgstr ""
msgid "InProductMarketing|GitLab is better with teammates to help out!"
msgstr ""
+msgid "InProductMarketing|GitLab is infrastructure agnostic (supporting GCP, AWS, Azure, OpenShift, VMWare, On Prem, Bare Metal, and more), offering a consistent workflow experience – irrespective of the environment."
+msgstr ""
+
msgid "InProductMarketing|GitLab provides static application security testing (SAST), dynamic application security testing (DAST), container scanning, and dependency scanning to help you deliver secure applications along with license compliance."
msgstr ""
@@ -18588,21 +18962,36 @@ msgstr ""
msgid "InProductMarketing|It's also possible to simply %{external_repo_link} in order to take advantage of GitLab's CI/CD."
msgstr ""
+msgid "InProductMarketing|Keep your code quality high by defining who should approve merge requests and how many approvals are required."
+msgstr ""
+
msgid "InProductMarketing|Launch GitLab CI/CD in 20 minutes or less"
msgstr ""
+msgid "InProductMarketing|Lower cost of development"
+msgstr ""
+
+msgid "InProductMarketing|Make it easier to collaborate on high-level ideas by grouping related issues in an epic."
+msgstr ""
+
msgid "InProductMarketing|Making the switch? It's easier than you think to import your projects into GitLab. Move %{github_link}, or import something %{bitbucket_link}."
msgstr ""
msgid "InProductMarketing|Master the art of importing!"
msgstr ""
+msgid "InProductMarketing|Merge request approval rule"
+msgstr ""
+
msgid "InProductMarketing|Move on to easily creating a Pages website %{ci_template_link}"
msgstr ""
msgid "InProductMarketing|Multiple owners, confusing workstreams? We've got you covered"
msgstr ""
+msgid "InProductMarketing|Multiple required approvers"
+msgstr ""
+
msgid "InProductMarketing|Need an alternative to importing?"
msgstr ""
@@ -18615,18 +19004,33 @@ msgstr ""
msgid "InProductMarketing|Our tool brings all the things together"
msgstr ""
+msgid "InProductMarketing|Protect your web application by using DAST to examine for vulnerabilities in deployed environments."
+msgstr ""
+
msgid "InProductMarketing|Rapid development, simplified"
msgstr ""
msgid "InProductMarketing|Reduce Security & Compliance Risk"
msgstr ""
+msgid "InProductMarketing|Require multiple approvers on a merge request, so you know it's in good shape before it's merged."
+msgstr ""
+
+msgid "InProductMarketing|Roadmaps"
+msgstr ""
+
+msgid "InProductMarketing|Scoped labels"
+msgstr ""
+
msgid "InProductMarketing|Security that's integrated into your development lifecycle"
msgstr ""
msgid "InProductMarketing|Sometimes you're not ready to make a full transition to a new tool. If you're not ready to fully commit, %{mirroring_link} gives you a safe way to try out GitLab in parallel with your current tool."
msgstr ""
+msgid "InProductMarketing|Speed. Efficiency. Trust."
+msgstr ""
+
msgid "InProductMarketing|Spin up an autoscaling runner in GitLab"
msgstr ""
@@ -18636,6 +19040,9 @@ msgstr ""
msgid "InProductMarketing|Start a Self-Managed trial"
msgstr ""
+msgid "InProductMarketing|Start a free trial"
+msgstr ""
+
msgid "InProductMarketing|Start a free trial of GitLab Ultimate – no credit card required"
msgstr ""
@@ -18702,6 +19109,9 @@ msgstr ""
msgid "InProductMarketing|To understand and get the most out of GitLab, start at the beginning and %{project_link}. In GitLab, repositories are part of a project, so after you've created your project you can go ahead and %{repo_link}."
msgstr ""
+msgid "InProductMarketing|Track completed issues in a chart, so you can see how a milestone is progressing at a glance."
+msgstr ""
+
msgid "InProductMarketing|Try GitLab Ultimate for free"
msgstr ""
@@ -18738,6 +19148,9 @@ msgstr ""
msgid "InProductMarketing|Very easy"
msgstr ""
+msgid "InProductMarketing|Visualize your epics and milestones in a timeline."
+msgstr ""
+
msgid "InProductMarketing|Want to host GitLab on your servers?"
msgstr ""
@@ -18759,6 +19172,9 @@ msgstr ""
msgid "InProductMarketing|YouTube"
msgstr ""
+msgid "InProductMarketing|Your software, deployed your way"
+msgstr ""
+
msgid "InProductMarketing|Your teams can be more efficient"
msgstr ""
@@ -18879,9 +19295,18 @@ msgstr ""
msgid "IncidentManagement|No incidents to display."
msgstr ""
+msgid "IncidentManagement|None"
+msgstr ""
+
msgid "IncidentManagement|Open"
msgstr ""
+msgid "IncidentManagement|Page your team with escalation policies"
+msgstr ""
+
+msgid "IncidentManagement|Paged"
+msgstr ""
+
msgid "IncidentManagement|Published"
msgstr ""
@@ -18891,6 +19316,9 @@ msgstr ""
msgid "IncidentManagement|Severity"
msgstr ""
+msgid "IncidentManagement|Status"
+msgstr ""
+
msgid "IncidentManagement|There are no closed incidents"
msgstr ""
@@ -18909,6 +19337,9 @@ msgstr ""
msgid "IncidentManagement|Unpublished"
msgstr ""
+msgid "IncidentManagement|Use escalation policies to automatically page your team when incidents are created."
+msgstr ""
+
msgid "IncidentSettings|Activate \"time to SLA\" countdown timer"
msgstr ""
@@ -18954,7 +19385,10 @@ msgstr ""
msgid "Incidents"
msgstr ""
-msgid "Incidents|Add a URL"
+msgid "Incidents|Add image details"
+msgstr ""
+
+msgid "Incidents|Add text or a link to display with your image. If you don't add either, the file name displays instead."
msgstr ""
msgid "Incidents|Drop or %{linkStart}upload%{linkEnd} a metric screenshot to attach it to the incident"
@@ -18969,10 +19403,10 @@ msgstr ""
msgid "Incidents|There was an issue loading metric images."
msgstr ""
-msgid "Incidents|There was an issue uploading your image."
+msgid "Incidents|There was an issue updating your image."
msgstr ""
-msgid "Incidents|You can optionally add a URL to link users to the original graph."
+msgid "Incidents|There was an issue uploading your image."
msgstr ""
msgid "Incident|Alert details"
@@ -18981,9 +19415,18 @@ msgstr ""
msgid "Incident|Are you sure you wish to delete this image?"
msgstr ""
+msgid "Incident|Delete image"
+msgstr ""
+
msgid "Incident|Deleting %{filename}"
msgstr ""
+msgid "Incident|Edit image text or link"
+msgstr ""
+
+msgid "Incident|Editing %{filename}"
+msgstr ""
+
msgid "Incident|Metrics"
msgstr ""
@@ -19253,12 +19696,18 @@ msgstr ""
msgid "Integrations|Branches for which notifications are to be sent"
msgstr ""
+msgid "Integrations|Clear if using a self-signed certificate."
+msgstr ""
+
msgid "Integrations|Comment detail:"
msgstr ""
msgid "Integrations|Comment settings:"
msgstr ""
+msgid "Integrations|Connection details"
+msgstr ""
+
msgid "Integrations|Connection failed. Please check your settings."
msgstr ""
@@ -19283,6 +19732,9 @@ msgstr ""
msgid "Integrations|Enable GitLab.com slash commands in a Slack workspace."
msgstr ""
+msgid "Integrations|Enable SSL verification"
+msgstr ""
+
msgid "Integrations|Enable comments"
msgstr ""
@@ -19361,6 +19813,9 @@ msgstr ""
msgid "Integrations|Return to GitLab for Jira"
msgstr ""
+msgid "Integrations|SSL verification"
+msgstr ""
+
msgid "Integrations|Save settings?"
msgstr ""
@@ -19406,9 +19861,6 @@ msgstr ""
msgid "Integrations|Use default settings"
msgstr ""
-msgid "Integrations|When you mention a Jira issue in a commit or merge request, GitLab creates a remote link and comment (if enabled)."
-msgstr ""
-
msgid "Integrations|You can now close this window and return to the GitLab for Jira application."
msgstr ""
@@ -19433,9 +19885,6 @@ msgstr ""
msgid "Integrations|can't exceed %{recipients_limit}"
msgstr ""
-msgid "Interactive developer security education."
-msgstr ""
-
msgid "Interactive mode"
msgstr ""
@@ -19925,6 +20374,9 @@ msgstr ""
msgid "IssueAnalytics|Assignees"
msgstr ""
+msgid "IssueAnalytics|Created by"
+msgstr ""
+
msgid "IssueAnalytics|Due date"
msgstr ""
@@ -19937,9 +20389,6 @@ msgstr ""
msgid "IssueAnalytics|Milestone"
msgstr ""
-msgid "IssueAnalytics|Opened by"
-msgstr ""
-
msgid "IssueAnalytics|Status"
msgstr ""
@@ -20063,10 +20512,10 @@ msgstr ""
msgid "IssuesAnalytics|Avg/Month:"
msgstr ""
-msgid "IssuesAnalytics|Issues opened"
+msgid "IssuesAnalytics|Issues created"
msgstr ""
-msgid "IssuesAnalytics|Issues opened per month"
+msgid "IssuesAnalytics|Issues created per month"
msgstr ""
msgid "IssuesAnalytics|Last 12 months"
@@ -20093,6 +20542,9 @@ msgstr ""
msgid "It looks like you have some draft commits in this branch."
msgstr ""
+msgid "It looks like you're attempting to activate your subscription. Use %{a_start}the Subscription page%{a_end} instead."
+msgstr ""
+
msgid "It may be several days before you see feature usage data."
msgstr ""
@@ -20321,6 +20773,9 @@ msgstr ""
msgid "JiraConnect|You can now close this window and return to Jira."
msgstr ""
+msgid "JiraConnect|You don't have permission to create branches for this project. Select a different project or contact the project owner for access. %{linkStart}Learn more.%{linkEnd}"
+msgstr ""
+
msgid "JiraRequest|A connection error occurred while connecting to Jira. Try your request again."
msgstr ""
@@ -20369,13 +20824,13 @@ msgstr ""
msgid "JiraService|Define the type of Jira issue to create from a vulnerability."
msgstr ""
-msgid "JiraService|Displaying Jira issues while leaving the GitLab issue functionality enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
+msgid "JiraService|Displaying Jira issues while leaving GitLab issues also enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
msgstr ""
-msgid "JiraService|Enable Jira issues"
+msgid "JiraService|Enable Jira issue creation from vulnerabilities"
msgstr ""
-msgid "JiraService|Enable Jira issues creation from vulnerabilities"
+msgid "JiraService|Enable Jira issues"
msgstr ""
msgid "JiraService|Enable Jira transitions"
@@ -20492,16 +20947,19 @@ msgstr ""
msgid "JiraService|View Jira issues in GitLab"
msgstr ""
-msgid "JiraService|Warning: All GitLab users that have access to this GitLab project are able to view all issues from the Jira project specified below."
+msgid "JiraService|Warning: All GitLab users with access to this GitLab project can view all issues from the Jira project you select."
msgstr ""
msgid "JiraService|Web URL"
msgstr ""
-msgid "JiraService|Work on Jira issues without leaving GitLab. Adds a Jira menu to access your list of Jira issues and view any issue as read-only."
+msgid "JiraService|When a Jira issue is mentioned in a commit or merge request, a remote link and comment (if enabled) will be created."
+msgstr ""
+
+msgid "JiraService|Work on Jira issues without leaving GitLab. Add a Jira menu to access a read-only list of your Jira issues."
msgstr ""
-msgid "JiraService|You need to configure Jira before enabling this integration. For more details, read the %{jira_doc_link_start}Jira integration documentation%{link_end}."
+msgid "JiraService|You must configure Jira before enabling this integration. %{jira_doc_link_start}Learn more.%{link_end}"
msgstr ""
msgid "Job"
@@ -20513,9 +20971,6 @@ msgstr ""
msgid "Job Failed #%{build_id}"
msgstr ""
-msgid "Job ID"
-msgstr ""
-
msgid "Job artifact"
msgstr ""
@@ -20582,9 +21037,27 @@ msgstr ""
msgid "Jobs|You're about to retry a job that failed because it attempted to deploy code that is older than the latest deployment. Retrying this job could result in overwriting the environment with the older source code."
msgstr ""
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source} into %{target}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{ref}"
+msgstr ""
+
+msgid "Job|Are you sure you want to erase this job log and artifacts?"
+msgstr ""
+
msgid "Job|Browse"
msgstr ""
+msgid "Job|Cancel"
+msgstr ""
+
msgid "Job|Complete Raw"
msgstr ""
@@ -20594,6 +21067,9 @@ msgstr ""
msgid "Job|Erase job log and artifacts"
msgstr ""
+msgid "Job|Finished at"
+msgstr ""
+
msgid "Job|Job artifacts"
msgstr ""
@@ -20606,7 +21082,7 @@ msgstr ""
msgid "Job|Keep"
msgstr ""
-msgid "Job|Pipeline"
+msgid "Job|Retry"
msgstr ""
msgid "Job|Scroll to bottom"
@@ -20618,6 +21094,9 @@ msgstr ""
msgid "Job|Show complete raw"
msgstr ""
+msgid "Job|Status"
+msgstr ""
+
msgid "Job|The artifacts were removed"
msgstr ""
@@ -20645,21 +21124,12 @@ msgstr ""
msgid "Job|delayed"
msgstr ""
-msgid "Job|for"
-msgstr ""
-
-msgid "Job|into"
-msgstr ""
-
msgid "Job|manual"
msgstr ""
msgid "Job|triggered"
msgstr ""
-msgid "Job|with"
-msgstr ""
-
msgid "Join Zoom meeting"
msgstr ""
@@ -20762,9 +21232,6 @@ msgstr ""
msgid "Ki"
msgstr ""
-msgid "Kontra"
-msgstr ""
-
msgid "Kroki"
msgstr ""
@@ -21088,6 +21555,9 @@ msgstr ""
msgid "Learn more about Auto DevOps"
msgstr ""
+msgid "Learn more about GitLab"
+msgstr ""
+
msgid "Learn more about Needs relationships"
msgstr ""
@@ -21415,9 +21885,18 @@ msgstr ""
msgid "Licenses|Displays licenses detected in the project, based on the %{linkStart}latest successful%{linkEnd} scan"
msgstr ""
+msgid "Licenses|Drag your license file here or %{linkStart}click to upload%{linkEnd}."
+msgstr ""
+
+msgid "Licenses|Drop your license file to start the upload."
+msgstr ""
+
msgid "Licenses|Error fetching the license list. Please check your network connection and try again."
msgstr ""
+msgid "Licenses|Error: You are trying to upload something other than a file"
+msgstr ""
+
msgid "Licenses|License Compliance"
msgstr ""
@@ -21436,6 +21915,9 @@ msgstr ""
msgid "Licenses|Specified policies in this project"
msgstr ""
+msgid "Licenses|The file could not be uploaded."
+msgstr ""
+
msgid "Licenses|The license list details information about the licenses used within your project."
msgstr ""
@@ -21469,11 +21951,6 @@ msgstr ""
msgid "Limit the size of Sidekiq jobs stored in Redis."
msgstr ""
-msgid "Limited to showing %d event at most"
-msgid_plural "Limited to showing %d events at most"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Limiting mode"
msgstr ""
@@ -21483,6 +21960,9 @@ msgstr ""
msgid "Link"
msgstr ""
+msgid "Link (optional)"
+msgstr ""
+
msgid "Link Prometheus monitoring to GitLab."
msgstr ""
@@ -21519,6 +21999,9 @@ msgstr ""
msgid "Linked emails (%{email_count})"
msgstr ""
+msgid "Linked epics"
+msgstr ""
+
msgid "Linked issues"
msgstr ""
@@ -21546,6 +22029,15 @@ msgstr ""
msgid "List of all merge commits"
msgstr ""
+msgid "List of environments for this project"
+msgstr ""
+
+msgid "List of suitable GCP locations"
+msgstr ""
+
+msgid "List of users allowed to exceed the rate limit."
+msgstr ""
+
msgid "List options"
msgstr ""
@@ -21765,6 +22257,9 @@ msgstr ""
msgid "Maintenance mode"
msgstr ""
+msgid "Make adjustments to how your GitLab instance is set up."
+msgstr ""
+
msgid "Make and review changes in the browser with the Web IDE"
msgstr ""
@@ -21909,6 +22404,12 @@ msgstr ""
msgid "MarkdownEditor|Add italic text (%{modifier_key}I)"
msgstr ""
+msgid "MarkdownEditor|Add strikethrough text (%{modifierKey}⇧X)"
+msgstr ""
+
+msgid "MarkdownEditor|Add strikethrough text (%{modifier_key}⇧X)"
+msgstr ""
+
msgid "Marked For Deletion At - %{deletion_time}"
msgstr ""
@@ -22170,6 +22671,9 @@ msgstr ""
msgid "Maximum push size (MB)"
msgstr ""
+msgid "Maximum requests per 10 minutes per user"
+msgstr ""
+
msgid "Maximum requests per minute"
msgstr ""
@@ -22260,6 +22764,19 @@ msgstr ""
msgid "Members of a group may only view projects they have permission to access"
msgstr ""
+msgid "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seat in use and will be billed for the overage."
+msgid_plural "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seats in use and will be billed for the overage."
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "MembersOverage|You are about to incur additional charges"
+msgstr ""
+
+msgid "MembersOverage|Your subscription includes %d seat."
+msgid_plural "MembersOverage|Your subscription includes %d seats."
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Membership"
msgstr ""
@@ -22464,9 +22981,6 @@ msgstr ""
msgid "Merge request not merged"
msgstr ""
-msgid "Merge request pipelines 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 merge request pipelines."
-msgstr ""
-
msgid "Merge request reports"
msgstr ""
@@ -22563,13 +23077,13 @@ msgstr ""
msgid "MergeRequests|Create issue to resolve thread"
msgstr ""
-msgid "MergeRequests|Failed to squash. Should be done manually."
+msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Saving the comment failed"
+msgid "MergeRequests|Squashing failed: Squash the commits locally, resolve any conflicts, then push the branch."
msgstr ""
-msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
+msgid "MergeRequests|Squashing not allowed: This project doesn't allow you to squash commits when merging."
msgstr ""
msgid "MergeRequests|Thread stays resolved"
@@ -23410,6 +23924,18 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "MrList|Assigned to %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from assignee %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from reviewer %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Review requested from %{name}, go to their profile."
+msgstr ""
+
msgid "Multi-project"
msgstr ""
@@ -23443,7 +23969,7 @@ msgstr ""
msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "My Awesome Group"
+msgid "My awesome group"
msgstr ""
msgid "My company or team"
@@ -24065,9 +24591,6 @@ msgstr ""
msgid "No available branches"
msgstr ""
-msgid "No available groups to fork the project."
-msgstr ""
-
msgid "No branches found"
msgstr ""
@@ -24278,6 +24801,9 @@ msgstr ""
msgid "No ref selected"
msgstr ""
+msgid "No regions configured"
+msgstr ""
+
msgid "No related merge requests found."
msgstr ""
@@ -25082,6 +25608,9 @@ msgstr ""
msgid "Only reCAPTCHA v2 is supported:"
msgstr ""
+msgid "Only required if not using role instance credentials."
+msgstr ""
+
msgid "Only use lowercase letters, numbers, and underscores."
msgstr ""
@@ -25106,9 +25635,6 @@ msgstr ""
msgid "Open a CLI and connect to the cluster you want to install the agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
-msgid "Open epics"
-msgstr ""
-
msgid "Open errors"
msgstr ""
@@ -25148,8 +25674,8 @@ msgstr ""
msgid "Opened issues"
msgstr ""
-msgid "OpenedNDaysAgo|Opened"
-msgstr "Отворен"
+msgid "OpenedNDaysAgo|Created"
+msgstr ""
msgid "Opens in a new window"
msgstr ""
@@ -25193,9 +25719,6 @@ msgstr ""
msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
-msgid "Optional."
-msgstr ""
-
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
msgstr ""
@@ -25984,6 +26507,9 @@ msgstr ""
msgid "PerformanceBar|Memory"
msgstr ""
+msgid "PerformanceBar|Memory report"
+msgstr ""
+
msgid "PerformanceBar|Redis calls"
msgstr ""
@@ -26017,18 +26543,12 @@ msgstr ""
msgid "PerformanceBar|wall"
msgstr ""
-msgid "Performs a rebase but skips triggering a new pipeline"
-msgstr ""
-
msgid "Period in seconds"
msgstr ""
msgid "Permalink"
msgstr ""
-msgid "Permanently delete project"
-msgstr ""
-
msgid "Permanently remove group"
msgstr ""
@@ -26299,6 +26819,51 @@ msgstr ""
msgid "PipelineStatusTooltip|Pipeline: %{ci_status}"
msgstr ""
+msgid "PipelineWizardDefaultCommitMessage|Add %{filename}"
+msgstr ""
+
+msgid "PipelineWizardDefaultCommitMessage|Update %{filename}"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|At least one entry is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This field is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This value is not valid"
+msgstr ""
+
+msgid "PipelineWizardListWidget|add another step"
+msgstr ""
+
+msgid "PipelineWizardListWidget|remove step"
+msgstr ""
+
+msgid "PipelineWizard|Commit"
+msgstr ""
+
+msgid "PipelineWizard|Commit Message"
+msgstr ""
+
+msgid "PipelineWizard|Commit changes to your file"
+msgstr ""
+
+msgid "PipelineWizard|Commit file to Branch"
+msgstr ""
+
+msgid "PipelineWizard|Commit your new file"
+msgstr ""
+
+msgid "PipelineWizard|The file has been committed."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem committing the changes."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem while checking whether your file already exists in the specified branch."
+msgstr ""
+
msgid "Pipelines"
msgstr "Схеми"
@@ -26413,7 +26978,7 @@ msgstr ""
msgid "Pipelines|Project cache successfully reset."
msgstr ""
-msgid "Pipelines|Revoke"
+msgid "Pipelines|Revoke trigger"
msgstr ""
msgid "Pipelines|Something went wrong while cleaning runners cache."
@@ -26458,6 +27023,12 @@ msgstr ""
msgid "Pipelines|This is a child pipeline within the parent pipeline"
msgstr ""
+msgid "Pipelines|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipelines|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipelines|This pipeline will run code originating from a forked project merge request. This means that the code can potentially have security considerations like exposing CI variables."
msgstr ""
@@ -26500,9 +27071,6 @@ msgstr ""
msgid "Pipelines|Your changes have been successfully committed. Now redirecting to the new merge request page."
msgstr ""
-msgid "Pipelines|detached"
-msgstr ""
-
msgid "Pipelines|error"
msgstr ""
@@ -26512,10 +27080,13 @@ msgstr ""
msgid "Pipelines|latest"
msgstr ""
-msgid "Pipelines|stuck"
+msgid "Pipelines|merge request"
msgstr ""
-msgid "Pipelines|train"
+msgid "Pipelines|merge train"
+msgstr ""
+
+msgid "Pipelines|stuck"
msgstr ""
msgid "Pipelines|yaml invalid"
@@ -26647,6 +27218,12 @@ msgstr ""
msgid "Pipeline|This change will not change the overall test coverage if merged."
msgstr ""
+msgid "Pipeline|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipeline|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipeline|Trigger author"
msgstr ""
@@ -26671,6 +27248,12 @@ msgstr ""
msgid "Pipeline|for"
msgstr ""
+msgid "Pipeline|merge request"
+msgstr ""
+
+msgid "Pipeline|merge train"
+msgstr ""
+
msgid "Pipeline|on"
msgstr ""
@@ -26809,9 +27392,6 @@ msgstr ""
msgid "Please enter a valid time interval"
msgstr ""
-msgid "Please enter or upload a valid license."
-msgstr ""
-
msgid "Please enter your current password."
msgstr ""
@@ -26920,9 +27500,6 @@ msgstr ""
msgid "Please type %{phrase_code} to proceed or close this modal to cancel."
msgstr ""
-msgid "Please type the following to confirm:"
-msgstr ""
-
msgid "Please use this form to report to the admin users who create spam issues, comments or behave inappropriately."
msgstr ""
@@ -26950,12 +27527,27 @@ msgstr ""
msgid "Policies"
msgstr ""
+msgid "Policy '%{escalation_policy_name}' does not exist."
+msgstr ""
+
msgid "Policy management project does have any policies in %{policy_path}"
msgstr ""
msgid "Policy project doesn't exist"
msgstr ""
+msgid "PolicyRuleMultiSelect|%{firstLabel} +%{numberOfAdditionalLabels} more"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|All %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select all"
+msgstr ""
+
msgid "Polling interval multiplier"
msgstr ""
@@ -27184,6 +27776,9 @@ msgstr ""
msgid "Private projects can be created in your personal namespace with:"
msgstr ""
+msgid "Problem with %{name} command: %{message}."
+msgstr ""
+
msgid "Proceed"
msgstr ""
@@ -27658,6 +28253,9 @@ msgstr ""
msgid "Progress"
msgstr ""
+msgid "Progress tracking"
+msgstr ""
+
msgid "Project"
msgstr ""
@@ -27889,6 +28487,9 @@ msgstr ""
msgid "ProjectQualitySummary|Failure"
msgstr ""
+msgid "ProjectQualitySummary|Get insight into the overall percentage of tests in your project that succeed, fail and are skipped."
+msgstr ""
+
msgid "ProjectQualitySummary|Latest pipeline results"
msgstr ""
@@ -27907,6 +28508,12 @@ msgstr ""
msgid "ProjectQualitySummary|See project Code Coverage Statistics"
msgstr ""
+msgid "ProjectQualitySummary|Set up test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|Set up test runs (opens in a new tab)"
+msgstr ""
+
msgid "ProjectQualitySummary|Skipped"
msgstr ""
@@ -28183,13 +28790,19 @@ msgstr ""
msgid "ProjectSettings|LFS objects from this repository are available to forks. %{linkStart}How do I remove them?%{linkEnd}"
msgstr ""
+msgid "ProjectSettings|Learn about commit history."
+msgstr ""
+
+msgid "ProjectSettings|Leave empty to use default template."
+msgstr ""
+
msgid "ProjectSettings|Manage who can see the project in the public access directory."
msgstr ""
msgid "ProjectSettings|Manages large files such as audio, video, and graphics files."
msgstr ""
-msgid "ProjectSettings|Maximum 500 characters."
+msgid "ProjectSettings|Maximum %{maxLength} characters."
msgstr ""
msgid "ProjectSettings|Merge checks"
@@ -28330,6 +28943,9 @@ msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
msgstr ""
+msgid "ProjectSettings|The default template will be applied on save."
+msgstr ""
+
msgid "ProjectSettings|These checks must pass before merge requests can be merged."
msgstr ""
@@ -28384,6 +29000,9 @@ msgstr ""
msgid "ProjectSettings|What are badges?"
msgstr ""
+msgid "ProjectSettings|What are merge trains?"
+msgstr ""
+
msgid "ProjectSettings|When merge request pipelines are enabled in the CI/CD configuration file, pipelines validate the combined results of the source and target branches. %{link_start}How to configure merge request pipelines?%{link_end}"
msgstr ""
@@ -28501,6 +29120,9 @@ msgstr ""
msgid "Projects are organized into groups"
msgstr ""
+msgid "Projects are where you store your code, access issues, wiki and other features of GitLab."
+msgstr ""
+
msgid "Projects contributed to"
msgstr ""
@@ -28516,12 +29138,6 @@ msgstr ""
msgid "Projects to index"
msgstr ""
-msgid "Projects will be permanently deleted after a %{waiting_period}-day waiting period."
-msgstr ""
-
-msgid "Projects will be permanently deleted immediately."
-msgstr ""
-
msgid "Projects with critical vulnerabilities"
msgstr ""
@@ -28606,6 +29222,9 @@ msgstr ""
msgid "ProjectsNew|Import project"
msgstr ""
+msgid "ProjectsNew|Include a Getting Started README"
+msgstr ""
+
msgid "ProjectsNew|Initialize repository with a README"
msgstr ""
@@ -28621,6 +29240,9 @@ msgstr ""
msgid "ProjectsNew|Project description %{tag_start}(optional)%{tag_end}"
msgstr ""
+msgid "ProjectsNew|Recommended if you're new to GitLab"
+msgstr ""
+
msgid "ProjectsNew|Run CI/CD for external repository"
msgstr ""
@@ -29038,6 +29660,9 @@ msgstr ""
msgid "ProtectedBranch|Unprotect"
msgstr ""
+msgid "ProtectedBranch|Unprotect branch"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
@@ -29065,6 +29690,9 @@ msgstr ""
msgid "ProtectedEnvironment|Protected Environment (%{protected_environments_count})"
msgstr ""
+msgid "ProtectedEnvironment|Required approvals"
+msgstr ""
+
msgid "ProtectedEnvironment|Select an environment"
msgstr ""
@@ -29086,10 +29714,13 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|Unprotect tag"
+msgstr ""
+
msgid "ProtectedTags|default"
msgstr ""
-msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
+msgid "ProtectedTag|By default, protected tags restrict who can modify the tag."
msgstr ""
msgid "ProtectedTag|Learn more."
@@ -29152,6 +29783,9 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Public projects are an easy way to allow everyone to have read-only access."
+msgstr ""
+
msgid "Publish to status page"
msgstr ""
@@ -29308,9 +29942,6 @@ msgstr ""
msgid "QualitySummary|Project quality"
msgstr ""
-msgid "Quarters"
-msgstr ""
-
msgid "Query"
msgstr ""
@@ -29395,6 +30026,9 @@ msgstr ""
msgid "Read more about project permissions %{help_link_open}here%{help_link_close}"
msgstr ""
+msgid "Read more about related epics"
+msgstr ""
+
msgid "Read more about related issues"
msgstr ""
@@ -29425,10 +30059,7 @@ msgstr ""
msgid "Rebase source branch on the target branch."
msgstr ""
-msgid "Rebase without CI"
-msgstr ""
-
-msgid "Rebases and triggers a pipeline"
+msgid "Rebase without pipeline"
msgstr ""
msgid "Recaptcha verified?"
@@ -29479,9 +30110,6 @@ msgstr ""
msgid "Reconfigure"
msgstr ""
-msgid "Recovering projects"
-msgstr ""
-
msgid "Recovery Codes"
msgstr ""
@@ -29541,6 +30169,12 @@ msgstr ""
msgid "Regex pattern"
msgstr ""
+msgid "Region"
+msgstr ""
+
+msgid "Regions"
+msgstr ""
+
msgid "Register"
msgstr ""
@@ -29771,9 +30405,6 @@ msgstr ""
msgid "Remove all or specific reviewer(s)"
msgstr ""
-msgid "Remove approver"
-msgstr ""
-
msgid "Remove approvers"
msgstr ""
@@ -29789,6 +30420,9 @@ msgstr ""
msgid "Remove attention request"
msgstr ""
+msgid "Remove attention request(s)"
+msgstr ""
+
msgid "Remove avatar"
msgstr ""
@@ -29927,6 +30561,9 @@ msgstr ""
msgid "Removed an issue from an epic."
msgstr ""
+msgid "Removed attention from %{users_sentence}."
+msgstr ""
+
msgid "Removed attention request from @%{username}"
msgstr ""
@@ -29978,6 +30615,9 @@ msgstr ""
msgid "Removes an issue from an epic."
msgstr ""
+msgid "Removes attention from %{users_sentence}."
+msgstr ""
+
msgid "Removes parent epic %{epic_ref}."
msgstr ""
@@ -30089,6 +30729,9 @@ msgstr ""
msgid "Report abuse to admin"
msgstr ""
+msgid "Report is generating and will be sent to your email address."
+msgstr ""
+
msgid "Reported %{timeAgo} by %{reportedBy}"
msgstr ""
@@ -30378,6 +31021,15 @@ msgstr ""
msgid "Request attention"
msgstr ""
+msgid "Request attention from %{users_sentence}."
+msgstr ""
+
+msgid "Request attention from assignee or reviewer"
+msgstr ""
+
+msgid "Request attention from assignee(s) or reviewer(s)"
+msgstr ""
+
msgid "Request attention to review"
msgstr ""
@@ -30402,6 +31054,9 @@ msgstr ""
msgid "Requested %{time_ago}"
msgstr ""
+msgid "Requested attention from %{users_sentence}."
+msgstr ""
+
msgid "Requested attention from @%{username}"
msgstr ""
@@ -30616,6 +31271,9 @@ msgstr ""
msgid "Restore project"
msgstr ""
+msgid "Restoring projects"
+msgstr ""
+
msgid "Restoring the group will prevent the group, its subgroups and projects from being removed on this date."
msgstr ""
@@ -30646,6 +31304,9 @@ msgstr ""
msgid "Retry"
msgstr ""
+msgid "Retry failed jobs"
+msgstr ""
+
msgid "Retry job"
msgstr ""
@@ -30693,9 +31354,6 @@ msgstr ""
msgid "Review changes"
msgstr ""
-msgid "Review requested from %{name}"
-msgstr ""
-
msgid "Review requests for you"
msgstr ""
@@ -30860,6 +31518,9 @@ msgstr ""
msgid "Runners|Assigned Group"
msgstr ""
+msgid "Runners|Assigned Projects (%{projectCount})"
+msgstr ""
+
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30929,6 +31590,9 @@ msgstr ""
msgid "Runners|Instance"
msgstr ""
+msgid "Runners|Jobs"
+msgstr ""
+
msgid "Runners|Last contact"
msgstr ""
@@ -31022,9 +31686,6 @@ msgstr ""
msgid "Runners|Runner %{name} was deleted"
msgstr ""
-msgid "Runners|Runner ID"
-msgstr ""
-
msgid "Runners|Runner assigned to project."
msgstr ""
@@ -31172,6 +31833,9 @@ msgstr ""
msgid "Runners|stale"
msgstr ""
+msgid "Runner|This runner has not run any jobs."
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -31286,6 +31950,24 @@ msgstr ""
msgid "Saving project."
msgstr ""
+msgid "ScanResultPolicy|%{ifLabelStart}if%{ifLabelEnd} %{scanners} scan in an open merge request targeting the %{branches} branch(es) finds %{vulnerabilitiesAllowed} or more %{severities} vulnerabilities that are %{vulnerabilityStates}"
+msgstr ""
+
+msgid "ScanResultPolicy|%{thenLabelStart}Then%{thenLabelEnd} Require approval from %{approvalsRequired} of the following approvers: %{approvers}"
+msgstr ""
+
+msgid "ScanResultPolicy|add an approver"
+msgstr ""
+
+msgid "ScanResultPolicy|scanners"
+msgstr ""
+
+msgid "ScanResultPolicy|severity levels"
+msgstr ""
+
+msgid "ScanResultPolicy|vulnerability states"
+msgstr ""
+
msgid "Scanner"
msgstr ""
@@ -31418,6 +32100,9 @@ msgstr ""
msgid "Search for a user"
msgstr ""
+msgid "Search for an emoji"
+msgstr ""
+
msgid "Search for projects, issues, etc."
msgstr ""
@@ -31605,18 +32290,12 @@ msgstr ""
msgid "Secret Detection"
msgstr ""
-msgid "Secret access key"
-msgstr ""
-
msgid "Secret token"
msgstr ""
msgid "Secure token that identifies an external storage request."
msgstr ""
-msgid "SecureCodeWarrior"
-msgstr ""
-
msgid "Security"
msgstr ""
@@ -31641,9 +32320,6 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "Security training with guide and learning pathways."
-msgstr ""
-
msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
@@ -31746,7 +32422,7 @@ msgstr ""
msgid "SecurityConfiguration|Manage corpus"
msgstr ""
-msgid "SecurityConfiguration|Manage corpus files used as mutation sources in coverage fuzzing."
+msgid "SecurityConfiguration|Manage corpus files used as seed inputs with coverage-guided fuzzing."
msgstr ""
msgid "SecurityConfiguration|Manage profiles for use by DAST scans."
@@ -31812,15 +32488,15 @@ msgstr ""
msgid "SecurityOrchestration|.yaml preview"
msgstr ""
-msgid "SecurityOrchestration|Action"
-msgstr ""
-
msgid "SecurityOrchestration|Actions"
msgstr ""
msgid "SecurityOrchestration|Add rule"
msgstr ""
+msgid "SecurityOrchestration|After dismissing the alert, the information will never be shown again."
+msgstr ""
+
msgid "SecurityOrchestration|All policies"
msgstr ""
@@ -31836,7 +32512,7 @@ msgstr ""
msgid "SecurityOrchestration|Description"
msgstr ""
-msgid "SecurityOrchestration|Disabled"
+msgid "SecurityOrchestration|Don't show the alert anymore"
msgstr ""
msgid "SecurityOrchestration|Edit policy"
@@ -31845,13 +32521,13 @@ msgstr ""
msgid "SecurityOrchestration|Edit policy project"
msgstr ""
-msgid "SecurityOrchestration|Enabled"
+msgid "SecurityOrchestration|Empty policy name"
msgstr ""
-msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Enabled"
msgstr ""
-msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
msgstr ""
msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
@@ -31860,7 +32536,7 @@ msgstr ""
msgid "SecurityOrchestration|Invalid policy type"
msgstr ""
-msgid "SecurityOrchestration|Latest scan"
+msgid "SecurityOrchestration|Latest scan run against %{agent}"
msgstr ""
msgid "SecurityOrchestration|Network"
@@ -31869,15 +32545,27 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No actions defined - policy will not run."
+msgstr ""
+
+msgid "SecurityOrchestration|No description"
+msgstr ""
+
msgid "SecurityOrchestration|No rules defined - policy will not run."
msgstr ""
+msgid "SecurityOrchestration|Not enabled"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
msgid "SecurityOrchestration|Policies"
msgstr ""
+msgid "SecurityOrchestration|Policy Type"
+msgstr ""
+
msgid "SecurityOrchestration|Policy cannot be enabled for non-existing branches (%{branches})"
msgstr ""
@@ -31902,10 +32590,13 @@ msgstr ""
msgid "SecurityOrchestration|Require %{approvals} %{plural} from %{approvers} if any of the following occur:"
msgstr ""
-msgid "SecurityOrchestration|Rule"
+msgid "SecurityOrchestration|Rules"
msgstr ""
-msgid "SecurityOrchestration|Rules"
+msgid "SecurityOrchestration|Runs %{actions} and %{lastAction} scans"
+msgstr ""
+
+msgid "SecurityOrchestration|Runs a %{action} scan"
msgstr ""
msgid "SecurityOrchestration|Scan Execution"
@@ -31965,6 +32656,9 @@ msgstr ""
msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
+msgid "SecurityOrchestration|This view only shows scan results for the agent %{agent}. You can view scan results for all agents in the %{linkStart}Operational Vulnerabilities tab of the vulnerability report%{linkEnd}."
+msgstr ""
+
msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
@@ -32019,9 +32713,6 @@ msgstr ""
msgid "SecurityOrchestration|users with ids"
msgstr ""
-msgid "SecurityOrchestration|view results"
-msgstr ""
-
msgid "SecurityOrchestration|vulnerabilities"
msgstr ""
@@ -32691,22 +33382,19 @@ 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|In order to start using functions as a service, you must first install Knative on your Kubernetes cluster. %{linkStart}More information%{linkEnd}"
-msgstr ""
-
msgid "Serverless|Learn more about Serverless"
msgstr ""
msgid "Serverless|No functions available"
msgstr ""
-msgid "Serverless|Sign up for First Look"
+msgid "Serverless|Serverless was %{linkStart}deprecated%{linkEnd} in GitLab 14.3."
+msgstr ""
+
+msgid "Serverless|Serverless was %{postLinkStart}deprecated%{postLinkEnd}. But if you opt to use it, you must install Knative in your Kubernetes cluster first. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "Serverless|The deploy job has not finished."
@@ -32718,9 +33406,6 @@ 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 ""
@@ -32736,9 +33421,6 @@ msgstr ""
msgid "Service Account Key"
msgstr ""
-msgid "Service Accounts"
-msgstr ""
-
msgid "Service Accounts keys authorize GitLab to deploy your Google Cloud project"
msgstr ""
@@ -32748,10 +33430,10 @@ msgstr ""
msgid "Service Desk allows people to create issues in your GitLab instance without their own user account. It provides a unique email address for end users to create issues in a project. Replies can be sent either through the GitLab interface or by email. End users only see threads through email."
msgstr ""
-msgid "Service Usage Data"
+msgid "Service account generated successfully"
msgstr ""
-msgid "Service account generated successfully"
+msgid "Service accounts"
msgstr ""
msgid "Service ping is disabled in your configuration file, and cannot be enabled through this form."
@@ -32895,6 +33577,9 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
+msgid "Set the per-user rate limit for getting a user by ID via the API."
+msgstr ""
+
msgid "Set the per-user rate limit for notes created by web or API requests."
msgstr ""
@@ -33074,6 +33759,9 @@ msgstr ""
msgid "Shared runners details"
msgstr ""
+msgid "Shared runners enabled cannot be enabled until a valid credit card is on file"
+msgstr ""
+
msgid "Shared runners help link"
msgstr ""
@@ -33131,6 +33819,9 @@ msgstr ""
msgid "Show all issues."
msgstr ""
+msgid "Show all milestones"
+msgstr ""
+
msgid "Show all test cases."
msgstr ""
@@ -33167,6 +33858,9 @@ msgstr ""
msgid "Show file contents"
msgstr ""
+msgid "Show group milestones"
+msgstr ""
+
msgid "Show labels"
msgstr ""
@@ -33182,6 +33876,12 @@ msgstr ""
msgid "Show open epics"
msgstr ""
+msgid "Show project milestones"
+msgstr ""
+
+msgid "Show sub-group milestones"
+msgstr ""
+
msgid "Show the Closed list"
msgstr ""
@@ -33191,11 +33891,6 @@ msgstr ""
msgid "Show whitespace changes"
msgstr ""
-msgid "Showing %d event"
-msgid_plural "Showing %d events"
-msgstr[0] "Показване на %d Ñъбитие"
-msgstr[1] "Показване на %d ÑъбитиÑ"
-
msgid "Showing %{conflict} between %{sourceBranch} and %{targetBranch}"
msgstr ""
@@ -33255,12 +33950,6 @@ msgstr ""
msgid "Sidebar|None"
msgstr ""
-msgid "Sidebar|Only numeral characters allowed"
-msgstr ""
-
-msgid "Sidebar|Weight"
-msgstr ""
-
msgid "Sidekiq job compression threshold (bytes)"
msgstr ""
@@ -33423,6 +34112,9 @@ msgstr ""
msgid "Slack logo"
msgstr ""
+msgid "SlackIntegration|Are you sure you want to remove this project from the Slack application?"
+msgstr ""
+
msgid "SlackIntegration|GitLab for Slack"
msgstr ""
@@ -33432,6 +34124,9 @@ msgstr ""
msgid "SlackIntegration|Project alias"
msgstr ""
+msgid "SlackIntegration|Remove project"
+msgstr ""
+
msgid "SlackIntegration|Select a GitLab project to link with your Slack workspace."
msgstr ""
@@ -33576,9 +34271,6 @@ msgstr ""
msgid "Something went wrong trying to load issue contacts."
msgstr ""
-msgid "Something went wrong when creating a work item. Please try again"
-msgstr ""
-
msgid "Something went wrong when reordering designs. Please try again"
msgstr ""
@@ -33672,9 +34364,6 @@ msgstr ""
msgid "Something went wrong while inserting your image. Please try again."
msgstr ""
-msgid "Something went wrong while merging this merge request. Please try again."
-msgstr ""
-
msgid "Something went wrong while obtaining the Let's Encrypt certificate."
msgstr ""
@@ -33996,10 +34685,10 @@ 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."
+msgid "SourcegraphAdmin|Learn more."
msgstr ""
-msgid "SourcegraphAdmin|More information"
+msgid "SourcegraphAdmin|Only public projects have code intelligence enabled and communicate with Sourcegraph."
msgstr ""
msgid "SourcegraphAdmin|Save changes"
@@ -34008,7 +34697,7 @@ msgstr ""
msgid "SourcegraphAdmin|Sourcegraph URL"
msgstr ""
-msgid "SourcegraphAdmin|e.g. https://sourcegraph.example.com"
+msgid "SourcegraphAdmin|https://sourcegraph.example.com"
msgstr ""
msgid "SourcegraphPreferences|This feature is experimental and currently limited to certain projects."
@@ -34143,6 +34832,9 @@ msgstr ""
msgid "Start date"
msgstr ""
+msgid "Start free trial"
+msgstr ""
+
msgid "Start merge train"
msgstr ""
@@ -34173,6 +34865,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started escalation for this incident."
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -34185,6 +34880,9 @@ msgstr ""
msgid "Starts at (UTC)"
msgstr ""
+msgid "Starts escalations for this incident"
+msgstr ""
+
msgid "Starts on"
msgstr ""
@@ -34446,6 +35144,9 @@ msgstr ""
msgid "Strikethrough"
msgstr ""
+msgid "Strikethrough text"
+msgstr ""
+
msgid "Subgroup information"
msgstr ""
@@ -34680,6 +35381,21 @@ msgstr ""
msgid "Subscriptions"
msgstr ""
+msgid "Subscriptions|Chat with sales"
+msgstr ""
+
+msgid "Subscriptions|Close"
+msgstr ""
+
+msgid "Subscriptions|Not ready to buy yet?"
+msgstr ""
+
+msgid "Subscriptions|Start a free trial"
+msgstr ""
+
+msgid "Subscriptions|We understand. Maybe you have some questions for our sales team, or maybe you'd like to try some of the paid features first. What would you like to do?"
+msgstr ""
+
msgid "Subscription|Your subscription for %{strong}%{namespace_name}%{strong_close} has expired and you are now on %{pricing_link_start}the GitLab Free tier%{pricing_link_end}. Don't worry, your data is safe. Get in touch with our support team (%{support_email}). They'll gladly help with your subscription renewal."
msgstr ""
@@ -34890,6 +35606,9 @@ msgstr ""
msgid "SuperSonics|Maximum users"
msgstr ""
+msgid "SuperSonics|Offline cloud"
+msgstr ""
+
msgid "SuperSonics|Paste your activation code"
msgstr ""
@@ -34956,6 +35675,12 @@ msgstr ""
msgid "SuperSonics|You do not have an active subscription"
msgstr ""
+msgid "SuperSonics|You have a future dated license"
+msgstr ""
+
+msgid "SuperSonics|You have added a license that activates on %{date}. Please see the subscription history table below for more details."
+msgstr ""
+
msgid "SuperSonics|You have successfully added a license that activates on %{date}. Please see the subscription history table below for more details."
msgstr ""
@@ -35115,6 +35840,9 @@ msgstr ""
msgid "Tag name is required"
msgstr ""
+msgid "Tag push"
+msgstr ""
+
msgid "Tag push events"
msgstr ""
@@ -35217,6 +35945,9 @@ msgstr ""
msgid "TagsPage|protected"
msgstr ""
+msgid "Take a look at the documentation to discover all of GitLab’s capabilities."
+msgstr ""
+
msgid "Target Branch"
msgstr "Целеви клон"
@@ -35619,6 +36350,9 @@ msgstr ""
msgid "Tests"
msgstr ""
+msgid "Text (optional)"
+msgstr ""
+
msgid "Text added to the body of all email messages. %{character_limit} character limit"
msgstr ""
@@ -35669,6 +36403,9 @@ msgstr ""
msgid "The CSV export will be created in the background. Once finished, it will be sent to %{email} in an attachment."
msgstr ""
+msgid "The CSV export you requested of all user memberships is attached to this email."
+msgstr ""
+
msgid "The GitLab subscription service (customers.gitlab.com) is currently experiencing an outage. You can monitor the status and get updates at %{linkStart}status.gitlab.com%{linkEnd}."
msgstr ""
@@ -35744,6 +36481,9 @@ 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 epic"
+msgstr ""
+
msgid "The current issue"
msgstr ""
@@ -35905,6 +36645,9 @@ msgstr ""
msgid "The latest pipeline for this merge request has failed."
msgstr ""
+msgid "The license key is invalid."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -35920,6 +36663,9 @@ msgstr ""
msgid "The license was successfully uploaded and will be active from %{starts_at}. You can see the details below."
msgstr ""
+msgid "The license you uploaded is invalid. If the issue persists, contact support at %{link}."
+msgstr ""
+
msgid "The list creation wizard is already open"
msgstr ""
@@ -36541,10 +37287,13 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} and everything this project contains. %{strongOpen}There is no going back%{strongClose}"
+msgstr ""
+
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains."
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}on %{date}%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains. %{strongOpen}There is no going back.%{strongClose}"
msgstr ""
msgid "This action will %{strongOpen}permanently remove%{strongClose} %{codeOpen}%{group}%{codeClose} %{strongOpen}immediately%{strongClose}."
@@ -36673,9 +37422,6 @@ msgstr ""
msgid "This file was modified for readability, and can't accept suggestions. Edit it directly."
msgstr ""
-msgid "This forked project has the following:"
-msgstr ""
-
msgid "This form is disabled in preview"
msgstr ""
@@ -36688,7 +37434,7 @@ msgstr ""
msgid "This group can't be removed because it is linked to a subscription. To remove this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
-msgid "This group can't be transfered because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
+msgid "This group can't be transferred because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
msgid "This group cannot be invited to a project inside a group with enforced SSO"
@@ -36715,6 +37461,9 @@ 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 incident is already escalated with '%{escalation_policy_name}'."
+msgstr ""
+
msgid "This invitation was sent to %{mail_to_invite_email}, but you are signed in as %{link_to_current_user} with email %{mail_to_current_user}."
msgstr ""
@@ -36733,9 +37482,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 merge train pipeline"
-msgstr ""
-
msgid "This is a private email address %{helpIcon} generated just for you. Anyone who has it can create issues or merge requests as if they were you. If that happens, %{resetLinkStart}reset this token%{resetLinkEnd}."
msgstr ""
@@ -36757,6 +37503,12 @@ msgstr ""
msgid "This is your current session"
msgstr ""
+msgid "This issue cannot be assigned to a confidential epic because it is public."
+msgstr ""
+
+msgid "This issue cannot be made public because it belongs to a confidential epic."
+msgstr ""
+
msgid "This issue is confidential and should only be visible to team members with at least Reporter access."
msgstr ""
@@ -36874,6 +37626,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 branch is protected from force push."
+msgstr ""
+
msgid "This merge request cannot be rebased while there are conflicts."
msgstr ""
@@ -36925,9 +37680,15 @@ msgstr ""
msgid "This pipeline was triggered by a schedule."
msgstr ""
+msgid "This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project"
msgstr ""
+msgid "This project can be restored until %{date}."
+msgstr ""
+
msgid "This project cannot be %{visibilityLevel} because the visibility of %{openShowLink}%{name}%{closeShowLink} is %{visibility}. To make this project %{visibilityLevel}, you must first %{openEditLink}change the visibility%{closeEditLink} of the parent group."
msgstr ""
@@ -36946,6 +37707,9 @@ msgstr ""
msgid "This project is %{strongStart}NOT%{strongEnd} a fork, and has the following:"
msgstr ""
+msgid "This project is %{strongStart}NOT%{strongEnd} a fork. This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -37637,6 +38401,9 @@ msgstr ""
msgid "Today"
msgstr ""
+msgid "Todos count"
+msgstr ""
+
msgid "Todos|Are you looking for things to do? Take a look at %{strongStart}%{openIssuesLinkStart}open issues%{openIssuesLinkEnd}%{strongEnd}, contribute to %{strongStart}%{mergeRequestLinkStart}a merge request%{mergeRequestLinkEnd}%{mergeRequestLinkEnd}%{strongEnd}, or mention someone in a comment to automatically assign them a new to-do item."
msgstr ""
@@ -37910,10 +38677,8 @@ msgstr ""
msgid "Trending"
msgstr ""
-msgid "Trials|%{planName} Trial %{enDash} %{num} day left"
-msgid_plural "Trials|%{planName} Trial %{enDash} %{num} days left"
-msgstr[0] ""
-msgstr[1] ""
+msgid "Trials|%{planName} Trial"
+msgstr ""
msgid "Trials|Compare all plans"
msgstr ""
@@ -37921,6 +38686,9 @@ msgstr ""
msgid "Trials|Create a new group to start your GitLab Ultimate trial."
msgstr ""
+msgid "Trials|Day %{daysUsed}/%{duration}"
+msgstr ""
+
msgid "Trials|Go back to GitLab"
msgstr ""
@@ -38170,7 +38938,7 @@ msgstr ""
msgid "URL is triggered when repository is updated"
msgstr ""
-msgid "URL must be percent-encoded if neccessary."
+msgid "URL must be percent-encoded if necessary."
msgstr ""
msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
@@ -38389,6 +39157,9 @@ msgstr ""
msgid "Unlock account"
msgstr ""
+msgid "Unlock more features with GitLab Ultimate"
+msgstr ""
+
msgid "Unlock the discussion"
msgstr ""
@@ -38452,6 +39223,9 @@ msgstr ""
msgid "Unsubscribes from this %{quick_action_target}."
msgstr ""
+msgid "Unsupported sort value."
+msgstr ""
+
msgid "Unsupported todo type passed. Supported todo types are: %{todo_types}"
msgstr ""
@@ -38680,6 +39454,9 @@ msgstr ""
msgid "UsageQuota|File attachments and smaller design graphics."
msgstr ""
+msgid "UsageQuota|From %{storage_enforcement_date} storage limits will apply to this namespace. View and manage your usage in %{strong_start}Group Settings &gt; Usage quotas%{strong_end}."
+msgstr ""
+
msgid "UsageQuota|Git repository."
msgstr ""
@@ -38740,6 +39517,9 @@ msgstr ""
msgid "UsageQuota|Storage type"
msgstr ""
+msgid "UsageQuota|Storage used"
+msgstr ""
+
msgid "UsageQuota|This is the total amount of storage used across your projects within this namespace."
msgstr ""
@@ -38935,6 +39715,12 @@ msgstr ""
msgid "Use hashed storage paths for newly created and renamed repositories. Always enabled since 13.0."
msgstr ""
+msgid "Use issue count"
+msgstr ""
+
+msgid "Use issue weight"
+msgstr ""
+
msgid "Use one line per URI"
msgstr ""
@@ -39316,6 +40102,9 @@ msgstr ""
msgid "Users"
msgstr ""
+msgid "Users API rate limit"
+msgstr ""
+
msgid "Users can launch a development environment from a GitLab browser tab when the %{linkStart}Gitpod%{linkEnd} integration is enabled."
msgstr ""
@@ -39641,6 +40430,9 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View group pipeline usage quota"
+msgstr ""
+
msgid "View incident details at"
msgstr ""
@@ -39793,6 +40585,9 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
+msgid "Vulnerability"
+msgstr ""
+
msgid "Vulnerability Report"
msgstr ""
@@ -39844,6 +40639,9 @@ msgstr ""
msgid "VulnerabilityManagement|An unverified non-confirmed finding"
msgstr ""
+msgid "VulnerabilityManagement|At least one identifier is required"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -39853,12 +40651,24 @@ msgstr ""
msgid "VulnerabilityManagement|Create Jira issue"
msgstr ""
+msgid "VulnerabilityManagement|Enter a name"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE code"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE identifier URL"
+msgstr ""
+
msgid "VulnerabilityManagement|Fetching linked Jira issues"
msgstr ""
msgid "VulnerabilityManagement|Manually add a vulnerability entry into the vulnerability report."
msgstr ""
+msgid "VulnerabilityManagement|Name is a required field"
+msgstr ""
+
msgid "VulnerabilityManagement|Needs triage"
msgstr ""
@@ -39874,6 +40684,18 @@ msgstr ""
msgid "VulnerabilityManagement|Select a method"
msgstr ""
+msgid "VulnerabilityManagement|Select a severity level"
+msgstr ""
+
+msgid "VulnerabilityManagement|Select a status"
+msgstr ""
+
+msgid "VulnerabilityManagement|Severity is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Something went wrong while creating vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -39898,6 +40720,12 @@ msgstr ""
msgid "VulnerabilityManagement|Something went wrong, could not update vulnerability state."
msgstr ""
+msgid "VulnerabilityManagement|Status is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Submit vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Summary, detailed description, steps to reproduce, etc."
msgstr ""
@@ -40093,6 +40921,9 @@ msgstr ""
msgid "WARNING:"
msgstr ""
+msgid "WARNING: This snippet contains hidden files which might be used to mask malicious behavior. Exercise caution if cloning and executing code from this snippet."
+msgstr ""
+
msgid "Wait for the file to load to copy its contents"
msgstr ""
@@ -40312,6 +41143,15 @@ msgstr ""
msgid "Webhooks|An issue is created, updated, closed, or reopened."
msgstr ""
+msgid "Webhooks|Are you sure you want to delete this group hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this project hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this webhook?"
+msgstr ""
+
msgid "Webhooks|Comments"
msgstr ""
@@ -40321,6 +41161,9 @@ msgstr ""
msgid "Webhooks|Confidential issues events"
msgstr ""
+msgid "Webhooks|Delete webhook"
+msgstr ""
+
msgid "Webhooks|Deployment events"
msgstr ""
@@ -40554,6 +41397,9 @@ msgstr ""
msgid "Wiki"
msgstr ""
+msgid "Wiki page"
+msgstr ""
+
msgid "Wiki page was successfully created."
msgstr ""
@@ -40659,7 +41505,7 @@ msgstr ""
msgid "WikiPageConflictMessage|Someone edited the page the same time you did. Please check out %{wikiLinkStart}the page%{wikiLinkEnd} and make sure your changes will not unintentionally remove theirs."
msgstr ""
-msgid "WikiPage|An error occured while trying to render the content editor. Please try again later."
+msgid "WikiPage|An error occurred while trying to render the content editor. Please try again later."
msgstr ""
msgid "WikiPage|Are you sure you want to switch back to the classic editor?"
@@ -40818,6 +41664,18 @@ msgstr ""
msgid "WorkItem|New Task"
msgstr ""
+msgid "WorkItem|Something went wrong when creating a work item. Please try again"
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching the work item. Please try again."
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching work item types. Please try again"
+msgstr ""
+
+msgid "WorkItem|Type"
+msgstr ""
+
msgid "WorkItem|Work Items"
msgstr ""
@@ -40884,7 +41742,10 @@ msgstr ""
msgid "You are about to add %{usersTag} people to the discussion. They will all receive a notification."
msgstr ""
-msgid "You are about to permanently delete this project"
+msgid "You are about to delete this forked project containing:"
+msgstr ""
+
+msgid "You are about to delete this project containing:"
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."
@@ -40905,6 +41766,9 @@ msgstr ""
msgid "You are attempting to update a file that has changed since you started editing it."
msgstr ""
+msgid "You are billed if you exceed this number. %{qsrOverageLinkStart}How does billing work?%{qsrOverageLinkEnd}"
+msgstr ""
+
msgid "You are connected to the Prometheus server, but there is currently no data to display."
msgstr ""
@@ -40962,6 +41826,9 @@ msgstr ""
msgid "You are not authorized to update this scanner profile"
msgstr ""
+msgid "You are not authorized to upload metric images"
+msgstr ""
+
msgid "You are now impersonating %{username}"
msgstr ""
@@ -41115,9 +41982,6 @@ msgstr ""
msgid "You can only upload one design when dropping onto an existing design."
msgstr ""
-msgid "You can recover this project until %{date}"
-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 ""
@@ -41166,9 +42030,6 @@ msgstr ""
msgid "You cannot write to this read-only GitLab instance."
msgstr ""
-msgid "You can’t %{tag_start}edit%{tag_end} files directly in this project. Fork this project and submit a merge request with your changes."
-msgstr ""
-
msgid "You can’t edit files directly in this project. Fork this project and submit a merge request with your changes."
msgstr ""
@@ -41321,9 +42182,6 @@ 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 set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
@@ -41354,12 +42212,6 @@ msgstr ""
msgid "You must have maintainer access to force delete a lock"
msgstr ""
-msgid "You must have permission to create a project in a group before forking."
-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 ""
@@ -41765,7 +42617,7 @@ msgstr ""
msgid "Your public email will be displayed on your public profile."
msgstr ""
-msgid "Your request for access could not be processed: %{error_meesage}"
+msgid "Your request for access could not be processed: %{error_message}"
msgstr ""
msgid "Your request for access has been queued for review."
@@ -41948,6 +42800,9 @@ msgstr ""
msgid "archived:"
msgstr ""
+msgid "artifacts"
+msgstr ""
+
msgid "assign yourself"
msgstr ""
@@ -41977,6 +42832,9 @@ msgstr[1] ""
msgid "branch name"
msgstr ""
+msgid "builds"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -42400,6 +43258,9 @@ msgstr ""
msgid "contact with same email already exists in group hierarchy"
msgstr ""
+msgid "container registry images"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -42439,6 +43300,9 @@ msgstr ""
msgid "data"
msgstr ""
+msgid "database"
+msgstr ""
+
msgid "date must not be after 9999-12-31"
msgstr ""
@@ -42462,9 +43326,6 @@ msgstr ""
msgid "design"
msgstr ""
-msgid "detached"
-msgstr ""
-
msgid "disabled"
msgstr ""
@@ -42713,7 +43574,7 @@ msgstr ""
msgid "is not a valid X509 certificate."
msgstr ""
-msgid "is not allowed for sign-up."
+msgid "is not allowed for sign-up. Please use your regular email address."
msgstr ""
msgid "is not allowed for this group."
@@ -42725,7 +43586,7 @@ msgstr ""
msgid "is not allowed since the group is not top-level group."
msgstr ""
-msgid "is not allowed."
+msgid "is not allowed. Please use your regular email address."
msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
@@ -42812,6 +43673,9 @@ msgstr ""
msgid "level: %{level}"
msgstr ""
+msgid "lfs objects"
+msgstr ""
+
msgid "limit of %{project_limit} reached"
msgstr ""
@@ -43031,6 +43895,9 @@ msgstr ""
msgid "mrWidget|Merge blocked: pipeline must succeed. It's waiting for a manual action to continue."
msgstr ""
+msgid "mrWidget|Merge blocked: pipeline must succeed. Push a commit that fixes the failure, or %{linkStart}learn about other solutions.%{linkEnd}"
+msgstr ""
+
msgid "mrWidget|Merge blocked: this merge request must be approved."
msgstr ""
@@ -43148,9 +44015,6 @@ msgstr ""
msgid "mrWidget|The changes were not merged into"
msgstr ""
-msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -43298,9 +44162,6 @@ msgstr ""
msgid "open issue"
msgstr ""
-msgid "opened %{timeAgo}"
-msgstr ""
-
msgid "or"
msgstr ""
@@ -43312,6 +44173,12 @@ msgid_plural "out of %d total tests"
msgstr[0] ""
msgstr[1] ""
+msgid "packages"
+msgstr ""
+
+msgid "pages"
+msgstr ""
+
msgid "parent"
msgid_plural "parents"
msgstr[0] "родител"
@@ -43461,6 +44328,9 @@ msgid_plural "replies"
msgstr[0] ""
msgstr[1] ""
+msgid "repositories"
+msgstr ""
+
msgid "repository:"
msgstr ""
@@ -43581,12 +44451,18 @@ msgstr ""
msgid "tag name"
msgstr ""
+msgid "terraform states"
+msgstr ""
+
msgid "the correct format."
msgstr ""
msgid "the file"
msgstr ""
+msgid "the following epic(s)"
+msgstr ""
+
msgid "the following issue(s)"
msgstr ""
@@ -43599,21 +44475,12 @@ msgstr ""
msgid "this document"
msgstr ""
-msgid "this issue cannot be assigned to a confidential epic since it is public"
-msgstr ""
-
-msgid "this issue cannot be made public since it belongs to a confidential epic"
-msgstr ""
-
msgid "time summary"
msgstr ""
msgid "toggle collapse"
msgstr ""
-msgid "train"
-msgstr ""
-
msgid "triggered"
msgstr ""
@@ -43742,3 +44609,6 @@ msgstr ""
msgid "{project}"
msgstr ""
+msgid "✔"
+msgstr ""
+
diff --git a/locale/bn_BD/gitlab.po b/locale/bn_BD/gitlab.po
index ee0818fc56b..0f9699254af 100644
--- a/locale/bn_BD/gitlab.po
+++ b/locale/bn_BD/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: bn\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2022-02-02 15:43\n"
+"PO-Revision-Date: 2022-03-01 20:37\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -146,6 +146,11 @@ msgid_plural "%d approvers (you've approved)"
msgstr[0] ""
msgstr[1] ""
+msgid "%d assigned issue"
+msgid_plural "%d assigned issues"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -421,8 +426,23 @@ msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
msgstr[1] ""
-msgid "%d vulnerability updated"
-msgid_plural "%d vulnerabilities updated"
+msgid "%d vulnerability set to confirmed"
+msgid_plural "%d vulnerabilities set to confirmed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to dismissed"
+msgid_plural "%d vulnerabilities set to dismissed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to needs triage"
+msgid_plural "%d vulnerabilities set to needs triage"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to resolved"
+msgid_plural "%d vulnerabilities set to resolved"
msgstr[0] ""
msgstr[1] ""
@@ -510,6 +530,12 @@ msgstr[1] ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{completed} of %{total} issues closed"
+msgstr ""
+
+msgid "%{completed} of %{total} weight completed"
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -858,6 +884,9 @@ msgstr ""
msgid "%{openedIssues} open, %{closedIssues} closed"
msgstr ""
+msgid "%{percentage}%% issues closed"
+msgstr ""
+
msgid "%{percentage}%% weight completed"
msgstr ""
@@ -1287,6 +1316,9 @@ msgid_plural "- Users"
msgstr[0] ""
msgstr[1] ""
+msgid "- of - issues closed"
+msgstr ""
+
msgid "- of - weight completed"
msgstr ""
@@ -1429,7 +1461,7 @@ msgstr ""
msgid "1000+"
msgstr ""
-msgid "192.168.0.0/24"
+msgid "192.168.0.0/24 or 2001:0DB8:1234::/48"
msgstr ""
msgid "1st contribution!"
@@ -1741,13 +1773,13 @@ msgstr ""
msgid "AWS Access Key"
msgstr ""
-msgid "AWS Access Key. Only required if not using role instance credentials"
+msgid "AWS Secret Access Key"
msgstr ""
-msgid "AWS Secret Access Key"
+msgid "AWS access key ID (Optional)"
msgstr ""
-msgid "AWS Secret Access Key. Only required if not using role instance credentials"
+msgid "AWS secret access key (Optional)"
msgstr ""
msgid "AWS service error: %{error}"
@@ -1807,9 +1839,6 @@ msgstr ""
msgid "Access granted"
msgstr ""
-msgid "Access key ID"
-msgstr ""
-
msgid "Access requests"
msgstr ""
@@ -1984,7 +2013,7 @@ msgstr ""
msgid "Activity"
msgstr ""
-msgid "Activity|An error occured while retrieving activity. Reload the page to try again."
+msgid "Activity|An error occurred while retrieving activity. Reload the page to try again."
msgstr ""
msgid "Add"
@@ -2023,6 +2052,9 @@ msgstr ""
msgid "Add a %{type}"
msgstr ""
+msgid "Add a GCP region"
+msgstr ""
+
msgid "Add a GPG key"
msgstr ""
@@ -2074,6 +2106,9 @@ msgstr ""
msgid "Add a numbered list"
msgstr ""
+msgid "Add a related epic"
+msgstr ""
+
msgid "Add a related issue"
msgstr ""
@@ -2188,6 +2223,9 @@ msgstr ""
msgid "Add or subtract spent time"
msgstr ""
+msgid "Add people"
+msgstr ""
+
msgid "Add previously merged commits"
msgstr ""
@@ -2254,6 +2292,9 @@ msgstr ""
msgid "Add webhook"
msgstr ""
+msgid "Add your team members and others to GitLab."
+msgstr ""
+
msgid "Add/remove"
msgstr ""
@@ -3076,12 +3117,6 @@ msgstr ""
msgid "AdvancedSearch|Reindex required"
msgstr ""
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. Permanently deleting this project will %{strongStart}immediately delete%{strongEnd} its repositories and %{strongStart}all related resources%{strongEnd}, including issues, merge requests etc."
-msgstr ""
-
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. You will lose this project's repository and %{strongStart}all related resources%{strongEnd}, including issues and merge requests."
-msgstr ""
-
msgid "After a successful password update you will be redirected to login screen."
msgstr ""
@@ -3112,6 +3147,9 @@ msgstr ""
msgid "Akismet helps prevent the creation of spam issues in public projects."
msgstr ""
+msgid "Alert"
+msgstr ""
+
msgid "AlertManagement|Acknowledged"
msgstr ""
@@ -3484,9 +3522,6 @@ msgstr ""
msgid "All environments"
msgstr ""
-msgid "All epics"
-msgstr ""
-
msgid "All groups and projects"
msgstr ""
@@ -4223,12 +4258,15 @@ msgstr ""
msgid "ApplicationSettings|Approve users in the pending approval status?"
msgstr ""
-msgid "ApplicationSettings|By making this change, you will automatically approve %d user with the pending approval status."
-msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users with the pending approval status."
+msgid "ApplicationSettings|Approve users who are pending approval?"
+msgstr ""
+
+msgid "ApplicationSettings|By making this change, you will automatically approve %d user who is pending approval."
+msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users who are pending approval."
msgstr[0] ""
msgstr[1] ""
-msgid "ApplicationSettings|By making this change, you will automatically approve all users in pending approval status."
+msgid "ApplicationSettings|By making this change, you will automatically approve all users who are pending approval."
msgstr ""
msgid "ApplicationSettings|Denied domains for sign-ups"
@@ -4634,10 +4672,10 @@ msgstr ""
msgid "Archiving the project will make it entirely read-only. It is hidden from the dashboard and doesn't show up in searches. %{strong_start}The repository cannot be committed to, and no issues, comments, or other entities can be created.%{strong_end} %{link_start}Learn more.%{link_end}"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to delete this project?"
+msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
+msgid "Are you absolutely sure?"
msgstr ""
msgid "Are you sure that you want to archive this project?"
@@ -4673,12 +4711,18 @@ msgstr ""
msgid "Are you sure you want to delete this SSH key?"
msgstr ""
+msgid "Are you sure you want to delete this comment?"
+msgstr ""
+
msgid "Are you sure you want to delete this deploy key?"
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 label?"
+msgstr ""
+
msgid "Are you sure you want to delete this pipeline schedule?"
msgstr ""
@@ -4694,9 +4738,6 @@ msgstr ""
msgid "Are you sure you want to discard your changes?"
msgstr ""
-msgid "Are you sure you want to erase this build?"
-msgstr ""
-
msgid "Are you sure you want to import %d repository?"
msgid_plural "Are you sure you want to import %d repositories?"
msgstr[0] ""
@@ -4744,6 +4785,9 @@ msgstr ""
msgid "Are you sure you want to remove this list?"
msgstr ""
+msgid "Are you sure you want to remove this nickname?"
+msgstr ""
+
msgid "Are you sure you want to reset the health check token?"
msgstr ""
@@ -4756,10 +4800,10 @@ 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?"
+msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
msgstr ""
-msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
+msgid "Are you sure you want to revoke this project access token? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to stop this environment?"
@@ -4906,9 +4950,6 @@ msgstr ""
msgid "Assigned to %{assignee_name}"
msgstr ""
-msgid "Assigned to %{name}"
-msgstr ""
-
msgid "Assigned to me"
msgstr ""
@@ -4973,6 +5014,9 @@ msgstr[1] ""
msgid "Attaching the file failed."
msgstr ""
+msgid "Attention"
+msgstr ""
+
msgid "Audit Events"
msgstr ""
@@ -5135,6 +5179,12 @@ msgstr ""
msgid "Authorized applications (%{size})"
msgstr ""
+msgid "AuthorizedApplication|Are you sure you want to revoke this application?"
+msgstr ""
+
+msgid "AuthorizedApplication|Revoke application"
+msgstr ""
+
msgid "Authors: %{authors}"
msgstr ""
@@ -6328,6 +6378,9 @@ msgstr ""
msgid "CICDAnalytics|Shared Runners Usage"
msgstr ""
+msgid "CICDAnalytics|Shared runner pipeline minute duration by month"
+msgstr ""
+
msgid "CICDAnalytics|Shared runner usage"
msgstr ""
@@ -6469,6 +6522,9 @@ msgstr ""
msgid "Can create groups:"
msgstr ""
+msgid "Can not delete primary training"
+msgstr ""
+
msgid "Can't apply as the source branch was deleted."
msgstr ""
@@ -6802,9 +6858,6 @@ msgstr ""
msgid "Changing any setting here requires an application restart"
msgstr ""
-msgid "Changing group URL can have unintended side effects."
-msgstr ""
-
msgid "Charts can't be displayed as the request for data has timed out. %{documentationLink}"
msgstr ""
@@ -6892,9 +6945,6 @@ msgstr ""
msgid "Checking branch availability..."
msgstr ""
-msgid "Checking group URL availability..."
-msgstr ""
-
msgid "Checking group path availability..."
msgstr ""
@@ -7388,6 +7438,9 @@ msgstr ""
msgid "Clear recent searches"
msgstr ""
+msgid "Clear repository checks"
+msgstr ""
+
msgid "Clear search"
msgstr ""
@@ -7520,9 +7573,6 @@ msgstr ""
msgid "Closed MRs"
msgstr ""
-msgid "Closed epics"
-msgstr ""
-
msgid "Closed issues"
msgstr ""
@@ -7559,13 +7609,13 @@ msgstr ""
msgid "Cluster level"
msgstr ""
-msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
+msgid "Cluster type must be specified for Stages::ClusterEndpointInserter"
msgstr ""
msgid "ClusterAgents|%{name} successfully deleted"
msgstr ""
-msgid "ClusterAgents|%{number} of %{total} Agents"
+msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
@@ -7607,6 +7657,15 @@ msgstr ""
msgid "ClusterAgents|Agent never connected to GitLab"
msgstr ""
+msgid "ClusterAgents|Agent version mismatch"
+msgstr ""
+
+msgid "ClusterAgents|Agent version mismatch and update"
+msgstr ""
+
+msgid "ClusterAgents|Agent version update required"
+msgstr ""
+
msgid "ClusterAgents|All"
msgstr ""
@@ -7631,7 +7690,7 @@ msgstr ""
msgid "ClusterAgents|Configuration"
msgstr ""
-msgid "ClusterAgents|Connect a cluster through the Agent"
+msgid "ClusterAgents|Connect a cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connect existing cluster"
@@ -7640,13 +7699,13 @@ msgstr ""
msgid "ClusterAgents|Connect with a certificate"
msgstr ""
-msgid "ClusterAgents|Connect with agent"
+msgid "ClusterAgents|Connect with an agent"
msgstr ""
msgid "ClusterAgents|Connect with the GitLab Agent"
msgstr ""
-msgid "ClusterAgents|Connect your cluster through the Agent"
+msgid "ClusterAgents|Connect your cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connected"
@@ -7706,7 +7765,10 @@ msgstr ""
msgid "ClusterAgents|How to register an agent?"
msgstr ""
-msgid "ClusterAgents|Install new Agent"
+msgid "ClusterAgents|How to update an agent?"
+msgstr ""
+
+msgid "ClusterAgents|Install a new agent"
msgstr ""
msgid "ClusterAgents|Last connected %{timeAgo}."
@@ -7733,7 +7795,7 @@ msgstr ""
msgid "ClusterAgents|Never connected"
msgstr ""
-msgid "ClusterAgents|No Agents"
+msgid "ClusterAgents|No agents"
msgstr ""
msgid "ClusterAgents|No clusters connected through cluster certificates"
@@ -7793,6 +7855,9 @@ msgstr ""
msgid "ClusterAgents|The agent has not been connected in a long time. There might be a connectivity issue. Last contact was %{timeAgo}."
msgstr ""
+msgid "ClusterAgents|The agent version do not match each other across your cluster's pods. This can happen when a new agent version was just deployed and Kubernetes is shutting down the old pods."
+msgstr ""
+
msgid "ClusterAgents|The recommended installation method includes the token. If you want to follow the advanced installation method provided in the docs, make sure you save the token value before you close this window."
msgstr ""
@@ -7840,6 +7905,9 @@ msgstr ""
msgid "ClusterAgents|You will need to create a token to connect to your agent"
msgstr ""
+msgid "ClusterAgents|Your agent version is out of sync with your GitLab version (v%{version}), which might cause compatibility problems. Update the agent installed on your cluster to the most recent version."
+msgstr ""
+
msgid "ClusterAgents|Your instance doesn't have the %{linkStart}GitLab Agent Server (KAS)%{linkEnd} set up. Ask a GitLab Administrator to install it."
msgstr ""
@@ -8716,9 +8784,6 @@ msgstr ""
msgid "Comma-separated list of email addresses."
msgstr ""
-msgid "Comma-separated list of users allowed to exceed the rate limit."
-msgstr ""
-
msgid "Comma-separated, e.g. '1.1.1.1, 2.2.2.0/24'"
msgstr ""
@@ -9045,6 +9110,12 @@ msgstr ""
msgid "Confidential"
msgstr ""
+msgid "Confidential issue"
+msgstr ""
+
+msgid "Confidential note"
+msgstr ""
+
msgid "Confidentiality"
msgstr ""
@@ -9078,6 +9149,9 @@ msgstr ""
msgid "Configure Dependency Scanning in `.gitlab-ci.yml`, creating this file if it does not already exist"
msgstr ""
+msgid "Configure GitLab"
+msgstr ""
+
msgid "Configure GitLab runners to start using the Web Terminal. %{helpStart}Learn more.%{helpEnd}"
msgstr ""
@@ -9126,6 +9200,15 @@ msgstr ""
msgid "Configure pipelines to deploy web apps, backend services, APIs and static resources to Google Cloud"
msgstr ""
+msgid "Configure region"
+msgstr ""
+
+msgid "Configure region for environment"
+msgstr ""
+
+msgid "Configure regions"
+msgstr ""
+
msgid "Configure repository mirroring."
msgstr ""
@@ -9159,6 +9242,9 @@ msgstr ""
msgid "Configure which lists are shown for anyone who visits this board"
msgstr ""
+msgid "Configure your environments to be deployed to specific geographical regions"
+msgstr ""
+
msgid "Confirm"
msgstr ""
@@ -9861,10 +9947,10 @@ msgstr ""
msgid "CorpusManagement|Actions"
msgstr ""
-msgid "CorpusManagement|Corpus are used in fuzz testing as mutation source to Improve future testing."
+msgid "CorpusManagement|Corpus file"
msgstr ""
-msgid "CorpusManagement|Corpus file"
+msgid "CorpusManagement|Corpus files are used in coverage-guided fuzz testing as seed inputs to improve testing."
msgstr ""
msgid "CorpusManagement|Corpus files must be in *.zip format. Maximum 5 GB"
@@ -9918,6 +10004,9 @@ msgstr ""
msgid "Could not apply %{name} command."
msgstr ""
+msgid "Could not apply %{name} command. %{message}."
+msgstr ""
+
msgid "Could not authorize chat nickname. Try again!"
msgstr ""
@@ -10068,6 +10157,9 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
+msgid "Create a group"
+msgstr ""
+
msgid "Create a merge request"
msgstr ""
@@ -10092,6 +10184,9 @@ msgstr ""
msgid "Create a personal access token on your account to pull or push via %{protocol}."
msgstr ""
+msgid "Create a project"
+msgstr ""
+
msgid "Create an account using:"
msgstr ""
@@ -10455,6 +10550,9 @@ msgstr ""
msgid "Creation date"
msgstr ""
+msgid "Creator"
+msgstr ""
+
msgid "Credentials"
msgstr ""
@@ -10467,9 +10565,15 @@ msgstr ""
msgid "CredentialsInventory|Personal Access Tokens"
msgstr ""
+msgid "CredentialsInventory|Project Access Tokens"
+msgstr ""
+
msgid "CredentialsInventory|SSH Keys"
msgstr ""
+msgid "Credit card required to be on file in order to create a pipeline"
+msgstr ""
+
msgid "Credit card:"
msgstr ""
@@ -10653,9 +10757,6 @@ msgstr ""
msgid "Customer relations"
msgstr ""
-msgid "Customizable by an administrator."
-msgstr ""
-
msgid "Customizable by owners."
msgstr ""
@@ -10785,30 +10886,18 @@ msgstr ""
msgid "CycleAnalytics|%{selectedLabelsCount} selected (%{maxLabels} max)"
msgstr ""
-msgid "CycleAnalytics|%{stageCount} stages selected"
-msgstr ""
-
-msgid "CycleAnalytics|All stages"
-msgstr ""
-
-msgid "CycleAnalytics|Average days to completion"
+msgid "CycleAnalytics|Average time to completion"
msgstr ""
msgid "CycleAnalytics|Date"
msgstr ""
-msgid "CycleAnalytics|Days to completion"
-msgstr ""
-
msgid "CycleAnalytics|Display chart filters"
msgstr ""
msgid "CycleAnalytics|Lead Time for Changes"
msgstr ""
-msgid "CycleAnalytics|No stages selected"
-msgstr ""
-
msgid "CycleAnalytics|Number of tasks"
msgstr ""
@@ -10837,18 +10926,30 @@ msgstr ""
msgid "CycleAnalytics|Showing data for group '%{groupName}' from %{createdAfter} to %{createdBefore}"
msgstr ""
-msgid "CycleAnalytics|Stages"
+msgid "CycleAnalytics|Stage time: %{title}"
msgstr ""
msgid "CycleAnalytics|Tasks by type"
msgstr ""
-msgid "CycleAnalytics|The average time spent in the selected stage for the items that were completed on each date. Data limited to the last 500 items."
+msgid "CycleAnalytics|The average time items spent in this stage. Data limited to items completed within this date range."
msgstr ""
msgid "CycleAnalytics|The given date range is larger than 180 days"
msgstr ""
+msgid "CycleAnalytics|The total time items spent across each value stream stage. Data limited to items completed within this date range."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Stage time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Total time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|Total time"
+msgstr ""
+
msgid "CycleAnalytics|Type of work"
msgstr ""
@@ -10861,9 +10962,6 @@ msgstr ""
msgid "CycleAnalytics|project dropdown filter"
msgstr ""
-msgid "CycleAnalytics|stage dropdown"
-msgstr ""
-
msgid "DAG visualization requires at least 3 dependent jobs."
msgstr ""
@@ -10963,10 +11061,16 @@ msgstr ""
msgid "DastProfiles|AJAX spider"
msgstr ""
+msgid "DastProfiles|API"
+msgstr ""
+
+msgid "DastProfiles|API endpoint URL"
+msgstr ""
+
msgid "DastProfiles|Active"
msgstr ""
-msgid "DastProfiles|Additional request headers (Optional)"
+msgid "DastProfiles|Additional request headers (optional)"
msgstr ""
msgid "DastProfiles|Are you sure you want to delete this profile?"
@@ -10981,6 +11085,9 @@ msgstr ""
msgid "DastProfiles|Branch missing"
msgstr ""
+msgid "DastProfiles|Choose a scan method"
+msgstr ""
+
msgid "DastProfiles|Could not create the scanner profile. Please try again."
msgstr ""
@@ -11050,7 +11157,13 @@ msgstr ""
msgid "DastProfiles|Excluded URLs"
msgstr ""
-msgid "DastProfiles|Excluded URLs (Optional)"
+msgid "DastProfiles|Excluded URLs (optional)"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths (optional)"
msgstr ""
msgid "DastProfiles|Hide debug messages"
@@ -11107,9 +11220,6 @@ msgstr ""
msgid "DastProfiles|Request headers"
msgstr ""
-msgid "DastProfiles|Rest API"
-msgstr ""
-
msgid "DastProfiles|Run the AJAX spider, in addition to the traditional spider, to crawl the target site."
msgstr ""
@@ -11119,6 +11229,9 @@ msgstr ""
msgid "DastProfiles|Save profile"
msgstr ""
+msgid "DastProfiles|Scan method"
+msgstr ""
+
msgid "DastProfiles|Scan mode"
msgstr ""
@@ -11197,12 +11310,24 @@ msgstr ""
msgid "DastProfiles|Website"
msgstr ""
+msgid "DastProfiles|What does each method do?"
+msgstr ""
+
msgid "DastProfiles|You can either choose a passive scan or validate the target site from the site profile management page. %{docsLinkStart}Learn more about site validation.%{docsLinkEnd}"
msgstr ""
msgid "DastProfiles|You cannot run an active scan against an unvalidated site."
msgstr ""
+msgid "DastProfiles|folder/dast_example.har or https://example.com/dast_example.har"
+msgstr ""
+
+msgid "DastProfiles|folder/example.postman_collection.json or https://example.com/"
+msgstr ""
+
+msgid "DastProfiles|folder/openapi.json or https://example.com/openapi.json"
+msgstr ""
+
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
@@ -11310,6 +11435,9 @@ msgstr ""
msgid "DatadogIntegration|API URL"
msgstr ""
+msgid "DatadogIntegration|Custom tags in Datadog. Enter one tag per line in the %{codeOpen}key:value%{codeClose} format. %{linkOpen}How do I use tags?%{linkClose}"
+msgstr ""
+
msgid "DatadogIntegration|Environment"
msgstr ""
@@ -11328,12 +11456,18 @@ msgstr ""
msgid "DatadogIntegration|Tag all data from this GitLab instance in Datadog. Useful when managing several self-managed deployments."
msgstr ""
+msgid "DatadogIntegration|Tags"
+msgstr ""
+
msgid "DatadogIntegration|The Datadog site to send data to. To send data to the EU site, use %{codeOpen}datadoghq.eu%{codeClose}."
msgstr ""
msgid "DatadogIntegration|Trace your GitLab pipelines with Datadog."
msgstr ""
+msgid "DatadogIntegration|have an invalid format"
+msgstr ""
+
msgid "Datasource name not found"
msgstr ""
@@ -11343,9 +11477,6 @@ msgstr ""
msgid "Date merged"
msgstr ""
-msgid "Date picker"
-msgstr ""
-
msgid "Date range"
msgstr ""
@@ -11499,9 +11630,6 @@ msgstr ""
msgid "Definition"
msgstr ""
-msgid "Delayed Project Deletion (%{adjourned_deletion})"
-msgstr ""
-
msgid "DelayedJobs|Are you sure you want to run %{jobName} immediately? Otherwise this job will run automatically after its timer finishes."
msgstr ""
@@ -11580,10 +11708,10 @@ msgstr ""
msgid "Delete pipeline"
msgstr ""
-msgid "Delete project"
+msgid "Delete pipeline schedule"
msgstr ""
-msgid "Delete project. Are you ABSOLUTELY SURE?"
+msgid "Delete project"
msgstr ""
msgid "Delete row"
@@ -11613,6 +11741,9 @@ msgstr ""
msgid "Delete this epic and all descendants?"
msgstr ""
+msgid "Delete this project"
+msgstr ""
+
msgid "Delete user list"
msgstr ""
@@ -11871,6 +12002,12 @@ msgstr ""
msgid "Deploy to..."
msgstr ""
+msgid "DeployBoards|To see deployment progress for your environments, make sure you are deploying to %{codeStart}$KUBE_NAMESPACE%{codeEnd} and annotating with %{codeStart}app.gitlab.com/app=$CI_PROJECT_PATH_SLUG%{codeEnd} and %{codeStart}app.gitlab.com/env=$CI_ENVIRONMENT_SLUG%{codeEnd}."
+msgstr ""
+
+msgid "DeployBoard|Kubernetes Pods"
+msgstr ""
+
msgid "DeployFreeze|Add a freeze period to prevent unintended releases during a period of time for a given environment. You must update the deployment jobs in %{filename} according to the deploy freezes added here. %{freeze_period_link_start}Learn more.%{freeze_period_link_end}"
msgstr ""
@@ -11955,9 +12092,6 @@ msgstr ""
msgid "DeployTokens|Active Deploy Tokens (%{active_tokens})"
msgstr ""
-msgid "DeployTokens|Allows read and write access to registry images."
-msgstr ""
-
msgid "DeployTokens|Allows read and write access to the package registry."
msgstr ""
@@ -11970,6 +12104,9 @@ msgstr ""
msgid "DeployTokens|Allows read-only access to the repository."
msgstr ""
+msgid "DeployTokens|Allows write access to registry images."
+msgstr ""
+
msgid "DeployTokens|Copy deploy token"
msgstr ""
@@ -12063,12 +12200,57 @@ msgstr ""
msgid "Deploying to AWS is easy with GitLab"
msgstr ""
+msgid "Deployment"
+msgstr ""
+
msgid "Deployment Frequency"
msgstr ""
+msgid "Deployment Target|Project deployment target (optional)"
+msgstr ""
+
+msgid "Deployment Target|Select the deployment target"
+msgstr ""
+
msgid "Deployment frequency"
msgstr ""
+msgid "DeploymentTarget|GitLab Pages"
+msgstr ""
+
+msgid "DeploymentTarget|Heroku"
+msgstr ""
+
+msgid "DeploymentTarget|Infrastructure provider (Terraform, Cloudformation, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Kubernetes (GKE, EKS, OpenShift, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Managed container runtime (Fargate, Cloud Run, DigitalOcean App)"
+msgstr ""
+
+msgid "DeploymentTarget|Mobile app store"
+msgstr ""
+
+msgid "DeploymentTarget|No deployment planned"
+msgstr ""
+
+msgid "DeploymentTarget|Other hosting service"
+msgstr ""
+
+msgid "DeploymentTarget|Registry (package or container)"
+msgstr ""
+
+msgid "DeploymentTarget|Self-managed container runtime (Podman, Docker Swarm, Docker Compose)"
+msgstr ""
+
+msgid "DeploymentTarget|Serverless backend (Lambda, Cloud functions)"
+msgstr ""
+
+msgid "DeploymentTarget|Virtual machine (for example, EC2)"
+msgstr ""
+
msgid "Deployments"
msgstr ""
@@ -12107,6 +12289,9 @@ msgstr ""
msgid "Deployment|This deployment was created using the API"
msgstr ""
+msgid "Deployment|Triggerer"
+msgstr ""
+
msgid "Deployment|Waiting"
msgstr ""
@@ -12134,6 +12319,18 @@ msgstr ""
msgid "Deprecated API rate limits"
msgstr ""
+msgid "Deprecations|Feature deprecation and removal"
+msgstr ""
+
+msgid "Deprecations|For information on a possible replacement %{epicStart} learn more about Opstrace %{epicEnd}."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7 and are %{epicStart} scheduled for removal %{epicEnd} in GitLab 15.0."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7, and are %{removal_link_start} scheduled for removal %{link_end} in GitLab 15.0. For information on a possible replacement, %{opstrace_link_start} learn more about Opstrace %{link_end}."
+msgstr ""
+
msgid "Deprioritize label"
msgstr ""
@@ -12379,10 +12576,10 @@ msgstr ""
msgid "DevopsAdoption|At least one deploy"
msgstr ""
-msgid "DevopsAdoption|At least one issue opened"
+msgid "DevopsAdoption|At least one issue created"
msgstr ""
-msgid "DevopsAdoption|At least one merge request opened"
+msgid "DevopsAdoption|At least one merge request created"
msgstr ""
msgid "DevopsAdoption|At least one pipeline successfully run"
@@ -12583,6 +12780,9 @@ msgstr ""
msgid "Direct member"
msgstr ""
+msgid "Direct members"
+msgstr ""
+
msgid "Direct non-authenticated users to this page."
msgstr ""
@@ -12699,6 +12899,9 @@ msgid_plural "Dismiss %d selected vulnerabilities as"
msgstr[0] ""
msgstr[1] ""
+msgid "Dismiss Alert"
+msgstr ""
+
msgid "Dismiss merge request promotion"
msgstr ""
@@ -12726,9 +12929,15 @@ msgstr ""
msgid "Display alerts from all configured monitoring tools."
msgstr ""
+msgid "Display milestones"
+msgstr ""
+
msgid "Display name"
msgstr ""
+msgid "Display progress of child issues"
+msgstr ""
+
msgid "Display rendered file"
msgstr ""
@@ -12834,6 +13043,9 @@ msgstr ""
msgid "Download image"
msgstr ""
+msgid "Download payload"
+msgstr ""
+
msgid "Download raw data (.csv)"
msgstr ""
@@ -13011,6 +13223,9 @@ msgstr ""
msgid "Edit in Web IDE"
msgstr ""
+msgid "Edit in pipeline editor"
+msgstr ""
+
msgid "Edit in single-file editor"
msgstr ""
@@ -13053,6 +13268,9 @@ msgstr ""
msgid "Edit your most recent comment in a thread (from an empty textarea)"
msgstr ""
+msgid "Edit, lint, and visualize your pipeline."
+msgstr ""
+
msgid "Edited"
msgstr ""
@@ -13494,6 +13712,9 @@ msgstr ""
msgid "Enforce two-factor authentication for all user sign-ins."
msgstr ""
+msgid "Enhance security by storing service account keys in secret managers - learn more about %{docLinkStart}secret management with GitLab%{docLinkEnd}"
+msgstr ""
+
msgid "Ensure connectivity is available from the GitLab server to the Prometheus server"
msgstr ""
@@ -13554,6 +13775,9 @@ 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 following to confirm:"
+msgstr ""
+
msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
@@ -14084,9 +14308,6 @@ 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 ""
@@ -14222,6 +14443,9 @@ msgstr ""
msgid "Errors:"
msgstr ""
+msgid "Escalate this incident"
+msgstr ""
+
msgid "Escalation Policies"
msgstr ""
@@ -14234,6 +14458,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy"
+msgstr ""
+
msgid "Escalation policy:"
msgstr ""
@@ -14485,6 +14712,9 @@ msgstr ""
msgid "Existing sign in methods may be removed"
msgstr ""
+msgid "Exit."
+msgstr ""
+
msgid "Expand"
msgstr ""
@@ -14581,6 +14811,9 @@ msgstr ""
msgid "Explore public groups"
msgstr ""
+msgid "Explore public projects"
+msgstr ""
+
msgid "Explore snippets"
msgstr ""
@@ -14742,7 +14975,7 @@ msgid_plural "Failed to archive designs. Please try again."
msgstr[0] ""
msgstr[1] ""
-msgid "Failed to assign a reviewer because no user was found."
+msgid "Failed to assign a reviewer because no user was specified."
msgstr ""
msgid "Failed to assign a user because no user was found."
@@ -14808,10 +15041,10 @@ msgstr ""
msgid "Failed to find import label for Jira import."
msgstr ""
-msgid "Failed to generate export, please try again later."
+msgid "Failed to find users for %{missing}"
msgstr ""
-msgid "Failed to generate report, please try again after sometime"
+msgid "Failed to generate export, please try again later."
msgstr ""
msgid "Failed to get ref."
@@ -14910,6 +15143,9 @@ msgstr ""
msgid "Failed to remove a to-do item for the design."
msgstr ""
+msgid "Failed to remove attention because no user was found."
+msgstr ""
+
msgid "Failed to remove mirror."
msgstr ""
@@ -14922,6 +15158,9 @@ msgstr ""
msgid "Failed to remove user key."
msgstr ""
+msgid "Failed to request attention because no user was found."
+msgstr ""
+
msgid "Failed to reset key. Please try again."
msgstr ""
@@ -15003,6 +15242,9 @@ msgstr ""
msgid "Feature Flags"
msgstr ""
+msgid "Feature deprecation and removal"
+msgstr ""
+
msgid "Feature flag status"
msgstr ""
@@ -15500,7 +15742,7 @@ msgstr ""
msgid "For each job, re-use the project workspace. If the workspace doesn't exist, use %{code_open}git clone%{code_close}."
msgstr ""
-msgid "For example, the application using the token or the purpose of the token."
+msgid "For example, the application using the token or the purpose of the token. Do not give sensitive information for the name of the token, as it will be visible to all %{resource_type} members."
msgstr ""
msgid "For files larger than this limit, only index the file name. The file content is neither indexed nor searchable."
@@ -15584,9 +15826,6 @@ msgstr ""
msgid "ForkProject|Select a namespace"
msgstr ""
-msgid "ForkProject|Select a namespace to fork the project"
-msgstr ""
-
msgid "ForkProject|The project can be accessed by any logged in user."
msgstr ""
@@ -15683,6 +15922,9 @@ msgstr ""
msgid "Full name"
msgstr ""
+msgid "GCP region configured"
+msgstr ""
+
msgid "GPG Key ID:"
msgstr ""
@@ -15863,6 +16105,9 @@ msgstr ""
msgid "Geo|Failed"
msgstr ""
+msgid "Geo|Filter Geo sites"
+msgstr ""
+
msgid "Geo|Filter by name"
msgstr ""
@@ -16274,6 +16519,12 @@ msgstr ""
msgid "GitLab Issue"
msgstr ""
+msgid "GitLab KAS"
+msgstr ""
+
+msgid "GitLab Memberships CSV Export"
+msgstr ""
+
msgid "GitLab Pages"
msgstr ""
@@ -16322,6 +16573,9 @@ 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 free to use. Many features for larger teams are part of our %{link_start}paid products%{link_end}. You can try Ultimate for free without any obligation or payment details."
+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 ""
@@ -16448,7 +16702,7 @@ msgstr ""
msgid "GitLabPages|When enabled, all attempts to visit your website through HTTP are automatically redirected to HTTPS using a response with status code 301. Requires a valid certificate for all domains. %{docs_link_start}Learn more.%{link_end}"
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. %{docs_link_start}Learn more.%{link_end}"
+msgid "GitLabPages|When using Pages under the general domain of a GitLab instance (%{pages_host}), you cannot use HTTPS with subdomains of subdomains. If your namespace or groupname contains a dot, it does not work. This is a limitation of the HTTP Over TLS protocol. HTTP pages work if you don't redirect HTTP to HTTPS. %{docs_link_start}Learn more.%{link_end}"
msgstr ""
msgid "GitLabPages|With GitLab Pages you can host your static website directly from your GitLab repository. %{docs_link_start}Learn more.%{link_end}"
@@ -16625,9 +16879,6 @@ msgstr ""
msgid "Go to find file"
msgstr ""
-msgid "Go to fork"
-msgstr ""
-
msgid "Go to issue boards"
msgstr ""
@@ -16835,9 +17086,6 @@ msgstr ""
msgid "Group Hooks"
msgstr ""
-msgid "Group ID"
-msgstr ""
-
msgid "Group Owner must have signed in with SAML before enabling Group Managed Accounts"
msgstr ""
@@ -16865,9 +17113,6 @@ msgstr ""
msgid "Group by"
msgstr ""
-msgid "Group description"
-msgstr ""
-
msgid "Group description (optional)"
msgstr ""
@@ -16982,7 +17227,7 @@ msgstr ""
msgid "Group: %{name}"
msgstr ""
-msgid "GroupActivityMetrics|Issues opened"
+msgid "GroupActivityMetrics|Issues created"
msgstr ""
msgid "GroupActivityMetrics|Last 90 days"
@@ -16991,7 +17236,7 @@ msgstr ""
msgid "GroupActivityMetrics|Members added"
msgstr ""
-msgid "GroupActivityMetrics|Merge Requests opened"
+msgid "GroupActivityMetrics|Merge Requests created"
msgstr ""
msgid "GroupActivityMetrics|Recent activity"
@@ -17282,6 +17527,9 @@ msgstr ""
msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
+msgid "GroupSettings|Choose a group path that does not start with a dash or end with a period. It can also contain alphanumeric characters and underscores."
+msgstr ""
+
msgid "GroupSettings|Compliance frameworks"
msgstr ""
@@ -17315,7 +17563,7 @@ msgstr ""
msgid "GroupSettings|If not specified at the group or instance level, the default is %{default_initial_branch_name}. Does not affect existing repositories."
msgstr ""
-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."
+msgid "GroupSettings|If the parent group's visibility is lower than the group's current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility."
msgstr ""
msgid "GroupSettings|New runners registration token has been generated!"
@@ -17432,7 +17680,10 @@ msgstr ""
msgid "Groups and projects"
msgstr ""
-msgid "Groups and subgroups"
+msgid "Groups are a great way to organize projects and people."
+msgstr ""
+
+msgid "Groups are the best way to manage projects and members."
msgstr ""
msgid "Groups to synchronize"
@@ -17543,13 +17794,16 @@ msgstr ""
msgid "GroupsTree|Are you sure you want to leave the \"%{fullName}\" group?"
msgstr ""
-msgid "GroupsTree|Edit group"
+msgid "GroupsTree|Delete"
+msgstr ""
+
+msgid "GroupsTree|Edit"
msgstr ""
msgid "GroupsTree|Failed to leave the group. Please make sure you are not the only owner."
msgstr ""
-msgid "GroupsTree|Leave this group"
+msgid "GroupsTree|Leave group"
msgstr ""
msgid "GroupsTree|Loading groups"
@@ -17561,9 +17815,57 @@ msgstr ""
msgid "GroupsTree|No groups or projects matched your search"
msgstr ""
+msgid "GroupsTree|Options"
+msgstr ""
+
msgid "GroupsTree|Search by name"
msgstr ""
+msgid "Groups|Avatar will be removed. Are you sure?"
+msgstr ""
+
+msgid "Groups|Changing group URL can have unintended side effects."
+msgstr ""
+
+msgid "Groups|Checking group URL availability..."
+msgstr ""
+
+msgid "Groups|Enter a descriptive name for your group."
+msgstr ""
+
+msgid "Groups|Group ID"
+msgstr ""
+
+msgid "Groups|Group URL"
+msgstr ""
+
+msgid "Groups|Group avatar"
+msgstr ""
+
+msgid "Groups|Group description (optional)"
+msgstr ""
+
+msgid "Groups|Group name"
+msgstr ""
+
+msgid "Groups|Group path is available."
+msgstr ""
+
+msgid "Groups|Group path is unavailable. Path has been replaced with a suggested available path."
+msgstr ""
+
+msgid "Groups|Learn more"
+msgstr ""
+
+msgid "Groups|Must start with letter, digit, emoji, or underscore. Can also contain periods, dashes, spaces, and parentheses."
+msgstr ""
+
+msgid "Groups|Remove avatar"
+msgstr ""
+
+msgid "Groups|Save changes"
+msgstr ""
+
msgid "Guideline"
msgstr ""
@@ -17573,6 +17875,9 @@ msgstr ""
msgid "HAR file path or URL"
msgstr ""
+msgid "HTTP Archive (HAR)"
+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 ""
@@ -17973,6 +18278,9 @@ msgstr ""
msgid "INFO: Your SSH key is expiring soon. Please generate a new key."
msgstr ""
+msgid "IP"
+msgstr ""
+
msgid "IP Address"
msgstr ""
@@ -18009,6 +18317,9 @@ msgstr ""
msgid "IdentityVerification|Verify your identity"
msgstr ""
+msgid "IdentityVerification|You can always verify your account at a later time to create a group."
+msgstr ""
+
msgid "If any indexed field exceeds this limit, it is truncated to this number of characters. The rest of the content is neither indexed nor searchable. This does not apply to repository and wiki indexing. For unlimited characters, set this to 0."
msgstr ""
@@ -18066,6 +18377,9 @@ msgstr ""
msgid "If you add %{codeStart}needs%{codeEnd} to jobs in your pipeline you'll be able to view the %{codeStart}needs%{codeEnd} relationships between jobs in this tab as a %{linkStart}Directed Acyclic Graph (DAG)%{linkEnd}."
msgstr ""
+msgid "If you are added to a project, it will be displayed here."
+msgstr ""
+
msgid "If you did not initiate these sign-in attempts, please reach out to your administrator or enable two-factor authentication (2FA) on your account."
msgstr ""
@@ -18372,12 +18686,24 @@ msgstr ""
msgid "InProductMarketing|3 ways to dive into GitLab CI/CD"
msgstr ""
+msgid "InProductMarketing|A single application eliminates complex integrations, data chokepoints, and toolchain maintenance, resulting in greater productivity and lower cost."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features, build more efficiently, strengthen security and compliance."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features."
+msgstr ""
+
msgid "InProductMarketing|Actually, GitLab makes the team work (better)"
msgstr ""
msgid "InProductMarketing|And finally %{deploy_link} a Python application."
msgstr ""
+msgid "InProductMarketing|And many more..."
+msgstr ""
+
msgid "InProductMarketing|Are your runners ready?"
msgstr ""
@@ -18396,15 +18722,33 @@ msgstr ""
msgid "InProductMarketing|Blog"
msgstr ""
+msgid "InProductMarketing|Break down silos to coordinate seamlessly across development, operations, and security with a consistent experience across the development lifecycle."
+msgstr ""
+
+msgid "InProductMarketing|Burn up/down charts"
+msgstr ""
+
msgid "InProductMarketing|By enabling code owners and required merge approvals the right person will review the right MR. This is a win-win: cleaner code and a more efficient review process."
msgstr ""
msgid "InProductMarketing|Click on the number below that corresponds with your answer — 1 being very difficult, 5 being very easy."
msgstr ""
+msgid "InProductMarketing|Code owners"
+msgstr ""
+
msgid "InProductMarketing|Code owners and required merge approvals are part of the paid tiers of GitLab. You can start a free 30-day trial of GitLab Ultimate and enable these features in less than 5 minutes with no credit card required."
msgstr ""
+msgid "InProductMarketing|Code review analytics"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration across stages in GitLab"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration made easy"
+msgstr ""
+
msgid "InProductMarketing|Create a custom CI runner with just a few clicks"
msgstr ""
@@ -18414,12 +18758,21 @@ msgstr ""
msgid "InProductMarketing|Create a project in GitLab in 5 minutes"
msgstr ""
+msgid "InProductMarketing|Create well-defined workflows by using scoped labels on issues, merge requests, and epics. Labels with the same scope cannot be used together, which prevents conflicts."
+msgstr ""
+
msgid "InProductMarketing|Create your first project!"
msgstr ""
+msgid "InProductMarketing|Define who owns specific files or directories, so the right reviewers are suggested when a merge request introduces changes to those files."
+msgstr ""
+
msgid "InProductMarketing|Deliver Better Products Faster"
msgstr ""
+msgid "InProductMarketing|Dependency scanning"
+msgstr ""
+
msgid "InProductMarketing|Did you know teams that use GitLab are far more efficient?"
msgstr ""
@@ -18429,15 +18782,27 @@ msgstr ""
msgid "InProductMarketing|Dig in and create a project and a repo"
msgstr ""
+msgid "InProductMarketing|Discover Premium & Ultimate"
+msgstr ""
+
+msgid "InProductMarketing|Discover Premium & Ultimate."
+msgstr ""
+
msgid "InProductMarketing|Do you have a minute?"
msgstr ""
msgid "InProductMarketing|Do you have a teammate who would be perfect for this task?"
msgstr ""
+msgid "InProductMarketing|Dynamic application security testing"
+msgstr ""
+
msgid "InProductMarketing|Easy"
msgstr ""
+msgid "InProductMarketing|Epics"
+msgstr ""
+
msgid "InProductMarketing|Expand your DevOps journey with a free GitLab trial"
msgstr ""
@@ -18459,9 +18824,15 @@ msgstr ""
msgid "InProductMarketing|Feel the need for speed?"
msgstr ""
+msgid "InProductMarketing|Find and fix bottlenecks in your code review process by understanding how long open merge requests have been in review."
+msgstr ""
+
msgid "InProductMarketing|Find out how your teams are really doing"
msgstr ""
+msgid "InProductMarketing|Find out if your external libraries are safe. Run dependency scanning jobs that check for known vulnerabilities in your external libraries."
+msgstr ""
+
msgid "InProductMarketing|Follow our steps"
msgstr ""
@@ -18498,6 +18869,9 @@ msgstr ""
msgid "InProductMarketing|GitLab is better with teammates to help out!"
msgstr ""
+msgid "InProductMarketing|GitLab is infrastructure agnostic (supporting GCP, AWS, Azure, OpenShift, VMWare, On Prem, Bare Metal, and more), offering a consistent workflow experience – irrespective of the environment."
+msgstr ""
+
msgid "InProductMarketing|GitLab provides static application security testing (SAST), dynamic application security testing (DAST), container scanning, and dependency scanning to help you deliver secure applications along with license compliance."
msgstr ""
@@ -18588,21 +18962,36 @@ msgstr ""
msgid "InProductMarketing|It's also possible to simply %{external_repo_link} in order to take advantage of GitLab's CI/CD."
msgstr ""
+msgid "InProductMarketing|Keep your code quality high by defining who should approve merge requests and how many approvals are required."
+msgstr ""
+
msgid "InProductMarketing|Launch GitLab CI/CD in 20 minutes or less"
msgstr ""
+msgid "InProductMarketing|Lower cost of development"
+msgstr ""
+
+msgid "InProductMarketing|Make it easier to collaborate on high-level ideas by grouping related issues in an epic."
+msgstr ""
+
msgid "InProductMarketing|Making the switch? It's easier than you think to import your projects into GitLab. Move %{github_link}, or import something %{bitbucket_link}."
msgstr ""
msgid "InProductMarketing|Master the art of importing!"
msgstr ""
+msgid "InProductMarketing|Merge request approval rule"
+msgstr ""
+
msgid "InProductMarketing|Move on to easily creating a Pages website %{ci_template_link}"
msgstr ""
msgid "InProductMarketing|Multiple owners, confusing workstreams? We've got you covered"
msgstr ""
+msgid "InProductMarketing|Multiple required approvers"
+msgstr ""
+
msgid "InProductMarketing|Need an alternative to importing?"
msgstr ""
@@ -18615,18 +19004,33 @@ msgstr ""
msgid "InProductMarketing|Our tool brings all the things together"
msgstr ""
+msgid "InProductMarketing|Protect your web application by using DAST to examine for vulnerabilities in deployed environments."
+msgstr ""
+
msgid "InProductMarketing|Rapid development, simplified"
msgstr ""
msgid "InProductMarketing|Reduce Security & Compliance Risk"
msgstr ""
+msgid "InProductMarketing|Require multiple approvers on a merge request, so you know it's in good shape before it's merged."
+msgstr ""
+
+msgid "InProductMarketing|Roadmaps"
+msgstr ""
+
+msgid "InProductMarketing|Scoped labels"
+msgstr ""
+
msgid "InProductMarketing|Security that's integrated into your development lifecycle"
msgstr ""
msgid "InProductMarketing|Sometimes you're not ready to make a full transition to a new tool. If you're not ready to fully commit, %{mirroring_link} gives you a safe way to try out GitLab in parallel with your current tool."
msgstr ""
+msgid "InProductMarketing|Speed. Efficiency. Trust."
+msgstr ""
+
msgid "InProductMarketing|Spin up an autoscaling runner in GitLab"
msgstr ""
@@ -18636,6 +19040,9 @@ msgstr ""
msgid "InProductMarketing|Start a Self-Managed trial"
msgstr ""
+msgid "InProductMarketing|Start a free trial"
+msgstr ""
+
msgid "InProductMarketing|Start a free trial of GitLab Ultimate – no credit card required"
msgstr ""
@@ -18702,6 +19109,9 @@ msgstr ""
msgid "InProductMarketing|To understand and get the most out of GitLab, start at the beginning and %{project_link}. In GitLab, repositories are part of a project, so after you've created your project you can go ahead and %{repo_link}."
msgstr ""
+msgid "InProductMarketing|Track completed issues in a chart, so you can see how a milestone is progressing at a glance."
+msgstr ""
+
msgid "InProductMarketing|Try GitLab Ultimate for free"
msgstr ""
@@ -18738,6 +19148,9 @@ msgstr ""
msgid "InProductMarketing|Very easy"
msgstr ""
+msgid "InProductMarketing|Visualize your epics and milestones in a timeline."
+msgstr ""
+
msgid "InProductMarketing|Want to host GitLab on your servers?"
msgstr ""
@@ -18759,6 +19172,9 @@ msgstr ""
msgid "InProductMarketing|YouTube"
msgstr ""
+msgid "InProductMarketing|Your software, deployed your way"
+msgstr ""
+
msgid "InProductMarketing|Your teams can be more efficient"
msgstr ""
@@ -18879,9 +19295,18 @@ msgstr ""
msgid "IncidentManagement|No incidents to display."
msgstr ""
+msgid "IncidentManagement|None"
+msgstr ""
+
msgid "IncidentManagement|Open"
msgstr ""
+msgid "IncidentManagement|Page your team with escalation policies"
+msgstr ""
+
+msgid "IncidentManagement|Paged"
+msgstr ""
+
msgid "IncidentManagement|Published"
msgstr ""
@@ -18891,6 +19316,9 @@ msgstr ""
msgid "IncidentManagement|Severity"
msgstr ""
+msgid "IncidentManagement|Status"
+msgstr ""
+
msgid "IncidentManagement|There are no closed incidents"
msgstr ""
@@ -18909,6 +19337,9 @@ msgstr ""
msgid "IncidentManagement|Unpublished"
msgstr ""
+msgid "IncidentManagement|Use escalation policies to automatically page your team when incidents are created."
+msgstr ""
+
msgid "IncidentSettings|Activate \"time to SLA\" countdown timer"
msgstr ""
@@ -18954,7 +19385,10 @@ msgstr ""
msgid "Incidents"
msgstr ""
-msgid "Incidents|Add a URL"
+msgid "Incidents|Add image details"
+msgstr ""
+
+msgid "Incidents|Add text or a link to display with your image. If you don't add either, the file name displays instead."
msgstr ""
msgid "Incidents|Drop or %{linkStart}upload%{linkEnd} a metric screenshot to attach it to the incident"
@@ -18969,10 +19403,10 @@ msgstr ""
msgid "Incidents|There was an issue loading metric images."
msgstr ""
-msgid "Incidents|There was an issue uploading your image."
+msgid "Incidents|There was an issue updating your image."
msgstr ""
-msgid "Incidents|You can optionally add a URL to link users to the original graph."
+msgid "Incidents|There was an issue uploading your image."
msgstr ""
msgid "Incident|Alert details"
@@ -18981,9 +19415,18 @@ msgstr ""
msgid "Incident|Are you sure you wish to delete this image?"
msgstr ""
+msgid "Incident|Delete image"
+msgstr ""
+
msgid "Incident|Deleting %{filename}"
msgstr ""
+msgid "Incident|Edit image text or link"
+msgstr ""
+
+msgid "Incident|Editing %{filename}"
+msgstr ""
+
msgid "Incident|Metrics"
msgstr ""
@@ -19253,12 +19696,18 @@ msgstr ""
msgid "Integrations|Branches for which notifications are to be sent"
msgstr ""
+msgid "Integrations|Clear if using a self-signed certificate."
+msgstr ""
+
msgid "Integrations|Comment detail:"
msgstr ""
msgid "Integrations|Comment settings:"
msgstr ""
+msgid "Integrations|Connection details"
+msgstr ""
+
msgid "Integrations|Connection failed. Please check your settings."
msgstr ""
@@ -19283,6 +19732,9 @@ msgstr ""
msgid "Integrations|Enable GitLab.com slash commands in a Slack workspace."
msgstr ""
+msgid "Integrations|Enable SSL verification"
+msgstr ""
+
msgid "Integrations|Enable comments"
msgstr ""
@@ -19361,6 +19813,9 @@ msgstr ""
msgid "Integrations|Return to GitLab for Jira"
msgstr ""
+msgid "Integrations|SSL verification"
+msgstr ""
+
msgid "Integrations|Save settings?"
msgstr ""
@@ -19406,9 +19861,6 @@ msgstr ""
msgid "Integrations|Use default settings"
msgstr ""
-msgid "Integrations|When you mention a Jira issue in a commit or merge request, GitLab creates a remote link and comment (if enabled)."
-msgstr ""
-
msgid "Integrations|You can now close this window and return to the GitLab for Jira application."
msgstr ""
@@ -19433,9 +19885,6 @@ msgstr ""
msgid "Integrations|can't exceed %{recipients_limit}"
msgstr ""
-msgid "Interactive developer security education."
-msgstr ""
-
msgid "Interactive mode"
msgstr ""
@@ -19925,6 +20374,9 @@ msgstr ""
msgid "IssueAnalytics|Assignees"
msgstr ""
+msgid "IssueAnalytics|Created by"
+msgstr ""
+
msgid "IssueAnalytics|Due date"
msgstr ""
@@ -19937,9 +20389,6 @@ msgstr ""
msgid "IssueAnalytics|Milestone"
msgstr ""
-msgid "IssueAnalytics|Opened by"
-msgstr ""
-
msgid "IssueAnalytics|Status"
msgstr ""
@@ -20063,10 +20512,10 @@ msgstr ""
msgid "IssuesAnalytics|Avg/Month:"
msgstr ""
-msgid "IssuesAnalytics|Issues opened"
+msgid "IssuesAnalytics|Issues created"
msgstr ""
-msgid "IssuesAnalytics|Issues opened per month"
+msgid "IssuesAnalytics|Issues created per month"
msgstr ""
msgid "IssuesAnalytics|Last 12 months"
@@ -20093,6 +20542,9 @@ msgstr ""
msgid "It looks like you have some draft commits in this branch."
msgstr ""
+msgid "It looks like you're attempting to activate your subscription. Use %{a_start}the Subscription page%{a_end} instead."
+msgstr ""
+
msgid "It may be several days before you see feature usage data."
msgstr ""
@@ -20321,6 +20773,9 @@ msgstr ""
msgid "JiraConnect|You can now close this window and return to Jira."
msgstr ""
+msgid "JiraConnect|You don't have permission to create branches for this project. Select a different project or contact the project owner for access. %{linkStart}Learn more.%{linkEnd}"
+msgstr ""
+
msgid "JiraRequest|A connection error occurred while connecting to Jira. Try your request again."
msgstr ""
@@ -20369,13 +20824,13 @@ msgstr ""
msgid "JiraService|Define the type of Jira issue to create from a vulnerability."
msgstr ""
-msgid "JiraService|Displaying Jira issues while leaving the GitLab issue functionality enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
+msgid "JiraService|Displaying Jira issues while leaving GitLab issues also enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
msgstr ""
-msgid "JiraService|Enable Jira issues"
+msgid "JiraService|Enable Jira issue creation from vulnerabilities"
msgstr ""
-msgid "JiraService|Enable Jira issues creation from vulnerabilities"
+msgid "JiraService|Enable Jira issues"
msgstr ""
msgid "JiraService|Enable Jira transitions"
@@ -20492,16 +20947,19 @@ msgstr ""
msgid "JiraService|View Jira issues in GitLab"
msgstr ""
-msgid "JiraService|Warning: All GitLab users that have access to this GitLab project are able to view all issues from the Jira project specified below."
+msgid "JiraService|Warning: All GitLab users with access to this GitLab project can view all issues from the Jira project you select."
msgstr ""
msgid "JiraService|Web URL"
msgstr ""
-msgid "JiraService|Work on Jira issues without leaving GitLab. Adds a Jira menu to access your list of Jira issues and view any issue as read-only."
+msgid "JiraService|When a Jira issue is mentioned in a commit or merge request, a remote link and comment (if enabled) will be created."
+msgstr ""
+
+msgid "JiraService|Work on Jira issues without leaving GitLab. Add a Jira menu to access a read-only list of your Jira issues."
msgstr ""
-msgid "JiraService|You need to configure Jira before enabling this integration. For more details, read the %{jira_doc_link_start}Jira integration documentation%{link_end}."
+msgid "JiraService|You must configure Jira before enabling this integration. %{jira_doc_link_start}Learn more.%{link_end}"
msgstr ""
msgid "Job"
@@ -20513,9 +20971,6 @@ msgstr ""
msgid "Job Failed #%{build_id}"
msgstr ""
-msgid "Job ID"
-msgstr ""
-
msgid "Job artifact"
msgstr ""
@@ -20582,9 +21037,27 @@ msgstr ""
msgid "Jobs|You're about to retry a job that failed because it attempted to deploy code that is older than the latest deployment. Retrying this job could result in overwriting the environment with the older source code."
msgstr ""
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source} into %{target}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{ref}"
+msgstr ""
+
+msgid "Job|Are you sure you want to erase this job log and artifacts?"
+msgstr ""
+
msgid "Job|Browse"
msgstr ""
+msgid "Job|Cancel"
+msgstr ""
+
msgid "Job|Complete Raw"
msgstr ""
@@ -20594,6 +21067,9 @@ msgstr ""
msgid "Job|Erase job log and artifacts"
msgstr ""
+msgid "Job|Finished at"
+msgstr ""
+
msgid "Job|Job artifacts"
msgstr ""
@@ -20606,7 +21082,7 @@ msgstr ""
msgid "Job|Keep"
msgstr ""
-msgid "Job|Pipeline"
+msgid "Job|Retry"
msgstr ""
msgid "Job|Scroll to bottom"
@@ -20618,6 +21094,9 @@ msgstr ""
msgid "Job|Show complete raw"
msgstr ""
+msgid "Job|Status"
+msgstr ""
+
msgid "Job|The artifacts were removed"
msgstr ""
@@ -20645,21 +21124,12 @@ msgstr ""
msgid "Job|delayed"
msgstr ""
-msgid "Job|for"
-msgstr ""
-
-msgid "Job|into"
-msgstr ""
-
msgid "Job|manual"
msgstr ""
msgid "Job|triggered"
msgstr ""
-msgid "Job|with"
-msgstr ""
-
msgid "Join Zoom meeting"
msgstr ""
@@ -20762,9 +21232,6 @@ msgstr ""
msgid "Ki"
msgstr ""
-msgid "Kontra"
-msgstr ""
-
msgid "Kroki"
msgstr ""
@@ -21088,6 +21555,9 @@ msgstr ""
msgid "Learn more about Auto DevOps"
msgstr ""
+msgid "Learn more about GitLab"
+msgstr ""
+
msgid "Learn more about Needs relationships"
msgstr ""
@@ -21415,9 +21885,18 @@ msgstr ""
msgid "Licenses|Displays licenses detected in the project, based on the %{linkStart}latest successful%{linkEnd} scan"
msgstr ""
+msgid "Licenses|Drag your license file here or %{linkStart}click to upload%{linkEnd}."
+msgstr ""
+
+msgid "Licenses|Drop your license file to start the upload."
+msgstr ""
+
msgid "Licenses|Error fetching the license list. Please check your network connection and try again."
msgstr ""
+msgid "Licenses|Error: You are trying to upload something other than a file"
+msgstr ""
+
msgid "Licenses|License Compliance"
msgstr ""
@@ -21436,6 +21915,9 @@ msgstr ""
msgid "Licenses|Specified policies in this project"
msgstr ""
+msgid "Licenses|The file could not be uploaded."
+msgstr ""
+
msgid "Licenses|The license list details information about the licenses used within your project."
msgstr ""
@@ -21469,11 +21951,6 @@ msgstr ""
msgid "Limit the size of Sidekiq jobs stored in Redis."
msgstr ""
-msgid "Limited to showing %d event at most"
-msgid_plural "Limited to showing %d events at most"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Limiting mode"
msgstr ""
@@ -21483,6 +21960,9 @@ msgstr ""
msgid "Link"
msgstr ""
+msgid "Link (optional)"
+msgstr ""
+
msgid "Link Prometheus monitoring to GitLab."
msgstr ""
@@ -21519,6 +21999,9 @@ msgstr ""
msgid "Linked emails (%{email_count})"
msgstr ""
+msgid "Linked epics"
+msgstr ""
+
msgid "Linked issues"
msgstr ""
@@ -21546,6 +22029,15 @@ msgstr ""
msgid "List of all merge commits"
msgstr ""
+msgid "List of environments for this project"
+msgstr ""
+
+msgid "List of suitable GCP locations"
+msgstr ""
+
+msgid "List of users allowed to exceed the rate limit."
+msgstr ""
+
msgid "List options"
msgstr ""
@@ -21765,6 +22257,9 @@ msgstr ""
msgid "Maintenance mode"
msgstr ""
+msgid "Make adjustments to how your GitLab instance is set up."
+msgstr ""
+
msgid "Make and review changes in the browser with the Web IDE"
msgstr ""
@@ -21909,6 +22404,12 @@ msgstr ""
msgid "MarkdownEditor|Add italic text (%{modifier_key}I)"
msgstr ""
+msgid "MarkdownEditor|Add strikethrough text (%{modifierKey}⇧X)"
+msgstr ""
+
+msgid "MarkdownEditor|Add strikethrough text (%{modifier_key}⇧X)"
+msgstr ""
+
msgid "Marked For Deletion At - %{deletion_time}"
msgstr ""
@@ -22170,6 +22671,9 @@ msgstr ""
msgid "Maximum push size (MB)"
msgstr ""
+msgid "Maximum requests per 10 minutes per user"
+msgstr ""
+
msgid "Maximum requests per minute"
msgstr ""
@@ -22260,6 +22764,19 @@ msgstr ""
msgid "Members of a group may only view projects they have permission to access"
msgstr ""
+msgid "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seat in use and will be billed for the overage."
+msgid_plural "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seats in use and will be billed for the overage."
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "MembersOverage|You are about to incur additional charges"
+msgstr ""
+
+msgid "MembersOverage|Your subscription includes %d seat."
+msgid_plural "MembersOverage|Your subscription includes %d seats."
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Membership"
msgstr ""
@@ -22464,9 +22981,6 @@ msgstr ""
msgid "Merge request not merged"
msgstr ""
-msgid "Merge request pipelines 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 merge request pipelines."
-msgstr ""
-
msgid "Merge request reports"
msgstr ""
@@ -22563,13 +23077,13 @@ msgstr ""
msgid "MergeRequests|Create issue to resolve thread"
msgstr ""
-msgid "MergeRequests|Failed to squash. Should be done manually."
+msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Saving the comment failed"
+msgid "MergeRequests|Squashing failed: Squash the commits locally, resolve any conflicts, then push the branch."
msgstr ""
-msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
+msgid "MergeRequests|Squashing not allowed: This project doesn't allow you to squash commits when merging."
msgstr ""
msgid "MergeRequests|Thread stays resolved"
@@ -23410,6 +23924,18 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "MrList|Assigned to %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from assignee %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from reviewer %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Review requested from %{name}, go to their profile."
+msgstr ""
+
msgid "Multi-project"
msgstr ""
@@ -23443,7 +23969,7 @@ msgstr ""
msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "My Awesome Group"
+msgid "My awesome group"
msgstr ""
msgid "My company or team"
@@ -24065,9 +24591,6 @@ msgstr ""
msgid "No available branches"
msgstr ""
-msgid "No available groups to fork the project."
-msgstr ""
-
msgid "No branches found"
msgstr ""
@@ -24278,6 +24801,9 @@ msgstr ""
msgid "No ref selected"
msgstr ""
+msgid "No regions configured"
+msgstr ""
+
msgid "No related merge requests found."
msgstr ""
@@ -25082,6 +25608,9 @@ msgstr ""
msgid "Only reCAPTCHA v2 is supported:"
msgstr ""
+msgid "Only required if not using role instance credentials."
+msgstr ""
+
msgid "Only use lowercase letters, numbers, and underscores."
msgstr ""
@@ -25106,9 +25635,6 @@ msgstr ""
msgid "Open a CLI and connect to the cluster you want to install the agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
-msgid "Open epics"
-msgstr ""
-
msgid "Open errors"
msgstr ""
@@ -25148,7 +25674,7 @@ msgstr ""
msgid "Opened issues"
msgstr ""
-msgid "OpenedNDaysAgo|Opened"
+msgid "OpenedNDaysAgo|Created"
msgstr ""
msgid "Opens in a new window"
@@ -25193,9 +25719,6 @@ msgstr ""
msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
-msgid "Optional."
-msgstr ""
-
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
msgstr ""
@@ -25984,6 +26507,9 @@ msgstr ""
msgid "PerformanceBar|Memory"
msgstr ""
+msgid "PerformanceBar|Memory report"
+msgstr ""
+
msgid "PerformanceBar|Redis calls"
msgstr ""
@@ -26017,18 +26543,12 @@ msgstr ""
msgid "PerformanceBar|wall"
msgstr ""
-msgid "Performs a rebase but skips triggering a new pipeline"
-msgstr ""
-
msgid "Period in seconds"
msgstr ""
msgid "Permalink"
msgstr ""
-msgid "Permanently delete project"
-msgstr ""
-
msgid "Permanently remove group"
msgstr ""
@@ -26299,6 +26819,51 @@ msgstr ""
msgid "PipelineStatusTooltip|Pipeline: %{ci_status}"
msgstr ""
+msgid "PipelineWizardDefaultCommitMessage|Add %{filename}"
+msgstr ""
+
+msgid "PipelineWizardDefaultCommitMessage|Update %{filename}"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|At least one entry is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This field is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This value is not valid"
+msgstr ""
+
+msgid "PipelineWizardListWidget|add another step"
+msgstr ""
+
+msgid "PipelineWizardListWidget|remove step"
+msgstr ""
+
+msgid "PipelineWizard|Commit"
+msgstr ""
+
+msgid "PipelineWizard|Commit Message"
+msgstr ""
+
+msgid "PipelineWizard|Commit changes to your file"
+msgstr ""
+
+msgid "PipelineWizard|Commit file to Branch"
+msgstr ""
+
+msgid "PipelineWizard|Commit your new file"
+msgstr ""
+
+msgid "PipelineWizard|The file has been committed."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem committing the changes."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem while checking whether your file already exists in the specified branch."
+msgstr ""
+
msgid "Pipelines"
msgstr ""
@@ -26413,7 +26978,7 @@ msgstr ""
msgid "Pipelines|Project cache successfully reset."
msgstr ""
-msgid "Pipelines|Revoke"
+msgid "Pipelines|Revoke trigger"
msgstr ""
msgid "Pipelines|Something went wrong while cleaning runners cache."
@@ -26458,6 +27023,12 @@ msgstr ""
msgid "Pipelines|This is a child pipeline within the parent pipeline"
msgstr ""
+msgid "Pipelines|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipelines|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipelines|This pipeline will run code originating from a forked project merge request. This means that the code can potentially have security considerations like exposing CI variables."
msgstr ""
@@ -26500,9 +27071,6 @@ msgstr ""
msgid "Pipelines|Your changes have been successfully committed. Now redirecting to the new merge request page."
msgstr ""
-msgid "Pipelines|detached"
-msgstr ""
-
msgid "Pipelines|error"
msgstr ""
@@ -26512,10 +27080,13 @@ msgstr ""
msgid "Pipelines|latest"
msgstr ""
-msgid "Pipelines|stuck"
+msgid "Pipelines|merge request"
msgstr ""
-msgid "Pipelines|train"
+msgid "Pipelines|merge train"
+msgstr ""
+
+msgid "Pipelines|stuck"
msgstr ""
msgid "Pipelines|yaml invalid"
@@ -26647,6 +27218,12 @@ msgstr ""
msgid "Pipeline|This change will not change the overall test coverage if merged."
msgstr ""
+msgid "Pipeline|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipeline|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipeline|Trigger author"
msgstr ""
@@ -26671,6 +27248,12 @@ msgstr ""
msgid "Pipeline|for"
msgstr ""
+msgid "Pipeline|merge request"
+msgstr ""
+
+msgid "Pipeline|merge train"
+msgstr ""
+
msgid "Pipeline|on"
msgstr ""
@@ -26809,9 +27392,6 @@ msgstr ""
msgid "Please enter a valid time interval"
msgstr ""
-msgid "Please enter or upload a valid license."
-msgstr ""
-
msgid "Please enter your current password."
msgstr ""
@@ -26920,9 +27500,6 @@ msgstr ""
msgid "Please type %{phrase_code} to proceed or close this modal to cancel."
msgstr ""
-msgid "Please type the following to confirm:"
-msgstr ""
-
msgid "Please use this form to report to the admin users who create spam issues, comments or behave inappropriately."
msgstr ""
@@ -26950,12 +27527,27 @@ msgstr ""
msgid "Policies"
msgstr ""
+msgid "Policy '%{escalation_policy_name}' does not exist."
+msgstr ""
+
msgid "Policy management project does have any policies in %{policy_path}"
msgstr ""
msgid "Policy project doesn't exist"
msgstr ""
+msgid "PolicyRuleMultiSelect|%{firstLabel} +%{numberOfAdditionalLabels} more"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|All %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select all"
+msgstr ""
+
msgid "Polling interval multiplier"
msgstr ""
@@ -27184,6 +27776,9 @@ msgstr ""
msgid "Private projects can be created in your personal namespace with:"
msgstr ""
+msgid "Problem with %{name} command: %{message}."
+msgstr ""
+
msgid "Proceed"
msgstr ""
@@ -27658,6 +28253,9 @@ msgstr ""
msgid "Progress"
msgstr ""
+msgid "Progress tracking"
+msgstr ""
+
msgid "Project"
msgstr ""
@@ -27889,6 +28487,9 @@ msgstr ""
msgid "ProjectQualitySummary|Failure"
msgstr ""
+msgid "ProjectQualitySummary|Get insight into the overall percentage of tests in your project that succeed, fail and are skipped."
+msgstr ""
+
msgid "ProjectQualitySummary|Latest pipeline results"
msgstr ""
@@ -27907,6 +28508,12 @@ msgstr ""
msgid "ProjectQualitySummary|See project Code Coverage Statistics"
msgstr ""
+msgid "ProjectQualitySummary|Set up test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|Set up test runs (opens in a new tab)"
+msgstr ""
+
msgid "ProjectQualitySummary|Skipped"
msgstr ""
@@ -28183,13 +28790,19 @@ msgstr ""
msgid "ProjectSettings|LFS objects from this repository are available to forks. %{linkStart}How do I remove them?%{linkEnd}"
msgstr ""
+msgid "ProjectSettings|Learn about commit history."
+msgstr ""
+
+msgid "ProjectSettings|Leave empty to use default template."
+msgstr ""
+
msgid "ProjectSettings|Manage who can see the project in the public access directory."
msgstr ""
msgid "ProjectSettings|Manages large files such as audio, video, and graphics files."
msgstr ""
-msgid "ProjectSettings|Maximum 500 characters."
+msgid "ProjectSettings|Maximum %{maxLength} characters."
msgstr ""
msgid "ProjectSettings|Merge checks"
@@ -28330,6 +28943,9 @@ msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
msgstr ""
+msgid "ProjectSettings|The default template will be applied on save."
+msgstr ""
+
msgid "ProjectSettings|These checks must pass before merge requests can be merged."
msgstr ""
@@ -28384,6 +29000,9 @@ msgstr ""
msgid "ProjectSettings|What are badges?"
msgstr ""
+msgid "ProjectSettings|What are merge trains?"
+msgstr ""
+
msgid "ProjectSettings|When merge request pipelines are enabled in the CI/CD configuration file, pipelines validate the combined results of the source and target branches. %{link_start}How to configure merge request pipelines?%{link_end}"
msgstr ""
@@ -28501,6 +29120,9 @@ msgstr ""
msgid "Projects are organized into groups"
msgstr ""
+msgid "Projects are where you store your code, access issues, wiki and other features of GitLab."
+msgstr ""
+
msgid "Projects contributed to"
msgstr ""
@@ -28516,12 +29138,6 @@ msgstr ""
msgid "Projects to index"
msgstr ""
-msgid "Projects will be permanently deleted after a %{waiting_period}-day waiting period."
-msgstr ""
-
-msgid "Projects will be permanently deleted immediately."
-msgstr ""
-
msgid "Projects with critical vulnerabilities"
msgstr ""
@@ -28606,6 +29222,9 @@ msgstr ""
msgid "ProjectsNew|Import project"
msgstr ""
+msgid "ProjectsNew|Include a Getting Started README"
+msgstr ""
+
msgid "ProjectsNew|Initialize repository with a README"
msgstr ""
@@ -28621,6 +29240,9 @@ msgstr ""
msgid "ProjectsNew|Project description %{tag_start}(optional)%{tag_end}"
msgstr ""
+msgid "ProjectsNew|Recommended if you're new to GitLab"
+msgstr ""
+
msgid "ProjectsNew|Run CI/CD for external repository"
msgstr ""
@@ -29038,6 +29660,9 @@ msgstr ""
msgid "ProtectedBranch|Unprotect"
msgstr ""
+msgid "ProtectedBranch|Unprotect branch"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
@@ -29065,6 +29690,9 @@ msgstr ""
msgid "ProtectedEnvironment|Protected Environment (%{protected_environments_count})"
msgstr ""
+msgid "ProtectedEnvironment|Required approvals"
+msgstr ""
+
msgid "ProtectedEnvironment|Select an environment"
msgstr ""
@@ -29086,10 +29714,13 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|Unprotect tag"
+msgstr ""
+
msgid "ProtectedTags|default"
msgstr ""
-msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
+msgid "ProtectedTag|By default, protected tags restrict who can modify the tag."
msgstr ""
msgid "ProtectedTag|Learn more."
@@ -29152,6 +29783,9 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Public projects are an easy way to allow everyone to have read-only access."
+msgstr ""
+
msgid "Publish to status page"
msgstr ""
@@ -29308,9 +29942,6 @@ msgstr ""
msgid "QualitySummary|Project quality"
msgstr ""
-msgid "Quarters"
-msgstr ""
-
msgid "Query"
msgstr ""
@@ -29395,6 +30026,9 @@ msgstr ""
msgid "Read more about project permissions %{help_link_open}here%{help_link_close}"
msgstr ""
+msgid "Read more about related epics"
+msgstr ""
+
msgid "Read more about related issues"
msgstr ""
@@ -29425,10 +30059,7 @@ msgstr ""
msgid "Rebase source branch on the target branch."
msgstr ""
-msgid "Rebase without CI"
-msgstr ""
-
-msgid "Rebases and triggers a pipeline"
+msgid "Rebase without pipeline"
msgstr ""
msgid "Recaptcha verified?"
@@ -29479,9 +30110,6 @@ msgstr ""
msgid "Reconfigure"
msgstr ""
-msgid "Recovering projects"
-msgstr ""
-
msgid "Recovery Codes"
msgstr ""
@@ -29541,6 +30169,12 @@ msgstr ""
msgid "Regex pattern"
msgstr ""
+msgid "Region"
+msgstr ""
+
+msgid "Regions"
+msgstr ""
+
msgid "Register"
msgstr ""
@@ -29771,9 +30405,6 @@ msgstr ""
msgid "Remove all or specific reviewer(s)"
msgstr ""
-msgid "Remove approver"
-msgstr ""
-
msgid "Remove approvers"
msgstr ""
@@ -29789,6 +30420,9 @@ msgstr ""
msgid "Remove attention request"
msgstr ""
+msgid "Remove attention request(s)"
+msgstr ""
+
msgid "Remove avatar"
msgstr ""
@@ -29927,6 +30561,9 @@ msgstr ""
msgid "Removed an issue from an epic."
msgstr ""
+msgid "Removed attention from %{users_sentence}."
+msgstr ""
+
msgid "Removed attention request from @%{username}"
msgstr ""
@@ -29978,6 +30615,9 @@ msgstr ""
msgid "Removes an issue from an epic."
msgstr ""
+msgid "Removes attention from %{users_sentence}."
+msgstr ""
+
msgid "Removes parent epic %{epic_ref}."
msgstr ""
@@ -30089,6 +30729,9 @@ msgstr ""
msgid "Report abuse to admin"
msgstr ""
+msgid "Report is generating and will be sent to your email address."
+msgstr ""
+
msgid "Reported %{timeAgo} by %{reportedBy}"
msgstr ""
@@ -30378,6 +31021,15 @@ msgstr ""
msgid "Request attention"
msgstr ""
+msgid "Request attention from %{users_sentence}."
+msgstr ""
+
+msgid "Request attention from assignee or reviewer"
+msgstr ""
+
+msgid "Request attention from assignee(s) or reviewer(s)"
+msgstr ""
+
msgid "Request attention to review"
msgstr ""
@@ -30402,6 +31054,9 @@ msgstr ""
msgid "Requested %{time_ago}"
msgstr ""
+msgid "Requested attention from %{users_sentence}."
+msgstr ""
+
msgid "Requested attention from @%{username}"
msgstr ""
@@ -30616,6 +31271,9 @@ msgstr ""
msgid "Restore project"
msgstr ""
+msgid "Restoring projects"
+msgstr ""
+
msgid "Restoring the group will prevent the group, its subgroups and projects from being removed on this date."
msgstr ""
@@ -30646,6 +31304,9 @@ msgstr ""
msgid "Retry"
msgstr ""
+msgid "Retry failed jobs"
+msgstr ""
+
msgid "Retry job"
msgstr ""
@@ -30693,9 +31354,6 @@ msgstr ""
msgid "Review changes"
msgstr ""
-msgid "Review requested from %{name}"
-msgstr ""
-
msgid "Review requests for you"
msgstr ""
@@ -30860,6 +31518,9 @@ msgstr ""
msgid "Runners|Assigned Group"
msgstr ""
+msgid "Runners|Assigned Projects (%{projectCount})"
+msgstr ""
+
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30929,6 +31590,9 @@ msgstr ""
msgid "Runners|Instance"
msgstr ""
+msgid "Runners|Jobs"
+msgstr ""
+
msgid "Runners|Last contact"
msgstr ""
@@ -31022,9 +31686,6 @@ msgstr ""
msgid "Runners|Runner %{name} was deleted"
msgstr ""
-msgid "Runners|Runner ID"
-msgstr ""
-
msgid "Runners|Runner assigned to project."
msgstr ""
@@ -31172,6 +31833,9 @@ msgstr ""
msgid "Runners|stale"
msgstr ""
+msgid "Runner|This runner has not run any jobs."
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -31286,6 +31950,24 @@ msgstr ""
msgid "Saving project."
msgstr ""
+msgid "ScanResultPolicy|%{ifLabelStart}if%{ifLabelEnd} %{scanners} scan in an open merge request targeting the %{branches} branch(es) finds %{vulnerabilitiesAllowed} or more %{severities} vulnerabilities that are %{vulnerabilityStates}"
+msgstr ""
+
+msgid "ScanResultPolicy|%{thenLabelStart}Then%{thenLabelEnd} Require approval from %{approvalsRequired} of the following approvers: %{approvers}"
+msgstr ""
+
+msgid "ScanResultPolicy|add an approver"
+msgstr ""
+
+msgid "ScanResultPolicy|scanners"
+msgstr ""
+
+msgid "ScanResultPolicy|severity levels"
+msgstr ""
+
+msgid "ScanResultPolicy|vulnerability states"
+msgstr ""
+
msgid "Scanner"
msgstr ""
@@ -31418,6 +32100,9 @@ msgstr ""
msgid "Search for a user"
msgstr ""
+msgid "Search for an emoji"
+msgstr ""
+
msgid "Search for projects, issues, etc."
msgstr ""
@@ -31605,18 +32290,12 @@ msgstr ""
msgid "Secret Detection"
msgstr ""
-msgid "Secret access key"
-msgstr ""
-
msgid "Secret token"
msgstr ""
msgid "Secure token that identifies an external storage request."
msgstr ""
-msgid "SecureCodeWarrior"
-msgstr ""
-
msgid "Security"
msgstr ""
@@ -31641,9 +32320,6 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "Security training with guide and learning pathways."
-msgstr ""
-
msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
@@ -31746,7 +32422,7 @@ msgstr ""
msgid "SecurityConfiguration|Manage corpus"
msgstr ""
-msgid "SecurityConfiguration|Manage corpus files used as mutation sources in coverage fuzzing."
+msgid "SecurityConfiguration|Manage corpus files used as seed inputs with coverage-guided fuzzing."
msgstr ""
msgid "SecurityConfiguration|Manage profiles for use by DAST scans."
@@ -31812,15 +32488,15 @@ msgstr ""
msgid "SecurityOrchestration|.yaml preview"
msgstr ""
-msgid "SecurityOrchestration|Action"
-msgstr ""
-
msgid "SecurityOrchestration|Actions"
msgstr ""
msgid "SecurityOrchestration|Add rule"
msgstr ""
+msgid "SecurityOrchestration|After dismissing the alert, the information will never be shown again."
+msgstr ""
+
msgid "SecurityOrchestration|All policies"
msgstr ""
@@ -31836,7 +32512,7 @@ msgstr ""
msgid "SecurityOrchestration|Description"
msgstr ""
-msgid "SecurityOrchestration|Disabled"
+msgid "SecurityOrchestration|Don't show the alert anymore"
msgstr ""
msgid "SecurityOrchestration|Edit policy"
@@ -31845,13 +32521,13 @@ msgstr ""
msgid "SecurityOrchestration|Edit policy project"
msgstr ""
-msgid "SecurityOrchestration|Enabled"
+msgid "SecurityOrchestration|Empty policy name"
msgstr ""
-msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Enabled"
msgstr ""
-msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
msgstr ""
msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
@@ -31860,7 +32536,7 @@ msgstr ""
msgid "SecurityOrchestration|Invalid policy type"
msgstr ""
-msgid "SecurityOrchestration|Latest scan"
+msgid "SecurityOrchestration|Latest scan run against %{agent}"
msgstr ""
msgid "SecurityOrchestration|Network"
@@ -31869,15 +32545,27 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No actions defined - policy will not run."
+msgstr ""
+
+msgid "SecurityOrchestration|No description"
+msgstr ""
+
msgid "SecurityOrchestration|No rules defined - policy will not run."
msgstr ""
+msgid "SecurityOrchestration|Not enabled"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
msgid "SecurityOrchestration|Policies"
msgstr ""
+msgid "SecurityOrchestration|Policy Type"
+msgstr ""
+
msgid "SecurityOrchestration|Policy cannot be enabled for non-existing branches (%{branches})"
msgstr ""
@@ -31902,10 +32590,13 @@ msgstr ""
msgid "SecurityOrchestration|Require %{approvals} %{plural} from %{approvers} if any of the following occur:"
msgstr ""
-msgid "SecurityOrchestration|Rule"
+msgid "SecurityOrchestration|Rules"
msgstr ""
-msgid "SecurityOrchestration|Rules"
+msgid "SecurityOrchestration|Runs %{actions} and %{lastAction} scans"
+msgstr ""
+
+msgid "SecurityOrchestration|Runs a %{action} scan"
msgstr ""
msgid "SecurityOrchestration|Scan Execution"
@@ -31965,6 +32656,9 @@ msgstr ""
msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
+msgid "SecurityOrchestration|This view only shows scan results for the agent %{agent}. You can view scan results for all agents in the %{linkStart}Operational Vulnerabilities tab of the vulnerability report%{linkEnd}."
+msgstr ""
+
msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
@@ -32019,9 +32713,6 @@ msgstr ""
msgid "SecurityOrchestration|users with ids"
msgstr ""
-msgid "SecurityOrchestration|view results"
-msgstr ""
-
msgid "SecurityOrchestration|vulnerabilities"
msgstr ""
@@ -32691,22 +33382,19 @@ 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|In order to start using functions as a service, you must first install Knative on your Kubernetes cluster. %{linkStart}More information%{linkEnd}"
-msgstr ""
-
msgid "Serverless|Learn more about Serverless"
msgstr ""
msgid "Serverless|No functions available"
msgstr ""
-msgid "Serverless|Sign up for First Look"
+msgid "Serverless|Serverless was %{linkStart}deprecated%{linkEnd} in GitLab 14.3."
+msgstr ""
+
+msgid "Serverless|Serverless was %{postLinkStart}deprecated%{postLinkEnd}. But if you opt to use it, you must install Knative in your Kubernetes cluster first. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "Serverless|The deploy job has not finished."
@@ -32718,9 +33406,6 @@ 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 ""
@@ -32736,9 +33421,6 @@ msgstr ""
msgid "Service Account Key"
msgstr ""
-msgid "Service Accounts"
-msgstr ""
-
msgid "Service Accounts keys authorize GitLab to deploy your Google Cloud project"
msgstr ""
@@ -32748,10 +33430,10 @@ msgstr ""
msgid "Service Desk allows people to create issues in your GitLab instance without their own user account. It provides a unique email address for end users to create issues in a project. Replies can be sent either through the GitLab interface or by email. End users only see threads through email."
msgstr ""
-msgid "Service Usage Data"
+msgid "Service account generated successfully"
msgstr ""
-msgid "Service account generated successfully"
+msgid "Service accounts"
msgstr ""
msgid "Service ping is disabled in your configuration file, and cannot be enabled through this form."
@@ -32895,6 +33577,9 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
+msgid "Set the per-user rate limit for getting a user by ID via the API."
+msgstr ""
+
msgid "Set the per-user rate limit for notes created by web or API requests."
msgstr ""
@@ -33074,6 +33759,9 @@ msgstr ""
msgid "Shared runners details"
msgstr ""
+msgid "Shared runners enabled cannot be enabled until a valid credit card is on file"
+msgstr ""
+
msgid "Shared runners help link"
msgstr ""
@@ -33131,6 +33819,9 @@ msgstr ""
msgid "Show all issues."
msgstr ""
+msgid "Show all milestones"
+msgstr ""
+
msgid "Show all test cases."
msgstr ""
@@ -33167,6 +33858,9 @@ msgstr ""
msgid "Show file contents"
msgstr ""
+msgid "Show group milestones"
+msgstr ""
+
msgid "Show labels"
msgstr ""
@@ -33182,6 +33876,12 @@ msgstr ""
msgid "Show open epics"
msgstr ""
+msgid "Show project milestones"
+msgstr ""
+
+msgid "Show sub-group milestones"
+msgstr ""
+
msgid "Show the Closed list"
msgstr ""
@@ -33191,11 +33891,6 @@ msgstr ""
msgid "Show whitespace changes"
msgstr ""
-msgid "Showing %d event"
-msgid_plural "Showing %d events"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Showing %{conflict} between %{sourceBranch} and %{targetBranch}"
msgstr ""
@@ -33255,12 +33950,6 @@ msgstr ""
msgid "Sidebar|None"
msgstr ""
-msgid "Sidebar|Only numeral characters allowed"
-msgstr ""
-
-msgid "Sidebar|Weight"
-msgstr ""
-
msgid "Sidekiq job compression threshold (bytes)"
msgstr ""
@@ -33423,6 +34112,9 @@ msgstr ""
msgid "Slack logo"
msgstr ""
+msgid "SlackIntegration|Are you sure you want to remove this project from the Slack application?"
+msgstr ""
+
msgid "SlackIntegration|GitLab for Slack"
msgstr ""
@@ -33432,6 +34124,9 @@ msgstr ""
msgid "SlackIntegration|Project alias"
msgstr ""
+msgid "SlackIntegration|Remove project"
+msgstr ""
+
msgid "SlackIntegration|Select a GitLab project to link with your Slack workspace."
msgstr ""
@@ -33576,9 +34271,6 @@ msgstr ""
msgid "Something went wrong trying to load issue contacts."
msgstr ""
-msgid "Something went wrong when creating a work item. Please try again"
-msgstr ""
-
msgid "Something went wrong when reordering designs. Please try again"
msgstr ""
@@ -33672,9 +34364,6 @@ msgstr ""
msgid "Something went wrong while inserting your image. Please try again."
msgstr ""
-msgid "Something went wrong while merging this merge request. Please try again."
-msgstr ""
-
msgid "Something went wrong while obtaining the Let's Encrypt certificate."
msgstr ""
@@ -33996,10 +34685,10 @@ 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."
+msgid "SourcegraphAdmin|Learn more."
msgstr ""
-msgid "SourcegraphAdmin|More information"
+msgid "SourcegraphAdmin|Only public projects have code intelligence enabled and communicate with Sourcegraph."
msgstr ""
msgid "SourcegraphAdmin|Save changes"
@@ -34008,7 +34697,7 @@ msgstr ""
msgid "SourcegraphAdmin|Sourcegraph URL"
msgstr ""
-msgid "SourcegraphAdmin|e.g. https://sourcegraph.example.com"
+msgid "SourcegraphAdmin|https://sourcegraph.example.com"
msgstr ""
msgid "SourcegraphPreferences|This feature is experimental and currently limited to certain projects."
@@ -34143,6 +34832,9 @@ msgstr ""
msgid "Start date"
msgstr ""
+msgid "Start free trial"
+msgstr ""
+
msgid "Start merge train"
msgstr ""
@@ -34173,6 +34865,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started escalation for this incident."
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -34185,6 +34880,9 @@ msgstr ""
msgid "Starts at (UTC)"
msgstr ""
+msgid "Starts escalations for this incident"
+msgstr ""
+
msgid "Starts on"
msgstr ""
@@ -34446,6 +35144,9 @@ msgstr ""
msgid "Strikethrough"
msgstr ""
+msgid "Strikethrough text"
+msgstr ""
+
msgid "Subgroup information"
msgstr ""
@@ -34680,6 +35381,21 @@ msgstr ""
msgid "Subscriptions"
msgstr ""
+msgid "Subscriptions|Chat with sales"
+msgstr ""
+
+msgid "Subscriptions|Close"
+msgstr ""
+
+msgid "Subscriptions|Not ready to buy yet?"
+msgstr ""
+
+msgid "Subscriptions|Start a free trial"
+msgstr ""
+
+msgid "Subscriptions|We understand. Maybe you have some questions for our sales team, or maybe you'd like to try some of the paid features first. What would you like to do?"
+msgstr ""
+
msgid "Subscription|Your subscription for %{strong}%{namespace_name}%{strong_close} has expired and you are now on %{pricing_link_start}the GitLab Free tier%{pricing_link_end}. Don't worry, your data is safe. Get in touch with our support team (%{support_email}). They'll gladly help with your subscription renewal."
msgstr ""
@@ -34890,6 +35606,9 @@ msgstr ""
msgid "SuperSonics|Maximum users"
msgstr ""
+msgid "SuperSonics|Offline cloud"
+msgstr ""
+
msgid "SuperSonics|Paste your activation code"
msgstr ""
@@ -34956,6 +35675,12 @@ msgstr ""
msgid "SuperSonics|You do not have an active subscription"
msgstr ""
+msgid "SuperSonics|You have a future dated license"
+msgstr ""
+
+msgid "SuperSonics|You have added a license that activates on %{date}. Please see the subscription history table below for more details."
+msgstr ""
+
msgid "SuperSonics|You have successfully added a license that activates on %{date}. Please see the subscription history table below for more details."
msgstr ""
@@ -35115,6 +35840,9 @@ msgstr ""
msgid "Tag name is required"
msgstr ""
+msgid "Tag push"
+msgstr ""
+
msgid "Tag push events"
msgstr ""
@@ -35217,6 +35945,9 @@ msgstr ""
msgid "TagsPage|protected"
msgstr ""
+msgid "Take a look at the documentation to discover all of GitLab’s capabilities."
+msgstr ""
+
msgid "Target Branch"
msgstr ""
@@ -35619,6 +36350,9 @@ msgstr ""
msgid "Tests"
msgstr ""
+msgid "Text (optional)"
+msgstr ""
+
msgid "Text added to the body of all email messages. %{character_limit} character limit"
msgstr ""
@@ -35669,6 +36403,9 @@ msgstr ""
msgid "The CSV export will be created in the background. Once finished, it will be sent to %{email} in an attachment."
msgstr ""
+msgid "The CSV export you requested of all user memberships is attached to this email."
+msgstr ""
+
msgid "The GitLab subscription service (customers.gitlab.com) is currently experiencing an outage. You can monitor the status and get updates at %{linkStart}status.gitlab.com%{linkEnd}."
msgstr ""
@@ -35744,6 +36481,9 @@ 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 epic"
+msgstr ""
+
msgid "The current issue"
msgstr ""
@@ -35905,6 +36645,9 @@ msgstr ""
msgid "The latest pipeline for this merge request has failed."
msgstr ""
+msgid "The license key is invalid."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -35920,6 +36663,9 @@ msgstr ""
msgid "The license was successfully uploaded and will be active from %{starts_at}. You can see the details below."
msgstr ""
+msgid "The license you uploaded is invalid. If the issue persists, contact support at %{link}."
+msgstr ""
+
msgid "The list creation wizard is already open"
msgstr ""
@@ -36541,10 +37287,13 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} and everything this project contains. %{strongOpen}There is no going back%{strongClose}"
+msgstr ""
+
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains."
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}on %{date}%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains. %{strongOpen}There is no going back.%{strongClose}"
msgstr ""
msgid "This action will %{strongOpen}permanently remove%{strongClose} %{codeOpen}%{group}%{codeClose} %{strongOpen}immediately%{strongClose}."
@@ -36673,9 +37422,6 @@ msgstr ""
msgid "This file was modified for readability, and can't accept suggestions. Edit it directly."
msgstr ""
-msgid "This forked project has the following:"
-msgstr ""
-
msgid "This form is disabled in preview"
msgstr ""
@@ -36688,7 +37434,7 @@ msgstr ""
msgid "This group can't be removed because it is linked to a subscription. To remove this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
-msgid "This group can't be transfered because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
+msgid "This group can't be transferred because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
msgid "This group cannot be invited to a project inside a group with enforced SSO"
@@ -36715,6 +37461,9 @@ 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 incident is already escalated with '%{escalation_policy_name}'."
+msgstr ""
+
msgid "This invitation was sent to %{mail_to_invite_email}, but you are signed in as %{link_to_current_user} with email %{mail_to_current_user}."
msgstr ""
@@ -36733,9 +37482,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 merge train pipeline"
-msgstr ""
-
msgid "This is a private email address %{helpIcon} generated just for you. Anyone who has it can create issues or merge requests as if they were you. If that happens, %{resetLinkStart}reset this token%{resetLinkEnd}."
msgstr ""
@@ -36757,6 +37503,12 @@ msgstr ""
msgid "This is your current session"
msgstr ""
+msgid "This issue cannot be assigned to a confidential epic because it is public."
+msgstr ""
+
+msgid "This issue cannot be made public because it belongs to a confidential epic."
+msgstr ""
+
msgid "This issue is confidential and should only be visible to team members with at least Reporter access."
msgstr ""
@@ -36874,6 +37626,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 branch is protected from force push."
+msgstr ""
+
msgid "This merge request cannot be rebased while there are conflicts."
msgstr ""
@@ -36925,9 +37680,15 @@ msgstr ""
msgid "This pipeline was triggered by a schedule."
msgstr ""
+msgid "This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project"
msgstr ""
+msgid "This project can be restored until %{date}."
+msgstr ""
+
msgid "This project cannot be %{visibilityLevel} because the visibility of %{openShowLink}%{name}%{closeShowLink} is %{visibility}. To make this project %{visibilityLevel}, you must first %{openEditLink}change the visibility%{closeEditLink} of the parent group."
msgstr ""
@@ -36946,6 +37707,9 @@ msgstr ""
msgid "This project is %{strongStart}NOT%{strongEnd} a fork, and has the following:"
msgstr ""
+msgid "This project is %{strongStart}NOT%{strongEnd} a fork. This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -37637,6 +38401,9 @@ msgstr ""
msgid "Today"
msgstr ""
+msgid "Todos count"
+msgstr ""
+
msgid "Todos|Are you looking for things to do? Take a look at %{strongStart}%{openIssuesLinkStart}open issues%{openIssuesLinkEnd}%{strongEnd}, contribute to %{strongStart}%{mergeRequestLinkStart}a merge request%{mergeRequestLinkEnd}%{mergeRequestLinkEnd}%{strongEnd}, or mention someone in a comment to automatically assign them a new to-do item."
msgstr ""
@@ -37910,10 +38677,8 @@ msgstr ""
msgid "Trending"
msgstr ""
-msgid "Trials|%{planName} Trial %{enDash} %{num} day left"
-msgid_plural "Trials|%{planName} Trial %{enDash} %{num} days left"
-msgstr[0] ""
-msgstr[1] ""
+msgid "Trials|%{planName} Trial"
+msgstr ""
msgid "Trials|Compare all plans"
msgstr ""
@@ -37921,6 +38686,9 @@ msgstr ""
msgid "Trials|Create a new group to start your GitLab Ultimate trial."
msgstr ""
+msgid "Trials|Day %{daysUsed}/%{duration}"
+msgstr ""
+
msgid "Trials|Go back to GitLab"
msgstr ""
@@ -38170,7 +38938,7 @@ msgstr ""
msgid "URL is triggered when repository is updated"
msgstr ""
-msgid "URL must be percent-encoded if neccessary."
+msgid "URL must be percent-encoded if necessary."
msgstr ""
msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
@@ -38389,6 +39157,9 @@ msgstr ""
msgid "Unlock account"
msgstr ""
+msgid "Unlock more features with GitLab Ultimate"
+msgstr ""
+
msgid "Unlock the discussion"
msgstr ""
@@ -38452,6 +39223,9 @@ msgstr ""
msgid "Unsubscribes from this %{quick_action_target}."
msgstr ""
+msgid "Unsupported sort value."
+msgstr ""
+
msgid "Unsupported todo type passed. Supported todo types are: %{todo_types}"
msgstr ""
@@ -38680,6 +39454,9 @@ msgstr ""
msgid "UsageQuota|File attachments and smaller design graphics."
msgstr ""
+msgid "UsageQuota|From %{storage_enforcement_date} storage limits will apply to this namespace. View and manage your usage in %{strong_start}Group Settings &gt; Usage quotas%{strong_end}."
+msgstr ""
+
msgid "UsageQuota|Git repository."
msgstr ""
@@ -38740,6 +39517,9 @@ msgstr ""
msgid "UsageQuota|Storage type"
msgstr ""
+msgid "UsageQuota|Storage used"
+msgstr ""
+
msgid "UsageQuota|This is the total amount of storage used across your projects within this namespace."
msgstr ""
@@ -38935,6 +39715,12 @@ msgstr ""
msgid "Use hashed storage paths for newly created and renamed repositories. Always enabled since 13.0."
msgstr ""
+msgid "Use issue count"
+msgstr ""
+
+msgid "Use issue weight"
+msgstr ""
+
msgid "Use one line per URI"
msgstr ""
@@ -39316,6 +40102,9 @@ msgstr ""
msgid "Users"
msgstr ""
+msgid "Users API rate limit"
+msgstr ""
+
msgid "Users can launch a development environment from a GitLab browser tab when the %{linkStart}Gitpod%{linkEnd} integration is enabled."
msgstr ""
@@ -39641,6 +40430,9 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View group pipeline usage quota"
+msgstr ""
+
msgid "View incident details at"
msgstr ""
@@ -39793,6 +40585,9 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
+msgid "Vulnerability"
+msgstr ""
+
msgid "Vulnerability Report"
msgstr ""
@@ -39844,6 +40639,9 @@ msgstr ""
msgid "VulnerabilityManagement|An unverified non-confirmed finding"
msgstr ""
+msgid "VulnerabilityManagement|At least one identifier is required"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -39853,12 +40651,24 @@ msgstr ""
msgid "VulnerabilityManagement|Create Jira issue"
msgstr ""
+msgid "VulnerabilityManagement|Enter a name"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE code"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE identifier URL"
+msgstr ""
+
msgid "VulnerabilityManagement|Fetching linked Jira issues"
msgstr ""
msgid "VulnerabilityManagement|Manually add a vulnerability entry into the vulnerability report."
msgstr ""
+msgid "VulnerabilityManagement|Name is a required field"
+msgstr ""
+
msgid "VulnerabilityManagement|Needs triage"
msgstr ""
@@ -39874,6 +40684,18 @@ msgstr ""
msgid "VulnerabilityManagement|Select a method"
msgstr ""
+msgid "VulnerabilityManagement|Select a severity level"
+msgstr ""
+
+msgid "VulnerabilityManagement|Select a status"
+msgstr ""
+
+msgid "VulnerabilityManagement|Severity is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Something went wrong while creating vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -39898,6 +40720,12 @@ msgstr ""
msgid "VulnerabilityManagement|Something went wrong, could not update vulnerability state."
msgstr ""
+msgid "VulnerabilityManagement|Status is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Submit vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Summary, detailed description, steps to reproduce, etc."
msgstr ""
@@ -40093,6 +40921,9 @@ msgstr ""
msgid "WARNING:"
msgstr ""
+msgid "WARNING: This snippet contains hidden files which might be used to mask malicious behavior. Exercise caution if cloning and executing code from this snippet."
+msgstr ""
+
msgid "Wait for the file to load to copy its contents"
msgstr ""
@@ -40312,6 +41143,15 @@ msgstr ""
msgid "Webhooks|An issue is created, updated, closed, or reopened."
msgstr ""
+msgid "Webhooks|Are you sure you want to delete this group hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this project hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this webhook?"
+msgstr ""
+
msgid "Webhooks|Comments"
msgstr ""
@@ -40321,6 +41161,9 @@ msgstr ""
msgid "Webhooks|Confidential issues events"
msgstr ""
+msgid "Webhooks|Delete webhook"
+msgstr ""
+
msgid "Webhooks|Deployment events"
msgstr ""
@@ -40554,6 +41397,9 @@ msgstr ""
msgid "Wiki"
msgstr ""
+msgid "Wiki page"
+msgstr ""
+
msgid "Wiki page was successfully created."
msgstr ""
@@ -40659,7 +41505,7 @@ msgstr ""
msgid "WikiPageConflictMessage|Someone edited the page the same time you did. Please check out %{wikiLinkStart}the page%{wikiLinkEnd} and make sure your changes will not unintentionally remove theirs."
msgstr ""
-msgid "WikiPage|An error occured while trying to render the content editor. Please try again later."
+msgid "WikiPage|An error occurred while trying to render the content editor. Please try again later."
msgstr ""
msgid "WikiPage|Are you sure you want to switch back to the classic editor?"
@@ -40818,6 +41664,18 @@ msgstr ""
msgid "WorkItem|New Task"
msgstr ""
+msgid "WorkItem|Something went wrong when creating a work item. Please try again"
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching the work item. Please try again."
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching work item types. Please try again"
+msgstr ""
+
+msgid "WorkItem|Type"
+msgstr ""
+
msgid "WorkItem|Work Items"
msgstr ""
@@ -40884,7 +41742,10 @@ msgstr ""
msgid "You are about to add %{usersTag} people to the discussion. They will all receive a notification."
msgstr ""
-msgid "You are about to permanently delete this project"
+msgid "You are about to delete this forked project containing:"
+msgstr ""
+
+msgid "You are about to delete this project containing:"
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."
@@ -40905,6 +41766,9 @@ msgstr ""
msgid "You are attempting to update a file that has changed since you started editing it."
msgstr ""
+msgid "You are billed if you exceed this number. %{qsrOverageLinkStart}How does billing work?%{qsrOverageLinkEnd}"
+msgstr ""
+
msgid "You are connected to the Prometheus server, but there is currently no data to display."
msgstr ""
@@ -40962,6 +41826,9 @@ msgstr ""
msgid "You are not authorized to update this scanner profile"
msgstr ""
+msgid "You are not authorized to upload metric images"
+msgstr ""
+
msgid "You are now impersonating %{username}"
msgstr ""
@@ -41115,9 +41982,6 @@ msgstr ""
msgid "You can only upload one design when dropping onto an existing design."
msgstr ""
-msgid "You can recover this project until %{date}"
-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 ""
@@ -41166,9 +42030,6 @@ msgstr ""
msgid "You cannot write to this read-only GitLab instance."
msgstr ""
-msgid "You can’t %{tag_start}edit%{tag_end} files directly in this project. Fork this project and submit a merge request with your changes."
-msgstr ""
-
msgid "You can’t edit files directly in this project. Fork this project and submit a merge request with your changes."
msgstr ""
@@ -41321,9 +42182,6 @@ 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 set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
@@ -41354,12 +42212,6 @@ msgstr ""
msgid "You must have maintainer access to force delete a lock"
msgstr ""
-msgid "You must have permission to create a project in a group before forking."
-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 ""
@@ -41765,7 +42617,7 @@ msgstr ""
msgid "Your public email will be displayed on your public profile."
msgstr ""
-msgid "Your request for access could not be processed: %{error_meesage}"
+msgid "Your request for access could not be processed: %{error_message}"
msgstr ""
msgid "Your request for access has been queued for review."
@@ -41948,6 +42800,9 @@ msgstr ""
msgid "archived:"
msgstr ""
+msgid "artifacts"
+msgstr ""
+
msgid "assign yourself"
msgstr ""
@@ -41977,6 +42832,9 @@ msgstr[1] ""
msgid "branch name"
msgstr ""
+msgid "builds"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -42400,6 +43258,9 @@ msgstr ""
msgid "contact with same email already exists in group hierarchy"
msgstr ""
+msgid "container registry images"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -42439,6 +43300,9 @@ msgstr ""
msgid "data"
msgstr ""
+msgid "database"
+msgstr ""
+
msgid "date must not be after 9999-12-31"
msgstr ""
@@ -42462,9 +43326,6 @@ msgstr ""
msgid "design"
msgstr ""
-msgid "detached"
-msgstr ""
-
msgid "disabled"
msgstr ""
@@ -42713,7 +43574,7 @@ msgstr ""
msgid "is not a valid X509 certificate."
msgstr ""
-msgid "is not allowed for sign-up."
+msgid "is not allowed for sign-up. Please use your regular email address."
msgstr ""
msgid "is not allowed for this group."
@@ -42725,7 +43586,7 @@ msgstr ""
msgid "is not allowed since the group is not top-level group."
msgstr ""
-msgid "is not allowed."
+msgid "is not allowed. Please use your regular email address."
msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
@@ -42812,6 +43673,9 @@ msgstr ""
msgid "level: %{level}"
msgstr ""
+msgid "lfs objects"
+msgstr ""
+
msgid "limit of %{project_limit} reached"
msgstr ""
@@ -43031,6 +43895,9 @@ msgstr ""
msgid "mrWidget|Merge blocked: pipeline must succeed. It's waiting for a manual action to continue."
msgstr ""
+msgid "mrWidget|Merge blocked: pipeline must succeed. Push a commit that fixes the failure, or %{linkStart}learn about other solutions.%{linkEnd}"
+msgstr ""
+
msgid "mrWidget|Merge blocked: this merge request must be approved."
msgstr ""
@@ -43148,9 +44015,6 @@ msgstr ""
msgid "mrWidget|The changes were not merged into"
msgstr ""
-msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -43298,9 +44162,6 @@ msgstr ""
msgid "open issue"
msgstr ""
-msgid "opened %{timeAgo}"
-msgstr ""
-
msgid "or"
msgstr ""
@@ -43312,6 +44173,12 @@ msgid_plural "out of %d total tests"
msgstr[0] ""
msgstr[1] ""
+msgid "packages"
+msgstr ""
+
+msgid "pages"
+msgstr ""
+
msgid "parent"
msgid_plural "parents"
msgstr[0] ""
@@ -43461,6 +44328,9 @@ msgid_plural "replies"
msgstr[0] ""
msgstr[1] ""
+msgid "repositories"
+msgstr ""
+
msgid "repository:"
msgstr ""
@@ -43581,12 +44451,18 @@ msgstr ""
msgid "tag name"
msgstr ""
+msgid "terraform states"
+msgstr ""
+
msgid "the correct format."
msgstr ""
msgid "the file"
msgstr ""
+msgid "the following epic(s)"
+msgstr ""
+
msgid "the following issue(s)"
msgstr ""
@@ -43599,21 +44475,12 @@ msgstr ""
msgid "this document"
msgstr ""
-msgid "this issue cannot be assigned to a confidential epic since it is public"
-msgstr ""
-
-msgid "this issue cannot be made public since it belongs to a confidential epic"
-msgstr ""
-
msgid "time summary"
msgstr ""
msgid "toggle collapse"
msgstr ""
-msgid "train"
-msgstr ""
-
msgid "triggered"
msgstr ""
@@ -43742,3 +44609,6 @@ msgstr ""
msgid "{project}"
msgstr ""
+msgid "✔"
+msgstr ""
+
diff --git a/locale/bn_IN/gitlab.po b/locale/bn_IN/gitlab.po
index 620f7ee1485..5aaabaaf15e 100644
--- a/locale/bn_IN/gitlab.po
+++ b/locale/bn_IN/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: bn-IN\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2022-02-02 15:47\n"
+"PO-Revision-Date: 2022-03-01 20:40\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -146,6 +146,11 @@ msgid_plural "%d approvers (you've approved)"
msgstr[0] ""
msgstr[1] ""
+msgid "%d assigned issue"
+msgid_plural "%d assigned issues"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -421,8 +426,23 @@ msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
msgstr[1] ""
-msgid "%d vulnerability updated"
-msgid_plural "%d vulnerabilities updated"
+msgid "%d vulnerability set to confirmed"
+msgid_plural "%d vulnerabilities set to confirmed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to dismissed"
+msgid_plural "%d vulnerabilities set to dismissed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to needs triage"
+msgid_plural "%d vulnerabilities set to needs triage"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to resolved"
+msgid_plural "%d vulnerabilities set to resolved"
msgstr[0] ""
msgstr[1] ""
@@ -510,6 +530,12 @@ msgstr[1] ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{completed} of %{total} issues closed"
+msgstr ""
+
+msgid "%{completed} of %{total} weight completed"
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -858,6 +884,9 @@ msgstr ""
msgid "%{openedIssues} open, %{closedIssues} closed"
msgstr ""
+msgid "%{percentage}%% issues closed"
+msgstr ""
+
msgid "%{percentage}%% weight completed"
msgstr ""
@@ -1287,6 +1316,9 @@ msgid_plural "- Users"
msgstr[0] ""
msgstr[1] ""
+msgid "- of - issues closed"
+msgstr ""
+
msgid "- of - weight completed"
msgstr ""
@@ -1429,7 +1461,7 @@ msgstr ""
msgid "1000+"
msgstr ""
-msgid "192.168.0.0/24"
+msgid "192.168.0.0/24 or 2001:0DB8:1234::/48"
msgstr ""
msgid "1st contribution!"
@@ -1741,13 +1773,13 @@ msgstr ""
msgid "AWS Access Key"
msgstr ""
-msgid "AWS Access Key. Only required if not using role instance credentials"
+msgid "AWS Secret Access Key"
msgstr ""
-msgid "AWS Secret Access Key"
+msgid "AWS access key ID (Optional)"
msgstr ""
-msgid "AWS Secret Access Key. Only required if not using role instance credentials"
+msgid "AWS secret access key (Optional)"
msgstr ""
msgid "AWS service error: %{error}"
@@ -1807,9 +1839,6 @@ msgstr ""
msgid "Access granted"
msgstr ""
-msgid "Access key ID"
-msgstr ""
-
msgid "Access requests"
msgstr ""
@@ -1984,7 +2013,7 @@ msgstr ""
msgid "Activity"
msgstr ""
-msgid "Activity|An error occured while retrieving activity. Reload the page to try again."
+msgid "Activity|An error occurred while retrieving activity. Reload the page to try again."
msgstr ""
msgid "Add"
@@ -2023,6 +2052,9 @@ msgstr ""
msgid "Add a %{type}"
msgstr ""
+msgid "Add a GCP region"
+msgstr ""
+
msgid "Add a GPG key"
msgstr ""
@@ -2074,6 +2106,9 @@ msgstr ""
msgid "Add a numbered list"
msgstr ""
+msgid "Add a related epic"
+msgstr ""
+
msgid "Add a related issue"
msgstr ""
@@ -2188,6 +2223,9 @@ msgstr ""
msgid "Add or subtract spent time"
msgstr ""
+msgid "Add people"
+msgstr ""
+
msgid "Add previously merged commits"
msgstr ""
@@ -2254,6 +2292,9 @@ msgstr ""
msgid "Add webhook"
msgstr ""
+msgid "Add your team members and others to GitLab."
+msgstr ""
+
msgid "Add/remove"
msgstr ""
@@ -3076,12 +3117,6 @@ msgstr ""
msgid "AdvancedSearch|Reindex required"
msgstr ""
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. Permanently deleting this project will %{strongStart}immediately delete%{strongEnd} its repositories and %{strongStart}all related resources%{strongEnd}, including issues, merge requests etc."
-msgstr ""
-
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. You will lose this project's repository and %{strongStart}all related resources%{strongEnd}, including issues and merge requests."
-msgstr ""
-
msgid "After a successful password update you will be redirected to login screen."
msgstr ""
@@ -3112,6 +3147,9 @@ msgstr ""
msgid "Akismet helps prevent the creation of spam issues in public projects."
msgstr ""
+msgid "Alert"
+msgstr ""
+
msgid "AlertManagement|Acknowledged"
msgstr ""
@@ -3484,9 +3522,6 @@ msgstr ""
msgid "All environments"
msgstr ""
-msgid "All epics"
-msgstr ""
-
msgid "All groups and projects"
msgstr ""
@@ -4223,12 +4258,15 @@ msgstr ""
msgid "ApplicationSettings|Approve users in the pending approval status?"
msgstr ""
-msgid "ApplicationSettings|By making this change, you will automatically approve %d user with the pending approval status."
-msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users with the pending approval status."
+msgid "ApplicationSettings|Approve users who are pending approval?"
+msgstr ""
+
+msgid "ApplicationSettings|By making this change, you will automatically approve %d user who is pending approval."
+msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users who are pending approval."
msgstr[0] ""
msgstr[1] ""
-msgid "ApplicationSettings|By making this change, you will automatically approve all users in pending approval status."
+msgid "ApplicationSettings|By making this change, you will automatically approve all users who are pending approval."
msgstr ""
msgid "ApplicationSettings|Denied domains for sign-ups"
@@ -4634,10 +4672,10 @@ msgstr ""
msgid "Archiving the project will make it entirely read-only. It is hidden from the dashboard and doesn't show up in searches. %{strong_start}The repository cannot be committed to, and no issues, comments, or other entities can be created.%{strong_end} %{link_start}Learn more.%{link_end}"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to delete this project?"
+msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
+msgid "Are you absolutely sure?"
msgstr ""
msgid "Are you sure that you want to archive this project?"
@@ -4673,12 +4711,18 @@ msgstr ""
msgid "Are you sure you want to delete this SSH key?"
msgstr ""
+msgid "Are you sure you want to delete this comment?"
+msgstr ""
+
msgid "Are you sure you want to delete this deploy key?"
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 label?"
+msgstr ""
+
msgid "Are you sure you want to delete this pipeline schedule?"
msgstr ""
@@ -4694,9 +4738,6 @@ msgstr ""
msgid "Are you sure you want to discard your changes?"
msgstr ""
-msgid "Are you sure you want to erase this build?"
-msgstr ""
-
msgid "Are you sure you want to import %d repository?"
msgid_plural "Are you sure you want to import %d repositories?"
msgstr[0] ""
@@ -4744,6 +4785,9 @@ msgstr ""
msgid "Are you sure you want to remove this list?"
msgstr ""
+msgid "Are you sure you want to remove this nickname?"
+msgstr ""
+
msgid "Are you sure you want to reset the health check token?"
msgstr ""
@@ -4756,10 +4800,10 @@ 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?"
+msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
msgstr ""
-msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
+msgid "Are you sure you want to revoke this project access token? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to stop this environment?"
@@ -4906,9 +4950,6 @@ msgstr ""
msgid "Assigned to %{assignee_name}"
msgstr ""
-msgid "Assigned to %{name}"
-msgstr ""
-
msgid "Assigned to me"
msgstr ""
@@ -4973,6 +5014,9 @@ msgstr[1] ""
msgid "Attaching the file failed."
msgstr ""
+msgid "Attention"
+msgstr ""
+
msgid "Audit Events"
msgstr ""
@@ -5135,6 +5179,12 @@ msgstr ""
msgid "Authorized applications (%{size})"
msgstr ""
+msgid "AuthorizedApplication|Are you sure you want to revoke this application?"
+msgstr ""
+
+msgid "AuthorizedApplication|Revoke application"
+msgstr ""
+
msgid "Authors: %{authors}"
msgstr ""
@@ -6328,6 +6378,9 @@ msgstr ""
msgid "CICDAnalytics|Shared Runners Usage"
msgstr ""
+msgid "CICDAnalytics|Shared runner pipeline minute duration by month"
+msgstr ""
+
msgid "CICDAnalytics|Shared runner usage"
msgstr ""
@@ -6469,6 +6522,9 @@ msgstr ""
msgid "Can create groups:"
msgstr ""
+msgid "Can not delete primary training"
+msgstr ""
+
msgid "Can't apply as the source branch was deleted."
msgstr ""
@@ -6802,9 +6858,6 @@ msgstr ""
msgid "Changing any setting here requires an application restart"
msgstr ""
-msgid "Changing group URL can have unintended side effects."
-msgstr ""
-
msgid "Charts can't be displayed as the request for data has timed out. %{documentationLink}"
msgstr ""
@@ -6892,9 +6945,6 @@ msgstr ""
msgid "Checking branch availability..."
msgstr ""
-msgid "Checking group URL availability..."
-msgstr ""
-
msgid "Checking group path availability..."
msgstr ""
@@ -7388,6 +7438,9 @@ msgstr ""
msgid "Clear recent searches"
msgstr ""
+msgid "Clear repository checks"
+msgstr ""
+
msgid "Clear search"
msgstr ""
@@ -7520,9 +7573,6 @@ msgstr ""
msgid "Closed MRs"
msgstr ""
-msgid "Closed epics"
-msgstr ""
-
msgid "Closed issues"
msgstr ""
@@ -7559,13 +7609,13 @@ msgstr ""
msgid "Cluster level"
msgstr ""
-msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
+msgid "Cluster type must be specified for Stages::ClusterEndpointInserter"
msgstr ""
msgid "ClusterAgents|%{name} successfully deleted"
msgstr ""
-msgid "ClusterAgents|%{number} of %{total} Agents"
+msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
@@ -7607,6 +7657,15 @@ msgstr ""
msgid "ClusterAgents|Agent never connected to GitLab"
msgstr ""
+msgid "ClusterAgents|Agent version mismatch"
+msgstr ""
+
+msgid "ClusterAgents|Agent version mismatch and update"
+msgstr ""
+
+msgid "ClusterAgents|Agent version update required"
+msgstr ""
+
msgid "ClusterAgents|All"
msgstr ""
@@ -7631,7 +7690,7 @@ msgstr ""
msgid "ClusterAgents|Configuration"
msgstr ""
-msgid "ClusterAgents|Connect a cluster through the Agent"
+msgid "ClusterAgents|Connect a cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connect existing cluster"
@@ -7640,13 +7699,13 @@ msgstr ""
msgid "ClusterAgents|Connect with a certificate"
msgstr ""
-msgid "ClusterAgents|Connect with agent"
+msgid "ClusterAgents|Connect with an agent"
msgstr ""
msgid "ClusterAgents|Connect with the GitLab Agent"
msgstr ""
-msgid "ClusterAgents|Connect your cluster through the Agent"
+msgid "ClusterAgents|Connect your cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connected"
@@ -7706,7 +7765,10 @@ msgstr ""
msgid "ClusterAgents|How to register an agent?"
msgstr ""
-msgid "ClusterAgents|Install new Agent"
+msgid "ClusterAgents|How to update an agent?"
+msgstr ""
+
+msgid "ClusterAgents|Install a new agent"
msgstr ""
msgid "ClusterAgents|Last connected %{timeAgo}."
@@ -7733,7 +7795,7 @@ msgstr ""
msgid "ClusterAgents|Never connected"
msgstr ""
-msgid "ClusterAgents|No Agents"
+msgid "ClusterAgents|No agents"
msgstr ""
msgid "ClusterAgents|No clusters connected through cluster certificates"
@@ -7793,6 +7855,9 @@ msgstr ""
msgid "ClusterAgents|The agent has not been connected in a long time. There might be a connectivity issue. Last contact was %{timeAgo}."
msgstr ""
+msgid "ClusterAgents|The agent version do not match each other across your cluster's pods. This can happen when a new agent version was just deployed and Kubernetes is shutting down the old pods."
+msgstr ""
+
msgid "ClusterAgents|The recommended installation method includes the token. If you want to follow the advanced installation method provided in the docs, make sure you save the token value before you close this window."
msgstr ""
@@ -7840,6 +7905,9 @@ msgstr ""
msgid "ClusterAgents|You will need to create a token to connect to your agent"
msgstr ""
+msgid "ClusterAgents|Your agent version is out of sync with your GitLab version (v%{version}), which might cause compatibility problems. Update the agent installed on your cluster to the most recent version."
+msgstr ""
+
msgid "ClusterAgents|Your instance doesn't have the %{linkStart}GitLab Agent Server (KAS)%{linkEnd} set up. Ask a GitLab Administrator to install it."
msgstr ""
@@ -8716,9 +8784,6 @@ msgstr ""
msgid "Comma-separated list of email addresses."
msgstr ""
-msgid "Comma-separated list of users allowed to exceed the rate limit."
-msgstr ""
-
msgid "Comma-separated, e.g. '1.1.1.1, 2.2.2.0/24'"
msgstr ""
@@ -9045,6 +9110,12 @@ msgstr ""
msgid "Confidential"
msgstr ""
+msgid "Confidential issue"
+msgstr ""
+
+msgid "Confidential note"
+msgstr ""
+
msgid "Confidentiality"
msgstr ""
@@ -9078,6 +9149,9 @@ msgstr ""
msgid "Configure Dependency Scanning in `.gitlab-ci.yml`, creating this file if it does not already exist"
msgstr ""
+msgid "Configure GitLab"
+msgstr ""
+
msgid "Configure GitLab runners to start using the Web Terminal. %{helpStart}Learn more.%{helpEnd}"
msgstr ""
@@ -9126,6 +9200,15 @@ msgstr ""
msgid "Configure pipelines to deploy web apps, backend services, APIs and static resources to Google Cloud"
msgstr ""
+msgid "Configure region"
+msgstr ""
+
+msgid "Configure region for environment"
+msgstr ""
+
+msgid "Configure regions"
+msgstr ""
+
msgid "Configure repository mirroring."
msgstr ""
@@ -9159,6 +9242,9 @@ msgstr ""
msgid "Configure which lists are shown for anyone who visits this board"
msgstr ""
+msgid "Configure your environments to be deployed to specific geographical regions"
+msgstr ""
+
msgid "Confirm"
msgstr ""
@@ -9861,10 +9947,10 @@ msgstr ""
msgid "CorpusManagement|Actions"
msgstr ""
-msgid "CorpusManagement|Corpus are used in fuzz testing as mutation source to Improve future testing."
+msgid "CorpusManagement|Corpus file"
msgstr ""
-msgid "CorpusManagement|Corpus file"
+msgid "CorpusManagement|Corpus files are used in coverage-guided fuzz testing as seed inputs to improve testing."
msgstr ""
msgid "CorpusManagement|Corpus files must be in *.zip format. Maximum 5 GB"
@@ -9918,6 +10004,9 @@ msgstr ""
msgid "Could not apply %{name} command."
msgstr ""
+msgid "Could not apply %{name} command. %{message}."
+msgstr ""
+
msgid "Could not authorize chat nickname. Try again!"
msgstr ""
@@ -10068,6 +10157,9 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
+msgid "Create a group"
+msgstr ""
+
msgid "Create a merge request"
msgstr ""
@@ -10092,6 +10184,9 @@ msgstr ""
msgid "Create a personal access token on your account to pull or push via %{protocol}."
msgstr ""
+msgid "Create a project"
+msgstr ""
+
msgid "Create an account using:"
msgstr ""
@@ -10455,6 +10550,9 @@ msgstr ""
msgid "Creation date"
msgstr ""
+msgid "Creator"
+msgstr ""
+
msgid "Credentials"
msgstr ""
@@ -10467,9 +10565,15 @@ msgstr ""
msgid "CredentialsInventory|Personal Access Tokens"
msgstr ""
+msgid "CredentialsInventory|Project Access Tokens"
+msgstr ""
+
msgid "CredentialsInventory|SSH Keys"
msgstr ""
+msgid "Credit card required to be on file in order to create a pipeline"
+msgstr ""
+
msgid "Credit card:"
msgstr ""
@@ -10653,9 +10757,6 @@ msgstr ""
msgid "Customer relations"
msgstr ""
-msgid "Customizable by an administrator."
-msgstr ""
-
msgid "Customizable by owners."
msgstr ""
@@ -10785,30 +10886,18 @@ msgstr ""
msgid "CycleAnalytics|%{selectedLabelsCount} selected (%{maxLabels} max)"
msgstr ""
-msgid "CycleAnalytics|%{stageCount} stages selected"
-msgstr ""
-
-msgid "CycleAnalytics|All stages"
-msgstr ""
-
-msgid "CycleAnalytics|Average days to completion"
+msgid "CycleAnalytics|Average time to completion"
msgstr ""
msgid "CycleAnalytics|Date"
msgstr ""
-msgid "CycleAnalytics|Days to completion"
-msgstr ""
-
msgid "CycleAnalytics|Display chart filters"
msgstr ""
msgid "CycleAnalytics|Lead Time for Changes"
msgstr ""
-msgid "CycleAnalytics|No stages selected"
-msgstr ""
-
msgid "CycleAnalytics|Number of tasks"
msgstr ""
@@ -10837,18 +10926,30 @@ msgstr ""
msgid "CycleAnalytics|Showing data for group '%{groupName}' from %{createdAfter} to %{createdBefore}"
msgstr ""
-msgid "CycleAnalytics|Stages"
+msgid "CycleAnalytics|Stage time: %{title}"
msgstr ""
msgid "CycleAnalytics|Tasks by type"
msgstr ""
-msgid "CycleAnalytics|The average time spent in the selected stage for the items that were completed on each date. Data limited to the last 500 items."
+msgid "CycleAnalytics|The average time items spent in this stage. Data limited to items completed within this date range."
msgstr ""
msgid "CycleAnalytics|The given date range is larger than 180 days"
msgstr ""
+msgid "CycleAnalytics|The total time items spent across each value stream stage. Data limited to items completed within this date range."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Stage time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Total time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|Total time"
+msgstr ""
+
msgid "CycleAnalytics|Type of work"
msgstr ""
@@ -10861,9 +10962,6 @@ msgstr ""
msgid "CycleAnalytics|project dropdown filter"
msgstr ""
-msgid "CycleAnalytics|stage dropdown"
-msgstr ""
-
msgid "DAG visualization requires at least 3 dependent jobs."
msgstr ""
@@ -10963,10 +11061,16 @@ msgstr ""
msgid "DastProfiles|AJAX spider"
msgstr ""
+msgid "DastProfiles|API"
+msgstr ""
+
+msgid "DastProfiles|API endpoint URL"
+msgstr ""
+
msgid "DastProfiles|Active"
msgstr ""
-msgid "DastProfiles|Additional request headers (Optional)"
+msgid "DastProfiles|Additional request headers (optional)"
msgstr ""
msgid "DastProfiles|Are you sure you want to delete this profile?"
@@ -10981,6 +11085,9 @@ msgstr ""
msgid "DastProfiles|Branch missing"
msgstr ""
+msgid "DastProfiles|Choose a scan method"
+msgstr ""
+
msgid "DastProfiles|Could not create the scanner profile. Please try again."
msgstr ""
@@ -11050,7 +11157,13 @@ msgstr ""
msgid "DastProfiles|Excluded URLs"
msgstr ""
-msgid "DastProfiles|Excluded URLs (Optional)"
+msgid "DastProfiles|Excluded URLs (optional)"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths (optional)"
msgstr ""
msgid "DastProfiles|Hide debug messages"
@@ -11107,9 +11220,6 @@ msgstr ""
msgid "DastProfiles|Request headers"
msgstr ""
-msgid "DastProfiles|Rest API"
-msgstr ""
-
msgid "DastProfiles|Run the AJAX spider, in addition to the traditional spider, to crawl the target site."
msgstr ""
@@ -11119,6 +11229,9 @@ msgstr ""
msgid "DastProfiles|Save profile"
msgstr ""
+msgid "DastProfiles|Scan method"
+msgstr ""
+
msgid "DastProfiles|Scan mode"
msgstr ""
@@ -11197,12 +11310,24 @@ msgstr ""
msgid "DastProfiles|Website"
msgstr ""
+msgid "DastProfiles|What does each method do?"
+msgstr ""
+
msgid "DastProfiles|You can either choose a passive scan or validate the target site from the site profile management page. %{docsLinkStart}Learn more about site validation.%{docsLinkEnd}"
msgstr ""
msgid "DastProfiles|You cannot run an active scan against an unvalidated site."
msgstr ""
+msgid "DastProfiles|folder/dast_example.har or https://example.com/dast_example.har"
+msgstr ""
+
+msgid "DastProfiles|folder/example.postman_collection.json or https://example.com/"
+msgstr ""
+
+msgid "DastProfiles|folder/openapi.json or https://example.com/openapi.json"
+msgstr ""
+
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
@@ -11310,6 +11435,9 @@ msgstr ""
msgid "DatadogIntegration|API URL"
msgstr ""
+msgid "DatadogIntegration|Custom tags in Datadog. Enter one tag per line in the %{codeOpen}key:value%{codeClose} format. %{linkOpen}How do I use tags?%{linkClose}"
+msgstr ""
+
msgid "DatadogIntegration|Environment"
msgstr ""
@@ -11328,12 +11456,18 @@ msgstr ""
msgid "DatadogIntegration|Tag all data from this GitLab instance in Datadog. Useful when managing several self-managed deployments."
msgstr ""
+msgid "DatadogIntegration|Tags"
+msgstr ""
+
msgid "DatadogIntegration|The Datadog site to send data to. To send data to the EU site, use %{codeOpen}datadoghq.eu%{codeClose}."
msgstr ""
msgid "DatadogIntegration|Trace your GitLab pipelines with Datadog."
msgstr ""
+msgid "DatadogIntegration|have an invalid format"
+msgstr ""
+
msgid "Datasource name not found"
msgstr ""
@@ -11343,9 +11477,6 @@ msgstr ""
msgid "Date merged"
msgstr ""
-msgid "Date picker"
-msgstr ""
-
msgid "Date range"
msgstr ""
@@ -11499,9 +11630,6 @@ msgstr ""
msgid "Definition"
msgstr ""
-msgid "Delayed Project Deletion (%{adjourned_deletion})"
-msgstr ""
-
msgid "DelayedJobs|Are you sure you want to run %{jobName} immediately? Otherwise this job will run automatically after its timer finishes."
msgstr ""
@@ -11580,10 +11708,10 @@ msgstr ""
msgid "Delete pipeline"
msgstr ""
-msgid "Delete project"
+msgid "Delete pipeline schedule"
msgstr ""
-msgid "Delete project. Are you ABSOLUTELY SURE?"
+msgid "Delete project"
msgstr ""
msgid "Delete row"
@@ -11613,6 +11741,9 @@ msgstr ""
msgid "Delete this epic and all descendants?"
msgstr ""
+msgid "Delete this project"
+msgstr ""
+
msgid "Delete user list"
msgstr ""
@@ -11871,6 +12002,12 @@ msgstr ""
msgid "Deploy to..."
msgstr ""
+msgid "DeployBoards|To see deployment progress for your environments, make sure you are deploying to %{codeStart}$KUBE_NAMESPACE%{codeEnd} and annotating with %{codeStart}app.gitlab.com/app=$CI_PROJECT_PATH_SLUG%{codeEnd} and %{codeStart}app.gitlab.com/env=$CI_ENVIRONMENT_SLUG%{codeEnd}."
+msgstr ""
+
+msgid "DeployBoard|Kubernetes Pods"
+msgstr ""
+
msgid "DeployFreeze|Add a freeze period to prevent unintended releases during a period of time for a given environment. You must update the deployment jobs in %{filename} according to the deploy freezes added here. %{freeze_period_link_start}Learn more.%{freeze_period_link_end}"
msgstr ""
@@ -11955,9 +12092,6 @@ msgstr ""
msgid "DeployTokens|Active Deploy Tokens (%{active_tokens})"
msgstr ""
-msgid "DeployTokens|Allows read and write access to registry images."
-msgstr ""
-
msgid "DeployTokens|Allows read and write access to the package registry."
msgstr ""
@@ -11970,6 +12104,9 @@ msgstr ""
msgid "DeployTokens|Allows read-only access to the repository."
msgstr ""
+msgid "DeployTokens|Allows write access to registry images."
+msgstr ""
+
msgid "DeployTokens|Copy deploy token"
msgstr ""
@@ -12063,12 +12200,57 @@ msgstr ""
msgid "Deploying to AWS is easy with GitLab"
msgstr ""
+msgid "Deployment"
+msgstr ""
+
msgid "Deployment Frequency"
msgstr ""
+msgid "Deployment Target|Project deployment target (optional)"
+msgstr ""
+
+msgid "Deployment Target|Select the deployment target"
+msgstr ""
+
msgid "Deployment frequency"
msgstr ""
+msgid "DeploymentTarget|GitLab Pages"
+msgstr ""
+
+msgid "DeploymentTarget|Heroku"
+msgstr ""
+
+msgid "DeploymentTarget|Infrastructure provider (Terraform, Cloudformation, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Kubernetes (GKE, EKS, OpenShift, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Managed container runtime (Fargate, Cloud Run, DigitalOcean App)"
+msgstr ""
+
+msgid "DeploymentTarget|Mobile app store"
+msgstr ""
+
+msgid "DeploymentTarget|No deployment planned"
+msgstr ""
+
+msgid "DeploymentTarget|Other hosting service"
+msgstr ""
+
+msgid "DeploymentTarget|Registry (package or container)"
+msgstr ""
+
+msgid "DeploymentTarget|Self-managed container runtime (Podman, Docker Swarm, Docker Compose)"
+msgstr ""
+
+msgid "DeploymentTarget|Serverless backend (Lambda, Cloud functions)"
+msgstr ""
+
+msgid "DeploymentTarget|Virtual machine (for example, EC2)"
+msgstr ""
+
msgid "Deployments"
msgstr ""
@@ -12107,6 +12289,9 @@ msgstr ""
msgid "Deployment|This deployment was created using the API"
msgstr ""
+msgid "Deployment|Triggerer"
+msgstr ""
+
msgid "Deployment|Waiting"
msgstr ""
@@ -12134,6 +12319,18 @@ msgstr ""
msgid "Deprecated API rate limits"
msgstr ""
+msgid "Deprecations|Feature deprecation and removal"
+msgstr ""
+
+msgid "Deprecations|For information on a possible replacement %{epicStart} learn more about Opstrace %{epicEnd}."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7 and are %{epicStart} scheduled for removal %{epicEnd} in GitLab 15.0."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7, and are %{removal_link_start} scheduled for removal %{link_end} in GitLab 15.0. For information on a possible replacement, %{opstrace_link_start} learn more about Opstrace %{link_end}."
+msgstr ""
+
msgid "Deprioritize label"
msgstr ""
@@ -12379,10 +12576,10 @@ msgstr ""
msgid "DevopsAdoption|At least one deploy"
msgstr ""
-msgid "DevopsAdoption|At least one issue opened"
+msgid "DevopsAdoption|At least one issue created"
msgstr ""
-msgid "DevopsAdoption|At least one merge request opened"
+msgid "DevopsAdoption|At least one merge request created"
msgstr ""
msgid "DevopsAdoption|At least one pipeline successfully run"
@@ -12583,6 +12780,9 @@ msgstr ""
msgid "Direct member"
msgstr ""
+msgid "Direct members"
+msgstr ""
+
msgid "Direct non-authenticated users to this page."
msgstr ""
@@ -12699,6 +12899,9 @@ msgid_plural "Dismiss %d selected vulnerabilities as"
msgstr[0] ""
msgstr[1] ""
+msgid "Dismiss Alert"
+msgstr ""
+
msgid "Dismiss merge request promotion"
msgstr ""
@@ -12726,9 +12929,15 @@ msgstr ""
msgid "Display alerts from all configured monitoring tools."
msgstr ""
+msgid "Display milestones"
+msgstr ""
+
msgid "Display name"
msgstr ""
+msgid "Display progress of child issues"
+msgstr ""
+
msgid "Display rendered file"
msgstr ""
@@ -12834,6 +13043,9 @@ msgstr ""
msgid "Download image"
msgstr ""
+msgid "Download payload"
+msgstr ""
+
msgid "Download raw data (.csv)"
msgstr ""
@@ -13011,6 +13223,9 @@ msgstr ""
msgid "Edit in Web IDE"
msgstr ""
+msgid "Edit in pipeline editor"
+msgstr ""
+
msgid "Edit in single-file editor"
msgstr ""
@@ -13053,6 +13268,9 @@ msgstr ""
msgid "Edit your most recent comment in a thread (from an empty textarea)"
msgstr ""
+msgid "Edit, lint, and visualize your pipeline."
+msgstr ""
+
msgid "Edited"
msgstr ""
@@ -13494,6 +13712,9 @@ msgstr ""
msgid "Enforce two-factor authentication for all user sign-ins."
msgstr ""
+msgid "Enhance security by storing service account keys in secret managers - learn more about %{docLinkStart}secret management with GitLab%{docLinkEnd}"
+msgstr ""
+
msgid "Ensure connectivity is available from the GitLab server to the Prometheus server"
msgstr ""
@@ -13554,6 +13775,9 @@ 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 following to confirm:"
+msgstr ""
+
msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
@@ -14084,9 +14308,6 @@ 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 ""
@@ -14222,6 +14443,9 @@ msgstr ""
msgid "Errors:"
msgstr ""
+msgid "Escalate this incident"
+msgstr ""
+
msgid "Escalation Policies"
msgstr ""
@@ -14234,6 +14458,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy"
+msgstr ""
+
msgid "Escalation policy:"
msgstr ""
@@ -14485,6 +14712,9 @@ msgstr ""
msgid "Existing sign in methods may be removed"
msgstr ""
+msgid "Exit."
+msgstr ""
+
msgid "Expand"
msgstr ""
@@ -14581,6 +14811,9 @@ msgstr ""
msgid "Explore public groups"
msgstr ""
+msgid "Explore public projects"
+msgstr ""
+
msgid "Explore snippets"
msgstr ""
@@ -14742,7 +14975,7 @@ msgid_plural "Failed to archive designs. Please try again."
msgstr[0] ""
msgstr[1] ""
-msgid "Failed to assign a reviewer because no user was found."
+msgid "Failed to assign a reviewer because no user was specified."
msgstr ""
msgid "Failed to assign a user because no user was found."
@@ -14808,10 +15041,10 @@ msgstr ""
msgid "Failed to find import label for Jira import."
msgstr ""
-msgid "Failed to generate export, please try again later."
+msgid "Failed to find users for %{missing}"
msgstr ""
-msgid "Failed to generate report, please try again after sometime"
+msgid "Failed to generate export, please try again later."
msgstr ""
msgid "Failed to get ref."
@@ -14910,6 +15143,9 @@ msgstr ""
msgid "Failed to remove a to-do item for the design."
msgstr ""
+msgid "Failed to remove attention because no user was found."
+msgstr ""
+
msgid "Failed to remove mirror."
msgstr ""
@@ -14922,6 +15158,9 @@ msgstr ""
msgid "Failed to remove user key."
msgstr ""
+msgid "Failed to request attention because no user was found."
+msgstr ""
+
msgid "Failed to reset key. Please try again."
msgstr ""
@@ -15003,6 +15242,9 @@ msgstr ""
msgid "Feature Flags"
msgstr ""
+msgid "Feature deprecation and removal"
+msgstr ""
+
msgid "Feature flag status"
msgstr ""
@@ -15500,7 +15742,7 @@ msgstr ""
msgid "For each job, re-use the project workspace. If the workspace doesn't exist, use %{code_open}git clone%{code_close}."
msgstr ""
-msgid "For example, the application using the token or the purpose of the token."
+msgid "For example, the application using the token or the purpose of the token. Do not give sensitive information for the name of the token, as it will be visible to all %{resource_type} members."
msgstr ""
msgid "For files larger than this limit, only index the file name. The file content is neither indexed nor searchable."
@@ -15584,9 +15826,6 @@ msgstr ""
msgid "ForkProject|Select a namespace"
msgstr ""
-msgid "ForkProject|Select a namespace to fork the project"
-msgstr ""
-
msgid "ForkProject|The project can be accessed by any logged in user."
msgstr ""
@@ -15683,6 +15922,9 @@ msgstr ""
msgid "Full name"
msgstr ""
+msgid "GCP region configured"
+msgstr ""
+
msgid "GPG Key ID:"
msgstr ""
@@ -15863,6 +16105,9 @@ msgstr ""
msgid "Geo|Failed"
msgstr ""
+msgid "Geo|Filter Geo sites"
+msgstr ""
+
msgid "Geo|Filter by name"
msgstr ""
@@ -16274,6 +16519,12 @@ msgstr ""
msgid "GitLab Issue"
msgstr ""
+msgid "GitLab KAS"
+msgstr ""
+
+msgid "GitLab Memberships CSV Export"
+msgstr ""
+
msgid "GitLab Pages"
msgstr ""
@@ -16322,6 +16573,9 @@ 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 free to use. Many features for larger teams are part of our %{link_start}paid products%{link_end}. You can try Ultimate for free without any obligation or payment details."
+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 ""
@@ -16448,7 +16702,7 @@ msgstr ""
msgid "GitLabPages|When enabled, all attempts to visit your website through HTTP are automatically redirected to HTTPS using a response with status code 301. Requires a valid certificate for all domains. %{docs_link_start}Learn more.%{link_end}"
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. %{docs_link_start}Learn more.%{link_end}"
+msgid "GitLabPages|When using Pages under the general domain of a GitLab instance (%{pages_host}), you cannot use HTTPS with subdomains of subdomains. If your namespace or groupname contains a dot, it does not work. This is a limitation of the HTTP Over TLS protocol. HTTP pages work if you don't redirect HTTP to HTTPS. %{docs_link_start}Learn more.%{link_end}"
msgstr ""
msgid "GitLabPages|With GitLab Pages you can host your static website directly from your GitLab repository. %{docs_link_start}Learn more.%{link_end}"
@@ -16625,9 +16879,6 @@ msgstr ""
msgid "Go to find file"
msgstr ""
-msgid "Go to fork"
-msgstr ""
-
msgid "Go to issue boards"
msgstr ""
@@ -16835,9 +17086,6 @@ msgstr ""
msgid "Group Hooks"
msgstr ""
-msgid "Group ID"
-msgstr ""
-
msgid "Group Owner must have signed in with SAML before enabling Group Managed Accounts"
msgstr ""
@@ -16865,9 +17113,6 @@ msgstr ""
msgid "Group by"
msgstr ""
-msgid "Group description"
-msgstr ""
-
msgid "Group description (optional)"
msgstr ""
@@ -16982,7 +17227,7 @@ msgstr ""
msgid "Group: %{name}"
msgstr ""
-msgid "GroupActivityMetrics|Issues opened"
+msgid "GroupActivityMetrics|Issues created"
msgstr ""
msgid "GroupActivityMetrics|Last 90 days"
@@ -16991,7 +17236,7 @@ msgstr ""
msgid "GroupActivityMetrics|Members added"
msgstr ""
-msgid "GroupActivityMetrics|Merge Requests opened"
+msgid "GroupActivityMetrics|Merge Requests created"
msgstr ""
msgid "GroupActivityMetrics|Recent activity"
@@ -17282,6 +17527,9 @@ msgstr ""
msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
+msgid "GroupSettings|Choose a group path that does not start with a dash or end with a period. It can also contain alphanumeric characters and underscores."
+msgstr ""
+
msgid "GroupSettings|Compliance frameworks"
msgstr ""
@@ -17315,7 +17563,7 @@ msgstr ""
msgid "GroupSettings|If not specified at the group or instance level, the default is %{default_initial_branch_name}. Does not affect existing repositories."
msgstr ""
-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."
+msgid "GroupSettings|If the parent group's visibility is lower than the group's current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility."
msgstr ""
msgid "GroupSettings|New runners registration token has been generated!"
@@ -17432,7 +17680,10 @@ msgstr ""
msgid "Groups and projects"
msgstr ""
-msgid "Groups and subgroups"
+msgid "Groups are a great way to organize projects and people."
+msgstr ""
+
+msgid "Groups are the best way to manage projects and members."
msgstr ""
msgid "Groups to synchronize"
@@ -17543,13 +17794,16 @@ msgstr ""
msgid "GroupsTree|Are you sure you want to leave the \"%{fullName}\" group?"
msgstr ""
-msgid "GroupsTree|Edit group"
+msgid "GroupsTree|Delete"
+msgstr ""
+
+msgid "GroupsTree|Edit"
msgstr ""
msgid "GroupsTree|Failed to leave the group. Please make sure you are not the only owner."
msgstr ""
-msgid "GroupsTree|Leave this group"
+msgid "GroupsTree|Leave group"
msgstr ""
msgid "GroupsTree|Loading groups"
@@ -17561,9 +17815,57 @@ msgstr ""
msgid "GroupsTree|No groups or projects matched your search"
msgstr ""
+msgid "GroupsTree|Options"
+msgstr ""
+
msgid "GroupsTree|Search by name"
msgstr ""
+msgid "Groups|Avatar will be removed. Are you sure?"
+msgstr ""
+
+msgid "Groups|Changing group URL can have unintended side effects."
+msgstr ""
+
+msgid "Groups|Checking group URL availability..."
+msgstr ""
+
+msgid "Groups|Enter a descriptive name for your group."
+msgstr ""
+
+msgid "Groups|Group ID"
+msgstr ""
+
+msgid "Groups|Group URL"
+msgstr ""
+
+msgid "Groups|Group avatar"
+msgstr ""
+
+msgid "Groups|Group description (optional)"
+msgstr ""
+
+msgid "Groups|Group name"
+msgstr ""
+
+msgid "Groups|Group path is available."
+msgstr ""
+
+msgid "Groups|Group path is unavailable. Path has been replaced with a suggested available path."
+msgstr ""
+
+msgid "Groups|Learn more"
+msgstr ""
+
+msgid "Groups|Must start with letter, digit, emoji, or underscore. Can also contain periods, dashes, spaces, and parentheses."
+msgstr ""
+
+msgid "Groups|Remove avatar"
+msgstr ""
+
+msgid "Groups|Save changes"
+msgstr ""
+
msgid "Guideline"
msgstr ""
@@ -17573,6 +17875,9 @@ msgstr ""
msgid "HAR file path or URL"
msgstr ""
+msgid "HTTP Archive (HAR)"
+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 ""
@@ -17973,6 +18278,9 @@ msgstr ""
msgid "INFO: Your SSH key is expiring soon. Please generate a new key."
msgstr ""
+msgid "IP"
+msgstr ""
+
msgid "IP Address"
msgstr ""
@@ -18009,6 +18317,9 @@ msgstr ""
msgid "IdentityVerification|Verify your identity"
msgstr ""
+msgid "IdentityVerification|You can always verify your account at a later time to create a group."
+msgstr ""
+
msgid "If any indexed field exceeds this limit, it is truncated to this number of characters. The rest of the content is neither indexed nor searchable. This does not apply to repository and wiki indexing. For unlimited characters, set this to 0."
msgstr ""
@@ -18066,6 +18377,9 @@ msgstr ""
msgid "If you add %{codeStart}needs%{codeEnd} to jobs in your pipeline you'll be able to view the %{codeStart}needs%{codeEnd} relationships between jobs in this tab as a %{linkStart}Directed Acyclic Graph (DAG)%{linkEnd}."
msgstr ""
+msgid "If you are added to a project, it will be displayed here."
+msgstr ""
+
msgid "If you did not initiate these sign-in attempts, please reach out to your administrator or enable two-factor authentication (2FA) on your account."
msgstr ""
@@ -18372,12 +18686,24 @@ msgstr ""
msgid "InProductMarketing|3 ways to dive into GitLab CI/CD"
msgstr ""
+msgid "InProductMarketing|A single application eliminates complex integrations, data chokepoints, and toolchain maintenance, resulting in greater productivity and lower cost."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features, build more efficiently, strengthen security and compliance."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features."
+msgstr ""
+
msgid "InProductMarketing|Actually, GitLab makes the team work (better)"
msgstr ""
msgid "InProductMarketing|And finally %{deploy_link} a Python application."
msgstr ""
+msgid "InProductMarketing|And many more..."
+msgstr ""
+
msgid "InProductMarketing|Are your runners ready?"
msgstr ""
@@ -18396,15 +18722,33 @@ msgstr ""
msgid "InProductMarketing|Blog"
msgstr ""
+msgid "InProductMarketing|Break down silos to coordinate seamlessly across development, operations, and security with a consistent experience across the development lifecycle."
+msgstr ""
+
+msgid "InProductMarketing|Burn up/down charts"
+msgstr ""
+
msgid "InProductMarketing|By enabling code owners and required merge approvals the right person will review the right MR. This is a win-win: cleaner code and a more efficient review process."
msgstr ""
msgid "InProductMarketing|Click on the number below that corresponds with your answer — 1 being very difficult, 5 being very easy."
msgstr ""
+msgid "InProductMarketing|Code owners"
+msgstr ""
+
msgid "InProductMarketing|Code owners and required merge approvals are part of the paid tiers of GitLab. You can start a free 30-day trial of GitLab Ultimate and enable these features in less than 5 minutes with no credit card required."
msgstr ""
+msgid "InProductMarketing|Code review analytics"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration across stages in GitLab"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration made easy"
+msgstr ""
+
msgid "InProductMarketing|Create a custom CI runner with just a few clicks"
msgstr ""
@@ -18414,12 +18758,21 @@ msgstr ""
msgid "InProductMarketing|Create a project in GitLab in 5 minutes"
msgstr ""
+msgid "InProductMarketing|Create well-defined workflows by using scoped labels on issues, merge requests, and epics. Labels with the same scope cannot be used together, which prevents conflicts."
+msgstr ""
+
msgid "InProductMarketing|Create your first project!"
msgstr ""
+msgid "InProductMarketing|Define who owns specific files or directories, so the right reviewers are suggested when a merge request introduces changes to those files."
+msgstr ""
+
msgid "InProductMarketing|Deliver Better Products Faster"
msgstr ""
+msgid "InProductMarketing|Dependency scanning"
+msgstr ""
+
msgid "InProductMarketing|Did you know teams that use GitLab are far more efficient?"
msgstr ""
@@ -18429,15 +18782,27 @@ msgstr ""
msgid "InProductMarketing|Dig in and create a project and a repo"
msgstr ""
+msgid "InProductMarketing|Discover Premium & Ultimate"
+msgstr ""
+
+msgid "InProductMarketing|Discover Premium & Ultimate."
+msgstr ""
+
msgid "InProductMarketing|Do you have a minute?"
msgstr ""
msgid "InProductMarketing|Do you have a teammate who would be perfect for this task?"
msgstr ""
+msgid "InProductMarketing|Dynamic application security testing"
+msgstr ""
+
msgid "InProductMarketing|Easy"
msgstr ""
+msgid "InProductMarketing|Epics"
+msgstr ""
+
msgid "InProductMarketing|Expand your DevOps journey with a free GitLab trial"
msgstr ""
@@ -18459,9 +18824,15 @@ msgstr ""
msgid "InProductMarketing|Feel the need for speed?"
msgstr ""
+msgid "InProductMarketing|Find and fix bottlenecks in your code review process by understanding how long open merge requests have been in review."
+msgstr ""
+
msgid "InProductMarketing|Find out how your teams are really doing"
msgstr ""
+msgid "InProductMarketing|Find out if your external libraries are safe. Run dependency scanning jobs that check for known vulnerabilities in your external libraries."
+msgstr ""
+
msgid "InProductMarketing|Follow our steps"
msgstr ""
@@ -18498,6 +18869,9 @@ msgstr ""
msgid "InProductMarketing|GitLab is better with teammates to help out!"
msgstr ""
+msgid "InProductMarketing|GitLab is infrastructure agnostic (supporting GCP, AWS, Azure, OpenShift, VMWare, On Prem, Bare Metal, and more), offering a consistent workflow experience – irrespective of the environment."
+msgstr ""
+
msgid "InProductMarketing|GitLab provides static application security testing (SAST), dynamic application security testing (DAST), container scanning, and dependency scanning to help you deliver secure applications along with license compliance."
msgstr ""
@@ -18588,21 +18962,36 @@ msgstr ""
msgid "InProductMarketing|It's also possible to simply %{external_repo_link} in order to take advantage of GitLab's CI/CD."
msgstr ""
+msgid "InProductMarketing|Keep your code quality high by defining who should approve merge requests and how many approvals are required."
+msgstr ""
+
msgid "InProductMarketing|Launch GitLab CI/CD in 20 minutes or less"
msgstr ""
+msgid "InProductMarketing|Lower cost of development"
+msgstr ""
+
+msgid "InProductMarketing|Make it easier to collaborate on high-level ideas by grouping related issues in an epic."
+msgstr ""
+
msgid "InProductMarketing|Making the switch? It's easier than you think to import your projects into GitLab. Move %{github_link}, or import something %{bitbucket_link}."
msgstr ""
msgid "InProductMarketing|Master the art of importing!"
msgstr ""
+msgid "InProductMarketing|Merge request approval rule"
+msgstr ""
+
msgid "InProductMarketing|Move on to easily creating a Pages website %{ci_template_link}"
msgstr ""
msgid "InProductMarketing|Multiple owners, confusing workstreams? We've got you covered"
msgstr ""
+msgid "InProductMarketing|Multiple required approvers"
+msgstr ""
+
msgid "InProductMarketing|Need an alternative to importing?"
msgstr ""
@@ -18615,18 +19004,33 @@ msgstr ""
msgid "InProductMarketing|Our tool brings all the things together"
msgstr ""
+msgid "InProductMarketing|Protect your web application by using DAST to examine for vulnerabilities in deployed environments."
+msgstr ""
+
msgid "InProductMarketing|Rapid development, simplified"
msgstr ""
msgid "InProductMarketing|Reduce Security & Compliance Risk"
msgstr ""
+msgid "InProductMarketing|Require multiple approvers on a merge request, so you know it's in good shape before it's merged."
+msgstr ""
+
+msgid "InProductMarketing|Roadmaps"
+msgstr ""
+
+msgid "InProductMarketing|Scoped labels"
+msgstr ""
+
msgid "InProductMarketing|Security that's integrated into your development lifecycle"
msgstr ""
msgid "InProductMarketing|Sometimes you're not ready to make a full transition to a new tool. If you're not ready to fully commit, %{mirroring_link} gives you a safe way to try out GitLab in parallel with your current tool."
msgstr ""
+msgid "InProductMarketing|Speed. Efficiency. Trust."
+msgstr ""
+
msgid "InProductMarketing|Spin up an autoscaling runner in GitLab"
msgstr ""
@@ -18636,6 +19040,9 @@ msgstr ""
msgid "InProductMarketing|Start a Self-Managed trial"
msgstr ""
+msgid "InProductMarketing|Start a free trial"
+msgstr ""
+
msgid "InProductMarketing|Start a free trial of GitLab Ultimate – no credit card required"
msgstr ""
@@ -18702,6 +19109,9 @@ msgstr ""
msgid "InProductMarketing|To understand and get the most out of GitLab, start at the beginning and %{project_link}. In GitLab, repositories are part of a project, so after you've created your project you can go ahead and %{repo_link}."
msgstr ""
+msgid "InProductMarketing|Track completed issues in a chart, so you can see how a milestone is progressing at a glance."
+msgstr ""
+
msgid "InProductMarketing|Try GitLab Ultimate for free"
msgstr ""
@@ -18738,6 +19148,9 @@ msgstr ""
msgid "InProductMarketing|Very easy"
msgstr ""
+msgid "InProductMarketing|Visualize your epics and milestones in a timeline."
+msgstr ""
+
msgid "InProductMarketing|Want to host GitLab on your servers?"
msgstr ""
@@ -18759,6 +19172,9 @@ msgstr ""
msgid "InProductMarketing|YouTube"
msgstr ""
+msgid "InProductMarketing|Your software, deployed your way"
+msgstr ""
+
msgid "InProductMarketing|Your teams can be more efficient"
msgstr ""
@@ -18879,9 +19295,18 @@ msgstr ""
msgid "IncidentManagement|No incidents to display."
msgstr ""
+msgid "IncidentManagement|None"
+msgstr ""
+
msgid "IncidentManagement|Open"
msgstr ""
+msgid "IncidentManagement|Page your team with escalation policies"
+msgstr ""
+
+msgid "IncidentManagement|Paged"
+msgstr ""
+
msgid "IncidentManagement|Published"
msgstr ""
@@ -18891,6 +19316,9 @@ msgstr ""
msgid "IncidentManagement|Severity"
msgstr ""
+msgid "IncidentManagement|Status"
+msgstr ""
+
msgid "IncidentManagement|There are no closed incidents"
msgstr ""
@@ -18909,6 +19337,9 @@ msgstr ""
msgid "IncidentManagement|Unpublished"
msgstr ""
+msgid "IncidentManagement|Use escalation policies to automatically page your team when incidents are created."
+msgstr ""
+
msgid "IncidentSettings|Activate \"time to SLA\" countdown timer"
msgstr ""
@@ -18954,7 +19385,10 @@ msgstr ""
msgid "Incidents"
msgstr ""
-msgid "Incidents|Add a URL"
+msgid "Incidents|Add image details"
+msgstr ""
+
+msgid "Incidents|Add text or a link to display with your image. If you don't add either, the file name displays instead."
msgstr ""
msgid "Incidents|Drop or %{linkStart}upload%{linkEnd} a metric screenshot to attach it to the incident"
@@ -18969,10 +19403,10 @@ msgstr ""
msgid "Incidents|There was an issue loading metric images."
msgstr ""
-msgid "Incidents|There was an issue uploading your image."
+msgid "Incidents|There was an issue updating your image."
msgstr ""
-msgid "Incidents|You can optionally add a URL to link users to the original graph."
+msgid "Incidents|There was an issue uploading your image."
msgstr ""
msgid "Incident|Alert details"
@@ -18981,9 +19415,18 @@ msgstr ""
msgid "Incident|Are you sure you wish to delete this image?"
msgstr ""
+msgid "Incident|Delete image"
+msgstr ""
+
msgid "Incident|Deleting %{filename}"
msgstr ""
+msgid "Incident|Edit image text or link"
+msgstr ""
+
+msgid "Incident|Editing %{filename}"
+msgstr ""
+
msgid "Incident|Metrics"
msgstr ""
@@ -19253,12 +19696,18 @@ msgstr ""
msgid "Integrations|Branches for which notifications are to be sent"
msgstr ""
+msgid "Integrations|Clear if using a self-signed certificate."
+msgstr ""
+
msgid "Integrations|Comment detail:"
msgstr ""
msgid "Integrations|Comment settings:"
msgstr ""
+msgid "Integrations|Connection details"
+msgstr ""
+
msgid "Integrations|Connection failed. Please check your settings."
msgstr ""
@@ -19283,6 +19732,9 @@ msgstr ""
msgid "Integrations|Enable GitLab.com slash commands in a Slack workspace."
msgstr ""
+msgid "Integrations|Enable SSL verification"
+msgstr ""
+
msgid "Integrations|Enable comments"
msgstr ""
@@ -19361,6 +19813,9 @@ msgstr ""
msgid "Integrations|Return to GitLab for Jira"
msgstr ""
+msgid "Integrations|SSL verification"
+msgstr ""
+
msgid "Integrations|Save settings?"
msgstr ""
@@ -19406,9 +19861,6 @@ msgstr ""
msgid "Integrations|Use default settings"
msgstr ""
-msgid "Integrations|When you mention a Jira issue in a commit or merge request, GitLab creates a remote link and comment (if enabled)."
-msgstr ""
-
msgid "Integrations|You can now close this window and return to the GitLab for Jira application."
msgstr ""
@@ -19433,9 +19885,6 @@ msgstr ""
msgid "Integrations|can't exceed %{recipients_limit}"
msgstr ""
-msgid "Interactive developer security education."
-msgstr ""
-
msgid "Interactive mode"
msgstr ""
@@ -19925,6 +20374,9 @@ msgstr ""
msgid "IssueAnalytics|Assignees"
msgstr ""
+msgid "IssueAnalytics|Created by"
+msgstr ""
+
msgid "IssueAnalytics|Due date"
msgstr ""
@@ -19937,9 +20389,6 @@ msgstr ""
msgid "IssueAnalytics|Milestone"
msgstr ""
-msgid "IssueAnalytics|Opened by"
-msgstr ""
-
msgid "IssueAnalytics|Status"
msgstr ""
@@ -20063,10 +20512,10 @@ msgstr ""
msgid "IssuesAnalytics|Avg/Month:"
msgstr ""
-msgid "IssuesAnalytics|Issues opened"
+msgid "IssuesAnalytics|Issues created"
msgstr ""
-msgid "IssuesAnalytics|Issues opened per month"
+msgid "IssuesAnalytics|Issues created per month"
msgstr ""
msgid "IssuesAnalytics|Last 12 months"
@@ -20093,6 +20542,9 @@ msgstr ""
msgid "It looks like you have some draft commits in this branch."
msgstr ""
+msgid "It looks like you're attempting to activate your subscription. Use %{a_start}the Subscription page%{a_end} instead."
+msgstr ""
+
msgid "It may be several days before you see feature usage data."
msgstr ""
@@ -20321,6 +20773,9 @@ msgstr ""
msgid "JiraConnect|You can now close this window and return to Jira."
msgstr ""
+msgid "JiraConnect|You don't have permission to create branches for this project. Select a different project or contact the project owner for access. %{linkStart}Learn more.%{linkEnd}"
+msgstr ""
+
msgid "JiraRequest|A connection error occurred while connecting to Jira. Try your request again."
msgstr ""
@@ -20369,13 +20824,13 @@ msgstr ""
msgid "JiraService|Define the type of Jira issue to create from a vulnerability."
msgstr ""
-msgid "JiraService|Displaying Jira issues while leaving the GitLab issue functionality enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
+msgid "JiraService|Displaying Jira issues while leaving GitLab issues also enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
msgstr ""
-msgid "JiraService|Enable Jira issues"
+msgid "JiraService|Enable Jira issue creation from vulnerabilities"
msgstr ""
-msgid "JiraService|Enable Jira issues creation from vulnerabilities"
+msgid "JiraService|Enable Jira issues"
msgstr ""
msgid "JiraService|Enable Jira transitions"
@@ -20492,16 +20947,19 @@ msgstr ""
msgid "JiraService|View Jira issues in GitLab"
msgstr ""
-msgid "JiraService|Warning: All GitLab users that have access to this GitLab project are able to view all issues from the Jira project specified below."
+msgid "JiraService|Warning: All GitLab users with access to this GitLab project can view all issues from the Jira project you select."
msgstr ""
msgid "JiraService|Web URL"
msgstr ""
-msgid "JiraService|Work on Jira issues without leaving GitLab. Adds a Jira menu to access your list of Jira issues and view any issue as read-only."
+msgid "JiraService|When a Jira issue is mentioned in a commit or merge request, a remote link and comment (if enabled) will be created."
+msgstr ""
+
+msgid "JiraService|Work on Jira issues without leaving GitLab. Add a Jira menu to access a read-only list of your Jira issues."
msgstr ""
-msgid "JiraService|You need to configure Jira before enabling this integration. For more details, read the %{jira_doc_link_start}Jira integration documentation%{link_end}."
+msgid "JiraService|You must configure Jira before enabling this integration. %{jira_doc_link_start}Learn more.%{link_end}"
msgstr ""
msgid "Job"
@@ -20513,9 +20971,6 @@ msgstr ""
msgid "Job Failed #%{build_id}"
msgstr ""
-msgid "Job ID"
-msgstr ""
-
msgid "Job artifact"
msgstr ""
@@ -20582,9 +21037,27 @@ msgstr ""
msgid "Jobs|You're about to retry a job that failed because it attempted to deploy code that is older than the latest deployment. Retrying this job could result in overwriting the environment with the older source code."
msgstr ""
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source} into %{target}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{ref}"
+msgstr ""
+
+msgid "Job|Are you sure you want to erase this job log and artifacts?"
+msgstr ""
+
msgid "Job|Browse"
msgstr ""
+msgid "Job|Cancel"
+msgstr ""
+
msgid "Job|Complete Raw"
msgstr ""
@@ -20594,6 +21067,9 @@ msgstr ""
msgid "Job|Erase job log and artifacts"
msgstr ""
+msgid "Job|Finished at"
+msgstr ""
+
msgid "Job|Job artifacts"
msgstr ""
@@ -20606,7 +21082,7 @@ msgstr ""
msgid "Job|Keep"
msgstr ""
-msgid "Job|Pipeline"
+msgid "Job|Retry"
msgstr ""
msgid "Job|Scroll to bottom"
@@ -20618,6 +21094,9 @@ msgstr ""
msgid "Job|Show complete raw"
msgstr ""
+msgid "Job|Status"
+msgstr ""
+
msgid "Job|The artifacts were removed"
msgstr ""
@@ -20645,21 +21124,12 @@ msgstr ""
msgid "Job|delayed"
msgstr ""
-msgid "Job|for"
-msgstr ""
-
-msgid "Job|into"
-msgstr ""
-
msgid "Job|manual"
msgstr ""
msgid "Job|triggered"
msgstr ""
-msgid "Job|with"
-msgstr ""
-
msgid "Join Zoom meeting"
msgstr ""
@@ -20762,9 +21232,6 @@ msgstr ""
msgid "Ki"
msgstr ""
-msgid "Kontra"
-msgstr ""
-
msgid "Kroki"
msgstr ""
@@ -21088,6 +21555,9 @@ msgstr ""
msgid "Learn more about Auto DevOps"
msgstr ""
+msgid "Learn more about GitLab"
+msgstr ""
+
msgid "Learn more about Needs relationships"
msgstr ""
@@ -21415,9 +21885,18 @@ msgstr ""
msgid "Licenses|Displays licenses detected in the project, based on the %{linkStart}latest successful%{linkEnd} scan"
msgstr ""
+msgid "Licenses|Drag your license file here or %{linkStart}click to upload%{linkEnd}."
+msgstr ""
+
+msgid "Licenses|Drop your license file to start the upload."
+msgstr ""
+
msgid "Licenses|Error fetching the license list. Please check your network connection and try again."
msgstr ""
+msgid "Licenses|Error: You are trying to upload something other than a file"
+msgstr ""
+
msgid "Licenses|License Compliance"
msgstr ""
@@ -21436,6 +21915,9 @@ msgstr ""
msgid "Licenses|Specified policies in this project"
msgstr ""
+msgid "Licenses|The file could not be uploaded."
+msgstr ""
+
msgid "Licenses|The license list details information about the licenses used within your project."
msgstr ""
@@ -21469,11 +21951,6 @@ msgstr ""
msgid "Limit the size of Sidekiq jobs stored in Redis."
msgstr ""
-msgid "Limited to showing %d event at most"
-msgid_plural "Limited to showing %d events at most"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Limiting mode"
msgstr ""
@@ -21483,6 +21960,9 @@ msgstr ""
msgid "Link"
msgstr ""
+msgid "Link (optional)"
+msgstr ""
+
msgid "Link Prometheus monitoring to GitLab."
msgstr ""
@@ -21519,6 +21999,9 @@ msgstr ""
msgid "Linked emails (%{email_count})"
msgstr ""
+msgid "Linked epics"
+msgstr ""
+
msgid "Linked issues"
msgstr ""
@@ -21546,6 +22029,15 @@ msgstr ""
msgid "List of all merge commits"
msgstr ""
+msgid "List of environments for this project"
+msgstr ""
+
+msgid "List of suitable GCP locations"
+msgstr ""
+
+msgid "List of users allowed to exceed the rate limit."
+msgstr ""
+
msgid "List options"
msgstr ""
@@ -21765,6 +22257,9 @@ msgstr ""
msgid "Maintenance mode"
msgstr ""
+msgid "Make adjustments to how your GitLab instance is set up."
+msgstr ""
+
msgid "Make and review changes in the browser with the Web IDE"
msgstr ""
@@ -21909,6 +22404,12 @@ msgstr ""
msgid "MarkdownEditor|Add italic text (%{modifier_key}I)"
msgstr ""
+msgid "MarkdownEditor|Add strikethrough text (%{modifierKey}⇧X)"
+msgstr ""
+
+msgid "MarkdownEditor|Add strikethrough text (%{modifier_key}⇧X)"
+msgstr ""
+
msgid "Marked For Deletion At - %{deletion_time}"
msgstr ""
@@ -22170,6 +22671,9 @@ msgstr ""
msgid "Maximum push size (MB)"
msgstr ""
+msgid "Maximum requests per 10 minutes per user"
+msgstr ""
+
msgid "Maximum requests per minute"
msgstr ""
@@ -22260,6 +22764,19 @@ msgstr ""
msgid "Members of a group may only view projects they have permission to access"
msgstr ""
+msgid "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seat in use and will be billed for the overage."
+msgid_plural "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seats in use and will be billed for the overage."
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "MembersOverage|You are about to incur additional charges"
+msgstr ""
+
+msgid "MembersOverage|Your subscription includes %d seat."
+msgid_plural "MembersOverage|Your subscription includes %d seats."
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Membership"
msgstr ""
@@ -22464,9 +22981,6 @@ msgstr ""
msgid "Merge request not merged"
msgstr ""
-msgid "Merge request pipelines 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 merge request pipelines."
-msgstr ""
-
msgid "Merge request reports"
msgstr ""
@@ -22563,13 +23077,13 @@ msgstr ""
msgid "MergeRequests|Create issue to resolve thread"
msgstr ""
-msgid "MergeRequests|Failed to squash. Should be done manually."
+msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Saving the comment failed"
+msgid "MergeRequests|Squashing failed: Squash the commits locally, resolve any conflicts, then push the branch."
msgstr ""
-msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
+msgid "MergeRequests|Squashing not allowed: This project doesn't allow you to squash commits when merging."
msgstr ""
msgid "MergeRequests|Thread stays resolved"
@@ -23410,6 +23924,18 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "MrList|Assigned to %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from assignee %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from reviewer %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Review requested from %{name}, go to their profile."
+msgstr ""
+
msgid "Multi-project"
msgstr ""
@@ -23443,7 +23969,7 @@ msgstr ""
msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "My Awesome Group"
+msgid "My awesome group"
msgstr ""
msgid "My company or team"
@@ -24065,9 +24591,6 @@ msgstr ""
msgid "No available branches"
msgstr ""
-msgid "No available groups to fork the project."
-msgstr ""
-
msgid "No branches found"
msgstr ""
@@ -24278,6 +24801,9 @@ msgstr ""
msgid "No ref selected"
msgstr ""
+msgid "No regions configured"
+msgstr ""
+
msgid "No related merge requests found."
msgstr ""
@@ -25082,6 +25608,9 @@ msgstr ""
msgid "Only reCAPTCHA v2 is supported:"
msgstr ""
+msgid "Only required if not using role instance credentials."
+msgstr ""
+
msgid "Only use lowercase letters, numbers, and underscores."
msgstr ""
@@ -25106,9 +25635,6 @@ msgstr ""
msgid "Open a CLI and connect to the cluster you want to install the agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
-msgid "Open epics"
-msgstr ""
-
msgid "Open errors"
msgstr ""
@@ -25148,7 +25674,7 @@ msgstr ""
msgid "Opened issues"
msgstr ""
-msgid "OpenedNDaysAgo|Opened"
+msgid "OpenedNDaysAgo|Created"
msgstr ""
msgid "Opens in a new window"
@@ -25193,9 +25719,6 @@ msgstr ""
msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
-msgid "Optional."
-msgstr ""
-
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
msgstr ""
@@ -25984,6 +26507,9 @@ msgstr ""
msgid "PerformanceBar|Memory"
msgstr ""
+msgid "PerformanceBar|Memory report"
+msgstr ""
+
msgid "PerformanceBar|Redis calls"
msgstr ""
@@ -26017,18 +26543,12 @@ msgstr ""
msgid "PerformanceBar|wall"
msgstr ""
-msgid "Performs a rebase but skips triggering a new pipeline"
-msgstr ""
-
msgid "Period in seconds"
msgstr ""
msgid "Permalink"
msgstr ""
-msgid "Permanently delete project"
-msgstr ""
-
msgid "Permanently remove group"
msgstr ""
@@ -26299,6 +26819,51 @@ msgstr ""
msgid "PipelineStatusTooltip|Pipeline: %{ci_status}"
msgstr ""
+msgid "PipelineWizardDefaultCommitMessage|Add %{filename}"
+msgstr ""
+
+msgid "PipelineWizardDefaultCommitMessage|Update %{filename}"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|At least one entry is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This field is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This value is not valid"
+msgstr ""
+
+msgid "PipelineWizardListWidget|add another step"
+msgstr ""
+
+msgid "PipelineWizardListWidget|remove step"
+msgstr ""
+
+msgid "PipelineWizard|Commit"
+msgstr ""
+
+msgid "PipelineWizard|Commit Message"
+msgstr ""
+
+msgid "PipelineWizard|Commit changes to your file"
+msgstr ""
+
+msgid "PipelineWizard|Commit file to Branch"
+msgstr ""
+
+msgid "PipelineWizard|Commit your new file"
+msgstr ""
+
+msgid "PipelineWizard|The file has been committed."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem committing the changes."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem while checking whether your file already exists in the specified branch."
+msgstr ""
+
msgid "Pipelines"
msgstr ""
@@ -26413,7 +26978,7 @@ msgstr ""
msgid "Pipelines|Project cache successfully reset."
msgstr ""
-msgid "Pipelines|Revoke"
+msgid "Pipelines|Revoke trigger"
msgstr ""
msgid "Pipelines|Something went wrong while cleaning runners cache."
@@ -26458,6 +27023,12 @@ msgstr ""
msgid "Pipelines|This is a child pipeline within the parent pipeline"
msgstr ""
+msgid "Pipelines|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipelines|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipelines|This pipeline will run code originating from a forked project merge request. This means that the code can potentially have security considerations like exposing CI variables."
msgstr ""
@@ -26500,9 +27071,6 @@ msgstr ""
msgid "Pipelines|Your changes have been successfully committed. Now redirecting to the new merge request page."
msgstr ""
-msgid "Pipelines|detached"
-msgstr ""
-
msgid "Pipelines|error"
msgstr ""
@@ -26512,10 +27080,13 @@ msgstr ""
msgid "Pipelines|latest"
msgstr ""
-msgid "Pipelines|stuck"
+msgid "Pipelines|merge request"
msgstr ""
-msgid "Pipelines|train"
+msgid "Pipelines|merge train"
+msgstr ""
+
+msgid "Pipelines|stuck"
msgstr ""
msgid "Pipelines|yaml invalid"
@@ -26647,6 +27218,12 @@ msgstr ""
msgid "Pipeline|This change will not change the overall test coverage if merged."
msgstr ""
+msgid "Pipeline|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipeline|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipeline|Trigger author"
msgstr ""
@@ -26671,6 +27248,12 @@ msgstr ""
msgid "Pipeline|for"
msgstr ""
+msgid "Pipeline|merge request"
+msgstr ""
+
+msgid "Pipeline|merge train"
+msgstr ""
+
msgid "Pipeline|on"
msgstr ""
@@ -26809,9 +27392,6 @@ msgstr ""
msgid "Please enter a valid time interval"
msgstr ""
-msgid "Please enter or upload a valid license."
-msgstr ""
-
msgid "Please enter your current password."
msgstr ""
@@ -26920,9 +27500,6 @@ msgstr ""
msgid "Please type %{phrase_code} to proceed or close this modal to cancel."
msgstr ""
-msgid "Please type the following to confirm:"
-msgstr ""
-
msgid "Please use this form to report to the admin users who create spam issues, comments or behave inappropriately."
msgstr ""
@@ -26950,12 +27527,27 @@ msgstr ""
msgid "Policies"
msgstr ""
+msgid "Policy '%{escalation_policy_name}' does not exist."
+msgstr ""
+
msgid "Policy management project does have any policies in %{policy_path}"
msgstr ""
msgid "Policy project doesn't exist"
msgstr ""
+msgid "PolicyRuleMultiSelect|%{firstLabel} +%{numberOfAdditionalLabels} more"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|All %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select all"
+msgstr ""
+
msgid "Polling interval multiplier"
msgstr ""
@@ -27184,6 +27776,9 @@ msgstr ""
msgid "Private projects can be created in your personal namespace with:"
msgstr ""
+msgid "Problem with %{name} command: %{message}."
+msgstr ""
+
msgid "Proceed"
msgstr ""
@@ -27658,6 +28253,9 @@ msgstr ""
msgid "Progress"
msgstr ""
+msgid "Progress tracking"
+msgstr ""
+
msgid "Project"
msgstr ""
@@ -27889,6 +28487,9 @@ msgstr ""
msgid "ProjectQualitySummary|Failure"
msgstr ""
+msgid "ProjectQualitySummary|Get insight into the overall percentage of tests in your project that succeed, fail and are skipped."
+msgstr ""
+
msgid "ProjectQualitySummary|Latest pipeline results"
msgstr ""
@@ -27907,6 +28508,12 @@ msgstr ""
msgid "ProjectQualitySummary|See project Code Coverage Statistics"
msgstr ""
+msgid "ProjectQualitySummary|Set up test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|Set up test runs (opens in a new tab)"
+msgstr ""
+
msgid "ProjectQualitySummary|Skipped"
msgstr ""
@@ -28183,13 +28790,19 @@ msgstr ""
msgid "ProjectSettings|LFS objects from this repository are available to forks. %{linkStart}How do I remove them?%{linkEnd}"
msgstr ""
+msgid "ProjectSettings|Learn about commit history."
+msgstr ""
+
+msgid "ProjectSettings|Leave empty to use default template."
+msgstr ""
+
msgid "ProjectSettings|Manage who can see the project in the public access directory."
msgstr ""
msgid "ProjectSettings|Manages large files such as audio, video, and graphics files."
msgstr ""
-msgid "ProjectSettings|Maximum 500 characters."
+msgid "ProjectSettings|Maximum %{maxLength} characters."
msgstr ""
msgid "ProjectSettings|Merge checks"
@@ -28330,6 +28943,9 @@ msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
msgstr ""
+msgid "ProjectSettings|The default template will be applied on save."
+msgstr ""
+
msgid "ProjectSettings|These checks must pass before merge requests can be merged."
msgstr ""
@@ -28384,6 +29000,9 @@ msgstr ""
msgid "ProjectSettings|What are badges?"
msgstr ""
+msgid "ProjectSettings|What are merge trains?"
+msgstr ""
+
msgid "ProjectSettings|When merge request pipelines are enabled in the CI/CD configuration file, pipelines validate the combined results of the source and target branches. %{link_start}How to configure merge request pipelines?%{link_end}"
msgstr ""
@@ -28501,6 +29120,9 @@ msgstr ""
msgid "Projects are organized into groups"
msgstr ""
+msgid "Projects are where you store your code, access issues, wiki and other features of GitLab."
+msgstr ""
+
msgid "Projects contributed to"
msgstr ""
@@ -28516,12 +29138,6 @@ msgstr ""
msgid "Projects to index"
msgstr ""
-msgid "Projects will be permanently deleted after a %{waiting_period}-day waiting period."
-msgstr ""
-
-msgid "Projects will be permanently deleted immediately."
-msgstr ""
-
msgid "Projects with critical vulnerabilities"
msgstr ""
@@ -28606,6 +29222,9 @@ msgstr ""
msgid "ProjectsNew|Import project"
msgstr ""
+msgid "ProjectsNew|Include a Getting Started README"
+msgstr ""
+
msgid "ProjectsNew|Initialize repository with a README"
msgstr ""
@@ -28621,6 +29240,9 @@ msgstr ""
msgid "ProjectsNew|Project description %{tag_start}(optional)%{tag_end}"
msgstr ""
+msgid "ProjectsNew|Recommended if you're new to GitLab"
+msgstr ""
+
msgid "ProjectsNew|Run CI/CD for external repository"
msgstr ""
@@ -29038,6 +29660,9 @@ msgstr ""
msgid "ProtectedBranch|Unprotect"
msgstr ""
+msgid "ProtectedBranch|Unprotect branch"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
@@ -29065,6 +29690,9 @@ msgstr ""
msgid "ProtectedEnvironment|Protected Environment (%{protected_environments_count})"
msgstr ""
+msgid "ProtectedEnvironment|Required approvals"
+msgstr ""
+
msgid "ProtectedEnvironment|Select an environment"
msgstr ""
@@ -29086,10 +29714,13 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|Unprotect tag"
+msgstr ""
+
msgid "ProtectedTags|default"
msgstr ""
-msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
+msgid "ProtectedTag|By default, protected tags restrict who can modify the tag."
msgstr ""
msgid "ProtectedTag|Learn more."
@@ -29152,6 +29783,9 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Public projects are an easy way to allow everyone to have read-only access."
+msgstr ""
+
msgid "Publish to status page"
msgstr ""
@@ -29308,9 +29942,6 @@ msgstr ""
msgid "QualitySummary|Project quality"
msgstr ""
-msgid "Quarters"
-msgstr ""
-
msgid "Query"
msgstr ""
@@ -29395,6 +30026,9 @@ msgstr ""
msgid "Read more about project permissions %{help_link_open}here%{help_link_close}"
msgstr ""
+msgid "Read more about related epics"
+msgstr ""
+
msgid "Read more about related issues"
msgstr ""
@@ -29425,10 +30059,7 @@ msgstr ""
msgid "Rebase source branch on the target branch."
msgstr ""
-msgid "Rebase without CI"
-msgstr ""
-
-msgid "Rebases and triggers a pipeline"
+msgid "Rebase without pipeline"
msgstr ""
msgid "Recaptcha verified?"
@@ -29479,9 +30110,6 @@ msgstr ""
msgid "Reconfigure"
msgstr ""
-msgid "Recovering projects"
-msgstr ""
-
msgid "Recovery Codes"
msgstr ""
@@ -29541,6 +30169,12 @@ msgstr ""
msgid "Regex pattern"
msgstr ""
+msgid "Region"
+msgstr ""
+
+msgid "Regions"
+msgstr ""
+
msgid "Register"
msgstr ""
@@ -29771,9 +30405,6 @@ msgstr ""
msgid "Remove all or specific reviewer(s)"
msgstr ""
-msgid "Remove approver"
-msgstr ""
-
msgid "Remove approvers"
msgstr ""
@@ -29789,6 +30420,9 @@ msgstr ""
msgid "Remove attention request"
msgstr ""
+msgid "Remove attention request(s)"
+msgstr ""
+
msgid "Remove avatar"
msgstr ""
@@ -29927,6 +30561,9 @@ msgstr ""
msgid "Removed an issue from an epic."
msgstr ""
+msgid "Removed attention from %{users_sentence}."
+msgstr ""
+
msgid "Removed attention request from @%{username}"
msgstr ""
@@ -29978,6 +30615,9 @@ msgstr ""
msgid "Removes an issue from an epic."
msgstr ""
+msgid "Removes attention from %{users_sentence}."
+msgstr ""
+
msgid "Removes parent epic %{epic_ref}."
msgstr ""
@@ -30089,6 +30729,9 @@ msgstr ""
msgid "Report abuse to admin"
msgstr ""
+msgid "Report is generating and will be sent to your email address."
+msgstr ""
+
msgid "Reported %{timeAgo} by %{reportedBy}"
msgstr ""
@@ -30378,6 +31021,15 @@ msgstr ""
msgid "Request attention"
msgstr ""
+msgid "Request attention from %{users_sentence}."
+msgstr ""
+
+msgid "Request attention from assignee or reviewer"
+msgstr ""
+
+msgid "Request attention from assignee(s) or reviewer(s)"
+msgstr ""
+
msgid "Request attention to review"
msgstr ""
@@ -30402,6 +31054,9 @@ msgstr ""
msgid "Requested %{time_ago}"
msgstr ""
+msgid "Requested attention from %{users_sentence}."
+msgstr ""
+
msgid "Requested attention from @%{username}"
msgstr ""
@@ -30616,6 +31271,9 @@ msgstr ""
msgid "Restore project"
msgstr ""
+msgid "Restoring projects"
+msgstr ""
+
msgid "Restoring the group will prevent the group, its subgroups and projects from being removed on this date."
msgstr ""
@@ -30646,6 +31304,9 @@ msgstr ""
msgid "Retry"
msgstr ""
+msgid "Retry failed jobs"
+msgstr ""
+
msgid "Retry job"
msgstr ""
@@ -30693,9 +31354,6 @@ msgstr ""
msgid "Review changes"
msgstr ""
-msgid "Review requested from %{name}"
-msgstr ""
-
msgid "Review requests for you"
msgstr ""
@@ -30860,6 +31518,9 @@ msgstr ""
msgid "Runners|Assigned Group"
msgstr ""
+msgid "Runners|Assigned Projects (%{projectCount})"
+msgstr ""
+
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30929,6 +31590,9 @@ msgstr ""
msgid "Runners|Instance"
msgstr ""
+msgid "Runners|Jobs"
+msgstr ""
+
msgid "Runners|Last contact"
msgstr ""
@@ -31022,9 +31686,6 @@ msgstr ""
msgid "Runners|Runner %{name} was deleted"
msgstr ""
-msgid "Runners|Runner ID"
-msgstr ""
-
msgid "Runners|Runner assigned to project."
msgstr ""
@@ -31172,6 +31833,9 @@ msgstr ""
msgid "Runners|stale"
msgstr ""
+msgid "Runner|This runner has not run any jobs."
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -31286,6 +31950,24 @@ msgstr ""
msgid "Saving project."
msgstr ""
+msgid "ScanResultPolicy|%{ifLabelStart}if%{ifLabelEnd} %{scanners} scan in an open merge request targeting the %{branches} branch(es) finds %{vulnerabilitiesAllowed} or more %{severities} vulnerabilities that are %{vulnerabilityStates}"
+msgstr ""
+
+msgid "ScanResultPolicy|%{thenLabelStart}Then%{thenLabelEnd} Require approval from %{approvalsRequired} of the following approvers: %{approvers}"
+msgstr ""
+
+msgid "ScanResultPolicy|add an approver"
+msgstr ""
+
+msgid "ScanResultPolicy|scanners"
+msgstr ""
+
+msgid "ScanResultPolicy|severity levels"
+msgstr ""
+
+msgid "ScanResultPolicy|vulnerability states"
+msgstr ""
+
msgid "Scanner"
msgstr ""
@@ -31418,6 +32100,9 @@ msgstr ""
msgid "Search for a user"
msgstr ""
+msgid "Search for an emoji"
+msgstr ""
+
msgid "Search for projects, issues, etc."
msgstr ""
@@ -31605,18 +32290,12 @@ msgstr ""
msgid "Secret Detection"
msgstr ""
-msgid "Secret access key"
-msgstr ""
-
msgid "Secret token"
msgstr ""
msgid "Secure token that identifies an external storage request."
msgstr ""
-msgid "SecureCodeWarrior"
-msgstr ""
-
msgid "Security"
msgstr ""
@@ -31641,9 +32320,6 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "Security training with guide and learning pathways."
-msgstr ""
-
msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
@@ -31746,7 +32422,7 @@ msgstr ""
msgid "SecurityConfiguration|Manage corpus"
msgstr ""
-msgid "SecurityConfiguration|Manage corpus files used as mutation sources in coverage fuzzing."
+msgid "SecurityConfiguration|Manage corpus files used as seed inputs with coverage-guided fuzzing."
msgstr ""
msgid "SecurityConfiguration|Manage profiles for use by DAST scans."
@@ -31812,15 +32488,15 @@ msgstr ""
msgid "SecurityOrchestration|.yaml preview"
msgstr ""
-msgid "SecurityOrchestration|Action"
-msgstr ""
-
msgid "SecurityOrchestration|Actions"
msgstr ""
msgid "SecurityOrchestration|Add rule"
msgstr ""
+msgid "SecurityOrchestration|After dismissing the alert, the information will never be shown again."
+msgstr ""
+
msgid "SecurityOrchestration|All policies"
msgstr ""
@@ -31836,7 +32512,7 @@ msgstr ""
msgid "SecurityOrchestration|Description"
msgstr ""
-msgid "SecurityOrchestration|Disabled"
+msgid "SecurityOrchestration|Don't show the alert anymore"
msgstr ""
msgid "SecurityOrchestration|Edit policy"
@@ -31845,13 +32521,13 @@ msgstr ""
msgid "SecurityOrchestration|Edit policy project"
msgstr ""
-msgid "SecurityOrchestration|Enabled"
+msgid "SecurityOrchestration|Empty policy name"
msgstr ""
-msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Enabled"
msgstr ""
-msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
msgstr ""
msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
@@ -31860,7 +32536,7 @@ msgstr ""
msgid "SecurityOrchestration|Invalid policy type"
msgstr ""
-msgid "SecurityOrchestration|Latest scan"
+msgid "SecurityOrchestration|Latest scan run against %{agent}"
msgstr ""
msgid "SecurityOrchestration|Network"
@@ -31869,15 +32545,27 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No actions defined - policy will not run."
+msgstr ""
+
+msgid "SecurityOrchestration|No description"
+msgstr ""
+
msgid "SecurityOrchestration|No rules defined - policy will not run."
msgstr ""
+msgid "SecurityOrchestration|Not enabled"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
msgid "SecurityOrchestration|Policies"
msgstr ""
+msgid "SecurityOrchestration|Policy Type"
+msgstr ""
+
msgid "SecurityOrchestration|Policy cannot be enabled for non-existing branches (%{branches})"
msgstr ""
@@ -31902,10 +32590,13 @@ msgstr ""
msgid "SecurityOrchestration|Require %{approvals} %{plural} from %{approvers} if any of the following occur:"
msgstr ""
-msgid "SecurityOrchestration|Rule"
+msgid "SecurityOrchestration|Rules"
msgstr ""
-msgid "SecurityOrchestration|Rules"
+msgid "SecurityOrchestration|Runs %{actions} and %{lastAction} scans"
+msgstr ""
+
+msgid "SecurityOrchestration|Runs a %{action} scan"
msgstr ""
msgid "SecurityOrchestration|Scan Execution"
@@ -31965,6 +32656,9 @@ msgstr ""
msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
+msgid "SecurityOrchestration|This view only shows scan results for the agent %{agent}. You can view scan results for all agents in the %{linkStart}Operational Vulnerabilities tab of the vulnerability report%{linkEnd}."
+msgstr ""
+
msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
@@ -32019,9 +32713,6 @@ msgstr ""
msgid "SecurityOrchestration|users with ids"
msgstr ""
-msgid "SecurityOrchestration|view results"
-msgstr ""
-
msgid "SecurityOrchestration|vulnerabilities"
msgstr ""
@@ -32691,22 +33382,19 @@ 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|In order to start using functions as a service, you must first install Knative on your Kubernetes cluster. %{linkStart}More information%{linkEnd}"
-msgstr ""
-
msgid "Serverless|Learn more about Serverless"
msgstr ""
msgid "Serverless|No functions available"
msgstr ""
-msgid "Serverless|Sign up for First Look"
+msgid "Serverless|Serverless was %{linkStart}deprecated%{linkEnd} in GitLab 14.3."
+msgstr ""
+
+msgid "Serverless|Serverless was %{postLinkStart}deprecated%{postLinkEnd}. But if you opt to use it, you must install Knative in your Kubernetes cluster first. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "Serverless|The deploy job has not finished."
@@ -32718,9 +33406,6 @@ 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 ""
@@ -32736,9 +33421,6 @@ msgstr ""
msgid "Service Account Key"
msgstr ""
-msgid "Service Accounts"
-msgstr ""
-
msgid "Service Accounts keys authorize GitLab to deploy your Google Cloud project"
msgstr ""
@@ -32748,10 +33430,10 @@ msgstr ""
msgid "Service Desk allows people to create issues in your GitLab instance without their own user account. It provides a unique email address for end users to create issues in a project. Replies can be sent either through the GitLab interface or by email. End users only see threads through email."
msgstr ""
-msgid "Service Usage Data"
+msgid "Service account generated successfully"
msgstr ""
-msgid "Service account generated successfully"
+msgid "Service accounts"
msgstr ""
msgid "Service ping is disabled in your configuration file, and cannot be enabled through this form."
@@ -32895,6 +33577,9 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
+msgid "Set the per-user rate limit for getting a user by ID via the API."
+msgstr ""
+
msgid "Set the per-user rate limit for notes created by web or API requests."
msgstr ""
@@ -33074,6 +33759,9 @@ msgstr ""
msgid "Shared runners details"
msgstr ""
+msgid "Shared runners enabled cannot be enabled until a valid credit card is on file"
+msgstr ""
+
msgid "Shared runners help link"
msgstr ""
@@ -33131,6 +33819,9 @@ msgstr ""
msgid "Show all issues."
msgstr ""
+msgid "Show all milestones"
+msgstr ""
+
msgid "Show all test cases."
msgstr ""
@@ -33167,6 +33858,9 @@ msgstr ""
msgid "Show file contents"
msgstr ""
+msgid "Show group milestones"
+msgstr ""
+
msgid "Show labels"
msgstr ""
@@ -33182,6 +33876,12 @@ msgstr ""
msgid "Show open epics"
msgstr ""
+msgid "Show project milestones"
+msgstr ""
+
+msgid "Show sub-group milestones"
+msgstr ""
+
msgid "Show the Closed list"
msgstr ""
@@ -33191,11 +33891,6 @@ msgstr ""
msgid "Show whitespace changes"
msgstr ""
-msgid "Showing %d event"
-msgid_plural "Showing %d events"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Showing %{conflict} between %{sourceBranch} and %{targetBranch}"
msgstr ""
@@ -33255,12 +33950,6 @@ msgstr ""
msgid "Sidebar|None"
msgstr ""
-msgid "Sidebar|Only numeral characters allowed"
-msgstr ""
-
-msgid "Sidebar|Weight"
-msgstr ""
-
msgid "Sidekiq job compression threshold (bytes)"
msgstr ""
@@ -33423,6 +34112,9 @@ msgstr ""
msgid "Slack logo"
msgstr ""
+msgid "SlackIntegration|Are you sure you want to remove this project from the Slack application?"
+msgstr ""
+
msgid "SlackIntegration|GitLab for Slack"
msgstr ""
@@ -33432,6 +34124,9 @@ msgstr ""
msgid "SlackIntegration|Project alias"
msgstr ""
+msgid "SlackIntegration|Remove project"
+msgstr ""
+
msgid "SlackIntegration|Select a GitLab project to link with your Slack workspace."
msgstr ""
@@ -33576,9 +34271,6 @@ msgstr ""
msgid "Something went wrong trying to load issue contacts."
msgstr ""
-msgid "Something went wrong when creating a work item. Please try again"
-msgstr ""
-
msgid "Something went wrong when reordering designs. Please try again"
msgstr ""
@@ -33672,9 +34364,6 @@ msgstr ""
msgid "Something went wrong while inserting your image. Please try again."
msgstr ""
-msgid "Something went wrong while merging this merge request. Please try again."
-msgstr ""
-
msgid "Something went wrong while obtaining the Let's Encrypt certificate."
msgstr ""
@@ -33996,10 +34685,10 @@ 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."
+msgid "SourcegraphAdmin|Learn more."
msgstr ""
-msgid "SourcegraphAdmin|More information"
+msgid "SourcegraphAdmin|Only public projects have code intelligence enabled and communicate with Sourcegraph."
msgstr ""
msgid "SourcegraphAdmin|Save changes"
@@ -34008,7 +34697,7 @@ msgstr ""
msgid "SourcegraphAdmin|Sourcegraph URL"
msgstr ""
-msgid "SourcegraphAdmin|e.g. https://sourcegraph.example.com"
+msgid "SourcegraphAdmin|https://sourcegraph.example.com"
msgstr ""
msgid "SourcegraphPreferences|This feature is experimental and currently limited to certain projects."
@@ -34143,6 +34832,9 @@ msgstr ""
msgid "Start date"
msgstr ""
+msgid "Start free trial"
+msgstr ""
+
msgid "Start merge train"
msgstr ""
@@ -34173,6 +34865,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started escalation for this incident."
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -34185,6 +34880,9 @@ msgstr ""
msgid "Starts at (UTC)"
msgstr ""
+msgid "Starts escalations for this incident"
+msgstr ""
+
msgid "Starts on"
msgstr ""
@@ -34446,6 +35144,9 @@ msgstr ""
msgid "Strikethrough"
msgstr ""
+msgid "Strikethrough text"
+msgstr ""
+
msgid "Subgroup information"
msgstr ""
@@ -34680,6 +35381,21 @@ msgstr ""
msgid "Subscriptions"
msgstr ""
+msgid "Subscriptions|Chat with sales"
+msgstr ""
+
+msgid "Subscriptions|Close"
+msgstr ""
+
+msgid "Subscriptions|Not ready to buy yet?"
+msgstr ""
+
+msgid "Subscriptions|Start a free trial"
+msgstr ""
+
+msgid "Subscriptions|We understand. Maybe you have some questions for our sales team, or maybe you'd like to try some of the paid features first. What would you like to do?"
+msgstr ""
+
msgid "Subscription|Your subscription for %{strong}%{namespace_name}%{strong_close} has expired and you are now on %{pricing_link_start}the GitLab Free tier%{pricing_link_end}. Don't worry, your data is safe. Get in touch with our support team (%{support_email}). They'll gladly help with your subscription renewal."
msgstr ""
@@ -34890,6 +35606,9 @@ msgstr ""
msgid "SuperSonics|Maximum users"
msgstr ""
+msgid "SuperSonics|Offline cloud"
+msgstr ""
+
msgid "SuperSonics|Paste your activation code"
msgstr ""
@@ -34956,6 +35675,12 @@ msgstr ""
msgid "SuperSonics|You do not have an active subscription"
msgstr ""
+msgid "SuperSonics|You have a future dated license"
+msgstr ""
+
+msgid "SuperSonics|You have added a license that activates on %{date}. Please see the subscription history table below for more details."
+msgstr ""
+
msgid "SuperSonics|You have successfully added a license that activates on %{date}. Please see the subscription history table below for more details."
msgstr ""
@@ -35115,6 +35840,9 @@ msgstr ""
msgid "Tag name is required"
msgstr ""
+msgid "Tag push"
+msgstr ""
+
msgid "Tag push events"
msgstr ""
@@ -35217,6 +35945,9 @@ msgstr ""
msgid "TagsPage|protected"
msgstr ""
+msgid "Take a look at the documentation to discover all of GitLab’s capabilities."
+msgstr ""
+
msgid "Target Branch"
msgstr ""
@@ -35619,6 +36350,9 @@ msgstr ""
msgid "Tests"
msgstr ""
+msgid "Text (optional)"
+msgstr ""
+
msgid "Text added to the body of all email messages. %{character_limit} character limit"
msgstr ""
@@ -35669,6 +36403,9 @@ msgstr ""
msgid "The CSV export will be created in the background. Once finished, it will be sent to %{email} in an attachment."
msgstr ""
+msgid "The CSV export you requested of all user memberships is attached to this email."
+msgstr ""
+
msgid "The GitLab subscription service (customers.gitlab.com) is currently experiencing an outage. You can monitor the status and get updates at %{linkStart}status.gitlab.com%{linkEnd}."
msgstr ""
@@ -35744,6 +36481,9 @@ 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 epic"
+msgstr ""
+
msgid "The current issue"
msgstr ""
@@ -35905,6 +36645,9 @@ msgstr ""
msgid "The latest pipeline for this merge request has failed."
msgstr ""
+msgid "The license key is invalid."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -35920,6 +36663,9 @@ msgstr ""
msgid "The license was successfully uploaded and will be active from %{starts_at}. You can see the details below."
msgstr ""
+msgid "The license you uploaded is invalid. If the issue persists, contact support at %{link}."
+msgstr ""
+
msgid "The list creation wizard is already open"
msgstr ""
@@ -36541,10 +37287,13 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} and everything this project contains. %{strongOpen}There is no going back%{strongClose}"
+msgstr ""
+
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains."
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}on %{date}%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains. %{strongOpen}There is no going back.%{strongClose}"
msgstr ""
msgid "This action will %{strongOpen}permanently remove%{strongClose} %{codeOpen}%{group}%{codeClose} %{strongOpen}immediately%{strongClose}."
@@ -36673,9 +37422,6 @@ msgstr ""
msgid "This file was modified for readability, and can't accept suggestions. Edit it directly."
msgstr ""
-msgid "This forked project has the following:"
-msgstr ""
-
msgid "This form is disabled in preview"
msgstr ""
@@ -36688,7 +37434,7 @@ msgstr ""
msgid "This group can't be removed because it is linked to a subscription. To remove this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
-msgid "This group can't be transfered because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
+msgid "This group can't be transferred because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
msgid "This group cannot be invited to a project inside a group with enforced SSO"
@@ -36715,6 +37461,9 @@ 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 incident is already escalated with '%{escalation_policy_name}'."
+msgstr ""
+
msgid "This invitation was sent to %{mail_to_invite_email}, but you are signed in as %{link_to_current_user} with email %{mail_to_current_user}."
msgstr ""
@@ -36733,9 +37482,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 merge train pipeline"
-msgstr ""
-
msgid "This is a private email address %{helpIcon} generated just for you. Anyone who has it can create issues or merge requests as if they were you. If that happens, %{resetLinkStart}reset this token%{resetLinkEnd}."
msgstr ""
@@ -36757,6 +37503,12 @@ msgstr ""
msgid "This is your current session"
msgstr ""
+msgid "This issue cannot be assigned to a confidential epic because it is public."
+msgstr ""
+
+msgid "This issue cannot be made public because it belongs to a confidential epic."
+msgstr ""
+
msgid "This issue is confidential and should only be visible to team members with at least Reporter access."
msgstr ""
@@ -36874,6 +37626,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 branch is protected from force push."
+msgstr ""
+
msgid "This merge request cannot be rebased while there are conflicts."
msgstr ""
@@ -36925,9 +37680,15 @@ msgstr ""
msgid "This pipeline was triggered by a schedule."
msgstr ""
+msgid "This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project"
msgstr ""
+msgid "This project can be restored until %{date}."
+msgstr ""
+
msgid "This project cannot be %{visibilityLevel} because the visibility of %{openShowLink}%{name}%{closeShowLink} is %{visibility}. To make this project %{visibilityLevel}, you must first %{openEditLink}change the visibility%{closeEditLink} of the parent group."
msgstr ""
@@ -36946,6 +37707,9 @@ msgstr ""
msgid "This project is %{strongStart}NOT%{strongEnd} a fork, and has the following:"
msgstr ""
+msgid "This project is %{strongStart}NOT%{strongEnd} a fork. This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -37637,6 +38401,9 @@ msgstr ""
msgid "Today"
msgstr ""
+msgid "Todos count"
+msgstr ""
+
msgid "Todos|Are you looking for things to do? Take a look at %{strongStart}%{openIssuesLinkStart}open issues%{openIssuesLinkEnd}%{strongEnd}, contribute to %{strongStart}%{mergeRequestLinkStart}a merge request%{mergeRequestLinkEnd}%{mergeRequestLinkEnd}%{strongEnd}, or mention someone in a comment to automatically assign them a new to-do item."
msgstr ""
@@ -37910,10 +38677,8 @@ msgstr ""
msgid "Trending"
msgstr ""
-msgid "Trials|%{planName} Trial %{enDash} %{num} day left"
-msgid_plural "Trials|%{planName} Trial %{enDash} %{num} days left"
-msgstr[0] ""
-msgstr[1] ""
+msgid "Trials|%{planName} Trial"
+msgstr ""
msgid "Trials|Compare all plans"
msgstr ""
@@ -37921,6 +38686,9 @@ msgstr ""
msgid "Trials|Create a new group to start your GitLab Ultimate trial."
msgstr ""
+msgid "Trials|Day %{daysUsed}/%{duration}"
+msgstr ""
+
msgid "Trials|Go back to GitLab"
msgstr ""
@@ -38170,7 +38938,7 @@ msgstr ""
msgid "URL is triggered when repository is updated"
msgstr ""
-msgid "URL must be percent-encoded if neccessary."
+msgid "URL must be percent-encoded if necessary."
msgstr ""
msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
@@ -38389,6 +39157,9 @@ msgstr ""
msgid "Unlock account"
msgstr ""
+msgid "Unlock more features with GitLab Ultimate"
+msgstr ""
+
msgid "Unlock the discussion"
msgstr ""
@@ -38452,6 +39223,9 @@ msgstr ""
msgid "Unsubscribes from this %{quick_action_target}."
msgstr ""
+msgid "Unsupported sort value."
+msgstr ""
+
msgid "Unsupported todo type passed. Supported todo types are: %{todo_types}"
msgstr ""
@@ -38680,6 +39454,9 @@ msgstr ""
msgid "UsageQuota|File attachments and smaller design graphics."
msgstr ""
+msgid "UsageQuota|From %{storage_enforcement_date} storage limits will apply to this namespace. View and manage your usage in %{strong_start}Group Settings &gt; Usage quotas%{strong_end}."
+msgstr ""
+
msgid "UsageQuota|Git repository."
msgstr ""
@@ -38740,6 +39517,9 @@ msgstr ""
msgid "UsageQuota|Storage type"
msgstr ""
+msgid "UsageQuota|Storage used"
+msgstr ""
+
msgid "UsageQuota|This is the total amount of storage used across your projects within this namespace."
msgstr ""
@@ -38935,6 +39715,12 @@ msgstr ""
msgid "Use hashed storage paths for newly created and renamed repositories. Always enabled since 13.0."
msgstr ""
+msgid "Use issue count"
+msgstr ""
+
+msgid "Use issue weight"
+msgstr ""
+
msgid "Use one line per URI"
msgstr ""
@@ -39316,6 +40102,9 @@ msgstr ""
msgid "Users"
msgstr ""
+msgid "Users API rate limit"
+msgstr ""
+
msgid "Users can launch a development environment from a GitLab browser tab when the %{linkStart}Gitpod%{linkEnd} integration is enabled."
msgstr ""
@@ -39641,6 +40430,9 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View group pipeline usage quota"
+msgstr ""
+
msgid "View incident details at"
msgstr ""
@@ -39793,6 +40585,9 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
+msgid "Vulnerability"
+msgstr ""
+
msgid "Vulnerability Report"
msgstr ""
@@ -39844,6 +40639,9 @@ msgstr ""
msgid "VulnerabilityManagement|An unverified non-confirmed finding"
msgstr ""
+msgid "VulnerabilityManagement|At least one identifier is required"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -39853,12 +40651,24 @@ msgstr ""
msgid "VulnerabilityManagement|Create Jira issue"
msgstr ""
+msgid "VulnerabilityManagement|Enter a name"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE code"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE identifier URL"
+msgstr ""
+
msgid "VulnerabilityManagement|Fetching linked Jira issues"
msgstr ""
msgid "VulnerabilityManagement|Manually add a vulnerability entry into the vulnerability report."
msgstr ""
+msgid "VulnerabilityManagement|Name is a required field"
+msgstr ""
+
msgid "VulnerabilityManagement|Needs triage"
msgstr ""
@@ -39874,6 +40684,18 @@ msgstr ""
msgid "VulnerabilityManagement|Select a method"
msgstr ""
+msgid "VulnerabilityManagement|Select a severity level"
+msgstr ""
+
+msgid "VulnerabilityManagement|Select a status"
+msgstr ""
+
+msgid "VulnerabilityManagement|Severity is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Something went wrong while creating vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -39898,6 +40720,12 @@ msgstr ""
msgid "VulnerabilityManagement|Something went wrong, could not update vulnerability state."
msgstr ""
+msgid "VulnerabilityManagement|Status is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Submit vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Summary, detailed description, steps to reproduce, etc."
msgstr ""
@@ -40093,6 +40921,9 @@ msgstr ""
msgid "WARNING:"
msgstr ""
+msgid "WARNING: This snippet contains hidden files which might be used to mask malicious behavior. Exercise caution if cloning and executing code from this snippet."
+msgstr ""
+
msgid "Wait for the file to load to copy its contents"
msgstr ""
@@ -40312,6 +41143,15 @@ msgstr ""
msgid "Webhooks|An issue is created, updated, closed, or reopened."
msgstr ""
+msgid "Webhooks|Are you sure you want to delete this group hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this project hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this webhook?"
+msgstr ""
+
msgid "Webhooks|Comments"
msgstr ""
@@ -40321,6 +41161,9 @@ msgstr ""
msgid "Webhooks|Confidential issues events"
msgstr ""
+msgid "Webhooks|Delete webhook"
+msgstr ""
+
msgid "Webhooks|Deployment events"
msgstr ""
@@ -40554,6 +41397,9 @@ msgstr ""
msgid "Wiki"
msgstr ""
+msgid "Wiki page"
+msgstr ""
+
msgid "Wiki page was successfully created."
msgstr ""
@@ -40659,7 +41505,7 @@ msgstr ""
msgid "WikiPageConflictMessage|Someone edited the page the same time you did. Please check out %{wikiLinkStart}the page%{wikiLinkEnd} and make sure your changes will not unintentionally remove theirs."
msgstr ""
-msgid "WikiPage|An error occured while trying to render the content editor. Please try again later."
+msgid "WikiPage|An error occurred while trying to render the content editor. Please try again later."
msgstr ""
msgid "WikiPage|Are you sure you want to switch back to the classic editor?"
@@ -40818,6 +41664,18 @@ msgstr ""
msgid "WorkItem|New Task"
msgstr ""
+msgid "WorkItem|Something went wrong when creating a work item. Please try again"
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching the work item. Please try again."
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching work item types. Please try again"
+msgstr ""
+
+msgid "WorkItem|Type"
+msgstr ""
+
msgid "WorkItem|Work Items"
msgstr ""
@@ -40884,7 +41742,10 @@ msgstr ""
msgid "You are about to add %{usersTag} people to the discussion. They will all receive a notification."
msgstr ""
-msgid "You are about to permanently delete this project"
+msgid "You are about to delete this forked project containing:"
+msgstr ""
+
+msgid "You are about to delete this project containing:"
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."
@@ -40905,6 +41766,9 @@ msgstr ""
msgid "You are attempting to update a file that has changed since you started editing it."
msgstr ""
+msgid "You are billed if you exceed this number. %{qsrOverageLinkStart}How does billing work?%{qsrOverageLinkEnd}"
+msgstr ""
+
msgid "You are connected to the Prometheus server, but there is currently no data to display."
msgstr ""
@@ -40962,6 +41826,9 @@ msgstr ""
msgid "You are not authorized to update this scanner profile"
msgstr ""
+msgid "You are not authorized to upload metric images"
+msgstr ""
+
msgid "You are now impersonating %{username}"
msgstr ""
@@ -41115,9 +41982,6 @@ msgstr ""
msgid "You can only upload one design when dropping onto an existing design."
msgstr ""
-msgid "You can recover this project until %{date}"
-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 ""
@@ -41166,9 +42030,6 @@ msgstr ""
msgid "You cannot write to this read-only GitLab instance."
msgstr ""
-msgid "You can’t %{tag_start}edit%{tag_end} files directly in this project. Fork this project and submit a merge request with your changes."
-msgstr ""
-
msgid "You can’t edit files directly in this project. Fork this project and submit a merge request with your changes."
msgstr ""
@@ -41321,9 +42182,6 @@ 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 set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
@@ -41354,12 +42212,6 @@ msgstr ""
msgid "You must have maintainer access to force delete a lock"
msgstr ""
-msgid "You must have permission to create a project in a group before forking."
-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 ""
@@ -41765,7 +42617,7 @@ msgstr ""
msgid "Your public email will be displayed on your public profile."
msgstr ""
-msgid "Your request for access could not be processed: %{error_meesage}"
+msgid "Your request for access could not be processed: %{error_message}"
msgstr ""
msgid "Your request for access has been queued for review."
@@ -41948,6 +42800,9 @@ msgstr ""
msgid "archived:"
msgstr ""
+msgid "artifacts"
+msgstr ""
+
msgid "assign yourself"
msgstr ""
@@ -41977,6 +42832,9 @@ msgstr[1] ""
msgid "branch name"
msgstr ""
+msgid "builds"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -42400,6 +43258,9 @@ msgstr ""
msgid "contact with same email already exists in group hierarchy"
msgstr ""
+msgid "container registry images"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -42439,6 +43300,9 @@ msgstr ""
msgid "data"
msgstr ""
+msgid "database"
+msgstr ""
+
msgid "date must not be after 9999-12-31"
msgstr ""
@@ -42462,9 +43326,6 @@ msgstr ""
msgid "design"
msgstr ""
-msgid "detached"
-msgstr ""
-
msgid "disabled"
msgstr ""
@@ -42713,7 +43574,7 @@ msgstr ""
msgid "is not a valid X509 certificate."
msgstr ""
-msgid "is not allowed for sign-up."
+msgid "is not allowed for sign-up. Please use your regular email address."
msgstr ""
msgid "is not allowed for this group."
@@ -42725,7 +43586,7 @@ msgstr ""
msgid "is not allowed since the group is not top-level group."
msgstr ""
-msgid "is not allowed."
+msgid "is not allowed. Please use your regular email address."
msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
@@ -42812,6 +43673,9 @@ msgstr ""
msgid "level: %{level}"
msgstr ""
+msgid "lfs objects"
+msgstr ""
+
msgid "limit of %{project_limit} reached"
msgstr ""
@@ -43031,6 +43895,9 @@ msgstr ""
msgid "mrWidget|Merge blocked: pipeline must succeed. It's waiting for a manual action to continue."
msgstr ""
+msgid "mrWidget|Merge blocked: pipeline must succeed. Push a commit that fixes the failure, or %{linkStart}learn about other solutions.%{linkEnd}"
+msgstr ""
+
msgid "mrWidget|Merge blocked: this merge request must be approved."
msgstr ""
@@ -43148,9 +44015,6 @@ msgstr ""
msgid "mrWidget|The changes were not merged into"
msgstr ""
-msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -43298,9 +44162,6 @@ msgstr ""
msgid "open issue"
msgstr ""
-msgid "opened %{timeAgo}"
-msgstr ""
-
msgid "or"
msgstr ""
@@ -43312,6 +44173,12 @@ msgid_plural "out of %d total tests"
msgstr[0] ""
msgstr[1] ""
+msgid "packages"
+msgstr ""
+
+msgid "pages"
+msgstr ""
+
msgid "parent"
msgid_plural "parents"
msgstr[0] ""
@@ -43461,6 +44328,9 @@ msgid_plural "replies"
msgstr[0] ""
msgstr[1] ""
+msgid "repositories"
+msgstr ""
+
msgid "repository:"
msgstr ""
@@ -43581,12 +44451,18 @@ msgstr ""
msgid "tag name"
msgstr ""
+msgid "terraform states"
+msgstr ""
+
msgid "the correct format."
msgstr ""
msgid "the file"
msgstr ""
+msgid "the following epic(s)"
+msgstr ""
+
msgid "the following issue(s)"
msgstr ""
@@ -43599,21 +44475,12 @@ msgstr ""
msgid "this document"
msgstr ""
-msgid "this issue cannot be assigned to a confidential epic since it is public"
-msgstr ""
-
-msgid "this issue cannot be made public since it belongs to a confidential epic"
-msgstr ""
-
msgid "time summary"
msgstr ""
msgid "toggle collapse"
msgstr ""
-msgid "train"
-msgstr ""
-
msgid "triggered"
msgstr ""
@@ -43742,3 +44609,6 @@ msgstr ""
msgid "{project}"
msgstr ""
+msgid "✔"
+msgstr ""
+
diff --git a/locale/br_FR/gitlab.po b/locale/br_FR/gitlab.po
index 7b26b894b62..1ad70c99a0f 100644
--- a/locale/br_FR/gitlab.po
+++ b/locale/br_FR/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: br-FR\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2022-02-02 15:49\n"
+"PO-Revision-Date: 2022-03-01 20:41\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -188,6 +188,14 @@ msgstr[2] ""
msgstr[3] ""
msgstr[4] ""
+msgid "%d assigned issue"
+msgid_plural "%d assigned issues"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+msgstr[4] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -628,8 +636,32 @@ msgstr[2] ""
msgstr[3] ""
msgstr[4] ""
-msgid "%d vulnerability updated"
-msgid_plural "%d vulnerabilities updated"
+msgid "%d vulnerability set to confirmed"
+msgid_plural "%d vulnerabilities set to confirmed"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+msgstr[4] ""
+
+msgid "%d vulnerability set to dismissed"
+msgid_plural "%d vulnerabilities set to dismissed"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+msgstr[4] ""
+
+msgid "%d vulnerability set to needs triage"
+msgid_plural "%d vulnerabilities set to needs triage"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+msgstr[4] ""
+
+msgid "%d vulnerability set to resolved"
+msgid_plural "%d vulnerabilities set to resolved"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
@@ -738,6 +770,12 @@ msgstr[4] ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{completed} of %{total} issues closed"
+msgstr ""
+
+msgid "%{completed} of %{total} weight completed"
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -1104,6 +1142,9 @@ msgstr ""
msgid "%{openedIssues} open, %{closedIssues} closed"
msgstr ""
+msgid "%{percentage}%% issues closed"
+msgstr ""
+
msgid "%{percentage}%% weight completed"
msgstr ""
@@ -1578,6 +1619,9 @@ msgstr[2] ""
msgstr[3] ""
msgstr[4] ""
+msgid "- of - issues closed"
+msgstr ""
+
msgid "- of - weight completed"
msgstr ""
@@ -1789,7 +1833,7 @@ msgstr ""
msgid "1000+"
msgstr ""
-msgid "192.168.0.0/24"
+msgid "192.168.0.0/24 or 2001:0DB8:1234::/48"
msgstr ""
msgid "1st contribution!"
@@ -2101,13 +2145,13 @@ msgstr ""
msgid "AWS Access Key"
msgstr ""
-msgid "AWS Access Key. Only required if not using role instance credentials"
+msgid "AWS Secret Access Key"
msgstr ""
-msgid "AWS Secret Access Key"
+msgid "AWS access key ID (Optional)"
msgstr ""
-msgid "AWS Secret Access Key. Only required if not using role instance credentials"
+msgid "AWS secret access key (Optional)"
msgstr ""
msgid "AWS service error: %{error}"
@@ -2167,9 +2211,6 @@ msgstr ""
msgid "Access granted"
msgstr ""
-msgid "Access key ID"
-msgstr ""
-
msgid "Access requests"
msgstr ""
@@ -2344,7 +2385,7 @@ msgstr ""
msgid "Activity"
msgstr ""
-msgid "Activity|An error occured while retrieving activity. Reload the page to try again."
+msgid "Activity|An error occurred while retrieving activity. Reload the page to try again."
msgstr ""
msgid "Add"
@@ -2383,6 +2424,9 @@ msgstr ""
msgid "Add a %{type}"
msgstr ""
+msgid "Add a GCP region"
+msgstr ""
+
msgid "Add a GPG key"
msgstr ""
@@ -2434,6 +2478,9 @@ msgstr ""
msgid "Add a numbered list"
msgstr ""
+msgid "Add a related epic"
+msgstr ""
+
msgid "Add a related issue"
msgstr ""
@@ -2548,6 +2595,9 @@ msgstr ""
msgid "Add or subtract spent time"
msgstr ""
+msgid "Add people"
+msgstr ""
+
msgid "Add previously merged commits"
msgstr ""
@@ -2614,6 +2664,9 @@ msgstr ""
msgid "Add webhook"
msgstr ""
+msgid "Add your team members and others to GitLab."
+msgstr ""
+
msgid "Add/remove"
msgstr ""
@@ -3436,12 +3489,6 @@ msgstr ""
msgid "AdvancedSearch|Reindex required"
msgstr ""
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. Permanently deleting this project will %{strongStart}immediately delete%{strongEnd} its repositories and %{strongStart}all related resources%{strongEnd}, including issues, merge requests etc."
-msgstr ""
-
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. You will lose this project's repository and %{strongStart}all related resources%{strongEnd}, including issues and merge requests."
-msgstr ""
-
msgid "After a successful password update you will be redirected to login screen."
msgstr ""
@@ -3472,6 +3519,9 @@ msgstr ""
msgid "Akismet helps prevent the creation of spam issues in public projects."
msgstr ""
+msgid "Alert"
+msgstr ""
+
msgid "AlertManagement|Acknowledged"
msgstr ""
@@ -3844,9 +3894,6 @@ msgstr ""
msgid "All environments"
msgstr ""
-msgid "All epics"
-msgstr ""
-
msgid "All groups and projects"
msgstr ""
@@ -4589,15 +4636,18 @@ msgstr ""
msgid "ApplicationSettings|Approve users in the pending approval status?"
msgstr ""
-msgid "ApplicationSettings|By making this change, you will automatically approve %d user with the pending approval status."
-msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users with the pending approval status."
+msgid "ApplicationSettings|Approve users who are pending approval?"
+msgstr ""
+
+msgid "ApplicationSettings|By making this change, you will automatically approve %d user who is pending approval."
+msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users who are pending approval."
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
msgstr[4] ""
-msgid "ApplicationSettings|By making this change, you will automatically approve all users in pending approval status."
+msgid "ApplicationSettings|By making this change, you will automatically approve all users who are pending approval."
msgstr ""
msgid "ApplicationSettings|Denied domains for sign-ups"
@@ -5018,10 +5068,10 @@ msgstr ""
msgid "Archiving the project will make it entirely read-only. It is hidden from the dashboard and doesn't show up in searches. %{strong_start}The repository cannot be committed to, and no issues, comments, or other entities can be created.%{strong_end} %{link_start}Learn more.%{link_end}"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to delete this project?"
+msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
+msgid "Are you absolutely sure?"
msgstr ""
msgid "Are you sure that you want to archive this project?"
@@ -5057,12 +5107,18 @@ msgstr ""
msgid "Are you sure you want to delete this SSH key?"
msgstr ""
+msgid "Are you sure you want to delete this comment?"
+msgstr ""
+
msgid "Are you sure you want to delete this deploy key?"
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 label?"
+msgstr ""
+
msgid "Are you sure you want to delete this pipeline schedule?"
msgstr ""
@@ -5078,9 +5134,6 @@ msgstr ""
msgid "Are you sure you want to discard your changes?"
msgstr ""
-msgid "Are you sure you want to erase this build?"
-msgstr ""
-
msgid "Are you sure you want to import %d repository?"
msgid_plural "Are you sure you want to import %d repositories?"
msgstr[0] ""
@@ -5131,6 +5184,9 @@ msgstr ""
msgid "Are you sure you want to remove this list?"
msgstr ""
+msgid "Are you sure you want to remove this nickname?"
+msgstr ""
+
msgid "Are you sure you want to reset the health check token?"
msgstr ""
@@ -5143,10 +5199,10 @@ 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?"
+msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
msgstr ""
-msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
+msgid "Are you sure you want to revoke this project access token? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to stop this environment?"
@@ -5293,9 +5349,6 @@ msgstr ""
msgid "Assigned to %{assignee_name}"
msgstr ""
-msgid "Assigned to %{name}"
-msgstr ""
-
msgid "Assigned to me"
msgstr ""
@@ -5366,6 +5419,9 @@ msgstr[4] ""
msgid "Attaching the file failed."
msgstr ""
+msgid "Attention"
+msgstr ""
+
msgid "Audit Events"
msgstr ""
@@ -5528,6 +5584,12 @@ msgstr ""
msgid "Authorized applications (%{size})"
msgstr ""
+msgid "AuthorizedApplication|Are you sure you want to revoke this application?"
+msgstr ""
+
+msgid "AuthorizedApplication|Revoke application"
+msgstr ""
+
msgid "Authors: %{authors}"
msgstr ""
@@ -6733,6 +6795,9 @@ msgstr ""
msgid "CICDAnalytics|Shared Runners Usage"
msgstr ""
+msgid "CICDAnalytics|Shared runner pipeline minute duration by month"
+msgstr ""
+
msgid "CICDAnalytics|Shared runner usage"
msgstr ""
@@ -6874,6 +6939,9 @@ msgstr ""
msgid "Can create groups:"
msgstr ""
+msgid "Can not delete primary training"
+msgstr ""
+
msgid "Can't apply as the source branch was deleted."
msgstr ""
@@ -7207,9 +7275,6 @@ msgstr ""
msgid "Changing any setting here requires an application restart"
msgstr ""
-msgid "Changing group URL can have unintended side effects."
-msgstr ""
-
msgid "Charts can't be displayed as the request for data has timed out. %{documentationLink}"
msgstr ""
@@ -7297,9 +7362,6 @@ msgstr ""
msgid "Checking branch availability..."
msgstr ""
-msgid "Checking group URL availability..."
-msgstr ""
-
msgid "Checking group path availability..."
msgstr ""
@@ -7799,6 +7861,9 @@ msgstr ""
msgid "Clear recent searches"
msgstr ""
+msgid "Clear repository checks"
+msgstr ""
+
msgid "Clear search"
msgstr ""
@@ -7931,9 +7996,6 @@ msgstr ""
msgid "Closed MRs"
msgstr ""
-msgid "Closed epics"
-msgstr ""
-
msgid "Closed issues"
msgstr ""
@@ -7970,13 +8032,13 @@ msgstr ""
msgid "Cluster level"
msgstr ""
-msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
+msgid "Cluster type must be specified for Stages::ClusterEndpointInserter"
msgstr ""
msgid "ClusterAgents|%{name} successfully deleted"
msgstr ""
-msgid "ClusterAgents|%{number} of %{total} Agents"
+msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
@@ -8018,6 +8080,15 @@ msgstr ""
msgid "ClusterAgents|Agent never connected to GitLab"
msgstr ""
+msgid "ClusterAgents|Agent version mismatch"
+msgstr ""
+
+msgid "ClusterAgents|Agent version mismatch and update"
+msgstr ""
+
+msgid "ClusterAgents|Agent version update required"
+msgstr ""
+
msgid "ClusterAgents|All"
msgstr ""
@@ -8042,7 +8113,7 @@ msgstr ""
msgid "ClusterAgents|Configuration"
msgstr ""
-msgid "ClusterAgents|Connect a cluster through the Agent"
+msgid "ClusterAgents|Connect a cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connect existing cluster"
@@ -8051,13 +8122,13 @@ msgstr ""
msgid "ClusterAgents|Connect with a certificate"
msgstr ""
-msgid "ClusterAgents|Connect with agent"
+msgid "ClusterAgents|Connect with an agent"
msgstr ""
msgid "ClusterAgents|Connect with the GitLab Agent"
msgstr ""
-msgid "ClusterAgents|Connect your cluster through the Agent"
+msgid "ClusterAgents|Connect your cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connected"
@@ -8117,7 +8188,10 @@ msgstr ""
msgid "ClusterAgents|How to register an agent?"
msgstr ""
-msgid "ClusterAgents|Install new Agent"
+msgid "ClusterAgents|How to update an agent?"
+msgstr ""
+
+msgid "ClusterAgents|Install a new agent"
msgstr ""
msgid "ClusterAgents|Last connected %{timeAgo}."
@@ -8144,7 +8218,7 @@ msgstr ""
msgid "ClusterAgents|Never connected"
msgstr ""
-msgid "ClusterAgents|No Agents"
+msgid "ClusterAgents|No agents"
msgstr ""
msgid "ClusterAgents|No clusters connected through cluster certificates"
@@ -8204,6 +8278,9 @@ msgstr ""
msgid "ClusterAgents|The agent has not been connected in a long time. There might be a connectivity issue. Last contact was %{timeAgo}."
msgstr ""
+msgid "ClusterAgents|The agent version do not match each other across your cluster's pods. This can happen when a new agent version was just deployed and Kubernetes is shutting down the old pods."
+msgstr ""
+
msgid "ClusterAgents|The recommended installation method includes the token. If you want to follow the advanced installation method provided in the docs, make sure you save the token value before you close this window."
msgstr ""
@@ -8254,6 +8331,9 @@ msgstr ""
msgid "ClusterAgents|You will need to create a token to connect to your agent"
msgstr ""
+msgid "ClusterAgents|Your agent version is out of sync with your GitLab version (v%{version}), which might cause compatibility problems. Update the agent installed on your cluster to the most recent version."
+msgstr ""
+
msgid "ClusterAgents|Your instance doesn't have the %{linkStart}GitLab Agent Server (KAS)%{linkEnd} set up. Ask a GitLab Administrator to install it."
msgstr ""
@@ -9130,9 +9210,6 @@ msgstr ""
msgid "Comma-separated list of email addresses."
msgstr ""
-msgid "Comma-separated list of users allowed to exceed the rate limit."
-msgstr ""
-
msgid "Comma-separated, e.g. '1.1.1.1, 2.2.2.0/24'"
msgstr ""
@@ -9462,6 +9539,12 @@ msgstr ""
msgid "Confidential"
msgstr ""
+msgid "Confidential issue"
+msgstr ""
+
+msgid "Confidential note"
+msgstr ""
+
msgid "Confidentiality"
msgstr ""
@@ -9495,6 +9578,9 @@ msgstr ""
msgid "Configure Dependency Scanning in `.gitlab-ci.yml`, creating this file if it does not already exist"
msgstr ""
+msgid "Configure GitLab"
+msgstr ""
+
msgid "Configure GitLab runners to start using the Web Terminal. %{helpStart}Learn more.%{helpEnd}"
msgstr ""
@@ -9543,6 +9629,15 @@ msgstr ""
msgid "Configure pipelines to deploy web apps, backend services, APIs and static resources to Google Cloud"
msgstr ""
+msgid "Configure region"
+msgstr ""
+
+msgid "Configure region for environment"
+msgstr ""
+
+msgid "Configure regions"
+msgstr ""
+
msgid "Configure repository mirroring."
msgstr ""
@@ -9576,6 +9671,9 @@ msgstr ""
msgid "Configure which lists are shown for anyone who visits this board"
msgstr ""
+msgid "Configure your environments to be deployed to specific geographical regions"
+msgstr ""
+
msgid "Confirm"
msgstr ""
@@ -10287,10 +10385,10 @@ msgstr ""
msgid "CorpusManagement|Actions"
msgstr ""
-msgid "CorpusManagement|Corpus are used in fuzz testing as mutation source to Improve future testing."
+msgid "CorpusManagement|Corpus file"
msgstr ""
-msgid "CorpusManagement|Corpus file"
+msgid "CorpusManagement|Corpus files are used in coverage-guided fuzz testing as seed inputs to improve testing."
msgstr ""
msgid "CorpusManagement|Corpus files must be in *.zip format. Maximum 5 GB"
@@ -10344,6 +10442,9 @@ msgstr ""
msgid "Could not apply %{name} command."
msgstr ""
+msgid "Could not apply %{name} command. %{message}."
+msgstr ""
+
msgid "Could not authorize chat nickname. Try again!"
msgstr ""
@@ -10494,6 +10595,9 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
+msgid "Create a group"
+msgstr ""
+
msgid "Create a merge request"
msgstr ""
@@ -10518,6 +10622,9 @@ msgstr ""
msgid "Create a personal access token on your account to pull or push via %{protocol}."
msgstr ""
+msgid "Create a project"
+msgstr ""
+
msgid "Create an account using:"
msgstr ""
@@ -10881,6 +10988,9 @@ msgstr ""
msgid "Creation date"
msgstr ""
+msgid "Creator"
+msgstr ""
+
msgid "Credentials"
msgstr ""
@@ -10893,9 +11003,15 @@ msgstr ""
msgid "CredentialsInventory|Personal Access Tokens"
msgstr ""
+msgid "CredentialsInventory|Project Access Tokens"
+msgstr ""
+
msgid "CredentialsInventory|SSH Keys"
msgstr ""
+msgid "Credit card required to be on file in order to create a pipeline"
+msgstr ""
+
msgid "Credit card:"
msgstr ""
@@ -11079,9 +11195,6 @@ msgstr ""
msgid "Customer relations"
msgstr ""
-msgid "Customizable by an administrator."
-msgstr ""
-
msgid "Customizable by owners."
msgstr ""
@@ -11211,30 +11324,18 @@ msgstr ""
msgid "CycleAnalytics|%{selectedLabelsCount} selected (%{maxLabels} max)"
msgstr ""
-msgid "CycleAnalytics|%{stageCount} stages selected"
-msgstr ""
-
-msgid "CycleAnalytics|All stages"
-msgstr ""
-
-msgid "CycleAnalytics|Average days to completion"
+msgid "CycleAnalytics|Average time to completion"
msgstr ""
msgid "CycleAnalytics|Date"
msgstr ""
-msgid "CycleAnalytics|Days to completion"
-msgstr ""
-
msgid "CycleAnalytics|Display chart filters"
msgstr ""
msgid "CycleAnalytics|Lead Time for Changes"
msgstr ""
-msgid "CycleAnalytics|No stages selected"
-msgstr ""
-
msgid "CycleAnalytics|Number of tasks"
msgstr ""
@@ -11269,18 +11370,30 @@ msgstr ""
msgid "CycleAnalytics|Showing data for group '%{groupName}' from %{createdAfter} to %{createdBefore}"
msgstr ""
-msgid "CycleAnalytics|Stages"
+msgid "CycleAnalytics|Stage time: %{title}"
msgstr ""
msgid "CycleAnalytics|Tasks by type"
msgstr ""
-msgid "CycleAnalytics|The average time spent in the selected stage for the items that were completed on each date. Data limited to the last 500 items."
+msgid "CycleAnalytics|The average time items spent in this stage. Data limited to items completed within this date range."
msgstr ""
msgid "CycleAnalytics|The given date range is larger than 180 days"
msgstr ""
+msgid "CycleAnalytics|The total time items spent across each value stream stage. Data limited to items completed within this date range."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Stage time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Total time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|Total time"
+msgstr ""
+
msgid "CycleAnalytics|Type of work"
msgstr ""
@@ -11293,9 +11406,6 @@ msgstr ""
msgid "CycleAnalytics|project dropdown filter"
msgstr ""
-msgid "CycleAnalytics|stage dropdown"
-msgstr ""
-
msgid "DAG visualization requires at least 3 dependent jobs."
msgstr ""
@@ -11395,10 +11505,16 @@ msgstr ""
msgid "DastProfiles|AJAX spider"
msgstr ""
+msgid "DastProfiles|API"
+msgstr ""
+
+msgid "DastProfiles|API endpoint URL"
+msgstr ""
+
msgid "DastProfiles|Active"
msgstr ""
-msgid "DastProfiles|Additional request headers (Optional)"
+msgid "DastProfiles|Additional request headers (optional)"
msgstr ""
msgid "DastProfiles|Are you sure you want to delete this profile?"
@@ -11413,6 +11529,9 @@ msgstr ""
msgid "DastProfiles|Branch missing"
msgstr ""
+msgid "DastProfiles|Choose a scan method"
+msgstr ""
+
msgid "DastProfiles|Could not create the scanner profile. Please try again."
msgstr ""
@@ -11482,7 +11601,13 @@ msgstr ""
msgid "DastProfiles|Excluded URLs"
msgstr ""
-msgid "DastProfiles|Excluded URLs (Optional)"
+msgid "DastProfiles|Excluded URLs (optional)"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths (optional)"
msgstr ""
msgid "DastProfiles|Hide debug messages"
@@ -11539,9 +11664,6 @@ msgstr ""
msgid "DastProfiles|Request headers"
msgstr ""
-msgid "DastProfiles|Rest API"
-msgstr ""
-
msgid "DastProfiles|Run the AJAX spider, in addition to the traditional spider, to crawl the target site."
msgstr ""
@@ -11551,6 +11673,9 @@ msgstr ""
msgid "DastProfiles|Save profile"
msgstr ""
+msgid "DastProfiles|Scan method"
+msgstr ""
+
msgid "DastProfiles|Scan mode"
msgstr ""
@@ -11629,12 +11754,24 @@ msgstr ""
msgid "DastProfiles|Website"
msgstr ""
+msgid "DastProfiles|What does each method do?"
+msgstr ""
+
msgid "DastProfiles|You can either choose a passive scan or validate the target site from the site profile management page. %{docsLinkStart}Learn more about site validation.%{docsLinkEnd}"
msgstr ""
msgid "DastProfiles|You cannot run an active scan against an unvalidated site."
msgstr ""
+msgid "DastProfiles|folder/dast_example.har or https://example.com/dast_example.har"
+msgstr ""
+
+msgid "DastProfiles|folder/example.postman_collection.json or https://example.com/"
+msgstr ""
+
+msgid "DastProfiles|folder/openapi.json or https://example.com/openapi.json"
+msgstr ""
+
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
@@ -11745,6 +11882,9 @@ msgstr ""
msgid "DatadogIntegration|API URL"
msgstr ""
+msgid "DatadogIntegration|Custom tags in Datadog. Enter one tag per line in the %{codeOpen}key:value%{codeClose} format. %{linkOpen}How do I use tags?%{linkClose}"
+msgstr ""
+
msgid "DatadogIntegration|Environment"
msgstr ""
@@ -11763,12 +11903,18 @@ msgstr ""
msgid "DatadogIntegration|Tag all data from this GitLab instance in Datadog. Useful when managing several self-managed deployments."
msgstr ""
+msgid "DatadogIntegration|Tags"
+msgstr ""
+
msgid "DatadogIntegration|The Datadog site to send data to. To send data to the EU site, use %{codeOpen}datadoghq.eu%{codeClose}."
msgstr ""
msgid "DatadogIntegration|Trace your GitLab pipelines with Datadog."
msgstr ""
+msgid "DatadogIntegration|have an invalid format"
+msgstr ""
+
msgid "Datasource name not found"
msgstr ""
@@ -11778,9 +11924,6 @@ msgstr ""
msgid "Date merged"
msgstr ""
-msgid "Date picker"
-msgstr ""
-
msgid "Date range"
msgstr ""
@@ -11934,9 +12077,6 @@ msgstr ""
msgid "Definition"
msgstr ""
-msgid "Delayed Project Deletion (%{adjourned_deletion})"
-msgstr ""
-
msgid "DelayedJobs|Are you sure you want to run %{jobName} immediately? Otherwise this job will run automatically after its timer finishes."
msgstr ""
@@ -12015,10 +12155,10 @@ msgstr ""
msgid "Delete pipeline"
msgstr ""
-msgid "Delete project"
+msgid "Delete pipeline schedule"
msgstr ""
-msgid "Delete project. Are you ABSOLUTELY SURE?"
+msgid "Delete project"
msgstr ""
msgid "Delete row"
@@ -12048,6 +12188,9 @@ msgstr ""
msgid "Delete this epic and all descendants?"
msgstr ""
+msgid "Delete this project"
+msgstr ""
+
msgid "Delete user list"
msgstr ""
@@ -12324,6 +12467,12 @@ msgstr ""
msgid "Deploy to..."
msgstr ""
+msgid "DeployBoards|To see deployment progress for your environments, make sure you are deploying to %{codeStart}$KUBE_NAMESPACE%{codeEnd} and annotating with %{codeStart}app.gitlab.com/app=$CI_PROJECT_PATH_SLUG%{codeEnd} and %{codeStart}app.gitlab.com/env=$CI_ENVIRONMENT_SLUG%{codeEnd}."
+msgstr ""
+
+msgid "DeployBoard|Kubernetes Pods"
+msgstr ""
+
msgid "DeployFreeze|Add a freeze period to prevent unintended releases during a period of time for a given environment. You must update the deployment jobs in %{filename} according to the deploy freezes added here. %{freeze_period_link_start}Learn more.%{freeze_period_link_end}"
msgstr ""
@@ -12408,9 +12557,6 @@ msgstr ""
msgid "DeployTokens|Active Deploy Tokens (%{active_tokens})"
msgstr ""
-msgid "DeployTokens|Allows read and write access to registry images."
-msgstr ""
-
msgid "DeployTokens|Allows read and write access to the package registry."
msgstr ""
@@ -12423,6 +12569,9 @@ msgstr ""
msgid "DeployTokens|Allows read-only access to the repository."
msgstr ""
+msgid "DeployTokens|Allows write access to registry images."
+msgstr ""
+
msgid "DeployTokens|Copy deploy token"
msgstr ""
@@ -12516,12 +12665,57 @@ msgstr ""
msgid "Deploying to AWS is easy with GitLab"
msgstr ""
+msgid "Deployment"
+msgstr ""
+
msgid "Deployment Frequency"
msgstr ""
+msgid "Deployment Target|Project deployment target (optional)"
+msgstr ""
+
+msgid "Deployment Target|Select the deployment target"
+msgstr ""
+
msgid "Deployment frequency"
msgstr ""
+msgid "DeploymentTarget|GitLab Pages"
+msgstr ""
+
+msgid "DeploymentTarget|Heroku"
+msgstr ""
+
+msgid "DeploymentTarget|Infrastructure provider (Terraform, Cloudformation, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Kubernetes (GKE, EKS, OpenShift, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Managed container runtime (Fargate, Cloud Run, DigitalOcean App)"
+msgstr ""
+
+msgid "DeploymentTarget|Mobile app store"
+msgstr ""
+
+msgid "DeploymentTarget|No deployment planned"
+msgstr ""
+
+msgid "DeploymentTarget|Other hosting service"
+msgstr ""
+
+msgid "DeploymentTarget|Registry (package or container)"
+msgstr ""
+
+msgid "DeploymentTarget|Self-managed container runtime (Podman, Docker Swarm, Docker Compose)"
+msgstr ""
+
+msgid "DeploymentTarget|Serverless backend (Lambda, Cloud functions)"
+msgstr ""
+
+msgid "DeploymentTarget|Virtual machine (for example, EC2)"
+msgstr ""
+
msgid "Deployments"
msgstr ""
@@ -12563,6 +12757,9 @@ msgstr ""
msgid "Deployment|This deployment was created using the API"
msgstr ""
+msgid "Deployment|Triggerer"
+msgstr ""
+
msgid "Deployment|Waiting"
msgstr ""
@@ -12590,6 +12787,18 @@ msgstr ""
msgid "Deprecated API rate limits"
msgstr ""
+msgid "Deprecations|Feature deprecation and removal"
+msgstr ""
+
+msgid "Deprecations|For information on a possible replacement %{epicStart} learn more about Opstrace %{epicEnd}."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7 and are %{epicStart} scheduled for removal %{epicEnd} in GitLab 15.0."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7, and are %{removal_link_start} scheduled for removal %{link_end} in GitLab 15.0. For information on a possible replacement, %{opstrace_link_start} learn more about Opstrace %{link_end}."
+msgstr ""
+
msgid "Deprioritize label"
msgstr ""
@@ -12838,10 +13047,10 @@ msgstr ""
msgid "DevopsAdoption|At least one deploy"
msgstr ""
-msgid "DevopsAdoption|At least one issue opened"
+msgid "DevopsAdoption|At least one issue created"
msgstr ""
-msgid "DevopsAdoption|At least one merge request opened"
+msgid "DevopsAdoption|At least one merge request created"
msgstr ""
msgid "DevopsAdoption|At least one pipeline successfully run"
@@ -13051,6 +13260,9 @@ msgstr ""
msgid "Direct member"
msgstr ""
+msgid "Direct members"
+msgstr ""
+
msgid "Direct non-authenticated users to this page."
msgstr ""
@@ -13170,6 +13382,9 @@ msgstr[2] ""
msgstr[3] ""
msgstr[4] ""
+msgid "Dismiss Alert"
+msgstr ""
+
msgid "Dismiss merge request promotion"
msgstr ""
@@ -13197,9 +13412,15 @@ msgstr ""
msgid "Display alerts from all configured monitoring tools."
msgstr ""
+msgid "Display milestones"
+msgstr ""
+
msgid "Display name"
msgstr ""
+msgid "Display progress of child issues"
+msgstr ""
+
msgid "Display rendered file"
msgstr ""
@@ -13305,6 +13526,9 @@ msgstr ""
msgid "Download image"
msgstr ""
+msgid "Download payload"
+msgstr ""
+
msgid "Download raw data (.csv)"
msgstr ""
@@ -13482,6 +13706,9 @@ msgstr ""
msgid "Edit in Web IDE"
msgstr ""
+msgid "Edit in pipeline editor"
+msgstr ""
+
msgid "Edit in single-file editor"
msgstr ""
@@ -13524,6 +13751,9 @@ msgstr ""
msgid "Edit your most recent comment in a thread (from an empty textarea)"
msgstr ""
+msgid "Edit, lint, and visualize your pipeline."
+msgstr ""
+
msgid "Edited"
msgstr ""
@@ -13965,6 +14195,9 @@ msgstr ""
msgid "Enforce two-factor authentication for all user sign-ins."
msgstr ""
+msgid "Enhance security by storing service account keys in secret managers - learn more about %{docLinkStart}secret management with GitLab%{docLinkEnd}"
+msgstr ""
+
msgid "Ensure connectivity is available from the GitLab server to the Prometheus server"
msgstr ""
@@ -14025,6 +14258,9 @@ 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 following to confirm:"
+msgstr ""
+
msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
@@ -14558,9 +14794,6 @@ 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 ""
@@ -14696,6 +14929,9 @@ msgstr ""
msgid "Errors:"
msgstr ""
+msgid "Escalate this incident"
+msgstr ""
+
msgid "Escalation Policies"
msgstr ""
@@ -14708,6 +14944,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy"
+msgstr ""
+
msgid "Escalation policy:"
msgstr ""
@@ -14962,6 +15201,9 @@ msgstr ""
msgid "Existing sign in methods may be removed"
msgstr ""
+msgid "Exit."
+msgstr ""
+
msgid "Expand"
msgstr ""
@@ -15058,6 +15300,9 @@ msgstr ""
msgid "Explore public groups"
msgstr ""
+msgid "Explore public projects"
+msgstr ""
+
msgid "Explore snippets"
msgstr ""
@@ -15222,7 +15467,7 @@ msgstr[2] ""
msgstr[3] ""
msgstr[4] ""
-msgid "Failed to assign a reviewer because no user was found."
+msgid "Failed to assign a reviewer because no user was specified."
msgstr ""
msgid "Failed to assign a user because no user was found."
@@ -15288,10 +15533,10 @@ msgstr ""
msgid "Failed to find import label for Jira import."
msgstr ""
-msgid "Failed to generate export, please try again later."
+msgid "Failed to find users for %{missing}"
msgstr ""
-msgid "Failed to generate report, please try again after sometime"
+msgid "Failed to generate export, please try again later."
msgstr ""
msgid "Failed to get ref."
@@ -15390,6 +15635,9 @@ msgstr ""
msgid "Failed to remove a to-do item for the design."
msgstr ""
+msgid "Failed to remove attention because no user was found."
+msgstr ""
+
msgid "Failed to remove mirror."
msgstr ""
@@ -15402,6 +15650,9 @@ msgstr ""
msgid "Failed to remove user key."
msgstr ""
+msgid "Failed to request attention because no user was found."
+msgstr ""
+
msgid "Failed to reset key. Please try again."
msgstr ""
@@ -15483,6 +15734,9 @@ msgstr ""
msgid "Feature Flags"
msgstr ""
+msgid "Feature deprecation and removal"
+msgstr ""
+
msgid "Feature flag status"
msgstr ""
@@ -15983,7 +16237,7 @@ msgstr ""
msgid "For each job, re-use the project workspace. If the workspace doesn't exist, use %{code_open}git clone%{code_close}."
msgstr ""
-msgid "For example, the application using the token or the purpose of the token."
+msgid "For example, the application using the token or the purpose of the token. Do not give sensitive information for the name of the token, as it will be visible to all %{resource_type} members."
msgstr ""
msgid "For files larger than this limit, only index the file name. The file content is neither indexed nor searchable."
@@ -16067,9 +16321,6 @@ msgstr ""
msgid "ForkProject|Select a namespace"
msgstr ""
-msgid "ForkProject|Select a namespace to fork the project"
-msgstr ""
-
msgid "ForkProject|The project can be accessed by any logged in user."
msgstr ""
@@ -16166,6 +16417,9 @@ msgstr ""
msgid "Full name"
msgstr ""
+msgid "GCP region configured"
+msgstr ""
+
msgid "GPG Key ID:"
msgstr ""
@@ -16346,6 +16600,9 @@ msgstr ""
msgid "Geo|Failed"
msgstr ""
+msgid "Geo|Filter Geo sites"
+msgstr ""
+
msgid "Geo|Filter by name"
msgstr ""
@@ -16757,6 +17014,12 @@ msgstr ""
msgid "GitLab Issue"
msgstr ""
+msgid "GitLab KAS"
+msgstr ""
+
+msgid "GitLab Memberships CSV Export"
+msgstr ""
+
msgid "GitLab Pages"
msgstr ""
@@ -16805,6 +17068,9 @@ 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 free to use. Many features for larger teams are part of our %{link_start}paid products%{link_end}. You can try Ultimate for free without any obligation or payment details."
+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 ""
@@ -16931,7 +17197,7 @@ msgstr ""
msgid "GitLabPages|When enabled, all attempts to visit your website through HTTP are automatically redirected to HTTPS using a response with status code 301. Requires a valid certificate for all domains. %{docs_link_start}Learn more.%{link_end}"
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. %{docs_link_start}Learn more.%{link_end}"
+msgid "GitLabPages|When using Pages under the general domain of a GitLab instance (%{pages_host}), you cannot use HTTPS with subdomains of subdomains. If your namespace or groupname contains a dot, it does not work. This is a limitation of the HTTP Over TLS protocol. HTTP pages work if you don't redirect HTTP to HTTPS. %{docs_link_start}Learn more.%{link_end}"
msgstr ""
msgid "GitLabPages|With GitLab Pages you can host your static website directly from your GitLab repository. %{docs_link_start}Learn more.%{link_end}"
@@ -17108,9 +17374,6 @@ msgstr ""
msgid "Go to find file"
msgstr ""
-msgid "Go to fork"
-msgstr ""
-
msgid "Go to issue boards"
msgstr ""
@@ -17318,9 +17581,6 @@ msgstr ""
msgid "Group Hooks"
msgstr ""
-msgid "Group ID"
-msgstr ""
-
msgid "Group Owner must have signed in with SAML before enabling Group Managed Accounts"
msgstr ""
@@ -17348,9 +17608,6 @@ msgstr ""
msgid "Group by"
msgstr ""
-msgid "Group description"
-msgstr ""
-
msgid "Group description (optional)"
msgstr ""
@@ -17465,7 +17722,7 @@ msgstr ""
msgid "Group: %{name}"
msgstr ""
-msgid "GroupActivityMetrics|Issues opened"
+msgid "GroupActivityMetrics|Issues created"
msgstr ""
msgid "GroupActivityMetrics|Last 90 days"
@@ -17474,7 +17731,7 @@ msgstr ""
msgid "GroupActivityMetrics|Members added"
msgstr ""
-msgid "GroupActivityMetrics|Merge Requests opened"
+msgid "GroupActivityMetrics|Merge Requests created"
msgstr ""
msgid "GroupActivityMetrics|Recent activity"
@@ -17765,6 +18022,9 @@ msgstr ""
msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
+msgid "GroupSettings|Choose a group path that does not start with a dash or end with a period. It can also contain alphanumeric characters and underscores."
+msgstr ""
+
msgid "GroupSettings|Compliance frameworks"
msgstr ""
@@ -17798,7 +18058,7 @@ msgstr ""
msgid "GroupSettings|If not specified at the group or instance level, the default is %{default_initial_branch_name}. Does not affect existing repositories."
msgstr ""
-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."
+msgid "GroupSettings|If the parent group's visibility is lower than the group's current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility."
msgstr ""
msgid "GroupSettings|New runners registration token has been generated!"
@@ -17915,7 +18175,10 @@ msgstr ""
msgid "Groups and projects"
msgstr ""
-msgid "Groups and subgroups"
+msgid "Groups are a great way to organize projects and people."
+msgstr ""
+
+msgid "Groups are the best way to manage projects and members."
msgstr ""
msgid "Groups to synchronize"
@@ -18026,13 +18289,16 @@ msgstr ""
msgid "GroupsTree|Are you sure you want to leave the \"%{fullName}\" group?"
msgstr ""
-msgid "GroupsTree|Edit group"
+msgid "GroupsTree|Delete"
+msgstr ""
+
+msgid "GroupsTree|Edit"
msgstr ""
msgid "GroupsTree|Failed to leave the group. Please make sure you are not the only owner."
msgstr ""
-msgid "GroupsTree|Leave this group"
+msgid "GroupsTree|Leave group"
msgstr ""
msgid "GroupsTree|Loading groups"
@@ -18044,9 +18310,57 @@ msgstr ""
msgid "GroupsTree|No groups or projects matched your search"
msgstr ""
+msgid "GroupsTree|Options"
+msgstr ""
+
msgid "GroupsTree|Search by name"
msgstr ""
+msgid "Groups|Avatar will be removed. Are you sure?"
+msgstr ""
+
+msgid "Groups|Changing group URL can have unintended side effects."
+msgstr ""
+
+msgid "Groups|Checking group URL availability..."
+msgstr ""
+
+msgid "Groups|Enter a descriptive name for your group."
+msgstr ""
+
+msgid "Groups|Group ID"
+msgstr ""
+
+msgid "Groups|Group URL"
+msgstr ""
+
+msgid "Groups|Group avatar"
+msgstr ""
+
+msgid "Groups|Group description (optional)"
+msgstr ""
+
+msgid "Groups|Group name"
+msgstr ""
+
+msgid "Groups|Group path is available."
+msgstr ""
+
+msgid "Groups|Group path is unavailable. Path has been replaced with a suggested available path."
+msgstr ""
+
+msgid "Groups|Learn more"
+msgstr ""
+
+msgid "Groups|Must start with letter, digit, emoji, or underscore. Can also contain periods, dashes, spaces, and parentheses."
+msgstr ""
+
+msgid "Groups|Remove avatar"
+msgstr ""
+
+msgid "Groups|Save changes"
+msgstr ""
+
msgid "Guideline"
msgstr ""
@@ -18056,6 +18370,9 @@ msgstr ""
msgid "HAR file path or URL"
msgstr ""
+msgid "HTTP Archive (HAR)"
+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 ""
@@ -18462,6 +18779,9 @@ msgstr ""
msgid "INFO: Your SSH key is expiring soon. Please generate a new key."
msgstr ""
+msgid "IP"
+msgstr ""
+
msgid "IP Address"
msgstr ""
@@ -18498,6 +18818,9 @@ msgstr ""
msgid "IdentityVerification|Verify your identity"
msgstr ""
+msgid "IdentityVerification|You can always verify your account at a later time to create a group."
+msgstr ""
+
msgid "If any indexed field exceeds this limit, it is truncated to this number of characters. The rest of the content is neither indexed nor searchable. This does not apply to repository and wiki indexing. For unlimited characters, set this to 0."
msgstr ""
@@ -18555,6 +18878,9 @@ msgstr ""
msgid "If you add %{codeStart}needs%{codeEnd} to jobs in your pipeline you'll be able to view the %{codeStart}needs%{codeEnd} relationships between jobs in this tab as a %{linkStart}Directed Acyclic Graph (DAG)%{linkEnd}."
msgstr ""
+msgid "If you are added to a project, it will be displayed here."
+msgstr ""
+
msgid "If you did not initiate these sign-in attempts, please reach out to your administrator or enable two-factor authentication (2FA) on your account."
msgstr ""
@@ -18870,12 +19196,24 @@ msgstr ""
msgid "InProductMarketing|3 ways to dive into GitLab CI/CD"
msgstr ""
+msgid "InProductMarketing|A single application eliminates complex integrations, data chokepoints, and toolchain maintenance, resulting in greater productivity and lower cost."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features, build more efficiently, strengthen security and compliance."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features."
+msgstr ""
+
msgid "InProductMarketing|Actually, GitLab makes the team work (better)"
msgstr ""
msgid "InProductMarketing|And finally %{deploy_link} a Python application."
msgstr ""
+msgid "InProductMarketing|And many more..."
+msgstr ""
+
msgid "InProductMarketing|Are your runners ready?"
msgstr ""
@@ -18894,15 +19232,33 @@ msgstr ""
msgid "InProductMarketing|Blog"
msgstr ""
+msgid "InProductMarketing|Break down silos to coordinate seamlessly across development, operations, and security with a consistent experience across the development lifecycle."
+msgstr ""
+
+msgid "InProductMarketing|Burn up/down charts"
+msgstr ""
+
msgid "InProductMarketing|By enabling code owners and required merge approvals the right person will review the right MR. This is a win-win: cleaner code and a more efficient review process."
msgstr ""
msgid "InProductMarketing|Click on the number below that corresponds with your answer — 1 being very difficult, 5 being very easy."
msgstr ""
+msgid "InProductMarketing|Code owners"
+msgstr ""
+
msgid "InProductMarketing|Code owners and required merge approvals are part of the paid tiers of GitLab. You can start a free 30-day trial of GitLab Ultimate and enable these features in less than 5 minutes with no credit card required."
msgstr ""
+msgid "InProductMarketing|Code review analytics"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration across stages in GitLab"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration made easy"
+msgstr ""
+
msgid "InProductMarketing|Create a custom CI runner with just a few clicks"
msgstr ""
@@ -18912,12 +19268,21 @@ msgstr ""
msgid "InProductMarketing|Create a project in GitLab in 5 minutes"
msgstr ""
+msgid "InProductMarketing|Create well-defined workflows by using scoped labels on issues, merge requests, and epics. Labels with the same scope cannot be used together, which prevents conflicts."
+msgstr ""
+
msgid "InProductMarketing|Create your first project!"
msgstr ""
+msgid "InProductMarketing|Define who owns specific files or directories, so the right reviewers are suggested when a merge request introduces changes to those files."
+msgstr ""
+
msgid "InProductMarketing|Deliver Better Products Faster"
msgstr ""
+msgid "InProductMarketing|Dependency scanning"
+msgstr ""
+
msgid "InProductMarketing|Did you know teams that use GitLab are far more efficient?"
msgstr ""
@@ -18927,15 +19292,27 @@ msgstr ""
msgid "InProductMarketing|Dig in and create a project and a repo"
msgstr ""
+msgid "InProductMarketing|Discover Premium & Ultimate"
+msgstr ""
+
+msgid "InProductMarketing|Discover Premium & Ultimate."
+msgstr ""
+
msgid "InProductMarketing|Do you have a minute?"
msgstr ""
msgid "InProductMarketing|Do you have a teammate who would be perfect for this task?"
msgstr ""
+msgid "InProductMarketing|Dynamic application security testing"
+msgstr ""
+
msgid "InProductMarketing|Easy"
msgstr ""
+msgid "InProductMarketing|Epics"
+msgstr ""
+
msgid "InProductMarketing|Expand your DevOps journey with a free GitLab trial"
msgstr ""
@@ -18957,9 +19334,15 @@ msgstr ""
msgid "InProductMarketing|Feel the need for speed?"
msgstr ""
+msgid "InProductMarketing|Find and fix bottlenecks in your code review process by understanding how long open merge requests have been in review."
+msgstr ""
+
msgid "InProductMarketing|Find out how your teams are really doing"
msgstr ""
+msgid "InProductMarketing|Find out if your external libraries are safe. Run dependency scanning jobs that check for known vulnerabilities in your external libraries."
+msgstr ""
+
msgid "InProductMarketing|Follow our steps"
msgstr ""
@@ -18996,6 +19379,9 @@ msgstr ""
msgid "InProductMarketing|GitLab is better with teammates to help out!"
msgstr ""
+msgid "InProductMarketing|GitLab is infrastructure agnostic (supporting GCP, AWS, Azure, OpenShift, VMWare, On Prem, Bare Metal, and more), offering a consistent workflow experience – irrespective of the environment."
+msgstr ""
+
msgid "InProductMarketing|GitLab provides static application security testing (SAST), dynamic application security testing (DAST), container scanning, and dependency scanning to help you deliver secure applications along with license compliance."
msgstr ""
@@ -19086,21 +19472,36 @@ msgstr ""
msgid "InProductMarketing|It's also possible to simply %{external_repo_link} in order to take advantage of GitLab's CI/CD."
msgstr ""
+msgid "InProductMarketing|Keep your code quality high by defining who should approve merge requests and how many approvals are required."
+msgstr ""
+
msgid "InProductMarketing|Launch GitLab CI/CD in 20 minutes or less"
msgstr ""
+msgid "InProductMarketing|Lower cost of development"
+msgstr ""
+
+msgid "InProductMarketing|Make it easier to collaborate on high-level ideas by grouping related issues in an epic."
+msgstr ""
+
msgid "InProductMarketing|Making the switch? It's easier than you think to import your projects into GitLab. Move %{github_link}, or import something %{bitbucket_link}."
msgstr ""
msgid "InProductMarketing|Master the art of importing!"
msgstr ""
+msgid "InProductMarketing|Merge request approval rule"
+msgstr ""
+
msgid "InProductMarketing|Move on to easily creating a Pages website %{ci_template_link}"
msgstr ""
msgid "InProductMarketing|Multiple owners, confusing workstreams? We've got you covered"
msgstr ""
+msgid "InProductMarketing|Multiple required approvers"
+msgstr ""
+
msgid "InProductMarketing|Need an alternative to importing?"
msgstr ""
@@ -19113,18 +19514,33 @@ msgstr ""
msgid "InProductMarketing|Our tool brings all the things together"
msgstr ""
+msgid "InProductMarketing|Protect your web application by using DAST to examine for vulnerabilities in deployed environments."
+msgstr ""
+
msgid "InProductMarketing|Rapid development, simplified"
msgstr ""
msgid "InProductMarketing|Reduce Security & Compliance Risk"
msgstr ""
+msgid "InProductMarketing|Require multiple approvers on a merge request, so you know it's in good shape before it's merged."
+msgstr ""
+
+msgid "InProductMarketing|Roadmaps"
+msgstr ""
+
+msgid "InProductMarketing|Scoped labels"
+msgstr ""
+
msgid "InProductMarketing|Security that's integrated into your development lifecycle"
msgstr ""
msgid "InProductMarketing|Sometimes you're not ready to make a full transition to a new tool. If you're not ready to fully commit, %{mirroring_link} gives you a safe way to try out GitLab in parallel with your current tool."
msgstr ""
+msgid "InProductMarketing|Speed. Efficiency. Trust."
+msgstr ""
+
msgid "InProductMarketing|Spin up an autoscaling runner in GitLab"
msgstr ""
@@ -19134,6 +19550,9 @@ msgstr ""
msgid "InProductMarketing|Start a Self-Managed trial"
msgstr ""
+msgid "InProductMarketing|Start a free trial"
+msgstr ""
+
msgid "InProductMarketing|Start a free trial of GitLab Ultimate – no credit card required"
msgstr ""
@@ -19200,6 +19619,9 @@ msgstr ""
msgid "InProductMarketing|To understand and get the most out of GitLab, start at the beginning and %{project_link}. In GitLab, repositories are part of a project, so after you've created your project you can go ahead and %{repo_link}."
msgstr ""
+msgid "InProductMarketing|Track completed issues in a chart, so you can see how a milestone is progressing at a glance."
+msgstr ""
+
msgid "InProductMarketing|Try GitLab Ultimate for free"
msgstr ""
@@ -19236,6 +19658,9 @@ msgstr ""
msgid "InProductMarketing|Very easy"
msgstr ""
+msgid "InProductMarketing|Visualize your epics and milestones in a timeline."
+msgstr ""
+
msgid "InProductMarketing|Want to host GitLab on your servers?"
msgstr ""
@@ -19257,6 +19682,9 @@ msgstr ""
msgid "InProductMarketing|YouTube"
msgstr ""
+msgid "InProductMarketing|Your software, deployed your way"
+msgstr ""
+
msgid "InProductMarketing|Your teams can be more efficient"
msgstr ""
@@ -19377,9 +19805,18 @@ msgstr ""
msgid "IncidentManagement|No incidents to display."
msgstr ""
+msgid "IncidentManagement|None"
+msgstr ""
+
msgid "IncidentManagement|Open"
msgstr ""
+msgid "IncidentManagement|Page your team with escalation policies"
+msgstr ""
+
+msgid "IncidentManagement|Paged"
+msgstr ""
+
msgid "IncidentManagement|Published"
msgstr ""
@@ -19389,6 +19826,9 @@ msgstr ""
msgid "IncidentManagement|Severity"
msgstr ""
+msgid "IncidentManagement|Status"
+msgstr ""
+
msgid "IncidentManagement|There are no closed incidents"
msgstr ""
@@ -19407,6 +19847,9 @@ msgstr ""
msgid "IncidentManagement|Unpublished"
msgstr ""
+msgid "IncidentManagement|Use escalation policies to automatically page your team when incidents are created."
+msgstr ""
+
msgid "IncidentSettings|Activate \"time to SLA\" countdown timer"
msgstr ""
@@ -19452,7 +19895,10 @@ msgstr ""
msgid "Incidents"
msgstr ""
-msgid "Incidents|Add a URL"
+msgid "Incidents|Add image details"
+msgstr ""
+
+msgid "Incidents|Add text or a link to display with your image. If you don't add either, the file name displays instead."
msgstr ""
msgid "Incidents|Drop or %{linkStart}upload%{linkEnd} a metric screenshot to attach it to the incident"
@@ -19467,10 +19913,10 @@ msgstr ""
msgid "Incidents|There was an issue loading metric images."
msgstr ""
-msgid "Incidents|There was an issue uploading your image."
+msgid "Incidents|There was an issue updating your image."
msgstr ""
-msgid "Incidents|You can optionally add a URL to link users to the original graph."
+msgid "Incidents|There was an issue uploading your image."
msgstr ""
msgid "Incident|Alert details"
@@ -19479,9 +19925,18 @@ msgstr ""
msgid "Incident|Are you sure you wish to delete this image?"
msgstr ""
+msgid "Incident|Delete image"
+msgstr ""
+
msgid "Incident|Deleting %{filename}"
msgstr ""
+msgid "Incident|Edit image text or link"
+msgstr ""
+
+msgid "Incident|Editing %{filename}"
+msgstr ""
+
msgid "Incident|Metrics"
msgstr ""
@@ -19754,12 +20209,18 @@ msgstr ""
msgid "Integrations|Branches for which notifications are to be sent"
msgstr ""
+msgid "Integrations|Clear if using a self-signed certificate."
+msgstr ""
+
msgid "Integrations|Comment detail:"
msgstr ""
msgid "Integrations|Comment settings:"
msgstr ""
+msgid "Integrations|Connection details"
+msgstr ""
+
msgid "Integrations|Connection failed. Please check your settings."
msgstr ""
@@ -19784,6 +20245,9 @@ msgstr ""
msgid "Integrations|Enable GitLab.com slash commands in a Slack workspace."
msgstr ""
+msgid "Integrations|Enable SSL verification"
+msgstr ""
+
msgid "Integrations|Enable comments"
msgstr ""
@@ -19862,6 +20326,9 @@ msgstr ""
msgid "Integrations|Return to GitLab for Jira"
msgstr ""
+msgid "Integrations|SSL verification"
+msgstr ""
+
msgid "Integrations|Save settings?"
msgstr ""
@@ -19907,9 +20374,6 @@ msgstr ""
msgid "Integrations|Use default settings"
msgstr ""
-msgid "Integrations|When you mention a Jira issue in a commit or merge request, GitLab creates a remote link and comment (if enabled)."
-msgstr ""
-
msgid "Integrations|You can now close this window and return to the GitLab for Jira application."
msgstr ""
@@ -19934,9 +20398,6 @@ msgstr ""
msgid "Integrations|can't exceed %{recipients_limit}"
msgstr ""
-msgid "Interactive developer security education."
-msgstr ""
-
msgid "Interactive mode"
msgstr ""
@@ -20426,6 +20887,9 @@ msgstr ""
msgid "IssueAnalytics|Assignees"
msgstr ""
+msgid "IssueAnalytics|Created by"
+msgstr ""
+
msgid "IssueAnalytics|Due date"
msgstr ""
@@ -20438,9 +20902,6 @@ msgstr ""
msgid "IssueAnalytics|Milestone"
msgstr ""
-msgid "IssueAnalytics|Opened by"
-msgstr ""
-
msgid "IssueAnalytics|Status"
msgstr ""
@@ -20564,10 +21025,10 @@ msgstr ""
msgid "IssuesAnalytics|Avg/Month:"
msgstr ""
-msgid "IssuesAnalytics|Issues opened"
+msgid "IssuesAnalytics|Issues created"
msgstr ""
-msgid "IssuesAnalytics|Issues opened per month"
+msgid "IssuesAnalytics|Issues created per month"
msgstr ""
msgid "IssuesAnalytics|Last 12 months"
@@ -20594,6 +21055,9 @@ msgstr ""
msgid "It looks like you have some draft commits in this branch."
msgstr ""
+msgid "It looks like you're attempting to activate your subscription. Use %{a_start}the Subscription page%{a_end} instead."
+msgstr ""
+
msgid "It may be several days before you see feature usage data."
msgstr ""
@@ -20822,6 +21286,9 @@ msgstr ""
msgid "JiraConnect|You can now close this window and return to Jira."
msgstr ""
+msgid "JiraConnect|You don't have permission to create branches for this project. Select a different project or contact the project owner for access. %{linkStart}Learn more.%{linkEnd}"
+msgstr ""
+
msgid "JiraRequest|A connection error occurred while connecting to Jira. Try your request again."
msgstr ""
@@ -20870,13 +21337,13 @@ msgstr ""
msgid "JiraService|Define the type of Jira issue to create from a vulnerability."
msgstr ""
-msgid "JiraService|Displaying Jira issues while leaving the GitLab issue functionality enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
+msgid "JiraService|Displaying Jira issues while leaving GitLab issues also enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
msgstr ""
-msgid "JiraService|Enable Jira issues"
+msgid "JiraService|Enable Jira issue creation from vulnerabilities"
msgstr ""
-msgid "JiraService|Enable Jira issues creation from vulnerabilities"
+msgid "JiraService|Enable Jira issues"
msgstr ""
msgid "JiraService|Enable Jira transitions"
@@ -20993,16 +21460,19 @@ msgstr ""
msgid "JiraService|View Jira issues in GitLab"
msgstr ""
-msgid "JiraService|Warning: All GitLab users that have access to this GitLab project are able to view all issues from the Jira project specified below."
+msgid "JiraService|Warning: All GitLab users with access to this GitLab project can view all issues from the Jira project you select."
msgstr ""
msgid "JiraService|Web URL"
msgstr ""
-msgid "JiraService|Work on Jira issues without leaving GitLab. Adds a Jira menu to access your list of Jira issues and view any issue as read-only."
+msgid "JiraService|When a Jira issue is mentioned in a commit or merge request, a remote link and comment (if enabled) will be created."
+msgstr ""
+
+msgid "JiraService|Work on Jira issues without leaving GitLab. Add a Jira menu to access a read-only list of your Jira issues."
msgstr ""
-msgid "JiraService|You need to configure Jira before enabling this integration. For more details, read the %{jira_doc_link_start}Jira integration documentation%{link_end}."
+msgid "JiraService|You must configure Jira before enabling this integration. %{jira_doc_link_start}Learn more.%{link_end}"
msgstr ""
msgid "Job"
@@ -21014,9 +21484,6 @@ msgstr ""
msgid "Job Failed #%{build_id}"
msgstr ""
-msgid "Job ID"
-msgstr ""
-
msgid "Job artifact"
msgstr ""
@@ -21083,9 +21550,27 @@ msgstr ""
msgid "Jobs|You're about to retry a job that failed because it attempted to deploy code that is older than the latest deployment. Retrying this job could result in overwriting the environment with the older source code."
msgstr ""
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source} into %{target}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{ref}"
+msgstr ""
+
+msgid "Job|Are you sure you want to erase this job log and artifacts?"
+msgstr ""
+
msgid "Job|Browse"
msgstr ""
+msgid "Job|Cancel"
+msgstr ""
+
msgid "Job|Complete Raw"
msgstr ""
@@ -21095,6 +21580,9 @@ msgstr ""
msgid "Job|Erase job log and artifacts"
msgstr ""
+msgid "Job|Finished at"
+msgstr ""
+
msgid "Job|Job artifacts"
msgstr ""
@@ -21107,7 +21595,7 @@ msgstr ""
msgid "Job|Keep"
msgstr ""
-msgid "Job|Pipeline"
+msgid "Job|Retry"
msgstr ""
msgid "Job|Scroll to bottom"
@@ -21119,6 +21607,9 @@ msgstr ""
msgid "Job|Show complete raw"
msgstr ""
+msgid "Job|Status"
+msgstr ""
+
msgid "Job|The artifacts were removed"
msgstr ""
@@ -21146,21 +21637,12 @@ msgstr ""
msgid "Job|delayed"
msgstr ""
-msgid "Job|for"
-msgstr ""
-
-msgid "Job|into"
-msgstr ""
-
msgid "Job|manual"
msgstr ""
msgid "Job|triggered"
msgstr ""
-msgid "Job|with"
-msgstr ""
-
msgid "Join Zoom meeting"
msgstr ""
@@ -21263,9 +21745,6 @@ msgstr ""
msgid "Ki"
msgstr ""
-msgid "Kontra"
-msgstr ""
-
msgid "Kroki"
msgstr ""
@@ -21592,6 +22071,9 @@ msgstr ""
msgid "Learn more about Auto DevOps"
msgstr ""
+msgid "Learn more about GitLab"
+msgstr ""
+
msgid "Learn more about Needs relationships"
msgstr ""
@@ -21937,9 +22419,18 @@ msgstr ""
msgid "Licenses|Displays licenses detected in the project, based on the %{linkStart}latest successful%{linkEnd} scan"
msgstr ""
+msgid "Licenses|Drag your license file here or %{linkStart}click to upload%{linkEnd}."
+msgstr ""
+
+msgid "Licenses|Drop your license file to start the upload."
+msgstr ""
+
msgid "Licenses|Error fetching the license list. Please check your network connection and try again."
msgstr ""
+msgid "Licenses|Error: You are trying to upload something other than a file"
+msgstr ""
+
msgid "Licenses|License Compliance"
msgstr ""
@@ -21958,6 +22449,9 @@ msgstr ""
msgid "Licenses|Specified policies in this project"
msgstr ""
+msgid "Licenses|The file could not be uploaded."
+msgstr ""
+
msgid "Licenses|The license list details information about the licenses used within your project."
msgstr ""
@@ -21991,14 +22485,6 @@ msgstr ""
msgid "Limit the size of Sidekiq jobs stored in Redis."
msgstr ""
-msgid "Limited to showing %d event at most"
-msgid_plural "Limited to showing %d events at most"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-msgstr[3] ""
-msgstr[4] ""
-
msgid "Limiting mode"
msgstr ""
@@ -22008,6 +22494,9 @@ msgstr ""
msgid "Link"
msgstr ""
+msgid "Link (optional)"
+msgstr ""
+
msgid "Link Prometheus monitoring to GitLab."
msgstr ""
@@ -22044,6 +22533,9 @@ msgstr ""
msgid "Linked emails (%{email_count})"
msgstr ""
+msgid "Linked epics"
+msgstr ""
+
msgid "Linked issues"
msgstr ""
@@ -22071,6 +22563,15 @@ msgstr ""
msgid "List of all merge commits"
msgstr ""
+msgid "List of environments for this project"
+msgstr ""
+
+msgid "List of suitable GCP locations"
+msgstr ""
+
+msgid "List of users allowed to exceed the rate limit."
+msgstr ""
+
msgid "List options"
msgstr ""
@@ -22290,6 +22791,9 @@ msgstr ""
msgid "Maintenance mode"
msgstr ""
+msgid "Make adjustments to how your GitLab instance is set up."
+msgstr ""
+
msgid "Make and review changes in the browser with the Web IDE"
msgstr ""
@@ -22434,6 +22938,12 @@ msgstr ""
msgid "MarkdownEditor|Add italic text (%{modifier_key}I)"
msgstr ""
+msgid "MarkdownEditor|Add strikethrough text (%{modifierKey}⇧X)"
+msgstr ""
+
+msgid "MarkdownEditor|Add strikethrough text (%{modifier_key}⇧X)"
+msgstr ""
+
msgid "Marked For Deletion At - %{deletion_time}"
msgstr ""
@@ -22695,6 +23205,9 @@ msgstr ""
msgid "Maximum push size (MB)"
msgstr ""
+msgid "Maximum requests per 10 minutes per user"
+msgstr ""
+
msgid "Maximum requests per minute"
msgstr ""
@@ -22785,6 +23298,25 @@ msgstr ""
msgid "Members of a group may only view projects they have permission to access"
msgstr ""
+msgid "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seat in use and will be billed for the overage."
+msgid_plural "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seats in use and will be billed for the overage."
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+msgstr[4] ""
+
+msgid "MembersOverage|You are about to incur additional charges"
+msgstr ""
+
+msgid "MembersOverage|Your subscription includes %d seat."
+msgid_plural "MembersOverage|Your subscription includes %d seats."
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+msgstr[4] ""
+
msgid "Membership"
msgstr ""
@@ -22989,9 +23521,6 @@ msgstr ""
msgid "Merge request not merged"
msgstr ""
-msgid "Merge request pipelines 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 merge request pipelines."
-msgstr ""
-
msgid "Merge request reports"
msgstr ""
@@ -23088,13 +23617,13 @@ msgstr ""
msgid "MergeRequests|Create issue to resolve thread"
msgstr ""
-msgid "MergeRequests|Failed to squash. Should be done manually."
+msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Saving the comment failed"
+msgid "MergeRequests|Squashing failed: Squash the commits locally, resolve any conflicts, then push the branch."
msgstr ""
-msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
+msgid "MergeRequests|Squashing not allowed: This project doesn't allow you to squash commits when merging."
msgstr ""
msgid "MergeRequests|Thread stays resolved"
@@ -23941,6 +24470,18 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "MrList|Assigned to %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from assignee %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from reviewer %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Review requested from %{name}, go to their profile."
+msgstr ""
+
msgid "Multi-project"
msgstr ""
@@ -23974,7 +24515,7 @@ msgstr ""
msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "My Awesome Group"
+msgid "My awesome group"
msgstr ""
msgid "My company or team"
@@ -24602,9 +25143,6 @@ msgstr ""
msgid "No available branches"
msgstr ""
-msgid "No available groups to fork the project."
-msgstr ""
-
msgid "No branches found"
msgstr ""
@@ -24815,6 +25353,9 @@ msgstr ""
msgid "No ref selected"
msgstr ""
+msgid "No regions configured"
+msgstr ""
+
msgid "No related merge requests found."
msgstr ""
@@ -25637,6 +26178,9 @@ msgstr ""
msgid "Only reCAPTCHA v2 is supported:"
msgstr ""
+msgid "Only required if not using role instance credentials."
+msgstr ""
+
msgid "Only use lowercase letters, numbers, and underscores."
msgstr ""
@@ -25661,9 +26205,6 @@ msgstr ""
msgid "Open a CLI and connect to the cluster you want to install the agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
-msgid "Open epics"
-msgstr ""
-
msgid "Open errors"
msgstr ""
@@ -25703,7 +26244,7 @@ msgstr ""
msgid "Opened issues"
msgstr ""
-msgid "OpenedNDaysAgo|Opened"
+msgid "OpenedNDaysAgo|Created"
msgstr ""
msgid "Opens in a new window"
@@ -25748,9 +26289,6 @@ msgstr ""
msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
-msgid "Optional."
-msgstr ""
-
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
msgstr ""
@@ -26542,6 +27080,9 @@ msgstr ""
msgid "PerformanceBar|Memory"
msgstr ""
+msgid "PerformanceBar|Memory report"
+msgstr ""
+
msgid "PerformanceBar|Redis calls"
msgstr ""
@@ -26575,18 +27116,12 @@ msgstr ""
msgid "PerformanceBar|wall"
msgstr ""
-msgid "Performs a rebase but skips triggering a new pipeline"
-msgstr ""
-
msgid "Period in seconds"
msgstr ""
msgid "Permalink"
msgstr ""
-msgid "Permanently delete project"
-msgstr ""
-
msgid "Permanently remove group"
msgstr ""
@@ -26857,6 +27392,51 @@ msgstr ""
msgid "PipelineStatusTooltip|Pipeline: %{ci_status}"
msgstr ""
+msgid "PipelineWizardDefaultCommitMessage|Add %{filename}"
+msgstr ""
+
+msgid "PipelineWizardDefaultCommitMessage|Update %{filename}"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|At least one entry is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This field is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This value is not valid"
+msgstr ""
+
+msgid "PipelineWizardListWidget|add another step"
+msgstr ""
+
+msgid "PipelineWizardListWidget|remove step"
+msgstr ""
+
+msgid "PipelineWizard|Commit"
+msgstr ""
+
+msgid "PipelineWizard|Commit Message"
+msgstr ""
+
+msgid "PipelineWizard|Commit changes to your file"
+msgstr ""
+
+msgid "PipelineWizard|Commit file to Branch"
+msgstr ""
+
+msgid "PipelineWizard|Commit your new file"
+msgstr ""
+
+msgid "PipelineWizard|The file has been committed."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem committing the changes."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem while checking whether your file already exists in the specified branch."
+msgstr ""
+
msgid "Pipelines"
msgstr ""
@@ -26971,7 +27551,7 @@ msgstr ""
msgid "Pipelines|Project cache successfully reset."
msgstr ""
-msgid "Pipelines|Revoke"
+msgid "Pipelines|Revoke trigger"
msgstr ""
msgid "Pipelines|Something went wrong while cleaning runners cache."
@@ -27016,6 +27596,12 @@ msgstr ""
msgid "Pipelines|This is a child pipeline within the parent pipeline"
msgstr ""
+msgid "Pipelines|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipelines|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipelines|This pipeline will run code originating from a forked project merge request. This means that the code can potentially have security considerations like exposing CI variables."
msgstr ""
@@ -27058,9 +27644,6 @@ msgstr ""
msgid "Pipelines|Your changes have been successfully committed. Now redirecting to the new merge request page."
msgstr ""
-msgid "Pipelines|detached"
-msgstr ""
-
msgid "Pipelines|error"
msgstr ""
@@ -27070,10 +27653,13 @@ msgstr ""
msgid "Pipelines|latest"
msgstr ""
-msgid "Pipelines|stuck"
+msgid "Pipelines|merge request"
+msgstr ""
+
+msgid "Pipelines|merge train"
msgstr ""
-msgid "Pipelines|train"
+msgid "Pipelines|stuck"
msgstr ""
msgid "Pipelines|yaml invalid"
@@ -27205,6 +27791,12 @@ msgstr ""
msgid "Pipeline|This change will not change the overall test coverage if merged."
msgstr ""
+msgid "Pipeline|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipeline|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipeline|Trigger author"
msgstr ""
@@ -27229,6 +27821,12 @@ msgstr ""
msgid "Pipeline|for"
msgstr ""
+msgid "Pipeline|merge request"
+msgstr ""
+
+msgid "Pipeline|merge train"
+msgstr ""
+
msgid "Pipeline|on"
msgstr ""
@@ -27367,9 +27965,6 @@ msgstr ""
msgid "Please enter a valid time interval"
msgstr ""
-msgid "Please enter or upload a valid license."
-msgstr ""
-
msgid "Please enter your current password."
msgstr ""
@@ -27478,9 +28073,6 @@ msgstr ""
msgid "Please type %{phrase_code} to proceed or close this modal to cancel."
msgstr ""
-msgid "Please type the following to confirm:"
-msgstr ""
-
msgid "Please use this form to report to the admin users who create spam issues, comments or behave inappropriately."
msgstr ""
@@ -27508,12 +28100,27 @@ msgstr ""
msgid "Policies"
msgstr ""
+msgid "Policy '%{escalation_policy_name}' does not exist."
+msgstr ""
+
msgid "Policy management project does have any policies in %{policy_path}"
msgstr ""
msgid "Policy project doesn't exist"
msgstr ""
+msgid "PolicyRuleMultiSelect|%{firstLabel} +%{numberOfAdditionalLabels} more"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|All %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select all"
+msgstr ""
+
msgid "Polling interval multiplier"
msgstr ""
@@ -27742,6 +28349,9 @@ msgstr ""
msgid "Private projects can be created in your personal namespace with:"
msgstr ""
+msgid "Problem with %{name} command: %{message}."
+msgstr ""
+
msgid "Proceed"
msgstr ""
@@ -28216,6 +28826,9 @@ msgstr ""
msgid "Progress"
msgstr ""
+msgid "Progress tracking"
+msgstr ""
+
msgid "Project"
msgstr ""
@@ -28447,6 +29060,9 @@ msgstr ""
msgid "ProjectQualitySummary|Failure"
msgstr ""
+msgid "ProjectQualitySummary|Get insight into the overall percentage of tests in your project that succeed, fail and are skipped."
+msgstr ""
+
msgid "ProjectQualitySummary|Latest pipeline results"
msgstr ""
@@ -28465,6 +29081,12 @@ msgstr ""
msgid "ProjectQualitySummary|See project Code Coverage Statistics"
msgstr ""
+msgid "ProjectQualitySummary|Set up test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|Set up test runs (opens in a new tab)"
+msgstr ""
+
msgid "ProjectQualitySummary|Skipped"
msgstr ""
@@ -28741,13 +29363,19 @@ msgstr ""
msgid "ProjectSettings|LFS objects from this repository are available to forks. %{linkStart}How do I remove them?%{linkEnd}"
msgstr ""
+msgid "ProjectSettings|Learn about commit history."
+msgstr ""
+
+msgid "ProjectSettings|Leave empty to use default template."
+msgstr ""
+
msgid "ProjectSettings|Manage who can see the project in the public access directory."
msgstr ""
msgid "ProjectSettings|Manages large files such as audio, video, and graphics files."
msgstr ""
-msgid "ProjectSettings|Maximum 500 characters."
+msgid "ProjectSettings|Maximum %{maxLength} characters."
msgstr ""
msgid "ProjectSettings|Merge checks"
@@ -28888,6 +29516,9 @@ msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
msgstr ""
+msgid "ProjectSettings|The default template will be applied on save."
+msgstr ""
+
msgid "ProjectSettings|These checks must pass before merge requests can be merged."
msgstr ""
@@ -28942,6 +29573,9 @@ msgstr ""
msgid "ProjectSettings|What are badges?"
msgstr ""
+msgid "ProjectSettings|What are merge trains?"
+msgstr ""
+
msgid "ProjectSettings|When merge request pipelines are enabled in the CI/CD configuration file, pipelines validate the combined results of the source and target branches. %{link_start}How to configure merge request pipelines?%{link_end}"
msgstr ""
@@ -29059,6 +29693,9 @@ msgstr ""
msgid "Projects are organized into groups"
msgstr ""
+msgid "Projects are where you store your code, access issues, wiki and other features of GitLab."
+msgstr ""
+
msgid "Projects contributed to"
msgstr ""
@@ -29074,12 +29711,6 @@ msgstr ""
msgid "Projects to index"
msgstr ""
-msgid "Projects will be permanently deleted after a %{waiting_period}-day waiting period."
-msgstr ""
-
-msgid "Projects will be permanently deleted immediately."
-msgstr ""
-
msgid "Projects with critical vulnerabilities"
msgstr ""
@@ -29164,6 +29795,9 @@ msgstr ""
msgid "ProjectsNew|Import project"
msgstr ""
+msgid "ProjectsNew|Include a Getting Started README"
+msgstr ""
+
msgid "ProjectsNew|Initialize repository with a README"
msgstr ""
@@ -29179,6 +29813,9 @@ msgstr ""
msgid "ProjectsNew|Project description %{tag_start}(optional)%{tag_end}"
msgstr ""
+msgid "ProjectsNew|Recommended if you're new to GitLab"
+msgstr ""
+
msgid "ProjectsNew|Run CI/CD for external repository"
msgstr ""
@@ -29596,6 +30233,9 @@ msgstr ""
msgid "ProtectedBranch|Unprotect"
msgstr ""
+msgid "ProtectedBranch|Unprotect branch"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
@@ -29623,6 +30263,9 @@ msgstr ""
msgid "ProtectedEnvironment|Protected Environment (%{protected_environments_count})"
msgstr ""
+msgid "ProtectedEnvironment|Required approvals"
+msgstr ""
+
msgid "ProtectedEnvironment|Select an environment"
msgstr ""
@@ -29644,10 +30287,13 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|Unprotect tag"
+msgstr ""
+
msgid "ProtectedTags|default"
msgstr ""
-msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
+msgid "ProtectedTag|By default, protected tags restrict who can modify the tag."
msgstr ""
msgid "ProtectedTag|Learn more."
@@ -29710,6 +30356,9 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Public projects are an easy way to allow everyone to have read-only access."
+msgstr ""
+
msgid "Publish to status page"
msgstr ""
@@ -29866,9 +30515,6 @@ msgstr ""
msgid "QualitySummary|Project quality"
msgstr ""
-msgid "Quarters"
-msgstr ""
-
msgid "Query"
msgstr ""
@@ -29953,6 +30599,9 @@ msgstr ""
msgid "Read more about project permissions %{help_link_open}here%{help_link_close}"
msgstr ""
+msgid "Read more about related epics"
+msgstr ""
+
msgid "Read more about related issues"
msgstr ""
@@ -29983,10 +30632,7 @@ msgstr ""
msgid "Rebase source branch on the target branch."
msgstr ""
-msgid "Rebase without CI"
-msgstr ""
-
-msgid "Rebases and triggers a pipeline"
+msgid "Rebase without pipeline"
msgstr ""
msgid "Recaptcha verified?"
@@ -30037,9 +30683,6 @@ msgstr ""
msgid "Reconfigure"
msgstr ""
-msgid "Recovering projects"
-msgstr ""
-
msgid "Recovery Codes"
msgstr ""
@@ -30102,6 +30745,12 @@ msgstr ""
msgid "Regex pattern"
msgstr ""
+msgid "Region"
+msgstr ""
+
+msgid "Regions"
+msgstr ""
+
msgid "Register"
msgstr ""
@@ -30335,9 +30984,6 @@ msgstr ""
msgid "Remove all or specific reviewer(s)"
msgstr ""
-msgid "Remove approver"
-msgstr ""
-
msgid "Remove approvers"
msgstr ""
@@ -30353,6 +30999,9 @@ msgstr ""
msgid "Remove attention request"
msgstr ""
+msgid "Remove attention request(s)"
+msgstr ""
+
msgid "Remove avatar"
msgstr ""
@@ -30491,6 +31140,9 @@ msgstr ""
msgid "Removed an issue from an epic."
msgstr ""
+msgid "Removed attention from %{users_sentence}."
+msgstr ""
+
msgid "Removed attention request from @%{username}"
msgstr ""
@@ -30542,6 +31194,9 @@ msgstr ""
msgid "Removes an issue from an epic."
msgstr ""
+msgid "Removes attention from %{users_sentence}."
+msgstr ""
+
msgid "Removes parent epic %{epic_ref}."
msgstr ""
@@ -30653,6 +31308,9 @@ msgstr ""
msgid "Report abuse to admin"
msgstr ""
+msgid "Report is generating and will be sent to your email address."
+msgstr ""
+
msgid "Reported %{timeAgo} by %{reportedBy}"
msgstr ""
@@ -30957,6 +31615,15 @@ msgstr ""
msgid "Request attention"
msgstr ""
+msgid "Request attention from %{users_sentence}."
+msgstr ""
+
+msgid "Request attention from assignee or reviewer"
+msgstr ""
+
+msgid "Request attention from assignee(s) or reviewer(s)"
+msgstr ""
+
msgid "Request attention to review"
msgstr ""
@@ -30981,6 +31648,9 @@ msgstr ""
msgid "Requested %{time_ago}"
msgstr ""
+msgid "Requested attention from %{users_sentence}."
+msgstr ""
+
msgid "Requested attention from @%{username}"
msgstr ""
@@ -31201,6 +31871,9 @@ msgstr ""
msgid "Restore project"
msgstr ""
+msgid "Restoring projects"
+msgstr ""
+
msgid "Restoring the group will prevent the group, its subgroups and projects from being removed on this date."
msgstr ""
@@ -31231,6 +31904,9 @@ msgstr ""
msgid "Retry"
msgstr ""
+msgid "Retry failed jobs"
+msgstr ""
+
msgid "Retry job"
msgstr ""
@@ -31281,9 +31957,6 @@ msgstr ""
msgid "Review changes"
msgstr ""
-msgid "Review requested from %{name}"
-msgstr ""
-
msgid "Review requests for you"
msgstr ""
@@ -31451,6 +32124,9 @@ msgstr ""
msgid "Runners|Assigned Group"
msgstr ""
+msgid "Runners|Assigned Projects (%{projectCount})"
+msgstr ""
+
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -31520,6 +32196,9 @@ msgstr ""
msgid "Runners|Instance"
msgstr ""
+msgid "Runners|Jobs"
+msgstr ""
+
msgid "Runners|Last contact"
msgstr ""
@@ -31613,9 +32292,6 @@ msgstr ""
msgid "Runners|Runner %{name} was deleted"
msgstr ""
-msgid "Runners|Runner ID"
-msgstr ""
-
msgid "Runners|Runner assigned to project."
msgstr ""
@@ -31763,6 +32439,9 @@ msgstr ""
msgid "Runners|stale"
msgstr ""
+msgid "Runner|This runner has not run any jobs."
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -31877,6 +32556,24 @@ msgstr ""
msgid "Saving project."
msgstr ""
+msgid "ScanResultPolicy|%{ifLabelStart}if%{ifLabelEnd} %{scanners} scan in an open merge request targeting the %{branches} branch(es) finds %{vulnerabilitiesAllowed} or more %{severities} vulnerabilities that are %{vulnerabilityStates}"
+msgstr ""
+
+msgid "ScanResultPolicy|%{thenLabelStart}Then%{thenLabelEnd} Require approval from %{approvalsRequired} of the following approvers: %{approvers}"
+msgstr ""
+
+msgid "ScanResultPolicy|add an approver"
+msgstr ""
+
+msgid "ScanResultPolicy|scanners"
+msgstr ""
+
+msgid "ScanResultPolicy|severity levels"
+msgstr ""
+
+msgid "ScanResultPolicy|vulnerability states"
+msgstr ""
+
msgid "Scanner"
msgstr ""
@@ -32009,6 +32706,9 @@ msgstr ""
msgid "Search for a user"
msgstr ""
+msgid "Search for an emoji"
+msgstr ""
+
msgid "Search for projects, issues, etc."
msgstr ""
@@ -32229,18 +32929,12 @@ msgstr ""
msgid "Secret Detection"
msgstr ""
-msgid "Secret access key"
-msgstr ""
-
msgid "Secret token"
msgstr ""
msgid "Secure token that identifies an external storage request."
msgstr ""
-msgid "SecureCodeWarrior"
-msgstr ""
-
msgid "Security"
msgstr ""
@@ -32265,9 +32959,6 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "Security training with guide and learning pathways."
-msgstr ""
-
msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
@@ -32370,7 +33061,7 @@ msgstr ""
msgid "SecurityConfiguration|Manage corpus"
msgstr ""
-msgid "SecurityConfiguration|Manage corpus files used as mutation sources in coverage fuzzing."
+msgid "SecurityConfiguration|Manage corpus files used as seed inputs with coverage-guided fuzzing."
msgstr ""
msgid "SecurityConfiguration|Manage profiles for use by DAST scans."
@@ -32436,15 +33127,15 @@ msgstr ""
msgid "SecurityOrchestration|.yaml preview"
msgstr ""
-msgid "SecurityOrchestration|Action"
-msgstr ""
-
msgid "SecurityOrchestration|Actions"
msgstr ""
msgid "SecurityOrchestration|Add rule"
msgstr ""
+msgid "SecurityOrchestration|After dismissing the alert, the information will never be shown again."
+msgstr ""
+
msgid "SecurityOrchestration|All policies"
msgstr ""
@@ -32460,7 +33151,7 @@ msgstr ""
msgid "SecurityOrchestration|Description"
msgstr ""
-msgid "SecurityOrchestration|Disabled"
+msgid "SecurityOrchestration|Don't show the alert anymore"
msgstr ""
msgid "SecurityOrchestration|Edit policy"
@@ -32469,13 +33160,13 @@ msgstr ""
msgid "SecurityOrchestration|Edit policy project"
msgstr ""
-msgid "SecurityOrchestration|Enabled"
+msgid "SecurityOrchestration|Empty policy name"
msgstr ""
-msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Enabled"
msgstr ""
-msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
msgstr ""
msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
@@ -32484,7 +33175,7 @@ msgstr ""
msgid "SecurityOrchestration|Invalid policy type"
msgstr ""
-msgid "SecurityOrchestration|Latest scan"
+msgid "SecurityOrchestration|Latest scan run against %{agent}"
msgstr ""
msgid "SecurityOrchestration|Network"
@@ -32493,15 +33184,27 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No actions defined - policy will not run."
+msgstr ""
+
+msgid "SecurityOrchestration|No description"
+msgstr ""
+
msgid "SecurityOrchestration|No rules defined - policy will not run."
msgstr ""
+msgid "SecurityOrchestration|Not enabled"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
msgid "SecurityOrchestration|Policies"
msgstr ""
+msgid "SecurityOrchestration|Policy Type"
+msgstr ""
+
msgid "SecurityOrchestration|Policy cannot be enabled for non-existing branches (%{branches})"
msgstr ""
@@ -32526,10 +33229,13 @@ msgstr ""
msgid "SecurityOrchestration|Require %{approvals} %{plural} from %{approvers} if any of the following occur:"
msgstr ""
-msgid "SecurityOrchestration|Rule"
+msgid "SecurityOrchestration|Rules"
msgstr ""
-msgid "SecurityOrchestration|Rules"
+msgid "SecurityOrchestration|Runs %{actions} and %{lastAction} scans"
+msgstr ""
+
+msgid "SecurityOrchestration|Runs a %{action} scan"
msgstr ""
msgid "SecurityOrchestration|Scan Execution"
@@ -32589,6 +33295,9 @@ msgstr ""
msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
+msgid "SecurityOrchestration|This view only shows scan results for the agent %{agent}. You can view scan results for all agents in the %{linkStart}Operational Vulnerabilities tab of the vulnerability report%{linkEnd}."
+msgstr ""
+
msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
@@ -32643,9 +33352,6 @@ msgstr ""
msgid "SecurityOrchestration|users with ids"
msgstr ""
-msgid "SecurityOrchestration|view results"
-msgstr ""
-
msgid "SecurityOrchestration|vulnerabilities"
msgstr ""
@@ -33315,22 +34021,19 @@ 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|In order to start using functions as a service, you must first install Knative on your Kubernetes cluster. %{linkStart}More information%{linkEnd}"
-msgstr ""
-
msgid "Serverless|Learn more about Serverless"
msgstr ""
msgid "Serverless|No functions available"
msgstr ""
-msgid "Serverless|Sign up for First Look"
+msgid "Serverless|Serverless was %{linkStart}deprecated%{linkEnd} in GitLab 14.3."
+msgstr ""
+
+msgid "Serverless|Serverless was %{postLinkStart}deprecated%{postLinkEnd}. But if you opt to use it, you must install Knative in your Kubernetes cluster first. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "Serverless|The deploy job has not finished."
@@ -33342,9 +34045,6 @@ 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 ""
@@ -33360,9 +34060,6 @@ msgstr ""
msgid "Service Account Key"
msgstr ""
-msgid "Service Accounts"
-msgstr ""
-
msgid "Service Accounts keys authorize GitLab to deploy your Google Cloud project"
msgstr ""
@@ -33372,10 +34069,10 @@ msgstr ""
msgid "Service Desk allows people to create issues in your GitLab instance without their own user account. It provides a unique email address for end users to create issues in a project. Replies can be sent either through the GitLab interface or by email. End users only see threads through email."
msgstr ""
-msgid "Service Usage Data"
+msgid "Service account generated successfully"
msgstr ""
-msgid "Service account generated successfully"
+msgid "Service accounts"
msgstr ""
msgid "Service ping is disabled in your configuration file, and cannot be enabled through this form."
@@ -33519,6 +34216,9 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
+msgid "Set the per-user rate limit for getting a user by ID via the API."
+msgstr ""
+
msgid "Set the per-user rate limit for notes created by web or API requests."
msgstr ""
@@ -33701,6 +34401,9 @@ msgstr ""
msgid "Shared runners details"
msgstr ""
+msgid "Shared runners enabled cannot be enabled until a valid credit card is on file"
+msgstr ""
+
msgid "Shared runners help link"
msgstr ""
@@ -33758,6 +34461,9 @@ msgstr ""
msgid "Show all issues."
msgstr ""
+msgid "Show all milestones"
+msgstr ""
+
msgid "Show all test cases."
msgstr ""
@@ -33794,6 +34500,9 @@ msgstr ""
msgid "Show file contents"
msgstr ""
+msgid "Show group milestones"
+msgstr ""
+
msgid "Show labels"
msgstr ""
@@ -33809,6 +34518,12 @@ msgstr ""
msgid "Show open epics"
msgstr ""
+msgid "Show project milestones"
+msgstr ""
+
+msgid "Show sub-group milestones"
+msgstr ""
+
msgid "Show the Closed list"
msgstr ""
@@ -33818,14 +34533,6 @@ msgstr ""
msgid "Show whitespace changes"
msgstr ""
-msgid "Showing %d event"
-msgid_plural "Showing %d events"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-msgstr[3] ""
-msgstr[4] ""
-
msgid "Showing %{conflict} between %{sourceBranch} and %{targetBranch}"
msgstr ""
@@ -33888,12 +34595,6 @@ msgstr ""
msgid "Sidebar|None"
msgstr ""
-msgid "Sidebar|Only numeral characters allowed"
-msgstr ""
-
-msgid "Sidebar|Weight"
-msgstr ""
-
msgid "Sidekiq job compression threshold (bytes)"
msgstr ""
@@ -34056,6 +34757,9 @@ msgstr ""
msgid "Slack logo"
msgstr ""
+msgid "SlackIntegration|Are you sure you want to remove this project from the Slack application?"
+msgstr ""
+
msgid "SlackIntegration|GitLab for Slack"
msgstr ""
@@ -34065,6 +34769,9 @@ msgstr ""
msgid "SlackIntegration|Project alias"
msgstr ""
+msgid "SlackIntegration|Remove project"
+msgstr ""
+
msgid "SlackIntegration|Select a GitLab project to link with your Slack workspace."
msgstr ""
@@ -34209,9 +34916,6 @@ msgstr ""
msgid "Something went wrong trying to load issue contacts."
msgstr ""
-msgid "Something went wrong when creating a work item. Please try again"
-msgstr ""
-
msgid "Something went wrong when reordering designs. Please try again"
msgstr ""
@@ -34305,9 +35009,6 @@ msgstr ""
msgid "Something went wrong while inserting your image. Please try again."
msgstr ""
-msgid "Something went wrong while merging this merge request. Please try again."
-msgstr ""
-
msgid "Something went wrong while obtaining the Let's Encrypt certificate."
msgstr ""
@@ -34629,10 +35330,10 @@ 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."
+msgid "SourcegraphAdmin|Learn more."
msgstr ""
-msgid "SourcegraphAdmin|More information"
+msgid "SourcegraphAdmin|Only public projects have code intelligence enabled and communicate with Sourcegraph."
msgstr ""
msgid "SourcegraphAdmin|Save changes"
@@ -34641,7 +35342,7 @@ msgstr ""
msgid "SourcegraphAdmin|Sourcegraph URL"
msgstr ""
-msgid "SourcegraphAdmin|e.g. https://sourcegraph.example.com"
+msgid "SourcegraphAdmin|https://sourcegraph.example.com"
msgstr ""
msgid "SourcegraphPreferences|This feature is experimental and currently limited to certain projects."
@@ -34776,6 +35477,9 @@ msgstr ""
msgid "Start date"
msgstr ""
+msgid "Start free trial"
+msgstr ""
+
msgid "Start merge train"
msgstr ""
@@ -34806,6 +35510,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started escalation for this incident."
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -34818,6 +35525,9 @@ msgstr ""
msgid "Starts at (UTC)"
msgstr ""
+msgid "Starts escalations for this incident"
+msgstr ""
+
msgid "Starts on"
msgstr ""
@@ -35079,6 +35789,9 @@ msgstr ""
msgid "Strikethrough"
msgstr ""
+msgid "Strikethrough text"
+msgstr ""
+
msgid "Subgroup information"
msgstr ""
@@ -35313,6 +36026,21 @@ msgstr ""
msgid "Subscriptions"
msgstr ""
+msgid "Subscriptions|Chat with sales"
+msgstr ""
+
+msgid "Subscriptions|Close"
+msgstr ""
+
+msgid "Subscriptions|Not ready to buy yet?"
+msgstr ""
+
+msgid "Subscriptions|Start a free trial"
+msgstr ""
+
+msgid "Subscriptions|We understand. Maybe you have some questions for our sales team, or maybe you'd like to try some of the paid features first. What would you like to do?"
+msgstr ""
+
msgid "Subscription|Your subscription for %{strong}%{namespace_name}%{strong_close} has expired and you are now on %{pricing_link_start}the GitLab Free tier%{pricing_link_end}. Don't worry, your data is safe. Get in touch with our support team (%{support_email}). They'll gladly help with your subscription renewal."
msgstr ""
@@ -35523,6 +36251,9 @@ msgstr ""
msgid "SuperSonics|Maximum users"
msgstr ""
+msgid "SuperSonics|Offline cloud"
+msgstr ""
+
msgid "SuperSonics|Paste your activation code"
msgstr ""
@@ -35589,6 +36320,12 @@ msgstr ""
msgid "SuperSonics|You do not have an active subscription"
msgstr ""
+msgid "SuperSonics|You have a future dated license"
+msgstr ""
+
+msgid "SuperSonics|You have added a license that activates on %{date}. Please see the subscription history table below for more details."
+msgstr ""
+
msgid "SuperSonics|You have successfully added a license that activates on %{date}. Please see the subscription history table below for more details."
msgstr ""
@@ -35748,6 +36485,9 @@ msgstr ""
msgid "Tag name is required"
msgstr ""
+msgid "Tag push"
+msgstr ""
+
msgid "Tag push events"
msgstr ""
@@ -35850,6 +36590,9 @@ msgstr ""
msgid "TagsPage|protected"
msgstr ""
+msgid "Take a look at the documentation to discover all of GitLab’s capabilities."
+msgstr ""
+
msgid "Target Branch"
msgstr ""
@@ -36270,6 +37013,9 @@ msgstr ""
msgid "Tests"
msgstr ""
+msgid "Text (optional)"
+msgstr ""
+
msgid "Text added to the body of all email messages. %{character_limit} character limit"
msgstr ""
@@ -36323,6 +37069,9 @@ msgstr ""
msgid "The CSV export will be created in the background. Once finished, it will be sent to %{email} in an attachment."
msgstr ""
+msgid "The CSV export you requested of all user memberships is attached to this email."
+msgstr ""
+
msgid "The GitLab subscription service (customers.gitlab.com) is currently experiencing an outage. You can monitor the status and get updates at %{linkStart}status.gitlab.com%{linkEnd}."
msgstr ""
@@ -36398,6 +37147,9 @@ 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 epic"
+msgstr ""
+
msgid "The current issue"
msgstr ""
@@ -36562,6 +37314,9 @@ msgstr ""
msgid "The latest pipeline for this merge request has failed."
msgstr ""
+msgid "The license key is invalid."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -36577,6 +37332,9 @@ msgstr ""
msgid "The license was successfully uploaded and will be active from %{starts_at}. You can see the details below."
msgstr ""
+msgid "The license you uploaded is invalid. If the issue persists, contact support at %{link}."
+msgstr ""
+
msgid "The list creation wizard is already open"
msgstr ""
@@ -37198,10 +37956,13 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} and everything this project contains. %{strongOpen}There is no going back%{strongClose}"
+msgstr ""
+
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains."
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}on %{date}%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains. %{strongOpen}There is no going back.%{strongClose}"
msgstr ""
msgid "This action will %{strongOpen}permanently remove%{strongClose} %{codeOpen}%{group}%{codeClose} %{strongOpen}immediately%{strongClose}."
@@ -37330,9 +38091,6 @@ msgstr ""
msgid "This file was modified for readability, and can't accept suggestions. Edit it directly."
msgstr ""
-msgid "This forked project has the following:"
-msgstr ""
-
msgid "This form is disabled in preview"
msgstr ""
@@ -37345,7 +38103,7 @@ msgstr ""
msgid "This group can't be removed because it is linked to a subscription. To remove this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
-msgid "This group can't be transfered because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
+msgid "This group can't be transferred because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
msgid "This group cannot be invited to a project inside a group with enforced SSO"
@@ -37372,6 +38130,9 @@ 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 incident is already escalated with '%{escalation_policy_name}'."
+msgstr ""
+
msgid "This invitation was sent to %{mail_to_invite_email}, but you are signed in as %{link_to_current_user} with email %{mail_to_current_user}."
msgstr ""
@@ -37390,9 +38151,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 merge train pipeline"
-msgstr ""
-
msgid "This is a private email address %{helpIcon} generated just for you. Anyone who has it can create issues or merge requests as if they were you. If that happens, %{resetLinkStart}reset this token%{resetLinkEnd}."
msgstr ""
@@ -37414,6 +38172,12 @@ msgstr ""
msgid "This is your current session"
msgstr ""
+msgid "This issue cannot be assigned to a confidential epic because it is public."
+msgstr ""
+
+msgid "This issue cannot be made public because it belongs to a confidential epic."
+msgstr ""
+
msgid "This issue is confidential and should only be visible to team members with at least Reporter access."
msgstr ""
@@ -37531,6 +38295,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 branch is protected from force push."
+msgstr ""
+
msgid "This merge request cannot be rebased while there are conflicts."
msgstr ""
@@ -37582,9 +38349,15 @@ msgstr ""
msgid "This pipeline was triggered by a schedule."
msgstr ""
+msgid "This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project"
msgstr ""
+msgid "This project can be restored until %{date}."
+msgstr ""
+
msgid "This project cannot be %{visibilityLevel} because the visibility of %{openShowLink}%{name}%{closeShowLink} is %{visibility}. To make this project %{visibilityLevel}, you must first %{openEditLink}change the visibility%{closeEditLink} of the parent group."
msgstr ""
@@ -37603,6 +38376,9 @@ msgstr ""
msgid "This project is %{strongStart}NOT%{strongEnd} a fork, and has the following:"
msgstr ""
+msgid "This project is %{strongStart}NOT%{strongEnd} a fork. This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -38300,6 +39076,9 @@ msgstr ""
msgid "Today"
msgstr ""
+msgid "Todos count"
+msgstr ""
+
msgid "Todos|Are you looking for things to do? Take a look at %{strongStart}%{openIssuesLinkStart}open issues%{openIssuesLinkEnd}%{strongEnd}, contribute to %{strongStart}%{mergeRequestLinkStart}a merge request%{mergeRequestLinkEnd}%{mergeRequestLinkEnd}%{strongEnd}, or mention someone in a comment to automatically assign them a new to-do item."
msgstr ""
@@ -38573,13 +39352,8 @@ msgstr ""
msgid "Trending"
msgstr ""
-msgid "Trials|%{planName} Trial %{enDash} %{num} day left"
-msgid_plural "Trials|%{planName} Trial %{enDash} %{num} days left"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-msgstr[3] ""
-msgstr[4] ""
+msgid "Trials|%{planName} Trial"
+msgstr ""
msgid "Trials|Compare all plans"
msgstr ""
@@ -38587,6 +39361,9 @@ msgstr ""
msgid "Trials|Create a new group to start your GitLab Ultimate trial."
msgstr ""
+msgid "Trials|Day %{daysUsed}/%{duration}"
+msgstr ""
+
msgid "Trials|Go back to GitLab"
msgstr ""
@@ -38836,7 +39613,7 @@ msgstr ""
msgid "URL is triggered when repository is updated"
msgstr ""
-msgid "URL must be percent-encoded if neccessary."
+msgid "URL must be percent-encoded if necessary."
msgstr ""
msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
@@ -39055,6 +39832,9 @@ msgstr ""
msgid "Unlock account"
msgstr ""
+msgid "Unlock more features with GitLab Ultimate"
+msgstr ""
+
msgid "Unlock the discussion"
msgstr ""
@@ -39118,6 +39898,9 @@ msgstr ""
msgid "Unsubscribes from this %{quick_action_target}."
msgstr ""
+msgid "Unsupported sort value."
+msgstr ""
+
msgid "Unsupported todo type passed. Supported todo types are: %{todo_types}"
msgstr ""
@@ -39346,6 +40129,9 @@ msgstr ""
msgid "UsageQuota|File attachments and smaller design graphics."
msgstr ""
+msgid "UsageQuota|From %{storage_enforcement_date} storage limits will apply to this namespace. View and manage your usage in %{strong_start}Group Settings &gt; Usage quotas%{strong_end}."
+msgstr ""
+
msgid "UsageQuota|Git repository."
msgstr ""
@@ -39406,6 +40192,9 @@ msgstr ""
msgid "UsageQuota|Storage type"
msgstr ""
+msgid "UsageQuota|Storage used"
+msgstr ""
+
msgid "UsageQuota|This is the total amount of storage used across your projects within this namespace."
msgstr ""
@@ -39601,6 +40390,12 @@ msgstr ""
msgid "Use hashed storage paths for newly created and renamed repositories. Always enabled since 13.0."
msgstr ""
+msgid "Use issue count"
+msgstr ""
+
+msgid "Use issue weight"
+msgstr ""
+
msgid "Use one line per URI"
msgstr ""
@@ -39982,6 +40777,9 @@ msgstr ""
msgid "Users"
msgstr ""
+msgid "Users API rate limit"
+msgstr ""
+
msgid "Users can launch a development environment from a GitLab browser tab when the %{linkStart}Gitpod%{linkEnd} integration is enabled."
msgstr ""
@@ -40313,6 +41111,9 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View group pipeline usage quota"
+msgstr ""
+
msgid "View incident details at"
msgstr ""
@@ -40468,6 +41269,9 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
+msgid "Vulnerability"
+msgstr ""
+
msgid "Vulnerability Report"
msgstr ""
@@ -40519,6 +41323,9 @@ msgstr ""
msgid "VulnerabilityManagement|An unverified non-confirmed finding"
msgstr ""
+msgid "VulnerabilityManagement|At least one identifier is required"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -40528,12 +41335,24 @@ msgstr ""
msgid "VulnerabilityManagement|Create Jira issue"
msgstr ""
+msgid "VulnerabilityManagement|Enter a name"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE code"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE identifier URL"
+msgstr ""
+
msgid "VulnerabilityManagement|Fetching linked Jira issues"
msgstr ""
msgid "VulnerabilityManagement|Manually add a vulnerability entry into the vulnerability report."
msgstr ""
+msgid "VulnerabilityManagement|Name is a required field"
+msgstr ""
+
msgid "VulnerabilityManagement|Needs triage"
msgstr ""
@@ -40549,6 +41368,18 @@ msgstr ""
msgid "VulnerabilityManagement|Select a method"
msgstr ""
+msgid "VulnerabilityManagement|Select a severity level"
+msgstr ""
+
+msgid "VulnerabilityManagement|Select a status"
+msgstr ""
+
+msgid "VulnerabilityManagement|Severity is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Something went wrong while creating vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -40573,6 +41404,12 @@ msgstr ""
msgid "VulnerabilityManagement|Something went wrong, could not update vulnerability state."
msgstr ""
+msgid "VulnerabilityManagement|Status is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Submit vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Summary, detailed description, steps to reproduce, etc."
msgstr ""
@@ -40768,6 +41605,9 @@ msgstr ""
msgid "WARNING:"
msgstr ""
+msgid "WARNING: This snippet contains hidden files which might be used to mask malicious behavior. Exercise caution if cloning and executing code from this snippet."
+msgstr ""
+
msgid "Wait for the file to load to copy its contents"
msgstr ""
@@ -40987,6 +41827,15 @@ msgstr ""
msgid "Webhooks|An issue is created, updated, closed, or reopened."
msgstr ""
+msgid "Webhooks|Are you sure you want to delete this group hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this project hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this webhook?"
+msgstr ""
+
msgid "Webhooks|Comments"
msgstr ""
@@ -40996,6 +41845,9 @@ msgstr ""
msgid "Webhooks|Confidential issues events"
msgstr ""
+msgid "Webhooks|Delete webhook"
+msgstr ""
+
msgid "Webhooks|Deployment events"
msgstr ""
@@ -41232,6 +42084,9 @@ msgstr ""
msgid "Wiki"
msgstr ""
+msgid "Wiki page"
+msgstr ""
+
msgid "Wiki page was successfully created."
msgstr ""
@@ -41337,7 +42192,7 @@ msgstr ""
msgid "WikiPageConflictMessage|Someone edited the page the same time you did. Please check out %{wikiLinkStart}the page%{wikiLinkEnd} and make sure your changes will not unintentionally remove theirs."
msgstr ""
-msgid "WikiPage|An error occured while trying to render the content editor. Please try again later."
+msgid "WikiPage|An error occurred while trying to render the content editor. Please try again later."
msgstr ""
msgid "WikiPage|Are you sure you want to switch back to the classic editor?"
@@ -41496,6 +42351,18 @@ msgstr ""
msgid "WorkItem|New Task"
msgstr ""
+msgid "WorkItem|Something went wrong when creating a work item. Please try again"
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching the work item. Please try again."
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching work item types. Please try again"
+msgstr ""
+
+msgid "WorkItem|Type"
+msgstr ""
+
msgid "WorkItem|Work Items"
msgstr ""
@@ -41562,7 +42429,10 @@ msgstr ""
msgid "You are about to add %{usersTag} people to the discussion. They will all receive a notification."
msgstr ""
-msgid "You are about to permanently delete this project"
+msgid "You are about to delete this forked project containing:"
+msgstr ""
+
+msgid "You are about to delete this project containing:"
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."
@@ -41583,6 +42453,9 @@ msgstr ""
msgid "You are attempting to update a file that has changed since you started editing it."
msgstr ""
+msgid "You are billed if you exceed this number. %{qsrOverageLinkStart}How does billing work?%{qsrOverageLinkEnd}"
+msgstr ""
+
msgid "You are connected to the Prometheus server, but there is currently no data to display."
msgstr ""
@@ -41640,6 +42513,9 @@ msgstr ""
msgid "You are not authorized to update this scanner profile"
msgstr ""
+msgid "You are not authorized to upload metric images"
+msgstr ""
+
msgid "You are now impersonating %{username}"
msgstr ""
@@ -41793,9 +42669,6 @@ msgstr ""
msgid "You can only upload one design when dropping onto an existing design."
msgstr ""
-msgid "You can recover this project until %{date}"
-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 ""
@@ -41844,9 +42717,6 @@ msgstr ""
msgid "You cannot write to this read-only GitLab instance."
msgstr ""
-msgid "You can’t %{tag_start}edit%{tag_end} files directly in this project. Fork this project and submit a merge request with your changes."
-msgstr ""
-
msgid "You can’t edit files directly in this project. Fork this project and submit a merge request with your changes."
msgstr ""
@@ -42002,9 +42872,6 @@ 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 set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
@@ -42035,12 +42902,6 @@ msgstr ""
msgid "You must have maintainer access to force delete a lock"
msgstr ""
-msgid "You must have permission to create a project in a group before forking."
-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 ""
@@ -42446,7 +43307,7 @@ msgstr ""
msgid "Your public email will be displayed on your public profile."
msgstr ""
-msgid "Your request for access could not be processed: %{error_meesage}"
+msgid "Your request for access could not be processed: %{error_message}"
msgstr ""
msgid "Your request for access has been queued for review."
@@ -42638,6 +43499,9 @@ msgstr ""
msgid "archived:"
msgstr ""
+msgid "artifacts"
+msgstr ""
+
msgid "assign yourself"
msgstr ""
@@ -42670,6 +43534,9 @@ msgstr[4] ""
msgid "branch name"
msgstr ""
+msgid "builds"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -43102,6 +43969,9 @@ msgstr ""
msgid "contact with same email already exists in group hierarchy"
msgstr ""
+msgid "container registry images"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -43141,6 +44011,9 @@ msgstr ""
msgid "data"
msgstr ""
+msgid "database"
+msgstr ""
+
msgid "date must not be after 9999-12-31"
msgstr ""
@@ -43167,9 +44040,6 @@ msgstr ""
msgid "design"
msgstr ""
-msgid "detached"
-msgstr ""
-
msgid "disabled"
msgstr ""
@@ -43430,7 +44300,7 @@ msgstr ""
msgid "is not a valid X509 certificate."
msgstr ""
-msgid "is not allowed for sign-up."
+msgid "is not allowed for sign-up. Please use your regular email address."
msgstr ""
msgid "is not allowed for this group."
@@ -43442,7 +44312,7 @@ msgstr ""
msgid "is not allowed since the group is not top-level group."
msgstr ""
-msgid "is not allowed."
+msgid "is not allowed. Please use your regular email address."
msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
@@ -43529,6 +44399,9 @@ msgstr ""
msgid "level: %{level}"
msgstr ""
+msgid "lfs objects"
+msgstr ""
+
msgid "limit of %{project_limit} reached"
msgstr ""
@@ -43757,6 +44630,9 @@ msgstr ""
msgid "mrWidget|Merge blocked: pipeline must succeed. It's waiting for a manual action to continue."
msgstr ""
+msgid "mrWidget|Merge blocked: pipeline must succeed. Push a commit that fixes the failure, or %{linkStart}learn about other solutions.%{linkEnd}"
+msgstr ""
+
msgid "mrWidget|Merge blocked: this merge request must be approved."
msgstr ""
@@ -43874,9 +44750,6 @@ msgstr ""
msgid "mrWidget|The changes were not merged into"
msgstr ""
-msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -44024,9 +44897,6 @@ msgstr ""
msgid "open issue"
msgstr ""
-msgid "opened %{timeAgo}"
-msgstr ""
-
msgid "or"
msgstr ""
@@ -44041,6 +44911,12 @@ msgstr[2] ""
msgstr[3] ""
msgstr[4] ""
+msgid "packages"
+msgstr ""
+
+msgid "pages"
+msgstr ""
+
msgid "parent"
msgid_plural "parents"
msgstr[0] ""
@@ -44202,6 +45078,9 @@ msgstr[2] ""
msgstr[3] ""
msgstr[4] ""
+msgid "repositories"
+msgstr ""
+
msgid "repository:"
msgstr ""
@@ -44322,12 +45201,18 @@ msgstr ""
msgid "tag name"
msgstr ""
+msgid "terraform states"
+msgstr ""
+
msgid "the correct format."
msgstr ""
msgid "the file"
msgstr ""
+msgid "the following epic(s)"
+msgstr ""
+
msgid "the following issue(s)"
msgstr ""
@@ -44340,21 +45225,12 @@ msgstr ""
msgid "this document"
msgstr ""
-msgid "this issue cannot be assigned to a confidential epic since it is public"
-msgstr ""
-
-msgid "this issue cannot be made public since it belongs to a confidential epic"
-msgstr ""
-
msgid "time summary"
msgstr ""
msgid "toggle collapse"
msgstr ""
-msgid "train"
-msgstr ""
-
msgid "triggered"
msgstr ""
@@ -44486,3 +45362,6 @@ msgstr ""
msgid "{project}"
msgstr ""
+msgid "✔"
+msgstr ""
+
diff --git a/locale/bs_BA/gitlab.po b/locale/bs_BA/gitlab.po
index a4c8c348b1c..f4fdf182538 100644
--- a/locale/bs_BA/gitlab.po
+++ b/locale/bs_BA/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: bs\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2022-02-02 15:48\n"
+"PO-Revision-Date: 2022-03-01 20:41\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -160,6 +160,12 @@ msgstr[0] "%d odobravatelj (ti si odobrio/la)"
msgstr[1] "%d odobravatelja (ti si odobrio/la)"
msgstr[2] "%d odobravatelja (ti si odobrio/la)"
+msgid "%d assigned issue"
+msgid_plural "%d assigned issues"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -490,8 +496,26 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
-msgid "%d vulnerability updated"
-msgid_plural "%d vulnerabilities updated"
+msgid "%d vulnerability set to confirmed"
+msgid_plural "%d vulnerabilities set to confirmed"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
+msgid "%d vulnerability set to dismissed"
+msgid_plural "%d vulnerabilities set to dismissed"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
+msgid "%d vulnerability set to needs triage"
+msgid_plural "%d vulnerabilities set to needs triage"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
+msgid "%d vulnerability set to resolved"
+msgid_plural "%d vulnerabilities set to resolved"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
@@ -586,6 +610,12 @@ msgstr[2] ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{completed} of %{total} issues closed"
+msgstr ""
+
+msgid "%{completed} of %{total} weight completed"
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -940,6 +970,9 @@ msgstr "%{openedEpics} otvoreno, %{closedEpics} zatvoreno"
msgid "%{openedIssues} open, %{closedIssues} closed"
msgstr "%{openedIssues} otvoreno, %{closedIssues} zatvoreno"
+msgid "%{percentage}%% issues closed"
+msgstr ""
+
msgid "%{percentage}%% weight completed"
msgstr ""
@@ -1384,6 +1417,9 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
+msgid "- of - issues closed"
+msgstr ""
+
msgid "- of - weight completed"
msgstr ""
@@ -1549,7 +1585,7 @@ msgstr ""
msgid "1000+"
msgstr ""
-msgid "192.168.0.0/24"
+msgid "192.168.0.0/24 or 2001:0DB8:1234::/48"
msgstr ""
msgid "1st contribution!"
@@ -1861,13 +1897,13 @@ msgstr ""
msgid "AWS Access Key"
msgstr ""
-msgid "AWS Access Key. Only required if not using role instance credentials"
+msgid "AWS Secret Access Key"
msgstr ""
-msgid "AWS Secret Access Key"
+msgid "AWS access key ID (Optional)"
msgstr ""
-msgid "AWS Secret Access Key. Only required if not using role instance credentials"
+msgid "AWS secret access key (Optional)"
msgstr ""
msgid "AWS service error: %{error}"
@@ -1927,9 +1963,6 @@ msgstr ""
msgid "Access granted"
msgstr ""
-msgid "Access key ID"
-msgstr ""
-
msgid "Access requests"
msgstr ""
@@ -2104,7 +2137,7 @@ msgstr ""
msgid "Activity"
msgstr ""
-msgid "Activity|An error occured while retrieving activity. Reload the page to try again."
+msgid "Activity|An error occurred while retrieving activity. Reload the page to try again."
msgstr ""
msgid "Add"
@@ -2143,6 +2176,9 @@ msgstr ""
msgid "Add a %{type}"
msgstr ""
+msgid "Add a GCP region"
+msgstr ""
+
msgid "Add a GPG key"
msgstr ""
@@ -2194,6 +2230,9 @@ msgstr ""
msgid "Add a numbered list"
msgstr ""
+msgid "Add a related epic"
+msgstr ""
+
msgid "Add a related issue"
msgstr ""
@@ -2308,6 +2347,9 @@ msgstr ""
msgid "Add or subtract spent time"
msgstr ""
+msgid "Add people"
+msgstr ""
+
msgid "Add previously merged commits"
msgstr ""
@@ -2374,6 +2416,9 @@ msgstr ""
msgid "Add webhook"
msgstr ""
+msgid "Add your team members and others to GitLab."
+msgstr ""
+
msgid "Add/remove"
msgstr ""
@@ -3196,12 +3241,6 @@ msgstr ""
msgid "AdvancedSearch|Reindex required"
msgstr ""
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. Permanently deleting this project will %{strongStart}immediately delete%{strongEnd} its repositories and %{strongStart}all related resources%{strongEnd}, including issues, merge requests etc."
-msgstr ""
-
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. You will lose this project's repository and %{strongStart}all related resources%{strongEnd}, including issues and merge requests."
-msgstr ""
-
msgid "After a successful password update you will be redirected to login screen."
msgstr ""
@@ -3232,6 +3271,9 @@ msgstr ""
msgid "Akismet helps prevent the creation of spam issues in public projects."
msgstr ""
+msgid "Alert"
+msgstr ""
+
msgid "AlertManagement|Acknowledged"
msgstr ""
@@ -3604,9 +3646,6 @@ msgstr ""
msgid "All environments"
msgstr ""
-msgid "All epics"
-msgstr ""
-
msgid "All groups and projects"
msgstr ""
@@ -4345,13 +4384,16 @@ msgstr ""
msgid "ApplicationSettings|Approve users in the pending approval status?"
msgstr ""
-msgid "ApplicationSettings|By making this change, you will automatically approve %d user with the pending approval status."
-msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users with the pending approval status."
+msgid "ApplicationSettings|Approve users who are pending approval?"
+msgstr ""
+
+msgid "ApplicationSettings|By making this change, you will automatically approve %d user who is pending approval."
+msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users who are pending approval."
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
-msgid "ApplicationSettings|By making this change, you will automatically approve all users in pending approval status."
+msgid "ApplicationSettings|By making this change, you will automatically approve all users who are pending approval."
msgstr ""
msgid "ApplicationSettings|Denied domains for sign-ups"
@@ -4762,10 +4804,10 @@ msgstr ""
msgid "Archiving the project will make it entirely read-only. It is hidden from the dashboard and doesn't show up in searches. %{strong_start}The repository cannot be committed to, and no issues, comments, or other entities can be created.%{strong_end} %{link_start}Learn more.%{link_end}"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to delete this project?"
+msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
+msgid "Are you absolutely sure?"
msgstr ""
msgid "Are you sure that you want to archive this project?"
@@ -4801,12 +4843,18 @@ msgstr ""
msgid "Are you sure you want to delete this SSH key?"
msgstr ""
+msgid "Are you sure you want to delete this comment?"
+msgstr ""
+
msgid "Are you sure you want to delete this deploy key?"
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 label?"
+msgstr ""
+
msgid "Are you sure you want to delete this pipeline schedule?"
msgstr ""
@@ -4822,9 +4870,6 @@ msgstr ""
msgid "Are you sure you want to discard your changes?"
msgstr ""
-msgid "Are you sure you want to erase this build?"
-msgstr ""
-
msgid "Are you sure you want to import %d repository?"
msgid_plural "Are you sure you want to import %d repositories?"
msgstr[0] ""
@@ -4873,6 +4918,9 @@ msgstr ""
msgid "Are you sure you want to remove this list?"
msgstr ""
+msgid "Are you sure you want to remove this nickname?"
+msgstr ""
+
msgid "Are you sure you want to reset the health check token?"
msgstr ""
@@ -4885,10 +4933,10 @@ 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?"
+msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
msgstr ""
-msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
+msgid "Are you sure you want to revoke this project access token? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to stop this environment?"
@@ -5035,9 +5083,6 @@ msgstr ""
msgid "Assigned to %{assignee_name}"
msgstr ""
-msgid "Assigned to %{name}"
-msgstr ""
-
msgid "Assigned to me"
msgstr ""
@@ -5104,6 +5149,9 @@ msgstr[2] ""
msgid "Attaching the file failed."
msgstr ""
+msgid "Attention"
+msgstr ""
+
msgid "Audit Events"
msgstr ""
@@ -5266,6 +5314,12 @@ msgstr ""
msgid "Authorized applications (%{size})"
msgstr ""
+msgid "AuthorizedApplication|Are you sure you want to revoke this application?"
+msgstr ""
+
+msgid "AuthorizedApplication|Revoke application"
+msgstr ""
+
msgid "Authors: %{authors}"
msgstr ""
@@ -6463,6 +6517,9 @@ msgstr ""
msgid "CICDAnalytics|Shared Runners Usage"
msgstr ""
+msgid "CICDAnalytics|Shared runner pipeline minute duration by month"
+msgstr ""
+
msgid "CICDAnalytics|Shared runner usage"
msgstr ""
@@ -6604,6 +6661,9 @@ msgstr ""
msgid "Can create groups:"
msgstr ""
+msgid "Can not delete primary training"
+msgstr ""
+
msgid "Can't apply as the source branch was deleted."
msgstr ""
@@ -6937,9 +6997,6 @@ msgstr ""
msgid "Changing any setting here requires an application restart"
msgstr ""
-msgid "Changing group URL can have unintended side effects."
-msgstr ""
-
msgid "Charts can't be displayed as the request for data has timed out. %{documentationLink}"
msgstr ""
@@ -7027,9 +7084,6 @@ msgstr ""
msgid "Checking branch availability..."
msgstr ""
-msgid "Checking group URL availability..."
-msgstr ""
-
msgid "Checking group path availability..."
msgstr ""
@@ -7525,6 +7579,9 @@ msgstr ""
msgid "Clear recent searches"
msgstr ""
+msgid "Clear repository checks"
+msgstr ""
+
msgid "Clear search"
msgstr ""
@@ -7657,9 +7714,6 @@ msgstr ""
msgid "Closed MRs"
msgstr ""
-msgid "Closed epics"
-msgstr ""
-
msgid "Closed issues"
msgstr "Zatvoreni zadaci"
@@ -7696,13 +7750,13 @@ msgstr ""
msgid "Cluster level"
msgstr ""
-msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
+msgid "Cluster type must be specified for Stages::ClusterEndpointInserter"
msgstr ""
msgid "ClusterAgents|%{name} successfully deleted"
msgstr ""
-msgid "ClusterAgents|%{number} of %{total} Agents"
+msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
@@ -7744,6 +7798,15 @@ msgstr ""
msgid "ClusterAgents|Agent never connected to GitLab"
msgstr ""
+msgid "ClusterAgents|Agent version mismatch"
+msgstr ""
+
+msgid "ClusterAgents|Agent version mismatch and update"
+msgstr ""
+
+msgid "ClusterAgents|Agent version update required"
+msgstr ""
+
msgid "ClusterAgents|All"
msgstr ""
@@ -7768,7 +7831,7 @@ msgstr ""
msgid "ClusterAgents|Configuration"
msgstr ""
-msgid "ClusterAgents|Connect a cluster through the Agent"
+msgid "ClusterAgents|Connect a cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connect existing cluster"
@@ -7777,13 +7840,13 @@ msgstr ""
msgid "ClusterAgents|Connect with a certificate"
msgstr ""
-msgid "ClusterAgents|Connect with agent"
+msgid "ClusterAgents|Connect with an agent"
msgstr ""
msgid "ClusterAgents|Connect with the GitLab Agent"
msgstr ""
-msgid "ClusterAgents|Connect your cluster through the Agent"
+msgid "ClusterAgents|Connect your cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connected"
@@ -7843,7 +7906,10 @@ msgstr ""
msgid "ClusterAgents|How to register an agent?"
msgstr ""
-msgid "ClusterAgents|Install new Agent"
+msgid "ClusterAgents|How to update an agent?"
+msgstr ""
+
+msgid "ClusterAgents|Install a new agent"
msgstr ""
msgid "ClusterAgents|Last connected %{timeAgo}."
@@ -7870,7 +7936,7 @@ msgstr ""
msgid "ClusterAgents|Never connected"
msgstr ""
-msgid "ClusterAgents|No Agents"
+msgid "ClusterAgents|No agents"
msgstr ""
msgid "ClusterAgents|No clusters connected through cluster certificates"
@@ -7930,6 +7996,9 @@ msgstr ""
msgid "ClusterAgents|The agent has not been connected in a long time. There might be a connectivity issue. Last contact was %{timeAgo}."
msgstr ""
+msgid "ClusterAgents|The agent version do not match each other across your cluster's pods. This can happen when a new agent version was just deployed and Kubernetes is shutting down the old pods."
+msgstr ""
+
msgid "ClusterAgents|The recommended installation method includes the token. If you want to follow the advanced installation method provided in the docs, make sure you save the token value before you close this window."
msgstr ""
@@ -7978,6 +8047,9 @@ msgstr ""
msgid "ClusterAgents|You will need to create a token to connect to your agent"
msgstr ""
+msgid "ClusterAgents|Your agent version is out of sync with your GitLab version (v%{version}), which might cause compatibility problems. Update the agent installed on your cluster to the most recent version."
+msgstr ""
+
msgid "ClusterAgents|Your instance doesn't have the %{linkStart}GitLab Agent Server (KAS)%{linkEnd} set up. Ask a GitLab Administrator to install it."
msgstr ""
@@ -8854,9 +8926,6 @@ msgstr ""
msgid "Comma-separated list of email addresses."
msgstr ""
-msgid "Comma-separated list of users allowed to exceed the rate limit."
-msgstr ""
-
msgid "Comma-separated, e.g. '1.1.1.1, 2.2.2.0/24'"
msgstr ""
@@ -9184,6 +9253,12 @@ msgstr ""
msgid "Confidential"
msgstr ""
+msgid "Confidential issue"
+msgstr ""
+
+msgid "Confidential note"
+msgstr ""
+
msgid "Confidentiality"
msgstr ""
@@ -9217,6 +9292,9 @@ msgstr ""
msgid "Configure Dependency Scanning in `.gitlab-ci.yml`, creating this file if it does not already exist"
msgstr ""
+msgid "Configure GitLab"
+msgstr ""
+
msgid "Configure GitLab runners to start using the Web Terminal. %{helpStart}Learn more.%{helpEnd}"
msgstr ""
@@ -9265,6 +9343,15 @@ msgstr ""
msgid "Configure pipelines to deploy web apps, backend services, APIs and static resources to Google Cloud"
msgstr ""
+msgid "Configure region"
+msgstr ""
+
+msgid "Configure region for environment"
+msgstr ""
+
+msgid "Configure regions"
+msgstr ""
+
msgid "Configure repository mirroring."
msgstr ""
@@ -9298,6 +9385,9 @@ msgstr ""
msgid "Configure which lists are shown for anyone who visits this board"
msgstr ""
+msgid "Configure your environments to be deployed to specific geographical regions"
+msgstr ""
+
msgid "Confirm"
msgstr ""
@@ -10003,10 +10093,10 @@ msgstr ""
msgid "CorpusManagement|Actions"
msgstr ""
-msgid "CorpusManagement|Corpus are used in fuzz testing as mutation source to Improve future testing."
+msgid "CorpusManagement|Corpus file"
msgstr ""
-msgid "CorpusManagement|Corpus file"
+msgid "CorpusManagement|Corpus files are used in coverage-guided fuzz testing as seed inputs to improve testing."
msgstr ""
msgid "CorpusManagement|Corpus files must be in *.zip format. Maximum 5 GB"
@@ -10060,6 +10150,9 @@ msgstr ""
msgid "Could not apply %{name} command."
msgstr ""
+msgid "Could not apply %{name} command. %{message}."
+msgstr ""
+
msgid "Could not authorize chat nickname. Try again!"
msgstr ""
@@ -10210,6 +10303,9 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
+msgid "Create a group"
+msgstr ""
+
msgid "Create a merge request"
msgstr ""
@@ -10234,6 +10330,9 @@ msgstr ""
msgid "Create a personal access token on your account to pull or push via %{protocol}."
msgstr ""
+msgid "Create a project"
+msgstr ""
+
msgid "Create an account using:"
msgstr ""
@@ -10597,6 +10696,9 @@ msgstr ""
msgid "Creation date"
msgstr ""
+msgid "Creator"
+msgstr ""
+
msgid "Credentials"
msgstr ""
@@ -10609,9 +10711,15 @@ msgstr ""
msgid "CredentialsInventory|Personal Access Tokens"
msgstr ""
+msgid "CredentialsInventory|Project Access Tokens"
+msgstr ""
+
msgid "CredentialsInventory|SSH Keys"
msgstr ""
+msgid "Credit card required to be on file in order to create a pipeline"
+msgstr ""
+
msgid "Credit card:"
msgstr ""
@@ -10795,9 +10903,6 @@ msgstr ""
msgid "Customer relations"
msgstr ""
-msgid "Customizable by an administrator."
-msgstr ""
-
msgid "Customizable by owners."
msgstr ""
@@ -10927,30 +11032,18 @@ msgstr ""
msgid "CycleAnalytics|%{selectedLabelsCount} selected (%{maxLabels} max)"
msgstr ""
-msgid "CycleAnalytics|%{stageCount} stages selected"
-msgstr ""
-
-msgid "CycleAnalytics|All stages"
-msgstr ""
-
-msgid "CycleAnalytics|Average days to completion"
+msgid "CycleAnalytics|Average time to completion"
msgstr ""
msgid "CycleAnalytics|Date"
msgstr ""
-msgid "CycleAnalytics|Days to completion"
-msgstr ""
-
msgid "CycleAnalytics|Display chart filters"
msgstr ""
msgid "CycleAnalytics|Lead Time for Changes"
msgstr ""
-msgid "CycleAnalytics|No stages selected"
-msgstr ""
-
msgid "CycleAnalytics|Number of tasks"
msgstr ""
@@ -10981,18 +11074,30 @@ msgstr ""
msgid "CycleAnalytics|Showing data for group '%{groupName}' from %{createdAfter} to %{createdBefore}"
msgstr ""
-msgid "CycleAnalytics|Stages"
+msgid "CycleAnalytics|Stage time: %{title}"
msgstr ""
msgid "CycleAnalytics|Tasks by type"
msgstr ""
-msgid "CycleAnalytics|The average time spent in the selected stage for the items that were completed on each date. Data limited to the last 500 items."
+msgid "CycleAnalytics|The average time items spent in this stage. Data limited to items completed within this date range."
msgstr ""
msgid "CycleAnalytics|The given date range is larger than 180 days"
msgstr ""
+msgid "CycleAnalytics|The total time items spent across each value stream stage. Data limited to items completed within this date range."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Stage time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Total time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|Total time"
+msgstr ""
+
msgid "CycleAnalytics|Type of work"
msgstr ""
@@ -11005,9 +11110,6 @@ msgstr ""
msgid "CycleAnalytics|project dropdown filter"
msgstr ""
-msgid "CycleAnalytics|stage dropdown"
-msgstr ""
-
msgid "DAG visualization requires at least 3 dependent jobs."
msgstr ""
@@ -11107,10 +11209,16 @@ msgstr ""
msgid "DastProfiles|AJAX spider"
msgstr ""
+msgid "DastProfiles|API"
+msgstr ""
+
+msgid "DastProfiles|API endpoint URL"
+msgstr ""
+
msgid "DastProfiles|Active"
msgstr ""
-msgid "DastProfiles|Additional request headers (Optional)"
+msgid "DastProfiles|Additional request headers (optional)"
msgstr ""
msgid "DastProfiles|Are you sure you want to delete this profile?"
@@ -11125,6 +11233,9 @@ msgstr ""
msgid "DastProfiles|Branch missing"
msgstr ""
+msgid "DastProfiles|Choose a scan method"
+msgstr ""
+
msgid "DastProfiles|Could not create the scanner profile. Please try again."
msgstr ""
@@ -11194,7 +11305,13 @@ msgstr ""
msgid "DastProfiles|Excluded URLs"
msgstr ""
-msgid "DastProfiles|Excluded URLs (Optional)"
+msgid "DastProfiles|Excluded URLs (optional)"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths (optional)"
msgstr ""
msgid "DastProfiles|Hide debug messages"
@@ -11251,9 +11368,6 @@ msgstr ""
msgid "DastProfiles|Request headers"
msgstr ""
-msgid "DastProfiles|Rest API"
-msgstr ""
-
msgid "DastProfiles|Run the AJAX spider, in addition to the traditional spider, to crawl the target site."
msgstr ""
@@ -11263,6 +11377,9 @@ msgstr ""
msgid "DastProfiles|Save profile"
msgstr ""
+msgid "DastProfiles|Scan method"
+msgstr ""
+
msgid "DastProfiles|Scan mode"
msgstr ""
@@ -11341,12 +11458,24 @@ msgstr ""
msgid "DastProfiles|Website"
msgstr ""
+msgid "DastProfiles|What does each method do?"
+msgstr ""
+
msgid "DastProfiles|You can either choose a passive scan or validate the target site from the site profile management page. %{docsLinkStart}Learn more about site validation.%{docsLinkEnd}"
msgstr ""
msgid "DastProfiles|You cannot run an active scan against an unvalidated site."
msgstr ""
+msgid "DastProfiles|folder/dast_example.har or https://example.com/dast_example.har"
+msgstr ""
+
+msgid "DastProfiles|folder/example.postman_collection.json or https://example.com/"
+msgstr ""
+
+msgid "DastProfiles|folder/openapi.json or https://example.com/openapi.json"
+msgstr ""
+
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
@@ -11455,6 +11584,9 @@ msgstr ""
msgid "DatadogIntegration|API URL"
msgstr ""
+msgid "DatadogIntegration|Custom tags in Datadog. Enter one tag per line in the %{codeOpen}key:value%{codeClose} format. %{linkOpen}How do I use tags?%{linkClose}"
+msgstr ""
+
msgid "DatadogIntegration|Environment"
msgstr ""
@@ -11473,12 +11605,18 @@ msgstr ""
msgid "DatadogIntegration|Tag all data from this GitLab instance in Datadog. Useful when managing several self-managed deployments."
msgstr ""
+msgid "DatadogIntegration|Tags"
+msgstr ""
+
msgid "DatadogIntegration|The Datadog site to send data to. To send data to the EU site, use %{codeOpen}datadoghq.eu%{codeClose}."
msgstr ""
msgid "DatadogIntegration|Trace your GitLab pipelines with Datadog."
msgstr ""
+msgid "DatadogIntegration|have an invalid format"
+msgstr ""
+
msgid "Datasource name not found"
msgstr ""
@@ -11488,9 +11626,6 @@ msgstr ""
msgid "Date merged"
msgstr ""
-msgid "Date picker"
-msgstr ""
-
msgid "Date range"
msgstr ""
@@ -11644,9 +11779,6 @@ msgstr ""
msgid "Definition"
msgstr ""
-msgid "Delayed Project Deletion (%{adjourned_deletion})"
-msgstr ""
-
msgid "DelayedJobs|Are you sure you want to run %{jobName} immediately? Otherwise this job will run automatically after its timer finishes."
msgstr ""
@@ -11725,10 +11857,10 @@ msgstr ""
msgid "Delete pipeline"
msgstr ""
-msgid "Delete project"
+msgid "Delete pipeline schedule"
msgstr ""
-msgid "Delete project. Are you ABSOLUTELY SURE?"
+msgid "Delete project"
msgstr ""
msgid "Delete row"
@@ -11758,6 +11890,9 @@ msgstr ""
msgid "Delete this epic and all descendants?"
msgstr ""
+msgid "Delete this project"
+msgstr ""
+
msgid "Delete user list"
msgstr ""
@@ -12022,6 +12157,12 @@ msgstr ""
msgid "Deploy to..."
msgstr ""
+msgid "DeployBoards|To see deployment progress for your environments, make sure you are deploying to %{codeStart}$KUBE_NAMESPACE%{codeEnd} and annotating with %{codeStart}app.gitlab.com/app=$CI_PROJECT_PATH_SLUG%{codeEnd} and %{codeStart}app.gitlab.com/env=$CI_ENVIRONMENT_SLUG%{codeEnd}."
+msgstr ""
+
+msgid "DeployBoard|Kubernetes Pods"
+msgstr ""
+
msgid "DeployFreeze|Add a freeze period to prevent unintended releases during a period of time for a given environment. You must update the deployment jobs in %{filename} according to the deploy freezes added here. %{freeze_period_link_start}Learn more.%{freeze_period_link_end}"
msgstr ""
@@ -12106,9 +12247,6 @@ msgstr ""
msgid "DeployTokens|Active Deploy Tokens (%{active_tokens})"
msgstr ""
-msgid "DeployTokens|Allows read and write access to registry images."
-msgstr ""
-
msgid "DeployTokens|Allows read and write access to the package registry."
msgstr ""
@@ -12121,6 +12259,9 @@ msgstr ""
msgid "DeployTokens|Allows read-only access to the repository."
msgstr ""
+msgid "DeployTokens|Allows write access to registry images."
+msgstr ""
+
msgid "DeployTokens|Copy deploy token"
msgstr ""
@@ -12214,12 +12355,57 @@ msgstr ""
msgid "Deploying to AWS is easy with GitLab"
msgstr ""
+msgid "Deployment"
+msgstr ""
+
msgid "Deployment Frequency"
msgstr ""
+msgid "Deployment Target|Project deployment target (optional)"
+msgstr ""
+
+msgid "Deployment Target|Select the deployment target"
+msgstr ""
+
msgid "Deployment frequency"
msgstr ""
+msgid "DeploymentTarget|GitLab Pages"
+msgstr ""
+
+msgid "DeploymentTarget|Heroku"
+msgstr ""
+
+msgid "DeploymentTarget|Infrastructure provider (Terraform, Cloudformation, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Kubernetes (GKE, EKS, OpenShift, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Managed container runtime (Fargate, Cloud Run, DigitalOcean App)"
+msgstr ""
+
+msgid "DeploymentTarget|Mobile app store"
+msgstr ""
+
+msgid "DeploymentTarget|No deployment planned"
+msgstr ""
+
+msgid "DeploymentTarget|Other hosting service"
+msgstr ""
+
+msgid "DeploymentTarget|Registry (package or container)"
+msgstr ""
+
+msgid "DeploymentTarget|Self-managed container runtime (Podman, Docker Swarm, Docker Compose)"
+msgstr ""
+
+msgid "DeploymentTarget|Serverless backend (Lambda, Cloud functions)"
+msgstr ""
+
+msgid "DeploymentTarget|Virtual machine (for example, EC2)"
+msgstr ""
+
msgid "Deployments"
msgstr ""
@@ -12259,6 +12445,9 @@ msgstr ""
msgid "Deployment|This deployment was created using the API"
msgstr ""
+msgid "Deployment|Triggerer"
+msgstr ""
+
msgid "Deployment|Waiting"
msgstr ""
@@ -12286,6 +12475,18 @@ msgstr ""
msgid "Deprecated API rate limits"
msgstr ""
+msgid "Deprecations|Feature deprecation and removal"
+msgstr ""
+
+msgid "Deprecations|For information on a possible replacement %{epicStart} learn more about Opstrace %{epicEnd}."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7 and are %{epicStart} scheduled for removal %{epicEnd} in GitLab 15.0."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7, and are %{removal_link_start} scheduled for removal %{link_end} in GitLab 15.0. For information on a possible replacement, %{opstrace_link_start} learn more about Opstrace %{link_end}."
+msgstr ""
+
msgid "Deprioritize label"
msgstr ""
@@ -12532,10 +12733,10 @@ msgstr ""
msgid "DevopsAdoption|At least one deploy"
msgstr ""
-msgid "DevopsAdoption|At least one issue opened"
+msgid "DevopsAdoption|At least one issue created"
msgstr ""
-msgid "DevopsAdoption|At least one merge request opened"
+msgid "DevopsAdoption|At least one merge request created"
msgstr ""
msgid "DevopsAdoption|At least one pipeline successfully run"
@@ -12739,6 +12940,9 @@ msgstr ""
msgid "Direct member"
msgstr ""
+msgid "Direct members"
+msgstr ""
+
msgid "Direct non-authenticated users to this page."
msgstr ""
@@ -12856,6 +13060,9 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
+msgid "Dismiss Alert"
+msgstr ""
+
msgid "Dismiss merge request promotion"
msgstr ""
@@ -12883,9 +13090,15 @@ msgstr ""
msgid "Display alerts from all configured monitoring tools."
msgstr ""
+msgid "Display milestones"
+msgstr ""
+
msgid "Display name"
msgstr ""
+msgid "Display progress of child issues"
+msgstr ""
+
msgid "Display rendered file"
msgstr ""
@@ -12991,6 +13204,9 @@ msgstr ""
msgid "Download image"
msgstr ""
+msgid "Download payload"
+msgstr ""
+
msgid "Download raw data (.csv)"
msgstr ""
@@ -13168,6 +13384,9 @@ msgstr ""
msgid "Edit in Web IDE"
msgstr ""
+msgid "Edit in pipeline editor"
+msgstr ""
+
msgid "Edit in single-file editor"
msgstr ""
@@ -13210,6 +13429,9 @@ msgstr ""
msgid "Edit your most recent comment in a thread (from an empty textarea)"
msgstr ""
+msgid "Edit, lint, and visualize your pipeline."
+msgstr ""
+
msgid "Edited"
msgstr ""
@@ -13651,6 +13873,9 @@ msgstr ""
msgid "Enforce two-factor authentication for all user sign-ins."
msgstr ""
+msgid "Enhance security by storing service account keys in secret managers - learn more about %{docLinkStart}secret management with GitLab%{docLinkEnd}"
+msgstr ""
+
msgid "Ensure connectivity is available from the GitLab server to the Prometheus server"
msgstr ""
@@ -13711,6 +13936,9 @@ 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 following to confirm:"
+msgstr ""
+
msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
@@ -14242,9 +14470,6 @@ 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 ""
@@ -14380,6 +14605,9 @@ msgstr ""
msgid "Errors:"
msgstr ""
+msgid "Escalate this incident"
+msgstr ""
+
msgid "Escalation Policies"
msgstr ""
@@ -14392,6 +14620,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy"
+msgstr ""
+
msgid "Escalation policy:"
msgstr ""
@@ -14644,6 +14875,9 @@ msgstr ""
msgid "Existing sign in methods may be removed"
msgstr ""
+msgid "Exit."
+msgstr ""
+
msgid "Expand"
msgstr ""
@@ -14740,6 +14974,9 @@ msgstr ""
msgid "Explore public groups"
msgstr ""
+msgid "Explore public projects"
+msgstr ""
+
msgid "Explore snippets"
msgstr ""
@@ -14902,7 +15139,7 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
-msgid "Failed to assign a reviewer because no user was found."
+msgid "Failed to assign a reviewer because no user was specified."
msgstr ""
msgid "Failed to assign a user because no user was found."
@@ -14968,10 +15205,10 @@ msgstr ""
msgid "Failed to find import label for Jira import."
msgstr ""
-msgid "Failed to generate export, please try again later."
+msgid "Failed to find users for %{missing}"
msgstr ""
-msgid "Failed to generate report, please try again after sometime"
+msgid "Failed to generate export, please try again later."
msgstr ""
msgid "Failed to get ref."
@@ -15070,6 +15307,9 @@ msgstr ""
msgid "Failed to remove a to-do item for the design."
msgstr ""
+msgid "Failed to remove attention because no user was found."
+msgstr ""
+
msgid "Failed to remove mirror."
msgstr ""
@@ -15082,6 +15322,9 @@ msgstr ""
msgid "Failed to remove user key."
msgstr ""
+msgid "Failed to request attention because no user was found."
+msgstr ""
+
msgid "Failed to reset key. Please try again."
msgstr ""
@@ -15163,6 +15406,9 @@ msgstr ""
msgid "Feature Flags"
msgstr ""
+msgid "Feature deprecation and removal"
+msgstr ""
+
msgid "Feature flag status"
msgstr ""
@@ -15661,7 +15907,7 @@ msgstr ""
msgid "For each job, re-use the project workspace. If the workspace doesn't exist, use %{code_open}git clone%{code_close}."
msgstr ""
-msgid "For example, the application using the token or the purpose of the token."
+msgid "For example, the application using the token or the purpose of the token. Do not give sensitive information for the name of the token, as it will be visible to all %{resource_type} members."
msgstr ""
msgid "For files larger than this limit, only index the file name. The file content is neither indexed nor searchable."
@@ -15745,9 +15991,6 @@ msgstr ""
msgid "ForkProject|Select a namespace"
msgstr ""
-msgid "ForkProject|Select a namespace to fork the project"
-msgstr ""
-
msgid "ForkProject|The project can be accessed by any logged in user."
msgstr ""
@@ -15844,6 +16087,9 @@ msgstr ""
msgid "Full name"
msgstr ""
+msgid "GCP region configured"
+msgstr ""
+
msgid "GPG Key ID:"
msgstr ""
@@ -16024,6 +16270,9 @@ msgstr ""
msgid "Geo|Failed"
msgstr ""
+msgid "Geo|Filter Geo sites"
+msgstr ""
+
msgid "Geo|Filter by name"
msgstr ""
@@ -16435,6 +16684,12 @@ msgstr ""
msgid "GitLab Issue"
msgstr "GitLab Zadatak"
+msgid "GitLab KAS"
+msgstr ""
+
+msgid "GitLab Memberships CSV Export"
+msgstr ""
+
msgid "GitLab Pages"
msgstr ""
@@ -16483,6 +16738,9 @@ 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 free to use. Many features for larger teams are part of our %{link_start}paid products%{link_end}. You can try Ultimate for free without any obligation or payment details."
+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 ""
@@ -16609,7 +16867,7 @@ msgstr ""
msgid "GitLabPages|When enabled, all attempts to visit your website through HTTP are automatically redirected to HTTPS using a response with status code 301. Requires a valid certificate for all domains. %{docs_link_start}Learn more.%{link_end}"
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. %{docs_link_start}Learn more.%{link_end}"
+msgid "GitLabPages|When using Pages under the general domain of a GitLab instance (%{pages_host}), you cannot use HTTPS with subdomains of subdomains. If your namespace or groupname contains a dot, it does not work. This is a limitation of the HTTP Over TLS protocol. HTTP pages work if you don't redirect HTTP to HTTPS. %{docs_link_start}Learn more.%{link_end}"
msgstr ""
msgid "GitLabPages|With GitLab Pages you can host your static website directly from your GitLab repository. %{docs_link_start}Learn more.%{link_end}"
@@ -16786,9 +17044,6 @@ msgstr ""
msgid "Go to find file"
msgstr ""
-msgid "Go to fork"
-msgstr ""
-
msgid "Go to issue boards"
msgstr "Idi na table sa zadacima"
@@ -16996,9 +17251,6 @@ msgstr ""
msgid "Group Hooks"
msgstr ""
-msgid "Group ID"
-msgstr ""
-
msgid "Group Owner must have signed in with SAML before enabling Group Managed Accounts"
msgstr ""
@@ -17026,9 +17278,6 @@ msgstr ""
msgid "Group by"
msgstr ""
-msgid "Group description"
-msgstr ""
-
msgid "Group description (optional)"
msgstr ""
@@ -17143,7 +17392,7 @@ msgstr ""
msgid "Group: %{name}"
msgstr ""
-msgid "GroupActivityMetrics|Issues opened"
+msgid "GroupActivityMetrics|Issues created"
msgstr ""
msgid "GroupActivityMetrics|Last 90 days"
@@ -17152,7 +17401,7 @@ msgstr ""
msgid "GroupActivityMetrics|Members added"
msgstr ""
-msgid "GroupActivityMetrics|Merge Requests opened"
+msgid "GroupActivityMetrics|Merge Requests created"
msgstr ""
msgid "GroupActivityMetrics|Recent activity"
@@ -17443,6 +17692,9 @@ msgstr ""
msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
+msgid "GroupSettings|Choose a group path that does not start with a dash or end with a period. It can also contain alphanumeric characters and underscores."
+msgstr ""
+
msgid "GroupSettings|Compliance frameworks"
msgstr ""
@@ -17476,7 +17728,7 @@ msgstr ""
msgid "GroupSettings|If not specified at the group or instance level, the default is %{default_initial_branch_name}. Does not affect existing repositories."
msgstr ""
-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."
+msgid "GroupSettings|If the parent group's visibility is lower than the group's current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility."
msgstr ""
msgid "GroupSettings|New runners registration token has been generated!"
@@ -17593,7 +17845,10 @@ msgstr ""
msgid "Groups and projects"
msgstr ""
-msgid "Groups and subgroups"
+msgid "Groups are a great way to organize projects and people."
+msgstr ""
+
+msgid "Groups are the best way to manage projects and members."
msgstr ""
msgid "Groups to synchronize"
@@ -17704,13 +17959,16 @@ msgstr ""
msgid "GroupsTree|Are you sure you want to leave the \"%{fullName}\" group?"
msgstr ""
-msgid "GroupsTree|Edit group"
+msgid "GroupsTree|Delete"
+msgstr ""
+
+msgid "GroupsTree|Edit"
msgstr ""
msgid "GroupsTree|Failed to leave the group. Please make sure you are not the only owner."
msgstr ""
-msgid "GroupsTree|Leave this group"
+msgid "GroupsTree|Leave group"
msgstr ""
msgid "GroupsTree|Loading groups"
@@ -17722,9 +17980,57 @@ msgstr ""
msgid "GroupsTree|No groups or projects matched your search"
msgstr ""
+msgid "GroupsTree|Options"
+msgstr ""
+
msgid "GroupsTree|Search by name"
msgstr ""
+msgid "Groups|Avatar will be removed. Are you sure?"
+msgstr ""
+
+msgid "Groups|Changing group URL can have unintended side effects."
+msgstr ""
+
+msgid "Groups|Checking group URL availability..."
+msgstr ""
+
+msgid "Groups|Enter a descriptive name for your group."
+msgstr ""
+
+msgid "Groups|Group ID"
+msgstr ""
+
+msgid "Groups|Group URL"
+msgstr ""
+
+msgid "Groups|Group avatar"
+msgstr ""
+
+msgid "Groups|Group description (optional)"
+msgstr ""
+
+msgid "Groups|Group name"
+msgstr ""
+
+msgid "Groups|Group path is available."
+msgstr ""
+
+msgid "Groups|Group path is unavailable. Path has been replaced with a suggested available path."
+msgstr ""
+
+msgid "Groups|Learn more"
+msgstr ""
+
+msgid "Groups|Must start with letter, digit, emoji, or underscore. Can also contain periods, dashes, spaces, and parentheses."
+msgstr ""
+
+msgid "Groups|Remove avatar"
+msgstr ""
+
+msgid "Groups|Save changes"
+msgstr ""
+
msgid "Guideline"
msgstr ""
@@ -17734,6 +18040,9 @@ msgstr ""
msgid "HAR file path or URL"
msgstr ""
+msgid "HTTP Archive (HAR)"
+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 ""
@@ -18136,6 +18445,9 @@ msgstr ""
msgid "INFO: Your SSH key is expiring soon. Please generate a new key."
msgstr ""
+msgid "IP"
+msgstr ""
+
msgid "IP Address"
msgstr ""
@@ -18172,6 +18484,9 @@ msgstr ""
msgid "IdentityVerification|Verify your identity"
msgstr ""
+msgid "IdentityVerification|You can always verify your account at a later time to create a group."
+msgstr ""
+
msgid "If any indexed field exceeds this limit, it is truncated to this number of characters. The rest of the content is neither indexed nor searchable. This does not apply to repository and wiki indexing. For unlimited characters, set this to 0."
msgstr ""
@@ -18229,6 +18544,9 @@ msgstr ""
msgid "If you add %{codeStart}needs%{codeEnd} to jobs in your pipeline you'll be able to view the %{codeStart}needs%{codeEnd} relationships between jobs in this tab as a %{linkStart}Directed Acyclic Graph (DAG)%{linkEnd}."
msgstr ""
+msgid "If you are added to a project, it will be displayed here."
+msgstr ""
+
msgid "If you did not initiate these sign-in attempts, please reach out to your administrator or enable two-factor authentication (2FA) on your account."
msgstr ""
@@ -18538,12 +18856,24 @@ msgstr ""
msgid "InProductMarketing|3 ways to dive into GitLab CI/CD"
msgstr ""
+msgid "InProductMarketing|A single application eliminates complex integrations, data chokepoints, and toolchain maintenance, resulting in greater productivity and lower cost."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features, build more efficiently, strengthen security and compliance."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features."
+msgstr ""
+
msgid "InProductMarketing|Actually, GitLab makes the team work (better)"
msgstr ""
msgid "InProductMarketing|And finally %{deploy_link} a Python application."
msgstr ""
+msgid "InProductMarketing|And many more..."
+msgstr ""
+
msgid "InProductMarketing|Are your runners ready?"
msgstr ""
@@ -18562,15 +18892,33 @@ msgstr ""
msgid "InProductMarketing|Blog"
msgstr ""
+msgid "InProductMarketing|Break down silos to coordinate seamlessly across development, operations, and security with a consistent experience across the development lifecycle."
+msgstr ""
+
+msgid "InProductMarketing|Burn up/down charts"
+msgstr ""
+
msgid "InProductMarketing|By enabling code owners and required merge approvals the right person will review the right MR. This is a win-win: cleaner code and a more efficient review process."
msgstr ""
msgid "InProductMarketing|Click on the number below that corresponds with your answer — 1 being very difficult, 5 being very easy."
msgstr ""
+msgid "InProductMarketing|Code owners"
+msgstr ""
+
msgid "InProductMarketing|Code owners and required merge approvals are part of the paid tiers of GitLab. You can start a free 30-day trial of GitLab Ultimate and enable these features in less than 5 minutes with no credit card required."
msgstr ""
+msgid "InProductMarketing|Code review analytics"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration across stages in GitLab"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration made easy"
+msgstr ""
+
msgid "InProductMarketing|Create a custom CI runner with just a few clicks"
msgstr ""
@@ -18580,12 +18928,21 @@ msgstr ""
msgid "InProductMarketing|Create a project in GitLab in 5 minutes"
msgstr ""
+msgid "InProductMarketing|Create well-defined workflows by using scoped labels on issues, merge requests, and epics. Labels with the same scope cannot be used together, which prevents conflicts."
+msgstr ""
+
msgid "InProductMarketing|Create your first project!"
msgstr ""
+msgid "InProductMarketing|Define who owns specific files or directories, so the right reviewers are suggested when a merge request introduces changes to those files."
+msgstr ""
+
msgid "InProductMarketing|Deliver Better Products Faster"
msgstr ""
+msgid "InProductMarketing|Dependency scanning"
+msgstr ""
+
msgid "InProductMarketing|Did you know teams that use GitLab are far more efficient?"
msgstr ""
@@ -18595,15 +18952,27 @@ msgstr ""
msgid "InProductMarketing|Dig in and create a project and a repo"
msgstr ""
+msgid "InProductMarketing|Discover Premium & Ultimate"
+msgstr ""
+
+msgid "InProductMarketing|Discover Premium & Ultimate."
+msgstr ""
+
msgid "InProductMarketing|Do you have a minute?"
msgstr ""
msgid "InProductMarketing|Do you have a teammate who would be perfect for this task?"
msgstr ""
+msgid "InProductMarketing|Dynamic application security testing"
+msgstr ""
+
msgid "InProductMarketing|Easy"
msgstr ""
+msgid "InProductMarketing|Epics"
+msgstr ""
+
msgid "InProductMarketing|Expand your DevOps journey with a free GitLab trial"
msgstr ""
@@ -18625,9 +18994,15 @@ msgstr ""
msgid "InProductMarketing|Feel the need for speed?"
msgstr ""
+msgid "InProductMarketing|Find and fix bottlenecks in your code review process by understanding how long open merge requests have been in review."
+msgstr ""
+
msgid "InProductMarketing|Find out how your teams are really doing"
msgstr ""
+msgid "InProductMarketing|Find out if your external libraries are safe. Run dependency scanning jobs that check for known vulnerabilities in your external libraries."
+msgstr ""
+
msgid "InProductMarketing|Follow our steps"
msgstr ""
@@ -18664,6 +19039,9 @@ msgstr ""
msgid "InProductMarketing|GitLab is better with teammates to help out!"
msgstr ""
+msgid "InProductMarketing|GitLab is infrastructure agnostic (supporting GCP, AWS, Azure, OpenShift, VMWare, On Prem, Bare Metal, and more), offering a consistent workflow experience – irrespective of the environment."
+msgstr ""
+
msgid "InProductMarketing|GitLab provides static application security testing (SAST), dynamic application security testing (DAST), container scanning, and dependency scanning to help you deliver secure applications along with license compliance."
msgstr ""
@@ -18754,21 +19132,36 @@ msgstr ""
msgid "InProductMarketing|It's also possible to simply %{external_repo_link} in order to take advantage of GitLab's CI/CD."
msgstr ""
+msgid "InProductMarketing|Keep your code quality high by defining who should approve merge requests and how many approvals are required."
+msgstr ""
+
msgid "InProductMarketing|Launch GitLab CI/CD in 20 minutes or less"
msgstr ""
+msgid "InProductMarketing|Lower cost of development"
+msgstr ""
+
+msgid "InProductMarketing|Make it easier to collaborate on high-level ideas by grouping related issues in an epic."
+msgstr ""
+
msgid "InProductMarketing|Making the switch? It's easier than you think to import your projects into GitLab. Move %{github_link}, or import something %{bitbucket_link}."
msgstr ""
msgid "InProductMarketing|Master the art of importing!"
msgstr ""
+msgid "InProductMarketing|Merge request approval rule"
+msgstr ""
+
msgid "InProductMarketing|Move on to easily creating a Pages website %{ci_template_link}"
msgstr ""
msgid "InProductMarketing|Multiple owners, confusing workstreams? We've got you covered"
msgstr ""
+msgid "InProductMarketing|Multiple required approvers"
+msgstr ""
+
msgid "InProductMarketing|Need an alternative to importing?"
msgstr ""
@@ -18781,18 +19174,33 @@ msgstr ""
msgid "InProductMarketing|Our tool brings all the things together"
msgstr ""
+msgid "InProductMarketing|Protect your web application by using DAST to examine for vulnerabilities in deployed environments."
+msgstr ""
+
msgid "InProductMarketing|Rapid development, simplified"
msgstr ""
msgid "InProductMarketing|Reduce Security & Compliance Risk"
msgstr ""
+msgid "InProductMarketing|Require multiple approvers on a merge request, so you know it's in good shape before it's merged."
+msgstr ""
+
+msgid "InProductMarketing|Roadmaps"
+msgstr ""
+
+msgid "InProductMarketing|Scoped labels"
+msgstr ""
+
msgid "InProductMarketing|Security that's integrated into your development lifecycle"
msgstr ""
msgid "InProductMarketing|Sometimes you're not ready to make a full transition to a new tool. If you're not ready to fully commit, %{mirroring_link} gives you a safe way to try out GitLab in parallel with your current tool."
msgstr ""
+msgid "InProductMarketing|Speed. Efficiency. Trust."
+msgstr ""
+
msgid "InProductMarketing|Spin up an autoscaling runner in GitLab"
msgstr ""
@@ -18802,6 +19210,9 @@ msgstr ""
msgid "InProductMarketing|Start a Self-Managed trial"
msgstr ""
+msgid "InProductMarketing|Start a free trial"
+msgstr ""
+
msgid "InProductMarketing|Start a free trial of GitLab Ultimate – no credit card required"
msgstr ""
@@ -18868,6 +19279,9 @@ msgstr ""
msgid "InProductMarketing|To understand and get the most out of GitLab, start at the beginning and %{project_link}. In GitLab, repositories are part of a project, so after you've created your project you can go ahead and %{repo_link}."
msgstr ""
+msgid "InProductMarketing|Track completed issues in a chart, so you can see how a milestone is progressing at a glance."
+msgstr ""
+
msgid "InProductMarketing|Try GitLab Ultimate for free"
msgstr ""
@@ -18904,6 +19318,9 @@ msgstr ""
msgid "InProductMarketing|Very easy"
msgstr ""
+msgid "InProductMarketing|Visualize your epics and milestones in a timeline."
+msgstr ""
+
msgid "InProductMarketing|Want to host GitLab on your servers?"
msgstr ""
@@ -18925,6 +19342,9 @@ msgstr ""
msgid "InProductMarketing|YouTube"
msgstr ""
+msgid "InProductMarketing|Your software, deployed your way"
+msgstr ""
+
msgid "InProductMarketing|Your teams can be more efficient"
msgstr ""
@@ -19045,9 +19465,18 @@ msgstr ""
msgid "IncidentManagement|No incidents to display."
msgstr ""
+msgid "IncidentManagement|None"
+msgstr ""
+
msgid "IncidentManagement|Open"
msgstr ""
+msgid "IncidentManagement|Page your team with escalation policies"
+msgstr ""
+
+msgid "IncidentManagement|Paged"
+msgstr ""
+
msgid "IncidentManagement|Published"
msgstr ""
@@ -19057,6 +19486,9 @@ msgstr ""
msgid "IncidentManagement|Severity"
msgstr ""
+msgid "IncidentManagement|Status"
+msgstr ""
+
msgid "IncidentManagement|There are no closed incidents"
msgstr ""
@@ -19075,6 +19507,9 @@ msgstr ""
msgid "IncidentManagement|Unpublished"
msgstr ""
+msgid "IncidentManagement|Use escalation policies to automatically page your team when incidents are created."
+msgstr ""
+
msgid "IncidentSettings|Activate \"time to SLA\" countdown timer"
msgstr ""
@@ -19120,7 +19555,10 @@ msgstr ""
msgid "Incidents"
msgstr ""
-msgid "Incidents|Add a URL"
+msgid "Incidents|Add image details"
+msgstr ""
+
+msgid "Incidents|Add text or a link to display with your image. If you don't add either, the file name displays instead."
msgstr ""
msgid "Incidents|Drop or %{linkStart}upload%{linkEnd} a metric screenshot to attach it to the incident"
@@ -19135,10 +19573,10 @@ msgstr ""
msgid "Incidents|There was an issue loading metric images."
msgstr ""
-msgid "Incidents|There was an issue uploading your image."
+msgid "Incidents|There was an issue updating your image."
msgstr ""
-msgid "Incidents|You can optionally add a URL to link users to the original graph."
+msgid "Incidents|There was an issue uploading your image."
msgstr ""
msgid "Incident|Alert details"
@@ -19147,9 +19585,18 @@ msgstr ""
msgid "Incident|Are you sure you wish to delete this image?"
msgstr ""
+msgid "Incident|Delete image"
+msgstr ""
+
msgid "Incident|Deleting %{filename}"
msgstr ""
+msgid "Incident|Edit image text or link"
+msgstr ""
+
+msgid "Incident|Editing %{filename}"
+msgstr ""
+
msgid "Incident|Metrics"
msgstr ""
@@ -19420,12 +19867,18 @@ msgstr ""
msgid "Integrations|Branches for which notifications are to be sent"
msgstr ""
+msgid "Integrations|Clear if using a self-signed certificate."
+msgstr ""
+
msgid "Integrations|Comment detail:"
msgstr ""
msgid "Integrations|Comment settings:"
msgstr ""
+msgid "Integrations|Connection details"
+msgstr ""
+
msgid "Integrations|Connection failed. Please check your settings."
msgstr ""
@@ -19450,6 +19903,9 @@ msgstr ""
msgid "Integrations|Enable GitLab.com slash commands in a Slack workspace."
msgstr ""
+msgid "Integrations|Enable SSL verification"
+msgstr ""
+
msgid "Integrations|Enable comments"
msgstr ""
@@ -19528,6 +19984,9 @@ msgstr ""
msgid "Integrations|Return to GitLab for Jira"
msgstr ""
+msgid "Integrations|SSL verification"
+msgstr ""
+
msgid "Integrations|Save settings?"
msgstr ""
@@ -19573,9 +20032,6 @@ msgstr ""
msgid "Integrations|Use default settings"
msgstr ""
-msgid "Integrations|When you mention a Jira issue in a commit or merge request, GitLab creates a remote link and comment (if enabled)."
-msgstr ""
-
msgid "Integrations|You can now close this window and return to the GitLab for Jira application."
msgstr ""
@@ -19600,9 +20056,6 @@ msgstr ""
msgid "Integrations|can't exceed %{recipients_limit}"
msgstr ""
-msgid "Interactive developer security education."
-msgstr ""
-
msgid "Interactive mode"
msgstr ""
@@ -20092,6 +20545,9 @@ msgstr ""
msgid "IssueAnalytics|Assignees"
msgstr ""
+msgid "IssueAnalytics|Created by"
+msgstr ""
+
msgid "IssueAnalytics|Due date"
msgstr ""
@@ -20104,9 +20560,6 @@ msgstr ""
msgid "IssueAnalytics|Milestone"
msgstr ""
-msgid "IssueAnalytics|Opened by"
-msgstr ""
-
msgid "IssueAnalytics|Status"
msgstr ""
@@ -20230,10 +20683,10 @@ msgstr ""
msgid "IssuesAnalytics|Avg/Month:"
msgstr ""
-msgid "IssuesAnalytics|Issues opened"
+msgid "IssuesAnalytics|Issues created"
msgstr ""
-msgid "IssuesAnalytics|Issues opened per month"
+msgid "IssuesAnalytics|Issues created per month"
msgstr ""
msgid "IssuesAnalytics|Last 12 months"
@@ -20260,6 +20713,9 @@ msgstr ""
msgid "It looks like you have some draft commits in this branch."
msgstr ""
+msgid "It looks like you're attempting to activate your subscription. Use %{a_start}the Subscription page%{a_end} instead."
+msgstr ""
+
msgid "It may be several days before you see feature usage data."
msgstr ""
@@ -20488,6 +20944,9 @@ msgstr ""
msgid "JiraConnect|You can now close this window and return to Jira."
msgstr ""
+msgid "JiraConnect|You don't have permission to create branches for this project. Select a different project or contact the project owner for access. %{linkStart}Learn more.%{linkEnd}"
+msgstr ""
+
msgid "JiraRequest|A connection error occurred while connecting to Jira. Try your request again."
msgstr ""
@@ -20536,13 +20995,13 @@ msgstr ""
msgid "JiraService|Define the type of Jira issue to create from a vulnerability."
msgstr ""
-msgid "JiraService|Displaying Jira issues while leaving the GitLab issue functionality enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
+msgid "JiraService|Displaying Jira issues while leaving GitLab issues also enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
msgstr ""
-msgid "JiraService|Enable Jira issues"
+msgid "JiraService|Enable Jira issue creation from vulnerabilities"
msgstr ""
-msgid "JiraService|Enable Jira issues creation from vulnerabilities"
+msgid "JiraService|Enable Jira issues"
msgstr ""
msgid "JiraService|Enable Jira transitions"
@@ -20659,16 +21118,19 @@ msgstr ""
msgid "JiraService|View Jira issues in GitLab"
msgstr ""
-msgid "JiraService|Warning: All GitLab users that have access to this GitLab project are able to view all issues from the Jira project specified below."
+msgid "JiraService|Warning: All GitLab users with access to this GitLab project can view all issues from the Jira project you select."
msgstr ""
msgid "JiraService|Web URL"
msgstr ""
-msgid "JiraService|Work on Jira issues without leaving GitLab. Adds a Jira menu to access your list of Jira issues and view any issue as read-only."
+msgid "JiraService|When a Jira issue is mentioned in a commit or merge request, a remote link and comment (if enabled) will be created."
+msgstr ""
+
+msgid "JiraService|Work on Jira issues without leaving GitLab. Add a Jira menu to access a read-only list of your Jira issues."
msgstr ""
-msgid "JiraService|You need to configure Jira before enabling this integration. For more details, read the %{jira_doc_link_start}Jira integration documentation%{link_end}."
+msgid "JiraService|You must configure Jira before enabling this integration. %{jira_doc_link_start}Learn more.%{link_end}"
msgstr ""
msgid "Job"
@@ -20680,9 +21142,6 @@ msgstr ""
msgid "Job Failed #%{build_id}"
msgstr ""
-msgid "Job ID"
-msgstr ""
-
msgid "Job artifact"
msgstr ""
@@ -20749,9 +21208,27 @@ msgstr ""
msgid "Jobs|You're about to retry a job that failed because it attempted to deploy code that is older than the latest deployment. Retrying this job could result in overwriting the environment with the older source code."
msgstr ""
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source} into %{target}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{ref}"
+msgstr ""
+
+msgid "Job|Are you sure you want to erase this job log and artifacts?"
+msgstr ""
+
msgid "Job|Browse"
msgstr ""
+msgid "Job|Cancel"
+msgstr ""
+
msgid "Job|Complete Raw"
msgstr ""
@@ -20761,6 +21238,9 @@ msgstr ""
msgid "Job|Erase job log and artifacts"
msgstr ""
+msgid "Job|Finished at"
+msgstr ""
+
msgid "Job|Job artifacts"
msgstr ""
@@ -20773,7 +21253,7 @@ msgstr ""
msgid "Job|Keep"
msgstr ""
-msgid "Job|Pipeline"
+msgid "Job|Retry"
msgstr ""
msgid "Job|Scroll to bottom"
@@ -20785,6 +21265,9 @@ msgstr ""
msgid "Job|Show complete raw"
msgstr ""
+msgid "Job|Status"
+msgstr ""
+
msgid "Job|The artifacts were removed"
msgstr ""
@@ -20812,21 +21295,12 @@ msgstr ""
msgid "Job|delayed"
msgstr ""
-msgid "Job|for"
-msgstr ""
-
-msgid "Job|into"
-msgstr ""
-
msgid "Job|manual"
msgstr ""
msgid "Job|triggered"
msgstr ""
-msgid "Job|with"
-msgstr ""
-
msgid "Join Zoom meeting"
msgstr ""
@@ -20929,9 +21403,6 @@ msgstr ""
msgid "Ki"
msgstr ""
-msgid "Kontra"
-msgstr ""
-
msgid "Kroki"
msgstr ""
@@ -21256,6 +21727,9 @@ msgstr ""
msgid "Learn more about Auto DevOps"
msgstr ""
+msgid "Learn more about GitLab"
+msgstr ""
+
msgid "Learn more about Needs relationships"
msgstr ""
@@ -21589,9 +22063,18 @@ msgstr ""
msgid "Licenses|Displays licenses detected in the project, based on the %{linkStart}latest successful%{linkEnd} scan"
msgstr ""
+msgid "Licenses|Drag your license file here or %{linkStart}click to upload%{linkEnd}."
+msgstr ""
+
+msgid "Licenses|Drop your license file to start the upload."
+msgstr ""
+
msgid "Licenses|Error fetching the license list. Please check your network connection and try again."
msgstr ""
+msgid "Licenses|Error: You are trying to upload something other than a file"
+msgstr ""
+
msgid "Licenses|License Compliance"
msgstr ""
@@ -21610,6 +22093,9 @@ msgstr ""
msgid "Licenses|Specified policies in this project"
msgstr ""
+msgid "Licenses|The file could not be uploaded."
+msgstr ""
+
msgid "Licenses|The license list details information about the licenses used within your project."
msgstr ""
@@ -21643,12 +22129,6 @@ msgstr ""
msgid "Limit the size of Sidekiq jobs stored in Redis."
msgstr ""
-msgid "Limited to showing %d event at most"
-msgid_plural "Limited to showing %d events at most"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-
msgid "Limiting mode"
msgstr ""
@@ -21658,6 +22138,9 @@ msgstr ""
msgid "Link"
msgstr ""
+msgid "Link (optional)"
+msgstr ""
+
msgid "Link Prometheus monitoring to GitLab."
msgstr ""
@@ -21694,6 +22177,9 @@ msgstr ""
msgid "Linked emails (%{email_count})"
msgstr ""
+msgid "Linked epics"
+msgstr ""
+
msgid "Linked issues"
msgstr ""
@@ -21721,6 +22207,15 @@ msgstr ""
msgid "List of all merge commits"
msgstr ""
+msgid "List of environments for this project"
+msgstr ""
+
+msgid "List of suitable GCP locations"
+msgstr ""
+
+msgid "List of users allowed to exceed the rate limit."
+msgstr ""
+
msgid "List options"
msgstr ""
@@ -21940,6 +22435,9 @@ msgstr ""
msgid "Maintenance mode"
msgstr ""
+msgid "Make adjustments to how your GitLab instance is set up."
+msgstr ""
+
msgid "Make and review changes in the browser with the Web IDE"
msgstr ""
@@ -22084,6 +22582,12 @@ msgstr ""
msgid "MarkdownEditor|Add italic text (%{modifier_key}I)"
msgstr ""
+msgid "MarkdownEditor|Add strikethrough text (%{modifierKey}⇧X)"
+msgstr ""
+
+msgid "MarkdownEditor|Add strikethrough text (%{modifier_key}⇧X)"
+msgstr ""
+
msgid "Marked For Deletion At - %{deletion_time}"
msgstr ""
@@ -22345,6 +22849,9 @@ msgstr ""
msgid "Maximum push size (MB)"
msgstr ""
+msgid "Maximum requests per 10 minutes per user"
+msgstr ""
+
msgid "Maximum requests per minute"
msgstr ""
@@ -22435,6 +22942,21 @@ msgstr ""
msgid "Members of a group may only view projects they have permission to access"
msgstr ""
+msgid "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seat in use and will be billed for the overage."
+msgid_plural "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seats in use and will be billed for the overage."
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
+msgid "MembersOverage|You are about to incur additional charges"
+msgstr ""
+
+msgid "MembersOverage|Your subscription includes %d seat."
+msgid_plural "MembersOverage|Your subscription includes %d seats."
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
msgid "Membership"
msgstr ""
@@ -22639,9 +23161,6 @@ msgstr ""
msgid "Merge request not merged"
msgstr ""
-msgid "Merge request pipelines 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 merge request pipelines."
-msgstr ""
-
msgid "Merge request reports"
msgstr ""
@@ -22738,13 +23257,13 @@ msgstr ""
msgid "MergeRequests|Create issue to resolve thread"
msgstr ""
-msgid "MergeRequests|Failed to squash. Should be done manually."
+msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Saving the comment failed"
+msgid "MergeRequests|Squashing failed: Squash the commits locally, resolve any conflicts, then push the branch."
msgstr ""
-msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
+msgid "MergeRequests|Squashing not allowed: This project doesn't allow you to squash commits when merging."
msgstr ""
msgid "MergeRequests|Thread stays resolved"
@@ -23587,6 +24106,18 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "MrList|Assigned to %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from assignee %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from reviewer %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Review requested from %{name}, go to their profile."
+msgstr ""
+
msgid "Multi-project"
msgstr ""
@@ -23620,7 +24151,7 @@ msgstr ""
msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "My Awesome Group"
+msgid "My awesome group"
msgstr ""
msgid "My company or team"
@@ -24244,9 +24775,6 @@ msgstr ""
msgid "No available branches"
msgstr ""
-msgid "No available groups to fork the project."
-msgstr ""
-
msgid "No branches found"
msgstr ""
@@ -24457,6 +24985,9 @@ msgstr ""
msgid "No ref selected"
msgstr ""
+msgid "No regions configured"
+msgstr ""
+
msgid "No related merge requests found."
msgstr ""
@@ -25267,6 +25798,9 @@ msgstr ""
msgid "Only reCAPTCHA v2 is supported:"
msgstr ""
+msgid "Only required if not using role instance credentials."
+msgstr ""
+
msgid "Only use lowercase letters, numbers, and underscores."
msgstr ""
@@ -25291,9 +25825,6 @@ msgstr ""
msgid "Open a CLI and connect to the cluster you want to install the agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
-msgid "Open epics"
-msgstr ""
-
msgid "Open errors"
msgstr ""
@@ -25333,8 +25864,8 @@ msgstr ""
msgid "Opened issues"
msgstr "Otvoreni zadaci"
-msgid "OpenedNDaysAgo|Opened"
-msgstr "Otvoreno"
+msgid "OpenedNDaysAgo|Created"
+msgstr ""
msgid "Opens in a new window"
msgstr ""
@@ -25378,9 +25909,6 @@ msgstr ""
msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
-msgid "Optional."
-msgstr ""
-
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
msgstr ""
@@ -26170,6 +26698,9 @@ msgstr ""
msgid "PerformanceBar|Memory"
msgstr ""
+msgid "PerformanceBar|Memory report"
+msgstr ""
+
msgid "PerformanceBar|Redis calls"
msgstr ""
@@ -26203,18 +26734,12 @@ msgstr ""
msgid "PerformanceBar|wall"
msgstr ""
-msgid "Performs a rebase but skips triggering a new pipeline"
-msgstr ""
-
msgid "Period in seconds"
msgstr ""
msgid "Permalink"
msgstr ""
-msgid "Permanently delete project"
-msgstr ""
-
msgid "Permanently remove group"
msgstr ""
@@ -26485,6 +27010,51 @@ msgstr ""
msgid "PipelineStatusTooltip|Pipeline: %{ci_status}"
msgstr ""
+msgid "PipelineWizardDefaultCommitMessage|Add %{filename}"
+msgstr ""
+
+msgid "PipelineWizardDefaultCommitMessage|Update %{filename}"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|At least one entry is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This field is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This value is not valid"
+msgstr ""
+
+msgid "PipelineWizardListWidget|add another step"
+msgstr ""
+
+msgid "PipelineWizardListWidget|remove step"
+msgstr ""
+
+msgid "PipelineWizard|Commit"
+msgstr ""
+
+msgid "PipelineWizard|Commit Message"
+msgstr ""
+
+msgid "PipelineWizard|Commit changes to your file"
+msgstr ""
+
+msgid "PipelineWizard|Commit file to Branch"
+msgstr ""
+
+msgid "PipelineWizard|Commit your new file"
+msgstr ""
+
+msgid "PipelineWizard|The file has been committed."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem committing the changes."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem while checking whether your file already exists in the specified branch."
+msgstr ""
+
msgid "Pipelines"
msgstr ""
@@ -26599,7 +27169,7 @@ msgstr ""
msgid "Pipelines|Project cache successfully reset."
msgstr ""
-msgid "Pipelines|Revoke"
+msgid "Pipelines|Revoke trigger"
msgstr ""
msgid "Pipelines|Something went wrong while cleaning runners cache."
@@ -26644,6 +27214,12 @@ msgstr ""
msgid "Pipelines|This is a child pipeline within the parent pipeline"
msgstr ""
+msgid "Pipelines|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipelines|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipelines|This pipeline will run code originating from a forked project merge request. This means that the code can potentially have security considerations like exposing CI variables."
msgstr ""
@@ -26686,9 +27262,6 @@ msgstr ""
msgid "Pipelines|Your changes have been successfully committed. Now redirecting to the new merge request page."
msgstr ""
-msgid "Pipelines|detached"
-msgstr ""
-
msgid "Pipelines|error"
msgstr ""
@@ -26698,10 +27271,13 @@ msgstr ""
msgid "Pipelines|latest"
msgstr ""
-msgid "Pipelines|stuck"
+msgid "Pipelines|merge request"
msgstr ""
-msgid "Pipelines|train"
+msgid "Pipelines|merge train"
+msgstr ""
+
+msgid "Pipelines|stuck"
msgstr ""
msgid "Pipelines|yaml invalid"
@@ -26833,6 +27409,12 @@ msgstr ""
msgid "Pipeline|This change will not change the overall test coverage if merged."
msgstr ""
+msgid "Pipeline|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipeline|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipeline|Trigger author"
msgstr ""
@@ -26857,6 +27439,12 @@ msgstr ""
msgid "Pipeline|for"
msgstr ""
+msgid "Pipeline|merge request"
+msgstr ""
+
+msgid "Pipeline|merge train"
+msgstr ""
+
msgid "Pipeline|on"
msgstr ""
@@ -26995,9 +27583,6 @@ msgstr ""
msgid "Please enter a valid time interval"
msgstr ""
-msgid "Please enter or upload a valid license."
-msgstr ""
-
msgid "Please enter your current password."
msgstr ""
@@ -27106,9 +27691,6 @@ msgstr ""
msgid "Please type %{phrase_code} to proceed or close this modal to cancel."
msgstr ""
-msgid "Please type the following to confirm:"
-msgstr ""
-
msgid "Please use this form to report to the admin users who create spam issues, comments or behave inappropriately."
msgstr ""
@@ -27136,12 +27718,27 @@ msgstr ""
msgid "Policies"
msgstr ""
+msgid "Policy '%{escalation_policy_name}' does not exist."
+msgstr ""
+
msgid "Policy management project does have any policies in %{policy_path}"
msgstr ""
msgid "Policy project doesn't exist"
msgstr ""
+msgid "PolicyRuleMultiSelect|%{firstLabel} +%{numberOfAdditionalLabels} more"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|All %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select all"
+msgstr ""
+
msgid "Polling interval multiplier"
msgstr ""
@@ -27370,6 +27967,9 @@ msgstr ""
msgid "Private projects can be created in your personal namespace with:"
msgstr ""
+msgid "Problem with %{name} command: %{message}."
+msgstr ""
+
msgid "Proceed"
msgstr ""
@@ -27844,6 +28444,9 @@ msgstr ""
msgid "Progress"
msgstr ""
+msgid "Progress tracking"
+msgstr ""
+
msgid "Project"
msgstr ""
@@ -28075,6 +28678,9 @@ msgstr ""
msgid "ProjectQualitySummary|Failure"
msgstr ""
+msgid "ProjectQualitySummary|Get insight into the overall percentage of tests in your project that succeed, fail and are skipped."
+msgstr ""
+
msgid "ProjectQualitySummary|Latest pipeline results"
msgstr ""
@@ -28093,6 +28699,12 @@ msgstr ""
msgid "ProjectQualitySummary|See project Code Coverage Statistics"
msgstr ""
+msgid "ProjectQualitySummary|Set up test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|Set up test runs (opens in a new tab)"
+msgstr ""
+
msgid "ProjectQualitySummary|Skipped"
msgstr ""
@@ -28369,13 +28981,19 @@ msgstr ""
msgid "ProjectSettings|LFS objects from this repository are available to forks. %{linkStart}How do I remove them?%{linkEnd}"
msgstr ""
+msgid "ProjectSettings|Learn about commit history."
+msgstr ""
+
+msgid "ProjectSettings|Leave empty to use default template."
+msgstr ""
+
msgid "ProjectSettings|Manage who can see the project in the public access directory."
msgstr ""
msgid "ProjectSettings|Manages large files such as audio, video, and graphics files."
msgstr ""
-msgid "ProjectSettings|Maximum 500 characters."
+msgid "ProjectSettings|Maximum %{maxLength} characters."
msgstr ""
msgid "ProjectSettings|Merge checks"
@@ -28516,6 +29134,9 @@ msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
msgstr ""
+msgid "ProjectSettings|The default template will be applied on save."
+msgstr ""
+
msgid "ProjectSettings|These checks must pass before merge requests can be merged."
msgstr ""
@@ -28570,6 +29191,9 @@ msgstr ""
msgid "ProjectSettings|What are badges?"
msgstr ""
+msgid "ProjectSettings|What are merge trains?"
+msgstr ""
+
msgid "ProjectSettings|When merge request pipelines are enabled in the CI/CD configuration file, pipelines validate the combined results of the source and target branches. %{link_start}How to configure merge request pipelines?%{link_end}"
msgstr ""
@@ -28687,6 +29311,9 @@ msgstr ""
msgid "Projects are organized into groups"
msgstr ""
+msgid "Projects are where you store your code, access issues, wiki and other features of GitLab."
+msgstr ""
+
msgid "Projects contributed to"
msgstr ""
@@ -28702,12 +29329,6 @@ msgstr ""
msgid "Projects to index"
msgstr ""
-msgid "Projects will be permanently deleted after a %{waiting_period}-day waiting period."
-msgstr ""
-
-msgid "Projects will be permanently deleted immediately."
-msgstr ""
-
msgid "Projects with critical vulnerabilities"
msgstr ""
@@ -28792,6 +29413,9 @@ msgstr ""
msgid "ProjectsNew|Import project"
msgstr ""
+msgid "ProjectsNew|Include a Getting Started README"
+msgstr ""
+
msgid "ProjectsNew|Initialize repository with a README"
msgstr ""
@@ -28807,6 +29431,9 @@ msgstr ""
msgid "ProjectsNew|Project description %{tag_start}(optional)%{tag_end}"
msgstr ""
+msgid "ProjectsNew|Recommended if you're new to GitLab"
+msgstr ""
+
msgid "ProjectsNew|Run CI/CD for external repository"
msgstr ""
@@ -29224,6 +29851,9 @@ msgstr ""
msgid "ProtectedBranch|Unprotect"
msgstr ""
+msgid "ProtectedBranch|Unprotect branch"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
@@ -29251,6 +29881,9 @@ msgstr ""
msgid "ProtectedEnvironment|Protected Environment (%{protected_environments_count})"
msgstr ""
+msgid "ProtectedEnvironment|Required approvals"
+msgstr ""
+
msgid "ProtectedEnvironment|Select an environment"
msgstr ""
@@ -29272,10 +29905,13 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|Unprotect tag"
+msgstr ""
+
msgid "ProtectedTags|default"
msgstr ""
-msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
+msgid "ProtectedTag|By default, protected tags restrict who can modify the tag."
msgstr ""
msgid "ProtectedTag|Learn more."
@@ -29338,6 +29974,9 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Public projects are an easy way to allow everyone to have read-only access."
+msgstr ""
+
msgid "Publish to status page"
msgstr ""
@@ -29494,9 +30133,6 @@ msgstr ""
msgid "QualitySummary|Project quality"
msgstr ""
-msgid "Quarters"
-msgstr ""
-
msgid "Query"
msgstr ""
@@ -29581,6 +30217,9 @@ msgstr ""
msgid "Read more about project permissions %{help_link_open}here%{help_link_close}"
msgstr ""
+msgid "Read more about related epics"
+msgstr ""
+
msgid "Read more about related issues"
msgstr ""
@@ -29611,10 +30250,7 @@ msgstr ""
msgid "Rebase source branch on the target branch."
msgstr ""
-msgid "Rebase without CI"
-msgstr ""
-
-msgid "Rebases and triggers a pipeline"
+msgid "Rebase without pipeline"
msgstr ""
msgid "Recaptcha verified?"
@@ -29665,9 +30301,6 @@ msgstr ""
msgid "Reconfigure"
msgstr ""
-msgid "Recovering projects"
-msgstr ""
-
msgid "Recovery Codes"
msgstr ""
@@ -29728,6 +30361,12 @@ msgstr ""
msgid "Regex pattern"
msgstr ""
+msgid "Region"
+msgstr ""
+
+msgid "Regions"
+msgstr ""
+
msgid "Register"
msgstr ""
@@ -29959,9 +30598,6 @@ msgstr ""
msgid "Remove all or specific reviewer(s)"
msgstr ""
-msgid "Remove approver"
-msgstr ""
-
msgid "Remove approvers"
msgstr ""
@@ -29977,6 +30613,9 @@ msgstr ""
msgid "Remove attention request"
msgstr ""
+msgid "Remove attention request(s)"
+msgstr ""
+
msgid "Remove avatar"
msgstr ""
@@ -30115,6 +30754,9 @@ msgstr ""
msgid "Removed an issue from an epic."
msgstr "Zadatak uklonjen iz epika."
+msgid "Removed attention from %{users_sentence}."
+msgstr ""
+
msgid "Removed attention request from @%{username}"
msgstr ""
@@ -30166,6 +30808,9 @@ msgstr ""
msgid "Removes an issue from an epic."
msgstr "Uklanja zadatak iz epika."
+msgid "Removes attention from %{users_sentence}."
+msgstr ""
+
msgid "Removes parent epic %{epic_ref}."
msgstr ""
@@ -30277,6 +30922,9 @@ msgstr ""
msgid "Report abuse to admin"
msgstr ""
+msgid "Report is generating and will be sent to your email address."
+msgstr ""
+
msgid "Reported %{timeAgo} by %{reportedBy}"
msgstr ""
@@ -30571,6 +31219,15 @@ msgstr ""
msgid "Request attention"
msgstr ""
+msgid "Request attention from %{users_sentence}."
+msgstr ""
+
+msgid "Request attention from assignee or reviewer"
+msgstr ""
+
+msgid "Request attention from assignee(s) or reviewer(s)"
+msgstr ""
+
msgid "Request attention to review"
msgstr ""
@@ -30595,6 +31252,9 @@ msgstr ""
msgid "Requested %{time_ago}"
msgstr ""
+msgid "Requested attention from %{users_sentence}."
+msgstr ""
+
msgid "Requested attention from @%{username}"
msgstr ""
@@ -30811,6 +31471,9 @@ msgstr ""
msgid "Restore project"
msgstr ""
+msgid "Restoring projects"
+msgstr ""
+
msgid "Restoring the group will prevent the group, its subgroups and projects from being removed on this date."
msgstr ""
@@ -30841,6 +31504,9 @@ msgstr ""
msgid "Retry"
msgstr ""
+msgid "Retry failed jobs"
+msgstr ""
+
msgid "Retry job"
msgstr ""
@@ -30889,9 +31555,6 @@ msgstr ""
msgid "Review changes"
msgstr ""
-msgid "Review requested from %{name}"
-msgstr ""
-
msgid "Review requests for you"
msgstr ""
@@ -31057,6 +31720,9 @@ msgstr ""
msgid "Runners|Assigned Group"
msgstr ""
+msgid "Runners|Assigned Projects (%{projectCount})"
+msgstr ""
+
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -31126,6 +31792,9 @@ msgstr ""
msgid "Runners|Instance"
msgstr ""
+msgid "Runners|Jobs"
+msgstr ""
+
msgid "Runners|Last contact"
msgstr ""
@@ -31219,9 +31888,6 @@ msgstr ""
msgid "Runners|Runner %{name} was deleted"
msgstr ""
-msgid "Runners|Runner ID"
-msgstr ""
-
msgid "Runners|Runner assigned to project."
msgstr ""
@@ -31369,6 +32035,9 @@ msgstr ""
msgid "Runners|stale"
msgstr ""
+msgid "Runner|This runner has not run any jobs."
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -31483,6 +32152,24 @@ msgstr ""
msgid "Saving project."
msgstr ""
+msgid "ScanResultPolicy|%{ifLabelStart}if%{ifLabelEnd} %{scanners} scan in an open merge request targeting the %{branches} branch(es) finds %{vulnerabilitiesAllowed} or more %{severities} vulnerabilities that are %{vulnerabilityStates}"
+msgstr ""
+
+msgid "ScanResultPolicy|%{thenLabelStart}Then%{thenLabelEnd} Require approval from %{approvalsRequired} of the following approvers: %{approvers}"
+msgstr ""
+
+msgid "ScanResultPolicy|add an approver"
+msgstr ""
+
+msgid "ScanResultPolicy|scanners"
+msgstr ""
+
+msgid "ScanResultPolicy|severity levels"
+msgstr ""
+
+msgid "ScanResultPolicy|vulnerability states"
+msgstr ""
+
msgid "Scanner"
msgstr ""
@@ -31615,6 +32302,9 @@ msgstr ""
msgid "Search for a user"
msgstr ""
+msgid "Search for an emoji"
+msgstr ""
+
msgid "Search for projects, issues, etc."
msgstr ""
@@ -31813,18 +32503,12 @@ msgstr ""
msgid "Secret Detection"
msgstr ""
-msgid "Secret access key"
-msgstr ""
-
msgid "Secret token"
msgstr ""
msgid "Secure token that identifies an external storage request."
msgstr ""
-msgid "SecureCodeWarrior"
-msgstr ""
-
msgid "Security"
msgstr ""
@@ -31849,9 +32533,6 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "Security training with guide and learning pathways."
-msgstr ""
-
msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
@@ -31954,7 +32635,7 @@ msgstr ""
msgid "SecurityConfiguration|Manage corpus"
msgstr ""
-msgid "SecurityConfiguration|Manage corpus files used as mutation sources in coverage fuzzing."
+msgid "SecurityConfiguration|Manage corpus files used as seed inputs with coverage-guided fuzzing."
msgstr ""
msgid "SecurityConfiguration|Manage profiles for use by DAST scans."
@@ -32020,15 +32701,15 @@ msgstr ""
msgid "SecurityOrchestration|.yaml preview"
msgstr ""
-msgid "SecurityOrchestration|Action"
-msgstr ""
-
msgid "SecurityOrchestration|Actions"
msgstr ""
msgid "SecurityOrchestration|Add rule"
msgstr ""
+msgid "SecurityOrchestration|After dismissing the alert, the information will never be shown again."
+msgstr ""
+
msgid "SecurityOrchestration|All policies"
msgstr ""
@@ -32044,7 +32725,7 @@ msgstr ""
msgid "SecurityOrchestration|Description"
msgstr ""
-msgid "SecurityOrchestration|Disabled"
+msgid "SecurityOrchestration|Don't show the alert anymore"
msgstr ""
msgid "SecurityOrchestration|Edit policy"
@@ -32053,13 +32734,13 @@ msgstr ""
msgid "SecurityOrchestration|Edit policy project"
msgstr ""
-msgid "SecurityOrchestration|Enabled"
+msgid "SecurityOrchestration|Empty policy name"
msgstr ""
-msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Enabled"
msgstr ""
-msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
msgstr ""
msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
@@ -32068,7 +32749,7 @@ msgstr ""
msgid "SecurityOrchestration|Invalid policy type"
msgstr ""
-msgid "SecurityOrchestration|Latest scan"
+msgid "SecurityOrchestration|Latest scan run against %{agent}"
msgstr ""
msgid "SecurityOrchestration|Network"
@@ -32077,15 +32758,27 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No actions defined - policy will not run."
+msgstr ""
+
+msgid "SecurityOrchestration|No description"
+msgstr ""
+
msgid "SecurityOrchestration|No rules defined - policy will not run."
msgstr ""
+msgid "SecurityOrchestration|Not enabled"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
msgid "SecurityOrchestration|Policies"
msgstr ""
+msgid "SecurityOrchestration|Policy Type"
+msgstr ""
+
msgid "SecurityOrchestration|Policy cannot be enabled for non-existing branches (%{branches})"
msgstr ""
@@ -32110,10 +32803,13 @@ msgstr ""
msgid "SecurityOrchestration|Require %{approvals} %{plural} from %{approvers} if any of the following occur:"
msgstr ""
-msgid "SecurityOrchestration|Rule"
+msgid "SecurityOrchestration|Rules"
msgstr ""
-msgid "SecurityOrchestration|Rules"
+msgid "SecurityOrchestration|Runs %{actions} and %{lastAction} scans"
+msgstr ""
+
+msgid "SecurityOrchestration|Runs a %{action} scan"
msgstr ""
msgid "SecurityOrchestration|Scan Execution"
@@ -32173,6 +32869,9 @@ msgstr ""
msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
+msgid "SecurityOrchestration|This view only shows scan results for the agent %{agent}. You can view scan results for all agents in the %{linkStart}Operational Vulnerabilities tab of the vulnerability report%{linkEnd}."
+msgstr ""
+
msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
@@ -32227,9 +32926,6 @@ msgstr ""
msgid "SecurityOrchestration|users with ids"
msgstr ""
-msgid "SecurityOrchestration|view results"
-msgstr ""
-
msgid "SecurityOrchestration|vulnerabilities"
msgstr ""
@@ -32899,22 +33595,19 @@ 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|In order to start using functions as a service, you must first install Knative on your Kubernetes cluster. %{linkStart}More information%{linkEnd}"
-msgstr ""
-
msgid "Serverless|Learn more about Serverless"
msgstr ""
msgid "Serverless|No functions available"
msgstr ""
-msgid "Serverless|Sign up for First Look"
+msgid "Serverless|Serverless was %{linkStart}deprecated%{linkEnd} in GitLab 14.3."
+msgstr ""
+
+msgid "Serverless|Serverless was %{postLinkStart}deprecated%{postLinkEnd}. But if you opt to use it, you must install Knative in your Kubernetes cluster first. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "Serverless|The deploy job has not finished."
@@ -32926,9 +33619,6 @@ 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 ""
@@ -32944,9 +33634,6 @@ msgstr ""
msgid "Service Account Key"
msgstr ""
-msgid "Service Accounts"
-msgstr ""
-
msgid "Service Accounts keys authorize GitLab to deploy your Google Cloud project"
msgstr ""
@@ -32956,10 +33643,10 @@ msgstr "TehniÄka PodrÅ¡ka"
msgid "Service Desk allows people to create issues in your GitLab instance without their own user account. It provides a unique email address for end users to create issues in a project. Replies can be sent either through the GitLab interface or by email. End users only see threads through email."
msgstr ""
-msgid "Service Usage Data"
+msgid "Service account generated successfully"
msgstr ""
-msgid "Service account generated successfully"
+msgid "Service accounts"
msgstr ""
msgid "Service ping is disabled in your configuration file, and cannot be enabled through this form."
@@ -33103,6 +33790,9 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
+msgid "Set the per-user rate limit for getting a user by ID via the API."
+msgstr ""
+
msgid "Set the per-user rate limit for notes created by web or API requests."
msgstr ""
@@ -33283,6 +33973,9 @@ msgstr ""
msgid "Shared runners details"
msgstr ""
+msgid "Shared runners enabled cannot be enabled until a valid credit card is on file"
+msgstr ""
+
msgid "Shared runners help link"
msgstr ""
@@ -33340,6 +34033,9 @@ msgstr ""
msgid "Show all issues."
msgstr ""
+msgid "Show all milestones"
+msgstr ""
+
msgid "Show all test cases."
msgstr ""
@@ -33376,6 +34072,9 @@ msgstr ""
msgid "Show file contents"
msgstr ""
+msgid "Show group milestones"
+msgstr ""
+
msgid "Show labels"
msgstr ""
@@ -33391,6 +34090,12 @@ msgstr ""
msgid "Show open epics"
msgstr ""
+msgid "Show project milestones"
+msgstr ""
+
+msgid "Show sub-group milestones"
+msgstr ""
+
msgid "Show the Closed list"
msgstr ""
@@ -33400,12 +34105,6 @@ msgstr ""
msgid "Show whitespace changes"
msgstr ""
-msgid "Showing %d event"
-msgid_plural "Showing %d events"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-
msgid "Showing %{conflict} between %{sourceBranch} and %{targetBranch}"
msgstr ""
@@ -33466,12 +34165,6 @@ msgstr ""
msgid "Sidebar|None"
msgstr ""
-msgid "Sidebar|Only numeral characters allowed"
-msgstr ""
-
-msgid "Sidebar|Weight"
-msgstr ""
-
msgid "Sidekiq job compression threshold (bytes)"
msgstr ""
@@ -33634,6 +34327,9 @@ msgstr ""
msgid "Slack logo"
msgstr ""
+msgid "SlackIntegration|Are you sure you want to remove this project from the Slack application?"
+msgstr ""
+
msgid "SlackIntegration|GitLab for Slack"
msgstr ""
@@ -33643,6 +34339,9 @@ msgstr ""
msgid "SlackIntegration|Project alias"
msgstr ""
+msgid "SlackIntegration|Remove project"
+msgstr ""
+
msgid "SlackIntegration|Select a GitLab project to link with your Slack workspace."
msgstr ""
@@ -33787,9 +34486,6 @@ msgstr ""
msgid "Something went wrong trying to load issue contacts."
msgstr ""
-msgid "Something went wrong when creating a work item. Please try again"
-msgstr ""
-
msgid "Something went wrong when reordering designs. Please try again"
msgstr ""
@@ -33883,9 +34579,6 @@ msgstr ""
msgid "Something went wrong while inserting your image. Please try again."
msgstr ""
-msgid "Something went wrong while merging this merge request. Please try again."
-msgstr ""
-
msgid "Something went wrong while obtaining the Let's Encrypt certificate."
msgstr ""
@@ -34207,10 +34900,10 @@ 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."
+msgid "SourcegraphAdmin|Learn more."
msgstr ""
-msgid "SourcegraphAdmin|More information"
+msgid "SourcegraphAdmin|Only public projects have code intelligence enabled and communicate with Sourcegraph."
msgstr ""
msgid "SourcegraphAdmin|Save changes"
@@ -34219,7 +34912,7 @@ msgstr ""
msgid "SourcegraphAdmin|Sourcegraph URL"
msgstr ""
-msgid "SourcegraphAdmin|e.g. https://sourcegraph.example.com"
+msgid "SourcegraphAdmin|https://sourcegraph.example.com"
msgstr ""
msgid "SourcegraphPreferences|This feature is experimental and currently limited to certain projects."
@@ -34354,6 +35047,9 @@ msgstr ""
msgid "Start date"
msgstr ""
+msgid "Start free trial"
+msgstr ""
+
msgid "Start merge train"
msgstr ""
@@ -34384,6 +35080,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started escalation for this incident."
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -34396,6 +35095,9 @@ msgstr ""
msgid "Starts at (UTC)"
msgstr ""
+msgid "Starts escalations for this incident"
+msgstr ""
+
msgid "Starts on"
msgstr ""
@@ -34657,6 +35359,9 @@ msgstr ""
msgid "Strikethrough"
msgstr ""
+msgid "Strikethrough text"
+msgstr ""
+
msgid "Subgroup information"
msgstr ""
@@ -34891,6 +35596,21 @@ msgstr ""
msgid "Subscriptions"
msgstr ""
+msgid "Subscriptions|Chat with sales"
+msgstr ""
+
+msgid "Subscriptions|Close"
+msgstr ""
+
+msgid "Subscriptions|Not ready to buy yet?"
+msgstr ""
+
+msgid "Subscriptions|Start a free trial"
+msgstr ""
+
+msgid "Subscriptions|We understand. Maybe you have some questions for our sales team, or maybe you'd like to try some of the paid features first. What would you like to do?"
+msgstr ""
+
msgid "Subscription|Your subscription for %{strong}%{namespace_name}%{strong_close} has expired and you are now on %{pricing_link_start}the GitLab Free tier%{pricing_link_end}. Don't worry, your data is safe. Get in touch with our support team (%{support_email}). They'll gladly help with your subscription renewal."
msgstr ""
@@ -35101,6 +35821,9 @@ msgstr ""
msgid "SuperSonics|Maximum users"
msgstr ""
+msgid "SuperSonics|Offline cloud"
+msgstr ""
+
msgid "SuperSonics|Paste your activation code"
msgstr ""
@@ -35167,6 +35890,12 @@ msgstr ""
msgid "SuperSonics|You do not have an active subscription"
msgstr ""
+msgid "SuperSonics|You have a future dated license"
+msgstr ""
+
+msgid "SuperSonics|You have added a license that activates on %{date}. Please see the subscription history table below for more details."
+msgstr ""
+
msgid "SuperSonics|You have successfully added a license that activates on %{date}. Please see the subscription history table below for more details."
msgstr ""
@@ -35326,6 +36055,9 @@ msgstr ""
msgid "Tag name is required"
msgstr ""
+msgid "Tag push"
+msgstr ""
+
msgid "Tag push events"
msgstr ""
@@ -35428,6 +36160,9 @@ msgstr ""
msgid "TagsPage|protected"
msgstr ""
+msgid "Take a look at the documentation to discover all of GitLab’s capabilities."
+msgstr ""
+
msgid "Target Branch"
msgstr ""
@@ -35836,6 +36571,9 @@ msgstr ""
msgid "Tests"
msgstr ""
+msgid "Text (optional)"
+msgstr ""
+
msgid "Text added to the body of all email messages. %{character_limit} character limit"
msgstr ""
@@ -35887,6 +36625,9 @@ msgstr ""
msgid "The CSV export will be created in the background. Once finished, it will be sent to %{email} in an attachment."
msgstr ""
+msgid "The CSV export you requested of all user memberships is attached to this email."
+msgstr ""
+
msgid "The GitLab subscription service (customers.gitlab.com) is currently experiencing an outage. You can monitor the status and get updates at %{linkStart}status.gitlab.com%{linkEnd}."
msgstr ""
@@ -35962,6 +36703,9 @@ 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 epic"
+msgstr ""
+
msgid "The current issue"
msgstr ""
@@ -36124,6 +36868,9 @@ msgstr ""
msgid "The latest pipeline for this merge request has failed."
msgstr ""
+msgid "The license key is invalid."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -36139,6 +36886,9 @@ msgstr ""
msgid "The license was successfully uploaded and will be active from %{starts_at}. You can see the details below."
msgstr ""
+msgid "The license you uploaded is invalid. If the issue persists, contact support at %{link}."
+msgstr ""
+
msgid "The list creation wizard is already open"
msgstr ""
@@ -36760,10 +37510,13 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} and everything this project contains. %{strongOpen}There is no going back%{strongClose}"
+msgstr ""
+
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains."
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}on %{date}%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains. %{strongOpen}There is no going back.%{strongClose}"
msgstr ""
msgid "This action will %{strongOpen}permanently remove%{strongClose} %{codeOpen}%{group}%{codeClose} %{strongOpen}immediately%{strongClose}."
@@ -36892,9 +37645,6 @@ msgstr ""
msgid "This file was modified for readability, and can't accept suggestions. Edit it directly."
msgstr ""
-msgid "This forked project has the following:"
-msgstr ""
-
msgid "This form is disabled in preview"
msgstr ""
@@ -36907,7 +37657,7 @@ msgstr ""
msgid "This group can't be removed because it is linked to a subscription. To remove this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
-msgid "This group can't be transfered because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
+msgid "This group can't be transferred because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
msgid "This group cannot be invited to a project inside a group with enforced SSO"
@@ -36934,6 +37684,9 @@ 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 incident is already escalated with '%{escalation_policy_name}'."
+msgstr ""
+
msgid "This invitation was sent to %{mail_to_invite_email}, but you are signed in as %{link_to_current_user} with email %{mail_to_current_user}."
msgstr ""
@@ -36952,9 +37705,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 merge train pipeline"
-msgstr ""
-
msgid "This is a private email address %{helpIcon} generated just for you. Anyone who has it can create issues or merge requests as if they were you. If that happens, %{resetLinkStart}reset this token%{resetLinkEnd}."
msgstr ""
@@ -36976,6 +37726,12 @@ msgstr ""
msgid "This is your current session"
msgstr ""
+msgid "This issue cannot be assigned to a confidential epic because it is public."
+msgstr ""
+
+msgid "This issue cannot be made public because it belongs to a confidential epic."
+msgstr ""
+
msgid "This issue is confidential and should only be visible to team members with at least Reporter access."
msgstr ""
@@ -37093,6 +37849,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 branch is protected from force push."
+msgstr ""
+
msgid "This merge request cannot be rebased while there are conflicts."
msgstr ""
@@ -37144,9 +37903,15 @@ msgstr ""
msgid "This pipeline was triggered by a schedule."
msgstr ""
+msgid "This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project"
msgstr ""
+msgid "This project can be restored until %{date}."
+msgstr ""
+
msgid "This project cannot be %{visibilityLevel} because the visibility of %{openShowLink}%{name}%{closeShowLink} is %{visibility}. To make this project %{visibilityLevel}, you must first %{openEditLink}change the visibility%{closeEditLink} of the parent group."
msgstr ""
@@ -37165,6 +37930,9 @@ msgstr ""
msgid "This project is %{strongStart}NOT%{strongEnd} a fork, and has the following:"
msgstr ""
+msgid "This project is %{strongStart}NOT%{strongEnd} a fork. This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -37858,6 +38626,9 @@ msgstr ""
msgid "Today"
msgstr "Danas"
+msgid "Todos count"
+msgstr ""
+
msgid "Todos|Are you looking for things to do? Take a look at %{strongStart}%{openIssuesLinkStart}open issues%{openIssuesLinkEnd}%{strongEnd}, contribute to %{strongStart}%{mergeRequestLinkStart}a merge request%{mergeRequestLinkEnd}%{mergeRequestLinkEnd}%{strongEnd}, or mention someone in a comment to automatically assign them a new to-do item."
msgstr ""
@@ -38131,11 +38902,8 @@ msgstr ""
msgid "Trending"
msgstr ""
-msgid "Trials|%{planName} Trial %{enDash} %{num} day left"
-msgid_plural "Trials|%{planName} Trial %{enDash} %{num} days left"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgid "Trials|%{planName} Trial"
+msgstr ""
msgid "Trials|Compare all plans"
msgstr ""
@@ -38143,6 +38911,9 @@ msgstr ""
msgid "Trials|Create a new group to start your GitLab Ultimate trial."
msgstr ""
+msgid "Trials|Day %{daysUsed}/%{duration}"
+msgstr ""
+
msgid "Trials|Go back to GitLab"
msgstr ""
@@ -38392,7 +39163,7 @@ msgstr ""
msgid "URL is triggered when repository is updated"
msgstr ""
-msgid "URL must be percent-encoded if neccessary."
+msgid "URL must be percent-encoded if necessary."
msgstr ""
msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
@@ -38611,6 +39382,9 @@ msgstr ""
msgid "Unlock account"
msgstr ""
+msgid "Unlock more features with GitLab Ultimate"
+msgstr ""
+
msgid "Unlock the discussion"
msgstr ""
@@ -38674,6 +39448,9 @@ msgstr ""
msgid "Unsubscribes from this %{quick_action_target}."
msgstr ""
+msgid "Unsupported sort value."
+msgstr ""
+
msgid "Unsupported todo type passed. Supported todo types are: %{todo_types}"
msgstr ""
@@ -38902,6 +39679,9 @@ msgstr ""
msgid "UsageQuota|File attachments and smaller design graphics."
msgstr ""
+msgid "UsageQuota|From %{storage_enforcement_date} storage limits will apply to this namespace. View and manage your usage in %{strong_start}Group Settings &gt; Usage quotas%{strong_end}."
+msgstr ""
+
msgid "UsageQuota|Git repository."
msgstr ""
@@ -38962,6 +39742,9 @@ msgstr ""
msgid "UsageQuota|Storage type"
msgstr ""
+msgid "UsageQuota|Storage used"
+msgstr ""
+
msgid "UsageQuota|This is the total amount of storage used across your projects within this namespace."
msgstr ""
@@ -39157,6 +39940,12 @@ msgstr ""
msgid "Use hashed storage paths for newly created and renamed repositories. Always enabled since 13.0."
msgstr ""
+msgid "Use issue count"
+msgstr ""
+
+msgid "Use issue weight"
+msgstr ""
+
msgid "Use one line per URI"
msgstr ""
@@ -39538,6 +40327,9 @@ msgstr ""
msgid "Users"
msgstr ""
+msgid "Users API rate limit"
+msgstr ""
+
msgid "Users can launch a development environment from a GitLab browser tab when the %{linkStart}Gitpod%{linkEnd} integration is enabled."
msgstr ""
@@ -39865,6 +40657,9 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View group pipeline usage quota"
+msgstr ""
+
msgid "View incident details at"
msgstr ""
@@ -40018,6 +40813,9 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
+msgid "Vulnerability"
+msgstr ""
+
msgid "Vulnerability Report"
msgstr ""
@@ -40069,6 +40867,9 @@ msgstr ""
msgid "VulnerabilityManagement|An unverified non-confirmed finding"
msgstr ""
+msgid "VulnerabilityManagement|At least one identifier is required"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -40078,12 +40879,24 @@ msgstr ""
msgid "VulnerabilityManagement|Create Jira issue"
msgstr ""
+msgid "VulnerabilityManagement|Enter a name"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE code"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE identifier URL"
+msgstr ""
+
msgid "VulnerabilityManagement|Fetching linked Jira issues"
msgstr ""
msgid "VulnerabilityManagement|Manually add a vulnerability entry into the vulnerability report."
msgstr ""
+msgid "VulnerabilityManagement|Name is a required field"
+msgstr ""
+
msgid "VulnerabilityManagement|Needs triage"
msgstr ""
@@ -40099,6 +40912,18 @@ msgstr ""
msgid "VulnerabilityManagement|Select a method"
msgstr ""
+msgid "VulnerabilityManagement|Select a severity level"
+msgstr ""
+
+msgid "VulnerabilityManagement|Select a status"
+msgstr ""
+
+msgid "VulnerabilityManagement|Severity is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Something went wrong while creating vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -40123,6 +40948,12 @@ msgstr ""
msgid "VulnerabilityManagement|Something went wrong, could not update vulnerability state."
msgstr ""
+msgid "VulnerabilityManagement|Status is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Submit vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Summary, detailed description, steps to reproduce, etc."
msgstr ""
@@ -40318,6 +41149,9 @@ msgstr ""
msgid "WARNING:"
msgstr ""
+msgid "WARNING: This snippet contains hidden files which might be used to mask malicious behavior. Exercise caution if cloning and executing code from this snippet."
+msgstr ""
+
msgid "Wait for the file to load to copy its contents"
msgstr ""
@@ -40537,6 +41371,15 @@ msgstr ""
msgid "Webhooks|An issue is created, updated, closed, or reopened."
msgstr ""
+msgid "Webhooks|Are you sure you want to delete this group hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this project hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this webhook?"
+msgstr ""
+
msgid "Webhooks|Comments"
msgstr ""
@@ -40546,6 +41389,9 @@ msgstr ""
msgid "Webhooks|Confidential issues events"
msgstr ""
+msgid "Webhooks|Delete webhook"
+msgstr ""
+
msgid "Webhooks|Deployment events"
msgstr ""
@@ -40780,6 +41626,9 @@ msgstr ""
msgid "Wiki"
msgstr ""
+msgid "Wiki page"
+msgstr ""
+
msgid "Wiki page was successfully created."
msgstr ""
@@ -40885,7 +41734,7 @@ msgstr ""
msgid "WikiPageConflictMessage|Someone edited the page the same time you did. Please check out %{wikiLinkStart}the page%{wikiLinkEnd} and make sure your changes will not unintentionally remove theirs."
msgstr ""
-msgid "WikiPage|An error occured while trying to render the content editor. Please try again later."
+msgid "WikiPage|An error occurred while trying to render the content editor. Please try again later."
msgstr ""
msgid "WikiPage|Are you sure you want to switch back to the classic editor?"
@@ -41044,6 +41893,18 @@ msgstr ""
msgid "WorkItem|New Task"
msgstr ""
+msgid "WorkItem|Something went wrong when creating a work item. Please try again"
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching the work item. Please try again."
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching work item types. Please try again"
+msgstr ""
+
+msgid "WorkItem|Type"
+msgstr ""
+
msgid "WorkItem|Work Items"
msgstr ""
@@ -41110,7 +41971,10 @@ msgstr ""
msgid "You are about to add %{usersTag} people to the discussion. They will all receive a notification."
msgstr ""
-msgid "You are about to permanently delete this project"
+msgid "You are about to delete this forked project containing:"
+msgstr ""
+
+msgid "You are about to delete this project containing:"
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."
@@ -41131,6 +41995,9 @@ msgstr ""
msgid "You are attempting to update a file that has changed since you started editing it."
msgstr ""
+msgid "You are billed if you exceed this number. %{qsrOverageLinkStart}How does billing work?%{qsrOverageLinkEnd}"
+msgstr ""
+
msgid "You are connected to the Prometheus server, but there is currently no data to display."
msgstr ""
@@ -41188,6 +42055,9 @@ msgstr ""
msgid "You are not authorized to update this scanner profile"
msgstr ""
+msgid "You are not authorized to upload metric images"
+msgstr ""
+
msgid "You are now impersonating %{username}"
msgstr ""
@@ -41341,9 +42211,6 @@ msgstr ""
msgid "You can only upload one design when dropping onto an existing design."
msgstr ""
-msgid "You can recover this project until %{date}"
-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 ""
@@ -41392,9 +42259,6 @@ msgstr ""
msgid "You cannot write to this read-only GitLab instance."
msgstr ""
-msgid "You can’t %{tag_start}edit%{tag_end} files directly in this project. Fork this project and submit a merge request with your changes."
-msgstr ""
-
msgid "You can’t edit files directly in this project. Fork this project and submit a merge request with your changes."
msgstr ""
@@ -41548,9 +42412,6 @@ 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 set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
@@ -41581,12 +42442,6 @@ msgstr ""
msgid "You must have maintainer access to force delete a lock"
msgstr ""
-msgid "You must have permission to create a project in a group before forking."
-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 ""
@@ -41992,7 +42847,7 @@ msgstr ""
msgid "Your public email will be displayed on your public profile."
msgstr ""
-msgid "Your request for access could not be processed: %{error_meesage}"
+msgid "Your request for access could not be processed: %{error_message}"
msgstr ""
msgid "Your request for access has been queued for review."
@@ -42178,6 +43033,9 @@ msgstr ""
msgid "archived:"
msgstr ""
+msgid "artifacts"
+msgstr ""
+
msgid "assign yourself"
msgstr ""
@@ -42208,6 +43066,9 @@ msgstr[2] ""
msgid "branch name"
msgstr ""
+msgid "builds"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -42634,6 +43495,9 @@ msgstr ""
msgid "contact with same email already exists in group hierarchy"
msgstr ""
+msgid "container registry images"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -42673,6 +43537,9 @@ msgstr ""
msgid "data"
msgstr ""
+msgid "database"
+msgstr ""
+
msgid "date must not be after 9999-12-31"
msgstr ""
@@ -42697,9 +43564,6 @@ msgstr "postavi"
msgid "design"
msgstr "dizajn"
-msgid "detached"
-msgstr ""
-
msgid "disabled"
msgstr ""
@@ -42952,7 +43816,7 @@ msgstr ""
msgid "is not a valid X509 certificate."
msgstr ""
-msgid "is not allowed for sign-up."
+msgid "is not allowed for sign-up. Please use your regular email address."
msgstr ""
msgid "is not allowed for this group."
@@ -42964,7 +43828,7 @@ msgstr ""
msgid "is not allowed since the group is not top-level group."
msgstr ""
-msgid "is not allowed."
+msgid "is not allowed. Please use your regular email address."
msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
@@ -43051,6 +43915,9 @@ msgstr "manje od minute"
msgid "level: %{level}"
msgstr ""
+msgid "lfs objects"
+msgstr ""
+
msgid "limit of %{project_limit} reached"
msgstr ""
@@ -43273,6 +44140,9 @@ msgstr ""
msgid "mrWidget|Merge blocked: pipeline must succeed. It's waiting for a manual action to continue."
msgstr ""
+msgid "mrWidget|Merge blocked: pipeline must succeed. Push a commit that fixes the failure, or %{linkStart}learn about other solutions.%{linkEnd}"
+msgstr ""
+
msgid "mrWidget|Merge blocked: this merge request must be approved."
msgstr ""
@@ -43390,9 +44260,6 @@ msgstr ""
msgid "mrWidget|The changes were not merged into"
msgstr ""
-msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -43540,9 +44407,6 @@ msgstr ""
msgid "open issue"
msgstr ""
-msgid "opened %{timeAgo}"
-msgstr ""
-
msgid "or"
msgstr ""
@@ -43555,6 +44419,12 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
+msgid "packages"
+msgstr ""
+
+msgid "pages"
+msgstr ""
+
msgid "parent"
msgid_plural "parents"
msgstr[0] ""
@@ -43708,6 +44578,9 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
+msgid "repositories"
+msgstr ""
+
msgid "repository:"
msgstr ""
@@ -43828,12 +44701,18 @@ msgstr ""
msgid "tag name"
msgstr ""
+msgid "terraform states"
+msgstr ""
+
msgid "the correct format."
msgstr ""
msgid "the file"
msgstr ""
+msgid "the following epic(s)"
+msgstr ""
+
msgid "the following issue(s)"
msgstr "sljedeći zadaci"
@@ -43846,21 +44725,12 @@ msgstr ""
msgid "this document"
msgstr ""
-msgid "this issue cannot be assigned to a confidential epic since it is public"
-msgstr ""
-
-msgid "this issue cannot be made public since it belongs to a confidential epic"
-msgstr ""
-
msgid "time summary"
msgstr ""
msgid "toggle collapse"
msgstr ""
-msgid "train"
-msgstr ""
-
msgid "triggered"
msgstr ""
@@ -43990,3 +44860,6 @@ msgstr ""
msgid "{project}"
msgstr ""
+msgid "✔"
+msgstr ""
+
diff --git a/locale/ca_ES/gitlab.po b/locale/ca_ES/gitlab.po
index 817cd3af60c..2253e6ec755 100644
--- a/locale/ca_ES/gitlab.po
+++ b/locale/ca_ES/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: ca\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2022-02-02 15:44\n"
+"PO-Revision-Date: 2022-03-01 20:38\n"
msgid " %{start} to %{end}"
msgstr " Des de %{start} fins %{end}"
@@ -146,6 +146,11 @@ msgid_plural "%d approvers (you've approved)"
msgstr[0] ""
msgstr[1] ""
+msgid "%d assigned issue"
+msgid_plural "%d assigned issues"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] "%d fitxer modificat"
@@ -421,8 +426,23 @@ msgid_plural "%d vulnerabilities dismissed"
msgstr[0] "%d vulnerabilitat descartada"
msgstr[1] "%d vulnerabilitats descartades"
-msgid "%d vulnerability updated"
-msgid_plural "%d vulnerabilities updated"
+msgid "%d vulnerability set to confirmed"
+msgid_plural "%d vulnerabilities set to confirmed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to dismissed"
+msgid_plural "%d vulnerabilities set to dismissed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to needs triage"
+msgid_plural "%d vulnerabilities set to needs triage"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to resolved"
+msgid_plural "%d vulnerabilities set to resolved"
msgstr[0] ""
msgstr[1] ""
@@ -510,6 +530,12 @@ msgstr[1] ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{completed} of %{total} issues closed"
+msgstr ""
+
+msgid "%{completed} of %{total} weight completed"
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -858,6 +884,9 @@ msgstr ""
msgid "%{openedIssues} open, %{closedIssues} closed"
msgstr ""
+msgid "%{percentage}%% issues closed"
+msgstr ""
+
msgid "%{percentage}%% weight completed"
msgstr "%{percentage}%% del pes completat"
@@ -1287,6 +1316,9 @@ msgid_plural "- Users"
msgstr[0] ""
msgstr[1] ""
+msgid "- of - issues closed"
+msgstr ""
+
msgid "- of - weight completed"
msgstr ""
@@ -1429,7 +1461,7 @@ msgstr ""
msgid "1000+"
msgstr ""
-msgid "192.168.0.0/24"
+msgid "192.168.0.0/24 or 2001:0DB8:1234::/48"
msgstr ""
msgid "1st contribution!"
@@ -1741,13 +1773,13 @@ msgstr ""
msgid "AWS Access Key"
msgstr ""
-msgid "AWS Access Key. Only required if not using role instance credentials"
+msgid "AWS Secret Access Key"
msgstr ""
-msgid "AWS Secret Access Key"
+msgid "AWS access key ID (Optional)"
msgstr ""
-msgid "AWS Secret Access Key. Only required if not using role instance credentials"
+msgid "AWS secret access key (Optional)"
msgstr ""
msgid "AWS service error: %{error}"
@@ -1807,9 +1839,6 @@ msgstr ""
msgid "Access granted"
msgstr ""
-msgid "Access key ID"
-msgstr ""
-
msgid "Access requests"
msgstr ""
@@ -1984,7 +2013,7 @@ msgstr ""
msgid "Activity"
msgstr "Activitat"
-msgid "Activity|An error occured while retrieving activity. Reload the page to try again."
+msgid "Activity|An error occurred while retrieving activity. Reload the page to try again."
msgstr ""
msgid "Add"
@@ -2023,6 +2052,9 @@ msgstr ""
msgid "Add a %{type}"
msgstr ""
+msgid "Add a GCP region"
+msgstr ""
+
msgid "Add a GPG key"
msgstr ""
@@ -2074,6 +2106,9 @@ msgstr ""
msgid "Add a numbered list"
msgstr ""
+msgid "Add a related epic"
+msgstr ""
+
msgid "Add a related issue"
msgstr ""
@@ -2188,6 +2223,9 @@ msgstr ""
msgid "Add or subtract spent time"
msgstr ""
+msgid "Add people"
+msgstr ""
+
msgid "Add previously merged commits"
msgstr ""
@@ -2254,6 +2292,9 @@ msgstr ""
msgid "Add webhook"
msgstr ""
+msgid "Add your team members and others to GitLab."
+msgstr ""
+
msgid "Add/remove"
msgstr ""
@@ -3076,12 +3117,6 @@ msgstr ""
msgid "AdvancedSearch|Reindex required"
msgstr ""
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. Permanently deleting this project will %{strongStart}immediately delete%{strongEnd} its repositories and %{strongStart}all related resources%{strongEnd}, including issues, merge requests etc."
-msgstr ""
-
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. You will lose this project's repository and %{strongStart}all related resources%{strongEnd}, including issues and merge requests."
-msgstr ""
-
msgid "After a successful password update you will be redirected to login screen."
msgstr ""
@@ -3112,6 +3147,9 @@ msgstr ""
msgid "Akismet helps prevent the creation of spam issues in public projects."
msgstr ""
+msgid "Alert"
+msgstr ""
+
msgid "AlertManagement|Acknowledged"
msgstr ""
@@ -3484,9 +3522,6 @@ msgstr ""
msgid "All environments"
msgstr ""
-msgid "All epics"
-msgstr ""
-
msgid "All groups and projects"
msgstr ""
@@ -4223,12 +4258,15 @@ msgstr ""
msgid "ApplicationSettings|Approve users in the pending approval status?"
msgstr ""
-msgid "ApplicationSettings|By making this change, you will automatically approve %d user with the pending approval status."
-msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users with the pending approval status."
+msgid "ApplicationSettings|Approve users who are pending approval?"
+msgstr ""
+
+msgid "ApplicationSettings|By making this change, you will automatically approve %d user who is pending approval."
+msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users who are pending approval."
msgstr[0] ""
msgstr[1] ""
-msgid "ApplicationSettings|By making this change, you will automatically approve all users in pending approval status."
+msgid "ApplicationSettings|By making this change, you will automatically approve all users who are pending approval."
msgstr ""
msgid "ApplicationSettings|Denied domains for sign-ups"
@@ -4634,10 +4672,10 @@ msgstr "Projectes arxivats"
msgid "Archiving the project will make it entirely read-only. It is hidden from the dashboard and doesn't show up in searches. %{strong_start}The repository cannot be committed to, and no issues, comments, or other entities can be created.%{strong_end} %{link_start}Learn more.%{link_end}"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to delete this project?"
+msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
+msgid "Are you absolutely sure?"
msgstr ""
msgid "Are you sure that you want to archive this project?"
@@ -4673,12 +4711,18 @@ msgstr ""
msgid "Are you sure you want to delete this SSH key?"
msgstr ""
+msgid "Are you sure you want to delete this comment?"
+msgstr ""
+
msgid "Are you sure you want to delete this deploy key?"
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 label?"
+msgstr ""
+
msgid "Are you sure you want to delete this pipeline schedule?"
msgstr ""
@@ -4694,9 +4738,6 @@ msgstr ""
msgid "Are you sure you want to discard your changes?"
msgstr ""
-msgid "Are you sure you want to erase this build?"
-msgstr ""
-
msgid "Are you sure you want to import %d repository?"
msgid_plural "Are you sure you want to import %d repositories?"
msgstr[0] ""
@@ -4744,6 +4785,9 @@ msgstr ""
msgid "Are you sure you want to remove this list?"
msgstr ""
+msgid "Are you sure you want to remove this nickname?"
+msgstr ""
+
msgid "Are you sure you want to reset the health check token?"
msgstr ""
@@ -4756,10 +4800,10 @@ 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?"
+msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
msgstr ""
-msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
+msgid "Are you sure you want to revoke this project access token? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to stop this environment?"
@@ -4906,9 +4950,6 @@ msgstr ""
msgid "Assigned to %{assignee_name}"
msgstr ""
-msgid "Assigned to %{name}"
-msgstr ""
-
msgid "Assigned to me"
msgstr ""
@@ -4973,6 +5014,9 @@ msgstr[1] ""
msgid "Attaching the file failed."
msgstr ""
+msgid "Attention"
+msgstr ""
+
msgid "Audit Events"
msgstr ""
@@ -5135,6 +5179,12 @@ msgstr ""
msgid "Authorized applications (%{size})"
msgstr ""
+msgid "AuthorizedApplication|Are you sure you want to revoke this application?"
+msgstr ""
+
+msgid "AuthorizedApplication|Revoke application"
+msgstr ""
+
msgid "Authors: %{authors}"
msgstr ""
@@ -6328,6 +6378,9 @@ msgstr ""
msgid "CICDAnalytics|Shared Runners Usage"
msgstr ""
+msgid "CICDAnalytics|Shared runner pipeline minute duration by month"
+msgstr ""
+
msgid "CICDAnalytics|Shared runner usage"
msgstr ""
@@ -6469,6 +6522,9 @@ msgstr ""
msgid "Can create groups:"
msgstr ""
+msgid "Can not delete primary training"
+msgstr ""
+
msgid "Can't apply as the source branch was deleted."
msgstr ""
@@ -6802,9 +6858,6 @@ msgstr ""
msgid "Changing any setting here requires an application restart"
msgstr ""
-msgid "Changing group URL can have unintended side effects."
-msgstr ""
-
msgid "Charts can't be displayed as the request for data has timed out. %{documentationLink}"
msgstr ""
@@ -6892,9 +6945,6 @@ msgstr ""
msgid "Checking branch availability..."
msgstr ""
-msgid "Checking group URL availability..."
-msgstr ""
-
msgid "Checking group path availability..."
msgstr ""
@@ -7388,6 +7438,9 @@ msgstr ""
msgid "Clear recent searches"
msgstr ""
+msgid "Clear repository checks"
+msgstr ""
+
msgid "Clear search"
msgstr ""
@@ -7520,9 +7573,6 @@ msgstr ""
msgid "Closed MRs"
msgstr ""
-msgid "Closed epics"
-msgstr ""
-
msgid "Closed issues"
msgstr "Incidències tancades"
@@ -7559,13 +7609,13 @@ msgstr ""
msgid "Cluster level"
msgstr ""
-msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
+msgid "Cluster type must be specified for Stages::ClusterEndpointInserter"
msgstr ""
msgid "ClusterAgents|%{name} successfully deleted"
msgstr ""
-msgid "ClusterAgents|%{number} of %{total} Agents"
+msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
@@ -7607,6 +7657,15 @@ msgstr ""
msgid "ClusterAgents|Agent never connected to GitLab"
msgstr ""
+msgid "ClusterAgents|Agent version mismatch"
+msgstr ""
+
+msgid "ClusterAgents|Agent version mismatch and update"
+msgstr ""
+
+msgid "ClusterAgents|Agent version update required"
+msgstr ""
+
msgid "ClusterAgents|All"
msgstr ""
@@ -7631,7 +7690,7 @@ msgstr ""
msgid "ClusterAgents|Configuration"
msgstr ""
-msgid "ClusterAgents|Connect a cluster through the Agent"
+msgid "ClusterAgents|Connect a cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connect existing cluster"
@@ -7640,13 +7699,13 @@ msgstr ""
msgid "ClusterAgents|Connect with a certificate"
msgstr ""
-msgid "ClusterAgents|Connect with agent"
+msgid "ClusterAgents|Connect with an agent"
msgstr ""
msgid "ClusterAgents|Connect with the GitLab Agent"
msgstr ""
-msgid "ClusterAgents|Connect your cluster through the Agent"
+msgid "ClusterAgents|Connect your cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connected"
@@ -7706,7 +7765,10 @@ msgstr ""
msgid "ClusterAgents|How to register an agent?"
msgstr ""
-msgid "ClusterAgents|Install new Agent"
+msgid "ClusterAgents|How to update an agent?"
+msgstr ""
+
+msgid "ClusterAgents|Install a new agent"
msgstr ""
msgid "ClusterAgents|Last connected %{timeAgo}."
@@ -7733,7 +7795,7 @@ msgstr ""
msgid "ClusterAgents|Never connected"
msgstr ""
-msgid "ClusterAgents|No Agents"
+msgid "ClusterAgents|No agents"
msgstr ""
msgid "ClusterAgents|No clusters connected through cluster certificates"
@@ -7793,6 +7855,9 @@ msgstr ""
msgid "ClusterAgents|The agent has not been connected in a long time. There might be a connectivity issue. Last contact was %{timeAgo}."
msgstr ""
+msgid "ClusterAgents|The agent version do not match each other across your cluster's pods. This can happen when a new agent version was just deployed and Kubernetes is shutting down the old pods."
+msgstr ""
+
msgid "ClusterAgents|The recommended installation method includes the token. If you want to follow the advanced installation method provided in the docs, make sure you save the token value before you close this window."
msgstr ""
@@ -7840,6 +7905,9 @@ msgstr ""
msgid "ClusterAgents|You will need to create a token to connect to your agent"
msgstr ""
+msgid "ClusterAgents|Your agent version is out of sync with your GitLab version (v%{version}), which might cause compatibility problems. Update the agent installed on your cluster to the most recent version."
+msgstr ""
+
msgid "ClusterAgents|Your instance doesn't have the %{linkStart}GitLab Agent Server (KAS)%{linkEnd} set up. Ask a GitLab Administrator to install it."
msgstr ""
@@ -8716,9 +8784,6 @@ msgstr ""
msgid "Comma-separated list of email addresses."
msgstr ""
-msgid "Comma-separated list of users allowed to exceed the rate limit."
-msgstr ""
-
msgid "Comma-separated, e.g. '1.1.1.1, 2.2.2.0/24'"
msgstr ""
@@ -9045,6 +9110,12 @@ msgstr ""
msgid "Confidential"
msgstr "Confidencial"
+msgid "Confidential issue"
+msgstr ""
+
+msgid "Confidential note"
+msgstr ""
+
msgid "Confidentiality"
msgstr "Confidencialitat"
@@ -9078,6 +9149,9 @@ msgstr ""
msgid "Configure Dependency Scanning in `.gitlab-ci.yml`, creating this file if it does not already exist"
msgstr ""
+msgid "Configure GitLab"
+msgstr ""
+
msgid "Configure GitLab runners to start using the Web Terminal. %{helpStart}Learn more.%{helpEnd}"
msgstr ""
@@ -9126,6 +9200,15 @@ msgstr ""
msgid "Configure pipelines to deploy web apps, backend services, APIs and static resources to Google Cloud"
msgstr ""
+msgid "Configure region"
+msgstr ""
+
+msgid "Configure region for environment"
+msgstr ""
+
+msgid "Configure regions"
+msgstr ""
+
msgid "Configure repository mirroring."
msgstr ""
@@ -9159,6 +9242,9 @@ msgstr ""
msgid "Configure which lists are shown for anyone who visits this board"
msgstr ""
+msgid "Configure your environments to be deployed to specific geographical regions"
+msgstr ""
+
msgid "Confirm"
msgstr ""
@@ -9861,10 +9947,10 @@ msgstr ""
msgid "CorpusManagement|Actions"
msgstr ""
-msgid "CorpusManagement|Corpus are used in fuzz testing as mutation source to Improve future testing."
+msgid "CorpusManagement|Corpus file"
msgstr ""
-msgid "CorpusManagement|Corpus file"
+msgid "CorpusManagement|Corpus files are used in coverage-guided fuzz testing as seed inputs to improve testing."
msgstr ""
msgid "CorpusManagement|Corpus files must be in *.zip format. Maximum 5 GB"
@@ -9918,6 +10004,9 @@ msgstr ""
msgid "Could not apply %{name} command."
msgstr ""
+msgid "Could not apply %{name} command. %{message}."
+msgstr ""
+
msgid "Could not authorize chat nickname. Try again!"
msgstr ""
@@ -10068,6 +10157,9 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
+msgid "Create a group"
+msgstr ""
+
msgid "Create a merge request"
msgstr ""
@@ -10092,6 +10184,9 @@ msgstr ""
msgid "Create a personal access token on your account to pull or push via %{protocol}."
msgstr ""
+msgid "Create a project"
+msgstr ""
+
msgid "Create an account using:"
msgstr ""
@@ -10455,6 +10550,9 @@ msgstr ""
msgid "Creation date"
msgstr ""
+msgid "Creator"
+msgstr ""
+
msgid "Credentials"
msgstr ""
@@ -10467,9 +10565,15 @@ msgstr ""
msgid "CredentialsInventory|Personal Access Tokens"
msgstr ""
+msgid "CredentialsInventory|Project Access Tokens"
+msgstr ""
+
msgid "CredentialsInventory|SSH Keys"
msgstr ""
+msgid "Credit card required to be on file in order to create a pipeline"
+msgstr ""
+
msgid "Credit card:"
msgstr ""
@@ -10653,9 +10757,6 @@ msgstr ""
msgid "Customer relations"
msgstr ""
-msgid "Customizable by an administrator."
-msgstr ""
-
msgid "Customizable by owners."
msgstr ""
@@ -10785,30 +10886,18 @@ msgstr ""
msgid "CycleAnalytics|%{selectedLabelsCount} selected (%{maxLabels} max)"
msgstr ""
-msgid "CycleAnalytics|%{stageCount} stages selected"
-msgstr ""
-
-msgid "CycleAnalytics|All stages"
-msgstr ""
-
-msgid "CycleAnalytics|Average days to completion"
+msgid "CycleAnalytics|Average time to completion"
msgstr ""
msgid "CycleAnalytics|Date"
msgstr ""
-msgid "CycleAnalytics|Days to completion"
-msgstr ""
-
msgid "CycleAnalytics|Display chart filters"
msgstr ""
msgid "CycleAnalytics|Lead Time for Changes"
msgstr ""
-msgid "CycleAnalytics|No stages selected"
-msgstr ""
-
msgid "CycleAnalytics|Number of tasks"
msgstr ""
@@ -10837,18 +10926,30 @@ msgstr ""
msgid "CycleAnalytics|Showing data for group '%{groupName}' from %{createdAfter} to %{createdBefore}"
msgstr ""
-msgid "CycleAnalytics|Stages"
+msgid "CycleAnalytics|Stage time: %{title}"
msgstr ""
msgid "CycleAnalytics|Tasks by type"
msgstr ""
-msgid "CycleAnalytics|The average time spent in the selected stage for the items that were completed on each date. Data limited to the last 500 items."
+msgid "CycleAnalytics|The average time items spent in this stage. Data limited to items completed within this date range."
msgstr ""
msgid "CycleAnalytics|The given date range is larger than 180 days"
msgstr ""
+msgid "CycleAnalytics|The total time items spent across each value stream stage. Data limited to items completed within this date range."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Stage time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Total time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|Total time"
+msgstr ""
+
msgid "CycleAnalytics|Type of work"
msgstr ""
@@ -10861,9 +10962,6 @@ msgstr ""
msgid "CycleAnalytics|project dropdown filter"
msgstr ""
-msgid "CycleAnalytics|stage dropdown"
-msgstr ""
-
msgid "DAG visualization requires at least 3 dependent jobs."
msgstr ""
@@ -10963,10 +11061,16 @@ msgstr ""
msgid "DastProfiles|AJAX spider"
msgstr ""
+msgid "DastProfiles|API"
+msgstr ""
+
+msgid "DastProfiles|API endpoint URL"
+msgstr ""
+
msgid "DastProfiles|Active"
msgstr ""
-msgid "DastProfiles|Additional request headers (Optional)"
+msgid "DastProfiles|Additional request headers (optional)"
msgstr ""
msgid "DastProfiles|Are you sure you want to delete this profile?"
@@ -10981,6 +11085,9 @@ msgstr ""
msgid "DastProfiles|Branch missing"
msgstr ""
+msgid "DastProfiles|Choose a scan method"
+msgstr ""
+
msgid "DastProfiles|Could not create the scanner profile. Please try again."
msgstr ""
@@ -11050,7 +11157,13 @@ msgstr ""
msgid "DastProfiles|Excluded URLs"
msgstr ""
-msgid "DastProfiles|Excluded URLs (Optional)"
+msgid "DastProfiles|Excluded URLs (optional)"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths (optional)"
msgstr ""
msgid "DastProfiles|Hide debug messages"
@@ -11107,9 +11220,6 @@ msgstr ""
msgid "DastProfiles|Request headers"
msgstr ""
-msgid "DastProfiles|Rest API"
-msgstr ""
-
msgid "DastProfiles|Run the AJAX spider, in addition to the traditional spider, to crawl the target site."
msgstr ""
@@ -11119,6 +11229,9 @@ msgstr ""
msgid "DastProfiles|Save profile"
msgstr ""
+msgid "DastProfiles|Scan method"
+msgstr ""
+
msgid "DastProfiles|Scan mode"
msgstr ""
@@ -11197,12 +11310,24 @@ msgstr ""
msgid "DastProfiles|Website"
msgstr ""
+msgid "DastProfiles|What does each method do?"
+msgstr ""
+
msgid "DastProfiles|You can either choose a passive scan or validate the target site from the site profile management page. %{docsLinkStart}Learn more about site validation.%{docsLinkEnd}"
msgstr ""
msgid "DastProfiles|You cannot run an active scan against an unvalidated site."
msgstr ""
+msgid "DastProfiles|folder/dast_example.har or https://example.com/dast_example.har"
+msgstr ""
+
+msgid "DastProfiles|folder/example.postman_collection.json or https://example.com/"
+msgstr ""
+
+msgid "DastProfiles|folder/openapi.json or https://example.com/openapi.json"
+msgstr ""
+
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
@@ -11310,6 +11435,9 @@ msgstr ""
msgid "DatadogIntegration|API URL"
msgstr ""
+msgid "DatadogIntegration|Custom tags in Datadog. Enter one tag per line in the %{codeOpen}key:value%{codeClose} format. %{linkOpen}How do I use tags?%{linkClose}"
+msgstr ""
+
msgid "DatadogIntegration|Environment"
msgstr ""
@@ -11328,12 +11456,18 @@ msgstr ""
msgid "DatadogIntegration|Tag all data from this GitLab instance in Datadog. Useful when managing several self-managed deployments."
msgstr ""
+msgid "DatadogIntegration|Tags"
+msgstr ""
+
msgid "DatadogIntegration|The Datadog site to send data to. To send data to the EU site, use %{codeOpen}datadoghq.eu%{codeClose}."
msgstr ""
msgid "DatadogIntegration|Trace your GitLab pipelines with Datadog."
msgstr ""
+msgid "DatadogIntegration|have an invalid format"
+msgstr ""
+
msgid "Datasource name not found"
msgstr ""
@@ -11343,9 +11477,6 @@ msgstr ""
msgid "Date merged"
msgstr ""
-msgid "Date picker"
-msgstr "Selector de data"
-
msgid "Date range"
msgstr ""
@@ -11499,9 +11630,6 @@ msgstr ""
msgid "Definition"
msgstr ""
-msgid "Delayed Project Deletion (%{adjourned_deletion})"
-msgstr ""
-
msgid "DelayedJobs|Are you sure you want to run %{jobName} immediately? Otherwise this job will run automatically after its timer finishes."
msgstr ""
@@ -11580,10 +11708,10 @@ msgstr ""
msgid "Delete pipeline"
msgstr ""
-msgid "Delete project"
+msgid "Delete pipeline schedule"
msgstr ""
-msgid "Delete project. Are you ABSOLUTELY SURE?"
+msgid "Delete project"
msgstr ""
msgid "Delete row"
@@ -11613,6 +11741,9 @@ msgstr ""
msgid "Delete this epic and all descendants?"
msgstr ""
+msgid "Delete this project"
+msgstr ""
+
msgid "Delete user list"
msgstr ""
@@ -11871,6 +12002,12 @@ msgstr ""
msgid "Deploy to..."
msgstr ""
+msgid "DeployBoards|To see deployment progress for your environments, make sure you are deploying to %{codeStart}$KUBE_NAMESPACE%{codeEnd} and annotating with %{codeStart}app.gitlab.com/app=$CI_PROJECT_PATH_SLUG%{codeEnd} and %{codeStart}app.gitlab.com/env=$CI_ENVIRONMENT_SLUG%{codeEnd}."
+msgstr ""
+
+msgid "DeployBoard|Kubernetes Pods"
+msgstr ""
+
msgid "DeployFreeze|Add a freeze period to prevent unintended releases during a period of time for a given environment. You must update the deployment jobs in %{filename} according to the deploy freezes added here. %{freeze_period_link_start}Learn more.%{freeze_period_link_end}"
msgstr ""
@@ -11955,9 +12092,6 @@ msgstr ""
msgid "DeployTokens|Active Deploy Tokens (%{active_tokens})"
msgstr ""
-msgid "DeployTokens|Allows read and write access to registry images."
-msgstr ""
-
msgid "DeployTokens|Allows read and write access to the package registry."
msgstr ""
@@ -11970,6 +12104,9 @@ msgstr ""
msgid "DeployTokens|Allows read-only access to the repository."
msgstr ""
+msgid "DeployTokens|Allows write access to registry images."
+msgstr ""
+
msgid "DeployTokens|Copy deploy token"
msgstr ""
@@ -12063,12 +12200,57 @@ msgstr ""
msgid "Deploying to AWS is easy with GitLab"
msgstr ""
+msgid "Deployment"
+msgstr ""
+
msgid "Deployment Frequency"
msgstr ""
+msgid "Deployment Target|Project deployment target (optional)"
+msgstr ""
+
+msgid "Deployment Target|Select the deployment target"
+msgstr ""
+
msgid "Deployment frequency"
msgstr ""
+msgid "DeploymentTarget|GitLab Pages"
+msgstr ""
+
+msgid "DeploymentTarget|Heroku"
+msgstr ""
+
+msgid "DeploymentTarget|Infrastructure provider (Terraform, Cloudformation, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Kubernetes (GKE, EKS, OpenShift, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Managed container runtime (Fargate, Cloud Run, DigitalOcean App)"
+msgstr ""
+
+msgid "DeploymentTarget|Mobile app store"
+msgstr ""
+
+msgid "DeploymentTarget|No deployment planned"
+msgstr ""
+
+msgid "DeploymentTarget|Other hosting service"
+msgstr ""
+
+msgid "DeploymentTarget|Registry (package or container)"
+msgstr ""
+
+msgid "DeploymentTarget|Self-managed container runtime (Podman, Docker Swarm, Docker Compose)"
+msgstr ""
+
+msgid "DeploymentTarget|Serverless backend (Lambda, Cloud functions)"
+msgstr ""
+
+msgid "DeploymentTarget|Virtual machine (for example, EC2)"
+msgstr ""
+
msgid "Deployments"
msgstr ""
@@ -12107,6 +12289,9 @@ msgstr ""
msgid "Deployment|This deployment was created using the API"
msgstr ""
+msgid "Deployment|Triggerer"
+msgstr ""
+
msgid "Deployment|Waiting"
msgstr ""
@@ -12134,6 +12319,18 @@ msgstr ""
msgid "Deprecated API rate limits"
msgstr ""
+msgid "Deprecations|Feature deprecation and removal"
+msgstr ""
+
+msgid "Deprecations|For information on a possible replacement %{epicStart} learn more about Opstrace %{epicEnd}."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7 and are %{epicStart} scheduled for removal %{epicEnd} in GitLab 15.0."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7, and are %{removal_link_start} scheduled for removal %{link_end} in GitLab 15.0. For information on a possible replacement, %{opstrace_link_start} learn more about Opstrace %{link_end}."
+msgstr ""
+
msgid "Deprioritize label"
msgstr ""
@@ -12379,10 +12576,10 @@ msgstr ""
msgid "DevopsAdoption|At least one deploy"
msgstr ""
-msgid "DevopsAdoption|At least one issue opened"
+msgid "DevopsAdoption|At least one issue created"
msgstr ""
-msgid "DevopsAdoption|At least one merge request opened"
+msgid "DevopsAdoption|At least one merge request created"
msgstr ""
msgid "DevopsAdoption|At least one pipeline successfully run"
@@ -12583,6 +12780,9 @@ msgstr ""
msgid "Direct member"
msgstr ""
+msgid "Direct members"
+msgstr ""
+
msgid "Direct non-authenticated users to this page."
msgstr ""
@@ -12699,6 +12899,9 @@ msgid_plural "Dismiss %d selected vulnerabilities as"
msgstr[0] ""
msgstr[1] ""
+msgid "Dismiss Alert"
+msgstr ""
+
msgid "Dismiss merge request promotion"
msgstr ""
@@ -12726,9 +12929,15 @@ msgstr ""
msgid "Display alerts from all configured monitoring tools."
msgstr ""
+msgid "Display milestones"
+msgstr ""
+
msgid "Display name"
msgstr ""
+msgid "Display progress of child issues"
+msgstr ""
+
msgid "Display rendered file"
msgstr ""
@@ -12834,6 +13043,9 @@ msgstr ""
msgid "Download image"
msgstr ""
+msgid "Download payload"
+msgstr ""
+
msgid "Download raw data (.csv)"
msgstr ""
@@ -13011,6 +13223,9 @@ msgstr ""
msgid "Edit in Web IDE"
msgstr ""
+msgid "Edit in pipeline editor"
+msgstr ""
+
msgid "Edit in single-file editor"
msgstr ""
@@ -13053,6 +13268,9 @@ msgstr ""
msgid "Edit your most recent comment in a thread (from an empty textarea)"
msgstr ""
+msgid "Edit, lint, and visualize your pipeline."
+msgstr ""
+
msgid "Edited"
msgstr ""
@@ -13494,6 +13712,9 @@ msgstr ""
msgid "Enforce two-factor authentication for all user sign-ins."
msgstr ""
+msgid "Enhance security by storing service account keys in secret managers - learn more about %{docLinkStart}secret management with GitLab%{docLinkEnd}"
+msgstr ""
+
msgid "Ensure connectivity is available from the GitLab server to the Prometheus server"
msgstr ""
@@ -13554,6 +13775,9 @@ 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 following to confirm:"
+msgstr ""
+
msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
@@ -14084,9 +14308,6 @@ 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 ""
@@ -14222,6 +14443,9 @@ msgstr ""
msgid "Errors:"
msgstr ""
+msgid "Escalate this incident"
+msgstr ""
+
msgid "Escalation Policies"
msgstr ""
@@ -14234,6 +14458,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy"
+msgstr ""
+
msgid "Escalation policy:"
msgstr ""
@@ -14485,6 +14712,9 @@ msgstr ""
msgid "Existing sign in methods may be removed"
msgstr ""
+msgid "Exit."
+msgstr ""
+
msgid "Expand"
msgstr ""
@@ -14581,6 +14811,9 @@ msgstr "Explora els projectes"
msgid "Explore public groups"
msgstr ""
+msgid "Explore public projects"
+msgstr ""
+
msgid "Explore snippets"
msgstr ""
@@ -14742,7 +14975,7 @@ msgid_plural "Failed to archive designs. Please try again."
msgstr[0] ""
msgstr[1] ""
-msgid "Failed to assign a reviewer because no user was found."
+msgid "Failed to assign a reviewer because no user was specified."
msgstr ""
msgid "Failed to assign a user because no user was found."
@@ -14808,10 +15041,10 @@ msgstr ""
msgid "Failed to find import label for Jira import."
msgstr ""
-msgid "Failed to generate export, please try again later."
+msgid "Failed to find users for %{missing}"
msgstr ""
-msgid "Failed to generate report, please try again after sometime"
+msgid "Failed to generate export, please try again later."
msgstr ""
msgid "Failed to get ref."
@@ -14910,6 +15143,9 @@ msgstr ""
msgid "Failed to remove a to-do item for the design."
msgstr ""
+msgid "Failed to remove attention because no user was found."
+msgstr ""
+
msgid "Failed to remove mirror."
msgstr ""
@@ -14922,6 +15158,9 @@ msgstr ""
msgid "Failed to remove user key."
msgstr ""
+msgid "Failed to request attention because no user was found."
+msgstr ""
+
msgid "Failed to reset key. Please try again."
msgstr ""
@@ -15003,6 +15242,9 @@ msgstr ""
msgid "Feature Flags"
msgstr ""
+msgid "Feature deprecation and removal"
+msgstr ""
+
msgid "Feature flag status"
msgstr ""
@@ -15500,7 +15742,7 @@ msgstr ""
msgid "For each job, re-use the project workspace. If the workspace doesn't exist, use %{code_open}git clone%{code_close}."
msgstr ""
-msgid "For example, the application using the token or the purpose of the token."
+msgid "For example, the application using the token or the purpose of the token. Do not give sensitive information for the name of the token, as it will be visible to all %{resource_type} members."
msgstr ""
msgid "For files larger than this limit, only index the file name. The file content is neither indexed nor searchable."
@@ -15584,9 +15826,6 @@ msgstr ""
msgid "ForkProject|Select a namespace"
msgstr ""
-msgid "ForkProject|Select a namespace to fork the project"
-msgstr ""
-
msgid "ForkProject|The project can be accessed by any logged in user."
msgstr ""
@@ -15683,6 +15922,9 @@ msgstr ""
msgid "Full name"
msgstr ""
+msgid "GCP region configured"
+msgstr ""
+
msgid "GPG Key ID:"
msgstr ""
@@ -15863,6 +16105,9 @@ msgstr ""
msgid "Geo|Failed"
msgstr "Fallit"
+msgid "Geo|Filter Geo sites"
+msgstr ""
+
msgid "Geo|Filter by name"
msgstr ""
@@ -16274,6 +16519,12 @@ msgstr ""
msgid "GitLab Issue"
msgstr ""
+msgid "GitLab KAS"
+msgstr ""
+
+msgid "GitLab Memberships CSV Export"
+msgstr ""
+
msgid "GitLab Pages"
msgstr ""
@@ -16322,6 +16573,9 @@ 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 free to use. Many features for larger teams are part of our %{link_start}paid products%{link_end}. You can try Ultimate for free without any obligation or payment details."
+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 ""
@@ -16448,7 +16702,7 @@ msgstr ""
msgid "GitLabPages|When enabled, all attempts to visit your website through HTTP are automatically redirected to HTTPS using a response with status code 301. Requires a valid certificate for all domains. %{docs_link_start}Learn more.%{link_end}"
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. %{docs_link_start}Learn more.%{link_end}"
+msgid "GitLabPages|When using Pages under the general domain of a GitLab instance (%{pages_host}), you cannot use HTTPS with subdomains of subdomains. If your namespace or groupname contains a dot, it does not work. This is a limitation of the HTTP Over TLS protocol. HTTP pages work if you don't redirect HTTP to HTTPS. %{docs_link_start}Learn more.%{link_end}"
msgstr ""
msgid "GitLabPages|With GitLab Pages you can host your static website directly from your GitLab repository. %{docs_link_start}Learn more.%{link_end}"
@@ -16625,9 +16879,6 @@ msgstr ""
msgid "Go to find file"
msgstr ""
-msgid "Go to fork"
-msgstr ""
-
msgid "Go to issue boards"
msgstr ""
@@ -16835,9 +17086,6 @@ msgstr ""
msgid "Group Hooks"
msgstr ""
-msgid "Group ID"
-msgstr ""
-
msgid "Group Owner must have signed in with SAML before enabling Group Managed Accounts"
msgstr ""
@@ -16865,9 +17113,6 @@ msgstr ""
msgid "Group by"
msgstr ""
-msgid "Group description"
-msgstr ""
-
msgid "Group description (optional)"
msgstr ""
@@ -16982,7 +17227,7 @@ msgstr ""
msgid "Group: %{name}"
msgstr ""
-msgid "GroupActivityMetrics|Issues opened"
+msgid "GroupActivityMetrics|Issues created"
msgstr ""
msgid "GroupActivityMetrics|Last 90 days"
@@ -16991,7 +17236,7 @@ msgstr ""
msgid "GroupActivityMetrics|Members added"
msgstr ""
-msgid "GroupActivityMetrics|Merge Requests opened"
+msgid "GroupActivityMetrics|Merge Requests created"
msgstr ""
msgid "GroupActivityMetrics|Recent activity"
@@ -17282,6 +17527,9 @@ msgstr ""
msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
+msgid "GroupSettings|Choose a group path that does not start with a dash or end with a period. It can also contain alphanumeric characters and underscores."
+msgstr ""
+
msgid "GroupSettings|Compliance frameworks"
msgstr ""
@@ -17315,7 +17563,7 @@ msgstr ""
msgid "GroupSettings|If not specified at the group or instance level, the default is %{default_initial_branch_name}. Does not affect existing repositories."
msgstr ""
-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."
+msgid "GroupSettings|If the parent group's visibility is lower than the group's current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility."
msgstr ""
msgid "GroupSettings|New runners registration token has been generated!"
@@ -17432,7 +17680,10 @@ msgstr ""
msgid "Groups and projects"
msgstr ""
-msgid "Groups and subgroups"
+msgid "Groups are a great way to organize projects and people."
+msgstr ""
+
+msgid "Groups are the best way to manage projects and members."
msgstr ""
msgid "Groups to synchronize"
@@ -17543,13 +17794,16 @@ msgstr ""
msgid "GroupsTree|Are you sure you want to leave the \"%{fullName}\" group?"
msgstr ""
-msgid "GroupsTree|Edit group"
-msgstr "Edita el grup"
+msgid "GroupsTree|Delete"
+msgstr ""
+
+msgid "GroupsTree|Edit"
+msgstr ""
msgid "GroupsTree|Failed to leave the group. Please make sure you are not the only owner."
msgstr ""
-msgid "GroupsTree|Leave this group"
+msgid "GroupsTree|Leave group"
msgstr ""
msgid "GroupsTree|Loading groups"
@@ -17561,9 +17815,57 @@ msgstr ""
msgid "GroupsTree|No groups or projects matched your search"
msgstr ""
+msgid "GroupsTree|Options"
+msgstr ""
+
msgid "GroupsTree|Search by name"
msgstr ""
+msgid "Groups|Avatar will be removed. Are you sure?"
+msgstr ""
+
+msgid "Groups|Changing group URL can have unintended side effects."
+msgstr ""
+
+msgid "Groups|Checking group URL availability..."
+msgstr ""
+
+msgid "Groups|Enter a descriptive name for your group."
+msgstr ""
+
+msgid "Groups|Group ID"
+msgstr ""
+
+msgid "Groups|Group URL"
+msgstr ""
+
+msgid "Groups|Group avatar"
+msgstr ""
+
+msgid "Groups|Group description (optional)"
+msgstr ""
+
+msgid "Groups|Group name"
+msgstr ""
+
+msgid "Groups|Group path is available."
+msgstr ""
+
+msgid "Groups|Group path is unavailable. Path has been replaced with a suggested available path."
+msgstr ""
+
+msgid "Groups|Learn more"
+msgstr ""
+
+msgid "Groups|Must start with letter, digit, emoji, or underscore. Can also contain periods, dashes, spaces, and parentheses."
+msgstr ""
+
+msgid "Groups|Remove avatar"
+msgstr ""
+
+msgid "Groups|Save changes"
+msgstr ""
+
msgid "Guideline"
msgstr ""
@@ -17573,6 +17875,9 @@ msgstr ""
msgid "HAR file path or URL"
msgstr ""
+msgid "HTTP Archive (HAR)"
+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 ""
@@ -17973,6 +18278,9 @@ msgstr ""
msgid "INFO: Your SSH key is expiring soon. Please generate a new key."
msgstr ""
+msgid "IP"
+msgstr ""
+
msgid "IP Address"
msgstr "Adreça IP"
@@ -18009,6 +18317,9 @@ msgstr ""
msgid "IdentityVerification|Verify your identity"
msgstr ""
+msgid "IdentityVerification|You can always verify your account at a later time to create a group."
+msgstr ""
+
msgid "If any indexed field exceeds this limit, it is truncated to this number of characters. The rest of the content is neither indexed nor searchable. This does not apply to repository and wiki indexing. For unlimited characters, set this to 0."
msgstr ""
@@ -18066,6 +18377,9 @@ msgstr ""
msgid "If you add %{codeStart}needs%{codeEnd} to jobs in your pipeline you'll be able to view the %{codeStart}needs%{codeEnd} relationships between jobs in this tab as a %{linkStart}Directed Acyclic Graph (DAG)%{linkEnd}."
msgstr ""
+msgid "If you are added to a project, it will be displayed here."
+msgstr ""
+
msgid "If you did not initiate these sign-in attempts, please reach out to your administrator or enable two-factor authentication (2FA) on your account."
msgstr ""
@@ -18372,12 +18686,24 @@ msgstr ""
msgid "InProductMarketing|3 ways to dive into GitLab CI/CD"
msgstr ""
+msgid "InProductMarketing|A single application eliminates complex integrations, data chokepoints, and toolchain maintenance, resulting in greater productivity and lower cost."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features, build more efficiently, strengthen security and compliance."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features."
+msgstr ""
+
msgid "InProductMarketing|Actually, GitLab makes the team work (better)"
msgstr ""
msgid "InProductMarketing|And finally %{deploy_link} a Python application."
msgstr ""
+msgid "InProductMarketing|And many more..."
+msgstr ""
+
msgid "InProductMarketing|Are your runners ready?"
msgstr ""
@@ -18396,15 +18722,33 @@ msgstr ""
msgid "InProductMarketing|Blog"
msgstr ""
+msgid "InProductMarketing|Break down silos to coordinate seamlessly across development, operations, and security with a consistent experience across the development lifecycle."
+msgstr ""
+
+msgid "InProductMarketing|Burn up/down charts"
+msgstr ""
+
msgid "InProductMarketing|By enabling code owners and required merge approvals the right person will review the right MR. This is a win-win: cleaner code and a more efficient review process."
msgstr ""
msgid "InProductMarketing|Click on the number below that corresponds with your answer — 1 being very difficult, 5 being very easy."
msgstr ""
+msgid "InProductMarketing|Code owners"
+msgstr ""
+
msgid "InProductMarketing|Code owners and required merge approvals are part of the paid tiers of GitLab. You can start a free 30-day trial of GitLab Ultimate and enable these features in less than 5 minutes with no credit card required."
msgstr ""
+msgid "InProductMarketing|Code review analytics"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration across stages in GitLab"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration made easy"
+msgstr ""
+
msgid "InProductMarketing|Create a custom CI runner with just a few clicks"
msgstr ""
@@ -18414,12 +18758,21 @@ msgstr ""
msgid "InProductMarketing|Create a project in GitLab in 5 minutes"
msgstr ""
+msgid "InProductMarketing|Create well-defined workflows by using scoped labels on issues, merge requests, and epics. Labels with the same scope cannot be used together, which prevents conflicts."
+msgstr ""
+
msgid "InProductMarketing|Create your first project!"
msgstr ""
+msgid "InProductMarketing|Define who owns specific files or directories, so the right reviewers are suggested when a merge request introduces changes to those files."
+msgstr ""
+
msgid "InProductMarketing|Deliver Better Products Faster"
msgstr ""
+msgid "InProductMarketing|Dependency scanning"
+msgstr ""
+
msgid "InProductMarketing|Did you know teams that use GitLab are far more efficient?"
msgstr ""
@@ -18429,15 +18782,27 @@ msgstr ""
msgid "InProductMarketing|Dig in and create a project and a repo"
msgstr ""
+msgid "InProductMarketing|Discover Premium & Ultimate"
+msgstr ""
+
+msgid "InProductMarketing|Discover Premium & Ultimate."
+msgstr ""
+
msgid "InProductMarketing|Do you have a minute?"
msgstr ""
msgid "InProductMarketing|Do you have a teammate who would be perfect for this task?"
msgstr ""
+msgid "InProductMarketing|Dynamic application security testing"
+msgstr ""
+
msgid "InProductMarketing|Easy"
msgstr ""
+msgid "InProductMarketing|Epics"
+msgstr ""
+
msgid "InProductMarketing|Expand your DevOps journey with a free GitLab trial"
msgstr ""
@@ -18459,9 +18824,15 @@ msgstr ""
msgid "InProductMarketing|Feel the need for speed?"
msgstr ""
+msgid "InProductMarketing|Find and fix bottlenecks in your code review process by understanding how long open merge requests have been in review."
+msgstr ""
+
msgid "InProductMarketing|Find out how your teams are really doing"
msgstr ""
+msgid "InProductMarketing|Find out if your external libraries are safe. Run dependency scanning jobs that check for known vulnerabilities in your external libraries."
+msgstr ""
+
msgid "InProductMarketing|Follow our steps"
msgstr ""
@@ -18498,6 +18869,9 @@ msgstr ""
msgid "InProductMarketing|GitLab is better with teammates to help out!"
msgstr ""
+msgid "InProductMarketing|GitLab is infrastructure agnostic (supporting GCP, AWS, Azure, OpenShift, VMWare, On Prem, Bare Metal, and more), offering a consistent workflow experience – irrespective of the environment."
+msgstr ""
+
msgid "InProductMarketing|GitLab provides static application security testing (SAST), dynamic application security testing (DAST), container scanning, and dependency scanning to help you deliver secure applications along with license compliance."
msgstr ""
@@ -18588,21 +18962,36 @@ msgstr ""
msgid "InProductMarketing|It's also possible to simply %{external_repo_link} in order to take advantage of GitLab's CI/CD."
msgstr ""
+msgid "InProductMarketing|Keep your code quality high by defining who should approve merge requests and how many approvals are required."
+msgstr ""
+
msgid "InProductMarketing|Launch GitLab CI/CD in 20 minutes or less"
msgstr ""
+msgid "InProductMarketing|Lower cost of development"
+msgstr ""
+
+msgid "InProductMarketing|Make it easier to collaborate on high-level ideas by grouping related issues in an epic."
+msgstr ""
+
msgid "InProductMarketing|Making the switch? It's easier than you think to import your projects into GitLab. Move %{github_link}, or import something %{bitbucket_link}."
msgstr ""
msgid "InProductMarketing|Master the art of importing!"
msgstr ""
+msgid "InProductMarketing|Merge request approval rule"
+msgstr ""
+
msgid "InProductMarketing|Move on to easily creating a Pages website %{ci_template_link}"
msgstr ""
msgid "InProductMarketing|Multiple owners, confusing workstreams? We've got you covered"
msgstr ""
+msgid "InProductMarketing|Multiple required approvers"
+msgstr ""
+
msgid "InProductMarketing|Need an alternative to importing?"
msgstr ""
@@ -18615,18 +19004,33 @@ msgstr ""
msgid "InProductMarketing|Our tool brings all the things together"
msgstr ""
+msgid "InProductMarketing|Protect your web application by using DAST to examine for vulnerabilities in deployed environments."
+msgstr ""
+
msgid "InProductMarketing|Rapid development, simplified"
msgstr ""
msgid "InProductMarketing|Reduce Security & Compliance Risk"
msgstr ""
+msgid "InProductMarketing|Require multiple approvers on a merge request, so you know it's in good shape before it's merged."
+msgstr ""
+
+msgid "InProductMarketing|Roadmaps"
+msgstr ""
+
+msgid "InProductMarketing|Scoped labels"
+msgstr ""
+
msgid "InProductMarketing|Security that's integrated into your development lifecycle"
msgstr ""
msgid "InProductMarketing|Sometimes you're not ready to make a full transition to a new tool. If you're not ready to fully commit, %{mirroring_link} gives you a safe way to try out GitLab in parallel with your current tool."
msgstr ""
+msgid "InProductMarketing|Speed. Efficiency. Trust."
+msgstr ""
+
msgid "InProductMarketing|Spin up an autoscaling runner in GitLab"
msgstr ""
@@ -18636,6 +19040,9 @@ msgstr ""
msgid "InProductMarketing|Start a Self-Managed trial"
msgstr ""
+msgid "InProductMarketing|Start a free trial"
+msgstr ""
+
msgid "InProductMarketing|Start a free trial of GitLab Ultimate – no credit card required"
msgstr ""
@@ -18702,6 +19109,9 @@ msgstr ""
msgid "InProductMarketing|To understand and get the most out of GitLab, start at the beginning and %{project_link}. In GitLab, repositories are part of a project, so after you've created your project you can go ahead and %{repo_link}."
msgstr ""
+msgid "InProductMarketing|Track completed issues in a chart, so you can see how a milestone is progressing at a glance."
+msgstr ""
+
msgid "InProductMarketing|Try GitLab Ultimate for free"
msgstr ""
@@ -18738,6 +19148,9 @@ msgstr ""
msgid "InProductMarketing|Very easy"
msgstr ""
+msgid "InProductMarketing|Visualize your epics and milestones in a timeline."
+msgstr ""
+
msgid "InProductMarketing|Want to host GitLab on your servers?"
msgstr ""
@@ -18759,6 +19172,9 @@ msgstr ""
msgid "InProductMarketing|YouTube"
msgstr ""
+msgid "InProductMarketing|Your software, deployed your way"
+msgstr ""
+
msgid "InProductMarketing|Your teams can be more efficient"
msgstr ""
@@ -18879,9 +19295,18 @@ msgstr ""
msgid "IncidentManagement|No incidents to display."
msgstr ""
+msgid "IncidentManagement|None"
+msgstr ""
+
msgid "IncidentManagement|Open"
msgstr ""
+msgid "IncidentManagement|Page your team with escalation policies"
+msgstr ""
+
+msgid "IncidentManagement|Paged"
+msgstr ""
+
msgid "IncidentManagement|Published"
msgstr ""
@@ -18891,6 +19316,9 @@ msgstr ""
msgid "IncidentManagement|Severity"
msgstr ""
+msgid "IncidentManagement|Status"
+msgstr ""
+
msgid "IncidentManagement|There are no closed incidents"
msgstr ""
@@ -18909,6 +19337,9 @@ msgstr ""
msgid "IncidentManagement|Unpublished"
msgstr ""
+msgid "IncidentManagement|Use escalation policies to automatically page your team when incidents are created."
+msgstr ""
+
msgid "IncidentSettings|Activate \"time to SLA\" countdown timer"
msgstr ""
@@ -18954,7 +19385,10 @@ msgstr ""
msgid "Incidents"
msgstr ""
-msgid "Incidents|Add a URL"
+msgid "Incidents|Add image details"
+msgstr ""
+
+msgid "Incidents|Add text or a link to display with your image. If you don't add either, the file name displays instead."
msgstr ""
msgid "Incidents|Drop or %{linkStart}upload%{linkEnd} a metric screenshot to attach it to the incident"
@@ -18969,10 +19403,10 @@ msgstr ""
msgid "Incidents|There was an issue loading metric images."
msgstr ""
-msgid "Incidents|There was an issue uploading your image."
+msgid "Incidents|There was an issue updating your image."
msgstr ""
-msgid "Incidents|You can optionally add a URL to link users to the original graph."
+msgid "Incidents|There was an issue uploading your image."
msgstr ""
msgid "Incident|Alert details"
@@ -18981,9 +19415,18 @@ msgstr ""
msgid "Incident|Are you sure you wish to delete this image?"
msgstr ""
+msgid "Incident|Delete image"
+msgstr ""
+
msgid "Incident|Deleting %{filename}"
msgstr ""
+msgid "Incident|Edit image text or link"
+msgstr ""
+
+msgid "Incident|Editing %{filename}"
+msgstr ""
+
msgid "Incident|Metrics"
msgstr ""
@@ -19253,12 +19696,18 @@ msgstr ""
msgid "Integrations|Branches for which notifications are to be sent"
msgstr ""
+msgid "Integrations|Clear if using a self-signed certificate."
+msgstr ""
+
msgid "Integrations|Comment detail:"
msgstr ""
msgid "Integrations|Comment settings:"
msgstr ""
+msgid "Integrations|Connection details"
+msgstr ""
+
msgid "Integrations|Connection failed. Please check your settings."
msgstr ""
@@ -19283,6 +19732,9 @@ msgstr ""
msgid "Integrations|Enable GitLab.com slash commands in a Slack workspace."
msgstr ""
+msgid "Integrations|Enable SSL verification"
+msgstr ""
+
msgid "Integrations|Enable comments"
msgstr ""
@@ -19361,6 +19813,9 @@ msgstr ""
msgid "Integrations|Return to GitLab for Jira"
msgstr ""
+msgid "Integrations|SSL verification"
+msgstr ""
+
msgid "Integrations|Save settings?"
msgstr ""
@@ -19406,9 +19861,6 @@ msgstr ""
msgid "Integrations|Use default settings"
msgstr ""
-msgid "Integrations|When you mention a Jira issue in a commit or merge request, GitLab creates a remote link and comment (if enabled)."
-msgstr ""
-
msgid "Integrations|You can now close this window and return to the GitLab for Jira application."
msgstr ""
@@ -19433,9 +19885,6 @@ msgstr ""
msgid "Integrations|can't exceed %{recipients_limit}"
msgstr ""
-msgid "Interactive developer security education."
-msgstr ""
-
msgid "Interactive mode"
msgstr ""
@@ -19925,6 +20374,9 @@ msgstr ""
msgid "IssueAnalytics|Assignees"
msgstr ""
+msgid "IssueAnalytics|Created by"
+msgstr ""
+
msgid "IssueAnalytics|Due date"
msgstr ""
@@ -19937,9 +20389,6 @@ msgstr ""
msgid "IssueAnalytics|Milestone"
msgstr ""
-msgid "IssueAnalytics|Opened by"
-msgstr ""
-
msgid "IssueAnalytics|Status"
msgstr ""
@@ -20063,10 +20512,10 @@ msgstr ""
msgid "IssuesAnalytics|Avg/Month:"
msgstr ""
-msgid "IssuesAnalytics|Issues opened"
+msgid "IssuesAnalytics|Issues created"
msgstr ""
-msgid "IssuesAnalytics|Issues opened per month"
+msgid "IssuesAnalytics|Issues created per month"
msgstr ""
msgid "IssuesAnalytics|Last 12 months"
@@ -20093,6 +20542,9 @@ msgstr ""
msgid "It looks like you have some draft commits in this branch."
msgstr ""
+msgid "It looks like you're attempting to activate your subscription. Use %{a_start}the Subscription page%{a_end} instead."
+msgstr ""
+
msgid "It may be several days before you see feature usage data."
msgstr ""
@@ -20321,6 +20773,9 @@ msgstr ""
msgid "JiraConnect|You can now close this window and return to Jira."
msgstr ""
+msgid "JiraConnect|You don't have permission to create branches for this project. Select a different project or contact the project owner for access. %{linkStart}Learn more.%{linkEnd}"
+msgstr ""
+
msgid "JiraRequest|A connection error occurred while connecting to Jira. Try your request again."
msgstr ""
@@ -20369,13 +20824,13 @@ msgstr ""
msgid "JiraService|Define the type of Jira issue to create from a vulnerability."
msgstr ""
-msgid "JiraService|Displaying Jira issues while leaving the GitLab issue functionality enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
+msgid "JiraService|Displaying Jira issues while leaving GitLab issues also enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
msgstr ""
-msgid "JiraService|Enable Jira issues"
+msgid "JiraService|Enable Jira issue creation from vulnerabilities"
msgstr ""
-msgid "JiraService|Enable Jira issues creation from vulnerabilities"
+msgid "JiraService|Enable Jira issues"
msgstr ""
msgid "JiraService|Enable Jira transitions"
@@ -20492,16 +20947,19 @@ msgstr ""
msgid "JiraService|View Jira issues in GitLab"
msgstr ""
-msgid "JiraService|Warning: All GitLab users that have access to this GitLab project are able to view all issues from the Jira project specified below."
+msgid "JiraService|Warning: All GitLab users with access to this GitLab project can view all issues from the Jira project you select."
msgstr ""
msgid "JiraService|Web URL"
msgstr ""
-msgid "JiraService|Work on Jira issues without leaving GitLab. Adds a Jira menu to access your list of Jira issues and view any issue as read-only."
+msgid "JiraService|When a Jira issue is mentioned in a commit or merge request, a remote link and comment (if enabled) will be created."
+msgstr ""
+
+msgid "JiraService|Work on Jira issues without leaving GitLab. Add a Jira menu to access a read-only list of your Jira issues."
msgstr ""
-msgid "JiraService|You need to configure Jira before enabling this integration. For more details, read the %{jira_doc_link_start}Jira integration documentation%{link_end}."
+msgid "JiraService|You must configure Jira before enabling this integration. %{jira_doc_link_start}Learn more.%{link_end}"
msgstr ""
msgid "Job"
@@ -20513,9 +20971,6 @@ msgstr ""
msgid "Job Failed #%{build_id}"
msgstr ""
-msgid "Job ID"
-msgstr ""
-
msgid "Job artifact"
msgstr ""
@@ -20582,9 +21037,27 @@ msgstr ""
msgid "Jobs|You're about to retry a job that failed because it attempted to deploy code that is older than the latest deployment. Retrying this job could result in overwriting the environment with the older source code."
msgstr ""
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source} into %{target}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{ref}"
+msgstr ""
+
+msgid "Job|Are you sure you want to erase this job log and artifacts?"
+msgstr ""
+
msgid "Job|Browse"
msgstr ""
+msgid "Job|Cancel"
+msgstr ""
+
msgid "Job|Complete Raw"
msgstr ""
@@ -20594,6 +21067,9 @@ msgstr ""
msgid "Job|Erase job log and artifacts"
msgstr ""
+msgid "Job|Finished at"
+msgstr ""
+
msgid "Job|Job artifacts"
msgstr ""
@@ -20606,7 +21082,7 @@ msgstr ""
msgid "Job|Keep"
msgstr ""
-msgid "Job|Pipeline"
+msgid "Job|Retry"
msgstr ""
msgid "Job|Scroll to bottom"
@@ -20618,6 +21094,9 @@ msgstr ""
msgid "Job|Show complete raw"
msgstr ""
+msgid "Job|Status"
+msgstr ""
+
msgid "Job|The artifacts were removed"
msgstr ""
@@ -20645,21 +21124,12 @@ msgstr ""
msgid "Job|delayed"
msgstr ""
-msgid "Job|for"
-msgstr ""
-
-msgid "Job|into"
-msgstr ""
-
msgid "Job|manual"
msgstr ""
msgid "Job|triggered"
msgstr ""
-msgid "Job|with"
-msgstr ""
-
msgid "Join Zoom meeting"
msgstr ""
@@ -20762,9 +21232,6 @@ msgstr ""
msgid "Ki"
msgstr ""
-msgid "Kontra"
-msgstr ""
-
msgid "Kroki"
msgstr ""
@@ -21088,6 +21555,9 @@ msgstr ""
msgid "Learn more about Auto DevOps"
msgstr ""
+msgid "Learn more about GitLab"
+msgstr ""
+
msgid "Learn more about Needs relationships"
msgstr ""
@@ -21415,9 +21885,18 @@ msgstr ""
msgid "Licenses|Displays licenses detected in the project, based on the %{linkStart}latest successful%{linkEnd} scan"
msgstr ""
+msgid "Licenses|Drag your license file here or %{linkStart}click to upload%{linkEnd}."
+msgstr ""
+
+msgid "Licenses|Drop your license file to start the upload."
+msgstr ""
+
msgid "Licenses|Error fetching the license list. Please check your network connection and try again."
msgstr ""
+msgid "Licenses|Error: You are trying to upload something other than a file"
+msgstr ""
+
msgid "Licenses|License Compliance"
msgstr ""
@@ -21436,6 +21915,9 @@ msgstr ""
msgid "Licenses|Specified policies in this project"
msgstr ""
+msgid "Licenses|The file could not be uploaded."
+msgstr ""
+
msgid "Licenses|The license list details information about the licenses used within your project."
msgstr ""
@@ -21469,11 +21951,6 @@ msgstr ""
msgid "Limit the size of Sidekiq jobs stored in Redis."
msgstr ""
-msgid "Limited to showing %d event at most"
-msgid_plural "Limited to showing %d events at most"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Limiting mode"
msgstr ""
@@ -21483,6 +21960,9 @@ msgstr ""
msgid "Link"
msgstr ""
+msgid "Link (optional)"
+msgstr ""
+
msgid "Link Prometheus monitoring to GitLab."
msgstr ""
@@ -21519,6 +21999,9 @@ msgstr ""
msgid "Linked emails (%{email_count})"
msgstr ""
+msgid "Linked epics"
+msgstr ""
+
msgid "Linked issues"
msgstr ""
@@ -21546,6 +22029,15 @@ msgstr ""
msgid "List of all merge commits"
msgstr ""
+msgid "List of environments for this project"
+msgstr ""
+
+msgid "List of suitable GCP locations"
+msgstr ""
+
+msgid "List of users allowed to exceed the rate limit."
+msgstr ""
+
msgid "List options"
msgstr ""
@@ -21765,6 +22257,9 @@ msgstr ""
msgid "Maintenance mode"
msgstr ""
+msgid "Make adjustments to how your GitLab instance is set up."
+msgstr ""
+
msgid "Make and review changes in the browser with the Web IDE"
msgstr ""
@@ -21909,6 +22404,12 @@ msgstr ""
msgid "MarkdownEditor|Add italic text (%{modifier_key}I)"
msgstr ""
+msgid "MarkdownEditor|Add strikethrough text (%{modifierKey}⇧X)"
+msgstr ""
+
+msgid "MarkdownEditor|Add strikethrough text (%{modifier_key}⇧X)"
+msgstr ""
+
msgid "Marked For Deletion At - %{deletion_time}"
msgstr ""
@@ -22170,6 +22671,9 @@ msgstr ""
msgid "Maximum push size (MB)"
msgstr ""
+msgid "Maximum requests per 10 minutes per user"
+msgstr ""
+
msgid "Maximum requests per minute"
msgstr ""
@@ -22260,6 +22764,19 @@ msgstr ""
msgid "Members of a group may only view projects they have permission to access"
msgstr ""
+msgid "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seat in use and will be billed for the overage."
+msgid_plural "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seats in use and will be billed for the overage."
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "MembersOverage|You are about to incur additional charges"
+msgstr ""
+
+msgid "MembersOverage|Your subscription includes %d seat."
+msgid_plural "MembersOverage|Your subscription includes %d seats."
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Membership"
msgstr ""
@@ -22464,9 +22981,6 @@ msgstr ""
msgid "Merge request not merged"
msgstr ""
-msgid "Merge request pipelines 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 merge request pipelines."
-msgstr ""
-
msgid "Merge request reports"
msgstr ""
@@ -22563,13 +23077,13 @@ msgstr ""
msgid "MergeRequests|Create issue to resolve thread"
msgstr ""
-msgid "MergeRequests|Failed to squash. Should be done manually."
+msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Saving the comment failed"
+msgid "MergeRequests|Squashing failed: Squash the commits locally, resolve any conflicts, then push the branch."
msgstr ""
-msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
+msgid "MergeRequests|Squashing not allowed: This project doesn't allow you to squash commits when merging."
msgstr ""
msgid "MergeRequests|Thread stays resolved"
@@ -23410,6 +23924,18 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "MrList|Assigned to %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from assignee %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from reviewer %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Review requested from %{name}, go to their profile."
+msgstr ""
+
msgid "Multi-project"
msgstr ""
@@ -23443,7 +23969,7 @@ msgstr ""
msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "My Awesome Group"
+msgid "My awesome group"
msgstr ""
msgid "My company or team"
@@ -24065,9 +24591,6 @@ msgstr ""
msgid "No available branches"
msgstr ""
-msgid "No available groups to fork the project."
-msgstr ""
-
msgid "No branches found"
msgstr ""
@@ -24278,6 +24801,9 @@ msgstr ""
msgid "No ref selected"
msgstr ""
+msgid "No regions configured"
+msgstr ""
+
msgid "No related merge requests found."
msgstr ""
@@ -25082,6 +25608,9 @@ msgstr ""
msgid "Only reCAPTCHA v2 is supported:"
msgstr ""
+msgid "Only required if not using role instance credentials."
+msgstr ""
+
msgid "Only use lowercase letters, numbers, and underscores."
msgstr ""
@@ -25106,9 +25635,6 @@ msgstr ""
msgid "Open a CLI and connect to the cluster you want to install the agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
-msgid "Open epics"
-msgstr ""
-
msgid "Open errors"
msgstr ""
@@ -25148,7 +25674,7 @@ msgstr ""
msgid "Opened issues"
msgstr ""
-msgid "OpenedNDaysAgo|Opened"
+msgid "OpenedNDaysAgo|Created"
msgstr ""
msgid "Opens in a new window"
@@ -25193,9 +25719,6 @@ msgstr ""
msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
-msgid "Optional."
-msgstr ""
-
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
msgstr ""
@@ -25984,6 +26507,9 @@ msgstr ""
msgid "PerformanceBar|Memory"
msgstr ""
+msgid "PerformanceBar|Memory report"
+msgstr ""
+
msgid "PerformanceBar|Redis calls"
msgstr ""
@@ -26017,18 +26543,12 @@ msgstr ""
msgid "PerformanceBar|wall"
msgstr ""
-msgid "Performs a rebase but skips triggering a new pipeline"
-msgstr ""
-
msgid "Period in seconds"
msgstr ""
msgid "Permalink"
msgstr ""
-msgid "Permanently delete project"
-msgstr ""
-
msgid "Permanently remove group"
msgstr ""
@@ -26299,6 +26819,51 @@ msgstr ""
msgid "PipelineStatusTooltip|Pipeline: %{ci_status}"
msgstr ""
+msgid "PipelineWizardDefaultCommitMessage|Add %{filename}"
+msgstr ""
+
+msgid "PipelineWizardDefaultCommitMessage|Update %{filename}"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|At least one entry is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This field is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This value is not valid"
+msgstr ""
+
+msgid "PipelineWizardListWidget|add another step"
+msgstr ""
+
+msgid "PipelineWizardListWidget|remove step"
+msgstr ""
+
+msgid "PipelineWizard|Commit"
+msgstr ""
+
+msgid "PipelineWizard|Commit Message"
+msgstr ""
+
+msgid "PipelineWizard|Commit changes to your file"
+msgstr ""
+
+msgid "PipelineWizard|Commit file to Branch"
+msgstr ""
+
+msgid "PipelineWizard|Commit your new file"
+msgstr ""
+
+msgid "PipelineWizard|The file has been committed."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem committing the changes."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem while checking whether your file already exists in the specified branch."
+msgstr ""
+
msgid "Pipelines"
msgstr ""
@@ -26413,7 +26978,7 @@ msgstr ""
msgid "Pipelines|Project cache successfully reset."
msgstr ""
-msgid "Pipelines|Revoke"
+msgid "Pipelines|Revoke trigger"
msgstr ""
msgid "Pipelines|Something went wrong while cleaning runners cache."
@@ -26458,6 +27023,12 @@ msgstr ""
msgid "Pipelines|This is a child pipeline within the parent pipeline"
msgstr ""
+msgid "Pipelines|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipelines|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipelines|This pipeline will run code originating from a forked project merge request. This means that the code can potentially have security considerations like exposing CI variables."
msgstr ""
@@ -26500,9 +27071,6 @@ msgstr ""
msgid "Pipelines|Your changes have been successfully committed. Now redirecting to the new merge request page."
msgstr ""
-msgid "Pipelines|detached"
-msgstr ""
-
msgid "Pipelines|error"
msgstr ""
@@ -26512,10 +27080,13 @@ msgstr ""
msgid "Pipelines|latest"
msgstr ""
-msgid "Pipelines|stuck"
+msgid "Pipelines|merge request"
msgstr ""
-msgid "Pipelines|train"
+msgid "Pipelines|merge train"
+msgstr ""
+
+msgid "Pipelines|stuck"
msgstr ""
msgid "Pipelines|yaml invalid"
@@ -26647,6 +27218,12 @@ msgstr ""
msgid "Pipeline|This change will not change the overall test coverage if merged."
msgstr ""
+msgid "Pipeline|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipeline|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipeline|Trigger author"
msgstr ""
@@ -26671,6 +27248,12 @@ msgstr ""
msgid "Pipeline|for"
msgstr ""
+msgid "Pipeline|merge request"
+msgstr ""
+
+msgid "Pipeline|merge train"
+msgstr ""
+
msgid "Pipeline|on"
msgstr ""
@@ -26809,9 +27392,6 @@ msgstr ""
msgid "Please enter a valid time interval"
msgstr ""
-msgid "Please enter or upload a valid license."
-msgstr ""
-
msgid "Please enter your current password."
msgstr ""
@@ -26920,9 +27500,6 @@ msgstr ""
msgid "Please type %{phrase_code} to proceed or close this modal to cancel."
msgstr ""
-msgid "Please type the following to confirm:"
-msgstr ""
-
msgid "Please use this form to report to the admin users who create spam issues, comments or behave inappropriately."
msgstr ""
@@ -26950,12 +27527,27 @@ msgstr ""
msgid "Policies"
msgstr ""
+msgid "Policy '%{escalation_policy_name}' does not exist."
+msgstr ""
+
msgid "Policy management project does have any policies in %{policy_path}"
msgstr ""
msgid "Policy project doesn't exist"
msgstr ""
+msgid "PolicyRuleMultiSelect|%{firstLabel} +%{numberOfAdditionalLabels} more"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|All %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select all"
+msgstr ""
+
msgid "Polling interval multiplier"
msgstr ""
@@ -27184,6 +27776,9 @@ msgstr ""
msgid "Private projects can be created in your personal namespace with:"
msgstr ""
+msgid "Problem with %{name} command: %{message}."
+msgstr ""
+
msgid "Proceed"
msgstr ""
@@ -27658,6 +28253,9 @@ msgstr ""
msgid "Progress"
msgstr ""
+msgid "Progress tracking"
+msgstr ""
+
msgid "Project"
msgstr ""
@@ -27889,6 +28487,9 @@ msgstr ""
msgid "ProjectQualitySummary|Failure"
msgstr ""
+msgid "ProjectQualitySummary|Get insight into the overall percentage of tests in your project that succeed, fail and are skipped."
+msgstr ""
+
msgid "ProjectQualitySummary|Latest pipeline results"
msgstr ""
@@ -27907,6 +28508,12 @@ msgstr ""
msgid "ProjectQualitySummary|See project Code Coverage Statistics"
msgstr ""
+msgid "ProjectQualitySummary|Set up test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|Set up test runs (opens in a new tab)"
+msgstr ""
+
msgid "ProjectQualitySummary|Skipped"
msgstr ""
@@ -28183,13 +28790,19 @@ msgstr ""
msgid "ProjectSettings|LFS objects from this repository are available to forks. %{linkStart}How do I remove them?%{linkEnd}"
msgstr ""
+msgid "ProjectSettings|Learn about commit history."
+msgstr ""
+
+msgid "ProjectSettings|Leave empty to use default template."
+msgstr ""
+
msgid "ProjectSettings|Manage who can see the project in the public access directory."
msgstr ""
msgid "ProjectSettings|Manages large files such as audio, video, and graphics files."
msgstr ""
-msgid "ProjectSettings|Maximum 500 characters."
+msgid "ProjectSettings|Maximum %{maxLength} characters."
msgstr ""
msgid "ProjectSettings|Merge checks"
@@ -28330,6 +28943,9 @@ msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
msgstr ""
+msgid "ProjectSettings|The default template will be applied on save."
+msgstr ""
+
msgid "ProjectSettings|These checks must pass before merge requests can be merged."
msgstr ""
@@ -28384,6 +29000,9 @@ msgstr ""
msgid "ProjectSettings|What are badges?"
msgstr ""
+msgid "ProjectSettings|What are merge trains?"
+msgstr ""
+
msgid "ProjectSettings|When merge request pipelines are enabled in the CI/CD configuration file, pipelines validate the combined results of the source and target branches. %{link_start}How to configure merge request pipelines?%{link_end}"
msgstr ""
@@ -28501,6 +29120,9 @@ msgstr ""
msgid "Projects are organized into groups"
msgstr ""
+msgid "Projects are where you store your code, access issues, wiki and other features of GitLab."
+msgstr ""
+
msgid "Projects contributed to"
msgstr ""
@@ -28516,12 +29138,6 @@ msgstr ""
msgid "Projects to index"
msgstr ""
-msgid "Projects will be permanently deleted after a %{waiting_period}-day waiting period."
-msgstr ""
-
-msgid "Projects will be permanently deleted immediately."
-msgstr ""
-
msgid "Projects with critical vulnerabilities"
msgstr ""
@@ -28606,6 +29222,9 @@ msgstr ""
msgid "ProjectsNew|Import project"
msgstr ""
+msgid "ProjectsNew|Include a Getting Started README"
+msgstr ""
+
msgid "ProjectsNew|Initialize repository with a README"
msgstr ""
@@ -28621,6 +29240,9 @@ msgstr ""
msgid "ProjectsNew|Project description %{tag_start}(optional)%{tag_end}"
msgstr ""
+msgid "ProjectsNew|Recommended if you're new to GitLab"
+msgstr ""
+
msgid "ProjectsNew|Run CI/CD for external repository"
msgstr ""
@@ -29038,6 +29660,9 @@ msgstr ""
msgid "ProtectedBranch|Unprotect"
msgstr ""
+msgid "ProtectedBranch|Unprotect branch"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
@@ -29065,6 +29690,9 @@ msgstr ""
msgid "ProtectedEnvironment|Protected Environment (%{protected_environments_count})"
msgstr ""
+msgid "ProtectedEnvironment|Required approvals"
+msgstr ""
+
msgid "ProtectedEnvironment|Select an environment"
msgstr ""
@@ -29086,10 +29714,13 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|Unprotect tag"
+msgstr ""
+
msgid "ProtectedTags|default"
msgstr ""
-msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
+msgid "ProtectedTag|By default, protected tags restrict who can modify the tag."
msgstr ""
msgid "ProtectedTag|Learn more."
@@ -29152,6 +29783,9 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Public projects are an easy way to allow everyone to have read-only access."
+msgstr ""
+
msgid "Publish to status page"
msgstr ""
@@ -29308,9 +29942,6 @@ msgstr ""
msgid "QualitySummary|Project quality"
msgstr ""
-msgid "Quarters"
-msgstr ""
-
msgid "Query"
msgstr ""
@@ -29395,6 +30026,9 @@ msgstr ""
msgid "Read more about project permissions %{help_link_open}here%{help_link_close}"
msgstr ""
+msgid "Read more about related epics"
+msgstr ""
+
msgid "Read more about related issues"
msgstr ""
@@ -29425,10 +30059,7 @@ msgstr ""
msgid "Rebase source branch on the target branch."
msgstr ""
-msgid "Rebase without CI"
-msgstr ""
-
-msgid "Rebases and triggers a pipeline"
+msgid "Rebase without pipeline"
msgstr ""
msgid "Recaptcha verified?"
@@ -29479,9 +30110,6 @@ msgstr ""
msgid "Reconfigure"
msgstr ""
-msgid "Recovering projects"
-msgstr ""
-
msgid "Recovery Codes"
msgstr ""
@@ -29541,6 +30169,12 @@ msgstr ""
msgid "Regex pattern"
msgstr ""
+msgid "Region"
+msgstr ""
+
+msgid "Regions"
+msgstr ""
+
msgid "Register"
msgstr ""
@@ -29771,9 +30405,6 @@ msgstr ""
msgid "Remove all or specific reviewer(s)"
msgstr ""
-msgid "Remove approver"
-msgstr ""
-
msgid "Remove approvers"
msgstr ""
@@ -29789,6 +30420,9 @@ msgstr ""
msgid "Remove attention request"
msgstr ""
+msgid "Remove attention request(s)"
+msgstr ""
+
msgid "Remove avatar"
msgstr ""
@@ -29927,6 +30561,9 @@ msgstr ""
msgid "Removed an issue from an epic."
msgstr ""
+msgid "Removed attention from %{users_sentence}."
+msgstr ""
+
msgid "Removed attention request from @%{username}"
msgstr ""
@@ -29978,6 +30615,9 @@ msgstr ""
msgid "Removes an issue from an epic."
msgstr ""
+msgid "Removes attention from %{users_sentence}."
+msgstr ""
+
msgid "Removes parent epic %{epic_ref}."
msgstr ""
@@ -30089,6 +30729,9 @@ msgstr ""
msgid "Report abuse to admin"
msgstr ""
+msgid "Report is generating and will be sent to your email address."
+msgstr ""
+
msgid "Reported %{timeAgo} by %{reportedBy}"
msgstr ""
@@ -30378,6 +31021,15 @@ msgstr ""
msgid "Request attention"
msgstr ""
+msgid "Request attention from %{users_sentence}."
+msgstr ""
+
+msgid "Request attention from assignee or reviewer"
+msgstr ""
+
+msgid "Request attention from assignee(s) or reviewer(s)"
+msgstr ""
+
msgid "Request attention to review"
msgstr ""
@@ -30402,6 +31054,9 @@ msgstr ""
msgid "Requested %{time_ago}"
msgstr ""
+msgid "Requested attention from %{users_sentence}."
+msgstr ""
+
msgid "Requested attention from @%{username}"
msgstr ""
@@ -30616,6 +31271,9 @@ msgstr ""
msgid "Restore project"
msgstr ""
+msgid "Restoring projects"
+msgstr ""
+
msgid "Restoring the group will prevent the group, its subgroups and projects from being removed on this date."
msgstr ""
@@ -30646,6 +31304,9 @@ msgstr ""
msgid "Retry"
msgstr ""
+msgid "Retry failed jobs"
+msgstr ""
+
msgid "Retry job"
msgstr ""
@@ -30693,9 +31354,6 @@ msgstr ""
msgid "Review changes"
msgstr ""
-msgid "Review requested from %{name}"
-msgstr ""
-
msgid "Review requests for you"
msgstr ""
@@ -30860,6 +31518,9 @@ msgstr ""
msgid "Runners|Assigned Group"
msgstr ""
+msgid "Runners|Assigned Projects (%{projectCount})"
+msgstr ""
+
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30929,6 +31590,9 @@ msgstr ""
msgid "Runners|Instance"
msgstr ""
+msgid "Runners|Jobs"
+msgstr ""
+
msgid "Runners|Last contact"
msgstr ""
@@ -31022,9 +31686,6 @@ msgstr ""
msgid "Runners|Runner %{name} was deleted"
msgstr ""
-msgid "Runners|Runner ID"
-msgstr ""
-
msgid "Runners|Runner assigned to project."
msgstr ""
@@ -31172,6 +31833,9 @@ msgstr ""
msgid "Runners|stale"
msgstr ""
+msgid "Runner|This runner has not run any jobs."
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -31286,6 +31950,24 @@ msgstr ""
msgid "Saving project."
msgstr ""
+msgid "ScanResultPolicy|%{ifLabelStart}if%{ifLabelEnd} %{scanners} scan in an open merge request targeting the %{branches} branch(es) finds %{vulnerabilitiesAllowed} or more %{severities} vulnerabilities that are %{vulnerabilityStates}"
+msgstr ""
+
+msgid "ScanResultPolicy|%{thenLabelStart}Then%{thenLabelEnd} Require approval from %{approvalsRequired} of the following approvers: %{approvers}"
+msgstr ""
+
+msgid "ScanResultPolicy|add an approver"
+msgstr ""
+
+msgid "ScanResultPolicy|scanners"
+msgstr ""
+
+msgid "ScanResultPolicy|severity levels"
+msgstr ""
+
+msgid "ScanResultPolicy|vulnerability states"
+msgstr ""
+
msgid "Scanner"
msgstr ""
@@ -31418,6 +32100,9 @@ msgstr ""
msgid "Search for a user"
msgstr ""
+msgid "Search for an emoji"
+msgstr ""
+
msgid "Search for projects, issues, etc."
msgstr ""
@@ -31605,18 +32290,12 @@ msgstr ""
msgid "Secret Detection"
msgstr ""
-msgid "Secret access key"
-msgstr ""
-
msgid "Secret token"
msgstr ""
msgid "Secure token that identifies an external storage request."
msgstr ""
-msgid "SecureCodeWarrior"
-msgstr ""
-
msgid "Security"
msgstr ""
@@ -31641,9 +32320,6 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "Security training with guide and learning pathways."
-msgstr ""
-
msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
@@ -31746,7 +32422,7 @@ msgstr ""
msgid "SecurityConfiguration|Manage corpus"
msgstr ""
-msgid "SecurityConfiguration|Manage corpus files used as mutation sources in coverage fuzzing."
+msgid "SecurityConfiguration|Manage corpus files used as seed inputs with coverage-guided fuzzing."
msgstr ""
msgid "SecurityConfiguration|Manage profiles for use by DAST scans."
@@ -31812,15 +32488,15 @@ msgstr ""
msgid "SecurityOrchestration|.yaml preview"
msgstr ""
-msgid "SecurityOrchestration|Action"
-msgstr ""
-
msgid "SecurityOrchestration|Actions"
msgstr ""
msgid "SecurityOrchestration|Add rule"
msgstr ""
+msgid "SecurityOrchestration|After dismissing the alert, the information will never be shown again."
+msgstr ""
+
msgid "SecurityOrchestration|All policies"
msgstr ""
@@ -31836,7 +32512,7 @@ msgstr ""
msgid "SecurityOrchestration|Description"
msgstr ""
-msgid "SecurityOrchestration|Disabled"
+msgid "SecurityOrchestration|Don't show the alert anymore"
msgstr ""
msgid "SecurityOrchestration|Edit policy"
@@ -31845,13 +32521,13 @@ msgstr ""
msgid "SecurityOrchestration|Edit policy project"
msgstr ""
-msgid "SecurityOrchestration|Enabled"
+msgid "SecurityOrchestration|Empty policy name"
msgstr ""
-msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Enabled"
msgstr ""
-msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
msgstr ""
msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
@@ -31860,7 +32536,7 @@ msgstr ""
msgid "SecurityOrchestration|Invalid policy type"
msgstr ""
-msgid "SecurityOrchestration|Latest scan"
+msgid "SecurityOrchestration|Latest scan run against %{agent}"
msgstr ""
msgid "SecurityOrchestration|Network"
@@ -31869,15 +32545,27 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No actions defined - policy will not run."
+msgstr ""
+
+msgid "SecurityOrchestration|No description"
+msgstr ""
+
msgid "SecurityOrchestration|No rules defined - policy will not run."
msgstr ""
+msgid "SecurityOrchestration|Not enabled"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
msgid "SecurityOrchestration|Policies"
msgstr ""
+msgid "SecurityOrchestration|Policy Type"
+msgstr ""
+
msgid "SecurityOrchestration|Policy cannot be enabled for non-existing branches (%{branches})"
msgstr ""
@@ -31902,10 +32590,13 @@ msgstr ""
msgid "SecurityOrchestration|Require %{approvals} %{plural} from %{approvers} if any of the following occur:"
msgstr ""
-msgid "SecurityOrchestration|Rule"
+msgid "SecurityOrchestration|Rules"
msgstr ""
-msgid "SecurityOrchestration|Rules"
+msgid "SecurityOrchestration|Runs %{actions} and %{lastAction} scans"
+msgstr ""
+
+msgid "SecurityOrchestration|Runs a %{action} scan"
msgstr ""
msgid "SecurityOrchestration|Scan Execution"
@@ -31965,6 +32656,9 @@ msgstr ""
msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
+msgid "SecurityOrchestration|This view only shows scan results for the agent %{agent}. You can view scan results for all agents in the %{linkStart}Operational Vulnerabilities tab of the vulnerability report%{linkEnd}."
+msgstr ""
+
msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
@@ -32019,9 +32713,6 @@ msgstr ""
msgid "SecurityOrchestration|users with ids"
msgstr ""
-msgid "SecurityOrchestration|view results"
-msgstr ""
-
msgid "SecurityOrchestration|vulnerabilities"
msgstr ""
@@ -32691,22 +33382,19 @@ 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|In order to start using functions as a service, you must first install Knative on your Kubernetes cluster. %{linkStart}More information%{linkEnd}"
-msgstr ""
-
msgid "Serverless|Learn more about Serverless"
msgstr ""
msgid "Serverless|No functions available"
msgstr ""
-msgid "Serverless|Sign up for First Look"
+msgid "Serverless|Serverless was %{linkStart}deprecated%{linkEnd} in GitLab 14.3."
+msgstr ""
+
+msgid "Serverless|Serverless was %{postLinkStart}deprecated%{postLinkEnd}. But if you opt to use it, you must install Knative in your Kubernetes cluster first. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "Serverless|The deploy job has not finished."
@@ -32718,9 +33406,6 @@ 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 ""
@@ -32736,9 +33421,6 @@ msgstr ""
msgid "Service Account Key"
msgstr ""
-msgid "Service Accounts"
-msgstr ""
-
msgid "Service Accounts keys authorize GitLab to deploy your Google Cloud project"
msgstr ""
@@ -32748,10 +33430,10 @@ msgstr ""
msgid "Service Desk allows people to create issues in your GitLab instance without their own user account. It provides a unique email address for end users to create issues in a project. Replies can be sent either through the GitLab interface or by email. End users only see threads through email."
msgstr ""
-msgid "Service Usage Data"
+msgid "Service account generated successfully"
msgstr ""
-msgid "Service account generated successfully"
+msgid "Service accounts"
msgstr ""
msgid "Service ping is disabled in your configuration file, and cannot be enabled through this form."
@@ -32895,6 +33577,9 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
+msgid "Set the per-user rate limit for getting a user by ID via the API."
+msgstr ""
+
msgid "Set the per-user rate limit for notes created by web or API requests."
msgstr ""
@@ -33074,6 +33759,9 @@ msgstr ""
msgid "Shared runners details"
msgstr ""
+msgid "Shared runners enabled cannot be enabled until a valid credit card is on file"
+msgstr ""
+
msgid "Shared runners help link"
msgstr ""
@@ -33131,6 +33819,9 @@ msgstr ""
msgid "Show all issues."
msgstr ""
+msgid "Show all milestones"
+msgstr ""
+
msgid "Show all test cases."
msgstr ""
@@ -33167,6 +33858,9 @@ msgstr ""
msgid "Show file contents"
msgstr ""
+msgid "Show group milestones"
+msgstr ""
+
msgid "Show labels"
msgstr ""
@@ -33182,6 +33876,12 @@ msgstr ""
msgid "Show open epics"
msgstr ""
+msgid "Show project milestones"
+msgstr ""
+
+msgid "Show sub-group milestones"
+msgstr ""
+
msgid "Show the Closed list"
msgstr ""
@@ -33191,11 +33891,6 @@ msgstr ""
msgid "Show whitespace changes"
msgstr ""
-msgid "Showing %d event"
-msgid_plural "Showing %d events"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Showing %{conflict} between %{sourceBranch} and %{targetBranch}"
msgstr ""
@@ -33255,12 +33950,6 @@ msgstr ""
msgid "Sidebar|None"
msgstr ""
-msgid "Sidebar|Only numeral characters allowed"
-msgstr ""
-
-msgid "Sidebar|Weight"
-msgstr ""
-
msgid "Sidekiq job compression threshold (bytes)"
msgstr ""
@@ -33423,6 +34112,9 @@ msgstr ""
msgid "Slack logo"
msgstr ""
+msgid "SlackIntegration|Are you sure you want to remove this project from the Slack application?"
+msgstr ""
+
msgid "SlackIntegration|GitLab for Slack"
msgstr ""
@@ -33432,6 +34124,9 @@ msgstr ""
msgid "SlackIntegration|Project alias"
msgstr ""
+msgid "SlackIntegration|Remove project"
+msgstr ""
+
msgid "SlackIntegration|Select a GitLab project to link with your Slack workspace."
msgstr ""
@@ -33576,9 +34271,6 @@ msgstr ""
msgid "Something went wrong trying to load issue contacts."
msgstr ""
-msgid "Something went wrong when creating a work item. Please try again"
-msgstr ""
-
msgid "Something went wrong when reordering designs. Please try again"
msgstr ""
@@ -33672,9 +34364,6 @@ msgstr ""
msgid "Something went wrong while inserting your image. Please try again."
msgstr ""
-msgid "Something went wrong while merging this merge request. Please try again."
-msgstr ""
-
msgid "Something went wrong while obtaining the Let's Encrypt certificate."
msgstr ""
@@ -33996,10 +34685,10 @@ 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."
+msgid "SourcegraphAdmin|Learn more."
msgstr ""
-msgid "SourcegraphAdmin|More information"
+msgid "SourcegraphAdmin|Only public projects have code intelligence enabled and communicate with Sourcegraph."
msgstr ""
msgid "SourcegraphAdmin|Save changes"
@@ -34008,7 +34697,7 @@ msgstr ""
msgid "SourcegraphAdmin|Sourcegraph URL"
msgstr ""
-msgid "SourcegraphAdmin|e.g. https://sourcegraph.example.com"
+msgid "SourcegraphAdmin|https://sourcegraph.example.com"
msgstr ""
msgid "SourcegraphPreferences|This feature is experimental and currently limited to certain projects."
@@ -34143,6 +34832,9 @@ msgstr ""
msgid "Start date"
msgstr ""
+msgid "Start free trial"
+msgstr ""
+
msgid "Start merge train"
msgstr ""
@@ -34173,6 +34865,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started escalation for this incident."
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -34185,6 +34880,9 @@ msgstr ""
msgid "Starts at (UTC)"
msgstr ""
+msgid "Starts escalations for this incident"
+msgstr ""
+
msgid "Starts on"
msgstr ""
@@ -34446,6 +35144,9 @@ msgstr ""
msgid "Strikethrough"
msgstr ""
+msgid "Strikethrough text"
+msgstr ""
+
msgid "Subgroup information"
msgstr ""
@@ -34680,6 +35381,21 @@ msgstr ""
msgid "Subscriptions"
msgstr ""
+msgid "Subscriptions|Chat with sales"
+msgstr ""
+
+msgid "Subscriptions|Close"
+msgstr ""
+
+msgid "Subscriptions|Not ready to buy yet?"
+msgstr ""
+
+msgid "Subscriptions|Start a free trial"
+msgstr ""
+
+msgid "Subscriptions|We understand. Maybe you have some questions for our sales team, or maybe you'd like to try some of the paid features first. What would you like to do?"
+msgstr ""
+
msgid "Subscription|Your subscription for %{strong}%{namespace_name}%{strong_close} has expired and you are now on %{pricing_link_start}the GitLab Free tier%{pricing_link_end}. Don't worry, your data is safe. Get in touch with our support team (%{support_email}). They'll gladly help with your subscription renewal."
msgstr ""
@@ -34890,6 +35606,9 @@ msgstr ""
msgid "SuperSonics|Maximum users"
msgstr ""
+msgid "SuperSonics|Offline cloud"
+msgstr ""
+
msgid "SuperSonics|Paste your activation code"
msgstr ""
@@ -34956,6 +35675,12 @@ msgstr ""
msgid "SuperSonics|You do not have an active subscription"
msgstr ""
+msgid "SuperSonics|You have a future dated license"
+msgstr ""
+
+msgid "SuperSonics|You have added a license that activates on %{date}. Please see the subscription history table below for more details."
+msgstr ""
+
msgid "SuperSonics|You have successfully added a license that activates on %{date}. Please see the subscription history table below for more details."
msgstr ""
@@ -35115,6 +35840,9 @@ msgstr ""
msgid "Tag name is required"
msgstr ""
+msgid "Tag push"
+msgstr ""
+
msgid "Tag push events"
msgstr ""
@@ -35217,6 +35945,9 @@ msgstr ""
msgid "TagsPage|protected"
msgstr ""
+msgid "Take a look at the documentation to discover all of GitLab’s capabilities."
+msgstr ""
+
msgid "Target Branch"
msgstr ""
@@ -35619,6 +36350,9 @@ msgstr ""
msgid "Tests"
msgstr ""
+msgid "Text (optional)"
+msgstr ""
+
msgid "Text added to the body of all email messages. %{character_limit} character limit"
msgstr ""
@@ -35669,6 +36403,9 @@ msgstr ""
msgid "The CSV export will be created in the background. Once finished, it will be sent to %{email} in an attachment."
msgstr ""
+msgid "The CSV export you requested of all user memberships is attached to this email."
+msgstr ""
+
msgid "The GitLab subscription service (customers.gitlab.com) is currently experiencing an outage. You can monitor the status and get updates at %{linkStart}status.gitlab.com%{linkEnd}."
msgstr ""
@@ -35744,6 +36481,9 @@ 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 epic"
+msgstr ""
+
msgid "The current issue"
msgstr ""
@@ -35905,6 +36645,9 @@ msgstr ""
msgid "The latest pipeline for this merge request has failed."
msgstr ""
+msgid "The license key is invalid."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -35920,6 +36663,9 @@ msgstr ""
msgid "The license was successfully uploaded and will be active from %{starts_at}. You can see the details below."
msgstr ""
+msgid "The license you uploaded is invalid. If the issue persists, contact support at %{link}."
+msgstr ""
+
msgid "The list creation wizard is already open"
msgstr ""
@@ -36541,10 +37287,13 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} and everything this project contains. %{strongOpen}There is no going back%{strongClose}"
+msgstr ""
+
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains."
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}on %{date}%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains. %{strongOpen}There is no going back.%{strongClose}"
msgstr ""
msgid "This action will %{strongOpen}permanently remove%{strongClose} %{codeOpen}%{group}%{codeClose} %{strongOpen}immediately%{strongClose}."
@@ -36673,9 +37422,6 @@ msgstr ""
msgid "This file was modified for readability, and can't accept suggestions. Edit it directly."
msgstr ""
-msgid "This forked project has the following:"
-msgstr ""
-
msgid "This form is disabled in preview"
msgstr ""
@@ -36688,7 +37434,7 @@ msgstr ""
msgid "This group can't be removed because it is linked to a subscription. To remove this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
-msgid "This group can't be transfered because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
+msgid "This group can't be transferred because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
msgid "This group cannot be invited to a project inside a group with enforced SSO"
@@ -36715,6 +37461,9 @@ 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 incident is already escalated with '%{escalation_policy_name}'."
+msgstr ""
+
msgid "This invitation was sent to %{mail_to_invite_email}, but you are signed in as %{link_to_current_user} with email %{mail_to_current_user}."
msgstr ""
@@ -36733,9 +37482,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 merge train pipeline"
-msgstr ""
-
msgid "This is a private email address %{helpIcon} generated just for you. Anyone who has it can create issues or merge requests as if they were you. If that happens, %{resetLinkStart}reset this token%{resetLinkEnd}."
msgstr ""
@@ -36757,6 +37503,12 @@ msgstr ""
msgid "This is your current session"
msgstr ""
+msgid "This issue cannot be assigned to a confidential epic because it is public."
+msgstr ""
+
+msgid "This issue cannot be made public because it belongs to a confidential epic."
+msgstr ""
+
msgid "This issue is confidential and should only be visible to team members with at least Reporter access."
msgstr ""
@@ -36874,6 +37626,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 branch is protected from force push."
+msgstr ""
+
msgid "This merge request cannot be rebased while there are conflicts."
msgstr ""
@@ -36925,9 +37680,15 @@ msgstr ""
msgid "This pipeline was triggered by a schedule."
msgstr ""
+msgid "This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project"
msgstr ""
+msgid "This project can be restored until %{date}."
+msgstr ""
+
msgid "This project cannot be %{visibilityLevel} because the visibility of %{openShowLink}%{name}%{closeShowLink} is %{visibility}. To make this project %{visibilityLevel}, you must first %{openEditLink}change the visibility%{closeEditLink} of the parent group."
msgstr ""
@@ -36946,6 +37707,9 @@ msgstr ""
msgid "This project is %{strongStart}NOT%{strongEnd} a fork, and has the following:"
msgstr ""
+msgid "This project is %{strongStart}NOT%{strongEnd} a fork. This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -37637,6 +38401,9 @@ msgstr ""
msgid "Today"
msgstr ""
+msgid "Todos count"
+msgstr ""
+
msgid "Todos|Are you looking for things to do? Take a look at %{strongStart}%{openIssuesLinkStart}open issues%{openIssuesLinkEnd}%{strongEnd}, contribute to %{strongStart}%{mergeRequestLinkStart}a merge request%{mergeRequestLinkEnd}%{mergeRequestLinkEnd}%{strongEnd}, or mention someone in a comment to automatically assign them a new to-do item."
msgstr ""
@@ -37910,10 +38677,8 @@ msgstr ""
msgid "Trending"
msgstr ""
-msgid "Trials|%{planName} Trial %{enDash} %{num} day left"
-msgid_plural "Trials|%{planName} Trial %{enDash} %{num} days left"
-msgstr[0] ""
-msgstr[1] ""
+msgid "Trials|%{planName} Trial"
+msgstr ""
msgid "Trials|Compare all plans"
msgstr ""
@@ -37921,6 +38686,9 @@ msgstr ""
msgid "Trials|Create a new group to start your GitLab Ultimate trial."
msgstr ""
+msgid "Trials|Day %{daysUsed}/%{duration}"
+msgstr ""
+
msgid "Trials|Go back to GitLab"
msgstr ""
@@ -38170,7 +38938,7 @@ msgstr ""
msgid "URL is triggered when repository is updated"
msgstr ""
-msgid "URL must be percent-encoded if neccessary."
+msgid "URL must be percent-encoded if necessary."
msgstr ""
msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
@@ -38389,6 +39157,9 @@ msgstr ""
msgid "Unlock account"
msgstr ""
+msgid "Unlock more features with GitLab Ultimate"
+msgstr ""
+
msgid "Unlock the discussion"
msgstr ""
@@ -38452,6 +39223,9 @@ msgstr ""
msgid "Unsubscribes from this %{quick_action_target}."
msgstr ""
+msgid "Unsupported sort value."
+msgstr ""
+
msgid "Unsupported todo type passed. Supported todo types are: %{todo_types}"
msgstr ""
@@ -38680,6 +39454,9 @@ msgstr ""
msgid "UsageQuota|File attachments and smaller design graphics."
msgstr ""
+msgid "UsageQuota|From %{storage_enforcement_date} storage limits will apply to this namespace. View and manage your usage in %{strong_start}Group Settings &gt; Usage quotas%{strong_end}."
+msgstr ""
+
msgid "UsageQuota|Git repository."
msgstr ""
@@ -38740,6 +39517,9 @@ msgstr ""
msgid "UsageQuota|Storage type"
msgstr ""
+msgid "UsageQuota|Storage used"
+msgstr ""
+
msgid "UsageQuota|This is the total amount of storage used across your projects within this namespace."
msgstr ""
@@ -38935,6 +39715,12 @@ msgstr ""
msgid "Use hashed storage paths for newly created and renamed repositories. Always enabled since 13.0."
msgstr ""
+msgid "Use issue count"
+msgstr ""
+
+msgid "Use issue weight"
+msgstr ""
+
msgid "Use one line per URI"
msgstr ""
@@ -39316,6 +40102,9 @@ msgstr ""
msgid "Users"
msgstr ""
+msgid "Users API rate limit"
+msgstr ""
+
msgid "Users can launch a development environment from a GitLab browser tab when the %{linkStart}Gitpod%{linkEnd} integration is enabled."
msgstr ""
@@ -39641,6 +40430,9 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View group pipeline usage quota"
+msgstr ""
+
msgid "View incident details at"
msgstr ""
@@ -39793,6 +40585,9 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
+msgid "Vulnerability"
+msgstr ""
+
msgid "Vulnerability Report"
msgstr ""
@@ -39844,6 +40639,9 @@ msgstr ""
msgid "VulnerabilityManagement|An unverified non-confirmed finding"
msgstr ""
+msgid "VulnerabilityManagement|At least one identifier is required"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -39853,12 +40651,24 @@ msgstr ""
msgid "VulnerabilityManagement|Create Jira issue"
msgstr ""
+msgid "VulnerabilityManagement|Enter a name"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE code"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE identifier URL"
+msgstr ""
+
msgid "VulnerabilityManagement|Fetching linked Jira issues"
msgstr ""
msgid "VulnerabilityManagement|Manually add a vulnerability entry into the vulnerability report."
msgstr ""
+msgid "VulnerabilityManagement|Name is a required field"
+msgstr ""
+
msgid "VulnerabilityManagement|Needs triage"
msgstr ""
@@ -39874,6 +40684,18 @@ msgstr ""
msgid "VulnerabilityManagement|Select a method"
msgstr ""
+msgid "VulnerabilityManagement|Select a severity level"
+msgstr ""
+
+msgid "VulnerabilityManagement|Select a status"
+msgstr ""
+
+msgid "VulnerabilityManagement|Severity is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Something went wrong while creating vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -39898,6 +40720,12 @@ msgstr ""
msgid "VulnerabilityManagement|Something went wrong, could not update vulnerability state."
msgstr ""
+msgid "VulnerabilityManagement|Status is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Submit vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Summary, detailed description, steps to reproduce, etc."
msgstr ""
@@ -40093,6 +40921,9 @@ msgstr ""
msgid "WARNING:"
msgstr ""
+msgid "WARNING: This snippet contains hidden files which might be used to mask malicious behavior. Exercise caution if cloning and executing code from this snippet."
+msgstr ""
+
msgid "Wait for the file to load to copy its contents"
msgstr ""
@@ -40312,6 +41143,15 @@ msgstr ""
msgid "Webhooks|An issue is created, updated, closed, or reopened."
msgstr ""
+msgid "Webhooks|Are you sure you want to delete this group hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this project hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this webhook?"
+msgstr ""
+
msgid "Webhooks|Comments"
msgstr ""
@@ -40321,6 +41161,9 @@ msgstr ""
msgid "Webhooks|Confidential issues events"
msgstr ""
+msgid "Webhooks|Delete webhook"
+msgstr ""
+
msgid "Webhooks|Deployment events"
msgstr ""
@@ -40554,6 +41397,9 @@ msgstr ""
msgid "Wiki"
msgstr ""
+msgid "Wiki page"
+msgstr ""
+
msgid "Wiki page was successfully created."
msgstr ""
@@ -40659,7 +41505,7 @@ msgstr ""
msgid "WikiPageConflictMessage|Someone edited the page the same time you did. Please check out %{wikiLinkStart}the page%{wikiLinkEnd} and make sure your changes will not unintentionally remove theirs."
msgstr ""
-msgid "WikiPage|An error occured while trying to render the content editor. Please try again later."
+msgid "WikiPage|An error occurred while trying to render the content editor. Please try again later."
msgstr ""
msgid "WikiPage|Are you sure you want to switch back to the classic editor?"
@@ -40818,6 +41664,18 @@ msgstr ""
msgid "WorkItem|New Task"
msgstr ""
+msgid "WorkItem|Something went wrong when creating a work item. Please try again"
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching the work item. Please try again."
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching work item types. Please try again"
+msgstr ""
+
+msgid "WorkItem|Type"
+msgstr ""
+
msgid "WorkItem|Work Items"
msgstr ""
@@ -40884,7 +41742,10 @@ msgstr ""
msgid "You are about to add %{usersTag} people to the discussion. They will all receive a notification."
msgstr ""
-msgid "You are about to permanently delete this project"
+msgid "You are about to delete this forked project containing:"
+msgstr ""
+
+msgid "You are about to delete this project containing:"
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."
@@ -40905,6 +41766,9 @@ msgstr ""
msgid "You are attempting to update a file that has changed since you started editing it."
msgstr ""
+msgid "You are billed if you exceed this number. %{qsrOverageLinkStart}How does billing work?%{qsrOverageLinkEnd}"
+msgstr ""
+
msgid "You are connected to the Prometheus server, but there is currently no data to display."
msgstr ""
@@ -40962,6 +41826,9 @@ msgstr ""
msgid "You are not authorized to update this scanner profile"
msgstr ""
+msgid "You are not authorized to upload metric images"
+msgstr ""
+
msgid "You are now impersonating %{username}"
msgstr ""
@@ -41115,9 +41982,6 @@ msgstr ""
msgid "You can only upload one design when dropping onto an existing design."
msgstr ""
-msgid "You can recover this project until %{date}"
-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 ""
@@ -41166,9 +42030,6 @@ msgstr ""
msgid "You cannot write to this read-only GitLab instance."
msgstr ""
-msgid "You can’t %{tag_start}edit%{tag_end} files directly in this project. Fork this project and submit a merge request with your changes."
-msgstr ""
-
msgid "You can’t edit files directly in this project. Fork this project and submit a merge request with your changes."
msgstr ""
@@ -41321,9 +42182,6 @@ 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 set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
@@ -41354,12 +42212,6 @@ msgstr ""
msgid "You must have maintainer access to force delete a lock"
msgstr ""
-msgid "You must have permission to create a project in a group before forking."
-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 ""
@@ -41765,7 +42617,7 @@ msgstr ""
msgid "Your public email will be displayed on your public profile."
msgstr ""
-msgid "Your request for access could not be processed: %{error_meesage}"
+msgid "Your request for access could not be processed: %{error_message}"
msgstr ""
msgid "Your request for access has been queued for review."
@@ -41948,6 +42800,9 @@ msgstr ""
msgid "archived:"
msgstr ""
+msgid "artifacts"
+msgstr ""
+
msgid "assign yourself"
msgstr ""
@@ -41977,6 +42832,9 @@ msgstr[1] ""
msgid "branch name"
msgstr ""
+msgid "builds"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -42400,6 +43258,9 @@ msgstr ""
msgid "contact with same email already exists in group hierarchy"
msgstr ""
+msgid "container registry images"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -42439,6 +43300,9 @@ msgstr ""
msgid "data"
msgstr ""
+msgid "database"
+msgstr ""
+
msgid "date must not be after 9999-12-31"
msgstr ""
@@ -42462,9 +43326,6 @@ msgstr ""
msgid "design"
msgstr ""
-msgid "detached"
-msgstr ""
-
msgid "disabled"
msgstr ""
@@ -42713,7 +43574,7 @@ msgstr ""
msgid "is not a valid X509 certificate."
msgstr ""
-msgid "is not allowed for sign-up."
+msgid "is not allowed for sign-up. Please use your regular email address."
msgstr ""
msgid "is not allowed for this group."
@@ -42725,7 +43586,7 @@ msgstr ""
msgid "is not allowed since the group is not top-level group."
msgstr ""
-msgid "is not allowed."
+msgid "is not allowed. Please use your regular email address."
msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
@@ -42812,6 +43673,9 @@ msgstr ""
msgid "level: %{level}"
msgstr ""
+msgid "lfs objects"
+msgstr ""
+
msgid "limit of %{project_limit} reached"
msgstr ""
@@ -43031,6 +43895,9 @@ msgstr ""
msgid "mrWidget|Merge blocked: pipeline must succeed. It's waiting for a manual action to continue."
msgstr ""
+msgid "mrWidget|Merge blocked: pipeline must succeed. Push a commit that fixes the failure, or %{linkStart}learn about other solutions.%{linkEnd}"
+msgstr ""
+
msgid "mrWidget|Merge blocked: this merge request must be approved."
msgstr ""
@@ -43148,9 +44015,6 @@ msgstr ""
msgid "mrWidget|The changes were not merged into"
msgstr ""
-msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -43298,9 +44162,6 @@ msgstr ""
msgid "open issue"
msgstr ""
-msgid "opened %{timeAgo}"
-msgstr ""
-
msgid "or"
msgstr ""
@@ -43312,6 +44173,12 @@ msgid_plural "out of %d total tests"
msgstr[0] ""
msgstr[1] ""
+msgid "packages"
+msgstr ""
+
+msgid "pages"
+msgstr ""
+
msgid "parent"
msgid_plural "parents"
msgstr[0] ""
@@ -43461,6 +44328,9 @@ msgid_plural "replies"
msgstr[0] ""
msgstr[1] ""
+msgid "repositories"
+msgstr ""
+
msgid "repository:"
msgstr ""
@@ -43581,12 +44451,18 @@ msgstr ""
msgid "tag name"
msgstr ""
+msgid "terraform states"
+msgstr ""
+
msgid "the correct format."
msgstr ""
msgid "the file"
msgstr ""
+msgid "the following epic(s)"
+msgstr ""
+
msgid "the following issue(s)"
msgstr ""
@@ -43599,21 +44475,12 @@ msgstr ""
msgid "this document"
msgstr ""
-msgid "this issue cannot be assigned to a confidential epic since it is public"
-msgstr ""
-
-msgid "this issue cannot be made public since it belongs to a confidential epic"
-msgstr ""
-
msgid "time summary"
msgstr ""
msgid "toggle collapse"
msgstr ""
-msgid "train"
-msgstr ""
-
msgid "triggered"
msgstr ""
@@ -43742,3 +44609,6 @@ msgstr ""
msgid "{project}"
msgstr ""
+msgid "✔"
+msgstr ""
+
diff --git a/locale/cs_CZ/gitlab.po b/locale/cs_CZ/gitlab.po
index ce37c2d4bc5..e193aa9e5cb 100644
--- a/locale/cs_CZ/gitlab.po
+++ b/locale/cs_CZ/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: cs\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2022-02-02 15:45\n"
+"PO-Revision-Date: 2022-03-01 20:38\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -174,6 +174,13 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "%d assigned issue"
+msgid_plural "%d assigned issues"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -559,8 +566,29 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
-msgid "%d vulnerability updated"
-msgid_plural "%d vulnerabilities updated"
+msgid "%d vulnerability set to confirmed"
+msgid_plural "%d vulnerabilities set to confirmed"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
+msgid "%d vulnerability set to dismissed"
+msgid_plural "%d vulnerabilities set to dismissed"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
+msgid "%d vulnerability set to needs triage"
+msgid_plural "%d vulnerabilities set to needs triage"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
+msgid "%d vulnerability set to resolved"
+msgid_plural "%d vulnerabilities set to resolved"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
@@ -662,6 +690,12 @@ msgstr[3] ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{completed} of %{total} issues closed"
+msgstr ""
+
+msgid "%{completed} of %{total} weight completed"
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -1022,6 +1056,9 @@ msgstr ""
msgid "%{openedIssues} open, %{closedIssues} closed"
msgstr ""
+msgid "%{percentage}%% issues closed"
+msgstr ""
+
msgid "%{percentage}%% weight completed"
msgstr ""
@@ -1481,6 +1518,9 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "- of - issues closed"
+msgstr ""
+
msgid "- of - weight completed"
msgstr ""
@@ -1669,7 +1709,7 @@ msgstr ""
msgid "1000+"
msgstr ""
-msgid "192.168.0.0/24"
+msgid "192.168.0.0/24 or 2001:0DB8:1234::/48"
msgstr ""
msgid "1st contribution!"
@@ -1981,13 +2021,13 @@ msgstr ""
msgid "AWS Access Key"
msgstr ""
-msgid "AWS Access Key. Only required if not using role instance credentials"
+msgid "AWS Secret Access Key"
msgstr ""
-msgid "AWS Secret Access Key"
+msgid "AWS access key ID (Optional)"
msgstr ""
-msgid "AWS Secret Access Key. Only required if not using role instance credentials"
+msgid "AWS secret access key (Optional)"
msgstr ""
msgid "AWS service error: %{error}"
@@ -2047,9 +2087,6 @@ msgstr ""
msgid "Access granted"
msgstr ""
-msgid "Access key ID"
-msgstr ""
-
msgid "Access requests"
msgstr ""
@@ -2224,7 +2261,7 @@ msgstr ""
msgid "Activity"
msgstr ""
-msgid "Activity|An error occured while retrieving activity. Reload the page to try again."
+msgid "Activity|An error occurred while retrieving activity. Reload the page to try again."
msgstr ""
msgid "Add"
@@ -2263,6 +2300,9 @@ msgstr ""
msgid "Add a %{type}"
msgstr ""
+msgid "Add a GCP region"
+msgstr ""
+
msgid "Add a GPG key"
msgstr ""
@@ -2314,6 +2354,9 @@ msgstr ""
msgid "Add a numbered list"
msgstr ""
+msgid "Add a related epic"
+msgstr ""
+
msgid "Add a related issue"
msgstr ""
@@ -2428,6 +2471,9 @@ msgstr ""
msgid "Add or subtract spent time"
msgstr ""
+msgid "Add people"
+msgstr ""
+
msgid "Add previously merged commits"
msgstr ""
@@ -2494,6 +2540,9 @@ msgstr ""
msgid "Add webhook"
msgstr ""
+msgid "Add your team members and others to GitLab."
+msgstr ""
+
msgid "Add/remove"
msgstr ""
@@ -3316,12 +3365,6 @@ msgstr ""
msgid "AdvancedSearch|Reindex required"
msgstr ""
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. Permanently deleting this project will %{strongStart}immediately delete%{strongEnd} its repositories and %{strongStart}all related resources%{strongEnd}, including issues, merge requests etc."
-msgstr ""
-
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. You will lose this project's repository and %{strongStart}all related resources%{strongEnd}, including issues and merge requests."
-msgstr ""
-
msgid "After a successful password update you will be redirected to login screen."
msgstr ""
@@ -3352,6 +3395,9 @@ msgstr ""
msgid "Akismet helps prevent the creation of spam issues in public projects."
msgstr ""
+msgid "Alert"
+msgstr ""
+
msgid "AlertManagement|Acknowledged"
msgstr ""
@@ -3724,9 +3770,6 @@ msgstr ""
msgid "All environments"
msgstr ""
-msgid "All epics"
-msgstr ""
-
msgid "All groups and projects"
msgstr ""
@@ -4467,14 +4510,17 @@ msgstr ""
msgid "ApplicationSettings|Approve users in the pending approval status?"
msgstr ""
-msgid "ApplicationSettings|By making this change, you will automatically approve %d user with the pending approval status."
-msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users with the pending approval status."
+msgid "ApplicationSettings|Approve users who are pending approval?"
+msgstr ""
+
+msgid "ApplicationSettings|By making this change, you will automatically approve %d user who is pending approval."
+msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users who are pending approval."
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
-msgid "ApplicationSettings|By making this change, you will automatically approve all users in pending approval status."
+msgid "ApplicationSettings|By making this change, you will automatically approve all users who are pending approval."
msgstr ""
msgid "ApplicationSettings|Denied domains for sign-ups"
@@ -4890,10 +4936,10 @@ msgstr ""
msgid "Archiving the project will make it entirely read-only. It is hidden from the dashboard and doesn't show up in searches. %{strong_start}The repository cannot be committed to, and no issues, comments, or other entities can be created.%{strong_end} %{link_start}Learn more.%{link_end}"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to delete this project?"
+msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
+msgid "Are you absolutely sure?"
msgstr ""
msgid "Are you sure that you want to archive this project?"
@@ -4929,12 +4975,18 @@ msgstr ""
msgid "Are you sure you want to delete this SSH key?"
msgstr ""
+msgid "Are you sure you want to delete this comment?"
+msgstr ""
+
msgid "Are you sure you want to delete this deploy key?"
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 label?"
+msgstr ""
+
msgid "Are you sure you want to delete this pipeline schedule?"
msgstr ""
@@ -4950,9 +5002,6 @@ msgstr ""
msgid "Are you sure you want to discard your changes?"
msgstr ""
-msgid "Are you sure you want to erase this build?"
-msgstr ""
-
msgid "Are you sure you want to import %d repository?"
msgid_plural "Are you sure you want to import %d repositories?"
msgstr[0] ""
@@ -5002,6 +5051,9 @@ msgstr ""
msgid "Are you sure you want to remove this list?"
msgstr ""
+msgid "Are you sure you want to remove this nickname?"
+msgstr ""
+
msgid "Are you sure you want to reset the health check token?"
msgstr ""
@@ -5014,10 +5066,10 @@ 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?"
+msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
msgstr ""
-msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
+msgid "Are you sure you want to revoke this project access token? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to stop this environment?"
@@ -5164,9 +5216,6 @@ msgstr ""
msgid "Assigned to %{assignee_name}"
msgstr ""
-msgid "Assigned to %{name}"
-msgstr ""
-
msgid "Assigned to me"
msgstr ""
@@ -5235,6 +5284,9 @@ msgstr[3] ""
msgid "Attaching the file failed."
msgstr ""
+msgid "Attention"
+msgstr ""
+
msgid "Audit Events"
msgstr ""
@@ -5397,6 +5449,12 @@ msgstr ""
msgid "Authorized applications (%{size})"
msgstr ""
+msgid "AuthorizedApplication|Are you sure you want to revoke this application?"
+msgstr ""
+
+msgid "AuthorizedApplication|Revoke application"
+msgstr ""
+
msgid "Authors: %{authors}"
msgstr "Autoři: %{authors}"
@@ -6598,6 +6656,9 @@ msgstr ""
msgid "CICDAnalytics|Shared Runners Usage"
msgstr ""
+msgid "CICDAnalytics|Shared runner pipeline minute duration by month"
+msgstr ""
+
msgid "CICDAnalytics|Shared runner usage"
msgstr ""
@@ -6739,6 +6800,9 @@ msgstr ""
msgid "Can create groups:"
msgstr ""
+msgid "Can not delete primary training"
+msgstr ""
+
msgid "Can't apply as the source branch was deleted."
msgstr ""
@@ -7072,9 +7136,6 @@ msgstr ""
msgid "Changing any setting here requires an application restart"
msgstr ""
-msgid "Changing group URL can have unintended side effects."
-msgstr ""
-
msgid "Charts can't be displayed as the request for data has timed out. %{documentationLink}"
msgstr ""
@@ -7162,9 +7223,6 @@ msgstr ""
msgid "Checking branch availability..."
msgstr ""
-msgid "Checking group URL availability..."
-msgstr ""
-
msgid "Checking group path availability..."
msgstr ""
@@ -7662,6 +7720,9 @@ msgstr ""
msgid "Clear recent searches"
msgstr ""
+msgid "Clear repository checks"
+msgstr ""
+
msgid "Clear search"
msgstr ""
@@ -7794,9 +7855,6 @@ msgstr ""
msgid "Closed MRs"
msgstr ""
-msgid "Closed epics"
-msgstr ""
-
msgid "Closed issues"
msgstr ""
@@ -7833,13 +7891,13 @@ msgstr ""
msgid "Cluster level"
msgstr ""
-msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
+msgid "Cluster type must be specified for Stages::ClusterEndpointInserter"
msgstr ""
msgid "ClusterAgents|%{name} successfully deleted"
msgstr ""
-msgid "ClusterAgents|%{number} of %{total} Agents"
+msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
@@ -7881,6 +7939,15 @@ msgstr ""
msgid "ClusterAgents|Agent never connected to GitLab"
msgstr ""
+msgid "ClusterAgents|Agent version mismatch"
+msgstr ""
+
+msgid "ClusterAgents|Agent version mismatch and update"
+msgstr ""
+
+msgid "ClusterAgents|Agent version update required"
+msgstr ""
+
msgid "ClusterAgents|All"
msgstr ""
@@ -7905,7 +7972,7 @@ msgstr ""
msgid "ClusterAgents|Configuration"
msgstr ""
-msgid "ClusterAgents|Connect a cluster through the Agent"
+msgid "ClusterAgents|Connect a cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connect existing cluster"
@@ -7914,13 +7981,13 @@ msgstr ""
msgid "ClusterAgents|Connect with a certificate"
msgstr ""
-msgid "ClusterAgents|Connect with agent"
+msgid "ClusterAgents|Connect with an agent"
msgstr ""
msgid "ClusterAgents|Connect with the GitLab Agent"
msgstr ""
-msgid "ClusterAgents|Connect your cluster through the Agent"
+msgid "ClusterAgents|Connect your cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connected"
@@ -7980,7 +8047,10 @@ msgstr ""
msgid "ClusterAgents|How to register an agent?"
msgstr ""
-msgid "ClusterAgents|Install new Agent"
+msgid "ClusterAgents|How to update an agent?"
+msgstr ""
+
+msgid "ClusterAgents|Install a new agent"
msgstr ""
msgid "ClusterAgents|Last connected %{timeAgo}."
@@ -8007,7 +8077,7 @@ msgstr ""
msgid "ClusterAgents|Never connected"
msgstr ""
-msgid "ClusterAgents|No Agents"
+msgid "ClusterAgents|No agents"
msgstr ""
msgid "ClusterAgents|No clusters connected through cluster certificates"
@@ -8067,6 +8137,9 @@ msgstr ""
msgid "ClusterAgents|The agent has not been connected in a long time. There might be a connectivity issue. Last contact was %{timeAgo}."
msgstr ""
+msgid "ClusterAgents|The agent version do not match each other across your cluster's pods. This can happen when a new agent version was just deployed and Kubernetes is shutting down the old pods."
+msgstr ""
+
msgid "ClusterAgents|The recommended installation method includes the token. If you want to follow the advanced installation method provided in the docs, make sure you save the token value before you close this window."
msgstr ""
@@ -8116,6 +8189,9 @@ msgstr ""
msgid "ClusterAgents|You will need to create a token to connect to your agent"
msgstr ""
+msgid "ClusterAgents|Your agent version is out of sync with your GitLab version (v%{version}), which might cause compatibility problems. Update the agent installed on your cluster to the most recent version."
+msgstr ""
+
msgid "ClusterAgents|Your instance doesn't have the %{linkStart}GitLab Agent Server (KAS)%{linkEnd} set up. Ask a GitLab Administrator to install it."
msgstr ""
@@ -8992,9 +9068,6 @@ msgstr ""
msgid "Comma-separated list of email addresses."
msgstr ""
-msgid "Comma-separated list of users allowed to exceed the rate limit."
-msgstr ""
-
msgid "Comma-separated, e.g. '1.1.1.1, 2.2.2.0/24'"
msgstr ""
@@ -9323,6 +9396,12 @@ msgstr ""
msgid "Confidential"
msgstr ""
+msgid "Confidential issue"
+msgstr ""
+
+msgid "Confidential note"
+msgstr ""
+
msgid "Confidentiality"
msgstr ""
@@ -9356,6 +9435,9 @@ msgstr ""
msgid "Configure Dependency Scanning in `.gitlab-ci.yml`, creating this file if it does not already exist"
msgstr ""
+msgid "Configure GitLab"
+msgstr ""
+
msgid "Configure GitLab runners to start using the Web Terminal. %{helpStart}Learn more.%{helpEnd}"
msgstr ""
@@ -9404,6 +9486,15 @@ msgstr ""
msgid "Configure pipelines to deploy web apps, backend services, APIs and static resources to Google Cloud"
msgstr ""
+msgid "Configure region"
+msgstr ""
+
+msgid "Configure region for environment"
+msgstr ""
+
+msgid "Configure regions"
+msgstr ""
+
msgid "Configure repository mirroring."
msgstr ""
@@ -9437,6 +9528,9 @@ msgstr ""
msgid "Configure which lists are shown for anyone who visits this board"
msgstr ""
+msgid "Configure your environments to be deployed to specific geographical regions"
+msgstr ""
+
msgid "Confirm"
msgstr ""
@@ -10145,10 +10239,10 @@ msgstr ""
msgid "CorpusManagement|Actions"
msgstr ""
-msgid "CorpusManagement|Corpus are used in fuzz testing as mutation source to Improve future testing."
+msgid "CorpusManagement|Corpus file"
msgstr ""
-msgid "CorpusManagement|Corpus file"
+msgid "CorpusManagement|Corpus files are used in coverage-guided fuzz testing as seed inputs to improve testing."
msgstr ""
msgid "CorpusManagement|Corpus files must be in *.zip format. Maximum 5 GB"
@@ -10202,6 +10296,9 @@ msgstr ""
msgid "Could not apply %{name} command."
msgstr ""
+msgid "Could not apply %{name} command. %{message}."
+msgstr ""
+
msgid "Could not authorize chat nickname. Try again!"
msgstr ""
@@ -10352,6 +10449,9 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
+msgid "Create a group"
+msgstr ""
+
msgid "Create a merge request"
msgstr ""
@@ -10376,6 +10476,9 @@ msgstr ""
msgid "Create a personal access token on your account to pull or push via %{protocol}."
msgstr ""
+msgid "Create a project"
+msgstr ""
+
msgid "Create an account using:"
msgstr ""
@@ -10739,6 +10842,9 @@ msgstr ""
msgid "Creation date"
msgstr ""
+msgid "Creator"
+msgstr ""
+
msgid "Credentials"
msgstr ""
@@ -10751,9 +10857,15 @@ msgstr ""
msgid "CredentialsInventory|Personal Access Tokens"
msgstr ""
+msgid "CredentialsInventory|Project Access Tokens"
+msgstr ""
+
msgid "CredentialsInventory|SSH Keys"
msgstr ""
+msgid "Credit card required to be on file in order to create a pipeline"
+msgstr ""
+
msgid "Credit card:"
msgstr ""
@@ -10937,9 +11049,6 @@ msgstr ""
msgid "Customer relations"
msgstr ""
-msgid "Customizable by an administrator."
-msgstr ""
-
msgid "Customizable by owners."
msgstr ""
@@ -11069,30 +11178,18 @@ msgstr ""
msgid "CycleAnalytics|%{selectedLabelsCount} selected (%{maxLabels} max)"
msgstr ""
-msgid "CycleAnalytics|%{stageCount} stages selected"
-msgstr ""
-
-msgid "CycleAnalytics|All stages"
-msgstr ""
-
-msgid "CycleAnalytics|Average days to completion"
+msgid "CycleAnalytics|Average time to completion"
msgstr ""
msgid "CycleAnalytics|Date"
msgstr ""
-msgid "CycleAnalytics|Days to completion"
-msgstr ""
-
msgid "CycleAnalytics|Display chart filters"
msgstr ""
msgid "CycleAnalytics|Lead Time for Changes"
msgstr ""
-msgid "CycleAnalytics|No stages selected"
-msgstr ""
-
msgid "CycleAnalytics|Number of tasks"
msgstr ""
@@ -11125,18 +11222,30 @@ msgstr ""
msgid "CycleAnalytics|Showing data for group '%{groupName}' from %{createdAfter} to %{createdBefore}"
msgstr ""
-msgid "CycleAnalytics|Stages"
+msgid "CycleAnalytics|Stage time: %{title}"
msgstr ""
msgid "CycleAnalytics|Tasks by type"
msgstr ""
-msgid "CycleAnalytics|The average time spent in the selected stage for the items that were completed on each date. Data limited to the last 500 items."
+msgid "CycleAnalytics|The average time items spent in this stage. Data limited to items completed within this date range."
msgstr ""
msgid "CycleAnalytics|The given date range is larger than 180 days"
msgstr ""
+msgid "CycleAnalytics|The total time items spent across each value stream stage. Data limited to items completed within this date range."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Stage time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Total time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|Total time"
+msgstr ""
+
msgid "CycleAnalytics|Type of work"
msgstr ""
@@ -11149,9 +11258,6 @@ msgstr ""
msgid "CycleAnalytics|project dropdown filter"
msgstr ""
-msgid "CycleAnalytics|stage dropdown"
-msgstr ""
-
msgid "DAG visualization requires at least 3 dependent jobs."
msgstr ""
@@ -11251,10 +11357,16 @@ msgstr ""
msgid "DastProfiles|AJAX spider"
msgstr ""
+msgid "DastProfiles|API"
+msgstr ""
+
+msgid "DastProfiles|API endpoint URL"
+msgstr ""
+
msgid "DastProfiles|Active"
msgstr ""
-msgid "DastProfiles|Additional request headers (Optional)"
+msgid "DastProfiles|Additional request headers (optional)"
msgstr ""
msgid "DastProfiles|Are you sure you want to delete this profile?"
@@ -11269,6 +11381,9 @@ msgstr ""
msgid "DastProfiles|Branch missing"
msgstr ""
+msgid "DastProfiles|Choose a scan method"
+msgstr ""
+
msgid "DastProfiles|Could not create the scanner profile. Please try again."
msgstr ""
@@ -11338,7 +11453,13 @@ msgstr ""
msgid "DastProfiles|Excluded URLs"
msgstr ""
-msgid "DastProfiles|Excluded URLs (Optional)"
+msgid "DastProfiles|Excluded URLs (optional)"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths (optional)"
msgstr ""
msgid "DastProfiles|Hide debug messages"
@@ -11395,9 +11516,6 @@ msgstr ""
msgid "DastProfiles|Request headers"
msgstr ""
-msgid "DastProfiles|Rest API"
-msgstr ""
-
msgid "DastProfiles|Run the AJAX spider, in addition to the traditional spider, to crawl the target site."
msgstr ""
@@ -11407,6 +11525,9 @@ msgstr ""
msgid "DastProfiles|Save profile"
msgstr ""
+msgid "DastProfiles|Scan method"
+msgstr ""
+
msgid "DastProfiles|Scan mode"
msgstr ""
@@ -11485,12 +11606,24 @@ msgstr ""
msgid "DastProfiles|Website"
msgstr ""
+msgid "DastProfiles|What does each method do?"
+msgstr ""
+
msgid "DastProfiles|You can either choose a passive scan or validate the target site from the site profile management page. %{docsLinkStart}Learn more about site validation.%{docsLinkEnd}"
msgstr ""
msgid "DastProfiles|You cannot run an active scan against an unvalidated site."
msgstr ""
+msgid "DastProfiles|folder/dast_example.har or https://example.com/dast_example.har"
+msgstr ""
+
+msgid "DastProfiles|folder/example.postman_collection.json or https://example.com/"
+msgstr ""
+
+msgid "DastProfiles|folder/openapi.json or https://example.com/openapi.json"
+msgstr ""
+
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
@@ -11600,6 +11733,9 @@ msgstr ""
msgid "DatadogIntegration|API URL"
msgstr ""
+msgid "DatadogIntegration|Custom tags in Datadog. Enter one tag per line in the %{codeOpen}key:value%{codeClose} format. %{linkOpen}How do I use tags?%{linkClose}"
+msgstr ""
+
msgid "DatadogIntegration|Environment"
msgstr ""
@@ -11618,12 +11754,18 @@ msgstr ""
msgid "DatadogIntegration|Tag all data from this GitLab instance in Datadog. Useful when managing several self-managed deployments."
msgstr ""
+msgid "DatadogIntegration|Tags"
+msgstr ""
+
msgid "DatadogIntegration|The Datadog site to send data to. To send data to the EU site, use %{codeOpen}datadoghq.eu%{codeClose}."
msgstr ""
msgid "DatadogIntegration|Trace your GitLab pipelines with Datadog."
msgstr ""
+msgid "DatadogIntegration|have an invalid format"
+msgstr ""
+
msgid "Datasource name not found"
msgstr ""
@@ -11633,9 +11775,6 @@ msgstr ""
msgid "Date merged"
msgstr ""
-msgid "Date picker"
-msgstr ""
-
msgid "Date range"
msgstr ""
@@ -11789,9 +11928,6 @@ msgstr ""
msgid "Definition"
msgstr ""
-msgid "Delayed Project Deletion (%{adjourned_deletion})"
-msgstr ""
-
msgid "DelayedJobs|Are you sure you want to run %{jobName} immediately? Otherwise this job will run automatically after its timer finishes."
msgstr ""
@@ -11870,10 +12006,10 @@ msgstr ""
msgid "Delete pipeline"
msgstr ""
-msgid "Delete project"
+msgid "Delete pipeline schedule"
msgstr ""
-msgid "Delete project. Are you ABSOLUTELY SURE?"
+msgid "Delete project"
msgstr ""
msgid "Delete row"
@@ -11903,6 +12039,9 @@ msgstr ""
msgid "Delete this epic and all descendants?"
msgstr ""
+msgid "Delete this project"
+msgstr ""
+
msgid "Delete user list"
msgstr ""
@@ -12173,6 +12312,12 @@ msgstr ""
msgid "Deploy to..."
msgstr ""
+msgid "DeployBoards|To see deployment progress for your environments, make sure you are deploying to %{codeStart}$KUBE_NAMESPACE%{codeEnd} and annotating with %{codeStart}app.gitlab.com/app=$CI_PROJECT_PATH_SLUG%{codeEnd} and %{codeStart}app.gitlab.com/env=$CI_ENVIRONMENT_SLUG%{codeEnd}."
+msgstr ""
+
+msgid "DeployBoard|Kubernetes Pods"
+msgstr ""
+
msgid "DeployFreeze|Add a freeze period to prevent unintended releases during a period of time for a given environment. You must update the deployment jobs in %{filename} according to the deploy freezes added here. %{freeze_period_link_start}Learn more.%{freeze_period_link_end}"
msgstr ""
@@ -12257,9 +12402,6 @@ msgstr ""
msgid "DeployTokens|Active Deploy Tokens (%{active_tokens})"
msgstr ""
-msgid "DeployTokens|Allows read and write access to registry images."
-msgstr ""
-
msgid "DeployTokens|Allows read and write access to the package registry."
msgstr ""
@@ -12272,6 +12414,9 @@ msgstr ""
msgid "DeployTokens|Allows read-only access to the repository."
msgstr ""
+msgid "DeployTokens|Allows write access to registry images."
+msgstr ""
+
msgid "DeployTokens|Copy deploy token"
msgstr ""
@@ -12365,12 +12510,57 @@ msgstr ""
msgid "Deploying to AWS is easy with GitLab"
msgstr ""
+msgid "Deployment"
+msgstr ""
+
msgid "Deployment Frequency"
msgstr ""
+msgid "Deployment Target|Project deployment target (optional)"
+msgstr ""
+
+msgid "Deployment Target|Select the deployment target"
+msgstr ""
+
msgid "Deployment frequency"
msgstr ""
+msgid "DeploymentTarget|GitLab Pages"
+msgstr ""
+
+msgid "DeploymentTarget|Heroku"
+msgstr ""
+
+msgid "DeploymentTarget|Infrastructure provider (Terraform, Cloudformation, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Kubernetes (GKE, EKS, OpenShift, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Managed container runtime (Fargate, Cloud Run, DigitalOcean App)"
+msgstr ""
+
+msgid "DeploymentTarget|Mobile app store"
+msgstr ""
+
+msgid "DeploymentTarget|No deployment planned"
+msgstr ""
+
+msgid "DeploymentTarget|Other hosting service"
+msgstr ""
+
+msgid "DeploymentTarget|Registry (package or container)"
+msgstr ""
+
+msgid "DeploymentTarget|Self-managed container runtime (Podman, Docker Swarm, Docker Compose)"
+msgstr ""
+
+msgid "DeploymentTarget|Serverless backend (Lambda, Cloud functions)"
+msgstr ""
+
+msgid "DeploymentTarget|Virtual machine (for example, EC2)"
+msgstr ""
+
msgid "Deployments"
msgstr ""
@@ -12411,6 +12601,9 @@ msgstr ""
msgid "Deployment|This deployment was created using the API"
msgstr ""
+msgid "Deployment|Triggerer"
+msgstr ""
+
msgid "Deployment|Waiting"
msgstr ""
@@ -12438,6 +12631,18 @@ msgstr ""
msgid "Deprecated API rate limits"
msgstr ""
+msgid "Deprecations|Feature deprecation and removal"
+msgstr ""
+
+msgid "Deprecations|For information on a possible replacement %{epicStart} learn more about Opstrace %{epicEnd}."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7 and are %{epicStart} scheduled for removal %{epicEnd} in GitLab 15.0."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7, and are %{removal_link_start} scheduled for removal %{link_end} in GitLab 15.0. For information on a possible replacement, %{opstrace_link_start} learn more about Opstrace %{link_end}."
+msgstr ""
+
msgid "Deprioritize label"
msgstr ""
@@ -12685,10 +12890,10 @@ msgstr ""
msgid "DevopsAdoption|At least one deploy"
msgstr ""
-msgid "DevopsAdoption|At least one issue opened"
+msgid "DevopsAdoption|At least one issue created"
msgstr ""
-msgid "DevopsAdoption|At least one merge request opened"
+msgid "DevopsAdoption|At least one merge request created"
msgstr ""
msgid "DevopsAdoption|At least one pipeline successfully run"
@@ -12895,6 +13100,9 @@ msgstr ""
msgid "Direct member"
msgstr ""
+msgid "Direct members"
+msgstr ""
+
msgid "Direct non-authenticated users to this page."
msgstr ""
@@ -13013,6 +13221,9 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "Dismiss Alert"
+msgstr ""
+
msgid "Dismiss merge request promotion"
msgstr ""
@@ -13040,9 +13251,15 @@ msgstr ""
msgid "Display alerts from all configured monitoring tools."
msgstr ""
+msgid "Display milestones"
+msgstr ""
+
msgid "Display name"
msgstr ""
+msgid "Display progress of child issues"
+msgstr ""
+
msgid "Display rendered file"
msgstr ""
@@ -13148,6 +13365,9 @@ msgstr ""
msgid "Download image"
msgstr ""
+msgid "Download payload"
+msgstr ""
+
msgid "Download raw data (.csv)"
msgstr ""
@@ -13325,6 +13545,9 @@ msgstr ""
msgid "Edit in Web IDE"
msgstr ""
+msgid "Edit in pipeline editor"
+msgstr ""
+
msgid "Edit in single-file editor"
msgstr ""
@@ -13367,6 +13590,9 @@ msgstr ""
msgid "Edit your most recent comment in a thread (from an empty textarea)"
msgstr ""
+msgid "Edit, lint, and visualize your pipeline."
+msgstr ""
+
msgid "Edited"
msgstr ""
@@ -13808,6 +14034,9 @@ msgstr ""
msgid "Enforce two-factor authentication for all user sign-ins."
msgstr ""
+msgid "Enhance security by storing service account keys in secret managers - learn more about %{docLinkStart}secret management with GitLab%{docLinkEnd}"
+msgstr ""
+
msgid "Ensure connectivity is available from the GitLab server to the Prometheus server"
msgstr ""
@@ -13868,6 +14097,9 @@ 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 following to confirm:"
+msgstr ""
+
msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
@@ -14400,9 +14632,6 @@ 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 ""
@@ -14538,6 +14767,9 @@ msgstr ""
msgid "Errors:"
msgstr ""
+msgid "Escalate this incident"
+msgstr ""
+
msgid "Escalation Policies"
msgstr ""
@@ -14550,6 +14782,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy"
+msgstr ""
+
msgid "Escalation policy:"
msgstr ""
@@ -14803,6 +15038,9 @@ msgstr ""
msgid "Existing sign in methods may be removed"
msgstr ""
+msgid "Exit."
+msgstr ""
+
msgid "Expand"
msgstr ""
@@ -14899,6 +15137,9 @@ msgstr ""
msgid "Explore public groups"
msgstr ""
+msgid "Explore public projects"
+msgstr ""
+
msgid "Explore snippets"
msgstr ""
@@ -15062,7 +15303,7 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
-msgid "Failed to assign a reviewer because no user was found."
+msgid "Failed to assign a reviewer because no user was specified."
msgstr ""
msgid "Failed to assign a user because no user was found."
@@ -15128,10 +15369,10 @@ msgstr ""
msgid "Failed to find import label for Jira import."
msgstr ""
-msgid "Failed to generate export, please try again later."
+msgid "Failed to find users for %{missing}"
msgstr ""
-msgid "Failed to generate report, please try again after sometime"
+msgid "Failed to generate export, please try again later."
msgstr ""
msgid "Failed to get ref."
@@ -15230,6 +15471,9 @@ msgstr ""
msgid "Failed to remove a to-do item for the design."
msgstr ""
+msgid "Failed to remove attention because no user was found."
+msgstr ""
+
msgid "Failed to remove mirror."
msgstr ""
@@ -15242,6 +15486,9 @@ msgstr ""
msgid "Failed to remove user key."
msgstr ""
+msgid "Failed to request attention because no user was found."
+msgstr ""
+
msgid "Failed to reset key. Please try again."
msgstr ""
@@ -15323,6 +15570,9 @@ msgstr ""
msgid "Feature Flags"
msgstr ""
+msgid "Feature deprecation and removal"
+msgstr ""
+
msgid "Feature flag status"
msgstr ""
@@ -15822,7 +16072,7 @@ msgstr ""
msgid "For each job, re-use the project workspace. If the workspace doesn't exist, use %{code_open}git clone%{code_close}."
msgstr ""
-msgid "For example, the application using the token or the purpose of the token."
+msgid "For example, the application using the token or the purpose of the token. Do not give sensitive information for the name of the token, as it will be visible to all %{resource_type} members."
msgstr ""
msgid "For files larger than this limit, only index the file name. The file content is neither indexed nor searchable."
@@ -15906,9 +16156,6 @@ msgstr ""
msgid "ForkProject|Select a namespace"
msgstr ""
-msgid "ForkProject|Select a namespace to fork the project"
-msgstr ""
-
msgid "ForkProject|The project can be accessed by any logged in user."
msgstr ""
@@ -16005,6 +16252,9 @@ msgstr ""
msgid "Full name"
msgstr ""
+msgid "GCP region configured"
+msgstr ""
+
msgid "GPG Key ID:"
msgstr ""
@@ -16185,6 +16435,9 @@ msgstr ""
msgid "Geo|Failed"
msgstr ""
+msgid "Geo|Filter Geo sites"
+msgstr ""
+
msgid "Geo|Filter by name"
msgstr ""
@@ -16596,6 +16849,12 @@ msgstr ""
msgid "GitLab Issue"
msgstr ""
+msgid "GitLab KAS"
+msgstr ""
+
+msgid "GitLab Memberships CSV Export"
+msgstr ""
+
msgid "GitLab Pages"
msgstr ""
@@ -16644,6 +16903,9 @@ 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 free to use. Many features for larger teams are part of our %{link_start}paid products%{link_end}. You can try Ultimate for free without any obligation or payment details."
+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 ""
@@ -16770,7 +17032,7 @@ msgstr ""
msgid "GitLabPages|When enabled, all attempts to visit your website through HTTP are automatically redirected to HTTPS using a response with status code 301. Requires a valid certificate for all domains. %{docs_link_start}Learn more.%{link_end}"
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. %{docs_link_start}Learn more.%{link_end}"
+msgid "GitLabPages|When using Pages under the general domain of a GitLab instance (%{pages_host}), you cannot use HTTPS with subdomains of subdomains. If your namespace or groupname contains a dot, it does not work. This is a limitation of the HTTP Over TLS protocol. HTTP pages work if you don't redirect HTTP to HTTPS. %{docs_link_start}Learn more.%{link_end}"
msgstr ""
msgid "GitLabPages|With GitLab Pages you can host your static website directly from your GitLab repository. %{docs_link_start}Learn more.%{link_end}"
@@ -16947,9 +17209,6 @@ msgstr ""
msgid "Go to find file"
msgstr ""
-msgid "Go to fork"
-msgstr ""
-
msgid "Go to issue boards"
msgstr ""
@@ -17157,9 +17416,6 @@ msgstr ""
msgid "Group Hooks"
msgstr ""
-msgid "Group ID"
-msgstr ""
-
msgid "Group Owner must have signed in with SAML before enabling Group Managed Accounts"
msgstr ""
@@ -17187,9 +17443,6 @@ msgstr ""
msgid "Group by"
msgstr ""
-msgid "Group description"
-msgstr ""
-
msgid "Group description (optional)"
msgstr ""
@@ -17304,7 +17557,7 @@ msgstr ""
msgid "Group: %{name}"
msgstr ""
-msgid "GroupActivityMetrics|Issues opened"
+msgid "GroupActivityMetrics|Issues created"
msgstr ""
msgid "GroupActivityMetrics|Last 90 days"
@@ -17313,7 +17566,7 @@ msgstr ""
msgid "GroupActivityMetrics|Members added"
msgstr ""
-msgid "GroupActivityMetrics|Merge Requests opened"
+msgid "GroupActivityMetrics|Merge Requests created"
msgstr ""
msgid "GroupActivityMetrics|Recent activity"
@@ -17604,6 +17857,9 @@ msgstr ""
msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
+msgid "GroupSettings|Choose a group path that does not start with a dash or end with a period. It can also contain alphanumeric characters and underscores."
+msgstr ""
+
msgid "GroupSettings|Compliance frameworks"
msgstr ""
@@ -17637,7 +17893,7 @@ msgstr ""
msgid "GroupSettings|If not specified at the group or instance level, the default is %{default_initial_branch_name}. Does not affect existing repositories."
msgstr ""
-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."
+msgid "GroupSettings|If the parent group's visibility is lower than the group's current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility."
msgstr ""
msgid "GroupSettings|New runners registration token has been generated!"
@@ -17754,7 +18010,10 @@ msgstr ""
msgid "Groups and projects"
msgstr ""
-msgid "Groups and subgroups"
+msgid "Groups are a great way to organize projects and people."
+msgstr ""
+
+msgid "Groups are the best way to manage projects and members."
msgstr ""
msgid "Groups to synchronize"
@@ -17865,13 +18124,16 @@ msgstr ""
msgid "GroupsTree|Are you sure you want to leave the \"%{fullName}\" group?"
msgstr ""
-msgid "GroupsTree|Edit group"
+msgid "GroupsTree|Delete"
+msgstr ""
+
+msgid "GroupsTree|Edit"
msgstr ""
msgid "GroupsTree|Failed to leave the group. Please make sure you are not the only owner."
msgstr ""
-msgid "GroupsTree|Leave this group"
+msgid "GroupsTree|Leave group"
msgstr ""
msgid "GroupsTree|Loading groups"
@@ -17883,9 +18145,57 @@ msgstr ""
msgid "GroupsTree|No groups or projects matched your search"
msgstr ""
+msgid "GroupsTree|Options"
+msgstr ""
+
msgid "GroupsTree|Search by name"
msgstr ""
+msgid "Groups|Avatar will be removed. Are you sure?"
+msgstr ""
+
+msgid "Groups|Changing group URL can have unintended side effects."
+msgstr ""
+
+msgid "Groups|Checking group URL availability..."
+msgstr ""
+
+msgid "Groups|Enter a descriptive name for your group."
+msgstr ""
+
+msgid "Groups|Group ID"
+msgstr ""
+
+msgid "Groups|Group URL"
+msgstr ""
+
+msgid "Groups|Group avatar"
+msgstr ""
+
+msgid "Groups|Group description (optional)"
+msgstr ""
+
+msgid "Groups|Group name"
+msgstr ""
+
+msgid "Groups|Group path is available."
+msgstr ""
+
+msgid "Groups|Group path is unavailable. Path has been replaced with a suggested available path."
+msgstr ""
+
+msgid "Groups|Learn more"
+msgstr ""
+
+msgid "Groups|Must start with letter, digit, emoji, or underscore. Can also contain periods, dashes, spaces, and parentheses."
+msgstr ""
+
+msgid "Groups|Remove avatar"
+msgstr ""
+
+msgid "Groups|Save changes"
+msgstr ""
+
msgid "Guideline"
msgstr ""
@@ -17895,6 +18205,9 @@ msgstr ""
msgid "HAR file path or URL"
msgstr ""
+msgid "HTTP Archive (HAR)"
+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 ""
@@ -18299,6 +18612,9 @@ msgstr ""
msgid "INFO: Your SSH key is expiring soon. Please generate a new key."
msgstr ""
+msgid "IP"
+msgstr ""
+
msgid "IP Address"
msgstr ""
@@ -18335,6 +18651,9 @@ msgstr ""
msgid "IdentityVerification|Verify your identity"
msgstr ""
+msgid "IdentityVerification|You can always verify your account at a later time to create a group."
+msgstr ""
+
msgid "If any indexed field exceeds this limit, it is truncated to this number of characters. The rest of the content is neither indexed nor searchable. This does not apply to repository and wiki indexing. For unlimited characters, set this to 0."
msgstr ""
@@ -18392,6 +18711,9 @@ msgstr ""
msgid "If you add %{codeStart}needs%{codeEnd} to jobs in your pipeline you'll be able to view the %{codeStart}needs%{codeEnd} relationships between jobs in this tab as a %{linkStart}Directed Acyclic Graph (DAG)%{linkEnd}."
msgstr ""
+msgid "If you are added to a project, it will be displayed here."
+msgstr ""
+
msgid "If you did not initiate these sign-in attempts, please reach out to your administrator or enable two-factor authentication (2FA) on your account."
msgstr ""
@@ -18704,12 +19026,24 @@ msgstr ""
msgid "InProductMarketing|3 ways to dive into GitLab CI/CD"
msgstr ""
+msgid "InProductMarketing|A single application eliminates complex integrations, data chokepoints, and toolchain maintenance, resulting in greater productivity and lower cost."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features, build more efficiently, strengthen security and compliance."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features."
+msgstr ""
+
msgid "InProductMarketing|Actually, GitLab makes the team work (better)"
msgstr ""
msgid "InProductMarketing|And finally %{deploy_link} a Python application."
msgstr ""
+msgid "InProductMarketing|And many more..."
+msgstr ""
+
msgid "InProductMarketing|Are your runners ready?"
msgstr ""
@@ -18728,15 +19062,33 @@ msgstr ""
msgid "InProductMarketing|Blog"
msgstr ""
+msgid "InProductMarketing|Break down silos to coordinate seamlessly across development, operations, and security with a consistent experience across the development lifecycle."
+msgstr ""
+
+msgid "InProductMarketing|Burn up/down charts"
+msgstr ""
+
msgid "InProductMarketing|By enabling code owners and required merge approvals the right person will review the right MR. This is a win-win: cleaner code and a more efficient review process."
msgstr ""
msgid "InProductMarketing|Click on the number below that corresponds with your answer — 1 being very difficult, 5 being very easy."
msgstr ""
+msgid "InProductMarketing|Code owners"
+msgstr ""
+
msgid "InProductMarketing|Code owners and required merge approvals are part of the paid tiers of GitLab. You can start a free 30-day trial of GitLab Ultimate and enable these features in less than 5 minutes with no credit card required."
msgstr ""
+msgid "InProductMarketing|Code review analytics"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration across stages in GitLab"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration made easy"
+msgstr ""
+
msgid "InProductMarketing|Create a custom CI runner with just a few clicks"
msgstr ""
@@ -18746,12 +19098,21 @@ msgstr ""
msgid "InProductMarketing|Create a project in GitLab in 5 minutes"
msgstr ""
+msgid "InProductMarketing|Create well-defined workflows by using scoped labels on issues, merge requests, and epics. Labels with the same scope cannot be used together, which prevents conflicts."
+msgstr ""
+
msgid "InProductMarketing|Create your first project!"
msgstr ""
+msgid "InProductMarketing|Define who owns specific files or directories, so the right reviewers are suggested when a merge request introduces changes to those files."
+msgstr ""
+
msgid "InProductMarketing|Deliver Better Products Faster"
msgstr ""
+msgid "InProductMarketing|Dependency scanning"
+msgstr ""
+
msgid "InProductMarketing|Did you know teams that use GitLab are far more efficient?"
msgstr ""
@@ -18761,15 +19122,27 @@ msgstr ""
msgid "InProductMarketing|Dig in and create a project and a repo"
msgstr ""
+msgid "InProductMarketing|Discover Premium & Ultimate"
+msgstr ""
+
+msgid "InProductMarketing|Discover Premium & Ultimate."
+msgstr ""
+
msgid "InProductMarketing|Do you have a minute?"
msgstr ""
msgid "InProductMarketing|Do you have a teammate who would be perfect for this task?"
msgstr ""
+msgid "InProductMarketing|Dynamic application security testing"
+msgstr ""
+
msgid "InProductMarketing|Easy"
msgstr ""
+msgid "InProductMarketing|Epics"
+msgstr ""
+
msgid "InProductMarketing|Expand your DevOps journey with a free GitLab trial"
msgstr ""
@@ -18791,9 +19164,15 @@ msgstr ""
msgid "InProductMarketing|Feel the need for speed?"
msgstr ""
+msgid "InProductMarketing|Find and fix bottlenecks in your code review process by understanding how long open merge requests have been in review."
+msgstr ""
+
msgid "InProductMarketing|Find out how your teams are really doing"
msgstr ""
+msgid "InProductMarketing|Find out if your external libraries are safe. Run dependency scanning jobs that check for known vulnerabilities in your external libraries."
+msgstr ""
+
msgid "InProductMarketing|Follow our steps"
msgstr ""
@@ -18830,6 +19209,9 @@ msgstr ""
msgid "InProductMarketing|GitLab is better with teammates to help out!"
msgstr ""
+msgid "InProductMarketing|GitLab is infrastructure agnostic (supporting GCP, AWS, Azure, OpenShift, VMWare, On Prem, Bare Metal, and more), offering a consistent workflow experience – irrespective of the environment."
+msgstr ""
+
msgid "InProductMarketing|GitLab provides static application security testing (SAST), dynamic application security testing (DAST), container scanning, and dependency scanning to help you deliver secure applications along with license compliance."
msgstr ""
@@ -18920,21 +19302,36 @@ msgstr ""
msgid "InProductMarketing|It's also possible to simply %{external_repo_link} in order to take advantage of GitLab's CI/CD."
msgstr ""
+msgid "InProductMarketing|Keep your code quality high by defining who should approve merge requests and how many approvals are required."
+msgstr ""
+
msgid "InProductMarketing|Launch GitLab CI/CD in 20 minutes or less"
msgstr ""
+msgid "InProductMarketing|Lower cost of development"
+msgstr ""
+
+msgid "InProductMarketing|Make it easier to collaborate on high-level ideas by grouping related issues in an epic."
+msgstr ""
+
msgid "InProductMarketing|Making the switch? It's easier than you think to import your projects into GitLab. Move %{github_link}, or import something %{bitbucket_link}."
msgstr ""
msgid "InProductMarketing|Master the art of importing!"
msgstr ""
+msgid "InProductMarketing|Merge request approval rule"
+msgstr ""
+
msgid "InProductMarketing|Move on to easily creating a Pages website %{ci_template_link}"
msgstr ""
msgid "InProductMarketing|Multiple owners, confusing workstreams? We've got you covered"
msgstr ""
+msgid "InProductMarketing|Multiple required approvers"
+msgstr ""
+
msgid "InProductMarketing|Need an alternative to importing?"
msgstr ""
@@ -18947,18 +19344,33 @@ msgstr ""
msgid "InProductMarketing|Our tool brings all the things together"
msgstr ""
+msgid "InProductMarketing|Protect your web application by using DAST to examine for vulnerabilities in deployed environments."
+msgstr ""
+
msgid "InProductMarketing|Rapid development, simplified"
msgstr ""
msgid "InProductMarketing|Reduce Security & Compliance Risk"
msgstr ""
+msgid "InProductMarketing|Require multiple approvers on a merge request, so you know it's in good shape before it's merged."
+msgstr ""
+
+msgid "InProductMarketing|Roadmaps"
+msgstr ""
+
+msgid "InProductMarketing|Scoped labels"
+msgstr ""
+
msgid "InProductMarketing|Security that's integrated into your development lifecycle"
msgstr ""
msgid "InProductMarketing|Sometimes you're not ready to make a full transition to a new tool. If you're not ready to fully commit, %{mirroring_link} gives you a safe way to try out GitLab in parallel with your current tool."
msgstr ""
+msgid "InProductMarketing|Speed. Efficiency. Trust."
+msgstr ""
+
msgid "InProductMarketing|Spin up an autoscaling runner in GitLab"
msgstr ""
@@ -18968,6 +19380,9 @@ msgstr ""
msgid "InProductMarketing|Start a Self-Managed trial"
msgstr ""
+msgid "InProductMarketing|Start a free trial"
+msgstr ""
+
msgid "InProductMarketing|Start a free trial of GitLab Ultimate – no credit card required"
msgstr ""
@@ -19034,6 +19449,9 @@ msgstr ""
msgid "InProductMarketing|To understand and get the most out of GitLab, start at the beginning and %{project_link}. In GitLab, repositories are part of a project, so after you've created your project you can go ahead and %{repo_link}."
msgstr ""
+msgid "InProductMarketing|Track completed issues in a chart, so you can see how a milestone is progressing at a glance."
+msgstr ""
+
msgid "InProductMarketing|Try GitLab Ultimate for free"
msgstr ""
@@ -19070,6 +19488,9 @@ msgstr ""
msgid "InProductMarketing|Very easy"
msgstr ""
+msgid "InProductMarketing|Visualize your epics and milestones in a timeline."
+msgstr ""
+
msgid "InProductMarketing|Want to host GitLab on your servers?"
msgstr ""
@@ -19091,6 +19512,9 @@ msgstr ""
msgid "InProductMarketing|YouTube"
msgstr ""
+msgid "InProductMarketing|Your software, deployed your way"
+msgstr ""
+
msgid "InProductMarketing|Your teams can be more efficient"
msgstr ""
@@ -19211,9 +19635,18 @@ msgstr ""
msgid "IncidentManagement|No incidents to display."
msgstr ""
+msgid "IncidentManagement|None"
+msgstr ""
+
msgid "IncidentManagement|Open"
msgstr ""
+msgid "IncidentManagement|Page your team with escalation policies"
+msgstr ""
+
+msgid "IncidentManagement|Paged"
+msgstr ""
+
msgid "IncidentManagement|Published"
msgstr ""
@@ -19223,6 +19656,9 @@ msgstr ""
msgid "IncidentManagement|Severity"
msgstr ""
+msgid "IncidentManagement|Status"
+msgstr ""
+
msgid "IncidentManagement|There are no closed incidents"
msgstr ""
@@ -19241,6 +19677,9 @@ msgstr ""
msgid "IncidentManagement|Unpublished"
msgstr ""
+msgid "IncidentManagement|Use escalation policies to automatically page your team when incidents are created."
+msgstr ""
+
msgid "IncidentSettings|Activate \"time to SLA\" countdown timer"
msgstr ""
@@ -19286,7 +19725,10 @@ msgstr ""
msgid "Incidents"
msgstr ""
-msgid "Incidents|Add a URL"
+msgid "Incidents|Add image details"
+msgstr ""
+
+msgid "Incidents|Add text or a link to display with your image. If you don't add either, the file name displays instead."
msgstr ""
msgid "Incidents|Drop or %{linkStart}upload%{linkEnd} a metric screenshot to attach it to the incident"
@@ -19301,10 +19743,10 @@ msgstr ""
msgid "Incidents|There was an issue loading metric images."
msgstr ""
-msgid "Incidents|There was an issue uploading your image."
+msgid "Incidents|There was an issue updating your image."
msgstr ""
-msgid "Incidents|You can optionally add a URL to link users to the original graph."
+msgid "Incidents|There was an issue uploading your image."
msgstr ""
msgid "Incident|Alert details"
@@ -19313,9 +19755,18 @@ msgstr ""
msgid "Incident|Are you sure you wish to delete this image?"
msgstr ""
+msgid "Incident|Delete image"
+msgstr ""
+
msgid "Incident|Deleting %{filename}"
msgstr ""
+msgid "Incident|Edit image text or link"
+msgstr ""
+
+msgid "Incident|Editing %{filename}"
+msgstr ""
+
msgid "Incident|Metrics"
msgstr ""
@@ -19587,12 +20038,18 @@ msgstr ""
msgid "Integrations|Branches for which notifications are to be sent"
msgstr ""
+msgid "Integrations|Clear if using a self-signed certificate."
+msgstr ""
+
msgid "Integrations|Comment detail:"
msgstr ""
msgid "Integrations|Comment settings:"
msgstr ""
+msgid "Integrations|Connection details"
+msgstr ""
+
msgid "Integrations|Connection failed. Please check your settings."
msgstr ""
@@ -19617,6 +20074,9 @@ msgstr ""
msgid "Integrations|Enable GitLab.com slash commands in a Slack workspace."
msgstr ""
+msgid "Integrations|Enable SSL verification"
+msgstr ""
+
msgid "Integrations|Enable comments"
msgstr ""
@@ -19695,6 +20155,9 @@ msgstr ""
msgid "Integrations|Return to GitLab for Jira"
msgstr ""
+msgid "Integrations|SSL verification"
+msgstr ""
+
msgid "Integrations|Save settings?"
msgstr ""
@@ -19740,9 +20203,6 @@ msgstr ""
msgid "Integrations|Use default settings"
msgstr ""
-msgid "Integrations|When you mention a Jira issue in a commit or merge request, GitLab creates a remote link and comment (if enabled)."
-msgstr ""
-
msgid "Integrations|You can now close this window and return to the GitLab for Jira application."
msgstr ""
@@ -19767,9 +20227,6 @@ msgstr ""
msgid "Integrations|can't exceed %{recipients_limit}"
msgstr ""
-msgid "Interactive developer security education."
-msgstr ""
-
msgid "Interactive mode"
msgstr ""
@@ -20259,6 +20716,9 @@ msgstr ""
msgid "IssueAnalytics|Assignees"
msgstr ""
+msgid "IssueAnalytics|Created by"
+msgstr ""
+
msgid "IssueAnalytics|Due date"
msgstr ""
@@ -20271,9 +20731,6 @@ msgstr ""
msgid "IssueAnalytics|Milestone"
msgstr ""
-msgid "IssueAnalytics|Opened by"
-msgstr ""
-
msgid "IssueAnalytics|Status"
msgstr ""
@@ -20397,10 +20854,10 @@ msgstr ""
msgid "IssuesAnalytics|Avg/Month:"
msgstr ""
-msgid "IssuesAnalytics|Issues opened"
+msgid "IssuesAnalytics|Issues created"
msgstr ""
-msgid "IssuesAnalytics|Issues opened per month"
+msgid "IssuesAnalytics|Issues created per month"
msgstr ""
msgid "IssuesAnalytics|Last 12 months"
@@ -20427,6 +20884,9 @@ msgstr ""
msgid "It looks like you have some draft commits in this branch."
msgstr ""
+msgid "It looks like you're attempting to activate your subscription. Use %{a_start}the Subscription page%{a_end} instead."
+msgstr ""
+
msgid "It may be several days before you see feature usage data."
msgstr ""
@@ -20655,6 +21115,9 @@ msgstr ""
msgid "JiraConnect|You can now close this window and return to Jira."
msgstr ""
+msgid "JiraConnect|You don't have permission to create branches for this project. Select a different project or contact the project owner for access. %{linkStart}Learn more.%{linkEnd}"
+msgstr ""
+
msgid "JiraRequest|A connection error occurred while connecting to Jira. Try your request again."
msgstr ""
@@ -20703,13 +21166,13 @@ msgstr ""
msgid "JiraService|Define the type of Jira issue to create from a vulnerability."
msgstr ""
-msgid "JiraService|Displaying Jira issues while leaving the GitLab issue functionality enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
+msgid "JiraService|Displaying Jira issues while leaving GitLab issues also enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
msgstr ""
-msgid "JiraService|Enable Jira issues"
+msgid "JiraService|Enable Jira issue creation from vulnerabilities"
msgstr ""
-msgid "JiraService|Enable Jira issues creation from vulnerabilities"
+msgid "JiraService|Enable Jira issues"
msgstr ""
msgid "JiraService|Enable Jira transitions"
@@ -20826,16 +21289,19 @@ msgstr ""
msgid "JiraService|View Jira issues in GitLab"
msgstr ""
-msgid "JiraService|Warning: All GitLab users that have access to this GitLab project are able to view all issues from the Jira project specified below."
+msgid "JiraService|Warning: All GitLab users with access to this GitLab project can view all issues from the Jira project you select."
msgstr ""
msgid "JiraService|Web URL"
msgstr ""
-msgid "JiraService|Work on Jira issues without leaving GitLab. Adds a Jira menu to access your list of Jira issues and view any issue as read-only."
+msgid "JiraService|When a Jira issue is mentioned in a commit or merge request, a remote link and comment (if enabled) will be created."
+msgstr ""
+
+msgid "JiraService|Work on Jira issues without leaving GitLab. Add a Jira menu to access a read-only list of your Jira issues."
msgstr ""
-msgid "JiraService|You need to configure Jira before enabling this integration. For more details, read the %{jira_doc_link_start}Jira integration documentation%{link_end}."
+msgid "JiraService|You must configure Jira before enabling this integration. %{jira_doc_link_start}Learn more.%{link_end}"
msgstr ""
msgid "Job"
@@ -20847,9 +21313,6 @@ msgstr ""
msgid "Job Failed #%{build_id}"
msgstr ""
-msgid "Job ID"
-msgstr ""
-
msgid "Job artifact"
msgstr ""
@@ -20916,9 +21379,27 @@ msgstr ""
msgid "Jobs|You're about to retry a job that failed because it attempted to deploy code that is older than the latest deployment. Retrying this job could result in overwriting the environment with the older source code."
msgstr ""
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source} into %{target}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{ref}"
+msgstr ""
+
+msgid "Job|Are you sure you want to erase this job log and artifacts?"
+msgstr ""
+
msgid "Job|Browse"
msgstr ""
+msgid "Job|Cancel"
+msgstr ""
+
msgid "Job|Complete Raw"
msgstr ""
@@ -20928,6 +21409,9 @@ msgstr ""
msgid "Job|Erase job log and artifacts"
msgstr ""
+msgid "Job|Finished at"
+msgstr ""
+
msgid "Job|Job artifacts"
msgstr ""
@@ -20940,7 +21424,7 @@ msgstr ""
msgid "Job|Keep"
msgstr ""
-msgid "Job|Pipeline"
+msgid "Job|Retry"
msgstr ""
msgid "Job|Scroll to bottom"
@@ -20952,6 +21436,9 @@ msgstr ""
msgid "Job|Show complete raw"
msgstr ""
+msgid "Job|Status"
+msgstr ""
+
msgid "Job|The artifacts were removed"
msgstr ""
@@ -20979,21 +21466,12 @@ msgstr ""
msgid "Job|delayed"
msgstr ""
-msgid "Job|for"
-msgstr ""
-
-msgid "Job|into"
-msgstr ""
-
msgid "Job|manual"
msgstr ""
msgid "Job|triggered"
msgstr ""
-msgid "Job|with"
-msgstr ""
-
msgid "Join Zoom meeting"
msgstr ""
@@ -21096,9 +21574,6 @@ msgstr ""
msgid "Ki"
msgstr ""
-msgid "Kontra"
-msgstr ""
-
msgid "Kroki"
msgstr ""
@@ -21424,6 +21899,9 @@ msgstr ""
msgid "Learn more about Auto DevOps"
msgstr ""
+msgid "Learn more about GitLab"
+msgstr ""
+
msgid "Learn more about Needs relationships"
msgstr ""
@@ -21763,9 +22241,18 @@ msgstr ""
msgid "Licenses|Displays licenses detected in the project, based on the %{linkStart}latest successful%{linkEnd} scan"
msgstr ""
+msgid "Licenses|Drag your license file here or %{linkStart}click to upload%{linkEnd}."
+msgstr ""
+
+msgid "Licenses|Drop your license file to start the upload."
+msgstr ""
+
msgid "Licenses|Error fetching the license list. Please check your network connection and try again."
msgstr ""
+msgid "Licenses|Error: You are trying to upload something other than a file"
+msgstr ""
+
msgid "Licenses|License Compliance"
msgstr ""
@@ -21784,6 +22271,9 @@ msgstr ""
msgid "Licenses|Specified policies in this project"
msgstr ""
+msgid "Licenses|The file could not be uploaded."
+msgstr ""
+
msgid "Licenses|The license list details information about the licenses used within your project."
msgstr ""
@@ -21817,13 +22307,6 @@ msgstr ""
msgid "Limit the size of Sidekiq jobs stored in Redis."
msgstr ""
-msgid "Limited to showing %d event at most"
-msgid_plural "Limited to showing %d events at most"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-msgstr[3] ""
-
msgid "Limiting mode"
msgstr ""
@@ -21833,6 +22316,9 @@ msgstr ""
msgid "Link"
msgstr ""
+msgid "Link (optional)"
+msgstr ""
+
msgid "Link Prometheus monitoring to GitLab."
msgstr ""
@@ -21869,6 +22355,9 @@ msgstr ""
msgid "Linked emails (%{email_count})"
msgstr ""
+msgid "Linked epics"
+msgstr ""
+
msgid "Linked issues"
msgstr ""
@@ -21896,6 +22385,15 @@ msgstr ""
msgid "List of all merge commits"
msgstr ""
+msgid "List of environments for this project"
+msgstr ""
+
+msgid "List of suitable GCP locations"
+msgstr ""
+
+msgid "List of users allowed to exceed the rate limit."
+msgstr ""
+
msgid "List options"
msgstr ""
@@ -22115,6 +22613,9 @@ msgstr ""
msgid "Maintenance mode"
msgstr ""
+msgid "Make adjustments to how your GitLab instance is set up."
+msgstr ""
+
msgid "Make and review changes in the browser with the Web IDE"
msgstr ""
@@ -22259,6 +22760,12 @@ msgstr ""
msgid "MarkdownEditor|Add italic text (%{modifier_key}I)"
msgstr ""
+msgid "MarkdownEditor|Add strikethrough text (%{modifierKey}⇧X)"
+msgstr ""
+
+msgid "MarkdownEditor|Add strikethrough text (%{modifier_key}⇧X)"
+msgstr ""
+
msgid "Marked For Deletion At - %{deletion_time}"
msgstr ""
@@ -22520,6 +23027,9 @@ msgstr ""
msgid "Maximum push size (MB)"
msgstr ""
+msgid "Maximum requests per 10 minutes per user"
+msgstr ""
+
msgid "Maximum requests per minute"
msgstr ""
@@ -22610,6 +23120,23 @@ msgstr ""
msgid "Members of a group may only view projects they have permission to access"
msgstr ""
+msgid "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seat in use and will be billed for the overage."
+msgid_plural "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seats in use and will be billed for the overage."
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
+msgid "MembersOverage|You are about to incur additional charges"
+msgstr ""
+
+msgid "MembersOverage|Your subscription includes %d seat."
+msgid_plural "MembersOverage|Your subscription includes %d seats."
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "Membership"
msgstr ""
@@ -22814,9 +23341,6 @@ msgstr ""
msgid "Merge request not merged"
msgstr ""
-msgid "Merge request pipelines 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 merge request pipelines."
-msgstr ""
-
msgid "Merge request reports"
msgstr ""
@@ -22913,13 +23437,13 @@ msgstr ""
msgid "MergeRequests|Create issue to resolve thread"
msgstr ""
-msgid "MergeRequests|Failed to squash. Should be done manually."
+msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Saving the comment failed"
+msgid "MergeRequests|Squashing failed: Squash the commits locally, resolve any conflicts, then push the branch."
msgstr ""
-msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
+msgid "MergeRequests|Squashing not allowed: This project doesn't allow you to squash commits when merging."
msgstr ""
msgid "MergeRequests|Thread stays resolved"
@@ -23764,6 +24288,18 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "MrList|Assigned to %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from assignee %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from reviewer %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Review requested from %{name}, go to their profile."
+msgstr ""
+
msgid "Multi-project"
msgstr ""
@@ -23797,7 +24333,7 @@ msgstr ""
msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "My Awesome Group"
+msgid "My awesome group"
msgstr ""
msgid "My company or team"
@@ -24423,9 +24959,6 @@ msgstr ""
msgid "No available branches"
msgstr ""
-msgid "No available groups to fork the project."
-msgstr ""
-
msgid "No branches found"
msgstr ""
@@ -24636,6 +25169,9 @@ msgstr ""
msgid "No ref selected"
msgstr ""
+msgid "No regions configured"
+msgstr ""
+
msgid "No related merge requests found."
msgstr ""
@@ -25452,6 +25988,9 @@ msgstr ""
msgid "Only reCAPTCHA v2 is supported:"
msgstr ""
+msgid "Only required if not using role instance credentials."
+msgstr ""
+
msgid "Only use lowercase letters, numbers, and underscores."
msgstr ""
@@ -25476,9 +26015,6 @@ msgstr ""
msgid "Open a CLI and connect to the cluster you want to install the agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
-msgid "Open epics"
-msgstr ""
-
msgid "Open errors"
msgstr ""
@@ -25518,7 +26054,7 @@ msgstr ""
msgid "Opened issues"
msgstr ""
-msgid "OpenedNDaysAgo|Opened"
+msgid "OpenedNDaysAgo|Created"
msgstr ""
msgid "Opens in a new window"
@@ -25563,9 +26099,6 @@ msgstr ""
msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
-msgid "Optional."
-msgstr ""
-
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
msgstr ""
@@ -26356,6 +26889,9 @@ msgstr ""
msgid "PerformanceBar|Memory"
msgstr ""
+msgid "PerformanceBar|Memory report"
+msgstr ""
+
msgid "PerformanceBar|Redis calls"
msgstr ""
@@ -26389,18 +26925,12 @@ msgstr ""
msgid "PerformanceBar|wall"
msgstr ""
-msgid "Performs a rebase but skips triggering a new pipeline"
-msgstr ""
-
msgid "Period in seconds"
msgstr ""
msgid "Permalink"
msgstr ""
-msgid "Permanently delete project"
-msgstr ""
-
msgid "Permanently remove group"
msgstr ""
@@ -26671,6 +27201,51 @@ msgstr ""
msgid "PipelineStatusTooltip|Pipeline: %{ci_status}"
msgstr ""
+msgid "PipelineWizardDefaultCommitMessage|Add %{filename}"
+msgstr ""
+
+msgid "PipelineWizardDefaultCommitMessage|Update %{filename}"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|At least one entry is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This field is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This value is not valid"
+msgstr ""
+
+msgid "PipelineWizardListWidget|add another step"
+msgstr ""
+
+msgid "PipelineWizardListWidget|remove step"
+msgstr ""
+
+msgid "PipelineWizard|Commit"
+msgstr ""
+
+msgid "PipelineWizard|Commit Message"
+msgstr ""
+
+msgid "PipelineWizard|Commit changes to your file"
+msgstr ""
+
+msgid "PipelineWizard|Commit file to Branch"
+msgstr ""
+
+msgid "PipelineWizard|Commit your new file"
+msgstr ""
+
+msgid "PipelineWizard|The file has been committed."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem committing the changes."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem while checking whether your file already exists in the specified branch."
+msgstr ""
+
msgid "Pipelines"
msgstr ""
@@ -26785,7 +27360,7 @@ msgstr ""
msgid "Pipelines|Project cache successfully reset."
msgstr ""
-msgid "Pipelines|Revoke"
+msgid "Pipelines|Revoke trigger"
msgstr ""
msgid "Pipelines|Something went wrong while cleaning runners cache."
@@ -26830,6 +27405,12 @@ msgstr ""
msgid "Pipelines|This is a child pipeline within the parent pipeline"
msgstr ""
+msgid "Pipelines|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipelines|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipelines|This pipeline will run code originating from a forked project merge request. This means that the code can potentially have security considerations like exposing CI variables."
msgstr ""
@@ -26872,9 +27453,6 @@ msgstr ""
msgid "Pipelines|Your changes have been successfully committed. Now redirecting to the new merge request page."
msgstr ""
-msgid "Pipelines|detached"
-msgstr ""
-
msgid "Pipelines|error"
msgstr ""
@@ -26884,10 +27462,13 @@ msgstr ""
msgid "Pipelines|latest"
msgstr ""
-msgid "Pipelines|stuck"
+msgid "Pipelines|merge request"
msgstr ""
-msgid "Pipelines|train"
+msgid "Pipelines|merge train"
+msgstr ""
+
+msgid "Pipelines|stuck"
msgstr ""
msgid "Pipelines|yaml invalid"
@@ -27019,6 +27600,12 @@ msgstr ""
msgid "Pipeline|This change will not change the overall test coverage if merged."
msgstr ""
+msgid "Pipeline|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipeline|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipeline|Trigger author"
msgstr ""
@@ -27043,6 +27630,12 @@ msgstr ""
msgid "Pipeline|for"
msgstr ""
+msgid "Pipeline|merge request"
+msgstr ""
+
+msgid "Pipeline|merge train"
+msgstr ""
+
msgid "Pipeline|on"
msgstr ""
@@ -27181,9 +27774,6 @@ msgstr ""
msgid "Please enter a valid time interval"
msgstr ""
-msgid "Please enter or upload a valid license."
-msgstr ""
-
msgid "Please enter your current password."
msgstr ""
@@ -27292,9 +27882,6 @@ msgstr ""
msgid "Please type %{phrase_code} to proceed or close this modal to cancel."
msgstr ""
-msgid "Please type the following to confirm:"
-msgstr ""
-
msgid "Please use this form to report to the admin users who create spam issues, comments or behave inappropriately."
msgstr ""
@@ -27322,12 +27909,27 @@ msgstr ""
msgid "Policies"
msgstr ""
+msgid "Policy '%{escalation_policy_name}' does not exist."
+msgstr ""
+
msgid "Policy management project does have any policies in %{policy_path}"
msgstr ""
msgid "Policy project doesn't exist"
msgstr ""
+msgid "PolicyRuleMultiSelect|%{firstLabel} +%{numberOfAdditionalLabels} more"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|All %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select all"
+msgstr ""
+
msgid "Polling interval multiplier"
msgstr ""
@@ -27556,6 +28158,9 @@ msgstr ""
msgid "Private projects can be created in your personal namespace with:"
msgstr ""
+msgid "Problem with %{name} command: %{message}."
+msgstr ""
+
msgid "Proceed"
msgstr ""
@@ -28030,6 +28635,9 @@ msgstr ""
msgid "Progress"
msgstr ""
+msgid "Progress tracking"
+msgstr ""
+
msgid "Project"
msgstr ""
@@ -28261,6 +28869,9 @@ msgstr ""
msgid "ProjectQualitySummary|Failure"
msgstr ""
+msgid "ProjectQualitySummary|Get insight into the overall percentage of tests in your project that succeed, fail and are skipped."
+msgstr ""
+
msgid "ProjectQualitySummary|Latest pipeline results"
msgstr ""
@@ -28279,6 +28890,12 @@ msgstr ""
msgid "ProjectQualitySummary|See project Code Coverage Statistics"
msgstr ""
+msgid "ProjectQualitySummary|Set up test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|Set up test runs (opens in a new tab)"
+msgstr ""
+
msgid "ProjectQualitySummary|Skipped"
msgstr ""
@@ -28555,13 +29172,19 @@ msgstr ""
msgid "ProjectSettings|LFS objects from this repository are available to forks. %{linkStart}How do I remove them?%{linkEnd}"
msgstr ""
+msgid "ProjectSettings|Learn about commit history."
+msgstr ""
+
+msgid "ProjectSettings|Leave empty to use default template."
+msgstr ""
+
msgid "ProjectSettings|Manage who can see the project in the public access directory."
msgstr ""
msgid "ProjectSettings|Manages large files such as audio, video, and graphics files."
msgstr ""
-msgid "ProjectSettings|Maximum 500 characters."
+msgid "ProjectSettings|Maximum %{maxLength} characters."
msgstr ""
msgid "ProjectSettings|Merge checks"
@@ -28702,6 +29325,9 @@ msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
msgstr ""
+msgid "ProjectSettings|The default template will be applied on save."
+msgstr ""
+
msgid "ProjectSettings|These checks must pass before merge requests can be merged."
msgstr ""
@@ -28756,6 +29382,9 @@ msgstr ""
msgid "ProjectSettings|What are badges?"
msgstr ""
+msgid "ProjectSettings|What are merge trains?"
+msgstr ""
+
msgid "ProjectSettings|When merge request pipelines are enabled in the CI/CD configuration file, pipelines validate the combined results of the source and target branches. %{link_start}How to configure merge request pipelines?%{link_end}"
msgstr ""
@@ -28873,6 +29502,9 @@ msgstr ""
msgid "Projects are organized into groups"
msgstr ""
+msgid "Projects are where you store your code, access issues, wiki and other features of GitLab."
+msgstr ""
+
msgid "Projects contributed to"
msgstr ""
@@ -28888,12 +29520,6 @@ msgstr ""
msgid "Projects to index"
msgstr ""
-msgid "Projects will be permanently deleted after a %{waiting_period}-day waiting period."
-msgstr ""
-
-msgid "Projects will be permanently deleted immediately."
-msgstr ""
-
msgid "Projects with critical vulnerabilities"
msgstr ""
@@ -28978,6 +29604,9 @@ msgstr ""
msgid "ProjectsNew|Import project"
msgstr ""
+msgid "ProjectsNew|Include a Getting Started README"
+msgstr ""
+
msgid "ProjectsNew|Initialize repository with a README"
msgstr ""
@@ -28993,6 +29622,9 @@ msgstr ""
msgid "ProjectsNew|Project description %{tag_start}(optional)%{tag_end}"
msgstr ""
+msgid "ProjectsNew|Recommended if you're new to GitLab"
+msgstr ""
+
msgid "ProjectsNew|Run CI/CD for external repository"
msgstr ""
@@ -29410,6 +30042,9 @@ msgstr ""
msgid "ProtectedBranch|Unprotect"
msgstr ""
+msgid "ProtectedBranch|Unprotect branch"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
@@ -29437,6 +30072,9 @@ msgstr ""
msgid "ProtectedEnvironment|Protected Environment (%{protected_environments_count})"
msgstr ""
+msgid "ProtectedEnvironment|Required approvals"
+msgstr ""
+
msgid "ProtectedEnvironment|Select an environment"
msgstr ""
@@ -29458,10 +30096,13 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|Unprotect tag"
+msgstr ""
+
msgid "ProtectedTags|default"
msgstr ""
-msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
+msgid "ProtectedTag|By default, protected tags restrict who can modify the tag."
msgstr ""
msgid "ProtectedTag|Learn more."
@@ -29524,6 +30165,9 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Public projects are an easy way to allow everyone to have read-only access."
+msgstr ""
+
msgid "Publish to status page"
msgstr ""
@@ -29680,9 +30324,6 @@ msgstr ""
msgid "QualitySummary|Project quality"
msgstr ""
-msgid "Quarters"
-msgstr ""
-
msgid "Query"
msgstr ""
@@ -29767,6 +30408,9 @@ msgstr ""
msgid "Read more about project permissions %{help_link_open}here%{help_link_close}"
msgstr ""
+msgid "Read more about related epics"
+msgstr ""
+
msgid "Read more about related issues"
msgstr ""
@@ -29797,10 +30441,7 @@ msgstr ""
msgid "Rebase source branch on the target branch."
msgstr ""
-msgid "Rebase without CI"
-msgstr ""
-
-msgid "Rebases and triggers a pipeline"
+msgid "Rebase without pipeline"
msgstr ""
msgid "Recaptcha verified?"
@@ -29851,9 +30492,6 @@ msgstr ""
msgid "Reconfigure"
msgstr ""
-msgid "Recovering projects"
-msgstr ""
-
msgid "Recovery Codes"
msgstr ""
@@ -29915,6 +30553,12 @@ msgstr ""
msgid "Regex pattern"
msgstr ""
+msgid "Region"
+msgstr ""
+
+msgid "Regions"
+msgstr ""
+
msgid "Register"
msgstr ""
@@ -30147,9 +30791,6 @@ msgstr ""
msgid "Remove all or specific reviewer(s)"
msgstr ""
-msgid "Remove approver"
-msgstr ""
-
msgid "Remove approvers"
msgstr ""
@@ -30165,6 +30806,9 @@ msgstr ""
msgid "Remove attention request"
msgstr ""
+msgid "Remove attention request(s)"
+msgstr ""
+
msgid "Remove avatar"
msgstr ""
@@ -30303,6 +30947,9 @@ msgstr ""
msgid "Removed an issue from an epic."
msgstr ""
+msgid "Removed attention from %{users_sentence}."
+msgstr ""
+
msgid "Removed attention request from @%{username}"
msgstr ""
@@ -30354,6 +31001,9 @@ msgstr ""
msgid "Removes an issue from an epic."
msgstr ""
+msgid "Removes attention from %{users_sentence}."
+msgstr ""
+
msgid "Removes parent epic %{epic_ref}."
msgstr ""
@@ -30465,6 +31115,9 @@ msgstr ""
msgid "Report abuse to admin"
msgstr ""
+msgid "Report is generating and will be sent to your email address."
+msgstr ""
+
msgid "Reported %{timeAgo} by %{reportedBy}"
msgstr ""
@@ -30764,6 +31417,15 @@ msgstr ""
msgid "Request attention"
msgstr ""
+msgid "Request attention from %{users_sentence}."
+msgstr ""
+
+msgid "Request attention from assignee or reviewer"
+msgstr ""
+
+msgid "Request attention from assignee(s) or reviewer(s)"
+msgstr ""
+
msgid "Request attention to review"
msgstr ""
@@ -30788,6 +31450,9 @@ msgstr ""
msgid "Requested %{time_ago}"
msgstr ""
+msgid "Requested attention from %{users_sentence}."
+msgstr ""
+
msgid "Requested attention from @%{username}"
msgstr ""
@@ -31006,6 +31671,9 @@ msgstr ""
msgid "Restore project"
msgstr ""
+msgid "Restoring projects"
+msgstr ""
+
msgid "Restoring the group will prevent the group, its subgroups and projects from being removed on this date."
msgstr ""
@@ -31036,6 +31704,9 @@ msgstr ""
msgid "Retry"
msgstr ""
+msgid "Retry failed jobs"
+msgstr ""
+
msgid "Retry job"
msgstr ""
@@ -31085,9 +31756,6 @@ msgstr ""
msgid "Review changes"
msgstr ""
-msgid "Review requested from %{name}"
-msgstr ""
-
msgid "Review requests for you"
msgstr ""
@@ -31254,6 +31922,9 @@ msgstr ""
msgid "Runners|Assigned Group"
msgstr ""
+msgid "Runners|Assigned Projects (%{projectCount})"
+msgstr ""
+
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -31323,6 +31994,9 @@ msgstr ""
msgid "Runners|Instance"
msgstr ""
+msgid "Runners|Jobs"
+msgstr ""
+
msgid "Runners|Last contact"
msgstr ""
@@ -31416,9 +32090,6 @@ msgstr ""
msgid "Runners|Runner %{name} was deleted"
msgstr ""
-msgid "Runners|Runner ID"
-msgstr ""
-
msgid "Runners|Runner assigned to project."
msgstr ""
@@ -31566,6 +32237,9 @@ msgstr ""
msgid "Runners|stale"
msgstr ""
+msgid "Runner|This runner has not run any jobs."
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -31680,6 +32354,24 @@ msgstr ""
msgid "Saving project."
msgstr ""
+msgid "ScanResultPolicy|%{ifLabelStart}if%{ifLabelEnd} %{scanners} scan in an open merge request targeting the %{branches} branch(es) finds %{vulnerabilitiesAllowed} or more %{severities} vulnerabilities that are %{vulnerabilityStates}"
+msgstr ""
+
+msgid "ScanResultPolicy|%{thenLabelStart}Then%{thenLabelEnd} Require approval from %{approvalsRequired} of the following approvers: %{approvers}"
+msgstr ""
+
+msgid "ScanResultPolicy|add an approver"
+msgstr ""
+
+msgid "ScanResultPolicy|scanners"
+msgstr ""
+
+msgid "ScanResultPolicy|severity levels"
+msgstr ""
+
+msgid "ScanResultPolicy|vulnerability states"
+msgstr ""
+
msgid "Scanner"
msgstr ""
@@ -31812,6 +32504,9 @@ msgstr ""
msgid "Search for a user"
msgstr ""
+msgid "Search for an emoji"
+msgstr ""
+
msgid "Search for projects, issues, etc."
msgstr ""
@@ -32021,18 +32716,12 @@ msgstr ""
msgid "Secret Detection"
msgstr ""
-msgid "Secret access key"
-msgstr ""
-
msgid "Secret token"
msgstr ""
msgid "Secure token that identifies an external storage request."
msgstr ""
-msgid "SecureCodeWarrior"
-msgstr ""
-
msgid "Security"
msgstr ""
@@ -32057,9 +32746,6 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "Security training with guide and learning pathways."
-msgstr ""
-
msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
@@ -32162,7 +32848,7 @@ msgstr ""
msgid "SecurityConfiguration|Manage corpus"
msgstr ""
-msgid "SecurityConfiguration|Manage corpus files used as mutation sources in coverage fuzzing."
+msgid "SecurityConfiguration|Manage corpus files used as seed inputs with coverage-guided fuzzing."
msgstr ""
msgid "SecurityConfiguration|Manage profiles for use by DAST scans."
@@ -32228,15 +32914,15 @@ msgstr ""
msgid "SecurityOrchestration|.yaml preview"
msgstr ""
-msgid "SecurityOrchestration|Action"
-msgstr ""
-
msgid "SecurityOrchestration|Actions"
msgstr ""
msgid "SecurityOrchestration|Add rule"
msgstr ""
+msgid "SecurityOrchestration|After dismissing the alert, the information will never be shown again."
+msgstr ""
+
msgid "SecurityOrchestration|All policies"
msgstr ""
@@ -32252,7 +32938,7 @@ msgstr ""
msgid "SecurityOrchestration|Description"
msgstr ""
-msgid "SecurityOrchestration|Disabled"
+msgid "SecurityOrchestration|Don't show the alert anymore"
msgstr ""
msgid "SecurityOrchestration|Edit policy"
@@ -32261,13 +32947,13 @@ msgstr ""
msgid "SecurityOrchestration|Edit policy project"
msgstr ""
-msgid "SecurityOrchestration|Enabled"
+msgid "SecurityOrchestration|Empty policy name"
msgstr ""
-msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Enabled"
msgstr ""
-msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
msgstr ""
msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
@@ -32276,7 +32962,7 @@ msgstr ""
msgid "SecurityOrchestration|Invalid policy type"
msgstr ""
-msgid "SecurityOrchestration|Latest scan"
+msgid "SecurityOrchestration|Latest scan run against %{agent}"
msgstr ""
msgid "SecurityOrchestration|Network"
@@ -32285,15 +32971,27 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No actions defined - policy will not run."
+msgstr ""
+
+msgid "SecurityOrchestration|No description"
+msgstr ""
+
msgid "SecurityOrchestration|No rules defined - policy will not run."
msgstr ""
+msgid "SecurityOrchestration|Not enabled"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
msgid "SecurityOrchestration|Policies"
msgstr ""
+msgid "SecurityOrchestration|Policy Type"
+msgstr ""
+
msgid "SecurityOrchestration|Policy cannot be enabled for non-existing branches (%{branches})"
msgstr ""
@@ -32318,10 +33016,13 @@ msgstr ""
msgid "SecurityOrchestration|Require %{approvals} %{plural} from %{approvers} if any of the following occur:"
msgstr ""
-msgid "SecurityOrchestration|Rule"
+msgid "SecurityOrchestration|Rules"
msgstr ""
-msgid "SecurityOrchestration|Rules"
+msgid "SecurityOrchestration|Runs %{actions} and %{lastAction} scans"
+msgstr ""
+
+msgid "SecurityOrchestration|Runs a %{action} scan"
msgstr ""
msgid "SecurityOrchestration|Scan Execution"
@@ -32381,6 +33082,9 @@ msgstr ""
msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
+msgid "SecurityOrchestration|This view only shows scan results for the agent %{agent}. You can view scan results for all agents in the %{linkStart}Operational Vulnerabilities tab of the vulnerability report%{linkEnd}."
+msgstr ""
+
msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
@@ -32435,9 +33139,6 @@ msgstr ""
msgid "SecurityOrchestration|users with ids"
msgstr ""
-msgid "SecurityOrchestration|view results"
-msgstr ""
-
msgid "SecurityOrchestration|vulnerabilities"
msgstr ""
@@ -33107,22 +33808,19 @@ 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|In order to start using functions as a service, you must first install Knative on your Kubernetes cluster. %{linkStart}More information%{linkEnd}"
-msgstr ""
-
msgid "Serverless|Learn more about Serverless"
msgstr ""
msgid "Serverless|No functions available"
msgstr ""
-msgid "Serverless|Sign up for First Look"
+msgid "Serverless|Serverless was %{linkStart}deprecated%{linkEnd} in GitLab 14.3."
+msgstr ""
+
+msgid "Serverless|Serverless was %{postLinkStart}deprecated%{postLinkEnd}. But if you opt to use it, you must install Knative in your Kubernetes cluster first. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "Serverless|The deploy job has not finished."
@@ -33134,9 +33832,6 @@ 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 ""
@@ -33152,9 +33847,6 @@ msgstr ""
msgid "Service Account Key"
msgstr ""
-msgid "Service Accounts"
-msgstr ""
-
msgid "Service Accounts keys authorize GitLab to deploy your Google Cloud project"
msgstr ""
@@ -33164,10 +33856,10 @@ msgstr ""
msgid "Service Desk allows people to create issues in your GitLab instance without their own user account. It provides a unique email address for end users to create issues in a project. Replies can be sent either through the GitLab interface or by email. End users only see threads through email."
msgstr ""
-msgid "Service Usage Data"
+msgid "Service account generated successfully"
msgstr ""
-msgid "Service account generated successfully"
+msgid "Service accounts"
msgstr ""
msgid "Service ping is disabled in your configuration file, and cannot be enabled through this form."
@@ -33311,6 +34003,9 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
+msgid "Set the per-user rate limit for getting a user by ID via the API."
+msgstr ""
+
msgid "Set the per-user rate limit for notes created by web or API requests."
msgstr ""
@@ -33492,6 +34187,9 @@ msgstr ""
msgid "Shared runners details"
msgstr ""
+msgid "Shared runners enabled cannot be enabled until a valid credit card is on file"
+msgstr ""
+
msgid "Shared runners help link"
msgstr ""
@@ -33549,6 +34247,9 @@ msgstr ""
msgid "Show all issues."
msgstr ""
+msgid "Show all milestones"
+msgstr ""
+
msgid "Show all test cases."
msgstr ""
@@ -33585,6 +34286,9 @@ msgstr ""
msgid "Show file contents"
msgstr ""
+msgid "Show group milestones"
+msgstr ""
+
msgid "Show labels"
msgstr ""
@@ -33600,6 +34304,12 @@ msgstr ""
msgid "Show open epics"
msgstr ""
+msgid "Show project milestones"
+msgstr ""
+
+msgid "Show sub-group milestones"
+msgstr ""
+
msgid "Show the Closed list"
msgstr ""
@@ -33609,13 +34319,6 @@ msgstr ""
msgid "Show whitespace changes"
msgstr ""
-msgid "Showing %d event"
-msgid_plural "Showing %d events"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-msgstr[3] ""
-
msgid "Showing %{conflict} between %{sourceBranch} and %{targetBranch}"
msgstr ""
@@ -33677,12 +34380,6 @@ msgstr ""
msgid "Sidebar|None"
msgstr ""
-msgid "Sidebar|Only numeral characters allowed"
-msgstr ""
-
-msgid "Sidebar|Weight"
-msgstr ""
-
msgid "Sidekiq job compression threshold (bytes)"
msgstr ""
@@ -33845,6 +34542,9 @@ msgstr ""
msgid "Slack logo"
msgstr ""
+msgid "SlackIntegration|Are you sure you want to remove this project from the Slack application?"
+msgstr ""
+
msgid "SlackIntegration|GitLab for Slack"
msgstr ""
@@ -33854,6 +34554,9 @@ msgstr ""
msgid "SlackIntegration|Project alias"
msgstr ""
+msgid "SlackIntegration|Remove project"
+msgstr ""
+
msgid "SlackIntegration|Select a GitLab project to link with your Slack workspace."
msgstr ""
@@ -33998,9 +34701,6 @@ msgstr ""
msgid "Something went wrong trying to load issue contacts."
msgstr ""
-msgid "Something went wrong when creating a work item. Please try again"
-msgstr ""
-
msgid "Something went wrong when reordering designs. Please try again"
msgstr ""
@@ -34094,9 +34794,6 @@ msgstr ""
msgid "Something went wrong while inserting your image. Please try again."
msgstr ""
-msgid "Something went wrong while merging this merge request. Please try again."
-msgstr ""
-
msgid "Something went wrong while obtaining the Let's Encrypt certificate."
msgstr ""
@@ -34418,10 +35115,10 @@ 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."
+msgid "SourcegraphAdmin|Learn more."
msgstr ""
-msgid "SourcegraphAdmin|More information"
+msgid "SourcegraphAdmin|Only public projects have code intelligence enabled and communicate with Sourcegraph."
msgstr ""
msgid "SourcegraphAdmin|Save changes"
@@ -34430,7 +35127,7 @@ msgstr ""
msgid "SourcegraphAdmin|Sourcegraph URL"
msgstr ""
-msgid "SourcegraphAdmin|e.g. https://sourcegraph.example.com"
+msgid "SourcegraphAdmin|https://sourcegraph.example.com"
msgstr ""
msgid "SourcegraphPreferences|This feature is experimental and currently limited to certain projects."
@@ -34565,6 +35262,9 @@ msgstr ""
msgid "Start date"
msgstr ""
+msgid "Start free trial"
+msgstr ""
+
msgid "Start merge train"
msgstr ""
@@ -34595,6 +35295,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started escalation for this incident."
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -34607,6 +35310,9 @@ msgstr ""
msgid "Starts at (UTC)"
msgstr ""
+msgid "Starts escalations for this incident"
+msgstr ""
+
msgid "Starts on"
msgstr ""
@@ -34868,6 +35574,9 @@ msgstr ""
msgid "Strikethrough"
msgstr ""
+msgid "Strikethrough text"
+msgstr ""
+
msgid "Subgroup information"
msgstr ""
@@ -35102,6 +35811,21 @@ msgstr ""
msgid "Subscriptions"
msgstr ""
+msgid "Subscriptions|Chat with sales"
+msgstr ""
+
+msgid "Subscriptions|Close"
+msgstr ""
+
+msgid "Subscriptions|Not ready to buy yet?"
+msgstr ""
+
+msgid "Subscriptions|Start a free trial"
+msgstr ""
+
+msgid "Subscriptions|We understand. Maybe you have some questions for our sales team, or maybe you'd like to try some of the paid features first. What would you like to do?"
+msgstr ""
+
msgid "Subscription|Your subscription for %{strong}%{namespace_name}%{strong_close} has expired and you are now on %{pricing_link_start}the GitLab Free tier%{pricing_link_end}. Don't worry, your data is safe. Get in touch with our support team (%{support_email}). They'll gladly help with your subscription renewal."
msgstr ""
@@ -35312,6 +36036,9 @@ msgstr ""
msgid "SuperSonics|Maximum users"
msgstr ""
+msgid "SuperSonics|Offline cloud"
+msgstr ""
+
msgid "SuperSonics|Paste your activation code"
msgstr ""
@@ -35378,6 +36105,12 @@ msgstr ""
msgid "SuperSonics|You do not have an active subscription"
msgstr ""
+msgid "SuperSonics|You have a future dated license"
+msgstr ""
+
+msgid "SuperSonics|You have added a license that activates on %{date}. Please see the subscription history table below for more details."
+msgstr ""
+
msgid "SuperSonics|You have successfully added a license that activates on %{date}. Please see the subscription history table below for more details."
msgstr ""
@@ -35537,6 +36270,9 @@ msgstr ""
msgid "Tag name is required"
msgstr ""
+msgid "Tag push"
+msgstr ""
+
msgid "Tag push events"
msgstr ""
@@ -35639,6 +36375,9 @@ msgstr ""
msgid "TagsPage|protected"
msgstr ""
+msgid "Take a look at the documentation to discover all of GitLab’s capabilities."
+msgstr ""
+
msgid "Target Branch"
msgstr ""
@@ -36053,6 +36792,9 @@ msgstr ""
msgid "Tests"
msgstr ""
+msgid "Text (optional)"
+msgstr ""
+
msgid "Text added to the body of all email messages. %{character_limit} character limit"
msgstr ""
@@ -36105,6 +36847,9 @@ msgstr ""
msgid "The CSV export will be created in the background. Once finished, it will be sent to %{email} in an attachment."
msgstr ""
+msgid "The CSV export you requested of all user memberships is attached to this email."
+msgstr ""
+
msgid "The GitLab subscription service (customers.gitlab.com) is currently experiencing an outage. You can monitor the status and get updates at %{linkStart}status.gitlab.com%{linkEnd}."
msgstr ""
@@ -36180,6 +36925,9 @@ 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 epic"
+msgstr ""
+
msgid "The current issue"
msgstr ""
@@ -36343,6 +37091,9 @@ msgstr ""
msgid "The latest pipeline for this merge request has failed."
msgstr ""
+msgid "The license key is invalid."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -36358,6 +37109,9 @@ msgstr ""
msgid "The license was successfully uploaded and will be active from %{starts_at}. You can see the details below."
msgstr ""
+msgid "The license you uploaded is invalid. If the issue persists, contact support at %{link}."
+msgstr ""
+
msgid "The list creation wizard is already open"
msgstr ""
@@ -36979,10 +37733,13 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} and everything this project contains. %{strongOpen}There is no going back%{strongClose}"
+msgstr ""
+
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains."
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}on %{date}%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains. %{strongOpen}There is no going back.%{strongClose}"
msgstr ""
msgid "This action will %{strongOpen}permanently remove%{strongClose} %{codeOpen}%{group}%{codeClose} %{strongOpen}immediately%{strongClose}."
@@ -37111,9 +37868,6 @@ msgstr ""
msgid "This file was modified for readability, and can't accept suggestions. Edit it directly."
msgstr ""
-msgid "This forked project has the following:"
-msgstr ""
-
msgid "This form is disabled in preview"
msgstr ""
@@ -37126,7 +37880,7 @@ msgstr ""
msgid "This group can't be removed because it is linked to a subscription. To remove this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
-msgid "This group can't be transfered because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
+msgid "This group can't be transferred because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
msgid "This group cannot be invited to a project inside a group with enforced SSO"
@@ -37153,6 +37907,9 @@ 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 incident is already escalated with '%{escalation_policy_name}'."
+msgstr ""
+
msgid "This invitation was sent to %{mail_to_invite_email}, but you are signed in as %{link_to_current_user} with email %{mail_to_current_user}."
msgstr ""
@@ -37171,9 +37928,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 merge train pipeline"
-msgstr ""
-
msgid "This is a private email address %{helpIcon} generated just for you. Anyone who has it can create issues or merge requests as if they were you. If that happens, %{resetLinkStart}reset this token%{resetLinkEnd}."
msgstr ""
@@ -37195,6 +37949,12 @@ msgstr ""
msgid "This is your current session"
msgstr ""
+msgid "This issue cannot be assigned to a confidential epic because it is public."
+msgstr ""
+
+msgid "This issue cannot be made public because it belongs to a confidential epic."
+msgstr ""
+
msgid "This issue is confidential and should only be visible to team members with at least Reporter access."
msgstr ""
@@ -37312,6 +38072,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 branch is protected from force push."
+msgstr ""
+
msgid "This merge request cannot be rebased while there are conflicts."
msgstr ""
@@ -37363,9 +38126,15 @@ msgstr ""
msgid "This pipeline was triggered by a schedule."
msgstr ""
+msgid "This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project"
msgstr ""
+msgid "This project can be restored until %{date}."
+msgstr ""
+
msgid "This project cannot be %{visibilityLevel} because the visibility of %{openShowLink}%{name}%{closeShowLink} is %{visibility}. To make this project %{visibilityLevel}, you must first %{openEditLink}change the visibility%{closeEditLink} of the parent group."
msgstr ""
@@ -37384,6 +38153,9 @@ msgstr ""
msgid "This project is %{strongStart}NOT%{strongEnd} a fork, and has the following:"
msgstr ""
+msgid "This project is %{strongStart}NOT%{strongEnd} a fork. This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -38079,6 +38851,9 @@ msgstr ""
msgid "Today"
msgstr ""
+msgid "Todos count"
+msgstr ""
+
msgid "Todos|Are you looking for things to do? Take a look at %{strongStart}%{openIssuesLinkStart}open issues%{openIssuesLinkEnd}%{strongEnd}, contribute to %{strongStart}%{mergeRequestLinkStart}a merge request%{mergeRequestLinkEnd}%{mergeRequestLinkEnd}%{strongEnd}, or mention someone in a comment to automatically assign them a new to-do item."
msgstr ""
@@ -38352,12 +39127,8 @@ msgstr ""
msgid "Trending"
msgstr ""
-msgid "Trials|%{planName} Trial %{enDash} %{num} day left"
-msgid_plural "Trials|%{planName} Trial %{enDash} %{num} days left"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-msgstr[3] ""
+msgid "Trials|%{planName} Trial"
+msgstr ""
msgid "Trials|Compare all plans"
msgstr ""
@@ -38365,6 +39136,9 @@ msgstr ""
msgid "Trials|Create a new group to start your GitLab Ultimate trial."
msgstr ""
+msgid "Trials|Day %{daysUsed}/%{duration}"
+msgstr ""
+
msgid "Trials|Go back to GitLab"
msgstr ""
@@ -38614,7 +39388,7 @@ msgstr ""
msgid "URL is triggered when repository is updated"
msgstr ""
-msgid "URL must be percent-encoded if neccessary."
+msgid "URL must be percent-encoded if necessary."
msgstr ""
msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
@@ -38833,6 +39607,9 @@ msgstr ""
msgid "Unlock account"
msgstr ""
+msgid "Unlock more features with GitLab Ultimate"
+msgstr ""
+
msgid "Unlock the discussion"
msgstr ""
@@ -38896,6 +39673,9 @@ msgstr ""
msgid "Unsubscribes from this %{quick_action_target}."
msgstr ""
+msgid "Unsupported sort value."
+msgstr ""
+
msgid "Unsupported todo type passed. Supported todo types are: %{todo_types}"
msgstr ""
@@ -39124,6 +39904,9 @@ msgstr ""
msgid "UsageQuota|File attachments and smaller design graphics."
msgstr ""
+msgid "UsageQuota|From %{storage_enforcement_date} storage limits will apply to this namespace. View and manage your usage in %{strong_start}Group Settings &gt; Usage quotas%{strong_end}."
+msgstr ""
+
msgid "UsageQuota|Git repository."
msgstr ""
@@ -39184,6 +39967,9 @@ msgstr ""
msgid "UsageQuota|Storage type"
msgstr ""
+msgid "UsageQuota|Storage used"
+msgstr ""
+
msgid "UsageQuota|This is the total amount of storage used across your projects within this namespace."
msgstr ""
@@ -39379,6 +40165,12 @@ msgstr ""
msgid "Use hashed storage paths for newly created and renamed repositories. Always enabled since 13.0."
msgstr ""
+msgid "Use issue count"
+msgstr ""
+
+msgid "Use issue weight"
+msgstr ""
+
msgid "Use one line per URI"
msgstr ""
@@ -39760,6 +40552,9 @@ msgstr ""
msgid "Users"
msgstr ""
+msgid "Users API rate limit"
+msgstr ""
+
msgid "Users can launch a development environment from a GitLab browser tab when the %{linkStart}Gitpod%{linkEnd} integration is enabled."
msgstr ""
@@ -40089,6 +40884,9 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View group pipeline usage quota"
+msgstr ""
+
msgid "View incident details at"
msgstr ""
@@ -40243,6 +41041,9 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
+msgid "Vulnerability"
+msgstr ""
+
msgid "Vulnerability Report"
msgstr ""
@@ -40294,6 +41095,9 @@ msgstr ""
msgid "VulnerabilityManagement|An unverified non-confirmed finding"
msgstr ""
+msgid "VulnerabilityManagement|At least one identifier is required"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -40303,12 +41107,24 @@ msgstr ""
msgid "VulnerabilityManagement|Create Jira issue"
msgstr ""
+msgid "VulnerabilityManagement|Enter a name"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE code"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE identifier URL"
+msgstr ""
+
msgid "VulnerabilityManagement|Fetching linked Jira issues"
msgstr ""
msgid "VulnerabilityManagement|Manually add a vulnerability entry into the vulnerability report."
msgstr ""
+msgid "VulnerabilityManagement|Name is a required field"
+msgstr ""
+
msgid "VulnerabilityManagement|Needs triage"
msgstr ""
@@ -40324,6 +41140,18 @@ msgstr ""
msgid "VulnerabilityManagement|Select a method"
msgstr ""
+msgid "VulnerabilityManagement|Select a severity level"
+msgstr ""
+
+msgid "VulnerabilityManagement|Select a status"
+msgstr ""
+
+msgid "VulnerabilityManagement|Severity is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Something went wrong while creating vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -40348,6 +41176,12 @@ msgstr ""
msgid "VulnerabilityManagement|Something went wrong, could not update vulnerability state."
msgstr ""
+msgid "VulnerabilityManagement|Status is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Submit vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Summary, detailed description, steps to reproduce, etc."
msgstr ""
@@ -40543,6 +41377,9 @@ msgstr ""
msgid "WARNING:"
msgstr ""
+msgid "WARNING: This snippet contains hidden files which might be used to mask malicious behavior. Exercise caution if cloning and executing code from this snippet."
+msgstr ""
+
msgid "Wait for the file to load to copy its contents"
msgstr ""
@@ -40762,6 +41599,15 @@ msgstr ""
msgid "Webhooks|An issue is created, updated, closed, or reopened."
msgstr ""
+msgid "Webhooks|Are you sure you want to delete this group hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this project hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this webhook?"
+msgstr ""
+
msgid "Webhooks|Comments"
msgstr ""
@@ -40771,6 +41617,9 @@ msgstr ""
msgid "Webhooks|Confidential issues events"
msgstr ""
+msgid "Webhooks|Delete webhook"
+msgstr ""
+
msgid "Webhooks|Deployment events"
msgstr ""
@@ -41006,6 +41855,9 @@ msgstr ""
msgid "Wiki"
msgstr ""
+msgid "Wiki page"
+msgstr ""
+
msgid "Wiki page was successfully created."
msgstr ""
@@ -41111,7 +41963,7 @@ msgstr ""
msgid "WikiPageConflictMessage|Someone edited the page the same time you did. Please check out %{wikiLinkStart}the page%{wikiLinkEnd} and make sure your changes will not unintentionally remove theirs."
msgstr ""
-msgid "WikiPage|An error occured while trying to render the content editor. Please try again later."
+msgid "WikiPage|An error occurred while trying to render the content editor. Please try again later."
msgstr ""
msgid "WikiPage|Are you sure you want to switch back to the classic editor?"
@@ -41270,6 +42122,18 @@ msgstr ""
msgid "WorkItem|New Task"
msgstr ""
+msgid "WorkItem|Something went wrong when creating a work item. Please try again"
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching the work item. Please try again."
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching work item types. Please try again"
+msgstr ""
+
+msgid "WorkItem|Type"
+msgstr ""
+
msgid "WorkItem|Work Items"
msgstr ""
@@ -41336,7 +42200,10 @@ msgstr ""
msgid "You are about to add %{usersTag} people to the discussion. They will all receive a notification."
msgstr ""
-msgid "You are about to permanently delete this project"
+msgid "You are about to delete this forked project containing:"
+msgstr ""
+
+msgid "You are about to delete this project containing:"
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."
@@ -41357,6 +42224,9 @@ msgstr ""
msgid "You are attempting to update a file that has changed since you started editing it."
msgstr ""
+msgid "You are billed if you exceed this number. %{qsrOverageLinkStart}How does billing work?%{qsrOverageLinkEnd}"
+msgstr ""
+
msgid "You are connected to the Prometheus server, but there is currently no data to display."
msgstr ""
@@ -41414,6 +42284,9 @@ msgstr ""
msgid "You are not authorized to update this scanner profile"
msgstr ""
+msgid "You are not authorized to upload metric images"
+msgstr ""
+
msgid "You are now impersonating %{username}"
msgstr ""
@@ -41567,9 +42440,6 @@ msgstr ""
msgid "You can only upload one design when dropping onto an existing design."
msgstr ""
-msgid "You can recover this project until %{date}"
-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 ""
@@ -41618,9 +42488,6 @@ msgstr ""
msgid "You cannot write to this read-only GitLab instance."
msgstr ""
-msgid "You can’t %{tag_start}edit%{tag_end} files directly in this project. Fork this project and submit a merge request with your changes."
-msgstr ""
-
msgid "You can’t edit files directly in this project. Fork this project and submit a merge request with your changes."
msgstr ""
@@ -41775,9 +42642,6 @@ 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 set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
@@ -41808,12 +42672,6 @@ msgstr ""
msgid "You must have maintainer access to force delete a lock"
msgstr ""
-msgid "You must have permission to create a project in a group before forking."
-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 ""
@@ -42219,7 +43077,7 @@ msgstr ""
msgid "Your public email will be displayed on your public profile."
msgstr ""
-msgid "Your request for access could not be processed: %{error_meesage}"
+msgid "Your request for access could not be processed: %{error_message}"
msgstr ""
msgid "Your request for access has been queued for review."
@@ -42408,6 +43266,9 @@ msgstr ""
msgid "archived:"
msgstr ""
+msgid "artifacts"
+msgstr ""
+
msgid "assign yourself"
msgstr ""
@@ -42439,6 +43300,9 @@ msgstr[3] ""
msgid "branch name"
msgstr ""
+msgid "builds"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -42868,6 +43732,9 @@ msgstr ""
msgid "contact with same email already exists in group hierarchy"
msgstr ""
+msgid "container registry images"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -42907,6 +43774,9 @@ msgstr ""
msgid "data"
msgstr ""
+msgid "database"
+msgstr ""
+
msgid "date must not be after 9999-12-31"
msgstr ""
@@ -42932,9 +43802,6 @@ msgstr ""
msgid "design"
msgstr ""
-msgid "detached"
-msgstr ""
-
msgid "disabled"
msgstr ""
@@ -43191,7 +44058,7 @@ msgstr ""
msgid "is not a valid X509 certificate."
msgstr ""
-msgid "is not allowed for sign-up."
+msgid "is not allowed for sign-up. Please use your regular email address."
msgstr ""
msgid "is not allowed for this group."
@@ -43203,7 +44070,7 @@ msgstr ""
msgid "is not allowed since the group is not top-level group."
msgstr ""
-msgid "is not allowed."
+msgid "is not allowed. Please use your regular email address."
msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
@@ -43290,6 +44157,9 @@ msgstr ""
msgid "level: %{level}"
msgstr ""
+msgid "lfs objects"
+msgstr ""
+
msgid "limit of %{project_limit} reached"
msgstr ""
@@ -43515,6 +44385,9 @@ msgstr ""
msgid "mrWidget|Merge blocked: pipeline must succeed. It's waiting for a manual action to continue."
msgstr ""
+msgid "mrWidget|Merge blocked: pipeline must succeed. Push a commit that fixes the failure, or %{linkStart}learn about other solutions.%{linkEnd}"
+msgstr ""
+
msgid "mrWidget|Merge blocked: this merge request must be approved."
msgstr ""
@@ -43632,9 +44505,6 @@ msgstr ""
msgid "mrWidget|The changes were not merged into"
msgstr ""
-msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -43782,9 +44652,6 @@ msgstr ""
msgid "open issue"
msgstr ""
-msgid "opened %{timeAgo}"
-msgstr ""
-
msgid "or"
msgstr ""
@@ -43798,6 +44665,12 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "packages"
+msgstr ""
+
+msgid "pages"
+msgstr ""
+
msgid "parent"
msgid_plural "parents"
msgstr[0] ""
@@ -43955,6 +44828,9 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "repositories"
+msgstr ""
+
msgid "repository:"
msgstr ""
@@ -44075,12 +44951,18 @@ msgstr ""
msgid "tag name"
msgstr ""
+msgid "terraform states"
+msgstr ""
+
msgid "the correct format."
msgstr ""
msgid "the file"
msgstr ""
+msgid "the following epic(s)"
+msgstr ""
+
msgid "the following issue(s)"
msgstr ""
@@ -44093,21 +44975,12 @@ msgstr ""
msgid "this document"
msgstr ""
-msgid "this issue cannot be assigned to a confidential epic since it is public"
-msgstr ""
-
-msgid "this issue cannot be made public since it belongs to a confidential epic"
-msgstr ""
-
msgid "time summary"
msgstr ""
msgid "toggle collapse"
msgstr ""
-msgid "train"
-msgstr ""
-
msgid "triggered"
msgstr ""
@@ -44238,3 +45111,6 @@ msgstr ""
msgid "{project}"
msgstr ""
+msgid "✔"
+msgstr ""
+
diff --git a/locale/cy_GB/gitlab.po b/locale/cy_GB/gitlab.po
index 215a59b7225..4cbb3ed30ae 100644
--- a/locale/cy_GB/gitlab.po
+++ b/locale/cy_GB/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: cy\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2022-02-02 15:46\n"
+"PO-Revision-Date: 2022-03-01 20:40\n"
msgid " %{start} to %{end}"
msgstr " %{start} i %{end}"
@@ -202,6 +202,15 @@ msgstr[3] ""
msgstr[4] ""
msgstr[5] ""
+msgid "%d assigned issue"
+msgid_plural "%d assigned issues"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+msgstr[4] ""
+msgstr[5] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -697,8 +706,35 @@ msgstr[3] ""
msgstr[4] ""
msgstr[5] ""
-msgid "%d vulnerability updated"
-msgid_plural "%d vulnerabilities updated"
+msgid "%d vulnerability set to confirmed"
+msgid_plural "%d vulnerabilities set to confirmed"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+msgstr[4] ""
+msgstr[5] ""
+
+msgid "%d vulnerability set to dismissed"
+msgid_plural "%d vulnerabilities set to dismissed"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+msgstr[4] ""
+msgstr[5] ""
+
+msgid "%d vulnerability set to needs triage"
+msgid_plural "%d vulnerabilities set to needs triage"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+msgstr[4] ""
+msgstr[5] ""
+
+msgid "%d vulnerability set to resolved"
+msgid_plural "%d vulnerabilities set to resolved"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
@@ -814,6 +850,12 @@ msgstr[5] ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{completed} of %{total} issues closed"
+msgstr ""
+
+msgid "%{completed} of %{total} weight completed"
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -1186,6 +1228,9 @@ msgstr ""
msgid "%{openedIssues} open, %{closedIssues} closed"
msgstr ""
+msgid "%{percentage}%% issues closed"
+msgstr ""
+
msgid "%{percentage}%% weight completed"
msgstr ""
@@ -1675,6 +1720,9 @@ msgstr[3] ""
msgstr[4] ""
msgstr[5] ""
+msgid "- of - issues closed"
+msgstr ""
+
msgid "- of - weight completed"
msgstr ""
@@ -1909,7 +1957,7 @@ msgstr ""
msgid "1000+"
msgstr ""
-msgid "192.168.0.0/24"
+msgid "192.168.0.0/24 or 2001:0DB8:1234::/48"
msgstr ""
msgid "1st contribution!"
@@ -2221,13 +2269,13 @@ msgstr ""
msgid "AWS Access Key"
msgstr ""
-msgid "AWS Access Key. Only required if not using role instance credentials"
+msgid "AWS Secret Access Key"
msgstr ""
-msgid "AWS Secret Access Key"
+msgid "AWS access key ID (Optional)"
msgstr ""
-msgid "AWS Secret Access Key. Only required if not using role instance credentials"
+msgid "AWS secret access key (Optional)"
msgstr ""
msgid "AWS service error: %{error}"
@@ -2287,9 +2335,6 @@ msgstr ""
msgid "Access granted"
msgstr ""
-msgid "Access key ID"
-msgstr ""
-
msgid "Access requests"
msgstr ""
@@ -2464,7 +2509,7 @@ msgstr ""
msgid "Activity"
msgstr ""
-msgid "Activity|An error occured while retrieving activity. Reload the page to try again."
+msgid "Activity|An error occurred while retrieving activity. Reload the page to try again."
msgstr ""
msgid "Add"
@@ -2503,6 +2548,9 @@ msgstr ""
msgid "Add a %{type}"
msgstr ""
+msgid "Add a GCP region"
+msgstr ""
+
msgid "Add a GPG key"
msgstr ""
@@ -2554,6 +2602,9 @@ msgstr ""
msgid "Add a numbered list"
msgstr ""
+msgid "Add a related epic"
+msgstr ""
+
msgid "Add a related issue"
msgstr ""
@@ -2668,6 +2719,9 @@ msgstr ""
msgid "Add or subtract spent time"
msgstr ""
+msgid "Add people"
+msgstr ""
+
msgid "Add previously merged commits"
msgstr ""
@@ -2734,6 +2788,9 @@ msgstr ""
msgid "Add webhook"
msgstr ""
+msgid "Add your team members and others to GitLab."
+msgstr ""
+
msgid "Add/remove"
msgstr ""
@@ -3556,12 +3613,6 @@ msgstr ""
msgid "AdvancedSearch|Reindex required"
msgstr ""
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. Permanently deleting this project will %{strongStart}immediately delete%{strongEnd} its repositories and %{strongStart}all related resources%{strongEnd}, including issues, merge requests etc."
-msgstr ""
-
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. You will lose this project's repository and %{strongStart}all related resources%{strongEnd}, including issues and merge requests."
-msgstr ""
-
msgid "After a successful password update you will be redirected to login screen."
msgstr ""
@@ -3592,6 +3643,9 @@ msgstr ""
msgid "Akismet helps prevent the creation of spam issues in public projects."
msgstr ""
+msgid "Alert"
+msgstr ""
+
msgid "AlertManagement|Acknowledged"
msgstr ""
@@ -3964,9 +4018,6 @@ msgstr ""
msgid "All environments"
msgstr ""
-msgid "All epics"
-msgstr ""
-
msgid "All groups and projects"
msgstr ""
@@ -4711,8 +4762,11 @@ msgstr ""
msgid "ApplicationSettings|Approve users in the pending approval status?"
msgstr ""
-msgid "ApplicationSettings|By making this change, you will automatically approve %d user with the pending approval status."
-msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users with the pending approval status."
+msgid "ApplicationSettings|Approve users who are pending approval?"
+msgstr ""
+
+msgid "ApplicationSettings|By making this change, you will automatically approve %d user who is pending approval."
+msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users who are pending approval."
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
@@ -4720,7 +4774,7 @@ msgstr[3] ""
msgstr[4] ""
msgstr[5] ""
-msgid "ApplicationSettings|By making this change, you will automatically approve all users in pending approval status."
+msgid "ApplicationSettings|By making this change, you will automatically approve all users who are pending approval."
msgstr ""
msgid "ApplicationSettings|Denied domains for sign-ups"
@@ -5146,10 +5200,10 @@ msgstr ""
msgid "Archiving the project will make it entirely read-only. It is hidden from the dashboard and doesn't show up in searches. %{strong_start}The repository cannot be committed to, and no issues, comments, or other entities can be created.%{strong_end} %{link_start}Learn more.%{link_end}"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to delete this project?"
+msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
+msgid "Are you absolutely sure?"
msgstr ""
msgid "Are you sure that you want to archive this project?"
@@ -5185,12 +5239,18 @@ msgstr ""
msgid "Are you sure you want to delete this SSH key?"
msgstr ""
+msgid "Are you sure you want to delete this comment?"
+msgstr ""
+
msgid "Are you sure you want to delete this deploy key?"
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 label?"
+msgstr ""
+
msgid "Are you sure you want to delete this pipeline schedule?"
msgstr ""
@@ -5206,9 +5266,6 @@ msgstr ""
msgid "Are you sure you want to discard your changes?"
msgstr ""
-msgid "Are you sure you want to erase this build?"
-msgstr ""
-
msgid "Are you sure you want to import %d repository?"
msgid_plural "Are you sure you want to import %d repositories?"
msgstr[0] ""
@@ -5260,6 +5317,9 @@ msgstr ""
msgid "Are you sure you want to remove this list?"
msgstr ""
+msgid "Are you sure you want to remove this nickname?"
+msgstr ""
+
msgid "Are you sure you want to reset the health check token?"
msgstr ""
@@ -5272,10 +5332,10 @@ 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?"
+msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
msgstr ""
-msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
+msgid "Are you sure you want to revoke this project access token? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to stop this environment?"
@@ -5422,9 +5482,6 @@ msgstr ""
msgid "Assigned to %{assignee_name}"
msgstr ""
-msgid "Assigned to %{name}"
-msgstr ""
-
msgid "Assigned to me"
msgstr ""
@@ -5497,6 +5554,9 @@ msgstr[5] ""
msgid "Attaching the file failed."
msgstr ""
+msgid "Attention"
+msgstr ""
+
msgid "Audit Events"
msgstr ""
@@ -5659,6 +5719,12 @@ msgstr ""
msgid "Authorized applications (%{size})"
msgstr ""
+msgid "AuthorizedApplication|Are you sure you want to revoke this application?"
+msgstr ""
+
+msgid "AuthorizedApplication|Revoke application"
+msgstr ""
+
msgid "Authors: %{authors}"
msgstr ""
@@ -6868,6 +6934,9 @@ msgstr ""
msgid "CICDAnalytics|Shared Runners Usage"
msgstr ""
+msgid "CICDAnalytics|Shared runner pipeline minute duration by month"
+msgstr ""
+
msgid "CICDAnalytics|Shared runner usage"
msgstr ""
@@ -7009,6 +7078,9 @@ msgstr ""
msgid "Can create groups:"
msgstr ""
+msgid "Can not delete primary training"
+msgstr ""
+
msgid "Can't apply as the source branch was deleted."
msgstr ""
@@ -7342,9 +7414,6 @@ msgstr ""
msgid "Changing any setting here requires an application restart"
msgstr ""
-msgid "Changing group URL can have unintended side effects."
-msgstr ""
-
msgid "Charts can't be displayed as the request for data has timed out. %{documentationLink}"
msgstr ""
@@ -7432,9 +7501,6 @@ msgstr ""
msgid "Checking branch availability..."
msgstr ""
-msgid "Checking group URL availability..."
-msgstr ""
-
msgid "Checking group path availability..."
msgstr ""
@@ -7936,6 +8002,9 @@ msgstr ""
msgid "Clear recent searches"
msgstr ""
+msgid "Clear repository checks"
+msgstr ""
+
msgid "Clear search"
msgstr ""
@@ -8068,9 +8137,6 @@ msgstr ""
msgid "Closed MRs"
msgstr ""
-msgid "Closed epics"
-msgstr ""
-
msgid "Closed issues"
msgstr ""
@@ -8107,13 +8173,13 @@ msgstr ""
msgid "Cluster level"
msgstr ""
-msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
+msgid "Cluster type must be specified for Stages::ClusterEndpointInserter"
msgstr ""
msgid "ClusterAgents|%{name} successfully deleted"
msgstr ""
-msgid "ClusterAgents|%{number} of %{total} Agents"
+msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
@@ -8155,6 +8221,15 @@ msgstr ""
msgid "ClusterAgents|Agent never connected to GitLab"
msgstr ""
+msgid "ClusterAgents|Agent version mismatch"
+msgstr ""
+
+msgid "ClusterAgents|Agent version mismatch and update"
+msgstr ""
+
+msgid "ClusterAgents|Agent version update required"
+msgstr ""
+
msgid "ClusterAgents|All"
msgstr ""
@@ -8179,7 +8254,7 @@ msgstr ""
msgid "ClusterAgents|Configuration"
msgstr ""
-msgid "ClusterAgents|Connect a cluster through the Agent"
+msgid "ClusterAgents|Connect a cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connect existing cluster"
@@ -8188,13 +8263,13 @@ msgstr ""
msgid "ClusterAgents|Connect with a certificate"
msgstr ""
-msgid "ClusterAgents|Connect with agent"
+msgid "ClusterAgents|Connect with an agent"
msgstr ""
msgid "ClusterAgents|Connect with the GitLab Agent"
msgstr ""
-msgid "ClusterAgents|Connect your cluster through the Agent"
+msgid "ClusterAgents|Connect your cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connected"
@@ -8254,7 +8329,10 @@ msgstr ""
msgid "ClusterAgents|How to register an agent?"
msgstr ""
-msgid "ClusterAgents|Install new Agent"
+msgid "ClusterAgents|How to update an agent?"
+msgstr ""
+
+msgid "ClusterAgents|Install a new agent"
msgstr ""
msgid "ClusterAgents|Last connected %{timeAgo}."
@@ -8281,7 +8359,7 @@ msgstr ""
msgid "ClusterAgents|Never connected"
msgstr ""
-msgid "ClusterAgents|No Agents"
+msgid "ClusterAgents|No agents"
msgstr ""
msgid "ClusterAgents|No clusters connected through cluster certificates"
@@ -8341,6 +8419,9 @@ msgstr ""
msgid "ClusterAgents|The agent has not been connected in a long time. There might be a connectivity issue. Last contact was %{timeAgo}."
msgstr ""
+msgid "ClusterAgents|The agent version do not match each other across your cluster's pods. This can happen when a new agent version was just deployed and Kubernetes is shutting down the old pods."
+msgstr ""
+
msgid "ClusterAgents|The recommended installation method includes the token. If you want to follow the advanced installation method provided in the docs, make sure you save the token value before you close this window."
msgstr ""
@@ -8392,6 +8473,9 @@ msgstr ""
msgid "ClusterAgents|You will need to create a token to connect to your agent"
msgstr ""
+msgid "ClusterAgents|Your agent version is out of sync with your GitLab version (v%{version}), which might cause compatibility problems. Update the agent installed on your cluster to the most recent version."
+msgstr ""
+
msgid "ClusterAgents|Your instance doesn't have the %{linkStart}GitLab Agent Server (KAS)%{linkEnd} set up. Ask a GitLab Administrator to install it."
msgstr ""
@@ -9268,9 +9352,6 @@ msgstr ""
msgid "Comma-separated list of email addresses."
msgstr ""
-msgid "Comma-separated list of users allowed to exceed the rate limit."
-msgstr ""
-
msgid "Comma-separated, e.g. '1.1.1.1, 2.2.2.0/24'"
msgstr ""
@@ -9601,6 +9682,12 @@ msgstr ""
msgid "Confidential"
msgstr ""
+msgid "Confidential issue"
+msgstr ""
+
+msgid "Confidential note"
+msgstr ""
+
msgid "Confidentiality"
msgstr ""
@@ -9634,6 +9721,9 @@ msgstr ""
msgid "Configure Dependency Scanning in `.gitlab-ci.yml`, creating this file if it does not already exist"
msgstr ""
+msgid "Configure GitLab"
+msgstr ""
+
msgid "Configure GitLab runners to start using the Web Terminal. %{helpStart}Learn more.%{helpEnd}"
msgstr ""
@@ -9682,6 +9772,15 @@ msgstr ""
msgid "Configure pipelines to deploy web apps, backend services, APIs and static resources to Google Cloud"
msgstr ""
+msgid "Configure region"
+msgstr ""
+
+msgid "Configure region for environment"
+msgstr ""
+
+msgid "Configure regions"
+msgstr ""
+
msgid "Configure repository mirroring."
msgstr ""
@@ -9715,6 +9814,9 @@ msgstr ""
msgid "Configure which lists are shown for anyone who visits this board"
msgstr ""
+msgid "Configure your environments to be deployed to specific geographical regions"
+msgstr ""
+
msgid "Confirm"
msgstr ""
@@ -10429,10 +10531,10 @@ msgstr ""
msgid "CorpusManagement|Actions"
msgstr ""
-msgid "CorpusManagement|Corpus are used in fuzz testing as mutation source to Improve future testing."
+msgid "CorpusManagement|Corpus file"
msgstr ""
-msgid "CorpusManagement|Corpus file"
+msgid "CorpusManagement|Corpus files are used in coverage-guided fuzz testing as seed inputs to improve testing."
msgstr ""
msgid "CorpusManagement|Corpus files must be in *.zip format. Maximum 5 GB"
@@ -10486,6 +10588,9 @@ msgstr ""
msgid "Could not apply %{name} command."
msgstr ""
+msgid "Could not apply %{name} command. %{message}."
+msgstr ""
+
msgid "Could not authorize chat nickname. Try again!"
msgstr ""
@@ -10636,6 +10741,9 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
+msgid "Create a group"
+msgstr ""
+
msgid "Create a merge request"
msgstr ""
@@ -10660,6 +10768,9 @@ msgstr ""
msgid "Create a personal access token on your account to pull or push via %{protocol}."
msgstr ""
+msgid "Create a project"
+msgstr ""
+
msgid "Create an account using:"
msgstr ""
@@ -11023,6 +11134,9 @@ msgstr ""
msgid "Creation date"
msgstr ""
+msgid "Creator"
+msgstr ""
+
msgid "Credentials"
msgstr ""
@@ -11035,9 +11149,15 @@ msgstr ""
msgid "CredentialsInventory|Personal Access Tokens"
msgstr ""
+msgid "CredentialsInventory|Project Access Tokens"
+msgstr ""
+
msgid "CredentialsInventory|SSH Keys"
msgstr ""
+msgid "Credit card required to be on file in order to create a pipeline"
+msgstr ""
+
msgid "Credit card:"
msgstr ""
@@ -11221,9 +11341,6 @@ msgstr ""
msgid "Customer relations"
msgstr ""
-msgid "Customizable by an administrator."
-msgstr ""
-
msgid "Customizable by owners."
msgstr ""
@@ -11353,30 +11470,18 @@ msgstr ""
msgid "CycleAnalytics|%{selectedLabelsCount} selected (%{maxLabels} max)"
msgstr ""
-msgid "CycleAnalytics|%{stageCount} stages selected"
-msgstr ""
-
-msgid "CycleAnalytics|All stages"
-msgstr ""
-
-msgid "CycleAnalytics|Average days to completion"
+msgid "CycleAnalytics|Average time to completion"
msgstr ""
msgid "CycleAnalytics|Date"
msgstr ""
-msgid "CycleAnalytics|Days to completion"
-msgstr ""
-
msgid "CycleAnalytics|Display chart filters"
msgstr ""
msgid "CycleAnalytics|Lead Time for Changes"
msgstr ""
-msgid "CycleAnalytics|No stages selected"
-msgstr ""
-
msgid "CycleAnalytics|Number of tasks"
msgstr ""
@@ -11413,18 +11518,30 @@ msgstr ""
msgid "CycleAnalytics|Showing data for group '%{groupName}' from %{createdAfter} to %{createdBefore}"
msgstr ""
-msgid "CycleAnalytics|Stages"
+msgid "CycleAnalytics|Stage time: %{title}"
msgstr ""
msgid "CycleAnalytics|Tasks by type"
msgstr ""
-msgid "CycleAnalytics|The average time spent in the selected stage for the items that were completed on each date. Data limited to the last 500 items."
+msgid "CycleAnalytics|The average time items spent in this stage. Data limited to items completed within this date range."
msgstr ""
msgid "CycleAnalytics|The given date range is larger than 180 days"
msgstr ""
+msgid "CycleAnalytics|The total time items spent across each value stream stage. Data limited to items completed within this date range."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Stage time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Total time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|Total time"
+msgstr ""
+
msgid "CycleAnalytics|Type of work"
msgstr ""
@@ -11437,9 +11554,6 @@ msgstr ""
msgid "CycleAnalytics|project dropdown filter"
msgstr ""
-msgid "CycleAnalytics|stage dropdown"
-msgstr ""
-
msgid "DAG visualization requires at least 3 dependent jobs."
msgstr ""
@@ -11539,10 +11653,16 @@ msgstr ""
msgid "DastProfiles|AJAX spider"
msgstr ""
+msgid "DastProfiles|API"
+msgstr ""
+
+msgid "DastProfiles|API endpoint URL"
+msgstr ""
+
msgid "DastProfiles|Active"
msgstr ""
-msgid "DastProfiles|Additional request headers (Optional)"
+msgid "DastProfiles|Additional request headers (optional)"
msgstr ""
msgid "DastProfiles|Are you sure you want to delete this profile?"
@@ -11557,6 +11677,9 @@ msgstr ""
msgid "DastProfiles|Branch missing"
msgstr ""
+msgid "DastProfiles|Choose a scan method"
+msgstr ""
+
msgid "DastProfiles|Could not create the scanner profile. Please try again."
msgstr ""
@@ -11626,7 +11749,13 @@ msgstr ""
msgid "DastProfiles|Excluded URLs"
msgstr ""
-msgid "DastProfiles|Excluded URLs (Optional)"
+msgid "DastProfiles|Excluded URLs (optional)"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths (optional)"
msgstr ""
msgid "DastProfiles|Hide debug messages"
@@ -11683,9 +11812,6 @@ msgstr ""
msgid "DastProfiles|Request headers"
msgstr ""
-msgid "DastProfiles|Rest API"
-msgstr ""
-
msgid "DastProfiles|Run the AJAX spider, in addition to the traditional spider, to crawl the target site."
msgstr ""
@@ -11695,6 +11821,9 @@ msgstr ""
msgid "DastProfiles|Save profile"
msgstr ""
+msgid "DastProfiles|Scan method"
+msgstr ""
+
msgid "DastProfiles|Scan mode"
msgstr ""
@@ -11773,12 +11902,24 @@ msgstr ""
msgid "DastProfiles|Website"
msgstr ""
+msgid "DastProfiles|What does each method do?"
+msgstr ""
+
msgid "DastProfiles|You can either choose a passive scan or validate the target site from the site profile management page. %{docsLinkStart}Learn more about site validation.%{docsLinkEnd}"
msgstr ""
msgid "DastProfiles|You cannot run an active scan against an unvalidated site."
msgstr ""
+msgid "DastProfiles|folder/dast_example.har or https://example.com/dast_example.har"
+msgstr ""
+
+msgid "DastProfiles|folder/example.postman_collection.json or https://example.com/"
+msgstr ""
+
+msgid "DastProfiles|folder/openapi.json or https://example.com/openapi.json"
+msgstr ""
+
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
@@ -11890,6 +12031,9 @@ msgstr ""
msgid "DatadogIntegration|API URL"
msgstr ""
+msgid "DatadogIntegration|Custom tags in Datadog. Enter one tag per line in the %{codeOpen}key:value%{codeClose} format. %{linkOpen}How do I use tags?%{linkClose}"
+msgstr ""
+
msgid "DatadogIntegration|Environment"
msgstr ""
@@ -11908,12 +12052,18 @@ msgstr ""
msgid "DatadogIntegration|Tag all data from this GitLab instance in Datadog. Useful when managing several self-managed deployments."
msgstr ""
+msgid "DatadogIntegration|Tags"
+msgstr ""
+
msgid "DatadogIntegration|The Datadog site to send data to. To send data to the EU site, use %{codeOpen}datadoghq.eu%{codeClose}."
msgstr ""
msgid "DatadogIntegration|Trace your GitLab pipelines with Datadog."
msgstr ""
+msgid "DatadogIntegration|have an invalid format"
+msgstr ""
+
msgid "Datasource name not found"
msgstr ""
@@ -11923,9 +12073,6 @@ msgstr ""
msgid "Date merged"
msgstr ""
-msgid "Date picker"
-msgstr ""
-
msgid "Date range"
msgstr ""
@@ -12079,9 +12226,6 @@ msgstr ""
msgid "Definition"
msgstr ""
-msgid "Delayed Project Deletion (%{adjourned_deletion})"
-msgstr ""
-
msgid "DelayedJobs|Are you sure you want to run %{jobName} immediately? Otherwise this job will run automatically after its timer finishes."
msgstr ""
@@ -12160,10 +12304,10 @@ msgstr ""
msgid "Delete pipeline"
msgstr ""
-msgid "Delete project"
+msgid "Delete pipeline schedule"
msgstr ""
-msgid "Delete project. Are you ABSOLUTELY SURE?"
+msgid "Delete project"
msgstr ""
msgid "Delete row"
@@ -12193,6 +12337,9 @@ msgstr ""
msgid "Delete this epic and all descendants?"
msgstr ""
+msgid "Delete this project"
+msgstr ""
+
msgid "Delete user list"
msgstr ""
@@ -12475,6 +12622,12 @@ msgstr ""
msgid "Deploy to..."
msgstr ""
+msgid "DeployBoards|To see deployment progress for your environments, make sure you are deploying to %{codeStart}$KUBE_NAMESPACE%{codeEnd} and annotating with %{codeStart}app.gitlab.com/app=$CI_PROJECT_PATH_SLUG%{codeEnd} and %{codeStart}app.gitlab.com/env=$CI_ENVIRONMENT_SLUG%{codeEnd}."
+msgstr ""
+
+msgid "DeployBoard|Kubernetes Pods"
+msgstr ""
+
msgid "DeployFreeze|Add a freeze period to prevent unintended releases during a period of time for a given environment. You must update the deployment jobs in %{filename} according to the deploy freezes added here. %{freeze_period_link_start}Learn more.%{freeze_period_link_end}"
msgstr ""
@@ -12559,9 +12712,6 @@ msgstr ""
msgid "DeployTokens|Active Deploy Tokens (%{active_tokens})"
msgstr ""
-msgid "DeployTokens|Allows read and write access to registry images."
-msgstr ""
-
msgid "DeployTokens|Allows read and write access to the package registry."
msgstr ""
@@ -12574,6 +12724,9 @@ msgstr ""
msgid "DeployTokens|Allows read-only access to the repository."
msgstr ""
+msgid "DeployTokens|Allows write access to registry images."
+msgstr ""
+
msgid "DeployTokens|Copy deploy token"
msgstr ""
@@ -12667,12 +12820,57 @@ msgstr ""
msgid "Deploying to AWS is easy with GitLab"
msgstr ""
+msgid "Deployment"
+msgstr ""
+
msgid "Deployment Frequency"
msgstr ""
+msgid "Deployment Target|Project deployment target (optional)"
+msgstr ""
+
+msgid "Deployment Target|Select the deployment target"
+msgstr ""
+
msgid "Deployment frequency"
msgstr ""
+msgid "DeploymentTarget|GitLab Pages"
+msgstr ""
+
+msgid "DeploymentTarget|Heroku"
+msgstr ""
+
+msgid "DeploymentTarget|Infrastructure provider (Terraform, Cloudformation, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Kubernetes (GKE, EKS, OpenShift, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Managed container runtime (Fargate, Cloud Run, DigitalOcean App)"
+msgstr ""
+
+msgid "DeploymentTarget|Mobile app store"
+msgstr ""
+
+msgid "DeploymentTarget|No deployment planned"
+msgstr ""
+
+msgid "DeploymentTarget|Other hosting service"
+msgstr ""
+
+msgid "DeploymentTarget|Registry (package or container)"
+msgstr ""
+
+msgid "DeploymentTarget|Self-managed container runtime (Podman, Docker Swarm, Docker Compose)"
+msgstr ""
+
+msgid "DeploymentTarget|Serverless backend (Lambda, Cloud functions)"
+msgstr ""
+
+msgid "DeploymentTarget|Virtual machine (for example, EC2)"
+msgstr ""
+
msgid "Deployments"
msgstr ""
@@ -12715,6 +12913,9 @@ msgstr ""
msgid "Deployment|This deployment was created using the API"
msgstr ""
+msgid "Deployment|Triggerer"
+msgstr ""
+
msgid "Deployment|Waiting"
msgstr ""
@@ -12742,6 +12943,18 @@ msgstr ""
msgid "Deprecated API rate limits"
msgstr ""
+msgid "Deprecations|Feature deprecation and removal"
+msgstr ""
+
+msgid "Deprecations|For information on a possible replacement %{epicStart} learn more about Opstrace %{epicEnd}."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7 and are %{epicStart} scheduled for removal %{epicEnd} in GitLab 15.0."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7, and are %{removal_link_start} scheduled for removal %{link_end} in GitLab 15.0. For information on a possible replacement, %{opstrace_link_start} learn more about Opstrace %{link_end}."
+msgstr ""
+
msgid "Deprioritize label"
msgstr ""
@@ -12991,10 +13204,10 @@ msgstr ""
msgid "DevopsAdoption|At least one deploy"
msgstr ""
-msgid "DevopsAdoption|At least one issue opened"
+msgid "DevopsAdoption|At least one issue created"
msgstr ""
-msgid "DevopsAdoption|At least one merge request opened"
+msgid "DevopsAdoption|At least one merge request created"
msgstr ""
msgid "DevopsAdoption|At least one pipeline successfully run"
@@ -13207,6 +13420,9 @@ msgstr ""
msgid "Direct member"
msgstr ""
+msgid "Direct members"
+msgstr ""
+
msgid "Direct non-authenticated users to this page."
msgstr ""
@@ -13327,6 +13543,9 @@ msgstr[3] ""
msgstr[4] ""
msgstr[5] ""
+msgid "Dismiss Alert"
+msgstr ""
+
msgid "Dismiss merge request promotion"
msgstr ""
@@ -13354,9 +13573,15 @@ msgstr ""
msgid "Display alerts from all configured monitoring tools."
msgstr ""
+msgid "Display milestones"
+msgstr ""
+
msgid "Display name"
msgstr ""
+msgid "Display progress of child issues"
+msgstr ""
+
msgid "Display rendered file"
msgstr ""
@@ -13462,6 +13687,9 @@ msgstr ""
msgid "Download image"
msgstr ""
+msgid "Download payload"
+msgstr ""
+
msgid "Download raw data (.csv)"
msgstr ""
@@ -13639,6 +13867,9 @@ msgstr ""
msgid "Edit in Web IDE"
msgstr ""
+msgid "Edit in pipeline editor"
+msgstr ""
+
msgid "Edit in single-file editor"
msgstr ""
@@ -13681,6 +13912,9 @@ msgstr ""
msgid "Edit your most recent comment in a thread (from an empty textarea)"
msgstr ""
+msgid "Edit, lint, and visualize your pipeline."
+msgstr ""
+
msgid "Edited"
msgstr ""
@@ -14122,6 +14356,9 @@ msgstr ""
msgid "Enforce two-factor authentication for all user sign-ins."
msgstr ""
+msgid "Enhance security by storing service account keys in secret managers - learn more about %{docLinkStart}secret management with GitLab%{docLinkEnd}"
+msgstr ""
+
msgid "Ensure connectivity is available from the GitLab server to the Prometheus server"
msgstr ""
@@ -14182,6 +14419,9 @@ 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 following to confirm:"
+msgstr ""
+
msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
@@ -14716,9 +14956,6 @@ 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 ""
@@ -14854,6 +15091,9 @@ msgstr ""
msgid "Errors:"
msgstr ""
+msgid "Escalate this incident"
+msgstr ""
+
msgid "Escalation Policies"
msgstr ""
@@ -14866,6 +15106,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy"
+msgstr ""
+
msgid "Escalation policy:"
msgstr ""
@@ -15121,6 +15364,9 @@ msgstr ""
msgid "Existing sign in methods may be removed"
msgstr ""
+msgid "Exit."
+msgstr ""
+
msgid "Expand"
msgstr ""
@@ -15217,6 +15463,9 @@ msgstr ""
msgid "Explore public groups"
msgstr ""
+msgid "Explore public projects"
+msgstr ""
+
msgid "Explore snippets"
msgstr ""
@@ -15382,7 +15631,7 @@ msgstr[3] ""
msgstr[4] ""
msgstr[5] ""
-msgid "Failed to assign a reviewer because no user was found."
+msgid "Failed to assign a reviewer because no user was specified."
msgstr ""
msgid "Failed to assign a user because no user was found."
@@ -15448,10 +15697,10 @@ msgstr ""
msgid "Failed to find import label for Jira import."
msgstr ""
-msgid "Failed to generate export, please try again later."
+msgid "Failed to find users for %{missing}"
msgstr ""
-msgid "Failed to generate report, please try again after sometime"
+msgid "Failed to generate export, please try again later."
msgstr ""
msgid "Failed to get ref."
@@ -15550,6 +15799,9 @@ msgstr ""
msgid "Failed to remove a to-do item for the design."
msgstr ""
+msgid "Failed to remove attention because no user was found."
+msgstr ""
+
msgid "Failed to remove mirror."
msgstr ""
@@ -15562,6 +15814,9 @@ msgstr ""
msgid "Failed to remove user key."
msgstr ""
+msgid "Failed to request attention because no user was found."
+msgstr ""
+
msgid "Failed to reset key. Please try again."
msgstr ""
@@ -15643,6 +15898,9 @@ msgstr ""
msgid "Feature Flags"
msgstr ""
+msgid "Feature deprecation and removal"
+msgstr ""
+
msgid "Feature flag status"
msgstr ""
@@ -16144,7 +16402,7 @@ msgstr ""
msgid "For each job, re-use the project workspace. If the workspace doesn't exist, use %{code_open}git clone%{code_close}."
msgstr ""
-msgid "For example, the application using the token or the purpose of the token."
+msgid "For example, the application using the token or the purpose of the token. Do not give sensitive information for the name of the token, as it will be visible to all %{resource_type} members."
msgstr ""
msgid "For files larger than this limit, only index the file name. The file content is neither indexed nor searchable."
@@ -16228,9 +16486,6 @@ msgstr ""
msgid "ForkProject|Select a namespace"
msgstr ""
-msgid "ForkProject|Select a namespace to fork the project"
-msgstr ""
-
msgid "ForkProject|The project can be accessed by any logged in user."
msgstr ""
@@ -16327,6 +16582,9 @@ msgstr ""
msgid "Full name"
msgstr ""
+msgid "GCP region configured"
+msgstr ""
+
msgid "GPG Key ID:"
msgstr ""
@@ -16507,6 +16765,9 @@ msgstr ""
msgid "Geo|Failed"
msgstr ""
+msgid "Geo|Filter Geo sites"
+msgstr ""
+
msgid "Geo|Filter by name"
msgstr ""
@@ -16918,6 +17179,12 @@ msgstr ""
msgid "GitLab Issue"
msgstr ""
+msgid "GitLab KAS"
+msgstr ""
+
+msgid "GitLab Memberships CSV Export"
+msgstr ""
+
msgid "GitLab Pages"
msgstr ""
@@ -16966,6 +17233,9 @@ 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 free to use. Many features for larger teams are part of our %{link_start}paid products%{link_end}. You can try Ultimate for free without any obligation or payment details."
+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 ""
@@ -17092,7 +17362,7 @@ msgstr ""
msgid "GitLabPages|When enabled, all attempts to visit your website through HTTP are automatically redirected to HTTPS using a response with status code 301. Requires a valid certificate for all domains. %{docs_link_start}Learn more.%{link_end}"
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. %{docs_link_start}Learn more.%{link_end}"
+msgid "GitLabPages|When using Pages under the general domain of a GitLab instance (%{pages_host}), you cannot use HTTPS with subdomains of subdomains. If your namespace or groupname contains a dot, it does not work. This is a limitation of the HTTP Over TLS protocol. HTTP pages work if you don't redirect HTTP to HTTPS. %{docs_link_start}Learn more.%{link_end}"
msgstr ""
msgid "GitLabPages|With GitLab Pages you can host your static website directly from your GitLab repository. %{docs_link_start}Learn more.%{link_end}"
@@ -17269,9 +17539,6 @@ msgstr ""
msgid "Go to find file"
msgstr ""
-msgid "Go to fork"
-msgstr ""
-
msgid "Go to issue boards"
msgstr ""
@@ -17479,9 +17746,6 @@ msgstr ""
msgid "Group Hooks"
msgstr ""
-msgid "Group ID"
-msgstr ""
-
msgid "Group Owner must have signed in with SAML before enabling Group Managed Accounts"
msgstr ""
@@ -17509,9 +17773,6 @@ msgstr ""
msgid "Group by"
msgstr ""
-msgid "Group description"
-msgstr ""
-
msgid "Group description (optional)"
msgstr ""
@@ -17626,7 +17887,7 @@ msgstr ""
msgid "Group: %{name}"
msgstr ""
-msgid "GroupActivityMetrics|Issues opened"
+msgid "GroupActivityMetrics|Issues created"
msgstr ""
msgid "GroupActivityMetrics|Last 90 days"
@@ -17635,7 +17896,7 @@ msgstr ""
msgid "GroupActivityMetrics|Members added"
msgstr ""
-msgid "GroupActivityMetrics|Merge Requests opened"
+msgid "GroupActivityMetrics|Merge Requests created"
msgstr ""
msgid "GroupActivityMetrics|Recent activity"
@@ -17926,6 +18187,9 @@ msgstr ""
msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
+msgid "GroupSettings|Choose a group path that does not start with a dash or end with a period. It can also contain alphanumeric characters and underscores."
+msgstr ""
+
msgid "GroupSettings|Compliance frameworks"
msgstr ""
@@ -17959,7 +18223,7 @@ msgstr ""
msgid "GroupSettings|If not specified at the group or instance level, the default is %{default_initial_branch_name}. Does not affect existing repositories."
msgstr ""
-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."
+msgid "GroupSettings|If the parent group's visibility is lower than the group's current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility."
msgstr ""
msgid "GroupSettings|New runners registration token has been generated!"
@@ -18076,7 +18340,10 @@ msgstr ""
msgid "Groups and projects"
msgstr ""
-msgid "Groups and subgroups"
+msgid "Groups are a great way to organize projects and people."
+msgstr ""
+
+msgid "Groups are the best way to manage projects and members."
msgstr ""
msgid "Groups to synchronize"
@@ -18187,13 +18454,16 @@ msgstr ""
msgid "GroupsTree|Are you sure you want to leave the \"%{fullName}\" group?"
msgstr ""
-msgid "GroupsTree|Edit group"
+msgid "GroupsTree|Delete"
+msgstr ""
+
+msgid "GroupsTree|Edit"
msgstr ""
msgid "GroupsTree|Failed to leave the group. Please make sure you are not the only owner."
msgstr ""
-msgid "GroupsTree|Leave this group"
+msgid "GroupsTree|Leave group"
msgstr ""
msgid "GroupsTree|Loading groups"
@@ -18205,9 +18475,57 @@ msgstr ""
msgid "GroupsTree|No groups or projects matched your search"
msgstr ""
+msgid "GroupsTree|Options"
+msgstr ""
+
msgid "GroupsTree|Search by name"
msgstr ""
+msgid "Groups|Avatar will be removed. Are you sure?"
+msgstr ""
+
+msgid "Groups|Changing group URL can have unintended side effects."
+msgstr ""
+
+msgid "Groups|Checking group URL availability..."
+msgstr ""
+
+msgid "Groups|Enter a descriptive name for your group."
+msgstr ""
+
+msgid "Groups|Group ID"
+msgstr ""
+
+msgid "Groups|Group URL"
+msgstr ""
+
+msgid "Groups|Group avatar"
+msgstr ""
+
+msgid "Groups|Group description (optional)"
+msgstr ""
+
+msgid "Groups|Group name"
+msgstr ""
+
+msgid "Groups|Group path is available."
+msgstr ""
+
+msgid "Groups|Group path is unavailable. Path has been replaced with a suggested available path."
+msgstr ""
+
+msgid "Groups|Learn more"
+msgstr ""
+
+msgid "Groups|Must start with letter, digit, emoji, or underscore. Can also contain periods, dashes, spaces, and parentheses."
+msgstr ""
+
+msgid "Groups|Remove avatar"
+msgstr ""
+
+msgid "Groups|Save changes"
+msgstr ""
+
msgid "Guideline"
msgstr ""
@@ -18217,6 +18535,9 @@ msgstr ""
msgid "HAR file path or URL"
msgstr ""
+msgid "HTTP Archive (HAR)"
+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 ""
@@ -18625,6 +18946,9 @@ msgstr ""
msgid "INFO: Your SSH key is expiring soon. Please generate a new key."
msgstr ""
+msgid "IP"
+msgstr ""
+
msgid "IP Address"
msgstr ""
@@ -18661,6 +18985,9 @@ msgstr ""
msgid "IdentityVerification|Verify your identity"
msgstr ""
+msgid "IdentityVerification|You can always verify your account at a later time to create a group."
+msgstr ""
+
msgid "If any indexed field exceeds this limit, it is truncated to this number of characters. The rest of the content is neither indexed nor searchable. This does not apply to repository and wiki indexing. For unlimited characters, set this to 0."
msgstr ""
@@ -18718,6 +19045,9 @@ msgstr ""
msgid "If you add %{codeStart}needs%{codeEnd} to jobs in your pipeline you'll be able to view the %{codeStart}needs%{codeEnd} relationships between jobs in this tab as a %{linkStart}Directed Acyclic Graph (DAG)%{linkEnd}."
msgstr ""
+msgid "If you are added to a project, it will be displayed here."
+msgstr ""
+
msgid "If you did not initiate these sign-in attempts, please reach out to your administrator or enable two-factor authentication (2FA) on your account."
msgstr ""
@@ -19036,12 +19366,24 @@ msgstr ""
msgid "InProductMarketing|3 ways to dive into GitLab CI/CD"
msgstr ""
+msgid "InProductMarketing|A single application eliminates complex integrations, data chokepoints, and toolchain maintenance, resulting in greater productivity and lower cost."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features, build more efficiently, strengthen security and compliance."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features."
+msgstr ""
+
msgid "InProductMarketing|Actually, GitLab makes the team work (better)"
msgstr ""
msgid "InProductMarketing|And finally %{deploy_link} a Python application."
msgstr ""
+msgid "InProductMarketing|And many more..."
+msgstr ""
+
msgid "InProductMarketing|Are your runners ready?"
msgstr ""
@@ -19060,15 +19402,33 @@ msgstr ""
msgid "InProductMarketing|Blog"
msgstr ""
+msgid "InProductMarketing|Break down silos to coordinate seamlessly across development, operations, and security with a consistent experience across the development lifecycle."
+msgstr ""
+
+msgid "InProductMarketing|Burn up/down charts"
+msgstr ""
+
msgid "InProductMarketing|By enabling code owners and required merge approvals the right person will review the right MR. This is a win-win: cleaner code and a more efficient review process."
msgstr ""
msgid "InProductMarketing|Click on the number below that corresponds with your answer — 1 being very difficult, 5 being very easy."
msgstr ""
+msgid "InProductMarketing|Code owners"
+msgstr ""
+
msgid "InProductMarketing|Code owners and required merge approvals are part of the paid tiers of GitLab. You can start a free 30-day trial of GitLab Ultimate and enable these features in less than 5 minutes with no credit card required."
msgstr ""
+msgid "InProductMarketing|Code review analytics"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration across stages in GitLab"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration made easy"
+msgstr ""
+
msgid "InProductMarketing|Create a custom CI runner with just a few clicks"
msgstr ""
@@ -19078,12 +19438,21 @@ msgstr ""
msgid "InProductMarketing|Create a project in GitLab in 5 minutes"
msgstr ""
+msgid "InProductMarketing|Create well-defined workflows by using scoped labels on issues, merge requests, and epics. Labels with the same scope cannot be used together, which prevents conflicts."
+msgstr ""
+
msgid "InProductMarketing|Create your first project!"
msgstr ""
+msgid "InProductMarketing|Define who owns specific files or directories, so the right reviewers are suggested when a merge request introduces changes to those files."
+msgstr ""
+
msgid "InProductMarketing|Deliver Better Products Faster"
msgstr ""
+msgid "InProductMarketing|Dependency scanning"
+msgstr ""
+
msgid "InProductMarketing|Did you know teams that use GitLab are far more efficient?"
msgstr ""
@@ -19093,15 +19462,27 @@ msgstr ""
msgid "InProductMarketing|Dig in and create a project and a repo"
msgstr ""
+msgid "InProductMarketing|Discover Premium & Ultimate"
+msgstr ""
+
+msgid "InProductMarketing|Discover Premium & Ultimate."
+msgstr ""
+
msgid "InProductMarketing|Do you have a minute?"
msgstr ""
msgid "InProductMarketing|Do you have a teammate who would be perfect for this task?"
msgstr ""
+msgid "InProductMarketing|Dynamic application security testing"
+msgstr ""
+
msgid "InProductMarketing|Easy"
msgstr ""
+msgid "InProductMarketing|Epics"
+msgstr ""
+
msgid "InProductMarketing|Expand your DevOps journey with a free GitLab trial"
msgstr ""
@@ -19123,9 +19504,15 @@ msgstr ""
msgid "InProductMarketing|Feel the need for speed?"
msgstr ""
+msgid "InProductMarketing|Find and fix bottlenecks in your code review process by understanding how long open merge requests have been in review."
+msgstr ""
+
msgid "InProductMarketing|Find out how your teams are really doing"
msgstr ""
+msgid "InProductMarketing|Find out if your external libraries are safe. Run dependency scanning jobs that check for known vulnerabilities in your external libraries."
+msgstr ""
+
msgid "InProductMarketing|Follow our steps"
msgstr ""
@@ -19162,6 +19549,9 @@ msgstr ""
msgid "InProductMarketing|GitLab is better with teammates to help out!"
msgstr ""
+msgid "InProductMarketing|GitLab is infrastructure agnostic (supporting GCP, AWS, Azure, OpenShift, VMWare, On Prem, Bare Metal, and more), offering a consistent workflow experience – irrespective of the environment."
+msgstr ""
+
msgid "InProductMarketing|GitLab provides static application security testing (SAST), dynamic application security testing (DAST), container scanning, and dependency scanning to help you deliver secure applications along with license compliance."
msgstr ""
@@ -19252,21 +19642,36 @@ msgstr ""
msgid "InProductMarketing|It's also possible to simply %{external_repo_link} in order to take advantage of GitLab's CI/CD."
msgstr ""
+msgid "InProductMarketing|Keep your code quality high by defining who should approve merge requests and how many approvals are required."
+msgstr ""
+
msgid "InProductMarketing|Launch GitLab CI/CD in 20 minutes or less"
msgstr ""
+msgid "InProductMarketing|Lower cost of development"
+msgstr ""
+
+msgid "InProductMarketing|Make it easier to collaborate on high-level ideas by grouping related issues in an epic."
+msgstr ""
+
msgid "InProductMarketing|Making the switch? It's easier than you think to import your projects into GitLab. Move %{github_link}, or import something %{bitbucket_link}."
msgstr ""
msgid "InProductMarketing|Master the art of importing!"
msgstr ""
+msgid "InProductMarketing|Merge request approval rule"
+msgstr ""
+
msgid "InProductMarketing|Move on to easily creating a Pages website %{ci_template_link}"
msgstr ""
msgid "InProductMarketing|Multiple owners, confusing workstreams? We've got you covered"
msgstr ""
+msgid "InProductMarketing|Multiple required approvers"
+msgstr ""
+
msgid "InProductMarketing|Need an alternative to importing?"
msgstr ""
@@ -19279,18 +19684,33 @@ msgstr ""
msgid "InProductMarketing|Our tool brings all the things together"
msgstr ""
+msgid "InProductMarketing|Protect your web application by using DAST to examine for vulnerabilities in deployed environments."
+msgstr ""
+
msgid "InProductMarketing|Rapid development, simplified"
msgstr ""
msgid "InProductMarketing|Reduce Security & Compliance Risk"
msgstr ""
+msgid "InProductMarketing|Require multiple approvers on a merge request, so you know it's in good shape before it's merged."
+msgstr ""
+
+msgid "InProductMarketing|Roadmaps"
+msgstr ""
+
+msgid "InProductMarketing|Scoped labels"
+msgstr ""
+
msgid "InProductMarketing|Security that's integrated into your development lifecycle"
msgstr ""
msgid "InProductMarketing|Sometimes you're not ready to make a full transition to a new tool. If you're not ready to fully commit, %{mirroring_link} gives you a safe way to try out GitLab in parallel with your current tool."
msgstr ""
+msgid "InProductMarketing|Speed. Efficiency. Trust."
+msgstr ""
+
msgid "InProductMarketing|Spin up an autoscaling runner in GitLab"
msgstr ""
@@ -19300,6 +19720,9 @@ msgstr ""
msgid "InProductMarketing|Start a Self-Managed trial"
msgstr ""
+msgid "InProductMarketing|Start a free trial"
+msgstr ""
+
msgid "InProductMarketing|Start a free trial of GitLab Ultimate – no credit card required"
msgstr ""
@@ -19366,6 +19789,9 @@ msgstr ""
msgid "InProductMarketing|To understand and get the most out of GitLab, start at the beginning and %{project_link}. In GitLab, repositories are part of a project, so after you've created your project you can go ahead and %{repo_link}."
msgstr ""
+msgid "InProductMarketing|Track completed issues in a chart, so you can see how a milestone is progressing at a glance."
+msgstr ""
+
msgid "InProductMarketing|Try GitLab Ultimate for free"
msgstr ""
@@ -19402,6 +19828,9 @@ msgstr ""
msgid "InProductMarketing|Very easy"
msgstr ""
+msgid "InProductMarketing|Visualize your epics and milestones in a timeline."
+msgstr ""
+
msgid "InProductMarketing|Want to host GitLab on your servers?"
msgstr ""
@@ -19423,6 +19852,9 @@ msgstr ""
msgid "InProductMarketing|YouTube"
msgstr ""
+msgid "InProductMarketing|Your software, deployed your way"
+msgstr ""
+
msgid "InProductMarketing|Your teams can be more efficient"
msgstr ""
@@ -19543,9 +19975,18 @@ msgstr ""
msgid "IncidentManagement|No incidents to display."
msgstr ""
+msgid "IncidentManagement|None"
+msgstr ""
+
msgid "IncidentManagement|Open"
msgstr ""
+msgid "IncidentManagement|Page your team with escalation policies"
+msgstr ""
+
+msgid "IncidentManagement|Paged"
+msgstr ""
+
msgid "IncidentManagement|Published"
msgstr ""
@@ -19555,6 +19996,9 @@ msgstr ""
msgid "IncidentManagement|Severity"
msgstr ""
+msgid "IncidentManagement|Status"
+msgstr ""
+
msgid "IncidentManagement|There are no closed incidents"
msgstr ""
@@ -19573,6 +20017,9 @@ msgstr ""
msgid "IncidentManagement|Unpublished"
msgstr ""
+msgid "IncidentManagement|Use escalation policies to automatically page your team when incidents are created."
+msgstr ""
+
msgid "IncidentSettings|Activate \"time to SLA\" countdown timer"
msgstr ""
@@ -19618,7 +20065,10 @@ msgstr ""
msgid "Incidents"
msgstr ""
-msgid "Incidents|Add a URL"
+msgid "Incidents|Add image details"
+msgstr ""
+
+msgid "Incidents|Add text or a link to display with your image. If you don't add either, the file name displays instead."
msgstr ""
msgid "Incidents|Drop or %{linkStart}upload%{linkEnd} a metric screenshot to attach it to the incident"
@@ -19633,10 +20083,10 @@ msgstr ""
msgid "Incidents|There was an issue loading metric images."
msgstr ""
-msgid "Incidents|There was an issue uploading your image."
+msgid "Incidents|There was an issue updating your image."
msgstr ""
-msgid "Incidents|You can optionally add a URL to link users to the original graph."
+msgid "Incidents|There was an issue uploading your image."
msgstr ""
msgid "Incident|Alert details"
@@ -19645,9 +20095,18 @@ msgstr ""
msgid "Incident|Are you sure you wish to delete this image?"
msgstr ""
+msgid "Incident|Delete image"
+msgstr ""
+
msgid "Incident|Deleting %{filename}"
msgstr ""
+msgid "Incident|Edit image text or link"
+msgstr ""
+
+msgid "Incident|Editing %{filename}"
+msgstr ""
+
msgid "Incident|Metrics"
msgstr ""
@@ -19921,12 +20380,18 @@ msgstr ""
msgid "Integrations|Branches for which notifications are to be sent"
msgstr ""
+msgid "Integrations|Clear if using a self-signed certificate."
+msgstr ""
+
msgid "Integrations|Comment detail:"
msgstr ""
msgid "Integrations|Comment settings:"
msgstr ""
+msgid "Integrations|Connection details"
+msgstr ""
+
msgid "Integrations|Connection failed. Please check your settings."
msgstr ""
@@ -19951,6 +20416,9 @@ msgstr ""
msgid "Integrations|Enable GitLab.com slash commands in a Slack workspace."
msgstr ""
+msgid "Integrations|Enable SSL verification"
+msgstr ""
+
msgid "Integrations|Enable comments"
msgstr ""
@@ -20029,6 +20497,9 @@ msgstr ""
msgid "Integrations|Return to GitLab for Jira"
msgstr ""
+msgid "Integrations|SSL verification"
+msgstr ""
+
msgid "Integrations|Save settings?"
msgstr ""
@@ -20074,9 +20545,6 @@ msgstr ""
msgid "Integrations|Use default settings"
msgstr ""
-msgid "Integrations|When you mention a Jira issue in a commit or merge request, GitLab creates a remote link and comment (if enabled)."
-msgstr ""
-
msgid "Integrations|You can now close this window and return to the GitLab for Jira application."
msgstr ""
@@ -20101,9 +20569,6 @@ msgstr ""
msgid "Integrations|can't exceed %{recipients_limit}"
msgstr ""
-msgid "Interactive developer security education."
-msgstr ""
-
msgid "Interactive mode"
msgstr ""
@@ -20593,6 +21058,9 @@ msgstr ""
msgid "IssueAnalytics|Assignees"
msgstr ""
+msgid "IssueAnalytics|Created by"
+msgstr ""
+
msgid "IssueAnalytics|Due date"
msgstr ""
@@ -20605,9 +21073,6 @@ msgstr ""
msgid "IssueAnalytics|Milestone"
msgstr ""
-msgid "IssueAnalytics|Opened by"
-msgstr ""
-
msgid "IssueAnalytics|Status"
msgstr ""
@@ -20731,10 +21196,10 @@ msgstr ""
msgid "IssuesAnalytics|Avg/Month:"
msgstr ""
-msgid "IssuesAnalytics|Issues opened"
+msgid "IssuesAnalytics|Issues created"
msgstr ""
-msgid "IssuesAnalytics|Issues opened per month"
+msgid "IssuesAnalytics|Issues created per month"
msgstr ""
msgid "IssuesAnalytics|Last 12 months"
@@ -20761,6 +21226,9 @@ msgstr ""
msgid "It looks like you have some draft commits in this branch."
msgstr ""
+msgid "It looks like you're attempting to activate your subscription. Use %{a_start}the Subscription page%{a_end} instead."
+msgstr ""
+
msgid "It may be several days before you see feature usage data."
msgstr ""
@@ -20989,6 +21457,9 @@ msgstr ""
msgid "JiraConnect|You can now close this window and return to Jira."
msgstr ""
+msgid "JiraConnect|You don't have permission to create branches for this project. Select a different project or contact the project owner for access. %{linkStart}Learn more.%{linkEnd}"
+msgstr ""
+
msgid "JiraRequest|A connection error occurred while connecting to Jira. Try your request again."
msgstr ""
@@ -21037,13 +21508,13 @@ msgstr ""
msgid "JiraService|Define the type of Jira issue to create from a vulnerability."
msgstr ""
-msgid "JiraService|Displaying Jira issues while leaving the GitLab issue functionality enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
+msgid "JiraService|Displaying Jira issues while leaving GitLab issues also enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
msgstr ""
-msgid "JiraService|Enable Jira issues"
+msgid "JiraService|Enable Jira issue creation from vulnerabilities"
msgstr ""
-msgid "JiraService|Enable Jira issues creation from vulnerabilities"
+msgid "JiraService|Enable Jira issues"
msgstr ""
msgid "JiraService|Enable Jira transitions"
@@ -21160,16 +21631,19 @@ msgstr ""
msgid "JiraService|View Jira issues in GitLab"
msgstr ""
-msgid "JiraService|Warning: All GitLab users that have access to this GitLab project are able to view all issues from the Jira project specified below."
+msgid "JiraService|Warning: All GitLab users with access to this GitLab project can view all issues from the Jira project you select."
msgstr ""
msgid "JiraService|Web URL"
msgstr ""
-msgid "JiraService|Work on Jira issues without leaving GitLab. Adds a Jira menu to access your list of Jira issues and view any issue as read-only."
+msgid "JiraService|When a Jira issue is mentioned in a commit or merge request, a remote link and comment (if enabled) will be created."
+msgstr ""
+
+msgid "JiraService|Work on Jira issues without leaving GitLab. Add a Jira menu to access a read-only list of your Jira issues."
msgstr ""
-msgid "JiraService|You need to configure Jira before enabling this integration. For more details, read the %{jira_doc_link_start}Jira integration documentation%{link_end}."
+msgid "JiraService|You must configure Jira before enabling this integration. %{jira_doc_link_start}Learn more.%{link_end}"
msgstr ""
msgid "Job"
@@ -21181,9 +21655,6 @@ msgstr ""
msgid "Job Failed #%{build_id}"
msgstr ""
-msgid "Job ID"
-msgstr ""
-
msgid "Job artifact"
msgstr ""
@@ -21250,9 +21721,27 @@ msgstr ""
msgid "Jobs|You're about to retry a job that failed because it attempted to deploy code that is older than the latest deployment. Retrying this job could result in overwriting the environment with the older source code."
msgstr ""
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source} into %{target}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{ref}"
+msgstr ""
+
+msgid "Job|Are you sure you want to erase this job log and artifacts?"
+msgstr ""
+
msgid "Job|Browse"
msgstr ""
+msgid "Job|Cancel"
+msgstr ""
+
msgid "Job|Complete Raw"
msgstr ""
@@ -21262,6 +21751,9 @@ msgstr ""
msgid "Job|Erase job log and artifacts"
msgstr ""
+msgid "Job|Finished at"
+msgstr ""
+
msgid "Job|Job artifacts"
msgstr ""
@@ -21274,7 +21766,7 @@ msgstr ""
msgid "Job|Keep"
msgstr ""
-msgid "Job|Pipeline"
+msgid "Job|Retry"
msgstr ""
msgid "Job|Scroll to bottom"
@@ -21286,6 +21778,9 @@ msgstr ""
msgid "Job|Show complete raw"
msgstr ""
+msgid "Job|Status"
+msgstr ""
+
msgid "Job|The artifacts were removed"
msgstr ""
@@ -21313,21 +21808,12 @@ msgstr ""
msgid "Job|delayed"
msgstr ""
-msgid "Job|for"
-msgstr ""
-
-msgid "Job|into"
-msgstr ""
-
msgid "Job|manual"
msgstr ""
msgid "Job|triggered"
msgstr ""
-msgid "Job|with"
-msgstr ""
-
msgid "Join Zoom meeting"
msgstr ""
@@ -21430,9 +21916,6 @@ msgstr ""
msgid "Ki"
msgstr ""
-msgid "Kontra"
-msgstr ""
-
msgid "Kroki"
msgstr ""
@@ -21760,6 +22243,9 @@ msgstr ""
msgid "Learn more about Auto DevOps"
msgstr ""
+msgid "Learn more about GitLab"
+msgstr ""
+
msgid "Learn more about Needs relationships"
msgstr ""
@@ -22111,9 +22597,18 @@ msgstr ""
msgid "Licenses|Displays licenses detected in the project, based on the %{linkStart}latest successful%{linkEnd} scan"
msgstr ""
+msgid "Licenses|Drag your license file here or %{linkStart}click to upload%{linkEnd}."
+msgstr ""
+
+msgid "Licenses|Drop your license file to start the upload."
+msgstr ""
+
msgid "Licenses|Error fetching the license list. Please check your network connection and try again."
msgstr ""
+msgid "Licenses|Error: You are trying to upload something other than a file"
+msgstr ""
+
msgid "Licenses|License Compliance"
msgstr ""
@@ -22132,6 +22627,9 @@ msgstr ""
msgid "Licenses|Specified policies in this project"
msgstr ""
+msgid "Licenses|The file could not be uploaded."
+msgstr ""
+
msgid "Licenses|The license list details information about the licenses used within your project."
msgstr ""
@@ -22165,15 +22663,6 @@ msgstr ""
msgid "Limit the size of Sidekiq jobs stored in Redis."
msgstr ""
-msgid "Limited to showing %d event at most"
-msgid_plural "Limited to showing %d events at most"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-msgstr[3] ""
-msgstr[4] ""
-msgstr[5] ""
-
msgid "Limiting mode"
msgstr ""
@@ -22183,6 +22672,9 @@ msgstr ""
msgid "Link"
msgstr ""
+msgid "Link (optional)"
+msgstr ""
+
msgid "Link Prometheus monitoring to GitLab."
msgstr ""
@@ -22219,6 +22711,9 @@ msgstr ""
msgid "Linked emails (%{email_count})"
msgstr ""
+msgid "Linked epics"
+msgstr ""
+
msgid "Linked issues"
msgstr ""
@@ -22246,6 +22741,15 @@ msgstr ""
msgid "List of all merge commits"
msgstr ""
+msgid "List of environments for this project"
+msgstr ""
+
+msgid "List of suitable GCP locations"
+msgstr ""
+
+msgid "List of users allowed to exceed the rate limit."
+msgstr ""
+
msgid "List options"
msgstr ""
@@ -22465,6 +22969,9 @@ msgstr ""
msgid "Maintenance mode"
msgstr ""
+msgid "Make adjustments to how your GitLab instance is set up."
+msgstr ""
+
msgid "Make and review changes in the browser with the Web IDE"
msgstr ""
@@ -22609,6 +23116,12 @@ msgstr ""
msgid "MarkdownEditor|Add italic text (%{modifier_key}I)"
msgstr ""
+msgid "MarkdownEditor|Add strikethrough text (%{modifierKey}⇧X)"
+msgstr ""
+
+msgid "MarkdownEditor|Add strikethrough text (%{modifier_key}⇧X)"
+msgstr ""
+
msgid "Marked For Deletion At - %{deletion_time}"
msgstr ""
@@ -22870,6 +23383,9 @@ msgstr ""
msgid "Maximum push size (MB)"
msgstr ""
+msgid "Maximum requests per 10 minutes per user"
+msgstr ""
+
msgid "Maximum requests per minute"
msgstr ""
@@ -22960,6 +23476,27 @@ msgstr ""
msgid "Members of a group may only view projects they have permission to access"
msgstr ""
+msgid "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seat in use and will be billed for the overage."
+msgid_plural "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seats in use and will be billed for the overage."
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+msgstr[4] ""
+msgstr[5] ""
+
+msgid "MembersOverage|You are about to incur additional charges"
+msgstr ""
+
+msgid "MembersOverage|Your subscription includes %d seat."
+msgid_plural "MembersOverage|Your subscription includes %d seats."
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+msgstr[4] ""
+msgstr[5] ""
+
msgid "Membership"
msgstr ""
@@ -23164,9 +23701,6 @@ msgstr ""
msgid "Merge request not merged"
msgstr ""
-msgid "Merge request pipelines 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 merge request pipelines."
-msgstr ""
-
msgid "Merge request reports"
msgstr ""
@@ -23263,13 +23797,13 @@ msgstr ""
msgid "MergeRequests|Create issue to resolve thread"
msgstr ""
-msgid "MergeRequests|Failed to squash. Should be done manually."
+msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Saving the comment failed"
+msgid "MergeRequests|Squashing failed: Squash the commits locally, resolve any conflicts, then push the branch."
msgstr ""
-msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
+msgid "MergeRequests|Squashing not allowed: This project doesn't allow you to squash commits when merging."
msgstr ""
msgid "MergeRequests|Thread stays resolved"
@@ -24118,6 +24652,18 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "MrList|Assigned to %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from assignee %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from reviewer %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Review requested from %{name}, go to their profile."
+msgstr ""
+
msgid "Multi-project"
msgstr ""
@@ -24151,7 +24697,7 @@ msgstr ""
msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "My Awesome Group"
+msgid "My awesome group"
msgstr ""
msgid "My company or team"
@@ -24781,9 +25327,6 @@ msgstr ""
msgid "No available branches"
msgstr ""
-msgid "No available groups to fork the project."
-msgstr ""
-
msgid "No branches found"
msgstr ""
@@ -24994,6 +25537,9 @@ msgstr ""
msgid "No ref selected"
msgstr ""
+msgid "No regions configured"
+msgstr ""
+
msgid "No related merge requests found."
msgstr ""
@@ -25822,6 +26368,9 @@ msgstr ""
msgid "Only reCAPTCHA v2 is supported:"
msgstr ""
+msgid "Only required if not using role instance credentials."
+msgstr ""
+
msgid "Only use lowercase letters, numbers, and underscores."
msgstr ""
@@ -25846,9 +26395,6 @@ msgstr ""
msgid "Open a CLI and connect to the cluster you want to install the agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
-msgid "Open epics"
-msgstr ""
-
msgid "Open errors"
msgstr ""
@@ -25888,7 +26434,7 @@ msgstr ""
msgid "Opened issues"
msgstr ""
-msgid "OpenedNDaysAgo|Opened"
+msgid "OpenedNDaysAgo|Created"
msgstr ""
msgid "Opens in a new window"
@@ -25933,9 +26479,6 @@ msgstr ""
msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
-msgid "Optional."
-msgstr ""
-
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
msgstr ""
@@ -26728,6 +27271,9 @@ msgstr ""
msgid "PerformanceBar|Memory"
msgstr ""
+msgid "PerformanceBar|Memory report"
+msgstr ""
+
msgid "PerformanceBar|Redis calls"
msgstr ""
@@ -26761,18 +27307,12 @@ msgstr ""
msgid "PerformanceBar|wall"
msgstr ""
-msgid "Performs a rebase but skips triggering a new pipeline"
-msgstr ""
-
msgid "Period in seconds"
msgstr ""
msgid "Permalink"
msgstr ""
-msgid "Permanently delete project"
-msgstr ""
-
msgid "Permanently remove group"
msgstr ""
@@ -27043,6 +27583,51 @@ msgstr ""
msgid "PipelineStatusTooltip|Pipeline: %{ci_status}"
msgstr ""
+msgid "PipelineWizardDefaultCommitMessage|Add %{filename}"
+msgstr ""
+
+msgid "PipelineWizardDefaultCommitMessage|Update %{filename}"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|At least one entry is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This field is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This value is not valid"
+msgstr ""
+
+msgid "PipelineWizardListWidget|add another step"
+msgstr ""
+
+msgid "PipelineWizardListWidget|remove step"
+msgstr ""
+
+msgid "PipelineWizard|Commit"
+msgstr ""
+
+msgid "PipelineWizard|Commit Message"
+msgstr ""
+
+msgid "PipelineWizard|Commit changes to your file"
+msgstr ""
+
+msgid "PipelineWizard|Commit file to Branch"
+msgstr ""
+
+msgid "PipelineWizard|Commit your new file"
+msgstr ""
+
+msgid "PipelineWizard|The file has been committed."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem committing the changes."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem while checking whether your file already exists in the specified branch."
+msgstr ""
+
msgid "Pipelines"
msgstr ""
@@ -27157,7 +27742,7 @@ msgstr ""
msgid "Pipelines|Project cache successfully reset."
msgstr ""
-msgid "Pipelines|Revoke"
+msgid "Pipelines|Revoke trigger"
msgstr ""
msgid "Pipelines|Something went wrong while cleaning runners cache."
@@ -27202,6 +27787,12 @@ msgstr ""
msgid "Pipelines|This is a child pipeline within the parent pipeline"
msgstr ""
+msgid "Pipelines|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipelines|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipelines|This pipeline will run code originating from a forked project merge request. This means that the code can potentially have security considerations like exposing CI variables."
msgstr ""
@@ -27244,9 +27835,6 @@ msgstr ""
msgid "Pipelines|Your changes have been successfully committed. Now redirecting to the new merge request page."
msgstr ""
-msgid "Pipelines|detached"
-msgstr ""
-
msgid "Pipelines|error"
msgstr ""
@@ -27256,10 +27844,13 @@ msgstr ""
msgid "Pipelines|latest"
msgstr ""
-msgid "Pipelines|stuck"
+msgid "Pipelines|merge request"
+msgstr ""
+
+msgid "Pipelines|merge train"
msgstr ""
-msgid "Pipelines|train"
+msgid "Pipelines|stuck"
msgstr ""
msgid "Pipelines|yaml invalid"
@@ -27391,6 +27982,12 @@ msgstr ""
msgid "Pipeline|This change will not change the overall test coverage if merged."
msgstr ""
+msgid "Pipeline|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipeline|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipeline|Trigger author"
msgstr ""
@@ -27415,6 +28012,12 @@ msgstr ""
msgid "Pipeline|for"
msgstr ""
+msgid "Pipeline|merge request"
+msgstr ""
+
+msgid "Pipeline|merge train"
+msgstr ""
+
msgid "Pipeline|on"
msgstr ""
@@ -27553,9 +28156,6 @@ msgstr ""
msgid "Please enter a valid time interval"
msgstr ""
-msgid "Please enter or upload a valid license."
-msgstr ""
-
msgid "Please enter your current password."
msgstr ""
@@ -27664,9 +28264,6 @@ msgstr ""
msgid "Please type %{phrase_code} to proceed or close this modal to cancel."
msgstr ""
-msgid "Please type the following to confirm:"
-msgstr ""
-
msgid "Please use this form to report to the admin users who create spam issues, comments or behave inappropriately."
msgstr ""
@@ -27694,12 +28291,27 @@ msgstr ""
msgid "Policies"
msgstr ""
+msgid "Policy '%{escalation_policy_name}' does not exist."
+msgstr ""
+
msgid "Policy management project does have any policies in %{policy_path}"
msgstr ""
msgid "Policy project doesn't exist"
msgstr ""
+msgid "PolicyRuleMultiSelect|%{firstLabel} +%{numberOfAdditionalLabels} more"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|All %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select all"
+msgstr ""
+
msgid "Polling interval multiplier"
msgstr ""
@@ -27928,6 +28540,9 @@ msgstr ""
msgid "Private projects can be created in your personal namespace with:"
msgstr ""
+msgid "Problem with %{name} command: %{message}."
+msgstr ""
+
msgid "Proceed"
msgstr ""
@@ -28402,6 +29017,9 @@ msgstr ""
msgid "Progress"
msgstr ""
+msgid "Progress tracking"
+msgstr ""
+
msgid "Project"
msgstr ""
@@ -28633,6 +29251,9 @@ msgstr ""
msgid "ProjectQualitySummary|Failure"
msgstr ""
+msgid "ProjectQualitySummary|Get insight into the overall percentage of tests in your project that succeed, fail and are skipped."
+msgstr ""
+
msgid "ProjectQualitySummary|Latest pipeline results"
msgstr ""
@@ -28651,6 +29272,12 @@ msgstr ""
msgid "ProjectQualitySummary|See project Code Coverage Statistics"
msgstr ""
+msgid "ProjectQualitySummary|Set up test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|Set up test runs (opens in a new tab)"
+msgstr ""
+
msgid "ProjectQualitySummary|Skipped"
msgstr ""
@@ -28927,13 +29554,19 @@ msgstr ""
msgid "ProjectSettings|LFS objects from this repository are available to forks. %{linkStart}How do I remove them?%{linkEnd}"
msgstr ""
+msgid "ProjectSettings|Learn about commit history."
+msgstr ""
+
+msgid "ProjectSettings|Leave empty to use default template."
+msgstr ""
+
msgid "ProjectSettings|Manage who can see the project in the public access directory."
msgstr ""
msgid "ProjectSettings|Manages large files such as audio, video, and graphics files."
msgstr ""
-msgid "ProjectSettings|Maximum 500 characters."
+msgid "ProjectSettings|Maximum %{maxLength} characters."
msgstr ""
msgid "ProjectSettings|Merge checks"
@@ -29074,6 +29707,9 @@ msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
msgstr ""
+msgid "ProjectSettings|The default template will be applied on save."
+msgstr ""
+
msgid "ProjectSettings|These checks must pass before merge requests can be merged."
msgstr ""
@@ -29128,6 +29764,9 @@ msgstr ""
msgid "ProjectSettings|What are badges?"
msgstr ""
+msgid "ProjectSettings|What are merge trains?"
+msgstr ""
+
msgid "ProjectSettings|When merge request pipelines are enabled in the CI/CD configuration file, pipelines validate the combined results of the source and target branches. %{link_start}How to configure merge request pipelines?%{link_end}"
msgstr ""
@@ -29245,6 +29884,9 @@ msgstr ""
msgid "Projects are organized into groups"
msgstr ""
+msgid "Projects are where you store your code, access issues, wiki and other features of GitLab."
+msgstr ""
+
msgid "Projects contributed to"
msgstr ""
@@ -29260,12 +29902,6 @@ msgstr ""
msgid "Projects to index"
msgstr ""
-msgid "Projects will be permanently deleted after a %{waiting_period}-day waiting period."
-msgstr ""
-
-msgid "Projects will be permanently deleted immediately."
-msgstr ""
-
msgid "Projects with critical vulnerabilities"
msgstr ""
@@ -29350,6 +29986,9 @@ msgstr ""
msgid "ProjectsNew|Import project"
msgstr ""
+msgid "ProjectsNew|Include a Getting Started README"
+msgstr ""
+
msgid "ProjectsNew|Initialize repository with a README"
msgstr ""
@@ -29365,6 +30004,9 @@ msgstr ""
msgid "ProjectsNew|Project description %{tag_start}(optional)%{tag_end}"
msgstr ""
+msgid "ProjectsNew|Recommended if you're new to GitLab"
+msgstr ""
+
msgid "ProjectsNew|Run CI/CD for external repository"
msgstr ""
@@ -29782,6 +30424,9 @@ msgstr ""
msgid "ProtectedBranch|Unprotect"
msgstr ""
+msgid "ProtectedBranch|Unprotect branch"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
@@ -29809,6 +30454,9 @@ msgstr ""
msgid "ProtectedEnvironment|Protected Environment (%{protected_environments_count})"
msgstr ""
+msgid "ProtectedEnvironment|Required approvals"
+msgstr ""
+
msgid "ProtectedEnvironment|Select an environment"
msgstr ""
@@ -29830,10 +30478,13 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|Unprotect tag"
+msgstr ""
+
msgid "ProtectedTags|default"
msgstr ""
-msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
+msgid "ProtectedTag|By default, protected tags restrict who can modify the tag."
msgstr ""
msgid "ProtectedTag|Learn more."
@@ -29896,6 +30547,9 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Public projects are an easy way to allow everyone to have read-only access."
+msgstr ""
+
msgid "Publish to status page"
msgstr ""
@@ -30052,9 +30706,6 @@ msgstr ""
msgid "QualitySummary|Project quality"
msgstr ""
-msgid "Quarters"
-msgstr ""
-
msgid "Query"
msgstr ""
@@ -30139,6 +30790,9 @@ msgstr ""
msgid "Read more about project permissions %{help_link_open}here%{help_link_close}"
msgstr ""
+msgid "Read more about related epics"
+msgstr ""
+
msgid "Read more about related issues"
msgstr ""
@@ -30169,10 +30823,7 @@ msgstr ""
msgid "Rebase source branch on the target branch."
msgstr ""
-msgid "Rebase without CI"
-msgstr ""
-
-msgid "Rebases and triggers a pipeline"
+msgid "Rebase without pipeline"
msgstr ""
msgid "Recaptcha verified?"
@@ -30223,9 +30874,6 @@ msgstr ""
msgid "Reconfigure"
msgstr ""
-msgid "Recovering projects"
-msgstr ""
-
msgid "Recovery Codes"
msgstr ""
@@ -30289,6 +30937,12 @@ msgstr ""
msgid "Regex pattern"
msgstr ""
+msgid "Region"
+msgstr ""
+
+msgid "Regions"
+msgstr ""
+
msgid "Register"
msgstr ""
@@ -30523,9 +31177,6 @@ msgstr ""
msgid "Remove all or specific reviewer(s)"
msgstr ""
-msgid "Remove approver"
-msgstr ""
-
msgid "Remove approvers"
msgstr ""
@@ -30541,6 +31192,9 @@ msgstr ""
msgid "Remove attention request"
msgstr ""
+msgid "Remove attention request(s)"
+msgstr ""
+
msgid "Remove avatar"
msgstr ""
@@ -30679,6 +31333,9 @@ msgstr ""
msgid "Removed an issue from an epic."
msgstr ""
+msgid "Removed attention from %{users_sentence}."
+msgstr ""
+
msgid "Removed attention request from @%{username}"
msgstr ""
@@ -30730,6 +31387,9 @@ msgstr ""
msgid "Removes an issue from an epic."
msgstr ""
+msgid "Removes attention from %{users_sentence}."
+msgstr ""
+
msgid "Removes parent epic %{epic_ref}."
msgstr ""
@@ -30841,6 +31501,9 @@ msgstr ""
msgid "Report abuse to admin"
msgstr ""
+msgid "Report is generating and will be sent to your email address."
+msgstr ""
+
msgid "Reported %{timeAgo} by %{reportedBy}"
msgstr ""
@@ -31150,6 +31813,15 @@ msgstr ""
msgid "Request attention"
msgstr ""
+msgid "Request attention from %{users_sentence}."
+msgstr ""
+
+msgid "Request attention from assignee or reviewer"
+msgstr ""
+
+msgid "Request attention from assignee(s) or reviewer(s)"
+msgstr ""
+
msgid "Request attention to review"
msgstr ""
@@ -31174,6 +31846,9 @@ msgstr ""
msgid "Requested %{time_ago}"
msgstr ""
+msgid "Requested attention from %{users_sentence}."
+msgstr ""
+
msgid "Requested attention from @%{username}"
msgstr ""
@@ -31396,6 +32071,9 @@ msgstr ""
msgid "Restore project"
msgstr ""
+msgid "Restoring projects"
+msgstr ""
+
msgid "Restoring the group will prevent the group, its subgroups and projects from being removed on this date."
msgstr ""
@@ -31426,6 +32104,9 @@ msgstr ""
msgid "Retry"
msgstr ""
+msgid "Retry failed jobs"
+msgstr ""
+
msgid "Retry job"
msgstr ""
@@ -31477,9 +32158,6 @@ msgstr ""
msgid "Review changes"
msgstr ""
-msgid "Review requested from %{name}"
-msgstr ""
-
msgid "Review requests for you"
msgstr ""
@@ -31648,6 +32326,9 @@ msgstr ""
msgid "Runners|Assigned Group"
msgstr ""
+msgid "Runners|Assigned Projects (%{projectCount})"
+msgstr ""
+
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -31717,6 +32398,9 @@ msgstr ""
msgid "Runners|Instance"
msgstr ""
+msgid "Runners|Jobs"
+msgstr ""
+
msgid "Runners|Last contact"
msgstr ""
@@ -31810,9 +32494,6 @@ msgstr ""
msgid "Runners|Runner %{name} was deleted"
msgstr ""
-msgid "Runners|Runner ID"
-msgstr ""
-
msgid "Runners|Runner assigned to project."
msgstr ""
@@ -31960,6 +32641,9 @@ msgstr ""
msgid "Runners|stale"
msgstr ""
+msgid "Runner|This runner has not run any jobs."
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -32074,6 +32758,24 @@ msgstr ""
msgid "Saving project."
msgstr ""
+msgid "ScanResultPolicy|%{ifLabelStart}if%{ifLabelEnd} %{scanners} scan in an open merge request targeting the %{branches} branch(es) finds %{vulnerabilitiesAllowed} or more %{severities} vulnerabilities that are %{vulnerabilityStates}"
+msgstr ""
+
+msgid "ScanResultPolicy|%{thenLabelStart}Then%{thenLabelEnd} Require approval from %{approvalsRequired} of the following approvers: %{approvers}"
+msgstr ""
+
+msgid "ScanResultPolicy|add an approver"
+msgstr ""
+
+msgid "ScanResultPolicy|scanners"
+msgstr ""
+
+msgid "ScanResultPolicy|severity levels"
+msgstr ""
+
+msgid "ScanResultPolicy|vulnerability states"
+msgstr ""
+
msgid "Scanner"
msgstr ""
@@ -32206,6 +32908,9 @@ msgstr ""
msgid "Search for a user"
msgstr ""
+msgid "Search for an emoji"
+msgstr ""
+
msgid "Search for projects, issues, etc."
msgstr ""
@@ -32437,18 +33142,12 @@ msgstr ""
msgid "Secret Detection"
msgstr ""
-msgid "Secret access key"
-msgstr ""
-
msgid "Secret token"
msgstr ""
msgid "Secure token that identifies an external storage request."
msgstr ""
-msgid "SecureCodeWarrior"
-msgstr ""
-
msgid "Security"
msgstr ""
@@ -32473,9 +33172,6 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "Security training with guide and learning pathways."
-msgstr ""
-
msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
@@ -32578,7 +33274,7 @@ msgstr ""
msgid "SecurityConfiguration|Manage corpus"
msgstr ""
-msgid "SecurityConfiguration|Manage corpus files used as mutation sources in coverage fuzzing."
+msgid "SecurityConfiguration|Manage corpus files used as seed inputs with coverage-guided fuzzing."
msgstr ""
msgid "SecurityConfiguration|Manage profiles for use by DAST scans."
@@ -32644,15 +33340,15 @@ msgstr ""
msgid "SecurityOrchestration|.yaml preview"
msgstr ""
-msgid "SecurityOrchestration|Action"
-msgstr ""
-
msgid "SecurityOrchestration|Actions"
msgstr ""
msgid "SecurityOrchestration|Add rule"
msgstr ""
+msgid "SecurityOrchestration|After dismissing the alert, the information will never be shown again."
+msgstr ""
+
msgid "SecurityOrchestration|All policies"
msgstr ""
@@ -32668,7 +33364,7 @@ msgstr ""
msgid "SecurityOrchestration|Description"
msgstr ""
-msgid "SecurityOrchestration|Disabled"
+msgid "SecurityOrchestration|Don't show the alert anymore"
msgstr ""
msgid "SecurityOrchestration|Edit policy"
@@ -32677,13 +33373,13 @@ msgstr ""
msgid "SecurityOrchestration|Edit policy project"
msgstr ""
-msgid "SecurityOrchestration|Enabled"
+msgid "SecurityOrchestration|Empty policy name"
msgstr ""
-msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Enabled"
msgstr ""
-msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
msgstr ""
msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
@@ -32692,7 +33388,7 @@ msgstr ""
msgid "SecurityOrchestration|Invalid policy type"
msgstr ""
-msgid "SecurityOrchestration|Latest scan"
+msgid "SecurityOrchestration|Latest scan run against %{agent}"
msgstr ""
msgid "SecurityOrchestration|Network"
@@ -32701,15 +33397,27 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No actions defined - policy will not run."
+msgstr ""
+
+msgid "SecurityOrchestration|No description"
+msgstr ""
+
msgid "SecurityOrchestration|No rules defined - policy will not run."
msgstr ""
+msgid "SecurityOrchestration|Not enabled"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
msgid "SecurityOrchestration|Policies"
msgstr ""
+msgid "SecurityOrchestration|Policy Type"
+msgstr ""
+
msgid "SecurityOrchestration|Policy cannot be enabled for non-existing branches (%{branches})"
msgstr ""
@@ -32734,10 +33442,13 @@ msgstr ""
msgid "SecurityOrchestration|Require %{approvals} %{plural} from %{approvers} if any of the following occur:"
msgstr ""
-msgid "SecurityOrchestration|Rule"
+msgid "SecurityOrchestration|Rules"
msgstr ""
-msgid "SecurityOrchestration|Rules"
+msgid "SecurityOrchestration|Runs %{actions} and %{lastAction} scans"
+msgstr ""
+
+msgid "SecurityOrchestration|Runs a %{action} scan"
msgstr ""
msgid "SecurityOrchestration|Scan Execution"
@@ -32797,6 +33508,9 @@ msgstr ""
msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
+msgid "SecurityOrchestration|This view only shows scan results for the agent %{agent}. You can view scan results for all agents in the %{linkStart}Operational Vulnerabilities tab of the vulnerability report%{linkEnd}."
+msgstr ""
+
msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
@@ -32851,9 +33565,6 @@ msgstr ""
msgid "SecurityOrchestration|users with ids"
msgstr ""
-msgid "SecurityOrchestration|view results"
-msgstr ""
-
msgid "SecurityOrchestration|vulnerabilities"
msgstr ""
@@ -33523,22 +34234,19 @@ 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|In order to start using functions as a service, you must first install Knative on your Kubernetes cluster. %{linkStart}More information%{linkEnd}"
-msgstr ""
-
msgid "Serverless|Learn more about Serverless"
msgstr ""
msgid "Serverless|No functions available"
msgstr ""
-msgid "Serverless|Sign up for First Look"
+msgid "Serverless|Serverless was %{linkStart}deprecated%{linkEnd} in GitLab 14.3."
+msgstr ""
+
+msgid "Serverless|Serverless was %{postLinkStart}deprecated%{postLinkEnd}. But if you opt to use it, you must install Knative in your Kubernetes cluster first. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "Serverless|The deploy job has not finished."
@@ -33550,9 +34258,6 @@ 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 ""
@@ -33568,9 +34273,6 @@ msgstr ""
msgid "Service Account Key"
msgstr ""
-msgid "Service Accounts"
-msgstr ""
-
msgid "Service Accounts keys authorize GitLab to deploy your Google Cloud project"
msgstr ""
@@ -33580,10 +34282,10 @@ msgstr ""
msgid "Service Desk allows people to create issues in your GitLab instance without their own user account. It provides a unique email address for end users to create issues in a project. Replies can be sent either through the GitLab interface or by email. End users only see threads through email."
msgstr ""
-msgid "Service Usage Data"
+msgid "Service account generated successfully"
msgstr ""
-msgid "Service account generated successfully"
+msgid "Service accounts"
msgstr ""
msgid "Service ping is disabled in your configuration file, and cannot be enabled through this form."
@@ -33727,6 +34429,9 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
+msgid "Set the per-user rate limit for getting a user by ID via the API."
+msgstr ""
+
msgid "Set the per-user rate limit for notes created by web or API requests."
msgstr ""
@@ -33910,6 +34615,9 @@ msgstr ""
msgid "Shared runners details"
msgstr ""
+msgid "Shared runners enabled cannot be enabled until a valid credit card is on file"
+msgstr ""
+
msgid "Shared runners help link"
msgstr ""
@@ -33967,6 +34675,9 @@ msgstr ""
msgid "Show all issues."
msgstr ""
+msgid "Show all milestones"
+msgstr ""
+
msgid "Show all test cases."
msgstr ""
@@ -34003,6 +34714,9 @@ msgstr ""
msgid "Show file contents"
msgstr ""
+msgid "Show group milestones"
+msgstr ""
+
msgid "Show labels"
msgstr ""
@@ -34018,6 +34732,12 @@ msgstr ""
msgid "Show open epics"
msgstr ""
+msgid "Show project milestones"
+msgstr ""
+
+msgid "Show sub-group milestones"
+msgstr ""
+
msgid "Show the Closed list"
msgstr ""
@@ -34027,15 +34747,6 @@ msgstr ""
msgid "Show whitespace changes"
msgstr ""
-msgid "Showing %d event"
-msgid_plural "Showing %d events"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-msgstr[3] ""
-msgstr[4] ""
-msgstr[5] ""
-
msgid "Showing %{conflict} between %{sourceBranch} and %{targetBranch}"
msgstr ""
@@ -34099,12 +34810,6 @@ msgstr ""
msgid "Sidebar|None"
msgstr ""
-msgid "Sidebar|Only numeral characters allowed"
-msgstr ""
-
-msgid "Sidebar|Weight"
-msgstr ""
-
msgid "Sidekiq job compression threshold (bytes)"
msgstr ""
@@ -34267,6 +34972,9 @@ msgstr ""
msgid "Slack logo"
msgstr ""
+msgid "SlackIntegration|Are you sure you want to remove this project from the Slack application?"
+msgstr ""
+
msgid "SlackIntegration|GitLab for Slack"
msgstr ""
@@ -34276,6 +34984,9 @@ msgstr ""
msgid "SlackIntegration|Project alias"
msgstr ""
+msgid "SlackIntegration|Remove project"
+msgstr ""
+
msgid "SlackIntegration|Select a GitLab project to link with your Slack workspace."
msgstr ""
@@ -34420,9 +35131,6 @@ msgstr ""
msgid "Something went wrong trying to load issue contacts."
msgstr ""
-msgid "Something went wrong when creating a work item. Please try again"
-msgstr ""
-
msgid "Something went wrong when reordering designs. Please try again"
msgstr ""
@@ -34516,9 +35224,6 @@ msgstr ""
msgid "Something went wrong while inserting your image. Please try again."
msgstr ""
-msgid "Something went wrong while merging this merge request. Please try again."
-msgstr ""
-
msgid "Something went wrong while obtaining the Let's Encrypt certificate."
msgstr ""
@@ -34840,10 +35545,10 @@ 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."
+msgid "SourcegraphAdmin|Learn more."
msgstr ""
-msgid "SourcegraphAdmin|More information"
+msgid "SourcegraphAdmin|Only public projects have code intelligence enabled and communicate with Sourcegraph."
msgstr ""
msgid "SourcegraphAdmin|Save changes"
@@ -34852,7 +35557,7 @@ msgstr ""
msgid "SourcegraphAdmin|Sourcegraph URL"
msgstr ""
-msgid "SourcegraphAdmin|e.g. https://sourcegraph.example.com"
+msgid "SourcegraphAdmin|https://sourcegraph.example.com"
msgstr ""
msgid "SourcegraphPreferences|This feature is experimental and currently limited to certain projects."
@@ -34987,6 +35692,9 @@ msgstr ""
msgid "Start date"
msgstr ""
+msgid "Start free trial"
+msgstr ""
+
msgid "Start merge train"
msgstr ""
@@ -35017,6 +35725,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started escalation for this incident."
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -35029,6 +35740,9 @@ msgstr ""
msgid "Starts at (UTC)"
msgstr ""
+msgid "Starts escalations for this incident"
+msgstr ""
+
msgid "Starts on"
msgstr ""
@@ -35290,6 +36004,9 @@ msgstr ""
msgid "Strikethrough"
msgstr ""
+msgid "Strikethrough text"
+msgstr ""
+
msgid "Subgroup information"
msgstr ""
@@ -35524,6 +36241,21 @@ msgstr ""
msgid "Subscriptions"
msgstr ""
+msgid "Subscriptions|Chat with sales"
+msgstr ""
+
+msgid "Subscriptions|Close"
+msgstr ""
+
+msgid "Subscriptions|Not ready to buy yet?"
+msgstr ""
+
+msgid "Subscriptions|Start a free trial"
+msgstr ""
+
+msgid "Subscriptions|We understand. Maybe you have some questions for our sales team, or maybe you'd like to try some of the paid features first. What would you like to do?"
+msgstr ""
+
msgid "Subscription|Your subscription for %{strong}%{namespace_name}%{strong_close} has expired and you are now on %{pricing_link_start}the GitLab Free tier%{pricing_link_end}. Don't worry, your data is safe. Get in touch with our support team (%{support_email}). They'll gladly help with your subscription renewal."
msgstr ""
@@ -35734,6 +36466,9 @@ msgstr ""
msgid "SuperSonics|Maximum users"
msgstr ""
+msgid "SuperSonics|Offline cloud"
+msgstr ""
+
msgid "SuperSonics|Paste your activation code"
msgstr ""
@@ -35800,6 +36535,12 @@ msgstr ""
msgid "SuperSonics|You do not have an active subscription"
msgstr ""
+msgid "SuperSonics|You have a future dated license"
+msgstr ""
+
+msgid "SuperSonics|You have added a license that activates on %{date}. Please see the subscription history table below for more details."
+msgstr ""
+
msgid "SuperSonics|You have successfully added a license that activates on %{date}. Please see the subscription history table below for more details."
msgstr ""
@@ -35959,6 +36700,9 @@ msgstr ""
msgid "Tag name is required"
msgstr ""
+msgid "Tag push"
+msgstr ""
+
msgid "Tag push events"
msgstr ""
@@ -36061,6 +36805,9 @@ msgstr ""
msgid "TagsPage|protected"
msgstr ""
+msgid "Take a look at the documentation to discover all of GitLab’s capabilities."
+msgstr ""
+
msgid "Target Branch"
msgstr ""
@@ -36487,6 +37234,9 @@ msgstr ""
msgid "Tests"
msgstr ""
+msgid "Text (optional)"
+msgstr ""
+
msgid "Text added to the body of all email messages. %{character_limit} character limit"
msgstr ""
@@ -36541,6 +37291,9 @@ msgstr ""
msgid "The CSV export will be created in the background. Once finished, it will be sent to %{email} in an attachment."
msgstr ""
+msgid "The CSV export you requested of all user memberships is attached to this email."
+msgstr ""
+
msgid "The GitLab subscription service (customers.gitlab.com) is currently experiencing an outage. You can monitor the status and get updates at %{linkStart}status.gitlab.com%{linkEnd}."
msgstr ""
@@ -36616,6 +37369,9 @@ 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 epic"
+msgstr ""
+
msgid "The current issue"
msgstr ""
@@ -36781,6 +37537,9 @@ msgstr ""
msgid "The latest pipeline for this merge request has failed."
msgstr ""
+msgid "The license key is invalid."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -36796,6 +37555,9 @@ msgstr ""
msgid "The license was successfully uploaded and will be active from %{starts_at}. You can see the details below."
msgstr ""
+msgid "The license you uploaded is invalid. If the issue persists, contact support at %{link}."
+msgstr ""
+
msgid "The list creation wizard is already open"
msgstr ""
@@ -37417,10 +38179,13 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} and everything this project contains. %{strongOpen}There is no going back%{strongClose}"
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}on %{date}%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains."
+msgstr ""
+
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains. %{strongOpen}There is no going back.%{strongClose}"
msgstr ""
msgid "This action will %{strongOpen}permanently remove%{strongClose} %{codeOpen}%{group}%{codeClose} %{strongOpen}immediately%{strongClose}."
@@ -37549,9 +38314,6 @@ msgstr ""
msgid "This file was modified for readability, and can't accept suggestions. Edit it directly."
msgstr ""
-msgid "This forked project has the following:"
-msgstr ""
-
msgid "This form is disabled in preview"
msgstr ""
@@ -37564,7 +38326,7 @@ msgstr ""
msgid "This group can't be removed because it is linked to a subscription. To remove this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
-msgid "This group can't be transfered because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
+msgid "This group can't be transferred because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
msgid "This group cannot be invited to a project inside a group with enforced SSO"
@@ -37591,6 +38353,9 @@ 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 incident is already escalated with '%{escalation_policy_name}'."
+msgstr ""
+
msgid "This invitation was sent to %{mail_to_invite_email}, but you are signed in as %{link_to_current_user} with email %{mail_to_current_user}."
msgstr ""
@@ -37609,9 +38374,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 merge train pipeline"
-msgstr ""
-
msgid "This is a private email address %{helpIcon} generated just for you. Anyone who has it can create issues or merge requests as if they were you. If that happens, %{resetLinkStart}reset this token%{resetLinkEnd}."
msgstr ""
@@ -37633,6 +38395,12 @@ msgstr ""
msgid "This is your current session"
msgstr ""
+msgid "This issue cannot be assigned to a confidential epic because it is public."
+msgstr ""
+
+msgid "This issue cannot be made public because it belongs to a confidential epic."
+msgstr ""
+
msgid "This issue is confidential and should only be visible to team members with at least Reporter access."
msgstr ""
@@ -37750,6 +38518,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 branch is protected from force push."
+msgstr ""
+
msgid "This merge request cannot be rebased while there are conflicts."
msgstr ""
@@ -37801,9 +38572,15 @@ msgstr ""
msgid "This pipeline was triggered by a schedule."
msgstr ""
+msgid "This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project"
msgstr ""
+msgid "This project can be restored until %{date}."
+msgstr ""
+
msgid "This project cannot be %{visibilityLevel} because the visibility of %{openShowLink}%{name}%{closeShowLink} is %{visibility}. To make this project %{visibilityLevel}, you must first %{openEditLink}change the visibility%{closeEditLink} of the parent group."
msgstr ""
@@ -37822,6 +38599,9 @@ msgstr ""
msgid "This project is %{strongStart}NOT%{strongEnd} a fork, and has the following:"
msgstr ""
+msgid "This project is %{strongStart}NOT%{strongEnd} a fork. This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -38521,6 +39301,9 @@ msgstr ""
msgid "Today"
msgstr ""
+msgid "Todos count"
+msgstr ""
+
msgid "Todos|Are you looking for things to do? Take a look at %{strongStart}%{openIssuesLinkStart}open issues%{openIssuesLinkEnd}%{strongEnd}, contribute to %{strongStart}%{mergeRequestLinkStart}a merge request%{mergeRequestLinkEnd}%{mergeRequestLinkEnd}%{strongEnd}, or mention someone in a comment to automatically assign them a new to-do item."
msgstr ""
@@ -38794,14 +39577,8 @@ msgstr ""
msgid "Trending"
msgstr ""
-msgid "Trials|%{planName} Trial %{enDash} %{num} day left"
-msgid_plural "Trials|%{planName} Trial %{enDash} %{num} days left"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-msgstr[3] ""
-msgstr[4] ""
-msgstr[5] ""
+msgid "Trials|%{planName} Trial"
+msgstr ""
msgid "Trials|Compare all plans"
msgstr ""
@@ -38809,6 +39586,9 @@ msgstr ""
msgid "Trials|Create a new group to start your GitLab Ultimate trial."
msgstr ""
+msgid "Trials|Day %{daysUsed}/%{duration}"
+msgstr ""
+
msgid "Trials|Go back to GitLab"
msgstr ""
@@ -39058,7 +39838,7 @@ msgstr ""
msgid "URL is triggered when repository is updated"
msgstr ""
-msgid "URL must be percent-encoded if neccessary."
+msgid "URL must be percent-encoded if necessary."
msgstr ""
msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
@@ -39277,6 +40057,9 @@ msgstr ""
msgid "Unlock account"
msgstr ""
+msgid "Unlock more features with GitLab Ultimate"
+msgstr ""
+
msgid "Unlock the discussion"
msgstr ""
@@ -39340,6 +40123,9 @@ msgstr ""
msgid "Unsubscribes from this %{quick_action_target}."
msgstr ""
+msgid "Unsupported sort value."
+msgstr ""
+
msgid "Unsupported todo type passed. Supported todo types are: %{todo_types}"
msgstr ""
@@ -39568,6 +40354,9 @@ msgstr ""
msgid "UsageQuota|File attachments and smaller design graphics."
msgstr ""
+msgid "UsageQuota|From %{storage_enforcement_date} storage limits will apply to this namespace. View and manage your usage in %{strong_start}Group Settings &gt; Usage quotas%{strong_end}."
+msgstr ""
+
msgid "UsageQuota|Git repository."
msgstr ""
@@ -39628,6 +40417,9 @@ msgstr ""
msgid "UsageQuota|Storage type"
msgstr ""
+msgid "UsageQuota|Storage used"
+msgstr ""
+
msgid "UsageQuota|This is the total amount of storage used across your projects within this namespace."
msgstr ""
@@ -39823,6 +40615,12 @@ msgstr ""
msgid "Use hashed storage paths for newly created and renamed repositories. Always enabled since 13.0."
msgstr ""
+msgid "Use issue count"
+msgstr ""
+
+msgid "Use issue weight"
+msgstr ""
+
msgid "Use one line per URI"
msgstr ""
@@ -40204,6 +41002,9 @@ msgstr ""
msgid "Users"
msgstr ""
+msgid "Users API rate limit"
+msgstr ""
+
msgid "Users can launch a development environment from a GitLab browser tab when the %{linkStart}Gitpod%{linkEnd} integration is enabled."
msgstr ""
@@ -40537,6 +41338,9 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View group pipeline usage quota"
+msgstr ""
+
msgid "View incident details at"
msgstr ""
@@ -40693,6 +41497,9 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
+msgid "Vulnerability"
+msgstr ""
+
msgid "Vulnerability Report"
msgstr ""
@@ -40744,6 +41551,9 @@ msgstr ""
msgid "VulnerabilityManagement|An unverified non-confirmed finding"
msgstr ""
+msgid "VulnerabilityManagement|At least one identifier is required"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -40753,12 +41563,24 @@ msgstr ""
msgid "VulnerabilityManagement|Create Jira issue"
msgstr ""
+msgid "VulnerabilityManagement|Enter a name"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE code"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE identifier URL"
+msgstr ""
+
msgid "VulnerabilityManagement|Fetching linked Jira issues"
msgstr ""
msgid "VulnerabilityManagement|Manually add a vulnerability entry into the vulnerability report."
msgstr ""
+msgid "VulnerabilityManagement|Name is a required field"
+msgstr ""
+
msgid "VulnerabilityManagement|Needs triage"
msgstr ""
@@ -40774,6 +41596,18 @@ msgstr ""
msgid "VulnerabilityManagement|Select a method"
msgstr ""
+msgid "VulnerabilityManagement|Select a severity level"
+msgstr ""
+
+msgid "VulnerabilityManagement|Select a status"
+msgstr ""
+
+msgid "VulnerabilityManagement|Severity is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Something went wrong while creating vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -40798,6 +41632,12 @@ msgstr ""
msgid "VulnerabilityManagement|Something went wrong, could not update vulnerability state."
msgstr ""
+msgid "VulnerabilityManagement|Status is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Submit vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Summary, detailed description, steps to reproduce, etc."
msgstr ""
@@ -40993,6 +41833,9 @@ msgstr ""
msgid "WARNING:"
msgstr ""
+msgid "WARNING: This snippet contains hidden files which might be used to mask malicious behavior. Exercise caution if cloning and executing code from this snippet."
+msgstr ""
+
msgid "Wait for the file to load to copy its contents"
msgstr ""
@@ -41212,6 +42055,15 @@ msgstr ""
msgid "Webhooks|An issue is created, updated, closed, or reopened."
msgstr ""
+msgid "Webhooks|Are you sure you want to delete this group hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this project hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this webhook?"
+msgstr ""
+
msgid "Webhooks|Comments"
msgstr ""
@@ -41221,6 +42073,9 @@ msgstr ""
msgid "Webhooks|Confidential issues events"
msgstr ""
+msgid "Webhooks|Delete webhook"
+msgstr ""
+
msgid "Webhooks|Deployment events"
msgstr ""
@@ -41458,6 +42313,9 @@ msgstr ""
msgid "Wiki"
msgstr ""
+msgid "Wiki page"
+msgstr ""
+
msgid "Wiki page was successfully created."
msgstr ""
@@ -41563,7 +42421,7 @@ msgstr ""
msgid "WikiPageConflictMessage|Someone edited the page the same time you did. Please check out %{wikiLinkStart}the page%{wikiLinkEnd} and make sure your changes will not unintentionally remove theirs."
msgstr ""
-msgid "WikiPage|An error occured while trying to render the content editor. Please try again later."
+msgid "WikiPage|An error occurred while trying to render the content editor. Please try again later."
msgstr ""
msgid "WikiPage|Are you sure you want to switch back to the classic editor?"
@@ -41722,6 +42580,18 @@ msgstr ""
msgid "WorkItem|New Task"
msgstr ""
+msgid "WorkItem|Something went wrong when creating a work item. Please try again"
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching the work item. Please try again."
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching work item types. Please try again"
+msgstr ""
+
+msgid "WorkItem|Type"
+msgstr ""
+
msgid "WorkItem|Work Items"
msgstr ""
@@ -41788,7 +42658,10 @@ msgstr ""
msgid "You are about to add %{usersTag} people to the discussion. They will all receive a notification."
msgstr ""
-msgid "You are about to permanently delete this project"
+msgid "You are about to delete this forked project containing:"
+msgstr ""
+
+msgid "You are about to delete this project containing:"
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."
@@ -41809,6 +42682,9 @@ msgstr ""
msgid "You are attempting to update a file that has changed since you started editing it."
msgstr ""
+msgid "You are billed if you exceed this number. %{qsrOverageLinkStart}How does billing work?%{qsrOverageLinkEnd}"
+msgstr ""
+
msgid "You are connected to the Prometheus server, but there is currently no data to display."
msgstr ""
@@ -41866,6 +42742,9 @@ msgstr ""
msgid "You are not authorized to update this scanner profile"
msgstr ""
+msgid "You are not authorized to upload metric images"
+msgstr ""
+
msgid "You are now impersonating %{username}"
msgstr ""
@@ -42019,9 +42898,6 @@ msgstr ""
msgid "You can only upload one design when dropping onto an existing design."
msgstr ""
-msgid "You can recover this project until %{date}"
-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 ""
@@ -42070,9 +42946,6 @@ msgstr ""
msgid "You cannot write to this read-only GitLab instance."
msgstr ""
-msgid "You can’t %{tag_start}edit%{tag_end} files directly in this project. Fork this project and submit a merge request with your changes."
-msgstr ""
-
msgid "You can’t edit files directly in this project. Fork this project and submit a merge request with your changes."
msgstr ""
@@ -42229,9 +43102,6 @@ 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 set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
@@ -42262,12 +43132,6 @@ msgstr ""
msgid "You must have maintainer access to force delete a lock"
msgstr ""
-msgid "You must have permission to create a project in a group before forking."
-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 ""
@@ -42673,7 +43537,7 @@ msgstr ""
msgid "Your public email will be displayed on your public profile."
msgstr ""
-msgid "Your request for access could not be processed: %{error_meesage}"
+msgid "Your request for access could not be processed: %{error_message}"
msgstr ""
msgid "Your request for access has been queued for review."
@@ -42868,6 +43732,9 @@ msgstr ""
msgid "archived:"
msgstr ""
+msgid "artifacts"
+msgstr ""
+
msgid "assign yourself"
msgstr ""
@@ -42901,6 +43768,9 @@ msgstr[5] ""
msgid "branch name"
msgstr ""
+msgid "builds"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -43336,6 +44206,9 @@ msgstr ""
msgid "contact with same email already exists in group hierarchy"
msgstr ""
+msgid "container registry images"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -43375,6 +44248,9 @@ msgstr ""
msgid "data"
msgstr ""
+msgid "database"
+msgstr ""
+
msgid "date must not be after 9999-12-31"
msgstr ""
@@ -43402,9 +44278,6 @@ msgstr ""
msgid "design"
msgstr ""
-msgid "detached"
-msgstr ""
-
msgid "disabled"
msgstr ""
@@ -43669,7 +44542,7 @@ msgstr ""
msgid "is not a valid X509 certificate."
msgstr ""
-msgid "is not allowed for sign-up."
+msgid "is not allowed for sign-up. Please use your regular email address."
msgstr ""
msgid "is not allowed for this group."
@@ -43681,7 +44554,7 @@ msgstr ""
msgid "is not allowed since the group is not top-level group."
msgstr ""
-msgid "is not allowed."
+msgid "is not allowed. Please use your regular email address."
msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
@@ -43768,6 +44641,9 @@ msgstr ""
msgid "level: %{level}"
msgstr ""
+msgid "lfs objects"
+msgstr ""
+
msgid "limit of %{project_limit} reached"
msgstr ""
@@ -43999,6 +44875,9 @@ msgstr ""
msgid "mrWidget|Merge blocked: pipeline must succeed. It's waiting for a manual action to continue."
msgstr ""
+msgid "mrWidget|Merge blocked: pipeline must succeed. Push a commit that fixes the failure, or %{linkStart}learn about other solutions.%{linkEnd}"
+msgstr ""
+
msgid "mrWidget|Merge blocked: this merge request must be approved."
msgstr ""
@@ -44116,9 +44995,6 @@ msgstr ""
msgid "mrWidget|The changes were not merged into"
msgstr ""
-msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -44266,9 +45142,6 @@ msgstr ""
msgid "open issue"
msgstr ""
-msgid "opened %{timeAgo}"
-msgstr ""
-
msgid "or"
msgstr ""
@@ -44284,6 +45157,12 @@ msgstr[3] ""
msgstr[4] ""
msgstr[5] ""
+msgid "packages"
+msgstr ""
+
+msgid "pages"
+msgstr ""
+
msgid "parent"
msgid_plural "parents"
msgstr[0] ""
@@ -44449,6 +45328,9 @@ msgstr[3] ""
msgstr[4] ""
msgstr[5] ""
+msgid "repositories"
+msgstr ""
+
msgid "repository:"
msgstr ""
@@ -44569,12 +45451,18 @@ msgstr ""
msgid "tag name"
msgstr ""
+msgid "terraform states"
+msgstr ""
+
msgid "the correct format."
msgstr ""
msgid "the file"
msgstr ""
+msgid "the following epic(s)"
+msgstr ""
+
msgid "the following issue(s)"
msgstr ""
@@ -44587,21 +45475,12 @@ msgstr ""
msgid "this document"
msgstr ""
-msgid "this issue cannot be assigned to a confidential epic since it is public"
-msgstr ""
-
-msgid "this issue cannot be made public since it belongs to a confidential epic"
-msgstr ""
-
msgid "time summary"
msgstr ""
msgid "toggle collapse"
msgstr ""
-msgid "train"
-msgstr ""
-
msgid "triggered"
msgstr ""
@@ -44734,3 +45613,6 @@ msgstr ""
msgid "{project}"
msgstr ""
+msgid "✔"
+msgstr ""
+
diff --git a/locale/da_DK/gitlab.po b/locale/da_DK/gitlab.po
index 7e06ad33c13..2d54be5fbf3 100644
--- a/locale/da_DK/gitlab.po
+++ b/locale/da_DK/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: da\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2022-02-02 15:45\n"
+"PO-Revision-Date: 2022-03-01 20:38\n"
msgid " %{start} to %{end}"
msgstr " %{start} til %{end}"
@@ -146,6 +146,11 @@ msgid_plural "%d approvers (you've approved)"
msgstr[0] "%d godkender (som du har godkendt)"
msgstr[1] "%d godkendere (som du har godkendt)"
+msgid "%d assigned issue"
+msgid_plural "%d assigned issues"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] "%d ændret fil"
@@ -421,10 +426,25 @@ msgid_plural "%d vulnerabilities dismissed"
msgstr[0] "%d sårbarhed afskediget"
msgstr[1] "%d sårbarheder afskediget"
-msgid "%d vulnerability updated"
-msgid_plural "%d vulnerabilities updated"
-msgstr[0] "%d sårbarhed opdateret"
-msgstr[1] "%d sårbarheder opdateret"
+msgid "%d vulnerability set to confirmed"
+msgid_plural "%d vulnerabilities set to confirmed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to dismissed"
+msgid_plural "%d vulnerabilities set to dismissed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to needs triage"
+msgid_plural "%d vulnerabilities set to needs triage"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to resolved"
+msgid_plural "%d vulnerabilities set to resolved"
+msgstr[0] ""
+msgstr[1] ""
msgid "%d warning found:"
msgid_plural "%d warnings found:"
@@ -510,6 +530,12 @@ msgstr[1] "%{completedCount} af %{count} opgaver fuldført"
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr "%{completedWeight} af %{totalWeight} vægt fuldført"
+msgid "%{completed} of %{total} issues closed"
+msgstr ""
+
+msgid "%{completed} of %{total} weight completed"
+msgstr ""
+
msgid "%{cores} cores"
msgstr "%{cores} kerner"
@@ -858,6 +884,9 @@ msgstr "%{openedEpics} åbne, %{closedEpics} lukkede"
msgid "%{openedIssues} open, %{closedIssues} closed"
msgstr "%{openedIssues} åbne, %{closedIssues} lukkede"
+msgid "%{percentage}%% issues closed"
+msgstr ""
+
msgid "%{percentage}%% weight completed"
msgstr "%{percentage} %% vægt fuldført"
@@ -1287,6 +1316,9 @@ msgid_plural "- Users"
msgstr[0] "- Bruger"
msgstr[1] "- Brugere"
+msgid "- of - issues closed"
+msgstr ""
+
msgid "- of - weight completed"
msgstr "- af - vægt fuldført"
@@ -1429,8 +1461,8 @@ msgstr "10-19 bidrag"
msgid "1000+"
msgstr "1000+"
-msgid "192.168.0.0/24"
-msgstr "192.168.0.0/24"
+msgid "192.168.0.0/24 or 2001:0DB8:1234::/48"
+msgstr ""
msgid "1st contribution!"
msgstr "Første bidrag!"
@@ -1741,13 +1773,13 @@ msgstr "mappe/openapi.json"
msgid "AWS Access Key"
msgstr ""
-msgid "AWS Access Key. Only required if not using role instance credentials"
+msgid "AWS Secret Access Key"
msgstr ""
-msgid "AWS Secret Access Key"
+msgid "AWS access key ID (Optional)"
msgstr ""
-msgid "AWS Secret Access Key. Only required if not using role instance credentials"
+msgid "AWS secret access key (Optional)"
msgstr ""
msgid "AWS service error: %{error}"
@@ -1807,9 +1839,6 @@ msgstr "Adgang forbudt. Tjek dit adgangsniveau."
msgid "Access granted"
msgstr "Adgang givet"
-msgid "Access key ID"
-msgstr "Adgangsnøgle-id"
-
msgid "Access requests"
msgstr "Adgangsanmodninger"
@@ -1984,8 +2013,8 @@ msgstr ""
msgid "Activity"
msgstr "Aktivitet"
-msgid "Activity|An error occured while retrieving activity. Reload the page to try again."
-msgstr "Der opstod en fejl under indhentning af aktiviteter. Genindlæs siden for at prøve igen."
+msgid "Activity|An error occurred while retrieving activity. Reload the page to try again."
+msgstr ""
msgid "Add"
msgstr "Tilføj"
@@ -2023,6 +2052,9 @@ msgstr "Tilføj Zoom-møde"
msgid "Add a %{type}"
msgstr "Tilføj en %{type}"
+msgid "Add a GCP region"
+msgstr ""
+
msgid "Add a GPG key"
msgstr "Tilføj en GPG-nøgle"
@@ -2074,6 +2106,9 @@ msgstr "Tilføj en ny problemstilling"
msgid "Add a numbered list"
msgstr "Tilføj en nummereret liste"
+msgid "Add a related epic"
+msgstr ""
+
msgid "Add a related issue"
msgstr "Tilføj en relateret problemstilling"
@@ -2188,6 +2223,9 @@ msgstr "Tilføj eller fjern commits, som tidligere er blevet sammenlagt"
msgid "Add or subtract spent time"
msgstr "Tilføj eller fratræk brugt tid"
+msgid "Add people"
+msgstr ""
+
msgid "Add previously merged commits"
msgstr "Tilføj commits, som tidligere er blevet sammenlagt"
@@ -2254,6 +2292,9 @@ msgstr ""
msgid "Add webhook"
msgstr "Tilføj webhook"
+msgid "Add your team members and others to GitLab."
+msgstr ""
+
msgid "Add/remove"
msgstr "Tilføj/fjern"
@@ -3076,12 +3117,6 @@ msgstr ""
msgid "AdvancedSearch|Reindex required"
msgstr ""
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. Permanently deleting this project will %{strongStart}immediately delete%{strongEnd} its repositories and %{strongStart}all related resources%{strongEnd}, including issues, merge requests etc."
-msgstr ""
-
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. You will lose this project's repository and %{strongStart}all related resources%{strongEnd}, including issues and merge requests."
-msgstr ""
-
msgid "After a successful password update you will be redirected to login screen."
msgstr "Efter adgangskoden er blevet opdateret vil du blive omdirigeret til indlogningsskærmen."
@@ -3112,6 +3147,9 @@ msgstr "Akismet API-nøgle"
msgid "Akismet helps prevent the creation of spam issues in public projects."
msgstr ""
+msgid "Alert"
+msgstr ""
+
msgid "AlertManagement|Acknowledged"
msgstr "Tilkendegivet"
@@ -3484,9 +3522,6 @@ msgstr "Alle e-mailadresser vil blive brugt til at identificere dine commits."
msgid "All environments"
msgstr "Alle miljøer"
-msgid "All epics"
-msgstr "Alle epics"
-
msgid "All groups and projects"
msgstr "Alle grupper og projekter"
@@ -4223,12 +4258,15 @@ msgstr ""
msgid "ApplicationSettings|Approve users in the pending approval status?"
msgstr "Godkend brugere med statussen afventer godkendelse?"
-msgid "ApplicationSettings|By making this change, you will automatically approve %d user with the pending approval status."
-msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users with the pending approval status."
-msgstr[0] "Ved at foretage ændringen godkender du automatisk %d bruger med statussen afventer godkendelse."
-msgstr[1] "Ved at foretage ændringen godkender du automatisk %d brugere med statussen afventer godkendelse."
+msgid "ApplicationSettings|Approve users who are pending approval?"
+msgstr ""
-msgid "ApplicationSettings|By making this change, you will automatically approve all users in pending approval status."
+msgid "ApplicationSettings|By making this change, you will automatically approve %d user who is pending approval."
+msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users who are pending approval."
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "ApplicationSettings|By making this change, you will automatically approve all users who are pending approval."
msgstr ""
msgid "ApplicationSettings|Denied domains for sign-ups"
@@ -4634,12 +4672,12 @@ msgstr "Arkiverede projekter"
msgid "Archiving the project will make it entirely read-only. It is hidden from the dashboard and doesn't show up in searches. %{strong_start}The repository cannot be committed to, and no issues, comments, or other entities can be created.%{strong_end} %{link_start}Learn more.%{link_end}"
msgstr "Arkivering af projektet vil gøre det fuldstændigt skrivebeskyttet. Det skjules fra betjeningspanelet og vises ikke i søgninger. %{strong_start}Der kan ikke commites til depotet og der kan ikke oprettes problemstillinger, kommentarer og andre indslag.%{strong_end} %{link_start}Lær mere%{link_end}."
-msgid "Are you ABSOLUTELY SURE you wish to delete this project?"
-msgstr "Er du HELT SIKKER på, at du vil slette projektet?"
-
msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
msgstr "Er du HELT SIKKER på, at du vil fjerne gruppen?"
+msgid "Are you absolutely sure?"
+msgstr ""
+
msgid "Are you sure that you want to archive this project?"
msgstr "Er du sikker på, at du vil arkivere projektet?"
@@ -4673,12 +4711,18 @@ msgstr "Er du sikker på, at du vil slette denne %{typeOfComment}?"
msgid "Are you sure you want to delete this SSH key?"
msgstr "Er du sikker på, at du vil slette SSH-nøglen?"
+msgid "Are you sure you want to delete this comment?"
+msgstr ""
+
msgid "Are you sure you want to delete this deploy key?"
msgstr ""
msgid "Are you sure you want to delete this device? This action cannot be undone."
msgstr "Er du sikker på, at du vil slette enheden? Handlingen kan ikke fortrydes."
+msgid "Are you sure you want to delete this label?"
+msgstr ""
+
msgid "Are you sure you want to delete this pipeline schedule?"
msgstr "Er du sikker på, at du vil slette pipeline-planlægningen?"
@@ -4694,9 +4738,6 @@ msgstr "Er du sikker på, at du vil forkaste kommentaren?"
msgid "Are you sure you want to discard your changes?"
msgstr "Er du sikker på, at du vil forkaste dine ændringer?"
-msgid "Are you sure you want to erase this build?"
-msgstr ""
-
msgid "Are you sure you want to import %d repository?"
msgid_plural "Are you sure you want to import %d repositories?"
msgstr[0] "Er du sikker på, at du vil importere %d depot?"
@@ -4744,6 +4785,9 @@ msgstr "Er du sikker på, at du vil fjerne identiteten?"
msgid "Are you sure you want to remove this list?"
msgstr "Er du sikker på, at du vil fjerne listen?"
+msgid "Are you sure you want to remove this nickname?"
+msgstr ""
+
msgid "Are you sure you want to reset the health check token?"
msgstr "Er du sikker på, at du vil nulstille tokenen til sundhedstjek?"
@@ -4756,12 +4800,12 @@ msgstr "Er du sikker på, at du vil prøve migreringen igen?"
msgid "Are you sure you want to revoke this %{type}? This action cannot be undone."
msgstr "Er du sikker på, at du vil tilbagekalde denne %{type}? Handlingen kan ikke fortrydes."
-msgid "Are you sure you want to revoke this nickname?"
-msgstr "Er du sikker på, at du vil tilbagekalde kaldenavnet?"
-
msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
msgstr "Er du sikker på, at du vil tilbagekalde den personlige adgangstoken? Handlingen kan ikke fortrydes."
+msgid "Are you sure you want to revoke this project access token? This action cannot be undone."
+msgstr ""
+
msgid "Are you sure you want to stop this environment?"
msgstr "Er du sikker på, at du vil stoppe miljøet?"
@@ -4906,9 +4950,6 @@ msgstr "Tildelt til %{assigneeName}"
msgid "Assigned to %{assignee_name}"
msgstr "Tildelt til %{assignee_name}"
-msgid "Assigned to %{name}"
-msgstr "Tildelt til %{name}"
-
msgid "Assigned to me"
msgstr "Tildelt til mig"
@@ -4973,6 +5014,9 @@ msgstr[1] "Vedhæfter %d filer"
msgid "Attaching the file failed."
msgstr "Kunne ikke vedhæfte filen."
+msgid "Attention"
+msgstr ""
+
msgid "Audit Events"
msgstr ""
@@ -5135,6 +5179,12 @@ msgstr "Tilladelse givet kl."
msgid "Authorized applications (%{size})"
msgstr "Godkendte programmer (%{size})"
+msgid "AuthorizedApplication|Are you sure you want to revoke this application?"
+msgstr ""
+
+msgid "AuthorizedApplication|Revoke application"
+msgstr ""
+
msgid "Authors: %{authors}"
msgstr "Forfattere: %{authors}"
@@ -6328,6 +6378,9 @@ msgstr "Udgivelser"
msgid "CICDAnalytics|Shared Runners Usage"
msgstr ""
+msgid "CICDAnalytics|Shared runner pipeline minute duration by month"
+msgstr ""
+
msgid "CICDAnalytics|Shared runner usage"
msgstr ""
@@ -6469,6 +6522,9 @@ msgstr ""
msgid "Can create groups:"
msgstr "Kan oprette grupper:"
+msgid "Can not delete primary training"
+msgstr ""
+
msgid "Can't apply as the source branch was deleted."
msgstr "Kan ikke anvende da kildegrenen blev slettet."
@@ -6802,9 +6858,6 @@ msgstr ""
msgid "Changing any setting here requires an application restart"
msgstr ""
-msgid "Changing group URL can have unintended side effects."
-msgstr ""
-
msgid "Charts can't be displayed as the request for data has timed out. %{documentationLink}"
msgstr "Diagrammer kan ikke vises fordi anmodningen om data har fået timeout. %{documentationLink}"
@@ -6892,9 +6945,6 @@ msgstr "Tjekker godkendelsesstatus"
msgid "Checking branch availability..."
msgstr "Tjekker tilgængelighed af gren ..."
-msgid "Checking group URL availability..."
-msgstr ""
-
msgid "Checking group path availability..."
msgstr ""
@@ -7388,6 +7438,9 @@ msgstr ""
msgid "Clear recent searches"
msgstr "Ryd seneste søgninger"
+msgid "Clear repository checks"
+msgstr ""
+
msgid "Clear search"
msgstr "Ryd søgning"
@@ -7520,9 +7573,6 @@ msgstr "Lukket %{epicTimeagoDate}"
msgid "Closed MRs"
msgstr "Lukkede sammenlægningsanmodninger"
-msgid "Closed epics"
-msgstr "Lukkede epics"
-
msgid "Closed issues"
msgstr "Lukkede problemstillinger"
@@ -7559,13 +7609,13 @@ msgstr "Klynge kræves for Stages::ClusterEndpointInserter"
msgid "Cluster level"
msgstr "Klyngeniveau"
-msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
+msgid "Cluster type must be specified for Stages::ClusterEndpointInserter"
msgstr ""
msgid "ClusterAgents|%{name} successfully deleted"
msgstr ""
-msgid "ClusterAgents|%{number} of %{total} Agents"
+msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
@@ -7607,6 +7657,15 @@ msgstr ""
msgid "ClusterAgents|Agent never connected to GitLab"
msgstr ""
+msgid "ClusterAgents|Agent version mismatch"
+msgstr ""
+
+msgid "ClusterAgents|Agent version mismatch and update"
+msgstr ""
+
+msgid "ClusterAgents|Agent version update required"
+msgstr ""
+
msgid "ClusterAgents|All"
msgstr ""
@@ -7631,7 +7690,7 @@ msgstr ""
msgid "ClusterAgents|Configuration"
msgstr "Konfiguration"
-msgid "ClusterAgents|Connect a cluster through the Agent"
+msgid "ClusterAgents|Connect a cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connect existing cluster"
@@ -7640,13 +7699,13 @@ msgstr ""
msgid "ClusterAgents|Connect with a certificate"
msgstr ""
-msgid "ClusterAgents|Connect with agent"
+msgid "ClusterAgents|Connect with an agent"
msgstr ""
msgid "ClusterAgents|Connect with the GitLab Agent"
msgstr ""
-msgid "ClusterAgents|Connect your cluster through the Agent"
+msgid "ClusterAgents|Connect your cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connected"
@@ -7706,7 +7765,10 @@ msgstr ""
msgid "ClusterAgents|How to register an agent?"
msgstr ""
-msgid "ClusterAgents|Install new Agent"
+msgid "ClusterAgents|How to update an agent?"
+msgstr ""
+
+msgid "ClusterAgents|Install a new agent"
msgstr ""
msgid "ClusterAgents|Last connected %{timeAgo}."
@@ -7733,7 +7795,7 @@ msgstr "Aldrig"
msgid "ClusterAgents|Never connected"
msgstr ""
-msgid "ClusterAgents|No Agents"
+msgid "ClusterAgents|No agents"
msgstr ""
msgid "ClusterAgents|No clusters connected through cluster certificates"
@@ -7793,6 +7855,9 @@ msgstr ""
msgid "ClusterAgents|The agent has not been connected in a long time. There might be a connectivity issue. Last contact was %{timeAgo}."
msgstr ""
+msgid "ClusterAgents|The agent version do not match each other across your cluster's pods. This can happen when a new agent version was just deployed and Kubernetes is shutting down the old pods."
+msgstr ""
+
msgid "ClusterAgents|The recommended installation method includes the token. If you want to follow the advanced installation method provided in the docs, make sure you save the token value before you close this window."
msgstr ""
@@ -7840,6 +7905,9 @@ msgstr ""
msgid "ClusterAgents|You will need to create a token to connect to your agent"
msgstr "Du skal oprette en token for at oprette forbindelse til din agent"
+msgid "ClusterAgents|Your agent version is out of sync with your GitLab version (v%{version}), which might cause compatibility problems. Update the agent installed on your cluster to the most recent version."
+msgstr ""
+
msgid "ClusterAgents|Your instance doesn't have the %{linkStart}GitLab Agent Server (KAS)%{linkEnd} set up. Ask a GitLab Administrator to install it."
msgstr ""
@@ -8716,9 +8784,6 @@ msgstr ""
msgid "Comma-separated list of email addresses."
msgstr "Kommasepareret liste over e-mailadresser."
-msgid "Comma-separated list of users allowed to exceed the rate limit."
-msgstr ""
-
msgid "Comma-separated, e.g. '1.1.1.1, 2.2.2.0/24'"
msgstr ""
@@ -9045,6 +9110,12 @@ msgstr "Selvtillid"
msgid "Confidential"
msgstr "Fortroligt"
+msgid "Confidential issue"
+msgstr ""
+
+msgid "Confidential note"
+msgstr ""
+
msgid "Confidentiality"
msgstr "Fortrolighed"
@@ -9078,6 +9149,9 @@ msgstr "Konfigurer afhængighedsskanning i `.gitlab-ci.yml` med den GitLab-hånd
msgid "Configure Dependency Scanning in `.gitlab-ci.yml`, creating this file if it does not already exist"
msgstr ""
+msgid "Configure GitLab"
+msgstr ""
+
msgid "Configure GitLab runners to start using the Web Terminal. %{helpStart}Learn more.%{helpEnd}"
msgstr "Konfigurer GitLab-runnere for at komme i gang med webterminal. %{helpStart}Lær mere%{helpEnd}."
@@ -9126,6 +9200,15 @@ msgstr "Konfigurer eksisterende installation"
msgid "Configure pipelines to deploy web apps, backend services, APIs and static resources to Google Cloud"
msgstr ""
+msgid "Configure region"
+msgstr ""
+
+msgid "Configure region for environment"
+msgstr ""
+
+msgid "Configure regions"
+msgstr ""
+
msgid "Configure repository mirroring."
msgstr ""
@@ -9159,6 +9242,9 @@ msgstr ""
msgid "Configure which lists are shown for anyone who visits this board"
msgstr ""
+msgid "Configure your environments to be deployed to specific geographical regions"
+msgstr ""
+
msgid "Confirm"
msgstr "Bekræft"
@@ -9861,10 +9947,10 @@ msgstr "Er du sikker på, at du vil slette korpusset?"
msgid "CorpusManagement|Actions"
msgstr "Handlinger"
-msgid "CorpusManagement|Corpus are used in fuzz testing as mutation source to Improve future testing."
+msgid "CorpusManagement|Corpus file"
msgstr ""
-msgid "CorpusManagement|Corpus file"
+msgid "CorpusManagement|Corpus files are used in coverage-guided fuzz testing as seed inputs to improve testing."
msgstr ""
msgid "CorpusManagement|Corpus files must be in *.zip format. Maximum 5 GB"
@@ -9918,6 +10004,9 @@ msgstr "Kunne ikke tilføje administratorer som medlemmer"
msgid "Could not apply %{name} command."
msgstr "Kunne ikke anvende kommandoen %{name}."
+msgid "Could not apply %{name} command. %{message}."
+msgstr ""
+
msgid "Could not authorize chat nickname. Try again!"
msgstr ""
@@ -10068,6 +10157,9 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr "Opret et Mattermost-team til gruppen"
+msgid "Create a group"
+msgstr ""
+
msgid "Create a merge request"
msgstr "Opret en sammenlægningsanmodning"
@@ -10092,6 +10184,9 @@ msgstr "Opret et nyt depot"
msgid "Create a personal access token on your account to pull or push via %{protocol}."
msgstr "Opret en personlig adgangstoken på din konto for at bruge pull eller push via %{protocol}."
+msgid "Create a project"
+msgstr ""
+
msgid "Create an account using:"
msgstr "Opret en konto med:"
@@ -10455,6 +10550,9 @@ msgstr ""
msgid "Creation date"
msgstr "Oprettelsesdato"
+msgid "Creator"
+msgstr ""
+
msgid "Credentials"
msgstr "Loginoplysninger"
@@ -10467,9 +10565,15 @@ msgstr "Ingen loginoplysninger fundet"
msgid "CredentialsInventory|Personal Access Tokens"
msgstr "Personlige adgangstokens"
+msgid "CredentialsInventory|Project Access Tokens"
+msgstr ""
+
msgid "CredentialsInventory|SSH Keys"
msgstr "SSH-nøgler"
+msgid "Credit card required to be on file in order to create a pipeline"
+msgstr ""
+
msgid "Credit card:"
msgstr "Kreditkort:"
@@ -10653,9 +10757,6 @@ msgstr ""
msgid "Customer relations"
msgstr ""
-msgid "Customizable by an administrator."
-msgstr "Kan tilpasses af en administrator."
-
msgid "Customizable by owners."
msgstr "Kan tilpasses af ejere."
@@ -10785,30 +10886,18 @@ msgstr "skal være under en gruppe"
msgid "CycleAnalytics|%{selectedLabelsCount} selected (%{maxLabels} max)"
msgstr "%{selectedLabelsCount} valgte (%{maxLabels} maks.)"
-msgid "CycleAnalytics|%{stageCount} stages selected"
-msgstr "%{stageCount} stadier valgt"
-
-msgid "CycleAnalytics|All stages"
-msgstr "Alle stadier"
-
-msgid "CycleAnalytics|Average days to completion"
+msgid "CycleAnalytics|Average time to completion"
msgstr ""
msgid "CycleAnalytics|Date"
msgstr "Dato"
-msgid "CycleAnalytics|Days to completion"
-msgstr ""
-
msgid "CycleAnalytics|Display chart filters"
msgstr "Vis diagramfiltre"
msgid "CycleAnalytics|Lead Time for Changes"
msgstr ""
-msgid "CycleAnalytics|No stages selected"
-msgstr "Ingen stadier valgt"
-
msgid "CycleAnalytics|Number of tasks"
msgstr "Antal opgaver"
@@ -10837,18 +10926,30 @@ msgstr ""
msgid "CycleAnalytics|Showing data for group '%{groupName}' from %{createdAfter} to %{createdBefore}"
msgstr ""
-msgid "CycleAnalytics|Stages"
-msgstr "Stadier"
+msgid "CycleAnalytics|Stage time: %{title}"
+msgstr ""
msgid "CycleAnalytics|Tasks by type"
msgstr "Opgaver efter type"
-msgid "CycleAnalytics|The average time spent in the selected stage for the items that were completed on each date. Data limited to the last 500 items."
+msgid "CycleAnalytics|The average time items spent in this stage. Data limited to items completed within this date range."
msgstr ""
msgid "CycleAnalytics|The given date range is larger than 180 days"
msgstr ""
+msgid "CycleAnalytics|The total time items spent across each value stream stage. Data limited to items completed within this date range."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Stage time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Total time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|Total time"
+msgstr ""
+
msgid "CycleAnalytics|Type of work"
msgstr ""
@@ -10861,9 +10962,6 @@ msgstr ""
msgid "CycleAnalytics|project dropdown filter"
msgstr ""
-msgid "CycleAnalytics|stage dropdown"
-msgstr ""
-
msgid "DAG visualization requires at least 3 dependent jobs."
msgstr ""
@@ -10963,11 +11061,17 @@ msgstr ""
msgid "DastProfiles|AJAX spider"
msgstr ""
+msgid "DastProfiles|API"
+msgstr ""
+
+msgid "DastProfiles|API endpoint URL"
+msgstr ""
+
msgid "DastProfiles|Active"
msgstr "Aktiv"
-msgid "DastProfiles|Additional request headers (Optional)"
-msgstr "Yderligere anmodningsheadere (valgfrit)"
+msgid "DastProfiles|Additional request headers (optional)"
+msgstr ""
msgid "DastProfiles|Are you sure you want to delete this profile?"
msgstr "Er du sikker på, at du vil slette profilen?"
@@ -10981,6 +11085,9 @@ msgstr ""
msgid "DastProfiles|Branch missing"
msgstr "Gren mangler"
+msgid "DastProfiles|Choose a scan method"
+msgstr ""
+
msgid "DastProfiles|Could not create the scanner profile. Please try again."
msgstr "Kunne ikke oprette skannerprofilen. Prøv venligst igen."
@@ -11050,7 +11157,13 @@ msgstr "Fejldetaljer"
msgid "DastProfiles|Excluded URLs"
msgstr ""
-msgid "DastProfiles|Excluded URLs (Optional)"
+msgid "DastProfiles|Excluded URLs (optional)"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths (optional)"
msgstr ""
msgid "DastProfiles|Hide debug messages"
@@ -11107,9 +11220,6 @@ msgstr ""
msgid "DastProfiles|Request headers"
msgstr ""
-msgid "DastProfiles|Rest API"
-msgstr ""
-
msgid "DastProfiles|Run the AJAX spider, in addition to the traditional spider, to crawl the target site."
msgstr ""
@@ -11119,6 +11229,9 @@ msgstr ""
msgid "DastProfiles|Save profile"
msgstr "Gem profil"
+msgid "DastProfiles|Scan method"
+msgstr ""
+
msgid "DastProfiles|Scan mode"
msgstr ""
@@ -11197,12 +11310,24 @@ msgstr ""
msgid "DastProfiles|Website"
msgstr "Websted"
+msgid "DastProfiles|What does each method do?"
+msgstr ""
+
msgid "DastProfiles|You can either choose a passive scan or validate the target site from the site profile management page. %{docsLinkStart}Learn more about site validation.%{docsLinkEnd}"
msgstr ""
msgid "DastProfiles|You cannot run an active scan against an unvalidated site."
msgstr ""
+msgid "DastProfiles|folder/dast_example.har or https://example.com/dast_example.har"
+msgstr ""
+
+msgid "DastProfiles|folder/example.postman_collection.json or https://example.com/"
+msgstr ""
+
+msgid "DastProfiles|folder/openapi.json or https://example.com/openapi.json"
+msgstr ""
+
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr "Kopiér HTTP-header til udklipsholder"
@@ -11310,6 +11435,9 @@ msgstr ""
msgid "DatadogIntegration|API URL"
msgstr "API URL"
+msgid "DatadogIntegration|Custom tags in Datadog. Enter one tag per line in the %{codeOpen}key:value%{codeClose} format. %{linkOpen}How do I use tags?%{linkClose}"
+msgstr ""
+
msgid "DatadogIntegration|Environment"
msgstr "Miljø"
@@ -11328,12 +11456,18 @@ msgstr "Tjeneste"
msgid "DatadogIntegration|Tag all data from this GitLab instance in Datadog. Useful when managing several self-managed deployments."
msgstr ""
+msgid "DatadogIntegration|Tags"
+msgstr ""
+
msgid "DatadogIntegration|The Datadog site to send data to. To send data to the EU site, use %{codeOpen}datadoghq.eu%{codeClose}."
msgstr ""
msgid "DatadogIntegration|Trace your GitLab pipelines with Datadog."
msgstr ""
+msgid "DatadogIntegration|have an invalid format"
+msgstr ""
+
msgid "Datasource name not found"
msgstr ""
@@ -11343,9 +11477,6 @@ msgstr "Dato"
msgid "Date merged"
msgstr ""
-msgid "Date picker"
-msgstr "Datovælger"
-
msgid "Date range"
msgstr "Datoområde"
@@ -11499,9 +11630,6 @@ msgstr ""
msgid "Definition"
msgstr "Definition"
-msgid "Delayed Project Deletion (%{adjourned_deletion})"
-msgstr ""
-
msgid "DelayedJobs|Are you sure you want to run %{jobName} immediately? Otherwise this job will run automatically after its timer finishes."
msgstr "Er du sikker på, at du vil køre %{jobName} straks? Ellers kører jobbet automatisk når dets timer er færdig."
@@ -11580,12 +11708,12 @@ msgstr "Slet etiket: %{labelName}"
msgid "Delete pipeline"
msgstr "Slet pipeline"
+msgid "Delete pipeline schedule"
+msgstr ""
+
msgid "Delete project"
msgstr "Slet projekt"
-msgid "Delete project. Are you ABSOLUTELY SURE?"
-msgstr "Slet projekt. Er du HELT SIKKER?"
-
msgid "Delete row"
msgstr "Slet række"
@@ -11613,6 +11741,9 @@ msgstr "Slet vedhæftningen"
msgid "Delete this epic and all descendants?"
msgstr "Slet epicen og alle efterkommere?"
+msgid "Delete this project"
+msgstr ""
+
msgid "Delete user list"
msgstr "Slet brugerliste"
@@ -11871,6 +12002,12 @@ msgstr ""
msgid "Deploy to..."
msgstr "Udsend til ..."
+msgid "DeployBoards|To see deployment progress for your environments, make sure you are deploying to %{codeStart}$KUBE_NAMESPACE%{codeEnd} and annotating with %{codeStart}app.gitlab.com/app=$CI_PROJECT_PATH_SLUG%{codeEnd} and %{codeStart}app.gitlab.com/env=$CI_ENVIRONMENT_SLUG%{codeEnd}."
+msgstr ""
+
+msgid "DeployBoard|Kubernetes Pods"
+msgstr ""
+
msgid "DeployFreeze|Add a freeze period to prevent unintended releases during a period of time for a given environment. You must update the deployment jobs in %{filename} according to the deploy freezes added here. %{freeze_period_link_start}Learn more.%{freeze_period_link_end}"
msgstr ""
@@ -11955,9 +12092,6 @@ msgstr ""
msgid "DeployTokens|Active Deploy Tokens (%{active_tokens})"
msgstr ""
-msgid "DeployTokens|Allows read and write access to registry images."
-msgstr "Tillader læse- og skriveadgang til registerbilleder."
-
msgid "DeployTokens|Allows read and write access to the package registry."
msgstr "Tillader læse- og skriveadgang til pakkeregisteret."
@@ -11970,6 +12104,9 @@ msgstr "Tillader skrivebeskyttet adgang til pakkeregisteret."
msgid "DeployTokens|Allows read-only access to the repository."
msgstr "Tillader skrivebeskyttet adgang til depotet."
+msgid "DeployTokens|Allows write access to registry images."
+msgstr ""
+
msgid "DeployTokens|Copy deploy token"
msgstr "Kopiér udsendelsestoken"
@@ -12063,12 +12200,57 @@ msgstr "Udsender til"
msgid "Deploying to AWS is easy with GitLab"
msgstr "Udsendelse til AWS er let med GitLab"
+msgid "Deployment"
+msgstr ""
+
msgid "Deployment Frequency"
msgstr "Udsendelseshyppighed"
+msgid "Deployment Target|Project deployment target (optional)"
+msgstr ""
+
+msgid "Deployment Target|Select the deployment target"
+msgstr ""
+
msgid "Deployment frequency"
msgstr "Udsendelseshyppighed"
+msgid "DeploymentTarget|GitLab Pages"
+msgstr ""
+
+msgid "DeploymentTarget|Heroku"
+msgstr ""
+
+msgid "DeploymentTarget|Infrastructure provider (Terraform, Cloudformation, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Kubernetes (GKE, EKS, OpenShift, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Managed container runtime (Fargate, Cloud Run, DigitalOcean App)"
+msgstr ""
+
+msgid "DeploymentTarget|Mobile app store"
+msgstr ""
+
+msgid "DeploymentTarget|No deployment planned"
+msgstr ""
+
+msgid "DeploymentTarget|Other hosting service"
+msgstr ""
+
+msgid "DeploymentTarget|Registry (package or container)"
+msgstr ""
+
+msgid "DeploymentTarget|Self-managed container runtime (Podman, Docker Swarm, Docker Compose)"
+msgstr ""
+
+msgid "DeploymentTarget|Serverless backend (Lambda, Cloud functions)"
+msgstr ""
+
+msgid "DeploymentTarget|Virtual machine (for example, EC2)"
+msgstr ""
+
msgid "Deployments"
msgstr "Udsendelser"
@@ -12107,6 +12289,9 @@ msgstr ""
msgid "Deployment|This deployment was created using the API"
msgstr ""
+msgid "Deployment|Triggerer"
+msgstr ""
+
msgid "Deployment|Waiting"
msgstr ""
@@ -12134,6 +12319,18 @@ msgstr "lykkedes"
msgid "Deprecated API rate limits"
msgstr ""
+msgid "Deprecations|Feature deprecation and removal"
+msgstr ""
+
+msgid "Deprecations|For information on a possible replacement %{epicStart} learn more about Opstrace %{epicEnd}."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7 and are %{epicStart} scheduled for removal %{epicEnd} in GitLab 15.0."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7, and are %{removal_link_start} scheduled for removal %{link_end} in GitLab 15.0. For information on a possible replacement, %{opstrace_link_start} learn more about Opstrace %{link_end}."
+msgstr ""
+
msgid "Deprioritize label"
msgstr ""
@@ -12379,11 +12576,11 @@ msgstr "Mindst én godkendelse på en sammenlægningsanmodning"
msgid "DevopsAdoption|At least one deploy"
msgstr ""
-msgid "DevopsAdoption|At least one issue opened"
+msgid "DevopsAdoption|At least one issue created"
msgstr ""
-msgid "DevopsAdoption|At least one merge request opened"
-msgstr "Mindst én sammenlægningsanmodning åbnet"
+msgid "DevopsAdoption|At least one merge request created"
+msgstr ""
msgid "DevopsAdoption|At least one pipeline successfully run"
msgstr ""
@@ -12583,6 +12780,9 @@ msgstr "med %{additions} og %{deletions}"
msgid "Direct member"
msgstr "Direkte medlem"
+msgid "Direct members"
+msgstr ""
+
msgid "Direct non-authenticated users to this page."
msgstr ""
@@ -12699,6 +12899,9 @@ msgid_plural "Dismiss %d selected vulnerabilities as"
msgstr[0] ""
msgstr[1] ""
+msgid "Dismiss Alert"
+msgstr ""
+
msgid "Dismiss merge request promotion"
msgstr ""
@@ -12726,9 +12929,15 @@ msgstr ""
msgid "Display alerts from all configured monitoring tools."
msgstr ""
+msgid "Display milestones"
+msgstr ""
+
msgid "Display name"
msgstr "Visningsnavn"
+msgid "Display progress of child issues"
+msgstr ""
+
msgid "Display rendered file"
msgstr ""
@@ -12834,6 +13043,9 @@ msgstr ""
msgid "Download image"
msgstr "Download billede"
+msgid "Download payload"
+msgstr ""
+
msgid "Download raw data (.csv)"
msgstr "Download rå data (.csv)"
@@ -13011,6 +13223,9 @@ msgstr ""
msgid "Edit in Web IDE"
msgstr "Rediger i web-IDE"
+msgid "Edit in pipeline editor"
+msgstr ""
+
msgid "Edit in single-file editor"
msgstr "Rediger i editor med én fil"
@@ -13053,6 +13268,9 @@ msgstr "Rediger wikiside"
msgid "Edit your most recent comment in a thread (from an empty textarea)"
msgstr ""
+msgid "Edit, lint, and visualize your pipeline."
+msgstr ""
+
msgid "Edited"
msgstr "Redigeret"
@@ -13494,6 +13712,9 @@ msgstr ""
msgid "Enforce two-factor authentication for all user sign-ins."
msgstr ""
+msgid "Enhance security by storing service account keys in secret managers - learn more about %{docLinkStart}secret management with GitLab%{docLinkEnd}"
+msgstr ""
+
msgid "Ensure connectivity is available from the GitLab server to the Prometheus server"
msgstr ""
@@ -13554,6 +13775,9 @@ msgstr "Indtast titlen for %{name}"
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 following to confirm:"
+msgstr ""
+
msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
@@ -14084,9 +14308,6 @@ 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 "Der opstod en fejl. En blokeret bruger kan ikke deaktiveres"
@@ -14222,6 +14443,9 @@ msgstr ""
msgid "Errors:"
msgstr "Fejl:"
+msgid "Escalate this incident"
+msgstr ""
+
msgid "Escalation Policies"
msgstr "Eskaleringsregelsæt"
@@ -14234,6 +14458,9 @@ msgstr "Eksaleringsregelsæt må ikke have mere end %{rule_count} regler"
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy"
+msgstr ""
+
msgid "Escalation policy:"
msgstr ""
@@ -14485,6 +14712,9 @@ msgstr ""
msgid "Existing sign in methods may be removed"
msgstr ""
+msgid "Exit."
+msgstr ""
+
msgid "Expand"
msgstr "Udfold"
@@ -14581,6 +14811,9 @@ msgstr "Udforsk projekter"
msgid "Explore public groups"
msgstr "Udforsk offentlige grupper"
+msgid "Explore public projects"
+msgstr ""
+
msgid "Explore snippets"
msgstr ""
@@ -14742,8 +14975,8 @@ msgid_plural "Failed to archive designs. Please try again."
msgstr[0] ""
msgstr[1] ""
-msgid "Failed to assign a reviewer because no user was found."
-msgstr "Kunne ikke tildele en kontrollant fordi der ikke blev fundet nogen bruger."
+msgid "Failed to assign a reviewer because no user was specified."
+msgstr ""
msgid "Failed to assign a user because no user was found."
msgstr ""
@@ -14808,12 +15041,12 @@ msgstr "Kunne ikke hente gennemløbene for gruppen. Prøv venligst igen."
msgid "Failed to find import label for Jira import."
msgstr ""
+msgid "Failed to find users for %{missing}"
+msgstr ""
+
msgid "Failed to generate export, please try again later."
msgstr "Kunne ikke generere eksport. Prøv venligst igen senere."
-msgid "Failed to generate report, please try again after sometime"
-msgstr "Kunne ikke generere rapport. Prøv venligst igen efter noget tid"
-
msgid "Failed to get ref."
msgstr ""
@@ -14910,6 +15143,9 @@ msgstr "Kunne ikke fjerne et Zoom-møde"
msgid "Failed to remove a to-do item for the design."
msgstr "Kunne ikke fjerne et gøremålselement for designet."
+msgid "Failed to remove attention because no user was found."
+msgstr ""
+
msgid "Failed to remove mirror."
msgstr ""
@@ -14922,6 +15158,9 @@ msgstr "Kunne ikke fjerne brugeridentitet."
msgid "Failed to remove user key."
msgstr "Kunne ikke fjerne brugernøgle."
+msgid "Failed to request attention because no user was found."
+msgstr ""
+
msgid "Failed to reset key. Please try again."
msgstr "Kunne ikke nulstille nøgle. Prøv venligst igen."
@@ -15003,6 +15242,9 @@ msgstr "Favicon fjernes. Er du sikker?"
msgid "Feature Flags"
msgstr "Funktionsflag"
+msgid "Feature deprecation and removal"
+msgstr ""
+
msgid "Feature flag status"
msgstr "Status for funktionsflag"
@@ -15500,7 +15742,7 @@ msgstr ""
msgid "For each job, re-use the project workspace. If the workspace doesn't exist, use %{code_open}git clone%{code_close}."
msgstr ""
-msgid "For example, the application using the token or the purpose of the token."
+msgid "For example, the application using the token or the purpose of the token. Do not give sensitive information for the name of the token, as it will be visible to all %{resource_type} members."
msgstr ""
msgid "For files larger than this limit, only index the file name. The file content is neither indexed nor searchable."
@@ -15584,9 +15826,6 @@ msgstr "Offentlig"
msgid "ForkProject|Select a namespace"
msgstr "Vælg et navnerum"
-msgid "ForkProject|Select a namespace to fork the project"
-msgstr ""
-
msgid "ForkProject|The project can be accessed by any logged in user."
msgstr "Projektet kan tilgås af alle brugere som er logget ind."
@@ -15683,6 +15922,9 @@ msgstr ""
msgid "Full name"
msgstr "Fulde navn"
+msgid "GCP region configured"
+msgstr ""
+
msgid "GPG Key ID:"
msgstr ""
@@ -15863,6 +16105,9 @@ msgstr ""
msgid "Geo|Failed"
msgstr "Mislykket"
+msgid "Geo|Filter Geo sites"
+msgstr ""
+
msgid "Geo|Filter by name"
msgstr "Filtrér efter navn"
@@ -16274,6 +16519,12 @@ msgstr ""
msgid "GitLab Issue"
msgstr "GitLab-problemstilling"
+msgid "GitLab KAS"
+msgstr ""
+
+msgid "GitLab Memberships CSV Export"
+msgstr ""
+
msgid "GitLab Pages"
msgstr "GitLab Pages"
@@ -16322,6 +16573,9 @@ 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 free to use. Many features for larger teams are part of our %{link_start}paid products%{link_end}. You can try Ultimate for free without any obligation or payment details."
+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 "GitLab indhenter et Let's Encrypt SSL-certifikat til domænet. Processen kan tage noget tid. Prøv venligst igen senere."
@@ -16448,8 +16702,8 @@ msgstr "Verificeret"
msgid "GitLabPages|When enabled, all attempts to visit your website through HTTP are automatically redirected to HTTPS using a response with status code 301. Requires a valid certificate for all domains. %{docs_link_start}Learn more.%{link_end}"
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. %{docs_link_start}Learn more.%{link_end}"
-msgstr "Når Pages bruges under det generelle domæne i en GitLab-instans (%{pages_host}), så kan du ikke bruge HTTPS med under-underdomæner. Det betyder at det ikke vil virke hvis dit brugernavn/gruppenavn indeholder et punktum. Det er en begrænsning i HTTP over TLS-protokollen. HTTP-sider til fortsat virke forudsat at du ikke omdirigerede HTTP til HTTPS. %{docs_link_start}Lær mere%{link_end}."
+msgid "GitLabPages|When using Pages under the general domain of a GitLab instance (%{pages_host}), you cannot use HTTPS with subdomains of subdomains. If your namespace or groupname contains a dot, it does not work. This is a limitation of the HTTP Over TLS protocol. HTTP pages work if you don't redirect HTTP to HTTPS. %{docs_link_start}Learn more.%{link_end}"
+msgstr ""
msgid "GitLabPages|With GitLab Pages you can host your static website directly from your GitLab repository. %{docs_link_start}Learn more.%{link_end}"
msgstr ""
@@ -16625,9 +16879,6 @@ msgstr "GÃ¥ til filer"
msgid "Go to find file"
msgstr "GÃ¥ til find fil"
-msgid "Go to fork"
-msgstr "GÃ¥ til forgrening"
-
msgid "Go to issue boards"
msgstr "GÃ¥ til problemstillingstavler"
@@ -16835,9 +17086,6 @@ msgstr ""
msgid "Group Hooks"
msgstr "Gruppehooks"
-msgid "Group ID"
-msgstr "Gruppe-id"
-
msgid "Group Owner must have signed in with SAML before enabling Group Managed Accounts"
msgstr ""
@@ -16865,9 +17113,6 @@ msgstr "Gruppeavatar"
msgid "Group by"
msgstr "Gruppér efter"
-msgid "Group description"
-msgstr ""
-
msgid "Group description (optional)"
msgstr "Gruppebeskrivelse (valgfrit)"
@@ -16982,7 +17227,7 @@ msgstr "Gruppe: %{group_name}"
msgid "Group: %{name}"
msgstr "Gruppe: %{name}"
-msgid "GroupActivityMetrics|Issues opened"
+msgid "GroupActivityMetrics|Issues created"
msgstr ""
msgid "GroupActivityMetrics|Last 90 days"
@@ -16991,8 +17236,8 @@ msgstr "Sidste 90 dage"
msgid "GroupActivityMetrics|Members added"
msgstr "Medlemmer tilføjet"
-msgid "GroupActivityMetrics|Merge Requests opened"
-msgstr "Sammenlægningsanmodninger åbnet"
+msgid "GroupActivityMetrics|Merge Requests created"
+msgstr ""
msgid "GroupActivityMetrics|Recent activity"
msgstr "Seneste aktivitet"
@@ -17282,6 +17527,9 @@ msgstr "Ændr gruppe-URL"
msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
+msgid "GroupSettings|Choose a group path that does not start with a dash or end with a period. It can also contain alphanumeric characters and underscores."
+msgstr ""
+
msgid "GroupSettings|Compliance frameworks"
msgstr "Overholdelsesframeworks"
@@ -17315,7 +17563,7 @@ msgstr "Eksportér gruppe"
msgid "GroupSettings|If not specified at the group or instance level, the default is %{default_initial_branch_name}. Does not affect existing repositories."
msgstr ""
-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."
+msgid "GroupSettings|If the parent group's visibility is lower than the group's current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility."
msgstr ""
msgid "GroupSettings|New runners registration token has been generated!"
@@ -17432,8 +17680,11 @@ msgstr "Grupper (%{count})"
msgid "Groups and projects"
msgstr "Grupper og projekter"
-msgid "Groups and subgroups"
-msgstr "Grupper og undergrupper"
+msgid "Groups are a great way to organize projects and people."
+msgstr ""
+
+msgid "Groups are the best way to manage projects and members."
+msgstr ""
msgid "Groups to synchronize"
msgstr "Grupper som skal synkroniseres"
@@ -17543,14 +17794,17 @@ msgstr "f.eks. h8d3f016698e ..."
msgid "GroupsTree|Are you sure you want to leave the \"%{fullName}\" group?"
msgstr "Er du sikker på, at du vil forlade gruppen \"%{fullName}\"?"
-msgid "GroupsTree|Edit group"
-msgstr "Rediger gruppe"
+msgid "GroupsTree|Delete"
+msgstr ""
+
+msgid "GroupsTree|Edit"
+msgstr ""
msgid "GroupsTree|Failed to leave the group. Please make sure you are not the only owner."
msgstr "Kunne ikke forlade gruppen. Sørg venligst for at du ikke er den eneste ejer."
-msgid "GroupsTree|Leave this group"
-msgstr "Forlad gruppen"
+msgid "GroupsTree|Leave group"
+msgstr ""
msgid "GroupsTree|Loading groups"
msgstr "Indlæser grupper"
@@ -17561,9 +17815,57 @@ msgstr "Ingen grupper matchede din søgning"
msgid "GroupsTree|No groups or projects matched your search"
msgstr ""
+msgid "GroupsTree|Options"
+msgstr ""
+
msgid "GroupsTree|Search by name"
msgstr "Søg efter navn"
+msgid "Groups|Avatar will be removed. Are you sure?"
+msgstr ""
+
+msgid "Groups|Changing group URL can have unintended side effects."
+msgstr ""
+
+msgid "Groups|Checking group URL availability..."
+msgstr ""
+
+msgid "Groups|Enter a descriptive name for your group."
+msgstr ""
+
+msgid "Groups|Group ID"
+msgstr ""
+
+msgid "Groups|Group URL"
+msgstr ""
+
+msgid "Groups|Group avatar"
+msgstr ""
+
+msgid "Groups|Group description (optional)"
+msgstr ""
+
+msgid "Groups|Group name"
+msgstr ""
+
+msgid "Groups|Group path is available."
+msgstr ""
+
+msgid "Groups|Group path is unavailable. Path has been replaced with a suggested available path."
+msgstr ""
+
+msgid "Groups|Learn more"
+msgstr ""
+
+msgid "Groups|Must start with letter, digit, emoji, or underscore. Can also contain periods, dashes, spaces, and parentheses."
+msgstr ""
+
+msgid "Groups|Remove avatar"
+msgstr ""
+
+msgid "Groups|Save changes"
+msgstr ""
+
msgid "Guideline"
msgstr "Retningslinje"
@@ -17573,6 +17875,9 @@ msgstr ""
msgid "HAR file path or URL"
msgstr ""
+msgid "HTTP Archive (HAR)"
+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 ""
@@ -17973,6 +18278,9 @@ msgstr "INFO: Din SSH-nøgle er udløbet. Generer venligst en ny nøgle."
msgid "INFO: Your SSH key is expiring soon. Please generate a new key."
msgstr "INFO: Din SSH-nøgle udløber snart. Generer venligst en ny nøgle."
+msgid "IP"
+msgstr ""
+
msgid "IP Address"
msgstr "IP-adresse"
@@ -18009,6 +18317,9 @@ msgstr ""
msgid "IdentityVerification|Verify your identity"
msgstr ""
+msgid "IdentityVerification|You can always verify your account at a later time to create a group."
+msgstr ""
+
msgid "If any indexed field exceeds this limit, it is truncated to this number of characters. The rest of the content is neither indexed nor searchable. This does not apply to repository and wiki indexing. For unlimited characters, set this to 0."
msgstr ""
@@ -18066,6 +18377,9 @@ msgstr ""
msgid "If you add %{codeStart}needs%{codeEnd} to jobs in your pipeline you'll be able to view the %{codeStart}needs%{codeEnd} relationships between jobs in this tab as a %{linkStart}Directed Acyclic Graph (DAG)%{linkEnd}."
msgstr "Hvis du tilføjer %{codeStart}behov%{codeEnd} til job i din pipeline, så vil du være i stand til at vise %{codeStart}behovrelationer%{codeEnd} mellem job i fanebladet som en %{linkStart}Directed Acyclic Graph (DAG)%{linkEnd}."
+msgid "If you are added to a project, it will be displayed here."
+msgstr ""
+
msgid "If you did not initiate these sign-in attempts, please reach out to your administrator or enable two-factor authentication (2FA) on your account."
msgstr ""
@@ -18372,12 +18686,24 @@ msgstr "...og du kan få en gratis prøveperiode af GitLab Ultimate"
msgid "InProductMarketing|3 ways to dive into GitLab CI/CD"
msgstr ""
+msgid "InProductMarketing|A single application eliminates complex integrations, data chokepoints, and toolchain maintenance, resulting in greater productivity and lower cost."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features, build more efficiently, strengthen security and compliance."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features."
+msgstr ""
+
msgid "InProductMarketing|Actually, GitLab makes the team work (better)"
msgstr ""
msgid "InProductMarketing|And finally %{deploy_link} a Python application."
msgstr ""
+msgid "InProductMarketing|And many more..."
+msgstr ""
+
msgid "InProductMarketing|Are your runners ready?"
msgstr "Er dine runnere klar?"
@@ -18396,15 +18722,33 @@ msgstr "Bedre kode på mindre tid"
msgid "InProductMarketing|Blog"
msgstr "Blog"
+msgid "InProductMarketing|Break down silos to coordinate seamlessly across development, operations, and security with a consistent experience across the development lifecycle."
+msgstr ""
+
+msgid "InProductMarketing|Burn up/down charts"
+msgstr ""
+
msgid "InProductMarketing|By enabling code owners and required merge approvals the right person will review the right MR. This is a win-win: cleaner code and a more efficient review process."
msgstr "Ved at aktivere kodeejere og krævede sammenlægningsgodkendelser vil den korrekte person kontrollere den rette sammenlægningsanmodning. Det har flere fordele: renere kode og en mere effektiv kontrolproces."
msgid "InProductMarketing|Click on the number below that corresponds with your answer — 1 being very difficult, 5 being very easy."
msgstr ""
+msgid "InProductMarketing|Code owners"
+msgstr ""
+
msgid "InProductMarketing|Code owners and required merge approvals are part of the paid tiers of GitLab. You can start a free 30-day trial of GitLab Ultimate and enable these features in less than 5 minutes with no credit card required."
msgstr ""
+msgid "InProductMarketing|Code review analytics"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration across stages in GitLab"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration made easy"
+msgstr ""
+
msgid "InProductMarketing|Create a custom CI runner with just a few clicks"
msgstr "Opret en tilpasset CI-runner med få klik"
@@ -18414,12 +18758,21 @@ msgstr "Opret en tilpasset runner"
msgid "InProductMarketing|Create a project in GitLab in 5 minutes"
msgstr "Opret et projekt i GitLab på 5 minutter"
+msgid "InProductMarketing|Create well-defined workflows by using scoped labels on issues, merge requests, and epics. Labels with the same scope cannot be used together, which prevents conflicts."
+msgstr ""
+
msgid "InProductMarketing|Create your first project!"
msgstr "Opret dit første projekt!"
+msgid "InProductMarketing|Define who owns specific files or directories, so the right reviewers are suggested when a merge request introduces changes to those files."
+msgstr ""
+
msgid "InProductMarketing|Deliver Better Products Faster"
msgstr ""
+msgid "InProductMarketing|Dependency scanning"
+msgstr ""
+
msgid "InProductMarketing|Did you know teams that use GitLab are far more efficient?"
msgstr ""
@@ -18429,15 +18782,27 @@ msgstr "Svært"
msgid "InProductMarketing|Dig in and create a project and a repo"
msgstr ""
+msgid "InProductMarketing|Discover Premium & Ultimate"
+msgstr ""
+
+msgid "InProductMarketing|Discover Premium & Ultimate."
+msgstr ""
+
msgid "InProductMarketing|Do you have a minute?"
msgstr "Har du et øjeblik?"
msgid "InProductMarketing|Do you have a teammate who would be perfect for this task?"
msgstr ""
+msgid "InProductMarketing|Dynamic application security testing"
+msgstr ""
+
msgid "InProductMarketing|Easy"
msgstr "Nemt"
+msgid "InProductMarketing|Epics"
+msgstr ""
+
msgid "InProductMarketing|Expand your DevOps journey with a free GitLab trial"
msgstr ""
@@ -18459,9 +18824,15 @@ msgstr "Feedback fra brugere som dig forbedrer virkelig vores produkt. Tak for d
msgid "InProductMarketing|Feel the need for speed?"
msgstr ""
+msgid "InProductMarketing|Find and fix bottlenecks in your code review process by understanding how long open merge requests have been in review."
+msgstr ""
+
msgid "InProductMarketing|Find out how your teams are really doing"
msgstr ""
+msgid "InProductMarketing|Find out if your external libraries are safe. Run dependency scanning jobs that check for known vulnerabilities in your external libraries."
+msgstr ""
+
msgid "InProductMarketing|Follow our steps"
msgstr ""
@@ -18498,6 +18869,9 @@ msgstr ""
msgid "InProductMarketing|GitLab is better with teammates to help out!"
msgstr ""
+msgid "InProductMarketing|GitLab is infrastructure agnostic (supporting GCP, AWS, Azure, OpenShift, VMWare, On Prem, Bare Metal, and more), offering a consistent workflow experience – irrespective of the environment."
+msgstr ""
+
msgid "InProductMarketing|GitLab provides static application security testing (SAST), dynamic application security testing (DAST), container scanning, and dependency scanning to help you deliver secure applications along with license compliance."
msgstr ""
@@ -18588,21 +18962,36 @@ msgstr ""
msgid "InProductMarketing|It's also possible to simply %{external_repo_link} in order to take advantage of GitLab's CI/CD."
msgstr ""
+msgid "InProductMarketing|Keep your code quality high by defining who should approve merge requests and how many approvals are required."
+msgstr ""
+
msgid "InProductMarketing|Launch GitLab CI/CD in 20 minutes or less"
msgstr "Start GitLab CI/CD på 20 minutter eller mindre"
+msgid "InProductMarketing|Lower cost of development"
+msgstr ""
+
+msgid "InProductMarketing|Make it easier to collaborate on high-level ideas by grouping related issues in an epic."
+msgstr ""
+
msgid "InProductMarketing|Making the switch? It's easier than you think to import your projects into GitLab. Move %{github_link}, or import something %{bitbucket_link}."
msgstr ""
msgid "InProductMarketing|Master the art of importing!"
msgstr ""
+msgid "InProductMarketing|Merge request approval rule"
+msgstr ""
+
msgid "InProductMarketing|Move on to easily creating a Pages website %{ci_template_link}"
msgstr ""
msgid "InProductMarketing|Multiple owners, confusing workstreams? We've got you covered"
msgstr ""
+msgid "InProductMarketing|Multiple required approvers"
+msgstr ""
+
msgid "InProductMarketing|Need an alternative to importing?"
msgstr "Har du brug for et alternativ til at importere?"
@@ -18615,18 +19004,33 @@ msgstr "Ingen kreditkort kræves."
msgid "InProductMarketing|Our tool brings all the things together"
msgstr ""
+msgid "InProductMarketing|Protect your web application by using DAST to examine for vulnerabilities in deployed environments."
+msgstr ""
+
msgid "InProductMarketing|Rapid development, simplified"
msgstr ""
msgid "InProductMarketing|Reduce Security & Compliance Risk"
msgstr ""
+msgid "InProductMarketing|Require multiple approvers on a merge request, so you know it's in good shape before it's merged."
+msgstr ""
+
+msgid "InProductMarketing|Roadmaps"
+msgstr ""
+
+msgid "InProductMarketing|Scoped labels"
+msgstr ""
+
msgid "InProductMarketing|Security that's integrated into your development lifecycle"
msgstr ""
msgid "InProductMarketing|Sometimes you're not ready to make a full transition to a new tool. If you're not ready to fully commit, %{mirroring_link} gives you a safe way to try out GitLab in parallel with your current tool."
msgstr ""
+msgid "InProductMarketing|Speed. Efficiency. Trust."
+msgstr ""
+
msgid "InProductMarketing|Spin up an autoscaling runner in GitLab"
msgstr ""
@@ -18636,6 +19040,9 @@ msgstr ""
msgid "InProductMarketing|Start a Self-Managed trial"
msgstr ""
+msgid "InProductMarketing|Start a free trial"
+msgstr ""
+
msgid "InProductMarketing|Start a free trial of GitLab Ultimate – no credit card required"
msgstr ""
@@ -18702,6 +19109,9 @@ msgstr ""
msgid "InProductMarketing|To understand and get the most out of GitLab, start at the beginning and %{project_link}. In GitLab, repositories are part of a project, so after you've created your project you can go ahead and %{repo_link}."
msgstr ""
+msgid "InProductMarketing|Track completed issues in a chart, so you can see how a milestone is progressing at a glance."
+msgstr ""
+
msgid "InProductMarketing|Try GitLab Ultimate for free"
msgstr "Prøv GitLab Ultimate, gratis"
@@ -18738,6 +19148,9 @@ msgstr "Meget svært"
msgid "InProductMarketing|Very easy"
msgstr "Meget nemt"
+msgid "InProductMarketing|Visualize your epics and milestones in a timeline."
+msgstr ""
+
msgid "InProductMarketing|Want to host GitLab on your servers?"
msgstr ""
@@ -18759,6 +19172,9 @@ msgstr ""
msgid "InProductMarketing|YouTube"
msgstr "YouTube"
+msgid "InProductMarketing|Your software, deployed your way"
+msgstr ""
+
msgid "InProductMarketing|Your teams can be more efficient"
msgstr ""
@@ -18879,9 +19295,18 @@ msgstr ""
msgid "IncidentManagement|No incidents to display."
msgstr "Ingen hændelser at vise."
+msgid "IncidentManagement|None"
+msgstr ""
+
msgid "IncidentManagement|Open"
msgstr ""
+msgid "IncidentManagement|Page your team with escalation policies"
+msgstr ""
+
+msgid "IncidentManagement|Paged"
+msgstr ""
+
msgid "IncidentManagement|Published"
msgstr ""
@@ -18891,6 +19316,9 @@ msgstr ""
msgid "IncidentManagement|Severity"
msgstr "Alvorlighed"
+msgid "IncidentManagement|Status"
+msgstr ""
+
msgid "IncidentManagement|There are no closed incidents"
msgstr "Der er ingen lukkede hændelser"
@@ -18909,6 +19337,9 @@ msgstr "Ukendt"
msgid "IncidentManagement|Unpublished"
msgstr ""
+msgid "IncidentManagement|Use escalation policies to automatically page your team when incidents are created."
+msgstr ""
+
msgid "IncidentSettings|Activate \"time to SLA\" countdown timer"
msgstr ""
@@ -18954,8 +19385,11 @@ msgstr "minutter"
msgid "Incidents"
msgstr "Hændelser"
-msgid "Incidents|Add a URL"
-msgstr "Tilføj en URL"
+msgid "Incidents|Add image details"
+msgstr ""
+
+msgid "Incidents|Add text or a link to display with your image. If you don't add either, the file name displays instead."
+msgstr ""
msgid "Incidents|Drop or %{linkStart}upload%{linkEnd} a metric screenshot to attach it to the incident"
msgstr ""
@@ -18969,11 +19403,11 @@ msgstr ""
msgid "Incidents|There was an issue loading metric images."
msgstr ""
-msgid "Incidents|There was an issue uploading your image."
+msgid "Incidents|There was an issue updating your image."
msgstr ""
-msgid "Incidents|You can optionally add a URL to link users to the original graph."
-msgstr "Du kan valgfrit tilføje en URL for at linke brugere til den oprindelige graf."
+msgid "Incidents|There was an issue uploading your image."
+msgstr ""
msgid "Incident|Alert details"
msgstr "Alertbeskeddetaljer"
@@ -18981,9 +19415,18 @@ msgstr "Alertbeskeddetaljer"
msgid "Incident|Are you sure you wish to delete this image?"
msgstr "Er du sikker på, at du vil slette billedet?"
+msgid "Incident|Delete image"
+msgstr ""
+
msgid "Incident|Deleting %{filename}"
msgstr "Sletter %{filename}"
+msgid "Incident|Edit image text or link"
+msgstr ""
+
+msgid "Incident|Editing %{filename}"
+msgstr ""
+
msgid "Incident|Metrics"
msgstr "MÃ¥linger"
@@ -19253,12 +19696,18 @@ msgstr "Der opstod en fejl under indlæsning af projekter med tilpassede indstil
msgid "Integrations|Branches for which notifications are to be sent"
msgstr ""
+msgid "Integrations|Clear if using a self-signed certificate."
+msgstr ""
+
msgid "Integrations|Comment detail:"
msgstr "Kommentardetalje:"
msgid "Integrations|Comment settings:"
msgstr "Kommentarindstillinger:"
+msgid "Integrations|Connection details"
+msgstr ""
+
msgid "Integrations|Connection failed. Please check your settings."
msgstr "Forbindelse mislykkedes. Tjek venligst dine indstillinger."
@@ -19283,6 +19732,9 @@ msgstr ""
msgid "Integrations|Enable GitLab.com slash commands in a Slack workspace."
msgstr "Aktivér GitLab.com-skråstregskommandoer i et Slack-arbejdsområde."
+msgid "Integrations|Enable SSL verification"
+msgstr ""
+
msgid "Integrations|Enable comments"
msgstr "Aktivér kommentarer"
@@ -19361,6 +19813,9 @@ msgstr "Nulstilling af integreringen rydder indstillingerne og deaktiverer integ
msgid "Integrations|Return to GitLab for Jira"
msgstr "Vend tilbage til GitLab for Jira"
+msgid "Integrations|SSL verification"
+msgstr ""
+
msgid "Integrations|Save settings?"
msgstr "Gem indstillinger?"
@@ -19406,9 +19861,6 @@ msgstr "Brug tilpassede indstillinger"
msgid "Integrations|Use default settings"
msgstr "Brug standardindstillinger"
-msgid "Integrations|When you mention a Jira issue in a commit or merge request, GitLab creates a remote link and comment (if enabled)."
-msgstr "Når du nævner en Jira-problemstilling i en commit eller sammenlægningsanmodning, så opretter GitLab et fjernlink og en kommentar (hvis det er aktiveret)."
-
msgid "Integrations|You can now close this window and return to the GitLab for Jira application."
msgstr "Du kan nu lukke vinduet og vende tilbage til GitLab for Jira-programmet."
@@ -19433,9 +19885,6 @@ msgstr ""
msgid "Integrations|can't exceed %{recipients_limit}"
msgstr ""
-msgid "Interactive developer security education."
-msgstr ""
-
msgid "Interactive mode"
msgstr "Interaktiv tilstand"
@@ -19925,6 +20374,9 @@ msgstr "Alder"
msgid "IssueAnalytics|Assignees"
msgstr "Tildelere"
+msgid "IssueAnalytics|Created by"
+msgstr ""
+
msgid "IssueAnalytics|Due date"
msgstr "Forfaldsdato"
@@ -19937,9 +20389,6 @@ msgstr "Problemstilling"
msgid "IssueAnalytics|Milestone"
msgstr "Milepæl"
-msgid "IssueAnalytics|Opened by"
-msgstr "Ã…bnet af"
-
msgid "IssueAnalytics|Status"
msgstr "Status"
@@ -20063,11 +20512,11 @@ msgstr ""
msgid "IssuesAnalytics|Avg/Month:"
msgstr "Gns./måned:"
-msgid "IssuesAnalytics|Issues opened"
-msgstr "Problemstillinger åbnet"
+msgid "IssuesAnalytics|Issues created"
+msgstr ""
-msgid "IssuesAnalytics|Issues opened per month"
-msgstr "Problemstillinger åbnet pr. måned"
+msgid "IssuesAnalytics|Issues created per month"
+msgstr ""
msgid "IssuesAnalytics|Last 12 months"
msgstr "Sidste 12 måneder"
@@ -20093,6 +20542,9 @@ msgstr "Det er nu muligt at %{action} filer som er gemt i LFS med webgrænseflad
msgid "It looks like you have some draft commits in this branch."
msgstr ""
+msgid "It looks like you're attempting to activate your subscription. Use %{a_start}the Subscription page%{a_end} instead."
+msgstr ""
+
msgid "It may be several days before you see feature usage data."
msgstr ""
@@ -20321,6 +20773,9 @@ msgstr ""
msgid "JiraConnect|You can now close this window and return to Jira."
msgstr "Du kan nu lukke vinduet og vende tilbage til Jira."
+msgid "JiraConnect|You don't have permission to create branches for this project. Select a different project or contact the project owner for access. %{linkStart}Learn more.%{linkEnd}"
+msgstr ""
+
msgid "JiraRequest|A connection error occurred while connecting to Jira. Try your request again."
msgstr ""
@@ -20369,15 +20824,15 @@ msgstr "Grund-URL for Jira-instansen."
msgid "JiraService|Define the type of Jira issue to create from a vulnerability."
msgstr ""
-msgid "JiraService|Displaying Jira issues while leaving the GitLab issue functionality enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
+msgid "JiraService|Displaying Jira issues while leaving GitLab issues also enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
+msgstr ""
+
+msgid "JiraService|Enable Jira issue creation from vulnerabilities"
msgstr ""
msgid "JiraService|Enable Jira issues"
msgstr "Aktivér Jira-problemstillinger"
-msgid "JiraService|Enable Jira issues creation from vulnerabilities"
-msgstr ""
-
msgid "JiraService|Enable Jira transitions"
msgstr "Aktivér Jira-overgange"
@@ -20492,16 +20947,19 @@ msgstr "Brug Jira til problemstillingssporing?"
msgid "JiraService|View Jira issues in GitLab"
msgstr "Vis Jira-problemstillinger i GitLab"
-msgid "JiraService|Warning: All GitLab users that have access to this GitLab project are able to view all issues from the Jira project specified below."
+msgid "JiraService|Warning: All GitLab users with access to this GitLab project can view all issues from the Jira project you select."
msgstr ""
msgid "JiraService|Web URL"
msgstr "Web-URL"
-msgid "JiraService|Work on Jira issues without leaving GitLab. Adds a Jira menu to access your list of Jira issues and view any issue as read-only."
+msgid "JiraService|When a Jira issue is mentioned in a commit or merge request, a remote link and comment (if enabled) will be created."
+msgstr ""
+
+msgid "JiraService|Work on Jira issues without leaving GitLab. Add a Jira menu to access a read-only list of your Jira issues."
msgstr ""
-msgid "JiraService|You need to configure Jira before enabling this integration. For more details, read the %{jira_doc_link_start}Jira integration documentation%{link_end}."
+msgid "JiraService|You must configure Jira before enabling this integration. %{jira_doc_link_start}Learn more.%{link_end}"
msgstr ""
msgid "Job"
@@ -20513,9 +20971,6 @@ msgstr "Job %{jobName}"
msgid "Job Failed #%{build_id}"
msgstr ""
-msgid "Job ID"
-msgstr "Job-id"
-
msgid "Job artifact"
msgstr "Jobartefakt"
@@ -20582,9 +21037,27 @@ msgstr ""
msgid "Jobs|You're about to retry a job that failed because it attempted to deploy code that is older than the latest deployment. Retrying this job could result in overwriting the environment with the older source code."
msgstr ""
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source} into %{target}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{ref}"
+msgstr ""
+
+msgid "Job|Are you sure you want to erase this job log and artifacts?"
+msgstr ""
+
msgid "Job|Browse"
msgstr "Gennemse"
+msgid "Job|Cancel"
+msgstr ""
+
msgid "Job|Complete Raw"
msgstr ""
@@ -20594,6 +21067,9 @@ msgstr "Download"
msgid "Job|Erase job log and artifacts"
msgstr ""
+msgid "Job|Finished at"
+msgstr ""
+
msgid "Job|Job artifacts"
msgstr "Jobartefakter"
@@ -20606,8 +21082,8 @@ msgstr ""
msgid "Job|Keep"
msgstr "Behold"
-msgid "Job|Pipeline"
-msgstr "Pipeline"
+msgid "Job|Retry"
+msgstr ""
msgid "Job|Scroll to bottom"
msgstr "Rul nederst"
@@ -20618,6 +21094,9 @@ msgstr "Rul øverst"
msgid "Job|Show complete raw"
msgstr ""
+msgid "Job|Status"
+msgstr ""
+
msgid "Job|The artifacts were removed"
msgstr "Artefakterne blev fjernet"
@@ -20645,21 +21124,12 @@ msgstr "må mislykkes"
msgid "Job|delayed"
msgstr "forsinket"
-msgid "Job|for"
-msgstr "for"
-
-msgid "Job|into"
-msgstr "i"
-
msgid "Job|manual"
msgstr "manuelt"
msgid "Job|triggered"
msgstr "udløst"
-msgid "Job|with"
-msgstr "med"
-
msgid "Join Zoom meeting"
msgstr "Deltag i Zoom-møde"
@@ -20762,9 +21232,6 @@ msgstr "Nøgler"
msgid "Ki"
msgstr "Ki"
-msgid "Kontra"
-msgstr ""
-
msgid "Kroki"
msgstr "Kroki"
@@ -21088,6 +21555,9 @@ msgstr "Lær mere om %{username}"
msgid "Learn more about Auto DevOps"
msgstr "Lær mere om Auto DevOps"
+msgid "Learn more about GitLab"
+msgstr ""
+
msgid "Learn more about Needs relationships"
msgstr "Lære mere om behovrelationer"
@@ -21415,9 +21885,18 @@ msgstr ""
msgid "Licenses|Displays licenses detected in the project, based on the %{linkStart}latest successful%{linkEnd} scan"
msgstr ""
+msgid "Licenses|Drag your license file here or %{linkStart}click to upload%{linkEnd}."
+msgstr ""
+
+msgid "Licenses|Drop your license file to start the upload."
+msgstr ""
+
msgid "Licenses|Error fetching the license list. Please check your network connection and try again."
msgstr "Fejl ved hentning af licenslisten. Tjek venligst din netværksforbindelse og prøv igen."
+msgid "Licenses|Error: You are trying to upload something other than a file"
+msgstr ""
+
msgid "Licenses|License Compliance"
msgstr "Licensoverholdelse"
@@ -21436,6 +21915,9 @@ msgstr ""
msgid "Licenses|Specified policies in this project"
msgstr "Angivne regelsæt i projektet"
+msgid "Licenses|The file could not be uploaded."
+msgstr ""
+
msgid "Licenses|The license list details information about the licenses used within your project."
msgstr ""
@@ -21469,11 +21951,6 @@ msgstr ""
msgid "Limit the size of Sidekiq jobs stored in Redis."
msgstr ""
-msgid "Limited to showing %d event at most"
-msgid_plural "Limited to showing %d events at most"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Limiting mode"
msgstr ""
@@ -21483,6 +21960,9 @@ msgstr "Linjeændringer"
msgid "Link"
msgstr "Link"
+msgid "Link (optional)"
+msgstr ""
+
msgid "Link Prometheus monitoring to GitLab."
msgstr ""
@@ -21519,6 +21999,9 @@ msgstr "Link til din Grafana-instans."
msgid "Linked emails (%{email_count})"
msgstr "Linkede e-mails (%{email_count})"
+msgid "Linked epics"
+msgstr ""
+
msgid "Linked issues"
msgstr "Linkede problemstillinger"
@@ -21546,6 +22029,15 @@ msgstr ""
msgid "List of all merge commits"
msgstr "Liste over alle sammenlægningscommits"
+msgid "List of environments for this project"
+msgstr ""
+
+msgid "List of suitable GCP locations"
+msgstr ""
+
+msgid "List of users allowed to exceed the rate limit."
+msgstr ""
+
msgid "List options"
msgstr "Valgmuligheder for lister"
@@ -21765,6 +22257,9 @@ msgstr "Mailgun-begivenheder"
msgid "Maintenance mode"
msgstr "Vedligeholdelsestilstand"
+msgid "Make adjustments to how your GitLab instance is set up."
+msgstr ""
+
msgid "Make and review changes in the browser with the Web IDE"
msgstr ""
@@ -21909,6 +22404,12 @@ msgstr "Tilføj kursiv tekst (%{modifierKey}I)"
msgid "MarkdownEditor|Add italic text (%{modifier_key}I)"
msgstr "Tilføj kursiv tekst (%{modifier_key}I)"
+msgid "MarkdownEditor|Add strikethrough text (%{modifierKey}⇧X)"
+msgstr ""
+
+msgid "MarkdownEditor|Add strikethrough text (%{modifier_key}⇧X)"
+msgstr ""
+
msgid "Marked For Deletion At - %{deletion_time}"
msgstr ""
@@ -22170,6 +22671,9 @@ msgstr "Maksimale størrelse på push"
msgid "Maximum push size (MB)"
msgstr "Maksimale størrelse på push (MB)"
+msgid "Maximum requests per 10 minutes per user"
+msgstr ""
+
msgid "Maximum requests per minute"
msgstr "Højeste anmodninger pr. minut"
@@ -22260,6 +22764,19 @@ msgstr "Medlemmer af %{group} kan også bruge push til grenen: %{branch}"
msgid "Members of a group may only view projects they have permission to access"
msgstr ""
+msgid "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seat in use and will be billed for the overage."
+msgid_plural "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seats in use and will be billed for the overage."
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "MembersOverage|You are about to incur additional charges"
+msgstr ""
+
+msgid "MembersOverage|Your subscription includes %d seat."
+msgid_plural "MembersOverage|Your subscription includes %d seats."
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Membership"
msgstr "Medlemskab"
@@ -22464,9 +22981,6 @@ msgstr ""
msgid "Merge request not merged"
msgstr ""
-msgid "Merge request pipelines 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 merge request pipelines."
-msgstr ""
-
msgid "Merge request reports"
msgstr ""
@@ -22563,13 +23077,13 @@ msgstr "Der opstod en fejl under gemning af kladdekommentaren."
msgid "MergeRequests|Create issue to resolve thread"
msgstr "Opret problemstilling for at løse alle tråde"
-msgid "MergeRequests|Failed to squash. Should be done manually."
-msgstr "Kunne ikke squash. Skal gøres manuelt."
-
msgid "MergeRequests|Saving the comment failed"
msgstr "Kunne ikke gemme kommentaren"
-msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
+msgid "MergeRequests|Squashing failed: Squash the commits locally, resolve any conflicts, then push the branch."
+msgstr ""
+
+msgid "MergeRequests|Squashing not allowed: This project doesn't allow you to squash commits when merging."
msgstr ""
msgid "MergeRequests|Thread stays resolved"
@@ -23410,6 +23924,18 @@ msgstr "Genudsend"
msgid "MrDeploymentActions|Stop environment"
msgstr "Stop miljø"
+msgid "MrList|Assigned to %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from assignee %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from reviewer %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Review requested from %{name}, go to their profile."
+msgstr ""
+
msgid "Multi-project"
msgstr "Multiprojekt"
@@ -23443,8 +23969,8 @@ msgstr "Skal matche %{codeStart}external_url%{codeEnd} i %{codeStart}/etc/gitlab
msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "My Awesome Group"
-msgstr "Min fantastiske gruppe"
+msgid "My awesome group"
+msgstr ""
msgid "My company or team"
msgstr "Min virksomhed eller team"
@@ -24065,9 +24591,6 @@ msgstr ""
msgid "No available branches"
msgstr "Ingen tilgængelige grene"
-msgid "No available groups to fork the project."
-msgstr "Ingen tilgængelige grupper til at forgrene projektet."
-
msgid "No branches found"
msgstr "Ingen grene fundet"
@@ -24278,6 +24801,9 @@ msgstr "Ingen offentlige grupper"
msgid "No ref selected"
msgstr ""
+msgid "No regions configured"
+msgstr ""
+
msgid "No related merge requests found."
msgstr "Ingen relaterede sammenlægningsanmodninger fundet."
@@ -25082,6 +25608,9 @@ msgstr ""
msgid "Only reCAPTCHA v2 is supported:"
msgstr "Kun reCAPTCHA v2 understøttes:"
+msgid "Only required if not using role instance credentials."
+msgstr ""
+
msgid "Only use lowercase letters, numbers, and underscores."
msgstr ""
@@ -25106,9 +25635,6 @@ msgstr "Ã…bn markering"
msgid "Open a CLI and connect to the cluster you want to install the agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
-msgid "Open epics"
-msgstr "Ã…bne epics"
-
msgid "Open errors"
msgstr "Ã…bne fejl"
@@ -25148,7 +25674,7 @@ msgstr "Åbnede sammenlægningsanmodninger"
msgid "Opened issues"
msgstr "Ã…bne problemstillinger"
-msgid "OpenedNDaysAgo|Opened"
+msgid "OpenedNDaysAgo|Created"
msgstr ""
msgid "Opens in a new window"
@@ -25193,9 +25719,6 @@ msgstr "Valgfrit"
msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
-msgid "Optional."
-msgstr ""
-
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
msgstr ""
@@ -25984,6 +26507,9 @@ msgstr ""
msgid "PerformanceBar|Memory"
msgstr "Hukommelse"
+msgid "PerformanceBar|Memory report"
+msgstr ""
+
msgid "PerformanceBar|Redis calls"
msgstr ""
@@ -26017,18 +26543,12 @@ msgstr "objekt"
msgid "PerformanceBar|wall"
msgstr "væg"
-msgid "Performs a rebase but skips triggering a new pipeline"
-msgstr ""
-
msgid "Period in seconds"
msgstr "Periode i sekunder"
msgid "Permalink"
msgstr ""
-msgid "Permanently delete project"
-msgstr "Slet projekt permanent"
-
msgid "Permanently remove group"
msgstr "Fjern gruppe permanent"
@@ -26299,6 +26819,51 @@ msgstr "Pipeline: %{ciStatus}"
msgid "PipelineStatusTooltip|Pipeline: %{ci_status}"
msgstr "Pipeline: %{ci_status}"
+msgid "PipelineWizardDefaultCommitMessage|Add %{filename}"
+msgstr ""
+
+msgid "PipelineWizardDefaultCommitMessage|Update %{filename}"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|At least one entry is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This field is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This value is not valid"
+msgstr ""
+
+msgid "PipelineWizardListWidget|add another step"
+msgstr ""
+
+msgid "PipelineWizardListWidget|remove step"
+msgstr ""
+
+msgid "PipelineWizard|Commit"
+msgstr ""
+
+msgid "PipelineWizard|Commit Message"
+msgstr ""
+
+msgid "PipelineWizard|Commit changes to your file"
+msgstr ""
+
+msgid "PipelineWizard|Commit file to Branch"
+msgstr ""
+
+msgid "PipelineWizard|Commit your new file"
+msgstr ""
+
+msgid "PipelineWizard|The file has been committed."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem committing the changes."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem while checking whether your file already exists in the specified branch."
+msgstr ""
+
msgid "Pipelines"
msgstr "Pipelines"
@@ -26413,8 +26978,8 @@ msgstr ""
msgid "Pipelines|Project cache successfully reset."
msgstr "Projektmellemlager nulstillet."
-msgid "Pipelines|Revoke"
-msgstr "Tilbagekald"
+msgid "Pipelines|Revoke trigger"
+msgstr ""
msgid "Pipelines|Something went wrong while cleaning runners cache."
msgstr "Noget gik galt under rensning af runnermellemlager."
@@ -26458,6 +27023,12 @@ msgstr ""
msgid "Pipelines|This is a child pipeline within the parent pipeline"
msgstr "Dette er en barnepipeline i forælderpipelinen"
+msgid "Pipelines|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipelines|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipelines|This pipeline will run code originating from a forked project merge request. This means that the code can potentially have security considerations like exposing CI variables."
msgstr ""
@@ -26500,9 +27071,6 @@ msgstr "Visualiser"
msgid "Pipelines|Your changes have been successfully committed. Now redirecting to the new merge request page."
msgstr ""
-msgid "Pipelines|detached"
-msgstr ""
-
msgid "Pipelines|error"
msgstr ""
@@ -26512,10 +27080,13 @@ msgstr "ugyldig"
msgid "Pipelines|latest"
msgstr ""
-msgid "Pipelines|stuck"
+msgid "Pipelines|merge request"
msgstr ""
-msgid "Pipelines|train"
+msgid "Pipelines|merge train"
+msgstr ""
+
+msgid "Pipelines|stuck"
msgstr ""
msgid "Pipelines|yaml invalid"
@@ -26647,6 +27218,12 @@ msgstr ""
msgid "Pipeline|This change will not change the overall test coverage if merged."
msgstr ""
+msgid "Pipeline|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipeline|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipeline|Trigger author"
msgstr "Udløserforfatter"
@@ -26671,6 +27248,12 @@ msgstr ""
msgid "Pipeline|for"
msgstr ""
+msgid "Pipeline|merge request"
+msgstr ""
+
+msgid "Pipeline|merge train"
+msgstr ""
+
msgid "Pipeline|on"
msgstr ""
@@ -26809,9 +27392,6 @@ msgstr "Indtast venligst et gyldigt tal"
msgid "Please enter a valid time interval"
msgstr ""
-msgid "Please enter or upload a valid license."
-msgstr "Indtast eller upload venligst en gyldig licens."
-
msgid "Please enter your current password."
msgstr ""
@@ -26920,9 +27500,6 @@ msgstr "Prøv venligst at opdatere siden. Hvis problemet fortsætter, så kontak
msgid "Please type %{phrase_code} to proceed or close this modal to cancel."
msgstr ""
-msgid "Please type the following to confirm:"
-msgstr "Skriv venligst følgende for at bekræfte:"
-
msgid "Please use this form to report to the admin users who create spam issues, comments or behave inappropriately."
msgstr ""
@@ -26950,12 +27527,27 @@ msgstr ""
msgid "Policies"
msgstr "Regelsæt"
+msgid "Policy '%{escalation_policy_name}' does not exist."
+msgstr ""
+
msgid "Policy management project does have any policies in %{policy_path}"
msgstr ""
msgid "Policy project doesn't exist"
msgstr ""
+msgid "PolicyRuleMultiSelect|%{firstLabel} +%{numberOfAdditionalLabels} more"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|All %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select all"
+msgstr ""
+
msgid "Polling interval multiplier"
msgstr ""
@@ -27184,6 +27776,9 @@ msgstr ""
msgid "Private projects can be created in your personal namespace with:"
msgstr "Private projekter kan oprettes i dit personlige navnerum med:"
+msgid "Problem with %{name} command: %{message}."
+msgstr ""
+
msgid "Proceed"
msgstr "Fortsæt"
@@ -27658,6 +28253,9 @@ msgstr "Programmeringssprog som bruges i depotet"
msgid "Progress"
msgstr "Forløb"
+msgid "Progress tracking"
+msgstr ""
+
msgid "Project"
msgstr "Projekt"
@@ -27889,6 +28487,9 @@ msgstr ""
msgid "ProjectQualitySummary|Failure"
msgstr ""
+msgid "ProjectQualitySummary|Get insight into the overall percentage of tests in your project that succeed, fail and are skipped."
+msgstr ""
+
msgid "ProjectQualitySummary|Latest pipeline results"
msgstr ""
@@ -27907,6 +28508,12 @@ msgstr ""
msgid "ProjectQualitySummary|See project Code Coverage Statistics"
msgstr ""
+msgid "ProjectQualitySummary|Set up test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|Set up test runs (opens in a new tab)"
+msgstr ""
+
msgid "ProjectQualitySummary|Skipped"
msgstr ""
@@ -28183,13 +28790,19 @@ msgstr "Problemstillinger"
msgid "ProjectSettings|LFS objects from this repository are available to forks. %{linkStart}How do I remove them?%{linkEnd}"
msgstr "LFS-objekter fra depotet er tilgængelige til forgreninger. %{linkStart}Hvordan fjerner jeg dem?%{linkEnd}"
+msgid "ProjectSettings|Learn about commit history."
+msgstr ""
+
+msgid "ProjectSettings|Leave empty to use default template."
+msgstr ""
+
msgid "ProjectSettings|Manage who can see the project in the public access directory."
msgstr ""
msgid "ProjectSettings|Manages large files such as audio, video, and graphics files."
msgstr ""
-msgid "ProjectSettings|Maximum 500 characters."
+msgid "ProjectSettings|Maximum %{maxLength} characters."
msgstr ""
msgid "ProjectSettings|Merge checks"
@@ -28330,6 +28943,9 @@ msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
msgstr ""
+msgid "ProjectSettings|The default template will be applied on save."
+msgstr ""
+
msgid "ProjectSettings|These checks must pass before merge requests can be merged."
msgstr ""
@@ -28384,6 +29000,9 @@ msgstr ""
msgid "ProjectSettings|What are badges?"
msgstr "Hvad er badges?"
+msgid "ProjectSettings|What are merge trains?"
+msgstr ""
+
msgid "ProjectSettings|When merge request pipelines are enabled in the CI/CD configuration file, pipelines validate the combined results of the source and target branches. %{link_start}How to configure merge request pipelines?%{link_end}"
msgstr ""
@@ -28501,6 +29120,9 @@ msgstr ""
msgid "Projects are organized into groups"
msgstr "Projekter organiseres i grupper"
+msgid "Projects are where you store your code, access issues, wiki and other features of GitLab."
+msgstr ""
+
msgid "Projects contributed to"
msgstr ""
@@ -28516,12 +29138,6 @@ msgstr ""
msgid "Projects to index"
msgstr "Projekter som skal indekseres"
-msgid "Projects will be permanently deleted after a %{waiting_period}-day waiting period."
-msgstr ""
-
-msgid "Projects will be permanently deleted immediately."
-msgstr "Projekter vil straks blive slettet permanent."
-
msgid "Projects with critical vulnerabilities"
msgstr "Projekter med kritiske sårbarheder"
@@ -28606,6 +29222,9 @@ msgstr "Importér"
msgid "ProjectsNew|Import project"
msgstr "Importér projekt"
+msgid "ProjectsNew|Include a Getting Started README"
+msgstr ""
+
msgid "ProjectsNew|Initialize repository with a README"
msgstr ""
@@ -28621,6 +29240,9 @@ msgstr "Projektkonfiguration"
msgid "ProjectsNew|Project description %{tag_start}(optional)%{tag_end}"
msgstr "Projektbeskrivelse %{tag_start}(valgfrit)%{tag_end}"
+msgid "ProjectsNew|Recommended if you're new to GitLab"
+msgstr ""
+
msgid "ProjectsNew|Run CI/CD for external repository"
msgstr "Kør CI/CD for eksternt depot"
@@ -29038,6 +29660,9 @@ msgstr "Kodeejergodkendelse til/fra"
msgid "ProtectedBranch|Unprotect"
msgstr ""
+msgid "ProtectedBranch|Unprotect branch"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr "Hvad er beskyttede grene?"
@@ -29065,6 +29690,9 @@ msgstr "Beskyt et miljø"
msgid "ProtectedEnvironment|Protected Environment (%{protected_environments_count})"
msgstr ""
+msgid "ProtectedEnvironment|Required approvals"
+msgstr ""
+
msgid "ProtectedEnvironment|Select an environment"
msgstr "Vælg et miljø"
@@ -29086,10 +29714,13 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr "Dit miljø har fået fjernet sin beskyttelse"
+msgid "ProtectedTags|Unprotect tag"
+msgstr ""
+
msgid "ProtectedTags|default"
msgstr ""
-msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
+msgid "ProtectedTag|By default, protected tags restrict who can modify the tag."
msgstr ""
msgid "ProtectedTag|Learn more."
@@ -29152,6 +29783,9 @@ msgstr "Offentlige pipelines"
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Public projects are an easy way to allow everyone to have read-only access."
+msgstr ""
+
msgid "Publish to status page"
msgstr "Udgiv til statussiden"
@@ -29308,9 +29942,6 @@ msgstr ""
msgid "QualitySummary|Project quality"
msgstr ""
-msgid "Quarters"
-msgstr ""
-
msgid "Query"
msgstr "Forespørgsel"
@@ -29395,6 +30026,9 @@ msgstr "Læs mere om GitLab på %{link_to_promo}."
msgid "Read more about project permissions %{help_link_open}here%{help_link_close}"
msgstr "Læs mere om projekttilladelser %{help_link_open}her%{help_link_close}"
+msgid "Read more about related epics"
+msgstr ""
+
msgid "Read more about related issues"
msgstr "Læs mere om relaterede problemstillinger"
@@ -29425,10 +30059,7 @@ msgstr "Rebase kildegren"
msgid "Rebase source branch on the target branch."
msgstr "Rebase kildegren på målgrenen."
-msgid "Rebase without CI"
-msgstr ""
-
-msgid "Rebases and triggers a pipeline"
+msgid "Rebase without pipeline"
msgstr ""
msgid "Recaptcha verified?"
@@ -29479,9 +30110,6 @@ msgstr ""
msgid "Reconfigure"
msgstr "Genkonfigurer"
-msgid "Recovering projects"
-msgstr "Gendanner projekter"
-
msgid "Recovery Codes"
msgstr "Gendannelseskoder"
@@ -29541,6 +30169,12 @@ msgstr ""
msgid "Regex pattern"
msgstr ""
+msgid "Region"
+msgstr ""
+
+msgid "Regions"
+msgstr ""
+
msgid "Register"
msgstr "Tilmeld"
@@ -29771,9 +30405,6 @@ msgstr ""
msgid "Remove all or specific reviewer(s)"
msgstr ""
-msgid "Remove approver"
-msgstr "Fjern godkender"
-
msgid "Remove approvers"
msgstr "Fjern godkendere"
@@ -29789,6 +30420,9 @@ msgstr ""
msgid "Remove attention request"
msgstr ""
+msgid "Remove attention request(s)"
+msgstr ""
+
msgid "Remove avatar"
msgstr "Fjern avatar"
@@ -29927,6 +30561,9 @@ msgstr "Fjernede alle etiketter."
msgid "Removed an issue from an epic."
msgstr "Fjernede en problemstilling fra en epic."
+msgid "Removed attention from %{users_sentence}."
+msgstr ""
+
msgid "Removed attention request from @%{username}"
msgstr ""
@@ -29978,6 +30615,9 @@ msgstr "Fjerner alle etiketter."
msgid "Removes an issue from an epic."
msgstr "Fjerner en problemstilling fra en epic."
+msgid "Removes attention from %{users_sentence}."
+msgstr ""
+
msgid "Removes parent epic %{epic_ref}."
msgstr "Fjerner forælderepicen %{epic_ref}."
@@ -30089,6 +30729,9 @@ msgstr "Rapportér misbrug"
msgid "Report abuse to admin"
msgstr "Rapportér misbrug til administrator"
+msgid "Report is generating and will be sent to your email address."
+msgstr ""
+
msgid "Reported %{timeAgo} by %{reportedBy}"
msgstr "Rapporteret %{timeAgo} af %{reportedBy}"
@@ -30378,6 +31021,15 @@ msgstr "Anmod om en ny"
msgid "Request attention"
msgstr ""
+msgid "Request attention from %{users_sentence}."
+msgstr ""
+
+msgid "Request attention from assignee or reviewer"
+msgstr ""
+
+msgid "Request attention from assignee(s) or reviewer(s)"
+msgstr ""
+
msgid "Request attention to review"
msgstr ""
@@ -30402,6 +31054,9 @@ msgstr "Anmodet"
msgid "Requested %{time_ago}"
msgstr "Anmodet %{time_ago}"
+msgid "Requested attention from %{users_sentence}."
+msgstr ""
+
msgid "Requested attention from @%{username}"
msgstr ""
@@ -30616,6 +31271,9 @@ msgstr "Gendan gruppe"
msgid "Restore project"
msgstr "Gendan projekt"
+msgid "Restoring projects"
+msgstr ""
+
msgid "Restoring the group will prevent the group, its subgroups and projects from being removed on this date."
msgstr ""
@@ -30646,6 +31304,9 @@ msgstr ""
msgid "Retry"
msgstr "Prøv igen"
+msgid "Retry failed jobs"
+msgstr ""
+
msgid "Retry job"
msgstr "Prøv job igen"
@@ -30693,9 +31354,6 @@ msgstr ""
msgid "Review changes"
msgstr "Kontrollér ændringer"
-msgid "Review requested from %{name}"
-msgstr ""
-
msgid "Review requests for you"
msgstr ""
@@ -30860,6 +31518,9 @@ msgstr "Arkitektur"
msgid "Runners|Assigned Group"
msgstr ""
+msgid "Runners|Assigned Projects (%{projectCount})"
+msgstr ""
+
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30929,6 +31590,9 @@ msgstr "Installer en runner"
msgid "Runners|Instance"
msgstr ""
+msgid "Runners|Jobs"
+msgstr ""
+
msgid "Runners|Last contact"
msgstr "Sidste kontakt"
@@ -31022,9 +31686,6 @@ msgstr "Runner #%{runner_id}"
msgid "Runners|Runner %{name} was deleted"
msgstr ""
-msgid "Runners|Runner ID"
-msgstr ""
-
msgid "Runners|Runner assigned to project."
msgstr ""
@@ -31172,6 +31833,9 @@ msgstr ""
msgid "Runners|stale"
msgstr ""
+msgid "Runner|This runner has not run any jobs."
+msgstr ""
+
msgid "Running"
msgstr "Kører"
@@ -31286,6 +31950,24 @@ msgstr "Gemmer"
msgid "Saving project."
msgstr "Gemmer projekt."
+msgid "ScanResultPolicy|%{ifLabelStart}if%{ifLabelEnd} %{scanners} scan in an open merge request targeting the %{branches} branch(es) finds %{vulnerabilitiesAllowed} or more %{severities} vulnerabilities that are %{vulnerabilityStates}"
+msgstr ""
+
+msgid "ScanResultPolicy|%{thenLabelStart}Then%{thenLabelEnd} Require approval from %{approvalsRequired} of the following approvers: %{approvers}"
+msgstr ""
+
+msgid "ScanResultPolicy|add an approver"
+msgstr ""
+
+msgid "ScanResultPolicy|scanners"
+msgstr ""
+
+msgid "ScanResultPolicy|severity levels"
+msgstr ""
+
+msgid "ScanResultPolicy|vulnerability states"
+msgstr ""
+
msgid "Scanner"
msgstr "Skanner"
@@ -31418,6 +32100,9 @@ msgstr "Søg efter en gruppe"
msgid "Search for a user"
msgstr "Søg efter en bruger"
+msgid "Search for an emoji"
+msgstr ""
+
msgid "Search for projects, issues, etc."
msgstr "Søg efter projekter, problemstillinger osv."
@@ -31605,18 +32290,12 @@ msgstr "Hemmelig"
msgid "Secret Detection"
msgstr ""
-msgid "Secret access key"
-msgstr "Hemmelig adgangsnøgle"
-
msgid "Secret token"
msgstr "Hemmelig token"
msgid "Secure token that identifies an external storage request."
msgstr ""
-msgid "SecureCodeWarrior"
-msgstr ""
-
msgid "Security"
msgstr "Sikkerhed"
@@ -31641,9 +32320,6 @@ msgstr "Sikkerhedsrapporten er forældet. Opdater venligst din gren med de senes
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr "Sikkerhedsrapporten er forældet. Kør %{newPipelineLinkStart}en ny pipeline%{newPipelineLinkEnd} for målgrenen (%{targetBranchName})"
-msgid "Security training with guide and learning pathways."
-msgstr ""
-
msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
@@ -31746,7 +32422,7 @@ msgstr ""
msgid "SecurityConfiguration|Manage corpus"
msgstr ""
-msgid "SecurityConfiguration|Manage corpus files used as mutation sources in coverage fuzzing."
+msgid "SecurityConfiguration|Manage corpus files used as seed inputs with coverage-guided fuzzing."
msgstr ""
msgid "SecurityConfiguration|Manage profiles for use by DAST scans."
@@ -31812,15 +32488,15 @@ msgstr "%{branches} og %{lastBranch} %{plural}"
msgid "SecurityOrchestration|.yaml preview"
msgstr ""
-msgid "SecurityOrchestration|Action"
-msgstr ""
-
msgid "SecurityOrchestration|Actions"
msgstr "Handlinger"
msgid "SecurityOrchestration|Add rule"
msgstr "Tilføj regel"
+msgid "SecurityOrchestration|After dismissing the alert, the information will never be shown again."
+msgstr ""
+
msgid "SecurityOrchestration|All policies"
msgstr "Alle regelsæt"
@@ -31836,7 +32512,7 @@ msgstr ""
msgid "SecurityOrchestration|Description"
msgstr "Beskrivelse"
-msgid "SecurityOrchestration|Disabled"
+msgid "SecurityOrchestration|Don't show the alert anymore"
msgstr ""
msgid "SecurityOrchestration|Edit policy"
@@ -31845,13 +32521,13 @@ msgstr "Rediger regelsæt"
msgid "SecurityOrchestration|Edit policy project"
msgstr "Rediger regelsætprojekt"
-msgid "SecurityOrchestration|Enabled"
+msgid "SecurityOrchestration|Empty policy name"
msgstr ""
-msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Enabled"
msgstr ""
-msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
msgstr ""
msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
@@ -31860,8 +32536,8 @@ msgstr ""
msgid "SecurityOrchestration|Invalid policy type"
msgstr ""
-msgid "SecurityOrchestration|Latest scan"
-msgstr "Seneste skanning"
+msgid "SecurityOrchestration|Latest scan run against %{agent}"
+msgstr ""
msgid "SecurityOrchestration|Network"
msgstr "Netværk"
@@ -31869,15 +32545,27 @@ msgstr "Netværk"
msgid "SecurityOrchestration|New policy"
msgstr "Nyt regelsæt"
+msgid "SecurityOrchestration|No actions defined - policy will not run."
+msgstr ""
+
+msgid "SecurityOrchestration|No description"
+msgstr ""
+
msgid "SecurityOrchestration|No rules defined - policy will not run."
msgstr ""
+msgid "SecurityOrchestration|Not enabled"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr "Kun ejere kan opdatere sikkerhedsregelsætprojekt"
msgid "SecurityOrchestration|Policies"
msgstr "Regelsæt"
+msgid "SecurityOrchestration|Policy Type"
+msgstr ""
+
msgid "SecurityOrchestration|Policy cannot be enabled for non-existing branches (%{branches})"
msgstr ""
@@ -31902,12 +32590,15 @@ msgstr "Regelsættype"
msgid "SecurityOrchestration|Require %{approvals} %{plural} from %{approvers} if any of the following occur:"
msgstr ""
-msgid "SecurityOrchestration|Rule"
-msgstr "Regel"
-
msgid "SecurityOrchestration|Rules"
msgstr "Regler"
+msgid "SecurityOrchestration|Runs %{actions} and %{lastAction} scans"
+msgstr ""
+
+msgid "SecurityOrchestration|Runs a %{action} scan"
+msgstr ""
+
msgid "SecurityOrchestration|Scan Execution"
msgstr ""
@@ -31965,6 +32656,9 @@ msgstr ""
msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
+msgid "SecurityOrchestration|This view only shows scan results for the agent %{agent}. You can view scan results for all agents in the %{linkStart}Operational Vulnerabilities tab of the vulnerability report%{linkEnd}."
+msgstr ""
+
msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
@@ -32019,9 +32713,6 @@ msgstr ""
msgid "SecurityOrchestration|users with ids"
msgstr ""
-msgid "SecurityOrchestration|view results"
-msgstr "vis resultater"
-
msgid "SecurityOrchestration|vulnerabilities"
msgstr ""
@@ -32691,22 +33382,19 @@ msgstr "Kopiér URL"
msgid "Serverless|Getting started with serverless"
msgstr "Kom godt i gang med serverfri"
-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|In order to start using functions as a service, you must first install Knative on your Kubernetes cluster. %{linkStart}More information%{linkEnd}"
-msgstr ""
-
msgid "Serverless|Learn more about Serverless"
msgstr "Lær mere om serverfri"
msgid "Serverless|No functions available"
msgstr "Ingen funktioner tilgængelige"
-msgid "Serverless|Sign up for First Look"
+msgid "Serverless|Serverless was %{linkStart}deprecated%{linkEnd} in GitLab 14.3."
+msgstr ""
+
+msgid "Serverless|Serverless was %{postLinkStart}deprecated%{postLinkEnd}. But if you opt to use it, you must install Knative in your Kubernetes cluster first. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "Serverless|The deploy job has not finished."
@@ -32718,9 +33406,6 @@ msgstr ""
msgid "Serverless|There is currently no function data available from Knative. This could be for a variety of reasons including:"
msgstr "Der er på nuværende tidspunkt ingen funktionsdata tilgængelige fra Knative. Det kan der være flere årsager til, herunder:"
-msgid "Serverless|We are continually striving to improve our Serverless functionality. As a Knative user, we would love to hear how we can make this experience better for you. Sign up for GitLab First Look today and we will be in touch shortly."
-msgstr ""
-
msgid "Serverless|Your %{startTag}.gitlab-ci.yml%{endTag} file is not properly configured."
msgstr "Din %{startTag}.gitlab-ci.yml%{endTag}-fil er ikke ordentligt konfigureret."
@@ -32736,9 +33421,6 @@ msgstr ""
msgid "Service Account Key"
msgstr ""
-msgid "Service Accounts"
-msgstr ""
-
msgid "Service Accounts keys authorize GitLab to deploy your Google Cloud project"
msgstr ""
@@ -32748,10 +33430,10 @@ msgstr "Serviceskranke"
msgid "Service Desk allows people to create issues in your GitLab instance without their own user account. It provides a unique email address for end users to create issues in a project. Replies can be sent either through the GitLab interface or by email. End users only see threads through email."
msgstr "Serviceskranke giver personer mulighed for at oprette problemstillinger i din GitLab-instans uden deres egen brugerkonto. Det giver en unik e-mailadressen til slutbrugeren som kan bruges til at oprette problemstillinger i et projekt. Svar kan enten sendes gennem GitLab-grænsefladen eller med e-mail. Kun slutbrugere ser tråde via e-mail."
-msgid "Service Usage Data"
+msgid "Service account generated successfully"
msgstr ""
-msgid "Service account generated successfully"
+msgid "Service accounts"
msgstr ""
msgid "Service ping is disabled in your configuration file, and cannot be enabled through this form."
@@ -32895,6 +33577,9 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
+msgid "Set the per-user rate limit for getting a user by ID via the API."
+msgstr ""
+
msgid "Set the per-user rate limit for notes created by web or API requests."
msgstr ""
@@ -33074,6 +33759,9 @@ msgstr "Delte runnere er deaktiveret på gruppeniveau"
msgid "Shared runners details"
msgstr "Detaljer for delte runnere"
+msgid "Shared runners enabled cannot be enabled until a valid credit card is on file"
+msgstr ""
+
msgid "Shared runners help link"
msgstr "Hjælpelink for delte runnere"
@@ -33131,6 +33819,9 @@ msgstr ""
msgid "Show all issues."
msgstr "Vis alle problemstillinger."
+msgid "Show all milestones"
+msgstr ""
+
msgid "Show all test cases."
msgstr ""
@@ -33167,6 +33858,9 @@ msgstr "Vis filvælger"
msgid "Show file contents"
msgstr ""
+msgid "Show group milestones"
+msgstr ""
+
msgid "Show labels"
msgstr "Vis etiketter"
@@ -33182,6 +33876,12 @@ msgstr "Vis én fil ad gangen"
msgid "Show open epics"
msgstr ""
+msgid "Show project milestones"
+msgstr ""
+
+msgid "Show sub-group milestones"
+msgstr ""
+
msgid "Show the Closed list"
msgstr "Vis listen lukket"
@@ -33191,11 +33891,6 @@ msgstr "Vis listen åbne"
msgid "Show whitespace changes"
msgstr ""
-msgid "Showing %d event"
-msgid_plural "Showing %d events"
-msgstr[0] "Viser %d begivenhed"
-msgstr[1] "Viser %d begivenheder"
-
msgid "Showing %{conflict} between %{sourceBranch} and %{targetBranch}"
msgstr ""
@@ -33255,12 +33950,6 @@ msgstr "Ingen status"
msgid "Sidebar|None"
msgstr "Ingen"
-msgid "Sidebar|Only numeral characters allowed"
-msgstr "Kun numeriske tegn er tilladt"
-
-msgid "Sidebar|Weight"
-msgstr "Vægt"
-
msgid "Sidekiq job compression threshold (bytes)"
msgstr ""
@@ -33423,6 +34112,9 @@ msgstr ""
msgid "Slack logo"
msgstr ""
+msgid "SlackIntegration|Are you sure you want to remove this project from the Slack application?"
+msgstr ""
+
msgid "SlackIntegration|GitLab for Slack"
msgstr ""
@@ -33432,6 +34124,9 @@ msgstr ""
msgid "SlackIntegration|Project alias"
msgstr ""
+msgid "SlackIntegration|Remove project"
+msgstr ""
+
msgid "SlackIntegration|Select a GitLab project to link with your Slack workspace."
msgstr ""
@@ -33576,9 +34271,6 @@ msgstr "Noget gik galt ved forsøg på at ændre den låste tilstand af denne %{
msgid "Something went wrong trying to load issue contacts."
msgstr ""
-msgid "Something went wrong when creating a work item. Please try again"
-msgstr ""
-
msgid "Something went wrong when reordering designs. Please try again"
msgstr "Noget gik galt ved omorganisering af designs. Prøv venligst igen"
@@ -33672,9 +34364,6 @@ msgstr "Noget gik galt under hentning af initiering af OpenAPI-fremviseren"
msgid "Something went wrong while inserting your image. Please try again."
msgstr "Noget gik galt under indsættelse af dit billede. Prøv venligst igen."
-msgid "Something went wrong while merging this merge request. Please try again."
-msgstr "Noget gik galt under sammenlægning af sammenlægningsanmodningen. Prøv venligst igen."
-
msgid "Something went wrong while obtaining the Let's Encrypt certificate."
msgstr "Noget gik galt under indhentelse af Let's Encrypt-certifikatet."
@@ -33996,11 +34685,11 @@ msgstr "Aktivér Sourcegraph"
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."
+msgid "SourcegraphAdmin|Learn more."
msgstr ""
-msgid "SourcegraphAdmin|More information"
-msgstr "Mere information"
+msgid "SourcegraphAdmin|Only public projects have code intelligence enabled and communicate with Sourcegraph."
+msgstr ""
msgid "SourcegraphAdmin|Save changes"
msgstr "Gem ændringer"
@@ -34008,8 +34697,8 @@ msgstr "Gem ændringer"
msgid "SourcegraphAdmin|Sourcegraph URL"
msgstr "Sourcegraph-URL"
-msgid "SourcegraphAdmin|e.g. https://sourcegraph.example.com"
-msgstr "f.eks. https://sourcegraph.example.com"
+msgid "SourcegraphAdmin|https://sourcegraph.example.com"
+msgstr ""
msgid "SourcegraphPreferences|This feature is experimental and currently limited to certain projects."
msgstr "Funktionen er eksperimentel og på nuværende tidspunkt begrænset til visse projekter."
@@ -34143,6 +34832,9 @@ msgstr "Start oprydning"
msgid "Start date"
msgstr "Startdato"
+msgid "Start free trial"
+msgstr ""
+
msgid "Start merge train"
msgstr "Start sammenlægningstog"
@@ -34173,6 +34865,9 @@ msgstr "Startet %{startsIn}"
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started escalation for this incident."
+msgstr ""
+
msgid "Starting..."
msgstr "Starter ..."
@@ -34185,6 +34880,9 @@ msgstr "Starter %{startsIn}"
msgid "Starts at (UTC)"
msgstr "Starter kl. (UTC)"
+msgid "Starts escalations for this incident"
+msgstr ""
+
msgid "Starts on"
msgstr "Starter"
@@ -34446,6 +35144,9 @@ msgstr "Ukendt"
msgid "Strikethrough"
msgstr "Gennemstreget"
+msgid "Strikethrough text"
+msgstr ""
+
msgid "Subgroup information"
msgstr ""
@@ -34680,6 +35381,21 @@ msgstr ""
msgid "Subscriptions"
msgstr "Abonnementer"
+msgid "Subscriptions|Chat with sales"
+msgstr ""
+
+msgid "Subscriptions|Close"
+msgstr ""
+
+msgid "Subscriptions|Not ready to buy yet?"
+msgstr ""
+
+msgid "Subscriptions|Start a free trial"
+msgstr ""
+
+msgid "Subscriptions|We understand. Maybe you have some questions for our sales team, or maybe you'd like to try some of the paid features first. What would you like to do?"
+msgstr ""
+
msgid "Subscription|Your subscription for %{strong}%{namespace_name}%{strong_close} has expired and you are now on %{pricing_link_start}the GitLab Free tier%{pricing_link_end}. Don't worry, your data is safe. Get in touch with our support team (%{support_email}). They'll gladly help with your subscription renewal."
msgstr ""
@@ -34890,6 +35606,9 @@ msgstr "HÃ¥ndter"
msgid "SuperSonics|Maximum users"
msgstr ""
+msgid "SuperSonics|Offline cloud"
+msgstr ""
+
msgid "SuperSonics|Paste your activation code"
msgstr "Indsæt din aktiveringskode"
@@ -34956,6 +35675,12 @@ msgstr ""
msgid "SuperSonics|You do not have an active subscription"
msgstr ""
+msgid "SuperSonics|You have a future dated license"
+msgstr ""
+
+msgid "SuperSonics|You have added a license that activates on %{date}. Please see the subscription history table below for more details."
+msgstr ""
+
msgid "SuperSonics|You have successfully added a license that activates on %{date}. Please see the subscription history table below for more details."
msgstr ""
@@ -35115,6 +35840,9 @@ msgstr "Mærkatnavn"
msgid "Tag name is required"
msgstr "Mærkatnavn kræves"
+msgid "Tag push"
+msgstr ""
+
msgid "Tag push events"
msgstr ""
@@ -35217,6 +35945,9 @@ msgstr "Skriv dine udgivelsesnoter eller træk filer hertil …"
msgid "TagsPage|protected"
msgstr "beskyttet"
+msgid "Take a look at the documentation to discover all of GitLab’s capabilities."
+msgstr ""
+
msgid "Target Branch"
msgstr "MÃ¥lgren"
@@ -35619,6 +36350,9 @@ msgstr "Du kan konfigurere dit job til at bruge enhedstestrapporter og GitLab vi
msgid "Tests"
msgstr "Tests"
+msgid "Text (optional)"
+msgstr ""
+
msgid "Text added to the body of all email messages. %{character_limit} character limit"
msgstr ""
@@ -35669,6 +36403,9 @@ msgstr ""
msgid "The CSV export will be created in the background. Once finished, it will be sent to %{email} in an attachment."
msgstr ""
+msgid "The CSV export you requested of all user memberships is attached to this email."
+msgstr ""
+
msgid "The GitLab subscription service (customers.gitlab.com) is currently experiencing an outage. You can monitor the status and get updates at %{linkStart}status.gitlab.com%{linkEnd}."
msgstr ""
@@ -35744,6 +36481,9 @@ 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 "Indholdet i gruppen, dens undergrupper og projekter vil blive fjernet permanent efter %{deletion_adjourned_period} dage %{date}. Herefter kan dine data ikke gendannes."
+msgid "The current epic"
+msgstr ""
+
msgid "The current issue"
msgstr "Den nuværende problemstilling"
@@ -35905,6 +36645,9 @@ msgstr ""
msgid "The latest pipeline for this merge request has failed."
msgstr "Den seneste pipeline for sammenlægningsanmodnigen mislykkedes."
+msgid "The license key is invalid."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr "Licensnøglen er ugyldig. Sørg for at den er præcist som du modtog den fra GitLab Inc."
@@ -35920,6 +36663,9 @@ msgstr "Licensen blev uploadet og er nu aktiv. Du kan se detaljerne nedenunder."
msgid "The license was successfully uploaded and will be active from %{starts_at}. You can see the details below."
msgstr "Licensen er blevet uploadet og vil være aktiv fra %{starts_at}. Du kan se detaljerne nedenunder."
+msgid "The license you uploaded is invalid. If the issue persists, contact support at %{link}."
+msgstr ""
+
msgid "The list creation wizard is already open"
msgstr ""
@@ -36541,10 +37287,13 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} and everything this project contains. %{strongOpen}There is no going back%{strongClose}"
+msgstr ""
+
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains."
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}on %{date}%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains. %{strongOpen}There is no going back.%{strongClose}"
msgstr ""
msgid "This action will %{strongOpen}permanently remove%{strongClose} %{codeOpen}%{group}%{codeClose} %{strongOpen}immediately%{strongClose}."
@@ -36673,9 +37422,6 @@ msgstr "Feltet kræves."
msgid "This file was modified for readability, and can't accept suggestions. Edit it directly."
msgstr ""
-msgid "This forked project has the following:"
-msgstr ""
-
msgid "This form is disabled in preview"
msgstr ""
@@ -36688,7 +37434,7 @@ msgstr ""
msgid "This group can't be removed because it is linked to a subscription. To remove this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
-msgid "This group can't be transfered because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
+msgid "This group can't be transferred because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
msgid "This group cannot be invited to a project inside a group with enforced SSO"
@@ -36715,6 +37461,9 @@ 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 incident is already escalated with '%{escalation_policy_name}'."
+msgstr ""
+
msgid "This invitation was sent to %{mail_to_invite_email}, but you are signed in as %{link_to_current_user} with email %{mail_to_current_user}."
msgstr ""
@@ -36733,9 +37482,6 @@ msgstr ""
msgid "This is a list of devices that have logged into your account. Revoke any sessions that you do not recognize."
msgstr "Dette er en liste over enheder som har logget ind på din konto. Tilbagekald sessioner som du ikke genkender."
-msgid "This is a merge train pipeline"
-msgstr ""
-
msgid "This is a private email address %{helpIcon} generated just for you. Anyone who has it can create issues or merge requests as if they were you. If that happens, %{resetLinkStart}reset this token%{resetLinkEnd}."
msgstr ""
@@ -36757,6 +37503,12 @@ msgstr ""
msgid "This is your current session"
msgstr "Dette er din nuværende session"
+msgid "This issue cannot be assigned to a confidential epic because it is public."
+msgstr ""
+
+msgid "This issue cannot be made public because it belongs to a confidential epic."
+msgstr ""
+
msgid "This issue is confidential and should only be visible to team members with at least Reporter access."
msgstr ""
@@ -36874,6 +37626,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 branch is protected from force push."
+msgstr ""
+
msgid "This merge request cannot be rebased while there are conflicts."
msgstr "Sammenlægningsanmodningen kan ikke rebases mens der er konflikter."
@@ -36925,9 +37680,15 @@ msgstr ""
msgid "This pipeline was triggered by a schedule."
msgstr "Pipelinen blev udløst af en planlægning."
+msgid "This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project"
msgstr "Projektet"
+msgid "This project can be restored until %{date}."
+msgstr ""
+
msgid "This project cannot be %{visibilityLevel} because the visibility of %{openShowLink}%{name}%{closeShowLink} is %{visibility}. To make this project %{visibilityLevel}, you must first %{openEditLink}change the visibility%{closeEditLink} of the parent group."
msgstr ""
@@ -36946,6 +37707,9 @@ msgstr "Projektet har ingen aktive adgangstokens."
msgid "This project is %{strongStart}NOT%{strongEnd} a fork, and has the following:"
msgstr ""
+msgid "This project is %{strongStart}NOT%{strongEnd} a fork. This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr "Projektet er arkiveret og kan ikke kommenteres på."
@@ -37637,6 +38401,9 @@ msgstr "Gøremålselement mærket som færdig."
msgid "Today"
msgstr "I dag"
+msgid "Todos count"
+msgstr ""
+
msgid "Todos|Are you looking for things to do? Take a look at %{strongStart}%{openIssuesLinkStart}open issues%{openIssuesLinkEnd}%{strongEnd}, contribute to %{strongStart}%{mergeRequestLinkStart}a merge request%{mergeRequestLinkEnd}%{mergeRequestLinkEnd}%{strongEnd}, or mention someone in a comment to automatically assign them a new to-do item."
msgstr ""
@@ -37910,10 +38677,8 @@ msgstr "Trævisning"
msgid "Trending"
msgstr "Trending"
-msgid "Trials|%{planName} Trial %{enDash} %{num} day left"
-msgid_plural "Trials|%{planName} Trial %{enDash} %{num} days left"
-msgstr[0] ""
-msgstr[1] ""
+msgid "Trials|%{planName} Trial"
+msgstr ""
msgid "Trials|Compare all plans"
msgstr ""
@@ -37921,6 +38686,9 @@ msgstr ""
msgid "Trials|Create a new group to start your GitLab Ultimate trial."
msgstr "Opret en ny gruppe for at starte din GitLab Ultimate-prøveperiode."
+msgid "Trials|Day %{daysUsed}/%{duration}"
+msgstr ""
+
msgid "Trials|Go back to GitLab"
msgstr "GÃ¥ tilbage til GitLab"
@@ -38170,8 +38938,8 @@ msgstr ""
msgid "URL is triggered when repository is updated"
msgstr ""
-msgid "URL must be percent-encoded if neccessary."
-msgstr "URL'en skal være procentkodet hvis det er nødvendigt."
+msgid "URL must be percent-encoded if necessary."
+msgstr ""
msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
msgstr "URL'en skal begynde med %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd} eller %{codeStart}ftp://%{codeEnd}"
@@ -38389,6 +39157,9 @@ msgstr "Oplås"
msgid "Unlock account"
msgstr "Oplås konto"
+msgid "Unlock more features with GitLab Ultimate"
+msgstr ""
+
msgid "Unlock the discussion"
msgstr "Oplås debatten"
@@ -38452,6 +39223,9 @@ msgstr "Fjernet abonnering fra %{quick_action_target}."
msgid "Unsubscribes from this %{quick_action_target}."
msgstr "Fjerner abonnering fra %{quick_action_target}."
+msgid "Unsupported sort value."
+msgstr ""
+
msgid "Unsupported todo type passed. Supported todo types are: %{todo_types}"
msgstr ""
@@ -38680,6 +39454,9 @@ msgstr ""
msgid "UsageQuota|File attachments and smaller design graphics."
msgstr ""
+msgid "UsageQuota|From %{storage_enforcement_date} storage limits will apply to this namespace. View and manage your usage in %{strong_start}Group Settings &gt; Usage quotas%{strong_end}."
+msgstr ""
+
msgid "UsageQuota|Git repository."
msgstr ""
@@ -38740,6 +39517,9 @@ msgstr "Lager"
msgid "UsageQuota|Storage type"
msgstr "Lagertype"
+msgid "UsageQuota|Storage used"
+msgstr ""
+
msgid "UsageQuota|This is the total amount of storage used across your projects within this namespace."
msgstr ""
@@ -38935,6 +39715,12 @@ msgstr ""
msgid "Use hashed storage paths for newly created and renamed repositories. Always enabled since 13.0."
msgstr ""
+msgid "Use issue count"
+msgstr ""
+
+msgid "Use issue weight"
+msgstr ""
+
msgid "Use one line per URI"
msgstr "Brug én linje pr. URI"
@@ -39316,6 +40102,9 @@ msgstr "Brugernavn: %{username}"
msgid "Users"
msgstr "Brugere"
+msgid "Users API rate limit"
+msgstr ""
+
msgid "Users can launch a development environment from a GitLab browser tab when the %{linkStart}Gitpod%{linkEnd} integration is enabled."
msgstr "Brugere kan starte et udviklingsmiljø fra et GitLab-browserfaneblad når %{linkStart}Gitpod%{linkEnd}-integreringen er aktiveret."
@@ -39641,6 +40430,9 @@ msgstr "Vis gruppe i administratorområde"
msgid "View group labels"
msgstr "Vis gruppeetiketter"
+msgid "View group pipeline usage quota"
+msgstr ""
+
msgid "View incident details at"
msgstr ""
@@ -39793,6 +40585,9 @@ msgstr "SÃ¥rbarheder"
msgid "Vulnerabilities over time"
msgstr "SÃ¥rbarheder over tid"
+msgid "Vulnerability"
+msgstr ""
+
msgid "Vulnerability Report"
msgstr "SÃ¥rbarhedsrapport"
@@ -39844,6 +40639,9 @@ msgstr ""
msgid "VulnerabilityManagement|An unverified non-confirmed finding"
msgstr ""
+msgid "VulnerabilityManagement|At least one identifier is required"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr "Ændr status"
@@ -39853,12 +40651,24 @@ msgstr ""
msgid "VulnerabilityManagement|Create Jira issue"
msgstr "Opret Jira-problemstilling"
+msgid "VulnerabilityManagement|Enter a name"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE code"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE identifier URL"
+msgstr ""
+
msgid "VulnerabilityManagement|Fetching linked Jira issues"
msgstr ""
msgid "VulnerabilityManagement|Manually add a vulnerability entry into the vulnerability report."
msgstr ""
+msgid "VulnerabilityManagement|Name is a required field"
+msgstr ""
+
msgid "VulnerabilityManagement|Needs triage"
msgstr ""
@@ -39874,6 +40684,18 @@ msgstr ""
msgid "VulnerabilityManagement|Select a method"
msgstr ""
+msgid "VulnerabilityManagement|Select a severity level"
+msgstr ""
+
+msgid "VulnerabilityManagement|Select a status"
+msgstr ""
+
+msgid "VulnerabilityManagement|Severity is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Something went wrong while creating vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr "Noget gik galt under forsøg på at slette kommentaren. Prøv venligst igen senere."
@@ -39898,6 +40720,12 @@ msgstr "Noget gik galt. Kunne ikke hente bruger."
msgid "VulnerabilityManagement|Something went wrong, could not update vulnerability state."
msgstr "Noget gik galt. Kunne ikke opdatere sårbarhedstilstand."
+msgid "VulnerabilityManagement|Status is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Submit vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Summary, detailed description, steps to reproduce, etc."
msgstr ""
@@ -40093,6 +40921,9 @@ msgstr ""
msgid "WARNING:"
msgstr "ADVARSEL:"
+msgid "WARNING: This snippet contains hidden files which might be used to mask malicious behavior. Exercise caution if cloning and executing code from this snippet."
+msgstr ""
+
msgid "Wait for the file to load to copy its contents"
msgstr ""
@@ -40312,6 +41143,15 @@ msgstr ""
msgid "Webhooks|An issue is created, updated, closed, or reopened."
msgstr ""
+msgid "Webhooks|Are you sure you want to delete this group hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this project hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this webhook?"
+msgstr ""
+
msgid "Webhooks|Comments"
msgstr "Kommentarer"
@@ -40321,6 +41161,9 @@ msgstr "Fortrolige kommentarer"
msgid "Webhooks|Confidential issues events"
msgstr "Hændelser for fortrolige problemstillinger"
+msgid "Webhooks|Delete webhook"
+msgstr ""
+
msgid "Webhooks|Deployment events"
msgstr "Hændelser for udsendelse"
@@ -40554,6 +41397,9 @@ msgstr "Hvorfor tilmelder du dig? (valgfrit)"
msgid "Wiki"
msgstr "Wiki"
+msgid "Wiki page"
+msgstr ""
+
msgid "Wiki page was successfully created."
msgstr "Wikisiden blev oprettet."
@@ -40659,8 +41505,8 @@ msgstr "Slet siden %{pageTitle}?"
msgid "WikiPageConflictMessage|Someone edited the page the same time you did. Please check out %{wikiLinkStart}the page%{wikiLinkEnd} and make sure your changes will not unintentionally remove theirs."
msgstr ""
-msgid "WikiPage|An error occured while trying to render the content editor. Please try again later."
-msgstr "Der opstod en fejl under forsøg på at gengive indholdseditoren. Prøv venligst igen senere."
+msgid "WikiPage|An error occurred while trying to render the content editor. Please try again later."
+msgstr ""
msgid "WikiPage|Are you sure you want to switch back to the classic editor?"
msgstr "Er du sikker på, at du vil skifte tilbage til den klassiske editor?"
@@ -40818,6 +41664,18 @@ msgstr ""
msgid "WorkItem|New Task"
msgstr ""
+msgid "WorkItem|Something went wrong when creating a work item. Please try again"
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching the work item. Please try again."
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching work item types. Please try again"
+msgstr ""
+
+msgid "WorkItem|Type"
+msgstr ""
+
msgid "WorkItem|Work Items"
msgstr ""
@@ -40884,8 +41742,11 @@ msgstr ""
msgid "You are about to add %{usersTag} people to the discussion. They will all receive a notification."
msgstr "Du er ved at tilføje %{usersTag} personer til debatten. De vil alle modtage en underretning."
-msgid "You are about to permanently delete this project"
-msgstr "Du er ved at slette projektet permanent"
+msgid "You are about to delete this forked project containing:"
+msgstr ""
+
+msgid "You are about to delete this project containing:"
+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 "Du er ved at overføre styringen af din konto til gruppen %{group_name}. Handlingen kan IKKE gøres om, så du vil ikke være i stand til at få adgang til dine grupper og projekter uden for %{group_name} når overførslen er gennemført."
@@ -40905,6 +41766,9 @@ msgstr "Du er ved at slette en fil som tidligere er blevet opdateret."
msgid "You are attempting to update a file that has changed since you started editing it."
msgstr ""
+msgid "You are billed if you exceed this number. %{qsrOverageLinkStart}How does billing work?%{qsrOverageLinkEnd}"
+msgstr ""
+
msgid "You are connected to the Prometheus server, but there is currently no data to display."
msgstr "Du er forbundet til Prometheus-serveren men der er i øjeblikket ingen data at vise."
@@ -40962,6 +41826,9 @@ msgstr ""
msgid "You are not authorized to update this scanner profile"
msgstr ""
+msgid "You are not authorized to upload metric images"
+msgstr ""
+
msgid "You are now impersonating %{username}"
msgstr "Du efterligner nu %{username}"
@@ -41115,9 +41982,6 @@ msgstr "Du kan kun overføre projektet til navnerum du håndterer."
msgid "You can only upload one design when dropping onto an existing design."
msgstr ""
-msgid "You can recover this project until %{date}"
-msgstr "Du kan gendanne projektet indtil %{date}"
-
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 ""
@@ -41166,9 +42030,6 @@ msgstr ""
msgid "You cannot write to this read-only GitLab instance."
msgstr "Du kan ikke skrive til denne skrivebeskyttede GitLab-instans."
-msgid "You can’t %{tag_start}edit%{tag_end} files directly in this project. Fork this project and submit a merge request with your changes."
-msgstr "Du kan ikke %{tag_start}redigere%{tag_end} filer direkte i projektet. Forgren projektet og indsend en sammenlægningsanmodning med dine ændringer."
-
msgid "You can’t edit files directly in this project. Fork this project and submit a merge request with your changes."
msgstr ""
@@ -41321,9 +42182,6 @@ msgstr "Du har ingen tilladelser"
msgid "You have not added any approvers. Start by adding users or groups."
msgstr ""
-msgid "You have reached your project limit"
-msgstr "Du har nået din projektgrænse"
-
msgid "You have set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr "Du har opsat 2FA til din konto! Hvis du mister adgang til din 2FA-enhed, så kan du bruge dine gendannelseskoder til at få adgang til din konto. Ellers kan du, hvis du uploader en SSH-nøgle, %{anchorOpen}bruge nøglen til at generere yderligere gendannelseskoder%{anchorClose}."
@@ -41354,12 +42212,6 @@ msgstr ""
msgid "You must have maintainer access to force delete a lock"
msgstr ""
-msgid "You must have permission to create a project in a group before forking."
-msgstr "Du skal have tilladelse til at oprette et projekt i en gruppe inden forgrening."
-
-msgid "You must have permission to create a project in a namespace before forking."
-msgstr "Du skal have tilladelse til at oprette et projekt i et navnerum inden forgrening."
-
msgid "You must provide a valid current password"
msgstr "Du skal angive en gyldig nuværende adgangskode"
@@ -41765,7 +42617,7 @@ msgstr "Dine projekter"
msgid "Your public email will be displayed on your public profile."
msgstr "Din offentlige e-mail vil blive vist på din offentlige profil."
-msgid "Your request for access could not be processed: %{error_meesage}"
+msgid "Your request for access could not be processed: %{error_message}"
msgstr ""
msgid "Your request for access has been queued for review."
@@ -41948,6 +42800,9 @@ msgstr "arkiveret"
msgid "archived:"
msgstr "arkiveret:"
+msgid "artifacts"
+msgstr ""
+
msgid "assign yourself"
msgstr "tildel dig selv"
@@ -41977,6 +42832,9 @@ msgstr[1] "grene"
msgid "branch name"
msgstr "grennavn"
+msgid "builds"
+msgstr ""
+
msgid "by"
msgstr "af"
@@ -42400,6 +43258,9 @@ msgstr ""
msgid "contact with same email already exists in group hierarchy"
msgstr ""
+msgid "container registry images"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -42439,6 +43300,9 @@ msgstr "oprettet af"
msgid "data"
msgstr "data"
+msgid "database"
+msgstr ""
+
msgid "date must not be after 9999-12-31"
msgstr "datoen må ikke være efter 9999-12-31"
@@ -42462,9 +43326,6 @@ msgstr "udsend"
msgid "design"
msgstr "design"
-msgid "detached"
-msgstr "løsrevet"
-
msgid "disabled"
msgstr "deaktiveret"
@@ -42713,7 +43574,7 @@ msgstr ""
msgid "is not a valid X509 certificate."
msgstr "er ikke et gyldigt X509-certifikat."
-msgid "is not allowed for sign-up."
+msgid "is not allowed for sign-up. Please use your regular email address."
msgstr ""
msgid "is not allowed for this group."
@@ -42725,7 +43586,7 @@ msgstr ""
msgid "is not allowed since the group is not top-level group."
msgstr "er ikke tilladt eftersom gruppen ikke er topniveaugruppe."
-msgid "is not allowed."
+msgid "is not allowed. Please use your regular email address."
msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
@@ -42812,6 +43673,9 @@ msgstr "mindre end et minut"
msgid "level: %{level}"
msgstr "niveau: %{level}"
+msgid "lfs objects"
+msgstr ""
+
msgid "limit of %{project_limit} reached"
msgstr ""
@@ -43031,6 +43895,9 @@ msgstr ""
msgid "mrWidget|Merge blocked: pipeline must succeed. It's waiting for a manual action to continue."
msgstr "Sammenlægning blokeret: pipeline skal lykkes. Den venter på en manuel handling for at fortsætte."
+msgid "mrWidget|Merge blocked: pipeline must succeed. Push a commit that fixes the failure, or %{linkStart}learn about other solutions.%{linkEnd}"
+msgstr ""
+
msgid "mrWidget|Merge blocked: this merge request must be approved."
msgstr ""
@@ -43148,9 +44015,6 @@ msgstr "Ændringerne blev sammenlagt i"
msgid "mrWidget|The changes were not merged into"
msgstr "Ændringerne blev ikke sammenlagt i"
-msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr "Kildegrenen er blevet slettet"
@@ -43298,9 +44162,6 @@ msgstr "kun tilgængelig på topniveaugrupper."
msgid "open issue"
msgstr "Ã¥ben problemstilling"
-msgid "opened %{timeAgo}"
-msgstr "Ã¥bnet %{timeAgo}"
-
msgid "or"
msgstr "eller"
@@ -43312,6 +44173,12 @@ msgid_plural "out of %d total tests"
msgstr[0] "ud af %d test i alt"
msgstr[1] "ud af %d tests i alt"
+msgid "packages"
+msgstr ""
+
+msgid "pages"
+msgstr ""
+
msgid "parent"
msgid_plural "parents"
msgstr[0] "forælder"
@@ -43461,6 +44328,9 @@ msgid_plural "replies"
msgstr[0] "svar"
msgstr[1] "svar"
+msgid "repositories"
+msgstr ""
+
msgid "repository:"
msgstr "depot:"
@@ -43581,12 +44451,18 @@ msgstr ""
msgid "tag name"
msgstr "mærkatnavn"
+msgid "terraform states"
+msgstr ""
+
msgid "the correct format."
msgstr ""
msgid "the file"
msgstr "filen"
+msgid "the following epic(s)"
+msgstr ""
+
msgid "the following issue(s)"
msgstr "følgende problemstillinger"
@@ -43599,21 +44475,12 @@ msgstr "efterfulgt af"
msgid "this document"
msgstr "dokumentet"
-msgid "this issue cannot be assigned to a confidential epic since it is public"
-msgstr ""
-
-msgid "this issue cannot be made public since it belongs to a confidential epic"
-msgstr ""
-
msgid "time summary"
msgstr "tidsopsummering"
msgid "toggle collapse"
msgstr "sammenfold til/fra"
-msgid "train"
-msgstr "tog"
-
msgid "triggered"
msgstr "udløst"
@@ -43742,3 +44609,6 @@ msgstr "{gruppe}"
msgid "{project}"
msgstr "{projekt}"
+msgid "✔"
+msgstr ""
+
diff --git a/locale/de/gitlab.po b/locale/de/gitlab.po
index ba82faa9a92..7058abba5bc 100644
--- a/locale/de/gitlab.po
+++ b/locale/de/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: de\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2022-02-02 15:45\n"
+"PO-Revision-Date: 2022-03-01 20:38\n"
msgid " %{start} to %{end}"
msgstr " %{start} bis %{end}"
@@ -146,6 +146,11 @@ msgid_plural "%d approvers (you've approved)"
msgstr[0] "%d Genehmigungsberechtigte(r) (Von dir genehmigt)"
msgstr[1] "%d Genehmigende (von dir genehmigt)"
+msgid "%d assigned issue"
+msgid_plural "%d assigned issues"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] "%d geänderte Datei"
@@ -421,10 +426,25 @@ msgid_plural "%d vulnerabilities dismissed"
msgstr[0] "%d Sicherheitslücke verworfen"
msgstr[1] "%d Sicherheitslücken verworfen"
-msgid "%d vulnerability updated"
-msgid_plural "%d vulnerabilities updated"
-msgstr[0] "%d Sicherheitslücke aktualisiert"
-msgstr[1] "%d Sicheitslücken aktualisiert"
+msgid "%d vulnerability set to confirmed"
+msgid_plural "%d vulnerabilities set to confirmed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to dismissed"
+msgid_plural "%d vulnerabilities set to dismissed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to needs triage"
+msgid_plural "%d vulnerabilities set to needs triage"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to resolved"
+msgid_plural "%d vulnerabilities set to resolved"
+msgstr[0] ""
+msgstr[1] ""
msgid "%d warning found:"
msgid_plural "%d warnings found:"
@@ -468,8 +488,8 @@ msgstr "%{board_target} nicht gefunden"
msgid "%{bold_start}%{count}%{bold_end} issue"
msgid_plural "%{bold_start}%{count}%{bold_end} issues"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%{bold_start}%{count}%{bold_end} Ticket"
+msgstr[1] "%{bold_start}%{count}%{bold_end} Tickets"
msgid "%{bold_start}%{count}%{bold_end} member"
msgid_plural "%{bold_start}%{count}%{bold_end} members"
@@ -510,6 +530,12 @@ msgstr[1] "%{completedCount} von %{count} Aufgaben erledigt"
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr "%{completedWeight} von %{totalWeight} Gewichtung abgeschlossen"
+msgid "%{completed} of %{total} issues closed"
+msgstr ""
+
+msgid "%{completed} of %{total} weight completed"
+msgstr ""
+
msgid "%{cores} cores"
msgstr "%{cores} Kerne"
@@ -710,7 +736,7 @@ msgid "%{labelStart}File:%{labelEnd} %{file}"
msgstr "%{labelStart}Datei:%{labelEnd} %{file}"
msgid "%{labelStart}Image:%{labelEnd} %{image}"
-msgstr ""
+msgstr "%{labelStart}Abbild:%{labelEnd} %{image}"
msgid "%{labelStart}Method:%{labelEnd} %{method}"
msgstr "%{labelStart}Methode:%{labelEnd} %{method}"
@@ -764,7 +790,7 @@ msgid "%{link_start}Start the title with %{draft_snippet}%{link_end} to prevent
msgstr ""
msgid "%{link_start}Upload a license%{link_end} file or enter the license key you have received from GitLab Inc."
-msgstr ""
+msgstr "%{link_start}Lade eine Lizenzdatei%{link_end} hoch oder gib den Lizenzschlüssel ein, den du von GitLab Inc. erhalten hast."
msgid "%{link_start}What information does GitLab Inc. collect?%{link_end}"
msgstr "%{link_start}Welche Informationen sammelt GitLab Inc.?%{link_end}"
@@ -833,7 +859,7 @@ msgid "%{name}(%{url}) namespace has run out of Shared Runner Pipeline minutes s
msgstr ""
msgid "%{name}, confirm your email address now!"
-msgstr ""
+msgstr "%{name}, bestätige jetzt deine E-Mail-Adresse!"
msgid "%{no_of_days} day"
msgid_plural "%{no_of_days} days"
@@ -858,6 +884,9 @@ msgstr "%{openedEpics} offen, %{closedEpics} geschlossen"
msgid "%{openedIssues} open, %{closedIssues} closed"
msgstr "%{openedIssues} offen, %{closedIssues} geschlossen"
+msgid "%{percentage}%% issues closed"
+msgstr ""
+
msgid "%{percentage}%% weight completed"
msgstr ""
@@ -868,10 +897,10 @@ msgid "%{percent}%{percentSymbol} complete"
msgstr "%{percent}%{percentSymbol} abgeschlossen"
msgid "%{placeholder} is not a valid color scheme"
-msgstr ""
+msgstr "%{placeholder} ist kein gültiges Farbschema"
msgid "%{placeholder} is not a valid theme"
-msgstr ""
+msgstr "%{placeholder} ist kein gültiges Theme"
msgid "%{policy_link} (notifying after %{elapsed_time} minutes unless %{status})"
msgstr ""
@@ -880,7 +909,7 @@ msgid "%{project_path} is a project that you can use to add a README to your Git
msgstr ""
msgid "%{ref} cannot be added: %{error}"
-msgstr ""
+msgstr "%{ref} kann nicht hinzugefügt werden: %{error}"
msgid "%{releases} release"
msgid_plural "%{releases} releases"
@@ -894,7 +923,7 @@ msgid "%{reportType} %{status}"
msgstr "%{reportType} %{status}"
msgid "%{reportType} detected %{totalStart}%{total}%{totalEnd} potential %{vulnMessage}"
-msgstr "%{reportType} erkannte %{totalStart}%{total}%{totalEnd} eventuell %{vulnMessage}"
+msgstr "%{reportType} erkannte %{totalStart}%{total}%{totalEnd} potentielle %{vulnMessage}"
msgid "%{reportType} detected %{totalStart}no%{totalEnd} vulnerabilities."
msgstr "%{reportType} hat %{totalStart} keine %{totalEnd} Sicherheitslücken erkannt."
@@ -998,12 +1027,12 @@ msgid "%{strong_start}%{human_size}%{strong_end} Files"
msgstr "%{strong_start}%{human_size}%{strong_end} Dateien"
msgid "%{strong_start}%{human_size}%{strong_end} Storage"
-msgstr ""
+msgstr "%{strong_start}%{human_size}%{strong_end} Speicher"
msgid "%{strong_start}%{release_count}%{strong_end} Release"
msgid_plural "%{strong_start}%{release_count}%{strong_end} Releases"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%{strong_start}%{release_count}%{strong_end} Veröffentlichung"
+msgstr[1] "%{strong_start}%{release_count}%{strong_end} Veröffentlichungen"
msgid "%{strong_start}%{tag_count}%{strong_end} Tag"
msgid_plural "%{strong_start}%{tag_count}%{strong_end} Tags"
@@ -1029,7 +1058,7 @@ msgid "%{text} is available"
msgstr "%{text} ist verfügbar"
msgid "%{timebox_name} should belong either to a project or a group."
-msgstr ""
+msgstr "%{timebox_name} sollte zu einem Projekt oder einer Gruppe gehören."
msgid "%{timebox_type} does not support burnup charts"
msgstr ""
@@ -1044,22 +1073,22 @@ msgid "%{title} changes"
msgstr "%{title} Änderungen"
msgid "%{totalCpu} (%{freeSpacePercentage}%{percentSymbol} free)"
-msgstr ""
+msgstr "%{totalCpu} (%{freeSpacePercentage}%{percentSymbol} frei)"
msgid "%{totalMemory} (%{freeSpacePercentage}%{percentSymbol} free)"
-msgstr ""
+msgstr "%{totalMemory} (%{freeSpacePercentage}%{percentSymbol} frei)"
msgid "%{totalWeight} total weight"
msgstr ""
msgid "%{total_warnings} warning(s) found:"
-msgstr ""
+msgstr "%{total_warnings} Warnung(en) gefunden:"
msgid "%{total} open issue weight"
msgstr "%{total} offenes Ticketgewicht"
msgid "%{total} warnings found: showing first %{warningsDisplayed}"
-msgstr ""
+msgstr "%{total} Warnungen gefunden: Zeige erste %{warningsDisplayed}"
msgid "%{type} only supports %{name} name"
msgstr ""
@@ -1122,10 +1151,10 @@ msgid "%{wildcards_link_start}Wildcards%{wildcards_link_end} such as %{code_tag_
msgstr ""
msgid "'%{data}' at %{location} does not match format: %{format}"
-msgstr ""
+msgstr "'%{data}' bei %{location} passt nicht zum Format: %{format}"
msgid "'%{data}' at %{location} does not match pattern: %{pattern}"
-msgstr ""
+msgstr "'%{data}' bei %{location} passt nicht zum Muster: %{pattern}"
msgid "'%{data}' at %{location} is invalid: error_type=%{type}"
msgstr ""
@@ -1137,7 +1166,7 @@ msgid "'%{data}' at %{location} is not one of: %{enum}"
msgstr ""
msgid "'%{data}' at %{location} is not: %{const}"
-msgstr ""
+msgstr "'%{data}' bei %{location} ist nicht: %{const}"
msgid "'%{level}' is not a valid visibility level"
msgstr "'%{level}' ist kein gültiger Sichtbarkeitslevel"
@@ -1166,7 +1195,7 @@ msgid "(%{mrCount} merged)"
msgstr "(%{mrCount} zusammengeführt)"
msgid "(%{value}) has already been taken"
-msgstr ""
+msgstr "(%{value}) wurde bereits verwendet"
msgid "(+%{count}&nbsp;rules)"
msgstr ""
@@ -1213,10 +1242,10 @@ msgid "(this user)"
msgstr ""
msgid "(we need your current password to confirm your changes)"
-msgstr ""
+msgstr "(aktuelles Passwort nötig, um die Änderung zu bestätigen!)"
msgid "* All times are in UTC unless specified"
-msgstr ""
+msgstr "* Alle Zeiten sind in UTC, sofern nicht anders angegeben"
msgid "*Required"
msgstr ""
@@ -1287,6 +1316,9 @@ msgid_plural "- Users"
msgstr[0] ""
msgstr[1] ""
+msgid "- of - issues closed"
+msgstr ""
+
msgid "- of - weight completed"
msgstr ""
@@ -1429,7 +1461,7 @@ msgstr "10-19 Beiträge"
msgid "1000+"
msgstr ""
-msgid "192.168.0.0/24"
+msgid "192.168.0.0/24 or 2001:0DB8:1234::/48"
msgstr ""
msgid "1st contribution!"
@@ -1490,7 +1522,7 @@ msgid "A .NET Core console application template, customizable for any .NET Core
msgstr "Eine .NET Core-Konsolenanwendungsvorlage, anpassbar für jedes .NET Core-Projekt"
msgid "A CI/CD pipeline must run and be successful before merge."
-msgstr ""
+msgstr "Vor dem Mergen muss eine CI/CD-Pipeline erfolgreich ablaufen."
msgid "A GitBook site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features"
msgstr ""
@@ -1547,7 +1579,7 @@ msgid "A group represents your organization in GitLab. Groups allow you to manag
msgstr "Eine Gruppe repräsentiert deine Organisation in GitLab. Mithilfe von Gruppen kannst du Benutzer(innen) verwalten und über mehrere Projekte hinweg zusammenarbeiten."
msgid "A job artifact is an archive of files and directories saved by a job when it finishes."
-msgstr ""
+msgstr "Ein erfolgreicher Job erzeugt und speichert ein Datei- und Verzeichnisarchiv als sein Artefakt."
msgid "A limit of %{ci_project_subscriptions_limit} subscriptions to or from a project applies."
msgstr ""
@@ -1604,7 +1636,7 @@ msgid "A ready-to-go template for use with iOS Swift apps"
msgstr ""
msgid "A rebase is already in progress."
-msgstr ""
+msgstr "Ein Rebase läuft bereits."
msgid "A sign-in to your account has been made from the following IP address: %{ip}"
msgstr "Eine Anmeldung in dein Konto ging von der folgenden IP-Adresse aus: %{ip}"
@@ -1664,7 +1696,7 @@ msgid "APIFuzzing|Customize your project's API fuzzing configuration options and
msgstr ""
msgid "APIFuzzing|Enable authentication"
-msgstr ""
+msgstr "Authentifizierung aktivieren"
msgid "APIFuzzing|Enter the name of the CI variable containing the password. For example, $VARIABLE_WITH_PASSWORD."
msgstr ""
@@ -1741,13 +1773,13 @@ msgstr ""
msgid "AWS Access Key"
msgstr "AWS Zugangsschlüssel"
-msgid "AWS Access Key. Only required if not using role instance credentials"
-msgstr ""
-
msgid "AWS Secret Access Key"
msgstr "AWS Geheimer Zugangsschlüssel"
-msgid "AWS Secret Access Key. Only required if not using role instance credentials"
+msgid "AWS access key ID (Optional)"
+msgstr ""
+
+msgid "AWS secret access key (Optional)"
msgstr ""
msgid "AWS service error: %{error}"
@@ -1781,7 +1813,7 @@ msgid "Accept terms"
msgstr "Bedingungen akzeptieren"
msgid "Acceptable for use in this project"
-msgstr ""
+msgstr "Akzeptabel für die Verwendung in diesem Projekt"
msgid "Access Git repositories or the API."
msgstr ""
@@ -1807,9 +1839,6 @@ msgstr "Zugriff verboten. Überprüfe deine Zugriffsebene."
msgid "Access granted"
msgstr "Zugriff gewährt"
-msgid "Access key ID"
-msgstr ""
-
msgid "Access requests"
msgstr ""
@@ -1901,7 +1930,7 @@ msgid "AccessibilityReport|Learn more"
msgstr ""
msgid "AccessibilityReport|Message: %{message}"
-msgstr ""
+msgstr "Nachricht: %{message}"
msgid "AccessibilityReport|New"
msgstr ""
@@ -1984,7 +2013,7 @@ msgstr ""
msgid "Activity"
msgstr "Aktivität"
-msgid "Activity|An error occured while retrieving activity. Reload the page to try again."
+msgid "Activity|An error occurred while retrieving activity. Reload the page to try again."
msgstr ""
msgid "Add"
@@ -2023,6 +2052,9 @@ msgstr "Zoom-Besprechung hinzufügen"
msgid "Add a %{type}"
msgstr ""
+msgid "Add a GCP region"
+msgstr ""
+
msgid "Add a GPG key"
msgstr "GPG-Schlüssel hinzufügen"
@@ -2074,6 +2106,9 @@ msgstr ""
msgid "Add a numbered list"
msgstr "Eine nummerierte Liste hinzufügen"
+msgid "Add a related epic"
+msgstr ""
+
msgid "Add a related issue"
msgstr ""
@@ -2156,7 +2191,7 @@ msgid "Add environment"
msgstr ""
msgid "Add existing confidential %{issuableType}"
-msgstr ""
+msgstr "Bestehende vertrauliche %{issuableType} hinzufügen"
msgid "Add header and footer to emails. Please note that color settings will only be applied within the application interface"
msgstr "Kopf- und Fußzeile zu E-Mails hinzufügen. Bitte beachte, dass Farbeinstellungen nur innerhalb des Anwendungs-Interfaces angewendet werden"
@@ -2183,11 +2218,14 @@ msgid "Add new directory"
msgstr "Erstelle eine neues Verzeichnis"
msgid "Add or remove previously merged commits"
-msgstr ""
+msgstr "Hinzufügen oder Entfernen von zuvor gemergten Commits"
msgid "Add or subtract spent time"
msgstr "Addiere oder subtrahiere verbrachte Zeit"
+msgid "Add people"
+msgstr ""
+
msgid "Add previously merged commits"
msgstr ""
@@ -2254,6 +2292,9 @@ msgstr ""
msgid "Add webhook"
msgstr "Webhook hinzufügen"
+msgid "Add your team members and others to GitLab."
+msgstr ""
+
msgid "Add/remove"
msgstr "Hinzufügen/Entfernen"
@@ -2267,7 +2308,7 @@ msgid "AddMember|Emails cannot be blank"
msgstr ""
msgid "AddMember|Invite email is invalid"
-msgstr ""
+msgstr "Einladungs-E-Mail ist ungültig"
msgid "AddMember|Invite limit of %{daily_invites} per day exceeded"
msgstr ""
@@ -3076,12 +3117,6 @@ msgstr ""
msgid "AdvancedSearch|Reindex required"
msgstr ""
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. Permanently deleting this project will %{strongStart}immediately delete%{strongEnd} its repositories and %{strongStart}all related resources%{strongEnd}, including issues, merge requests etc."
-msgstr ""
-
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. You will lose this project's repository and %{strongStart}all related resources%{strongEnd}, including issues and merge requests."
-msgstr ""
-
msgid "After a successful password update you will be redirected to login screen."
msgstr "Nach dem erfolgreichen Ändern des Passwortes wirst du zum Anmeldebildschirm weitergeleitet."
@@ -3112,6 +3147,9 @@ msgstr ""
msgid "Akismet helps prevent the creation of spam issues in public projects."
msgstr ""
+msgid "Alert"
+msgstr ""
+
msgid "AlertManagement|Acknowledged"
msgstr ""
@@ -3122,7 +3160,7 @@ msgid "AlertManagement|Alert"
msgstr ""
msgid "AlertManagement|Alert assignee(s): %{assignees}"
-msgstr ""
+msgstr "Alarm-Beauftragte(r): %{assignees}"
msgid "AlertManagement|Alert detail"
msgstr ""
@@ -3484,9 +3522,6 @@ msgstr "Alle E-Mail-Adressen werden verwendet, um deine Commits zu identifiziere
msgid "All environments"
msgstr ""
-msgid "All epics"
-msgstr ""
-
msgid "All groups and projects"
msgstr "Alle Gruppen und Projekte"
@@ -3533,7 +3568,7 @@ msgid "Allow access to members of the following group"
msgstr ""
msgid "Allow access to the following IP addresses"
-msgstr ""
+msgstr "Erlaube Zugriff auf die folgenden IP-Adressen"
msgid "Allow commits from members who can merge to the target branch."
msgstr "Erlaube Commits von Mitgliedern die zum Zielbranch mergen können."
@@ -3548,7 +3583,7 @@ msgid "Allow only the selected protocols to be used for Git access."
msgstr "Nur die ausgewählten Protokolle für den Git-Zugriff zulassen."
msgid "Allow owners to manage default branch protection per group"
-msgstr ""
+msgstr "Erlaube den Inhaber(inne)n den Standard-Branch-Schutz pro Gruppe zu verwalten"
msgid "Allow owners to manually add users outside of LDAP"
msgstr ""
@@ -3707,7 +3742,7 @@ msgid "An error occurred fetching the dropdown data."
msgstr "Beim Abrufen der Dropdown-Daten ist ein Fehler aufgetreten."
msgid "An error occurred fetching the project authors."
-msgstr ""
+msgstr "Beim Abrufen des Projektautors trat ein Fehler auf."
msgid "An error occurred fetching the public deploy keys. Please try again."
msgstr ""
@@ -3722,7 +3757,7 @@ msgid "An error occurred while acknowledging the notification. Refresh the page
msgstr ""
msgid "An error occurred while adding approvers"
-msgstr ""
+msgstr "Konnte Genehmigungsberechtigte nicht hinzufügen."
msgid "An error occurred while adding formatted title for epic"
msgstr ""
@@ -3734,7 +3769,7 @@ msgid "An error occurred while checking group path. Please refresh and try again
msgstr ""
msgid "An error occurred while decoding the file."
-msgstr ""
+msgstr "Beim Dekodieren der Datei ist ein Fehler aufgetreten."
msgid "An error occurred while deleting the approvers group"
msgstr "Beim Löschen der Genehmigungsberechtigten-Gruppe trat ein Fehler auf"
@@ -3743,7 +3778,7 @@ msgid "An error occurred while deleting the comment"
msgstr "Beim Löschen des Kommentars ist ein Fehler aufgetreten"
msgid "An error occurred while deleting the pipeline."
-msgstr ""
+msgstr "Beim Löschen der Pipeline ist ein Fehler aufgetreten."
msgid "An error occurred while detecting host keys"
msgstr "Bei der Erkennung von Hostschlüsseln ist ein Fehler aufgetreten"
@@ -4223,12 +4258,15 @@ msgstr ""
msgid "ApplicationSettings|Approve users in the pending approval status?"
msgstr ""
-msgid "ApplicationSettings|By making this change, you will automatically approve %d user with the pending approval status."
-msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users with the pending approval status."
+msgid "ApplicationSettings|Approve users who are pending approval?"
+msgstr ""
+
+msgid "ApplicationSettings|By making this change, you will automatically approve %d user who is pending approval."
+msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users who are pending approval."
msgstr[0] ""
msgstr[1] ""
-msgid "ApplicationSettings|By making this change, you will automatically approve all users in pending approval status."
+msgid "ApplicationSettings|By making this change, you will automatically approve all users who are pending approval."
msgstr ""
msgid "ApplicationSettings|Denied domains for sign-ups"
@@ -4634,10 +4672,10 @@ msgstr "Archivierte Projekte"
msgid "Archiving the project will make it entirely read-only. It is hidden from the dashboard and doesn't show up in searches. %{strong_start}The repository cannot be committed to, and no issues, comments, or other entities can be created.%{strong_end} %{link_start}Learn more.%{link_end}"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to delete this project?"
-msgstr ""
-
msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
+msgstr "Bist du ABSOLUT SICHER, dass du diese Gruppe entfernen möchstest?"
+
+msgid "Are you absolutely sure?"
msgstr ""
msgid "Are you sure that you want to archive this project?"
@@ -4673,12 +4711,18 @@ msgstr "Möchtest du diesen %{typeOfComment} wirklich entfernen?"
msgid "Are you sure you want to delete this SSH key?"
msgstr ""
+msgid "Are you sure you want to delete this comment?"
+msgstr ""
+
msgid "Are you sure you want to delete this deploy key?"
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 label?"
+msgstr ""
+
msgid "Are you sure you want to delete this pipeline schedule?"
msgstr "Bist Du sicher, dass Du diesen Pipeline-Zeitplan löschen möchtest?"
@@ -4694,9 +4738,6 @@ msgstr ""
msgid "Are you sure you want to discard your changes?"
msgstr ""
-msgid "Are you sure you want to erase this build?"
-msgstr "Bist du sicher, dass du diesen Build löschen möchtest?"
-
msgid "Are you sure you want to import %d repository?"
msgid_plural "Are you sure you want to import %d repositories?"
msgstr[0] ""
@@ -4744,6 +4785,9 @@ msgstr "Bist du sicher, dass du diese Identität entfernen willst?"
msgid "Are you sure you want to remove this list?"
msgstr ""
+msgid "Are you sure you want to remove this nickname?"
+msgstr ""
+
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?"
@@ -4756,10 +4800,10 @@ 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?"
+msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
msgstr ""
-msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
+msgid "Are you sure you want to revoke this project access token? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to stop this environment?"
@@ -4826,7 +4870,7 @@ msgid "Ask again later"
msgstr ""
msgid "Ask someone with write access to resolve it."
-msgstr ""
+msgstr "Bitte jemanden mit Schreibzugriff, das Problem zu beheben."
msgid "Ask your group owner to set up a group runner."
msgstr ""
@@ -4906,9 +4950,6 @@ msgstr ""
msgid "Assigned to %{assignee_name}"
msgstr ""
-msgid "Assigned to %{name}"
-msgstr ""
-
msgid "Assigned to me"
msgstr "Mir zugewiesen"
@@ -4973,6 +5014,9 @@ msgstr[1] "%d Dateien anhängen"
msgid "Attaching the file failed."
msgstr "Die Datei konnte nicht angehängt werden."
+msgid "Attention"
+msgstr ""
+
msgid "Audit Events"
msgstr "Audit-Ereignisse"
@@ -5135,6 +5179,12 @@ msgstr "Autorisiert bei"
msgid "Authorized applications (%{size})"
msgstr "Autorisierte Anwendungen (%{size})"
+msgid "AuthorizedApplication|Are you sure you want to revoke this application?"
+msgstr ""
+
+msgid "AuthorizedApplication|Revoke application"
+msgstr ""
+
msgid "Authors: %{authors}"
msgstr "Autoren: %{authors}"
@@ -5678,7 +5728,7 @@ msgid "Blocking issues"
msgstr ""
msgid "Blocks"
-msgstr "Blöcke"
+msgstr "Blockiert"
msgid "Blog"
msgstr "Blog"
@@ -6328,6 +6378,9 @@ msgstr ""
msgid "CICDAnalytics|Shared Runners Usage"
msgstr ""
+msgid "CICDAnalytics|Shared runner pipeline minute duration by month"
+msgstr ""
+
msgid "CICDAnalytics|Shared runner usage"
msgstr ""
@@ -6469,6 +6522,9 @@ msgstr ""
msgid "Can create groups:"
msgstr ""
+msgid "Can not delete primary training"
+msgstr ""
+
msgid "Can't apply as the source branch was deleted."
msgstr ""
@@ -6802,9 +6858,6 @@ msgstr ""
msgid "Changing any setting here requires an application restart"
msgstr ""
-msgid "Changing group URL can have unintended side effects."
-msgstr ""
-
msgid "Charts can't be displayed as the request for data has timed out. %{documentationLink}"
msgstr ""
@@ -6892,9 +6945,6 @@ msgstr "Prüfe Genehmigungsstatus"
msgid "Checking branch availability..."
msgstr "Überprüfe Verfügbarkeit des Branches..."
-msgid "Checking group URL availability..."
-msgstr ""
-
msgid "Checking group path availability..."
msgstr ""
@@ -7388,6 +7438,9 @@ msgstr ""
msgid "Clear recent searches"
msgstr "Letzte Suchen löschen"
+msgid "Clear repository checks"
+msgstr ""
+
msgid "Clear search"
msgstr "Suche löschen"
@@ -7520,9 +7573,6 @@ msgstr ""
msgid "Closed MRs"
msgstr ""
-msgid "Closed epics"
-msgstr ""
-
msgid "Closed issues"
msgstr "Geschlossene Tickets"
@@ -7559,13 +7609,13 @@ msgstr ""
msgid "Cluster level"
msgstr ""
-msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
+msgid "Cluster type must be specified for Stages::ClusterEndpointInserter"
msgstr ""
msgid "ClusterAgents|%{name} successfully deleted"
msgstr ""
-msgid "ClusterAgents|%{number} of %{total} Agents"
+msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
@@ -7607,6 +7657,15 @@ msgstr ""
msgid "ClusterAgents|Agent never connected to GitLab"
msgstr ""
+msgid "ClusterAgents|Agent version mismatch"
+msgstr ""
+
+msgid "ClusterAgents|Agent version mismatch and update"
+msgstr ""
+
+msgid "ClusterAgents|Agent version update required"
+msgstr ""
+
msgid "ClusterAgents|All"
msgstr ""
@@ -7631,7 +7690,7 @@ msgstr ""
msgid "ClusterAgents|Configuration"
msgstr ""
-msgid "ClusterAgents|Connect a cluster through the Agent"
+msgid "ClusterAgents|Connect a cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connect existing cluster"
@@ -7640,13 +7699,13 @@ msgstr ""
msgid "ClusterAgents|Connect with a certificate"
msgstr ""
-msgid "ClusterAgents|Connect with agent"
+msgid "ClusterAgents|Connect with an agent"
msgstr ""
msgid "ClusterAgents|Connect with the GitLab Agent"
msgstr ""
-msgid "ClusterAgents|Connect your cluster through the Agent"
+msgid "ClusterAgents|Connect your cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connected"
@@ -7706,7 +7765,10 @@ msgstr ""
msgid "ClusterAgents|How to register an agent?"
msgstr ""
-msgid "ClusterAgents|Install new Agent"
+msgid "ClusterAgents|How to update an agent?"
+msgstr ""
+
+msgid "ClusterAgents|Install a new agent"
msgstr ""
msgid "ClusterAgents|Last connected %{timeAgo}."
@@ -7733,7 +7795,7 @@ msgstr ""
msgid "ClusterAgents|Never connected"
msgstr ""
-msgid "ClusterAgents|No Agents"
+msgid "ClusterAgents|No agents"
msgstr ""
msgid "ClusterAgents|No clusters connected through cluster certificates"
@@ -7793,6 +7855,9 @@ msgstr ""
msgid "ClusterAgents|The agent has not been connected in a long time. There might be a connectivity issue. Last contact was %{timeAgo}."
msgstr ""
+msgid "ClusterAgents|The agent version do not match each other across your cluster's pods. This can happen when a new agent version was just deployed and Kubernetes is shutting down the old pods."
+msgstr ""
+
msgid "ClusterAgents|The recommended installation method includes the token. If you want to follow the advanced installation method provided in the docs, make sure you save the token value before you close this window."
msgstr ""
@@ -7840,6 +7905,9 @@ msgstr ""
msgid "ClusterAgents|You will need to create a token to connect to your agent"
msgstr ""
+msgid "ClusterAgents|Your agent version is out of sync with your GitLab version (v%{version}), which might cause compatibility problems. Update the agent installed on your cluster to the most recent version."
+msgstr ""
+
msgid "ClusterAgents|Your instance doesn't have the %{linkStart}GitLab Agent Server (KAS)%{linkEnd} set up. Ask a GitLab Administrator to install it."
msgstr ""
@@ -8716,9 +8784,6 @@ msgstr ""
msgid "Comma-separated list of email addresses."
msgstr ""
-msgid "Comma-separated list of users allowed to exceed the rate limit."
-msgstr ""
-
msgid "Comma-separated, e.g. '1.1.1.1, 2.2.2.0/24'"
msgstr ""
@@ -9045,6 +9110,12 @@ msgstr ""
msgid "Confidential"
msgstr "Vertraulich"
+msgid "Confidential issue"
+msgstr ""
+
+msgid "Confidential note"
+msgstr ""
+
msgid "Confidentiality"
msgstr "Vertraulichkeit"
@@ -9078,6 +9149,9 @@ msgstr ""
msgid "Configure Dependency Scanning in `.gitlab-ci.yml`, creating this file if it does not already exist"
msgstr ""
+msgid "Configure GitLab"
+msgstr ""
+
msgid "Configure GitLab runners to start using the Web Terminal. %{helpStart}Learn more.%{helpEnd}"
msgstr ""
@@ -9126,6 +9200,15 @@ msgstr "Vorhandene Installation konfigurieren"
msgid "Configure pipelines to deploy web apps, backend services, APIs and static resources to Google Cloud"
msgstr ""
+msgid "Configure region"
+msgstr ""
+
+msgid "Configure region for environment"
+msgstr ""
+
+msgid "Configure regions"
+msgstr ""
+
msgid "Configure repository mirroring."
msgstr ""
@@ -9159,6 +9242,9 @@ msgstr ""
msgid "Configure which lists are shown for anyone who visits this board"
msgstr ""
+msgid "Configure your environments to be deployed to specific geographical regions"
+msgstr ""
+
msgid "Confirm"
msgstr "Bestätigen"
@@ -9452,7 +9538,7 @@ msgid "ContainerRegistry|Keep these tags"
msgstr ""
msgid "ContainerRegistry|Last updated %{time}"
-msgstr ""
+msgstr "Zuletzt aktualisiert %{time}"
msgid "ContainerRegistry|Login"
msgstr ""
@@ -9718,7 +9804,7 @@ msgid "Contributors"
msgstr "Mitwirkende"
msgid "Control emails linked to your account"
-msgstr ""
+msgstr "Lege mit deinem Konto verknüpfte E-Mails fest"
msgid "Control how the GitLab Package Registry functions."
msgstr ""
@@ -9861,10 +9947,10 @@ msgstr ""
msgid "CorpusManagement|Actions"
msgstr ""
-msgid "CorpusManagement|Corpus are used in fuzz testing as mutation source to Improve future testing."
+msgid "CorpusManagement|Corpus file"
msgstr ""
-msgid "CorpusManagement|Corpus file"
+msgid "CorpusManagement|Corpus files are used in coverage-guided fuzz testing as seed inputs to improve testing."
msgstr ""
msgid "CorpusManagement|Corpus files must be in *.zip format. Maximum 5 GB"
@@ -9918,6 +10004,9 @@ msgstr "Konnte Admins nicht als Mitglieder hinzufügen"
msgid "Could not apply %{name} command."
msgstr ""
+msgid "Could not apply %{name} command. %{message}."
+msgstr ""
+
msgid "Could not authorize chat nickname. Try again!"
msgstr ""
@@ -10068,6 +10157,9 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
+msgid "Create a group"
+msgstr ""
+
msgid "Create a merge request"
msgstr "Merge-Request erzeugen"
@@ -10092,6 +10184,9 @@ msgstr ""
msgid "Create a personal access token on your account to pull or push via %{protocol}."
msgstr "Erstelle einen persönlichen Zugriffstoken in deinem Konto um mittels %{protocol} zu übertragen (push) oder abzurufen (pull)."
+msgid "Create a project"
+msgstr ""
+
msgid "Create an account using:"
msgstr ""
@@ -10114,7 +10209,7 @@ msgid "Create confidential merge request"
msgstr ""
msgid "Create confidential merge request and branch"
-msgstr ""
+msgstr "Vertraulichen Merge-Request und Branch erstellen"
msgid "Create directory"
msgstr "Erstelle Verzeichnis"
@@ -10455,6 +10550,9 @@ msgstr ""
msgid "Creation date"
msgstr ""
+msgid "Creator"
+msgstr ""
+
msgid "Credentials"
msgstr "Zugangsdaten"
@@ -10467,9 +10565,15 @@ msgstr ""
msgid "CredentialsInventory|Personal Access Tokens"
msgstr ""
+msgid "CredentialsInventory|Project Access Tokens"
+msgstr ""
+
msgid "CredentialsInventory|SSH Keys"
msgstr ""
+msgid "Credit card required to be on file in order to create a pipeline"
+msgstr ""
+
msgid "Credit card:"
msgstr ""
@@ -10653,9 +10757,6 @@ msgstr ""
msgid "Customer relations"
msgstr ""
-msgid "Customizable by an administrator."
-msgstr ""
-
msgid "Customizable by owners."
msgstr ""
@@ -10785,30 +10886,18 @@ msgstr ""
msgid "CycleAnalytics|%{selectedLabelsCount} selected (%{maxLabels} max)"
msgstr ""
-msgid "CycleAnalytics|%{stageCount} stages selected"
-msgstr "%{stageCount} Phasen ausgewählt"
-
-msgid "CycleAnalytics|All stages"
-msgstr ""
-
-msgid "CycleAnalytics|Average days to completion"
+msgid "CycleAnalytics|Average time to completion"
msgstr ""
msgid "CycleAnalytics|Date"
msgstr ""
-msgid "CycleAnalytics|Days to completion"
-msgstr ""
-
msgid "CycleAnalytics|Display chart filters"
msgstr "Diagrammfilter anzeigen"
msgid "CycleAnalytics|Lead Time for Changes"
msgstr ""
-msgid "CycleAnalytics|No stages selected"
-msgstr ""
-
msgid "CycleAnalytics|Number of tasks"
msgstr "Anzahl der Aufgaben"
@@ -10837,18 +10926,30 @@ msgstr ""
msgid "CycleAnalytics|Showing data for group '%{groupName}' from %{createdAfter} to %{createdBefore}"
msgstr ""
-msgid "CycleAnalytics|Stages"
+msgid "CycleAnalytics|Stage time: %{title}"
msgstr ""
msgid "CycleAnalytics|Tasks by type"
msgstr ""
-msgid "CycleAnalytics|The average time spent in the selected stage for the items that were completed on each date. Data limited to the last 500 items."
+msgid "CycleAnalytics|The average time items spent in this stage. Data limited to items completed within this date range."
msgstr ""
msgid "CycleAnalytics|The given date range is larger than 180 days"
msgstr ""
+msgid "CycleAnalytics|The total time items spent across each value stream stage. Data limited to items completed within this date range."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Stage time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Total time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|Total time"
+msgstr ""
+
msgid "CycleAnalytics|Type of work"
msgstr ""
@@ -10861,9 +10962,6 @@ msgstr ""
msgid "CycleAnalytics|project dropdown filter"
msgstr ""
-msgid "CycleAnalytics|stage dropdown"
-msgstr ""
-
msgid "DAG visualization requires at least 3 dependent jobs."
msgstr ""
@@ -10963,10 +11061,16 @@ msgstr ""
msgid "DastProfiles|AJAX spider"
msgstr ""
+msgid "DastProfiles|API"
+msgstr ""
+
+msgid "DastProfiles|API endpoint URL"
+msgstr ""
+
msgid "DastProfiles|Active"
msgstr ""
-msgid "DastProfiles|Additional request headers (Optional)"
+msgid "DastProfiles|Additional request headers (optional)"
msgstr ""
msgid "DastProfiles|Are you sure you want to delete this profile?"
@@ -10981,6 +11085,9 @@ msgstr ""
msgid "DastProfiles|Branch missing"
msgstr ""
+msgid "DastProfiles|Choose a scan method"
+msgstr ""
+
msgid "DastProfiles|Could not create the scanner profile. Please try again."
msgstr ""
@@ -11050,7 +11157,13 @@ msgstr ""
msgid "DastProfiles|Excluded URLs"
msgstr ""
-msgid "DastProfiles|Excluded URLs (Optional)"
+msgid "DastProfiles|Excluded URLs (optional)"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths (optional)"
msgstr ""
msgid "DastProfiles|Hide debug messages"
@@ -11107,9 +11220,6 @@ msgstr ""
msgid "DastProfiles|Request headers"
msgstr ""
-msgid "DastProfiles|Rest API"
-msgstr ""
-
msgid "DastProfiles|Run the AJAX spider, in addition to the traditional spider, to crawl the target site."
msgstr ""
@@ -11119,6 +11229,9 @@ msgstr ""
msgid "DastProfiles|Save profile"
msgstr ""
+msgid "DastProfiles|Scan method"
+msgstr ""
+
msgid "DastProfiles|Scan mode"
msgstr ""
@@ -11197,12 +11310,24 @@ msgstr ""
msgid "DastProfiles|Website"
msgstr ""
+msgid "DastProfiles|What does each method do?"
+msgstr ""
+
msgid "DastProfiles|You can either choose a passive scan or validate the target site from the site profile management page. %{docsLinkStart}Learn more about site validation.%{docsLinkEnd}"
msgstr ""
msgid "DastProfiles|You cannot run an active scan against an unvalidated site."
msgstr ""
+msgid "DastProfiles|folder/dast_example.har or https://example.com/dast_example.har"
+msgstr ""
+
+msgid "DastProfiles|folder/example.postman_collection.json or https://example.com/"
+msgstr ""
+
+msgid "DastProfiles|folder/openapi.json or https://example.com/openapi.json"
+msgstr ""
+
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
@@ -11310,6 +11435,9 @@ msgstr ""
msgid "DatadogIntegration|API URL"
msgstr ""
+msgid "DatadogIntegration|Custom tags in Datadog. Enter one tag per line in the %{codeOpen}key:value%{codeClose} format. %{linkOpen}How do I use tags?%{linkClose}"
+msgstr ""
+
msgid "DatadogIntegration|Environment"
msgstr ""
@@ -11328,12 +11456,18 @@ msgstr ""
msgid "DatadogIntegration|Tag all data from this GitLab instance in Datadog. Useful when managing several self-managed deployments."
msgstr ""
+msgid "DatadogIntegration|Tags"
+msgstr ""
+
msgid "DatadogIntegration|The Datadog site to send data to. To send data to the EU site, use %{codeOpen}datadoghq.eu%{codeClose}."
msgstr ""
msgid "DatadogIntegration|Trace your GitLab pipelines with Datadog."
msgstr ""
+msgid "DatadogIntegration|have an invalid format"
+msgstr ""
+
msgid "Datasource name not found"
msgstr ""
@@ -11343,9 +11477,6 @@ msgstr ""
msgid "Date merged"
msgstr ""
-msgid "Date picker"
-msgstr "Datumsauswahl"
-
msgid "Date range"
msgstr ""
@@ -11431,7 +11562,7 @@ msgid "Default description template for issues"
msgstr "Standard Beschreibungsvorlage für Tickets"
msgid "Default description template for merge requests"
-msgstr ""
+msgstr "Standard-Beschreibungsvorlage für Merge-Requests"
msgid "Default first day of the week"
msgstr "Standardwert für den ersten Wochentag"
@@ -11499,9 +11630,6 @@ msgstr ""
msgid "Definition"
msgstr ""
-msgid "Delayed Project Deletion (%{adjourned_deletion})"
-msgstr ""
-
msgid "DelayedJobs|Are you sure you want to run %{jobName} immediately? Otherwise this job will run automatically after its timer finishes."
msgstr ""
@@ -11580,10 +11708,10 @@ msgstr ""
msgid "Delete pipeline"
msgstr ""
-msgid "Delete project"
+msgid "Delete pipeline schedule"
msgstr ""
-msgid "Delete project. Are you ABSOLUTELY SURE?"
+msgid "Delete project"
msgstr ""
msgid "Delete row"
@@ -11613,6 +11741,9 @@ msgstr "Diesen Anhang löschen"
msgid "Delete this epic and all descendants?"
msgstr ""
+msgid "Delete this project"
+msgstr ""
+
msgid "Delete user list"
msgstr ""
@@ -11871,6 +12002,12 @@ msgstr ""
msgid "Deploy to..."
msgstr "Bereitstellen auf..."
+msgid "DeployBoards|To see deployment progress for your environments, make sure you are deploying to %{codeStart}$KUBE_NAMESPACE%{codeEnd} and annotating with %{codeStart}app.gitlab.com/app=$CI_PROJECT_PATH_SLUG%{codeEnd} and %{codeStart}app.gitlab.com/env=$CI_ENVIRONMENT_SLUG%{codeEnd}."
+msgstr ""
+
+msgid "DeployBoard|Kubernetes Pods"
+msgstr ""
+
msgid "DeployFreeze|Add a freeze period to prevent unintended releases during a period of time for a given environment. You must update the deployment jobs in %{filename} according to the deploy freezes added here. %{freeze_period_link_start}Learn more.%{freeze_period_link_end}"
msgstr ""
@@ -11955,9 +12092,6 @@ msgstr "Nur Lesezugriff"
msgid "DeployTokens|Active Deploy Tokens (%{active_tokens})"
msgstr "Aktive Bereitstellungstoken (%{active_tokens})"
-msgid "DeployTokens|Allows read and write access to registry images."
-msgstr ""
-
msgid "DeployTokens|Allows read and write access to the package registry."
msgstr ""
@@ -11970,6 +12104,9 @@ msgstr ""
msgid "DeployTokens|Allows read-only access to the repository."
msgstr ""
+msgid "DeployTokens|Allows write access to registry images."
+msgstr ""
+
msgid "DeployTokens|Copy deploy token"
msgstr ""
@@ -12063,12 +12200,57 @@ msgstr "Bereitstellung für"
msgid "Deploying to AWS is easy with GitLab"
msgstr ""
+msgid "Deployment"
+msgstr ""
+
msgid "Deployment Frequency"
msgstr ""
+msgid "Deployment Target|Project deployment target (optional)"
+msgstr ""
+
+msgid "Deployment Target|Select the deployment target"
+msgstr ""
+
msgid "Deployment frequency"
msgstr ""
+msgid "DeploymentTarget|GitLab Pages"
+msgstr ""
+
+msgid "DeploymentTarget|Heroku"
+msgstr ""
+
+msgid "DeploymentTarget|Infrastructure provider (Terraform, Cloudformation, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Kubernetes (GKE, EKS, OpenShift, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Managed container runtime (Fargate, Cloud Run, DigitalOcean App)"
+msgstr ""
+
+msgid "DeploymentTarget|Mobile app store"
+msgstr ""
+
+msgid "DeploymentTarget|No deployment planned"
+msgstr ""
+
+msgid "DeploymentTarget|Other hosting service"
+msgstr ""
+
+msgid "DeploymentTarget|Registry (package or container)"
+msgstr ""
+
+msgid "DeploymentTarget|Self-managed container runtime (Podman, Docker Swarm, Docker Compose)"
+msgstr ""
+
+msgid "DeploymentTarget|Serverless backend (Lambda, Cloud functions)"
+msgstr ""
+
+msgid "DeploymentTarget|Virtual machine (for example, EC2)"
+msgstr ""
+
msgid "Deployments"
msgstr ""
@@ -12107,6 +12289,9 @@ msgstr ""
msgid "Deployment|This deployment was created using the API"
msgstr ""
+msgid "Deployment|Triggerer"
+msgstr ""
+
msgid "Deployment|Waiting"
msgstr ""
@@ -12134,6 +12319,18 @@ msgstr ""
msgid "Deprecated API rate limits"
msgstr ""
+msgid "Deprecations|Feature deprecation and removal"
+msgstr ""
+
+msgid "Deprecations|For information on a possible replacement %{epicStart} learn more about Opstrace %{epicEnd}."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7 and are %{epicStart} scheduled for removal %{epicEnd} in GitLab 15.0."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7, and are %{removal_link_start} scheduled for removal %{link_end} in GitLab 15.0. For information on a possible replacement, %{opstrace_link_start} learn more about Opstrace %{link_end}."
+msgstr ""
+
msgid "Deprioritize label"
msgstr "Label entpriorisieren"
@@ -12379,10 +12576,10 @@ msgstr ""
msgid "DevopsAdoption|At least one deploy"
msgstr ""
-msgid "DevopsAdoption|At least one issue opened"
+msgid "DevopsAdoption|At least one issue created"
msgstr ""
-msgid "DevopsAdoption|At least one merge request opened"
+msgid "DevopsAdoption|At least one merge request created"
msgstr ""
msgid "DevopsAdoption|At least one pipeline successfully run"
@@ -12583,6 +12780,9 @@ msgstr ""
msgid "Direct member"
msgstr ""
+msgid "Direct members"
+msgstr ""
+
msgid "Direct non-authenticated users to this page."
msgstr ""
@@ -12614,7 +12814,7 @@ msgid "Disable group runners"
msgstr ""
msgid "Disable two-factor authentication"
-msgstr ""
+msgstr "Zwei-Faktor-Authentifizierung deaktivieren"
msgid "Disabled"
msgstr "Deaktiviert"
@@ -12699,6 +12899,9 @@ msgid_plural "Dismiss %d selected vulnerabilities as"
msgstr[0] ""
msgstr[1] ""
+msgid "Dismiss Alert"
+msgstr ""
+
msgid "Dismiss merge request promotion"
msgstr ""
@@ -12726,9 +12929,15 @@ msgstr ""
msgid "Display alerts from all configured monitoring tools."
msgstr ""
+msgid "Display milestones"
+msgstr ""
+
msgid "Display name"
msgstr ""
+msgid "Display progress of child issues"
+msgstr ""
+
msgid "Display rendered file"
msgstr ""
@@ -12834,6 +13043,9 @@ msgstr "Export herunterladen"
msgid "Download image"
msgstr "Bild herunterladen"
+msgid "Download payload"
+msgstr ""
+
msgid "Download raw data (.csv)"
msgstr ""
@@ -13011,6 +13223,9 @@ msgstr "Identität für %{user_name} bearbeiten"
msgid "Edit in Web IDE"
msgstr ""
+msgid "Edit in pipeline editor"
+msgstr ""
+
msgid "Edit in single-file editor"
msgstr ""
@@ -13053,6 +13268,9 @@ msgstr "Wiki-Seite bearbeiten"
msgid "Edit your most recent comment in a thread (from an empty textarea)"
msgstr ""
+msgid "Edit, lint, and visualize your pipeline."
+msgstr ""
+
msgid "Edited"
msgstr ""
@@ -13494,6 +13712,9 @@ msgstr ""
msgid "Enforce two-factor authentication for all user sign-ins."
msgstr ""
+msgid "Enhance security by storing service account keys in secret managers - learn more about %{docLinkStart}secret management with GitLab%{docLinkEnd}"
+msgstr ""
+
msgid "Ensure connectivity is available from the GitLab server to the Prometheus server"
msgstr ""
@@ -13554,6 +13775,9 @@ 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 following to confirm:"
+msgstr ""
+
msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
@@ -14084,9 +14308,6 @@ 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 ""
@@ -14097,19 +14318,19 @@ msgid "Error occurred. User was not banned"
msgstr ""
msgid "Error occurred. User was not blocked"
-msgstr ""
+msgstr "Fehler aufgetreten. Nutzer:in wurde nicht blockiert"
msgid "Error occurred. User was not confirmed"
-msgstr ""
+msgstr "Fehler aufgetreten. Nutzer:in wurde nicht bestätigt"
msgid "Error occurred. User was not unbanned"
msgstr ""
msgid "Error occurred. User was not unblocked"
-msgstr ""
+msgstr "Fehler aufgetreten. Nutzer:in nicht reaktiviert"
msgid "Error occurred. User was not unlocked"
-msgstr ""
+msgstr "Fehler aufgetreten. Nutzer:in wurde nicht entsperrt"
msgid "Error parsing CSV file. Please make sure it has"
msgstr ""
@@ -14222,6 +14443,9 @@ msgstr ""
msgid "Errors:"
msgstr "Fehler:"
+msgid "Escalate this incident"
+msgstr ""
+
msgid "Escalation Policies"
msgstr ""
@@ -14234,6 +14458,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy"
+msgstr ""
+
msgid "Escalation policy:"
msgstr ""
@@ -14485,6 +14712,9 @@ msgstr ""
msgid "Existing sign in methods may be removed"
msgstr ""
+msgid "Exit."
+msgstr ""
+
msgid "Expand"
msgstr "Aufklappen"
@@ -14581,6 +14811,9 @@ msgstr "Projekte entdecken"
msgid "Explore public groups"
msgstr "Erkunde öffentliche Gruppen"
+msgid "Explore public projects"
+msgstr ""
+
msgid "Explore snippets"
msgstr ""
@@ -14742,7 +14975,7 @@ msgid_plural "Failed to archive designs. Please try again."
msgstr[0] ""
msgstr[1] ""
-msgid "Failed to assign a reviewer because no user was found."
+msgid "Failed to assign a reviewer because no user was specified."
msgstr ""
msgid "Failed to assign a user because no user was found."
@@ -14808,10 +15041,10 @@ msgstr ""
msgid "Failed to find import label for Jira import."
msgstr ""
-msgid "Failed to generate export, please try again later."
+msgid "Failed to find users for %{missing}"
msgstr ""
-msgid "Failed to generate report, please try again after sometime"
+msgid "Failed to generate export, please try again later."
msgstr ""
msgid "Failed to get ref."
@@ -14881,7 +15114,7 @@ msgid "Failed to mark this issue as a duplicate because referenced issue was not
msgstr ""
msgid "Failed to move this issue because label was not found."
-msgstr ""
+msgstr "Konnte Ticket nicht verschieben, da das Label nicht gefunden wurde."
msgid "Failed to move this issue because only a single label can be provided."
msgstr ""
@@ -14910,6 +15143,9 @@ msgstr ""
msgid "Failed to remove a to-do item for the design."
msgstr ""
+msgid "Failed to remove attention because no user was found."
+msgstr ""
+
msgid "Failed to remove mirror."
msgstr "Fehler beim Entfernen des Mirrors."
@@ -14922,6 +15158,9 @@ msgstr ""
msgid "Failed to remove user key."
msgstr ""
+msgid "Failed to request attention because no user was found."
+msgstr ""
+
msgid "Failed to reset key. Please try again."
msgstr ""
@@ -14935,13 +15174,13 @@ msgid "Failed to save new settings"
msgstr ""
msgid "Failed to save preferences (%{error_message})."
-msgstr ""
+msgstr "Speichern der Einstellungen fehlgeschlagen (%{error_message})."
msgid "Failed to save preferences."
msgstr ""
msgid "Failed to set due date because the date format is invalid."
-msgstr ""
+msgstr "Konnte Fälligkeitsdatum wegen ungültigen Formats nicht festlegen."
msgid "Failed to set iteration on this issue. Please try again."
msgstr ""
@@ -15003,6 +15242,9 @@ msgstr ""
msgid "Feature Flags"
msgstr "Feature Flags"
+msgid "Feature deprecation and removal"
+msgstr ""
+
msgid "Feature flag status"
msgstr ""
@@ -15500,7 +15742,7 @@ msgstr ""
msgid "For each job, re-use the project workspace. If the workspace doesn't exist, use %{code_open}git clone%{code_close}."
msgstr ""
-msgid "For example, the application using the token or the purpose of the token."
+msgid "For example, the application using the token or the purpose of the token. Do not give sensitive information for the name of the token, as it will be visible to all %{resource_type} members."
msgstr ""
msgid "For files larger than this limit, only index the file name. The file content is neither indexed nor searchable."
@@ -15584,9 +15826,6 @@ msgstr ""
msgid "ForkProject|Select a namespace"
msgstr ""
-msgid "ForkProject|Select a namespace to fork the project"
-msgstr ""
-
msgid "ForkProject|The project can be accessed by any logged in user."
msgstr ""
@@ -15683,6 +15922,9 @@ msgstr ""
msgid "Full name"
msgstr ""
+msgid "GCP region configured"
+msgstr ""
+
msgid "GPG Key ID:"
msgstr ""
@@ -15863,6 +16105,9 @@ msgstr ""
msgid "Geo|Failed"
msgstr "Fehlgeschlagen"
+msgid "Geo|Filter Geo sites"
+msgstr ""
+
msgid "Geo|Filter by name"
msgstr ""
@@ -16274,6 +16519,12 @@ msgstr "GitLab-Import"
msgid "GitLab Issue"
msgstr ""
+msgid "GitLab KAS"
+msgstr ""
+
+msgid "GitLab Memberships CSV Export"
+msgstr ""
+
msgid "GitLab Pages"
msgstr ""
@@ -16322,6 +16573,9 @@ 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 free to use. Many features for larger teams are part of our %{link_start}paid products%{link_end}. You can try Ultimate for free without any obligation or payment details."
+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 ""
@@ -16448,7 +16702,7 @@ msgstr ""
msgid "GitLabPages|When enabled, all attempts to visit your website through HTTP are automatically redirected to HTTPS using a response with status code 301. Requires a valid certificate for all domains. %{docs_link_start}Learn more.%{link_end}"
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. %{docs_link_start}Learn more.%{link_end}"
+msgid "GitLabPages|When using Pages under the general domain of a GitLab instance (%{pages_host}), you cannot use HTTPS with subdomains of subdomains. If your namespace or groupname contains a dot, it does not work. This is a limitation of the HTTP Over TLS protocol. HTTP pages work if you don't redirect HTTP to HTTPS. %{docs_link_start}Learn more.%{link_end}"
msgstr ""
msgid "GitLabPages|With GitLab Pages you can host your static website directly from your GitLab repository. %{docs_link_start}Learn more.%{link_end}"
@@ -16625,9 +16879,6 @@ msgstr ""
msgid "Go to find file"
msgstr ""
-msgid "Go to fork"
-msgstr ""
-
msgid "Go to issue boards"
msgstr ""
@@ -16835,9 +17086,6 @@ msgstr "Gruppen-Git-LFS-Status:"
msgid "Group Hooks"
msgstr "Gruppen-Hooks"
-msgid "Group ID"
-msgstr "Gruppen-ID"
-
msgid "Group Owner must have signed in with SAML before enabling Group Managed Accounts"
msgstr ""
@@ -16865,9 +17113,6 @@ msgstr "Gruppenavatar"
msgid "Group by"
msgstr ""
-msgid "Group description"
-msgstr ""
-
msgid "Group description (optional)"
msgstr "Gruppenbeschreibung (optional)"
@@ -16982,7 +17227,7 @@ msgstr "Gruppe: %{group_name}"
msgid "Group: %{name}"
msgstr ""
-msgid "GroupActivityMetrics|Issues opened"
+msgid "GroupActivityMetrics|Issues created"
msgstr ""
msgid "GroupActivityMetrics|Last 90 days"
@@ -16991,7 +17236,7 @@ msgstr ""
msgid "GroupActivityMetrics|Members added"
msgstr ""
-msgid "GroupActivityMetrics|Merge Requests opened"
+msgid "GroupActivityMetrics|Merge Requests created"
msgstr ""
msgid "GroupActivityMetrics|Recent activity"
@@ -17282,6 +17527,9 @@ msgstr ""
msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
+msgid "GroupSettings|Choose a group path that does not start with a dash or end with a period. It can also contain alphanumeric characters and underscores."
+msgstr ""
+
msgid "GroupSettings|Compliance frameworks"
msgstr ""
@@ -17315,7 +17563,7 @@ msgstr "Gruppe exportieren"
msgid "GroupSettings|If not specified at the group or instance level, the default is %{default_initial_branch_name}. Does not affect existing repositories."
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."
+msgid "GroupSettings|If the parent group's visibility is lower than the group's current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility."
msgstr ""
msgid "GroupSettings|New runners registration token has been generated!"
@@ -17432,7 +17680,10 @@ msgstr ""
msgid "Groups and projects"
msgstr ""
-msgid "Groups and subgroups"
+msgid "Groups are a great way to organize projects and people."
+msgstr ""
+
+msgid "Groups are the best way to manage projects and members."
msgstr ""
msgid "Groups to synchronize"
@@ -17543,14 +17794,17 @@ msgstr ""
msgid "GroupsTree|Are you sure you want to leave the \"%{fullName}\" group?"
msgstr "Bist du sicher, dass du die Gruppe \"%{fullName}\" verlassen willst?"
-msgid "GroupsTree|Edit group"
-msgstr "Gruppe bearbeiten"
+msgid "GroupsTree|Delete"
+msgstr ""
+
+msgid "GroupsTree|Edit"
+msgstr ""
msgid "GroupsTree|Failed to leave the group. Please make sure you are not the only owner."
msgstr "Konnte die Gruppe nicht verlassen. Bitte stelle sicher, dass du nicht der/die einzige Besitzer(in) bist."
-msgid "GroupsTree|Leave this group"
-msgstr "Diese Gruppe verlassen"
+msgid "GroupsTree|Leave group"
+msgstr ""
msgid "GroupsTree|Loading groups"
msgstr "Lade Gruppen"
@@ -17561,9 +17815,57 @@ msgstr "Keine Gruppen entsprachen Ihrer Suche"
msgid "GroupsTree|No groups or projects matched your search"
msgstr "Keine Gruppen oder Projekte entsprachen deiner Suche"
+msgid "GroupsTree|Options"
+msgstr ""
+
msgid "GroupsTree|Search by name"
msgstr "Nach Namen suchen"
+msgid "Groups|Avatar will be removed. Are you sure?"
+msgstr ""
+
+msgid "Groups|Changing group URL can have unintended side effects."
+msgstr ""
+
+msgid "Groups|Checking group URL availability..."
+msgstr ""
+
+msgid "Groups|Enter a descriptive name for your group."
+msgstr ""
+
+msgid "Groups|Group ID"
+msgstr ""
+
+msgid "Groups|Group URL"
+msgstr ""
+
+msgid "Groups|Group avatar"
+msgstr ""
+
+msgid "Groups|Group description (optional)"
+msgstr ""
+
+msgid "Groups|Group name"
+msgstr ""
+
+msgid "Groups|Group path is available."
+msgstr ""
+
+msgid "Groups|Group path is unavailable. Path has been replaced with a suggested available path."
+msgstr ""
+
+msgid "Groups|Learn more"
+msgstr ""
+
+msgid "Groups|Must start with letter, digit, emoji, or underscore. Can also contain periods, dashes, spaces, and parentheses."
+msgstr ""
+
+msgid "Groups|Remove avatar"
+msgstr ""
+
+msgid "Groups|Save changes"
+msgstr ""
+
msgid "Guideline"
msgstr ""
@@ -17573,6 +17875,9 @@ msgstr ""
msgid "HAR file path or URL"
msgstr ""
+msgid "HTTP Archive (HAR)"
+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 ""
@@ -17973,6 +18278,9 @@ msgstr ""
msgid "INFO: Your SSH key is expiring soon. Please generate a new key."
msgstr ""
+msgid "IP"
+msgstr ""
+
msgid "IP Address"
msgstr "IP-Adresse"
@@ -18009,6 +18317,9 @@ msgstr ""
msgid "IdentityVerification|Verify your identity"
msgstr ""
+msgid "IdentityVerification|You can always verify your account at a later time to create a group."
+msgstr ""
+
msgid "If any indexed field exceeds this limit, it is truncated to this number of characters. The rest of the content is neither indexed nor searchable. This does not apply to repository and wiki indexing. For unlimited characters, set this to 0."
msgstr ""
@@ -18066,6 +18377,9 @@ msgstr "Wenn du GitHub verwendest, siehst du den Pipeline-Status für deine Comm
msgid "If you add %{codeStart}needs%{codeEnd} to jobs in your pipeline you'll be able to view the %{codeStart}needs%{codeEnd} relationships between jobs in this tab as a %{linkStart}Directed Acyclic Graph (DAG)%{linkEnd}."
msgstr ""
+msgid "If you are added to a project, it will be displayed here."
+msgstr ""
+
msgid "If you did not initiate these sign-in attempts, please reach out to your administrator or enable two-factor authentication (2FA) on your account."
msgstr ""
@@ -18372,12 +18686,24 @@ msgstr ""
msgid "InProductMarketing|3 ways to dive into GitLab CI/CD"
msgstr ""
+msgid "InProductMarketing|A single application eliminates complex integrations, data chokepoints, and toolchain maintenance, resulting in greater productivity and lower cost."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features, build more efficiently, strengthen security and compliance."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features."
+msgstr ""
+
msgid "InProductMarketing|Actually, GitLab makes the team work (better)"
msgstr ""
msgid "InProductMarketing|And finally %{deploy_link} a Python application."
msgstr ""
+msgid "InProductMarketing|And many more..."
+msgstr ""
+
msgid "InProductMarketing|Are your runners ready?"
msgstr ""
@@ -18396,15 +18722,33 @@ msgstr ""
msgid "InProductMarketing|Blog"
msgstr ""
+msgid "InProductMarketing|Break down silos to coordinate seamlessly across development, operations, and security with a consistent experience across the development lifecycle."
+msgstr ""
+
+msgid "InProductMarketing|Burn up/down charts"
+msgstr ""
+
msgid "InProductMarketing|By enabling code owners and required merge approvals the right person will review the right MR. This is a win-win: cleaner code and a more efficient review process."
msgstr ""
msgid "InProductMarketing|Click on the number below that corresponds with your answer — 1 being very difficult, 5 being very easy."
msgstr ""
+msgid "InProductMarketing|Code owners"
+msgstr ""
+
msgid "InProductMarketing|Code owners and required merge approvals are part of the paid tiers of GitLab. You can start a free 30-day trial of GitLab Ultimate and enable these features in less than 5 minutes with no credit card required."
msgstr ""
+msgid "InProductMarketing|Code review analytics"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration across stages in GitLab"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration made easy"
+msgstr ""
+
msgid "InProductMarketing|Create a custom CI runner with just a few clicks"
msgstr ""
@@ -18414,12 +18758,21 @@ msgstr ""
msgid "InProductMarketing|Create a project in GitLab in 5 minutes"
msgstr ""
+msgid "InProductMarketing|Create well-defined workflows by using scoped labels on issues, merge requests, and epics. Labels with the same scope cannot be used together, which prevents conflicts."
+msgstr ""
+
msgid "InProductMarketing|Create your first project!"
msgstr ""
+msgid "InProductMarketing|Define who owns specific files or directories, so the right reviewers are suggested when a merge request introduces changes to those files."
+msgstr ""
+
msgid "InProductMarketing|Deliver Better Products Faster"
msgstr ""
+msgid "InProductMarketing|Dependency scanning"
+msgstr ""
+
msgid "InProductMarketing|Did you know teams that use GitLab are far more efficient?"
msgstr ""
@@ -18429,15 +18782,27 @@ msgstr ""
msgid "InProductMarketing|Dig in and create a project and a repo"
msgstr ""
+msgid "InProductMarketing|Discover Premium & Ultimate"
+msgstr ""
+
+msgid "InProductMarketing|Discover Premium & Ultimate."
+msgstr ""
+
msgid "InProductMarketing|Do you have a minute?"
msgstr ""
msgid "InProductMarketing|Do you have a teammate who would be perfect for this task?"
msgstr ""
+msgid "InProductMarketing|Dynamic application security testing"
+msgstr ""
+
msgid "InProductMarketing|Easy"
msgstr ""
+msgid "InProductMarketing|Epics"
+msgstr ""
+
msgid "InProductMarketing|Expand your DevOps journey with a free GitLab trial"
msgstr ""
@@ -18459,9 +18824,15 @@ msgstr ""
msgid "InProductMarketing|Feel the need for speed?"
msgstr ""
+msgid "InProductMarketing|Find and fix bottlenecks in your code review process by understanding how long open merge requests have been in review."
+msgstr ""
+
msgid "InProductMarketing|Find out how your teams are really doing"
msgstr ""
+msgid "InProductMarketing|Find out if your external libraries are safe. Run dependency scanning jobs that check for known vulnerabilities in your external libraries."
+msgstr ""
+
msgid "InProductMarketing|Follow our steps"
msgstr ""
@@ -18498,6 +18869,9 @@ msgstr ""
msgid "InProductMarketing|GitLab is better with teammates to help out!"
msgstr ""
+msgid "InProductMarketing|GitLab is infrastructure agnostic (supporting GCP, AWS, Azure, OpenShift, VMWare, On Prem, Bare Metal, and more), offering a consistent workflow experience – irrespective of the environment."
+msgstr ""
+
msgid "InProductMarketing|GitLab provides static application security testing (SAST), dynamic application security testing (DAST), container scanning, and dependency scanning to help you deliver secure applications along with license compliance."
msgstr ""
@@ -18588,21 +18962,36 @@ msgstr ""
msgid "InProductMarketing|It's also possible to simply %{external_repo_link} in order to take advantage of GitLab's CI/CD."
msgstr ""
+msgid "InProductMarketing|Keep your code quality high by defining who should approve merge requests and how many approvals are required."
+msgstr ""
+
msgid "InProductMarketing|Launch GitLab CI/CD in 20 minutes or less"
msgstr ""
+msgid "InProductMarketing|Lower cost of development"
+msgstr ""
+
+msgid "InProductMarketing|Make it easier to collaborate on high-level ideas by grouping related issues in an epic."
+msgstr ""
+
msgid "InProductMarketing|Making the switch? It's easier than you think to import your projects into GitLab. Move %{github_link}, or import something %{bitbucket_link}."
msgstr ""
msgid "InProductMarketing|Master the art of importing!"
msgstr ""
+msgid "InProductMarketing|Merge request approval rule"
+msgstr ""
+
msgid "InProductMarketing|Move on to easily creating a Pages website %{ci_template_link}"
msgstr ""
msgid "InProductMarketing|Multiple owners, confusing workstreams? We've got you covered"
msgstr ""
+msgid "InProductMarketing|Multiple required approvers"
+msgstr ""
+
msgid "InProductMarketing|Need an alternative to importing?"
msgstr ""
@@ -18615,18 +19004,33 @@ msgstr ""
msgid "InProductMarketing|Our tool brings all the things together"
msgstr ""
+msgid "InProductMarketing|Protect your web application by using DAST to examine for vulnerabilities in deployed environments."
+msgstr ""
+
msgid "InProductMarketing|Rapid development, simplified"
msgstr ""
msgid "InProductMarketing|Reduce Security & Compliance Risk"
msgstr ""
+msgid "InProductMarketing|Require multiple approvers on a merge request, so you know it's in good shape before it's merged."
+msgstr ""
+
+msgid "InProductMarketing|Roadmaps"
+msgstr ""
+
+msgid "InProductMarketing|Scoped labels"
+msgstr ""
+
msgid "InProductMarketing|Security that's integrated into your development lifecycle"
msgstr ""
msgid "InProductMarketing|Sometimes you're not ready to make a full transition to a new tool. If you're not ready to fully commit, %{mirroring_link} gives you a safe way to try out GitLab in parallel with your current tool."
msgstr ""
+msgid "InProductMarketing|Speed. Efficiency. Trust."
+msgstr ""
+
msgid "InProductMarketing|Spin up an autoscaling runner in GitLab"
msgstr ""
@@ -18636,6 +19040,9 @@ msgstr ""
msgid "InProductMarketing|Start a Self-Managed trial"
msgstr ""
+msgid "InProductMarketing|Start a free trial"
+msgstr ""
+
msgid "InProductMarketing|Start a free trial of GitLab Ultimate – no credit card required"
msgstr ""
@@ -18702,6 +19109,9 @@ msgstr ""
msgid "InProductMarketing|To understand and get the most out of GitLab, start at the beginning and %{project_link}. In GitLab, repositories are part of a project, so after you've created your project you can go ahead and %{repo_link}."
msgstr ""
+msgid "InProductMarketing|Track completed issues in a chart, so you can see how a milestone is progressing at a glance."
+msgstr ""
+
msgid "InProductMarketing|Try GitLab Ultimate for free"
msgstr ""
@@ -18738,6 +19148,9 @@ msgstr ""
msgid "InProductMarketing|Very easy"
msgstr ""
+msgid "InProductMarketing|Visualize your epics and milestones in a timeline."
+msgstr ""
+
msgid "InProductMarketing|Want to host GitLab on your servers?"
msgstr ""
@@ -18759,6 +19172,9 @@ msgstr ""
msgid "InProductMarketing|YouTube"
msgstr ""
+msgid "InProductMarketing|Your software, deployed your way"
+msgstr ""
+
msgid "InProductMarketing|Your teams can be more efficient"
msgstr ""
@@ -18879,9 +19295,18 @@ msgstr ""
msgid "IncidentManagement|No incidents to display."
msgstr ""
+msgid "IncidentManagement|None"
+msgstr ""
+
msgid "IncidentManagement|Open"
msgstr ""
+msgid "IncidentManagement|Page your team with escalation policies"
+msgstr ""
+
+msgid "IncidentManagement|Paged"
+msgstr ""
+
msgid "IncidentManagement|Published"
msgstr ""
@@ -18891,6 +19316,9 @@ msgstr ""
msgid "IncidentManagement|Severity"
msgstr ""
+msgid "IncidentManagement|Status"
+msgstr ""
+
msgid "IncidentManagement|There are no closed incidents"
msgstr ""
@@ -18909,6 +19337,9 @@ msgstr ""
msgid "IncidentManagement|Unpublished"
msgstr ""
+msgid "IncidentManagement|Use escalation policies to automatically page your team when incidents are created."
+msgstr ""
+
msgid "IncidentSettings|Activate \"time to SLA\" countdown timer"
msgstr ""
@@ -18954,7 +19385,10 @@ msgstr ""
msgid "Incidents"
msgstr ""
-msgid "Incidents|Add a URL"
+msgid "Incidents|Add image details"
+msgstr ""
+
+msgid "Incidents|Add text or a link to display with your image. If you don't add either, the file name displays instead."
msgstr ""
msgid "Incidents|Drop or %{linkStart}upload%{linkEnd} a metric screenshot to attach it to the incident"
@@ -18969,10 +19403,10 @@ msgstr ""
msgid "Incidents|There was an issue loading metric images."
msgstr ""
-msgid "Incidents|There was an issue uploading your image."
+msgid "Incidents|There was an issue updating your image."
msgstr ""
-msgid "Incidents|You can optionally add a URL to link users to the original graph."
+msgid "Incidents|There was an issue uploading your image."
msgstr ""
msgid "Incident|Alert details"
@@ -18981,9 +19415,18 @@ msgstr ""
msgid "Incident|Are you sure you wish to delete this image?"
msgstr ""
+msgid "Incident|Delete image"
+msgstr ""
+
msgid "Incident|Deleting %{filename}"
msgstr ""
+msgid "Incident|Edit image text or link"
+msgstr ""
+
+msgid "Incident|Editing %{filename}"
+msgstr ""
+
msgid "Incident|Metrics"
msgstr ""
@@ -19253,12 +19696,18 @@ msgstr ""
msgid "Integrations|Branches for which notifications are to be sent"
msgstr ""
+msgid "Integrations|Clear if using a self-signed certificate."
+msgstr ""
+
msgid "Integrations|Comment detail:"
msgstr ""
msgid "Integrations|Comment settings:"
msgstr ""
+msgid "Integrations|Connection details"
+msgstr ""
+
msgid "Integrations|Connection failed. Please check your settings."
msgstr ""
@@ -19283,6 +19732,9 @@ msgstr ""
msgid "Integrations|Enable GitLab.com slash commands in a Slack workspace."
msgstr ""
+msgid "Integrations|Enable SSL verification"
+msgstr ""
+
msgid "Integrations|Enable comments"
msgstr ""
@@ -19361,6 +19813,9 @@ msgstr ""
msgid "Integrations|Return to GitLab for Jira"
msgstr ""
+msgid "Integrations|SSL verification"
+msgstr ""
+
msgid "Integrations|Save settings?"
msgstr ""
@@ -19406,9 +19861,6 @@ msgstr ""
msgid "Integrations|Use default settings"
msgstr ""
-msgid "Integrations|When you mention a Jira issue in a commit or merge request, GitLab creates a remote link and comment (if enabled)."
-msgstr ""
-
msgid "Integrations|You can now close this window and return to the GitLab for Jira application."
msgstr ""
@@ -19433,9 +19885,6 @@ msgstr ""
msgid "Integrations|can't exceed %{recipients_limit}"
msgstr ""
-msgid "Interactive developer security education."
-msgstr ""
-
msgid "Interactive mode"
msgstr ""
@@ -19925,6 +20374,9 @@ msgstr ""
msgid "IssueAnalytics|Assignees"
msgstr ""
+msgid "IssueAnalytics|Created by"
+msgstr ""
+
msgid "IssueAnalytics|Due date"
msgstr ""
@@ -19937,9 +20389,6 @@ msgstr ""
msgid "IssueAnalytics|Milestone"
msgstr ""
-msgid "IssueAnalytics|Opened by"
-msgstr ""
-
msgid "IssueAnalytics|Status"
msgstr ""
@@ -20063,11 +20512,11 @@ msgstr ""
msgid "IssuesAnalytics|Avg/Month:"
msgstr ""
-msgid "IssuesAnalytics|Issues opened"
-msgstr "Geöffnete Issues"
+msgid "IssuesAnalytics|Issues created"
+msgstr ""
-msgid "IssuesAnalytics|Issues opened per month"
-msgstr "Geöffnete Issues pro Monat"
+msgid "IssuesAnalytics|Issues created per month"
+msgstr ""
msgid "IssuesAnalytics|Last 12 months"
msgstr "Letzten 12 Monate"
@@ -20093,6 +20542,9 @@ msgstr ""
msgid "It looks like you have some draft commits in this branch."
msgstr ""
+msgid "It looks like you're attempting to activate your subscription. Use %{a_start}the Subscription page%{a_end} instead."
+msgstr ""
+
msgid "It may be several days before you see feature usage data."
msgstr ""
@@ -20321,6 +20773,9 @@ msgstr ""
msgid "JiraConnect|You can now close this window and return to Jira."
msgstr ""
+msgid "JiraConnect|You don't have permission to create branches for this project. Select a different project or contact the project owner for access. %{linkStart}Learn more.%{linkEnd}"
+msgstr ""
+
msgid "JiraRequest|A connection error occurred while connecting to Jira. Try your request again."
msgstr ""
@@ -20369,13 +20824,13 @@ msgstr ""
msgid "JiraService|Define the type of Jira issue to create from a vulnerability."
msgstr ""
-msgid "JiraService|Displaying Jira issues while leaving the GitLab issue functionality enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
+msgid "JiraService|Displaying Jira issues while leaving GitLab issues also enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
msgstr ""
-msgid "JiraService|Enable Jira issues"
+msgid "JiraService|Enable Jira issue creation from vulnerabilities"
msgstr ""
-msgid "JiraService|Enable Jira issues creation from vulnerabilities"
+msgid "JiraService|Enable Jira issues"
msgstr ""
msgid "JiraService|Enable Jira transitions"
@@ -20492,16 +20947,19 @@ msgstr ""
msgid "JiraService|View Jira issues in GitLab"
msgstr ""
-msgid "JiraService|Warning: All GitLab users that have access to this GitLab project are able to view all issues from the Jira project specified below."
+msgid "JiraService|Warning: All GitLab users with access to this GitLab project can view all issues from the Jira project you select."
msgstr ""
msgid "JiraService|Web URL"
msgstr ""
-msgid "JiraService|Work on Jira issues without leaving GitLab. Adds a Jira menu to access your list of Jira issues and view any issue as read-only."
+msgid "JiraService|When a Jira issue is mentioned in a commit or merge request, a remote link and comment (if enabled) will be created."
+msgstr ""
+
+msgid "JiraService|Work on Jira issues without leaving GitLab. Add a Jira menu to access a read-only list of your Jira issues."
msgstr ""
-msgid "JiraService|You need to configure Jira before enabling this integration. For more details, read the %{jira_doc_link_start}Jira integration documentation%{link_end}."
+msgid "JiraService|You must configure Jira before enabling this integration. %{jira_doc_link_start}Learn more.%{link_end}"
msgstr ""
msgid "Job"
@@ -20513,9 +20971,6 @@ msgstr ""
msgid "Job Failed #%{build_id}"
msgstr ""
-msgid "Job ID"
-msgstr ""
-
msgid "Job artifact"
msgstr ""
@@ -20582,9 +21037,27 @@ msgstr ""
msgid "Jobs|You're about to retry a job that failed because it attempted to deploy code that is older than the latest deployment. Retrying this job could result in overwriting the environment with the older source code."
msgstr ""
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source} into %{target}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{ref}"
+msgstr ""
+
+msgid "Job|Are you sure you want to erase this job log and artifacts?"
+msgstr ""
+
msgid "Job|Browse"
msgstr "Durchsuchen"
+msgid "Job|Cancel"
+msgstr ""
+
msgid "Job|Complete Raw"
msgstr "Komplette Rohdaten"
@@ -20594,6 +21067,9 @@ msgstr "Herunterladen"
msgid "Job|Erase job log and artifacts"
msgstr ""
+msgid "Job|Finished at"
+msgstr ""
+
msgid "Job|Job artifacts"
msgstr "Jobartefakte"
@@ -20606,7 +21082,7 @@ msgstr ""
msgid "Job|Keep"
msgstr "Behalten"
-msgid "Job|Pipeline"
+msgid "Job|Retry"
msgstr ""
msgid "Job|Scroll to bottom"
@@ -20618,6 +21094,9 @@ msgstr "Scrolle nach oben"
msgid "Job|Show complete raw"
msgstr "Zeige komplette Rohdaten"
+msgid "Job|Status"
+msgstr ""
+
msgid "Job|The artifacts were removed"
msgstr "Die Artefakte wurden entfernt"
@@ -20645,21 +21124,12 @@ msgstr ""
msgid "Job|delayed"
msgstr ""
-msgid "Job|for"
-msgstr ""
-
-msgid "Job|into"
-msgstr "in"
-
msgid "Job|manual"
msgstr ""
msgid "Job|triggered"
msgstr ""
-msgid "Job|with"
-msgstr ""
-
msgid "Join Zoom meeting"
msgstr ""
@@ -20762,9 +21232,6 @@ msgstr ""
msgid "Ki"
msgstr ""
-msgid "Kontra"
-msgstr ""
-
msgid "Kroki"
msgstr ""
@@ -21088,6 +21555,9 @@ msgstr ""
msgid "Learn more about Auto DevOps"
msgstr ""
+msgid "Learn more about GitLab"
+msgstr ""
+
msgid "Learn more about Needs relationships"
msgstr ""
@@ -21415,9 +21885,18 @@ msgstr ""
msgid "Licenses|Displays licenses detected in the project, based on the %{linkStart}latest successful%{linkEnd} scan"
msgstr ""
+msgid "Licenses|Drag your license file here or %{linkStart}click to upload%{linkEnd}."
+msgstr ""
+
+msgid "Licenses|Drop your license file to start the upload."
+msgstr ""
+
msgid "Licenses|Error fetching the license list. Please check your network connection and try again."
msgstr ""
+msgid "Licenses|Error: You are trying to upload something other than a file"
+msgstr ""
+
msgid "Licenses|License Compliance"
msgstr ""
@@ -21436,6 +21915,9 @@ msgstr ""
msgid "Licenses|Specified policies in this project"
msgstr ""
+msgid "Licenses|The file could not be uploaded."
+msgstr ""
+
msgid "Licenses|The license list details information about the licenses used within your project."
msgstr ""
@@ -21469,11 +21951,6 @@ msgstr ""
msgid "Limit the size of Sidekiq jobs stored in Redis."
msgstr ""
-msgid "Limited to showing %d event at most"
-msgid_plural "Limited to showing %d events at most"
-msgstr[0] "Anzeige beschränkt auf maximal %d Ereignis"
-msgstr[1] "Anzeige beschränkt auf maximal %d Ereignisse"
-
msgid "Limiting mode"
msgstr ""
@@ -21483,6 +21960,9 @@ msgstr ""
msgid "Link"
msgstr ""
+msgid "Link (optional)"
+msgstr ""
+
msgid "Link Prometheus monitoring to GitLab."
msgstr "Prometheus-Monitoring mit GitLab verknüpfen."
@@ -21519,6 +21999,9 @@ msgstr ""
msgid "Linked emails (%{email_count})"
msgstr ""
+msgid "Linked epics"
+msgstr ""
+
msgid "Linked issues"
msgstr ""
@@ -21546,6 +22029,15 @@ msgstr "Verfügbare Repositories auflisten"
msgid "List of all merge commits"
msgstr ""
+msgid "List of environments for this project"
+msgstr ""
+
+msgid "List of suitable GCP locations"
+msgstr ""
+
+msgid "List of users allowed to exceed the rate limit."
+msgstr ""
+
msgid "List options"
msgstr ""
@@ -21765,6 +22257,9 @@ msgstr ""
msgid "Maintenance mode"
msgstr ""
+msgid "Make adjustments to how your GitLab instance is set up."
+msgstr ""
+
msgid "Make and review changes in the browser with the Web IDE"
msgstr ""
@@ -21909,6 +22404,12 @@ msgstr ""
msgid "MarkdownEditor|Add italic text (%{modifier_key}I)"
msgstr ""
+msgid "MarkdownEditor|Add strikethrough text (%{modifierKey}⇧X)"
+msgstr ""
+
+msgid "MarkdownEditor|Add strikethrough text (%{modifier_key}⇧X)"
+msgstr ""
+
msgid "Marked For Deletion At - %{deletion_time}"
msgstr ""
@@ -22170,6 +22671,9 @@ msgstr ""
msgid "Maximum push size (MB)"
msgstr ""
+msgid "Maximum requests per 10 minutes per user"
+msgstr ""
+
msgid "Maximum requests per minute"
msgstr ""
@@ -22260,6 +22764,19 @@ msgstr ""
msgid "Members of a group may only view projects they have permission to access"
msgstr ""
+msgid "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seat in use and will be billed for the overage."
+msgid_plural "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seats in use and will be billed for the overage."
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "MembersOverage|You are about to incur additional charges"
+msgstr ""
+
+msgid "MembersOverage|Your subscription includes %d seat."
+msgid_plural "MembersOverage|Your subscription includes %d seats."
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Membership"
msgstr ""
@@ -22464,9 +22981,6 @@ msgstr ""
msgid "Merge request not merged"
msgstr ""
-msgid "Merge request pipelines 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 merge request pipelines."
-msgstr ""
-
msgid "Merge request reports"
msgstr ""
@@ -22563,18 +23077,18 @@ msgstr "Beim Hinzufügen des Kommentarentwurfs ist ein Fehler aufgetreten."
msgid "MergeRequests|Create issue to resolve thread"
msgstr ""
-msgid "MergeRequests|Failed to squash. Should be done manually."
-msgstr ""
-
msgid "MergeRequests|Saving the comment failed"
msgstr "Speichern des Kommentars fehlgeschlagen"
-msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
+msgid "MergeRequests|Squashing failed: Squash the commits locally, resolve any conflicts, then push the branch."
msgstr ""
-msgid "MergeRequests|Thread stays resolved"
+msgid "MergeRequests|Squashing not allowed: This project doesn't allow you to squash commits when merging."
msgstr ""
+msgid "MergeRequests|Thread stays resolved"
+msgstr "Diskussion bleibt beendet"
+
msgid "MergeRequests|Thread stays unresolved"
msgstr ""
@@ -23410,6 +23924,18 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "MrList|Assigned to %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from assignee %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from reviewer %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Review requested from %{name}, go to their profile."
+msgstr ""
+
msgid "Multi-project"
msgstr ""
@@ -23443,7 +23969,7 @@ msgstr ""
msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "My Awesome Group"
+msgid "My awesome group"
msgstr ""
msgid "My company or team"
@@ -24065,9 +24591,6 @@ msgstr ""
msgid "No available branches"
msgstr ""
-msgid "No available groups to fork the project."
-msgstr ""
-
msgid "No branches found"
msgstr "Keine Branches gefunden"
@@ -24278,6 +24801,9 @@ msgstr "Keine öffentlichen Gruppen"
msgid "No ref selected"
msgstr ""
+msgid "No regions configured"
+msgstr ""
+
msgid "No related merge requests found."
msgstr ""
@@ -25082,6 +25608,9 @@ msgstr ""
msgid "Only reCAPTCHA v2 is supported:"
msgstr ""
+msgid "Only required if not using role instance credentials."
+msgstr ""
+
msgid "Only use lowercase letters, numbers, and underscores."
msgstr ""
@@ -25106,9 +25635,6 @@ msgstr ""
msgid "Open a CLI and connect to the cluster you want to install the agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
-msgid "Open epics"
-msgstr ""
-
msgid "Open errors"
msgstr ""
@@ -25148,8 +25674,8 @@ msgstr ""
msgid "Opened issues"
msgstr "Geöffnete Tickets"
-msgid "OpenedNDaysAgo|Opened"
-msgstr "Erstellt"
+msgid "OpenedNDaysAgo|Created"
+msgstr ""
msgid "Opens in a new window"
msgstr "Wird in einem neuen Fenster geöffnet"
@@ -25193,9 +25719,6 @@ msgstr "Optional"
msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
-msgid "Optional."
-msgstr ""
-
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
msgstr "Optional kannst du %{link_to_customize}, wie FogBugz E-Mail-Adressen und Benutzernamen in GitLab importiert werden."
@@ -25984,6 +26507,9 @@ msgstr ""
msgid "PerformanceBar|Memory"
msgstr ""
+msgid "PerformanceBar|Memory report"
+msgstr ""
+
msgid "PerformanceBar|Redis calls"
msgstr ""
@@ -26017,18 +26543,12 @@ msgstr ""
msgid "PerformanceBar|wall"
msgstr ""
-msgid "Performs a rebase but skips triggering a new pipeline"
-msgstr ""
-
msgid "Period in seconds"
msgstr ""
msgid "Permalink"
msgstr ""
-msgid "Permanently delete project"
-msgstr ""
-
msgid "Permanently remove group"
msgstr ""
@@ -26299,6 +26819,51 @@ msgstr ""
msgid "PipelineStatusTooltip|Pipeline: %{ci_status}"
msgstr ""
+msgid "PipelineWizardDefaultCommitMessage|Add %{filename}"
+msgstr ""
+
+msgid "PipelineWizardDefaultCommitMessage|Update %{filename}"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|At least one entry is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This field is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This value is not valid"
+msgstr ""
+
+msgid "PipelineWizardListWidget|add another step"
+msgstr ""
+
+msgid "PipelineWizardListWidget|remove step"
+msgstr ""
+
+msgid "PipelineWizard|Commit"
+msgstr ""
+
+msgid "PipelineWizard|Commit Message"
+msgstr ""
+
+msgid "PipelineWizard|Commit changes to your file"
+msgstr ""
+
+msgid "PipelineWizard|Commit file to Branch"
+msgstr ""
+
+msgid "PipelineWizard|Commit your new file"
+msgstr ""
+
+msgid "PipelineWizard|The file has been committed."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem committing the changes."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem while checking whether your file already exists in the specified branch."
+msgstr ""
+
msgid "Pipelines"
msgstr "Pipelines"
@@ -26413,7 +26978,7 @@ msgstr ""
msgid "Pipelines|Project cache successfully reset."
msgstr "Der Projekt-Cache wurde erfolgreich zurückgesetzt."
-msgid "Pipelines|Revoke"
+msgid "Pipelines|Revoke trigger"
msgstr ""
msgid "Pipelines|Something went wrong while cleaning runners cache."
@@ -26458,6 +27023,12 @@ msgstr ""
msgid "Pipelines|This is a child pipeline within the parent pipeline"
msgstr ""
+msgid "Pipelines|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipelines|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipelines|This pipeline will run code originating from a forked project merge request. This means that the code can potentially have security considerations like exposing CI variables."
msgstr ""
@@ -26500,9 +27071,6 @@ msgstr ""
msgid "Pipelines|Your changes have been successfully committed. Now redirecting to the new merge request page."
msgstr ""
-msgid "Pipelines|detached"
-msgstr ""
-
msgid "Pipelines|error"
msgstr ""
@@ -26512,10 +27080,13 @@ msgstr ""
msgid "Pipelines|latest"
msgstr ""
-msgid "Pipelines|stuck"
+msgid "Pipelines|merge request"
+msgstr ""
+
+msgid "Pipelines|merge train"
msgstr ""
-msgid "Pipelines|train"
+msgid "Pipelines|stuck"
msgstr ""
msgid "Pipelines|yaml invalid"
@@ -26647,6 +27218,12 @@ msgstr ""
msgid "Pipeline|This change will not change the overall test coverage if merged."
msgstr ""
+msgid "Pipeline|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipeline|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipeline|Trigger author"
msgstr ""
@@ -26671,6 +27248,12 @@ msgstr ""
msgid "Pipeline|for"
msgstr ""
+msgid "Pipeline|merge request"
+msgstr ""
+
+msgid "Pipeline|merge train"
+msgstr ""
+
msgid "Pipeline|on"
msgstr ""
@@ -26809,9 +27392,6 @@ msgstr ""
msgid "Please enter a valid time interval"
msgstr ""
-msgid "Please enter or upload a valid license."
-msgstr ""
-
msgid "Please enter your current password."
msgstr ""
@@ -26920,9 +27500,6 @@ msgstr ""
msgid "Please type %{phrase_code} to proceed or close this modal to cancel."
msgstr ""
-msgid "Please type the following to confirm:"
-msgstr ""
-
msgid "Please use this form to report to the admin users who create spam issues, comments or behave inappropriately."
msgstr ""
@@ -26950,12 +27527,27 @@ msgstr ""
msgid "Policies"
msgstr ""
+msgid "Policy '%{escalation_policy_name}' does not exist."
+msgstr ""
+
msgid "Policy management project does have any policies in %{policy_path}"
msgstr ""
msgid "Policy project doesn't exist"
msgstr ""
+msgid "PolicyRuleMultiSelect|%{firstLabel} +%{numberOfAdditionalLabels} more"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|All %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select all"
+msgstr ""
+
msgid "Polling interval multiplier"
msgstr ""
@@ -27005,7 +27597,7 @@ msgid "Preferences|Customize the appearance of the application header and naviga
msgstr ""
msgid "Preferences|Display time in 24-hour format"
-msgstr ""
+msgstr "Uhrzeit im 24h-Format anzeigen"
msgid "Preferences|Enable Gitpod integration"
msgstr ""
@@ -27041,7 +27633,7 @@ msgid "Preferences|Navigation theme"
msgstr "Navigationsthema"
msgid "Preferences|Project overview content"
-msgstr ""
+msgstr "Inhalt der Projektübersicht"
msgid "Preferences|Render whitespace characters in the Web IDE"
msgstr ""
@@ -27059,7 +27651,7 @@ msgid "Preferences|Surround text selection when typing quotes or brackets"
msgstr ""
msgid "Preferences|Syntax highlighting theme"
-msgstr ""
+msgstr "Syntax-Highlight Theme"
msgid "Preferences|Tab width"
msgstr ""
@@ -27184,6 +27776,9 @@ msgstr ""
msgid "Private projects can be created in your personal namespace with:"
msgstr "Private Projekte können in deinem persönlichen Namensraum erstellt werden:"
+msgid "Problem with %{name} command: %{message}."
+msgstr ""
+
msgid "Proceed"
msgstr ""
@@ -27554,7 +28149,7 @@ msgid "Profiles|Time settings"
msgstr ""
msgid "Profiles|Two-Factor Authentication"
-msgstr ""
+msgstr "Zwei-Faktor-Authentifizierung"
msgid "Profiles|Type your %{confirmationValue} to confirm:"
msgstr "Gib deinen %{confirmationValue} zur Bestätigung ein:"
@@ -27647,7 +28242,7 @@ msgid "Profiles|your account"
msgstr "Dein Konto"
msgid "Profile|%{job_title} at %{organization}"
-msgstr ""
+msgstr "%{job_title} bei %{organization}"
msgid "Profiling - Performance bar"
msgstr "Pro­fi­ling - Performance-Leiste"
@@ -27658,6 +28253,9 @@ msgstr "Programmiersprachen, die in diesem Repository verwendet werden"
msgid "Progress"
msgstr "Fortschritt"
+msgid "Progress tracking"
+msgstr ""
+
msgid "Project"
msgstr "Projekt"
@@ -27889,6 +28487,9 @@ msgstr ""
msgid "ProjectQualitySummary|Failure"
msgstr ""
+msgid "ProjectQualitySummary|Get insight into the overall percentage of tests in your project that succeed, fail and are skipped."
+msgstr ""
+
msgid "ProjectQualitySummary|Latest pipeline results"
msgstr ""
@@ -27907,6 +28508,12 @@ msgstr ""
msgid "ProjectQualitySummary|See project Code Coverage Statistics"
msgstr ""
+msgid "ProjectQualitySummary|Set up test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|Set up test runs (opens in a new tab)"
+msgstr ""
+
msgid "ProjectQualitySummary|Skipped"
msgstr ""
@@ -28183,13 +28790,19 @@ msgstr ""
msgid "ProjectSettings|LFS objects from this repository are available to forks. %{linkStart}How do I remove them?%{linkEnd}"
msgstr ""
+msgid "ProjectSettings|Learn about commit history."
+msgstr ""
+
+msgid "ProjectSettings|Leave empty to use default template."
+msgstr ""
+
msgid "ProjectSettings|Manage who can see the project in the public access directory."
msgstr ""
msgid "ProjectSettings|Manages large files such as audio, video, and graphics files."
msgstr ""
-msgid "ProjectSettings|Maximum 500 characters."
+msgid "ProjectSettings|Maximum %{maxLength} characters."
msgstr ""
msgid "ProjectSettings|Merge checks"
@@ -28330,6 +28943,9 @@ msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
msgstr ""
+msgid "ProjectSettings|The default template will be applied on save."
+msgstr ""
+
msgid "ProjectSettings|These checks must pass before merge requests can be merged."
msgstr ""
@@ -28384,6 +29000,9 @@ msgstr ""
msgid "ProjectSettings|What are badges?"
msgstr ""
+msgid "ProjectSettings|What are merge trains?"
+msgstr ""
+
msgid "ProjectSettings|When merge request pipelines are enabled in the CI/CD configuration file, pipelines validate the combined results of the source and target branches. %{link_start}How to configure merge request pipelines?%{link_end}"
msgstr ""
@@ -28501,6 +29120,9 @@ msgstr ""
msgid "Projects are organized into groups"
msgstr ""
+msgid "Projects are where you store your code, access issues, wiki and other features of GitLab."
+msgstr ""
+
msgid "Projects contributed to"
msgstr ""
@@ -28516,12 +29138,6 @@ msgstr ""
msgid "Projects to index"
msgstr ""
-msgid "Projects will be permanently deleted after a %{waiting_period}-day waiting period."
-msgstr ""
-
-msgid "Projects will be permanently deleted immediately."
-msgstr ""
-
msgid "Projects with critical vulnerabilities"
msgstr ""
@@ -28606,6 +29222,9 @@ msgstr ""
msgid "ProjectsNew|Import project"
msgstr ""
+msgid "ProjectsNew|Include a Getting Started README"
+msgstr ""
+
msgid "ProjectsNew|Initialize repository with a README"
msgstr ""
@@ -28621,6 +29240,9 @@ msgstr ""
msgid "ProjectsNew|Project description %{tag_start}(optional)%{tag_end}"
msgstr ""
+msgid "ProjectsNew|Recommended if you're new to GitLab"
+msgstr ""
+
msgid "ProjectsNew|Run CI/CD for external repository"
msgstr ""
@@ -29038,6 +29660,9 @@ msgstr ""
msgid "ProtectedBranch|Unprotect"
msgstr ""
+msgid "ProtectedBranch|Unprotect branch"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
@@ -29065,11 +29690,14 @@ msgstr "Schütze eine Umgebung"
msgid "ProtectedEnvironment|Protected Environment (%{protected_environments_count})"
msgstr "Geschützte Umgebung (%{protected_environments_count})"
+msgid "ProtectedEnvironment|Required approvals"
+msgstr ""
+
msgid "ProtectedEnvironment|Select an environment"
msgstr "Wähle eine Umgebung"
msgid "ProtectedEnvironment|Select users"
-msgstr ""
+msgstr "Nutzer:innen auswählen"
msgid "ProtectedEnvironment|There are currently no protected environments. Protect an environment with this form."
msgstr ""
@@ -29086,10 +29714,13 @@ msgstr "Deine Umgebung wurde geschützt."
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr "Der Schutz deiner Umgebung wurde aufgehoben"
+msgid "ProtectedTags|Unprotect tag"
+msgstr ""
+
msgid "ProtectedTags|default"
msgstr ""
-msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
+msgid "ProtectedTag|By default, protected tags restrict who can modify the tag."
msgstr ""
msgid "ProtectedTag|Learn more."
@@ -29152,6 +29783,9 @@ msgstr "Öffentliche Pipelines"
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Public projects are an easy way to allow everyone to have read-only access."
+msgstr ""
+
msgid "Publish to status page"
msgstr ""
@@ -29308,9 +29942,6 @@ msgstr ""
msgid "QualitySummary|Project quality"
msgstr ""
-msgid "Quarters"
-msgstr "Quartale"
-
msgid "Query"
msgstr ""
@@ -29395,6 +30026,9 @@ msgstr ""
msgid "Read more about project permissions %{help_link_open}here%{help_link_close}"
msgstr ""
+msgid "Read more about related epics"
+msgstr ""
+
msgid "Read more about related issues"
msgstr ""
@@ -29425,10 +30059,7 @@ msgstr ""
msgid "Rebase source branch on the target branch."
msgstr ""
-msgid "Rebase without CI"
-msgstr ""
-
-msgid "Rebases and triggers a pipeline"
+msgid "Rebase without pipeline"
msgstr ""
msgid "Recaptcha verified?"
@@ -29479,9 +30110,6 @@ msgstr ""
msgid "Reconfigure"
msgstr ""
-msgid "Recovering projects"
-msgstr ""
-
msgid "Recovery Codes"
msgstr ""
@@ -29541,6 +30169,12 @@ msgstr ""
msgid "Regex pattern"
msgstr "Regex-Muster"
+msgid "Region"
+msgstr ""
+
+msgid "Regions"
+msgstr ""
+
msgid "Register"
msgstr ""
@@ -29771,9 +30405,6 @@ msgstr ""
msgid "Remove all or specific reviewer(s)"
msgstr ""
-msgid "Remove approver"
-msgstr ""
-
msgid "Remove approvers"
msgstr "Genehmigungsberechtigte entfernen"
@@ -29789,6 +30420,9 @@ msgstr ""
msgid "Remove attention request"
msgstr ""
+msgid "Remove attention request(s)"
+msgstr ""
+
msgid "Remove avatar"
msgstr "Avatar entfernen"
@@ -29927,6 +30561,9 @@ msgstr ""
msgid "Removed an issue from an epic."
msgstr ""
+msgid "Removed attention from %{users_sentence}."
+msgstr ""
+
msgid "Removed attention request from @%{username}"
msgstr ""
@@ -29978,6 +30615,9 @@ msgstr ""
msgid "Removes an issue from an epic."
msgstr ""
+msgid "Removes attention from %{users_sentence}."
+msgstr ""
+
msgid "Removes parent epic %{epic_ref}."
msgstr "Entfernt übergeordnetes Epic %{epic_ref}."
@@ -30089,6 +30729,9 @@ msgstr ""
msgid "Report abuse to admin"
msgstr ""
+msgid "Report is generating and will be sent to your email address."
+msgstr ""
+
msgid "Reported %{timeAgo} by %{reportedBy}"
msgstr ""
@@ -30378,6 +31021,15 @@ msgstr ""
msgid "Request attention"
msgstr ""
+msgid "Request attention from %{users_sentence}."
+msgstr ""
+
+msgid "Request attention from assignee or reviewer"
+msgstr ""
+
+msgid "Request attention from assignee(s) or reviewer(s)"
+msgstr ""
+
msgid "Request attention to review"
msgstr ""
@@ -30402,6 +31054,9 @@ msgstr ""
msgid "Requested %{time_ago}"
msgstr ""
+msgid "Requested attention from %{users_sentence}."
+msgstr ""
+
msgid "Requested attention from @%{username}"
msgstr ""
@@ -30616,6 +31271,9 @@ msgstr ""
msgid "Restore project"
msgstr "Projekt wiederherstellen"
+msgid "Restoring projects"
+msgstr ""
+
msgid "Restoring the group will prevent the group, its subgroups and projects from being removed on this date."
msgstr ""
@@ -30646,6 +31304,9 @@ msgstr ""
msgid "Retry"
msgstr "Wiederholen"
+msgid "Retry failed jobs"
+msgstr ""
+
msgid "Retry job"
msgstr ""
@@ -30693,9 +31354,6 @@ msgstr ""
msgid "Review changes"
msgstr ""
-msgid "Review requested from %{name}"
-msgstr ""
-
msgid "Review requests for you"
msgstr ""
@@ -30860,6 +31518,9 @@ msgstr ""
msgid "Runners|Assigned Group"
msgstr ""
+msgid "Runners|Assigned Projects (%{projectCount})"
+msgstr ""
+
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30929,6 +31590,9 @@ msgstr ""
msgid "Runners|Instance"
msgstr ""
+msgid "Runners|Jobs"
+msgstr ""
+
msgid "Runners|Last contact"
msgstr ""
@@ -31022,9 +31686,6 @@ msgstr ""
msgid "Runners|Runner %{name} was deleted"
msgstr ""
-msgid "Runners|Runner ID"
-msgstr ""
-
msgid "Runners|Runner assigned to project."
msgstr ""
@@ -31172,6 +31833,9 @@ msgstr ""
msgid "Runners|stale"
msgstr ""
+msgid "Runner|This runner has not run any jobs."
+msgstr ""
+
msgid "Running"
msgstr "Laufend"
@@ -31286,6 +31950,24 @@ msgstr ""
msgid "Saving project."
msgstr ""
+msgid "ScanResultPolicy|%{ifLabelStart}if%{ifLabelEnd} %{scanners} scan in an open merge request targeting the %{branches} branch(es) finds %{vulnerabilitiesAllowed} or more %{severities} vulnerabilities that are %{vulnerabilityStates}"
+msgstr ""
+
+msgid "ScanResultPolicy|%{thenLabelStart}Then%{thenLabelEnd} Require approval from %{approvalsRequired} of the following approvers: %{approvers}"
+msgstr ""
+
+msgid "ScanResultPolicy|add an approver"
+msgstr ""
+
+msgid "ScanResultPolicy|scanners"
+msgstr ""
+
+msgid "ScanResultPolicy|severity levels"
+msgstr ""
+
+msgid "ScanResultPolicy|vulnerability states"
+msgstr ""
+
msgid "Scanner"
msgstr ""
@@ -31418,6 +32100,9 @@ msgstr ""
msgid "Search for a user"
msgstr ""
+msgid "Search for an emoji"
+msgstr ""
+
msgid "Search for projects, issues, etc."
msgstr "Suche nach Projekten, Tickets usw."
@@ -31605,18 +32290,12 @@ msgstr "Secret"
msgid "Secret Detection"
msgstr ""
-msgid "Secret access key"
-msgstr ""
-
msgid "Secret token"
msgstr ""
msgid "Secure token that identifies an external storage request."
msgstr ""
-msgid "SecureCodeWarrior"
-msgstr ""
-
msgid "Security"
msgstr "Sicherheit"
@@ -31641,9 +32320,6 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "Security training with guide and learning pathways."
-msgstr ""
-
msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
@@ -31746,7 +32422,7 @@ msgstr ""
msgid "SecurityConfiguration|Manage corpus"
msgstr ""
-msgid "SecurityConfiguration|Manage corpus files used as mutation sources in coverage fuzzing."
+msgid "SecurityConfiguration|Manage corpus files used as seed inputs with coverage-guided fuzzing."
msgstr ""
msgid "SecurityConfiguration|Manage profiles for use by DAST scans."
@@ -31812,15 +32488,15 @@ msgstr ""
msgid "SecurityOrchestration|.yaml preview"
msgstr ""
-msgid "SecurityOrchestration|Action"
-msgstr ""
-
msgid "SecurityOrchestration|Actions"
msgstr ""
msgid "SecurityOrchestration|Add rule"
msgstr ""
+msgid "SecurityOrchestration|After dismissing the alert, the information will never be shown again."
+msgstr ""
+
msgid "SecurityOrchestration|All policies"
msgstr ""
@@ -31836,7 +32512,7 @@ msgstr ""
msgid "SecurityOrchestration|Description"
msgstr ""
-msgid "SecurityOrchestration|Disabled"
+msgid "SecurityOrchestration|Don't show the alert anymore"
msgstr ""
msgid "SecurityOrchestration|Edit policy"
@@ -31845,13 +32521,13 @@ msgstr ""
msgid "SecurityOrchestration|Edit policy project"
msgstr ""
-msgid "SecurityOrchestration|Enabled"
+msgid "SecurityOrchestration|Empty policy name"
msgstr ""
-msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Enabled"
msgstr ""
-msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
msgstr ""
msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
@@ -31860,7 +32536,7 @@ msgstr ""
msgid "SecurityOrchestration|Invalid policy type"
msgstr ""
-msgid "SecurityOrchestration|Latest scan"
+msgid "SecurityOrchestration|Latest scan run against %{agent}"
msgstr ""
msgid "SecurityOrchestration|Network"
@@ -31869,15 +32545,27 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No actions defined - policy will not run."
+msgstr ""
+
+msgid "SecurityOrchestration|No description"
+msgstr ""
+
msgid "SecurityOrchestration|No rules defined - policy will not run."
msgstr ""
+msgid "SecurityOrchestration|Not enabled"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
msgid "SecurityOrchestration|Policies"
msgstr ""
+msgid "SecurityOrchestration|Policy Type"
+msgstr ""
+
msgid "SecurityOrchestration|Policy cannot be enabled for non-existing branches (%{branches})"
msgstr ""
@@ -31902,10 +32590,13 @@ msgstr ""
msgid "SecurityOrchestration|Require %{approvals} %{plural} from %{approvers} if any of the following occur:"
msgstr ""
-msgid "SecurityOrchestration|Rule"
+msgid "SecurityOrchestration|Rules"
msgstr ""
-msgid "SecurityOrchestration|Rules"
+msgid "SecurityOrchestration|Runs %{actions} and %{lastAction} scans"
+msgstr ""
+
+msgid "SecurityOrchestration|Runs a %{action} scan"
msgstr ""
msgid "SecurityOrchestration|Scan Execution"
@@ -31965,6 +32656,9 @@ msgstr ""
msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
+msgid "SecurityOrchestration|This view only shows scan results for the agent %{agent}. You can view scan results for all agents in the %{linkStart}Operational Vulnerabilities tab of the vulnerability report%{linkEnd}."
+msgstr ""
+
msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
@@ -32019,9 +32713,6 @@ msgstr ""
msgid "SecurityOrchestration|users with ids"
msgstr ""
-msgid "SecurityOrchestration|view results"
-msgstr ""
-
msgid "SecurityOrchestration|vulnerabilities"
msgstr ""
@@ -32691,22 +33382,19 @@ 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|In order to start using functions as a service, you must first install Knative on your Kubernetes cluster. %{linkStart}More information%{linkEnd}"
-msgstr ""
-
msgid "Serverless|Learn more about Serverless"
msgstr ""
msgid "Serverless|No functions available"
msgstr ""
-msgid "Serverless|Sign up for First Look"
+msgid "Serverless|Serverless was %{linkStart}deprecated%{linkEnd} in GitLab 14.3."
+msgstr ""
+
+msgid "Serverless|Serverless was %{postLinkStart}deprecated%{postLinkEnd}. But if you opt to use it, you must install Knative in your Kubernetes cluster first. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "Serverless|The deploy job has not finished."
@@ -32718,9 +33406,6 @@ 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 ""
@@ -32736,9 +33421,6 @@ msgstr ""
msgid "Service Account Key"
msgstr ""
-msgid "Service Accounts"
-msgstr ""
-
msgid "Service Accounts keys authorize GitLab to deploy your Google Cloud project"
msgstr ""
@@ -32748,10 +33430,10 @@ msgstr "Service-Desk"
msgid "Service Desk allows people to create issues in your GitLab instance without their own user account. It provides a unique email address for end users to create issues in a project. Replies can be sent either through the GitLab interface or by email. End users only see threads through email."
msgstr ""
-msgid "Service Usage Data"
+msgid "Service account generated successfully"
msgstr ""
-msgid "Service account generated successfully"
+msgid "Service accounts"
msgstr ""
msgid "Service ping is disabled in your configuration file, and cannot be enabled through this form."
@@ -32895,6 +33577,9 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
+msgid "Set the per-user rate limit for getting a user by ID via the API."
+msgstr ""
+
msgid "Set the per-user rate limit for notes created by web or API requests."
msgstr ""
@@ -33074,6 +33759,9 @@ msgstr ""
msgid "Shared runners details"
msgstr ""
+msgid "Shared runners enabled cannot be enabled until a valid credit card is on file"
+msgstr ""
+
msgid "Shared runners help link"
msgstr ""
@@ -33131,6 +33819,9 @@ msgstr ""
msgid "Show all issues."
msgstr ""
+msgid "Show all milestones"
+msgstr ""
+
msgid "Show all test cases."
msgstr ""
@@ -33167,6 +33858,9 @@ msgstr ""
msgid "Show file contents"
msgstr ""
+msgid "Show group milestones"
+msgstr ""
+
msgid "Show labels"
msgstr ""
@@ -33182,6 +33876,12 @@ msgstr ""
msgid "Show open epics"
msgstr ""
+msgid "Show project milestones"
+msgstr ""
+
+msgid "Show sub-group milestones"
+msgstr ""
+
msgid "Show the Closed list"
msgstr ""
@@ -33191,11 +33891,6 @@ msgstr ""
msgid "Show whitespace changes"
msgstr "Leerzeichenänderungen anzeigen"
-msgid "Showing %d event"
-msgid_plural "Showing %d events"
-msgstr[0] "Zeige %d Ereignis"
-msgstr[1] "Zeige %d Ereignisse"
-
msgid "Showing %{conflict} between %{sourceBranch} and %{targetBranch}"
msgstr ""
@@ -33255,12 +33950,6 @@ msgstr ""
msgid "Sidebar|None"
msgstr "Keine"
-msgid "Sidebar|Only numeral characters allowed"
-msgstr "Nur numerische Zeichen erlaubt"
-
-msgid "Sidebar|Weight"
-msgstr "Gewichtung"
-
msgid "Sidekiq job compression threshold (bytes)"
msgstr ""
@@ -33423,6 +34112,9 @@ msgstr "Die Slack-Integration ermöglicht es dir, mit GitLab über Slash-Befehle
msgid "Slack logo"
msgstr ""
+msgid "SlackIntegration|Are you sure you want to remove this project from the Slack application?"
+msgstr ""
+
msgid "SlackIntegration|GitLab for Slack"
msgstr ""
@@ -33432,6 +34124,9 @@ msgstr ""
msgid "SlackIntegration|Project alias"
msgstr ""
+msgid "SlackIntegration|Remove project"
+msgstr ""
+
msgid "SlackIntegration|Select a GitLab project to link with your Slack workspace."
msgstr ""
@@ -33576,9 +34271,6 @@ msgstr "Etwas ist beim Ändern des Sperrzustandes von %{issuableDisplayName} sch
msgid "Something went wrong trying to load issue contacts."
msgstr ""
-msgid "Something went wrong when creating a work item. Please try again"
-msgstr ""
-
msgid "Something went wrong when reordering designs. Please try again"
msgstr ""
@@ -33672,9 +34364,6 @@ msgstr ""
msgid "Something went wrong while inserting your image. Please try again."
msgstr ""
-msgid "Something went wrong while merging this merge request. Please try again."
-msgstr ""
-
msgid "Something went wrong while obtaining the Let's Encrypt certificate."
msgstr ""
@@ -33996,10 +34685,10 @@ 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."
+msgid "SourcegraphAdmin|Learn more."
msgstr ""
-msgid "SourcegraphAdmin|More information"
+msgid "SourcegraphAdmin|Only public projects have code intelligence enabled and communicate with Sourcegraph."
msgstr ""
msgid "SourcegraphAdmin|Save changes"
@@ -34008,7 +34697,7 @@ msgstr "Änderungen speichern"
msgid "SourcegraphAdmin|Sourcegraph URL"
msgstr "Sourcegraph-URL"
-msgid "SourcegraphAdmin|e.g. https://sourcegraph.example.com"
+msgid "SourcegraphAdmin|https://sourcegraph.example.com"
msgstr ""
msgid "SourcegraphPreferences|This feature is experimental and currently limited to certain projects."
@@ -34018,7 +34707,7 @@ msgid "SourcegraphPreferences|This feature is experimental and limited to public
msgstr "Diese Funktion ist experimentell und beschränkt auf öffentliche Projekte."
msgid "SourcegraphPreferences|This feature is experimental."
-msgstr ""
+msgstr "Diese Feature ist experimentell."
msgid "SourcegraphPreferences|Uses %{linkStart}Sourcegraph.com%{linkEnd}."
msgstr ""
@@ -34143,6 +34832,9 @@ msgstr ""
msgid "Start date"
msgstr "Startdatum"
+msgid "Start free trial"
+msgstr ""
+
msgid "Start merge train"
msgstr ""
@@ -34173,6 +34865,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started escalation for this incident."
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -34185,6 +34880,9 @@ msgstr ""
msgid "Starts at (UTC)"
msgstr "Beginnt am (UTC)"
+msgid "Starts escalations for this incident"
+msgstr ""
+
msgid "Starts on"
msgstr ""
@@ -34446,6 +35144,9 @@ msgstr ""
msgid "Strikethrough"
msgstr ""
+msgid "Strikethrough text"
+msgstr ""
+
msgid "Subgroup information"
msgstr ""
@@ -34680,6 +35381,21 @@ msgstr ""
msgid "Subscriptions"
msgstr ""
+msgid "Subscriptions|Chat with sales"
+msgstr ""
+
+msgid "Subscriptions|Close"
+msgstr ""
+
+msgid "Subscriptions|Not ready to buy yet?"
+msgstr ""
+
+msgid "Subscriptions|Start a free trial"
+msgstr ""
+
+msgid "Subscriptions|We understand. Maybe you have some questions for our sales team, or maybe you'd like to try some of the paid features first. What would you like to do?"
+msgstr ""
+
msgid "Subscription|Your subscription for %{strong}%{namespace_name}%{strong_close} has expired and you are now on %{pricing_link_start}the GitLab Free tier%{pricing_link_end}. Don't worry, your data is safe. Get in touch with our support team (%{support_email}). They'll gladly help with your subscription renewal."
msgstr ""
@@ -34890,6 +35606,9 @@ msgstr ""
msgid "SuperSonics|Maximum users"
msgstr ""
+msgid "SuperSonics|Offline cloud"
+msgstr ""
+
msgid "SuperSonics|Paste your activation code"
msgstr ""
@@ -34956,6 +35675,12 @@ msgstr ""
msgid "SuperSonics|You do not have an active subscription"
msgstr ""
+msgid "SuperSonics|You have a future dated license"
+msgstr ""
+
+msgid "SuperSonics|You have added a license that activates on %{date}. Please see the subscription history table below for more details."
+msgstr ""
+
msgid "SuperSonics|You have successfully added a license that activates on %{date}. Please see the subscription history table below for more details."
msgstr ""
@@ -35115,6 +35840,9 @@ msgstr ""
msgid "Tag name is required"
msgstr ""
+msgid "Tag push"
+msgstr ""
+
msgid "Tag push events"
msgstr ""
@@ -35217,6 +35945,9 @@ msgstr "Schreibe deine Versionshinweise oder ziehen Dateien hier hinein…"
msgid "TagsPage|protected"
msgstr "geschützt"
+msgid "Take a look at the documentation to discover all of GitLab’s capabilities."
+msgstr ""
+
msgid "Target Branch"
msgstr "Zielbranch"
@@ -35619,6 +36350,9 @@ msgstr ""
msgid "Tests"
msgstr ""
+msgid "Text (optional)"
+msgstr ""
+
msgid "Text added to the body of all email messages. %{character_limit} character limit"
msgstr ""
@@ -35669,6 +36403,9 @@ msgstr ""
msgid "The CSV export will be created in the background. Once finished, it will be sent to %{email} in an attachment."
msgstr ""
+msgid "The CSV export you requested of all user memberships is attached to this email."
+msgstr ""
+
msgid "The GitLab subscription service (customers.gitlab.com) is currently experiencing an outage. You can monitor the status and get updates at %{linkStart}status.gitlab.com%{linkEnd}."
msgstr ""
@@ -35744,6 +36481,9 @@ 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 epic"
+msgstr ""
+
msgid "The current issue"
msgstr "Das aktuelle Ticket"
@@ -35905,6 +36645,9 @@ msgstr ""
msgid "The latest pipeline for this merge request has failed."
msgstr ""
+msgid "The license key is invalid."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -35920,6 +36663,9 @@ msgstr ""
msgid "The license was successfully uploaded and will be active from %{starts_at}. You can see the details below."
msgstr ""
+msgid "The license you uploaded is invalid. If the issue persists, contact support at %{link}."
+msgstr ""
+
msgid "The list creation wizard is already open"
msgstr ""
@@ -36541,10 +37287,13 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} and everything this project contains. %{strongOpen}There is no going back%{strongClose}"
+msgstr ""
+
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains."
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}on %{date}%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains. %{strongOpen}There is no going back.%{strongClose}"
msgstr ""
msgid "This action will %{strongOpen}permanently remove%{strongClose} %{codeOpen}%{group}%{codeClose} %{strongOpen}immediately%{strongClose}."
@@ -36673,9 +37422,6 @@ msgstr ""
msgid "This file was modified for readability, and can't accept suggestions. Edit it directly."
msgstr ""
-msgid "This forked project has the following:"
-msgstr ""
-
msgid "This form is disabled in preview"
msgstr ""
@@ -36688,7 +37434,7 @@ msgstr ""
msgid "This group can't be removed because it is linked to a subscription. To remove this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
-msgid "This group can't be transfered because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
+msgid "This group can't be transferred because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
msgid "This group cannot be invited to a project inside a group with enforced SSO"
@@ -36715,6 +37461,9 @@ 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 incident is already escalated with '%{escalation_policy_name}'."
+msgstr ""
+
msgid "This invitation was sent to %{mail_to_invite_email}, but you are signed in as %{link_to_current_user} with email %{mail_to_current_user}."
msgstr ""
@@ -36733,9 +37482,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 merge train pipeline"
-msgstr ""
-
msgid "This is a private email address %{helpIcon} generated just for you. Anyone who has it can create issues or merge requests as if they were you. If that happens, %{resetLinkStart}reset this token%{resetLinkEnd}."
msgstr ""
@@ -36757,6 +37503,12 @@ msgstr ""
msgid "This is your current session"
msgstr ""
+msgid "This issue cannot be assigned to a confidential epic because it is public."
+msgstr ""
+
+msgid "This issue cannot be made public because it belongs to a confidential epic."
+msgstr ""
+
msgid "This issue is confidential and should only be visible to team members with at least Reporter access."
msgstr ""
@@ -36874,6 +37626,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 branch is protected from force push."
+msgstr ""
+
msgid "This merge request cannot be rebased while there are conflicts."
msgstr ""
@@ -36925,9 +37680,15 @@ msgstr ""
msgid "This pipeline was triggered by a schedule."
msgstr ""
+msgid "This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project"
msgstr "Dieses Projekt"
+msgid "This project can be restored until %{date}."
+msgstr ""
+
msgid "This project cannot be %{visibilityLevel} because the visibility of %{openShowLink}%{name}%{closeShowLink} is %{visibility}. To make this project %{visibilityLevel}, you must first %{openEditLink}change the visibility%{closeEditLink} of the parent group."
msgstr ""
@@ -36946,6 +37707,9 @@ msgstr ""
msgid "This project is %{strongStart}NOT%{strongEnd} a fork, and has the following:"
msgstr ""
+msgid "This project is %{strongStart}NOT%{strongEnd} a fork. This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr "Dieses Projekt ist archiviert und kann nicht kommentiert werden."
@@ -37637,6 +38401,9 @@ msgstr ""
msgid "Today"
msgstr "Heute"
+msgid "Todos count"
+msgstr ""
+
msgid "Todos|Are you looking for things to do? Take a look at %{strongStart}%{openIssuesLinkStart}open issues%{openIssuesLinkEnd}%{strongEnd}, contribute to %{strongStart}%{mergeRequestLinkStart}a merge request%{mergeRequestLinkEnd}%{mergeRequestLinkEnd}%{strongEnd}, or mention someone in a comment to automatically assign them a new to-do item."
msgstr ""
@@ -37910,10 +38677,8 @@ msgstr "Baumstrukturansicht"
msgid "Trending"
msgstr "Beliebt"
-msgid "Trials|%{planName} Trial %{enDash} %{num} day left"
-msgid_plural "Trials|%{planName} Trial %{enDash} %{num} days left"
-msgstr[0] ""
-msgstr[1] ""
+msgid "Trials|%{planName} Trial"
+msgstr ""
msgid "Trials|Compare all plans"
msgstr ""
@@ -37921,6 +38686,9 @@ msgstr ""
msgid "Trials|Create a new group to start your GitLab Ultimate trial."
msgstr ""
+msgid "Trials|Day %{daysUsed}/%{duration}"
+msgstr ""
+
msgid "Trials|Go back to GitLab"
msgstr ""
@@ -38170,7 +38938,7 @@ msgstr ""
msgid "URL is triggered when repository is updated"
msgstr ""
-msgid "URL must be percent-encoded if neccessary."
+msgid "URL must be percent-encoded if necessary."
msgstr ""
msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
@@ -38389,6 +39157,9 @@ msgstr "Entsperren"
msgid "Unlock account"
msgstr ""
+msgid "Unlock more features with GitLab Ultimate"
+msgstr ""
+
msgid "Unlock the discussion"
msgstr ""
@@ -38452,6 +39223,9 @@ msgstr ""
msgid "Unsubscribes from this %{quick_action_target}."
msgstr ""
+msgid "Unsupported sort value."
+msgstr ""
+
msgid "Unsupported todo type passed. Supported todo types are: %{todo_types}"
msgstr ""
@@ -38680,6 +39454,9 @@ msgstr ""
msgid "UsageQuota|File attachments and smaller design graphics."
msgstr ""
+msgid "UsageQuota|From %{storage_enforcement_date} storage limits will apply to this namespace. View and manage your usage in %{strong_start}Group Settings &gt; Usage quotas%{strong_end}."
+msgstr ""
+
msgid "UsageQuota|Git repository."
msgstr ""
@@ -38740,6 +39517,9 @@ msgstr ""
msgid "UsageQuota|Storage type"
msgstr ""
+msgid "UsageQuota|Storage used"
+msgstr ""
+
msgid "UsageQuota|This is the total amount of storage used across your projects within this namespace."
msgstr ""
@@ -38935,6 +39715,12 @@ msgstr ""
msgid "Use hashed storage paths for newly created and renamed repositories. Always enabled since 13.0."
msgstr ""
+msgid "Use issue count"
+msgstr ""
+
+msgid "Use issue weight"
+msgstr ""
+
msgid "Use one line per URI"
msgstr "Verwende eine Zeile pro URI"
@@ -39035,7 +39821,7 @@ msgid "User identity was successfully removed."
msgstr ""
msgid "User identity was successfully updated."
-msgstr ""
+msgstr "Nutzeridentität wurde erfolgreich aktualisiert."
msgid "User is not allowed to resolve thread"
msgstr ""
@@ -39071,7 +39857,7 @@ msgid "User was successfully removed from group."
msgstr ""
msgid "User was successfully removed from project."
-msgstr ""
+msgstr "Benutzer(in) wurde erfolgreich von dem Projekt entfernt."
msgid "User was successfully updated."
msgstr ""
@@ -39316,6 +40102,9 @@ msgstr ""
msgid "Users"
msgstr "Benutzer(innen)"
+msgid "Users API rate limit"
+msgstr ""
+
msgid "Users can launch a development environment from a GitLab browser tab when the %{linkStart}Gitpod%{linkEnd} integration is enabled."
msgstr ""
@@ -39641,6 +40430,9 @@ msgstr ""
msgid "View group labels"
msgstr "Gruppenlabels ansehen"
+msgid "View group pipeline usage quota"
+msgstr ""
+
msgid "View incident details at"
msgstr ""
@@ -39793,6 +40585,9 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
+msgid "Vulnerability"
+msgstr ""
+
msgid "Vulnerability Report"
msgstr ""
@@ -39844,6 +40639,9 @@ msgstr ""
msgid "VulnerabilityManagement|An unverified non-confirmed finding"
msgstr ""
+msgid "VulnerabilityManagement|At least one identifier is required"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -39853,12 +40651,24 @@ msgstr ""
msgid "VulnerabilityManagement|Create Jira issue"
msgstr ""
+msgid "VulnerabilityManagement|Enter a name"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE code"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE identifier URL"
+msgstr ""
+
msgid "VulnerabilityManagement|Fetching linked Jira issues"
msgstr ""
msgid "VulnerabilityManagement|Manually add a vulnerability entry into the vulnerability report."
msgstr ""
+msgid "VulnerabilityManagement|Name is a required field"
+msgstr ""
+
msgid "VulnerabilityManagement|Needs triage"
msgstr ""
@@ -39874,6 +40684,18 @@ msgstr ""
msgid "VulnerabilityManagement|Select a method"
msgstr ""
+msgid "VulnerabilityManagement|Select a severity level"
+msgstr ""
+
+msgid "VulnerabilityManagement|Select a status"
+msgstr ""
+
+msgid "VulnerabilityManagement|Severity is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Something went wrong while creating vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -39898,6 +40720,12 @@ msgstr ""
msgid "VulnerabilityManagement|Something went wrong, could not update vulnerability state."
msgstr ""
+msgid "VulnerabilityManagement|Status is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Submit vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Summary, detailed description, steps to reproduce, etc."
msgstr ""
@@ -40093,6 +40921,9 @@ msgstr ""
msgid "WARNING:"
msgstr ""
+msgid "WARNING: This snippet contains hidden files which might be used to mask malicious behavior. Exercise caution if cloning and executing code from this snippet."
+msgstr ""
+
msgid "Wait for the file to load to copy its contents"
msgstr ""
@@ -40312,6 +41143,15 @@ msgstr ""
msgid "Webhooks|An issue is created, updated, closed, or reopened."
msgstr ""
+msgid "Webhooks|Are you sure you want to delete this group hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this project hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this webhook?"
+msgstr ""
+
msgid "Webhooks|Comments"
msgstr ""
@@ -40321,6 +41161,9 @@ msgstr ""
msgid "Webhooks|Confidential issues events"
msgstr ""
+msgid "Webhooks|Delete webhook"
+msgstr ""
+
msgid "Webhooks|Deployment events"
msgstr ""
@@ -40554,6 +41397,9 @@ msgstr ""
msgid "Wiki"
msgstr "Wiki"
+msgid "Wiki page"
+msgstr ""
+
msgid "Wiki page was successfully created."
msgstr ""
@@ -40659,7 +41505,7 @@ msgstr "Seite %{pageTitle} löschen?"
msgid "WikiPageConflictMessage|Someone edited the page the same time you did. Please check out %{wikiLinkStart}the page%{wikiLinkEnd} and make sure your changes will not unintentionally remove theirs."
msgstr ""
-msgid "WikiPage|An error occured while trying to render the content editor. Please try again later."
+msgid "WikiPage|An error occurred while trying to render the content editor. Please try again later."
msgstr ""
msgid "WikiPage|Are you sure you want to switch back to the classic editor?"
@@ -40818,6 +41664,18 @@ msgstr ""
msgid "WorkItem|New Task"
msgstr ""
+msgid "WorkItem|Something went wrong when creating a work item. Please try again"
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching the work item. Please try again."
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching work item types. Please try again"
+msgstr ""
+
+msgid "WorkItem|Type"
+msgstr ""
+
msgid "WorkItem|Work Items"
msgstr ""
@@ -40831,7 +41689,7 @@ msgid "Write"
msgstr "Schreiben"
msgid "Write a comment or drag your files here…"
-msgstr ""
+msgstr "Schreibe einen Kommentar oder füge Dateien hier ein…"
msgid "Write a comment…"
msgstr ""
@@ -40884,7 +41742,10 @@ msgstr ""
msgid "You are about to add %{usersTag} people to the discussion. They will all receive a notification."
msgstr ""
-msgid "You are about to permanently delete this project"
+msgid "You are about to delete this forked project containing:"
+msgstr ""
+
+msgid "You are about to delete this project containing:"
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."
@@ -40905,6 +41766,9 @@ msgstr "Du versuchst eine Datei zu löschen, die zuvor aktualisiert wurde."
msgid "You are attempting to update a file that has changed since you started editing it."
msgstr ""
+msgid "You are billed if you exceed this number. %{qsrOverageLinkStart}How does billing work?%{qsrOverageLinkEnd}"
+msgstr ""
+
msgid "You are connected to the Prometheus server, but there is currently no data to display."
msgstr ""
@@ -40962,6 +41826,9 @@ msgstr ""
msgid "You are not authorized to update this scanner profile"
msgstr ""
+msgid "You are not authorized to upload metric images"
+msgstr ""
+
msgid "You are now impersonating %{username}"
msgstr ""
@@ -41110,14 +41977,11 @@ msgid "You can only edit files when you are on a branch"
msgstr "Du kannst Dateien nur bearbeiten, wenn du dich auf einem Branch befindest"
msgid "You can only transfer the project to namespaces you manage."
-msgstr ""
+msgstr "Du kannst das Projekt nur in deine Namensräume übertragen."
msgid "You can only upload one design when dropping onto an existing design."
msgstr ""
-msgid "You can recover this project until %{date}"
-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 "Du kannst den Merge-Konflikt lösen, indem du entweder den interaktiven Modus verwendest, indem du die Schaltflächen %{use_ours} oder %{use_theirs} wählst, oder indem du die Dateien direkt bearbeitest. Übernimm diese Änderungen mittels Commit in %{branch_name}"
@@ -41166,9 +42030,6 @@ msgstr "Du kannst nicht auf eine schreibgeschützte sekundäre Gitlab Geo-Instan
msgid "You cannot write to this read-only GitLab instance."
msgstr "Du kannst nicht auf dieser schreibgeschützte GitLab-Instanz schreiben."
-msgid "You can’t %{tag_start}edit%{tag_end} files directly in this project. Fork this project and submit a merge request with your changes."
-msgstr ""
-
msgid "You can’t edit files directly in this project. Fork this project and submit a merge request with your changes."
msgstr ""
@@ -41321,9 +42182,6 @@ msgstr "Du hast keine Berechtigungen"
msgid "You have not added any approvers. Start by adding users or groups."
msgstr "Du hast keine Genehmigungsberechtigten hinzugefügt. Beginne, indem du Benutzer(innen) oder Gruppen hinzufügst."
-msgid "You have reached your project limit"
-msgstr "Du hast die Projektbegrenzung erreicht"
-
msgid "You have set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
@@ -41354,12 +42212,6 @@ msgstr ""
msgid "You must have maintainer access to force delete a lock"
msgstr "Du musst Betreuerzugriff besitzen, um das Entfernen einer Sperre zu erzwingen"
-msgid "You must have permission to create a project in a group before forking."
-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 ""
@@ -41765,7 +42617,7 @@ msgstr "Deine Projekte"
msgid "Your public email will be displayed on your public profile."
msgstr ""
-msgid "Your request for access could not be processed: %{error_meesage}"
+msgid "Your request for access could not be processed: %{error_message}"
msgstr ""
msgid "Your request for access has been queued for review."
@@ -41948,6 +42800,9 @@ msgstr "archiviert"
msgid "archived:"
msgstr ""
+msgid "artifacts"
+msgstr ""
+
msgid "assign yourself"
msgstr ""
@@ -41977,6 +42832,9 @@ msgstr[1] ""
msgid "branch name"
msgstr "Branch-Name"
+msgid "builds"
+msgstr ""
+
msgid "by"
msgstr "von"
@@ -42400,6 +43258,9 @@ msgstr ""
msgid "contact with same email already exists in group hierarchy"
msgstr ""
+msgid "container registry images"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -42439,6 +43300,9 @@ msgstr ""
msgid "data"
msgstr ""
+msgid "database"
+msgstr ""
+
msgid "date must not be after 9999-12-31"
msgstr ""
@@ -42462,9 +43326,6 @@ msgstr ""
msgid "design"
msgstr ""
-msgid "detached"
-msgstr ""
-
msgid "disabled"
msgstr "dektiviert"
@@ -42713,7 +43574,7 @@ msgstr ""
msgid "is not a valid X509 certificate."
msgstr "ist kein gültiges X509-Zertifikat."
-msgid "is not allowed for sign-up."
+msgid "is not allowed for sign-up. Please use your regular email address."
msgstr ""
msgid "is not allowed for this group."
@@ -42725,7 +43586,7 @@ msgstr ""
msgid "is not allowed since the group is not top-level group."
msgstr ""
-msgid "is not allowed."
+msgid "is not allowed. Please use your regular email address."
msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
@@ -42812,6 +43673,9 @@ msgstr "weniger als eine Minute"
msgid "level: %{level}"
msgstr "Level: %{level}"
+msgid "lfs objects"
+msgstr ""
+
msgid "limit of %{project_limit} reached"
msgstr "Limit von %{project_limit} erreicht"
@@ -43031,6 +43895,9 @@ msgstr ""
msgid "mrWidget|Merge blocked: pipeline must succeed. It's waiting for a manual action to continue."
msgstr ""
+msgid "mrWidget|Merge blocked: pipeline must succeed. Push a commit that fixes the failure, or %{linkStart}learn about other solutions.%{linkEnd}"
+msgstr ""
+
msgid "mrWidget|Merge blocked: this merge request must be approved."
msgstr ""
@@ -43148,9 +44015,6 @@ msgstr "Die Änderungen wurden gemerged nach"
msgid "mrWidget|The changes were not merged into"
msgstr "Die Änderungen wurden nicht gemerged nach"
-msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr "Der Quellbranch wurde gelöscht"
@@ -43298,9 +44162,6 @@ msgstr ""
msgid "open issue"
msgstr ""
-msgid "opened %{timeAgo}"
-msgstr "erstellt %{timeAgo}"
-
msgid "or"
msgstr "oder"
@@ -43312,6 +44173,12 @@ msgid_plural "out of %d total tests"
msgstr[0] "von insgesamt %d Test"
msgstr[1] "von insgesamt %d Tests"
+msgid "packages"
+msgstr ""
+
+msgid "pages"
+msgstr ""
+
msgid "parent"
msgid_plural "parents"
msgstr[0] "Ãœbergeordneter"
@@ -43461,6 +44328,9 @@ msgid_plural "replies"
msgstr[0] "Antwort"
msgstr[1] "Antworten"
+msgid "repositories"
+msgstr ""
+
msgid "repository:"
msgstr ""
@@ -43581,12 +44451,18 @@ msgstr ""
msgid "tag name"
msgstr "Tag-Name"
+msgid "terraform states"
+msgstr ""
+
msgid "the correct format."
msgstr ""
msgid "the file"
msgstr ""
+msgid "the following epic(s)"
+msgstr ""
+
msgid "the following issue(s)"
msgstr "die folgenden Ticket(s)"
@@ -43599,21 +44475,12 @@ msgstr ""
msgid "this document"
msgstr "dieses Dokument"
-msgid "this issue cannot be assigned to a confidential epic since it is public"
-msgstr ""
-
-msgid "this issue cannot be made public since it belongs to a confidential epic"
-msgstr ""
-
msgid "time summary"
msgstr ""
msgid "toggle collapse"
msgstr ""
-msgid "train"
-msgstr ""
-
msgid "triggered"
msgstr "ausgelöst"
@@ -43742,3 +44609,6 @@ msgstr ""
msgid "{project}"
msgstr ""
+msgid "✔"
+msgstr ""
+
diff --git a/locale/el_GR/gitlab.po b/locale/el_GR/gitlab.po
index 8eabb110e70..1e73df936fd 100644
--- a/locale/el_GR/gitlab.po
+++ b/locale/el_GR/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: el\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2022-02-02 15:45\n"
+"PO-Revision-Date: 2022-03-01 20:38\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -146,6 +146,11 @@ msgid_plural "%d approvers (you've approved)"
msgstr[0] ""
msgstr[1] ""
+msgid "%d assigned issue"
+msgid_plural "%d assigned issues"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -421,8 +426,23 @@ msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
msgstr[1] ""
-msgid "%d vulnerability updated"
-msgid_plural "%d vulnerabilities updated"
+msgid "%d vulnerability set to confirmed"
+msgid_plural "%d vulnerabilities set to confirmed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to dismissed"
+msgid_plural "%d vulnerabilities set to dismissed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to needs triage"
+msgid_plural "%d vulnerabilities set to needs triage"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to resolved"
+msgid_plural "%d vulnerabilities set to resolved"
msgstr[0] ""
msgstr[1] ""
@@ -510,6 +530,12 @@ msgstr[1] ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{completed} of %{total} issues closed"
+msgstr ""
+
+msgid "%{completed} of %{total} weight completed"
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -858,6 +884,9 @@ msgstr ""
msgid "%{openedIssues} open, %{closedIssues} closed"
msgstr ""
+msgid "%{percentage}%% issues closed"
+msgstr ""
+
msgid "%{percentage}%% weight completed"
msgstr ""
@@ -1287,6 +1316,9 @@ msgid_plural "- Users"
msgstr[0] ""
msgstr[1] ""
+msgid "- of - issues closed"
+msgstr ""
+
msgid "- of - weight completed"
msgstr ""
@@ -1429,7 +1461,7 @@ msgstr ""
msgid "1000+"
msgstr ""
-msgid "192.168.0.0/24"
+msgid "192.168.0.0/24 or 2001:0DB8:1234::/48"
msgstr ""
msgid "1st contribution!"
@@ -1741,13 +1773,13 @@ msgstr ""
msgid "AWS Access Key"
msgstr ""
-msgid "AWS Access Key. Only required if not using role instance credentials"
+msgid "AWS Secret Access Key"
msgstr ""
-msgid "AWS Secret Access Key"
+msgid "AWS access key ID (Optional)"
msgstr ""
-msgid "AWS Secret Access Key. Only required if not using role instance credentials"
+msgid "AWS secret access key (Optional)"
msgstr ""
msgid "AWS service error: %{error}"
@@ -1807,9 +1839,6 @@ msgstr ""
msgid "Access granted"
msgstr ""
-msgid "Access key ID"
-msgstr ""
-
msgid "Access requests"
msgstr ""
@@ -1984,7 +2013,7 @@ msgstr ""
msgid "Activity"
msgstr ""
-msgid "Activity|An error occured while retrieving activity. Reload the page to try again."
+msgid "Activity|An error occurred while retrieving activity. Reload the page to try again."
msgstr ""
msgid "Add"
@@ -2023,6 +2052,9 @@ msgstr ""
msgid "Add a %{type}"
msgstr ""
+msgid "Add a GCP region"
+msgstr ""
+
msgid "Add a GPG key"
msgstr ""
@@ -2074,6 +2106,9 @@ msgstr ""
msgid "Add a numbered list"
msgstr ""
+msgid "Add a related epic"
+msgstr ""
+
msgid "Add a related issue"
msgstr ""
@@ -2188,6 +2223,9 @@ msgstr ""
msgid "Add or subtract spent time"
msgstr ""
+msgid "Add people"
+msgstr ""
+
msgid "Add previously merged commits"
msgstr ""
@@ -2254,6 +2292,9 @@ msgstr ""
msgid "Add webhook"
msgstr ""
+msgid "Add your team members and others to GitLab."
+msgstr ""
+
msgid "Add/remove"
msgstr ""
@@ -3076,12 +3117,6 @@ msgstr ""
msgid "AdvancedSearch|Reindex required"
msgstr ""
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. Permanently deleting this project will %{strongStart}immediately delete%{strongEnd} its repositories and %{strongStart}all related resources%{strongEnd}, including issues, merge requests etc."
-msgstr ""
-
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. You will lose this project's repository and %{strongStart}all related resources%{strongEnd}, including issues and merge requests."
-msgstr ""
-
msgid "After a successful password update you will be redirected to login screen."
msgstr ""
@@ -3112,6 +3147,9 @@ msgstr ""
msgid "Akismet helps prevent the creation of spam issues in public projects."
msgstr ""
+msgid "Alert"
+msgstr ""
+
msgid "AlertManagement|Acknowledged"
msgstr ""
@@ -3484,9 +3522,6 @@ msgstr ""
msgid "All environments"
msgstr ""
-msgid "All epics"
-msgstr ""
-
msgid "All groups and projects"
msgstr ""
@@ -4223,12 +4258,15 @@ msgstr ""
msgid "ApplicationSettings|Approve users in the pending approval status?"
msgstr ""
-msgid "ApplicationSettings|By making this change, you will automatically approve %d user with the pending approval status."
-msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users with the pending approval status."
+msgid "ApplicationSettings|Approve users who are pending approval?"
+msgstr ""
+
+msgid "ApplicationSettings|By making this change, you will automatically approve %d user who is pending approval."
+msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users who are pending approval."
msgstr[0] ""
msgstr[1] ""
-msgid "ApplicationSettings|By making this change, you will automatically approve all users in pending approval status."
+msgid "ApplicationSettings|By making this change, you will automatically approve all users who are pending approval."
msgstr ""
msgid "ApplicationSettings|Denied domains for sign-ups"
@@ -4634,10 +4672,10 @@ msgstr ""
msgid "Archiving the project will make it entirely read-only. It is hidden from the dashboard and doesn't show up in searches. %{strong_start}The repository cannot be committed to, and no issues, comments, or other entities can be created.%{strong_end} %{link_start}Learn more.%{link_end}"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to delete this project?"
+msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
+msgid "Are you absolutely sure?"
msgstr ""
msgid "Are you sure that you want to archive this project?"
@@ -4673,12 +4711,18 @@ msgstr ""
msgid "Are you sure you want to delete this SSH key?"
msgstr ""
+msgid "Are you sure you want to delete this comment?"
+msgstr ""
+
msgid "Are you sure you want to delete this deploy key?"
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 label?"
+msgstr ""
+
msgid "Are you sure you want to delete this pipeline schedule?"
msgstr ""
@@ -4694,9 +4738,6 @@ msgstr ""
msgid "Are you sure you want to discard your changes?"
msgstr ""
-msgid "Are you sure you want to erase this build?"
-msgstr ""
-
msgid "Are you sure you want to import %d repository?"
msgid_plural "Are you sure you want to import %d repositories?"
msgstr[0] ""
@@ -4744,6 +4785,9 @@ msgstr ""
msgid "Are you sure you want to remove this list?"
msgstr ""
+msgid "Are you sure you want to remove this nickname?"
+msgstr ""
+
msgid "Are you sure you want to reset the health check token?"
msgstr ""
@@ -4756,10 +4800,10 @@ 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?"
+msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
msgstr ""
-msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
+msgid "Are you sure you want to revoke this project access token? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to stop this environment?"
@@ -4906,9 +4950,6 @@ msgstr ""
msgid "Assigned to %{assignee_name}"
msgstr ""
-msgid "Assigned to %{name}"
-msgstr ""
-
msgid "Assigned to me"
msgstr ""
@@ -4973,6 +5014,9 @@ msgstr[1] ""
msgid "Attaching the file failed."
msgstr ""
+msgid "Attention"
+msgstr ""
+
msgid "Audit Events"
msgstr ""
@@ -5135,6 +5179,12 @@ msgstr ""
msgid "Authorized applications (%{size})"
msgstr ""
+msgid "AuthorizedApplication|Are you sure you want to revoke this application?"
+msgstr ""
+
+msgid "AuthorizedApplication|Revoke application"
+msgstr ""
+
msgid "Authors: %{authors}"
msgstr ""
@@ -6328,6 +6378,9 @@ msgstr ""
msgid "CICDAnalytics|Shared Runners Usage"
msgstr ""
+msgid "CICDAnalytics|Shared runner pipeline minute duration by month"
+msgstr ""
+
msgid "CICDAnalytics|Shared runner usage"
msgstr ""
@@ -6469,6 +6522,9 @@ msgstr ""
msgid "Can create groups:"
msgstr ""
+msgid "Can not delete primary training"
+msgstr ""
+
msgid "Can't apply as the source branch was deleted."
msgstr ""
@@ -6802,9 +6858,6 @@ msgstr ""
msgid "Changing any setting here requires an application restart"
msgstr ""
-msgid "Changing group URL can have unintended side effects."
-msgstr ""
-
msgid "Charts can't be displayed as the request for data has timed out. %{documentationLink}"
msgstr ""
@@ -6892,9 +6945,6 @@ msgstr ""
msgid "Checking branch availability..."
msgstr ""
-msgid "Checking group URL availability..."
-msgstr ""
-
msgid "Checking group path availability..."
msgstr ""
@@ -7388,6 +7438,9 @@ msgstr ""
msgid "Clear recent searches"
msgstr ""
+msgid "Clear repository checks"
+msgstr ""
+
msgid "Clear search"
msgstr ""
@@ -7520,9 +7573,6 @@ msgstr ""
msgid "Closed MRs"
msgstr ""
-msgid "Closed epics"
-msgstr ""
-
msgid "Closed issues"
msgstr ""
@@ -7559,13 +7609,13 @@ msgstr ""
msgid "Cluster level"
msgstr ""
-msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
+msgid "Cluster type must be specified for Stages::ClusterEndpointInserter"
msgstr ""
msgid "ClusterAgents|%{name} successfully deleted"
msgstr ""
-msgid "ClusterAgents|%{number} of %{total} Agents"
+msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
@@ -7607,6 +7657,15 @@ msgstr ""
msgid "ClusterAgents|Agent never connected to GitLab"
msgstr ""
+msgid "ClusterAgents|Agent version mismatch"
+msgstr ""
+
+msgid "ClusterAgents|Agent version mismatch and update"
+msgstr ""
+
+msgid "ClusterAgents|Agent version update required"
+msgstr ""
+
msgid "ClusterAgents|All"
msgstr ""
@@ -7631,7 +7690,7 @@ msgstr ""
msgid "ClusterAgents|Configuration"
msgstr ""
-msgid "ClusterAgents|Connect a cluster through the Agent"
+msgid "ClusterAgents|Connect a cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connect existing cluster"
@@ -7640,13 +7699,13 @@ msgstr ""
msgid "ClusterAgents|Connect with a certificate"
msgstr ""
-msgid "ClusterAgents|Connect with agent"
+msgid "ClusterAgents|Connect with an agent"
msgstr ""
msgid "ClusterAgents|Connect with the GitLab Agent"
msgstr ""
-msgid "ClusterAgents|Connect your cluster through the Agent"
+msgid "ClusterAgents|Connect your cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connected"
@@ -7706,7 +7765,10 @@ msgstr ""
msgid "ClusterAgents|How to register an agent?"
msgstr ""
-msgid "ClusterAgents|Install new Agent"
+msgid "ClusterAgents|How to update an agent?"
+msgstr ""
+
+msgid "ClusterAgents|Install a new agent"
msgstr ""
msgid "ClusterAgents|Last connected %{timeAgo}."
@@ -7733,7 +7795,7 @@ msgstr ""
msgid "ClusterAgents|Never connected"
msgstr ""
-msgid "ClusterAgents|No Agents"
+msgid "ClusterAgents|No agents"
msgstr ""
msgid "ClusterAgents|No clusters connected through cluster certificates"
@@ -7793,6 +7855,9 @@ msgstr ""
msgid "ClusterAgents|The agent has not been connected in a long time. There might be a connectivity issue. Last contact was %{timeAgo}."
msgstr ""
+msgid "ClusterAgents|The agent version do not match each other across your cluster's pods. This can happen when a new agent version was just deployed and Kubernetes is shutting down the old pods."
+msgstr ""
+
msgid "ClusterAgents|The recommended installation method includes the token. If you want to follow the advanced installation method provided in the docs, make sure you save the token value before you close this window."
msgstr ""
@@ -7840,6 +7905,9 @@ msgstr ""
msgid "ClusterAgents|You will need to create a token to connect to your agent"
msgstr ""
+msgid "ClusterAgents|Your agent version is out of sync with your GitLab version (v%{version}), which might cause compatibility problems. Update the agent installed on your cluster to the most recent version."
+msgstr ""
+
msgid "ClusterAgents|Your instance doesn't have the %{linkStart}GitLab Agent Server (KAS)%{linkEnd} set up. Ask a GitLab Administrator to install it."
msgstr ""
@@ -8716,9 +8784,6 @@ msgstr ""
msgid "Comma-separated list of email addresses."
msgstr ""
-msgid "Comma-separated list of users allowed to exceed the rate limit."
-msgstr ""
-
msgid "Comma-separated, e.g. '1.1.1.1, 2.2.2.0/24'"
msgstr ""
@@ -9045,6 +9110,12 @@ msgstr ""
msgid "Confidential"
msgstr ""
+msgid "Confidential issue"
+msgstr ""
+
+msgid "Confidential note"
+msgstr ""
+
msgid "Confidentiality"
msgstr ""
@@ -9078,6 +9149,9 @@ msgstr ""
msgid "Configure Dependency Scanning in `.gitlab-ci.yml`, creating this file if it does not already exist"
msgstr ""
+msgid "Configure GitLab"
+msgstr ""
+
msgid "Configure GitLab runners to start using the Web Terminal. %{helpStart}Learn more.%{helpEnd}"
msgstr ""
@@ -9126,6 +9200,15 @@ msgstr ""
msgid "Configure pipelines to deploy web apps, backend services, APIs and static resources to Google Cloud"
msgstr ""
+msgid "Configure region"
+msgstr ""
+
+msgid "Configure region for environment"
+msgstr ""
+
+msgid "Configure regions"
+msgstr ""
+
msgid "Configure repository mirroring."
msgstr ""
@@ -9159,6 +9242,9 @@ msgstr ""
msgid "Configure which lists are shown for anyone who visits this board"
msgstr ""
+msgid "Configure your environments to be deployed to specific geographical regions"
+msgstr ""
+
msgid "Confirm"
msgstr ""
@@ -9861,10 +9947,10 @@ msgstr ""
msgid "CorpusManagement|Actions"
msgstr ""
-msgid "CorpusManagement|Corpus are used in fuzz testing as mutation source to Improve future testing."
+msgid "CorpusManagement|Corpus file"
msgstr ""
-msgid "CorpusManagement|Corpus file"
+msgid "CorpusManagement|Corpus files are used in coverage-guided fuzz testing as seed inputs to improve testing."
msgstr ""
msgid "CorpusManagement|Corpus files must be in *.zip format. Maximum 5 GB"
@@ -9918,6 +10004,9 @@ msgstr ""
msgid "Could not apply %{name} command."
msgstr ""
+msgid "Could not apply %{name} command. %{message}."
+msgstr ""
+
msgid "Could not authorize chat nickname. Try again!"
msgstr ""
@@ -10068,6 +10157,9 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
+msgid "Create a group"
+msgstr ""
+
msgid "Create a merge request"
msgstr ""
@@ -10092,6 +10184,9 @@ msgstr ""
msgid "Create a personal access token on your account to pull or push via %{protocol}."
msgstr ""
+msgid "Create a project"
+msgstr ""
+
msgid "Create an account using:"
msgstr ""
@@ -10455,6 +10550,9 @@ msgstr ""
msgid "Creation date"
msgstr ""
+msgid "Creator"
+msgstr ""
+
msgid "Credentials"
msgstr ""
@@ -10467,9 +10565,15 @@ msgstr ""
msgid "CredentialsInventory|Personal Access Tokens"
msgstr ""
+msgid "CredentialsInventory|Project Access Tokens"
+msgstr ""
+
msgid "CredentialsInventory|SSH Keys"
msgstr ""
+msgid "Credit card required to be on file in order to create a pipeline"
+msgstr ""
+
msgid "Credit card:"
msgstr ""
@@ -10653,9 +10757,6 @@ msgstr ""
msgid "Customer relations"
msgstr ""
-msgid "Customizable by an administrator."
-msgstr ""
-
msgid "Customizable by owners."
msgstr ""
@@ -10785,30 +10886,18 @@ msgstr ""
msgid "CycleAnalytics|%{selectedLabelsCount} selected (%{maxLabels} max)"
msgstr ""
-msgid "CycleAnalytics|%{stageCount} stages selected"
-msgstr ""
-
-msgid "CycleAnalytics|All stages"
-msgstr ""
-
-msgid "CycleAnalytics|Average days to completion"
+msgid "CycleAnalytics|Average time to completion"
msgstr ""
msgid "CycleAnalytics|Date"
msgstr ""
-msgid "CycleAnalytics|Days to completion"
-msgstr ""
-
msgid "CycleAnalytics|Display chart filters"
msgstr ""
msgid "CycleAnalytics|Lead Time for Changes"
msgstr ""
-msgid "CycleAnalytics|No stages selected"
-msgstr ""
-
msgid "CycleAnalytics|Number of tasks"
msgstr ""
@@ -10837,18 +10926,30 @@ msgstr ""
msgid "CycleAnalytics|Showing data for group '%{groupName}' from %{createdAfter} to %{createdBefore}"
msgstr ""
-msgid "CycleAnalytics|Stages"
+msgid "CycleAnalytics|Stage time: %{title}"
msgstr ""
msgid "CycleAnalytics|Tasks by type"
msgstr ""
-msgid "CycleAnalytics|The average time spent in the selected stage for the items that were completed on each date. Data limited to the last 500 items."
+msgid "CycleAnalytics|The average time items spent in this stage. Data limited to items completed within this date range."
msgstr ""
msgid "CycleAnalytics|The given date range is larger than 180 days"
msgstr ""
+msgid "CycleAnalytics|The total time items spent across each value stream stage. Data limited to items completed within this date range."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Stage time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Total time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|Total time"
+msgstr ""
+
msgid "CycleAnalytics|Type of work"
msgstr ""
@@ -10861,9 +10962,6 @@ msgstr ""
msgid "CycleAnalytics|project dropdown filter"
msgstr ""
-msgid "CycleAnalytics|stage dropdown"
-msgstr ""
-
msgid "DAG visualization requires at least 3 dependent jobs."
msgstr ""
@@ -10963,10 +11061,16 @@ msgstr ""
msgid "DastProfiles|AJAX spider"
msgstr ""
+msgid "DastProfiles|API"
+msgstr ""
+
+msgid "DastProfiles|API endpoint URL"
+msgstr ""
+
msgid "DastProfiles|Active"
msgstr ""
-msgid "DastProfiles|Additional request headers (Optional)"
+msgid "DastProfiles|Additional request headers (optional)"
msgstr ""
msgid "DastProfiles|Are you sure you want to delete this profile?"
@@ -10981,6 +11085,9 @@ msgstr ""
msgid "DastProfiles|Branch missing"
msgstr ""
+msgid "DastProfiles|Choose a scan method"
+msgstr ""
+
msgid "DastProfiles|Could not create the scanner profile. Please try again."
msgstr ""
@@ -11050,7 +11157,13 @@ msgstr ""
msgid "DastProfiles|Excluded URLs"
msgstr ""
-msgid "DastProfiles|Excluded URLs (Optional)"
+msgid "DastProfiles|Excluded URLs (optional)"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths (optional)"
msgstr ""
msgid "DastProfiles|Hide debug messages"
@@ -11107,9 +11220,6 @@ msgstr ""
msgid "DastProfiles|Request headers"
msgstr ""
-msgid "DastProfiles|Rest API"
-msgstr ""
-
msgid "DastProfiles|Run the AJAX spider, in addition to the traditional spider, to crawl the target site."
msgstr ""
@@ -11119,6 +11229,9 @@ msgstr ""
msgid "DastProfiles|Save profile"
msgstr ""
+msgid "DastProfiles|Scan method"
+msgstr ""
+
msgid "DastProfiles|Scan mode"
msgstr ""
@@ -11197,12 +11310,24 @@ msgstr ""
msgid "DastProfiles|Website"
msgstr ""
+msgid "DastProfiles|What does each method do?"
+msgstr ""
+
msgid "DastProfiles|You can either choose a passive scan or validate the target site from the site profile management page. %{docsLinkStart}Learn more about site validation.%{docsLinkEnd}"
msgstr ""
msgid "DastProfiles|You cannot run an active scan against an unvalidated site."
msgstr ""
+msgid "DastProfiles|folder/dast_example.har or https://example.com/dast_example.har"
+msgstr ""
+
+msgid "DastProfiles|folder/example.postman_collection.json or https://example.com/"
+msgstr ""
+
+msgid "DastProfiles|folder/openapi.json or https://example.com/openapi.json"
+msgstr ""
+
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
@@ -11310,6 +11435,9 @@ msgstr ""
msgid "DatadogIntegration|API URL"
msgstr ""
+msgid "DatadogIntegration|Custom tags in Datadog. Enter one tag per line in the %{codeOpen}key:value%{codeClose} format. %{linkOpen}How do I use tags?%{linkClose}"
+msgstr ""
+
msgid "DatadogIntegration|Environment"
msgstr ""
@@ -11328,12 +11456,18 @@ msgstr ""
msgid "DatadogIntegration|Tag all data from this GitLab instance in Datadog. Useful when managing several self-managed deployments."
msgstr ""
+msgid "DatadogIntegration|Tags"
+msgstr ""
+
msgid "DatadogIntegration|The Datadog site to send data to. To send data to the EU site, use %{codeOpen}datadoghq.eu%{codeClose}."
msgstr ""
msgid "DatadogIntegration|Trace your GitLab pipelines with Datadog."
msgstr ""
+msgid "DatadogIntegration|have an invalid format"
+msgstr ""
+
msgid "Datasource name not found"
msgstr ""
@@ -11343,9 +11477,6 @@ msgstr ""
msgid "Date merged"
msgstr ""
-msgid "Date picker"
-msgstr ""
-
msgid "Date range"
msgstr ""
@@ -11499,9 +11630,6 @@ msgstr ""
msgid "Definition"
msgstr ""
-msgid "Delayed Project Deletion (%{adjourned_deletion})"
-msgstr ""
-
msgid "DelayedJobs|Are you sure you want to run %{jobName} immediately? Otherwise this job will run automatically after its timer finishes."
msgstr ""
@@ -11580,10 +11708,10 @@ msgstr ""
msgid "Delete pipeline"
msgstr ""
-msgid "Delete project"
+msgid "Delete pipeline schedule"
msgstr ""
-msgid "Delete project. Are you ABSOLUTELY SURE?"
+msgid "Delete project"
msgstr ""
msgid "Delete row"
@@ -11613,6 +11741,9 @@ msgstr ""
msgid "Delete this epic and all descendants?"
msgstr ""
+msgid "Delete this project"
+msgstr ""
+
msgid "Delete user list"
msgstr ""
@@ -11871,6 +12002,12 @@ msgstr ""
msgid "Deploy to..."
msgstr ""
+msgid "DeployBoards|To see deployment progress for your environments, make sure you are deploying to %{codeStart}$KUBE_NAMESPACE%{codeEnd} and annotating with %{codeStart}app.gitlab.com/app=$CI_PROJECT_PATH_SLUG%{codeEnd} and %{codeStart}app.gitlab.com/env=$CI_ENVIRONMENT_SLUG%{codeEnd}."
+msgstr ""
+
+msgid "DeployBoard|Kubernetes Pods"
+msgstr ""
+
msgid "DeployFreeze|Add a freeze period to prevent unintended releases during a period of time for a given environment. You must update the deployment jobs in %{filename} according to the deploy freezes added here. %{freeze_period_link_start}Learn more.%{freeze_period_link_end}"
msgstr ""
@@ -11955,9 +12092,6 @@ msgstr ""
msgid "DeployTokens|Active Deploy Tokens (%{active_tokens})"
msgstr ""
-msgid "DeployTokens|Allows read and write access to registry images."
-msgstr ""
-
msgid "DeployTokens|Allows read and write access to the package registry."
msgstr ""
@@ -11970,6 +12104,9 @@ msgstr ""
msgid "DeployTokens|Allows read-only access to the repository."
msgstr ""
+msgid "DeployTokens|Allows write access to registry images."
+msgstr ""
+
msgid "DeployTokens|Copy deploy token"
msgstr ""
@@ -12063,12 +12200,57 @@ msgstr ""
msgid "Deploying to AWS is easy with GitLab"
msgstr ""
+msgid "Deployment"
+msgstr ""
+
msgid "Deployment Frequency"
msgstr ""
+msgid "Deployment Target|Project deployment target (optional)"
+msgstr ""
+
+msgid "Deployment Target|Select the deployment target"
+msgstr ""
+
msgid "Deployment frequency"
msgstr ""
+msgid "DeploymentTarget|GitLab Pages"
+msgstr ""
+
+msgid "DeploymentTarget|Heroku"
+msgstr ""
+
+msgid "DeploymentTarget|Infrastructure provider (Terraform, Cloudformation, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Kubernetes (GKE, EKS, OpenShift, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Managed container runtime (Fargate, Cloud Run, DigitalOcean App)"
+msgstr ""
+
+msgid "DeploymentTarget|Mobile app store"
+msgstr ""
+
+msgid "DeploymentTarget|No deployment planned"
+msgstr ""
+
+msgid "DeploymentTarget|Other hosting service"
+msgstr ""
+
+msgid "DeploymentTarget|Registry (package or container)"
+msgstr ""
+
+msgid "DeploymentTarget|Self-managed container runtime (Podman, Docker Swarm, Docker Compose)"
+msgstr ""
+
+msgid "DeploymentTarget|Serverless backend (Lambda, Cloud functions)"
+msgstr ""
+
+msgid "DeploymentTarget|Virtual machine (for example, EC2)"
+msgstr ""
+
msgid "Deployments"
msgstr ""
@@ -12107,6 +12289,9 @@ msgstr ""
msgid "Deployment|This deployment was created using the API"
msgstr ""
+msgid "Deployment|Triggerer"
+msgstr ""
+
msgid "Deployment|Waiting"
msgstr ""
@@ -12134,6 +12319,18 @@ msgstr ""
msgid "Deprecated API rate limits"
msgstr ""
+msgid "Deprecations|Feature deprecation and removal"
+msgstr ""
+
+msgid "Deprecations|For information on a possible replacement %{epicStart} learn more about Opstrace %{epicEnd}."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7 and are %{epicStart} scheduled for removal %{epicEnd} in GitLab 15.0."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7, and are %{removal_link_start} scheduled for removal %{link_end} in GitLab 15.0. For information on a possible replacement, %{opstrace_link_start} learn more about Opstrace %{link_end}."
+msgstr ""
+
msgid "Deprioritize label"
msgstr ""
@@ -12379,10 +12576,10 @@ msgstr ""
msgid "DevopsAdoption|At least one deploy"
msgstr ""
-msgid "DevopsAdoption|At least one issue opened"
+msgid "DevopsAdoption|At least one issue created"
msgstr ""
-msgid "DevopsAdoption|At least one merge request opened"
+msgid "DevopsAdoption|At least one merge request created"
msgstr ""
msgid "DevopsAdoption|At least one pipeline successfully run"
@@ -12583,6 +12780,9 @@ msgstr ""
msgid "Direct member"
msgstr ""
+msgid "Direct members"
+msgstr ""
+
msgid "Direct non-authenticated users to this page."
msgstr ""
@@ -12699,6 +12899,9 @@ msgid_plural "Dismiss %d selected vulnerabilities as"
msgstr[0] ""
msgstr[1] ""
+msgid "Dismiss Alert"
+msgstr ""
+
msgid "Dismiss merge request promotion"
msgstr ""
@@ -12726,9 +12929,15 @@ msgstr ""
msgid "Display alerts from all configured monitoring tools."
msgstr ""
+msgid "Display milestones"
+msgstr ""
+
msgid "Display name"
msgstr ""
+msgid "Display progress of child issues"
+msgstr ""
+
msgid "Display rendered file"
msgstr ""
@@ -12834,6 +13043,9 @@ msgstr ""
msgid "Download image"
msgstr ""
+msgid "Download payload"
+msgstr ""
+
msgid "Download raw data (.csv)"
msgstr ""
@@ -13011,6 +13223,9 @@ msgstr ""
msgid "Edit in Web IDE"
msgstr ""
+msgid "Edit in pipeline editor"
+msgstr ""
+
msgid "Edit in single-file editor"
msgstr ""
@@ -13053,6 +13268,9 @@ msgstr ""
msgid "Edit your most recent comment in a thread (from an empty textarea)"
msgstr ""
+msgid "Edit, lint, and visualize your pipeline."
+msgstr ""
+
msgid "Edited"
msgstr ""
@@ -13494,6 +13712,9 @@ msgstr ""
msgid "Enforce two-factor authentication for all user sign-ins."
msgstr ""
+msgid "Enhance security by storing service account keys in secret managers - learn more about %{docLinkStart}secret management with GitLab%{docLinkEnd}"
+msgstr ""
+
msgid "Ensure connectivity is available from the GitLab server to the Prometheus server"
msgstr ""
@@ -13554,6 +13775,9 @@ 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 following to confirm:"
+msgstr ""
+
msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
@@ -14084,9 +14308,6 @@ 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 ""
@@ -14222,6 +14443,9 @@ msgstr ""
msgid "Errors:"
msgstr ""
+msgid "Escalate this incident"
+msgstr ""
+
msgid "Escalation Policies"
msgstr ""
@@ -14234,6 +14458,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy"
+msgstr ""
+
msgid "Escalation policy:"
msgstr ""
@@ -14485,6 +14712,9 @@ msgstr ""
msgid "Existing sign in methods may be removed"
msgstr ""
+msgid "Exit."
+msgstr ""
+
msgid "Expand"
msgstr ""
@@ -14581,6 +14811,9 @@ msgstr ""
msgid "Explore public groups"
msgstr ""
+msgid "Explore public projects"
+msgstr ""
+
msgid "Explore snippets"
msgstr ""
@@ -14742,7 +14975,7 @@ msgid_plural "Failed to archive designs. Please try again."
msgstr[0] ""
msgstr[1] ""
-msgid "Failed to assign a reviewer because no user was found."
+msgid "Failed to assign a reviewer because no user was specified."
msgstr ""
msgid "Failed to assign a user because no user was found."
@@ -14808,10 +15041,10 @@ msgstr ""
msgid "Failed to find import label for Jira import."
msgstr ""
-msgid "Failed to generate export, please try again later."
+msgid "Failed to find users for %{missing}"
msgstr ""
-msgid "Failed to generate report, please try again after sometime"
+msgid "Failed to generate export, please try again later."
msgstr ""
msgid "Failed to get ref."
@@ -14910,6 +15143,9 @@ msgstr ""
msgid "Failed to remove a to-do item for the design."
msgstr ""
+msgid "Failed to remove attention because no user was found."
+msgstr ""
+
msgid "Failed to remove mirror."
msgstr ""
@@ -14922,6 +15158,9 @@ msgstr ""
msgid "Failed to remove user key."
msgstr ""
+msgid "Failed to request attention because no user was found."
+msgstr ""
+
msgid "Failed to reset key. Please try again."
msgstr ""
@@ -15003,6 +15242,9 @@ msgstr ""
msgid "Feature Flags"
msgstr ""
+msgid "Feature deprecation and removal"
+msgstr ""
+
msgid "Feature flag status"
msgstr ""
@@ -15500,7 +15742,7 @@ msgstr ""
msgid "For each job, re-use the project workspace. If the workspace doesn't exist, use %{code_open}git clone%{code_close}."
msgstr ""
-msgid "For example, the application using the token or the purpose of the token."
+msgid "For example, the application using the token or the purpose of the token. Do not give sensitive information for the name of the token, as it will be visible to all %{resource_type} members."
msgstr ""
msgid "For files larger than this limit, only index the file name. The file content is neither indexed nor searchable."
@@ -15584,9 +15826,6 @@ msgstr ""
msgid "ForkProject|Select a namespace"
msgstr ""
-msgid "ForkProject|Select a namespace to fork the project"
-msgstr ""
-
msgid "ForkProject|The project can be accessed by any logged in user."
msgstr ""
@@ -15683,6 +15922,9 @@ msgstr ""
msgid "Full name"
msgstr ""
+msgid "GCP region configured"
+msgstr ""
+
msgid "GPG Key ID:"
msgstr ""
@@ -15863,6 +16105,9 @@ msgstr ""
msgid "Geo|Failed"
msgstr ""
+msgid "Geo|Filter Geo sites"
+msgstr ""
+
msgid "Geo|Filter by name"
msgstr ""
@@ -16274,6 +16519,12 @@ msgstr ""
msgid "GitLab Issue"
msgstr ""
+msgid "GitLab KAS"
+msgstr ""
+
+msgid "GitLab Memberships CSV Export"
+msgstr ""
+
msgid "GitLab Pages"
msgstr ""
@@ -16322,6 +16573,9 @@ 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 free to use. Many features for larger teams are part of our %{link_start}paid products%{link_end}. You can try Ultimate for free without any obligation or payment details."
+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 ""
@@ -16448,7 +16702,7 @@ msgstr ""
msgid "GitLabPages|When enabled, all attempts to visit your website through HTTP are automatically redirected to HTTPS using a response with status code 301. Requires a valid certificate for all domains. %{docs_link_start}Learn more.%{link_end}"
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. %{docs_link_start}Learn more.%{link_end}"
+msgid "GitLabPages|When using Pages under the general domain of a GitLab instance (%{pages_host}), you cannot use HTTPS with subdomains of subdomains. If your namespace or groupname contains a dot, it does not work. This is a limitation of the HTTP Over TLS protocol. HTTP pages work if you don't redirect HTTP to HTTPS. %{docs_link_start}Learn more.%{link_end}"
msgstr ""
msgid "GitLabPages|With GitLab Pages you can host your static website directly from your GitLab repository. %{docs_link_start}Learn more.%{link_end}"
@@ -16625,9 +16879,6 @@ msgstr ""
msgid "Go to find file"
msgstr ""
-msgid "Go to fork"
-msgstr ""
-
msgid "Go to issue boards"
msgstr ""
@@ -16835,9 +17086,6 @@ msgstr ""
msgid "Group Hooks"
msgstr ""
-msgid "Group ID"
-msgstr ""
-
msgid "Group Owner must have signed in with SAML before enabling Group Managed Accounts"
msgstr ""
@@ -16865,9 +17113,6 @@ msgstr ""
msgid "Group by"
msgstr ""
-msgid "Group description"
-msgstr ""
-
msgid "Group description (optional)"
msgstr ""
@@ -16982,7 +17227,7 @@ msgstr ""
msgid "Group: %{name}"
msgstr ""
-msgid "GroupActivityMetrics|Issues opened"
+msgid "GroupActivityMetrics|Issues created"
msgstr ""
msgid "GroupActivityMetrics|Last 90 days"
@@ -16991,7 +17236,7 @@ msgstr ""
msgid "GroupActivityMetrics|Members added"
msgstr ""
-msgid "GroupActivityMetrics|Merge Requests opened"
+msgid "GroupActivityMetrics|Merge Requests created"
msgstr ""
msgid "GroupActivityMetrics|Recent activity"
@@ -17282,6 +17527,9 @@ msgstr ""
msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
+msgid "GroupSettings|Choose a group path that does not start with a dash or end with a period. It can also contain alphanumeric characters and underscores."
+msgstr ""
+
msgid "GroupSettings|Compliance frameworks"
msgstr ""
@@ -17315,7 +17563,7 @@ msgstr ""
msgid "GroupSettings|If not specified at the group or instance level, the default is %{default_initial_branch_name}. Does not affect existing repositories."
msgstr ""
-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."
+msgid "GroupSettings|If the parent group's visibility is lower than the group's current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility."
msgstr ""
msgid "GroupSettings|New runners registration token has been generated!"
@@ -17432,7 +17680,10 @@ msgstr ""
msgid "Groups and projects"
msgstr ""
-msgid "Groups and subgroups"
+msgid "Groups are a great way to organize projects and people."
+msgstr ""
+
+msgid "Groups are the best way to manage projects and members."
msgstr ""
msgid "Groups to synchronize"
@@ -17543,13 +17794,16 @@ msgstr ""
msgid "GroupsTree|Are you sure you want to leave the \"%{fullName}\" group?"
msgstr ""
-msgid "GroupsTree|Edit group"
+msgid "GroupsTree|Delete"
+msgstr ""
+
+msgid "GroupsTree|Edit"
msgstr ""
msgid "GroupsTree|Failed to leave the group. Please make sure you are not the only owner."
msgstr ""
-msgid "GroupsTree|Leave this group"
+msgid "GroupsTree|Leave group"
msgstr ""
msgid "GroupsTree|Loading groups"
@@ -17561,9 +17815,57 @@ msgstr ""
msgid "GroupsTree|No groups or projects matched your search"
msgstr ""
+msgid "GroupsTree|Options"
+msgstr ""
+
msgid "GroupsTree|Search by name"
msgstr ""
+msgid "Groups|Avatar will be removed. Are you sure?"
+msgstr ""
+
+msgid "Groups|Changing group URL can have unintended side effects."
+msgstr ""
+
+msgid "Groups|Checking group URL availability..."
+msgstr ""
+
+msgid "Groups|Enter a descriptive name for your group."
+msgstr ""
+
+msgid "Groups|Group ID"
+msgstr ""
+
+msgid "Groups|Group URL"
+msgstr ""
+
+msgid "Groups|Group avatar"
+msgstr ""
+
+msgid "Groups|Group description (optional)"
+msgstr ""
+
+msgid "Groups|Group name"
+msgstr ""
+
+msgid "Groups|Group path is available."
+msgstr ""
+
+msgid "Groups|Group path is unavailable. Path has been replaced with a suggested available path."
+msgstr ""
+
+msgid "Groups|Learn more"
+msgstr ""
+
+msgid "Groups|Must start with letter, digit, emoji, or underscore. Can also contain periods, dashes, spaces, and parentheses."
+msgstr ""
+
+msgid "Groups|Remove avatar"
+msgstr ""
+
+msgid "Groups|Save changes"
+msgstr ""
+
msgid "Guideline"
msgstr ""
@@ -17573,6 +17875,9 @@ msgstr ""
msgid "HAR file path or URL"
msgstr ""
+msgid "HTTP Archive (HAR)"
+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 ""
@@ -17973,6 +18278,9 @@ msgstr ""
msgid "INFO: Your SSH key is expiring soon. Please generate a new key."
msgstr ""
+msgid "IP"
+msgstr ""
+
msgid "IP Address"
msgstr ""
@@ -18009,6 +18317,9 @@ msgstr ""
msgid "IdentityVerification|Verify your identity"
msgstr ""
+msgid "IdentityVerification|You can always verify your account at a later time to create a group."
+msgstr ""
+
msgid "If any indexed field exceeds this limit, it is truncated to this number of characters. The rest of the content is neither indexed nor searchable. This does not apply to repository and wiki indexing. For unlimited characters, set this to 0."
msgstr ""
@@ -18066,6 +18377,9 @@ msgstr ""
msgid "If you add %{codeStart}needs%{codeEnd} to jobs in your pipeline you'll be able to view the %{codeStart}needs%{codeEnd} relationships between jobs in this tab as a %{linkStart}Directed Acyclic Graph (DAG)%{linkEnd}."
msgstr ""
+msgid "If you are added to a project, it will be displayed here."
+msgstr ""
+
msgid "If you did not initiate these sign-in attempts, please reach out to your administrator or enable two-factor authentication (2FA) on your account."
msgstr ""
@@ -18372,12 +18686,24 @@ msgstr ""
msgid "InProductMarketing|3 ways to dive into GitLab CI/CD"
msgstr ""
+msgid "InProductMarketing|A single application eliminates complex integrations, data chokepoints, and toolchain maintenance, resulting in greater productivity and lower cost."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features, build more efficiently, strengthen security and compliance."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features."
+msgstr ""
+
msgid "InProductMarketing|Actually, GitLab makes the team work (better)"
msgstr ""
msgid "InProductMarketing|And finally %{deploy_link} a Python application."
msgstr ""
+msgid "InProductMarketing|And many more..."
+msgstr ""
+
msgid "InProductMarketing|Are your runners ready?"
msgstr ""
@@ -18396,15 +18722,33 @@ msgstr ""
msgid "InProductMarketing|Blog"
msgstr ""
+msgid "InProductMarketing|Break down silos to coordinate seamlessly across development, operations, and security with a consistent experience across the development lifecycle."
+msgstr ""
+
+msgid "InProductMarketing|Burn up/down charts"
+msgstr ""
+
msgid "InProductMarketing|By enabling code owners and required merge approvals the right person will review the right MR. This is a win-win: cleaner code and a more efficient review process."
msgstr ""
msgid "InProductMarketing|Click on the number below that corresponds with your answer — 1 being very difficult, 5 being very easy."
msgstr ""
+msgid "InProductMarketing|Code owners"
+msgstr ""
+
msgid "InProductMarketing|Code owners and required merge approvals are part of the paid tiers of GitLab. You can start a free 30-day trial of GitLab Ultimate and enable these features in less than 5 minutes with no credit card required."
msgstr ""
+msgid "InProductMarketing|Code review analytics"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration across stages in GitLab"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration made easy"
+msgstr ""
+
msgid "InProductMarketing|Create a custom CI runner with just a few clicks"
msgstr ""
@@ -18414,12 +18758,21 @@ msgstr ""
msgid "InProductMarketing|Create a project in GitLab in 5 minutes"
msgstr ""
+msgid "InProductMarketing|Create well-defined workflows by using scoped labels on issues, merge requests, and epics. Labels with the same scope cannot be used together, which prevents conflicts."
+msgstr ""
+
msgid "InProductMarketing|Create your first project!"
msgstr ""
+msgid "InProductMarketing|Define who owns specific files or directories, so the right reviewers are suggested when a merge request introduces changes to those files."
+msgstr ""
+
msgid "InProductMarketing|Deliver Better Products Faster"
msgstr ""
+msgid "InProductMarketing|Dependency scanning"
+msgstr ""
+
msgid "InProductMarketing|Did you know teams that use GitLab are far more efficient?"
msgstr ""
@@ -18429,15 +18782,27 @@ msgstr ""
msgid "InProductMarketing|Dig in and create a project and a repo"
msgstr ""
+msgid "InProductMarketing|Discover Premium & Ultimate"
+msgstr ""
+
+msgid "InProductMarketing|Discover Premium & Ultimate."
+msgstr ""
+
msgid "InProductMarketing|Do you have a minute?"
msgstr ""
msgid "InProductMarketing|Do you have a teammate who would be perfect for this task?"
msgstr ""
+msgid "InProductMarketing|Dynamic application security testing"
+msgstr ""
+
msgid "InProductMarketing|Easy"
msgstr ""
+msgid "InProductMarketing|Epics"
+msgstr ""
+
msgid "InProductMarketing|Expand your DevOps journey with a free GitLab trial"
msgstr ""
@@ -18459,9 +18824,15 @@ msgstr ""
msgid "InProductMarketing|Feel the need for speed?"
msgstr ""
+msgid "InProductMarketing|Find and fix bottlenecks in your code review process by understanding how long open merge requests have been in review."
+msgstr ""
+
msgid "InProductMarketing|Find out how your teams are really doing"
msgstr ""
+msgid "InProductMarketing|Find out if your external libraries are safe. Run dependency scanning jobs that check for known vulnerabilities in your external libraries."
+msgstr ""
+
msgid "InProductMarketing|Follow our steps"
msgstr ""
@@ -18498,6 +18869,9 @@ msgstr ""
msgid "InProductMarketing|GitLab is better with teammates to help out!"
msgstr ""
+msgid "InProductMarketing|GitLab is infrastructure agnostic (supporting GCP, AWS, Azure, OpenShift, VMWare, On Prem, Bare Metal, and more), offering a consistent workflow experience – irrespective of the environment."
+msgstr ""
+
msgid "InProductMarketing|GitLab provides static application security testing (SAST), dynamic application security testing (DAST), container scanning, and dependency scanning to help you deliver secure applications along with license compliance."
msgstr ""
@@ -18588,21 +18962,36 @@ msgstr ""
msgid "InProductMarketing|It's also possible to simply %{external_repo_link} in order to take advantage of GitLab's CI/CD."
msgstr ""
+msgid "InProductMarketing|Keep your code quality high by defining who should approve merge requests and how many approvals are required."
+msgstr ""
+
msgid "InProductMarketing|Launch GitLab CI/CD in 20 minutes or less"
msgstr ""
+msgid "InProductMarketing|Lower cost of development"
+msgstr ""
+
+msgid "InProductMarketing|Make it easier to collaborate on high-level ideas by grouping related issues in an epic."
+msgstr ""
+
msgid "InProductMarketing|Making the switch? It's easier than you think to import your projects into GitLab. Move %{github_link}, or import something %{bitbucket_link}."
msgstr ""
msgid "InProductMarketing|Master the art of importing!"
msgstr ""
+msgid "InProductMarketing|Merge request approval rule"
+msgstr ""
+
msgid "InProductMarketing|Move on to easily creating a Pages website %{ci_template_link}"
msgstr ""
msgid "InProductMarketing|Multiple owners, confusing workstreams? We've got you covered"
msgstr ""
+msgid "InProductMarketing|Multiple required approvers"
+msgstr ""
+
msgid "InProductMarketing|Need an alternative to importing?"
msgstr ""
@@ -18615,18 +19004,33 @@ msgstr ""
msgid "InProductMarketing|Our tool brings all the things together"
msgstr ""
+msgid "InProductMarketing|Protect your web application by using DAST to examine for vulnerabilities in deployed environments."
+msgstr ""
+
msgid "InProductMarketing|Rapid development, simplified"
msgstr ""
msgid "InProductMarketing|Reduce Security & Compliance Risk"
msgstr ""
+msgid "InProductMarketing|Require multiple approvers on a merge request, so you know it's in good shape before it's merged."
+msgstr ""
+
+msgid "InProductMarketing|Roadmaps"
+msgstr ""
+
+msgid "InProductMarketing|Scoped labels"
+msgstr ""
+
msgid "InProductMarketing|Security that's integrated into your development lifecycle"
msgstr ""
msgid "InProductMarketing|Sometimes you're not ready to make a full transition to a new tool. If you're not ready to fully commit, %{mirroring_link} gives you a safe way to try out GitLab in parallel with your current tool."
msgstr ""
+msgid "InProductMarketing|Speed. Efficiency. Trust."
+msgstr ""
+
msgid "InProductMarketing|Spin up an autoscaling runner in GitLab"
msgstr ""
@@ -18636,6 +19040,9 @@ msgstr ""
msgid "InProductMarketing|Start a Self-Managed trial"
msgstr ""
+msgid "InProductMarketing|Start a free trial"
+msgstr ""
+
msgid "InProductMarketing|Start a free trial of GitLab Ultimate – no credit card required"
msgstr ""
@@ -18702,6 +19109,9 @@ msgstr ""
msgid "InProductMarketing|To understand and get the most out of GitLab, start at the beginning and %{project_link}. In GitLab, repositories are part of a project, so after you've created your project you can go ahead and %{repo_link}."
msgstr ""
+msgid "InProductMarketing|Track completed issues in a chart, so you can see how a milestone is progressing at a glance."
+msgstr ""
+
msgid "InProductMarketing|Try GitLab Ultimate for free"
msgstr ""
@@ -18738,6 +19148,9 @@ msgstr ""
msgid "InProductMarketing|Very easy"
msgstr ""
+msgid "InProductMarketing|Visualize your epics and milestones in a timeline."
+msgstr ""
+
msgid "InProductMarketing|Want to host GitLab on your servers?"
msgstr ""
@@ -18759,6 +19172,9 @@ msgstr ""
msgid "InProductMarketing|YouTube"
msgstr ""
+msgid "InProductMarketing|Your software, deployed your way"
+msgstr ""
+
msgid "InProductMarketing|Your teams can be more efficient"
msgstr ""
@@ -18879,9 +19295,18 @@ msgstr ""
msgid "IncidentManagement|No incidents to display."
msgstr ""
+msgid "IncidentManagement|None"
+msgstr ""
+
msgid "IncidentManagement|Open"
msgstr ""
+msgid "IncidentManagement|Page your team with escalation policies"
+msgstr ""
+
+msgid "IncidentManagement|Paged"
+msgstr ""
+
msgid "IncidentManagement|Published"
msgstr ""
@@ -18891,6 +19316,9 @@ msgstr ""
msgid "IncidentManagement|Severity"
msgstr ""
+msgid "IncidentManagement|Status"
+msgstr ""
+
msgid "IncidentManagement|There are no closed incidents"
msgstr ""
@@ -18909,6 +19337,9 @@ msgstr ""
msgid "IncidentManagement|Unpublished"
msgstr ""
+msgid "IncidentManagement|Use escalation policies to automatically page your team when incidents are created."
+msgstr ""
+
msgid "IncidentSettings|Activate \"time to SLA\" countdown timer"
msgstr ""
@@ -18954,7 +19385,10 @@ msgstr ""
msgid "Incidents"
msgstr ""
-msgid "Incidents|Add a URL"
+msgid "Incidents|Add image details"
+msgstr ""
+
+msgid "Incidents|Add text or a link to display with your image. If you don't add either, the file name displays instead."
msgstr ""
msgid "Incidents|Drop or %{linkStart}upload%{linkEnd} a metric screenshot to attach it to the incident"
@@ -18969,10 +19403,10 @@ msgstr ""
msgid "Incidents|There was an issue loading metric images."
msgstr ""
-msgid "Incidents|There was an issue uploading your image."
+msgid "Incidents|There was an issue updating your image."
msgstr ""
-msgid "Incidents|You can optionally add a URL to link users to the original graph."
+msgid "Incidents|There was an issue uploading your image."
msgstr ""
msgid "Incident|Alert details"
@@ -18981,9 +19415,18 @@ msgstr ""
msgid "Incident|Are you sure you wish to delete this image?"
msgstr ""
+msgid "Incident|Delete image"
+msgstr ""
+
msgid "Incident|Deleting %{filename}"
msgstr ""
+msgid "Incident|Edit image text or link"
+msgstr ""
+
+msgid "Incident|Editing %{filename}"
+msgstr ""
+
msgid "Incident|Metrics"
msgstr ""
@@ -19253,12 +19696,18 @@ msgstr ""
msgid "Integrations|Branches for which notifications are to be sent"
msgstr ""
+msgid "Integrations|Clear if using a self-signed certificate."
+msgstr ""
+
msgid "Integrations|Comment detail:"
msgstr ""
msgid "Integrations|Comment settings:"
msgstr ""
+msgid "Integrations|Connection details"
+msgstr ""
+
msgid "Integrations|Connection failed. Please check your settings."
msgstr ""
@@ -19283,6 +19732,9 @@ msgstr ""
msgid "Integrations|Enable GitLab.com slash commands in a Slack workspace."
msgstr ""
+msgid "Integrations|Enable SSL verification"
+msgstr ""
+
msgid "Integrations|Enable comments"
msgstr ""
@@ -19361,6 +19813,9 @@ msgstr ""
msgid "Integrations|Return to GitLab for Jira"
msgstr ""
+msgid "Integrations|SSL verification"
+msgstr ""
+
msgid "Integrations|Save settings?"
msgstr ""
@@ -19406,9 +19861,6 @@ msgstr ""
msgid "Integrations|Use default settings"
msgstr ""
-msgid "Integrations|When you mention a Jira issue in a commit or merge request, GitLab creates a remote link and comment (if enabled)."
-msgstr ""
-
msgid "Integrations|You can now close this window and return to the GitLab for Jira application."
msgstr ""
@@ -19433,9 +19885,6 @@ msgstr ""
msgid "Integrations|can't exceed %{recipients_limit}"
msgstr ""
-msgid "Interactive developer security education."
-msgstr ""
-
msgid "Interactive mode"
msgstr ""
@@ -19925,6 +20374,9 @@ msgstr ""
msgid "IssueAnalytics|Assignees"
msgstr ""
+msgid "IssueAnalytics|Created by"
+msgstr ""
+
msgid "IssueAnalytics|Due date"
msgstr ""
@@ -19937,9 +20389,6 @@ msgstr ""
msgid "IssueAnalytics|Milestone"
msgstr ""
-msgid "IssueAnalytics|Opened by"
-msgstr ""
-
msgid "IssueAnalytics|Status"
msgstr ""
@@ -20063,10 +20512,10 @@ msgstr ""
msgid "IssuesAnalytics|Avg/Month:"
msgstr ""
-msgid "IssuesAnalytics|Issues opened"
+msgid "IssuesAnalytics|Issues created"
msgstr ""
-msgid "IssuesAnalytics|Issues opened per month"
+msgid "IssuesAnalytics|Issues created per month"
msgstr ""
msgid "IssuesAnalytics|Last 12 months"
@@ -20093,6 +20542,9 @@ msgstr ""
msgid "It looks like you have some draft commits in this branch."
msgstr ""
+msgid "It looks like you're attempting to activate your subscription. Use %{a_start}the Subscription page%{a_end} instead."
+msgstr ""
+
msgid "It may be several days before you see feature usage data."
msgstr ""
@@ -20321,6 +20773,9 @@ msgstr ""
msgid "JiraConnect|You can now close this window and return to Jira."
msgstr ""
+msgid "JiraConnect|You don't have permission to create branches for this project. Select a different project or contact the project owner for access. %{linkStart}Learn more.%{linkEnd}"
+msgstr ""
+
msgid "JiraRequest|A connection error occurred while connecting to Jira. Try your request again."
msgstr ""
@@ -20369,13 +20824,13 @@ msgstr ""
msgid "JiraService|Define the type of Jira issue to create from a vulnerability."
msgstr ""
-msgid "JiraService|Displaying Jira issues while leaving the GitLab issue functionality enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
+msgid "JiraService|Displaying Jira issues while leaving GitLab issues also enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
msgstr ""
-msgid "JiraService|Enable Jira issues"
+msgid "JiraService|Enable Jira issue creation from vulnerabilities"
msgstr ""
-msgid "JiraService|Enable Jira issues creation from vulnerabilities"
+msgid "JiraService|Enable Jira issues"
msgstr ""
msgid "JiraService|Enable Jira transitions"
@@ -20492,16 +20947,19 @@ msgstr ""
msgid "JiraService|View Jira issues in GitLab"
msgstr ""
-msgid "JiraService|Warning: All GitLab users that have access to this GitLab project are able to view all issues from the Jira project specified below."
+msgid "JiraService|Warning: All GitLab users with access to this GitLab project can view all issues from the Jira project you select."
msgstr ""
msgid "JiraService|Web URL"
msgstr ""
-msgid "JiraService|Work on Jira issues without leaving GitLab. Adds a Jira menu to access your list of Jira issues and view any issue as read-only."
+msgid "JiraService|When a Jira issue is mentioned in a commit or merge request, a remote link and comment (if enabled) will be created."
+msgstr ""
+
+msgid "JiraService|Work on Jira issues without leaving GitLab. Add a Jira menu to access a read-only list of your Jira issues."
msgstr ""
-msgid "JiraService|You need to configure Jira before enabling this integration. For more details, read the %{jira_doc_link_start}Jira integration documentation%{link_end}."
+msgid "JiraService|You must configure Jira before enabling this integration. %{jira_doc_link_start}Learn more.%{link_end}"
msgstr ""
msgid "Job"
@@ -20513,9 +20971,6 @@ msgstr ""
msgid "Job Failed #%{build_id}"
msgstr ""
-msgid "Job ID"
-msgstr ""
-
msgid "Job artifact"
msgstr ""
@@ -20582,9 +21037,27 @@ msgstr ""
msgid "Jobs|You're about to retry a job that failed because it attempted to deploy code that is older than the latest deployment. Retrying this job could result in overwriting the environment with the older source code."
msgstr ""
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source} into %{target}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{ref}"
+msgstr ""
+
+msgid "Job|Are you sure you want to erase this job log and artifacts?"
+msgstr ""
+
msgid "Job|Browse"
msgstr ""
+msgid "Job|Cancel"
+msgstr ""
+
msgid "Job|Complete Raw"
msgstr ""
@@ -20594,6 +21067,9 @@ msgstr ""
msgid "Job|Erase job log and artifacts"
msgstr ""
+msgid "Job|Finished at"
+msgstr ""
+
msgid "Job|Job artifacts"
msgstr ""
@@ -20606,7 +21082,7 @@ msgstr ""
msgid "Job|Keep"
msgstr ""
-msgid "Job|Pipeline"
+msgid "Job|Retry"
msgstr ""
msgid "Job|Scroll to bottom"
@@ -20618,6 +21094,9 @@ msgstr ""
msgid "Job|Show complete raw"
msgstr ""
+msgid "Job|Status"
+msgstr ""
+
msgid "Job|The artifacts were removed"
msgstr ""
@@ -20645,21 +21124,12 @@ msgstr ""
msgid "Job|delayed"
msgstr ""
-msgid "Job|for"
-msgstr ""
-
-msgid "Job|into"
-msgstr ""
-
msgid "Job|manual"
msgstr ""
msgid "Job|triggered"
msgstr ""
-msgid "Job|with"
-msgstr ""
-
msgid "Join Zoom meeting"
msgstr ""
@@ -20762,9 +21232,6 @@ msgstr ""
msgid "Ki"
msgstr ""
-msgid "Kontra"
-msgstr ""
-
msgid "Kroki"
msgstr ""
@@ -21088,6 +21555,9 @@ msgstr ""
msgid "Learn more about Auto DevOps"
msgstr ""
+msgid "Learn more about GitLab"
+msgstr ""
+
msgid "Learn more about Needs relationships"
msgstr ""
@@ -21415,9 +21885,18 @@ msgstr ""
msgid "Licenses|Displays licenses detected in the project, based on the %{linkStart}latest successful%{linkEnd} scan"
msgstr ""
+msgid "Licenses|Drag your license file here or %{linkStart}click to upload%{linkEnd}."
+msgstr ""
+
+msgid "Licenses|Drop your license file to start the upload."
+msgstr ""
+
msgid "Licenses|Error fetching the license list. Please check your network connection and try again."
msgstr ""
+msgid "Licenses|Error: You are trying to upload something other than a file"
+msgstr ""
+
msgid "Licenses|License Compliance"
msgstr ""
@@ -21436,6 +21915,9 @@ msgstr ""
msgid "Licenses|Specified policies in this project"
msgstr ""
+msgid "Licenses|The file could not be uploaded."
+msgstr ""
+
msgid "Licenses|The license list details information about the licenses used within your project."
msgstr ""
@@ -21469,11 +21951,6 @@ msgstr ""
msgid "Limit the size of Sidekiq jobs stored in Redis."
msgstr ""
-msgid "Limited to showing %d event at most"
-msgid_plural "Limited to showing %d events at most"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Limiting mode"
msgstr ""
@@ -21483,6 +21960,9 @@ msgstr ""
msgid "Link"
msgstr ""
+msgid "Link (optional)"
+msgstr ""
+
msgid "Link Prometheus monitoring to GitLab."
msgstr ""
@@ -21519,6 +21999,9 @@ msgstr ""
msgid "Linked emails (%{email_count})"
msgstr ""
+msgid "Linked epics"
+msgstr ""
+
msgid "Linked issues"
msgstr ""
@@ -21546,6 +22029,15 @@ msgstr ""
msgid "List of all merge commits"
msgstr ""
+msgid "List of environments for this project"
+msgstr ""
+
+msgid "List of suitable GCP locations"
+msgstr ""
+
+msgid "List of users allowed to exceed the rate limit."
+msgstr ""
+
msgid "List options"
msgstr ""
@@ -21765,6 +22257,9 @@ msgstr ""
msgid "Maintenance mode"
msgstr ""
+msgid "Make adjustments to how your GitLab instance is set up."
+msgstr ""
+
msgid "Make and review changes in the browser with the Web IDE"
msgstr ""
@@ -21909,6 +22404,12 @@ msgstr ""
msgid "MarkdownEditor|Add italic text (%{modifier_key}I)"
msgstr ""
+msgid "MarkdownEditor|Add strikethrough text (%{modifierKey}⇧X)"
+msgstr ""
+
+msgid "MarkdownEditor|Add strikethrough text (%{modifier_key}⇧X)"
+msgstr ""
+
msgid "Marked For Deletion At - %{deletion_time}"
msgstr ""
@@ -22170,6 +22671,9 @@ msgstr ""
msgid "Maximum push size (MB)"
msgstr ""
+msgid "Maximum requests per 10 minutes per user"
+msgstr ""
+
msgid "Maximum requests per minute"
msgstr ""
@@ -22260,6 +22764,19 @@ msgstr ""
msgid "Members of a group may only view projects they have permission to access"
msgstr ""
+msgid "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seat in use and will be billed for the overage."
+msgid_plural "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seats in use and will be billed for the overage."
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "MembersOverage|You are about to incur additional charges"
+msgstr ""
+
+msgid "MembersOverage|Your subscription includes %d seat."
+msgid_plural "MembersOverage|Your subscription includes %d seats."
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Membership"
msgstr ""
@@ -22464,9 +22981,6 @@ msgstr ""
msgid "Merge request not merged"
msgstr ""
-msgid "Merge request pipelines 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 merge request pipelines."
-msgstr ""
-
msgid "Merge request reports"
msgstr ""
@@ -22563,13 +23077,13 @@ msgstr ""
msgid "MergeRequests|Create issue to resolve thread"
msgstr ""
-msgid "MergeRequests|Failed to squash. Should be done manually."
+msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Saving the comment failed"
+msgid "MergeRequests|Squashing failed: Squash the commits locally, resolve any conflicts, then push the branch."
msgstr ""
-msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
+msgid "MergeRequests|Squashing not allowed: This project doesn't allow you to squash commits when merging."
msgstr ""
msgid "MergeRequests|Thread stays resolved"
@@ -23410,6 +23924,18 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "MrList|Assigned to %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from assignee %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from reviewer %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Review requested from %{name}, go to their profile."
+msgstr ""
+
msgid "Multi-project"
msgstr ""
@@ -23443,7 +23969,7 @@ msgstr ""
msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "My Awesome Group"
+msgid "My awesome group"
msgstr ""
msgid "My company or team"
@@ -24065,9 +24591,6 @@ msgstr ""
msgid "No available branches"
msgstr ""
-msgid "No available groups to fork the project."
-msgstr ""
-
msgid "No branches found"
msgstr ""
@@ -24278,6 +24801,9 @@ msgstr ""
msgid "No ref selected"
msgstr ""
+msgid "No regions configured"
+msgstr ""
+
msgid "No related merge requests found."
msgstr ""
@@ -25082,6 +25608,9 @@ msgstr ""
msgid "Only reCAPTCHA v2 is supported:"
msgstr ""
+msgid "Only required if not using role instance credentials."
+msgstr ""
+
msgid "Only use lowercase letters, numbers, and underscores."
msgstr ""
@@ -25106,9 +25635,6 @@ msgstr ""
msgid "Open a CLI and connect to the cluster you want to install the agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
-msgid "Open epics"
-msgstr ""
-
msgid "Open errors"
msgstr ""
@@ -25148,7 +25674,7 @@ msgstr ""
msgid "Opened issues"
msgstr ""
-msgid "OpenedNDaysAgo|Opened"
+msgid "OpenedNDaysAgo|Created"
msgstr ""
msgid "Opens in a new window"
@@ -25193,9 +25719,6 @@ msgstr ""
msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
-msgid "Optional."
-msgstr ""
-
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
msgstr ""
@@ -25984,6 +26507,9 @@ msgstr ""
msgid "PerformanceBar|Memory"
msgstr ""
+msgid "PerformanceBar|Memory report"
+msgstr ""
+
msgid "PerformanceBar|Redis calls"
msgstr ""
@@ -26017,18 +26543,12 @@ msgstr ""
msgid "PerformanceBar|wall"
msgstr ""
-msgid "Performs a rebase but skips triggering a new pipeline"
-msgstr ""
-
msgid "Period in seconds"
msgstr ""
msgid "Permalink"
msgstr ""
-msgid "Permanently delete project"
-msgstr ""
-
msgid "Permanently remove group"
msgstr ""
@@ -26299,6 +26819,51 @@ msgstr ""
msgid "PipelineStatusTooltip|Pipeline: %{ci_status}"
msgstr ""
+msgid "PipelineWizardDefaultCommitMessage|Add %{filename}"
+msgstr ""
+
+msgid "PipelineWizardDefaultCommitMessage|Update %{filename}"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|At least one entry is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This field is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This value is not valid"
+msgstr ""
+
+msgid "PipelineWizardListWidget|add another step"
+msgstr ""
+
+msgid "PipelineWizardListWidget|remove step"
+msgstr ""
+
+msgid "PipelineWizard|Commit"
+msgstr ""
+
+msgid "PipelineWizard|Commit Message"
+msgstr ""
+
+msgid "PipelineWizard|Commit changes to your file"
+msgstr ""
+
+msgid "PipelineWizard|Commit file to Branch"
+msgstr ""
+
+msgid "PipelineWizard|Commit your new file"
+msgstr ""
+
+msgid "PipelineWizard|The file has been committed."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem committing the changes."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem while checking whether your file already exists in the specified branch."
+msgstr ""
+
msgid "Pipelines"
msgstr ""
@@ -26413,7 +26978,7 @@ msgstr ""
msgid "Pipelines|Project cache successfully reset."
msgstr ""
-msgid "Pipelines|Revoke"
+msgid "Pipelines|Revoke trigger"
msgstr ""
msgid "Pipelines|Something went wrong while cleaning runners cache."
@@ -26458,6 +27023,12 @@ msgstr ""
msgid "Pipelines|This is a child pipeline within the parent pipeline"
msgstr ""
+msgid "Pipelines|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipelines|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipelines|This pipeline will run code originating from a forked project merge request. This means that the code can potentially have security considerations like exposing CI variables."
msgstr ""
@@ -26500,9 +27071,6 @@ msgstr ""
msgid "Pipelines|Your changes have been successfully committed. Now redirecting to the new merge request page."
msgstr ""
-msgid "Pipelines|detached"
-msgstr ""
-
msgid "Pipelines|error"
msgstr ""
@@ -26512,10 +27080,13 @@ msgstr ""
msgid "Pipelines|latest"
msgstr ""
-msgid "Pipelines|stuck"
+msgid "Pipelines|merge request"
msgstr ""
-msgid "Pipelines|train"
+msgid "Pipelines|merge train"
+msgstr ""
+
+msgid "Pipelines|stuck"
msgstr ""
msgid "Pipelines|yaml invalid"
@@ -26647,6 +27218,12 @@ msgstr ""
msgid "Pipeline|This change will not change the overall test coverage if merged."
msgstr ""
+msgid "Pipeline|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipeline|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipeline|Trigger author"
msgstr ""
@@ -26671,6 +27248,12 @@ msgstr ""
msgid "Pipeline|for"
msgstr ""
+msgid "Pipeline|merge request"
+msgstr ""
+
+msgid "Pipeline|merge train"
+msgstr ""
+
msgid "Pipeline|on"
msgstr ""
@@ -26809,9 +27392,6 @@ msgstr ""
msgid "Please enter a valid time interval"
msgstr ""
-msgid "Please enter or upload a valid license."
-msgstr ""
-
msgid "Please enter your current password."
msgstr ""
@@ -26920,9 +27500,6 @@ msgstr ""
msgid "Please type %{phrase_code} to proceed or close this modal to cancel."
msgstr ""
-msgid "Please type the following to confirm:"
-msgstr ""
-
msgid "Please use this form to report to the admin users who create spam issues, comments or behave inappropriately."
msgstr ""
@@ -26950,12 +27527,27 @@ msgstr ""
msgid "Policies"
msgstr ""
+msgid "Policy '%{escalation_policy_name}' does not exist."
+msgstr ""
+
msgid "Policy management project does have any policies in %{policy_path}"
msgstr ""
msgid "Policy project doesn't exist"
msgstr ""
+msgid "PolicyRuleMultiSelect|%{firstLabel} +%{numberOfAdditionalLabels} more"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|All %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select all"
+msgstr ""
+
msgid "Polling interval multiplier"
msgstr ""
@@ -27184,6 +27776,9 @@ msgstr ""
msgid "Private projects can be created in your personal namespace with:"
msgstr ""
+msgid "Problem with %{name} command: %{message}."
+msgstr ""
+
msgid "Proceed"
msgstr ""
@@ -27658,6 +28253,9 @@ msgstr ""
msgid "Progress"
msgstr ""
+msgid "Progress tracking"
+msgstr ""
+
msgid "Project"
msgstr ""
@@ -27889,6 +28487,9 @@ msgstr ""
msgid "ProjectQualitySummary|Failure"
msgstr ""
+msgid "ProjectQualitySummary|Get insight into the overall percentage of tests in your project that succeed, fail and are skipped."
+msgstr ""
+
msgid "ProjectQualitySummary|Latest pipeline results"
msgstr ""
@@ -27907,6 +28508,12 @@ msgstr ""
msgid "ProjectQualitySummary|See project Code Coverage Statistics"
msgstr ""
+msgid "ProjectQualitySummary|Set up test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|Set up test runs (opens in a new tab)"
+msgstr ""
+
msgid "ProjectQualitySummary|Skipped"
msgstr ""
@@ -28183,13 +28790,19 @@ msgstr ""
msgid "ProjectSettings|LFS objects from this repository are available to forks. %{linkStart}How do I remove them?%{linkEnd}"
msgstr ""
+msgid "ProjectSettings|Learn about commit history."
+msgstr ""
+
+msgid "ProjectSettings|Leave empty to use default template."
+msgstr ""
+
msgid "ProjectSettings|Manage who can see the project in the public access directory."
msgstr ""
msgid "ProjectSettings|Manages large files such as audio, video, and graphics files."
msgstr ""
-msgid "ProjectSettings|Maximum 500 characters."
+msgid "ProjectSettings|Maximum %{maxLength} characters."
msgstr ""
msgid "ProjectSettings|Merge checks"
@@ -28330,6 +28943,9 @@ msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
msgstr ""
+msgid "ProjectSettings|The default template will be applied on save."
+msgstr ""
+
msgid "ProjectSettings|These checks must pass before merge requests can be merged."
msgstr ""
@@ -28384,6 +29000,9 @@ msgstr ""
msgid "ProjectSettings|What are badges?"
msgstr ""
+msgid "ProjectSettings|What are merge trains?"
+msgstr ""
+
msgid "ProjectSettings|When merge request pipelines are enabled in the CI/CD configuration file, pipelines validate the combined results of the source and target branches. %{link_start}How to configure merge request pipelines?%{link_end}"
msgstr ""
@@ -28501,6 +29120,9 @@ msgstr ""
msgid "Projects are organized into groups"
msgstr ""
+msgid "Projects are where you store your code, access issues, wiki and other features of GitLab."
+msgstr ""
+
msgid "Projects contributed to"
msgstr ""
@@ -28516,12 +29138,6 @@ msgstr ""
msgid "Projects to index"
msgstr ""
-msgid "Projects will be permanently deleted after a %{waiting_period}-day waiting period."
-msgstr ""
-
-msgid "Projects will be permanently deleted immediately."
-msgstr ""
-
msgid "Projects with critical vulnerabilities"
msgstr ""
@@ -28606,6 +29222,9 @@ msgstr ""
msgid "ProjectsNew|Import project"
msgstr ""
+msgid "ProjectsNew|Include a Getting Started README"
+msgstr ""
+
msgid "ProjectsNew|Initialize repository with a README"
msgstr ""
@@ -28621,6 +29240,9 @@ msgstr ""
msgid "ProjectsNew|Project description %{tag_start}(optional)%{tag_end}"
msgstr ""
+msgid "ProjectsNew|Recommended if you're new to GitLab"
+msgstr ""
+
msgid "ProjectsNew|Run CI/CD for external repository"
msgstr ""
@@ -29038,6 +29660,9 @@ msgstr ""
msgid "ProtectedBranch|Unprotect"
msgstr ""
+msgid "ProtectedBranch|Unprotect branch"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
@@ -29065,6 +29690,9 @@ msgstr ""
msgid "ProtectedEnvironment|Protected Environment (%{protected_environments_count})"
msgstr ""
+msgid "ProtectedEnvironment|Required approvals"
+msgstr ""
+
msgid "ProtectedEnvironment|Select an environment"
msgstr ""
@@ -29086,10 +29714,13 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|Unprotect tag"
+msgstr ""
+
msgid "ProtectedTags|default"
msgstr ""
-msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
+msgid "ProtectedTag|By default, protected tags restrict who can modify the tag."
msgstr ""
msgid "ProtectedTag|Learn more."
@@ -29152,6 +29783,9 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Public projects are an easy way to allow everyone to have read-only access."
+msgstr ""
+
msgid "Publish to status page"
msgstr ""
@@ -29308,9 +29942,6 @@ msgstr ""
msgid "QualitySummary|Project quality"
msgstr ""
-msgid "Quarters"
-msgstr ""
-
msgid "Query"
msgstr ""
@@ -29395,6 +30026,9 @@ msgstr ""
msgid "Read more about project permissions %{help_link_open}here%{help_link_close}"
msgstr ""
+msgid "Read more about related epics"
+msgstr ""
+
msgid "Read more about related issues"
msgstr ""
@@ -29425,10 +30059,7 @@ msgstr ""
msgid "Rebase source branch on the target branch."
msgstr ""
-msgid "Rebase without CI"
-msgstr ""
-
-msgid "Rebases and triggers a pipeline"
+msgid "Rebase without pipeline"
msgstr ""
msgid "Recaptcha verified?"
@@ -29479,9 +30110,6 @@ msgstr ""
msgid "Reconfigure"
msgstr ""
-msgid "Recovering projects"
-msgstr ""
-
msgid "Recovery Codes"
msgstr ""
@@ -29541,6 +30169,12 @@ msgstr ""
msgid "Regex pattern"
msgstr ""
+msgid "Region"
+msgstr ""
+
+msgid "Regions"
+msgstr ""
+
msgid "Register"
msgstr ""
@@ -29771,9 +30405,6 @@ msgstr ""
msgid "Remove all or specific reviewer(s)"
msgstr ""
-msgid "Remove approver"
-msgstr ""
-
msgid "Remove approvers"
msgstr ""
@@ -29789,6 +30420,9 @@ msgstr ""
msgid "Remove attention request"
msgstr ""
+msgid "Remove attention request(s)"
+msgstr ""
+
msgid "Remove avatar"
msgstr ""
@@ -29927,6 +30561,9 @@ msgstr ""
msgid "Removed an issue from an epic."
msgstr ""
+msgid "Removed attention from %{users_sentence}."
+msgstr ""
+
msgid "Removed attention request from @%{username}"
msgstr ""
@@ -29978,6 +30615,9 @@ msgstr ""
msgid "Removes an issue from an epic."
msgstr ""
+msgid "Removes attention from %{users_sentence}."
+msgstr ""
+
msgid "Removes parent epic %{epic_ref}."
msgstr ""
@@ -30089,6 +30729,9 @@ msgstr ""
msgid "Report abuse to admin"
msgstr ""
+msgid "Report is generating and will be sent to your email address."
+msgstr ""
+
msgid "Reported %{timeAgo} by %{reportedBy}"
msgstr ""
@@ -30378,6 +31021,15 @@ msgstr ""
msgid "Request attention"
msgstr ""
+msgid "Request attention from %{users_sentence}."
+msgstr ""
+
+msgid "Request attention from assignee or reviewer"
+msgstr ""
+
+msgid "Request attention from assignee(s) or reviewer(s)"
+msgstr ""
+
msgid "Request attention to review"
msgstr ""
@@ -30402,6 +31054,9 @@ msgstr ""
msgid "Requested %{time_ago}"
msgstr ""
+msgid "Requested attention from %{users_sentence}."
+msgstr ""
+
msgid "Requested attention from @%{username}"
msgstr ""
@@ -30616,6 +31271,9 @@ msgstr ""
msgid "Restore project"
msgstr ""
+msgid "Restoring projects"
+msgstr ""
+
msgid "Restoring the group will prevent the group, its subgroups and projects from being removed on this date."
msgstr ""
@@ -30646,6 +31304,9 @@ msgstr ""
msgid "Retry"
msgstr ""
+msgid "Retry failed jobs"
+msgstr ""
+
msgid "Retry job"
msgstr ""
@@ -30693,9 +31354,6 @@ msgstr ""
msgid "Review changes"
msgstr ""
-msgid "Review requested from %{name}"
-msgstr ""
-
msgid "Review requests for you"
msgstr ""
@@ -30860,6 +31518,9 @@ msgstr ""
msgid "Runners|Assigned Group"
msgstr ""
+msgid "Runners|Assigned Projects (%{projectCount})"
+msgstr ""
+
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30929,6 +31590,9 @@ msgstr ""
msgid "Runners|Instance"
msgstr ""
+msgid "Runners|Jobs"
+msgstr ""
+
msgid "Runners|Last contact"
msgstr ""
@@ -31022,9 +31686,6 @@ msgstr ""
msgid "Runners|Runner %{name} was deleted"
msgstr ""
-msgid "Runners|Runner ID"
-msgstr ""
-
msgid "Runners|Runner assigned to project."
msgstr ""
@@ -31172,6 +31833,9 @@ msgstr ""
msgid "Runners|stale"
msgstr ""
+msgid "Runner|This runner has not run any jobs."
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -31286,6 +31950,24 @@ msgstr ""
msgid "Saving project."
msgstr ""
+msgid "ScanResultPolicy|%{ifLabelStart}if%{ifLabelEnd} %{scanners} scan in an open merge request targeting the %{branches} branch(es) finds %{vulnerabilitiesAllowed} or more %{severities} vulnerabilities that are %{vulnerabilityStates}"
+msgstr ""
+
+msgid "ScanResultPolicy|%{thenLabelStart}Then%{thenLabelEnd} Require approval from %{approvalsRequired} of the following approvers: %{approvers}"
+msgstr ""
+
+msgid "ScanResultPolicy|add an approver"
+msgstr ""
+
+msgid "ScanResultPolicy|scanners"
+msgstr ""
+
+msgid "ScanResultPolicy|severity levels"
+msgstr ""
+
+msgid "ScanResultPolicy|vulnerability states"
+msgstr ""
+
msgid "Scanner"
msgstr ""
@@ -31418,6 +32100,9 @@ msgstr ""
msgid "Search for a user"
msgstr ""
+msgid "Search for an emoji"
+msgstr ""
+
msgid "Search for projects, issues, etc."
msgstr ""
@@ -31605,18 +32290,12 @@ msgstr ""
msgid "Secret Detection"
msgstr ""
-msgid "Secret access key"
-msgstr ""
-
msgid "Secret token"
msgstr ""
msgid "Secure token that identifies an external storage request."
msgstr ""
-msgid "SecureCodeWarrior"
-msgstr ""
-
msgid "Security"
msgstr ""
@@ -31641,9 +32320,6 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "Security training with guide and learning pathways."
-msgstr ""
-
msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
@@ -31746,7 +32422,7 @@ msgstr ""
msgid "SecurityConfiguration|Manage corpus"
msgstr ""
-msgid "SecurityConfiguration|Manage corpus files used as mutation sources in coverage fuzzing."
+msgid "SecurityConfiguration|Manage corpus files used as seed inputs with coverage-guided fuzzing."
msgstr ""
msgid "SecurityConfiguration|Manage profiles for use by DAST scans."
@@ -31812,15 +32488,15 @@ msgstr ""
msgid "SecurityOrchestration|.yaml preview"
msgstr ""
-msgid "SecurityOrchestration|Action"
-msgstr ""
-
msgid "SecurityOrchestration|Actions"
msgstr ""
msgid "SecurityOrchestration|Add rule"
msgstr ""
+msgid "SecurityOrchestration|After dismissing the alert, the information will never be shown again."
+msgstr ""
+
msgid "SecurityOrchestration|All policies"
msgstr ""
@@ -31836,7 +32512,7 @@ msgstr ""
msgid "SecurityOrchestration|Description"
msgstr ""
-msgid "SecurityOrchestration|Disabled"
+msgid "SecurityOrchestration|Don't show the alert anymore"
msgstr ""
msgid "SecurityOrchestration|Edit policy"
@@ -31845,13 +32521,13 @@ msgstr ""
msgid "SecurityOrchestration|Edit policy project"
msgstr ""
-msgid "SecurityOrchestration|Enabled"
+msgid "SecurityOrchestration|Empty policy name"
msgstr ""
-msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Enabled"
msgstr ""
-msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
msgstr ""
msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
@@ -31860,7 +32536,7 @@ msgstr ""
msgid "SecurityOrchestration|Invalid policy type"
msgstr ""
-msgid "SecurityOrchestration|Latest scan"
+msgid "SecurityOrchestration|Latest scan run against %{agent}"
msgstr ""
msgid "SecurityOrchestration|Network"
@@ -31869,15 +32545,27 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No actions defined - policy will not run."
+msgstr ""
+
+msgid "SecurityOrchestration|No description"
+msgstr ""
+
msgid "SecurityOrchestration|No rules defined - policy will not run."
msgstr ""
+msgid "SecurityOrchestration|Not enabled"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
msgid "SecurityOrchestration|Policies"
msgstr ""
+msgid "SecurityOrchestration|Policy Type"
+msgstr ""
+
msgid "SecurityOrchestration|Policy cannot be enabled for non-existing branches (%{branches})"
msgstr ""
@@ -31902,10 +32590,13 @@ msgstr ""
msgid "SecurityOrchestration|Require %{approvals} %{plural} from %{approvers} if any of the following occur:"
msgstr ""
-msgid "SecurityOrchestration|Rule"
+msgid "SecurityOrchestration|Rules"
msgstr ""
-msgid "SecurityOrchestration|Rules"
+msgid "SecurityOrchestration|Runs %{actions} and %{lastAction} scans"
+msgstr ""
+
+msgid "SecurityOrchestration|Runs a %{action} scan"
msgstr ""
msgid "SecurityOrchestration|Scan Execution"
@@ -31965,6 +32656,9 @@ msgstr ""
msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
+msgid "SecurityOrchestration|This view only shows scan results for the agent %{agent}. You can view scan results for all agents in the %{linkStart}Operational Vulnerabilities tab of the vulnerability report%{linkEnd}."
+msgstr ""
+
msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
@@ -32019,9 +32713,6 @@ msgstr ""
msgid "SecurityOrchestration|users with ids"
msgstr ""
-msgid "SecurityOrchestration|view results"
-msgstr ""
-
msgid "SecurityOrchestration|vulnerabilities"
msgstr ""
@@ -32691,22 +33382,19 @@ 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|In order to start using functions as a service, you must first install Knative on your Kubernetes cluster. %{linkStart}More information%{linkEnd}"
-msgstr ""
-
msgid "Serverless|Learn more about Serverless"
msgstr ""
msgid "Serverless|No functions available"
msgstr ""
-msgid "Serverless|Sign up for First Look"
+msgid "Serverless|Serverless was %{linkStart}deprecated%{linkEnd} in GitLab 14.3."
+msgstr ""
+
+msgid "Serverless|Serverless was %{postLinkStart}deprecated%{postLinkEnd}. But if you opt to use it, you must install Knative in your Kubernetes cluster first. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "Serverless|The deploy job has not finished."
@@ -32718,9 +33406,6 @@ 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 ""
@@ -32736,9 +33421,6 @@ msgstr ""
msgid "Service Account Key"
msgstr ""
-msgid "Service Accounts"
-msgstr ""
-
msgid "Service Accounts keys authorize GitLab to deploy your Google Cloud project"
msgstr ""
@@ -32748,10 +33430,10 @@ msgstr ""
msgid "Service Desk allows people to create issues in your GitLab instance without their own user account. It provides a unique email address for end users to create issues in a project. Replies can be sent either through the GitLab interface or by email. End users only see threads through email."
msgstr ""
-msgid "Service Usage Data"
+msgid "Service account generated successfully"
msgstr ""
-msgid "Service account generated successfully"
+msgid "Service accounts"
msgstr ""
msgid "Service ping is disabled in your configuration file, and cannot be enabled through this form."
@@ -32895,6 +33577,9 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
+msgid "Set the per-user rate limit for getting a user by ID via the API."
+msgstr ""
+
msgid "Set the per-user rate limit for notes created by web or API requests."
msgstr ""
@@ -33074,6 +33759,9 @@ msgstr ""
msgid "Shared runners details"
msgstr ""
+msgid "Shared runners enabled cannot be enabled until a valid credit card is on file"
+msgstr ""
+
msgid "Shared runners help link"
msgstr ""
@@ -33131,6 +33819,9 @@ msgstr ""
msgid "Show all issues."
msgstr ""
+msgid "Show all milestones"
+msgstr ""
+
msgid "Show all test cases."
msgstr ""
@@ -33167,6 +33858,9 @@ msgstr ""
msgid "Show file contents"
msgstr ""
+msgid "Show group milestones"
+msgstr ""
+
msgid "Show labels"
msgstr ""
@@ -33182,6 +33876,12 @@ msgstr ""
msgid "Show open epics"
msgstr ""
+msgid "Show project milestones"
+msgstr ""
+
+msgid "Show sub-group milestones"
+msgstr ""
+
msgid "Show the Closed list"
msgstr ""
@@ -33191,11 +33891,6 @@ msgstr ""
msgid "Show whitespace changes"
msgstr ""
-msgid "Showing %d event"
-msgid_plural "Showing %d events"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Showing %{conflict} between %{sourceBranch} and %{targetBranch}"
msgstr ""
@@ -33255,12 +33950,6 @@ msgstr ""
msgid "Sidebar|None"
msgstr ""
-msgid "Sidebar|Only numeral characters allowed"
-msgstr ""
-
-msgid "Sidebar|Weight"
-msgstr ""
-
msgid "Sidekiq job compression threshold (bytes)"
msgstr ""
@@ -33423,6 +34112,9 @@ msgstr ""
msgid "Slack logo"
msgstr ""
+msgid "SlackIntegration|Are you sure you want to remove this project from the Slack application?"
+msgstr ""
+
msgid "SlackIntegration|GitLab for Slack"
msgstr ""
@@ -33432,6 +34124,9 @@ msgstr ""
msgid "SlackIntegration|Project alias"
msgstr ""
+msgid "SlackIntegration|Remove project"
+msgstr ""
+
msgid "SlackIntegration|Select a GitLab project to link with your Slack workspace."
msgstr ""
@@ -33576,9 +34271,6 @@ msgstr ""
msgid "Something went wrong trying to load issue contacts."
msgstr ""
-msgid "Something went wrong when creating a work item. Please try again"
-msgstr ""
-
msgid "Something went wrong when reordering designs. Please try again"
msgstr ""
@@ -33672,9 +34364,6 @@ msgstr ""
msgid "Something went wrong while inserting your image. Please try again."
msgstr ""
-msgid "Something went wrong while merging this merge request. Please try again."
-msgstr ""
-
msgid "Something went wrong while obtaining the Let's Encrypt certificate."
msgstr ""
@@ -33996,10 +34685,10 @@ 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."
+msgid "SourcegraphAdmin|Learn more."
msgstr ""
-msgid "SourcegraphAdmin|More information"
+msgid "SourcegraphAdmin|Only public projects have code intelligence enabled and communicate with Sourcegraph."
msgstr ""
msgid "SourcegraphAdmin|Save changes"
@@ -34008,7 +34697,7 @@ msgstr ""
msgid "SourcegraphAdmin|Sourcegraph URL"
msgstr ""
-msgid "SourcegraphAdmin|e.g. https://sourcegraph.example.com"
+msgid "SourcegraphAdmin|https://sourcegraph.example.com"
msgstr ""
msgid "SourcegraphPreferences|This feature is experimental and currently limited to certain projects."
@@ -34143,6 +34832,9 @@ msgstr ""
msgid "Start date"
msgstr ""
+msgid "Start free trial"
+msgstr ""
+
msgid "Start merge train"
msgstr ""
@@ -34173,6 +34865,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started escalation for this incident."
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -34185,6 +34880,9 @@ msgstr ""
msgid "Starts at (UTC)"
msgstr ""
+msgid "Starts escalations for this incident"
+msgstr ""
+
msgid "Starts on"
msgstr ""
@@ -34446,6 +35144,9 @@ msgstr ""
msgid "Strikethrough"
msgstr ""
+msgid "Strikethrough text"
+msgstr ""
+
msgid "Subgroup information"
msgstr ""
@@ -34680,6 +35381,21 @@ msgstr ""
msgid "Subscriptions"
msgstr ""
+msgid "Subscriptions|Chat with sales"
+msgstr ""
+
+msgid "Subscriptions|Close"
+msgstr ""
+
+msgid "Subscriptions|Not ready to buy yet?"
+msgstr ""
+
+msgid "Subscriptions|Start a free trial"
+msgstr ""
+
+msgid "Subscriptions|We understand. Maybe you have some questions for our sales team, or maybe you'd like to try some of the paid features first. What would you like to do?"
+msgstr ""
+
msgid "Subscription|Your subscription for %{strong}%{namespace_name}%{strong_close} has expired and you are now on %{pricing_link_start}the GitLab Free tier%{pricing_link_end}. Don't worry, your data is safe. Get in touch with our support team (%{support_email}). They'll gladly help with your subscription renewal."
msgstr ""
@@ -34890,6 +35606,9 @@ msgstr ""
msgid "SuperSonics|Maximum users"
msgstr ""
+msgid "SuperSonics|Offline cloud"
+msgstr ""
+
msgid "SuperSonics|Paste your activation code"
msgstr ""
@@ -34956,6 +35675,12 @@ msgstr ""
msgid "SuperSonics|You do not have an active subscription"
msgstr ""
+msgid "SuperSonics|You have a future dated license"
+msgstr ""
+
+msgid "SuperSonics|You have added a license that activates on %{date}. Please see the subscription history table below for more details."
+msgstr ""
+
msgid "SuperSonics|You have successfully added a license that activates on %{date}. Please see the subscription history table below for more details."
msgstr ""
@@ -35115,6 +35840,9 @@ msgstr ""
msgid "Tag name is required"
msgstr ""
+msgid "Tag push"
+msgstr ""
+
msgid "Tag push events"
msgstr ""
@@ -35217,6 +35945,9 @@ msgstr ""
msgid "TagsPage|protected"
msgstr ""
+msgid "Take a look at the documentation to discover all of GitLab’s capabilities."
+msgstr ""
+
msgid "Target Branch"
msgstr ""
@@ -35619,6 +36350,9 @@ msgstr ""
msgid "Tests"
msgstr ""
+msgid "Text (optional)"
+msgstr ""
+
msgid "Text added to the body of all email messages. %{character_limit} character limit"
msgstr ""
@@ -35669,6 +36403,9 @@ msgstr ""
msgid "The CSV export will be created in the background. Once finished, it will be sent to %{email} in an attachment."
msgstr ""
+msgid "The CSV export you requested of all user memberships is attached to this email."
+msgstr ""
+
msgid "The GitLab subscription service (customers.gitlab.com) is currently experiencing an outage. You can monitor the status and get updates at %{linkStart}status.gitlab.com%{linkEnd}."
msgstr ""
@@ -35744,6 +36481,9 @@ 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 epic"
+msgstr ""
+
msgid "The current issue"
msgstr ""
@@ -35905,6 +36645,9 @@ msgstr ""
msgid "The latest pipeline for this merge request has failed."
msgstr ""
+msgid "The license key is invalid."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -35920,6 +36663,9 @@ msgstr ""
msgid "The license was successfully uploaded and will be active from %{starts_at}. You can see the details below."
msgstr ""
+msgid "The license you uploaded is invalid. If the issue persists, contact support at %{link}."
+msgstr ""
+
msgid "The list creation wizard is already open"
msgstr ""
@@ -36541,10 +37287,13 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} and everything this project contains. %{strongOpen}There is no going back%{strongClose}"
+msgstr ""
+
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains."
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}on %{date}%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains. %{strongOpen}There is no going back.%{strongClose}"
msgstr ""
msgid "This action will %{strongOpen}permanently remove%{strongClose} %{codeOpen}%{group}%{codeClose} %{strongOpen}immediately%{strongClose}."
@@ -36673,9 +37422,6 @@ msgstr ""
msgid "This file was modified for readability, and can't accept suggestions. Edit it directly."
msgstr ""
-msgid "This forked project has the following:"
-msgstr ""
-
msgid "This form is disabled in preview"
msgstr ""
@@ -36688,7 +37434,7 @@ msgstr ""
msgid "This group can't be removed because it is linked to a subscription. To remove this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
-msgid "This group can't be transfered because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
+msgid "This group can't be transferred because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
msgid "This group cannot be invited to a project inside a group with enforced SSO"
@@ -36715,6 +37461,9 @@ 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 incident is already escalated with '%{escalation_policy_name}'."
+msgstr ""
+
msgid "This invitation was sent to %{mail_to_invite_email}, but you are signed in as %{link_to_current_user} with email %{mail_to_current_user}."
msgstr ""
@@ -36733,9 +37482,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 merge train pipeline"
-msgstr ""
-
msgid "This is a private email address %{helpIcon} generated just for you. Anyone who has it can create issues or merge requests as if they were you. If that happens, %{resetLinkStart}reset this token%{resetLinkEnd}."
msgstr ""
@@ -36757,6 +37503,12 @@ msgstr ""
msgid "This is your current session"
msgstr ""
+msgid "This issue cannot be assigned to a confidential epic because it is public."
+msgstr ""
+
+msgid "This issue cannot be made public because it belongs to a confidential epic."
+msgstr ""
+
msgid "This issue is confidential and should only be visible to team members with at least Reporter access."
msgstr ""
@@ -36874,6 +37626,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 branch is protected from force push."
+msgstr ""
+
msgid "This merge request cannot be rebased while there are conflicts."
msgstr ""
@@ -36925,9 +37680,15 @@ msgstr ""
msgid "This pipeline was triggered by a schedule."
msgstr ""
+msgid "This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project"
msgstr ""
+msgid "This project can be restored until %{date}."
+msgstr ""
+
msgid "This project cannot be %{visibilityLevel} because the visibility of %{openShowLink}%{name}%{closeShowLink} is %{visibility}. To make this project %{visibilityLevel}, you must first %{openEditLink}change the visibility%{closeEditLink} of the parent group."
msgstr ""
@@ -36946,6 +37707,9 @@ msgstr ""
msgid "This project is %{strongStart}NOT%{strongEnd} a fork, and has the following:"
msgstr ""
+msgid "This project is %{strongStart}NOT%{strongEnd} a fork. This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -37637,6 +38401,9 @@ msgstr ""
msgid "Today"
msgstr ""
+msgid "Todos count"
+msgstr ""
+
msgid "Todos|Are you looking for things to do? Take a look at %{strongStart}%{openIssuesLinkStart}open issues%{openIssuesLinkEnd}%{strongEnd}, contribute to %{strongStart}%{mergeRequestLinkStart}a merge request%{mergeRequestLinkEnd}%{mergeRequestLinkEnd}%{strongEnd}, or mention someone in a comment to automatically assign them a new to-do item."
msgstr ""
@@ -37910,10 +38677,8 @@ msgstr ""
msgid "Trending"
msgstr ""
-msgid "Trials|%{planName} Trial %{enDash} %{num} day left"
-msgid_plural "Trials|%{planName} Trial %{enDash} %{num} days left"
-msgstr[0] ""
-msgstr[1] ""
+msgid "Trials|%{planName} Trial"
+msgstr ""
msgid "Trials|Compare all plans"
msgstr ""
@@ -37921,6 +38686,9 @@ msgstr ""
msgid "Trials|Create a new group to start your GitLab Ultimate trial."
msgstr ""
+msgid "Trials|Day %{daysUsed}/%{duration}"
+msgstr ""
+
msgid "Trials|Go back to GitLab"
msgstr ""
@@ -38170,7 +38938,7 @@ msgstr ""
msgid "URL is triggered when repository is updated"
msgstr ""
-msgid "URL must be percent-encoded if neccessary."
+msgid "URL must be percent-encoded if necessary."
msgstr ""
msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
@@ -38389,6 +39157,9 @@ msgstr ""
msgid "Unlock account"
msgstr ""
+msgid "Unlock more features with GitLab Ultimate"
+msgstr ""
+
msgid "Unlock the discussion"
msgstr ""
@@ -38452,6 +39223,9 @@ msgstr ""
msgid "Unsubscribes from this %{quick_action_target}."
msgstr ""
+msgid "Unsupported sort value."
+msgstr ""
+
msgid "Unsupported todo type passed. Supported todo types are: %{todo_types}"
msgstr ""
@@ -38680,6 +39454,9 @@ msgstr ""
msgid "UsageQuota|File attachments and smaller design graphics."
msgstr ""
+msgid "UsageQuota|From %{storage_enforcement_date} storage limits will apply to this namespace. View and manage your usage in %{strong_start}Group Settings &gt; Usage quotas%{strong_end}."
+msgstr ""
+
msgid "UsageQuota|Git repository."
msgstr ""
@@ -38740,6 +39517,9 @@ msgstr ""
msgid "UsageQuota|Storage type"
msgstr ""
+msgid "UsageQuota|Storage used"
+msgstr ""
+
msgid "UsageQuota|This is the total amount of storage used across your projects within this namespace."
msgstr ""
@@ -38935,6 +39715,12 @@ msgstr ""
msgid "Use hashed storage paths for newly created and renamed repositories. Always enabled since 13.0."
msgstr ""
+msgid "Use issue count"
+msgstr ""
+
+msgid "Use issue weight"
+msgstr ""
+
msgid "Use one line per URI"
msgstr ""
@@ -39316,6 +40102,9 @@ msgstr ""
msgid "Users"
msgstr ""
+msgid "Users API rate limit"
+msgstr ""
+
msgid "Users can launch a development environment from a GitLab browser tab when the %{linkStart}Gitpod%{linkEnd} integration is enabled."
msgstr ""
@@ -39641,6 +40430,9 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View group pipeline usage quota"
+msgstr ""
+
msgid "View incident details at"
msgstr ""
@@ -39793,6 +40585,9 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
+msgid "Vulnerability"
+msgstr ""
+
msgid "Vulnerability Report"
msgstr ""
@@ -39844,6 +40639,9 @@ msgstr ""
msgid "VulnerabilityManagement|An unverified non-confirmed finding"
msgstr ""
+msgid "VulnerabilityManagement|At least one identifier is required"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -39853,12 +40651,24 @@ msgstr ""
msgid "VulnerabilityManagement|Create Jira issue"
msgstr ""
+msgid "VulnerabilityManagement|Enter a name"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE code"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE identifier URL"
+msgstr ""
+
msgid "VulnerabilityManagement|Fetching linked Jira issues"
msgstr ""
msgid "VulnerabilityManagement|Manually add a vulnerability entry into the vulnerability report."
msgstr ""
+msgid "VulnerabilityManagement|Name is a required field"
+msgstr ""
+
msgid "VulnerabilityManagement|Needs triage"
msgstr ""
@@ -39874,6 +40684,18 @@ msgstr ""
msgid "VulnerabilityManagement|Select a method"
msgstr ""
+msgid "VulnerabilityManagement|Select a severity level"
+msgstr ""
+
+msgid "VulnerabilityManagement|Select a status"
+msgstr ""
+
+msgid "VulnerabilityManagement|Severity is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Something went wrong while creating vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -39898,6 +40720,12 @@ msgstr ""
msgid "VulnerabilityManagement|Something went wrong, could not update vulnerability state."
msgstr ""
+msgid "VulnerabilityManagement|Status is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Submit vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Summary, detailed description, steps to reproduce, etc."
msgstr ""
@@ -40093,6 +40921,9 @@ msgstr ""
msgid "WARNING:"
msgstr ""
+msgid "WARNING: This snippet contains hidden files which might be used to mask malicious behavior. Exercise caution if cloning and executing code from this snippet."
+msgstr ""
+
msgid "Wait for the file to load to copy its contents"
msgstr ""
@@ -40312,6 +41143,15 @@ msgstr ""
msgid "Webhooks|An issue is created, updated, closed, or reopened."
msgstr ""
+msgid "Webhooks|Are you sure you want to delete this group hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this project hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this webhook?"
+msgstr ""
+
msgid "Webhooks|Comments"
msgstr ""
@@ -40321,6 +41161,9 @@ msgstr ""
msgid "Webhooks|Confidential issues events"
msgstr ""
+msgid "Webhooks|Delete webhook"
+msgstr ""
+
msgid "Webhooks|Deployment events"
msgstr ""
@@ -40554,6 +41397,9 @@ msgstr ""
msgid "Wiki"
msgstr ""
+msgid "Wiki page"
+msgstr ""
+
msgid "Wiki page was successfully created."
msgstr ""
@@ -40659,7 +41505,7 @@ msgstr ""
msgid "WikiPageConflictMessage|Someone edited the page the same time you did. Please check out %{wikiLinkStart}the page%{wikiLinkEnd} and make sure your changes will not unintentionally remove theirs."
msgstr ""
-msgid "WikiPage|An error occured while trying to render the content editor. Please try again later."
+msgid "WikiPage|An error occurred while trying to render the content editor. Please try again later."
msgstr ""
msgid "WikiPage|Are you sure you want to switch back to the classic editor?"
@@ -40818,6 +41664,18 @@ msgstr ""
msgid "WorkItem|New Task"
msgstr ""
+msgid "WorkItem|Something went wrong when creating a work item. Please try again"
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching the work item. Please try again."
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching work item types. Please try again"
+msgstr ""
+
+msgid "WorkItem|Type"
+msgstr ""
+
msgid "WorkItem|Work Items"
msgstr ""
@@ -40884,7 +41742,10 @@ msgstr ""
msgid "You are about to add %{usersTag} people to the discussion. They will all receive a notification."
msgstr ""
-msgid "You are about to permanently delete this project"
+msgid "You are about to delete this forked project containing:"
+msgstr ""
+
+msgid "You are about to delete this project containing:"
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."
@@ -40905,6 +41766,9 @@ msgstr ""
msgid "You are attempting to update a file that has changed since you started editing it."
msgstr ""
+msgid "You are billed if you exceed this number. %{qsrOverageLinkStart}How does billing work?%{qsrOverageLinkEnd}"
+msgstr ""
+
msgid "You are connected to the Prometheus server, but there is currently no data to display."
msgstr ""
@@ -40962,6 +41826,9 @@ msgstr ""
msgid "You are not authorized to update this scanner profile"
msgstr ""
+msgid "You are not authorized to upload metric images"
+msgstr ""
+
msgid "You are now impersonating %{username}"
msgstr ""
@@ -41115,9 +41982,6 @@ msgstr ""
msgid "You can only upload one design when dropping onto an existing design."
msgstr ""
-msgid "You can recover this project until %{date}"
-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 ""
@@ -41166,9 +42030,6 @@ msgstr ""
msgid "You cannot write to this read-only GitLab instance."
msgstr ""
-msgid "You can’t %{tag_start}edit%{tag_end} files directly in this project. Fork this project and submit a merge request with your changes."
-msgstr ""
-
msgid "You can’t edit files directly in this project. Fork this project and submit a merge request with your changes."
msgstr ""
@@ -41321,9 +42182,6 @@ 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 set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
@@ -41354,12 +42212,6 @@ msgstr ""
msgid "You must have maintainer access to force delete a lock"
msgstr ""
-msgid "You must have permission to create a project in a group before forking."
-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 ""
@@ -41765,7 +42617,7 @@ msgstr ""
msgid "Your public email will be displayed on your public profile."
msgstr ""
-msgid "Your request for access could not be processed: %{error_meesage}"
+msgid "Your request for access could not be processed: %{error_message}"
msgstr ""
msgid "Your request for access has been queued for review."
@@ -41948,6 +42800,9 @@ msgstr ""
msgid "archived:"
msgstr ""
+msgid "artifacts"
+msgstr ""
+
msgid "assign yourself"
msgstr ""
@@ -41977,6 +42832,9 @@ msgstr[1] ""
msgid "branch name"
msgstr ""
+msgid "builds"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -42400,6 +43258,9 @@ msgstr ""
msgid "contact with same email already exists in group hierarchy"
msgstr ""
+msgid "container registry images"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -42439,6 +43300,9 @@ msgstr ""
msgid "data"
msgstr ""
+msgid "database"
+msgstr ""
+
msgid "date must not be after 9999-12-31"
msgstr ""
@@ -42462,9 +43326,6 @@ msgstr ""
msgid "design"
msgstr ""
-msgid "detached"
-msgstr ""
-
msgid "disabled"
msgstr ""
@@ -42713,7 +43574,7 @@ msgstr ""
msgid "is not a valid X509 certificate."
msgstr ""
-msgid "is not allowed for sign-up."
+msgid "is not allowed for sign-up. Please use your regular email address."
msgstr ""
msgid "is not allowed for this group."
@@ -42725,7 +43586,7 @@ msgstr ""
msgid "is not allowed since the group is not top-level group."
msgstr ""
-msgid "is not allowed."
+msgid "is not allowed. Please use your regular email address."
msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
@@ -42812,6 +43673,9 @@ msgstr ""
msgid "level: %{level}"
msgstr ""
+msgid "lfs objects"
+msgstr ""
+
msgid "limit of %{project_limit} reached"
msgstr ""
@@ -43031,6 +43895,9 @@ msgstr ""
msgid "mrWidget|Merge blocked: pipeline must succeed. It's waiting for a manual action to continue."
msgstr ""
+msgid "mrWidget|Merge blocked: pipeline must succeed. Push a commit that fixes the failure, or %{linkStart}learn about other solutions.%{linkEnd}"
+msgstr ""
+
msgid "mrWidget|Merge blocked: this merge request must be approved."
msgstr ""
@@ -43148,9 +44015,6 @@ msgstr ""
msgid "mrWidget|The changes were not merged into"
msgstr ""
-msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -43298,9 +44162,6 @@ msgstr ""
msgid "open issue"
msgstr ""
-msgid "opened %{timeAgo}"
-msgstr ""
-
msgid "or"
msgstr ""
@@ -43312,6 +44173,12 @@ msgid_plural "out of %d total tests"
msgstr[0] ""
msgstr[1] ""
+msgid "packages"
+msgstr ""
+
+msgid "pages"
+msgstr ""
+
msgid "parent"
msgid_plural "parents"
msgstr[0] ""
@@ -43461,6 +44328,9 @@ msgid_plural "replies"
msgstr[0] ""
msgstr[1] ""
+msgid "repositories"
+msgstr ""
+
msgid "repository:"
msgstr ""
@@ -43581,12 +44451,18 @@ msgstr ""
msgid "tag name"
msgstr ""
+msgid "terraform states"
+msgstr ""
+
msgid "the correct format."
msgstr ""
msgid "the file"
msgstr ""
+msgid "the following epic(s)"
+msgstr ""
+
msgid "the following issue(s)"
msgstr ""
@@ -43599,21 +44475,12 @@ msgstr ""
msgid "this document"
msgstr ""
-msgid "this issue cannot be assigned to a confidential epic since it is public"
-msgstr ""
-
-msgid "this issue cannot be made public since it belongs to a confidential epic"
-msgstr ""
-
msgid "time summary"
msgstr ""
msgid "toggle collapse"
msgstr ""
-msgid "train"
-msgstr ""
-
msgid "triggered"
msgstr ""
@@ -43742,3 +44609,6 @@ msgstr ""
msgid "{project}"
msgstr ""
+msgid "✔"
+msgstr ""
+
diff --git a/locale/eo/gitlab.po b/locale/eo/gitlab.po
index 0f026fc1f2a..9abb7eb3f64 100644
--- a/locale/eo/gitlab.po
+++ b/locale/eo/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: eo\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2022-02-02 15:48\n"
+"PO-Revision-Date: 2022-03-01 20:40\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -146,6 +146,11 @@ msgid_plural "%d approvers (you've approved)"
msgstr[0] ""
msgstr[1] ""
+msgid "%d assigned issue"
+msgid_plural "%d assigned issues"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -421,8 +426,23 @@ msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
msgstr[1] ""
-msgid "%d vulnerability updated"
-msgid_plural "%d vulnerabilities updated"
+msgid "%d vulnerability set to confirmed"
+msgid_plural "%d vulnerabilities set to confirmed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to dismissed"
+msgid_plural "%d vulnerabilities set to dismissed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to needs triage"
+msgid_plural "%d vulnerabilities set to needs triage"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to resolved"
+msgid_plural "%d vulnerabilities set to resolved"
msgstr[0] ""
msgstr[1] ""
@@ -510,6 +530,12 @@ msgstr[1] ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{completed} of %{total} issues closed"
+msgstr ""
+
+msgid "%{completed} of %{total} weight completed"
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -858,6 +884,9 @@ msgstr ""
msgid "%{openedIssues} open, %{closedIssues} closed"
msgstr ""
+msgid "%{percentage}%% issues closed"
+msgstr ""
+
msgid "%{percentage}%% weight completed"
msgstr ""
@@ -1287,6 +1316,9 @@ msgid_plural "- Users"
msgstr[0] ""
msgstr[1] ""
+msgid "- of - issues closed"
+msgstr ""
+
msgid "- of - weight completed"
msgstr ""
@@ -1429,7 +1461,7 @@ msgstr ""
msgid "1000+"
msgstr ""
-msgid "192.168.0.0/24"
+msgid "192.168.0.0/24 or 2001:0DB8:1234::/48"
msgstr ""
msgid "1st contribution!"
@@ -1741,13 +1773,13 @@ msgstr ""
msgid "AWS Access Key"
msgstr ""
-msgid "AWS Access Key. Only required if not using role instance credentials"
+msgid "AWS Secret Access Key"
msgstr ""
-msgid "AWS Secret Access Key"
+msgid "AWS access key ID (Optional)"
msgstr ""
-msgid "AWS Secret Access Key. Only required if not using role instance credentials"
+msgid "AWS secret access key (Optional)"
msgstr ""
msgid "AWS service error: %{error}"
@@ -1807,9 +1839,6 @@ msgstr ""
msgid "Access granted"
msgstr ""
-msgid "Access key ID"
-msgstr ""
-
msgid "Access requests"
msgstr ""
@@ -1984,7 +2013,7 @@ msgstr ""
msgid "Activity"
msgstr "Aktiveco"
-msgid "Activity|An error occured while retrieving activity. Reload the page to try again."
+msgid "Activity|An error occurred while retrieving activity. Reload the page to try again."
msgstr ""
msgid "Add"
@@ -2023,6 +2052,9 @@ msgstr ""
msgid "Add a %{type}"
msgstr ""
+msgid "Add a GCP region"
+msgstr ""
+
msgid "Add a GPG key"
msgstr ""
@@ -2074,6 +2106,9 @@ msgstr ""
msgid "Add a numbered list"
msgstr ""
+msgid "Add a related epic"
+msgstr ""
+
msgid "Add a related issue"
msgstr ""
@@ -2188,6 +2223,9 @@ msgstr ""
msgid "Add or subtract spent time"
msgstr ""
+msgid "Add people"
+msgstr ""
+
msgid "Add previously merged commits"
msgstr ""
@@ -2254,6 +2292,9 @@ msgstr ""
msgid "Add webhook"
msgstr ""
+msgid "Add your team members and others to GitLab."
+msgstr ""
+
msgid "Add/remove"
msgstr ""
@@ -3076,12 +3117,6 @@ msgstr ""
msgid "AdvancedSearch|Reindex required"
msgstr ""
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. Permanently deleting this project will %{strongStart}immediately delete%{strongEnd} its repositories and %{strongStart}all related resources%{strongEnd}, including issues, merge requests etc."
-msgstr ""
-
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. You will lose this project's repository and %{strongStart}all related resources%{strongEnd}, including issues and merge requests."
-msgstr ""
-
msgid "After a successful password update you will be redirected to login screen."
msgstr ""
@@ -3112,6 +3147,9 @@ msgstr ""
msgid "Akismet helps prevent the creation of spam issues in public projects."
msgstr ""
+msgid "Alert"
+msgstr ""
+
msgid "AlertManagement|Acknowledged"
msgstr ""
@@ -3484,9 +3522,6 @@ msgstr ""
msgid "All environments"
msgstr ""
-msgid "All epics"
-msgstr ""
-
msgid "All groups and projects"
msgstr ""
@@ -4223,12 +4258,15 @@ msgstr ""
msgid "ApplicationSettings|Approve users in the pending approval status?"
msgstr ""
-msgid "ApplicationSettings|By making this change, you will automatically approve %d user with the pending approval status."
-msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users with the pending approval status."
+msgid "ApplicationSettings|Approve users who are pending approval?"
+msgstr ""
+
+msgid "ApplicationSettings|By making this change, you will automatically approve %d user who is pending approval."
+msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users who are pending approval."
msgstr[0] ""
msgstr[1] ""
-msgid "ApplicationSettings|By making this change, you will automatically approve all users in pending approval status."
+msgid "ApplicationSettings|By making this change, you will automatically approve all users who are pending approval."
msgstr ""
msgid "ApplicationSettings|Denied domains for sign-ups"
@@ -4634,10 +4672,10 @@ msgstr ""
msgid "Archiving the project will make it entirely read-only. It is hidden from the dashboard and doesn't show up in searches. %{strong_start}The repository cannot be committed to, and no issues, comments, or other entities can be created.%{strong_end} %{link_start}Learn more.%{link_end}"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to delete this project?"
+msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
+msgid "Are you absolutely sure?"
msgstr ""
msgid "Are you sure that you want to archive this project?"
@@ -4673,12 +4711,18 @@ msgstr ""
msgid "Are you sure you want to delete this SSH key?"
msgstr ""
+msgid "Are you sure you want to delete this comment?"
+msgstr ""
+
msgid "Are you sure you want to delete this deploy key?"
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 label?"
+msgstr ""
+
msgid "Are you sure you want to delete this pipeline schedule?"
msgstr "Ĉu vi certe volas forigi ĉi tiun ĉenstablan planon?"
@@ -4694,9 +4738,6 @@ msgstr ""
msgid "Are you sure you want to discard your changes?"
msgstr ""
-msgid "Are you sure you want to erase this build?"
-msgstr ""
-
msgid "Are you sure you want to import %d repository?"
msgid_plural "Are you sure you want to import %d repositories?"
msgstr[0] ""
@@ -4744,6 +4785,9 @@ msgstr ""
msgid "Are you sure you want to remove this list?"
msgstr ""
+msgid "Are you sure you want to remove this nickname?"
+msgstr ""
+
msgid "Are you sure you want to reset the health check token?"
msgstr ""
@@ -4756,10 +4800,10 @@ 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?"
+msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
msgstr ""
-msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
+msgid "Are you sure you want to revoke this project access token? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to stop this environment?"
@@ -4906,9 +4950,6 @@ msgstr ""
msgid "Assigned to %{assignee_name}"
msgstr ""
-msgid "Assigned to %{name}"
-msgstr ""
-
msgid "Assigned to me"
msgstr ""
@@ -4973,6 +5014,9 @@ msgstr[1] ""
msgid "Attaching the file failed."
msgstr ""
+msgid "Attention"
+msgstr ""
+
msgid "Audit Events"
msgstr ""
@@ -5135,6 +5179,12 @@ msgstr ""
msgid "Authorized applications (%{size})"
msgstr ""
+msgid "AuthorizedApplication|Are you sure you want to revoke this application?"
+msgstr ""
+
+msgid "AuthorizedApplication|Revoke application"
+msgstr ""
+
msgid "Authors: %{authors}"
msgstr ""
@@ -6328,6 +6378,9 @@ msgstr ""
msgid "CICDAnalytics|Shared Runners Usage"
msgstr ""
+msgid "CICDAnalytics|Shared runner pipeline minute duration by month"
+msgstr ""
+
msgid "CICDAnalytics|Shared runner usage"
msgstr ""
@@ -6469,6 +6522,9 @@ msgstr ""
msgid "Can create groups:"
msgstr ""
+msgid "Can not delete primary training"
+msgstr ""
+
msgid "Can't apply as the source branch was deleted."
msgstr ""
@@ -6802,9 +6858,6 @@ msgstr ""
msgid "Changing any setting here requires an application restart"
msgstr ""
-msgid "Changing group URL can have unintended side effects."
-msgstr ""
-
msgid "Charts can't be displayed as the request for data has timed out. %{documentationLink}"
msgstr ""
@@ -6892,9 +6945,6 @@ msgstr ""
msgid "Checking branch availability..."
msgstr ""
-msgid "Checking group URL availability..."
-msgstr ""
-
msgid "Checking group path availability..."
msgstr ""
@@ -7388,6 +7438,9 @@ msgstr ""
msgid "Clear recent searches"
msgstr ""
+msgid "Clear repository checks"
+msgstr ""
+
msgid "Clear search"
msgstr ""
@@ -7520,9 +7573,6 @@ msgstr ""
msgid "Closed MRs"
msgstr ""
-msgid "Closed epics"
-msgstr ""
-
msgid "Closed issues"
msgstr ""
@@ -7559,13 +7609,13 @@ msgstr ""
msgid "Cluster level"
msgstr ""
-msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
+msgid "Cluster type must be specified for Stages::ClusterEndpointInserter"
msgstr ""
msgid "ClusterAgents|%{name} successfully deleted"
msgstr ""
-msgid "ClusterAgents|%{number} of %{total} Agents"
+msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
@@ -7607,6 +7657,15 @@ msgstr ""
msgid "ClusterAgents|Agent never connected to GitLab"
msgstr ""
+msgid "ClusterAgents|Agent version mismatch"
+msgstr ""
+
+msgid "ClusterAgents|Agent version mismatch and update"
+msgstr ""
+
+msgid "ClusterAgents|Agent version update required"
+msgstr ""
+
msgid "ClusterAgents|All"
msgstr ""
@@ -7631,7 +7690,7 @@ msgstr ""
msgid "ClusterAgents|Configuration"
msgstr ""
-msgid "ClusterAgents|Connect a cluster through the Agent"
+msgid "ClusterAgents|Connect a cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connect existing cluster"
@@ -7640,13 +7699,13 @@ msgstr ""
msgid "ClusterAgents|Connect with a certificate"
msgstr ""
-msgid "ClusterAgents|Connect with agent"
+msgid "ClusterAgents|Connect with an agent"
msgstr ""
msgid "ClusterAgents|Connect with the GitLab Agent"
msgstr ""
-msgid "ClusterAgents|Connect your cluster through the Agent"
+msgid "ClusterAgents|Connect your cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connected"
@@ -7706,7 +7765,10 @@ msgstr ""
msgid "ClusterAgents|How to register an agent?"
msgstr ""
-msgid "ClusterAgents|Install new Agent"
+msgid "ClusterAgents|How to update an agent?"
+msgstr ""
+
+msgid "ClusterAgents|Install a new agent"
msgstr ""
msgid "ClusterAgents|Last connected %{timeAgo}."
@@ -7733,7 +7795,7 @@ msgstr ""
msgid "ClusterAgents|Never connected"
msgstr ""
-msgid "ClusterAgents|No Agents"
+msgid "ClusterAgents|No agents"
msgstr ""
msgid "ClusterAgents|No clusters connected through cluster certificates"
@@ -7793,6 +7855,9 @@ msgstr ""
msgid "ClusterAgents|The agent has not been connected in a long time. There might be a connectivity issue. Last contact was %{timeAgo}."
msgstr ""
+msgid "ClusterAgents|The agent version do not match each other across your cluster's pods. This can happen when a new agent version was just deployed and Kubernetes is shutting down the old pods."
+msgstr ""
+
msgid "ClusterAgents|The recommended installation method includes the token. If you want to follow the advanced installation method provided in the docs, make sure you save the token value before you close this window."
msgstr ""
@@ -7840,6 +7905,9 @@ msgstr ""
msgid "ClusterAgents|You will need to create a token to connect to your agent"
msgstr ""
+msgid "ClusterAgents|Your agent version is out of sync with your GitLab version (v%{version}), which might cause compatibility problems. Update the agent installed on your cluster to the most recent version."
+msgstr ""
+
msgid "ClusterAgents|Your instance doesn't have the %{linkStart}GitLab Agent Server (KAS)%{linkEnd} set up. Ask a GitLab Administrator to install it."
msgstr ""
@@ -8716,9 +8784,6 @@ msgstr ""
msgid "Comma-separated list of email addresses."
msgstr ""
-msgid "Comma-separated list of users allowed to exceed the rate limit."
-msgstr ""
-
msgid "Comma-separated, e.g. '1.1.1.1, 2.2.2.0/24'"
msgstr ""
@@ -9045,6 +9110,12 @@ msgstr ""
msgid "Confidential"
msgstr ""
+msgid "Confidential issue"
+msgstr ""
+
+msgid "Confidential note"
+msgstr ""
+
msgid "Confidentiality"
msgstr ""
@@ -9078,6 +9149,9 @@ msgstr ""
msgid "Configure Dependency Scanning in `.gitlab-ci.yml`, creating this file if it does not already exist"
msgstr ""
+msgid "Configure GitLab"
+msgstr ""
+
msgid "Configure GitLab runners to start using the Web Terminal. %{helpStart}Learn more.%{helpEnd}"
msgstr ""
@@ -9126,6 +9200,15 @@ msgstr ""
msgid "Configure pipelines to deploy web apps, backend services, APIs and static resources to Google Cloud"
msgstr ""
+msgid "Configure region"
+msgstr ""
+
+msgid "Configure region for environment"
+msgstr ""
+
+msgid "Configure regions"
+msgstr ""
+
msgid "Configure repository mirroring."
msgstr ""
@@ -9159,6 +9242,9 @@ msgstr ""
msgid "Configure which lists are shown for anyone who visits this board"
msgstr ""
+msgid "Configure your environments to be deployed to specific geographical regions"
+msgstr ""
+
msgid "Confirm"
msgstr ""
@@ -9861,10 +9947,10 @@ msgstr ""
msgid "CorpusManagement|Actions"
msgstr ""
-msgid "CorpusManagement|Corpus are used in fuzz testing as mutation source to Improve future testing."
+msgid "CorpusManagement|Corpus file"
msgstr ""
-msgid "CorpusManagement|Corpus file"
+msgid "CorpusManagement|Corpus files are used in coverage-guided fuzz testing as seed inputs to improve testing."
msgstr ""
msgid "CorpusManagement|Corpus files must be in *.zip format. Maximum 5 GB"
@@ -9918,6 +10004,9 @@ msgstr ""
msgid "Could not apply %{name} command."
msgstr ""
+msgid "Could not apply %{name} command. %{message}."
+msgstr ""
+
msgid "Could not authorize chat nickname. Try again!"
msgstr ""
@@ -10068,6 +10157,9 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
+msgid "Create a group"
+msgstr ""
+
msgid "Create a merge request"
msgstr ""
@@ -10092,6 +10184,9 @@ msgstr ""
msgid "Create a personal access token on your account to pull or push via %{protocol}."
msgstr "Kreu propran atingoĵetonon en via konto por ebligi al vi eltiri kaj alpuÅi per %{protocol}."
+msgid "Create a project"
+msgstr ""
+
msgid "Create an account using:"
msgstr ""
@@ -10455,6 +10550,9 @@ msgstr ""
msgid "Creation date"
msgstr ""
+msgid "Creator"
+msgstr ""
+
msgid "Credentials"
msgstr ""
@@ -10467,9 +10565,15 @@ msgstr ""
msgid "CredentialsInventory|Personal Access Tokens"
msgstr ""
+msgid "CredentialsInventory|Project Access Tokens"
+msgstr ""
+
msgid "CredentialsInventory|SSH Keys"
msgstr ""
+msgid "Credit card required to be on file in order to create a pipeline"
+msgstr ""
+
msgid "Credit card:"
msgstr ""
@@ -10653,9 +10757,6 @@ msgstr ""
msgid "Customer relations"
msgstr ""
-msgid "Customizable by an administrator."
-msgstr ""
-
msgid "Customizable by owners."
msgstr ""
@@ -10785,30 +10886,18 @@ msgstr ""
msgid "CycleAnalytics|%{selectedLabelsCount} selected (%{maxLabels} max)"
msgstr ""
-msgid "CycleAnalytics|%{stageCount} stages selected"
-msgstr ""
-
-msgid "CycleAnalytics|All stages"
-msgstr ""
-
-msgid "CycleAnalytics|Average days to completion"
+msgid "CycleAnalytics|Average time to completion"
msgstr ""
msgid "CycleAnalytics|Date"
msgstr ""
-msgid "CycleAnalytics|Days to completion"
-msgstr ""
-
msgid "CycleAnalytics|Display chart filters"
msgstr ""
msgid "CycleAnalytics|Lead Time for Changes"
msgstr ""
-msgid "CycleAnalytics|No stages selected"
-msgstr ""
-
msgid "CycleAnalytics|Number of tasks"
msgstr ""
@@ -10837,18 +10926,30 @@ msgstr ""
msgid "CycleAnalytics|Showing data for group '%{groupName}' from %{createdAfter} to %{createdBefore}"
msgstr ""
-msgid "CycleAnalytics|Stages"
+msgid "CycleAnalytics|Stage time: %{title}"
msgstr ""
msgid "CycleAnalytics|Tasks by type"
msgstr ""
-msgid "CycleAnalytics|The average time spent in the selected stage for the items that were completed on each date. Data limited to the last 500 items."
+msgid "CycleAnalytics|The average time items spent in this stage. Data limited to items completed within this date range."
msgstr ""
msgid "CycleAnalytics|The given date range is larger than 180 days"
msgstr ""
+msgid "CycleAnalytics|The total time items spent across each value stream stage. Data limited to items completed within this date range."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Stage time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Total time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|Total time"
+msgstr ""
+
msgid "CycleAnalytics|Type of work"
msgstr ""
@@ -10861,9 +10962,6 @@ msgstr ""
msgid "CycleAnalytics|project dropdown filter"
msgstr ""
-msgid "CycleAnalytics|stage dropdown"
-msgstr ""
-
msgid "DAG visualization requires at least 3 dependent jobs."
msgstr ""
@@ -10963,10 +11061,16 @@ msgstr ""
msgid "DastProfiles|AJAX spider"
msgstr ""
+msgid "DastProfiles|API"
+msgstr ""
+
+msgid "DastProfiles|API endpoint URL"
+msgstr ""
+
msgid "DastProfiles|Active"
msgstr ""
-msgid "DastProfiles|Additional request headers (Optional)"
+msgid "DastProfiles|Additional request headers (optional)"
msgstr ""
msgid "DastProfiles|Are you sure you want to delete this profile?"
@@ -10981,6 +11085,9 @@ msgstr ""
msgid "DastProfiles|Branch missing"
msgstr ""
+msgid "DastProfiles|Choose a scan method"
+msgstr ""
+
msgid "DastProfiles|Could not create the scanner profile. Please try again."
msgstr ""
@@ -11050,7 +11157,13 @@ msgstr ""
msgid "DastProfiles|Excluded URLs"
msgstr ""
-msgid "DastProfiles|Excluded URLs (Optional)"
+msgid "DastProfiles|Excluded URLs (optional)"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths (optional)"
msgstr ""
msgid "DastProfiles|Hide debug messages"
@@ -11107,9 +11220,6 @@ msgstr ""
msgid "DastProfiles|Request headers"
msgstr ""
-msgid "DastProfiles|Rest API"
-msgstr ""
-
msgid "DastProfiles|Run the AJAX spider, in addition to the traditional spider, to crawl the target site."
msgstr ""
@@ -11119,6 +11229,9 @@ msgstr ""
msgid "DastProfiles|Save profile"
msgstr ""
+msgid "DastProfiles|Scan method"
+msgstr ""
+
msgid "DastProfiles|Scan mode"
msgstr ""
@@ -11197,12 +11310,24 @@ msgstr ""
msgid "DastProfiles|Website"
msgstr ""
+msgid "DastProfiles|What does each method do?"
+msgstr ""
+
msgid "DastProfiles|You can either choose a passive scan or validate the target site from the site profile management page. %{docsLinkStart}Learn more about site validation.%{docsLinkEnd}"
msgstr ""
msgid "DastProfiles|You cannot run an active scan against an unvalidated site."
msgstr ""
+msgid "DastProfiles|folder/dast_example.har or https://example.com/dast_example.har"
+msgstr ""
+
+msgid "DastProfiles|folder/example.postman_collection.json or https://example.com/"
+msgstr ""
+
+msgid "DastProfiles|folder/openapi.json or https://example.com/openapi.json"
+msgstr ""
+
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
@@ -11310,6 +11435,9 @@ msgstr ""
msgid "DatadogIntegration|API URL"
msgstr ""
+msgid "DatadogIntegration|Custom tags in Datadog. Enter one tag per line in the %{codeOpen}key:value%{codeClose} format. %{linkOpen}How do I use tags?%{linkClose}"
+msgstr ""
+
msgid "DatadogIntegration|Environment"
msgstr ""
@@ -11328,12 +11456,18 @@ msgstr ""
msgid "DatadogIntegration|Tag all data from this GitLab instance in Datadog. Useful when managing several self-managed deployments."
msgstr ""
+msgid "DatadogIntegration|Tags"
+msgstr ""
+
msgid "DatadogIntegration|The Datadog site to send data to. To send data to the EU site, use %{codeOpen}datadoghq.eu%{codeClose}."
msgstr ""
msgid "DatadogIntegration|Trace your GitLab pipelines with Datadog."
msgstr ""
+msgid "DatadogIntegration|have an invalid format"
+msgstr ""
+
msgid "Datasource name not found"
msgstr ""
@@ -11343,9 +11477,6 @@ msgstr ""
msgid "Date merged"
msgstr ""
-msgid "Date picker"
-msgstr ""
-
msgid "Date range"
msgstr ""
@@ -11499,9 +11630,6 @@ msgstr ""
msgid "Definition"
msgstr ""
-msgid "Delayed Project Deletion (%{adjourned_deletion})"
-msgstr ""
-
msgid "DelayedJobs|Are you sure you want to run %{jobName} immediately? Otherwise this job will run automatically after its timer finishes."
msgstr ""
@@ -11580,10 +11708,10 @@ msgstr ""
msgid "Delete pipeline"
msgstr ""
-msgid "Delete project"
+msgid "Delete pipeline schedule"
msgstr ""
-msgid "Delete project. Are you ABSOLUTELY SURE?"
+msgid "Delete project"
msgstr ""
msgid "Delete row"
@@ -11613,6 +11741,9 @@ msgstr ""
msgid "Delete this epic and all descendants?"
msgstr ""
+msgid "Delete this project"
+msgstr ""
+
msgid "Delete user list"
msgstr ""
@@ -11871,6 +12002,12 @@ msgstr ""
msgid "Deploy to..."
msgstr ""
+msgid "DeployBoards|To see deployment progress for your environments, make sure you are deploying to %{codeStart}$KUBE_NAMESPACE%{codeEnd} and annotating with %{codeStart}app.gitlab.com/app=$CI_PROJECT_PATH_SLUG%{codeEnd} and %{codeStart}app.gitlab.com/env=$CI_ENVIRONMENT_SLUG%{codeEnd}."
+msgstr ""
+
+msgid "DeployBoard|Kubernetes Pods"
+msgstr ""
+
msgid "DeployFreeze|Add a freeze period to prevent unintended releases during a period of time for a given environment. You must update the deployment jobs in %{filename} according to the deploy freezes added here. %{freeze_period_link_start}Learn more.%{freeze_period_link_end}"
msgstr ""
@@ -11955,9 +12092,6 @@ msgstr ""
msgid "DeployTokens|Active Deploy Tokens (%{active_tokens})"
msgstr ""
-msgid "DeployTokens|Allows read and write access to registry images."
-msgstr ""
-
msgid "DeployTokens|Allows read and write access to the package registry."
msgstr ""
@@ -11970,6 +12104,9 @@ msgstr ""
msgid "DeployTokens|Allows read-only access to the repository."
msgstr ""
+msgid "DeployTokens|Allows write access to registry images."
+msgstr ""
+
msgid "DeployTokens|Copy deploy token"
msgstr ""
@@ -12063,12 +12200,57 @@ msgstr ""
msgid "Deploying to AWS is easy with GitLab"
msgstr ""
+msgid "Deployment"
+msgstr ""
+
msgid "Deployment Frequency"
msgstr ""
+msgid "Deployment Target|Project deployment target (optional)"
+msgstr ""
+
+msgid "Deployment Target|Select the deployment target"
+msgstr ""
+
msgid "Deployment frequency"
msgstr ""
+msgid "DeploymentTarget|GitLab Pages"
+msgstr ""
+
+msgid "DeploymentTarget|Heroku"
+msgstr ""
+
+msgid "DeploymentTarget|Infrastructure provider (Terraform, Cloudformation, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Kubernetes (GKE, EKS, OpenShift, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Managed container runtime (Fargate, Cloud Run, DigitalOcean App)"
+msgstr ""
+
+msgid "DeploymentTarget|Mobile app store"
+msgstr ""
+
+msgid "DeploymentTarget|No deployment planned"
+msgstr ""
+
+msgid "DeploymentTarget|Other hosting service"
+msgstr ""
+
+msgid "DeploymentTarget|Registry (package or container)"
+msgstr ""
+
+msgid "DeploymentTarget|Self-managed container runtime (Podman, Docker Swarm, Docker Compose)"
+msgstr ""
+
+msgid "DeploymentTarget|Serverless backend (Lambda, Cloud functions)"
+msgstr ""
+
+msgid "DeploymentTarget|Virtual machine (for example, EC2)"
+msgstr ""
+
msgid "Deployments"
msgstr ""
@@ -12107,6 +12289,9 @@ msgstr ""
msgid "Deployment|This deployment was created using the API"
msgstr ""
+msgid "Deployment|Triggerer"
+msgstr ""
+
msgid "Deployment|Waiting"
msgstr ""
@@ -12134,6 +12319,18 @@ msgstr ""
msgid "Deprecated API rate limits"
msgstr ""
+msgid "Deprecations|Feature deprecation and removal"
+msgstr ""
+
+msgid "Deprecations|For information on a possible replacement %{epicStart} learn more about Opstrace %{epicEnd}."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7 and are %{epicStart} scheduled for removal %{epicEnd} in GitLab 15.0."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7, and are %{removal_link_start} scheduled for removal %{link_end} in GitLab 15.0. For information on a possible replacement, %{opstrace_link_start} learn more about Opstrace %{link_end}."
+msgstr ""
+
msgid "Deprioritize label"
msgstr ""
@@ -12379,10 +12576,10 @@ msgstr ""
msgid "DevopsAdoption|At least one deploy"
msgstr ""
-msgid "DevopsAdoption|At least one issue opened"
+msgid "DevopsAdoption|At least one issue created"
msgstr ""
-msgid "DevopsAdoption|At least one merge request opened"
+msgid "DevopsAdoption|At least one merge request created"
msgstr ""
msgid "DevopsAdoption|At least one pipeline successfully run"
@@ -12583,6 +12780,9 @@ msgstr ""
msgid "Direct member"
msgstr ""
+msgid "Direct members"
+msgstr ""
+
msgid "Direct non-authenticated users to this page."
msgstr ""
@@ -12699,6 +12899,9 @@ msgid_plural "Dismiss %d selected vulnerabilities as"
msgstr[0] ""
msgstr[1] ""
+msgid "Dismiss Alert"
+msgstr ""
+
msgid "Dismiss merge request promotion"
msgstr ""
@@ -12726,9 +12929,15 @@ msgstr ""
msgid "Display alerts from all configured monitoring tools."
msgstr ""
+msgid "Display milestones"
+msgstr ""
+
msgid "Display name"
msgstr ""
+msgid "Display progress of child issues"
+msgstr ""
+
msgid "Display rendered file"
msgstr ""
@@ -12834,6 +13043,9 @@ msgstr ""
msgid "Download image"
msgstr ""
+msgid "Download payload"
+msgstr ""
+
msgid "Download raw data (.csv)"
msgstr ""
@@ -13011,6 +13223,9 @@ msgstr ""
msgid "Edit in Web IDE"
msgstr ""
+msgid "Edit in pipeline editor"
+msgstr ""
+
msgid "Edit in single-file editor"
msgstr ""
@@ -13053,6 +13268,9 @@ msgstr ""
msgid "Edit your most recent comment in a thread (from an empty textarea)"
msgstr ""
+msgid "Edit, lint, and visualize your pipeline."
+msgstr ""
+
msgid "Edited"
msgstr ""
@@ -13494,6 +13712,9 @@ msgstr ""
msgid "Enforce two-factor authentication for all user sign-ins."
msgstr ""
+msgid "Enhance security by storing service account keys in secret managers - learn more about %{docLinkStart}secret management with GitLab%{docLinkEnd}"
+msgstr ""
+
msgid "Ensure connectivity is available from the GitLab server to the Prometheus server"
msgstr ""
@@ -13554,6 +13775,9 @@ 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 following to confirm:"
+msgstr ""
+
msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
@@ -14084,9 +14308,6 @@ 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 ""
@@ -14222,6 +14443,9 @@ msgstr ""
msgid "Errors:"
msgstr ""
+msgid "Escalate this incident"
+msgstr ""
+
msgid "Escalation Policies"
msgstr ""
@@ -14234,6 +14458,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy"
+msgstr ""
+
msgid "Escalation policy:"
msgstr ""
@@ -14485,6 +14712,9 @@ msgstr ""
msgid "Existing sign in methods may be removed"
msgstr ""
+msgid "Exit."
+msgstr ""
+
msgid "Expand"
msgstr ""
@@ -14581,6 +14811,9 @@ msgstr ""
msgid "Explore public groups"
msgstr ""
+msgid "Explore public projects"
+msgstr ""
+
msgid "Explore snippets"
msgstr ""
@@ -14742,7 +14975,7 @@ msgid_plural "Failed to archive designs. Please try again."
msgstr[0] ""
msgstr[1] ""
-msgid "Failed to assign a reviewer because no user was found."
+msgid "Failed to assign a reviewer because no user was specified."
msgstr ""
msgid "Failed to assign a user because no user was found."
@@ -14808,10 +15041,10 @@ msgstr ""
msgid "Failed to find import label for Jira import."
msgstr ""
-msgid "Failed to generate export, please try again later."
+msgid "Failed to find users for %{missing}"
msgstr ""
-msgid "Failed to generate report, please try again after sometime"
+msgid "Failed to generate export, please try again later."
msgstr ""
msgid "Failed to get ref."
@@ -14910,6 +15143,9 @@ msgstr ""
msgid "Failed to remove a to-do item for the design."
msgstr ""
+msgid "Failed to remove attention because no user was found."
+msgstr ""
+
msgid "Failed to remove mirror."
msgstr ""
@@ -14922,6 +15158,9 @@ msgstr ""
msgid "Failed to remove user key."
msgstr ""
+msgid "Failed to request attention because no user was found."
+msgstr ""
+
msgid "Failed to reset key. Please try again."
msgstr ""
@@ -15003,6 +15242,9 @@ msgstr ""
msgid "Feature Flags"
msgstr ""
+msgid "Feature deprecation and removal"
+msgstr ""
+
msgid "Feature flag status"
msgstr ""
@@ -15500,7 +15742,7 @@ msgstr ""
msgid "For each job, re-use the project workspace. If the workspace doesn't exist, use %{code_open}git clone%{code_close}."
msgstr ""
-msgid "For example, the application using the token or the purpose of the token."
+msgid "For example, the application using the token or the purpose of the token. Do not give sensitive information for the name of the token, as it will be visible to all %{resource_type} members."
msgstr ""
msgid "For files larger than this limit, only index the file name. The file content is neither indexed nor searchable."
@@ -15584,9 +15826,6 @@ msgstr ""
msgid "ForkProject|Select a namespace"
msgstr ""
-msgid "ForkProject|Select a namespace to fork the project"
-msgstr ""
-
msgid "ForkProject|The project can be accessed by any logged in user."
msgstr ""
@@ -15683,6 +15922,9 @@ msgstr ""
msgid "Full name"
msgstr ""
+msgid "GCP region configured"
+msgstr ""
+
msgid "GPG Key ID:"
msgstr ""
@@ -15863,6 +16105,9 @@ msgstr ""
msgid "Geo|Failed"
msgstr ""
+msgid "Geo|Filter Geo sites"
+msgstr ""
+
msgid "Geo|Filter by name"
msgstr ""
@@ -16274,6 +16519,12 @@ msgstr ""
msgid "GitLab Issue"
msgstr ""
+msgid "GitLab KAS"
+msgstr ""
+
+msgid "GitLab Memberships CSV Export"
+msgstr ""
+
msgid "GitLab Pages"
msgstr ""
@@ -16322,6 +16573,9 @@ 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 free to use. Many features for larger teams are part of our %{link_start}paid products%{link_end}. You can try Ultimate for free without any obligation or payment details."
+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 ""
@@ -16448,7 +16702,7 @@ msgstr ""
msgid "GitLabPages|When enabled, all attempts to visit your website through HTTP are automatically redirected to HTTPS using a response with status code 301. Requires a valid certificate for all domains. %{docs_link_start}Learn more.%{link_end}"
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. %{docs_link_start}Learn more.%{link_end}"
+msgid "GitLabPages|When using Pages under the general domain of a GitLab instance (%{pages_host}), you cannot use HTTPS with subdomains of subdomains. If your namespace or groupname contains a dot, it does not work. This is a limitation of the HTTP Over TLS protocol. HTTP pages work if you don't redirect HTTP to HTTPS. %{docs_link_start}Learn more.%{link_end}"
msgstr ""
msgid "GitLabPages|With GitLab Pages you can host your static website directly from your GitLab repository. %{docs_link_start}Learn more.%{link_end}"
@@ -16625,9 +16879,6 @@ msgstr ""
msgid "Go to find file"
msgstr ""
-msgid "Go to fork"
-msgstr ""
-
msgid "Go to issue boards"
msgstr ""
@@ -16835,9 +17086,6 @@ msgstr ""
msgid "Group Hooks"
msgstr ""
-msgid "Group ID"
-msgstr ""
-
msgid "Group Owner must have signed in with SAML before enabling Group Managed Accounts"
msgstr ""
@@ -16865,9 +17113,6 @@ msgstr ""
msgid "Group by"
msgstr ""
-msgid "Group description"
-msgstr ""
-
msgid "Group description (optional)"
msgstr ""
@@ -16982,7 +17227,7 @@ msgstr ""
msgid "Group: %{name}"
msgstr ""
-msgid "GroupActivityMetrics|Issues opened"
+msgid "GroupActivityMetrics|Issues created"
msgstr ""
msgid "GroupActivityMetrics|Last 90 days"
@@ -16991,7 +17236,7 @@ msgstr ""
msgid "GroupActivityMetrics|Members added"
msgstr ""
-msgid "GroupActivityMetrics|Merge Requests opened"
+msgid "GroupActivityMetrics|Merge Requests created"
msgstr ""
msgid "GroupActivityMetrics|Recent activity"
@@ -17282,6 +17527,9 @@ msgstr ""
msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
+msgid "GroupSettings|Choose a group path that does not start with a dash or end with a period. It can also contain alphanumeric characters and underscores."
+msgstr ""
+
msgid "GroupSettings|Compliance frameworks"
msgstr ""
@@ -17315,7 +17563,7 @@ msgstr ""
msgid "GroupSettings|If not specified at the group or instance level, the default is %{default_initial_branch_name}. Does not affect existing repositories."
msgstr ""
-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."
+msgid "GroupSettings|If the parent group's visibility is lower than the group's current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility."
msgstr ""
msgid "GroupSettings|New runners registration token has been generated!"
@@ -17432,7 +17680,10 @@ msgstr ""
msgid "Groups and projects"
msgstr ""
-msgid "Groups and subgroups"
+msgid "Groups are a great way to organize projects and people."
+msgstr ""
+
+msgid "Groups are the best way to manage projects and members."
msgstr ""
msgid "Groups to synchronize"
@@ -17543,13 +17794,16 @@ msgstr ""
msgid "GroupsTree|Are you sure you want to leave the \"%{fullName}\" group?"
msgstr ""
-msgid "GroupsTree|Edit group"
+msgid "GroupsTree|Delete"
+msgstr ""
+
+msgid "GroupsTree|Edit"
msgstr ""
msgid "GroupsTree|Failed to leave the group. Please make sure you are not the only owner."
msgstr ""
-msgid "GroupsTree|Leave this group"
+msgid "GroupsTree|Leave group"
msgstr ""
msgid "GroupsTree|Loading groups"
@@ -17561,9 +17815,57 @@ msgstr ""
msgid "GroupsTree|No groups or projects matched your search"
msgstr ""
+msgid "GroupsTree|Options"
+msgstr ""
+
msgid "GroupsTree|Search by name"
msgstr ""
+msgid "Groups|Avatar will be removed. Are you sure?"
+msgstr ""
+
+msgid "Groups|Changing group URL can have unintended side effects."
+msgstr ""
+
+msgid "Groups|Checking group URL availability..."
+msgstr ""
+
+msgid "Groups|Enter a descriptive name for your group."
+msgstr ""
+
+msgid "Groups|Group ID"
+msgstr ""
+
+msgid "Groups|Group URL"
+msgstr ""
+
+msgid "Groups|Group avatar"
+msgstr ""
+
+msgid "Groups|Group description (optional)"
+msgstr ""
+
+msgid "Groups|Group name"
+msgstr ""
+
+msgid "Groups|Group path is available."
+msgstr ""
+
+msgid "Groups|Group path is unavailable. Path has been replaced with a suggested available path."
+msgstr ""
+
+msgid "Groups|Learn more"
+msgstr ""
+
+msgid "Groups|Must start with letter, digit, emoji, or underscore. Can also contain periods, dashes, spaces, and parentheses."
+msgstr ""
+
+msgid "Groups|Remove avatar"
+msgstr ""
+
+msgid "Groups|Save changes"
+msgstr ""
+
msgid "Guideline"
msgstr ""
@@ -17573,6 +17875,9 @@ msgstr ""
msgid "HAR file path or URL"
msgstr ""
+msgid "HTTP Archive (HAR)"
+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 ""
@@ -17973,6 +18278,9 @@ msgstr ""
msgid "INFO: Your SSH key is expiring soon. Please generate a new key."
msgstr ""
+msgid "IP"
+msgstr ""
+
msgid "IP Address"
msgstr ""
@@ -18009,6 +18317,9 @@ msgstr ""
msgid "IdentityVerification|Verify your identity"
msgstr ""
+msgid "IdentityVerification|You can always verify your account at a later time to create a group."
+msgstr ""
+
msgid "If any indexed field exceeds this limit, it is truncated to this number of characters. The rest of the content is neither indexed nor searchable. This does not apply to repository and wiki indexing. For unlimited characters, set this to 0."
msgstr ""
@@ -18066,6 +18377,9 @@ msgstr ""
msgid "If you add %{codeStart}needs%{codeEnd} to jobs in your pipeline you'll be able to view the %{codeStart}needs%{codeEnd} relationships between jobs in this tab as a %{linkStart}Directed Acyclic Graph (DAG)%{linkEnd}."
msgstr ""
+msgid "If you are added to a project, it will be displayed here."
+msgstr ""
+
msgid "If you did not initiate these sign-in attempts, please reach out to your administrator or enable two-factor authentication (2FA) on your account."
msgstr ""
@@ -18372,12 +18686,24 @@ msgstr ""
msgid "InProductMarketing|3 ways to dive into GitLab CI/CD"
msgstr ""
+msgid "InProductMarketing|A single application eliminates complex integrations, data chokepoints, and toolchain maintenance, resulting in greater productivity and lower cost."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features, build more efficiently, strengthen security and compliance."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features."
+msgstr ""
+
msgid "InProductMarketing|Actually, GitLab makes the team work (better)"
msgstr ""
msgid "InProductMarketing|And finally %{deploy_link} a Python application."
msgstr ""
+msgid "InProductMarketing|And many more..."
+msgstr ""
+
msgid "InProductMarketing|Are your runners ready?"
msgstr ""
@@ -18396,15 +18722,33 @@ msgstr ""
msgid "InProductMarketing|Blog"
msgstr ""
+msgid "InProductMarketing|Break down silos to coordinate seamlessly across development, operations, and security with a consistent experience across the development lifecycle."
+msgstr ""
+
+msgid "InProductMarketing|Burn up/down charts"
+msgstr ""
+
msgid "InProductMarketing|By enabling code owners and required merge approvals the right person will review the right MR. This is a win-win: cleaner code and a more efficient review process."
msgstr ""
msgid "InProductMarketing|Click on the number below that corresponds with your answer — 1 being very difficult, 5 being very easy."
msgstr ""
+msgid "InProductMarketing|Code owners"
+msgstr ""
+
msgid "InProductMarketing|Code owners and required merge approvals are part of the paid tiers of GitLab. You can start a free 30-day trial of GitLab Ultimate and enable these features in less than 5 minutes with no credit card required."
msgstr ""
+msgid "InProductMarketing|Code review analytics"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration across stages in GitLab"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration made easy"
+msgstr ""
+
msgid "InProductMarketing|Create a custom CI runner with just a few clicks"
msgstr ""
@@ -18414,12 +18758,21 @@ msgstr ""
msgid "InProductMarketing|Create a project in GitLab in 5 minutes"
msgstr ""
+msgid "InProductMarketing|Create well-defined workflows by using scoped labels on issues, merge requests, and epics. Labels with the same scope cannot be used together, which prevents conflicts."
+msgstr ""
+
msgid "InProductMarketing|Create your first project!"
msgstr ""
+msgid "InProductMarketing|Define who owns specific files or directories, so the right reviewers are suggested when a merge request introduces changes to those files."
+msgstr ""
+
msgid "InProductMarketing|Deliver Better Products Faster"
msgstr ""
+msgid "InProductMarketing|Dependency scanning"
+msgstr ""
+
msgid "InProductMarketing|Did you know teams that use GitLab are far more efficient?"
msgstr ""
@@ -18429,15 +18782,27 @@ msgstr ""
msgid "InProductMarketing|Dig in and create a project and a repo"
msgstr ""
+msgid "InProductMarketing|Discover Premium & Ultimate"
+msgstr ""
+
+msgid "InProductMarketing|Discover Premium & Ultimate."
+msgstr ""
+
msgid "InProductMarketing|Do you have a minute?"
msgstr ""
msgid "InProductMarketing|Do you have a teammate who would be perfect for this task?"
msgstr ""
+msgid "InProductMarketing|Dynamic application security testing"
+msgstr ""
+
msgid "InProductMarketing|Easy"
msgstr ""
+msgid "InProductMarketing|Epics"
+msgstr ""
+
msgid "InProductMarketing|Expand your DevOps journey with a free GitLab trial"
msgstr ""
@@ -18459,9 +18824,15 @@ msgstr ""
msgid "InProductMarketing|Feel the need for speed?"
msgstr ""
+msgid "InProductMarketing|Find and fix bottlenecks in your code review process by understanding how long open merge requests have been in review."
+msgstr ""
+
msgid "InProductMarketing|Find out how your teams are really doing"
msgstr ""
+msgid "InProductMarketing|Find out if your external libraries are safe. Run dependency scanning jobs that check for known vulnerabilities in your external libraries."
+msgstr ""
+
msgid "InProductMarketing|Follow our steps"
msgstr ""
@@ -18498,6 +18869,9 @@ msgstr ""
msgid "InProductMarketing|GitLab is better with teammates to help out!"
msgstr ""
+msgid "InProductMarketing|GitLab is infrastructure agnostic (supporting GCP, AWS, Azure, OpenShift, VMWare, On Prem, Bare Metal, and more), offering a consistent workflow experience – irrespective of the environment."
+msgstr ""
+
msgid "InProductMarketing|GitLab provides static application security testing (SAST), dynamic application security testing (DAST), container scanning, and dependency scanning to help you deliver secure applications along with license compliance."
msgstr ""
@@ -18588,21 +18962,36 @@ msgstr ""
msgid "InProductMarketing|It's also possible to simply %{external_repo_link} in order to take advantage of GitLab's CI/CD."
msgstr ""
+msgid "InProductMarketing|Keep your code quality high by defining who should approve merge requests and how many approvals are required."
+msgstr ""
+
msgid "InProductMarketing|Launch GitLab CI/CD in 20 minutes or less"
msgstr ""
+msgid "InProductMarketing|Lower cost of development"
+msgstr ""
+
+msgid "InProductMarketing|Make it easier to collaborate on high-level ideas by grouping related issues in an epic."
+msgstr ""
+
msgid "InProductMarketing|Making the switch? It's easier than you think to import your projects into GitLab. Move %{github_link}, or import something %{bitbucket_link}."
msgstr ""
msgid "InProductMarketing|Master the art of importing!"
msgstr ""
+msgid "InProductMarketing|Merge request approval rule"
+msgstr ""
+
msgid "InProductMarketing|Move on to easily creating a Pages website %{ci_template_link}"
msgstr ""
msgid "InProductMarketing|Multiple owners, confusing workstreams? We've got you covered"
msgstr ""
+msgid "InProductMarketing|Multiple required approvers"
+msgstr ""
+
msgid "InProductMarketing|Need an alternative to importing?"
msgstr ""
@@ -18615,18 +19004,33 @@ msgstr ""
msgid "InProductMarketing|Our tool brings all the things together"
msgstr ""
+msgid "InProductMarketing|Protect your web application by using DAST to examine for vulnerabilities in deployed environments."
+msgstr ""
+
msgid "InProductMarketing|Rapid development, simplified"
msgstr ""
msgid "InProductMarketing|Reduce Security & Compliance Risk"
msgstr ""
+msgid "InProductMarketing|Require multiple approvers on a merge request, so you know it's in good shape before it's merged."
+msgstr ""
+
+msgid "InProductMarketing|Roadmaps"
+msgstr ""
+
+msgid "InProductMarketing|Scoped labels"
+msgstr ""
+
msgid "InProductMarketing|Security that's integrated into your development lifecycle"
msgstr ""
msgid "InProductMarketing|Sometimes you're not ready to make a full transition to a new tool. If you're not ready to fully commit, %{mirroring_link} gives you a safe way to try out GitLab in parallel with your current tool."
msgstr ""
+msgid "InProductMarketing|Speed. Efficiency. Trust."
+msgstr ""
+
msgid "InProductMarketing|Spin up an autoscaling runner in GitLab"
msgstr ""
@@ -18636,6 +19040,9 @@ msgstr ""
msgid "InProductMarketing|Start a Self-Managed trial"
msgstr ""
+msgid "InProductMarketing|Start a free trial"
+msgstr ""
+
msgid "InProductMarketing|Start a free trial of GitLab Ultimate – no credit card required"
msgstr ""
@@ -18702,6 +19109,9 @@ msgstr ""
msgid "InProductMarketing|To understand and get the most out of GitLab, start at the beginning and %{project_link}. In GitLab, repositories are part of a project, so after you've created your project you can go ahead and %{repo_link}."
msgstr ""
+msgid "InProductMarketing|Track completed issues in a chart, so you can see how a milestone is progressing at a glance."
+msgstr ""
+
msgid "InProductMarketing|Try GitLab Ultimate for free"
msgstr ""
@@ -18738,6 +19148,9 @@ msgstr ""
msgid "InProductMarketing|Very easy"
msgstr ""
+msgid "InProductMarketing|Visualize your epics and milestones in a timeline."
+msgstr ""
+
msgid "InProductMarketing|Want to host GitLab on your servers?"
msgstr ""
@@ -18759,6 +19172,9 @@ msgstr ""
msgid "InProductMarketing|YouTube"
msgstr ""
+msgid "InProductMarketing|Your software, deployed your way"
+msgstr ""
+
msgid "InProductMarketing|Your teams can be more efficient"
msgstr ""
@@ -18879,9 +19295,18 @@ msgstr ""
msgid "IncidentManagement|No incidents to display."
msgstr ""
+msgid "IncidentManagement|None"
+msgstr ""
+
msgid "IncidentManagement|Open"
msgstr ""
+msgid "IncidentManagement|Page your team with escalation policies"
+msgstr ""
+
+msgid "IncidentManagement|Paged"
+msgstr ""
+
msgid "IncidentManagement|Published"
msgstr ""
@@ -18891,6 +19316,9 @@ msgstr ""
msgid "IncidentManagement|Severity"
msgstr ""
+msgid "IncidentManagement|Status"
+msgstr ""
+
msgid "IncidentManagement|There are no closed incidents"
msgstr ""
@@ -18909,6 +19337,9 @@ msgstr ""
msgid "IncidentManagement|Unpublished"
msgstr ""
+msgid "IncidentManagement|Use escalation policies to automatically page your team when incidents are created."
+msgstr ""
+
msgid "IncidentSettings|Activate \"time to SLA\" countdown timer"
msgstr ""
@@ -18954,7 +19385,10 @@ msgstr ""
msgid "Incidents"
msgstr ""
-msgid "Incidents|Add a URL"
+msgid "Incidents|Add image details"
+msgstr ""
+
+msgid "Incidents|Add text or a link to display with your image. If you don't add either, the file name displays instead."
msgstr ""
msgid "Incidents|Drop or %{linkStart}upload%{linkEnd} a metric screenshot to attach it to the incident"
@@ -18969,10 +19403,10 @@ msgstr ""
msgid "Incidents|There was an issue loading metric images."
msgstr ""
-msgid "Incidents|There was an issue uploading your image."
+msgid "Incidents|There was an issue updating your image."
msgstr ""
-msgid "Incidents|You can optionally add a URL to link users to the original graph."
+msgid "Incidents|There was an issue uploading your image."
msgstr ""
msgid "Incident|Alert details"
@@ -18981,9 +19415,18 @@ msgstr ""
msgid "Incident|Are you sure you wish to delete this image?"
msgstr ""
+msgid "Incident|Delete image"
+msgstr ""
+
msgid "Incident|Deleting %{filename}"
msgstr ""
+msgid "Incident|Edit image text or link"
+msgstr ""
+
+msgid "Incident|Editing %{filename}"
+msgstr ""
+
msgid "Incident|Metrics"
msgstr ""
@@ -19253,12 +19696,18 @@ msgstr ""
msgid "Integrations|Branches for which notifications are to be sent"
msgstr ""
+msgid "Integrations|Clear if using a self-signed certificate."
+msgstr ""
+
msgid "Integrations|Comment detail:"
msgstr ""
msgid "Integrations|Comment settings:"
msgstr ""
+msgid "Integrations|Connection details"
+msgstr ""
+
msgid "Integrations|Connection failed. Please check your settings."
msgstr ""
@@ -19283,6 +19732,9 @@ msgstr ""
msgid "Integrations|Enable GitLab.com slash commands in a Slack workspace."
msgstr ""
+msgid "Integrations|Enable SSL verification"
+msgstr ""
+
msgid "Integrations|Enable comments"
msgstr ""
@@ -19361,6 +19813,9 @@ msgstr ""
msgid "Integrations|Return to GitLab for Jira"
msgstr ""
+msgid "Integrations|SSL verification"
+msgstr ""
+
msgid "Integrations|Save settings?"
msgstr ""
@@ -19406,9 +19861,6 @@ msgstr ""
msgid "Integrations|Use default settings"
msgstr ""
-msgid "Integrations|When you mention a Jira issue in a commit or merge request, GitLab creates a remote link and comment (if enabled)."
-msgstr ""
-
msgid "Integrations|You can now close this window and return to the GitLab for Jira application."
msgstr ""
@@ -19433,9 +19885,6 @@ msgstr ""
msgid "Integrations|can't exceed %{recipients_limit}"
msgstr ""
-msgid "Interactive developer security education."
-msgstr ""
-
msgid "Interactive mode"
msgstr ""
@@ -19925,6 +20374,9 @@ msgstr ""
msgid "IssueAnalytics|Assignees"
msgstr ""
+msgid "IssueAnalytics|Created by"
+msgstr ""
+
msgid "IssueAnalytics|Due date"
msgstr ""
@@ -19937,9 +20389,6 @@ msgstr ""
msgid "IssueAnalytics|Milestone"
msgstr ""
-msgid "IssueAnalytics|Opened by"
-msgstr ""
-
msgid "IssueAnalytics|Status"
msgstr ""
@@ -20063,10 +20512,10 @@ msgstr ""
msgid "IssuesAnalytics|Avg/Month:"
msgstr ""
-msgid "IssuesAnalytics|Issues opened"
+msgid "IssuesAnalytics|Issues created"
msgstr ""
-msgid "IssuesAnalytics|Issues opened per month"
+msgid "IssuesAnalytics|Issues created per month"
msgstr ""
msgid "IssuesAnalytics|Last 12 months"
@@ -20093,6 +20542,9 @@ msgstr ""
msgid "It looks like you have some draft commits in this branch."
msgstr ""
+msgid "It looks like you're attempting to activate your subscription. Use %{a_start}the Subscription page%{a_end} instead."
+msgstr ""
+
msgid "It may be several days before you see feature usage data."
msgstr ""
@@ -20321,6 +20773,9 @@ msgstr ""
msgid "JiraConnect|You can now close this window and return to Jira."
msgstr ""
+msgid "JiraConnect|You don't have permission to create branches for this project. Select a different project or contact the project owner for access. %{linkStart}Learn more.%{linkEnd}"
+msgstr ""
+
msgid "JiraRequest|A connection error occurred while connecting to Jira. Try your request again."
msgstr ""
@@ -20369,13 +20824,13 @@ msgstr ""
msgid "JiraService|Define the type of Jira issue to create from a vulnerability."
msgstr ""
-msgid "JiraService|Displaying Jira issues while leaving the GitLab issue functionality enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
+msgid "JiraService|Displaying Jira issues while leaving GitLab issues also enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
msgstr ""
-msgid "JiraService|Enable Jira issues"
+msgid "JiraService|Enable Jira issue creation from vulnerabilities"
msgstr ""
-msgid "JiraService|Enable Jira issues creation from vulnerabilities"
+msgid "JiraService|Enable Jira issues"
msgstr ""
msgid "JiraService|Enable Jira transitions"
@@ -20492,16 +20947,19 @@ msgstr ""
msgid "JiraService|View Jira issues in GitLab"
msgstr ""
-msgid "JiraService|Warning: All GitLab users that have access to this GitLab project are able to view all issues from the Jira project specified below."
+msgid "JiraService|Warning: All GitLab users with access to this GitLab project can view all issues from the Jira project you select."
msgstr ""
msgid "JiraService|Web URL"
msgstr ""
-msgid "JiraService|Work on Jira issues without leaving GitLab. Adds a Jira menu to access your list of Jira issues and view any issue as read-only."
+msgid "JiraService|When a Jira issue is mentioned in a commit or merge request, a remote link and comment (if enabled) will be created."
+msgstr ""
+
+msgid "JiraService|Work on Jira issues without leaving GitLab. Add a Jira menu to access a read-only list of your Jira issues."
msgstr ""
-msgid "JiraService|You need to configure Jira before enabling this integration. For more details, read the %{jira_doc_link_start}Jira integration documentation%{link_end}."
+msgid "JiraService|You must configure Jira before enabling this integration. %{jira_doc_link_start}Learn more.%{link_end}"
msgstr ""
msgid "Job"
@@ -20513,9 +20971,6 @@ msgstr ""
msgid "Job Failed #%{build_id}"
msgstr ""
-msgid "Job ID"
-msgstr ""
-
msgid "Job artifact"
msgstr ""
@@ -20582,9 +21037,27 @@ msgstr ""
msgid "Jobs|You're about to retry a job that failed because it attempted to deploy code that is older than the latest deployment. Retrying this job could result in overwriting the environment with the older source code."
msgstr ""
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source} into %{target}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{ref}"
+msgstr ""
+
+msgid "Job|Are you sure you want to erase this job log and artifacts?"
+msgstr ""
+
msgid "Job|Browse"
msgstr ""
+msgid "Job|Cancel"
+msgstr ""
+
msgid "Job|Complete Raw"
msgstr ""
@@ -20594,6 +21067,9 @@ msgstr ""
msgid "Job|Erase job log and artifacts"
msgstr ""
+msgid "Job|Finished at"
+msgstr ""
+
msgid "Job|Job artifacts"
msgstr ""
@@ -20606,7 +21082,7 @@ msgstr ""
msgid "Job|Keep"
msgstr ""
-msgid "Job|Pipeline"
+msgid "Job|Retry"
msgstr ""
msgid "Job|Scroll to bottom"
@@ -20618,6 +21094,9 @@ msgstr ""
msgid "Job|Show complete raw"
msgstr ""
+msgid "Job|Status"
+msgstr ""
+
msgid "Job|The artifacts were removed"
msgstr ""
@@ -20645,21 +21124,12 @@ msgstr ""
msgid "Job|delayed"
msgstr ""
-msgid "Job|for"
-msgstr ""
-
-msgid "Job|into"
-msgstr ""
-
msgid "Job|manual"
msgstr ""
msgid "Job|triggered"
msgstr ""
-msgid "Job|with"
-msgstr ""
-
msgid "Join Zoom meeting"
msgstr ""
@@ -20762,9 +21232,6 @@ msgstr ""
msgid "Ki"
msgstr ""
-msgid "Kontra"
-msgstr ""
-
msgid "Kroki"
msgstr ""
@@ -21088,6 +21555,9 @@ msgstr ""
msgid "Learn more about Auto DevOps"
msgstr ""
+msgid "Learn more about GitLab"
+msgstr ""
+
msgid "Learn more about Needs relationships"
msgstr ""
@@ -21415,9 +21885,18 @@ msgstr ""
msgid "Licenses|Displays licenses detected in the project, based on the %{linkStart}latest successful%{linkEnd} scan"
msgstr ""
+msgid "Licenses|Drag your license file here or %{linkStart}click to upload%{linkEnd}."
+msgstr ""
+
+msgid "Licenses|Drop your license file to start the upload."
+msgstr ""
+
msgid "Licenses|Error fetching the license list. Please check your network connection and try again."
msgstr ""
+msgid "Licenses|Error: You are trying to upload something other than a file"
+msgstr ""
+
msgid "Licenses|License Compliance"
msgstr ""
@@ -21436,6 +21915,9 @@ msgstr ""
msgid "Licenses|Specified policies in this project"
msgstr ""
+msgid "Licenses|The file could not be uploaded."
+msgstr ""
+
msgid "Licenses|The license list details information about the licenses used within your project."
msgstr ""
@@ -21469,11 +21951,6 @@ msgstr ""
msgid "Limit the size of Sidekiq jobs stored in Redis."
msgstr ""
-msgid "Limited to showing %d event at most"
-msgid_plural "Limited to showing %d events at most"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Limiting mode"
msgstr ""
@@ -21483,6 +21960,9 @@ msgstr ""
msgid "Link"
msgstr ""
+msgid "Link (optional)"
+msgstr ""
+
msgid "Link Prometheus monitoring to GitLab."
msgstr ""
@@ -21519,6 +21999,9 @@ msgstr ""
msgid "Linked emails (%{email_count})"
msgstr ""
+msgid "Linked epics"
+msgstr ""
+
msgid "Linked issues"
msgstr ""
@@ -21546,6 +22029,15 @@ msgstr ""
msgid "List of all merge commits"
msgstr ""
+msgid "List of environments for this project"
+msgstr ""
+
+msgid "List of suitable GCP locations"
+msgstr ""
+
+msgid "List of users allowed to exceed the rate limit."
+msgstr ""
+
msgid "List options"
msgstr ""
@@ -21765,6 +22257,9 @@ msgstr ""
msgid "Maintenance mode"
msgstr ""
+msgid "Make adjustments to how your GitLab instance is set up."
+msgstr ""
+
msgid "Make and review changes in the browser with the Web IDE"
msgstr ""
@@ -21909,6 +22404,12 @@ msgstr ""
msgid "MarkdownEditor|Add italic text (%{modifier_key}I)"
msgstr ""
+msgid "MarkdownEditor|Add strikethrough text (%{modifierKey}⇧X)"
+msgstr ""
+
+msgid "MarkdownEditor|Add strikethrough text (%{modifier_key}⇧X)"
+msgstr ""
+
msgid "Marked For Deletion At - %{deletion_time}"
msgstr ""
@@ -22170,6 +22671,9 @@ msgstr ""
msgid "Maximum push size (MB)"
msgstr ""
+msgid "Maximum requests per 10 minutes per user"
+msgstr ""
+
msgid "Maximum requests per minute"
msgstr ""
@@ -22260,6 +22764,19 @@ msgstr ""
msgid "Members of a group may only view projects they have permission to access"
msgstr ""
+msgid "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seat in use and will be billed for the overage."
+msgid_plural "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seats in use and will be billed for the overage."
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "MembersOverage|You are about to incur additional charges"
+msgstr ""
+
+msgid "MembersOverage|Your subscription includes %d seat."
+msgid_plural "MembersOverage|Your subscription includes %d seats."
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Membership"
msgstr ""
@@ -22464,9 +22981,6 @@ msgstr ""
msgid "Merge request not merged"
msgstr ""
-msgid "Merge request pipelines 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 merge request pipelines."
-msgstr ""
-
msgid "Merge request reports"
msgstr ""
@@ -22563,13 +23077,13 @@ msgstr ""
msgid "MergeRequests|Create issue to resolve thread"
msgstr ""
-msgid "MergeRequests|Failed to squash. Should be done manually."
+msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Saving the comment failed"
+msgid "MergeRequests|Squashing failed: Squash the commits locally, resolve any conflicts, then push the branch."
msgstr ""
-msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
+msgid "MergeRequests|Squashing not allowed: This project doesn't allow you to squash commits when merging."
msgstr ""
msgid "MergeRequests|Thread stays resolved"
@@ -23410,6 +23924,18 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "MrList|Assigned to %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from assignee %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from reviewer %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Review requested from %{name}, go to their profile."
+msgstr ""
+
msgid "Multi-project"
msgstr ""
@@ -23443,7 +23969,7 @@ msgstr ""
msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "My Awesome Group"
+msgid "My awesome group"
msgstr ""
msgid "My company or team"
@@ -24065,9 +24591,6 @@ msgstr ""
msgid "No available branches"
msgstr ""
-msgid "No available groups to fork the project."
-msgstr ""
-
msgid "No branches found"
msgstr ""
@@ -24278,6 +24801,9 @@ msgstr ""
msgid "No ref selected"
msgstr ""
+msgid "No regions configured"
+msgstr ""
+
msgid "No related merge requests found."
msgstr ""
@@ -25082,6 +25608,9 @@ msgstr ""
msgid "Only reCAPTCHA v2 is supported:"
msgstr ""
+msgid "Only required if not using role instance credentials."
+msgstr ""
+
msgid "Only use lowercase letters, numbers, and underscores."
msgstr ""
@@ -25106,9 +25635,6 @@ msgstr ""
msgid "Open a CLI and connect to the cluster you want to install the agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
-msgid "Open epics"
-msgstr ""
-
msgid "Open errors"
msgstr ""
@@ -25148,8 +25674,8 @@ msgstr ""
msgid "Opened issues"
msgstr ""
-msgid "OpenedNDaysAgo|Opened"
-msgstr "Malfermita"
+msgid "OpenedNDaysAgo|Created"
+msgstr ""
msgid "Opens in a new window"
msgstr ""
@@ -25193,9 +25719,6 @@ msgstr ""
msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
-msgid "Optional."
-msgstr ""
-
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
msgstr ""
@@ -25984,6 +26507,9 @@ msgstr ""
msgid "PerformanceBar|Memory"
msgstr ""
+msgid "PerformanceBar|Memory report"
+msgstr ""
+
msgid "PerformanceBar|Redis calls"
msgstr ""
@@ -26017,18 +26543,12 @@ msgstr ""
msgid "PerformanceBar|wall"
msgstr ""
-msgid "Performs a rebase but skips triggering a new pipeline"
-msgstr ""
-
msgid "Period in seconds"
msgstr ""
msgid "Permalink"
msgstr ""
-msgid "Permanently delete project"
-msgstr ""
-
msgid "Permanently remove group"
msgstr ""
@@ -26299,6 +26819,51 @@ msgstr ""
msgid "PipelineStatusTooltip|Pipeline: %{ci_status}"
msgstr ""
+msgid "PipelineWizardDefaultCommitMessage|Add %{filename}"
+msgstr ""
+
+msgid "PipelineWizardDefaultCommitMessage|Update %{filename}"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|At least one entry is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This field is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This value is not valid"
+msgstr ""
+
+msgid "PipelineWizardListWidget|add another step"
+msgstr ""
+
+msgid "PipelineWizardListWidget|remove step"
+msgstr ""
+
+msgid "PipelineWizard|Commit"
+msgstr ""
+
+msgid "PipelineWizard|Commit Message"
+msgstr ""
+
+msgid "PipelineWizard|Commit changes to your file"
+msgstr ""
+
+msgid "PipelineWizard|Commit file to Branch"
+msgstr ""
+
+msgid "PipelineWizard|Commit your new file"
+msgstr ""
+
+msgid "PipelineWizard|The file has been committed."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem committing the changes."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem while checking whether your file already exists in the specified branch."
+msgstr ""
+
msgid "Pipelines"
msgstr "Ĉenstabloj"
@@ -26413,7 +26978,7 @@ msgstr ""
msgid "Pipelines|Project cache successfully reset."
msgstr ""
-msgid "Pipelines|Revoke"
+msgid "Pipelines|Revoke trigger"
msgstr ""
msgid "Pipelines|Something went wrong while cleaning runners cache."
@@ -26458,6 +27023,12 @@ msgstr ""
msgid "Pipelines|This is a child pipeline within the parent pipeline"
msgstr ""
+msgid "Pipelines|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipelines|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipelines|This pipeline will run code originating from a forked project merge request. This means that the code can potentially have security considerations like exposing CI variables."
msgstr ""
@@ -26500,9 +27071,6 @@ msgstr ""
msgid "Pipelines|Your changes have been successfully committed. Now redirecting to the new merge request page."
msgstr ""
-msgid "Pipelines|detached"
-msgstr ""
-
msgid "Pipelines|error"
msgstr ""
@@ -26512,10 +27080,13 @@ msgstr ""
msgid "Pipelines|latest"
msgstr ""
-msgid "Pipelines|stuck"
+msgid "Pipelines|merge request"
msgstr ""
-msgid "Pipelines|train"
+msgid "Pipelines|merge train"
+msgstr ""
+
+msgid "Pipelines|stuck"
msgstr ""
msgid "Pipelines|yaml invalid"
@@ -26647,6 +27218,12 @@ msgstr ""
msgid "Pipeline|This change will not change the overall test coverage if merged."
msgstr ""
+msgid "Pipeline|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipeline|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipeline|Trigger author"
msgstr ""
@@ -26671,6 +27248,12 @@ msgstr ""
msgid "Pipeline|for"
msgstr ""
+msgid "Pipeline|merge request"
+msgstr ""
+
+msgid "Pipeline|merge train"
+msgstr ""
+
msgid "Pipeline|on"
msgstr ""
@@ -26809,9 +27392,6 @@ msgstr ""
msgid "Please enter a valid time interval"
msgstr ""
-msgid "Please enter or upload a valid license."
-msgstr ""
-
msgid "Please enter your current password."
msgstr ""
@@ -26920,9 +27500,6 @@ msgstr ""
msgid "Please type %{phrase_code} to proceed or close this modal to cancel."
msgstr ""
-msgid "Please type the following to confirm:"
-msgstr ""
-
msgid "Please use this form to report to the admin users who create spam issues, comments or behave inappropriately."
msgstr ""
@@ -26950,12 +27527,27 @@ msgstr ""
msgid "Policies"
msgstr ""
+msgid "Policy '%{escalation_policy_name}' does not exist."
+msgstr ""
+
msgid "Policy management project does have any policies in %{policy_path}"
msgstr ""
msgid "Policy project doesn't exist"
msgstr ""
+msgid "PolicyRuleMultiSelect|%{firstLabel} +%{numberOfAdditionalLabels} more"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|All %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select all"
+msgstr ""
+
msgid "Polling interval multiplier"
msgstr ""
@@ -27184,6 +27776,9 @@ msgstr ""
msgid "Private projects can be created in your personal namespace with:"
msgstr ""
+msgid "Problem with %{name} command: %{message}."
+msgstr ""
+
msgid "Proceed"
msgstr ""
@@ -27658,6 +28253,9 @@ msgstr ""
msgid "Progress"
msgstr ""
+msgid "Progress tracking"
+msgstr ""
+
msgid "Project"
msgstr ""
@@ -27889,6 +28487,9 @@ msgstr ""
msgid "ProjectQualitySummary|Failure"
msgstr ""
+msgid "ProjectQualitySummary|Get insight into the overall percentage of tests in your project that succeed, fail and are skipped."
+msgstr ""
+
msgid "ProjectQualitySummary|Latest pipeline results"
msgstr ""
@@ -27907,6 +28508,12 @@ msgstr ""
msgid "ProjectQualitySummary|See project Code Coverage Statistics"
msgstr ""
+msgid "ProjectQualitySummary|Set up test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|Set up test runs (opens in a new tab)"
+msgstr ""
+
msgid "ProjectQualitySummary|Skipped"
msgstr ""
@@ -28183,13 +28790,19 @@ msgstr ""
msgid "ProjectSettings|LFS objects from this repository are available to forks. %{linkStart}How do I remove them?%{linkEnd}"
msgstr ""
+msgid "ProjectSettings|Learn about commit history."
+msgstr ""
+
+msgid "ProjectSettings|Leave empty to use default template."
+msgstr ""
+
msgid "ProjectSettings|Manage who can see the project in the public access directory."
msgstr ""
msgid "ProjectSettings|Manages large files such as audio, video, and graphics files."
msgstr ""
-msgid "ProjectSettings|Maximum 500 characters."
+msgid "ProjectSettings|Maximum %{maxLength} characters."
msgstr ""
msgid "ProjectSettings|Merge checks"
@@ -28330,6 +28943,9 @@ msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
msgstr ""
+msgid "ProjectSettings|The default template will be applied on save."
+msgstr ""
+
msgid "ProjectSettings|These checks must pass before merge requests can be merged."
msgstr ""
@@ -28384,6 +29000,9 @@ msgstr ""
msgid "ProjectSettings|What are badges?"
msgstr ""
+msgid "ProjectSettings|What are merge trains?"
+msgstr ""
+
msgid "ProjectSettings|When merge request pipelines are enabled in the CI/CD configuration file, pipelines validate the combined results of the source and target branches. %{link_start}How to configure merge request pipelines?%{link_end}"
msgstr ""
@@ -28501,6 +29120,9 @@ msgstr ""
msgid "Projects are organized into groups"
msgstr ""
+msgid "Projects are where you store your code, access issues, wiki and other features of GitLab."
+msgstr ""
+
msgid "Projects contributed to"
msgstr ""
@@ -28516,12 +29138,6 @@ msgstr ""
msgid "Projects to index"
msgstr ""
-msgid "Projects will be permanently deleted after a %{waiting_period}-day waiting period."
-msgstr ""
-
-msgid "Projects will be permanently deleted immediately."
-msgstr ""
-
msgid "Projects with critical vulnerabilities"
msgstr ""
@@ -28606,6 +29222,9 @@ msgstr ""
msgid "ProjectsNew|Import project"
msgstr ""
+msgid "ProjectsNew|Include a Getting Started README"
+msgstr ""
+
msgid "ProjectsNew|Initialize repository with a README"
msgstr ""
@@ -28621,6 +29240,9 @@ msgstr ""
msgid "ProjectsNew|Project description %{tag_start}(optional)%{tag_end}"
msgstr ""
+msgid "ProjectsNew|Recommended if you're new to GitLab"
+msgstr ""
+
msgid "ProjectsNew|Run CI/CD for external repository"
msgstr ""
@@ -29038,6 +29660,9 @@ msgstr ""
msgid "ProtectedBranch|Unprotect"
msgstr ""
+msgid "ProtectedBranch|Unprotect branch"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
@@ -29065,6 +29690,9 @@ msgstr ""
msgid "ProtectedEnvironment|Protected Environment (%{protected_environments_count})"
msgstr ""
+msgid "ProtectedEnvironment|Required approvals"
+msgstr ""
+
msgid "ProtectedEnvironment|Select an environment"
msgstr ""
@@ -29086,10 +29714,13 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|Unprotect tag"
+msgstr ""
+
msgid "ProtectedTags|default"
msgstr ""
-msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
+msgid "ProtectedTag|By default, protected tags restrict who can modify the tag."
msgstr ""
msgid "ProtectedTag|Learn more."
@@ -29152,6 +29783,9 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Public projects are an easy way to allow everyone to have read-only access."
+msgstr ""
+
msgid "Publish to status page"
msgstr ""
@@ -29308,9 +29942,6 @@ msgstr ""
msgid "QualitySummary|Project quality"
msgstr ""
-msgid "Quarters"
-msgstr ""
-
msgid "Query"
msgstr ""
@@ -29395,6 +30026,9 @@ msgstr ""
msgid "Read more about project permissions %{help_link_open}here%{help_link_close}"
msgstr ""
+msgid "Read more about related epics"
+msgstr ""
+
msgid "Read more about related issues"
msgstr ""
@@ -29425,10 +30059,7 @@ msgstr ""
msgid "Rebase source branch on the target branch."
msgstr ""
-msgid "Rebase without CI"
-msgstr ""
-
-msgid "Rebases and triggers a pipeline"
+msgid "Rebase without pipeline"
msgstr ""
msgid "Recaptcha verified?"
@@ -29479,9 +30110,6 @@ msgstr ""
msgid "Reconfigure"
msgstr ""
-msgid "Recovering projects"
-msgstr ""
-
msgid "Recovery Codes"
msgstr ""
@@ -29541,6 +30169,12 @@ msgstr ""
msgid "Regex pattern"
msgstr ""
+msgid "Region"
+msgstr ""
+
+msgid "Regions"
+msgstr ""
+
msgid "Register"
msgstr ""
@@ -29771,9 +30405,6 @@ msgstr ""
msgid "Remove all or specific reviewer(s)"
msgstr ""
-msgid "Remove approver"
-msgstr ""
-
msgid "Remove approvers"
msgstr ""
@@ -29789,6 +30420,9 @@ msgstr ""
msgid "Remove attention request"
msgstr ""
+msgid "Remove attention request(s)"
+msgstr ""
+
msgid "Remove avatar"
msgstr ""
@@ -29927,6 +30561,9 @@ msgstr ""
msgid "Removed an issue from an epic."
msgstr ""
+msgid "Removed attention from %{users_sentence}."
+msgstr ""
+
msgid "Removed attention request from @%{username}"
msgstr ""
@@ -29978,6 +30615,9 @@ msgstr ""
msgid "Removes an issue from an epic."
msgstr ""
+msgid "Removes attention from %{users_sentence}."
+msgstr ""
+
msgid "Removes parent epic %{epic_ref}."
msgstr ""
@@ -30089,6 +30729,9 @@ msgstr ""
msgid "Report abuse to admin"
msgstr ""
+msgid "Report is generating and will be sent to your email address."
+msgstr ""
+
msgid "Reported %{timeAgo} by %{reportedBy}"
msgstr ""
@@ -30378,6 +31021,15 @@ msgstr ""
msgid "Request attention"
msgstr ""
+msgid "Request attention from %{users_sentence}."
+msgstr ""
+
+msgid "Request attention from assignee or reviewer"
+msgstr ""
+
+msgid "Request attention from assignee(s) or reviewer(s)"
+msgstr ""
+
msgid "Request attention to review"
msgstr ""
@@ -30402,6 +31054,9 @@ msgstr ""
msgid "Requested %{time_ago}"
msgstr ""
+msgid "Requested attention from %{users_sentence}."
+msgstr ""
+
msgid "Requested attention from @%{username}"
msgstr ""
@@ -30616,6 +31271,9 @@ msgstr ""
msgid "Restore project"
msgstr ""
+msgid "Restoring projects"
+msgstr ""
+
msgid "Restoring the group will prevent the group, its subgroups and projects from being removed on this date."
msgstr ""
@@ -30646,6 +31304,9 @@ msgstr ""
msgid "Retry"
msgstr ""
+msgid "Retry failed jobs"
+msgstr ""
+
msgid "Retry job"
msgstr ""
@@ -30693,9 +31354,6 @@ msgstr ""
msgid "Review changes"
msgstr ""
-msgid "Review requested from %{name}"
-msgstr ""
-
msgid "Review requests for you"
msgstr ""
@@ -30860,6 +31518,9 @@ msgstr ""
msgid "Runners|Assigned Group"
msgstr ""
+msgid "Runners|Assigned Projects (%{projectCount})"
+msgstr ""
+
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30929,6 +31590,9 @@ msgstr ""
msgid "Runners|Instance"
msgstr ""
+msgid "Runners|Jobs"
+msgstr ""
+
msgid "Runners|Last contact"
msgstr ""
@@ -31022,9 +31686,6 @@ msgstr ""
msgid "Runners|Runner %{name} was deleted"
msgstr ""
-msgid "Runners|Runner ID"
-msgstr ""
-
msgid "Runners|Runner assigned to project."
msgstr ""
@@ -31172,6 +31833,9 @@ msgstr ""
msgid "Runners|stale"
msgstr ""
+msgid "Runner|This runner has not run any jobs."
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -31286,6 +31950,24 @@ msgstr ""
msgid "Saving project."
msgstr ""
+msgid "ScanResultPolicy|%{ifLabelStart}if%{ifLabelEnd} %{scanners} scan in an open merge request targeting the %{branches} branch(es) finds %{vulnerabilitiesAllowed} or more %{severities} vulnerabilities that are %{vulnerabilityStates}"
+msgstr ""
+
+msgid "ScanResultPolicy|%{thenLabelStart}Then%{thenLabelEnd} Require approval from %{approvalsRequired} of the following approvers: %{approvers}"
+msgstr ""
+
+msgid "ScanResultPolicy|add an approver"
+msgstr ""
+
+msgid "ScanResultPolicy|scanners"
+msgstr ""
+
+msgid "ScanResultPolicy|severity levels"
+msgstr ""
+
+msgid "ScanResultPolicy|vulnerability states"
+msgstr ""
+
msgid "Scanner"
msgstr ""
@@ -31418,6 +32100,9 @@ msgstr ""
msgid "Search for a user"
msgstr ""
+msgid "Search for an emoji"
+msgstr ""
+
msgid "Search for projects, issues, etc."
msgstr ""
@@ -31605,18 +32290,12 @@ msgstr ""
msgid "Secret Detection"
msgstr ""
-msgid "Secret access key"
-msgstr ""
-
msgid "Secret token"
msgstr ""
msgid "Secure token that identifies an external storage request."
msgstr ""
-msgid "SecureCodeWarrior"
-msgstr ""
-
msgid "Security"
msgstr ""
@@ -31641,9 +32320,6 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "Security training with guide and learning pathways."
-msgstr ""
-
msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
@@ -31746,7 +32422,7 @@ msgstr ""
msgid "SecurityConfiguration|Manage corpus"
msgstr ""
-msgid "SecurityConfiguration|Manage corpus files used as mutation sources in coverage fuzzing."
+msgid "SecurityConfiguration|Manage corpus files used as seed inputs with coverage-guided fuzzing."
msgstr ""
msgid "SecurityConfiguration|Manage profiles for use by DAST scans."
@@ -31812,15 +32488,15 @@ msgstr ""
msgid "SecurityOrchestration|.yaml preview"
msgstr ""
-msgid "SecurityOrchestration|Action"
-msgstr ""
-
msgid "SecurityOrchestration|Actions"
msgstr ""
msgid "SecurityOrchestration|Add rule"
msgstr ""
+msgid "SecurityOrchestration|After dismissing the alert, the information will never be shown again."
+msgstr ""
+
msgid "SecurityOrchestration|All policies"
msgstr ""
@@ -31836,7 +32512,7 @@ msgstr ""
msgid "SecurityOrchestration|Description"
msgstr ""
-msgid "SecurityOrchestration|Disabled"
+msgid "SecurityOrchestration|Don't show the alert anymore"
msgstr ""
msgid "SecurityOrchestration|Edit policy"
@@ -31845,13 +32521,13 @@ msgstr ""
msgid "SecurityOrchestration|Edit policy project"
msgstr ""
-msgid "SecurityOrchestration|Enabled"
+msgid "SecurityOrchestration|Empty policy name"
msgstr ""
-msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Enabled"
msgstr ""
-msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
msgstr ""
msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
@@ -31860,7 +32536,7 @@ msgstr ""
msgid "SecurityOrchestration|Invalid policy type"
msgstr ""
-msgid "SecurityOrchestration|Latest scan"
+msgid "SecurityOrchestration|Latest scan run against %{agent}"
msgstr ""
msgid "SecurityOrchestration|Network"
@@ -31869,15 +32545,27 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No actions defined - policy will not run."
+msgstr ""
+
+msgid "SecurityOrchestration|No description"
+msgstr ""
+
msgid "SecurityOrchestration|No rules defined - policy will not run."
msgstr ""
+msgid "SecurityOrchestration|Not enabled"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
msgid "SecurityOrchestration|Policies"
msgstr ""
+msgid "SecurityOrchestration|Policy Type"
+msgstr ""
+
msgid "SecurityOrchestration|Policy cannot be enabled for non-existing branches (%{branches})"
msgstr ""
@@ -31902,10 +32590,13 @@ msgstr ""
msgid "SecurityOrchestration|Require %{approvals} %{plural} from %{approvers} if any of the following occur:"
msgstr ""
-msgid "SecurityOrchestration|Rule"
+msgid "SecurityOrchestration|Rules"
msgstr ""
-msgid "SecurityOrchestration|Rules"
+msgid "SecurityOrchestration|Runs %{actions} and %{lastAction} scans"
+msgstr ""
+
+msgid "SecurityOrchestration|Runs a %{action} scan"
msgstr ""
msgid "SecurityOrchestration|Scan Execution"
@@ -31965,6 +32656,9 @@ msgstr ""
msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
+msgid "SecurityOrchestration|This view only shows scan results for the agent %{agent}. You can view scan results for all agents in the %{linkStart}Operational Vulnerabilities tab of the vulnerability report%{linkEnd}."
+msgstr ""
+
msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
@@ -32019,9 +32713,6 @@ msgstr ""
msgid "SecurityOrchestration|users with ids"
msgstr ""
-msgid "SecurityOrchestration|view results"
-msgstr ""
-
msgid "SecurityOrchestration|vulnerabilities"
msgstr ""
@@ -32691,22 +33382,19 @@ 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|In order to start using functions as a service, you must first install Knative on your Kubernetes cluster. %{linkStart}More information%{linkEnd}"
-msgstr ""
-
msgid "Serverless|Learn more about Serverless"
msgstr ""
msgid "Serverless|No functions available"
msgstr ""
-msgid "Serverless|Sign up for First Look"
+msgid "Serverless|Serverless was %{linkStart}deprecated%{linkEnd} in GitLab 14.3."
+msgstr ""
+
+msgid "Serverless|Serverless was %{postLinkStart}deprecated%{postLinkEnd}. But if you opt to use it, you must install Knative in your Kubernetes cluster first. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "Serverless|The deploy job has not finished."
@@ -32718,9 +33406,6 @@ 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 ""
@@ -32736,9 +33421,6 @@ msgstr ""
msgid "Service Account Key"
msgstr ""
-msgid "Service Accounts"
-msgstr ""
-
msgid "Service Accounts keys authorize GitLab to deploy your Google Cloud project"
msgstr ""
@@ -32748,10 +33430,10 @@ msgstr ""
msgid "Service Desk allows people to create issues in your GitLab instance without their own user account. It provides a unique email address for end users to create issues in a project. Replies can be sent either through the GitLab interface or by email. End users only see threads through email."
msgstr ""
-msgid "Service Usage Data"
+msgid "Service account generated successfully"
msgstr ""
-msgid "Service account generated successfully"
+msgid "Service accounts"
msgstr ""
msgid "Service ping is disabled in your configuration file, and cannot be enabled through this form."
@@ -32895,6 +33577,9 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
+msgid "Set the per-user rate limit for getting a user by ID via the API."
+msgstr ""
+
msgid "Set the per-user rate limit for notes created by web or API requests."
msgstr ""
@@ -33074,6 +33759,9 @@ msgstr ""
msgid "Shared runners details"
msgstr ""
+msgid "Shared runners enabled cannot be enabled until a valid credit card is on file"
+msgstr ""
+
msgid "Shared runners help link"
msgstr ""
@@ -33131,6 +33819,9 @@ msgstr ""
msgid "Show all issues."
msgstr ""
+msgid "Show all milestones"
+msgstr ""
+
msgid "Show all test cases."
msgstr ""
@@ -33167,6 +33858,9 @@ msgstr ""
msgid "Show file contents"
msgstr ""
+msgid "Show group milestones"
+msgstr ""
+
msgid "Show labels"
msgstr ""
@@ -33182,6 +33876,12 @@ msgstr ""
msgid "Show open epics"
msgstr ""
+msgid "Show project milestones"
+msgstr ""
+
+msgid "Show sub-group milestones"
+msgstr ""
+
msgid "Show the Closed list"
msgstr ""
@@ -33191,11 +33891,6 @@ msgstr ""
msgid "Show whitespace changes"
msgstr ""
-msgid "Showing %d event"
-msgid_plural "Showing %d events"
-msgstr[0] "Estas montrata %d evento"
-msgstr[1] "Estas montrataj %d eventoj"
-
msgid "Showing %{conflict} between %{sourceBranch} and %{targetBranch}"
msgstr ""
@@ -33255,12 +33950,6 @@ msgstr ""
msgid "Sidebar|None"
msgstr ""
-msgid "Sidebar|Only numeral characters allowed"
-msgstr ""
-
-msgid "Sidebar|Weight"
-msgstr ""
-
msgid "Sidekiq job compression threshold (bytes)"
msgstr ""
@@ -33423,6 +34112,9 @@ msgstr ""
msgid "Slack logo"
msgstr ""
+msgid "SlackIntegration|Are you sure you want to remove this project from the Slack application?"
+msgstr ""
+
msgid "SlackIntegration|GitLab for Slack"
msgstr ""
@@ -33432,6 +34124,9 @@ msgstr ""
msgid "SlackIntegration|Project alias"
msgstr ""
+msgid "SlackIntegration|Remove project"
+msgstr ""
+
msgid "SlackIntegration|Select a GitLab project to link with your Slack workspace."
msgstr ""
@@ -33576,9 +34271,6 @@ msgstr ""
msgid "Something went wrong trying to load issue contacts."
msgstr ""
-msgid "Something went wrong when creating a work item. Please try again"
-msgstr ""
-
msgid "Something went wrong when reordering designs. Please try again"
msgstr ""
@@ -33672,9 +34364,6 @@ msgstr ""
msgid "Something went wrong while inserting your image. Please try again."
msgstr ""
-msgid "Something went wrong while merging this merge request. Please try again."
-msgstr ""
-
msgid "Something went wrong while obtaining the Let's Encrypt certificate."
msgstr ""
@@ -33996,10 +34685,10 @@ 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."
+msgid "SourcegraphAdmin|Learn more."
msgstr ""
-msgid "SourcegraphAdmin|More information"
+msgid "SourcegraphAdmin|Only public projects have code intelligence enabled and communicate with Sourcegraph."
msgstr ""
msgid "SourcegraphAdmin|Save changes"
@@ -34008,7 +34697,7 @@ msgstr ""
msgid "SourcegraphAdmin|Sourcegraph URL"
msgstr ""
-msgid "SourcegraphAdmin|e.g. https://sourcegraph.example.com"
+msgid "SourcegraphAdmin|https://sourcegraph.example.com"
msgstr ""
msgid "SourcegraphPreferences|This feature is experimental and currently limited to certain projects."
@@ -34143,6 +34832,9 @@ msgstr ""
msgid "Start date"
msgstr ""
+msgid "Start free trial"
+msgstr ""
+
msgid "Start merge train"
msgstr ""
@@ -34173,6 +34865,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started escalation for this incident."
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -34185,6 +34880,9 @@ msgstr ""
msgid "Starts at (UTC)"
msgstr ""
+msgid "Starts escalations for this incident"
+msgstr ""
+
msgid "Starts on"
msgstr ""
@@ -34446,6 +35144,9 @@ msgstr ""
msgid "Strikethrough"
msgstr ""
+msgid "Strikethrough text"
+msgstr ""
+
msgid "Subgroup information"
msgstr ""
@@ -34680,6 +35381,21 @@ msgstr ""
msgid "Subscriptions"
msgstr ""
+msgid "Subscriptions|Chat with sales"
+msgstr ""
+
+msgid "Subscriptions|Close"
+msgstr ""
+
+msgid "Subscriptions|Not ready to buy yet?"
+msgstr ""
+
+msgid "Subscriptions|Start a free trial"
+msgstr ""
+
+msgid "Subscriptions|We understand. Maybe you have some questions for our sales team, or maybe you'd like to try some of the paid features first. What would you like to do?"
+msgstr ""
+
msgid "Subscription|Your subscription for %{strong}%{namespace_name}%{strong_close} has expired and you are now on %{pricing_link_start}the GitLab Free tier%{pricing_link_end}. Don't worry, your data is safe. Get in touch with our support team (%{support_email}). They'll gladly help with your subscription renewal."
msgstr ""
@@ -34890,6 +35606,9 @@ msgstr ""
msgid "SuperSonics|Maximum users"
msgstr ""
+msgid "SuperSonics|Offline cloud"
+msgstr ""
+
msgid "SuperSonics|Paste your activation code"
msgstr ""
@@ -34956,6 +35675,12 @@ msgstr ""
msgid "SuperSonics|You do not have an active subscription"
msgstr ""
+msgid "SuperSonics|You have a future dated license"
+msgstr ""
+
+msgid "SuperSonics|You have added a license that activates on %{date}. Please see the subscription history table below for more details."
+msgstr ""
+
msgid "SuperSonics|You have successfully added a license that activates on %{date}. Please see the subscription history table below for more details."
msgstr ""
@@ -35115,6 +35840,9 @@ msgstr ""
msgid "Tag name is required"
msgstr ""
+msgid "Tag push"
+msgstr ""
+
msgid "Tag push events"
msgstr ""
@@ -35217,6 +35945,9 @@ msgstr ""
msgid "TagsPage|protected"
msgstr ""
+msgid "Take a look at the documentation to discover all of GitLab’s capabilities."
+msgstr ""
+
msgid "Target Branch"
msgstr "Cela branĉo"
@@ -35619,6 +36350,9 @@ msgstr ""
msgid "Tests"
msgstr ""
+msgid "Text (optional)"
+msgstr ""
+
msgid "Text added to the body of all email messages. %{character_limit} character limit"
msgstr ""
@@ -35669,6 +36403,9 @@ msgstr ""
msgid "The CSV export will be created in the background. Once finished, it will be sent to %{email} in an attachment."
msgstr ""
+msgid "The CSV export you requested of all user memberships is attached to this email."
+msgstr ""
+
msgid "The GitLab subscription service (customers.gitlab.com) is currently experiencing an outage. You can monitor the status and get updates at %{linkStart}status.gitlab.com%{linkEnd}."
msgstr ""
@@ -35744,6 +36481,9 @@ 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 epic"
+msgstr ""
+
msgid "The current issue"
msgstr ""
@@ -35905,6 +36645,9 @@ msgstr ""
msgid "The latest pipeline for this merge request has failed."
msgstr ""
+msgid "The license key is invalid."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -35920,6 +36663,9 @@ msgstr ""
msgid "The license was successfully uploaded and will be active from %{starts_at}. You can see the details below."
msgstr ""
+msgid "The license you uploaded is invalid. If the issue persists, contact support at %{link}."
+msgstr ""
+
msgid "The list creation wizard is already open"
msgstr ""
@@ -36541,10 +37287,13 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} and everything this project contains. %{strongOpen}There is no going back%{strongClose}"
+msgstr ""
+
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains."
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}on %{date}%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains. %{strongOpen}There is no going back.%{strongClose}"
msgstr ""
msgid "This action will %{strongOpen}permanently remove%{strongClose} %{codeOpen}%{group}%{codeClose} %{strongOpen}immediately%{strongClose}."
@@ -36673,9 +37422,6 @@ msgstr ""
msgid "This file was modified for readability, and can't accept suggestions. Edit it directly."
msgstr ""
-msgid "This forked project has the following:"
-msgstr ""
-
msgid "This form is disabled in preview"
msgstr ""
@@ -36688,7 +37434,7 @@ msgstr ""
msgid "This group can't be removed because it is linked to a subscription. To remove this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
-msgid "This group can't be transfered because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
+msgid "This group can't be transferred because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
msgid "This group cannot be invited to a project inside a group with enforced SSO"
@@ -36715,6 +37461,9 @@ 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 incident is already escalated with '%{escalation_policy_name}'."
+msgstr ""
+
msgid "This invitation was sent to %{mail_to_invite_email}, but you are signed in as %{link_to_current_user} with email %{mail_to_current_user}."
msgstr ""
@@ -36733,9 +37482,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 merge train pipeline"
-msgstr ""
-
msgid "This is a private email address %{helpIcon} generated just for you. Anyone who has it can create issues or merge requests as if they were you. If that happens, %{resetLinkStart}reset this token%{resetLinkEnd}."
msgstr ""
@@ -36757,6 +37503,12 @@ msgstr ""
msgid "This is your current session"
msgstr ""
+msgid "This issue cannot be assigned to a confidential epic because it is public."
+msgstr ""
+
+msgid "This issue cannot be made public because it belongs to a confidential epic."
+msgstr ""
+
msgid "This issue is confidential and should only be visible to team members with at least Reporter access."
msgstr ""
@@ -36874,6 +37626,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 branch is protected from force push."
+msgstr ""
+
msgid "This merge request cannot be rebased while there are conflicts."
msgstr ""
@@ -36925,9 +37680,15 @@ msgstr ""
msgid "This pipeline was triggered by a schedule."
msgstr ""
+msgid "This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project"
msgstr ""
+msgid "This project can be restored until %{date}."
+msgstr ""
+
msgid "This project cannot be %{visibilityLevel} because the visibility of %{openShowLink}%{name}%{closeShowLink} is %{visibility}. To make this project %{visibilityLevel}, you must first %{openEditLink}change the visibility%{closeEditLink} of the parent group."
msgstr ""
@@ -36946,6 +37707,9 @@ msgstr ""
msgid "This project is %{strongStart}NOT%{strongEnd} a fork, and has the following:"
msgstr ""
+msgid "This project is %{strongStart}NOT%{strongEnd} a fork. This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -37637,6 +38401,9 @@ msgstr ""
msgid "Today"
msgstr ""
+msgid "Todos count"
+msgstr ""
+
msgid "Todos|Are you looking for things to do? Take a look at %{strongStart}%{openIssuesLinkStart}open issues%{openIssuesLinkEnd}%{strongEnd}, contribute to %{strongStart}%{mergeRequestLinkStart}a merge request%{mergeRequestLinkEnd}%{mergeRequestLinkEnd}%{strongEnd}, or mention someone in a comment to automatically assign them a new to-do item."
msgstr ""
@@ -37910,10 +38677,8 @@ msgstr ""
msgid "Trending"
msgstr ""
-msgid "Trials|%{planName} Trial %{enDash} %{num} day left"
-msgid_plural "Trials|%{planName} Trial %{enDash} %{num} days left"
-msgstr[0] ""
-msgstr[1] ""
+msgid "Trials|%{planName} Trial"
+msgstr ""
msgid "Trials|Compare all plans"
msgstr ""
@@ -37921,6 +38686,9 @@ msgstr ""
msgid "Trials|Create a new group to start your GitLab Ultimate trial."
msgstr ""
+msgid "Trials|Day %{daysUsed}/%{duration}"
+msgstr ""
+
msgid "Trials|Go back to GitLab"
msgstr ""
@@ -38170,7 +38938,7 @@ msgstr ""
msgid "URL is triggered when repository is updated"
msgstr ""
-msgid "URL must be percent-encoded if neccessary."
+msgid "URL must be percent-encoded if necessary."
msgstr ""
msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
@@ -38389,6 +39157,9 @@ msgstr ""
msgid "Unlock account"
msgstr ""
+msgid "Unlock more features with GitLab Ultimate"
+msgstr ""
+
msgid "Unlock the discussion"
msgstr ""
@@ -38452,6 +39223,9 @@ msgstr ""
msgid "Unsubscribes from this %{quick_action_target}."
msgstr ""
+msgid "Unsupported sort value."
+msgstr ""
+
msgid "Unsupported todo type passed. Supported todo types are: %{todo_types}"
msgstr ""
@@ -38680,6 +39454,9 @@ msgstr ""
msgid "UsageQuota|File attachments and smaller design graphics."
msgstr ""
+msgid "UsageQuota|From %{storage_enforcement_date} storage limits will apply to this namespace. View and manage your usage in %{strong_start}Group Settings &gt; Usage quotas%{strong_end}."
+msgstr ""
+
msgid "UsageQuota|Git repository."
msgstr ""
@@ -38740,6 +39517,9 @@ msgstr ""
msgid "UsageQuota|Storage type"
msgstr ""
+msgid "UsageQuota|Storage used"
+msgstr ""
+
msgid "UsageQuota|This is the total amount of storage used across your projects within this namespace."
msgstr ""
@@ -38935,6 +39715,12 @@ msgstr ""
msgid "Use hashed storage paths for newly created and renamed repositories. Always enabled since 13.0."
msgstr ""
+msgid "Use issue count"
+msgstr ""
+
+msgid "Use issue weight"
+msgstr ""
+
msgid "Use one line per URI"
msgstr ""
@@ -39316,6 +40102,9 @@ msgstr ""
msgid "Users"
msgstr ""
+msgid "Users API rate limit"
+msgstr ""
+
msgid "Users can launch a development environment from a GitLab browser tab when the %{linkStart}Gitpod%{linkEnd} integration is enabled."
msgstr ""
@@ -39641,6 +40430,9 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View group pipeline usage quota"
+msgstr ""
+
msgid "View incident details at"
msgstr ""
@@ -39793,6 +40585,9 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
+msgid "Vulnerability"
+msgstr ""
+
msgid "Vulnerability Report"
msgstr ""
@@ -39844,6 +40639,9 @@ msgstr ""
msgid "VulnerabilityManagement|An unverified non-confirmed finding"
msgstr ""
+msgid "VulnerabilityManagement|At least one identifier is required"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -39853,12 +40651,24 @@ msgstr ""
msgid "VulnerabilityManagement|Create Jira issue"
msgstr ""
+msgid "VulnerabilityManagement|Enter a name"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE code"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE identifier URL"
+msgstr ""
+
msgid "VulnerabilityManagement|Fetching linked Jira issues"
msgstr ""
msgid "VulnerabilityManagement|Manually add a vulnerability entry into the vulnerability report."
msgstr ""
+msgid "VulnerabilityManagement|Name is a required field"
+msgstr ""
+
msgid "VulnerabilityManagement|Needs triage"
msgstr ""
@@ -39874,6 +40684,18 @@ msgstr ""
msgid "VulnerabilityManagement|Select a method"
msgstr ""
+msgid "VulnerabilityManagement|Select a severity level"
+msgstr ""
+
+msgid "VulnerabilityManagement|Select a status"
+msgstr ""
+
+msgid "VulnerabilityManagement|Severity is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Something went wrong while creating vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -39898,6 +40720,12 @@ msgstr ""
msgid "VulnerabilityManagement|Something went wrong, could not update vulnerability state."
msgstr ""
+msgid "VulnerabilityManagement|Status is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Submit vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Summary, detailed description, steps to reproduce, etc."
msgstr ""
@@ -40093,6 +40921,9 @@ msgstr ""
msgid "WARNING:"
msgstr ""
+msgid "WARNING: This snippet contains hidden files which might be used to mask malicious behavior. Exercise caution if cloning and executing code from this snippet."
+msgstr ""
+
msgid "Wait for the file to load to copy its contents"
msgstr ""
@@ -40312,6 +41143,15 @@ msgstr ""
msgid "Webhooks|An issue is created, updated, closed, or reopened."
msgstr ""
+msgid "Webhooks|Are you sure you want to delete this group hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this project hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this webhook?"
+msgstr ""
+
msgid "Webhooks|Comments"
msgstr ""
@@ -40321,6 +41161,9 @@ msgstr ""
msgid "Webhooks|Confidential issues events"
msgstr ""
+msgid "Webhooks|Delete webhook"
+msgstr ""
+
msgid "Webhooks|Deployment events"
msgstr ""
@@ -40554,6 +41397,9 @@ msgstr ""
msgid "Wiki"
msgstr ""
+msgid "Wiki page"
+msgstr ""
+
msgid "Wiki page was successfully created."
msgstr ""
@@ -40659,7 +41505,7 @@ msgstr ""
msgid "WikiPageConflictMessage|Someone edited the page the same time you did. Please check out %{wikiLinkStart}the page%{wikiLinkEnd} and make sure your changes will not unintentionally remove theirs."
msgstr ""
-msgid "WikiPage|An error occured while trying to render the content editor. Please try again later."
+msgid "WikiPage|An error occurred while trying to render the content editor. Please try again later."
msgstr ""
msgid "WikiPage|Are you sure you want to switch back to the classic editor?"
@@ -40818,6 +41664,18 @@ msgstr ""
msgid "WorkItem|New Task"
msgstr ""
+msgid "WorkItem|Something went wrong when creating a work item. Please try again"
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching the work item. Please try again."
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching work item types. Please try again"
+msgstr ""
+
+msgid "WorkItem|Type"
+msgstr ""
+
msgid "WorkItem|Work Items"
msgstr ""
@@ -40884,7 +41742,10 @@ msgstr ""
msgid "You are about to add %{usersTag} people to the discussion. They will all receive a notification."
msgstr ""
-msgid "You are about to permanently delete this project"
+msgid "You are about to delete this forked project containing:"
+msgstr ""
+
+msgid "You are about to delete this project containing:"
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."
@@ -40905,6 +41766,9 @@ msgstr ""
msgid "You are attempting to update a file that has changed since you started editing it."
msgstr ""
+msgid "You are billed if you exceed this number. %{qsrOverageLinkStart}How does billing work?%{qsrOverageLinkEnd}"
+msgstr ""
+
msgid "You are connected to the Prometheus server, but there is currently no data to display."
msgstr ""
@@ -40962,6 +41826,9 @@ msgstr ""
msgid "You are not authorized to update this scanner profile"
msgstr ""
+msgid "You are not authorized to upload metric images"
+msgstr ""
+
msgid "You are now impersonating %{username}"
msgstr ""
@@ -41115,9 +41982,6 @@ msgstr ""
msgid "You can only upload one design when dropping onto an existing design."
msgstr ""
-msgid "You can recover this project until %{date}"
-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 ""
@@ -41166,9 +42030,6 @@ msgstr ""
msgid "You cannot write to this read-only GitLab instance."
msgstr ""
-msgid "You can’t %{tag_start}edit%{tag_end} files directly in this project. Fork this project and submit a merge request with your changes."
-msgstr ""
-
msgid "You can’t edit files directly in this project. Fork this project and submit a merge request with your changes."
msgstr ""
@@ -41321,9 +42182,6 @@ msgstr ""
msgid "You have not added any approvers. Start by adding users or groups."
msgstr ""
-msgid "You have reached your project limit"
-msgstr "Vi ne povas krei pliajn projektojn"
-
msgid "You have set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
@@ -41354,12 +42212,6 @@ msgstr ""
msgid "You must have maintainer access to force delete a lock"
msgstr ""
-msgid "You must have permission to create a project in a group before forking."
-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 ""
@@ -41765,7 +42617,7 @@ msgstr ""
msgid "Your public email will be displayed on your public profile."
msgstr ""
-msgid "Your request for access could not be processed: %{error_meesage}"
+msgid "Your request for access could not be processed: %{error_message}"
msgstr ""
msgid "Your request for access has been queued for review."
@@ -41948,6 +42800,9 @@ msgstr ""
msgid "archived:"
msgstr ""
+msgid "artifacts"
+msgstr ""
+
msgid "assign yourself"
msgstr ""
@@ -41977,6 +42832,9 @@ msgstr[1] ""
msgid "branch name"
msgstr ""
+msgid "builds"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -42400,6 +43258,9 @@ msgstr ""
msgid "contact with same email already exists in group hierarchy"
msgstr ""
+msgid "container registry images"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -42439,6 +43300,9 @@ msgstr ""
msgid "data"
msgstr ""
+msgid "database"
+msgstr ""
+
msgid "date must not be after 9999-12-31"
msgstr ""
@@ -42462,9 +43326,6 @@ msgstr ""
msgid "design"
msgstr ""
-msgid "detached"
-msgstr ""
-
msgid "disabled"
msgstr ""
@@ -42713,7 +43574,7 @@ msgstr ""
msgid "is not a valid X509 certificate."
msgstr ""
-msgid "is not allowed for sign-up."
+msgid "is not allowed for sign-up. Please use your regular email address."
msgstr ""
msgid "is not allowed for this group."
@@ -42725,7 +43586,7 @@ msgstr ""
msgid "is not allowed since the group is not top-level group."
msgstr ""
-msgid "is not allowed."
+msgid "is not allowed. Please use your regular email address."
msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
@@ -42812,6 +43673,9 @@ msgstr ""
msgid "level: %{level}"
msgstr ""
+msgid "lfs objects"
+msgstr ""
+
msgid "limit of %{project_limit} reached"
msgstr ""
@@ -43031,6 +43895,9 @@ msgstr ""
msgid "mrWidget|Merge blocked: pipeline must succeed. It's waiting for a manual action to continue."
msgstr ""
+msgid "mrWidget|Merge blocked: pipeline must succeed. Push a commit that fixes the failure, or %{linkStart}learn about other solutions.%{linkEnd}"
+msgstr ""
+
msgid "mrWidget|Merge blocked: this merge request must be approved."
msgstr ""
@@ -43148,9 +44015,6 @@ msgstr ""
msgid "mrWidget|The changes were not merged into"
msgstr ""
-msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -43298,9 +44162,6 @@ msgstr ""
msgid "open issue"
msgstr ""
-msgid "opened %{timeAgo}"
-msgstr ""
-
msgid "or"
msgstr ""
@@ -43312,6 +44173,12 @@ msgid_plural "out of %d total tests"
msgstr[0] ""
msgstr[1] ""
+msgid "packages"
+msgstr ""
+
+msgid "pages"
+msgstr ""
+
msgid "parent"
msgid_plural "parents"
msgstr[0] "patro"
@@ -43461,6 +44328,9 @@ msgid_plural "replies"
msgstr[0] ""
msgstr[1] ""
+msgid "repositories"
+msgstr ""
+
msgid "repository:"
msgstr ""
@@ -43581,12 +44451,18 @@ msgstr ""
msgid "tag name"
msgstr ""
+msgid "terraform states"
+msgstr ""
+
msgid "the correct format."
msgstr ""
msgid "the file"
msgstr ""
+msgid "the following epic(s)"
+msgstr ""
+
msgid "the following issue(s)"
msgstr ""
@@ -43599,21 +44475,12 @@ msgstr ""
msgid "this document"
msgstr ""
-msgid "this issue cannot be assigned to a confidential epic since it is public"
-msgstr ""
-
-msgid "this issue cannot be made public since it belongs to a confidential epic"
-msgstr ""
-
msgid "time summary"
msgstr ""
msgid "toggle collapse"
msgstr ""
-msgid "train"
-msgstr ""
-
msgid "triggered"
msgstr ""
@@ -43742,3 +44609,6 @@ msgstr ""
msgid "{project}"
msgstr ""
+msgid "✔"
+msgstr ""
+
diff --git a/locale/es/gitlab.po b/locale/es/gitlab.po
index 6e4a6a19c43..b218f571799 100644
--- a/locale/es/gitlab.po
+++ b/locale/es/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: es-ES\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2022-02-02 15:44\n"
+"PO-Revision-Date: 2022-03-01 20:38\n"
msgid " %{start} to %{end}"
msgstr " %{start} hasta %{end}"
@@ -118,18 +118,18 @@ msgstr[1] "%d URLs analizadas"
msgid "%d additional approver"
msgid_plural "%d additional approvers"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d aprobador adicional"
+msgstr[1] "%d aprobadores adicionales"
msgid "%d additional assignee"
msgid_plural "%d additional assignees"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d asignado adicional"
+msgstr[1] "%d asignados adicionales"
msgid "%d additional commenter"
msgid_plural "%d additional commenters"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d comentarista adicional"
+msgstr[1] "%d comentarios adicionales"
msgid "%d additional committer"
msgid_plural "%d additional committers"
@@ -146,6 +146,11 @@ msgid_plural "%d approvers (you've approved)"
msgstr[0] "%d aprobador (has aprobado)"
msgstr[1] "%d aprobadores (has aprobado)"
+msgid "%d assigned issue"
+msgid_plural "%d assigned issues"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] "%d archivo modificado"
@@ -421,8 +426,23 @@ msgid_plural "%d vulnerabilities dismissed"
msgstr[0] "%d vulnerabilidad descartada"
msgstr[1] "%d vulnerabilidades descartadas"
-msgid "%d vulnerability updated"
-msgid_plural "%d vulnerabilities updated"
+msgid "%d vulnerability set to confirmed"
+msgid_plural "%d vulnerabilities set to confirmed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to dismissed"
+msgid_plural "%d vulnerabilities set to dismissed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to needs triage"
+msgid_plural "%d vulnerabilities set to needs triage"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to resolved"
+msgid_plural "%d vulnerabilities set to resolved"
msgstr[0] ""
msgstr[1] ""
@@ -440,10 +460,10 @@ msgid "%{actionText} & %{openOrClose} %{noteable}"
msgstr "%{actionText} & %{openOrClose} %{noteable}"
msgid "%{actionText} & close %{noteable}"
-msgstr ""
+msgstr "%{actionText} & cerrar %{noteable}"
msgid "%{actionText} & reopen %{noteable}"
-msgstr ""
+msgstr "%{actionText} y reabrir %{noteable}"
msgid "%{address} is an invalid IP address range"
msgstr "%{address} no es en un rango de direcciones IP válido"
@@ -482,25 +502,25 @@ msgstr[0] ""
msgstr[1] ""
msgid "%{codeStart}type%{codeEnd} is deprecated and will be removed in 15.0. Use %{codeStart}stage%{codeEnd} instead. %{linkStart}Learn More %{linkEnd}"
-msgstr ""
+msgstr "%{codeStart}type%{codeEnd} está obsoleto y se eliminará en la versión 15.0. Utilice %{codeStart}stage%{codeEnd} en su lugar. %{linkStart}Aprenda más %{linkEnd}"
msgid "%{codeStart}types%{codeEnd} is deprecated and will be removed in 15.0. Use %{codeStart}stages%{codeEnd} instead. %{linkStart}Learn More %{linkEnd}"
-msgstr ""
+msgstr "%{codeStart}types%{codeEnd} está obsoleto y se eliminará en la versión 15.0. Utilice %{codeStart}stages%{codeEnd} en su lugar. %{linkStart}Aprenda más %{linkEnd}"
msgid "%{code_open}Masked:%{code_close} Hidden in job logs. Must match masking requirements."
-msgstr ""
+msgstr "%{code_open}Enmascarado:%{code_close} Oculto en los registros de trabajo. Debe coincidir con los requisitos de enmascaramiento."
msgid "%{code_open}Protected:%{code_close} Only exposed to protected branches or tags."
-msgstr ""
+msgstr "%{code_open}Protegido:%{code_close} Sólo expuesto a etiquetas o ramas protegidas."
msgid "%{commit_author_link} authored %{commit_authored_timeago}"
-msgstr ""
+msgstr "%{commit_author_link} creado %{commit_authored_timeago}"
msgid "%{commit_author_link} authored %{commit_authored_timeago} and %{commit_committer_avatar} %{commit_committer_link} committed %{commit_committer_timeago}"
-msgstr ""
+msgstr "%{commit_author_link} creado %{commit_authored_timeago} y %{commit_committer_avatar} %{commit_committer_link} creó el commit %{commit_committer_timeago}"
msgid "%{completedCount} completed weight"
-msgstr ""
+msgstr "%{completedCount} peso completado"
msgid "%{completedCount} of %{count} task completed"
msgid_plural "%{completedCount} of %{count} tasks completed"
@@ -510,6 +530,12 @@ msgstr[1] "%{completedCount} de %{count} tareas completadas"
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr "%{completedWeight} de %{totalWeight} del peso completado"
+msgid "%{completed} of %{total} issues closed"
+msgstr ""
+
+msgid "%{completed} of %{total} weight completed"
+msgstr ""
+
msgid "%{cores} cores"
msgstr "%{cores} núcleos"
@@ -590,16 +616,16 @@ msgid "%{description}- Sentry event: %{errorUrl}- First seen: %{firstSeen}- Last
msgstr "%{description}- Evento de Sentry: %{errorUrl}- Visto por primera vez: %{firstSeen}- Visto por última vez: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch. %{docs_link}"
-msgstr ""
+msgstr "%{doc_link_start}La búsqueda avanzada%{doc_link_end} está deshabilitada porque %{ref_elem} no es la rama predeterminada. %{docs_link}"
msgid "%{doc_link_start}Advanced search%{doc_link_end} is enabled."
-msgstr ""
+msgstr "%{doc_link_start}La búsqueda avanzada%{doc_link_end} está habilitada."
msgid "%{docs_link_start}Learn about visibility levels.%{docs_link_end}"
-msgstr ""
+msgstr "%{docs_link_start}Sobre los niveles de visibilidad.%{docs_link_end}"
msgid "%{docs_link_start}What is Large File Storage?%{docs_link_end}"
-msgstr ""
+msgstr "%{docs_link_start}¿Qué es el almacenamiento para grandes ficheros?%{docs_link_end}"
msgid "%{docs_link_start}What is two-factor authentication?%{docs_link_end}"
msgstr ""
@@ -653,7 +679,7 @@ msgid "%{group_name} group members"
msgstr "miembros del grupo %{group_name}"
msgid "%{group_name} is approaching the limit of available seats"
-msgstr ""
+msgstr "%{group_name} se acerca al límite de asientos disponibles"
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}."
@@ -737,7 +763,7 @@ msgid "%{label_for_message} unavailable"
msgstr "%{label_for_message} no disponible"
msgid "%{learn_more_link}."
-msgstr ""
+msgstr "%{learn_more_link}."
msgid "%{lessThan} 1 hour"
msgstr "%{lessThan} 1 hora"
@@ -752,7 +778,7 @@ msgid "%{level_name} is not allowed since the fork source project has lower visi
msgstr "%{level_name} no está permitido debido a que el fork del proyecto origen tiene menor visibilidad."
msgid "%{linkStart}Learn more.%{linkEnd}"
-msgstr ""
+msgstr "%{linkStart}Más información.%{linkEnd}"
msgid "%{link_start}Learn more%{link_end} about roles."
msgstr "%{link_start}Obtener más información%{link_end} sobre los roles."
@@ -764,7 +790,7 @@ msgid "%{link_start}Start the title with %{draft_snippet}%{link_end} to prevent
msgstr ""
msgid "%{link_start}Upload a license%{link_end} file or enter the license key you have received from GitLab Inc."
-msgstr ""
+msgstr "%{link_start}Cargue un archivo de licencia%{link_end} o introduzca la clave de licencia que recibió de GitLab Inc."
msgid "%{link_start}What information does GitLab Inc. collect?%{link_end}"
msgstr ""
@@ -818,7 +844,7 @@ msgid "%{name} is already being used for another emoji"
msgstr "%{name} ya está siendo utilizado para otro emoji"
msgid "%{name} is reserved for %{type} report type"
-msgstr ""
+msgstr "%{name} está reservado para %{type} tipo de informe"
msgid "%{name} is scheduled for %{action}"
msgstr "%{name} está programado para %{action}"
@@ -858,6 +884,9 @@ msgstr "%{openedEpics} abiertas, %{closedEpics} cerradas"
msgid "%{openedIssues} open, %{closedIssues} closed"
msgstr "%{openedIssues} abiertas, %{closedIssues} cerradas"
+msgid "%{percentage}%% issues closed"
+msgstr ""
+
msgid "%{percentage}%% weight completed"
msgstr "%{percentage}%% del peso completado"
@@ -909,7 +938,7 @@ msgid "%{rotation} has been recalculated with the remaining participants. Please
msgstr ""
msgid "%{runner} created %{timeago}"
-msgstr ""
+msgstr "%{runner} creado %{timeago}"
msgid "%{scope} results for term '%{term}'"
msgstr "%{scope} resultados para el término '%{term}'"
@@ -1287,6 +1316,9 @@ msgid_plural "- Users"
msgstr[0] "- Usuario"
msgstr[1] "- Usuarios"
+msgid "- of - issues closed"
+msgstr ""
+
msgid "- of - weight completed"
msgstr "- de - peso completado"
@@ -1429,7 +1461,7 @@ msgstr "10-19 contribuciones"
msgid "1000+"
msgstr "1000+"
-msgid "192.168.0.0/24"
+msgid "192.168.0.0/24 or 2001:0DB8:1234::/48"
msgstr ""
msgid "1st contribution!"
@@ -1490,7 +1522,7 @@ msgid "A .NET Core console application template, customizable for any .NET Core
msgstr "Una plantilla de aplicación de consola .NET Core, personalizable para cualquier proyecto .NET Core"
msgid "A CI/CD pipeline must run and be successful before merge."
-msgstr ""
+msgstr "Un pipeline CI/CD debe ejecutarse y completarse correctamente antes de hacer un merge."
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 todas las otras excelentes características de GitLab"
@@ -1511,7 +1543,7 @@ msgid "A Let's Encrypt SSL certificate can not be obtained until your domain is
msgstr "No se puede obtener un certificado SSL de Let's Encrypt hasta que se verifique su dominio."
msgid "A Metrics Dashboard menu item appears in the Monitoring section of the Admin Area."
-msgstr ""
+msgstr "Un elemento de menú del tablero de métricas aparece en la sección de monitorización del área de administración."
msgid "A basic page and serverless function that uses AWS Lambda, AWS API Gateway, and GitLab Pages"
msgstr "Una página básica y una función serverless que usa AWS Lambda, AWS API Gateway y GitLab Pages"
@@ -1562,7 +1594,7 @@ msgid "A merge request hasn't yet been merged"
msgstr ""
msgid "A new Auto DevOps pipeline has been created, go to the Pipelines page for details"
-msgstr ""
+msgstr "Se ha creado un nuevo pipeline de Auto DevOps,diríjase a la página de Pipelines para ver más detalles"
msgid "A new Release %{tag} for %{name} was published. Visit the %{release_link_start}Releases page%{release_link_end} to read more about it."
msgstr "Se publicó una nueva versión %{tag} para %{name}. Visite la página de %{release_link_start}versiones%{release_link_end} para obtener más información al respecto."
@@ -1574,19 +1606,19 @@ msgid "A new impersonation token has been created."
msgstr "Se ha creado un nuevo token de impersonación."
msgid "A non-confidential epic cannot be assigned to a confidential parent epic"
-msgstr ""
+msgstr "Una tarea épica no confidencial no se puede asignar a una tarea épica padre confidencial"
msgid "A plain HTML site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features"
-msgstr ""
+msgstr "Un sitio HTML simple que utiliza Netlify para CI/CD en lugar de GitLab, pero que mantiene todas las otras excelentes características de GitLab"
msgid "A platform value can be web, mob or app."
msgstr "Un valor de plataforma puede ser web, mob o aplicación."
msgid "A project boilerplate for Salesforce App development with Salesforce Developer tools"
-msgstr ""
+msgstr "Una plantilla de proyecto para el desarrollo de aplicaciones de Salesforce con las herramientas de desarrollo de Salesforce"
msgid "A project boilerplate for Tencent Serverless Framework that uses Next.js SSR"
-msgstr ""
+msgstr "Una plantilla de proyecto para Tencent Serverless Framework que utiliza Next.js SSR"
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 ""
@@ -1616,7 +1648,7 @@ msgid "A user with write access to the source branch selected this option"
msgstr "Un usuario con acceso de escritura a la rama origen seleccionó esta opción"
msgid "ACTION REQUIRED: Something went wrong while obtaining the Let's Encrypt certificate for GitLab Pages domain '%{domain}'"
-msgstr ""
+msgstr "ACCIÓN REQUERIDA: Se ha producido un error mientras se obtenía el certificado de Let's Encrypt para el dominio de GitLab Pages '%{domain}'"
msgid "API"
msgstr "API"
@@ -1741,14 +1773,14 @@ msgstr "folder/openapi.json"
msgid "AWS Access Key"
msgstr "AWS Access Key"
-msgid "AWS Access Key. Only required if not using role instance credentials"
-msgstr "Clave de acceso de AWS. Solo se requiere si no se están utilizando credenciales de instancia de rol"
-
msgid "AWS Secret Access Key"
msgstr "AWS Secret Access Key"
-msgid "AWS Secret Access Key. Only required if not using role instance credentials"
-msgstr "Clave de acceso secreta de AWS. Solo se requiere si no se utilizan credenciales de instancia de rol"
+msgid "AWS access key ID (Optional)"
+msgstr ""
+
+msgid "AWS secret access key (Optional)"
+msgstr ""
msgid "AWS service error: %{error}"
msgstr "Error de servicio de AWS: %{error}"
@@ -1807,9 +1839,6 @@ msgstr "Acceso denegado. Por favor, compruebe su nivel de acceso."
msgid "Access granted"
msgstr "Acceso permitido"
-msgid "Access key ID"
-msgstr ""
-
msgid "Access requests"
msgstr "Peticiones de acceso"
@@ -1952,7 +1981,7 @@ msgid "AccountValidation|unsubscribe"
msgstr "Cancelar suscripción"
msgid "AccountValidation|you may %{unsubscribe_link} at any time."
-msgstr ""
+msgstr "Puede %{unsubscribe_link} en cualquier momento."
msgid "Action"
msgstr "Acción"
@@ -1979,13 +2008,13 @@ msgid "Active Sessions"
msgstr "Sesiones activas"
msgid "Active chat names (%{count})"
-msgstr ""
+msgstr "Nombres de chat activos (%{count})"
msgid "Activity"
msgstr "Actividad"
-msgid "Activity|An error occured while retrieving activity. Reload the page to try again."
-msgstr "Se ha producido un error al recuperar la actividad. Por favor, recargue la página para volver a intentarlo."
+msgid "Activity|An error occurred while retrieving activity. Reload the page to try again."
+msgstr ""
msgid "Add"
msgstr "Añadir"
@@ -2012,7 +2041,7 @@ msgid "Add LICENSE"
msgstr "Añadir LICENSE"
msgid "Add New Site"
-msgstr ""
+msgstr "Añadir un nuevo sitio"
msgid "Add README"
msgstr "Añadir README"
@@ -2023,6 +2052,9 @@ msgstr "Añadir una reunión de Zoom"
msgid "Add a %{type}"
msgstr "Añadir un %{type}"
+msgid "Add a GCP region"
+msgstr ""
+
msgid "Add a GPG key"
msgstr "Añadir una clave GPG"
@@ -2039,13 +2071,13 @@ msgid "Add a bullet list"
msgstr "Añadir una lista de viñetas"
msgid "Add a collapsible section"
-msgstr ""
+msgstr "Añadir una sección colapsable"
msgid "Add a comment to this line"
msgstr "Añadir un comentario a esta línea"
msgid "Add a comment to this line or drag for multiple lines"
-msgstr ""
+msgstr "Añada un comentario a esta línea o arrastre para varias líneas"
msgid "Add a custom message with details about the instance's shared runners. The message is visible in group and project CI/CD settings, in the Runners section. Markdown is supported."
msgstr ""
@@ -2066,7 +2098,7 @@ msgid "Add a link"
msgstr "Añadir un enlace"
msgid "Add a link to Grafana"
-msgstr "Agregar un enlace a Grafana"
+msgstr "Añsdir un enlace a Grafana"
msgid "Add a new issue"
msgstr "Añadir una nueva incidencia"
@@ -2074,6 +2106,9 @@ msgstr "Añadir una nueva incidencia"
msgid "Add a numbered list"
msgstr "Añadir una lista numerada"
+msgid "Add a related epic"
+msgstr ""
+
msgid "Add a related issue"
msgstr "Añadir una incidencia relacionada"
@@ -2108,7 +2143,7 @@ msgid "Add another link"
msgstr "Añadir otro enlace"
msgid "Add approval rule"
-msgstr "Agregar una regla de aprobación"
+msgstr "Añadir una regla de aprobación"
msgid "Add approvers"
msgstr "Añadir aprobadores"
@@ -2180,13 +2215,16 @@ msgid "Add new application"
msgstr "Añadir una nueva aplicación"
msgid "Add new directory"
-msgstr "Agregar nuevo directorio"
+msgstr "Añadir nuevo directorio"
msgid "Add or remove previously merged commits"
msgstr ""
msgid "Add or subtract spent time"
-msgstr "Agregar o restar tiempo consumido"
+msgstr "Añadir o restar tiempo consumido"
+
+msgid "Add people"
+msgstr ""
msgid "Add previously merged commits"
msgstr ""
@@ -2204,7 +2242,7 @@ msgid "Add request manually"
msgstr "Añadir solicitud manualmente"
msgid "Add strikethrough text"
-msgstr "Agregar texto tachado"
+msgstr "Añadir texto tachado"
msgid "Add suggestion to batch"
msgstr "Añadir sugerencia para el lote"
@@ -2231,7 +2269,7 @@ msgid "Add to review"
msgstr "Añadir a revisión"
msgid "Add to tree"
-msgstr "Agregar al árbol"
+msgstr "Añadir al árbol"
msgid "Add topics to projects to help users find them."
msgstr ""
@@ -2243,7 +2281,7 @@ msgid "Add user(s) to the group:"
msgstr "Añadir usuario(s) al grupo:"
msgid "Add users to group"
-msgstr "Agregar usuarios al grupo"
+msgstr "Añadir usuarios al grupo"
msgid "Add variable"
msgstr "Añadir variable"
@@ -2254,14 +2292,17 @@ msgstr ""
msgid "Add webhook"
msgstr "Añadir webhook"
+msgid "Add your team members and others to GitLab."
+msgstr ""
+
msgid "Add/remove"
-msgstr "Agregar/eliminar"
+msgstr "Añadir/eliminar"
msgid "AddContextCommits|Add previously merged commits"
msgstr ""
msgid "AddContextCommits|Add/remove"
-msgstr "Añadir/eliminar"
+msgstr "AddContextCommits|Añadir/eliminar"
msgid "AddMember|Emails cannot be blank"
msgstr "Los correos electrónicos no pueden estar en blanco"
@@ -2345,7 +2386,7 @@ msgid "Adds a to do."
msgstr "Añade una tarea pendiente."
msgid "Adds an issue to an epic."
-msgstr "Agregar una incidencia a una tarea épica."
+msgstr "Añadir una incidencia a una tarea épica."
msgid "Adds email participant(s)."
msgstr "Añadir las direcciones de correo electrónico de los participantes"
@@ -2675,7 +2716,7 @@ msgid "AdminUsers|(Internal)"
msgstr "(Interno)"
msgid "AdminUsers|(Locked)"
-msgstr ""
+msgstr "(Bloqueado)"
msgid "AdminUsers|(Pending approval)"
msgstr "(Pendiente de aprobación)"
@@ -2714,7 +2755,7 @@ msgid "AdminUsers|Admin"
msgstr "Admin"
msgid "AdminUsers|Administrator"
-msgstr ""
+msgstr "Administrador"
msgid "AdminUsers|Admins"
msgstr "Administradores"
@@ -2732,7 +2773,7 @@ msgid "AdminUsers|Auditor"
msgstr "Auditor"
msgid "AdminUsers|Auditors have read-only access to all groups, projects, and users."
-msgstr ""
+msgstr "Los auditores tienen acceso de solo lectura a todos los grupos, proyectos y usuarios."
msgid "AdminUsers|Automatically marked as default internal user"
msgstr "Marcado automáticamente como usuario interno por defecto"
@@ -2771,7 +2812,7 @@ msgid "AdminUsers|Cannot unblock LDAP blocked users"
msgstr "No se pueden desbloquear los usuarios bloqueados de LDAP"
msgid "AdminUsers|Cohorts"
-msgstr ""
+msgstr "AdminUsers|Cohortes"
msgid "AdminUsers|Confirm user"
msgstr "Confirmar usuario"
@@ -2825,7 +2866,7 @@ msgid "AdminUsers|If you have any questions about this process please consult ou
msgstr ""
msgid "AdminUsers|Important information about usage on your GitLab instance"
-msgstr ""
+msgstr "AdminUsers|Información importante sobre el uso en su instancia de GitLab"
msgid "AdminUsers|Is using seat"
msgstr "Está utilizando un asiento"
@@ -2840,7 +2881,7 @@ msgid "AdminUsers|Learn more about %{link_start}banned users.%{link_end}"
msgstr ""
msgid "AdminUsers|Locked"
-msgstr ""
+msgstr "Bloqueado"
msgid "AdminUsers|Log in"
msgstr "Iniciar sesión"
@@ -2873,7 +2914,7 @@ msgid "AdminUsers|Regular"
msgstr "Habituales"
msgid "AdminUsers|Regular users have access to their groups and projects."
-msgstr ""
+msgstr "AdminUsers|Los usuarios normales tienen acceso a sus grupos y proyectos."
msgid "AdminUsers|Reject"
msgstr "Rechazar"
@@ -2900,13 +2941,13 @@ msgid "AdminUsers|Sort by"
msgstr "Ordenar por"
msgid "AdminUsers|The user can't access git repositories."
-msgstr ""
+msgstr "AdminUsers|El usuario no puede acceder a los repositorios de git."
msgid "AdminUsers|The user can't log in."
msgstr "El usuario no puede iniciar sesión."
msgid "AdminUsers|The user has unlimited access to all groups, projects, users, and features."
-msgstr ""
+msgstr "AdminUsers|El usuario tiene acceso ilimitado a todos los grupos, proyectos, usuarios y funciones."
msgid "AdminUsers|The user will be logged out"
msgstr "El usuario será desconectado"
@@ -2918,7 +2959,7 @@ msgid "AdminUsers|The user will not be able to access the API"
msgstr "El usuario no podrá acceder a la API"
msgid "AdminUsers|The user will not be able to use slash commands"
-msgstr ""
+msgstr "El usuario no podrá usar comandos de barra"
msgid "AdminUsers|The user will not receive any notifications"
msgstr "El usuario no recibirá ninguna notificación"
@@ -2975,7 +3016,7 @@ msgid "AdminUsers|What does this mean?"
msgstr "¿Qué significa esto?"
msgid "AdminUsers|When banned:"
-msgstr ""
+msgstr "AdminUsers|Cuando está prohibido:"
msgid "AdminUsers|When the user logs back in, their account will reactivate as a fully active account"
msgstr "Cuando el usuario vuelve a iniciar sesión, su cuenta se activará como una cuenta totalmente activa"
@@ -3076,12 +3117,6 @@ msgstr "Opciones de exportación avanzadas"
msgid "AdvancedSearch|Reindex required"
msgstr ""
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. Permanently deleting this project will %{strongStart}immediately delete%{strongEnd} its repositories and %{strongStart}all related resources%{strongEnd}, including issues, merge requests etc."
-msgstr ""
-
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. You will lose this project's repository and %{strongStart}all related resources%{strongEnd}, including issues and merge requests."
-msgstr ""
-
msgid "After a successful password update you will be redirected to login screen."
msgstr "Después de una actualización correcta de la contraseña, será redirigido a la pantalla de inicio de sesión."
@@ -3112,6 +3147,9 @@ msgstr "Clave de API de Akismet"
msgid "Akismet helps prevent the creation of spam issues in public projects."
msgstr ""
+msgid "Alert"
+msgstr ""
+
msgid "AlertManagement|Acknowledged"
msgstr "Confirmado"
@@ -3332,7 +3370,7 @@ msgid "AlertSettings|Integration successfully saved"
msgstr ""
msgid "AlertSettings|Name integration"
-msgstr ""
+msgstr "AlertSettings|Integración de nombres"
msgid "AlertSettings|Parse payload fields"
msgstr ""
@@ -3484,9 +3522,6 @@ msgstr "Todas las direcciones de correo electrónico se utilizarán para identif
msgid "All environments"
msgstr "Todos los entornos"
-msgid "All epics"
-msgstr "Todas las tareas épicas"
-
msgid "All groups and projects"
msgstr "Todos los grupos y proyectos"
@@ -3614,7 +3649,7 @@ msgid "Allows projects or subgroups in this group to override the global setting
msgstr ""
msgid "Allows you to add and manage Kubernetes clusters."
-msgstr "Le permite agregar y administrar clusters de Kubernetes."
+msgstr "Le permite añadir y administrar clusters de Kubernetes."
msgid "Almost there"
msgstr "¡Ya queda poco!"
@@ -3665,7 +3700,7 @@ msgid "An Enterprise User GitLab account has been created for you by your organi
msgstr ""
msgid "An administrator changed the password for your GitLab account on %{link_to}."
-msgstr ""
+msgstr "Un administrador cambió la contraseña de su cuenta de GitLab en %{link_to}."
msgid "An alert has been resolved in %{project_path}."
msgstr "Se ha resuelto una alerta en %{project_path}."
@@ -3776,10 +3811,10 @@ msgid "An error occurred while fetching codequality mr diff reports."
msgstr ""
msgid "An error occurred while fetching commit data."
-msgstr ""
+msgstr "Se ha producido un error al recuperar los datos del commit."
msgid "An error occurred while fetching commits. Retry the search."
-msgstr ""
+msgstr "Se ha producido un error al recuperar los commits. Vuelva a intentar la búsqueda."
msgid "An error occurred while fetching coverage reports."
msgstr "Se ha producido un error al recuperar los informes de cobertura."
@@ -3836,7 +3871,7 @@ msgid "An error occurred while fetching the latest pipeline."
msgstr "Se ha producido un error al obtener el último pipeline."
msgid "An error occurred while fetching the pipelines jobs."
-msgstr ""
+msgstr "Se ha producido un error al recuperar los trabajos de los pipelines."
msgid "An error occurred while fetching the releases. Please try again."
msgstr "Se ha producido un error al obtener las versiones. Por favor, inténtelo de nuevo."
@@ -3866,7 +3901,7 @@ 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 code owners."
-msgstr ""
+msgstr "Se ha producido un error al cargar los propietarios del código."
msgid "An error occurred while loading commit signatures"
msgstr "Se ha producido un error al cargar las firmas de los commits"
@@ -3890,7 +3925,7 @@ 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 projects."
-msgstr ""
+msgstr "Se ha producido un error al cargar los proyectos."
msgid "An error occurred while loading the Jobs tab."
msgstr ""
@@ -3899,7 +3934,7 @@ msgid "An error occurred while loading the Needs tab."
msgstr ""
msgid "An error occurred while loading the Test Reports tab."
-msgstr ""
+msgstr "Se ha producido un error al cargar la pestaña de informes de prueba."
msgid "An error occurred while loading the access tokens form, please try again."
msgstr "Se ha producido un error al cargar el formulario de tokens de acceso. Por favor, inténtelo de nuevo."
@@ -4057,10 +4092,10 @@ msgid "An example showing how to use Jsonnet with GitLab dynamic child pipelines
msgstr ""
msgid "An incident has been resolved in %{project_path}."
-msgstr ""
+msgstr "Se ha resuelto una incidencia en %{project_path}."
msgid "An incident has been triggered in %{project_path}."
-msgstr ""
+msgstr "Se ha disparado un incidente en %{project_path}."
msgid "An integer value is required for seconds"
msgstr ""
@@ -4223,12 +4258,15 @@ msgstr ""
msgid "ApplicationSettings|Approve users in the pending approval status?"
msgstr ""
-msgid "ApplicationSettings|By making this change, you will automatically approve %d user with the pending approval status."
-msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users with the pending approval status."
+msgid "ApplicationSettings|Approve users who are pending approval?"
+msgstr ""
+
+msgid "ApplicationSettings|By making this change, you will automatically approve %d user who is pending approval."
+msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users who are pending approval."
msgstr[0] ""
msgstr[1] ""
-msgid "ApplicationSettings|By making this change, you will automatically approve all users in pending approval status."
+msgid "ApplicationSettings|By making this change, you will automatically approve all users who are pending approval."
msgstr ""
msgid "ApplicationSettings|Denied domains for sign-ups"
@@ -4503,7 +4541,7 @@ msgid "ApprovalRule|Target branch"
msgstr "Branch de destino"
msgid "ApprovalRule|Try for free"
-msgstr ""
+msgstr "Pruébelo gratis"
msgid "ApprovalRule|Vulnerabilities allowed"
msgstr "Vulnerabilidades permitidas"
@@ -4515,7 +4553,7 @@ msgid "ApprovalSettings|Merge request approval settings have been updated."
msgstr ""
msgid "ApprovalSettings|Prevent approval by author"
-msgstr ""
+msgstr "Evitar la aprobación por parte del autor"
msgid "ApprovalSettings|Prevent approval by author."
msgstr ""
@@ -4634,10 +4672,10 @@ msgstr "Proyectos archivados"
msgid "Archiving the project will make it entirely read-only. It is hidden from the dashboard and doesn't show up in searches. %{strong_start}The repository cannot be committed to, and no issues, comments, or other entities can be created.%{strong_end} %{link_start}Learn more.%{link_end}"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to delete this project?"
+msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
+msgid "Are you absolutely sure?"
msgstr ""
msgid "Are you sure that you want to archive this project?"
@@ -4673,12 +4711,18 @@ msgstr "¿Esta seguro de que desea eliminar esto %{typeOfComment}?"
msgid "Are you sure you want to delete this SSH key?"
msgstr "¿Está seguro de que desea eliminar la clave SSH?"
+msgid "Are you sure you want to delete this comment?"
+msgstr ""
+
msgid "Are you sure you want to delete this deploy key?"
msgstr ""
msgid "Are you sure you want to delete this device? This action cannot be undone."
msgstr "¿Está seguro de que desea borrar este dispositivo? Esta acción no se puede deshacer."
+msgid "Are you sure you want to delete this label?"
+msgstr ""
+
msgid "Are you sure you want to delete this pipeline schedule?"
msgstr "¿Estás seguro que deseas eliminar esta programación del pipeline?"
@@ -4694,9 +4738,6 @@ msgstr "¿Está seguro de que desea descartar este comentario?"
msgid "Are you sure you want to discard your changes?"
msgstr "¿Está seguro de que desea descartar sus cambios?"
-msgid "Are you sure you want to erase this build?"
-msgstr "¿Estás seguro de que quieres borrar esta versión?"
-
msgid "Are you sure you want to import %d repository?"
msgid_plural "Are you sure you want to import %d repositories?"
msgstr[0] "¿Está seguro que desea importar el repositorio %d?"
@@ -4744,6 +4785,9 @@ msgstr "¿Está seguro de que desea eliminar esta identidad?"
msgid "Are you sure you want to remove this list?"
msgstr "¿Está seguro de que desea eliminar esta lista?"
+msgid "Are you sure you want to remove this nickname?"
+msgstr ""
+
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?"
@@ -4756,12 +4800,12 @@ msgstr "¿Está seguro de que desea volver a intentar esta migración?"
msgid "Are you sure you want to revoke this %{type}? This action cannot be undone."
msgstr "¿Está seguro de que desea revocar este token %{type}? Esta acción no se puede deshacer."
-msgid "Are you sure you want to revoke this nickname?"
-msgstr "¿Está seguro que desea revocar este nick?"
-
msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
msgstr "¿Está seguro de que desea revocar el token de acceso token personal?. Esta acción no se puede deshacer."
+msgid "Are you sure you want to revoke this project access token? This action cannot be undone."
+msgstr ""
+
msgid "Are you sure you want to stop this environment?"
msgstr "¿Está seguro de que desea detener este entorno?"
@@ -4906,9 +4950,6 @@ msgstr "Asignado a %{assigneeName}"
msgid "Assigned to %{assignee_name}"
msgstr "Asignado a %{assignee_name}"
-msgid "Assigned to %{name}"
-msgstr "Asignado a %{name}"
-
msgid "Assigned to me"
msgstr "Asignado a mí"
@@ -4973,6 +5014,9 @@ msgstr[1] "Adjuntar %d archivos"
msgid "Attaching the file failed."
msgstr "Se ha producido un error al adjuntar el archivo."
+msgid "Attention"
+msgstr ""
+
msgid "Audit Events"
msgstr "Eventos de auditoría"
@@ -5135,6 +5179,12 @@ msgstr "Autorizado en"
msgid "Authorized applications (%{size})"
msgstr "Aplicaciones autorizadas (%{size})"
+msgid "AuthorizedApplication|Are you sure you want to revoke this application?"
+msgstr ""
+
+msgid "AuthorizedApplication|Revoke application"
+msgstr ""
+
msgid "Authors: %{authors}"
msgstr "Autores: %{authors}"
@@ -5406,7 +5456,7 @@ msgid "Based on"
msgstr "Basado en"
msgid "Basic information"
-msgstr ""
+msgstr "Información básica"
msgid "Be careful. Changing the project's namespace can have unintended side effects."
msgstr "Tenga cuidado. Cambiar el espacio de nombres del proyecto puede tener efectos secundarios no deseados."
@@ -5436,7 +5486,7 @@ msgid "Below you will find all the groups that are public."
msgstr "A continuación encontrará todos los grupos públicos."
msgid "Beta"
-msgstr ""
+msgstr "Beta"
msgid "Bi-weekly code coverage"
msgstr "Cobertura de código quincenal"
@@ -5568,13 +5618,13 @@ msgid "Billings|Your account has been validated"
msgstr "Su cuenta ha sido validada"
msgid "Billing|%{user} was successfully approved"
-msgstr ""
+msgstr "%{user} fue aprobado con éxito"
msgid "Billing|An email address is only visible for users with public emails."
msgstr ""
msgid "Billing|An error occurred while approving %{user}"
-msgstr ""
+msgstr "Se ha producido un error al aprobar %{user}"
msgid "Billing|An error occurred while getting a billable member details"
msgstr ""
@@ -5622,7 +5672,7 @@ msgid "Billing|Project invite"
msgstr "Invitación al proyecto"
msgid "Billing|Remove user %{username} from your subscription"
-msgstr ""
+msgstr "Eliminar al usuario %{username} de su suscripción"
msgid "Billing|Toggle seat details"
msgstr ""
@@ -5687,7 +5737,7 @@ msgid "Board scope affects which epics are displayed for anyone who visits this
msgstr ""
msgid "Board scope affects which issues are displayed for anyone who visits this board"
-msgstr "El alcance del panel de control afecta qué problemas se muestran para cualquiera persona que visite este panel"
+msgstr "El alcance del tablero afecta a qué problemas se muestran para cualquiera persona que visite este panel"
msgid "BoardNewEpic|Groups"
msgstr "Grupos"
@@ -6123,7 +6173,7 @@ msgid "BulkImport| %{host} is running outdated GitLab version (v%{version})"
msgstr ""
msgid "BulkImport|%{feature} (require v%{version})"
-msgstr ""
+msgstr "%{feature} (requiere v%{version})"
msgid "BulkImport|Existing groups"
msgstr "Grupos existentes"
@@ -6153,7 +6203,7 @@ msgid "BulkImport|Import selected"
msgstr "Importar seleccionados"
msgid "BulkImport|Importing the group failed."
-msgstr ""
+msgstr "Error al importar el grupo."
msgid "BulkImport|Last imported to %{link}"
msgstr ""
@@ -6252,13 +6302,13 @@ msgid "By default, all projects and groups will use the global notifications set
msgstr "Por defecto, todos los proyectos y grupos utilizarán la configuración de notificaciones global."
msgid "By month"
-msgstr ""
+msgstr "Por mes"
msgid "By quarter"
-msgstr ""
+msgstr "Por trimestre"
msgid "By week"
-msgstr ""
+msgstr "Por semana"
msgid "ByAuthor|by"
msgstr "por"
@@ -6326,19 +6376,22 @@ msgid "CICDAnalytics|Releases"
msgstr ""
msgid "CICDAnalytics|Shared Runners Usage"
+msgstr "Uso de los ejecutores compartidos"
+
+msgid "CICDAnalytics|Shared runner pipeline minute duration by month"
msgstr ""
msgid "CICDAnalytics|Shared runner usage"
-msgstr ""
+msgstr "Uso compartido del ejecutor"
msgid "CICDAnalytics|Shared runner usage is the total runtime of all jobs that ran on shared runners"
-msgstr ""
+msgstr "El uso compartido del ejecutor es el tiempo de ejecución total de todos los trabajos que se ejecutaron en ejecutores compartidos"
msgid "CICDAnalytics|Something went wrong while fetching release statistics"
msgstr ""
msgid "CICDAnalytics|What is shared runner usage?"
-msgstr ""
+msgstr "¿Qué es el uso compartido del ejecutor?"
msgid "CICD|Add a %{base_domain_link_start}base domain%{link_end} to your %{kubernetes_cluster_link_start}Kubernetes cluster%{link_end} for your deployment strategy to work."
msgstr ""
@@ -6469,6 +6522,9 @@ msgstr ""
msgid "Can create groups:"
msgstr "Puede crear grupos:"
+msgid "Can not delete primary training"
+msgstr ""
+
msgid "Can't apply as the source branch was deleted."
msgstr ""
@@ -6802,9 +6858,6 @@ msgstr "No se han guardado los cambios en el título"
msgid "Changing any setting here requires an application restart"
msgstr ""
-msgid "Changing group URL can have unintended side effects."
-msgstr ""
-
msgid "Charts can't be displayed as the request for data has timed out. %{documentationLink}"
msgstr ""
@@ -6892,9 +6945,6 @@ msgstr "Comprobar el estado de aprobación"
msgid "Checking branch availability..."
msgstr "Verificando disponibilidad de la rama..."
-msgid "Checking group URL availability..."
-msgstr "Comprobando la disponibilidad de la URL del grupo..."
-
msgid "Checking group path availability..."
msgstr "Comprobando la disponibilidad de la ruta de grupo ..."
@@ -7388,6 +7438,9 @@ msgstr ""
msgid "Clear recent searches"
msgstr "Borrar el historial de búsquedas recientes"
+msgid "Clear repository checks"
+msgstr ""
+
msgid "Clear search"
msgstr "Limpiar búsqueda"
@@ -7520,9 +7573,6 @@ msgstr "Cerrado %{epicTimeagoDate}"
msgid "Closed MRs"
msgstr "MRs cerrados"
-msgid "Closed epics"
-msgstr "Épicas cerradas"
-
msgid "Closed issues"
msgstr "Incidencias cerradas"
@@ -7559,13 +7609,13 @@ msgstr ""
msgid "Cluster level"
msgstr "Nivel de clúster"
-msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
+msgid "Cluster type must be specified for Stages::ClusterEndpointInserter"
msgstr ""
msgid "ClusterAgents|%{name} successfully deleted"
msgstr ""
-msgid "ClusterAgents|%{number} of %{total} Agents"
+msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
@@ -7607,6 +7657,15 @@ msgstr "Es posible que el agente no esté conectado a GitLab"
msgid "ClusterAgents|Agent never connected to GitLab"
msgstr "El agente nunca se ha conectado a GitLab"
+msgid "ClusterAgents|Agent version mismatch"
+msgstr ""
+
+msgid "ClusterAgents|Agent version mismatch and update"
+msgstr ""
+
+msgid "ClusterAgents|Agent version update required"
+msgstr ""
+
msgid "ClusterAgents|All"
msgstr "Todos"
@@ -7631,8 +7690,8 @@ msgstr "Certificado"
msgid "ClusterAgents|Configuration"
msgstr "Configuración"
-msgid "ClusterAgents|Connect a cluster through the Agent"
-msgstr "Conectar a un clúster mediante el agente"
+msgid "ClusterAgents|Connect a cluster through an agent"
+msgstr ""
msgid "ClusterAgents|Connect existing cluster"
msgstr "Conectar a un clúster existente"
@@ -7640,13 +7699,13 @@ msgstr "Conectar a un clúster existente"
msgid "ClusterAgents|Connect with a certificate"
msgstr "Conectar con un certificado"
-msgid "ClusterAgents|Connect with agent"
+msgid "ClusterAgents|Connect with an agent"
msgstr ""
msgid "ClusterAgents|Connect with the GitLab Agent"
msgstr "Conectar con el agente de GitLab"
-msgid "ClusterAgents|Connect your cluster through the Agent"
+msgid "ClusterAgents|Connect your cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connected"
@@ -7698,7 +7757,7 @@ msgid "ClusterAgents|GitLab Agent for Kubernetes"
msgstr "Agente de GitLab para Kubernetes"
msgid "ClusterAgents|Give feedback"
-msgstr ""
+msgstr "Dar su opinión"
msgid "ClusterAgents|Go to the repository files"
msgstr "Ir a los archivos del repositorio"
@@ -7706,7 +7765,10 @@ msgstr "Ir a los archivos del repositorio"
msgid "ClusterAgents|How to register an agent?"
msgstr "¿Cómo registrar un agente?"
-msgid "ClusterAgents|Install new Agent"
+msgid "ClusterAgents|How to update an agent?"
+msgstr ""
+
+msgid "ClusterAgents|Install a new agent"
msgstr ""
msgid "ClusterAgents|Last connected %{timeAgo}."
@@ -7733,7 +7795,7 @@ msgstr "Nunca"
msgid "ClusterAgents|Never connected"
msgstr "Nunca se ha conectado"
-msgid "ClusterAgents|No Agents"
+msgid "ClusterAgents|No agents"
msgstr ""
msgid "ClusterAgents|No clusters connected through cluster certificates"
@@ -7785,7 +7847,7 @@ msgid "ClusterAgents|Select an agent to register with GitLab"
msgstr "Seleccione un agente para registrar en GitLab"
msgid "ClusterAgents|Tell us what you think"
-msgstr ""
+msgstr "Diganos lo que piensa"
msgid "ClusterAgents|The GitLab Agent provides an increased level of security when connecting Kubernetes clusters to GitLab. %{linkStart}Learn more about the GitLab Agent.%{linkEnd}"
msgstr ""
@@ -7793,6 +7855,9 @@ msgstr ""
msgid "ClusterAgents|The agent has not been connected in a long time. There might be a connectivity issue. Last contact was %{timeAgo}."
msgstr ""
+msgid "ClusterAgents|The agent version do not match each other across your cluster's pods. This can happen when a new agent version was just deployed and Kubernetes is shutting down the old pods."
+msgstr ""
+
msgid "ClusterAgents|The recommended installation method includes the token. If you want to follow the advanced installation method provided in the docs, make sure you save the token value before you close this window."
msgstr ""
@@ -7814,10 +7879,10 @@ msgid "ClusterAgents|To install a new agent, first add the agent's configuration
msgstr ""
msgid "ClusterAgents|Token created by %{userName}"
-msgstr ""
+msgstr "Token creado por %{userName}"
msgid "ClusterAgents|Token revoked by %{userName}"
-msgstr ""
+msgstr "Token revocado por %{userName}"
msgid "ClusterAgents|Unknown user"
msgstr "Usuario desconocido"
@@ -7829,7 +7894,7 @@ msgid "ClusterAgents|View all %{number} clusters"
msgstr "Ver todos los %{number} clústeres"
msgid "ClusterAgents|We would love to learn more about your experience with the GitLab Agent."
-msgstr ""
+msgstr "Nos encantaría saber más sobre su experiencia con GitLab Agent."
msgid "ClusterAgents|What is GitLab Agent activity?"
msgstr ""
@@ -7840,6 +7905,9 @@ msgstr ""
msgid "ClusterAgents|You will need to create a token to connect to your agent"
msgstr ""
+msgid "ClusterAgents|Your agent version is out of sync with your GitLab version (v%{version}), which might cause compatibility problems. Update the agent installed on your cluster to the most recent version."
+msgstr ""
+
msgid "ClusterAgents|Your instance doesn't have the %{linkStart}GitLab Agent Server (KAS)%{linkEnd} set up. Ask a GitLab Administrator to install it."
msgstr ""
@@ -7877,16 +7945,16 @@ msgid "ClusterIntegration|Add a Kubernetes cluster integration"
msgstr "Añadir integración con clúster de Kubernetes"
msgid "ClusterIntegration|Adding a Kubernetes cluster to your group will automatically share the cluster across all your projects. Use review apps, deploy your applications, and easily run your pipelines for all projects using the same cluster."
-msgstr "Agregar un cluster Kubernetes a su grupo compartirá automáticamente el cluster en todos sus proyectos. Utilice las aplicaciones de revisión, implemente sus aplicaciones y ejecute fácilmente los pipelines para todos los proyectos que utilizan el mismo clúster."
+msgstr "ClusterIntegration|Añadir un cluster Kubernetes a su grupo permitirá compartir automáticamente el cluster en todos sus proyectos. Utilice las aplicaciones de revisión, implemente sus aplicaciones y ejecute fácilmente los pipelines para todos los proyectos que utilizan el mismo clúster."
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 "Agregar un clúster Kubernetes compartirá automáticamente el clúster a todos los proyectos. Utilice las aplicaciones de revisión, implemente sus aplicaciones y ejecute fácilmente sus pipelines en todos los proyectos que utilizan el mismo clúster."
+msgstr "ClusterIntegration| Añadir un clúster Kubernetes permitira compartir automáticamente el clúster a todos los proyectos. Utilice las aplicaciones de revisión, implemente sus aplicaciones y ejecute fácilmente sus pipelines en todos los proyectos que utilizan el mismo clúster."
msgid "ClusterIntegration|Adding an integration to your group will share the cluster across all your projects."
-msgstr "Agregar una integración a su grupo compartirá el cluster en todos sus proyectos."
+msgstr "ClusterIntegration|Añadir una integración a su grupo permitirá compartir el cluster con todos sus proyectos."
msgid "ClusterIntegration|Adding an integration will share the cluster across all projects."
-msgstr "Agregar una integración compartirá el cluster en todos sus proyectos."
+msgstr "ClusterIntegration|Añadir una integración permitirá compartir el cluster en todos sus proyectos."
msgid "ClusterIntegration|Advanced options on this Kubernetes cluster’s integration"
msgstr ""
@@ -8716,9 +8784,6 @@ msgstr "ComboSearch no está definido"
msgid "Comma-separated list of email addresses."
msgstr "Lista de direcciones de correo electrónico separadas por comas."
-msgid "Comma-separated list of users allowed to exceed the rate limit."
-msgstr ""
-
msgid "Comma-separated, e.g. '1.1.1.1, 2.2.2.0/24'"
msgstr "Separados por comas, ej. '1.1.1.1, 2.2.2.0/24'"
@@ -8782,7 +8847,7 @@ msgid "Commit Message"
msgstr "Mensaje del commit"
msgid "Commit SHA"
-msgstr ""
+msgstr "SHA del commit"
msgid "Commit changes"
msgstr ""
@@ -8806,7 +8871,7 @@ msgid "CommitBoxTitle|Commit"
msgstr "Cambio"
msgid "CommitMessage|Add %{file_name}"
-msgstr "Agregar %{file_name}"
+msgstr "CommitMessage|Añadir %{file_name}"
msgid "CommitMessage|Add %{file_name} and create a code quality job"
msgstr ""
@@ -8968,7 +9033,7 @@ msgid "ComplianceFrameworks|Compliance pipeline configuration (optional)"
msgstr ""
msgid "ComplianceFrameworks|Configuration not found"
-msgstr ""
+msgstr "Configuración no encontrada"
msgid "ComplianceFrameworks|Configured compliance frameworks appear here."
msgstr ""
@@ -8983,7 +9048,7 @@ msgid "ComplianceFrameworks|Description"
msgstr ""
msgid "ComplianceFrameworks|Description is required"
-msgstr ""
+msgstr "Se requiere una descripción"
msgid "ComplianceFrameworks|Edit framework"
msgstr "Editar framework"
@@ -9045,6 +9110,12 @@ msgstr "Confianza"
msgid "Confidential"
msgstr "Confidencial"
+msgid "Confidential issue"
+msgstr ""
+
+msgid "Confidential note"
+msgstr ""
+
msgid "Confidentiality"
msgstr "Confidencialidad"
@@ -9078,6 +9149,9 @@ msgstr ""
msgid "Configure Dependency Scanning in `.gitlab-ci.yml`, creating this file if it does not already exist"
msgstr ""
+msgid "Configure GitLab"
+msgstr ""
+
msgid "Configure GitLab runners to start using the Web Terminal. %{helpStart}Learn more.%{helpEnd}"
msgstr "Configure los ejecutores de GitLab para comenzar a usar el terminal web. %{helpStart}Aprenda más.%{helpEnd}"
@@ -9126,6 +9200,15 @@ msgstr "Configurar la instalación existente"
msgid "Configure pipelines to deploy web apps, backend services, APIs and static resources to Google Cloud"
msgstr ""
+msgid "Configure region"
+msgstr ""
+
+msgid "Configure region for environment"
+msgstr ""
+
+msgid "Configure regions"
+msgstr ""
+
msgid "Configure repository mirroring."
msgstr "Configurar las réplicas del repositorio."
@@ -9159,6 +9242,9 @@ msgstr ""
msgid "Configure which lists are shown for anyone who visits this board"
msgstr ""
+msgid "Configure your environments to be deployed to specific geographical regions"
+msgstr ""
+
msgid "Confirm"
msgstr "Confirmar"
@@ -9861,12 +9947,12 @@ msgstr "¿Está seguro de que desea eliminar el corpus?"
msgid "CorpusManagement|Actions"
msgstr "Acciones"
-msgid "CorpusManagement|Corpus are used in fuzz testing as mutation source to Improve future testing."
-msgstr "Los corpus se utilizan en las pruebas de tipo fuzz como fuente de mutación para mejorar futuras pruebas."
-
msgid "CorpusManagement|Corpus file"
msgstr ""
+msgid "CorpusManagement|Corpus files are used in coverage-guided fuzz testing as seed inputs to improve testing."
+msgstr ""
+
msgid "CorpusManagement|Corpus files must be in *.zip format. Maximum 5 GB"
msgstr ""
@@ -9877,7 +9963,7 @@ msgid "CorpusManagement|Currently, there are no uploaded or generated corpuses."
msgstr ""
msgid "CorpusManagement|File too large, Maximum 5 GB"
-msgstr ""
+msgstr "Archivo demasiado grande, máximo 5 GB"
msgid "CorpusManagement|Filename can contain only lowercase letters (a-z), uppercase letter (A-Z), numbers (0-9), dots (.), hyphens (-), or underscores (_)."
msgstr ""
@@ -9913,11 +9999,14 @@ msgid "CorpusMnagement|New corpus"
msgstr "Nuevo corpus"
msgid "Could not add admins as members"
-msgstr "No se puede agregar administradores como miembros"
+msgstr "No se puede añadir administradores como miembros"
msgid "Could not apply %{name} command."
msgstr "No se pudo aplicar el comando %{name}."
+msgid "Could not apply %{name} command. %{message}."
+msgstr ""
+
msgid "Could not authorize chat nickname. Try again!"
msgstr "No se puede autorizar el nick del chat. Por favor, inténtelo de nuevo"
@@ -10068,6 +10157,9 @@ 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"
+msgstr ""
+
msgid "Create a merge request"
msgstr "Crear un merge request"
@@ -10092,6 +10184,9 @@ msgstr "Crear un nuevo repositorio"
msgid "Create a personal access token on your account to pull or push via %{protocol}."
msgstr "Crear un token de acceso personal en tu cuenta para actualizar o enviar a través de %{protocol}."
+msgid "Create a project"
+msgstr ""
+
msgid "Create an account using:"
msgstr "Crear una cuenta utilizando:"
@@ -10150,7 +10245,7 @@ msgid "Create iteration"
msgstr "Crear iteración"
msgid "Create label"
-msgstr ""
+msgstr "Crear etiqueta"
msgid "Create list"
msgstr "Crear lista"
@@ -10357,7 +10452,7 @@ msgid "CreateValueStreamForm|Stage %{index}"
msgstr "Etapa %{index}"
msgid "CreateValueStreamForm|Stage name already exists"
-msgstr ""
+msgstr "El nombre de la etapa ya existe"
msgid "CreateValueStreamForm|Stage name is required"
msgstr ""
@@ -10455,6 +10550,9 @@ msgstr "La creación de los gráficos utiliza los datos del servidor Prometheus.
msgid "Creation date"
msgstr "Fecha de creación"
+msgid "Creator"
+msgstr ""
+
msgid "Credentials"
msgstr "Credenciales"
@@ -10467,9 +10565,15 @@ msgstr "No se encontraron credenciales"
msgid "CredentialsInventory|Personal Access Tokens"
msgstr "Tokens de acceso personal"
+msgid "CredentialsInventory|Project Access Tokens"
+msgstr ""
+
msgid "CredentialsInventory|SSH Keys"
msgstr "Claves SSH"
+msgid "Credit card required to be on file in order to create a pipeline"
+msgstr ""
+
msgid "Credit card:"
msgstr "Tarjeta de crédito:"
@@ -10501,7 +10605,7 @@ msgid "Crm|Description (optional)"
msgstr "Descripción (opcional)"
msgid "Crm|Edit contact"
-msgstr ""
+msgstr "Editar contacto"
msgid "Crm|Email"
msgstr "Correo electrónico"
@@ -10528,7 +10632,7 @@ msgid "Crm|No organizations found"
msgstr "No se encontraron organizaciones"
msgid "Crm|Organization has been added"
-msgstr ""
+msgstr "Se ha añadido la organización"
msgid "Crm|Phone number (optional)"
msgstr "Número de teléfono (opcional)"
@@ -10653,9 +10757,6 @@ msgstr ""
msgid "Customer relations"
msgstr ""
-msgid "Customizable by an administrator."
-msgstr "Personalizable por un administrador."
-
msgid "Customizable by owners."
msgstr "Personalizable por los propietarios."
@@ -10705,7 +10806,7 @@ msgid "CycleAnalyticsEvent|Issue created"
msgstr "Incidencia creada"
msgid "CycleAnalyticsEvent|Issue first added to a board"
-msgstr "Incidencia añadida por primera vez a un panel de control"
+msgstr "CycleAnalyticsEvent|Incidencia añadida por primera vez a un tablero"
msgid "CycleAnalyticsEvent|Issue first associated with a milestone"
msgstr "Incidencia asociada por primera con un hito"
@@ -10785,30 +10886,18 @@ msgstr "debe estar bajo un grupo"
msgid "CycleAnalytics|%{selectedLabelsCount} selected (%{maxLabels} max)"
msgstr ""
-msgid "CycleAnalytics|%{stageCount} stages selected"
-msgstr "%{stageCount} etapas seleccionadas"
-
-msgid "CycleAnalytics|All stages"
-msgstr "Todas las etapas"
-
-msgid "CycleAnalytics|Average days to completion"
-msgstr "Promedio de días hasta completar"
+msgid "CycleAnalytics|Average time to completion"
+msgstr ""
msgid "CycleAnalytics|Date"
msgstr "Fecha"
-msgid "CycleAnalytics|Days to completion"
-msgstr "Días hasta completar"
-
msgid "CycleAnalytics|Display chart filters"
msgstr "Mostrar filtros de gráficos"
msgid "CycleAnalytics|Lead Time for Changes"
msgstr ""
-msgid "CycleAnalytics|No stages selected"
-msgstr "Ninguna etapa seleccionada"
-
msgid "CycleAnalytics|Number of tasks"
msgstr "Número de tareas"
@@ -10837,18 +10926,30 @@ msgstr ""
msgid "CycleAnalytics|Showing data for group '%{groupName}' from %{createdAfter} to %{createdBefore}"
msgstr ""
-msgid "CycleAnalytics|Stages"
-msgstr "Etapas"
+msgid "CycleAnalytics|Stage time: %{title}"
+msgstr ""
msgid "CycleAnalytics|Tasks by type"
msgstr "Tareas por tipo"
-msgid "CycleAnalytics|The average time spent in the selected stage for the items that were completed on each date. Data limited to the last 500 items."
+msgid "CycleAnalytics|The average time items spent in this stage. Data limited to items completed within this date range."
msgstr ""
msgid "CycleAnalytics|The given date range is larger than 180 days"
msgstr ""
+msgid "CycleAnalytics|The total time items spent across each value stream stage. Data limited to items completed within this date range."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Stage time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Total time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|Total time"
+msgstr ""
+
msgid "CycleAnalytics|Type of work"
msgstr "Tipo de trabajo"
@@ -10861,9 +10962,6 @@ msgstr ""
msgid "CycleAnalytics|project dropdown filter"
msgstr ""
-msgid "CycleAnalytics|stage dropdown"
-msgstr "Lista desplegable de las etapas"
-
msgid "DAG visualization requires at least 3 dependent jobs."
msgstr ""
@@ -10922,7 +11020,7 @@ msgid "DSN"
msgstr "DSN"
msgid "Dashboard"
-msgstr "Panel de control"
+msgstr "Tablero"
msgid "Dashboard uid not found"
msgstr "No se ha encontrado el uid del tablero no encontrado"
@@ -10937,7 +11035,7 @@ msgid "DashboardProjects|Trending"
msgstr "Tendencia"
msgid "Dashboard|%{firstProject} and %{secondProject}"
-msgstr "%{firstProject} y %{secondProject}"
+msgstr "Dashboard|%{firstProject} y %{secondProject}"
msgid "Dashboard|%{firstProject}, %{rest}, and %{secondProject}"
msgstr "%{firstProject}, %{rest}, y %{secondProject}"
@@ -10963,10 +11061,16 @@ msgstr ""
msgid "DastProfiles|AJAX spider"
msgstr ""
+msgid "DastProfiles|API"
+msgstr ""
+
+msgid "DastProfiles|API endpoint URL"
+msgstr ""
+
msgid "DastProfiles|Active"
msgstr "Activo"
-msgid "DastProfiles|Additional request headers (Optional)"
+msgid "DastProfiles|Additional request headers (optional)"
msgstr ""
msgid "DastProfiles|Are you sure you want to delete this profile?"
@@ -10981,6 +11085,9 @@ msgstr "URL de autentificación"
msgid "DastProfiles|Branch missing"
msgstr ""
+msgid "DastProfiles|Choose a scan method"
+msgstr ""
+
msgid "DastProfiles|Could not create the scanner profile. Please try again."
msgstr ""
@@ -11050,8 +11157,14 @@ msgstr "Detalles del error"
msgid "DastProfiles|Excluded URLs"
msgstr "URL excluidas"
-msgid "DastProfiles|Excluded URLs (Optional)"
-msgstr "URL excluidas (opcional)"
+msgid "DastProfiles|Excluded URLs (optional)"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths (optional)"
+msgstr ""
msgid "DastProfiles|Hide debug messages"
msgstr "Ocultar mensajes de depuración"
@@ -11107,9 +11220,6 @@ msgstr ""
msgid "DastProfiles|Request headers"
msgstr ""
-msgid "DastProfiles|Rest API"
-msgstr ""
-
msgid "DastProfiles|Run the AJAX spider, in addition to the traditional spider, to crawl the target site."
msgstr ""
@@ -11119,6 +11229,9 @@ msgstr ""
msgid "DastProfiles|Save profile"
msgstr ""
+msgid "DastProfiles|Scan method"
+msgstr ""
+
msgid "DastProfiles|Scan mode"
msgstr "Modo de análisis"
@@ -11197,12 +11310,24 @@ msgstr "Estado de validación"
msgid "DastProfiles|Website"
msgstr "Sitio web"
+msgid "DastProfiles|What does each method do?"
+msgstr ""
+
msgid "DastProfiles|You can either choose a passive scan or validate the target site from the site profile management page. %{docsLinkStart}Learn more about site validation.%{docsLinkEnd}"
msgstr ""
msgid "DastProfiles|You cannot run an active scan against an unvalidated site."
msgstr ""
+msgid "DastProfiles|folder/dast_example.har or https://example.com/dast_example.har"
+msgstr ""
+
+msgid "DastProfiles|folder/example.postman_collection.json or https://example.com/"
+msgstr ""
+
+msgid "DastProfiles|folder/openapi.json or https://example.com/openapi.json"
+msgstr ""
+
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
@@ -11310,6 +11435,9 @@ msgstr ""
msgid "DatadogIntegration|API URL"
msgstr "URL del API"
+msgid "DatadogIntegration|Custom tags in Datadog. Enter one tag per line in the %{codeOpen}key:value%{codeClose} format. %{linkOpen}How do I use tags?%{linkClose}"
+msgstr ""
+
msgid "DatadogIntegration|Environment"
msgstr "Entorno"
@@ -11328,12 +11456,18 @@ msgstr "Servicio"
msgid "DatadogIntegration|Tag all data from this GitLab instance in Datadog. Useful when managing several self-managed deployments."
msgstr ""
+msgid "DatadogIntegration|Tags"
+msgstr ""
+
msgid "DatadogIntegration|The Datadog site to send data to. To send data to the EU site, use %{codeOpen}datadoghq.eu%{codeClose}."
msgstr ""
msgid "DatadogIntegration|Trace your GitLab pipelines with Datadog."
msgstr ""
+msgid "DatadogIntegration|have an invalid format"
+msgstr ""
+
msgid "Datasource name not found"
msgstr ""
@@ -11343,9 +11477,6 @@ msgstr "Fecha"
msgid "Date merged"
msgstr ""
-msgid "Date picker"
-msgstr "Selector de fecha"
-
msgid "Date range"
msgstr "Rango de fechas"
@@ -11499,9 +11630,6 @@ msgstr ""
msgid "Definition"
msgstr "Definición"
-msgid "Delayed Project Deletion (%{adjourned_deletion})"
-msgstr ""
-
msgid "DelayedJobs|Are you sure you want to run %{jobName} immediately? Otherwise this job will run automatically after its timer finishes."
msgstr ""
@@ -11569,7 +11697,7 @@ msgid "Delete file"
msgstr "Eliminar el archivo"
msgid "Delete image repository"
-msgstr ""
+msgstr "Eliminar el epositorio de imágenes"
msgid "Delete label"
msgstr "Eliminar etiqueta"
@@ -11580,12 +11708,12 @@ msgstr ""
msgid "Delete pipeline"
msgstr "Eliminar pipeline"
+msgid "Delete pipeline schedule"
+msgstr ""
+
msgid "Delete project"
msgstr "Eliminar proyecto"
-msgid "Delete project. Are you ABSOLUTELY SURE?"
-msgstr ""
-
msgid "Delete row"
msgstr "Eliminar fila"
@@ -11613,6 +11741,9 @@ msgstr "Eliminar este adjunto"
msgid "Delete this epic and all descendants?"
msgstr ""
+msgid "Delete this project"
+msgstr ""
+
msgid "Delete user list"
msgstr "Eliminar la lista de usuarios"
@@ -11871,6 +12002,12 @@ msgstr ""
msgid "Deploy to..."
msgstr "Desplegar en..."
+msgid "DeployBoards|To see deployment progress for your environments, make sure you are deploying to %{codeStart}$KUBE_NAMESPACE%{codeEnd} and annotating with %{codeStart}app.gitlab.com/app=$CI_PROJECT_PATH_SLUG%{codeEnd} and %{codeStart}app.gitlab.com/env=$CI_ENVIRONMENT_SLUG%{codeEnd}."
+msgstr ""
+
+msgid "DeployBoard|Kubernetes Pods"
+msgstr ""
+
msgid "DeployFreeze|Add a freeze period to prevent unintended releases during a period of time for a given environment. You must update the deployment jobs in %{filename} according to the deploy freezes added here. %{freeze_period_link_start}Learn more.%{freeze_period_link_end}"
msgstr ""
@@ -11955,9 +12092,6 @@ msgstr "Acceso de sólo lectura"
msgid "DeployTokens|Active Deploy Tokens (%{active_tokens})"
msgstr "Claves de despliegue activas (%{active_tokens})"
-msgid "DeployTokens|Allows read and write access to registry images."
-msgstr ""
-
msgid "DeployTokens|Allows read and write access to the package registry."
msgstr ""
@@ -11970,6 +12104,9 @@ msgstr ""
msgid "DeployTokens|Allows read-only access to the repository."
msgstr ""
+msgid "DeployTokens|Allows write access to registry images."
+msgstr ""
+
msgid "DeployTokens|Copy deploy token"
msgstr "Copiar token de despliegue"
@@ -12063,12 +12200,57 @@ msgstr "Desplegando en"
msgid "Deploying to AWS is easy with GitLab"
msgstr "Desplegar en AWS es fácil con GitLab"
+msgid "Deployment"
+msgstr ""
+
msgid "Deployment Frequency"
msgstr "Frecuencia de despliegue"
+msgid "Deployment Target|Project deployment target (optional)"
+msgstr ""
+
+msgid "Deployment Target|Select the deployment target"
+msgstr ""
+
msgid "Deployment frequency"
msgstr ""
+msgid "DeploymentTarget|GitLab Pages"
+msgstr ""
+
+msgid "DeploymentTarget|Heroku"
+msgstr ""
+
+msgid "DeploymentTarget|Infrastructure provider (Terraform, Cloudformation, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Kubernetes (GKE, EKS, OpenShift, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Managed container runtime (Fargate, Cloud Run, DigitalOcean App)"
+msgstr ""
+
+msgid "DeploymentTarget|Mobile app store"
+msgstr ""
+
+msgid "DeploymentTarget|No deployment planned"
+msgstr ""
+
+msgid "DeploymentTarget|Other hosting service"
+msgstr ""
+
+msgid "DeploymentTarget|Registry (package or container)"
+msgstr ""
+
+msgid "DeploymentTarget|Self-managed container runtime (Podman, Docker Swarm, Docker Compose)"
+msgstr ""
+
+msgid "DeploymentTarget|Serverless backend (Lambda, Cloud functions)"
+msgstr ""
+
+msgid "DeploymentTarget|Virtual machine (for example, EC2)"
+msgstr ""
+
msgid "Deployments"
msgstr "Despliegues"
@@ -12081,37 +12263,40 @@ msgid "Deployment|API"
msgstr "API"
msgid "Deployment|Cancelled"
-msgstr ""
+msgstr "Cancelado"
msgid "Deployment|Created"
-msgstr ""
+msgstr "Creado"
msgid "Deployment|Deployment ID"
msgstr ""
msgid "Deployment|Failed"
-msgstr ""
+msgstr "Falló"
msgid "Deployment|Latest Deployed"
-msgstr ""
+msgstr "Último despliegue"
msgid "Deployment|Running"
-msgstr ""
+msgstr "En ejecución"
msgid "Deployment|Skipped"
-msgstr ""
+msgstr "Omitido"
msgid "Deployment|Success"
-msgstr ""
+msgstr "Éxito"
msgid "Deployment|This deployment was created using the API"
msgstr "Este despliegue se creó utilizando el API"
-msgid "Deployment|Waiting"
+msgid "Deployment|Triggerer"
msgstr ""
+msgid "Deployment|Waiting"
+msgstr "Esperando"
+
msgid "Deployment|blocked"
-msgstr ""
+msgstr "bloqueado"
msgid "Deployment|canceled"
msgstr "cancelado"
@@ -12134,6 +12319,18 @@ msgstr "exitoso"
msgid "Deprecated API rate limits"
msgstr ""
+msgid "Deprecations|Feature deprecation and removal"
+msgstr ""
+
+msgid "Deprecations|For information on a possible replacement %{epicStart} learn more about Opstrace %{epicEnd}."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7 and are %{epicStart} scheduled for removal %{epicEnd} in GitLab 15.0."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7, and are %{removal_link_start} scheduled for removal %{link_end} in GitLab 15.0. For information on a possible replacement, %{opstrace_link_start} learn more about Opstrace %{link_end}."
+msgstr ""
+
msgid "Deprioritize label"
msgstr "Bajar la prioridad de la etiqueta"
@@ -12178,11 +12375,11 @@ msgstr "%{current_design} de %{designs_count}"
msgid "DesignManagement|%{filename} did not change."
msgid_plural "DesignManagement|The designs you tried uploading did not change."
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%{filename} no ha cambiado."
+msgstr[1] "Los diseños que intentó cargar no cambiaron."
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."
+msgstr "Añadir un diseño con el mismo nombre de archivo reemplaza el archivo en una nueva versión."
msgid "DesignManagement|Archive design"
msgstr ""
@@ -12284,10 +12481,10 @@ msgid "DesignManagement|Select all"
msgstr "Seleccionar todo"
msgid "DesignManagement|Some of the designs you tried uploading did not change: %{skippedFiles} and %{moreCount} more."
-msgstr ""
+msgstr "Algunos de los diseños que intentó cargar no cambiaron: %{skippedFiles} y %{moreCount} más."
msgid "DesignManagement|Some of the designs you tried uploading did not change: %{skippedFiles}."
-msgstr ""
+msgstr "Algunos de los diseños que intentó cargar no han cambiado: %{skippedFiles}."
msgid "DesignManagement|The maximum number of designs allowed to be uploaded is %{upload_limit}. Please try again."
msgstr "El número máximo de diseños permitidos que se pueden cargar es %{upload_limit}. Por favor, inténtalo de nuevo."
@@ -12362,7 +12559,7 @@ msgid "DevopsAdoption|Adoption by subgroup"
msgstr ""
msgid "DevopsAdoption|Adoption over time"
-msgstr ""
+msgstr "Adopción a lo largo del tiempo"
msgid "DevopsAdoption|An error occurred while removing the group. Please try again."
msgstr ""
@@ -12379,10 +12576,10 @@ msgstr ""
msgid "DevopsAdoption|At least one deploy"
msgstr ""
-msgid "DevopsAdoption|At least one issue opened"
+msgid "DevopsAdoption|At least one issue created"
msgstr ""
-msgid "DevopsAdoption|At least one merge request opened"
+msgid "DevopsAdoption|At least one merge request created"
msgstr ""
msgid "DevopsAdoption|At least one pipeline successfully run"
@@ -12583,6 +12780,9 @@ msgstr ""
msgid "Direct member"
msgstr "Miembro directo"
+msgid "Direct members"
+msgstr ""
+
msgid "Direct non-authenticated users to this page."
msgstr ""
@@ -12699,6 +12899,9 @@ msgid_plural "Dismiss %d selected vulnerabilities as"
msgstr[0] ""
msgstr[1] ""
+msgid "Dismiss Alert"
+msgstr ""
+
msgid "Dismiss merge request promotion"
msgstr ""
@@ -12726,9 +12929,15 @@ msgstr "Descartado en el pipeline %{pipelineLink} en %{projectLink}"
msgid "Display alerts from all configured monitoring tools."
msgstr ""
+msgid "Display milestones"
+msgstr ""
+
msgid "Display name"
msgstr "Nombre para mostrar"
+msgid "Display progress of child issues"
+msgstr ""
+
msgid "Display rendered file"
msgstr "Mostrar el archivo renderizado"
@@ -12760,7 +12969,7 @@ msgid "Documentation pages URL"
msgstr ""
msgid "Documents reindexed: %{processed_documents} (%{percentage}%%)"
-msgstr ""
+msgstr "Documentos reindexados: %{processed_documents} (%{percentage}%%)"
msgid "Does not apply to projects in personal namespaces, which are deleted immediately on request."
msgstr ""
@@ -12834,6 +13043,9 @@ msgstr "Descargar exportación"
msgid "Download image"
msgstr "Descargar imagen"
+msgid "Download payload"
+msgstr ""
+
msgid "Download raw data (.csv)"
msgstr "Descargar datos (.csv)"
@@ -13011,6 +13223,9 @@ msgstr "Editar la identidad para %{user_name}"
msgid "Edit in Web IDE"
msgstr "Editar en IDE Web"
+msgid "Edit in pipeline editor"
+msgstr ""
+
msgid "Edit in single-file editor"
msgstr ""
@@ -13053,6 +13268,9 @@ msgstr "Editar página wiki"
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 "Edit, lint, and visualize your pipeline."
+msgstr ""
+
msgid "Edited"
msgstr "Editado"
@@ -13153,7 +13371,7 @@ msgid "Email the pipeline status to a list of recipients."
msgstr ""
msgid "Email updates (optional)"
-msgstr ""
+msgstr "Actualizaciones por correo electrónico (opcional)"
msgid "Email:"
msgstr "Correo electrónico:"
@@ -13324,7 +13542,7 @@ msgid "Enable authentication"
msgstr "Habilitar la autenticación"
msgid "Enable automatic repository housekeeping"
-msgstr ""
+msgstr "Activar mantenimiento automático del repositorio"
msgid "Enable container expiration and retention policies for projects created earlier than GitLab 12.7."
msgstr ""
@@ -13494,6 +13712,9 @@ msgstr "Forzar la autenticación de doble factor"
msgid "Enforce two-factor authentication for all user sign-ins."
msgstr ""
+msgid "Enhance security by storing service account keys in secret managers - learn more about %{docLinkStart}secret management with GitLab%{docLinkEnd}"
+msgstr ""
+
msgid "Ensure connectivity is available from the GitLab server to the Prometheus server"
msgstr ""
@@ -13531,7 +13752,7 @@ msgid "Enter in your Phabricator Server URL and personal access token below"
msgstr "Introduzca la URL de su servidor Phabricator y su token de acceso"
msgid "Enter license key"
-msgstr ""
+msgstr "Introduzca la clave de la licencia"
msgid "Enter merge request URLs"
msgstr "Introduzca las URL de la solicitud de fusión"
@@ -13554,9 +13775,12 @@ msgstr "Introduzca el título de %{name}"
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 name of your application, and we'll return a unique %{type}."
+msgid "Enter the following to confirm:"
msgstr ""
+msgid "Enter the name of your application, and we'll return a unique %{type}."
+msgstr "Introduzca el nombre de su aplicación y le devolveremos un único %{type}."
+
msgid "Enter the number of seconds, or other human-readable input, like \"1 hour\". This timeout takes precedence over lower timeouts set for the project."
msgstr ""
@@ -13570,10 +13794,10 @@ msgid "Enter your Packagist server. Defaults to https://packagist.org."
msgstr ""
msgid "Enter your Packagist token."
-msgstr ""
+msgstr "Introduzca su token de Packagist."
msgid "Enter your Packagist username."
-msgstr ""
+msgstr "Introduzca su nombre de usuario de Packagist."
msgid "Enter your password to approve"
msgstr "Introduzca su contraseña para aprobar"
@@ -13587,7 +13811,7 @@ msgstr[0] ""
msgstr[1] ""
msgid "Environment does not have deployments"
-msgstr ""
+msgstr "El entorno no tiene implementaciones"
msgid "Environment is required for Stages::MetricEndpointInserter"
msgstr ""
@@ -13623,7 +13847,7 @@ msgid "Environments"
msgstr "Entornos"
msgid "Environments Dashboard"
-msgstr "Panel de control de entornos"
+msgstr "Tablero de entornos"
msgid "Environments allow you to track deployments of your application. %{linkStart}More information%{linkEnd}."
msgstr ""
@@ -13635,13 +13859,13 @@ msgid "EnvironmentsAlert|%{severity} • %{title} %{text}. %{linkStart}View Deta
msgstr ""
msgid "EnvironmentsDashboard|Add a project to the dashboard"
-msgstr "Añadir un proyecto al panel de control"
+msgstr "EnvironmentsDashboard|Añadir un proyecto al tablero"
msgid "EnvironmentsDashboard|Add projects"
msgstr "Añadir proyectos"
msgid "EnvironmentsDashboard|Environments Dashboard"
-msgstr "Panel de control de entornos"
+msgstr "EnvironmentsDashboard|Tablero de entornos"
msgid "EnvironmentsDashboard|Job: %{job}"
msgstr "Trabajo: %{job}"
@@ -13653,7 +13877,7 @@ msgid "EnvironmentsDashboard|Remove"
msgstr "Eliminar"
msgid "EnvironmentsDashboard|The environments dashboard provides a summary of each project's environments' status, including pipeline and alert statuses."
-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."
+msgstr "EnvironmentsDashboard|El tablero 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 3 environments per project, and is linked to the Operations Dashboard. When you add or remove a project from one dashboard, GitLab adds or removes the project from the other. %{linkStart}More information%{linkEnd}"
msgstr ""
@@ -13821,7 +14045,7 @@ msgid "Environments|This action will run the job defined by %{name} for commit %
msgstr "Esta acción ejecutará el trabajo definido por %{name} para el commit %{linkStart}%{commitId}%{linkEnd}, estableciendo el entorno a una versión anterior. Puede dejar el entorno en la última versión de su aplicación volviendo a desplegarlo. ¿Está seguro de que desea continuar?"
msgid "Environments|Upcoming"
-msgstr ""
+msgstr "Próximos"
msgid "Environments|Upcoming deployment"
msgstr ""
@@ -14084,9 +14308,6 @@ msgstr ""
msgid "Error occurred while updating the issue status"
msgstr ""
-msgid "Error occurred while updating the issue weight"
-msgstr "Se ha producido un error al actualizar el peso de la incidencia"
-
msgid "Error occurred. A blocked user cannot be deactivated"
msgstr "Se ha producido un error. No es posible desactivar un usuario bloqueado"
@@ -14222,6 +14443,9 @@ msgstr ""
msgid "Errors:"
msgstr "Errores:"
+msgid "Escalate this incident"
+msgstr ""
+
msgid "Escalation Policies"
msgstr "Políticas de escalado"
@@ -14234,9 +14458,12 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
-msgid "Escalation policy:"
+msgid "Escalation policy"
msgstr ""
+msgid "Escalation policy:"
+msgstr "Política de escalado:"
+
msgid "EscalationPolicies|%{clockIcon} IF alert is not %{alertStatus} in %{minutes}"
msgstr ""
@@ -14244,10 +14471,10 @@ msgid "EscalationPolicies|%{notificationIcon} THEN %{doAction} %{forScheduleOrUs
msgstr ""
msgid "EscalationPolicies|+ Add an additional rule"
-msgstr ""
+msgstr "+ Añadir una regla adicional"
msgid "EscalationPolicies|A schedule is required for adding an escalation policy."
-msgstr ""
+msgstr "Se requiere un horario para añadir una política de escalado."
msgid "EscalationPolicies|A schedule is required for adding an escalation policy. Please create an on-call schedule first."
msgstr ""
@@ -14268,28 +14495,28 @@ msgid "EscalationPolicies|Are you sure you want to delete the \"%{escalationPoli
msgstr ""
msgid "EscalationPolicies|Create an escalation policy in GitLab"
-msgstr ""
+msgstr "Crear una política de escalado en GitLab"
msgid "EscalationPolicies|Delete escalation policy"
msgstr "Eliminar política de escalado"
msgid "EscalationPolicies|Edit escalation policy"
-msgstr ""
+msgstr "Editar política de escalado"
msgid "EscalationPolicies|Email on-call user in schedule"
msgstr ""
msgid "EscalationPolicies|Email user"
-msgstr ""
+msgstr "Usuario de correo electrónico"
msgid "EscalationPolicies|Escalation policies"
-msgstr ""
+msgstr "Políticas de escalado"
msgid "EscalationPolicies|Escalation policy %{obstacle} in project %{project}"
-msgstr ""
+msgstr "EscalationPolicies|Política de escalado %{obstacle} en el proyecto %{project}"
msgid "EscalationPolicies|Escalation rules"
-msgstr ""
+msgstr "Reglas de escalado"
msgid "EscalationPolicies|Failed to load oncall-schedules"
msgstr ""
@@ -14485,6 +14712,9 @@ msgstr ""
msgid "Existing sign in methods may be removed"
msgstr ""
+msgid "Exit."
+msgstr ""
+
msgid "Expand"
msgstr "Expandir"
@@ -14581,6 +14811,9 @@ msgstr "Explorar proyectos"
msgid "Explore public groups"
msgstr "Explorar grupos públicos"
+msgid "Explore public projects"
+msgstr ""
+
msgid "Explore snippets"
msgstr "Explorar fragmentos de código"
@@ -14696,7 +14929,7 @@ msgid "ExternalAuthorization|Private key of client authentication certificate. E
msgstr ""
msgid "ExternalAuthorization|Service URL"
-msgstr ""
+msgstr "URL del servicio"
msgid "ExternalAuthorization|URL to which the projects make authorization requests. If the URL is blank, cross-project features are available and can still specify classification labels for projects."
msgstr ""
@@ -14732,17 +14965,17 @@ msgid "Failed on"
msgstr "Error en"
msgid "Failed to add a Zoom meeting"
-msgstr "Se ha producido un error al agregar una reunión de Zoom"
+msgstr "Se ha producido un error al añadir una reunión de Zoom"
msgid "Failed to apply commands."
msgstr "Se ha producido un error al aplicar los comandos."
msgid "Failed to archive a design. Please try again."
msgid_plural "Failed to archive designs. Please try again."
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "Se ha producido un error al archivar un diseño. Por favor, inténtalo de nuevo."
+msgstr[1] "Se ha producido un error al archivar los diseños. Por favor, inténtalo de nuevo."
-msgid "Failed to assign a reviewer because no user was found."
+msgid "Failed to assign a reviewer because no user was specified."
msgstr ""
msgid "Failed to assign a user because no user was found."
@@ -14764,10 +14997,10 @@ msgid "Failed to check related branches."
msgstr "Se ha producido un error al verificar las branchs relacionadas."
msgid "Failed to clone this issue because target project doesn't exist."
-msgstr ""
+msgstr "Se ha producido un error al clonar este problema porque el proyecto objetivo no existe."
msgid "Failed to clone this issue: wrong parameters."
-msgstr ""
+msgstr "Se ha producido un error al clonar este problema: parámetros incorrectos."
msgid "Failed to create a branch for this issue. Please try again."
msgstr "Se ha producido un erro al crear una rama para esta incidencia. Por favor, inténtalo de nuevo."
@@ -14808,10 +15041,10 @@ msgstr ""
msgid "Failed to find import label for Jira import."
msgstr ""
-msgid "Failed to generate export, please try again later."
+msgid "Failed to find users for %{missing}"
msgstr ""
-msgid "Failed to generate report, please try again after sometime"
+msgid "Failed to generate export, please try again later."
msgstr ""
msgid "Failed to get ref."
@@ -14866,7 +15099,7 @@ msgid "Failed to load milestones. Please try again."
msgstr "Se ha producido un error al cargar los hitos. Por favor, inténtelo de nuevo."
msgid "Failed to load projects"
-msgstr ""
+msgstr "Se ha producido un error al cargar los proyectos"
msgid "Failed to load related branches"
msgstr "Se ha producido un error al cargar ramas relacionadas"
@@ -14910,6 +15143,9 @@ msgstr "Se ha producido un error al eliminar una reunión de Zoom"
msgid "Failed to remove a to-do item for the design."
msgstr ""
+msgid "Failed to remove attention because no user was found."
+msgstr ""
+
msgid "Failed to remove mirror."
msgstr "Se ha producido un error al eliminar el mirror."
@@ -14922,6 +15158,9 @@ msgstr "Se ha producido un error al eliminar la identidad del usuario."
msgid "Failed to remove user key."
msgstr "Se ha producido un error al eliminar la clave del usuario."
+msgid "Failed to request attention because no user was found."
+msgstr ""
+
msgid "Failed to reset key. Please try again."
msgstr "Se ha producido un error al restablecer la clave. Por favor, inténtalo de nuevo."
@@ -15003,6 +15242,9 @@ msgstr "Se eliminará el favicon. ¿Seguro que quieres hacerlo?"
msgid "Feature Flags"
msgstr "Feature Flags"
+msgid "Feature deprecation and removal"
+msgstr ""
+
msgid "Feature flag status"
msgstr ""
@@ -15156,7 +15398,7 @@ msgid "FeatureFlags|No user list selected"
msgstr "No se ha seleccionado ninguna lista de usuarios"
msgid "FeatureFlags|Percent of users"
-msgstr ""
+msgstr "Porcentaje de usuarios"
msgid "FeatureFlags|Percent rollout"
msgstr ""
@@ -15198,7 +15440,7 @@ msgid "FeatureFlags|User Lists"
msgstr ""
msgid "FeatureFlags|View user lists"
-msgstr ""
+msgstr "Ver las listas de usuarios"
msgid "FeatureFlag|Percentage"
msgstr "Porcentaje"
@@ -15441,7 +15683,7 @@ msgid "FloC|Federated Learning of Cohorts"
msgstr ""
msgid "FlowdockService|1b609b52537..."
-msgstr ""
+msgstr "1b609b52537..."
msgid "FlowdockService|Send event notifications from GitLab to Flowdock flows."
msgstr ""
@@ -15495,12 +15737,12 @@ msgid "For additional information, review your group membership: %{link_to} or c
msgstr ""
msgid "For each job, clone the repository."
-msgstr ""
+msgstr "Para cada trabajo, clone el repositorio."
msgid "For each job, re-use the project workspace. If the workspace doesn't exist, use %{code_open}git clone%{code_close}."
msgstr ""
-msgid "For example, the application using the token or the purpose of the token."
+msgid "For example, the application using the token or the purpose of the token. Do not give sensitive information for the name of the token, as it will be visible to all %{resource_type} members."
msgstr ""
msgid "For files larger than this limit, only index the file name. The file content is neither indexed nor searchable."
@@ -15584,9 +15826,6 @@ msgstr "Público"
msgid "ForkProject|Select a namespace"
msgstr "Seleccione un espacio de nombres"
-msgid "ForkProject|Select a namespace to fork the project"
-msgstr ""
-
msgid "ForkProject|The project can be accessed by any logged in user."
msgstr ""
@@ -15606,7 +15845,7 @@ msgid "ForkSuggestion|Fork"
msgstr ""
msgid "ForkSuggestion|You can’t %{edit_start}edit%{edit_end} files directly in this project. Fork this project and submit a merge request with your changes."
-msgstr ""
+msgstr "No puede %{edit_start}editar%{edit_end} archivos directamente en este proyecto. Haga un fork de este proyecto y envíe un merge request con sus cambios."
msgid "ForkedFromProjectPath|Forked from"
msgstr "Bifurcado de"
@@ -15683,6 +15922,9 @@ msgstr ""
msgid "Full name"
msgstr "Nombre completo"
+msgid "GCP region configured"
+msgstr ""
+
msgid "GPG Key ID:"
msgstr "ID de la clave GPG:"
@@ -15765,10 +16007,10 @@ msgid "Geo|%{boldStart}N/A%{boldEnd}: Geo does not verify this component yet. Se
msgstr ""
msgid "Geo|%{component} synced"
-msgstr ""
+msgstr "Geo|%{component} sincronizado"
msgid "Geo|%{component} verified"
-msgstr ""
+msgstr "Geo|%{component} verificado"
msgid "Geo|%{label} can't be blank"
msgstr "%{label} no puede estar en blanco"
@@ -15786,7 +16028,7 @@ msgid "Geo|%{name} is scheduled for re-verify"
msgstr "Se ha programado %{name} para que se vuelva a comprobar"
msgid "Geo|%{timeAgoStr} (%{pendingEvents} events)"
-msgstr ""
+msgstr "Geo|%{timeAgoStr} (%{pendingEvents} eventos)"
msgid "Geo|%{title} checksum progress"
msgstr ""
@@ -15795,13 +16037,13 @@ msgid "Geo|(%{timeAgo})"
msgstr ""
msgid "Geo|Add site"
-msgstr ""
+msgstr "Añadir sitio"
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"
-msgstr ""
+msgstr "Todo"
msgid "Geo|All %{replicable_name}"
msgstr "Todo %{replicable_name}"
@@ -15863,6 +16105,9 @@ msgstr ""
msgid "Geo|Failed"
msgstr "Fallido"
+msgid "Geo|Filter Geo sites"
+msgstr ""
+
msgid "Geo|Filter by name"
msgstr "Filtrar por nombre"
@@ -15882,7 +16127,7 @@ msgid "Geo|Geo supports replication of many data types."
msgstr ""
msgid "Geo|Go to the primary site"
-msgstr ""
+msgstr "Ir al sitio principal"
msgid "Geo|Healthy"
msgstr "Saludable"
@@ -15942,10 +16187,10 @@ msgid "Geo|Nothing to checksum"
msgstr ""
msgid "Geo|Nothing to synchronize"
-msgstr ""
+msgstr "No hay nada que sincronizar"
msgid "Geo|Nothing to verify"
-msgstr ""
+msgstr "No hay nada que verificar"
msgid "Geo|Offline"
msgstr ""
@@ -16182,10 +16427,10 @@ msgid "Get a free instance review"
msgstr "Obtenga una revisión de instancia gratuita"
msgid "Get a free trial"
-msgstr ""
+msgstr "Obtenga una prueba gratuita"
msgid "Get a support subscription"
-msgstr ""
+msgstr "Obtenga una suscripción de soporte"
msgid "Get started"
msgstr "Empezar"
@@ -16236,10 +16481,10 @@ msgid "Git shallow clone"
msgstr ""
msgid "Git strategy"
-msgstr ""
+msgstr "Estrategia de Git"
msgid "Git transfer in progress"
-msgstr ""
+msgstr "Transferencia de Git en progreso"
msgid "Git version"
msgstr "Versión de Git"
@@ -16274,6 +16519,12 @@ msgstr "Importar desde GitLab"
msgid "GitLab Issue"
msgstr "Incidencia de GitLab"
+msgid "GitLab KAS"
+msgstr ""
+
+msgid "GitLab Memberships CSV Export"
+msgstr ""
+
msgid "GitLab Pages"
msgstr "GitLab Pages"
@@ -16290,10 +16541,10 @@ msgid "GitLab User"
msgstr "Usuario de GitLab"
msgid "GitLab Workhorse"
-msgstr ""
+msgstr "GitLab Workhorse"
msgid "GitLab account request rejected"
-msgstr ""
+msgstr "Solicitud de cuenta de GitLab rechazada"
msgid "GitLab and Google Cloud configuration seems to be incomplete. This probably can be fixed by your GitLab administration team. You may share these logs with them:"
msgstr ""
@@ -16322,6 +16573,9 @@ 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 free to use. Many features for larger teams are part of our %{link_start}paid products%{link_end}. You can try Ultimate for free without any obligation or payment details."
+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 "GitLab está obteniendo un certificado SSL desde Let's Encrypt para este dominio. Este proceso puede llevar algo de tiempo. Por favor, inténtelo de nuevo más tarde."
@@ -16332,7 +16586,7 @@ msgid "GitLab is undergoing maintenance and is operating in read-only mode."
msgstr ""
msgid "GitLab logo"
-msgstr ""
+msgstr "Logotipo de GitLab"
msgid "GitLab member or Email address"
msgstr "Miembro de GitLab o dirección de correo electrónico"
@@ -16347,7 +16601,7 @@ msgid "GitLab runs a background job to export pseudonymized CSVs of the GitLab d
msgstr ""
msgid "GitLab single sign-on URL"
-msgstr ""
+msgstr "URL de inicio de sesión único de GitLab"
msgid "GitLab username"
msgstr "Nombre de usuario de GitLab"
@@ -16448,7 +16702,7 @@ msgstr "Verificado"
msgid "GitLabPages|When enabled, all attempts to visit your website through HTTP are automatically redirected to HTTPS using a response with status code 301. Requires a valid certificate for all domains. %{docs_link_start}Learn more.%{link_end}"
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. %{docs_link_start}Learn more.%{link_end}"
+msgid "GitLabPages|When using Pages under the general domain of a GitLab instance (%{pages_host}), you cannot use HTTPS with subdomains of subdomains. If your namespace or groupname contains a dot, it does not work. This is a limitation of the HTTP Over TLS protocol. HTTP pages work if you don't redirect HTTP to HTTPS. %{docs_link_start}Learn more.%{link_end}"
msgstr ""
msgid "GitLabPages|With GitLab Pages you can host your static website directly from your GitLab repository. %{docs_link_start}Learn more.%{link_end}"
@@ -16464,13 +16718,13 @@ msgid "Gitaly Servers"
msgstr "Servidores de Gitaly"
msgid "Gitaly relative path:"
-msgstr ""
+msgstr "Ruta relativa de Gitaly:"
msgid "Gitaly storage name:"
-msgstr ""
+msgstr "Nombre de almacenamiento de Gitaly:"
msgid "Gitaly timeouts"
-msgstr ""
+msgstr "Tiempos de espera de Gitaly"
msgid "Gitaly|Address"
msgstr "Dirección"
@@ -16506,7 +16760,7 @@ msgid "Gitpod"
msgstr ""
msgid "Gitpod|Enable Gitpod integration"
-msgstr ""
+msgstr "Habilitar integración con Gitpod"
msgid "Gitpod|Gitpod URL"
msgstr "URL de Gitpod"
@@ -16542,10 +16796,10 @@ msgid "GlobalSearch|%{count} default results provided. Use the up and down arrow
msgstr ""
msgid "GlobalSearch|Issues I've created"
-msgstr ""
+msgstr "Incidencias que he creado"
msgid "GlobalSearch|Issues assigned to me"
-msgstr ""
+msgstr "Incidencias asignadas a mí"
msgid "GlobalSearch|Merge requests I've created"
msgstr ""
@@ -16625,9 +16879,6 @@ msgstr "Ir a archivos"
msgid "Go to find file"
msgstr "Ir a la búsqueda de archivos"
-msgid "Go to fork"
-msgstr ""
-
msgid "Go to issue boards"
msgstr "Ir al tablero de incidencias"
@@ -16734,13 +16985,13 @@ msgid "Google Cloud"
msgstr ""
msgid "Google Cloud Project"
-msgstr ""
+msgstr "Projecto de Google Cloud"
msgid "Google Cloud authorizations required"
msgstr ""
msgid "Google Cloud project"
-msgstr ""
+msgstr "Projecto de Google Cloud"
msgid "Google Cloud project misconfigured"
msgstr ""
@@ -16788,19 +17039,19 @@ msgid "Grant access"
msgstr "Conceder acceso"
msgid "Grant write permissions to this key"
-msgstr ""
+msgstr "Conceder permisos de escritura a esta clave"
msgid "Graph"
msgstr "Gráfico"
msgid "GraphViewType|Job dependencies"
-msgstr ""
+msgstr "Dependencias del trabajo"
msgid "GraphViewType|Show dependencies"
-msgstr ""
+msgstr "Mostrar dependencias"
msgid "GraphViewType|Stage"
-msgstr ""
+msgstr "Etapa"
msgid "Graphs"
msgstr "Gráficos"
@@ -16835,9 +17086,6 @@ msgstr "Estado del grupo GIT LFS:"
msgid "Group Hooks"
msgstr "Hooks de grupo"
-msgid "Group ID"
-msgstr "Id de grupo"
-
msgid "Group Owner must have signed in with SAML before enabling Group Managed Accounts"
msgstr "El propietario del grupo debe haber iniciado sesión con SAML antes de habilitar las cuentas administradas de grupo"
@@ -16851,7 +17099,7 @@ msgid "Group access token creation is disabled in this group. You can still use
msgstr ""
msgid "Group application: %{name}"
-msgstr ""
+msgstr "Aplicación de grupo: %{name}"
msgid "Group applications"
msgstr ""
@@ -16865,9 +17113,6 @@ msgstr "Avatar del grupo"
msgid "Group by"
msgstr "Agrupar por"
-msgid "Group description"
-msgstr ""
-
msgid "Group description (optional)"
msgstr "Descripción del grupo (opcional)"
@@ -16982,7 +17227,7 @@ msgstr "Grupo: %{group_name}"
msgid "Group: %{name}"
msgstr "Grupo: %{name}"
-msgid "GroupActivityMetrics|Issues opened"
+msgid "GroupActivityMetrics|Issues created"
msgstr ""
msgid "GroupActivityMetrics|Last 90 days"
@@ -16991,7 +17236,7 @@ msgstr ""
msgid "GroupActivityMetrics|Members added"
msgstr ""
-msgid "GroupActivityMetrics|Merge Requests opened"
+msgid "GroupActivityMetrics|Merge Requests created"
msgstr ""
msgid "GroupActivityMetrics|Recent activity"
@@ -17028,13 +17273,13 @@ msgid "GroupRoadmap|%{startDateInWords} – %{endDateInWords}"
msgstr ""
msgid "GroupRoadmap|Loading epics"
-msgstr ""
+msgstr "Cargando tareas épicas"
msgid "GroupRoadmap|No start and end date"
-msgstr ""
+msgstr "Sin fecha de inicio y sin fecha de finalización"
msgid "GroupRoadmap|No start date – %{dateWord}"
-msgstr ""
+msgstr "No hay fecha de inicio – %{dateWord}"
msgid "GroupRoadmap|Something went wrong while fetching epics"
msgstr " Se ha producido un error al obtener las tareas épicas"
@@ -17079,10 +17324,10 @@ msgid "GroupSAML|Active SAML Group Links (%{count})"
msgstr ""
msgid "GroupSAML|An error occurred generating your SCIM token. Please try again."
-msgstr ""
+msgstr "Se ha producido un error al generar su token SCIM. Por favor, inténtelo de nuevo."
msgid "GroupSAML|An error occurred resetting your SCIM token. Please try again."
-msgstr ""
+msgstr "Se ha producido un error al restablecer su token SCIM. Por favor, inténtelo de nuevo."
msgid "GroupSAML|Are you sure you want to remove the SAML group link?"
msgstr ""
@@ -17139,7 +17384,7 @@ msgid "GroupSAML|Make sure you save this token — you won't be able to access i
msgstr "Asegúrese de guardar este token - no podrá acceder a él de nuevo."
msgid "GroupSAML|Manage your group’s membership while adding another level of security with SAML."
-msgstr "Administre los miembros del grupo al agregar otro nivel de seguridad con SAML."
+msgstr "Administre los miembros del grupo al añadir otro nivel de seguridad con SAML."
msgid "GroupSAML|Members"
msgstr "Miembros"
@@ -17163,7 +17408,7 @@ msgid "GroupSAML|Prohibit outer forks for this group"
msgstr ""
msgid "GroupSAML|Reset SCIM token"
-msgstr ""
+msgstr "Restablecer token SCIM"
msgid "GroupSAML|Role to assign members of this SAML group."
msgstr ""
@@ -17172,10 +17417,10 @@ msgid "GroupSAML|SAML Group Links"
msgstr ""
msgid "GroupSAML|SAML Group Name"
-msgstr ""
+msgstr "Nombre del grupo SAML"
msgid "GroupSAML|SAML Group Name: %{saml_group_name}"
-msgstr ""
+msgstr "Nombre del grupo SAML %{saml_group_name}"
msgid "GroupSAML|SAML Response Output"
msgstr "Salida de la respuesta SAML"
@@ -17241,10 +17486,10 @@ msgid "GroupSaml|SCIM API endpoint URL"
msgstr ""
msgid "GroupSaml|Your SCIM token"
-msgstr ""
+msgstr "Su token SCIM"
msgid "GroupSelect|No matching results"
-msgstr ""
+msgstr "No hay resultados coincidentes"
msgid "GroupSelect|Search groups"
msgstr "Buscar grupos"
@@ -17282,6 +17527,9 @@ msgstr "Cambiar la URL del grupo"
msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
+msgid "GroupSettings|Choose a group path that does not start with a dash or end with a period. It can also contain alphanumeric characters and underscores."
+msgstr ""
+
msgid "GroupSettings|Compliance frameworks"
msgstr ""
@@ -17315,8 +17563,8 @@ msgstr "Exportar grupo"
msgid "GroupSettings|If not specified at the group or instance level, the default is %{default_initial_branch_name}. Does not affect existing repositories."
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 "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."
+msgid "GroupSettings|If the parent group's visibility is lower than the group's current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility."
+msgstr ""
msgid "GroupSettings|New runners registration token has been generated!"
msgstr "¡Se ha generado el token de registro para los nuevos ejecutores!"
@@ -17432,8 +17680,11 @@ msgstr "Grupos: (%{count})"
msgid "Groups and projects"
msgstr "Grupos y proyectos"
-msgid "Groups and subgroups"
-msgstr "Grupos y subgrupos"
+msgid "Groups are a great way to organize projects and people."
+msgstr ""
+
+msgid "Groups are the best way to manage projects and members."
+msgstr ""
msgid "Groups to synchronize"
msgstr "Grupos para sincronizar"
@@ -17517,7 +17768,7 @@ msgid "GroupsNew|Not all related objects are migrated. %{docs_link_start}More in
msgstr ""
msgid "GroupsNew|Personal access token"
-msgstr ""
+msgstr "Token de acceso personal"
msgid "GroupsNew|Please fill in GitLab source URL."
msgstr ""
@@ -17535,22 +17786,25 @@ msgid "GroupsNew|To import a group, navigate to the group settings for the GitLa
msgstr ""
msgid "GroupsNew|Upload file"
-msgstr ""
+msgstr "Subir archivo"
msgid "GroupsNew|e.g. h8d3f016698e..."
-msgstr ""
+msgstr "Por ejemplo, h8d3f016698..."
msgid "GroupsTree|Are you sure you want to leave the \"%{fullName}\" group?"
msgstr "¿Está seguro que desea dejar el grupo \"%{fullName}\"?"
-msgid "GroupsTree|Edit group"
-msgstr "Editar grupo"
+msgid "GroupsTree|Delete"
+msgstr ""
+
+msgid "GroupsTree|Edit"
+msgstr ""
msgid "GroupsTree|Failed to leave the group. Please make sure you are not the only owner."
msgstr "No pudiste dejar el grupo. Por favor, asegúrate que no seas el único propietario."
-msgid "GroupsTree|Leave this group"
-msgstr "Dejar este grupo"
+msgid "GroupsTree|Leave group"
+msgstr ""
msgid "GroupsTree|Loading groups"
msgstr "Cargando grupos"
@@ -17561,9 +17815,57 @@ msgstr "Lo sentimos, no existen grupos que coincidan con su búsqueda"
msgid "GroupsTree|No groups or projects matched your search"
msgstr "Lo sentimos, no existen grupos ni proyectos que coincidan con su búsqueda"
+msgid "GroupsTree|Options"
+msgstr ""
+
msgid "GroupsTree|Search by name"
msgstr "Buscar por nombre"
+msgid "Groups|Avatar will be removed. Are you sure?"
+msgstr ""
+
+msgid "Groups|Changing group URL can have unintended side effects."
+msgstr ""
+
+msgid "Groups|Checking group URL availability..."
+msgstr ""
+
+msgid "Groups|Enter a descriptive name for your group."
+msgstr ""
+
+msgid "Groups|Group ID"
+msgstr ""
+
+msgid "Groups|Group URL"
+msgstr ""
+
+msgid "Groups|Group avatar"
+msgstr ""
+
+msgid "Groups|Group description (optional)"
+msgstr ""
+
+msgid "Groups|Group name"
+msgstr ""
+
+msgid "Groups|Group path is available."
+msgstr ""
+
+msgid "Groups|Group path is unavailable. Path has been replaced with a suggested available path."
+msgstr ""
+
+msgid "Groups|Learn more"
+msgstr ""
+
+msgid "Groups|Must start with letter, digit, emoji, or underscore. Can also contain periods, dashes, spaces, and parentheses."
+msgstr ""
+
+msgid "Groups|Remove avatar"
+msgstr ""
+
+msgid "Groups|Save changes"
+msgstr ""
+
msgid "Guideline"
msgstr "Guía"
@@ -17573,6 +17875,9 @@ msgstr "HAR (archivo HTTP)"
msgid "HAR file path or URL"
msgstr "Ruta del archivo HAR o URL"
+msgid "HTTP Archive (HAR)"
+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 básico: Acceso denegado\\nDebe utilizar un token de acceso personal con alcance 'api' para Git a través de HTTP.\\nPuedes generar uno a %{profile_personal_access_tokens_url}"
@@ -17589,16 +17894,16 @@ msgid "Have a quick chat with us about your experience."
msgstr ""
msgid "Have more to say about GitLab?"
-msgstr ""
+msgstr "¿Tiene más cosas que decir sobre GitLab?"
msgid "Header logo"
-msgstr ""
+msgstr "Logo de cabecera"
msgid "Header logo was successfully removed."
msgstr "Se ha eliminado el logo del encabezado correctamente."
msgid "Header logo will be removed. Are you sure?"
-msgstr ""
+msgstr "Se eliminará el logotipo de la cabecera. ¿Está seguro?"
msgid "Header message"
msgstr "Encabezado del mensaje"
@@ -17610,7 +17915,7 @@ msgid "HeaderAction|issue"
msgstr "incidencia"
msgid "Headers"
-msgstr ""
+msgstr "Encabezados"
msgid "Heading 1"
msgstr ""
@@ -17676,7 +17981,7 @@ msgid "HelloMessage|Does this page need fixes or improvements? Open an issue or
msgstr ""
msgid "HelloMessage|Welcome to GitLab!"
-msgstr ""
+msgstr "¡Bienvenido a GitLab!"
msgid "Help"
msgstr "Ayuda"
@@ -17779,7 +18084,7 @@ msgid "Hierarchy|These items are unavailable in the current structure."
msgstr ""
msgid "Hierarchy|Unavailable structure"
-msgstr ""
+msgstr "Estructura no disponible"
msgid "Hierarchy|You can start using these items now."
msgstr ""
@@ -17797,7 +18102,7 @@ msgid "HighlightBar|Alert start time:"
msgstr ""
msgid "HighlightBar|Original alert:"
-msgstr ""
+msgstr "Alerta original:"
msgid "HighlightBar|Time to SLA:"
msgstr ""
@@ -17854,10 +18159,10 @@ msgid "How do I configure it?"
msgstr ""
msgid "How do I configure runners?"
-msgstr ""
+msgstr "¿Cómo configuro los ejecutores?"
msgid "How do I configure this integration?"
-msgstr ""
+msgstr "¿Cómo configuro esta integración?"
msgid "How do I generate it?"
msgstr ""
@@ -17902,22 +18207,22 @@ msgid "I want to explore GitLab to see if it’s worth switching to"
msgstr ""
msgid "I want to learn the basics of Git"
-msgstr ""
+msgstr "Quiero aprender los conceptos básicos de Git"
msgid "I want to move my repository to GitLab from somewhere else"
-msgstr ""
+msgstr "Quiero mover mi repositorio de código a GitLab desde otro sitio"
msgid "I want to store my code"
-msgstr ""
+msgstr "Quiero almacenar mi código"
msgid "I want to use GitLab CI with my existing repository"
-msgstr ""
+msgstr "Quiero utilizar GitLab CI con mi repositorio de código existente"
msgid "I'd like to receive updates about GitLab via email"
-msgstr ""
+msgstr "Me gustaría recibir actualizaciones sobre GitLab por correo electrónico"
msgid "I'm signing up for GitLab because:"
-msgstr ""
+msgstr "Me registro en GitLab porque:"
msgid "ID"
msgstr "ID"
@@ -17973,6 +18278,9 @@ msgstr "INFO: Su clave SSH ha caducado. Por favor, genere una nueva clave."
msgid "INFO: Your SSH key is expiring soon. Please generate a new key."
msgstr "INFO: Su clave SSH caducará pronto. Por favor genere una nueva clave."
+msgid "IP"
+msgstr ""
+
msgid "IP Address"
msgstr "Direccion IP"
@@ -18004,9 +18312,12 @@ msgid "IdentityVerification|Before you create your group, we need you to verify
msgstr ""
msgid "IdentityVerification|Create a project"
-msgstr ""
+msgstr "Crear un proyecto"
msgid "IdentityVerification|Verify your identity"
+msgstr "Verifique su identidad"
+
+msgid "IdentityVerification|You can always verify your account at a later time to create a group."
msgstr ""
msgid "If any indexed field exceeds this limit, it is truncated to this number of characters. The rest of the content is neither indexed nor searchable. This does not apply to repository and wiki indexing. For unlimited characters, set this to 0."
@@ -18022,7 +18333,7 @@ msgid "If checked, group owners can manage LDAP group links and LDAP member over
msgstr "Si está marcado, los propietarios de grupos pueden administrar enlaces de grupo LDAP y anular los miembros LDAP"
msgid "If checked, new group memberships and permissions can only be added via LDAP synchronization"
-msgstr "Si se marca, las nuevas miembros del grupo y los permisos sólo se pueden agregar a través de la sincronización vía LDAP"
+msgstr "Si se marca, las nuevas miembros del grupo y los permisos sólo se pueden añadir a través de la sincronización vía 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 ""
@@ -18066,6 +18377,9 @@ msgstr "Si utiliza GitHub, verá los estados del pipeline en GitHub para sus com
msgid "If you add %{codeStart}needs%{codeEnd} to jobs in your pipeline you'll be able to view the %{codeStart}needs%{codeEnd} relationships between jobs in this tab as a %{linkStart}Directed Acyclic Graph (DAG)%{linkEnd}."
msgstr ""
+msgid "If you are added to a project, it will be displayed here."
+msgstr ""
+
msgid "If you did not initiate these sign-in attempts, please reach out to your administrator or enable two-factor authentication (2FA) on your account."
msgstr ""
@@ -18236,7 +18550,7 @@ msgid "Import repository"
msgstr "Importar repositorio"
msgid "Import requirements"
-msgstr ""
+msgstr "Importar requisitos"
msgid "Import started by: %{importInitiator}"
msgstr "Importación iniciada por: %{importInitiator}"
@@ -18251,13 +18565,13 @@ msgid "Import timed out. Import took longer than %{import_jobs_expiration} secon
msgstr "Se agotó el tiempo de espera para el proceso de importación. Este proceso ha tardado más de %{import_jobs_expiration} segundos"
msgid "ImportAProjectModal|Import from a project"
-msgstr ""
+msgstr "Importar desde un proyecto"
msgid "ImportAProjectModal|Import members from another project"
-msgstr ""
+msgstr "Importar miembros desde otro proyecto"
msgid "ImportAProjectModal|Import project members"
-msgstr ""
+msgstr "Importar miembros del proyecto"
msgid "ImportAProjectModal|Only project members (not group members) are imported, and they get the same permissions as the project you import from."
msgstr ""
@@ -18372,12 +18686,24 @@ msgstr ""
msgid "InProductMarketing|3 ways to dive into GitLab CI/CD"
msgstr ""
+msgid "InProductMarketing|A single application eliminates complex integrations, data chokepoints, and toolchain maintenance, resulting in greater productivity and lower cost."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features, build more efficiently, strengthen security and compliance."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features."
+msgstr ""
+
msgid "InProductMarketing|Actually, GitLab makes the team work (better)"
msgstr ""
msgid "InProductMarketing|And finally %{deploy_link} a Python application."
msgstr ""
+msgid "InProductMarketing|And many more..."
+msgstr ""
+
msgid "InProductMarketing|Are your runners ready?"
msgstr "¿Sus ejecutores están preparados?"
@@ -18385,10 +18711,10 @@ msgid "InProductMarketing|Automated security scans directly within GitLab"
msgstr ""
msgid "InProductMarketing|Be a DevOps hero"
-msgstr ""
+msgstr "Conviértase en un héroe de DevOps"
msgid "InProductMarketing|Beef up your security"
-msgstr ""
+msgstr "Refuerce su seguridad"
msgid "InProductMarketing|Better code in less time"
msgstr ""
@@ -18396,15 +18722,33 @@ msgstr ""
msgid "InProductMarketing|Blog"
msgstr ""
+msgid "InProductMarketing|Break down silos to coordinate seamlessly across development, operations, and security with a consistent experience across the development lifecycle."
+msgstr ""
+
+msgid "InProductMarketing|Burn up/down charts"
+msgstr ""
+
msgid "InProductMarketing|By enabling code owners and required merge approvals the right person will review the right MR. This is a win-win: cleaner code and a more efficient review process."
msgstr ""
msgid "InProductMarketing|Click on the number below that corresponds with your answer — 1 being very difficult, 5 being very easy."
msgstr ""
+msgid "InProductMarketing|Code owners"
+msgstr ""
+
msgid "InProductMarketing|Code owners and required merge approvals are part of the paid tiers of GitLab. You can start a free 30-day trial of GitLab Ultimate and enable these features in less than 5 minutes with no credit card required."
msgstr ""
+msgid "InProductMarketing|Code review analytics"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration across stages in GitLab"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration made easy"
+msgstr ""
+
msgid "InProductMarketing|Create a custom CI runner with just a few clicks"
msgstr ""
@@ -18414,12 +18758,21 @@ msgstr ""
msgid "InProductMarketing|Create a project in GitLab in 5 minutes"
msgstr "Cree un proyecto en GitLab en 5 minutos"
+msgid "InProductMarketing|Create well-defined workflows by using scoped labels on issues, merge requests, and epics. Labels with the same scope cannot be used together, which prevents conflicts."
+msgstr ""
+
msgid "InProductMarketing|Create your first project!"
msgstr "¡Cree su primer proyecto!"
+msgid "InProductMarketing|Define who owns specific files or directories, so the right reviewers are suggested when a merge request introduces changes to those files."
+msgstr ""
+
msgid "InProductMarketing|Deliver Better Products Faster"
msgstr ""
+msgid "InProductMarketing|Dependency scanning"
+msgstr ""
+
msgid "InProductMarketing|Did you know teams that use GitLab are far more efficient?"
msgstr ""
@@ -18429,15 +18782,27 @@ msgstr ""
msgid "InProductMarketing|Dig in and create a project and a repo"
msgstr ""
+msgid "InProductMarketing|Discover Premium & Ultimate"
+msgstr ""
+
+msgid "InProductMarketing|Discover Premium & Ultimate."
+msgstr ""
+
msgid "InProductMarketing|Do you have a minute?"
msgstr "¿Tiene un minuto?"
msgid "InProductMarketing|Do you have a teammate who would be perfect for this task?"
msgstr "¿Tiene un compañero que sería perfecto para esta tarea?"
+msgid "InProductMarketing|Dynamic application security testing"
+msgstr ""
+
msgid "InProductMarketing|Easy"
msgstr ""
+msgid "InProductMarketing|Epics"
+msgstr ""
+
msgid "InProductMarketing|Expand your DevOps journey with a free GitLab trial"
msgstr "Amplíe su viaje de DevOps con una prueba gratuita de GitLab"
@@ -18459,9 +18824,15 @@ msgstr ""
msgid "InProductMarketing|Feel the need for speed?"
msgstr ""
+msgid "InProductMarketing|Find and fix bottlenecks in your code review process by understanding how long open merge requests have been in review."
+msgstr ""
+
msgid "InProductMarketing|Find out how your teams are really doing"
msgstr ""
+msgid "InProductMarketing|Find out if your external libraries are safe. Run dependency scanning jobs that check for known vulnerabilities in your external libraries."
+msgstr ""
+
msgid "InProductMarketing|Follow our steps"
msgstr "Siga nuestros pasos"
@@ -18472,10 +18843,10 @@ msgid "InProductMarketing|Get going with CI/CD quickly using our %{quick_start_l
msgstr ""
msgid "InProductMarketing|Get our import guides"
-msgstr ""
+msgstr "Obtenga nuestras guías de importación"
msgid "InProductMarketing|Get started today"
-msgstr ""
+msgstr "Comience hoy"
msgid "InProductMarketing|Get started today with a 30-day GitLab Ultimate trial, no credit card required."
msgstr ""
@@ -18498,6 +18869,9 @@ msgstr ""
msgid "InProductMarketing|GitLab is better with teammates to help out!"
msgstr ""
+msgid "InProductMarketing|GitLab is infrastructure agnostic (supporting GCP, AWS, Azure, OpenShift, VMWare, On Prem, Bare Metal, and more), offering a consistent workflow experience – irrespective of the environment."
+msgstr ""
+
msgid "InProductMarketing|GitLab provides static application security testing (SAST), dynamic application security testing (DAST), container scanning, and dependency scanning to help you deliver secure applications along with license compliance."
msgstr ""
@@ -18508,7 +18882,7 @@ msgid "InProductMarketing|GitLab's premium tiers are designed to make you, your
msgstr ""
msgid "InProductMarketing|Give us one minute..."
-msgstr ""
+msgstr "InProductMarketing|Danos un minuto..."
msgid "InProductMarketing|Go farther with GitLab"
msgstr ""
@@ -18532,10 +18906,10 @@ msgid "InProductMarketing|How many days does it take our team to complete variou
msgstr ""
msgid "InProductMarketing|How to build and test faster"
-msgstr ""
+msgstr "InProductMarketing|Cómo construir y probar más rápido"
msgid "InProductMarketing|If you don't want to receive marketing emails directly from GitLab, %{marketing_preference_link}."
-msgstr ""
+msgstr "InProductMarketing|Si no desea seguir recibiendo correos electrónicos de marketing directamente desde GitLab, %{marketing_preference_link}."
msgid "InProductMarketing|If you no longer wish to receive marketing emails from us,"
msgstr ""
@@ -18559,91 +18933,124 @@ msgid "InProductMarketing|Invite your colleagues and start shipping code faster.
msgstr ""
msgid "InProductMarketing|Invite your colleagues to join in less than one minute"
-msgstr ""
+msgstr "InProductMarketing|Invite a sus compañeros a unirse en menos de un minuto"
msgid "InProductMarketing|Invite your colleagues today"
-msgstr ""
+msgstr "InProductMarketing|Invite a sus colegas hoy"
msgid "InProductMarketing|Invite your team in less than 60 seconds"
-msgstr ""
+msgstr "InProductMarketing|Invite a su equipo en menos de 60 segundos"
msgid "InProductMarketing|Invite your team now"
-msgstr ""
+msgstr "InProductMarketing|Invite a su equipo ahora"
msgid "InProductMarketing|Invite your team today to build better code (and processes) together"
-msgstr ""
+msgstr "InProductMarketing|Invite a su equipo hoy mismo a crear mejor código y mejores procesos juntos"
msgid "InProductMarketing|Invite your teammates to GitLab"
-msgstr ""
+msgstr "InProductMarketing|Invite a sus compañeros de equipo a GitLab"
msgid "InProductMarketing|Invite your teammates to help"
-msgstr ""
+msgstr "InProductMarketing|Invite a tus compañeros de equipo a ayudar"
msgid "InProductMarketing|Invite your teammates today and build better code together. You can even assign tasks to new teammates such as setting up CI/CD, to help get projects up and running."
msgstr ""
msgid "InProductMarketing|It's all in the stats"
-msgstr ""
+msgstr "InProductMarketing|Está todo en las estadísticas"
msgid "InProductMarketing|It's also possible to simply %{external_repo_link} in order to take advantage of GitLab's CI/CD."
msgstr ""
+msgid "InProductMarketing|Keep your code quality high by defining who should approve merge requests and how many approvals are required."
+msgstr ""
+
msgid "InProductMarketing|Launch GitLab CI/CD in 20 minutes or less"
msgstr ""
+msgid "InProductMarketing|Lower cost of development"
+msgstr ""
+
+msgid "InProductMarketing|Make it easier to collaborate on high-level ideas by grouping related issues in an epic."
+msgstr ""
+
msgid "InProductMarketing|Making the switch? It's easier than you think to import your projects into GitLab. Move %{github_link}, or import something %{bitbucket_link}."
msgstr ""
msgid "InProductMarketing|Master the art of importing!"
msgstr ""
+msgid "InProductMarketing|Merge request approval rule"
+msgstr ""
+
msgid "InProductMarketing|Move on to easily creating a Pages website %{ci_template_link}"
msgstr ""
msgid "InProductMarketing|Multiple owners, confusing workstreams? We've got you covered"
msgstr ""
+msgid "InProductMarketing|Multiple required approvers"
+msgstr ""
+
msgid "InProductMarketing|Need an alternative to importing?"
msgstr ""
msgid "InProductMarketing|Neutral"
-msgstr ""
+msgstr "InProductMarketing|Neutral"
msgid "InProductMarketing|No credit card required."
-msgstr ""
+msgstr "No es necesaria una tarjeta de crédito."
msgid "InProductMarketing|Our tool brings all the things together"
+msgstr "InProductMarketing|Nuestra herramienta reúne todas las cosas"
+
+msgid "InProductMarketing|Protect your web application by using DAST to examine for vulnerabilities in deployed environments."
msgstr ""
msgid "InProductMarketing|Rapid development, simplified"
-msgstr ""
+msgstr "InProductMarketing|Desarrollo rápido, simplificado"
msgid "InProductMarketing|Reduce Security & Compliance Risk"
+msgstr "InProductMarketing|Reduzca el riesgo de seguridad y cumplimiento"
+
+msgid "InProductMarketing|Require multiple approvers on a merge request, so you know it's in good shape before it's merged."
msgstr ""
-msgid "InProductMarketing|Security that's integrated into your development lifecycle"
+msgid "InProductMarketing|Roadmaps"
+msgstr ""
+
+msgid "InProductMarketing|Scoped labels"
msgstr ""
+msgid "InProductMarketing|Security that's integrated into your development lifecycle"
+msgstr "InProductMarketing|Seguridad integrada en su ciclo de vida de desarrollo"
+
msgid "InProductMarketing|Sometimes you're not ready to make a full transition to a new tool. If you're not ready to fully commit, %{mirroring_link} gives you a safe way to try out GitLab in parallel with your current tool."
msgstr ""
-msgid "InProductMarketing|Spin up an autoscaling runner in GitLab"
+msgid "InProductMarketing|Speed. Efficiency. Trust."
msgstr ""
+msgid "InProductMarketing|Spin up an autoscaling runner in GitLab"
+msgstr "InProductMarketing|Ponga un ejecutor con escalado automático en GitLab"
+
msgid "InProductMarketing|Start a GitLab Ultimate trial today in less than one minute, no credit card required."
-msgstr ""
+msgstr "InProductMarketing|Comience una prueba de GitLab Ultimate hoy en menos de un minuto, sin necesidad de tarjeta de crédito."
msgid "InProductMarketing|Start a Self-Managed trial"
+msgstr "InProductMarketing|Comenzar una prueba autogestionada"
+
+msgid "InProductMarketing|Start a free trial"
msgstr ""
msgid "InProductMarketing|Start a free trial of GitLab Ultimate – no credit card required"
-msgstr ""
+msgstr "InProductMarketing|Comience una prueba gratuita de GitLab Ultimate: sin necesidad de una tarjeta de crédito"
msgid "InProductMarketing|Start a trial"
-msgstr ""
+msgstr "InProductMarketing|Iniciar una prueba"
msgid "InProductMarketing|Start by %{performance_link}"
-msgstr ""
+msgstr "InProductMarketing|Comenzar por %{performance_link}"
msgid "InProductMarketing|Start by importing your projects"
msgstr ""
@@ -18652,7 +19059,7 @@ msgid "InProductMarketing|Start with a GitLab Ultimate free trial"
msgstr ""
msgid "InProductMarketing|Start your trial now!"
-msgstr ""
+msgstr "InProductMarketing|¡Comience su prueba ahora!"
msgid "InProductMarketing|Start your trial today to experience single application success and discover all the features of GitLab Ultimate for free!"
msgstr ""
@@ -18702,14 +19109,17 @@ msgstr ""
msgid "InProductMarketing|To understand and get the most out of GitLab, start at the beginning and %{project_link}. In GitLab, repositories are part of a project, so after you've created your project you can go ahead and %{repo_link}."
msgstr ""
+msgid "InProductMarketing|Track completed issues in a chart, so you can see how a milestone is progressing at a glance."
+msgstr ""
+
msgid "InProductMarketing|Try GitLab Ultimate for free"
msgstr ""
msgid "InProductMarketing|Try it out"
-msgstr ""
+msgstr "InProductMarketing|Pruébalo"
msgid "InProductMarketing|Try it yourself"
-msgstr ""
+msgstr "InProductMarketing|Pruébelo usted mismo"
msgid "InProductMarketing|Turn coworkers into collaborators"
msgstr ""
@@ -18738,6 +19148,9 @@ msgstr "Muy difícil"
msgid "InProductMarketing|Very easy"
msgstr ""
+msgid "InProductMarketing|Visualize your epics and milestones in a timeline."
+msgstr ""
+
msgid "InProductMarketing|Want to host GitLab on your servers?"
msgstr ""
@@ -18754,11 +19167,14 @@ msgid "InProductMarketing|When your team is on GitLab these answers are a click
msgstr ""
msgid "InProductMarketing|Working in GitLab = more efficient"
-msgstr ""
+msgstr "Trabajar en GitLab = más eficiente"
msgid "InProductMarketing|YouTube"
msgstr "YouTube"
+msgid "InProductMarketing|Your software, deployed your way"
+msgstr ""
+
msgid "InProductMarketing|Your teams can be more efficient"
msgstr "Sus equipos pueden ser más eficientes"
@@ -18879,9 +19295,18 @@ msgstr "SLA omitido"
msgid "IncidentManagement|No incidents to display."
msgstr "No hay incidentes que mostrar."
+msgid "IncidentManagement|None"
+msgstr ""
+
msgid "IncidentManagement|Open"
msgstr "Abierto"
+msgid "IncidentManagement|Page your team with escalation policies"
+msgstr ""
+
+msgid "IncidentManagement|Paged"
+msgstr ""
+
msgid "IncidentManagement|Published"
msgstr "Publicado"
@@ -18891,6 +19316,9 @@ msgstr "Publicado en la página de estado"
msgid "IncidentManagement|Severity"
msgstr "Gravedad"
+msgid "IncidentManagement|Status"
+msgstr ""
+
msgid "IncidentManagement|There are no closed incidents"
msgstr "No hay incidentes cerrados"
@@ -18909,6 +19337,9 @@ msgstr "Desconocido"
msgid "IncidentManagement|Unpublished"
msgstr "Sin publicar"
+msgid "IncidentManagement|Use escalation policies to automatically page your team when incidents are created."
+msgstr ""
+
msgid "IncidentSettings|Activate \"time to SLA\" countdown timer"
msgstr ""
@@ -18919,7 +19350,7 @@ msgid "IncidentSettings|Grafana integration"
msgstr "Integración de Grafana"
msgid "IncidentSettings|Incident settings"
-msgstr ""
+msgstr "Configuración de incidentes"
msgid "IncidentSettings|Incidents"
msgstr "Incidentes"
@@ -18931,7 +19362,7 @@ msgid "IncidentSettings|PagerDuty integration"
msgstr "Integración con PagerDuty"
msgid "IncidentSettings|Time limit"
-msgstr ""
+msgstr "Límite de tiempo"
msgid "IncidentSettings|Time limit must be a multiple of 15 minutes."
msgstr ""
@@ -18949,31 +19380,34 @@ msgid "IncidentSettings|hours"
msgstr "horas"
msgid "IncidentSettings|minutes"
-msgstr ""
+msgstr "minutos"
msgid "Incidents"
msgstr "Incidentes"
-msgid "Incidents|Add a URL"
-msgstr "Añadir una URL"
+msgid "Incidents|Add image details"
+msgstr ""
+
+msgid "Incidents|Add text or a link to display with your image. If you don't add either, the file name displays instead."
+msgstr ""
msgid "Incidents|Drop or %{linkStart}upload%{linkEnd} a metric screenshot to attach it to the incident"
msgstr ""
msgid "Incidents|Must start with http or https"
-msgstr ""
+msgstr "Debe comenzar con http o https"
msgid "Incidents|There was an issue deleting the image."
-msgstr ""
+msgstr "Se ha producido un problema al eliminar la imagen."
msgid "Incidents|There was an issue loading metric images."
-msgstr ""
+msgstr "Se ha producido un problema al cargar las métricas de las imágenes."
-msgid "Incidents|There was an issue uploading your image."
+msgid "Incidents|There was an issue updating your image."
msgstr ""
-msgid "Incidents|You can optionally add a URL to link users to the original graph."
-msgstr ""
+msgid "Incidents|There was an issue uploading your image."
+msgstr "Se ha producido un problema al cargar su imagen."
msgid "Incident|Alert details"
msgstr "Detalles de la alerta"
@@ -18981,9 +19415,18 @@ msgstr "Detalles de la alerta"
msgid "Incident|Are you sure you wish to delete this image?"
msgstr "¿Está seguro que desea eliminar esta imagen?"
+msgid "Incident|Delete image"
+msgstr ""
+
msgid "Incident|Deleting %{filename}"
msgstr "Eliminando %{filename}"
+msgid "Incident|Edit image text or link"
+msgstr ""
+
+msgid "Incident|Editing %{filename}"
+msgstr ""
+
msgid "Incident|Metrics"
msgstr "Métricas"
@@ -19138,10 +19581,10 @@ msgid "Insert code"
msgstr "Insertar código"
msgid "Insert column after"
-msgstr ""
+msgstr "Insertar columna después"
msgid "Insert column before"
-msgstr ""
+msgstr "Insertar columna antes"
msgid "Insert image"
msgstr "Insertar imagen"
@@ -19153,10 +19596,10 @@ msgid "Insert link"
msgstr "Insertar un enlace"
msgid "Insert row after"
-msgstr ""
+msgstr "Insertar fila después"
msgid "Insert row before"
-msgstr ""
+msgstr "Insertar fila antes"
msgid "Insert suggestion"
msgstr "Insertar sugerencia"
@@ -19253,12 +19696,18 @@ msgstr ""
msgid "Integrations|Branches for which notifications are to be sent"
msgstr ""
+msgid "Integrations|Clear if using a self-signed certificate."
+msgstr ""
+
msgid "Integrations|Comment detail:"
msgstr "Detalles del comentario:"
msgid "Integrations|Comment settings:"
msgstr "Configuración de los comentarios:"
+msgid "Integrations|Connection details"
+msgstr ""
+
msgid "Integrations|Connection failed. Please check your settings."
msgstr "Error de conexión. Por favor, compruebe su configuración."
@@ -19283,6 +19732,9 @@ msgstr "Editar el alias del proyecto"
msgid "Integrations|Enable GitLab.com slash commands in a Slack workspace."
msgstr ""
+msgid "Integrations|Enable SSL verification"
+msgstr ""
+
msgid "Integrations|Enable comments"
msgstr "Habilitar comentarios"
@@ -19361,6 +19813,9 @@ msgstr ""
msgid "Integrations|Return to GitLab for Jira"
msgstr ""
+msgid "Integrations|SSL verification"
+msgstr ""
+
msgid "Integrations|Save settings?"
msgstr "¿Guardar configuración?"
@@ -19406,9 +19861,6 @@ msgstr ""
msgid "Integrations|Use default settings"
msgstr ""
-msgid "Integrations|When you mention a Jira issue in a commit or merge request, GitLab creates a remote link and comment (if enabled)."
-msgstr ""
-
msgid "Integrations|You can now close this window and return to the GitLab for Jira application."
msgstr ""
@@ -19433,9 +19885,6 @@ msgstr ""
msgid "Integrations|can't exceed %{recipients_limit}"
msgstr ""
-msgid "Interactive developer security education."
-msgstr ""
-
msgid "Interactive mode"
msgstr "Modo interactivo"
@@ -19884,7 +20333,7 @@ msgid "Issue creation requests"
msgstr ""
msgid "Issue details"
-msgstr ""
+msgstr "Detalles de la incidencia"
msgid "Issue events"
msgstr "Eventos de incidencia"
@@ -19925,6 +20374,9 @@ msgstr "Edad"
msgid "IssueAnalytics|Assignees"
msgstr "Asignados"
+msgid "IssueAnalytics|Created by"
+msgstr ""
+
msgid "IssueAnalytics|Due date"
msgstr "Fecha de fin"
@@ -19937,9 +20389,6 @@ msgstr "Incidencia"
msgid "IssueAnalytics|Milestone"
msgstr "Hito"
-msgid "IssueAnalytics|Opened by"
-msgstr "Abierto por"
-
msgid "IssueAnalytics|Status"
msgstr "Estado"
@@ -19977,7 +20426,7 @@ msgid "IssueTracker|Issue URL"
msgstr "URL de la incidencia"
msgid "IssueTracker|New issue URL"
-msgstr ""
+msgstr "URL de la nueva incidencia"
msgid "IssueTracker|The URL to create an issue in the external issue tracker."
msgstr ""
@@ -20063,10 +20512,10 @@ msgstr "Una vez haya comenzado a crear incidencias, podremos iniciar el seguimie
msgid "IssuesAnalytics|Avg/Month:"
msgstr "Promedio mensual:"
-msgid "IssuesAnalytics|Issues opened"
-msgstr "Incidencias abiertas"
+msgid "IssuesAnalytics|Issues created"
+msgstr ""
-msgid "IssuesAnalytics|Issues opened per month"
+msgid "IssuesAnalytics|Issues created per month"
msgstr ""
msgid "IssuesAnalytics|Last 12 months"
@@ -20093,6 +20542,9 @@ msgstr ""
msgid "It looks like you have some draft commits in this branch."
msgstr ""
+msgid "It looks like you're attempting to activate your subscription. Use %{a_start}the Subscription page%{a_end} instead."
+msgstr ""
+
msgid "It may be several days before you see feature usage data."
msgstr ""
@@ -20142,7 +20594,7 @@ msgid "Iterations|Cadence name"
msgstr "Nombre de la cadencia"
msgid "Iterations|Couldn't find iteration cadence"
-msgstr ""
+msgstr "No se pudo encontrar la cadencia de iteración"
msgid "Iterations|Create cadence"
msgstr "Crear cadencia"
@@ -20151,13 +20603,13 @@ msgid "Iterations|Create cadence and start iteration"
msgstr "Crear cadencia e iniciar iteración"
msgid "Iterations|Create iteration"
-msgstr ""
+msgstr "Crear iteración"
msgid "Iterations|Delete cadence"
-msgstr ""
+msgstr "Eliminar cadencia"
msgid "Iterations|Delete iteration cadence?"
-msgstr ""
+msgstr "¿Eliminar la cadencia de la iteración?"
msgid "Iterations|Delete iteration?"
msgstr ""
@@ -20214,7 +20666,7 @@ msgid "Iterations|Roll over issues"
msgstr ""
msgid "Iterations|Save cadence"
-msgstr ""
+msgstr "Guardar cadencia"
msgid "Iterations|Select duration"
msgstr "Seleccionar la duración"
@@ -20321,6 +20773,9 @@ msgstr ""
msgid "JiraConnect|You can now close this window and return to Jira."
msgstr ""
+msgid "JiraConnect|You don't have permission to create branches for this project. Select a different project or contact the project owner for access. %{linkStart}Learn more.%{linkEnd}"
+msgstr ""
+
msgid "JiraRequest|A connection error occurred while connecting to Jira. Try your request again."
msgstr ""
@@ -20369,15 +20824,15 @@ msgstr "URL base de la instancia de Jira."
msgid "JiraService|Define the type of Jira issue to create from a vulnerability."
msgstr ""
-msgid "JiraService|Displaying Jira issues while leaving the GitLab issue functionality enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
+msgid "JiraService|Displaying Jira issues while leaving GitLab issues also enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
+msgstr ""
+
+msgid "JiraService|Enable Jira issue creation from vulnerabilities"
msgstr ""
msgid "JiraService|Enable Jira issues"
msgstr "Habilitar incidencias de Jira"
-msgid "JiraService|Enable Jira issues creation from vulnerabilities"
-msgstr ""
-
msgid "JiraService|Enable Jira transitions"
msgstr "Habilitar transiciones de Jira"
@@ -20421,7 +20876,7 @@ msgid "JiraService|Jira comments are created when an issue is referenced in a me
msgstr ""
msgid "JiraService|Jira issue type"
-msgstr ""
+msgstr "Tipo de incidencia de Jira"
msgid "JiraService|Jira issues"
msgstr "Incidencias de Jira"
@@ -20442,10 +20897,10 @@ msgid "JiraService|Password or API token"
msgstr "Contraseña o token del API"
msgid "JiraService|Project key changed, refresh list"
-msgstr ""
+msgstr "Clave del proyecto cambiada, actualice la lista"
msgid "JiraService|Project key is required to generate issue types"
-msgstr ""
+msgstr "La clave del proyecto es necesaria para generar los tipos de incidencias"
msgid "JiraService|Select issue type"
msgstr "Seleccione el tipo de incidencia"
@@ -20472,7 +20927,7 @@ msgid "JiraService|Upgrade your plan to enable this feature of the Jira Integrat
msgstr ""
msgid "JiraService|Use Jira as this project's issue tracker."
-msgstr ""
+msgstr "Utilice Jira como el gestor de incidencias de este proyecto."
msgid "JiraService|Use a password for server version and an API token for cloud version."
msgstr ""
@@ -20492,30 +20947,30 @@ msgstr ""
msgid "JiraService|View Jira issues in GitLab"
msgstr "Ver las incidencias de Jira en GitLab"
-msgid "JiraService|Warning: All GitLab users that have access to this GitLab project are able to view all issues from the Jira project specified below."
+msgid "JiraService|Warning: All GitLab users with access to this GitLab project can view all issues from the Jira project you select."
msgstr ""
msgid "JiraService|Web URL"
msgstr "URL web"
-msgid "JiraService|Work on Jira issues without leaving GitLab. Adds a Jira menu to access your list of Jira issues and view any issue as read-only."
+msgid "JiraService|When a Jira issue is mentioned in a commit or merge request, a remote link and comment (if enabled) will be created."
+msgstr ""
+
+msgid "JiraService|Work on Jira issues without leaving GitLab. Add a Jira menu to access a read-only list of your Jira issues."
msgstr ""
-msgid "JiraService|You need to configure Jira before enabling this integration. For more details, read the %{jira_doc_link_start}Jira integration documentation%{link_end}."
+msgid "JiraService|You must configure Jira before enabling this integration. %{jira_doc_link_start}Learn more.%{link_end}"
msgstr ""
msgid "Job"
msgstr "Trabajo"
msgid "Job %{jobName}"
-msgstr ""
+msgstr "Trabajo %{jobName}"
msgid "Job Failed #%{build_id}"
msgstr "Trabajo fallido #%{build_id}"
-msgid "Job ID"
-msgstr "Id del trabajo"
-
msgid "Job artifact"
msgstr "Artefacto del trabajo"
@@ -20582,9 +21037,27 @@ msgstr "Utilice trabajos para automatizar sus tareas"
msgid "Jobs|You're about to retry a job that failed because it attempted to deploy code that is older than the latest deployment. Retrying this job could result in overwriting the environment with the older source code."
msgstr ""
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source} into %{target}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{ref}"
+msgstr ""
+
+msgid "Job|Are you sure you want to erase this job log and artifacts?"
+msgstr ""
+
msgid "Job|Browse"
msgstr "Explorar"
+msgid "Job|Cancel"
+msgstr ""
+
msgid "Job|Complete Raw"
msgstr "Raw completo"
@@ -20594,6 +21067,9 @@ msgstr "Descargar"
msgid "Job|Erase job log and artifacts"
msgstr ""
+msgid "Job|Finished at"
+msgstr ""
+
msgid "Job|Job artifacts"
msgstr "Artefactos del trabajo"
@@ -20606,8 +21082,8 @@ msgstr ""
msgid "Job|Keep"
msgstr "Mantener"
-msgid "Job|Pipeline"
-msgstr "Pipeline"
+msgid "Job|Retry"
+msgstr ""
msgid "Job|Scroll to bottom"
msgstr "Desplazar hacia abajo"
@@ -20618,6 +21094,9 @@ msgstr "Desplazar hacia arriba"
msgid "Job|Show complete raw"
msgstr "Mostrar trabajo completo en crudo"
+msgid "Job|Status"
+msgstr ""
+
msgid "Job|The artifacts were removed"
msgstr "Se han eliminado los artefactos"
@@ -20645,21 +21124,12 @@ msgstr ""
msgid "Job|delayed"
msgstr ""
-msgid "Job|for"
-msgstr "Trabajo para"
-
-msgid "Job|into"
-msgstr "en"
-
msgid "Job|manual"
msgstr "manual"
msgid "Job|triggered"
msgstr "activado"
-msgid "Job|with"
-msgstr "con"
-
msgid "Join Zoom meeting"
msgstr "Unirse a la reunión de Zoom"
@@ -20762,9 +21232,6 @@ msgstr "Claves"
msgid "Ki"
msgstr ""
-msgid "Kontra"
-msgstr "Kontra"
-
msgid "Kroki"
msgstr "Kroki"
@@ -21088,6 +21555,9 @@ msgstr ""
msgid "Learn more about Auto DevOps"
msgstr "Aprenda más sobre Auto DevOps"
+msgid "Learn more about GitLab"
+msgstr ""
+
msgid "Learn more about Needs relationships"
msgstr ""
@@ -21098,7 +21568,7 @@ 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."
+msgstr "Obtenga más información sobre cómo añadir certificados a su proyecto siguiendo la documentación %{docs_link_start}en las páginas%{docs_link_end}GitLab."
msgid "Learn more about custom project templates"
msgstr "Más información sobre las plantillas de proyecto personalizadas"
@@ -21415,9 +21885,18 @@ msgstr ""
msgid "Licenses|Displays licenses detected in the project, based on the %{linkStart}latest successful%{linkEnd} scan"
msgstr ""
+msgid "Licenses|Drag your license file here or %{linkStart}click to upload%{linkEnd}."
+msgstr ""
+
+msgid "Licenses|Drop your license file to start the upload."
+msgstr ""
+
msgid "Licenses|Error fetching the license list. Please check your network connection and try again."
msgstr "Se ha producido un error al obtener la lista de licencias. Por favor, compruebe su conexión de red e inténtelo de nuevo."
+msgid "Licenses|Error: You are trying to upload something other than a file"
+msgstr ""
+
msgid "Licenses|License Compliance"
msgstr "License Compliance"
@@ -21436,6 +21915,9 @@ msgstr ""
msgid "Licenses|Specified policies in this project"
msgstr ""
+msgid "Licenses|The file could not be uploaded."
+msgstr ""
+
msgid "Licenses|The license list details information about the licenses used within your project."
msgstr "La lista de licencias detalla información acerca de las licencias utilizadas dentro de su proyecto."
@@ -21469,11 +21951,6 @@ msgstr ""
msgid "Limit the size of Sidekiq jobs stored in Redis."
msgstr ""
-msgid "Limited to showing %d event at most"
-msgid_plural "Limited to showing %d events at most"
-msgstr[0] "Limitado a mostrar %d evento como máximo"
-msgstr[1] "Limitado a mostrar %d eventos como máximo"
-
msgid "Limiting mode"
msgstr ""
@@ -21483,6 +21960,9 @@ msgstr "Cambios de línea"
msgid "Link"
msgstr "Enlace"
+msgid "Link (optional)"
+msgstr ""
+
msgid "Link Prometheus monitoring to GitLab."
msgstr ""
@@ -21519,6 +21999,9 @@ msgstr ""
msgid "Linked emails (%{email_count})"
msgstr "Correos electrónicos vinculados (%{email_count})"
+msgid "Linked epics"
+msgstr ""
+
msgid "Linked issues"
msgstr "Incidencias relacionadas"
@@ -21546,6 +22029,15 @@ msgstr "Lista de repositorios disponibles"
msgid "List of all merge commits"
msgstr ""
+msgid "List of environments for this project"
+msgstr ""
+
+msgid "List of suitable GCP locations"
+msgstr ""
+
+msgid "List of users allowed to exceed the rate limit."
+msgstr ""
+
msgid "List options"
msgstr ""
@@ -21765,6 +22257,9 @@ msgstr ""
msgid "Maintenance mode"
msgstr "Modo mantenimiento"
+msgid "Make adjustments to how your GitLab instance is set up."
+msgstr ""
+
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"
@@ -21909,6 +22404,12 @@ msgstr "Añadir texto en cursiva (%{modifierKey}I)"
msgid "MarkdownEditor|Add italic text (%{modifier_key}I)"
msgstr "Añadir texto en cursiva (%{modifier_key}I)"
+msgid "MarkdownEditor|Add strikethrough text (%{modifierKey}⇧X)"
+msgstr ""
+
+msgid "MarkdownEditor|Add strikethrough text (%{modifier_key}⇧X)"
+msgstr ""
+
msgid "Marked For Deletion At - %{deletion_time}"
msgstr ""
@@ -21958,7 +22459,7 @@ msgid "Mattermost notifications"
msgstr "Notificaciones de Mattermost"
msgid "MattermostService|Add to Mattermost"
-msgstr "Agregar a Mattermost"
+msgstr "MattermostService|Añadir a Mattermost"
msgid "MattermostService|After you configure the integration, view your new Mattermost commands by entering"
msgstr ""
@@ -22170,6 +22671,9 @@ msgstr ""
msgid "Maximum push size (MB)"
msgstr "Tamaño máximo para los archivos a subir al ejecutar un comando push (MB)"
+msgid "Maximum requests per 10 minutes per user"
+msgstr ""
+
msgid "Maximum requests per minute"
msgstr ""
@@ -22260,6 +22764,19 @@ msgstr ""
msgid "Members of a group may only view projects they have permission to access"
msgstr ""
+msgid "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seat in use and will be billed for the overage."
+msgid_plural "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seats in use and will be billed for the overage."
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "MembersOverage|You are about to incur additional charges"
+msgstr ""
+
+msgid "MembersOverage|Your subscription includes %d seat."
+msgid_plural "MembersOverage|Your subscription includes %d seats."
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Membership"
msgstr ""
@@ -22342,7 +22859,7 @@ msgid "Members|Remove \"%{groupName}\""
msgstr ""
msgid "Members|Remove group"
-msgstr ""
+msgstr "Eliminar grupo"
msgid "Members|Revert to LDAP group sync settings"
msgstr ""
@@ -22464,9 +22981,6 @@ msgstr ""
msgid "Merge request not merged"
msgstr ""
-msgid "Merge request pipelines 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 merge request pipelines."
-msgstr ""
-
msgid "Merge request reports"
msgstr ""
@@ -22563,13 +23077,13 @@ msgstr "Se ha producido un error al guardar el borrador del comentario."
msgid "MergeRequests|Create issue to resolve thread"
msgstr ""
-msgid "MergeRequests|Failed to squash. Should be done manually."
-msgstr "Se ha producido un error al realizar el squash. Debe hacerse de forma manual."
-
msgid "MergeRequests|Saving the comment failed"
msgstr "Se ha producido un error al guardar el comentario"
-msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
+msgid "MergeRequests|Squashing failed: Squash the commits locally, resolve any conflicts, then push the branch."
+msgstr ""
+
+msgid "MergeRequests|Squashing not allowed: This project doesn't allow you to squash commits when merging."
msgstr ""
msgid "MergeRequests|Thread stays resolved"
@@ -22705,13 +23219,13 @@ msgid "Metrics - Prometheus"
msgstr "Métricas - Prometheus"
msgid "Metrics Dashboard"
-msgstr "Panel de control de métricas"
+msgstr "Tablero de métricas"
msgid "Metrics Dashboard YAML definition"
msgstr ""
msgid "Metrics Dashboard YAML definition is invalid:"
-msgstr "La definición del panel de control de métricas YAML no es válida:"
+msgstr "La definición del tablero de métricas YAML no es válida:"
msgid "Metrics Dashboard YAML definition is valid."
msgstr ""
@@ -22762,7 +23276,7 @@ msgid "MetricsSettings|Manage metrics dashboard settings."
msgstr ""
msgid "MetricsSettings|Metrics"
-msgstr ""
+msgstr "Métricas"
msgid "MetricsSettings|UTC (Coordinated Universal Time)"
msgstr "UTC (hora universal coordinada)"
@@ -22792,7 +23306,7 @@ msgid "Metrics|Avg"
msgstr "Avg"
msgid "Metrics|Back to dashboard"
-msgstr "Volver al panel de control"
+msgstr "Metrics|Volver al tablero"
msgid "Metrics|Cancel"
msgstr "Cancelar"
@@ -22813,7 +23327,7 @@ msgid "Metrics|Copy and paste the panel YAML into your dashboard YAML file."
msgstr ""
msgid "Metrics|Create custom dashboard %{fileName}"
-msgstr ""
+msgstr "Metrics|Crear panel personalizado %{fileName}"
msgid "Metrics|Create metric"
msgstr "Crear métrica"
@@ -22926,7 +23440,7 @@ msgid "Metrics|Refresh Prometheus data"
msgstr ""
msgid "Metrics|Refresh dashboard"
-msgstr "Actualizar el panel de control"
+msgstr "Metrics|Actualizar el tablero"
msgid "Metrics|Select a value"
msgstr "Seleccione un valor"
@@ -22938,7 +23452,7 @@ msgid "Metrics|Star dashboard"
msgstr ""
msgid "Metrics|There was an error creating the dashboard."
-msgstr ""
+msgstr "Metrics|Se ha producido un error al crear el tablero."
msgid "Metrics|There was an error creating the dashboard. %{error}"
msgstr ""
@@ -23063,25 +23577,25 @@ msgid "MilestoneCombobox|An error occurred while searching for milestones"
msgstr ""
msgid "MilestoneCombobox|Group milestones"
-msgstr ""
+msgstr "Hitos del grupo"
msgid "MilestoneCombobox|Milestone"
-msgstr ""
+msgstr "Hito"
msgid "MilestoneCombobox|No matching results"
-msgstr ""
+msgstr "No hay resultados coincidentes"
msgid "MilestoneCombobox|No milestone"
-msgstr ""
+msgstr "Sin hito"
msgid "MilestoneCombobox|Project milestones"
-msgstr ""
+msgstr "Hitos del proyecto"
msgid "MilestoneCombobox|Search Milestones"
-msgstr ""
+msgstr "Buscar hitos"
msgid "MilestoneCombobox|Select milestone"
-msgstr ""
+msgstr "Seleccionar hito"
msgid "MilestoneSidebar|Closed:"
msgstr "Cerrado:"
@@ -23165,16 +23679,16 @@ msgid "Milestones|Failed to delete milestone %{milestoneTitle}"
msgstr "Se ha producido un error al eliminar el hito %{milestoneTitle}"
msgid "Milestones|Group Milestone"
-msgstr ""
+msgstr "Hito de grupo"
msgid "Milestones|Milestone %{milestoneTitle} was not found"
msgstr "No se puede encontrar el hito %{milestoneTitle}"
msgid "Milestones|Ongoing Issues (open and assigned)"
-msgstr ""
+msgstr "Incidencias en curso (abiertas y asignadas)"
msgid "Milestones|Project Milestone"
-msgstr ""
+msgstr "Hito del proyecto"
msgid "Milestones|Promote %{milestoneTitle} to group milestone?"
msgstr "¿Promocionar %{milestoneTitle} para agrupar el hito?"
@@ -23183,25 +23697,25 @@ msgid "Milestones|Promote Milestone"
msgstr ""
msgid "Milestones|Promote to Group Milestone"
-msgstr ""
+msgstr "Promover a hito de grupo"
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 ""
+msgstr "Reabrir Hito"
msgid "Milestones|This action cannot be reversed."
msgstr "Esta acción no se puede deshacer"
msgid "Milestones|Unstarted Issues (open and unassigned)"
-msgstr ""
+msgstr "Incidencias no iniciadas (abiertas y no asignadas)"
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."
msgid "Minimum interval in days"
-msgstr ""
+msgstr "Intervalo mínimo en días"
msgid "Minutes"
msgstr "Minutos"
@@ -23270,7 +23784,7 @@ msgid "MissingSSHKeyWarningLink|You won't be able to pull or push repositories v
msgstr ""
msgid "ModalButton|Add projects"
-msgstr ""
+msgstr "Añadir proyectos"
msgid "Modal|Close"
msgstr "Cerrar"
@@ -23410,6 +23924,18 @@ msgstr "Volver a desplegar"
msgid "MrDeploymentActions|Stop environment"
msgstr "Detener entorno"
+msgid "MrList|Assigned to %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from assignee %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from reviewer %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Review requested from %{name}, go to their profile."
+msgstr ""
+
msgid "Multi-project"
msgstr "Multi-proyecto"
@@ -23443,8 +23969,8 @@ msgstr ""
msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "My Awesome Group"
-msgstr "Mi increíble grupo"
+msgid "My awesome group"
+msgstr ""
msgid "My company or team"
msgstr "Mi empresa o equipo"
@@ -23468,7 +23994,7 @@ msgid "Name has already been taken"
msgstr "El nombre ya está en uso"
msgid "Name is already taken."
-msgstr ""
+msgstr "El nombre ya está en uso."
msgid "Name new label"
msgstr "Nombre de la nueva etiqueta"
@@ -23623,16 +24149,16 @@ msgid "NetworkPolicies|%{strongOpen}any%{strongClose} port"
msgstr ""
msgid "NetworkPolicies|.yaml mode"
-msgstr ""
+msgstr "modo .yaml"
msgid "NetworkPolicies|Add alert"
-msgstr ""
+msgstr "Añadir alerta"
msgid "NetworkPolicies|Alerts are intended to be selectively used for a limited number of events that are potentially concerning and warrant a manual review. Alerts should not be used as a substitute for a SIEM or a logging tool. High volume alerts are likely to be dropped so as to preserve the stability of GitLab's integration with Kubernetes."
msgstr ""
msgid "NetworkPolicies|All selected"
-msgstr ""
+msgstr "Todo seleccionado"
msgid "NetworkPolicies|Allow"
msgstr ""
@@ -23662,7 +24188,7 @@ msgid "NetworkPolicies|Deny all traffic"
msgstr "Denegar todo el tráfico"
msgid "NetworkPolicies|Edit policy"
-msgstr ""
+msgstr "Editar política"
msgid "NetworkPolicies|Environment does not have deployment platform"
msgstr "El entorno no tiene plataforma de despliegue"
@@ -23674,19 +24200,19 @@ msgid "NetworkPolicies|Invalid or empty policy"
msgstr "Política no válida o vacía"
msgid "NetworkPolicies|Invalid or unsupported policy kind"
-msgstr ""
+msgstr "Tipo de política no válida o no soportada"
msgid "NetworkPolicies|Kubernetes error: %{error}"
msgstr "Error de Kubernetes: %{error}"
msgid "NetworkPolicies|Network"
-msgstr ""
+msgstr "Red"
msgid "NetworkPolicies|Network Policies can be used to limit which network traffic is allowed between containers inside the cluster."
-msgstr ""
+msgstr "Las políticas de red se pueden utilizar para limitar qué tráfico de red está permitido entre contenedores dentro del cluster."
msgid "NetworkPolicies|Network policy can be created after the environment is loaded successfully."
-msgstr ""
+msgstr "La política de red se puede crear después de que el entorno se cargue correctamente."
msgid "NetworkPolicies|Network traffic"
msgstr "Tráfico de red"
@@ -23728,46 +24254,46 @@ msgid "NetworkPolicies|any pod"
msgstr "cualquier pod"
msgid "NetworkPolicies|any port"
-msgstr ""
+msgstr "cualquier puerto"
msgid "NetworkPolicies|domain name"
msgstr "nombre de dominio"
msgid "NetworkPolicies|entity"
-msgstr ""
+msgstr "entidad"
msgid "NetworkPolicies|inbound to"
msgstr ""
msgid "NetworkPolicies|nowhere"
-msgstr ""
+msgstr "en ninguna parte"
msgid "NetworkPolicies|outbound from"
-msgstr ""
+msgstr "saliente desde"
msgid "NetworkPolicies|pod with labels"
-msgstr ""
+msgstr "pod con etiquetas"
msgid "NetworkPolicies|pods %{pods}"
-msgstr ""
+msgstr "pods %{pods}"
msgid "NetworkPolicies|pods with labels"
-msgstr ""
+msgstr "pods con etiquetas"
msgid "NetworkPolicies|ports %{ports}"
-msgstr ""
+msgstr "pods %{ports}"
msgid "NetworkPolicies|ports/protocols"
-msgstr ""
+msgstr "puertos/protocolos"
msgid "NetworkPolicy|Policy"
-msgstr ""
+msgstr "Política"
msgid "NetworkPolicy|Search by policy name"
-msgstr ""
+msgstr "Buscar por nombre de política"
msgid "NetworkPolicy|Status"
-msgstr ""
+msgstr "Estado"
msgid "Never"
msgstr "Nunca"
@@ -23779,16 +24305,16 @@ msgid "New %{issueType}"
msgstr "Nueva %{issueType}"
msgid "New %{type} in %{project}"
-msgstr ""
+msgstr "Nuevo %{type} en %{project}"
msgid "New Application"
msgstr "Nueva aplicación"
msgid "New Branch"
-msgstr ""
+msgstr "Nueva rama"
msgid "New Deploy Key"
-msgstr ""
+msgstr "Nueva clave de despliegue"
msgid "New Environment"
msgstr "Nuevo entorno"
@@ -23856,7 +24382,7 @@ msgid "New branch unavailable"
msgstr "Nueva rama no disponible"
msgid "New confidential epic title "
-msgstr ""
+msgstr "Nuevo título épico confidencial "
msgid "New confidential issue title"
msgstr ""
@@ -24065,9 +24591,6 @@ msgstr "No hay métodos de autenticación configurados."
msgid "No available branches"
msgstr ""
-msgid "No available groups to fork the project."
-msgstr ""
-
msgid "No branches found"
msgstr "No se han encontrado ramas"
@@ -24216,7 +24739,7 @@ msgid "No member provided"
msgstr ""
msgid "No members found"
-msgstr ""
+msgstr "No se han encontrado miembros"
msgid "No memberships found"
msgstr ""
@@ -24246,7 +24769,7 @@ msgid "No parent group"
msgstr "Ningún grupo padre"
msgid "No plan"
-msgstr ""
+msgstr "Sin plan"
msgid "No pods available"
msgstr "No hay pods disponibles"
@@ -24278,6 +24801,9 @@ msgstr "No hay grupos públicos"
msgid "No ref selected"
msgstr "Ningún ref seleccionado"
+msgid "No regions configured"
+msgstr ""
+
msgid "No related merge requests found."
msgstr ""
@@ -24694,10 +25220,10 @@ msgid "On track"
msgstr ""
msgid "On-call Schedules"
-msgstr ""
+msgstr "Horarios de guardia"
msgid "On-call schedules"
-msgstr ""
+msgstr "Horarios de guardia"
msgid "OnCallScheduless|Any escalation rules that are using this schedule will also be deleted."
msgstr ""
@@ -24709,70 +25235,70 @@ msgid "OnCallSchedules|2 weeks"
msgstr "2 semanas"
msgid "OnCallSchedules|Add a rotation"
-msgstr ""
+msgstr "Añadir una rotación"
msgid "OnCallSchedules|Add a schedule"
-msgstr ""
+msgstr "Añadir un horario"
msgid "OnCallSchedules|Add an additional schedule to your project"
msgstr "Añada un horario adicional a su proyecto"
msgid "OnCallSchedules|Add rotation"
-msgstr ""
+msgstr "Añadir rotación"
msgid "OnCallSchedules|Add schedule"
-msgstr ""
+msgstr "Añadir horario"
msgid "OnCallSchedules|Are you sure you want to delete the \"%{deleteRotation}\" rotation? This action cannot be undone."
-msgstr ""
+msgstr "¿Está seguro de que desea eliminar %{deleteRotation}\"?. Esta acción no se puede deshacer."
msgid "OnCallSchedules|Are you sure you want to delete the \"%{deleteSchedule}\" schedule? This action cannot be undone."
-msgstr ""
+msgstr "¿Está seguro de que desea eliminar el%{deleteSchedule}\"?. Esta acción no se puede deshacer."
msgid "OnCallSchedules|Collapse schedule"
msgstr "Colapsar horario"
msgid "OnCallSchedules|Create on-call schedules in GitLab"
-msgstr ""
+msgstr "Crear horarios de guardia en GitLab"
msgid "OnCallSchedules|Currently no rotation."
-msgstr ""
+msgstr "Actualmente sin rotación."
msgid "OnCallSchedules|Delete rotation"
-msgstr ""
+msgstr "Eliminar rotación"
msgid "OnCallSchedules|Delete schedule"
-msgstr ""
+msgstr "Eliminar horario"
msgid "OnCallSchedules|Edit rotation"
-msgstr ""
+msgstr "Editar rotación"
msgid "OnCallSchedules|Edit schedule"
-msgstr ""
+msgstr "Editar horario"
msgid "OnCallSchedules|Enable end date"
-msgstr ""
+msgstr "Habilitar fecha de finalización"
msgid "OnCallSchedules|Expand schedule"
msgstr "Expandir horario"
msgid "OnCallSchedules|Failed to add rotation"
-msgstr ""
+msgstr "Se ha producido un error al añadir rotación"
msgid "OnCallSchedules|Failed to add schedule"
-msgstr ""
+msgstr "Se ha producido un error al añadir un horario"
msgid "OnCallSchedules|Failed to edit schedule"
-msgstr ""
+msgstr "Se ha producido un error al editar el horario"
msgid "OnCallSchedules|For this rotation, on-call will be:"
-msgstr ""
+msgstr "Para esta rotación, la guardia será:"
msgid "OnCallSchedules|On-call schedule %{obstacle} in project %{project}"
-msgstr ""
+msgstr "Horario de guardia %{obstacle} en el proyecto %{project}"
msgid "OnCallSchedules|On-call schedules"
-msgstr ""
+msgstr "Horarios de guardia"
msgid "OnCallSchedules|Please note, rotations with shifts that are less than four hours are currently not supported in the weekly view."
msgstr ""
@@ -24802,13 +25328,13 @@ msgid "OnCallSchedules|Rotation start date cannot be empty"
msgstr ""
msgid "OnCallSchedules|Rotations"
-msgstr ""
+msgstr "Rotaciones"
msgid "OnCallSchedules|Route alerts directly to specific members of your team"
msgstr ""
msgid "OnCallSchedules|Select participant"
-msgstr ""
+msgstr "Seleccionar participante"
msgid "OnCallSchedules|Select timezone"
msgstr ""
@@ -24847,7 +25373,7 @@ msgid "OnCallSchedules|View previous timeframe"
msgstr ""
msgid "OnCallSchedules|You are currently a part of:"
-msgstr ""
+msgstr "Actualmente es parte de:"
msgid "OnCallSchedules|Your schedule has been successfully created. To add individual users to this schedule, use the Add a rotation button. To enable notifications for this schedule, you must also create an %{linkStart}escalation policy%{linkEnd}."
msgstr ""
@@ -24883,7 +25409,7 @@ msgid "OnDemandScans|Delete profile"
msgstr "Eliminar perfil"
msgid "OnDemandScans|Description (optional)"
-msgstr ""
+msgstr "Descripción (opcional)"
msgid "OnDemandScans|Edit on-demand DAST scan"
msgstr ""
@@ -24937,16 +25463,16 @@ msgid "OnDemandScans|Run scan"
msgstr "Ejecutar análisis"
msgid "OnDemandScans|Save and run scan"
-msgstr ""
+msgstr "Guardar y ejecutar análisis"
msgid "OnDemandScans|Save scan"
-msgstr ""
+msgstr "Guardar análisis"
msgid "OnDemandScans|Scan library"
msgstr ""
msgid "OnDemandScans|Scan name"
-msgstr ""
+msgstr "Nombre del análisis"
msgid "OnDemandScans|Scan type"
msgstr "Tipo de análisis"
@@ -24955,16 +25481,16 @@ msgid "OnDemandScans|Scanner profile"
msgstr ""
msgid "OnDemandScans|Schedule scan"
-msgstr ""
+msgstr "Programar análisis"
msgid "OnDemandScans|Select one of the existing profiles"
msgstr "Seleccione uno de los perfiles existentes"
msgid "OnDemandScans|Site profile"
-msgstr ""
+msgstr "Perfil del sitio"
msgid "OnDemandScans|Start time"
-msgstr ""
+msgstr "Hora de inicio"
msgid "OnDemandScans|Target"
msgstr ""
@@ -24994,7 +25520,7 @@ msgid "OnDemandScans|Use existing site profile"
msgstr ""
msgid "OnDemandScans|View results"
-msgstr ""
+msgstr "Ver resultados"
msgid "OnDemandScans|You must create a repository within your project to run an on-demand scan."
msgstr ""
@@ -25082,6 +25608,9 @@ msgstr ""
msgid "Only reCAPTCHA v2 is supported:"
msgstr ""
+msgid "Only required if not using role instance credentials."
+msgstr ""
+
msgid "Only use lowercase letters, numbers, and underscores."
msgstr ""
@@ -25106,9 +25635,6 @@ msgstr "Abrir la selección"
msgid "Open a CLI and connect to the cluster you want to install the agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
-msgid "Open epics"
-msgstr ""
-
msgid "Open errors"
msgstr "Errores abiertos"
@@ -25134,10 +25660,10 @@ msgid "Open: %{open}"
msgstr "Abierto: %{open}"
msgid "OpenAPI"
-msgstr ""
+msgstr "OpenAPI"
msgid "OpenAPI Specification file path or URL"
-msgstr ""
+msgstr "URL o ruta del archivo de especificación de OpenAPI"
msgid "Opened"
msgstr "Abierto"
@@ -25148,8 +25674,8 @@ msgstr "MRs abiertos"
msgid "Opened issues"
msgstr "Incidencias abiertas"
-msgid "OpenedNDaysAgo|Opened"
-msgstr "Abierto"
+msgid "OpenedNDaysAgo|Created"
+msgstr ""
msgid "Opens in a new window"
msgstr "Abre en una nueva ventana"
@@ -25164,13 +25690,13 @@ 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."
msgid "Operations"
-msgstr ""
+msgstr "Operaciones"
msgid "Operations Dashboard"
-msgstr "Panel de control de operaciones"
+msgstr "Tablero de operaciones"
msgid "OperationsDashboard|Add a project to the dashboard"
-msgstr "Agregar un proyecto al panel"
+msgstr "OperationsDashboard|Añadir un proyecto al tablero"
msgid "OperationsDashboard|Add projects"
msgstr "Añadir proyectos"
@@ -25179,13 +25705,13 @@ msgid "OperationsDashboard|More information"
msgstr "Más información"
msgid "OperationsDashboard|Operations Dashboard"
-msgstr "Panel de control de operaciones"
+msgstr "OperationsDashboard|Tablero de operaciones"
msgid "OperationsDashboard|The operations dashboard provides a summary of each project's operational health, including pipeline and alert statuses."
-msgstr "El panel de control de operaciones proporciona un resumen del estado operativo de cada proyecto, incluidos los estados de canalización y alerta."
+msgstr "OperationsDashboard|El tablero de operaciones proporciona un resumen del estado operativo de cada proyecto, incluidos los estados de los pipelines y de las alertas."
msgid "Optimize your workflow with CI/CD Pipelines"
-msgstr ""
+msgstr "Optimice su flujo de trabajo con los pipelines de CI/CD"
msgid "Optional"
msgstr "Opcional"
@@ -25193,9 +25719,6 @@ msgstr "Opcional"
msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
-msgid "Optional."
-msgstr "Opcional."
-
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
msgstr "Opcionalmente, puede %{link_to_customize} cómo se importan en Gitlab las direcciones de correo y los nombres de usuario de FogBugz."
@@ -25209,7 +25732,7 @@ msgid "Organizations"
msgstr "Organización"
msgid "Orphaned member"
-msgstr ""
+msgstr "Miembro huérfano"
msgid "Other Labels"
msgstr "Otras etiquetas"
@@ -25236,7 +25759,7 @@ msgid "Otherwise, click the link below to complete the process:"
msgstr "De lo contrario, haga clic en el siguiente enlace para completar el proceso:"
msgid "Our team has been notified. Please try again."
-msgstr ""
+msgstr "Nuestro equipo ha sido notificado. Por favor, inténtalo de nuevo."
msgid "Out-of-compliance with this project's policies and should be removed"
msgstr ""
@@ -25284,7 +25807,7 @@ msgid "Overwrite diverged branches"
msgstr "Sobreescribir ramas divergentes"
msgid "Owned by %{image_tag}"
-msgstr ""
+msgstr "Propiedad de %{image_tag}"
msgid "Owned by anyone"
msgstr "Propiedad de cualquier persona"
@@ -25308,7 +25831,7 @@ msgid "PQL|Cancel"
msgstr "Cancelar"
msgid "PQL|Contact our Sales team"
-msgstr ""
+msgstr "Póngase en contacto con nuestro equipo de ventas"
msgid "PQL|Contact sales"
msgstr "Contactar con ventas"
@@ -25332,10 +25855,10 @@ msgid "Package Registry"
msgstr "Registro de paquetes"
msgid "Package Registry: authenticated API requests"
-msgstr ""
+msgstr "Registro de paquetes: Peticiones del API autenticadas"
msgid "Package Registry: unauthenticated API requests"
-msgstr ""
+msgstr "Registro de paquetes: solicitudes del API no autenticadas"
msgid "Package already exists"
msgstr "El paquete ya existe"
@@ -25353,16 +25876,16 @@ msgid "Package registry rate limits"
msgstr ""
msgid "Package type"
-msgstr ""
+msgstr "Tipo de paquete"
msgid "Package type must be Conan"
msgstr "El tipo de paquete debe ser Conan"
msgid "Package type must be Debian"
-msgstr ""
+msgstr "El tipo de paquete debe ser Debian"
msgid "Package type must be Helm"
-msgstr ""
+msgstr "El tipo de paquete debe ser Helm"
msgid "Package type must be Maven"
msgstr "El tipo de paquete debe ser Maven"
@@ -25380,13 +25903,13 @@ msgid "Package type must be RubyGems"
msgstr "El tipo de paquete debe ser RubyGems"
msgid "PackageRegistry|%{boldStart}Allow duplicates%{boldEnd} - Accept packages with the same name and version."
-msgstr ""
+msgstr "%{boldStart}Permitir duplicados%{boldEnd} - Acepta paquetes con el mismo nombre y versión."
msgid "PackageRegistry|%{boldStart}Do not allow duplicates%{boldEnd} - Reject packages with the same name and version."
-msgstr ""
+msgstr "%{boldStart}No permitir duplicados%{boldEnd} - Rechaza paquetes con el mismo nombre y versión."
msgid "PackageRegistry|%{name} version %{version} was first created %{datetime}"
-msgstr ""
+msgstr "%{name} versión %{version} creada por primera vez %{datetime}"
msgid "PackageRegistry|Add Conan Remote"
msgstr "Añadir un remoto de Conan"
@@ -25401,25 +25924,25 @@ msgid "PackageRegistry|Add NuGet Source"
msgstr "Añadir fuente de NuGet"
msgid "PackageRegistry|Add composer registry"
-msgstr ""
+msgstr "Añadir registro de Composer"
msgid "PackageRegistry|Allow duplicates"
-msgstr ""
+msgstr "Permitir duplicados"
msgid "PackageRegistry|App group: %{group}"
-msgstr ""
+msgstr "Grupo de aplicaciones: %{group}"
msgid "PackageRegistry|App name: %{name}"
-msgstr ""
+msgstr "Nombre de la aplicación: %{name}"
msgid "PackageRegistry|Built by pipeline %{link} triggered %{datetime} by %{author}"
msgstr ""
msgid "PackageRegistry|Composer"
-msgstr ""
+msgstr "Composer"
msgid "PackageRegistry|Composer.json with license: %{license} and version: %{version}"
-msgstr ""
+msgstr "Composer.json con licencia: %{license} y versión: %{version}"
msgid "PackageRegistry|Conan"
msgstr "Conan"
@@ -25461,7 +25984,7 @@ msgid "PackageRegistry|Copy Pip command"
msgstr "Copiar comando de Pip"
msgid "PackageRegistry|Copy SHA"
-msgstr ""
+msgstr "Copiar SHA"
msgid "PackageRegistry|Copy add Gradle Groovy DSL repository command"
msgstr ""
@@ -25497,7 +26020,7 @@ msgid "PackageRegistry|Created by commit %{link} on branch %{branch}"
msgstr ""
msgid "PackageRegistry|Debian"
-msgstr ""
+msgstr "Debian"
msgid "PackageRegistry|Delete Package File"
msgstr ""
@@ -25512,7 +26035,7 @@ msgid "PackageRegistry|Failed to load the package data"
msgstr ""
msgid "PackageRegistry|For more information on Composer packages in GitLab, %{linkStart}see the documentation.%{linkEnd}"
-msgstr ""
+msgstr "Para obtener más información sobre los paquetes de Composer en GitLab, %{linkStart}vea la documentación%{linkEnd}"
msgid "PackageRegistry|For more information on the Conan registry, %{linkStart}see the documentation%{linkEnd}."
msgstr "Para más información sobre el registro de Conan, %{linkStart}vea la documentación%{linkEnd}."
@@ -25527,22 +26050,22 @@ msgid "PackageRegistry|For more information on the PyPi registry, %{linkStart}se
msgstr "Para obtener más información sobre el registro PyPiPi, %{linkStart}vea la documentación%{linkEnd}."
msgid "PackageRegistry|Generic"
-msgstr ""
+msgstr "Genérico"
msgid "PackageRegistry|Gradle Groovy DSL"
-msgstr ""
+msgstr "Gradle Groovy DSL"
msgid "PackageRegistry|Gradle Groovy DSL install command"
-msgstr ""
+msgstr "Comando de instalación de Gradle Groovy DSL"
msgid "PackageRegistry|Gradle Kotlin DSL"
-msgstr ""
+msgstr "Gradle Kotlin DSL"
msgid "PackageRegistry|Gradle Kotlin DSL install command"
-msgstr ""
+msgstr "Comando de instalación de Gradle Kotlin DSL"
msgid "PackageRegistry|Helm"
-msgstr ""
+msgstr "Helm"
msgid "PackageRegistry|If you haven't already done so, you will need to add the below to your %{codeStart}.pypirc%{codeEnd} file."
msgstr "Si todavía no lo ha hecho, necesitará añadir lo siguiente a su archivo %{codeStart}.pypirc%{codeEnd}."
@@ -25551,13 +26074,13 @@ msgid "PackageRegistry|If you haven't already done so, you will need to add the
msgstr "Si aún no lo ha hecho, debe añadir lo siguiente a su archivo %{codeStart}pom.xml%{codeEnd}."
msgid "PackageRegistry|Install package version"
-msgstr ""
+msgstr "Instalar versión del paquete"
msgid "PackageRegistry|Instance-level"
-msgstr ""
+msgstr "Nivel de instancia"
msgid "PackageRegistry|Invalid Package: failed metadata extraction"
-msgstr ""
+msgstr "Paquete no válido: se ha producido un error en la extracción de metadatos"
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."
@@ -25575,7 +26098,7 @@ msgid "PackageRegistry|Maven Command"
msgstr "Comando Maven"
msgid "PackageRegistry|Maven XML"
-msgstr ""
+msgstr "Maven XML"
msgid "PackageRegistry|NuGet"
msgstr "NuGet"
@@ -25584,13 +26107,13 @@ msgid "PackageRegistry|NuGet Command"
msgstr "Comando NuGet"
msgid "PackageRegistry|Package Registry"
-msgstr ""
+msgstr "Registro de paquetes"
msgid "PackageRegistry|Package deleted successfully"
msgstr "Paquete eliminado correctamente"
msgid "PackageRegistry|Package file deleted successfully"
-msgstr ""
+msgstr "Archivo de paquete eliminado correctamente"
msgid "PackageRegistry|Package has %{updatesCount} archived update"
msgid_plural "PackageRegistry|Package has %{updatesCount} archived updates"
@@ -25598,13 +26121,13 @@ msgstr[0] "El paquete tiene %{updatesCount} actualizacion archivada"
msgstr[1] "El paquete tiene %{updatesCount} actualizaciones archivadas"
msgid "PackageRegistry|Package updated by commit %{link} on branch %{branch}, built by pipeline %{pipeline}, and published to the registry %{datetime}"
-msgstr ""
+msgstr "Paquete actualizado por el commit %{link} en la rama %{branch}, construido por pipeline %{pipeline}, y publicado en el registro %{datetime}"
msgid "PackageRegistry|Pip Command"
msgstr "Comando Pip"
msgid "PackageRegistry|Project-level"
-msgstr ""
+msgstr "Nivel de proyecto"
msgid "PackageRegistry|Publish and share packages for a variety of common package managers. %{docLinkStart}More information%{docLinkEnd}"
msgstr ""
@@ -25616,7 +26139,7 @@ msgid "PackageRegistry|Published to the %{project} Package Registry %{datetime}"
msgstr ""
msgid "PackageRegistry|PyPI"
-msgstr ""
+msgstr "PyPI"
msgid "PackageRegistry|Recipe: %{recipe}"
msgstr "Receta: %{recipe}"
@@ -25628,13 +26151,13 @@ msgid "PackageRegistry|Remove package"
msgstr "Eliminar paquete"
msgid "PackageRegistry|Required Python: %{pythonVersion}"
-msgstr ""
+msgstr "Python requerido: %{pythonVersion}"
msgid "PackageRegistry|RubyGems"
msgstr "RubyGems"
msgid "PackageRegistry|Settings for Generic packages"
-msgstr ""
+msgstr "Configuración para paquetes genéricos"
msgid "PackageRegistry|Settings for Maven packages"
msgstr "Configuración para paquetes de Maven"
@@ -25697,10 +26220,10 @@ msgid "PackageRegistry|Unable to load package"
msgstr "Se ha producido un error al cargar el paquete"
msgid "PackageRegistry|Use GitLab as a private registry for common package formats. %{linkStart}Learn more.%{linkEnd}"
-msgstr ""
+msgstr "Utilice GitLab como un registro privado para formatos de paquetes comunes. %{linkStart}Más información.%{linkEnd}"
msgid "PackageRegistry|You are about to delete %{filename}. This is a destructive action that may render your package unusable. Are you sure?"
-msgstr ""
+msgstr "Está a punto de eliminar %{filename}. Esta es una acción destructiva que puede hacer que su paquete sea inutilizable. ¿Está seguro?"
msgid "PackageRegistry|You are about to delete %{name}, this operation is irreversible, are you sure?"
msgstr "Está a punto de eliminar %{name}, esta operación es irreversible, ¿está seguro?"
@@ -25724,13 +26247,13 @@ msgid "Page not found"
msgstr "Página no encontrada"
msgid "Page settings"
-msgstr ""
+msgstr "Configuración de página"
msgid "PagerDutySettings|Active"
msgstr "Activo"
msgid "PagerDutySettings|Create a GitLab incident for each PagerDuty incident by %{linkStart}configuring a webhook in PagerDuty%{linkEnd}"
-msgstr ""
+msgstr "Crear un incidente de GitLab para cada incidente de PagerDuty mediante %{linkStart}configurando un webhook en PagerDuty%{linkEnd}"
msgid "PagerDutySettings|Failed to update Webhook URL"
msgstr "Se ha producido un error al actualizar la URL del webhook"
@@ -25754,7 +26277,7 @@ msgid "Pages Domain"
msgstr "Dominio de Pages"
msgid "Pagination|First"
-msgstr ""
+msgstr "Primero"
msgid "Pagination|Go to first page"
msgstr "Ir a la primera página"
@@ -25769,7 +26292,7 @@ msgid "Pagination|Go to previous page"
msgstr "Ir a la página anterior"
msgid "Pagination|Last"
-msgstr ""
+msgstr "Último"
msgid "Pagination|Last »"
msgstr "Último »"
@@ -25787,7 +26310,7 @@ msgid "Parameter"
msgstr "Parámetro"
msgid "Parameter \"job_id\" cannot exceed length of %{job_id_max_size}"
-msgstr ""
+msgstr "El parámetro \"job_id\" no puede exceder la longitud de %{job_id_max_size}"
msgid "Parent"
msgstr "Padre"
@@ -25838,13 +26361,13 @@ msgid "Password was successfully updated. Please sign in again."
msgstr ""
msgid "PasswordPrompt|Confirm password"
-msgstr ""
+msgstr "Confirmar contraseña"
msgid "PasswordPrompt|Confirm password to continue"
-msgstr ""
+msgstr "Confirme la contraseña para continuar"
msgid "PasswordPrompt|Password is required"
-msgstr ""
+msgstr "Se requiere contraseña"
msgid "PasswordPrompt|Please enter your password to confirm"
msgstr ""
@@ -25984,6 +26507,9 @@ msgstr "Llamadas a Gitaly"
msgid "PerformanceBar|Memory"
msgstr ""
+msgid "PerformanceBar|Memory report"
+msgstr ""
+
msgid "PerformanceBar|Redis calls"
msgstr "Llamas de Redis"
@@ -26009,28 +26535,22 @@ msgid "PerformanceBar|Trace"
msgstr "Traza"
msgid "PerformanceBar|cpu"
-msgstr ""
+msgstr "cpu"
msgid "PerformanceBar|object"
-msgstr ""
+msgstr "objeto"
msgid "PerformanceBar|wall"
msgstr ""
-msgid "Performs a rebase but skips triggering a new pipeline"
-msgstr ""
-
msgid "Period in seconds"
-msgstr ""
+msgstr "Período en segundos"
msgid "Permalink"
msgstr "Enlace permanente"
-msgid "Permanently delete project"
-msgstr ""
-
msgid "Permanently remove group"
-msgstr ""
+msgstr "Eliminar el grupo de manera permanente"
msgid "Permissions"
msgstr "Permisos"
@@ -26090,10 +26610,10 @@ msgid "Pipeline Editor|Are you sure you want to reset the file to its last commi
msgstr ""
msgid "Pipeline ID"
-msgstr ""
+msgstr "ID del pipeline"
msgid "Pipeline IID"
-msgstr ""
+msgstr "IID del pipeline"
msgid "Pipeline Schedule"
msgstr "Programación del Pipeline"
@@ -26105,7 +26625,7 @@ msgid "Pipeline URL"
msgstr "URL del pipeline"
msgid "Pipeline durations for the last 30 commits"
-msgstr ""
+msgstr "Duraciones de los pipelines para los últimos 30 commits"
msgid "Pipeline ran in fork of project"
msgstr ""
@@ -26258,7 +26778,7 @@ msgid "PipelineSource|Chat"
msgstr ""
msgid "PipelineSource|External"
-msgstr ""
+msgstr "Externo"
msgid "PipelineSource|External Pull Request"
msgstr ""
@@ -26288,10 +26808,10 @@ msgid "PipelineSource|Trigger"
msgstr ""
msgid "PipelineSource|Web"
-msgstr ""
+msgstr "Web"
msgid "PipelineSource|Web IDE"
-msgstr ""
+msgstr "IDE Web"
msgid "PipelineStatusTooltip|Pipeline: %{ciStatus}"
msgstr "Canal: %{ciStatus}"
@@ -26299,6 +26819,51 @@ msgstr "Canal: %{ciStatus}"
msgid "PipelineStatusTooltip|Pipeline: %{ci_status}"
msgstr "Pipeline: %{ci_status}"
+msgid "PipelineWizardDefaultCommitMessage|Add %{filename}"
+msgstr ""
+
+msgid "PipelineWizardDefaultCommitMessage|Update %{filename}"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|At least one entry is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This field is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This value is not valid"
+msgstr ""
+
+msgid "PipelineWizardListWidget|add another step"
+msgstr ""
+
+msgid "PipelineWizardListWidget|remove step"
+msgstr ""
+
+msgid "PipelineWizard|Commit"
+msgstr ""
+
+msgid "PipelineWizard|Commit Message"
+msgstr ""
+
+msgid "PipelineWizard|Commit changes to your file"
+msgstr ""
+
+msgid "PipelineWizard|Commit file to Branch"
+msgstr ""
+
+msgid "PipelineWizard|Commit your new file"
+msgstr ""
+
+msgid "PipelineWizard|The file has been committed."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem committing the changes."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem while checking whether your file already exists in the specified branch."
+msgstr ""
+
msgid "Pipelines"
msgstr "Pipelines"
@@ -26318,7 +26883,7 @@ msgid "Pipelines|Are you sure you want to run this pipeline?"
msgstr ""
msgid "Pipelines|Auto DevOps"
-msgstr ""
+msgstr "Auto DevOps"
msgid "Pipelines|Build with confidence"
msgstr "Construir con confianza"
@@ -26351,13 +26916,13 @@ msgid "Pipelines|Could not load merged YAML content"
msgstr ""
msgid "Pipelines|Description"
-msgstr ""
+msgstr "Descripción"
msgid "Pipelines|Edit"
-msgstr ""
+msgstr "Editar"
msgid "Pipelines|Editor"
-msgstr ""
+msgstr "Editor"
msgid "Pipelines|Get familiar with GitLab CI/CD syntax by starting with a basic 3 stage CI/CD pipeline."
msgstr ""
@@ -26405,15 +26970,15 @@ msgid "Pipelines|No triggers have been created yet. Add one using the form above
msgstr ""
msgid "Pipelines|Owner"
-msgstr ""
+msgstr "Propietario"
msgid "Pipelines|Pipeline Editor"
-msgstr ""
+msgstr "Editor de pipeline"
msgid "Pipelines|Project cache successfully reset."
msgstr "Caché del proyecto restablecida correctamente."
-msgid "Pipelines|Revoke"
+msgid "Pipelines|Revoke trigger"
msgstr ""
msgid "Pipelines|Something went wrong while cleaning runners cache."
@@ -26458,6 +27023,12 @@ msgstr ""
msgid "Pipelines|This is a child pipeline within the parent pipeline"
msgstr ""
+msgid "Pipelines|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipelines|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipelines|This pipeline will run code originating from a forked project merge request. This means that the code can potentially have security considerations like exposing CI variables."
msgstr ""
@@ -26495,31 +27066,31 @@ msgid "Pipelines|View merged YAML"
msgstr ""
msgid "Pipelines|Visualize"
-msgstr ""
+msgstr "Visualizar"
msgid "Pipelines|Your changes have been successfully committed. Now redirecting to the new merge request page."
msgstr ""
-msgid "Pipelines|detached"
-msgstr ""
-
msgid "Pipelines|error"
-msgstr ""
+msgstr "error"
msgid "Pipelines|invalid"
msgstr "no válido"
msgid "Pipelines|latest"
+msgstr "Últimos"
+
+msgid "Pipelines|merge request"
msgstr ""
-msgid "Pipelines|stuck"
+msgid "Pipelines|merge train"
msgstr ""
-msgid "Pipelines|train"
+msgid "Pipelines|stuck"
msgstr ""
msgid "Pipelines|yaml invalid"
-msgstr ""
+msgstr "yaml no válido"
msgid "Pipeline|Actions"
msgstr "Acciones"
@@ -26582,7 +27153,7 @@ msgid "Pipeline|Passed"
msgstr ""
msgid "Pipeline|Pending"
-msgstr ""
+msgstr "Pendiente"
msgid "Pipeline|Pipeline"
msgstr "Pipeline"
@@ -26612,7 +27183,7 @@ msgid "Pipeline|Skipped"
msgstr "Omitido"
msgid "Pipeline|Source"
-msgstr ""
+msgstr "Origen"
msgid "Pipeline|Source|Security Policy"
msgstr ""
@@ -26647,6 +27218,12 @@ msgstr ""
msgid "Pipeline|This change will not change the overall test coverage if merged."
msgstr ""
+msgid "Pipeline|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipeline|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipeline|Trigger author"
msgstr ""
@@ -26671,6 +27248,12 @@ msgstr ""
msgid "Pipeline|for"
msgstr "para"
+msgid "Pipeline|merge request"
+msgstr ""
+
+msgid "Pipeline|merge train"
+msgstr ""
+
msgid "Pipeline|on"
msgstr "en"
@@ -26756,10 +27339,10 @@ msgid "Please complete your profile with email address"
msgstr "Por favor, complete su perfil con una dirección de correo electrónico"
msgid "Please confirm your email address"
-msgstr ""
+msgstr "Por favor, confirme su dirección de correo electrónico"
msgid "Please contact an admin to register runners."
-msgstr ""
+msgstr "Póngase en contacto con un administrador para registrar ejecutores."
msgid "Please contact your GitLab administrator if you think this is an error."
msgstr ""
@@ -26809,9 +27392,6 @@ msgstr "Por favor, introduzca un número válido"
msgid "Please enter a valid time interval"
msgstr ""
-msgid "Please enter or upload a valid license."
-msgstr ""
-
msgid "Please enter your current password."
msgstr ""
@@ -26840,28 +27420,28 @@ msgid "Please provide a name"
msgstr "Por favor, proporcione un nombre"
msgid "Please provide a name."
-msgstr ""
+msgstr "Por favor, proporcione un nombre."
msgid "Please provide a valid URL"
-msgstr ""
+msgstr "Por favor, proporcione una URL válida"
msgid "Please provide a valid URL."
-msgstr ""
+msgstr "Por favor, introduzca una URL válida."
msgid "Please provide a valid YouTube URL or ID"
-msgstr ""
+msgstr "Por favor, proporcione una URL o ID de YouTube válidos"
msgid "Please provide a valid email address."
msgstr "Por favor proporcione una dirección de correo electrónico válida."
msgid "Please provide attributes to update"
-msgstr ""
+msgstr "Por favor, proporcione atributos para actualizar"
msgid "Please reach out if you have any questions and we'll be happy to assist."
-msgstr ""
+msgstr "Contacte con nosotros si tiene alguna pregunta y estaremos encantados de ayudarle."
msgid "Please refer to %{docs_url}"
-msgstr ""
+msgstr "Por favor, consulte %{docs_url}"
msgid "Please review the updated escalation policies for %{project_link}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
msgstr ""
@@ -26882,7 +27462,7 @@ msgid "Please select a file"
msgstr "Por favor, seleccione un archivo"
msgid "Please select a group"
-msgstr ""
+msgstr "Por favor, seleccione un grupo"
msgid "Please select a group."
msgstr "Por favor, seleccione un grupo."
@@ -26920,9 +27500,6 @@ msgstr ""
msgid "Please type %{phrase_code} to proceed or close this modal to cancel."
msgstr "Por favor, escriba %{phrase_code} para continuar o cierre esta ventana modal para cancelar."
-msgid "Please type the following to confirm:"
-msgstr ""
-
msgid "Please use this form to report to the admin users who create spam issues, comments or behave inappropriately."
msgstr "Utilice este formulario para informar a los administradores sobre los usuarios que crean spam en las incidencias, en los comentarios o se comportan de una manera inadecuada."
@@ -26950,12 +27527,27 @@ msgstr ""
msgid "Policies"
msgstr ""
+msgid "Policy '%{escalation_policy_name}' does not exist."
+msgstr ""
+
msgid "Policy management project does have any policies in %{policy_path}"
msgstr ""
msgid "Policy project doesn't exist"
msgstr ""
+msgid "PolicyRuleMultiSelect|%{firstLabel} +%{numberOfAdditionalLabels} more"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|All %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select all"
+msgstr ""
+
msgid "Polling interval multiplier"
msgstr ""
@@ -26969,7 +27561,7 @@ msgid "Postman collection"
msgstr "Colección de Postman"
msgid "Postman collection file path or URL"
-msgstr ""
+msgstr "Ruta o URL del archivo de colección de Postman"
msgid "Potentially unwanted character detected: Unicode BiDi Control"
msgstr ""
@@ -27020,7 +27612,7 @@ msgid "Preferences|For example: 30 minutes ago."
msgstr "Por ejemplo: hace 30 minutos."
msgid "Preferences|Gitpod"
-msgstr ""
+msgstr "Gitpod"
msgid "Preferences|Homepage content"
msgstr ""
@@ -27143,7 +27735,7 @@ msgid "Primary Action"
msgstr "Acción primaria"
msgid "Print codes"
-msgstr ""
+msgstr "Imprimir códigos"
msgid "Prioritize"
msgstr "Priorizar"
@@ -27184,6 +27776,9 @@ msgstr ""
msgid "Private projects can be created in your personal namespace with:"
msgstr "Los proyectos privados se pueden crear en su espacio de nombres personal con:"
+msgid "Problem with %{name} command: %{message}."
+msgstr ""
+
msgid "Proceed"
msgstr "Continuar"
@@ -27272,7 +27867,7 @@ msgid "Profiles| You are going to change the username %{currentUsernameBold} to
msgstr "Está a punto de renombrar el usuario %{currentUsernameBold} a %{newUsernameBold}. El perfil del usuario y los proyectos serán redirigidos al espacio de nombres %{newUsername} pero este redireccionamiento caducará una vez que otro usuario o grupo registre el %{currentUsername}. Por favor, actualice los remotos de su repositorio Git tan pronto como sea posible."
msgid "Profiles|%{provider} Active"
-msgstr ""
+msgstr "Perfiles|%{provider} activo"
msgid "Profiles|@username"
msgstr "@nombredeusuario"
@@ -27293,7 +27888,7 @@ msgid "Profiles|Add key"
msgstr "Añadir clave"
msgid "Profiles|Add status emoji"
-msgstr "Agregar emoji de estado"
+msgstr "Añadir emoji de estado"
msgid "Profiles|An error occurred while updating your username, please try again."
msgstr ""
@@ -27389,7 +27984,7 @@ msgid "Profiles|Enter your pronouns to let people know how to refer to you"
msgstr ""
msgid "Profiles|Expiration date"
-msgstr ""
+msgstr "Fecha de caducidad"
msgid "Profiles|Expired key is not valid."
msgstr ""
@@ -27658,6 +28253,9 @@ msgstr "Lenguajes de programación utilizados en este repositorio"
msgid "Progress"
msgstr "Progreso"
+msgid "Progress tracking"
+msgstr ""
+
msgid "Project"
msgstr "Proyecto"
@@ -27692,7 +28290,7 @@ msgid "Project '%{project_name}' will be deleted on %{date}"
msgstr "El proyecto '%{project_name}' será eliminado el %{date}"
msgid "Project Access Tokens"
-msgstr ""
+msgstr "Tokens de acceso al proyecto"
msgid "Project Badges"
msgstr "Insignias de proyecto"
@@ -27704,7 +28302,7 @@ msgid "Project ID"
msgstr "ID de proyecto"
msgid "Project Templates"
-msgstr ""
+msgstr "Plantillas de proyecto"
msgid "Project URL"
msgstr "URL del proyecto"
@@ -27731,7 +28329,7 @@ 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 configuration, excluding integrations"
-msgstr ""
+msgstr "Configuración del proyecto, excluyendo integraciones"
msgid "Project description (optional)"
msgstr "Descripción del proyecto (opcional)"
@@ -27839,7 +28437,7 @@ msgid "ProjectFileTree|Name"
msgstr "Nombre"
msgid "ProjectFileTree|Show more"
-msgstr ""
+msgstr "Mostrar más"
msgid "ProjectLastActivity|Never"
msgstr "Nunca"
@@ -27889,6 +28487,9 @@ msgstr "Cobertura"
msgid "ProjectQualitySummary|Failure"
msgstr "Error"
+msgid "ProjectQualitySummary|Get insight into the overall percentage of tests in your project that succeed, fail and are skipped."
+msgstr ""
+
msgid "ProjectQualitySummary|Latest pipeline results"
msgstr ""
@@ -27907,6 +28508,12 @@ msgstr "Ver informe completo"
msgid "ProjectQualitySummary|See project Code Coverage Statistics"
msgstr "Ver las estadísticas de cobertura del código del proyecto"
+msgid "ProjectQualitySummary|Set up test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|Set up test runs (opens in a new tab)"
+msgstr ""
+
msgid "ProjectQualitySummary|Skipped"
msgstr "Omitido"
@@ -27932,22 +28539,22 @@ msgid "ProjectSelect|Search for project"
msgstr "Buscar proyecto"
msgid "ProjectSelect|Search projects"
-msgstr ""
+msgstr "Buscar proyectos"
msgid "ProjectSelect|Select a project"
-msgstr ""
+msgstr "Seleccione un proyecto"
msgid "ProjectSelect|There was an error fetching the projects. Please try again."
msgstr ""
msgid "ProjectService|Drone server URL"
-msgstr ""
+msgstr "URL del servidor Drone"
msgid "ProjectService|Enter new API key"
-msgstr ""
+msgstr "Introduzca una nueva clave del API"
msgid "ProjectService|Enter new password"
-msgstr ""
+msgstr "Introduzca una nueva contraseña"
msgid "ProjectService|Enter new password."
msgstr "Introducir una nueva contraseña."
@@ -27959,7 +28566,7 @@ msgid "ProjectService|Issue URL"
msgstr "URL de la incidencia"
msgid "ProjectService|Jenkins server URL"
-msgstr ""
+msgstr "URL del servidor Jenkins"
msgid "ProjectService|Leave blank to use your current API key"
msgstr ""
@@ -27968,10 +28575,10 @@ msgid "ProjectService|Leave blank to use your current password"
msgstr ""
msgid "ProjectService|Leave blank to use your current password."
-msgstr ""
+msgstr "Déjelo en blanco para utilizar su contraseña actual."
msgid "ProjectService|Leave blank to use your current token."
-msgstr ""
+msgstr "Déjelo en blanco para utilizar su token actual."
msgid "ProjectService|Mock service URL"
msgstr ""
@@ -28109,7 +28716,7 @@ msgid "ProjectSettings|Disable email notifications"
msgstr "Desactivar notificaciones por correo electrónico"
msgid "ProjectSettings|Do not allow"
-msgstr ""
+msgstr "No permitir"
msgid "ProjectSettings|Enable \"Delete source branch\" option by default"
msgstr ""
@@ -28183,13 +28790,19 @@ msgstr "Incidencias"
msgid "ProjectSettings|LFS objects from this repository are available to forks. %{linkStart}How do I remove them?%{linkEnd}"
msgstr ""
+msgid "ProjectSettings|Learn about commit history."
+msgstr ""
+
+msgid "ProjectSettings|Leave empty to use default template."
+msgstr ""
+
msgid "ProjectSettings|Manage who can see the project in the public access directory."
msgstr ""
msgid "ProjectSettings|Manages large files such as audio, video, and graphics files."
msgstr ""
-msgid "ProjectSettings|Maximum 500 characters."
+msgid "ProjectSettings|Maximum %{maxLength} characters."
msgstr ""
msgid "ProjectSettings|Merge checks"
@@ -28232,7 +28845,7 @@ msgid "ProjectSettings|Only signed commits can be pushed to this repository."
msgstr "Solo se pueden enviar commits firmados a este repositorio."
msgid "ProjectSettings|Operations"
-msgstr ""
+msgstr "Operaciones"
msgid "ProjectSettings|Override user notification preferences for all project members."
msgstr ""
@@ -28262,16 +28875,16 @@ msgid "ProjectSettings|Repository"
msgstr "Repositorio"
msgid "ProjectSettings|Require"
-msgstr ""
+msgstr "Requerir"
msgid "ProjectSettings|Require an associated issue from Jira"
-msgstr ""
+msgstr "Requerir una incidencia asociada de Jira"
msgid "ProjectSettings|Requirements"
-msgstr ""
+msgstr "Requisitos"
msgid "ProjectSettings|Requirements management system."
-msgstr ""
+msgstr "Sistema de gestión de requisitos."
msgid "ProjectSettings|Search for topic"
msgstr ""
@@ -28330,6 +28943,9 @@ msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
msgstr ""
+msgid "ProjectSettings|The default template will be applied on save."
+msgstr ""
+
msgid "ProjectSettings|These checks must pass before merge requests can be merged."
msgstr ""
@@ -28384,6 +29000,9 @@ msgstr ""
msgid "ProjectSettings|What are badges?"
msgstr ""
+msgid "ProjectSettings|What are merge trains?"
+msgstr ""
+
msgid "ProjectSettings|When merge request pipelines are enabled in the CI/CD configuration file, pipelines validate the combined results of the source and target branches. %{link_start}How to configure merge request pipelines?%{link_end}"
msgstr ""
@@ -28412,10 +29031,10 @@ msgid "ProjectTemplates|Go Micro"
msgstr "Go Micro"
msgid "ProjectTemplates|HIPAA Audit Protocol"
-msgstr ""
+msgstr "Protocolo de auditoría HIPAA"
msgid "ProjectTemplates|Kotlin Native for Linux"
-msgstr ""
+msgstr "Kotlin Native para Linux"
msgid "ProjectTemplates|Netlify/GitBook"
msgstr "Netlify/GitBook"
@@ -28460,7 +29079,7 @@ msgid "ProjectTemplates|SalesforceDX"
msgstr "SalesforceDX"
msgid "ProjectTemplates|Sample GitLab Project"
-msgstr ""
+msgstr "Proyecto ejemplo de GitLab"
msgid "ProjectTemplates|Serverless Framework/JS"
msgstr "Serverless Framework/JS"
@@ -28478,13 +29097,13 @@ msgid "ProjectTemplates|iOS (Swift)"
msgstr "IOS (Swift)"
msgid "ProjectView|Activity"
-msgstr ""
+msgstr "Actividad"
msgid "ProjectView|Files and Readme (default)"
msgstr ""
msgid "ProjectView|Readme"
-msgstr ""
+msgstr "Léeme"
msgid "Projects"
msgstr "Proyectos"
@@ -28499,10 +29118,13 @@ msgid "Projects are graded based on the highest severity vulnerability present"
msgstr ""
msgid "Projects are organized into groups"
+msgstr "Los proyectos están organizados en grupos"
+
+msgid "Projects are where you store your code, access issues, wiki and other features of GitLab."
msgstr ""
msgid "Projects contributed to"
-msgstr ""
+msgstr "Proyectos a los que ha contribuido"
msgid "Projects help you organize your work. They contain your file repository, issues, merge requests, and so much more."
msgstr ""
@@ -28511,17 +29133,11 @@ msgid "Projects shared with %{group_name}"
msgstr "Proyectos compartidos con %{group_name}"
msgid "Projects that can be accessed"
-msgstr ""
+msgstr "Proyectos a los que puede acceder"
msgid "Projects to index"
msgstr "Proyectos a indexar"
-msgid "Projects will be permanently deleted after a %{waiting_period}-day waiting period."
-msgstr ""
-
-msgid "Projects will be permanently deleted immediately."
-msgstr ""
-
msgid "Projects with critical vulnerabilities"
msgstr "Proyectos con vulnerabilidades críticas"
@@ -28538,7 +29154,7 @@ msgid "Projects with no vulnerabilities and security scanning enabled"
msgstr "Proyectos sin vulnerabilidades y escaneo de seguridad habilitado"
msgid "Projects with this topic"
-msgstr ""
+msgstr "Proyectos con este tema"
msgid "Projects with write access"
msgstr "Proyectos con acceso de escritura"
@@ -28592,7 +29208,7 @@ msgid "ProjectsNew|Create from template"
msgstr "Crear desde una plantilla"
msgid "ProjectsNew|Create new project"
-msgstr ""
+msgstr "Crear nuevo proyecto"
msgid "ProjectsNew|Description format"
msgstr "Formato de la descripción"
@@ -28606,6 +29222,9 @@ msgstr "Importar"
msgid "ProjectsNew|Import project"
msgstr "Importar proyecto"
+msgid "ProjectsNew|Include a Getting Started README"
+msgstr ""
+
msgid "ProjectsNew|Initialize repository with a README"
msgstr "Inicializar el repositorio con un archivo README"
@@ -28616,11 +29235,14 @@ msgid "ProjectsNew|No import options available"
msgstr "No hay opciones de importación disponibles"
msgid "ProjectsNew|Project Configuration"
-msgstr ""
+msgstr "Configuración del proyecto"
msgid "ProjectsNew|Project description %{tag_start}(optional)%{tag_end}"
msgstr "Descripción del proyecto %{tag_start}(opcional)%{tag_end}"
+msgid "ProjectsNew|Recommended if you're new to GitLab"
+msgstr ""
+
msgid "ProjectsNew|Run CI/CD for external repository"
msgstr "Ejecutar CI/CD para un repositorio externo"
@@ -28637,10 +29259,10 @@ msgid "PrometheusAlerts|exceeded"
msgstr ""
msgid "PrometheusAlerts|is equal to"
-msgstr ""
+msgstr "es igual a"
msgid "PrometheusAlerts|is less than"
-msgstr ""
+msgstr "es menor que"
msgid "PrometheusService|%{exporters} with %{metrics} were found"
msgstr "se han encontrado %{exporters} con %{metrics}"
@@ -29038,6 +29660,9 @@ msgstr ""
msgid "ProtectedBranch|Unprotect"
msgstr "Desproteger"
+msgid "ProtectedBranch|Unprotect branch"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
@@ -29065,6 +29690,9 @@ msgstr "Proteger un entorno"
msgid "ProtectedEnvironment|Protected Environment (%{protected_environments_count})"
msgstr "Entorno Protegido (%{protected_environments_count})"
+msgid "ProtectedEnvironment|Required approvals"
+msgstr ""
+
msgid "ProtectedEnvironment|Select an environment"
msgstr "Seleccione un entorno"
@@ -29086,10 +29714,13 @@ msgstr "Se ha protegido su entorno."
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr "Se ha desprotegido su entorno"
+msgid "ProtectedTags|Unprotect tag"
+msgstr ""
+
msgid "ProtectedTags|default"
msgstr ""
-msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
+msgid "ProtectedTag|By default, protected tags restrict who can modify the tag."
msgstr ""
msgid "ProtectedTag|Learn more."
@@ -29152,6 +29783,9 @@ msgstr "Pipelines públicos"
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Public projects are an easy way to allow everyone to have read-only access."
+msgstr ""
+
msgid "Publish to status page"
msgstr ""
@@ -29285,7 +29919,7 @@ msgid "PushoverService|Get real-time notifications on your device."
msgstr ""
msgid "PushoverService|High priority"
-msgstr ""
+msgstr "Prioridad alta"
msgid "PushoverService|Leave blank for all active devices."
msgstr ""
@@ -29308,9 +29942,6 @@ msgstr "Número total de commits: %{total_commits_count}"
msgid "QualitySummary|Project quality"
msgstr ""
-msgid "Quarters"
-msgstr "Trimestres"
-
msgid "Query"
msgstr "Consulta"
@@ -29395,6 +30026,9 @@ msgstr ""
msgid "Read more about project permissions %{help_link_open}here%{help_link_close}"
msgstr ""
+msgid "Read more about related epics"
+msgstr ""
+
msgid "Read more about related issues"
msgstr "Lea más acerca de las incidencias relacionadas"
@@ -29425,10 +30059,7 @@ msgstr ""
msgid "Rebase source branch on the target branch."
msgstr ""
-msgid "Rebase without CI"
-msgstr ""
-
-msgid "Rebases and triggers a pipeline"
+msgid "Rebase without pipeline"
msgstr ""
msgid "Recaptcha verified?"
@@ -29479,9 +30110,6 @@ msgstr ""
msgid "Reconfigure"
msgstr "Reconfigurar"
-msgid "Recovering projects"
-msgstr ""
-
msgid "Recovery Codes"
msgstr "Codigos de recuperacion"
@@ -29541,6 +30169,12 @@ msgstr "La regeneración del id de una instancia puede interrumpir la integraciÃ
msgid "Regex pattern"
msgstr "Patrón regex"
+msgid "Region"
+msgstr ""
+
+msgid "Regions"
+msgstr ""
+
msgid "Register"
msgstr "Registro"
@@ -29771,9 +30405,6 @@ msgstr "Eliminar todas las etiquetas o las etiquetas específicas"
msgid "Remove all or specific reviewer(s)"
msgstr ""
-msgid "Remove approver"
-msgstr ""
-
msgid "Remove approvers"
msgstr "Eliminar los aprobadores"
@@ -29789,6 +30420,9 @@ msgstr "Eliminar el usuario asignado"
msgid "Remove attention request"
msgstr ""
+msgid "Remove attention request(s)"
+msgstr ""
+
msgid "Remove avatar"
msgstr "Eliminar avatar"
@@ -29927,6 +30561,9 @@ msgstr "Eliminar todas las etiquetas."
msgid "Removed an issue from an epic."
msgstr "Se eliminó la incidencia de la tarea épica."
+msgid "Removed attention from %{users_sentence}."
+msgstr ""
+
msgid "Removed attention request from @%{username}"
msgstr ""
@@ -29978,6 +30615,9 @@ msgstr "Elimina todas las etiquetas."
msgid "Removes an issue from an epic."
msgstr "Eliminar una incidencia de una tarea épica."
+msgid "Removes attention from %{users_sentence}."
+msgstr ""
+
msgid "Removes parent epic %{epic_ref}."
msgstr "Elimina la tarea épica padre %{epic_ref}."
@@ -30089,6 +30729,9 @@ msgstr "Informar de un abuso"
msgid "Report abuse to admin"
msgstr "Informar de un abuso al administrador"
+msgid "Report is generating and will be sent to your email address."
+msgstr ""
+
msgid "Reported %{timeAgo} by %{reportedBy}"
msgstr "Denunciado %{timeAgo} por %{reportedBy}"
@@ -30378,6 +31021,15 @@ msgstr ""
msgid "Request attention"
msgstr ""
+msgid "Request attention from %{users_sentence}."
+msgstr ""
+
+msgid "Request attention from assignee or reviewer"
+msgstr ""
+
+msgid "Request attention from assignee(s) or reviewer(s)"
+msgstr ""
+
msgid "Request attention to review"
msgstr ""
@@ -30402,6 +31054,9 @@ msgstr ""
msgid "Requested %{time_ago}"
msgstr "Solicitado %{time_ago}"
+msgid "Requested attention from %{users_sentence}."
+msgstr ""
+
msgid "Requested attention from @%{username}"
msgstr ""
@@ -30439,7 +31094,7 @@ msgid "Required approvals (%{approvals_given} given, you've approved)"
msgstr ""
msgid "Required in this project."
-msgstr ""
+msgstr "Requerido en este proyecto."
msgid "Required only if you are not using role instance credentials."
msgstr ""
@@ -30539,7 +31194,7 @@ msgid "Reset template"
msgstr "Restablecer plantilla"
msgid "Reset to project defaults"
-msgstr ""
+msgstr "Restablecer a los valores predeterminados del proyecto"
msgid "Resetting the authorization key will invalidate the previous key. Existing alert configurations will need to be updated with the new key."
msgstr "Al restablecer la clave de autorización se invalidará la clave anterior. Las configuraciones de alerta existentes deberán actualizarse con la nueva clave."
@@ -30616,6 +31271,9 @@ msgstr "Restaurar grupo"
msgid "Restore project"
msgstr "Restaurar proyecto"
+msgid "Restoring projects"
+msgstr ""
+
msgid "Restoring the group will prevent the group, its subgroups and projects from being removed on this date."
msgstr ""
@@ -30646,6 +31304,9 @@ msgstr ""
msgid "Retry"
msgstr "Reintentar"
+msgid "Retry failed jobs"
+msgstr ""
+
msgid "Retry job"
msgstr ""
@@ -30693,9 +31354,6 @@ msgstr "Ver la última aplicación"
msgid "Review changes"
msgstr ""
-msgid "Review requested from %{name}"
-msgstr "Revisión solicitada por %{name}"
-
msgid "Review requests for you"
msgstr ""
@@ -30756,7 +31414,7 @@ msgid "RightSidebar|Issue email"
msgstr ""
msgid "RightSidebar|adding a"
-msgstr "Agregar a"
+msgstr "Añadir a"
msgid "RightSidebar|deleting the"
msgstr "Eliminar el"
@@ -30860,14 +31518,17 @@ msgstr ""
msgid "Runners|Assigned Group"
msgstr ""
-msgid "Runners|Associated with one or more projects"
+msgid "Runners|Assigned Projects (%{projectCount})"
msgstr ""
+msgid "Runners|Associated with one or more projects"
+msgstr "Asociado con uno o más proyectos"
+
msgid "Runners|Available to all projects"
-msgstr ""
+msgstr "Disponible para todos los proyectos"
msgid "Runners|Available to all projects and subgroups in the group"
-msgstr ""
+msgstr "Disponible para todos los proyectos y subgrupos del grupo"
msgid "Runners|Can run untagged jobs"
msgstr ""
@@ -30929,6 +31590,9 @@ msgstr ""
msgid "Runners|Instance"
msgstr ""
+msgid "Runners|Jobs"
+msgstr ""
+
msgid "Runners|Last contact"
msgstr ""
@@ -31022,9 +31686,6 @@ msgstr ""
msgid "Runners|Runner %{name} was deleted"
msgstr ""
-msgid "Runners|Runner ID"
-msgstr ""
-
msgid "Runners|Runner assigned to project."
msgstr ""
@@ -31172,6 +31833,9 @@ msgstr ""
msgid "Runners|stale"
msgstr ""
+msgid "Runner|This runner has not run any jobs."
+msgstr ""
+
msgid "Running"
msgstr "En ejecución"
@@ -31286,6 +31950,24 @@ msgstr "Guardando"
msgid "Saving project."
msgstr "Guardar proyecto."
+msgid "ScanResultPolicy|%{ifLabelStart}if%{ifLabelEnd} %{scanners} scan in an open merge request targeting the %{branches} branch(es) finds %{vulnerabilitiesAllowed} or more %{severities} vulnerabilities that are %{vulnerabilityStates}"
+msgstr ""
+
+msgid "ScanResultPolicy|%{thenLabelStart}Then%{thenLabelEnd} Require approval from %{approvalsRequired} of the following approvers: %{approvers}"
+msgstr ""
+
+msgid "ScanResultPolicy|add an approver"
+msgstr ""
+
+msgid "ScanResultPolicy|scanners"
+msgstr ""
+
+msgid "ScanResultPolicy|severity levels"
+msgstr ""
+
+msgid "ScanResultPolicy|vulnerability states"
+msgstr ""
+
msgid "Scanner"
msgstr ""
@@ -31418,6 +32100,9 @@ msgstr "Buscar un grupo"
msgid "Search for a user"
msgstr "Buscar un usuario"
+msgid "Search for an emoji"
+msgstr ""
+
msgid "Search for projects, issues, etc."
msgstr "Buscar proyectos, incidencias, etc."
@@ -31506,7 +32191,7 @@ msgid "SearchAutocomplete|in group %{groupName}"
msgstr ""
msgid "SearchAutocomplete|in project %{projectName}"
-msgstr ""
+msgstr "en el proyecto %{projectName}"
msgid "SearchCodeResults|of %{link_to_project}"
msgstr "de %{link_to_project}"
@@ -31605,18 +32290,12 @@ msgstr "Secreto"
msgid "Secret Detection"
msgstr "Detección de secretos"
-msgid "Secret access key"
-msgstr ""
-
msgid "Secret token"
msgstr ""
msgid "Secure token that identifies an external storage request."
msgstr ""
-msgid "SecureCodeWarrior"
-msgstr ""
-
msgid "Security"
msgstr "Seguridad"
@@ -31627,10 +32306,10 @@ msgid "Security Configuration"
msgstr "Configuración de seguridad"
msgid "Security Dashboard"
-msgstr "Panel de control de seguridad"
+msgstr "Tablero de seguridad"
msgid "Security dashboard"
-msgstr "Panel de control de seguridad"
+msgstr "Tablero de seguridad"
msgid "Security navigation"
msgstr ""
@@ -31641,9 +32320,6 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "Security training with guide and learning pathways."
-msgstr ""
-
msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
@@ -31746,7 +32422,7 @@ msgstr ""
msgid "SecurityConfiguration|Manage corpus"
msgstr ""
-msgid "SecurityConfiguration|Manage corpus files used as mutation sources in coverage fuzzing."
+msgid "SecurityConfiguration|Manage corpus files used as seed inputs with coverage-guided fuzzing."
msgstr ""
msgid "SecurityConfiguration|Manage profiles for use by DAST scans."
@@ -31777,7 +32453,7 @@ msgid "SecurityConfiguration|SAST Configuration"
msgstr ""
msgid "SecurityConfiguration|Secure your project"
-msgstr ""
+msgstr "Securice su proyecto"
msgid "SecurityConfiguration|Security testing"
msgstr ""
@@ -31812,15 +32488,15 @@ msgstr ""
msgid "SecurityOrchestration|.yaml preview"
msgstr ""
-msgid "SecurityOrchestration|Action"
-msgstr ""
-
msgid "SecurityOrchestration|Actions"
msgstr ""
msgid "SecurityOrchestration|Add rule"
msgstr ""
+msgid "SecurityOrchestration|After dismissing the alert, the information will never be shown again."
+msgstr ""
+
msgid "SecurityOrchestration|All policies"
msgstr ""
@@ -31831,28 +32507,28 @@ msgid "SecurityOrchestration|An error occurred unassigning your security policy
msgstr ""
msgid "SecurityOrchestration|Choose a project"
-msgstr ""
+msgstr "Seleccione un proyecto"
msgid "SecurityOrchestration|Description"
msgstr ""
-msgid "SecurityOrchestration|Disabled"
+msgid "SecurityOrchestration|Don't show the alert anymore"
msgstr ""
msgid "SecurityOrchestration|Edit policy"
msgstr ""
msgid "SecurityOrchestration|Edit policy project"
+msgstr "Editar la política del proyecto"
+
+msgid "SecurityOrchestration|Empty policy name"
msgstr ""
msgid "SecurityOrchestration|Enabled"
msgstr ""
msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
-msgstr ""
-
-msgid "SecurityOrchestration|Executes a %{scanType} scan"
-msgstr ""
+msgstr "Forzar la seguridad para este proyecto. %{linkStart}Más información%{linkEnd}"
msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
msgstr ""
@@ -31860,7 +32536,7 @@ msgstr ""
msgid "SecurityOrchestration|Invalid policy type"
msgstr ""
-msgid "SecurityOrchestration|Latest scan"
+msgid "SecurityOrchestration|Latest scan run against %{agent}"
msgstr ""
msgid "SecurityOrchestration|Network"
@@ -31869,15 +32545,27 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No actions defined - policy will not run."
+msgstr ""
+
+msgid "SecurityOrchestration|No description"
+msgstr ""
+
msgid "SecurityOrchestration|No rules defined - policy will not run."
msgstr ""
+msgid "SecurityOrchestration|Not enabled"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
msgid "SecurityOrchestration|Policies"
msgstr ""
+msgid "SecurityOrchestration|Policy Type"
+msgstr ""
+
msgid "SecurityOrchestration|Policy cannot be enabled for non-existing branches (%{branches})"
msgstr ""
@@ -31902,10 +32590,13 @@ msgstr ""
msgid "SecurityOrchestration|Require %{approvals} %{plural} from %{approvers} if any of the following occur:"
msgstr ""
-msgid "SecurityOrchestration|Rule"
+msgid "SecurityOrchestration|Rules"
msgstr ""
-msgid "SecurityOrchestration|Rules"
+msgid "SecurityOrchestration|Runs %{actions} and %{lastAction} scans"
+msgstr ""
+
+msgid "SecurityOrchestration|Runs a %{action} scan"
msgstr ""
msgid "SecurityOrchestration|Scan Execution"
@@ -31965,6 +32656,9 @@ msgstr ""
msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
+msgid "SecurityOrchestration|This view only shows scan results for the agent %{agent}. You can view scan results for all agents in the %{linkStart}Operational Vulnerabilities tab of the vulnerability report%{linkEnd}."
+msgstr ""
+
msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
@@ -32019,9 +32713,6 @@ msgstr ""
msgid "SecurityOrchestration|users with ids"
msgstr ""
-msgid "SecurityOrchestration|view results"
-msgstr ""
-
msgid "SecurityOrchestration|vulnerabilities"
msgstr ""
@@ -32038,7 +32729,7 @@ msgid "SecurityPolicies|Policy type"
msgstr ""
msgid "SecurityReports|%{count}+ projects"
-msgstr ""
+msgstr "%{count}+ proyectos"
msgid "SecurityReports|%{firstProject} and %{secondProject}"
msgstr "%{firstProject} y %{secondProject}"
@@ -32161,16 +32852,16 @@ msgid "SecurityReports|Monitor vulnerabilities across clusters"
msgstr ""
msgid "SecurityReports|Monitor vulnerabilities in all of your projects"
-msgstr ""
+msgstr "Monitorizar las vulnerabilidades en todos sus proyectos"
msgid "SecurityReports|Monitor vulnerabilities in your group"
msgstr ""
msgid "SecurityReports|Monitor vulnerabilities in your project"
-msgstr ""
+msgstr "Monitorizar las vulnerabilidades en su proyecto"
msgid "SecurityReports|Monitored projects"
-msgstr ""
+msgstr "Proyectos monitorizados"
msgid "SecurityReports|More info"
msgstr "Más información"
@@ -32203,7 +32894,7 @@ msgid "SecurityReports|Projects added"
msgstr "Proyectos añadidos"
msgid "SecurityReports|Remove project from dashboard"
-msgstr "Eliminar proyecto del panel de control"
+msgstr "SecurityReports|Eliminar proyecto del tablero"
msgid "SecurityReports|Scan details"
msgstr ""
@@ -32691,22 +33382,19 @@ msgstr "Copiar URL"
msgid "Serverless|Getting started with serverless"
msgstr "Comenzando con serverless"
-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 "Sí cree que ninguno de estos casos aplican, por favor, vuelva a intentarlo más tarde. Es posible que los datos de la función todavía no esté disponible."
-msgid "Serverless|In order to start using functions as a service, you must first install Knative on your Kubernetes cluster. %{linkStart}More information%{linkEnd}"
-msgstr ""
-
msgid "Serverless|Learn more about Serverless"
msgstr "Obtenga más información sobre Serverless"
msgid "Serverless|No functions available"
msgstr "No hay funciones disponibles"
-msgid "Serverless|Sign up for First Look"
+msgid "Serverless|Serverless was %{linkStart}deprecated%{linkEnd} in GitLab 14.3."
+msgstr ""
+
+msgid "Serverless|Serverless was %{postLinkStart}deprecated%{postLinkEnd}. But if you opt to use it, you must install Knative in your Kubernetes cluster first. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "Serverless|The deploy job has not finished."
@@ -32718,9 +33406,6 @@ msgstr "Las funciones enumeradas en el archivo %{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 "Actualmente no hay datos de función disponibles desde Knative. Esto puede deberse por a múltiples razones, incluyendo:"
-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 "Su archivo %{startTag}.gitlab-ci.yml%{endTag} no está configurado correctamente."
@@ -32736,9 +33421,6 @@ msgstr ""
msgid "Service Account Key"
msgstr ""
-msgid "Service Accounts"
-msgstr ""
-
msgid "Service Accounts keys authorize GitLab to deploy your Google Cloud project"
msgstr ""
@@ -32748,10 +33430,10 @@ msgstr "Service Desk"
msgid "Service Desk allows people to create issues in your GitLab instance without their own user account. It provides a unique email address for end users to create issues in a project. Replies can be sent either through the GitLab interface or by email. End users only see threads through email."
msgstr ""
-msgid "Service Usage Data"
+msgid "Service account generated successfully"
msgstr ""
-msgid "Service account generated successfully"
+msgid "Service accounts"
msgstr ""
msgid "Service ping is disabled in your configuration file, and cannot be enabled through this form."
@@ -32895,6 +33577,9 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr "Establecer el hito a %{milestone_reference}."
+msgid "Set the per-user rate limit for getting a user by ID via the API."
+msgstr ""
+
msgid "Set the per-user rate limit for notes created by web or API requests."
msgstr ""
@@ -33074,6 +33759,9 @@ msgstr ""
msgid "Shared runners details"
msgstr ""
+msgid "Shared runners enabled cannot be enabled until a valid credit card is on file"
+msgstr ""
+
msgid "Shared runners help link"
msgstr "Enlace de ayuda de los ejecutores compartidos"
@@ -33131,6 +33819,9 @@ msgstr ""
msgid "Show all issues."
msgstr "Mostrar todas las incidencias."
+msgid "Show all milestones"
+msgstr ""
+
msgid "Show all test cases."
msgstr ""
@@ -33167,6 +33858,9 @@ msgstr "Mostrar el explorador de archivos"
msgid "Show file contents"
msgstr ""
+msgid "Show group milestones"
+msgstr ""
+
msgid "Show labels"
msgstr ""
@@ -33182,6 +33876,12 @@ msgstr ""
msgid "Show open epics"
msgstr ""
+msgid "Show project milestones"
+msgstr ""
+
+msgid "Show sub-group milestones"
+msgstr ""
+
msgid "Show the Closed list"
msgstr ""
@@ -33191,11 +33891,6 @@ msgstr ""
msgid "Show whitespace changes"
msgstr "Mostrar los espacios en blanco de los cambios"
-msgid "Showing %d event"
-msgid_plural "Showing %d events"
-msgstr[0] "Mostrando %d evento"
-msgstr[1] "Mostrando %d eventos"
-
msgid "Showing %{conflict} between %{sourceBranch} and %{targetBranch}"
msgstr ""
@@ -33255,12 +33950,6 @@ msgstr "Sin estado"
msgid "Sidebar|None"
msgstr "Ninguno"
-msgid "Sidebar|Only numeral characters allowed"
-msgstr "Solo se permiten caracteres numéricos"
-
-msgid "Sidebar|Weight"
-msgstr "Peso"
-
msgid "Sidekiq job compression threshold (bytes)"
msgstr ""
@@ -33423,6 +34112,9 @@ msgstr "La integración con Slack le permite interactuar con GitLab mediante com
msgid "Slack logo"
msgstr ""
+msgid "SlackIntegration|Are you sure you want to remove this project from the Slack application?"
+msgstr ""
+
msgid "SlackIntegration|GitLab for Slack"
msgstr ""
@@ -33432,6 +34124,9 @@ msgstr ""
msgid "SlackIntegration|Project alias"
msgstr ""
+msgid "SlackIntegration|Remove project"
+msgstr ""
+
msgid "SlackIntegration|Select a GitLab project to link with your Slack workspace."
msgstr ""
@@ -33576,9 +34271,6 @@ msgstr "Algo salió mal al intentar cambiar el estado de bloqueo de este %{issua
msgid "Something went wrong trying to load issue contacts."
msgstr ""
-msgid "Something went wrong when creating a work item. Please try again"
-msgstr ""
-
msgid "Something went wrong when reordering designs. Please try again"
msgstr ""
@@ -33586,7 +34278,7 @@ msgid "Something went wrong when toggling the button"
msgstr "Algo salió mal al cambiar el estado del botón. ¡Por favor, inténtelo de nuevo!"
msgid "Something went wrong while adding your award. Please try again."
-msgstr "Se ha producido un error al agregar su premio. Por favor, inténtalo de nuevo."
+msgstr "Se ha producido un error al añadir su premio. Por favor, inténtalo de nuevo."
msgid "Something went wrong while applying the batch of suggestions. Please try again."
msgstr ""
@@ -33672,9 +34364,6 @@ msgstr "Se ha producido un error al inicializar el visor OpenAPI"
msgid "Something went wrong while inserting your image. Please try again."
msgstr ""
-msgid "Something went wrong while merging this merge request. Please try again."
-msgstr "Se ha producido un error, mientras se realizaba el merge request. Por favor, inténtelo de nuevo."
-
msgid "Something went wrong while obtaining the Let's Encrypt certificate."
msgstr ""
@@ -33730,10 +34419,10 @@ msgid "Something went wrong with your automatic subscription renewal."
msgstr ""
msgid "Something went wrong, unable to add %{project} to dashboard"
-msgstr "Algo salió mal, no se puede agregar %{project} al panel de control"
+msgstr "Se ha producido un erro al añadir %{project} al tablero"
msgid "Something went wrong, unable to add projects to dashboard"
-msgstr "Se ha producido un erro al añadir los proyectos al panel de control"
+msgstr "Se ha producido un erro al añadir los proyectos al tablero"
msgid "Something went wrong, unable to delete project"
msgstr ""
@@ -33996,11 +34685,11 @@ msgstr "Habilitar Sourcegraph"
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."
+msgid "SourcegraphAdmin|Learn more."
msgstr ""
-msgid "SourcegraphAdmin|More information"
-msgstr "Más información"
+msgid "SourcegraphAdmin|Only public projects have code intelligence enabled and communicate with Sourcegraph."
+msgstr ""
msgid "SourcegraphAdmin|Save changes"
msgstr "Guardar cambios"
@@ -34008,8 +34697,8 @@ msgstr "Guardar cambios"
msgid "SourcegraphAdmin|Sourcegraph URL"
msgstr "URL de Sourcegraph"
-msgid "SourcegraphAdmin|e.g. https://sourcegraph.example.com"
-msgstr "por ejemplo: https://sourcegraph.example.com"
+msgid "SourcegraphAdmin|https://sourcegraph.example.com"
+msgstr ""
msgid "SourcegraphPreferences|This feature is experimental and currently limited to certain projects."
msgstr "Esta característica es experimental y actualmente limitada a determinados proyectos."
@@ -34143,6 +34832,9 @@ msgstr "Iniciar la limpieza"
msgid "Start date"
msgstr "Fecha de inicio"
+msgid "Start free trial"
+msgstr ""
+
msgid "Start merge train"
msgstr ""
@@ -34173,6 +34865,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 escalation for this incident."
+msgstr ""
+
msgid "Starting..."
msgstr "Iniciando..."
@@ -34185,6 +34880,9 @@ msgstr "Comienza %{startsIn}"
msgid "Starts at (UTC)"
msgstr "Comienza a las (UTC)"
+msgid "Starts escalations for this incident"
+msgstr ""
+
msgid "Starts on"
msgstr ""
@@ -34446,6 +35144,9 @@ msgstr "Desconocido"
msgid "Strikethrough"
msgstr ""
+msgid "Strikethrough text"
+msgstr ""
+
msgid "Subgroup information"
msgstr ""
@@ -34680,6 +35381,21 @@ msgstr "El recuento de uso se realiza una vez al día a 12:00 PM."
msgid "Subscriptions"
msgstr "Suscripciones"
+msgid "Subscriptions|Chat with sales"
+msgstr ""
+
+msgid "Subscriptions|Close"
+msgstr ""
+
+msgid "Subscriptions|Not ready to buy yet?"
+msgstr ""
+
+msgid "Subscriptions|Start a free trial"
+msgstr ""
+
+msgid "Subscriptions|We understand. Maybe you have some questions for our sales team, or maybe you'd like to try some of the paid features first. What would you like to do?"
+msgstr ""
+
msgid "Subscription|Your subscription for %{strong}%{namespace_name}%{strong_close} has expired and you are now on %{pricing_link_start}the GitLab Free tier%{pricing_link_end}. Don't worry, your data is safe. Get in touch with our support team (%{support_email}). They'll gladly help with your subscription renewal."
msgstr ""
@@ -34890,6 +35606,9 @@ msgstr ""
msgid "SuperSonics|Maximum users"
msgstr ""
+msgid "SuperSonics|Offline cloud"
+msgstr ""
+
msgid "SuperSonics|Paste your activation code"
msgstr ""
@@ -34956,6 +35675,12 @@ msgstr ""
msgid "SuperSonics|You do not have an active subscription"
msgstr ""
+msgid "SuperSonics|You have a future dated license"
+msgstr ""
+
+msgid "SuperSonics|You have added a license that activates on %{date}. Please see the subscription history table below for more details."
+msgstr ""
+
msgid "SuperSonics|You have successfully added a license that activates on %{date}. Please see the subscription history table below for more details."
msgstr ""
@@ -35115,6 +35840,9 @@ msgstr "Nombre de la etiqueta"
msgid "Tag name is required"
msgstr ""
+msgid "Tag push"
+msgstr ""
+
msgid "Tag push events"
msgstr ""
@@ -35209,7 +35937,7 @@ msgid "TagsPage|Unable to load tags"
msgstr ""
msgid "TagsPage|Use git tag command to add a new one:"
-msgstr "Utilice el comando git tag para agregar una nueva:"
+msgstr "Utilice el comando git tag para añadir una nueva:"
msgid "TagsPage|Write your release notes or drag files here…"
msgstr "Escriba sus notas de la versión o arrastre los archivos aquí…"
@@ -35217,6 +35945,9 @@ msgstr "Escriba sus notas de la versión o arrastre los archivos aquí…"
msgid "TagsPage|protected"
msgstr "protegido"
+msgid "Take a look at the documentation to discover all of GitLab’s capabilities."
+msgstr ""
+
msgid "Target Branch"
msgstr "Rama de destino"
@@ -35619,6 +36350,9 @@ msgstr ""
msgid "Tests"
msgstr "Pruebas"
+msgid "Text (optional)"
+msgstr ""
+
msgid "Text added to the body of all email messages. %{character_limit} character limit"
msgstr ""
@@ -35669,6 +36403,9 @@ msgstr ""
msgid "The CSV export will be created in the background. Once finished, it will be sent to %{email} in an attachment."
msgstr ""
+msgid "The CSV export you requested of all user memberships is attached to this email."
+msgstr ""
+
msgid "The GitLab subscription service (customers.gitlab.com) is currently experiencing an outage. You can monitor the status and get updates at %{linkStart}status.gitlab.com%{linkEnd}."
msgstr ""
@@ -35679,10 +36416,10 @@ msgid "The ID of the application."
msgstr ""
msgid "The Issue Tracker is the place to add things that need to be improved or solved in a project"
-msgstr "El gestor de incidencias es el lugar para agregar cosas que necesitan ser mejoradas o resueltas en un proyecto"
+msgstr "El gestor de incidencias es el lugar para añadir cosas que necesitan ser mejoradas o resueltas en un proyecto"
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 "El gestor de incidencias es el lugar para agregar cosas que necesitan ser mejoradas o resueltas en un proyecto. Puede registrarse o iniciar sesión para crear incidencias para este proyecto."
+msgstr "El gestor de incidencias es el lugar para añadir cosas que necesitan ser mejoradas o resueltas en un proyecto. Puede registrarse o iniciar sesión para crear incidencias para este proyecto."
msgid "The Prometheus server responded with \"bad request\". Please check your queries are correct and are supported in your Prometheus version. %{documentationLink}"
msgstr ""
@@ -35744,6 +36481,9 @@ msgstr "El contenido de esta página no está codificado en UTF-8. Las ediciones
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 epic"
+msgstr ""
+
msgid "The current issue"
msgstr "La incidencia actual"
@@ -35905,6 +36645,9 @@ msgstr ""
msgid "The latest pipeline for this merge request has failed."
msgstr ""
+msgid "The license key is invalid."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -35920,6 +36663,9 @@ msgstr "La licencia se ha subido correctamente y está activada. Puede ver los d
msgid "The license was successfully uploaded and will be active from %{starts_at}. You can see the details below."
msgstr ""
+msgid "The license you uploaded is invalid. If the issue persists, contact support at %{link}."
+msgstr ""
+
msgid "The list creation wizard is already open"
msgstr ""
@@ -36541,10 +37287,13 @@ msgstr "Esta acción puede provocar la pérdida de datos. Para prevenir acciones
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} and everything this project contains. %{strongOpen}There is no going back%{strongClose}"
+msgstr ""
+
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains."
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}on %{date}%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains. %{strongOpen}There is no going back.%{strongClose}"
msgstr ""
msgid "This action will %{strongOpen}permanently remove%{strongClose} %{codeOpen}%{group}%{codeClose} %{strongOpen}immediately%{strongClose}."
@@ -36673,9 +37422,6 @@ msgstr "Este campo es obligatorio."
msgid "This file was modified for readability, and can't accept suggestions. Edit it directly."
msgstr ""
-msgid "This forked project has the following:"
-msgstr ""
-
msgid "This form is disabled in preview"
msgstr ""
@@ -36688,7 +37434,7 @@ msgstr ""
msgid "This group can't be removed because it is linked to a subscription. To remove this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
-msgid "This group can't be transfered because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
+msgid "This group can't be transferred because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
msgid "This group cannot be invited to a project inside a group with enforced SSO"
@@ -36715,6 +37461,9 @@ 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 incident is already escalated with '%{escalation_policy_name}'."
+msgstr ""
+
msgid "This invitation was sent to %{mail_to_invite_email}, but you are signed in as %{link_to_current_user} with email %{mail_to_current_user}."
msgstr ""
@@ -36733,9 +37482,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 merge train pipeline"
-msgstr ""
-
msgid "This is a private email address %{helpIcon} generated just for you. Anyone who has it can create issues or merge requests as if they were you. If that happens, %{resetLinkStart}reset this token%{resetLinkEnd}."
msgstr ""
@@ -36757,6 +37503,12 @@ msgstr ""
msgid "This is your current session"
msgstr "Esta es su sesión actual"
+msgid "This issue cannot be assigned to a confidential epic because it is public."
+msgstr ""
+
+msgid "This issue cannot be made public because it belongs to a confidential epic."
+msgstr ""
+
msgid "This issue is confidential and should only be visible to team members with at least Reporter access."
msgstr ""
@@ -36874,6 +37626,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 branch is protected from force push."
+msgstr ""
+
msgid "This merge request cannot be rebased while there are conflicts."
msgstr ""
@@ -36925,9 +37680,15 @@ msgstr "Este pipeline utiliza una configuración de CI/CD predefinida habilitada
msgid "This pipeline was triggered by a schedule."
msgstr ""
+msgid "This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project"
msgstr "Este proyecto"
+msgid "This project can be restored until %{date}."
+msgstr ""
+
msgid "This project cannot be %{visibilityLevel} because the visibility of %{openShowLink}%{name}%{closeShowLink} is %{visibility}. To make this project %{visibilityLevel}, you must first %{openEditLink}change the visibility%{closeEditLink} of the parent group."
msgstr ""
@@ -36946,6 +37707,9 @@ msgstr "Este proyecto no tiene tokens de acceso activos."
msgid "This project is %{strongStart}NOT%{strongEnd} a fork, and has the following:"
msgstr ""
+msgid "This project is %{strongStart}NOT%{strongEnd} a fork. This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr "Este proyecto está archivado y no se puede comentar en el."
@@ -37019,7 +37783,7 @@ msgid "This user has no identities"
msgstr "El usuario no tiene ninguna identidad"
msgid "This user has no personal projects."
-msgstr ""
+msgstr "Este usuario no tiene proyectos personales."
msgid "This user has previously committed to the %{name} project."
msgstr ""
@@ -37473,7 +38237,7 @@ msgid "To add a custom suffix, set up a Service Desk email address. %{linkStart}
msgstr ""
msgid "To add the entry manually, provide the following details to the application on your phone."
-msgstr "Para agregar la entrada manualmente, proporcione los siguientes detalles a la aplicación en su teléfono."
+msgstr "Para añadir la entrada manualmente, proporcione los siguientes detalles a la aplicación en su teléfono."
msgid "To confirm, type %{phrase_code}"
msgstr "Para confirmar, escriba %{phrase_code}"
@@ -37590,7 +38354,7 @@ msgid "To see this project's operational details, %{linkStart}upgrade its group
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 "Para ver los detalles operacionales de este proyecto, contacte con un dueño del grupo %{groupName} para actualizar el plan. También puede eiminar el proyecto del panel de control."
+msgstr "Para ver los detalles operacionales de este proyecto, contacte con un propietario del grupo %{groupName} para actualizar el plan. También puede eiminar el proyecto del tablero."
msgid "To see what's changed or create a merge request, choose a branch or tag (like %{branch}), or enter a commit (like %{sha})."
msgstr ""
@@ -37637,6 +38401,9 @@ msgstr "La tarea pendiente se ha marcado como realizada correctamente."
msgid "Today"
msgstr "Hoy"
+msgid "Todos count"
+msgstr ""
+
msgid "Todos|Are you looking for things to do? Take a look at %{strongStart}%{openIssuesLinkStart}open issues%{openIssuesLinkEnd}%{strongEnd}, contribute to %{strongStart}%{mergeRequestLinkStart}a merge request%{mergeRequestLinkEnd}%{mergeRequestLinkEnd}%{strongEnd}, or mention someone in a comment to automatically assign them a new to-do item."
msgstr ""
@@ -37910,10 +38677,8 @@ msgstr "Vista de árbol"
msgid "Trending"
msgstr "Tendencia"
-msgid "Trials|%{planName} Trial %{enDash} %{num} day left"
-msgid_plural "Trials|%{planName} Trial %{enDash} %{num} days left"
-msgstr[0] ""
-msgstr[1] ""
+msgid "Trials|%{planName} Trial"
+msgstr ""
msgid "Trials|Compare all plans"
msgstr "Comparar todos los planes"
@@ -37921,6 +38686,9 @@ msgstr "Comparar todos los planes"
msgid "Trials|Create a new group to start your GitLab Ultimate trial."
msgstr ""
+msgid "Trials|Day %{daysUsed}/%{duration}"
+msgstr ""
+
msgid "Trials|Go back to GitLab"
msgstr "Volver a GitLab"
@@ -38170,7 +38938,7 @@ msgstr ""
msgid "URL is triggered when repository is updated"
msgstr ""
-msgid "URL must be percent-encoded if neccessary."
+msgid "URL must be percent-encoded if necessary."
msgstr ""
msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
@@ -38389,6 +39157,9 @@ msgstr "Desbloquear"
msgid "Unlock account"
msgstr ""
+msgid "Unlock more features with GitLab Ultimate"
+msgstr ""
+
msgid "Unlock the discussion"
msgstr "Desbloquear la discusión"
@@ -38452,6 +39223,9 @@ msgstr "Cancelar la suscripción de %{quick_action_target}."
msgid "Unsubscribes from this %{quick_action_target}."
msgstr "Cancelar la suscripción desde este %{quick_action_target}."
+msgid "Unsupported sort value."
+msgstr ""
+
msgid "Unsupported todo type passed. Supported todo types are: %{todo_types}"
msgstr "Tipo de tarea no soportada. Los tipos de tareas soportadas son: %{todo_types}"
@@ -38680,6 +39454,9 @@ msgstr "Periodo actual de uso"
msgid "UsageQuota|File attachments and smaller design graphics."
msgstr ""
+msgid "UsageQuota|From %{storage_enforcement_date} storage limits will apply to this namespace. View and manage your usage in %{strong_start}Group Settings &gt; Usage quotas%{strong_end}."
+msgstr ""
+
msgid "UsageQuota|Git repository."
msgstr ""
@@ -38740,6 +39517,9 @@ msgstr "Almacenamiento"
msgid "UsageQuota|Storage type"
msgstr ""
+msgid "UsageQuota|Storage used"
+msgstr ""
+
msgid "UsageQuota|This is the total amount of storage used across your projects within this namespace."
msgstr ""
@@ -38935,6 +39715,12 @@ msgstr "Utilizar almacenamiento hash"
msgid "Use hashed storage paths for newly created and renamed repositories. Always enabled since 13.0."
msgstr ""
+msgid "Use issue count"
+msgstr ""
+
+msgid "Use issue weight"
+msgstr ""
+
msgid "Use one line per URI"
msgstr "Utilice una línea por URI"
@@ -39316,6 +40102,9 @@ msgstr "Nombre de usuario: %{username}"
msgid "Users"
msgstr "Usuarios"
+msgid "Users API rate limit"
+msgstr ""
+
msgid "Users can launch a development environment from a GitLab browser tab when the %{linkStart}Gitpod%{linkEnd} integration is enabled."
msgstr ""
@@ -39630,7 +40419,7 @@ msgid "View file @ %{commitSha}"
msgstr "Ver archivo @ %{commitSha}"
msgid "View full dashboard"
-msgstr "Ver el panel de control completo"
+msgstr "Ver el tablero completo"
msgid "View full log"
msgstr "Ver registro completo"
@@ -39641,6 +40430,9 @@ msgstr ""
msgid "View group labels"
msgstr "Ver etiquetas de grupo"
+msgid "View group pipeline usage quota"
+msgstr ""
+
msgid "View incident details at"
msgstr ""
@@ -39693,7 +40485,7 @@ msgid "View page @ "
msgstr "Ver página @ "
msgid "View performance dashboard."
-msgstr "Ver panel de control de rendimiento."
+msgstr "Ver el tablero de rendimiento."
msgid "View project"
msgstr "Ver proyecto"
@@ -39728,7 +40520,7 @@ msgid "View the latest successful deployment to this environment"
msgstr "Vea la última despliegue con éxito en este entorno"
msgid "View the performance dashboard at"
-msgstr "Ver el panel de control del rendimiento en"
+msgstr "Ver el tablero de rendimiento en"
msgid "View usage details"
msgstr ""
@@ -39793,6 +40585,9 @@ msgstr "Vulnerabilidades"
msgid "Vulnerabilities over time"
msgstr "Vulnerabilidades a lo largo del tiempo"
+msgid "Vulnerability"
+msgstr ""
+
msgid "Vulnerability Report"
msgstr "Informe de vulnerabilidad"
@@ -39844,6 +40639,9 @@ msgstr ""
msgid "VulnerabilityManagement|An unverified non-confirmed finding"
msgstr ""
+msgid "VulnerabilityManagement|At least one identifier is required"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr "Cambiar estado"
@@ -39853,12 +40651,24 @@ msgstr ""
msgid "VulnerabilityManagement|Create Jira issue"
msgstr "Crear una incidencia en Jira"
+msgid "VulnerabilityManagement|Enter a name"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE code"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE identifier URL"
+msgstr ""
+
msgid "VulnerabilityManagement|Fetching linked Jira issues"
msgstr ""
msgid "VulnerabilityManagement|Manually add a vulnerability entry into the vulnerability report."
msgstr ""
+msgid "VulnerabilityManagement|Name is a required field"
+msgstr ""
+
msgid "VulnerabilityManagement|Needs triage"
msgstr ""
@@ -39874,6 +40684,18 @@ msgstr ""
msgid "VulnerabilityManagement|Select a method"
msgstr ""
+msgid "VulnerabilityManagement|Select a severity level"
+msgstr ""
+
+msgid "VulnerabilityManagement|Select a status"
+msgstr ""
+
+msgid "VulnerabilityManagement|Severity is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Something went wrong while creating vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -39898,6 +40720,12 @@ msgstr ""
msgid "VulnerabilityManagement|Something went wrong, could not update vulnerability state."
msgstr ""
+msgid "VulnerabilityManagement|Status is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Submit vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Summary, detailed description, steps to reproduce, etc."
msgstr ""
@@ -40093,6 +40921,9 @@ msgstr ""
msgid "WARNING:"
msgstr ""
+msgid "WARNING: This snippet contains hidden files which might be used to mask malicious behavior. Exercise caution if cloning and executing code from this snippet."
+msgstr ""
+
msgid "Wait for the file to load to copy its contents"
msgstr "Espera a que el archivo se cargue para copiar su contenido"
@@ -40312,6 +41143,15 @@ msgstr ""
msgid "Webhooks|An issue is created, updated, closed, or reopened."
msgstr ""
+msgid "Webhooks|Are you sure you want to delete this group hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this project hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this webhook?"
+msgstr ""
+
msgid "Webhooks|Comments"
msgstr "Comentarios"
@@ -40321,6 +41161,9 @@ msgstr "Comentarios confidenciales"
msgid "Webhooks|Confidential issues events"
msgstr "Eventos confidenciales"
+msgid "Webhooks|Delete webhook"
+msgstr ""
+
msgid "Webhooks|Deployment events"
msgstr "Eventos de despliegue"
@@ -40554,6 +41397,9 @@ msgstr ""
msgid "Wiki"
msgstr "Wiki"
+msgid "Wiki page"
+msgstr ""
+
msgid "Wiki page was successfully created."
msgstr "La página Wiki se ha creado con éxito."
@@ -40585,7 +41431,7 @@ msgid "WikiEmptyIssueMessage|You must be a group member in order to add wiki pag
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 "Debe ser un miembro del proyecto para poder agregar páginas al wiki. Si tiene sugerencias sobre cómo mejorar el wiki para este proyecto, considere abrir una incidencia en el enlace, %{issues_link}."
+msgstr "Debe ser un miembro del proyecto para poder añadir páginas al wiki. Si tiene sugerencias sobre cómo mejorar el wiki para este proyecto, considere abrir una incidencia en el enlace, %{issues_link}."
msgid "WikiEmptyIssueMessage|issue tracker"
msgstr "Gestor de incidencias"
@@ -40630,7 +41476,7 @@ 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 "Debe ser un miembro del proyecto para agregar páginas al wiki."
+msgstr "Debe ser un miembro del proyecto para añadir páginas al wiki."
msgid "WikiEmpty|You've enabled the Confluence Workspace integration. Your wiki will be viewable directly within Confluence. We are hard at work integrating Confluence more seamlessly into GitLab. If you'd like to stay up to date, follow our %{wiki_confluence_epic_link_start}Confluence epic%{wiki_confluence_epic_link_end}."
msgstr ""
@@ -40659,7 +41505,7 @@ msgstr "¿Desea eliminar la página %{pageTitle}?"
msgid "WikiPageConflictMessage|Someone edited the page the same time you did. Please check out %{wikiLinkStart}the page%{wikiLinkEnd} and make sure your changes will not unintentionally remove theirs."
msgstr ""
-msgid "WikiPage|An error occured while trying to render the content editor. Please try again later."
+msgid "WikiPage|An error occurred while trying to render the content editor. Please try again later."
msgstr ""
msgid "WikiPage|Are you sure you want to switch back to the classic editor?"
@@ -40818,6 +41664,18 @@ msgstr ""
msgid "WorkItem|New Task"
msgstr ""
+msgid "WorkItem|Something went wrong when creating a work item. Please try again"
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching the work item. Please try again."
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching work item types. Please try again"
+msgstr ""
+
+msgid "WorkItem|Type"
+msgstr ""
+
msgid "WorkItem|Work Items"
msgstr ""
@@ -40884,8 +41742,11 @@ msgstr "Ya tiene una tarea pendiente para esta alerta"
msgid "You are about to add %{usersTag} people to the discussion. They will all receive a notification."
msgstr "Está a punto de añadir %{usersTag} personas a la discusión. Todas ellas recibirán una notificación."
-msgid "You are about to permanently delete this project"
-msgstr "Está a punto de eliminar definitivamente este proyecto"
+msgid "You are about to delete this forked project containing:"
+msgstr ""
+
+msgid "You are about to delete this project containing:"
+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 "Está a punto de transferir el control de su cuenta al grupo %{group_name}. Esta acción NO es reversible, no podrá acceder a ninguno de sus grupos y proyectos fuera de %{group_name} una vez completada esta transferencia."
@@ -40905,6 +41766,9 @@ msgstr "Está intentando eliminar un archivo que ha sido actualizado previamente
msgid "You are attempting to update a file that has changed since you started editing it."
msgstr "Está intentando actualizar un archivo que ha sido modificado desde que comenzó a editarlo."
+msgid "You are billed if you exceed this number. %{qsrOverageLinkStart}How does billing work?%{qsrOverageLinkEnd}"
+msgstr ""
+
msgid "You are connected to the Prometheus server, but there is currently no data to display."
msgstr "Está conectado al servidor de Prometheus, pero actualmente no hay datos disponibles para mostrar."
@@ -40962,6 +41826,9 @@ msgstr ""
msgid "You are not authorized to update this scanner profile"
msgstr ""
+msgid "You are not authorized to upload metric images"
+msgstr ""
+
msgid "You are now impersonating %{username}"
msgstr "Está suplantando la identidad de %{username}"
@@ -41107,7 +41974,7 @@ msgid "You can only add up to %{max_contacts} contacts at one time"
msgstr ""
msgid "You can only edit files when you are on a branch"
-msgstr "Solo puede agregar archivos cuando está en una rama"
+msgstr "Solo puede añadir archivos cuando está en una rama"
msgid "You can only transfer the project to namespaces you manage."
msgstr "Solo puede transferir el proyecto a los espacios de nombres que administre."
@@ -41115,9 +41982,6 @@ msgstr "Solo puede transferir el proyecto a los espacios de nombres que administ
msgid "You can only upload one design when dropping onto an existing design."
msgstr ""
-msgid "You can recover this project until %{date}"
-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 "Puede resolver el conflicto del merge request utilizando el modo Interactivo, utilizando los botones %{use_ours} o %{use_theirs}, o editando los archivos directamente. Confirme estos cambios en %{branch_name}"
@@ -41166,9 +42030,6 @@ msgstr "No puedes escribir en una instancia secundaria de sólo lectura de GitLa
msgid "You cannot write to this read-only GitLab instance."
msgstr "No puede escribir en esta instancia de sólo lectura de GitLab."
-msgid "You can’t %{tag_start}edit%{tag_end} files directly in this project. Fork this project and submit a merge request with your changes."
-msgstr ""
-
msgid "You can’t edit files directly in this project. Fork this project and submit a merge request with your changes."
msgstr ""
@@ -41321,9 +42182,6 @@ msgstr "No tiene permisos"
msgid "You have not added any approvers. Start by adding users or groups."
msgstr "No ha añadido aprobadores. Empiece por añadir usuarios o grupos."
-msgid "You have reached your project limit"
-msgstr "Has alcanzado el límite de tu proyecto"
-
msgid "You have set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
@@ -41354,12 +42212,6 @@ msgstr ""
msgid "You must have maintainer access to force delete a lock"
msgstr "Debe tener permiso como mantenedor para forzar la eliminación de un bloqueo"
-msgid "You must have permission to create a project in a group before forking."
-msgstr ""
-
-msgid "You must have permission to create a project in a namespace before forking."
-msgstr "Debe tener permiso para crear un proyecto en un espacio de nombres antes de realizar fork."
-
msgid "You must provide a valid current password"
msgstr "Debe proporcionar una contraseña válida"
@@ -41765,7 +42617,7 @@ msgstr "Tus proyectos"
msgid "Your public email will be displayed on your public profile."
msgstr ""
-msgid "Your request for access could not be processed: %{error_meesage}"
+msgid "Your request for access could not be processed: %{error_message}"
msgstr ""
msgid "Your request for access has been queued for review."
@@ -41948,6 +42800,9 @@ msgstr "archivado"
msgid "archived:"
msgstr ""
+msgid "artifacts"
+msgstr ""
+
msgid "assign yourself"
msgstr "asignar a ti mismo"
@@ -41977,6 +42832,9 @@ msgstr[1] ""
msgid "branch name"
msgstr "nombre de la rama"
+msgid "builds"
+msgstr ""
+
msgid "by"
msgstr "por"
@@ -42400,6 +43258,9 @@ msgstr ""
msgid "contact with same email already exists in group hierarchy"
msgstr ""
+msgid "container registry images"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -42439,6 +43300,9 @@ msgstr ""
msgid "data"
msgstr "dato"
+msgid "database"
+msgstr ""
+
msgid "date must not be after 9999-12-31"
msgstr "la fecha no puede ser superior a 9999-12-31"
@@ -42462,9 +43326,6 @@ msgstr "desplegar"
msgid "design"
msgstr "diseño"
-msgid "detached"
-msgstr "Desvinculado"
-
msgid "disabled"
msgstr "deshabilitado"
@@ -42713,7 +43574,7 @@ msgstr "no es un descendiente del grupo que es propietario de la plantilla"
msgid "is not a valid X509 certificate."
msgstr "no es un certificado X509 válido."
-msgid "is not allowed for sign-up."
+msgid "is not allowed for sign-up. Please use your regular email address."
msgstr ""
msgid "is not allowed for this group."
@@ -42725,7 +43586,7 @@ msgstr ""
msgid "is not allowed since the group is not top-level group."
msgstr ""
-msgid "is not allowed."
+msgid "is not allowed. Please use your regular email address."
msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
@@ -42812,6 +43673,9 @@ msgstr "hace menos de un minuto"
msgid "level: %{level}"
msgstr "nivel %{level}"
+msgid "lfs objects"
+msgstr ""
+
msgid "limit of %{project_limit} reached"
msgstr "límite de %{project_limit} alcanzado"
@@ -43031,6 +43895,9 @@ msgstr ""
msgid "mrWidget|Merge blocked: pipeline must succeed. It's waiting for a manual action to continue."
msgstr ""
+msgid "mrWidget|Merge blocked: pipeline must succeed. Push a commit that fixes the failure, or %{linkStart}learn about other solutions.%{linkEnd}"
+msgstr ""
+
msgid "mrWidget|Merge blocked: this merge request must be approved."
msgstr ""
@@ -43148,9 +44015,6 @@ msgstr "Los cambios se fusionaron en"
msgid "mrWidget|The changes were not merged into"
msgstr "Los cambios no se fusionaron en"
-msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr "Se ha eliminado el branch de origen"
@@ -43298,9 +44162,6 @@ msgstr ""
msgid "open issue"
msgstr "incidencia abierta"
-msgid "opened %{timeAgo}"
-msgstr "abierto %{timeAgo}"
-
msgid "or"
msgstr "o"
@@ -43312,6 +44173,12 @@ msgid_plural "out of %d total tests"
msgstr[0] "total de %d prueba"
msgstr[1] "totales de %d pruebas"
+msgid "packages"
+msgstr ""
+
+msgid "pages"
+msgstr ""
+
msgid "parent"
msgid_plural "parents"
msgstr[0] "padre"
@@ -43461,6 +44328,9 @@ msgid_plural "replies"
msgstr[0] "respuesta"
msgstr[1] "respuestas"
+msgid "repositories"
+msgstr ""
+
msgid "repository:"
msgstr "repositorio:"
@@ -43581,12 +44451,18 @@ msgstr ""
msgid "tag name"
msgstr "nombre de la etiqueta"
+msgid "terraform states"
+msgstr ""
+
msgid "the correct format."
msgstr ""
msgid "the file"
msgstr "el archivo"
+msgid "the following epic(s)"
+msgstr ""
+
msgid "the following issue(s)"
msgstr "la siguiente incidencia(s)"
@@ -43599,21 +44475,12 @@ msgstr ""
msgid "this document"
msgstr "este documento"
-msgid "this issue cannot be assigned to a confidential epic since it is public"
-msgstr ""
-
-msgid "this issue cannot be made public since it belongs to a confidential epic"
-msgstr ""
-
msgid "time summary"
msgstr ""
msgid "toggle collapse"
msgstr "Colapsar/Expandir"
-msgid "train"
-msgstr ""
-
msgid "triggered"
msgstr "disparado"
@@ -43695,7 +44562,7 @@ msgid "vulnerability|Add a comment or reason for dismissal"
msgstr "Añadir un comentario o motivo para el descarte"
msgid "vulnerability|Add comment"
-msgstr "Agregar un comentario"
+msgstr "Añadir un comentario"
msgid "vulnerability|Add comment & dismiss"
msgstr "Añadir comentario y descartar"
@@ -43742,3 +44609,6 @@ msgstr "{group}"
msgid "{project}"
msgstr ""
+msgid "✔"
+msgstr ""
+
diff --git a/locale/et_EE/gitlab.po b/locale/et_EE/gitlab.po
index 04a99950930..7fbd7c9ef5b 100644
--- a/locale/et_EE/gitlab.po
+++ b/locale/et_EE/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: et\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2022-02-02 15:43\n"
+"PO-Revision-Date: 2022-03-01 20:37\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -146,6 +146,11 @@ msgid_plural "%d approvers (you've approved)"
msgstr[0] ""
msgstr[1] ""
+msgid "%d assigned issue"
+msgid_plural "%d assigned issues"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -421,8 +426,23 @@ msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
msgstr[1] ""
-msgid "%d vulnerability updated"
-msgid_plural "%d vulnerabilities updated"
+msgid "%d vulnerability set to confirmed"
+msgid_plural "%d vulnerabilities set to confirmed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to dismissed"
+msgid_plural "%d vulnerabilities set to dismissed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to needs triage"
+msgid_plural "%d vulnerabilities set to needs triage"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to resolved"
+msgid_plural "%d vulnerabilities set to resolved"
msgstr[0] ""
msgstr[1] ""
@@ -510,6 +530,12 @@ msgstr[1] ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{completed} of %{total} issues closed"
+msgstr ""
+
+msgid "%{completed} of %{total} weight completed"
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -858,6 +884,9 @@ msgstr ""
msgid "%{openedIssues} open, %{closedIssues} closed"
msgstr ""
+msgid "%{percentage}%% issues closed"
+msgstr ""
+
msgid "%{percentage}%% weight completed"
msgstr ""
@@ -1287,6 +1316,9 @@ msgid_plural "- Users"
msgstr[0] ""
msgstr[1] ""
+msgid "- of - issues closed"
+msgstr ""
+
msgid "- of - weight completed"
msgstr ""
@@ -1429,7 +1461,7 @@ msgstr ""
msgid "1000+"
msgstr ""
-msgid "192.168.0.0/24"
+msgid "192.168.0.0/24 or 2001:0DB8:1234::/48"
msgstr ""
msgid "1st contribution!"
@@ -1741,13 +1773,13 @@ msgstr ""
msgid "AWS Access Key"
msgstr ""
-msgid "AWS Access Key. Only required if not using role instance credentials"
+msgid "AWS Secret Access Key"
msgstr ""
-msgid "AWS Secret Access Key"
+msgid "AWS access key ID (Optional)"
msgstr ""
-msgid "AWS Secret Access Key. Only required if not using role instance credentials"
+msgid "AWS secret access key (Optional)"
msgstr ""
msgid "AWS service error: %{error}"
@@ -1807,9 +1839,6 @@ msgstr ""
msgid "Access granted"
msgstr ""
-msgid "Access key ID"
-msgstr ""
-
msgid "Access requests"
msgstr ""
@@ -1984,7 +2013,7 @@ msgstr ""
msgid "Activity"
msgstr ""
-msgid "Activity|An error occured while retrieving activity. Reload the page to try again."
+msgid "Activity|An error occurred while retrieving activity. Reload the page to try again."
msgstr ""
msgid "Add"
@@ -2023,6 +2052,9 @@ msgstr ""
msgid "Add a %{type}"
msgstr ""
+msgid "Add a GCP region"
+msgstr ""
+
msgid "Add a GPG key"
msgstr ""
@@ -2074,6 +2106,9 @@ msgstr ""
msgid "Add a numbered list"
msgstr ""
+msgid "Add a related epic"
+msgstr ""
+
msgid "Add a related issue"
msgstr ""
@@ -2188,6 +2223,9 @@ msgstr ""
msgid "Add or subtract spent time"
msgstr ""
+msgid "Add people"
+msgstr ""
+
msgid "Add previously merged commits"
msgstr ""
@@ -2254,6 +2292,9 @@ msgstr ""
msgid "Add webhook"
msgstr ""
+msgid "Add your team members and others to GitLab."
+msgstr ""
+
msgid "Add/remove"
msgstr ""
@@ -3076,12 +3117,6 @@ msgstr ""
msgid "AdvancedSearch|Reindex required"
msgstr ""
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. Permanently deleting this project will %{strongStart}immediately delete%{strongEnd} its repositories and %{strongStart}all related resources%{strongEnd}, including issues, merge requests etc."
-msgstr ""
-
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. You will lose this project's repository and %{strongStart}all related resources%{strongEnd}, including issues and merge requests."
-msgstr ""
-
msgid "After a successful password update you will be redirected to login screen."
msgstr ""
@@ -3112,6 +3147,9 @@ msgstr ""
msgid "Akismet helps prevent the creation of spam issues in public projects."
msgstr ""
+msgid "Alert"
+msgstr ""
+
msgid "AlertManagement|Acknowledged"
msgstr ""
@@ -3484,9 +3522,6 @@ msgstr ""
msgid "All environments"
msgstr ""
-msgid "All epics"
-msgstr ""
-
msgid "All groups and projects"
msgstr ""
@@ -4223,12 +4258,15 @@ msgstr ""
msgid "ApplicationSettings|Approve users in the pending approval status?"
msgstr ""
-msgid "ApplicationSettings|By making this change, you will automatically approve %d user with the pending approval status."
-msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users with the pending approval status."
+msgid "ApplicationSettings|Approve users who are pending approval?"
+msgstr ""
+
+msgid "ApplicationSettings|By making this change, you will automatically approve %d user who is pending approval."
+msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users who are pending approval."
msgstr[0] ""
msgstr[1] ""
-msgid "ApplicationSettings|By making this change, you will automatically approve all users in pending approval status."
+msgid "ApplicationSettings|By making this change, you will automatically approve all users who are pending approval."
msgstr ""
msgid "ApplicationSettings|Denied domains for sign-ups"
@@ -4634,10 +4672,10 @@ msgstr ""
msgid "Archiving the project will make it entirely read-only. It is hidden from the dashboard and doesn't show up in searches. %{strong_start}The repository cannot be committed to, and no issues, comments, or other entities can be created.%{strong_end} %{link_start}Learn more.%{link_end}"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to delete this project?"
+msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
+msgid "Are you absolutely sure?"
msgstr ""
msgid "Are you sure that you want to archive this project?"
@@ -4673,12 +4711,18 @@ msgstr ""
msgid "Are you sure you want to delete this SSH key?"
msgstr ""
+msgid "Are you sure you want to delete this comment?"
+msgstr ""
+
msgid "Are you sure you want to delete this deploy key?"
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 label?"
+msgstr ""
+
msgid "Are you sure you want to delete this pipeline schedule?"
msgstr ""
@@ -4694,9 +4738,6 @@ msgstr ""
msgid "Are you sure you want to discard your changes?"
msgstr ""
-msgid "Are you sure you want to erase this build?"
-msgstr ""
-
msgid "Are you sure you want to import %d repository?"
msgid_plural "Are you sure you want to import %d repositories?"
msgstr[0] ""
@@ -4744,6 +4785,9 @@ msgstr ""
msgid "Are you sure you want to remove this list?"
msgstr ""
+msgid "Are you sure you want to remove this nickname?"
+msgstr ""
+
msgid "Are you sure you want to reset the health check token?"
msgstr ""
@@ -4756,10 +4800,10 @@ 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?"
+msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
msgstr ""
-msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
+msgid "Are you sure you want to revoke this project access token? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to stop this environment?"
@@ -4906,9 +4950,6 @@ msgstr ""
msgid "Assigned to %{assignee_name}"
msgstr ""
-msgid "Assigned to %{name}"
-msgstr ""
-
msgid "Assigned to me"
msgstr ""
@@ -4973,6 +5014,9 @@ msgstr[1] ""
msgid "Attaching the file failed."
msgstr ""
+msgid "Attention"
+msgstr ""
+
msgid "Audit Events"
msgstr ""
@@ -5135,6 +5179,12 @@ msgstr ""
msgid "Authorized applications (%{size})"
msgstr ""
+msgid "AuthorizedApplication|Are you sure you want to revoke this application?"
+msgstr ""
+
+msgid "AuthorizedApplication|Revoke application"
+msgstr ""
+
msgid "Authors: %{authors}"
msgstr ""
@@ -6328,6 +6378,9 @@ msgstr ""
msgid "CICDAnalytics|Shared Runners Usage"
msgstr ""
+msgid "CICDAnalytics|Shared runner pipeline minute duration by month"
+msgstr ""
+
msgid "CICDAnalytics|Shared runner usage"
msgstr ""
@@ -6469,6 +6522,9 @@ msgstr ""
msgid "Can create groups:"
msgstr ""
+msgid "Can not delete primary training"
+msgstr ""
+
msgid "Can't apply as the source branch was deleted."
msgstr ""
@@ -6802,9 +6858,6 @@ msgstr ""
msgid "Changing any setting here requires an application restart"
msgstr ""
-msgid "Changing group URL can have unintended side effects."
-msgstr ""
-
msgid "Charts can't be displayed as the request for data has timed out. %{documentationLink}"
msgstr ""
@@ -6892,9 +6945,6 @@ msgstr ""
msgid "Checking branch availability..."
msgstr ""
-msgid "Checking group URL availability..."
-msgstr ""
-
msgid "Checking group path availability..."
msgstr ""
@@ -7388,6 +7438,9 @@ msgstr ""
msgid "Clear recent searches"
msgstr ""
+msgid "Clear repository checks"
+msgstr ""
+
msgid "Clear search"
msgstr ""
@@ -7520,9 +7573,6 @@ msgstr ""
msgid "Closed MRs"
msgstr ""
-msgid "Closed epics"
-msgstr ""
-
msgid "Closed issues"
msgstr ""
@@ -7559,13 +7609,13 @@ msgstr ""
msgid "Cluster level"
msgstr ""
-msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
+msgid "Cluster type must be specified for Stages::ClusterEndpointInserter"
msgstr ""
msgid "ClusterAgents|%{name} successfully deleted"
msgstr ""
-msgid "ClusterAgents|%{number} of %{total} Agents"
+msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
@@ -7607,6 +7657,15 @@ msgstr ""
msgid "ClusterAgents|Agent never connected to GitLab"
msgstr ""
+msgid "ClusterAgents|Agent version mismatch"
+msgstr ""
+
+msgid "ClusterAgents|Agent version mismatch and update"
+msgstr ""
+
+msgid "ClusterAgents|Agent version update required"
+msgstr ""
+
msgid "ClusterAgents|All"
msgstr ""
@@ -7631,7 +7690,7 @@ msgstr ""
msgid "ClusterAgents|Configuration"
msgstr ""
-msgid "ClusterAgents|Connect a cluster through the Agent"
+msgid "ClusterAgents|Connect a cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connect existing cluster"
@@ -7640,13 +7699,13 @@ msgstr ""
msgid "ClusterAgents|Connect with a certificate"
msgstr ""
-msgid "ClusterAgents|Connect with agent"
+msgid "ClusterAgents|Connect with an agent"
msgstr ""
msgid "ClusterAgents|Connect with the GitLab Agent"
msgstr ""
-msgid "ClusterAgents|Connect your cluster through the Agent"
+msgid "ClusterAgents|Connect your cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connected"
@@ -7706,7 +7765,10 @@ msgstr ""
msgid "ClusterAgents|How to register an agent?"
msgstr ""
-msgid "ClusterAgents|Install new Agent"
+msgid "ClusterAgents|How to update an agent?"
+msgstr ""
+
+msgid "ClusterAgents|Install a new agent"
msgstr ""
msgid "ClusterAgents|Last connected %{timeAgo}."
@@ -7733,7 +7795,7 @@ msgstr ""
msgid "ClusterAgents|Never connected"
msgstr ""
-msgid "ClusterAgents|No Agents"
+msgid "ClusterAgents|No agents"
msgstr ""
msgid "ClusterAgents|No clusters connected through cluster certificates"
@@ -7793,6 +7855,9 @@ msgstr ""
msgid "ClusterAgents|The agent has not been connected in a long time. There might be a connectivity issue. Last contact was %{timeAgo}."
msgstr ""
+msgid "ClusterAgents|The agent version do not match each other across your cluster's pods. This can happen when a new agent version was just deployed and Kubernetes is shutting down the old pods."
+msgstr ""
+
msgid "ClusterAgents|The recommended installation method includes the token. If you want to follow the advanced installation method provided in the docs, make sure you save the token value before you close this window."
msgstr ""
@@ -7840,6 +7905,9 @@ msgstr ""
msgid "ClusterAgents|You will need to create a token to connect to your agent"
msgstr ""
+msgid "ClusterAgents|Your agent version is out of sync with your GitLab version (v%{version}), which might cause compatibility problems. Update the agent installed on your cluster to the most recent version."
+msgstr ""
+
msgid "ClusterAgents|Your instance doesn't have the %{linkStart}GitLab Agent Server (KAS)%{linkEnd} set up. Ask a GitLab Administrator to install it."
msgstr ""
@@ -8716,9 +8784,6 @@ msgstr ""
msgid "Comma-separated list of email addresses."
msgstr ""
-msgid "Comma-separated list of users allowed to exceed the rate limit."
-msgstr ""
-
msgid "Comma-separated, e.g. '1.1.1.1, 2.2.2.0/24'"
msgstr ""
@@ -9045,6 +9110,12 @@ msgstr ""
msgid "Confidential"
msgstr ""
+msgid "Confidential issue"
+msgstr ""
+
+msgid "Confidential note"
+msgstr ""
+
msgid "Confidentiality"
msgstr ""
@@ -9078,6 +9149,9 @@ msgstr ""
msgid "Configure Dependency Scanning in `.gitlab-ci.yml`, creating this file if it does not already exist"
msgstr ""
+msgid "Configure GitLab"
+msgstr ""
+
msgid "Configure GitLab runners to start using the Web Terminal. %{helpStart}Learn more.%{helpEnd}"
msgstr ""
@@ -9126,6 +9200,15 @@ msgstr ""
msgid "Configure pipelines to deploy web apps, backend services, APIs and static resources to Google Cloud"
msgstr ""
+msgid "Configure region"
+msgstr ""
+
+msgid "Configure region for environment"
+msgstr ""
+
+msgid "Configure regions"
+msgstr ""
+
msgid "Configure repository mirroring."
msgstr ""
@@ -9159,6 +9242,9 @@ msgstr ""
msgid "Configure which lists are shown for anyone who visits this board"
msgstr ""
+msgid "Configure your environments to be deployed to specific geographical regions"
+msgstr ""
+
msgid "Confirm"
msgstr ""
@@ -9861,10 +9947,10 @@ msgstr ""
msgid "CorpusManagement|Actions"
msgstr ""
-msgid "CorpusManagement|Corpus are used in fuzz testing as mutation source to Improve future testing."
+msgid "CorpusManagement|Corpus file"
msgstr ""
-msgid "CorpusManagement|Corpus file"
+msgid "CorpusManagement|Corpus files are used in coverage-guided fuzz testing as seed inputs to improve testing."
msgstr ""
msgid "CorpusManagement|Corpus files must be in *.zip format. Maximum 5 GB"
@@ -9918,6 +10004,9 @@ msgstr ""
msgid "Could not apply %{name} command."
msgstr ""
+msgid "Could not apply %{name} command. %{message}."
+msgstr ""
+
msgid "Could not authorize chat nickname. Try again!"
msgstr ""
@@ -10068,6 +10157,9 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
+msgid "Create a group"
+msgstr ""
+
msgid "Create a merge request"
msgstr ""
@@ -10092,6 +10184,9 @@ msgstr ""
msgid "Create a personal access token on your account to pull or push via %{protocol}."
msgstr ""
+msgid "Create a project"
+msgstr ""
+
msgid "Create an account using:"
msgstr ""
@@ -10455,6 +10550,9 @@ msgstr ""
msgid "Creation date"
msgstr ""
+msgid "Creator"
+msgstr ""
+
msgid "Credentials"
msgstr ""
@@ -10467,9 +10565,15 @@ msgstr ""
msgid "CredentialsInventory|Personal Access Tokens"
msgstr ""
+msgid "CredentialsInventory|Project Access Tokens"
+msgstr ""
+
msgid "CredentialsInventory|SSH Keys"
msgstr ""
+msgid "Credit card required to be on file in order to create a pipeline"
+msgstr ""
+
msgid "Credit card:"
msgstr ""
@@ -10653,9 +10757,6 @@ msgstr ""
msgid "Customer relations"
msgstr ""
-msgid "Customizable by an administrator."
-msgstr ""
-
msgid "Customizable by owners."
msgstr ""
@@ -10785,30 +10886,18 @@ msgstr ""
msgid "CycleAnalytics|%{selectedLabelsCount} selected (%{maxLabels} max)"
msgstr ""
-msgid "CycleAnalytics|%{stageCount} stages selected"
-msgstr ""
-
-msgid "CycleAnalytics|All stages"
-msgstr ""
-
-msgid "CycleAnalytics|Average days to completion"
+msgid "CycleAnalytics|Average time to completion"
msgstr ""
msgid "CycleAnalytics|Date"
msgstr ""
-msgid "CycleAnalytics|Days to completion"
-msgstr ""
-
msgid "CycleAnalytics|Display chart filters"
msgstr ""
msgid "CycleAnalytics|Lead Time for Changes"
msgstr ""
-msgid "CycleAnalytics|No stages selected"
-msgstr ""
-
msgid "CycleAnalytics|Number of tasks"
msgstr ""
@@ -10837,18 +10926,30 @@ msgstr ""
msgid "CycleAnalytics|Showing data for group '%{groupName}' from %{createdAfter} to %{createdBefore}"
msgstr ""
-msgid "CycleAnalytics|Stages"
+msgid "CycleAnalytics|Stage time: %{title}"
msgstr ""
msgid "CycleAnalytics|Tasks by type"
msgstr ""
-msgid "CycleAnalytics|The average time spent in the selected stage for the items that were completed on each date. Data limited to the last 500 items."
+msgid "CycleAnalytics|The average time items spent in this stage. Data limited to items completed within this date range."
msgstr ""
msgid "CycleAnalytics|The given date range is larger than 180 days"
msgstr ""
+msgid "CycleAnalytics|The total time items spent across each value stream stage. Data limited to items completed within this date range."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Stage time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Total time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|Total time"
+msgstr ""
+
msgid "CycleAnalytics|Type of work"
msgstr ""
@@ -10861,9 +10962,6 @@ msgstr ""
msgid "CycleAnalytics|project dropdown filter"
msgstr ""
-msgid "CycleAnalytics|stage dropdown"
-msgstr ""
-
msgid "DAG visualization requires at least 3 dependent jobs."
msgstr ""
@@ -10963,10 +11061,16 @@ msgstr ""
msgid "DastProfiles|AJAX spider"
msgstr ""
+msgid "DastProfiles|API"
+msgstr ""
+
+msgid "DastProfiles|API endpoint URL"
+msgstr ""
+
msgid "DastProfiles|Active"
msgstr ""
-msgid "DastProfiles|Additional request headers (Optional)"
+msgid "DastProfiles|Additional request headers (optional)"
msgstr ""
msgid "DastProfiles|Are you sure you want to delete this profile?"
@@ -10981,6 +11085,9 @@ msgstr ""
msgid "DastProfiles|Branch missing"
msgstr ""
+msgid "DastProfiles|Choose a scan method"
+msgstr ""
+
msgid "DastProfiles|Could not create the scanner profile. Please try again."
msgstr ""
@@ -11050,7 +11157,13 @@ msgstr ""
msgid "DastProfiles|Excluded URLs"
msgstr ""
-msgid "DastProfiles|Excluded URLs (Optional)"
+msgid "DastProfiles|Excluded URLs (optional)"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths (optional)"
msgstr ""
msgid "DastProfiles|Hide debug messages"
@@ -11107,9 +11220,6 @@ msgstr ""
msgid "DastProfiles|Request headers"
msgstr ""
-msgid "DastProfiles|Rest API"
-msgstr ""
-
msgid "DastProfiles|Run the AJAX spider, in addition to the traditional spider, to crawl the target site."
msgstr ""
@@ -11119,6 +11229,9 @@ msgstr ""
msgid "DastProfiles|Save profile"
msgstr ""
+msgid "DastProfiles|Scan method"
+msgstr ""
+
msgid "DastProfiles|Scan mode"
msgstr ""
@@ -11197,12 +11310,24 @@ msgstr ""
msgid "DastProfiles|Website"
msgstr ""
+msgid "DastProfiles|What does each method do?"
+msgstr ""
+
msgid "DastProfiles|You can either choose a passive scan or validate the target site from the site profile management page. %{docsLinkStart}Learn more about site validation.%{docsLinkEnd}"
msgstr ""
msgid "DastProfiles|You cannot run an active scan against an unvalidated site."
msgstr ""
+msgid "DastProfiles|folder/dast_example.har or https://example.com/dast_example.har"
+msgstr ""
+
+msgid "DastProfiles|folder/example.postman_collection.json or https://example.com/"
+msgstr ""
+
+msgid "DastProfiles|folder/openapi.json or https://example.com/openapi.json"
+msgstr ""
+
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
@@ -11310,6 +11435,9 @@ msgstr ""
msgid "DatadogIntegration|API URL"
msgstr ""
+msgid "DatadogIntegration|Custom tags in Datadog. Enter one tag per line in the %{codeOpen}key:value%{codeClose} format. %{linkOpen}How do I use tags?%{linkClose}"
+msgstr ""
+
msgid "DatadogIntegration|Environment"
msgstr ""
@@ -11328,12 +11456,18 @@ msgstr ""
msgid "DatadogIntegration|Tag all data from this GitLab instance in Datadog. Useful when managing several self-managed deployments."
msgstr ""
+msgid "DatadogIntegration|Tags"
+msgstr ""
+
msgid "DatadogIntegration|The Datadog site to send data to. To send data to the EU site, use %{codeOpen}datadoghq.eu%{codeClose}."
msgstr ""
msgid "DatadogIntegration|Trace your GitLab pipelines with Datadog."
msgstr ""
+msgid "DatadogIntegration|have an invalid format"
+msgstr ""
+
msgid "Datasource name not found"
msgstr ""
@@ -11343,9 +11477,6 @@ msgstr ""
msgid "Date merged"
msgstr ""
-msgid "Date picker"
-msgstr ""
-
msgid "Date range"
msgstr ""
@@ -11499,9 +11630,6 @@ msgstr ""
msgid "Definition"
msgstr ""
-msgid "Delayed Project Deletion (%{adjourned_deletion})"
-msgstr ""
-
msgid "DelayedJobs|Are you sure you want to run %{jobName} immediately? Otherwise this job will run automatically after its timer finishes."
msgstr ""
@@ -11580,10 +11708,10 @@ msgstr ""
msgid "Delete pipeline"
msgstr ""
-msgid "Delete project"
+msgid "Delete pipeline schedule"
msgstr ""
-msgid "Delete project. Are you ABSOLUTELY SURE?"
+msgid "Delete project"
msgstr ""
msgid "Delete row"
@@ -11613,6 +11741,9 @@ msgstr ""
msgid "Delete this epic and all descendants?"
msgstr ""
+msgid "Delete this project"
+msgstr ""
+
msgid "Delete user list"
msgstr ""
@@ -11871,6 +12002,12 @@ msgstr ""
msgid "Deploy to..."
msgstr ""
+msgid "DeployBoards|To see deployment progress for your environments, make sure you are deploying to %{codeStart}$KUBE_NAMESPACE%{codeEnd} and annotating with %{codeStart}app.gitlab.com/app=$CI_PROJECT_PATH_SLUG%{codeEnd} and %{codeStart}app.gitlab.com/env=$CI_ENVIRONMENT_SLUG%{codeEnd}."
+msgstr ""
+
+msgid "DeployBoard|Kubernetes Pods"
+msgstr ""
+
msgid "DeployFreeze|Add a freeze period to prevent unintended releases during a period of time for a given environment. You must update the deployment jobs in %{filename} according to the deploy freezes added here. %{freeze_period_link_start}Learn more.%{freeze_period_link_end}"
msgstr ""
@@ -11955,9 +12092,6 @@ msgstr ""
msgid "DeployTokens|Active Deploy Tokens (%{active_tokens})"
msgstr ""
-msgid "DeployTokens|Allows read and write access to registry images."
-msgstr ""
-
msgid "DeployTokens|Allows read and write access to the package registry."
msgstr ""
@@ -11970,6 +12104,9 @@ msgstr ""
msgid "DeployTokens|Allows read-only access to the repository."
msgstr ""
+msgid "DeployTokens|Allows write access to registry images."
+msgstr ""
+
msgid "DeployTokens|Copy deploy token"
msgstr ""
@@ -12063,12 +12200,57 @@ msgstr ""
msgid "Deploying to AWS is easy with GitLab"
msgstr ""
+msgid "Deployment"
+msgstr ""
+
msgid "Deployment Frequency"
msgstr ""
+msgid "Deployment Target|Project deployment target (optional)"
+msgstr ""
+
+msgid "Deployment Target|Select the deployment target"
+msgstr ""
+
msgid "Deployment frequency"
msgstr ""
+msgid "DeploymentTarget|GitLab Pages"
+msgstr ""
+
+msgid "DeploymentTarget|Heroku"
+msgstr ""
+
+msgid "DeploymentTarget|Infrastructure provider (Terraform, Cloudformation, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Kubernetes (GKE, EKS, OpenShift, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Managed container runtime (Fargate, Cloud Run, DigitalOcean App)"
+msgstr ""
+
+msgid "DeploymentTarget|Mobile app store"
+msgstr ""
+
+msgid "DeploymentTarget|No deployment planned"
+msgstr ""
+
+msgid "DeploymentTarget|Other hosting service"
+msgstr ""
+
+msgid "DeploymentTarget|Registry (package or container)"
+msgstr ""
+
+msgid "DeploymentTarget|Self-managed container runtime (Podman, Docker Swarm, Docker Compose)"
+msgstr ""
+
+msgid "DeploymentTarget|Serverless backend (Lambda, Cloud functions)"
+msgstr ""
+
+msgid "DeploymentTarget|Virtual machine (for example, EC2)"
+msgstr ""
+
msgid "Deployments"
msgstr ""
@@ -12107,6 +12289,9 @@ msgstr ""
msgid "Deployment|This deployment was created using the API"
msgstr ""
+msgid "Deployment|Triggerer"
+msgstr ""
+
msgid "Deployment|Waiting"
msgstr ""
@@ -12134,6 +12319,18 @@ msgstr ""
msgid "Deprecated API rate limits"
msgstr ""
+msgid "Deprecations|Feature deprecation and removal"
+msgstr ""
+
+msgid "Deprecations|For information on a possible replacement %{epicStart} learn more about Opstrace %{epicEnd}."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7 and are %{epicStart} scheduled for removal %{epicEnd} in GitLab 15.0."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7, and are %{removal_link_start} scheduled for removal %{link_end} in GitLab 15.0. For information on a possible replacement, %{opstrace_link_start} learn more about Opstrace %{link_end}."
+msgstr ""
+
msgid "Deprioritize label"
msgstr ""
@@ -12379,10 +12576,10 @@ msgstr ""
msgid "DevopsAdoption|At least one deploy"
msgstr ""
-msgid "DevopsAdoption|At least one issue opened"
+msgid "DevopsAdoption|At least one issue created"
msgstr ""
-msgid "DevopsAdoption|At least one merge request opened"
+msgid "DevopsAdoption|At least one merge request created"
msgstr ""
msgid "DevopsAdoption|At least one pipeline successfully run"
@@ -12583,6 +12780,9 @@ msgstr ""
msgid "Direct member"
msgstr ""
+msgid "Direct members"
+msgstr ""
+
msgid "Direct non-authenticated users to this page."
msgstr ""
@@ -12699,6 +12899,9 @@ msgid_plural "Dismiss %d selected vulnerabilities as"
msgstr[0] ""
msgstr[1] ""
+msgid "Dismiss Alert"
+msgstr ""
+
msgid "Dismiss merge request promotion"
msgstr ""
@@ -12726,9 +12929,15 @@ msgstr ""
msgid "Display alerts from all configured monitoring tools."
msgstr ""
+msgid "Display milestones"
+msgstr ""
+
msgid "Display name"
msgstr ""
+msgid "Display progress of child issues"
+msgstr ""
+
msgid "Display rendered file"
msgstr ""
@@ -12834,6 +13043,9 @@ msgstr ""
msgid "Download image"
msgstr ""
+msgid "Download payload"
+msgstr ""
+
msgid "Download raw data (.csv)"
msgstr ""
@@ -13011,6 +13223,9 @@ msgstr ""
msgid "Edit in Web IDE"
msgstr ""
+msgid "Edit in pipeline editor"
+msgstr ""
+
msgid "Edit in single-file editor"
msgstr ""
@@ -13053,6 +13268,9 @@ msgstr ""
msgid "Edit your most recent comment in a thread (from an empty textarea)"
msgstr ""
+msgid "Edit, lint, and visualize your pipeline."
+msgstr ""
+
msgid "Edited"
msgstr ""
@@ -13494,6 +13712,9 @@ msgstr ""
msgid "Enforce two-factor authentication for all user sign-ins."
msgstr ""
+msgid "Enhance security by storing service account keys in secret managers - learn more about %{docLinkStart}secret management with GitLab%{docLinkEnd}"
+msgstr ""
+
msgid "Ensure connectivity is available from the GitLab server to the Prometheus server"
msgstr ""
@@ -13554,6 +13775,9 @@ 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 following to confirm:"
+msgstr ""
+
msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
@@ -14084,9 +14308,6 @@ 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 ""
@@ -14222,6 +14443,9 @@ msgstr ""
msgid "Errors:"
msgstr ""
+msgid "Escalate this incident"
+msgstr ""
+
msgid "Escalation Policies"
msgstr ""
@@ -14234,6 +14458,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy"
+msgstr ""
+
msgid "Escalation policy:"
msgstr ""
@@ -14485,6 +14712,9 @@ msgstr ""
msgid "Existing sign in methods may be removed"
msgstr ""
+msgid "Exit."
+msgstr ""
+
msgid "Expand"
msgstr ""
@@ -14581,6 +14811,9 @@ msgstr ""
msgid "Explore public groups"
msgstr ""
+msgid "Explore public projects"
+msgstr ""
+
msgid "Explore snippets"
msgstr ""
@@ -14742,7 +14975,7 @@ msgid_plural "Failed to archive designs. Please try again."
msgstr[0] ""
msgstr[1] ""
-msgid "Failed to assign a reviewer because no user was found."
+msgid "Failed to assign a reviewer because no user was specified."
msgstr ""
msgid "Failed to assign a user because no user was found."
@@ -14808,10 +15041,10 @@ msgstr ""
msgid "Failed to find import label for Jira import."
msgstr ""
-msgid "Failed to generate export, please try again later."
+msgid "Failed to find users for %{missing}"
msgstr ""
-msgid "Failed to generate report, please try again after sometime"
+msgid "Failed to generate export, please try again later."
msgstr ""
msgid "Failed to get ref."
@@ -14910,6 +15143,9 @@ msgstr ""
msgid "Failed to remove a to-do item for the design."
msgstr ""
+msgid "Failed to remove attention because no user was found."
+msgstr ""
+
msgid "Failed to remove mirror."
msgstr ""
@@ -14922,6 +15158,9 @@ msgstr ""
msgid "Failed to remove user key."
msgstr ""
+msgid "Failed to request attention because no user was found."
+msgstr ""
+
msgid "Failed to reset key. Please try again."
msgstr ""
@@ -15003,6 +15242,9 @@ msgstr ""
msgid "Feature Flags"
msgstr ""
+msgid "Feature deprecation and removal"
+msgstr ""
+
msgid "Feature flag status"
msgstr ""
@@ -15500,7 +15742,7 @@ msgstr ""
msgid "For each job, re-use the project workspace. If the workspace doesn't exist, use %{code_open}git clone%{code_close}."
msgstr ""
-msgid "For example, the application using the token or the purpose of the token."
+msgid "For example, the application using the token or the purpose of the token. Do not give sensitive information for the name of the token, as it will be visible to all %{resource_type} members."
msgstr ""
msgid "For files larger than this limit, only index the file name. The file content is neither indexed nor searchable."
@@ -15584,9 +15826,6 @@ msgstr ""
msgid "ForkProject|Select a namespace"
msgstr ""
-msgid "ForkProject|Select a namespace to fork the project"
-msgstr ""
-
msgid "ForkProject|The project can be accessed by any logged in user."
msgstr ""
@@ -15683,6 +15922,9 @@ msgstr ""
msgid "Full name"
msgstr ""
+msgid "GCP region configured"
+msgstr ""
+
msgid "GPG Key ID:"
msgstr ""
@@ -15863,6 +16105,9 @@ msgstr ""
msgid "Geo|Failed"
msgstr ""
+msgid "Geo|Filter Geo sites"
+msgstr ""
+
msgid "Geo|Filter by name"
msgstr ""
@@ -16274,6 +16519,12 @@ msgstr ""
msgid "GitLab Issue"
msgstr ""
+msgid "GitLab KAS"
+msgstr ""
+
+msgid "GitLab Memberships CSV Export"
+msgstr ""
+
msgid "GitLab Pages"
msgstr ""
@@ -16322,6 +16573,9 @@ 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 free to use. Many features for larger teams are part of our %{link_start}paid products%{link_end}. You can try Ultimate for free without any obligation or payment details."
+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 ""
@@ -16448,7 +16702,7 @@ msgstr ""
msgid "GitLabPages|When enabled, all attempts to visit your website through HTTP are automatically redirected to HTTPS using a response with status code 301. Requires a valid certificate for all domains. %{docs_link_start}Learn more.%{link_end}"
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. %{docs_link_start}Learn more.%{link_end}"
+msgid "GitLabPages|When using Pages under the general domain of a GitLab instance (%{pages_host}), you cannot use HTTPS with subdomains of subdomains. If your namespace or groupname contains a dot, it does not work. This is a limitation of the HTTP Over TLS protocol. HTTP pages work if you don't redirect HTTP to HTTPS. %{docs_link_start}Learn more.%{link_end}"
msgstr ""
msgid "GitLabPages|With GitLab Pages you can host your static website directly from your GitLab repository. %{docs_link_start}Learn more.%{link_end}"
@@ -16625,9 +16879,6 @@ msgstr ""
msgid "Go to find file"
msgstr ""
-msgid "Go to fork"
-msgstr ""
-
msgid "Go to issue boards"
msgstr ""
@@ -16835,9 +17086,6 @@ msgstr ""
msgid "Group Hooks"
msgstr ""
-msgid "Group ID"
-msgstr ""
-
msgid "Group Owner must have signed in with SAML before enabling Group Managed Accounts"
msgstr ""
@@ -16865,9 +17113,6 @@ msgstr ""
msgid "Group by"
msgstr ""
-msgid "Group description"
-msgstr ""
-
msgid "Group description (optional)"
msgstr ""
@@ -16982,7 +17227,7 @@ msgstr ""
msgid "Group: %{name}"
msgstr ""
-msgid "GroupActivityMetrics|Issues opened"
+msgid "GroupActivityMetrics|Issues created"
msgstr ""
msgid "GroupActivityMetrics|Last 90 days"
@@ -16991,7 +17236,7 @@ msgstr ""
msgid "GroupActivityMetrics|Members added"
msgstr ""
-msgid "GroupActivityMetrics|Merge Requests opened"
+msgid "GroupActivityMetrics|Merge Requests created"
msgstr ""
msgid "GroupActivityMetrics|Recent activity"
@@ -17282,6 +17527,9 @@ msgstr ""
msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
+msgid "GroupSettings|Choose a group path that does not start with a dash or end with a period. It can also contain alphanumeric characters and underscores."
+msgstr ""
+
msgid "GroupSettings|Compliance frameworks"
msgstr ""
@@ -17315,7 +17563,7 @@ msgstr ""
msgid "GroupSettings|If not specified at the group or instance level, the default is %{default_initial_branch_name}. Does not affect existing repositories."
msgstr ""
-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."
+msgid "GroupSettings|If the parent group's visibility is lower than the group's current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility."
msgstr ""
msgid "GroupSettings|New runners registration token has been generated!"
@@ -17432,7 +17680,10 @@ msgstr ""
msgid "Groups and projects"
msgstr ""
-msgid "Groups and subgroups"
+msgid "Groups are a great way to organize projects and people."
+msgstr ""
+
+msgid "Groups are the best way to manage projects and members."
msgstr ""
msgid "Groups to synchronize"
@@ -17543,13 +17794,16 @@ msgstr ""
msgid "GroupsTree|Are you sure you want to leave the \"%{fullName}\" group?"
msgstr ""
-msgid "GroupsTree|Edit group"
+msgid "GroupsTree|Delete"
+msgstr ""
+
+msgid "GroupsTree|Edit"
msgstr ""
msgid "GroupsTree|Failed to leave the group. Please make sure you are not the only owner."
msgstr ""
-msgid "GroupsTree|Leave this group"
+msgid "GroupsTree|Leave group"
msgstr ""
msgid "GroupsTree|Loading groups"
@@ -17561,9 +17815,57 @@ msgstr ""
msgid "GroupsTree|No groups or projects matched your search"
msgstr ""
+msgid "GroupsTree|Options"
+msgstr ""
+
msgid "GroupsTree|Search by name"
msgstr ""
+msgid "Groups|Avatar will be removed. Are you sure?"
+msgstr ""
+
+msgid "Groups|Changing group URL can have unintended side effects."
+msgstr ""
+
+msgid "Groups|Checking group URL availability..."
+msgstr ""
+
+msgid "Groups|Enter a descriptive name for your group."
+msgstr ""
+
+msgid "Groups|Group ID"
+msgstr ""
+
+msgid "Groups|Group URL"
+msgstr ""
+
+msgid "Groups|Group avatar"
+msgstr ""
+
+msgid "Groups|Group description (optional)"
+msgstr ""
+
+msgid "Groups|Group name"
+msgstr ""
+
+msgid "Groups|Group path is available."
+msgstr ""
+
+msgid "Groups|Group path is unavailable. Path has been replaced with a suggested available path."
+msgstr ""
+
+msgid "Groups|Learn more"
+msgstr ""
+
+msgid "Groups|Must start with letter, digit, emoji, or underscore. Can also contain periods, dashes, spaces, and parentheses."
+msgstr ""
+
+msgid "Groups|Remove avatar"
+msgstr ""
+
+msgid "Groups|Save changes"
+msgstr ""
+
msgid "Guideline"
msgstr ""
@@ -17573,6 +17875,9 @@ msgstr ""
msgid "HAR file path or URL"
msgstr ""
+msgid "HTTP Archive (HAR)"
+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 ""
@@ -17973,6 +18278,9 @@ msgstr ""
msgid "INFO: Your SSH key is expiring soon. Please generate a new key."
msgstr ""
+msgid "IP"
+msgstr ""
+
msgid "IP Address"
msgstr ""
@@ -18009,6 +18317,9 @@ msgstr ""
msgid "IdentityVerification|Verify your identity"
msgstr ""
+msgid "IdentityVerification|You can always verify your account at a later time to create a group."
+msgstr ""
+
msgid "If any indexed field exceeds this limit, it is truncated to this number of characters. The rest of the content is neither indexed nor searchable. This does not apply to repository and wiki indexing. For unlimited characters, set this to 0."
msgstr ""
@@ -18066,6 +18377,9 @@ msgstr ""
msgid "If you add %{codeStart}needs%{codeEnd} to jobs in your pipeline you'll be able to view the %{codeStart}needs%{codeEnd} relationships between jobs in this tab as a %{linkStart}Directed Acyclic Graph (DAG)%{linkEnd}."
msgstr ""
+msgid "If you are added to a project, it will be displayed here."
+msgstr ""
+
msgid "If you did not initiate these sign-in attempts, please reach out to your administrator or enable two-factor authentication (2FA) on your account."
msgstr ""
@@ -18372,12 +18686,24 @@ msgstr ""
msgid "InProductMarketing|3 ways to dive into GitLab CI/CD"
msgstr ""
+msgid "InProductMarketing|A single application eliminates complex integrations, data chokepoints, and toolchain maintenance, resulting in greater productivity and lower cost."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features, build more efficiently, strengthen security and compliance."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features."
+msgstr ""
+
msgid "InProductMarketing|Actually, GitLab makes the team work (better)"
msgstr ""
msgid "InProductMarketing|And finally %{deploy_link} a Python application."
msgstr ""
+msgid "InProductMarketing|And many more..."
+msgstr ""
+
msgid "InProductMarketing|Are your runners ready?"
msgstr ""
@@ -18396,15 +18722,33 @@ msgstr ""
msgid "InProductMarketing|Blog"
msgstr ""
+msgid "InProductMarketing|Break down silos to coordinate seamlessly across development, operations, and security with a consistent experience across the development lifecycle."
+msgstr ""
+
+msgid "InProductMarketing|Burn up/down charts"
+msgstr ""
+
msgid "InProductMarketing|By enabling code owners and required merge approvals the right person will review the right MR. This is a win-win: cleaner code and a more efficient review process."
msgstr ""
msgid "InProductMarketing|Click on the number below that corresponds with your answer — 1 being very difficult, 5 being very easy."
msgstr ""
+msgid "InProductMarketing|Code owners"
+msgstr ""
+
msgid "InProductMarketing|Code owners and required merge approvals are part of the paid tiers of GitLab. You can start a free 30-day trial of GitLab Ultimate and enable these features in less than 5 minutes with no credit card required."
msgstr ""
+msgid "InProductMarketing|Code review analytics"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration across stages in GitLab"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration made easy"
+msgstr ""
+
msgid "InProductMarketing|Create a custom CI runner with just a few clicks"
msgstr ""
@@ -18414,12 +18758,21 @@ msgstr ""
msgid "InProductMarketing|Create a project in GitLab in 5 minutes"
msgstr ""
+msgid "InProductMarketing|Create well-defined workflows by using scoped labels on issues, merge requests, and epics. Labels with the same scope cannot be used together, which prevents conflicts."
+msgstr ""
+
msgid "InProductMarketing|Create your first project!"
msgstr ""
+msgid "InProductMarketing|Define who owns specific files or directories, so the right reviewers are suggested when a merge request introduces changes to those files."
+msgstr ""
+
msgid "InProductMarketing|Deliver Better Products Faster"
msgstr ""
+msgid "InProductMarketing|Dependency scanning"
+msgstr ""
+
msgid "InProductMarketing|Did you know teams that use GitLab are far more efficient?"
msgstr ""
@@ -18429,15 +18782,27 @@ msgstr ""
msgid "InProductMarketing|Dig in and create a project and a repo"
msgstr ""
+msgid "InProductMarketing|Discover Premium & Ultimate"
+msgstr ""
+
+msgid "InProductMarketing|Discover Premium & Ultimate."
+msgstr ""
+
msgid "InProductMarketing|Do you have a minute?"
msgstr ""
msgid "InProductMarketing|Do you have a teammate who would be perfect for this task?"
msgstr ""
+msgid "InProductMarketing|Dynamic application security testing"
+msgstr ""
+
msgid "InProductMarketing|Easy"
msgstr ""
+msgid "InProductMarketing|Epics"
+msgstr ""
+
msgid "InProductMarketing|Expand your DevOps journey with a free GitLab trial"
msgstr ""
@@ -18459,9 +18824,15 @@ msgstr ""
msgid "InProductMarketing|Feel the need for speed?"
msgstr ""
+msgid "InProductMarketing|Find and fix bottlenecks in your code review process by understanding how long open merge requests have been in review."
+msgstr ""
+
msgid "InProductMarketing|Find out how your teams are really doing"
msgstr ""
+msgid "InProductMarketing|Find out if your external libraries are safe. Run dependency scanning jobs that check for known vulnerabilities in your external libraries."
+msgstr ""
+
msgid "InProductMarketing|Follow our steps"
msgstr ""
@@ -18498,6 +18869,9 @@ msgstr ""
msgid "InProductMarketing|GitLab is better with teammates to help out!"
msgstr ""
+msgid "InProductMarketing|GitLab is infrastructure agnostic (supporting GCP, AWS, Azure, OpenShift, VMWare, On Prem, Bare Metal, and more), offering a consistent workflow experience – irrespective of the environment."
+msgstr ""
+
msgid "InProductMarketing|GitLab provides static application security testing (SAST), dynamic application security testing (DAST), container scanning, and dependency scanning to help you deliver secure applications along with license compliance."
msgstr ""
@@ -18588,21 +18962,36 @@ msgstr ""
msgid "InProductMarketing|It's also possible to simply %{external_repo_link} in order to take advantage of GitLab's CI/CD."
msgstr ""
+msgid "InProductMarketing|Keep your code quality high by defining who should approve merge requests and how many approvals are required."
+msgstr ""
+
msgid "InProductMarketing|Launch GitLab CI/CD in 20 minutes or less"
msgstr ""
+msgid "InProductMarketing|Lower cost of development"
+msgstr ""
+
+msgid "InProductMarketing|Make it easier to collaborate on high-level ideas by grouping related issues in an epic."
+msgstr ""
+
msgid "InProductMarketing|Making the switch? It's easier than you think to import your projects into GitLab. Move %{github_link}, or import something %{bitbucket_link}."
msgstr ""
msgid "InProductMarketing|Master the art of importing!"
msgstr ""
+msgid "InProductMarketing|Merge request approval rule"
+msgstr ""
+
msgid "InProductMarketing|Move on to easily creating a Pages website %{ci_template_link}"
msgstr ""
msgid "InProductMarketing|Multiple owners, confusing workstreams? We've got you covered"
msgstr ""
+msgid "InProductMarketing|Multiple required approvers"
+msgstr ""
+
msgid "InProductMarketing|Need an alternative to importing?"
msgstr ""
@@ -18615,18 +19004,33 @@ msgstr ""
msgid "InProductMarketing|Our tool brings all the things together"
msgstr ""
+msgid "InProductMarketing|Protect your web application by using DAST to examine for vulnerabilities in deployed environments."
+msgstr ""
+
msgid "InProductMarketing|Rapid development, simplified"
msgstr ""
msgid "InProductMarketing|Reduce Security & Compliance Risk"
msgstr ""
+msgid "InProductMarketing|Require multiple approvers on a merge request, so you know it's in good shape before it's merged."
+msgstr ""
+
+msgid "InProductMarketing|Roadmaps"
+msgstr ""
+
+msgid "InProductMarketing|Scoped labels"
+msgstr ""
+
msgid "InProductMarketing|Security that's integrated into your development lifecycle"
msgstr ""
msgid "InProductMarketing|Sometimes you're not ready to make a full transition to a new tool. If you're not ready to fully commit, %{mirroring_link} gives you a safe way to try out GitLab in parallel with your current tool."
msgstr ""
+msgid "InProductMarketing|Speed. Efficiency. Trust."
+msgstr ""
+
msgid "InProductMarketing|Spin up an autoscaling runner in GitLab"
msgstr ""
@@ -18636,6 +19040,9 @@ msgstr ""
msgid "InProductMarketing|Start a Self-Managed trial"
msgstr ""
+msgid "InProductMarketing|Start a free trial"
+msgstr ""
+
msgid "InProductMarketing|Start a free trial of GitLab Ultimate – no credit card required"
msgstr ""
@@ -18702,6 +19109,9 @@ msgstr ""
msgid "InProductMarketing|To understand and get the most out of GitLab, start at the beginning and %{project_link}. In GitLab, repositories are part of a project, so after you've created your project you can go ahead and %{repo_link}."
msgstr ""
+msgid "InProductMarketing|Track completed issues in a chart, so you can see how a milestone is progressing at a glance."
+msgstr ""
+
msgid "InProductMarketing|Try GitLab Ultimate for free"
msgstr ""
@@ -18738,6 +19148,9 @@ msgstr ""
msgid "InProductMarketing|Very easy"
msgstr ""
+msgid "InProductMarketing|Visualize your epics and milestones in a timeline."
+msgstr ""
+
msgid "InProductMarketing|Want to host GitLab on your servers?"
msgstr ""
@@ -18759,6 +19172,9 @@ msgstr ""
msgid "InProductMarketing|YouTube"
msgstr ""
+msgid "InProductMarketing|Your software, deployed your way"
+msgstr ""
+
msgid "InProductMarketing|Your teams can be more efficient"
msgstr ""
@@ -18879,9 +19295,18 @@ msgstr ""
msgid "IncidentManagement|No incidents to display."
msgstr ""
+msgid "IncidentManagement|None"
+msgstr ""
+
msgid "IncidentManagement|Open"
msgstr ""
+msgid "IncidentManagement|Page your team with escalation policies"
+msgstr ""
+
+msgid "IncidentManagement|Paged"
+msgstr ""
+
msgid "IncidentManagement|Published"
msgstr ""
@@ -18891,6 +19316,9 @@ msgstr ""
msgid "IncidentManagement|Severity"
msgstr ""
+msgid "IncidentManagement|Status"
+msgstr ""
+
msgid "IncidentManagement|There are no closed incidents"
msgstr ""
@@ -18909,6 +19337,9 @@ msgstr ""
msgid "IncidentManagement|Unpublished"
msgstr ""
+msgid "IncidentManagement|Use escalation policies to automatically page your team when incidents are created."
+msgstr ""
+
msgid "IncidentSettings|Activate \"time to SLA\" countdown timer"
msgstr ""
@@ -18954,7 +19385,10 @@ msgstr ""
msgid "Incidents"
msgstr ""
-msgid "Incidents|Add a URL"
+msgid "Incidents|Add image details"
+msgstr ""
+
+msgid "Incidents|Add text or a link to display with your image. If you don't add either, the file name displays instead."
msgstr ""
msgid "Incidents|Drop or %{linkStart}upload%{linkEnd} a metric screenshot to attach it to the incident"
@@ -18969,10 +19403,10 @@ msgstr ""
msgid "Incidents|There was an issue loading metric images."
msgstr ""
-msgid "Incidents|There was an issue uploading your image."
+msgid "Incidents|There was an issue updating your image."
msgstr ""
-msgid "Incidents|You can optionally add a URL to link users to the original graph."
+msgid "Incidents|There was an issue uploading your image."
msgstr ""
msgid "Incident|Alert details"
@@ -18981,9 +19415,18 @@ msgstr ""
msgid "Incident|Are you sure you wish to delete this image?"
msgstr ""
+msgid "Incident|Delete image"
+msgstr ""
+
msgid "Incident|Deleting %{filename}"
msgstr ""
+msgid "Incident|Edit image text or link"
+msgstr ""
+
+msgid "Incident|Editing %{filename}"
+msgstr ""
+
msgid "Incident|Metrics"
msgstr ""
@@ -19253,12 +19696,18 @@ msgstr ""
msgid "Integrations|Branches for which notifications are to be sent"
msgstr ""
+msgid "Integrations|Clear if using a self-signed certificate."
+msgstr ""
+
msgid "Integrations|Comment detail:"
msgstr ""
msgid "Integrations|Comment settings:"
msgstr ""
+msgid "Integrations|Connection details"
+msgstr ""
+
msgid "Integrations|Connection failed. Please check your settings."
msgstr ""
@@ -19283,6 +19732,9 @@ msgstr ""
msgid "Integrations|Enable GitLab.com slash commands in a Slack workspace."
msgstr ""
+msgid "Integrations|Enable SSL verification"
+msgstr ""
+
msgid "Integrations|Enable comments"
msgstr ""
@@ -19361,6 +19813,9 @@ msgstr ""
msgid "Integrations|Return to GitLab for Jira"
msgstr ""
+msgid "Integrations|SSL verification"
+msgstr ""
+
msgid "Integrations|Save settings?"
msgstr ""
@@ -19406,9 +19861,6 @@ msgstr ""
msgid "Integrations|Use default settings"
msgstr ""
-msgid "Integrations|When you mention a Jira issue in a commit or merge request, GitLab creates a remote link and comment (if enabled)."
-msgstr ""
-
msgid "Integrations|You can now close this window and return to the GitLab for Jira application."
msgstr ""
@@ -19433,9 +19885,6 @@ msgstr ""
msgid "Integrations|can't exceed %{recipients_limit}"
msgstr ""
-msgid "Interactive developer security education."
-msgstr ""
-
msgid "Interactive mode"
msgstr ""
@@ -19925,6 +20374,9 @@ msgstr ""
msgid "IssueAnalytics|Assignees"
msgstr ""
+msgid "IssueAnalytics|Created by"
+msgstr ""
+
msgid "IssueAnalytics|Due date"
msgstr ""
@@ -19937,9 +20389,6 @@ msgstr ""
msgid "IssueAnalytics|Milestone"
msgstr ""
-msgid "IssueAnalytics|Opened by"
-msgstr ""
-
msgid "IssueAnalytics|Status"
msgstr ""
@@ -20063,10 +20512,10 @@ msgstr ""
msgid "IssuesAnalytics|Avg/Month:"
msgstr ""
-msgid "IssuesAnalytics|Issues opened"
+msgid "IssuesAnalytics|Issues created"
msgstr ""
-msgid "IssuesAnalytics|Issues opened per month"
+msgid "IssuesAnalytics|Issues created per month"
msgstr ""
msgid "IssuesAnalytics|Last 12 months"
@@ -20093,6 +20542,9 @@ msgstr ""
msgid "It looks like you have some draft commits in this branch."
msgstr ""
+msgid "It looks like you're attempting to activate your subscription. Use %{a_start}the Subscription page%{a_end} instead."
+msgstr ""
+
msgid "It may be several days before you see feature usage data."
msgstr ""
@@ -20321,6 +20773,9 @@ msgstr ""
msgid "JiraConnect|You can now close this window and return to Jira."
msgstr ""
+msgid "JiraConnect|You don't have permission to create branches for this project. Select a different project or contact the project owner for access. %{linkStart}Learn more.%{linkEnd}"
+msgstr ""
+
msgid "JiraRequest|A connection error occurred while connecting to Jira. Try your request again."
msgstr ""
@@ -20369,13 +20824,13 @@ msgstr ""
msgid "JiraService|Define the type of Jira issue to create from a vulnerability."
msgstr ""
-msgid "JiraService|Displaying Jira issues while leaving the GitLab issue functionality enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
+msgid "JiraService|Displaying Jira issues while leaving GitLab issues also enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
msgstr ""
-msgid "JiraService|Enable Jira issues"
+msgid "JiraService|Enable Jira issue creation from vulnerabilities"
msgstr ""
-msgid "JiraService|Enable Jira issues creation from vulnerabilities"
+msgid "JiraService|Enable Jira issues"
msgstr ""
msgid "JiraService|Enable Jira transitions"
@@ -20492,16 +20947,19 @@ msgstr ""
msgid "JiraService|View Jira issues in GitLab"
msgstr ""
-msgid "JiraService|Warning: All GitLab users that have access to this GitLab project are able to view all issues from the Jira project specified below."
+msgid "JiraService|Warning: All GitLab users with access to this GitLab project can view all issues from the Jira project you select."
msgstr ""
msgid "JiraService|Web URL"
msgstr ""
-msgid "JiraService|Work on Jira issues without leaving GitLab. Adds a Jira menu to access your list of Jira issues and view any issue as read-only."
+msgid "JiraService|When a Jira issue is mentioned in a commit or merge request, a remote link and comment (if enabled) will be created."
+msgstr ""
+
+msgid "JiraService|Work on Jira issues without leaving GitLab. Add a Jira menu to access a read-only list of your Jira issues."
msgstr ""
-msgid "JiraService|You need to configure Jira before enabling this integration. For more details, read the %{jira_doc_link_start}Jira integration documentation%{link_end}."
+msgid "JiraService|You must configure Jira before enabling this integration. %{jira_doc_link_start}Learn more.%{link_end}"
msgstr ""
msgid "Job"
@@ -20513,9 +20971,6 @@ msgstr ""
msgid "Job Failed #%{build_id}"
msgstr ""
-msgid "Job ID"
-msgstr ""
-
msgid "Job artifact"
msgstr ""
@@ -20582,9 +21037,27 @@ msgstr ""
msgid "Jobs|You're about to retry a job that failed because it attempted to deploy code that is older than the latest deployment. Retrying this job could result in overwriting the environment with the older source code."
msgstr ""
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source} into %{target}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{ref}"
+msgstr ""
+
+msgid "Job|Are you sure you want to erase this job log and artifacts?"
+msgstr ""
+
msgid "Job|Browse"
msgstr ""
+msgid "Job|Cancel"
+msgstr ""
+
msgid "Job|Complete Raw"
msgstr ""
@@ -20594,6 +21067,9 @@ msgstr ""
msgid "Job|Erase job log and artifacts"
msgstr ""
+msgid "Job|Finished at"
+msgstr ""
+
msgid "Job|Job artifacts"
msgstr ""
@@ -20606,7 +21082,7 @@ msgstr ""
msgid "Job|Keep"
msgstr ""
-msgid "Job|Pipeline"
+msgid "Job|Retry"
msgstr ""
msgid "Job|Scroll to bottom"
@@ -20618,6 +21094,9 @@ msgstr ""
msgid "Job|Show complete raw"
msgstr ""
+msgid "Job|Status"
+msgstr ""
+
msgid "Job|The artifacts were removed"
msgstr ""
@@ -20645,21 +21124,12 @@ msgstr ""
msgid "Job|delayed"
msgstr ""
-msgid "Job|for"
-msgstr ""
-
-msgid "Job|into"
-msgstr ""
-
msgid "Job|manual"
msgstr ""
msgid "Job|triggered"
msgstr ""
-msgid "Job|with"
-msgstr ""
-
msgid "Join Zoom meeting"
msgstr ""
@@ -20762,9 +21232,6 @@ msgstr ""
msgid "Ki"
msgstr ""
-msgid "Kontra"
-msgstr ""
-
msgid "Kroki"
msgstr ""
@@ -21088,6 +21555,9 @@ msgstr ""
msgid "Learn more about Auto DevOps"
msgstr ""
+msgid "Learn more about GitLab"
+msgstr ""
+
msgid "Learn more about Needs relationships"
msgstr ""
@@ -21415,9 +21885,18 @@ msgstr ""
msgid "Licenses|Displays licenses detected in the project, based on the %{linkStart}latest successful%{linkEnd} scan"
msgstr ""
+msgid "Licenses|Drag your license file here or %{linkStart}click to upload%{linkEnd}."
+msgstr ""
+
+msgid "Licenses|Drop your license file to start the upload."
+msgstr ""
+
msgid "Licenses|Error fetching the license list. Please check your network connection and try again."
msgstr ""
+msgid "Licenses|Error: You are trying to upload something other than a file"
+msgstr ""
+
msgid "Licenses|License Compliance"
msgstr ""
@@ -21436,6 +21915,9 @@ msgstr ""
msgid "Licenses|Specified policies in this project"
msgstr ""
+msgid "Licenses|The file could not be uploaded."
+msgstr ""
+
msgid "Licenses|The license list details information about the licenses used within your project."
msgstr ""
@@ -21469,11 +21951,6 @@ msgstr ""
msgid "Limit the size of Sidekiq jobs stored in Redis."
msgstr ""
-msgid "Limited to showing %d event at most"
-msgid_plural "Limited to showing %d events at most"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Limiting mode"
msgstr ""
@@ -21483,6 +21960,9 @@ msgstr ""
msgid "Link"
msgstr ""
+msgid "Link (optional)"
+msgstr ""
+
msgid "Link Prometheus monitoring to GitLab."
msgstr ""
@@ -21519,6 +21999,9 @@ msgstr ""
msgid "Linked emails (%{email_count})"
msgstr ""
+msgid "Linked epics"
+msgstr ""
+
msgid "Linked issues"
msgstr ""
@@ -21546,6 +22029,15 @@ msgstr ""
msgid "List of all merge commits"
msgstr ""
+msgid "List of environments for this project"
+msgstr ""
+
+msgid "List of suitable GCP locations"
+msgstr ""
+
+msgid "List of users allowed to exceed the rate limit."
+msgstr ""
+
msgid "List options"
msgstr ""
@@ -21765,6 +22257,9 @@ msgstr ""
msgid "Maintenance mode"
msgstr ""
+msgid "Make adjustments to how your GitLab instance is set up."
+msgstr ""
+
msgid "Make and review changes in the browser with the Web IDE"
msgstr ""
@@ -21909,6 +22404,12 @@ msgstr ""
msgid "MarkdownEditor|Add italic text (%{modifier_key}I)"
msgstr ""
+msgid "MarkdownEditor|Add strikethrough text (%{modifierKey}⇧X)"
+msgstr ""
+
+msgid "MarkdownEditor|Add strikethrough text (%{modifier_key}⇧X)"
+msgstr ""
+
msgid "Marked For Deletion At - %{deletion_time}"
msgstr ""
@@ -22170,6 +22671,9 @@ msgstr ""
msgid "Maximum push size (MB)"
msgstr ""
+msgid "Maximum requests per 10 minutes per user"
+msgstr ""
+
msgid "Maximum requests per minute"
msgstr ""
@@ -22260,6 +22764,19 @@ msgstr ""
msgid "Members of a group may only view projects they have permission to access"
msgstr ""
+msgid "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seat in use and will be billed for the overage."
+msgid_plural "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seats in use and will be billed for the overage."
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "MembersOverage|You are about to incur additional charges"
+msgstr ""
+
+msgid "MembersOverage|Your subscription includes %d seat."
+msgid_plural "MembersOverage|Your subscription includes %d seats."
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Membership"
msgstr ""
@@ -22464,9 +22981,6 @@ msgstr ""
msgid "Merge request not merged"
msgstr ""
-msgid "Merge request pipelines 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 merge request pipelines."
-msgstr ""
-
msgid "Merge request reports"
msgstr ""
@@ -22563,13 +23077,13 @@ msgstr ""
msgid "MergeRequests|Create issue to resolve thread"
msgstr ""
-msgid "MergeRequests|Failed to squash. Should be done manually."
+msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Saving the comment failed"
+msgid "MergeRequests|Squashing failed: Squash the commits locally, resolve any conflicts, then push the branch."
msgstr ""
-msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
+msgid "MergeRequests|Squashing not allowed: This project doesn't allow you to squash commits when merging."
msgstr ""
msgid "MergeRequests|Thread stays resolved"
@@ -23410,6 +23924,18 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "MrList|Assigned to %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from assignee %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from reviewer %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Review requested from %{name}, go to their profile."
+msgstr ""
+
msgid "Multi-project"
msgstr ""
@@ -23443,7 +23969,7 @@ msgstr ""
msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "My Awesome Group"
+msgid "My awesome group"
msgstr ""
msgid "My company or team"
@@ -24065,9 +24591,6 @@ msgstr ""
msgid "No available branches"
msgstr ""
-msgid "No available groups to fork the project."
-msgstr ""
-
msgid "No branches found"
msgstr ""
@@ -24278,6 +24801,9 @@ msgstr ""
msgid "No ref selected"
msgstr ""
+msgid "No regions configured"
+msgstr ""
+
msgid "No related merge requests found."
msgstr ""
@@ -25082,6 +25608,9 @@ msgstr ""
msgid "Only reCAPTCHA v2 is supported:"
msgstr ""
+msgid "Only required if not using role instance credentials."
+msgstr ""
+
msgid "Only use lowercase letters, numbers, and underscores."
msgstr ""
@@ -25106,9 +25635,6 @@ msgstr ""
msgid "Open a CLI and connect to the cluster you want to install the agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
-msgid "Open epics"
-msgstr ""
-
msgid "Open errors"
msgstr ""
@@ -25148,7 +25674,7 @@ msgstr ""
msgid "Opened issues"
msgstr ""
-msgid "OpenedNDaysAgo|Opened"
+msgid "OpenedNDaysAgo|Created"
msgstr ""
msgid "Opens in a new window"
@@ -25193,9 +25719,6 @@ msgstr ""
msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
-msgid "Optional."
-msgstr ""
-
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
msgstr ""
@@ -25984,6 +26507,9 @@ msgstr ""
msgid "PerformanceBar|Memory"
msgstr ""
+msgid "PerformanceBar|Memory report"
+msgstr ""
+
msgid "PerformanceBar|Redis calls"
msgstr ""
@@ -26017,18 +26543,12 @@ msgstr ""
msgid "PerformanceBar|wall"
msgstr ""
-msgid "Performs a rebase but skips triggering a new pipeline"
-msgstr ""
-
msgid "Period in seconds"
msgstr ""
msgid "Permalink"
msgstr ""
-msgid "Permanently delete project"
-msgstr ""
-
msgid "Permanently remove group"
msgstr ""
@@ -26299,6 +26819,51 @@ msgstr ""
msgid "PipelineStatusTooltip|Pipeline: %{ci_status}"
msgstr ""
+msgid "PipelineWizardDefaultCommitMessage|Add %{filename}"
+msgstr ""
+
+msgid "PipelineWizardDefaultCommitMessage|Update %{filename}"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|At least one entry is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This field is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This value is not valid"
+msgstr ""
+
+msgid "PipelineWizardListWidget|add another step"
+msgstr ""
+
+msgid "PipelineWizardListWidget|remove step"
+msgstr ""
+
+msgid "PipelineWizard|Commit"
+msgstr ""
+
+msgid "PipelineWizard|Commit Message"
+msgstr ""
+
+msgid "PipelineWizard|Commit changes to your file"
+msgstr ""
+
+msgid "PipelineWizard|Commit file to Branch"
+msgstr ""
+
+msgid "PipelineWizard|Commit your new file"
+msgstr ""
+
+msgid "PipelineWizard|The file has been committed."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem committing the changes."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem while checking whether your file already exists in the specified branch."
+msgstr ""
+
msgid "Pipelines"
msgstr ""
@@ -26413,7 +26978,7 @@ msgstr ""
msgid "Pipelines|Project cache successfully reset."
msgstr ""
-msgid "Pipelines|Revoke"
+msgid "Pipelines|Revoke trigger"
msgstr ""
msgid "Pipelines|Something went wrong while cleaning runners cache."
@@ -26458,6 +27023,12 @@ msgstr ""
msgid "Pipelines|This is a child pipeline within the parent pipeline"
msgstr ""
+msgid "Pipelines|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipelines|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipelines|This pipeline will run code originating from a forked project merge request. This means that the code can potentially have security considerations like exposing CI variables."
msgstr ""
@@ -26500,9 +27071,6 @@ msgstr ""
msgid "Pipelines|Your changes have been successfully committed. Now redirecting to the new merge request page."
msgstr ""
-msgid "Pipelines|detached"
-msgstr ""
-
msgid "Pipelines|error"
msgstr ""
@@ -26512,10 +27080,13 @@ msgstr ""
msgid "Pipelines|latest"
msgstr ""
-msgid "Pipelines|stuck"
+msgid "Pipelines|merge request"
msgstr ""
-msgid "Pipelines|train"
+msgid "Pipelines|merge train"
+msgstr ""
+
+msgid "Pipelines|stuck"
msgstr ""
msgid "Pipelines|yaml invalid"
@@ -26647,6 +27218,12 @@ msgstr ""
msgid "Pipeline|This change will not change the overall test coverage if merged."
msgstr ""
+msgid "Pipeline|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipeline|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipeline|Trigger author"
msgstr ""
@@ -26671,6 +27248,12 @@ msgstr ""
msgid "Pipeline|for"
msgstr ""
+msgid "Pipeline|merge request"
+msgstr ""
+
+msgid "Pipeline|merge train"
+msgstr ""
+
msgid "Pipeline|on"
msgstr ""
@@ -26809,9 +27392,6 @@ msgstr ""
msgid "Please enter a valid time interval"
msgstr ""
-msgid "Please enter or upload a valid license."
-msgstr ""
-
msgid "Please enter your current password."
msgstr ""
@@ -26920,9 +27500,6 @@ msgstr ""
msgid "Please type %{phrase_code} to proceed or close this modal to cancel."
msgstr ""
-msgid "Please type the following to confirm:"
-msgstr ""
-
msgid "Please use this form to report to the admin users who create spam issues, comments or behave inappropriately."
msgstr ""
@@ -26950,12 +27527,27 @@ msgstr ""
msgid "Policies"
msgstr ""
+msgid "Policy '%{escalation_policy_name}' does not exist."
+msgstr ""
+
msgid "Policy management project does have any policies in %{policy_path}"
msgstr ""
msgid "Policy project doesn't exist"
msgstr ""
+msgid "PolicyRuleMultiSelect|%{firstLabel} +%{numberOfAdditionalLabels} more"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|All %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select all"
+msgstr ""
+
msgid "Polling interval multiplier"
msgstr ""
@@ -27184,6 +27776,9 @@ msgstr ""
msgid "Private projects can be created in your personal namespace with:"
msgstr ""
+msgid "Problem with %{name} command: %{message}."
+msgstr ""
+
msgid "Proceed"
msgstr ""
@@ -27658,6 +28253,9 @@ msgstr ""
msgid "Progress"
msgstr ""
+msgid "Progress tracking"
+msgstr ""
+
msgid "Project"
msgstr ""
@@ -27889,6 +28487,9 @@ msgstr ""
msgid "ProjectQualitySummary|Failure"
msgstr ""
+msgid "ProjectQualitySummary|Get insight into the overall percentage of tests in your project that succeed, fail and are skipped."
+msgstr ""
+
msgid "ProjectQualitySummary|Latest pipeline results"
msgstr ""
@@ -27907,6 +28508,12 @@ msgstr ""
msgid "ProjectQualitySummary|See project Code Coverage Statistics"
msgstr ""
+msgid "ProjectQualitySummary|Set up test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|Set up test runs (opens in a new tab)"
+msgstr ""
+
msgid "ProjectQualitySummary|Skipped"
msgstr ""
@@ -28183,13 +28790,19 @@ msgstr ""
msgid "ProjectSettings|LFS objects from this repository are available to forks. %{linkStart}How do I remove them?%{linkEnd}"
msgstr ""
+msgid "ProjectSettings|Learn about commit history."
+msgstr ""
+
+msgid "ProjectSettings|Leave empty to use default template."
+msgstr ""
+
msgid "ProjectSettings|Manage who can see the project in the public access directory."
msgstr ""
msgid "ProjectSettings|Manages large files such as audio, video, and graphics files."
msgstr ""
-msgid "ProjectSettings|Maximum 500 characters."
+msgid "ProjectSettings|Maximum %{maxLength} characters."
msgstr ""
msgid "ProjectSettings|Merge checks"
@@ -28330,6 +28943,9 @@ msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
msgstr ""
+msgid "ProjectSettings|The default template will be applied on save."
+msgstr ""
+
msgid "ProjectSettings|These checks must pass before merge requests can be merged."
msgstr ""
@@ -28384,6 +29000,9 @@ msgstr ""
msgid "ProjectSettings|What are badges?"
msgstr ""
+msgid "ProjectSettings|What are merge trains?"
+msgstr ""
+
msgid "ProjectSettings|When merge request pipelines are enabled in the CI/CD configuration file, pipelines validate the combined results of the source and target branches. %{link_start}How to configure merge request pipelines?%{link_end}"
msgstr ""
@@ -28501,6 +29120,9 @@ msgstr ""
msgid "Projects are organized into groups"
msgstr ""
+msgid "Projects are where you store your code, access issues, wiki and other features of GitLab."
+msgstr ""
+
msgid "Projects contributed to"
msgstr ""
@@ -28516,12 +29138,6 @@ msgstr ""
msgid "Projects to index"
msgstr ""
-msgid "Projects will be permanently deleted after a %{waiting_period}-day waiting period."
-msgstr ""
-
-msgid "Projects will be permanently deleted immediately."
-msgstr ""
-
msgid "Projects with critical vulnerabilities"
msgstr ""
@@ -28606,6 +29222,9 @@ msgstr ""
msgid "ProjectsNew|Import project"
msgstr ""
+msgid "ProjectsNew|Include a Getting Started README"
+msgstr ""
+
msgid "ProjectsNew|Initialize repository with a README"
msgstr ""
@@ -28621,6 +29240,9 @@ msgstr ""
msgid "ProjectsNew|Project description %{tag_start}(optional)%{tag_end}"
msgstr ""
+msgid "ProjectsNew|Recommended if you're new to GitLab"
+msgstr ""
+
msgid "ProjectsNew|Run CI/CD for external repository"
msgstr ""
@@ -29038,6 +29660,9 @@ msgstr ""
msgid "ProtectedBranch|Unprotect"
msgstr ""
+msgid "ProtectedBranch|Unprotect branch"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
@@ -29065,6 +29690,9 @@ msgstr ""
msgid "ProtectedEnvironment|Protected Environment (%{protected_environments_count})"
msgstr ""
+msgid "ProtectedEnvironment|Required approvals"
+msgstr ""
+
msgid "ProtectedEnvironment|Select an environment"
msgstr ""
@@ -29086,10 +29714,13 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|Unprotect tag"
+msgstr ""
+
msgid "ProtectedTags|default"
msgstr ""
-msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
+msgid "ProtectedTag|By default, protected tags restrict who can modify the tag."
msgstr ""
msgid "ProtectedTag|Learn more."
@@ -29152,6 +29783,9 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Public projects are an easy way to allow everyone to have read-only access."
+msgstr ""
+
msgid "Publish to status page"
msgstr ""
@@ -29308,9 +29942,6 @@ msgstr ""
msgid "QualitySummary|Project quality"
msgstr ""
-msgid "Quarters"
-msgstr ""
-
msgid "Query"
msgstr ""
@@ -29395,6 +30026,9 @@ msgstr ""
msgid "Read more about project permissions %{help_link_open}here%{help_link_close}"
msgstr ""
+msgid "Read more about related epics"
+msgstr ""
+
msgid "Read more about related issues"
msgstr ""
@@ -29425,10 +30059,7 @@ msgstr ""
msgid "Rebase source branch on the target branch."
msgstr ""
-msgid "Rebase without CI"
-msgstr ""
-
-msgid "Rebases and triggers a pipeline"
+msgid "Rebase without pipeline"
msgstr ""
msgid "Recaptcha verified?"
@@ -29479,9 +30110,6 @@ msgstr ""
msgid "Reconfigure"
msgstr ""
-msgid "Recovering projects"
-msgstr ""
-
msgid "Recovery Codes"
msgstr ""
@@ -29541,6 +30169,12 @@ msgstr ""
msgid "Regex pattern"
msgstr ""
+msgid "Region"
+msgstr ""
+
+msgid "Regions"
+msgstr ""
+
msgid "Register"
msgstr ""
@@ -29771,9 +30405,6 @@ msgstr ""
msgid "Remove all or specific reviewer(s)"
msgstr ""
-msgid "Remove approver"
-msgstr ""
-
msgid "Remove approvers"
msgstr ""
@@ -29789,6 +30420,9 @@ msgstr ""
msgid "Remove attention request"
msgstr ""
+msgid "Remove attention request(s)"
+msgstr ""
+
msgid "Remove avatar"
msgstr ""
@@ -29927,6 +30561,9 @@ msgstr ""
msgid "Removed an issue from an epic."
msgstr ""
+msgid "Removed attention from %{users_sentence}."
+msgstr ""
+
msgid "Removed attention request from @%{username}"
msgstr ""
@@ -29978,6 +30615,9 @@ msgstr ""
msgid "Removes an issue from an epic."
msgstr ""
+msgid "Removes attention from %{users_sentence}."
+msgstr ""
+
msgid "Removes parent epic %{epic_ref}."
msgstr ""
@@ -30089,6 +30729,9 @@ msgstr ""
msgid "Report abuse to admin"
msgstr ""
+msgid "Report is generating and will be sent to your email address."
+msgstr ""
+
msgid "Reported %{timeAgo} by %{reportedBy}"
msgstr ""
@@ -30378,6 +31021,15 @@ msgstr ""
msgid "Request attention"
msgstr ""
+msgid "Request attention from %{users_sentence}."
+msgstr ""
+
+msgid "Request attention from assignee or reviewer"
+msgstr ""
+
+msgid "Request attention from assignee(s) or reviewer(s)"
+msgstr ""
+
msgid "Request attention to review"
msgstr ""
@@ -30402,6 +31054,9 @@ msgstr ""
msgid "Requested %{time_ago}"
msgstr ""
+msgid "Requested attention from %{users_sentence}."
+msgstr ""
+
msgid "Requested attention from @%{username}"
msgstr ""
@@ -30616,6 +31271,9 @@ msgstr ""
msgid "Restore project"
msgstr ""
+msgid "Restoring projects"
+msgstr ""
+
msgid "Restoring the group will prevent the group, its subgroups and projects from being removed on this date."
msgstr ""
@@ -30646,6 +31304,9 @@ msgstr ""
msgid "Retry"
msgstr ""
+msgid "Retry failed jobs"
+msgstr ""
+
msgid "Retry job"
msgstr ""
@@ -30693,9 +31354,6 @@ msgstr ""
msgid "Review changes"
msgstr ""
-msgid "Review requested from %{name}"
-msgstr ""
-
msgid "Review requests for you"
msgstr ""
@@ -30860,6 +31518,9 @@ msgstr ""
msgid "Runners|Assigned Group"
msgstr ""
+msgid "Runners|Assigned Projects (%{projectCount})"
+msgstr ""
+
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30929,6 +31590,9 @@ msgstr ""
msgid "Runners|Instance"
msgstr ""
+msgid "Runners|Jobs"
+msgstr ""
+
msgid "Runners|Last contact"
msgstr ""
@@ -31022,9 +31686,6 @@ msgstr ""
msgid "Runners|Runner %{name} was deleted"
msgstr ""
-msgid "Runners|Runner ID"
-msgstr ""
-
msgid "Runners|Runner assigned to project."
msgstr ""
@@ -31172,6 +31833,9 @@ msgstr ""
msgid "Runners|stale"
msgstr ""
+msgid "Runner|This runner has not run any jobs."
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -31286,6 +31950,24 @@ msgstr ""
msgid "Saving project."
msgstr ""
+msgid "ScanResultPolicy|%{ifLabelStart}if%{ifLabelEnd} %{scanners} scan in an open merge request targeting the %{branches} branch(es) finds %{vulnerabilitiesAllowed} or more %{severities} vulnerabilities that are %{vulnerabilityStates}"
+msgstr ""
+
+msgid "ScanResultPolicy|%{thenLabelStart}Then%{thenLabelEnd} Require approval from %{approvalsRequired} of the following approvers: %{approvers}"
+msgstr ""
+
+msgid "ScanResultPolicy|add an approver"
+msgstr ""
+
+msgid "ScanResultPolicy|scanners"
+msgstr ""
+
+msgid "ScanResultPolicy|severity levels"
+msgstr ""
+
+msgid "ScanResultPolicy|vulnerability states"
+msgstr ""
+
msgid "Scanner"
msgstr ""
@@ -31418,6 +32100,9 @@ msgstr ""
msgid "Search for a user"
msgstr ""
+msgid "Search for an emoji"
+msgstr ""
+
msgid "Search for projects, issues, etc."
msgstr ""
@@ -31605,18 +32290,12 @@ msgstr ""
msgid "Secret Detection"
msgstr ""
-msgid "Secret access key"
-msgstr ""
-
msgid "Secret token"
msgstr ""
msgid "Secure token that identifies an external storage request."
msgstr ""
-msgid "SecureCodeWarrior"
-msgstr ""
-
msgid "Security"
msgstr ""
@@ -31641,9 +32320,6 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "Security training with guide and learning pathways."
-msgstr ""
-
msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
@@ -31746,7 +32422,7 @@ msgstr ""
msgid "SecurityConfiguration|Manage corpus"
msgstr ""
-msgid "SecurityConfiguration|Manage corpus files used as mutation sources in coverage fuzzing."
+msgid "SecurityConfiguration|Manage corpus files used as seed inputs with coverage-guided fuzzing."
msgstr ""
msgid "SecurityConfiguration|Manage profiles for use by DAST scans."
@@ -31812,15 +32488,15 @@ msgstr ""
msgid "SecurityOrchestration|.yaml preview"
msgstr ""
-msgid "SecurityOrchestration|Action"
-msgstr ""
-
msgid "SecurityOrchestration|Actions"
msgstr ""
msgid "SecurityOrchestration|Add rule"
msgstr ""
+msgid "SecurityOrchestration|After dismissing the alert, the information will never be shown again."
+msgstr ""
+
msgid "SecurityOrchestration|All policies"
msgstr ""
@@ -31836,7 +32512,7 @@ msgstr ""
msgid "SecurityOrchestration|Description"
msgstr ""
-msgid "SecurityOrchestration|Disabled"
+msgid "SecurityOrchestration|Don't show the alert anymore"
msgstr ""
msgid "SecurityOrchestration|Edit policy"
@@ -31845,13 +32521,13 @@ msgstr ""
msgid "SecurityOrchestration|Edit policy project"
msgstr ""
-msgid "SecurityOrchestration|Enabled"
+msgid "SecurityOrchestration|Empty policy name"
msgstr ""
-msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Enabled"
msgstr ""
-msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
msgstr ""
msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
@@ -31860,7 +32536,7 @@ msgstr ""
msgid "SecurityOrchestration|Invalid policy type"
msgstr ""
-msgid "SecurityOrchestration|Latest scan"
+msgid "SecurityOrchestration|Latest scan run against %{agent}"
msgstr ""
msgid "SecurityOrchestration|Network"
@@ -31869,15 +32545,27 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No actions defined - policy will not run."
+msgstr ""
+
+msgid "SecurityOrchestration|No description"
+msgstr ""
+
msgid "SecurityOrchestration|No rules defined - policy will not run."
msgstr ""
+msgid "SecurityOrchestration|Not enabled"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
msgid "SecurityOrchestration|Policies"
msgstr ""
+msgid "SecurityOrchestration|Policy Type"
+msgstr ""
+
msgid "SecurityOrchestration|Policy cannot be enabled for non-existing branches (%{branches})"
msgstr ""
@@ -31902,10 +32590,13 @@ msgstr ""
msgid "SecurityOrchestration|Require %{approvals} %{plural} from %{approvers} if any of the following occur:"
msgstr ""
-msgid "SecurityOrchestration|Rule"
+msgid "SecurityOrchestration|Rules"
msgstr ""
-msgid "SecurityOrchestration|Rules"
+msgid "SecurityOrchestration|Runs %{actions} and %{lastAction} scans"
+msgstr ""
+
+msgid "SecurityOrchestration|Runs a %{action} scan"
msgstr ""
msgid "SecurityOrchestration|Scan Execution"
@@ -31965,6 +32656,9 @@ msgstr ""
msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
+msgid "SecurityOrchestration|This view only shows scan results for the agent %{agent}. You can view scan results for all agents in the %{linkStart}Operational Vulnerabilities tab of the vulnerability report%{linkEnd}."
+msgstr ""
+
msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
@@ -32019,9 +32713,6 @@ msgstr ""
msgid "SecurityOrchestration|users with ids"
msgstr ""
-msgid "SecurityOrchestration|view results"
-msgstr ""
-
msgid "SecurityOrchestration|vulnerabilities"
msgstr ""
@@ -32691,22 +33382,19 @@ 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|In order to start using functions as a service, you must first install Knative on your Kubernetes cluster. %{linkStart}More information%{linkEnd}"
-msgstr ""
-
msgid "Serverless|Learn more about Serverless"
msgstr ""
msgid "Serverless|No functions available"
msgstr ""
-msgid "Serverless|Sign up for First Look"
+msgid "Serverless|Serverless was %{linkStart}deprecated%{linkEnd} in GitLab 14.3."
+msgstr ""
+
+msgid "Serverless|Serverless was %{postLinkStart}deprecated%{postLinkEnd}. But if you opt to use it, you must install Knative in your Kubernetes cluster first. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "Serverless|The deploy job has not finished."
@@ -32718,9 +33406,6 @@ 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 ""
@@ -32736,9 +33421,6 @@ msgstr ""
msgid "Service Account Key"
msgstr ""
-msgid "Service Accounts"
-msgstr ""
-
msgid "Service Accounts keys authorize GitLab to deploy your Google Cloud project"
msgstr ""
@@ -32748,10 +33430,10 @@ msgstr ""
msgid "Service Desk allows people to create issues in your GitLab instance without their own user account. It provides a unique email address for end users to create issues in a project. Replies can be sent either through the GitLab interface or by email. End users only see threads through email."
msgstr ""
-msgid "Service Usage Data"
+msgid "Service account generated successfully"
msgstr ""
-msgid "Service account generated successfully"
+msgid "Service accounts"
msgstr ""
msgid "Service ping is disabled in your configuration file, and cannot be enabled through this form."
@@ -32895,6 +33577,9 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
+msgid "Set the per-user rate limit for getting a user by ID via the API."
+msgstr ""
+
msgid "Set the per-user rate limit for notes created by web or API requests."
msgstr ""
@@ -33074,6 +33759,9 @@ msgstr ""
msgid "Shared runners details"
msgstr ""
+msgid "Shared runners enabled cannot be enabled until a valid credit card is on file"
+msgstr ""
+
msgid "Shared runners help link"
msgstr ""
@@ -33131,6 +33819,9 @@ msgstr ""
msgid "Show all issues."
msgstr ""
+msgid "Show all milestones"
+msgstr ""
+
msgid "Show all test cases."
msgstr ""
@@ -33167,6 +33858,9 @@ msgstr ""
msgid "Show file contents"
msgstr ""
+msgid "Show group milestones"
+msgstr ""
+
msgid "Show labels"
msgstr ""
@@ -33182,6 +33876,12 @@ msgstr ""
msgid "Show open epics"
msgstr ""
+msgid "Show project milestones"
+msgstr ""
+
+msgid "Show sub-group milestones"
+msgstr ""
+
msgid "Show the Closed list"
msgstr ""
@@ -33191,11 +33891,6 @@ msgstr ""
msgid "Show whitespace changes"
msgstr ""
-msgid "Showing %d event"
-msgid_plural "Showing %d events"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Showing %{conflict} between %{sourceBranch} and %{targetBranch}"
msgstr ""
@@ -33255,12 +33950,6 @@ msgstr ""
msgid "Sidebar|None"
msgstr ""
-msgid "Sidebar|Only numeral characters allowed"
-msgstr ""
-
-msgid "Sidebar|Weight"
-msgstr ""
-
msgid "Sidekiq job compression threshold (bytes)"
msgstr ""
@@ -33423,6 +34112,9 @@ msgstr ""
msgid "Slack logo"
msgstr ""
+msgid "SlackIntegration|Are you sure you want to remove this project from the Slack application?"
+msgstr ""
+
msgid "SlackIntegration|GitLab for Slack"
msgstr ""
@@ -33432,6 +34124,9 @@ msgstr ""
msgid "SlackIntegration|Project alias"
msgstr ""
+msgid "SlackIntegration|Remove project"
+msgstr ""
+
msgid "SlackIntegration|Select a GitLab project to link with your Slack workspace."
msgstr ""
@@ -33576,9 +34271,6 @@ msgstr ""
msgid "Something went wrong trying to load issue contacts."
msgstr ""
-msgid "Something went wrong when creating a work item. Please try again"
-msgstr ""
-
msgid "Something went wrong when reordering designs. Please try again"
msgstr ""
@@ -33672,9 +34364,6 @@ msgstr ""
msgid "Something went wrong while inserting your image. Please try again."
msgstr ""
-msgid "Something went wrong while merging this merge request. Please try again."
-msgstr ""
-
msgid "Something went wrong while obtaining the Let's Encrypt certificate."
msgstr ""
@@ -33996,10 +34685,10 @@ 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."
+msgid "SourcegraphAdmin|Learn more."
msgstr ""
-msgid "SourcegraphAdmin|More information"
+msgid "SourcegraphAdmin|Only public projects have code intelligence enabled and communicate with Sourcegraph."
msgstr ""
msgid "SourcegraphAdmin|Save changes"
@@ -34008,7 +34697,7 @@ msgstr ""
msgid "SourcegraphAdmin|Sourcegraph URL"
msgstr ""
-msgid "SourcegraphAdmin|e.g. https://sourcegraph.example.com"
+msgid "SourcegraphAdmin|https://sourcegraph.example.com"
msgstr ""
msgid "SourcegraphPreferences|This feature is experimental and currently limited to certain projects."
@@ -34143,6 +34832,9 @@ msgstr ""
msgid "Start date"
msgstr ""
+msgid "Start free trial"
+msgstr ""
+
msgid "Start merge train"
msgstr ""
@@ -34173,6 +34865,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started escalation for this incident."
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -34185,6 +34880,9 @@ msgstr ""
msgid "Starts at (UTC)"
msgstr ""
+msgid "Starts escalations for this incident"
+msgstr ""
+
msgid "Starts on"
msgstr ""
@@ -34446,6 +35144,9 @@ msgstr ""
msgid "Strikethrough"
msgstr ""
+msgid "Strikethrough text"
+msgstr ""
+
msgid "Subgroup information"
msgstr ""
@@ -34680,6 +35381,21 @@ msgstr ""
msgid "Subscriptions"
msgstr ""
+msgid "Subscriptions|Chat with sales"
+msgstr ""
+
+msgid "Subscriptions|Close"
+msgstr ""
+
+msgid "Subscriptions|Not ready to buy yet?"
+msgstr ""
+
+msgid "Subscriptions|Start a free trial"
+msgstr ""
+
+msgid "Subscriptions|We understand. Maybe you have some questions for our sales team, or maybe you'd like to try some of the paid features first. What would you like to do?"
+msgstr ""
+
msgid "Subscription|Your subscription for %{strong}%{namespace_name}%{strong_close} has expired and you are now on %{pricing_link_start}the GitLab Free tier%{pricing_link_end}. Don't worry, your data is safe. Get in touch with our support team (%{support_email}). They'll gladly help with your subscription renewal."
msgstr ""
@@ -34890,6 +35606,9 @@ msgstr ""
msgid "SuperSonics|Maximum users"
msgstr ""
+msgid "SuperSonics|Offline cloud"
+msgstr ""
+
msgid "SuperSonics|Paste your activation code"
msgstr ""
@@ -34956,6 +35675,12 @@ msgstr ""
msgid "SuperSonics|You do not have an active subscription"
msgstr ""
+msgid "SuperSonics|You have a future dated license"
+msgstr ""
+
+msgid "SuperSonics|You have added a license that activates on %{date}. Please see the subscription history table below for more details."
+msgstr ""
+
msgid "SuperSonics|You have successfully added a license that activates on %{date}. Please see the subscription history table below for more details."
msgstr ""
@@ -35115,6 +35840,9 @@ msgstr ""
msgid "Tag name is required"
msgstr ""
+msgid "Tag push"
+msgstr ""
+
msgid "Tag push events"
msgstr ""
@@ -35217,6 +35945,9 @@ msgstr ""
msgid "TagsPage|protected"
msgstr ""
+msgid "Take a look at the documentation to discover all of GitLab’s capabilities."
+msgstr ""
+
msgid "Target Branch"
msgstr ""
@@ -35619,6 +36350,9 @@ msgstr ""
msgid "Tests"
msgstr ""
+msgid "Text (optional)"
+msgstr ""
+
msgid "Text added to the body of all email messages. %{character_limit} character limit"
msgstr ""
@@ -35669,6 +36403,9 @@ msgstr ""
msgid "The CSV export will be created in the background. Once finished, it will be sent to %{email} in an attachment."
msgstr ""
+msgid "The CSV export you requested of all user memberships is attached to this email."
+msgstr ""
+
msgid "The GitLab subscription service (customers.gitlab.com) is currently experiencing an outage. You can monitor the status and get updates at %{linkStart}status.gitlab.com%{linkEnd}."
msgstr ""
@@ -35744,6 +36481,9 @@ 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 epic"
+msgstr ""
+
msgid "The current issue"
msgstr ""
@@ -35905,6 +36645,9 @@ msgstr ""
msgid "The latest pipeline for this merge request has failed."
msgstr ""
+msgid "The license key is invalid."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -35920,6 +36663,9 @@ msgstr ""
msgid "The license was successfully uploaded and will be active from %{starts_at}. You can see the details below."
msgstr ""
+msgid "The license you uploaded is invalid. If the issue persists, contact support at %{link}."
+msgstr ""
+
msgid "The list creation wizard is already open"
msgstr ""
@@ -36541,10 +37287,13 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} and everything this project contains. %{strongOpen}There is no going back%{strongClose}"
+msgstr ""
+
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains."
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}on %{date}%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains. %{strongOpen}There is no going back.%{strongClose}"
msgstr ""
msgid "This action will %{strongOpen}permanently remove%{strongClose} %{codeOpen}%{group}%{codeClose} %{strongOpen}immediately%{strongClose}."
@@ -36673,9 +37422,6 @@ msgstr ""
msgid "This file was modified for readability, and can't accept suggestions. Edit it directly."
msgstr ""
-msgid "This forked project has the following:"
-msgstr ""
-
msgid "This form is disabled in preview"
msgstr ""
@@ -36688,7 +37434,7 @@ msgstr ""
msgid "This group can't be removed because it is linked to a subscription. To remove this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
-msgid "This group can't be transfered because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
+msgid "This group can't be transferred because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
msgid "This group cannot be invited to a project inside a group with enforced SSO"
@@ -36715,6 +37461,9 @@ 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 incident is already escalated with '%{escalation_policy_name}'."
+msgstr ""
+
msgid "This invitation was sent to %{mail_to_invite_email}, but you are signed in as %{link_to_current_user} with email %{mail_to_current_user}."
msgstr ""
@@ -36733,9 +37482,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 merge train pipeline"
-msgstr ""
-
msgid "This is a private email address %{helpIcon} generated just for you. Anyone who has it can create issues or merge requests as if they were you. If that happens, %{resetLinkStart}reset this token%{resetLinkEnd}."
msgstr ""
@@ -36757,6 +37503,12 @@ msgstr ""
msgid "This is your current session"
msgstr ""
+msgid "This issue cannot be assigned to a confidential epic because it is public."
+msgstr ""
+
+msgid "This issue cannot be made public because it belongs to a confidential epic."
+msgstr ""
+
msgid "This issue is confidential and should only be visible to team members with at least Reporter access."
msgstr ""
@@ -36874,6 +37626,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 branch is protected from force push."
+msgstr ""
+
msgid "This merge request cannot be rebased while there are conflicts."
msgstr ""
@@ -36925,9 +37680,15 @@ msgstr ""
msgid "This pipeline was triggered by a schedule."
msgstr ""
+msgid "This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project"
msgstr ""
+msgid "This project can be restored until %{date}."
+msgstr ""
+
msgid "This project cannot be %{visibilityLevel} because the visibility of %{openShowLink}%{name}%{closeShowLink} is %{visibility}. To make this project %{visibilityLevel}, you must first %{openEditLink}change the visibility%{closeEditLink} of the parent group."
msgstr ""
@@ -36946,6 +37707,9 @@ msgstr ""
msgid "This project is %{strongStart}NOT%{strongEnd} a fork, and has the following:"
msgstr ""
+msgid "This project is %{strongStart}NOT%{strongEnd} a fork. This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -37637,6 +38401,9 @@ msgstr ""
msgid "Today"
msgstr ""
+msgid "Todos count"
+msgstr ""
+
msgid "Todos|Are you looking for things to do? Take a look at %{strongStart}%{openIssuesLinkStart}open issues%{openIssuesLinkEnd}%{strongEnd}, contribute to %{strongStart}%{mergeRequestLinkStart}a merge request%{mergeRequestLinkEnd}%{mergeRequestLinkEnd}%{strongEnd}, or mention someone in a comment to automatically assign them a new to-do item."
msgstr ""
@@ -37910,10 +38677,8 @@ msgstr ""
msgid "Trending"
msgstr ""
-msgid "Trials|%{planName} Trial %{enDash} %{num} day left"
-msgid_plural "Trials|%{planName} Trial %{enDash} %{num} days left"
-msgstr[0] ""
-msgstr[1] ""
+msgid "Trials|%{planName} Trial"
+msgstr ""
msgid "Trials|Compare all plans"
msgstr ""
@@ -37921,6 +38686,9 @@ msgstr ""
msgid "Trials|Create a new group to start your GitLab Ultimate trial."
msgstr ""
+msgid "Trials|Day %{daysUsed}/%{duration}"
+msgstr ""
+
msgid "Trials|Go back to GitLab"
msgstr ""
@@ -38170,7 +38938,7 @@ msgstr ""
msgid "URL is triggered when repository is updated"
msgstr ""
-msgid "URL must be percent-encoded if neccessary."
+msgid "URL must be percent-encoded if necessary."
msgstr ""
msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
@@ -38389,6 +39157,9 @@ msgstr ""
msgid "Unlock account"
msgstr ""
+msgid "Unlock more features with GitLab Ultimate"
+msgstr ""
+
msgid "Unlock the discussion"
msgstr ""
@@ -38452,6 +39223,9 @@ msgstr ""
msgid "Unsubscribes from this %{quick_action_target}."
msgstr ""
+msgid "Unsupported sort value."
+msgstr ""
+
msgid "Unsupported todo type passed. Supported todo types are: %{todo_types}"
msgstr ""
@@ -38680,6 +39454,9 @@ msgstr ""
msgid "UsageQuota|File attachments and smaller design graphics."
msgstr ""
+msgid "UsageQuota|From %{storage_enforcement_date} storage limits will apply to this namespace. View and manage your usage in %{strong_start}Group Settings &gt; Usage quotas%{strong_end}."
+msgstr ""
+
msgid "UsageQuota|Git repository."
msgstr ""
@@ -38740,6 +39517,9 @@ msgstr ""
msgid "UsageQuota|Storage type"
msgstr ""
+msgid "UsageQuota|Storage used"
+msgstr ""
+
msgid "UsageQuota|This is the total amount of storage used across your projects within this namespace."
msgstr ""
@@ -38935,6 +39715,12 @@ msgstr ""
msgid "Use hashed storage paths for newly created and renamed repositories. Always enabled since 13.0."
msgstr ""
+msgid "Use issue count"
+msgstr ""
+
+msgid "Use issue weight"
+msgstr ""
+
msgid "Use one line per URI"
msgstr ""
@@ -39316,6 +40102,9 @@ msgstr ""
msgid "Users"
msgstr ""
+msgid "Users API rate limit"
+msgstr ""
+
msgid "Users can launch a development environment from a GitLab browser tab when the %{linkStart}Gitpod%{linkEnd} integration is enabled."
msgstr ""
@@ -39641,6 +40430,9 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View group pipeline usage quota"
+msgstr ""
+
msgid "View incident details at"
msgstr ""
@@ -39793,6 +40585,9 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
+msgid "Vulnerability"
+msgstr ""
+
msgid "Vulnerability Report"
msgstr ""
@@ -39844,6 +40639,9 @@ msgstr ""
msgid "VulnerabilityManagement|An unverified non-confirmed finding"
msgstr ""
+msgid "VulnerabilityManagement|At least one identifier is required"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -39853,12 +40651,24 @@ msgstr ""
msgid "VulnerabilityManagement|Create Jira issue"
msgstr ""
+msgid "VulnerabilityManagement|Enter a name"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE code"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE identifier URL"
+msgstr ""
+
msgid "VulnerabilityManagement|Fetching linked Jira issues"
msgstr ""
msgid "VulnerabilityManagement|Manually add a vulnerability entry into the vulnerability report."
msgstr ""
+msgid "VulnerabilityManagement|Name is a required field"
+msgstr ""
+
msgid "VulnerabilityManagement|Needs triage"
msgstr ""
@@ -39874,6 +40684,18 @@ msgstr ""
msgid "VulnerabilityManagement|Select a method"
msgstr ""
+msgid "VulnerabilityManagement|Select a severity level"
+msgstr ""
+
+msgid "VulnerabilityManagement|Select a status"
+msgstr ""
+
+msgid "VulnerabilityManagement|Severity is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Something went wrong while creating vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -39898,6 +40720,12 @@ msgstr ""
msgid "VulnerabilityManagement|Something went wrong, could not update vulnerability state."
msgstr ""
+msgid "VulnerabilityManagement|Status is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Submit vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Summary, detailed description, steps to reproduce, etc."
msgstr ""
@@ -40093,6 +40921,9 @@ msgstr ""
msgid "WARNING:"
msgstr ""
+msgid "WARNING: This snippet contains hidden files which might be used to mask malicious behavior. Exercise caution if cloning and executing code from this snippet."
+msgstr ""
+
msgid "Wait for the file to load to copy its contents"
msgstr ""
@@ -40312,6 +41143,15 @@ msgstr ""
msgid "Webhooks|An issue is created, updated, closed, or reopened."
msgstr ""
+msgid "Webhooks|Are you sure you want to delete this group hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this project hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this webhook?"
+msgstr ""
+
msgid "Webhooks|Comments"
msgstr ""
@@ -40321,6 +41161,9 @@ msgstr ""
msgid "Webhooks|Confidential issues events"
msgstr ""
+msgid "Webhooks|Delete webhook"
+msgstr ""
+
msgid "Webhooks|Deployment events"
msgstr ""
@@ -40554,6 +41397,9 @@ msgstr ""
msgid "Wiki"
msgstr ""
+msgid "Wiki page"
+msgstr ""
+
msgid "Wiki page was successfully created."
msgstr ""
@@ -40659,7 +41505,7 @@ msgstr ""
msgid "WikiPageConflictMessage|Someone edited the page the same time you did. Please check out %{wikiLinkStart}the page%{wikiLinkEnd} and make sure your changes will not unintentionally remove theirs."
msgstr ""
-msgid "WikiPage|An error occured while trying to render the content editor. Please try again later."
+msgid "WikiPage|An error occurred while trying to render the content editor. Please try again later."
msgstr ""
msgid "WikiPage|Are you sure you want to switch back to the classic editor?"
@@ -40818,6 +41664,18 @@ msgstr ""
msgid "WorkItem|New Task"
msgstr ""
+msgid "WorkItem|Something went wrong when creating a work item. Please try again"
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching the work item. Please try again."
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching work item types. Please try again"
+msgstr ""
+
+msgid "WorkItem|Type"
+msgstr ""
+
msgid "WorkItem|Work Items"
msgstr ""
@@ -40884,7 +41742,10 @@ msgstr ""
msgid "You are about to add %{usersTag} people to the discussion. They will all receive a notification."
msgstr ""
-msgid "You are about to permanently delete this project"
+msgid "You are about to delete this forked project containing:"
+msgstr ""
+
+msgid "You are about to delete this project containing:"
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."
@@ -40905,6 +41766,9 @@ msgstr ""
msgid "You are attempting to update a file that has changed since you started editing it."
msgstr ""
+msgid "You are billed if you exceed this number. %{qsrOverageLinkStart}How does billing work?%{qsrOverageLinkEnd}"
+msgstr ""
+
msgid "You are connected to the Prometheus server, but there is currently no data to display."
msgstr ""
@@ -40962,6 +41826,9 @@ msgstr ""
msgid "You are not authorized to update this scanner profile"
msgstr ""
+msgid "You are not authorized to upload metric images"
+msgstr ""
+
msgid "You are now impersonating %{username}"
msgstr ""
@@ -41115,9 +41982,6 @@ msgstr ""
msgid "You can only upload one design when dropping onto an existing design."
msgstr ""
-msgid "You can recover this project until %{date}"
-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 ""
@@ -41166,9 +42030,6 @@ msgstr ""
msgid "You cannot write to this read-only GitLab instance."
msgstr ""
-msgid "You can’t %{tag_start}edit%{tag_end} files directly in this project. Fork this project and submit a merge request with your changes."
-msgstr ""
-
msgid "You can’t edit files directly in this project. Fork this project and submit a merge request with your changes."
msgstr ""
@@ -41321,9 +42182,6 @@ 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 set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
@@ -41354,12 +42212,6 @@ msgstr ""
msgid "You must have maintainer access to force delete a lock"
msgstr ""
-msgid "You must have permission to create a project in a group before forking."
-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 ""
@@ -41765,7 +42617,7 @@ msgstr ""
msgid "Your public email will be displayed on your public profile."
msgstr ""
-msgid "Your request for access could not be processed: %{error_meesage}"
+msgid "Your request for access could not be processed: %{error_message}"
msgstr ""
msgid "Your request for access has been queued for review."
@@ -41948,6 +42800,9 @@ msgstr ""
msgid "archived:"
msgstr ""
+msgid "artifacts"
+msgstr ""
+
msgid "assign yourself"
msgstr ""
@@ -41977,6 +42832,9 @@ msgstr[1] ""
msgid "branch name"
msgstr ""
+msgid "builds"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -42400,6 +43258,9 @@ msgstr ""
msgid "contact with same email already exists in group hierarchy"
msgstr ""
+msgid "container registry images"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -42439,6 +43300,9 @@ msgstr ""
msgid "data"
msgstr ""
+msgid "database"
+msgstr ""
+
msgid "date must not be after 9999-12-31"
msgstr ""
@@ -42462,9 +43326,6 @@ msgstr ""
msgid "design"
msgstr ""
-msgid "detached"
-msgstr ""
-
msgid "disabled"
msgstr ""
@@ -42713,7 +43574,7 @@ msgstr ""
msgid "is not a valid X509 certificate."
msgstr ""
-msgid "is not allowed for sign-up."
+msgid "is not allowed for sign-up. Please use your regular email address."
msgstr ""
msgid "is not allowed for this group."
@@ -42725,7 +43586,7 @@ msgstr ""
msgid "is not allowed since the group is not top-level group."
msgstr ""
-msgid "is not allowed."
+msgid "is not allowed. Please use your regular email address."
msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
@@ -42812,6 +43673,9 @@ msgstr ""
msgid "level: %{level}"
msgstr ""
+msgid "lfs objects"
+msgstr ""
+
msgid "limit of %{project_limit} reached"
msgstr ""
@@ -43031,6 +43895,9 @@ msgstr ""
msgid "mrWidget|Merge blocked: pipeline must succeed. It's waiting for a manual action to continue."
msgstr ""
+msgid "mrWidget|Merge blocked: pipeline must succeed. Push a commit that fixes the failure, or %{linkStart}learn about other solutions.%{linkEnd}"
+msgstr ""
+
msgid "mrWidget|Merge blocked: this merge request must be approved."
msgstr ""
@@ -43148,9 +44015,6 @@ msgstr ""
msgid "mrWidget|The changes were not merged into"
msgstr ""
-msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -43298,9 +44162,6 @@ msgstr ""
msgid "open issue"
msgstr ""
-msgid "opened %{timeAgo}"
-msgstr ""
-
msgid "or"
msgstr ""
@@ -43312,6 +44173,12 @@ msgid_plural "out of %d total tests"
msgstr[0] ""
msgstr[1] ""
+msgid "packages"
+msgstr ""
+
+msgid "pages"
+msgstr ""
+
msgid "parent"
msgid_plural "parents"
msgstr[0] ""
@@ -43461,6 +44328,9 @@ msgid_plural "replies"
msgstr[0] ""
msgstr[1] ""
+msgid "repositories"
+msgstr ""
+
msgid "repository:"
msgstr ""
@@ -43581,12 +44451,18 @@ msgstr ""
msgid "tag name"
msgstr ""
+msgid "terraform states"
+msgstr ""
+
msgid "the correct format."
msgstr ""
msgid "the file"
msgstr ""
+msgid "the following epic(s)"
+msgstr ""
+
msgid "the following issue(s)"
msgstr ""
@@ -43599,21 +44475,12 @@ msgstr ""
msgid "this document"
msgstr ""
-msgid "this issue cannot be assigned to a confidential epic since it is public"
-msgstr ""
-
-msgid "this issue cannot be made public since it belongs to a confidential epic"
-msgstr ""
-
msgid "time summary"
msgstr ""
msgid "toggle collapse"
msgstr ""
-msgid "train"
-msgstr ""
-
msgid "triggered"
msgstr ""
@@ -43742,3 +44609,6 @@ msgstr ""
msgid "{project}"
msgstr ""
+msgid "✔"
+msgstr ""
+
diff --git a/locale/fa_IR/gitlab.po b/locale/fa_IR/gitlab.po
index b45e2ca7ff3..677cc00c55e 100644
--- a/locale/fa_IR/gitlab.po
+++ b/locale/fa_IR/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: fa\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2022-02-02 15:43\n"
+"PO-Revision-Date: 2022-03-01 20:37\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -146,6 +146,11 @@ msgid_plural "%d approvers (you've approved)"
msgstr[0] ""
msgstr[1] ""
+msgid "%d assigned issue"
+msgid_plural "%d assigned issues"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -421,8 +426,23 @@ msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
msgstr[1] ""
-msgid "%d vulnerability updated"
-msgid_plural "%d vulnerabilities updated"
+msgid "%d vulnerability set to confirmed"
+msgid_plural "%d vulnerabilities set to confirmed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to dismissed"
+msgid_plural "%d vulnerabilities set to dismissed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to needs triage"
+msgid_plural "%d vulnerabilities set to needs triage"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to resolved"
+msgid_plural "%d vulnerabilities set to resolved"
msgstr[0] ""
msgstr[1] ""
@@ -510,6 +530,12 @@ msgstr[1] ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{completed} of %{total} issues closed"
+msgstr ""
+
+msgid "%{completed} of %{total} weight completed"
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -858,6 +884,9 @@ msgstr ""
msgid "%{openedIssues} open, %{closedIssues} closed"
msgstr ""
+msgid "%{percentage}%% issues closed"
+msgstr ""
+
msgid "%{percentage}%% weight completed"
msgstr ""
@@ -1287,6 +1316,9 @@ msgid_plural "- Users"
msgstr[0] ""
msgstr[1] ""
+msgid "- of - issues closed"
+msgstr ""
+
msgid "- of - weight completed"
msgstr ""
@@ -1429,7 +1461,7 @@ msgstr ""
msgid "1000+"
msgstr ""
-msgid "192.168.0.0/24"
+msgid "192.168.0.0/24 or 2001:0DB8:1234::/48"
msgstr ""
msgid "1st contribution!"
@@ -1741,13 +1773,13 @@ msgstr ""
msgid "AWS Access Key"
msgstr ""
-msgid "AWS Access Key. Only required if not using role instance credentials"
+msgid "AWS Secret Access Key"
msgstr ""
-msgid "AWS Secret Access Key"
+msgid "AWS access key ID (Optional)"
msgstr ""
-msgid "AWS Secret Access Key. Only required if not using role instance credentials"
+msgid "AWS secret access key (Optional)"
msgstr ""
msgid "AWS service error: %{error}"
@@ -1807,9 +1839,6 @@ msgstr ""
msgid "Access granted"
msgstr ""
-msgid "Access key ID"
-msgstr ""
-
msgid "Access requests"
msgstr ""
@@ -1984,7 +2013,7 @@ msgstr ""
msgid "Activity"
msgstr ""
-msgid "Activity|An error occured while retrieving activity. Reload the page to try again."
+msgid "Activity|An error occurred while retrieving activity. Reload the page to try again."
msgstr ""
msgid "Add"
@@ -2023,6 +2052,9 @@ msgstr ""
msgid "Add a %{type}"
msgstr ""
+msgid "Add a GCP region"
+msgstr ""
+
msgid "Add a GPG key"
msgstr ""
@@ -2074,6 +2106,9 @@ msgstr ""
msgid "Add a numbered list"
msgstr ""
+msgid "Add a related epic"
+msgstr ""
+
msgid "Add a related issue"
msgstr ""
@@ -2188,6 +2223,9 @@ msgstr ""
msgid "Add or subtract spent time"
msgstr ""
+msgid "Add people"
+msgstr ""
+
msgid "Add previously merged commits"
msgstr ""
@@ -2254,6 +2292,9 @@ msgstr ""
msgid "Add webhook"
msgstr ""
+msgid "Add your team members and others to GitLab."
+msgstr ""
+
msgid "Add/remove"
msgstr ""
@@ -3076,12 +3117,6 @@ msgstr ""
msgid "AdvancedSearch|Reindex required"
msgstr ""
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. Permanently deleting this project will %{strongStart}immediately delete%{strongEnd} its repositories and %{strongStart}all related resources%{strongEnd}, including issues, merge requests etc."
-msgstr ""
-
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. You will lose this project's repository and %{strongStart}all related resources%{strongEnd}, including issues and merge requests."
-msgstr ""
-
msgid "After a successful password update you will be redirected to login screen."
msgstr ""
@@ -3112,6 +3147,9 @@ msgstr ""
msgid "Akismet helps prevent the creation of spam issues in public projects."
msgstr ""
+msgid "Alert"
+msgstr ""
+
msgid "AlertManagement|Acknowledged"
msgstr ""
@@ -3484,9 +3522,6 @@ msgstr ""
msgid "All environments"
msgstr ""
-msgid "All epics"
-msgstr ""
-
msgid "All groups and projects"
msgstr ""
@@ -4223,12 +4258,15 @@ msgstr ""
msgid "ApplicationSettings|Approve users in the pending approval status?"
msgstr ""
-msgid "ApplicationSettings|By making this change, you will automatically approve %d user with the pending approval status."
-msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users with the pending approval status."
+msgid "ApplicationSettings|Approve users who are pending approval?"
+msgstr ""
+
+msgid "ApplicationSettings|By making this change, you will automatically approve %d user who is pending approval."
+msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users who are pending approval."
msgstr[0] ""
msgstr[1] ""
-msgid "ApplicationSettings|By making this change, you will automatically approve all users in pending approval status."
+msgid "ApplicationSettings|By making this change, you will automatically approve all users who are pending approval."
msgstr ""
msgid "ApplicationSettings|Denied domains for sign-ups"
@@ -4634,10 +4672,10 @@ msgstr ""
msgid "Archiving the project will make it entirely read-only. It is hidden from the dashboard and doesn't show up in searches. %{strong_start}The repository cannot be committed to, and no issues, comments, or other entities can be created.%{strong_end} %{link_start}Learn more.%{link_end}"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to delete this project?"
+msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
+msgid "Are you absolutely sure?"
msgstr ""
msgid "Are you sure that you want to archive this project?"
@@ -4673,12 +4711,18 @@ msgstr ""
msgid "Are you sure you want to delete this SSH key?"
msgstr ""
+msgid "Are you sure you want to delete this comment?"
+msgstr ""
+
msgid "Are you sure you want to delete this deploy key?"
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 label?"
+msgstr ""
+
msgid "Are you sure you want to delete this pipeline schedule?"
msgstr ""
@@ -4694,9 +4738,6 @@ msgstr ""
msgid "Are you sure you want to discard your changes?"
msgstr ""
-msgid "Are you sure you want to erase this build?"
-msgstr ""
-
msgid "Are you sure you want to import %d repository?"
msgid_plural "Are you sure you want to import %d repositories?"
msgstr[0] ""
@@ -4744,6 +4785,9 @@ msgstr ""
msgid "Are you sure you want to remove this list?"
msgstr ""
+msgid "Are you sure you want to remove this nickname?"
+msgstr ""
+
msgid "Are you sure you want to reset the health check token?"
msgstr ""
@@ -4756,10 +4800,10 @@ 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?"
+msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
msgstr ""
-msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
+msgid "Are you sure you want to revoke this project access token? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to stop this environment?"
@@ -4906,9 +4950,6 @@ msgstr ""
msgid "Assigned to %{assignee_name}"
msgstr ""
-msgid "Assigned to %{name}"
-msgstr ""
-
msgid "Assigned to me"
msgstr ""
@@ -4973,6 +5014,9 @@ msgstr[1] ""
msgid "Attaching the file failed."
msgstr ""
+msgid "Attention"
+msgstr ""
+
msgid "Audit Events"
msgstr ""
@@ -5135,6 +5179,12 @@ msgstr ""
msgid "Authorized applications (%{size})"
msgstr ""
+msgid "AuthorizedApplication|Are you sure you want to revoke this application?"
+msgstr ""
+
+msgid "AuthorizedApplication|Revoke application"
+msgstr ""
+
msgid "Authors: %{authors}"
msgstr ""
@@ -6328,6 +6378,9 @@ msgstr ""
msgid "CICDAnalytics|Shared Runners Usage"
msgstr ""
+msgid "CICDAnalytics|Shared runner pipeline minute duration by month"
+msgstr ""
+
msgid "CICDAnalytics|Shared runner usage"
msgstr ""
@@ -6469,6 +6522,9 @@ msgstr ""
msgid "Can create groups:"
msgstr ""
+msgid "Can not delete primary training"
+msgstr ""
+
msgid "Can't apply as the source branch was deleted."
msgstr ""
@@ -6802,9 +6858,6 @@ msgstr ""
msgid "Changing any setting here requires an application restart"
msgstr ""
-msgid "Changing group URL can have unintended side effects."
-msgstr ""
-
msgid "Charts can't be displayed as the request for data has timed out. %{documentationLink}"
msgstr ""
@@ -6892,9 +6945,6 @@ msgstr ""
msgid "Checking branch availability..."
msgstr ""
-msgid "Checking group URL availability..."
-msgstr ""
-
msgid "Checking group path availability..."
msgstr ""
@@ -7388,6 +7438,9 @@ msgstr ""
msgid "Clear recent searches"
msgstr ""
+msgid "Clear repository checks"
+msgstr ""
+
msgid "Clear search"
msgstr ""
@@ -7520,9 +7573,6 @@ msgstr ""
msgid "Closed MRs"
msgstr ""
-msgid "Closed epics"
-msgstr ""
-
msgid "Closed issues"
msgstr ""
@@ -7559,13 +7609,13 @@ msgstr ""
msgid "Cluster level"
msgstr ""
-msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
+msgid "Cluster type must be specified for Stages::ClusterEndpointInserter"
msgstr ""
msgid "ClusterAgents|%{name} successfully deleted"
msgstr ""
-msgid "ClusterAgents|%{number} of %{total} Agents"
+msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
@@ -7607,6 +7657,15 @@ msgstr ""
msgid "ClusterAgents|Agent never connected to GitLab"
msgstr ""
+msgid "ClusterAgents|Agent version mismatch"
+msgstr ""
+
+msgid "ClusterAgents|Agent version mismatch and update"
+msgstr ""
+
+msgid "ClusterAgents|Agent version update required"
+msgstr ""
+
msgid "ClusterAgents|All"
msgstr ""
@@ -7631,7 +7690,7 @@ msgstr ""
msgid "ClusterAgents|Configuration"
msgstr ""
-msgid "ClusterAgents|Connect a cluster through the Agent"
+msgid "ClusterAgents|Connect a cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connect existing cluster"
@@ -7640,13 +7699,13 @@ msgstr ""
msgid "ClusterAgents|Connect with a certificate"
msgstr ""
-msgid "ClusterAgents|Connect with agent"
+msgid "ClusterAgents|Connect with an agent"
msgstr ""
msgid "ClusterAgents|Connect with the GitLab Agent"
msgstr ""
-msgid "ClusterAgents|Connect your cluster through the Agent"
+msgid "ClusterAgents|Connect your cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connected"
@@ -7706,7 +7765,10 @@ msgstr ""
msgid "ClusterAgents|How to register an agent?"
msgstr ""
-msgid "ClusterAgents|Install new Agent"
+msgid "ClusterAgents|How to update an agent?"
+msgstr ""
+
+msgid "ClusterAgents|Install a new agent"
msgstr ""
msgid "ClusterAgents|Last connected %{timeAgo}."
@@ -7733,7 +7795,7 @@ msgstr ""
msgid "ClusterAgents|Never connected"
msgstr ""
-msgid "ClusterAgents|No Agents"
+msgid "ClusterAgents|No agents"
msgstr ""
msgid "ClusterAgents|No clusters connected through cluster certificates"
@@ -7793,6 +7855,9 @@ msgstr ""
msgid "ClusterAgents|The agent has not been connected in a long time. There might be a connectivity issue. Last contact was %{timeAgo}."
msgstr ""
+msgid "ClusterAgents|The agent version do not match each other across your cluster's pods. This can happen when a new agent version was just deployed and Kubernetes is shutting down the old pods."
+msgstr ""
+
msgid "ClusterAgents|The recommended installation method includes the token. If you want to follow the advanced installation method provided in the docs, make sure you save the token value before you close this window."
msgstr ""
@@ -7840,6 +7905,9 @@ msgstr ""
msgid "ClusterAgents|You will need to create a token to connect to your agent"
msgstr ""
+msgid "ClusterAgents|Your agent version is out of sync with your GitLab version (v%{version}), which might cause compatibility problems. Update the agent installed on your cluster to the most recent version."
+msgstr ""
+
msgid "ClusterAgents|Your instance doesn't have the %{linkStart}GitLab Agent Server (KAS)%{linkEnd} set up. Ask a GitLab Administrator to install it."
msgstr ""
@@ -8716,9 +8784,6 @@ msgstr ""
msgid "Comma-separated list of email addresses."
msgstr ""
-msgid "Comma-separated list of users allowed to exceed the rate limit."
-msgstr ""
-
msgid "Comma-separated, e.g. '1.1.1.1, 2.2.2.0/24'"
msgstr ""
@@ -9045,6 +9110,12 @@ msgstr ""
msgid "Confidential"
msgstr ""
+msgid "Confidential issue"
+msgstr ""
+
+msgid "Confidential note"
+msgstr ""
+
msgid "Confidentiality"
msgstr ""
@@ -9078,6 +9149,9 @@ msgstr ""
msgid "Configure Dependency Scanning in `.gitlab-ci.yml`, creating this file if it does not already exist"
msgstr ""
+msgid "Configure GitLab"
+msgstr ""
+
msgid "Configure GitLab runners to start using the Web Terminal. %{helpStart}Learn more.%{helpEnd}"
msgstr ""
@@ -9126,6 +9200,15 @@ msgstr ""
msgid "Configure pipelines to deploy web apps, backend services, APIs and static resources to Google Cloud"
msgstr ""
+msgid "Configure region"
+msgstr ""
+
+msgid "Configure region for environment"
+msgstr ""
+
+msgid "Configure regions"
+msgstr ""
+
msgid "Configure repository mirroring."
msgstr ""
@@ -9159,6 +9242,9 @@ msgstr ""
msgid "Configure which lists are shown for anyone who visits this board"
msgstr ""
+msgid "Configure your environments to be deployed to specific geographical regions"
+msgstr ""
+
msgid "Confirm"
msgstr ""
@@ -9861,10 +9947,10 @@ msgstr ""
msgid "CorpusManagement|Actions"
msgstr ""
-msgid "CorpusManagement|Corpus are used in fuzz testing as mutation source to Improve future testing."
+msgid "CorpusManagement|Corpus file"
msgstr ""
-msgid "CorpusManagement|Corpus file"
+msgid "CorpusManagement|Corpus files are used in coverage-guided fuzz testing as seed inputs to improve testing."
msgstr ""
msgid "CorpusManagement|Corpus files must be in *.zip format. Maximum 5 GB"
@@ -9918,6 +10004,9 @@ msgstr ""
msgid "Could not apply %{name} command."
msgstr ""
+msgid "Could not apply %{name} command. %{message}."
+msgstr ""
+
msgid "Could not authorize chat nickname. Try again!"
msgstr ""
@@ -10068,6 +10157,9 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
+msgid "Create a group"
+msgstr ""
+
msgid "Create a merge request"
msgstr ""
@@ -10092,6 +10184,9 @@ msgstr ""
msgid "Create a personal access token on your account to pull or push via %{protocol}."
msgstr ""
+msgid "Create a project"
+msgstr ""
+
msgid "Create an account using:"
msgstr ""
@@ -10455,6 +10550,9 @@ msgstr ""
msgid "Creation date"
msgstr ""
+msgid "Creator"
+msgstr ""
+
msgid "Credentials"
msgstr ""
@@ -10467,9 +10565,15 @@ msgstr ""
msgid "CredentialsInventory|Personal Access Tokens"
msgstr ""
+msgid "CredentialsInventory|Project Access Tokens"
+msgstr ""
+
msgid "CredentialsInventory|SSH Keys"
msgstr ""
+msgid "Credit card required to be on file in order to create a pipeline"
+msgstr ""
+
msgid "Credit card:"
msgstr ""
@@ -10653,9 +10757,6 @@ msgstr ""
msgid "Customer relations"
msgstr ""
-msgid "Customizable by an administrator."
-msgstr ""
-
msgid "Customizable by owners."
msgstr ""
@@ -10785,30 +10886,18 @@ msgstr ""
msgid "CycleAnalytics|%{selectedLabelsCount} selected (%{maxLabels} max)"
msgstr ""
-msgid "CycleAnalytics|%{stageCount} stages selected"
-msgstr ""
-
-msgid "CycleAnalytics|All stages"
-msgstr ""
-
-msgid "CycleAnalytics|Average days to completion"
+msgid "CycleAnalytics|Average time to completion"
msgstr ""
msgid "CycleAnalytics|Date"
msgstr ""
-msgid "CycleAnalytics|Days to completion"
-msgstr ""
-
msgid "CycleAnalytics|Display chart filters"
msgstr ""
msgid "CycleAnalytics|Lead Time for Changes"
msgstr ""
-msgid "CycleAnalytics|No stages selected"
-msgstr ""
-
msgid "CycleAnalytics|Number of tasks"
msgstr ""
@@ -10837,18 +10926,30 @@ msgstr ""
msgid "CycleAnalytics|Showing data for group '%{groupName}' from %{createdAfter} to %{createdBefore}"
msgstr ""
-msgid "CycleAnalytics|Stages"
+msgid "CycleAnalytics|Stage time: %{title}"
msgstr ""
msgid "CycleAnalytics|Tasks by type"
msgstr ""
-msgid "CycleAnalytics|The average time spent in the selected stage for the items that were completed on each date. Data limited to the last 500 items."
+msgid "CycleAnalytics|The average time items spent in this stage. Data limited to items completed within this date range."
msgstr ""
msgid "CycleAnalytics|The given date range is larger than 180 days"
msgstr ""
+msgid "CycleAnalytics|The total time items spent across each value stream stage. Data limited to items completed within this date range."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Stage time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Total time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|Total time"
+msgstr ""
+
msgid "CycleAnalytics|Type of work"
msgstr ""
@@ -10861,9 +10962,6 @@ msgstr ""
msgid "CycleAnalytics|project dropdown filter"
msgstr ""
-msgid "CycleAnalytics|stage dropdown"
-msgstr ""
-
msgid "DAG visualization requires at least 3 dependent jobs."
msgstr ""
@@ -10963,10 +11061,16 @@ msgstr ""
msgid "DastProfiles|AJAX spider"
msgstr ""
+msgid "DastProfiles|API"
+msgstr ""
+
+msgid "DastProfiles|API endpoint URL"
+msgstr ""
+
msgid "DastProfiles|Active"
msgstr ""
-msgid "DastProfiles|Additional request headers (Optional)"
+msgid "DastProfiles|Additional request headers (optional)"
msgstr ""
msgid "DastProfiles|Are you sure you want to delete this profile?"
@@ -10981,6 +11085,9 @@ msgstr ""
msgid "DastProfiles|Branch missing"
msgstr ""
+msgid "DastProfiles|Choose a scan method"
+msgstr ""
+
msgid "DastProfiles|Could not create the scanner profile. Please try again."
msgstr ""
@@ -11050,7 +11157,13 @@ msgstr ""
msgid "DastProfiles|Excluded URLs"
msgstr ""
-msgid "DastProfiles|Excluded URLs (Optional)"
+msgid "DastProfiles|Excluded URLs (optional)"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths (optional)"
msgstr ""
msgid "DastProfiles|Hide debug messages"
@@ -11107,9 +11220,6 @@ msgstr ""
msgid "DastProfiles|Request headers"
msgstr ""
-msgid "DastProfiles|Rest API"
-msgstr ""
-
msgid "DastProfiles|Run the AJAX spider, in addition to the traditional spider, to crawl the target site."
msgstr ""
@@ -11119,6 +11229,9 @@ msgstr ""
msgid "DastProfiles|Save profile"
msgstr ""
+msgid "DastProfiles|Scan method"
+msgstr ""
+
msgid "DastProfiles|Scan mode"
msgstr ""
@@ -11197,12 +11310,24 @@ msgstr ""
msgid "DastProfiles|Website"
msgstr ""
+msgid "DastProfiles|What does each method do?"
+msgstr ""
+
msgid "DastProfiles|You can either choose a passive scan or validate the target site from the site profile management page. %{docsLinkStart}Learn more about site validation.%{docsLinkEnd}"
msgstr ""
msgid "DastProfiles|You cannot run an active scan against an unvalidated site."
msgstr ""
+msgid "DastProfiles|folder/dast_example.har or https://example.com/dast_example.har"
+msgstr ""
+
+msgid "DastProfiles|folder/example.postman_collection.json or https://example.com/"
+msgstr ""
+
+msgid "DastProfiles|folder/openapi.json or https://example.com/openapi.json"
+msgstr ""
+
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
@@ -11310,6 +11435,9 @@ msgstr ""
msgid "DatadogIntegration|API URL"
msgstr ""
+msgid "DatadogIntegration|Custom tags in Datadog. Enter one tag per line in the %{codeOpen}key:value%{codeClose} format. %{linkOpen}How do I use tags?%{linkClose}"
+msgstr ""
+
msgid "DatadogIntegration|Environment"
msgstr ""
@@ -11328,12 +11456,18 @@ msgstr ""
msgid "DatadogIntegration|Tag all data from this GitLab instance in Datadog. Useful when managing several self-managed deployments."
msgstr ""
+msgid "DatadogIntegration|Tags"
+msgstr ""
+
msgid "DatadogIntegration|The Datadog site to send data to. To send data to the EU site, use %{codeOpen}datadoghq.eu%{codeClose}."
msgstr ""
msgid "DatadogIntegration|Trace your GitLab pipelines with Datadog."
msgstr ""
+msgid "DatadogIntegration|have an invalid format"
+msgstr ""
+
msgid "Datasource name not found"
msgstr ""
@@ -11343,9 +11477,6 @@ msgstr ""
msgid "Date merged"
msgstr ""
-msgid "Date picker"
-msgstr ""
-
msgid "Date range"
msgstr ""
@@ -11499,9 +11630,6 @@ msgstr ""
msgid "Definition"
msgstr ""
-msgid "Delayed Project Deletion (%{adjourned_deletion})"
-msgstr ""
-
msgid "DelayedJobs|Are you sure you want to run %{jobName} immediately? Otherwise this job will run automatically after its timer finishes."
msgstr ""
@@ -11580,10 +11708,10 @@ msgstr ""
msgid "Delete pipeline"
msgstr ""
-msgid "Delete project"
+msgid "Delete pipeline schedule"
msgstr ""
-msgid "Delete project. Are you ABSOLUTELY SURE?"
+msgid "Delete project"
msgstr ""
msgid "Delete row"
@@ -11613,6 +11741,9 @@ msgstr ""
msgid "Delete this epic and all descendants?"
msgstr ""
+msgid "Delete this project"
+msgstr ""
+
msgid "Delete user list"
msgstr ""
@@ -11871,6 +12002,12 @@ msgstr ""
msgid "Deploy to..."
msgstr ""
+msgid "DeployBoards|To see deployment progress for your environments, make sure you are deploying to %{codeStart}$KUBE_NAMESPACE%{codeEnd} and annotating with %{codeStart}app.gitlab.com/app=$CI_PROJECT_PATH_SLUG%{codeEnd} and %{codeStart}app.gitlab.com/env=$CI_ENVIRONMENT_SLUG%{codeEnd}."
+msgstr ""
+
+msgid "DeployBoard|Kubernetes Pods"
+msgstr ""
+
msgid "DeployFreeze|Add a freeze period to prevent unintended releases during a period of time for a given environment. You must update the deployment jobs in %{filename} according to the deploy freezes added here. %{freeze_period_link_start}Learn more.%{freeze_period_link_end}"
msgstr ""
@@ -11955,9 +12092,6 @@ msgstr ""
msgid "DeployTokens|Active Deploy Tokens (%{active_tokens})"
msgstr ""
-msgid "DeployTokens|Allows read and write access to registry images."
-msgstr ""
-
msgid "DeployTokens|Allows read and write access to the package registry."
msgstr ""
@@ -11970,6 +12104,9 @@ msgstr ""
msgid "DeployTokens|Allows read-only access to the repository."
msgstr ""
+msgid "DeployTokens|Allows write access to registry images."
+msgstr ""
+
msgid "DeployTokens|Copy deploy token"
msgstr ""
@@ -12063,12 +12200,57 @@ msgstr ""
msgid "Deploying to AWS is easy with GitLab"
msgstr ""
+msgid "Deployment"
+msgstr ""
+
msgid "Deployment Frequency"
msgstr ""
+msgid "Deployment Target|Project deployment target (optional)"
+msgstr ""
+
+msgid "Deployment Target|Select the deployment target"
+msgstr ""
+
msgid "Deployment frequency"
msgstr ""
+msgid "DeploymentTarget|GitLab Pages"
+msgstr ""
+
+msgid "DeploymentTarget|Heroku"
+msgstr ""
+
+msgid "DeploymentTarget|Infrastructure provider (Terraform, Cloudformation, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Kubernetes (GKE, EKS, OpenShift, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Managed container runtime (Fargate, Cloud Run, DigitalOcean App)"
+msgstr ""
+
+msgid "DeploymentTarget|Mobile app store"
+msgstr ""
+
+msgid "DeploymentTarget|No deployment planned"
+msgstr ""
+
+msgid "DeploymentTarget|Other hosting service"
+msgstr ""
+
+msgid "DeploymentTarget|Registry (package or container)"
+msgstr ""
+
+msgid "DeploymentTarget|Self-managed container runtime (Podman, Docker Swarm, Docker Compose)"
+msgstr ""
+
+msgid "DeploymentTarget|Serverless backend (Lambda, Cloud functions)"
+msgstr ""
+
+msgid "DeploymentTarget|Virtual machine (for example, EC2)"
+msgstr ""
+
msgid "Deployments"
msgstr ""
@@ -12107,6 +12289,9 @@ msgstr ""
msgid "Deployment|This deployment was created using the API"
msgstr ""
+msgid "Deployment|Triggerer"
+msgstr ""
+
msgid "Deployment|Waiting"
msgstr ""
@@ -12134,6 +12319,18 @@ msgstr ""
msgid "Deprecated API rate limits"
msgstr ""
+msgid "Deprecations|Feature deprecation and removal"
+msgstr ""
+
+msgid "Deprecations|For information on a possible replacement %{epicStart} learn more about Opstrace %{epicEnd}."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7 and are %{epicStart} scheduled for removal %{epicEnd} in GitLab 15.0."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7, and are %{removal_link_start} scheduled for removal %{link_end} in GitLab 15.0. For information on a possible replacement, %{opstrace_link_start} learn more about Opstrace %{link_end}."
+msgstr ""
+
msgid "Deprioritize label"
msgstr ""
@@ -12379,10 +12576,10 @@ msgstr ""
msgid "DevopsAdoption|At least one deploy"
msgstr ""
-msgid "DevopsAdoption|At least one issue opened"
+msgid "DevopsAdoption|At least one issue created"
msgstr ""
-msgid "DevopsAdoption|At least one merge request opened"
+msgid "DevopsAdoption|At least one merge request created"
msgstr ""
msgid "DevopsAdoption|At least one pipeline successfully run"
@@ -12583,6 +12780,9 @@ msgstr ""
msgid "Direct member"
msgstr ""
+msgid "Direct members"
+msgstr ""
+
msgid "Direct non-authenticated users to this page."
msgstr ""
@@ -12699,6 +12899,9 @@ msgid_plural "Dismiss %d selected vulnerabilities as"
msgstr[0] ""
msgstr[1] ""
+msgid "Dismiss Alert"
+msgstr ""
+
msgid "Dismiss merge request promotion"
msgstr ""
@@ -12726,9 +12929,15 @@ msgstr ""
msgid "Display alerts from all configured monitoring tools."
msgstr ""
+msgid "Display milestones"
+msgstr ""
+
msgid "Display name"
msgstr ""
+msgid "Display progress of child issues"
+msgstr ""
+
msgid "Display rendered file"
msgstr ""
@@ -12834,6 +13043,9 @@ msgstr ""
msgid "Download image"
msgstr ""
+msgid "Download payload"
+msgstr ""
+
msgid "Download raw data (.csv)"
msgstr ""
@@ -13011,6 +13223,9 @@ msgstr ""
msgid "Edit in Web IDE"
msgstr ""
+msgid "Edit in pipeline editor"
+msgstr ""
+
msgid "Edit in single-file editor"
msgstr ""
@@ -13053,6 +13268,9 @@ msgstr ""
msgid "Edit your most recent comment in a thread (from an empty textarea)"
msgstr ""
+msgid "Edit, lint, and visualize your pipeline."
+msgstr ""
+
msgid "Edited"
msgstr ""
@@ -13494,6 +13712,9 @@ msgstr ""
msgid "Enforce two-factor authentication for all user sign-ins."
msgstr ""
+msgid "Enhance security by storing service account keys in secret managers - learn more about %{docLinkStart}secret management with GitLab%{docLinkEnd}"
+msgstr ""
+
msgid "Ensure connectivity is available from the GitLab server to the Prometheus server"
msgstr ""
@@ -13554,6 +13775,9 @@ 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 following to confirm:"
+msgstr ""
+
msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
@@ -14084,9 +14308,6 @@ 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 ""
@@ -14222,6 +14443,9 @@ msgstr ""
msgid "Errors:"
msgstr ""
+msgid "Escalate this incident"
+msgstr ""
+
msgid "Escalation Policies"
msgstr ""
@@ -14234,6 +14458,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy"
+msgstr ""
+
msgid "Escalation policy:"
msgstr ""
@@ -14485,6 +14712,9 @@ msgstr ""
msgid "Existing sign in methods may be removed"
msgstr ""
+msgid "Exit."
+msgstr ""
+
msgid "Expand"
msgstr ""
@@ -14581,6 +14811,9 @@ msgstr ""
msgid "Explore public groups"
msgstr ""
+msgid "Explore public projects"
+msgstr ""
+
msgid "Explore snippets"
msgstr ""
@@ -14742,7 +14975,7 @@ msgid_plural "Failed to archive designs. Please try again."
msgstr[0] ""
msgstr[1] ""
-msgid "Failed to assign a reviewer because no user was found."
+msgid "Failed to assign a reviewer because no user was specified."
msgstr ""
msgid "Failed to assign a user because no user was found."
@@ -14808,10 +15041,10 @@ msgstr ""
msgid "Failed to find import label for Jira import."
msgstr ""
-msgid "Failed to generate export, please try again later."
+msgid "Failed to find users for %{missing}"
msgstr ""
-msgid "Failed to generate report, please try again after sometime"
+msgid "Failed to generate export, please try again later."
msgstr ""
msgid "Failed to get ref."
@@ -14910,6 +15143,9 @@ msgstr ""
msgid "Failed to remove a to-do item for the design."
msgstr ""
+msgid "Failed to remove attention because no user was found."
+msgstr ""
+
msgid "Failed to remove mirror."
msgstr ""
@@ -14922,6 +15158,9 @@ msgstr ""
msgid "Failed to remove user key."
msgstr ""
+msgid "Failed to request attention because no user was found."
+msgstr ""
+
msgid "Failed to reset key. Please try again."
msgstr ""
@@ -15003,6 +15242,9 @@ msgstr ""
msgid "Feature Flags"
msgstr ""
+msgid "Feature deprecation and removal"
+msgstr ""
+
msgid "Feature flag status"
msgstr ""
@@ -15500,7 +15742,7 @@ msgstr ""
msgid "For each job, re-use the project workspace. If the workspace doesn't exist, use %{code_open}git clone%{code_close}."
msgstr ""
-msgid "For example, the application using the token or the purpose of the token."
+msgid "For example, the application using the token or the purpose of the token. Do not give sensitive information for the name of the token, as it will be visible to all %{resource_type} members."
msgstr ""
msgid "For files larger than this limit, only index the file name. The file content is neither indexed nor searchable."
@@ -15584,9 +15826,6 @@ msgstr ""
msgid "ForkProject|Select a namespace"
msgstr ""
-msgid "ForkProject|Select a namespace to fork the project"
-msgstr ""
-
msgid "ForkProject|The project can be accessed by any logged in user."
msgstr ""
@@ -15683,6 +15922,9 @@ msgstr ""
msgid "Full name"
msgstr ""
+msgid "GCP region configured"
+msgstr ""
+
msgid "GPG Key ID:"
msgstr ""
@@ -15863,6 +16105,9 @@ msgstr ""
msgid "Geo|Failed"
msgstr ""
+msgid "Geo|Filter Geo sites"
+msgstr ""
+
msgid "Geo|Filter by name"
msgstr ""
@@ -16274,6 +16519,12 @@ msgstr ""
msgid "GitLab Issue"
msgstr ""
+msgid "GitLab KAS"
+msgstr ""
+
+msgid "GitLab Memberships CSV Export"
+msgstr ""
+
msgid "GitLab Pages"
msgstr ""
@@ -16322,6 +16573,9 @@ 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 free to use. Many features for larger teams are part of our %{link_start}paid products%{link_end}. You can try Ultimate for free without any obligation or payment details."
+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 ""
@@ -16448,7 +16702,7 @@ msgstr ""
msgid "GitLabPages|When enabled, all attempts to visit your website through HTTP are automatically redirected to HTTPS using a response with status code 301. Requires a valid certificate for all domains. %{docs_link_start}Learn more.%{link_end}"
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. %{docs_link_start}Learn more.%{link_end}"
+msgid "GitLabPages|When using Pages under the general domain of a GitLab instance (%{pages_host}), you cannot use HTTPS with subdomains of subdomains. If your namespace or groupname contains a dot, it does not work. This is a limitation of the HTTP Over TLS protocol. HTTP pages work if you don't redirect HTTP to HTTPS. %{docs_link_start}Learn more.%{link_end}"
msgstr ""
msgid "GitLabPages|With GitLab Pages you can host your static website directly from your GitLab repository. %{docs_link_start}Learn more.%{link_end}"
@@ -16625,9 +16879,6 @@ msgstr ""
msgid "Go to find file"
msgstr ""
-msgid "Go to fork"
-msgstr ""
-
msgid "Go to issue boards"
msgstr ""
@@ -16835,9 +17086,6 @@ msgstr ""
msgid "Group Hooks"
msgstr ""
-msgid "Group ID"
-msgstr ""
-
msgid "Group Owner must have signed in with SAML before enabling Group Managed Accounts"
msgstr ""
@@ -16865,9 +17113,6 @@ msgstr ""
msgid "Group by"
msgstr ""
-msgid "Group description"
-msgstr ""
-
msgid "Group description (optional)"
msgstr ""
@@ -16982,7 +17227,7 @@ msgstr ""
msgid "Group: %{name}"
msgstr ""
-msgid "GroupActivityMetrics|Issues opened"
+msgid "GroupActivityMetrics|Issues created"
msgstr ""
msgid "GroupActivityMetrics|Last 90 days"
@@ -16991,7 +17236,7 @@ msgstr ""
msgid "GroupActivityMetrics|Members added"
msgstr ""
-msgid "GroupActivityMetrics|Merge Requests opened"
+msgid "GroupActivityMetrics|Merge Requests created"
msgstr ""
msgid "GroupActivityMetrics|Recent activity"
@@ -17282,6 +17527,9 @@ msgstr ""
msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
+msgid "GroupSettings|Choose a group path that does not start with a dash or end with a period. It can also contain alphanumeric characters and underscores."
+msgstr ""
+
msgid "GroupSettings|Compliance frameworks"
msgstr ""
@@ -17315,7 +17563,7 @@ msgstr ""
msgid "GroupSettings|If not specified at the group or instance level, the default is %{default_initial_branch_name}. Does not affect existing repositories."
msgstr ""
-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."
+msgid "GroupSettings|If the parent group's visibility is lower than the group's current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility."
msgstr ""
msgid "GroupSettings|New runners registration token has been generated!"
@@ -17432,7 +17680,10 @@ msgstr ""
msgid "Groups and projects"
msgstr ""
-msgid "Groups and subgroups"
+msgid "Groups are a great way to organize projects and people."
+msgstr ""
+
+msgid "Groups are the best way to manage projects and members."
msgstr ""
msgid "Groups to synchronize"
@@ -17543,13 +17794,16 @@ msgstr ""
msgid "GroupsTree|Are you sure you want to leave the \"%{fullName}\" group?"
msgstr ""
-msgid "GroupsTree|Edit group"
+msgid "GroupsTree|Delete"
+msgstr ""
+
+msgid "GroupsTree|Edit"
msgstr ""
msgid "GroupsTree|Failed to leave the group. Please make sure you are not the only owner."
msgstr ""
-msgid "GroupsTree|Leave this group"
+msgid "GroupsTree|Leave group"
msgstr ""
msgid "GroupsTree|Loading groups"
@@ -17561,9 +17815,57 @@ msgstr ""
msgid "GroupsTree|No groups or projects matched your search"
msgstr ""
+msgid "GroupsTree|Options"
+msgstr ""
+
msgid "GroupsTree|Search by name"
msgstr ""
+msgid "Groups|Avatar will be removed. Are you sure?"
+msgstr ""
+
+msgid "Groups|Changing group URL can have unintended side effects."
+msgstr ""
+
+msgid "Groups|Checking group URL availability..."
+msgstr ""
+
+msgid "Groups|Enter a descriptive name for your group."
+msgstr ""
+
+msgid "Groups|Group ID"
+msgstr ""
+
+msgid "Groups|Group URL"
+msgstr ""
+
+msgid "Groups|Group avatar"
+msgstr ""
+
+msgid "Groups|Group description (optional)"
+msgstr ""
+
+msgid "Groups|Group name"
+msgstr ""
+
+msgid "Groups|Group path is available."
+msgstr ""
+
+msgid "Groups|Group path is unavailable. Path has been replaced with a suggested available path."
+msgstr ""
+
+msgid "Groups|Learn more"
+msgstr ""
+
+msgid "Groups|Must start with letter, digit, emoji, or underscore. Can also contain periods, dashes, spaces, and parentheses."
+msgstr ""
+
+msgid "Groups|Remove avatar"
+msgstr ""
+
+msgid "Groups|Save changes"
+msgstr ""
+
msgid "Guideline"
msgstr ""
@@ -17573,6 +17875,9 @@ msgstr ""
msgid "HAR file path or URL"
msgstr ""
+msgid "HTTP Archive (HAR)"
+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 ""
@@ -17973,6 +18278,9 @@ msgstr ""
msgid "INFO: Your SSH key is expiring soon. Please generate a new key."
msgstr ""
+msgid "IP"
+msgstr ""
+
msgid "IP Address"
msgstr ""
@@ -18009,6 +18317,9 @@ msgstr ""
msgid "IdentityVerification|Verify your identity"
msgstr ""
+msgid "IdentityVerification|You can always verify your account at a later time to create a group."
+msgstr ""
+
msgid "If any indexed field exceeds this limit, it is truncated to this number of characters. The rest of the content is neither indexed nor searchable. This does not apply to repository and wiki indexing. For unlimited characters, set this to 0."
msgstr ""
@@ -18066,6 +18377,9 @@ msgstr ""
msgid "If you add %{codeStart}needs%{codeEnd} to jobs in your pipeline you'll be able to view the %{codeStart}needs%{codeEnd} relationships between jobs in this tab as a %{linkStart}Directed Acyclic Graph (DAG)%{linkEnd}."
msgstr ""
+msgid "If you are added to a project, it will be displayed here."
+msgstr ""
+
msgid "If you did not initiate these sign-in attempts, please reach out to your administrator or enable two-factor authentication (2FA) on your account."
msgstr ""
@@ -18372,12 +18686,24 @@ msgstr ""
msgid "InProductMarketing|3 ways to dive into GitLab CI/CD"
msgstr ""
+msgid "InProductMarketing|A single application eliminates complex integrations, data chokepoints, and toolchain maintenance, resulting in greater productivity and lower cost."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features, build more efficiently, strengthen security and compliance."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features."
+msgstr ""
+
msgid "InProductMarketing|Actually, GitLab makes the team work (better)"
msgstr ""
msgid "InProductMarketing|And finally %{deploy_link} a Python application."
msgstr ""
+msgid "InProductMarketing|And many more..."
+msgstr ""
+
msgid "InProductMarketing|Are your runners ready?"
msgstr ""
@@ -18396,15 +18722,33 @@ msgstr ""
msgid "InProductMarketing|Blog"
msgstr ""
+msgid "InProductMarketing|Break down silos to coordinate seamlessly across development, operations, and security with a consistent experience across the development lifecycle."
+msgstr ""
+
+msgid "InProductMarketing|Burn up/down charts"
+msgstr ""
+
msgid "InProductMarketing|By enabling code owners and required merge approvals the right person will review the right MR. This is a win-win: cleaner code and a more efficient review process."
msgstr ""
msgid "InProductMarketing|Click on the number below that corresponds with your answer — 1 being very difficult, 5 being very easy."
msgstr ""
+msgid "InProductMarketing|Code owners"
+msgstr ""
+
msgid "InProductMarketing|Code owners and required merge approvals are part of the paid tiers of GitLab. You can start a free 30-day trial of GitLab Ultimate and enable these features in less than 5 minutes with no credit card required."
msgstr ""
+msgid "InProductMarketing|Code review analytics"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration across stages in GitLab"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration made easy"
+msgstr ""
+
msgid "InProductMarketing|Create a custom CI runner with just a few clicks"
msgstr ""
@@ -18414,12 +18758,21 @@ msgstr ""
msgid "InProductMarketing|Create a project in GitLab in 5 minutes"
msgstr ""
+msgid "InProductMarketing|Create well-defined workflows by using scoped labels on issues, merge requests, and epics. Labels with the same scope cannot be used together, which prevents conflicts."
+msgstr ""
+
msgid "InProductMarketing|Create your first project!"
msgstr ""
+msgid "InProductMarketing|Define who owns specific files or directories, so the right reviewers are suggested when a merge request introduces changes to those files."
+msgstr ""
+
msgid "InProductMarketing|Deliver Better Products Faster"
msgstr ""
+msgid "InProductMarketing|Dependency scanning"
+msgstr ""
+
msgid "InProductMarketing|Did you know teams that use GitLab are far more efficient?"
msgstr ""
@@ -18429,15 +18782,27 @@ msgstr ""
msgid "InProductMarketing|Dig in and create a project and a repo"
msgstr ""
+msgid "InProductMarketing|Discover Premium & Ultimate"
+msgstr ""
+
+msgid "InProductMarketing|Discover Premium & Ultimate."
+msgstr ""
+
msgid "InProductMarketing|Do you have a minute?"
msgstr ""
msgid "InProductMarketing|Do you have a teammate who would be perfect for this task?"
msgstr ""
+msgid "InProductMarketing|Dynamic application security testing"
+msgstr ""
+
msgid "InProductMarketing|Easy"
msgstr ""
+msgid "InProductMarketing|Epics"
+msgstr ""
+
msgid "InProductMarketing|Expand your DevOps journey with a free GitLab trial"
msgstr ""
@@ -18459,9 +18824,15 @@ msgstr ""
msgid "InProductMarketing|Feel the need for speed?"
msgstr ""
+msgid "InProductMarketing|Find and fix bottlenecks in your code review process by understanding how long open merge requests have been in review."
+msgstr ""
+
msgid "InProductMarketing|Find out how your teams are really doing"
msgstr ""
+msgid "InProductMarketing|Find out if your external libraries are safe. Run dependency scanning jobs that check for known vulnerabilities in your external libraries."
+msgstr ""
+
msgid "InProductMarketing|Follow our steps"
msgstr ""
@@ -18498,6 +18869,9 @@ msgstr ""
msgid "InProductMarketing|GitLab is better with teammates to help out!"
msgstr ""
+msgid "InProductMarketing|GitLab is infrastructure agnostic (supporting GCP, AWS, Azure, OpenShift, VMWare, On Prem, Bare Metal, and more), offering a consistent workflow experience – irrespective of the environment."
+msgstr ""
+
msgid "InProductMarketing|GitLab provides static application security testing (SAST), dynamic application security testing (DAST), container scanning, and dependency scanning to help you deliver secure applications along with license compliance."
msgstr ""
@@ -18588,21 +18962,36 @@ msgstr ""
msgid "InProductMarketing|It's also possible to simply %{external_repo_link} in order to take advantage of GitLab's CI/CD."
msgstr ""
+msgid "InProductMarketing|Keep your code quality high by defining who should approve merge requests and how many approvals are required."
+msgstr ""
+
msgid "InProductMarketing|Launch GitLab CI/CD in 20 minutes or less"
msgstr ""
+msgid "InProductMarketing|Lower cost of development"
+msgstr ""
+
+msgid "InProductMarketing|Make it easier to collaborate on high-level ideas by grouping related issues in an epic."
+msgstr ""
+
msgid "InProductMarketing|Making the switch? It's easier than you think to import your projects into GitLab. Move %{github_link}, or import something %{bitbucket_link}."
msgstr ""
msgid "InProductMarketing|Master the art of importing!"
msgstr ""
+msgid "InProductMarketing|Merge request approval rule"
+msgstr ""
+
msgid "InProductMarketing|Move on to easily creating a Pages website %{ci_template_link}"
msgstr ""
msgid "InProductMarketing|Multiple owners, confusing workstreams? We've got you covered"
msgstr ""
+msgid "InProductMarketing|Multiple required approvers"
+msgstr ""
+
msgid "InProductMarketing|Need an alternative to importing?"
msgstr ""
@@ -18615,18 +19004,33 @@ msgstr ""
msgid "InProductMarketing|Our tool brings all the things together"
msgstr ""
+msgid "InProductMarketing|Protect your web application by using DAST to examine for vulnerabilities in deployed environments."
+msgstr ""
+
msgid "InProductMarketing|Rapid development, simplified"
msgstr ""
msgid "InProductMarketing|Reduce Security & Compliance Risk"
msgstr ""
+msgid "InProductMarketing|Require multiple approvers on a merge request, so you know it's in good shape before it's merged."
+msgstr ""
+
+msgid "InProductMarketing|Roadmaps"
+msgstr ""
+
+msgid "InProductMarketing|Scoped labels"
+msgstr ""
+
msgid "InProductMarketing|Security that's integrated into your development lifecycle"
msgstr ""
msgid "InProductMarketing|Sometimes you're not ready to make a full transition to a new tool. If you're not ready to fully commit, %{mirroring_link} gives you a safe way to try out GitLab in parallel with your current tool."
msgstr ""
+msgid "InProductMarketing|Speed. Efficiency. Trust."
+msgstr ""
+
msgid "InProductMarketing|Spin up an autoscaling runner in GitLab"
msgstr ""
@@ -18636,6 +19040,9 @@ msgstr ""
msgid "InProductMarketing|Start a Self-Managed trial"
msgstr ""
+msgid "InProductMarketing|Start a free trial"
+msgstr ""
+
msgid "InProductMarketing|Start a free trial of GitLab Ultimate – no credit card required"
msgstr ""
@@ -18702,6 +19109,9 @@ msgstr ""
msgid "InProductMarketing|To understand and get the most out of GitLab, start at the beginning and %{project_link}. In GitLab, repositories are part of a project, so after you've created your project you can go ahead and %{repo_link}."
msgstr ""
+msgid "InProductMarketing|Track completed issues in a chart, so you can see how a milestone is progressing at a glance."
+msgstr ""
+
msgid "InProductMarketing|Try GitLab Ultimate for free"
msgstr ""
@@ -18738,6 +19148,9 @@ msgstr ""
msgid "InProductMarketing|Very easy"
msgstr ""
+msgid "InProductMarketing|Visualize your epics and milestones in a timeline."
+msgstr ""
+
msgid "InProductMarketing|Want to host GitLab on your servers?"
msgstr ""
@@ -18759,6 +19172,9 @@ msgstr ""
msgid "InProductMarketing|YouTube"
msgstr ""
+msgid "InProductMarketing|Your software, deployed your way"
+msgstr ""
+
msgid "InProductMarketing|Your teams can be more efficient"
msgstr ""
@@ -18879,9 +19295,18 @@ msgstr ""
msgid "IncidentManagement|No incidents to display."
msgstr ""
+msgid "IncidentManagement|None"
+msgstr ""
+
msgid "IncidentManagement|Open"
msgstr ""
+msgid "IncidentManagement|Page your team with escalation policies"
+msgstr ""
+
+msgid "IncidentManagement|Paged"
+msgstr ""
+
msgid "IncidentManagement|Published"
msgstr ""
@@ -18891,6 +19316,9 @@ msgstr ""
msgid "IncidentManagement|Severity"
msgstr ""
+msgid "IncidentManagement|Status"
+msgstr ""
+
msgid "IncidentManagement|There are no closed incidents"
msgstr ""
@@ -18909,6 +19337,9 @@ msgstr ""
msgid "IncidentManagement|Unpublished"
msgstr ""
+msgid "IncidentManagement|Use escalation policies to automatically page your team when incidents are created."
+msgstr ""
+
msgid "IncidentSettings|Activate \"time to SLA\" countdown timer"
msgstr ""
@@ -18954,7 +19385,10 @@ msgstr ""
msgid "Incidents"
msgstr ""
-msgid "Incidents|Add a URL"
+msgid "Incidents|Add image details"
+msgstr ""
+
+msgid "Incidents|Add text or a link to display with your image. If you don't add either, the file name displays instead."
msgstr ""
msgid "Incidents|Drop or %{linkStart}upload%{linkEnd} a metric screenshot to attach it to the incident"
@@ -18969,10 +19403,10 @@ msgstr ""
msgid "Incidents|There was an issue loading metric images."
msgstr ""
-msgid "Incidents|There was an issue uploading your image."
+msgid "Incidents|There was an issue updating your image."
msgstr ""
-msgid "Incidents|You can optionally add a URL to link users to the original graph."
+msgid "Incidents|There was an issue uploading your image."
msgstr ""
msgid "Incident|Alert details"
@@ -18981,9 +19415,18 @@ msgstr ""
msgid "Incident|Are you sure you wish to delete this image?"
msgstr ""
+msgid "Incident|Delete image"
+msgstr ""
+
msgid "Incident|Deleting %{filename}"
msgstr ""
+msgid "Incident|Edit image text or link"
+msgstr ""
+
+msgid "Incident|Editing %{filename}"
+msgstr ""
+
msgid "Incident|Metrics"
msgstr ""
@@ -19253,12 +19696,18 @@ msgstr ""
msgid "Integrations|Branches for which notifications are to be sent"
msgstr ""
+msgid "Integrations|Clear if using a self-signed certificate."
+msgstr ""
+
msgid "Integrations|Comment detail:"
msgstr ""
msgid "Integrations|Comment settings:"
msgstr ""
+msgid "Integrations|Connection details"
+msgstr ""
+
msgid "Integrations|Connection failed. Please check your settings."
msgstr ""
@@ -19283,6 +19732,9 @@ msgstr ""
msgid "Integrations|Enable GitLab.com slash commands in a Slack workspace."
msgstr ""
+msgid "Integrations|Enable SSL verification"
+msgstr ""
+
msgid "Integrations|Enable comments"
msgstr ""
@@ -19361,6 +19813,9 @@ msgstr ""
msgid "Integrations|Return to GitLab for Jira"
msgstr ""
+msgid "Integrations|SSL verification"
+msgstr ""
+
msgid "Integrations|Save settings?"
msgstr ""
@@ -19406,9 +19861,6 @@ msgstr ""
msgid "Integrations|Use default settings"
msgstr ""
-msgid "Integrations|When you mention a Jira issue in a commit or merge request, GitLab creates a remote link and comment (if enabled)."
-msgstr ""
-
msgid "Integrations|You can now close this window and return to the GitLab for Jira application."
msgstr ""
@@ -19433,9 +19885,6 @@ msgstr ""
msgid "Integrations|can't exceed %{recipients_limit}"
msgstr ""
-msgid "Interactive developer security education."
-msgstr ""
-
msgid "Interactive mode"
msgstr ""
@@ -19925,6 +20374,9 @@ msgstr ""
msgid "IssueAnalytics|Assignees"
msgstr ""
+msgid "IssueAnalytics|Created by"
+msgstr ""
+
msgid "IssueAnalytics|Due date"
msgstr ""
@@ -19937,9 +20389,6 @@ msgstr ""
msgid "IssueAnalytics|Milestone"
msgstr ""
-msgid "IssueAnalytics|Opened by"
-msgstr ""
-
msgid "IssueAnalytics|Status"
msgstr ""
@@ -20063,10 +20512,10 @@ msgstr ""
msgid "IssuesAnalytics|Avg/Month:"
msgstr ""
-msgid "IssuesAnalytics|Issues opened"
+msgid "IssuesAnalytics|Issues created"
msgstr ""
-msgid "IssuesAnalytics|Issues opened per month"
+msgid "IssuesAnalytics|Issues created per month"
msgstr ""
msgid "IssuesAnalytics|Last 12 months"
@@ -20093,6 +20542,9 @@ msgstr ""
msgid "It looks like you have some draft commits in this branch."
msgstr ""
+msgid "It looks like you're attempting to activate your subscription. Use %{a_start}the Subscription page%{a_end} instead."
+msgstr ""
+
msgid "It may be several days before you see feature usage data."
msgstr ""
@@ -20321,6 +20773,9 @@ msgstr ""
msgid "JiraConnect|You can now close this window and return to Jira."
msgstr ""
+msgid "JiraConnect|You don't have permission to create branches for this project. Select a different project or contact the project owner for access. %{linkStart}Learn more.%{linkEnd}"
+msgstr ""
+
msgid "JiraRequest|A connection error occurred while connecting to Jira. Try your request again."
msgstr ""
@@ -20369,13 +20824,13 @@ msgstr ""
msgid "JiraService|Define the type of Jira issue to create from a vulnerability."
msgstr ""
-msgid "JiraService|Displaying Jira issues while leaving the GitLab issue functionality enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
+msgid "JiraService|Displaying Jira issues while leaving GitLab issues also enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
msgstr ""
-msgid "JiraService|Enable Jira issues"
+msgid "JiraService|Enable Jira issue creation from vulnerabilities"
msgstr ""
-msgid "JiraService|Enable Jira issues creation from vulnerabilities"
+msgid "JiraService|Enable Jira issues"
msgstr ""
msgid "JiraService|Enable Jira transitions"
@@ -20492,16 +20947,19 @@ msgstr ""
msgid "JiraService|View Jira issues in GitLab"
msgstr ""
-msgid "JiraService|Warning: All GitLab users that have access to this GitLab project are able to view all issues from the Jira project specified below."
+msgid "JiraService|Warning: All GitLab users with access to this GitLab project can view all issues from the Jira project you select."
msgstr ""
msgid "JiraService|Web URL"
msgstr ""
-msgid "JiraService|Work on Jira issues without leaving GitLab. Adds a Jira menu to access your list of Jira issues and view any issue as read-only."
+msgid "JiraService|When a Jira issue is mentioned in a commit or merge request, a remote link and comment (if enabled) will be created."
+msgstr ""
+
+msgid "JiraService|Work on Jira issues without leaving GitLab. Add a Jira menu to access a read-only list of your Jira issues."
msgstr ""
-msgid "JiraService|You need to configure Jira before enabling this integration. For more details, read the %{jira_doc_link_start}Jira integration documentation%{link_end}."
+msgid "JiraService|You must configure Jira before enabling this integration. %{jira_doc_link_start}Learn more.%{link_end}"
msgstr ""
msgid "Job"
@@ -20513,9 +20971,6 @@ msgstr ""
msgid "Job Failed #%{build_id}"
msgstr ""
-msgid "Job ID"
-msgstr ""
-
msgid "Job artifact"
msgstr ""
@@ -20582,9 +21037,27 @@ msgstr ""
msgid "Jobs|You're about to retry a job that failed because it attempted to deploy code that is older than the latest deployment. Retrying this job could result in overwriting the environment with the older source code."
msgstr ""
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source} into %{target}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{ref}"
+msgstr ""
+
+msgid "Job|Are you sure you want to erase this job log and artifacts?"
+msgstr ""
+
msgid "Job|Browse"
msgstr ""
+msgid "Job|Cancel"
+msgstr ""
+
msgid "Job|Complete Raw"
msgstr ""
@@ -20594,6 +21067,9 @@ msgstr ""
msgid "Job|Erase job log and artifacts"
msgstr ""
+msgid "Job|Finished at"
+msgstr ""
+
msgid "Job|Job artifacts"
msgstr ""
@@ -20606,7 +21082,7 @@ msgstr ""
msgid "Job|Keep"
msgstr ""
-msgid "Job|Pipeline"
+msgid "Job|Retry"
msgstr ""
msgid "Job|Scroll to bottom"
@@ -20618,6 +21094,9 @@ msgstr ""
msgid "Job|Show complete raw"
msgstr ""
+msgid "Job|Status"
+msgstr ""
+
msgid "Job|The artifacts were removed"
msgstr ""
@@ -20645,21 +21124,12 @@ msgstr ""
msgid "Job|delayed"
msgstr ""
-msgid "Job|for"
-msgstr ""
-
-msgid "Job|into"
-msgstr ""
-
msgid "Job|manual"
msgstr ""
msgid "Job|triggered"
msgstr ""
-msgid "Job|with"
-msgstr ""
-
msgid "Join Zoom meeting"
msgstr ""
@@ -20762,9 +21232,6 @@ msgstr ""
msgid "Ki"
msgstr ""
-msgid "Kontra"
-msgstr ""
-
msgid "Kroki"
msgstr ""
@@ -21088,6 +21555,9 @@ msgstr ""
msgid "Learn more about Auto DevOps"
msgstr ""
+msgid "Learn more about GitLab"
+msgstr ""
+
msgid "Learn more about Needs relationships"
msgstr ""
@@ -21415,9 +21885,18 @@ msgstr ""
msgid "Licenses|Displays licenses detected in the project, based on the %{linkStart}latest successful%{linkEnd} scan"
msgstr ""
+msgid "Licenses|Drag your license file here or %{linkStart}click to upload%{linkEnd}."
+msgstr ""
+
+msgid "Licenses|Drop your license file to start the upload."
+msgstr ""
+
msgid "Licenses|Error fetching the license list. Please check your network connection and try again."
msgstr ""
+msgid "Licenses|Error: You are trying to upload something other than a file"
+msgstr ""
+
msgid "Licenses|License Compliance"
msgstr ""
@@ -21436,6 +21915,9 @@ msgstr ""
msgid "Licenses|Specified policies in this project"
msgstr ""
+msgid "Licenses|The file could not be uploaded."
+msgstr ""
+
msgid "Licenses|The license list details information about the licenses used within your project."
msgstr ""
@@ -21469,11 +21951,6 @@ msgstr ""
msgid "Limit the size of Sidekiq jobs stored in Redis."
msgstr ""
-msgid "Limited to showing %d event at most"
-msgid_plural "Limited to showing %d events at most"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Limiting mode"
msgstr ""
@@ -21483,6 +21960,9 @@ msgstr ""
msgid "Link"
msgstr ""
+msgid "Link (optional)"
+msgstr ""
+
msgid "Link Prometheus monitoring to GitLab."
msgstr ""
@@ -21519,6 +21999,9 @@ msgstr ""
msgid "Linked emails (%{email_count})"
msgstr ""
+msgid "Linked epics"
+msgstr ""
+
msgid "Linked issues"
msgstr ""
@@ -21546,6 +22029,15 @@ msgstr ""
msgid "List of all merge commits"
msgstr ""
+msgid "List of environments for this project"
+msgstr ""
+
+msgid "List of suitable GCP locations"
+msgstr ""
+
+msgid "List of users allowed to exceed the rate limit."
+msgstr ""
+
msgid "List options"
msgstr ""
@@ -21765,6 +22257,9 @@ msgstr ""
msgid "Maintenance mode"
msgstr ""
+msgid "Make adjustments to how your GitLab instance is set up."
+msgstr ""
+
msgid "Make and review changes in the browser with the Web IDE"
msgstr ""
@@ -21909,6 +22404,12 @@ msgstr ""
msgid "MarkdownEditor|Add italic text (%{modifier_key}I)"
msgstr ""
+msgid "MarkdownEditor|Add strikethrough text (%{modifierKey}⇧X)"
+msgstr ""
+
+msgid "MarkdownEditor|Add strikethrough text (%{modifier_key}⇧X)"
+msgstr ""
+
msgid "Marked For Deletion At - %{deletion_time}"
msgstr ""
@@ -22170,6 +22671,9 @@ msgstr ""
msgid "Maximum push size (MB)"
msgstr ""
+msgid "Maximum requests per 10 minutes per user"
+msgstr ""
+
msgid "Maximum requests per minute"
msgstr ""
@@ -22260,6 +22764,19 @@ msgstr ""
msgid "Members of a group may only view projects they have permission to access"
msgstr ""
+msgid "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seat in use and will be billed for the overage."
+msgid_plural "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seats in use and will be billed for the overage."
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "MembersOverage|You are about to incur additional charges"
+msgstr ""
+
+msgid "MembersOverage|Your subscription includes %d seat."
+msgid_plural "MembersOverage|Your subscription includes %d seats."
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Membership"
msgstr ""
@@ -22464,9 +22981,6 @@ msgstr ""
msgid "Merge request not merged"
msgstr ""
-msgid "Merge request pipelines 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 merge request pipelines."
-msgstr ""
-
msgid "Merge request reports"
msgstr ""
@@ -22563,13 +23077,13 @@ msgstr ""
msgid "MergeRequests|Create issue to resolve thread"
msgstr ""
-msgid "MergeRequests|Failed to squash. Should be done manually."
+msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Saving the comment failed"
+msgid "MergeRequests|Squashing failed: Squash the commits locally, resolve any conflicts, then push the branch."
msgstr ""
-msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
+msgid "MergeRequests|Squashing not allowed: This project doesn't allow you to squash commits when merging."
msgstr ""
msgid "MergeRequests|Thread stays resolved"
@@ -23410,6 +23924,18 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "MrList|Assigned to %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from assignee %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from reviewer %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Review requested from %{name}, go to their profile."
+msgstr ""
+
msgid "Multi-project"
msgstr ""
@@ -23443,7 +23969,7 @@ msgstr ""
msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "My Awesome Group"
+msgid "My awesome group"
msgstr ""
msgid "My company or team"
@@ -24065,9 +24591,6 @@ msgstr ""
msgid "No available branches"
msgstr ""
-msgid "No available groups to fork the project."
-msgstr ""
-
msgid "No branches found"
msgstr ""
@@ -24278,6 +24801,9 @@ msgstr ""
msgid "No ref selected"
msgstr ""
+msgid "No regions configured"
+msgstr ""
+
msgid "No related merge requests found."
msgstr ""
@@ -25082,6 +25608,9 @@ msgstr ""
msgid "Only reCAPTCHA v2 is supported:"
msgstr ""
+msgid "Only required if not using role instance credentials."
+msgstr ""
+
msgid "Only use lowercase letters, numbers, and underscores."
msgstr ""
@@ -25106,9 +25635,6 @@ msgstr ""
msgid "Open a CLI and connect to the cluster you want to install the agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
-msgid "Open epics"
-msgstr ""
-
msgid "Open errors"
msgstr ""
@@ -25148,7 +25674,7 @@ msgstr ""
msgid "Opened issues"
msgstr ""
-msgid "OpenedNDaysAgo|Opened"
+msgid "OpenedNDaysAgo|Created"
msgstr ""
msgid "Opens in a new window"
@@ -25193,9 +25719,6 @@ msgstr ""
msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
-msgid "Optional."
-msgstr ""
-
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
msgstr ""
@@ -25984,6 +26507,9 @@ msgstr ""
msgid "PerformanceBar|Memory"
msgstr ""
+msgid "PerformanceBar|Memory report"
+msgstr ""
+
msgid "PerformanceBar|Redis calls"
msgstr ""
@@ -26017,18 +26543,12 @@ msgstr ""
msgid "PerformanceBar|wall"
msgstr ""
-msgid "Performs a rebase but skips triggering a new pipeline"
-msgstr ""
-
msgid "Period in seconds"
msgstr ""
msgid "Permalink"
msgstr ""
-msgid "Permanently delete project"
-msgstr ""
-
msgid "Permanently remove group"
msgstr ""
@@ -26299,6 +26819,51 @@ msgstr ""
msgid "PipelineStatusTooltip|Pipeline: %{ci_status}"
msgstr ""
+msgid "PipelineWizardDefaultCommitMessage|Add %{filename}"
+msgstr ""
+
+msgid "PipelineWizardDefaultCommitMessage|Update %{filename}"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|At least one entry is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This field is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This value is not valid"
+msgstr ""
+
+msgid "PipelineWizardListWidget|add another step"
+msgstr ""
+
+msgid "PipelineWizardListWidget|remove step"
+msgstr ""
+
+msgid "PipelineWizard|Commit"
+msgstr ""
+
+msgid "PipelineWizard|Commit Message"
+msgstr ""
+
+msgid "PipelineWizard|Commit changes to your file"
+msgstr ""
+
+msgid "PipelineWizard|Commit file to Branch"
+msgstr ""
+
+msgid "PipelineWizard|Commit your new file"
+msgstr ""
+
+msgid "PipelineWizard|The file has been committed."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem committing the changes."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem while checking whether your file already exists in the specified branch."
+msgstr ""
+
msgid "Pipelines"
msgstr ""
@@ -26413,7 +26978,7 @@ msgstr ""
msgid "Pipelines|Project cache successfully reset."
msgstr ""
-msgid "Pipelines|Revoke"
+msgid "Pipelines|Revoke trigger"
msgstr ""
msgid "Pipelines|Something went wrong while cleaning runners cache."
@@ -26458,6 +27023,12 @@ msgstr ""
msgid "Pipelines|This is a child pipeline within the parent pipeline"
msgstr ""
+msgid "Pipelines|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipelines|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipelines|This pipeline will run code originating from a forked project merge request. This means that the code can potentially have security considerations like exposing CI variables."
msgstr ""
@@ -26500,9 +27071,6 @@ msgstr ""
msgid "Pipelines|Your changes have been successfully committed. Now redirecting to the new merge request page."
msgstr ""
-msgid "Pipelines|detached"
-msgstr ""
-
msgid "Pipelines|error"
msgstr ""
@@ -26512,10 +27080,13 @@ msgstr ""
msgid "Pipelines|latest"
msgstr ""
-msgid "Pipelines|stuck"
+msgid "Pipelines|merge request"
msgstr ""
-msgid "Pipelines|train"
+msgid "Pipelines|merge train"
+msgstr ""
+
+msgid "Pipelines|stuck"
msgstr ""
msgid "Pipelines|yaml invalid"
@@ -26647,6 +27218,12 @@ msgstr ""
msgid "Pipeline|This change will not change the overall test coverage if merged."
msgstr ""
+msgid "Pipeline|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipeline|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipeline|Trigger author"
msgstr ""
@@ -26671,6 +27248,12 @@ msgstr ""
msgid "Pipeline|for"
msgstr ""
+msgid "Pipeline|merge request"
+msgstr ""
+
+msgid "Pipeline|merge train"
+msgstr ""
+
msgid "Pipeline|on"
msgstr ""
@@ -26809,9 +27392,6 @@ msgstr ""
msgid "Please enter a valid time interval"
msgstr ""
-msgid "Please enter or upload a valid license."
-msgstr ""
-
msgid "Please enter your current password."
msgstr ""
@@ -26920,9 +27500,6 @@ msgstr ""
msgid "Please type %{phrase_code} to proceed or close this modal to cancel."
msgstr ""
-msgid "Please type the following to confirm:"
-msgstr ""
-
msgid "Please use this form to report to the admin users who create spam issues, comments or behave inappropriately."
msgstr ""
@@ -26950,12 +27527,27 @@ msgstr ""
msgid "Policies"
msgstr ""
+msgid "Policy '%{escalation_policy_name}' does not exist."
+msgstr ""
+
msgid "Policy management project does have any policies in %{policy_path}"
msgstr ""
msgid "Policy project doesn't exist"
msgstr ""
+msgid "PolicyRuleMultiSelect|%{firstLabel} +%{numberOfAdditionalLabels} more"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|All %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select all"
+msgstr ""
+
msgid "Polling interval multiplier"
msgstr ""
@@ -27184,6 +27776,9 @@ msgstr ""
msgid "Private projects can be created in your personal namespace with:"
msgstr ""
+msgid "Problem with %{name} command: %{message}."
+msgstr ""
+
msgid "Proceed"
msgstr ""
@@ -27658,6 +28253,9 @@ msgstr ""
msgid "Progress"
msgstr ""
+msgid "Progress tracking"
+msgstr ""
+
msgid "Project"
msgstr ""
@@ -27889,6 +28487,9 @@ msgstr ""
msgid "ProjectQualitySummary|Failure"
msgstr ""
+msgid "ProjectQualitySummary|Get insight into the overall percentage of tests in your project that succeed, fail and are skipped."
+msgstr ""
+
msgid "ProjectQualitySummary|Latest pipeline results"
msgstr ""
@@ -27907,6 +28508,12 @@ msgstr ""
msgid "ProjectQualitySummary|See project Code Coverage Statistics"
msgstr ""
+msgid "ProjectQualitySummary|Set up test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|Set up test runs (opens in a new tab)"
+msgstr ""
+
msgid "ProjectQualitySummary|Skipped"
msgstr ""
@@ -28183,13 +28790,19 @@ msgstr ""
msgid "ProjectSettings|LFS objects from this repository are available to forks. %{linkStart}How do I remove them?%{linkEnd}"
msgstr ""
+msgid "ProjectSettings|Learn about commit history."
+msgstr ""
+
+msgid "ProjectSettings|Leave empty to use default template."
+msgstr ""
+
msgid "ProjectSettings|Manage who can see the project in the public access directory."
msgstr ""
msgid "ProjectSettings|Manages large files such as audio, video, and graphics files."
msgstr ""
-msgid "ProjectSettings|Maximum 500 characters."
+msgid "ProjectSettings|Maximum %{maxLength} characters."
msgstr ""
msgid "ProjectSettings|Merge checks"
@@ -28330,6 +28943,9 @@ msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
msgstr ""
+msgid "ProjectSettings|The default template will be applied on save."
+msgstr ""
+
msgid "ProjectSettings|These checks must pass before merge requests can be merged."
msgstr ""
@@ -28384,6 +29000,9 @@ msgstr ""
msgid "ProjectSettings|What are badges?"
msgstr ""
+msgid "ProjectSettings|What are merge trains?"
+msgstr ""
+
msgid "ProjectSettings|When merge request pipelines are enabled in the CI/CD configuration file, pipelines validate the combined results of the source and target branches. %{link_start}How to configure merge request pipelines?%{link_end}"
msgstr ""
@@ -28501,6 +29120,9 @@ msgstr ""
msgid "Projects are organized into groups"
msgstr ""
+msgid "Projects are where you store your code, access issues, wiki and other features of GitLab."
+msgstr ""
+
msgid "Projects contributed to"
msgstr ""
@@ -28516,12 +29138,6 @@ msgstr ""
msgid "Projects to index"
msgstr ""
-msgid "Projects will be permanently deleted after a %{waiting_period}-day waiting period."
-msgstr ""
-
-msgid "Projects will be permanently deleted immediately."
-msgstr ""
-
msgid "Projects with critical vulnerabilities"
msgstr ""
@@ -28606,6 +29222,9 @@ msgstr ""
msgid "ProjectsNew|Import project"
msgstr ""
+msgid "ProjectsNew|Include a Getting Started README"
+msgstr ""
+
msgid "ProjectsNew|Initialize repository with a README"
msgstr ""
@@ -28621,6 +29240,9 @@ msgstr ""
msgid "ProjectsNew|Project description %{tag_start}(optional)%{tag_end}"
msgstr ""
+msgid "ProjectsNew|Recommended if you're new to GitLab"
+msgstr ""
+
msgid "ProjectsNew|Run CI/CD for external repository"
msgstr ""
@@ -29038,6 +29660,9 @@ msgstr ""
msgid "ProtectedBranch|Unprotect"
msgstr ""
+msgid "ProtectedBranch|Unprotect branch"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
@@ -29065,6 +29690,9 @@ msgstr ""
msgid "ProtectedEnvironment|Protected Environment (%{protected_environments_count})"
msgstr ""
+msgid "ProtectedEnvironment|Required approvals"
+msgstr ""
+
msgid "ProtectedEnvironment|Select an environment"
msgstr ""
@@ -29086,10 +29714,13 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|Unprotect tag"
+msgstr ""
+
msgid "ProtectedTags|default"
msgstr ""
-msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
+msgid "ProtectedTag|By default, protected tags restrict who can modify the tag."
msgstr ""
msgid "ProtectedTag|Learn more."
@@ -29152,6 +29783,9 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Public projects are an easy way to allow everyone to have read-only access."
+msgstr ""
+
msgid "Publish to status page"
msgstr ""
@@ -29308,9 +29942,6 @@ msgstr ""
msgid "QualitySummary|Project quality"
msgstr ""
-msgid "Quarters"
-msgstr ""
-
msgid "Query"
msgstr ""
@@ -29395,6 +30026,9 @@ msgstr ""
msgid "Read more about project permissions %{help_link_open}here%{help_link_close}"
msgstr ""
+msgid "Read more about related epics"
+msgstr ""
+
msgid "Read more about related issues"
msgstr ""
@@ -29425,10 +30059,7 @@ msgstr ""
msgid "Rebase source branch on the target branch."
msgstr ""
-msgid "Rebase without CI"
-msgstr ""
-
-msgid "Rebases and triggers a pipeline"
+msgid "Rebase without pipeline"
msgstr ""
msgid "Recaptcha verified?"
@@ -29479,9 +30110,6 @@ msgstr ""
msgid "Reconfigure"
msgstr ""
-msgid "Recovering projects"
-msgstr ""
-
msgid "Recovery Codes"
msgstr ""
@@ -29541,6 +30169,12 @@ msgstr ""
msgid "Regex pattern"
msgstr ""
+msgid "Region"
+msgstr ""
+
+msgid "Regions"
+msgstr ""
+
msgid "Register"
msgstr ""
@@ -29771,9 +30405,6 @@ msgstr ""
msgid "Remove all or specific reviewer(s)"
msgstr ""
-msgid "Remove approver"
-msgstr ""
-
msgid "Remove approvers"
msgstr ""
@@ -29789,6 +30420,9 @@ msgstr ""
msgid "Remove attention request"
msgstr ""
+msgid "Remove attention request(s)"
+msgstr ""
+
msgid "Remove avatar"
msgstr ""
@@ -29927,6 +30561,9 @@ msgstr ""
msgid "Removed an issue from an epic."
msgstr ""
+msgid "Removed attention from %{users_sentence}."
+msgstr ""
+
msgid "Removed attention request from @%{username}"
msgstr ""
@@ -29978,6 +30615,9 @@ msgstr ""
msgid "Removes an issue from an epic."
msgstr ""
+msgid "Removes attention from %{users_sentence}."
+msgstr ""
+
msgid "Removes parent epic %{epic_ref}."
msgstr ""
@@ -30089,6 +30729,9 @@ msgstr ""
msgid "Report abuse to admin"
msgstr ""
+msgid "Report is generating and will be sent to your email address."
+msgstr ""
+
msgid "Reported %{timeAgo} by %{reportedBy}"
msgstr ""
@@ -30378,6 +31021,15 @@ msgstr ""
msgid "Request attention"
msgstr ""
+msgid "Request attention from %{users_sentence}."
+msgstr ""
+
+msgid "Request attention from assignee or reviewer"
+msgstr ""
+
+msgid "Request attention from assignee(s) or reviewer(s)"
+msgstr ""
+
msgid "Request attention to review"
msgstr ""
@@ -30402,6 +31054,9 @@ msgstr ""
msgid "Requested %{time_ago}"
msgstr ""
+msgid "Requested attention from %{users_sentence}."
+msgstr ""
+
msgid "Requested attention from @%{username}"
msgstr ""
@@ -30616,6 +31271,9 @@ msgstr ""
msgid "Restore project"
msgstr ""
+msgid "Restoring projects"
+msgstr ""
+
msgid "Restoring the group will prevent the group, its subgroups and projects from being removed on this date."
msgstr ""
@@ -30646,6 +31304,9 @@ msgstr ""
msgid "Retry"
msgstr ""
+msgid "Retry failed jobs"
+msgstr ""
+
msgid "Retry job"
msgstr ""
@@ -30693,9 +31354,6 @@ msgstr ""
msgid "Review changes"
msgstr ""
-msgid "Review requested from %{name}"
-msgstr ""
-
msgid "Review requests for you"
msgstr ""
@@ -30860,6 +31518,9 @@ msgstr ""
msgid "Runners|Assigned Group"
msgstr ""
+msgid "Runners|Assigned Projects (%{projectCount})"
+msgstr ""
+
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30929,6 +31590,9 @@ msgstr ""
msgid "Runners|Instance"
msgstr ""
+msgid "Runners|Jobs"
+msgstr ""
+
msgid "Runners|Last contact"
msgstr ""
@@ -31022,9 +31686,6 @@ msgstr ""
msgid "Runners|Runner %{name} was deleted"
msgstr ""
-msgid "Runners|Runner ID"
-msgstr ""
-
msgid "Runners|Runner assigned to project."
msgstr ""
@@ -31172,6 +31833,9 @@ msgstr ""
msgid "Runners|stale"
msgstr ""
+msgid "Runner|This runner has not run any jobs."
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -31286,6 +31950,24 @@ msgstr ""
msgid "Saving project."
msgstr ""
+msgid "ScanResultPolicy|%{ifLabelStart}if%{ifLabelEnd} %{scanners} scan in an open merge request targeting the %{branches} branch(es) finds %{vulnerabilitiesAllowed} or more %{severities} vulnerabilities that are %{vulnerabilityStates}"
+msgstr ""
+
+msgid "ScanResultPolicy|%{thenLabelStart}Then%{thenLabelEnd} Require approval from %{approvalsRequired} of the following approvers: %{approvers}"
+msgstr ""
+
+msgid "ScanResultPolicy|add an approver"
+msgstr ""
+
+msgid "ScanResultPolicy|scanners"
+msgstr ""
+
+msgid "ScanResultPolicy|severity levels"
+msgstr ""
+
+msgid "ScanResultPolicy|vulnerability states"
+msgstr ""
+
msgid "Scanner"
msgstr ""
@@ -31418,6 +32100,9 @@ msgstr ""
msgid "Search for a user"
msgstr ""
+msgid "Search for an emoji"
+msgstr ""
+
msgid "Search for projects, issues, etc."
msgstr ""
@@ -31605,18 +32290,12 @@ msgstr ""
msgid "Secret Detection"
msgstr ""
-msgid "Secret access key"
-msgstr ""
-
msgid "Secret token"
msgstr ""
msgid "Secure token that identifies an external storage request."
msgstr ""
-msgid "SecureCodeWarrior"
-msgstr ""
-
msgid "Security"
msgstr ""
@@ -31641,9 +32320,6 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "Security training with guide and learning pathways."
-msgstr ""
-
msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
@@ -31746,7 +32422,7 @@ msgstr ""
msgid "SecurityConfiguration|Manage corpus"
msgstr ""
-msgid "SecurityConfiguration|Manage corpus files used as mutation sources in coverage fuzzing."
+msgid "SecurityConfiguration|Manage corpus files used as seed inputs with coverage-guided fuzzing."
msgstr ""
msgid "SecurityConfiguration|Manage profiles for use by DAST scans."
@@ -31812,15 +32488,15 @@ msgstr ""
msgid "SecurityOrchestration|.yaml preview"
msgstr ""
-msgid "SecurityOrchestration|Action"
-msgstr ""
-
msgid "SecurityOrchestration|Actions"
msgstr ""
msgid "SecurityOrchestration|Add rule"
msgstr ""
+msgid "SecurityOrchestration|After dismissing the alert, the information will never be shown again."
+msgstr ""
+
msgid "SecurityOrchestration|All policies"
msgstr ""
@@ -31836,7 +32512,7 @@ msgstr ""
msgid "SecurityOrchestration|Description"
msgstr ""
-msgid "SecurityOrchestration|Disabled"
+msgid "SecurityOrchestration|Don't show the alert anymore"
msgstr ""
msgid "SecurityOrchestration|Edit policy"
@@ -31845,13 +32521,13 @@ msgstr ""
msgid "SecurityOrchestration|Edit policy project"
msgstr ""
-msgid "SecurityOrchestration|Enabled"
+msgid "SecurityOrchestration|Empty policy name"
msgstr ""
-msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Enabled"
msgstr ""
-msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
msgstr ""
msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
@@ -31860,7 +32536,7 @@ msgstr ""
msgid "SecurityOrchestration|Invalid policy type"
msgstr ""
-msgid "SecurityOrchestration|Latest scan"
+msgid "SecurityOrchestration|Latest scan run against %{agent}"
msgstr ""
msgid "SecurityOrchestration|Network"
@@ -31869,15 +32545,27 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No actions defined - policy will not run."
+msgstr ""
+
+msgid "SecurityOrchestration|No description"
+msgstr ""
+
msgid "SecurityOrchestration|No rules defined - policy will not run."
msgstr ""
+msgid "SecurityOrchestration|Not enabled"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
msgid "SecurityOrchestration|Policies"
msgstr ""
+msgid "SecurityOrchestration|Policy Type"
+msgstr ""
+
msgid "SecurityOrchestration|Policy cannot be enabled for non-existing branches (%{branches})"
msgstr ""
@@ -31902,10 +32590,13 @@ msgstr ""
msgid "SecurityOrchestration|Require %{approvals} %{plural} from %{approvers} if any of the following occur:"
msgstr ""
-msgid "SecurityOrchestration|Rule"
+msgid "SecurityOrchestration|Rules"
msgstr ""
-msgid "SecurityOrchestration|Rules"
+msgid "SecurityOrchestration|Runs %{actions} and %{lastAction} scans"
+msgstr ""
+
+msgid "SecurityOrchestration|Runs a %{action} scan"
msgstr ""
msgid "SecurityOrchestration|Scan Execution"
@@ -31965,6 +32656,9 @@ msgstr ""
msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
+msgid "SecurityOrchestration|This view only shows scan results for the agent %{agent}. You can view scan results for all agents in the %{linkStart}Operational Vulnerabilities tab of the vulnerability report%{linkEnd}."
+msgstr ""
+
msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
@@ -32019,9 +32713,6 @@ msgstr ""
msgid "SecurityOrchestration|users with ids"
msgstr ""
-msgid "SecurityOrchestration|view results"
-msgstr ""
-
msgid "SecurityOrchestration|vulnerabilities"
msgstr ""
@@ -32691,22 +33382,19 @@ 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|In order to start using functions as a service, you must first install Knative on your Kubernetes cluster. %{linkStart}More information%{linkEnd}"
-msgstr ""
-
msgid "Serverless|Learn more about Serverless"
msgstr ""
msgid "Serverless|No functions available"
msgstr ""
-msgid "Serverless|Sign up for First Look"
+msgid "Serverless|Serverless was %{linkStart}deprecated%{linkEnd} in GitLab 14.3."
+msgstr ""
+
+msgid "Serverless|Serverless was %{postLinkStart}deprecated%{postLinkEnd}. But if you opt to use it, you must install Knative in your Kubernetes cluster first. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "Serverless|The deploy job has not finished."
@@ -32718,9 +33406,6 @@ 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 ""
@@ -32736,9 +33421,6 @@ msgstr ""
msgid "Service Account Key"
msgstr ""
-msgid "Service Accounts"
-msgstr ""
-
msgid "Service Accounts keys authorize GitLab to deploy your Google Cloud project"
msgstr ""
@@ -32748,10 +33430,10 @@ msgstr ""
msgid "Service Desk allows people to create issues in your GitLab instance without their own user account. It provides a unique email address for end users to create issues in a project. Replies can be sent either through the GitLab interface or by email. End users only see threads through email."
msgstr ""
-msgid "Service Usage Data"
+msgid "Service account generated successfully"
msgstr ""
-msgid "Service account generated successfully"
+msgid "Service accounts"
msgstr ""
msgid "Service ping is disabled in your configuration file, and cannot be enabled through this form."
@@ -32895,6 +33577,9 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
+msgid "Set the per-user rate limit for getting a user by ID via the API."
+msgstr ""
+
msgid "Set the per-user rate limit for notes created by web or API requests."
msgstr ""
@@ -33074,6 +33759,9 @@ msgstr ""
msgid "Shared runners details"
msgstr ""
+msgid "Shared runners enabled cannot be enabled until a valid credit card is on file"
+msgstr ""
+
msgid "Shared runners help link"
msgstr ""
@@ -33131,6 +33819,9 @@ msgstr ""
msgid "Show all issues."
msgstr ""
+msgid "Show all milestones"
+msgstr ""
+
msgid "Show all test cases."
msgstr ""
@@ -33167,6 +33858,9 @@ msgstr ""
msgid "Show file contents"
msgstr ""
+msgid "Show group milestones"
+msgstr ""
+
msgid "Show labels"
msgstr ""
@@ -33182,6 +33876,12 @@ msgstr ""
msgid "Show open epics"
msgstr ""
+msgid "Show project milestones"
+msgstr ""
+
+msgid "Show sub-group milestones"
+msgstr ""
+
msgid "Show the Closed list"
msgstr ""
@@ -33191,11 +33891,6 @@ msgstr ""
msgid "Show whitespace changes"
msgstr ""
-msgid "Showing %d event"
-msgid_plural "Showing %d events"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Showing %{conflict} between %{sourceBranch} and %{targetBranch}"
msgstr ""
@@ -33255,12 +33950,6 @@ msgstr ""
msgid "Sidebar|None"
msgstr ""
-msgid "Sidebar|Only numeral characters allowed"
-msgstr ""
-
-msgid "Sidebar|Weight"
-msgstr ""
-
msgid "Sidekiq job compression threshold (bytes)"
msgstr ""
@@ -33423,6 +34112,9 @@ msgstr ""
msgid "Slack logo"
msgstr ""
+msgid "SlackIntegration|Are you sure you want to remove this project from the Slack application?"
+msgstr ""
+
msgid "SlackIntegration|GitLab for Slack"
msgstr ""
@@ -33432,6 +34124,9 @@ msgstr ""
msgid "SlackIntegration|Project alias"
msgstr ""
+msgid "SlackIntegration|Remove project"
+msgstr ""
+
msgid "SlackIntegration|Select a GitLab project to link with your Slack workspace."
msgstr ""
@@ -33576,9 +34271,6 @@ msgstr ""
msgid "Something went wrong trying to load issue contacts."
msgstr ""
-msgid "Something went wrong when creating a work item. Please try again"
-msgstr ""
-
msgid "Something went wrong when reordering designs. Please try again"
msgstr ""
@@ -33672,9 +34364,6 @@ msgstr ""
msgid "Something went wrong while inserting your image. Please try again."
msgstr ""
-msgid "Something went wrong while merging this merge request. Please try again."
-msgstr ""
-
msgid "Something went wrong while obtaining the Let's Encrypt certificate."
msgstr ""
@@ -33996,10 +34685,10 @@ 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."
+msgid "SourcegraphAdmin|Learn more."
msgstr ""
-msgid "SourcegraphAdmin|More information"
+msgid "SourcegraphAdmin|Only public projects have code intelligence enabled and communicate with Sourcegraph."
msgstr ""
msgid "SourcegraphAdmin|Save changes"
@@ -34008,7 +34697,7 @@ msgstr ""
msgid "SourcegraphAdmin|Sourcegraph URL"
msgstr ""
-msgid "SourcegraphAdmin|e.g. https://sourcegraph.example.com"
+msgid "SourcegraphAdmin|https://sourcegraph.example.com"
msgstr ""
msgid "SourcegraphPreferences|This feature is experimental and currently limited to certain projects."
@@ -34143,6 +34832,9 @@ msgstr ""
msgid "Start date"
msgstr ""
+msgid "Start free trial"
+msgstr ""
+
msgid "Start merge train"
msgstr ""
@@ -34173,6 +34865,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started escalation for this incident."
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -34185,6 +34880,9 @@ msgstr ""
msgid "Starts at (UTC)"
msgstr ""
+msgid "Starts escalations for this incident"
+msgstr ""
+
msgid "Starts on"
msgstr ""
@@ -34446,6 +35144,9 @@ msgstr ""
msgid "Strikethrough"
msgstr ""
+msgid "Strikethrough text"
+msgstr ""
+
msgid "Subgroup information"
msgstr ""
@@ -34680,6 +35381,21 @@ msgstr ""
msgid "Subscriptions"
msgstr ""
+msgid "Subscriptions|Chat with sales"
+msgstr ""
+
+msgid "Subscriptions|Close"
+msgstr ""
+
+msgid "Subscriptions|Not ready to buy yet?"
+msgstr ""
+
+msgid "Subscriptions|Start a free trial"
+msgstr ""
+
+msgid "Subscriptions|We understand. Maybe you have some questions for our sales team, or maybe you'd like to try some of the paid features first. What would you like to do?"
+msgstr ""
+
msgid "Subscription|Your subscription for %{strong}%{namespace_name}%{strong_close} has expired and you are now on %{pricing_link_start}the GitLab Free tier%{pricing_link_end}. Don't worry, your data is safe. Get in touch with our support team (%{support_email}). They'll gladly help with your subscription renewal."
msgstr ""
@@ -34890,6 +35606,9 @@ msgstr ""
msgid "SuperSonics|Maximum users"
msgstr ""
+msgid "SuperSonics|Offline cloud"
+msgstr ""
+
msgid "SuperSonics|Paste your activation code"
msgstr ""
@@ -34956,6 +35675,12 @@ msgstr ""
msgid "SuperSonics|You do not have an active subscription"
msgstr ""
+msgid "SuperSonics|You have a future dated license"
+msgstr ""
+
+msgid "SuperSonics|You have added a license that activates on %{date}. Please see the subscription history table below for more details."
+msgstr ""
+
msgid "SuperSonics|You have successfully added a license that activates on %{date}. Please see the subscription history table below for more details."
msgstr ""
@@ -35115,6 +35840,9 @@ msgstr ""
msgid "Tag name is required"
msgstr ""
+msgid "Tag push"
+msgstr ""
+
msgid "Tag push events"
msgstr ""
@@ -35217,6 +35945,9 @@ msgstr ""
msgid "TagsPage|protected"
msgstr ""
+msgid "Take a look at the documentation to discover all of GitLab’s capabilities."
+msgstr ""
+
msgid "Target Branch"
msgstr ""
@@ -35619,6 +36350,9 @@ msgstr ""
msgid "Tests"
msgstr ""
+msgid "Text (optional)"
+msgstr ""
+
msgid "Text added to the body of all email messages. %{character_limit} character limit"
msgstr ""
@@ -35669,6 +36403,9 @@ msgstr ""
msgid "The CSV export will be created in the background. Once finished, it will be sent to %{email} in an attachment."
msgstr ""
+msgid "The CSV export you requested of all user memberships is attached to this email."
+msgstr ""
+
msgid "The GitLab subscription service (customers.gitlab.com) is currently experiencing an outage. You can monitor the status and get updates at %{linkStart}status.gitlab.com%{linkEnd}."
msgstr ""
@@ -35744,6 +36481,9 @@ 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 epic"
+msgstr ""
+
msgid "The current issue"
msgstr ""
@@ -35905,6 +36645,9 @@ msgstr ""
msgid "The latest pipeline for this merge request has failed."
msgstr ""
+msgid "The license key is invalid."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -35920,6 +36663,9 @@ msgstr ""
msgid "The license was successfully uploaded and will be active from %{starts_at}. You can see the details below."
msgstr ""
+msgid "The license you uploaded is invalid. If the issue persists, contact support at %{link}."
+msgstr ""
+
msgid "The list creation wizard is already open"
msgstr ""
@@ -36541,10 +37287,13 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} and everything this project contains. %{strongOpen}There is no going back%{strongClose}"
+msgstr ""
+
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains."
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}on %{date}%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains. %{strongOpen}There is no going back.%{strongClose}"
msgstr ""
msgid "This action will %{strongOpen}permanently remove%{strongClose} %{codeOpen}%{group}%{codeClose} %{strongOpen}immediately%{strongClose}."
@@ -36673,9 +37422,6 @@ msgstr ""
msgid "This file was modified for readability, and can't accept suggestions. Edit it directly."
msgstr ""
-msgid "This forked project has the following:"
-msgstr ""
-
msgid "This form is disabled in preview"
msgstr ""
@@ -36688,7 +37434,7 @@ msgstr ""
msgid "This group can't be removed because it is linked to a subscription. To remove this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
-msgid "This group can't be transfered because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
+msgid "This group can't be transferred because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
msgid "This group cannot be invited to a project inside a group with enforced SSO"
@@ -36715,6 +37461,9 @@ 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 incident is already escalated with '%{escalation_policy_name}'."
+msgstr ""
+
msgid "This invitation was sent to %{mail_to_invite_email}, but you are signed in as %{link_to_current_user} with email %{mail_to_current_user}."
msgstr ""
@@ -36733,9 +37482,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 merge train pipeline"
-msgstr ""
-
msgid "This is a private email address %{helpIcon} generated just for you. Anyone who has it can create issues or merge requests as if they were you. If that happens, %{resetLinkStart}reset this token%{resetLinkEnd}."
msgstr ""
@@ -36757,6 +37503,12 @@ msgstr ""
msgid "This is your current session"
msgstr ""
+msgid "This issue cannot be assigned to a confidential epic because it is public."
+msgstr ""
+
+msgid "This issue cannot be made public because it belongs to a confidential epic."
+msgstr ""
+
msgid "This issue is confidential and should only be visible to team members with at least Reporter access."
msgstr ""
@@ -36874,6 +37626,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 branch is protected from force push."
+msgstr ""
+
msgid "This merge request cannot be rebased while there are conflicts."
msgstr ""
@@ -36925,9 +37680,15 @@ msgstr ""
msgid "This pipeline was triggered by a schedule."
msgstr ""
+msgid "This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project"
msgstr ""
+msgid "This project can be restored until %{date}."
+msgstr ""
+
msgid "This project cannot be %{visibilityLevel} because the visibility of %{openShowLink}%{name}%{closeShowLink} is %{visibility}. To make this project %{visibilityLevel}, you must first %{openEditLink}change the visibility%{closeEditLink} of the parent group."
msgstr ""
@@ -36946,6 +37707,9 @@ msgstr ""
msgid "This project is %{strongStart}NOT%{strongEnd} a fork, and has the following:"
msgstr ""
+msgid "This project is %{strongStart}NOT%{strongEnd} a fork. This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -37637,6 +38401,9 @@ msgstr ""
msgid "Today"
msgstr ""
+msgid "Todos count"
+msgstr ""
+
msgid "Todos|Are you looking for things to do? Take a look at %{strongStart}%{openIssuesLinkStart}open issues%{openIssuesLinkEnd}%{strongEnd}, contribute to %{strongStart}%{mergeRequestLinkStart}a merge request%{mergeRequestLinkEnd}%{mergeRequestLinkEnd}%{strongEnd}, or mention someone in a comment to automatically assign them a new to-do item."
msgstr ""
@@ -37910,10 +38677,8 @@ msgstr ""
msgid "Trending"
msgstr ""
-msgid "Trials|%{planName} Trial %{enDash} %{num} day left"
-msgid_plural "Trials|%{planName} Trial %{enDash} %{num} days left"
-msgstr[0] ""
-msgstr[1] ""
+msgid "Trials|%{planName} Trial"
+msgstr ""
msgid "Trials|Compare all plans"
msgstr ""
@@ -37921,6 +38686,9 @@ msgstr ""
msgid "Trials|Create a new group to start your GitLab Ultimate trial."
msgstr ""
+msgid "Trials|Day %{daysUsed}/%{duration}"
+msgstr ""
+
msgid "Trials|Go back to GitLab"
msgstr ""
@@ -38170,7 +38938,7 @@ msgstr ""
msgid "URL is triggered when repository is updated"
msgstr ""
-msgid "URL must be percent-encoded if neccessary."
+msgid "URL must be percent-encoded if necessary."
msgstr ""
msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
@@ -38389,6 +39157,9 @@ msgstr ""
msgid "Unlock account"
msgstr ""
+msgid "Unlock more features with GitLab Ultimate"
+msgstr ""
+
msgid "Unlock the discussion"
msgstr ""
@@ -38452,6 +39223,9 @@ msgstr ""
msgid "Unsubscribes from this %{quick_action_target}."
msgstr ""
+msgid "Unsupported sort value."
+msgstr ""
+
msgid "Unsupported todo type passed. Supported todo types are: %{todo_types}"
msgstr ""
@@ -38680,6 +39454,9 @@ msgstr ""
msgid "UsageQuota|File attachments and smaller design graphics."
msgstr ""
+msgid "UsageQuota|From %{storage_enforcement_date} storage limits will apply to this namespace. View and manage your usage in %{strong_start}Group Settings &gt; Usage quotas%{strong_end}."
+msgstr ""
+
msgid "UsageQuota|Git repository."
msgstr ""
@@ -38740,6 +39517,9 @@ msgstr ""
msgid "UsageQuota|Storage type"
msgstr ""
+msgid "UsageQuota|Storage used"
+msgstr ""
+
msgid "UsageQuota|This is the total amount of storage used across your projects within this namespace."
msgstr ""
@@ -38935,6 +39715,12 @@ msgstr ""
msgid "Use hashed storage paths for newly created and renamed repositories. Always enabled since 13.0."
msgstr ""
+msgid "Use issue count"
+msgstr ""
+
+msgid "Use issue weight"
+msgstr ""
+
msgid "Use one line per URI"
msgstr ""
@@ -39316,6 +40102,9 @@ msgstr ""
msgid "Users"
msgstr ""
+msgid "Users API rate limit"
+msgstr ""
+
msgid "Users can launch a development environment from a GitLab browser tab when the %{linkStart}Gitpod%{linkEnd} integration is enabled."
msgstr ""
@@ -39641,6 +40430,9 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View group pipeline usage quota"
+msgstr ""
+
msgid "View incident details at"
msgstr ""
@@ -39793,6 +40585,9 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
+msgid "Vulnerability"
+msgstr ""
+
msgid "Vulnerability Report"
msgstr ""
@@ -39844,6 +40639,9 @@ msgstr ""
msgid "VulnerabilityManagement|An unverified non-confirmed finding"
msgstr ""
+msgid "VulnerabilityManagement|At least one identifier is required"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -39853,12 +40651,24 @@ msgstr ""
msgid "VulnerabilityManagement|Create Jira issue"
msgstr ""
+msgid "VulnerabilityManagement|Enter a name"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE code"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE identifier URL"
+msgstr ""
+
msgid "VulnerabilityManagement|Fetching linked Jira issues"
msgstr ""
msgid "VulnerabilityManagement|Manually add a vulnerability entry into the vulnerability report."
msgstr ""
+msgid "VulnerabilityManagement|Name is a required field"
+msgstr ""
+
msgid "VulnerabilityManagement|Needs triage"
msgstr ""
@@ -39874,6 +40684,18 @@ msgstr ""
msgid "VulnerabilityManagement|Select a method"
msgstr ""
+msgid "VulnerabilityManagement|Select a severity level"
+msgstr ""
+
+msgid "VulnerabilityManagement|Select a status"
+msgstr ""
+
+msgid "VulnerabilityManagement|Severity is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Something went wrong while creating vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -39898,6 +40720,12 @@ msgstr ""
msgid "VulnerabilityManagement|Something went wrong, could not update vulnerability state."
msgstr ""
+msgid "VulnerabilityManagement|Status is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Submit vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Summary, detailed description, steps to reproduce, etc."
msgstr ""
@@ -40093,6 +40921,9 @@ msgstr ""
msgid "WARNING:"
msgstr ""
+msgid "WARNING: This snippet contains hidden files which might be used to mask malicious behavior. Exercise caution if cloning and executing code from this snippet."
+msgstr ""
+
msgid "Wait for the file to load to copy its contents"
msgstr ""
@@ -40312,6 +41143,15 @@ msgstr ""
msgid "Webhooks|An issue is created, updated, closed, or reopened."
msgstr ""
+msgid "Webhooks|Are you sure you want to delete this group hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this project hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this webhook?"
+msgstr ""
+
msgid "Webhooks|Comments"
msgstr ""
@@ -40321,6 +41161,9 @@ msgstr ""
msgid "Webhooks|Confidential issues events"
msgstr ""
+msgid "Webhooks|Delete webhook"
+msgstr ""
+
msgid "Webhooks|Deployment events"
msgstr ""
@@ -40554,6 +41397,9 @@ msgstr ""
msgid "Wiki"
msgstr ""
+msgid "Wiki page"
+msgstr ""
+
msgid "Wiki page was successfully created."
msgstr ""
@@ -40659,7 +41505,7 @@ msgstr ""
msgid "WikiPageConflictMessage|Someone edited the page the same time you did. Please check out %{wikiLinkStart}the page%{wikiLinkEnd} and make sure your changes will not unintentionally remove theirs."
msgstr ""
-msgid "WikiPage|An error occured while trying to render the content editor. Please try again later."
+msgid "WikiPage|An error occurred while trying to render the content editor. Please try again later."
msgstr ""
msgid "WikiPage|Are you sure you want to switch back to the classic editor?"
@@ -40818,6 +41664,18 @@ msgstr ""
msgid "WorkItem|New Task"
msgstr ""
+msgid "WorkItem|Something went wrong when creating a work item. Please try again"
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching the work item. Please try again."
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching work item types. Please try again"
+msgstr ""
+
+msgid "WorkItem|Type"
+msgstr ""
+
msgid "WorkItem|Work Items"
msgstr ""
@@ -40884,7 +41742,10 @@ msgstr ""
msgid "You are about to add %{usersTag} people to the discussion. They will all receive a notification."
msgstr ""
-msgid "You are about to permanently delete this project"
+msgid "You are about to delete this forked project containing:"
+msgstr ""
+
+msgid "You are about to delete this project containing:"
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."
@@ -40905,6 +41766,9 @@ msgstr ""
msgid "You are attempting to update a file that has changed since you started editing it."
msgstr ""
+msgid "You are billed if you exceed this number. %{qsrOverageLinkStart}How does billing work?%{qsrOverageLinkEnd}"
+msgstr ""
+
msgid "You are connected to the Prometheus server, but there is currently no data to display."
msgstr ""
@@ -40962,6 +41826,9 @@ msgstr ""
msgid "You are not authorized to update this scanner profile"
msgstr ""
+msgid "You are not authorized to upload metric images"
+msgstr ""
+
msgid "You are now impersonating %{username}"
msgstr ""
@@ -41115,9 +41982,6 @@ msgstr ""
msgid "You can only upload one design when dropping onto an existing design."
msgstr ""
-msgid "You can recover this project until %{date}"
-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 ""
@@ -41166,9 +42030,6 @@ msgstr ""
msgid "You cannot write to this read-only GitLab instance."
msgstr ""
-msgid "You can’t %{tag_start}edit%{tag_end} files directly in this project. Fork this project and submit a merge request with your changes."
-msgstr ""
-
msgid "You can’t edit files directly in this project. Fork this project and submit a merge request with your changes."
msgstr ""
@@ -41321,9 +42182,6 @@ 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 set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
@@ -41354,12 +42212,6 @@ msgstr ""
msgid "You must have maintainer access to force delete a lock"
msgstr ""
-msgid "You must have permission to create a project in a group before forking."
-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 ""
@@ -41765,7 +42617,7 @@ msgstr ""
msgid "Your public email will be displayed on your public profile."
msgstr ""
-msgid "Your request for access could not be processed: %{error_meesage}"
+msgid "Your request for access could not be processed: %{error_message}"
msgstr ""
msgid "Your request for access has been queued for review."
@@ -41948,6 +42800,9 @@ msgstr ""
msgid "archived:"
msgstr ""
+msgid "artifacts"
+msgstr ""
+
msgid "assign yourself"
msgstr ""
@@ -41977,6 +42832,9 @@ msgstr[1] ""
msgid "branch name"
msgstr ""
+msgid "builds"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -42400,6 +43258,9 @@ msgstr ""
msgid "contact with same email already exists in group hierarchy"
msgstr ""
+msgid "container registry images"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -42439,6 +43300,9 @@ msgstr ""
msgid "data"
msgstr ""
+msgid "database"
+msgstr ""
+
msgid "date must not be after 9999-12-31"
msgstr ""
@@ -42462,9 +43326,6 @@ msgstr ""
msgid "design"
msgstr ""
-msgid "detached"
-msgstr ""
-
msgid "disabled"
msgstr ""
@@ -42713,7 +43574,7 @@ msgstr ""
msgid "is not a valid X509 certificate."
msgstr ""
-msgid "is not allowed for sign-up."
+msgid "is not allowed for sign-up. Please use your regular email address."
msgstr ""
msgid "is not allowed for this group."
@@ -42725,7 +43586,7 @@ msgstr ""
msgid "is not allowed since the group is not top-level group."
msgstr ""
-msgid "is not allowed."
+msgid "is not allowed. Please use your regular email address."
msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
@@ -42812,6 +43673,9 @@ msgstr ""
msgid "level: %{level}"
msgstr ""
+msgid "lfs objects"
+msgstr ""
+
msgid "limit of %{project_limit} reached"
msgstr ""
@@ -43031,6 +43895,9 @@ msgstr ""
msgid "mrWidget|Merge blocked: pipeline must succeed. It's waiting for a manual action to continue."
msgstr ""
+msgid "mrWidget|Merge blocked: pipeline must succeed. Push a commit that fixes the failure, or %{linkStart}learn about other solutions.%{linkEnd}"
+msgstr ""
+
msgid "mrWidget|Merge blocked: this merge request must be approved."
msgstr ""
@@ -43148,9 +44015,6 @@ msgstr ""
msgid "mrWidget|The changes were not merged into"
msgstr ""
-msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -43298,9 +44162,6 @@ msgstr ""
msgid "open issue"
msgstr ""
-msgid "opened %{timeAgo}"
-msgstr ""
-
msgid "or"
msgstr ""
@@ -43312,6 +44173,12 @@ msgid_plural "out of %d total tests"
msgstr[0] ""
msgstr[1] ""
+msgid "packages"
+msgstr ""
+
+msgid "pages"
+msgstr ""
+
msgid "parent"
msgid_plural "parents"
msgstr[0] ""
@@ -43461,6 +44328,9 @@ msgid_plural "replies"
msgstr[0] ""
msgstr[1] ""
+msgid "repositories"
+msgstr ""
+
msgid "repository:"
msgstr ""
@@ -43581,12 +44451,18 @@ msgstr ""
msgid "tag name"
msgstr ""
+msgid "terraform states"
+msgstr ""
+
msgid "the correct format."
msgstr ""
msgid "the file"
msgstr ""
+msgid "the following epic(s)"
+msgstr ""
+
msgid "the following issue(s)"
msgstr ""
@@ -43599,21 +44475,12 @@ msgstr ""
msgid "this document"
msgstr ""
-msgid "this issue cannot be assigned to a confidential epic since it is public"
-msgstr ""
-
-msgid "this issue cannot be made public since it belongs to a confidential epic"
-msgstr ""
-
msgid "time summary"
msgstr ""
msgid "toggle collapse"
msgstr ""
-msgid "train"
-msgstr ""
-
msgid "triggered"
msgstr ""
@@ -43742,3 +44609,6 @@ msgstr ""
msgid "{project}"
msgstr ""
+msgid "✔"
+msgstr ""
+
diff --git a/locale/fi_FI/gitlab.po b/locale/fi_FI/gitlab.po
index 3f9d5a25419..9f075220822 100644
--- a/locale/fi_FI/gitlab.po
+++ b/locale/fi_FI/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: fi\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2022-02-02 15:45\n"
+"PO-Revision-Date: 2022-03-01 20:38\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -146,6 +146,11 @@ msgid_plural "%d approvers (you've approved)"
msgstr[0] ""
msgstr[1] ""
+msgid "%d assigned issue"
+msgid_plural "%d assigned issues"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -421,8 +426,23 @@ msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
msgstr[1] ""
-msgid "%d vulnerability updated"
-msgid_plural "%d vulnerabilities updated"
+msgid "%d vulnerability set to confirmed"
+msgid_plural "%d vulnerabilities set to confirmed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to dismissed"
+msgid_plural "%d vulnerabilities set to dismissed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to needs triage"
+msgid_plural "%d vulnerabilities set to needs triage"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to resolved"
+msgid_plural "%d vulnerabilities set to resolved"
msgstr[0] ""
msgstr[1] ""
@@ -510,6 +530,12 @@ msgstr[1] ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{completed} of %{total} issues closed"
+msgstr ""
+
+msgid "%{completed} of %{total} weight completed"
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -858,6 +884,9 @@ msgstr ""
msgid "%{openedIssues} open, %{closedIssues} closed"
msgstr ""
+msgid "%{percentage}%% issues closed"
+msgstr ""
+
msgid "%{percentage}%% weight completed"
msgstr ""
@@ -1287,6 +1316,9 @@ msgid_plural "- Users"
msgstr[0] ""
msgstr[1] ""
+msgid "- of - issues closed"
+msgstr ""
+
msgid "- of - weight completed"
msgstr ""
@@ -1429,7 +1461,7 @@ msgstr ""
msgid "1000+"
msgstr ""
-msgid "192.168.0.0/24"
+msgid "192.168.0.0/24 or 2001:0DB8:1234::/48"
msgstr ""
msgid "1st contribution!"
@@ -1741,13 +1773,13 @@ msgstr ""
msgid "AWS Access Key"
msgstr ""
-msgid "AWS Access Key. Only required if not using role instance credentials"
+msgid "AWS Secret Access Key"
msgstr ""
-msgid "AWS Secret Access Key"
+msgid "AWS access key ID (Optional)"
msgstr ""
-msgid "AWS Secret Access Key. Only required if not using role instance credentials"
+msgid "AWS secret access key (Optional)"
msgstr ""
msgid "AWS service error: %{error}"
@@ -1807,9 +1839,6 @@ msgstr ""
msgid "Access granted"
msgstr ""
-msgid "Access key ID"
-msgstr ""
-
msgid "Access requests"
msgstr ""
@@ -1984,7 +2013,7 @@ msgstr ""
msgid "Activity"
msgstr ""
-msgid "Activity|An error occured while retrieving activity. Reload the page to try again."
+msgid "Activity|An error occurred while retrieving activity. Reload the page to try again."
msgstr ""
msgid "Add"
@@ -2023,6 +2052,9 @@ msgstr ""
msgid "Add a %{type}"
msgstr ""
+msgid "Add a GCP region"
+msgstr ""
+
msgid "Add a GPG key"
msgstr ""
@@ -2074,6 +2106,9 @@ msgstr ""
msgid "Add a numbered list"
msgstr ""
+msgid "Add a related epic"
+msgstr ""
+
msgid "Add a related issue"
msgstr ""
@@ -2188,6 +2223,9 @@ msgstr ""
msgid "Add or subtract spent time"
msgstr ""
+msgid "Add people"
+msgstr ""
+
msgid "Add previously merged commits"
msgstr ""
@@ -2254,6 +2292,9 @@ msgstr ""
msgid "Add webhook"
msgstr ""
+msgid "Add your team members and others to GitLab."
+msgstr ""
+
msgid "Add/remove"
msgstr ""
@@ -3076,12 +3117,6 @@ msgstr ""
msgid "AdvancedSearch|Reindex required"
msgstr ""
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. Permanently deleting this project will %{strongStart}immediately delete%{strongEnd} its repositories and %{strongStart}all related resources%{strongEnd}, including issues, merge requests etc."
-msgstr ""
-
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. You will lose this project's repository and %{strongStart}all related resources%{strongEnd}, including issues and merge requests."
-msgstr ""
-
msgid "After a successful password update you will be redirected to login screen."
msgstr ""
@@ -3112,6 +3147,9 @@ msgstr ""
msgid "Akismet helps prevent the creation of spam issues in public projects."
msgstr ""
+msgid "Alert"
+msgstr ""
+
msgid "AlertManagement|Acknowledged"
msgstr ""
@@ -3484,9 +3522,6 @@ msgstr ""
msgid "All environments"
msgstr ""
-msgid "All epics"
-msgstr ""
-
msgid "All groups and projects"
msgstr ""
@@ -4223,12 +4258,15 @@ msgstr ""
msgid "ApplicationSettings|Approve users in the pending approval status?"
msgstr ""
-msgid "ApplicationSettings|By making this change, you will automatically approve %d user with the pending approval status."
-msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users with the pending approval status."
+msgid "ApplicationSettings|Approve users who are pending approval?"
+msgstr ""
+
+msgid "ApplicationSettings|By making this change, you will automatically approve %d user who is pending approval."
+msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users who are pending approval."
msgstr[0] ""
msgstr[1] ""
-msgid "ApplicationSettings|By making this change, you will automatically approve all users in pending approval status."
+msgid "ApplicationSettings|By making this change, you will automatically approve all users who are pending approval."
msgstr ""
msgid "ApplicationSettings|Denied domains for sign-ups"
@@ -4634,10 +4672,10 @@ msgstr ""
msgid "Archiving the project will make it entirely read-only. It is hidden from the dashboard and doesn't show up in searches. %{strong_start}The repository cannot be committed to, and no issues, comments, or other entities can be created.%{strong_end} %{link_start}Learn more.%{link_end}"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to delete this project?"
+msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
+msgid "Are you absolutely sure?"
msgstr ""
msgid "Are you sure that you want to archive this project?"
@@ -4673,12 +4711,18 @@ msgstr ""
msgid "Are you sure you want to delete this SSH key?"
msgstr ""
+msgid "Are you sure you want to delete this comment?"
+msgstr ""
+
msgid "Are you sure you want to delete this deploy key?"
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 label?"
+msgstr ""
+
msgid "Are you sure you want to delete this pipeline schedule?"
msgstr ""
@@ -4694,9 +4738,6 @@ msgstr ""
msgid "Are you sure you want to discard your changes?"
msgstr ""
-msgid "Are you sure you want to erase this build?"
-msgstr ""
-
msgid "Are you sure you want to import %d repository?"
msgid_plural "Are you sure you want to import %d repositories?"
msgstr[0] ""
@@ -4744,6 +4785,9 @@ msgstr ""
msgid "Are you sure you want to remove this list?"
msgstr ""
+msgid "Are you sure you want to remove this nickname?"
+msgstr ""
+
msgid "Are you sure you want to reset the health check token?"
msgstr ""
@@ -4756,10 +4800,10 @@ 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?"
+msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
msgstr ""
-msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
+msgid "Are you sure you want to revoke this project access token? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to stop this environment?"
@@ -4906,9 +4950,6 @@ msgstr ""
msgid "Assigned to %{assignee_name}"
msgstr ""
-msgid "Assigned to %{name}"
-msgstr ""
-
msgid "Assigned to me"
msgstr ""
@@ -4973,6 +5014,9 @@ msgstr[1] ""
msgid "Attaching the file failed."
msgstr ""
+msgid "Attention"
+msgstr ""
+
msgid "Audit Events"
msgstr ""
@@ -5135,6 +5179,12 @@ msgstr ""
msgid "Authorized applications (%{size})"
msgstr ""
+msgid "AuthorizedApplication|Are you sure you want to revoke this application?"
+msgstr ""
+
+msgid "AuthorizedApplication|Revoke application"
+msgstr ""
+
msgid "Authors: %{authors}"
msgstr ""
@@ -6328,6 +6378,9 @@ msgstr ""
msgid "CICDAnalytics|Shared Runners Usage"
msgstr ""
+msgid "CICDAnalytics|Shared runner pipeline minute duration by month"
+msgstr ""
+
msgid "CICDAnalytics|Shared runner usage"
msgstr ""
@@ -6469,6 +6522,9 @@ msgstr ""
msgid "Can create groups:"
msgstr ""
+msgid "Can not delete primary training"
+msgstr ""
+
msgid "Can't apply as the source branch was deleted."
msgstr ""
@@ -6802,9 +6858,6 @@ msgstr ""
msgid "Changing any setting here requires an application restart"
msgstr ""
-msgid "Changing group URL can have unintended side effects."
-msgstr ""
-
msgid "Charts can't be displayed as the request for data has timed out. %{documentationLink}"
msgstr ""
@@ -6892,9 +6945,6 @@ msgstr ""
msgid "Checking branch availability..."
msgstr ""
-msgid "Checking group URL availability..."
-msgstr ""
-
msgid "Checking group path availability..."
msgstr ""
@@ -7388,6 +7438,9 @@ msgstr ""
msgid "Clear recent searches"
msgstr ""
+msgid "Clear repository checks"
+msgstr ""
+
msgid "Clear search"
msgstr ""
@@ -7520,9 +7573,6 @@ msgstr ""
msgid "Closed MRs"
msgstr ""
-msgid "Closed epics"
-msgstr ""
-
msgid "Closed issues"
msgstr ""
@@ -7559,13 +7609,13 @@ msgstr ""
msgid "Cluster level"
msgstr ""
-msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
+msgid "Cluster type must be specified for Stages::ClusterEndpointInserter"
msgstr ""
msgid "ClusterAgents|%{name} successfully deleted"
msgstr ""
-msgid "ClusterAgents|%{number} of %{total} Agents"
+msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
@@ -7607,6 +7657,15 @@ msgstr ""
msgid "ClusterAgents|Agent never connected to GitLab"
msgstr ""
+msgid "ClusterAgents|Agent version mismatch"
+msgstr ""
+
+msgid "ClusterAgents|Agent version mismatch and update"
+msgstr ""
+
+msgid "ClusterAgents|Agent version update required"
+msgstr ""
+
msgid "ClusterAgents|All"
msgstr ""
@@ -7631,7 +7690,7 @@ msgstr ""
msgid "ClusterAgents|Configuration"
msgstr ""
-msgid "ClusterAgents|Connect a cluster through the Agent"
+msgid "ClusterAgents|Connect a cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connect existing cluster"
@@ -7640,13 +7699,13 @@ msgstr ""
msgid "ClusterAgents|Connect with a certificate"
msgstr ""
-msgid "ClusterAgents|Connect with agent"
+msgid "ClusterAgents|Connect with an agent"
msgstr ""
msgid "ClusterAgents|Connect with the GitLab Agent"
msgstr ""
-msgid "ClusterAgents|Connect your cluster through the Agent"
+msgid "ClusterAgents|Connect your cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connected"
@@ -7706,7 +7765,10 @@ msgstr ""
msgid "ClusterAgents|How to register an agent?"
msgstr ""
-msgid "ClusterAgents|Install new Agent"
+msgid "ClusterAgents|How to update an agent?"
+msgstr ""
+
+msgid "ClusterAgents|Install a new agent"
msgstr ""
msgid "ClusterAgents|Last connected %{timeAgo}."
@@ -7733,7 +7795,7 @@ msgstr ""
msgid "ClusterAgents|Never connected"
msgstr ""
-msgid "ClusterAgents|No Agents"
+msgid "ClusterAgents|No agents"
msgstr ""
msgid "ClusterAgents|No clusters connected through cluster certificates"
@@ -7793,6 +7855,9 @@ msgstr ""
msgid "ClusterAgents|The agent has not been connected in a long time. There might be a connectivity issue. Last contact was %{timeAgo}."
msgstr ""
+msgid "ClusterAgents|The agent version do not match each other across your cluster's pods. This can happen when a new agent version was just deployed and Kubernetes is shutting down the old pods."
+msgstr ""
+
msgid "ClusterAgents|The recommended installation method includes the token. If you want to follow the advanced installation method provided in the docs, make sure you save the token value before you close this window."
msgstr ""
@@ -7840,6 +7905,9 @@ msgstr ""
msgid "ClusterAgents|You will need to create a token to connect to your agent"
msgstr ""
+msgid "ClusterAgents|Your agent version is out of sync with your GitLab version (v%{version}), which might cause compatibility problems. Update the agent installed on your cluster to the most recent version."
+msgstr ""
+
msgid "ClusterAgents|Your instance doesn't have the %{linkStart}GitLab Agent Server (KAS)%{linkEnd} set up. Ask a GitLab Administrator to install it."
msgstr ""
@@ -8716,9 +8784,6 @@ msgstr ""
msgid "Comma-separated list of email addresses."
msgstr ""
-msgid "Comma-separated list of users allowed to exceed the rate limit."
-msgstr ""
-
msgid "Comma-separated, e.g. '1.1.1.1, 2.2.2.0/24'"
msgstr ""
@@ -9045,6 +9110,12 @@ msgstr ""
msgid "Confidential"
msgstr ""
+msgid "Confidential issue"
+msgstr ""
+
+msgid "Confidential note"
+msgstr ""
+
msgid "Confidentiality"
msgstr ""
@@ -9078,6 +9149,9 @@ msgstr ""
msgid "Configure Dependency Scanning in `.gitlab-ci.yml`, creating this file if it does not already exist"
msgstr ""
+msgid "Configure GitLab"
+msgstr ""
+
msgid "Configure GitLab runners to start using the Web Terminal. %{helpStart}Learn more.%{helpEnd}"
msgstr ""
@@ -9126,6 +9200,15 @@ msgstr ""
msgid "Configure pipelines to deploy web apps, backend services, APIs and static resources to Google Cloud"
msgstr ""
+msgid "Configure region"
+msgstr ""
+
+msgid "Configure region for environment"
+msgstr ""
+
+msgid "Configure regions"
+msgstr ""
+
msgid "Configure repository mirroring."
msgstr ""
@@ -9159,6 +9242,9 @@ msgstr ""
msgid "Configure which lists are shown for anyone who visits this board"
msgstr ""
+msgid "Configure your environments to be deployed to specific geographical regions"
+msgstr ""
+
msgid "Confirm"
msgstr ""
@@ -9861,10 +9947,10 @@ msgstr ""
msgid "CorpusManagement|Actions"
msgstr ""
-msgid "CorpusManagement|Corpus are used in fuzz testing as mutation source to Improve future testing."
+msgid "CorpusManagement|Corpus file"
msgstr ""
-msgid "CorpusManagement|Corpus file"
+msgid "CorpusManagement|Corpus files are used in coverage-guided fuzz testing as seed inputs to improve testing."
msgstr ""
msgid "CorpusManagement|Corpus files must be in *.zip format. Maximum 5 GB"
@@ -9918,6 +10004,9 @@ msgstr ""
msgid "Could not apply %{name} command."
msgstr ""
+msgid "Could not apply %{name} command. %{message}."
+msgstr ""
+
msgid "Could not authorize chat nickname. Try again!"
msgstr ""
@@ -10068,6 +10157,9 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
+msgid "Create a group"
+msgstr ""
+
msgid "Create a merge request"
msgstr ""
@@ -10092,6 +10184,9 @@ msgstr ""
msgid "Create a personal access token on your account to pull or push via %{protocol}."
msgstr ""
+msgid "Create a project"
+msgstr ""
+
msgid "Create an account using:"
msgstr ""
@@ -10455,6 +10550,9 @@ msgstr ""
msgid "Creation date"
msgstr ""
+msgid "Creator"
+msgstr ""
+
msgid "Credentials"
msgstr ""
@@ -10467,9 +10565,15 @@ msgstr ""
msgid "CredentialsInventory|Personal Access Tokens"
msgstr ""
+msgid "CredentialsInventory|Project Access Tokens"
+msgstr ""
+
msgid "CredentialsInventory|SSH Keys"
msgstr ""
+msgid "Credit card required to be on file in order to create a pipeline"
+msgstr ""
+
msgid "Credit card:"
msgstr ""
@@ -10653,9 +10757,6 @@ msgstr ""
msgid "Customer relations"
msgstr ""
-msgid "Customizable by an administrator."
-msgstr ""
-
msgid "Customizable by owners."
msgstr ""
@@ -10785,30 +10886,18 @@ msgstr ""
msgid "CycleAnalytics|%{selectedLabelsCount} selected (%{maxLabels} max)"
msgstr ""
-msgid "CycleAnalytics|%{stageCount} stages selected"
-msgstr ""
-
-msgid "CycleAnalytics|All stages"
-msgstr ""
-
-msgid "CycleAnalytics|Average days to completion"
+msgid "CycleAnalytics|Average time to completion"
msgstr ""
msgid "CycleAnalytics|Date"
msgstr ""
-msgid "CycleAnalytics|Days to completion"
-msgstr ""
-
msgid "CycleAnalytics|Display chart filters"
msgstr ""
msgid "CycleAnalytics|Lead Time for Changes"
msgstr ""
-msgid "CycleAnalytics|No stages selected"
-msgstr ""
-
msgid "CycleAnalytics|Number of tasks"
msgstr ""
@@ -10837,18 +10926,30 @@ msgstr ""
msgid "CycleAnalytics|Showing data for group '%{groupName}' from %{createdAfter} to %{createdBefore}"
msgstr ""
-msgid "CycleAnalytics|Stages"
+msgid "CycleAnalytics|Stage time: %{title}"
msgstr ""
msgid "CycleAnalytics|Tasks by type"
msgstr ""
-msgid "CycleAnalytics|The average time spent in the selected stage for the items that were completed on each date. Data limited to the last 500 items."
+msgid "CycleAnalytics|The average time items spent in this stage. Data limited to items completed within this date range."
msgstr ""
msgid "CycleAnalytics|The given date range is larger than 180 days"
msgstr ""
+msgid "CycleAnalytics|The total time items spent across each value stream stage. Data limited to items completed within this date range."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Stage time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Total time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|Total time"
+msgstr ""
+
msgid "CycleAnalytics|Type of work"
msgstr ""
@@ -10861,9 +10962,6 @@ msgstr ""
msgid "CycleAnalytics|project dropdown filter"
msgstr ""
-msgid "CycleAnalytics|stage dropdown"
-msgstr ""
-
msgid "DAG visualization requires at least 3 dependent jobs."
msgstr ""
@@ -10963,10 +11061,16 @@ msgstr ""
msgid "DastProfiles|AJAX spider"
msgstr ""
+msgid "DastProfiles|API"
+msgstr ""
+
+msgid "DastProfiles|API endpoint URL"
+msgstr ""
+
msgid "DastProfiles|Active"
msgstr ""
-msgid "DastProfiles|Additional request headers (Optional)"
+msgid "DastProfiles|Additional request headers (optional)"
msgstr ""
msgid "DastProfiles|Are you sure you want to delete this profile?"
@@ -10981,6 +11085,9 @@ msgstr ""
msgid "DastProfiles|Branch missing"
msgstr ""
+msgid "DastProfiles|Choose a scan method"
+msgstr ""
+
msgid "DastProfiles|Could not create the scanner profile. Please try again."
msgstr ""
@@ -11050,7 +11157,13 @@ msgstr ""
msgid "DastProfiles|Excluded URLs"
msgstr ""
-msgid "DastProfiles|Excluded URLs (Optional)"
+msgid "DastProfiles|Excluded URLs (optional)"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths (optional)"
msgstr ""
msgid "DastProfiles|Hide debug messages"
@@ -11107,9 +11220,6 @@ msgstr ""
msgid "DastProfiles|Request headers"
msgstr ""
-msgid "DastProfiles|Rest API"
-msgstr ""
-
msgid "DastProfiles|Run the AJAX spider, in addition to the traditional spider, to crawl the target site."
msgstr ""
@@ -11119,6 +11229,9 @@ msgstr ""
msgid "DastProfiles|Save profile"
msgstr ""
+msgid "DastProfiles|Scan method"
+msgstr ""
+
msgid "DastProfiles|Scan mode"
msgstr ""
@@ -11197,12 +11310,24 @@ msgstr ""
msgid "DastProfiles|Website"
msgstr ""
+msgid "DastProfiles|What does each method do?"
+msgstr ""
+
msgid "DastProfiles|You can either choose a passive scan or validate the target site from the site profile management page. %{docsLinkStart}Learn more about site validation.%{docsLinkEnd}"
msgstr ""
msgid "DastProfiles|You cannot run an active scan against an unvalidated site."
msgstr ""
+msgid "DastProfiles|folder/dast_example.har or https://example.com/dast_example.har"
+msgstr ""
+
+msgid "DastProfiles|folder/example.postman_collection.json or https://example.com/"
+msgstr ""
+
+msgid "DastProfiles|folder/openapi.json or https://example.com/openapi.json"
+msgstr ""
+
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
@@ -11310,6 +11435,9 @@ msgstr ""
msgid "DatadogIntegration|API URL"
msgstr ""
+msgid "DatadogIntegration|Custom tags in Datadog. Enter one tag per line in the %{codeOpen}key:value%{codeClose} format. %{linkOpen}How do I use tags?%{linkClose}"
+msgstr ""
+
msgid "DatadogIntegration|Environment"
msgstr ""
@@ -11328,12 +11456,18 @@ msgstr ""
msgid "DatadogIntegration|Tag all data from this GitLab instance in Datadog. Useful when managing several self-managed deployments."
msgstr ""
+msgid "DatadogIntegration|Tags"
+msgstr ""
+
msgid "DatadogIntegration|The Datadog site to send data to. To send data to the EU site, use %{codeOpen}datadoghq.eu%{codeClose}."
msgstr ""
msgid "DatadogIntegration|Trace your GitLab pipelines with Datadog."
msgstr ""
+msgid "DatadogIntegration|have an invalid format"
+msgstr ""
+
msgid "Datasource name not found"
msgstr ""
@@ -11343,9 +11477,6 @@ msgstr ""
msgid "Date merged"
msgstr ""
-msgid "Date picker"
-msgstr ""
-
msgid "Date range"
msgstr ""
@@ -11499,9 +11630,6 @@ msgstr ""
msgid "Definition"
msgstr ""
-msgid "Delayed Project Deletion (%{adjourned_deletion})"
-msgstr ""
-
msgid "DelayedJobs|Are you sure you want to run %{jobName} immediately? Otherwise this job will run automatically after its timer finishes."
msgstr ""
@@ -11580,10 +11708,10 @@ msgstr ""
msgid "Delete pipeline"
msgstr ""
-msgid "Delete project"
+msgid "Delete pipeline schedule"
msgstr ""
-msgid "Delete project. Are you ABSOLUTELY SURE?"
+msgid "Delete project"
msgstr ""
msgid "Delete row"
@@ -11613,6 +11741,9 @@ msgstr ""
msgid "Delete this epic and all descendants?"
msgstr ""
+msgid "Delete this project"
+msgstr ""
+
msgid "Delete user list"
msgstr ""
@@ -11871,6 +12002,12 @@ msgstr ""
msgid "Deploy to..."
msgstr ""
+msgid "DeployBoards|To see deployment progress for your environments, make sure you are deploying to %{codeStart}$KUBE_NAMESPACE%{codeEnd} and annotating with %{codeStart}app.gitlab.com/app=$CI_PROJECT_PATH_SLUG%{codeEnd} and %{codeStart}app.gitlab.com/env=$CI_ENVIRONMENT_SLUG%{codeEnd}."
+msgstr ""
+
+msgid "DeployBoard|Kubernetes Pods"
+msgstr ""
+
msgid "DeployFreeze|Add a freeze period to prevent unintended releases during a period of time for a given environment. You must update the deployment jobs in %{filename} according to the deploy freezes added here. %{freeze_period_link_start}Learn more.%{freeze_period_link_end}"
msgstr ""
@@ -11955,9 +12092,6 @@ msgstr ""
msgid "DeployTokens|Active Deploy Tokens (%{active_tokens})"
msgstr ""
-msgid "DeployTokens|Allows read and write access to registry images."
-msgstr ""
-
msgid "DeployTokens|Allows read and write access to the package registry."
msgstr ""
@@ -11970,6 +12104,9 @@ msgstr ""
msgid "DeployTokens|Allows read-only access to the repository."
msgstr ""
+msgid "DeployTokens|Allows write access to registry images."
+msgstr ""
+
msgid "DeployTokens|Copy deploy token"
msgstr ""
@@ -12063,12 +12200,57 @@ msgstr ""
msgid "Deploying to AWS is easy with GitLab"
msgstr ""
+msgid "Deployment"
+msgstr ""
+
msgid "Deployment Frequency"
msgstr ""
+msgid "Deployment Target|Project deployment target (optional)"
+msgstr ""
+
+msgid "Deployment Target|Select the deployment target"
+msgstr ""
+
msgid "Deployment frequency"
msgstr ""
+msgid "DeploymentTarget|GitLab Pages"
+msgstr ""
+
+msgid "DeploymentTarget|Heroku"
+msgstr ""
+
+msgid "DeploymentTarget|Infrastructure provider (Terraform, Cloudformation, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Kubernetes (GKE, EKS, OpenShift, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Managed container runtime (Fargate, Cloud Run, DigitalOcean App)"
+msgstr ""
+
+msgid "DeploymentTarget|Mobile app store"
+msgstr ""
+
+msgid "DeploymentTarget|No deployment planned"
+msgstr ""
+
+msgid "DeploymentTarget|Other hosting service"
+msgstr ""
+
+msgid "DeploymentTarget|Registry (package or container)"
+msgstr ""
+
+msgid "DeploymentTarget|Self-managed container runtime (Podman, Docker Swarm, Docker Compose)"
+msgstr ""
+
+msgid "DeploymentTarget|Serverless backend (Lambda, Cloud functions)"
+msgstr ""
+
+msgid "DeploymentTarget|Virtual machine (for example, EC2)"
+msgstr ""
+
msgid "Deployments"
msgstr ""
@@ -12107,6 +12289,9 @@ msgstr ""
msgid "Deployment|This deployment was created using the API"
msgstr ""
+msgid "Deployment|Triggerer"
+msgstr ""
+
msgid "Deployment|Waiting"
msgstr ""
@@ -12134,6 +12319,18 @@ msgstr ""
msgid "Deprecated API rate limits"
msgstr ""
+msgid "Deprecations|Feature deprecation and removal"
+msgstr ""
+
+msgid "Deprecations|For information on a possible replacement %{epicStart} learn more about Opstrace %{epicEnd}."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7 and are %{epicStart} scheduled for removal %{epicEnd} in GitLab 15.0."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7, and are %{removal_link_start} scheduled for removal %{link_end} in GitLab 15.0. For information on a possible replacement, %{opstrace_link_start} learn more about Opstrace %{link_end}."
+msgstr ""
+
msgid "Deprioritize label"
msgstr ""
@@ -12379,10 +12576,10 @@ msgstr ""
msgid "DevopsAdoption|At least one deploy"
msgstr ""
-msgid "DevopsAdoption|At least one issue opened"
+msgid "DevopsAdoption|At least one issue created"
msgstr ""
-msgid "DevopsAdoption|At least one merge request opened"
+msgid "DevopsAdoption|At least one merge request created"
msgstr ""
msgid "DevopsAdoption|At least one pipeline successfully run"
@@ -12583,6 +12780,9 @@ msgstr ""
msgid "Direct member"
msgstr ""
+msgid "Direct members"
+msgstr ""
+
msgid "Direct non-authenticated users to this page."
msgstr ""
@@ -12699,6 +12899,9 @@ msgid_plural "Dismiss %d selected vulnerabilities as"
msgstr[0] ""
msgstr[1] ""
+msgid "Dismiss Alert"
+msgstr ""
+
msgid "Dismiss merge request promotion"
msgstr ""
@@ -12726,9 +12929,15 @@ msgstr ""
msgid "Display alerts from all configured monitoring tools."
msgstr ""
+msgid "Display milestones"
+msgstr ""
+
msgid "Display name"
msgstr ""
+msgid "Display progress of child issues"
+msgstr ""
+
msgid "Display rendered file"
msgstr ""
@@ -12834,6 +13043,9 @@ msgstr ""
msgid "Download image"
msgstr ""
+msgid "Download payload"
+msgstr ""
+
msgid "Download raw data (.csv)"
msgstr ""
@@ -13011,6 +13223,9 @@ msgstr ""
msgid "Edit in Web IDE"
msgstr ""
+msgid "Edit in pipeline editor"
+msgstr ""
+
msgid "Edit in single-file editor"
msgstr ""
@@ -13053,6 +13268,9 @@ msgstr ""
msgid "Edit your most recent comment in a thread (from an empty textarea)"
msgstr ""
+msgid "Edit, lint, and visualize your pipeline."
+msgstr ""
+
msgid "Edited"
msgstr ""
@@ -13494,6 +13712,9 @@ msgstr ""
msgid "Enforce two-factor authentication for all user sign-ins."
msgstr ""
+msgid "Enhance security by storing service account keys in secret managers - learn more about %{docLinkStart}secret management with GitLab%{docLinkEnd}"
+msgstr ""
+
msgid "Ensure connectivity is available from the GitLab server to the Prometheus server"
msgstr ""
@@ -13554,6 +13775,9 @@ 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 following to confirm:"
+msgstr ""
+
msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
@@ -14084,9 +14308,6 @@ 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 ""
@@ -14222,6 +14443,9 @@ msgstr ""
msgid "Errors:"
msgstr ""
+msgid "Escalate this incident"
+msgstr ""
+
msgid "Escalation Policies"
msgstr ""
@@ -14234,6 +14458,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy"
+msgstr ""
+
msgid "Escalation policy:"
msgstr ""
@@ -14485,6 +14712,9 @@ msgstr ""
msgid "Existing sign in methods may be removed"
msgstr ""
+msgid "Exit."
+msgstr ""
+
msgid "Expand"
msgstr ""
@@ -14581,6 +14811,9 @@ msgstr ""
msgid "Explore public groups"
msgstr ""
+msgid "Explore public projects"
+msgstr ""
+
msgid "Explore snippets"
msgstr ""
@@ -14742,7 +14975,7 @@ msgid_plural "Failed to archive designs. Please try again."
msgstr[0] ""
msgstr[1] ""
-msgid "Failed to assign a reviewer because no user was found."
+msgid "Failed to assign a reviewer because no user was specified."
msgstr ""
msgid "Failed to assign a user because no user was found."
@@ -14808,10 +15041,10 @@ msgstr ""
msgid "Failed to find import label for Jira import."
msgstr ""
-msgid "Failed to generate export, please try again later."
+msgid "Failed to find users for %{missing}"
msgstr ""
-msgid "Failed to generate report, please try again after sometime"
+msgid "Failed to generate export, please try again later."
msgstr ""
msgid "Failed to get ref."
@@ -14910,6 +15143,9 @@ msgstr ""
msgid "Failed to remove a to-do item for the design."
msgstr ""
+msgid "Failed to remove attention because no user was found."
+msgstr ""
+
msgid "Failed to remove mirror."
msgstr ""
@@ -14922,6 +15158,9 @@ msgstr ""
msgid "Failed to remove user key."
msgstr ""
+msgid "Failed to request attention because no user was found."
+msgstr ""
+
msgid "Failed to reset key. Please try again."
msgstr ""
@@ -15003,6 +15242,9 @@ msgstr ""
msgid "Feature Flags"
msgstr ""
+msgid "Feature deprecation and removal"
+msgstr ""
+
msgid "Feature flag status"
msgstr ""
@@ -15500,7 +15742,7 @@ msgstr ""
msgid "For each job, re-use the project workspace. If the workspace doesn't exist, use %{code_open}git clone%{code_close}."
msgstr ""
-msgid "For example, the application using the token or the purpose of the token."
+msgid "For example, the application using the token or the purpose of the token. Do not give sensitive information for the name of the token, as it will be visible to all %{resource_type} members."
msgstr ""
msgid "For files larger than this limit, only index the file name. The file content is neither indexed nor searchable."
@@ -15584,9 +15826,6 @@ msgstr ""
msgid "ForkProject|Select a namespace"
msgstr ""
-msgid "ForkProject|Select a namespace to fork the project"
-msgstr ""
-
msgid "ForkProject|The project can be accessed by any logged in user."
msgstr ""
@@ -15683,6 +15922,9 @@ msgstr ""
msgid "Full name"
msgstr ""
+msgid "GCP region configured"
+msgstr ""
+
msgid "GPG Key ID:"
msgstr ""
@@ -15863,6 +16105,9 @@ msgstr ""
msgid "Geo|Failed"
msgstr ""
+msgid "Geo|Filter Geo sites"
+msgstr ""
+
msgid "Geo|Filter by name"
msgstr ""
@@ -16274,6 +16519,12 @@ msgstr ""
msgid "GitLab Issue"
msgstr ""
+msgid "GitLab KAS"
+msgstr ""
+
+msgid "GitLab Memberships CSV Export"
+msgstr ""
+
msgid "GitLab Pages"
msgstr ""
@@ -16322,6 +16573,9 @@ 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 free to use. Many features for larger teams are part of our %{link_start}paid products%{link_end}. You can try Ultimate for free without any obligation or payment details."
+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 ""
@@ -16448,7 +16702,7 @@ msgstr ""
msgid "GitLabPages|When enabled, all attempts to visit your website through HTTP are automatically redirected to HTTPS using a response with status code 301. Requires a valid certificate for all domains. %{docs_link_start}Learn more.%{link_end}"
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. %{docs_link_start}Learn more.%{link_end}"
+msgid "GitLabPages|When using Pages under the general domain of a GitLab instance (%{pages_host}), you cannot use HTTPS with subdomains of subdomains. If your namespace or groupname contains a dot, it does not work. This is a limitation of the HTTP Over TLS protocol. HTTP pages work if you don't redirect HTTP to HTTPS. %{docs_link_start}Learn more.%{link_end}"
msgstr ""
msgid "GitLabPages|With GitLab Pages you can host your static website directly from your GitLab repository. %{docs_link_start}Learn more.%{link_end}"
@@ -16625,9 +16879,6 @@ msgstr ""
msgid "Go to find file"
msgstr ""
-msgid "Go to fork"
-msgstr ""
-
msgid "Go to issue boards"
msgstr ""
@@ -16835,9 +17086,6 @@ msgstr ""
msgid "Group Hooks"
msgstr ""
-msgid "Group ID"
-msgstr ""
-
msgid "Group Owner must have signed in with SAML before enabling Group Managed Accounts"
msgstr ""
@@ -16865,9 +17113,6 @@ msgstr ""
msgid "Group by"
msgstr ""
-msgid "Group description"
-msgstr ""
-
msgid "Group description (optional)"
msgstr ""
@@ -16982,7 +17227,7 @@ msgstr ""
msgid "Group: %{name}"
msgstr ""
-msgid "GroupActivityMetrics|Issues opened"
+msgid "GroupActivityMetrics|Issues created"
msgstr ""
msgid "GroupActivityMetrics|Last 90 days"
@@ -16991,7 +17236,7 @@ msgstr ""
msgid "GroupActivityMetrics|Members added"
msgstr ""
-msgid "GroupActivityMetrics|Merge Requests opened"
+msgid "GroupActivityMetrics|Merge Requests created"
msgstr ""
msgid "GroupActivityMetrics|Recent activity"
@@ -17282,6 +17527,9 @@ msgstr ""
msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
+msgid "GroupSettings|Choose a group path that does not start with a dash or end with a period. It can also contain alphanumeric characters and underscores."
+msgstr ""
+
msgid "GroupSettings|Compliance frameworks"
msgstr ""
@@ -17315,7 +17563,7 @@ msgstr ""
msgid "GroupSettings|If not specified at the group or instance level, the default is %{default_initial_branch_name}. Does not affect existing repositories."
msgstr ""
-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."
+msgid "GroupSettings|If the parent group's visibility is lower than the group's current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility."
msgstr ""
msgid "GroupSettings|New runners registration token has been generated!"
@@ -17432,7 +17680,10 @@ msgstr ""
msgid "Groups and projects"
msgstr ""
-msgid "Groups and subgroups"
+msgid "Groups are a great way to organize projects and people."
+msgstr ""
+
+msgid "Groups are the best way to manage projects and members."
msgstr ""
msgid "Groups to synchronize"
@@ -17543,13 +17794,16 @@ msgstr ""
msgid "GroupsTree|Are you sure you want to leave the \"%{fullName}\" group?"
msgstr ""
-msgid "GroupsTree|Edit group"
+msgid "GroupsTree|Delete"
+msgstr ""
+
+msgid "GroupsTree|Edit"
msgstr ""
msgid "GroupsTree|Failed to leave the group. Please make sure you are not the only owner."
msgstr ""
-msgid "GroupsTree|Leave this group"
+msgid "GroupsTree|Leave group"
msgstr ""
msgid "GroupsTree|Loading groups"
@@ -17561,9 +17815,57 @@ msgstr ""
msgid "GroupsTree|No groups or projects matched your search"
msgstr ""
+msgid "GroupsTree|Options"
+msgstr ""
+
msgid "GroupsTree|Search by name"
msgstr ""
+msgid "Groups|Avatar will be removed. Are you sure?"
+msgstr ""
+
+msgid "Groups|Changing group URL can have unintended side effects."
+msgstr ""
+
+msgid "Groups|Checking group URL availability..."
+msgstr ""
+
+msgid "Groups|Enter a descriptive name for your group."
+msgstr ""
+
+msgid "Groups|Group ID"
+msgstr ""
+
+msgid "Groups|Group URL"
+msgstr ""
+
+msgid "Groups|Group avatar"
+msgstr ""
+
+msgid "Groups|Group description (optional)"
+msgstr ""
+
+msgid "Groups|Group name"
+msgstr ""
+
+msgid "Groups|Group path is available."
+msgstr ""
+
+msgid "Groups|Group path is unavailable. Path has been replaced with a suggested available path."
+msgstr ""
+
+msgid "Groups|Learn more"
+msgstr ""
+
+msgid "Groups|Must start with letter, digit, emoji, or underscore. Can also contain periods, dashes, spaces, and parentheses."
+msgstr ""
+
+msgid "Groups|Remove avatar"
+msgstr ""
+
+msgid "Groups|Save changes"
+msgstr ""
+
msgid "Guideline"
msgstr ""
@@ -17573,6 +17875,9 @@ msgstr ""
msgid "HAR file path or URL"
msgstr ""
+msgid "HTTP Archive (HAR)"
+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 ""
@@ -17973,6 +18278,9 @@ msgstr ""
msgid "INFO: Your SSH key is expiring soon. Please generate a new key."
msgstr ""
+msgid "IP"
+msgstr ""
+
msgid "IP Address"
msgstr ""
@@ -18009,6 +18317,9 @@ msgstr ""
msgid "IdentityVerification|Verify your identity"
msgstr ""
+msgid "IdentityVerification|You can always verify your account at a later time to create a group."
+msgstr ""
+
msgid "If any indexed field exceeds this limit, it is truncated to this number of characters. The rest of the content is neither indexed nor searchable. This does not apply to repository and wiki indexing. For unlimited characters, set this to 0."
msgstr ""
@@ -18066,6 +18377,9 @@ msgstr ""
msgid "If you add %{codeStart}needs%{codeEnd} to jobs in your pipeline you'll be able to view the %{codeStart}needs%{codeEnd} relationships between jobs in this tab as a %{linkStart}Directed Acyclic Graph (DAG)%{linkEnd}."
msgstr ""
+msgid "If you are added to a project, it will be displayed here."
+msgstr ""
+
msgid "If you did not initiate these sign-in attempts, please reach out to your administrator or enable two-factor authentication (2FA) on your account."
msgstr ""
@@ -18372,12 +18686,24 @@ msgstr ""
msgid "InProductMarketing|3 ways to dive into GitLab CI/CD"
msgstr ""
+msgid "InProductMarketing|A single application eliminates complex integrations, data chokepoints, and toolchain maintenance, resulting in greater productivity and lower cost."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features, build more efficiently, strengthen security and compliance."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features."
+msgstr ""
+
msgid "InProductMarketing|Actually, GitLab makes the team work (better)"
msgstr ""
msgid "InProductMarketing|And finally %{deploy_link} a Python application."
msgstr ""
+msgid "InProductMarketing|And many more..."
+msgstr ""
+
msgid "InProductMarketing|Are your runners ready?"
msgstr ""
@@ -18396,15 +18722,33 @@ msgstr ""
msgid "InProductMarketing|Blog"
msgstr ""
+msgid "InProductMarketing|Break down silos to coordinate seamlessly across development, operations, and security with a consistent experience across the development lifecycle."
+msgstr ""
+
+msgid "InProductMarketing|Burn up/down charts"
+msgstr ""
+
msgid "InProductMarketing|By enabling code owners and required merge approvals the right person will review the right MR. This is a win-win: cleaner code and a more efficient review process."
msgstr ""
msgid "InProductMarketing|Click on the number below that corresponds with your answer — 1 being very difficult, 5 being very easy."
msgstr ""
+msgid "InProductMarketing|Code owners"
+msgstr ""
+
msgid "InProductMarketing|Code owners and required merge approvals are part of the paid tiers of GitLab. You can start a free 30-day trial of GitLab Ultimate and enable these features in less than 5 minutes with no credit card required."
msgstr ""
+msgid "InProductMarketing|Code review analytics"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration across stages in GitLab"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration made easy"
+msgstr ""
+
msgid "InProductMarketing|Create a custom CI runner with just a few clicks"
msgstr ""
@@ -18414,12 +18758,21 @@ msgstr ""
msgid "InProductMarketing|Create a project in GitLab in 5 minutes"
msgstr ""
+msgid "InProductMarketing|Create well-defined workflows by using scoped labels on issues, merge requests, and epics. Labels with the same scope cannot be used together, which prevents conflicts."
+msgstr ""
+
msgid "InProductMarketing|Create your first project!"
msgstr ""
+msgid "InProductMarketing|Define who owns specific files or directories, so the right reviewers are suggested when a merge request introduces changes to those files."
+msgstr ""
+
msgid "InProductMarketing|Deliver Better Products Faster"
msgstr ""
+msgid "InProductMarketing|Dependency scanning"
+msgstr ""
+
msgid "InProductMarketing|Did you know teams that use GitLab are far more efficient?"
msgstr ""
@@ -18429,15 +18782,27 @@ msgstr ""
msgid "InProductMarketing|Dig in and create a project and a repo"
msgstr ""
+msgid "InProductMarketing|Discover Premium & Ultimate"
+msgstr ""
+
+msgid "InProductMarketing|Discover Premium & Ultimate."
+msgstr ""
+
msgid "InProductMarketing|Do you have a minute?"
msgstr ""
msgid "InProductMarketing|Do you have a teammate who would be perfect for this task?"
msgstr ""
+msgid "InProductMarketing|Dynamic application security testing"
+msgstr ""
+
msgid "InProductMarketing|Easy"
msgstr ""
+msgid "InProductMarketing|Epics"
+msgstr ""
+
msgid "InProductMarketing|Expand your DevOps journey with a free GitLab trial"
msgstr ""
@@ -18459,9 +18824,15 @@ msgstr ""
msgid "InProductMarketing|Feel the need for speed?"
msgstr ""
+msgid "InProductMarketing|Find and fix bottlenecks in your code review process by understanding how long open merge requests have been in review."
+msgstr ""
+
msgid "InProductMarketing|Find out how your teams are really doing"
msgstr ""
+msgid "InProductMarketing|Find out if your external libraries are safe. Run dependency scanning jobs that check for known vulnerabilities in your external libraries."
+msgstr ""
+
msgid "InProductMarketing|Follow our steps"
msgstr ""
@@ -18498,6 +18869,9 @@ msgstr ""
msgid "InProductMarketing|GitLab is better with teammates to help out!"
msgstr ""
+msgid "InProductMarketing|GitLab is infrastructure agnostic (supporting GCP, AWS, Azure, OpenShift, VMWare, On Prem, Bare Metal, and more), offering a consistent workflow experience – irrespective of the environment."
+msgstr ""
+
msgid "InProductMarketing|GitLab provides static application security testing (SAST), dynamic application security testing (DAST), container scanning, and dependency scanning to help you deliver secure applications along with license compliance."
msgstr ""
@@ -18588,21 +18962,36 @@ msgstr ""
msgid "InProductMarketing|It's also possible to simply %{external_repo_link} in order to take advantage of GitLab's CI/CD."
msgstr ""
+msgid "InProductMarketing|Keep your code quality high by defining who should approve merge requests and how many approvals are required."
+msgstr ""
+
msgid "InProductMarketing|Launch GitLab CI/CD in 20 minutes or less"
msgstr ""
+msgid "InProductMarketing|Lower cost of development"
+msgstr ""
+
+msgid "InProductMarketing|Make it easier to collaborate on high-level ideas by grouping related issues in an epic."
+msgstr ""
+
msgid "InProductMarketing|Making the switch? It's easier than you think to import your projects into GitLab. Move %{github_link}, or import something %{bitbucket_link}."
msgstr ""
msgid "InProductMarketing|Master the art of importing!"
msgstr ""
+msgid "InProductMarketing|Merge request approval rule"
+msgstr ""
+
msgid "InProductMarketing|Move on to easily creating a Pages website %{ci_template_link}"
msgstr ""
msgid "InProductMarketing|Multiple owners, confusing workstreams? We've got you covered"
msgstr ""
+msgid "InProductMarketing|Multiple required approvers"
+msgstr ""
+
msgid "InProductMarketing|Need an alternative to importing?"
msgstr ""
@@ -18615,18 +19004,33 @@ msgstr ""
msgid "InProductMarketing|Our tool brings all the things together"
msgstr ""
+msgid "InProductMarketing|Protect your web application by using DAST to examine for vulnerabilities in deployed environments."
+msgstr ""
+
msgid "InProductMarketing|Rapid development, simplified"
msgstr ""
msgid "InProductMarketing|Reduce Security & Compliance Risk"
msgstr ""
+msgid "InProductMarketing|Require multiple approvers on a merge request, so you know it's in good shape before it's merged."
+msgstr ""
+
+msgid "InProductMarketing|Roadmaps"
+msgstr ""
+
+msgid "InProductMarketing|Scoped labels"
+msgstr ""
+
msgid "InProductMarketing|Security that's integrated into your development lifecycle"
msgstr ""
msgid "InProductMarketing|Sometimes you're not ready to make a full transition to a new tool. If you're not ready to fully commit, %{mirroring_link} gives you a safe way to try out GitLab in parallel with your current tool."
msgstr ""
+msgid "InProductMarketing|Speed. Efficiency. Trust."
+msgstr ""
+
msgid "InProductMarketing|Spin up an autoscaling runner in GitLab"
msgstr ""
@@ -18636,6 +19040,9 @@ msgstr ""
msgid "InProductMarketing|Start a Self-Managed trial"
msgstr ""
+msgid "InProductMarketing|Start a free trial"
+msgstr ""
+
msgid "InProductMarketing|Start a free trial of GitLab Ultimate – no credit card required"
msgstr ""
@@ -18702,6 +19109,9 @@ msgstr ""
msgid "InProductMarketing|To understand and get the most out of GitLab, start at the beginning and %{project_link}. In GitLab, repositories are part of a project, so after you've created your project you can go ahead and %{repo_link}."
msgstr ""
+msgid "InProductMarketing|Track completed issues in a chart, so you can see how a milestone is progressing at a glance."
+msgstr ""
+
msgid "InProductMarketing|Try GitLab Ultimate for free"
msgstr ""
@@ -18738,6 +19148,9 @@ msgstr ""
msgid "InProductMarketing|Very easy"
msgstr ""
+msgid "InProductMarketing|Visualize your epics and milestones in a timeline."
+msgstr ""
+
msgid "InProductMarketing|Want to host GitLab on your servers?"
msgstr ""
@@ -18759,6 +19172,9 @@ msgstr ""
msgid "InProductMarketing|YouTube"
msgstr ""
+msgid "InProductMarketing|Your software, deployed your way"
+msgstr ""
+
msgid "InProductMarketing|Your teams can be more efficient"
msgstr ""
@@ -18879,9 +19295,18 @@ msgstr ""
msgid "IncidentManagement|No incidents to display."
msgstr ""
+msgid "IncidentManagement|None"
+msgstr ""
+
msgid "IncidentManagement|Open"
msgstr ""
+msgid "IncidentManagement|Page your team with escalation policies"
+msgstr ""
+
+msgid "IncidentManagement|Paged"
+msgstr ""
+
msgid "IncidentManagement|Published"
msgstr ""
@@ -18891,6 +19316,9 @@ msgstr ""
msgid "IncidentManagement|Severity"
msgstr ""
+msgid "IncidentManagement|Status"
+msgstr ""
+
msgid "IncidentManagement|There are no closed incidents"
msgstr ""
@@ -18909,6 +19337,9 @@ msgstr ""
msgid "IncidentManagement|Unpublished"
msgstr ""
+msgid "IncidentManagement|Use escalation policies to automatically page your team when incidents are created."
+msgstr ""
+
msgid "IncidentSettings|Activate \"time to SLA\" countdown timer"
msgstr ""
@@ -18954,7 +19385,10 @@ msgstr ""
msgid "Incidents"
msgstr ""
-msgid "Incidents|Add a URL"
+msgid "Incidents|Add image details"
+msgstr ""
+
+msgid "Incidents|Add text or a link to display with your image. If you don't add either, the file name displays instead."
msgstr ""
msgid "Incidents|Drop or %{linkStart}upload%{linkEnd} a metric screenshot to attach it to the incident"
@@ -18969,10 +19403,10 @@ msgstr ""
msgid "Incidents|There was an issue loading metric images."
msgstr ""
-msgid "Incidents|There was an issue uploading your image."
+msgid "Incidents|There was an issue updating your image."
msgstr ""
-msgid "Incidents|You can optionally add a URL to link users to the original graph."
+msgid "Incidents|There was an issue uploading your image."
msgstr ""
msgid "Incident|Alert details"
@@ -18981,9 +19415,18 @@ msgstr ""
msgid "Incident|Are you sure you wish to delete this image?"
msgstr ""
+msgid "Incident|Delete image"
+msgstr ""
+
msgid "Incident|Deleting %{filename}"
msgstr ""
+msgid "Incident|Edit image text or link"
+msgstr ""
+
+msgid "Incident|Editing %{filename}"
+msgstr ""
+
msgid "Incident|Metrics"
msgstr ""
@@ -19253,12 +19696,18 @@ msgstr ""
msgid "Integrations|Branches for which notifications are to be sent"
msgstr ""
+msgid "Integrations|Clear if using a self-signed certificate."
+msgstr ""
+
msgid "Integrations|Comment detail:"
msgstr ""
msgid "Integrations|Comment settings:"
msgstr ""
+msgid "Integrations|Connection details"
+msgstr ""
+
msgid "Integrations|Connection failed. Please check your settings."
msgstr ""
@@ -19283,6 +19732,9 @@ msgstr ""
msgid "Integrations|Enable GitLab.com slash commands in a Slack workspace."
msgstr ""
+msgid "Integrations|Enable SSL verification"
+msgstr ""
+
msgid "Integrations|Enable comments"
msgstr ""
@@ -19361,6 +19813,9 @@ msgstr ""
msgid "Integrations|Return to GitLab for Jira"
msgstr ""
+msgid "Integrations|SSL verification"
+msgstr ""
+
msgid "Integrations|Save settings?"
msgstr ""
@@ -19406,9 +19861,6 @@ msgstr ""
msgid "Integrations|Use default settings"
msgstr ""
-msgid "Integrations|When you mention a Jira issue in a commit or merge request, GitLab creates a remote link and comment (if enabled)."
-msgstr ""
-
msgid "Integrations|You can now close this window and return to the GitLab for Jira application."
msgstr ""
@@ -19433,9 +19885,6 @@ msgstr ""
msgid "Integrations|can't exceed %{recipients_limit}"
msgstr ""
-msgid "Interactive developer security education."
-msgstr ""
-
msgid "Interactive mode"
msgstr ""
@@ -19925,6 +20374,9 @@ msgstr ""
msgid "IssueAnalytics|Assignees"
msgstr ""
+msgid "IssueAnalytics|Created by"
+msgstr ""
+
msgid "IssueAnalytics|Due date"
msgstr ""
@@ -19937,9 +20389,6 @@ msgstr ""
msgid "IssueAnalytics|Milestone"
msgstr ""
-msgid "IssueAnalytics|Opened by"
-msgstr ""
-
msgid "IssueAnalytics|Status"
msgstr ""
@@ -20063,10 +20512,10 @@ msgstr ""
msgid "IssuesAnalytics|Avg/Month:"
msgstr ""
-msgid "IssuesAnalytics|Issues opened"
+msgid "IssuesAnalytics|Issues created"
msgstr ""
-msgid "IssuesAnalytics|Issues opened per month"
+msgid "IssuesAnalytics|Issues created per month"
msgstr ""
msgid "IssuesAnalytics|Last 12 months"
@@ -20093,6 +20542,9 @@ msgstr ""
msgid "It looks like you have some draft commits in this branch."
msgstr ""
+msgid "It looks like you're attempting to activate your subscription. Use %{a_start}the Subscription page%{a_end} instead."
+msgstr ""
+
msgid "It may be several days before you see feature usage data."
msgstr ""
@@ -20321,6 +20773,9 @@ msgstr ""
msgid "JiraConnect|You can now close this window and return to Jira."
msgstr ""
+msgid "JiraConnect|You don't have permission to create branches for this project. Select a different project or contact the project owner for access. %{linkStart}Learn more.%{linkEnd}"
+msgstr ""
+
msgid "JiraRequest|A connection error occurred while connecting to Jira. Try your request again."
msgstr ""
@@ -20369,13 +20824,13 @@ msgstr ""
msgid "JiraService|Define the type of Jira issue to create from a vulnerability."
msgstr ""
-msgid "JiraService|Displaying Jira issues while leaving the GitLab issue functionality enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
+msgid "JiraService|Displaying Jira issues while leaving GitLab issues also enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
msgstr ""
-msgid "JiraService|Enable Jira issues"
+msgid "JiraService|Enable Jira issue creation from vulnerabilities"
msgstr ""
-msgid "JiraService|Enable Jira issues creation from vulnerabilities"
+msgid "JiraService|Enable Jira issues"
msgstr ""
msgid "JiraService|Enable Jira transitions"
@@ -20492,16 +20947,19 @@ msgstr ""
msgid "JiraService|View Jira issues in GitLab"
msgstr ""
-msgid "JiraService|Warning: All GitLab users that have access to this GitLab project are able to view all issues from the Jira project specified below."
+msgid "JiraService|Warning: All GitLab users with access to this GitLab project can view all issues from the Jira project you select."
msgstr ""
msgid "JiraService|Web URL"
msgstr ""
-msgid "JiraService|Work on Jira issues without leaving GitLab. Adds a Jira menu to access your list of Jira issues and view any issue as read-only."
+msgid "JiraService|When a Jira issue is mentioned in a commit or merge request, a remote link and comment (if enabled) will be created."
+msgstr ""
+
+msgid "JiraService|Work on Jira issues without leaving GitLab. Add a Jira menu to access a read-only list of your Jira issues."
msgstr ""
-msgid "JiraService|You need to configure Jira before enabling this integration. For more details, read the %{jira_doc_link_start}Jira integration documentation%{link_end}."
+msgid "JiraService|You must configure Jira before enabling this integration. %{jira_doc_link_start}Learn more.%{link_end}"
msgstr ""
msgid "Job"
@@ -20513,9 +20971,6 @@ msgstr ""
msgid "Job Failed #%{build_id}"
msgstr ""
-msgid "Job ID"
-msgstr ""
-
msgid "Job artifact"
msgstr ""
@@ -20582,9 +21037,27 @@ msgstr ""
msgid "Jobs|You're about to retry a job that failed because it attempted to deploy code that is older than the latest deployment. Retrying this job could result in overwriting the environment with the older source code."
msgstr ""
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source} into %{target}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{ref}"
+msgstr ""
+
+msgid "Job|Are you sure you want to erase this job log and artifacts?"
+msgstr ""
+
msgid "Job|Browse"
msgstr ""
+msgid "Job|Cancel"
+msgstr ""
+
msgid "Job|Complete Raw"
msgstr ""
@@ -20594,6 +21067,9 @@ msgstr ""
msgid "Job|Erase job log and artifacts"
msgstr ""
+msgid "Job|Finished at"
+msgstr ""
+
msgid "Job|Job artifacts"
msgstr ""
@@ -20606,7 +21082,7 @@ msgstr ""
msgid "Job|Keep"
msgstr ""
-msgid "Job|Pipeline"
+msgid "Job|Retry"
msgstr ""
msgid "Job|Scroll to bottom"
@@ -20618,6 +21094,9 @@ msgstr ""
msgid "Job|Show complete raw"
msgstr ""
+msgid "Job|Status"
+msgstr ""
+
msgid "Job|The artifacts were removed"
msgstr ""
@@ -20645,21 +21124,12 @@ msgstr ""
msgid "Job|delayed"
msgstr ""
-msgid "Job|for"
-msgstr ""
-
-msgid "Job|into"
-msgstr ""
-
msgid "Job|manual"
msgstr ""
msgid "Job|triggered"
msgstr ""
-msgid "Job|with"
-msgstr ""
-
msgid "Join Zoom meeting"
msgstr ""
@@ -20762,9 +21232,6 @@ msgstr ""
msgid "Ki"
msgstr ""
-msgid "Kontra"
-msgstr ""
-
msgid "Kroki"
msgstr ""
@@ -21088,6 +21555,9 @@ msgstr ""
msgid "Learn more about Auto DevOps"
msgstr ""
+msgid "Learn more about GitLab"
+msgstr ""
+
msgid "Learn more about Needs relationships"
msgstr ""
@@ -21415,9 +21885,18 @@ msgstr ""
msgid "Licenses|Displays licenses detected in the project, based on the %{linkStart}latest successful%{linkEnd} scan"
msgstr ""
+msgid "Licenses|Drag your license file here or %{linkStart}click to upload%{linkEnd}."
+msgstr ""
+
+msgid "Licenses|Drop your license file to start the upload."
+msgstr ""
+
msgid "Licenses|Error fetching the license list. Please check your network connection and try again."
msgstr ""
+msgid "Licenses|Error: You are trying to upload something other than a file"
+msgstr ""
+
msgid "Licenses|License Compliance"
msgstr ""
@@ -21436,6 +21915,9 @@ msgstr ""
msgid "Licenses|Specified policies in this project"
msgstr ""
+msgid "Licenses|The file could not be uploaded."
+msgstr ""
+
msgid "Licenses|The license list details information about the licenses used within your project."
msgstr ""
@@ -21469,11 +21951,6 @@ msgstr ""
msgid "Limit the size of Sidekiq jobs stored in Redis."
msgstr ""
-msgid "Limited to showing %d event at most"
-msgid_plural "Limited to showing %d events at most"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Limiting mode"
msgstr ""
@@ -21483,6 +21960,9 @@ msgstr ""
msgid "Link"
msgstr ""
+msgid "Link (optional)"
+msgstr ""
+
msgid "Link Prometheus monitoring to GitLab."
msgstr ""
@@ -21519,6 +21999,9 @@ msgstr ""
msgid "Linked emails (%{email_count})"
msgstr ""
+msgid "Linked epics"
+msgstr ""
+
msgid "Linked issues"
msgstr ""
@@ -21546,6 +22029,15 @@ msgstr ""
msgid "List of all merge commits"
msgstr ""
+msgid "List of environments for this project"
+msgstr ""
+
+msgid "List of suitable GCP locations"
+msgstr ""
+
+msgid "List of users allowed to exceed the rate limit."
+msgstr ""
+
msgid "List options"
msgstr ""
@@ -21765,6 +22257,9 @@ msgstr ""
msgid "Maintenance mode"
msgstr ""
+msgid "Make adjustments to how your GitLab instance is set up."
+msgstr ""
+
msgid "Make and review changes in the browser with the Web IDE"
msgstr ""
@@ -21909,6 +22404,12 @@ msgstr ""
msgid "MarkdownEditor|Add italic text (%{modifier_key}I)"
msgstr ""
+msgid "MarkdownEditor|Add strikethrough text (%{modifierKey}⇧X)"
+msgstr ""
+
+msgid "MarkdownEditor|Add strikethrough text (%{modifier_key}⇧X)"
+msgstr ""
+
msgid "Marked For Deletion At - %{deletion_time}"
msgstr ""
@@ -22170,6 +22671,9 @@ msgstr ""
msgid "Maximum push size (MB)"
msgstr ""
+msgid "Maximum requests per 10 minutes per user"
+msgstr ""
+
msgid "Maximum requests per minute"
msgstr ""
@@ -22260,6 +22764,19 @@ msgstr ""
msgid "Members of a group may only view projects they have permission to access"
msgstr ""
+msgid "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seat in use and will be billed for the overage."
+msgid_plural "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seats in use and will be billed for the overage."
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "MembersOverage|You are about to incur additional charges"
+msgstr ""
+
+msgid "MembersOverage|Your subscription includes %d seat."
+msgid_plural "MembersOverage|Your subscription includes %d seats."
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Membership"
msgstr ""
@@ -22464,9 +22981,6 @@ msgstr ""
msgid "Merge request not merged"
msgstr ""
-msgid "Merge request pipelines 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 merge request pipelines."
-msgstr ""
-
msgid "Merge request reports"
msgstr ""
@@ -22563,13 +23077,13 @@ msgstr ""
msgid "MergeRequests|Create issue to resolve thread"
msgstr ""
-msgid "MergeRequests|Failed to squash. Should be done manually."
+msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Saving the comment failed"
+msgid "MergeRequests|Squashing failed: Squash the commits locally, resolve any conflicts, then push the branch."
msgstr ""
-msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
+msgid "MergeRequests|Squashing not allowed: This project doesn't allow you to squash commits when merging."
msgstr ""
msgid "MergeRequests|Thread stays resolved"
@@ -23410,6 +23924,18 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "MrList|Assigned to %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from assignee %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from reviewer %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Review requested from %{name}, go to their profile."
+msgstr ""
+
msgid "Multi-project"
msgstr ""
@@ -23443,7 +23969,7 @@ msgstr ""
msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "My Awesome Group"
+msgid "My awesome group"
msgstr ""
msgid "My company or team"
@@ -24065,9 +24591,6 @@ msgstr ""
msgid "No available branches"
msgstr ""
-msgid "No available groups to fork the project."
-msgstr ""
-
msgid "No branches found"
msgstr ""
@@ -24278,6 +24801,9 @@ msgstr ""
msgid "No ref selected"
msgstr ""
+msgid "No regions configured"
+msgstr ""
+
msgid "No related merge requests found."
msgstr ""
@@ -25082,6 +25608,9 @@ msgstr ""
msgid "Only reCAPTCHA v2 is supported:"
msgstr ""
+msgid "Only required if not using role instance credentials."
+msgstr ""
+
msgid "Only use lowercase letters, numbers, and underscores."
msgstr ""
@@ -25106,9 +25635,6 @@ msgstr ""
msgid "Open a CLI and connect to the cluster you want to install the agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
-msgid "Open epics"
-msgstr ""
-
msgid "Open errors"
msgstr ""
@@ -25148,7 +25674,7 @@ msgstr ""
msgid "Opened issues"
msgstr ""
-msgid "OpenedNDaysAgo|Opened"
+msgid "OpenedNDaysAgo|Created"
msgstr ""
msgid "Opens in a new window"
@@ -25193,9 +25719,6 @@ msgstr ""
msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
-msgid "Optional."
-msgstr ""
-
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
msgstr ""
@@ -25984,6 +26507,9 @@ msgstr ""
msgid "PerformanceBar|Memory"
msgstr ""
+msgid "PerformanceBar|Memory report"
+msgstr ""
+
msgid "PerformanceBar|Redis calls"
msgstr ""
@@ -26017,18 +26543,12 @@ msgstr ""
msgid "PerformanceBar|wall"
msgstr ""
-msgid "Performs a rebase but skips triggering a new pipeline"
-msgstr ""
-
msgid "Period in seconds"
msgstr ""
msgid "Permalink"
msgstr ""
-msgid "Permanently delete project"
-msgstr ""
-
msgid "Permanently remove group"
msgstr ""
@@ -26299,6 +26819,51 @@ msgstr ""
msgid "PipelineStatusTooltip|Pipeline: %{ci_status}"
msgstr ""
+msgid "PipelineWizardDefaultCommitMessage|Add %{filename}"
+msgstr ""
+
+msgid "PipelineWizardDefaultCommitMessage|Update %{filename}"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|At least one entry is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This field is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This value is not valid"
+msgstr ""
+
+msgid "PipelineWizardListWidget|add another step"
+msgstr ""
+
+msgid "PipelineWizardListWidget|remove step"
+msgstr ""
+
+msgid "PipelineWizard|Commit"
+msgstr ""
+
+msgid "PipelineWizard|Commit Message"
+msgstr ""
+
+msgid "PipelineWizard|Commit changes to your file"
+msgstr ""
+
+msgid "PipelineWizard|Commit file to Branch"
+msgstr ""
+
+msgid "PipelineWizard|Commit your new file"
+msgstr ""
+
+msgid "PipelineWizard|The file has been committed."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem committing the changes."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem while checking whether your file already exists in the specified branch."
+msgstr ""
+
msgid "Pipelines"
msgstr ""
@@ -26413,7 +26978,7 @@ msgstr ""
msgid "Pipelines|Project cache successfully reset."
msgstr ""
-msgid "Pipelines|Revoke"
+msgid "Pipelines|Revoke trigger"
msgstr ""
msgid "Pipelines|Something went wrong while cleaning runners cache."
@@ -26458,6 +27023,12 @@ msgstr ""
msgid "Pipelines|This is a child pipeline within the parent pipeline"
msgstr ""
+msgid "Pipelines|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipelines|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipelines|This pipeline will run code originating from a forked project merge request. This means that the code can potentially have security considerations like exposing CI variables."
msgstr ""
@@ -26500,9 +27071,6 @@ msgstr ""
msgid "Pipelines|Your changes have been successfully committed. Now redirecting to the new merge request page."
msgstr ""
-msgid "Pipelines|detached"
-msgstr ""
-
msgid "Pipelines|error"
msgstr ""
@@ -26512,10 +27080,13 @@ msgstr ""
msgid "Pipelines|latest"
msgstr ""
-msgid "Pipelines|stuck"
+msgid "Pipelines|merge request"
msgstr ""
-msgid "Pipelines|train"
+msgid "Pipelines|merge train"
+msgstr ""
+
+msgid "Pipelines|stuck"
msgstr ""
msgid "Pipelines|yaml invalid"
@@ -26647,6 +27218,12 @@ msgstr ""
msgid "Pipeline|This change will not change the overall test coverage if merged."
msgstr ""
+msgid "Pipeline|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipeline|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipeline|Trigger author"
msgstr ""
@@ -26671,6 +27248,12 @@ msgstr ""
msgid "Pipeline|for"
msgstr ""
+msgid "Pipeline|merge request"
+msgstr ""
+
+msgid "Pipeline|merge train"
+msgstr ""
+
msgid "Pipeline|on"
msgstr ""
@@ -26809,9 +27392,6 @@ msgstr ""
msgid "Please enter a valid time interval"
msgstr ""
-msgid "Please enter or upload a valid license."
-msgstr ""
-
msgid "Please enter your current password."
msgstr ""
@@ -26920,9 +27500,6 @@ msgstr ""
msgid "Please type %{phrase_code} to proceed or close this modal to cancel."
msgstr ""
-msgid "Please type the following to confirm:"
-msgstr ""
-
msgid "Please use this form to report to the admin users who create spam issues, comments or behave inappropriately."
msgstr ""
@@ -26950,12 +27527,27 @@ msgstr ""
msgid "Policies"
msgstr ""
+msgid "Policy '%{escalation_policy_name}' does not exist."
+msgstr ""
+
msgid "Policy management project does have any policies in %{policy_path}"
msgstr ""
msgid "Policy project doesn't exist"
msgstr ""
+msgid "PolicyRuleMultiSelect|%{firstLabel} +%{numberOfAdditionalLabels} more"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|All %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select all"
+msgstr ""
+
msgid "Polling interval multiplier"
msgstr ""
@@ -27184,6 +27776,9 @@ msgstr ""
msgid "Private projects can be created in your personal namespace with:"
msgstr ""
+msgid "Problem with %{name} command: %{message}."
+msgstr ""
+
msgid "Proceed"
msgstr ""
@@ -27658,6 +28253,9 @@ msgstr ""
msgid "Progress"
msgstr ""
+msgid "Progress tracking"
+msgstr ""
+
msgid "Project"
msgstr ""
@@ -27889,6 +28487,9 @@ msgstr ""
msgid "ProjectQualitySummary|Failure"
msgstr ""
+msgid "ProjectQualitySummary|Get insight into the overall percentage of tests in your project that succeed, fail and are skipped."
+msgstr ""
+
msgid "ProjectQualitySummary|Latest pipeline results"
msgstr ""
@@ -27907,6 +28508,12 @@ msgstr ""
msgid "ProjectQualitySummary|See project Code Coverage Statistics"
msgstr ""
+msgid "ProjectQualitySummary|Set up test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|Set up test runs (opens in a new tab)"
+msgstr ""
+
msgid "ProjectQualitySummary|Skipped"
msgstr ""
@@ -28183,13 +28790,19 @@ msgstr ""
msgid "ProjectSettings|LFS objects from this repository are available to forks. %{linkStart}How do I remove them?%{linkEnd}"
msgstr ""
+msgid "ProjectSettings|Learn about commit history."
+msgstr ""
+
+msgid "ProjectSettings|Leave empty to use default template."
+msgstr ""
+
msgid "ProjectSettings|Manage who can see the project in the public access directory."
msgstr ""
msgid "ProjectSettings|Manages large files such as audio, video, and graphics files."
msgstr ""
-msgid "ProjectSettings|Maximum 500 characters."
+msgid "ProjectSettings|Maximum %{maxLength} characters."
msgstr ""
msgid "ProjectSettings|Merge checks"
@@ -28330,6 +28943,9 @@ msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
msgstr ""
+msgid "ProjectSettings|The default template will be applied on save."
+msgstr ""
+
msgid "ProjectSettings|These checks must pass before merge requests can be merged."
msgstr ""
@@ -28384,6 +29000,9 @@ msgstr ""
msgid "ProjectSettings|What are badges?"
msgstr ""
+msgid "ProjectSettings|What are merge trains?"
+msgstr ""
+
msgid "ProjectSettings|When merge request pipelines are enabled in the CI/CD configuration file, pipelines validate the combined results of the source and target branches. %{link_start}How to configure merge request pipelines?%{link_end}"
msgstr ""
@@ -28501,6 +29120,9 @@ msgstr ""
msgid "Projects are organized into groups"
msgstr ""
+msgid "Projects are where you store your code, access issues, wiki and other features of GitLab."
+msgstr ""
+
msgid "Projects contributed to"
msgstr ""
@@ -28516,12 +29138,6 @@ msgstr ""
msgid "Projects to index"
msgstr ""
-msgid "Projects will be permanently deleted after a %{waiting_period}-day waiting period."
-msgstr ""
-
-msgid "Projects will be permanently deleted immediately."
-msgstr ""
-
msgid "Projects with critical vulnerabilities"
msgstr ""
@@ -28606,6 +29222,9 @@ msgstr ""
msgid "ProjectsNew|Import project"
msgstr ""
+msgid "ProjectsNew|Include a Getting Started README"
+msgstr ""
+
msgid "ProjectsNew|Initialize repository with a README"
msgstr ""
@@ -28621,6 +29240,9 @@ msgstr ""
msgid "ProjectsNew|Project description %{tag_start}(optional)%{tag_end}"
msgstr ""
+msgid "ProjectsNew|Recommended if you're new to GitLab"
+msgstr ""
+
msgid "ProjectsNew|Run CI/CD for external repository"
msgstr ""
@@ -29038,6 +29660,9 @@ msgstr ""
msgid "ProtectedBranch|Unprotect"
msgstr ""
+msgid "ProtectedBranch|Unprotect branch"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
@@ -29065,6 +29690,9 @@ msgstr ""
msgid "ProtectedEnvironment|Protected Environment (%{protected_environments_count})"
msgstr ""
+msgid "ProtectedEnvironment|Required approvals"
+msgstr ""
+
msgid "ProtectedEnvironment|Select an environment"
msgstr ""
@@ -29086,10 +29714,13 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|Unprotect tag"
+msgstr ""
+
msgid "ProtectedTags|default"
msgstr ""
-msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
+msgid "ProtectedTag|By default, protected tags restrict who can modify the tag."
msgstr ""
msgid "ProtectedTag|Learn more."
@@ -29152,6 +29783,9 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Public projects are an easy way to allow everyone to have read-only access."
+msgstr ""
+
msgid "Publish to status page"
msgstr ""
@@ -29308,9 +29942,6 @@ msgstr ""
msgid "QualitySummary|Project quality"
msgstr ""
-msgid "Quarters"
-msgstr ""
-
msgid "Query"
msgstr ""
@@ -29395,6 +30026,9 @@ msgstr ""
msgid "Read more about project permissions %{help_link_open}here%{help_link_close}"
msgstr ""
+msgid "Read more about related epics"
+msgstr ""
+
msgid "Read more about related issues"
msgstr ""
@@ -29425,10 +30059,7 @@ msgstr ""
msgid "Rebase source branch on the target branch."
msgstr ""
-msgid "Rebase without CI"
-msgstr ""
-
-msgid "Rebases and triggers a pipeline"
+msgid "Rebase without pipeline"
msgstr ""
msgid "Recaptcha verified?"
@@ -29479,9 +30110,6 @@ msgstr ""
msgid "Reconfigure"
msgstr ""
-msgid "Recovering projects"
-msgstr ""
-
msgid "Recovery Codes"
msgstr ""
@@ -29541,6 +30169,12 @@ msgstr ""
msgid "Regex pattern"
msgstr ""
+msgid "Region"
+msgstr ""
+
+msgid "Regions"
+msgstr ""
+
msgid "Register"
msgstr ""
@@ -29771,9 +30405,6 @@ msgstr ""
msgid "Remove all or specific reviewer(s)"
msgstr ""
-msgid "Remove approver"
-msgstr ""
-
msgid "Remove approvers"
msgstr ""
@@ -29789,6 +30420,9 @@ msgstr ""
msgid "Remove attention request"
msgstr ""
+msgid "Remove attention request(s)"
+msgstr ""
+
msgid "Remove avatar"
msgstr ""
@@ -29927,6 +30561,9 @@ msgstr ""
msgid "Removed an issue from an epic."
msgstr ""
+msgid "Removed attention from %{users_sentence}."
+msgstr ""
+
msgid "Removed attention request from @%{username}"
msgstr ""
@@ -29978,6 +30615,9 @@ msgstr ""
msgid "Removes an issue from an epic."
msgstr ""
+msgid "Removes attention from %{users_sentence}."
+msgstr ""
+
msgid "Removes parent epic %{epic_ref}."
msgstr ""
@@ -30089,6 +30729,9 @@ msgstr ""
msgid "Report abuse to admin"
msgstr ""
+msgid "Report is generating and will be sent to your email address."
+msgstr ""
+
msgid "Reported %{timeAgo} by %{reportedBy}"
msgstr ""
@@ -30378,6 +31021,15 @@ msgstr ""
msgid "Request attention"
msgstr ""
+msgid "Request attention from %{users_sentence}."
+msgstr ""
+
+msgid "Request attention from assignee or reviewer"
+msgstr ""
+
+msgid "Request attention from assignee(s) or reviewer(s)"
+msgstr ""
+
msgid "Request attention to review"
msgstr ""
@@ -30402,6 +31054,9 @@ msgstr ""
msgid "Requested %{time_ago}"
msgstr ""
+msgid "Requested attention from %{users_sentence}."
+msgstr ""
+
msgid "Requested attention from @%{username}"
msgstr ""
@@ -30616,6 +31271,9 @@ msgstr ""
msgid "Restore project"
msgstr ""
+msgid "Restoring projects"
+msgstr ""
+
msgid "Restoring the group will prevent the group, its subgroups and projects from being removed on this date."
msgstr ""
@@ -30646,6 +31304,9 @@ msgstr ""
msgid "Retry"
msgstr ""
+msgid "Retry failed jobs"
+msgstr ""
+
msgid "Retry job"
msgstr ""
@@ -30693,9 +31354,6 @@ msgstr ""
msgid "Review changes"
msgstr ""
-msgid "Review requested from %{name}"
-msgstr ""
-
msgid "Review requests for you"
msgstr ""
@@ -30860,6 +31518,9 @@ msgstr ""
msgid "Runners|Assigned Group"
msgstr ""
+msgid "Runners|Assigned Projects (%{projectCount})"
+msgstr ""
+
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30929,6 +31590,9 @@ msgstr ""
msgid "Runners|Instance"
msgstr ""
+msgid "Runners|Jobs"
+msgstr ""
+
msgid "Runners|Last contact"
msgstr ""
@@ -31022,9 +31686,6 @@ msgstr ""
msgid "Runners|Runner %{name} was deleted"
msgstr ""
-msgid "Runners|Runner ID"
-msgstr ""
-
msgid "Runners|Runner assigned to project."
msgstr ""
@@ -31172,6 +31833,9 @@ msgstr ""
msgid "Runners|stale"
msgstr ""
+msgid "Runner|This runner has not run any jobs."
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -31286,6 +31950,24 @@ msgstr ""
msgid "Saving project."
msgstr ""
+msgid "ScanResultPolicy|%{ifLabelStart}if%{ifLabelEnd} %{scanners} scan in an open merge request targeting the %{branches} branch(es) finds %{vulnerabilitiesAllowed} or more %{severities} vulnerabilities that are %{vulnerabilityStates}"
+msgstr ""
+
+msgid "ScanResultPolicy|%{thenLabelStart}Then%{thenLabelEnd} Require approval from %{approvalsRequired} of the following approvers: %{approvers}"
+msgstr ""
+
+msgid "ScanResultPolicy|add an approver"
+msgstr ""
+
+msgid "ScanResultPolicy|scanners"
+msgstr ""
+
+msgid "ScanResultPolicy|severity levels"
+msgstr ""
+
+msgid "ScanResultPolicy|vulnerability states"
+msgstr ""
+
msgid "Scanner"
msgstr ""
@@ -31418,6 +32100,9 @@ msgstr ""
msgid "Search for a user"
msgstr ""
+msgid "Search for an emoji"
+msgstr ""
+
msgid "Search for projects, issues, etc."
msgstr ""
@@ -31605,18 +32290,12 @@ msgstr ""
msgid "Secret Detection"
msgstr ""
-msgid "Secret access key"
-msgstr ""
-
msgid "Secret token"
msgstr ""
msgid "Secure token that identifies an external storage request."
msgstr ""
-msgid "SecureCodeWarrior"
-msgstr ""
-
msgid "Security"
msgstr ""
@@ -31641,9 +32320,6 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "Security training with guide and learning pathways."
-msgstr ""
-
msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
@@ -31746,7 +32422,7 @@ msgstr ""
msgid "SecurityConfiguration|Manage corpus"
msgstr ""
-msgid "SecurityConfiguration|Manage corpus files used as mutation sources in coverage fuzzing."
+msgid "SecurityConfiguration|Manage corpus files used as seed inputs with coverage-guided fuzzing."
msgstr ""
msgid "SecurityConfiguration|Manage profiles for use by DAST scans."
@@ -31812,15 +32488,15 @@ msgstr ""
msgid "SecurityOrchestration|.yaml preview"
msgstr ""
-msgid "SecurityOrchestration|Action"
-msgstr ""
-
msgid "SecurityOrchestration|Actions"
msgstr ""
msgid "SecurityOrchestration|Add rule"
msgstr ""
+msgid "SecurityOrchestration|After dismissing the alert, the information will never be shown again."
+msgstr ""
+
msgid "SecurityOrchestration|All policies"
msgstr ""
@@ -31836,7 +32512,7 @@ msgstr ""
msgid "SecurityOrchestration|Description"
msgstr ""
-msgid "SecurityOrchestration|Disabled"
+msgid "SecurityOrchestration|Don't show the alert anymore"
msgstr ""
msgid "SecurityOrchestration|Edit policy"
@@ -31845,13 +32521,13 @@ msgstr ""
msgid "SecurityOrchestration|Edit policy project"
msgstr ""
-msgid "SecurityOrchestration|Enabled"
+msgid "SecurityOrchestration|Empty policy name"
msgstr ""
-msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Enabled"
msgstr ""
-msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
msgstr ""
msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
@@ -31860,7 +32536,7 @@ msgstr ""
msgid "SecurityOrchestration|Invalid policy type"
msgstr ""
-msgid "SecurityOrchestration|Latest scan"
+msgid "SecurityOrchestration|Latest scan run against %{agent}"
msgstr ""
msgid "SecurityOrchestration|Network"
@@ -31869,15 +32545,27 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No actions defined - policy will not run."
+msgstr ""
+
+msgid "SecurityOrchestration|No description"
+msgstr ""
+
msgid "SecurityOrchestration|No rules defined - policy will not run."
msgstr ""
+msgid "SecurityOrchestration|Not enabled"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
msgid "SecurityOrchestration|Policies"
msgstr ""
+msgid "SecurityOrchestration|Policy Type"
+msgstr ""
+
msgid "SecurityOrchestration|Policy cannot be enabled for non-existing branches (%{branches})"
msgstr ""
@@ -31902,10 +32590,13 @@ msgstr ""
msgid "SecurityOrchestration|Require %{approvals} %{plural} from %{approvers} if any of the following occur:"
msgstr ""
-msgid "SecurityOrchestration|Rule"
+msgid "SecurityOrchestration|Rules"
msgstr ""
-msgid "SecurityOrchestration|Rules"
+msgid "SecurityOrchestration|Runs %{actions} and %{lastAction} scans"
+msgstr ""
+
+msgid "SecurityOrchestration|Runs a %{action} scan"
msgstr ""
msgid "SecurityOrchestration|Scan Execution"
@@ -31965,6 +32656,9 @@ msgstr ""
msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
+msgid "SecurityOrchestration|This view only shows scan results for the agent %{agent}. You can view scan results for all agents in the %{linkStart}Operational Vulnerabilities tab of the vulnerability report%{linkEnd}."
+msgstr ""
+
msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
@@ -32019,9 +32713,6 @@ msgstr ""
msgid "SecurityOrchestration|users with ids"
msgstr ""
-msgid "SecurityOrchestration|view results"
-msgstr ""
-
msgid "SecurityOrchestration|vulnerabilities"
msgstr ""
@@ -32691,22 +33382,19 @@ 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|In order to start using functions as a service, you must first install Knative on your Kubernetes cluster. %{linkStart}More information%{linkEnd}"
-msgstr ""
-
msgid "Serverless|Learn more about Serverless"
msgstr ""
msgid "Serverless|No functions available"
msgstr ""
-msgid "Serverless|Sign up for First Look"
+msgid "Serverless|Serverless was %{linkStart}deprecated%{linkEnd} in GitLab 14.3."
+msgstr ""
+
+msgid "Serverless|Serverless was %{postLinkStart}deprecated%{postLinkEnd}. But if you opt to use it, you must install Knative in your Kubernetes cluster first. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "Serverless|The deploy job has not finished."
@@ -32718,9 +33406,6 @@ 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 ""
@@ -32736,9 +33421,6 @@ msgstr ""
msgid "Service Account Key"
msgstr ""
-msgid "Service Accounts"
-msgstr ""
-
msgid "Service Accounts keys authorize GitLab to deploy your Google Cloud project"
msgstr ""
@@ -32748,10 +33430,10 @@ msgstr ""
msgid "Service Desk allows people to create issues in your GitLab instance without their own user account. It provides a unique email address for end users to create issues in a project. Replies can be sent either through the GitLab interface or by email. End users only see threads through email."
msgstr ""
-msgid "Service Usage Data"
+msgid "Service account generated successfully"
msgstr ""
-msgid "Service account generated successfully"
+msgid "Service accounts"
msgstr ""
msgid "Service ping is disabled in your configuration file, and cannot be enabled through this form."
@@ -32895,6 +33577,9 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
+msgid "Set the per-user rate limit for getting a user by ID via the API."
+msgstr ""
+
msgid "Set the per-user rate limit for notes created by web or API requests."
msgstr ""
@@ -33074,6 +33759,9 @@ msgstr ""
msgid "Shared runners details"
msgstr ""
+msgid "Shared runners enabled cannot be enabled until a valid credit card is on file"
+msgstr ""
+
msgid "Shared runners help link"
msgstr ""
@@ -33131,6 +33819,9 @@ msgstr ""
msgid "Show all issues."
msgstr ""
+msgid "Show all milestones"
+msgstr ""
+
msgid "Show all test cases."
msgstr ""
@@ -33167,6 +33858,9 @@ msgstr ""
msgid "Show file contents"
msgstr ""
+msgid "Show group milestones"
+msgstr ""
+
msgid "Show labels"
msgstr ""
@@ -33182,6 +33876,12 @@ msgstr ""
msgid "Show open epics"
msgstr ""
+msgid "Show project milestones"
+msgstr ""
+
+msgid "Show sub-group milestones"
+msgstr ""
+
msgid "Show the Closed list"
msgstr ""
@@ -33191,11 +33891,6 @@ msgstr ""
msgid "Show whitespace changes"
msgstr ""
-msgid "Showing %d event"
-msgid_plural "Showing %d events"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Showing %{conflict} between %{sourceBranch} and %{targetBranch}"
msgstr ""
@@ -33255,12 +33950,6 @@ msgstr ""
msgid "Sidebar|None"
msgstr ""
-msgid "Sidebar|Only numeral characters allowed"
-msgstr ""
-
-msgid "Sidebar|Weight"
-msgstr ""
-
msgid "Sidekiq job compression threshold (bytes)"
msgstr ""
@@ -33423,6 +34112,9 @@ msgstr ""
msgid "Slack logo"
msgstr ""
+msgid "SlackIntegration|Are you sure you want to remove this project from the Slack application?"
+msgstr ""
+
msgid "SlackIntegration|GitLab for Slack"
msgstr ""
@@ -33432,6 +34124,9 @@ msgstr ""
msgid "SlackIntegration|Project alias"
msgstr ""
+msgid "SlackIntegration|Remove project"
+msgstr ""
+
msgid "SlackIntegration|Select a GitLab project to link with your Slack workspace."
msgstr ""
@@ -33576,9 +34271,6 @@ msgstr ""
msgid "Something went wrong trying to load issue contacts."
msgstr ""
-msgid "Something went wrong when creating a work item. Please try again"
-msgstr ""
-
msgid "Something went wrong when reordering designs. Please try again"
msgstr ""
@@ -33672,9 +34364,6 @@ msgstr ""
msgid "Something went wrong while inserting your image. Please try again."
msgstr ""
-msgid "Something went wrong while merging this merge request. Please try again."
-msgstr ""
-
msgid "Something went wrong while obtaining the Let's Encrypt certificate."
msgstr ""
@@ -33996,10 +34685,10 @@ 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."
+msgid "SourcegraphAdmin|Learn more."
msgstr ""
-msgid "SourcegraphAdmin|More information"
+msgid "SourcegraphAdmin|Only public projects have code intelligence enabled and communicate with Sourcegraph."
msgstr ""
msgid "SourcegraphAdmin|Save changes"
@@ -34008,7 +34697,7 @@ msgstr ""
msgid "SourcegraphAdmin|Sourcegraph URL"
msgstr ""
-msgid "SourcegraphAdmin|e.g. https://sourcegraph.example.com"
+msgid "SourcegraphAdmin|https://sourcegraph.example.com"
msgstr ""
msgid "SourcegraphPreferences|This feature is experimental and currently limited to certain projects."
@@ -34143,6 +34832,9 @@ msgstr ""
msgid "Start date"
msgstr ""
+msgid "Start free trial"
+msgstr ""
+
msgid "Start merge train"
msgstr ""
@@ -34173,6 +34865,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started escalation for this incident."
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -34185,6 +34880,9 @@ msgstr ""
msgid "Starts at (UTC)"
msgstr ""
+msgid "Starts escalations for this incident"
+msgstr ""
+
msgid "Starts on"
msgstr ""
@@ -34446,6 +35144,9 @@ msgstr ""
msgid "Strikethrough"
msgstr ""
+msgid "Strikethrough text"
+msgstr ""
+
msgid "Subgroup information"
msgstr ""
@@ -34680,6 +35381,21 @@ msgstr ""
msgid "Subscriptions"
msgstr ""
+msgid "Subscriptions|Chat with sales"
+msgstr ""
+
+msgid "Subscriptions|Close"
+msgstr ""
+
+msgid "Subscriptions|Not ready to buy yet?"
+msgstr ""
+
+msgid "Subscriptions|Start a free trial"
+msgstr ""
+
+msgid "Subscriptions|We understand. Maybe you have some questions for our sales team, or maybe you'd like to try some of the paid features first. What would you like to do?"
+msgstr ""
+
msgid "Subscription|Your subscription for %{strong}%{namespace_name}%{strong_close} has expired and you are now on %{pricing_link_start}the GitLab Free tier%{pricing_link_end}. Don't worry, your data is safe. Get in touch with our support team (%{support_email}). They'll gladly help with your subscription renewal."
msgstr ""
@@ -34890,6 +35606,9 @@ msgstr ""
msgid "SuperSonics|Maximum users"
msgstr ""
+msgid "SuperSonics|Offline cloud"
+msgstr ""
+
msgid "SuperSonics|Paste your activation code"
msgstr ""
@@ -34956,6 +35675,12 @@ msgstr ""
msgid "SuperSonics|You do not have an active subscription"
msgstr ""
+msgid "SuperSonics|You have a future dated license"
+msgstr ""
+
+msgid "SuperSonics|You have added a license that activates on %{date}. Please see the subscription history table below for more details."
+msgstr ""
+
msgid "SuperSonics|You have successfully added a license that activates on %{date}. Please see the subscription history table below for more details."
msgstr ""
@@ -35115,6 +35840,9 @@ msgstr ""
msgid "Tag name is required"
msgstr ""
+msgid "Tag push"
+msgstr ""
+
msgid "Tag push events"
msgstr ""
@@ -35217,6 +35945,9 @@ msgstr ""
msgid "TagsPage|protected"
msgstr ""
+msgid "Take a look at the documentation to discover all of GitLab’s capabilities."
+msgstr ""
+
msgid "Target Branch"
msgstr ""
@@ -35619,6 +36350,9 @@ msgstr ""
msgid "Tests"
msgstr ""
+msgid "Text (optional)"
+msgstr ""
+
msgid "Text added to the body of all email messages. %{character_limit} character limit"
msgstr ""
@@ -35669,6 +36403,9 @@ msgstr ""
msgid "The CSV export will be created in the background. Once finished, it will be sent to %{email} in an attachment."
msgstr ""
+msgid "The CSV export you requested of all user memberships is attached to this email."
+msgstr ""
+
msgid "The GitLab subscription service (customers.gitlab.com) is currently experiencing an outage. You can monitor the status and get updates at %{linkStart}status.gitlab.com%{linkEnd}."
msgstr ""
@@ -35744,6 +36481,9 @@ 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 epic"
+msgstr ""
+
msgid "The current issue"
msgstr ""
@@ -35905,6 +36645,9 @@ msgstr ""
msgid "The latest pipeline for this merge request has failed."
msgstr ""
+msgid "The license key is invalid."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -35920,6 +36663,9 @@ msgstr ""
msgid "The license was successfully uploaded and will be active from %{starts_at}. You can see the details below."
msgstr ""
+msgid "The license you uploaded is invalid. If the issue persists, contact support at %{link}."
+msgstr ""
+
msgid "The list creation wizard is already open"
msgstr ""
@@ -36541,10 +37287,13 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} and everything this project contains. %{strongOpen}There is no going back%{strongClose}"
+msgstr ""
+
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains."
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}on %{date}%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains. %{strongOpen}There is no going back.%{strongClose}"
msgstr ""
msgid "This action will %{strongOpen}permanently remove%{strongClose} %{codeOpen}%{group}%{codeClose} %{strongOpen}immediately%{strongClose}."
@@ -36673,9 +37422,6 @@ msgstr ""
msgid "This file was modified for readability, and can't accept suggestions. Edit it directly."
msgstr ""
-msgid "This forked project has the following:"
-msgstr ""
-
msgid "This form is disabled in preview"
msgstr ""
@@ -36688,7 +37434,7 @@ msgstr ""
msgid "This group can't be removed because it is linked to a subscription. To remove this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
-msgid "This group can't be transfered because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
+msgid "This group can't be transferred because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
msgid "This group cannot be invited to a project inside a group with enforced SSO"
@@ -36715,6 +37461,9 @@ 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 incident is already escalated with '%{escalation_policy_name}'."
+msgstr ""
+
msgid "This invitation was sent to %{mail_to_invite_email}, but you are signed in as %{link_to_current_user} with email %{mail_to_current_user}."
msgstr ""
@@ -36733,9 +37482,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 merge train pipeline"
-msgstr ""
-
msgid "This is a private email address %{helpIcon} generated just for you. Anyone who has it can create issues or merge requests as if they were you. If that happens, %{resetLinkStart}reset this token%{resetLinkEnd}."
msgstr ""
@@ -36757,6 +37503,12 @@ msgstr ""
msgid "This is your current session"
msgstr ""
+msgid "This issue cannot be assigned to a confidential epic because it is public."
+msgstr ""
+
+msgid "This issue cannot be made public because it belongs to a confidential epic."
+msgstr ""
+
msgid "This issue is confidential and should only be visible to team members with at least Reporter access."
msgstr ""
@@ -36874,6 +37626,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 branch is protected from force push."
+msgstr ""
+
msgid "This merge request cannot be rebased while there are conflicts."
msgstr ""
@@ -36925,9 +37680,15 @@ msgstr ""
msgid "This pipeline was triggered by a schedule."
msgstr ""
+msgid "This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project"
msgstr ""
+msgid "This project can be restored until %{date}."
+msgstr ""
+
msgid "This project cannot be %{visibilityLevel} because the visibility of %{openShowLink}%{name}%{closeShowLink} is %{visibility}. To make this project %{visibilityLevel}, you must first %{openEditLink}change the visibility%{closeEditLink} of the parent group."
msgstr ""
@@ -36946,6 +37707,9 @@ msgstr ""
msgid "This project is %{strongStart}NOT%{strongEnd} a fork, and has the following:"
msgstr ""
+msgid "This project is %{strongStart}NOT%{strongEnd} a fork. This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -37637,6 +38401,9 @@ msgstr ""
msgid "Today"
msgstr ""
+msgid "Todos count"
+msgstr ""
+
msgid "Todos|Are you looking for things to do? Take a look at %{strongStart}%{openIssuesLinkStart}open issues%{openIssuesLinkEnd}%{strongEnd}, contribute to %{strongStart}%{mergeRequestLinkStart}a merge request%{mergeRequestLinkEnd}%{mergeRequestLinkEnd}%{strongEnd}, or mention someone in a comment to automatically assign them a new to-do item."
msgstr ""
@@ -37910,10 +38677,8 @@ msgstr ""
msgid "Trending"
msgstr ""
-msgid "Trials|%{planName} Trial %{enDash} %{num} day left"
-msgid_plural "Trials|%{planName} Trial %{enDash} %{num} days left"
-msgstr[0] ""
-msgstr[1] ""
+msgid "Trials|%{planName} Trial"
+msgstr ""
msgid "Trials|Compare all plans"
msgstr ""
@@ -37921,6 +38686,9 @@ msgstr ""
msgid "Trials|Create a new group to start your GitLab Ultimate trial."
msgstr ""
+msgid "Trials|Day %{daysUsed}/%{duration}"
+msgstr ""
+
msgid "Trials|Go back to GitLab"
msgstr ""
@@ -38170,7 +38938,7 @@ msgstr ""
msgid "URL is triggered when repository is updated"
msgstr ""
-msgid "URL must be percent-encoded if neccessary."
+msgid "URL must be percent-encoded if necessary."
msgstr ""
msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
@@ -38389,6 +39157,9 @@ msgstr ""
msgid "Unlock account"
msgstr ""
+msgid "Unlock more features with GitLab Ultimate"
+msgstr ""
+
msgid "Unlock the discussion"
msgstr ""
@@ -38452,6 +39223,9 @@ msgstr ""
msgid "Unsubscribes from this %{quick_action_target}."
msgstr ""
+msgid "Unsupported sort value."
+msgstr ""
+
msgid "Unsupported todo type passed. Supported todo types are: %{todo_types}"
msgstr ""
@@ -38680,6 +39454,9 @@ msgstr ""
msgid "UsageQuota|File attachments and smaller design graphics."
msgstr ""
+msgid "UsageQuota|From %{storage_enforcement_date} storage limits will apply to this namespace. View and manage your usage in %{strong_start}Group Settings &gt; Usage quotas%{strong_end}."
+msgstr ""
+
msgid "UsageQuota|Git repository."
msgstr ""
@@ -38740,6 +39517,9 @@ msgstr ""
msgid "UsageQuota|Storage type"
msgstr ""
+msgid "UsageQuota|Storage used"
+msgstr ""
+
msgid "UsageQuota|This is the total amount of storage used across your projects within this namespace."
msgstr ""
@@ -38935,6 +39715,12 @@ msgstr ""
msgid "Use hashed storage paths for newly created and renamed repositories. Always enabled since 13.0."
msgstr ""
+msgid "Use issue count"
+msgstr ""
+
+msgid "Use issue weight"
+msgstr ""
+
msgid "Use one line per URI"
msgstr ""
@@ -39316,6 +40102,9 @@ msgstr ""
msgid "Users"
msgstr ""
+msgid "Users API rate limit"
+msgstr ""
+
msgid "Users can launch a development environment from a GitLab browser tab when the %{linkStart}Gitpod%{linkEnd} integration is enabled."
msgstr ""
@@ -39641,6 +40430,9 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View group pipeline usage quota"
+msgstr ""
+
msgid "View incident details at"
msgstr ""
@@ -39793,6 +40585,9 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
+msgid "Vulnerability"
+msgstr ""
+
msgid "Vulnerability Report"
msgstr ""
@@ -39844,6 +40639,9 @@ msgstr ""
msgid "VulnerabilityManagement|An unverified non-confirmed finding"
msgstr ""
+msgid "VulnerabilityManagement|At least one identifier is required"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -39853,12 +40651,24 @@ msgstr ""
msgid "VulnerabilityManagement|Create Jira issue"
msgstr ""
+msgid "VulnerabilityManagement|Enter a name"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE code"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE identifier URL"
+msgstr ""
+
msgid "VulnerabilityManagement|Fetching linked Jira issues"
msgstr ""
msgid "VulnerabilityManagement|Manually add a vulnerability entry into the vulnerability report."
msgstr ""
+msgid "VulnerabilityManagement|Name is a required field"
+msgstr ""
+
msgid "VulnerabilityManagement|Needs triage"
msgstr ""
@@ -39874,6 +40684,18 @@ msgstr ""
msgid "VulnerabilityManagement|Select a method"
msgstr ""
+msgid "VulnerabilityManagement|Select a severity level"
+msgstr ""
+
+msgid "VulnerabilityManagement|Select a status"
+msgstr ""
+
+msgid "VulnerabilityManagement|Severity is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Something went wrong while creating vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -39898,6 +40720,12 @@ msgstr ""
msgid "VulnerabilityManagement|Something went wrong, could not update vulnerability state."
msgstr ""
+msgid "VulnerabilityManagement|Status is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Submit vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Summary, detailed description, steps to reproduce, etc."
msgstr ""
@@ -40093,6 +40921,9 @@ msgstr ""
msgid "WARNING:"
msgstr ""
+msgid "WARNING: This snippet contains hidden files which might be used to mask malicious behavior. Exercise caution if cloning and executing code from this snippet."
+msgstr ""
+
msgid "Wait for the file to load to copy its contents"
msgstr ""
@@ -40312,6 +41143,15 @@ msgstr ""
msgid "Webhooks|An issue is created, updated, closed, or reopened."
msgstr ""
+msgid "Webhooks|Are you sure you want to delete this group hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this project hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this webhook?"
+msgstr ""
+
msgid "Webhooks|Comments"
msgstr ""
@@ -40321,6 +41161,9 @@ msgstr ""
msgid "Webhooks|Confidential issues events"
msgstr ""
+msgid "Webhooks|Delete webhook"
+msgstr ""
+
msgid "Webhooks|Deployment events"
msgstr ""
@@ -40554,6 +41397,9 @@ msgstr ""
msgid "Wiki"
msgstr ""
+msgid "Wiki page"
+msgstr ""
+
msgid "Wiki page was successfully created."
msgstr ""
@@ -40659,7 +41505,7 @@ msgstr ""
msgid "WikiPageConflictMessage|Someone edited the page the same time you did. Please check out %{wikiLinkStart}the page%{wikiLinkEnd} and make sure your changes will not unintentionally remove theirs."
msgstr ""
-msgid "WikiPage|An error occured while trying to render the content editor. Please try again later."
+msgid "WikiPage|An error occurred while trying to render the content editor. Please try again later."
msgstr ""
msgid "WikiPage|Are you sure you want to switch back to the classic editor?"
@@ -40818,6 +41664,18 @@ msgstr ""
msgid "WorkItem|New Task"
msgstr ""
+msgid "WorkItem|Something went wrong when creating a work item. Please try again"
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching the work item. Please try again."
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching work item types. Please try again"
+msgstr ""
+
+msgid "WorkItem|Type"
+msgstr ""
+
msgid "WorkItem|Work Items"
msgstr ""
@@ -40884,7 +41742,10 @@ msgstr ""
msgid "You are about to add %{usersTag} people to the discussion. They will all receive a notification."
msgstr ""
-msgid "You are about to permanently delete this project"
+msgid "You are about to delete this forked project containing:"
+msgstr ""
+
+msgid "You are about to delete this project containing:"
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."
@@ -40905,6 +41766,9 @@ msgstr ""
msgid "You are attempting to update a file that has changed since you started editing it."
msgstr ""
+msgid "You are billed if you exceed this number. %{qsrOverageLinkStart}How does billing work?%{qsrOverageLinkEnd}"
+msgstr ""
+
msgid "You are connected to the Prometheus server, but there is currently no data to display."
msgstr ""
@@ -40962,6 +41826,9 @@ msgstr ""
msgid "You are not authorized to update this scanner profile"
msgstr ""
+msgid "You are not authorized to upload metric images"
+msgstr ""
+
msgid "You are now impersonating %{username}"
msgstr ""
@@ -41115,9 +41982,6 @@ msgstr ""
msgid "You can only upload one design when dropping onto an existing design."
msgstr ""
-msgid "You can recover this project until %{date}"
-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 ""
@@ -41166,9 +42030,6 @@ msgstr ""
msgid "You cannot write to this read-only GitLab instance."
msgstr ""
-msgid "You can’t %{tag_start}edit%{tag_end} files directly in this project. Fork this project and submit a merge request with your changes."
-msgstr ""
-
msgid "You can’t edit files directly in this project. Fork this project and submit a merge request with your changes."
msgstr ""
@@ -41321,9 +42182,6 @@ 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 set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
@@ -41354,12 +42212,6 @@ msgstr ""
msgid "You must have maintainer access to force delete a lock"
msgstr ""
-msgid "You must have permission to create a project in a group before forking."
-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 ""
@@ -41765,7 +42617,7 @@ msgstr ""
msgid "Your public email will be displayed on your public profile."
msgstr ""
-msgid "Your request for access could not be processed: %{error_meesage}"
+msgid "Your request for access could not be processed: %{error_message}"
msgstr ""
msgid "Your request for access has been queued for review."
@@ -41948,6 +42800,9 @@ msgstr ""
msgid "archived:"
msgstr ""
+msgid "artifacts"
+msgstr ""
+
msgid "assign yourself"
msgstr ""
@@ -41977,6 +42832,9 @@ msgstr[1] ""
msgid "branch name"
msgstr ""
+msgid "builds"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -42400,6 +43258,9 @@ msgstr ""
msgid "contact with same email already exists in group hierarchy"
msgstr ""
+msgid "container registry images"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -42439,6 +43300,9 @@ msgstr ""
msgid "data"
msgstr ""
+msgid "database"
+msgstr ""
+
msgid "date must not be after 9999-12-31"
msgstr ""
@@ -42462,9 +43326,6 @@ msgstr ""
msgid "design"
msgstr ""
-msgid "detached"
-msgstr ""
-
msgid "disabled"
msgstr ""
@@ -42713,7 +43574,7 @@ msgstr ""
msgid "is not a valid X509 certificate."
msgstr ""
-msgid "is not allowed for sign-up."
+msgid "is not allowed for sign-up. Please use your regular email address."
msgstr ""
msgid "is not allowed for this group."
@@ -42725,7 +43586,7 @@ msgstr ""
msgid "is not allowed since the group is not top-level group."
msgstr ""
-msgid "is not allowed."
+msgid "is not allowed. Please use your regular email address."
msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
@@ -42812,6 +43673,9 @@ msgstr ""
msgid "level: %{level}"
msgstr ""
+msgid "lfs objects"
+msgstr ""
+
msgid "limit of %{project_limit} reached"
msgstr ""
@@ -43031,6 +43895,9 @@ msgstr ""
msgid "mrWidget|Merge blocked: pipeline must succeed. It's waiting for a manual action to continue."
msgstr ""
+msgid "mrWidget|Merge blocked: pipeline must succeed. Push a commit that fixes the failure, or %{linkStart}learn about other solutions.%{linkEnd}"
+msgstr ""
+
msgid "mrWidget|Merge blocked: this merge request must be approved."
msgstr ""
@@ -43148,9 +44015,6 @@ msgstr ""
msgid "mrWidget|The changes were not merged into"
msgstr ""
-msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -43298,9 +44162,6 @@ msgstr ""
msgid "open issue"
msgstr ""
-msgid "opened %{timeAgo}"
-msgstr ""
-
msgid "or"
msgstr ""
@@ -43312,6 +44173,12 @@ msgid_plural "out of %d total tests"
msgstr[0] ""
msgstr[1] ""
+msgid "packages"
+msgstr ""
+
+msgid "pages"
+msgstr ""
+
msgid "parent"
msgid_plural "parents"
msgstr[0] ""
@@ -43461,6 +44328,9 @@ msgid_plural "replies"
msgstr[0] ""
msgstr[1] ""
+msgid "repositories"
+msgstr ""
+
msgid "repository:"
msgstr ""
@@ -43581,12 +44451,18 @@ msgstr ""
msgid "tag name"
msgstr ""
+msgid "terraform states"
+msgstr ""
+
msgid "the correct format."
msgstr ""
msgid "the file"
msgstr ""
+msgid "the following epic(s)"
+msgstr ""
+
msgid "the following issue(s)"
msgstr ""
@@ -43599,21 +44475,12 @@ msgstr ""
msgid "this document"
msgstr ""
-msgid "this issue cannot be assigned to a confidential epic since it is public"
-msgstr ""
-
-msgid "this issue cannot be made public since it belongs to a confidential epic"
-msgstr ""
-
msgid "time summary"
msgstr ""
msgid "toggle collapse"
msgstr ""
-msgid "train"
-msgstr ""
-
msgid "triggered"
msgstr ""
@@ -43742,3 +44609,6 @@ msgstr ""
msgid "{project}"
msgstr ""
+msgid "✔"
+msgstr ""
+
diff --git a/locale/fil_PH/gitlab.po b/locale/fil_PH/gitlab.po
index 494b17b465a..273ee4ee957 100644
--- a/locale/fil_PH/gitlab.po
+++ b/locale/fil_PH/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: fil\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2022-02-02 15:49\n"
+"PO-Revision-Date: 2022-03-01 20:41\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -146,6 +146,11 @@ msgid_plural "%d approvers (you've approved)"
msgstr[0] ""
msgstr[1] ""
+msgid "%d assigned issue"
+msgid_plural "%d assigned issues"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -421,8 +426,23 @@ msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
msgstr[1] ""
-msgid "%d vulnerability updated"
-msgid_plural "%d vulnerabilities updated"
+msgid "%d vulnerability set to confirmed"
+msgid_plural "%d vulnerabilities set to confirmed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to dismissed"
+msgid_plural "%d vulnerabilities set to dismissed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to needs triage"
+msgid_plural "%d vulnerabilities set to needs triage"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to resolved"
+msgid_plural "%d vulnerabilities set to resolved"
msgstr[0] ""
msgstr[1] ""
@@ -510,6 +530,12 @@ msgstr[1] ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{completed} of %{total} issues closed"
+msgstr ""
+
+msgid "%{completed} of %{total} weight completed"
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -858,6 +884,9 @@ msgstr ""
msgid "%{openedIssues} open, %{closedIssues} closed"
msgstr ""
+msgid "%{percentage}%% issues closed"
+msgstr ""
+
msgid "%{percentage}%% weight completed"
msgstr ""
@@ -1287,6 +1316,9 @@ msgid_plural "- Users"
msgstr[0] ""
msgstr[1] ""
+msgid "- of - issues closed"
+msgstr ""
+
msgid "- of - weight completed"
msgstr ""
@@ -1429,7 +1461,7 @@ msgstr ""
msgid "1000+"
msgstr ""
-msgid "192.168.0.0/24"
+msgid "192.168.0.0/24 or 2001:0DB8:1234::/48"
msgstr ""
msgid "1st contribution!"
@@ -1741,13 +1773,13 @@ msgstr ""
msgid "AWS Access Key"
msgstr ""
-msgid "AWS Access Key. Only required if not using role instance credentials"
+msgid "AWS Secret Access Key"
msgstr ""
-msgid "AWS Secret Access Key"
+msgid "AWS access key ID (Optional)"
msgstr ""
-msgid "AWS Secret Access Key. Only required if not using role instance credentials"
+msgid "AWS secret access key (Optional)"
msgstr ""
msgid "AWS service error: %{error}"
@@ -1807,9 +1839,6 @@ msgstr ""
msgid "Access granted"
msgstr ""
-msgid "Access key ID"
-msgstr ""
-
msgid "Access requests"
msgstr ""
@@ -1984,7 +2013,7 @@ msgstr ""
msgid "Activity"
msgstr ""
-msgid "Activity|An error occured while retrieving activity. Reload the page to try again."
+msgid "Activity|An error occurred while retrieving activity. Reload the page to try again."
msgstr ""
msgid "Add"
@@ -2023,6 +2052,9 @@ msgstr ""
msgid "Add a %{type}"
msgstr ""
+msgid "Add a GCP region"
+msgstr ""
+
msgid "Add a GPG key"
msgstr ""
@@ -2074,6 +2106,9 @@ msgstr ""
msgid "Add a numbered list"
msgstr ""
+msgid "Add a related epic"
+msgstr ""
+
msgid "Add a related issue"
msgstr ""
@@ -2188,6 +2223,9 @@ msgstr ""
msgid "Add or subtract spent time"
msgstr ""
+msgid "Add people"
+msgstr ""
+
msgid "Add previously merged commits"
msgstr ""
@@ -2254,6 +2292,9 @@ msgstr ""
msgid "Add webhook"
msgstr ""
+msgid "Add your team members and others to GitLab."
+msgstr ""
+
msgid "Add/remove"
msgstr ""
@@ -3076,12 +3117,6 @@ msgstr ""
msgid "AdvancedSearch|Reindex required"
msgstr ""
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. Permanently deleting this project will %{strongStart}immediately delete%{strongEnd} its repositories and %{strongStart}all related resources%{strongEnd}, including issues, merge requests etc."
-msgstr ""
-
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. You will lose this project's repository and %{strongStart}all related resources%{strongEnd}, including issues and merge requests."
-msgstr ""
-
msgid "After a successful password update you will be redirected to login screen."
msgstr ""
@@ -3112,6 +3147,9 @@ msgstr ""
msgid "Akismet helps prevent the creation of spam issues in public projects."
msgstr ""
+msgid "Alert"
+msgstr ""
+
msgid "AlertManagement|Acknowledged"
msgstr ""
@@ -3484,9 +3522,6 @@ msgstr ""
msgid "All environments"
msgstr ""
-msgid "All epics"
-msgstr ""
-
msgid "All groups and projects"
msgstr ""
@@ -4223,12 +4258,15 @@ msgstr ""
msgid "ApplicationSettings|Approve users in the pending approval status?"
msgstr ""
-msgid "ApplicationSettings|By making this change, you will automatically approve %d user with the pending approval status."
-msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users with the pending approval status."
+msgid "ApplicationSettings|Approve users who are pending approval?"
+msgstr ""
+
+msgid "ApplicationSettings|By making this change, you will automatically approve %d user who is pending approval."
+msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users who are pending approval."
msgstr[0] ""
msgstr[1] ""
-msgid "ApplicationSettings|By making this change, you will automatically approve all users in pending approval status."
+msgid "ApplicationSettings|By making this change, you will automatically approve all users who are pending approval."
msgstr ""
msgid "ApplicationSettings|Denied domains for sign-ups"
@@ -4634,10 +4672,10 @@ msgstr ""
msgid "Archiving the project will make it entirely read-only. It is hidden from the dashboard and doesn't show up in searches. %{strong_start}The repository cannot be committed to, and no issues, comments, or other entities can be created.%{strong_end} %{link_start}Learn more.%{link_end}"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to delete this project?"
+msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
+msgid "Are you absolutely sure?"
msgstr ""
msgid "Are you sure that you want to archive this project?"
@@ -4673,12 +4711,18 @@ msgstr ""
msgid "Are you sure you want to delete this SSH key?"
msgstr ""
+msgid "Are you sure you want to delete this comment?"
+msgstr ""
+
msgid "Are you sure you want to delete this deploy key?"
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 label?"
+msgstr ""
+
msgid "Are you sure you want to delete this pipeline schedule?"
msgstr ""
@@ -4694,9 +4738,6 @@ msgstr ""
msgid "Are you sure you want to discard your changes?"
msgstr ""
-msgid "Are you sure you want to erase this build?"
-msgstr ""
-
msgid "Are you sure you want to import %d repository?"
msgid_plural "Are you sure you want to import %d repositories?"
msgstr[0] ""
@@ -4744,6 +4785,9 @@ msgstr ""
msgid "Are you sure you want to remove this list?"
msgstr ""
+msgid "Are you sure you want to remove this nickname?"
+msgstr ""
+
msgid "Are you sure you want to reset the health check token?"
msgstr ""
@@ -4756,10 +4800,10 @@ 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?"
+msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
msgstr ""
-msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
+msgid "Are you sure you want to revoke this project access token? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to stop this environment?"
@@ -4906,9 +4950,6 @@ msgstr ""
msgid "Assigned to %{assignee_name}"
msgstr ""
-msgid "Assigned to %{name}"
-msgstr ""
-
msgid "Assigned to me"
msgstr ""
@@ -4973,6 +5014,9 @@ msgstr[1] ""
msgid "Attaching the file failed."
msgstr ""
+msgid "Attention"
+msgstr ""
+
msgid "Audit Events"
msgstr ""
@@ -5135,6 +5179,12 @@ msgstr ""
msgid "Authorized applications (%{size})"
msgstr ""
+msgid "AuthorizedApplication|Are you sure you want to revoke this application?"
+msgstr ""
+
+msgid "AuthorizedApplication|Revoke application"
+msgstr ""
+
msgid "Authors: %{authors}"
msgstr ""
@@ -6328,6 +6378,9 @@ msgstr ""
msgid "CICDAnalytics|Shared Runners Usage"
msgstr ""
+msgid "CICDAnalytics|Shared runner pipeline minute duration by month"
+msgstr ""
+
msgid "CICDAnalytics|Shared runner usage"
msgstr ""
@@ -6469,6 +6522,9 @@ msgstr ""
msgid "Can create groups:"
msgstr ""
+msgid "Can not delete primary training"
+msgstr ""
+
msgid "Can't apply as the source branch was deleted."
msgstr ""
@@ -6802,9 +6858,6 @@ msgstr ""
msgid "Changing any setting here requires an application restart"
msgstr ""
-msgid "Changing group URL can have unintended side effects."
-msgstr ""
-
msgid "Charts can't be displayed as the request for data has timed out. %{documentationLink}"
msgstr ""
@@ -6892,9 +6945,6 @@ msgstr ""
msgid "Checking branch availability..."
msgstr ""
-msgid "Checking group URL availability..."
-msgstr ""
-
msgid "Checking group path availability..."
msgstr ""
@@ -7388,6 +7438,9 @@ msgstr ""
msgid "Clear recent searches"
msgstr ""
+msgid "Clear repository checks"
+msgstr ""
+
msgid "Clear search"
msgstr ""
@@ -7520,9 +7573,6 @@ msgstr ""
msgid "Closed MRs"
msgstr ""
-msgid "Closed epics"
-msgstr ""
-
msgid "Closed issues"
msgstr ""
@@ -7559,13 +7609,13 @@ msgstr ""
msgid "Cluster level"
msgstr ""
-msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
+msgid "Cluster type must be specified for Stages::ClusterEndpointInserter"
msgstr ""
msgid "ClusterAgents|%{name} successfully deleted"
msgstr ""
-msgid "ClusterAgents|%{number} of %{total} Agents"
+msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
@@ -7607,6 +7657,15 @@ msgstr ""
msgid "ClusterAgents|Agent never connected to GitLab"
msgstr ""
+msgid "ClusterAgents|Agent version mismatch"
+msgstr ""
+
+msgid "ClusterAgents|Agent version mismatch and update"
+msgstr ""
+
+msgid "ClusterAgents|Agent version update required"
+msgstr ""
+
msgid "ClusterAgents|All"
msgstr ""
@@ -7631,7 +7690,7 @@ msgstr ""
msgid "ClusterAgents|Configuration"
msgstr ""
-msgid "ClusterAgents|Connect a cluster through the Agent"
+msgid "ClusterAgents|Connect a cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connect existing cluster"
@@ -7640,13 +7699,13 @@ msgstr ""
msgid "ClusterAgents|Connect with a certificate"
msgstr ""
-msgid "ClusterAgents|Connect with agent"
+msgid "ClusterAgents|Connect with an agent"
msgstr ""
msgid "ClusterAgents|Connect with the GitLab Agent"
msgstr ""
-msgid "ClusterAgents|Connect your cluster through the Agent"
+msgid "ClusterAgents|Connect your cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connected"
@@ -7706,7 +7765,10 @@ msgstr ""
msgid "ClusterAgents|How to register an agent?"
msgstr ""
-msgid "ClusterAgents|Install new Agent"
+msgid "ClusterAgents|How to update an agent?"
+msgstr ""
+
+msgid "ClusterAgents|Install a new agent"
msgstr ""
msgid "ClusterAgents|Last connected %{timeAgo}."
@@ -7733,7 +7795,7 @@ msgstr ""
msgid "ClusterAgents|Never connected"
msgstr ""
-msgid "ClusterAgents|No Agents"
+msgid "ClusterAgents|No agents"
msgstr ""
msgid "ClusterAgents|No clusters connected through cluster certificates"
@@ -7793,6 +7855,9 @@ msgstr ""
msgid "ClusterAgents|The agent has not been connected in a long time. There might be a connectivity issue. Last contact was %{timeAgo}."
msgstr ""
+msgid "ClusterAgents|The agent version do not match each other across your cluster's pods. This can happen when a new agent version was just deployed and Kubernetes is shutting down the old pods."
+msgstr ""
+
msgid "ClusterAgents|The recommended installation method includes the token. If you want to follow the advanced installation method provided in the docs, make sure you save the token value before you close this window."
msgstr ""
@@ -7840,6 +7905,9 @@ msgstr ""
msgid "ClusterAgents|You will need to create a token to connect to your agent"
msgstr ""
+msgid "ClusterAgents|Your agent version is out of sync with your GitLab version (v%{version}), which might cause compatibility problems. Update the agent installed on your cluster to the most recent version."
+msgstr ""
+
msgid "ClusterAgents|Your instance doesn't have the %{linkStart}GitLab Agent Server (KAS)%{linkEnd} set up. Ask a GitLab Administrator to install it."
msgstr ""
@@ -8716,9 +8784,6 @@ msgstr ""
msgid "Comma-separated list of email addresses."
msgstr ""
-msgid "Comma-separated list of users allowed to exceed the rate limit."
-msgstr ""
-
msgid "Comma-separated, e.g. '1.1.1.1, 2.2.2.0/24'"
msgstr ""
@@ -9045,6 +9110,12 @@ msgstr ""
msgid "Confidential"
msgstr ""
+msgid "Confidential issue"
+msgstr ""
+
+msgid "Confidential note"
+msgstr ""
+
msgid "Confidentiality"
msgstr ""
@@ -9078,6 +9149,9 @@ msgstr ""
msgid "Configure Dependency Scanning in `.gitlab-ci.yml`, creating this file if it does not already exist"
msgstr ""
+msgid "Configure GitLab"
+msgstr ""
+
msgid "Configure GitLab runners to start using the Web Terminal. %{helpStart}Learn more.%{helpEnd}"
msgstr ""
@@ -9126,6 +9200,15 @@ msgstr ""
msgid "Configure pipelines to deploy web apps, backend services, APIs and static resources to Google Cloud"
msgstr ""
+msgid "Configure region"
+msgstr ""
+
+msgid "Configure region for environment"
+msgstr ""
+
+msgid "Configure regions"
+msgstr ""
+
msgid "Configure repository mirroring."
msgstr ""
@@ -9159,6 +9242,9 @@ msgstr ""
msgid "Configure which lists are shown for anyone who visits this board"
msgstr ""
+msgid "Configure your environments to be deployed to specific geographical regions"
+msgstr ""
+
msgid "Confirm"
msgstr ""
@@ -9861,10 +9947,10 @@ msgstr ""
msgid "CorpusManagement|Actions"
msgstr ""
-msgid "CorpusManagement|Corpus are used in fuzz testing as mutation source to Improve future testing."
+msgid "CorpusManagement|Corpus file"
msgstr ""
-msgid "CorpusManagement|Corpus file"
+msgid "CorpusManagement|Corpus files are used in coverage-guided fuzz testing as seed inputs to improve testing."
msgstr ""
msgid "CorpusManagement|Corpus files must be in *.zip format. Maximum 5 GB"
@@ -9918,6 +10004,9 @@ msgstr ""
msgid "Could not apply %{name} command."
msgstr ""
+msgid "Could not apply %{name} command. %{message}."
+msgstr ""
+
msgid "Could not authorize chat nickname. Try again!"
msgstr ""
@@ -10068,6 +10157,9 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
+msgid "Create a group"
+msgstr ""
+
msgid "Create a merge request"
msgstr ""
@@ -10092,6 +10184,9 @@ msgstr ""
msgid "Create a personal access token on your account to pull or push via %{protocol}."
msgstr ""
+msgid "Create a project"
+msgstr ""
+
msgid "Create an account using:"
msgstr ""
@@ -10455,6 +10550,9 @@ msgstr ""
msgid "Creation date"
msgstr ""
+msgid "Creator"
+msgstr ""
+
msgid "Credentials"
msgstr ""
@@ -10467,9 +10565,15 @@ msgstr ""
msgid "CredentialsInventory|Personal Access Tokens"
msgstr ""
+msgid "CredentialsInventory|Project Access Tokens"
+msgstr ""
+
msgid "CredentialsInventory|SSH Keys"
msgstr ""
+msgid "Credit card required to be on file in order to create a pipeline"
+msgstr ""
+
msgid "Credit card:"
msgstr ""
@@ -10653,9 +10757,6 @@ msgstr ""
msgid "Customer relations"
msgstr ""
-msgid "Customizable by an administrator."
-msgstr ""
-
msgid "Customizable by owners."
msgstr ""
@@ -10785,30 +10886,18 @@ msgstr ""
msgid "CycleAnalytics|%{selectedLabelsCount} selected (%{maxLabels} max)"
msgstr ""
-msgid "CycleAnalytics|%{stageCount} stages selected"
-msgstr ""
-
-msgid "CycleAnalytics|All stages"
-msgstr ""
-
-msgid "CycleAnalytics|Average days to completion"
+msgid "CycleAnalytics|Average time to completion"
msgstr ""
msgid "CycleAnalytics|Date"
msgstr ""
-msgid "CycleAnalytics|Days to completion"
-msgstr ""
-
msgid "CycleAnalytics|Display chart filters"
msgstr ""
msgid "CycleAnalytics|Lead Time for Changes"
msgstr ""
-msgid "CycleAnalytics|No stages selected"
-msgstr ""
-
msgid "CycleAnalytics|Number of tasks"
msgstr ""
@@ -10837,18 +10926,30 @@ msgstr ""
msgid "CycleAnalytics|Showing data for group '%{groupName}' from %{createdAfter} to %{createdBefore}"
msgstr ""
-msgid "CycleAnalytics|Stages"
+msgid "CycleAnalytics|Stage time: %{title}"
msgstr ""
msgid "CycleAnalytics|Tasks by type"
msgstr ""
-msgid "CycleAnalytics|The average time spent in the selected stage for the items that were completed on each date. Data limited to the last 500 items."
+msgid "CycleAnalytics|The average time items spent in this stage. Data limited to items completed within this date range."
msgstr ""
msgid "CycleAnalytics|The given date range is larger than 180 days"
msgstr ""
+msgid "CycleAnalytics|The total time items spent across each value stream stage. Data limited to items completed within this date range."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Stage time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Total time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|Total time"
+msgstr ""
+
msgid "CycleAnalytics|Type of work"
msgstr ""
@@ -10861,9 +10962,6 @@ msgstr ""
msgid "CycleAnalytics|project dropdown filter"
msgstr ""
-msgid "CycleAnalytics|stage dropdown"
-msgstr ""
-
msgid "DAG visualization requires at least 3 dependent jobs."
msgstr ""
@@ -10963,10 +11061,16 @@ msgstr ""
msgid "DastProfiles|AJAX spider"
msgstr ""
+msgid "DastProfiles|API"
+msgstr ""
+
+msgid "DastProfiles|API endpoint URL"
+msgstr ""
+
msgid "DastProfiles|Active"
msgstr ""
-msgid "DastProfiles|Additional request headers (Optional)"
+msgid "DastProfiles|Additional request headers (optional)"
msgstr ""
msgid "DastProfiles|Are you sure you want to delete this profile?"
@@ -10981,6 +11085,9 @@ msgstr ""
msgid "DastProfiles|Branch missing"
msgstr ""
+msgid "DastProfiles|Choose a scan method"
+msgstr ""
+
msgid "DastProfiles|Could not create the scanner profile. Please try again."
msgstr ""
@@ -11050,7 +11157,13 @@ msgstr ""
msgid "DastProfiles|Excluded URLs"
msgstr ""
-msgid "DastProfiles|Excluded URLs (Optional)"
+msgid "DastProfiles|Excluded URLs (optional)"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths (optional)"
msgstr ""
msgid "DastProfiles|Hide debug messages"
@@ -11107,9 +11220,6 @@ msgstr ""
msgid "DastProfiles|Request headers"
msgstr ""
-msgid "DastProfiles|Rest API"
-msgstr ""
-
msgid "DastProfiles|Run the AJAX spider, in addition to the traditional spider, to crawl the target site."
msgstr ""
@@ -11119,6 +11229,9 @@ msgstr ""
msgid "DastProfiles|Save profile"
msgstr ""
+msgid "DastProfiles|Scan method"
+msgstr ""
+
msgid "DastProfiles|Scan mode"
msgstr ""
@@ -11197,12 +11310,24 @@ msgstr ""
msgid "DastProfiles|Website"
msgstr ""
+msgid "DastProfiles|What does each method do?"
+msgstr ""
+
msgid "DastProfiles|You can either choose a passive scan or validate the target site from the site profile management page. %{docsLinkStart}Learn more about site validation.%{docsLinkEnd}"
msgstr ""
msgid "DastProfiles|You cannot run an active scan against an unvalidated site."
msgstr ""
+msgid "DastProfiles|folder/dast_example.har or https://example.com/dast_example.har"
+msgstr ""
+
+msgid "DastProfiles|folder/example.postman_collection.json or https://example.com/"
+msgstr ""
+
+msgid "DastProfiles|folder/openapi.json or https://example.com/openapi.json"
+msgstr ""
+
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
@@ -11310,6 +11435,9 @@ msgstr ""
msgid "DatadogIntegration|API URL"
msgstr ""
+msgid "DatadogIntegration|Custom tags in Datadog. Enter one tag per line in the %{codeOpen}key:value%{codeClose} format. %{linkOpen}How do I use tags?%{linkClose}"
+msgstr ""
+
msgid "DatadogIntegration|Environment"
msgstr ""
@@ -11328,12 +11456,18 @@ msgstr ""
msgid "DatadogIntegration|Tag all data from this GitLab instance in Datadog. Useful when managing several self-managed deployments."
msgstr ""
+msgid "DatadogIntegration|Tags"
+msgstr ""
+
msgid "DatadogIntegration|The Datadog site to send data to. To send data to the EU site, use %{codeOpen}datadoghq.eu%{codeClose}."
msgstr ""
msgid "DatadogIntegration|Trace your GitLab pipelines with Datadog."
msgstr ""
+msgid "DatadogIntegration|have an invalid format"
+msgstr ""
+
msgid "Datasource name not found"
msgstr ""
@@ -11343,9 +11477,6 @@ msgstr ""
msgid "Date merged"
msgstr ""
-msgid "Date picker"
-msgstr ""
-
msgid "Date range"
msgstr ""
@@ -11499,9 +11630,6 @@ msgstr ""
msgid "Definition"
msgstr ""
-msgid "Delayed Project Deletion (%{adjourned_deletion})"
-msgstr ""
-
msgid "DelayedJobs|Are you sure you want to run %{jobName} immediately? Otherwise this job will run automatically after its timer finishes."
msgstr ""
@@ -11580,10 +11708,10 @@ msgstr ""
msgid "Delete pipeline"
msgstr ""
-msgid "Delete project"
+msgid "Delete pipeline schedule"
msgstr ""
-msgid "Delete project. Are you ABSOLUTELY SURE?"
+msgid "Delete project"
msgstr ""
msgid "Delete row"
@@ -11613,6 +11741,9 @@ msgstr ""
msgid "Delete this epic and all descendants?"
msgstr ""
+msgid "Delete this project"
+msgstr ""
+
msgid "Delete user list"
msgstr ""
@@ -11871,6 +12002,12 @@ msgstr ""
msgid "Deploy to..."
msgstr ""
+msgid "DeployBoards|To see deployment progress for your environments, make sure you are deploying to %{codeStart}$KUBE_NAMESPACE%{codeEnd} and annotating with %{codeStart}app.gitlab.com/app=$CI_PROJECT_PATH_SLUG%{codeEnd} and %{codeStart}app.gitlab.com/env=$CI_ENVIRONMENT_SLUG%{codeEnd}."
+msgstr ""
+
+msgid "DeployBoard|Kubernetes Pods"
+msgstr ""
+
msgid "DeployFreeze|Add a freeze period to prevent unintended releases during a period of time for a given environment. You must update the deployment jobs in %{filename} according to the deploy freezes added here. %{freeze_period_link_start}Learn more.%{freeze_period_link_end}"
msgstr ""
@@ -11955,9 +12092,6 @@ msgstr ""
msgid "DeployTokens|Active Deploy Tokens (%{active_tokens})"
msgstr ""
-msgid "DeployTokens|Allows read and write access to registry images."
-msgstr ""
-
msgid "DeployTokens|Allows read and write access to the package registry."
msgstr ""
@@ -11970,6 +12104,9 @@ msgstr ""
msgid "DeployTokens|Allows read-only access to the repository."
msgstr ""
+msgid "DeployTokens|Allows write access to registry images."
+msgstr ""
+
msgid "DeployTokens|Copy deploy token"
msgstr ""
@@ -12063,12 +12200,57 @@ msgstr ""
msgid "Deploying to AWS is easy with GitLab"
msgstr ""
+msgid "Deployment"
+msgstr ""
+
msgid "Deployment Frequency"
msgstr ""
+msgid "Deployment Target|Project deployment target (optional)"
+msgstr ""
+
+msgid "Deployment Target|Select the deployment target"
+msgstr ""
+
msgid "Deployment frequency"
msgstr ""
+msgid "DeploymentTarget|GitLab Pages"
+msgstr ""
+
+msgid "DeploymentTarget|Heroku"
+msgstr ""
+
+msgid "DeploymentTarget|Infrastructure provider (Terraform, Cloudformation, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Kubernetes (GKE, EKS, OpenShift, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Managed container runtime (Fargate, Cloud Run, DigitalOcean App)"
+msgstr ""
+
+msgid "DeploymentTarget|Mobile app store"
+msgstr ""
+
+msgid "DeploymentTarget|No deployment planned"
+msgstr ""
+
+msgid "DeploymentTarget|Other hosting service"
+msgstr ""
+
+msgid "DeploymentTarget|Registry (package or container)"
+msgstr ""
+
+msgid "DeploymentTarget|Self-managed container runtime (Podman, Docker Swarm, Docker Compose)"
+msgstr ""
+
+msgid "DeploymentTarget|Serverless backend (Lambda, Cloud functions)"
+msgstr ""
+
+msgid "DeploymentTarget|Virtual machine (for example, EC2)"
+msgstr ""
+
msgid "Deployments"
msgstr ""
@@ -12107,6 +12289,9 @@ msgstr ""
msgid "Deployment|This deployment was created using the API"
msgstr ""
+msgid "Deployment|Triggerer"
+msgstr ""
+
msgid "Deployment|Waiting"
msgstr ""
@@ -12134,6 +12319,18 @@ msgstr ""
msgid "Deprecated API rate limits"
msgstr ""
+msgid "Deprecations|Feature deprecation and removal"
+msgstr ""
+
+msgid "Deprecations|For information on a possible replacement %{epicStart} learn more about Opstrace %{epicEnd}."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7 and are %{epicStart} scheduled for removal %{epicEnd} in GitLab 15.0."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7, and are %{removal_link_start} scheduled for removal %{link_end} in GitLab 15.0. For information on a possible replacement, %{opstrace_link_start} learn more about Opstrace %{link_end}."
+msgstr ""
+
msgid "Deprioritize label"
msgstr ""
@@ -12379,10 +12576,10 @@ msgstr ""
msgid "DevopsAdoption|At least one deploy"
msgstr ""
-msgid "DevopsAdoption|At least one issue opened"
+msgid "DevopsAdoption|At least one issue created"
msgstr ""
-msgid "DevopsAdoption|At least one merge request opened"
+msgid "DevopsAdoption|At least one merge request created"
msgstr ""
msgid "DevopsAdoption|At least one pipeline successfully run"
@@ -12583,6 +12780,9 @@ msgstr ""
msgid "Direct member"
msgstr ""
+msgid "Direct members"
+msgstr ""
+
msgid "Direct non-authenticated users to this page."
msgstr ""
@@ -12699,6 +12899,9 @@ msgid_plural "Dismiss %d selected vulnerabilities as"
msgstr[0] ""
msgstr[1] ""
+msgid "Dismiss Alert"
+msgstr ""
+
msgid "Dismiss merge request promotion"
msgstr ""
@@ -12726,9 +12929,15 @@ msgstr ""
msgid "Display alerts from all configured monitoring tools."
msgstr ""
+msgid "Display milestones"
+msgstr ""
+
msgid "Display name"
msgstr ""
+msgid "Display progress of child issues"
+msgstr ""
+
msgid "Display rendered file"
msgstr ""
@@ -12834,6 +13043,9 @@ msgstr ""
msgid "Download image"
msgstr ""
+msgid "Download payload"
+msgstr ""
+
msgid "Download raw data (.csv)"
msgstr ""
@@ -13011,6 +13223,9 @@ msgstr ""
msgid "Edit in Web IDE"
msgstr ""
+msgid "Edit in pipeline editor"
+msgstr ""
+
msgid "Edit in single-file editor"
msgstr ""
@@ -13053,6 +13268,9 @@ msgstr ""
msgid "Edit your most recent comment in a thread (from an empty textarea)"
msgstr ""
+msgid "Edit, lint, and visualize your pipeline."
+msgstr ""
+
msgid "Edited"
msgstr ""
@@ -13494,6 +13712,9 @@ msgstr ""
msgid "Enforce two-factor authentication for all user sign-ins."
msgstr ""
+msgid "Enhance security by storing service account keys in secret managers - learn more about %{docLinkStart}secret management with GitLab%{docLinkEnd}"
+msgstr ""
+
msgid "Ensure connectivity is available from the GitLab server to the Prometheus server"
msgstr ""
@@ -13554,6 +13775,9 @@ 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 following to confirm:"
+msgstr ""
+
msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
@@ -14084,9 +14308,6 @@ 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 ""
@@ -14222,6 +14443,9 @@ msgstr ""
msgid "Errors:"
msgstr ""
+msgid "Escalate this incident"
+msgstr ""
+
msgid "Escalation Policies"
msgstr ""
@@ -14234,6 +14458,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy"
+msgstr ""
+
msgid "Escalation policy:"
msgstr ""
@@ -14485,6 +14712,9 @@ msgstr ""
msgid "Existing sign in methods may be removed"
msgstr ""
+msgid "Exit."
+msgstr ""
+
msgid "Expand"
msgstr ""
@@ -14581,6 +14811,9 @@ msgstr ""
msgid "Explore public groups"
msgstr ""
+msgid "Explore public projects"
+msgstr ""
+
msgid "Explore snippets"
msgstr ""
@@ -14742,7 +14975,7 @@ msgid_plural "Failed to archive designs. Please try again."
msgstr[0] ""
msgstr[1] ""
-msgid "Failed to assign a reviewer because no user was found."
+msgid "Failed to assign a reviewer because no user was specified."
msgstr ""
msgid "Failed to assign a user because no user was found."
@@ -14808,10 +15041,10 @@ msgstr ""
msgid "Failed to find import label for Jira import."
msgstr ""
-msgid "Failed to generate export, please try again later."
+msgid "Failed to find users for %{missing}"
msgstr ""
-msgid "Failed to generate report, please try again after sometime"
+msgid "Failed to generate export, please try again later."
msgstr ""
msgid "Failed to get ref."
@@ -14910,6 +15143,9 @@ msgstr ""
msgid "Failed to remove a to-do item for the design."
msgstr ""
+msgid "Failed to remove attention because no user was found."
+msgstr ""
+
msgid "Failed to remove mirror."
msgstr ""
@@ -14922,6 +15158,9 @@ msgstr ""
msgid "Failed to remove user key."
msgstr ""
+msgid "Failed to request attention because no user was found."
+msgstr ""
+
msgid "Failed to reset key. Please try again."
msgstr ""
@@ -15003,6 +15242,9 @@ msgstr ""
msgid "Feature Flags"
msgstr ""
+msgid "Feature deprecation and removal"
+msgstr ""
+
msgid "Feature flag status"
msgstr ""
@@ -15500,7 +15742,7 @@ msgstr ""
msgid "For each job, re-use the project workspace. If the workspace doesn't exist, use %{code_open}git clone%{code_close}."
msgstr ""
-msgid "For example, the application using the token or the purpose of the token."
+msgid "For example, the application using the token or the purpose of the token. Do not give sensitive information for the name of the token, as it will be visible to all %{resource_type} members."
msgstr ""
msgid "For files larger than this limit, only index the file name. The file content is neither indexed nor searchable."
@@ -15584,9 +15826,6 @@ msgstr ""
msgid "ForkProject|Select a namespace"
msgstr ""
-msgid "ForkProject|Select a namespace to fork the project"
-msgstr ""
-
msgid "ForkProject|The project can be accessed by any logged in user."
msgstr ""
@@ -15683,6 +15922,9 @@ msgstr ""
msgid "Full name"
msgstr ""
+msgid "GCP region configured"
+msgstr ""
+
msgid "GPG Key ID:"
msgstr ""
@@ -15863,6 +16105,9 @@ msgstr ""
msgid "Geo|Failed"
msgstr ""
+msgid "Geo|Filter Geo sites"
+msgstr ""
+
msgid "Geo|Filter by name"
msgstr ""
@@ -16274,6 +16519,12 @@ msgstr ""
msgid "GitLab Issue"
msgstr ""
+msgid "GitLab KAS"
+msgstr ""
+
+msgid "GitLab Memberships CSV Export"
+msgstr ""
+
msgid "GitLab Pages"
msgstr ""
@@ -16322,6 +16573,9 @@ 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 free to use. Many features for larger teams are part of our %{link_start}paid products%{link_end}. You can try Ultimate for free without any obligation or payment details."
+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 ""
@@ -16448,7 +16702,7 @@ msgstr ""
msgid "GitLabPages|When enabled, all attempts to visit your website through HTTP are automatically redirected to HTTPS using a response with status code 301. Requires a valid certificate for all domains. %{docs_link_start}Learn more.%{link_end}"
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. %{docs_link_start}Learn more.%{link_end}"
+msgid "GitLabPages|When using Pages under the general domain of a GitLab instance (%{pages_host}), you cannot use HTTPS with subdomains of subdomains. If your namespace or groupname contains a dot, it does not work. This is a limitation of the HTTP Over TLS protocol. HTTP pages work if you don't redirect HTTP to HTTPS. %{docs_link_start}Learn more.%{link_end}"
msgstr ""
msgid "GitLabPages|With GitLab Pages you can host your static website directly from your GitLab repository. %{docs_link_start}Learn more.%{link_end}"
@@ -16625,9 +16879,6 @@ msgstr ""
msgid "Go to find file"
msgstr ""
-msgid "Go to fork"
-msgstr ""
-
msgid "Go to issue boards"
msgstr ""
@@ -16835,9 +17086,6 @@ msgstr ""
msgid "Group Hooks"
msgstr ""
-msgid "Group ID"
-msgstr ""
-
msgid "Group Owner must have signed in with SAML before enabling Group Managed Accounts"
msgstr ""
@@ -16865,9 +17113,6 @@ msgstr ""
msgid "Group by"
msgstr ""
-msgid "Group description"
-msgstr ""
-
msgid "Group description (optional)"
msgstr ""
@@ -16982,7 +17227,7 @@ msgstr ""
msgid "Group: %{name}"
msgstr ""
-msgid "GroupActivityMetrics|Issues opened"
+msgid "GroupActivityMetrics|Issues created"
msgstr ""
msgid "GroupActivityMetrics|Last 90 days"
@@ -16991,7 +17236,7 @@ msgstr ""
msgid "GroupActivityMetrics|Members added"
msgstr ""
-msgid "GroupActivityMetrics|Merge Requests opened"
+msgid "GroupActivityMetrics|Merge Requests created"
msgstr ""
msgid "GroupActivityMetrics|Recent activity"
@@ -17282,6 +17527,9 @@ msgstr ""
msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
+msgid "GroupSettings|Choose a group path that does not start with a dash or end with a period. It can also contain alphanumeric characters and underscores."
+msgstr ""
+
msgid "GroupSettings|Compliance frameworks"
msgstr ""
@@ -17315,7 +17563,7 @@ msgstr ""
msgid "GroupSettings|If not specified at the group or instance level, the default is %{default_initial_branch_name}. Does not affect existing repositories."
msgstr ""
-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."
+msgid "GroupSettings|If the parent group's visibility is lower than the group's current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility."
msgstr ""
msgid "GroupSettings|New runners registration token has been generated!"
@@ -17432,7 +17680,10 @@ msgstr ""
msgid "Groups and projects"
msgstr ""
-msgid "Groups and subgroups"
+msgid "Groups are a great way to organize projects and people."
+msgstr ""
+
+msgid "Groups are the best way to manage projects and members."
msgstr ""
msgid "Groups to synchronize"
@@ -17543,13 +17794,16 @@ msgstr ""
msgid "GroupsTree|Are you sure you want to leave the \"%{fullName}\" group?"
msgstr ""
-msgid "GroupsTree|Edit group"
+msgid "GroupsTree|Delete"
+msgstr ""
+
+msgid "GroupsTree|Edit"
msgstr ""
msgid "GroupsTree|Failed to leave the group. Please make sure you are not the only owner."
msgstr ""
-msgid "GroupsTree|Leave this group"
+msgid "GroupsTree|Leave group"
msgstr ""
msgid "GroupsTree|Loading groups"
@@ -17561,9 +17815,57 @@ msgstr ""
msgid "GroupsTree|No groups or projects matched your search"
msgstr ""
+msgid "GroupsTree|Options"
+msgstr ""
+
msgid "GroupsTree|Search by name"
msgstr ""
+msgid "Groups|Avatar will be removed. Are you sure?"
+msgstr ""
+
+msgid "Groups|Changing group URL can have unintended side effects."
+msgstr ""
+
+msgid "Groups|Checking group URL availability..."
+msgstr ""
+
+msgid "Groups|Enter a descriptive name for your group."
+msgstr ""
+
+msgid "Groups|Group ID"
+msgstr ""
+
+msgid "Groups|Group URL"
+msgstr ""
+
+msgid "Groups|Group avatar"
+msgstr ""
+
+msgid "Groups|Group description (optional)"
+msgstr ""
+
+msgid "Groups|Group name"
+msgstr ""
+
+msgid "Groups|Group path is available."
+msgstr ""
+
+msgid "Groups|Group path is unavailable. Path has been replaced with a suggested available path."
+msgstr ""
+
+msgid "Groups|Learn more"
+msgstr ""
+
+msgid "Groups|Must start with letter, digit, emoji, or underscore. Can also contain periods, dashes, spaces, and parentheses."
+msgstr ""
+
+msgid "Groups|Remove avatar"
+msgstr ""
+
+msgid "Groups|Save changes"
+msgstr ""
+
msgid "Guideline"
msgstr ""
@@ -17573,6 +17875,9 @@ msgstr ""
msgid "HAR file path or URL"
msgstr ""
+msgid "HTTP Archive (HAR)"
+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 ""
@@ -17973,6 +18278,9 @@ msgstr ""
msgid "INFO: Your SSH key is expiring soon. Please generate a new key."
msgstr ""
+msgid "IP"
+msgstr ""
+
msgid "IP Address"
msgstr ""
@@ -18009,6 +18317,9 @@ msgstr ""
msgid "IdentityVerification|Verify your identity"
msgstr ""
+msgid "IdentityVerification|You can always verify your account at a later time to create a group."
+msgstr ""
+
msgid "If any indexed field exceeds this limit, it is truncated to this number of characters. The rest of the content is neither indexed nor searchable. This does not apply to repository and wiki indexing. For unlimited characters, set this to 0."
msgstr ""
@@ -18066,6 +18377,9 @@ msgstr ""
msgid "If you add %{codeStart}needs%{codeEnd} to jobs in your pipeline you'll be able to view the %{codeStart}needs%{codeEnd} relationships between jobs in this tab as a %{linkStart}Directed Acyclic Graph (DAG)%{linkEnd}."
msgstr ""
+msgid "If you are added to a project, it will be displayed here."
+msgstr ""
+
msgid "If you did not initiate these sign-in attempts, please reach out to your administrator or enable two-factor authentication (2FA) on your account."
msgstr ""
@@ -18372,12 +18686,24 @@ msgstr ""
msgid "InProductMarketing|3 ways to dive into GitLab CI/CD"
msgstr ""
+msgid "InProductMarketing|A single application eliminates complex integrations, data chokepoints, and toolchain maintenance, resulting in greater productivity and lower cost."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features, build more efficiently, strengthen security and compliance."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features."
+msgstr ""
+
msgid "InProductMarketing|Actually, GitLab makes the team work (better)"
msgstr ""
msgid "InProductMarketing|And finally %{deploy_link} a Python application."
msgstr ""
+msgid "InProductMarketing|And many more..."
+msgstr ""
+
msgid "InProductMarketing|Are your runners ready?"
msgstr ""
@@ -18396,15 +18722,33 @@ msgstr ""
msgid "InProductMarketing|Blog"
msgstr ""
+msgid "InProductMarketing|Break down silos to coordinate seamlessly across development, operations, and security with a consistent experience across the development lifecycle."
+msgstr ""
+
+msgid "InProductMarketing|Burn up/down charts"
+msgstr ""
+
msgid "InProductMarketing|By enabling code owners and required merge approvals the right person will review the right MR. This is a win-win: cleaner code and a more efficient review process."
msgstr ""
msgid "InProductMarketing|Click on the number below that corresponds with your answer — 1 being very difficult, 5 being very easy."
msgstr ""
+msgid "InProductMarketing|Code owners"
+msgstr ""
+
msgid "InProductMarketing|Code owners and required merge approvals are part of the paid tiers of GitLab. You can start a free 30-day trial of GitLab Ultimate and enable these features in less than 5 minutes with no credit card required."
msgstr ""
+msgid "InProductMarketing|Code review analytics"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration across stages in GitLab"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration made easy"
+msgstr ""
+
msgid "InProductMarketing|Create a custom CI runner with just a few clicks"
msgstr ""
@@ -18414,12 +18758,21 @@ msgstr ""
msgid "InProductMarketing|Create a project in GitLab in 5 minutes"
msgstr ""
+msgid "InProductMarketing|Create well-defined workflows by using scoped labels on issues, merge requests, and epics. Labels with the same scope cannot be used together, which prevents conflicts."
+msgstr ""
+
msgid "InProductMarketing|Create your first project!"
msgstr ""
+msgid "InProductMarketing|Define who owns specific files or directories, so the right reviewers are suggested when a merge request introduces changes to those files."
+msgstr ""
+
msgid "InProductMarketing|Deliver Better Products Faster"
msgstr ""
+msgid "InProductMarketing|Dependency scanning"
+msgstr ""
+
msgid "InProductMarketing|Did you know teams that use GitLab are far more efficient?"
msgstr ""
@@ -18429,15 +18782,27 @@ msgstr ""
msgid "InProductMarketing|Dig in and create a project and a repo"
msgstr ""
+msgid "InProductMarketing|Discover Premium & Ultimate"
+msgstr ""
+
+msgid "InProductMarketing|Discover Premium & Ultimate."
+msgstr ""
+
msgid "InProductMarketing|Do you have a minute?"
msgstr ""
msgid "InProductMarketing|Do you have a teammate who would be perfect for this task?"
msgstr ""
+msgid "InProductMarketing|Dynamic application security testing"
+msgstr ""
+
msgid "InProductMarketing|Easy"
msgstr ""
+msgid "InProductMarketing|Epics"
+msgstr ""
+
msgid "InProductMarketing|Expand your DevOps journey with a free GitLab trial"
msgstr ""
@@ -18459,9 +18824,15 @@ msgstr ""
msgid "InProductMarketing|Feel the need for speed?"
msgstr ""
+msgid "InProductMarketing|Find and fix bottlenecks in your code review process by understanding how long open merge requests have been in review."
+msgstr ""
+
msgid "InProductMarketing|Find out how your teams are really doing"
msgstr ""
+msgid "InProductMarketing|Find out if your external libraries are safe. Run dependency scanning jobs that check for known vulnerabilities in your external libraries."
+msgstr ""
+
msgid "InProductMarketing|Follow our steps"
msgstr ""
@@ -18498,6 +18869,9 @@ msgstr ""
msgid "InProductMarketing|GitLab is better with teammates to help out!"
msgstr ""
+msgid "InProductMarketing|GitLab is infrastructure agnostic (supporting GCP, AWS, Azure, OpenShift, VMWare, On Prem, Bare Metal, and more), offering a consistent workflow experience – irrespective of the environment."
+msgstr ""
+
msgid "InProductMarketing|GitLab provides static application security testing (SAST), dynamic application security testing (DAST), container scanning, and dependency scanning to help you deliver secure applications along with license compliance."
msgstr ""
@@ -18588,21 +18962,36 @@ msgstr ""
msgid "InProductMarketing|It's also possible to simply %{external_repo_link} in order to take advantage of GitLab's CI/CD."
msgstr ""
+msgid "InProductMarketing|Keep your code quality high by defining who should approve merge requests and how many approvals are required."
+msgstr ""
+
msgid "InProductMarketing|Launch GitLab CI/CD in 20 minutes or less"
msgstr ""
+msgid "InProductMarketing|Lower cost of development"
+msgstr ""
+
+msgid "InProductMarketing|Make it easier to collaborate on high-level ideas by grouping related issues in an epic."
+msgstr ""
+
msgid "InProductMarketing|Making the switch? It's easier than you think to import your projects into GitLab. Move %{github_link}, or import something %{bitbucket_link}."
msgstr ""
msgid "InProductMarketing|Master the art of importing!"
msgstr ""
+msgid "InProductMarketing|Merge request approval rule"
+msgstr ""
+
msgid "InProductMarketing|Move on to easily creating a Pages website %{ci_template_link}"
msgstr ""
msgid "InProductMarketing|Multiple owners, confusing workstreams? We've got you covered"
msgstr ""
+msgid "InProductMarketing|Multiple required approvers"
+msgstr ""
+
msgid "InProductMarketing|Need an alternative to importing?"
msgstr ""
@@ -18615,18 +19004,33 @@ msgstr ""
msgid "InProductMarketing|Our tool brings all the things together"
msgstr ""
+msgid "InProductMarketing|Protect your web application by using DAST to examine for vulnerabilities in deployed environments."
+msgstr ""
+
msgid "InProductMarketing|Rapid development, simplified"
msgstr ""
msgid "InProductMarketing|Reduce Security & Compliance Risk"
msgstr ""
+msgid "InProductMarketing|Require multiple approvers on a merge request, so you know it's in good shape before it's merged."
+msgstr ""
+
+msgid "InProductMarketing|Roadmaps"
+msgstr ""
+
+msgid "InProductMarketing|Scoped labels"
+msgstr ""
+
msgid "InProductMarketing|Security that's integrated into your development lifecycle"
msgstr ""
msgid "InProductMarketing|Sometimes you're not ready to make a full transition to a new tool. If you're not ready to fully commit, %{mirroring_link} gives you a safe way to try out GitLab in parallel with your current tool."
msgstr ""
+msgid "InProductMarketing|Speed. Efficiency. Trust."
+msgstr ""
+
msgid "InProductMarketing|Spin up an autoscaling runner in GitLab"
msgstr ""
@@ -18636,6 +19040,9 @@ msgstr ""
msgid "InProductMarketing|Start a Self-Managed trial"
msgstr ""
+msgid "InProductMarketing|Start a free trial"
+msgstr ""
+
msgid "InProductMarketing|Start a free trial of GitLab Ultimate – no credit card required"
msgstr ""
@@ -18702,6 +19109,9 @@ msgstr ""
msgid "InProductMarketing|To understand and get the most out of GitLab, start at the beginning and %{project_link}. In GitLab, repositories are part of a project, so after you've created your project you can go ahead and %{repo_link}."
msgstr ""
+msgid "InProductMarketing|Track completed issues in a chart, so you can see how a milestone is progressing at a glance."
+msgstr ""
+
msgid "InProductMarketing|Try GitLab Ultimate for free"
msgstr ""
@@ -18738,6 +19148,9 @@ msgstr ""
msgid "InProductMarketing|Very easy"
msgstr ""
+msgid "InProductMarketing|Visualize your epics and milestones in a timeline."
+msgstr ""
+
msgid "InProductMarketing|Want to host GitLab on your servers?"
msgstr ""
@@ -18759,6 +19172,9 @@ msgstr ""
msgid "InProductMarketing|YouTube"
msgstr ""
+msgid "InProductMarketing|Your software, deployed your way"
+msgstr ""
+
msgid "InProductMarketing|Your teams can be more efficient"
msgstr ""
@@ -18879,9 +19295,18 @@ msgstr ""
msgid "IncidentManagement|No incidents to display."
msgstr ""
+msgid "IncidentManagement|None"
+msgstr ""
+
msgid "IncidentManagement|Open"
msgstr ""
+msgid "IncidentManagement|Page your team with escalation policies"
+msgstr ""
+
+msgid "IncidentManagement|Paged"
+msgstr ""
+
msgid "IncidentManagement|Published"
msgstr ""
@@ -18891,6 +19316,9 @@ msgstr ""
msgid "IncidentManagement|Severity"
msgstr ""
+msgid "IncidentManagement|Status"
+msgstr ""
+
msgid "IncidentManagement|There are no closed incidents"
msgstr ""
@@ -18909,6 +19337,9 @@ msgstr ""
msgid "IncidentManagement|Unpublished"
msgstr ""
+msgid "IncidentManagement|Use escalation policies to automatically page your team when incidents are created."
+msgstr ""
+
msgid "IncidentSettings|Activate \"time to SLA\" countdown timer"
msgstr ""
@@ -18954,7 +19385,10 @@ msgstr ""
msgid "Incidents"
msgstr ""
-msgid "Incidents|Add a URL"
+msgid "Incidents|Add image details"
+msgstr ""
+
+msgid "Incidents|Add text or a link to display with your image. If you don't add either, the file name displays instead."
msgstr ""
msgid "Incidents|Drop or %{linkStart}upload%{linkEnd} a metric screenshot to attach it to the incident"
@@ -18969,10 +19403,10 @@ msgstr ""
msgid "Incidents|There was an issue loading metric images."
msgstr ""
-msgid "Incidents|There was an issue uploading your image."
+msgid "Incidents|There was an issue updating your image."
msgstr ""
-msgid "Incidents|You can optionally add a URL to link users to the original graph."
+msgid "Incidents|There was an issue uploading your image."
msgstr ""
msgid "Incident|Alert details"
@@ -18981,9 +19415,18 @@ msgstr ""
msgid "Incident|Are you sure you wish to delete this image?"
msgstr ""
+msgid "Incident|Delete image"
+msgstr ""
+
msgid "Incident|Deleting %{filename}"
msgstr ""
+msgid "Incident|Edit image text or link"
+msgstr ""
+
+msgid "Incident|Editing %{filename}"
+msgstr ""
+
msgid "Incident|Metrics"
msgstr ""
@@ -19253,12 +19696,18 @@ msgstr ""
msgid "Integrations|Branches for which notifications are to be sent"
msgstr ""
+msgid "Integrations|Clear if using a self-signed certificate."
+msgstr ""
+
msgid "Integrations|Comment detail:"
msgstr ""
msgid "Integrations|Comment settings:"
msgstr ""
+msgid "Integrations|Connection details"
+msgstr ""
+
msgid "Integrations|Connection failed. Please check your settings."
msgstr ""
@@ -19283,6 +19732,9 @@ msgstr ""
msgid "Integrations|Enable GitLab.com slash commands in a Slack workspace."
msgstr ""
+msgid "Integrations|Enable SSL verification"
+msgstr ""
+
msgid "Integrations|Enable comments"
msgstr ""
@@ -19361,6 +19813,9 @@ msgstr ""
msgid "Integrations|Return to GitLab for Jira"
msgstr ""
+msgid "Integrations|SSL verification"
+msgstr ""
+
msgid "Integrations|Save settings?"
msgstr ""
@@ -19406,9 +19861,6 @@ msgstr ""
msgid "Integrations|Use default settings"
msgstr ""
-msgid "Integrations|When you mention a Jira issue in a commit or merge request, GitLab creates a remote link and comment (if enabled)."
-msgstr ""
-
msgid "Integrations|You can now close this window and return to the GitLab for Jira application."
msgstr ""
@@ -19433,9 +19885,6 @@ msgstr ""
msgid "Integrations|can't exceed %{recipients_limit}"
msgstr ""
-msgid "Interactive developer security education."
-msgstr ""
-
msgid "Interactive mode"
msgstr ""
@@ -19925,6 +20374,9 @@ msgstr ""
msgid "IssueAnalytics|Assignees"
msgstr ""
+msgid "IssueAnalytics|Created by"
+msgstr ""
+
msgid "IssueAnalytics|Due date"
msgstr ""
@@ -19937,9 +20389,6 @@ msgstr ""
msgid "IssueAnalytics|Milestone"
msgstr ""
-msgid "IssueAnalytics|Opened by"
-msgstr ""
-
msgid "IssueAnalytics|Status"
msgstr ""
@@ -20063,10 +20512,10 @@ msgstr ""
msgid "IssuesAnalytics|Avg/Month:"
msgstr ""
-msgid "IssuesAnalytics|Issues opened"
+msgid "IssuesAnalytics|Issues created"
msgstr ""
-msgid "IssuesAnalytics|Issues opened per month"
+msgid "IssuesAnalytics|Issues created per month"
msgstr ""
msgid "IssuesAnalytics|Last 12 months"
@@ -20093,6 +20542,9 @@ msgstr ""
msgid "It looks like you have some draft commits in this branch."
msgstr ""
+msgid "It looks like you're attempting to activate your subscription. Use %{a_start}the Subscription page%{a_end} instead."
+msgstr ""
+
msgid "It may be several days before you see feature usage data."
msgstr ""
@@ -20321,6 +20773,9 @@ msgstr ""
msgid "JiraConnect|You can now close this window and return to Jira."
msgstr ""
+msgid "JiraConnect|You don't have permission to create branches for this project. Select a different project or contact the project owner for access. %{linkStart}Learn more.%{linkEnd}"
+msgstr ""
+
msgid "JiraRequest|A connection error occurred while connecting to Jira. Try your request again."
msgstr ""
@@ -20369,13 +20824,13 @@ msgstr ""
msgid "JiraService|Define the type of Jira issue to create from a vulnerability."
msgstr ""
-msgid "JiraService|Displaying Jira issues while leaving the GitLab issue functionality enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
+msgid "JiraService|Displaying Jira issues while leaving GitLab issues also enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
msgstr ""
-msgid "JiraService|Enable Jira issues"
+msgid "JiraService|Enable Jira issue creation from vulnerabilities"
msgstr ""
-msgid "JiraService|Enable Jira issues creation from vulnerabilities"
+msgid "JiraService|Enable Jira issues"
msgstr ""
msgid "JiraService|Enable Jira transitions"
@@ -20492,16 +20947,19 @@ msgstr ""
msgid "JiraService|View Jira issues in GitLab"
msgstr ""
-msgid "JiraService|Warning: All GitLab users that have access to this GitLab project are able to view all issues from the Jira project specified below."
+msgid "JiraService|Warning: All GitLab users with access to this GitLab project can view all issues from the Jira project you select."
msgstr ""
msgid "JiraService|Web URL"
msgstr ""
-msgid "JiraService|Work on Jira issues without leaving GitLab. Adds a Jira menu to access your list of Jira issues and view any issue as read-only."
+msgid "JiraService|When a Jira issue is mentioned in a commit or merge request, a remote link and comment (if enabled) will be created."
+msgstr ""
+
+msgid "JiraService|Work on Jira issues without leaving GitLab. Add a Jira menu to access a read-only list of your Jira issues."
msgstr ""
-msgid "JiraService|You need to configure Jira before enabling this integration. For more details, read the %{jira_doc_link_start}Jira integration documentation%{link_end}."
+msgid "JiraService|You must configure Jira before enabling this integration. %{jira_doc_link_start}Learn more.%{link_end}"
msgstr ""
msgid "Job"
@@ -20513,9 +20971,6 @@ msgstr ""
msgid "Job Failed #%{build_id}"
msgstr ""
-msgid "Job ID"
-msgstr ""
-
msgid "Job artifact"
msgstr ""
@@ -20582,9 +21037,27 @@ msgstr ""
msgid "Jobs|You're about to retry a job that failed because it attempted to deploy code that is older than the latest deployment. Retrying this job could result in overwriting the environment with the older source code."
msgstr ""
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source} into %{target}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{ref}"
+msgstr ""
+
+msgid "Job|Are you sure you want to erase this job log and artifacts?"
+msgstr ""
+
msgid "Job|Browse"
msgstr ""
+msgid "Job|Cancel"
+msgstr ""
+
msgid "Job|Complete Raw"
msgstr ""
@@ -20594,6 +21067,9 @@ msgstr ""
msgid "Job|Erase job log and artifacts"
msgstr ""
+msgid "Job|Finished at"
+msgstr ""
+
msgid "Job|Job artifacts"
msgstr ""
@@ -20606,7 +21082,7 @@ msgstr ""
msgid "Job|Keep"
msgstr ""
-msgid "Job|Pipeline"
+msgid "Job|Retry"
msgstr ""
msgid "Job|Scroll to bottom"
@@ -20618,6 +21094,9 @@ msgstr ""
msgid "Job|Show complete raw"
msgstr ""
+msgid "Job|Status"
+msgstr ""
+
msgid "Job|The artifacts were removed"
msgstr ""
@@ -20645,21 +21124,12 @@ msgstr ""
msgid "Job|delayed"
msgstr ""
-msgid "Job|for"
-msgstr ""
-
-msgid "Job|into"
-msgstr ""
-
msgid "Job|manual"
msgstr ""
msgid "Job|triggered"
msgstr ""
-msgid "Job|with"
-msgstr ""
-
msgid "Join Zoom meeting"
msgstr ""
@@ -20762,9 +21232,6 @@ msgstr ""
msgid "Ki"
msgstr ""
-msgid "Kontra"
-msgstr ""
-
msgid "Kroki"
msgstr ""
@@ -21088,6 +21555,9 @@ msgstr ""
msgid "Learn more about Auto DevOps"
msgstr ""
+msgid "Learn more about GitLab"
+msgstr ""
+
msgid "Learn more about Needs relationships"
msgstr ""
@@ -21415,9 +21885,18 @@ msgstr ""
msgid "Licenses|Displays licenses detected in the project, based on the %{linkStart}latest successful%{linkEnd} scan"
msgstr ""
+msgid "Licenses|Drag your license file here or %{linkStart}click to upload%{linkEnd}."
+msgstr ""
+
+msgid "Licenses|Drop your license file to start the upload."
+msgstr ""
+
msgid "Licenses|Error fetching the license list. Please check your network connection and try again."
msgstr ""
+msgid "Licenses|Error: You are trying to upload something other than a file"
+msgstr ""
+
msgid "Licenses|License Compliance"
msgstr ""
@@ -21436,6 +21915,9 @@ msgstr ""
msgid "Licenses|Specified policies in this project"
msgstr ""
+msgid "Licenses|The file could not be uploaded."
+msgstr ""
+
msgid "Licenses|The license list details information about the licenses used within your project."
msgstr ""
@@ -21469,11 +21951,6 @@ msgstr ""
msgid "Limit the size of Sidekiq jobs stored in Redis."
msgstr ""
-msgid "Limited to showing %d event at most"
-msgid_plural "Limited to showing %d events at most"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Limiting mode"
msgstr ""
@@ -21483,6 +21960,9 @@ msgstr ""
msgid "Link"
msgstr ""
+msgid "Link (optional)"
+msgstr ""
+
msgid "Link Prometheus monitoring to GitLab."
msgstr ""
@@ -21519,6 +21999,9 @@ msgstr ""
msgid "Linked emails (%{email_count})"
msgstr ""
+msgid "Linked epics"
+msgstr ""
+
msgid "Linked issues"
msgstr ""
@@ -21546,6 +22029,15 @@ msgstr ""
msgid "List of all merge commits"
msgstr ""
+msgid "List of environments for this project"
+msgstr ""
+
+msgid "List of suitable GCP locations"
+msgstr ""
+
+msgid "List of users allowed to exceed the rate limit."
+msgstr ""
+
msgid "List options"
msgstr ""
@@ -21765,6 +22257,9 @@ msgstr ""
msgid "Maintenance mode"
msgstr ""
+msgid "Make adjustments to how your GitLab instance is set up."
+msgstr ""
+
msgid "Make and review changes in the browser with the Web IDE"
msgstr ""
@@ -21909,6 +22404,12 @@ msgstr ""
msgid "MarkdownEditor|Add italic text (%{modifier_key}I)"
msgstr ""
+msgid "MarkdownEditor|Add strikethrough text (%{modifierKey}⇧X)"
+msgstr ""
+
+msgid "MarkdownEditor|Add strikethrough text (%{modifier_key}⇧X)"
+msgstr ""
+
msgid "Marked For Deletion At - %{deletion_time}"
msgstr ""
@@ -22170,6 +22671,9 @@ msgstr ""
msgid "Maximum push size (MB)"
msgstr ""
+msgid "Maximum requests per 10 minutes per user"
+msgstr ""
+
msgid "Maximum requests per minute"
msgstr ""
@@ -22260,6 +22764,19 @@ msgstr ""
msgid "Members of a group may only view projects they have permission to access"
msgstr ""
+msgid "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seat in use and will be billed for the overage."
+msgid_plural "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seats in use and will be billed for the overage."
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "MembersOverage|You are about to incur additional charges"
+msgstr ""
+
+msgid "MembersOverage|Your subscription includes %d seat."
+msgid_plural "MembersOverage|Your subscription includes %d seats."
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Membership"
msgstr ""
@@ -22464,9 +22981,6 @@ msgstr ""
msgid "Merge request not merged"
msgstr ""
-msgid "Merge request pipelines 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 merge request pipelines."
-msgstr ""
-
msgid "Merge request reports"
msgstr ""
@@ -22563,13 +23077,13 @@ msgstr ""
msgid "MergeRequests|Create issue to resolve thread"
msgstr ""
-msgid "MergeRequests|Failed to squash. Should be done manually."
+msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Saving the comment failed"
+msgid "MergeRequests|Squashing failed: Squash the commits locally, resolve any conflicts, then push the branch."
msgstr ""
-msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
+msgid "MergeRequests|Squashing not allowed: This project doesn't allow you to squash commits when merging."
msgstr ""
msgid "MergeRequests|Thread stays resolved"
@@ -23410,6 +23924,18 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "MrList|Assigned to %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from assignee %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from reviewer %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Review requested from %{name}, go to their profile."
+msgstr ""
+
msgid "Multi-project"
msgstr ""
@@ -23443,7 +23969,7 @@ msgstr ""
msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "My Awesome Group"
+msgid "My awesome group"
msgstr ""
msgid "My company or team"
@@ -24065,9 +24591,6 @@ msgstr ""
msgid "No available branches"
msgstr ""
-msgid "No available groups to fork the project."
-msgstr ""
-
msgid "No branches found"
msgstr ""
@@ -24278,6 +24801,9 @@ msgstr ""
msgid "No ref selected"
msgstr ""
+msgid "No regions configured"
+msgstr ""
+
msgid "No related merge requests found."
msgstr ""
@@ -25082,6 +25608,9 @@ msgstr ""
msgid "Only reCAPTCHA v2 is supported:"
msgstr ""
+msgid "Only required if not using role instance credentials."
+msgstr ""
+
msgid "Only use lowercase letters, numbers, and underscores."
msgstr ""
@@ -25106,9 +25635,6 @@ msgstr ""
msgid "Open a CLI and connect to the cluster you want to install the agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
-msgid "Open epics"
-msgstr ""
-
msgid "Open errors"
msgstr ""
@@ -25148,7 +25674,7 @@ msgstr ""
msgid "Opened issues"
msgstr ""
-msgid "OpenedNDaysAgo|Opened"
+msgid "OpenedNDaysAgo|Created"
msgstr ""
msgid "Opens in a new window"
@@ -25193,9 +25719,6 @@ msgstr ""
msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
-msgid "Optional."
-msgstr ""
-
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
msgstr ""
@@ -25984,6 +26507,9 @@ msgstr ""
msgid "PerformanceBar|Memory"
msgstr ""
+msgid "PerformanceBar|Memory report"
+msgstr ""
+
msgid "PerformanceBar|Redis calls"
msgstr ""
@@ -26017,18 +26543,12 @@ msgstr ""
msgid "PerformanceBar|wall"
msgstr ""
-msgid "Performs a rebase but skips triggering a new pipeline"
-msgstr ""
-
msgid "Period in seconds"
msgstr ""
msgid "Permalink"
msgstr ""
-msgid "Permanently delete project"
-msgstr ""
-
msgid "Permanently remove group"
msgstr ""
@@ -26299,6 +26819,51 @@ msgstr ""
msgid "PipelineStatusTooltip|Pipeline: %{ci_status}"
msgstr ""
+msgid "PipelineWizardDefaultCommitMessage|Add %{filename}"
+msgstr ""
+
+msgid "PipelineWizardDefaultCommitMessage|Update %{filename}"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|At least one entry is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This field is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This value is not valid"
+msgstr ""
+
+msgid "PipelineWizardListWidget|add another step"
+msgstr ""
+
+msgid "PipelineWizardListWidget|remove step"
+msgstr ""
+
+msgid "PipelineWizard|Commit"
+msgstr ""
+
+msgid "PipelineWizard|Commit Message"
+msgstr ""
+
+msgid "PipelineWizard|Commit changes to your file"
+msgstr ""
+
+msgid "PipelineWizard|Commit file to Branch"
+msgstr ""
+
+msgid "PipelineWizard|Commit your new file"
+msgstr ""
+
+msgid "PipelineWizard|The file has been committed."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem committing the changes."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem while checking whether your file already exists in the specified branch."
+msgstr ""
+
msgid "Pipelines"
msgstr ""
@@ -26413,7 +26978,7 @@ msgstr ""
msgid "Pipelines|Project cache successfully reset."
msgstr ""
-msgid "Pipelines|Revoke"
+msgid "Pipelines|Revoke trigger"
msgstr ""
msgid "Pipelines|Something went wrong while cleaning runners cache."
@@ -26458,6 +27023,12 @@ msgstr ""
msgid "Pipelines|This is a child pipeline within the parent pipeline"
msgstr ""
+msgid "Pipelines|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipelines|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipelines|This pipeline will run code originating from a forked project merge request. This means that the code can potentially have security considerations like exposing CI variables."
msgstr ""
@@ -26500,9 +27071,6 @@ msgstr ""
msgid "Pipelines|Your changes have been successfully committed. Now redirecting to the new merge request page."
msgstr ""
-msgid "Pipelines|detached"
-msgstr ""
-
msgid "Pipelines|error"
msgstr ""
@@ -26512,10 +27080,13 @@ msgstr ""
msgid "Pipelines|latest"
msgstr ""
-msgid "Pipelines|stuck"
+msgid "Pipelines|merge request"
msgstr ""
-msgid "Pipelines|train"
+msgid "Pipelines|merge train"
+msgstr ""
+
+msgid "Pipelines|stuck"
msgstr ""
msgid "Pipelines|yaml invalid"
@@ -26647,6 +27218,12 @@ msgstr ""
msgid "Pipeline|This change will not change the overall test coverage if merged."
msgstr ""
+msgid "Pipeline|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipeline|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipeline|Trigger author"
msgstr ""
@@ -26671,6 +27248,12 @@ msgstr ""
msgid "Pipeline|for"
msgstr ""
+msgid "Pipeline|merge request"
+msgstr ""
+
+msgid "Pipeline|merge train"
+msgstr ""
+
msgid "Pipeline|on"
msgstr ""
@@ -26809,9 +27392,6 @@ msgstr ""
msgid "Please enter a valid time interval"
msgstr ""
-msgid "Please enter or upload a valid license."
-msgstr ""
-
msgid "Please enter your current password."
msgstr ""
@@ -26920,9 +27500,6 @@ msgstr ""
msgid "Please type %{phrase_code} to proceed or close this modal to cancel."
msgstr ""
-msgid "Please type the following to confirm:"
-msgstr ""
-
msgid "Please use this form to report to the admin users who create spam issues, comments or behave inappropriately."
msgstr ""
@@ -26950,12 +27527,27 @@ msgstr ""
msgid "Policies"
msgstr ""
+msgid "Policy '%{escalation_policy_name}' does not exist."
+msgstr ""
+
msgid "Policy management project does have any policies in %{policy_path}"
msgstr ""
msgid "Policy project doesn't exist"
msgstr ""
+msgid "PolicyRuleMultiSelect|%{firstLabel} +%{numberOfAdditionalLabels} more"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|All %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select all"
+msgstr ""
+
msgid "Polling interval multiplier"
msgstr ""
@@ -27184,6 +27776,9 @@ msgstr ""
msgid "Private projects can be created in your personal namespace with:"
msgstr ""
+msgid "Problem with %{name} command: %{message}."
+msgstr ""
+
msgid "Proceed"
msgstr ""
@@ -27658,6 +28253,9 @@ msgstr ""
msgid "Progress"
msgstr ""
+msgid "Progress tracking"
+msgstr ""
+
msgid "Project"
msgstr ""
@@ -27889,6 +28487,9 @@ msgstr ""
msgid "ProjectQualitySummary|Failure"
msgstr ""
+msgid "ProjectQualitySummary|Get insight into the overall percentage of tests in your project that succeed, fail and are skipped."
+msgstr ""
+
msgid "ProjectQualitySummary|Latest pipeline results"
msgstr ""
@@ -27907,6 +28508,12 @@ msgstr ""
msgid "ProjectQualitySummary|See project Code Coverage Statistics"
msgstr ""
+msgid "ProjectQualitySummary|Set up test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|Set up test runs (opens in a new tab)"
+msgstr ""
+
msgid "ProjectQualitySummary|Skipped"
msgstr ""
@@ -28183,13 +28790,19 @@ msgstr ""
msgid "ProjectSettings|LFS objects from this repository are available to forks. %{linkStart}How do I remove them?%{linkEnd}"
msgstr ""
+msgid "ProjectSettings|Learn about commit history."
+msgstr ""
+
+msgid "ProjectSettings|Leave empty to use default template."
+msgstr ""
+
msgid "ProjectSettings|Manage who can see the project in the public access directory."
msgstr ""
msgid "ProjectSettings|Manages large files such as audio, video, and graphics files."
msgstr ""
-msgid "ProjectSettings|Maximum 500 characters."
+msgid "ProjectSettings|Maximum %{maxLength} characters."
msgstr ""
msgid "ProjectSettings|Merge checks"
@@ -28330,6 +28943,9 @@ msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
msgstr ""
+msgid "ProjectSettings|The default template will be applied on save."
+msgstr ""
+
msgid "ProjectSettings|These checks must pass before merge requests can be merged."
msgstr ""
@@ -28384,6 +29000,9 @@ msgstr ""
msgid "ProjectSettings|What are badges?"
msgstr ""
+msgid "ProjectSettings|What are merge trains?"
+msgstr ""
+
msgid "ProjectSettings|When merge request pipelines are enabled in the CI/CD configuration file, pipelines validate the combined results of the source and target branches. %{link_start}How to configure merge request pipelines?%{link_end}"
msgstr ""
@@ -28501,6 +29120,9 @@ msgstr ""
msgid "Projects are organized into groups"
msgstr ""
+msgid "Projects are where you store your code, access issues, wiki and other features of GitLab."
+msgstr ""
+
msgid "Projects contributed to"
msgstr ""
@@ -28516,12 +29138,6 @@ msgstr ""
msgid "Projects to index"
msgstr ""
-msgid "Projects will be permanently deleted after a %{waiting_period}-day waiting period."
-msgstr ""
-
-msgid "Projects will be permanently deleted immediately."
-msgstr ""
-
msgid "Projects with critical vulnerabilities"
msgstr ""
@@ -28606,6 +29222,9 @@ msgstr ""
msgid "ProjectsNew|Import project"
msgstr ""
+msgid "ProjectsNew|Include a Getting Started README"
+msgstr ""
+
msgid "ProjectsNew|Initialize repository with a README"
msgstr ""
@@ -28621,6 +29240,9 @@ msgstr ""
msgid "ProjectsNew|Project description %{tag_start}(optional)%{tag_end}"
msgstr ""
+msgid "ProjectsNew|Recommended if you're new to GitLab"
+msgstr ""
+
msgid "ProjectsNew|Run CI/CD for external repository"
msgstr ""
@@ -29038,6 +29660,9 @@ msgstr ""
msgid "ProtectedBranch|Unprotect"
msgstr ""
+msgid "ProtectedBranch|Unprotect branch"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
@@ -29065,6 +29690,9 @@ msgstr ""
msgid "ProtectedEnvironment|Protected Environment (%{protected_environments_count})"
msgstr ""
+msgid "ProtectedEnvironment|Required approvals"
+msgstr ""
+
msgid "ProtectedEnvironment|Select an environment"
msgstr ""
@@ -29086,10 +29714,13 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|Unprotect tag"
+msgstr ""
+
msgid "ProtectedTags|default"
msgstr ""
-msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
+msgid "ProtectedTag|By default, protected tags restrict who can modify the tag."
msgstr ""
msgid "ProtectedTag|Learn more."
@@ -29152,6 +29783,9 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Public projects are an easy way to allow everyone to have read-only access."
+msgstr ""
+
msgid "Publish to status page"
msgstr ""
@@ -29308,9 +29942,6 @@ msgstr ""
msgid "QualitySummary|Project quality"
msgstr ""
-msgid "Quarters"
-msgstr ""
-
msgid "Query"
msgstr ""
@@ -29395,6 +30026,9 @@ msgstr ""
msgid "Read more about project permissions %{help_link_open}here%{help_link_close}"
msgstr ""
+msgid "Read more about related epics"
+msgstr ""
+
msgid "Read more about related issues"
msgstr ""
@@ -29425,10 +30059,7 @@ msgstr ""
msgid "Rebase source branch on the target branch."
msgstr ""
-msgid "Rebase without CI"
-msgstr ""
-
-msgid "Rebases and triggers a pipeline"
+msgid "Rebase without pipeline"
msgstr ""
msgid "Recaptcha verified?"
@@ -29479,9 +30110,6 @@ msgstr ""
msgid "Reconfigure"
msgstr ""
-msgid "Recovering projects"
-msgstr ""
-
msgid "Recovery Codes"
msgstr ""
@@ -29541,6 +30169,12 @@ msgstr ""
msgid "Regex pattern"
msgstr ""
+msgid "Region"
+msgstr ""
+
+msgid "Regions"
+msgstr ""
+
msgid "Register"
msgstr ""
@@ -29771,9 +30405,6 @@ msgstr ""
msgid "Remove all or specific reviewer(s)"
msgstr ""
-msgid "Remove approver"
-msgstr ""
-
msgid "Remove approvers"
msgstr ""
@@ -29789,6 +30420,9 @@ msgstr ""
msgid "Remove attention request"
msgstr ""
+msgid "Remove attention request(s)"
+msgstr ""
+
msgid "Remove avatar"
msgstr ""
@@ -29927,6 +30561,9 @@ msgstr ""
msgid "Removed an issue from an epic."
msgstr ""
+msgid "Removed attention from %{users_sentence}."
+msgstr ""
+
msgid "Removed attention request from @%{username}"
msgstr ""
@@ -29978,6 +30615,9 @@ msgstr ""
msgid "Removes an issue from an epic."
msgstr ""
+msgid "Removes attention from %{users_sentence}."
+msgstr ""
+
msgid "Removes parent epic %{epic_ref}."
msgstr ""
@@ -30089,6 +30729,9 @@ msgstr ""
msgid "Report abuse to admin"
msgstr ""
+msgid "Report is generating and will be sent to your email address."
+msgstr ""
+
msgid "Reported %{timeAgo} by %{reportedBy}"
msgstr ""
@@ -30378,6 +31021,15 @@ msgstr ""
msgid "Request attention"
msgstr ""
+msgid "Request attention from %{users_sentence}."
+msgstr ""
+
+msgid "Request attention from assignee or reviewer"
+msgstr ""
+
+msgid "Request attention from assignee(s) or reviewer(s)"
+msgstr ""
+
msgid "Request attention to review"
msgstr ""
@@ -30402,6 +31054,9 @@ msgstr ""
msgid "Requested %{time_ago}"
msgstr ""
+msgid "Requested attention from %{users_sentence}."
+msgstr ""
+
msgid "Requested attention from @%{username}"
msgstr ""
@@ -30616,6 +31271,9 @@ msgstr ""
msgid "Restore project"
msgstr ""
+msgid "Restoring projects"
+msgstr ""
+
msgid "Restoring the group will prevent the group, its subgroups and projects from being removed on this date."
msgstr ""
@@ -30646,6 +31304,9 @@ msgstr ""
msgid "Retry"
msgstr ""
+msgid "Retry failed jobs"
+msgstr ""
+
msgid "Retry job"
msgstr ""
@@ -30693,9 +31354,6 @@ msgstr ""
msgid "Review changes"
msgstr ""
-msgid "Review requested from %{name}"
-msgstr ""
-
msgid "Review requests for you"
msgstr ""
@@ -30860,6 +31518,9 @@ msgstr ""
msgid "Runners|Assigned Group"
msgstr ""
+msgid "Runners|Assigned Projects (%{projectCount})"
+msgstr ""
+
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30929,6 +31590,9 @@ msgstr ""
msgid "Runners|Instance"
msgstr ""
+msgid "Runners|Jobs"
+msgstr ""
+
msgid "Runners|Last contact"
msgstr ""
@@ -31022,9 +31686,6 @@ msgstr ""
msgid "Runners|Runner %{name} was deleted"
msgstr ""
-msgid "Runners|Runner ID"
-msgstr ""
-
msgid "Runners|Runner assigned to project."
msgstr ""
@@ -31172,6 +31833,9 @@ msgstr ""
msgid "Runners|stale"
msgstr ""
+msgid "Runner|This runner has not run any jobs."
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -31286,6 +31950,24 @@ msgstr ""
msgid "Saving project."
msgstr ""
+msgid "ScanResultPolicy|%{ifLabelStart}if%{ifLabelEnd} %{scanners} scan in an open merge request targeting the %{branches} branch(es) finds %{vulnerabilitiesAllowed} or more %{severities} vulnerabilities that are %{vulnerabilityStates}"
+msgstr ""
+
+msgid "ScanResultPolicy|%{thenLabelStart}Then%{thenLabelEnd} Require approval from %{approvalsRequired} of the following approvers: %{approvers}"
+msgstr ""
+
+msgid "ScanResultPolicy|add an approver"
+msgstr ""
+
+msgid "ScanResultPolicy|scanners"
+msgstr ""
+
+msgid "ScanResultPolicy|severity levels"
+msgstr ""
+
+msgid "ScanResultPolicy|vulnerability states"
+msgstr ""
+
msgid "Scanner"
msgstr ""
@@ -31418,6 +32100,9 @@ msgstr ""
msgid "Search for a user"
msgstr ""
+msgid "Search for an emoji"
+msgstr ""
+
msgid "Search for projects, issues, etc."
msgstr ""
@@ -31605,18 +32290,12 @@ msgstr ""
msgid "Secret Detection"
msgstr ""
-msgid "Secret access key"
-msgstr ""
-
msgid "Secret token"
msgstr ""
msgid "Secure token that identifies an external storage request."
msgstr ""
-msgid "SecureCodeWarrior"
-msgstr ""
-
msgid "Security"
msgstr ""
@@ -31641,9 +32320,6 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "Security training with guide and learning pathways."
-msgstr ""
-
msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
@@ -31746,7 +32422,7 @@ msgstr ""
msgid "SecurityConfiguration|Manage corpus"
msgstr ""
-msgid "SecurityConfiguration|Manage corpus files used as mutation sources in coverage fuzzing."
+msgid "SecurityConfiguration|Manage corpus files used as seed inputs with coverage-guided fuzzing."
msgstr ""
msgid "SecurityConfiguration|Manage profiles for use by DAST scans."
@@ -31812,15 +32488,15 @@ msgstr ""
msgid "SecurityOrchestration|.yaml preview"
msgstr ""
-msgid "SecurityOrchestration|Action"
-msgstr ""
-
msgid "SecurityOrchestration|Actions"
msgstr ""
msgid "SecurityOrchestration|Add rule"
msgstr ""
+msgid "SecurityOrchestration|After dismissing the alert, the information will never be shown again."
+msgstr ""
+
msgid "SecurityOrchestration|All policies"
msgstr ""
@@ -31836,7 +32512,7 @@ msgstr ""
msgid "SecurityOrchestration|Description"
msgstr ""
-msgid "SecurityOrchestration|Disabled"
+msgid "SecurityOrchestration|Don't show the alert anymore"
msgstr ""
msgid "SecurityOrchestration|Edit policy"
@@ -31845,13 +32521,13 @@ msgstr ""
msgid "SecurityOrchestration|Edit policy project"
msgstr ""
-msgid "SecurityOrchestration|Enabled"
+msgid "SecurityOrchestration|Empty policy name"
msgstr ""
-msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Enabled"
msgstr ""
-msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
msgstr ""
msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
@@ -31860,7 +32536,7 @@ msgstr ""
msgid "SecurityOrchestration|Invalid policy type"
msgstr ""
-msgid "SecurityOrchestration|Latest scan"
+msgid "SecurityOrchestration|Latest scan run against %{agent}"
msgstr ""
msgid "SecurityOrchestration|Network"
@@ -31869,15 +32545,27 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No actions defined - policy will not run."
+msgstr ""
+
+msgid "SecurityOrchestration|No description"
+msgstr ""
+
msgid "SecurityOrchestration|No rules defined - policy will not run."
msgstr ""
+msgid "SecurityOrchestration|Not enabled"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
msgid "SecurityOrchestration|Policies"
msgstr ""
+msgid "SecurityOrchestration|Policy Type"
+msgstr ""
+
msgid "SecurityOrchestration|Policy cannot be enabled for non-existing branches (%{branches})"
msgstr ""
@@ -31902,10 +32590,13 @@ msgstr ""
msgid "SecurityOrchestration|Require %{approvals} %{plural} from %{approvers} if any of the following occur:"
msgstr ""
-msgid "SecurityOrchestration|Rule"
+msgid "SecurityOrchestration|Rules"
msgstr ""
-msgid "SecurityOrchestration|Rules"
+msgid "SecurityOrchestration|Runs %{actions} and %{lastAction} scans"
+msgstr ""
+
+msgid "SecurityOrchestration|Runs a %{action} scan"
msgstr ""
msgid "SecurityOrchestration|Scan Execution"
@@ -31965,6 +32656,9 @@ msgstr ""
msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
+msgid "SecurityOrchestration|This view only shows scan results for the agent %{agent}. You can view scan results for all agents in the %{linkStart}Operational Vulnerabilities tab of the vulnerability report%{linkEnd}."
+msgstr ""
+
msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
@@ -32019,9 +32713,6 @@ msgstr ""
msgid "SecurityOrchestration|users with ids"
msgstr ""
-msgid "SecurityOrchestration|view results"
-msgstr ""
-
msgid "SecurityOrchestration|vulnerabilities"
msgstr ""
@@ -32691,22 +33382,19 @@ 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|In order to start using functions as a service, you must first install Knative on your Kubernetes cluster. %{linkStart}More information%{linkEnd}"
-msgstr ""
-
msgid "Serverless|Learn more about Serverless"
msgstr ""
msgid "Serverless|No functions available"
msgstr ""
-msgid "Serverless|Sign up for First Look"
+msgid "Serverless|Serverless was %{linkStart}deprecated%{linkEnd} in GitLab 14.3."
+msgstr ""
+
+msgid "Serverless|Serverless was %{postLinkStart}deprecated%{postLinkEnd}. But if you opt to use it, you must install Knative in your Kubernetes cluster first. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "Serverless|The deploy job has not finished."
@@ -32718,9 +33406,6 @@ 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 ""
@@ -32736,9 +33421,6 @@ msgstr ""
msgid "Service Account Key"
msgstr ""
-msgid "Service Accounts"
-msgstr ""
-
msgid "Service Accounts keys authorize GitLab to deploy your Google Cloud project"
msgstr ""
@@ -32748,10 +33430,10 @@ msgstr ""
msgid "Service Desk allows people to create issues in your GitLab instance without their own user account. It provides a unique email address for end users to create issues in a project. Replies can be sent either through the GitLab interface or by email. End users only see threads through email."
msgstr ""
-msgid "Service Usage Data"
+msgid "Service account generated successfully"
msgstr ""
-msgid "Service account generated successfully"
+msgid "Service accounts"
msgstr ""
msgid "Service ping is disabled in your configuration file, and cannot be enabled through this form."
@@ -32895,6 +33577,9 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
+msgid "Set the per-user rate limit for getting a user by ID via the API."
+msgstr ""
+
msgid "Set the per-user rate limit for notes created by web or API requests."
msgstr ""
@@ -33074,6 +33759,9 @@ msgstr ""
msgid "Shared runners details"
msgstr ""
+msgid "Shared runners enabled cannot be enabled until a valid credit card is on file"
+msgstr ""
+
msgid "Shared runners help link"
msgstr ""
@@ -33131,6 +33819,9 @@ msgstr ""
msgid "Show all issues."
msgstr ""
+msgid "Show all milestones"
+msgstr ""
+
msgid "Show all test cases."
msgstr ""
@@ -33167,6 +33858,9 @@ msgstr ""
msgid "Show file contents"
msgstr ""
+msgid "Show group milestones"
+msgstr ""
+
msgid "Show labels"
msgstr ""
@@ -33182,6 +33876,12 @@ msgstr ""
msgid "Show open epics"
msgstr ""
+msgid "Show project milestones"
+msgstr ""
+
+msgid "Show sub-group milestones"
+msgstr ""
+
msgid "Show the Closed list"
msgstr ""
@@ -33191,11 +33891,6 @@ msgstr ""
msgid "Show whitespace changes"
msgstr ""
-msgid "Showing %d event"
-msgid_plural "Showing %d events"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Showing %{conflict} between %{sourceBranch} and %{targetBranch}"
msgstr ""
@@ -33255,12 +33950,6 @@ msgstr ""
msgid "Sidebar|None"
msgstr ""
-msgid "Sidebar|Only numeral characters allowed"
-msgstr ""
-
-msgid "Sidebar|Weight"
-msgstr ""
-
msgid "Sidekiq job compression threshold (bytes)"
msgstr ""
@@ -33423,6 +34112,9 @@ msgstr ""
msgid "Slack logo"
msgstr ""
+msgid "SlackIntegration|Are you sure you want to remove this project from the Slack application?"
+msgstr ""
+
msgid "SlackIntegration|GitLab for Slack"
msgstr ""
@@ -33432,6 +34124,9 @@ msgstr ""
msgid "SlackIntegration|Project alias"
msgstr ""
+msgid "SlackIntegration|Remove project"
+msgstr ""
+
msgid "SlackIntegration|Select a GitLab project to link with your Slack workspace."
msgstr ""
@@ -33576,9 +34271,6 @@ msgstr ""
msgid "Something went wrong trying to load issue contacts."
msgstr ""
-msgid "Something went wrong when creating a work item. Please try again"
-msgstr ""
-
msgid "Something went wrong when reordering designs. Please try again"
msgstr ""
@@ -33672,9 +34364,6 @@ msgstr ""
msgid "Something went wrong while inserting your image. Please try again."
msgstr ""
-msgid "Something went wrong while merging this merge request. Please try again."
-msgstr ""
-
msgid "Something went wrong while obtaining the Let's Encrypt certificate."
msgstr ""
@@ -33996,10 +34685,10 @@ 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."
+msgid "SourcegraphAdmin|Learn more."
msgstr ""
-msgid "SourcegraphAdmin|More information"
+msgid "SourcegraphAdmin|Only public projects have code intelligence enabled and communicate with Sourcegraph."
msgstr ""
msgid "SourcegraphAdmin|Save changes"
@@ -34008,7 +34697,7 @@ msgstr ""
msgid "SourcegraphAdmin|Sourcegraph URL"
msgstr ""
-msgid "SourcegraphAdmin|e.g. https://sourcegraph.example.com"
+msgid "SourcegraphAdmin|https://sourcegraph.example.com"
msgstr ""
msgid "SourcegraphPreferences|This feature is experimental and currently limited to certain projects."
@@ -34143,6 +34832,9 @@ msgstr ""
msgid "Start date"
msgstr ""
+msgid "Start free trial"
+msgstr ""
+
msgid "Start merge train"
msgstr ""
@@ -34173,6 +34865,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started escalation for this incident."
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -34185,6 +34880,9 @@ msgstr ""
msgid "Starts at (UTC)"
msgstr ""
+msgid "Starts escalations for this incident"
+msgstr ""
+
msgid "Starts on"
msgstr ""
@@ -34446,6 +35144,9 @@ msgstr ""
msgid "Strikethrough"
msgstr ""
+msgid "Strikethrough text"
+msgstr ""
+
msgid "Subgroup information"
msgstr ""
@@ -34680,6 +35381,21 @@ msgstr ""
msgid "Subscriptions"
msgstr ""
+msgid "Subscriptions|Chat with sales"
+msgstr ""
+
+msgid "Subscriptions|Close"
+msgstr ""
+
+msgid "Subscriptions|Not ready to buy yet?"
+msgstr ""
+
+msgid "Subscriptions|Start a free trial"
+msgstr ""
+
+msgid "Subscriptions|We understand. Maybe you have some questions for our sales team, or maybe you'd like to try some of the paid features first. What would you like to do?"
+msgstr ""
+
msgid "Subscription|Your subscription for %{strong}%{namespace_name}%{strong_close} has expired and you are now on %{pricing_link_start}the GitLab Free tier%{pricing_link_end}. Don't worry, your data is safe. Get in touch with our support team (%{support_email}). They'll gladly help with your subscription renewal."
msgstr ""
@@ -34890,6 +35606,9 @@ msgstr ""
msgid "SuperSonics|Maximum users"
msgstr ""
+msgid "SuperSonics|Offline cloud"
+msgstr ""
+
msgid "SuperSonics|Paste your activation code"
msgstr ""
@@ -34956,6 +35675,12 @@ msgstr ""
msgid "SuperSonics|You do not have an active subscription"
msgstr ""
+msgid "SuperSonics|You have a future dated license"
+msgstr ""
+
+msgid "SuperSonics|You have added a license that activates on %{date}. Please see the subscription history table below for more details."
+msgstr ""
+
msgid "SuperSonics|You have successfully added a license that activates on %{date}. Please see the subscription history table below for more details."
msgstr ""
@@ -35115,6 +35840,9 @@ msgstr ""
msgid "Tag name is required"
msgstr ""
+msgid "Tag push"
+msgstr ""
+
msgid "Tag push events"
msgstr ""
@@ -35217,6 +35945,9 @@ msgstr ""
msgid "TagsPage|protected"
msgstr ""
+msgid "Take a look at the documentation to discover all of GitLab’s capabilities."
+msgstr ""
+
msgid "Target Branch"
msgstr ""
@@ -35619,6 +36350,9 @@ msgstr ""
msgid "Tests"
msgstr ""
+msgid "Text (optional)"
+msgstr ""
+
msgid "Text added to the body of all email messages. %{character_limit} character limit"
msgstr ""
@@ -35669,6 +36403,9 @@ msgstr ""
msgid "The CSV export will be created in the background. Once finished, it will be sent to %{email} in an attachment."
msgstr ""
+msgid "The CSV export you requested of all user memberships is attached to this email."
+msgstr ""
+
msgid "The GitLab subscription service (customers.gitlab.com) is currently experiencing an outage. You can monitor the status and get updates at %{linkStart}status.gitlab.com%{linkEnd}."
msgstr ""
@@ -35744,6 +36481,9 @@ 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 epic"
+msgstr ""
+
msgid "The current issue"
msgstr ""
@@ -35905,6 +36645,9 @@ msgstr ""
msgid "The latest pipeline for this merge request has failed."
msgstr ""
+msgid "The license key is invalid."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -35920,6 +36663,9 @@ msgstr ""
msgid "The license was successfully uploaded and will be active from %{starts_at}. You can see the details below."
msgstr ""
+msgid "The license you uploaded is invalid. If the issue persists, contact support at %{link}."
+msgstr ""
+
msgid "The list creation wizard is already open"
msgstr ""
@@ -36541,10 +37287,13 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} and everything this project contains. %{strongOpen}There is no going back%{strongClose}"
+msgstr ""
+
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains."
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}on %{date}%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains. %{strongOpen}There is no going back.%{strongClose}"
msgstr ""
msgid "This action will %{strongOpen}permanently remove%{strongClose} %{codeOpen}%{group}%{codeClose} %{strongOpen}immediately%{strongClose}."
@@ -36673,9 +37422,6 @@ msgstr ""
msgid "This file was modified for readability, and can't accept suggestions. Edit it directly."
msgstr ""
-msgid "This forked project has the following:"
-msgstr ""
-
msgid "This form is disabled in preview"
msgstr ""
@@ -36688,7 +37434,7 @@ msgstr ""
msgid "This group can't be removed because it is linked to a subscription. To remove this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
-msgid "This group can't be transfered because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
+msgid "This group can't be transferred because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
msgid "This group cannot be invited to a project inside a group with enforced SSO"
@@ -36715,6 +37461,9 @@ 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 incident is already escalated with '%{escalation_policy_name}'."
+msgstr ""
+
msgid "This invitation was sent to %{mail_to_invite_email}, but you are signed in as %{link_to_current_user} with email %{mail_to_current_user}."
msgstr ""
@@ -36733,9 +37482,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 merge train pipeline"
-msgstr ""
-
msgid "This is a private email address %{helpIcon} generated just for you. Anyone who has it can create issues or merge requests as if they were you. If that happens, %{resetLinkStart}reset this token%{resetLinkEnd}."
msgstr ""
@@ -36757,6 +37503,12 @@ msgstr ""
msgid "This is your current session"
msgstr ""
+msgid "This issue cannot be assigned to a confidential epic because it is public."
+msgstr ""
+
+msgid "This issue cannot be made public because it belongs to a confidential epic."
+msgstr ""
+
msgid "This issue is confidential and should only be visible to team members with at least Reporter access."
msgstr ""
@@ -36874,6 +37626,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 branch is protected from force push."
+msgstr ""
+
msgid "This merge request cannot be rebased while there are conflicts."
msgstr ""
@@ -36925,9 +37680,15 @@ msgstr ""
msgid "This pipeline was triggered by a schedule."
msgstr ""
+msgid "This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project"
msgstr ""
+msgid "This project can be restored until %{date}."
+msgstr ""
+
msgid "This project cannot be %{visibilityLevel} because the visibility of %{openShowLink}%{name}%{closeShowLink} is %{visibility}. To make this project %{visibilityLevel}, you must first %{openEditLink}change the visibility%{closeEditLink} of the parent group."
msgstr ""
@@ -36946,6 +37707,9 @@ msgstr ""
msgid "This project is %{strongStart}NOT%{strongEnd} a fork, and has the following:"
msgstr ""
+msgid "This project is %{strongStart}NOT%{strongEnd} a fork. This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -37637,6 +38401,9 @@ msgstr ""
msgid "Today"
msgstr ""
+msgid "Todos count"
+msgstr ""
+
msgid "Todos|Are you looking for things to do? Take a look at %{strongStart}%{openIssuesLinkStart}open issues%{openIssuesLinkEnd}%{strongEnd}, contribute to %{strongStart}%{mergeRequestLinkStart}a merge request%{mergeRequestLinkEnd}%{mergeRequestLinkEnd}%{strongEnd}, or mention someone in a comment to automatically assign them a new to-do item."
msgstr ""
@@ -37910,10 +38677,8 @@ msgstr ""
msgid "Trending"
msgstr ""
-msgid "Trials|%{planName} Trial %{enDash} %{num} day left"
-msgid_plural "Trials|%{planName} Trial %{enDash} %{num} days left"
-msgstr[0] ""
-msgstr[1] ""
+msgid "Trials|%{planName} Trial"
+msgstr ""
msgid "Trials|Compare all plans"
msgstr ""
@@ -37921,6 +38686,9 @@ msgstr ""
msgid "Trials|Create a new group to start your GitLab Ultimate trial."
msgstr ""
+msgid "Trials|Day %{daysUsed}/%{duration}"
+msgstr ""
+
msgid "Trials|Go back to GitLab"
msgstr ""
@@ -38170,7 +38938,7 @@ msgstr ""
msgid "URL is triggered when repository is updated"
msgstr ""
-msgid "URL must be percent-encoded if neccessary."
+msgid "URL must be percent-encoded if necessary."
msgstr ""
msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
@@ -38389,6 +39157,9 @@ msgstr ""
msgid "Unlock account"
msgstr ""
+msgid "Unlock more features with GitLab Ultimate"
+msgstr ""
+
msgid "Unlock the discussion"
msgstr ""
@@ -38452,6 +39223,9 @@ msgstr ""
msgid "Unsubscribes from this %{quick_action_target}."
msgstr ""
+msgid "Unsupported sort value."
+msgstr ""
+
msgid "Unsupported todo type passed. Supported todo types are: %{todo_types}"
msgstr ""
@@ -38680,6 +39454,9 @@ msgstr ""
msgid "UsageQuota|File attachments and smaller design graphics."
msgstr ""
+msgid "UsageQuota|From %{storage_enforcement_date} storage limits will apply to this namespace. View and manage your usage in %{strong_start}Group Settings &gt; Usage quotas%{strong_end}."
+msgstr ""
+
msgid "UsageQuota|Git repository."
msgstr ""
@@ -38740,6 +39517,9 @@ msgstr ""
msgid "UsageQuota|Storage type"
msgstr ""
+msgid "UsageQuota|Storage used"
+msgstr ""
+
msgid "UsageQuota|This is the total amount of storage used across your projects within this namespace."
msgstr ""
@@ -38935,6 +39715,12 @@ msgstr ""
msgid "Use hashed storage paths for newly created and renamed repositories. Always enabled since 13.0."
msgstr ""
+msgid "Use issue count"
+msgstr ""
+
+msgid "Use issue weight"
+msgstr ""
+
msgid "Use one line per URI"
msgstr ""
@@ -39316,6 +40102,9 @@ msgstr ""
msgid "Users"
msgstr ""
+msgid "Users API rate limit"
+msgstr ""
+
msgid "Users can launch a development environment from a GitLab browser tab when the %{linkStart}Gitpod%{linkEnd} integration is enabled."
msgstr ""
@@ -39641,6 +40430,9 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View group pipeline usage quota"
+msgstr ""
+
msgid "View incident details at"
msgstr ""
@@ -39793,6 +40585,9 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
+msgid "Vulnerability"
+msgstr ""
+
msgid "Vulnerability Report"
msgstr ""
@@ -39844,6 +40639,9 @@ msgstr ""
msgid "VulnerabilityManagement|An unverified non-confirmed finding"
msgstr ""
+msgid "VulnerabilityManagement|At least one identifier is required"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -39853,12 +40651,24 @@ msgstr ""
msgid "VulnerabilityManagement|Create Jira issue"
msgstr ""
+msgid "VulnerabilityManagement|Enter a name"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE code"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE identifier URL"
+msgstr ""
+
msgid "VulnerabilityManagement|Fetching linked Jira issues"
msgstr ""
msgid "VulnerabilityManagement|Manually add a vulnerability entry into the vulnerability report."
msgstr ""
+msgid "VulnerabilityManagement|Name is a required field"
+msgstr ""
+
msgid "VulnerabilityManagement|Needs triage"
msgstr ""
@@ -39874,6 +40684,18 @@ msgstr ""
msgid "VulnerabilityManagement|Select a method"
msgstr ""
+msgid "VulnerabilityManagement|Select a severity level"
+msgstr ""
+
+msgid "VulnerabilityManagement|Select a status"
+msgstr ""
+
+msgid "VulnerabilityManagement|Severity is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Something went wrong while creating vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -39898,6 +40720,12 @@ msgstr ""
msgid "VulnerabilityManagement|Something went wrong, could not update vulnerability state."
msgstr ""
+msgid "VulnerabilityManagement|Status is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Submit vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Summary, detailed description, steps to reproduce, etc."
msgstr ""
@@ -40093,6 +40921,9 @@ msgstr ""
msgid "WARNING:"
msgstr ""
+msgid "WARNING: This snippet contains hidden files which might be used to mask malicious behavior. Exercise caution if cloning and executing code from this snippet."
+msgstr ""
+
msgid "Wait for the file to load to copy its contents"
msgstr ""
@@ -40312,6 +41143,15 @@ msgstr ""
msgid "Webhooks|An issue is created, updated, closed, or reopened."
msgstr ""
+msgid "Webhooks|Are you sure you want to delete this group hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this project hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this webhook?"
+msgstr ""
+
msgid "Webhooks|Comments"
msgstr ""
@@ -40321,6 +41161,9 @@ msgstr ""
msgid "Webhooks|Confidential issues events"
msgstr ""
+msgid "Webhooks|Delete webhook"
+msgstr ""
+
msgid "Webhooks|Deployment events"
msgstr ""
@@ -40554,6 +41397,9 @@ msgstr ""
msgid "Wiki"
msgstr ""
+msgid "Wiki page"
+msgstr ""
+
msgid "Wiki page was successfully created."
msgstr ""
@@ -40659,7 +41505,7 @@ msgstr ""
msgid "WikiPageConflictMessage|Someone edited the page the same time you did. Please check out %{wikiLinkStart}the page%{wikiLinkEnd} and make sure your changes will not unintentionally remove theirs."
msgstr ""
-msgid "WikiPage|An error occured while trying to render the content editor. Please try again later."
+msgid "WikiPage|An error occurred while trying to render the content editor. Please try again later."
msgstr ""
msgid "WikiPage|Are you sure you want to switch back to the classic editor?"
@@ -40818,6 +41664,18 @@ msgstr ""
msgid "WorkItem|New Task"
msgstr ""
+msgid "WorkItem|Something went wrong when creating a work item. Please try again"
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching the work item. Please try again."
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching work item types. Please try again"
+msgstr ""
+
+msgid "WorkItem|Type"
+msgstr ""
+
msgid "WorkItem|Work Items"
msgstr ""
@@ -40884,7 +41742,10 @@ msgstr ""
msgid "You are about to add %{usersTag} people to the discussion. They will all receive a notification."
msgstr ""
-msgid "You are about to permanently delete this project"
+msgid "You are about to delete this forked project containing:"
+msgstr ""
+
+msgid "You are about to delete this project containing:"
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."
@@ -40905,6 +41766,9 @@ msgstr ""
msgid "You are attempting to update a file that has changed since you started editing it."
msgstr ""
+msgid "You are billed if you exceed this number. %{qsrOverageLinkStart}How does billing work?%{qsrOverageLinkEnd}"
+msgstr ""
+
msgid "You are connected to the Prometheus server, but there is currently no data to display."
msgstr ""
@@ -40962,6 +41826,9 @@ msgstr ""
msgid "You are not authorized to update this scanner profile"
msgstr ""
+msgid "You are not authorized to upload metric images"
+msgstr ""
+
msgid "You are now impersonating %{username}"
msgstr ""
@@ -41115,9 +41982,6 @@ msgstr ""
msgid "You can only upload one design when dropping onto an existing design."
msgstr ""
-msgid "You can recover this project until %{date}"
-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 ""
@@ -41166,9 +42030,6 @@ msgstr ""
msgid "You cannot write to this read-only GitLab instance."
msgstr ""
-msgid "You can’t %{tag_start}edit%{tag_end} files directly in this project. Fork this project and submit a merge request with your changes."
-msgstr ""
-
msgid "You can’t edit files directly in this project. Fork this project and submit a merge request with your changes."
msgstr ""
@@ -41321,9 +42182,6 @@ 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 set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
@@ -41354,12 +42212,6 @@ msgstr ""
msgid "You must have maintainer access to force delete a lock"
msgstr ""
-msgid "You must have permission to create a project in a group before forking."
-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 ""
@@ -41765,7 +42617,7 @@ msgstr ""
msgid "Your public email will be displayed on your public profile."
msgstr ""
-msgid "Your request for access could not be processed: %{error_meesage}"
+msgid "Your request for access could not be processed: %{error_message}"
msgstr ""
msgid "Your request for access has been queued for review."
@@ -41948,6 +42800,9 @@ msgstr ""
msgid "archived:"
msgstr ""
+msgid "artifacts"
+msgstr ""
+
msgid "assign yourself"
msgstr ""
@@ -41977,6 +42832,9 @@ msgstr[1] ""
msgid "branch name"
msgstr ""
+msgid "builds"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -42400,6 +43258,9 @@ msgstr ""
msgid "contact with same email already exists in group hierarchy"
msgstr ""
+msgid "container registry images"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -42439,6 +43300,9 @@ msgstr ""
msgid "data"
msgstr ""
+msgid "database"
+msgstr ""
+
msgid "date must not be after 9999-12-31"
msgstr ""
@@ -42462,9 +43326,6 @@ msgstr ""
msgid "design"
msgstr ""
-msgid "detached"
-msgstr ""
-
msgid "disabled"
msgstr ""
@@ -42713,7 +43574,7 @@ msgstr ""
msgid "is not a valid X509 certificate."
msgstr ""
-msgid "is not allowed for sign-up."
+msgid "is not allowed for sign-up. Please use your regular email address."
msgstr ""
msgid "is not allowed for this group."
@@ -42725,7 +43586,7 @@ msgstr ""
msgid "is not allowed since the group is not top-level group."
msgstr ""
-msgid "is not allowed."
+msgid "is not allowed. Please use your regular email address."
msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
@@ -42812,6 +43673,9 @@ msgstr ""
msgid "level: %{level}"
msgstr ""
+msgid "lfs objects"
+msgstr ""
+
msgid "limit of %{project_limit} reached"
msgstr ""
@@ -43031,6 +43895,9 @@ msgstr ""
msgid "mrWidget|Merge blocked: pipeline must succeed. It's waiting for a manual action to continue."
msgstr ""
+msgid "mrWidget|Merge blocked: pipeline must succeed. Push a commit that fixes the failure, or %{linkStart}learn about other solutions.%{linkEnd}"
+msgstr ""
+
msgid "mrWidget|Merge blocked: this merge request must be approved."
msgstr ""
@@ -43148,9 +44015,6 @@ msgstr ""
msgid "mrWidget|The changes were not merged into"
msgstr ""
-msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -43298,9 +44162,6 @@ msgstr ""
msgid "open issue"
msgstr ""
-msgid "opened %{timeAgo}"
-msgstr ""
-
msgid "or"
msgstr ""
@@ -43312,6 +44173,12 @@ msgid_plural "out of %d total tests"
msgstr[0] ""
msgstr[1] ""
+msgid "packages"
+msgstr ""
+
+msgid "pages"
+msgstr ""
+
msgid "parent"
msgid_plural "parents"
msgstr[0] ""
@@ -43461,6 +44328,9 @@ msgid_plural "replies"
msgstr[0] ""
msgstr[1] ""
+msgid "repositories"
+msgstr ""
+
msgid "repository:"
msgstr ""
@@ -43581,12 +44451,18 @@ msgstr ""
msgid "tag name"
msgstr ""
+msgid "terraform states"
+msgstr ""
+
msgid "the correct format."
msgstr ""
msgid "the file"
msgstr ""
+msgid "the following epic(s)"
+msgstr ""
+
msgid "the following issue(s)"
msgstr ""
@@ -43599,21 +44475,12 @@ msgstr ""
msgid "this document"
msgstr ""
-msgid "this issue cannot be assigned to a confidential epic since it is public"
-msgstr ""
-
-msgid "this issue cannot be made public since it belongs to a confidential epic"
-msgstr ""
-
msgid "time summary"
msgstr ""
msgid "toggle collapse"
msgstr ""
-msgid "train"
-msgstr ""
-
msgid "triggered"
msgstr ""
@@ -43742,3 +44609,6 @@ msgstr ""
msgid "{project}"
msgstr ""
+msgid "✔"
+msgstr ""
+
diff --git a/locale/fr/gitlab.po b/locale/fr/gitlab.po
index 92352666ac3..a3901da993c 100644
--- a/locale/fr/gitlab.po
+++ b/locale/fr/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: fr\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2022-02-02 15:44\n"
+"PO-Revision-Date: 2022-03-01 20:38\n"
msgid " %{start} to %{end}"
msgstr " %{start} à %{end}"
@@ -146,6 +146,11 @@ msgid_plural "%d approvers (you've approved)"
msgstr[0] "%d approbateur (vous avez approuvé)"
msgstr[1] "%d approbateurs (vous avez approuvé)"
+msgid "%d assigned issue"
+msgid_plural "%d assigned issues"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] "%d fichier modifié"
@@ -421,10 +426,25 @@ msgid_plural "%d vulnerabilities dismissed"
msgstr[0] "%d vulnérabilité rejetée"
msgstr[1] "%d vulnérabilités rejetées"
-msgid "%d vulnerability updated"
-msgid_plural "%d vulnerabilities updated"
-msgstr[0] "%d vulnérabilité mise à jour"
-msgstr[1] "%d vulnérabilités mises à jour"
+msgid "%d vulnerability set to confirmed"
+msgid_plural "%d vulnerabilities set to confirmed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to dismissed"
+msgid_plural "%d vulnerabilities set to dismissed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to needs triage"
+msgid_plural "%d vulnerabilities set to needs triage"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to resolved"
+msgid_plural "%d vulnerabilities set to resolved"
+msgstr[0] ""
+msgstr[1] ""
msgid "%d warning found:"
msgid_plural "%d warnings found:"
@@ -510,6 +530,12 @@ msgstr[1] "%{completedCount} tâches terminées sur %{count}"
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr "%{completedWeight} sur %{totalWeight} du poids complété"
+msgid "%{completed} of %{total} issues closed"
+msgstr ""
+
+msgid "%{completed} of %{total} weight completed"
+msgstr ""
+
msgid "%{cores} cores"
msgstr "%{cores} cœurs"
@@ -858,6 +884,9 @@ msgstr "%{openedEpics} ouvertes, %{closedEpics} fermées"
msgid "%{openedIssues} open, %{closedIssues} closed"
msgstr "%{openedIssues} ouverts, %{closedIssues} fermés"
+msgid "%{percentage}%% issues closed"
+msgstr ""
+
msgid "%{percentage}%% weight completed"
msgstr "%{percentage}%% du poids completé"
@@ -1287,6 +1316,9 @@ msgid_plural "- Users"
msgstr[0] ""
msgstr[1] ""
+msgid "- of - issues closed"
+msgstr ""
+
msgid "- of - weight completed"
msgstr ""
@@ -1429,7 +1461,7 @@ msgstr ""
msgid "1000+"
msgstr ""
-msgid "192.168.0.0/24"
+msgid "192.168.0.0/24 or 2001:0DB8:1234::/48"
msgstr ""
msgid "1st contribution!"
@@ -1741,13 +1773,13 @@ msgstr ""
msgid "AWS Access Key"
msgstr ""
-msgid "AWS Access Key. Only required if not using role instance credentials"
+msgid "AWS Secret Access Key"
msgstr ""
-msgid "AWS Secret Access Key"
+msgid "AWS access key ID (Optional)"
msgstr ""
-msgid "AWS Secret Access Key. Only required if not using role instance credentials"
+msgid "AWS secret access key (Optional)"
msgstr ""
msgid "AWS service error: %{error}"
@@ -1807,9 +1839,6 @@ msgstr ""
msgid "Access granted"
msgstr ""
-msgid "Access key ID"
-msgstr ""
-
msgid "Access requests"
msgstr ""
@@ -1984,7 +2013,7 @@ msgstr ""
msgid "Activity"
msgstr "Activité"
-msgid "Activity|An error occured while retrieving activity. Reload the page to try again."
+msgid "Activity|An error occurred while retrieving activity. Reload the page to try again."
msgstr ""
msgid "Add"
@@ -2023,6 +2052,9 @@ msgstr ""
msgid "Add a %{type}"
msgstr ""
+msgid "Add a GCP region"
+msgstr ""
+
msgid "Add a GPG key"
msgstr ""
@@ -2074,6 +2106,9 @@ msgstr ""
msgid "Add a numbered list"
msgstr "Ajouter une liste numérotée"
+msgid "Add a related epic"
+msgstr ""
+
msgid "Add a related issue"
msgstr ""
@@ -2188,6 +2223,9 @@ msgstr ""
msgid "Add or subtract spent time"
msgstr ""
+msgid "Add people"
+msgstr ""
+
msgid "Add previously merged commits"
msgstr ""
@@ -2254,6 +2292,9 @@ msgstr ""
msgid "Add webhook"
msgstr ""
+msgid "Add your team members and others to GitLab."
+msgstr ""
+
msgid "Add/remove"
msgstr ""
@@ -3076,12 +3117,6 @@ msgstr ""
msgid "AdvancedSearch|Reindex required"
msgstr ""
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. Permanently deleting this project will %{strongStart}immediately delete%{strongEnd} its repositories and %{strongStart}all related resources%{strongEnd}, including issues, merge requests etc."
-msgstr ""
-
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. You will lose this project's repository and %{strongStart}all related resources%{strongEnd}, including issues and merge requests."
-msgstr ""
-
msgid "After a successful password update you will be redirected to login screen."
msgstr "Après modification de votre mot de passe, vous serez redirigé vers l’écran de connexion."
@@ -3112,6 +3147,9 @@ msgstr ""
msgid "Akismet helps prevent the creation of spam issues in public projects."
msgstr ""
+msgid "Alert"
+msgstr ""
+
msgid "AlertManagement|Acknowledged"
msgstr ""
@@ -3484,9 +3522,6 @@ msgstr ""
msgid "All environments"
msgstr ""
-msgid "All epics"
-msgstr ""
-
msgid "All groups and projects"
msgstr ""
@@ -4223,12 +4258,15 @@ msgstr ""
msgid "ApplicationSettings|Approve users in the pending approval status?"
msgstr ""
-msgid "ApplicationSettings|By making this change, you will automatically approve %d user with the pending approval status."
-msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users with the pending approval status."
+msgid "ApplicationSettings|Approve users who are pending approval?"
+msgstr ""
+
+msgid "ApplicationSettings|By making this change, you will automatically approve %d user who is pending approval."
+msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users who are pending approval."
msgstr[0] ""
msgstr[1] ""
-msgid "ApplicationSettings|By making this change, you will automatically approve all users in pending approval status."
+msgid "ApplicationSettings|By making this change, you will automatically approve all users who are pending approval."
msgstr ""
msgid "ApplicationSettings|Denied domains for sign-ups"
@@ -4634,10 +4672,10 @@ msgstr "Projets archivés"
msgid "Archiving the project will make it entirely read-only. It is hidden from the dashboard and doesn't show up in searches. %{strong_start}The repository cannot be committed to, and no issues, comments, or other entities can be created.%{strong_end} %{link_start}Learn more.%{link_end}"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to delete this project?"
+msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
+msgid "Are you absolutely sure?"
msgstr ""
msgid "Are you sure that you want to archive this project?"
@@ -4673,12 +4711,18 @@ msgstr ""
msgid "Are you sure you want to delete this SSH key?"
msgstr ""
+msgid "Are you sure you want to delete this comment?"
+msgstr ""
+
msgid "Are you sure you want to delete this deploy key?"
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 label?"
+msgstr ""
+
msgid "Are you sure you want to delete this pipeline schedule?"
msgstr "Êtesâ€vous sûr·e de vouloir supprimer ce pipeline programmé ?"
@@ -4694,9 +4738,6 @@ msgstr ""
msgid "Are you sure you want to discard your changes?"
msgstr ""
-msgid "Are you sure you want to erase this build?"
-msgstr "Êtesâ€vous sûr(e) de vouloir supprimer cette construction ?"
-
msgid "Are you sure you want to import %d repository?"
msgid_plural "Are you sure you want to import %d repositories?"
msgstr[0] ""
@@ -4744,6 +4785,9 @@ msgstr "Êtesâ€vous sûr(e) de vouloir supprimer cette identité ?"
msgid "Are you sure you want to remove this list?"
msgstr ""
+msgid "Are you sure you want to remove this nickname?"
+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é ?"
@@ -4756,10 +4800,10 @@ 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?"
+msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
msgstr ""
-msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
+msgid "Are you sure you want to revoke this project access token? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to stop this environment?"
@@ -4906,9 +4950,6 @@ msgstr ""
msgid "Assigned to %{assignee_name}"
msgstr ""
-msgid "Assigned to %{name}"
-msgstr ""
-
msgid "Assigned to me"
msgstr "Assigné à moi"
@@ -4973,6 +5014,9 @@ msgstr[1] ""
msgid "Attaching the file failed."
msgstr ""
+msgid "Attention"
+msgstr ""
+
msgid "Audit Events"
msgstr "Événements d’audit"
@@ -5135,6 +5179,12 @@ msgstr "Autorisé à"
msgid "Authorized applications (%{size})"
msgstr "Applications autorisées (%{size})"
+msgid "AuthorizedApplication|Are you sure you want to revoke this application?"
+msgstr ""
+
+msgid "AuthorizedApplication|Revoke application"
+msgstr ""
+
msgid "Authors: %{authors}"
msgstr "Auteur·e·s : %{authors}"
@@ -6328,6 +6378,9 @@ msgstr ""
msgid "CICDAnalytics|Shared Runners Usage"
msgstr ""
+msgid "CICDAnalytics|Shared runner pipeline minute duration by month"
+msgstr ""
+
msgid "CICDAnalytics|Shared runner usage"
msgstr ""
@@ -6469,6 +6522,9 @@ msgstr ""
msgid "Can create groups:"
msgstr ""
+msgid "Can not delete primary training"
+msgstr ""
+
msgid "Can't apply as the source branch was deleted."
msgstr ""
@@ -6802,9 +6858,6 @@ msgstr ""
msgid "Changing any setting here requires an application restart"
msgstr ""
-msgid "Changing group URL can have unintended side effects."
-msgstr ""
-
msgid "Charts can't be displayed as the request for data has timed out. %{documentationLink}"
msgstr ""
@@ -6892,9 +6945,6 @@ msgstr ""
msgid "Checking branch availability..."
msgstr "Vérification de la disponibilité du nom de branche…"
-msgid "Checking group URL availability..."
-msgstr ""
-
msgid "Checking group path availability..."
msgstr ""
@@ -7388,6 +7438,9 @@ msgstr ""
msgid "Clear recent searches"
msgstr ""
+msgid "Clear repository checks"
+msgstr ""
+
msgid "Clear search"
msgstr "Effacer la recherche"
@@ -7520,9 +7573,6 @@ msgstr ""
msgid "Closed MRs"
msgstr ""
-msgid "Closed epics"
-msgstr ""
-
msgid "Closed issues"
msgstr "Tickets clos"
@@ -7559,13 +7609,13 @@ msgstr ""
msgid "Cluster level"
msgstr ""
-msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
+msgid "Cluster type must be specified for Stages::ClusterEndpointInserter"
msgstr ""
msgid "ClusterAgents|%{name} successfully deleted"
msgstr ""
-msgid "ClusterAgents|%{number} of %{total} Agents"
+msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
@@ -7607,6 +7657,15 @@ msgstr ""
msgid "ClusterAgents|Agent never connected to GitLab"
msgstr ""
+msgid "ClusterAgents|Agent version mismatch"
+msgstr ""
+
+msgid "ClusterAgents|Agent version mismatch and update"
+msgstr ""
+
+msgid "ClusterAgents|Agent version update required"
+msgstr ""
+
msgid "ClusterAgents|All"
msgstr ""
@@ -7631,7 +7690,7 @@ msgstr ""
msgid "ClusterAgents|Configuration"
msgstr ""
-msgid "ClusterAgents|Connect a cluster through the Agent"
+msgid "ClusterAgents|Connect a cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connect existing cluster"
@@ -7640,13 +7699,13 @@ msgstr ""
msgid "ClusterAgents|Connect with a certificate"
msgstr ""
-msgid "ClusterAgents|Connect with agent"
+msgid "ClusterAgents|Connect with an agent"
msgstr ""
msgid "ClusterAgents|Connect with the GitLab Agent"
msgstr ""
-msgid "ClusterAgents|Connect your cluster through the Agent"
+msgid "ClusterAgents|Connect your cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connected"
@@ -7706,7 +7765,10 @@ msgstr ""
msgid "ClusterAgents|How to register an agent?"
msgstr ""
-msgid "ClusterAgents|Install new Agent"
+msgid "ClusterAgents|How to update an agent?"
+msgstr ""
+
+msgid "ClusterAgents|Install a new agent"
msgstr ""
msgid "ClusterAgents|Last connected %{timeAgo}."
@@ -7733,7 +7795,7 @@ msgstr ""
msgid "ClusterAgents|Never connected"
msgstr ""
-msgid "ClusterAgents|No Agents"
+msgid "ClusterAgents|No agents"
msgstr ""
msgid "ClusterAgents|No clusters connected through cluster certificates"
@@ -7793,6 +7855,9 @@ msgstr ""
msgid "ClusterAgents|The agent has not been connected in a long time. There might be a connectivity issue. Last contact was %{timeAgo}."
msgstr ""
+msgid "ClusterAgents|The agent version do not match each other across your cluster's pods. This can happen when a new agent version was just deployed and Kubernetes is shutting down the old pods."
+msgstr ""
+
msgid "ClusterAgents|The recommended installation method includes the token. If you want to follow the advanced installation method provided in the docs, make sure you save the token value before you close this window."
msgstr ""
@@ -7840,6 +7905,9 @@ msgstr ""
msgid "ClusterAgents|You will need to create a token to connect to your agent"
msgstr ""
+msgid "ClusterAgents|Your agent version is out of sync with your GitLab version (v%{version}), which might cause compatibility problems. Update the agent installed on your cluster to the most recent version."
+msgstr ""
+
msgid "ClusterAgents|Your instance doesn't have the %{linkStart}GitLab Agent Server (KAS)%{linkEnd} set up. Ask a GitLab Administrator to install it."
msgstr ""
@@ -8716,9 +8784,6 @@ msgstr ""
msgid "Comma-separated list of email addresses."
msgstr ""
-msgid "Comma-separated list of users allowed to exceed the rate limit."
-msgstr ""
-
msgid "Comma-separated, e.g. '1.1.1.1, 2.2.2.0/24'"
msgstr ""
@@ -9045,6 +9110,12 @@ msgstr ""
msgid "Confidential"
msgstr "Confidentiel"
+msgid "Confidential issue"
+msgstr ""
+
+msgid "Confidential note"
+msgstr ""
+
msgid "Confidentiality"
msgstr "Confidentialité"
@@ -9078,6 +9149,9 @@ msgstr ""
msgid "Configure Dependency Scanning in `.gitlab-ci.yml`, creating this file if it does not already exist"
msgstr ""
+msgid "Configure GitLab"
+msgstr ""
+
msgid "Configure GitLab runners to start using the Web Terminal. %{helpStart}Learn more.%{helpEnd}"
msgstr ""
@@ -9126,6 +9200,15 @@ msgstr ""
msgid "Configure pipelines to deploy web apps, backend services, APIs and static resources to Google Cloud"
msgstr ""
+msgid "Configure region"
+msgstr ""
+
+msgid "Configure region for environment"
+msgstr ""
+
+msgid "Configure regions"
+msgstr ""
+
msgid "Configure repository mirroring."
msgstr ""
@@ -9159,6 +9242,9 @@ msgstr ""
msgid "Configure which lists are shown for anyone who visits this board"
msgstr ""
+msgid "Configure your environments to be deployed to specific geographical regions"
+msgstr ""
+
msgid "Confirm"
msgstr ""
@@ -9861,10 +9947,10 @@ msgstr ""
msgid "CorpusManagement|Actions"
msgstr ""
-msgid "CorpusManagement|Corpus are used in fuzz testing as mutation source to Improve future testing."
+msgid "CorpusManagement|Corpus file"
msgstr ""
-msgid "CorpusManagement|Corpus file"
+msgid "CorpusManagement|Corpus files are used in coverage-guided fuzz testing as seed inputs to improve testing."
msgstr ""
msgid "CorpusManagement|Corpus files must be in *.zip format. Maximum 5 GB"
@@ -9918,6 +10004,9 @@ msgstr ""
msgid "Could not apply %{name} command."
msgstr ""
+msgid "Could not apply %{name} command. %{message}."
+msgstr ""
+
msgid "Could not authorize chat nickname. Try again!"
msgstr ""
@@ -10068,6 +10157,9 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
+msgid "Create a group"
+msgstr ""
+
msgid "Create a merge request"
msgstr ""
@@ -10092,6 +10184,9 @@ msgstr ""
msgid "Create a personal access token on your account to pull or push via %{protocol}."
msgstr "Créer un jeton d’accès personnel pour votre compte afin de récupérer ou pousser par %{protocol}."
+msgid "Create a project"
+msgstr ""
+
msgid "Create an account using:"
msgstr ""
@@ -10455,6 +10550,9 @@ msgstr ""
msgid "Creation date"
msgstr ""
+msgid "Creator"
+msgstr ""
+
msgid "Credentials"
msgstr ""
@@ -10467,9 +10565,15 @@ msgstr ""
msgid "CredentialsInventory|Personal Access Tokens"
msgstr ""
+msgid "CredentialsInventory|Project Access Tokens"
+msgstr ""
+
msgid "CredentialsInventory|SSH Keys"
msgstr ""
+msgid "Credit card required to be on file in order to create a pipeline"
+msgstr ""
+
msgid "Credit card:"
msgstr ""
@@ -10653,9 +10757,6 @@ msgstr ""
msgid "Customer relations"
msgstr ""
-msgid "Customizable by an administrator."
-msgstr ""
-
msgid "Customizable by owners."
msgstr ""
@@ -10785,30 +10886,18 @@ msgstr ""
msgid "CycleAnalytics|%{selectedLabelsCount} selected (%{maxLabels} max)"
msgstr ""
-msgid "CycleAnalytics|%{stageCount} stages selected"
-msgstr ""
-
-msgid "CycleAnalytics|All stages"
-msgstr ""
-
-msgid "CycleAnalytics|Average days to completion"
+msgid "CycleAnalytics|Average time to completion"
msgstr ""
msgid "CycleAnalytics|Date"
msgstr ""
-msgid "CycleAnalytics|Days to completion"
-msgstr ""
-
msgid "CycleAnalytics|Display chart filters"
msgstr ""
msgid "CycleAnalytics|Lead Time for Changes"
msgstr ""
-msgid "CycleAnalytics|No stages selected"
-msgstr ""
-
msgid "CycleAnalytics|Number of tasks"
msgstr ""
@@ -10837,18 +10926,30 @@ msgstr ""
msgid "CycleAnalytics|Showing data for group '%{groupName}' from %{createdAfter} to %{createdBefore}"
msgstr ""
-msgid "CycleAnalytics|Stages"
+msgid "CycleAnalytics|Stage time: %{title}"
msgstr ""
msgid "CycleAnalytics|Tasks by type"
msgstr ""
-msgid "CycleAnalytics|The average time spent in the selected stage for the items that were completed on each date. Data limited to the last 500 items."
+msgid "CycleAnalytics|The average time items spent in this stage. Data limited to items completed within this date range."
msgstr ""
msgid "CycleAnalytics|The given date range is larger than 180 days"
msgstr ""
+msgid "CycleAnalytics|The total time items spent across each value stream stage. Data limited to items completed within this date range."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Stage time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Total time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|Total time"
+msgstr ""
+
msgid "CycleAnalytics|Type of work"
msgstr ""
@@ -10861,9 +10962,6 @@ msgstr ""
msgid "CycleAnalytics|project dropdown filter"
msgstr ""
-msgid "CycleAnalytics|stage dropdown"
-msgstr ""
-
msgid "DAG visualization requires at least 3 dependent jobs."
msgstr ""
@@ -10963,10 +11061,16 @@ msgstr ""
msgid "DastProfiles|AJAX spider"
msgstr ""
+msgid "DastProfiles|API"
+msgstr ""
+
+msgid "DastProfiles|API endpoint URL"
+msgstr ""
+
msgid "DastProfiles|Active"
msgstr ""
-msgid "DastProfiles|Additional request headers (Optional)"
+msgid "DastProfiles|Additional request headers (optional)"
msgstr ""
msgid "DastProfiles|Are you sure you want to delete this profile?"
@@ -10981,6 +11085,9 @@ msgstr ""
msgid "DastProfiles|Branch missing"
msgstr ""
+msgid "DastProfiles|Choose a scan method"
+msgstr ""
+
msgid "DastProfiles|Could not create the scanner profile. Please try again."
msgstr ""
@@ -11050,7 +11157,13 @@ msgstr ""
msgid "DastProfiles|Excluded URLs"
msgstr ""
-msgid "DastProfiles|Excluded URLs (Optional)"
+msgid "DastProfiles|Excluded URLs (optional)"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths (optional)"
msgstr ""
msgid "DastProfiles|Hide debug messages"
@@ -11107,9 +11220,6 @@ msgstr ""
msgid "DastProfiles|Request headers"
msgstr ""
-msgid "DastProfiles|Rest API"
-msgstr ""
-
msgid "DastProfiles|Run the AJAX spider, in addition to the traditional spider, to crawl the target site."
msgstr ""
@@ -11119,6 +11229,9 @@ msgstr ""
msgid "DastProfiles|Save profile"
msgstr ""
+msgid "DastProfiles|Scan method"
+msgstr ""
+
msgid "DastProfiles|Scan mode"
msgstr ""
@@ -11197,12 +11310,24 @@ msgstr ""
msgid "DastProfiles|Website"
msgstr ""
+msgid "DastProfiles|What does each method do?"
+msgstr ""
+
msgid "DastProfiles|You can either choose a passive scan or validate the target site from the site profile management page. %{docsLinkStart}Learn more about site validation.%{docsLinkEnd}"
msgstr ""
msgid "DastProfiles|You cannot run an active scan against an unvalidated site."
msgstr ""
+msgid "DastProfiles|folder/dast_example.har or https://example.com/dast_example.har"
+msgstr ""
+
+msgid "DastProfiles|folder/example.postman_collection.json or https://example.com/"
+msgstr ""
+
+msgid "DastProfiles|folder/openapi.json or https://example.com/openapi.json"
+msgstr ""
+
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
@@ -11310,6 +11435,9 @@ msgstr ""
msgid "DatadogIntegration|API URL"
msgstr ""
+msgid "DatadogIntegration|Custom tags in Datadog. Enter one tag per line in the %{codeOpen}key:value%{codeClose} format. %{linkOpen}How do I use tags?%{linkClose}"
+msgstr ""
+
msgid "DatadogIntegration|Environment"
msgstr ""
@@ -11328,12 +11456,18 @@ msgstr ""
msgid "DatadogIntegration|Tag all data from this GitLab instance in Datadog. Useful when managing several self-managed deployments."
msgstr ""
+msgid "DatadogIntegration|Tags"
+msgstr ""
+
msgid "DatadogIntegration|The Datadog site to send data to. To send data to the EU site, use %{codeOpen}datadoghq.eu%{codeClose}."
msgstr ""
msgid "DatadogIntegration|Trace your GitLab pipelines with Datadog."
msgstr ""
+msgid "DatadogIntegration|have an invalid format"
+msgstr ""
+
msgid "Datasource name not found"
msgstr ""
@@ -11343,9 +11477,6 @@ msgstr ""
msgid "Date merged"
msgstr ""
-msgid "Date picker"
-msgstr "Sélecteur de date"
-
msgid "Date range"
msgstr ""
@@ -11499,9 +11630,6 @@ msgstr ""
msgid "Definition"
msgstr ""
-msgid "Delayed Project Deletion (%{adjourned_deletion})"
-msgstr ""
-
msgid "DelayedJobs|Are you sure you want to run %{jobName} immediately? Otherwise this job will run automatically after its timer finishes."
msgstr ""
@@ -11580,10 +11708,10 @@ msgstr ""
msgid "Delete pipeline"
msgstr ""
-msgid "Delete project"
+msgid "Delete pipeline schedule"
msgstr ""
-msgid "Delete project. Are you ABSOLUTELY SURE?"
+msgid "Delete project"
msgstr ""
msgid "Delete row"
@@ -11613,6 +11741,9 @@ msgstr ""
msgid "Delete this epic and all descendants?"
msgstr ""
+msgid "Delete this project"
+msgstr ""
+
msgid "Delete user list"
msgstr ""
@@ -11871,6 +12002,12 @@ msgstr ""
msgid "Deploy to..."
msgstr ""
+msgid "DeployBoards|To see deployment progress for your environments, make sure you are deploying to %{codeStart}$KUBE_NAMESPACE%{codeEnd} and annotating with %{codeStart}app.gitlab.com/app=$CI_PROJECT_PATH_SLUG%{codeEnd} and %{codeStart}app.gitlab.com/env=$CI_ENVIRONMENT_SLUG%{codeEnd}."
+msgstr ""
+
+msgid "DeployBoard|Kubernetes Pods"
+msgstr ""
+
msgid "DeployFreeze|Add a freeze period to prevent unintended releases during a period of time for a given environment. You must update the deployment jobs in %{filename} according to the deploy freezes added here. %{freeze_period_link_start}Learn more.%{freeze_period_link_end}"
msgstr ""
@@ -11955,9 +12092,6 @@ msgstr "Accès en lecture seule"
msgid "DeployTokens|Active Deploy Tokens (%{active_tokens})"
msgstr "Jetons de déploiement actifs : (%{active_tokens})"
-msgid "DeployTokens|Allows read and write access to registry images."
-msgstr ""
-
msgid "DeployTokens|Allows read and write access to the package registry."
msgstr ""
@@ -11970,6 +12104,9 @@ msgstr ""
msgid "DeployTokens|Allows read-only access to the repository."
msgstr ""
+msgid "DeployTokens|Allows write access to registry images."
+msgstr ""
+
msgid "DeployTokens|Copy deploy token"
msgstr ""
@@ -12063,12 +12200,57 @@ msgstr "En cours de déploiement sur"
msgid "Deploying to AWS is easy with GitLab"
msgstr ""
+msgid "Deployment"
+msgstr ""
+
msgid "Deployment Frequency"
msgstr ""
+msgid "Deployment Target|Project deployment target (optional)"
+msgstr ""
+
+msgid "Deployment Target|Select the deployment target"
+msgstr ""
+
msgid "Deployment frequency"
msgstr ""
+msgid "DeploymentTarget|GitLab Pages"
+msgstr ""
+
+msgid "DeploymentTarget|Heroku"
+msgstr ""
+
+msgid "DeploymentTarget|Infrastructure provider (Terraform, Cloudformation, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Kubernetes (GKE, EKS, OpenShift, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Managed container runtime (Fargate, Cloud Run, DigitalOcean App)"
+msgstr ""
+
+msgid "DeploymentTarget|Mobile app store"
+msgstr ""
+
+msgid "DeploymentTarget|No deployment planned"
+msgstr ""
+
+msgid "DeploymentTarget|Other hosting service"
+msgstr ""
+
+msgid "DeploymentTarget|Registry (package or container)"
+msgstr ""
+
+msgid "DeploymentTarget|Self-managed container runtime (Podman, Docker Swarm, Docker Compose)"
+msgstr ""
+
+msgid "DeploymentTarget|Serverless backend (Lambda, Cloud functions)"
+msgstr ""
+
+msgid "DeploymentTarget|Virtual machine (for example, EC2)"
+msgstr ""
+
msgid "Deployments"
msgstr ""
@@ -12107,6 +12289,9 @@ msgstr ""
msgid "Deployment|This deployment was created using the API"
msgstr ""
+msgid "Deployment|Triggerer"
+msgstr ""
+
msgid "Deployment|Waiting"
msgstr ""
@@ -12134,6 +12319,18 @@ msgstr ""
msgid "Deprecated API rate limits"
msgstr ""
+msgid "Deprecations|Feature deprecation and removal"
+msgstr ""
+
+msgid "Deprecations|For information on a possible replacement %{epicStart} learn more about Opstrace %{epicEnd}."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7 and are %{epicStart} scheduled for removal %{epicEnd} in GitLab 15.0."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7, and are %{removal_link_start} scheduled for removal %{link_end} in GitLab 15.0. For information on a possible replacement, %{opstrace_link_start} learn more about Opstrace %{link_end}."
+msgstr ""
+
msgid "Deprioritize label"
msgstr "Déprioriser l’étiquette"
@@ -12379,10 +12576,10 @@ msgstr ""
msgid "DevopsAdoption|At least one deploy"
msgstr ""
-msgid "DevopsAdoption|At least one issue opened"
+msgid "DevopsAdoption|At least one issue created"
msgstr ""
-msgid "DevopsAdoption|At least one merge request opened"
+msgid "DevopsAdoption|At least one merge request created"
msgstr ""
msgid "DevopsAdoption|At least one pipeline successfully run"
@@ -12583,6 +12780,9 @@ msgstr ""
msgid "Direct member"
msgstr ""
+msgid "Direct members"
+msgstr ""
+
msgid "Direct non-authenticated users to this page."
msgstr ""
@@ -12699,6 +12899,9 @@ msgid_plural "Dismiss %d selected vulnerabilities as"
msgstr[0] ""
msgstr[1] ""
+msgid "Dismiss Alert"
+msgstr ""
+
msgid "Dismiss merge request promotion"
msgstr ""
@@ -12726,9 +12929,15 @@ msgstr ""
msgid "Display alerts from all configured monitoring tools."
msgstr ""
+msgid "Display milestones"
+msgstr ""
+
msgid "Display name"
msgstr ""
+msgid "Display progress of child issues"
+msgstr ""
+
msgid "Display rendered file"
msgstr ""
@@ -12834,6 +13043,9 @@ msgstr ""
msgid "Download image"
msgstr ""
+msgid "Download payload"
+msgstr ""
+
msgid "Download raw data (.csv)"
msgstr ""
@@ -13011,6 +13223,9 @@ msgstr "Modifier l’identité de %{user_name}"
msgid "Edit in Web IDE"
msgstr ""
+msgid "Edit in pipeline editor"
+msgstr ""
+
msgid "Edit in single-file editor"
msgstr ""
@@ -13053,6 +13268,9 @@ msgstr ""
msgid "Edit your most recent comment in a thread (from an empty textarea)"
msgstr ""
+msgid "Edit, lint, and visualize your pipeline."
+msgstr ""
+
msgid "Edited"
msgstr ""
@@ -13494,6 +13712,9 @@ msgstr ""
msgid "Enforce two-factor authentication for all user sign-ins."
msgstr ""
+msgid "Enhance security by storing service account keys in secret managers - learn more about %{docLinkStart}secret management with GitLab%{docLinkEnd}"
+msgstr ""
+
msgid "Ensure connectivity is available from the GitLab server to the Prometheus server"
msgstr ""
@@ -13554,6 +13775,9 @@ 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 following to confirm:"
+msgstr ""
+
msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
@@ -14084,9 +14308,6 @@ 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 ""
@@ -14222,6 +14443,9 @@ msgstr ""
msgid "Errors:"
msgstr ""
+msgid "Escalate this incident"
+msgstr ""
+
msgid "Escalation Policies"
msgstr ""
@@ -14234,6 +14458,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy"
+msgstr ""
+
msgid "Escalation policy:"
msgstr ""
@@ -14485,6 +14712,9 @@ msgstr ""
msgid "Existing sign in methods may be removed"
msgstr ""
+msgid "Exit."
+msgstr ""
+
msgid "Expand"
msgstr "Étendre"
@@ -14581,6 +14811,9 @@ msgstr "Explorer les projets"
msgid "Explore public groups"
msgstr "Explorer les groupes publics"
+msgid "Explore public projects"
+msgstr ""
+
msgid "Explore snippets"
msgstr ""
@@ -14742,7 +14975,7 @@ msgid_plural "Failed to archive designs. Please try again."
msgstr[0] ""
msgstr[1] ""
-msgid "Failed to assign a reviewer because no user was found."
+msgid "Failed to assign a reviewer because no user was specified."
msgstr ""
msgid "Failed to assign a user because no user was found."
@@ -14808,10 +15041,10 @@ msgstr ""
msgid "Failed to find import label for Jira import."
msgstr ""
-msgid "Failed to generate export, please try again later."
+msgid "Failed to find users for %{missing}"
msgstr ""
-msgid "Failed to generate report, please try again after sometime"
+msgid "Failed to generate export, please try again later."
msgstr ""
msgid "Failed to get ref."
@@ -14910,6 +15143,9 @@ msgstr ""
msgid "Failed to remove a to-do item for the design."
msgstr ""
+msgid "Failed to remove attention because no user was found."
+msgstr ""
+
msgid "Failed to remove mirror."
msgstr "Impossible de supprimer le miroir."
@@ -14922,6 +15158,9 @@ msgstr ""
msgid "Failed to remove user key."
msgstr ""
+msgid "Failed to request attention because no user was found."
+msgstr ""
+
msgid "Failed to reset key. Please try again."
msgstr ""
@@ -15003,6 +15242,9 @@ msgstr ""
msgid "Feature Flags"
msgstr "Indicateurs de fonctionnalités"
+msgid "Feature deprecation and removal"
+msgstr ""
+
msgid "Feature flag status"
msgstr ""
@@ -15500,7 +15742,7 @@ msgstr ""
msgid "For each job, re-use the project workspace. If the workspace doesn't exist, use %{code_open}git clone%{code_close}."
msgstr ""
-msgid "For example, the application using the token or the purpose of the token."
+msgid "For example, the application using the token or the purpose of the token. Do not give sensitive information for the name of the token, as it will be visible to all %{resource_type} members."
msgstr ""
msgid "For files larger than this limit, only index the file name. The file content is neither indexed nor searchable."
@@ -15584,9 +15826,6 @@ msgstr ""
msgid "ForkProject|Select a namespace"
msgstr ""
-msgid "ForkProject|Select a namespace to fork the project"
-msgstr ""
-
msgid "ForkProject|The project can be accessed by any logged in user."
msgstr ""
@@ -15683,6 +15922,9 @@ msgstr ""
msgid "Full name"
msgstr ""
+msgid "GCP region configured"
+msgstr ""
+
msgid "GPG Key ID:"
msgstr ""
@@ -15863,6 +16105,9 @@ msgstr ""
msgid "Geo|Failed"
msgstr "En échec"
+msgid "Geo|Filter Geo sites"
+msgstr ""
+
msgid "Geo|Filter by name"
msgstr ""
@@ -16274,6 +16519,12 @@ msgstr "Importation depuis GitLab"
msgid "GitLab Issue"
msgstr ""
+msgid "GitLab KAS"
+msgstr ""
+
+msgid "GitLab Memberships CSV Export"
+msgstr ""
+
msgid "GitLab Pages"
msgstr ""
@@ -16322,6 +16573,9 @@ 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 free to use. Many features for larger teams are part of our %{link_start}paid products%{link_end}. You can try Ultimate for free without any obligation or payment details."
+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 ""
@@ -16448,7 +16702,7 @@ msgstr ""
msgid "GitLabPages|When enabled, all attempts to visit your website through HTTP are automatically redirected to HTTPS using a response with status code 301. Requires a valid certificate for all domains. %{docs_link_start}Learn more.%{link_end}"
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. %{docs_link_start}Learn more.%{link_end}"
+msgid "GitLabPages|When using Pages under the general domain of a GitLab instance (%{pages_host}), you cannot use HTTPS with subdomains of subdomains. If your namespace or groupname contains a dot, it does not work. This is a limitation of the HTTP Over TLS protocol. HTTP pages work if you don't redirect HTTP to HTTPS. %{docs_link_start}Learn more.%{link_end}"
msgstr ""
msgid "GitLabPages|With GitLab Pages you can host your static website directly from your GitLab repository. %{docs_link_start}Learn more.%{link_end}"
@@ -16625,9 +16879,6 @@ msgstr ""
msgid "Go to find file"
msgstr ""
-msgid "Go to fork"
-msgstr ""
-
msgid "Go to issue boards"
msgstr ""
@@ -16835,9 +17086,6 @@ msgstr "Statut du stockage LFS Git du groupe :"
msgid "Group Hooks"
msgstr ""
-msgid "Group ID"
-msgstr "Identifiant du groupe"
-
msgid "Group Owner must have signed in with SAML before enabling Group Managed Accounts"
msgstr ""
@@ -16865,9 +17113,6 @@ msgstr "Avatar de groupe"
msgid "Group by"
msgstr ""
-msgid "Group description"
-msgstr ""
-
msgid "Group description (optional)"
msgstr "Description du groupe (optionnel)"
@@ -16982,7 +17227,7 @@ msgstr "Groupe : %{group_name}"
msgid "Group: %{name}"
msgstr ""
-msgid "GroupActivityMetrics|Issues opened"
+msgid "GroupActivityMetrics|Issues created"
msgstr ""
msgid "GroupActivityMetrics|Last 90 days"
@@ -16991,7 +17236,7 @@ msgstr ""
msgid "GroupActivityMetrics|Members added"
msgstr ""
-msgid "GroupActivityMetrics|Merge Requests opened"
+msgid "GroupActivityMetrics|Merge Requests created"
msgstr ""
msgid "GroupActivityMetrics|Recent activity"
@@ -17282,6 +17527,9 @@ msgstr ""
msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
+msgid "GroupSettings|Choose a group path that does not start with a dash or end with a period. It can also contain alphanumeric characters and underscores."
+msgstr ""
+
msgid "GroupSettings|Compliance frameworks"
msgstr ""
@@ -17315,7 +17563,7 @@ msgstr ""
msgid "GroupSettings|If not specified at the group or instance level, the default is %{default_initial_branch_name}. Does not affect existing repositories."
msgstr ""
-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."
+msgid "GroupSettings|If the parent group's visibility is lower than the group's current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility."
msgstr ""
msgid "GroupSettings|New runners registration token has been generated!"
@@ -17432,7 +17680,10 @@ msgstr ""
msgid "Groups and projects"
msgstr ""
-msgid "Groups and subgroups"
+msgid "Groups are a great way to organize projects and people."
+msgstr ""
+
+msgid "Groups are the best way to manage projects and members."
msgstr ""
msgid "Groups to synchronize"
@@ -17543,14 +17794,17 @@ msgstr ""
msgid "GroupsTree|Are you sure you want to leave the \"%{fullName}\" group?"
msgstr "Êtes-vous sûr·e de vouloir quitter le groupe « %{fullName} » ?"
-msgid "GroupsTree|Edit group"
-msgstr "Modifier le groupe"
+msgid "GroupsTree|Delete"
+msgstr ""
+
+msgid "GroupsTree|Edit"
+msgstr ""
msgid "GroupsTree|Failed to leave the group. Please make sure you are not the only owner."
msgstr "Impossible de quitter le groupe. Veuillez vous assurer que vous n’êtes pas seul·e propriétaire."
-msgid "GroupsTree|Leave this group"
-msgstr "Quitter ce groupe"
+msgid "GroupsTree|Leave group"
+msgstr ""
msgid "GroupsTree|Loading groups"
msgstr "Chargement des groupes"
@@ -17561,9 +17815,57 @@ msgstr "Aucun groupe ne correspond à votre recherche"
msgid "GroupsTree|No groups or projects matched your search"
msgstr "Aucun groupe ni projet ne correspond à votre recherche"
+msgid "GroupsTree|Options"
+msgstr ""
+
msgid "GroupsTree|Search by name"
msgstr "Rechercher par nom"
+msgid "Groups|Avatar will be removed. Are you sure?"
+msgstr ""
+
+msgid "Groups|Changing group URL can have unintended side effects."
+msgstr ""
+
+msgid "Groups|Checking group URL availability..."
+msgstr ""
+
+msgid "Groups|Enter a descriptive name for your group."
+msgstr ""
+
+msgid "Groups|Group ID"
+msgstr ""
+
+msgid "Groups|Group URL"
+msgstr ""
+
+msgid "Groups|Group avatar"
+msgstr ""
+
+msgid "Groups|Group description (optional)"
+msgstr ""
+
+msgid "Groups|Group name"
+msgstr ""
+
+msgid "Groups|Group path is available."
+msgstr ""
+
+msgid "Groups|Group path is unavailable. Path has been replaced with a suggested available path."
+msgstr ""
+
+msgid "Groups|Learn more"
+msgstr ""
+
+msgid "Groups|Must start with letter, digit, emoji, or underscore. Can also contain periods, dashes, spaces, and parentheses."
+msgstr ""
+
+msgid "Groups|Remove avatar"
+msgstr ""
+
+msgid "Groups|Save changes"
+msgstr ""
+
msgid "Guideline"
msgstr ""
@@ -17573,6 +17875,9 @@ msgstr ""
msgid "HAR file path or URL"
msgstr ""
+msgid "HTTP Archive (HAR)"
+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 ""
@@ -17973,6 +18278,9 @@ msgstr ""
msgid "INFO: Your SSH key is expiring soon. Please generate a new key."
msgstr ""
+msgid "IP"
+msgstr ""
+
msgid "IP Address"
msgstr "Adresse IP"
@@ -18009,6 +18317,9 @@ msgstr ""
msgid "IdentityVerification|Verify your identity"
msgstr ""
+msgid "IdentityVerification|You can always verify your account at a later time to create a group."
+msgstr ""
+
msgid "If any indexed field exceeds this limit, it is truncated to this number of characters. The rest of the content is neither indexed nor searchable. This does not apply to repository and wiki indexing. For unlimited characters, set this to 0."
msgstr ""
@@ -18066,6 +18377,9 @@ msgstr "Si vous utilisez GitHub, vous verrez les statuts des pipelines sur GitHu
msgid "If you add %{codeStart}needs%{codeEnd} to jobs in your pipeline you'll be able to view the %{codeStart}needs%{codeEnd} relationships between jobs in this tab as a %{linkStart}Directed Acyclic Graph (DAG)%{linkEnd}."
msgstr ""
+msgid "If you are added to a project, it will be displayed here."
+msgstr ""
+
msgid "If you did not initiate these sign-in attempts, please reach out to your administrator or enable two-factor authentication (2FA) on your account."
msgstr ""
@@ -18372,12 +18686,24 @@ msgstr ""
msgid "InProductMarketing|3 ways to dive into GitLab CI/CD"
msgstr ""
+msgid "InProductMarketing|A single application eliminates complex integrations, data chokepoints, and toolchain maintenance, resulting in greater productivity and lower cost."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features, build more efficiently, strengthen security and compliance."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features."
+msgstr ""
+
msgid "InProductMarketing|Actually, GitLab makes the team work (better)"
msgstr ""
msgid "InProductMarketing|And finally %{deploy_link} a Python application."
msgstr ""
+msgid "InProductMarketing|And many more..."
+msgstr ""
+
msgid "InProductMarketing|Are your runners ready?"
msgstr ""
@@ -18396,15 +18722,33 @@ msgstr ""
msgid "InProductMarketing|Blog"
msgstr ""
+msgid "InProductMarketing|Break down silos to coordinate seamlessly across development, operations, and security with a consistent experience across the development lifecycle."
+msgstr ""
+
+msgid "InProductMarketing|Burn up/down charts"
+msgstr ""
+
msgid "InProductMarketing|By enabling code owners and required merge approvals the right person will review the right MR. This is a win-win: cleaner code and a more efficient review process."
msgstr ""
msgid "InProductMarketing|Click on the number below that corresponds with your answer — 1 being very difficult, 5 being very easy."
msgstr ""
+msgid "InProductMarketing|Code owners"
+msgstr ""
+
msgid "InProductMarketing|Code owners and required merge approvals are part of the paid tiers of GitLab. You can start a free 30-day trial of GitLab Ultimate and enable these features in less than 5 minutes with no credit card required."
msgstr ""
+msgid "InProductMarketing|Code review analytics"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration across stages in GitLab"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration made easy"
+msgstr ""
+
msgid "InProductMarketing|Create a custom CI runner with just a few clicks"
msgstr ""
@@ -18414,12 +18758,21 @@ msgstr ""
msgid "InProductMarketing|Create a project in GitLab in 5 minutes"
msgstr ""
+msgid "InProductMarketing|Create well-defined workflows by using scoped labels on issues, merge requests, and epics. Labels with the same scope cannot be used together, which prevents conflicts."
+msgstr ""
+
msgid "InProductMarketing|Create your first project!"
msgstr ""
+msgid "InProductMarketing|Define who owns specific files or directories, so the right reviewers are suggested when a merge request introduces changes to those files."
+msgstr ""
+
msgid "InProductMarketing|Deliver Better Products Faster"
msgstr ""
+msgid "InProductMarketing|Dependency scanning"
+msgstr ""
+
msgid "InProductMarketing|Did you know teams that use GitLab are far more efficient?"
msgstr ""
@@ -18429,15 +18782,27 @@ msgstr ""
msgid "InProductMarketing|Dig in and create a project and a repo"
msgstr ""
+msgid "InProductMarketing|Discover Premium & Ultimate"
+msgstr ""
+
+msgid "InProductMarketing|Discover Premium & Ultimate."
+msgstr ""
+
msgid "InProductMarketing|Do you have a minute?"
msgstr ""
msgid "InProductMarketing|Do you have a teammate who would be perfect for this task?"
msgstr ""
+msgid "InProductMarketing|Dynamic application security testing"
+msgstr ""
+
msgid "InProductMarketing|Easy"
msgstr ""
+msgid "InProductMarketing|Epics"
+msgstr ""
+
msgid "InProductMarketing|Expand your DevOps journey with a free GitLab trial"
msgstr ""
@@ -18459,9 +18824,15 @@ msgstr ""
msgid "InProductMarketing|Feel the need for speed?"
msgstr ""
+msgid "InProductMarketing|Find and fix bottlenecks in your code review process by understanding how long open merge requests have been in review."
+msgstr ""
+
msgid "InProductMarketing|Find out how your teams are really doing"
msgstr ""
+msgid "InProductMarketing|Find out if your external libraries are safe. Run dependency scanning jobs that check for known vulnerabilities in your external libraries."
+msgstr ""
+
msgid "InProductMarketing|Follow our steps"
msgstr ""
@@ -18498,6 +18869,9 @@ msgstr ""
msgid "InProductMarketing|GitLab is better with teammates to help out!"
msgstr ""
+msgid "InProductMarketing|GitLab is infrastructure agnostic (supporting GCP, AWS, Azure, OpenShift, VMWare, On Prem, Bare Metal, and more), offering a consistent workflow experience – irrespective of the environment."
+msgstr ""
+
msgid "InProductMarketing|GitLab provides static application security testing (SAST), dynamic application security testing (DAST), container scanning, and dependency scanning to help you deliver secure applications along with license compliance."
msgstr ""
@@ -18588,21 +18962,36 @@ msgstr ""
msgid "InProductMarketing|It's also possible to simply %{external_repo_link} in order to take advantage of GitLab's CI/CD."
msgstr ""
+msgid "InProductMarketing|Keep your code quality high by defining who should approve merge requests and how many approvals are required."
+msgstr ""
+
msgid "InProductMarketing|Launch GitLab CI/CD in 20 minutes or less"
msgstr ""
+msgid "InProductMarketing|Lower cost of development"
+msgstr ""
+
+msgid "InProductMarketing|Make it easier to collaborate on high-level ideas by grouping related issues in an epic."
+msgstr ""
+
msgid "InProductMarketing|Making the switch? It's easier than you think to import your projects into GitLab. Move %{github_link}, or import something %{bitbucket_link}."
msgstr ""
msgid "InProductMarketing|Master the art of importing!"
msgstr ""
+msgid "InProductMarketing|Merge request approval rule"
+msgstr ""
+
msgid "InProductMarketing|Move on to easily creating a Pages website %{ci_template_link}"
msgstr ""
msgid "InProductMarketing|Multiple owners, confusing workstreams? We've got you covered"
msgstr ""
+msgid "InProductMarketing|Multiple required approvers"
+msgstr ""
+
msgid "InProductMarketing|Need an alternative to importing?"
msgstr ""
@@ -18615,18 +19004,33 @@ msgstr ""
msgid "InProductMarketing|Our tool brings all the things together"
msgstr ""
+msgid "InProductMarketing|Protect your web application by using DAST to examine for vulnerabilities in deployed environments."
+msgstr ""
+
msgid "InProductMarketing|Rapid development, simplified"
msgstr ""
msgid "InProductMarketing|Reduce Security & Compliance Risk"
msgstr ""
+msgid "InProductMarketing|Require multiple approvers on a merge request, so you know it's in good shape before it's merged."
+msgstr ""
+
+msgid "InProductMarketing|Roadmaps"
+msgstr ""
+
+msgid "InProductMarketing|Scoped labels"
+msgstr ""
+
msgid "InProductMarketing|Security that's integrated into your development lifecycle"
msgstr ""
msgid "InProductMarketing|Sometimes you're not ready to make a full transition to a new tool. If you're not ready to fully commit, %{mirroring_link} gives you a safe way to try out GitLab in parallel with your current tool."
msgstr ""
+msgid "InProductMarketing|Speed. Efficiency. Trust."
+msgstr ""
+
msgid "InProductMarketing|Spin up an autoscaling runner in GitLab"
msgstr ""
@@ -18636,6 +19040,9 @@ msgstr ""
msgid "InProductMarketing|Start a Self-Managed trial"
msgstr ""
+msgid "InProductMarketing|Start a free trial"
+msgstr ""
+
msgid "InProductMarketing|Start a free trial of GitLab Ultimate – no credit card required"
msgstr ""
@@ -18702,6 +19109,9 @@ msgstr ""
msgid "InProductMarketing|To understand and get the most out of GitLab, start at the beginning and %{project_link}. In GitLab, repositories are part of a project, so after you've created your project you can go ahead and %{repo_link}."
msgstr ""
+msgid "InProductMarketing|Track completed issues in a chart, so you can see how a milestone is progressing at a glance."
+msgstr ""
+
msgid "InProductMarketing|Try GitLab Ultimate for free"
msgstr ""
@@ -18738,6 +19148,9 @@ msgstr ""
msgid "InProductMarketing|Very easy"
msgstr ""
+msgid "InProductMarketing|Visualize your epics and milestones in a timeline."
+msgstr ""
+
msgid "InProductMarketing|Want to host GitLab on your servers?"
msgstr ""
@@ -18759,6 +19172,9 @@ msgstr ""
msgid "InProductMarketing|YouTube"
msgstr ""
+msgid "InProductMarketing|Your software, deployed your way"
+msgstr ""
+
msgid "InProductMarketing|Your teams can be more efficient"
msgstr ""
@@ -18879,9 +19295,18 @@ msgstr ""
msgid "IncidentManagement|No incidents to display."
msgstr ""
+msgid "IncidentManagement|None"
+msgstr ""
+
msgid "IncidentManagement|Open"
msgstr ""
+msgid "IncidentManagement|Page your team with escalation policies"
+msgstr ""
+
+msgid "IncidentManagement|Paged"
+msgstr ""
+
msgid "IncidentManagement|Published"
msgstr ""
@@ -18891,6 +19316,9 @@ msgstr ""
msgid "IncidentManagement|Severity"
msgstr ""
+msgid "IncidentManagement|Status"
+msgstr ""
+
msgid "IncidentManagement|There are no closed incidents"
msgstr ""
@@ -18909,6 +19337,9 @@ msgstr ""
msgid "IncidentManagement|Unpublished"
msgstr ""
+msgid "IncidentManagement|Use escalation policies to automatically page your team when incidents are created."
+msgstr ""
+
msgid "IncidentSettings|Activate \"time to SLA\" countdown timer"
msgstr ""
@@ -18954,7 +19385,10 @@ msgstr ""
msgid "Incidents"
msgstr ""
-msgid "Incidents|Add a URL"
+msgid "Incidents|Add image details"
+msgstr ""
+
+msgid "Incidents|Add text or a link to display with your image. If you don't add either, the file name displays instead."
msgstr ""
msgid "Incidents|Drop or %{linkStart}upload%{linkEnd} a metric screenshot to attach it to the incident"
@@ -18969,10 +19403,10 @@ msgstr ""
msgid "Incidents|There was an issue loading metric images."
msgstr ""
-msgid "Incidents|There was an issue uploading your image."
+msgid "Incidents|There was an issue updating your image."
msgstr ""
-msgid "Incidents|You can optionally add a URL to link users to the original graph."
+msgid "Incidents|There was an issue uploading your image."
msgstr ""
msgid "Incident|Alert details"
@@ -18981,9 +19415,18 @@ msgstr ""
msgid "Incident|Are you sure you wish to delete this image?"
msgstr ""
+msgid "Incident|Delete image"
+msgstr ""
+
msgid "Incident|Deleting %{filename}"
msgstr ""
+msgid "Incident|Edit image text or link"
+msgstr ""
+
+msgid "Incident|Editing %{filename}"
+msgstr ""
+
msgid "Incident|Metrics"
msgstr ""
@@ -19253,12 +19696,18 @@ msgstr ""
msgid "Integrations|Branches for which notifications are to be sent"
msgstr ""
+msgid "Integrations|Clear if using a self-signed certificate."
+msgstr ""
+
msgid "Integrations|Comment detail:"
msgstr ""
msgid "Integrations|Comment settings:"
msgstr ""
+msgid "Integrations|Connection details"
+msgstr ""
+
msgid "Integrations|Connection failed. Please check your settings."
msgstr ""
@@ -19283,6 +19732,9 @@ msgstr ""
msgid "Integrations|Enable GitLab.com slash commands in a Slack workspace."
msgstr ""
+msgid "Integrations|Enable SSL verification"
+msgstr ""
+
msgid "Integrations|Enable comments"
msgstr ""
@@ -19361,6 +19813,9 @@ msgstr ""
msgid "Integrations|Return to GitLab for Jira"
msgstr ""
+msgid "Integrations|SSL verification"
+msgstr ""
+
msgid "Integrations|Save settings?"
msgstr ""
@@ -19406,9 +19861,6 @@ msgstr ""
msgid "Integrations|Use default settings"
msgstr ""
-msgid "Integrations|When you mention a Jira issue in a commit or merge request, GitLab creates a remote link and comment (if enabled)."
-msgstr ""
-
msgid "Integrations|You can now close this window and return to the GitLab for Jira application."
msgstr ""
@@ -19433,9 +19885,6 @@ msgstr ""
msgid "Integrations|can't exceed %{recipients_limit}"
msgstr ""
-msgid "Interactive developer security education."
-msgstr ""
-
msgid "Interactive mode"
msgstr ""
@@ -19925,6 +20374,9 @@ msgstr ""
msgid "IssueAnalytics|Assignees"
msgstr ""
+msgid "IssueAnalytics|Created by"
+msgstr ""
+
msgid "IssueAnalytics|Due date"
msgstr ""
@@ -19937,9 +20389,6 @@ msgstr ""
msgid "IssueAnalytics|Milestone"
msgstr ""
-msgid "IssueAnalytics|Opened by"
-msgstr ""
-
msgid "IssueAnalytics|Status"
msgstr ""
@@ -20063,10 +20512,10 @@ msgstr "Une fois que vous aurez commencé à créer des tickets d’incident en
msgid "IssuesAnalytics|Avg/Month:"
msgstr ""
-msgid "IssuesAnalytics|Issues opened"
+msgid "IssuesAnalytics|Issues created"
msgstr ""
-msgid "IssuesAnalytics|Issues opened per month"
+msgid "IssuesAnalytics|Issues created per month"
msgstr ""
msgid "IssuesAnalytics|Last 12 months"
@@ -20093,6 +20542,9 @@ msgstr ""
msgid "It looks like you have some draft commits in this branch."
msgstr ""
+msgid "It looks like you're attempting to activate your subscription. Use %{a_start}the Subscription page%{a_end} instead."
+msgstr ""
+
msgid "It may be several days before you see feature usage data."
msgstr ""
@@ -20321,6 +20773,9 @@ msgstr ""
msgid "JiraConnect|You can now close this window and return to Jira."
msgstr ""
+msgid "JiraConnect|You don't have permission to create branches for this project. Select a different project or contact the project owner for access. %{linkStart}Learn more.%{linkEnd}"
+msgstr ""
+
msgid "JiraRequest|A connection error occurred while connecting to Jira. Try your request again."
msgstr ""
@@ -20369,13 +20824,13 @@ msgstr ""
msgid "JiraService|Define the type of Jira issue to create from a vulnerability."
msgstr ""
-msgid "JiraService|Displaying Jira issues while leaving the GitLab issue functionality enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
+msgid "JiraService|Displaying Jira issues while leaving GitLab issues also enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
msgstr ""
-msgid "JiraService|Enable Jira issues"
+msgid "JiraService|Enable Jira issue creation from vulnerabilities"
msgstr ""
-msgid "JiraService|Enable Jira issues creation from vulnerabilities"
+msgid "JiraService|Enable Jira issues"
msgstr ""
msgid "JiraService|Enable Jira transitions"
@@ -20492,16 +20947,19 @@ msgstr ""
msgid "JiraService|View Jira issues in GitLab"
msgstr ""
-msgid "JiraService|Warning: All GitLab users that have access to this GitLab project are able to view all issues from the Jira project specified below."
+msgid "JiraService|Warning: All GitLab users with access to this GitLab project can view all issues from the Jira project you select."
msgstr ""
msgid "JiraService|Web URL"
msgstr ""
-msgid "JiraService|Work on Jira issues without leaving GitLab. Adds a Jira menu to access your list of Jira issues and view any issue as read-only."
+msgid "JiraService|When a Jira issue is mentioned in a commit or merge request, a remote link and comment (if enabled) will be created."
msgstr ""
-msgid "JiraService|You need to configure Jira before enabling this integration. For more details, read the %{jira_doc_link_start}Jira integration documentation%{link_end}."
+msgid "JiraService|Work on Jira issues without leaving GitLab. Add a Jira menu to access a read-only list of your Jira issues."
+msgstr ""
+
+msgid "JiraService|You must configure Jira before enabling this integration. %{jira_doc_link_start}Learn more.%{link_end}"
msgstr ""
msgid "Job"
@@ -20513,9 +20971,6 @@ msgstr ""
msgid "Job Failed #%{build_id}"
msgstr ""
-msgid "Job ID"
-msgstr ""
-
msgid "Job artifact"
msgstr ""
@@ -20582,9 +21037,27 @@ msgstr ""
msgid "Jobs|You're about to retry a job that failed because it attempted to deploy code that is older than the latest deployment. Retrying this job could result in overwriting the environment with the older source code."
msgstr ""
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source} into %{target}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{ref}"
+msgstr ""
+
+msgid "Job|Are you sure you want to erase this job log and artifacts?"
+msgstr ""
+
msgid "Job|Browse"
msgstr "Parcourir"
+msgid "Job|Cancel"
+msgstr ""
+
msgid "Job|Complete Raw"
msgstr "Brut complet"
@@ -20594,6 +21067,9 @@ msgstr "Télécharger"
msgid "Job|Erase job log and artifacts"
msgstr ""
+msgid "Job|Finished at"
+msgstr ""
+
msgid "Job|Job artifacts"
msgstr "Artefacts de la tâche"
@@ -20606,7 +21082,7 @@ msgstr ""
msgid "Job|Keep"
msgstr "Garder"
-msgid "Job|Pipeline"
+msgid "Job|Retry"
msgstr ""
msgid "Job|Scroll to bottom"
@@ -20618,6 +21094,9 @@ msgstr "Faire défiler vers le haut"
msgid "Job|Show complete raw"
msgstr "Afficher la version brute"
+msgid "Job|Status"
+msgstr ""
+
msgid "Job|The artifacts were removed"
msgstr "Les artefacts ont été supprimés"
@@ -20645,21 +21124,12 @@ msgstr ""
msgid "Job|delayed"
msgstr ""
-msgid "Job|for"
-msgstr ""
-
-msgid "Job|into"
-msgstr ""
-
msgid "Job|manual"
msgstr ""
msgid "Job|triggered"
msgstr ""
-msgid "Job|with"
-msgstr ""
-
msgid "Join Zoom meeting"
msgstr ""
@@ -20762,9 +21232,6 @@ msgstr ""
msgid "Ki"
msgstr ""
-msgid "Kontra"
-msgstr ""
-
msgid "Kroki"
msgstr ""
@@ -21088,6 +21555,9 @@ msgstr ""
msgid "Learn more about Auto DevOps"
msgstr ""
+msgid "Learn more about GitLab"
+msgstr ""
+
msgid "Learn more about Needs relationships"
msgstr ""
@@ -21415,9 +21885,18 @@ msgstr ""
msgid "Licenses|Displays licenses detected in the project, based on the %{linkStart}latest successful%{linkEnd} scan"
msgstr ""
+msgid "Licenses|Drag your license file here or %{linkStart}click to upload%{linkEnd}."
+msgstr ""
+
+msgid "Licenses|Drop your license file to start the upload."
+msgstr ""
+
msgid "Licenses|Error fetching the license list. Please check your network connection and try again."
msgstr ""
+msgid "Licenses|Error: You are trying to upload something other than a file"
+msgstr ""
+
msgid "Licenses|License Compliance"
msgstr ""
@@ -21436,6 +21915,9 @@ msgstr ""
msgid "Licenses|Specified policies in this project"
msgstr ""
+msgid "Licenses|The file could not be uploaded."
+msgstr ""
+
msgid "Licenses|The license list details information about the licenses used within your project."
msgstr ""
@@ -21469,11 +21951,6 @@ msgstr ""
msgid "Limit the size of Sidekiq jobs stored in Redis."
msgstr ""
-msgid "Limited to showing %d event at most"
-msgid_plural "Limited to showing %d events at most"
-msgstr[0] "Affichage limité à %d événement maximum"
-msgstr[1] "Affichage limité à %d événements maximum"
-
msgid "Limiting mode"
msgstr ""
@@ -21483,6 +21960,9 @@ msgstr ""
msgid "Link"
msgstr ""
+msgid "Link (optional)"
+msgstr ""
+
msgid "Link Prometheus monitoring to GitLab."
msgstr ""
@@ -21519,6 +21999,9 @@ msgstr ""
msgid "Linked emails (%{email_count})"
msgstr ""
+msgid "Linked epics"
+msgstr ""
+
msgid "Linked issues"
msgstr ""
@@ -21546,6 +22029,15 @@ msgstr "Lister les dépôts disponibles"
msgid "List of all merge commits"
msgstr ""
+msgid "List of environments for this project"
+msgstr ""
+
+msgid "List of suitable GCP locations"
+msgstr ""
+
+msgid "List of users allowed to exceed the rate limit."
+msgstr ""
+
msgid "List options"
msgstr ""
@@ -21765,6 +22257,9 @@ msgstr ""
msgid "Maintenance mode"
msgstr ""
+msgid "Make adjustments to how your GitLab instance is set up."
+msgstr ""
+
msgid "Make and review changes in the browser with the Web IDE"
msgstr ""
@@ -21909,6 +22404,12 @@ msgstr ""
msgid "MarkdownEditor|Add italic text (%{modifier_key}I)"
msgstr ""
+msgid "MarkdownEditor|Add strikethrough text (%{modifierKey}⇧X)"
+msgstr ""
+
+msgid "MarkdownEditor|Add strikethrough text (%{modifier_key}⇧X)"
+msgstr ""
+
msgid "Marked For Deletion At - %{deletion_time}"
msgstr ""
@@ -22170,6 +22671,9 @@ msgstr ""
msgid "Maximum push size (MB)"
msgstr ""
+msgid "Maximum requests per 10 minutes per user"
+msgstr ""
+
msgid "Maximum requests per minute"
msgstr ""
@@ -22260,6 +22764,19 @@ msgstr ""
msgid "Members of a group may only view projects they have permission to access"
msgstr ""
+msgid "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seat in use and will be billed for the overage."
+msgid_plural "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seats in use and will be billed for the overage."
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "MembersOverage|You are about to incur additional charges"
+msgstr ""
+
+msgid "MembersOverage|Your subscription includes %d seat."
+msgid_plural "MembersOverage|Your subscription includes %d seats."
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Membership"
msgstr ""
@@ -22464,9 +22981,6 @@ msgstr ""
msgid "Merge request not merged"
msgstr ""
-msgid "Merge request pipelines 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 merge request pipelines."
-msgstr ""
-
msgid "Merge request reports"
msgstr ""
@@ -22563,13 +23077,13 @@ msgstr "Une erreur est survenue lors de l’enregistrement du brouillon du comme
msgid "MergeRequests|Create issue to resolve thread"
msgstr ""
-msgid "MergeRequests|Failed to squash. Should be done manually."
-msgstr ""
-
msgid "MergeRequests|Saving the comment failed"
msgstr "L’enregistrement du commentaire a échoué"
-msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
+msgid "MergeRequests|Squashing failed: Squash the commits locally, resolve any conflicts, then push the branch."
+msgstr ""
+
+msgid "MergeRequests|Squashing not allowed: This project doesn't allow you to squash commits when merging."
msgstr ""
msgid "MergeRequests|Thread stays resolved"
@@ -23410,6 +23924,18 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "MrList|Assigned to %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from assignee %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from reviewer %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Review requested from %{name}, go to their profile."
+msgstr ""
+
msgid "Multi-project"
msgstr ""
@@ -23443,7 +23969,7 @@ msgstr ""
msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "My Awesome Group"
+msgid "My awesome group"
msgstr ""
msgid "My company or team"
@@ -24065,9 +24591,6 @@ msgstr ""
msgid "No available branches"
msgstr ""
-msgid "No available groups to fork the project."
-msgstr ""
-
msgid "No branches found"
msgstr "Aucune branche trouvée"
@@ -24278,6 +24801,9 @@ msgstr "Aucun groupe public"
msgid "No ref selected"
msgstr ""
+msgid "No regions configured"
+msgstr ""
+
msgid "No related merge requests found."
msgstr ""
@@ -25082,6 +25608,9 @@ msgstr ""
msgid "Only reCAPTCHA v2 is supported:"
msgstr ""
+msgid "Only required if not using role instance credentials."
+msgstr ""
+
msgid "Only use lowercase letters, numbers, and underscores."
msgstr ""
@@ -25106,9 +25635,6 @@ msgstr ""
msgid "Open a CLI and connect to the cluster you want to install the agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
-msgid "Open epics"
-msgstr ""
-
msgid "Open errors"
msgstr ""
@@ -25148,8 +25674,8 @@ msgstr ""
msgid "Opened issues"
msgstr "Tickets ouverts"
-msgid "OpenedNDaysAgo|Opened"
-msgstr "Ouvert"
+msgid "OpenedNDaysAgo|Created"
+msgstr ""
msgid "Opens in a new window"
msgstr "Ouvrir dans une nouvelle fenêtre"
@@ -25193,9 +25719,6 @@ msgstr ""
msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
-msgid "Optional."
-msgstr ""
-
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
msgstr "Vous pouvez éventuellement %{link_to_customize} la manière dont les adresses de courriel et les noms d’utilisateur issus de FogBugz sont importés dans GitLab."
@@ -25984,6 +26507,9 @@ msgstr ""
msgid "PerformanceBar|Memory"
msgstr ""
+msgid "PerformanceBar|Memory report"
+msgstr ""
+
msgid "PerformanceBar|Redis calls"
msgstr ""
@@ -26017,18 +26543,12 @@ msgstr ""
msgid "PerformanceBar|wall"
msgstr ""
-msgid "Performs a rebase but skips triggering a new pipeline"
-msgstr ""
-
msgid "Period in seconds"
msgstr ""
msgid "Permalink"
msgstr ""
-msgid "Permanently delete project"
-msgstr ""
-
msgid "Permanently remove group"
msgstr ""
@@ -26299,6 +26819,51 @@ msgstr ""
msgid "PipelineStatusTooltip|Pipeline: %{ci_status}"
msgstr ""
+msgid "PipelineWizardDefaultCommitMessage|Add %{filename}"
+msgstr ""
+
+msgid "PipelineWizardDefaultCommitMessage|Update %{filename}"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|At least one entry is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This field is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This value is not valid"
+msgstr ""
+
+msgid "PipelineWizardListWidget|add another step"
+msgstr ""
+
+msgid "PipelineWizardListWidget|remove step"
+msgstr ""
+
+msgid "PipelineWizard|Commit"
+msgstr ""
+
+msgid "PipelineWizard|Commit Message"
+msgstr ""
+
+msgid "PipelineWizard|Commit changes to your file"
+msgstr ""
+
+msgid "PipelineWizard|Commit file to Branch"
+msgstr ""
+
+msgid "PipelineWizard|Commit your new file"
+msgstr ""
+
+msgid "PipelineWizard|The file has been committed."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem committing the changes."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem while checking whether your file already exists in the specified branch."
+msgstr ""
+
msgid "Pipelines"
msgstr "Pipelines"
@@ -26413,7 +26978,7 @@ msgstr ""
msgid "Pipelines|Project cache successfully reset."
msgstr "Réinitialisation du cache de projet réussie."
-msgid "Pipelines|Revoke"
+msgid "Pipelines|Revoke trigger"
msgstr ""
msgid "Pipelines|Something went wrong while cleaning runners cache."
@@ -26458,6 +27023,12 @@ msgstr ""
msgid "Pipelines|This is a child pipeline within the parent pipeline"
msgstr ""
+msgid "Pipelines|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipelines|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipelines|This pipeline will run code originating from a forked project merge request. This means that the code can potentially have security considerations like exposing CI variables."
msgstr ""
@@ -26500,9 +27071,6 @@ msgstr ""
msgid "Pipelines|Your changes have been successfully committed. Now redirecting to the new merge request page."
msgstr ""
-msgid "Pipelines|detached"
-msgstr ""
-
msgid "Pipelines|error"
msgstr ""
@@ -26512,10 +27080,13 @@ msgstr ""
msgid "Pipelines|latest"
msgstr ""
-msgid "Pipelines|stuck"
+msgid "Pipelines|merge request"
msgstr ""
-msgid "Pipelines|train"
+msgid "Pipelines|merge train"
+msgstr ""
+
+msgid "Pipelines|stuck"
msgstr ""
msgid "Pipelines|yaml invalid"
@@ -26647,6 +27218,12 @@ msgstr ""
msgid "Pipeline|This change will not change the overall test coverage if merged."
msgstr ""
+msgid "Pipeline|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipeline|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipeline|Trigger author"
msgstr ""
@@ -26671,6 +27248,12 @@ msgstr ""
msgid "Pipeline|for"
msgstr ""
+msgid "Pipeline|merge request"
+msgstr ""
+
+msgid "Pipeline|merge train"
+msgstr ""
+
msgid "Pipeline|on"
msgstr ""
@@ -26809,9 +27392,6 @@ msgstr ""
msgid "Please enter a valid time interval"
msgstr ""
-msgid "Please enter or upload a valid license."
-msgstr ""
-
msgid "Please enter your current password."
msgstr ""
@@ -26920,9 +27500,6 @@ msgstr ""
msgid "Please type %{phrase_code} to proceed or close this modal to cancel."
msgstr ""
-msgid "Please type the following to confirm:"
-msgstr ""
-
msgid "Please use this form to report to the admin users who create spam issues, comments or behave inappropriately."
msgstr ""
@@ -26950,12 +27527,27 @@ msgstr ""
msgid "Policies"
msgstr ""
+msgid "Policy '%{escalation_policy_name}' does not exist."
+msgstr ""
+
msgid "Policy management project does have any policies in %{policy_path}"
msgstr ""
msgid "Policy project doesn't exist"
msgstr ""
+msgid "PolicyRuleMultiSelect|%{firstLabel} +%{numberOfAdditionalLabels} more"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|All %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select all"
+msgstr ""
+
msgid "Polling interval multiplier"
msgstr ""
@@ -27184,6 +27776,9 @@ msgstr ""
msgid "Private projects can be created in your personal namespace with:"
msgstr "Des projets privés peuvent être créés dans votre espace de noms personnel avec :"
+msgid "Problem with %{name} command: %{message}."
+msgstr ""
+
msgid "Proceed"
msgstr ""
@@ -27658,6 +28253,9 @@ msgstr "Langages de programmation utilisés dans ce dépôt"
msgid "Progress"
msgstr "Progression"
+msgid "Progress tracking"
+msgstr ""
+
msgid "Project"
msgstr "Projet"
@@ -27889,6 +28487,9 @@ msgstr ""
msgid "ProjectQualitySummary|Failure"
msgstr ""
+msgid "ProjectQualitySummary|Get insight into the overall percentage of tests in your project that succeed, fail and are skipped."
+msgstr ""
+
msgid "ProjectQualitySummary|Latest pipeline results"
msgstr ""
@@ -27907,6 +28508,12 @@ msgstr ""
msgid "ProjectQualitySummary|See project Code Coverage Statistics"
msgstr ""
+msgid "ProjectQualitySummary|Set up test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|Set up test runs (opens in a new tab)"
+msgstr ""
+
msgid "ProjectQualitySummary|Skipped"
msgstr ""
@@ -28183,13 +28790,19 @@ msgstr ""
msgid "ProjectSettings|LFS objects from this repository are available to forks. %{linkStart}How do I remove them?%{linkEnd}"
msgstr ""
+msgid "ProjectSettings|Learn about commit history."
+msgstr ""
+
+msgid "ProjectSettings|Leave empty to use default template."
+msgstr ""
+
msgid "ProjectSettings|Manage who can see the project in the public access directory."
msgstr ""
msgid "ProjectSettings|Manages large files such as audio, video, and graphics files."
msgstr ""
-msgid "ProjectSettings|Maximum 500 characters."
+msgid "ProjectSettings|Maximum %{maxLength} characters."
msgstr ""
msgid "ProjectSettings|Merge checks"
@@ -28330,6 +28943,9 @@ msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
msgstr ""
+msgid "ProjectSettings|The default template will be applied on save."
+msgstr ""
+
msgid "ProjectSettings|These checks must pass before merge requests can be merged."
msgstr ""
@@ -28384,6 +29000,9 @@ msgstr ""
msgid "ProjectSettings|What are badges?"
msgstr ""
+msgid "ProjectSettings|What are merge trains?"
+msgstr ""
+
msgid "ProjectSettings|When merge request pipelines are enabled in the CI/CD configuration file, pipelines validate the combined results of the source and target branches. %{link_start}How to configure merge request pipelines?%{link_end}"
msgstr ""
@@ -28501,6 +29120,9 @@ msgstr ""
msgid "Projects are organized into groups"
msgstr ""
+msgid "Projects are where you store your code, access issues, wiki and other features of GitLab."
+msgstr ""
+
msgid "Projects contributed to"
msgstr ""
@@ -28516,12 +29138,6 @@ msgstr ""
msgid "Projects to index"
msgstr ""
-msgid "Projects will be permanently deleted after a %{waiting_period}-day waiting period."
-msgstr ""
-
-msgid "Projects will be permanently deleted immediately."
-msgstr ""
-
msgid "Projects with critical vulnerabilities"
msgstr ""
@@ -28606,6 +29222,9 @@ msgstr ""
msgid "ProjectsNew|Import project"
msgstr ""
+msgid "ProjectsNew|Include a Getting Started README"
+msgstr ""
+
msgid "ProjectsNew|Initialize repository with a README"
msgstr ""
@@ -28621,6 +29240,9 @@ msgstr ""
msgid "ProjectsNew|Project description %{tag_start}(optional)%{tag_end}"
msgstr ""
+msgid "ProjectsNew|Recommended if you're new to GitLab"
+msgstr ""
+
msgid "ProjectsNew|Run CI/CD for external repository"
msgstr ""
@@ -29038,6 +29660,9 @@ msgstr ""
msgid "ProtectedBranch|Unprotect"
msgstr ""
+msgid "ProtectedBranch|Unprotect branch"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
@@ -29065,6 +29690,9 @@ msgstr "Protéger un environnement"
msgid "ProtectedEnvironment|Protected Environment (%{protected_environments_count})"
msgstr "Environnements protégés (%{protected_environments_count})"
+msgid "ProtectedEnvironment|Required approvals"
+msgstr ""
+
msgid "ProtectedEnvironment|Select an environment"
msgstr "Sélectionner un environnement"
@@ -29086,10 +29714,13 @@ msgstr "Votre environnement a été protégé."
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr "Votre environnement a été déprotégé"
+msgid "ProtectedTags|Unprotect tag"
+msgstr ""
+
msgid "ProtectedTags|default"
msgstr ""
-msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
+msgid "ProtectedTag|By default, protected tags restrict who can modify the tag."
msgstr ""
msgid "ProtectedTag|Learn more."
@@ -29152,6 +29783,9 @@ msgstr "Pipelines publics"
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Public projects are an easy way to allow everyone to have read-only access."
+msgstr ""
+
msgid "Publish to status page"
msgstr ""
@@ -29308,9 +29942,6 @@ msgstr ""
msgid "QualitySummary|Project quality"
msgstr ""
-msgid "Quarters"
-msgstr "Trimestres"
-
msgid "Query"
msgstr ""
@@ -29395,6 +30026,9 @@ msgstr ""
msgid "Read more about project permissions %{help_link_open}here%{help_link_close}"
msgstr ""
+msgid "Read more about related epics"
+msgstr ""
+
msgid "Read more about related issues"
msgstr ""
@@ -29425,10 +30059,7 @@ msgstr ""
msgid "Rebase source branch on the target branch."
msgstr ""
-msgid "Rebase without CI"
-msgstr ""
-
-msgid "Rebases and triggers a pipeline"
+msgid "Rebase without pipeline"
msgstr ""
msgid "Recaptcha verified?"
@@ -29479,9 +30110,6 @@ msgstr ""
msgid "Reconfigure"
msgstr ""
-msgid "Recovering projects"
-msgstr ""
-
msgid "Recovery Codes"
msgstr ""
@@ -29541,6 +30169,12 @@ msgstr ""
msgid "Regex pattern"
msgstr "Expression rationnelle"
+msgid "Region"
+msgstr ""
+
+msgid "Regions"
+msgstr ""
+
msgid "Register"
msgstr ""
@@ -29771,9 +30405,6 @@ msgstr ""
msgid "Remove all or specific reviewer(s)"
msgstr ""
-msgid "Remove approver"
-msgstr ""
-
msgid "Remove approvers"
msgstr ""
@@ -29789,6 +30420,9 @@ msgstr ""
msgid "Remove attention request"
msgstr ""
+msgid "Remove attention request(s)"
+msgstr ""
+
msgid "Remove avatar"
msgstr "Supprimer l’avatar"
@@ -29927,6 +30561,9 @@ msgstr ""
msgid "Removed an issue from an epic."
msgstr ""
+msgid "Removed attention from %{users_sentence}."
+msgstr ""
+
msgid "Removed attention request from @%{username}"
msgstr ""
@@ -29978,6 +30615,9 @@ msgstr ""
msgid "Removes an issue from an epic."
msgstr ""
+msgid "Removes attention from %{users_sentence}."
+msgstr ""
+
msgid "Removes parent epic %{epic_ref}."
msgstr ""
@@ -30089,6 +30729,9 @@ msgstr ""
msgid "Report abuse to admin"
msgstr ""
+msgid "Report is generating and will be sent to your email address."
+msgstr ""
+
msgid "Reported %{timeAgo} by %{reportedBy}"
msgstr ""
@@ -30378,6 +31021,15 @@ msgstr ""
msgid "Request attention"
msgstr ""
+msgid "Request attention from %{users_sentence}."
+msgstr ""
+
+msgid "Request attention from assignee or reviewer"
+msgstr ""
+
+msgid "Request attention from assignee(s) or reviewer(s)"
+msgstr ""
+
msgid "Request attention to review"
msgstr ""
@@ -30402,6 +31054,9 @@ msgstr ""
msgid "Requested %{time_ago}"
msgstr ""
+msgid "Requested attention from %{users_sentence}."
+msgstr ""
+
msgid "Requested attention from @%{username}"
msgstr ""
@@ -30616,6 +31271,9 @@ msgstr ""
msgid "Restore project"
msgstr ""
+msgid "Restoring projects"
+msgstr ""
+
msgid "Restoring the group will prevent the group, its subgroups and projects from being removed on this date."
msgstr ""
@@ -30646,6 +31304,9 @@ msgstr ""
msgid "Retry"
msgstr "Réessayer"
+msgid "Retry failed jobs"
+msgstr ""
+
msgid "Retry job"
msgstr ""
@@ -30693,9 +31354,6 @@ msgstr ""
msgid "Review changes"
msgstr ""
-msgid "Review requested from %{name}"
-msgstr ""
-
msgid "Review requests for you"
msgstr ""
@@ -30860,6 +31518,9 @@ msgstr ""
msgid "Runners|Assigned Group"
msgstr ""
+msgid "Runners|Assigned Projects (%{projectCount})"
+msgstr ""
+
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30929,6 +31590,9 @@ msgstr ""
msgid "Runners|Instance"
msgstr ""
+msgid "Runners|Jobs"
+msgstr ""
+
msgid "Runners|Last contact"
msgstr ""
@@ -31022,9 +31686,6 @@ msgstr ""
msgid "Runners|Runner %{name} was deleted"
msgstr ""
-msgid "Runners|Runner ID"
-msgstr ""
-
msgid "Runners|Runner assigned to project."
msgstr ""
@@ -31172,6 +31833,9 @@ msgstr ""
msgid "Runners|stale"
msgstr ""
+msgid "Runner|This runner has not run any jobs."
+msgstr ""
+
msgid "Running"
msgstr "En cours d’exécution"
@@ -31286,6 +31950,24 @@ msgstr ""
msgid "Saving project."
msgstr ""
+msgid "ScanResultPolicy|%{ifLabelStart}if%{ifLabelEnd} %{scanners} scan in an open merge request targeting the %{branches} branch(es) finds %{vulnerabilitiesAllowed} or more %{severities} vulnerabilities that are %{vulnerabilityStates}"
+msgstr ""
+
+msgid "ScanResultPolicy|%{thenLabelStart}Then%{thenLabelEnd} Require approval from %{approvalsRequired} of the following approvers: %{approvers}"
+msgstr ""
+
+msgid "ScanResultPolicy|add an approver"
+msgstr ""
+
+msgid "ScanResultPolicy|scanners"
+msgstr ""
+
+msgid "ScanResultPolicy|severity levels"
+msgstr ""
+
+msgid "ScanResultPolicy|vulnerability states"
+msgstr ""
+
msgid "Scanner"
msgstr ""
@@ -31418,6 +32100,9 @@ msgstr ""
msgid "Search for a user"
msgstr ""
+msgid "Search for an emoji"
+msgstr ""
+
msgid "Search for projects, issues, etc."
msgstr "Rechercher des projets, des tickets, etc."
@@ -31605,18 +32290,12 @@ msgstr "Secret"
msgid "Secret Detection"
msgstr ""
-msgid "Secret access key"
-msgstr ""
-
msgid "Secret token"
msgstr ""
msgid "Secure token that identifies an external storage request."
msgstr ""
-msgid "SecureCodeWarrior"
-msgstr ""
-
msgid "Security"
msgstr "Sécurité"
@@ -31641,9 +32320,6 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "Security training with guide and learning pathways."
-msgstr ""
-
msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
@@ -31746,7 +32422,7 @@ msgstr ""
msgid "SecurityConfiguration|Manage corpus"
msgstr ""
-msgid "SecurityConfiguration|Manage corpus files used as mutation sources in coverage fuzzing."
+msgid "SecurityConfiguration|Manage corpus files used as seed inputs with coverage-guided fuzzing."
msgstr ""
msgid "SecurityConfiguration|Manage profiles for use by DAST scans."
@@ -31812,15 +32488,15 @@ msgstr ""
msgid "SecurityOrchestration|.yaml preview"
msgstr ""
-msgid "SecurityOrchestration|Action"
-msgstr ""
-
msgid "SecurityOrchestration|Actions"
msgstr ""
msgid "SecurityOrchestration|Add rule"
msgstr ""
+msgid "SecurityOrchestration|After dismissing the alert, the information will never be shown again."
+msgstr ""
+
msgid "SecurityOrchestration|All policies"
msgstr ""
@@ -31836,7 +32512,7 @@ msgstr ""
msgid "SecurityOrchestration|Description"
msgstr ""
-msgid "SecurityOrchestration|Disabled"
+msgid "SecurityOrchestration|Don't show the alert anymore"
msgstr ""
msgid "SecurityOrchestration|Edit policy"
@@ -31845,13 +32521,13 @@ msgstr ""
msgid "SecurityOrchestration|Edit policy project"
msgstr ""
-msgid "SecurityOrchestration|Enabled"
+msgid "SecurityOrchestration|Empty policy name"
msgstr ""
-msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Enabled"
msgstr ""
-msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
msgstr ""
msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
@@ -31860,7 +32536,7 @@ msgstr ""
msgid "SecurityOrchestration|Invalid policy type"
msgstr ""
-msgid "SecurityOrchestration|Latest scan"
+msgid "SecurityOrchestration|Latest scan run against %{agent}"
msgstr ""
msgid "SecurityOrchestration|Network"
@@ -31869,15 +32545,27 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No actions defined - policy will not run."
+msgstr ""
+
+msgid "SecurityOrchestration|No description"
+msgstr ""
+
msgid "SecurityOrchestration|No rules defined - policy will not run."
msgstr ""
+msgid "SecurityOrchestration|Not enabled"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
msgid "SecurityOrchestration|Policies"
msgstr ""
+msgid "SecurityOrchestration|Policy Type"
+msgstr ""
+
msgid "SecurityOrchestration|Policy cannot be enabled for non-existing branches (%{branches})"
msgstr ""
@@ -31902,10 +32590,13 @@ msgstr ""
msgid "SecurityOrchestration|Require %{approvals} %{plural} from %{approvers} if any of the following occur:"
msgstr ""
-msgid "SecurityOrchestration|Rule"
+msgid "SecurityOrchestration|Rules"
msgstr ""
-msgid "SecurityOrchestration|Rules"
+msgid "SecurityOrchestration|Runs %{actions} and %{lastAction} scans"
+msgstr ""
+
+msgid "SecurityOrchestration|Runs a %{action} scan"
msgstr ""
msgid "SecurityOrchestration|Scan Execution"
@@ -31965,6 +32656,9 @@ msgstr ""
msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
+msgid "SecurityOrchestration|This view only shows scan results for the agent %{agent}. You can view scan results for all agents in the %{linkStart}Operational Vulnerabilities tab of the vulnerability report%{linkEnd}."
+msgstr ""
+
msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
@@ -32019,9 +32713,6 @@ msgstr ""
msgid "SecurityOrchestration|users with ids"
msgstr ""
-msgid "SecurityOrchestration|view results"
-msgstr ""
-
msgid "SecurityOrchestration|vulnerabilities"
msgstr ""
@@ -32691,22 +33382,19 @@ 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|In order to start using functions as a service, you must first install Knative on your Kubernetes cluster. %{linkStart}More information%{linkEnd}"
-msgstr ""
-
msgid "Serverless|Learn more about Serverless"
msgstr ""
msgid "Serverless|No functions available"
msgstr ""
-msgid "Serverless|Sign up for First Look"
+msgid "Serverless|Serverless was %{linkStart}deprecated%{linkEnd} in GitLab 14.3."
+msgstr ""
+
+msgid "Serverless|Serverless was %{postLinkStart}deprecated%{postLinkEnd}. But if you opt to use it, you must install Knative in your Kubernetes cluster first. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "Serverless|The deploy job has not finished."
@@ -32718,9 +33406,6 @@ 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 ""
@@ -32736,9 +33421,6 @@ msgstr ""
msgid "Service Account Key"
msgstr ""
-msgid "Service Accounts"
-msgstr ""
-
msgid "Service Accounts keys authorize GitLab to deploy your Google Cloud project"
msgstr ""
@@ -32748,10 +33430,10 @@ msgstr "Service d’assistance"
msgid "Service Desk allows people to create issues in your GitLab instance without their own user account. It provides a unique email address for end users to create issues in a project. Replies can be sent either through the GitLab interface or by email. End users only see threads through email."
msgstr ""
-msgid "Service Usage Data"
+msgid "Service account generated successfully"
msgstr ""
-msgid "Service account generated successfully"
+msgid "Service accounts"
msgstr ""
msgid "Service ping is disabled in your configuration file, and cannot be enabled through this form."
@@ -32895,6 +33577,9 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
+msgid "Set the per-user rate limit for getting a user by ID via the API."
+msgstr ""
+
msgid "Set the per-user rate limit for notes created by web or API requests."
msgstr ""
@@ -33074,6 +33759,9 @@ msgstr ""
msgid "Shared runners details"
msgstr ""
+msgid "Shared runners enabled cannot be enabled until a valid credit card is on file"
+msgstr ""
+
msgid "Shared runners help link"
msgstr ""
@@ -33131,6 +33819,9 @@ msgstr ""
msgid "Show all issues."
msgstr ""
+msgid "Show all milestones"
+msgstr ""
+
msgid "Show all test cases."
msgstr ""
@@ -33167,6 +33858,9 @@ msgstr ""
msgid "Show file contents"
msgstr ""
+msgid "Show group milestones"
+msgstr ""
+
msgid "Show labels"
msgstr ""
@@ -33182,6 +33876,12 @@ msgstr ""
msgid "Show open epics"
msgstr ""
+msgid "Show project milestones"
+msgstr ""
+
+msgid "Show sub-group milestones"
+msgstr ""
+
msgid "Show the Closed list"
msgstr ""
@@ -33191,11 +33891,6 @@ msgstr ""
msgid "Show whitespace changes"
msgstr "Afficher les modifications des espaces"
-msgid "Showing %d event"
-msgid_plural "Showing %d events"
-msgstr[0] "Affichage de %d évènement"
-msgstr[1] "Affichage de %d événements"
-
msgid "Showing %{conflict} between %{sourceBranch} and %{targetBranch}"
msgstr ""
@@ -33255,12 +33950,6 @@ msgstr ""
msgid "Sidebar|None"
msgstr ""
-msgid "Sidebar|Only numeral characters allowed"
-msgstr "Seuls les caractères numériques sont autorisés"
-
-msgid "Sidebar|Weight"
-msgstr "Poids"
-
msgid "Sidekiq job compression threshold (bytes)"
msgstr ""
@@ -33423,6 +34112,9 @@ msgstr "L’intégration de Slack permet d’interagir avec GitLab via des comma
msgid "Slack logo"
msgstr ""
+msgid "SlackIntegration|Are you sure you want to remove this project from the Slack application?"
+msgstr ""
+
msgid "SlackIntegration|GitLab for Slack"
msgstr ""
@@ -33432,6 +34124,9 @@ msgstr ""
msgid "SlackIntegration|Project alias"
msgstr ""
+msgid "SlackIntegration|Remove project"
+msgstr ""
+
msgid "SlackIntegration|Select a GitLab project to link with your Slack workspace."
msgstr ""
@@ -33576,9 +34271,6 @@ msgstr "Une erreur est survenue lors de la tentative de modification de l’éta
msgid "Something went wrong trying to load issue contacts."
msgstr ""
-msgid "Something went wrong when creating a work item. Please try again"
-msgstr ""
-
msgid "Something went wrong when reordering designs. Please try again"
msgstr ""
@@ -33672,9 +34364,6 @@ msgstr ""
msgid "Something went wrong while inserting your image. Please try again."
msgstr ""
-msgid "Something went wrong while merging this merge request. Please try again."
-msgstr ""
-
msgid "Something went wrong while obtaining the Let's Encrypt certificate."
msgstr ""
@@ -33996,10 +34685,10 @@ 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."
+msgid "SourcegraphAdmin|Learn more."
msgstr ""
-msgid "SourcegraphAdmin|More information"
+msgid "SourcegraphAdmin|Only public projects have code intelligence enabled and communicate with Sourcegraph."
msgstr ""
msgid "SourcegraphAdmin|Save changes"
@@ -34008,7 +34697,7 @@ msgstr ""
msgid "SourcegraphAdmin|Sourcegraph URL"
msgstr ""
-msgid "SourcegraphAdmin|e.g. https://sourcegraph.example.com"
+msgid "SourcegraphAdmin|https://sourcegraph.example.com"
msgstr ""
msgid "SourcegraphPreferences|This feature is experimental and currently limited to certain projects."
@@ -34143,6 +34832,9 @@ msgstr ""
msgid "Start date"
msgstr "Date de début"
+msgid "Start free trial"
+msgstr ""
+
msgid "Start merge train"
msgstr ""
@@ -34173,6 +34865,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started escalation for this incident."
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -34185,6 +34880,9 @@ msgstr ""
msgid "Starts at (UTC)"
msgstr "Démarre à (UTC)"
+msgid "Starts escalations for this incident"
+msgstr ""
+
msgid "Starts on"
msgstr ""
@@ -34446,6 +35144,9 @@ msgstr ""
msgid "Strikethrough"
msgstr ""
+msgid "Strikethrough text"
+msgstr ""
+
msgid "Subgroup information"
msgstr ""
@@ -34680,6 +35381,21 @@ msgstr ""
msgid "Subscriptions"
msgstr ""
+msgid "Subscriptions|Chat with sales"
+msgstr ""
+
+msgid "Subscriptions|Close"
+msgstr ""
+
+msgid "Subscriptions|Not ready to buy yet?"
+msgstr ""
+
+msgid "Subscriptions|Start a free trial"
+msgstr ""
+
+msgid "Subscriptions|We understand. Maybe you have some questions for our sales team, or maybe you'd like to try some of the paid features first. What would you like to do?"
+msgstr ""
+
msgid "Subscription|Your subscription for %{strong}%{namespace_name}%{strong_close} has expired and you are now on %{pricing_link_start}the GitLab Free tier%{pricing_link_end}. Don't worry, your data is safe. Get in touch with our support team (%{support_email}). They'll gladly help with your subscription renewal."
msgstr ""
@@ -34890,6 +35606,9 @@ msgstr ""
msgid "SuperSonics|Maximum users"
msgstr ""
+msgid "SuperSonics|Offline cloud"
+msgstr ""
+
msgid "SuperSonics|Paste your activation code"
msgstr ""
@@ -34956,6 +35675,12 @@ msgstr ""
msgid "SuperSonics|You do not have an active subscription"
msgstr ""
+msgid "SuperSonics|You have a future dated license"
+msgstr ""
+
+msgid "SuperSonics|You have added a license that activates on %{date}. Please see the subscription history table below for more details."
+msgstr ""
+
msgid "SuperSonics|You have successfully added a license that activates on %{date}. Please see the subscription history table below for more details."
msgstr ""
@@ -35115,6 +35840,9 @@ msgstr ""
msgid "Tag name is required"
msgstr ""
+msgid "Tag push"
+msgstr ""
+
msgid "Tag push events"
msgstr ""
@@ -35217,6 +35945,9 @@ msgstr "Rédigez vos notes de version ou faites glisser des fichiers ici…"
msgid "TagsPage|protected"
msgstr "protégé"
+msgid "Take a look at the documentation to discover all of GitLab’s capabilities."
+msgstr ""
+
msgid "Target Branch"
msgstr "Branche cible"
@@ -35619,6 +36350,9 @@ msgstr ""
msgid "Tests"
msgstr ""
+msgid "Text (optional)"
+msgstr ""
+
msgid "Text added to the body of all email messages. %{character_limit} character limit"
msgstr ""
@@ -35669,6 +36403,9 @@ msgstr ""
msgid "The CSV export will be created in the background. Once finished, it will be sent to %{email} in an attachment."
msgstr ""
+msgid "The CSV export you requested of all user memberships is attached to this email."
+msgstr ""
+
msgid "The GitLab subscription service (customers.gitlab.com) is currently experiencing an outage. You can monitor the status and get updates at %{linkStart}status.gitlab.com%{linkEnd}."
msgstr ""
@@ -35744,6 +36481,9 @@ 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 epic"
+msgstr ""
+
msgid "The current issue"
msgstr ""
@@ -35905,6 +36645,9 @@ msgstr ""
msgid "The latest pipeline for this merge request has failed."
msgstr ""
+msgid "The license key is invalid."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -35920,6 +36663,9 @@ msgstr ""
msgid "The license was successfully uploaded and will be active from %{starts_at}. You can see the details below."
msgstr ""
+msgid "The license you uploaded is invalid. If the issue persists, contact support at %{link}."
+msgstr ""
+
msgid "The list creation wizard is already open"
msgstr ""
@@ -36541,10 +37287,13 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} and everything this project contains. %{strongOpen}There is no going back%{strongClose}"
+msgstr ""
+
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains."
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}on %{date}%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains. %{strongOpen}There is no going back.%{strongClose}"
msgstr ""
msgid "This action will %{strongOpen}permanently remove%{strongClose} %{codeOpen}%{group}%{codeClose} %{strongOpen}immediately%{strongClose}."
@@ -36673,9 +37422,6 @@ msgstr ""
msgid "This file was modified for readability, and can't accept suggestions. Edit it directly."
msgstr ""
-msgid "This forked project has the following:"
-msgstr ""
-
msgid "This form is disabled in preview"
msgstr ""
@@ -36688,7 +37434,7 @@ msgstr ""
msgid "This group can't be removed because it is linked to a subscription. To remove this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
-msgid "This group can't be transfered because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
+msgid "This group can't be transferred because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
msgid "This group cannot be invited to a project inside a group with enforced SSO"
@@ -36715,6 +37461,9 @@ 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 incident is already escalated with '%{escalation_policy_name}'."
+msgstr ""
+
msgid "This invitation was sent to %{mail_to_invite_email}, but you are signed in as %{link_to_current_user} with email %{mail_to_current_user}."
msgstr ""
@@ -36733,9 +37482,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 merge train pipeline"
-msgstr ""
-
msgid "This is a private email address %{helpIcon} generated just for you. Anyone who has it can create issues or merge requests as if they were you. If that happens, %{resetLinkStart}reset this token%{resetLinkEnd}."
msgstr ""
@@ -36757,6 +37503,12 @@ msgstr ""
msgid "This is your current session"
msgstr ""
+msgid "This issue cannot be assigned to a confidential epic because it is public."
+msgstr ""
+
+msgid "This issue cannot be made public because it belongs to a confidential epic."
+msgstr ""
+
msgid "This issue is confidential and should only be visible to team members with at least Reporter access."
msgstr ""
@@ -36874,6 +37626,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 branch is protected from force push."
+msgstr ""
+
msgid "This merge request cannot be rebased while there are conflicts."
msgstr ""
@@ -36925,9 +37680,15 @@ msgstr ""
msgid "This pipeline was triggered by a schedule."
msgstr ""
+msgid "This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project"
msgstr "Ce projet"
+msgid "This project can be restored until %{date}."
+msgstr ""
+
msgid "This project cannot be %{visibilityLevel} because the visibility of %{openShowLink}%{name}%{closeShowLink} is %{visibility}. To make this project %{visibilityLevel}, you must first %{openEditLink}change the visibility%{closeEditLink} of the parent group."
msgstr ""
@@ -36946,6 +37707,9 @@ msgstr ""
msgid "This project is %{strongStart}NOT%{strongEnd} a fork, and has the following:"
msgstr ""
+msgid "This project is %{strongStart}NOT%{strongEnd} a fork. This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -37637,6 +38401,9 @@ msgstr ""
msgid "Today"
msgstr "Aujourd’hui"
+msgid "Todos count"
+msgstr ""
+
msgid "Todos|Are you looking for things to do? Take a look at %{strongStart}%{openIssuesLinkStart}open issues%{openIssuesLinkEnd}%{strongEnd}, contribute to %{strongStart}%{mergeRequestLinkStart}a merge request%{mergeRequestLinkEnd}%{mergeRequestLinkEnd}%{strongEnd}, or mention someone in a comment to automatically assign them a new to-do item."
msgstr ""
@@ -37910,10 +38677,8 @@ msgstr "Vue arborescente"
msgid "Trending"
msgstr "Tendance"
-msgid "Trials|%{planName} Trial %{enDash} %{num} day left"
-msgid_plural "Trials|%{planName} Trial %{enDash} %{num} days left"
-msgstr[0] ""
-msgstr[1] ""
+msgid "Trials|%{planName} Trial"
+msgstr ""
msgid "Trials|Compare all plans"
msgstr ""
@@ -37921,6 +38686,9 @@ msgstr ""
msgid "Trials|Create a new group to start your GitLab Ultimate trial."
msgstr ""
+msgid "Trials|Day %{daysUsed}/%{duration}"
+msgstr ""
+
msgid "Trials|Go back to GitLab"
msgstr ""
@@ -38170,7 +38938,7 @@ msgstr ""
msgid "URL is triggered when repository is updated"
msgstr ""
-msgid "URL must be percent-encoded if neccessary."
+msgid "URL must be percent-encoded if necessary."
msgstr ""
msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
@@ -38389,6 +39157,9 @@ msgstr "Déverrouiller"
msgid "Unlock account"
msgstr ""
+msgid "Unlock more features with GitLab Ultimate"
+msgstr ""
+
msgid "Unlock the discussion"
msgstr ""
@@ -38452,6 +39223,9 @@ msgstr ""
msgid "Unsubscribes from this %{quick_action_target}."
msgstr ""
+msgid "Unsupported sort value."
+msgstr ""
+
msgid "Unsupported todo type passed. Supported todo types are: %{todo_types}"
msgstr ""
@@ -38680,6 +39454,9 @@ msgstr ""
msgid "UsageQuota|File attachments and smaller design graphics."
msgstr ""
+msgid "UsageQuota|From %{storage_enforcement_date} storage limits will apply to this namespace. View and manage your usage in %{strong_start}Group Settings &gt; Usage quotas%{strong_end}."
+msgstr ""
+
msgid "UsageQuota|Git repository."
msgstr ""
@@ -38740,6 +39517,9 @@ msgstr ""
msgid "UsageQuota|Storage type"
msgstr ""
+msgid "UsageQuota|Storage used"
+msgstr ""
+
msgid "UsageQuota|This is the total amount of storage used across your projects within this namespace."
msgstr ""
@@ -38935,6 +39715,12 @@ msgstr ""
msgid "Use hashed storage paths for newly created and renamed repositories. Always enabled since 13.0."
msgstr ""
+msgid "Use issue count"
+msgstr ""
+
+msgid "Use issue weight"
+msgstr ""
+
msgid "Use one line per URI"
msgstr "Utilisez une ligne par URI"
@@ -39316,6 +40102,9 @@ msgstr ""
msgid "Users"
msgstr "Utilisateurs et utilisatrices"
+msgid "Users API rate limit"
+msgstr ""
+
msgid "Users can launch a development environment from a GitLab browser tab when the %{linkStart}Gitpod%{linkEnd} integration is enabled."
msgstr ""
@@ -39641,6 +40430,9 @@ msgstr ""
msgid "View group labels"
msgstr "Afficher les labels de groupe"
+msgid "View group pipeline usage quota"
+msgstr ""
+
msgid "View incident details at"
msgstr ""
@@ -39793,6 +40585,9 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
+msgid "Vulnerability"
+msgstr ""
+
msgid "Vulnerability Report"
msgstr ""
@@ -39844,6 +40639,9 @@ msgstr ""
msgid "VulnerabilityManagement|An unverified non-confirmed finding"
msgstr ""
+msgid "VulnerabilityManagement|At least one identifier is required"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -39853,12 +40651,24 @@ msgstr ""
msgid "VulnerabilityManagement|Create Jira issue"
msgstr ""
+msgid "VulnerabilityManagement|Enter a name"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE code"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE identifier URL"
+msgstr ""
+
msgid "VulnerabilityManagement|Fetching linked Jira issues"
msgstr ""
msgid "VulnerabilityManagement|Manually add a vulnerability entry into the vulnerability report."
msgstr ""
+msgid "VulnerabilityManagement|Name is a required field"
+msgstr ""
+
msgid "VulnerabilityManagement|Needs triage"
msgstr ""
@@ -39874,6 +40684,18 @@ msgstr ""
msgid "VulnerabilityManagement|Select a method"
msgstr ""
+msgid "VulnerabilityManagement|Select a severity level"
+msgstr ""
+
+msgid "VulnerabilityManagement|Select a status"
+msgstr ""
+
+msgid "VulnerabilityManagement|Severity is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Something went wrong while creating vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -39898,6 +40720,12 @@ msgstr ""
msgid "VulnerabilityManagement|Something went wrong, could not update vulnerability state."
msgstr ""
+msgid "VulnerabilityManagement|Status is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Submit vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Summary, detailed description, steps to reproduce, etc."
msgstr ""
@@ -40093,6 +40921,9 @@ msgstr ""
msgid "WARNING:"
msgstr ""
+msgid "WARNING: This snippet contains hidden files which might be used to mask malicious behavior. Exercise caution if cloning and executing code from this snippet."
+msgstr ""
+
msgid "Wait for the file to load to copy its contents"
msgstr ""
@@ -40312,6 +41143,15 @@ msgstr ""
msgid "Webhooks|An issue is created, updated, closed, or reopened."
msgstr ""
+msgid "Webhooks|Are you sure you want to delete this group hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this project hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this webhook?"
+msgstr ""
+
msgid "Webhooks|Comments"
msgstr ""
@@ -40321,6 +41161,9 @@ msgstr ""
msgid "Webhooks|Confidential issues events"
msgstr ""
+msgid "Webhooks|Delete webhook"
+msgstr ""
+
msgid "Webhooks|Deployment events"
msgstr ""
@@ -40554,6 +41397,9 @@ msgstr ""
msgid "Wiki"
msgstr "Wiki"
+msgid "Wiki page"
+msgstr ""
+
msgid "Wiki page was successfully created."
msgstr ""
@@ -40659,7 +41505,7 @@ msgstr "Supprimer la page %{pageTitle} ?"
msgid "WikiPageConflictMessage|Someone edited the page the same time you did. Please check out %{wikiLinkStart}the page%{wikiLinkEnd} and make sure your changes will not unintentionally remove theirs."
msgstr ""
-msgid "WikiPage|An error occured while trying to render the content editor. Please try again later."
+msgid "WikiPage|An error occurred while trying to render the content editor. Please try again later."
msgstr ""
msgid "WikiPage|Are you sure you want to switch back to the classic editor?"
@@ -40818,6 +41664,18 @@ msgstr ""
msgid "WorkItem|New Task"
msgstr ""
+msgid "WorkItem|Something went wrong when creating a work item. Please try again"
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching the work item. Please try again."
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching work item types. Please try again"
+msgstr ""
+
+msgid "WorkItem|Type"
+msgstr ""
+
msgid "WorkItem|Work Items"
msgstr ""
@@ -40884,7 +41742,10 @@ msgstr ""
msgid "You are about to add %{usersTag} people to the discussion. They will all receive a notification."
msgstr ""
-msgid "You are about to permanently delete this project"
+msgid "You are about to delete this forked project containing:"
+msgstr ""
+
+msgid "You are about to delete this project containing:"
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."
@@ -40905,6 +41766,9 @@ msgstr ""
msgid "You are attempting to update a file that has changed since you started editing it."
msgstr ""
+msgid "You are billed if you exceed this number. %{qsrOverageLinkStart}How does billing work?%{qsrOverageLinkEnd}"
+msgstr ""
+
msgid "You are connected to the Prometheus server, but there is currently no data to display."
msgstr ""
@@ -40962,6 +41826,9 @@ msgstr ""
msgid "You are not authorized to update this scanner profile"
msgstr ""
+msgid "You are not authorized to upload metric images"
+msgstr ""
+
msgid "You are now impersonating %{username}"
msgstr ""
@@ -41115,9 +41982,6 @@ msgstr ""
msgid "You can only upload one design when dropping onto an existing design."
msgstr ""
-msgid "You can recover this project until %{date}"
-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 "Vous pouvez résoudre le conflit de fusion Git soit en mode interactif, en cliquant sur les boutons « %{use_ours} » ou « %{use_theirs} », soit en modifiant directement les fichiers. Valider ces modifications dans la branche « %{branch_name} »"
@@ -41166,9 +42030,6 @@ msgstr "Vous ne pouvez pas écrire sur une instance GitLab Geo secondaire en le
msgid "You cannot write to this read-only GitLab instance."
msgstr "Vous ne pouvez pas écrire sur cette instance GitLab en lecture seule."
-msgid "You can’t %{tag_start}edit%{tag_end} files directly in this project. Fork this project and submit a merge request with your changes."
-msgstr ""
-
msgid "You can’t edit files directly in this project. Fork this project and submit a merge request with your changes."
msgstr ""
@@ -41321,9 +42182,6 @@ msgstr "Vous n’avez pas les autorisations"
msgid "You have not added any approvers. Start by adding users or groups."
msgstr ""
-msgid "You have reached your project limit"
-msgstr "Vous avez atteint votre limite de projet"
-
msgid "You have set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
@@ -41354,12 +42212,6 @@ msgstr ""
msgid "You must have maintainer access to force delete a lock"
msgstr "Seul un responsable peut forcer la suppression d’un verrou"
-msgid "You must have permission to create a project in a group before forking."
-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 ""
@@ -41765,7 +42617,7 @@ msgstr "Vos projets"
msgid "Your public email will be displayed on your public profile."
msgstr ""
-msgid "Your request for access could not be processed: %{error_meesage}"
+msgid "Your request for access could not be processed: %{error_message}"
msgstr ""
msgid "Your request for access has been queued for review."
@@ -41948,6 +42800,9 @@ msgstr ""
msgid "archived:"
msgstr ""
+msgid "artifacts"
+msgstr ""
+
msgid "assign yourself"
msgstr ""
@@ -41977,6 +42832,9 @@ msgstr[1] ""
msgid "branch name"
msgstr "nom de la branche"
+msgid "builds"
+msgstr ""
+
msgid "by"
msgstr "par"
@@ -42400,6 +43258,9 @@ msgstr ""
msgid "contact with same email already exists in group hierarchy"
msgstr ""
+msgid "container registry images"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -42439,6 +43300,9 @@ msgstr ""
msgid "data"
msgstr ""
+msgid "database"
+msgstr ""
+
msgid "date must not be after 9999-12-31"
msgstr ""
@@ -42462,9 +43326,6 @@ msgstr ""
msgid "design"
msgstr ""
-msgid "detached"
-msgstr ""
-
msgid "disabled"
msgstr "désactivé"
@@ -42713,7 +43574,7 @@ msgstr ""
msgid "is not a valid X509 certificate."
msgstr "n’est pas un certificat X.509 valide."
-msgid "is not allowed for sign-up."
+msgid "is not allowed for sign-up. Please use your regular email address."
msgstr ""
msgid "is not allowed for this group."
@@ -42725,7 +43586,7 @@ msgstr ""
msgid "is not allowed since the group is not top-level group."
msgstr ""
-msgid "is not allowed."
+msgid "is not allowed. Please use your regular email address."
msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
@@ -42812,6 +43673,9 @@ msgstr ""
msgid "level: %{level}"
msgstr ""
+msgid "lfs objects"
+msgstr ""
+
msgid "limit of %{project_limit} reached"
msgstr ""
@@ -43031,6 +43895,9 @@ msgstr ""
msgid "mrWidget|Merge blocked: pipeline must succeed. It's waiting for a manual action to continue."
msgstr ""
+msgid "mrWidget|Merge blocked: pipeline must succeed. Push a commit that fixes the failure, or %{linkStart}learn about other solutions.%{linkEnd}"
+msgstr ""
+
msgid "mrWidget|Merge blocked: this merge request must be approved."
msgstr ""
@@ -43148,9 +44015,6 @@ msgstr "Les modifications ont été fusionnées dans"
msgid "mrWidget|The changes were not merged into"
msgstr "Les modifications n’ont pas été fusionnées dans"
-msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -43298,9 +44162,6 @@ msgstr ""
msgid "open issue"
msgstr ""
-msgid "opened %{timeAgo}"
-msgstr ""
-
msgid "or"
msgstr ""
@@ -43312,6 +44173,12 @@ msgid_plural "out of %d total tests"
msgstr[0] "sur un total de %d test"
msgstr[1] "sur un total de %d tests"
+msgid "packages"
+msgstr ""
+
+msgid "pages"
+msgstr ""
+
msgid "parent"
msgid_plural "parents"
msgstr[0] "parent"
@@ -43461,6 +44328,9 @@ msgid_plural "replies"
msgstr[0] "réponse"
msgstr[1] "réponses"
+msgid "repositories"
+msgstr ""
+
msgid "repository:"
msgstr ""
@@ -43581,12 +44451,18 @@ msgstr ""
msgid "tag name"
msgstr ""
+msgid "terraform states"
+msgstr ""
+
msgid "the correct format."
msgstr ""
msgid "the file"
msgstr ""
+msgid "the following epic(s)"
+msgstr ""
+
msgid "the following issue(s)"
msgstr ""
@@ -43599,21 +44475,12 @@ msgstr ""
msgid "this document"
msgstr "ce document"
-msgid "this issue cannot be assigned to a confidential epic since it is public"
-msgstr ""
-
-msgid "this issue cannot be made public since it belongs to a confidential epic"
-msgstr ""
-
msgid "time summary"
msgstr ""
msgid "toggle collapse"
msgstr ""
-msgid "train"
-msgstr ""
-
msgid "triggered"
msgstr ""
@@ -43742,3 +44609,6 @@ msgstr ""
msgid "{project}"
msgstr ""
+msgid "✔"
+msgstr ""
+
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 6cdc5ba18e2..e8075deb16c 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -28,15 +28,9 @@ msgstr ""
msgid " Please sign in."
msgstr ""
-msgid " Target Path"
-msgstr ""
-
msgid " Try to %{action} this file again."
msgstr ""
-msgid " Type"
-msgstr ""
-
msgid " You need to do this before %{grace_period_deadline}."
msgstr ""
@@ -356,6 +350,11 @@ msgid_plural "%d personal projects will be removed and cannot be restored."
msgstr[0] ""
msgstr[1] ""
+msgid "%d point"
+msgid_plural "%d points"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d previously merged commit"
msgid_plural "%d previously merged commits"
msgstr[0] ""
@@ -371,11 +370,6 @@ msgid_plural "%d projects selected"
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] ""
@@ -468,9 +462,6 @@ msgstr ""
msgid "%{address} is an invalid IP address range"
msgstr ""
-msgid "%{anchorOpen}Learn more%{anchorClose} about how you can customize / disable registration on your instance."
-msgstr ""
-
msgid "%{author_link} cloned %{original_issue} to %{new_issue}."
msgstr ""
@@ -663,6 +654,9 @@ msgstr ""
msgid "%{firstMilestoneName} + %{numberOfOtherMilestones} more"
msgstr ""
+msgid "%{from_address} (reply to: %{reply_to_address})"
+msgstr ""
+
msgid "%{gitlab_experience_text}. Don't worry, this information isn't shared outside of your self-managed GitLab instance."
msgstr ""
@@ -702,6 +696,9 @@ msgstr ""
msgid "%{issuableType} will be removed! Are you sure?"
msgstr ""
+msgid "%{issuable}(s) already assigned"
+msgstr ""
+
msgid "%{issueType} actions"
msgstr ""
@@ -780,7 +777,7 @@ msgstr ""
msgid "%{linkStart}Learn more.%{linkEnd}"
msgstr ""
-msgid "%{link_start}Learn more%{link_end} about roles."
+msgid "%{link_start}Add a license%{link_end} that you have received from GitLab Inc."
msgstr ""
msgid "%{link_start}Remove the %{draft_snippet} prefix%{link_end} from the title to allow this merge request to be merged when it's ready."
@@ -789,9 +786,6 @@ msgstr ""
msgid "%{link_start}Start the title with %{draft_snippet}%{link_end} to prevent a merge request draft from merging before it's ready."
msgstr ""
-msgid "%{link_start}Upload a license%{link_end} file or enter the license key you have received from GitLab Inc."
-msgstr ""
-
msgid "%{link_start}What information does GitLab Inc. collect?%{link_end}"
msgstr ""
@@ -992,10 +986,18 @@ msgstr ""
msgid "%{start} to %{end}"
msgstr ""
+msgid "%{strongOpen}%{errors}%{strongClose} point"
+msgid_plural "%{strongOpen}%{errors}%{strongClose} points"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%{strongOpen}Warning:%{strongClose} SAML group links can cause GitLab to automatically remove members from groups."
msgstr ""
-msgid "%{strongStart}Tip:%{strongEnd} You can also checkout merge requests locally by %{linkStart}following these guidelines%{linkEnd}"
+msgid "%{strongStart}Need your attention%{strongEnd} are the merge requests that need your help to move forward, as an assignee or reviewer."
+msgstr ""
+
+msgid "%{strongStart}Tip:%{strongEnd} You can also check out merge requests locally. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "%{strong_start}%{branch_count}%{strong_end} Branch"
@@ -1288,7 +1290,7 @@ msgstr ""
msgid "+%{tags} more"
msgstr ""
-msgid ", and "
+msgid ", "
msgstr ""
msgid ", or "
@@ -1461,7 +1463,7 @@ msgstr ""
msgid "1000+"
msgstr ""
-msgid "192.168.0.0/24"
+msgid "192.168.0.0/24 or 2001:0DB8:1234::/48"
msgstr ""
msgid "1st contribution!"
@@ -1605,6 +1607,12 @@ msgstr ""
msgid "A new impersonation token has been created."
msgstr ""
+msgid "A new personal access token has been created"
+msgstr ""
+
+msgid "A new personal access token, named %{token_name}, has been created."
+msgstr ""
+
msgid "A non-confidential epic cannot be assigned to a confidential parent epic"
msgstr ""
@@ -1773,13 +1781,13 @@ msgstr ""
msgid "AWS Access Key"
msgstr ""
-msgid "AWS Access Key. Only required if not using role instance credentials"
+msgid "AWS Secret Access Key"
msgstr ""
-msgid "AWS Secret Access Key"
+msgid "AWS access key ID (Optional)"
msgstr ""
-msgid "AWS Secret Access Key. Only required if not using role instance credentials"
+msgid "AWS secret access key (Optional)"
msgstr ""
msgid "AWS service error: %{error}"
@@ -1827,9 +1835,6 @@ msgstr ""
msgid "Access denied: %{error}"
msgstr ""
-msgid "Access expiration date"
-msgstr ""
-
msgid "Access expires"
msgstr ""
@@ -1839,9 +1844,6 @@ msgstr ""
msgid "Access granted"
msgstr ""
-msgid "Access key ID"
-msgstr ""
-
msgid "Access requests"
msgstr ""
@@ -1986,6 +1988,9 @@ msgstr ""
msgid "AccountValidation|you may %{unsubscribe_link} at any time."
msgstr ""
+msgid "Acknowledge"
+msgstr ""
+
msgid "Action"
msgstr ""
@@ -2016,7 +2021,7 @@ msgstr ""
msgid "Activity"
msgstr ""
-msgid "Activity|An error occured while retrieving activity. Reload the page to try again."
+msgid "Activity|An error occurred while retrieving activity. Reload the page to try again."
msgstr ""
msgid "Add"
@@ -2043,6 +2048,9 @@ msgstr ""
msgid "Add LICENSE"
msgstr ""
+msgid "Add License"
+msgstr ""
+
msgid "Add New Site"
msgstr ""
@@ -2055,6 +2063,9 @@ msgstr ""
msgid "Add a %{type}"
msgstr ""
+msgid "Add a GCP region"
+msgstr ""
+
msgid "Add a GPG key"
msgstr ""
@@ -2163,6 +2174,9 @@ msgstr ""
msgid "Add comment to design"
msgstr ""
+msgid "Add comment..."
+msgstr ""
+
msgid "Add commit messages as comments to Asana tasks. %{docs_link}"
msgstr ""
@@ -2391,6 +2405,9 @@ msgstr ""
msgid "Adds email participant(s)."
msgstr ""
+msgid "Adds this %{issuable_type} as related to the %{issuable_type} it was created from"
+msgstr ""
+
msgid "Adjust how frequently the GitLab UI polls for updates."
msgstr ""
@@ -2580,6 +2597,9 @@ msgstr ""
msgid "AdminSettings|A Let's Encrypt account will be configured for this GitLab instance using this email address. You will receive emails to warn of expiring certificates. %{link_start}Learn more.%{link_end}"
msgstr ""
+msgid "AdminSettings|Affects all new and existing groups."
+msgstr ""
+
msgid "AdminSettings|All new projects can use the instance's shared runners by default."
msgstr ""
@@ -2655,6 +2675,9 @@ msgstr ""
msgid "AdminSettings|Set a CI/CD template as the required pipeline configuration for all projects in the instance. Project CI/CD configuration merges into the required pipeline configuration when the pipeline runs. %{link_start}What is a required pipeline configuration?%{link_end}"
msgstr ""
+msgid "AdminSettings|Set the initial name and protections for the default branch of new repositories created in the instance."
+msgstr ""
+
msgid "AdminSettings|Set the maximum size of GitLab Pages per project (0 for unlimited). %{link_start}Learn more.%{link_end}"
msgstr ""
@@ -2664,9 +2687,6 @@ msgstr ""
msgid "AdminSettings|The default domain to use for Auto Review Apps and Auto Deploy stages in all projects."
msgstr ""
-msgid "AdminSettings|The default name for the initial branch of new repositories created in the instance."
-msgstr ""
-
msgid "AdminSettings|The latest artifacts for all jobs in the most recent successful pipelines in each project are stored and do not expire."
msgstr ""
@@ -3147,6 +3167,9 @@ msgstr ""
msgid "Akismet helps prevent the creation of spam issues in public projects."
msgstr ""
+msgid "Alert"
+msgstr ""
+
msgid "AlertManagement|Acknowledged"
msgstr ""
@@ -3519,9 +3542,6 @@ msgstr ""
msgid "All environments"
msgstr ""
-msgid "All epics"
-msgstr ""
-
msgid "All groups and projects"
msgstr ""
@@ -3582,7 +3602,7 @@ msgstr ""
msgid "Allow only the selected protocols to be used for Git access."
msgstr ""
-msgid "Allow owners to manage default branch protection per group"
+msgid "Allow owners to manage default branch protection per group."
msgstr ""
msgid "Allow owners to manually add users outside of LDAP"
@@ -3696,6 +3716,9 @@ msgstr ""
msgid "An %{link_start}alert%{link_end} with the same fingerprint is already open. To change the status of this alert, resolve the linked alert."
msgstr ""
+msgid "An Administrator has set the maximum expiration date to %{maxDate}. %{helpLinkStart}Learn more%{helpLinkEnd}."
+msgstr ""
+
msgid "An Enterprise User GitLab account has been created for you by your organization:"
msgstr ""
@@ -3993,6 +4016,9 @@ msgstr ""
msgid "An error occurred while parsing the file."
msgstr ""
+msgid "An error occurred while pasting text in the editor. Please try again."
+msgstr ""
+
msgid "An error occurred while removing epics."
msgstr ""
@@ -4106,6 +4132,9 @@ msgstr ""
msgid "An unauthenticated user"
msgstr ""
+msgid "An unexpected error occurred"
+msgstr ""
+
msgid "An unexpected error occurred while checking the project environment."
msgstr ""
@@ -4196,6 +4225,9 @@ msgstr ""
msgid "Any namespace"
msgstr ""
+msgid "Anyone can register for an account."
+msgstr ""
+
msgid "App ID"
msgstr ""
@@ -4681,6 +4713,9 @@ msgstr ""
msgid "Are you sure that you want to archive this project?"
msgstr ""
+msgid "Are you sure that you want to destroy %{application}"
+msgstr ""
+
msgid "Are you sure that you want to unarchive this project?"
msgstr ""
@@ -4738,9 +4773,6 @@ msgstr ""
msgid "Are you sure you want to discard your changes?"
msgstr ""
-msgid "Are you sure you want to erase this build?"
-msgstr ""
-
msgid "Are you sure you want to import %d repository?"
msgid_plural "Are you sure you want to import %d repositories?"
msgstr[0] ""
@@ -4788,6 +4820,9 @@ msgstr ""
msgid "Are you sure you want to remove this list?"
msgstr ""
+msgid "Are you sure you want to remove this nickname?"
+msgstr ""
+
msgid "Are you sure you want to reset the health check token?"
msgstr ""
@@ -4800,9 +4835,6 @@ 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 revoke this personal access token? This action cannot be undone."
msgstr ""
@@ -4926,12 +4958,6 @@ msgstr ""
msgid "Assign to me"
msgstr ""
-msgid "Assign yourself to these issues"
-msgstr ""
-
-msgid "Assign yourself to this issue"
-msgstr ""
-
msgid "Assigned %{assignee_users_sentence}."
msgstr ""
@@ -5020,6 +5046,9 @@ msgstr ""
msgid "Attention"
msgstr ""
+msgid "Attention requested"
+msgstr ""
+
msgid "Audit Events"
msgstr ""
@@ -5050,6 +5079,9 @@ msgstr ""
msgid "AuditLogs|IP Address"
msgstr ""
+msgid "AuditLogs|Log"
+msgstr ""
+
msgid "AuditLogs|Member Events"
msgstr ""
@@ -5071,6 +5103,54 @@ msgstr ""
msgid "AuditLogs|User Events"
msgstr ""
+msgid "AuditStreams|Active"
+msgstr ""
+
+msgid "AuditStreams|Add an HTTP endpoint to manage audit logs in third-party systems."
+msgstr ""
+
+msgid "AuditStreams|Add external stream destination"
+msgstr ""
+
+msgid "AuditStreams|Add stream"
+msgstr ""
+
+msgid "AuditStreams|An error occurred when creating external audit event stream destination. Please try it again."
+msgstr ""
+
+msgid "AuditStreams|An error occurred when deleting external audit event stream destination. Please try it again."
+msgstr ""
+
+msgid "AuditStreams|An error occurred when fetching external audit event streams. Please try it again"
+msgstr ""
+
+msgid "AuditStreams|Cancel editing"
+msgstr ""
+
+msgid "AuditStreams|Delete %{link}"
+msgstr ""
+
+msgid "AuditStreams|Destination URL"
+msgstr ""
+
+msgid "AuditStreams|Destinations receive all audit event data"
+msgstr ""
+
+msgid "AuditStreams|Setup streaming for audit events"
+msgstr ""
+
+msgid "AuditStreams|Stream count icon"
+msgstr ""
+
+msgid "AuditStreams|Streams"
+msgstr ""
+
+msgid "AuditStreams|This could include sensitive information. Make sure you trust the destination endpoint."
+msgstr ""
+
+msgid "AuditStreams|This is great for keeping everything one place."
+msgstr ""
+
msgid "Aug"
msgstr ""
@@ -5455,6 +5535,9 @@ msgstr ""
msgid "BambooService|The user with API access to the Bamboo server."
msgstr ""
+msgid "Banner message"
+msgstr ""
+
msgid "Based on"
msgstr ""
@@ -5769,6 +5852,9 @@ msgstr ""
msgid "BoardNewIssue|Select a project"
msgstr ""
+msgid "BoardScope|An error occurred while getting iterations. Please try again."
+msgstr ""
+
msgid "BoardScope|An error occurred while getting milestones, please try again."
msgstr ""
@@ -5784,6 +5870,9 @@ msgstr ""
msgid "BoardScope|Any assignee"
msgstr ""
+msgid "BoardScope|Any iteration"
+msgstr ""
+
msgid "BoardScope|Any label"
msgstr ""
@@ -5793,24 +5882,39 @@ msgstr ""
msgid "BoardScope|Choose labels"
msgstr ""
+msgid "BoardScope|Current iteration"
+msgstr ""
+
msgid "BoardScope|Edit"
msgstr ""
+msgid "BoardScope|Iteration"
+msgstr ""
+
msgid "BoardScope|Labels"
msgstr ""
msgid "BoardScope|Milestone"
msgstr ""
+msgid "BoardScope|No iteration"
+msgstr ""
+
msgid "BoardScope|No milestone"
msgstr ""
+msgid "BoardScope|Search iterations"
+msgstr ""
+
msgid "BoardScope|Search milestones"
msgstr ""
msgid "BoardScope|Select assignee"
msgstr ""
+msgid "BoardScope|Select iteration"
+msgstr ""
+
msgid "BoardScope|Select labels"
msgstr ""
@@ -5873,6 +5977,9 @@ msgstr ""
msgid "Boards|An error occurred while fetching the board swimlanes. Please reload the page."
msgstr ""
+msgid "Boards|An error occurred while fetching the board. Please reload the page."
+msgstr ""
+
msgid "Boards|An error occurred while generating lists. Please reload the page."
msgstr ""
@@ -5977,6 +6084,9 @@ msgstr ""
msgid "Branch changed"
msgstr ""
+msgid "Branch has been updated since the merge was requested."
+msgstr ""
+
msgid "Branch is already taken"
msgstr ""
@@ -6136,9 +6246,6 @@ msgstr ""
msgid "Broadcast Messages"
msgstr ""
-msgid "Broadcast messages are displayed for every user and can be used to notify users about scheduled maintenance, recent upgrades and more."
-msgstr ""
-
msgid "Browse Directory"
msgstr ""
@@ -6831,6 +6938,9 @@ msgstr ""
msgid "ChangeTypeAction|Your changes will be committed to %{branchName} because a merge request is open."
msgstr ""
+msgid "Changed"
+msgstr ""
+
msgid "Changed assignee(s)."
msgstr ""
@@ -6861,6 +6971,12 @@ msgstr ""
msgid "Changing any setting here requires an application restart"
msgstr ""
+msgid "Characters left"
+msgstr ""
+
+msgid "Characters over limit"
+msgstr ""
+
msgid "Charts can't be displayed as the request for data has timed out. %{documentationLink}"
msgstr ""
@@ -7024,6 +7140,9 @@ msgstr ""
msgid "Checkout|CI minutes"
msgstr ""
+msgid "Checkout|Calculating your subscription..."
+msgstr ""
+
msgid "Checkout|Checkout"
msgstr ""
@@ -7138,6 +7257,9 @@ msgstr ""
msgid "Checkout|Tax"
msgstr ""
+msgid "Checkout|This number must be %{minimumNumberOfUsers} (your seats in use) or more."
+msgstr ""
+
msgid "Checkout|Total"
msgstr ""
@@ -7381,24 +7503,12 @@ msgstr ""
msgid "CiVariable|Create wildcard"
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 "Classification Label (optional)"
msgstr ""
@@ -7456,6 +7566,15 @@ msgstr ""
msgid "Clear templates search input"
msgstr ""
+msgid "Clear this checkbox to use a personal access token instead."
+msgstr ""
+
+msgid "Clear this checkbox to use a personal access token or LDAP password instead."
+msgstr ""
+
+msgid "Clear this checkbox to use an external authentication provider instead."
+msgstr ""
+
msgid "Clear weight"
msgstr ""
@@ -7576,9 +7695,6 @@ msgstr ""
msgid "Closed MRs"
msgstr ""
-msgid "Closed epics"
-msgstr ""
-
msgid "Closed issues"
msgstr ""
@@ -7615,13 +7731,13 @@ msgstr ""
msgid "Cluster level"
msgstr ""
-msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
+msgid "Cluster type must be specified for Stages::ClusterEndpointInserter"
msgstr ""
msgid "ClusterAgents|%{name} successfully deleted"
msgstr ""
-msgid "ClusterAgents|%{number} of %{total} Agents"
+msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
@@ -7645,6 +7761,9 @@ msgstr ""
msgid "ClusterAgents|Actions"
msgstr ""
+msgid "ClusterAgents|Add an agent configuration file to %{linkStart}this repository%{linkEnd} and select it, or create a new one to register with GitLab:"
+msgstr ""
+
msgid "ClusterAgents|Advanced installation methods"
msgstr ""
@@ -7696,22 +7815,19 @@ msgstr ""
msgid "ClusterAgents|Configuration"
msgstr ""
-msgid "ClusterAgents|Connect a cluster through the Agent"
+msgid "ClusterAgents|Connect a cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connect existing cluster"
msgstr ""
-msgid "ClusterAgents|Connect with Agent"
-msgstr ""
-
msgid "ClusterAgents|Connect with a certificate"
msgstr ""
-msgid "ClusterAgents|Connect with the GitLab Agent"
+msgid "ClusterAgents|Connect with an agent"
msgstr ""
-msgid "ClusterAgents|Connect your cluster through the Agent"
+msgid "ClusterAgents|Connect with the GitLab Agent"
msgstr ""
msgid "ClusterAgents|Connected"
@@ -7720,12 +7836,24 @@ msgstr ""
msgid "ClusterAgents|Connection status"
msgstr ""
+msgid "ClusterAgents|Copy command"
+msgstr ""
+
msgid "ClusterAgents|Copy token"
msgstr ""
msgid "ClusterAgents|Create a new cluster"
msgstr ""
+msgid "ClusterAgents|Create agent access token"
+msgstr ""
+
+msgid "ClusterAgents|Create agent: %{searchTerm}"
+msgstr ""
+
+msgid "ClusterAgents|Create token"
+msgstr ""
+
msgid "ClusterAgents|Created by"
msgstr ""
@@ -7735,6 +7863,9 @@ msgstr ""
msgid "ClusterAgents|Date created"
msgstr ""
+msgid "ClusterAgents|Default configuration"
+msgstr ""
+
msgid "ClusterAgents|Delete"
msgstr ""
@@ -7750,6 +7881,9 @@ msgstr ""
msgid "ClusterAgents|Event occurred"
msgstr ""
+msgid "ClusterAgents|Failed to create a token"
+msgstr ""
+
msgid "ClusterAgents|Failed to register an agent"
msgstr ""
@@ -7765,16 +7899,13 @@ msgstr ""
msgid "ClusterAgents|Give feedback"
msgstr ""
-msgid "ClusterAgents|Go to the repository files"
+msgid "ClusterAgents|How do I register an agent?"
msgstr ""
-msgid "ClusterAgents|How to register an agent?"
+msgid "ClusterAgents|How to update an agent?"
msgstr ""
-msgid "ClusterAgents|How to update the Agent?"
-msgstr ""
-
-msgid "ClusterAgents|Install new Agent"
+msgid "ClusterAgents|Install a new agent"
msgstr ""
msgid "ClusterAgents|Last connected %{timeAgo}."
@@ -7783,9 +7914,6 @@ msgstr ""
msgid "ClusterAgents|Last contact"
msgstr ""
-msgid "ClusterAgents|Learn how to create an agent access token"
-msgstr ""
-
msgid "ClusterAgents|Learn how to troubleshoot"
msgstr ""
@@ -7801,7 +7929,7 @@ msgstr ""
msgid "ClusterAgents|Never connected"
msgstr ""
-msgid "ClusterAgents|No Agents"
+msgid "ClusterAgents|No agents"
msgstr ""
msgid "ClusterAgents|No clusters connected through cluster certificates"
@@ -7819,10 +7947,7 @@ msgstr ""
msgid "ClusterAgents|Register"
msgstr ""
-msgid "ClusterAgents|Register an agent to generate a token that will be used to install the agent on your cluster in the next step."
-msgstr ""
-
-msgid "ClusterAgents|Registering Agent"
+msgid "ClusterAgents|Registering agent"
msgstr ""
msgid "ClusterAgents|Registration token"
@@ -7846,24 +7971,21 @@ msgstr ""
msgid "ClusterAgents|See Agent activity updates such as tokens created or revoked and clusters connected or not connected."
msgstr ""
-msgid "ClusterAgents|Select an agent"
-msgstr ""
-
-msgid "ClusterAgents|Select an agent to register with GitLab"
+msgid "ClusterAgents|Select an agent or enter a name to create new"
msgstr ""
msgid "ClusterAgents|Tell us what you think"
msgstr ""
-msgid "ClusterAgents|The Agent version do not match each other across your cluster's pods. This can happen when a new Agent version was just deployed and Kubernetes is shutting down the old pods."
-msgstr ""
-
msgid "ClusterAgents|The GitLab Agent provides an increased level of security when connecting Kubernetes clusters to GitLab. %{linkStart}Learn more about the GitLab Agent.%{linkEnd}"
msgstr ""
msgid "ClusterAgents|The agent has not been connected in a long time. There might be a connectivity issue. Last contact was %{timeAgo}."
msgstr ""
+msgid "ClusterAgents|The agent version do not match each other across your cluster's pods. This can happen when a new agent version was just deployed and Kubernetes is shutting down the old pods."
+msgstr ""
+
msgid "ClusterAgents|The recommended installation method includes the token. If you want to follow the advanced installation method provided in the docs, make sure you save the token value before you close this window."
msgstr ""
@@ -7881,9 +8003,6 @@ msgstr ""
msgid "ClusterAgents|To delete the agent, type %{name} to confirm:"
msgstr ""
-msgid "ClusterAgents|To install a new agent, first add the agent's configuration file to this repository. %{linkStart}Learn more about installing GitLab Agent.%{linkEnd}"
-msgstr ""
-
msgid "ClusterAgents|Token created by %{userName}"
msgstr ""
@@ -7905,13 +8024,16 @@ msgstr ""
msgid "ClusterAgents|What is GitLab Agent activity?"
msgstr ""
+msgid "ClusterAgents|What is default configuration?"
+msgstr ""
+
msgid "ClusterAgents|You cannot see this token again after you close this window."
msgstr ""
msgid "ClusterAgents|You will need to create a token to connect to your agent"
msgstr ""
-msgid "ClusterAgents|Your Agent version is out of sync with your GitLab version (v%{version}), which might cause compatibility problems. Update the Agent installed on your cluster to the most recent version."
+msgid "ClusterAgents|Your agent version is out of sync with your GitLab version (v%{version}), which might cause compatibility problems. Update the agent installed on your cluster to the most recent version."
msgstr ""
msgid "ClusterAgents|Your instance doesn't have the %{linkStart}GitLab Agent Server (KAS)%{linkEnd} set up. Ask a GitLab Administrator to install it."
@@ -7947,9 +8069,6 @@ 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 ""
@@ -8058,10 +8177,7 @@ msgstr ""
msgid "ClusterIntegration|Clusters are utilized by selecting the nearest ancestor with a matching environment scope. For example, project clusters will override group clusters. %{linkStart}More information%{linkEnd}"
msgstr ""
-msgid "ClusterIntegration|Connect cluster with certificate"
-msgstr ""
-
-msgid "ClusterIntegration|Connect existing cluster"
+msgid "ClusterIntegration|Connect a Kubernetes cluster"
msgstr ""
msgid "ClusterIntegration|Connect with a certificate"
@@ -8109,18 +8225,6 @@ msgstr ""
msgid "ClusterIntegration|Create Kubernetes cluster"
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 ""
@@ -8154,6 +8258,9 @@ msgstr ""
msgid "ClusterIntegration|Enable this setting if using role-based access control (RBAC)."
msgstr ""
+msgid "ClusterIntegration|Enter details about your cluster. %{linkStart}How do I use a certificate to connect to my cluster?%{linkEnd}"
+msgstr ""
+
msgid "ClusterIntegration|Enter new Service Token"
msgstr ""
@@ -8163,6 +8270,9 @@ msgstr ""
msgid "ClusterIntegration|Enter the details for your Kubernetes cluster"
msgstr ""
+msgid "ClusterIntegration|Enter your Kubernetes cluster certificate details"
+msgstr ""
+
msgid "ClusterIntegration|Environment scope"
msgstr ""
@@ -8226,9 +8336,6 @@ msgstr ""
msgid "ClusterIntegration|HTTP Error"
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 ""
@@ -8274,7 +8381,7 @@ msgstr ""
msgid "ClusterIntegration|Learn more about %{help_link_start}zones%{help_link_end}."
msgstr ""
-msgid "ClusterIntegration|Learn more about Kubernetes"
+msgid "ClusterIntegration|Learn more about Kubernetes."
msgstr ""
msgid "ClusterIntegration|Learn more about group Kubernetes clusters"
@@ -8367,9 +8474,6 @@ 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 %{linkStart}documentation%{linkEnd} on Kubernetes"
-msgstr ""
-
msgid "ClusterIntegration|Please make sure that your Google account meets the following requirements:"
msgstr ""
@@ -8619,12 +8723,18 @@ msgstr ""
msgid "ClusterIntegration|Unknown Error"
msgstr ""
+msgid "ClusterIntegration|Use GitLab to deploy to your cluster, run jobs, use review apps, and more."
+msgstr ""
+
msgid "ClusterIntegration|Use the %{linkStart}GitLab Agent%{linkEnd} to safely connect your Kubernetes clusters to GitLab. You can deploy your applications, run your pipelines, use Review Apps, and much more."
msgstr ""
msgid "ClusterIntegration|Uses the Cloud Run, Istio, and HTTP Load Balancing addons for this cluster."
msgstr ""
+msgid "ClusterIntegration|Using AutoDevOps with multiple clusters? %{help_link_start}Read this first.%{help_link_end}"
+msgstr ""
+
msgid "ClusterIntegration|VPC"
msgstr ""
@@ -8637,7 +8747,7 @@ msgstr ""
msgid "ClusterIntegration|We were unable to fetch any projects. Ensure that you have a project on %{docsLinkStart}Google Cloud Platform%{docsLinkEnd}."
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."
+msgid "ClusterIntegration|Where do you want to create a cluster?"
msgstr ""
msgid "ClusterIntegration|You are about to remove your cluster integration and all GitLab-created resources associated with this cluster."
@@ -8879,9 +8989,6 @@ msgstr ""
msgid "CommitMessage|Add %{file_name}"
msgstr ""
-msgid "CommitMessage|Add %{file_name} and create a code quality job"
-msgstr ""
-
msgid "CommitWidget|authored"
msgstr ""
@@ -9041,9 +9148,6 @@ msgstr ""
msgid "ComplianceFrameworks|Configuration not found"
msgstr ""
-msgid "ComplianceFrameworks|Configured compliance frameworks appear here."
-msgstr ""
-
msgid "ComplianceFrameworks|Delete compliance framework %{framework}"
msgstr ""
@@ -9068,6 +9172,9 @@ msgstr ""
msgid "ComplianceFrameworks|Error fetching compliance frameworks data. Please refresh the page or try a different framework"
msgstr ""
+msgid "ComplianceFrameworks|Frameworks that have been added will appear here."
+msgstr ""
+
msgid "ComplianceFrameworks|Invalid format"
msgstr ""
@@ -9077,7 +9184,7 @@ msgstr ""
msgid "ComplianceFrameworks|Name is required"
msgstr ""
-msgid "ComplianceFrameworks|No compliance frameworks are configured"
+msgid "ComplianceFrameworks|No compliance frameworks are set up yet"
msgstr ""
msgid "ComplianceFrameworks|Required format: %{codeStart}path/file.y[a]ml@group-name/project-name%{codeEnd}. %{linkStart}Learn more.%{linkEnd}"
@@ -9089,12 +9196,24 @@ msgstr ""
msgid "ComplianceFrameworks|You are about to permanently delete the compliance framework %{framework} from all projects which currently have it applied, which may remove other functionality. This cannot be undone."
msgstr ""
+msgid "ComplianceFramework|Add a framework to %{linkStart}%{groupName}%{linkEnd} and it will appear here."
+msgstr ""
+
+msgid "ComplianceFramework|Add framework in %{groupName}"
+msgstr ""
+
+msgid "ComplianceFramework|After a framework is added to %{linkStart}%{groupName}%{linkEnd}, it will appear here."
+msgstr ""
+
msgid "ComplianceFramework|Edit compliance framework"
msgstr ""
msgid "ComplianceFramework|New compliance framework"
msgstr ""
+msgid "ComplianceFramework|No compliance frameworks are set up yet"
+msgstr ""
+
msgid "ComplianceReport|Approved by author"
msgstr ""
@@ -9116,6 +9235,12 @@ msgstr ""
msgid "Confidential"
msgstr ""
+msgid "Confidential issue"
+msgstr ""
+
+msgid "Confidential note"
+msgstr ""
+
msgid "Confidentiality"
msgstr ""
@@ -9200,6 +9325,15 @@ msgstr ""
msgid "Configure pipelines to deploy web apps, backend services, APIs and static resources to Google Cloud"
msgstr ""
+msgid "Configure region"
+msgstr ""
+
+msgid "Configure region for environment"
+msgstr ""
+
+msgid "Configure regions"
+msgstr ""
+
msgid "Configure repository mirroring."
msgstr ""
@@ -9233,15 +9367,27 @@ msgstr ""
msgid "Configure which lists are shown for anyone who visits this board"
msgstr ""
+msgid "Configure with a merge request"
+msgstr ""
+
+msgid "Configure your environments to be deployed to specific geographical regions"
+msgstr ""
+
msgid "Confirm"
msgstr ""
msgid "Confirm approval"
msgstr ""
+msgid "Confirm destroy application"
+msgstr ""
+
msgid "Confirm new password"
msgstr ""
+msgid "Confirm remove avatar"
+msgstr ""
+
msgid "Confirm user"
msgstr ""
@@ -9308,6 +9454,12 @@ msgstr ""
msgid "Connect"
msgstr ""
+msgid "Connect a Kubernetes Cluster"
+msgstr ""
+
+msgid "Connect a cluster"
+msgstr ""
+
msgid "Connect all repositories"
msgstr ""
@@ -9623,6 +9775,9 @@ msgstr ""
msgid "ContainerRegistry|Tags successfully marked for deletion."
msgstr ""
+msgid "ContainerRegistry|Tags temporarily cannot be marked for deletion. Please try again in a few minutes. %{docLinkStart}More details%{docLinkEnd}."
+msgstr ""
+
msgid "ContainerRegistry|Tags that match these rules are %{strongStart}kept%{strongEnd}, even if they match a removal rule below. The %{secondStrongStart}latest%{secondStrongEnd} tag is always kept."
msgstr ""
@@ -10142,9 +10297,15 @@ msgstr ""
msgid "Create a GitLab account first, and then connect it to your %{label} account."
msgstr ""
+msgid "Create a Kubernetes cluster"
+msgstr ""
+
msgid "Create a Mattermost team for this group"
msgstr ""
+msgid "Create a cluster"
+msgstr ""
+
msgid "Create a group"
msgstr ""
@@ -10313,9 +10474,6 @@ msgstr ""
msgid "Create user"
msgstr ""
-msgid "Create via merge request"
-msgstr ""
-
msgid "Create wildcard: %{searchTerm}"
msgstr ""
@@ -10745,9 +10903,6 @@ msgstr ""
msgid "Customer relations"
msgstr ""
-msgid "Customizable by owners."
-msgstr ""
-
msgid "Customize CI/CD settings, including Auto DevOps, shared runners, and job artifacts."
msgstr ""
@@ -10874,28 +11029,34 @@ msgstr ""
msgid "CycleAnalytics|%{selectedLabelsCount} selected (%{maxLabels} max)"
msgstr ""
-msgid "CycleAnalytics|%{stageCount} stages selected"
+msgid "CycleAnalytics|Aggregation disabled"
msgstr ""
-msgid "CycleAnalytics|All stages"
+msgid "CycleAnalytics|Aggregation enabled"
msgstr ""
-msgid "CycleAnalytics|Average days to completion"
+msgid "CycleAnalytics|Average time to completion"
msgstr ""
-msgid "CycleAnalytics|Date"
+msgid "CycleAnalytics|Create a custom value stream to view metrics about stages specific to your development process. Use your value stream to visualize your DevSecOps lifecycle, determine the velocity of your group, and identify inefficient processes."
+msgstr ""
+
+msgid "CycleAnalytics|Create a custom value stream…"
msgstr ""
-msgid "CycleAnalytics|Days to completion"
+msgid "CycleAnalytics|Custom value streams to measure your DevSecOps lifecycle"
+msgstr ""
+
+msgid "CycleAnalytics|Date"
msgstr ""
msgid "CycleAnalytics|Display chart filters"
msgstr ""
-msgid "CycleAnalytics|Lead Time for Changes"
+msgid "CycleAnalytics|Filter by stop date"
msgstr ""
-msgid "CycleAnalytics|No stages selected"
+msgid "CycleAnalytics|Lead Time for Changes"
msgstr ""
msgid "CycleAnalytics|Number of tasks"
@@ -10926,21 +11087,39 @@ msgstr ""
msgid "CycleAnalytics|Showing data for group '%{groupName}' from %{createdAfter} to %{createdBefore}"
msgstr ""
-msgid "CycleAnalytics|Stages"
+msgid "CycleAnalytics|Stage time: %{title}"
msgstr ""
msgid "CycleAnalytics|Tasks by type"
msgstr ""
-msgid "CycleAnalytics|The average time spent in the selected stage for the items that were completed on each date. Data limited to the last 500 items."
+msgid "CycleAnalytics|The average time items spent in this stage. Data limited to items completed within this date range."
msgstr ""
msgid "CycleAnalytics|The given date range is larger than 180 days"
msgstr ""
+msgid "CycleAnalytics|The total time items spent across each value stream stage. Data limited to items completed within this date range."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Stage time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Total time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|There was an error updating the aggregation status, please try again."
+msgstr ""
+
+msgid "CycleAnalytics|Total time"
+msgstr ""
+
msgid "CycleAnalytics|Type of work"
msgstr ""
+msgid "CycleAnalytics|When enabled, the results show items with a stop event within the date range. When disabled, the results show items with a start event within the date range."
+msgstr ""
+
msgid "CycleAnalytics|group dropdown filter"
msgstr ""
@@ -10950,9 +11129,6 @@ msgstr ""
msgid "CycleAnalytics|project dropdown filter"
msgstr ""
-msgid "CycleAnalytics|stage dropdown"
-msgstr ""
-
msgid "DAG visualization requires at least 3 dependent jobs."
msgstr ""
@@ -11076,6 +11252,9 @@ msgstr ""
msgid "DastProfiles|Branch missing"
msgstr ""
+msgid "DastProfiles|Choose a scan method"
+msgstr ""
+
msgid "DastProfiles|Could not create the scanner profile. Please try again."
msgstr ""
@@ -11217,6 +11396,9 @@ msgstr ""
msgid "DastProfiles|Save profile"
msgstr ""
+msgid "DastProfiles|Scan method"
+msgstr ""
+
msgid "DastProfiles|Scan mode"
msgstr ""
@@ -11295,12 +11477,24 @@ msgstr ""
msgid "DastProfiles|Website"
msgstr ""
+msgid "DastProfiles|What does each method do?"
+msgstr ""
+
msgid "DastProfiles|You can either choose a passive scan or validate the target site from the site profile management page. %{docsLinkStart}Learn more about site validation.%{docsLinkEnd}"
msgstr ""
msgid "DastProfiles|You cannot run an active scan against an unvalidated site."
msgstr ""
+msgid "DastProfiles|folder/dast_example.har or https://example.com/dast_example.har"
+msgstr ""
+
+msgid "DastProfiles|folder/example.postman_collection.json or https://example.com/"
+msgstr ""
+
+msgid "DastProfiles|folder/openapi.json or https://example.com/openapi.json"
+msgstr ""
+
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
@@ -11393,6 +11587,9 @@ msgstr ""
msgid "Data is still calculating..."
msgstr ""
+msgid "Data refresh"
+msgstr ""
+
msgid "Data type"
msgstr ""
@@ -11522,9 +11719,6 @@ msgstr ""
msgid "Default branch and protected branches"
msgstr ""
-msgid "Default branch protection"
-msgstr ""
-
msgid "Default delayed project deletion"
msgstr ""
@@ -11543,9 +11737,6 @@ msgstr ""
msgid "Default first day of the week in calendars and date pickers."
msgstr ""
-msgid "Default initial branch name"
-msgstr ""
-
msgid "Default project deletion protection"
msgstr ""
@@ -12173,6 +12364,9 @@ msgstr ""
msgid "Deploying to AWS is easy with GitLab"
msgstr ""
+msgid "Deployment"
+msgstr ""
+
msgid "Deployment Frequency"
msgstr ""
@@ -12185,6 +12379,33 @@ msgstr ""
msgid "Deployment frequency"
msgstr ""
+msgid "DeploymentApproval| Current approvals: %{current}"
+msgstr ""
+
+msgid "DeploymentApproval|Approval options"
+msgstr ""
+
+msgid "DeploymentApproval|Approve or reject deployment #%{deploymentIid}"
+msgstr ""
+
+msgid "DeploymentApproval|Approved by %{user} %{time}"
+msgstr ""
+
+msgid "DeploymentApproval|Approved by you %{time}"
+msgstr ""
+
+msgid "DeploymentApproval|Approving will run the manual job from deployment #%{deploymentIid}. Rejecting will fail the manual job."
+msgstr ""
+
+msgid "DeploymentApproval|Deployment tier: %{tier}"
+msgstr ""
+
+msgid "DeploymentApproval|Environment: %{environment}"
+msgstr ""
+
+msgid "DeploymentApproval|Manual job: %{jobName}"
+msgstr ""
+
msgid "DeploymentTarget|GitLab Pages"
msgstr ""
@@ -12247,6 +12468,9 @@ msgstr ""
msgid "Deployment|Latest Deployed"
msgstr ""
+msgid "Deployment|Needs Approval"
+msgstr ""
+
msgid "Deployment|Running"
msgstr ""
@@ -12750,6 +12974,9 @@ msgstr ""
msgid "Direct member"
msgstr ""
+msgid "Direct members"
+msgstr ""
+
msgid "Direct non-authenticated users to this page."
msgstr ""
@@ -13040,6 +13267,9 @@ msgstr ""
msgid "Draft"
msgstr ""
+msgid "Draft: %{filename}"
+msgstr ""
+
msgid "Drag your designs here or %{linkStart}click to upload%{linkEnd}."
msgstr ""
@@ -13187,7 +13417,7 @@ msgstr ""
msgid "Edit identity for %{user_name}"
msgstr ""
-msgid "Edit in Web IDE"
+msgid "Edit in pipeline editor"
msgstr ""
msgid "Edit in single-file editor"
@@ -13232,6 +13462,9 @@ msgstr ""
msgid "Edit your most recent comment in a thread (from an empty textarea)"
msgstr ""
+msgid "Edit, lint, and visualize your pipeline."
+msgstr ""
+
msgid "Edited"
msgstr ""
@@ -13508,6 +13741,9 @@ msgstr ""
msgid "Enable container expiration and retention policies for projects created earlier than GitLab 12.7."
msgstr ""
+msgid "Enable container expiration caching."
+msgstr ""
+
msgid "Enable delayed project deletion by default for newly-created groups."
msgstr ""
@@ -13783,7 +14019,7 @@ msgstr ""
msgid "Environment scope"
msgstr ""
-msgid "Environment variable %{code_start}%{environment_variable}%{code_end} does not exist or is not pointing to a valid directory."
+msgid "Environment variable %{environment_variable} does not exist or is not pointing to a valid directory."
msgstr ""
msgid "Environment variables are configured by your administrator to be %{link_start}protected%{link_end} by default."
@@ -14386,6 +14622,12 @@ msgstr ""
msgid "ErrorTracking|If you self-host Sentry, enter your Sentry instance's full URL. If you use Sentry's hosted solution, enter https://sentry.io"
msgstr ""
+msgid "ErrorTracking|Integrated error tracking is %{epicLinkStart}turned off by default%{epicLinkEnd} and no longer active for this project. To re-enable error tracking on self-hosted instances, you can either %{flagLinkStart}turn on the feature flag%{flagLinkEnd} for integrated error tracking, or provide a %{settingsLinkStart}Sentry API URL and Auth Token%{settingsLinkEnd} on your project settings page. However, error tracking is not ready for production use and cannot be enabled on GitLab.com."
+msgstr ""
+
+msgid "ErrorTracking|Integrated error tracking is %{epicLinkStart}turned off by default%{epicLinkEnd} and no longer active for this project. To re-enable error tracking on self-hosted instances, you can either %{flagLinkStart}turn on the feature flag%{flagLinkEnd} for integrated error tracking, or provide a Sentry API URL and Auth Token below. However, error tracking is not ready for production use and cannot be enabled on GitLab.com."
+msgstr ""
+
msgid "ErrorTracking|No projects available"
msgstr ""
@@ -14395,6 +14637,9 @@ msgstr ""
msgid "ErrorTracking|To enable project selection, enter a valid Auth Token."
msgstr ""
+msgid "ErrorTracking|View project settings"
+msgstr ""
+
msgid "Errors"
msgstr ""
@@ -14404,6 +14649,9 @@ msgstr ""
msgid "Errors:"
msgstr ""
+msgid "Escalate this incident"
+msgstr ""
+
msgid "Escalation Policies"
msgstr ""
@@ -14670,6 +14918,9 @@ msgstr ""
msgid "Existing sign in methods may be removed"
msgstr ""
+msgid "Exit."
+msgstr ""
+
msgid "Expand"
msgstr ""
@@ -14889,9 +15140,15 @@ msgstr ""
msgid "ExternalAuthorization|URL to which the projects make authorization requests. If the URL is blank, cross-project features are available and can still specify classification labels for projects."
msgstr ""
+msgid "ExternalIssueIntegration|Another issue tracker is already in use"
+msgstr ""
+
msgid "ExternalIssueIntegration|Not all data may be displayed here. To view more details or make changes to this issue, go to %{linkStart}%{trackerName}%{linkEnd}."
msgstr ""
+msgid "ExternalIssueIntegration|Only one issue tracker integration can be active at a time. Please disable the active tracker first and try again."
+msgstr ""
+
msgid "ExternalIssueIntegration|This issue is synchronized with %{trackerName}"
msgstr ""
@@ -15427,7 +15684,7 @@ msgstr ""
msgid "February"
msgstr ""
-msgid "Fetch and check out the branch for this merge request"
+msgid "Fetch and check out this merge request's feature branch:"
msgstr ""
msgid "Fetching incoming email"
@@ -15568,9 +15825,6 @@ msgstr ""
msgid "Filter users"
msgstr ""
-msgid "Filter your repositories by name"
-msgstr ""
-
msgid "Filter..."
msgstr ""
@@ -15700,7 +15954,7 @@ msgstr ""
msgid "For each job, re-use the project workspace. If the workspace doesn't exist, use %{code_open}git clone%{code_close}."
msgstr ""
-msgid "For example, the application using the token or the purpose of the token."
+msgid "For example, the application using the token or the purpose of the token. Do not give sensitive information for the name of the token, as it will be visible to all %{resource_type} members."
msgstr ""
msgid "For files larger than this limit, only index the file name. The file content is neither indexed nor searchable."
@@ -15784,9 +16038,6 @@ msgstr ""
msgid "ForkProject|Select a namespace"
msgstr ""
-msgid "ForkProject|Select a namespace to fork the project"
-msgstr ""
-
msgid "ForkProject|The project can be accessed by any logged in user."
msgstr ""
@@ -15883,6 +16134,9 @@ msgstr ""
msgid "Full name"
msgstr ""
+msgid "GCP region configured"
+msgstr ""
+
msgid "GPG Key ID:"
msgstr ""
@@ -15928,9 +16182,6 @@ msgstr ""
msgid "Generate site and private keys at"
msgstr ""
-msgid "Generated service account is linked to the selected environment"
-msgstr ""
-
msgid "Generic"
msgstr ""
@@ -16543,9 +16794,6 @@ msgstr ""
msgid "GitLab logo"
msgstr ""
-msgid "GitLab member or Email address"
-msgstr ""
-
msgid "GitLab metadata URL"
msgstr ""
@@ -16657,7 +16905,7 @@ msgstr ""
msgid "GitLabPages|When enabled, all attempts to visit your website through HTTP are automatically redirected to HTTPS using a response with status code 301. Requires a valid certificate for all domains. %{docs_link_start}Learn more.%{link_end}"
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. %{docs_link_start}Learn more.%{link_end}"
+msgid "GitLabPages|When using Pages under the general domain of a GitLab instance (%{pages_host}), you cannot use HTTPS with subdomains of subdomains. If your namespace or groupname contains a dot, it does not work. This is a limitation of the HTTP Over TLS protocol. HTTP pages work if you don't redirect HTTP to HTTPS. %{docs_link_start}Learn more.%{link_end}"
msgstr ""
msgid "GitLabPages|With GitLab Pages you can host your static website directly from your GitLab repository. %{docs_link_start}Learn more.%{link_end}"
@@ -16771,15 +17019,24 @@ msgstr ""
msgid "GlobalSearch|Search GitLab"
msgstr ""
+msgid "GlobalSearch|Search for projects, issues, etc."
+msgstr ""
+
msgid "GlobalSearch|Search results are loading"
msgstr ""
+msgid "GlobalSearch|There was an error fetching search autocomplete suggestions."
+msgstr ""
+
msgid "GlobalSearch|Type and press the enter key to submit search."
msgstr ""
msgid "GlobalSearch|Type for new suggestions to appear below."
msgstr ""
+msgid "GlobalSearch|What are you searching for?"
+msgstr ""
+
msgid "GlobalSearch|in all GitLab"
msgstr ""
@@ -16819,6 +17076,9 @@ msgstr ""
msgid "Go to environments"
msgstr ""
+msgid "Go to environments page to approve or reject"
+msgstr ""
+
msgid "Go to epic"
msgstr ""
@@ -16834,9 +17094,6 @@ msgstr ""
msgid "Go to find file"
msgstr ""
-msgid "Go to fork"
-msgstr ""
-
msgid "Go to issue boards"
msgstr ""
@@ -16948,9 +17205,6 @@ msgstr ""
msgid "Google Cloud authorizations required"
msgstr ""
-msgid "Google Cloud project"
-msgstr ""
-
msgid "Google Cloud project misconfigured"
msgstr ""
@@ -16960,6 +17214,42 @@ 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 "GoogleCloud|Cancel"
+msgstr ""
+
+msgid "GoogleCloud|Configured region is linked to the selected branch or tag"
+msgstr ""
+
+msgid "GoogleCloud|Create service account"
+msgstr ""
+
+msgid "GoogleCloud|Generated service account is linked to the selected branch or tag"
+msgstr ""
+
+msgid "GoogleCloud|Google Cloud project"
+msgstr ""
+
+msgid "GoogleCloud|Google OAuth2 token revocation request failed"
+msgstr ""
+
+msgid "GoogleCloud|Google OAuth2 token revocation requested"
+msgstr ""
+
+msgid "GoogleCloud|I understand the responsibilities involved with managing service account keys"
+msgstr ""
+
+msgid "GoogleCloud|New service account is generated for the selected Google Cloud project"
+msgstr ""
+
+msgid "GoogleCloud|Refs"
+msgstr ""
+
+msgid "GoogleCloud|Revoke authorizations"
+msgstr ""
+
+msgid "GoogleCloud|Revoke authorizations granted to GitLab. This does not invalidate service accounts."
+msgstr ""
+
msgid "Got it"
msgstr ""
@@ -17164,9 +17454,6 @@ msgstr ""
msgid "Group runners can be managed with the %{link}."
msgstr ""
-msgid "Group sharing provides access to all group members (including members who inherited group membership from a parent group)."
-msgstr ""
-
msgid "Group variables (inherited)"
msgstr ""
@@ -17569,13 +17856,13 @@ msgstr ""
msgid "GroupSettings|Select the project that contains your custom Insights file."
msgstr ""
-msgid "GroupSettings|Set the maximum size of GitLab Pages for this group. %{link_start}Learn more.%{link_end}"
+msgid "GroupSettings|Set the initial name and protections for the default branch of new repositories created in the group."
msgstr ""
-msgid "GroupSettings|The Auto DevOps pipeline runs if no alternative CI configuration file is found."
+msgid "GroupSettings|Set the maximum size of GitLab Pages for this group. %{link_start}Learn more.%{link_end}"
msgstr ""
-msgid "GroupSettings|The default name for the initial branch of new repositories created in the group."
+msgid "GroupSettings|The Auto DevOps pipeline runs if no alternative CI configuration file is found."
msgstr ""
msgid "GroupSettings|The projects in this subgroup can be selected as templates for new projects created in the group. %{link_start}Learn more.%{link_end}"
@@ -17638,9 +17925,6 @@ msgstr ""
msgid "Groups and projects"
msgstr ""
-msgid "Groups and subgroups"
-msgstr ""
-
msgid "Groups are a great way to organize projects and people."
msgstr ""
@@ -17701,6 +17985,9 @@ msgstr ""
msgid "GroupsNew|Create new group"
msgstr ""
+msgid "GroupsNew|Create this in the %{pat_link_start}user settings%{pat_link_end} of the source GitLab instance. For %{short_living_link_start}security reasons%{short_living_link_end}, use a short expiration date when creating the token."
+msgstr ""
+
msgid "GroupsNew|Export groups with all their related data and move to a new GitLab instance."
msgstr ""
@@ -17719,9 +18006,6 @@ msgstr ""
msgid "GroupsNew|My Awesome Group"
msgstr ""
-msgid "GroupsNew|Navigate to user settings to find your %{link_start}personal access token%{link_end}."
-msgstr ""
-
msgid "GroupsNew|No import options available"
msgstr ""
@@ -17836,9 +18120,45 @@ msgstr ""
msgid "HAR file path or URL"
msgstr ""
+msgid "HTTP Archive (HAR)"
+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 "Harbor Registry"
+msgstr ""
+
+msgid "HarborIntegration|After the Harbor integration is activated, global variables ‘$HARBOR_USERNAME’, ‘$HARBOR_PASSWORD’, ‘$HARBOR_URL’ and ‘$HARBOR_PROJECT’ will be created for CI/CD use."
+msgstr ""
+
+msgid "HarborIntegration|Base URL of the Harbor instance."
+msgstr ""
+
+msgid "HarborIntegration|Enter Harbor password"
+msgstr ""
+
+msgid "HarborIntegration|Harbor URL"
+msgstr ""
+
+msgid "HarborIntegration|Harbor password"
+msgstr ""
+
+msgid "HarborIntegration|Harbor project name"
+msgstr ""
+
+msgid "HarborIntegration|Harbor username"
+msgstr ""
+
+msgid "HarborIntegration|Password for your Harbor username."
+msgstr ""
+
+msgid "HarborIntegration|The name of the project in Harbor."
+msgstr ""
+
+msgid "HarborIntegration|Use Harbor as this project's container registry."
+msgstr ""
+
msgid "Hashed Storage must be enabled to use Geo"
msgstr ""
@@ -18009,6 +18329,9 @@ msgstr ""
msgid "Hide shared projects"
msgstr ""
+msgid "Hide thread"
+msgstr ""
+
msgid "Hide tooltips or popovers"
msgstr ""
@@ -18158,9 +18481,6 @@ msgstr ""
msgid "I forgot my password"
msgstr ""
-msgid "I understand the responsibilities involved with managing service account keys"
-msgstr ""
-
msgid "I want to explore GitLab to see if it’s worth switching to"
msgstr ""
@@ -18275,6 +18595,9 @@ msgstr ""
msgid "IdentityVerification|Verify your identity"
msgstr ""
+msgid "IdentityVerification|You can always verify your account at a later time to create a group."
+msgstr ""
+
msgid "If any indexed field exceeds this limit, it is truncated to this number of characters. The rest of the content is neither indexed nor searchable. This does not apply to repository and wiki indexing. For unlimited characters, set this to 0."
msgstr ""
@@ -18465,12 +18788,6 @@ 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 ""
@@ -18480,9 +18797,6 @@ msgstr ""
msgid "Import project from"
msgstr ""
-msgid "Import project members"
-msgstr ""
-
msgid "Import projects from Bitbucket"
msgstr ""
@@ -19202,6 +19516,9 @@ msgstr ""
msgid "IncidentManagement|Achieved SLA"
msgstr ""
+msgid "IncidentManagement|Acknowledged"
+msgstr ""
+
msgid "IncidentManagement|All"
msgstr ""
@@ -19211,6 +19528,15 @@ msgstr ""
msgid "IncidentManagement|All alerts promoted to incidents are automatically displayed within the list. You can also create a new incident using the button below."
msgstr ""
+msgid "IncidentManagement|An error occurred while fetching the incident status. Please reload the page."
+msgstr ""
+
+msgid "IncidentManagement|An error occurred while updating the incident status. Please reload the page and try again."
+msgstr ""
+
+msgid "IncidentManagement|Assign paging status"
+msgstr ""
+
msgid "IncidentManagement|Assignees"
msgstr ""
@@ -19250,6 +19576,9 @@ msgstr ""
msgid "IncidentManagement|No incidents to display."
msgstr ""
+msgid "IncidentManagement|None"
+msgstr ""
+
msgid "IncidentManagement|Open"
msgstr ""
@@ -19265,9 +19594,18 @@ msgstr ""
msgid "IncidentManagement|Published to status page"
msgstr ""
+msgid "IncidentManagement|Resolved"
+msgstr ""
+
+msgid "IncidentManagement|Setting the status to Acknowledged or Resolved stops paging when escalation policies are selected for the incident."
+msgstr ""
+
msgid "IncidentManagement|Severity"
msgstr ""
+msgid "IncidentManagement|Status"
+msgstr ""
+
msgid "IncidentManagement|There are no closed incidents"
msgstr ""
@@ -19277,6 +19615,9 @@ msgstr ""
msgid "IncidentManagement|Time to SLA"
msgstr ""
+msgid "IncidentManagement|Triggered"
+msgstr ""
+
msgid "IncidentManagement|Unassigned"
msgstr ""
@@ -19358,6 +19699,9 @@ msgstr ""
msgid "Incidents|There was an issue uploading your image."
msgstr ""
+msgid "Incident|Add new timeline event"
+msgstr ""
+
msgid "Incident|Alert details"
msgstr ""
@@ -19379,6 +19723,9 @@ msgstr ""
msgid "Incident|Metrics"
msgstr ""
+msgid "Incident|No timeline items have been added yet."
+msgstr ""
+
msgid "Incident|Summary"
msgstr ""
@@ -19388,6 +19735,9 @@ msgstr ""
msgid "Incident|There was an issue loading incident data. Please try again."
msgstr ""
+msgid "Incident|Timeline"
+msgstr ""
+
msgid "Include author name in notification email body"
msgstr ""
@@ -19496,6 +19846,12 @@ msgstr ""
msgid "Inherited:"
msgstr ""
+msgid "Initial default branch name"
+msgstr ""
+
+msgid "Initial default branch protection"
+msgstr ""
+
msgid "Inline"
msgstr ""
@@ -19654,6 +20010,9 @@ msgstr ""
msgid "Integrations|Comment settings:"
msgstr ""
+msgid "Integrations|Connection details"
+msgstr ""
+
msgid "Integrations|Connection failed. Please check your settings."
msgstr ""
@@ -19693,6 +20052,9 @@ msgstr ""
msgid "Integrations|Failed to load namespaces. Please try again."
msgstr ""
+msgid "Integrations|Failed to sign in to GitLab."
+msgstr ""
+
msgid "Integrations|Failed to unlink namespace. Please try again."
msgstr ""
@@ -19807,7 +20169,7 @@ msgstr ""
msgid "Integrations|Use default settings"
msgstr ""
-msgid "Integrations|When you mention a Jira issue in a commit or merge request, GitLab creates a remote link and comment (if enabled)."
+msgid "Integrations|You can close this window."
msgstr ""
msgid "Integrations|You can now close this window and return to the GitLab for Jira application."
@@ -19975,9 +20337,6 @@ msgstr ""
msgid "Invitation declined"
msgstr ""
-msgid "Invite"
-msgstr ""
-
msgid "Invite \"%{email}\" by email"
msgstr ""
@@ -19993,12 +20352,6 @@ msgstr ""
msgid "Invite email has already been taken"
msgstr ""
-msgid "Invite group"
-msgstr ""
-
-msgid "Invite member"
-msgstr ""
-
msgid "Invite members"
msgstr ""
@@ -20314,9 +20667,6 @@ msgstr ""
msgid "Issue weight"
msgstr ""
-msgid "Issue(s) already assigned"
-msgstr ""
-
msgid "IssueAnalytics|Age"
msgstr ""
@@ -20359,7 +20709,7 @@ msgstr ""
msgid "IssueBoards|No matching boards found"
msgstr ""
-msgid "IssueBoards|Some of your boards are hidden, activate a license to see them again."
+msgid "IssueBoards|Some of your boards are hidden, add a license to see them again."
msgstr ""
msgid "IssueBoards|Switch board"
@@ -20773,13 +21123,13 @@ msgstr ""
msgid "JiraService|Define the type of Jira issue to create from a vulnerability."
msgstr ""
-msgid "JiraService|Displaying Jira issues while leaving the GitLab issue functionality enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
+msgid "JiraService|Displaying Jira issues while leaving GitLab issues also enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
msgstr ""
-msgid "JiraService|Enable Jira issues"
+msgid "JiraService|Enable Jira issue creation from vulnerabilities"
msgstr ""
-msgid "JiraService|Enable Jira issues creation from vulnerabilities"
+msgid "JiraService|Enable Jira issues"
msgstr ""
msgid "JiraService|Enable Jira transitions"
@@ -20896,16 +21246,22 @@ msgstr ""
msgid "JiraService|View Jira issues in GitLab"
msgstr ""
-msgid "JiraService|Warning: All GitLab users that have access to this GitLab project are able to view all issues from the Jira project specified below."
+msgid "JiraService|Warning: All GitLab users with access to this GitLab project can view all issues from the Jira project you select."
msgstr ""
msgid "JiraService|Web URL"
msgstr ""
-msgid "JiraService|Work on Jira issues without leaving GitLab. Adds a Jira menu to access your list of Jira issues and view any issue as read-only."
+msgid "JiraService|When a Jira issue is mentioned in a commit or merge request, a remote link and comment (if enabled) will be created."
+msgstr ""
+
+msgid "JiraService|Work on Jira issues without leaving GitLab. Add a Jira menu to access a read-only list of your Jira issues."
msgstr ""
-msgid "JiraService|You need to configure Jira before enabling this integration. For more details, read the %{jira_doc_link_start}Jira integration documentation%{link_end}."
+msgid "JiraService|Work on Jira issues without leaving GitLab. Add a Jira menu to access a read-only list of your Jira issues. %{jira_issues_link_start}Learn more.%{link_end}"
+msgstr ""
+
+msgid "JiraService|You must configure Jira before enabling this integration. %{jira_doc_link_start}Learn more.%{link_end}"
msgstr ""
msgid "Job"
@@ -20917,9 +21273,6 @@ msgstr ""
msgid "Job Failed #%{build_id}"
msgstr ""
-msgid "Job ID"
-msgstr ""
-
msgid "Job artifact"
msgstr ""
@@ -20986,9 +21339,27 @@ msgstr ""
msgid "Jobs|You're about to retry a job that failed because it attempted to deploy code that is older than the latest deployment. Retrying this job could result in overwriting the environment with the older source code."
msgstr ""
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source} into %{target}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{ref}"
+msgstr ""
+
+msgid "Job|Are you sure you want to erase this job log and artifacts?"
+msgstr ""
+
msgid "Job|Browse"
msgstr ""
+msgid "Job|Cancel"
+msgstr ""
+
msgid "Job|Complete Raw"
msgstr ""
@@ -21013,7 +21384,7 @@ msgstr ""
msgid "Job|Keep"
msgstr ""
-msgid "Job|Pipeline"
+msgid "Job|Retry"
msgstr ""
msgid "Job|Scroll to bottom"
@@ -21055,21 +21426,12 @@ msgstr ""
msgid "Job|delayed"
msgstr ""
-msgid "Job|for"
-msgstr ""
-
-msgid "Job|into"
-msgstr ""
-
msgid "Job|manual"
msgstr ""
msgid "Job|triggered"
msgstr ""
-msgid "Job|with"
-msgstr ""
-
msgid "Join Zoom meeting"
msgstr ""
@@ -21417,6 +21779,9 @@ msgstr ""
msgid "Last updated"
msgstr ""
+msgid "Last updated %{time} ago"
+msgstr ""
+
msgid "Last used"
msgstr ""
@@ -21525,6 +21890,12 @@ msgstr ""
msgid "Learn more about groups."
msgstr ""
+msgid "Learn more about max seats used"
+msgstr ""
+
+msgid "Learn more about seats owed"
+msgstr ""
+
msgid "Learn more about shards and replicas in the %{configuration_link_start}Advanced Search configuration%{configuration_link_end} documentation. Changes don't take place until you %{recreated_link_start}recreate%{recreated_link_end} the index."
msgstr ""
@@ -21666,6 +22037,9 @@ msgstr ""
msgid "Legacy burndown chart"
msgstr ""
+msgid "Less Details"
+msgstr ""
+
msgid "Let's Encrypt does not accept emails on example.com"
msgstr ""
@@ -21891,11 +22265,6 @@ msgstr ""
msgid "Limit the size of Sidekiq jobs stored in Redis."
msgstr ""
-msgid "Limited to showing %d event at most"
-msgid_plural "Limited to showing %d events at most"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Limiting mode"
msgstr ""
@@ -21974,6 +22343,9 @@ msgstr ""
msgid "List of all merge commits"
msgstr ""
+msgid "List of suitable GCP locations"
+msgstr ""
+
msgid "List of users allowed to exceed the rate limit."
msgstr ""
@@ -22343,6 +22715,12 @@ msgstr ""
msgid "MarkdownEditor|Add italic text (%{modifier_key}I)"
msgstr ""
+msgid "MarkdownEditor|Add strikethrough text (%{modifierKey}⇧X)"
+msgstr ""
+
+msgid "MarkdownEditor|Add strikethrough text (%{modifier_key}⇧X)"
+msgstr ""
+
msgid "Marked For Deletion At - %{deletion_time}"
msgstr ""
@@ -22433,6 +22811,9 @@ msgstr ""
msgid "Max role"
msgstr ""
+msgid "Max seats used"
+msgstr ""
+
msgid "Max session time"
msgstr ""
@@ -22553,9 +22934,6 @@ 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 lines in a diff"
msgstr ""
@@ -22577,6 +22955,12 @@ msgstr ""
msgid "Maximum number of projects."
msgstr ""
+msgid "Maximum number of requests per minute for an authenticated user"
+msgstr ""
+
+msgid "Maximum number of requests per minute for an unauthenticated IP address"
+msgstr ""
+
msgid "Maximum number of requests per minute for each raw path (default is 300). Set to 0 to disable throttling."
msgstr ""
@@ -22812,9 +23196,6 @@ msgstr ""
msgid "Member|Deny access"
msgstr ""
-msgid "Member|Remove member"
-msgstr ""
-
msgid "Member|Revoke invite"
msgstr ""
@@ -22851,7 +23232,7 @@ msgstr ""
msgid "Merge automatically (%{strategy})"
msgstr ""
-msgid "Merge blocked: all merge request dependencies must be merged or closed."
+msgid "Merge blocked: all merge request dependencies must be merged."
msgstr ""
msgid "Merge blocked: merge request must be marked as ready. It's still marked as draft."
@@ -22908,13 +23289,13 @@ msgstr ""
msgid "Merge request dependencies"
msgstr ""
-msgid "Merge request events"
+msgid "Merge request diff sha parameter is required for the merge quick action."
msgstr ""
-msgid "Merge request not merged"
+msgid "Merge request events"
msgstr ""
-msgid "Merge request pipelines 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 merge request pipelines."
+msgid "Merge request not merged"
msgstr ""
msgid "Merge request reports"
@@ -22929,7 +23310,7 @@ 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 the branch and fix any conflicts that come up"
+msgid "Merge the feature branch into the target branch and fix any conflicts. %{linkStart}How do I fix them?%{linkEnd}"
msgstr ""
msgid "Merge unavailable: merge requests are read-only in a secondary Geo node."
@@ -23764,6 +24145,9 @@ msgstr ""
msgid "Months"
msgstr ""
+msgid "More Details"
+msgstr ""
+
msgid "More Information"
msgstr ""
@@ -23976,6 +24360,33 @@ msgstr ""
msgid "NamespaceStorageSize|push to your repository, create pipelines, create issues or add comments. To reduce storage capacity, delete unused repositories, artifacts, wikis, issues, and pipelines."
msgstr ""
+msgid "NamespaceStorage|%{name_with_link} namespace has %{percent} or less namespace storage space remaining."
+msgstr ""
+
+msgid "NamespaceStorage|%{name_with_link} namespace has exceeded its namespace storage limit."
+msgstr ""
+
+msgid "NamespaceStorage|%{name}(%{url}) namespace has %{percent} or less namespace storage space remaining."
+msgstr ""
+
+msgid "NamespaceStorage|%{name}(%{url}) namespace has exceeded its namespace storage limit."
+msgstr ""
+
+msgid "NamespaceStorage|Action required: Less than %{percentage_of_available_storage}%% of namespace storage remains for %{namespace_name}"
+msgstr ""
+
+msgid "NamespaceStorage|Action required: Storage has been exceeded for %{namespace_name}"
+msgstr ""
+
+msgid "NamespaceStorage|Buy more storage"
+msgstr ""
+
+msgid "NamespaceStorage|We recommend that you buy additional storage to ensure your service is not interrupted."
+msgstr ""
+
+msgid "NamespaceStorage|We recommend that you buy additional storage to resume normal service."
+msgstr ""
+
msgid "NamespaceUserCap|Pending users must be reviewed and approved by a group owner. Learn more about %{user_caps_link_start}user caps%{link_end} and %{users_pending_approval_link_start}users pending approval%{link_end}."
msgstr ""
@@ -24051,6 +24462,9 @@ msgstr ""
msgid "Need help?"
msgstr ""
+msgid "Need your attention"
+msgstr ""
+
msgid "Needs"
msgstr ""
@@ -24237,9 +24651,6 @@ msgstr ""
msgid "New"
msgstr ""
-msgid "New %{issueType}"
-msgstr ""
-
msgid "New %{type} in %{project}"
msgstr ""
@@ -24407,6 +24818,9 @@ msgstr ""
msgid "New public deploy key"
msgstr ""
+msgid "New related %{issueType}"
+msgstr ""
+
msgid "New release"
msgstr ""
@@ -24422,9 +24836,6 @@ msgstr ""
msgid "New schedule"
msgstr ""
-msgid "New service account is generated for the selected Google Cloud project"
-msgstr ""
-
msgid "New snippet"
msgstr ""
@@ -24473,6 +24884,9 @@ msgstr ""
msgid "Next unresolved discussion"
msgstr ""
+msgid "Next update"
+msgstr ""
+
msgid "Nickname"
msgstr ""
@@ -24521,13 +24935,13 @@ msgstr ""
msgid "No assignee"
msgstr ""
-msgid "No authentication methods configured."
+msgid "No attention request"
msgstr ""
-msgid "No available branches"
+msgid "No authentication methods configured."
msgstr ""
-msgid "No available groups to fork the project."
+msgid "No available branches"
msgstr ""
msgid "No branches found"
@@ -24551,12 +24965,6 @@ msgstr ""
msgid "No committers"
msgstr ""
-msgid "No compliance frameworks are in use."
-msgstr ""
-
-msgid "No compliance frameworks are in use. Create one from the %{link} section in Group Settings."
-msgstr ""
-
msgid "No confirmation email received? Check your spam folder or %{request_link_start}request new confirmation email%{request_link_end}."
msgstr ""
@@ -24659,7 +25067,7 @@ msgstr ""
msgid "No matches found"
msgstr ""
-msgid "No matching issue found. Make sure that you are adding a valid issue URL."
+msgid "No matching %{issuable} found. Make sure that you are adding a valid %{issuable} URL."
msgstr ""
msgid "No matching labels"
@@ -24740,6 +25148,9 @@ msgstr ""
msgid "No ref selected"
msgstr ""
+msgid "No regions configured"
+msgstr ""
+
msgid "No related merge requests found."
msgstr ""
@@ -24773,6 +25184,9 @@ msgstr ""
msgid "No start date"
msgstr ""
+msgid "No suggestions found"
+msgstr ""
+
msgid "No tag selected"
msgstr ""
@@ -25517,6 +25931,9 @@ msgstr ""
msgid "Only admins can delete project"
msgstr ""
+msgid "Only allow anyone to register for accounts on GitLab instances that you intend to be used by anyone. Allowing anyone to register makes GitLab instances more vulnerable."
+msgstr ""
+
msgid "Only effective when remote storage is enabled. Set to 0 for no size limit."
msgstr ""
@@ -25535,15 +25952,15 @@ msgstr ""
msgid "Only project members can comment."
msgstr ""
-msgid "Only project members will be imported. Group members will be skipped."
-msgstr ""
-
msgid "Only projects created under a Ultimate license are available in Security Dashboards."
msgstr ""
msgid "Only reCAPTCHA v2 is supported:"
msgstr ""
+msgid "Only required if not using role instance credentials."
+msgstr ""
+
msgid "Only use lowercase letters, numbers, and underscores."
msgstr ""
@@ -25568,10 +25985,10 @@ msgstr ""
msgid "Open a CLI and connect to the cluster you want to install the agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
-msgid "Open epics"
+msgid "Open errors"
msgstr ""
-msgid "Open errors"
+msgid "Open in Gitpod"
msgstr ""
msgid "Open in Web IDE"
@@ -25586,9 +26003,6 @@ msgstr ""
msgid "Open raw"
msgstr ""
-msgid "Open registration is enabled on your instance."
-msgstr ""
-
msgid "Open sidebar"
msgstr ""
@@ -25616,6 +26030,9 @@ msgstr ""
msgid "Opens in a new window"
msgstr ""
+msgid "Opens new window"
+msgstr ""
+
msgid "Operation failed. Check pod logs for %{pod_name} for more details."
msgstr ""
@@ -25757,6 +26174,9 @@ msgstr ""
msgid "Owner"
msgstr ""
+msgid "Owners can modify this selection."
+msgstr ""
+
msgid "PQL|An error occurred while sending hand raise lead."
msgstr ""
@@ -26479,9 +26899,6 @@ msgstr ""
msgid "PerformanceBar|wall"
msgstr ""
-msgid "Performs a rebase but skips triggering a new pipeline"
-msgstr ""
-
msgid "Period in seconds"
msgstr ""
@@ -26764,12 +27181,21 @@ msgstr ""
msgid "PipelineWizardDefaultCommitMessage|Update %{filename}"
msgstr ""
+msgid "PipelineWizardInputValidation|At least one entry is required"
+msgstr ""
+
msgid "PipelineWizardInputValidation|This field is required"
msgstr ""
msgid "PipelineWizardInputValidation|This value is not valid"
msgstr ""
+msgid "PipelineWizardListWidget|add another step"
+msgstr ""
+
+msgid "PipelineWizardListWidget|remove step"
+msgstr ""
+
msgid "PipelineWizard|Commit"
msgstr ""
@@ -26794,6 +27220,9 @@ msgstr ""
msgid "PipelineWizard|There was a problem while checking whether your file already exists in the specified branch."
msgstr ""
+msgid "PipelineWizard|There was an unexpected error trying to set up the template. The error has been logged."
+msgstr ""
+
msgid "Pipelines"
msgstr ""
@@ -26803,10 +27232,13 @@ msgstr ""
msgid "Pipelines settings for '%{project_name}' were successfully updated."
msgstr ""
-msgid "Pipelines|API"
+msgid "Pipelines|\"Hello world\" with GitLab CI"
+msgstr ""
+
+msgid "Pipelines|A GitLab Runner is an application that works with GitLab CI/CD to run jobs in a pipeline. Install GitLab Runner and register your own runners to get started with CI/CD."
msgstr ""
-msgid "Pipelines|Add a code quality job"
+msgid "Pipelines|API"
msgstr ""
msgid "Pipelines|Are you sure you want to run this pipeline?"
@@ -26854,7 +27286,7 @@ msgstr ""
msgid "Pipelines|Editor"
msgstr ""
-msgid "Pipelines|Get familiar with GitLab CI/CD syntax by starting with a basic 3 stage CI/CD pipeline."
+msgid "Pipelines|Get familiar with GitLab CI syntax by setting up a simple pipeline running a \"Hello world\" script to see how it runs, explore how CI/CD works."
msgstr ""
msgid "Pipelines|Get started with GitLab CI/CD"
@@ -26863,13 +27295,13 @@ msgstr ""
msgid "Pipelines|GitLab CI/CD can automatically build, test, and deploy your code. Let GitLab take care of time consuming tasks, so you can spend more time creating."
msgstr ""
-msgid "Pipelines|If you are unsure, please ask a project maintainer to review it for you."
+msgid "Pipelines|GitLab Runner is an application that works with GitLab CI/CD to run jobs in a pipeline. There are active runners available to run your jobs right now. If you prefer, you can %{settingsLinkStart}configure your runners%{settingsLinkEnd} or %{docsLinkStart}learn more%{docsLinkEnd} about runners."
msgstr ""
-msgid "Pipelines|Improve code quality with GitLab CI/CD"
+msgid "Pipelines|If you are unsure, please ask a project maintainer to review it for you."
msgstr ""
-msgid "Pipelines|Install GitLab Runners"
+msgid "Pipelines|Install GitLab Runner"
msgstr ""
msgid "Pipelines|It is recommended the code is reviewed thoroughly before running this pipeline with the parent project's CI resource."
@@ -26878,7 +27310,7 @@ msgstr ""
msgid "Pipelines|Last Used"
msgstr ""
-msgid "Pipelines|Learn about Runners"
+msgid "Pipelines|Learn the basics of pipelines and .yml files"
msgstr ""
msgid "Pipelines|Lint"
@@ -26896,6 +27328,9 @@ msgstr ""
msgid "Pipelines|More Information"
msgstr ""
+msgid "Pipelines|No runners detected"
+msgstr ""
+
msgid "Pipelines|No triggers have been created yet. Add one using the form above."
msgstr ""
@@ -26908,7 +27343,13 @@ msgstr ""
msgid "Pipelines|Project cache successfully reset."
msgstr ""
-msgid "Pipelines|Revoke"
+msgid "Pipelines|Ready to set up CI/CD for your project?"
+msgstr ""
+
+msgid "Pipelines|Revoke trigger"
+msgstr ""
+
+msgid "Pipelines|Runners are available to run your jobs now"
msgstr ""
msgid "Pipelines|Something went wrong while cleaning runners cache."
@@ -26953,13 +27394,16 @@ msgstr ""
msgid "Pipelines|This is a child pipeline within the parent pipeline"
msgstr ""
-msgid "Pipelines|This pipeline will run code originating from a forked project merge request. This means that the code can potentially have security considerations like exposing CI variables."
+msgid "Pipelines|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
msgstr ""
-msgid "Pipelines|This project is not currently set up to run pipelines."
+msgid "Pipelines|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
+msgid "Pipelines|This pipeline will run code originating from a forked project merge request. This means that the code can potentially have security considerations like exposing CI variables."
msgstr ""
-msgid "Pipelines|To keep your codebase simple, readable, and accessible to contributors, use GitLab CI/CD to analyze your code quality with every push to your project."
+msgid "Pipelines|This project is not currently set up to run pipelines."
msgstr ""
msgid "Pipelines|Token"
@@ -26968,15 +27412,12 @@ msgstr ""
msgid "Pipelines|Trigger user has insufficient permissions to project"
msgstr ""
-msgid "Pipelines|Use a CI/CD template"
+msgid "Pipelines|Try test template"
msgstr ""
msgid "Pipelines|Use a sample %{codeStart}.gitlab-ci.yml%{codeEnd} template file to explore how CI/CD works."
msgstr ""
-msgid "Pipelines|Use a sample CI/CD template"
-msgstr ""
-
msgid "Pipelines|Use a template based on your project's language or framework to get started with GitLab CI/CD."
msgstr ""
@@ -26995,9 +27436,6 @@ msgstr ""
msgid "Pipelines|Your changes have been successfully committed. Now redirecting to the new merge request page."
msgstr ""
-msgid "Pipelines|detached"
-msgstr ""
-
msgid "Pipelines|error"
msgstr ""
@@ -27007,10 +27445,13 @@ msgstr ""
msgid "Pipelines|latest"
msgstr ""
-msgid "Pipelines|stuck"
+msgid "Pipelines|merge request"
msgstr ""
-msgid "Pipelines|train"
+msgid "Pipelines|merge train"
+msgstr ""
+
+msgid "Pipelines|stuck"
msgstr ""
msgid "Pipelines|yaml invalid"
@@ -27034,9 +27475,6 @@ msgstr ""
msgid "Pipeline|Checking pipeline status."
msgstr ""
-msgid "Pipeline|Commit"
-msgstr ""
-
msgid "Pipeline|Could not retrieve the pipeline status. For troubleshooting steps, read the %{linkStart}documentation%{linkEnd}."
msgstr ""
@@ -27052,9 +27490,6 @@ msgstr ""
msgid "Pipeline|Detached merge request pipeline"
msgstr ""
-msgid "Pipeline|Duration"
-msgstr ""
-
msgid "Pipeline|Failed"
msgstr ""
@@ -27142,6 +27577,12 @@ msgstr ""
msgid "Pipeline|This change will not change the overall test coverage if merged."
msgstr ""
+msgid "Pipeline|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipeline|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipeline|Trigger author"
msgstr ""
@@ -27166,6 +27607,12 @@ msgstr ""
msgid "Pipeline|for"
msgstr ""
+msgid "Pipeline|merge request"
+msgstr ""
+
+msgid "Pipeline|merge train"
+msgstr ""
+
msgid "Pipeline|on"
msgstr ""
@@ -27433,12 +27880,15 @@ 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."
+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. Each URL and link title must be unique."
msgstr ""
msgid "Policies"
msgstr ""
+msgid "Policy '%{escalation_policy_name}' does not exist."
+msgstr ""
+
msgid "Policy management project does have any policies in %{policy_path}"
msgstr ""
@@ -27475,7 +27925,7 @@ msgstr ""
msgid "Potentially unwanted character detected: Unicode BiDi Control"
msgstr ""
-msgid "Pre-defined push rules."
+msgid "Pre-defined push rules"
msgstr ""
msgid "Preferences"
@@ -27583,6 +28033,9 @@ msgstr ""
msgid "Preferences|When you type in a description or comment box, selected text is surrounded by the corresponding character after typing one of the following characters: %{supported_characters}."
msgstr ""
+msgid "Preparing the report for the scan."
+msgstr ""
+
msgid "Prev"
msgstr ""
@@ -28396,6 +28849,9 @@ msgstr ""
msgid "ProjectQualitySummary|Failure"
msgstr ""
+msgid "ProjectQualitySummary|Get insight into the overall percentage of tests in your project that succeed, fail and are skipped."
+msgstr ""
+
msgid "ProjectQualitySummary|Latest pipeline results"
msgstr ""
@@ -28414,6 +28870,12 @@ msgstr ""
msgid "ProjectQualitySummary|See project Code Coverage Statistics"
msgstr ""
+msgid "ProjectQualitySummary|Set up test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|Set up test runs (opens in a new tab)"
+msgstr ""
+
msgid "ProjectQualitySummary|Skipped"
msgstr ""
@@ -28735,6 +29197,9 @@ msgstr ""
msgid "ProjectSettings|Merge suggestions"
msgstr ""
+msgid "ProjectSettings|Merging is only allowed when the source branch is up-to-date with its target."
+msgstr ""
+
msgid "ProjectSettings|No merge commits are created."
msgstr ""
@@ -28906,6 +29371,9 @@ msgstr ""
msgid "ProjectSettings|When merge request pipelines are enabled in the CI/CD configuration file, pipelines validate the combined results of the source and target branches. %{link_start}How to configure merge request pipelines?%{link_end}"
msgstr ""
+msgid "ProjectSettings|When semi-linear merge is not possible, the user is given the option to rebase."
+msgstr ""
+
msgid "ProjectSettings|When there is a merge conflict, the user is given the option to rebase."
msgstr ""
@@ -29122,6 +29590,9 @@ msgstr ""
msgid "ProjectsNew|Import project"
msgstr ""
+msgid "ProjectsNew|Include a Getting Started README"
+msgstr ""
+
msgid "ProjectsNew|Initialize repository with a README"
msgstr ""
@@ -29137,6 +29608,9 @@ msgstr ""
msgid "ProjectsNew|Project description %{tag_start}(optional)%{tag_end}"
msgstr ""
+msgid "ProjectsNew|Recommended if you're new to GitLab"
+msgstr ""
+
msgid "ProjectsNew|Run CI/CD for external repository"
msgstr ""
@@ -29737,7 +30211,10 @@ msgstr ""
msgid "Push project from command line"
msgstr ""
-msgid "Push the result of the merge to GitLab"
+msgid "Push rules"
+msgstr ""
+
+msgid "Push the target branch up to GitLab."
msgstr ""
msgid "Push to create a project"
@@ -29836,9 +30313,6 @@ msgstr ""
msgid "QualitySummary|Project quality"
msgstr ""
-msgid "Quarters"
-msgstr ""
-
msgid "Query"
msgstr ""
@@ -29956,10 +30430,7 @@ msgstr ""
msgid "Rebase source branch on the target branch."
msgstr ""
-msgid "Rebase without CI"
-msgstr ""
-
-msgid "Rebases and triggers a pipeline"
+msgid "Rebase without pipeline"
msgstr ""
msgid "Recaptcha verified?"
@@ -30069,6 +30540,12 @@ msgstr ""
msgid "Regex pattern"
msgstr ""
+msgid "Region"
+msgstr ""
+
+msgid "Regions"
+msgstr ""
+
msgid "Register"
msgstr ""
@@ -30168,9 +30645,15 @@ msgstr ""
msgid "Reindexing Status: %{status} (Slice multiplier: %{multiplier}, Maximum running slices: %{max_slices})"
msgstr ""
+msgid "Reject"
+msgstr ""
+
msgid "Rejected (closed)"
msgstr ""
+msgid "Relate to %{issuable_type} %{add_related_issue_link}"
+msgstr ""
+
msgid "Related feature flags"
msgstr ""
@@ -30180,9 +30663,6 @@ msgstr ""
msgid "Related merge requests"
msgstr ""
-msgid "Related to #%{issue_id}."
-msgstr ""
-
msgid "Relates to"
msgstr ""
@@ -30623,6 +31103,12 @@ msgstr ""
msgid "Report abuse to admin"
msgstr ""
+msgid "Report couldn't be prepared."
+msgstr ""
+
+msgid "Report for the scan has been removed from the database."
+msgstr ""
+
msgid "Reported %{timeAgo} by %{reportedBy}"
msgstr ""
@@ -30708,6 +31194,9 @@ msgstr ""
msgid "Reports|Identifier"
msgstr ""
+msgid "Reports|Metrics report scanning detected no new changes"
+msgstr ""
+
msgid "Reports|Metrics reports are loading"
msgstr ""
@@ -30720,6 +31209,12 @@ msgstr ""
msgid "Reports|Metrics reports failed loading results"
msgstr ""
+msgid "Reports|Metrics reports failed to load results"
+msgstr ""
+
+msgid "Reports|Metrics reports: %{strong_start}%{numberOfChanges}%{strong_end} %{changes}"
+msgstr ""
+
msgid "Reports|Scanner"
msgstr ""
@@ -31248,7 +31743,7 @@ msgstr ""
msgid "Review requests for you"
msgstr ""
-msgid "Review the changes locally"
+msgid "Review the changes locally."
msgstr ""
msgid "Review the process for configuring service providers in your identity provider — in this case, GitLab is the \"service provider\" or \"relying party\"."
@@ -31310,9 +31805,6 @@ msgstr ""
msgid "RightSidebar|deleting the"
msgstr ""
-msgid "Rnners|Don't see what you are looking for? See the full list of options, including a fully customizable option, %{linkStart}here%{linkEnd}."
-msgstr ""
-
msgid "Roadmap"
msgstr ""
@@ -31364,10 +31856,10 @@ msgstr ""
msgid "Runner API"
msgstr ""
-msgid "Runner tokens"
+msgid "Runner cannot be deleted, please contact your administrator."
msgstr ""
-msgid "Runner was not deleted because it is assigned to multiple projects."
+msgid "Runner tokens"
msgstr ""
msgid "Runner was not updated."
@@ -31388,6 +31880,12 @@ msgstr ""
msgid "Runners page."
msgstr ""
+msgid "Runners|%{percentage} spot."
+msgstr ""
+
+msgid "Runners|A capacity of 1 enables warm HA through Auto Scaling group re-spawn. A capacity of 2 enables hot HA because the service is available even when a node is lost. A capacity of 3 or more enables hot HA and manual scaling of runner fleet."
+msgstr ""
+
msgid "Runners|Active"
msgstr ""
@@ -31397,7 +31895,7 @@ msgstr ""
msgid "Runners|Amazon Linux 2 Docker HA with manual scaling and optional scheduling. %{percentage} spot."
msgstr ""
-msgid "Runners|Amazon Linux 2 Docker HA with manual scaling and optional scheduling. Non-spot. Default choice for Linux Docker executor."
+msgid "Runners|Amazon Linux 2 Docker HA with manual scaling and optional scheduling. Non-spot."
msgstr ""
msgid "Runners|An error has occurred fetching instructions"
@@ -31424,9 +31922,15 @@ msgstr ""
msgid "Runners|Can run untagged jobs"
msgstr ""
+msgid "Runners|Capacity of 1 enables warm HA through Auto Scaling group re-spawn. Capacity of 2 enables hot HA because the service is available even when a node is lost. Capacity of 3 or more enables hot HA and manual scaling of runner fleet."
+msgstr ""
+
msgid "Runners|Change to project runner"
msgstr ""
+msgid "Runners|Choose your preferred GitLab Runner"
+msgstr ""
+
msgid "Runners|Command to register runner"
msgstr ""
@@ -31454,6 +31958,9 @@ msgstr ""
msgid "Runners|Details"
msgstr ""
+msgid "Runners|Don't see what you are looking for? See the full list of options, including a fully customizable option %{linkStart}here%{linkEnd}."
+msgstr ""
+
msgid "Runners|Download and install binary"
msgstr ""
@@ -31463,18 +31970,12 @@ msgstr ""
msgid "Runners|Enter the number of seconds. This timeout takes precedence over lower timeouts set for the project."
msgstr ""
-msgid "Runners|For each solution, you will choose a capacity. 1 enables warm HA through Auto Scaling group re-spawn. 2 enables hot HA because the service is available even when a node is lost. 3 or more enables hot HA and manual scaling of runner fleet."
-msgstr ""
-
msgid "Runners|Group"
msgstr ""
msgid "Runners|IP Address"
msgstr ""
-msgid "Runners|If you do not select an AWS VPC, the runner will deploy to the Default VPC in the AWS Region you select. Please consult with your AWS administrator to understand if there are any security risks to deploying into the Default VPC in any given region in your AWS account."
-msgstr ""
-
msgid "Runners|Install a runner"
msgstr ""
@@ -31502,6 +32003,9 @@ msgstr ""
msgid "Runners|Never contacted"
msgstr ""
+msgid "Runners|New group runners view"
+msgstr ""
+
msgid "Runners|New registration token generated!"
msgstr ""
@@ -31514,7 +32018,13 @@ msgstr ""
msgid "Runners|No recent contact from this runner; last contact was %{timeAgo}"
msgstr ""
-msgid "Runners|Not available to run jobs"
+msgid "Runners|No spot. Default choice for Windows Shell executor."
+msgstr ""
+
+msgid "Runners|No spot. This is the default choice for Linux Docker executor."
+msgstr ""
+
+msgid "Runners|Not accepting jobs"
msgstr ""
msgid "Runners|Offline"
@@ -31529,6 +32039,9 @@ msgstr ""
msgid "Runners|Online runners"
msgstr ""
+msgid "Runners|Pause from accepting jobs"
+msgstr ""
+
msgid "Runners|Paused"
msgstr ""
@@ -31565,9 +32078,15 @@ msgstr ""
msgid "Runners|Reset token"
msgstr ""
+msgid "Runners|Resume accepting jobs"
+msgstr ""
+
msgid "Runners|Revision"
msgstr ""
+msgid "Runners|Rocket launch illustration"
+msgstr ""
+
msgid "Runners|Runner"
msgstr ""
@@ -31604,6 +32123,9 @@ msgstr ""
msgid "Runners|Runs untagged jobs"
msgstr ""
+msgid "Runners|Select your preferred option here. In the next step, you can choose the capacity for your runner in the AWS CloudFormation console."
+msgstr ""
+
msgid "Runners|Shared runners are available to every project in a GitLab instance. If you want a runner to build only specific projects, restrict the project in the table below. After you restrict a runner to a project, you cannot change it back to a shared runner."
msgstr ""
@@ -31634,6 +32156,12 @@ msgstr ""
msgid "Runners|Tags"
msgstr ""
+msgid "Runners|Take me there!"
+msgstr ""
+
+msgid "Runners|The new view gives you more space and better visibility into your fleet of runners."
+msgstr ""
+
msgid "Runners|The runner will be permanently deleted and no longer available for projects or groups in the instance. Are you sure you want to continue?"
msgstr ""
@@ -31679,7 +32207,7 @@ msgstr ""
msgid "Runners|Windows 2019 Shell with manual scaling and optional scheduling. %{percentage} spot."
msgstr ""
-msgid "Runners|Windows 2019 Shell with manual scaling and optional scheduling. Non-spot. Default choice for Windows Shell executor."
+msgid "Runners|Windows 2019 Shell with manual scaling and optional scheduling. Non-spot."
msgstr ""
msgid "Runners|You are about to change this instance runner to a project runner. This operation is not reversible. Are you sure you want to continue?"
@@ -31841,12 +32369,24 @@ msgstr ""
msgid "Saving project."
msgstr ""
-msgid "ScanResultPolicy|%{thenLabelStart}Then%{thenLabelEnd} Require approval from %{approvalsRequired} of the following approvers: %{approvers}"
+msgid "ScanResultPolicy|%{ifLabelStart}if%{ifLabelEnd} %{scanners} find(s) more than %{vulnerabilitiesAllowed} %{severities} %{vulnerabilityStates} vulnerabilities in an open merge request targeting %{branches}"
+msgstr ""
+
+msgid "ScanResultPolicy|%{thenLabelStart}Then%{thenLabelEnd} Require approval from %{approvalsRequired} of the following approvers:"
msgstr ""
msgid "ScanResultPolicy|add an approver"
msgstr ""
+msgid "ScanResultPolicy|scanners"
+msgstr ""
+
+msgid "ScanResultPolicy|severity levels"
+msgstr ""
+
+msgid "ScanResultPolicy|vulnerability states"
+msgstr ""
+
msgid "Scanner"
msgstr ""
@@ -31979,6 +32519,9 @@ msgstr ""
msgid "Search for a user"
msgstr ""
+msgid "Search for an emoji"
+msgstr ""
+
msgid "Search for projects, issues, etc."
msgstr ""
@@ -32021,6 +32564,9 @@ msgstr ""
msgid "Search projects..."
msgstr ""
+msgid "Search rate limits"
+msgstr ""
+
msgid "Search refs"
msgstr ""
@@ -32145,6 +32691,9 @@ msgstr ""
msgid "Seats"
msgstr ""
+msgid "Seats owed"
+msgstr ""
+
msgid "Seats usage data as of %{last_enqueue_time} (Updated daily)"
msgstr ""
@@ -32166,10 +32715,13 @@ msgstr ""
msgid "Secret Detection"
msgstr ""
-msgid "Secret access key"
+msgid "Secret token"
msgstr ""
-msgid "Secret token"
+msgid "Secure Code Warrior"
+msgstr ""
+
+msgid "Secure Files"
msgstr ""
msgid "Secure token that identifies an external storage request."
@@ -32367,9 +32919,6 @@ msgstr ""
msgid "SecurityOrchestration|.yaml preview"
msgstr ""
-msgid "SecurityOrchestration|Action"
-msgstr ""
-
msgid "SecurityOrchestration|Actions"
msgstr ""
@@ -32403,13 +32952,13 @@ msgstr ""
msgid "SecurityOrchestration|Edit policy project"
msgstr ""
-msgid "SecurityOrchestration|Enabled"
+msgid "SecurityOrchestration|Empty policy name"
msgstr ""
-msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Enabled"
msgstr ""
-msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
msgstr ""
msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
@@ -32418,9 +32967,6 @@ msgstr ""
msgid "SecurityOrchestration|Invalid policy type"
msgstr ""
-msgid "SecurityOrchestration|Latest scan"
-msgstr ""
-
msgid "SecurityOrchestration|Latest scan run against %{agent}"
msgstr ""
@@ -32430,6 +32976,12 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No actions defined - policy will not run."
+msgstr ""
+
+msgid "SecurityOrchestration|No description"
+msgstr ""
+
msgid "SecurityOrchestration|No rules defined - policy will not run."
msgstr ""
@@ -32442,6 +32994,9 @@ msgstr ""
msgid "SecurityOrchestration|Policies"
msgstr ""
+msgid "SecurityOrchestration|Policy Type"
+msgstr ""
+
msgid "SecurityOrchestration|Policy cannot be enabled for non-existing branches (%{branches})"
msgstr ""
@@ -32466,10 +33021,13 @@ msgstr ""
msgid "SecurityOrchestration|Require %{approvals} %{plural} from %{approvers} if any of the following occur:"
msgstr ""
-msgid "SecurityOrchestration|Rule"
+msgid "SecurityOrchestration|Rules"
msgstr ""
-msgid "SecurityOrchestration|Rules"
+msgid "SecurityOrchestration|Runs %{actions} and %{lastAction} scans"
+msgstr ""
+
+msgid "SecurityOrchestration|Runs a %{action} scan"
msgstr ""
msgid "SecurityOrchestration|Scan Execution"
@@ -32544,6 +33102,9 @@ msgstr ""
msgid "SecurityOrchestration|Update scan policies"
msgstr ""
+msgid "SecurityOrchestration|View policy project"
+msgstr ""
+
msgid "SecurityOrchestration|a"
msgstr ""
@@ -32586,9 +33147,6 @@ msgstr ""
msgid "SecurityOrchestration|users with ids"
msgstr ""
-msgid "SecurityOrchestration|view results"
-msgstr ""
-
msgid "SecurityOrchestration|vulnerabilities"
msgstr ""
@@ -32631,6 +33189,9 @@ msgstr ""
msgid "SecurityReports|Change status"
msgstr ""
+msgid "SecurityReports|Check the messages generated while parsing the following security reports, as they may prevent the results from being ingested by GitLab. Ensure the security report conforms to a supported %{helpPageLinkStart}JSON schema%{helpPageLinkEnd}."
+msgstr ""
+
msgid "SecurityReports|Comment added to '%{vulnerabilityName}'"
msgstr ""
@@ -32808,6 +33369,9 @@ msgstr ""
msgid "SecurityReports|Status"
msgstr ""
+msgid "SecurityReports|Submit vulnerability"
+msgstr ""
+
msgid "SecurityReports|Take survey"
msgstr ""
@@ -32817,7 +33381,7 @@ msgstr ""
msgid "SecurityReports|The Vulnerability Report shows the results of the latest successful pipeline on your project's default branch, as well as vulnerabilities from your latest container scan. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
-msgid "SecurityReports|The security reports below contain one or more vulnerability findings that could not be parsed and were not recorded. Download the artifacts in the job output to investigate. Ensure any security report created conforms to the relevant %{helpPageLinkStart}JSON schema%{helpPageLinkEnd}."
+msgid "SecurityReports|The following security reports contain one or more vulnerability findings that could not be parsed and were not recorded. To investigate a report, download the artifacts in the job output. Ensure the security report conforms to the relevant %{helpPageLinkStart}JSON schema%{helpPageLinkEnd}."
msgstr ""
msgid "SecurityReports|There was an error adding the comment."
@@ -32877,6 +33441,9 @@ msgstr ""
msgid "SecurityReports|Vulnerability Report"
msgstr ""
+msgid "SecurityReports|Warning parsing security reports"
+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 ""
@@ -32898,6 +33465,12 @@ msgstr ""
msgid "SecurityReports|scanned resources"
msgstr ""
+msgid "SecurityTraining|Primary Training"
+msgstr ""
+
+msgid "SecurityTraining|Training from this partner takes precedence when more than one training partner is enabled."
+msgstr ""
+
msgid "See example DevOps Score page in our documentation."
msgstr ""
@@ -32934,15 +33507,12 @@ msgstr ""
msgid "Select a branch"
msgstr ""
-msgid "Select a compliance framework to apply to this project. %{linkStart}Learn more.%{linkEnd}"
+msgid "Select a compliance framework to apply to this project. %{linkStart}How are these added?%{linkEnd}"
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 ""
@@ -33081,6 +33651,9 @@ msgstr ""
msgid "Select target branch"
msgstr ""
+msgid "Select target branch or tag"
+msgstr ""
+
msgid "Select timezone"
msgstr ""
@@ -33417,6 +33990,9 @@ msgstr ""
msgid "Set rate limits for package registry API requests that supersede the general user and IP rate limits."
msgstr ""
+msgid "Set rate limits for searches performed by web or API requests."
+msgstr ""
+
msgid "Set severity"
msgstr ""
@@ -33462,6 +34038,9 @@ msgstr ""
msgid "Set the timeout in seconds to send a secondary site status to the primary and IPs allowed for the secondary sites."
msgstr ""
+msgid "Set this number to 0 to disable the limit."
+msgstr ""
+
msgid "Set time estimate"
msgstr ""
@@ -33764,13 +34343,11 @@ msgstr ""
msgid "Show the Open list"
msgstr ""
-msgid "Show whitespace changes"
+msgid "Show thread"
msgstr ""
-msgid "Showing %d event"
-msgid_plural "Showing %d events"
-msgstr[0] ""
-msgstr[1] ""
+msgid "Show whitespace changes"
+msgstr ""
msgid "Showing %{conflict} between %{sourceBranch} and %{targetBranch}"
msgstr ""
@@ -33936,6 +34513,9 @@ msgstr ""
msgid "Signed in"
msgstr ""
+msgid "Signed in to GitLab"
+msgstr ""
+
msgid "Signed in to GitLab as %{user_link}"
msgstr ""
@@ -34107,6 +34687,9 @@ msgstr ""
msgid "Solution"
msgstr ""
+msgid "Some actions remove attention requests, like a reviewer approving or anyone merging the merge request."
+msgstr ""
+
msgid "Some changes are not shown"
msgstr ""
@@ -34116,6 +34699,9 @@ msgstr ""
msgid "Some common domains are not allowed. %{learn_more_link}."
msgstr ""
+msgid "Someone edited the file the same time you did. Please check out %{link_start}the file %{icon}%{link_end} and make sure your changes will not unintentionally remove theirs."
+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 ""
@@ -34155,9 +34741,6 @@ msgstr ""
msgid "Something went wrong when reordering designs. Please try again"
msgstr ""
-msgid "Something went wrong when toggling the button"
-msgstr ""
-
msgid "Something went wrong while adding your award. Please try again."
msgstr ""
@@ -34566,10 +35149,10 @@ 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."
+msgid "SourcegraphAdmin|Learn more."
msgstr ""
-msgid "SourcegraphAdmin|More information"
+msgid "SourcegraphAdmin|Only public projects have code intelligence enabled and communicate with Sourcegraph."
msgstr ""
msgid "SourcegraphAdmin|Save changes"
@@ -34578,7 +35161,7 @@ msgstr ""
msgid "SourcegraphAdmin|Sourcegraph URL"
msgstr ""
-msgid "SourcegraphAdmin|e.g. https://sourcegraph.example.com"
+msgid "SourcegraphAdmin|https://sourcegraph.example.com"
msgstr ""
msgid "SourcegraphPreferences|This feature is experimental and currently limited to certain projects."
@@ -34716,6 +35299,9 @@ msgstr ""
msgid "Start free trial"
msgstr ""
+msgid "Start inputting changes and we will generate a YAML-file for you to add to your repository"
+msgstr ""
+
msgid "Start merge train"
msgstr ""
@@ -34746,6 +35332,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started escalation for this incident."
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -34758,6 +35347,9 @@ msgstr ""
msgid "Starts at (UTC)"
msgstr ""
+msgid "Starts escalations for this incident"
+msgstr ""
+
msgid "Starts on"
msgstr ""
@@ -34854,6 +35446,9 @@ msgstr ""
msgid "Status: %{title}"
msgstr ""
+msgid "StatusCheck| %{failed} failed, and %{pending} pending"
+msgstr ""
+
msgid "StatusCheck|%{failed} failed"
msgstr ""
@@ -34926,9 +35521,6 @@ msgstr ""
msgid "StatusCheck|Update status check"
msgstr ""
-msgid "StatusCheck|When this merge request is updated, a call is sent to the following APIs to confirm their status. %{linkStart}Learn more%{linkEnd}."
-msgstr ""
-
msgid "StatusCheck|You are about to remove the %{name} status check."
msgstr ""
@@ -34977,6 +35569,9 @@ msgstr ""
msgid "Stay updated about the performance and health of your environment by configuring Prometheus to monitor your deployments."
msgstr ""
+msgid "Step %{currentStep} of %{stepCount}"
+msgstr ""
+
msgid "Step 1."
msgstr ""
@@ -35019,6 +35614,9 @@ msgstr ""
msgid "Strikethrough"
msgstr ""
+msgid "Strikethrough text"
+msgstr ""
+
msgid "Subgroup information"
msgstr ""
@@ -35139,10 +35737,10 @@ msgstr ""
msgid "Subscription successfully deleted."
msgstr ""
-msgid "SubscriptionBanner|Export license usage file"
+msgid "SubscriptionBanner|Add new license"
msgstr ""
-msgid "SubscriptionBanner|Upload new license"
+msgid "SubscriptionBanner|Export license usage file"
msgstr ""
msgid "SubscriptionEmail|%{doc_link_start}Please reach out if you have questions%{doc_link_end}, and we'll be happy to assist."
@@ -35478,6 +36076,9 @@ msgstr ""
msgid "SuperSonics|Maximum users"
msgstr ""
+msgid "SuperSonics|Offline cloud"
+msgstr ""
+
msgid "SuperSonics|Paste your activation code"
msgstr ""
@@ -35520,9 +36121,6 @@ msgstr ""
msgid "SuperSonics|To activate your subscription, connect to GitLab servers through the %{linkStart}Cloud Licensing%{linkEnd} service, a hassle-free way to manage your subscription."
msgstr ""
-msgid "SuperSonics|Upload a license file"
-msgstr ""
-
msgid "SuperSonics|Users in subscription"
msgstr ""
@@ -35544,6 +36142,12 @@ msgstr ""
msgid "SuperSonics|You do not have an active subscription"
msgstr ""
+msgid "SuperSonics|You have a future dated license"
+msgstr ""
+
+msgid "SuperSonics|You have added a license that activates on %{date}. Please see the subscription history table below for more details."
+msgstr ""
+
msgid "SuperSonics|You have successfully added a license that activates on %{date}. Please see the subscription history table below for more details."
msgstr ""
@@ -35703,6 +36307,9 @@ msgstr ""
msgid "Tag name is required"
msgstr ""
+msgid "Tag push"
+msgstr ""
+
msgid "Tag push events"
msgstr ""
@@ -35817,6 +36424,12 @@ msgstr ""
msgid "Target branch"
msgstr ""
+msgid "Target branch or tag"
+msgstr ""
+
+msgid "Target roles"
+msgstr ""
+
msgid "Target-Branch"
msgstr ""
@@ -36305,6 +36918,9 @@ msgstr ""
msgid "The branch or tag does not exist"
msgstr ""
+msgid "The broadcast message displays only to users in projects and groups who have these roles."
+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 ""
@@ -36326,7 +36942,7 @@ msgstr ""
msgid "The connection will time out after %{timeout}. For repositories that take longer, use a clone/push combination."
msgstr ""
-msgid "The contact does not belong to the issue group or an ancestor"
+msgid "The contact does not belong to the issue group's root ancestor"
msgstr ""
msgid "The content editor may change the markdown formatting style of the document, which may not match your original markdown style."
@@ -36625,6 +37241,9 @@ msgstr ""
msgid "The regular expression used to find test coverage output in the job log. For example, use %{regex} for Simplecov (Ruby). Leave blank to disable."
msgstr ""
+msgid "The related CI build failed."
+msgstr ""
+
msgid "The remote mirror URL is invalid."
msgstr ""
@@ -36634,6 +37253,12 @@ msgstr ""
msgid "The remote repository is being updated..."
msgstr ""
+msgid "The report artifact provided by the CI build couldn't be parsed."
+msgstr ""
+
+msgid "The report has been successfully prepared."
+msgstr ""
+
msgid "The repository can be committed to, and issues, comments and other entities can be created."
msgstr ""
@@ -36655,6 +37280,9 @@ msgstr ""
msgid "The same shared runner executes code from multiple projects, unless you configure autoscaling with %{link} set to 1 (which it is on GitLab.com)."
msgstr ""
+msgid "The scan has been created."
+msgstr ""
+
msgid "The snippet can be accessed without any authentication."
msgstr ""
@@ -36667,6 +37295,9 @@ msgstr ""
msgid "The snippet is visible to any logged in user except external users."
msgstr ""
+msgid "The source project of this merge request has been removed."
+msgstr ""
+
msgid "The specified tab is invalid, please select another"
msgstr ""
@@ -36952,9 +37583,6 @@ msgstr ""
msgid "There was an error fetching projects"
msgstr ""
-msgid "There was an error fetching search autocomplete suggestions"
-msgstr ""
-
msgid "There was an error fetching stage total counts"
msgstr ""
@@ -37108,7 +37736,7 @@ msgstr ""
msgid "This %{issuable} is locked. Only %{strong_open}project members%{strong_close} can comment."
msgstr ""
-msgid "This %{noteableTypeText} is %{confidentialLinkStart}confidential%{linkEnd} and %{lockedLinkStart}locked%{linkEnd}."
+msgid "This %{noteableTypeText} is %{confidentialLinkStart}confidential%{confidentialLinkEnd} and %{lockedLinkStart}locked%{lockedLinkEnd}."
msgstr ""
msgid "This %{noteableTypeText} is locked."
@@ -37135,7 +37763,7 @@ 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"
+msgid "This URL already exists."
msgstr ""
msgid "This action can lead to data loss. To prevent accidental actions we ask you to confirm your intention."
@@ -37144,12 +37772,15 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} and everything this project contains. %{strongOpen}There is no going back%{strongClose}"
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} and everything this project contains. %{strongOpen}There is no going back.%{strongClose}"
msgstr ""
msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains."
msgstr ""
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains. %{strongOpen}There is no going back.%{strongClose}"
+msgstr ""
+
msgid "This action will %{strongOpen}permanently remove%{strongClose} %{codeOpen}%{group}%{codeClose} %{strongOpen}immediately%{strongClose}."
msgstr ""
@@ -37228,6 +37859,9 @@ msgstr ""
msgid "This credential has expired"
msgstr ""
+msgid "This deployment is not waiting for approvals."
+msgstr ""
+
msgid "This device has already been registered with us."
msgstr ""
@@ -37255,6 +37889,9 @@ msgstr ""
msgid "This environment is being re-deployed"
msgstr ""
+msgid "This environment is not protected."
+msgstr ""
+
msgid "This environment's canary ingress has been updated recently. Please retry later."
msgstr ""
@@ -37288,7 +37925,7 @@ msgstr ""
msgid "This group can't be removed because it is linked to a subscription. To remove this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
-msgid "This group can't be transfered because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
+msgid "This group can't be transferred because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
msgid "This group cannot be invited to a project inside a group with enforced SSO"
@@ -37315,6 +37952,9 @@ 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 incident is already escalated with '%{escalation_policy_name}'."
+msgstr ""
+
msgid "This invitation was sent to %{mail_to_invite_email}, but you are signed in as %{link_to_current_user} with email %{mail_to_current_user}."
msgstr ""
@@ -37333,9 +37973,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 merge train pipeline"
-msgstr ""
-
msgid "This is a private email address %{helpIcon} generated just for you. Anyone who has it can create issues or merge requests as if they were you. If that happens, %{resetLinkStart}reset this token%{resetLinkEnd}."
msgstr ""
@@ -37381,6 +38018,9 @@ msgstr ""
msgid "This job depends on upstream jobs that need to succeed in order for this job to be triggered"
msgstr ""
+msgid "This job deploys to the protected environment \"%{environment}\" which requires approvals."
+msgstr ""
+
msgid "This job does not have a trace."
msgstr ""
@@ -37621,6 +38261,9 @@ msgstr ""
msgid "This suggestion already matches its content."
msgstr ""
+msgid "This title already exists."
+msgstr ""
+
msgid "This user cannot be unlocked manually from GitLab"
msgstr ""
@@ -38093,6 +38736,9 @@ msgstr ""
msgid "To add the entry manually, provide the following details to the application on your phone."
msgstr ""
+msgid "To ask someone to look at a merge request, select %{strongStart}Request attention%{strongEnd}. Select again to remove the request."
+msgstr ""
+
msgid "To confirm, type %{phrase_code}"
msgstr ""
@@ -38174,6 +38820,9 @@ msgstr ""
msgid "To personalize your GitLab experience, we'd like to know a bit more about you"
msgstr ""
+msgid "To preserve performance only %{strongStart}%{visible} of %{total}%{strongEnd} files are displayed."
+msgstr ""
+
msgid "To preserve performance only %{strong_open}%{display_size} of %{real_size}%{strong_close} files are displayed."
msgstr ""
@@ -38192,7 +38841,7 @@ 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 renew, export your license usage file and email it to %{renewal_service_email}. A new license will be emailed to the email address registered in the %{customers_dot}. You can upload this license to your instance."
+msgid "To renew, export your license usage file and email it to %{renewal_service_email}. A new license will be emailed to the email address registered in the %{customers_dot}. You can add this license to your instance."
msgstr ""
msgid "To resolve this, try to:"
@@ -38342,9 +38991,6 @@ msgstr ""
msgid "Toggle the Performance Bar"
msgstr ""
-msgid "Toggle thread"
-msgstr ""
-
msgid "Toggled :%{name}: emoji award."
msgstr ""
@@ -38531,10 +39177,8 @@ msgstr ""
msgid "Trending"
msgstr ""
-msgid "Trials|%{planName} Trial %{enDash} %{num} day left"
-msgid_plural "Trials|%{planName} Trial %{enDash} %{num} days left"
-msgstr[0] ""
-msgstr[1] ""
+msgid "Trials|%{planName} Trial"
+msgstr ""
msgid "Trials|Compare all plans"
msgstr ""
@@ -38542,6 +39186,9 @@ msgstr ""
msgid "Trials|Create a new group to start your GitLab Ultimate trial."
msgstr ""
+msgid "Trials|Day %{daysUsed}/%{duration}"
+msgstr ""
+
msgid "Trials|Go back to GitLab"
msgstr ""
@@ -38791,7 +39438,7 @@ msgstr ""
msgid "URL is triggered when repository is updated"
msgstr ""
-msgid "URL must be percent-encoded if neccessary."
+msgid "URL must be percent-encoded if necessary."
msgstr ""
msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
@@ -39037,6 +39684,9 @@ msgstr ""
msgid "Unreachable"
msgstr ""
+msgid "Unrecognized approval status."
+msgstr ""
+
msgid "Unrecognized cluster type"
msgstr ""
@@ -39217,9 +39867,6 @@ msgstr ""
msgid "Upload File"
msgstr ""
-msgid "Upload License"
-msgstr ""
-
msgid "Upload New File"
msgstr ""
@@ -39238,9 +39885,6 @@ msgstr ""
msgid "Upload image"
msgstr ""
-msgid "Upload license"
-msgstr ""
-
msgid "Upload new file"
msgstr ""
@@ -39250,6 +39894,9 @@ msgstr ""
msgid "UploadLink|click to upload"
msgstr ""
+msgid "Uploaded"
+msgstr ""
+
msgid "Uploading changes to terminal"
msgstr ""
@@ -39307,7 +39954,7 @@ msgstr ""
msgid "UsageQuota|File attachments and smaller design graphics."
msgstr ""
-msgid "UsageQuota|From %{storage_enforcement_date} storage limits will apply to this namespace. View and manage your usage in %{strong_start}Group Settings &gt; Usage quotas%{strong_end}."
+msgid "UsageQuota|From %{storage_enforcement_date} storage limits will apply to this namespace. View and manage your usage in %{strong_start}%{namespace_type} settings &gt; Usage quotas%{strong_end}."
msgstr ""
msgid "UsageQuota|Git repository."
@@ -39370,6 +40017,9 @@ msgstr ""
msgid "UsageQuota|Storage type"
msgstr ""
+msgid "UsageQuota|Storage used"
+msgstr ""
+
msgid "UsageQuota|This is the total amount of storage used across your projects within this namespace."
msgstr ""
@@ -39541,6 +40191,9 @@ msgstr ""
msgid "Use GitLab Runner in AWS"
msgstr ""
+msgid "Use Secure Files to store files used by your pipelines such as Android keystores, or Apple provisioning profiles and signing certificates."
+msgstr ""
+
msgid "Use a one-time password authenticator on your mobile device or computer to enable two-factor authentication (2FA)."
msgstr ""
@@ -39550,6 +40203,9 @@ msgstr ""
msgid "Use authorized_keys file to authenticate SSH keys"
msgstr ""
+msgid "Use banners and notifications to notify your users about scheduled maintenance, recent upgrades, and more."
+msgstr ""
+
msgid "Use cURL"
msgstr ""
@@ -40357,9 +41013,6 @@ msgstr ""
msgid "View seat usage"
msgstr ""
-msgid "View setting"
-msgstr ""
-
msgid "View supported languages and frameworks"
msgstr ""
@@ -40384,6 +41037,9 @@ msgstr ""
msgid "Viewing commit"
msgstr ""
+msgid "Viewing projects and designs data from a primary site is not possible when using a unified URL. Visit the secondary site directly. %{geo_help_url}"
+msgstr ""
+
msgid "Violation"
msgstr ""
@@ -40435,6 +41091,9 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
+msgid "Vulnerability"
+msgstr ""
+
msgid "Vulnerability Report"
msgstr ""
@@ -40486,9 +41145,6 @@ msgstr ""
msgid "VulnerabilityManagement|An unverified non-confirmed finding"
msgstr ""
-msgid "VulnerabilityManagement|At least one identifier is required"
-msgstr ""
-
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -40510,6 +41166,9 @@ msgstr ""
msgid "VulnerabilityManagement|Fetching linked Jira issues"
msgstr ""
+msgid "VulnerabilityManagement|Identifier code and URL are required fields"
+msgstr ""
+
msgid "VulnerabilityManagement|Manually add a vulnerability entry into the vulnerability report."
msgstr ""
@@ -40630,6 +41289,9 @@ msgstr ""
msgid "Vulnerability|Class"
msgstr ""
+msgid "Vulnerability|Cluster"
+msgstr ""
+
msgid "Vulnerability|Code Review"
msgstr ""
@@ -40726,9 +41388,6 @@ msgstr ""
msgid "Vulnerability|Scanner Provider"
msgstr ""
-msgid "Vulnerability|Secure Code Warrior"
-msgstr ""
-
msgid "Vulnerability|Security Audit"
msgstr ""
@@ -40774,6 +41433,9 @@ msgstr ""
msgid "Wait for the file to load to copy its contents"
msgstr ""
+msgid "Waiting for approval"
+msgstr ""
+
msgid "Waiting for merge (open and assigned)"
msgstr ""
@@ -41140,9 +41802,6 @@ msgstr ""
msgid "What are project audit events?"
msgstr ""
-msgid "What are you searching for?"
-msgstr ""
-
msgid "What does this command do?"
msgstr ""
@@ -41185,13 +41844,13 @@ msgstr ""
msgid "When enabled, SSH keys with no expiry date or an invalid expiration date are no longer accepted. Leave blank for no limit."
msgstr ""
-msgid "When enabled, existing personal access tokens may be revoked. Leave blank for no limit."
+msgid "When enabled, cleanup polices execute faster but put more load on Redis."
msgstr ""
-msgid "When enabled, job logs are collected by Datadog and displayed along with pipeline execution traces."
+msgid "When enabled, existing personal access tokens may be revoked. Leave blank for no limit."
msgstr ""
-msgid "When inactive, an external authentication provider must be used."
+msgid "When enabled, job logs are collected by Datadog and displayed along with pipeline execution traces."
msgstr ""
msgid "When merge requests and commits in the default branch close, any issues they reference also close."
@@ -41244,6 +41903,9 @@ msgstr ""
msgid "Wiki"
msgstr ""
+msgid "Wiki page"
+msgstr ""
+
msgid "Wiki page was successfully created."
msgstr ""
@@ -41349,7 +42011,7 @@ msgstr ""
msgid "WikiPageConflictMessage|Someone edited the page the same time you did. Please check out %{wikiLinkStart}the page%{wikiLinkEnd} and make sure your changes will not unintentionally remove theirs."
msgstr ""
-msgid "WikiPage|An error occured while trying to render the content editor. Please try again later."
+msgid "WikiPage|An error occurred while trying to render the content editor. Please try again later."
msgstr ""
msgid "WikiPage|Are you sure you want to switch back to the classic editor?"
@@ -41511,6 +42173,9 @@ msgstr ""
msgid "WorkItem|Something went wrong when creating a work item. Please try again"
msgstr ""
+msgid "WorkItem|Something went wrong when fetching the work item. Please try again."
+msgstr ""
+
msgid "WorkItem|Something went wrong when fetching work item types. Please try again"
msgstr ""
@@ -41667,6 +42332,9 @@ msgstr ""
msgid "You are not authorized to update this scanner profile"
msgstr ""
+msgid "You are not authorized to upload metric images"
+msgstr ""
+
msgid "You are now impersonating %{username}"
msgstr ""
@@ -41721,6 +42389,12 @@ msgstr ""
msgid "You can always edit this later"
msgstr ""
+msgid "You can check it in your %{pat_link_start}personal access tokens%{pat_link_end} settings."
+msgstr ""
+
+msgid "You can check it in your in your personal access tokens settings %{pat_link}."
+msgstr ""
+
msgid "You can create a new %{link}."
msgstr ""
@@ -41814,6 +42488,9 @@ 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 transfer the project to namespaces you manage."
msgstr ""
@@ -41844,6 +42521,9 @@ msgstr ""
msgid "You cannot access the raw file. Please wait a minute."
msgstr ""
+msgid "You cannot approve your own deployment."
+msgstr ""
+
msgid "You cannot combine replace_ids with add_ids or remove_ids"
msgstr ""
@@ -41928,6 +42608,9 @@ msgstr ""
msgid "You don't have any recent searches"
msgstr ""
+msgid "You don't have permission to review this deployment. Contact the project or group owner for help."
+msgstr ""
+
msgid "You don't have sufficient permission to perform this action."
msgstr ""
@@ -42008,10 +42691,10 @@ msgstr ""
msgid "You have insufficient permissions to view shifts for this rotation"
msgstr ""
-msgid "You have more active users than are allowed by your license. Before %{date} GitLab must reconcile your subscription. To complete this process, export your license usage file and email it to %{renewal_service_email}. A new license will be emailed to the email address registered in the %{customers_dot}. You can upload this license to your instance."
+msgid "You have more active users than are allowed by your license. Before %{date} GitLab must reconcile your subscription. To complete this process, export your license usage file and email it to %{renewal_service_email}. A new license will be emailed to the email address registered in the %{customers_dot}. You can add this license to your instance."
msgstr ""
-msgid "You have more active users than are allowed by your license. GitLab must now reconcile your subscription. To complete this process, export your license usage file and email it to %{renewal_service_email}. A new license will be emailed to the email address registered in the %{customers_dot}. You can upload this license to your instance."
+msgid "You have more active users than are allowed by your license. GitLab must now reconcile your subscription. To complete this process, export your license usage file and email it to %{renewal_service_email}. A new license will be emailed to the email address registered in the %{customers_dot}. You can add this license to your instance."
msgstr ""
msgid "You have no permissions"
@@ -42020,9 +42703,6 @@ 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 set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
@@ -42053,12 +42733,6 @@ msgstr ""
msgid "You must have maintainer access to force delete a lock"
msgstr ""
-msgid "You must have permission to create a project in a group before forking."
-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 ""
@@ -42212,6 +42886,9 @@ msgstr ""
msgid "Your %{plan} subscription expires on %{expiry_date}"
msgstr ""
+msgid "Your %{spammable_entity_type} has been recognized as spam. Please, change the content or solve the reCAPTCHA to proceed."
+msgstr ""
+
msgid "Your %{strong}%{plan_name}%{strong_close} subscription expires on %{strong}%{expires_on}%{strong_close}. After that date, you cannot create issues or merge requests, or use many other features."
msgstr ""
@@ -42464,7 +43141,7 @@ msgstr ""
msgid "Your public email will be displayed on your public profile."
msgstr ""
-msgid "Your request for access could not be processed: %{error_meesage}"
+msgid "Your request for access could not be processed: %{error_message}"
msgstr ""
msgid "Your request for access has been queued for review."
@@ -42503,7 +43180,7 @@ msgstr ""
msgid "Your subscription has %{remaining_seats_count} out of %{total_seats_count} seats remaining. Even if you reach the number of seats in your subscription, you can continue to add users, and GitLab will bill you for the overage."
msgstr ""
-msgid "Your subscription is now expired. To renew, export your license usage file and email it to %{renewal_service_email}. A new license will be emailed to the email address registered in the %{customers_dot}. You can upload this license to your instance. To use Free tier, remove your current license."
+msgid "Your subscription is now expired. To renew, export your license usage file and email it to %{renewal_service_email}. A new license will be emailed to the email address registered in the %{customers_dot}. You can add this license to your instance. To use Free tier, remove your current license."
msgstr ""
msgid "Your subscription will expire in %{remaining_days} day."
@@ -42760,6 +43437,11 @@ msgstr ""
msgid "cannot merge"
msgstr ""
+msgid "change"
+msgid_plural "changes"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "ciReport|%{danger_start}%{degradedNum} degraded%{danger_end}, %{same_start}%{sameNum} same%{same_end}, and %{success_start}%{improvedNum} improved%{success_end}"
msgstr ""
@@ -42855,6 +43537,15 @@ msgstr ""
msgid "ciReport|Cluster Image Scanning"
msgstr ""
+msgid "ciReport|Code Quality"
+msgstr ""
+
+msgid "ciReport|Code Quality failed loading results"
+msgstr ""
+
+msgid "ciReport|Code Quality test metrics results are being parsed"
+msgstr ""
+
msgid "ciReport|Code quality degraded"
msgstr ""
@@ -42962,6 +43653,9 @@ msgstr ""
msgid "ciReport|New"
msgstr ""
+msgid "ciReport|No changes to Code Quality."
+msgstr ""
+
msgid "ciReport|No changes to code quality"
msgstr ""
@@ -43045,45 +43739,6 @@ msgstr ""
msgid "closed issue"
msgstr ""
-msgid "codeQualityWalkthrough|A code quality job will now run every time you or your team members commit changes to your project. You can view the results of the code quality job in the job logs."
-msgstr ""
-
-msgid "codeQualityWalkthrough|Congrats! Your first pipeline is running %{emojiStart}zap%{emojiEnd}"
-msgstr ""
-
-msgid "codeQualityWalkthrough|Got it"
-msgstr ""
-
-msgid "codeQualityWalkthrough|Let's start by creating a new CI file."
-msgstr ""
-
-msgid "codeQualityWalkthrough|Not sure how to fix your failed job? We have compiled some tips on how to troubleshoot code quality jobs in the documentation."
-msgstr ""
-
-msgid "codeQualityWalkthrough|Read the documentation"
-msgstr ""
-
-msgid "codeQualityWalkthrough|Something went wrong. %{emojiStart}thinking%{emojiEnd} Let's fix it."
-msgstr ""
-
-msgid "codeQualityWalkthrough|To begin with code quality, we first need to create a new CI file using our code editor. We added a code quality template in the code editor to help you get started %{emojiStart}wink%{emojiEnd} .%{lineBreak}Take some time to review the template, when you are ready, use the %{strongStart}commit changes%{strongEnd} button at the bottom of the page."
-msgstr ""
-
-msgid "codeQualityWalkthrough|Troubleshoot your code quality job"
-msgstr ""
-
-msgid "codeQualityWalkthrough|View the logs"
-msgstr ""
-
-msgid "codeQualityWalkthrough|Well done! You've just automated your code quality review. %{emojiStart}raised_hands%{emojiEnd}"
-msgstr ""
-
-msgid "codeQualityWalkthrough|Your job failed. No worries - this happens. Let's view the logs, and see how we can fix it."
-msgstr ""
-
-msgid "codeQualityWalkthrough|Your pipeline can take a few minutes to run. If you enabled email notifications, you'll receive an email with your pipeline status. In the meantime, why don't you get some coffee? You earned it!"
-msgstr ""
-
msgid "collect usage information"
msgstr ""
@@ -43102,7 +43757,7 @@ msgstr ""
msgid "compliance violation has already been recorded"
msgstr ""
-msgid "contact with same email already exists in group hierarchy"
+msgid "contacts can only be added to root groups"
msgstr ""
msgid "container registry images"
@@ -43173,9 +43828,6 @@ msgstr ""
msgid "design"
msgstr ""
-msgid "detached"
-msgstr ""
-
msgid "disabled"
msgstr ""
@@ -43424,7 +44076,7 @@ msgstr ""
msgid "is not a valid X509 certificate."
msgstr ""
-msgid "is not allowed for sign-up."
+msgid "is not allowed for sign-up. Please use your regular email address."
msgstr ""
msgid "is not allowed for this group."
@@ -43436,7 +44088,7 @@ msgstr ""
msgid "is not allowed since the group is not top-level group."
msgstr ""
-msgid "is not allowed."
+msgid "is not allowed. Please use your regular email address."
msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
@@ -43642,6 +44294,12 @@ msgstr ""
msgid "mrWidget|Approved by you and others"
msgstr ""
+msgid "mrWidget|Assign yourself to these issues"
+msgstr ""
+
+msgid "mrWidget|Assign yourself to this issue"
+msgstr ""
+
msgid "mrWidget|Cancel auto-merge"
msgstr ""
@@ -43757,9 +44415,6 @@ msgstr ""
msgid "mrWidget|Merge failed."
msgstr ""
-msgid "mrWidget|Merge locally"
-msgstr ""
-
msgid "mrWidget|Merge unavailable: merge requests are read-only on archived projects."
msgstr ""
@@ -43832,6 +44487,9 @@ msgstr ""
msgid "mrWidget|Resolve conflicts"
msgstr ""
+msgid "mrWidget|Resolve locally"
+msgstr ""
+
msgid "mrWidget|Revert"
msgstr ""
@@ -44015,6 +44673,9 @@ msgstr ""
msgid "or"
msgstr ""
+msgid "organizations can only be added to root groups"
+msgstr ""
+
msgid "other card matches"
msgstr ""
@@ -44307,9 +44968,6 @@ msgstr ""
msgid "the correct format."
msgstr ""
-msgid "the file"
-msgstr ""
-
msgid "the following epic(s)"
msgstr ""
@@ -44331,9 +44989,6 @@ msgstr ""
msgid "toggle collapse"
msgstr ""
-msgid "train"
-msgstr ""
-
msgid "triggered"
msgstr ""
diff --git a/locale/gl_ES/gitlab.po b/locale/gl_ES/gitlab.po
index 4a23d97d8e4..7aea2c10400 100644
--- a/locale/gl_ES/gitlab.po
+++ b/locale/gl_ES/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: gl\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2022-02-02 15:43\n"
+"PO-Revision-Date: 2022-03-01 20:37\n"
msgid " %{start} to %{end}"
msgstr " %{start} a %{end}"
@@ -146,6 +146,11 @@ msgid_plural "%d approvers (you've approved)"
msgstr[0] ""
msgstr[1] ""
+msgid "%d assigned issue"
+msgid_plural "%d assigned issues"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -421,8 +426,23 @@ msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
msgstr[1] ""
-msgid "%d vulnerability updated"
-msgid_plural "%d vulnerabilities updated"
+msgid "%d vulnerability set to confirmed"
+msgid_plural "%d vulnerabilities set to confirmed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to dismissed"
+msgid_plural "%d vulnerabilities set to dismissed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to needs triage"
+msgid_plural "%d vulnerabilities set to needs triage"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to resolved"
+msgid_plural "%d vulnerabilities set to resolved"
msgstr[0] ""
msgstr[1] ""
@@ -510,6 +530,12 @@ msgstr[1] ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{completed} of %{total} issues closed"
+msgstr ""
+
+msgid "%{completed} of %{total} weight completed"
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -858,6 +884,9 @@ msgstr ""
msgid "%{openedIssues} open, %{closedIssues} closed"
msgstr ""
+msgid "%{percentage}%% issues closed"
+msgstr ""
+
msgid "%{percentage}%% weight completed"
msgstr ""
@@ -1287,6 +1316,9 @@ msgid_plural "- Users"
msgstr[0] ""
msgstr[1] ""
+msgid "- of - issues closed"
+msgstr ""
+
msgid "- of - weight completed"
msgstr ""
@@ -1429,7 +1461,7 @@ msgstr ""
msgid "1000+"
msgstr ""
-msgid "192.168.0.0/24"
+msgid "192.168.0.0/24 or 2001:0DB8:1234::/48"
msgstr ""
msgid "1st contribution!"
@@ -1741,13 +1773,13 @@ msgstr ""
msgid "AWS Access Key"
msgstr ""
-msgid "AWS Access Key. Only required if not using role instance credentials"
+msgid "AWS Secret Access Key"
msgstr ""
-msgid "AWS Secret Access Key"
+msgid "AWS access key ID (Optional)"
msgstr ""
-msgid "AWS Secret Access Key. Only required if not using role instance credentials"
+msgid "AWS secret access key (Optional)"
msgstr ""
msgid "AWS service error: %{error}"
@@ -1807,9 +1839,6 @@ msgstr ""
msgid "Access granted"
msgstr ""
-msgid "Access key ID"
-msgstr ""
-
msgid "Access requests"
msgstr ""
@@ -1984,7 +2013,7 @@ msgstr ""
msgid "Activity"
msgstr ""
-msgid "Activity|An error occured while retrieving activity. Reload the page to try again."
+msgid "Activity|An error occurred while retrieving activity. Reload the page to try again."
msgstr ""
msgid "Add"
@@ -2023,6 +2052,9 @@ msgstr ""
msgid "Add a %{type}"
msgstr ""
+msgid "Add a GCP region"
+msgstr ""
+
msgid "Add a GPG key"
msgstr ""
@@ -2074,6 +2106,9 @@ msgstr ""
msgid "Add a numbered list"
msgstr ""
+msgid "Add a related epic"
+msgstr ""
+
msgid "Add a related issue"
msgstr ""
@@ -2188,6 +2223,9 @@ msgstr ""
msgid "Add or subtract spent time"
msgstr ""
+msgid "Add people"
+msgstr ""
+
msgid "Add previously merged commits"
msgstr ""
@@ -2254,6 +2292,9 @@ msgstr ""
msgid "Add webhook"
msgstr ""
+msgid "Add your team members and others to GitLab."
+msgstr ""
+
msgid "Add/remove"
msgstr ""
@@ -3076,12 +3117,6 @@ msgstr ""
msgid "AdvancedSearch|Reindex required"
msgstr ""
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. Permanently deleting this project will %{strongStart}immediately delete%{strongEnd} its repositories and %{strongStart}all related resources%{strongEnd}, including issues, merge requests etc."
-msgstr ""
-
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. You will lose this project's repository and %{strongStart}all related resources%{strongEnd}, including issues and merge requests."
-msgstr ""
-
msgid "After a successful password update you will be redirected to login screen."
msgstr ""
@@ -3112,6 +3147,9 @@ msgstr ""
msgid "Akismet helps prevent the creation of spam issues in public projects."
msgstr ""
+msgid "Alert"
+msgstr ""
+
msgid "AlertManagement|Acknowledged"
msgstr ""
@@ -3484,9 +3522,6 @@ msgstr ""
msgid "All environments"
msgstr ""
-msgid "All epics"
-msgstr ""
-
msgid "All groups and projects"
msgstr ""
@@ -4223,12 +4258,15 @@ msgstr ""
msgid "ApplicationSettings|Approve users in the pending approval status?"
msgstr ""
-msgid "ApplicationSettings|By making this change, you will automatically approve %d user with the pending approval status."
-msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users with the pending approval status."
+msgid "ApplicationSettings|Approve users who are pending approval?"
+msgstr ""
+
+msgid "ApplicationSettings|By making this change, you will automatically approve %d user who is pending approval."
+msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users who are pending approval."
msgstr[0] ""
msgstr[1] ""
-msgid "ApplicationSettings|By making this change, you will automatically approve all users in pending approval status."
+msgid "ApplicationSettings|By making this change, you will automatically approve all users who are pending approval."
msgstr ""
msgid "ApplicationSettings|Denied domains for sign-ups"
@@ -4634,10 +4672,10 @@ msgstr ""
msgid "Archiving the project will make it entirely read-only. It is hidden from the dashboard and doesn't show up in searches. %{strong_start}The repository cannot be committed to, and no issues, comments, or other entities can be created.%{strong_end} %{link_start}Learn more.%{link_end}"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to delete this project?"
+msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
+msgid "Are you absolutely sure?"
msgstr ""
msgid "Are you sure that you want to archive this project?"
@@ -4673,12 +4711,18 @@ msgstr ""
msgid "Are you sure you want to delete this SSH key?"
msgstr ""
+msgid "Are you sure you want to delete this comment?"
+msgstr ""
+
msgid "Are you sure you want to delete this deploy key?"
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 label?"
+msgstr ""
+
msgid "Are you sure you want to delete this pipeline schedule?"
msgstr ""
@@ -4694,9 +4738,6 @@ msgstr ""
msgid "Are you sure you want to discard your changes?"
msgstr ""
-msgid "Are you sure you want to erase this build?"
-msgstr ""
-
msgid "Are you sure you want to import %d repository?"
msgid_plural "Are you sure you want to import %d repositories?"
msgstr[0] ""
@@ -4744,6 +4785,9 @@ msgstr ""
msgid "Are you sure you want to remove this list?"
msgstr ""
+msgid "Are you sure you want to remove this nickname?"
+msgstr ""
+
msgid "Are you sure you want to reset the health check token?"
msgstr ""
@@ -4756,10 +4800,10 @@ 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?"
+msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
msgstr ""
-msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
+msgid "Are you sure you want to revoke this project access token? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to stop this environment?"
@@ -4906,9 +4950,6 @@ msgstr ""
msgid "Assigned to %{assignee_name}"
msgstr ""
-msgid "Assigned to %{name}"
-msgstr ""
-
msgid "Assigned to me"
msgstr ""
@@ -4973,6 +5014,9 @@ msgstr[1] ""
msgid "Attaching the file failed."
msgstr ""
+msgid "Attention"
+msgstr ""
+
msgid "Audit Events"
msgstr ""
@@ -5135,6 +5179,12 @@ msgstr ""
msgid "Authorized applications (%{size})"
msgstr ""
+msgid "AuthorizedApplication|Are you sure you want to revoke this application?"
+msgstr ""
+
+msgid "AuthorizedApplication|Revoke application"
+msgstr ""
+
msgid "Authors: %{authors}"
msgstr ""
@@ -6328,6 +6378,9 @@ msgstr ""
msgid "CICDAnalytics|Shared Runners Usage"
msgstr ""
+msgid "CICDAnalytics|Shared runner pipeline minute duration by month"
+msgstr ""
+
msgid "CICDAnalytics|Shared runner usage"
msgstr ""
@@ -6469,6 +6522,9 @@ msgstr ""
msgid "Can create groups:"
msgstr ""
+msgid "Can not delete primary training"
+msgstr ""
+
msgid "Can't apply as the source branch was deleted."
msgstr ""
@@ -6802,9 +6858,6 @@ msgstr ""
msgid "Changing any setting here requires an application restart"
msgstr ""
-msgid "Changing group URL can have unintended side effects."
-msgstr ""
-
msgid "Charts can't be displayed as the request for data has timed out. %{documentationLink}"
msgstr ""
@@ -6892,9 +6945,6 @@ msgstr ""
msgid "Checking branch availability..."
msgstr ""
-msgid "Checking group URL availability..."
-msgstr ""
-
msgid "Checking group path availability..."
msgstr ""
@@ -7388,6 +7438,9 @@ msgstr ""
msgid "Clear recent searches"
msgstr ""
+msgid "Clear repository checks"
+msgstr ""
+
msgid "Clear search"
msgstr ""
@@ -7520,9 +7573,6 @@ msgstr ""
msgid "Closed MRs"
msgstr ""
-msgid "Closed epics"
-msgstr ""
-
msgid "Closed issues"
msgstr ""
@@ -7559,13 +7609,13 @@ msgstr ""
msgid "Cluster level"
msgstr ""
-msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
+msgid "Cluster type must be specified for Stages::ClusterEndpointInserter"
msgstr ""
msgid "ClusterAgents|%{name} successfully deleted"
msgstr ""
-msgid "ClusterAgents|%{number} of %{total} Agents"
+msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
@@ -7607,6 +7657,15 @@ msgstr ""
msgid "ClusterAgents|Agent never connected to GitLab"
msgstr ""
+msgid "ClusterAgents|Agent version mismatch"
+msgstr ""
+
+msgid "ClusterAgents|Agent version mismatch and update"
+msgstr ""
+
+msgid "ClusterAgents|Agent version update required"
+msgstr ""
+
msgid "ClusterAgents|All"
msgstr ""
@@ -7631,7 +7690,7 @@ msgstr ""
msgid "ClusterAgents|Configuration"
msgstr ""
-msgid "ClusterAgents|Connect a cluster through the Agent"
+msgid "ClusterAgents|Connect a cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connect existing cluster"
@@ -7640,13 +7699,13 @@ msgstr ""
msgid "ClusterAgents|Connect with a certificate"
msgstr ""
-msgid "ClusterAgents|Connect with agent"
+msgid "ClusterAgents|Connect with an agent"
msgstr ""
msgid "ClusterAgents|Connect with the GitLab Agent"
msgstr ""
-msgid "ClusterAgents|Connect your cluster through the Agent"
+msgid "ClusterAgents|Connect your cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connected"
@@ -7706,7 +7765,10 @@ msgstr ""
msgid "ClusterAgents|How to register an agent?"
msgstr ""
-msgid "ClusterAgents|Install new Agent"
+msgid "ClusterAgents|How to update an agent?"
+msgstr ""
+
+msgid "ClusterAgents|Install a new agent"
msgstr ""
msgid "ClusterAgents|Last connected %{timeAgo}."
@@ -7733,7 +7795,7 @@ msgstr ""
msgid "ClusterAgents|Never connected"
msgstr ""
-msgid "ClusterAgents|No Agents"
+msgid "ClusterAgents|No agents"
msgstr ""
msgid "ClusterAgents|No clusters connected through cluster certificates"
@@ -7793,6 +7855,9 @@ msgstr ""
msgid "ClusterAgents|The agent has not been connected in a long time. There might be a connectivity issue. Last contact was %{timeAgo}."
msgstr ""
+msgid "ClusterAgents|The agent version do not match each other across your cluster's pods. This can happen when a new agent version was just deployed and Kubernetes is shutting down the old pods."
+msgstr ""
+
msgid "ClusterAgents|The recommended installation method includes the token. If you want to follow the advanced installation method provided in the docs, make sure you save the token value before you close this window."
msgstr ""
@@ -7840,6 +7905,9 @@ msgstr ""
msgid "ClusterAgents|You will need to create a token to connect to your agent"
msgstr ""
+msgid "ClusterAgents|Your agent version is out of sync with your GitLab version (v%{version}), which might cause compatibility problems. Update the agent installed on your cluster to the most recent version."
+msgstr ""
+
msgid "ClusterAgents|Your instance doesn't have the %{linkStart}GitLab Agent Server (KAS)%{linkEnd} set up. Ask a GitLab Administrator to install it."
msgstr ""
@@ -8716,9 +8784,6 @@ msgstr ""
msgid "Comma-separated list of email addresses."
msgstr ""
-msgid "Comma-separated list of users allowed to exceed the rate limit."
-msgstr ""
-
msgid "Comma-separated, e.g. '1.1.1.1, 2.2.2.0/24'"
msgstr ""
@@ -9045,6 +9110,12 @@ msgstr ""
msgid "Confidential"
msgstr ""
+msgid "Confidential issue"
+msgstr ""
+
+msgid "Confidential note"
+msgstr ""
+
msgid "Confidentiality"
msgstr ""
@@ -9078,6 +9149,9 @@ msgstr ""
msgid "Configure Dependency Scanning in `.gitlab-ci.yml`, creating this file if it does not already exist"
msgstr ""
+msgid "Configure GitLab"
+msgstr ""
+
msgid "Configure GitLab runners to start using the Web Terminal. %{helpStart}Learn more.%{helpEnd}"
msgstr ""
@@ -9126,6 +9200,15 @@ msgstr ""
msgid "Configure pipelines to deploy web apps, backend services, APIs and static resources to Google Cloud"
msgstr ""
+msgid "Configure region"
+msgstr ""
+
+msgid "Configure region for environment"
+msgstr ""
+
+msgid "Configure regions"
+msgstr ""
+
msgid "Configure repository mirroring."
msgstr ""
@@ -9159,6 +9242,9 @@ msgstr ""
msgid "Configure which lists are shown for anyone who visits this board"
msgstr ""
+msgid "Configure your environments to be deployed to specific geographical regions"
+msgstr ""
+
msgid "Confirm"
msgstr ""
@@ -9861,10 +9947,10 @@ msgstr ""
msgid "CorpusManagement|Actions"
msgstr ""
-msgid "CorpusManagement|Corpus are used in fuzz testing as mutation source to Improve future testing."
+msgid "CorpusManagement|Corpus file"
msgstr ""
-msgid "CorpusManagement|Corpus file"
+msgid "CorpusManagement|Corpus files are used in coverage-guided fuzz testing as seed inputs to improve testing."
msgstr ""
msgid "CorpusManagement|Corpus files must be in *.zip format. Maximum 5 GB"
@@ -9918,6 +10004,9 @@ msgstr ""
msgid "Could not apply %{name} command."
msgstr ""
+msgid "Could not apply %{name} command. %{message}."
+msgstr ""
+
msgid "Could not authorize chat nickname. Try again!"
msgstr ""
@@ -10068,6 +10157,9 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
+msgid "Create a group"
+msgstr ""
+
msgid "Create a merge request"
msgstr ""
@@ -10092,6 +10184,9 @@ msgstr ""
msgid "Create a personal access token on your account to pull or push via %{protocol}."
msgstr ""
+msgid "Create a project"
+msgstr ""
+
msgid "Create an account using:"
msgstr ""
@@ -10455,6 +10550,9 @@ msgstr ""
msgid "Creation date"
msgstr ""
+msgid "Creator"
+msgstr ""
+
msgid "Credentials"
msgstr ""
@@ -10467,9 +10565,15 @@ msgstr ""
msgid "CredentialsInventory|Personal Access Tokens"
msgstr ""
+msgid "CredentialsInventory|Project Access Tokens"
+msgstr ""
+
msgid "CredentialsInventory|SSH Keys"
msgstr ""
+msgid "Credit card required to be on file in order to create a pipeline"
+msgstr ""
+
msgid "Credit card:"
msgstr ""
@@ -10653,9 +10757,6 @@ msgstr ""
msgid "Customer relations"
msgstr ""
-msgid "Customizable by an administrator."
-msgstr ""
-
msgid "Customizable by owners."
msgstr ""
@@ -10785,30 +10886,18 @@ msgstr ""
msgid "CycleAnalytics|%{selectedLabelsCount} selected (%{maxLabels} max)"
msgstr ""
-msgid "CycleAnalytics|%{stageCount} stages selected"
-msgstr ""
-
-msgid "CycleAnalytics|All stages"
-msgstr ""
-
-msgid "CycleAnalytics|Average days to completion"
+msgid "CycleAnalytics|Average time to completion"
msgstr ""
msgid "CycleAnalytics|Date"
msgstr ""
-msgid "CycleAnalytics|Days to completion"
-msgstr ""
-
msgid "CycleAnalytics|Display chart filters"
msgstr ""
msgid "CycleAnalytics|Lead Time for Changes"
msgstr ""
-msgid "CycleAnalytics|No stages selected"
-msgstr ""
-
msgid "CycleAnalytics|Number of tasks"
msgstr ""
@@ -10837,18 +10926,30 @@ msgstr ""
msgid "CycleAnalytics|Showing data for group '%{groupName}' from %{createdAfter} to %{createdBefore}"
msgstr ""
-msgid "CycleAnalytics|Stages"
+msgid "CycleAnalytics|Stage time: %{title}"
msgstr ""
msgid "CycleAnalytics|Tasks by type"
msgstr ""
-msgid "CycleAnalytics|The average time spent in the selected stage for the items that were completed on each date. Data limited to the last 500 items."
+msgid "CycleAnalytics|The average time items spent in this stage. Data limited to items completed within this date range."
msgstr ""
msgid "CycleAnalytics|The given date range is larger than 180 days"
msgstr ""
+msgid "CycleAnalytics|The total time items spent across each value stream stage. Data limited to items completed within this date range."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Stage time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Total time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|Total time"
+msgstr ""
+
msgid "CycleAnalytics|Type of work"
msgstr ""
@@ -10861,9 +10962,6 @@ msgstr ""
msgid "CycleAnalytics|project dropdown filter"
msgstr ""
-msgid "CycleAnalytics|stage dropdown"
-msgstr ""
-
msgid "DAG visualization requires at least 3 dependent jobs."
msgstr ""
@@ -10963,10 +11061,16 @@ msgstr ""
msgid "DastProfiles|AJAX spider"
msgstr ""
+msgid "DastProfiles|API"
+msgstr ""
+
+msgid "DastProfiles|API endpoint URL"
+msgstr ""
+
msgid "DastProfiles|Active"
msgstr ""
-msgid "DastProfiles|Additional request headers (Optional)"
+msgid "DastProfiles|Additional request headers (optional)"
msgstr ""
msgid "DastProfiles|Are you sure you want to delete this profile?"
@@ -10981,6 +11085,9 @@ msgstr ""
msgid "DastProfiles|Branch missing"
msgstr ""
+msgid "DastProfiles|Choose a scan method"
+msgstr ""
+
msgid "DastProfiles|Could not create the scanner profile. Please try again."
msgstr ""
@@ -11050,7 +11157,13 @@ msgstr ""
msgid "DastProfiles|Excluded URLs"
msgstr ""
-msgid "DastProfiles|Excluded URLs (Optional)"
+msgid "DastProfiles|Excluded URLs (optional)"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths (optional)"
msgstr ""
msgid "DastProfiles|Hide debug messages"
@@ -11107,9 +11220,6 @@ msgstr ""
msgid "DastProfiles|Request headers"
msgstr ""
-msgid "DastProfiles|Rest API"
-msgstr ""
-
msgid "DastProfiles|Run the AJAX spider, in addition to the traditional spider, to crawl the target site."
msgstr ""
@@ -11119,6 +11229,9 @@ msgstr ""
msgid "DastProfiles|Save profile"
msgstr ""
+msgid "DastProfiles|Scan method"
+msgstr ""
+
msgid "DastProfiles|Scan mode"
msgstr ""
@@ -11197,12 +11310,24 @@ msgstr ""
msgid "DastProfiles|Website"
msgstr ""
+msgid "DastProfiles|What does each method do?"
+msgstr ""
+
msgid "DastProfiles|You can either choose a passive scan or validate the target site from the site profile management page. %{docsLinkStart}Learn more about site validation.%{docsLinkEnd}"
msgstr ""
msgid "DastProfiles|You cannot run an active scan against an unvalidated site."
msgstr ""
+msgid "DastProfiles|folder/dast_example.har or https://example.com/dast_example.har"
+msgstr ""
+
+msgid "DastProfiles|folder/example.postman_collection.json or https://example.com/"
+msgstr ""
+
+msgid "DastProfiles|folder/openapi.json or https://example.com/openapi.json"
+msgstr ""
+
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
@@ -11310,6 +11435,9 @@ msgstr ""
msgid "DatadogIntegration|API URL"
msgstr ""
+msgid "DatadogIntegration|Custom tags in Datadog. Enter one tag per line in the %{codeOpen}key:value%{codeClose} format. %{linkOpen}How do I use tags?%{linkClose}"
+msgstr ""
+
msgid "DatadogIntegration|Environment"
msgstr ""
@@ -11328,12 +11456,18 @@ msgstr ""
msgid "DatadogIntegration|Tag all data from this GitLab instance in Datadog. Useful when managing several self-managed deployments."
msgstr ""
+msgid "DatadogIntegration|Tags"
+msgstr ""
+
msgid "DatadogIntegration|The Datadog site to send data to. To send data to the EU site, use %{codeOpen}datadoghq.eu%{codeClose}."
msgstr ""
msgid "DatadogIntegration|Trace your GitLab pipelines with Datadog."
msgstr ""
+msgid "DatadogIntegration|have an invalid format"
+msgstr ""
+
msgid "Datasource name not found"
msgstr ""
@@ -11343,9 +11477,6 @@ msgstr ""
msgid "Date merged"
msgstr ""
-msgid "Date picker"
-msgstr ""
-
msgid "Date range"
msgstr ""
@@ -11499,9 +11630,6 @@ msgstr ""
msgid "Definition"
msgstr ""
-msgid "Delayed Project Deletion (%{adjourned_deletion})"
-msgstr ""
-
msgid "DelayedJobs|Are you sure you want to run %{jobName} immediately? Otherwise this job will run automatically after its timer finishes."
msgstr ""
@@ -11580,10 +11708,10 @@ msgstr ""
msgid "Delete pipeline"
msgstr ""
-msgid "Delete project"
+msgid "Delete pipeline schedule"
msgstr ""
-msgid "Delete project. Are you ABSOLUTELY SURE?"
+msgid "Delete project"
msgstr ""
msgid "Delete row"
@@ -11613,6 +11741,9 @@ msgstr ""
msgid "Delete this epic and all descendants?"
msgstr ""
+msgid "Delete this project"
+msgstr ""
+
msgid "Delete user list"
msgstr ""
@@ -11871,6 +12002,12 @@ msgstr ""
msgid "Deploy to..."
msgstr ""
+msgid "DeployBoards|To see deployment progress for your environments, make sure you are deploying to %{codeStart}$KUBE_NAMESPACE%{codeEnd} and annotating with %{codeStart}app.gitlab.com/app=$CI_PROJECT_PATH_SLUG%{codeEnd} and %{codeStart}app.gitlab.com/env=$CI_ENVIRONMENT_SLUG%{codeEnd}."
+msgstr ""
+
+msgid "DeployBoard|Kubernetes Pods"
+msgstr ""
+
msgid "DeployFreeze|Add a freeze period to prevent unintended releases during a period of time for a given environment. You must update the deployment jobs in %{filename} according to the deploy freezes added here. %{freeze_period_link_start}Learn more.%{freeze_period_link_end}"
msgstr ""
@@ -11955,9 +12092,6 @@ msgstr ""
msgid "DeployTokens|Active Deploy Tokens (%{active_tokens})"
msgstr ""
-msgid "DeployTokens|Allows read and write access to registry images."
-msgstr ""
-
msgid "DeployTokens|Allows read and write access to the package registry."
msgstr ""
@@ -11970,6 +12104,9 @@ msgstr ""
msgid "DeployTokens|Allows read-only access to the repository."
msgstr ""
+msgid "DeployTokens|Allows write access to registry images."
+msgstr ""
+
msgid "DeployTokens|Copy deploy token"
msgstr ""
@@ -12063,12 +12200,57 @@ msgstr ""
msgid "Deploying to AWS is easy with GitLab"
msgstr ""
+msgid "Deployment"
+msgstr ""
+
msgid "Deployment Frequency"
msgstr ""
+msgid "Deployment Target|Project deployment target (optional)"
+msgstr ""
+
+msgid "Deployment Target|Select the deployment target"
+msgstr ""
+
msgid "Deployment frequency"
msgstr ""
+msgid "DeploymentTarget|GitLab Pages"
+msgstr ""
+
+msgid "DeploymentTarget|Heroku"
+msgstr ""
+
+msgid "DeploymentTarget|Infrastructure provider (Terraform, Cloudformation, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Kubernetes (GKE, EKS, OpenShift, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Managed container runtime (Fargate, Cloud Run, DigitalOcean App)"
+msgstr ""
+
+msgid "DeploymentTarget|Mobile app store"
+msgstr ""
+
+msgid "DeploymentTarget|No deployment planned"
+msgstr ""
+
+msgid "DeploymentTarget|Other hosting service"
+msgstr ""
+
+msgid "DeploymentTarget|Registry (package or container)"
+msgstr ""
+
+msgid "DeploymentTarget|Self-managed container runtime (Podman, Docker Swarm, Docker Compose)"
+msgstr ""
+
+msgid "DeploymentTarget|Serverless backend (Lambda, Cloud functions)"
+msgstr ""
+
+msgid "DeploymentTarget|Virtual machine (for example, EC2)"
+msgstr ""
+
msgid "Deployments"
msgstr ""
@@ -12107,6 +12289,9 @@ msgstr ""
msgid "Deployment|This deployment was created using the API"
msgstr ""
+msgid "Deployment|Triggerer"
+msgstr ""
+
msgid "Deployment|Waiting"
msgstr ""
@@ -12134,6 +12319,18 @@ msgstr ""
msgid "Deprecated API rate limits"
msgstr ""
+msgid "Deprecations|Feature deprecation and removal"
+msgstr ""
+
+msgid "Deprecations|For information on a possible replacement %{epicStart} learn more about Opstrace %{epicEnd}."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7 and are %{epicStart} scheduled for removal %{epicEnd} in GitLab 15.0."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7, and are %{removal_link_start} scheduled for removal %{link_end} in GitLab 15.0. For information on a possible replacement, %{opstrace_link_start} learn more about Opstrace %{link_end}."
+msgstr ""
+
msgid "Deprioritize label"
msgstr ""
@@ -12379,10 +12576,10 @@ msgstr ""
msgid "DevopsAdoption|At least one deploy"
msgstr ""
-msgid "DevopsAdoption|At least one issue opened"
+msgid "DevopsAdoption|At least one issue created"
msgstr ""
-msgid "DevopsAdoption|At least one merge request opened"
+msgid "DevopsAdoption|At least one merge request created"
msgstr ""
msgid "DevopsAdoption|At least one pipeline successfully run"
@@ -12583,6 +12780,9 @@ msgstr ""
msgid "Direct member"
msgstr ""
+msgid "Direct members"
+msgstr ""
+
msgid "Direct non-authenticated users to this page."
msgstr ""
@@ -12699,6 +12899,9 @@ msgid_plural "Dismiss %d selected vulnerabilities as"
msgstr[0] ""
msgstr[1] ""
+msgid "Dismiss Alert"
+msgstr ""
+
msgid "Dismiss merge request promotion"
msgstr ""
@@ -12726,9 +12929,15 @@ msgstr ""
msgid "Display alerts from all configured monitoring tools."
msgstr ""
+msgid "Display milestones"
+msgstr ""
+
msgid "Display name"
msgstr ""
+msgid "Display progress of child issues"
+msgstr ""
+
msgid "Display rendered file"
msgstr ""
@@ -12834,6 +13043,9 @@ msgstr ""
msgid "Download image"
msgstr ""
+msgid "Download payload"
+msgstr ""
+
msgid "Download raw data (.csv)"
msgstr ""
@@ -13011,6 +13223,9 @@ msgstr ""
msgid "Edit in Web IDE"
msgstr ""
+msgid "Edit in pipeline editor"
+msgstr ""
+
msgid "Edit in single-file editor"
msgstr ""
@@ -13053,6 +13268,9 @@ msgstr ""
msgid "Edit your most recent comment in a thread (from an empty textarea)"
msgstr ""
+msgid "Edit, lint, and visualize your pipeline."
+msgstr ""
+
msgid "Edited"
msgstr ""
@@ -13494,6 +13712,9 @@ msgstr ""
msgid "Enforce two-factor authentication for all user sign-ins."
msgstr ""
+msgid "Enhance security by storing service account keys in secret managers - learn more about %{docLinkStart}secret management with GitLab%{docLinkEnd}"
+msgstr ""
+
msgid "Ensure connectivity is available from the GitLab server to the Prometheus server"
msgstr ""
@@ -13554,6 +13775,9 @@ 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 following to confirm:"
+msgstr ""
+
msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
@@ -14084,9 +14308,6 @@ 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 ""
@@ -14222,6 +14443,9 @@ msgstr ""
msgid "Errors:"
msgstr ""
+msgid "Escalate this incident"
+msgstr ""
+
msgid "Escalation Policies"
msgstr ""
@@ -14234,6 +14458,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy"
+msgstr ""
+
msgid "Escalation policy:"
msgstr ""
@@ -14485,6 +14712,9 @@ msgstr ""
msgid "Existing sign in methods may be removed"
msgstr ""
+msgid "Exit."
+msgstr ""
+
msgid "Expand"
msgstr ""
@@ -14581,6 +14811,9 @@ msgstr ""
msgid "Explore public groups"
msgstr ""
+msgid "Explore public projects"
+msgstr ""
+
msgid "Explore snippets"
msgstr ""
@@ -14742,7 +14975,7 @@ msgid_plural "Failed to archive designs. Please try again."
msgstr[0] ""
msgstr[1] ""
-msgid "Failed to assign a reviewer because no user was found."
+msgid "Failed to assign a reviewer because no user was specified."
msgstr ""
msgid "Failed to assign a user because no user was found."
@@ -14808,10 +15041,10 @@ msgstr ""
msgid "Failed to find import label for Jira import."
msgstr ""
-msgid "Failed to generate export, please try again later."
+msgid "Failed to find users for %{missing}"
msgstr ""
-msgid "Failed to generate report, please try again after sometime"
+msgid "Failed to generate export, please try again later."
msgstr ""
msgid "Failed to get ref."
@@ -14910,6 +15143,9 @@ msgstr ""
msgid "Failed to remove a to-do item for the design."
msgstr ""
+msgid "Failed to remove attention because no user was found."
+msgstr ""
+
msgid "Failed to remove mirror."
msgstr ""
@@ -14922,6 +15158,9 @@ msgstr ""
msgid "Failed to remove user key."
msgstr ""
+msgid "Failed to request attention because no user was found."
+msgstr ""
+
msgid "Failed to reset key. Please try again."
msgstr ""
@@ -15003,6 +15242,9 @@ msgstr ""
msgid "Feature Flags"
msgstr ""
+msgid "Feature deprecation and removal"
+msgstr ""
+
msgid "Feature flag status"
msgstr ""
@@ -15500,7 +15742,7 @@ msgstr ""
msgid "For each job, re-use the project workspace. If the workspace doesn't exist, use %{code_open}git clone%{code_close}."
msgstr ""
-msgid "For example, the application using the token or the purpose of the token."
+msgid "For example, the application using the token or the purpose of the token. Do not give sensitive information for the name of the token, as it will be visible to all %{resource_type} members."
msgstr ""
msgid "For files larger than this limit, only index the file name. The file content is neither indexed nor searchable."
@@ -15584,9 +15826,6 @@ msgstr ""
msgid "ForkProject|Select a namespace"
msgstr ""
-msgid "ForkProject|Select a namespace to fork the project"
-msgstr ""
-
msgid "ForkProject|The project can be accessed by any logged in user."
msgstr ""
@@ -15683,6 +15922,9 @@ msgstr ""
msgid "Full name"
msgstr ""
+msgid "GCP region configured"
+msgstr ""
+
msgid "GPG Key ID:"
msgstr ""
@@ -15863,6 +16105,9 @@ msgstr ""
msgid "Geo|Failed"
msgstr ""
+msgid "Geo|Filter Geo sites"
+msgstr ""
+
msgid "Geo|Filter by name"
msgstr ""
@@ -16274,6 +16519,12 @@ msgstr ""
msgid "GitLab Issue"
msgstr ""
+msgid "GitLab KAS"
+msgstr ""
+
+msgid "GitLab Memberships CSV Export"
+msgstr ""
+
msgid "GitLab Pages"
msgstr ""
@@ -16322,6 +16573,9 @@ 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 free to use. Many features for larger teams are part of our %{link_start}paid products%{link_end}. You can try Ultimate for free without any obligation or payment details."
+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 ""
@@ -16448,7 +16702,7 @@ msgstr ""
msgid "GitLabPages|When enabled, all attempts to visit your website through HTTP are automatically redirected to HTTPS using a response with status code 301. Requires a valid certificate for all domains. %{docs_link_start}Learn more.%{link_end}"
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. %{docs_link_start}Learn more.%{link_end}"
+msgid "GitLabPages|When using Pages under the general domain of a GitLab instance (%{pages_host}), you cannot use HTTPS with subdomains of subdomains. If your namespace or groupname contains a dot, it does not work. This is a limitation of the HTTP Over TLS protocol. HTTP pages work if you don't redirect HTTP to HTTPS. %{docs_link_start}Learn more.%{link_end}"
msgstr ""
msgid "GitLabPages|With GitLab Pages you can host your static website directly from your GitLab repository. %{docs_link_start}Learn more.%{link_end}"
@@ -16625,9 +16879,6 @@ msgstr ""
msgid "Go to find file"
msgstr ""
-msgid "Go to fork"
-msgstr ""
-
msgid "Go to issue boards"
msgstr ""
@@ -16835,9 +17086,6 @@ msgstr ""
msgid "Group Hooks"
msgstr ""
-msgid "Group ID"
-msgstr ""
-
msgid "Group Owner must have signed in with SAML before enabling Group Managed Accounts"
msgstr ""
@@ -16865,9 +17113,6 @@ msgstr ""
msgid "Group by"
msgstr ""
-msgid "Group description"
-msgstr ""
-
msgid "Group description (optional)"
msgstr ""
@@ -16982,7 +17227,7 @@ msgstr ""
msgid "Group: %{name}"
msgstr ""
-msgid "GroupActivityMetrics|Issues opened"
+msgid "GroupActivityMetrics|Issues created"
msgstr ""
msgid "GroupActivityMetrics|Last 90 days"
@@ -16991,7 +17236,7 @@ msgstr ""
msgid "GroupActivityMetrics|Members added"
msgstr ""
-msgid "GroupActivityMetrics|Merge Requests opened"
+msgid "GroupActivityMetrics|Merge Requests created"
msgstr ""
msgid "GroupActivityMetrics|Recent activity"
@@ -17282,6 +17527,9 @@ msgstr ""
msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
+msgid "GroupSettings|Choose a group path that does not start with a dash or end with a period. It can also contain alphanumeric characters and underscores."
+msgstr ""
+
msgid "GroupSettings|Compliance frameworks"
msgstr ""
@@ -17315,7 +17563,7 @@ msgstr ""
msgid "GroupSettings|If not specified at the group or instance level, the default is %{default_initial_branch_name}. Does not affect existing repositories."
msgstr ""
-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."
+msgid "GroupSettings|If the parent group's visibility is lower than the group's current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility."
msgstr ""
msgid "GroupSettings|New runners registration token has been generated!"
@@ -17432,7 +17680,10 @@ msgstr ""
msgid "Groups and projects"
msgstr ""
-msgid "Groups and subgroups"
+msgid "Groups are a great way to organize projects and people."
+msgstr ""
+
+msgid "Groups are the best way to manage projects and members."
msgstr ""
msgid "Groups to synchronize"
@@ -17543,13 +17794,16 @@ msgstr ""
msgid "GroupsTree|Are you sure you want to leave the \"%{fullName}\" group?"
msgstr ""
-msgid "GroupsTree|Edit group"
+msgid "GroupsTree|Delete"
+msgstr ""
+
+msgid "GroupsTree|Edit"
msgstr ""
msgid "GroupsTree|Failed to leave the group. Please make sure you are not the only owner."
msgstr ""
-msgid "GroupsTree|Leave this group"
+msgid "GroupsTree|Leave group"
msgstr ""
msgid "GroupsTree|Loading groups"
@@ -17561,9 +17815,57 @@ msgstr ""
msgid "GroupsTree|No groups or projects matched your search"
msgstr ""
+msgid "GroupsTree|Options"
+msgstr ""
+
msgid "GroupsTree|Search by name"
msgstr ""
+msgid "Groups|Avatar will be removed. Are you sure?"
+msgstr ""
+
+msgid "Groups|Changing group URL can have unintended side effects."
+msgstr ""
+
+msgid "Groups|Checking group URL availability..."
+msgstr ""
+
+msgid "Groups|Enter a descriptive name for your group."
+msgstr ""
+
+msgid "Groups|Group ID"
+msgstr ""
+
+msgid "Groups|Group URL"
+msgstr ""
+
+msgid "Groups|Group avatar"
+msgstr ""
+
+msgid "Groups|Group description (optional)"
+msgstr ""
+
+msgid "Groups|Group name"
+msgstr ""
+
+msgid "Groups|Group path is available."
+msgstr ""
+
+msgid "Groups|Group path is unavailable. Path has been replaced with a suggested available path."
+msgstr ""
+
+msgid "Groups|Learn more"
+msgstr ""
+
+msgid "Groups|Must start with letter, digit, emoji, or underscore. Can also contain periods, dashes, spaces, and parentheses."
+msgstr ""
+
+msgid "Groups|Remove avatar"
+msgstr ""
+
+msgid "Groups|Save changes"
+msgstr ""
+
msgid "Guideline"
msgstr ""
@@ -17573,6 +17875,9 @@ msgstr ""
msgid "HAR file path or URL"
msgstr ""
+msgid "HTTP Archive (HAR)"
+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 ""
@@ -17973,6 +18278,9 @@ msgstr ""
msgid "INFO: Your SSH key is expiring soon. Please generate a new key."
msgstr ""
+msgid "IP"
+msgstr ""
+
msgid "IP Address"
msgstr ""
@@ -18009,6 +18317,9 @@ msgstr ""
msgid "IdentityVerification|Verify your identity"
msgstr ""
+msgid "IdentityVerification|You can always verify your account at a later time to create a group."
+msgstr ""
+
msgid "If any indexed field exceeds this limit, it is truncated to this number of characters. The rest of the content is neither indexed nor searchable. This does not apply to repository and wiki indexing. For unlimited characters, set this to 0."
msgstr ""
@@ -18066,6 +18377,9 @@ msgstr ""
msgid "If you add %{codeStart}needs%{codeEnd} to jobs in your pipeline you'll be able to view the %{codeStart}needs%{codeEnd} relationships between jobs in this tab as a %{linkStart}Directed Acyclic Graph (DAG)%{linkEnd}."
msgstr ""
+msgid "If you are added to a project, it will be displayed here."
+msgstr ""
+
msgid "If you did not initiate these sign-in attempts, please reach out to your administrator or enable two-factor authentication (2FA) on your account."
msgstr ""
@@ -18372,12 +18686,24 @@ msgstr ""
msgid "InProductMarketing|3 ways to dive into GitLab CI/CD"
msgstr ""
+msgid "InProductMarketing|A single application eliminates complex integrations, data chokepoints, and toolchain maintenance, resulting in greater productivity and lower cost."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features, build more efficiently, strengthen security and compliance."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features."
+msgstr ""
+
msgid "InProductMarketing|Actually, GitLab makes the team work (better)"
msgstr ""
msgid "InProductMarketing|And finally %{deploy_link} a Python application."
msgstr ""
+msgid "InProductMarketing|And many more..."
+msgstr ""
+
msgid "InProductMarketing|Are your runners ready?"
msgstr ""
@@ -18396,15 +18722,33 @@ msgstr ""
msgid "InProductMarketing|Blog"
msgstr ""
+msgid "InProductMarketing|Break down silos to coordinate seamlessly across development, operations, and security with a consistent experience across the development lifecycle."
+msgstr ""
+
+msgid "InProductMarketing|Burn up/down charts"
+msgstr ""
+
msgid "InProductMarketing|By enabling code owners and required merge approvals the right person will review the right MR. This is a win-win: cleaner code and a more efficient review process."
msgstr ""
msgid "InProductMarketing|Click on the number below that corresponds with your answer — 1 being very difficult, 5 being very easy."
msgstr ""
+msgid "InProductMarketing|Code owners"
+msgstr ""
+
msgid "InProductMarketing|Code owners and required merge approvals are part of the paid tiers of GitLab. You can start a free 30-day trial of GitLab Ultimate and enable these features in less than 5 minutes with no credit card required."
msgstr ""
+msgid "InProductMarketing|Code review analytics"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration across stages in GitLab"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration made easy"
+msgstr ""
+
msgid "InProductMarketing|Create a custom CI runner with just a few clicks"
msgstr ""
@@ -18414,12 +18758,21 @@ msgstr ""
msgid "InProductMarketing|Create a project in GitLab in 5 minutes"
msgstr ""
+msgid "InProductMarketing|Create well-defined workflows by using scoped labels on issues, merge requests, and epics. Labels with the same scope cannot be used together, which prevents conflicts."
+msgstr ""
+
msgid "InProductMarketing|Create your first project!"
msgstr ""
+msgid "InProductMarketing|Define who owns specific files or directories, so the right reviewers are suggested when a merge request introduces changes to those files."
+msgstr ""
+
msgid "InProductMarketing|Deliver Better Products Faster"
msgstr ""
+msgid "InProductMarketing|Dependency scanning"
+msgstr ""
+
msgid "InProductMarketing|Did you know teams that use GitLab are far more efficient?"
msgstr ""
@@ -18429,15 +18782,27 @@ msgstr ""
msgid "InProductMarketing|Dig in and create a project and a repo"
msgstr ""
+msgid "InProductMarketing|Discover Premium & Ultimate"
+msgstr ""
+
+msgid "InProductMarketing|Discover Premium & Ultimate."
+msgstr ""
+
msgid "InProductMarketing|Do you have a minute?"
msgstr ""
msgid "InProductMarketing|Do you have a teammate who would be perfect for this task?"
msgstr ""
+msgid "InProductMarketing|Dynamic application security testing"
+msgstr ""
+
msgid "InProductMarketing|Easy"
msgstr ""
+msgid "InProductMarketing|Epics"
+msgstr ""
+
msgid "InProductMarketing|Expand your DevOps journey with a free GitLab trial"
msgstr ""
@@ -18459,9 +18824,15 @@ msgstr ""
msgid "InProductMarketing|Feel the need for speed?"
msgstr ""
+msgid "InProductMarketing|Find and fix bottlenecks in your code review process by understanding how long open merge requests have been in review."
+msgstr ""
+
msgid "InProductMarketing|Find out how your teams are really doing"
msgstr ""
+msgid "InProductMarketing|Find out if your external libraries are safe. Run dependency scanning jobs that check for known vulnerabilities in your external libraries."
+msgstr ""
+
msgid "InProductMarketing|Follow our steps"
msgstr ""
@@ -18498,6 +18869,9 @@ msgstr ""
msgid "InProductMarketing|GitLab is better with teammates to help out!"
msgstr ""
+msgid "InProductMarketing|GitLab is infrastructure agnostic (supporting GCP, AWS, Azure, OpenShift, VMWare, On Prem, Bare Metal, and more), offering a consistent workflow experience – irrespective of the environment."
+msgstr ""
+
msgid "InProductMarketing|GitLab provides static application security testing (SAST), dynamic application security testing (DAST), container scanning, and dependency scanning to help you deliver secure applications along with license compliance."
msgstr ""
@@ -18588,21 +18962,36 @@ msgstr ""
msgid "InProductMarketing|It's also possible to simply %{external_repo_link} in order to take advantage of GitLab's CI/CD."
msgstr ""
+msgid "InProductMarketing|Keep your code quality high by defining who should approve merge requests and how many approvals are required."
+msgstr ""
+
msgid "InProductMarketing|Launch GitLab CI/CD in 20 minutes or less"
msgstr ""
+msgid "InProductMarketing|Lower cost of development"
+msgstr ""
+
+msgid "InProductMarketing|Make it easier to collaborate on high-level ideas by grouping related issues in an epic."
+msgstr ""
+
msgid "InProductMarketing|Making the switch? It's easier than you think to import your projects into GitLab. Move %{github_link}, or import something %{bitbucket_link}."
msgstr ""
msgid "InProductMarketing|Master the art of importing!"
msgstr ""
+msgid "InProductMarketing|Merge request approval rule"
+msgstr ""
+
msgid "InProductMarketing|Move on to easily creating a Pages website %{ci_template_link}"
msgstr ""
msgid "InProductMarketing|Multiple owners, confusing workstreams? We've got you covered"
msgstr ""
+msgid "InProductMarketing|Multiple required approvers"
+msgstr ""
+
msgid "InProductMarketing|Need an alternative to importing?"
msgstr ""
@@ -18615,18 +19004,33 @@ msgstr ""
msgid "InProductMarketing|Our tool brings all the things together"
msgstr ""
+msgid "InProductMarketing|Protect your web application by using DAST to examine for vulnerabilities in deployed environments."
+msgstr ""
+
msgid "InProductMarketing|Rapid development, simplified"
msgstr ""
msgid "InProductMarketing|Reduce Security & Compliance Risk"
msgstr ""
+msgid "InProductMarketing|Require multiple approvers on a merge request, so you know it's in good shape before it's merged."
+msgstr ""
+
+msgid "InProductMarketing|Roadmaps"
+msgstr ""
+
+msgid "InProductMarketing|Scoped labels"
+msgstr ""
+
msgid "InProductMarketing|Security that's integrated into your development lifecycle"
msgstr ""
msgid "InProductMarketing|Sometimes you're not ready to make a full transition to a new tool. If you're not ready to fully commit, %{mirroring_link} gives you a safe way to try out GitLab in parallel with your current tool."
msgstr ""
+msgid "InProductMarketing|Speed. Efficiency. Trust."
+msgstr ""
+
msgid "InProductMarketing|Spin up an autoscaling runner in GitLab"
msgstr ""
@@ -18636,6 +19040,9 @@ msgstr ""
msgid "InProductMarketing|Start a Self-Managed trial"
msgstr ""
+msgid "InProductMarketing|Start a free trial"
+msgstr ""
+
msgid "InProductMarketing|Start a free trial of GitLab Ultimate – no credit card required"
msgstr ""
@@ -18702,6 +19109,9 @@ msgstr ""
msgid "InProductMarketing|To understand and get the most out of GitLab, start at the beginning and %{project_link}. In GitLab, repositories are part of a project, so after you've created your project you can go ahead and %{repo_link}."
msgstr ""
+msgid "InProductMarketing|Track completed issues in a chart, so you can see how a milestone is progressing at a glance."
+msgstr ""
+
msgid "InProductMarketing|Try GitLab Ultimate for free"
msgstr ""
@@ -18738,6 +19148,9 @@ msgstr ""
msgid "InProductMarketing|Very easy"
msgstr ""
+msgid "InProductMarketing|Visualize your epics and milestones in a timeline."
+msgstr ""
+
msgid "InProductMarketing|Want to host GitLab on your servers?"
msgstr ""
@@ -18759,6 +19172,9 @@ msgstr ""
msgid "InProductMarketing|YouTube"
msgstr ""
+msgid "InProductMarketing|Your software, deployed your way"
+msgstr ""
+
msgid "InProductMarketing|Your teams can be more efficient"
msgstr ""
@@ -18879,9 +19295,18 @@ msgstr ""
msgid "IncidentManagement|No incidents to display."
msgstr ""
+msgid "IncidentManagement|None"
+msgstr ""
+
msgid "IncidentManagement|Open"
msgstr ""
+msgid "IncidentManagement|Page your team with escalation policies"
+msgstr ""
+
+msgid "IncidentManagement|Paged"
+msgstr ""
+
msgid "IncidentManagement|Published"
msgstr ""
@@ -18891,6 +19316,9 @@ msgstr ""
msgid "IncidentManagement|Severity"
msgstr ""
+msgid "IncidentManagement|Status"
+msgstr ""
+
msgid "IncidentManagement|There are no closed incidents"
msgstr ""
@@ -18909,6 +19337,9 @@ msgstr ""
msgid "IncidentManagement|Unpublished"
msgstr ""
+msgid "IncidentManagement|Use escalation policies to automatically page your team when incidents are created."
+msgstr ""
+
msgid "IncidentSettings|Activate \"time to SLA\" countdown timer"
msgstr ""
@@ -18954,7 +19385,10 @@ msgstr ""
msgid "Incidents"
msgstr ""
-msgid "Incidents|Add a URL"
+msgid "Incidents|Add image details"
+msgstr ""
+
+msgid "Incidents|Add text or a link to display with your image. If you don't add either, the file name displays instead."
msgstr ""
msgid "Incidents|Drop or %{linkStart}upload%{linkEnd} a metric screenshot to attach it to the incident"
@@ -18969,10 +19403,10 @@ msgstr ""
msgid "Incidents|There was an issue loading metric images."
msgstr ""
-msgid "Incidents|There was an issue uploading your image."
+msgid "Incidents|There was an issue updating your image."
msgstr ""
-msgid "Incidents|You can optionally add a URL to link users to the original graph."
+msgid "Incidents|There was an issue uploading your image."
msgstr ""
msgid "Incident|Alert details"
@@ -18981,9 +19415,18 @@ msgstr ""
msgid "Incident|Are you sure you wish to delete this image?"
msgstr ""
+msgid "Incident|Delete image"
+msgstr ""
+
msgid "Incident|Deleting %{filename}"
msgstr ""
+msgid "Incident|Edit image text or link"
+msgstr ""
+
+msgid "Incident|Editing %{filename}"
+msgstr ""
+
msgid "Incident|Metrics"
msgstr ""
@@ -19253,12 +19696,18 @@ msgstr ""
msgid "Integrations|Branches for which notifications are to be sent"
msgstr ""
+msgid "Integrations|Clear if using a self-signed certificate."
+msgstr ""
+
msgid "Integrations|Comment detail:"
msgstr ""
msgid "Integrations|Comment settings:"
msgstr ""
+msgid "Integrations|Connection details"
+msgstr ""
+
msgid "Integrations|Connection failed. Please check your settings."
msgstr ""
@@ -19283,6 +19732,9 @@ msgstr ""
msgid "Integrations|Enable GitLab.com slash commands in a Slack workspace."
msgstr ""
+msgid "Integrations|Enable SSL verification"
+msgstr ""
+
msgid "Integrations|Enable comments"
msgstr ""
@@ -19361,6 +19813,9 @@ msgstr ""
msgid "Integrations|Return to GitLab for Jira"
msgstr ""
+msgid "Integrations|SSL verification"
+msgstr ""
+
msgid "Integrations|Save settings?"
msgstr ""
@@ -19406,9 +19861,6 @@ msgstr ""
msgid "Integrations|Use default settings"
msgstr ""
-msgid "Integrations|When you mention a Jira issue in a commit or merge request, GitLab creates a remote link and comment (if enabled)."
-msgstr ""
-
msgid "Integrations|You can now close this window and return to the GitLab for Jira application."
msgstr ""
@@ -19433,9 +19885,6 @@ msgstr ""
msgid "Integrations|can't exceed %{recipients_limit}"
msgstr ""
-msgid "Interactive developer security education."
-msgstr ""
-
msgid "Interactive mode"
msgstr ""
@@ -19925,6 +20374,9 @@ msgstr ""
msgid "IssueAnalytics|Assignees"
msgstr ""
+msgid "IssueAnalytics|Created by"
+msgstr ""
+
msgid "IssueAnalytics|Due date"
msgstr ""
@@ -19937,9 +20389,6 @@ msgstr ""
msgid "IssueAnalytics|Milestone"
msgstr ""
-msgid "IssueAnalytics|Opened by"
-msgstr ""
-
msgid "IssueAnalytics|Status"
msgstr ""
@@ -20063,10 +20512,10 @@ msgstr ""
msgid "IssuesAnalytics|Avg/Month:"
msgstr ""
-msgid "IssuesAnalytics|Issues opened"
+msgid "IssuesAnalytics|Issues created"
msgstr ""
-msgid "IssuesAnalytics|Issues opened per month"
+msgid "IssuesAnalytics|Issues created per month"
msgstr ""
msgid "IssuesAnalytics|Last 12 months"
@@ -20093,6 +20542,9 @@ msgstr ""
msgid "It looks like you have some draft commits in this branch."
msgstr ""
+msgid "It looks like you're attempting to activate your subscription. Use %{a_start}the Subscription page%{a_end} instead."
+msgstr ""
+
msgid "It may be several days before you see feature usage data."
msgstr ""
@@ -20321,6 +20773,9 @@ msgstr ""
msgid "JiraConnect|You can now close this window and return to Jira."
msgstr ""
+msgid "JiraConnect|You don't have permission to create branches for this project. Select a different project or contact the project owner for access. %{linkStart}Learn more.%{linkEnd}"
+msgstr ""
+
msgid "JiraRequest|A connection error occurred while connecting to Jira. Try your request again."
msgstr ""
@@ -20369,13 +20824,13 @@ msgstr ""
msgid "JiraService|Define the type of Jira issue to create from a vulnerability."
msgstr ""
-msgid "JiraService|Displaying Jira issues while leaving the GitLab issue functionality enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
+msgid "JiraService|Displaying Jira issues while leaving GitLab issues also enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
msgstr ""
-msgid "JiraService|Enable Jira issues"
+msgid "JiraService|Enable Jira issue creation from vulnerabilities"
msgstr ""
-msgid "JiraService|Enable Jira issues creation from vulnerabilities"
+msgid "JiraService|Enable Jira issues"
msgstr ""
msgid "JiraService|Enable Jira transitions"
@@ -20492,16 +20947,19 @@ msgstr ""
msgid "JiraService|View Jira issues in GitLab"
msgstr ""
-msgid "JiraService|Warning: All GitLab users that have access to this GitLab project are able to view all issues from the Jira project specified below."
+msgid "JiraService|Warning: All GitLab users with access to this GitLab project can view all issues from the Jira project you select."
msgstr ""
msgid "JiraService|Web URL"
msgstr ""
-msgid "JiraService|Work on Jira issues without leaving GitLab. Adds a Jira menu to access your list of Jira issues and view any issue as read-only."
+msgid "JiraService|When a Jira issue is mentioned in a commit or merge request, a remote link and comment (if enabled) will be created."
+msgstr ""
+
+msgid "JiraService|Work on Jira issues without leaving GitLab. Add a Jira menu to access a read-only list of your Jira issues."
msgstr ""
-msgid "JiraService|You need to configure Jira before enabling this integration. For more details, read the %{jira_doc_link_start}Jira integration documentation%{link_end}."
+msgid "JiraService|You must configure Jira before enabling this integration. %{jira_doc_link_start}Learn more.%{link_end}"
msgstr ""
msgid "Job"
@@ -20513,9 +20971,6 @@ msgstr ""
msgid "Job Failed #%{build_id}"
msgstr ""
-msgid "Job ID"
-msgstr ""
-
msgid "Job artifact"
msgstr ""
@@ -20582,9 +21037,27 @@ msgstr ""
msgid "Jobs|You're about to retry a job that failed because it attempted to deploy code that is older than the latest deployment. Retrying this job could result in overwriting the environment with the older source code."
msgstr ""
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source} into %{target}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{ref}"
+msgstr ""
+
+msgid "Job|Are you sure you want to erase this job log and artifacts?"
+msgstr ""
+
msgid "Job|Browse"
msgstr ""
+msgid "Job|Cancel"
+msgstr ""
+
msgid "Job|Complete Raw"
msgstr ""
@@ -20594,6 +21067,9 @@ msgstr ""
msgid "Job|Erase job log and artifacts"
msgstr ""
+msgid "Job|Finished at"
+msgstr ""
+
msgid "Job|Job artifacts"
msgstr ""
@@ -20606,7 +21082,7 @@ msgstr ""
msgid "Job|Keep"
msgstr ""
-msgid "Job|Pipeline"
+msgid "Job|Retry"
msgstr ""
msgid "Job|Scroll to bottom"
@@ -20618,6 +21094,9 @@ msgstr ""
msgid "Job|Show complete raw"
msgstr ""
+msgid "Job|Status"
+msgstr ""
+
msgid "Job|The artifacts were removed"
msgstr ""
@@ -20645,21 +21124,12 @@ msgstr ""
msgid "Job|delayed"
msgstr ""
-msgid "Job|for"
-msgstr ""
-
-msgid "Job|into"
-msgstr ""
-
msgid "Job|manual"
msgstr ""
msgid "Job|triggered"
msgstr ""
-msgid "Job|with"
-msgstr ""
-
msgid "Join Zoom meeting"
msgstr ""
@@ -20762,9 +21232,6 @@ msgstr ""
msgid "Ki"
msgstr ""
-msgid "Kontra"
-msgstr ""
-
msgid "Kroki"
msgstr ""
@@ -21088,6 +21555,9 @@ msgstr ""
msgid "Learn more about Auto DevOps"
msgstr ""
+msgid "Learn more about GitLab"
+msgstr ""
+
msgid "Learn more about Needs relationships"
msgstr ""
@@ -21415,9 +21885,18 @@ msgstr ""
msgid "Licenses|Displays licenses detected in the project, based on the %{linkStart}latest successful%{linkEnd} scan"
msgstr ""
+msgid "Licenses|Drag your license file here or %{linkStart}click to upload%{linkEnd}."
+msgstr ""
+
+msgid "Licenses|Drop your license file to start the upload."
+msgstr ""
+
msgid "Licenses|Error fetching the license list. Please check your network connection and try again."
msgstr ""
+msgid "Licenses|Error: You are trying to upload something other than a file"
+msgstr ""
+
msgid "Licenses|License Compliance"
msgstr ""
@@ -21436,6 +21915,9 @@ msgstr ""
msgid "Licenses|Specified policies in this project"
msgstr ""
+msgid "Licenses|The file could not be uploaded."
+msgstr ""
+
msgid "Licenses|The license list details information about the licenses used within your project."
msgstr ""
@@ -21469,11 +21951,6 @@ msgstr ""
msgid "Limit the size of Sidekiq jobs stored in Redis."
msgstr ""
-msgid "Limited to showing %d event at most"
-msgid_plural "Limited to showing %d events at most"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Limiting mode"
msgstr ""
@@ -21483,6 +21960,9 @@ msgstr ""
msgid "Link"
msgstr ""
+msgid "Link (optional)"
+msgstr ""
+
msgid "Link Prometheus monitoring to GitLab."
msgstr ""
@@ -21519,6 +21999,9 @@ msgstr ""
msgid "Linked emails (%{email_count})"
msgstr ""
+msgid "Linked epics"
+msgstr ""
+
msgid "Linked issues"
msgstr ""
@@ -21546,6 +22029,15 @@ msgstr ""
msgid "List of all merge commits"
msgstr ""
+msgid "List of environments for this project"
+msgstr ""
+
+msgid "List of suitable GCP locations"
+msgstr ""
+
+msgid "List of users allowed to exceed the rate limit."
+msgstr ""
+
msgid "List options"
msgstr ""
@@ -21765,6 +22257,9 @@ msgstr ""
msgid "Maintenance mode"
msgstr ""
+msgid "Make adjustments to how your GitLab instance is set up."
+msgstr ""
+
msgid "Make and review changes in the browser with the Web IDE"
msgstr ""
@@ -21909,6 +22404,12 @@ msgstr ""
msgid "MarkdownEditor|Add italic text (%{modifier_key}I)"
msgstr ""
+msgid "MarkdownEditor|Add strikethrough text (%{modifierKey}⇧X)"
+msgstr ""
+
+msgid "MarkdownEditor|Add strikethrough text (%{modifier_key}⇧X)"
+msgstr ""
+
msgid "Marked For Deletion At - %{deletion_time}"
msgstr ""
@@ -22170,6 +22671,9 @@ msgstr ""
msgid "Maximum push size (MB)"
msgstr ""
+msgid "Maximum requests per 10 minutes per user"
+msgstr ""
+
msgid "Maximum requests per minute"
msgstr ""
@@ -22260,6 +22764,19 @@ msgstr ""
msgid "Members of a group may only view projects they have permission to access"
msgstr ""
+msgid "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seat in use and will be billed for the overage."
+msgid_plural "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seats in use and will be billed for the overage."
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "MembersOverage|You are about to incur additional charges"
+msgstr ""
+
+msgid "MembersOverage|Your subscription includes %d seat."
+msgid_plural "MembersOverage|Your subscription includes %d seats."
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Membership"
msgstr ""
@@ -22464,9 +22981,6 @@ msgstr ""
msgid "Merge request not merged"
msgstr ""
-msgid "Merge request pipelines 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 merge request pipelines."
-msgstr ""
-
msgid "Merge request reports"
msgstr ""
@@ -22563,13 +23077,13 @@ msgstr ""
msgid "MergeRequests|Create issue to resolve thread"
msgstr ""
-msgid "MergeRequests|Failed to squash. Should be done manually."
+msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Saving the comment failed"
+msgid "MergeRequests|Squashing failed: Squash the commits locally, resolve any conflicts, then push the branch."
msgstr ""
-msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
+msgid "MergeRequests|Squashing not allowed: This project doesn't allow you to squash commits when merging."
msgstr ""
msgid "MergeRequests|Thread stays resolved"
@@ -23410,6 +23924,18 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "MrList|Assigned to %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from assignee %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from reviewer %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Review requested from %{name}, go to their profile."
+msgstr ""
+
msgid "Multi-project"
msgstr ""
@@ -23443,7 +23969,7 @@ msgstr ""
msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "My Awesome Group"
+msgid "My awesome group"
msgstr ""
msgid "My company or team"
@@ -24065,9 +24591,6 @@ msgstr ""
msgid "No available branches"
msgstr ""
-msgid "No available groups to fork the project."
-msgstr ""
-
msgid "No branches found"
msgstr ""
@@ -24278,6 +24801,9 @@ msgstr ""
msgid "No ref selected"
msgstr ""
+msgid "No regions configured"
+msgstr ""
+
msgid "No related merge requests found."
msgstr ""
@@ -25082,6 +25608,9 @@ msgstr ""
msgid "Only reCAPTCHA v2 is supported:"
msgstr ""
+msgid "Only required if not using role instance credentials."
+msgstr ""
+
msgid "Only use lowercase letters, numbers, and underscores."
msgstr ""
@@ -25106,9 +25635,6 @@ msgstr ""
msgid "Open a CLI and connect to the cluster you want to install the agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
-msgid "Open epics"
-msgstr ""
-
msgid "Open errors"
msgstr ""
@@ -25148,7 +25674,7 @@ msgstr ""
msgid "Opened issues"
msgstr ""
-msgid "OpenedNDaysAgo|Opened"
+msgid "OpenedNDaysAgo|Created"
msgstr ""
msgid "Opens in a new window"
@@ -25193,9 +25719,6 @@ msgstr ""
msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
-msgid "Optional."
-msgstr ""
-
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
msgstr ""
@@ -25984,6 +26507,9 @@ msgstr ""
msgid "PerformanceBar|Memory"
msgstr ""
+msgid "PerformanceBar|Memory report"
+msgstr ""
+
msgid "PerformanceBar|Redis calls"
msgstr ""
@@ -26017,18 +26543,12 @@ msgstr ""
msgid "PerformanceBar|wall"
msgstr ""
-msgid "Performs a rebase but skips triggering a new pipeline"
-msgstr ""
-
msgid "Period in seconds"
msgstr ""
msgid "Permalink"
msgstr ""
-msgid "Permanently delete project"
-msgstr ""
-
msgid "Permanently remove group"
msgstr ""
@@ -26299,6 +26819,51 @@ msgstr ""
msgid "PipelineStatusTooltip|Pipeline: %{ci_status}"
msgstr ""
+msgid "PipelineWizardDefaultCommitMessage|Add %{filename}"
+msgstr ""
+
+msgid "PipelineWizardDefaultCommitMessage|Update %{filename}"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|At least one entry is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This field is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This value is not valid"
+msgstr ""
+
+msgid "PipelineWizardListWidget|add another step"
+msgstr ""
+
+msgid "PipelineWizardListWidget|remove step"
+msgstr ""
+
+msgid "PipelineWizard|Commit"
+msgstr ""
+
+msgid "PipelineWizard|Commit Message"
+msgstr ""
+
+msgid "PipelineWizard|Commit changes to your file"
+msgstr ""
+
+msgid "PipelineWizard|Commit file to Branch"
+msgstr ""
+
+msgid "PipelineWizard|Commit your new file"
+msgstr ""
+
+msgid "PipelineWizard|The file has been committed."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem committing the changes."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem while checking whether your file already exists in the specified branch."
+msgstr ""
+
msgid "Pipelines"
msgstr ""
@@ -26413,7 +26978,7 @@ msgstr ""
msgid "Pipelines|Project cache successfully reset."
msgstr ""
-msgid "Pipelines|Revoke"
+msgid "Pipelines|Revoke trigger"
msgstr ""
msgid "Pipelines|Something went wrong while cleaning runners cache."
@@ -26458,6 +27023,12 @@ msgstr ""
msgid "Pipelines|This is a child pipeline within the parent pipeline"
msgstr ""
+msgid "Pipelines|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipelines|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipelines|This pipeline will run code originating from a forked project merge request. This means that the code can potentially have security considerations like exposing CI variables."
msgstr ""
@@ -26500,9 +27071,6 @@ msgstr ""
msgid "Pipelines|Your changes have been successfully committed. Now redirecting to the new merge request page."
msgstr ""
-msgid "Pipelines|detached"
-msgstr ""
-
msgid "Pipelines|error"
msgstr ""
@@ -26512,10 +27080,13 @@ msgstr ""
msgid "Pipelines|latest"
msgstr ""
-msgid "Pipelines|stuck"
+msgid "Pipelines|merge request"
msgstr ""
-msgid "Pipelines|train"
+msgid "Pipelines|merge train"
+msgstr ""
+
+msgid "Pipelines|stuck"
msgstr ""
msgid "Pipelines|yaml invalid"
@@ -26647,6 +27218,12 @@ msgstr ""
msgid "Pipeline|This change will not change the overall test coverage if merged."
msgstr ""
+msgid "Pipeline|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipeline|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipeline|Trigger author"
msgstr ""
@@ -26671,6 +27248,12 @@ msgstr ""
msgid "Pipeline|for"
msgstr ""
+msgid "Pipeline|merge request"
+msgstr ""
+
+msgid "Pipeline|merge train"
+msgstr ""
+
msgid "Pipeline|on"
msgstr ""
@@ -26809,9 +27392,6 @@ msgstr ""
msgid "Please enter a valid time interval"
msgstr ""
-msgid "Please enter or upload a valid license."
-msgstr ""
-
msgid "Please enter your current password."
msgstr ""
@@ -26920,9 +27500,6 @@ msgstr ""
msgid "Please type %{phrase_code} to proceed or close this modal to cancel."
msgstr ""
-msgid "Please type the following to confirm:"
-msgstr ""
-
msgid "Please use this form to report to the admin users who create spam issues, comments or behave inappropriately."
msgstr ""
@@ -26950,12 +27527,27 @@ msgstr ""
msgid "Policies"
msgstr ""
+msgid "Policy '%{escalation_policy_name}' does not exist."
+msgstr ""
+
msgid "Policy management project does have any policies in %{policy_path}"
msgstr ""
msgid "Policy project doesn't exist"
msgstr ""
+msgid "PolicyRuleMultiSelect|%{firstLabel} +%{numberOfAdditionalLabels} more"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|All %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select all"
+msgstr ""
+
msgid "Polling interval multiplier"
msgstr ""
@@ -27184,6 +27776,9 @@ msgstr ""
msgid "Private projects can be created in your personal namespace with:"
msgstr ""
+msgid "Problem with %{name} command: %{message}."
+msgstr ""
+
msgid "Proceed"
msgstr ""
@@ -27658,6 +28253,9 @@ msgstr ""
msgid "Progress"
msgstr ""
+msgid "Progress tracking"
+msgstr ""
+
msgid "Project"
msgstr ""
@@ -27889,6 +28487,9 @@ msgstr ""
msgid "ProjectQualitySummary|Failure"
msgstr ""
+msgid "ProjectQualitySummary|Get insight into the overall percentage of tests in your project that succeed, fail and are skipped."
+msgstr ""
+
msgid "ProjectQualitySummary|Latest pipeline results"
msgstr ""
@@ -27907,6 +28508,12 @@ msgstr ""
msgid "ProjectQualitySummary|See project Code Coverage Statistics"
msgstr ""
+msgid "ProjectQualitySummary|Set up test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|Set up test runs (opens in a new tab)"
+msgstr ""
+
msgid "ProjectQualitySummary|Skipped"
msgstr ""
@@ -28183,13 +28790,19 @@ msgstr ""
msgid "ProjectSettings|LFS objects from this repository are available to forks. %{linkStart}How do I remove them?%{linkEnd}"
msgstr ""
+msgid "ProjectSettings|Learn about commit history."
+msgstr ""
+
+msgid "ProjectSettings|Leave empty to use default template."
+msgstr ""
+
msgid "ProjectSettings|Manage who can see the project in the public access directory."
msgstr ""
msgid "ProjectSettings|Manages large files such as audio, video, and graphics files."
msgstr ""
-msgid "ProjectSettings|Maximum 500 characters."
+msgid "ProjectSettings|Maximum %{maxLength} characters."
msgstr ""
msgid "ProjectSettings|Merge checks"
@@ -28330,6 +28943,9 @@ msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
msgstr ""
+msgid "ProjectSettings|The default template will be applied on save."
+msgstr ""
+
msgid "ProjectSettings|These checks must pass before merge requests can be merged."
msgstr ""
@@ -28384,6 +29000,9 @@ msgstr ""
msgid "ProjectSettings|What are badges?"
msgstr ""
+msgid "ProjectSettings|What are merge trains?"
+msgstr ""
+
msgid "ProjectSettings|When merge request pipelines are enabled in the CI/CD configuration file, pipelines validate the combined results of the source and target branches. %{link_start}How to configure merge request pipelines?%{link_end}"
msgstr ""
@@ -28501,6 +29120,9 @@ msgstr ""
msgid "Projects are organized into groups"
msgstr ""
+msgid "Projects are where you store your code, access issues, wiki and other features of GitLab."
+msgstr ""
+
msgid "Projects contributed to"
msgstr ""
@@ -28516,12 +29138,6 @@ msgstr ""
msgid "Projects to index"
msgstr ""
-msgid "Projects will be permanently deleted after a %{waiting_period}-day waiting period."
-msgstr ""
-
-msgid "Projects will be permanently deleted immediately."
-msgstr ""
-
msgid "Projects with critical vulnerabilities"
msgstr ""
@@ -28606,6 +29222,9 @@ msgstr ""
msgid "ProjectsNew|Import project"
msgstr ""
+msgid "ProjectsNew|Include a Getting Started README"
+msgstr ""
+
msgid "ProjectsNew|Initialize repository with a README"
msgstr ""
@@ -28621,6 +29240,9 @@ msgstr ""
msgid "ProjectsNew|Project description %{tag_start}(optional)%{tag_end}"
msgstr ""
+msgid "ProjectsNew|Recommended if you're new to GitLab"
+msgstr ""
+
msgid "ProjectsNew|Run CI/CD for external repository"
msgstr ""
@@ -29038,6 +29660,9 @@ msgstr ""
msgid "ProtectedBranch|Unprotect"
msgstr ""
+msgid "ProtectedBranch|Unprotect branch"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
@@ -29065,6 +29690,9 @@ msgstr ""
msgid "ProtectedEnvironment|Protected Environment (%{protected_environments_count})"
msgstr ""
+msgid "ProtectedEnvironment|Required approvals"
+msgstr ""
+
msgid "ProtectedEnvironment|Select an environment"
msgstr ""
@@ -29086,10 +29714,13 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|Unprotect tag"
+msgstr ""
+
msgid "ProtectedTags|default"
msgstr ""
-msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
+msgid "ProtectedTag|By default, protected tags restrict who can modify the tag."
msgstr ""
msgid "ProtectedTag|Learn more."
@@ -29152,6 +29783,9 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Public projects are an easy way to allow everyone to have read-only access."
+msgstr ""
+
msgid "Publish to status page"
msgstr ""
@@ -29308,9 +29942,6 @@ msgstr ""
msgid "QualitySummary|Project quality"
msgstr ""
-msgid "Quarters"
-msgstr ""
-
msgid "Query"
msgstr ""
@@ -29395,6 +30026,9 @@ msgstr ""
msgid "Read more about project permissions %{help_link_open}here%{help_link_close}"
msgstr ""
+msgid "Read more about related epics"
+msgstr ""
+
msgid "Read more about related issues"
msgstr ""
@@ -29425,10 +30059,7 @@ msgstr ""
msgid "Rebase source branch on the target branch."
msgstr ""
-msgid "Rebase without CI"
-msgstr ""
-
-msgid "Rebases and triggers a pipeline"
+msgid "Rebase without pipeline"
msgstr ""
msgid "Recaptcha verified?"
@@ -29479,9 +30110,6 @@ msgstr ""
msgid "Reconfigure"
msgstr ""
-msgid "Recovering projects"
-msgstr ""
-
msgid "Recovery Codes"
msgstr ""
@@ -29541,6 +30169,12 @@ msgstr ""
msgid "Regex pattern"
msgstr ""
+msgid "Region"
+msgstr ""
+
+msgid "Regions"
+msgstr ""
+
msgid "Register"
msgstr ""
@@ -29771,9 +30405,6 @@ msgstr ""
msgid "Remove all or specific reviewer(s)"
msgstr ""
-msgid "Remove approver"
-msgstr ""
-
msgid "Remove approvers"
msgstr ""
@@ -29789,6 +30420,9 @@ msgstr ""
msgid "Remove attention request"
msgstr ""
+msgid "Remove attention request(s)"
+msgstr ""
+
msgid "Remove avatar"
msgstr ""
@@ -29927,6 +30561,9 @@ msgstr ""
msgid "Removed an issue from an epic."
msgstr ""
+msgid "Removed attention from %{users_sentence}."
+msgstr ""
+
msgid "Removed attention request from @%{username}"
msgstr ""
@@ -29978,6 +30615,9 @@ msgstr ""
msgid "Removes an issue from an epic."
msgstr ""
+msgid "Removes attention from %{users_sentence}."
+msgstr ""
+
msgid "Removes parent epic %{epic_ref}."
msgstr ""
@@ -30089,6 +30729,9 @@ msgstr ""
msgid "Report abuse to admin"
msgstr ""
+msgid "Report is generating and will be sent to your email address."
+msgstr ""
+
msgid "Reported %{timeAgo} by %{reportedBy}"
msgstr ""
@@ -30378,6 +31021,15 @@ msgstr ""
msgid "Request attention"
msgstr ""
+msgid "Request attention from %{users_sentence}."
+msgstr ""
+
+msgid "Request attention from assignee or reviewer"
+msgstr ""
+
+msgid "Request attention from assignee(s) or reviewer(s)"
+msgstr ""
+
msgid "Request attention to review"
msgstr ""
@@ -30402,6 +31054,9 @@ msgstr ""
msgid "Requested %{time_ago}"
msgstr ""
+msgid "Requested attention from %{users_sentence}."
+msgstr ""
+
msgid "Requested attention from @%{username}"
msgstr ""
@@ -30616,6 +31271,9 @@ msgstr ""
msgid "Restore project"
msgstr ""
+msgid "Restoring projects"
+msgstr ""
+
msgid "Restoring the group will prevent the group, its subgroups and projects from being removed on this date."
msgstr ""
@@ -30646,6 +31304,9 @@ msgstr ""
msgid "Retry"
msgstr ""
+msgid "Retry failed jobs"
+msgstr ""
+
msgid "Retry job"
msgstr ""
@@ -30693,9 +31354,6 @@ msgstr ""
msgid "Review changes"
msgstr ""
-msgid "Review requested from %{name}"
-msgstr ""
-
msgid "Review requests for you"
msgstr ""
@@ -30860,6 +31518,9 @@ msgstr ""
msgid "Runners|Assigned Group"
msgstr ""
+msgid "Runners|Assigned Projects (%{projectCount})"
+msgstr ""
+
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30929,6 +31590,9 @@ msgstr ""
msgid "Runners|Instance"
msgstr ""
+msgid "Runners|Jobs"
+msgstr ""
+
msgid "Runners|Last contact"
msgstr ""
@@ -31022,9 +31686,6 @@ msgstr ""
msgid "Runners|Runner %{name} was deleted"
msgstr ""
-msgid "Runners|Runner ID"
-msgstr ""
-
msgid "Runners|Runner assigned to project."
msgstr ""
@@ -31172,6 +31833,9 @@ msgstr ""
msgid "Runners|stale"
msgstr ""
+msgid "Runner|This runner has not run any jobs."
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -31286,6 +31950,24 @@ msgstr ""
msgid "Saving project."
msgstr ""
+msgid "ScanResultPolicy|%{ifLabelStart}if%{ifLabelEnd} %{scanners} scan in an open merge request targeting the %{branches} branch(es) finds %{vulnerabilitiesAllowed} or more %{severities} vulnerabilities that are %{vulnerabilityStates}"
+msgstr ""
+
+msgid "ScanResultPolicy|%{thenLabelStart}Then%{thenLabelEnd} Require approval from %{approvalsRequired} of the following approvers: %{approvers}"
+msgstr ""
+
+msgid "ScanResultPolicy|add an approver"
+msgstr ""
+
+msgid "ScanResultPolicy|scanners"
+msgstr ""
+
+msgid "ScanResultPolicy|severity levels"
+msgstr ""
+
+msgid "ScanResultPolicy|vulnerability states"
+msgstr ""
+
msgid "Scanner"
msgstr ""
@@ -31418,6 +32100,9 @@ msgstr ""
msgid "Search for a user"
msgstr ""
+msgid "Search for an emoji"
+msgstr ""
+
msgid "Search for projects, issues, etc."
msgstr ""
@@ -31605,18 +32290,12 @@ msgstr ""
msgid "Secret Detection"
msgstr ""
-msgid "Secret access key"
-msgstr ""
-
msgid "Secret token"
msgstr ""
msgid "Secure token that identifies an external storage request."
msgstr ""
-msgid "SecureCodeWarrior"
-msgstr ""
-
msgid "Security"
msgstr ""
@@ -31641,9 +32320,6 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "Security training with guide and learning pathways."
-msgstr ""
-
msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
@@ -31746,7 +32422,7 @@ msgstr ""
msgid "SecurityConfiguration|Manage corpus"
msgstr ""
-msgid "SecurityConfiguration|Manage corpus files used as mutation sources in coverage fuzzing."
+msgid "SecurityConfiguration|Manage corpus files used as seed inputs with coverage-guided fuzzing."
msgstr ""
msgid "SecurityConfiguration|Manage profiles for use by DAST scans."
@@ -31812,15 +32488,15 @@ msgstr ""
msgid "SecurityOrchestration|.yaml preview"
msgstr ""
-msgid "SecurityOrchestration|Action"
-msgstr ""
-
msgid "SecurityOrchestration|Actions"
msgstr ""
msgid "SecurityOrchestration|Add rule"
msgstr ""
+msgid "SecurityOrchestration|After dismissing the alert, the information will never be shown again."
+msgstr ""
+
msgid "SecurityOrchestration|All policies"
msgstr ""
@@ -31836,7 +32512,7 @@ msgstr ""
msgid "SecurityOrchestration|Description"
msgstr ""
-msgid "SecurityOrchestration|Disabled"
+msgid "SecurityOrchestration|Don't show the alert anymore"
msgstr ""
msgid "SecurityOrchestration|Edit policy"
@@ -31845,13 +32521,13 @@ msgstr ""
msgid "SecurityOrchestration|Edit policy project"
msgstr ""
-msgid "SecurityOrchestration|Enabled"
+msgid "SecurityOrchestration|Empty policy name"
msgstr ""
-msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Enabled"
msgstr ""
-msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
msgstr ""
msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
@@ -31860,7 +32536,7 @@ msgstr ""
msgid "SecurityOrchestration|Invalid policy type"
msgstr ""
-msgid "SecurityOrchestration|Latest scan"
+msgid "SecurityOrchestration|Latest scan run against %{agent}"
msgstr ""
msgid "SecurityOrchestration|Network"
@@ -31869,15 +32545,27 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No actions defined - policy will not run."
+msgstr ""
+
+msgid "SecurityOrchestration|No description"
+msgstr ""
+
msgid "SecurityOrchestration|No rules defined - policy will not run."
msgstr ""
+msgid "SecurityOrchestration|Not enabled"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
msgid "SecurityOrchestration|Policies"
msgstr ""
+msgid "SecurityOrchestration|Policy Type"
+msgstr ""
+
msgid "SecurityOrchestration|Policy cannot be enabled for non-existing branches (%{branches})"
msgstr ""
@@ -31902,10 +32590,13 @@ msgstr ""
msgid "SecurityOrchestration|Require %{approvals} %{plural} from %{approvers} if any of the following occur:"
msgstr ""
-msgid "SecurityOrchestration|Rule"
+msgid "SecurityOrchestration|Rules"
msgstr ""
-msgid "SecurityOrchestration|Rules"
+msgid "SecurityOrchestration|Runs %{actions} and %{lastAction} scans"
+msgstr ""
+
+msgid "SecurityOrchestration|Runs a %{action} scan"
msgstr ""
msgid "SecurityOrchestration|Scan Execution"
@@ -31965,6 +32656,9 @@ msgstr ""
msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
+msgid "SecurityOrchestration|This view only shows scan results for the agent %{agent}. You can view scan results for all agents in the %{linkStart}Operational Vulnerabilities tab of the vulnerability report%{linkEnd}."
+msgstr ""
+
msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
@@ -32019,9 +32713,6 @@ msgstr ""
msgid "SecurityOrchestration|users with ids"
msgstr ""
-msgid "SecurityOrchestration|view results"
-msgstr ""
-
msgid "SecurityOrchestration|vulnerabilities"
msgstr ""
@@ -32691,22 +33382,19 @@ 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|In order to start using functions as a service, you must first install Knative on your Kubernetes cluster. %{linkStart}More information%{linkEnd}"
-msgstr ""
-
msgid "Serverless|Learn more about Serverless"
msgstr ""
msgid "Serverless|No functions available"
msgstr ""
-msgid "Serverless|Sign up for First Look"
+msgid "Serverless|Serverless was %{linkStart}deprecated%{linkEnd} in GitLab 14.3."
+msgstr ""
+
+msgid "Serverless|Serverless was %{postLinkStart}deprecated%{postLinkEnd}. But if you opt to use it, you must install Knative in your Kubernetes cluster first. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "Serverless|The deploy job has not finished."
@@ -32718,9 +33406,6 @@ 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 ""
@@ -32736,9 +33421,6 @@ msgstr ""
msgid "Service Account Key"
msgstr ""
-msgid "Service Accounts"
-msgstr ""
-
msgid "Service Accounts keys authorize GitLab to deploy your Google Cloud project"
msgstr ""
@@ -32748,10 +33430,10 @@ msgstr ""
msgid "Service Desk allows people to create issues in your GitLab instance without their own user account. It provides a unique email address for end users to create issues in a project. Replies can be sent either through the GitLab interface or by email. End users only see threads through email."
msgstr ""
-msgid "Service Usage Data"
+msgid "Service account generated successfully"
msgstr ""
-msgid "Service account generated successfully"
+msgid "Service accounts"
msgstr ""
msgid "Service ping is disabled in your configuration file, and cannot be enabled through this form."
@@ -32895,6 +33577,9 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
+msgid "Set the per-user rate limit for getting a user by ID via the API."
+msgstr ""
+
msgid "Set the per-user rate limit for notes created by web or API requests."
msgstr ""
@@ -33074,6 +33759,9 @@ msgstr ""
msgid "Shared runners details"
msgstr ""
+msgid "Shared runners enabled cannot be enabled until a valid credit card is on file"
+msgstr ""
+
msgid "Shared runners help link"
msgstr ""
@@ -33131,6 +33819,9 @@ msgstr ""
msgid "Show all issues."
msgstr ""
+msgid "Show all milestones"
+msgstr ""
+
msgid "Show all test cases."
msgstr ""
@@ -33167,6 +33858,9 @@ msgstr ""
msgid "Show file contents"
msgstr ""
+msgid "Show group milestones"
+msgstr ""
+
msgid "Show labels"
msgstr ""
@@ -33182,6 +33876,12 @@ msgstr ""
msgid "Show open epics"
msgstr ""
+msgid "Show project milestones"
+msgstr ""
+
+msgid "Show sub-group milestones"
+msgstr ""
+
msgid "Show the Closed list"
msgstr ""
@@ -33191,11 +33891,6 @@ msgstr ""
msgid "Show whitespace changes"
msgstr ""
-msgid "Showing %d event"
-msgid_plural "Showing %d events"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Showing %{conflict} between %{sourceBranch} and %{targetBranch}"
msgstr ""
@@ -33255,12 +33950,6 @@ msgstr ""
msgid "Sidebar|None"
msgstr ""
-msgid "Sidebar|Only numeral characters allowed"
-msgstr ""
-
-msgid "Sidebar|Weight"
-msgstr ""
-
msgid "Sidekiq job compression threshold (bytes)"
msgstr ""
@@ -33423,6 +34112,9 @@ msgstr ""
msgid "Slack logo"
msgstr ""
+msgid "SlackIntegration|Are you sure you want to remove this project from the Slack application?"
+msgstr ""
+
msgid "SlackIntegration|GitLab for Slack"
msgstr ""
@@ -33432,6 +34124,9 @@ msgstr ""
msgid "SlackIntegration|Project alias"
msgstr ""
+msgid "SlackIntegration|Remove project"
+msgstr ""
+
msgid "SlackIntegration|Select a GitLab project to link with your Slack workspace."
msgstr ""
@@ -33576,9 +34271,6 @@ msgstr ""
msgid "Something went wrong trying to load issue contacts."
msgstr ""
-msgid "Something went wrong when creating a work item. Please try again"
-msgstr ""
-
msgid "Something went wrong when reordering designs. Please try again"
msgstr ""
@@ -33672,9 +34364,6 @@ msgstr ""
msgid "Something went wrong while inserting your image. Please try again."
msgstr ""
-msgid "Something went wrong while merging this merge request. Please try again."
-msgstr ""
-
msgid "Something went wrong while obtaining the Let's Encrypt certificate."
msgstr ""
@@ -33996,10 +34685,10 @@ 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."
+msgid "SourcegraphAdmin|Learn more."
msgstr ""
-msgid "SourcegraphAdmin|More information"
+msgid "SourcegraphAdmin|Only public projects have code intelligence enabled and communicate with Sourcegraph."
msgstr ""
msgid "SourcegraphAdmin|Save changes"
@@ -34008,7 +34697,7 @@ msgstr ""
msgid "SourcegraphAdmin|Sourcegraph URL"
msgstr ""
-msgid "SourcegraphAdmin|e.g. https://sourcegraph.example.com"
+msgid "SourcegraphAdmin|https://sourcegraph.example.com"
msgstr ""
msgid "SourcegraphPreferences|This feature is experimental and currently limited to certain projects."
@@ -34143,6 +34832,9 @@ msgstr ""
msgid "Start date"
msgstr ""
+msgid "Start free trial"
+msgstr ""
+
msgid "Start merge train"
msgstr ""
@@ -34173,6 +34865,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started escalation for this incident."
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -34185,6 +34880,9 @@ msgstr ""
msgid "Starts at (UTC)"
msgstr ""
+msgid "Starts escalations for this incident"
+msgstr ""
+
msgid "Starts on"
msgstr ""
@@ -34446,6 +35144,9 @@ msgstr ""
msgid "Strikethrough"
msgstr ""
+msgid "Strikethrough text"
+msgstr ""
+
msgid "Subgroup information"
msgstr ""
@@ -34680,6 +35381,21 @@ msgstr ""
msgid "Subscriptions"
msgstr ""
+msgid "Subscriptions|Chat with sales"
+msgstr ""
+
+msgid "Subscriptions|Close"
+msgstr ""
+
+msgid "Subscriptions|Not ready to buy yet?"
+msgstr ""
+
+msgid "Subscriptions|Start a free trial"
+msgstr ""
+
+msgid "Subscriptions|We understand. Maybe you have some questions for our sales team, or maybe you'd like to try some of the paid features first. What would you like to do?"
+msgstr ""
+
msgid "Subscription|Your subscription for %{strong}%{namespace_name}%{strong_close} has expired and you are now on %{pricing_link_start}the GitLab Free tier%{pricing_link_end}. Don't worry, your data is safe. Get in touch with our support team (%{support_email}). They'll gladly help with your subscription renewal."
msgstr ""
@@ -34890,6 +35606,9 @@ msgstr ""
msgid "SuperSonics|Maximum users"
msgstr ""
+msgid "SuperSonics|Offline cloud"
+msgstr ""
+
msgid "SuperSonics|Paste your activation code"
msgstr ""
@@ -34956,6 +35675,12 @@ msgstr ""
msgid "SuperSonics|You do not have an active subscription"
msgstr ""
+msgid "SuperSonics|You have a future dated license"
+msgstr ""
+
+msgid "SuperSonics|You have added a license that activates on %{date}. Please see the subscription history table below for more details."
+msgstr ""
+
msgid "SuperSonics|You have successfully added a license that activates on %{date}. Please see the subscription history table below for more details."
msgstr ""
@@ -35115,6 +35840,9 @@ msgstr ""
msgid "Tag name is required"
msgstr ""
+msgid "Tag push"
+msgstr ""
+
msgid "Tag push events"
msgstr ""
@@ -35217,6 +35945,9 @@ msgstr ""
msgid "TagsPage|protected"
msgstr ""
+msgid "Take a look at the documentation to discover all of GitLab’s capabilities."
+msgstr ""
+
msgid "Target Branch"
msgstr ""
@@ -35619,6 +36350,9 @@ msgstr ""
msgid "Tests"
msgstr ""
+msgid "Text (optional)"
+msgstr ""
+
msgid "Text added to the body of all email messages. %{character_limit} character limit"
msgstr ""
@@ -35669,6 +36403,9 @@ msgstr ""
msgid "The CSV export will be created in the background. Once finished, it will be sent to %{email} in an attachment."
msgstr ""
+msgid "The CSV export you requested of all user memberships is attached to this email."
+msgstr ""
+
msgid "The GitLab subscription service (customers.gitlab.com) is currently experiencing an outage. You can monitor the status and get updates at %{linkStart}status.gitlab.com%{linkEnd}."
msgstr ""
@@ -35744,6 +36481,9 @@ 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 epic"
+msgstr ""
+
msgid "The current issue"
msgstr ""
@@ -35905,6 +36645,9 @@ msgstr ""
msgid "The latest pipeline for this merge request has failed."
msgstr ""
+msgid "The license key is invalid."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -35920,6 +36663,9 @@ msgstr ""
msgid "The license was successfully uploaded and will be active from %{starts_at}. You can see the details below."
msgstr ""
+msgid "The license you uploaded is invalid. If the issue persists, contact support at %{link}."
+msgstr ""
+
msgid "The list creation wizard is already open"
msgstr ""
@@ -36541,10 +37287,13 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} and everything this project contains. %{strongOpen}There is no going back%{strongClose}"
+msgstr ""
+
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains."
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}on %{date}%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains. %{strongOpen}There is no going back.%{strongClose}"
msgstr ""
msgid "This action will %{strongOpen}permanently remove%{strongClose} %{codeOpen}%{group}%{codeClose} %{strongOpen}immediately%{strongClose}."
@@ -36673,9 +37422,6 @@ msgstr ""
msgid "This file was modified for readability, and can't accept suggestions. Edit it directly."
msgstr ""
-msgid "This forked project has the following:"
-msgstr ""
-
msgid "This form is disabled in preview"
msgstr ""
@@ -36688,7 +37434,7 @@ msgstr ""
msgid "This group can't be removed because it is linked to a subscription. To remove this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
-msgid "This group can't be transfered because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
+msgid "This group can't be transferred because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
msgid "This group cannot be invited to a project inside a group with enforced SSO"
@@ -36715,6 +37461,9 @@ 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 incident is already escalated with '%{escalation_policy_name}'."
+msgstr ""
+
msgid "This invitation was sent to %{mail_to_invite_email}, but you are signed in as %{link_to_current_user} with email %{mail_to_current_user}."
msgstr ""
@@ -36733,9 +37482,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 merge train pipeline"
-msgstr ""
-
msgid "This is a private email address %{helpIcon} generated just for you. Anyone who has it can create issues or merge requests as if they were you. If that happens, %{resetLinkStart}reset this token%{resetLinkEnd}."
msgstr ""
@@ -36757,6 +37503,12 @@ msgstr ""
msgid "This is your current session"
msgstr ""
+msgid "This issue cannot be assigned to a confidential epic because it is public."
+msgstr ""
+
+msgid "This issue cannot be made public because it belongs to a confidential epic."
+msgstr ""
+
msgid "This issue is confidential and should only be visible to team members with at least Reporter access."
msgstr ""
@@ -36874,6 +37626,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 branch is protected from force push."
+msgstr ""
+
msgid "This merge request cannot be rebased while there are conflicts."
msgstr ""
@@ -36925,9 +37680,15 @@ msgstr ""
msgid "This pipeline was triggered by a schedule."
msgstr ""
+msgid "This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project"
msgstr ""
+msgid "This project can be restored until %{date}."
+msgstr ""
+
msgid "This project cannot be %{visibilityLevel} because the visibility of %{openShowLink}%{name}%{closeShowLink} is %{visibility}. To make this project %{visibilityLevel}, you must first %{openEditLink}change the visibility%{closeEditLink} of the parent group."
msgstr ""
@@ -36946,6 +37707,9 @@ msgstr ""
msgid "This project is %{strongStart}NOT%{strongEnd} a fork, and has the following:"
msgstr ""
+msgid "This project is %{strongStart}NOT%{strongEnd} a fork. This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -37637,6 +38401,9 @@ msgstr ""
msgid "Today"
msgstr ""
+msgid "Todos count"
+msgstr ""
+
msgid "Todos|Are you looking for things to do? Take a look at %{strongStart}%{openIssuesLinkStart}open issues%{openIssuesLinkEnd}%{strongEnd}, contribute to %{strongStart}%{mergeRequestLinkStart}a merge request%{mergeRequestLinkEnd}%{mergeRequestLinkEnd}%{strongEnd}, or mention someone in a comment to automatically assign them a new to-do item."
msgstr ""
@@ -37910,10 +38677,8 @@ msgstr ""
msgid "Trending"
msgstr ""
-msgid "Trials|%{planName} Trial %{enDash} %{num} day left"
-msgid_plural "Trials|%{planName} Trial %{enDash} %{num} days left"
-msgstr[0] ""
-msgstr[1] ""
+msgid "Trials|%{planName} Trial"
+msgstr ""
msgid "Trials|Compare all plans"
msgstr ""
@@ -37921,6 +38686,9 @@ msgstr ""
msgid "Trials|Create a new group to start your GitLab Ultimate trial."
msgstr ""
+msgid "Trials|Day %{daysUsed}/%{duration}"
+msgstr ""
+
msgid "Trials|Go back to GitLab"
msgstr ""
@@ -38170,7 +38938,7 @@ msgstr ""
msgid "URL is triggered when repository is updated"
msgstr ""
-msgid "URL must be percent-encoded if neccessary."
+msgid "URL must be percent-encoded if necessary."
msgstr ""
msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
@@ -38389,6 +39157,9 @@ msgstr ""
msgid "Unlock account"
msgstr ""
+msgid "Unlock more features with GitLab Ultimate"
+msgstr ""
+
msgid "Unlock the discussion"
msgstr ""
@@ -38452,6 +39223,9 @@ msgstr ""
msgid "Unsubscribes from this %{quick_action_target}."
msgstr ""
+msgid "Unsupported sort value."
+msgstr ""
+
msgid "Unsupported todo type passed. Supported todo types are: %{todo_types}"
msgstr ""
@@ -38680,6 +39454,9 @@ msgstr ""
msgid "UsageQuota|File attachments and smaller design graphics."
msgstr ""
+msgid "UsageQuota|From %{storage_enforcement_date} storage limits will apply to this namespace. View and manage your usage in %{strong_start}Group Settings &gt; Usage quotas%{strong_end}."
+msgstr ""
+
msgid "UsageQuota|Git repository."
msgstr ""
@@ -38740,6 +39517,9 @@ msgstr ""
msgid "UsageQuota|Storage type"
msgstr ""
+msgid "UsageQuota|Storage used"
+msgstr ""
+
msgid "UsageQuota|This is the total amount of storage used across your projects within this namespace."
msgstr ""
@@ -38935,6 +39715,12 @@ msgstr ""
msgid "Use hashed storage paths for newly created and renamed repositories. Always enabled since 13.0."
msgstr ""
+msgid "Use issue count"
+msgstr ""
+
+msgid "Use issue weight"
+msgstr ""
+
msgid "Use one line per URI"
msgstr ""
@@ -39316,6 +40102,9 @@ msgstr ""
msgid "Users"
msgstr ""
+msgid "Users API rate limit"
+msgstr ""
+
msgid "Users can launch a development environment from a GitLab browser tab when the %{linkStart}Gitpod%{linkEnd} integration is enabled."
msgstr ""
@@ -39641,6 +40430,9 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View group pipeline usage quota"
+msgstr ""
+
msgid "View incident details at"
msgstr ""
@@ -39793,6 +40585,9 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
+msgid "Vulnerability"
+msgstr ""
+
msgid "Vulnerability Report"
msgstr ""
@@ -39844,6 +40639,9 @@ msgstr ""
msgid "VulnerabilityManagement|An unverified non-confirmed finding"
msgstr ""
+msgid "VulnerabilityManagement|At least one identifier is required"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -39853,12 +40651,24 @@ msgstr ""
msgid "VulnerabilityManagement|Create Jira issue"
msgstr ""
+msgid "VulnerabilityManagement|Enter a name"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE code"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE identifier URL"
+msgstr ""
+
msgid "VulnerabilityManagement|Fetching linked Jira issues"
msgstr ""
msgid "VulnerabilityManagement|Manually add a vulnerability entry into the vulnerability report."
msgstr ""
+msgid "VulnerabilityManagement|Name is a required field"
+msgstr ""
+
msgid "VulnerabilityManagement|Needs triage"
msgstr ""
@@ -39874,6 +40684,18 @@ msgstr ""
msgid "VulnerabilityManagement|Select a method"
msgstr ""
+msgid "VulnerabilityManagement|Select a severity level"
+msgstr ""
+
+msgid "VulnerabilityManagement|Select a status"
+msgstr ""
+
+msgid "VulnerabilityManagement|Severity is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Something went wrong while creating vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -39898,6 +40720,12 @@ msgstr ""
msgid "VulnerabilityManagement|Something went wrong, could not update vulnerability state."
msgstr ""
+msgid "VulnerabilityManagement|Status is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Submit vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Summary, detailed description, steps to reproduce, etc."
msgstr ""
@@ -40093,6 +40921,9 @@ msgstr ""
msgid "WARNING:"
msgstr ""
+msgid "WARNING: This snippet contains hidden files which might be used to mask malicious behavior. Exercise caution if cloning and executing code from this snippet."
+msgstr ""
+
msgid "Wait for the file to load to copy its contents"
msgstr ""
@@ -40312,6 +41143,15 @@ msgstr ""
msgid "Webhooks|An issue is created, updated, closed, or reopened."
msgstr ""
+msgid "Webhooks|Are you sure you want to delete this group hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this project hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this webhook?"
+msgstr ""
+
msgid "Webhooks|Comments"
msgstr ""
@@ -40321,6 +41161,9 @@ msgstr ""
msgid "Webhooks|Confidential issues events"
msgstr ""
+msgid "Webhooks|Delete webhook"
+msgstr ""
+
msgid "Webhooks|Deployment events"
msgstr ""
@@ -40554,6 +41397,9 @@ msgstr ""
msgid "Wiki"
msgstr ""
+msgid "Wiki page"
+msgstr ""
+
msgid "Wiki page was successfully created."
msgstr ""
@@ -40659,7 +41505,7 @@ msgstr ""
msgid "WikiPageConflictMessage|Someone edited the page the same time you did. Please check out %{wikiLinkStart}the page%{wikiLinkEnd} and make sure your changes will not unintentionally remove theirs."
msgstr ""
-msgid "WikiPage|An error occured while trying to render the content editor. Please try again later."
+msgid "WikiPage|An error occurred while trying to render the content editor. Please try again later."
msgstr ""
msgid "WikiPage|Are you sure you want to switch back to the classic editor?"
@@ -40818,6 +41664,18 @@ msgstr ""
msgid "WorkItem|New Task"
msgstr ""
+msgid "WorkItem|Something went wrong when creating a work item. Please try again"
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching the work item. Please try again."
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching work item types. Please try again"
+msgstr ""
+
+msgid "WorkItem|Type"
+msgstr ""
+
msgid "WorkItem|Work Items"
msgstr ""
@@ -40884,7 +41742,10 @@ msgstr ""
msgid "You are about to add %{usersTag} people to the discussion. They will all receive a notification."
msgstr ""
-msgid "You are about to permanently delete this project"
+msgid "You are about to delete this forked project containing:"
+msgstr ""
+
+msgid "You are about to delete this project containing:"
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."
@@ -40905,6 +41766,9 @@ msgstr ""
msgid "You are attempting to update a file that has changed since you started editing it."
msgstr ""
+msgid "You are billed if you exceed this number. %{qsrOverageLinkStart}How does billing work?%{qsrOverageLinkEnd}"
+msgstr ""
+
msgid "You are connected to the Prometheus server, but there is currently no data to display."
msgstr ""
@@ -40962,6 +41826,9 @@ msgstr ""
msgid "You are not authorized to update this scanner profile"
msgstr ""
+msgid "You are not authorized to upload metric images"
+msgstr ""
+
msgid "You are now impersonating %{username}"
msgstr ""
@@ -41115,9 +41982,6 @@ msgstr ""
msgid "You can only upload one design when dropping onto an existing design."
msgstr ""
-msgid "You can recover this project until %{date}"
-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 ""
@@ -41166,9 +42030,6 @@ msgstr ""
msgid "You cannot write to this read-only GitLab instance."
msgstr ""
-msgid "You can’t %{tag_start}edit%{tag_end} files directly in this project. Fork this project and submit a merge request with your changes."
-msgstr ""
-
msgid "You can’t edit files directly in this project. Fork this project and submit a merge request with your changes."
msgstr ""
@@ -41321,9 +42182,6 @@ 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 set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
@@ -41354,12 +42212,6 @@ msgstr ""
msgid "You must have maintainer access to force delete a lock"
msgstr ""
-msgid "You must have permission to create a project in a group before forking."
-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 ""
@@ -41765,7 +42617,7 @@ msgstr ""
msgid "Your public email will be displayed on your public profile."
msgstr ""
-msgid "Your request for access could not be processed: %{error_meesage}"
+msgid "Your request for access could not be processed: %{error_message}"
msgstr ""
msgid "Your request for access has been queued for review."
@@ -41948,6 +42800,9 @@ msgstr ""
msgid "archived:"
msgstr ""
+msgid "artifacts"
+msgstr ""
+
msgid "assign yourself"
msgstr ""
@@ -41977,6 +42832,9 @@ msgstr[1] ""
msgid "branch name"
msgstr ""
+msgid "builds"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -42400,6 +43258,9 @@ msgstr ""
msgid "contact with same email already exists in group hierarchy"
msgstr ""
+msgid "container registry images"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -42439,6 +43300,9 @@ msgstr ""
msgid "data"
msgstr ""
+msgid "database"
+msgstr ""
+
msgid "date must not be after 9999-12-31"
msgstr ""
@@ -42462,9 +43326,6 @@ msgstr ""
msgid "design"
msgstr ""
-msgid "detached"
-msgstr ""
-
msgid "disabled"
msgstr ""
@@ -42713,7 +43574,7 @@ msgstr ""
msgid "is not a valid X509 certificate."
msgstr ""
-msgid "is not allowed for sign-up."
+msgid "is not allowed for sign-up. Please use your regular email address."
msgstr ""
msgid "is not allowed for this group."
@@ -42725,7 +43586,7 @@ msgstr ""
msgid "is not allowed since the group is not top-level group."
msgstr ""
-msgid "is not allowed."
+msgid "is not allowed. Please use your regular email address."
msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
@@ -42812,6 +43673,9 @@ msgstr ""
msgid "level: %{level}"
msgstr ""
+msgid "lfs objects"
+msgstr ""
+
msgid "limit of %{project_limit} reached"
msgstr ""
@@ -43031,6 +43895,9 @@ msgstr ""
msgid "mrWidget|Merge blocked: pipeline must succeed. It's waiting for a manual action to continue."
msgstr ""
+msgid "mrWidget|Merge blocked: pipeline must succeed. Push a commit that fixes the failure, or %{linkStart}learn about other solutions.%{linkEnd}"
+msgstr ""
+
msgid "mrWidget|Merge blocked: this merge request must be approved."
msgstr ""
@@ -43148,9 +44015,6 @@ msgstr ""
msgid "mrWidget|The changes were not merged into"
msgstr ""
-msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -43298,9 +44162,6 @@ msgstr ""
msgid "open issue"
msgstr ""
-msgid "opened %{timeAgo}"
-msgstr ""
-
msgid "or"
msgstr ""
@@ -43312,6 +44173,12 @@ msgid_plural "out of %d total tests"
msgstr[0] ""
msgstr[1] ""
+msgid "packages"
+msgstr ""
+
+msgid "pages"
+msgstr ""
+
msgid "parent"
msgid_plural "parents"
msgstr[0] ""
@@ -43461,6 +44328,9 @@ msgid_plural "replies"
msgstr[0] ""
msgstr[1] ""
+msgid "repositories"
+msgstr ""
+
msgid "repository:"
msgstr ""
@@ -43581,12 +44451,18 @@ msgstr ""
msgid "tag name"
msgstr ""
+msgid "terraform states"
+msgstr ""
+
msgid "the correct format."
msgstr ""
msgid "the file"
msgstr ""
+msgid "the following epic(s)"
+msgstr ""
+
msgid "the following issue(s)"
msgstr ""
@@ -43599,21 +44475,12 @@ msgstr ""
msgid "this document"
msgstr ""
-msgid "this issue cannot be assigned to a confidential epic since it is public"
-msgstr ""
-
-msgid "this issue cannot be made public since it belongs to a confidential epic"
-msgstr ""
-
msgid "time summary"
msgstr ""
msgid "toggle collapse"
msgstr ""
-msgid "train"
-msgstr ""
-
msgid "triggered"
msgstr ""
@@ -43742,3 +44609,6 @@ msgstr ""
msgid "{project}"
msgstr ""
+msgid "✔"
+msgstr ""
+
diff --git a/locale/he_IL/gitlab.po b/locale/he_IL/gitlab.po
index 26cb7e7c4a6..747981d06e7 100644
--- a/locale/he_IL/gitlab.po
+++ b/locale/he_IL/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: he\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2022-02-02 15:45\n"
+"PO-Revision-Date: 2022-03-01 20:39\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -174,6 +174,13 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "%d assigned issue"
+msgid_plural "%d assigned issues"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -559,8 +566,29 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
-msgid "%d vulnerability updated"
-msgid_plural "%d vulnerabilities updated"
+msgid "%d vulnerability set to confirmed"
+msgid_plural "%d vulnerabilities set to confirmed"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
+msgid "%d vulnerability set to dismissed"
+msgid_plural "%d vulnerabilities set to dismissed"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
+msgid "%d vulnerability set to needs triage"
+msgid_plural "%d vulnerabilities set to needs triage"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
+msgid "%d vulnerability set to resolved"
+msgid_plural "%d vulnerabilities set to resolved"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
@@ -662,6 +690,12 @@ msgstr[3] ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{completed} of %{total} issues closed"
+msgstr ""
+
+msgid "%{completed} of %{total} weight completed"
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -1022,6 +1056,9 @@ msgstr ""
msgid "%{openedIssues} open, %{closedIssues} closed"
msgstr ""
+msgid "%{percentage}%% issues closed"
+msgstr ""
+
msgid "%{percentage}%% weight completed"
msgstr ""
@@ -1481,6 +1518,9 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "- of - issues closed"
+msgstr ""
+
msgid "- of - weight completed"
msgstr ""
@@ -1669,7 +1709,7 @@ msgstr "10â€-19 תרומות"
msgid "1000+"
msgstr ""
-msgid "192.168.0.0/24"
+msgid "192.168.0.0/24 or 2001:0DB8:1234::/48"
msgstr ""
msgid "1st contribution!"
@@ -1981,13 +2021,13 @@ msgstr ""
msgid "AWS Access Key"
msgstr ""
-msgid "AWS Access Key. Only required if not using role instance credentials"
+msgid "AWS Secret Access Key"
msgstr ""
-msgid "AWS Secret Access Key"
+msgid "AWS access key ID (Optional)"
msgstr ""
-msgid "AWS Secret Access Key. Only required if not using role instance credentials"
+msgid "AWS secret access key (Optional)"
msgstr ""
msgid "AWS service error: %{error}"
@@ -2047,9 +2087,6 @@ msgstr "הגישה נדחתה. × × ×œ×‘×“×•×§ ×ת רמת הגישה שלך."
msgid "Access granted"
msgstr "הוענקה גישה"
-msgid "Access key ID"
-msgstr ""
-
msgid "Access requests"
msgstr "בקשות גישה"
@@ -2224,8 +2261,8 @@ msgstr ""
msgid "Activity"
msgstr "פעילות"
-msgid "Activity|An error occured while retrieving activity. Reload the page to try again."
-msgstr "×ירעה שגי××” בקבלת הפעילות. × × ×œ×¨×¢× ×Ÿ ×ת העמוד ולנסות שוב."
+msgid "Activity|An error occurred while retrieving activity. Reload the page to try again."
+msgstr ""
msgid "Add"
msgstr "הוספה"
@@ -2263,6 +2300,9 @@ msgstr "הוספת פגישת Zoom"
msgid "Add a %{type}"
msgstr ""
+msgid "Add a GCP region"
+msgstr ""
+
msgid "Add a GPG key"
msgstr "הוספת מפתח GPG"
@@ -2314,6 +2354,9 @@ msgstr ""
msgid "Add a numbered list"
msgstr "הוספת רשימה ממוספרת"
+msgid "Add a related epic"
+msgstr ""
+
msgid "Add a related issue"
msgstr ""
@@ -2428,6 +2471,9 @@ msgstr ""
msgid "Add or subtract spent time"
msgstr ""
+msgid "Add people"
+msgstr ""
+
msgid "Add previously merged commits"
msgstr ""
@@ -2494,6 +2540,9 @@ msgstr ""
msgid "Add webhook"
msgstr "הוספת התליית רשת"
+msgid "Add your team members and others to GitLab."
+msgstr ""
+
msgid "Add/remove"
msgstr "הוספה/הסרה"
@@ -3316,12 +3365,6 @@ msgstr ""
msgid "AdvancedSearch|Reindex required"
msgstr ""
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. Permanently deleting this project will %{strongStart}immediately delete%{strongEnd} its repositories and %{strongStart}all related resources%{strongEnd}, including issues, merge requests etc."
-msgstr ""
-
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. You will lose this project's repository and %{strongStart}all related resources%{strongEnd}, including issues and merge requests."
-msgstr ""
-
msgid "After a successful password update you will be redirected to login screen."
msgstr ""
@@ -3352,6 +3395,9 @@ msgstr ""
msgid "Akismet helps prevent the creation of spam issues in public projects."
msgstr ""
+msgid "Alert"
+msgstr ""
+
msgid "AlertManagement|Acknowledged"
msgstr ""
@@ -3724,9 +3770,6 @@ msgstr ""
msgid "All environments"
msgstr "כל הסביבות"
-msgid "All epics"
-msgstr ""
-
msgid "All groups and projects"
msgstr "כל הקבוצות והמיזמי×"
@@ -4467,14 +4510,17 @@ msgstr ""
msgid "ApplicationSettings|Approve users in the pending approval status?"
msgstr ""
-msgid "ApplicationSettings|By making this change, you will automatically approve %d user with the pending approval status."
-msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users with the pending approval status."
+msgid "ApplicationSettings|Approve users who are pending approval?"
+msgstr ""
+
+msgid "ApplicationSettings|By making this change, you will automatically approve %d user who is pending approval."
+msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users who are pending approval."
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
-msgid "ApplicationSettings|By making this change, you will automatically approve all users in pending approval status."
+msgid "ApplicationSettings|By making this change, you will automatically approve all users who are pending approval."
msgstr ""
msgid "ApplicationSettings|Denied domains for sign-ups"
@@ -4890,10 +4936,10 @@ msgstr ""
msgid "Archiving the project will make it entirely read-only. It is hidden from the dashboard and doesn't show up in searches. %{strong_start}The repository cannot be committed to, and no issues, comments, or other entities can be created.%{strong_end} %{link_start}Learn more.%{link_end}"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to delete this project?"
+msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
+msgid "Are you absolutely sure?"
msgstr ""
msgid "Are you sure that you want to archive this project?"
@@ -4929,12 +4975,18 @@ msgstr ""
msgid "Are you sure you want to delete this SSH key?"
msgstr ""
+msgid "Are you sure you want to delete this comment?"
+msgstr ""
+
msgid "Are you sure you want to delete this deploy key?"
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 label?"
+msgstr ""
+
msgid "Are you sure you want to delete this pipeline schedule?"
msgstr ""
@@ -4950,9 +5002,6 @@ msgstr ""
msgid "Are you sure you want to discard your changes?"
msgstr ""
-msgid "Are you sure you want to erase this build?"
-msgstr ""
-
msgid "Are you sure you want to import %d repository?"
msgid_plural "Are you sure you want to import %d repositories?"
msgstr[0] ""
@@ -5002,6 +5051,9 @@ msgstr ""
msgid "Are you sure you want to remove this list?"
msgstr ""
+msgid "Are you sure you want to remove this nickname?"
+msgstr ""
+
msgid "Are you sure you want to reset the health check token?"
msgstr ""
@@ -5014,10 +5066,10 @@ 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?"
+msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
msgstr ""
-msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
+msgid "Are you sure you want to revoke this project access token? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to stop this environment?"
@@ -5164,9 +5216,6 @@ msgstr ""
msgid "Assigned to %{assignee_name}"
msgstr ""
-msgid "Assigned to %{name}"
-msgstr ""
-
msgid "Assigned to me"
msgstr ""
@@ -5235,6 +5284,9 @@ msgstr[3] ""
msgid "Attaching the file failed."
msgstr ""
+msgid "Attention"
+msgstr ""
+
msgid "Audit Events"
msgstr ""
@@ -5397,6 +5449,12 @@ msgstr ""
msgid "Authorized applications (%{size})"
msgstr ""
+msgid "AuthorizedApplication|Are you sure you want to revoke this application?"
+msgstr ""
+
+msgid "AuthorizedApplication|Revoke application"
+msgstr ""
+
msgid "Authors: %{authors}"
msgstr ""
@@ -6598,6 +6656,9 @@ msgstr ""
msgid "CICDAnalytics|Shared Runners Usage"
msgstr ""
+msgid "CICDAnalytics|Shared runner pipeline minute duration by month"
+msgstr ""
+
msgid "CICDAnalytics|Shared runner usage"
msgstr ""
@@ -6739,6 +6800,9 @@ msgstr ""
msgid "Can create groups:"
msgstr ""
+msgid "Can not delete primary training"
+msgstr ""
+
msgid "Can't apply as the source branch was deleted."
msgstr ""
@@ -7072,9 +7136,6 @@ msgstr ""
msgid "Changing any setting here requires an application restart"
msgstr ""
-msgid "Changing group URL can have unintended side effects."
-msgstr ""
-
msgid "Charts can't be displayed as the request for data has timed out. %{documentationLink}"
msgstr ""
@@ -7162,9 +7223,6 @@ msgstr ""
msgid "Checking branch availability..."
msgstr ""
-msgid "Checking group URL availability..."
-msgstr ""
-
msgid "Checking group path availability..."
msgstr ""
@@ -7662,6 +7720,9 @@ msgstr ""
msgid "Clear recent searches"
msgstr ""
+msgid "Clear repository checks"
+msgstr ""
+
msgid "Clear search"
msgstr ""
@@ -7794,9 +7855,6 @@ msgstr ""
msgid "Closed MRs"
msgstr ""
-msgid "Closed epics"
-msgstr ""
-
msgid "Closed issues"
msgstr ""
@@ -7833,13 +7891,13 @@ msgstr ""
msgid "Cluster level"
msgstr ""
-msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
+msgid "Cluster type must be specified for Stages::ClusterEndpointInserter"
msgstr ""
msgid "ClusterAgents|%{name} successfully deleted"
msgstr ""
-msgid "ClusterAgents|%{number} of %{total} Agents"
+msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
@@ -7881,6 +7939,15 @@ msgstr ""
msgid "ClusterAgents|Agent never connected to GitLab"
msgstr ""
+msgid "ClusterAgents|Agent version mismatch"
+msgstr ""
+
+msgid "ClusterAgents|Agent version mismatch and update"
+msgstr ""
+
+msgid "ClusterAgents|Agent version update required"
+msgstr ""
+
msgid "ClusterAgents|All"
msgstr ""
@@ -7905,7 +7972,7 @@ msgstr ""
msgid "ClusterAgents|Configuration"
msgstr ""
-msgid "ClusterAgents|Connect a cluster through the Agent"
+msgid "ClusterAgents|Connect a cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connect existing cluster"
@@ -7914,13 +7981,13 @@ msgstr ""
msgid "ClusterAgents|Connect with a certificate"
msgstr ""
-msgid "ClusterAgents|Connect with agent"
+msgid "ClusterAgents|Connect with an agent"
msgstr ""
msgid "ClusterAgents|Connect with the GitLab Agent"
msgstr ""
-msgid "ClusterAgents|Connect your cluster through the Agent"
+msgid "ClusterAgents|Connect your cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connected"
@@ -7980,7 +8047,10 @@ msgstr ""
msgid "ClusterAgents|How to register an agent?"
msgstr ""
-msgid "ClusterAgents|Install new Agent"
+msgid "ClusterAgents|How to update an agent?"
+msgstr ""
+
+msgid "ClusterAgents|Install a new agent"
msgstr ""
msgid "ClusterAgents|Last connected %{timeAgo}."
@@ -8007,7 +8077,7 @@ msgstr ""
msgid "ClusterAgents|Never connected"
msgstr ""
-msgid "ClusterAgents|No Agents"
+msgid "ClusterAgents|No agents"
msgstr ""
msgid "ClusterAgents|No clusters connected through cluster certificates"
@@ -8067,6 +8137,9 @@ msgstr ""
msgid "ClusterAgents|The agent has not been connected in a long time. There might be a connectivity issue. Last contact was %{timeAgo}."
msgstr ""
+msgid "ClusterAgents|The agent version do not match each other across your cluster's pods. This can happen when a new agent version was just deployed and Kubernetes is shutting down the old pods."
+msgstr ""
+
msgid "ClusterAgents|The recommended installation method includes the token. If you want to follow the advanced installation method provided in the docs, make sure you save the token value before you close this window."
msgstr ""
@@ -8116,6 +8189,9 @@ msgstr ""
msgid "ClusterAgents|You will need to create a token to connect to your agent"
msgstr ""
+msgid "ClusterAgents|Your agent version is out of sync with your GitLab version (v%{version}), which might cause compatibility problems. Update the agent installed on your cluster to the most recent version."
+msgstr ""
+
msgid "ClusterAgents|Your instance doesn't have the %{linkStart}GitLab Agent Server (KAS)%{linkEnd} set up. Ask a GitLab Administrator to install it."
msgstr ""
@@ -8992,9 +9068,6 @@ msgstr ""
msgid "Comma-separated list of email addresses."
msgstr ""
-msgid "Comma-separated list of users allowed to exceed the rate limit."
-msgstr ""
-
msgid "Comma-separated, e.g. '1.1.1.1, 2.2.2.0/24'"
msgstr ""
@@ -9323,6 +9396,12 @@ msgstr ""
msgid "Confidential"
msgstr ""
+msgid "Confidential issue"
+msgstr ""
+
+msgid "Confidential note"
+msgstr ""
+
msgid "Confidentiality"
msgstr ""
@@ -9356,6 +9435,9 @@ msgstr ""
msgid "Configure Dependency Scanning in `.gitlab-ci.yml`, creating this file if it does not already exist"
msgstr ""
+msgid "Configure GitLab"
+msgstr ""
+
msgid "Configure GitLab runners to start using the Web Terminal. %{helpStart}Learn more.%{helpEnd}"
msgstr ""
@@ -9404,6 +9486,15 @@ msgstr ""
msgid "Configure pipelines to deploy web apps, backend services, APIs and static resources to Google Cloud"
msgstr ""
+msgid "Configure region"
+msgstr ""
+
+msgid "Configure region for environment"
+msgstr ""
+
+msgid "Configure regions"
+msgstr ""
+
msgid "Configure repository mirroring."
msgstr ""
@@ -9437,6 +9528,9 @@ msgstr ""
msgid "Configure which lists are shown for anyone who visits this board"
msgstr ""
+msgid "Configure your environments to be deployed to specific geographical regions"
+msgstr ""
+
msgid "Confirm"
msgstr ""
@@ -10145,10 +10239,10 @@ msgstr ""
msgid "CorpusManagement|Actions"
msgstr ""
-msgid "CorpusManagement|Corpus are used in fuzz testing as mutation source to Improve future testing."
+msgid "CorpusManagement|Corpus file"
msgstr ""
-msgid "CorpusManagement|Corpus file"
+msgid "CorpusManagement|Corpus files are used in coverage-guided fuzz testing as seed inputs to improve testing."
msgstr ""
msgid "CorpusManagement|Corpus files must be in *.zip format. Maximum 5 GB"
@@ -10202,6 +10296,9 @@ msgstr ""
msgid "Could not apply %{name} command."
msgstr ""
+msgid "Could not apply %{name} command. %{message}."
+msgstr ""
+
msgid "Could not authorize chat nickname. Try again!"
msgstr ""
@@ -10352,6 +10449,9 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
+msgid "Create a group"
+msgstr ""
+
msgid "Create a merge request"
msgstr ""
@@ -10376,6 +10476,9 @@ msgstr ""
msgid "Create a personal access token on your account to pull or push via %{protocol}."
msgstr ""
+msgid "Create a project"
+msgstr ""
+
msgid "Create an account using:"
msgstr ""
@@ -10739,6 +10842,9 @@ msgstr ""
msgid "Creation date"
msgstr ""
+msgid "Creator"
+msgstr ""
+
msgid "Credentials"
msgstr ""
@@ -10751,9 +10857,15 @@ msgstr ""
msgid "CredentialsInventory|Personal Access Tokens"
msgstr ""
+msgid "CredentialsInventory|Project Access Tokens"
+msgstr ""
+
msgid "CredentialsInventory|SSH Keys"
msgstr ""
+msgid "Credit card required to be on file in order to create a pipeline"
+msgstr ""
+
msgid "Credit card:"
msgstr ""
@@ -10937,9 +11049,6 @@ msgstr ""
msgid "Customer relations"
msgstr ""
-msgid "Customizable by an administrator."
-msgstr ""
-
msgid "Customizable by owners."
msgstr ""
@@ -11069,30 +11178,18 @@ msgstr ""
msgid "CycleAnalytics|%{selectedLabelsCount} selected (%{maxLabels} max)"
msgstr ""
-msgid "CycleAnalytics|%{stageCount} stages selected"
-msgstr ""
-
-msgid "CycleAnalytics|All stages"
-msgstr ""
-
-msgid "CycleAnalytics|Average days to completion"
+msgid "CycleAnalytics|Average time to completion"
msgstr ""
msgid "CycleAnalytics|Date"
msgstr ""
-msgid "CycleAnalytics|Days to completion"
-msgstr ""
-
msgid "CycleAnalytics|Display chart filters"
msgstr ""
msgid "CycleAnalytics|Lead Time for Changes"
msgstr ""
-msgid "CycleAnalytics|No stages selected"
-msgstr ""
-
msgid "CycleAnalytics|Number of tasks"
msgstr ""
@@ -11125,18 +11222,30 @@ msgstr ""
msgid "CycleAnalytics|Showing data for group '%{groupName}' from %{createdAfter} to %{createdBefore}"
msgstr ""
-msgid "CycleAnalytics|Stages"
+msgid "CycleAnalytics|Stage time: %{title}"
msgstr ""
msgid "CycleAnalytics|Tasks by type"
msgstr ""
-msgid "CycleAnalytics|The average time spent in the selected stage for the items that were completed on each date. Data limited to the last 500 items."
+msgid "CycleAnalytics|The average time items spent in this stage. Data limited to items completed within this date range."
msgstr ""
msgid "CycleAnalytics|The given date range is larger than 180 days"
msgstr ""
+msgid "CycleAnalytics|The total time items spent across each value stream stage. Data limited to items completed within this date range."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Stage time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Total time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|Total time"
+msgstr ""
+
msgid "CycleAnalytics|Type of work"
msgstr ""
@@ -11149,9 +11258,6 @@ msgstr ""
msgid "CycleAnalytics|project dropdown filter"
msgstr ""
-msgid "CycleAnalytics|stage dropdown"
-msgstr ""
-
msgid "DAG visualization requires at least 3 dependent jobs."
msgstr ""
@@ -11251,10 +11357,16 @@ msgstr ""
msgid "DastProfiles|AJAX spider"
msgstr ""
+msgid "DastProfiles|API"
+msgstr ""
+
+msgid "DastProfiles|API endpoint URL"
+msgstr ""
+
msgid "DastProfiles|Active"
msgstr ""
-msgid "DastProfiles|Additional request headers (Optional)"
+msgid "DastProfiles|Additional request headers (optional)"
msgstr ""
msgid "DastProfiles|Are you sure you want to delete this profile?"
@@ -11269,6 +11381,9 @@ msgstr ""
msgid "DastProfiles|Branch missing"
msgstr ""
+msgid "DastProfiles|Choose a scan method"
+msgstr ""
+
msgid "DastProfiles|Could not create the scanner profile. Please try again."
msgstr ""
@@ -11338,7 +11453,13 @@ msgstr ""
msgid "DastProfiles|Excluded URLs"
msgstr ""
-msgid "DastProfiles|Excluded URLs (Optional)"
+msgid "DastProfiles|Excluded URLs (optional)"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths (optional)"
msgstr ""
msgid "DastProfiles|Hide debug messages"
@@ -11395,9 +11516,6 @@ msgstr ""
msgid "DastProfiles|Request headers"
msgstr ""
-msgid "DastProfiles|Rest API"
-msgstr ""
-
msgid "DastProfiles|Run the AJAX spider, in addition to the traditional spider, to crawl the target site."
msgstr ""
@@ -11407,6 +11525,9 @@ msgstr ""
msgid "DastProfiles|Save profile"
msgstr ""
+msgid "DastProfiles|Scan method"
+msgstr ""
+
msgid "DastProfiles|Scan mode"
msgstr ""
@@ -11485,12 +11606,24 @@ msgstr ""
msgid "DastProfiles|Website"
msgstr ""
+msgid "DastProfiles|What does each method do?"
+msgstr ""
+
msgid "DastProfiles|You can either choose a passive scan or validate the target site from the site profile management page. %{docsLinkStart}Learn more about site validation.%{docsLinkEnd}"
msgstr ""
msgid "DastProfiles|You cannot run an active scan against an unvalidated site."
msgstr ""
+msgid "DastProfiles|folder/dast_example.har or https://example.com/dast_example.har"
+msgstr ""
+
+msgid "DastProfiles|folder/example.postman_collection.json or https://example.com/"
+msgstr ""
+
+msgid "DastProfiles|folder/openapi.json or https://example.com/openapi.json"
+msgstr ""
+
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
@@ -11600,6 +11733,9 @@ msgstr ""
msgid "DatadogIntegration|API URL"
msgstr ""
+msgid "DatadogIntegration|Custom tags in Datadog. Enter one tag per line in the %{codeOpen}key:value%{codeClose} format. %{linkOpen}How do I use tags?%{linkClose}"
+msgstr ""
+
msgid "DatadogIntegration|Environment"
msgstr ""
@@ -11618,12 +11754,18 @@ msgstr ""
msgid "DatadogIntegration|Tag all data from this GitLab instance in Datadog. Useful when managing several self-managed deployments."
msgstr ""
+msgid "DatadogIntegration|Tags"
+msgstr ""
+
msgid "DatadogIntegration|The Datadog site to send data to. To send data to the EU site, use %{codeOpen}datadoghq.eu%{codeClose}."
msgstr ""
msgid "DatadogIntegration|Trace your GitLab pipelines with Datadog."
msgstr ""
+msgid "DatadogIntegration|have an invalid format"
+msgstr ""
+
msgid "Datasource name not found"
msgstr ""
@@ -11633,9 +11775,6 @@ msgstr ""
msgid "Date merged"
msgstr ""
-msgid "Date picker"
-msgstr ""
-
msgid "Date range"
msgstr ""
@@ -11789,9 +11928,6 @@ msgstr ""
msgid "Definition"
msgstr ""
-msgid "Delayed Project Deletion (%{adjourned_deletion})"
-msgstr ""
-
msgid "DelayedJobs|Are you sure you want to run %{jobName} immediately? Otherwise this job will run automatically after its timer finishes."
msgstr ""
@@ -11870,10 +12006,10 @@ msgstr ""
msgid "Delete pipeline"
msgstr ""
-msgid "Delete project"
+msgid "Delete pipeline schedule"
msgstr ""
-msgid "Delete project. Are you ABSOLUTELY SURE?"
+msgid "Delete project"
msgstr ""
msgid "Delete row"
@@ -11903,6 +12039,9 @@ msgstr ""
msgid "Delete this epic and all descendants?"
msgstr ""
+msgid "Delete this project"
+msgstr ""
+
msgid "Delete user list"
msgstr ""
@@ -12173,6 +12312,12 @@ msgstr ""
msgid "Deploy to..."
msgstr ""
+msgid "DeployBoards|To see deployment progress for your environments, make sure you are deploying to %{codeStart}$KUBE_NAMESPACE%{codeEnd} and annotating with %{codeStart}app.gitlab.com/app=$CI_PROJECT_PATH_SLUG%{codeEnd} and %{codeStart}app.gitlab.com/env=$CI_ENVIRONMENT_SLUG%{codeEnd}."
+msgstr ""
+
+msgid "DeployBoard|Kubernetes Pods"
+msgstr ""
+
msgid "DeployFreeze|Add a freeze period to prevent unintended releases during a period of time for a given environment. You must update the deployment jobs in %{filename} according to the deploy freezes added here. %{freeze_period_link_start}Learn more.%{freeze_period_link_end}"
msgstr ""
@@ -12257,9 +12402,6 @@ msgstr ""
msgid "DeployTokens|Active Deploy Tokens (%{active_tokens})"
msgstr ""
-msgid "DeployTokens|Allows read and write access to registry images."
-msgstr ""
-
msgid "DeployTokens|Allows read and write access to the package registry."
msgstr ""
@@ -12272,6 +12414,9 @@ msgstr ""
msgid "DeployTokens|Allows read-only access to the repository."
msgstr ""
+msgid "DeployTokens|Allows write access to registry images."
+msgstr ""
+
msgid "DeployTokens|Copy deploy token"
msgstr ""
@@ -12365,12 +12510,57 @@ msgstr ""
msgid "Deploying to AWS is easy with GitLab"
msgstr ""
+msgid "Deployment"
+msgstr ""
+
msgid "Deployment Frequency"
msgstr ""
+msgid "Deployment Target|Project deployment target (optional)"
+msgstr ""
+
+msgid "Deployment Target|Select the deployment target"
+msgstr ""
+
msgid "Deployment frequency"
msgstr ""
+msgid "DeploymentTarget|GitLab Pages"
+msgstr ""
+
+msgid "DeploymentTarget|Heroku"
+msgstr ""
+
+msgid "DeploymentTarget|Infrastructure provider (Terraform, Cloudformation, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Kubernetes (GKE, EKS, OpenShift, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Managed container runtime (Fargate, Cloud Run, DigitalOcean App)"
+msgstr ""
+
+msgid "DeploymentTarget|Mobile app store"
+msgstr ""
+
+msgid "DeploymentTarget|No deployment planned"
+msgstr ""
+
+msgid "DeploymentTarget|Other hosting service"
+msgstr ""
+
+msgid "DeploymentTarget|Registry (package or container)"
+msgstr ""
+
+msgid "DeploymentTarget|Self-managed container runtime (Podman, Docker Swarm, Docker Compose)"
+msgstr ""
+
+msgid "DeploymentTarget|Serverless backend (Lambda, Cloud functions)"
+msgstr ""
+
+msgid "DeploymentTarget|Virtual machine (for example, EC2)"
+msgstr ""
+
msgid "Deployments"
msgstr ""
@@ -12411,6 +12601,9 @@ msgstr ""
msgid "Deployment|This deployment was created using the API"
msgstr ""
+msgid "Deployment|Triggerer"
+msgstr ""
+
msgid "Deployment|Waiting"
msgstr ""
@@ -12438,6 +12631,18 @@ msgstr ""
msgid "Deprecated API rate limits"
msgstr ""
+msgid "Deprecations|Feature deprecation and removal"
+msgstr ""
+
+msgid "Deprecations|For information on a possible replacement %{epicStart} learn more about Opstrace %{epicEnd}."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7 and are %{epicStart} scheduled for removal %{epicEnd} in GitLab 15.0."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7, and are %{removal_link_start} scheduled for removal %{link_end} in GitLab 15.0. For information on a possible replacement, %{opstrace_link_start} learn more about Opstrace %{link_end}."
+msgstr ""
+
msgid "Deprioritize label"
msgstr ""
@@ -12685,10 +12890,10 @@ msgstr ""
msgid "DevopsAdoption|At least one deploy"
msgstr ""
-msgid "DevopsAdoption|At least one issue opened"
+msgid "DevopsAdoption|At least one issue created"
msgstr ""
-msgid "DevopsAdoption|At least one merge request opened"
+msgid "DevopsAdoption|At least one merge request created"
msgstr ""
msgid "DevopsAdoption|At least one pipeline successfully run"
@@ -12895,6 +13100,9 @@ msgstr ""
msgid "Direct member"
msgstr ""
+msgid "Direct members"
+msgstr ""
+
msgid "Direct non-authenticated users to this page."
msgstr ""
@@ -13013,6 +13221,9 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "Dismiss Alert"
+msgstr ""
+
msgid "Dismiss merge request promotion"
msgstr ""
@@ -13040,9 +13251,15 @@ msgstr ""
msgid "Display alerts from all configured monitoring tools."
msgstr ""
+msgid "Display milestones"
+msgstr ""
+
msgid "Display name"
msgstr ""
+msgid "Display progress of child issues"
+msgstr ""
+
msgid "Display rendered file"
msgstr ""
@@ -13148,6 +13365,9 @@ msgstr ""
msgid "Download image"
msgstr ""
+msgid "Download payload"
+msgstr ""
+
msgid "Download raw data (.csv)"
msgstr ""
@@ -13325,6 +13545,9 @@ msgstr ""
msgid "Edit in Web IDE"
msgstr ""
+msgid "Edit in pipeline editor"
+msgstr ""
+
msgid "Edit in single-file editor"
msgstr ""
@@ -13367,6 +13590,9 @@ msgstr ""
msgid "Edit your most recent comment in a thread (from an empty textarea)"
msgstr ""
+msgid "Edit, lint, and visualize your pipeline."
+msgstr ""
+
msgid "Edited"
msgstr ""
@@ -13808,6 +14034,9 @@ msgstr ""
msgid "Enforce two-factor authentication for all user sign-ins."
msgstr ""
+msgid "Enhance security by storing service account keys in secret managers - learn more about %{docLinkStart}secret management with GitLab%{docLinkEnd}"
+msgstr ""
+
msgid "Ensure connectivity is available from the GitLab server to the Prometheus server"
msgstr ""
@@ -13868,6 +14097,9 @@ 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 following to confirm:"
+msgstr ""
+
msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
@@ -14400,9 +14632,6 @@ 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 ""
@@ -14538,6 +14767,9 @@ msgstr ""
msgid "Errors:"
msgstr ""
+msgid "Escalate this incident"
+msgstr ""
+
msgid "Escalation Policies"
msgstr ""
@@ -14550,6 +14782,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy"
+msgstr ""
+
msgid "Escalation policy:"
msgstr ""
@@ -14803,6 +15038,9 @@ msgstr ""
msgid "Existing sign in methods may be removed"
msgstr ""
+msgid "Exit."
+msgstr ""
+
msgid "Expand"
msgstr ""
@@ -14899,6 +15137,9 @@ msgstr ""
msgid "Explore public groups"
msgstr ""
+msgid "Explore public projects"
+msgstr ""
+
msgid "Explore snippets"
msgstr ""
@@ -15062,7 +15303,7 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
-msgid "Failed to assign a reviewer because no user was found."
+msgid "Failed to assign a reviewer because no user was specified."
msgstr ""
msgid "Failed to assign a user because no user was found."
@@ -15128,10 +15369,10 @@ msgstr ""
msgid "Failed to find import label for Jira import."
msgstr ""
-msgid "Failed to generate export, please try again later."
+msgid "Failed to find users for %{missing}"
msgstr ""
-msgid "Failed to generate report, please try again after sometime"
+msgid "Failed to generate export, please try again later."
msgstr ""
msgid "Failed to get ref."
@@ -15230,6 +15471,9 @@ msgstr ""
msgid "Failed to remove a to-do item for the design."
msgstr ""
+msgid "Failed to remove attention because no user was found."
+msgstr ""
+
msgid "Failed to remove mirror."
msgstr ""
@@ -15242,6 +15486,9 @@ msgstr ""
msgid "Failed to remove user key."
msgstr ""
+msgid "Failed to request attention because no user was found."
+msgstr ""
+
msgid "Failed to reset key. Please try again."
msgstr ""
@@ -15323,6 +15570,9 @@ msgstr ""
msgid "Feature Flags"
msgstr ""
+msgid "Feature deprecation and removal"
+msgstr ""
+
msgid "Feature flag status"
msgstr ""
@@ -15822,7 +16072,7 @@ msgstr ""
msgid "For each job, re-use the project workspace. If the workspace doesn't exist, use %{code_open}git clone%{code_close}."
msgstr ""
-msgid "For example, the application using the token or the purpose of the token."
+msgid "For example, the application using the token or the purpose of the token. Do not give sensitive information for the name of the token, as it will be visible to all %{resource_type} members."
msgstr ""
msgid "For files larger than this limit, only index the file name. The file content is neither indexed nor searchable."
@@ -15906,9 +16156,6 @@ msgstr ""
msgid "ForkProject|Select a namespace"
msgstr ""
-msgid "ForkProject|Select a namespace to fork the project"
-msgstr ""
-
msgid "ForkProject|The project can be accessed by any logged in user."
msgstr ""
@@ -16005,6 +16252,9 @@ msgstr ""
msgid "Full name"
msgstr ""
+msgid "GCP region configured"
+msgstr ""
+
msgid "GPG Key ID:"
msgstr ""
@@ -16185,6 +16435,9 @@ msgstr ""
msgid "Geo|Failed"
msgstr ""
+msgid "Geo|Filter Geo sites"
+msgstr ""
+
msgid "Geo|Filter by name"
msgstr ""
@@ -16596,6 +16849,12 @@ msgstr ""
msgid "GitLab Issue"
msgstr ""
+msgid "GitLab KAS"
+msgstr ""
+
+msgid "GitLab Memberships CSV Export"
+msgstr ""
+
msgid "GitLab Pages"
msgstr ""
@@ -16644,6 +16903,9 @@ 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 free to use. Many features for larger teams are part of our %{link_start}paid products%{link_end}. You can try Ultimate for free without any obligation or payment details."
+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 ""
@@ -16770,7 +17032,7 @@ msgstr ""
msgid "GitLabPages|When enabled, all attempts to visit your website through HTTP are automatically redirected to HTTPS using a response with status code 301. Requires a valid certificate for all domains. %{docs_link_start}Learn more.%{link_end}"
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. %{docs_link_start}Learn more.%{link_end}"
+msgid "GitLabPages|When using Pages under the general domain of a GitLab instance (%{pages_host}), you cannot use HTTPS with subdomains of subdomains. If your namespace or groupname contains a dot, it does not work. This is a limitation of the HTTP Over TLS protocol. HTTP pages work if you don't redirect HTTP to HTTPS. %{docs_link_start}Learn more.%{link_end}"
msgstr ""
msgid "GitLabPages|With GitLab Pages you can host your static website directly from your GitLab repository. %{docs_link_start}Learn more.%{link_end}"
@@ -16947,9 +17209,6 @@ msgstr ""
msgid "Go to find file"
msgstr ""
-msgid "Go to fork"
-msgstr ""
-
msgid "Go to issue boards"
msgstr ""
@@ -17157,9 +17416,6 @@ msgstr ""
msgid "Group Hooks"
msgstr ""
-msgid "Group ID"
-msgstr ""
-
msgid "Group Owner must have signed in with SAML before enabling Group Managed Accounts"
msgstr ""
@@ -17187,9 +17443,6 @@ msgstr ""
msgid "Group by"
msgstr ""
-msgid "Group description"
-msgstr ""
-
msgid "Group description (optional)"
msgstr ""
@@ -17304,7 +17557,7 @@ msgstr ""
msgid "Group: %{name}"
msgstr ""
-msgid "GroupActivityMetrics|Issues opened"
+msgid "GroupActivityMetrics|Issues created"
msgstr ""
msgid "GroupActivityMetrics|Last 90 days"
@@ -17313,7 +17566,7 @@ msgstr ""
msgid "GroupActivityMetrics|Members added"
msgstr ""
-msgid "GroupActivityMetrics|Merge Requests opened"
+msgid "GroupActivityMetrics|Merge Requests created"
msgstr ""
msgid "GroupActivityMetrics|Recent activity"
@@ -17604,6 +17857,9 @@ msgstr ""
msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
+msgid "GroupSettings|Choose a group path that does not start with a dash or end with a period. It can also contain alphanumeric characters and underscores."
+msgstr ""
+
msgid "GroupSettings|Compliance frameworks"
msgstr ""
@@ -17637,7 +17893,7 @@ msgstr ""
msgid "GroupSettings|If not specified at the group or instance level, the default is %{default_initial_branch_name}. Does not affect existing repositories."
msgstr ""
-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."
+msgid "GroupSettings|If the parent group's visibility is lower than the group's current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility."
msgstr ""
msgid "GroupSettings|New runners registration token has been generated!"
@@ -17754,7 +18010,10 @@ msgstr ""
msgid "Groups and projects"
msgstr ""
-msgid "Groups and subgroups"
+msgid "Groups are a great way to organize projects and people."
+msgstr ""
+
+msgid "Groups are the best way to manage projects and members."
msgstr ""
msgid "Groups to synchronize"
@@ -17865,13 +18124,16 @@ msgstr ""
msgid "GroupsTree|Are you sure you want to leave the \"%{fullName}\" group?"
msgstr ""
-msgid "GroupsTree|Edit group"
+msgid "GroupsTree|Delete"
+msgstr ""
+
+msgid "GroupsTree|Edit"
msgstr ""
msgid "GroupsTree|Failed to leave the group. Please make sure you are not the only owner."
msgstr ""
-msgid "GroupsTree|Leave this group"
+msgid "GroupsTree|Leave group"
msgstr ""
msgid "GroupsTree|Loading groups"
@@ -17883,9 +18145,57 @@ msgstr ""
msgid "GroupsTree|No groups or projects matched your search"
msgstr ""
+msgid "GroupsTree|Options"
+msgstr ""
+
msgid "GroupsTree|Search by name"
msgstr ""
+msgid "Groups|Avatar will be removed. Are you sure?"
+msgstr ""
+
+msgid "Groups|Changing group URL can have unintended side effects."
+msgstr ""
+
+msgid "Groups|Checking group URL availability..."
+msgstr ""
+
+msgid "Groups|Enter a descriptive name for your group."
+msgstr ""
+
+msgid "Groups|Group ID"
+msgstr ""
+
+msgid "Groups|Group URL"
+msgstr ""
+
+msgid "Groups|Group avatar"
+msgstr ""
+
+msgid "Groups|Group description (optional)"
+msgstr ""
+
+msgid "Groups|Group name"
+msgstr ""
+
+msgid "Groups|Group path is available."
+msgstr ""
+
+msgid "Groups|Group path is unavailable. Path has been replaced with a suggested available path."
+msgstr ""
+
+msgid "Groups|Learn more"
+msgstr ""
+
+msgid "Groups|Must start with letter, digit, emoji, or underscore. Can also contain periods, dashes, spaces, and parentheses."
+msgstr ""
+
+msgid "Groups|Remove avatar"
+msgstr ""
+
+msgid "Groups|Save changes"
+msgstr ""
+
msgid "Guideline"
msgstr ""
@@ -17895,6 +18205,9 @@ msgstr ""
msgid "HAR file path or URL"
msgstr ""
+msgid "HTTP Archive (HAR)"
+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 ""
@@ -18299,6 +18612,9 @@ msgstr ""
msgid "INFO: Your SSH key is expiring soon. Please generate a new key."
msgstr ""
+msgid "IP"
+msgstr ""
+
msgid "IP Address"
msgstr ""
@@ -18335,6 +18651,9 @@ msgstr ""
msgid "IdentityVerification|Verify your identity"
msgstr ""
+msgid "IdentityVerification|You can always verify your account at a later time to create a group."
+msgstr ""
+
msgid "If any indexed field exceeds this limit, it is truncated to this number of characters. The rest of the content is neither indexed nor searchable. This does not apply to repository and wiki indexing. For unlimited characters, set this to 0."
msgstr ""
@@ -18392,6 +18711,9 @@ msgstr ""
msgid "If you add %{codeStart}needs%{codeEnd} to jobs in your pipeline you'll be able to view the %{codeStart}needs%{codeEnd} relationships between jobs in this tab as a %{linkStart}Directed Acyclic Graph (DAG)%{linkEnd}."
msgstr ""
+msgid "If you are added to a project, it will be displayed here."
+msgstr ""
+
msgid "If you did not initiate these sign-in attempts, please reach out to your administrator or enable two-factor authentication (2FA) on your account."
msgstr ""
@@ -18704,12 +19026,24 @@ msgstr ""
msgid "InProductMarketing|3 ways to dive into GitLab CI/CD"
msgstr ""
+msgid "InProductMarketing|A single application eliminates complex integrations, data chokepoints, and toolchain maintenance, resulting in greater productivity and lower cost."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features, build more efficiently, strengthen security and compliance."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features."
+msgstr ""
+
msgid "InProductMarketing|Actually, GitLab makes the team work (better)"
msgstr ""
msgid "InProductMarketing|And finally %{deploy_link} a Python application."
msgstr ""
+msgid "InProductMarketing|And many more..."
+msgstr ""
+
msgid "InProductMarketing|Are your runners ready?"
msgstr ""
@@ -18728,15 +19062,33 @@ msgstr ""
msgid "InProductMarketing|Blog"
msgstr ""
+msgid "InProductMarketing|Break down silos to coordinate seamlessly across development, operations, and security with a consistent experience across the development lifecycle."
+msgstr ""
+
+msgid "InProductMarketing|Burn up/down charts"
+msgstr ""
+
msgid "InProductMarketing|By enabling code owners and required merge approvals the right person will review the right MR. This is a win-win: cleaner code and a more efficient review process."
msgstr ""
msgid "InProductMarketing|Click on the number below that corresponds with your answer — 1 being very difficult, 5 being very easy."
msgstr ""
+msgid "InProductMarketing|Code owners"
+msgstr ""
+
msgid "InProductMarketing|Code owners and required merge approvals are part of the paid tiers of GitLab. You can start a free 30-day trial of GitLab Ultimate and enable these features in less than 5 minutes with no credit card required."
msgstr ""
+msgid "InProductMarketing|Code review analytics"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration across stages in GitLab"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration made easy"
+msgstr ""
+
msgid "InProductMarketing|Create a custom CI runner with just a few clicks"
msgstr ""
@@ -18746,12 +19098,21 @@ msgstr ""
msgid "InProductMarketing|Create a project in GitLab in 5 minutes"
msgstr ""
+msgid "InProductMarketing|Create well-defined workflows by using scoped labels on issues, merge requests, and epics. Labels with the same scope cannot be used together, which prevents conflicts."
+msgstr ""
+
msgid "InProductMarketing|Create your first project!"
msgstr ""
+msgid "InProductMarketing|Define who owns specific files or directories, so the right reviewers are suggested when a merge request introduces changes to those files."
+msgstr ""
+
msgid "InProductMarketing|Deliver Better Products Faster"
msgstr ""
+msgid "InProductMarketing|Dependency scanning"
+msgstr ""
+
msgid "InProductMarketing|Did you know teams that use GitLab are far more efficient?"
msgstr ""
@@ -18761,15 +19122,27 @@ msgstr ""
msgid "InProductMarketing|Dig in and create a project and a repo"
msgstr ""
+msgid "InProductMarketing|Discover Premium & Ultimate"
+msgstr ""
+
+msgid "InProductMarketing|Discover Premium & Ultimate."
+msgstr ""
+
msgid "InProductMarketing|Do you have a minute?"
msgstr ""
msgid "InProductMarketing|Do you have a teammate who would be perfect for this task?"
msgstr ""
+msgid "InProductMarketing|Dynamic application security testing"
+msgstr ""
+
msgid "InProductMarketing|Easy"
msgstr ""
+msgid "InProductMarketing|Epics"
+msgstr ""
+
msgid "InProductMarketing|Expand your DevOps journey with a free GitLab trial"
msgstr ""
@@ -18791,9 +19164,15 @@ msgstr ""
msgid "InProductMarketing|Feel the need for speed?"
msgstr ""
+msgid "InProductMarketing|Find and fix bottlenecks in your code review process by understanding how long open merge requests have been in review."
+msgstr ""
+
msgid "InProductMarketing|Find out how your teams are really doing"
msgstr ""
+msgid "InProductMarketing|Find out if your external libraries are safe. Run dependency scanning jobs that check for known vulnerabilities in your external libraries."
+msgstr ""
+
msgid "InProductMarketing|Follow our steps"
msgstr ""
@@ -18830,6 +19209,9 @@ msgstr ""
msgid "InProductMarketing|GitLab is better with teammates to help out!"
msgstr ""
+msgid "InProductMarketing|GitLab is infrastructure agnostic (supporting GCP, AWS, Azure, OpenShift, VMWare, On Prem, Bare Metal, and more), offering a consistent workflow experience – irrespective of the environment."
+msgstr ""
+
msgid "InProductMarketing|GitLab provides static application security testing (SAST), dynamic application security testing (DAST), container scanning, and dependency scanning to help you deliver secure applications along with license compliance."
msgstr ""
@@ -18920,21 +19302,36 @@ msgstr ""
msgid "InProductMarketing|It's also possible to simply %{external_repo_link} in order to take advantage of GitLab's CI/CD."
msgstr ""
+msgid "InProductMarketing|Keep your code quality high by defining who should approve merge requests and how many approvals are required."
+msgstr ""
+
msgid "InProductMarketing|Launch GitLab CI/CD in 20 minutes or less"
msgstr ""
+msgid "InProductMarketing|Lower cost of development"
+msgstr ""
+
+msgid "InProductMarketing|Make it easier to collaborate on high-level ideas by grouping related issues in an epic."
+msgstr ""
+
msgid "InProductMarketing|Making the switch? It's easier than you think to import your projects into GitLab. Move %{github_link}, or import something %{bitbucket_link}."
msgstr ""
msgid "InProductMarketing|Master the art of importing!"
msgstr ""
+msgid "InProductMarketing|Merge request approval rule"
+msgstr ""
+
msgid "InProductMarketing|Move on to easily creating a Pages website %{ci_template_link}"
msgstr ""
msgid "InProductMarketing|Multiple owners, confusing workstreams? We've got you covered"
msgstr ""
+msgid "InProductMarketing|Multiple required approvers"
+msgstr ""
+
msgid "InProductMarketing|Need an alternative to importing?"
msgstr ""
@@ -18947,18 +19344,33 @@ msgstr ""
msgid "InProductMarketing|Our tool brings all the things together"
msgstr ""
+msgid "InProductMarketing|Protect your web application by using DAST to examine for vulnerabilities in deployed environments."
+msgstr ""
+
msgid "InProductMarketing|Rapid development, simplified"
msgstr ""
msgid "InProductMarketing|Reduce Security & Compliance Risk"
msgstr ""
+msgid "InProductMarketing|Require multiple approvers on a merge request, so you know it's in good shape before it's merged."
+msgstr ""
+
+msgid "InProductMarketing|Roadmaps"
+msgstr ""
+
+msgid "InProductMarketing|Scoped labels"
+msgstr ""
+
msgid "InProductMarketing|Security that's integrated into your development lifecycle"
msgstr ""
msgid "InProductMarketing|Sometimes you're not ready to make a full transition to a new tool. If you're not ready to fully commit, %{mirroring_link} gives you a safe way to try out GitLab in parallel with your current tool."
msgstr ""
+msgid "InProductMarketing|Speed. Efficiency. Trust."
+msgstr ""
+
msgid "InProductMarketing|Spin up an autoscaling runner in GitLab"
msgstr ""
@@ -18968,6 +19380,9 @@ msgstr ""
msgid "InProductMarketing|Start a Self-Managed trial"
msgstr ""
+msgid "InProductMarketing|Start a free trial"
+msgstr ""
+
msgid "InProductMarketing|Start a free trial of GitLab Ultimate – no credit card required"
msgstr ""
@@ -19034,6 +19449,9 @@ msgstr ""
msgid "InProductMarketing|To understand and get the most out of GitLab, start at the beginning and %{project_link}. In GitLab, repositories are part of a project, so after you've created your project you can go ahead and %{repo_link}."
msgstr ""
+msgid "InProductMarketing|Track completed issues in a chart, so you can see how a milestone is progressing at a glance."
+msgstr ""
+
msgid "InProductMarketing|Try GitLab Ultimate for free"
msgstr ""
@@ -19070,6 +19488,9 @@ msgstr ""
msgid "InProductMarketing|Very easy"
msgstr ""
+msgid "InProductMarketing|Visualize your epics and milestones in a timeline."
+msgstr ""
+
msgid "InProductMarketing|Want to host GitLab on your servers?"
msgstr ""
@@ -19091,6 +19512,9 @@ msgstr ""
msgid "InProductMarketing|YouTube"
msgstr ""
+msgid "InProductMarketing|Your software, deployed your way"
+msgstr ""
+
msgid "InProductMarketing|Your teams can be more efficient"
msgstr ""
@@ -19211,9 +19635,18 @@ msgstr ""
msgid "IncidentManagement|No incidents to display."
msgstr ""
+msgid "IncidentManagement|None"
+msgstr ""
+
msgid "IncidentManagement|Open"
msgstr ""
+msgid "IncidentManagement|Page your team with escalation policies"
+msgstr ""
+
+msgid "IncidentManagement|Paged"
+msgstr ""
+
msgid "IncidentManagement|Published"
msgstr ""
@@ -19223,6 +19656,9 @@ msgstr ""
msgid "IncidentManagement|Severity"
msgstr ""
+msgid "IncidentManagement|Status"
+msgstr ""
+
msgid "IncidentManagement|There are no closed incidents"
msgstr ""
@@ -19241,6 +19677,9 @@ msgstr ""
msgid "IncidentManagement|Unpublished"
msgstr ""
+msgid "IncidentManagement|Use escalation policies to automatically page your team when incidents are created."
+msgstr ""
+
msgid "IncidentSettings|Activate \"time to SLA\" countdown timer"
msgstr ""
@@ -19286,7 +19725,10 @@ msgstr ""
msgid "Incidents"
msgstr ""
-msgid "Incidents|Add a URL"
+msgid "Incidents|Add image details"
+msgstr ""
+
+msgid "Incidents|Add text or a link to display with your image. If you don't add either, the file name displays instead."
msgstr ""
msgid "Incidents|Drop or %{linkStart}upload%{linkEnd} a metric screenshot to attach it to the incident"
@@ -19301,10 +19743,10 @@ msgstr ""
msgid "Incidents|There was an issue loading metric images."
msgstr ""
-msgid "Incidents|There was an issue uploading your image."
+msgid "Incidents|There was an issue updating your image."
msgstr ""
-msgid "Incidents|You can optionally add a URL to link users to the original graph."
+msgid "Incidents|There was an issue uploading your image."
msgstr ""
msgid "Incident|Alert details"
@@ -19313,9 +19755,18 @@ msgstr ""
msgid "Incident|Are you sure you wish to delete this image?"
msgstr ""
+msgid "Incident|Delete image"
+msgstr ""
+
msgid "Incident|Deleting %{filename}"
msgstr ""
+msgid "Incident|Edit image text or link"
+msgstr ""
+
+msgid "Incident|Editing %{filename}"
+msgstr ""
+
msgid "Incident|Metrics"
msgstr ""
@@ -19587,12 +20038,18 @@ msgstr ""
msgid "Integrations|Branches for which notifications are to be sent"
msgstr ""
+msgid "Integrations|Clear if using a self-signed certificate."
+msgstr ""
+
msgid "Integrations|Comment detail:"
msgstr ""
msgid "Integrations|Comment settings:"
msgstr ""
+msgid "Integrations|Connection details"
+msgstr ""
+
msgid "Integrations|Connection failed. Please check your settings."
msgstr ""
@@ -19617,6 +20074,9 @@ msgstr ""
msgid "Integrations|Enable GitLab.com slash commands in a Slack workspace."
msgstr ""
+msgid "Integrations|Enable SSL verification"
+msgstr ""
+
msgid "Integrations|Enable comments"
msgstr ""
@@ -19695,6 +20155,9 @@ msgstr ""
msgid "Integrations|Return to GitLab for Jira"
msgstr ""
+msgid "Integrations|SSL verification"
+msgstr ""
+
msgid "Integrations|Save settings?"
msgstr ""
@@ -19740,9 +20203,6 @@ msgstr ""
msgid "Integrations|Use default settings"
msgstr ""
-msgid "Integrations|When you mention a Jira issue in a commit or merge request, GitLab creates a remote link and comment (if enabled)."
-msgstr ""
-
msgid "Integrations|You can now close this window and return to the GitLab for Jira application."
msgstr ""
@@ -19767,9 +20227,6 @@ msgstr ""
msgid "Integrations|can't exceed %{recipients_limit}"
msgstr ""
-msgid "Interactive developer security education."
-msgstr ""
-
msgid "Interactive mode"
msgstr ""
@@ -20259,6 +20716,9 @@ msgstr ""
msgid "IssueAnalytics|Assignees"
msgstr ""
+msgid "IssueAnalytics|Created by"
+msgstr ""
+
msgid "IssueAnalytics|Due date"
msgstr ""
@@ -20271,9 +20731,6 @@ msgstr ""
msgid "IssueAnalytics|Milestone"
msgstr ""
-msgid "IssueAnalytics|Opened by"
-msgstr ""
-
msgid "IssueAnalytics|Status"
msgstr ""
@@ -20397,10 +20854,10 @@ msgstr ""
msgid "IssuesAnalytics|Avg/Month:"
msgstr ""
-msgid "IssuesAnalytics|Issues opened"
+msgid "IssuesAnalytics|Issues created"
msgstr ""
-msgid "IssuesAnalytics|Issues opened per month"
+msgid "IssuesAnalytics|Issues created per month"
msgstr ""
msgid "IssuesAnalytics|Last 12 months"
@@ -20427,6 +20884,9 @@ msgstr ""
msgid "It looks like you have some draft commits in this branch."
msgstr ""
+msgid "It looks like you're attempting to activate your subscription. Use %{a_start}the Subscription page%{a_end} instead."
+msgstr ""
+
msgid "It may be several days before you see feature usage data."
msgstr ""
@@ -20655,6 +21115,9 @@ msgstr ""
msgid "JiraConnect|You can now close this window and return to Jira."
msgstr ""
+msgid "JiraConnect|You don't have permission to create branches for this project. Select a different project or contact the project owner for access. %{linkStart}Learn more.%{linkEnd}"
+msgstr ""
+
msgid "JiraRequest|A connection error occurred while connecting to Jira. Try your request again."
msgstr ""
@@ -20703,13 +21166,13 @@ msgstr ""
msgid "JiraService|Define the type of Jira issue to create from a vulnerability."
msgstr ""
-msgid "JiraService|Displaying Jira issues while leaving the GitLab issue functionality enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
+msgid "JiraService|Displaying Jira issues while leaving GitLab issues also enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
msgstr ""
-msgid "JiraService|Enable Jira issues"
+msgid "JiraService|Enable Jira issue creation from vulnerabilities"
msgstr ""
-msgid "JiraService|Enable Jira issues creation from vulnerabilities"
+msgid "JiraService|Enable Jira issues"
msgstr ""
msgid "JiraService|Enable Jira transitions"
@@ -20826,16 +21289,19 @@ msgstr ""
msgid "JiraService|View Jira issues in GitLab"
msgstr ""
-msgid "JiraService|Warning: All GitLab users that have access to this GitLab project are able to view all issues from the Jira project specified below."
+msgid "JiraService|Warning: All GitLab users with access to this GitLab project can view all issues from the Jira project you select."
msgstr ""
msgid "JiraService|Web URL"
msgstr ""
-msgid "JiraService|Work on Jira issues without leaving GitLab. Adds a Jira menu to access your list of Jira issues and view any issue as read-only."
+msgid "JiraService|When a Jira issue is mentioned in a commit or merge request, a remote link and comment (if enabled) will be created."
+msgstr ""
+
+msgid "JiraService|Work on Jira issues without leaving GitLab. Add a Jira menu to access a read-only list of your Jira issues."
msgstr ""
-msgid "JiraService|You need to configure Jira before enabling this integration. For more details, read the %{jira_doc_link_start}Jira integration documentation%{link_end}."
+msgid "JiraService|You must configure Jira before enabling this integration. %{jira_doc_link_start}Learn more.%{link_end}"
msgstr ""
msgid "Job"
@@ -20847,9 +21313,6 @@ msgstr ""
msgid "Job Failed #%{build_id}"
msgstr ""
-msgid "Job ID"
-msgstr ""
-
msgid "Job artifact"
msgstr ""
@@ -20916,9 +21379,27 @@ msgstr ""
msgid "Jobs|You're about to retry a job that failed because it attempted to deploy code that is older than the latest deployment. Retrying this job could result in overwriting the environment with the older source code."
msgstr ""
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source} into %{target}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{ref}"
+msgstr ""
+
+msgid "Job|Are you sure you want to erase this job log and artifacts?"
+msgstr ""
+
msgid "Job|Browse"
msgstr ""
+msgid "Job|Cancel"
+msgstr ""
+
msgid "Job|Complete Raw"
msgstr ""
@@ -20928,6 +21409,9 @@ msgstr ""
msgid "Job|Erase job log and artifacts"
msgstr ""
+msgid "Job|Finished at"
+msgstr ""
+
msgid "Job|Job artifacts"
msgstr ""
@@ -20940,7 +21424,7 @@ msgstr ""
msgid "Job|Keep"
msgstr ""
-msgid "Job|Pipeline"
+msgid "Job|Retry"
msgstr ""
msgid "Job|Scroll to bottom"
@@ -20952,6 +21436,9 @@ msgstr ""
msgid "Job|Show complete raw"
msgstr ""
+msgid "Job|Status"
+msgstr ""
+
msgid "Job|The artifacts were removed"
msgstr ""
@@ -20979,21 +21466,12 @@ msgstr ""
msgid "Job|delayed"
msgstr ""
-msgid "Job|for"
-msgstr ""
-
-msgid "Job|into"
-msgstr ""
-
msgid "Job|manual"
msgstr ""
msgid "Job|triggered"
msgstr ""
-msgid "Job|with"
-msgstr ""
-
msgid "Join Zoom meeting"
msgstr ""
@@ -21096,9 +21574,6 @@ msgstr ""
msgid "Ki"
msgstr ""
-msgid "Kontra"
-msgstr ""
-
msgid "Kroki"
msgstr ""
@@ -21424,6 +21899,9 @@ msgstr ""
msgid "Learn more about Auto DevOps"
msgstr ""
+msgid "Learn more about GitLab"
+msgstr ""
+
msgid "Learn more about Needs relationships"
msgstr ""
@@ -21763,9 +22241,18 @@ msgstr ""
msgid "Licenses|Displays licenses detected in the project, based on the %{linkStart}latest successful%{linkEnd} scan"
msgstr ""
+msgid "Licenses|Drag your license file here or %{linkStart}click to upload%{linkEnd}."
+msgstr ""
+
+msgid "Licenses|Drop your license file to start the upload."
+msgstr ""
+
msgid "Licenses|Error fetching the license list. Please check your network connection and try again."
msgstr ""
+msgid "Licenses|Error: You are trying to upload something other than a file"
+msgstr ""
+
msgid "Licenses|License Compliance"
msgstr ""
@@ -21784,6 +22271,9 @@ msgstr ""
msgid "Licenses|Specified policies in this project"
msgstr ""
+msgid "Licenses|The file could not be uploaded."
+msgstr ""
+
msgid "Licenses|The license list details information about the licenses used within your project."
msgstr ""
@@ -21817,13 +22307,6 @@ msgstr ""
msgid "Limit the size of Sidekiq jobs stored in Redis."
msgstr ""
-msgid "Limited to showing %d event at most"
-msgid_plural "Limited to showing %d events at most"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-msgstr[3] ""
-
msgid "Limiting mode"
msgstr ""
@@ -21833,6 +22316,9 @@ msgstr ""
msgid "Link"
msgstr ""
+msgid "Link (optional)"
+msgstr ""
+
msgid "Link Prometheus monitoring to GitLab."
msgstr ""
@@ -21869,6 +22355,9 @@ msgstr ""
msgid "Linked emails (%{email_count})"
msgstr ""
+msgid "Linked epics"
+msgstr ""
+
msgid "Linked issues"
msgstr ""
@@ -21896,6 +22385,15 @@ msgstr ""
msgid "List of all merge commits"
msgstr ""
+msgid "List of environments for this project"
+msgstr ""
+
+msgid "List of suitable GCP locations"
+msgstr ""
+
+msgid "List of users allowed to exceed the rate limit."
+msgstr ""
+
msgid "List options"
msgstr ""
@@ -22115,6 +22613,9 @@ msgstr ""
msgid "Maintenance mode"
msgstr ""
+msgid "Make adjustments to how your GitLab instance is set up."
+msgstr ""
+
msgid "Make and review changes in the browser with the Web IDE"
msgstr ""
@@ -22259,6 +22760,12 @@ msgstr ""
msgid "MarkdownEditor|Add italic text (%{modifier_key}I)"
msgstr ""
+msgid "MarkdownEditor|Add strikethrough text (%{modifierKey}⇧X)"
+msgstr ""
+
+msgid "MarkdownEditor|Add strikethrough text (%{modifier_key}⇧X)"
+msgstr ""
+
msgid "Marked For Deletion At - %{deletion_time}"
msgstr ""
@@ -22520,6 +23027,9 @@ msgstr ""
msgid "Maximum push size (MB)"
msgstr ""
+msgid "Maximum requests per 10 minutes per user"
+msgstr ""
+
msgid "Maximum requests per minute"
msgstr ""
@@ -22610,6 +23120,23 @@ msgstr ""
msgid "Members of a group may only view projects they have permission to access"
msgstr ""
+msgid "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seat in use and will be billed for the overage."
+msgid_plural "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seats in use and will be billed for the overage."
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
+msgid "MembersOverage|You are about to incur additional charges"
+msgstr ""
+
+msgid "MembersOverage|Your subscription includes %d seat."
+msgid_plural "MembersOverage|Your subscription includes %d seats."
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "Membership"
msgstr ""
@@ -22814,9 +23341,6 @@ msgstr ""
msgid "Merge request not merged"
msgstr ""
-msgid "Merge request pipelines 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 merge request pipelines."
-msgstr ""
-
msgid "Merge request reports"
msgstr ""
@@ -22913,13 +23437,13 @@ msgstr ""
msgid "MergeRequests|Create issue to resolve thread"
msgstr ""
-msgid "MergeRequests|Failed to squash. Should be done manually."
+msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Saving the comment failed"
+msgid "MergeRequests|Squashing failed: Squash the commits locally, resolve any conflicts, then push the branch."
msgstr ""
-msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
+msgid "MergeRequests|Squashing not allowed: This project doesn't allow you to squash commits when merging."
msgstr ""
msgid "MergeRequests|Thread stays resolved"
@@ -23764,6 +24288,18 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "MrList|Assigned to %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from assignee %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from reviewer %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Review requested from %{name}, go to their profile."
+msgstr ""
+
msgid "Multi-project"
msgstr ""
@@ -23797,7 +24333,7 @@ msgstr ""
msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "My Awesome Group"
+msgid "My awesome group"
msgstr ""
msgid "My company or team"
@@ -24423,9 +24959,6 @@ msgstr ""
msgid "No available branches"
msgstr ""
-msgid "No available groups to fork the project."
-msgstr ""
-
msgid "No branches found"
msgstr ""
@@ -24636,6 +25169,9 @@ msgstr ""
msgid "No ref selected"
msgstr ""
+msgid "No regions configured"
+msgstr ""
+
msgid "No related merge requests found."
msgstr ""
@@ -25452,6 +25988,9 @@ msgstr ""
msgid "Only reCAPTCHA v2 is supported:"
msgstr ""
+msgid "Only required if not using role instance credentials."
+msgstr ""
+
msgid "Only use lowercase letters, numbers, and underscores."
msgstr ""
@@ -25476,9 +26015,6 @@ msgstr ""
msgid "Open a CLI and connect to the cluster you want to install the agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
-msgid "Open epics"
-msgstr ""
-
msgid "Open errors"
msgstr ""
@@ -25518,7 +26054,7 @@ msgstr ""
msgid "Opened issues"
msgstr ""
-msgid "OpenedNDaysAgo|Opened"
+msgid "OpenedNDaysAgo|Created"
msgstr ""
msgid "Opens in a new window"
@@ -25563,9 +26099,6 @@ msgstr ""
msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
-msgid "Optional."
-msgstr ""
-
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
msgstr ""
@@ -26356,6 +26889,9 @@ msgstr ""
msgid "PerformanceBar|Memory"
msgstr ""
+msgid "PerformanceBar|Memory report"
+msgstr ""
+
msgid "PerformanceBar|Redis calls"
msgstr ""
@@ -26389,18 +26925,12 @@ msgstr ""
msgid "PerformanceBar|wall"
msgstr ""
-msgid "Performs a rebase but skips triggering a new pipeline"
-msgstr ""
-
msgid "Period in seconds"
msgstr ""
msgid "Permalink"
msgstr ""
-msgid "Permanently delete project"
-msgstr ""
-
msgid "Permanently remove group"
msgstr ""
@@ -26671,6 +27201,51 @@ msgstr ""
msgid "PipelineStatusTooltip|Pipeline: %{ci_status}"
msgstr ""
+msgid "PipelineWizardDefaultCommitMessage|Add %{filename}"
+msgstr ""
+
+msgid "PipelineWizardDefaultCommitMessage|Update %{filename}"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|At least one entry is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This field is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This value is not valid"
+msgstr ""
+
+msgid "PipelineWizardListWidget|add another step"
+msgstr ""
+
+msgid "PipelineWizardListWidget|remove step"
+msgstr ""
+
+msgid "PipelineWizard|Commit"
+msgstr ""
+
+msgid "PipelineWizard|Commit Message"
+msgstr ""
+
+msgid "PipelineWizard|Commit changes to your file"
+msgstr ""
+
+msgid "PipelineWizard|Commit file to Branch"
+msgstr ""
+
+msgid "PipelineWizard|Commit your new file"
+msgstr ""
+
+msgid "PipelineWizard|The file has been committed."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem committing the changes."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem while checking whether your file already exists in the specified branch."
+msgstr ""
+
msgid "Pipelines"
msgstr ""
@@ -26785,7 +27360,7 @@ msgstr ""
msgid "Pipelines|Project cache successfully reset."
msgstr ""
-msgid "Pipelines|Revoke"
+msgid "Pipelines|Revoke trigger"
msgstr ""
msgid "Pipelines|Something went wrong while cleaning runners cache."
@@ -26830,6 +27405,12 @@ msgstr ""
msgid "Pipelines|This is a child pipeline within the parent pipeline"
msgstr ""
+msgid "Pipelines|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipelines|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipelines|This pipeline will run code originating from a forked project merge request. This means that the code can potentially have security considerations like exposing CI variables."
msgstr ""
@@ -26872,9 +27453,6 @@ msgstr ""
msgid "Pipelines|Your changes have been successfully committed. Now redirecting to the new merge request page."
msgstr ""
-msgid "Pipelines|detached"
-msgstr ""
-
msgid "Pipelines|error"
msgstr ""
@@ -26884,10 +27462,13 @@ msgstr ""
msgid "Pipelines|latest"
msgstr ""
-msgid "Pipelines|stuck"
+msgid "Pipelines|merge request"
msgstr ""
-msgid "Pipelines|train"
+msgid "Pipelines|merge train"
+msgstr ""
+
+msgid "Pipelines|stuck"
msgstr ""
msgid "Pipelines|yaml invalid"
@@ -27019,6 +27600,12 @@ msgstr ""
msgid "Pipeline|This change will not change the overall test coverage if merged."
msgstr ""
+msgid "Pipeline|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipeline|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipeline|Trigger author"
msgstr ""
@@ -27043,6 +27630,12 @@ msgstr ""
msgid "Pipeline|for"
msgstr ""
+msgid "Pipeline|merge request"
+msgstr ""
+
+msgid "Pipeline|merge train"
+msgstr ""
+
msgid "Pipeline|on"
msgstr ""
@@ -27181,9 +27774,6 @@ msgstr ""
msgid "Please enter a valid time interval"
msgstr ""
-msgid "Please enter or upload a valid license."
-msgstr ""
-
msgid "Please enter your current password."
msgstr ""
@@ -27292,9 +27882,6 @@ msgstr ""
msgid "Please type %{phrase_code} to proceed or close this modal to cancel."
msgstr ""
-msgid "Please type the following to confirm:"
-msgstr ""
-
msgid "Please use this form to report to the admin users who create spam issues, comments or behave inappropriately."
msgstr ""
@@ -27322,12 +27909,27 @@ msgstr ""
msgid "Policies"
msgstr ""
+msgid "Policy '%{escalation_policy_name}' does not exist."
+msgstr ""
+
msgid "Policy management project does have any policies in %{policy_path}"
msgstr ""
msgid "Policy project doesn't exist"
msgstr ""
+msgid "PolicyRuleMultiSelect|%{firstLabel} +%{numberOfAdditionalLabels} more"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|All %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select all"
+msgstr ""
+
msgid "Polling interval multiplier"
msgstr ""
@@ -27556,6 +28158,9 @@ msgstr ""
msgid "Private projects can be created in your personal namespace with:"
msgstr ""
+msgid "Problem with %{name} command: %{message}."
+msgstr ""
+
msgid "Proceed"
msgstr ""
@@ -28030,6 +28635,9 @@ msgstr ""
msgid "Progress"
msgstr ""
+msgid "Progress tracking"
+msgstr ""
+
msgid "Project"
msgstr ""
@@ -28261,6 +28869,9 @@ msgstr ""
msgid "ProjectQualitySummary|Failure"
msgstr ""
+msgid "ProjectQualitySummary|Get insight into the overall percentage of tests in your project that succeed, fail and are skipped."
+msgstr ""
+
msgid "ProjectQualitySummary|Latest pipeline results"
msgstr ""
@@ -28279,6 +28890,12 @@ msgstr ""
msgid "ProjectQualitySummary|See project Code Coverage Statistics"
msgstr ""
+msgid "ProjectQualitySummary|Set up test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|Set up test runs (opens in a new tab)"
+msgstr ""
+
msgid "ProjectQualitySummary|Skipped"
msgstr ""
@@ -28555,13 +29172,19 @@ msgstr ""
msgid "ProjectSettings|LFS objects from this repository are available to forks. %{linkStart}How do I remove them?%{linkEnd}"
msgstr ""
+msgid "ProjectSettings|Learn about commit history."
+msgstr ""
+
+msgid "ProjectSettings|Leave empty to use default template."
+msgstr ""
+
msgid "ProjectSettings|Manage who can see the project in the public access directory."
msgstr ""
msgid "ProjectSettings|Manages large files such as audio, video, and graphics files."
msgstr ""
-msgid "ProjectSettings|Maximum 500 characters."
+msgid "ProjectSettings|Maximum %{maxLength} characters."
msgstr ""
msgid "ProjectSettings|Merge checks"
@@ -28702,6 +29325,9 @@ msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
msgstr ""
+msgid "ProjectSettings|The default template will be applied on save."
+msgstr ""
+
msgid "ProjectSettings|These checks must pass before merge requests can be merged."
msgstr ""
@@ -28756,6 +29382,9 @@ msgstr ""
msgid "ProjectSettings|What are badges?"
msgstr ""
+msgid "ProjectSettings|What are merge trains?"
+msgstr ""
+
msgid "ProjectSettings|When merge request pipelines are enabled in the CI/CD configuration file, pipelines validate the combined results of the source and target branches. %{link_start}How to configure merge request pipelines?%{link_end}"
msgstr ""
@@ -28873,6 +29502,9 @@ msgstr ""
msgid "Projects are organized into groups"
msgstr ""
+msgid "Projects are where you store your code, access issues, wiki and other features of GitLab."
+msgstr ""
+
msgid "Projects contributed to"
msgstr ""
@@ -28888,12 +29520,6 @@ msgstr ""
msgid "Projects to index"
msgstr ""
-msgid "Projects will be permanently deleted after a %{waiting_period}-day waiting period."
-msgstr ""
-
-msgid "Projects will be permanently deleted immediately."
-msgstr ""
-
msgid "Projects with critical vulnerabilities"
msgstr ""
@@ -28978,6 +29604,9 @@ msgstr ""
msgid "ProjectsNew|Import project"
msgstr ""
+msgid "ProjectsNew|Include a Getting Started README"
+msgstr ""
+
msgid "ProjectsNew|Initialize repository with a README"
msgstr ""
@@ -28993,6 +29622,9 @@ msgstr ""
msgid "ProjectsNew|Project description %{tag_start}(optional)%{tag_end}"
msgstr ""
+msgid "ProjectsNew|Recommended if you're new to GitLab"
+msgstr ""
+
msgid "ProjectsNew|Run CI/CD for external repository"
msgstr ""
@@ -29410,6 +30042,9 @@ msgstr ""
msgid "ProtectedBranch|Unprotect"
msgstr ""
+msgid "ProtectedBranch|Unprotect branch"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
@@ -29437,6 +30072,9 @@ msgstr ""
msgid "ProtectedEnvironment|Protected Environment (%{protected_environments_count})"
msgstr ""
+msgid "ProtectedEnvironment|Required approvals"
+msgstr ""
+
msgid "ProtectedEnvironment|Select an environment"
msgstr ""
@@ -29458,10 +30096,13 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|Unprotect tag"
+msgstr ""
+
msgid "ProtectedTags|default"
msgstr ""
-msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
+msgid "ProtectedTag|By default, protected tags restrict who can modify the tag."
msgstr ""
msgid "ProtectedTag|Learn more."
@@ -29524,6 +30165,9 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Public projects are an easy way to allow everyone to have read-only access."
+msgstr ""
+
msgid "Publish to status page"
msgstr ""
@@ -29680,9 +30324,6 @@ msgstr ""
msgid "QualitySummary|Project quality"
msgstr ""
-msgid "Quarters"
-msgstr ""
-
msgid "Query"
msgstr ""
@@ -29767,6 +30408,9 @@ msgstr ""
msgid "Read more about project permissions %{help_link_open}here%{help_link_close}"
msgstr ""
+msgid "Read more about related epics"
+msgstr ""
+
msgid "Read more about related issues"
msgstr ""
@@ -29797,10 +30441,7 @@ msgstr ""
msgid "Rebase source branch on the target branch."
msgstr ""
-msgid "Rebase without CI"
-msgstr ""
-
-msgid "Rebases and triggers a pipeline"
+msgid "Rebase without pipeline"
msgstr ""
msgid "Recaptcha verified?"
@@ -29851,9 +30492,6 @@ msgstr ""
msgid "Reconfigure"
msgstr ""
-msgid "Recovering projects"
-msgstr ""
-
msgid "Recovery Codes"
msgstr ""
@@ -29915,6 +30553,12 @@ msgstr ""
msgid "Regex pattern"
msgstr ""
+msgid "Region"
+msgstr ""
+
+msgid "Regions"
+msgstr ""
+
msgid "Register"
msgstr ""
@@ -30147,9 +30791,6 @@ msgstr ""
msgid "Remove all or specific reviewer(s)"
msgstr ""
-msgid "Remove approver"
-msgstr ""
-
msgid "Remove approvers"
msgstr ""
@@ -30165,6 +30806,9 @@ msgstr ""
msgid "Remove attention request"
msgstr ""
+msgid "Remove attention request(s)"
+msgstr ""
+
msgid "Remove avatar"
msgstr ""
@@ -30303,6 +30947,9 @@ msgstr ""
msgid "Removed an issue from an epic."
msgstr ""
+msgid "Removed attention from %{users_sentence}."
+msgstr ""
+
msgid "Removed attention request from @%{username}"
msgstr ""
@@ -30354,6 +31001,9 @@ msgstr ""
msgid "Removes an issue from an epic."
msgstr ""
+msgid "Removes attention from %{users_sentence}."
+msgstr ""
+
msgid "Removes parent epic %{epic_ref}."
msgstr ""
@@ -30465,6 +31115,9 @@ msgstr ""
msgid "Report abuse to admin"
msgstr ""
+msgid "Report is generating and will be sent to your email address."
+msgstr ""
+
msgid "Reported %{timeAgo} by %{reportedBy}"
msgstr ""
@@ -30764,6 +31417,15 @@ msgstr ""
msgid "Request attention"
msgstr ""
+msgid "Request attention from %{users_sentence}."
+msgstr ""
+
+msgid "Request attention from assignee or reviewer"
+msgstr ""
+
+msgid "Request attention from assignee(s) or reviewer(s)"
+msgstr ""
+
msgid "Request attention to review"
msgstr ""
@@ -30788,6 +31450,9 @@ msgstr ""
msgid "Requested %{time_ago}"
msgstr ""
+msgid "Requested attention from %{users_sentence}."
+msgstr ""
+
msgid "Requested attention from @%{username}"
msgstr ""
@@ -31006,6 +31671,9 @@ msgstr ""
msgid "Restore project"
msgstr ""
+msgid "Restoring projects"
+msgstr ""
+
msgid "Restoring the group will prevent the group, its subgroups and projects from being removed on this date."
msgstr ""
@@ -31036,6 +31704,9 @@ msgstr ""
msgid "Retry"
msgstr ""
+msgid "Retry failed jobs"
+msgstr ""
+
msgid "Retry job"
msgstr ""
@@ -31085,9 +31756,6 @@ msgstr ""
msgid "Review changes"
msgstr ""
-msgid "Review requested from %{name}"
-msgstr ""
-
msgid "Review requests for you"
msgstr ""
@@ -31254,6 +31922,9 @@ msgstr ""
msgid "Runners|Assigned Group"
msgstr ""
+msgid "Runners|Assigned Projects (%{projectCount})"
+msgstr ""
+
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -31323,6 +31994,9 @@ msgstr ""
msgid "Runners|Instance"
msgstr ""
+msgid "Runners|Jobs"
+msgstr ""
+
msgid "Runners|Last contact"
msgstr ""
@@ -31416,9 +32090,6 @@ msgstr ""
msgid "Runners|Runner %{name} was deleted"
msgstr ""
-msgid "Runners|Runner ID"
-msgstr ""
-
msgid "Runners|Runner assigned to project."
msgstr ""
@@ -31566,6 +32237,9 @@ msgstr ""
msgid "Runners|stale"
msgstr ""
+msgid "Runner|This runner has not run any jobs."
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -31680,6 +32354,24 @@ msgstr ""
msgid "Saving project."
msgstr ""
+msgid "ScanResultPolicy|%{ifLabelStart}if%{ifLabelEnd} %{scanners} scan in an open merge request targeting the %{branches} branch(es) finds %{vulnerabilitiesAllowed} or more %{severities} vulnerabilities that are %{vulnerabilityStates}"
+msgstr ""
+
+msgid "ScanResultPolicy|%{thenLabelStart}Then%{thenLabelEnd} Require approval from %{approvalsRequired} of the following approvers: %{approvers}"
+msgstr ""
+
+msgid "ScanResultPolicy|add an approver"
+msgstr ""
+
+msgid "ScanResultPolicy|scanners"
+msgstr ""
+
+msgid "ScanResultPolicy|severity levels"
+msgstr ""
+
+msgid "ScanResultPolicy|vulnerability states"
+msgstr ""
+
msgid "Scanner"
msgstr ""
@@ -31812,6 +32504,9 @@ msgstr ""
msgid "Search for a user"
msgstr ""
+msgid "Search for an emoji"
+msgstr ""
+
msgid "Search for projects, issues, etc."
msgstr ""
@@ -32021,18 +32716,12 @@ msgstr ""
msgid "Secret Detection"
msgstr ""
-msgid "Secret access key"
-msgstr ""
-
msgid "Secret token"
msgstr ""
msgid "Secure token that identifies an external storage request."
msgstr ""
-msgid "SecureCodeWarrior"
-msgstr ""
-
msgid "Security"
msgstr ""
@@ -32057,9 +32746,6 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "Security training with guide and learning pathways."
-msgstr ""
-
msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
@@ -32162,7 +32848,7 @@ msgstr ""
msgid "SecurityConfiguration|Manage corpus"
msgstr ""
-msgid "SecurityConfiguration|Manage corpus files used as mutation sources in coverage fuzzing."
+msgid "SecurityConfiguration|Manage corpus files used as seed inputs with coverage-guided fuzzing."
msgstr ""
msgid "SecurityConfiguration|Manage profiles for use by DAST scans."
@@ -32228,15 +32914,15 @@ msgstr ""
msgid "SecurityOrchestration|.yaml preview"
msgstr ""
-msgid "SecurityOrchestration|Action"
-msgstr ""
-
msgid "SecurityOrchestration|Actions"
msgstr ""
msgid "SecurityOrchestration|Add rule"
msgstr ""
+msgid "SecurityOrchestration|After dismissing the alert, the information will never be shown again."
+msgstr ""
+
msgid "SecurityOrchestration|All policies"
msgstr ""
@@ -32252,7 +32938,7 @@ msgstr ""
msgid "SecurityOrchestration|Description"
msgstr ""
-msgid "SecurityOrchestration|Disabled"
+msgid "SecurityOrchestration|Don't show the alert anymore"
msgstr ""
msgid "SecurityOrchestration|Edit policy"
@@ -32261,13 +32947,13 @@ msgstr ""
msgid "SecurityOrchestration|Edit policy project"
msgstr ""
-msgid "SecurityOrchestration|Enabled"
+msgid "SecurityOrchestration|Empty policy name"
msgstr ""
-msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Enabled"
msgstr ""
-msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
msgstr ""
msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
@@ -32276,7 +32962,7 @@ msgstr ""
msgid "SecurityOrchestration|Invalid policy type"
msgstr ""
-msgid "SecurityOrchestration|Latest scan"
+msgid "SecurityOrchestration|Latest scan run against %{agent}"
msgstr ""
msgid "SecurityOrchestration|Network"
@@ -32285,15 +32971,27 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No actions defined - policy will not run."
+msgstr ""
+
+msgid "SecurityOrchestration|No description"
+msgstr ""
+
msgid "SecurityOrchestration|No rules defined - policy will not run."
msgstr ""
+msgid "SecurityOrchestration|Not enabled"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
msgid "SecurityOrchestration|Policies"
msgstr ""
+msgid "SecurityOrchestration|Policy Type"
+msgstr ""
+
msgid "SecurityOrchestration|Policy cannot be enabled for non-existing branches (%{branches})"
msgstr ""
@@ -32318,10 +33016,13 @@ msgstr ""
msgid "SecurityOrchestration|Require %{approvals} %{plural} from %{approvers} if any of the following occur:"
msgstr ""
-msgid "SecurityOrchestration|Rule"
+msgid "SecurityOrchestration|Rules"
msgstr ""
-msgid "SecurityOrchestration|Rules"
+msgid "SecurityOrchestration|Runs %{actions} and %{lastAction} scans"
+msgstr ""
+
+msgid "SecurityOrchestration|Runs a %{action} scan"
msgstr ""
msgid "SecurityOrchestration|Scan Execution"
@@ -32381,6 +33082,9 @@ msgstr ""
msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
+msgid "SecurityOrchestration|This view only shows scan results for the agent %{agent}. You can view scan results for all agents in the %{linkStart}Operational Vulnerabilities tab of the vulnerability report%{linkEnd}."
+msgstr ""
+
msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
@@ -32435,9 +33139,6 @@ msgstr ""
msgid "SecurityOrchestration|users with ids"
msgstr ""
-msgid "SecurityOrchestration|view results"
-msgstr ""
-
msgid "SecurityOrchestration|vulnerabilities"
msgstr ""
@@ -33107,22 +33808,19 @@ 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|In order to start using functions as a service, you must first install Knative on your Kubernetes cluster. %{linkStart}More information%{linkEnd}"
-msgstr ""
-
msgid "Serverless|Learn more about Serverless"
msgstr ""
msgid "Serverless|No functions available"
msgstr ""
-msgid "Serverless|Sign up for First Look"
+msgid "Serverless|Serverless was %{linkStart}deprecated%{linkEnd} in GitLab 14.3."
+msgstr ""
+
+msgid "Serverless|Serverless was %{postLinkStart}deprecated%{postLinkEnd}. But if you opt to use it, you must install Knative in your Kubernetes cluster first. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "Serverless|The deploy job has not finished."
@@ -33134,9 +33832,6 @@ 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 ""
@@ -33152,9 +33847,6 @@ msgstr ""
msgid "Service Account Key"
msgstr ""
-msgid "Service Accounts"
-msgstr ""
-
msgid "Service Accounts keys authorize GitLab to deploy your Google Cloud project"
msgstr ""
@@ -33164,10 +33856,10 @@ msgstr ""
msgid "Service Desk allows people to create issues in your GitLab instance without their own user account. It provides a unique email address for end users to create issues in a project. Replies can be sent either through the GitLab interface or by email. End users only see threads through email."
msgstr ""
-msgid "Service Usage Data"
+msgid "Service account generated successfully"
msgstr ""
-msgid "Service account generated successfully"
+msgid "Service accounts"
msgstr ""
msgid "Service ping is disabled in your configuration file, and cannot be enabled through this form."
@@ -33311,6 +34003,9 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
+msgid "Set the per-user rate limit for getting a user by ID via the API."
+msgstr ""
+
msgid "Set the per-user rate limit for notes created by web or API requests."
msgstr ""
@@ -33492,6 +34187,9 @@ msgstr ""
msgid "Shared runners details"
msgstr ""
+msgid "Shared runners enabled cannot be enabled until a valid credit card is on file"
+msgstr ""
+
msgid "Shared runners help link"
msgstr ""
@@ -33549,6 +34247,9 @@ msgstr ""
msgid "Show all issues."
msgstr ""
+msgid "Show all milestones"
+msgstr ""
+
msgid "Show all test cases."
msgstr ""
@@ -33585,6 +34286,9 @@ msgstr ""
msgid "Show file contents"
msgstr ""
+msgid "Show group milestones"
+msgstr ""
+
msgid "Show labels"
msgstr ""
@@ -33600,6 +34304,12 @@ msgstr ""
msgid "Show open epics"
msgstr ""
+msgid "Show project milestones"
+msgstr ""
+
+msgid "Show sub-group milestones"
+msgstr ""
+
msgid "Show the Closed list"
msgstr ""
@@ -33609,13 +34319,6 @@ msgstr ""
msgid "Show whitespace changes"
msgstr ""
-msgid "Showing %d event"
-msgid_plural "Showing %d events"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-msgstr[3] ""
-
msgid "Showing %{conflict} between %{sourceBranch} and %{targetBranch}"
msgstr ""
@@ -33677,12 +34380,6 @@ msgstr ""
msgid "Sidebar|None"
msgstr ""
-msgid "Sidebar|Only numeral characters allowed"
-msgstr ""
-
-msgid "Sidebar|Weight"
-msgstr ""
-
msgid "Sidekiq job compression threshold (bytes)"
msgstr ""
@@ -33845,6 +34542,9 @@ msgstr ""
msgid "Slack logo"
msgstr ""
+msgid "SlackIntegration|Are you sure you want to remove this project from the Slack application?"
+msgstr ""
+
msgid "SlackIntegration|GitLab for Slack"
msgstr ""
@@ -33854,6 +34554,9 @@ msgstr ""
msgid "SlackIntegration|Project alias"
msgstr ""
+msgid "SlackIntegration|Remove project"
+msgstr ""
+
msgid "SlackIntegration|Select a GitLab project to link with your Slack workspace."
msgstr ""
@@ -33998,9 +34701,6 @@ msgstr ""
msgid "Something went wrong trying to load issue contacts."
msgstr ""
-msgid "Something went wrong when creating a work item. Please try again"
-msgstr ""
-
msgid "Something went wrong when reordering designs. Please try again"
msgstr ""
@@ -34094,9 +34794,6 @@ msgstr ""
msgid "Something went wrong while inserting your image. Please try again."
msgstr ""
-msgid "Something went wrong while merging this merge request. Please try again."
-msgstr ""
-
msgid "Something went wrong while obtaining the Let's Encrypt certificate."
msgstr ""
@@ -34418,10 +35115,10 @@ 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."
+msgid "SourcegraphAdmin|Learn more."
msgstr ""
-msgid "SourcegraphAdmin|More information"
+msgid "SourcegraphAdmin|Only public projects have code intelligence enabled and communicate with Sourcegraph."
msgstr ""
msgid "SourcegraphAdmin|Save changes"
@@ -34430,7 +35127,7 @@ msgstr ""
msgid "SourcegraphAdmin|Sourcegraph URL"
msgstr ""
-msgid "SourcegraphAdmin|e.g. https://sourcegraph.example.com"
+msgid "SourcegraphAdmin|https://sourcegraph.example.com"
msgstr ""
msgid "SourcegraphPreferences|This feature is experimental and currently limited to certain projects."
@@ -34565,6 +35262,9 @@ msgstr ""
msgid "Start date"
msgstr ""
+msgid "Start free trial"
+msgstr ""
+
msgid "Start merge train"
msgstr ""
@@ -34595,6 +35295,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started escalation for this incident."
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -34607,6 +35310,9 @@ msgstr ""
msgid "Starts at (UTC)"
msgstr ""
+msgid "Starts escalations for this incident"
+msgstr ""
+
msgid "Starts on"
msgstr ""
@@ -34868,6 +35574,9 @@ msgstr ""
msgid "Strikethrough"
msgstr ""
+msgid "Strikethrough text"
+msgstr ""
+
msgid "Subgroup information"
msgstr ""
@@ -35102,6 +35811,21 @@ msgstr ""
msgid "Subscriptions"
msgstr ""
+msgid "Subscriptions|Chat with sales"
+msgstr ""
+
+msgid "Subscriptions|Close"
+msgstr ""
+
+msgid "Subscriptions|Not ready to buy yet?"
+msgstr ""
+
+msgid "Subscriptions|Start a free trial"
+msgstr ""
+
+msgid "Subscriptions|We understand. Maybe you have some questions for our sales team, or maybe you'd like to try some of the paid features first. What would you like to do?"
+msgstr ""
+
msgid "Subscription|Your subscription for %{strong}%{namespace_name}%{strong_close} has expired and you are now on %{pricing_link_start}the GitLab Free tier%{pricing_link_end}. Don't worry, your data is safe. Get in touch with our support team (%{support_email}). They'll gladly help with your subscription renewal."
msgstr ""
@@ -35312,6 +36036,9 @@ msgstr ""
msgid "SuperSonics|Maximum users"
msgstr ""
+msgid "SuperSonics|Offline cloud"
+msgstr ""
+
msgid "SuperSonics|Paste your activation code"
msgstr ""
@@ -35378,6 +36105,12 @@ msgstr ""
msgid "SuperSonics|You do not have an active subscription"
msgstr ""
+msgid "SuperSonics|You have a future dated license"
+msgstr ""
+
+msgid "SuperSonics|You have added a license that activates on %{date}. Please see the subscription history table below for more details."
+msgstr ""
+
msgid "SuperSonics|You have successfully added a license that activates on %{date}. Please see the subscription history table below for more details."
msgstr ""
@@ -35537,6 +36270,9 @@ msgstr ""
msgid "Tag name is required"
msgstr ""
+msgid "Tag push"
+msgstr ""
+
msgid "Tag push events"
msgstr ""
@@ -35639,6 +36375,9 @@ msgstr ""
msgid "TagsPage|protected"
msgstr ""
+msgid "Take a look at the documentation to discover all of GitLab’s capabilities."
+msgstr ""
+
msgid "Target Branch"
msgstr ""
@@ -36053,6 +36792,9 @@ msgstr ""
msgid "Tests"
msgstr ""
+msgid "Text (optional)"
+msgstr ""
+
msgid "Text added to the body of all email messages. %{character_limit} character limit"
msgstr ""
@@ -36105,6 +36847,9 @@ msgstr ""
msgid "The CSV export will be created in the background. Once finished, it will be sent to %{email} in an attachment."
msgstr ""
+msgid "The CSV export you requested of all user memberships is attached to this email."
+msgstr ""
+
msgid "The GitLab subscription service (customers.gitlab.com) is currently experiencing an outage. You can monitor the status and get updates at %{linkStart}status.gitlab.com%{linkEnd}."
msgstr ""
@@ -36180,6 +36925,9 @@ 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 epic"
+msgstr ""
+
msgid "The current issue"
msgstr ""
@@ -36343,6 +37091,9 @@ msgstr ""
msgid "The latest pipeline for this merge request has failed."
msgstr ""
+msgid "The license key is invalid."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -36358,6 +37109,9 @@ msgstr ""
msgid "The license was successfully uploaded and will be active from %{starts_at}. You can see the details below."
msgstr ""
+msgid "The license you uploaded is invalid. If the issue persists, contact support at %{link}."
+msgstr ""
+
msgid "The list creation wizard is already open"
msgstr ""
@@ -36979,10 +37733,13 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} and everything this project contains. %{strongOpen}There is no going back%{strongClose}"
+msgstr ""
+
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains."
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}on %{date}%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains. %{strongOpen}There is no going back.%{strongClose}"
msgstr ""
msgid "This action will %{strongOpen}permanently remove%{strongClose} %{codeOpen}%{group}%{codeClose} %{strongOpen}immediately%{strongClose}."
@@ -37111,9 +37868,6 @@ msgstr ""
msgid "This file was modified for readability, and can't accept suggestions. Edit it directly."
msgstr ""
-msgid "This forked project has the following:"
-msgstr ""
-
msgid "This form is disabled in preview"
msgstr ""
@@ -37126,7 +37880,7 @@ msgstr ""
msgid "This group can't be removed because it is linked to a subscription. To remove this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
-msgid "This group can't be transfered because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
+msgid "This group can't be transferred because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
msgid "This group cannot be invited to a project inside a group with enforced SSO"
@@ -37153,6 +37907,9 @@ 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 incident is already escalated with '%{escalation_policy_name}'."
+msgstr ""
+
msgid "This invitation was sent to %{mail_to_invite_email}, but you are signed in as %{link_to_current_user} with email %{mail_to_current_user}."
msgstr ""
@@ -37171,9 +37928,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 merge train pipeline"
-msgstr ""
-
msgid "This is a private email address %{helpIcon} generated just for you. Anyone who has it can create issues or merge requests as if they were you. If that happens, %{resetLinkStart}reset this token%{resetLinkEnd}."
msgstr ""
@@ -37195,6 +37949,12 @@ msgstr ""
msgid "This is your current session"
msgstr ""
+msgid "This issue cannot be assigned to a confidential epic because it is public."
+msgstr ""
+
+msgid "This issue cannot be made public because it belongs to a confidential epic."
+msgstr ""
+
msgid "This issue is confidential and should only be visible to team members with at least Reporter access."
msgstr ""
@@ -37312,6 +38072,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 branch is protected from force push."
+msgstr ""
+
msgid "This merge request cannot be rebased while there are conflicts."
msgstr ""
@@ -37363,9 +38126,15 @@ msgstr ""
msgid "This pipeline was triggered by a schedule."
msgstr ""
+msgid "This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project"
msgstr ""
+msgid "This project can be restored until %{date}."
+msgstr ""
+
msgid "This project cannot be %{visibilityLevel} because the visibility of %{openShowLink}%{name}%{closeShowLink} is %{visibility}. To make this project %{visibilityLevel}, you must first %{openEditLink}change the visibility%{closeEditLink} of the parent group."
msgstr ""
@@ -37384,6 +38153,9 @@ msgstr ""
msgid "This project is %{strongStart}NOT%{strongEnd} a fork, and has the following:"
msgstr ""
+msgid "This project is %{strongStart}NOT%{strongEnd} a fork. This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -38079,6 +38851,9 @@ msgstr ""
msgid "Today"
msgstr ""
+msgid "Todos count"
+msgstr ""
+
msgid "Todos|Are you looking for things to do? Take a look at %{strongStart}%{openIssuesLinkStart}open issues%{openIssuesLinkEnd}%{strongEnd}, contribute to %{strongStart}%{mergeRequestLinkStart}a merge request%{mergeRequestLinkEnd}%{mergeRequestLinkEnd}%{strongEnd}, or mention someone in a comment to automatically assign them a new to-do item."
msgstr ""
@@ -38352,12 +39127,8 @@ msgstr ""
msgid "Trending"
msgstr ""
-msgid "Trials|%{planName} Trial %{enDash} %{num} day left"
-msgid_plural "Trials|%{planName} Trial %{enDash} %{num} days left"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-msgstr[3] ""
+msgid "Trials|%{planName} Trial"
+msgstr ""
msgid "Trials|Compare all plans"
msgstr ""
@@ -38365,6 +39136,9 @@ msgstr ""
msgid "Trials|Create a new group to start your GitLab Ultimate trial."
msgstr ""
+msgid "Trials|Day %{daysUsed}/%{duration}"
+msgstr ""
+
msgid "Trials|Go back to GitLab"
msgstr ""
@@ -38614,7 +39388,7 @@ msgstr ""
msgid "URL is triggered when repository is updated"
msgstr ""
-msgid "URL must be percent-encoded if neccessary."
+msgid "URL must be percent-encoded if necessary."
msgstr ""
msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
@@ -38833,6 +39607,9 @@ msgstr ""
msgid "Unlock account"
msgstr ""
+msgid "Unlock more features with GitLab Ultimate"
+msgstr ""
+
msgid "Unlock the discussion"
msgstr ""
@@ -38896,6 +39673,9 @@ msgstr ""
msgid "Unsubscribes from this %{quick_action_target}."
msgstr ""
+msgid "Unsupported sort value."
+msgstr ""
+
msgid "Unsupported todo type passed. Supported todo types are: %{todo_types}"
msgstr ""
@@ -39124,6 +39904,9 @@ msgstr ""
msgid "UsageQuota|File attachments and smaller design graphics."
msgstr ""
+msgid "UsageQuota|From %{storage_enforcement_date} storage limits will apply to this namespace. View and manage your usage in %{strong_start}Group Settings &gt; Usage quotas%{strong_end}."
+msgstr ""
+
msgid "UsageQuota|Git repository."
msgstr ""
@@ -39184,6 +39967,9 @@ msgstr ""
msgid "UsageQuota|Storage type"
msgstr ""
+msgid "UsageQuota|Storage used"
+msgstr ""
+
msgid "UsageQuota|This is the total amount of storage used across your projects within this namespace."
msgstr ""
@@ -39379,6 +40165,12 @@ msgstr ""
msgid "Use hashed storage paths for newly created and renamed repositories. Always enabled since 13.0."
msgstr ""
+msgid "Use issue count"
+msgstr ""
+
+msgid "Use issue weight"
+msgstr ""
+
msgid "Use one line per URI"
msgstr ""
@@ -39760,6 +40552,9 @@ msgstr ""
msgid "Users"
msgstr ""
+msgid "Users API rate limit"
+msgstr ""
+
msgid "Users can launch a development environment from a GitLab browser tab when the %{linkStart}Gitpod%{linkEnd} integration is enabled."
msgstr ""
@@ -40089,6 +40884,9 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View group pipeline usage quota"
+msgstr ""
+
msgid "View incident details at"
msgstr ""
@@ -40243,6 +41041,9 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
+msgid "Vulnerability"
+msgstr ""
+
msgid "Vulnerability Report"
msgstr ""
@@ -40294,6 +41095,9 @@ msgstr ""
msgid "VulnerabilityManagement|An unverified non-confirmed finding"
msgstr ""
+msgid "VulnerabilityManagement|At least one identifier is required"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -40303,12 +41107,24 @@ msgstr ""
msgid "VulnerabilityManagement|Create Jira issue"
msgstr ""
+msgid "VulnerabilityManagement|Enter a name"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE code"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE identifier URL"
+msgstr ""
+
msgid "VulnerabilityManagement|Fetching linked Jira issues"
msgstr ""
msgid "VulnerabilityManagement|Manually add a vulnerability entry into the vulnerability report."
msgstr ""
+msgid "VulnerabilityManagement|Name is a required field"
+msgstr ""
+
msgid "VulnerabilityManagement|Needs triage"
msgstr ""
@@ -40324,6 +41140,18 @@ msgstr ""
msgid "VulnerabilityManagement|Select a method"
msgstr ""
+msgid "VulnerabilityManagement|Select a severity level"
+msgstr ""
+
+msgid "VulnerabilityManagement|Select a status"
+msgstr ""
+
+msgid "VulnerabilityManagement|Severity is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Something went wrong while creating vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -40348,6 +41176,12 @@ msgstr ""
msgid "VulnerabilityManagement|Something went wrong, could not update vulnerability state."
msgstr ""
+msgid "VulnerabilityManagement|Status is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Submit vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Summary, detailed description, steps to reproduce, etc."
msgstr ""
@@ -40543,6 +41377,9 @@ msgstr ""
msgid "WARNING:"
msgstr ""
+msgid "WARNING: This snippet contains hidden files which might be used to mask malicious behavior. Exercise caution if cloning and executing code from this snippet."
+msgstr ""
+
msgid "Wait for the file to load to copy its contents"
msgstr ""
@@ -40762,6 +41599,15 @@ msgstr ""
msgid "Webhooks|An issue is created, updated, closed, or reopened."
msgstr ""
+msgid "Webhooks|Are you sure you want to delete this group hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this project hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this webhook?"
+msgstr ""
+
msgid "Webhooks|Comments"
msgstr ""
@@ -40771,6 +41617,9 @@ msgstr ""
msgid "Webhooks|Confidential issues events"
msgstr ""
+msgid "Webhooks|Delete webhook"
+msgstr ""
+
msgid "Webhooks|Deployment events"
msgstr ""
@@ -41006,6 +41855,9 @@ msgstr ""
msgid "Wiki"
msgstr ""
+msgid "Wiki page"
+msgstr ""
+
msgid "Wiki page was successfully created."
msgstr ""
@@ -41111,7 +41963,7 @@ msgstr ""
msgid "WikiPageConflictMessage|Someone edited the page the same time you did. Please check out %{wikiLinkStart}the page%{wikiLinkEnd} and make sure your changes will not unintentionally remove theirs."
msgstr ""
-msgid "WikiPage|An error occured while trying to render the content editor. Please try again later."
+msgid "WikiPage|An error occurred while trying to render the content editor. Please try again later."
msgstr ""
msgid "WikiPage|Are you sure you want to switch back to the classic editor?"
@@ -41270,6 +42122,18 @@ msgstr ""
msgid "WorkItem|New Task"
msgstr ""
+msgid "WorkItem|Something went wrong when creating a work item. Please try again"
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching the work item. Please try again."
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching work item types. Please try again"
+msgstr ""
+
+msgid "WorkItem|Type"
+msgstr ""
+
msgid "WorkItem|Work Items"
msgstr ""
@@ -41336,7 +42200,10 @@ msgstr ""
msgid "You are about to add %{usersTag} people to the discussion. They will all receive a notification."
msgstr ""
-msgid "You are about to permanently delete this project"
+msgid "You are about to delete this forked project containing:"
+msgstr ""
+
+msgid "You are about to delete this project containing:"
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."
@@ -41357,6 +42224,9 @@ msgstr ""
msgid "You are attempting to update a file that has changed since you started editing it."
msgstr ""
+msgid "You are billed if you exceed this number. %{qsrOverageLinkStart}How does billing work?%{qsrOverageLinkEnd}"
+msgstr ""
+
msgid "You are connected to the Prometheus server, but there is currently no data to display."
msgstr ""
@@ -41414,6 +42284,9 @@ msgstr ""
msgid "You are not authorized to update this scanner profile"
msgstr ""
+msgid "You are not authorized to upload metric images"
+msgstr ""
+
msgid "You are now impersonating %{username}"
msgstr ""
@@ -41567,9 +42440,6 @@ msgstr ""
msgid "You can only upload one design when dropping onto an existing design."
msgstr ""
-msgid "You can recover this project until %{date}"
-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 ""
@@ -41618,9 +42488,6 @@ msgstr ""
msgid "You cannot write to this read-only GitLab instance."
msgstr ""
-msgid "You can’t %{tag_start}edit%{tag_end} files directly in this project. Fork this project and submit a merge request with your changes."
-msgstr ""
-
msgid "You can’t edit files directly in this project. Fork this project and submit a merge request with your changes."
msgstr ""
@@ -41775,9 +42642,6 @@ 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 set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
@@ -41808,12 +42672,6 @@ msgstr ""
msgid "You must have maintainer access to force delete a lock"
msgstr ""
-msgid "You must have permission to create a project in a group before forking."
-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 ""
@@ -42219,7 +43077,7 @@ msgstr ""
msgid "Your public email will be displayed on your public profile."
msgstr ""
-msgid "Your request for access could not be processed: %{error_meesage}"
+msgid "Your request for access could not be processed: %{error_message}"
msgstr ""
msgid "Your request for access has been queued for review."
@@ -42408,6 +43266,9 @@ msgstr ""
msgid "archived:"
msgstr ""
+msgid "artifacts"
+msgstr ""
+
msgid "assign yourself"
msgstr ""
@@ -42439,6 +43300,9 @@ msgstr[3] ""
msgid "branch name"
msgstr ""
+msgid "builds"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -42868,6 +43732,9 @@ msgstr ""
msgid "contact with same email already exists in group hierarchy"
msgstr ""
+msgid "container registry images"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -42907,6 +43774,9 @@ msgstr ""
msgid "data"
msgstr ""
+msgid "database"
+msgstr ""
+
msgid "date must not be after 9999-12-31"
msgstr ""
@@ -42932,9 +43802,6 @@ msgstr ""
msgid "design"
msgstr ""
-msgid "detached"
-msgstr ""
-
msgid "disabled"
msgstr ""
@@ -43191,7 +44058,7 @@ msgstr ""
msgid "is not a valid X509 certificate."
msgstr ""
-msgid "is not allowed for sign-up."
+msgid "is not allowed for sign-up. Please use your regular email address."
msgstr ""
msgid "is not allowed for this group."
@@ -43203,7 +44070,7 @@ msgstr ""
msgid "is not allowed since the group is not top-level group."
msgstr ""
-msgid "is not allowed."
+msgid "is not allowed. Please use your regular email address."
msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
@@ -43290,6 +44157,9 @@ msgstr ""
msgid "level: %{level}"
msgstr ""
+msgid "lfs objects"
+msgstr ""
+
msgid "limit of %{project_limit} reached"
msgstr ""
@@ -43515,6 +44385,9 @@ msgstr ""
msgid "mrWidget|Merge blocked: pipeline must succeed. It's waiting for a manual action to continue."
msgstr ""
+msgid "mrWidget|Merge blocked: pipeline must succeed. Push a commit that fixes the failure, or %{linkStart}learn about other solutions.%{linkEnd}"
+msgstr ""
+
msgid "mrWidget|Merge blocked: this merge request must be approved."
msgstr ""
@@ -43632,9 +44505,6 @@ msgstr ""
msgid "mrWidget|The changes were not merged into"
msgstr ""
-msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -43782,9 +44652,6 @@ msgstr ""
msgid "open issue"
msgstr ""
-msgid "opened %{timeAgo}"
-msgstr ""
-
msgid "or"
msgstr ""
@@ -43798,6 +44665,12 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "packages"
+msgstr ""
+
+msgid "pages"
+msgstr ""
+
msgid "parent"
msgid_plural "parents"
msgstr[0] ""
@@ -43955,6 +44828,9 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "repositories"
+msgstr ""
+
msgid "repository:"
msgstr ""
@@ -44075,12 +44951,18 @@ msgstr ""
msgid "tag name"
msgstr ""
+msgid "terraform states"
+msgstr ""
+
msgid "the correct format."
msgstr ""
msgid "the file"
msgstr ""
+msgid "the following epic(s)"
+msgstr ""
+
msgid "the following issue(s)"
msgstr ""
@@ -44093,21 +44975,12 @@ msgstr ""
msgid "this document"
msgstr ""
-msgid "this issue cannot be assigned to a confidential epic since it is public"
-msgstr ""
-
-msgid "this issue cannot be made public since it belongs to a confidential epic"
-msgstr ""
-
msgid "time summary"
msgstr ""
msgid "toggle collapse"
msgstr ""
-msgid "train"
-msgstr ""
-
msgid "triggered"
msgstr ""
@@ -44238,3 +45111,6 @@ msgstr ""
msgid "{project}"
msgstr ""
+msgid "✔"
+msgstr ""
+
diff --git a/locale/hi_IN/gitlab.po b/locale/hi_IN/gitlab.po
index f0c42e611c1..9d897c2447e 100644
--- a/locale/hi_IN/gitlab.po
+++ b/locale/hi_IN/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: hi\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2022-02-02 15:44\n"
+"PO-Revision-Date: 2022-03-01 20:38\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -146,6 +146,11 @@ msgid_plural "%d approvers (you've approved)"
msgstr[0] ""
msgstr[1] ""
+msgid "%d assigned issue"
+msgid_plural "%d assigned issues"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -421,8 +426,23 @@ msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
msgstr[1] ""
-msgid "%d vulnerability updated"
-msgid_plural "%d vulnerabilities updated"
+msgid "%d vulnerability set to confirmed"
+msgid_plural "%d vulnerabilities set to confirmed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to dismissed"
+msgid_plural "%d vulnerabilities set to dismissed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to needs triage"
+msgid_plural "%d vulnerabilities set to needs triage"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to resolved"
+msgid_plural "%d vulnerabilities set to resolved"
msgstr[0] ""
msgstr[1] ""
@@ -510,6 +530,12 @@ msgstr[1] ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{completed} of %{total} issues closed"
+msgstr ""
+
+msgid "%{completed} of %{total} weight completed"
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -858,6 +884,9 @@ msgstr ""
msgid "%{openedIssues} open, %{closedIssues} closed"
msgstr ""
+msgid "%{percentage}%% issues closed"
+msgstr ""
+
msgid "%{percentage}%% weight completed"
msgstr ""
@@ -1287,6 +1316,9 @@ msgid_plural "- Users"
msgstr[0] ""
msgstr[1] ""
+msgid "- of - issues closed"
+msgstr ""
+
msgid "- of - weight completed"
msgstr ""
@@ -1429,7 +1461,7 @@ msgstr ""
msgid "1000+"
msgstr ""
-msgid "192.168.0.0/24"
+msgid "192.168.0.0/24 or 2001:0DB8:1234::/48"
msgstr ""
msgid "1st contribution!"
@@ -1741,13 +1773,13 @@ msgstr ""
msgid "AWS Access Key"
msgstr ""
-msgid "AWS Access Key. Only required if not using role instance credentials"
+msgid "AWS Secret Access Key"
msgstr ""
-msgid "AWS Secret Access Key"
+msgid "AWS access key ID (Optional)"
msgstr ""
-msgid "AWS Secret Access Key. Only required if not using role instance credentials"
+msgid "AWS secret access key (Optional)"
msgstr ""
msgid "AWS service error: %{error}"
@@ -1807,9 +1839,6 @@ msgstr ""
msgid "Access granted"
msgstr ""
-msgid "Access key ID"
-msgstr ""
-
msgid "Access requests"
msgstr ""
@@ -1984,7 +2013,7 @@ msgstr ""
msgid "Activity"
msgstr ""
-msgid "Activity|An error occured while retrieving activity. Reload the page to try again."
+msgid "Activity|An error occurred while retrieving activity. Reload the page to try again."
msgstr ""
msgid "Add"
@@ -2023,6 +2052,9 @@ msgstr ""
msgid "Add a %{type}"
msgstr ""
+msgid "Add a GCP region"
+msgstr ""
+
msgid "Add a GPG key"
msgstr ""
@@ -2074,6 +2106,9 @@ msgstr ""
msgid "Add a numbered list"
msgstr ""
+msgid "Add a related epic"
+msgstr ""
+
msgid "Add a related issue"
msgstr ""
@@ -2188,6 +2223,9 @@ msgstr ""
msgid "Add or subtract spent time"
msgstr ""
+msgid "Add people"
+msgstr ""
+
msgid "Add previously merged commits"
msgstr ""
@@ -2254,6 +2292,9 @@ msgstr ""
msgid "Add webhook"
msgstr ""
+msgid "Add your team members and others to GitLab."
+msgstr ""
+
msgid "Add/remove"
msgstr ""
@@ -3076,12 +3117,6 @@ msgstr ""
msgid "AdvancedSearch|Reindex required"
msgstr ""
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. Permanently deleting this project will %{strongStart}immediately delete%{strongEnd} its repositories and %{strongStart}all related resources%{strongEnd}, including issues, merge requests etc."
-msgstr ""
-
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. You will lose this project's repository and %{strongStart}all related resources%{strongEnd}, including issues and merge requests."
-msgstr ""
-
msgid "After a successful password update you will be redirected to login screen."
msgstr ""
@@ -3112,6 +3147,9 @@ msgstr ""
msgid "Akismet helps prevent the creation of spam issues in public projects."
msgstr ""
+msgid "Alert"
+msgstr ""
+
msgid "AlertManagement|Acknowledged"
msgstr ""
@@ -3484,9 +3522,6 @@ msgstr ""
msgid "All environments"
msgstr ""
-msgid "All epics"
-msgstr ""
-
msgid "All groups and projects"
msgstr ""
@@ -4223,12 +4258,15 @@ msgstr ""
msgid "ApplicationSettings|Approve users in the pending approval status?"
msgstr ""
-msgid "ApplicationSettings|By making this change, you will automatically approve %d user with the pending approval status."
-msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users with the pending approval status."
+msgid "ApplicationSettings|Approve users who are pending approval?"
+msgstr ""
+
+msgid "ApplicationSettings|By making this change, you will automatically approve %d user who is pending approval."
+msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users who are pending approval."
msgstr[0] ""
msgstr[1] ""
-msgid "ApplicationSettings|By making this change, you will automatically approve all users in pending approval status."
+msgid "ApplicationSettings|By making this change, you will automatically approve all users who are pending approval."
msgstr ""
msgid "ApplicationSettings|Denied domains for sign-ups"
@@ -4634,10 +4672,10 @@ msgstr ""
msgid "Archiving the project will make it entirely read-only. It is hidden from the dashboard and doesn't show up in searches. %{strong_start}The repository cannot be committed to, and no issues, comments, or other entities can be created.%{strong_end} %{link_start}Learn more.%{link_end}"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to delete this project?"
+msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
+msgid "Are you absolutely sure?"
msgstr ""
msgid "Are you sure that you want to archive this project?"
@@ -4673,12 +4711,18 @@ msgstr ""
msgid "Are you sure you want to delete this SSH key?"
msgstr ""
+msgid "Are you sure you want to delete this comment?"
+msgstr ""
+
msgid "Are you sure you want to delete this deploy key?"
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 label?"
+msgstr ""
+
msgid "Are you sure you want to delete this pipeline schedule?"
msgstr ""
@@ -4694,9 +4738,6 @@ msgstr ""
msgid "Are you sure you want to discard your changes?"
msgstr ""
-msgid "Are you sure you want to erase this build?"
-msgstr ""
-
msgid "Are you sure you want to import %d repository?"
msgid_plural "Are you sure you want to import %d repositories?"
msgstr[0] ""
@@ -4744,6 +4785,9 @@ msgstr ""
msgid "Are you sure you want to remove this list?"
msgstr ""
+msgid "Are you sure you want to remove this nickname?"
+msgstr ""
+
msgid "Are you sure you want to reset the health check token?"
msgstr ""
@@ -4756,10 +4800,10 @@ 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?"
+msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
msgstr ""
-msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
+msgid "Are you sure you want to revoke this project access token? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to stop this environment?"
@@ -4906,9 +4950,6 @@ msgstr ""
msgid "Assigned to %{assignee_name}"
msgstr ""
-msgid "Assigned to %{name}"
-msgstr ""
-
msgid "Assigned to me"
msgstr ""
@@ -4973,6 +5014,9 @@ msgstr[1] ""
msgid "Attaching the file failed."
msgstr ""
+msgid "Attention"
+msgstr ""
+
msgid "Audit Events"
msgstr ""
@@ -5135,6 +5179,12 @@ msgstr ""
msgid "Authorized applications (%{size})"
msgstr ""
+msgid "AuthorizedApplication|Are you sure you want to revoke this application?"
+msgstr ""
+
+msgid "AuthorizedApplication|Revoke application"
+msgstr ""
+
msgid "Authors: %{authors}"
msgstr ""
@@ -6328,6 +6378,9 @@ msgstr ""
msgid "CICDAnalytics|Shared Runners Usage"
msgstr ""
+msgid "CICDAnalytics|Shared runner pipeline minute duration by month"
+msgstr ""
+
msgid "CICDAnalytics|Shared runner usage"
msgstr ""
@@ -6469,6 +6522,9 @@ msgstr ""
msgid "Can create groups:"
msgstr ""
+msgid "Can not delete primary training"
+msgstr ""
+
msgid "Can't apply as the source branch was deleted."
msgstr ""
@@ -6802,9 +6858,6 @@ msgstr ""
msgid "Changing any setting here requires an application restart"
msgstr ""
-msgid "Changing group URL can have unintended side effects."
-msgstr ""
-
msgid "Charts can't be displayed as the request for data has timed out. %{documentationLink}"
msgstr ""
@@ -6892,9 +6945,6 @@ msgstr ""
msgid "Checking branch availability..."
msgstr ""
-msgid "Checking group URL availability..."
-msgstr ""
-
msgid "Checking group path availability..."
msgstr ""
@@ -7388,6 +7438,9 @@ msgstr ""
msgid "Clear recent searches"
msgstr ""
+msgid "Clear repository checks"
+msgstr ""
+
msgid "Clear search"
msgstr ""
@@ -7520,9 +7573,6 @@ msgstr ""
msgid "Closed MRs"
msgstr ""
-msgid "Closed epics"
-msgstr ""
-
msgid "Closed issues"
msgstr ""
@@ -7559,13 +7609,13 @@ msgstr ""
msgid "Cluster level"
msgstr ""
-msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
+msgid "Cluster type must be specified for Stages::ClusterEndpointInserter"
msgstr ""
msgid "ClusterAgents|%{name} successfully deleted"
msgstr ""
-msgid "ClusterAgents|%{number} of %{total} Agents"
+msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
@@ -7607,6 +7657,15 @@ msgstr ""
msgid "ClusterAgents|Agent never connected to GitLab"
msgstr ""
+msgid "ClusterAgents|Agent version mismatch"
+msgstr ""
+
+msgid "ClusterAgents|Agent version mismatch and update"
+msgstr ""
+
+msgid "ClusterAgents|Agent version update required"
+msgstr ""
+
msgid "ClusterAgents|All"
msgstr ""
@@ -7631,7 +7690,7 @@ msgstr ""
msgid "ClusterAgents|Configuration"
msgstr ""
-msgid "ClusterAgents|Connect a cluster through the Agent"
+msgid "ClusterAgents|Connect a cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connect existing cluster"
@@ -7640,13 +7699,13 @@ msgstr ""
msgid "ClusterAgents|Connect with a certificate"
msgstr ""
-msgid "ClusterAgents|Connect with agent"
+msgid "ClusterAgents|Connect with an agent"
msgstr ""
msgid "ClusterAgents|Connect with the GitLab Agent"
msgstr ""
-msgid "ClusterAgents|Connect your cluster through the Agent"
+msgid "ClusterAgents|Connect your cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connected"
@@ -7706,7 +7765,10 @@ msgstr ""
msgid "ClusterAgents|How to register an agent?"
msgstr ""
-msgid "ClusterAgents|Install new Agent"
+msgid "ClusterAgents|How to update an agent?"
+msgstr ""
+
+msgid "ClusterAgents|Install a new agent"
msgstr ""
msgid "ClusterAgents|Last connected %{timeAgo}."
@@ -7733,7 +7795,7 @@ msgstr ""
msgid "ClusterAgents|Never connected"
msgstr ""
-msgid "ClusterAgents|No Agents"
+msgid "ClusterAgents|No agents"
msgstr ""
msgid "ClusterAgents|No clusters connected through cluster certificates"
@@ -7793,6 +7855,9 @@ msgstr ""
msgid "ClusterAgents|The agent has not been connected in a long time. There might be a connectivity issue. Last contact was %{timeAgo}."
msgstr ""
+msgid "ClusterAgents|The agent version do not match each other across your cluster's pods. This can happen when a new agent version was just deployed and Kubernetes is shutting down the old pods."
+msgstr ""
+
msgid "ClusterAgents|The recommended installation method includes the token. If you want to follow the advanced installation method provided in the docs, make sure you save the token value before you close this window."
msgstr ""
@@ -7840,6 +7905,9 @@ msgstr ""
msgid "ClusterAgents|You will need to create a token to connect to your agent"
msgstr ""
+msgid "ClusterAgents|Your agent version is out of sync with your GitLab version (v%{version}), which might cause compatibility problems. Update the agent installed on your cluster to the most recent version."
+msgstr ""
+
msgid "ClusterAgents|Your instance doesn't have the %{linkStart}GitLab Agent Server (KAS)%{linkEnd} set up. Ask a GitLab Administrator to install it."
msgstr ""
@@ -8716,9 +8784,6 @@ msgstr ""
msgid "Comma-separated list of email addresses."
msgstr ""
-msgid "Comma-separated list of users allowed to exceed the rate limit."
-msgstr ""
-
msgid "Comma-separated, e.g. '1.1.1.1, 2.2.2.0/24'"
msgstr ""
@@ -9045,6 +9110,12 @@ msgstr ""
msgid "Confidential"
msgstr ""
+msgid "Confidential issue"
+msgstr ""
+
+msgid "Confidential note"
+msgstr ""
+
msgid "Confidentiality"
msgstr ""
@@ -9078,6 +9149,9 @@ msgstr ""
msgid "Configure Dependency Scanning in `.gitlab-ci.yml`, creating this file if it does not already exist"
msgstr ""
+msgid "Configure GitLab"
+msgstr ""
+
msgid "Configure GitLab runners to start using the Web Terminal. %{helpStart}Learn more.%{helpEnd}"
msgstr ""
@@ -9126,6 +9200,15 @@ msgstr ""
msgid "Configure pipelines to deploy web apps, backend services, APIs and static resources to Google Cloud"
msgstr ""
+msgid "Configure region"
+msgstr ""
+
+msgid "Configure region for environment"
+msgstr ""
+
+msgid "Configure regions"
+msgstr ""
+
msgid "Configure repository mirroring."
msgstr ""
@@ -9159,6 +9242,9 @@ msgstr ""
msgid "Configure which lists are shown for anyone who visits this board"
msgstr ""
+msgid "Configure your environments to be deployed to specific geographical regions"
+msgstr ""
+
msgid "Confirm"
msgstr ""
@@ -9861,10 +9947,10 @@ msgstr ""
msgid "CorpusManagement|Actions"
msgstr ""
-msgid "CorpusManagement|Corpus are used in fuzz testing as mutation source to Improve future testing."
+msgid "CorpusManagement|Corpus file"
msgstr ""
-msgid "CorpusManagement|Corpus file"
+msgid "CorpusManagement|Corpus files are used in coverage-guided fuzz testing as seed inputs to improve testing."
msgstr ""
msgid "CorpusManagement|Corpus files must be in *.zip format. Maximum 5 GB"
@@ -9918,6 +10004,9 @@ msgstr ""
msgid "Could not apply %{name} command."
msgstr ""
+msgid "Could not apply %{name} command. %{message}."
+msgstr ""
+
msgid "Could not authorize chat nickname. Try again!"
msgstr ""
@@ -10068,6 +10157,9 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
+msgid "Create a group"
+msgstr ""
+
msgid "Create a merge request"
msgstr ""
@@ -10092,6 +10184,9 @@ msgstr ""
msgid "Create a personal access token on your account to pull or push via %{protocol}."
msgstr ""
+msgid "Create a project"
+msgstr ""
+
msgid "Create an account using:"
msgstr ""
@@ -10455,6 +10550,9 @@ msgstr ""
msgid "Creation date"
msgstr ""
+msgid "Creator"
+msgstr ""
+
msgid "Credentials"
msgstr ""
@@ -10467,9 +10565,15 @@ msgstr ""
msgid "CredentialsInventory|Personal Access Tokens"
msgstr ""
+msgid "CredentialsInventory|Project Access Tokens"
+msgstr ""
+
msgid "CredentialsInventory|SSH Keys"
msgstr ""
+msgid "Credit card required to be on file in order to create a pipeline"
+msgstr ""
+
msgid "Credit card:"
msgstr ""
@@ -10653,9 +10757,6 @@ msgstr ""
msgid "Customer relations"
msgstr ""
-msgid "Customizable by an administrator."
-msgstr ""
-
msgid "Customizable by owners."
msgstr ""
@@ -10785,30 +10886,18 @@ msgstr ""
msgid "CycleAnalytics|%{selectedLabelsCount} selected (%{maxLabels} max)"
msgstr ""
-msgid "CycleAnalytics|%{stageCount} stages selected"
-msgstr ""
-
-msgid "CycleAnalytics|All stages"
-msgstr ""
-
-msgid "CycleAnalytics|Average days to completion"
+msgid "CycleAnalytics|Average time to completion"
msgstr ""
msgid "CycleAnalytics|Date"
msgstr ""
-msgid "CycleAnalytics|Days to completion"
-msgstr ""
-
msgid "CycleAnalytics|Display chart filters"
msgstr ""
msgid "CycleAnalytics|Lead Time for Changes"
msgstr ""
-msgid "CycleAnalytics|No stages selected"
-msgstr ""
-
msgid "CycleAnalytics|Number of tasks"
msgstr ""
@@ -10837,18 +10926,30 @@ msgstr ""
msgid "CycleAnalytics|Showing data for group '%{groupName}' from %{createdAfter} to %{createdBefore}"
msgstr ""
-msgid "CycleAnalytics|Stages"
+msgid "CycleAnalytics|Stage time: %{title}"
msgstr ""
msgid "CycleAnalytics|Tasks by type"
msgstr ""
-msgid "CycleAnalytics|The average time spent in the selected stage for the items that were completed on each date. Data limited to the last 500 items."
+msgid "CycleAnalytics|The average time items spent in this stage. Data limited to items completed within this date range."
msgstr ""
msgid "CycleAnalytics|The given date range is larger than 180 days"
msgstr ""
+msgid "CycleAnalytics|The total time items spent across each value stream stage. Data limited to items completed within this date range."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Stage time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Total time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|Total time"
+msgstr ""
+
msgid "CycleAnalytics|Type of work"
msgstr ""
@@ -10861,9 +10962,6 @@ msgstr ""
msgid "CycleAnalytics|project dropdown filter"
msgstr ""
-msgid "CycleAnalytics|stage dropdown"
-msgstr ""
-
msgid "DAG visualization requires at least 3 dependent jobs."
msgstr ""
@@ -10963,10 +11061,16 @@ msgstr ""
msgid "DastProfiles|AJAX spider"
msgstr ""
+msgid "DastProfiles|API"
+msgstr ""
+
+msgid "DastProfiles|API endpoint URL"
+msgstr ""
+
msgid "DastProfiles|Active"
msgstr ""
-msgid "DastProfiles|Additional request headers (Optional)"
+msgid "DastProfiles|Additional request headers (optional)"
msgstr ""
msgid "DastProfiles|Are you sure you want to delete this profile?"
@@ -10981,6 +11085,9 @@ msgstr ""
msgid "DastProfiles|Branch missing"
msgstr ""
+msgid "DastProfiles|Choose a scan method"
+msgstr ""
+
msgid "DastProfiles|Could not create the scanner profile. Please try again."
msgstr ""
@@ -11050,7 +11157,13 @@ msgstr ""
msgid "DastProfiles|Excluded URLs"
msgstr ""
-msgid "DastProfiles|Excluded URLs (Optional)"
+msgid "DastProfiles|Excluded URLs (optional)"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths (optional)"
msgstr ""
msgid "DastProfiles|Hide debug messages"
@@ -11107,9 +11220,6 @@ msgstr ""
msgid "DastProfiles|Request headers"
msgstr ""
-msgid "DastProfiles|Rest API"
-msgstr ""
-
msgid "DastProfiles|Run the AJAX spider, in addition to the traditional spider, to crawl the target site."
msgstr ""
@@ -11119,6 +11229,9 @@ msgstr ""
msgid "DastProfiles|Save profile"
msgstr ""
+msgid "DastProfiles|Scan method"
+msgstr ""
+
msgid "DastProfiles|Scan mode"
msgstr ""
@@ -11197,12 +11310,24 @@ msgstr ""
msgid "DastProfiles|Website"
msgstr ""
+msgid "DastProfiles|What does each method do?"
+msgstr ""
+
msgid "DastProfiles|You can either choose a passive scan or validate the target site from the site profile management page. %{docsLinkStart}Learn more about site validation.%{docsLinkEnd}"
msgstr ""
msgid "DastProfiles|You cannot run an active scan against an unvalidated site."
msgstr ""
+msgid "DastProfiles|folder/dast_example.har or https://example.com/dast_example.har"
+msgstr ""
+
+msgid "DastProfiles|folder/example.postman_collection.json or https://example.com/"
+msgstr ""
+
+msgid "DastProfiles|folder/openapi.json or https://example.com/openapi.json"
+msgstr ""
+
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
@@ -11310,6 +11435,9 @@ msgstr ""
msgid "DatadogIntegration|API URL"
msgstr ""
+msgid "DatadogIntegration|Custom tags in Datadog. Enter one tag per line in the %{codeOpen}key:value%{codeClose} format. %{linkOpen}How do I use tags?%{linkClose}"
+msgstr ""
+
msgid "DatadogIntegration|Environment"
msgstr ""
@@ -11328,12 +11456,18 @@ msgstr ""
msgid "DatadogIntegration|Tag all data from this GitLab instance in Datadog. Useful when managing several self-managed deployments."
msgstr ""
+msgid "DatadogIntegration|Tags"
+msgstr ""
+
msgid "DatadogIntegration|The Datadog site to send data to. To send data to the EU site, use %{codeOpen}datadoghq.eu%{codeClose}."
msgstr ""
msgid "DatadogIntegration|Trace your GitLab pipelines with Datadog."
msgstr ""
+msgid "DatadogIntegration|have an invalid format"
+msgstr ""
+
msgid "Datasource name not found"
msgstr ""
@@ -11343,9 +11477,6 @@ msgstr ""
msgid "Date merged"
msgstr ""
-msgid "Date picker"
-msgstr ""
-
msgid "Date range"
msgstr ""
@@ -11499,9 +11630,6 @@ msgstr ""
msgid "Definition"
msgstr ""
-msgid "Delayed Project Deletion (%{adjourned_deletion})"
-msgstr ""
-
msgid "DelayedJobs|Are you sure you want to run %{jobName} immediately? Otherwise this job will run automatically after its timer finishes."
msgstr ""
@@ -11580,10 +11708,10 @@ msgstr ""
msgid "Delete pipeline"
msgstr ""
-msgid "Delete project"
+msgid "Delete pipeline schedule"
msgstr ""
-msgid "Delete project. Are you ABSOLUTELY SURE?"
+msgid "Delete project"
msgstr ""
msgid "Delete row"
@@ -11613,6 +11741,9 @@ msgstr ""
msgid "Delete this epic and all descendants?"
msgstr ""
+msgid "Delete this project"
+msgstr ""
+
msgid "Delete user list"
msgstr ""
@@ -11871,6 +12002,12 @@ msgstr ""
msgid "Deploy to..."
msgstr ""
+msgid "DeployBoards|To see deployment progress for your environments, make sure you are deploying to %{codeStart}$KUBE_NAMESPACE%{codeEnd} and annotating with %{codeStart}app.gitlab.com/app=$CI_PROJECT_PATH_SLUG%{codeEnd} and %{codeStart}app.gitlab.com/env=$CI_ENVIRONMENT_SLUG%{codeEnd}."
+msgstr ""
+
+msgid "DeployBoard|Kubernetes Pods"
+msgstr ""
+
msgid "DeployFreeze|Add a freeze period to prevent unintended releases during a period of time for a given environment. You must update the deployment jobs in %{filename} according to the deploy freezes added here. %{freeze_period_link_start}Learn more.%{freeze_period_link_end}"
msgstr ""
@@ -11955,9 +12092,6 @@ msgstr ""
msgid "DeployTokens|Active Deploy Tokens (%{active_tokens})"
msgstr ""
-msgid "DeployTokens|Allows read and write access to registry images."
-msgstr ""
-
msgid "DeployTokens|Allows read and write access to the package registry."
msgstr ""
@@ -11970,6 +12104,9 @@ msgstr ""
msgid "DeployTokens|Allows read-only access to the repository."
msgstr ""
+msgid "DeployTokens|Allows write access to registry images."
+msgstr ""
+
msgid "DeployTokens|Copy deploy token"
msgstr ""
@@ -12063,12 +12200,57 @@ msgstr ""
msgid "Deploying to AWS is easy with GitLab"
msgstr ""
+msgid "Deployment"
+msgstr ""
+
msgid "Deployment Frequency"
msgstr ""
+msgid "Deployment Target|Project deployment target (optional)"
+msgstr ""
+
+msgid "Deployment Target|Select the deployment target"
+msgstr ""
+
msgid "Deployment frequency"
msgstr ""
+msgid "DeploymentTarget|GitLab Pages"
+msgstr ""
+
+msgid "DeploymentTarget|Heroku"
+msgstr ""
+
+msgid "DeploymentTarget|Infrastructure provider (Terraform, Cloudformation, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Kubernetes (GKE, EKS, OpenShift, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Managed container runtime (Fargate, Cloud Run, DigitalOcean App)"
+msgstr ""
+
+msgid "DeploymentTarget|Mobile app store"
+msgstr ""
+
+msgid "DeploymentTarget|No deployment planned"
+msgstr ""
+
+msgid "DeploymentTarget|Other hosting service"
+msgstr ""
+
+msgid "DeploymentTarget|Registry (package or container)"
+msgstr ""
+
+msgid "DeploymentTarget|Self-managed container runtime (Podman, Docker Swarm, Docker Compose)"
+msgstr ""
+
+msgid "DeploymentTarget|Serverless backend (Lambda, Cloud functions)"
+msgstr ""
+
+msgid "DeploymentTarget|Virtual machine (for example, EC2)"
+msgstr ""
+
msgid "Deployments"
msgstr ""
@@ -12107,6 +12289,9 @@ msgstr ""
msgid "Deployment|This deployment was created using the API"
msgstr ""
+msgid "Deployment|Triggerer"
+msgstr ""
+
msgid "Deployment|Waiting"
msgstr ""
@@ -12134,6 +12319,18 @@ msgstr ""
msgid "Deprecated API rate limits"
msgstr ""
+msgid "Deprecations|Feature deprecation and removal"
+msgstr ""
+
+msgid "Deprecations|For information on a possible replacement %{epicStart} learn more about Opstrace %{epicEnd}."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7 and are %{epicStart} scheduled for removal %{epicEnd} in GitLab 15.0."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7, and are %{removal_link_start} scheduled for removal %{link_end} in GitLab 15.0. For information on a possible replacement, %{opstrace_link_start} learn more about Opstrace %{link_end}."
+msgstr ""
+
msgid "Deprioritize label"
msgstr ""
@@ -12379,10 +12576,10 @@ msgstr ""
msgid "DevopsAdoption|At least one deploy"
msgstr ""
-msgid "DevopsAdoption|At least one issue opened"
+msgid "DevopsAdoption|At least one issue created"
msgstr ""
-msgid "DevopsAdoption|At least one merge request opened"
+msgid "DevopsAdoption|At least one merge request created"
msgstr ""
msgid "DevopsAdoption|At least one pipeline successfully run"
@@ -12583,6 +12780,9 @@ msgstr ""
msgid "Direct member"
msgstr ""
+msgid "Direct members"
+msgstr ""
+
msgid "Direct non-authenticated users to this page."
msgstr ""
@@ -12699,6 +12899,9 @@ msgid_plural "Dismiss %d selected vulnerabilities as"
msgstr[0] ""
msgstr[1] ""
+msgid "Dismiss Alert"
+msgstr ""
+
msgid "Dismiss merge request promotion"
msgstr ""
@@ -12726,9 +12929,15 @@ msgstr ""
msgid "Display alerts from all configured monitoring tools."
msgstr ""
+msgid "Display milestones"
+msgstr ""
+
msgid "Display name"
msgstr ""
+msgid "Display progress of child issues"
+msgstr ""
+
msgid "Display rendered file"
msgstr ""
@@ -12834,6 +13043,9 @@ msgstr ""
msgid "Download image"
msgstr ""
+msgid "Download payload"
+msgstr ""
+
msgid "Download raw data (.csv)"
msgstr ""
@@ -13011,6 +13223,9 @@ msgstr ""
msgid "Edit in Web IDE"
msgstr ""
+msgid "Edit in pipeline editor"
+msgstr ""
+
msgid "Edit in single-file editor"
msgstr ""
@@ -13053,6 +13268,9 @@ msgstr ""
msgid "Edit your most recent comment in a thread (from an empty textarea)"
msgstr ""
+msgid "Edit, lint, and visualize your pipeline."
+msgstr ""
+
msgid "Edited"
msgstr ""
@@ -13494,6 +13712,9 @@ msgstr ""
msgid "Enforce two-factor authentication for all user sign-ins."
msgstr ""
+msgid "Enhance security by storing service account keys in secret managers - learn more about %{docLinkStart}secret management with GitLab%{docLinkEnd}"
+msgstr ""
+
msgid "Ensure connectivity is available from the GitLab server to the Prometheus server"
msgstr ""
@@ -13554,6 +13775,9 @@ 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 following to confirm:"
+msgstr ""
+
msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
@@ -14084,9 +14308,6 @@ 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 ""
@@ -14222,6 +14443,9 @@ msgstr ""
msgid "Errors:"
msgstr ""
+msgid "Escalate this incident"
+msgstr ""
+
msgid "Escalation Policies"
msgstr ""
@@ -14234,6 +14458,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy"
+msgstr ""
+
msgid "Escalation policy:"
msgstr ""
@@ -14485,6 +14712,9 @@ msgstr ""
msgid "Existing sign in methods may be removed"
msgstr ""
+msgid "Exit."
+msgstr ""
+
msgid "Expand"
msgstr ""
@@ -14581,6 +14811,9 @@ msgstr ""
msgid "Explore public groups"
msgstr ""
+msgid "Explore public projects"
+msgstr ""
+
msgid "Explore snippets"
msgstr ""
@@ -14742,7 +14975,7 @@ msgid_plural "Failed to archive designs. Please try again."
msgstr[0] ""
msgstr[1] ""
-msgid "Failed to assign a reviewer because no user was found."
+msgid "Failed to assign a reviewer because no user was specified."
msgstr ""
msgid "Failed to assign a user because no user was found."
@@ -14808,10 +15041,10 @@ msgstr ""
msgid "Failed to find import label for Jira import."
msgstr ""
-msgid "Failed to generate export, please try again later."
+msgid "Failed to find users for %{missing}"
msgstr ""
-msgid "Failed to generate report, please try again after sometime"
+msgid "Failed to generate export, please try again later."
msgstr ""
msgid "Failed to get ref."
@@ -14910,6 +15143,9 @@ msgstr ""
msgid "Failed to remove a to-do item for the design."
msgstr ""
+msgid "Failed to remove attention because no user was found."
+msgstr ""
+
msgid "Failed to remove mirror."
msgstr ""
@@ -14922,6 +15158,9 @@ msgstr ""
msgid "Failed to remove user key."
msgstr ""
+msgid "Failed to request attention because no user was found."
+msgstr ""
+
msgid "Failed to reset key. Please try again."
msgstr ""
@@ -15003,6 +15242,9 @@ msgstr ""
msgid "Feature Flags"
msgstr ""
+msgid "Feature deprecation and removal"
+msgstr ""
+
msgid "Feature flag status"
msgstr ""
@@ -15500,7 +15742,7 @@ msgstr ""
msgid "For each job, re-use the project workspace. If the workspace doesn't exist, use %{code_open}git clone%{code_close}."
msgstr ""
-msgid "For example, the application using the token or the purpose of the token."
+msgid "For example, the application using the token or the purpose of the token. Do not give sensitive information for the name of the token, as it will be visible to all %{resource_type} members."
msgstr ""
msgid "For files larger than this limit, only index the file name. The file content is neither indexed nor searchable."
@@ -15584,9 +15826,6 @@ msgstr ""
msgid "ForkProject|Select a namespace"
msgstr ""
-msgid "ForkProject|Select a namespace to fork the project"
-msgstr ""
-
msgid "ForkProject|The project can be accessed by any logged in user."
msgstr ""
@@ -15683,6 +15922,9 @@ msgstr ""
msgid "Full name"
msgstr ""
+msgid "GCP region configured"
+msgstr ""
+
msgid "GPG Key ID:"
msgstr ""
@@ -15863,6 +16105,9 @@ msgstr ""
msgid "Geo|Failed"
msgstr ""
+msgid "Geo|Filter Geo sites"
+msgstr ""
+
msgid "Geo|Filter by name"
msgstr ""
@@ -16274,6 +16519,12 @@ msgstr ""
msgid "GitLab Issue"
msgstr ""
+msgid "GitLab KAS"
+msgstr ""
+
+msgid "GitLab Memberships CSV Export"
+msgstr ""
+
msgid "GitLab Pages"
msgstr ""
@@ -16322,6 +16573,9 @@ 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 free to use. Many features for larger teams are part of our %{link_start}paid products%{link_end}. You can try Ultimate for free without any obligation or payment details."
+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 ""
@@ -16448,7 +16702,7 @@ msgstr ""
msgid "GitLabPages|When enabled, all attempts to visit your website through HTTP are automatically redirected to HTTPS using a response with status code 301. Requires a valid certificate for all domains. %{docs_link_start}Learn more.%{link_end}"
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. %{docs_link_start}Learn more.%{link_end}"
+msgid "GitLabPages|When using Pages under the general domain of a GitLab instance (%{pages_host}), you cannot use HTTPS with subdomains of subdomains. If your namespace or groupname contains a dot, it does not work. This is a limitation of the HTTP Over TLS protocol. HTTP pages work if you don't redirect HTTP to HTTPS. %{docs_link_start}Learn more.%{link_end}"
msgstr ""
msgid "GitLabPages|With GitLab Pages you can host your static website directly from your GitLab repository. %{docs_link_start}Learn more.%{link_end}"
@@ -16625,9 +16879,6 @@ msgstr ""
msgid "Go to find file"
msgstr ""
-msgid "Go to fork"
-msgstr ""
-
msgid "Go to issue boards"
msgstr ""
@@ -16835,9 +17086,6 @@ msgstr ""
msgid "Group Hooks"
msgstr ""
-msgid "Group ID"
-msgstr ""
-
msgid "Group Owner must have signed in with SAML before enabling Group Managed Accounts"
msgstr ""
@@ -16865,9 +17113,6 @@ msgstr ""
msgid "Group by"
msgstr ""
-msgid "Group description"
-msgstr ""
-
msgid "Group description (optional)"
msgstr ""
@@ -16982,7 +17227,7 @@ msgstr ""
msgid "Group: %{name}"
msgstr ""
-msgid "GroupActivityMetrics|Issues opened"
+msgid "GroupActivityMetrics|Issues created"
msgstr ""
msgid "GroupActivityMetrics|Last 90 days"
@@ -16991,7 +17236,7 @@ msgstr ""
msgid "GroupActivityMetrics|Members added"
msgstr ""
-msgid "GroupActivityMetrics|Merge Requests opened"
+msgid "GroupActivityMetrics|Merge Requests created"
msgstr ""
msgid "GroupActivityMetrics|Recent activity"
@@ -17282,6 +17527,9 @@ msgstr ""
msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
+msgid "GroupSettings|Choose a group path that does not start with a dash or end with a period. It can also contain alphanumeric characters and underscores."
+msgstr ""
+
msgid "GroupSettings|Compliance frameworks"
msgstr ""
@@ -17315,7 +17563,7 @@ msgstr ""
msgid "GroupSettings|If not specified at the group or instance level, the default is %{default_initial_branch_name}. Does not affect existing repositories."
msgstr ""
-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."
+msgid "GroupSettings|If the parent group's visibility is lower than the group's current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility."
msgstr ""
msgid "GroupSettings|New runners registration token has been generated!"
@@ -17432,7 +17680,10 @@ msgstr ""
msgid "Groups and projects"
msgstr ""
-msgid "Groups and subgroups"
+msgid "Groups are a great way to organize projects and people."
+msgstr ""
+
+msgid "Groups are the best way to manage projects and members."
msgstr ""
msgid "Groups to synchronize"
@@ -17543,13 +17794,16 @@ msgstr ""
msgid "GroupsTree|Are you sure you want to leave the \"%{fullName}\" group?"
msgstr ""
-msgid "GroupsTree|Edit group"
+msgid "GroupsTree|Delete"
+msgstr ""
+
+msgid "GroupsTree|Edit"
msgstr ""
msgid "GroupsTree|Failed to leave the group. Please make sure you are not the only owner."
msgstr ""
-msgid "GroupsTree|Leave this group"
+msgid "GroupsTree|Leave group"
msgstr ""
msgid "GroupsTree|Loading groups"
@@ -17561,9 +17815,57 @@ msgstr ""
msgid "GroupsTree|No groups or projects matched your search"
msgstr ""
+msgid "GroupsTree|Options"
+msgstr ""
+
msgid "GroupsTree|Search by name"
msgstr ""
+msgid "Groups|Avatar will be removed. Are you sure?"
+msgstr ""
+
+msgid "Groups|Changing group URL can have unintended side effects."
+msgstr ""
+
+msgid "Groups|Checking group URL availability..."
+msgstr ""
+
+msgid "Groups|Enter a descriptive name for your group."
+msgstr ""
+
+msgid "Groups|Group ID"
+msgstr ""
+
+msgid "Groups|Group URL"
+msgstr ""
+
+msgid "Groups|Group avatar"
+msgstr ""
+
+msgid "Groups|Group description (optional)"
+msgstr ""
+
+msgid "Groups|Group name"
+msgstr ""
+
+msgid "Groups|Group path is available."
+msgstr ""
+
+msgid "Groups|Group path is unavailable. Path has been replaced with a suggested available path."
+msgstr ""
+
+msgid "Groups|Learn more"
+msgstr ""
+
+msgid "Groups|Must start with letter, digit, emoji, or underscore. Can also contain periods, dashes, spaces, and parentheses."
+msgstr ""
+
+msgid "Groups|Remove avatar"
+msgstr ""
+
+msgid "Groups|Save changes"
+msgstr ""
+
msgid "Guideline"
msgstr ""
@@ -17573,6 +17875,9 @@ msgstr ""
msgid "HAR file path or URL"
msgstr ""
+msgid "HTTP Archive (HAR)"
+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 ""
@@ -17973,6 +18278,9 @@ msgstr ""
msgid "INFO: Your SSH key is expiring soon. Please generate a new key."
msgstr ""
+msgid "IP"
+msgstr ""
+
msgid "IP Address"
msgstr ""
@@ -18009,6 +18317,9 @@ msgstr ""
msgid "IdentityVerification|Verify your identity"
msgstr ""
+msgid "IdentityVerification|You can always verify your account at a later time to create a group."
+msgstr ""
+
msgid "If any indexed field exceeds this limit, it is truncated to this number of characters. The rest of the content is neither indexed nor searchable. This does not apply to repository and wiki indexing. For unlimited characters, set this to 0."
msgstr ""
@@ -18066,6 +18377,9 @@ msgstr ""
msgid "If you add %{codeStart}needs%{codeEnd} to jobs in your pipeline you'll be able to view the %{codeStart}needs%{codeEnd} relationships between jobs in this tab as a %{linkStart}Directed Acyclic Graph (DAG)%{linkEnd}."
msgstr ""
+msgid "If you are added to a project, it will be displayed here."
+msgstr ""
+
msgid "If you did not initiate these sign-in attempts, please reach out to your administrator or enable two-factor authentication (2FA) on your account."
msgstr ""
@@ -18372,12 +18686,24 @@ msgstr ""
msgid "InProductMarketing|3 ways to dive into GitLab CI/CD"
msgstr ""
+msgid "InProductMarketing|A single application eliminates complex integrations, data chokepoints, and toolchain maintenance, resulting in greater productivity and lower cost."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features, build more efficiently, strengthen security and compliance."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features."
+msgstr ""
+
msgid "InProductMarketing|Actually, GitLab makes the team work (better)"
msgstr ""
msgid "InProductMarketing|And finally %{deploy_link} a Python application."
msgstr ""
+msgid "InProductMarketing|And many more..."
+msgstr ""
+
msgid "InProductMarketing|Are your runners ready?"
msgstr ""
@@ -18396,15 +18722,33 @@ msgstr ""
msgid "InProductMarketing|Blog"
msgstr ""
+msgid "InProductMarketing|Break down silos to coordinate seamlessly across development, operations, and security with a consistent experience across the development lifecycle."
+msgstr ""
+
+msgid "InProductMarketing|Burn up/down charts"
+msgstr ""
+
msgid "InProductMarketing|By enabling code owners and required merge approvals the right person will review the right MR. This is a win-win: cleaner code and a more efficient review process."
msgstr ""
msgid "InProductMarketing|Click on the number below that corresponds with your answer — 1 being very difficult, 5 being very easy."
msgstr ""
+msgid "InProductMarketing|Code owners"
+msgstr ""
+
msgid "InProductMarketing|Code owners and required merge approvals are part of the paid tiers of GitLab. You can start a free 30-day trial of GitLab Ultimate and enable these features in less than 5 minutes with no credit card required."
msgstr ""
+msgid "InProductMarketing|Code review analytics"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration across stages in GitLab"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration made easy"
+msgstr ""
+
msgid "InProductMarketing|Create a custom CI runner with just a few clicks"
msgstr ""
@@ -18414,12 +18758,21 @@ msgstr ""
msgid "InProductMarketing|Create a project in GitLab in 5 minutes"
msgstr ""
+msgid "InProductMarketing|Create well-defined workflows by using scoped labels on issues, merge requests, and epics. Labels with the same scope cannot be used together, which prevents conflicts."
+msgstr ""
+
msgid "InProductMarketing|Create your first project!"
msgstr ""
+msgid "InProductMarketing|Define who owns specific files or directories, so the right reviewers are suggested when a merge request introduces changes to those files."
+msgstr ""
+
msgid "InProductMarketing|Deliver Better Products Faster"
msgstr ""
+msgid "InProductMarketing|Dependency scanning"
+msgstr ""
+
msgid "InProductMarketing|Did you know teams that use GitLab are far more efficient?"
msgstr ""
@@ -18429,15 +18782,27 @@ msgstr ""
msgid "InProductMarketing|Dig in and create a project and a repo"
msgstr ""
+msgid "InProductMarketing|Discover Premium & Ultimate"
+msgstr ""
+
+msgid "InProductMarketing|Discover Premium & Ultimate."
+msgstr ""
+
msgid "InProductMarketing|Do you have a minute?"
msgstr ""
msgid "InProductMarketing|Do you have a teammate who would be perfect for this task?"
msgstr ""
+msgid "InProductMarketing|Dynamic application security testing"
+msgstr ""
+
msgid "InProductMarketing|Easy"
msgstr ""
+msgid "InProductMarketing|Epics"
+msgstr ""
+
msgid "InProductMarketing|Expand your DevOps journey with a free GitLab trial"
msgstr ""
@@ -18459,9 +18824,15 @@ msgstr ""
msgid "InProductMarketing|Feel the need for speed?"
msgstr ""
+msgid "InProductMarketing|Find and fix bottlenecks in your code review process by understanding how long open merge requests have been in review."
+msgstr ""
+
msgid "InProductMarketing|Find out how your teams are really doing"
msgstr ""
+msgid "InProductMarketing|Find out if your external libraries are safe. Run dependency scanning jobs that check for known vulnerabilities in your external libraries."
+msgstr ""
+
msgid "InProductMarketing|Follow our steps"
msgstr ""
@@ -18498,6 +18869,9 @@ msgstr ""
msgid "InProductMarketing|GitLab is better with teammates to help out!"
msgstr ""
+msgid "InProductMarketing|GitLab is infrastructure agnostic (supporting GCP, AWS, Azure, OpenShift, VMWare, On Prem, Bare Metal, and more), offering a consistent workflow experience – irrespective of the environment."
+msgstr ""
+
msgid "InProductMarketing|GitLab provides static application security testing (SAST), dynamic application security testing (DAST), container scanning, and dependency scanning to help you deliver secure applications along with license compliance."
msgstr ""
@@ -18588,21 +18962,36 @@ msgstr ""
msgid "InProductMarketing|It's also possible to simply %{external_repo_link} in order to take advantage of GitLab's CI/CD."
msgstr ""
+msgid "InProductMarketing|Keep your code quality high by defining who should approve merge requests and how many approvals are required."
+msgstr ""
+
msgid "InProductMarketing|Launch GitLab CI/CD in 20 minutes or less"
msgstr ""
+msgid "InProductMarketing|Lower cost of development"
+msgstr ""
+
+msgid "InProductMarketing|Make it easier to collaborate on high-level ideas by grouping related issues in an epic."
+msgstr ""
+
msgid "InProductMarketing|Making the switch? It's easier than you think to import your projects into GitLab. Move %{github_link}, or import something %{bitbucket_link}."
msgstr ""
msgid "InProductMarketing|Master the art of importing!"
msgstr ""
+msgid "InProductMarketing|Merge request approval rule"
+msgstr ""
+
msgid "InProductMarketing|Move on to easily creating a Pages website %{ci_template_link}"
msgstr ""
msgid "InProductMarketing|Multiple owners, confusing workstreams? We've got you covered"
msgstr ""
+msgid "InProductMarketing|Multiple required approvers"
+msgstr ""
+
msgid "InProductMarketing|Need an alternative to importing?"
msgstr ""
@@ -18615,18 +19004,33 @@ msgstr ""
msgid "InProductMarketing|Our tool brings all the things together"
msgstr ""
+msgid "InProductMarketing|Protect your web application by using DAST to examine for vulnerabilities in deployed environments."
+msgstr ""
+
msgid "InProductMarketing|Rapid development, simplified"
msgstr ""
msgid "InProductMarketing|Reduce Security & Compliance Risk"
msgstr ""
+msgid "InProductMarketing|Require multiple approvers on a merge request, so you know it's in good shape before it's merged."
+msgstr ""
+
+msgid "InProductMarketing|Roadmaps"
+msgstr ""
+
+msgid "InProductMarketing|Scoped labels"
+msgstr ""
+
msgid "InProductMarketing|Security that's integrated into your development lifecycle"
msgstr ""
msgid "InProductMarketing|Sometimes you're not ready to make a full transition to a new tool. If you're not ready to fully commit, %{mirroring_link} gives you a safe way to try out GitLab in parallel with your current tool."
msgstr ""
+msgid "InProductMarketing|Speed. Efficiency. Trust."
+msgstr ""
+
msgid "InProductMarketing|Spin up an autoscaling runner in GitLab"
msgstr ""
@@ -18636,6 +19040,9 @@ msgstr ""
msgid "InProductMarketing|Start a Self-Managed trial"
msgstr ""
+msgid "InProductMarketing|Start a free trial"
+msgstr ""
+
msgid "InProductMarketing|Start a free trial of GitLab Ultimate – no credit card required"
msgstr ""
@@ -18702,6 +19109,9 @@ msgstr ""
msgid "InProductMarketing|To understand and get the most out of GitLab, start at the beginning and %{project_link}. In GitLab, repositories are part of a project, so after you've created your project you can go ahead and %{repo_link}."
msgstr ""
+msgid "InProductMarketing|Track completed issues in a chart, so you can see how a milestone is progressing at a glance."
+msgstr ""
+
msgid "InProductMarketing|Try GitLab Ultimate for free"
msgstr ""
@@ -18738,6 +19148,9 @@ msgstr ""
msgid "InProductMarketing|Very easy"
msgstr ""
+msgid "InProductMarketing|Visualize your epics and milestones in a timeline."
+msgstr ""
+
msgid "InProductMarketing|Want to host GitLab on your servers?"
msgstr ""
@@ -18759,6 +19172,9 @@ msgstr ""
msgid "InProductMarketing|YouTube"
msgstr ""
+msgid "InProductMarketing|Your software, deployed your way"
+msgstr ""
+
msgid "InProductMarketing|Your teams can be more efficient"
msgstr ""
@@ -18879,9 +19295,18 @@ msgstr ""
msgid "IncidentManagement|No incidents to display."
msgstr ""
+msgid "IncidentManagement|None"
+msgstr ""
+
msgid "IncidentManagement|Open"
msgstr ""
+msgid "IncidentManagement|Page your team with escalation policies"
+msgstr ""
+
+msgid "IncidentManagement|Paged"
+msgstr ""
+
msgid "IncidentManagement|Published"
msgstr ""
@@ -18891,6 +19316,9 @@ msgstr ""
msgid "IncidentManagement|Severity"
msgstr ""
+msgid "IncidentManagement|Status"
+msgstr ""
+
msgid "IncidentManagement|There are no closed incidents"
msgstr ""
@@ -18909,6 +19337,9 @@ msgstr ""
msgid "IncidentManagement|Unpublished"
msgstr ""
+msgid "IncidentManagement|Use escalation policies to automatically page your team when incidents are created."
+msgstr ""
+
msgid "IncidentSettings|Activate \"time to SLA\" countdown timer"
msgstr ""
@@ -18954,7 +19385,10 @@ msgstr ""
msgid "Incidents"
msgstr ""
-msgid "Incidents|Add a URL"
+msgid "Incidents|Add image details"
+msgstr ""
+
+msgid "Incidents|Add text or a link to display with your image. If you don't add either, the file name displays instead."
msgstr ""
msgid "Incidents|Drop or %{linkStart}upload%{linkEnd} a metric screenshot to attach it to the incident"
@@ -18969,10 +19403,10 @@ msgstr ""
msgid "Incidents|There was an issue loading metric images."
msgstr ""
-msgid "Incidents|There was an issue uploading your image."
+msgid "Incidents|There was an issue updating your image."
msgstr ""
-msgid "Incidents|You can optionally add a URL to link users to the original graph."
+msgid "Incidents|There was an issue uploading your image."
msgstr ""
msgid "Incident|Alert details"
@@ -18981,9 +19415,18 @@ msgstr ""
msgid "Incident|Are you sure you wish to delete this image?"
msgstr ""
+msgid "Incident|Delete image"
+msgstr ""
+
msgid "Incident|Deleting %{filename}"
msgstr ""
+msgid "Incident|Edit image text or link"
+msgstr ""
+
+msgid "Incident|Editing %{filename}"
+msgstr ""
+
msgid "Incident|Metrics"
msgstr ""
@@ -19253,12 +19696,18 @@ msgstr ""
msgid "Integrations|Branches for which notifications are to be sent"
msgstr ""
+msgid "Integrations|Clear if using a self-signed certificate."
+msgstr ""
+
msgid "Integrations|Comment detail:"
msgstr ""
msgid "Integrations|Comment settings:"
msgstr ""
+msgid "Integrations|Connection details"
+msgstr ""
+
msgid "Integrations|Connection failed. Please check your settings."
msgstr ""
@@ -19283,6 +19732,9 @@ msgstr ""
msgid "Integrations|Enable GitLab.com slash commands in a Slack workspace."
msgstr ""
+msgid "Integrations|Enable SSL verification"
+msgstr ""
+
msgid "Integrations|Enable comments"
msgstr ""
@@ -19361,6 +19813,9 @@ msgstr ""
msgid "Integrations|Return to GitLab for Jira"
msgstr ""
+msgid "Integrations|SSL verification"
+msgstr ""
+
msgid "Integrations|Save settings?"
msgstr ""
@@ -19406,9 +19861,6 @@ msgstr ""
msgid "Integrations|Use default settings"
msgstr ""
-msgid "Integrations|When you mention a Jira issue in a commit or merge request, GitLab creates a remote link and comment (if enabled)."
-msgstr ""
-
msgid "Integrations|You can now close this window and return to the GitLab for Jira application."
msgstr ""
@@ -19433,9 +19885,6 @@ msgstr ""
msgid "Integrations|can't exceed %{recipients_limit}"
msgstr ""
-msgid "Interactive developer security education."
-msgstr ""
-
msgid "Interactive mode"
msgstr ""
@@ -19925,6 +20374,9 @@ msgstr ""
msgid "IssueAnalytics|Assignees"
msgstr ""
+msgid "IssueAnalytics|Created by"
+msgstr ""
+
msgid "IssueAnalytics|Due date"
msgstr ""
@@ -19937,9 +20389,6 @@ msgstr ""
msgid "IssueAnalytics|Milestone"
msgstr ""
-msgid "IssueAnalytics|Opened by"
-msgstr ""
-
msgid "IssueAnalytics|Status"
msgstr ""
@@ -20063,10 +20512,10 @@ msgstr ""
msgid "IssuesAnalytics|Avg/Month:"
msgstr ""
-msgid "IssuesAnalytics|Issues opened"
+msgid "IssuesAnalytics|Issues created"
msgstr ""
-msgid "IssuesAnalytics|Issues opened per month"
+msgid "IssuesAnalytics|Issues created per month"
msgstr ""
msgid "IssuesAnalytics|Last 12 months"
@@ -20093,6 +20542,9 @@ msgstr ""
msgid "It looks like you have some draft commits in this branch."
msgstr ""
+msgid "It looks like you're attempting to activate your subscription. Use %{a_start}the Subscription page%{a_end} instead."
+msgstr ""
+
msgid "It may be several days before you see feature usage data."
msgstr ""
@@ -20321,6 +20773,9 @@ msgstr ""
msgid "JiraConnect|You can now close this window and return to Jira."
msgstr ""
+msgid "JiraConnect|You don't have permission to create branches for this project. Select a different project or contact the project owner for access. %{linkStart}Learn more.%{linkEnd}"
+msgstr ""
+
msgid "JiraRequest|A connection error occurred while connecting to Jira. Try your request again."
msgstr ""
@@ -20369,13 +20824,13 @@ msgstr ""
msgid "JiraService|Define the type of Jira issue to create from a vulnerability."
msgstr ""
-msgid "JiraService|Displaying Jira issues while leaving the GitLab issue functionality enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
+msgid "JiraService|Displaying Jira issues while leaving GitLab issues also enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
msgstr ""
-msgid "JiraService|Enable Jira issues"
+msgid "JiraService|Enable Jira issue creation from vulnerabilities"
msgstr ""
-msgid "JiraService|Enable Jira issues creation from vulnerabilities"
+msgid "JiraService|Enable Jira issues"
msgstr ""
msgid "JiraService|Enable Jira transitions"
@@ -20492,16 +20947,19 @@ msgstr ""
msgid "JiraService|View Jira issues in GitLab"
msgstr ""
-msgid "JiraService|Warning: All GitLab users that have access to this GitLab project are able to view all issues from the Jira project specified below."
+msgid "JiraService|Warning: All GitLab users with access to this GitLab project can view all issues from the Jira project you select."
msgstr ""
msgid "JiraService|Web URL"
msgstr ""
-msgid "JiraService|Work on Jira issues without leaving GitLab. Adds a Jira menu to access your list of Jira issues and view any issue as read-only."
+msgid "JiraService|When a Jira issue is mentioned in a commit or merge request, a remote link and comment (if enabled) will be created."
+msgstr ""
+
+msgid "JiraService|Work on Jira issues without leaving GitLab. Add a Jira menu to access a read-only list of your Jira issues."
msgstr ""
-msgid "JiraService|You need to configure Jira before enabling this integration. For more details, read the %{jira_doc_link_start}Jira integration documentation%{link_end}."
+msgid "JiraService|You must configure Jira before enabling this integration. %{jira_doc_link_start}Learn more.%{link_end}"
msgstr ""
msgid "Job"
@@ -20513,9 +20971,6 @@ msgstr ""
msgid "Job Failed #%{build_id}"
msgstr ""
-msgid "Job ID"
-msgstr ""
-
msgid "Job artifact"
msgstr ""
@@ -20582,9 +21037,27 @@ msgstr ""
msgid "Jobs|You're about to retry a job that failed because it attempted to deploy code that is older than the latest deployment. Retrying this job could result in overwriting the environment with the older source code."
msgstr ""
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source} into %{target}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{ref}"
+msgstr ""
+
+msgid "Job|Are you sure you want to erase this job log and artifacts?"
+msgstr ""
+
msgid "Job|Browse"
msgstr ""
+msgid "Job|Cancel"
+msgstr ""
+
msgid "Job|Complete Raw"
msgstr ""
@@ -20594,6 +21067,9 @@ msgstr ""
msgid "Job|Erase job log and artifacts"
msgstr ""
+msgid "Job|Finished at"
+msgstr ""
+
msgid "Job|Job artifacts"
msgstr ""
@@ -20606,7 +21082,7 @@ msgstr ""
msgid "Job|Keep"
msgstr ""
-msgid "Job|Pipeline"
+msgid "Job|Retry"
msgstr ""
msgid "Job|Scroll to bottom"
@@ -20618,6 +21094,9 @@ msgstr ""
msgid "Job|Show complete raw"
msgstr ""
+msgid "Job|Status"
+msgstr ""
+
msgid "Job|The artifacts were removed"
msgstr ""
@@ -20645,21 +21124,12 @@ msgstr ""
msgid "Job|delayed"
msgstr ""
-msgid "Job|for"
-msgstr ""
-
-msgid "Job|into"
-msgstr ""
-
msgid "Job|manual"
msgstr ""
msgid "Job|triggered"
msgstr ""
-msgid "Job|with"
-msgstr ""
-
msgid "Join Zoom meeting"
msgstr ""
@@ -20762,9 +21232,6 @@ msgstr ""
msgid "Ki"
msgstr ""
-msgid "Kontra"
-msgstr ""
-
msgid "Kroki"
msgstr ""
@@ -21088,6 +21555,9 @@ msgstr ""
msgid "Learn more about Auto DevOps"
msgstr ""
+msgid "Learn more about GitLab"
+msgstr ""
+
msgid "Learn more about Needs relationships"
msgstr ""
@@ -21415,9 +21885,18 @@ msgstr ""
msgid "Licenses|Displays licenses detected in the project, based on the %{linkStart}latest successful%{linkEnd} scan"
msgstr ""
+msgid "Licenses|Drag your license file here or %{linkStart}click to upload%{linkEnd}."
+msgstr ""
+
+msgid "Licenses|Drop your license file to start the upload."
+msgstr ""
+
msgid "Licenses|Error fetching the license list. Please check your network connection and try again."
msgstr ""
+msgid "Licenses|Error: You are trying to upload something other than a file"
+msgstr ""
+
msgid "Licenses|License Compliance"
msgstr ""
@@ -21436,6 +21915,9 @@ msgstr ""
msgid "Licenses|Specified policies in this project"
msgstr ""
+msgid "Licenses|The file could not be uploaded."
+msgstr ""
+
msgid "Licenses|The license list details information about the licenses used within your project."
msgstr ""
@@ -21469,11 +21951,6 @@ msgstr ""
msgid "Limit the size of Sidekiq jobs stored in Redis."
msgstr ""
-msgid "Limited to showing %d event at most"
-msgid_plural "Limited to showing %d events at most"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Limiting mode"
msgstr ""
@@ -21483,6 +21960,9 @@ msgstr ""
msgid "Link"
msgstr ""
+msgid "Link (optional)"
+msgstr ""
+
msgid "Link Prometheus monitoring to GitLab."
msgstr ""
@@ -21519,6 +21999,9 @@ msgstr ""
msgid "Linked emails (%{email_count})"
msgstr ""
+msgid "Linked epics"
+msgstr ""
+
msgid "Linked issues"
msgstr ""
@@ -21546,6 +22029,15 @@ msgstr ""
msgid "List of all merge commits"
msgstr ""
+msgid "List of environments for this project"
+msgstr ""
+
+msgid "List of suitable GCP locations"
+msgstr ""
+
+msgid "List of users allowed to exceed the rate limit."
+msgstr ""
+
msgid "List options"
msgstr ""
@@ -21765,6 +22257,9 @@ msgstr ""
msgid "Maintenance mode"
msgstr ""
+msgid "Make adjustments to how your GitLab instance is set up."
+msgstr ""
+
msgid "Make and review changes in the browser with the Web IDE"
msgstr ""
@@ -21909,6 +22404,12 @@ msgstr ""
msgid "MarkdownEditor|Add italic text (%{modifier_key}I)"
msgstr ""
+msgid "MarkdownEditor|Add strikethrough text (%{modifierKey}⇧X)"
+msgstr ""
+
+msgid "MarkdownEditor|Add strikethrough text (%{modifier_key}⇧X)"
+msgstr ""
+
msgid "Marked For Deletion At - %{deletion_time}"
msgstr ""
@@ -22170,6 +22671,9 @@ msgstr ""
msgid "Maximum push size (MB)"
msgstr ""
+msgid "Maximum requests per 10 minutes per user"
+msgstr ""
+
msgid "Maximum requests per minute"
msgstr ""
@@ -22260,6 +22764,19 @@ msgstr ""
msgid "Members of a group may only view projects they have permission to access"
msgstr ""
+msgid "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seat in use and will be billed for the overage."
+msgid_plural "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seats in use and will be billed for the overage."
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "MembersOverage|You are about to incur additional charges"
+msgstr ""
+
+msgid "MembersOverage|Your subscription includes %d seat."
+msgid_plural "MembersOverage|Your subscription includes %d seats."
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Membership"
msgstr ""
@@ -22464,9 +22981,6 @@ msgstr ""
msgid "Merge request not merged"
msgstr ""
-msgid "Merge request pipelines 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 merge request pipelines."
-msgstr ""
-
msgid "Merge request reports"
msgstr ""
@@ -22563,13 +23077,13 @@ msgstr ""
msgid "MergeRequests|Create issue to resolve thread"
msgstr ""
-msgid "MergeRequests|Failed to squash. Should be done manually."
+msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Saving the comment failed"
+msgid "MergeRequests|Squashing failed: Squash the commits locally, resolve any conflicts, then push the branch."
msgstr ""
-msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
+msgid "MergeRequests|Squashing not allowed: This project doesn't allow you to squash commits when merging."
msgstr ""
msgid "MergeRequests|Thread stays resolved"
@@ -23410,6 +23924,18 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "MrList|Assigned to %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from assignee %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from reviewer %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Review requested from %{name}, go to their profile."
+msgstr ""
+
msgid "Multi-project"
msgstr ""
@@ -23443,7 +23969,7 @@ msgstr ""
msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "My Awesome Group"
+msgid "My awesome group"
msgstr ""
msgid "My company or team"
@@ -24065,9 +24591,6 @@ msgstr ""
msgid "No available branches"
msgstr ""
-msgid "No available groups to fork the project."
-msgstr ""
-
msgid "No branches found"
msgstr ""
@@ -24278,6 +24801,9 @@ msgstr ""
msgid "No ref selected"
msgstr ""
+msgid "No regions configured"
+msgstr ""
+
msgid "No related merge requests found."
msgstr ""
@@ -25082,6 +25608,9 @@ msgstr ""
msgid "Only reCAPTCHA v2 is supported:"
msgstr ""
+msgid "Only required if not using role instance credentials."
+msgstr ""
+
msgid "Only use lowercase letters, numbers, and underscores."
msgstr ""
@@ -25106,9 +25635,6 @@ msgstr ""
msgid "Open a CLI and connect to the cluster you want to install the agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
-msgid "Open epics"
-msgstr ""
-
msgid "Open errors"
msgstr ""
@@ -25148,7 +25674,7 @@ msgstr ""
msgid "Opened issues"
msgstr ""
-msgid "OpenedNDaysAgo|Opened"
+msgid "OpenedNDaysAgo|Created"
msgstr ""
msgid "Opens in a new window"
@@ -25193,9 +25719,6 @@ msgstr ""
msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
-msgid "Optional."
-msgstr ""
-
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
msgstr ""
@@ -25984,6 +26507,9 @@ msgstr ""
msgid "PerformanceBar|Memory"
msgstr ""
+msgid "PerformanceBar|Memory report"
+msgstr ""
+
msgid "PerformanceBar|Redis calls"
msgstr ""
@@ -26017,18 +26543,12 @@ msgstr ""
msgid "PerformanceBar|wall"
msgstr ""
-msgid "Performs a rebase but skips triggering a new pipeline"
-msgstr ""
-
msgid "Period in seconds"
msgstr ""
msgid "Permalink"
msgstr ""
-msgid "Permanently delete project"
-msgstr ""
-
msgid "Permanently remove group"
msgstr ""
@@ -26299,6 +26819,51 @@ msgstr ""
msgid "PipelineStatusTooltip|Pipeline: %{ci_status}"
msgstr ""
+msgid "PipelineWizardDefaultCommitMessage|Add %{filename}"
+msgstr ""
+
+msgid "PipelineWizardDefaultCommitMessage|Update %{filename}"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|At least one entry is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This field is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This value is not valid"
+msgstr ""
+
+msgid "PipelineWizardListWidget|add another step"
+msgstr ""
+
+msgid "PipelineWizardListWidget|remove step"
+msgstr ""
+
+msgid "PipelineWizard|Commit"
+msgstr ""
+
+msgid "PipelineWizard|Commit Message"
+msgstr ""
+
+msgid "PipelineWizard|Commit changes to your file"
+msgstr ""
+
+msgid "PipelineWizard|Commit file to Branch"
+msgstr ""
+
+msgid "PipelineWizard|Commit your new file"
+msgstr ""
+
+msgid "PipelineWizard|The file has been committed."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem committing the changes."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem while checking whether your file already exists in the specified branch."
+msgstr ""
+
msgid "Pipelines"
msgstr ""
@@ -26413,7 +26978,7 @@ msgstr ""
msgid "Pipelines|Project cache successfully reset."
msgstr ""
-msgid "Pipelines|Revoke"
+msgid "Pipelines|Revoke trigger"
msgstr ""
msgid "Pipelines|Something went wrong while cleaning runners cache."
@@ -26458,6 +27023,12 @@ msgstr ""
msgid "Pipelines|This is a child pipeline within the parent pipeline"
msgstr ""
+msgid "Pipelines|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipelines|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipelines|This pipeline will run code originating from a forked project merge request. This means that the code can potentially have security considerations like exposing CI variables."
msgstr ""
@@ -26500,9 +27071,6 @@ msgstr ""
msgid "Pipelines|Your changes have been successfully committed. Now redirecting to the new merge request page."
msgstr ""
-msgid "Pipelines|detached"
-msgstr ""
-
msgid "Pipelines|error"
msgstr ""
@@ -26512,10 +27080,13 @@ msgstr ""
msgid "Pipelines|latest"
msgstr ""
-msgid "Pipelines|stuck"
+msgid "Pipelines|merge request"
msgstr ""
-msgid "Pipelines|train"
+msgid "Pipelines|merge train"
+msgstr ""
+
+msgid "Pipelines|stuck"
msgstr ""
msgid "Pipelines|yaml invalid"
@@ -26647,6 +27218,12 @@ msgstr ""
msgid "Pipeline|This change will not change the overall test coverage if merged."
msgstr ""
+msgid "Pipeline|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipeline|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipeline|Trigger author"
msgstr ""
@@ -26671,6 +27248,12 @@ msgstr ""
msgid "Pipeline|for"
msgstr ""
+msgid "Pipeline|merge request"
+msgstr ""
+
+msgid "Pipeline|merge train"
+msgstr ""
+
msgid "Pipeline|on"
msgstr ""
@@ -26809,9 +27392,6 @@ msgstr ""
msgid "Please enter a valid time interval"
msgstr ""
-msgid "Please enter or upload a valid license."
-msgstr ""
-
msgid "Please enter your current password."
msgstr ""
@@ -26920,9 +27500,6 @@ msgstr ""
msgid "Please type %{phrase_code} to proceed or close this modal to cancel."
msgstr ""
-msgid "Please type the following to confirm:"
-msgstr ""
-
msgid "Please use this form to report to the admin users who create spam issues, comments or behave inappropriately."
msgstr ""
@@ -26950,12 +27527,27 @@ msgstr ""
msgid "Policies"
msgstr ""
+msgid "Policy '%{escalation_policy_name}' does not exist."
+msgstr ""
+
msgid "Policy management project does have any policies in %{policy_path}"
msgstr ""
msgid "Policy project doesn't exist"
msgstr ""
+msgid "PolicyRuleMultiSelect|%{firstLabel} +%{numberOfAdditionalLabels} more"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|All %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select all"
+msgstr ""
+
msgid "Polling interval multiplier"
msgstr ""
@@ -27184,6 +27776,9 @@ msgstr ""
msgid "Private projects can be created in your personal namespace with:"
msgstr ""
+msgid "Problem with %{name} command: %{message}."
+msgstr ""
+
msgid "Proceed"
msgstr ""
@@ -27658,6 +28253,9 @@ msgstr ""
msgid "Progress"
msgstr ""
+msgid "Progress tracking"
+msgstr ""
+
msgid "Project"
msgstr ""
@@ -27889,6 +28487,9 @@ msgstr ""
msgid "ProjectQualitySummary|Failure"
msgstr ""
+msgid "ProjectQualitySummary|Get insight into the overall percentage of tests in your project that succeed, fail and are skipped."
+msgstr ""
+
msgid "ProjectQualitySummary|Latest pipeline results"
msgstr ""
@@ -27907,6 +28508,12 @@ msgstr ""
msgid "ProjectQualitySummary|See project Code Coverage Statistics"
msgstr ""
+msgid "ProjectQualitySummary|Set up test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|Set up test runs (opens in a new tab)"
+msgstr ""
+
msgid "ProjectQualitySummary|Skipped"
msgstr ""
@@ -28183,13 +28790,19 @@ msgstr ""
msgid "ProjectSettings|LFS objects from this repository are available to forks. %{linkStart}How do I remove them?%{linkEnd}"
msgstr ""
+msgid "ProjectSettings|Learn about commit history."
+msgstr ""
+
+msgid "ProjectSettings|Leave empty to use default template."
+msgstr ""
+
msgid "ProjectSettings|Manage who can see the project in the public access directory."
msgstr ""
msgid "ProjectSettings|Manages large files such as audio, video, and graphics files."
msgstr ""
-msgid "ProjectSettings|Maximum 500 characters."
+msgid "ProjectSettings|Maximum %{maxLength} characters."
msgstr ""
msgid "ProjectSettings|Merge checks"
@@ -28330,6 +28943,9 @@ msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
msgstr ""
+msgid "ProjectSettings|The default template will be applied on save."
+msgstr ""
+
msgid "ProjectSettings|These checks must pass before merge requests can be merged."
msgstr ""
@@ -28384,6 +29000,9 @@ msgstr ""
msgid "ProjectSettings|What are badges?"
msgstr ""
+msgid "ProjectSettings|What are merge trains?"
+msgstr ""
+
msgid "ProjectSettings|When merge request pipelines are enabled in the CI/CD configuration file, pipelines validate the combined results of the source and target branches. %{link_start}How to configure merge request pipelines?%{link_end}"
msgstr ""
@@ -28501,6 +29120,9 @@ msgstr ""
msgid "Projects are organized into groups"
msgstr ""
+msgid "Projects are where you store your code, access issues, wiki and other features of GitLab."
+msgstr ""
+
msgid "Projects contributed to"
msgstr ""
@@ -28516,12 +29138,6 @@ msgstr ""
msgid "Projects to index"
msgstr ""
-msgid "Projects will be permanently deleted after a %{waiting_period}-day waiting period."
-msgstr ""
-
-msgid "Projects will be permanently deleted immediately."
-msgstr ""
-
msgid "Projects with critical vulnerabilities"
msgstr ""
@@ -28606,6 +29222,9 @@ msgstr ""
msgid "ProjectsNew|Import project"
msgstr ""
+msgid "ProjectsNew|Include a Getting Started README"
+msgstr ""
+
msgid "ProjectsNew|Initialize repository with a README"
msgstr ""
@@ -28621,6 +29240,9 @@ msgstr ""
msgid "ProjectsNew|Project description %{tag_start}(optional)%{tag_end}"
msgstr ""
+msgid "ProjectsNew|Recommended if you're new to GitLab"
+msgstr ""
+
msgid "ProjectsNew|Run CI/CD for external repository"
msgstr ""
@@ -29038,6 +29660,9 @@ msgstr ""
msgid "ProtectedBranch|Unprotect"
msgstr ""
+msgid "ProtectedBranch|Unprotect branch"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
@@ -29065,6 +29690,9 @@ msgstr ""
msgid "ProtectedEnvironment|Protected Environment (%{protected_environments_count})"
msgstr ""
+msgid "ProtectedEnvironment|Required approvals"
+msgstr ""
+
msgid "ProtectedEnvironment|Select an environment"
msgstr ""
@@ -29086,10 +29714,13 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|Unprotect tag"
+msgstr ""
+
msgid "ProtectedTags|default"
msgstr ""
-msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
+msgid "ProtectedTag|By default, protected tags restrict who can modify the tag."
msgstr ""
msgid "ProtectedTag|Learn more."
@@ -29152,6 +29783,9 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Public projects are an easy way to allow everyone to have read-only access."
+msgstr ""
+
msgid "Publish to status page"
msgstr ""
@@ -29308,9 +29942,6 @@ msgstr ""
msgid "QualitySummary|Project quality"
msgstr ""
-msgid "Quarters"
-msgstr ""
-
msgid "Query"
msgstr ""
@@ -29395,6 +30026,9 @@ msgstr ""
msgid "Read more about project permissions %{help_link_open}here%{help_link_close}"
msgstr ""
+msgid "Read more about related epics"
+msgstr ""
+
msgid "Read more about related issues"
msgstr ""
@@ -29425,10 +30059,7 @@ msgstr ""
msgid "Rebase source branch on the target branch."
msgstr ""
-msgid "Rebase without CI"
-msgstr ""
-
-msgid "Rebases and triggers a pipeline"
+msgid "Rebase without pipeline"
msgstr ""
msgid "Recaptcha verified?"
@@ -29479,9 +30110,6 @@ msgstr ""
msgid "Reconfigure"
msgstr ""
-msgid "Recovering projects"
-msgstr ""
-
msgid "Recovery Codes"
msgstr ""
@@ -29541,6 +30169,12 @@ msgstr ""
msgid "Regex pattern"
msgstr ""
+msgid "Region"
+msgstr ""
+
+msgid "Regions"
+msgstr ""
+
msgid "Register"
msgstr ""
@@ -29771,9 +30405,6 @@ msgstr ""
msgid "Remove all or specific reviewer(s)"
msgstr ""
-msgid "Remove approver"
-msgstr ""
-
msgid "Remove approvers"
msgstr ""
@@ -29789,6 +30420,9 @@ msgstr ""
msgid "Remove attention request"
msgstr ""
+msgid "Remove attention request(s)"
+msgstr ""
+
msgid "Remove avatar"
msgstr ""
@@ -29927,6 +30561,9 @@ msgstr ""
msgid "Removed an issue from an epic."
msgstr ""
+msgid "Removed attention from %{users_sentence}."
+msgstr ""
+
msgid "Removed attention request from @%{username}"
msgstr ""
@@ -29978,6 +30615,9 @@ msgstr ""
msgid "Removes an issue from an epic."
msgstr ""
+msgid "Removes attention from %{users_sentence}."
+msgstr ""
+
msgid "Removes parent epic %{epic_ref}."
msgstr ""
@@ -30089,6 +30729,9 @@ msgstr ""
msgid "Report abuse to admin"
msgstr ""
+msgid "Report is generating and will be sent to your email address."
+msgstr ""
+
msgid "Reported %{timeAgo} by %{reportedBy}"
msgstr ""
@@ -30378,6 +31021,15 @@ msgstr ""
msgid "Request attention"
msgstr ""
+msgid "Request attention from %{users_sentence}."
+msgstr ""
+
+msgid "Request attention from assignee or reviewer"
+msgstr ""
+
+msgid "Request attention from assignee(s) or reviewer(s)"
+msgstr ""
+
msgid "Request attention to review"
msgstr ""
@@ -30402,6 +31054,9 @@ msgstr ""
msgid "Requested %{time_ago}"
msgstr ""
+msgid "Requested attention from %{users_sentence}."
+msgstr ""
+
msgid "Requested attention from @%{username}"
msgstr ""
@@ -30616,6 +31271,9 @@ msgstr ""
msgid "Restore project"
msgstr ""
+msgid "Restoring projects"
+msgstr ""
+
msgid "Restoring the group will prevent the group, its subgroups and projects from being removed on this date."
msgstr ""
@@ -30646,6 +31304,9 @@ msgstr ""
msgid "Retry"
msgstr ""
+msgid "Retry failed jobs"
+msgstr ""
+
msgid "Retry job"
msgstr ""
@@ -30693,9 +31354,6 @@ msgstr ""
msgid "Review changes"
msgstr ""
-msgid "Review requested from %{name}"
-msgstr ""
-
msgid "Review requests for you"
msgstr ""
@@ -30860,6 +31518,9 @@ msgstr ""
msgid "Runners|Assigned Group"
msgstr ""
+msgid "Runners|Assigned Projects (%{projectCount})"
+msgstr ""
+
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30929,6 +31590,9 @@ msgstr ""
msgid "Runners|Instance"
msgstr ""
+msgid "Runners|Jobs"
+msgstr ""
+
msgid "Runners|Last contact"
msgstr ""
@@ -31022,9 +31686,6 @@ msgstr ""
msgid "Runners|Runner %{name} was deleted"
msgstr ""
-msgid "Runners|Runner ID"
-msgstr ""
-
msgid "Runners|Runner assigned to project."
msgstr ""
@@ -31172,6 +31833,9 @@ msgstr ""
msgid "Runners|stale"
msgstr ""
+msgid "Runner|This runner has not run any jobs."
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -31286,6 +31950,24 @@ msgstr ""
msgid "Saving project."
msgstr ""
+msgid "ScanResultPolicy|%{ifLabelStart}if%{ifLabelEnd} %{scanners} scan in an open merge request targeting the %{branches} branch(es) finds %{vulnerabilitiesAllowed} or more %{severities} vulnerabilities that are %{vulnerabilityStates}"
+msgstr ""
+
+msgid "ScanResultPolicy|%{thenLabelStart}Then%{thenLabelEnd} Require approval from %{approvalsRequired} of the following approvers: %{approvers}"
+msgstr ""
+
+msgid "ScanResultPolicy|add an approver"
+msgstr ""
+
+msgid "ScanResultPolicy|scanners"
+msgstr ""
+
+msgid "ScanResultPolicy|severity levels"
+msgstr ""
+
+msgid "ScanResultPolicy|vulnerability states"
+msgstr ""
+
msgid "Scanner"
msgstr ""
@@ -31418,6 +32100,9 @@ msgstr ""
msgid "Search for a user"
msgstr ""
+msgid "Search for an emoji"
+msgstr ""
+
msgid "Search for projects, issues, etc."
msgstr ""
@@ -31605,18 +32290,12 @@ msgstr ""
msgid "Secret Detection"
msgstr ""
-msgid "Secret access key"
-msgstr ""
-
msgid "Secret token"
msgstr ""
msgid "Secure token that identifies an external storage request."
msgstr ""
-msgid "SecureCodeWarrior"
-msgstr ""
-
msgid "Security"
msgstr ""
@@ -31641,9 +32320,6 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "Security training with guide and learning pathways."
-msgstr ""
-
msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
@@ -31746,7 +32422,7 @@ msgstr ""
msgid "SecurityConfiguration|Manage corpus"
msgstr ""
-msgid "SecurityConfiguration|Manage corpus files used as mutation sources in coverage fuzzing."
+msgid "SecurityConfiguration|Manage corpus files used as seed inputs with coverage-guided fuzzing."
msgstr ""
msgid "SecurityConfiguration|Manage profiles for use by DAST scans."
@@ -31812,15 +32488,15 @@ msgstr ""
msgid "SecurityOrchestration|.yaml preview"
msgstr ""
-msgid "SecurityOrchestration|Action"
-msgstr ""
-
msgid "SecurityOrchestration|Actions"
msgstr ""
msgid "SecurityOrchestration|Add rule"
msgstr ""
+msgid "SecurityOrchestration|After dismissing the alert, the information will never be shown again."
+msgstr ""
+
msgid "SecurityOrchestration|All policies"
msgstr ""
@@ -31836,7 +32512,7 @@ msgstr ""
msgid "SecurityOrchestration|Description"
msgstr ""
-msgid "SecurityOrchestration|Disabled"
+msgid "SecurityOrchestration|Don't show the alert anymore"
msgstr ""
msgid "SecurityOrchestration|Edit policy"
@@ -31845,13 +32521,13 @@ msgstr ""
msgid "SecurityOrchestration|Edit policy project"
msgstr ""
-msgid "SecurityOrchestration|Enabled"
+msgid "SecurityOrchestration|Empty policy name"
msgstr ""
-msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Enabled"
msgstr ""
-msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
msgstr ""
msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
@@ -31860,7 +32536,7 @@ msgstr ""
msgid "SecurityOrchestration|Invalid policy type"
msgstr ""
-msgid "SecurityOrchestration|Latest scan"
+msgid "SecurityOrchestration|Latest scan run against %{agent}"
msgstr ""
msgid "SecurityOrchestration|Network"
@@ -31869,15 +32545,27 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No actions defined - policy will not run."
+msgstr ""
+
+msgid "SecurityOrchestration|No description"
+msgstr ""
+
msgid "SecurityOrchestration|No rules defined - policy will not run."
msgstr ""
+msgid "SecurityOrchestration|Not enabled"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
msgid "SecurityOrchestration|Policies"
msgstr ""
+msgid "SecurityOrchestration|Policy Type"
+msgstr ""
+
msgid "SecurityOrchestration|Policy cannot be enabled for non-existing branches (%{branches})"
msgstr ""
@@ -31902,10 +32590,13 @@ msgstr ""
msgid "SecurityOrchestration|Require %{approvals} %{plural} from %{approvers} if any of the following occur:"
msgstr ""
-msgid "SecurityOrchestration|Rule"
+msgid "SecurityOrchestration|Rules"
msgstr ""
-msgid "SecurityOrchestration|Rules"
+msgid "SecurityOrchestration|Runs %{actions} and %{lastAction} scans"
+msgstr ""
+
+msgid "SecurityOrchestration|Runs a %{action} scan"
msgstr ""
msgid "SecurityOrchestration|Scan Execution"
@@ -31965,6 +32656,9 @@ msgstr ""
msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
+msgid "SecurityOrchestration|This view only shows scan results for the agent %{agent}. You can view scan results for all agents in the %{linkStart}Operational Vulnerabilities tab of the vulnerability report%{linkEnd}."
+msgstr ""
+
msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
@@ -32019,9 +32713,6 @@ msgstr ""
msgid "SecurityOrchestration|users with ids"
msgstr ""
-msgid "SecurityOrchestration|view results"
-msgstr ""
-
msgid "SecurityOrchestration|vulnerabilities"
msgstr ""
@@ -32691,22 +33382,19 @@ 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|In order to start using functions as a service, you must first install Knative on your Kubernetes cluster. %{linkStart}More information%{linkEnd}"
-msgstr ""
-
msgid "Serverless|Learn more about Serverless"
msgstr ""
msgid "Serverless|No functions available"
msgstr ""
-msgid "Serverless|Sign up for First Look"
+msgid "Serverless|Serverless was %{linkStart}deprecated%{linkEnd} in GitLab 14.3."
+msgstr ""
+
+msgid "Serverless|Serverless was %{postLinkStart}deprecated%{postLinkEnd}. But if you opt to use it, you must install Knative in your Kubernetes cluster first. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "Serverless|The deploy job has not finished."
@@ -32718,9 +33406,6 @@ 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 ""
@@ -32736,9 +33421,6 @@ msgstr ""
msgid "Service Account Key"
msgstr ""
-msgid "Service Accounts"
-msgstr ""
-
msgid "Service Accounts keys authorize GitLab to deploy your Google Cloud project"
msgstr ""
@@ -32748,10 +33430,10 @@ msgstr ""
msgid "Service Desk allows people to create issues in your GitLab instance without their own user account. It provides a unique email address for end users to create issues in a project. Replies can be sent either through the GitLab interface or by email. End users only see threads through email."
msgstr ""
-msgid "Service Usage Data"
+msgid "Service account generated successfully"
msgstr ""
-msgid "Service account generated successfully"
+msgid "Service accounts"
msgstr ""
msgid "Service ping is disabled in your configuration file, and cannot be enabled through this form."
@@ -32895,6 +33577,9 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
+msgid "Set the per-user rate limit for getting a user by ID via the API."
+msgstr ""
+
msgid "Set the per-user rate limit for notes created by web or API requests."
msgstr ""
@@ -33074,6 +33759,9 @@ msgstr ""
msgid "Shared runners details"
msgstr ""
+msgid "Shared runners enabled cannot be enabled until a valid credit card is on file"
+msgstr ""
+
msgid "Shared runners help link"
msgstr ""
@@ -33131,6 +33819,9 @@ msgstr ""
msgid "Show all issues."
msgstr ""
+msgid "Show all milestones"
+msgstr ""
+
msgid "Show all test cases."
msgstr ""
@@ -33167,6 +33858,9 @@ msgstr ""
msgid "Show file contents"
msgstr ""
+msgid "Show group milestones"
+msgstr ""
+
msgid "Show labels"
msgstr ""
@@ -33182,6 +33876,12 @@ msgstr ""
msgid "Show open epics"
msgstr ""
+msgid "Show project milestones"
+msgstr ""
+
+msgid "Show sub-group milestones"
+msgstr ""
+
msgid "Show the Closed list"
msgstr ""
@@ -33191,11 +33891,6 @@ msgstr ""
msgid "Show whitespace changes"
msgstr ""
-msgid "Showing %d event"
-msgid_plural "Showing %d events"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Showing %{conflict} between %{sourceBranch} and %{targetBranch}"
msgstr ""
@@ -33255,12 +33950,6 @@ msgstr ""
msgid "Sidebar|None"
msgstr ""
-msgid "Sidebar|Only numeral characters allowed"
-msgstr ""
-
-msgid "Sidebar|Weight"
-msgstr ""
-
msgid "Sidekiq job compression threshold (bytes)"
msgstr ""
@@ -33423,6 +34112,9 @@ msgstr ""
msgid "Slack logo"
msgstr ""
+msgid "SlackIntegration|Are you sure you want to remove this project from the Slack application?"
+msgstr ""
+
msgid "SlackIntegration|GitLab for Slack"
msgstr ""
@@ -33432,6 +34124,9 @@ msgstr ""
msgid "SlackIntegration|Project alias"
msgstr ""
+msgid "SlackIntegration|Remove project"
+msgstr ""
+
msgid "SlackIntegration|Select a GitLab project to link with your Slack workspace."
msgstr ""
@@ -33576,9 +34271,6 @@ msgstr ""
msgid "Something went wrong trying to load issue contacts."
msgstr ""
-msgid "Something went wrong when creating a work item. Please try again"
-msgstr ""
-
msgid "Something went wrong when reordering designs. Please try again"
msgstr ""
@@ -33672,9 +34364,6 @@ msgstr ""
msgid "Something went wrong while inserting your image. Please try again."
msgstr ""
-msgid "Something went wrong while merging this merge request. Please try again."
-msgstr ""
-
msgid "Something went wrong while obtaining the Let's Encrypt certificate."
msgstr ""
@@ -33996,10 +34685,10 @@ 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."
+msgid "SourcegraphAdmin|Learn more."
msgstr ""
-msgid "SourcegraphAdmin|More information"
+msgid "SourcegraphAdmin|Only public projects have code intelligence enabled and communicate with Sourcegraph."
msgstr ""
msgid "SourcegraphAdmin|Save changes"
@@ -34008,7 +34697,7 @@ msgstr ""
msgid "SourcegraphAdmin|Sourcegraph URL"
msgstr ""
-msgid "SourcegraphAdmin|e.g. https://sourcegraph.example.com"
+msgid "SourcegraphAdmin|https://sourcegraph.example.com"
msgstr ""
msgid "SourcegraphPreferences|This feature is experimental and currently limited to certain projects."
@@ -34143,6 +34832,9 @@ msgstr ""
msgid "Start date"
msgstr ""
+msgid "Start free trial"
+msgstr ""
+
msgid "Start merge train"
msgstr ""
@@ -34173,6 +34865,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started escalation for this incident."
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -34185,6 +34880,9 @@ msgstr ""
msgid "Starts at (UTC)"
msgstr ""
+msgid "Starts escalations for this incident"
+msgstr ""
+
msgid "Starts on"
msgstr ""
@@ -34446,6 +35144,9 @@ msgstr ""
msgid "Strikethrough"
msgstr ""
+msgid "Strikethrough text"
+msgstr ""
+
msgid "Subgroup information"
msgstr ""
@@ -34680,6 +35381,21 @@ msgstr ""
msgid "Subscriptions"
msgstr ""
+msgid "Subscriptions|Chat with sales"
+msgstr ""
+
+msgid "Subscriptions|Close"
+msgstr ""
+
+msgid "Subscriptions|Not ready to buy yet?"
+msgstr ""
+
+msgid "Subscriptions|Start a free trial"
+msgstr ""
+
+msgid "Subscriptions|We understand. Maybe you have some questions for our sales team, or maybe you'd like to try some of the paid features first. What would you like to do?"
+msgstr ""
+
msgid "Subscription|Your subscription for %{strong}%{namespace_name}%{strong_close} has expired and you are now on %{pricing_link_start}the GitLab Free tier%{pricing_link_end}. Don't worry, your data is safe. Get in touch with our support team (%{support_email}). They'll gladly help with your subscription renewal."
msgstr ""
@@ -34890,6 +35606,9 @@ msgstr ""
msgid "SuperSonics|Maximum users"
msgstr ""
+msgid "SuperSonics|Offline cloud"
+msgstr ""
+
msgid "SuperSonics|Paste your activation code"
msgstr ""
@@ -34956,6 +35675,12 @@ msgstr ""
msgid "SuperSonics|You do not have an active subscription"
msgstr ""
+msgid "SuperSonics|You have a future dated license"
+msgstr ""
+
+msgid "SuperSonics|You have added a license that activates on %{date}. Please see the subscription history table below for more details."
+msgstr ""
+
msgid "SuperSonics|You have successfully added a license that activates on %{date}. Please see the subscription history table below for more details."
msgstr ""
@@ -35115,6 +35840,9 @@ msgstr ""
msgid "Tag name is required"
msgstr ""
+msgid "Tag push"
+msgstr ""
+
msgid "Tag push events"
msgstr ""
@@ -35217,6 +35945,9 @@ msgstr ""
msgid "TagsPage|protected"
msgstr ""
+msgid "Take a look at the documentation to discover all of GitLab’s capabilities."
+msgstr ""
+
msgid "Target Branch"
msgstr ""
@@ -35619,6 +36350,9 @@ msgstr ""
msgid "Tests"
msgstr ""
+msgid "Text (optional)"
+msgstr ""
+
msgid "Text added to the body of all email messages. %{character_limit} character limit"
msgstr ""
@@ -35669,6 +36403,9 @@ msgstr ""
msgid "The CSV export will be created in the background. Once finished, it will be sent to %{email} in an attachment."
msgstr ""
+msgid "The CSV export you requested of all user memberships is attached to this email."
+msgstr ""
+
msgid "The GitLab subscription service (customers.gitlab.com) is currently experiencing an outage. You can monitor the status and get updates at %{linkStart}status.gitlab.com%{linkEnd}."
msgstr ""
@@ -35744,6 +36481,9 @@ 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 epic"
+msgstr ""
+
msgid "The current issue"
msgstr ""
@@ -35905,6 +36645,9 @@ msgstr ""
msgid "The latest pipeline for this merge request has failed."
msgstr ""
+msgid "The license key is invalid."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -35920,6 +36663,9 @@ msgstr ""
msgid "The license was successfully uploaded and will be active from %{starts_at}. You can see the details below."
msgstr ""
+msgid "The license you uploaded is invalid. If the issue persists, contact support at %{link}."
+msgstr ""
+
msgid "The list creation wizard is already open"
msgstr ""
@@ -36541,10 +37287,13 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} and everything this project contains. %{strongOpen}There is no going back%{strongClose}"
+msgstr ""
+
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains."
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}on %{date}%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains. %{strongOpen}There is no going back.%{strongClose}"
msgstr ""
msgid "This action will %{strongOpen}permanently remove%{strongClose} %{codeOpen}%{group}%{codeClose} %{strongOpen}immediately%{strongClose}."
@@ -36673,9 +37422,6 @@ msgstr ""
msgid "This file was modified for readability, and can't accept suggestions. Edit it directly."
msgstr ""
-msgid "This forked project has the following:"
-msgstr ""
-
msgid "This form is disabled in preview"
msgstr ""
@@ -36688,7 +37434,7 @@ msgstr ""
msgid "This group can't be removed because it is linked to a subscription. To remove this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
-msgid "This group can't be transfered because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
+msgid "This group can't be transferred because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
msgid "This group cannot be invited to a project inside a group with enforced SSO"
@@ -36715,6 +37461,9 @@ 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 incident is already escalated with '%{escalation_policy_name}'."
+msgstr ""
+
msgid "This invitation was sent to %{mail_to_invite_email}, but you are signed in as %{link_to_current_user} with email %{mail_to_current_user}."
msgstr ""
@@ -36733,9 +37482,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 merge train pipeline"
-msgstr ""
-
msgid "This is a private email address %{helpIcon} generated just for you. Anyone who has it can create issues or merge requests as if they were you. If that happens, %{resetLinkStart}reset this token%{resetLinkEnd}."
msgstr ""
@@ -36757,6 +37503,12 @@ msgstr ""
msgid "This is your current session"
msgstr ""
+msgid "This issue cannot be assigned to a confidential epic because it is public."
+msgstr ""
+
+msgid "This issue cannot be made public because it belongs to a confidential epic."
+msgstr ""
+
msgid "This issue is confidential and should only be visible to team members with at least Reporter access."
msgstr ""
@@ -36874,6 +37626,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 branch is protected from force push."
+msgstr ""
+
msgid "This merge request cannot be rebased while there are conflicts."
msgstr ""
@@ -36925,9 +37680,15 @@ msgstr ""
msgid "This pipeline was triggered by a schedule."
msgstr ""
+msgid "This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project"
msgstr ""
+msgid "This project can be restored until %{date}."
+msgstr ""
+
msgid "This project cannot be %{visibilityLevel} because the visibility of %{openShowLink}%{name}%{closeShowLink} is %{visibility}. To make this project %{visibilityLevel}, you must first %{openEditLink}change the visibility%{closeEditLink} of the parent group."
msgstr ""
@@ -36946,6 +37707,9 @@ msgstr ""
msgid "This project is %{strongStart}NOT%{strongEnd} a fork, and has the following:"
msgstr ""
+msgid "This project is %{strongStart}NOT%{strongEnd} a fork. This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -37637,6 +38401,9 @@ msgstr ""
msgid "Today"
msgstr ""
+msgid "Todos count"
+msgstr ""
+
msgid "Todos|Are you looking for things to do? Take a look at %{strongStart}%{openIssuesLinkStart}open issues%{openIssuesLinkEnd}%{strongEnd}, contribute to %{strongStart}%{mergeRequestLinkStart}a merge request%{mergeRequestLinkEnd}%{mergeRequestLinkEnd}%{strongEnd}, or mention someone in a comment to automatically assign them a new to-do item."
msgstr ""
@@ -37910,10 +38677,8 @@ msgstr ""
msgid "Trending"
msgstr ""
-msgid "Trials|%{planName} Trial %{enDash} %{num} day left"
-msgid_plural "Trials|%{planName} Trial %{enDash} %{num} days left"
-msgstr[0] ""
-msgstr[1] ""
+msgid "Trials|%{planName} Trial"
+msgstr ""
msgid "Trials|Compare all plans"
msgstr ""
@@ -37921,6 +38686,9 @@ msgstr ""
msgid "Trials|Create a new group to start your GitLab Ultimate trial."
msgstr ""
+msgid "Trials|Day %{daysUsed}/%{duration}"
+msgstr ""
+
msgid "Trials|Go back to GitLab"
msgstr ""
@@ -38170,7 +38938,7 @@ msgstr ""
msgid "URL is triggered when repository is updated"
msgstr ""
-msgid "URL must be percent-encoded if neccessary."
+msgid "URL must be percent-encoded if necessary."
msgstr ""
msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
@@ -38389,6 +39157,9 @@ msgstr ""
msgid "Unlock account"
msgstr ""
+msgid "Unlock more features with GitLab Ultimate"
+msgstr ""
+
msgid "Unlock the discussion"
msgstr ""
@@ -38452,6 +39223,9 @@ msgstr ""
msgid "Unsubscribes from this %{quick_action_target}."
msgstr ""
+msgid "Unsupported sort value."
+msgstr ""
+
msgid "Unsupported todo type passed. Supported todo types are: %{todo_types}"
msgstr ""
@@ -38680,6 +39454,9 @@ msgstr ""
msgid "UsageQuota|File attachments and smaller design graphics."
msgstr ""
+msgid "UsageQuota|From %{storage_enforcement_date} storage limits will apply to this namespace. View and manage your usage in %{strong_start}Group Settings &gt; Usage quotas%{strong_end}."
+msgstr ""
+
msgid "UsageQuota|Git repository."
msgstr ""
@@ -38740,6 +39517,9 @@ msgstr ""
msgid "UsageQuota|Storage type"
msgstr ""
+msgid "UsageQuota|Storage used"
+msgstr ""
+
msgid "UsageQuota|This is the total amount of storage used across your projects within this namespace."
msgstr ""
@@ -38935,6 +39715,12 @@ msgstr ""
msgid "Use hashed storage paths for newly created and renamed repositories. Always enabled since 13.0."
msgstr ""
+msgid "Use issue count"
+msgstr ""
+
+msgid "Use issue weight"
+msgstr ""
+
msgid "Use one line per URI"
msgstr ""
@@ -39316,6 +40102,9 @@ msgstr ""
msgid "Users"
msgstr ""
+msgid "Users API rate limit"
+msgstr ""
+
msgid "Users can launch a development environment from a GitLab browser tab when the %{linkStart}Gitpod%{linkEnd} integration is enabled."
msgstr ""
@@ -39641,6 +40430,9 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View group pipeline usage quota"
+msgstr ""
+
msgid "View incident details at"
msgstr ""
@@ -39793,6 +40585,9 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
+msgid "Vulnerability"
+msgstr ""
+
msgid "Vulnerability Report"
msgstr ""
@@ -39844,6 +40639,9 @@ msgstr ""
msgid "VulnerabilityManagement|An unverified non-confirmed finding"
msgstr ""
+msgid "VulnerabilityManagement|At least one identifier is required"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -39853,12 +40651,24 @@ msgstr ""
msgid "VulnerabilityManagement|Create Jira issue"
msgstr ""
+msgid "VulnerabilityManagement|Enter a name"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE code"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE identifier URL"
+msgstr ""
+
msgid "VulnerabilityManagement|Fetching linked Jira issues"
msgstr ""
msgid "VulnerabilityManagement|Manually add a vulnerability entry into the vulnerability report."
msgstr ""
+msgid "VulnerabilityManagement|Name is a required field"
+msgstr ""
+
msgid "VulnerabilityManagement|Needs triage"
msgstr ""
@@ -39874,6 +40684,18 @@ msgstr ""
msgid "VulnerabilityManagement|Select a method"
msgstr ""
+msgid "VulnerabilityManagement|Select a severity level"
+msgstr ""
+
+msgid "VulnerabilityManagement|Select a status"
+msgstr ""
+
+msgid "VulnerabilityManagement|Severity is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Something went wrong while creating vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -39898,6 +40720,12 @@ msgstr ""
msgid "VulnerabilityManagement|Something went wrong, could not update vulnerability state."
msgstr ""
+msgid "VulnerabilityManagement|Status is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Submit vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Summary, detailed description, steps to reproduce, etc."
msgstr ""
@@ -40093,6 +40921,9 @@ msgstr ""
msgid "WARNING:"
msgstr ""
+msgid "WARNING: This snippet contains hidden files which might be used to mask malicious behavior. Exercise caution if cloning and executing code from this snippet."
+msgstr ""
+
msgid "Wait for the file to load to copy its contents"
msgstr ""
@@ -40312,6 +41143,15 @@ msgstr ""
msgid "Webhooks|An issue is created, updated, closed, or reopened."
msgstr ""
+msgid "Webhooks|Are you sure you want to delete this group hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this project hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this webhook?"
+msgstr ""
+
msgid "Webhooks|Comments"
msgstr ""
@@ -40321,6 +41161,9 @@ msgstr ""
msgid "Webhooks|Confidential issues events"
msgstr ""
+msgid "Webhooks|Delete webhook"
+msgstr ""
+
msgid "Webhooks|Deployment events"
msgstr ""
@@ -40554,6 +41397,9 @@ msgstr ""
msgid "Wiki"
msgstr ""
+msgid "Wiki page"
+msgstr ""
+
msgid "Wiki page was successfully created."
msgstr ""
@@ -40659,7 +41505,7 @@ msgstr ""
msgid "WikiPageConflictMessage|Someone edited the page the same time you did. Please check out %{wikiLinkStart}the page%{wikiLinkEnd} and make sure your changes will not unintentionally remove theirs."
msgstr ""
-msgid "WikiPage|An error occured while trying to render the content editor. Please try again later."
+msgid "WikiPage|An error occurred while trying to render the content editor. Please try again later."
msgstr ""
msgid "WikiPage|Are you sure you want to switch back to the classic editor?"
@@ -40818,6 +41664,18 @@ msgstr ""
msgid "WorkItem|New Task"
msgstr ""
+msgid "WorkItem|Something went wrong when creating a work item. Please try again"
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching the work item. Please try again."
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching work item types. Please try again"
+msgstr ""
+
+msgid "WorkItem|Type"
+msgstr ""
+
msgid "WorkItem|Work Items"
msgstr ""
@@ -40884,7 +41742,10 @@ msgstr ""
msgid "You are about to add %{usersTag} people to the discussion. They will all receive a notification."
msgstr ""
-msgid "You are about to permanently delete this project"
+msgid "You are about to delete this forked project containing:"
+msgstr ""
+
+msgid "You are about to delete this project containing:"
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."
@@ -40905,6 +41766,9 @@ msgstr ""
msgid "You are attempting to update a file that has changed since you started editing it."
msgstr ""
+msgid "You are billed if you exceed this number. %{qsrOverageLinkStart}How does billing work?%{qsrOverageLinkEnd}"
+msgstr ""
+
msgid "You are connected to the Prometheus server, but there is currently no data to display."
msgstr ""
@@ -40962,6 +41826,9 @@ msgstr ""
msgid "You are not authorized to update this scanner profile"
msgstr ""
+msgid "You are not authorized to upload metric images"
+msgstr ""
+
msgid "You are now impersonating %{username}"
msgstr ""
@@ -41115,9 +41982,6 @@ msgstr ""
msgid "You can only upload one design when dropping onto an existing design."
msgstr ""
-msgid "You can recover this project until %{date}"
-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 ""
@@ -41166,9 +42030,6 @@ msgstr ""
msgid "You cannot write to this read-only GitLab instance."
msgstr ""
-msgid "You can’t %{tag_start}edit%{tag_end} files directly in this project. Fork this project and submit a merge request with your changes."
-msgstr ""
-
msgid "You can’t edit files directly in this project. Fork this project and submit a merge request with your changes."
msgstr ""
@@ -41321,9 +42182,6 @@ 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 set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
@@ -41354,12 +42212,6 @@ msgstr ""
msgid "You must have maintainer access to force delete a lock"
msgstr ""
-msgid "You must have permission to create a project in a group before forking."
-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 ""
@@ -41765,7 +42617,7 @@ msgstr ""
msgid "Your public email will be displayed on your public profile."
msgstr ""
-msgid "Your request for access could not be processed: %{error_meesage}"
+msgid "Your request for access could not be processed: %{error_message}"
msgstr ""
msgid "Your request for access has been queued for review."
@@ -41948,6 +42800,9 @@ msgstr ""
msgid "archived:"
msgstr ""
+msgid "artifacts"
+msgstr ""
+
msgid "assign yourself"
msgstr ""
@@ -41977,6 +42832,9 @@ msgstr[1] ""
msgid "branch name"
msgstr ""
+msgid "builds"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -42400,6 +43258,9 @@ msgstr ""
msgid "contact with same email already exists in group hierarchy"
msgstr ""
+msgid "container registry images"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -42439,6 +43300,9 @@ msgstr ""
msgid "data"
msgstr ""
+msgid "database"
+msgstr ""
+
msgid "date must not be after 9999-12-31"
msgstr ""
@@ -42462,9 +43326,6 @@ msgstr ""
msgid "design"
msgstr ""
-msgid "detached"
-msgstr ""
-
msgid "disabled"
msgstr ""
@@ -42713,7 +43574,7 @@ msgstr ""
msgid "is not a valid X509 certificate."
msgstr ""
-msgid "is not allowed for sign-up."
+msgid "is not allowed for sign-up. Please use your regular email address."
msgstr ""
msgid "is not allowed for this group."
@@ -42725,7 +43586,7 @@ msgstr ""
msgid "is not allowed since the group is not top-level group."
msgstr ""
-msgid "is not allowed."
+msgid "is not allowed. Please use your regular email address."
msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
@@ -42812,6 +43673,9 @@ msgstr ""
msgid "level: %{level}"
msgstr ""
+msgid "lfs objects"
+msgstr ""
+
msgid "limit of %{project_limit} reached"
msgstr ""
@@ -43031,6 +43895,9 @@ msgstr ""
msgid "mrWidget|Merge blocked: pipeline must succeed. It's waiting for a manual action to continue."
msgstr ""
+msgid "mrWidget|Merge blocked: pipeline must succeed. Push a commit that fixes the failure, or %{linkStart}learn about other solutions.%{linkEnd}"
+msgstr ""
+
msgid "mrWidget|Merge blocked: this merge request must be approved."
msgstr ""
@@ -43148,9 +44015,6 @@ msgstr ""
msgid "mrWidget|The changes were not merged into"
msgstr ""
-msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -43298,9 +44162,6 @@ msgstr ""
msgid "open issue"
msgstr ""
-msgid "opened %{timeAgo}"
-msgstr ""
-
msgid "or"
msgstr ""
@@ -43312,6 +44173,12 @@ msgid_plural "out of %d total tests"
msgstr[0] ""
msgstr[1] ""
+msgid "packages"
+msgstr ""
+
+msgid "pages"
+msgstr ""
+
msgid "parent"
msgid_plural "parents"
msgstr[0] ""
@@ -43461,6 +44328,9 @@ msgid_plural "replies"
msgstr[0] ""
msgstr[1] ""
+msgid "repositories"
+msgstr ""
+
msgid "repository:"
msgstr ""
@@ -43581,12 +44451,18 @@ msgstr ""
msgid "tag name"
msgstr ""
+msgid "terraform states"
+msgstr ""
+
msgid "the correct format."
msgstr ""
msgid "the file"
msgstr ""
+msgid "the following epic(s)"
+msgstr ""
+
msgid "the following issue(s)"
msgstr ""
@@ -43599,21 +44475,12 @@ msgstr ""
msgid "this document"
msgstr ""
-msgid "this issue cannot be assigned to a confidential epic since it is public"
-msgstr ""
-
-msgid "this issue cannot be made public since it belongs to a confidential epic"
-msgstr ""
-
msgid "time summary"
msgstr ""
msgid "toggle collapse"
msgstr ""
-msgid "train"
-msgstr ""
-
msgid "triggered"
msgstr ""
@@ -43742,3 +44609,6 @@ msgstr ""
msgid "{project}"
msgstr ""
+msgid "✔"
+msgstr ""
+
diff --git a/locale/hr_HR/gitlab.po b/locale/hr_HR/gitlab.po
index a32857f1e13..b0ebaab76a8 100644
--- a/locale/hr_HR/gitlab.po
+++ b/locale/hr_HR/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: hr\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2022-02-02 15:43\n"
+"PO-Revision-Date: 2022-03-01 20:37\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -160,6 +160,12 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
+msgid "%d assigned issue"
+msgid_plural "%d assigned issues"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -490,8 +496,26 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
-msgid "%d vulnerability updated"
-msgid_plural "%d vulnerabilities updated"
+msgid "%d vulnerability set to confirmed"
+msgid_plural "%d vulnerabilities set to confirmed"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
+msgid "%d vulnerability set to dismissed"
+msgid_plural "%d vulnerabilities set to dismissed"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
+msgid "%d vulnerability set to needs triage"
+msgid_plural "%d vulnerabilities set to needs triage"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
+msgid "%d vulnerability set to resolved"
+msgid_plural "%d vulnerabilities set to resolved"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
@@ -586,6 +610,12 @@ msgstr[2] ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{completed} of %{total} issues closed"
+msgstr ""
+
+msgid "%{completed} of %{total} weight completed"
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -940,6 +970,9 @@ msgstr ""
msgid "%{openedIssues} open, %{closedIssues} closed"
msgstr ""
+msgid "%{percentage}%% issues closed"
+msgstr ""
+
msgid "%{percentage}%% weight completed"
msgstr ""
@@ -1384,6 +1417,9 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
+msgid "- of - issues closed"
+msgstr ""
+
msgid "- of - weight completed"
msgstr ""
@@ -1549,7 +1585,7 @@ msgstr ""
msgid "1000+"
msgstr ""
-msgid "192.168.0.0/24"
+msgid "192.168.0.0/24 or 2001:0DB8:1234::/48"
msgstr ""
msgid "1st contribution!"
@@ -1861,13 +1897,13 @@ msgstr ""
msgid "AWS Access Key"
msgstr ""
-msgid "AWS Access Key. Only required if not using role instance credentials"
+msgid "AWS Secret Access Key"
msgstr ""
-msgid "AWS Secret Access Key"
+msgid "AWS access key ID (Optional)"
msgstr ""
-msgid "AWS Secret Access Key. Only required if not using role instance credentials"
+msgid "AWS secret access key (Optional)"
msgstr ""
msgid "AWS service error: %{error}"
@@ -1927,9 +1963,6 @@ msgstr ""
msgid "Access granted"
msgstr ""
-msgid "Access key ID"
-msgstr ""
-
msgid "Access requests"
msgstr ""
@@ -2104,7 +2137,7 @@ msgstr ""
msgid "Activity"
msgstr ""
-msgid "Activity|An error occured while retrieving activity. Reload the page to try again."
+msgid "Activity|An error occurred while retrieving activity. Reload the page to try again."
msgstr ""
msgid "Add"
@@ -2143,6 +2176,9 @@ msgstr ""
msgid "Add a %{type}"
msgstr ""
+msgid "Add a GCP region"
+msgstr ""
+
msgid "Add a GPG key"
msgstr ""
@@ -2194,6 +2230,9 @@ msgstr ""
msgid "Add a numbered list"
msgstr ""
+msgid "Add a related epic"
+msgstr ""
+
msgid "Add a related issue"
msgstr ""
@@ -2308,6 +2347,9 @@ msgstr ""
msgid "Add or subtract spent time"
msgstr ""
+msgid "Add people"
+msgstr ""
+
msgid "Add previously merged commits"
msgstr ""
@@ -2374,6 +2416,9 @@ msgstr ""
msgid "Add webhook"
msgstr ""
+msgid "Add your team members and others to GitLab."
+msgstr ""
+
msgid "Add/remove"
msgstr ""
@@ -3196,12 +3241,6 @@ msgstr ""
msgid "AdvancedSearch|Reindex required"
msgstr ""
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. Permanently deleting this project will %{strongStart}immediately delete%{strongEnd} its repositories and %{strongStart}all related resources%{strongEnd}, including issues, merge requests etc."
-msgstr ""
-
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. You will lose this project's repository and %{strongStart}all related resources%{strongEnd}, including issues and merge requests."
-msgstr ""
-
msgid "After a successful password update you will be redirected to login screen."
msgstr ""
@@ -3232,6 +3271,9 @@ msgstr ""
msgid "Akismet helps prevent the creation of spam issues in public projects."
msgstr ""
+msgid "Alert"
+msgstr ""
+
msgid "AlertManagement|Acknowledged"
msgstr ""
@@ -3604,9 +3646,6 @@ msgstr ""
msgid "All environments"
msgstr ""
-msgid "All epics"
-msgstr ""
-
msgid "All groups and projects"
msgstr ""
@@ -4345,13 +4384,16 @@ msgstr ""
msgid "ApplicationSettings|Approve users in the pending approval status?"
msgstr ""
-msgid "ApplicationSettings|By making this change, you will automatically approve %d user with the pending approval status."
-msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users with the pending approval status."
+msgid "ApplicationSettings|Approve users who are pending approval?"
+msgstr ""
+
+msgid "ApplicationSettings|By making this change, you will automatically approve %d user who is pending approval."
+msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users who are pending approval."
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
-msgid "ApplicationSettings|By making this change, you will automatically approve all users in pending approval status."
+msgid "ApplicationSettings|By making this change, you will automatically approve all users who are pending approval."
msgstr ""
msgid "ApplicationSettings|Denied domains for sign-ups"
@@ -4762,10 +4804,10 @@ msgstr ""
msgid "Archiving the project will make it entirely read-only. It is hidden from the dashboard and doesn't show up in searches. %{strong_start}The repository cannot be committed to, and no issues, comments, or other entities can be created.%{strong_end} %{link_start}Learn more.%{link_end}"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to delete this project?"
+msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
+msgid "Are you absolutely sure?"
msgstr ""
msgid "Are you sure that you want to archive this project?"
@@ -4801,12 +4843,18 @@ msgstr ""
msgid "Are you sure you want to delete this SSH key?"
msgstr ""
+msgid "Are you sure you want to delete this comment?"
+msgstr ""
+
msgid "Are you sure you want to delete this deploy key?"
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 label?"
+msgstr ""
+
msgid "Are you sure you want to delete this pipeline schedule?"
msgstr ""
@@ -4822,9 +4870,6 @@ msgstr ""
msgid "Are you sure you want to discard your changes?"
msgstr ""
-msgid "Are you sure you want to erase this build?"
-msgstr ""
-
msgid "Are you sure you want to import %d repository?"
msgid_plural "Are you sure you want to import %d repositories?"
msgstr[0] ""
@@ -4873,6 +4918,9 @@ msgstr ""
msgid "Are you sure you want to remove this list?"
msgstr ""
+msgid "Are you sure you want to remove this nickname?"
+msgstr ""
+
msgid "Are you sure you want to reset the health check token?"
msgstr ""
@@ -4885,10 +4933,10 @@ 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?"
+msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
msgstr ""
-msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
+msgid "Are you sure you want to revoke this project access token? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to stop this environment?"
@@ -5035,9 +5083,6 @@ msgstr ""
msgid "Assigned to %{assignee_name}"
msgstr ""
-msgid "Assigned to %{name}"
-msgstr ""
-
msgid "Assigned to me"
msgstr ""
@@ -5104,6 +5149,9 @@ msgstr[2] ""
msgid "Attaching the file failed."
msgstr ""
+msgid "Attention"
+msgstr ""
+
msgid "Audit Events"
msgstr ""
@@ -5266,6 +5314,12 @@ msgstr ""
msgid "Authorized applications (%{size})"
msgstr ""
+msgid "AuthorizedApplication|Are you sure you want to revoke this application?"
+msgstr ""
+
+msgid "AuthorizedApplication|Revoke application"
+msgstr ""
+
msgid "Authors: %{authors}"
msgstr ""
@@ -6463,6 +6517,9 @@ msgstr ""
msgid "CICDAnalytics|Shared Runners Usage"
msgstr ""
+msgid "CICDAnalytics|Shared runner pipeline minute duration by month"
+msgstr ""
+
msgid "CICDAnalytics|Shared runner usage"
msgstr ""
@@ -6604,6 +6661,9 @@ msgstr ""
msgid "Can create groups:"
msgstr ""
+msgid "Can not delete primary training"
+msgstr ""
+
msgid "Can't apply as the source branch was deleted."
msgstr ""
@@ -6937,9 +6997,6 @@ msgstr ""
msgid "Changing any setting here requires an application restart"
msgstr ""
-msgid "Changing group URL can have unintended side effects."
-msgstr ""
-
msgid "Charts can't be displayed as the request for data has timed out. %{documentationLink}"
msgstr ""
@@ -7027,9 +7084,6 @@ msgstr ""
msgid "Checking branch availability..."
msgstr ""
-msgid "Checking group URL availability..."
-msgstr ""
-
msgid "Checking group path availability..."
msgstr ""
@@ -7525,6 +7579,9 @@ msgstr ""
msgid "Clear recent searches"
msgstr ""
+msgid "Clear repository checks"
+msgstr ""
+
msgid "Clear search"
msgstr ""
@@ -7657,9 +7714,6 @@ msgstr ""
msgid "Closed MRs"
msgstr ""
-msgid "Closed epics"
-msgstr ""
-
msgid "Closed issues"
msgstr ""
@@ -7696,13 +7750,13 @@ msgstr ""
msgid "Cluster level"
msgstr ""
-msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
+msgid "Cluster type must be specified for Stages::ClusterEndpointInserter"
msgstr ""
msgid "ClusterAgents|%{name} successfully deleted"
msgstr ""
-msgid "ClusterAgents|%{number} of %{total} Agents"
+msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
@@ -7744,6 +7798,15 @@ msgstr ""
msgid "ClusterAgents|Agent never connected to GitLab"
msgstr ""
+msgid "ClusterAgents|Agent version mismatch"
+msgstr ""
+
+msgid "ClusterAgents|Agent version mismatch and update"
+msgstr ""
+
+msgid "ClusterAgents|Agent version update required"
+msgstr ""
+
msgid "ClusterAgents|All"
msgstr ""
@@ -7768,7 +7831,7 @@ msgstr ""
msgid "ClusterAgents|Configuration"
msgstr ""
-msgid "ClusterAgents|Connect a cluster through the Agent"
+msgid "ClusterAgents|Connect a cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connect existing cluster"
@@ -7777,13 +7840,13 @@ msgstr ""
msgid "ClusterAgents|Connect with a certificate"
msgstr ""
-msgid "ClusterAgents|Connect with agent"
+msgid "ClusterAgents|Connect with an agent"
msgstr ""
msgid "ClusterAgents|Connect with the GitLab Agent"
msgstr ""
-msgid "ClusterAgents|Connect your cluster through the Agent"
+msgid "ClusterAgents|Connect your cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connected"
@@ -7843,7 +7906,10 @@ msgstr ""
msgid "ClusterAgents|How to register an agent?"
msgstr ""
-msgid "ClusterAgents|Install new Agent"
+msgid "ClusterAgents|How to update an agent?"
+msgstr ""
+
+msgid "ClusterAgents|Install a new agent"
msgstr ""
msgid "ClusterAgents|Last connected %{timeAgo}."
@@ -7870,7 +7936,7 @@ msgstr ""
msgid "ClusterAgents|Never connected"
msgstr ""
-msgid "ClusterAgents|No Agents"
+msgid "ClusterAgents|No agents"
msgstr ""
msgid "ClusterAgents|No clusters connected through cluster certificates"
@@ -7930,6 +7996,9 @@ msgstr ""
msgid "ClusterAgents|The agent has not been connected in a long time. There might be a connectivity issue. Last contact was %{timeAgo}."
msgstr ""
+msgid "ClusterAgents|The agent version do not match each other across your cluster's pods. This can happen when a new agent version was just deployed and Kubernetes is shutting down the old pods."
+msgstr ""
+
msgid "ClusterAgents|The recommended installation method includes the token. If you want to follow the advanced installation method provided in the docs, make sure you save the token value before you close this window."
msgstr ""
@@ -7978,6 +8047,9 @@ msgstr ""
msgid "ClusterAgents|You will need to create a token to connect to your agent"
msgstr ""
+msgid "ClusterAgents|Your agent version is out of sync with your GitLab version (v%{version}), which might cause compatibility problems. Update the agent installed on your cluster to the most recent version."
+msgstr ""
+
msgid "ClusterAgents|Your instance doesn't have the %{linkStart}GitLab Agent Server (KAS)%{linkEnd} set up. Ask a GitLab Administrator to install it."
msgstr ""
@@ -8854,9 +8926,6 @@ msgstr ""
msgid "Comma-separated list of email addresses."
msgstr ""
-msgid "Comma-separated list of users allowed to exceed the rate limit."
-msgstr ""
-
msgid "Comma-separated, e.g. '1.1.1.1, 2.2.2.0/24'"
msgstr ""
@@ -9184,6 +9253,12 @@ msgstr ""
msgid "Confidential"
msgstr ""
+msgid "Confidential issue"
+msgstr ""
+
+msgid "Confidential note"
+msgstr ""
+
msgid "Confidentiality"
msgstr ""
@@ -9217,6 +9292,9 @@ msgstr ""
msgid "Configure Dependency Scanning in `.gitlab-ci.yml`, creating this file if it does not already exist"
msgstr ""
+msgid "Configure GitLab"
+msgstr ""
+
msgid "Configure GitLab runners to start using the Web Terminal. %{helpStart}Learn more.%{helpEnd}"
msgstr ""
@@ -9265,6 +9343,15 @@ msgstr ""
msgid "Configure pipelines to deploy web apps, backend services, APIs and static resources to Google Cloud"
msgstr ""
+msgid "Configure region"
+msgstr ""
+
+msgid "Configure region for environment"
+msgstr ""
+
+msgid "Configure regions"
+msgstr ""
+
msgid "Configure repository mirroring."
msgstr ""
@@ -9298,6 +9385,9 @@ msgstr ""
msgid "Configure which lists are shown for anyone who visits this board"
msgstr ""
+msgid "Configure your environments to be deployed to specific geographical regions"
+msgstr ""
+
msgid "Confirm"
msgstr ""
@@ -10003,10 +10093,10 @@ msgstr ""
msgid "CorpusManagement|Actions"
msgstr ""
-msgid "CorpusManagement|Corpus are used in fuzz testing as mutation source to Improve future testing."
+msgid "CorpusManagement|Corpus file"
msgstr ""
-msgid "CorpusManagement|Corpus file"
+msgid "CorpusManagement|Corpus files are used in coverage-guided fuzz testing as seed inputs to improve testing."
msgstr ""
msgid "CorpusManagement|Corpus files must be in *.zip format. Maximum 5 GB"
@@ -10060,6 +10150,9 @@ msgstr ""
msgid "Could not apply %{name} command."
msgstr ""
+msgid "Could not apply %{name} command. %{message}."
+msgstr ""
+
msgid "Could not authorize chat nickname. Try again!"
msgstr ""
@@ -10210,6 +10303,9 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
+msgid "Create a group"
+msgstr ""
+
msgid "Create a merge request"
msgstr ""
@@ -10234,6 +10330,9 @@ msgstr ""
msgid "Create a personal access token on your account to pull or push via %{protocol}."
msgstr ""
+msgid "Create a project"
+msgstr ""
+
msgid "Create an account using:"
msgstr ""
@@ -10597,6 +10696,9 @@ msgstr ""
msgid "Creation date"
msgstr ""
+msgid "Creator"
+msgstr ""
+
msgid "Credentials"
msgstr ""
@@ -10609,9 +10711,15 @@ msgstr ""
msgid "CredentialsInventory|Personal Access Tokens"
msgstr ""
+msgid "CredentialsInventory|Project Access Tokens"
+msgstr ""
+
msgid "CredentialsInventory|SSH Keys"
msgstr ""
+msgid "Credit card required to be on file in order to create a pipeline"
+msgstr ""
+
msgid "Credit card:"
msgstr ""
@@ -10795,9 +10903,6 @@ msgstr ""
msgid "Customer relations"
msgstr ""
-msgid "Customizable by an administrator."
-msgstr ""
-
msgid "Customizable by owners."
msgstr ""
@@ -10927,30 +11032,18 @@ msgstr ""
msgid "CycleAnalytics|%{selectedLabelsCount} selected (%{maxLabels} max)"
msgstr ""
-msgid "CycleAnalytics|%{stageCount} stages selected"
-msgstr ""
-
-msgid "CycleAnalytics|All stages"
-msgstr ""
-
-msgid "CycleAnalytics|Average days to completion"
+msgid "CycleAnalytics|Average time to completion"
msgstr ""
msgid "CycleAnalytics|Date"
msgstr ""
-msgid "CycleAnalytics|Days to completion"
-msgstr ""
-
msgid "CycleAnalytics|Display chart filters"
msgstr ""
msgid "CycleAnalytics|Lead Time for Changes"
msgstr ""
-msgid "CycleAnalytics|No stages selected"
-msgstr ""
-
msgid "CycleAnalytics|Number of tasks"
msgstr ""
@@ -10981,18 +11074,30 @@ msgstr ""
msgid "CycleAnalytics|Showing data for group '%{groupName}' from %{createdAfter} to %{createdBefore}"
msgstr ""
-msgid "CycleAnalytics|Stages"
+msgid "CycleAnalytics|Stage time: %{title}"
msgstr ""
msgid "CycleAnalytics|Tasks by type"
msgstr ""
-msgid "CycleAnalytics|The average time spent in the selected stage for the items that were completed on each date. Data limited to the last 500 items."
+msgid "CycleAnalytics|The average time items spent in this stage. Data limited to items completed within this date range."
msgstr ""
msgid "CycleAnalytics|The given date range is larger than 180 days"
msgstr ""
+msgid "CycleAnalytics|The total time items spent across each value stream stage. Data limited to items completed within this date range."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Stage time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Total time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|Total time"
+msgstr ""
+
msgid "CycleAnalytics|Type of work"
msgstr ""
@@ -11005,9 +11110,6 @@ msgstr ""
msgid "CycleAnalytics|project dropdown filter"
msgstr ""
-msgid "CycleAnalytics|stage dropdown"
-msgstr ""
-
msgid "DAG visualization requires at least 3 dependent jobs."
msgstr ""
@@ -11107,10 +11209,16 @@ msgstr ""
msgid "DastProfiles|AJAX spider"
msgstr ""
+msgid "DastProfiles|API"
+msgstr ""
+
+msgid "DastProfiles|API endpoint URL"
+msgstr ""
+
msgid "DastProfiles|Active"
msgstr ""
-msgid "DastProfiles|Additional request headers (Optional)"
+msgid "DastProfiles|Additional request headers (optional)"
msgstr ""
msgid "DastProfiles|Are you sure you want to delete this profile?"
@@ -11125,6 +11233,9 @@ msgstr ""
msgid "DastProfiles|Branch missing"
msgstr ""
+msgid "DastProfiles|Choose a scan method"
+msgstr ""
+
msgid "DastProfiles|Could not create the scanner profile. Please try again."
msgstr ""
@@ -11194,7 +11305,13 @@ msgstr ""
msgid "DastProfiles|Excluded URLs"
msgstr ""
-msgid "DastProfiles|Excluded URLs (Optional)"
+msgid "DastProfiles|Excluded URLs (optional)"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths (optional)"
msgstr ""
msgid "DastProfiles|Hide debug messages"
@@ -11251,9 +11368,6 @@ msgstr ""
msgid "DastProfiles|Request headers"
msgstr ""
-msgid "DastProfiles|Rest API"
-msgstr ""
-
msgid "DastProfiles|Run the AJAX spider, in addition to the traditional spider, to crawl the target site."
msgstr ""
@@ -11263,6 +11377,9 @@ msgstr ""
msgid "DastProfiles|Save profile"
msgstr ""
+msgid "DastProfiles|Scan method"
+msgstr ""
+
msgid "DastProfiles|Scan mode"
msgstr ""
@@ -11341,12 +11458,24 @@ msgstr ""
msgid "DastProfiles|Website"
msgstr ""
+msgid "DastProfiles|What does each method do?"
+msgstr ""
+
msgid "DastProfiles|You can either choose a passive scan or validate the target site from the site profile management page. %{docsLinkStart}Learn more about site validation.%{docsLinkEnd}"
msgstr ""
msgid "DastProfiles|You cannot run an active scan against an unvalidated site."
msgstr ""
+msgid "DastProfiles|folder/dast_example.har or https://example.com/dast_example.har"
+msgstr ""
+
+msgid "DastProfiles|folder/example.postman_collection.json or https://example.com/"
+msgstr ""
+
+msgid "DastProfiles|folder/openapi.json or https://example.com/openapi.json"
+msgstr ""
+
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
@@ -11455,6 +11584,9 @@ msgstr ""
msgid "DatadogIntegration|API URL"
msgstr ""
+msgid "DatadogIntegration|Custom tags in Datadog. Enter one tag per line in the %{codeOpen}key:value%{codeClose} format. %{linkOpen}How do I use tags?%{linkClose}"
+msgstr ""
+
msgid "DatadogIntegration|Environment"
msgstr ""
@@ -11473,12 +11605,18 @@ msgstr ""
msgid "DatadogIntegration|Tag all data from this GitLab instance in Datadog. Useful when managing several self-managed deployments."
msgstr ""
+msgid "DatadogIntegration|Tags"
+msgstr ""
+
msgid "DatadogIntegration|The Datadog site to send data to. To send data to the EU site, use %{codeOpen}datadoghq.eu%{codeClose}."
msgstr ""
msgid "DatadogIntegration|Trace your GitLab pipelines with Datadog."
msgstr ""
+msgid "DatadogIntegration|have an invalid format"
+msgstr ""
+
msgid "Datasource name not found"
msgstr ""
@@ -11488,9 +11626,6 @@ msgstr ""
msgid "Date merged"
msgstr ""
-msgid "Date picker"
-msgstr ""
-
msgid "Date range"
msgstr ""
@@ -11644,9 +11779,6 @@ msgstr ""
msgid "Definition"
msgstr ""
-msgid "Delayed Project Deletion (%{adjourned_deletion})"
-msgstr ""
-
msgid "DelayedJobs|Are you sure you want to run %{jobName} immediately? Otherwise this job will run automatically after its timer finishes."
msgstr ""
@@ -11725,10 +11857,10 @@ msgstr ""
msgid "Delete pipeline"
msgstr ""
-msgid "Delete project"
+msgid "Delete pipeline schedule"
msgstr ""
-msgid "Delete project. Are you ABSOLUTELY SURE?"
+msgid "Delete project"
msgstr ""
msgid "Delete row"
@@ -11758,6 +11890,9 @@ msgstr ""
msgid "Delete this epic and all descendants?"
msgstr ""
+msgid "Delete this project"
+msgstr ""
+
msgid "Delete user list"
msgstr ""
@@ -12022,6 +12157,12 @@ msgstr ""
msgid "Deploy to..."
msgstr ""
+msgid "DeployBoards|To see deployment progress for your environments, make sure you are deploying to %{codeStart}$KUBE_NAMESPACE%{codeEnd} and annotating with %{codeStart}app.gitlab.com/app=$CI_PROJECT_PATH_SLUG%{codeEnd} and %{codeStart}app.gitlab.com/env=$CI_ENVIRONMENT_SLUG%{codeEnd}."
+msgstr ""
+
+msgid "DeployBoard|Kubernetes Pods"
+msgstr ""
+
msgid "DeployFreeze|Add a freeze period to prevent unintended releases during a period of time for a given environment. You must update the deployment jobs in %{filename} according to the deploy freezes added here. %{freeze_period_link_start}Learn more.%{freeze_period_link_end}"
msgstr ""
@@ -12106,9 +12247,6 @@ msgstr ""
msgid "DeployTokens|Active Deploy Tokens (%{active_tokens})"
msgstr ""
-msgid "DeployTokens|Allows read and write access to registry images."
-msgstr ""
-
msgid "DeployTokens|Allows read and write access to the package registry."
msgstr ""
@@ -12121,6 +12259,9 @@ msgstr ""
msgid "DeployTokens|Allows read-only access to the repository."
msgstr ""
+msgid "DeployTokens|Allows write access to registry images."
+msgstr ""
+
msgid "DeployTokens|Copy deploy token"
msgstr ""
@@ -12214,12 +12355,57 @@ msgstr ""
msgid "Deploying to AWS is easy with GitLab"
msgstr ""
+msgid "Deployment"
+msgstr ""
+
msgid "Deployment Frequency"
msgstr ""
+msgid "Deployment Target|Project deployment target (optional)"
+msgstr ""
+
+msgid "Deployment Target|Select the deployment target"
+msgstr ""
+
msgid "Deployment frequency"
msgstr ""
+msgid "DeploymentTarget|GitLab Pages"
+msgstr ""
+
+msgid "DeploymentTarget|Heroku"
+msgstr ""
+
+msgid "DeploymentTarget|Infrastructure provider (Terraform, Cloudformation, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Kubernetes (GKE, EKS, OpenShift, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Managed container runtime (Fargate, Cloud Run, DigitalOcean App)"
+msgstr ""
+
+msgid "DeploymentTarget|Mobile app store"
+msgstr ""
+
+msgid "DeploymentTarget|No deployment planned"
+msgstr ""
+
+msgid "DeploymentTarget|Other hosting service"
+msgstr ""
+
+msgid "DeploymentTarget|Registry (package or container)"
+msgstr ""
+
+msgid "DeploymentTarget|Self-managed container runtime (Podman, Docker Swarm, Docker Compose)"
+msgstr ""
+
+msgid "DeploymentTarget|Serverless backend (Lambda, Cloud functions)"
+msgstr ""
+
+msgid "DeploymentTarget|Virtual machine (for example, EC2)"
+msgstr ""
+
msgid "Deployments"
msgstr ""
@@ -12259,6 +12445,9 @@ msgstr ""
msgid "Deployment|This deployment was created using the API"
msgstr ""
+msgid "Deployment|Triggerer"
+msgstr ""
+
msgid "Deployment|Waiting"
msgstr ""
@@ -12286,6 +12475,18 @@ msgstr ""
msgid "Deprecated API rate limits"
msgstr ""
+msgid "Deprecations|Feature deprecation and removal"
+msgstr ""
+
+msgid "Deprecations|For information on a possible replacement %{epicStart} learn more about Opstrace %{epicEnd}."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7 and are %{epicStart} scheduled for removal %{epicEnd} in GitLab 15.0."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7, and are %{removal_link_start} scheduled for removal %{link_end} in GitLab 15.0. For information on a possible replacement, %{opstrace_link_start} learn more about Opstrace %{link_end}."
+msgstr ""
+
msgid "Deprioritize label"
msgstr ""
@@ -12532,10 +12733,10 @@ msgstr ""
msgid "DevopsAdoption|At least one deploy"
msgstr ""
-msgid "DevopsAdoption|At least one issue opened"
+msgid "DevopsAdoption|At least one issue created"
msgstr ""
-msgid "DevopsAdoption|At least one merge request opened"
+msgid "DevopsAdoption|At least one merge request created"
msgstr ""
msgid "DevopsAdoption|At least one pipeline successfully run"
@@ -12739,6 +12940,9 @@ msgstr ""
msgid "Direct member"
msgstr ""
+msgid "Direct members"
+msgstr ""
+
msgid "Direct non-authenticated users to this page."
msgstr ""
@@ -12856,6 +13060,9 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
+msgid "Dismiss Alert"
+msgstr ""
+
msgid "Dismiss merge request promotion"
msgstr ""
@@ -12883,9 +13090,15 @@ msgstr ""
msgid "Display alerts from all configured monitoring tools."
msgstr ""
+msgid "Display milestones"
+msgstr ""
+
msgid "Display name"
msgstr ""
+msgid "Display progress of child issues"
+msgstr ""
+
msgid "Display rendered file"
msgstr ""
@@ -12991,6 +13204,9 @@ msgstr ""
msgid "Download image"
msgstr ""
+msgid "Download payload"
+msgstr ""
+
msgid "Download raw data (.csv)"
msgstr ""
@@ -13168,6 +13384,9 @@ msgstr ""
msgid "Edit in Web IDE"
msgstr ""
+msgid "Edit in pipeline editor"
+msgstr ""
+
msgid "Edit in single-file editor"
msgstr ""
@@ -13210,6 +13429,9 @@ msgstr ""
msgid "Edit your most recent comment in a thread (from an empty textarea)"
msgstr ""
+msgid "Edit, lint, and visualize your pipeline."
+msgstr ""
+
msgid "Edited"
msgstr ""
@@ -13651,6 +13873,9 @@ msgstr ""
msgid "Enforce two-factor authentication for all user sign-ins."
msgstr ""
+msgid "Enhance security by storing service account keys in secret managers - learn more about %{docLinkStart}secret management with GitLab%{docLinkEnd}"
+msgstr ""
+
msgid "Ensure connectivity is available from the GitLab server to the Prometheus server"
msgstr ""
@@ -13711,6 +13936,9 @@ 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 following to confirm:"
+msgstr ""
+
msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
@@ -14242,9 +14470,6 @@ 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 ""
@@ -14380,6 +14605,9 @@ msgstr ""
msgid "Errors:"
msgstr ""
+msgid "Escalate this incident"
+msgstr ""
+
msgid "Escalation Policies"
msgstr ""
@@ -14392,6 +14620,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy"
+msgstr ""
+
msgid "Escalation policy:"
msgstr ""
@@ -14644,6 +14875,9 @@ msgstr ""
msgid "Existing sign in methods may be removed"
msgstr ""
+msgid "Exit."
+msgstr ""
+
msgid "Expand"
msgstr ""
@@ -14740,6 +14974,9 @@ msgstr ""
msgid "Explore public groups"
msgstr ""
+msgid "Explore public projects"
+msgstr ""
+
msgid "Explore snippets"
msgstr ""
@@ -14902,7 +15139,7 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
-msgid "Failed to assign a reviewer because no user was found."
+msgid "Failed to assign a reviewer because no user was specified."
msgstr ""
msgid "Failed to assign a user because no user was found."
@@ -14968,10 +15205,10 @@ msgstr ""
msgid "Failed to find import label for Jira import."
msgstr ""
-msgid "Failed to generate export, please try again later."
+msgid "Failed to find users for %{missing}"
msgstr ""
-msgid "Failed to generate report, please try again after sometime"
+msgid "Failed to generate export, please try again later."
msgstr ""
msgid "Failed to get ref."
@@ -15070,6 +15307,9 @@ msgstr ""
msgid "Failed to remove a to-do item for the design."
msgstr ""
+msgid "Failed to remove attention because no user was found."
+msgstr ""
+
msgid "Failed to remove mirror."
msgstr ""
@@ -15082,6 +15322,9 @@ msgstr ""
msgid "Failed to remove user key."
msgstr ""
+msgid "Failed to request attention because no user was found."
+msgstr ""
+
msgid "Failed to reset key. Please try again."
msgstr ""
@@ -15163,6 +15406,9 @@ msgstr ""
msgid "Feature Flags"
msgstr ""
+msgid "Feature deprecation and removal"
+msgstr ""
+
msgid "Feature flag status"
msgstr ""
@@ -15661,7 +15907,7 @@ msgstr ""
msgid "For each job, re-use the project workspace. If the workspace doesn't exist, use %{code_open}git clone%{code_close}."
msgstr ""
-msgid "For example, the application using the token or the purpose of the token."
+msgid "For example, the application using the token or the purpose of the token. Do not give sensitive information for the name of the token, as it will be visible to all %{resource_type} members."
msgstr ""
msgid "For files larger than this limit, only index the file name. The file content is neither indexed nor searchable."
@@ -15745,9 +15991,6 @@ msgstr ""
msgid "ForkProject|Select a namespace"
msgstr ""
-msgid "ForkProject|Select a namespace to fork the project"
-msgstr ""
-
msgid "ForkProject|The project can be accessed by any logged in user."
msgstr ""
@@ -15844,6 +16087,9 @@ msgstr ""
msgid "Full name"
msgstr ""
+msgid "GCP region configured"
+msgstr ""
+
msgid "GPG Key ID:"
msgstr ""
@@ -16024,6 +16270,9 @@ msgstr ""
msgid "Geo|Failed"
msgstr ""
+msgid "Geo|Filter Geo sites"
+msgstr ""
+
msgid "Geo|Filter by name"
msgstr ""
@@ -16435,6 +16684,12 @@ msgstr ""
msgid "GitLab Issue"
msgstr ""
+msgid "GitLab KAS"
+msgstr ""
+
+msgid "GitLab Memberships CSV Export"
+msgstr ""
+
msgid "GitLab Pages"
msgstr ""
@@ -16483,6 +16738,9 @@ 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 free to use. Many features for larger teams are part of our %{link_start}paid products%{link_end}. You can try Ultimate for free without any obligation or payment details."
+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 ""
@@ -16609,7 +16867,7 @@ msgstr ""
msgid "GitLabPages|When enabled, all attempts to visit your website through HTTP are automatically redirected to HTTPS using a response with status code 301. Requires a valid certificate for all domains. %{docs_link_start}Learn more.%{link_end}"
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. %{docs_link_start}Learn more.%{link_end}"
+msgid "GitLabPages|When using Pages under the general domain of a GitLab instance (%{pages_host}), you cannot use HTTPS with subdomains of subdomains. If your namespace or groupname contains a dot, it does not work. This is a limitation of the HTTP Over TLS protocol. HTTP pages work if you don't redirect HTTP to HTTPS. %{docs_link_start}Learn more.%{link_end}"
msgstr ""
msgid "GitLabPages|With GitLab Pages you can host your static website directly from your GitLab repository. %{docs_link_start}Learn more.%{link_end}"
@@ -16786,9 +17044,6 @@ msgstr ""
msgid "Go to find file"
msgstr ""
-msgid "Go to fork"
-msgstr ""
-
msgid "Go to issue boards"
msgstr ""
@@ -16996,9 +17251,6 @@ msgstr ""
msgid "Group Hooks"
msgstr ""
-msgid "Group ID"
-msgstr ""
-
msgid "Group Owner must have signed in with SAML before enabling Group Managed Accounts"
msgstr ""
@@ -17026,9 +17278,6 @@ msgstr ""
msgid "Group by"
msgstr ""
-msgid "Group description"
-msgstr ""
-
msgid "Group description (optional)"
msgstr ""
@@ -17143,7 +17392,7 @@ msgstr ""
msgid "Group: %{name}"
msgstr ""
-msgid "GroupActivityMetrics|Issues opened"
+msgid "GroupActivityMetrics|Issues created"
msgstr ""
msgid "GroupActivityMetrics|Last 90 days"
@@ -17152,7 +17401,7 @@ msgstr ""
msgid "GroupActivityMetrics|Members added"
msgstr ""
-msgid "GroupActivityMetrics|Merge Requests opened"
+msgid "GroupActivityMetrics|Merge Requests created"
msgstr ""
msgid "GroupActivityMetrics|Recent activity"
@@ -17443,6 +17692,9 @@ msgstr ""
msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
+msgid "GroupSettings|Choose a group path that does not start with a dash or end with a period. It can also contain alphanumeric characters and underscores."
+msgstr ""
+
msgid "GroupSettings|Compliance frameworks"
msgstr ""
@@ -17476,7 +17728,7 @@ msgstr ""
msgid "GroupSettings|If not specified at the group or instance level, the default is %{default_initial_branch_name}. Does not affect existing repositories."
msgstr ""
-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."
+msgid "GroupSettings|If the parent group's visibility is lower than the group's current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility."
msgstr ""
msgid "GroupSettings|New runners registration token has been generated!"
@@ -17593,7 +17845,10 @@ msgstr ""
msgid "Groups and projects"
msgstr ""
-msgid "Groups and subgroups"
+msgid "Groups are a great way to organize projects and people."
+msgstr ""
+
+msgid "Groups are the best way to manage projects and members."
msgstr ""
msgid "Groups to synchronize"
@@ -17704,13 +17959,16 @@ msgstr ""
msgid "GroupsTree|Are you sure you want to leave the \"%{fullName}\" group?"
msgstr ""
-msgid "GroupsTree|Edit group"
+msgid "GroupsTree|Delete"
+msgstr ""
+
+msgid "GroupsTree|Edit"
msgstr ""
msgid "GroupsTree|Failed to leave the group. Please make sure you are not the only owner."
msgstr ""
-msgid "GroupsTree|Leave this group"
+msgid "GroupsTree|Leave group"
msgstr ""
msgid "GroupsTree|Loading groups"
@@ -17722,9 +17980,57 @@ msgstr ""
msgid "GroupsTree|No groups or projects matched your search"
msgstr ""
+msgid "GroupsTree|Options"
+msgstr ""
+
msgid "GroupsTree|Search by name"
msgstr ""
+msgid "Groups|Avatar will be removed. Are you sure?"
+msgstr ""
+
+msgid "Groups|Changing group URL can have unintended side effects."
+msgstr ""
+
+msgid "Groups|Checking group URL availability..."
+msgstr ""
+
+msgid "Groups|Enter a descriptive name for your group."
+msgstr ""
+
+msgid "Groups|Group ID"
+msgstr ""
+
+msgid "Groups|Group URL"
+msgstr ""
+
+msgid "Groups|Group avatar"
+msgstr ""
+
+msgid "Groups|Group description (optional)"
+msgstr ""
+
+msgid "Groups|Group name"
+msgstr ""
+
+msgid "Groups|Group path is available."
+msgstr ""
+
+msgid "Groups|Group path is unavailable. Path has been replaced with a suggested available path."
+msgstr ""
+
+msgid "Groups|Learn more"
+msgstr ""
+
+msgid "Groups|Must start with letter, digit, emoji, or underscore. Can also contain periods, dashes, spaces, and parentheses."
+msgstr ""
+
+msgid "Groups|Remove avatar"
+msgstr ""
+
+msgid "Groups|Save changes"
+msgstr ""
+
msgid "Guideline"
msgstr ""
@@ -17734,6 +18040,9 @@ msgstr ""
msgid "HAR file path or URL"
msgstr ""
+msgid "HTTP Archive (HAR)"
+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 ""
@@ -18136,6 +18445,9 @@ msgstr ""
msgid "INFO: Your SSH key is expiring soon. Please generate a new key."
msgstr ""
+msgid "IP"
+msgstr ""
+
msgid "IP Address"
msgstr ""
@@ -18172,6 +18484,9 @@ msgstr ""
msgid "IdentityVerification|Verify your identity"
msgstr ""
+msgid "IdentityVerification|You can always verify your account at a later time to create a group."
+msgstr ""
+
msgid "If any indexed field exceeds this limit, it is truncated to this number of characters. The rest of the content is neither indexed nor searchable. This does not apply to repository and wiki indexing. For unlimited characters, set this to 0."
msgstr ""
@@ -18229,6 +18544,9 @@ msgstr ""
msgid "If you add %{codeStart}needs%{codeEnd} to jobs in your pipeline you'll be able to view the %{codeStart}needs%{codeEnd} relationships between jobs in this tab as a %{linkStart}Directed Acyclic Graph (DAG)%{linkEnd}."
msgstr ""
+msgid "If you are added to a project, it will be displayed here."
+msgstr ""
+
msgid "If you did not initiate these sign-in attempts, please reach out to your administrator or enable two-factor authentication (2FA) on your account."
msgstr ""
@@ -18538,12 +18856,24 @@ msgstr ""
msgid "InProductMarketing|3 ways to dive into GitLab CI/CD"
msgstr ""
+msgid "InProductMarketing|A single application eliminates complex integrations, data chokepoints, and toolchain maintenance, resulting in greater productivity and lower cost."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features, build more efficiently, strengthen security and compliance."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features."
+msgstr ""
+
msgid "InProductMarketing|Actually, GitLab makes the team work (better)"
msgstr ""
msgid "InProductMarketing|And finally %{deploy_link} a Python application."
msgstr ""
+msgid "InProductMarketing|And many more..."
+msgstr ""
+
msgid "InProductMarketing|Are your runners ready?"
msgstr ""
@@ -18562,15 +18892,33 @@ msgstr ""
msgid "InProductMarketing|Blog"
msgstr ""
+msgid "InProductMarketing|Break down silos to coordinate seamlessly across development, operations, and security with a consistent experience across the development lifecycle."
+msgstr ""
+
+msgid "InProductMarketing|Burn up/down charts"
+msgstr ""
+
msgid "InProductMarketing|By enabling code owners and required merge approvals the right person will review the right MR. This is a win-win: cleaner code and a more efficient review process."
msgstr ""
msgid "InProductMarketing|Click on the number below that corresponds with your answer — 1 being very difficult, 5 being very easy."
msgstr ""
+msgid "InProductMarketing|Code owners"
+msgstr ""
+
msgid "InProductMarketing|Code owners and required merge approvals are part of the paid tiers of GitLab. You can start a free 30-day trial of GitLab Ultimate and enable these features in less than 5 minutes with no credit card required."
msgstr ""
+msgid "InProductMarketing|Code review analytics"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration across stages in GitLab"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration made easy"
+msgstr ""
+
msgid "InProductMarketing|Create a custom CI runner with just a few clicks"
msgstr ""
@@ -18580,12 +18928,21 @@ msgstr ""
msgid "InProductMarketing|Create a project in GitLab in 5 minutes"
msgstr ""
+msgid "InProductMarketing|Create well-defined workflows by using scoped labels on issues, merge requests, and epics. Labels with the same scope cannot be used together, which prevents conflicts."
+msgstr ""
+
msgid "InProductMarketing|Create your first project!"
msgstr ""
+msgid "InProductMarketing|Define who owns specific files or directories, so the right reviewers are suggested when a merge request introduces changes to those files."
+msgstr ""
+
msgid "InProductMarketing|Deliver Better Products Faster"
msgstr ""
+msgid "InProductMarketing|Dependency scanning"
+msgstr ""
+
msgid "InProductMarketing|Did you know teams that use GitLab are far more efficient?"
msgstr ""
@@ -18595,15 +18952,27 @@ msgstr ""
msgid "InProductMarketing|Dig in and create a project and a repo"
msgstr ""
+msgid "InProductMarketing|Discover Premium & Ultimate"
+msgstr ""
+
+msgid "InProductMarketing|Discover Premium & Ultimate."
+msgstr ""
+
msgid "InProductMarketing|Do you have a minute?"
msgstr ""
msgid "InProductMarketing|Do you have a teammate who would be perfect for this task?"
msgstr ""
+msgid "InProductMarketing|Dynamic application security testing"
+msgstr ""
+
msgid "InProductMarketing|Easy"
msgstr ""
+msgid "InProductMarketing|Epics"
+msgstr ""
+
msgid "InProductMarketing|Expand your DevOps journey with a free GitLab trial"
msgstr ""
@@ -18625,9 +18994,15 @@ msgstr ""
msgid "InProductMarketing|Feel the need for speed?"
msgstr ""
+msgid "InProductMarketing|Find and fix bottlenecks in your code review process by understanding how long open merge requests have been in review."
+msgstr ""
+
msgid "InProductMarketing|Find out how your teams are really doing"
msgstr ""
+msgid "InProductMarketing|Find out if your external libraries are safe. Run dependency scanning jobs that check for known vulnerabilities in your external libraries."
+msgstr ""
+
msgid "InProductMarketing|Follow our steps"
msgstr ""
@@ -18664,6 +19039,9 @@ msgstr ""
msgid "InProductMarketing|GitLab is better with teammates to help out!"
msgstr ""
+msgid "InProductMarketing|GitLab is infrastructure agnostic (supporting GCP, AWS, Azure, OpenShift, VMWare, On Prem, Bare Metal, and more), offering a consistent workflow experience – irrespective of the environment."
+msgstr ""
+
msgid "InProductMarketing|GitLab provides static application security testing (SAST), dynamic application security testing (DAST), container scanning, and dependency scanning to help you deliver secure applications along with license compliance."
msgstr ""
@@ -18754,21 +19132,36 @@ msgstr ""
msgid "InProductMarketing|It's also possible to simply %{external_repo_link} in order to take advantage of GitLab's CI/CD."
msgstr ""
+msgid "InProductMarketing|Keep your code quality high by defining who should approve merge requests and how many approvals are required."
+msgstr ""
+
msgid "InProductMarketing|Launch GitLab CI/CD in 20 minutes or less"
msgstr ""
+msgid "InProductMarketing|Lower cost of development"
+msgstr ""
+
+msgid "InProductMarketing|Make it easier to collaborate on high-level ideas by grouping related issues in an epic."
+msgstr ""
+
msgid "InProductMarketing|Making the switch? It's easier than you think to import your projects into GitLab. Move %{github_link}, or import something %{bitbucket_link}."
msgstr ""
msgid "InProductMarketing|Master the art of importing!"
msgstr ""
+msgid "InProductMarketing|Merge request approval rule"
+msgstr ""
+
msgid "InProductMarketing|Move on to easily creating a Pages website %{ci_template_link}"
msgstr ""
msgid "InProductMarketing|Multiple owners, confusing workstreams? We've got you covered"
msgstr ""
+msgid "InProductMarketing|Multiple required approvers"
+msgstr ""
+
msgid "InProductMarketing|Need an alternative to importing?"
msgstr ""
@@ -18781,18 +19174,33 @@ msgstr ""
msgid "InProductMarketing|Our tool brings all the things together"
msgstr ""
+msgid "InProductMarketing|Protect your web application by using DAST to examine for vulnerabilities in deployed environments."
+msgstr ""
+
msgid "InProductMarketing|Rapid development, simplified"
msgstr ""
msgid "InProductMarketing|Reduce Security & Compliance Risk"
msgstr ""
+msgid "InProductMarketing|Require multiple approvers on a merge request, so you know it's in good shape before it's merged."
+msgstr ""
+
+msgid "InProductMarketing|Roadmaps"
+msgstr ""
+
+msgid "InProductMarketing|Scoped labels"
+msgstr ""
+
msgid "InProductMarketing|Security that's integrated into your development lifecycle"
msgstr ""
msgid "InProductMarketing|Sometimes you're not ready to make a full transition to a new tool. If you're not ready to fully commit, %{mirroring_link} gives you a safe way to try out GitLab in parallel with your current tool."
msgstr ""
+msgid "InProductMarketing|Speed. Efficiency. Trust."
+msgstr ""
+
msgid "InProductMarketing|Spin up an autoscaling runner in GitLab"
msgstr ""
@@ -18802,6 +19210,9 @@ msgstr ""
msgid "InProductMarketing|Start a Self-Managed trial"
msgstr ""
+msgid "InProductMarketing|Start a free trial"
+msgstr ""
+
msgid "InProductMarketing|Start a free trial of GitLab Ultimate – no credit card required"
msgstr ""
@@ -18868,6 +19279,9 @@ msgstr ""
msgid "InProductMarketing|To understand and get the most out of GitLab, start at the beginning and %{project_link}. In GitLab, repositories are part of a project, so after you've created your project you can go ahead and %{repo_link}."
msgstr ""
+msgid "InProductMarketing|Track completed issues in a chart, so you can see how a milestone is progressing at a glance."
+msgstr ""
+
msgid "InProductMarketing|Try GitLab Ultimate for free"
msgstr ""
@@ -18904,6 +19318,9 @@ msgstr ""
msgid "InProductMarketing|Very easy"
msgstr ""
+msgid "InProductMarketing|Visualize your epics and milestones in a timeline."
+msgstr ""
+
msgid "InProductMarketing|Want to host GitLab on your servers?"
msgstr ""
@@ -18925,6 +19342,9 @@ msgstr ""
msgid "InProductMarketing|YouTube"
msgstr ""
+msgid "InProductMarketing|Your software, deployed your way"
+msgstr ""
+
msgid "InProductMarketing|Your teams can be more efficient"
msgstr ""
@@ -19045,9 +19465,18 @@ msgstr ""
msgid "IncidentManagement|No incidents to display."
msgstr ""
+msgid "IncidentManagement|None"
+msgstr ""
+
msgid "IncidentManagement|Open"
msgstr ""
+msgid "IncidentManagement|Page your team with escalation policies"
+msgstr ""
+
+msgid "IncidentManagement|Paged"
+msgstr ""
+
msgid "IncidentManagement|Published"
msgstr ""
@@ -19057,6 +19486,9 @@ msgstr ""
msgid "IncidentManagement|Severity"
msgstr ""
+msgid "IncidentManagement|Status"
+msgstr ""
+
msgid "IncidentManagement|There are no closed incidents"
msgstr ""
@@ -19075,6 +19507,9 @@ msgstr ""
msgid "IncidentManagement|Unpublished"
msgstr ""
+msgid "IncidentManagement|Use escalation policies to automatically page your team when incidents are created."
+msgstr ""
+
msgid "IncidentSettings|Activate \"time to SLA\" countdown timer"
msgstr ""
@@ -19120,7 +19555,10 @@ msgstr ""
msgid "Incidents"
msgstr ""
-msgid "Incidents|Add a URL"
+msgid "Incidents|Add image details"
+msgstr ""
+
+msgid "Incidents|Add text or a link to display with your image. If you don't add either, the file name displays instead."
msgstr ""
msgid "Incidents|Drop or %{linkStart}upload%{linkEnd} a metric screenshot to attach it to the incident"
@@ -19135,10 +19573,10 @@ msgstr ""
msgid "Incidents|There was an issue loading metric images."
msgstr ""
-msgid "Incidents|There was an issue uploading your image."
+msgid "Incidents|There was an issue updating your image."
msgstr ""
-msgid "Incidents|You can optionally add a URL to link users to the original graph."
+msgid "Incidents|There was an issue uploading your image."
msgstr ""
msgid "Incident|Alert details"
@@ -19147,9 +19585,18 @@ msgstr ""
msgid "Incident|Are you sure you wish to delete this image?"
msgstr ""
+msgid "Incident|Delete image"
+msgstr ""
+
msgid "Incident|Deleting %{filename}"
msgstr ""
+msgid "Incident|Edit image text or link"
+msgstr ""
+
+msgid "Incident|Editing %{filename}"
+msgstr ""
+
msgid "Incident|Metrics"
msgstr ""
@@ -19420,12 +19867,18 @@ msgstr ""
msgid "Integrations|Branches for which notifications are to be sent"
msgstr ""
+msgid "Integrations|Clear if using a self-signed certificate."
+msgstr ""
+
msgid "Integrations|Comment detail:"
msgstr ""
msgid "Integrations|Comment settings:"
msgstr ""
+msgid "Integrations|Connection details"
+msgstr ""
+
msgid "Integrations|Connection failed. Please check your settings."
msgstr ""
@@ -19450,6 +19903,9 @@ msgstr ""
msgid "Integrations|Enable GitLab.com slash commands in a Slack workspace."
msgstr ""
+msgid "Integrations|Enable SSL verification"
+msgstr ""
+
msgid "Integrations|Enable comments"
msgstr ""
@@ -19528,6 +19984,9 @@ msgstr ""
msgid "Integrations|Return to GitLab for Jira"
msgstr ""
+msgid "Integrations|SSL verification"
+msgstr ""
+
msgid "Integrations|Save settings?"
msgstr ""
@@ -19573,9 +20032,6 @@ msgstr ""
msgid "Integrations|Use default settings"
msgstr ""
-msgid "Integrations|When you mention a Jira issue in a commit or merge request, GitLab creates a remote link and comment (if enabled)."
-msgstr ""
-
msgid "Integrations|You can now close this window and return to the GitLab for Jira application."
msgstr ""
@@ -19600,9 +20056,6 @@ msgstr ""
msgid "Integrations|can't exceed %{recipients_limit}"
msgstr ""
-msgid "Interactive developer security education."
-msgstr ""
-
msgid "Interactive mode"
msgstr ""
@@ -20092,6 +20545,9 @@ msgstr ""
msgid "IssueAnalytics|Assignees"
msgstr ""
+msgid "IssueAnalytics|Created by"
+msgstr ""
+
msgid "IssueAnalytics|Due date"
msgstr ""
@@ -20104,9 +20560,6 @@ msgstr ""
msgid "IssueAnalytics|Milestone"
msgstr ""
-msgid "IssueAnalytics|Opened by"
-msgstr ""
-
msgid "IssueAnalytics|Status"
msgstr ""
@@ -20230,10 +20683,10 @@ msgstr ""
msgid "IssuesAnalytics|Avg/Month:"
msgstr ""
-msgid "IssuesAnalytics|Issues opened"
+msgid "IssuesAnalytics|Issues created"
msgstr ""
-msgid "IssuesAnalytics|Issues opened per month"
+msgid "IssuesAnalytics|Issues created per month"
msgstr ""
msgid "IssuesAnalytics|Last 12 months"
@@ -20260,6 +20713,9 @@ msgstr ""
msgid "It looks like you have some draft commits in this branch."
msgstr ""
+msgid "It looks like you're attempting to activate your subscription. Use %{a_start}the Subscription page%{a_end} instead."
+msgstr ""
+
msgid "It may be several days before you see feature usage data."
msgstr ""
@@ -20488,6 +20944,9 @@ msgstr ""
msgid "JiraConnect|You can now close this window and return to Jira."
msgstr ""
+msgid "JiraConnect|You don't have permission to create branches for this project. Select a different project or contact the project owner for access. %{linkStart}Learn more.%{linkEnd}"
+msgstr ""
+
msgid "JiraRequest|A connection error occurred while connecting to Jira. Try your request again."
msgstr ""
@@ -20536,13 +20995,13 @@ msgstr ""
msgid "JiraService|Define the type of Jira issue to create from a vulnerability."
msgstr ""
-msgid "JiraService|Displaying Jira issues while leaving the GitLab issue functionality enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
+msgid "JiraService|Displaying Jira issues while leaving GitLab issues also enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
msgstr ""
-msgid "JiraService|Enable Jira issues"
+msgid "JiraService|Enable Jira issue creation from vulnerabilities"
msgstr ""
-msgid "JiraService|Enable Jira issues creation from vulnerabilities"
+msgid "JiraService|Enable Jira issues"
msgstr ""
msgid "JiraService|Enable Jira transitions"
@@ -20659,16 +21118,19 @@ msgstr ""
msgid "JiraService|View Jira issues in GitLab"
msgstr ""
-msgid "JiraService|Warning: All GitLab users that have access to this GitLab project are able to view all issues from the Jira project specified below."
+msgid "JiraService|Warning: All GitLab users with access to this GitLab project can view all issues from the Jira project you select."
msgstr ""
msgid "JiraService|Web URL"
msgstr ""
-msgid "JiraService|Work on Jira issues without leaving GitLab. Adds a Jira menu to access your list of Jira issues and view any issue as read-only."
+msgid "JiraService|When a Jira issue is mentioned in a commit or merge request, a remote link and comment (if enabled) will be created."
+msgstr ""
+
+msgid "JiraService|Work on Jira issues without leaving GitLab. Add a Jira menu to access a read-only list of your Jira issues."
msgstr ""
-msgid "JiraService|You need to configure Jira before enabling this integration. For more details, read the %{jira_doc_link_start}Jira integration documentation%{link_end}."
+msgid "JiraService|You must configure Jira before enabling this integration. %{jira_doc_link_start}Learn more.%{link_end}"
msgstr ""
msgid "Job"
@@ -20680,9 +21142,6 @@ msgstr ""
msgid "Job Failed #%{build_id}"
msgstr ""
-msgid "Job ID"
-msgstr ""
-
msgid "Job artifact"
msgstr ""
@@ -20749,9 +21208,27 @@ msgstr ""
msgid "Jobs|You're about to retry a job that failed because it attempted to deploy code that is older than the latest deployment. Retrying this job could result in overwriting the environment with the older source code."
msgstr ""
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source} into %{target}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{ref}"
+msgstr ""
+
+msgid "Job|Are you sure you want to erase this job log and artifacts?"
+msgstr ""
+
msgid "Job|Browse"
msgstr ""
+msgid "Job|Cancel"
+msgstr ""
+
msgid "Job|Complete Raw"
msgstr ""
@@ -20761,6 +21238,9 @@ msgstr ""
msgid "Job|Erase job log and artifacts"
msgstr ""
+msgid "Job|Finished at"
+msgstr ""
+
msgid "Job|Job artifacts"
msgstr ""
@@ -20773,7 +21253,7 @@ msgstr ""
msgid "Job|Keep"
msgstr ""
-msgid "Job|Pipeline"
+msgid "Job|Retry"
msgstr ""
msgid "Job|Scroll to bottom"
@@ -20785,6 +21265,9 @@ msgstr ""
msgid "Job|Show complete raw"
msgstr ""
+msgid "Job|Status"
+msgstr ""
+
msgid "Job|The artifacts were removed"
msgstr ""
@@ -20812,21 +21295,12 @@ msgstr ""
msgid "Job|delayed"
msgstr ""
-msgid "Job|for"
-msgstr ""
-
-msgid "Job|into"
-msgstr ""
-
msgid "Job|manual"
msgstr ""
msgid "Job|triggered"
msgstr ""
-msgid "Job|with"
-msgstr ""
-
msgid "Join Zoom meeting"
msgstr ""
@@ -20929,9 +21403,6 @@ msgstr ""
msgid "Ki"
msgstr ""
-msgid "Kontra"
-msgstr ""
-
msgid "Kroki"
msgstr ""
@@ -21256,6 +21727,9 @@ msgstr ""
msgid "Learn more about Auto DevOps"
msgstr ""
+msgid "Learn more about GitLab"
+msgstr ""
+
msgid "Learn more about Needs relationships"
msgstr ""
@@ -21589,9 +22063,18 @@ msgstr ""
msgid "Licenses|Displays licenses detected in the project, based on the %{linkStart}latest successful%{linkEnd} scan"
msgstr ""
+msgid "Licenses|Drag your license file here or %{linkStart}click to upload%{linkEnd}."
+msgstr ""
+
+msgid "Licenses|Drop your license file to start the upload."
+msgstr ""
+
msgid "Licenses|Error fetching the license list. Please check your network connection and try again."
msgstr ""
+msgid "Licenses|Error: You are trying to upload something other than a file"
+msgstr ""
+
msgid "Licenses|License Compliance"
msgstr ""
@@ -21610,6 +22093,9 @@ msgstr ""
msgid "Licenses|Specified policies in this project"
msgstr ""
+msgid "Licenses|The file could not be uploaded."
+msgstr ""
+
msgid "Licenses|The license list details information about the licenses used within your project."
msgstr ""
@@ -21643,12 +22129,6 @@ msgstr ""
msgid "Limit the size of Sidekiq jobs stored in Redis."
msgstr ""
-msgid "Limited to showing %d event at most"
-msgid_plural "Limited to showing %d events at most"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-
msgid "Limiting mode"
msgstr ""
@@ -21658,6 +22138,9 @@ msgstr ""
msgid "Link"
msgstr ""
+msgid "Link (optional)"
+msgstr ""
+
msgid "Link Prometheus monitoring to GitLab."
msgstr ""
@@ -21694,6 +22177,9 @@ msgstr ""
msgid "Linked emails (%{email_count})"
msgstr ""
+msgid "Linked epics"
+msgstr ""
+
msgid "Linked issues"
msgstr ""
@@ -21721,6 +22207,15 @@ msgstr ""
msgid "List of all merge commits"
msgstr ""
+msgid "List of environments for this project"
+msgstr ""
+
+msgid "List of suitable GCP locations"
+msgstr ""
+
+msgid "List of users allowed to exceed the rate limit."
+msgstr ""
+
msgid "List options"
msgstr ""
@@ -21940,6 +22435,9 @@ msgstr ""
msgid "Maintenance mode"
msgstr ""
+msgid "Make adjustments to how your GitLab instance is set up."
+msgstr ""
+
msgid "Make and review changes in the browser with the Web IDE"
msgstr ""
@@ -22084,6 +22582,12 @@ msgstr ""
msgid "MarkdownEditor|Add italic text (%{modifier_key}I)"
msgstr ""
+msgid "MarkdownEditor|Add strikethrough text (%{modifierKey}⇧X)"
+msgstr ""
+
+msgid "MarkdownEditor|Add strikethrough text (%{modifier_key}⇧X)"
+msgstr ""
+
msgid "Marked For Deletion At - %{deletion_time}"
msgstr ""
@@ -22345,6 +22849,9 @@ msgstr ""
msgid "Maximum push size (MB)"
msgstr ""
+msgid "Maximum requests per 10 minutes per user"
+msgstr ""
+
msgid "Maximum requests per minute"
msgstr ""
@@ -22435,6 +22942,21 @@ msgstr ""
msgid "Members of a group may only view projects they have permission to access"
msgstr ""
+msgid "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seat in use and will be billed for the overage."
+msgid_plural "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seats in use and will be billed for the overage."
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
+msgid "MembersOverage|You are about to incur additional charges"
+msgstr ""
+
+msgid "MembersOverage|Your subscription includes %d seat."
+msgid_plural "MembersOverage|Your subscription includes %d seats."
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
msgid "Membership"
msgstr ""
@@ -22639,9 +23161,6 @@ msgstr ""
msgid "Merge request not merged"
msgstr ""
-msgid "Merge request pipelines 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 merge request pipelines."
-msgstr ""
-
msgid "Merge request reports"
msgstr ""
@@ -22738,13 +23257,13 @@ msgstr ""
msgid "MergeRequests|Create issue to resolve thread"
msgstr ""
-msgid "MergeRequests|Failed to squash. Should be done manually."
+msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Saving the comment failed"
+msgid "MergeRequests|Squashing failed: Squash the commits locally, resolve any conflicts, then push the branch."
msgstr ""
-msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
+msgid "MergeRequests|Squashing not allowed: This project doesn't allow you to squash commits when merging."
msgstr ""
msgid "MergeRequests|Thread stays resolved"
@@ -23587,6 +24106,18 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "MrList|Assigned to %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from assignee %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from reviewer %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Review requested from %{name}, go to their profile."
+msgstr ""
+
msgid "Multi-project"
msgstr ""
@@ -23620,7 +24151,7 @@ msgstr ""
msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "My Awesome Group"
+msgid "My awesome group"
msgstr ""
msgid "My company or team"
@@ -24244,9 +24775,6 @@ msgstr ""
msgid "No available branches"
msgstr ""
-msgid "No available groups to fork the project."
-msgstr ""
-
msgid "No branches found"
msgstr ""
@@ -24457,6 +24985,9 @@ msgstr ""
msgid "No ref selected"
msgstr ""
+msgid "No regions configured"
+msgstr ""
+
msgid "No related merge requests found."
msgstr ""
@@ -25267,6 +25798,9 @@ msgstr ""
msgid "Only reCAPTCHA v2 is supported:"
msgstr ""
+msgid "Only required if not using role instance credentials."
+msgstr ""
+
msgid "Only use lowercase letters, numbers, and underscores."
msgstr ""
@@ -25291,9 +25825,6 @@ msgstr ""
msgid "Open a CLI and connect to the cluster you want to install the agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
-msgid "Open epics"
-msgstr ""
-
msgid "Open errors"
msgstr ""
@@ -25333,7 +25864,7 @@ msgstr ""
msgid "Opened issues"
msgstr ""
-msgid "OpenedNDaysAgo|Opened"
+msgid "OpenedNDaysAgo|Created"
msgstr ""
msgid "Opens in a new window"
@@ -25378,9 +25909,6 @@ msgstr ""
msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
-msgid "Optional."
-msgstr ""
-
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
msgstr ""
@@ -26170,6 +26698,9 @@ msgstr ""
msgid "PerformanceBar|Memory"
msgstr ""
+msgid "PerformanceBar|Memory report"
+msgstr ""
+
msgid "PerformanceBar|Redis calls"
msgstr ""
@@ -26203,18 +26734,12 @@ msgstr ""
msgid "PerformanceBar|wall"
msgstr ""
-msgid "Performs a rebase but skips triggering a new pipeline"
-msgstr ""
-
msgid "Period in seconds"
msgstr ""
msgid "Permalink"
msgstr ""
-msgid "Permanently delete project"
-msgstr ""
-
msgid "Permanently remove group"
msgstr ""
@@ -26485,6 +27010,51 @@ msgstr ""
msgid "PipelineStatusTooltip|Pipeline: %{ci_status}"
msgstr ""
+msgid "PipelineWizardDefaultCommitMessage|Add %{filename}"
+msgstr ""
+
+msgid "PipelineWizardDefaultCommitMessage|Update %{filename}"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|At least one entry is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This field is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This value is not valid"
+msgstr ""
+
+msgid "PipelineWizardListWidget|add another step"
+msgstr ""
+
+msgid "PipelineWizardListWidget|remove step"
+msgstr ""
+
+msgid "PipelineWizard|Commit"
+msgstr ""
+
+msgid "PipelineWizard|Commit Message"
+msgstr ""
+
+msgid "PipelineWizard|Commit changes to your file"
+msgstr ""
+
+msgid "PipelineWizard|Commit file to Branch"
+msgstr ""
+
+msgid "PipelineWizard|Commit your new file"
+msgstr ""
+
+msgid "PipelineWizard|The file has been committed."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem committing the changes."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem while checking whether your file already exists in the specified branch."
+msgstr ""
+
msgid "Pipelines"
msgstr ""
@@ -26599,7 +27169,7 @@ msgstr ""
msgid "Pipelines|Project cache successfully reset."
msgstr ""
-msgid "Pipelines|Revoke"
+msgid "Pipelines|Revoke trigger"
msgstr ""
msgid "Pipelines|Something went wrong while cleaning runners cache."
@@ -26644,6 +27214,12 @@ msgstr ""
msgid "Pipelines|This is a child pipeline within the parent pipeline"
msgstr ""
+msgid "Pipelines|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipelines|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipelines|This pipeline will run code originating from a forked project merge request. This means that the code can potentially have security considerations like exposing CI variables."
msgstr ""
@@ -26686,9 +27262,6 @@ msgstr ""
msgid "Pipelines|Your changes have been successfully committed. Now redirecting to the new merge request page."
msgstr ""
-msgid "Pipelines|detached"
-msgstr ""
-
msgid "Pipelines|error"
msgstr ""
@@ -26698,10 +27271,13 @@ msgstr ""
msgid "Pipelines|latest"
msgstr ""
-msgid "Pipelines|stuck"
+msgid "Pipelines|merge request"
msgstr ""
-msgid "Pipelines|train"
+msgid "Pipelines|merge train"
+msgstr ""
+
+msgid "Pipelines|stuck"
msgstr ""
msgid "Pipelines|yaml invalid"
@@ -26833,6 +27409,12 @@ msgstr ""
msgid "Pipeline|This change will not change the overall test coverage if merged."
msgstr ""
+msgid "Pipeline|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipeline|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipeline|Trigger author"
msgstr ""
@@ -26857,6 +27439,12 @@ msgstr ""
msgid "Pipeline|for"
msgstr ""
+msgid "Pipeline|merge request"
+msgstr ""
+
+msgid "Pipeline|merge train"
+msgstr ""
+
msgid "Pipeline|on"
msgstr ""
@@ -26995,9 +27583,6 @@ msgstr ""
msgid "Please enter a valid time interval"
msgstr ""
-msgid "Please enter or upload a valid license."
-msgstr ""
-
msgid "Please enter your current password."
msgstr ""
@@ -27106,9 +27691,6 @@ msgstr ""
msgid "Please type %{phrase_code} to proceed or close this modal to cancel."
msgstr ""
-msgid "Please type the following to confirm:"
-msgstr ""
-
msgid "Please use this form to report to the admin users who create spam issues, comments or behave inappropriately."
msgstr ""
@@ -27136,12 +27718,27 @@ msgstr ""
msgid "Policies"
msgstr ""
+msgid "Policy '%{escalation_policy_name}' does not exist."
+msgstr ""
+
msgid "Policy management project does have any policies in %{policy_path}"
msgstr ""
msgid "Policy project doesn't exist"
msgstr ""
+msgid "PolicyRuleMultiSelect|%{firstLabel} +%{numberOfAdditionalLabels} more"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|All %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select all"
+msgstr ""
+
msgid "Polling interval multiplier"
msgstr ""
@@ -27370,6 +27967,9 @@ msgstr ""
msgid "Private projects can be created in your personal namespace with:"
msgstr ""
+msgid "Problem with %{name} command: %{message}."
+msgstr ""
+
msgid "Proceed"
msgstr ""
@@ -27844,6 +28444,9 @@ msgstr ""
msgid "Progress"
msgstr ""
+msgid "Progress tracking"
+msgstr ""
+
msgid "Project"
msgstr ""
@@ -28075,6 +28678,9 @@ msgstr ""
msgid "ProjectQualitySummary|Failure"
msgstr ""
+msgid "ProjectQualitySummary|Get insight into the overall percentage of tests in your project that succeed, fail and are skipped."
+msgstr ""
+
msgid "ProjectQualitySummary|Latest pipeline results"
msgstr ""
@@ -28093,6 +28699,12 @@ msgstr ""
msgid "ProjectQualitySummary|See project Code Coverage Statistics"
msgstr ""
+msgid "ProjectQualitySummary|Set up test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|Set up test runs (opens in a new tab)"
+msgstr ""
+
msgid "ProjectQualitySummary|Skipped"
msgstr ""
@@ -28369,13 +28981,19 @@ msgstr ""
msgid "ProjectSettings|LFS objects from this repository are available to forks. %{linkStart}How do I remove them?%{linkEnd}"
msgstr ""
+msgid "ProjectSettings|Learn about commit history."
+msgstr ""
+
+msgid "ProjectSettings|Leave empty to use default template."
+msgstr ""
+
msgid "ProjectSettings|Manage who can see the project in the public access directory."
msgstr ""
msgid "ProjectSettings|Manages large files such as audio, video, and graphics files."
msgstr ""
-msgid "ProjectSettings|Maximum 500 characters."
+msgid "ProjectSettings|Maximum %{maxLength} characters."
msgstr ""
msgid "ProjectSettings|Merge checks"
@@ -28516,6 +29134,9 @@ msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
msgstr ""
+msgid "ProjectSettings|The default template will be applied on save."
+msgstr ""
+
msgid "ProjectSettings|These checks must pass before merge requests can be merged."
msgstr ""
@@ -28570,6 +29191,9 @@ msgstr ""
msgid "ProjectSettings|What are badges?"
msgstr ""
+msgid "ProjectSettings|What are merge trains?"
+msgstr ""
+
msgid "ProjectSettings|When merge request pipelines are enabled in the CI/CD configuration file, pipelines validate the combined results of the source and target branches. %{link_start}How to configure merge request pipelines?%{link_end}"
msgstr ""
@@ -28687,6 +29311,9 @@ msgstr ""
msgid "Projects are organized into groups"
msgstr ""
+msgid "Projects are where you store your code, access issues, wiki and other features of GitLab."
+msgstr ""
+
msgid "Projects contributed to"
msgstr ""
@@ -28702,12 +29329,6 @@ msgstr ""
msgid "Projects to index"
msgstr ""
-msgid "Projects will be permanently deleted after a %{waiting_period}-day waiting period."
-msgstr ""
-
-msgid "Projects will be permanently deleted immediately."
-msgstr ""
-
msgid "Projects with critical vulnerabilities"
msgstr ""
@@ -28792,6 +29413,9 @@ msgstr ""
msgid "ProjectsNew|Import project"
msgstr ""
+msgid "ProjectsNew|Include a Getting Started README"
+msgstr ""
+
msgid "ProjectsNew|Initialize repository with a README"
msgstr ""
@@ -28807,6 +29431,9 @@ msgstr ""
msgid "ProjectsNew|Project description %{tag_start}(optional)%{tag_end}"
msgstr ""
+msgid "ProjectsNew|Recommended if you're new to GitLab"
+msgstr ""
+
msgid "ProjectsNew|Run CI/CD for external repository"
msgstr ""
@@ -29224,6 +29851,9 @@ msgstr ""
msgid "ProtectedBranch|Unprotect"
msgstr ""
+msgid "ProtectedBranch|Unprotect branch"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
@@ -29251,6 +29881,9 @@ msgstr ""
msgid "ProtectedEnvironment|Protected Environment (%{protected_environments_count})"
msgstr ""
+msgid "ProtectedEnvironment|Required approvals"
+msgstr ""
+
msgid "ProtectedEnvironment|Select an environment"
msgstr ""
@@ -29272,10 +29905,13 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|Unprotect tag"
+msgstr ""
+
msgid "ProtectedTags|default"
msgstr ""
-msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
+msgid "ProtectedTag|By default, protected tags restrict who can modify the tag."
msgstr ""
msgid "ProtectedTag|Learn more."
@@ -29338,6 +29974,9 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Public projects are an easy way to allow everyone to have read-only access."
+msgstr ""
+
msgid "Publish to status page"
msgstr ""
@@ -29494,9 +30133,6 @@ msgstr ""
msgid "QualitySummary|Project quality"
msgstr ""
-msgid "Quarters"
-msgstr ""
-
msgid "Query"
msgstr ""
@@ -29581,6 +30217,9 @@ msgstr ""
msgid "Read more about project permissions %{help_link_open}here%{help_link_close}"
msgstr ""
+msgid "Read more about related epics"
+msgstr ""
+
msgid "Read more about related issues"
msgstr ""
@@ -29611,10 +30250,7 @@ msgstr ""
msgid "Rebase source branch on the target branch."
msgstr ""
-msgid "Rebase without CI"
-msgstr ""
-
-msgid "Rebases and triggers a pipeline"
+msgid "Rebase without pipeline"
msgstr ""
msgid "Recaptcha verified?"
@@ -29665,9 +30301,6 @@ msgstr ""
msgid "Reconfigure"
msgstr ""
-msgid "Recovering projects"
-msgstr ""
-
msgid "Recovery Codes"
msgstr ""
@@ -29728,6 +30361,12 @@ msgstr ""
msgid "Regex pattern"
msgstr ""
+msgid "Region"
+msgstr ""
+
+msgid "Regions"
+msgstr ""
+
msgid "Register"
msgstr ""
@@ -29959,9 +30598,6 @@ msgstr ""
msgid "Remove all or specific reviewer(s)"
msgstr ""
-msgid "Remove approver"
-msgstr ""
-
msgid "Remove approvers"
msgstr ""
@@ -29977,6 +30613,9 @@ msgstr ""
msgid "Remove attention request"
msgstr ""
+msgid "Remove attention request(s)"
+msgstr ""
+
msgid "Remove avatar"
msgstr ""
@@ -30115,6 +30754,9 @@ msgstr ""
msgid "Removed an issue from an epic."
msgstr ""
+msgid "Removed attention from %{users_sentence}."
+msgstr ""
+
msgid "Removed attention request from @%{username}"
msgstr ""
@@ -30166,6 +30808,9 @@ msgstr ""
msgid "Removes an issue from an epic."
msgstr ""
+msgid "Removes attention from %{users_sentence}."
+msgstr ""
+
msgid "Removes parent epic %{epic_ref}."
msgstr ""
@@ -30277,6 +30922,9 @@ msgstr ""
msgid "Report abuse to admin"
msgstr ""
+msgid "Report is generating and will be sent to your email address."
+msgstr ""
+
msgid "Reported %{timeAgo} by %{reportedBy}"
msgstr ""
@@ -30571,6 +31219,15 @@ msgstr ""
msgid "Request attention"
msgstr ""
+msgid "Request attention from %{users_sentence}."
+msgstr ""
+
+msgid "Request attention from assignee or reviewer"
+msgstr ""
+
+msgid "Request attention from assignee(s) or reviewer(s)"
+msgstr ""
+
msgid "Request attention to review"
msgstr ""
@@ -30595,6 +31252,9 @@ msgstr ""
msgid "Requested %{time_ago}"
msgstr ""
+msgid "Requested attention from %{users_sentence}."
+msgstr ""
+
msgid "Requested attention from @%{username}"
msgstr ""
@@ -30811,6 +31471,9 @@ msgstr ""
msgid "Restore project"
msgstr ""
+msgid "Restoring projects"
+msgstr ""
+
msgid "Restoring the group will prevent the group, its subgroups and projects from being removed on this date."
msgstr ""
@@ -30841,6 +31504,9 @@ msgstr ""
msgid "Retry"
msgstr ""
+msgid "Retry failed jobs"
+msgstr ""
+
msgid "Retry job"
msgstr ""
@@ -30889,9 +31555,6 @@ msgstr ""
msgid "Review changes"
msgstr ""
-msgid "Review requested from %{name}"
-msgstr ""
-
msgid "Review requests for you"
msgstr ""
@@ -31057,6 +31720,9 @@ msgstr ""
msgid "Runners|Assigned Group"
msgstr ""
+msgid "Runners|Assigned Projects (%{projectCount})"
+msgstr ""
+
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -31126,6 +31792,9 @@ msgstr ""
msgid "Runners|Instance"
msgstr ""
+msgid "Runners|Jobs"
+msgstr ""
+
msgid "Runners|Last contact"
msgstr ""
@@ -31219,9 +31888,6 @@ msgstr ""
msgid "Runners|Runner %{name} was deleted"
msgstr ""
-msgid "Runners|Runner ID"
-msgstr ""
-
msgid "Runners|Runner assigned to project."
msgstr ""
@@ -31369,6 +32035,9 @@ msgstr ""
msgid "Runners|stale"
msgstr ""
+msgid "Runner|This runner has not run any jobs."
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -31483,6 +32152,24 @@ msgstr ""
msgid "Saving project."
msgstr ""
+msgid "ScanResultPolicy|%{ifLabelStart}if%{ifLabelEnd} %{scanners} scan in an open merge request targeting the %{branches} branch(es) finds %{vulnerabilitiesAllowed} or more %{severities} vulnerabilities that are %{vulnerabilityStates}"
+msgstr ""
+
+msgid "ScanResultPolicy|%{thenLabelStart}Then%{thenLabelEnd} Require approval from %{approvalsRequired} of the following approvers: %{approvers}"
+msgstr ""
+
+msgid "ScanResultPolicy|add an approver"
+msgstr ""
+
+msgid "ScanResultPolicy|scanners"
+msgstr ""
+
+msgid "ScanResultPolicy|severity levels"
+msgstr ""
+
+msgid "ScanResultPolicy|vulnerability states"
+msgstr ""
+
msgid "Scanner"
msgstr ""
@@ -31615,6 +32302,9 @@ msgstr ""
msgid "Search for a user"
msgstr ""
+msgid "Search for an emoji"
+msgstr ""
+
msgid "Search for projects, issues, etc."
msgstr ""
@@ -31813,18 +32503,12 @@ msgstr ""
msgid "Secret Detection"
msgstr ""
-msgid "Secret access key"
-msgstr ""
-
msgid "Secret token"
msgstr ""
msgid "Secure token that identifies an external storage request."
msgstr ""
-msgid "SecureCodeWarrior"
-msgstr ""
-
msgid "Security"
msgstr ""
@@ -31849,9 +32533,6 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "Security training with guide and learning pathways."
-msgstr ""
-
msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
@@ -31954,7 +32635,7 @@ msgstr ""
msgid "SecurityConfiguration|Manage corpus"
msgstr ""
-msgid "SecurityConfiguration|Manage corpus files used as mutation sources in coverage fuzzing."
+msgid "SecurityConfiguration|Manage corpus files used as seed inputs with coverage-guided fuzzing."
msgstr ""
msgid "SecurityConfiguration|Manage profiles for use by DAST scans."
@@ -32020,15 +32701,15 @@ msgstr ""
msgid "SecurityOrchestration|.yaml preview"
msgstr ""
-msgid "SecurityOrchestration|Action"
-msgstr ""
-
msgid "SecurityOrchestration|Actions"
msgstr ""
msgid "SecurityOrchestration|Add rule"
msgstr ""
+msgid "SecurityOrchestration|After dismissing the alert, the information will never be shown again."
+msgstr ""
+
msgid "SecurityOrchestration|All policies"
msgstr ""
@@ -32044,7 +32725,7 @@ msgstr ""
msgid "SecurityOrchestration|Description"
msgstr ""
-msgid "SecurityOrchestration|Disabled"
+msgid "SecurityOrchestration|Don't show the alert anymore"
msgstr ""
msgid "SecurityOrchestration|Edit policy"
@@ -32053,13 +32734,13 @@ msgstr ""
msgid "SecurityOrchestration|Edit policy project"
msgstr ""
-msgid "SecurityOrchestration|Enabled"
+msgid "SecurityOrchestration|Empty policy name"
msgstr ""
-msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Enabled"
msgstr ""
-msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
msgstr ""
msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
@@ -32068,7 +32749,7 @@ msgstr ""
msgid "SecurityOrchestration|Invalid policy type"
msgstr ""
-msgid "SecurityOrchestration|Latest scan"
+msgid "SecurityOrchestration|Latest scan run against %{agent}"
msgstr ""
msgid "SecurityOrchestration|Network"
@@ -32077,15 +32758,27 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No actions defined - policy will not run."
+msgstr ""
+
+msgid "SecurityOrchestration|No description"
+msgstr ""
+
msgid "SecurityOrchestration|No rules defined - policy will not run."
msgstr ""
+msgid "SecurityOrchestration|Not enabled"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
msgid "SecurityOrchestration|Policies"
msgstr ""
+msgid "SecurityOrchestration|Policy Type"
+msgstr ""
+
msgid "SecurityOrchestration|Policy cannot be enabled for non-existing branches (%{branches})"
msgstr ""
@@ -32110,10 +32803,13 @@ msgstr ""
msgid "SecurityOrchestration|Require %{approvals} %{plural} from %{approvers} if any of the following occur:"
msgstr ""
-msgid "SecurityOrchestration|Rule"
+msgid "SecurityOrchestration|Rules"
msgstr ""
-msgid "SecurityOrchestration|Rules"
+msgid "SecurityOrchestration|Runs %{actions} and %{lastAction} scans"
+msgstr ""
+
+msgid "SecurityOrchestration|Runs a %{action} scan"
msgstr ""
msgid "SecurityOrchestration|Scan Execution"
@@ -32173,6 +32869,9 @@ msgstr ""
msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
+msgid "SecurityOrchestration|This view only shows scan results for the agent %{agent}. You can view scan results for all agents in the %{linkStart}Operational Vulnerabilities tab of the vulnerability report%{linkEnd}."
+msgstr ""
+
msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
@@ -32227,9 +32926,6 @@ msgstr ""
msgid "SecurityOrchestration|users with ids"
msgstr ""
-msgid "SecurityOrchestration|view results"
-msgstr ""
-
msgid "SecurityOrchestration|vulnerabilities"
msgstr ""
@@ -32899,22 +33595,19 @@ 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|In order to start using functions as a service, you must first install Knative on your Kubernetes cluster. %{linkStart}More information%{linkEnd}"
-msgstr ""
-
msgid "Serverless|Learn more about Serverless"
msgstr ""
msgid "Serverless|No functions available"
msgstr ""
-msgid "Serverless|Sign up for First Look"
+msgid "Serverless|Serverless was %{linkStart}deprecated%{linkEnd} in GitLab 14.3."
+msgstr ""
+
+msgid "Serverless|Serverless was %{postLinkStart}deprecated%{postLinkEnd}. But if you opt to use it, you must install Knative in your Kubernetes cluster first. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "Serverless|The deploy job has not finished."
@@ -32926,9 +33619,6 @@ 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 ""
@@ -32944,9 +33634,6 @@ msgstr ""
msgid "Service Account Key"
msgstr ""
-msgid "Service Accounts"
-msgstr ""
-
msgid "Service Accounts keys authorize GitLab to deploy your Google Cloud project"
msgstr ""
@@ -32956,10 +33643,10 @@ msgstr ""
msgid "Service Desk allows people to create issues in your GitLab instance without their own user account. It provides a unique email address for end users to create issues in a project. Replies can be sent either through the GitLab interface or by email. End users only see threads through email."
msgstr ""
-msgid "Service Usage Data"
+msgid "Service account generated successfully"
msgstr ""
-msgid "Service account generated successfully"
+msgid "Service accounts"
msgstr ""
msgid "Service ping is disabled in your configuration file, and cannot be enabled through this form."
@@ -33103,6 +33790,9 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
+msgid "Set the per-user rate limit for getting a user by ID via the API."
+msgstr ""
+
msgid "Set the per-user rate limit for notes created by web or API requests."
msgstr ""
@@ -33283,6 +33973,9 @@ msgstr ""
msgid "Shared runners details"
msgstr ""
+msgid "Shared runners enabled cannot be enabled until a valid credit card is on file"
+msgstr ""
+
msgid "Shared runners help link"
msgstr ""
@@ -33340,6 +34033,9 @@ msgstr ""
msgid "Show all issues."
msgstr ""
+msgid "Show all milestones"
+msgstr ""
+
msgid "Show all test cases."
msgstr ""
@@ -33376,6 +34072,9 @@ msgstr ""
msgid "Show file contents"
msgstr ""
+msgid "Show group milestones"
+msgstr ""
+
msgid "Show labels"
msgstr ""
@@ -33391,6 +34090,12 @@ msgstr ""
msgid "Show open epics"
msgstr ""
+msgid "Show project milestones"
+msgstr ""
+
+msgid "Show sub-group milestones"
+msgstr ""
+
msgid "Show the Closed list"
msgstr ""
@@ -33400,12 +34105,6 @@ msgstr ""
msgid "Show whitespace changes"
msgstr ""
-msgid "Showing %d event"
-msgid_plural "Showing %d events"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-
msgid "Showing %{conflict} between %{sourceBranch} and %{targetBranch}"
msgstr ""
@@ -33466,12 +34165,6 @@ msgstr ""
msgid "Sidebar|None"
msgstr ""
-msgid "Sidebar|Only numeral characters allowed"
-msgstr ""
-
-msgid "Sidebar|Weight"
-msgstr ""
-
msgid "Sidekiq job compression threshold (bytes)"
msgstr ""
@@ -33634,6 +34327,9 @@ msgstr ""
msgid "Slack logo"
msgstr ""
+msgid "SlackIntegration|Are you sure you want to remove this project from the Slack application?"
+msgstr ""
+
msgid "SlackIntegration|GitLab for Slack"
msgstr ""
@@ -33643,6 +34339,9 @@ msgstr ""
msgid "SlackIntegration|Project alias"
msgstr ""
+msgid "SlackIntegration|Remove project"
+msgstr ""
+
msgid "SlackIntegration|Select a GitLab project to link with your Slack workspace."
msgstr ""
@@ -33787,9 +34486,6 @@ msgstr ""
msgid "Something went wrong trying to load issue contacts."
msgstr ""
-msgid "Something went wrong when creating a work item. Please try again"
-msgstr ""
-
msgid "Something went wrong when reordering designs. Please try again"
msgstr ""
@@ -33883,9 +34579,6 @@ msgstr ""
msgid "Something went wrong while inserting your image. Please try again."
msgstr ""
-msgid "Something went wrong while merging this merge request. Please try again."
-msgstr ""
-
msgid "Something went wrong while obtaining the Let's Encrypt certificate."
msgstr ""
@@ -34207,10 +34900,10 @@ 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."
+msgid "SourcegraphAdmin|Learn more."
msgstr ""
-msgid "SourcegraphAdmin|More information"
+msgid "SourcegraphAdmin|Only public projects have code intelligence enabled and communicate with Sourcegraph."
msgstr ""
msgid "SourcegraphAdmin|Save changes"
@@ -34219,7 +34912,7 @@ msgstr ""
msgid "SourcegraphAdmin|Sourcegraph URL"
msgstr ""
-msgid "SourcegraphAdmin|e.g. https://sourcegraph.example.com"
+msgid "SourcegraphAdmin|https://sourcegraph.example.com"
msgstr ""
msgid "SourcegraphPreferences|This feature is experimental and currently limited to certain projects."
@@ -34354,6 +35047,9 @@ msgstr ""
msgid "Start date"
msgstr ""
+msgid "Start free trial"
+msgstr ""
+
msgid "Start merge train"
msgstr ""
@@ -34384,6 +35080,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started escalation for this incident."
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -34396,6 +35095,9 @@ msgstr ""
msgid "Starts at (UTC)"
msgstr ""
+msgid "Starts escalations for this incident"
+msgstr ""
+
msgid "Starts on"
msgstr ""
@@ -34657,6 +35359,9 @@ msgstr ""
msgid "Strikethrough"
msgstr ""
+msgid "Strikethrough text"
+msgstr ""
+
msgid "Subgroup information"
msgstr ""
@@ -34891,6 +35596,21 @@ msgstr ""
msgid "Subscriptions"
msgstr ""
+msgid "Subscriptions|Chat with sales"
+msgstr ""
+
+msgid "Subscriptions|Close"
+msgstr ""
+
+msgid "Subscriptions|Not ready to buy yet?"
+msgstr ""
+
+msgid "Subscriptions|Start a free trial"
+msgstr ""
+
+msgid "Subscriptions|We understand. Maybe you have some questions for our sales team, or maybe you'd like to try some of the paid features first. What would you like to do?"
+msgstr ""
+
msgid "Subscription|Your subscription for %{strong}%{namespace_name}%{strong_close} has expired and you are now on %{pricing_link_start}the GitLab Free tier%{pricing_link_end}. Don't worry, your data is safe. Get in touch with our support team (%{support_email}). They'll gladly help with your subscription renewal."
msgstr ""
@@ -35101,6 +35821,9 @@ msgstr ""
msgid "SuperSonics|Maximum users"
msgstr ""
+msgid "SuperSonics|Offline cloud"
+msgstr ""
+
msgid "SuperSonics|Paste your activation code"
msgstr ""
@@ -35167,6 +35890,12 @@ msgstr ""
msgid "SuperSonics|You do not have an active subscription"
msgstr ""
+msgid "SuperSonics|You have a future dated license"
+msgstr ""
+
+msgid "SuperSonics|You have added a license that activates on %{date}. Please see the subscription history table below for more details."
+msgstr ""
+
msgid "SuperSonics|You have successfully added a license that activates on %{date}. Please see the subscription history table below for more details."
msgstr ""
@@ -35326,6 +36055,9 @@ msgstr ""
msgid "Tag name is required"
msgstr ""
+msgid "Tag push"
+msgstr ""
+
msgid "Tag push events"
msgstr ""
@@ -35428,6 +36160,9 @@ msgstr ""
msgid "TagsPage|protected"
msgstr ""
+msgid "Take a look at the documentation to discover all of GitLab’s capabilities."
+msgstr ""
+
msgid "Target Branch"
msgstr ""
@@ -35836,6 +36571,9 @@ msgstr ""
msgid "Tests"
msgstr ""
+msgid "Text (optional)"
+msgstr ""
+
msgid "Text added to the body of all email messages. %{character_limit} character limit"
msgstr ""
@@ -35887,6 +36625,9 @@ msgstr ""
msgid "The CSV export will be created in the background. Once finished, it will be sent to %{email} in an attachment."
msgstr ""
+msgid "The CSV export you requested of all user memberships is attached to this email."
+msgstr ""
+
msgid "The GitLab subscription service (customers.gitlab.com) is currently experiencing an outage. You can monitor the status and get updates at %{linkStart}status.gitlab.com%{linkEnd}."
msgstr ""
@@ -35962,6 +36703,9 @@ 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 epic"
+msgstr ""
+
msgid "The current issue"
msgstr ""
@@ -36124,6 +36868,9 @@ msgstr ""
msgid "The latest pipeline for this merge request has failed."
msgstr ""
+msgid "The license key is invalid."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -36139,6 +36886,9 @@ msgstr ""
msgid "The license was successfully uploaded and will be active from %{starts_at}. You can see the details below."
msgstr ""
+msgid "The license you uploaded is invalid. If the issue persists, contact support at %{link}."
+msgstr ""
+
msgid "The list creation wizard is already open"
msgstr ""
@@ -36760,10 +37510,13 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} and everything this project contains. %{strongOpen}There is no going back%{strongClose}"
+msgstr ""
+
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains."
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}on %{date}%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains. %{strongOpen}There is no going back.%{strongClose}"
msgstr ""
msgid "This action will %{strongOpen}permanently remove%{strongClose} %{codeOpen}%{group}%{codeClose} %{strongOpen}immediately%{strongClose}."
@@ -36892,9 +37645,6 @@ msgstr ""
msgid "This file was modified for readability, and can't accept suggestions. Edit it directly."
msgstr ""
-msgid "This forked project has the following:"
-msgstr ""
-
msgid "This form is disabled in preview"
msgstr ""
@@ -36907,7 +37657,7 @@ msgstr ""
msgid "This group can't be removed because it is linked to a subscription. To remove this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
-msgid "This group can't be transfered because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
+msgid "This group can't be transferred because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
msgid "This group cannot be invited to a project inside a group with enforced SSO"
@@ -36934,6 +37684,9 @@ 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 incident is already escalated with '%{escalation_policy_name}'."
+msgstr ""
+
msgid "This invitation was sent to %{mail_to_invite_email}, but you are signed in as %{link_to_current_user} with email %{mail_to_current_user}."
msgstr ""
@@ -36952,9 +37705,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 merge train pipeline"
-msgstr ""
-
msgid "This is a private email address %{helpIcon} generated just for you. Anyone who has it can create issues or merge requests as if they were you. If that happens, %{resetLinkStart}reset this token%{resetLinkEnd}."
msgstr ""
@@ -36976,6 +37726,12 @@ msgstr ""
msgid "This is your current session"
msgstr ""
+msgid "This issue cannot be assigned to a confidential epic because it is public."
+msgstr ""
+
+msgid "This issue cannot be made public because it belongs to a confidential epic."
+msgstr ""
+
msgid "This issue is confidential and should only be visible to team members with at least Reporter access."
msgstr ""
@@ -37093,6 +37849,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 branch is protected from force push."
+msgstr ""
+
msgid "This merge request cannot be rebased while there are conflicts."
msgstr ""
@@ -37144,9 +37903,15 @@ msgstr ""
msgid "This pipeline was triggered by a schedule."
msgstr ""
+msgid "This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project"
msgstr ""
+msgid "This project can be restored until %{date}."
+msgstr ""
+
msgid "This project cannot be %{visibilityLevel} because the visibility of %{openShowLink}%{name}%{closeShowLink} is %{visibility}. To make this project %{visibilityLevel}, you must first %{openEditLink}change the visibility%{closeEditLink} of the parent group."
msgstr ""
@@ -37165,6 +37930,9 @@ msgstr ""
msgid "This project is %{strongStart}NOT%{strongEnd} a fork, and has the following:"
msgstr ""
+msgid "This project is %{strongStart}NOT%{strongEnd} a fork. This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -37858,6 +38626,9 @@ msgstr ""
msgid "Today"
msgstr ""
+msgid "Todos count"
+msgstr ""
+
msgid "Todos|Are you looking for things to do? Take a look at %{strongStart}%{openIssuesLinkStart}open issues%{openIssuesLinkEnd}%{strongEnd}, contribute to %{strongStart}%{mergeRequestLinkStart}a merge request%{mergeRequestLinkEnd}%{mergeRequestLinkEnd}%{strongEnd}, or mention someone in a comment to automatically assign them a new to-do item."
msgstr ""
@@ -38131,11 +38902,8 @@ msgstr ""
msgid "Trending"
msgstr ""
-msgid "Trials|%{planName} Trial %{enDash} %{num} day left"
-msgid_plural "Trials|%{planName} Trial %{enDash} %{num} days left"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgid "Trials|%{planName} Trial"
+msgstr ""
msgid "Trials|Compare all plans"
msgstr ""
@@ -38143,6 +38911,9 @@ msgstr ""
msgid "Trials|Create a new group to start your GitLab Ultimate trial."
msgstr ""
+msgid "Trials|Day %{daysUsed}/%{duration}"
+msgstr ""
+
msgid "Trials|Go back to GitLab"
msgstr ""
@@ -38392,7 +39163,7 @@ msgstr ""
msgid "URL is triggered when repository is updated"
msgstr ""
-msgid "URL must be percent-encoded if neccessary."
+msgid "URL must be percent-encoded if necessary."
msgstr ""
msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
@@ -38611,6 +39382,9 @@ msgstr ""
msgid "Unlock account"
msgstr ""
+msgid "Unlock more features with GitLab Ultimate"
+msgstr ""
+
msgid "Unlock the discussion"
msgstr ""
@@ -38674,6 +39448,9 @@ msgstr ""
msgid "Unsubscribes from this %{quick_action_target}."
msgstr ""
+msgid "Unsupported sort value."
+msgstr ""
+
msgid "Unsupported todo type passed. Supported todo types are: %{todo_types}"
msgstr ""
@@ -38902,6 +39679,9 @@ msgstr ""
msgid "UsageQuota|File attachments and smaller design graphics."
msgstr ""
+msgid "UsageQuota|From %{storage_enforcement_date} storage limits will apply to this namespace. View and manage your usage in %{strong_start}Group Settings &gt; Usage quotas%{strong_end}."
+msgstr ""
+
msgid "UsageQuota|Git repository."
msgstr ""
@@ -38962,6 +39742,9 @@ msgstr ""
msgid "UsageQuota|Storage type"
msgstr ""
+msgid "UsageQuota|Storage used"
+msgstr ""
+
msgid "UsageQuota|This is the total amount of storage used across your projects within this namespace."
msgstr ""
@@ -39157,6 +39940,12 @@ msgstr ""
msgid "Use hashed storage paths for newly created and renamed repositories. Always enabled since 13.0."
msgstr ""
+msgid "Use issue count"
+msgstr ""
+
+msgid "Use issue weight"
+msgstr ""
+
msgid "Use one line per URI"
msgstr ""
@@ -39538,6 +40327,9 @@ msgstr ""
msgid "Users"
msgstr ""
+msgid "Users API rate limit"
+msgstr ""
+
msgid "Users can launch a development environment from a GitLab browser tab when the %{linkStart}Gitpod%{linkEnd} integration is enabled."
msgstr ""
@@ -39865,6 +40657,9 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View group pipeline usage quota"
+msgstr ""
+
msgid "View incident details at"
msgstr ""
@@ -40018,6 +40813,9 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
+msgid "Vulnerability"
+msgstr ""
+
msgid "Vulnerability Report"
msgstr ""
@@ -40069,6 +40867,9 @@ msgstr ""
msgid "VulnerabilityManagement|An unverified non-confirmed finding"
msgstr ""
+msgid "VulnerabilityManagement|At least one identifier is required"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -40078,12 +40879,24 @@ msgstr ""
msgid "VulnerabilityManagement|Create Jira issue"
msgstr ""
+msgid "VulnerabilityManagement|Enter a name"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE code"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE identifier URL"
+msgstr ""
+
msgid "VulnerabilityManagement|Fetching linked Jira issues"
msgstr ""
msgid "VulnerabilityManagement|Manually add a vulnerability entry into the vulnerability report."
msgstr ""
+msgid "VulnerabilityManagement|Name is a required field"
+msgstr ""
+
msgid "VulnerabilityManagement|Needs triage"
msgstr ""
@@ -40099,6 +40912,18 @@ msgstr ""
msgid "VulnerabilityManagement|Select a method"
msgstr ""
+msgid "VulnerabilityManagement|Select a severity level"
+msgstr ""
+
+msgid "VulnerabilityManagement|Select a status"
+msgstr ""
+
+msgid "VulnerabilityManagement|Severity is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Something went wrong while creating vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -40123,6 +40948,12 @@ msgstr ""
msgid "VulnerabilityManagement|Something went wrong, could not update vulnerability state."
msgstr ""
+msgid "VulnerabilityManagement|Status is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Submit vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Summary, detailed description, steps to reproduce, etc."
msgstr ""
@@ -40318,6 +41149,9 @@ msgstr ""
msgid "WARNING:"
msgstr ""
+msgid "WARNING: This snippet contains hidden files which might be used to mask malicious behavior. Exercise caution if cloning and executing code from this snippet."
+msgstr ""
+
msgid "Wait for the file to load to copy its contents"
msgstr ""
@@ -40537,6 +41371,15 @@ msgstr ""
msgid "Webhooks|An issue is created, updated, closed, or reopened."
msgstr ""
+msgid "Webhooks|Are you sure you want to delete this group hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this project hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this webhook?"
+msgstr ""
+
msgid "Webhooks|Comments"
msgstr ""
@@ -40546,6 +41389,9 @@ msgstr ""
msgid "Webhooks|Confidential issues events"
msgstr ""
+msgid "Webhooks|Delete webhook"
+msgstr ""
+
msgid "Webhooks|Deployment events"
msgstr ""
@@ -40780,6 +41626,9 @@ msgstr ""
msgid "Wiki"
msgstr ""
+msgid "Wiki page"
+msgstr ""
+
msgid "Wiki page was successfully created."
msgstr ""
@@ -40885,7 +41734,7 @@ msgstr ""
msgid "WikiPageConflictMessage|Someone edited the page the same time you did. Please check out %{wikiLinkStart}the page%{wikiLinkEnd} and make sure your changes will not unintentionally remove theirs."
msgstr ""
-msgid "WikiPage|An error occured while trying to render the content editor. Please try again later."
+msgid "WikiPage|An error occurred while trying to render the content editor. Please try again later."
msgstr ""
msgid "WikiPage|Are you sure you want to switch back to the classic editor?"
@@ -41044,6 +41893,18 @@ msgstr ""
msgid "WorkItem|New Task"
msgstr ""
+msgid "WorkItem|Something went wrong when creating a work item. Please try again"
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching the work item. Please try again."
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching work item types. Please try again"
+msgstr ""
+
+msgid "WorkItem|Type"
+msgstr ""
+
msgid "WorkItem|Work Items"
msgstr ""
@@ -41110,7 +41971,10 @@ msgstr ""
msgid "You are about to add %{usersTag} people to the discussion. They will all receive a notification."
msgstr ""
-msgid "You are about to permanently delete this project"
+msgid "You are about to delete this forked project containing:"
+msgstr ""
+
+msgid "You are about to delete this project containing:"
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."
@@ -41131,6 +41995,9 @@ msgstr ""
msgid "You are attempting to update a file that has changed since you started editing it."
msgstr ""
+msgid "You are billed if you exceed this number. %{qsrOverageLinkStart}How does billing work?%{qsrOverageLinkEnd}"
+msgstr ""
+
msgid "You are connected to the Prometheus server, but there is currently no data to display."
msgstr ""
@@ -41188,6 +42055,9 @@ msgstr ""
msgid "You are not authorized to update this scanner profile"
msgstr ""
+msgid "You are not authorized to upload metric images"
+msgstr ""
+
msgid "You are now impersonating %{username}"
msgstr ""
@@ -41341,9 +42211,6 @@ msgstr ""
msgid "You can only upload one design when dropping onto an existing design."
msgstr ""
-msgid "You can recover this project until %{date}"
-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 ""
@@ -41392,9 +42259,6 @@ msgstr ""
msgid "You cannot write to this read-only GitLab instance."
msgstr ""
-msgid "You can’t %{tag_start}edit%{tag_end} files directly in this project. Fork this project and submit a merge request with your changes."
-msgstr ""
-
msgid "You can’t edit files directly in this project. Fork this project and submit a merge request with your changes."
msgstr ""
@@ -41548,9 +42412,6 @@ 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 set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
@@ -41581,12 +42442,6 @@ msgstr ""
msgid "You must have maintainer access to force delete a lock"
msgstr ""
-msgid "You must have permission to create a project in a group before forking."
-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 ""
@@ -41992,7 +42847,7 @@ msgstr ""
msgid "Your public email will be displayed on your public profile."
msgstr ""
-msgid "Your request for access could not be processed: %{error_meesage}"
+msgid "Your request for access could not be processed: %{error_message}"
msgstr ""
msgid "Your request for access has been queued for review."
@@ -42178,6 +43033,9 @@ msgstr ""
msgid "archived:"
msgstr ""
+msgid "artifacts"
+msgstr ""
+
msgid "assign yourself"
msgstr ""
@@ -42208,6 +43066,9 @@ msgstr[2] ""
msgid "branch name"
msgstr ""
+msgid "builds"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -42634,6 +43495,9 @@ msgstr ""
msgid "contact with same email already exists in group hierarchy"
msgstr ""
+msgid "container registry images"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -42673,6 +43537,9 @@ msgstr ""
msgid "data"
msgstr ""
+msgid "database"
+msgstr ""
+
msgid "date must not be after 9999-12-31"
msgstr ""
@@ -42697,9 +43564,6 @@ msgstr ""
msgid "design"
msgstr ""
-msgid "detached"
-msgstr ""
-
msgid "disabled"
msgstr ""
@@ -42952,7 +43816,7 @@ msgstr ""
msgid "is not a valid X509 certificate."
msgstr ""
-msgid "is not allowed for sign-up."
+msgid "is not allowed for sign-up. Please use your regular email address."
msgstr ""
msgid "is not allowed for this group."
@@ -42964,7 +43828,7 @@ msgstr ""
msgid "is not allowed since the group is not top-level group."
msgstr ""
-msgid "is not allowed."
+msgid "is not allowed. Please use your regular email address."
msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
@@ -43051,6 +43915,9 @@ msgstr ""
msgid "level: %{level}"
msgstr ""
+msgid "lfs objects"
+msgstr ""
+
msgid "limit of %{project_limit} reached"
msgstr ""
@@ -43273,6 +44140,9 @@ msgstr ""
msgid "mrWidget|Merge blocked: pipeline must succeed. It's waiting for a manual action to continue."
msgstr ""
+msgid "mrWidget|Merge blocked: pipeline must succeed. Push a commit that fixes the failure, or %{linkStart}learn about other solutions.%{linkEnd}"
+msgstr ""
+
msgid "mrWidget|Merge blocked: this merge request must be approved."
msgstr ""
@@ -43390,9 +44260,6 @@ msgstr ""
msgid "mrWidget|The changes were not merged into"
msgstr ""
-msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -43540,9 +44407,6 @@ msgstr ""
msgid "open issue"
msgstr ""
-msgid "opened %{timeAgo}"
-msgstr ""
-
msgid "or"
msgstr ""
@@ -43555,6 +44419,12 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
+msgid "packages"
+msgstr ""
+
+msgid "pages"
+msgstr ""
+
msgid "parent"
msgid_plural "parents"
msgstr[0] ""
@@ -43708,6 +44578,9 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
+msgid "repositories"
+msgstr ""
+
msgid "repository:"
msgstr ""
@@ -43828,12 +44701,18 @@ msgstr ""
msgid "tag name"
msgstr ""
+msgid "terraform states"
+msgstr ""
+
msgid "the correct format."
msgstr ""
msgid "the file"
msgstr ""
+msgid "the following epic(s)"
+msgstr ""
+
msgid "the following issue(s)"
msgstr ""
@@ -43846,21 +44725,12 @@ msgstr ""
msgid "this document"
msgstr ""
-msgid "this issue cannot be assigned to a confidential epic since it is public"
-msgstr ""
-
-msgid "this issue cannot be made public since it belongs to a confidential epic"
-msgstr ""
-
msgid "time summary"
msgstr ""
msgid "toggle collapse"
msgstr ""
-msgid "train"
-msgstr ""
-
msgid "triggered"
msgstr ""
@@ -43990,3 +44860,6 @@ msgstr ""
msgid "{project}"
msgstr ""
+msgid "✔"
+msgstr ""
+
diff --git a/locale/hu_HU/gitlab.po b/locale/hu_HU/gitlab.po
index c100c167bbd..3cf13e43578 100644
--- a/locale/hu_HU/gitlab.po
+++ b/locale/hu_HU/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: hu\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2022-02-02 15:44\n"
+"PO-Revision-Date: 2022-03-01 20:38\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -146,6 +146,11 @@ msgid_plural "%d approvers (you've approved)"
msgstr[0] ""
msgstr[1] ""
+msgid "%d assigned issue"
+msgid_plural "%d assigned issues"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -421,8 +426,23 @@ msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
msgstr[1] ""
-msgid "%d vulnerability updated"
-msgid_plural "%d vulnerabilities updated"
+msgid "%d vulnerability set to confirmed"
+msgid_plural "%d vulnerabilities set to confirmed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to dismissed"
+msgid_plural "%d vulnerabilities set to dismissed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to needs triage"
+msgid_plural "%d vulnerabilities set to needs triage"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to resolved"
+msgid_plural "%d vulnerabilities set to resolved"
msgstr[0] ""
msgstr[1] ""
@@ -510,6 +530,12 @@ msgstr[1] ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{completed} of %{total} issues closed"
+msgstr ""
+
+msgid "%{completed} of %{total} weight completed"
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -858,6 +884,9 @@ msgstr ""
msgid "%{openedIssues} open, %{closedIssues} closed"
msgstr ""
+msgid "%{percentage}%% issues closed"
+msgstr ""
+
msgid "%{percentage}%% weight completed"
msgstr ""
@@ -1287,6 +1316,9 @@ msgid_plural "- Users"
msgstr[0] ""
msgstr[1] ""
+msgid "- of - issues closed"
+msgstr ""
+
msgid "- of - weight completed"
msgstr ""
@@ -1429,7 +1461,7 @@ msgstr ""
msgid "1000+"
msgstr ""
-msgid "192.168.0.0/24"
+msgid "192.168.0.0/24 or 2001:0DB8:1234::/48"
msgstr ""
msgid "1st contribution!"
@@ -1741,13 +1773,13 @@ msgstr ""
msgid "AWS Access Key"
msgstr ""
-msgid "AWS Access Key. Only required if not using role instance credentials"
+msgid "AWS Secret Access Key"
msgstr ""
-msgid "AWS Secret Access Key"
+msgid "AWS access key ID (Optional)"
msgstr ""
-msgid "AWS Secret Access Key. Only required if not using role instance credentials"
+msgid "AWS secret access key (Optional)"
msgstr ""
msgid "AWS service error: %{error}"
@@ -1807,9 +1839,6 @@ msgstr ""
msgid "Access granted"
msgstr ""
-msgid "Access key ID"
-msgstr ""
-
msgid "Access requests"
msgstr ""
@@ -1984,7 +2013,7 @@ msgstr ""
msgid "Activity"
msgstr ""
-msgid "Activity|An error occured while retrieving activity. Reload the page to try again."
+msgid "Activity|An error occurred while retrieving activity. Reload the page to try again."
msgstr ""
msgid "Add"
@@ -2023,6 +2052,9 @@ msgstr ""
msgid "Add a %{type}"
msgstr ""
+msgid "Add a GCP region"
+msgstr ""
+
msgid "Add a GPG key"
msgstr ""
@@ -2074,6 +2106,9 @@ msgstr ""
msgid "Add a numbered list"
msgstr ""
+msgid "Add a related epic"
+msgstr ""
+
msgid "Add a related issue"
msgstr ""
@@ -2188,6 +2223,9 @@ msgstr ""
msgid "Add or subtract spent time"
msgstr ""
+msgid "Add people"
+msgstr ""
+
msgid "Add previously merged commits"
msgstr ""
@@ -2254,6 +2292,9 @@ msgstr ""
msgid "Add webhook"
msgstr ""
+msgid "Add your team members and others to GitLab."
+msgstr ""
+
msgid "Add/remove"
msgstr ""
@@ -3076,12 +3117,6 @@ msgstr ""
msgid "AdvancedSearch|Reindex required"
msgstr ""
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. Permanently deleting this project will %{strongStart}immediately delete%{strongEnd} its repositories and %{strongStart}all related resources%{strongEnd}, including issues, merge requests etc."
-msgstr ""
-
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. You will lose this project's repository and %{strongStart}all related resources%{strongEnd}, including issues and merge requests."
-msgstr ""
-
msgid "After a successful password update you will be redirected to login screen."
msgstr ""
@@ -3112,6 +3147,9 @@ msgstr ""
msgid "Akismet helps prevent the creation of spam issues in public projects."
msgstr ""
+msgid "Alert"
+msgstr ""
+
msgid "AlertManagement|Acknowledged"
msgstr ""
@@ -3484,9 +3522,6 @@ msgstr ""
msgid "All environments"
msgstr ""
-msgid "All epics"
-msgstr ""
-
msgid "All groups and projects"
msgstr ""
@@ -4223,12 +4258,15 @@ msgstr ""
msgid "ApplicationSettings|Approve users in the pending approval status?"
msgstr ""
-msgid "ApplicationSettings|By making this change, you will automatically approve %d user with the pending approval status."
-msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users with the pending approval status."
+msgid "ApplicationSettings|Approve users who are pending approval?"
+msgstr ""
+
+msgid "ApplicationSettings|By making this change, you will automatically approve %d user who is pending approval."
+msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users who are pending approval."
msgstr[0] ""
msgstr[1] ""
-msgid "ApplicationSettings|By making this change, you will automatically approve all users in pending approval status."
+msgid "ApplicationSettings|By making this change, you will automatically approve all users who are pending approval."
msgstr ""
msgid "ApplicationSettings|Denied domains for sign-ups"
@@ -4634,10 +4672,10 @@ msgstr ""
msgid "Archiving the project will make it entirely read-only. It is hidden from the dashboard and doesn't show up in searches. %{strong_start}The repository cannot be committed to, and no issues, comments, or other entities can be created.%{strong_end} %{link_start}Learn more.%{link_end}"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to delete this project?"
+msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
+msgid "Are you absolutely sure?"
msgstr ""
msgid "Are you sure that you want to archive this project?"
@@ -4673,12 +4711,18 @@ msgstr ""
msgid "Are you sure you want to delete this SSH key?"
msgstr ""
+msgid "Are you sure you want to delete this comment?"
+msgstr ""
+
msgid "Are you sure you want to delete this deploy key?"
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 label?"
+msgstr ""
+
msgid "Are you sure you want to delete this pipeline schedule?"
msgstr ""
@@ -4694,9 +4738,6 @@ msgstr ""
msgid "Are you sure you want to discard your changes?"
msgstr ""
-msgid "Are you sure you want to erase this build?"
-msgstr ""
-
msgid "Are you sure you want to import %d repository?"
msgid_plural "Are you sure you want to import %d repositories?"
msgstr[0] ""
@@ -4744,6 +4785,9 @@ msgstr ""
msgid "Are you sure you want to remove this list?"
msgstr ""
+msgid "Are you sure you want to remove this nickname?"
+msgstr ""
+
msgid "Are you sure you want to reset the health check token?"
msgstr ""
@@ -4756,10 +4800,10 @@ 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?"
+msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
msgstr ""
-msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
+msgid "Are you sure you want to revoke this project access token? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to stop this environment?"
@@ -4906,9 +4950,6 @@ msgstr ""
msgid "Assigned to %{assignee_name}"
msgstr ""
-msgid "Assigned to %{name}"
-msgstr ""
-
msgid "Assigned to me"
msgstr ""
@@ -4973,6 +5014,9 @@ msgstr[1] ""
msgid "Attaching the file failed."
msgstr ""
+msgid "Attention"
+msgstr ""
+
msgid "Audit Events"
msgstr ""
@@ -5135,6 +5179,12 @@ msgstr ""
msgid "Authorized applications (%{size})"
msgstr ""
+msgid "AuthorizedApplication|Are you sure you want to revoke this application?"
+msgstr ""
+
+msgid "AuthorizedApplication|Revoke application"
+msgstr ""
+
msgid "Authors: %{authors}"
msgstr ""
@@ -6328,6 +6378,9 @@ msgstr ""
msgid "CICDAnalytics|Shared Runners Usage"
msgstr ""
+msgid "CICDAnalytics|Shared runner pipeline minute duration by month"
+msgstr ""
+
msgid "CICDAnalytics|Shared runner usage"
msgstr ""
@@ -6469,6 +6522,9 @@ msgstr ""
msgid "Can create groups:"
msgstr ""
+msgid "Can not delete primary training"
+msgstr ""
+
msgid "Can't apply as the source branch was deleted."
msgstr ""
@@ -6802,9 +6858,6 @@ msgstr ""
msgid "Changing any setting here requires an application restart"
msgstr ""
-msgid "Changing group URL can have unintended side effects."
-msgstr ""
-
msgid "Charts can't be displayed as the request for data has timed out. %{documentationLink}"
msgstr ""
@@ -6892,9 +6945,6 @@ msgstr ""
msgid "Checking branch availability..."
msgstr ""
-msgid "Checking group URL availability..."
-msgstr ""
-
msgid "Checking group path availability..."
msgstr ""
@@ -7388,6 +7438,9 @@ msgstr ""
msgid "Clear recent searches"
msgstr ""
+msgid "Clear repository checks"
+msgstr ""
+
msgid "Clear search"
msgstr ""
@@ -7520,9 +7573,6 @@ msgstr ""
msgid "Closed MRs"
msgstr ""
-msgid "Closed epics"
-msgstr ""
-
msgid "Closed issues"
msgstr ""
@@ -7559,13 +7609,13 @@ msgstr ""
msgid "Cluster level"
msgstr ""
-msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
+msgid "Cluster type must be specified for Stages::ClusterEndpointInserter"
msgstr ""
msgid "ClusterAgents|%{name} successfully deleted"
msgstr ""
-msgid "ClusterAgents|%{number} of %{total} Agents"
+msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
@@ -7607,6 +7657,15 @@ msgstr ""
msgid "ClusterAgents|Agent never connected to GitLab"
msgstr ""
+msgid "ClusterAgents|Agent version mismatch"
+msgstr ""
+
+msgid "ClusterAgents|Agent version mismatch and update"
+msgstr ""
+
+msgid "ClusterAgents|Agent version update required"
+msgstr ""
+
msgid "ClusterAgents|All"
msgstr ""
@@ -7631,7 +7690,7 @@ msgstr ""
msgid "ClusterAgents|Configuration"
msgstr ""
-msgid "ClusterAgents|Connect a cluster through the Agent"
+msgid "ClusterAgents|Connect a cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connect existing cluster"
@@ -7640,13 +7699,13 @@ msgstr ""
msgid "ClusterAgents|Connect with a certificate"
msgstr ""
-msgid "ClusterAgents|Connect with agent"
+msgid "ClusterAgents|Connect with an agent"
msgstr ""
msgid "ClusterAgents|Connect with the GitLab Agent"
msgstr ""
-msgid "ClusterAgents|Connect your cluster through the Agent"
+msgid "ClusterAgents|Connect your cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connected"
@@ -7706,7 +7765,10 @@ msgstr ""
msgid "ClusterAgents|How to register an agent?"
msgstr ""
-msgid "ClusterAgents|Install new Agent"
+msgid "ClusterAgents|How to update an agent?"
+msgstr ""
+
+msgid "ClusterAgents|Install a new agent"
msgstr ""
msgid "ClusterAgents|Last connected %{timeAgo}."
@@ -7733,7 +7795,7 @@ msgstr ""
msgid "ClusterAgents|Never connected"
msgstr ""
-msgid "ClusterAgents|No Agents"
+msgid "ClusterAgents|No agents"
msgstr ""
msgid "ClusterAgents|No clusters connected through cluster certificates"
@@ -7793,6 +7855,9 @@ msgstr ""
msgid "ClusterAgents|The agent has not been connected in a long time. There might be a connectivity issue. Last contact was %{timeAgo}."
msgstr ""
+msgid "ClusterAgents|The agent version do not match each other across your cluster's pods. This can happen when a new agent version was just deployed and Kubernetes is shutting down the old pods."
+msgstr ""
+
msgid "ClusterAgents|The recommended installation method includes the token. If you want to follow the advanced installation method provided in the docs, make sure you save the token value before you close this window."
msgstr ""
@@ -7840,6 +7905,9 @@ msgstr ""
msgid "ClusterAgents|You will need to create a token to connect to your agent"
msgstr ""
+msgid "ClusterAgents|Your agent version is out of sync with your GitLab version (v%{version}), which might cause compatibility problems. Update the agent installed on your cluster to the most recent version."
+msgstr ""
+
msgid "ClusterAgents|Your instance doesn't have the %{linkStart}GitLab Agent Server (KAS)%{linkEnd} set up. Ask a GitLab Administrator to install it."
msgstr ""
@@ -8716,9 +8784,6 @@ msgstr ""
msgid "Comma-separated list of email addresses."
msgstr ""
-msgid "Comma-separated list of users allowed to exceed the rate limit."
-msgstr ""
-
msgid "Comma-separated, e.g. '1.1.1.1, 2.2.2.0/24'"
msgstr ""
@@ -9045,6 +9110,12 @@ msgstr ""
msgid "Confidential"
msgstr ""
+msgid "Confidential issue"
+msgstr ""
+
+msgid "Confidential note"
+msgstr ""
+
msgid "Confidentiality"
msgstr ""
@@ -9078,6 +9149,9 @@ msgstr ""
msgid "Configure Dependency Scanning in `.gitlab-ci.yml`, creating this file if it does not already exist"
msgstr ""
+msgid "Configure GitLab"
+msgstr ""
+
msgid "Configure GitLab runners to start using the Web Terminal. %{helpStart}Learn more.%{helpEnd}"
msgstr ""
@@ -9126,6 +9200,15 @@ msgstr ""
msgid "Configure pipelines to deploy web apps, backend services, APIs and static resources to Google Cloud"
msgstr ""
+msgid "Configure region"
+msgstr ""
+
+msgid "Configure region for environment"
+msgstr ""
+
+msgid "Configure regions"
+msgstr ""
+
msgid "Configure repository mirroring."
msgstr ""
@@ -9159,6 +9242,9 @@ msgstr ""
msgid "Configure which lists are shown for anyone who visits this board"
msgstr ""
+msgid "Configure your environments to be deployed to specific geographical regions"
+msgstr ""
+
msgid "Confirm"
msgstr ""
@@ -9861,10 +9947,10 @@ msgstr ""
msgid "CorpusManagement|Actions"
msgstr ""
-msgid "CorpusManagement|Corpus are used in fuzz testing as mutation source to Improve future testing."
+msgid "CorpusManagement|Corpus file"
msgstr ""
-msgid "CorpusManagement|Corpus file"
+msgid "CorpusManagement|Corpus files are used in coverage-guided fuzz testing as seed inputs to improve testing."
msgstr ""
msgid "CorpusManagement|Corpus files must be in *.zip format. Maximum 5 GB"
@@ -9918,6 +10004,9 @@ msgstr ""
msgid "Could not apply %{name} command."
msgstr ""
+msgid "Could not apply %{name} command. %{message}."
+msgstr ""
+
msgid "Could not authorize chat nickname. Try again!"
msgstr ""
@@ -10068,6 +10157,9 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
+msgid "Create a group"
+msgstr ""
+
msgid "Create a merge request"
msgstr ""
@@ -10092,6 +10184,9 @@ msgstr ""
msgid "Create a personal access token on your account to pull or push via %{protocol}."
msgstr ""
+msgid "Create a project"
+msgstr ""
+
msgid "Create an account using:"
msgstr ""
@@ -10455,6 +10550,9 @@ msgstr ""
msgid "Creation date"
msgstr ""
+msgid "Creator"
+msgstr ""
+
msgid "Credentials"
msgstr ""
@@ -10467,9 +10565,15 @@ msgstr ""
msgid "CredentialsInventory|Personal Access Tokens"
msgstr ""
+msgid "CredentialsInventory|Project Access Tokens"
+msgstr ""
+
msgid "CredentialsInventory|SSH Keys"
msgstr ""
+msgid "Credit card required to be on file in order to create a pipeline"
+msgstr ""
+
msgid "Credit card:"
msgstr ""
@@ -10653,9 +10757,6 @@ msgstr ""
msgid "Customer relations"
msgstr ""
-msgid "Customizable by an administrator."
-msgstr ""
-
msgid "Customizable by owners."
msgstr ""
@@ -10785,30 +10886,18 @@ msgstr ""
msgid "CycleAnalytics|%{selectedLabelsCount} selected (%{maxLabels} max)"
msgstr ""
-msgid "CycleAnalytics|%{stageCount} stages selected"
-msgstr ""
-
-msgid "CycleAnalytics|All stages"
-msgstr ""
-
-msgid "CycleAnalytics|Average days to completion"
+msgid "CycleAnalytics|Average time to completion"
msgstr ""
msgid "CycleAnalytics|Date"
msgstr ""
-msgid "CycleAnalytics|Days to completion"
-msgstr ""
-
msgid "CycleAnalytics|Display chart filters"
msgstr ""
msgid "CycleAnalytics|Lead Time for Changes"
msgstr ""
-msgid "CycleAnalytics|No stages selected"
-msgstr ""
-
msgid "CycleAnalytics|Number of tasks"
msgstr ""
@@ -10837,18 +10926,30 @@ msgstr ""
msgid "CycleAnalytics|Showing data for group '%{groupName}' from %{createdAfter} to %{createdBefore}"
msgstr ""
-msgid "CycleAnalytics|Stages"
+msgid "CycleAnalytics|Stage time: %{title}"
msgstr ""
msgid "CycleAnalytics|Tasks by type"
msgstr ""
-msgid "CycleAnalytics|The average time spent in the selected stage for the items that were completed on each date. Data limited to the last 500 items."
+msgid "CycleAnalytics|The average time items spent in this stage. Data limited to items completed within this date range."
msgstr ""
msgid "CycleAnalytics|The given date range is larger than 180 days"
msgstr ""
+msgid "CycleAnalytics|The total time items spent across each value stream stage. Data limited to items completed within this date range."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Stage time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Total time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|Total time"
+msgstr ""
+
msgid "CycleAnalytics|Type of work"
msgstr ""
@@ -10861,9 +10962,6 @@ msgstr ""
msgid "CycleAnalytics|project dropdown filter"
msgstr ""
-msgid "CycleAnalytics|stage dropdown"
-msgstr ""
-
msgid "DAG visualization requires at least 3 dependent jobs."
msgstr ""
@@ -10963,10 +11061,16 @@ msgstr ""
msgid "DastProfiles|AJAX spider"
msgstr ""
+msgid "DastProfiles|API"
+msgstr ""
+
+msgid "DastProfiles|API endpoint URL"
+msgstr ""
+
msgid "DastProfiles|Active"
msgstr ""
-msgid "DastProfiles|Additional request headers (Optional)"
+msgid "DastProfiles|Additional request headers (optional)"
msgstr ""
msgid "DastProfiles|Are you sure you want to delete this profile?"
@@ -10981,6 +11085,9 @@ msgstr ""
msgid "DastProfiles|Branch missing"
msgstr ""
+msgid "DastProfiles|Choose a scan method"
+msgstr ""
+
msgid "DastProfiles|Could not create the scanner profile. Please try again."
msgstr ""
@@ -11050,7 +11157,13 @@ msgstr ""
msgid "DastProfiles|Excluded URLs"
msgstr ""
-msgid "DastProfiles|Excluded URLs (Optional)"
+msgid "DastProfiles|Excluded URLs (optional)"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths (optional)"
msgstr ""
msgid "DastProfiles|Hide debug messages"
@@ -11107,9 +11220,6 @@ msgstr ""
msgid "DastProfiles|Request headers"
msgstr ""
-msgid "DastProfiles|Rest API"
-msgstr ""
-
msgid "DastProfiles|Run the AJAX spider, in addition to the traditional spider, to crawl the target site."
msgstr ""
@@ -11119,6 +11229,9 @@ msgstr ""
msgid "DastProfiles|Save profile"
msgstr ""
+msgid "DastProfiles|Scan method"
+msgstr ""
+
msgid "DastProfiles|Scan mode"
msgstr ""
@@ -11197,12 +11310,24 @@ msgstr ""
msgid "DastProfiles|Website"
msgstr ""
+msgid "DastProfiles|What does each method do?"
+msgstr ""
+
msgid "DastProfiles|You can either choose a passive scan or validate the target site from the site profile management page. %{docsLinkStart}Learn more about site validation.%{docsLinkEnd}"
msgstr ""
msgid "DastProfiles|You cannot run an active scan against an unvalidated site."
msgstr ""
+msgid "DastProfiles|folder/dast_example.har or https://example.com/dast_example.har"
+msgstr ""
+
+msgid "DastProfiles|folder/example.postman_collection.json or https://example.com/"
+msgstr ""
+
+msgid "DastProfiles|folder/openapi.json or https://example.com/openapi.json"
+msgstr ""
+
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
@@ -11310,6 +11435,9 @@ msgstr ""
msgid "DatadogIntegration|API URL"
msgstr ""
+msgid "DatadogIntegration|Custom tags in Datadog. Enter one tag per line in the %{codeOpen}key:value%{codeClose} format. %{linkOpen}How do I use tags?%{linkClose}"
+msgstr ""
+
msgid "DatadogIntegration|Environment"
msgstr ""
@@ -11328,12 +11456,18 @@ msgstr ""
msgid "DatadogIntegration|Tag all data from this GitLab instance in Datadog. Useful when managing several self-managed deployments."
msgstr ""
+msgid "DatadogIntegration|Tags"
+msgstr ""
+
msgid "DatadogIntegration|The Datadog site to send data to. To send data to the EU site, use %{codeOpen}datadoghq.eu%{codeClose}."
msgstr ""
msgid "DatadogIntegration|Trace your GitLab pipelines with Datadog."
msgstr ""
+msgid "DatadogIntegration|have an invalid format"
+msgstr ""
+
msgid "Datasource name not found"
msgstr ""
@@ -11343,9 +11477,6 @@ msgstr ""
msgid "Date merged"
msgstr ""
-msgid "Date picker"
-msgstr ""
-
msgid "Date range"
msgstr ""
@@ -11499,9 +11630,6 @@ msgstr ""
msgid "Definition"
msgstr ""
-msgid "Delayed Project Deletion (%{adjourned_deletion})"
-msgstr ""
-
msgid "DelayedJobs|Are you sure you want to run %{jobName} immediately? Otherwise this job will run automatically after its timer finishes."
msgstr ""
@@ -11580,10 +11708,10 @@ msgstr ""
msgid "Delete pipeline"
msgstr ""
-msgid "Delete project"
+msgid "Delete pipeline schedule"
msgstr ""
-msgid "Delete project. Are you ABSOLUTELY SURE?"
+msgid "Delete project"
msgstr ""
msgid "Delete row"
@@ -11613,6 +11741,9 @@ msgstr ""
msgid "Delete this epic and all descendants?"
msgstr ""
+msgid "Delete this project"
+msgstr ""
+
msgid "Delete user list"
msgstr ""
@@ -11871,6 +12002,12 @@ msgstr ""
msgid "Deploy to..."
msgstr ""
+msgid "DeployBoards|To see deployment progress for your environments, make sure you are deploying to %{codeStart}$KUBE_NAMESPACE%{codeEnd} and annotating with %{codeStart}app.gitlab.com/app=$CI_PROJECT_PATH_SLUG%{codeEnd} and %{codeStart}app.gitlab.com/env=$CI_ENVIRONMENT_SLUG%{codeEnd}."
+msgstr ""
+
+msgid "DeployBoard|Kubernetes Pods"
+msgstr ""
+
msgid "DeployFreeze|Add a freeze period to prevent unintended releases during a period of time for a given environment. You must update the deployment jobs in %{filename} according to the deploy freezes added here. %{freeze_period_link_start}Learn more.%{freeze_period_link_end}"
msgstr ""
@@ -11955,9 +12092,6 @@ msgstr ""
msgid "DeployTokens|Active Deploy Tokens (%{active_tokens})"
msgstr ""
-msgid "DeployTokens|Allows read and write access to registry images."
-msgstr ""
-
msgid "DeployTokens|Allows read and write access to the package registry."
msgstr ""
@@ -11970,6 +12104,9 @@ msgstr ""
msgid "DeployTokens|Allows read-only access to the repository."
msgstr ""
+msgid "DeployTokens|Allows write access to registry images."
+msgstr ""
+
msgid "DeployTokens|Copy deploy token"
msgstr ""
@@ -12063,12 +12200,57 @@ msgstr ""
msgid "Deploying to AWS is easy with GitLab"
msgstr ""
+msgid "Deployment"
+msgstr ""
+
msgid "Deployment Frequency"
msgstr ""
+msgid "Deployment Target|Project deployment target (optional)"
+msgstr ""
+
+msgid "Deployment Target|Select the deployment target"
+msgstr ""
+
msgid "Deployment frequency"
msgstr ""
+msgid "DeploymentTarget|GitLab Pages"
+msgstr ""
+
+msgid "DeploymentTarget|Heroku"
+msgstr ""
+
+msgid "DeploymentTarget|Infrastructure provider (Terraform, Cloudformation, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Kubernetes (GKE, EKS, OpenShift, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Managed container runtime (Fargate, Cloud Run, DigitalOcean App)"
+msgstr ""
+
+msgid "DeploymentTarget|Mobile app store"
+msgstr ""
+
+msgid "DeploymentTarget|No deployment planned"
+msgstr ""
+
+msgid "DeploymentTarget|Other hosting service"
+msgstr ""
+
+msgid "DeploymentTarget|Registry (package or container)"
+msgstr ""
+
+msgid "DeploymentTarget|Self-managed container runtime (Podman, Docker Swarm, Docker Compose)"
+msgstr ""
+
+msgid "DeploymentTarget|Serverless backend (Lambda, Cloud functions)"
+msgstr ""
+
+msgid "DeploymentTarget|Virtual machine (for example, EC2)"
+msgstr ""
+
msgid "Deployments"
msgstr ""
@@ -12107,6 +12289,9 @@ msgstr ""
msgid "Deployment|This deployment was created using the API"
msgstr ""
+msgid "Deployment|Triggerer"
+msgstr ""
+
msgid "Deployment|Waiting"
msgstr ""
@@ -12134,6 +12319,18 @@ msgstr ""
msgid "Deprecated API rate limits"
msgstr ""
+msgid "Deprecations|Feature deprecation and removal"
+msgstr ""
+
+msgid "Deprecations|For information on a possible replacement %{epicStart} learn more about Opstrace %{epicEnd}."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7 and are %{epicStart} scheduled for removal %{epicEnd} in GitLab 15.0."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7, and are %{removal_link_start} scheduled for removal %{link_end} in GitLab 15.0. For information on a possible replacement, %{opstrace_link_start} learn more about Opstrace %{link_end}."
+msgstr ""
+
msgid "Deprioritize label"
msgstr ""
@@ -12379,10 +12576,10 @@ msgstr ""
msgid "DevopsAdoption|At least one deploy"
msgstr ""
-msgid "DevopsAdoption|At least one issue opened"
+msgid "DevopsAdoption|At least one issue created"
msgstr ""
-msgid "DevopsAdoption|At least one merge request opened"
+msgid "DevopsAdoption|At least one merge request created"
msgstr ""
msgid "DevopsAdoption|At least one pipeline successfully run"
@@ -12583,6 +12780,9 @@ msgstr ""
msgid "Direct member"
msgstr ""
+msgid "Direct members"
+msgstr ""
+
msgid "Direct non-authenticated users to this page."
msgstr ""
@@ -12699,6 +12899,9 @@ msgid_plural "Dismiss %d selected vulnerabilities as"
msgstr[0] ""
msgstr[1] ""
+msgid "Dismiss Alert"
+msgstr ""
+
msgid "Dismiss merge request promotion"
msgstr ""
@@ -12726,9 +12929,15 @@ msgstr ""
msgid "Display alerts from all configured monitoring tools."
msgstr ""
+msgid "Display milestones"
+msgstr ""
+
msgid "Display name"
msgstr ""
+msgid "Display progress of child issues"
+msgstr ""
+
msgid "Display rendered file"
msgstr ""
@@ -12834,6 +13043,9 @@ msgstr ""
msgid "Download image"
msgstr ""
+msgid "Download payload"
+msgstr ""
+
msgid "Download raw data (.csv)"
msgstr ""
@@ -13011,6 +13223,9 @@ msgstr ""
msgid "Edit in Web IDE"
msgstr ""
+msgid "Edit in pipeline editor"
+msgstr ""
+
msgid "Edit in single-file editor"
msgstr ""
@@ -13053,6 +13268,9 @@ msgstr ""
msgid "Edit your most recent comment in a thread (from an empty textarea)"
msgstr ""
+msgid "Edit, lint, and visualize your pipeline."
+msgstr ""
+
msgid "Edited"
msgstr ""
@@ -13494,6 +13712,9 @@ msgstr ""
msgid "Enforce two-factor authentication for all user sign-ins."
msgstr ""
+msgid "Enhance security by storing service account keys in secret managers - learn more about %{docLinkStart}secret management with GitLab%{docLinkEnd}"
+msgstr ""
+
msgid "Ensure connectivity is available from the GitLab server to the Prometheus server"
msgstr ""
@@ -13554,6 +13775,9 @@ 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 following to confirm:"
+msgstr ""
+
msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
@@ -14084,9 +14308,6 @@ 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 ""
@@ -14222,6 +14443,9 @@ msgstr ""
msgid "Errors:"
msgstr ""
+msgid "Escalate this incident"
+msgstr ""
+
msgid "Escalation Policies"
msgstr ""
@@ -14234,6 +14458,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy"
+msgstr ""
+
msgid "Escalation policy:"
msgstr ""
@@ -14485,6 +14712,9 @@ msgstr ""
msgid "Existing sign in methods may be removed"
msgstr ""
+msgid "Exit."
+msgstr ""
+
msgid "Expand"
msgstr ""
@@ -14581,6 +14811,9 @@ msgstr ""
msgid "Explore public groups"
msgstr ""
+msgid "Explore public projects"
+msgstr ""
+
msgid "Explore snippets"
msgstr ""
@@ -14742,7 +14975,7 @@ msgid_plural "Failed to archive designs. Please try again."
msgstr[0] ""
msgstr[1] ""
-msgid "Failed to assign a reviewer because no user was found."
+msgid "Failed to assign a reviewer because no user was specified."
msgstr ""
msgid "Failed to assign a user because no user was found."
@@ -14808,10 +15041,10 @@ msgstr ""
msgid "Failed to find import label for Jira import."
msgstr ""
-msgid "Failed to generate export, please try again later."
+msgid "Failed to find users for %{missing}"
msgstr ""
-msgid "Failed to generate report, please try again after sometime"
+msgid "Failed to generate export, please try again later."
msgstr ""
msgid "Failed to get ref."
@@ -14910,6 +15143,9 @@ msgstr ""
msgid "Failed to remove a to-do item for the design."
msgstr ""
+msgid "Failed to remove attention because no user was found."
+msgstr ""
+
msgid "Failed to remove mirror."
msgstr ""
@@ -14922,6 +15158,9 @@ msgstr ""
msgid "Failed to remove user key."
msgstr ""
+msgid "Failed to request attention because no user was found."
+msgstr ""
+
msgid "Failed to reset key. Please try again."
msgstr ""
@@ -15003,6 +15242,9 @@ msgstr ""
msgid "Feature Flags"
msgstr ""
+msgid "Feature deprecation and removal"
+msgstr ""
+
msgid "Feature flag status"
msgstr ""
@@ -15500,7 +15742,7 @@ msgstr ""
msgid "For each job, re-use the project workspace. If the workspace doesn't exist, use %{code_open}git clone%{code_close}."
msgstr ""
-msgid "For example, the application using the token or the purpose of the token."
+msgid "For example, the application using the token or the purpose of the token. Do not give sensitive information for the name of the token, as it will be visible to all %{resource_type} members."
msgstr ""
msgid "For files larger than this limit, only index the file name. The file content is neither indexed nor searchable."
@@ -15584,9 +15826,6 @@ msgstr ""
msgid "ForkProject|Select a namespace"
msgstr ""
-msgid "ForkProject|Select a namespace to fork the project"
-msgstr ""
-
msgid "ForkProject|The project can be accessed by any logged in user."
msgstr ""
@@ -15683,6 +15922,9 @@ msgstr ""
msgid "Full name"
msgstr ""
+msgid "GCP region configured"
+msgstr ""
+
msgid "GPG Key ID:"
msgstr ""
@@ -15863,6 +16105,9 @@ msgstr ""
msgid "Geo|Failed"
msgstr ""
+msgid "Geo|Filter Geo sites"
+msgstr ""
+
msgid "Geo|Filter by name"
msgstr ""
@@ -16274,6 +16519,12 @@ msgstr ""
msgid "GitLab Issue"
msgstr ""
+msgid "GitLab KAS"
+msgstr ""
+
+msgid "GitLab Memberships CSV Export"
+msgstr ""
+
msgid "GitLab Pages"
msgstr ""
@@ -16322,6 +16573,9 @@ 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 free to use. Many features for larger teams are part of our %{link_start}paid products%{link_end}. You can try Ultimate for free without any obligation or payment details."
+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 ""
@@ -16448,7 +16702,7 @@ msgstr ""
msgid "GitLabPages|When enabled, all attempts to visit your website through HTTP are automatically redirected to HTTPS using a response with status code 301. Requires a valid certificate for all domains. %{docs_link_start}Learn more.%{link_end}"
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. %{docs_link_start}Learn more.%{link_end}"
+msgid "GitLabPages|When using Pages under the general domain of a GitLab instance (%{pages_host}), you cannot use HTTPS with subdomains of subdomains. If your namespace or groupname contains a dot, it does not work. This is a limitation of the HTTP Over TLS protocol. HTTP pages work if you don't redirect HTTP to HTTPS. %{docs_link_start}Learn more.%{link_end}"
msgstr ""
msgid "GitLabPages|With GitLab Pages you can host your static website directly from your GitLab repository. %{docs_link_start}Learn more.%{link_end}"
@@ -16625,9 +16879,6 @@ msgstr ""
msgid "Go to find file"
msgstr ""
-msgid "Go to fork"
-msgstr ""
-
msgid "Go to issue boards"
msgstr ""
@@ -16835,9 +17086,6 @@ msgstr ""
msgid "Group Hooks"
msgstr ""
-msgid "Group ID"
-msgstr ""
-
msgid "Group Owner must have signed in with SAML before enabling Group Managed Accounts"
msgstr ""
@@ -16865,9 +17113,6 @@ msgstr ""
msgid "Group by"
msgstr ""
-msgid "Group description"
-msgstr ""
-
msgid "Group description (optional)"
msgstr ""
@@ -16982,7 +17227,7 @@ msgstr ""
msgid "Group: %{name}"
msgstr ""
-msgid "GroupActivityMetrics|Issues opened"
+msgid "GroupActivityMetrics|Issues created"
msgstr ""
msgid "GroupActivityMetrics|Last 90 days"
@@ -16991,7 +17236,7 @@ msgstr ""
msgid "GroupActivityMetrics|Members added"
msgstr ""
-msgid "GroupActivityMetrics|Merge Requests opened"
+msgid "GroupActivityMetrics|Merge Requests created"
msgstr ""
msgid "GroupActivityMetrics|Recent activity"
@@ -17282,6 +17527,9 @@ msgstr ""
msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
+msgid "GroupSettings|Choose a group path that does not start with a dash or end with a period. It can also contain alphanumeric characters and underscores."
+msgstr ""
+
msgid "GroupSettings|Compliance frameworks"
msgstr ""
@@ -17315,7 +17563,7 @@ msgstr ""
msgid "GroupSettings|If not specified at the group or instance level, the default is %{default_initial_branch_name}. Does not affect existing repositories."
msgstr ""
-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."
+msgid "GroupSettings|If the parent group's visibility is lower than the group's current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility."
msgstr ""
msgid "GroupSettings|New runners registration token has been generated!"
@@ -17432,7 +17680,10 @@ msgstr ""
msgid "Groups and projects"
msgstr ""
-msgid "Groups and subgroups"
+msgid "Groups are a great way to organize projects and people."
+msgstr ""
+
+msgid "Groups are the best way to manage projects and members."
msgstr ""
msgid "Groups to synchronize"
@@ -17543,13 +17794,16 @@ msgstr ""
msgid "GroupsTree|Are you sure you want to leave the \"%{fullName}\" group?"
msgstr ""
-msgid "GroupsTree|Edit group"
+msgid "GroupsTree|Delete"
+msgstr ""
+
+msgid "GroupsTree|Edit"
msgstr ""
msgid "GroupsTree|Failed to leave the group. Please make sure you are not the only owner."
msgstr ""
-msgid "GroupsTree|Leave this group"
+msgid "GroupsTree|Leave group"
msgstr ""
msgid "GroupsTree|Loading groups"
@@ -17561,9 +17815,57 @@ msgstr ""
msgid "GroupsTree|No groups or projects matched your search"
msgstr ""
+msgid "GroupsTree|Options"
+msgstr ""
+
msgid "GroupsTree|Search by name"
msgstr ""
+msgid "Groups|Avatar will be removed. Are you sure?"
+msgstr ""
+
+msgid "Groups|Changing group URL can have unintended side effects."
+msgstr ""
+
+msgid "Groups|Checking group URL availability..."
+msgstr ""
+
+msgid "Groups|Enter a descriptive name for your group."
+msgstr ""
+
+msgid "Groups|Group ID"
+msgstr ""
+
+msgid "Groups|Group URL"
+msgstr ""
+
+msgid "Groups|Group avatar"
+msgstr ""
+
+msgid "Groups|Group description (optional)"
+msgstr ""
+
+msgid "Groups|Group name"
+msgstr ""
+
+msgid "Groups|Group path is available."
+msgstr ""
+
+msgid "Groups|Group path is unavailable. Path has been replaced with a suggested available path."
+msgstr ""
+
+msgid "Groups|Learn more"
+msgstr ""
+
+msgid "Groups|Must start with letter, digit, emoji, or underscore. Can also contain periods, dashes, spaces, and parentheses."
+msgstr ""
+
+msgid "Groups|Remove avatar"
+msgstr ""
+
+msgid "Groups|Save changes"
+msgstr ""
+
msgid "Guideline"
msgstr ""
@@ -17573,6 +17875,9 @@ msgstr ""
msgid "HAR file path or URL"
msgstr ""
+msgid "HTTP Archive (HAR)"
+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 ""
@@ -17973,6 +18278,9 @@ msgstr ""
msgid "INFO: Your SSH key is expiring soon. Please generate a new key."
msgstr ""
+msgid "IP"
+msgstr ""
+
msgid "IP Address"
msgstr ""
@@ -18009,6 +18317,9 @@ msgstr ""
msgid "IdentityVerification|Verify your identity"
msgstr ""
+msgid "IdentityVerification|You can always verify your account at a later time to create a group."
+msgstr ""
+
msgid "If any indexed field exceeds this limit, it is truncated to this number of characters. The rest of the content is neither indexed nor searchable. This does not apply to repository and wiki indexing. For unlimited characters, set this to 0."
msgstr ""
@@ -18066,6 +18377,9 @@ msgstr ""
msgid "If you add %{codeStart}needs%{codeEnd} to jobs in your pipeline you'll be able to view the %{codeStart}needs%{codeEnd} relationships between jobs in this tab as a %{linkStart}Directed Acyclic Graph (DAG)%{linkEnd}."
msgstr ""
+msgid "If you are added to a project, it will be displayed here."
+msgstr ""
+
msgid "If you did not initiate these sign-in attempts, please reach out to your administrator or enable two-factor authentication (2FA) on your account."
msgstr ""
@@ -18372,12 +18686,24 @@ msgstr ""
msgid "InProductMarketing|3 ways to dive into GitLab CI/CD"
msgstr ""
+msgid "InProductMarketing|A single application eliminates complex integrations, data chokepoints, and toolchain maintenance, resulting in greater productivity and lower cost."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features, build more efficiently, strengthen security and compliance."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features."
+msgstr ""
+
msgid "InProductMarketing|Actually, GitLab makes the team work (better)"
msgstr ""
msgid "InProductMarketing|And finally %{deploy_link} a Python application."
msgstr ""
+msgid "InProductMarketing|And many more..."
+msgstr ""
+
msgid "InProductMarketing|Are your runners ready?"
msgstr ""
@@ -18396,15 +18722,33 @@ msgstr ""
msgid "InProductMarketing|Blog"
msgstr ""
+msgid "InProductMarketing|Break down silos to coordinate seamlessly across development, operations, and security with a consistent experience across the development lifecycle."
+msgstr ""
+
+msgid "InProductMarketing|Burn up/down charts"
+msgstr ""
+
msgid "InProductMarketing|By enabling code owners and required merge approvals the right person will review the right MR. This is a win-win: cleaner code and a more efficient review process."
msgstr ""
msgid "InProductMarketing|Click on the number below that corresponds with your answer — 1 being very difficult, 5 being very easy."
msgstr ""
+msgid "InProductMarketing|Code owners"
+msgstr ""
+
msgid "InProductMarketing|Code owners and required merge approvals are part of the paid tiers of GitLab. You can start a free 30-day trial of GitLab Ultimate and enable these features in less than 5 minutes with no credit card required."
msgstr ""
+msgid "InProductMarketing|Code review analytics"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration across stages in GitLab"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration made easy"
+msgstr ""
+
msgid "InProductMarketing|Create a custom CI runner with just a few clicks"
msgstr ""
@@ -18414,12 +18758,21 @@ msgstr ""
msgid "InProductMarketing|Create a project in GitLab in 5 minutes"
msgstr ""
+msgid "InProductMarketing|Create well-defined workflows by using scoped labels on issues, merge requests, and epics. Labels with the same scope cannot be used together, which prevents conflicts."
+msgstr ""
+
msgid "InProductMarketing|Create your first project!"
msgstr ""
+msgid "InProductMarketing|Define who owns specific files or directories, so the right reviewers are suggested when a merge request introduces changes to those files."
+msgstr ""
+
msgid "InProductMarketing|Deliver Better Products Faster"
msgstr ""
+msgid "InProductMarketing|Dependency scanning"
+msgstr ""
+
msgid "InProductMarketing|Did you know teams that use GitLab are far more efficient?"
msgstr ""
@@ -18429,15 +18782,27 @@ msgstr ""
msgid "InProductMarketing|Dig in and create a project and a repo"
msgstr ""
+msgid "InProductMarketing|Discover Premium & Ultimate"
+msgstr ""
+
+msgid "InProductMarketing|Discover Premium & Ultimate."
+msgstr ""
+
msgid "InProductMarketing|Do you have a minute?"
msgstr ""
msgid "InProductMarketing|Do you have a teammate who would be perfect for this task?"
msgstr ""
+msgid "InProductMarketing|Dynamic application security testing"
+msgstr ""
+
msgid "InProductMarketing|Easy"
msgstr ""
+msgid "InProductMarketing|Epics"
+msgstr ""
+
msgid "InProductMarketing|Expand your DevOps journey with a free GitLab trial"
msgstr ""
@@ -18459,9 +18824,15 @@ msgstr ""
msgid "InProductMarketing|Feel the need for speed?"
msgstr ""
+msgid "InProductMarketing|Find and fix bottlenecks in your code review process by understanding how long open merge requests have been in review."
+msgstr ""
+
msgid "InProductMarketing|Find out how your teams are really doing"
msgstr ""
+msgid "InProductMarketing|Find out if your external libraries are safe. Run dependency scanning jobs that check for known vulnerabilities in your external libraries."
+msgstr ""
+
msgid "InProductMarketing|Follow our steps"
msgstr ""
@@ -18498,6 +18869,9 @@ msgstr ""
msgid "InProductMarketing|GitLab is better with teammates to help out!"
msgstr ""
+msgid "InProductMarketing|GitLab is infrastructure agnostic (supporting GCP, AWS, Azure, OpenShift, VMWare, On Prem, Bare Metal, and more), offering a consistent workflow experience – irrespective of the environment."
+msgstr ""
+
msgid "InProductMarketing|GitLab provides static application security testing (SAST), dynamic application security testing (DAST), container scanning, and dependency scanning to help you deliver secure applications along with license compliance."
msgstr ""
@@ -18588,21 +18962,36 @@ msgstr ""
msgid "InProductMarketing|It's also possible to simply %{external_repo_link} in order to take advantage of GitLab's CI/CD."
msgstr ""
+msgid "InProductMarketing|Keep your code quality high by defining who should approve merge requests and how many approvals are required."
+msgstr ""
+
msgid "InProductMarketing|Launch GitLab CI/CD in 20 minutes or less"
msgstr ""
+msgid "InProductMarketing|Lower cost of development"
+msgstr ""
+
+msgid "InProductMarketing|Make it easier to collaborate on high-level ideas by grouping related issues in an epic."
+msgstr ""
+
msgid "InProductMarketing|Making the switch? It's easier than you think to import your projects into GitLab. Move %{github_link}, or import something %{bitbucket_link}."
msgstr ""
msgid "InProductMarketing|Master the art of importing!"
msgstr ""
+msgid "InProductMarketing|Merge request approval rule"
+msgstr ""
+
msgid "InProductMarketing|Move on to easily creating a Pages website %{ci_template_link}"
msgstr ""
msgid "InProductMarketing|Multiple owners, confusing workstreams? We've got you covered"
msgstr ""
+msgid "InProductMarketing|Multiple required approvers"
+msgstr ""
+
msgid "InProductMarketing|Need an alternative to importing?"
msgstr ""
@@ -18615,18 +19004,33 @@ msgstr ""
msgid "InProductMarketing|Our tool brings all the things together"
msgstr ""
+msgid "InProductMarketing|Protect your web application by using DAST to examine for vulnerabilities in deployed environments."
+msgstr ""
+
msgid "InProductMarketing|Rapid development, simplified"
msgstr ""
msgid "InProductMarketing|Reduce Security & Compliance Risk"
msgstr ""
+msgid "InProductMarketing|Require multiple approvers on a merge request, so you know it's in good shape before it's merged."
+msgstr ""
+
+msgid "InProductMarketing|Roadmaps"
+msgstr ""
+
+msgid "InProductMarketing|Scoped labels"
+msgstr ""
+
msgid "InProductMarketing|Security that's integrated into your development lifecycle"
msgstr ""
msgid "InProductMarketing|Sometimes you're not ready to make a full transition to a new tool. If you're not ready to fully commit, %{mirroring_link} gives you a safe way to try out GitLab in parallel with your current tool."
msgstr ""
+msgid "InProductMarketing|Speed. Efficiency. Trust."
+msgstr ""
+
msgid "InProductMarketing|Spin up an autoscaling runner in GitLab"
msgstr ""
@@ -18636,6 +19040,9 @@ msgstr ""
msgid "InProductMarketing|Start a Self-Managed trial"
msgstr ""
+msgid "InProductMarketing|Start a free trial"
+msgstr ""
+
msgid "InProductMarketing|Start a free trial of GitLab Ultimate – no credit card required"
msgstr ""
@@ -18702,6 +19109,9 @@ msgstr ""
msgid "InProductMarketing|To understand and get the most out of GitLab, start at the beginning and %{project_link}. In GitLab, repositories are part of a project, so after you've created your project you can go ahead and %{repo_link}."
msgstr ""
+msgid "InProductMarketing|Track completed issues in a chart, so you can see how a milestone is progressing at a glance."
+msgstr ""
+
msgid "InProductMarketing|Try GitLab Ultimate for free"
msgstr ""
@@ -18738,6 +19148,9 @@ msgstr ""
msgid "InProductMarketing|Very easy"
msgstr ""
+msgid "InProductMarketing|Visualize your epics and milestones in a timeline."
+msgstr ""
+
msgid "InProductMarketing|Want to host GitLab on your servers?"
msgstr ""
@@ -18759,6 +19172,9 @@ msgstr ""
msgid "InProductMarketing|YouTube"
msgstr ""
+msgid "InProductMarketing|Your software, deployed your way"
+msgstr ""
+
msgid "InProductMarketing|Your teams can be more efficient"
msgstr ""
@@ -18879,9 +19295,18 @@ msgstr ""
msgid "IncidentManagement|No incidents to display."
msgstr ""
+msgid "IncidentManagement|None"
+msgstr ""
+
msgid "IncidentManagement|Open"
msgstr ""
+msgid "IncidentManagement|Page your team with escalation policies"
+msgstr ""
+
+msgid "IncidentManagement|Paged"
+msgstr ""
+
msgid "IncidentManagement|Published"
msgstr ""
@@ -18891,6 +19316,9 @@ msgstr ""
msgid "IncidentManagement|Severity"
msgstr ""
+msgid "IncidentManagement|Status"
+msgstr ""
+
msgid "IncidentManagement|There are no closed incidents"
msgstr ""
@@ -18909,6 +19337,9 @@ msgstr ""
msgid "IncidentManagement|Unpublished"
msgstr ""
+msgid "IncidentManagement|Use escalation policies to automatically page your team when incidents are created."
+msgstr ""
+
msgid "IncidentSettings|Activate \"time to SLA\" countdown timer"
msgstr ""
@@ -18954,7 +19385,10 @@ msgstr ""
msgid "Incidents"
msgstr ""
-msgid "Incidents|Add a URL"
+msgid "Incidents|Add image details"
+msgstr ""
+
+msgid "Incidents|Add text or a link to display with your image. If you don't add either, the file name displays instead."
msgstr ""
msgid "Incidents|Drop or %{linkStart}upload%{linkEnd} a metric screenshot to attach it to the incident"
@@ -18969,10 +19403,10 @@ msgstr ""
msgid "Incidents|There was an issue loading metric images."
msgstr ""
-msgid "Incidents|There was an issue uploading your image."
+msgid "Incidents|There was an issue updating your image."
msgstr ""
-msgid "Incidents|You can optionally add a URL to link users to the original graph."
+msgid "Incidents|There was an issue uploading your image."
msgstr ""
msgid "Incident|Alert details"
@@ -18981,9 +19415,18 @@ msgstr ""
msgid "Incident|Are you sure you wish to delete this image?"
msgstr ""
+msgid "Incident|Delete image"
+msgstr ""
+
msgid "Incident|Deleting %{filename}"
msgstr ""
+msgid "Incident|Edit image text or link"
+msgstr ""
+
+msgid "Incident|Editing %{filename}"
+msgstr ""
+
msgid "Incident|Metrics"
msgstr ""
@@ -19253,12 +19696,18 @@ msgstr ""
msgid "Integrations|Branches for which notifications are to be sent"
msgstr ""
+msgid "Integrations|Clear if using a self-signed certificate."
+msgstr ""
+
msgid "Integrations|Comment detail:"
msgstr ""
msgid "Integrations|Comment settings:"
msgstr ""
+msgid "Integrations|Connection details"
+msgstr ""
+
msgid "Integrations|Connection failed. Please check your settings."
msgstr ""
@@ -19283,6 +19732,9 @@ msgstr ""
msgid "Integrations|Enable GitLab.com slash commands in a Slack workspace."
msgstr ""
+msgid "Integrations|Enable SSL verification"
+msgstr ""
+
msgid "Integrations|Enable comments"
msgstr ""
@@ -19361,6 +19813,9 @@ msgstr ""
msgid "Integrations|Return to GitLab for Jira"
msgstr ""
+msgid "Integrations|SSL verification"
+msgstr ""
+
msgid "Integrations|Save settings?"
msgstr ""
@@ -19406,9 +19861,6 @@ msgstr ""
msgid "Integrations|Use default settings"
msgstr ""
-msgid "Integrations|When you mention a Jira issue in a commit or merge request, GitLab creates a remote link and comment (if enabled)."
-msgstr ""
-
msgid "Integrations|You can now close this window and return to the GitLab for Jira application."
msgstr ""
@@ -19433,9 +19885,6 @@ msgstr ""
msgid "Integrations|can't exceed %{recipients_limit}"
msgstr ""
-msgid "Interactive developer security education."
-msgstr ""
-
msgid "Interactive mode"
msgstr ""
@@ -19925,6 +20374,9 @@ msgstr ""
msgid "IssueAnalytics|Assignees"
msgstr ""
+msgid "IssueAnalytics|Created by"
+msgstr ""
+
msgid "IssueAnalytics|Due date"
msgstr ""
@@ -19937,9 +20389,6 @@ msgstr ""
msgid "IssueAnalytics|Milestone"
msgstr ""
-msgid "IssueAnalytics|Opened by"
-msgstr ""
-
msgid "IssueAnalytics|Status"
msgstr ""
@@ -20063,10 +20512,10 @@ msgstr ""
msgid "IssuesAnalytics|Avg/Month:"
msgstr ""
-msgid "IssuesAnalytics|Issues opened"
+msgid "IssuesAnalytics|Issues created"
msgstr ""
-msgid "IssuesAnalytics|Issues opened per month"
+msgid "IssuesAnalytics|Issues created per month"
msgstr ""
msgid "IssuesAnalytics|Last 12 months"
@@ -20093,6 +20542,9 @@ msgstr ""
msgid "It looks like you have some draft commits in this branch."
msgstr ""
+msgid "It looks like you're attempting to activate your subscription. Use %{a_start}the Subscription page%{a_end} instead."
+msgstr ""
+
msgid "It may be several days before you see feature usage data."
msgstr ""
@@ -20321,6 +20773,9 @@ msgstr ""
msgid "JiraConnect|You can now close this window and return to Jira."
msgstr ""
+msgid "JiraConnect|You don't have permission to create branches for this project. Select a different project or contact the project owner for access. %{linkStart}Learn more.%{linkEnd}"
+msgstr ""
+
msgid "JiraRequest|A connection error occurred while connecting to Jira. Try your request again."
msgstr ""
@@ -20369,13 +20824,13 @@ msgstr ""
msgid "JiraService|Define the type of Jira issue to create from a vulnerability."
msgstr ""
-msgid "JiraService|Displaying Jira issues while leaving the GitLab issue functionality enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
+msgid "JiraService|Displaying Jira issues while leaving GitLab issues also enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
msgstr ""
-msgid "JiraService|Enable Jira issues"
+msgid "JiraService|Enable Jira issue creation from vulnerabilities"
msgstr ""
-msgid "JiraService|Enable Jira issues creation from vulnerabilities"
+msgid "JiraService|Enable Jira issues"
msgstr ""
msgid "JiraService|Enable Jira transitions"
@@ -20492,16 +20947,19 @@ msgstr ""
msgid "JiraService|View Jira issues in GitLab"
msgstr ""
-msgid "JiraService|Warning: All GitLab users that have access to this GitLab project are able to view all issues from the Jira project specified below."
+msgid "JiraService|Warning: All GitLab users with access to this GitLab project can view all issues from the Jira project you select."
msgstr ""
msgid "JiraService|Web URL"
msgstr ""
-msgid "JiraService|Work on Jira issues without leaving GitLab. Adds a Jira menu to access your list of Jira issues and view any issue as read-only."
+msgid "JiraService|When a Jira issue is mentioned in a commit or merge request, a remote link and comment (if enabled) will be created."
+msgstr ""
+
+msgid "JiraService|Work on Jira issues without leaving GitLab. Add a Jira menu to access a read-only list of your Jira issues."
msgstr ""
-msgid "JiraService|You need to configure Jira before enabling this integration. For more details, read the %{jira_doc_link_start}Jira integration documentation%{link_end}."
+msgid "JiraService|You must configure Jira before enabling this integration. %{jira_doc_link_start}Learn more.%{link_end}"
msgstr ""
msgid "Job"
@@ -20513,9 +20971,6 @@ msgstr ""
msgid "Job Failed #%{build_id}"
msgstr ""
-msgid "Job ID"
-msgstr ""
-
msgid "Job artifact"
msgstr ""
@@ -20582,9 +21037,27 @@ msgstr ""
msgid "Jobs|You're about to retry a job that failed because it attempted to deploy code that is older than the latest deployment. Retrying this job could result in overwriting the environment with the older source code."
msgstr ""
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source} into %{target}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{ref}"
+msgstr ""
+
+msgid "Job|Are you sure you want to erase this job log and artifacts?"
+msgstr ""
+
msgid "Job|Browse"
msgstr ""
+msgid "Job|Cancel"
+msgstr ""
+
msgid "Job|Complete Raw"
msgstr ""
@@ -20594,6 +21067,9 @@ msgstr ""
msgid "Job|Erase job log and artifacts"
msgstr ""
+msgid "Job|Finished at"
+msgstr ""
+
msgid "Job|Job artifacts"
msgstr ""
@@ -20606,7 +21082,7 @@ msgstr ""
msgid "Job|Keep"
msgstr ""
-msgid "Job|Pipeline"
+msgid "Job|Retry"
msgstr ""
msgid "Job|Scroll to bottom"
@@ -20618,6 +21094,9 @@ msgstr ""
msgid "Job|Show complete raw"
msgstr ""
+msgid "Job|Status"
+msgstr ""
+
msgid "Job|The artifacts were removed"
msgstr ""
@@ -20645,21 +21124,12 @@ msgstr ""
msgid "Job|delayed"
msgstr ""
-msgid "Job|for"
-msgstr ""
-
-msgid "Job|into"
-msgstr ""
-
msgid "Job|manual"
msgstr ""
msgid "Job|triggered"
msgstr ""
-msgid "Job|with"
-msgstr ""
-
msgid "Join Zoom meeting"
msgstr ""
@@ -20762,9 +21232,6 @@ msgstr ""
msgid "Ki"
msgstr ""
-msgid "Kontra"
-msgstr ""
-
msgid "Kroki"
msgstr ""
@@ -21088,6 +21555,9 @@ msgstr ""
msgid "Learn more about Auto DevOps"
msgstr ""
+msgid "Learn more about GitLab"
+msgstr ""
+
msgid "Learn more about Needs relationships"
msgstr ""
@@ -21415,9 +21885,18 @@ msgstr ""
msgid "Licenses|Displays licenses detected in the project, based on the %{linkStart}latest successful%{linkEnd} scan"
msgstr ""
+msgid "Licenses|Drag your license file here or %{linkStart}click to upload%{linkEnd}."
+msgstr ""
+
+msgid "Licenses|Drop your license file to start the upload."
+msgstr ""
+
msgid "Licenses|Error fetching the license list. Please check your network connection and try again."
msgstr ""
+msgid "Licenses|Error: You are trying to upload something other than a file"
+msgstr ""
+
msgid "Licenses|License Compliance"
msgstr ""
@@ -21436,6 +21915,9 @@ msgstr ""
msgid "Licenses|Specified policies in this project"
msgstr ""
+msgid "Licenses|The file could not be uploaded."
+msgstr ""
+
msgid "Licenses|The license list details information about the licenses used within your project."
msgstr ""
@@ -21469,11 +21951,6 @@ msgstr ""
msgid "Limit the size of Sidekiq jobs stored in Redis."
msgstr ""
-msgid "Limited to showing %d event at most"
-msgid_plural "Limited to showing %d events at most"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Limiting mode"
msgstr ""
@@ -21483,6 +21960,9 @@ msgstr ""
msgid "Link"
msgstr ""
+msgid "Link (optional)"
+msgstr ""
+
msgid "Link Prometheus monitoring to GitLab."
msgstr ""
@@ -21519,6 +21999,9 @@ msgstr ""
msgid "Linked emails (%{email_count})"
msgstr ""
+msgid "Linked epics"
+msgstr ""
+
msgid "Linked issues"
msgstr ""
@@ -21546,6 +22029,15 @@ msgstr ""
msgid "List of all merge commits"
msgstr ""
+msgid "List of environments for this project"
+msgstr ""
+
+msgid "List of suitable GCP locations"
+msgstr ""
+
+msgid "List of users allowed to exceed the rate limit."
+msgstr ""
+
msgid "List options"
msgstr ""
@@ -21765,6 +22257,9 @@ msgstr ""
msgid "Maintenance mode"
msgstr ""
+msgid "Make adjustments to how your GitLab instance is set up."
+msgstr ""
+
msgid "Make and review changes in the browser with the Web IDE"
msgstr ""
@@ -21909,6 +22404,12 @@ msgstr ""
msgid "MarkdownEditor|Add italic text (%{modifier_key}I)"
msgstr ""
+msgid "MarkdownEditor|Add strikethrough text (%{modifierKey}⇧X)"
+msgstr ""
+
+msgid "MarkdownEditor|Add strikethrough text (%{modifier_key}⇧X)"
+msgstr ""
+
msgid "Marked For Deletion At - %{deletion_time}"
msgstr ""
@@ -22170,6 +22671,9 @@ msgstr ""
msgid "Maximum push size (MB)"
msgstr ""
+msgid "Maximum requests per 10 minutes per user"
+msgstr ""
+
msgid "Maximum requests per minute"
msgstr ""
@@ -22260,6 +22764,19 @@ msgstr ""
msgid "Members of a group may only view projects they have permission to access"
msgstr ""
+msgid "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seat in use and will be billed for the overage."
+msgid_plural "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seats in use and will be billed for the overage."
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "MembersOverage|You are about to incur additional charges"
+msgstr ""
+
+msgid "MembersOverage|Your subscription includes %d seat."
+msgid_plural "MembersOverage|Your subscription includes %d seats."
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Membership"
msgstr ""
@@ -22464,9 +22981,6 @@ msgstr ""
msgid "Merge request not merged"
msgstr ""
-msgid "Merge request pipelines 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 merge request pipelines."
-msgstr ""
-
msgid "Merge request reports"
msgstr ""
@@ -22563,13 +23077,13 @@ msgstr ""
msgid "MergeRequests|Create issue to resolve thread"
msgstr ""
-msgid "MergeRequests|Failed to squash. Should be done manually."
+msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Saving the comment failed"
+msgid "MergeRequests|Squashing failed: Squash the commits locally, resolve any conflicts, then push the branch."
msgstr ""
-msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
+msgid "MergeRequests|Squashing not allowed: This project doesn't allow you to squash commits when merging."
msgstr ""
msgid "MergeRequests|Thread stays resolved"
@@ -23410,6 +23924,18 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "MrList|Assigned to %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from assignee %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from reviewer %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Review requested from %{name}, go to their profile."
+msgstr ""
+
msgid "Multi-project"
msgstr ""
@@ -23443,7 +23969,7 @@ msgstr ""
msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "My Awesome Group"
+msgid "My awesome group"
msgstr ""
msgid "My company or team"
@@ -24065,9 +24591,6 @@ msgstr ""
msgid "No available branches"
msgstr ""
-msgid "No available groups to fork the project."
-msgstr ""
-
msgid "No branches found"
msgstr ""
@@ -24278,6 +24801,9 @@ msgstr ""
msgid "No ref selected"
msgstr ""
+msgid "No regions configured"
+msgstr ""
+
msgid "No related merge requests found."
msgstr ""
@@ -25082,6 +25608,9 @@ msgstr ""
msgid "Only reCAPTCHA v2 is supported:"
msgstr ""
+msgid "Only required if not using role instance credentials."
+msgstr ""
+
msgid "Only use lowercase letters, numbers, and underscores."
msgstr ""
@@ -25106,9 +25635,6 @@ msgstr ""
msgid "Open a CLI and connect to the cluster you want to install the agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
-msgid "Open epics"
-msgstr ""
-
msgid "Open errors"
msgstr ""
@@ -25148,7 +25674,7 @@ msgstr ""
msgid "Opened issues"
msgstr ""
-msgid "OpenedNDaysAgo|Opened"
+msgid "OpenedNDaysAgo|Created"
msgstr ""
msgid "Opens in a new window"
@@ -25193,9 +25719,6 @@ msgstr ""
msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
-msgid "Optional."
-msgstr ""
-
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
msgstr ""
@@ -25984,6 +26507,9 @@ msgstr ""
msgid "PerformanceBar|Memory"
msgstr ""
+msgid "PerformanceBar|Memory report"
+msgstr ""
+
msgid "PerformanceBar|Redis calls"
msgstr ""
@@ -26017,18 +26543,12 @@ msgstr ""
msgid "PerformanceBar|wall"
msgstr ""
-msgid "Performs a rebase but skips triggering a new pipeline"
-msgstr ""
-
msgid "Period in seconds"
msgstr ""
msgid "Permalink"
msgstr ""
-msgid "Permanently delete project"
-msgstr ""
-
msgid "Permanently remove group"
msgstr ""
@@ -26299,6 +26819,51 @@ msgstr ""
msgid "PipelineStatusTooltip|Pipeline: %{ci_status}"
msgstr ""
+msgid "PipelineWizardDefaultCommitMessage|Add %{filename}"
+msgstr ""
+
+msgid "PipelineWizardDefaultCommitMessage|Update %{filename}"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|At least one entry is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This field is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This value is not valid"
+msgstr ""
+
+msgid "PipelineWizardListWidget|add another step"
+msgstr ""
+
+msgid "PipelineWizardListWidget|remove step"
+msgstr ""
+
+msgid "PipelineWizard|Commit"
+msgstr ""
+
+msgid "PipelineWizard|Commit Message"
+msgstr ""
+
+msgid "PipelineWizard|Commit changes to your file"
+msgstr ""
+
+msgid "PipelineWizard|Commit file to Branch"
+msgstr ""
+
+msgid "PipelineWizard|Commit your new file"
+msgstr ""
+
+msgid "PipelineWizard|The file has been committed."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem committing the changes."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem while checking whether your file already exists in the specified branch."
+msgstr ""
+
msgid "Pipelines"
msgstr ""
@@ -26413,7 +26978,7 @@ msgstr ""
msgid "Pipelines|Project cache successfully reset."
msgstr ""
-msgid "Pipelines|Revoke"
+msgid "Pipelines|Revoke trigger"
msgstr ""
msgid "Pipelines|Something went wrong while cleaning runners cache."
@@ -26458,6 +27023,12 @@ msgstr ""
msgid "Pipelines|This is a child pipeline within the parent pipeline"
msgstr ""
+msgid "Pipelines|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipelines|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipelines|This pipeline will run code originating from a forked project merge request. This means that the code can potentially have security considerations like exposing CI variables."
msgstr ""
@@ -26500,9 +27071,6 @@ msgstr ""
msgid "Pipelines|Your changes have been successfully committed. Now redirecting to the new merge request page."
msgstr ""
-msgid "Pipelines|detached"
-msgstr ""
-
msgid "Pipelines|error"
msgstr ""
@@ -26512,10 +27080,13 @@ msgstr ""
msgid "Pipelines|latest"
msgstr ""
-msgid "Pipelines|stuck"
+msgid "Pipelines|merge request"
msgstr ""
-msgid "Pipelines|train"
+msgid "Pipelines|merge train"
+msgstr ""
+
+msgid "Pipelines|stuck"
msgstr ""
msgid "Pipelines|yaml invalid"
@@ -26647,6 +27218,12 @@ msgstr ""
msgid "Pipeline|This change will not change the overall test coverage if merged."
msgstr ""
+msgid "Pipeline|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipeline|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipeline|Trigger author"
msgstr ""
@@ -26671,6 +27248,12 @@ msgstr ""
msgid "Pipeline|for"
msgstr ""
+msgid "Pipeline|merge request"
+msgstr ""
+
+msgid "Pipeline|merge train"
+msgstr ""
+
msgid "Pipeline|on"
msgstr ""
@@ -26809,9 +27392,6 @@ msgstr ""
msgid "Please enter a valid time interval"
msgstr ""
-msgid "Please enter or upload a valid license."
-msgstr ""
-
msgid "Please enter your current password."
msgstr ""
@@ -26920,9 +27500,6 @@ msgstr ""
msgid "Please type %{phrase_code} to proceed or close this modal to cancel."
msgstr ""
-msgid "Please type the following to confirm:"
-msgstr ""
-
msgid "Please use this form to report to the admin users who create spam issues, comments or behave inappropriately."
msgstr ""
@@ -26950,12 +27527,27 @@ msgstr ""
msgid "Policies"
msgstr ""
+msgid "Policy '%{escalation_policy_name}' does not exist."
+msgstr ""
+
msgid "Policy management project does have any policies in %{policy_path}"
msgstr ""
msgid "Policy project doesn't exist"
msgstr ""
+msgid "PolicyRuleMultiSelect|%{firstLabel} +%{numberOfAdditionalLabels} more"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|All %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select all"
+msgstr ""
+
msgid "Polling interval multiplier"
msgstr ""
@@ -27184,6 +27776,9 @@ msgstr ""
msgid "Private projects can be created in your personal namespace with:"
msgstr ""
+msgid "Problem with %{name} command: %{message}."
+msgstr ""
+
msgid "Proceed"
msgstr ""
@@ -27658,6 +28253,9 @@ msgstr ""
msgid "Progress"
msgstr ""
+msgid "Progress tracking"
+msgstr ""
+
msgid "Project"
msgstr ""
@@ -27889,6 +28487,9 @@ msgstr ""
msgid "ProjectQualitySummary|Failure"
msgstr ""
+msgid "ProjectQualitySummary|Get insight into the overall percentage of tests in your project that succeed, fail and are skipped."
+msgstr ""
+
msgid "ProjectQualitySummary|Latest pipeline results"
msgstr ""
@@ -27907,6 +28508,12 @@ msgstr ""
msgid "ProjectQualitySummary|See project Code Coverage Statistics"
msgstr ""
+msgid "ProjectQualitySummary|Set up test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|Set up test runs (opens in a new tab)"
+msgstr ""
+
msgid "ProjectQualitySummary|Skipped"
msgstr ""
@@ -28183,13 +28790,19 @@ msgstr ""
msgid "ProjectSettings|LFS objects from this repository are available to forks. %{linkStart}How do I remove them?%{linkEnd}"
msgstr ""
+msgid "ProjectSettings|Learn about commit history."
+msgstr ""
+
+msgid "ProjectSettings|Leave empty to use default template."
+msgstr ""
+
msgid "ProjectSettings|Manage who can see the project in the public access directory."
msgstr ""
msgid "ProjectSettings|Manages large files such as audio, video, and graphics files."
msgstr ""
-msgid "ProjectSettings|Maximum 500 characters."
+msgid "ProjectSettings|Maximum %{maxLength} characters."
msgstr ""
msgid "ProjectSettings|Merge checks"
@@ -28330,6 +28943,9 @@ msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
msgstr ""
+msgid "ProjectSettings|The default template will be applied on save."
+msgstr ""
+
msgid "ProjectSettings|These checks must pass before merge requests can be merged."
msgstr ""
@@ -28384,6 +29000,9 @@ msgstr ""
msgid "ProjectSettings|What are badges?"
msgstr ""
+msgid "ProjectSettings|What are merge trains?"
+msgstr ""
+
msgid "ProjectSettings|When merge request pipelines are enabled in the CI/CD configuration file, pipelines validate the combined results of the source and target branches. %{link_start}How to configure merge request pipelines?%{link_end}"
msgstr ""
@@ -28501,6 +29120,9 @@ msgstr ""
msgid "Projects are organized into groups"
msgstr ""
+msgid "Projects are where you store your code, access issues, wiki and other features of GitLab."
+msgstr ""
+
msgid "Projects contributed to"
msgstr ""
@@ -28516,12 +29138,6 @@ msgstr ""
msgid "Projects to index"
msgstr ""
-msgid "Projects will be permanently deleted after a %{waiting_period}-day waiting period."
-msgstr ""
-
-msgid "Projects will be permanently deleted immediately."
-msgstr ""
-
msgid "Projects with critical vulnerabilities"
msgstr ""
@@ -28606,6 +29222,9 @@ msgstr ""
msgid "ProjectsNew|Import project"
msgstr ""
+msgid "ProjectsNew|Include a Getting Started README"
+msgstr ""
+
msgid "ProjectsNew|Initialize repository with a README"
msgstr ""
@@ -28621,6 +29240,9 @@ msgstr ""
msgid "ProjectsNew|Project description %{tag_start}(optional)%{tag_end}"
msgstr ""
+msgid "ProjectsNew|Recommended if you're new to GitLab"
+msgstr ""
+
msgid "ProjectsNew|Run CI/CD for external repository"
msgstr ""
@@ -29038,6 +29660,9 @@ msgstr ""
msgid "ProtectedBranch|Unprotect"
msgstr ""
+msgid "ProtectedBranch|Unprotect branch"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
@@ -29065,6 +29690,9 @@ msgstr ""
msgid "ProtectedEnvironment|Protected Environment (%{protected_environments_count})"
msgstr ""
+msgid "ProtectedEnvironment|Required approvals"
+msgstr ""
+
msgid "ProtectedEnvironment|Select an environment"
msgstr ""
@@ -29086,10 +29714,13 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|Unprotect tag"
+msgstr ""
+
msgid "ProtectedTags|default"
msgstr ""
-msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
+msgid "ProtectedTag|By default, protected tags restrict who can modify the tag."
msgstr ""
msgid "ProtectedTag|Learn more."
@@ -29152,6 +29783,9 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Public projects are an easy way to allow everyone to have read-only access."
+msgstr ""
+
msgid "Publish to status page"
msgstr ""
@@ -29308,9 +29942,6 @@ msgstr ""
msgid "QualitySummary|Project quality"
msgstr ""
-msgid "Quarters"
-msgstr ""
-
msgid "Query"
msgstr ""
@@ -29395,6 +30026,9 @@ msgstr ""
msgid "Read more about project permissions %{help_link_open}here%{help_link_close}"
msgstr ""
+msgid "Read more about related epics"
+msgstr ""
+
msgid "Read more about related issues"
msgstr ""
@@ -29425,10 +30059,7 @@ msgstr ""
msgid "Rebase source branch on the target branch."
msgstr ""
-msgid "Rebase without CI"
-msgstr ""
-
-msgid "Rebases and triggers a pipeline"
+msgid "Rebase without pipeline"
msgstr ""
msgid "Recaptcha verified?"
@@ -29479,9 +30110,6 @@ msgstr ""
msgid "Reconfigure"
msgstr ""
-msgid "Recovering projects"
-msgstr ""
-
msgid "Recovery Codes"
msgstr ""
@@ -29541,6 +30169,12 @@ msgstr ""
msgid "Regex pattern"
msgstr ""
+msgid "Region"
+msgstr ""
+
+msgid "Regions"
+msgstr ""
+
msgid "Register"
msgstr ""
@@ -29771,9 +30405,6 @@ msgstr ""
msgid "Remove all or specific reviewer(s)"
msgstr ""
-msgid "Remove approver"
-msgstr ""
-
msgid "Remove approvers"
msgstr ""
@@ -29789,6 +30420,9 @@ msgstr ""
msgid "Remove attention request"
msgstr ""
+msgid "Remove attention request(s)"
+msgstr ""
+
msgid "Remove avatar"
msgstr ""
@@ -29927,6 +30561,9 @@ msgstr ""
msgid "Removed an issue from an epic."
msgstr ""
+msgid "Removed attention from %{users_sentence}."
+msgstr ""
+
msgid "Removed attention request from @%{username}"
msgstr ""
@@ -29978,6 +30615,9 @@ msgstr ""
msgid "Removes an issue from an epic."
msgstr ""
+msgid "Removes attention from %{users_sentence}."
+msgstr ""
+
msgid "Removes parent epic %{epic_ref}."
msgstr ""
@@ -30089,6 +30729,9 @@ msgstr ""
msgid "Report abuse to admin"
msgstr ""
+msgid "Report is generating and will be sent to your email address."
+msgstr ""
+
msgid "Reported %{timeAgo} by %{reportedBy}"
msgstr ""
@@ -30378,6 +31021,15 @@ msgstr ""
msgid "Request attention"
msgstr ""
+msgid "Request attention from %{users_sentence}."
+msgstr ""
+
+msgid "Request attention from assignee or reviewer"
+msgstr ""
+
+msgid "Request attention from assignee(s) or reviewer(s)"
+msgstr ""
+
msgid "Request attention to review"
msgstr ""
@@ -30402,6 +31054,9 @@ msgstr ""
msgid "Requested %{time_ago}"
msgstr ""
+msgid "Requested attention from %{users_sentence}."
+msgstr ""
+
msgid "Requested attention from @%{username}"
msgstr ""
@@ -30616,6 +31271,9 @@ msgstr ""
msgid "Restore project"
msgstr ""
+msgid "Restoring projects"
+msgstr ""
+
msgid "Restoring the group will prevent the group, its subgroups and projects from being removed on this date."
msgstr ""
@@ -30646,6 +31304,9 @@ msgstr ""
msgid "Retry"
msgstr ""
+msgid "Retry failed jobs"
+msgstr ""
+
msgid "Retry job"
msgstr ""
@@ -30693,9 +31354,6 @@ msgstr ""
msgid "Review changes"
msgstr ""
-msgid "Review requested from %{name}"
-msgstr ""
-
msgid "Review requests for you"
msgstr ""
@@ -30860,6 +31518,9 @@ msgstr ""
msgid "Runners|Assigned Group"
msgstr ""
+msgid "Runners|Assigned Projects (%{projectCount})"
+msgstr ""
+
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30929,6 +31590,9 @@ msgstr ""
msgid "Runners|Instance"
msgstr ""
+msgid "Runners|Jobs"
+msgstr ""
+
msgid "Runners|Last contact"
msgstr ""
@@ -31022,9 +31686,6 @@ msgstr ""
msgid "Runners|Runner %{name} was deleted"
msgstr ""
-msgid "Runners|Runner ID"
-msgstr ""
-
msgid "Runners|Runner assigned to project."
msgstr ""
@@ -31172,6 +31833,9 @@ msgstr ""
msgid "Runners|stale"
msgstr ""
+msgid "Runner|This runner has not run any jobs."
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -31286,6 +31950,24 @@ msgstr ""
msgid "Saving project."
msgstr ""
+msgid "ScanResultPolicy|%{ifLabelStart}if%{ifLabelEnd} %{scanners} scan in an open merge request targeting the %{branches} branch(es) finds %{vulnerabilitiesAllowed} or more %{severities} vulnerabilities that are %{vulnerabilityStates}"
+msgstr ""
+
+msgid "ScanResultPolicy|%{thenLabelStart}Then%{thenLabelEnd} Require approval from %{approvalsRequired} of the following approvers: %{approvers}"
+msgstr ""
+
+msgid "ScanResultPolicy|add an approver"
+msgstr ""
+
+msgid "ScanResultPolicy|scanners"
+msgstr ""
+
+msgid "ScanResultPolicy|severity levels"
+msgstr ""
+
+msgid "ScanResultPolicy|vulnerability states"
+msgstr ""
+
msgid "Scanner"
msgstr ""
@@ -31418,6 +32100,9 @@ msgstr ""
msgid "Search for a user"
msgstr ""
+msgid "Search for an emoji"
+msgstr ""
+
msgid "Search for projects, issues, etc."
msgstr ""
@@ -31605,18 +32290,12 @@ msgstr ""
msgid "Secret Detection"
msgstr ""
-msgid "Secret access key"
-msgstr ""
-
msgid "Secret token"
msgstr ""
msgid "Secure token that identifies an external storage request."
msgstr ""
-msgid "SecureCodeWarrior"
-msgstr ""
-
msgid "Security"
msgstr ""
@@ -31641,9 +32320,6 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "Security training with guide and learning pathways."
-msgstr ""
-
msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
@@ -31746,7 +32422,7 @@ msgstr ""
msgid "SecurityConfiguration|Manage corpus"
msgstr ""
-msgid "SecurityConfiguration|Manage corpus files used as mutation sources in coverage fuzzing."
+msgid "SecurityConfiguration|Manage corpus files used as seed inputs with coverage-guided fuzzing."
msgstr ""
msgid "SecurityConfiguration|Manage profiles for use by DAST scans."
@@ -31812,15 +32488,15 @@ msgstr ""
msgid "SecurityOrchestration|.yaml preview"
msgstr ""
-msgid "SecurityOrchestration|Action"
-msgstr ""
-
msgid "SecurityOrchestration|Actions"
msgstr ""
msgid "SecurityOrchestration|Add rule"
msgstr ""
+msgid "SecurityOrchestration|After dismissing the alert, the information will never be shown again."
+msgstr ""
+
msgid "SecurityOrchestration|All policies"
msgstr ""
@@ -31836,7 +32512,7 @@ msgstr ""
msgid "SecurityOrchestration|Description"
msgstr ""
-msgid "SecurityOrchestration|Disabled"
+msgid "SecurityOrchestration|Don't show the alert anymore"
msgstr ""
msgid "SecurityOrchestration|Edit policy"
@@ -31845,13 +32521,13 @@ msgstr ""
msgid "SecurityOrchestration|Edit policy project"
msgstr ""
-msgid "SecurityOrchestration|Enabled"
+msgid "SecurityOrchestration|Empty policy name"
msgstr ""
-msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Enabled"
msgstr ""
-msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
msgstr ""
msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
@@ -31860,7 +32536,7 @@ msgstr ""
msgid "SecurityOrchestration|Invalid policy type"
msgstr ""
-msgid "SecurityOrchestration|Latest scan"
+msgid "SecurityOrchestration|Latest scan run against %{agent}"
msgstr ""
msgid "SecurityOrchestration|Network"
@@ -31869,15 +32545,27 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No actions defined - policy will not run."
+msgstr ""
+
+msgid "SecurityOrchestration|No description"
+msgstr ""
+
msgid "SecurityOrchestration|No rules defined - policy will not run."
msgstr ""
+msgid "SecurityOrchestration|Not enabled"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
msgid "SecurityOrchestration|Policies"
msgstr ""
+msgid "SecurityOrchestration|Policy Type"
+msgstr ""
+
msgid "SecurityOrchestration|Policy cannot be enabled for non-existing branches (%{branches})"
msgstr ""
@@ -31902,10 +32590,13 @@ msgstr ""
msgid "SecurityOrchestration|Require %{approvals} %{plural} from %{approvers} if any of the following occur:"
msgstr ""
-msgid "SecurityOrchestration|Rule"
+msgid "SecurityOrchestration|Rules"
msgstr ""
-msgid "SecurityOrchestration|Rules"
+msgid "SecurityOrchestration|Runs %{actions} and %{lastAction} scans"
+msgstr ""
+
+msgid "SecurityOrchestration|Runs a %{action} scan"
msgstr ""
msgid "SecurityOrchestration|Scan Execution"
@@ -31965,6 +32656,9 @@ msgstr ""
msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
+msgid "SecurityOrchestration|This view only shows scan results for the agent %{agent}. You can view scan results for all agents in the %{linkStart}Operational Vulnerabilities tab of the vulnerability report%{linkEnd}."
+msgstr ""
+
msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
@@ -32019,9 +32713,6 @@ msgstr ""
msgid "SecurityOrchestration|users with ids"
msgstr ""
-msgid "SecurityOrchestration|view results"
-msgstr ""
-
msgid "SecurityOrchestration|vulnerabilities"
msgstr ""
@@ -32691,22 +33382,19 @@ 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|In order to start using functions as a service, you must first install Knative on your Kubernetes cluster. %{linkStart}More information%{linkEnd}"
-msgstr ""
-
msgid "Serverless|Learn more about Serverless"
msgstr ""
msgid "Serverless|No functions available"
msgstr ""
-msgid "Serverless|Sign up for First Look"
+msgid "Serverless|Serverless was %{linkStart}deprecated%{linkEnd} in GitLab 14.3."
+msgstr ""
+
+msgid "Serverless|Serverless was %{postLinkStart}deprecated%{postLinkEnd}. But if you opt to use it, you must install Knative in your Kubernetes cluster first. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "Serverless|The deploy job has not finished."
@@ -32718,9 +33406,6 @@ 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 ""
@@ -32736,9 +33421,6 @@ msgstr ""
msgid "Service Account Key"
msgstr ""
-msgid "Service Accounts"
-msgstr ""
-
msgid "Service Accounts keys authorize GitLab to deploy your Google Cloud project"
msgstr ""
@@ -32748,10 +33430,10 @@ msgstr ""
msgid "Service Desk allows people to create issues in your GitLab instance without their own user account. It provides a unique email address for end users to create issues in a project. Replies can be sent either through the GitLab interface or by email. End users only see threads through email."
msgstr ""
-msgid "Service Usage Data"
+msgid "Service account generated successfully"
msgstr ""
-msgid "Service account generated successfully"
+msgid "Service accounts"
msgstr ""
msgid "Service ping is disabled in your configuration file, and cannot be enabled through this form."
@@ -32895,6 +33577,9 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
+msgid "Set the per-user rate limit for getting a user by ID via the API."
+msgstr ""
+
msgid "Set the per-user rate limit for notes created by web or API requests."
msgstr ""
@@ -33074,6 +33759,9 @@ msgstr ""
msgid "Shared runners details"
msgstr ""
+msgid "Shared runners enabled cannot be enabled until a valid credit card is on file"
+msgstr ""
+
msgid "Shared runners help link"
msgstr ""
@@ -33131,6 +33819,9 @@ msgstr ""
msgid "Show all issues."
msgstr ""
+msgid "Show all milestones"
+msgstr ""
+
msgid "Show all test cases."
msgstr ""
@@ -33167,6 +33858,9 @@ msgstr ""
msgid "Show file contents"
msgstr ""
+msgid "Show group milestones"
+msgstr ""
+
msgid "Show labels"
msgstr ""
@@ -33182,6 +33876,12 @@ msgstr ""
msgid "Show open epics"
msgstr ""
+msgid "Show project milestones"
+msgstr ""
+
+msgid "Show sub-group milestones"
+msgstr ""
+
msgid "Show the Closed list"
msgstr ""
@@ -33191,11 +33891,6 @@ msgstr ""
msgid "Show whitespace changes"
msgstr ""
-msgid "Showing %d event"
-msgid_plural "Showing %d events"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Showing %{conflict} between %{sourceBranch} and %{targetBranch}"
msgstr ""
@@ -33255,12 +33950,6 @@ msgstr ""
msgid "Sidebar|None"
msgstr ""
-msgid "Sidebar|Only numeral characters allowed"
-msgstr ""
-
-msgid "Sidebar|Weight"
-msgstr ""
-
msgid "Sidekiq job compression threshold (bytes)"
msgstr ""
@@ -33423,6 +34112,9 @@ msgstr ""
msgid "Slack logo"
msgstr ""
+msgid "SlackIntegration|Are you sure you want to remove this project from the Slack application?"
+msgstr ""
+
msgid "SlackIntegration|GitLab for Slack"
msgstr ""
@@ -33432,6 +34124,9 @@ msgstr ""
msgid "SlackIntegration|Project alias"
msgstr ""
+msgid "SlackIntegration|Remove project"
+msgstr ""
+
msgid "SlackIntegration|Select a GitLab project to link with your Slack workspace."
msgstr ""
@@ -33576,9 +34271,6 @@ msgstr ""
msgid "Something went wrong trying to load issue contacts."
msgstr ""
-msgid "Something went wrong when creating a work item. Please try again"
-msgstr ""
-
msgid "Something went wrong when reordering designs. Please try again"
msgstr ""
@@ -33672,9 +34364,6 @@ msgstr ""
msgid "Something went wrong while inserting your image. Please try again."
msgstr ""
-msgid "Something went wrong while merging this merge request. Please try again."
-msgstr ""
-
msgid "Something went wrong while obtaining the Let's Encrypt certificate."
msgstr ""
@@ -33996,10 +34685,10 @@ 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."
+msgid "SourcegraphAdmin|Learn more."
msgstr ""
-msgid "SourcegraphAdmin|More information"
+msgid "SourcegraphAdmin|Only public projects have code intelligence enabled and communicate with Sourcegraph."
msgstr ""
msgid "SourcegraphAdmin|Save changes"
@@ -34008,7 +34697,7 @@ msgstr ""
msgid "SourcegraphAdmin|Sourcegraph URL"
msgstr ""
-msgid "SourcegraphAdmin|e.g. https://sourcegraph.example.com"
+msgid "SourcegraphAdmin|https://sourcegraph.example.com"
msgstr ""
msgid "SourcegraphPreferences|This feature is experimental and currently limited to certain projects."
@@ -34143,6 +34832,9 @@ msgstr ""
msgid "Start date"
msgstr ""
+msgid "Start free trial"
+msgstr ""
+
msgid "Start merge train"
msgstr ""
@@ -34173,6 +34865,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started escalation for this incident."
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -34185,6 +34880,9 @@ msgstr ""
msgid "Starts at (UTC)"
msgstr ""
+msgid "Starts escalations for this incident"
+msgstr ""
+
msgid "Starts on"
msgstr ""
@@ -34446,6 +35144,9 @@ msgstr ""
msgid "Strikethrough"
msgstr ""
+msgid "Strikethrough text"
+msgstr ""
+
msgid "Subgroup information"
msgstr ""
@@ -34680,6 +35381,21 @@ msgstr ""
msgid "Subscriptions"
msgstr ""
+msgid "Subscriptions|Chat with sales"
+msgstr ""
+
+msgid "Subscriptions|Close"
+msgstr ""
+
+msgid "Subscriptions|Not ready to buy yet?"
+msgstr ""
+
+msgid "Subscriptions|Start a free trial"
+msgstr ""
+
+msgid "Subscriptions|We understand. Maybe you have some questions for our sales team, or maybe you'd like to try some of the paid features first. What would you like to do?"
+msgstr ""
+
msgid "Subscription|Your subscription for %{strong}%{namespace_name}%{strong_close} has expired and you are now on %{pricing_link_start}the GitLab Free tier%{pricing_link_end}. Don't worry, your data is safe. Get in touch with our support team (%{support_email}). They'll gladly help with your subscription renewal."
msgstr ""
@@ -34890,6 +35606,9 @@ msgstr ""
msgid "SuperSonics|Maximum users"
msgstr ""
+msgid "SuperSonics|Offline cloud"
+msgstr ""
+
msgid "SuperSonics|Paste your activation code"
msgstr ""
@@ -34956,6 +35675,12 @@ msgstr ""
msgid "SuperSonics|You do not have an active subscription"
msgstr ""
+msgid "SuperSonics|You have a future dated license"
+msgstr ""
+
+msgid "SuperSonics|You have added a license that activates on %{date}. Please see the subscription history table below for more details."
+msgstr ""
+
msgid "SuperSonics|You have successfully added a license that activates on %{date}. Please see the subscription history table below for more details."
msgstr ""
@@ -35115,6 +35840,9 @@ msgstr ""
msgid "Tag name is required"
msgstr ""
+msgid "Tag push"
+msgstr ""
+
msgid "Tag push events"
msgstr ""
@@ -35217,6 +35945,9 @@ msgstr ""
msgid "TagsPage|protected"
msgstr ""
+msgid "Take a look at the documentation to discover all of GitLab’s capabilities."
+msgstr ""
+
msgid "Target Branch"
msgstr ""
@@ -35619,6 +36350,9 @@ msgstr ""
msgid "Tests"
msgstr ""
+msgid "Text (optional)"
+msgstr ""
+
msgid "Text added to the body of all email messages. %{character_limit} character limit"
msgstr ""
@@ -35669,6 +36403,9 @@ msgstr ""
msgid "The CSV export will be created in the background. Once finished, it will be sent to %{email} in an attachment."
msgstr ""
+msgid "The CSV export you requested of all user memberships is attached to this email."
+msgstr ""
+
msgid "The GitLab subscription service (customers.gitlab.com) is currently experiencing an outage. You can monitor the status and get updates at %{linkStart}status.gitlab.com%{linkEnd}."
msgstr ""
@@ -35744,6 +36481,9 @@ 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 epic"
+msgstr ""
+
msgid "The current issue"
msgstr ""
@@ -35905,6 +36645,9 @@ msgstr ""
msgid "The latest pipeline for this merge request has failed."
msgstr ""
+msgid "The license key is invalid."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -35920,6 +36663,9 @@ msgstr ""
msgid "The license was successfully uploaded and will be active from %{starts_at}. You can see the details below."
msgstr ""
+msgid "The license you uploaded is invalid. If the issue persists, contact support at %{link}."
+msgstr ""
+
msgid "The list creation wizard is already open"
msgstr ""
@@ -36541,10 +37287,13 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} and everything this project contains. %{strongOpen}There is no going back%{strongClose}"
+msgstr ""
+
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains."
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}on %{date}%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains. %{strongOpen}There is no going back.%{strongClose}"
msgstr ""
msgid "This action will %{strongOpen}permanently remove%{strongClose} %{codeOpen}%{group}%{codeClose} %{strongOpen}immediately%{strongClose}."
@@ -36673,9 +37422,6 @@ msgstr ""
msgid "This file was modified for readability, and can't accept suggestions. Edit it directly."
msgstr ""
-msgid "This forked project has the following:"
-msgstr ""
-
msgid "This form is disabled in preview"
msgstr ""
@@ -36688,7 +37434,7 @@ msgstr ""
msgid "This group can't be removed because it is linked to a subscription. To remove this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
-msgid "This group can't be transfered because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
+msgid "This group can't be transferred because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
msgid "This group cannot be invited to a project inside a group with enforced SSO"
@@ -36715,6 +37461,9 @@ 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 incident is already escalated with '%{escalation_policy_name}'."
+msgstr ""
+
msgid "This invitation was sent to %{mail_to_invite_email}, but you are signed in as %{link_to_current_user} with email %{mail_to_current_user}."
msgstr ""
@@ -36733,9 +37482,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 merge train pipeline"
-msgstr ""
-
msgid "This is a private email address %{helpIcon} generated just for you. Anyone who has it can create issues or merge requests as if they were you. If that happens, %{resetLinkStart}reset this token%{resetLinkEnd}."
msgstr ""
@@ -36757,6 +37503,12 @@ msgstr ""
msgid "This is your current session"
msgstr ""
+msgid "This issue cannot be assigned to a confidential epic because it is public."
+msgstr ""
+
+msgid "This issue cannot be made public because it belongs to a confidential epic."
+msgstr ""
+
msgid "This issue is confidential and should only be visible to team members with at least Reporter access."
msgstr ""
@@ -36874,6 +37626,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 branch is protected from force push."
+msgstr ""
+
msgid "This merge request cannot be rebased while there are conflicts."
msgstr ""
@@ -36925,9 +37680,15 @@ msgstr ""
msgid "This pipeline was triggered by a schedule."
msgstr ""
+msgid "This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project"
msgstr ""
+msgid "This project can be restored until %{date}."
+msgstr ""
+
msgid "This project cannot be %{visibilityLevel} because the visibility of %{openShowLink}%{name}%{closeShowLink} is %{visibility}. To make this project %{visibilityLevel}, you must first %{openEditLink}change the visibility%{closeEditLink} of the parent group."
msgstr ""
@@ -36946,6 +37707,9 @@ msgstr ""
msgid "This project is %{strongStart}NOT%{strongEnd} a fork, and has the following:"
msgstr ""
+msgid "This project is %{strongStart}NOT%{strongEnd} a fork. This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -37637,6 +38401,9 @@ msgstr ""
msgid "Today"
msgstr ""
+msgid "Todos count"
+msgstr ""
+
msgid "Todos|Are you looking for things to do? Take a look at %{strongStart}%{openIssuesLinkStart}open issues%{openIssuesLinkEnd}%{strongEnd}, contribute to %{strongStart}%{mergeRequestLinkStart}a merge request%{mergeRequestLinkEnd}%{mergeRequestLinkEnd}%{strongEnd}, or mention someone in a comment to automatically assign them a new to-do item."
msgstr ""
@@ -37910,10 +38677,8 @@ msgstr ""
msgid "Trending"
msgstr ""
-msgid "Trials|%{planName} Trial %{enDash} %{num} day left"
-msgid_plural "Trials|%{planName} Trial %{enDash} %{num} days left"
-msgstr[0] ""
-msgstr[1] ""
+msgid "Trials|%{planName} Trial"
+msgstr ""
msgid "Trials|Compare all plans"
msgstr ""
@@ -37921,6 +38686,9 @@ msgstr ""
msgid "Trials|Create a new group to start your GitLab Ultimate trial."
msgstr ""
+msgid "Trials|Day %{daysUsed}/%{duration}"
+msgstr ""
+
msgid "Trials|Go back to GitLab"
msgstr ""
@@ -38170,7 +38938,7 @@ msgstr ""
msgid "URL is triggered when repository is updated"
msgstr ""
-msgid "URL must be percent-encoded if neccessary."
+msgid "URL must be percent-encoded if necessary."
msgstr ""
msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
@@ -38389,6 +39157,9 @@ msgstr ""
msgid "Unlock account"
msgstr ""
+msgid "Unlock more features with GitLab Ultimate"
+msgstr ""
+
msgid "Unlock the discussion"
msgstr ""
@@ -38452,6 +39223,9 @@ msgstr ""
msgid "Unsubscribes from this %{quick_action_target}."
msgstr ""
+msgid "Unsupported sort value."
+msgstr ""
+
msgid "Unsupported todo type passed. Supported todo types are: %{todo_types}"
msgstr ""
@@ -38680,6 +39454,9 @@ msgstr ""
msgid "UsageQuota|File attachments and smaller design graphics."
msgstr ""
+msgid "UsageQuota|From %{storage_enforcement_date} storage limits will apply to this namespace. View and manage your usage in %{strong_start}Group Settings &gt; Usage quotas%{strong_end}."
+msgstr ""
+
msgid "UsageQuota|Git repository."
msgstr ""
@@ -38740,6 +39517,9 @@ msgstr ""
msgid "UsageQuota|Storage type"
msgstr ""
+msgid "UsageQuota|Storage used"
+msgstr ""
+
msgid "UsageQuota|This is the total amount of storage used across your projects within this namespace."
msgstr ""
@@ -38935,6 +39715,12 @@ msgstr ""
msgid "Use hashed storage paths for newly created and renamed repositories. Always enabled since 13.0."
msgstr ""
+msgid "Use issue count"
+msgstr ""
+
+msgid "Use issue weight"
+msgstr ""
+
msgid "Use one line per URI"
msgstr ""
@@ -39316,6 +40102,9 @@ msgstr ""
msgid "Users"
msgstr ""
+msgid "Users API rate limit"
+msgstr ""
+
msgid "Users can launch a development environment from a GitLab browser tab when the %{linkStart}Gitpod%{linkEnd} integration is enabled."
msgstr ""
@@ -39641,6 +40430,9 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View group pipeline usage quota"
+msgstr ""
+
msgid "View incident details at"
msgstr ""
@@ -39793,6 +40585,9 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
+msgid "Vulnerability"
+msgstr ""
+
msgid "Vulnerability Report"
msgstr ""
@@ -39844,6 +40639,9 @@ msgstr ""
msgid "VulnerabilityManagement|An unverified non-confirmed finding"
msgstr ""
+msgid "VulnerabilityManagement|At least one identifier is required"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -39853,12 +40651,24 @@ msgstr ""
msgid "VulnerabilityManagement|Create Jira issue"
msgstr ""
+msgid "VulnerabilityManagement|Enter a name"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE code"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE identifier URL"
+msgstr ""
+
msgid "VulnerabilityManagement|Fetching linked Jira issues"
msgstr ""
msgid "VulnerabilityManagement|Manually add a vulnerability entry into the vulnerability report."
msgstr ""
+msgid "VulnerabilityManagement|Name is a required field"
+msgstr ""
+
msgid "VulnerabilityManagement|Needs triage"
msgstr ""
@@ -39874,6 +40684,18 @@ msgstr ""
msgid "VulnerabilityManagement|Select a method"
msgstr ""
+msgid "VulnerabilityManagement|Select a severity level"
+msgstr ""
+
+msgid "VulnerabilityManagement|Select a status"
+msgstr ""
+
+msgid "VulnerabilityManagement|Severity is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Something went wrong while creating vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -39898,6 +40720,12 @@ msgstr ""
msgid "VulnerabilityManagement|Something went wrong, could not update vulnerability state."
msgstr ""
+msgid "VulnerabilityManagement|Status is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Submit vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Summary, detailed description, steps to reproduce, etc."
msgstr ""
@@ -40093,6 +40921,9 @@ msgstr ""
msgid "WARNING:"
msgstr ""
+msgid "WARNING: This snippet contains hidden files which might be used to mask malicious behavior. Exercise caution if cloning and executing code from this snippet."
+msgstr ""
+
msgid "Wait for the file to load to copy its contents"
msgstr ""
@@ -40312,6 +41143,15 @@ msgstr ""
msgid "Webhooks|An issue is created, updated, closed, or reopened."
msgstr ""
+msgid "Webhooks|Are you sure you want to delete this group hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this project hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this webhook?"
+msgstr ""
+
msgid "Webhooks|Comments"
msgstr ""
@@ -40321,6 +41161,9 @@ msgstr ""
msgid "Webhooks|Confidential issues events"
msgstr ""
+msgid "Webhooks|Delete webhook"
+msgstr ""
+
msgid "Webhooks|Deployment events"
msgstr ""
@@ -40554,6 +41397,9 @@ msgstr ""
msgid "Wiki"
msgstr ""
+msgid "Wiki page"
+msgstr ""
+
msgid "Wiki page was successfully created."
msgstr ""
@@ -40659,7 +41505,7 @@ msgstr ""
msgid "WikiPageConflictMessage|Someone edited the page the same time you did. Please check out %{wikiLinkStart}the page%{wikiLinkEnd} and make sure your changes will not unintentionally remove theirs."
msgstr ""
-msgid "WikiPage|An error occured while trying to render the content editor. Please try again later."
+msgid "WikiPage|An error occurred while trying to render the content editor. Please try again later."
msgstr ""
msgid "WikiPage|Are you sure you want to switch back to the classic editor?"
@@ -40818,6 +41664,18 @@ msgstr ""
msgid "WorkItem|New Task"
msgstr ""
+msgid "WorkItem|Something went wrong when creating a work item. Please try again"
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching the work item. Please try again."
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching work item types. Please try again"
+msgstr ""
+
+msgid "WorkItem|Type"
+msgstr ""
+
msgid "WorkItem|Work Items"
msgstr ""
@@ -40884,7 +41742,10 @@ msgstr ""
msgid "You are about to add %{usersTag} people to the discussion. They will all receive a notification."
msgstr ""
-msgid "You are about to permanently delete this project"
+msgid "You are about to delete this forked project containing:"
+msgstr ""
+
+msgid "You are about to delete this project containing:"
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."
@@ -40905,6 +41766,9 @@ msgstr ""
msgid "You are attempting to update a file that has changed since you started editing it."
msgstr ""
+msgid "You are billed if you exceed this number. %{qsrOverageLinkStart}How does billing work?%{qsrOverageLinkEnd}"
+msgstr ""
+
msgid "You are connected to the Prometheus server, but there is currently no data to display."
msgstr ""
@@ -40962,6 +41826,9 @@ msgstr ""
msgid "You are not authorized to update this scanner profile"
msgstr ""
+msgid "You are not authorized to upload metric images"
+msgstr ""
+
msgid "You are now impersonating %{username}"
msgstr ""
@@ -41115,9 +41982,6 @@ msgstr ""
msgid "You can only upload one design when dropping onto an existing design."
msgstr ""
-msgid "You can recover this project until %{date}"
-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 ""
@@ -41166,9 +42030,6 @@ msgstr ""
msgid "You cannot write to this read-only GitLab instance."
msgstr ""
-msgid "You can’t %{tag_start}edit%{tag_end} files directly in this project. Fork this project and submit a merge request with your changes."
-msgstr ""
-
msgid "You can’t edit files directly in this project. Fork this project and submit a merge request with your changes."
msgstr ""
@@ -41321,9 +42182,6 @@ 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 set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
@@ -41354,12 +42212,6 @@ msgstr ""
msgid "You must have maintainer access to force delete a lock"
msgstr ""
-msgid "You must have permission to create a project in a group before forking."
-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 ""
@@ -41765,7 +42617,7 @@ msgstr ""
msgid "Your public email will be displayed on your public profile."
msgstr ""
-msgid "Your request for access could not be processed: %{error_meesage}"
+msgid "Your request for access could not be processed: %{error_message}"
msgstr ""
msgid "Your request for access has been queued for review."
@@ -41948,6 +42800,9 @@ msgstr ""
msgid "archived:"
msgstr ""
+msgid "artifacts"
+msgstr ""
+
msgid "assign yourself"
msgstr ""
@@ -41977,6 +42832,9 @@ msgstr[1] ""
msgid "branch name"
msgstr ""
+msgid "builds"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -42400,6 +43258,9 @@ msgstr ""
msgid "contact with same email already exists in group hierarchy"
msgstr ""
+msgid "container registry images"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -42439,6 +43300,9 @@ msgstr ""
msgid "data"
msgstr ""
+msgid "database"
+msgstr ""
+
msgid "date must not be after 9999-12-31"
msgstr ""
@@ -42462,9 +43326,6 @@ msgstr ""
msgid "design"
msgstr ""
-msgid "detached"
-msgstr ""
-
msgid "disabled"
msgstr ""
@@ -42713,7 +43574,7 @@ msgstr ""
msgid "is not a valid X509 certificate."
msgstr ""
-msgid "is not allowed for sign-up."
+msgid "is not allowed for sign-up. Please use your regular email address."
msgstr ""
msgid "is not allowed for this group."
@@ -42725,7 +43586,7 @@ msgstr ""
msgid "is not allowed since the group is not top-level group."
msgstr ""
-msgid "is not allowed."
+msgid "is not allowed. Please use your regular email address."
msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
@@ -42812,6 +43673,9 @@ msgstr ""
msgid "level: %{level}"
msgstr ""
+msgid "lfs objects"
+msgstr ""
+
msgid "limit of %{project_limit} reached"
msgstr ""
@@ -43031,6 +43895,9 @@ msgstr ""
msgid "mrWidget|Merge blocked: pipeline must succeed. It's waiting for a manual action to continue."
msgstr ""
+msgid "mrWidget|Merge blocked: pipeline must succeed. Push a commit that fixes the failure, or %{linkStart}learn about other solutions.%{linkEnd}"
+msgstr ""
+
msgid "mrWidget|Merge blocked: this merge request must be approved."
msgstr ""
@@ -43148,9 +44015,6 @@ msgstr ""
msgid "mrWidget|The changes were not merged into"
msgstr ""
-msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -43298,9 +44162,6 @@ msgstr ""
msgid "open issue"
msgstr ""
-msgid "opened %{timeAgo}"
-msgstr ""
-
msgid "or"
msgstr ""
@@ -43312,6 +44173,12 @@ msgid_plural "out of %d total tests"
msgstr[0] ""
msgstr[1] ""
+msgid "packages"
+msgstr ""
+
+msgid "pages"
+msgstr ""
+
msgid "parent"
msgid_plural "parents"
msgstr[0] ""
@@ -43461,6 +44328,9 @@ msgid_plural "replies"
msgstr[0] ""
msgstr[1] ""
+msgid "repositories"
+msgstr ""
+
msgid "repository:"
msgstr ""
@@ -43581,12 +44451,18 @@ msgstr ""
msgid "tag name"
msgstr ""
+msgid "terraform states"
+msgstr ""
+
msgid "the correct format."
msgstr ""
msgid "the file"
msgstr ""
+msgid "the following epic(s)"
+msgstr ""
+
msgid "the following issue(s)"
msgstr ""
@@ -43599,21 +44475,12 @@ msgstr ""
msgid "this document"
msgstr ""
-msgid "this issue cannot be assigned to a confidential epic since it is public"
-msgstr ""
-
-msgid "this issue cannot be made public since it belongs to a confidential epic"
-msgstr ""
-
msgid "time summary"
msgstr ""
msgid "toggle collapse"
msgstr ""
-msgid "train"
-msgstr ""
-
msgid "triggered"
msgstr ""
@@ -43742,3 +44609,6 @@ msgstr ""
msgid "{project}"
msgstr ""
+msgid "✔"
+msgstr ""
+
diff --git a/locale/hy_AM/gitlab.po b/locale/hy_AM/gitlab.po
index 0e66f44665a..5bf973b26a6 100644
--- a/locale/hy_AM/gitlab.po
+++ b/locale/hy_AM/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: hy-AM\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2022-02-02 15:45\n"
+"PO-Revision-Date: 2022-03-01 20:39\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -146,6 +146,11 @@ msgid_plural "%d approvers (you've approved)"
msgstr[0] ""
msgstr[1] ""
+msgid "%d assigned issue"
+msgid_plural "%d assigned issues"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -421,8 +426,23 @@ msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
msgstr[1] ""
-msgid "%d vulnerability updated"
-msgid_plural "%d vulnerabilities updated"
+msgid "%d vulnerability set to confirmed"
+msgid_plural "%d vulnerabilities set to confirmed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to dismissed"
+msgid_plural "%d vulnerabilities set to dismissed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to needs triage"
+msgid_plural "%d vulnerabilities set to needs triage"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to resolved"
+msgid_plural "%d vulnerabilities set to resolved"
msgstr[0] ""
msgstr[1] ""
@@ -510,6 +530,12 @@ msgstr[1] ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{completed} of %{total} issues closed"
+msgstr ""
+
+msgid "%{completed} of %{total} weight completed"
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -858,6 +884,9 @@ msgstr ""
msgid "%{openedIssues} open, %{closedIssues} closed"
msgstr ""
+msgid "%{percentage}%% issues closed"
+msgstr ""
+
msgid "%{percentage}%% weight completed"
msgstr ""
@@ -1287,6 +1316,9 @@ msgid_plural "- Users"
msgstr[0] ""
msgstr[1] ""
+msgid "- of - issues closed"
+msgstr ""
+
msgid "- of - weight completed"
msgstr ""
@@ -1429,7 +1461,7 @@ msgstr ""
msgid "1000+"
msgstr ""
-msgid "192.168.0.0/24"
+msgid "192.168.0.0/24 or 2001:0DB8:1234::/48"
msgstr ""
msgid "1st contribution!"
@@ -1741,13 +1773,13 @@ msgstr ""
msgid "AWS Access Key"
msgstr ""
-msgid "AWS Access Key. Only required if not using role instance credentials"
+msgid "AWS Secret Access Key"
msgstr ""
-msgid "AWS Secret Access Key"
+msgid "AWS access key ID (Optional)"
msgstr ""
-msgid "AWS Secret Access Key. Only required if not using role instance credentials"
+msgid "AWS secret access key (Optional)"
msgstr ""
msgid "AWS service error: %{error}"
@@ -1807,9 +1839,6 @@ msgstr ""
msgid "Access granted"
msgstr ""
-msgid "Access key ID"
-msgstr ""
-
msgid "Access requests"
msgstr ""
@@ -1984,7 +2013,7 @@ msgstr ""
msgid "Activity"
msgstr ""
-msgid "Activity|An error occured while retrieving activity. Reload the page to try again."
+msgid "Activity|An error occurred while retrieving activity. Reload the page to try again."
msgstr ""
msgid "Add"
@@ -2023,6 +2052,9 @@ msgstr ""
msgid "Add a %{type}"
msgstr ""
+msgid "Add a GCP region"
+msgstr ""
+
msgid "Add a GPG key"
msgstr ""
@@ -2074,6 +2106,9 @@ msgstr ""
msgid "Add a numbered list"
msgstr ""
+msgid "Add a related epic"
+msgstr ""
+
msgid "Add a related issue"
msgstr ""
@@ -2188,6 +2223,9 @@ msgstr ""
msgid "Add or subtract spent time"
msgstr ""
+msgid "Add people"
+msgstr ""
+
msgid "Add previously merged commits"
msgstr ""
@@ -2254,6 +2292,9 @@ msgstr ""
msgid "Add webhook"
msgstr ""
+msgid "Add your team members and others to GitLab."
+msgstr ""
+
msgid "Add/remove"
msgstr ""
@@ -3076,12 +3117,6 @@ msgstr ""
msgid "AdvancedSearch|Reindex required"
msgstr ""
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. Permanently deleting this project will %{strongStart}immediately delete%{strongEnd} its repositories and %{strongStart}all related resources%{strongEnd}, including issues, merge requests etc."
-msgstr ""
-
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. You will lose this project's repository and %{strongStart}all related resources%{strongEnd}, including issues and merge requests."
-msgstr ""
-
msgid "After a successful password update you will be redirected to login screen."
msgstr ""
@@ -3112,6 +3147,9 @@ msgstr ""
msgid "Akismet helps prevent the creation of spam issues in public projects."
msgstr ""
+msgid "Alert"
+msgstr ""
+
msgid "AlertManagement|Acknowledged"
msgstr ""
@@ -3484,9 +3522,6 @@ msgstr ""
msgid "All environments"
msgstr ""
-msgid "All epics"
-msgstr ""
-
msgid "All groups and projects"
msgstr ""
@@ -4223,12 +4258,15 @@ msgstr ""
msgid "ApplicationSettings|Approve users in the pending approval status?"
msgstr ""
-msgid "ApplicationSettings|By making this change, you will automatically approve %d user with the pending approval status."
-msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users with the pending approval status."
+msgid "ApplicationSettings|Approve users who are pending approval?"
+msgstr ""
+
+msgid "ApplicationSettings|By making this change, you will automatically approve %d user who is pending approval."
+msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users who are pending approval."
msgstr[0] ""
msgstr[1] ""
-msgid "ApplicationSettings|By making this change, you will automatically approve all users in pending approval status."
+msgid "ApplicationSettings|By making this change, you will automatically approve all users who are pending approval."
msgstr ""
msgid "ApplicationSettings|Denied domains for sign-ups"
@@ -4634,10 +4672,10 @@ msgstr ""
msgid "Archiving the project will make it entirely read-only. It is hidden from the dashboard and doesn't show up in searches. %{strong_start}The repository cannot be committed to, and no issues, comments, or other entities can be created.%{strong_end} %{link_start}Learn more.%{link_end}"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to delete this project?"
+msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
+msgid "Are you absolutely sure?"
msgstr ""
msgid "Are you sure that you want to archive this project?"
@@ -4673,12 +4711,18 @@ msgstr ""
msgid "Are you sure you want to delete this SSH key?"
msgstr ""
+msgid "Are you sure you want to delete this comment?"
+msgstr ""
+
msgid "Are you sure you want to delete this deploy key?"
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 label?"
+msgstr ""
+
msgid "Are you sure you want to delete this pipeline schedule?"
msgstr ""
@@ -4694,9 +4738,6 @@ msgstr ""
msgid "Are you sure you want to discard your changes?"
msgstr ""
-msgid "Are you sure you want to erase this build?"
-msgstr ""
-
msgid "Are you sure you want to import %d repository?"
msgid_plural "Are you sure you want to import %d repositories?"
msgstr[0] ""
@@ -4744,6 +4785,9 @@ msgstr ""
msgid "Are you sure you want to remove this list?"
msgstr ""
+msgid "Are you sure you want to remove this nickname?"
+msgstr ""
+
msgid "Are you sure you want to reset the health check token?"
msgstr ""
@@ -4756,10 +4800,10 @@ 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?"
+msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
msgstr ""
-msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
+msgid "Are you sure you want to revoke this project access token? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to stop this environment?"
@@ -4906,9 +4950,6 @@ msgstr ""
msgid "Assigned to %{assignee_name}"
msgstr ""
-msgid "Assigned to %{name}"
-msgstr ""
-
msgid "Assigned to me"
msgstr ""
@@ -4973,6 +5014,9 @@ msgstr[1] ""
msgid "Attaching the file failed."
msgstr ""
+msgid "Attention"
+msgstr ""
+
msgid "Audit Events"
msgstr ""
@@ -5135,6 +5179,12 @@ msgstr ""
msgid "Authorized applications (%{size})"
msgstr ""
+msgid "AuthorizedApplication|Are you sure you want to revoke this application?"
+msgstr ""
+
+msgid "AuthorizedApplication|Revoke application"
+msgstr ""
+
msgid "Authors: %{authors}"
msgstr ""
@@ -6328,6 +6378,9 @@ msgstr ""
msgid "CICDAnalytics|Shared Runners Usage"
msgstr ""
+msgid "CICDAnalytics|Shared runner pipeline minute duration by month"
+msgstr ""
+
msgid "CICDAnalytics|Shared runner usage"
msgstr ""
@@ -6469,6 +6522,9 @@ msgstr ""
msgid "Can create groups:"
msgstr ""
+msgid "Can not delete primary training"
+msgstr ""
+
msgid "Can't apply as the source branch was deleted."
msgstr ""
@@ -6802,9 +6858,6 @@ msgstr ""
msgid "Changing any setting here requires an application restart"
msgstr ""
-msgid "Changing group URL can have unintended side effects."
-msgstr ""
-
msgid "Charts can't be displayed as the request for data has timed out. %{documentationLink}"
msgstr ""
@@ -6892,9 +6945,6 @@ msgstr ""
msgid "Checking branch availability..."
msgstr ""
-msgid "Checking group URL availability..."
-msgstr ""
-
msgid "Checking group path availability..."
msgstr ""
@@ -7388,6 +7438,9 @@ msgstr ""
msgid "Clear recent searches"
msgstr ""
+msgid "Clear repository checks"
+msgstr ""
+
msgid "Clear search"
msgstr ""
@@ -7520,9 +7573,6 @@ msgstr ""
msgid "Closed MRs"
msgstr ""
-msgid "Closed epics"
-msgstr ""
-
msgid "Closed issues"
msgstr ""
@@ -7559,13 +7609,13 @@ msgstr ""
msgid "Cluster level"
msgstr ""
-msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
+msgid "Cluster type must be specified for Stages::ClusterEndpointInserter"
msgstr ""
msgid "ClusterAgents|%{name} successfully deleted"
msgstr ""
-msgid "ClusterAgents|%{number} of %{total} Agents"
+msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
@@ -7607,6 +7657,15 @@ msgstr ""
msgid "ClusterAgents|Agent never connected to GitLab"
msgstr ""
+msgid "ClusterAgents|Agent version mismatch"
+msgstr ""
+
+msgid "ClusterAgents|Agent version mismatch and update"
+msgstr ""
+
+msgid "ClusterAgents|Agent version update required"
+msgstr ""
+
msgid "ClusterAgents|All"
msgstr ""
@@ -7631,7 +7690,7 @@ msgstr ""
msgid "ClusterAgents|Configuration"
msgstr ""
-msgid "ClusterAgents|Connect a cluster through the Agent"
+msgid "ClusterAgents|Connect a cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connect existing cluster"
@@ -7640,13 +7699,13 @@ msgstr ""
msgid "ClusterAgents|Connect with a certificate"
msgstr ""
-msgid "ClusterAgents|Connect with agent"
+msgid "ClusterAgents|Connect with an agent"
msgstr ""
msgid "ClusterAgents|Connect with the GitLab Agent"
msgstr ""
-msgid "ClusterAgents|Connect your cluster through the Agent"
+msgid "ClusterAgents|Connect your cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connected"
@@ -7706,7 +7765,10 @@ msgstr ""
msgid "ClusterAgents|How to register an agent?"
msgstr ""
-msgid "ClusterAgents|Install new Agent"
+msgid "ClusterAgents|How to update an agent?"
+msgstr ""
+
+msgid "ClusterAgents|Install a new agent"
msgstr ""
msgid "ClusterAgents|Last connected %{timeAgo}."
@@ -7733,7 +7795,7 @@ msgstr ""
msgid "ClusterAgents|Never connected"
msgstr ""
-msgid "ClusterAgents|No Agents"
+msgid "ClusterAgents|No agents"
msgstr ""
msgid "ClusterAgents|No clusters connected through cluster certificates"
@@ -7793,6 +7855,9 @@ msgstr ""
msgid "ClusterAgents|The agent has not been connected in a long time. There might be a connectivity issue. Last contact was %{timeAgo}."
msgstr ""
+msgid "ClusterAgents|The agent version do not match each other across your cluster's pods. This can happen when a new agent version was just deployed and Kubernetes is shutting down the old pods."
+msgstr ""
+
msgid "ClusterAgents|The recommended installation method includes the token. If you want to follow the advanced installation method provided in the docs, make sure you save the token value before you close this window."
msgstr ""
@@ -7840,6 +7905,9 @@ msgstr ""
msgid "ClusterAgents|You will need to create a token to connect to your agent"
msgstr ""
+msgid "ClusterAgents|Your agent version is out of sync with your GitLab version (v%{version}), which might cause compatibility problems. Update the agent installed on your cluster to the most recent version."
+msgstr ""
+
msgid "ClusterAgents|Your instance doesn't have the %{linkStart}GitLab Agent Server (KAS)%{linkEnd} set up. Ask a GitLab Administrator to install it."
msgstr ""
@@ -8716,9 +8784,6 @@ msgstr ""
msgid "Comma-separated list of email addresses."
msgstr ""
-msgid "Comma-separated list of users allowed to exceed the rate limit."
-msgstr ""
-
msgid "Comma-separated, e.g. '1.1.1.1, 2.2.2.0/24'"
msgstr ""
@@ -9045,6 +9110,12 @@ msgstr ""
msgid "Confidential"
msgstr ""
+msgid "Confidential issue"
+msgstr ""
+
+msgid "Confidential note"
+msgstr ""
+
msgid "Confidentiality"
msgstr ""
@@ -9078,6 +9149,9 @@ msgstr ""
msgid "Configure Dependency Scanning in `.gitlab-ci.yml`, creating this file if it does not already exist"
msgstr ""
+msgid "Configure GitLab"
+msgstr ""
+
msgid "Configure GitLab runners to start using the Web Terminal. %{helpStart}Learn more.%{helpEnd}"
msgstr ""
@@ -9126,6 +9200,15 @@ msgstr ""
msgid "Configure pipelines to deploy web apps, backend services, APIs and static resources to Google Cloud"
msgstr ""
+msgid "Configure region"
+msgstr ""
+
+msgid "Configure region for environment"
+msgstr ""
+
+msgid "Configure regions"
+msgstr ""
+
msgid "Configure repository mirroring."
msgstr ""
@@ -9159,6 +9242,9 @@ msgstr ""
msgid "Configure which lists are shown for anyone who visits this board"
msgstr ""
+msgid "Configure your environments to be deployed to specific geographical regions"
+msgstr ""
+
msgid "Confirm"
msgstr ""
@@ -9861,10 +9947,10 @@ msgstr ""
msgid "CorpusManagement|Actions"
msgstr ""
-msgid "CorpusManagement|Corpus are used in fuzz testing as mutation source to Improve future testing."
+msgid "CorpusManagement|Corpus file"
msgstr ""
-msgid "CorpusManagement|Corpus file"
+msgid "CorpusManagement|Corpus files are used in coverage-guided fuzz testing as seed inputs to improve testing."
msgstr ""
msgid "CorpusManagement|Corpus files must be in *.zip format. Maximum 5 GB"
@@ -9918,6 +10004,9 @@ msgstr ""
msgid "Could not apply %{name} command."
msgstr ""
+msgid "Could not apply %{name} command. %{message}."
+msgstr ""
+
msgid "Could not authorize chat nickname. Try again!"
msgstr ""
@@ -10068,6 +10157,9 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
+msgid "Create a group"
+msgstr ""
+
msgid "Create a merge request"
msgstr ""
@@ -10092,6 +10184,9 @@ msgstr ""
msgid "Create a personal access token on your account to pull or push via %{protocol}."
msgstr ""
+msgid "Create a project"
+msgstr ""
+
msgid "Create an account using:"
msgstr ""
@@ -10455,6 +10550,9 @@ msgstr ""
msgid "Creation date"
msgstr ""
+msgid "Creator"
+msgstr ""
+
msgid "Credentials"
msgstr ""
@@ -10467,9 +10565,15 @@ msgstr ""
msgid "CredentialsInventory|Personal Access Tokens"
msgstr ""
+msgid "CredentialsInventory|Project Access Tokens"
+msgstr ""
+
msgid "CredentialsInventory|SSH Keys"
msgstr ""
+msgid "Credit card required to be on file in order to create a pipeline"
+msgstr ""
+
msgid "Credit card:"
msgstr ""
@@ -10653,9 +10757,6 @@ msgstr ""
msgid "Customer relations"
msgstr ""
-msgid "Customizable by an administrator."
-msgstr ""
-
msgid "Customizable by owners."
msgstr ""
@@ -10785,30 +10886,18 @@ msgstr ""
msgid "CycleAnalytics|%{selectedLabelsCount} selected (%{maxLabels} max)"
msgstr ""
-msgid "CycleAnalytics|%{stageCount} stages selected"
-msgstr ""
-
-msgid "CycleAnalytics|All stages"
-msgstr ""
-
-msgid "CycleAnalytics|Average days to completion"
+msgid "CycleAnalytics|Average time to completion"
msgstr ""
msgid "CycleAnalytics|Date"
msgstr ""
-msgid "CycleAnalytics|Days to completion"
-msgstr ""
-
msgid "CycleAnalytics|Display chart filters"
msgstr ""
msgid "CycleAnalytics|Lead Time for Changes"
msgstr ""
-msgid "CycleAnalytics|No stages selected"
-msgstr ""
-
msgid "CycleAnalytics|Number of tasks"
msgstr ""
@@ -10837,18 +10926,30 @@ msgstr ""
msgid "CycleAnalytics|Showing data for group '%{groupName}' from %{createdAfter} to %{createdBefore}"
msgstr ""
-msgid "CycleAnalytics|Stages"
+msgid "CycleAnalytics|Stage time: %{title}"
msgstr ""
msgid "CycleAnalytics|Tasks by type"
msgstr ""
-msgid "CycleAnalytics|The average time spent in the selected stage for the items that were completed on each date. Data limited to the last 500 items."
+msgid "CycleAnalytics|The average time items spent in this stage. Data limited to items completed within this date range."
msgstr ""
msgid "CycleAnalytics|The given date range is larger than 180 days"
msgstr ""
+msgid "CycleAnalytics|The total time items spent across each value stream stage. Data limited to items completed within this date range."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Stage time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Total time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|Total time"
+msgstr ""
+
msgid "CycleAnalytics|Type of work"
msgstr ""
@@ -10861,9 +10962,6 @@ msgstr ""
msgid "CycleAnalytics|project dropdown filter"
msgstr ""
-msgid "CycleAnalytics|stage dropdown"
-msgstr ""
-
msgid "DAG visualization requires at least 3 dependent jobs."
msgstr ""
@@ -10963,10 +11061,16 @@ msgstr ""
msgid "DastProfiles|AJAX spider"
msgstr ""
+msgid "DastProfiles|API"
+msgstr ""
+
+msgid "DastProfiles|API endpoint URL"
+msgstr ""
+
msgid "DastProfiles|Active"
msgstr ""
-msgid "DastProfiles|Additional request headers (Optional)"
+msgid "DastProfiles|Additional request headers (optional)"
msgstr ""
msgid "DastProfiles|Are you sure you want to delete this profile?"
@@ -10981,6 +11085,9 @@ msgstr ""
msgid "DastProfiles|Branch missing"
msgstr ""
+msgid "DastProfiles|Choose a scan method"
+msgstr ""
+
msgid "DastProfiles|Could not create the scanner profile. Please try again."
msgstr ""
@@ -11050,7 +11157,13 @@ msgstr ""
msgid "DastProfiles|Excluded URLs"
msgstr ""
-msgid "DastProfiles|Excluded URLs (Optional)"
+msgid "DastProfiles|Excluded URLs (optional)"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths (optional)"
msgstr ""
msgid "DastProfiles|Hide debug messages"
@@ -11107,9 +11220,6 @@ msgstr ""
msgid "DastProfiles|Request headers"
msgstr ""
-msgid "DastProfiles|Rest API"
-msgstr ""
-
msgid "DastProfiles|Run the AJAX spider, in addition to the traditional spider, to crawl the target site."
msgstr ""
@@ -11119,6 +11229,9 @@ msgstr ""
msgid "DastProfiles|Save profile"
msgstr ""
+msgid "DastProfiles|Scan method"
+msgstr ""
+
msgid "DastProfiles|Scan mode"
msgstr ""
@@ -11197,12 +11310,24 @@ msgstr ""
msgid "DastProfiles|Website"
msgstr ""
+msgid "DastProfiles|What does each method do?"
+msgstr ""
+
msgid "DastProfiles|You can either choose a passive scan or validate the target site from the site profile management page. %{docsLinkStart}Learn more about site validation.%{docsLinkEnd}"
msgstr ""
msgid "DastProfiles|You cannot run an active scan against an unvalidated site."
msgstr ""
+msgid "DastProfiles|folder/dast_example.har or https://example.com/dast_example.har"
+msgstr ""
+
+msgid "DastProfiles|folder/example.postman_collection.json or https://example.com/"
+msgstr ""
+
+msgid "DastProfiles|folder/openapi.json or https://example.com/openapi.json"
+msgstr ""
+
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
@@ -11310,6 +11435,9 @@ msgstr ""
msgid "DatadogIntegration|API URL"
msgstr ""
+msgid "DatadogIntegration|Custom tags in Datadog. Enter one tag per line in the %{codeOpen}key:value%{codeClose} format. %{linkOpen}How do I use tags?%{linkClose}"
+msgstr ""
+
msgid "DatadogIntegration|Environment"
msgstr ""
@@ -11328,12 +11456,18 @@ msgstr ""
msgid "DatadogIntegration|Tag all data from this GitLab instance in Datadog. Useful when managing several self-managed deployments."
msgstr ""
+msgid "DatadogIntegration|Tags"
+msgstr ""
+
msgid "DatadogIntegration|The Datadog site to send data to. To send data to the EU site, use %{codeOpen}datadoghq.eu%{codeClose}."
msgstr ""
msgid "DatadogIntegration|Trace your GitLab pipelines with Datadog."
msgstr ""
+msgid "DatadogIntegration|have an invalid format"
+msgstr ""
+
msgid "Datasource name not found"
msgstr ""
@@ -11343,9 +11477,6 @@ msgstr ""
msgid "Date merged"
msgstr ""
-msgid "Date picker"
-msgstr ""
-
msgid "Date range"
msgstr ""
@@ -11499,9 +11630,6 @@ msgstr ""
msgid "Definition"
msgstr ""
-msgid "Delayed Project Deletion (%{adjourned_deletion})"
-msgstr ""
-
msgid "DelayedJobs|Are you sure you want to run %{jobName} immediately? Otherwise this job will run automatically after its timer finishes."
msgstr ""
@@ -11580,10 +11708,10 @@ msgstr ""
msgid "Delete pipeline"
msgstr ""
-msgid "Delete project"
+msgid "Delete pipeline schedule"
msgstr ""
-msgid "Delete project. Are you ABSOLUTELY SURE?"
+msgid "Delete project"
msgstr ""
msgid "Delete row"
@@ -11613,6 +11741,9 @@ msgstr ""
msgid "Delete this epic and all descendants?"
msgstr ""
+msgid "Delete this project"
+msgstr ""
+
msgid "Delete user list"
msgstr ""
@@ -11871,6 +12002,12 @@ msgstr ""
msgid "Deploy to..."
msgstr ""
+msgid "DeployBoards|To see deployment progress for your environments, make sure you are deploying to %{codeStart}$KUBE_NAMESPACE%{codeEnd} and annotating with %{codeStart}app.gitlab.com/app=$CI_PROJECT_PATH_SLUG%{codeEnd} and %{codeStart}app.gitlab.com/env=$CI_ENVIRONMENT_SLUG%{codeEnd}."
+msgstr ""
+
+msgid "DeployBoard|Kubernetes Pods"
+msgstr ""
+
msgid "DeployFreeze|Add a freeze period to prevent unintended releases during a period of time for a given environment. You must update the deployment jobs in %{filename} according to the deploy freezes added here. %{freeze_period_link_start}Learn more.%{freeze_period_link_end}"
msgstr ""
@@ -11955,9 +12092,6 @@ msgstr ""
msgid "DeployTokens|Active Deploy Tokens (%{active_tokens})"
msgstr ""
-msgid "DeployTokens|Allows read and write access to registry images."
-msgstr ""
-
msgid "DeployTokens|Allows read and write access to the package registry."
msgstr ""
@@ -11970,6 +12104,9 @@ msgstr ""
msgid "DeployTokens|Allows read-only access to the repository."
msgstr ""
+msgid "DeployTokens|Allows write access to registry images."
+msgstr ""
+
msgid "DeployTokens|Copy deploy token"
msgstr ""
@@ -12063,12 +12200,57 @@ msgstr ""
msgid "Deploying to AWS is easy with GitLab"
msgstr ""
+msgid "Deployment"
+msgstr ""
+
msgid "Deployment Frequency"
msgstr ""
+msgid "Deployment Target|Project deployment target (optional)"
+msgstr ""
+
+msgid "Deployment Target|Select the deployment target"
+msgstr ""
+
msgid "Deployment frequency"
msgstr ""
+msgid "DeploymentTarget|GitLab Pages"
+msgstr ""
+
+msgid "DeploymentTarget|Heroku"
+msgstr ""
+
+msgid "DeploymentTarget|Infrastructure provider (Terraform, Cloudformation, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Kubernetes (GKE, EKS, OpenShift, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Managed container runtime (Fargate, Cloud Run, DigitalOcean App)"
+msgstr ""
+
+msgid "DeploymentTarget|Mobile app store"
+msgstr ""
+
+msgid "DeploymentTarget|No deployment planned"
+msgstr ""
+
+msgid "DeploymentTarget|Other hosting service"
+msgstr ""
+
+msgid "DeploymentTarget|Registry (package or container)"
+msgstr ""
+
+msgid "DeploymentTarget|Self-managed container runtime (Podman, Docker Swarm, Docker Compose)"
+msgstr ""
+
+msgid "DeploymentTarget|Serverless backend (Lambda, Cloud functions)"
+msgstr ""
+
+msgid "DeploymentTarget|Virtual machine (for example, EC2)"
+msgstr ""
+
msgid "Deployments"
msgstr ""
@@ -12107,6 +12289,9 @@ msgstr ""
msgid "Deployment|This deployment was created using the API"
msgstr ""
+msgid "Deployment|Triggerer"
+msgstr ""
+
msgid "Deployment|Waiting"
msgstr ""
@@ -12134,6 +12319,18 @@ msgstr ""
msgid "Deprecated API rate limits"
msgstr ""
+msgid "Deprecations|Feature deprecation and removal"
+msgstr ""
+
+msgid "Deprecations|For information on a possible replacement %{epicStart} learn more about Opstrace %{epicEnd}."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7 and are %{epicStart} scheduled for removal %{epicEnd} in GitLab 15.0."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7, and are %{removal_link_start} scheduled for removal %{link_end} in GitLab 15.0. For information on a possible replacement, %{opstrace_link_start} learn more about Opstrace %{link_end}."
+msgstr ""
+
msgid "Deprioritize label"
msgstr ""
@@ -12379,10 +12576,10 @@ msgstr ""
msgid "DevopsAdoption|At least one deploy"
msgstr ""
-msgid "DevopsAdoption|At least one issue opened"
+msgid "DevopsAdoption|At least one issue created"
msgstr ""
-msgid "DevopsAdoption|At least one merge request opened"
+msgid "DevopsAdoption|At least one merge request created"
msgstr ""
msgid "DevopsAdoption|At least one pipeline successfully run"
@@ -12583,6 +12780,9 @@ msgstr ""
msgid "Direct member"
msgstr ""
+msgid "Direct members"
+msgstr ""
+
msgid "Direct non-authenticated users to this page."
msgstr ""
@@ -12699,6 +12899,9 @@ msgid_plural "Dismiss %d selected vulnerabilities as"
msgstr[0] ""
msgstr[1] ""
+msgid "Dismiss Alert"
+msgstr ""
+
msgid "Dismiss merge request promotion"
msgstr ""
@@ -12726,9 +12929,15 @@ msgstr ""
msgid "Display alerts from all configured monitoring tools."
msgstr ""
+msgid "Display milestones"
+msgstr ""
+
msgid "Display name"
msgstr ""
+msgid "Display progress of child issues"
+msgstr ""
+
msgid "Display rendered file"
msgstr ""
@@ -12834,6 +13043,9 @@ msgstr ""
msgid "Download image"
msgstr ""
+msgid "Download payload"
+msgstr ""
+
msgid "Download raw data (.csv)"
msgstr ""
@@ -13011,6 +13223,9 @@ msgstr ""
msgid "Edit in Web IDE"
msgstr ""
+msgid "Edit in pipeline editor"
+msgstr ""
+
msgid "Edit in single-file editor"
msgstr ""
@@ -13053,6 +13268,9 @@ msgstr ""
msgid "Edit your most recent comment in a thread (from an empty textarea)"
msgstr ""
+msgid "Edit, lint, and visualize your pipeline."
+msgstr ""
+
msgid "Edited"
msgstr ""
@@ -13494,6 +13712,9 @@ msgstr ""
msgid "Enforce two-factor authentication for all user sign-ins."
msgstr ""
+msgid "Enhance security by storing service account keys in secret managers - learn more about %{docLinkStart}secret management with GitLab%{docLinkEnd}"
+msgstr ""
+
msgid "Ensure connectivity is available from the GitLab server to the Prometheus server"
msgstr ""
@@ -13554,6 +13775,9 @@ 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 following to confirm:"
+msgstr ""
+
msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
@@ -14084,9 +14308,6 @@ 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 ""
@@ -14222,6 +14443,9 @@ msgstr ""
msgid "Errors:"
msgstr ""
+msgid "Escalate this incident"
+msgstr ""
+
msgid "Escalation Policies"
msgstr ""
@@ -14234,6 +14458,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy"
+msgstr ""
+
msgid "Escalation policy:"
msgstr ""
@@ -14485,6 +14712,9 @@ msgstr ""
msgid "Existing sign in methods may be removed"
msgstr ""
+msgid "Exit."
+msgstr ""
+
msgid "Expand"
msgstr ""
@@ -14581,6 +14811,9 @@ msgstr ""
msgid "Explore public groups"
msgstr ""
+msgid "Explore public projects"
+msgstr ""
+
msgid "Explore snippets"
msgstr ""
@@ -14742,7 +14975,7 @@ msgid_plural "Failed to archive designs. Please try again."
msgstr[0] ""
msgstr[1] ""
-msgid "Failed to assign a reviewer because no user was found."
+msgid "Failed to assign a reviewer because no user was specified."
msgstr ""
msgid "Failed to assign a user because no user was found."
@@ -14808,10 +15041,10 @@ msgstr ""
msgid "Failed to find import label for Jira import."
msgstr ""
-msgid "Failed to generate export, please try again later."
+msgid "Failed to find users for %{missing}"
msgstr ""
-msgid "Failed to generate report, please try again after sometime"
+msgid "Failed to generate export, please try again later."
msgstr ""
msgid "Failed to get ref."
@@ -14910,6 +15143,9 @@ msgstr ""
msgid "Failed to remove a to-do item for the design."
msgstr ""
+msgid "Failed to remove attention because no user was found."
+msgstr ""
+
msgid "Failed to remove mirror."
msgstr ""
@@ -14922,6 +15158,9 @@ msgstr ""
msgid "Failed to remove user key."
msgstr ""
+msgid "Failed to request attention because no user was found."
+msgstr ""
+
msgid "Failed to reset key. Please try again."
msgstr ""
@@ -15003,6 +15242,9 @@ msgstr ""
msgid "Feature Flags"
msgstr ""
+msgid "Feature deprecation and removal"
+msgstr ""
+
msgid "Feature flag status"
msgstr ""
@@ -15500,7 +15742,7 @@ msgstr ""
msgid "For each job, re-use the project workspace. If the workspace doesn't exist, use %{code_open}git clone%{code_close}."
msgstr ""
-msgid "For example, the application using the token or the purpose of the token."
+msgid "For example, the application using the token or the purpose of the token. Do not give sensitive information for the name of the token, as it will be visible to all %{resource_type} members."
msgstr ""
msgid "For files larger than this limit, only index the file name. The file content is neither indexed nor searchable."
@@ -15584,9 +15826,6 @@ msgstr ""
msgid "ForkProject|Select a namespace"
msgstr ""
-msgid "ForkProject|Select a namespace to fork the project"
-msgstr ""
-
msgid "ForkProject|The project can be accessed by any logged in user."
msgstr ""
@@ -15683,6 +15922,9 @@ msgstr ""
msgid "Full name"
msgstr ""
+msgid "GCP region configured"
+msgstr ""
+
msgid "GPG Key ID:"
msgstr ""
@@ -15863,6 +16105,9 @@ msgstr ""
msgid "Geo|Failed"
msgstr ""
+msgid "Geo|Filter Geo sites"
+msgstr ""
+
msgid "Geo|Filter by name"
msgstr ""
@@ -16274,6 +16519,12 @@ msgstr ""
msgid "GitLab Issue"
msgstr ""
+msgid "GitLab KAS"
+msgstr ""
+
+msgid "GitLab Memberships CSV Export"
+msgstr ""
+
msgid "GitLab Pages"
msgstr ""
@@ -16322,6 +16573,9 @@ 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 free to use. Many features for larger teams are part of our %{link_start}paid products%{link_end}. You can try Ultimate for free without any obligation or payment details."
+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 ""
@@ -16448,7 +16702,7 @@ msgstr ""
msgid "GitLabPages|When enabled, all attempts to visit your website through HTTP are automatically redirected to HTTPS using a response with status code 301. Requires a valid certificate for all domains. %{docs_link_start}Learn more.%{link_end}"
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. %{docs_link_start}Learn more.%{link_end}"
+msgid "GitLabPages|When using Pages under the general domain of a GitLab instance (%{pages_host}), you cannot use HTTPS with subdomains of subdomains. If your namespace or groupname contains a dot, it does not work. This is a limitation of the HTTP Over TLS protocol. HTTP pages work if you don't redirect HTTP to HTTPS. %{docs_link_start}Learn more.%{link_end}"
msgstr ""
msgid "GitLabPages|With GitLab Pages you can host your static website directly from your GitLab repository. %{docs_link_start}Learn more.%{link_end}"
@@ -16625,9 +16879,6 @@ msgstr ""
msgid "Go to find file"
msgstr ""
-msgid "Go to fork"
-msgstr ""
-
msgid "Go to issue boards"
msgstr ""
@@ -16835,9 +17086,6 @@ msgstr ""
msgid "Group Hooks"
msgstr ""
-msgid "Group ID"
-msgstr ""
-
msgid "Group Owner must have signed in with SAML before enabling Group Managed Accounts"
msgstr ""
@@ -16865,9 +17113,6 @@ msgstr ""
msgid "Group by"
msgstr ""
-msgid "Group description"
-msgstr ""
-
msgid "Group description (optional)"
msgstr ""
@@ -16982,7 +17227,7 @@ msgstr ""
msgid "Group: %{name}"
msgstr ""
-msgid "GroupActivityMetrics|Issues opened"
+msgid "GroupActivityMetrics|Issues created"
msgstr ""
msgid "GroupActivityMetrics|Last 90 days"
@@ -16991,7 +17236,7 @@ msgstr ""
msgid "GroupActivityMetrics|Members added"
msgstr ""
-msgid "GroupActivityMetrics|Merge Requests opened"
+msgid "GroupActivityMetrics|Merge Requests created"
msgstr ""
msgid "GroupActivityMetrics|Recent activity"
@@ -17282,6 +17527,9 @@ msgstr ""
msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
+msgid "GroupSettings|Choose a group path that does not start with a dash or end with a period. It can also contain alphanumeric characters and underscores."
+msgstr ""
+
msgid "GroupSettings|Compliance frameworks"
msgstr ""
@@ -17315,7 +17563,7 @@ msgstr ""
msgid "GroupSettings|If not specified at the group or instance level, the default is %{default_initial_branch_name}. Does not affect existing repositories."
msgstr ""
-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."
+msgid "GroupSettings|If the parent group's visibility is lower than the group's current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility."
msgstr ""
msgid "GroupSettings|New runners registration token has been generated!"
@@ -17432,7 +17680,10 @@ msgstr ""
msgid "Groups and projects"
msgstr ""
-msgid "Groups and subgroups"
+msgid "Groups are a great way to organize projects and people."
+msgstr ""
+
+msgid "Groups are the best way to manage projects and members."
msgstr ""
msgid "Groups to synchronize"
@@ -17543,13 +17794,16 @@ msgstr ""
msgid "GroupsTree|Are you sure you want to leave the \"%{fullName}\" group?"
msgstr ""
-msgid "GroupsTree|Edit group"
+msgid "GroupsTree|Delete"
+msgstr ""
+
+msgid "GroupsTree|Edit"
msgstr ""
msgid "GroupsTree|Failed to leave the group. Please make sure you are not the only owner."
msgstr ""
-msgid "GroupsTree|Leave this group"
+msgid "GroupsTree|Leave group"
msgstr ""
msgid "GroupsTree|Loading groups"
@@ -17561,9 +17815,57 @@ msgstr ""
msgid "GroupsTree|No groups or projects matched your search"
msgstr ""
+msgid "GroupsTree|Options"
+msgstr ""
+
msgid "GroupsTree|Search by name"
msgstr ""
+msgid "Groups|Avatar will be removed. Are you sure?"
+msgstr ""
+
+msgid "Groups|Changing group URL can have unintended side effects."
+msgstr ""
+
+msgid "Groups|Checking group URL availability..."
+msgstr ""
+
+msgid "Groups|Enter a descriptive name for your group."
+msgstr ""
+
+msgid "Groups|Group ID"
+msgstr ""
+
+msgid "Groups|Group URL"
+msgstr ""
+
+msgid "Groups|Group avatar"
+msgstr ""
+
+msgid "Groups|Group description (optional)"
+msgstr ""
+
+msgid "Groups|Group name"
+msgstr ""
+
+msgid "Groups|Group path is available."
+msgstr ""
+
+msgid "Groups|Group path is unavailable. Path has been replaced with a suggested available path."
+msgstr ""
+
+msgid "Groups|Learn more"
+msgstr ""
+
+msgid "Groups|Must start with letter, digit, emoji, or underscore. Can also contain periods, dashes, spaces, and parentheses."
+msgstr ""
+
+msgid "Groups|Remove avatar"
+msgstr ""
+
+msgid "Groups|Save changes"
+msgstr ""
+
msgid "Guideline"
msgstr ""
@@ -17573,6 +17875,9 @@ msgstr ""
msgid "HAR file path or URL"
msgstr ""
+msgid "HTTP Archive (HAR)"
+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 ""
@@ -17973,6 +18278,9 @@ msgstr ""
msgid "INFO: Your SSH key is expiring soon. Please generate a new key."
msgstr ""
+msgid "IP"
+msgstr ""
+
msgid "IP Address"
msgstr ""
@@ -18009,6 +18317,9 @@ msgstr ""
msgid "IdentityVerification|Verify your identity"
msgstr ""
+msgid "IdentityVerification|You can always verify your account at a later time to create a group."
+msgstr ""
+
msgid "If any indexed field exceeds this limit, it is truncated to this number of characters. The rest of the content is neither indexed nor searchable. This does not apply to repository and wiki indexing. For unlimited characters, set this to 0."
msgstr ""
@@ -18066,6 +18377,9 @@ msgstr ""
msgid "If you add %{codeStart}needs%{codeEnd} to jobs in your pipeline you'll be able to view the %{codeStart}needs%{codeEnd} relationships between jobs in this tab as a %{linkStart}Directed Acyclic Graph (DAG)%{linkEnd}."
msgstr ""
+msgid "If you are added to a project, it will be displayed here."
+msgstr ""
+
msgid "If you did not initiate these sign-in attempts, please reach out to your administrator or enable two-factor authentication (2FA) on your account."
msgstr ""
@@ -18372,12 +18686,24 @@ msgstr ""
msgid "InProductMarketing|3 ways to dive into GitLab CI/CD"
msgstr ""
+msgid "InProductMarketing|A single application eliminates complex integrations, data chokepoints, and toolchain maintenance, resulting in greater productivity and lower cost."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features, build more efficiently, strengthen security and compliance."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features."
+msgstr ""
+
msgid "InProductMarketing|Actually, GitLab makes the team work (better)"
msgstr ""
msgid "InProductMarketing|And finally %{deploy_link} a Python application."
msgstr ""
+msgid "InProductMarketing|And many more..."
+msgstr ""
+
msgid "InProductMarketing|Are your runners ready?"
msgstr ""
@@ -18396,15 +18722,33 @@ msgstr ""
msgid "InProductMarketing|Blog"
msgstr ""
+msgid "InProductMarketing|Break down silos to coordinate seamlessly across development, operations, and security with a consistent experience across the development lifecycle."
+msgstr ""
+
+msgid "InProductMarketing|Burn up/down charts"
+msgstr ""
+
msgid "InProductMarketing|By enabling code owners and required merge approvals the right person will review the right MR. This is a win-win: cleaner code and a more efficient review process."
msgstr ""
msgid "InProductMarketing|Click on the number below that corresponds with your answer — 1 being very difficult, 5 being very easy."
msgstr ""
+msgid "InProductMarketing|Code owners"
+msgstr ""
+
msgid "InProductMarketing|Code owners and required merge approvals are part of the paid tiers of GitLab. You can start a free 30-day trial of GitLab Ultimate and enable these features in less than 5 minutes with no credit card required."
msgstr ""
+msgid "InProductMarketing|Code review analytics"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration across stages in GitLab"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration made easy"
+msgstr ""
+
msgid "InProductMarketing|Create a custom CI runner with just a few clicks"
msgstr ""
@@ -18414,12 +18758,21 @@ msgstr ""
msgid "InProductMarketing|Create a project in GitLab in 5 minutes"
msgstr ""
+msgid "InProductMarketing|Create well-defined workflows by using scoped labels on issues, merge requests, and epics. Labels with the same scope cannot be used together, which prevents conflicts."
+msgstr ""
+
msgid "InProductMarketing|Create your first project!"
msgstr ""
+msgid "InProductMarketing|Define who owns specific files or directories, so the right reviewers are suggested when a merge request introduces changes to those files."
+msgstr ""
+
msgid "InProductMarketing|Deliver Better Products Faster"
msgstr ""
+msgid "InProductMarketing|Dependency scanning"
+msgstr ""
+
msgid "InProductMarketing|Did you know teams that use GitLab are far more efficient?"
msgstr ""
@@ -18429,15 +18782,27 @@ msgstr ""
msgid "InProductMarketing|Dig in and create a project and a repo"
msgstr ""
+msgid "InProductMarketing|Discover Premium & Ultimate"
+msgstr ""
+
+msgid "InProductMarketing|Discover Premium & Ultimate."
+msgstr ""
+
msgid "InProductMarketing|Do you have a minute?"
msgstr ""
msgid "InProductMarketing|Do you have a teammate who would be perfect for this task?"
msgstr ""
+msgid "InProductMarketing|Dynamic application security testing"
+msgstr ""
+
msgid "InProductMarketing|Easy"
msgstr ""
+msgid "InProductMarketing|Epics"
+msgstr ""
+
msgid "InProductMarketing|Expand your DevOps journey with a free GitLab trial"
msgstr ""
@@ -18459,9 +18824,15 @@ msgstr ""
msgid "InProductMarketing|Feel the need for speed?"
msgstr ""
+msgid "InProductMarketing|Find and fix bottlenecks in your code review process by understanding how long open merge requests have been in review."
+msgstr ""
+
msgid "InProductMarketing|Find out how your teams are really doing"
msgstr ""
+msgid "InProductMarketing|Find out if your external libraries are safe. Run dependency scanning jobs that check for known vulnerabilities in your external libraries."
+msgstr ""
+
msgid "InProductMarketing|Follow our steps"
msgstr ""
@@ -18498,6 +18869,9 @@ msgstr ""
msgid "InProductMarketing|GitLab is better with teammates to help out!"
msgstr ""
+msgid "InProductMarketing|GitLab is infrastructure agnostic (supporting GCP, AWS, Azure, OpenShift, VMWare, On Prem, Bare Metal, and more), offering a consistent workflow experience – irrespective of the environment."
+msgstr ""
+
msgid "InProductMarketing|GitLab provides static application security testing (SAST), dynamic application security testing (DAST), container scanning, and dependency scanning to help you deliver secure applications along with license compliance."
msgstr ""
@@ -18588,21 +18962,36 @@ msgstr ""
msgid "InProductMarketing|It's also possible to simply %{external_repo_link} in order to take advantage of GitLab's CI/CD."
msgstr ""
+msgid "InProductMarketing|Keep your code quality high by defining who should approve merge requests and how many approvals are required."
+msgstr ""
+
msgid "InProductMarketing|Launch GitLab CI/CD in 20 minutes or less"
msgstr ""
+msgid "InProductMarketing|Lower cost of development"
+msgstr ""
+
+msgid "InProductMarketing|Make it easier to collaborate on high-level ideas by grouping related issues in an epic."
+msgstr ""
+
msgid "InProductMarketing|Making the switch? It's easier than you think to import your projects into GitLab. Move %{github_link}, or import something %{bitbucket_link}."
msgstr ""
msgid "InProductMarketing|Master the art of importing!"
msgstr ""
+msgid "InProductMarketing|Merge request approval rule"
+msgstr ""
+
msgid "InProductMarketing|Move on to easily creating a Pages website %{ci_template_link}"
msgstr ""
msgid "InProductMarketing|Multiple owners, confusing workstreams? We've got you covered"
msgstr ""
+msgid "InProductMarketing|Multiple required approvers"
+msgstr ""
+
msgid "InProductMarketing|Need an alternative to importing?"
msgstr ""
@@ -18615,18 +19004,33 @@ msgstr ""
msgid "InProductMarketing|Our tool brings all the things together"
msgstr ""
+msgid "InProductMarketing|Protect your web application by using DAST to examine for vulnerabilities in deployed environments."
+msgstr ""
+
msgid "InProductMarketing|Rapid development, simplified"
msgstr ""
msgid "InProductMarketing|Reduce Security & Compliance Risk"
msgstr ""
+msgid "InProductMarketing|Require multiple approvers on a merge request, so you know it's in good shape before it's merged."
+msgstr ""
+
+msgid "InProductMarketing|Roadmaps"
+msgstr ""
+
+msgid "InProductMarketing|Scoped labels"
+msgstr ""
+
msgid "InProductMarketing|Security that's integrated into your development lifecycle"
msgstr ""
msgid "InProductMarketing|Sometimes you're not ready to make a full transition to a new tool. If you're not ready to fully commit, %{mirroring_link} gives you a safe way to try out GitLab in parallel with your current tool."
msgstr ""
+msgid "InProductMarketing|Speed. Efficiency. Trust."
+msgstr ""
+
msgid "InProductMarketing|Spin up an autoscaling runner in GitLab"
msgstr ""
@@ -18636,6 +19040,9 @@ msgstr ""
msgid "InProductMarketing|Start a Self-Managed trial"
msgstr ""
+msgid "InProductMarketing|Start a free trial"
+msgstr ""
+
msgid "InProductMarketing|Start a free trial of GitLab Ultimate – no credit card required"
msgstr ""
@@ -18702,6 +19109,9 @@ msgstr ""
msgid "InProductMarketing|To understand and get the most out of GitLab, start at the beginning and %{project_link}. In GitLab, repositories are part of a project, so after you've created your project you can go ahead and %{repo_link}."
msgstr ""
+msgid "InProductMarketing|Track completed issues in a chart, so you can see how a milestone is progressing at a glance."
+msgstr ""
+
msgid "InProductMarketing|Try GitLab Ultimate for free"
msgstr ""
@@ -18738,6 +19148,9 @@ msgstr ""
msgid "InProductMarketing|Very easy"
msgstr ""
+msgid "InProductMarketing|Visualize your epics and milestones in a timeline."
+msgstr ""
+
msgid "InProductMarketing|Want to host GitLab on your servers?"
msgstr ""
@@ -18759,6 +19172,9 @@ msgstr ""
msgid "InProductMarketing|YouTube"
msgstr ""
+msgid "InProductMarketing|Your software, deployed your way"
+msgstr ""
+
msgid "InProductMarketing|Your teams can be more efficient"
msgstr ""
@@ -18879,9 +19295,18 @@ msgstr ""
msgid "IncidentManagement|No incidents to display."
msgstr ""
+msgid "IncidentManagement|None"
+msgstr ""
+
msgid "IncidentManagement|Open"
msgstr ""
+msgid "IncidentManagement|Page your team with escalation policies"
+msgstr ""
+
+msgid "IncidentManagement|Paged"
+msgstr ""
+
msgid "IncidentManagement|Published"
msgstr ""
@@ -18891,6 +19316,9 @@ msgstr ""
msgid "IncidentManagement|Severity"
msgstr ""
+msgid "IncidentManagement|Status"
+msgstr ""
+
msgid "IncidentManagement|There are no closed incidents"
msgstr ""
@@ -18909,6 +19337,9 @@ msgstr ""
msgid "IncidentManagement|Unpublished"
msgstr ""
+msgid "IncidentManagement|Use escalation policies to automatically page your team when incidents are created."
+msgstr ""
+
msgid "IncidentSettings|Activate \"time to SLA\" countdown timer"
msgstr ""
@@ -18954,7 +19385,10 @@ msgstr ""
msgid "Incidents"
msgstr ""
-msgid "Incidents|Add a URL"
+msgid "Incidents|Add image details"
+msgstr ""
+
+msgid "Incidents|Add text or a link to display with your image. If you don't add either, the file name displays instead."
msgstr ""
msgid "Incidents|Drop or %{linkStart}upload%{linkEnd} a metric screenshot to attach it to the incident"
@@ -18969,10 +19403,10 @@ msgstr ""
msgid "Incidents|There was an issue loading metric images."
msgstr ""
-msgid "Incidents|There was an issue uploading your image."
+msgid "Incidents|There was an issue updating your image."
msgstr ""
-msgid "Incidents|You can optionally add a URL to link users to the original graph."
+msgid "Incidents|There was an issue uploading your image."
msgstr ""
msgid "Incident|Alert details"
@@ -18981,9 +19415,18 @@ msgstr ""
msgid "Incident|Are you sure you wish to delete this image?"
msgstr ""
+msgid "Incident|Delete image"
+msgstr ""
+
msgid "Incident|Deleting %{filename}"
msgstr ""
+msgid "Incident|Edit image text or link"
+msgstr ""
+
+msgid "Incident|Editing %{filename}"
+msgstr ""
+
msgid "Incident|Metrics"
msgstr ""
@@ -19253,12 +19696,18 @@ msgstr ""
msgid "Integrations|Branches for which notifications are to be sent"
msgstr ""
+msgid "Integrations|Clear if using a self-signed certificate."
+msgstr ""
+
msgid "Integrations|Comment detail:"
msgstr ""
msgid "Integrations|Comment settings:"
msgstr ""
+msgid "Integrations|Connection details"
+msgstr ""
+
msgid "Integrations|Connection failed. Please check your settings."
msgstr ""
@@ -19283,6 +19732,9 @@ msgstr ""
msgid "Integrations|Enable GitLab.com slash commands in a Slack workspace."
msgstr ""
+msgid "Integrations|Enable SSL verification"
+msgstr ""
+
msgid "Integrations|Enable comments"
msgstr ""
@@ -19361,6 +19813,9 @@ msgstr ""
msgid "Integrations|Return to GitLab for Jira"
msgstr ""
+msgid "Integrations|SSL verification"
+msgstr ""
+
msgid "Integrations|Save settings?"
msgstr ""
@@ -19406,9 +19861,6 @@ msgstr ""
msgid "Integrations|Use default settings"
msgstr ""
-msgid "Integrations|When you mention a Jira issue in a commit or merge request, GitLab creates a remote link and comment (if enabled)."
-msgstr ""
-
msgid "Integrations|You can now close this window and return to the GitLab for Jira application."
msgstr ""
@@ -19433,9 +19885,6 @@ msgstr ""
msgid "Integrations|can't exceed %{recipients_limit}"
msgstr ""
-msgid "Interactive developer security education."
-msgstr ""
-
msgid "Interactive mode"
msgstr ""
@@ -19925,6 +20374,9 @@ msgstr ""
msgid "IssueAnalytics|Assignees"
msgstr ""
+msgid "IssueAnalytics|Created by"
+msgstr ""
+
msgid "IssueAnalytics|Due date"
msgstr ""
@@ -19937,9 +20389,6 @@ msgstr ""
msgid "IssueAnalytics|Milestone"
msgstr ""
-msgid "IssueAnalytics|Opened by"
-msgstr ""
-
msgid "IssueAnalytics|Status"
msgstr ""
@@ -20063,10 +20512,10 @@ msgstr ""
msgid "IssuesAnalytics|Avg/Month:"
msgstr ""
-msgid "IssuesAnalytics|Issues opened"
+msgid "IssuesAnalytics|Issues created"
msgstr ""
-msgid "IssuesAnalytics|Issues opened per month"
+msgid "IssuesAnalytics|Issues created per month"
msgstr ""
msgid "IssuesAnalytics|Last 12 months"
@@ -20093,6 +20542,9 @@ msgstr ""
msgid "It looks like you have some draft commits in this branch."
msgstr ""
+msgid "It looks like you're attempting to activate your subscription. Use %{a_start}the Subscription page%{a_end} instead."
+msgstr ""
+
msgid "It may be several days before you see feature usage data."
msgstr ""
@@ -20321,6 +20773,9 @@ msgstr ""
msgid "JiraConnect|You can now close this window and return to Jira."
msgstr ""
+msgid "JiraConnect|You don't have permission to create branches for this project. Select a different project or contact the project owner for access. %{linkStart}Learn more.%{linkEnd}"
+msgstr ""
+
msgid "JiraRequest|A connection error occurred while connecting to Jira. Try your request again."
msgstr ""
@@ -20369,13 +20824,13 @@ msgstr ""
msgid "JiraService|Define the type of Jira issue to create from a vulnerability."
msgstr ""
-msgid "JiraService|Displaying Jira issues while leaving the GitLab issue functionality enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
+msgid "JiraService|Displaying Jira issues while leaving GitLab issues also enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
msgstr ""
-msgid "JiraService|Enable Jira issues"
+msgid "JiraService|Enable Jira issue creation from vulnerabilities"
msgstr ""
-msgid "JiraService|Enable Jira issues creation from vulnerabilities"
+msgid "JiraService|Enable Jira issues"
msgstr ""
msgid "JiraService|Enable Jira transitions"
@@ -20492,16 +20947,19 @@ msgstr ""
msgid "JiraService|View Jira issues in GitLab"
msgstr ""
-msgid "JiraService|Warning: All GitLab users that have access to this GitLab project are able to view all issues from the Jira project specified below."
+msgid "JiraService|Warning: All GitLab users with access to this GitLab project can view all issues from the Jira project you select."
msgstr ""
msgid "JiraService|Web URL"
msgstr ""
-msgid "JiraService|Work on Jira issues without leaving GitLab. Adds a Jira menu to access your list of Jira issues and view any issue as read-only."
+msgid "JiraService|When a Jira issue is mentioned in a commit or merge request, a remote link and comment (if enabled) will be created."
+msgstr ""
+
+msgid "JiraService|Work on Jira issues without leaving GitLab. Add a Jira menu to access a read-only list of your Jira issues."
msgstr ""
-msgid "JiraService|You need to configure Jira before enabling this integration. For more details, read the %{jira_doc_link_start}Jira integration documentation%{link_end}."
+msgid "JiraService|You must configure Jira before enabling this integration. %{jira_doc_link_start}Learn more.%{link_end}"
msgstr ""
msgid "Job"
@@ -20513,9 +20971,6 @@ msgstr ""
msgid "Job Failed #%{build_id}"
msgstr ""
-msgid "Job ID"
-msgstr ""
-
msgid "Job artifact"
msgstr ""
@@ -20582,9 +21037,27 @@ msgstr ""
msgid "Jobs|You're about to retry a job that failed because it attempted to deploy code that is older than the latest deployment. Retrying this job could result in overwriting the environment with the older source code."
msgstr ""
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source} into %{target}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{ref}"
+msgstr ""
+
+msgid "Job|Are you sure you want to erase this job log and artifacts?"
+msgstr ""
+
msgid "Job|Browse"
msgstr ""
+msgid "Job|Cancel"
+msgstr ""
+
msgid "Job|Complete Raw"
msgstr ""
@@ -20594,6 +21067,9 @@ msgstr ""
msgid "Job|Erase job log and artifacts"
msgstr ""
+msgid "Job|Finished at"
+msgstr ""
+
msgid "Job|Job artifacts"
msgstr ""
@@ -20606,7 +21082,7 @@ msgstr ""
msgid "Job|Keep"
msgstr ""
-msgid "Job|Pipeline"
+msgid "Job|Retry"
msgstr ""
msgid "Job|Scroll to bottom"
@@ -20618,6 +21094,9 @@ msgstr ""
msgid "Job|Show complete raw"
msgstr ""
+msgid "Job|Status"
+msgstr ""
+
msgid "Job|The artifacts were removed"
msgstr ""
@@ -20645,21 +21124,12 @@ msgstr ""
msgid "Job|delayed"
msgstr ""
-msgid "Job|for"
-msgstr ""
-
-msgid "Job|into"
-msgstr ""
-
msgid "Job|manual"
msgstr ""
msgid "Job|triggered"
msgstr ""
-msgid "Job|with"
-msgstr ""
-
msgid "Join Zoom meeting"
msgstr ""
@@ -20762,9 +21232,6 @@ msgstr ""
msgid "Ki"
msgstr ""
-msgid "Kontra"
-msgstr ""
-
msgid "Kroki"
msgstr ""
@@ -21088,6 +21555,9 @@ msgstr ""
msgid "Learn more about Auto DevOps"
msgstr ""
+msgid "Learn more about GitLab"
+msgstr ""
+
msgid "Learn more about Needs relationships"
msgstr ""
@@ -21415,9 +21885,18 @@ msgstr ""
msgid "Licenses|Displays licenses detected in the project, based on the %{linkStart}latest successful%{linkEnd} scan"
msgstr ""
+msgid "Licenses|Drag your license file here or %{linkStart}click to upload%{linkEnd}."
+msgstr ""
+
+msgid "Licenses|Drop your license file to start the upload."
+msgstr ""
+
msgid "Licenses|Error fetching the license list. Please check your network connection and try again."
msgstr ""
+msgid "Licenses|Error: You are trying to upload something other than a file"
+msgstr ""
+
msgid "Licenses|License Compliance"
msgstr ""
@@ -21436,6 +21915,9 @@ msgstr ""
msgid "Licenses|Specified policies in this project"
msgstr ""
+msgid "Licenses|The file could not be uploaded."
+msgstr ""
+
msgid "Licenses|The license list details information about the licenses used within your project."
msgstr ""
@@ -21469,11 +21951,6 @@ msgstr ""
msgid "Limit the size of Sidekiq jobs stored in Redis."
msgstr ""
-msgid "Limited to showing %d event at most"
-msgid_plural "Limited to showing %d events at most"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Limiting mode"
msgstr ""
@@ -21483,6 +21960,9 @@ msgstr ""
msgid "Link"
msgstr ""
+msgid "Link (optional)"
+msgstr ""
+
msgid "Link Prometheus monitoring to GitLab."
msgstr ""
@@ -21519,6 +21999,9 @@ msgstr ""
msgid "Linked emails (%{email_count})"
msgstr ""
+msgid "Linked epics"
+msgstr ""
+
msgid "Linked issues"
msgstr ""
@@ -21546,6 +22029,15 @@ msgstr ""
msgid "List of all merge commits"
msgstr ""
+msgid "List of environments for this project"
+msgstr ""
+
+msgid "List of suitable GCP locations"
+msgstr ""
+
+msgid "List of users allowed to exceed the rate limit."
+msgstr ""
+
msgid "List options"
msgstr ""
@@ -21765,6 +22257,9 @@ msgstr ""
msgid "Maintenance mode"
msgstr ""
+msgid "Make adjustments to how your GitLab instance is set up."
+msgstr ""
+
msgid "Make and review changes in the browser with the Web IDE"
msgstr ""
@@ -21909,6 +22404,12 @@ msgstr ""
msgid "MarkdownEditor|Add italic text (%{modifier_key}I)"
msgstr ""
+msgid "MarkdownEditor|Add strikethrough text (%{modifierKey}⇧X)"
+msgstr ""
+
+msgid "MarkdownEditor|Add strikethrough text (%{modifier_key}⇧X)"
+msgstr ""
+
msgid "Marked For Deletion At - %{deletion_time}"
msgstr ""
@@ -22170,6 +22671,9 @@ msgstr ""
msgid "Maximum push size (MB)"
msgstr ""
+msgid "Maximum requests per 10 minutes per user"
+msgstr ""
+
msgid "Maximum requests per minute"
msgstr ""
@@ -22260,6 +22764,19 @@ msgstr ""
msgid "Members of a group may only view projects they have permission to access"
msgstr ""
+msgid "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seat in use and will be billed for the overage."
+msgid_plural "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seats in use and will be billed for the overage."
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "MembersOverage|You are about to incur additional charges"
+msgstr ""
+
+msgid "MembersOverage|Your subscription includes %d seat."
+msgid_plural "MembersOverage|Your subscription includes %d seats."
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Membership"
msgstr ""
@@ -22464,9 +22981,6 @@ msgstr ""
msgid "Merge request not merged"
msgstr ""
-msgid "Merge request pipelines 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 merge request pipelines."
-msgstr ""
-
msgid "Merge request reports"
msgstr ""
@@ -22563,13 +23077,13 @@ msgstr ""
msgid "MergeRequests|Create issue to resolve thread"
msgstr ""
-msgid "MergeRequests|Failed to squash. Should be done manually."
+msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Saving the comment failed"
+msgid "MergeRequests|Squashing failed: Squash the commits locally, resolve any conflicts, then push the branch."
msgstr ""
-msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
+msgid "MergeRequests|Squashing not allowed: This project doesn't allow you to squash commits when merging."
msgstr ""
msgid "MergeRequests|Thread stays resolved"
@@ -23410,6 +23924,18 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "MrList|Assigned to %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from assignee %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from reviewer %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Review requested from %{name}, go to their profile."
+msgstr ""
+
msgid "Multi-project"
msgstr ""
@@ -23443,7 +23969,7 @@ msgstr ""
msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "My Awesome Group"
+msgid "My awesome group"
msgstr ""
msgid "My company or team"
@@ -24065,9 +24591,6 @@ msgstr ""
msgid "No available branches"
msgstr ""
-msgid "No available groups to fork the project."
-msgstr ""
-
msgid "No branches found"
msgstr ""
@@ -24278,6 +24801,9 @@ msgstr ""
msgid "No ref selected"
msgstr ""
+msgid "No regions configured"
+msgstr ""
+
msgid "No related merge requests found."
msgstr ""
@@ -25082,6 +25608,9 @@ msgstr ""
msgid "Only reCAPTCHA v2 is supported:"
msgstr ""
+msgid "Only required if not using role instance credentials."
+msgstr ""
+
msgid "Only use lowercase letters, numbers, and underscores."
msgstr ""
@@ -25106,9 +25635,6 @@ msgstr ""
msgid "Open a CLI and connect to the cluster you want to install the agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
-msgid "Open epics"
-msgstr ""
-
msgid "Open errors"
msgstr ""
@@ -25148,7 +25674,7 @@ msgstr ""
msgid "Opened issues"
msgstr ""
-msgid "OpenedNDaysAgo|Opened"
+msgid "OpenedNDaysAgo|Created"
msgstr ""
msgid "Opens in a new window"
@@ -25193,9 +25719,6 @@ msgstr ""
msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
-msgid "Optional."
-msgstr ""
-
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
msgstr ""
@@ -25984,6 +26507,9 @@ msgstr ""
msgid "PerformanceBar|Memory"
msgstr ""
+msgid "PerformanceBar|Memory report"
+msgstr ""
+
msgid "PerformanceBar|Redis calls"
msgstr ""
@@ -26017,18 +26543,12 @@ msgstr ""
msgid "PerformanceBar|wall"
msgstr ""
-msgid "Performs a rebase but skips triggering a new pipeline"
-msgstr ""
-
msgid "Period in seconds"
msgstr ""
msgid "Permalink"
msgstr ""
-msgid "Permanently delete project"
-msgstr ""
-
msgid "Permanently remove group"
msgstr ""
@@ -26299,6 +26819,51 @@ msgstr ""
msgid "PipelineStatusTooltip|Pipeline: %{ci_status}"
msgstr ""
+msgid "PipelineWizardDefaultCommitMessage|Add %{filename}"
+msgstr ""
+
+msgid "PipelineWizardDefaultCommitMessage|Update %{filename}"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|At least one entry is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This field is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This value is not valid"
+msgstr ""
+
+msgid "PipelineWizardListWidget|add another step"
+msgstr ""
+
+msgid "PipelineWizardListWidget|remove step"
+msgstr ""
+
+msgid "PipelineWizard|Commit"
+msgstr ""
+
+msgid "PipelineWizard|Commit Message"
+msgstr ""
+
+msgid "PipelineWizard|Commit changes to your file"
+msgstr ""
+
+msgid "PipelineWizard|Commit file to Branch"
+msgstr ""
+
+msgid "PipelineWizard|Commit your new file"
+msgstr ""
+
+msgid "PipelineWizard|The file has been committed."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem committing the changes."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem while checking whether your file already exists in the specified branch."
+msgstr ""
+
msgid "Pipelines"
msgstr ""
@@ -26413,7 +26978,7 @@ msgstr ""
msgid "Pipelines|Project cache successfully reset."
msgstr ""
-msgid "Pipelines|Revoke"
+msgid "Pipelines|Revoke trigger"
msgstr ""
msgid "Pipelines|Something went wrong while cleaning runners cache."
@@ -26458,6 +27023,12 @@ msgstr ""
msgid "Pipelines|This is a child pipeline within the parent pipeline"
msgstr ""
+msgid "Pipelines|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipelines|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipelines|This pipeline will run code originating from a forked project merge request. This means that the code can potentially have security considerations like exposing CI variables."
msgstr ""
@@ -26500,9 +27071,6 @@ msgstr ""
msgid "Pipelines|Your changes have been successfully committed. Now redirecting to the new merge request page."
msgstr ""
-msgid "Pipelines|detached"
-msgstr ""
-
msgid "Pipelines|error"
msgstr ""
@@ -26512,10 +27080,13 @@ msgstr ""
msgid "Pipelines|latest"
msgstr ""
-msgid "Pipelines|stuck"
+msgid "Pipelines|merge request"
msgstr ""
-msgid "Pipelines|train"
+msgid "Pipelines|merge train"
+msgstr ""
+
+msgid "Pipelines|stuck"
msgstr ""
msgid "Pipelines|yaml invalid"
@@ -26647,6 +27218,12 @@ msgstr ""
msgid "Pipeline|This change will not change the overall test coverage if merged."
msgstr ""
+msgid "Pipeline|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipeline|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipeline|Trigger author"
msgstr ""
@@ -26671,6 +27248,12 @@ msgstr ""
msgid "Pipeline|for"
msgstr ""
+msgid "Pipeline|merge request"
+msgstr ""
+
+msgid "Pipeline|merge train"
+msgstr ""
+
msgid "Pipeline|on"
msgstr ""
@@ -26809,9 +27392,6 @@ msgstr ""
msgid "Please enter a valid time interval"
msgstr ""
-msgid "Please enter or upload a valid license."
-msgstr ""
-
msgid "Please enter your current password."
msgstr ""
@@ -26920,9 +27500,6 @@ msgstr ""
msgid "Please type %{phrase_code} to proceed or close this modal to cancel."
msgstr ""
-msgid "Please type the following to confirm:"
-msgstr ""
-
msgid "Please use this form to report to the admin users who create spam issues, comments or behave inappropriately."
msgstr ""
@@ -26950,12 +27527,27 @@ msgstr ""
msgid "Policies"
msgstr ""
+msgid "Policy '%{escalation_policy_name}' does not exist."
+msgstr ""
+
msgid "Policy management project does have any policies in %{policy_path}"
msgstr ""
msgid "Policy project doesn't exist"
msgstr ""
+msgid "PolicyRuleMultiSelect|%{firstLabel} +%{numberOfAdditionalLabels} more"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|All %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select all"
+msgstr ""
+
msgid "Polling interval multiplier"
msgstr ""
@@ -27184,6 +27776,9 @@ msgstr ""
msgid "Private projects can be created in your personal namespace with:"
msgstr ""
+msgid "Problem with %{name} command: %{message}."
+msgstr ""
+
msgid "Proceed"
msgstr ""
@@ -27658,6 +28253,9 @@ msgstr ""
msgid "Progress"
msgstr ""
+msgid "Progress tracking"
+msgstr ""
+
msgid "Project"
msgstr ""
@@ -27889,6 +28487,9 @@ msgstr ""
msgid "ProjectQualitySummary|Failure"
msgstr ""
+msgid "ProjectQualitySummary|Get insight into the overall percentage of tests in your project that succeed, fail and are skipped."
+msgstr ""
+
msgid "ProjectQualitySummary|Latest pipeline results"
msgstr ""
@@ -27907,6 +28508,12 @@ msgstr ""
msgid "ProjectQualitySummary|See project Code Coverage Statistics"
msgstr ""
+msgid "ProjectQualitySummary|Set up test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|Set up test runs (opens in a new tab)"
+msgstr ""
+
msgid "ProjectQualitySummary|Skipped"
msgstr ""
@@ -28183,13 +28790,19 @@ msgstr ""
msgid "ProjectSettings|LFS objects from this repository are available to forks. %{linkStart}How do I remove them?%{linkEnd}"
msgstr ""
+msgid "ProjectSettings|Learn about commit history."
+msgstr ""
+
+msgid "ProjectSettings|Leave empty to use default template."
+msgstr ""
+
msgid "ProjectSettings|Manage who can see the project in the public access directory."
msgstr ""
msgid "ProjectSettings|Manages large files such as audio, video, and graphics files."
msgstr ""
-msgid "ProjectSettings|Maximum 500 characters."
+msgid "ProjectSettings|Maximum %{maxLength} characters."
msgstr ""
msgid "ProjectSettings|Merge checks"
@@ -28330,6 +28943,9 @@ msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
msgstr ""
+msgid "ProjectSettings|The default template will be applied on save."
+msgstr ""
+
msgid "ProjectSettings|These checks must pass before merge requests can be merged."
msgstr ""
@@ -28384,6 +29000,9 @@ msgstr ""
msgid "ProjectSettings|What are badges?"
msgstr ""
+msgid "ProjectSettings|What are merge trains?"
+msgstr ""
+
msgid "ProjectSettings|When merge request pipelines are enabled in the CI/CD configuration file, pipelines validate the combined results of the source and target branches. %{link_start}How to configure merge request pipelines?%{link_end}"
msgstr ""
@@ -28501,6 +29120,9 @@ msgstr ""
msgid "Projects are organized into groups"
msgstr ""
+msgid "Projects are where you store your code, access issues, wiki and other features of GitLab."
+msgstr ""
+
msgid "Projects contributed to"
msgstr ""
@@ -28516,12 +29138,6 @@ msgstr ""
msgid "Projects to index"
msgstr ""
-msgid "Projects will be permanently deleted after a %{waiting_period}-day waiting period."
-msgstr ""
-
-msgid "Projects will be permanently deleted immediately."
-msgstr ""
-
msgid "Projects with critical vulnerabilities"
msgstr ""
@@ -28606,6 +29222,9 @@ msgstr ""
msgid "ProjectsNew|Import project"
msgstr ""
+msgid "ProjectsNew|Include a Getting Started README"
+msgstr ""
+
msgid "ProjectsNew|Initialize repository with a README"
msgstr ""
@@ -28621,6 +29240,9 @@ msgstr ""
msgid "ProjectsNew|Project description %{tag_start}(optional)%{tag_end}"
msgstr ""
+msgid "ProjectsNew|Recommended if you're new to GitLab"
+msgstr ""
+
msgid "ProjectsNew|Run CI/CD for external repository"
msgstr ""
@@ -29038,6 +29660,9 @@ msgstr ""
msgid "ProtectedBranch|Unprotect"
msgstr ""
+msgid "ProtectedBranch|Unprotect branch"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
@@ -29065,6 +29690,9 @@ msgstr ""
msgid "ProtectedEnvironment|Protected Environment (%{protected_environments_count})"
msgstr ""
+msgid "ProtectedEnvironment|Required approvals"
+msgstr ""
+
msgid "ProtectedEnvironment|Select an environment"
msgstr ""
@@ -29086,10 +29714,13 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|Unprotect tag"
+msgstr ""
+
msgid "ProtectedTags|default"
msgstr ""
-msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
+msgid "ProtectedTag|By default, protected tags restrict who can modify the tag."
msgstr ""
msgid "ProtectedTag|Learn more."
@@ -29152,6 +29783,9 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Public projects are an easy way to allow everyone to have read-only access."
+msgstr ""
+
msgid "Publish to status page"
msgstr ""
@@ -29308,9 +29942,6 @@ msgstr ""
msgid "QualitySummary|Project quality"
msgstr ""
-msgid "Quarters"
-msgstr ""
-
msgid "Query"
msgstr ""
@@ -29395,6 +30026,9 @@ msgstr ""
msgid "Read more about project permissions %{help_link_open}here%{help_link_close}"
msgstr ""
+msgid "Read more about related epics"
+msgstr ""
+
msgid "Read more about related issues"
msgstr ""
@@ -29425,10 +30059,7 @@ msgstr ""
msgid "Rebase source branch on the target branch."
msgstr ""
-msgid "Rebase without CI"
-msgstr ""
-
-msgid "Rebases and triggers a pipeline"
+msgid "Rebase without pipeline"
msgstr ""
msgid "Recaptcha verified?"
@@ -29479,9 +30110,6 @@ msgstr ""
msgid "Reconfigure"
msgstr ""
-msgid "Recovering projects"
-msgstr ""
-
msgid "Recovery Codes"
msgstr ""
@@ -29541,6 +30169,12 @@ msgstr ""
msgid "Regex pattern"
msgstr ""
+msgid "Region"
+msgstr ""
+
+msgid "Regions"
+msgstr ""
+
msgid "Register"
msgstr ""
@@ -29771,9 +30405,6 @@ msgstr ""
msgid "Remove all or specific reviewer(s)"
msgstr ""
-msgid "Remove approver"
-msgstr ""
-
msgid "Remove approvers"
msgstr ""
@@ -29789,6 +30420,9 @@ msgstr ""
msgid "Remove attention request"
msgstr ""
+msgid "Remove attention request(s)"
+msgstr ""
+
msgid "Remove avatar"
msgstr ""
@@ -29927,6 +30561,9 @@ msgstr ""
msgid "Removed an issue from an epic."
msgstr ""
+msgid "Removed attention from %{users_sentence}."
+msgstr ""
+
msgid "Removed attention request from @%{username}"
msgstr ""
@@ -29978,6 +30615,9 @@ msgstr ""
msgid "Removes an issue from an epic."
msgstr ""
+msgid "Removes attention from %{users_sentence}."
+msgstr ""
+
msgid "Removes parent epic %{epic_ref}."
msgstr ""
@@ -30089,6 +30729,9 @@ msgstr ""
msgid "Report abuse to admin"
msgstr ""
+msgid "Report is generating and will be sent to your email address."
+msgstr ""
+
msgid "Reported %{timeAgo} by %{reportedBy}"
msgstr ""
@@ -30378,6 +31021,15 @@ msgstr ""
msgid "Request attention"
msgstr ""
+msgid "Request attention from %{users_sentence}."
+msgstr ""
+
+msgid "Request attention from assignee or reviewer"
+msgstr ""
+
+msgid "Request attention from assignee(s) or reviewer(s)"
+msgstr ""
+
msgid "Request attention to review"
msgstr ""
@@ -30402,6 +31054,9 @@ msgstr ""
msgid "Requested %{time_ago}"
msgstr ""
+msgid "Requested attention from %{users_sentence}."
+msgstr ""
+
msgid "Requested attention from @%{username}"
msgstr ""
@@ -30616,6 +31271,9 @@ msgstr ""
msgid "Restore project"
msgstr ""
+msgid "Restoring projects"
+msgstr ""
+
msgid "Restoring the group will prevent the group, its subgroups and projects from being removed on this date."
msgstr ""
@@ -30646,6 +31304,9 @@ msgstr ""
msgid "Retry"
msgstr ""
+msgid "Retry failed jobs"
+msgstr ""
+
msgid "Retry job"
msgstr ""
@@ -30693,9 +31354,6 @@ msgstr ""
msgid "Review changes"
msgstr ""
-msgid "Review requested from %{name}"
-msgstr ""
-
msgid "Review requests for you"
msgstr ""
@@ -30860,6 +31518,9 @@ msgstr ""
msgid "Runners|Assigned Group"
msgstr ""
+msgid "Runners|Assigned Projects (%{projectCount})"
+msgstr ""
+
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30929,6 +31590,9 @@ msgstr ""
msgid "Runners|Instance"
msgstr ""
+msgid "Runners|Jobs"
+msgstr ""
+
msgid "Runners|Last contact"
msgstr ""
@@ -31022,9 +31686,6 @@ msgstr ""
msgid "Runners|Runner %{name} was deleted"
msgstr ""
-msgid "Runners|Runner ID"
-msgstr ""
-
msgid "Runners|Runner assigned to project."
msgstr ""
@@ -31172,6 +31833,9 @@ msgstr ""
msgid "Runners|stale"
msgstr ""
+msgid "Runner|This runner has not run any jobs."
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -31286,6 +31950,24 @@ msgstr ""
msgid "Saving project."
msgstr ""
+msgid "ScanResultPolicy|%{ifLabelStart}if%{ifLabelEnd} %{scanners} scan in an open merge request targeting the %{branches} branch(es) finds %{vulnerabilitiesAllowed} or more %{severities} vulnerabilities that are %{vulnerabilityStates}"
+msgstr ""
+
+msgid "ScanResultPolicy|%{thenLabelStart}Then%{thenLabelEnd} Require approval from %{approvalsRequired} of the following approvers: %{approvers}"
+msgstr ""
+
+msgid "ScanResultPolicy|add an approver"
+msgstr ""
+
+msgid "ScanResultPolicy|scanners"
+msgstr ""
+
+msgid "ScanResultPolicy|severity levels"
+msgstr ""
+
+msgid "ScanResultPolicy|vulnerability states"
+msgstr ""
+
msgid "Scanner"
msgstr ""
@@ -31418,6 +32100,9 @@ msgstr ""
msgid "Search for a user"
msgstr ""
+msgid "Search for an emoji"
+msgstr ""
+
msgid "Search for projects, issues, etc."
msgstr ""
@@ -31605,18 +32290,12 @@ msgstr ""
msgid "Secret Detection"
msgstr ""
-msgid "Secret access key"
-msgstr ""
-
msgid "Secret token"
msgstr ""
msgid "Secure token that identifies an external storage request."
msgstr ""
-msgid "SecureCodeWarrior"
-msgstr ""
-
msgid "Security"
msgstr ""
@@ -31641,9 +32320,6 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "Security training with guide and learning pathways."
-msgstr ""
-
msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
@@ -31746,7 +32422,7 @@ msgstr ""
msgid "SecurityConfiguration|Manage corpus"
msgstr ""
-msgid "SecurityConfiguration|Manage corpus files used as mutation sources in coverage fuzzing."
+msgid "SecurityConfiguration|Manage corpus files used as seed inputs with coverage-guided fuzzing."
msgstr ""
msgid "SecurityConfiguration|Manage profiles for use by DAST scans."
@@ -31812,15 +32488,15 @@ msgstr ""
msgid "SecurityOrchestration|.yaml preview"
msgstr ""
-msgid "SecurityOrchestration|Action"
-msgstr ""
-
msgid "SecurityOrchestration|Actions"
msgstr ""
msgid "SecurityOrchestration|Add rule"
msgstr ""
+msgid "SecurityOrchestration|After dismissing the alert, the information will never be shown again."
+msgstr ""
+
msgid "SecurityOrchestration|All policies"
msgstr ""
@@ -31836,7 +32512,7 @@ msgstr ""
msgid "SecurityOrchestration|Description"
msgstr ""
-msgid "SecurityOrchestration|Disabled"
+msgid "SecurityOrchestration|Don't show the alert anymore"
msgstr ""
msgid "SecurityOrchestration|Edit policy"
@@ -31845,13 +32521,13 @@ msgstr ""
msgid "SecurityOrchestration|Edit policy project"
msgstr ""
-msgid "SecurityOrchestration|Enabled"
+msgid "SecurityOrchestration|Empty policy name"
msgstr ""
-msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Enabled"
msgstr ""
-msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
msgstr ""
msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
@@ -31860,7 +32536,7 @@ msgstr ""
msgid "SecurityOrchestration|Invalid policy type"
msgstr ""
-msgid "SecurityOrchestration|Latest scan"
+msgid "SecurityOrchestration|Latest scan run against %{agent}"
msgstr ""
msgid "SecurityOrchestration|Network"
@@ -31869,15 +32545,27 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No actions defined - policy will not run."
+msgstr ""
+
+msgid "SecurityOrchestration|No description"
+msgstr ""
+
msgid "SecurityOrchestration|No rules defined - policy will not run."
msgstr ""
+msgid "SecurityOrchestration|Not enabled"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
msgid "SecurityOrchestration|Policies"
msgstr ""
+msgid "SecurityOrchestration|Policy Type"
+msgstr ""
+
msgid "SecurityOrchestration|Policy cannot be enabled for non-existing branches (%{branches})"
msgstr ""
@@ -31902,10 +32590,13 @@ msgstr ""
msgid "SecurityOrchestration|Require %{approvals} %{plural} from %{approvers} if any of the following occur:"
msgstr ""
-msgid "SecurityOrchestration|Rule"
+msgid "SecurityOrchestration|Rules"
msgstr ""
-msgid "SecurityOrchestration|Rules"
+msgid "SecurityOrchestration|Runs %{actions} and %{lastAction} scans"
+msgstr ""
+
+msgid "SecurityOrchestration|Runs a %{action} scan"
msgstr ""
msgid "SecurityOrchestration|Scan Execution"
@@ -31965,6 +32656,9 @@ msgstr ""
msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
+msgid "SecurityOrchestration|This view only shows scan results for the agent %{agent}. You can view scan results for all agents in the %{linkStart}Operational Vulnerabilities tab of the vulnerability report%{linkEnd}."
+msgstr ""
+
msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
@@ -32019,9 +32713,6 @@ msgstr ""
msgid "SecurityOrchestration|users with ids"
msgstr ""
-msgid "SecurityOrchestration|view results"
-msgstr ""
-
msgid "SecurityOrchestration|vulnerabilities"
msgstr ""
@@ -32691,22 +33382,19 @@ 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|In order to start using functions as a service, you must first install Knative on your Kubernetes cluster. %{linkStart}More information%{linkEnd}"
-msgstr ""
-
msgid "Serverless|Learn more about Serverless"
msgstr ""
msgid "Serverless|No functions available"
msgstr ""
-msgid "Serverless|Sign up for First Look"
+msgid "Serverless|Serverless was %{linkStart}deprecated%{linkEnd} in GitLab 14.3."
+msgstr ""
+
+msgid "Serverless|Serverless was %{postLinkStart}deprecated%{postLinkEnd}. But if you opt to use it, you must install Knative in your Kubernetes cluster first. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "Serverless|The deploy job has not finished."
@@ -32718,9 +33406,6 @@ 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 ""
@@ -32736,9 +33421,6 @@ msgstr ""
msgid "Service Account Key"
msgstr ""
-msgid "Service Accounts"
-msgstr ""
-
msgid "Service Accounts keys authorize GitLab to deploy your Google Cloud project"
msgstr ""
@@ -32748,10 +33430,10 @@ msgstr ""
msgid "Service Desk allows people to create issues in your GitLab instance without their own user account. It provides a unique email address for end users to create issues in a project. Replies can be sent either through the GitLab interface or by email. End users only see threads through email."
msgstr ""
-msgid "Service Usage Data"
+msgid "Service account generated successfully"
msgstr ""
-msgid "Service account generated successfully"
+msgid "Service accounts"
msgstr ""
msgid "Service ping is disabled in your configuration file, and cannot be enabled through this form."
@@ -32895,6 +33577,9 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
+msgid "Set the per-user rate limit for getting a user by ID via the API."
+msgstr ""
+
msgid "Set the per-user rate limit for notes created by web or API requests."
msgstr ""
@@ -33074,6 +33759,9 @@ msgstr ""
msgid "Shared runners details"
msgstr ""
+msgid "Shared runners enabled cannot be enabled until a valid credit card is on file"
+msgstr ""
+
msgid "Shared runners help link"
msgstr ""
@@ -33131,6 +33819,9 @@ msgstr ""
msgid "Show all issues."
msgstr ""
+msgid "Show all milestones"
+msgstr ""
+
msgid "Show all test cases."
msgstr ""
@@ -33167,6 +33858,9 @@ msgstr ""
msgid "Show file contents"
msgstr ""
+msgid "Show group milestones"
+msgstr ""
+
msgid "Show labels"
msgstr ""
@@ -33182,6 +33876,12 @@ msgstr ""
msgid "Show open epics"
msgstr ""
+msgid "Show project milestones"
+msgstr ""
+
+msgid "Show sub-group milestones"
+msgstr ""
+
msgid "Show the Closed list"
msgstr ""
@@ -33191,11 +33891,6 @@ msgstr ""
msgid "Show whitespace changes"
msgstr ""
-msgid "Showing %d event"
-msgid_plural "Showing %d events"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Showing %{conflict} between %{sourceBranch} and %{targetBranch}"
msgstr ""
@@ -33255,12 +33950,6 @@ msgstr ""
msgid "Sidebar|None"
msgstr ""
-msgid "Sidebar|Only numeral characters allowed"
-msgstr ""
-
-msgid "Sidebar|Weight"
-msgstr ""
-
msgid "Sidekiq job compression threshold (bytes)"
msgstr ""
@@ -33423,6 +34112,9 @@ msgstr ""
msgid "Slack logo"
msgstr ""
+msgid "SlackIntegration|Are you sure you want to remove this project from the Slack application?"
+msgstr ""
+
msgid "SlackIntegration|GitLab for Slack"
msgstr ""
@@ -33432,6 +34124,9 @@ msgstr ""
msgid "SlackIntegration|Project alias"
msgstr ""
+msgid "SlackIntegration|Remove project"
+msgstr ""
+
msgid "SlackIntegration|Select a GitLab project to link with your Slack workspace."
msgstr ""
@@ -33576,9 +34271,6 @@ msgstr ""
msgid "Something went wrong trying to load issue contacts."
msgstr ""
-msgid "Something went wrong when creating a work item. Please try again"
-msgstr ""
-
msgid "Something went wrong when reordering designs. Please try again"
msgstr ""
@@ -33672,9 +34364,6 @@ msgstr ""
msgid "Something went wrong while inserting your image. Please try again."
msgstr ""
-msgid "Something went wrong while merging this merge request. Please try again."
-msgstr ""
-
msgid "Something went wrong while obtaining the Let's Encrypt certificate."
msgstr ""
@@ -33996,10 +34685,10 @@ 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."
+msgid "SourcegraphAdmin|Learn more."
msgstr ""
-msgid "SourcegraphAdmin|More information"
+msgid "SourcegraphAdmin|Only public projects have code intelligence enabled and communicate with Sourcegraph."
msgstr ""
msgid "SourcegraphAdmin|Save changes"
@@ -34008,7 +34697,7 @@ msgstr ""
msgid "SourcegraphAdmin|Sourcegraph URL"
msgstr ""
-msgid "SourcegraphAdmin|e.g. https://sourcegraph.example.com"
+msgid "SourcegraphAdmin|https://sourcegraph.example.com"
msgstr ""
msgid "SourcegraphPreferences|This feature is experimental and currently limited to certain projects."
@@ -34143,6 +34832,9 @@ msgstr ""
msgid "Start date"
msgstr ""
+msgid "Start free trial"
+msgstr ""
+
msgid "Start merge train"
msgstr ""
@@ -34173,6 +34865,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started escalation for this incident."
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -34185,6 +34880,9 @@ msgstr ""
msgid "Starts at (UTC)"
msgstr ""
+msgid "Starts escalations for this incident"
+msgstr ""
+
msgid "Starts on"
msgstr ""
@@ -34446,6 +35144,9 @@ msgstr ""
msgid "Strikethrough"
msgstr ""
+msgid "Strikethrough text"
+msgstr ""
+
msgid "Subgroup information"
msgstr ""
@@ -34680,6 +35381,21 @@ msgstr ""
msgid "Subscriptions"
msgstr ""
+msgid "Subscriptions|Chat with sales"
+msgstr ""
+
+msgid "Subscriptions|Close"
+msgstr ""
+
+msgid "Subscriptions|Not ready to buy yet?"
+msgstr ""
+
+msgid "Subscriptions|Start a free trial"
+msgstr ""
+
+msgid "Subscriptions|We understand. Maybe you have some questions for our sales team, or maybe you'd like to try some of the paid features first. What would you like to do?"
+msgstr ""
+
msgid "Subscription|Your subscription for %{strong}%{namespace_name}%{strong_close} has expired and you are now on %{pricing_link_start}the GitLab Free tier%{pricing_link_end}. Don't worry, your data is safe. Get in touch with our support team (%{support_email}). They'll gladly help with your subscription renewal."
msgstr ""
@@ -34890,6 +35606,9 @@ msgstr ""
msgid "SuperSonics|Maximum users"
msgstr ""
+msgid "SuperSonics|Offline cloud"
+msgstr ""
+
msgid "SuperSonics|Paste your activation code"
msgstr ""
@@ -34956,6 +35675,12 @@ msgstr ""
msgid "SuperSonics|You do not have an active subscription"
msgstr ""
+msgid "SuperSonics|You have a future dated license"
+msgstr ""
+
+msgid "SuperSonics|You have added a license that activates on %{date}. Please see the subscription history table below for more details."
+msgstr ""
+
msgid "SuperSonics|You have successfully added a license that activates on %{date}. Please see the subscription history table below for more details."
msgstr ""
@@ -35115,6 +35840,9 @@ msgstr ""
msgid "Tag name is required"
msgstr ""
+msgid "Tag push"
+msgstr ""
+
msgid "Tag push events"
msgstr ""
@@ -35217,6 +35945,9 @@ msgstr ""
msgid "TagsPage|protected"
msgstr ""
+msgid "Take a look at the documentation to discover all of GitLab’s capabilities."
+msgstr ""
+
msgid "Target Branch"
msgstr ""
@@ -35619,6 +36350,9 @@ msgstr ""
msgid "Tests"
msgstr ""
+msgid "Text (optional)"
+msgstr ""
+
msgid "Text added to the body of all email messages. %{character_limit} character limit"
msgstr ""
@@ -35669,6 +36403,9 @@ msgstr ""
msgid "The CSV export will be created in the background. Once finished, it will be sent to %{email} in an attachment."
msgstr ""
+msgid "The CSV export you requested of all user memberships is attached to this email."
+msgstr ""
+
msgid "The GitLab subscription service (customers.gitlab.com) is currently experiencing an outage. You can monitor the status and get updates at %{linkStart}status.gitlab.com%{linkEnd}."
msgstr ""
@@ -35744,6 +36481,9 @@ 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 epic"
+msgstr ""
+
msgid "The current issue"
msgstr ""
@@ -35905,6 +36645,9 @@ msgstr ""
msgid "The latest pipeline for this merge request has failed."
msgstr ""
+msgid "The license key is invalid."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -35920,6 +36663,9 @@ msgstr ""
msgid "The license was successfully uploaded and will be active from %{starts_at}. You can see the details below."
msgstr ""
+msgid "The license you uploaded is invalid. If the issue persists, contact support at %{link}."
+msgstr ""
+
msgid "The list creation wizard is already open"
msgstr ""
@@ -36541,10 +37287,13 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} and everything this project contains. %{strongOpen}There is no going back%{strongClose}"
+msgstr ""
+
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains."
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}on %{date}%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains. %{strongOpen}There is no going back.%{strongClose}"
msgstr ""
msgid "This action will %{strongOpen}permanently remove%{strongClose} %{codeOpen}%{group}%{codeClose} %{strongOpen}immediately%{strongClose}."
@@ -36673,9 +37422,6 @@ msgstr ""
msgid "This file was modified for readability, and can't accept suggestions. Edit it directly."
msgstr ""
-msgid "This forked project has the following:"
-msgstr ""
-
msgid "This form is disabled in preview"
msgstr ""
@@ -36688,7 +37434,7 @@ msgstr ""
msgid "This group can't be removed because it is linked to a subscription. To remove this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
-msgid "This group can't be transfered because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
+msgid "This group can't be transferred because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
msgid "This group cannot be invited to a project inside a group with enforced SSO"
@@ -36715,6 +37461,9 @@ 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 incident is already escalated with '%{escalation_policy_name}'."
+msgstr ""
+
msgid "This invitation was sent to %{mail_to_invite_email}, but you are signed in as %{link_to_current_user} with email %{mail_to_current_user}."
msgstr ""
@@ -36733,9 +37482,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 merge train pipeline"
-msgstr ""
-
msgid "This is a private email address %{helpIcon} generated just for you. Anyone who has it can create issues or merge requests as if they were you. If that happens, %{resetLinkStart}reset this token%{resetLinkEnd}."
msgstr ""
@@ -36757,6 +37503,12 @@ msgstr ""
msgid "This is your current session"
msgstr ""
+msgid "This issue cannot be assigned to a confidential epic because it is public."
+msgstr ""
+
+msgid "This issue cannot be made public because it belongs to a confidential epic."
+msgstr ""
+
msgid "This issue is confidential and should only be visible to team members with at least Reporter access."
msgstr ""
@@ -36874,6 +37626,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 branch is protected from force push."
+msgstr ""
+
msgid "This merge request cannot be rebased while there are conflicts."
msgstr ""
@@ -36925,9 +37680,15 @@ msgstr ""
msgid "This pipeline was triggered by a schedule."
msgstr ""
+msgid "This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project"
msgstr ""
+msgid "This project can be restored until %{date}."
+msgstr ""
+
msgid "This project cannot be %{visibilityLevel} because the visibility of %{openShowLink}%{name}%{closeShowLink} is %{visibility}. To make this project %{visibilityLevel}, you must first %{openEditLink}change the visibility%{closeEditLink} of the parent group."
msgstr ""
@@ -36946,6 +37707,9 @@ msgstr ""
msgid "This project is %{strongStart}NOT%{strongEnd} a fork, and has the following:"
msgstr ""
+msgid "This project is %{strongStart}NOT%{strongEnd} a fork. This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -37637,6 +38401,9 @@ msgstr ""
msgid "Today"
msgstr ""
+msgid "Todos count"
+msgstr ""
+
msgid "Todos|Are you looking for things to do? Take a look at %{strongStart}%{openIssuesLinkStart}open issues%{openIssuesLinkEnd}%{strongEnd}, contribute to %{strongStart}%{mergeRequestLinkStart}a merge request%{mergeRequestLinkEnd}%{mergeRequestLinkEnd}%{strongEnd}, or mention someone in a comment to automatically assign them a new to-do item."
msgstr ""
@@ -37910,10 +38677,8 @@ msgstr ""
msgid "Trending"
msgstr ""
-msgid "Trials|%{planName} Trial %{enDash} %{num} day left"
-msgid_plural "Trials|%{planName} Trial %{enDash} %{num} days left"
-msgstr[0] ""
-msgstr[1] ""
+msgid "Trials|%{planName} Trial"
+msgstr ""
msgid "Trials|Compare all plans"
msgstr ""
@@ -37921,6 +38686,9 @@ msgstr ""
msgid "Trials|Create a new group to start your GitLab Ultimate trial."
msgstr ""
+msgid "Trials|Day %{daysUsed}/%{duration}"
+msgstr ""
+
msgid "Trials|Go back to GitLab"
msgstr ""
@@ -38170,7 +38938,7 @@ msgstr ""
msgid "URL is triggered when repository is updated"
msgstr ""
-msgid "URL must be percent-encoded if neccessary."
+msgid "URL must be percent-encoded if necessary."
msgstr ""
msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
@@ -38389,6 +39157,9 @@ msgstr ""
msgid "Unlock account"
msgstr ""
+msgid "Unlock more features with GitLab Ultimate"
+msgstr ""
+
msgid "Unlock the discussion"
msgstr ""
@@ -38452,6 +39223,9 @@ msgstr ""
msgid "Unsubscribes from this %{quick_action_target}."
msgstr ""
+msgid "Unsupported sort value."
+msgstr ""
+
msgid "Unsupported todo type passed. Supported todo types are: %{todo_types}"
msgstr ""
@@ -38680,6 +39454,9 @@ msgstr ""
msgid "UsageQuota|File attachments and smaller design graphics."
msgstr ""
+msgid "UsageQuota|From %{storage_enforcement_date} storage limits will apply to this namespace. View and manage your usage in %{strong_start}Group Settings &gt; Usage quotas%{strong_end}."
+msgstr ""
+
msgid "UsageQuota|Git repository."
msgstr ""
@@ -38740,6 +39517,9 @@ msgstr ""
msgid "UsageQuota|Storage type"
msgstr ""
+msgid "UsageQuota|Storage used"
+msgstr ""
+
msgid "UsageQuota|This is the total amount of storage used across your projects within this namespace."
msgstr ""
@@ -38935,6 +39715,12 @@ msgstr ""
msgid "Use hashed storage paths for newly created and renamed repositories. Always enabled since 13.0."
msgstr ""
+msgid "Use issue count"
+msgstr ""
+
+msgid "Use issue weight"
+msgstr ""
+
msgid "Use one line per URI"
msgstr ""
@@ -39316,6 +40102,9 @@ msgstr ""
msgid "Users"
msgstr ""
+msgid "Users API rate limit"
+msgstr ""
+
msgid "Users can launch a development environment from a GitLab browser tab when the %{linkStart}Gitpod%{linkEnd} integration is enabled."
msgstr ""
@@ -39641,6 +40430,9 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View group pipeline usage quota"
+msgstr ""
+
msgid "View incident details at"
msgstr ""
@@ -39793,6 +40585,9 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
+msgid "Vulnerability"
+msgstr ""
+
msgid "Vulnerability Report"
msgstr ""
@@ -39844,6 +40639,9 @@ msgstr ""
msgid "VulnerabilityManagement|An unverified non-confirmed finding"
msgstr ""
+msgid "VulnerabilityManagement|At least one identifier is required"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -39853,12 +40651,24 @@ msgstr ""
msgid "VulnerabilityManagement|Create Jira issue"
msgstr ""
+msgid "VulnerabilityManagement|Enter a name"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE code"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE identifier URL"
+msgstr ""
+
msgid "VulnerabilityManagement|Fetching linked Jira issues"
msgstr ""
msgid "VulnerabilityManagement|Manually add a vulnerability entry into the vulnerability report."
msgstr ""
+msgid "VulnerabilityManagement|Name is a required field"
+msgstr ""
+
msgid "VulnerabilityManagement|Needs triage"
msgstr ""
@@ -39874,6 +40684,18 @@ msgstr ""
msgid "VulnerabilityManagement|Select a method"
msgstr ""
+msgid "VulnerabilityManagement|Select a severity level"
+msgstr ""
+
+msgid "VulnerabilityManagement|Select a status"
+msgstr ""
+
+msgid "VulnerabilityManagement|Severity is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Something went wrong while creating vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -39898,6 +40720,12 @@ msgstr ""
msgid "VulnerabilityManagement|Something went wrong, could not update vulnerability state."
msgstr ""
+msgid "VulnerabilityManagement|Status is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Submit vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Summary, detailed description, steps to reproduce, etc."
msgstr ""
@@ -40093,6 +40921,9 @@ msgstr ""
msgid "WARNING:"
msgstr ""
+msgid "WARNING: This snippet contains hidden files which might be used to mask malicious behavior. Exercise caution if cloning and executing code from this snippet."
+msgstr ""
+
msgid "Wait for the file to load to copy its contents"
msgstr ""
@@ -40312,6 +41143,15 @@ msgstr ""
msgid "Webhooks|An issue is created, updated, closed, or reopened."
msgstr ""
+msgid "Webhooks|Are you sure you want to delete this group hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this project hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this webhook?"
+msgstr ""
+
msgid "Webhooks|Comments"
msgstr ""
@@ -40321,6 +41161,9 @@ msgstr ""
msgid "Webhooks|Confidential issues events"
msgstr ""
+msgid "Webhooks|Delete webhook"
+msgstr ""
+
msgid "Webhooks|Deployment events"
msgstr ""
@@ -40554,6 +41397,9 @@ msgstr ""
msgid "Wiki"
msgstr ""
+msgid "Wiki page"
+msgstr ""
+
msgid "Wiki page was successfully created."
msgstr ""
@@ -40659,7 +41505,7 @@ msgstr ""
msgid "WikiPageConflictMessage|Someone edited the page the same time you did. Please check out %{wikiLinkStart}the page%{wikiLinkEnd} and make sure your changes will not unintentionally remove theirs."
msgstr ""
-msgid "WikiPage|An error occured while trying to render the content editor. Please try again later."
+msgid "WikiPage|An error occurred while trying to render the content editor. Please try again later."
msgstr ""
msgid "WikiPage|Are you sure you want to switch back to the classic editor?"
@@ -40818,6 +41664,18 @@ msgstr ""
msgid "WorkItem|New Task"
msgstr ""
+msgid "WorkItem|Something went wrong when creating a work item. Please try again"
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching the work item. Please try again."
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching work item types. Please try again"
+msgstr ""
+
+msgid "WorkItem|Type"
+msgstr ""
+
msgid "WorkItem|Work Items"
msgstr ""
@@ -40884,7 +41742,10 @@ msgstr ""
msgid "You are about to add %{usersTag} people to the discussion. They will all receive a notification."
msgstr ""
-msgid "You are about to permanently delete this project"
+msgid "You are about to delete this forked project containing:"
+msgstr ""
+
+msgid "You are about to delete this project containing:"
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."
@@ -40905,6 +41766,9 @@ msgstr ""
msgid "You are attempting to update a file that has changed since you started editing it."
msgstr ""
+msgid "You are billed if you exceed this number. %{qsrOverageLinkStart}How does billing work?%{qsrOverageLinkEnd}"
+msgstr ""
+
msgid "You are connected to the Prometheus server, but there is currently no data to display."
msgstr ""
@@ -40962,6 +41826,9 @@ msgstr ""
msgid "You are not authorized to update this scanner profile"
msgstr ""
+msgid "You are not authorized to upload metric images"
+msgstr ""
+
msgid "You are now impersonating %{username}"
msgstr ""
@@ -41115,9 +41982,6 @@ msgstr ""
msgid "You can only upload one design when dropping onto an existing design."
msgstr ""
-msgid "You can recover this project until %{date}"
-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 ""
@@ -41166,9 +42030,6 @@ msgstr ""
msgid "You cannot write to this read-only GitLab instance."
msgstr ""
-msgid "You can’t %{tag_start}edit%{tag_end} files directly in this project. Fork this project and submit a merge request with your changes."
-msgstr ""
-
msgid "You can’t edit files directly in this project. Fork this project and submit a merge request with your changes."
msgstr ""
@@ -41321,9 +42182,6 @@ 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 set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
@@ -41354,12 +42212,6 @@ msgstr ""
msgid "You must have maintainer access to force delete a lock"
msgstr ""
-msgid "You must have permission to create a project in a group before forking."
-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 ""
@@ -41765,7 +42617,7 @@ msgstr ""
msgid "Your public email will be displayed on your public profile."
msgstr ""
-msgid "Your request for access could not be processed: %{error_meesage}"
+msgid "Your request for access could not be processed: %{error_message}"
msgstr ""
msgid "Your request for access has been queued for review."
@@ -41948,6 +42800,9 @@ msgstr ""
msgid "archived:"
msgstr ""
+msgid "artifacts"
+msgstr ""
+
msgid "assign yourself"
msgstr ""
@@ -41977,6 +42832,9 @@ msgstr[1] ""
msgid "branch name"
msgstr ""
+msgid "builds"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -42400,6 +43258,9 @@ msgstr ""
msgid "contact with same email already exists in group hierarchy"
msgstr ""
+msgid "container registry images"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -42439,6 +43300,9 @@ msgstr ""
msgid "data"
msgstr ""
+msgid "database"
+msgstr ""
+
msgid "date must not be after 9999-12-31"
msgstr ""
@@ -42462,9 +43326,6 @@ msgstr ""
msgid "design"
msgstr ""
-msgid "detached"
-msgstr ""
-
msgid "disabled"
msgstr ""
@@ -42713,7 +43574,7 @@ msgstr ""
msgid "is not a valid X509 certificate."
msgstr ""
-msgid "is not allowed for sign-up."
+msgid "is not allowed for sign-up. Please use your regular email address."
msgstr ""
msgid "is not allowed for this group."
@@ -42725,7 +43586,7 @@ msgstr ""
msgid "is not allowed since the group is not top-level group."
msgstr ""
-msgid "is not allowed."
+msgid "is not allowed. Please use your regular email address."
msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
@@ -42812,6 +43673,9 @@ msgstr ""
msgid "level: %{level}"
msgstr ""
+msgid "lfs objects"
+msgstr ""
+
msgid "limit of %{project_limit} reached"
msgstr ""
@@ -43031,6 +43895,9 @@ msgstr ""
msgid "mrWidget|Merge blocked: pipeline must succeed. It's waiting for a manual action to continue."
msgstr ""
+msgid "mrWidget|Merge blocked: pipeline must succeed. Push a commit that fixes the failure, or %{linkStart}learn about other solutions.%{linkEnd}"
+msgstr ""
+
msgid "mrWidget|Merge blocked: this merge request must be approved."
msgstr ""
@@ -43148,9 +44015,6 @@ msgstr ""
msgid "mrWidget|The changes were not merged into"
msgstr ""
-msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -43298,9 +44162,6 @@ msgstr ""
msgid "open issue"
msgstr ""
-msgid "opened %{timeAgo}"
-msgstr ""
-
msgid "or"
msgstr ""
@@ -43312,6 +44173,12 @@ msgid_plural "out of %d total tests"
msgstr[0] ""
msgstr[1] ""
+msgid "packages"
+msgstr ""
+
+msgid "pages"
+msgstr ""
+
msgid "parent"
msgid_plural "parents"
msgstr[0] ""
@@ -43461,6 +44328,9 @@ msgid_plural "replies"
msgstr[0] ""
msgstr[1] ""
+msgid "repositories"
+msgstr ""
+
msgid "repository:"
msgstr ""
@@ -43581,12 +44451,18 @@ msgstr ""
msgid "tag name"
msgstr ""
+msgid "terraform states"
+msgstr ""
+
msgid "the correct format."
msgstr ""
msgid "the file"
msgstr ""
+msgid "the following epic(s)"
+msgstr ""
+
msgid "the following issue(s)"
msgstr ""
@@ -43599,21 +44475,12 @@ msgstr ""
msgid "this document"
msgstr ""
-msgid "this issue cannot be assigned to a confidential epic since it is public"
-msgstr ""
-
-msgid "this issue cannot be made public since it belongs to a confidential epic"
-msgstr ""
-
msgid "time summary"
msgstr ""
msgid "toggle collapse"
msgstr ""
-msgid "train"
-msgstr ""
-
msgid "triggered"
msgstr ""
@@ -43742,3 +44609,6 @@ msgstr ""
msgid "{project}"
msgstr ""
+msgid "✔"
+msgstr ""
+
diff --git a/locale/id_ID/gitlab.po b/locale/id_ID/gitlab.po
index ac7ab4845ba..df6be9194a6 100644
--- a/locale/id_ID/gitlab.po
+++ b/locale/id_ID/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: id\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2022-02-02 15:43\n"
+"PO-Revision-Date: 2022-03-01 20:37\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -132,6 +132,10 @@ msgid "%d approver (you've approved)"
msgid_plural "%d approvers (you've approved)"
msgstr[0] ""
+msgid "%d assigned issue"
+msgid_plural "%d assigned issues"
+msgstr[0] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -352,8 +356,20 @@ msgid "%d vulnerability dismissed"
msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
-msgid "%d vulnerability updated"
-msgid_plural "%d vulnerabilities updated"
+msgid "%d vulnerability set to confirmed"
+msgid_plural "%d vulnerabilities set to confirmed"
+msgstr[0] ""
+
+msgid "%d vulnerability set to dismissed"
+msgid_plural "%d vulnerabilities set to dismissed"
+msgstr[0] ""
+
+msgid "%d vulnerability set to needs triage"
+msgid_plural "%d vulnerabilities set to needs triage"
+msgstr[0] ""
+
+msgid "%d vulnerability set to resolved"
+msgid_plural "%d vulnerabilities set to resolved"
msgstr[0] ""
msgid "%d warning found:"
@@ -434,6 +450,12 @@ msgstr[0] ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{completed} of %{total} issues closed"
+msgstr ""
+
+msgid "%{completed} of %{total} weight completed"
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -776,6 +798,9 @@ msgstr ""
msgid "%{openedIssues} open, %{closedIssues} closed"
msgstr ""
+msgid "%{percentage}%% issues closed"
+msgstr ""
+
msgid "%{percentage}%% weight completed"
msgstr ""
@@ -1190,6 +1215,9 @@ msgid "- User"
msgid_plural "- Users"
msgstr[0] ""
+msgid "- of - issues closed"
+msgstr ""
+
msgid "- of - weight completed"
msgstr ""
@@ -1309,7 +1337,7 @@ msgstr ""
msgid "1000+"
msgstr ""
-msgid "192.168.0.0/24"
+msgid "192.168.0.0/24 or 2001:0DB8:1234::/48"
msgstr ""
msgid "1st contribution!"
@@ -1621,13 +1649,13 @@ msgstr ""
msgid "AWS Access Key"
msgstr ""
-msgid "AWS Access Key. Only required if not using role instance credentials"
+msgid "AWS Secret Access Key"
msgstr ""
-msgid "AWS Secret Access Key"
+msgid "AWS access key ID (Optional)"
msgstr ""
-msgid "AWS Secret Access Key. Only required if not using role instance credentials"
+msgid "AWS secret access key (Optional)"
msgstr ""
msgid "AWS service error: %{error}"
@@ -1687,9 +1715,6 @@ msgstr ""
msgid "Access granted"
msgstr ""
-msgid "Access key ID"
-msgstr ""
-
msgid "Access requests"
msgstr ""
@@ -1864,7 +1889,7 @@ msgstr ""
msgid "Activity"
msgstr ""
-msgid "Activity|An error occured while retrieving activity. Reload the page to try again."
+msgid "Activity|An error occurred while retrieving activity. Reload the page to try again."
msgstr ""
msgid "Add"
@@ -1903,6 +1928,9 @@ msgstr ""
msgid "Add a %{type}"
msgstr ""
+msgid "Add a GCP region"
+msgstr ""
+
msgid "Add a GPG key"
msgstr ""
@@ -1954,6 +1982,9 @@ msgstr ""
msgid "Add a numbered list"
msgstr ""
+msgid "Add a related epic"
+msgstr ""
+
msgid "Add a related issue"
msgstr ""
@@ -2068,6 +2099,9 @@ msgstr ""
msgid "Add or subtract spent time"
msgstr ""
+msgid "Add people"
+msgstr ""
+
msgid "Add previously merged commits"
msgstr ""
@@ -2134,6 +2168,9 @@ msgstr ""
msgid "Add webhook"
msgstr ""
+msgid "Add your team members and others to GitLab."
+msgstr ""
+
msgid "Add/remove"
msgstr ""
@@ -2956,12 +2993,6 @@ msgstr ""
msgid "AdvancedSearch|Reindex required"
msgstr ""
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. Permanently deleting this project will %{strongStart}immediately delete%{strongEnd} its repositories and %{strongStart}all related resources%{strongEnd}, including issues, merge requests etc."
-msgstr ""
-
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. You will lose this project's repository and %{strongStart}all related resources%{strongEnd}, including issues and merge requests."
-msgstr ""
-
msgid "After a successful password update you will be redirected to login screen."
msgstr ""
@@ -2992,6 +3023,9 @@ msgstr ""
msgid "Akismet helps prevent the creation of spam issues in public projects."
msgstr ""
+msgid "Alert"
+msgstr ""
+
msgid "AlertManagement|Acknowledged"
msgstr ""
@@ -3364,9 +3398,6 @@ msgstr ""
msgid "All environments"
msgstr ""
-msgid "All epics"
-msgstr ""
-
msgid "All groups and projects"
msgstr ""
@@ -4101,11 +4132,14 @@ msgstr ""
msgid "ApplicationSettings|Approve users in the pending approval status?"
msgstr ""
-msgid "ApplicationSettings|By making this change, you will automatically approve %d user with the pending approval status."
-msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users with the pending approval status."
+msgid "ApplicationSettings|Approve users who are pending approval?"
+msgstr ""
+
+msgid "ApplicationSettings|By making this change, you will automatically approve %d user who is pending approval."
+msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users who are pending approval."
msgstr[0] ""
-msgid "ApplicationSettings|By making this change, you will automatically approve all users in pending approval status."
+msgid "ApplicationSettings|By making this change, you will automatically approve all users who are pending approval."
msgstr ""
msgid "ApplicationSettings|Denied domains for sign-ups"
@@ -4506,10 +4540,10 @@ msgstr ""
msgid "Archiving the project will make it entirely read-only. It is hidden from the dashboard and doesn't show up in searches. %{strong_start}The repository cannot be committed to, and no issues, comments, or other entities can be created.%{strong_end} %{link_start}Learn more.%{link_end}"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to delete this project?"
+msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
+msgid "Are you absolutely sure?"
msgstr ""
msgid "Are you sure that you want to archive this project?"
@@ -4545,12 +4579,18 @@ msgstr ""
msgid "Are you sure you want to delete this SSH key?"
msgstr ""
+msgid "Are you sure you want to delete this comment?"
+msgstr ""
+
msgid "Are you sure you want to delete this deploy key?"
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 label?"
+msgstr ""
+
msgid "Are you sure you want to delete this pipeline schedule?"
msgstr ""
@@ -4566,9 +4606,6 @@ msgstr ""
msgid "Are you sure you want to discard your changes?"
msgstr ""
-msgid "Are you sure you want to erase this build?"
-msgstr ""
-
msgid "Are you sure you want to import %d repository?"
msgid_plural "Are you sure you want to import %d repositories?"
msgstr[0] ""
@@ -4615,6 +4652,9 @@ msgstr ""
msgid "Are you sure you want to remove this list?"
msgstr ""
+msgid "Are you sure you want to remove this nickname?"
+msgstr ""
+
msgid "Are you sure you want to reset the health check token?"
msgstr ""
@@ -4627,10 +4667,10 @@ 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?"
+msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
msgstr ""
-msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
+msgid "Are you sure you want to revoke this project access token? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to stop this environment?"
@@ -4777,9 +4817,6 @@ msgstr ""
msgid "Assigned to %{assignee_name}"
msgstr ""
-msgid "Assigned to %{name}"
-msgstr ""
-
msgid "Assigned to me"
msgstr ""
@@ -4842,6 +4879,9 @@ msgstr[0] ""
msgid "Attaching the file failed."
msgstr ""
+msgid "Attention"
+msgstr ""
+
msgid "Audit Events"
msgstr ""
@@ -5004,6 +5044,12 @@ msgstr ""
msgid "Authorized applications (%{size})"
msgstr ""
+msgid "AuthorizedApplication|Are you sure you want to revoke this application?"
+msgstr ""
+
+msgid "AuthorizedApplication|Revoke application"
+msgstr ""
+
msgid "Authors: %{authors}"
msgstr ""
@@ -6193,6 +6239,9 @@ msgstr ""
msgid "CICDAnalytics|Shared Runners Usage"
msgstr ""
+msgid "CICDAnalytics|Shared runner pipeline minute duration by month"
+msgstr ""
+
msgid "CICDAnalytics|Shared runner usage"
msgstr ""
@@ -6334,6 +6383,9 @@ msgstr ""
msgid "Can create groups:"
msgstr ""
+msgid "Can not delete primary training"
+msgstr ""
+
msgid "Can't apply as the source branch was deleted."
msgstr ""
@@ -6667,9 +6719,6 @@ msgstr ""
msgid "Changing any setting here requires an application restart"
msgstr ""
-msgid "Changing group URL can have unintended side effects."
-msgstr ""
-
msgid "Charts can't be displayed as the request for data has timed out. %{documentationLink}"
msgstr ""
@@ -6757,9 +6806,6 @@ msgstr ""
msgid "Checking branch availability..."
msgstr ""
-msgid "Checking group URL availability..."
-msgstr ""
-
msgid "Checking group path availability..."
msgstr ""
@@ -7251,6 +7297,9 @@ msgstr ""
msgid "Clear recent searches"
msgstr ""
+msgid "Clear repository checks"
+msgstr ""
+
msgid "Clear search"
msgstr ""
@@ -7383,9 +7432,6 @@ msgstr ""
msgid "Closed MRs"
msgstr ""
-msgid "Closed epics"
-msgstr ""
-
msgid "Closed issues"
msgstr ""
@@ -7422,13 +7468,13 @@ msgstr ""
msgid "Cluster level"
msgstr ""
-msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
+msgid "Cluster type must be specified for Stages::ClusterEndpointInserter"
msgstr ""
msgid "ClusterAgents|%{name} successfully deleted"
msgstr ""
-msgid "ClusterAgents|%{number} of %{total} Agents"
+msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
@@ -7470,6 +7516,15 @@ msgstr ""
msgid "ClusterAgents|Agent never connected to GitLab"
msgstr ""
+msgid "ClusterAgents|Agent version mismatch"
+msgstr ""
+
+msgid "ClusterAgents|Agent version mismatch and update"
+msgstr ""
+
+msgid "ClusterAgents|Agent version update required"
+msgstr ""
+
msgid "ClusterAgents|All"
msgstr ""
@@ -7494,7 +7549,7 @@ msgstr ""
msgid "ClusterAgents|Configuration"
msgstr ""
-msgid "ClusterAgents|Connect a cluster through the Agent"
+msgid "ClusterAgents|Connect a cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connect existing cluster"
@@ -7503,13 +7558,13 @@ msgstr ""
msgid "ClusterAgents|Connect with a certificate"
msgstr ""
-msgid "ClusterAgents|Connect with agent"
+msgid "ClusterAgents|Connect with an agent"
msgstr ""
msgid "ClusterAgents|Connect with the GitLab Agent"
msgstr ""
-msgid "ClusterAgents|Connect your cluster through the Agent"
+msgid "ClusterAgents|Connect your cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connected"
@@ -7569,7 +7624,10 @@ msgstr ""
msgid "ClusterAgents|How to register an agent?"
msgstr ""
-msgid "ClusterAgents|Install new Agent"
+msgid "ClusterAgents|How to update an agent?"
+msgstr ""
+
+msgid "ClusterAgents|Install a new agent"
msgstr ""
msgid "ClusterAgents|Last connected %{timeAgo}."
@@ -7596,7 +7654,7 @@ msgstr ""
msgid "ClusterAgents|Never connected"
msgstr ""
-msgid "ClusterAgents|No Agents"
+msgid "ClusterAgents|No agents"
msgstr ""
msgid "ClusterAgents|No clusters connected through cluster certificates"
@@ -7656,6 +7714,9 @@ msgstr ""
msgid "ClusterAgents|The agent has not been connected in a long time. There might be a connectivity issue. Last contact was %{timeAgo}."
msgstr ""
+msgid "ClusterAgents|The agent version do not match each other across your cluster's pods. This can happen when a new agent version was just deployed and Kubernetes is shutting down the old pods."
+msgstr ""
+
msgid "ClusterAgents|The recommended installation method includes the token. If you want to follow the advanced installation method provided in the docs, make sure you save the token value before you close this window."
msgstr ""
@@ -7702,6 +7763,9 @@ msgstr ""
msgid "ClusterAgents|You will need to create a token to connect to your agent"
msgstr ""
+msgid "ClusterAgents|Your agent version is out of sync with your GitLab version (v%{version}), which might cause compatibility problems. Update the agent installed on your cluster to the most recent version."
+msgstr ""
+
msgid "ClusterAgents|Your instance doesn't have the %{linkStart}GitLab Agent Server (KAS)%{linkEnd} set up. Ask a GitLab Administrator to install it."
msgstr ""
@@ -8578,9 +8642,6 @@ msgstr ""
msgid "Comma-separated list of email addresses."
msgstr ""
-msgid "Comma-separated list of users allowed to exceed the rate limit."
-msgstr ""
-
msgid "Comma-separated, e.g. '1.1.1.1, 2.2.2.0/24'"
msgstr ""
@@ -8906,6 +8967,12 @@ msgstr ""
msgid "Confidential"
msgstr ""
+msgid "Confidential issue"
+msgstr ""
+
+msgid "Confidential note"
+msgstr ""
+
msgid "Confidentiality"
msgstr ""
@@ -8939,6 +9006,9 @@ msgstr ""
msgid "Configure Dependency Scanning in `.gitlab-ci.yml`, creating this file if it does not already exist"
msgstr ""
+msgid "Configure GitLab"
+msgstr ""
+
msgid "Configure GitLab runners to start using the Web Terminal. %{helpStart}Learn more.%{helpEnd}"
msgstr ""
@@ -8987,6 +9057,15 @@ msgstr ""
msgid "Configure pipelines to deploy web apps, backend services, APIs and static resources to Google Cloud"
msgstr ""
+msgid "Configure region"
+msgstr ""
+
+msgid "Configure region for environment"
+msgstr ""
+
+msgid "Configure regions"
+msgstr ""
+
msgid "Configure repository mirroring."
msgstr ""
@@ -9020,6 +9099,9 @@ msgstr ""
msgid "Configure which lists are shown for anyone who visits this board"
msgstr ""
+msgid "Configure your environments to be deployed to specific geographical regions"
+msgstr ""
+
msgid "Confirm"
msgstr ""
@@ -9719,10 +9801,10 @@ msgstr ""
msgid "CorpusManagement|Actions"
msgstr ""
-msgid "CorpusManagement|Corpus are used in fuzz testing as mutation source to Improve future testing."
+msgid "CorpusManagement|Corpus file"
msgstr ""
-msgid "CorpusManagement|Corpus file"
+msgid "CorpusManagement|Corpus files are used in coverage-guided fuzz testing as seed inputs to improve testing."
msgstr ""
msgid "CorpusManagement|Corpus files must be in *.zip format. Maximum 5 GB"
@@ -9776,6 +9858,9 @@ msgstr ""
msgid "Could not apply %{name} command."
msgstr ""
+msgid "Could not apply %{name} command. %{message}."
+msgstr ""
+
msgid "Could not authorize chat nickname. Try again!"
msgstr ""
@@ -9926,6 +10011,9 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
+msgid "Create a group"
+msgstr ""
+
msgid "Create a merge request"
msgstr ""
@@ -9950,6 +10038,9 @@ msgstr ""
msgid "Create a personal access token on your account to pull or push via %{protocol}."
msgstr ""
+msgid "Create a project"
+msgstr ""
+
msgid "Create an account using:"
msgstr ""
@@ -10313,6 +10404,9 @@ msgstr ""
msgid "Creation date"
msgstr ""
+msgid "Creator"
+msgstr ""
+
msgid "Credentials"
msgstr ""
@@ -10325,9 +10419,15 @@ msgstr ""
msgid "CredentialsInventory|Personal Access Tokens"
msgstr ""
+msgid "CredentialsInventory|Project Access Tokens"
+msgstr ""
+
msgid "CredentialsInventory|SSH Keys"
msgstr ""
+msgid "Credit card required to be on file in order to create a pipeline"
+msgstr ""
+
msgid "Credit card:"
msgstr ""
@@ -10511,9 +10611,6 @@ msgstr ""
msgid "Customer relations"
msgstr ""
-msgid "Customizable by an administrator."
-msgstr ""
-
msgid "Customizable by owners."
msgstr ""
@@ -10643,30 +10740,18 @@ msgstr ""
msgid "CycleAnalytics|%{selectedLabelsCount} selected (%{maxLabels} max)"
msgstr ""
-msgid "CycleAnalytics|%{stageCount} stages selected"
-msgstr ""
-
-msgid "CycleAnalytics|All stages"
-msgstr ""
-
-msgid "CycleAnalytics|Average days to completion"
+msgid "CycleAnalytics|Average time to completion"
msgstr ""
msgid "CycleAnalytics|Date"
msgstr ""
-msgid "CycleAnalytics|Days to completion"
-msgstr ""
-
msgid "CycleAnalytics|Display chart filters"
msgstr ""
msgid "CycleAnalytics|Lead Time for Changes"
msgstr ""
-msgid "CycleAnalytics|No stages selected"
-msgstr ""
-
msgid "CycleAnalytics|Number of tasks"
msgstr ""
@@ -10693,18 +10778,30 @@ msgstr ""
msgid "CycleAnalytics|Showing data for group '%{groupName}' from %{createdAfter} to %{createdBefore}"
msgstr ""
-msgid "CycleAnalytics|Stages"
+msgid "CycleAnalytics|Stage time: %{title}"
msgstr ""
msgid "CycleAnalytics|Tasks by type"
msgstr ""
-msgid "CycleAnalytics|The average time spent in the selected stage for the items that were completed on each date. Data limited to the last 500 items."
+msgid "CycleAnalytics|The average time items spent in this stage. Data limited to items completed within this date range."
msgstr ""
msgid "CycleAnalytics|The given date range is larger than 180 days"
msgstr ""
+msgid "CycleAnalytics|The total time items spent across each value stream stage. Data limited to items completed within this date range."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Stage time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Total time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|Total time"
+msgstr ""
+
msgid "CycleAnalytics|Type of work"
msgstr ""
@@ -10717,9 +10814,6 @@ msgstr ""
msgid "CycleAnalytics|project dropdown filter"
msgstr ""
-msgid "CycleAnalytics|stage dropdown"
-msgstr ""
-
msgid "DAG visualization requires at least 3 dependent jobs."
msgstr ""
@@ -10819,10 +10913,16 @@ msgstr ""
msgid "DastProfiles|AJAX spider"
msgstr ""
+msgid "DastProfiles|API"
+msgstr ""
+
+msgid "DastProfiles|API endpoint URL"
+msgstr ""
+
msgid "DastProfiles|Active"
msgstr ""
-msgid "DastProfiles|Additional request headers (Optional)"
+msgid "DastProfiles|Additional request headers (optional)"
msgstr ""
msgid "DastProfiles|Are you sure you want to delete this profile?"
@@ -10837,6 +10937,9 @@ msgstr ""
msgid "DastProfiles|Branch missing"
msgstr ""
+msgid "DastProfiles|Choose a scan method"
+msgstr ""
+
msgid "DastProfiles|Could not create the scanner profile. Please try again."
msgstr ""
@@ -10906,7 +11009,13 @@ msgstr ""
msgid "DastProfiles|Excluded URLs"
msgstr ""
-msgid "DastProfiles|Excluded URLs (Optional)"
+msgid "DastProfiles|Excluded URLs (optional)"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths (optional)"
msgstr ""
msgid "DastProfiles|Hide debug messages"
@@ -10963,9 +11072,6 @@ msgstr ""
msgid "DastProfiles|Request headers"
msgstr ""
-msgid "DastProfiles|Rest API"
-msgstr ""
-
msgid "DastProfiles|Run the AJAX spider, in addition to the traditional spider, to crawl the target site."
msgstr ""
@@ -10975,6 +11081,9 @@ msgstr ""
msgid "DastProfiles|Save profile"
msgstr ""
+msgid "DastProfiles|Scan method"
+msgstr ""
+
msgid "DastProfiles|Scan mode"
msgstr ""
@@ -11053,12 +11162,24 @@ msgstr ""
msgid "DastProfiles|Website"
msgstr ""
+msgid "DastProfiles|What does each method do?"
+msgstr ""
+
msgid "DastProfiles|You can either choose a passive scan or validate the target site from the site profile management page. %{docsLinkStart}Learn more about site validation.%{docsLinkEnd}"
msgstr ""
msgid "DastProfiles|You cannot run an active scan against an unvalidated site."
msgstr ""
+msgid "DastProfiles|folder/dast_example.har or https://example.com/dast_example.har"
+msgstr ""
+
+msgid "DastProfiles|folder/example.postman_collection.json or https://example.com/"
+msgstr ""
+
+msgid "DastProfiles|folder/openapi.json or https://example.com/openapi.json"
+msgstr ""
+
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
@@ -11165,6 +11286,9 @@ msgstr ""
msgid "DatadogIntegration|API URL"
msgstr ""
+msgid "DatadogIntegration|Custom tags in Datadog. Enter one tag per line in the %{codeOpen}key:value%{codeClose} format. %{linkOpen}How do I use tags?%{linkClose}"
+msgstr ""
+
msgid "DatadogIntegration|Environment"
msgstr ""
@@ -11183,12 +11307,18 @@ msgstr ""
msgid "DatadogIntegration|Tag all data from this GitLab instance in Datadog. Useful when managing several self-managed deployments."
msgstr ""
+msgid "DatadogIntegration|Tags"
+msgstr ""
+
msgid "DatadogIntegration|The Datadog site to send data to. To send data to the EU site, use %{codeOpen}datadoghq.eu%{codeClose}."
msgstr ""
msgid "DatadogIntegration|Trace your GitLab pipelines with Datadog."
msgstr ""
+msgid "DatadogIntegration|have an invalid format"
+msgstr ""
+
msgid "Datasource name not found"
msgstr ""
@@ -11198,9 +11328,6 @@ msgstr ""
msgid "Date merged"
msgstr ""
-msgid "Date picker"
-msgstr ""
-
msgid "Date range"
msgstr ""
@@ -11354,9 +11481,6 @@ msgstr ""
msgid "Definition"
msgstr ""
-msgid "Delayed Project Deletion (%{adjourned_deletion})"
-msgstr ""
-
msgid "DelayedJobs|Are you sure you want to run %{jobName} immediately? Otherwise this job will run automatically after its timer finishes."
msgstr ""
@@ -11435,10 +11559,10 @@ msgstr ""
msgid "Delete pipeline"
msgstr ""
-msgid "Delete project"
+msgid "Delete pipeline schedule"
msgstr ""
-msgid "Delete project. Are you ABSOLUTELY SURE?"
+msgid "Delete project"
msgstr ""
msgid "Delete row"
@@ -11468,6 +11592,9 @@ msgstr ""
msgid "Delete this epic and all descendants?"
msgstr ""
+msgid "Delete this project"
+msgstr ""
+
msgid "Delete user list"
msgstr ""
@@ -11720,6 +11847,12 @@ msgstr ""
msgid "Deploy to..."
msgstr ""
+msgid "DeployBoards|To see deployment progress for your environments, make sure you are deploying to %{codeStart}$KUBE_NAMESPACE%{codeEnd} and annotating with %{codeStart}app.gitlab.com/app=$CI_PROJECT_PATH_SLUG%{codeEnd} and %{codeStart}app.gitlab.com/env=$CI_ENVIRONMENT_SLUG%{codeEnd}."
+msgstr ""
+
+msgid "DeployBoard|Kubernetes Pods"
+msgstr ""
+
msgid "DeployFreeze|Add a freeze period to prevent unintended releases during a period of time for a given environment. You must update the deployment jobs in %{filename} according to the deploy freezes added here. %{freeze_period_link_start}Learn more.%{freeze_period_link_end}"
msgstr ""
@@ -11804,9 +11937,6 @@ msgstr ""
msgid "DeployTokens|Active Deploy Tokens (%{active_tokens})"
msgstr ""
-msgid "DeployTokens|Allows read and write access to registry images."
-msgstr ""
-
msgid "DeployTokens|Allows read and write access to the package registry."
msgstr ""
@@ -11819,6 +11949,9 @@ msgstr ""
msgid "DeployTokens|Allows read-only access to the repository."
msgstr ""
+msgid "DeployTokens|Allows write access to registry images."
+msgstr ""
+
msgid "DeployTokens|Copy deploy token"
msgstr ""
@@ -11912,12 +12045,57 @@ msgstr ""
msgid "Deploying to AWS is easy with GitLab"
msgstr ""
+msgid "Deployment"
+msgstr ""
+
msgid "Deployment Frequency"
msgstr ""
+msgid "Deployment Target|Project deployment target (optional)"
+msgstr ""
+
+msgid "Deployment Target|Select the deployment target"
+msgstr ""
+
msgid "Deployment frequency"
msgstr ""
+msgid "DeploymentTarget|GitLab Pages"
+msgstr ""
+
+msgid "DeploymentTarget|Heroku"
+msgstr ""
+
+msgid "DeploymentTarget|Infrastructure provider (Terraform, Cloudformation, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Kubernetes (GKE, EKS, OpenShift, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Managed container runtime (Fargate, Cloud Run, DigitalOcean App)"
+msgstr ""
+
+msgid "DeploymentTarget|Mobile app store"
+msgstr ""
+
+msgid "DeploymentTarget|No deployment planned"
+msgstr ""
+
+msgid "DeploymentTarget|Other hosting service"
+msgstr ""
+
+msgid "DeploymentTarget|Registry (package or container)"
+msgstr ""
+
+msgid "DeploymentTarget|Self-managed container runtime (Podman, Docker Swarm, Docker Compose)"
+msgstr ""
+
+msgid "DeploymentTarget|Serverless backend (Lambda, Cloud functions)"
+msgstr ""
+
+msgid "DeploymentTarget|Virtual machine (for example, EC2)"
+msgstr ""
+
msgid "Deployments"
msgstr ""
@@ -11955,6 +12133,9 @@ msgstr ""
msgid "Deployment|This deployment was created using the API"
msgstr ""
+msgid "Deployment|Triggerer"
+msgstr ""
+
msgid "Deployment|Waiting"
msgstr ""
@@ -11982,6 +12163,18 @@ msgstr ""
msgid "Deprecated API rate limits"
msgstr ""
+msgid "Deprecations|Feature deprecation and removal"
+msgstr ""
+
+msgid "Deprecations|For information on a possible replacement %{epicStart} learn more about Opstrace %{epicEnd}."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7 and are %{epicStart} scheduled for removal %{epicEnd} in GitLab 15.0."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7, and are %{removal_link_start} scheduled for removal %{link_end} in GitLab 15.0. For information on a possible replacement, %{opstrace_link_start} learn more about Opstrace %{link_end}."
+msgstr ""
+
msgid "Deprioritize label"
msgstr ""
@@ -12226,10 +12419,10 @@ msgstr ""
msgid "DevopsAdoption|At least one deploy"
msgstr ""
-msgid "DevopsAdoption|At least one issue opened"
+msgid "DevopsAdoption|At least one issue created"
msgstr ""
-msgid "DevopsAdoption|At least one merge request opened"
+msgid "DevopsAdoption|At least one merge request created"
msgstr ""
msgid "DevopsAdoption|At least one pipeline successfully run"
@@ -12427,6 +12620,9 @@ msgstr ""
msgid "Direct member"
msgstr ""
+msgid "Direct members"
+msgstr ""
+
msgid "Direct non-authenticated users to this page."
msgstr ""
@@ -12542,6 +12738,9 @@ msgid "Dismiss %d selected vulnerability as"
msgid_plural "Dismiss %d selected vulnerabilities as"
msgstr[0] ""
+msgid "Dismiss Alert"
+msgstr ""
+
msgid "Dismiss merge request promotion"
msgstr ""
@@ -12569,9 +12768,15 @@ msgstr ""
msgid "Display alerts from all configured monitoring tools."
msgstr ""
+msgid "Display milestones"
+msgstr ""
+
msgid "Display name"
msgstr ""
+msgid "Display progress of child issues"
+msgstr ""
+
msgid "Display rendered file"
msgstr ""
@@ -12677,6 +12882,9 @@ msgstr ""
msgid "Download image"
msgstr ""
+msgid "Download payload"
+msgstr ""
+
msgid "Download raw data (.csv)"
msgstr ""
@@ -12854,6 +13062,9 @@ msgstr ""
msgid "Edit in Web IDE"
msgstr ""
+msgid "Edit in pipeline editor"
+msgstr ""
+
msgid "Edit in single-file editor"
msgstr ""
@@ -12896,6 +13107,9 @@ msgstr ""
msgid "Edit your most recent comment in a thread (from an empty textarea)"
msgstr ""
+msgid "Edit, lint, and visualize your pipeline."
+msgstr ""
+
msgid "Edited"
msgstr ""
@@ -13337,6 +13551,9 @@ msgstr ""
msgid "Enforce two-factor authentication for all user sign-ins."
msgstr ""
+msgid "Enhance security by storing service account keys in secret managers - learn more about %{docLinkStart}secret management with GitLab%{docLinkEnd}"
+msgstr ""
+
msgid "Ensure connectivity is available from the GitLab server to the Prometheus server"
msgstr ""
@@ -13397,6 +13614,9 @@ 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 following to confirm:"
+msgstr ""
+
msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
@@ -13926,9 +14146,6 @@ 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 ""
@@ -14064,6 +14281,9 @@ msgstr ""
msgid "Errors:"
msgstr ""
+msgid "Escalate this incident"
+msgstr ""
+
msgid "Escalation Policies"
msgstr ""
@@ -14076,6 +14296,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy"
+msgstr ""
+
msgid "Escalation policy:"
msgstr ""
@@ -14326,6 +14549,9 @@ msgstr ""
msgid "Existing sign in methods may be removed"
msgstr ""
+msgid "Exit."
+msgstr ""
+
msgid "Expand"
msgstr ""
@@ -14422,6 +14648,9 @@ msgstr ""
msgid "Explore public groups"
msgstr ""
+msgid "Explore public projects"
+msgstr ""
+
msgid "Explore snippets"
msgstr ""
@@ -14582,7 +14811,7 @@ msgid "Failed to archive a design. Please try again."
msgid_plural "Failed to archive designs. Please try again."
msgstr[0] ""
-msgid "Failed to assign a reviewer because no user was found."
+msgid "Failed to assign a reviewer because no user was specified."
msgstr ""
msgid "Failed to assign a user because no user was found."
@@ -14648,10 +14877,10 @@ msgstr ""
msgid "Failed to find import label for Jira import."
msgstr ""
-msgid "Failed to generate export, please try again later."
+msgid "Failed to find users for %{missing}"
msgstr ""
-msgid "Failed to generate report, please try again after sometime"
+msgid "Failed to generate export, please try again later."
msgstr ""
msgid "Failed to get ref."
@@ -14750,6 +14979,9 @@ msgstr ""
msgid "Failed to remove a to-do item for the design."
msgstr ""
+msgid "Failed to remove attention because no user was found."
+msgstr ""
+
msgid "Failed to remove mirror."
msgstr ""
@@ -14762,6 +14994,9 @@ msgstr ""
msgid "Failed to remove user key."
msgstr ""
+msgid "Failed to request attention because no user was found."
+msgstr ""
+
msgid "Failed to reset key. Please try again."
msgstr ""
@@ -14843,6 +15078,9 @@ msgstr ""
msgid "Feature Flags"
msgstr ""
+msgid "Feature deprecation and removal"
+msgstr ""
+
msgid "Feature flag status"
msgstr ""
@@ -15339,7 +15577,7 @@ msgstr ""
msgid "For each job, re-use the project workspace. If the workspace doesn't exist, use %{code_open}git clone%{code_close}."
msgstr ""
-msgid "For example, the application using the token or the purpose of the token."
+msgid "For example, the application using the token or the purpose of the token. Do not give sensitive information for the name of the token, as it will be visible to all %{resource_type} members."
msgstr ""
msgid "For files larger than this limit, only index the file name. The file content is neither indexed nor searchable."
@@ -15423,9 +15661,6 @@ msgstr ""
msgid "ForkProject|Select a namespace"
msgstr ""
-msgid "ForkProject|Select a namespace to fork the project"
-msgstr ""
-
msgid "ForkProject|The project can be accessed by any logged in user."
msgstr ""
@@ -15522,6 +15757,9 @@ msgstr ""
msgid "Full name"
msgstr ""
+msgid "GCP region configured"
+msgstr ""
+
msgid "GPG Key ID:"
msgstr ""
@@ -15702,6 +15940,9 @@ msgstr ""
msgid "Geo|Failed"
msgstr ""
+msgid "Geo|Filter Geo sites"
+msgstr ""
+
msgid "Geo|Filter by name"
msgstr ""
@@ -16113,6 +16354,12 @@ msgstr ""
msgid "GitLab Issue"
msgstr ""
+msgid "GitLab KAS"
+msgstr ""
+
+msgid "GitLab Memberships CSV Export"
+msgstr ""
+
msgid "GitLab Pages"
msgstr ""
@@ -16161,6 +16408,9 @@ 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 free to use. Many features for larger teams are part of our %{link_start}paid products%{link_end}. You can try Ultimate for free without any obligation or payment details."
+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 ""
@@ -16287,7 +16537,7 @@ msgstr ""
msgid "GitLabPages|When enabled, all attempts to visit your website through HTTP are automatically redirected to HTTPS using a response with status code 301. Requires a valid certificate for all domains. %{docs_link_start}Learn more.%{link_end}"
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. %{docs_link_start}Learn more.%{link_end}"
+msgid "GitLabPages|When using Pages under the general domain of a GitLab instance (%{pages_host}), you cannot use HTTPS with subdomains of subdomains. If your namespace or groupname contains a dot, it does not work. This is a limitation of the HTTP Over TLS protocol. HTTP pages work if you don't redirect HTTP to HTTPS. %{docs_link_start}Learn more.%{link_end}"
msgstr ""
msgid "GitLabPages|With GitLab Pages you can host your static website directly from your GitLab repository. %{docs_link_start}Learn more.%{link_end}"
@@ -16464,9 +16714,6 @@ msgstr ""
msgid "Go to find file"
msgstr ""
-msgid "Go to fork"
-msgstr ""
-
msgid "Go to issue boards"
msgstr ""
@@ -16674,9 +16921,6 @@ msgstr ""
msgid "Group Hooks"
msgstr ""
-msgid "Group ID"
-msgstr ""
-
msgid "Group Owner must have signed in with SAML before enabling Group Managed Accounts"
msgstr ""
@@ -16704,9 +16948,6 @@ msgstr ""
msgid "Group by"
msgstr ""
-msgid "Group description"
-msgstr ""
-
msgid "Group description (optional)"
msgstr ""
@@ -16821,7 +17062,7 @@ msgstr ""
msgid "Group: %{name}"
msgstr ""
-msgid "GroupActivityMetrics|Issues opened"
+msgid "GroupActivityMetrics|Issues created"
msgstr ""
msgid "GroupActivityMetrics|Last 90 days"
@@ -16830,7 +17071,7 @@ msgstr ""
msgid "GroupActivityMetrics|Members added"
msgstr ""
-msgid "GroupActivityMetrics|Merge Requests opened"
+msgid "GroupActivityMetrics|Merge Requests created"
msgstr ""
msgid "GroupActivityMetrics|Recent activity"
@@ -17121,6 +17362,9 @@ msgstr ""
msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
+msgid "GroupSettings|Choose a group path that does not start with a dash or end with a period. It can also contain alphanumeric characters and underscores."
+msgstr ""
+
msgid "GroupSettings|Compliance frameworks"
msgstr ""
@@ -17154,7 +17398,7 @@ msgstr ""
msgid "GroupSettings|If not specified at the group or instance level, the default is %{default_initial_branch_name}. Does not affect existing repositories."
msgstr ""
-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."
+msgid "GroupSettings|If the parent group's visibility is lower than the group's current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility."
msgstr ""
msgid "GroupSettings|New runners registration token has been generated!"
@@ -17271,7 +17515,10 @@ msgstr ""
msgid "Groups and projects"
msgstr ""
-msgid "Groups and subgroups"
+msgid "Groups are a great way to organize projects and people."
+msgstr ""
+
+msgid "Groups are the best way to manage projects and members."
msgstr ""
msgid "Groups to synchronize"
@@ -17382,13 +17629,16 @@ msgstr ""
msgid "GroupsTree|Are you sure you want to leave the \"%{fullName}\" group?"
msgstr ""
-msgid "GroupsTree|Edit group"
+msgid "GroupsTree|Delete"
+msgstr ""
+
+msgid "GroupsTree|Edit"
msgstr ""
msgid "GroupsTree|Failed to leave the group. Please make sure you are not the only owner."
msgstr ""
-msgid "GroupsTree|Leave this group"
+msgid "GroupsTree|Leave group"
msgstr ""
msgid "GroupsTree|Loading groups"
@@ -17400,9 +17650,57 @@ msgstr ""
msgid "GroupsTree|No groups or projects matched your search"
msgstr ""
+msgid "GroupsTree|Options"
+msgstr ""
+
msgid "GroupsTree|Search by name"
msgstr ""
+msgid "Groups|Avatar will be removed. Are you sure?"
+msgstr ""
+
+msgid "Groups|Changing group URL can have unintended side effects."
+msgstr ""
+
+msgid "Groups|Checking group URL availability..."
+msgstr ""
+
+msgid "Groups|Enter a descriptive name for your group."
+msgstr ""
+
+msgid "Groups|Group ID"
+msgstr ""
+
+msgid "Groups|Group URL"
+msgstr ""
+
+msgid "Groups|Group avatar"
+msgstr ""
+
+msgid "Groups|Group description (optional)"
+msgstr ""
+
+msgid "Groups|Group name"
+msgstr ""
+
+msgid "Groups|Group path is available."
+msgstr ""
+
+msgid "Groups|Group path is unavailable. Path has been replaced with a suggested available path."
+msgstr ""
+
+msgid "Groups|Learn more"
+msgstr ""
+
+msgid "Groups|Must start with letter, digit, emoji, or underscore. Can also contain periods, dashes, spaces, and parentheses."
+msgstr ""
+
+msgid "Groups|Remove avatar"
+msgstr ""
+
+msgid "Groups|Save changes"
+msgstr ""
+
msgid "Guideline"
msgstr ""
@@ -17412,6 +17710,9 @@ msgstr ""
msgid "HAR file path or URL"
msgstr ""
+msgid "HTTP Archive (HAR)"
+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 ""
@@ -17810,6 +18111,9 @@ msgstr ""
msgid "INFO: Your SSH key is expiring soon. Please generate a new key."
msgstr ""
+msgid "IP"
+msgstr ""
+
msgid "IP Address"
msgstr ""
@@ -17846,6 +18150,9 @@ msgstr ""
msgid "IdentityVerification|Verify your identity"
msgstr ""
+msgid "IdentityVerification|You can always verify your account at a later time to create a group."
+msgstr ""
+
msgid "If any indexed field exceeds this limit, it is truncated to this number of characters. The rest of the content is neither indexed nor searchable. This does not apply to repository and wiki indexing. For unlimited characters, set this to 0."
msgstr ""
@@ -17903,6 +18210,9 @@ msgstr ""
msgid "If you add %{codeStart}needs%{codeEnd} to jobs in your pipeline you'll be able to view the %{codeStart}needs%{codeEnd} relationships between jobs in this tab as a %{linkStart}Directed Acyclic Graph (DAG)%{linkEnd}."
msgstr ""
+msgid "If you are added to a project, it will be displayed here."
+msgstr ""
+
msgid "If you did not initiate these sign-in attempts, please reach out to your administrator or enable two-factor authentication (2FA) on your account."
msgstr ""
@@ -18206,12 +18516,24 @@ msgstr ""
msgid "InProductMarketing|3 ways to dive into GitLab CI/CD"
msgstr ""
+msgid "InProductMarketing|A single application eliminates complex integrations, data chokepoints, and toolchain maintenance, resulting in greater productivity and lower cost."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features, build more efficiently, strengthen security and compliance."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features."
+msgstr ""
+
msgid "InProductMarketing|Actually, GitLab makes the team work (better)"
msgstr ""
msgid "InProductMarketing|And finally %{deploy_link} a Python application."
msgstr ""
+msgid "InProductMarketing|And many more..."
+msgstr ""
+
msgid "InProductMarketing|Are your runners ready?"
msgstr ""
@@ -18230,15 +18552,33 @@ msgstr ""
msgid "InProductMarketing|Blog"
msgstr ""
+msgid "InProductMarketing|Break down silos to coordinate seamlessly across development, operations, and security with a consistent experience across the development lifecycle."
+msgstr ""
+
+msgid "InProductMarketing|Burn up/down charts"
+msgstr ""
+
msgid "InProductMarketing|By enabling code owners and required merge approvals the right person will review the right MR. This is a win-win: cleaner code and a more efficient review process."
msgstr ""
msgid "InProductMarketing|Click on the number below that corresponds with your answer — 1 being very difficult, 5 being very easy."
msgstr ""
+msgid "InProductMarketing|Code owners"
+msgstr ""
+
msgid "InProductMarketing|Code owners and required merge approvals are part of the paid tiers of GitLab. You can start a free 30-day trial of GitLab Ultimate and enable these features in less than 5 minutes with no credit card required."
msgstr ""
+msgid "InProductMarketing|Code review analytics"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration across stages in GitLab"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration made easy"
+msgstr ""
+
msgid "InProductMarketing|Create a custom CI runner with just a few clicks"
msgstr ""
@@ -18248,12 +18588,21 @@ msgstr ""
msgid "InProductMarketing|Create a project in GitLab in 5 minutes"
msgstr ""
+msgid "InProductMarketing|Create well-defined workflows by using scoped labels on issues, merge requests, and epics. Labels with the same scope cannot be used together, which prevents conflicts."
+msgstr ""
+
msgid "InProductMarketing|Create your first project!"
msgstr ""
+msgid "InProductMarketing|Define who owns specific files or directories, so the right reviewers are suggested when a merge request introduces changes to those files."
+msgstr ""
+
msgid "InProductMarketing|Deliver Better Products Faster"
msgstr ""
+msgid "InProductMarketing|Dependency scanning"
+msgstr ""
+
msgid "InProductMarketing|Did you know teams that use GitLab are far more efficient?"
msgstr ""
@@ -18263,15 +18612,27 @@ msgstr ""
msgid "InProductMarketing|Dig in and create a project and a repo"
msgstr ""
+msgid "InProductMarketing|Discover Premium & Ultimate"
+msgstr ""
+
+msgid "InProductMarketing|Discover Premium & Ultimate."
+msgstr ""
+
msgid "InProductMarketing|Do you have a minute?"
msgstr ""
msgid "InProductMarketing|Do you have a teammate who would be perfect for this task?"
msgstr ""
+msgid "InProductMarketing|Dynamic application security testing"
+msgstr ""
+
msgid "InProductMarketing|Easy"
msgstr ""
+msgid "InProductMarketing|Epics"
+msgstr ""
+
msgid "InProductMarketing|Expand your DevOps journey with a free GitLab trial"
msgstr ""
@@ -18293,9 +18654,15 @@ msgstr ""
msgid "InProductMarketing|Feel the need for speed?"
msgstr ""
+msgid "InProductMarketing|Find and fix bottlenecks in your code review process by understanding how long open merge requests have been in review."
+msgstr ""
+
msgid "InProductMarketing|Find out how your teams are really doing"
msgstr ""
+msgid "InProductMarketing|Find out if your external libraries are safe. Run dependency scanning jobs that check for known vulnerabilities in your external libraries."
+msgstr ""
+
msgid "InProductMarketing|Follow our steps"
msgstr ""
@@ -18332,6 +18699,9 @@ msgstr ""
msgid "InProductMarketing|GitLab is better with teammates to help out!"
msgstr ""
+msgid "InProductMarketing|GitLab is infrastructure agnostic (supporting GCP, AWS, Azure, OpenShift, VMWare, On Prem, Bare Metal, and more), offering a consistent workflow experience – irrespective of the environment."
+msgstr ""
+
msgid "InProductMarketing|GitLab provides static application security testing (SAST), dynamic application security testing (DAST), container scanning, and dependency scanning to help you deliver secure applications along with license compliance."
msgstr ""
@@ -18422,21 +18792,36 @@ msgstr ""
msgid "InProductMarketing|It's also possible to simply %{external_repo_link} in order to take advantage of GitLab's CI/CD."
msgstr ""
+msgid "InProductMarketing|Keep your code quality high by defining who should approve merge requests and how many approvals are required."
+msgstr ""
+
msgid "InProductMarketing|Launch GitLab CI/CD in 20 minutes or less"
msgstr ""
+msgid "InProductMarketing|Lower cost of development"
+msgstr ""
+
+msgid "InProductMarketing|Make it easier to collaborate on high-level ideas by grouping related issues in an epic."
+msgstr ""
+
msgid "InProductMarketing|Making the switch? It's easier than you think to import your projects into GitLab. Move %{github_link}, or import something %{bitbucket_link}."
msgstr ""
msgid "InProductMarketing|Master the art of importing!"
msgstr ""
+msgid "InProductMarketing|Merge request approval rule"
+msgstr ""
+
msgid "InProductMarketing|Move on to easily creating a Pages website %{ci_template_link}"
msgstr ""
msgid "InProductMarketing|Multiple owners, confusing workstreams? We've got you covered"
msgstr ""
+msgid "InProductMarketing|Multiple required approvers"
+msgstr ""
+
msgid "InProductMarketing|Need an alternative to importing?"
msgstr ""
@@ -18449,18 +18834,33 @@ msgstr ""
msgid "InProductMarketing|Our tool brings all the things together"
msgstr ""
+msgid "InProductMarketing|Protect your web application by using DAST to examine for vulnerabilities in deployed environments."
+msgstr ""
+
msgid "InProductMarketing|Rapid development, simplified"
msgstr ""
msgid "InProductMarketing|Reduce Security & Compliance Risk"
msgstr ""
+msgid "InProductMarketing|Require multiple approvers on a merge request, so you know it's in good shape before it's merged."
+msgstr ""
+
+msgid "InProductMarketing|Roadmaps"
+msgstr ""
+
+msgid "InProductMarketing|Scoped labels"
+msgstr ""
+
msgid "InProductMarketing|Security that's integrated into your development lifecycle"
msgstr ""
msgid "InProductMarketing|Sometimes you're not ready to make a full transition to a new tool. If you're not ready to fully commit, %{mirroring_link} gives you a safe way to try out GitLab in parallel with your current tool."
msgstr ""
+msgid "InProductMarketing|Speed. Efficiency. Trust."
+msgstr ""
+
msgid "InProductMarketing|Spin up an autoscaling runner in GitLab"
msgstr ""
@@ -18470,6 +18870,9 @@ msgstr ""
msgid "InProductMarketing|Start a Self-Managed trial"
msgstr ""
+msgid "InProductMarketing|Start a free trial"
+msgstr ""
+
msgid "InProductMarketing|Start a free trial of GitLab Ultimate – no credit card required"
msgstr ""
@@ -18536,6 +18939,9 @@ msgstr ""
msgid "InProductMarketing|To understand and get the most out of GitLab, start at the beginning and %{project_link}. In GitLab, repositories are part of a project, so after you've created your project you can go ahead and %{repo_link}."
msgstr ""
+msgid "InProductMarketing|Track completed issues in a chart, so you can see how a milestone is progressing at a glance."
+msgstr ""
+
msgid "InProductMarketing|Try GitLab Ultimate for free"
msgstr ""
@@ -18572,6 +18978,9 @@ msgstr ""
msgid "InProductMarketing|Very easy"
msgstr ""
+msgid "InProductMarketing|Visualize your epics and milestones in a timeline."
+msgstr ""
+
msgid "InProductMarketing|Want to host GitLab on your servers?"
msgstr ""
@@ -18593,6 +19002,9 @@ msgstr ""
msgid "InProductMarketing|YouTube"
msgstr ""
+msgid "InProductMarketing|Your software, deployed your way"
+msgstr ""
+
msgid "InProductMarketing|Your teams can be more efficient"
msgstr ""
@@ -18713,9 +19125,18 @@ msgstr ""
msgid "IncidentManagement|No incidents to display."
msgstr ""
+msgid "IncidentManagement|None"
+msgstr ""
+
msgid "IncidentManagement|Open"
msgstr ""
+msgid "IncidentManagement|Page your team with escalation policies"
+msgstr ""
+
+msgid "IncidentManagement|Paged"
+msgstr ""
+
msgid "IncidentManagement|Published"
msgstr ""
@@ -18725,6 +19146,9 @@ msgstr ""
msgid "IncidentManagement|Severity"
msgstr ""
+msgid "IncidentManagement|Status"
+msgstr ""
+
msgid "IncidentManagement|There are no closed incidents"
msgstr ""
@@ -18743,6 +19167,9 @@ msgstr ""
msgid "IncidentManagement|Unpublished"
msgstr ""
+msgid "IncidentManagement|Use escalation policies to automatically page your team when incidents are created."
+msgstr ""
+
msgid "IncidentSettings|Activate \"time to SLA\" countdown timer"
msgstr ""
@@ -18788,7 +19215,10 @@ msgstr ""
msgid "Incidents"
msgstr ""
-msgid "Incidents|Add a URL"
+msgid "Incidents|Add image details"
+msgstr ""
+
+msgid "Incidents|Add text or a link to display with your image. If you don't add either, the file name displays instead."
msgstr ""
msgid "Incidents|Drop or %{linkStart}upload%{linkEnd} a metric screenshot to attach it to the incident"
@@ -18803,10 +19233,10 @@ msgstr ""
msgid "Incidents|There was an issue loading metric images."
msgstr ""
-msgid "Incidents|There was an issue uploading your image."
+msgid "Incidents|There was an issue updating your image."
msgstr ""
-msgid "Incidents|You can optionally add a URL to link users to the original graph."
+msgid "Incidents|There was an issue uploading your image."
msgstr ""
msgid "Incident|Alert details"
@@ -18815,9 +19245,18 @@ msgstr ""
msgid "Incident|Are you sure you wish to delete this image?"
msgstr ""
+msgid "Incident|Delete image"
+msgstr ""
+
msgid "Incident|Deleting %{filename}"
msgstr ""
+msgid "Incident|Edit image text or link"
+msgstr ""
+
+msgid "Incident|Editing %{filename}"
+msgstr ""
+
msgid "Incident|Metrics"
msgstr ""
@@ -19086,12 +19525,18 @@ msgstr ""
msgid "Integrations|Branches for which notifications are to be sent"
msgstr ""
+msgid "Integrations|Clear if using a self-signed certificate."
+msgstr ""
+
msgid "Integrations|Comment detail:"
msgstr ""
msgid "Integrations|Comment settings:"
msgstr ""
+msgid "Integrations|Connection details"
+msgstr ""
+
msgid "Integrations|Connection failed. Please check your settings."
msgstr ""
@@ -19116,6 +19561,9 @@ msgstr ""
msgid "Integrations|Enable GitLab.com slash commands in a Slack workspace."
msgstr ""
+msgid "Integrations|Enable SSL verification"
+msgstr ""
+
msgid "Integrations|Enable comments"
msgstr ""
@@ -19194,6 +19642,9 @@ msgstr ""
msgid "Integrations|Return to GitLab for Jira"
msgstr ""
+msgid "Integrations|SSL verification"
+msgstr ""
+
msgid "Integrations|Save settings?"
msgstr ""
@@ -19239,9 +19690,6 @@ msgstr ""
msgid "Integrations|Use default settings"
msgstr ""
-msgid "Integrations|When you mention a Jira issue in a commit or merge request, GitLab creates a remote link and comment (if enabled)."
-msgstr ""
-
msgid "Integrations|You can now close this window and return to the GitLab for Jira application."
msgstr ""
@@ -19266,9 +19714,6 @@ msgstr ""
msgid "Integrations|can't exceed %{recipients_limit}"
msgstr ""
-msgid "Interactive developer security education."
-msgstr ""
-
msgid "Interactive mode"
msgstr ""
@@ -19758,6 +20203,9 @@ msgstr ""
msgid "IssueAnalytics|Assignees"
msgstr ""
+msgid "IssueAnalytics|Created by"
+msgstr ""
+
msgid "IssueAnalytics|Due date"
msgstr ""
@@ -19770,9 +20218,6 @@ msgstr ""
msgid "IssueAnalytics|Milestone"
msgstr ""
-msgid "IssueAnalytics|Opened by"
-msgstr ""
-
msgid "IssueAnalytics|Status"
msgstr ""
@@ -19896,10 +20341,10 @@ msgstr ""
msgid "IssuesAnalytics|Avg/Month:"
msgstr ""
-msgid "IssuesAnalytics|Issues opened"
+msgid "IssuesAnalytics|Issues created"
msgstr ""
-msgid "IssuesAnalytics|Issues opened per month"
+msgid "IssuesAnalytics|Issues created per month"
msgstr ""
msgid "IssuesAnalytics|Last 12 months"
@@ -19926,6 +20371,9 @@ msgstr ""
msgid "It looks like you have some draft commits in this branch."
msgstr ""
+msgid "It looks like you're attempting to activate your subscription. Use %{a_start}the Subscription page%{a_end} instead."
+msgstr ""
+
msgid "It may be several days before you see feature usage data."
msgstr ""
@@ -20154,6 +20602,9 @@ msgstr ""
msgid "JiraConnect|You can now close this window and return to Jira."
msgstr ""
+msgid "JiraConnect|You don't have permission to create branches for this project. Select a different project or contact the project owner for access. %{linkStart}Learn more.%{linkEnd}"
+msgstr ""
+
msgid "JiraRequest|A connection error occurred while connecting to Jira. Try your request again."
msgstr ""
@@ -20202,13 +20653,13 @@ msgstr ""
msgid "JiraService|Define the type of Jira issue to create from a vulnerability."
msgstr ""
-msgid "JiraService|Displaying Jira issues while leaving the GitLab issue functionality enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
+msgid "JiraService|Displaying Jira issues while leaving GitLab issues also enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
msgstr ""
-msgid "JiraService|Enable Jira issues"
+msgid "JiraService|Enable Jira issue creation from vulnerabilities"
msgstr ""
-msgid "JiraService|Enable Jira issues creation from vulnerabilities"
+msgid "JiraService|Enable Jira issues"
msgstr ""
msgid "JiraService|Enable Jira transitions"
@@ -20325,16 +20776,19 @@ msgstr ""
msgid "JiraService|View Jira issues in GitLab"
msgstr ""
-msgid "JiraService|Warning: All GitLab users that have access to this GitLab project are able to view all issues from the Jira project specified below."
+msgid "JiraService|Warning: All GitLab users with access to this GitLab project can view all issues from the Jira project you select."
msgstr ""
msgid "JiraService|Web URL"
msgstr ""
-msgid "JiraService|Work on Jira issues without leaving GitLab. Adds a Jira menu to access your list of Jira issues and view any issue as read-only."
+msgid "JiraService|When a Jira issue is mentioned in a commit or merge request, a remote link and comment (if enabled) will be created."
+msgstr ""
+
+msgid "JiraService|Work on Jira issues without leaving GitLab. Add a Jira menu to access a read-only list of your Jira issues."
msgstr ""
-msgid "JiraService|You need to configure Jira before enabling this integration. For more details, read the %{jira_doc_link_start}Jira integration documentation%{link_end}."
+msgid "JiraService|You must configure Jira before enabling this integration. %{jira_doc_link_start}Learn more.%{link_end}"
msgstr ""
msgid "Job"
@@ -20346,9 +20800,6 @@ msgstr ""
msgid "Job Failed #%{build_id}"
msgstr ""
-msgid "Job ID"
-msgstr ""
-
msgid "Job artifact"
msgstr ""
@@ -20415,9 +20866,27 @@ msgstr ""
msgid "Jobs|You're about to retry a job that failed because it attempted to deploy code that is older than the latest deployment. Retrying this job could result in overwriting the environment with the older source code."
msgstr ""
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source} into %{target}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{ref}"
+msgstr ""
+
+msgid "Job|Are you sure you want to erase this job log and artifacts?"
+msgstr ""
+
msgid "Job|Browse"
msgstr ""
+msgid "Job|Cancel"
+msgstr ""
+
msgid "Job|Complete Raw"
msgstr ""
@@ -20427,6 +20896,9 @@ msgstr ""
msgid "Job|Erase job log and artifacts"
msgstr ""
+msgid "Job|Finished at"
+msgstr ""
+
msgid "Job|Job artifacts"
msgstr ""
@@ -20439,7 +20911,7 @@ msgstr ""
msgid "Job|Keep"
msgstr ""
-msgid "Job|Pipeline"
+msgid "Job|Retry"
msgstr ""
msgid "Job|Scroll to bottom"
@@ -20451,6 +20923,9 @@ msgstr ""
msgid "Job|Show complete raw"
msgstr ""
+msgid "Job|Status"
+msgstr ""
+
msgid "Job|The artifacts were removed"
msgstr ""
@@ -20478,21 +20953,12 @@ msgstr ""
msgid "Job|delayed"
msgstr ""
-msgid "Job|for"
-msgstr ""
-
-msgid "Job|into"
-msgstr ""
-
msgid "Job|manual"
msgstr ""
msgid "Job|triggered"
msgstr ""
-msgid "Job|with"
-msgstr ""
-
msgid "Join Zoom meeting"
msgstr ""
@@ -20595,9 +21061,6 @@ msgstr ""
msgid "Ki"
msgstr ""
-msgid "Kontra"
-msgstr ""
-
msgid "Kroki"
msgstr ""
@@ -20920,6 +21383,9 @@ msgstr ""
msgid "Learn more about Auto DevOps"
msgstr ""
+msgid "Learn more about GitLab"
+msgstr ""
+
msgid "Learn more about Needs relationships"
msgstr ""
@@ -21241,9 +21707,18 @@ msgstr ""
msgid "Licenses|Displays licenses detected in the project, based on the %{linkStart}latest successful%{linkEnd} scan"
msgstr ""
+msgid "Licenses|Drag your license file here or %{linkStart}click to upload%{linkEnd}."
+msgstr ""
+
+msgid "Licenses|Drop your license file to start the upload."
+msgstr ""
+
msgid "Licenses|Error fetching the license list. Please check your network connection and try again."
msgstr ""
+msgid "Licenses|Error: You are trying to upload something other than a file"
+msgstr ""
+
msgid "Licenses|License Compliance"
msgstr ""
@@ -21262,6 +21737,9 @@ msgstr ""
msgid "Licenses|Specified policies in this project"
msgstr ""
+msgid "Licenses|The file could not be uploaded."
+msgstr ""
+
msgid "Licenses|The license list details information about the licenses used within your project."
msgstr ""
@@ -21295,10 +21773,6 @@ msgstr ""
msgid "Limit the size of Sidekiq jobs stored in Redis."
msgstr ""
-msgid "Limited to showing %d event at most"
-msgid_plural "Limited to showing %d events at most"
-msgstr[0] ""
-
msgid "Limiting mode"
msgstr ""
@@ -21308,6 +21782,9 @@ msgstr ""
msgid "Link"
msgstr ""
+msgid "Link (optional)"
+msgstr ""
+
msgid "Link Prometheus monitoring to GitLab."
msgstr ""
@@ -21344,6 +21821,9 @@ msgstr ""
msgid "Linked emails (%{email_count})"
msgstr ""
+msgid "Linked epics"
+msgstr ""
+
msgid "Linked issues"
msgstr ""
@@ -21371,6 +21851,15 @@ msgstr ""
msgid "List of all merge commits"
msgstr ""
+msgid "List of environments for this project"
+msgstr ""
+
+msgid "List of suitable GCP locations"
+msgstr ""
+
+msgid "List of users allowed to exceed the rate limit."
+msgstr ""
+
msgid "List options"
msgstr ""
@@ -21590,6 +22079,9 @@ msgstr ""
msgid "Maintenance mode"
msgstr ""
+msgid "Make adjustments to how your GitLab instance is set up."
+msgstr ""
+
msgid "Make and review changes in the browser with the Web IDE"
msgstr ""
@@ -21734,6 +22226,12 @@ msgstr ""
msgid "MarkdownEditor|Add italic text (%{modifier_key}I)"
msgstr ""
+msgid "MarkdownEditor|Add strikethrough text (%{modifierKey}⇧X)"
+msgstr ""
+
+msgid "MarkdownEditor|Add strikethrough text (%{modifier_key}⇧X)"
+msgstr ""
+
msgid "Marked For Deletion At - %{deletion_time}"
msgstr ""
@@ -21995,6 +22493,9 @@ msgstr ""
msgid "Maximum push size (MB)"
msgstr ""
+msgid "Maximum requests per 10 minutes per user"
+msgstr ""
+
msgid "Maximum requests per minute"
msgstr ""
@@ -22085,6 +22586,17 @@ msgstr ""
msgid "Members of a group may only view projects they have permission to access"
msgstr ""
+msgid "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seat in use and will be billed for the overage."
+msgid_plural "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seats in use and will be billed for the overage."
+msgstr[0] ""
+
+msgid "MembersOverage|You are about to incur additional charges"
+msgstr ""
+
+msgid "MembersOverage|Your subscription includes %d seat."
+msgid_plural "MembersOverage|Your subscription includes %d seats."
+msgstr[0] ""
+
msgid "Membership"
msgstr ""
@@ -22289,9 +22801,6 @@ msgstr ""
msgid "Merge request not merged"
msgstr ""
-msgid "Merge request pipelines 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 merge request pipelines."
-msgstr ""
-
msgid "Merge request reports"
msgstr ""
@@ -22388,13 +22897,13 @@ msgstr ""
msgid "MergeRequests|Create issue to resolve thread"
msgstr ""
-msgid "MergeRequests|Failed to squash. Should be done manually."
+msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Saving the comment failed"
+msgid "MergeRequests|Squashing failed: Squash the commits locally, resolve any conflicts, then push the branch."
msgstr ""
-msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
+msgid "MergeRequests|Squashing not allowed: This project doesn't allow you to squash commits when merging."
msgstr ""
msgid "MergeRequests|Thread stays resolved"
@@ -23233,6 +23742,18 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "MrList|Assigned to %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from assignee %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from reviewer %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Review requested from %{name}, go to their profile."
+msgstr ""
+
msgid "Multi-project"
msgstr ""
@@ -23266,7 +23787,7 @@ msgstr ""
msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "My Awesome Group"
+msgid "My awesome group"
msgstr ""
msgid "My company or team"
@@ -23886,9 +24407,6 @@ msgstr ""
msgid "No available branches"
msgstr ""
-msgid "No available groups to fork the project."
-msgstr ""
-
msgid "No branches found"
msgstr ""
@@ -24099,6 +24617,9 @@ msgstr ""
msgid "No ref selected"
msgstr ""
+msgid "No regions configured"
+msgstr ""
+
msgid "No related merge requests found."
msgstr ""
@@ -24897,6 +25418,9 @@ msgstr ""
msgid "Only reCAPTCHA v2 is supported:"
msgstr ""
+msgid "Only required if not using role instance credentials."
+msgstr ""
+
msgid "Only use lowercase letters, numbers, and underscores."
msgstr ""
@@ -24921,9 +25445,6 @@ msgstr ""
msgid "Open a CLI and connect to the cluster you want to install the agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
-msgid "Open epics"
-msgstr ""
-
msgid "Open errors"
msgstr ""
@@ -24963,7 +25484,7 @@ msgstr ""
msgid "Opened issues"
msgstr ""
-msgid "OpenedNDaysAgo|Opened"
+msgid "OpenedNDaysAgo|Created"
msgstr ""
msgid "Opens in a new window"
@@ -25008,9 +25529,6 @@ msgstr ""
msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
-msgid "Optional."
-msgstr ""
-
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
msgstr ""
@@ -25798,6 +26316,9 @@ msgstr ""
msgid "PerformanceBar|Memory"
msgstr ""
+msgid "PerformanceBar|Memory report"
+msgstr ""
+
msgid "PerformanceBar|Redis calls"
msgstr ""
@@ -25831,18 +26352,12 @@ msgstr ""
msgid "PerformanceBar|wall"
msgstr ""
-msgid "Performs a rebase but skips triggering a new pipeline"
-msgstr ""
-
msgid "Period in seconds"
msgstr ""
msgid "Permalink"
msgstr ""
-msgid "Permanently delete project"
-msgstr ""
-
msgid "Permanently remove group"
msgstr ""
@@ -26113,6 +26628,51 @@ msgstr ""
msgid "PipelineStatusTooltip|Pipeline: %{ci_status}"
msgstr ""
+msgid "PipelineWizardDefaultCommitMessage|Add %{filename}"
+msgstr ""
+
+msgid "PipelineWizardDefaultCommitMessage|Update %{filename}"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|At least one entry is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This field is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This value is not valid"
+msgstr ""
+
+msgid "PipelineWizardListWidget|add another step"
+msgstr ""
+
+msgid "PipelineWizardListWidget|remove step"
+msgstr ""
+
+msgid "PipelineWizard|Commit"
+msgstr ""
+
+msgid "PipelineWizard|Commit Message"
+msgstr ""
+
+msgid "PipelineWizard|Commit changes to your file"
+msgstr ""
+
+msgid "PipelineWizard|Commit file to Branch"
+msgstr ""
+
+msgid "PipelineWizard|Commit your new file"
+msgstr ""
+
+msgid "PipelineWizard|The file has been committed."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem committing the changes."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem while checking whether your file already exists in the specified branch."
+msgstr ""
+
msgid "Pipelines"
msgstr ""
@@ -26227,7 +26787,7 @@ msgstr ""
msgid "Pipelines|Project cache successfully reset."
msgstr ""
-msgid "Pipelines|Revoke"
+msgid "Pipelines|Revoke trigger"
msgstr ""
msgid "Pipelines|Something went wrong while cleaning runners cache."
@@ -26272,6 +26832,12 @@ msgstr ""
msgid "Pipelines|This is a child pipeline within the parent pipeline"
msgstr ""
+msgid "Pipelines|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipelines|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipelines|This pipeline will run code originating from a forked project merge request. This means that the code can potentially have security considerations like exposing CI variables."
msgstr ""
@@ -26314,9 +26880,6 @@ msgstr ""
msgid "Pipelines|Your changes have been successfully committed. Now redirecting to the new merge request page."
msgstr ""
-msgid "Pipelines|detached"
-msgstr ""
-
msgid "Pipelines|error"
msgstr ""
@@ -26326,10 +26889,13 @@ msgstr ""
msgid "Pipelines|latest"
msgstr ""
-msgid "Pipelines|stuck"
+msgid "Pipelines|merge request"
msgstr ""
-msgid "Pipelines|train"
+msgid "Pipelines|merge train"
+msgstr ""
+
+msgid "Pipelines|stuck"
msgstr ""
msgid "Pipelines|yaml invalid"
@@ -26461,6 +27027,12 @@ msgstr ""
msgid "Pipeline|This change will not change the overall test coverage if merged."
msgstr ""
+msgid "Pipeline|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipeline|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipeline|Trigger author"
msgstr ""
@@ -26485,6 +27057,12 @@ msgstr ""
msgid "Pipeline|for"
msgstr ""
+msgid "Pipeline|merge request"
+msgstr ""
+
+msgid "Pipeline|merge train"
+msgstr ""
+
msgid "Pipeline|on"
msgstr ""
@@ -26623,9 +27201,6 @@ msgstr ""
msgid "Please enter a valid time interval"
msgstr ""
-msgid "Please enter or upload a valid license."
-msgstr ""
-
msgid "Please enter your current password."
msgstr ""
@@ -26734,9 +27309,6 @@ msgstr ""
msgid "Please type %{phrase_code} to proceed or close this modal to cancel."
msgstr ""
-msgid "Please type the following to confirm:"
-msgstr ""
-
msgid "Please use this form to report to the admin users who create spam issues, comments or behave inappropriately."
msgstr ""
@@ -26764,12 +27336,27 @@ msgstr ""
msgid "Policies"
msgstr ""
+msgid "Policy '%{escalation_policy_name}' does not exist."
+msgstr ""
+
msgid "Policy management project does have any policies in %{policy_path}"
msgstr ""
msgid "Policy project doesn't exist"
msgstr ""
+msgid "PolicyRuleMultiSelect|%{firstLabel} +%{numberOfAdditionalLabels} more"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|All %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select all"
+msgstr ""
+
msgid "Polling interval multiplier"
msgstr ""
@@ -26998,6 +27585,9 @@ msgstr ""
msgid "Private projects can be created in your personal namespace with:"
msgstr ""
+msgid "Problem with %{name} command: %{message}."
+msgstr ""
+
msgid "Proceed"
msgstr ""
@@ -27472,6 +28062,9 @@ msgstr ""
msgid "Progress"
msgstr ""
+msgid "Progress tracking"
+msgstr ""
+
msgid "Project"
msgstr ""
@@ -27703,6 +28296,9 @@ msgstr ""
msgid "ProjectQualitySummary|Failure"
msgstr ""
+msgid "ProjectQualitySummary|Get insight into the overall percentage of tests in your project that succeed, fail and are skipped."
+msgstr ""
+
msgid "ProjectQualitySummary|Latest pipeline results"
msgstr ""
@@ -27721,6 +28317,12 @@ msgstr ""
msgid "ProjectQualitySummary|See project Code Coverage Statistics"
msgstr ""
+msgid "ProjectQualitySummary|Set up test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|Set up test runs (opens in a new tab)"
+msgstr ""
+
msgid "ProjectQualitySummary|Skipped"
msgstr ""
@@ -27997,13 +28599,19 @@ msgstr ""
msgid "ProjectSettings|LFS objects from this repository are available to forks. %{linkStart}How do I remove them?%{linkEnd}"
msgstr ""
+msgid "ProjectSettings|Learn about commit history."
+msgstr ""
+
+msgid "ProjectSettings|Leave empty to use default template."
+msgstr ""
+
msgid "ProjectSettings|Manage who can see the project in the public access directory."
msgstr ""
msgid "ProjectSettings|Manages large files such as audio, video, and graphics files."
msgstr ""
-msgid "ProjectSettings|Maximum 500 characters."
+msgid "ProjectSettings|Maximum %{maxLength} characters."
msgstr ""
msgid "ProjectSettings|Merge checks"
@@ -28144,6 +28752,9 @@ msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
msgstr ""
+msgid "ProjectSettings|The default template will be applied on save."
+msgstr ""
+
msgid "ProjectSettings|These checks must pass before merge requests can be merged."
msgstr ""
@@ -28198,6 +28809,9 @@ msgstr ""
msgid "ProjectSettings|What are badges?"
msgstr ""
+msgid "ProjectSettings|What are merge trains?"
+msgstr ""
+
msgid "ProjectSettings|When merge request pipelines are enabled in the CI/CD configuration file, pipelines validate the combined results of the source and target branches. %{link_start}How to configure merge request pipelines?%{link_end}"
msgstr ""
@@ -28315,6 +28929,9 @@ msgstr ""
msgid "Projects are organized into groups"
msgstr ""
+msgid "Projects are where you store your code, access issues, wiki and other features of GitLab."
+msgstr ""
+
msgid "Projects contributed to"
msgstr ""
@@ -28330,12 +28947,6 @@ msgstr ""
msgid "Projects to index"
msgstr ""
-msgid "Projects will be permanently deleted after a %{waiting_period}-day waiting period."
-msgstr ""
-
-msgid "Projects will be permanently deleted immediately."
-msgstr ""
-
msgid "Projects with critical vulnerabilities"
msgstr ""
@@ -28420,6 +29031,9 @@ msgstr ""
msgid "ProjectsNew|Import project"
msgstr ""
+msgid "ProjectsNew|Include a Getting Started README"
+msgstr ""
+
msgid "ProjectsNew|Initialize repository with a README"
msgstr ""
@@ -28435,6 +29049,9 @@ msgstr ""
msgid "ProjectsNew|Project description %{tag_start}(optional)%{tag_end}"
msgstr ""
+msgid "ProjectsNew|Recommended if you're new to GitLab"
+msgstr ""
+
msgid "ProjectsNew|Run CI/CD for external repository"
msgstr ""
@@ -28852,6 +29469,9 @@ msgstr ""
msgid "ProtectedBranch|Unprotect"
msgstr ""
+msgid "ProtectedBranch|Unprotect branch"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
@@ -28879,6 +29499,9 @@ msgstr ""
msgid "ProtectedEnvironment|Protected Environment (%{protected_environments_count})"
msgstr ""
+msgid "ProtectedEnvironment|Required approvals"
+msgstr ""
+
msgid "ProtectedEnvironment|Select an environment"
msgstr ""
@@ -28900,10 +29523,13 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|Unprotect tag"
+msgstr ""
+
msgid "ProtectedTags|default"
msgstr ""
-msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
+msgid "ProtectedTag|By default, protected tags restrict who can modify the tag."
msgstr ""
msgid "ProtectedTag|Learn more."
@@ -28966,6 +29592,9 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Public projects are an easy way to allow everyone to have read-only access."
+msgstr ""
+
msgid "Publish to status page"
msgstr ""
@@ -29122,9 +29751,6 @@ msgstr ""
msgid "QualitySummary|Project quality"
msgstr ""
-msgid "Quarters"
-msgstr ""
-
msgid "Query"
msgstr ""
@@ -29209,6 +29835,9 @@ msgstr ""
msgid "Read more about project permissions %{help_link_open}here%{help_link_close}"
msgstr ""
+msgid "Read more about related epics"
+msgstr ""
+
msgid "Read more about related issues"
msgstr ""
@@ -29239,10 +29868,7 @@ msgstr ""
msgid "Rebase source branch on the target branch."
msgstr ""
-msgid "Rebase without CI"
-msgstr ""
-
-msgid "Rebases and triggers a pipeline"
+msgid "Rebase without pipeline"
msgstr ""
msgid "Recaptcha verified?"
@@ -29293,9 +29919,6 @@ msgstr ""
msgid "Reconfigure"
msgstr ""
-msgid "Recovering projects"
-msgstr ""
-
msgid "Recovery Codes"
msgstr ""
@@ -29354,6 +29977,12 @@ msgstr ""
msgid "Regex pattern"
msgstr ""
+msgid "Region"
+msgstr ""
+
+msgid "Regions"
+msgstr ""
+
msgid "Register"
msgstr ""
@@ -29583,9 +30212,6 @@ msgstr ""
msgid "Remove all or specific reviewer(s)"
msgstr ""
-msgid "Remove approver"
-msgstr ""
-
msgid "Remove approvers"
msgstr ""
@@ -29601,6 +30227,9 @@ msgstr ""
msgid "Remove attention request"
msgstr ""
+msgid "Remove attention request(s)"
+msgstr ""
+
msgid "Remove avatar"
msgstr ""
@@ -29739,6 +30368,9 @@ msgstr ""
msgid "Removed an issue from an epic."
msgstr ""
+msgid "Removed attention from %{users_sentence}."
+msgstr ""
+
msgid "Removed attention request from @%{username}"
msgstr ""
@@ -29790,6 +30422,9 @@ msgstr ""
msgid "Removes an issue from an epic."
msgstr ""
+msgid "Removes attention from %{users_sentence}."
+msgstr ""
+
msgid "Removes parent epic %{epic_ref}."
msgstr ""
@@ -29901,6 +30536,9 @@ msgstr ""
msgid "Report abuse to admin"
msgstr ""
+msgid "Report is generating and will be sent to your email address."
+msgstr ""
+
msgid "Reported %{timeAgo} by %{reportedBy}"
msgstr ""
@@ -30185,6 +30823,15 @@ msgstr ""
msgid "Request attention"
msgstr ""
+msgid "Request attention from %{users_sentence}."
+msgstr ""
+
+msgid "Request attention from assignee or reviewer"
+msgstr ""
+
+msgid "Request attention from assignee(s) or reviewer(s)"
+msgstr ""
+
msgid "Request attention to review"
msgstr ""
@@ -30209,6 +30856,9 @@ msgstr ""
msgid "Requested %{time_ago}"
msgstr ""
+msgid "Requested attention from %{users_sentence}."
+msgstr ""
+
msgid "Requested attention from @%{username}"
msgstr ""
@@ -30421,6 +31071,9 @@ msgstr ""
msgid "Restore project"
msgstr ""
+msgid "Restoring projects"
+msgstr ""
+
msgid "Restoring the group will prevent the group, its subgroups and projects from being removed on this date."
msgstr ""
@@ -30451,6 +31104,9 @@ msgstr ""
msgid "Retry"
msgstr ""
+msgid "Retry failed jobs"
+msgstr ""
+
msgid "Retry job"
msgstr ""
@@ -30497,9 +31153,6 @@ msgstr ""
msgid "Review changes"
msgstr ""
-msgid "Review requested from %{name}"
-msgstr ""
-
msgid "Review requests for you"
msgstr ""
@@ -30663,6 +31316,9 @@ msgstr ""
msgid "Runners|Assigned Group"
msgstr ""
+msgid "Runners|Assigned Projects (%{projectCount})"
+msgstr ""
+
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30732,6 +31388,9 @@ msgstr ""
msgid "Runners|Instance"
msgstr ""
+msgid "Runners|Jobs"
+msgstr ""
+
msgid "Runners|Last contact"
msgstr ""
@@ -30825,9 +31484,6 @@ msgstr ""
msgid "Runners|Runner %{name} was deleted"
msgstr ""
-msgid "Runners|Runner ID"
-msgstr ""
-
msgid "Runners|Runner assigned to project."
msgstr ""
@@ -30975,6 +31631,9 @@ msgstr ""
msgid "Runners|stale"
msgstr ""
+msgid "Runner|This runner has not run any jobs."
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -31089,6 +31748,24 @@ msgstr ""
msgid "Saving project."
msgstr ""
+msgid "ScanResultPolicy|%{ifLabelStart}if%{ifLabelEnd} %{scanners} scan in an open merge request targeting the %{branches} branch(es) finds %{vulnerabilitiesAllowed} or more %{severities} vulnerabilities that are %{vulnerabilityStates}"
+msgstr ""
+
+msgid "ScanResultPolicy|%{thenLabelStart}Then%{thenLabelEnd} Require approval from %{approvalsRequired} of the following approvers: %{approvers}"
+msgstr ""
+
+msgid "ScanResultPolicy|add an approver"
+msgstr ""
+
+msgid "ScanResultPolicy|scanners"
+msgstr ""
+
+msgid "ScanResultPolicy|severity levels"
+msgstr ""
+
+msgid "ScanResultPolicy|vulnerability states"
+msgstr ""
+
msgid "Scanner"
msgstr ""
@@ -31221,6 +31898,9 @@ msgstr ""
msgid "Search for a user"
msgstr ""
+msgid "Search for an emoji"
+msgstr ""
+
msgid "Search for projects, issues, etc."
msgstr ""
@@ -31397,18 +32077,12 @@ msgstr ""
msgid "Secret Detection"
msgstr ""
-msgid "Secret access key"
-msgstr ""
-
msgid "Secret token"
msgstr ""
msgid "Secure token that identifies an external storage request."
msgstr ""
-msgid "SecureCodeWarrior"
-msgstr ""
-
msgid "Security"
msgstr ""
@@ -31433,9 +32107,6 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "Security training with guide and learning pathways."
-msgstr ""
-
msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
@@ -31538,7 +32209,7 @@ msgstr ""
msgid "SecurityConfiguration|Manage corpus"
msgstr ""
-msgid "SecurityConfiguration|Manage corpus files used as mutation sources in coverage fuzzing."
+msgid "SecurityConfiguration|Manage corpus files used as seed inputs with coverage-guided fuzzing."
msgstr ""
msgid "SecurityConfiguration|Manage profiles for use by DAST scans."
@@ -31604,15 +32275,15 @@ msgstr ""
msgid "SecurityOrchestration|.yaml preview"
msgstr ""
-msgid "SecurityOrchestration|Action"
-msgstr ""
-
msgid "SecurityOrchestration|Actions"
msgstr ""
msgid "SecurityOrchestration|Add rule"
msgstr ""
+msgid "SecurityOrchestration|After dismissing the alert, the information will never be shown again."
+msgstr ""
+
msgid "SecurityOrchestration|All policies"
msgstr ""
@@ -31628,7 +32299,7 @@ msgstr ""
msgid "SecurityOrchestration|Description"
msgstr ""
-msgid "SecurityOrchestration|Disabled"
+msgid "SecurityOrchestration|Don't show the alert anymore"
msgstr ""
msgid "SecurityOrchestration|Edit policy"
@@ -31637,13 +32308,13 @@ msgstr ""
msgid "SecurityOrchestration|Edit policy project"
msgstr ""
-msgid "SecurityOrchestration|Enabled"
+msgid "SecurityOrchestration|Empty policy name"
msgstr ""
-msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Enabled"
msgstr ""
-msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
msgstr ""
msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
@@ -31652,7 +32323,7 @@ msgstr ""
msgid "SecurityOrchestration|Invalid policy type"
msgstr ""
-msgid "SecurityOrchestration|Latest scan"
+msgid "SecurityOrchestration|Latest scan run against %{agent}"
msgstr ""
msgid "SecurityOrchestration|Network"
@@ -31661,15 +32332,27 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No actions defined - policy will not run."
+msgstr ""
+
+msgid "SecurityOrchestration|No description"
+msgstr ""
+
msgid "SecurityOrchestration|No rules defined - policy will not run."
msgstr ""
+msgid "SecurityOrchestration|Not enabled"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
msgid "SecurityOrchestration|Policies"
msgstr ""
+msgid "SecurityOrchestration|Policy Type"
+msgstr ""
+
msgid "SecurityOrchestration|Policy cannot be enabled for non-existing branches (%{branches})"
msgstr ""
@@ -31694,10 +32377,13 @@ msgstr ""
msgid "SecurityOrchestration|Require %{approvals} %{plural} from %{approvers} if any of the following occur:"
msgstr ""
-msgid "SecurityOrchestration|Rule"
+msgid "SecurityOrchestration|Rules"
msgstr ""
-msgid "SecurityOrchestration|Rules"
+msgid "SecurityOrchestration|Runs %{actions} and %{lastAction} scans"
+msgstr ""
+
+msgid "SecurityOrchestration|Runs a %{action} scan"
msgstr ""
msgid "SecurityOrchestration|Scan Execution"
@@ -31757,6 +32443,9 @@ msgstr ""
msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
+msgid "SecurityOrchestration|This view only shows scan results for the agent %{agent}. You can view scan results for all agents in the %{linkStart}Operational Vulnerabilities tab of the vulnerability report%{linkEnd}."
+msgstr ""
+
msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
@@ -31811,9 +32500,6 @@ msgstr ""
msgid "SecurityOrchestration|users with ids"
msgstr ""
-msgid "SecurityOrchestration|view results"
-msgstr ""
-
msgid "SecurityOrchestration|vulnerabilities"
msgstr ""
@@ -32483,22 +33169,19 @@ 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|In order to start using functions as a service, you must first install Knative on your Kubernetes cluster. %{linkStart}More information%{linkEnd}"
-msgstr ""
-
msgid "Serverless|Learn more about Serverless"
msgstr ""
msgid "Serverless|No functions available"
msgstr ""
-msgid "Serverless|Sign up for First Look"
+msgid "Serverless|Serverless was %{linkStart}deprecated%{linkEnd} in GitLab 14.3."
+msgstr ""
+
+msgid "Serverless|Serverless was %{postLinkStart}deprecated%{postLinkEnd}. But if you opt to use it, you must install Knative in your Kubernetes cluster first. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "Serverless|The deploy job has not finished."
@@ -32510,9 +33193,6 @@ 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 ""
@@ -32528,9 +33208,6 @@ msgstr ""
msgid "Service Account Key"
msgstr ""
-msgid "Service Accounts"
-msgstr ""
-
msgid "Service Accounts keys authorize GitLab to deploy your Google Cloud project"
msgstr ""
@@ -32540,10 +33217,10 @@ msgstr ""
msgid "Service Desk allows people to create issues in your GitLab instance without their own user account. It provides a unique email address for end users to create issues in a project. Replies can be sent either through the GitLab interface or by email. End users only see threads through email."
msgstr ""
-msgid "Service Usage Data"
+msgid "Service account generated successfully"
msgstr ""
-msgid "Service account generated successfully"
+msgid "Service accounts"
msgstr ""
msgid "Service ping is disabled in your configuration file, and cannot be enabled through this form."
@@ -32687,6 +33364,9 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
+msgid "Set the per-user rate limit for getting a user by ID via the API."
+msgstr ""
+
msgid "Set the per-user rate limit for notes created by web or API requests."
msgstr ""
@@ -32865,6 +33545,9 @@ msgstr ""
msgid "Shared runners details"
msgstr ""
+msgid "Shared runners enabled cannot be enabled until a valid credit card is on file"
+msgstr ""
+
msgid "Shared runners help link"
msgstr ""
@@ -32922,6 +33605,9 @@ msgstr ""
msgid "Show all issues."
msgstr ""
+msgid "Show all milestones"
+msgstr ""
+
msgid "Show all test cases."
msgstr ""
@@ -32958,6 +33644,9 @@ msgstr ""
msgid "Show file contents"
msgstr ""
+msgid "Show group milestones"
+msgstr ""
+
msgid "Show labels"
msgstr ""
@@ -32973,6 +33662,12 @@ msgstr ""
msgid "Show open epics"
msgstr ""
+msgid "Show project milestones"
+msgstr ""
+
+msgid "Show sub-group milestones"
+msgstr ""
+
msgid "Show the Closed list"
msgstr ""
@@ -32982,10 +33677,6 @@ msgstr ""
msgid "Show whitespace changes"
msgstr ""
-msgid "Showing %d event"
-msgid_plural "Showing %d events"
-msgstr[0] ""
-
msgid "Showing %{conflict} between %{sourceBranch} and %{targetBranch}"
msgstr ""
@@ -33044,12 +33735,6 @@ msgstr ""
msgid "Sidebar|None"
msgstr ""
-msgid "Sidebar|Only numeral characters allowed"
-msgstr ""
-
-msgid "Sidebar|Weight"
-msgstr ""
-
msgid "Sidekiq job compression threshold (bytes)"
msgstr ""
@@ -33212,6 +33897,9 @@ msgstr ""
msgid "Slack logo"
msgstr ""
+msgid "SlackIntegration|Are you sure you want to remove this project from the Slack application?"
+msgstr ""
+
msgid "SlackIntegration|GitLab for Slack"
msgstr ""
@@ -33221,6 +33909,9 @@ msgstr ""
msgid "SlackIntegration|Project alias"
msgstr ""
+msgid "SlackIntegration|Remove project"
+msgstr ""
+
msgid "SlackIntegration|Select a GitLab project to link with your Slack workspace."
msgstr ""
@@ -33365,9 +34056,6 @@ msgstr ""
msgid "Something went wrong trying to load issue contacts."
msgstr ""
-msgid "Something went wrong when creating a work item. Please try again"
-msgstr ""
-
msgid "Something went wrong when reordering designs. Please try again"
msgstr ""
@@ -33461,9 +34149,6 @@ msgstr ""
msgid "Something went wrong while inserting your image. Please try again."
msgstr ""
-msgid "Something went wrong while merging this merge request. Please try again."
-msgstr ""
-
msgid "Something went wrong while obtaining the Let's Encrypt certificate."
msgstr ""
@@ -33785,10 +34470,10 @@ 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."
+msgid "SourcegraphAdmin|Learn more."
msgstr ""
-msgid "SourcegraphAdmin|More information"
+msgid "SourcegraphAdmin|Only public projects have code intelligence enabled and communicate with Sourcegraph."
msgstr ""
msgid "SourcegraphAdmin|Save changes"
@@ -33797,7 +34482,7 @@ msgstr ""
msgid "SourcegraphAdmin|Sourcegraph URL"
msgstr ""
-msgid "SourcegraphAdmin|e.g. https://sourcegraph.example.com"
+msgid "SourcegraphAdmin|https://sourcegraph.example.com"
msgstr ""
msgid "SourcegraphPreferences|This feature is experimental and currently limited to certain projects."
@@ -33932,6 +34617,9 @@ msgstr ""
msgid "Start date"
msgstr ""
+msgid "Start free trial"
+msgstr ""
+
msgid "Start merge train"
msgstr ""
@@ -33962,6 +34650,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started escalation for this incident."
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -33974,6 +34665,9 @@ msgstr ""
msgid "Starts at (UTC)"
msgstr ""
+msgid "Starts escalations for this incident"
+msgstr ""
+
msgid "Starts on"
msgstr ""
@@ -34235,6 +34929,9 @@ msgstr ""
msgid "Strikethrough"
msgstr ""
+msgid "Strikethrough text"
+msgstr ""
+
msgid "Subgroup information"
msgstr ""
@@ -34469,6 +35166,21 @@ msgstr ""
msgid "Subscriptions"
msgstr ""
+msgid "Subscriptions|Chat with sales"
+msgstr ""
+
+msgid "Subscriptions|Close"
+msgstr ""
+
+msgid "Subscriptions|Not ready to buy yet?"
+msgstr ""
+
+msgid "Subscriptions|Start a free trial"
+msgstr ""
+
+msgid "Subscriptions|We understand. Maybe you have some questions for our sales team, or maybe you'd like to try some of the paid features first. What would you like to do?"
+msgstr ""
+
msgid "Subscription|Your subscription for %{strong}%{namespace_name}%{strong_close} has expired and you are now on %{pricing_link_start}the GitLab Free tier%{pricing_link_end}. Don't worry, your data is safe. Get in touch with our support team (%{support_email}). They'll gladly help with your subscription renewal."
msgstr ""
@@ -34679,6 +35391,9 @@ msgstr ""
msgid "SuperSonics|Maximum users"
msgstr ""
+msgid "SuperSonics|Offline cloud"
+msgstr ""
+
msgid "SuperSonics|Paste your activation code"
msgstr ""
@@ -34745,6 +35460,12 @@ msgstr ""
msgid "SuperSonics|You do not have an active subscription"
msgstr ""
+msgid "SuperSonics|You have a future dated license"
+msgstr ""
+
+msgid "SuperSonics|You have added a license that activates on %{date}. Please see the subscription history table below for more details."
+msgstr ""
+
msgid "SuperSonics|You have successfully added a license that activates on %{date}. Please see the subscription history table below for more details."
msgstr ""
@@ -34904,6 +35625,9 @@ msgstr ""
msgid "Tag name is required"
msgstr ""
+msgid "Tag push"
+msgstr ""
+
msgid "Tag push events"
msgstr ""
@@ -35006,6 +35730,9 @@ msgstr ""
msgid "TagsPage|protected"
msgstr ""
+msgid "Take a look at the documentation to discover all of GitLab’s capabilities."
+msgstr ""
+
msgid "Target Branch"
msgstr ""
@@ -35402,6 +36129,9 @@ msgstr ""
msgid "Tests"
msgstr ""
+msgid "Text (optional)"
+msgstr ""
+
msgid "Text added to the body of all email messages. %{character_limit} character limit"
msgstr ""
@@ -35451,6 +36181,9 @@ msgstr ""
msgid "The CSV export will be created in the background. Once finished, it will be sent to %{email} in an attachment."
msgstr ""
+msgid "The CSV export you requested of all user memberships is attached to this email."
+msgstr ""
+
msgid "The GitLab subscription service (customers.gitlab.com) is currently experiencing an outage. You can monitor the status and get updates at %{linkStart}status.gitlab.com%{linkEnd}."
msgstr ""
@@ -35526,6 +36259,9 @@ 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 epic"
+msgstr ""
+
msgid "The current issue"
msgstr ""
@@ -35686,6 +36422,9 @@ msgstr ""
msgid "The latest pipeline for this merge request has failed."
msgstr ""
+msgid "The license key is invalid."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -35701,6 +36440,9 @@ msgstr ""
msgid "The license was successfully uploaded and will be active from %{starts_at}. You can see the details below."
msgstr ""
+msgid "The license you uploaded is invalid. If the issue persists, contact support at %{link}."
+msgstr ""
+
msgid "The list creation wizard is already open"
msgstr ""
@@ -36322,10 +37064,13 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} and everything this project contains. %{strongOpen}There is no going back%{strongClose}"
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}on %{date}%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains."
+msgstr ""
+
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains. %{strongOpen}There is no going back.%{strongClose}"
msgstr ""
msgid "This action will %{strongOpen}permanently remove%{strongClose} %{codeOpen}%{group}%{codeClose} %{strongOpen}immediately%{strongClose}."
@@ -36454,9 +37199,6 @@ msgstr ""
msgid "This file was modified for readability, and can't accept suggestions. Edit it directly."
msgstr ""
-msgid "This forked project has the following:"
-msgstr ""
-
msgid "This form is disabled in preview"
msgstr ""
@@ -36469,7 +37211,7 @@ msgstr ""
msgid "This group can't be removed because it is linked to a subscription. To remove this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
-msgid "This group can't be transfered because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
+msgid "This group can't be transferred because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
msgid "This group cannot be invited to a project inside a group with enforced SSO"
@@ -36496,6 +37238,9 @@ 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 incident is already escalated with '%{escalation_policy_name}'."
+msgstr ""
+
msgid "This invitation was sent to %{mail_to_invite_email}, but you are signed in as %{link_to_current_user} with email %{mail_to_current_user}."
msgstr ""
@@ -36514,9 +37259,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 merge train pipeline"
-msgstr ""
-
msgid "This is a private email address %{helpIcon} generated just for you. Anyone who has it can create issues or merge requests as if they were you. If that happens, %{resetLinkStart}reset this token%{resetLinkEnd}."
msgstr ""
@@ -36538,6 +37280,12 @@ msgstr ""
msgid "This is your current session"
msgstr ""
+msgid "This issue cannot be assigned to a confidential epic because it is public."
+msgstr ""
+
+msgid "This issue cannot be made public because it belongs to a confidential epic."
+msgstr ""
+
msgid "This issue is confidential and should only be visible to team members with at least Reporter access."
msgstr ""
@@ -36655,6 +37403,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 branch is protected from force push."
+msgstr ""
+
msgid "This merge request cannot be rebased while there are conflicts."
msgstr ""
@@ -36706,9 +37457,15 @@ msgstr ""
msgid "This pipeline was triggered by a schedule."
msgstr ""
+msgid "This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project"
msgstr ""
+msgid "This project can be restored until %{date}."
+msgstr ""
+
msgid "This project cannot be %{visibilityLevel} because the visibility of %{openShowLink}%{name}%{closeShowLink} is %{visibility}. To make this project %{visibilityLevel}, you must first %{openEditLink}change the visibility%{closeEditLink} of the parent group."
msgstr ""
@@ -36727,6 +37484,9 @@ msgstr ""
msgid "This project is %{strongStart}NOT%{strongEnd} a fork, and has the following:"
msgstr ""
+msgid "This project is %{strongStart}NOT%{strongEnd} a fork. This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -37416,6 +38176,9 @@ msgstr ""
msgid "Today"
msgstr ""
+msgid "Todos count"
+msgstr ""
+
msgid "Todos|Are you looking for things to do? Take a look at %{strongStart}%{openIssuesLinkStart}open issues%{openIssuesLinkEnd}%{strongEnd}, contribute to %{strongStart}%{mergeRequestLinkStart}a merge request%{mergeRequestLinkEnd}%{mergeRequestLinkEnd}%{strongEnd}, or mention someone in a comment to automatically assign them a new to-do item."
msgstr ""
@@ -37689,9 +38452,8 @@ msgstr ""
msgid "Trending"
msgstr ""
-msgid "Trials|%{planName} Trial %{enDash} %{num} day left"
-msgid_plural "Trials|%{planName} Trial %{enDash} %{num} days left"
-msgstr[0] ""
+msgid "Trials|%{planName} Trial"
+msgstr ""
msgid "Trials|Compare all plans"
msgstr ""
@@ -37699,6 +38461,9 @@ msgstr ""
msgid "Trials|Create a new group to start your GitLab Ultimate trial."
msgstr ""
+msgid "Trials|Day %{daysUsed}/%{duration}"
+msgstr ""
+
msgid "Trials|Go back to GitLab"
msgstr ""
@@ -37948,7 +38713,7 @@ msgstr ""
msgid "URL is triggered when repository is updated"
msgstr ""
-msgid "URL must be percent-encoded if neccessary."
+msgid "URL must be percent-encoded if necessary."
msgstr ""
msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
@@ -38167,6 +38932,9 @@ msgstr ""
msgid "Unlock account"
msgstr ""
+msgid "Unlock more features with GitLab Ultimate"
+msgstr ""
+
msgid "Unlock the discussion"
msgstr ""
@@ -38230,6 +38998,9 @@ msgstr ""
msgid "Unsubscribes from this %{quick_action_target}."
msgstr ""
+msgid "Unsupported sort value."
+msgstr ""
+
msgid "Unsupported todo type passed. Supported todo types are: %{todo_types}"
msgstr ""
@@ -38458,6 +39229,9 @@ msgstr ""
msgid "UsageQuota|File attachments and smaller design graphics."
msgstr ""
+msgid "UsageQuota|From %{storage_enforcement_date} storage limits will apply to this namespace. View and manage your usage in %{strong_start}Group Settings &gt; Usage quotas%{strong_end}."
+msgstr ""
+
msgid "UsageQuota|Git repository."
msgstr ""
@@ -38518,6 +39292,9 @@ msgstr ""
msgid "UsageQuota|Storage type"
msgstr ""
+msgid "UsageQuota|Storage used"
+msgstr ""
+
msgid "UsageQuota|This is the total amount of storage used across your projects within this namespace."
msgstr ""
@@ -38713,6 +39490,12 @@ msgstr ""
msgid "Use hashed storage paths for newly created and renamed repositories. Always enabled since 13.0."
msgstr ""
+msgid "Use issue count"
+msgstr ""
+
+msgid "Use issue weight"
+msgstr ""
+
msgid "Use one line per URI"
msgstr ""
@@ -39094,6 +39877,9 @@ msgstr ""
msgid "Users"
msgstr ""
+msgid "Users API rate limit"
+msgstr ""
+
msgid "Users can launch a development environment from a GitLab browser tab when the %{linkStart}Gitpod%{linkEnd} integration is enabled."
msgstr ""
@@ -39417,6 +40203,9 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View group pipeline usage quota"
+msgstr ""
+
msgid "View incident details at"
msgstr ""
@@ -39568,6 +40357,9 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
+msgid "Vulnerability"
+msgstr ""
+
msgid "Vulnerability Report"
msgstr ""
@@ -39619,6 +40411,9 @@ msgstr ""
msgid "VulnerabilityManagement|An unverified non-confirmed finding"
msgstr ""
+msgid "VulnerabilityManagement|At least one identifier is required"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -39628,12 +40423,24 @@ msgstr ""
msgid "VulnerabilityManagement|Create Jira issue"
msgstr ""
+msgid "VulnerabilityManagement|Enter a name"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE code"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE identifier URL"
+msgstr ""
+
msgid "VulnerabilityManagement|Fetching linked Jira issues"
msgstr ""
msgid "VulnerabilityManagement|Manually add a vulnerability entry into the vulnerability report."
msgstr ""
+msgid "VulnerabilityManagement|Name is a required field"
+msgstr ""
+
msgid "VulnerabilityManagement|Needs triage"
msgstr ""
@@ -39649,6 +40456,18 @@ msgstr ""
msgid "VulnerabilityManagement|Select a method"
msgstr ""
+msgid "VulnerabilityManagement|Select a severity level"
+msgstr ""
+
+msgid "VulnerabilityManagement|Select a status"
+msgstr ""
+
+msgid "VulnerabilityManagement|Severity is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Something went wrong while creating vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -39673,6 +40492,12 @@ msgstr ""
msgid "VulnerabilityManagement|Something went wrong, could not update vulnerability state."
msgstr ""
+msgid "VulnerabilityManagement|Status is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Submit vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Summary, detailed description, steps to reproduce, etc."
msgstr ""
@@ -39868,6 +40693,9 @@ msgstr ""
msgid "WARNING:"
msgstr ""
+msgid "WARNING: This snippet contains hidden files which might be used to mask malicious behavior. Exercise caution if cloning and executing code from this snippet."
+msgstr ""
+
msgid "Wait for the file to load to copy its contents"
msgstr ""
@@ -40087,6 +40915,15 @@ msgstr ""
msgid "Webhooks|An issue is created, updated, closed, or reopened."
msgstr ""
+msgid "Webhooks|Are you sure you want to delete this group hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this project hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this webhook?"
+msgstr ""
+
msgid "Webhooks|Comments"
msgstr ""
@@ -40096,6 +40933,9 @@ msgstr ""
msgid "Webhooks|Confidential issues events"
msgstr ""
+msgid "Webhooks|Delete webhook"
+msgstr ""
+
msgid "Webhooks|Deployment events"
msgstr ""
@@ -40328,6 +41168,9 @@ msgstr ""
msgid "Wiki"
msgstr ""
+msgid "Wiki page"
+msgstr ""
+
msgid "Wiki page was successfully created."
msgstr ""
@@ -40433,7 +41276,7 @@ msgstr ""
msgid "WikiPageConflictMessage|Someone edited the page the same time you did. Please check out %{wikiLinkStart}the page%{wikiLinkEnd} and make sure your changes will not unintentionally remove theirs."
msgstr ""
-msgid "WikiPage|An error occured while trying to render the content editor. Please try again later."
+msgid "WikiPage|An error occurred while trying to render the content editor. Please try again later."
msgstr ""
msgid "WikiPage|Are you sure you want to switch back to the classic editor?"
@@ -40592,6 +41435,18 @@ msgstr ""
msgid "WorkItem|New Task"
msgstr ""
+msgid "WorkItem|Something went wrong when creating a work item. Please try again"
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching the work item. Please try again."
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching work item types. Please try again"
+msgstr ""
+
+msgid "WorkItem|Type"
+msgstr ""
+
msgid "WorkItem|Work Items"
msgstr ""
@@ -40658,7 +41513,10 @@ msgstr ""
msgid "You are about to add %{usersTag} people to the discussion. They will all receive a notification."
msgstr ""
-msgid "You are about to permanently delete this project"
+msgid "You are about to delete this forked project containing:"
+msgstr ""
+
+msgid "You are about to delete this project containing:"
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."
@@ -40679,6 +41537,9 @@ msgstr ""
msgid "You are attempting to update a file that has changed since you started editing it."
msgstr ""
+msgid "You are billed if you exceed this number. %{qsrOverageLinkStart}How does billing work?%{qsrOverageLinkEnd}"
+msgstr ""
+
msgid "You are connected to the Prometheus server, but there is currently no data to display."
msgstr ""
@@ -40736,6 +41597,9 @@ msgstr ""
msgid "You are not authorized to update this scanner profile"
msgstr ""
+msgid "You are not authorized to upload metric images"
+msgstr ""
+
msgid "You are now impersonating %{username}"
msgstr ""
@@ -40889,9 +41753,6 @@ msgstr ""
msgid "You can only upload one design when dropping onto an existing design."
msgstr ""
-msgid "You can recover this project until %{date}"
-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 ""
@@ -40940,9 +41801,6 @@ msgstr ""
msgid "You cannot write to this read-only GitLab instance."
msgstr ""
-msgid "You can’t %{tag_start}edit%{tag_end} files directly in this project. Fork this project and submit a merge request with your changes."
-msgstr ""
-
msgid "You can’t edit files directly in this project. Fork this project and submit a merge request with your changes."
msgstr ""
@@ -41094,9 +41952,6 @@ 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 set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
@@ -41127,12 +41982,6 @@ msgstr ""
msgid "You must have maintainer access to force delete a lock"
msgstr ""
-msgid "You must have permission to create a project in a group before forking."
-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 ""
@@ -41538,7 +42387,7 @@ msgstr ""
msgid "Your public email will be displayed on your public profile."
msgstr ""
-msgid "Your request for access could not be processed: %{error_meesage}"
+msgid "Your request for access could not be processed: %{error_message}"
msgstr ""
msgid "Your request for access has been queued for review."
@@ -41718,6 +42567,9 @@ msgstr ""
msgid "archived:"
msgstr ""
+msgid "artifacts"
+msgstr ""
+
msgid "assign yourself"
msgstr ""
@@ -41746,6 +42598,9 @@ msgstr[0] ""
msgid "branch name"
msgstr ""
+msgid "builds"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -42166,6 +43021,9 @@ msgstr ""
msgid "contact with same email already exists in group hierarchy"
msgstr ""
+msgid "container registry images"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -42205,6 +43063,9 @@ msgstr ""
msgid "data"
msgstr ""
+msgid "database"
+msgstr ""
+
msgid "date must not be after 9999-12-31"
msgstr ""
@@ -42227,9 +43088,6 @@ msgstr ""
msgid "design"
msgstr ""
-msgid "detached"
-msgstr ""
-
msgid "disabled"
msgstr ""
@@ -42474,7 +43332,7 @@ msgstr ""
msgid "is not a valid X509 certificate."
msgstr ""
-msgid "is not allowed for sign-up."
+msgid "is not allowed for sign-up. Please use your regular email address."
msgstr ""
msgid "is not allowed for this group."
@@ -42486,7 +43344,7 @@ msgstr ""
msgid "is not allowed since the group is not top-level group."
msgstr ""
-msgid "is not allowed."
+msgid "is not allowed. Please use your regular email address."
msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
@@ -42573,6 +43431,9 @@ msgstr ""
msgid "level: %{level}"
msgstr ""
+msgid "lfs objects"
+msgstr ""
+
msgid "limit of %{project_limit} reached"
msgstr ""
@@ -42789,6 +43650,9 @@ msgstr ""
msgid "mrWidget|Merge blocked: pipeline must succeed. It's waiting for a manual action to continue."
msgstr ""
+msgid "mrWidget|Merge blocked: pipeline must succeed. Push a commit that fixes the failure, or %{linkStart}learn about other solutions.%{linkEnd}"
+msgstr ""
+
msgid "mrWidget|Merge blocked: this merge request must be approved."
msgstr ""
@@ -42906,9 +43770,6 @@ msgstr ""
msgid "mrWidget|The changes were not merged into"
msgstr ""
-msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -43056,9 +43917,6 @@ msgstr ""
msgid "open issue"
msgstr ""
-msgid "opened %{timeAgo}"
-msgstr ""
-
msgid "or"
msgstr ""
@@ -43069,6 +43927,12 @@ msgid "out of %d total test"
msgid_plural "out of %d total tests"
msgstr[0] ""
+msgid "packages"
+msgstr ""
+
+msgid "pages"
+msgstr ""
+
msgid "parent"
msgid_plural "parents"
msgstr[0] ""
@@ -43214,6 +44078,9 @@ msgid "reply"
msgid_plural "replies"
msgstr[0] ""
+msgid "repositories"
+msgstr ""
+
msgid "repository:"
msgstr ""
@@ -43334,12 +44201,18 @@ msgstr ""
msgid "tag name"
msgstr ""
+msgid "terraform states"
+msgstr ""
+
msgid "the correct format."
msgstr ""
msgid "the file"
msgstr ""
+msgid "the following epic(s)"
+msgstr ""
+
msgid "the following issue(s)"
msgstr ""
@@ -43352,21 +44225,12 @@ msgstr ""
msgid "this document"
msgstr ""
-msgid "this issue cannot be assigned to a confidential epic since it is public"
-msgstr ""
-
-msgid "this issue cannot be made public since it belongs to a confidential epic"
-msgstr ""
-
msgid "time summary"
msgstr ""
msgid "toggle collapse"
msgstr ""
-msgid "train"
-msgstr ""
-
msgid "triggered"
msgstr ""
@@ -43494,3 +44358,6 @@ msgstr ""
msgid "{project}"
msgstr ""
+msgid "✔"
+msgstr ""
+
diff --git a/locale/ig_NG/gitlab.po b/locale/ig_NG/gitlab.po
index 119c3833bc0..7113067d3aa 100644
--- a/locale/ig_NG/gitlab.po
+++ b/locale/ig_NG/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: ig\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2022-02-02 15:47\n"
+"PO-Revision-Date: 2022-03-01 20:40\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -132,6 +132,10 @@ msgid "%d approver (you've approved)"
msgid_plural "%d approvers (you've approved)"
msgstr[0] ""
+msgid "%d assigned issue"
+msgid_plural "%d assigned issues"
+msgstr[0] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -352,8 +356,20 @@ msgid "%d vulnerability dismissed"
msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
-msgid "%d vulnerability updated"
-msgid_plural "%d vulnerabilities updated"
+msgid "%d vulnerability set to confirmed"
+msgid_plural "%d vulnerabilities set to confirmed"
+msgstr[0] ""
+
+msgid "%d vulnerability set to dismissed"
+msgid_plural "%d vulnerabilities set to dismissed"
+msgstr[0] ""
+
+msgid "%d vulnerability set to needs triage"
+msgid_plural "%d vulnerabilities set to needs triage"
+msgstr[0] ""
+
+msgid "%d vulnerability set to resolved"
+msgid_plural "%d vulnerabilities set to resolved"
msgstr[0] ""
msgid "%d warning found:"
@@ -434,6 +450,12 @@ msgstr[0] ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{completed} of %{total} issues closed"
+msgstr ""
+
+msgid "%{completed} of %{total} weight completed"
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -776,6 +798,9 @@ msgstr ""
msgid "%{openedIssues} open, %{closedIssues} closed"
msgstr ""
+msgid "%{percentage}%% issues closed"
+msgstr ""
+
msgid "%{percentage}%% weight completed"
msgstr ""
@@ -1190,6 +1215,9 @@ msgid "- User"
msgid_plural "- Users"
msgstr[0] ""
+msgid "- of - issues closed"
+msgstr ""
+
msgid "- of - weight completed"
msgstr ""
@@ -1309,7 +1337,7 @@ msgstr ""
msgid "1000+"
msgstr ""
-msgid "192.168.0.0/24"
+msgid "192.168.0.0/24 or 2001:0DB8:1234::/48"
msgstr ""
msgid "1st contribution!"
@@ -1621,13 +1649,13 @@ msgstr ""
msgid "AWS Access Key"
msgstr ""
-msgid "AWS Access Key. Only required if not using role instance credentials"
+msgid "AWS Secret Access Key"
msgstr ""
-msgid "AWS Secret Access Key"
+msgid "AWS access key ID (Optional)"
msgstr ""
-msgid "AWS Secret Access Key. Only required if not using role instance credentials"
+msgid "AWS secret access key (Optional)"
msgstr ""
msgid "AWS service error: %{error}"
@@ -1687,9 +1715,6 @@ msgstr ""
msgid "Access granted"
msgstr ""
-msgid "Access key ID"
-msgstr ""
-
msgid "Access requests"
msgstr ""
@@ -1864,7 +1889,7 @@ msgstr ""
msgid "Activity"
msgstr ""
-msgid "Activity|An error occured while retrieving activity. Reload the page to try again."
+msgid "Activity|An error occurred while retrieving activity. Reload the page to try again."
msgstr ""
msgid "Add"
@@ -1903,6 +1928,9 @@ msgstr ""
msgid "Add a %{type}"
msgstr ""
+msgid "Add a GCP region"
+msgstr ""
+
msgid "Add a GPG key"
msgstr ""
@@ -1954,6 +1982,9 @@ msgstr ""
msgid "Add a numbered list"
msgstr ""
+msgid "Add a related epic"
+msgstr ""
+
msgid "Add a related issue"
msgstr ""
@@ -2068,6 +2099,9 @@ msgstr ""
msgid "Add or subtract spent time"
msgstr ""
+msgid "Add people"
+msgstr ""
+
msgid "Add previously merged commits"
msgstr ""
@@ -2134,6 +2168,9 @@ msgstr ""
msgid "Add webhook"
msgstr ""
+msgid "Add your team members and others to GitLab."
+msgstr ""
+
msgid "Add/remove"
msgstr ""
@@ -2956,12 +2993,6 @@ msgstr ""
msgid "AdvancedSearch|Reindex required"
msgstr ""
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. Permanently deleting this project will %{strongStart}immediately delete%{strongEnd} its repositories and %{strongStart}all related resources%{strongEnd}, including issues, merge requests etc."
-msgstr ""
-
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. You will lose this project's repository and %{strongStart}all related resources%{strongEnd}, including issues and merge requests."
-msgstr ""
-
msgid "After a successful password update you will be redirected to login screen."
msgstr ""
@@ -2992,6 +3023,9 @@ msgstr ""
msgid "Akismet helps prevent the creation of spam issues in public projects."
msgstr ""
+msgid "Alert"
+msgstr ""
+
msgid "AlertManagement|Acknowledged"
msgstr ""
@@ -3364,9 +3398,6 @@ msgstr ""
msgid "All environments"
msgstr ""
-msgid "All epics"
-msgstr ""
-
msgid "All groups and projects"
msgstr ""
@@ -4101,11 +4132,14 @@ msgstr ""
msgid "ApplicationSettings|Approve users in the pending approval status?"
msgstr ""
-msgid "ApplicationSettings|By making this change, you will automatically approve %d user with the pending approval status."
-msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users with the pending approval status."
+msgid "ApplicationSettings|Approve users who are pending approval?"
+msgstr ""
+
+msgid "ApplicationSettings|By making this change, you will automatically approve %d user who is pending approval."
+msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users who are pending approval."
msgstr[0] ""
-msgid "ApplicationSettings|By making this change, you will automatically approve all users in pending approval status."
+msgid "ApplicationSettings|By making this change, you will automatically approve all users who are pending approval."
msgstr ""
msgid "ApplicationSettings|Denied domains for sign-ups"
@@ -4506,10 +4540,10 @@ msgstr ""
msgid "Archiving the project will make it entirely read-only. It is hidden from the dashboard and doesn't show up in searches. %{strong_start}The repository cannot be committed to, and no issues, comments, or other entities can be created.%{strong_end} %{link_start}Learn more.%{link_end}"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to delete this project?"
+msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
+msgid "Are you absolutely sure?"
msgstr ""
msgid "Are you sure that you want to archive this project?"
@@ -4545,12 +4579,18 @@ msgstr ""
msgid "Are you sure you want to delete this SSH key?"
msgstr ""
+msgid "Are you sure you want to delete this comment?"
+msgstr ""
+
msgid "Are you sure you want to delete this deploy key?"
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 label?"
+msgstr ""
+
msgid "Are you sure you want to delete this pipeline schedule?"
msgstr ""
@@ -4566,9 +4606,6 @@ msgstr ""
msgid "Are you sure you want to discard your changes?"
msgstr ""
-msgid "Are you sure you want to erase this build?"
-msgstr ""
-
msgid "Are you sure you want to import %d repository?"
msgid_plural "Are you sure you want to import %d repositories?"
msgstr[0] ""
@@ -4615,6 +4652,9 @@ msgstr ""
msgid "Are you sure you want to remove this list?"
msgstr ""
+msgid "Are you sure you want to remove this nickname?"
+msgstr ""
+
msgid "Are you sure you want to reset the health check token?"
msgstr ""
@@ -4627,10 +4667,10 @@ 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?"
+msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
msgstr ""
-msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
+msgid "Are you sure you want to revoke this project access token? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to stop this environment?"
@@ -4777,9 +4817,6 @@ msgstr ""
msgid "Assigned to %{assignee_name}"
msgstr ""
-msgid "Assigned to %{name}"
-msgstr ""
-
msgid "Assigned to me"
msgstr ""
@@ -4842,6 +4879,9 @@ msgstr[0] ""
msgid "Attaching the file failed."
msgstr ""
+msgid "Attention"
+msgstr ""
+
msgid "Audit Events"
msgstr ""
@@ -5004,6 +5044,12 @@ msgstr ""
msgid "Authorized applications (%{size})"
msgstr ""
+msgid "AuthorizedApplication|Are you sure you want to revoke this application?"
+msgstr ""
+
+msgid "AuthorizedApplication|Revoke application"
+msgstr ""
+
msgid "Authors: %{authors}"
msgstr ""
@@ -6193,6 +6239,9 @@ msgstr ""
msgid "CICDAnalytics|Shared Runners Usage"
msgstr ""
+msgid "CICDAnalytics|Shared runner pipeline minute duration by month"
+msgstr ""
+
msgid "CICDAnalytics|Shared runner usage"
msgstr ""
@@ -6334,6 +6383,9 @@ msgstr ""
msgid "Can create groups:"
msgstr ""
+msgid "Can not delete primary training"
+msgstr ""
+
msgid "Can't apply as the source branch was deleted."
msgstr ""
@@ -6667,9 +6719,6 @@ msgstr ""
msgid "Changing any setting here requires an application restart"
msgstr ""
-msgid "Changing group URL can have unintended side effects."
-msgstr ""
-
msgid "Charts can't be displayed as the request for data has timed out. %{documentationLink}"
msgstr ""
@@ -6757,9 +6806,6 @@ msgstr ""
msgid "Checking branch availability..."
msgstr ""
-msgid "Checking group URL availability..."
-msgstr ""
-
msgid "Checking group path availability..."
msgstr ""
@@ -7251,6 +7297,9 @@ msgstr ""
msgid "Clear recent searches"
msgstr ""
+msgid "Clear repository checks"
+msgstr ""
+
msgid "Clear search"
msgstr ""
@@ -7383,9 +7432,6 @@ msgstr ""
msgid "Closed MRs"
msgstr ""
-msgid "Closed epics"
-msgstr ""
-
msgid "Closed issues"
msgstr ""
@@ -7422,13 +7468,13 @@ msgstr ""
msgid "Cluster level"
msgstr ""
-msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
+msgid "Cluster type must be specified for Stages::ClusterEndpointInserter"
msgstr ""
msgid "ClusterAgents|%{name} successfully deleted"
msgstr ""
-msgid "ClusterAgents|%{number} of %{total} Agents"
+msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
@@ -7470,6 +7516,15 @@ msgstr ""
msgid "ClusterAgents|Agent never connected to GitLab"
msgstr ""
+msgid "ClusterAgents|Agent version mismatch"
+msgstr ""
+
+msgid "ClusterAgents|Agent version mismatch and update"
+msgstr ""
+
+msgid "ClusterAgents|Agent version update required"
+msgstr ""
+
msgid "ClusterAgents|All"
msgstr ""
@@ -7494,7 +7549,7 @@ msgstr ""
msgid "ClusterAgents|Configuration"
msgstr ""
-msgid "ClusterAgents|Connect a cluster through the Agent"
+msgid "ClusterAgents|Connect a cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connect existing cluster"
@@ -7503,13 +7558,13 @@ msgstr ""
msgid "ClusterAgents|Connect with a certificate"
msgstr ""
-msgid "ClusterAgents|Connect with agent"
+msgid "ClusterAgents|Connect with an agent"
msgstr ""
msgid "ClusterAgents|Connect with the GitLab Agent"
msgstr ""
-msgid "ClusterAgents|Connect your cluster through the Agent"
+msgid "ClusterAgents|Connect your cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connected"
@@ -7569,7 +7624,10 @@ msgstr ""
msgid "ClusterAgents|How to register an agent?"
msgstr ""
-msgid "ClusterAgents|Install new Agent"
+msgid "ClusterAgents|How to update an agent?"
+msgstr ""
+
+msgid "ClusterAgents|Install a new agent"
msgstr ""
msgid "ClusterAgents|Last connected %{timeAgo}."
@@ -7596,7 +7654,7 @@ msgstr ""
msgid "ClusterAgents|Never connected"
msgstr ""
-msgid "ClusterAgents|No Agents"
+msgid "ClusterAgents|No agents"
msgstr ""
msgid "ClusterAgents|No clusters connected through cluster certificates"
@@ -7656,6 +7714,9 @@ msgstr ""
msgid "ClusterAgents|The agent has not been connected in a long time. There might be a connectivity issue. Last contact was %{timeAgo}."
msgstr ""
+msgid "ClusterAgents|The agent version do not match each other across your cluster's pods. This can happen when a new agent version was just deployed and Kubernetes is shutting down the old pods."
+msgstr ""
+
msgid "ClusterAgents|The recommended installation method includes the token. If you want to follow the advanced installation method provided in the docs, make sure you save the token value before you close this window."
msgstr ""
@@ -7702,6 +7763,9 @@ msgstr ""
msgid "ClusterAgents|You will need to create a token to connect to your agent"
msgstr ""
+msgid "ClusterAgents|Your agent version is out of sync with your GitLab version (v%{version}), which might cause compatibility problems. Update the agent installed on your cluster to the most recent version."
+msgstr ""
+
msgid "ClusterAgents|Your instance doesn't have the %{linkStart}GitLab Agent Server (KAS)%{linkEnd} set up. Ask a GitLab Administrator to install it."
msgstr ""
@@ -8578,9 +8642,6 @@ msgstr ""
msgid "Comma-separated list of email addresses."
msgstr ""
-msgid "Comma-separated list of users allowed to exceed the rate limit."
-msgstr ""
-
msgid "Comma-separated, e.g. '1.1.1.1, 2.2.2.0/24'"
msgstr ""
@@ -8906,6 +8967,12 @@ msgstr ""
msgid "Confidential"
msgstr ""
+msgid "Confidential issue"
+msgstr ""
+
+msgid "Confidential note"
+msgstr ""
+
msgid "Confidentiality"
msgstr ""
@@ -8939,6 +9006,9 @@ msgstr ""
msgid "Configure Dependency Scanning in `.gitlab-ci.yml`, creating this file if it does not already exist"
msgstr ""
+msgid "Configure GitLab"
+msgstr ""
+
msgid "Configure GitLab runners to start using the Web Terminal. %{helpStart}Learn more.%{helpEnd}"
msgstr ""
@@ -8987,6 +9057,15 @@ msgstr ""
msgid "Configure pipelines to deploy web apps, backend services, APIs and static resources to Google Cloud"
msgstr ""
+msgid "Configure region"
+msgstr ""
+
+msgid "Configure region for environment"
+msgstr ""
+
+msgid "Configure regions"
+msgstr ""
+
msgid "Configure repository mirroring."
msgstr ""
@@ -9020,6 +9099,9 @@ msgstr ""
msgid "Configure which lists are shown for anyone who visits this board"
msgstr ""
+msgid "Configure your environments to be deployed to specific geographical regions"
+msgstr ""
+
msgid "Confirm"
msgstr ""
@@ -9719,10 +9801,10 @@ msgstr ""
msgid "CorpusManagement|Actions"
msgstr ""
-msgid "CorpusManagement|Corpus are used in fuzz testing as mutation source to Improve future testing."
+msgid "CorpusManagement|Corpus file"
msgstr ""
-msgid "CorpusManagement|Corpus file"
+msgid "CorpusManagement|Corpus files are used in coverage-guided fuzz testing as seed inputs to improve testing."
msgstr ""
msgid "CorpusManagement|Corpus files must be in *.zip format. Maximum 5 GB"
@@ -9776,6 +9858,9 @@ msgstr ""
msgid "Could not apply %{name} command."
msgstr ""
+msgid "Could not apply %{name} command. %{message}."
+msgstr ""
+
msgid "Could not authorize chat nickname. Try again!"
msgstr ""
@@ -9926,6 +10011,9 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
+msgid "Create a group"
+msgstr ""
+
msgid "Create a merge request"
msgstr ""
@@ -9950,6 +10038,9 @@ msgstr ""
msgid "Create a personal access token on your account to pull or push via %{protocol}."
msgstr ""
+msgid "Create a project"
+msgstr ""
+
msgid "Create an account using:"
msgstr ""
@@ -10313,6 +10404,9 @@ msgstr ""
msgid "Creation date"
msgstr ""
+msgid "Creator"
+msgstr ""
+
msgid "Credentials"
msgstr ""
@@ -10325,9 +10419,15 @@ msgstr ""
msgid "CredentialsInventory|Personal Access Tokens"
msgstr ""
+msgid "CredentialsInventory|Project Access Tokens"
+msgstr ""
+
msgid "CredentialsInventory|SSH Keys"
msgstr ""
+msgid "Credit card required to be on file in order to create a pipeline"
+msgstr ""
+
msgid "Credit card:"
msgstr ""
@@ -10511,9 +10611,6 @@ msgstr ""
msgid "Customer relations"
msgstr ""
-msgid "Customizable by an administrator."
-msgstr ""
-
msgid "Customizable by owners."
msgstr ""
@@ -10643,30 +10740,18 @@ msgstr ""
msgid "CycleAnalytics|%{selectedLabelsCount} selected (%{maxLabels} max)"
msgstr ""
-msgid "CycleAnalytics|%{stageCount} stages selected"
-msgstr ""
-
-msgid "CycleAnalytics|All stages"
-msgstr ""
-
-msgid "CycleAnalytics|Average days to completion"
+msgid "CycleAnalytics|Average time to completion"
msgstr ""
msgid "CycleAnalytics|Date"
msgstr ""
-msgid "CycleAnalytics|Days to completion"
-msgstr ""
-
msgid "CycleAnalytics|Display chart filters"
msgstr ""
msgid "CycleAnalytics|Lead Time for Changes"
msgstr ""
-msgid "CycleAnalytics|No stages selected"
-msgstr ""
-
msgid "CycleAnalytics|Number of tasks"
msgstr ""
@@ -10693,18 +10778,30 @@ msgstr ""
msgid "CycleAnalytics|Showing data for group '%{groupName}' from %{createdAfter} to %{createdBefore}"
msgstr ""
-msgid "CycleAnalytics|Stages"
+msgid "CycleAnalytics|Stage time: %{title}"
msgstr ""
msgid "CycleAnalytics|Tasks by type"
msgstr ""
-msgid "CycleAnalytics|The average time spent in the selected stage for the items that were completed on each date. Data limited to the last 500 items."
+msgid "CycleAnalytics|The average time items spent in this stage. Data limited to items completed within this date range."
msgstr ""
msgid "CycleAnalytics|The given date range is larger than 180 days"
msgstr ""
+msgid "CycleAnalytics|The total time items spent across each value stream stage. Data limited to items completed within this date range."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Stage time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Total time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|Total time"
+msgstr ""
+
msgid "CycleAnalytics|Type of work"
msgstr ""
@@ -10717,9 +10814,6 @@ msgstr ""
msgid "CycleAnalytics|project dropdown filter"
msgstr ""
-msgid "CycleAnalytics|stage dropdown"
-msgstr ""
-
msgid "DAG visualization requires at least 3 dependent jobs."
msgstr ""
@@ -10819,10 +10913,16 @@ msgstr ""
msgid "DastProfiles|AJAX spider"
msgstr ""
+msgid "DastProfiles|API"
+msgstr ""
+
+msgid "DastProfiles|API endpoint URL"
+msgstr ""
+
msgid "DastProfiles|Active"
msgstr ""
-msgid "DastProfiles|Additional request headers (Optional)"
+msgid "DastProfiles|Additional request headers (optional)"
msgstr ""
msgid "DastProfiles|Are you sure you want to delete this profile?"
@@ -10837,6 +10937,9 @@ msgstr ""
msgid "DastProfiles|Branch missing"
msgstr ""
+msgid "DastProfiles|Choose a scan method"
+msgstr ""
+
msgid "DastProfiles|Could not create the scanner profile. Please try again."
msgstr ""
@@ -10906,7 +11009,13 @@ msgstr ""
msgid "DastProfiles|Excluded URLs"
msgstr ""
-msgid "DastProfiles|Excluded URLs (Optional)"
+msgid "DastProfiles|Excluded URLs (optional)"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths (optional)"
msgstr ""
msgid "DastProfiles|Hide debug messages"
@@ -10963,9 +11072,6 @@ msgstr ""
msgid "DastProfiles|Request headers"
msgstr ""
-msgid "DastProfiles|Rest API"
-msgstr ""
-
msgid "DastProfiles|Run the AJAX spider, in addition to the traditional spider, to crawl the target site."
msgstr ""
@@ -10975,6 +11081,9 @@ msgstr ""
msgid "DastProfiles|Save profile"
msgstr ""
+msgid "DastProfiles|Scan method"
+msgstr ""
+
msgid "DastProfiles|Scan mode"
msgstr ""
@@ -11053,12 +11162,24 @@ msgstr ""
msgid "DastProfiles|Website"
msgstr ""
+msgid "DastProfiles|What does each method do?"
+msgstr ""
+
msgid "DastProfiles|You can either choose a passive scan or validate the target site from the site profile management page. %{docsLinkStart}Learn more about site validation.%{docsLinkEnd}"
msgstr ""
msgid "DastProfiles|You cannot run an active scan against an unvalidated site."
msgstr ""
+msgid "DastProfiles|folder/dast_example.har or https://example.com/dast_example.har"
+msgstr ""
+
+msgid "DastProfiles|folder/example.postman_collection.json or https://example.com/"
+msgstr ""
+
+msgid "DastProfiles|folder/openapi.json or https://example.com/openapi.json"
+msgstr ""
+
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
@@ -11165,6 +11286,9 @@ msgstr ""
msgid "DatadogIntegration|API URL"
msgstr ""
+msgid "DatadogIntegration|Custom tags in Datadog. Enter one tag per line in the %{codeOpen}key:value%{codeClose} format. %{linkOpen}How do I use tags?%{linkClose}"
+msgstr ""
+
msgid "DatadogIntegration|Environment"
msgstr ""
@@ -11183,12 +11307,18 @@ msgstr ""
msgid "DatadogIntegration|Tag all data from this GitLab instance in Datadog. Useful when managing several self-managed deployments."
msgstr ""
+msgid "DatadogIntegration|Tags"
+msgstr ""
+
msgid "DatadogIntegration|The Datadog site to send data to. To send data to the EU site, use %{codeOpen}datadoghq.eu%{codeClose}."
msgstr ""
msgid "DatadogIntegration|Trace your GitLab pipelines with Datadog."
msgstr ""
+msgid "DatadogIntegration|have an invalid format"
+msgstr ""
+
msgid "Datasource name not found"
msgstr ""
@@ -11198,9 +11328,6 @@ msgstr ""
msgid "Date merged"
msgstr ""
-msgid "Date picker"
-msgstr ""
-
msgid "Date range"
msgstr ""
@@ -11354,9 +11481,6 @@ msgstr ""
msgid "Definition"
msgstr ""
-msgid "Delayed Project Deletion (%{adjourned_deletion})"
-msgstr ""
-
msgid "DelayedJobs|Are you sure you want to run %{jobName} immediately? Otherwise this job will run automatically after its timer finishes."
msgstr ""
@@ -11435,10 +11559,10 @@ msgstr ""
msgid "Delete pipeline"
msgstr ""
-msgid "Delete project"
+msgid "Delete pipeline schedule"
msgstr ""
-msgid "Delete project. Are you ABSOLUTELY SURE?"
+msgid "Delete project"
msgstr ""
msgid "Delete row"
@@ -11468,6 +11592,9 @@ msgstr ""
msgid "Delete this epic and all descendants?"
msgstr ""
+msgid "Delete this project"
+msgstr ""
+
msgid "Delete user list"
msgstr ""
@@ -11720,6 +11847,12 @@ msgstr ""
msgid "Deploy to..."
msgstr ""
+msgid "DeployBoards|To see deployment progress for your environments, make sure you are deploying to %{codeStart}$KUBE_NAMESPACE%{codeEnd} and annotating with %{codeStart}app.gitlab.com/app=$CI_PROJECT_PATH_SLUG%{codeEnd} and %{codeStart}app.gitlab.com/env=$CI_ENVIRONMENT_SLUG%{codeEnd}."
+msgstr ""
+
+msgid "DeployBoard|Kubernetes Pods"
+msgstr ""
+
msgid "DeployFreeze|Add a freeze period to prevent unintended releases during a period of time for a given environment. You must update the deployment jobs in %{filename} according to the deploy freezes added here. %{freeze_period_link_start}Learn more.%{freeze_period_link_end}"
msgstr ""
@@ -11804,9 +11937,6 @@ msgstr ""
msgid "DeployTokens|Active Deploy Tokens (%{active_tokens})"
msgstr ""
-msgid "DeployTokens|Allows read and write access to registry images."
-msgstr ""
-
msgid "DeployTokens|Allows read and write access to the package registry."
msgstr ""
@@ -11819,6 +11949,9 @@ msgstr ""
msgid "DeployTokens|Allows read-only access to the repository."
msgstr ""
+msgid "DeployTokens|Allows write access to registry images."
+msgstr ""
+
msgid "DeployTokens|Copy deploy token"
msgstr ""
@@ -11912,12 +12045,57 @@ msgstr ""
msgid "Deploying to AWS is easy with GitLab"
msgstr ""
+msgid "Deployment"
+msgstr ""
+
msgid "Deployment Frequency"
msgstr ""
+msgid "Deployment Target|Project deployment target (optional)"
+msgstr ""
+
+msgid "Deployment Target|Select the deployment target"
+msgstr ""
+
msgid "Deployment frequency"
msgstr ""
+msgid "DeploymentTarget|GitLab Pages"
+msgstr ""
+
+msgid "DeploymentTarget|Heroku"
+msgstr ""
+
+msgid "DeploymentTarget|Infrastructure provider (Terraform, Cloudformation, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Kubernetes (GKE, EKS, OpenShift, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Managed container runtime (Fargate, Cloud Run, DigitalOcean App)"
+msgstr ""
+
+msgid "DeploymentTarget|Mobile app store"
+msgstr ""
+
+msgid "DeploymentTarget|No deployment planned"
+msgstr ""
+
+msgid "DeploymentTarget|Other hosting service"
+msgstr ""
+
+msgid "DeploymentTarget|Registry (package or container)"
+msgstr ""
+
+msgid "DeploymentTarget|Self-managed container runtime (Podman, Docker Swarm, Docker Compose)"
+msgstr ""
+
+msgid "DeploymentTarget|Serverless backend (Lambda, Cloud functions)"
+msgstr ""
+
+msgid "DeploymentTarget|Virtual machine (for example, EC2)"
+msgstr ""
+
msgid "Deployments"
msgstr ""
@@ -11955,6 +12133,9 @@ msgstr ""
msgid "Deployment|This deployment was created using the API"
msgstr ""
+msgid "Deployment|Triggerer"
+msgstr ""
+
msgid "Deployment|Waiting"
msgstr ""
@@ -11982,6 +12163,18 @@ msgstr ""
msgid "Deprecated API rate limits"
msgstr ""
+msgid "Deprecations|Feature deprecation and removal"
+msgstr ""
+
+msgid "Deprecations|For information on a possible replacement %{epicStart} learn more about Opstrace %{epicEnd}."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7 and are %{epicStart} scheduled for removal %{epicEnd} in GitLab 15.0."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7, and are %{removal_link_start} scheduled for removal %{link_end} in GitLab 15.0. For information on a possible replacement, %{opstrace_link_start} learn more about Opstrace %{link_end}."
+msgstr ""
+
msgid "Deprioritize label"
msgstr ""
@@ -12226,10 +12419,10 @@ msgstr ""
msgid "DevopsAdoption|At least one deploy"
msgstr ""
-msgid "DevopsAdoption|At least one issue opened"
+msgid "DevopsAdoption|At least one issue created"
msgstr ""
-msgid "DevopsAdoption|At least one merge request opened"
+msgid "DevopsAdoption|At least one merge request created"
msgstr ""
msgid "DevopsAdoption|At least one pipeline successfully run"
@@ -12427,6 +12620,9 @@ msgstr ""
msgid "Direct member"
msgstr ""
+msgid "Direct members"
+msgstr ""
+
msgid "Direct non-authenticated users to this page."
msgstr ""
@@ -12542,6 +12738,9 @@ msgid "Dismiss %d selected vulnerability as"
msgid_plural "Dismiss %d selected vulnerabilities as"
msgstr[0] ""
+msgid "Dismiss Alert"
+msgstr ""
+
msgid "Dismiss merge request promotion"
msgstr ""
@@ -12569,9 +12768,15 @@ msgstr ""
msgid "Display alerts from all configured monitoring tools."
msgstr ""
+msgid "Display milestones"
+msgstr ""
+
msgid "Display name"
msgstr ""
+msgid "Display progress of child issues"
+msgstr ""
+
msgid "Display rendered file"
msgstr ""
@@ -12677,6 +12882,9 @@ msgstr ""
msgid "Download image"
msgstr ""
+msgid "Download payload"
+msgstr ""
+
msgid "Download raw data (.csv)"
msgstr ""
@@ -12854,6 +13062,9 @@ msgstr ""
msgid "Edit in Web IDE"
msgstr ""
+msgid "Edit in pipeline editor"
+msgstr ""
+
msgid "Edit in single-file editor"
msgstr ""
@@ -12896,6 +13107,9 @@ msgstr ""
msgid "Edit your most recent comment in a thread (from an empty textarea)"
msgstr ""
+msgid "Edit, lint, and visualize your pipeline."
+msgstr ""
+
msgid "Edited"
msgstr ""
@@ -13337,6 +13551,9 @@ msgstr ""
msgid "Enforce two-factor authentication for all user sign-ins."
msgstr ""
+msgid "Enhance security by storing service account keys in secret managers - learn more about %{docLinkStart}secret management with GitLab%{docLinkEnd}"
+msgstr ""
+
msgid "Ensure connectivity is available from the GitLab server to the Prometheus server"
msgstr ""
@@ -13397,6 +13614,9 @@ 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 following to confirm:"
+msgstr ""
+
msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
@@ -13926,9 +14146,6 @@ 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 ""
@@ -14064,6 +14281,9 @@ msgstr ""
msgid "Errors:"
msgstr ""
+msgid "Escalate this incident"
+msgstr ""
+
msgid "Escalation Policies"
msgstr ""
@@ -14076,6 +14296,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy"
+msgstr ""
+
msgid "Escalation policy:"
msgstr ""
@@ -14326,6 +14549,9 @@ msgstr ""
msgid "Existing sign in methods may be removed"
msgstr ""
+msgid "Exit."
+msgstr ""
+
msgid "Expand"
msgstr ""
@@ -14422,6 +14648,9 @@ msgstr ""
msgid "Explore public groups"
msgstr ""
+msgid "Explore public projects"
+msgstr ""
+
msgid "Explore snippets"
msgstr ""
@@ -14582,7 +14811,7 @@ msgid "Failed to archive a design. Please try again."
msgid_plural "Failed to archive designs. Please try again."
msgstr[0] ""
-msgid "Failed to assign a reviewer because no user was found."
+msgid "Failed to assign a reviewer because no user was specified."
msgstr ""
msgid "Failed to assign a user because no user was found."
@@ -14648,10 +14877,10 @@ msgstr ""
msgid "Failed to find import label for Jira import."
msgstr ""
-msgid "Failed to generate export, please try again later."
+msgid "Failed to find users for %{missing}"
msgstr ""
-msgid "Failed to generate report, please try again after sometime"
+msgid "Failed to generate export, please try again later."
msgstr ""
msgid "Failed to get ref."
@@ -14750,6 +14979,9 @@ msgstr ""
msgid "Failed to remove a to-do item for the design."
msgstr ""
+msgid "Failed to remove attention because no user was found."
+msgstr ""
+
msgid "Failed to remove mirror."
msgstr ""
@@ -14762,6 +14994,9 @@ msgstr ""
msgid "Failed to remove user key."
msgstr ""
+msgid "Failed to request attention because no user was found."
+msgstr ""
+
msgid "Failed to reset key. Please try again."
msgstr ""
@@ -14843,6 +15078,9 @@ msgstr ""
msgid "Feature Flags"
msgstr ""
+msgid "Feature deprecation and removal"
+msgstr ""
+
msgid "Feature flag status"
msgstr ""
@@ -15339,7 +15577,7 @@ msgstr ""
msgid "For each job, re-use the project workspace. If the workspace doesn't exist, use %{code_open}git clone%{code_close}."
msgstr ""
-msgid "For example, the application using the token or the purpose of the token."
+msgid "For example, the application using the token or the purpose of the token. Do not give sensitive information for the name of the token, as it will be visible to all %{resource_type} members."
msgstr ""
msgid "For files larger than this limit, only index the file name. The file content is neither indexed nor searchable."
@@ -15423,9 +15661,6 @@ msgstr ""
msgid "ForkProject|Select a namespace"
msgstr ""
-msgid "ForkProject|Select a namespace to fork the project"
-msgstr ""
-
msgid "ForkProject|The project can be accessed by any logged in user."
msgstr ""
@@ -15522,6 +15757,9 @@ msgstr ""
msgid "Full name"
msgstr ""
+msgid "GCP region configured"
+msgstr ""
+
msgid "GPG Key ID:"
msgstr ""
@@ -15702,6 +15940,9 @@ msgstr ""
msgid "Geo|Failed"
msgstr ""
+msgid "Geo|Filter Geo sites"
+msgstr ""
+
msgid "Geo|Filter by name"
msgstr ""
@@ -16113,6 +16354,12 @@ msgstr ""
msgid "GitLab Issue"
msgstr ""
+msgid "GitLab KAS"
+msgstr ""
+
+msgid "GitLab Memberships CSV Export"
+msgstr ""
+
msgid "GitLab Pages"
msgstr ""
@@ -16161,6 +16408,9 @@ 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 free to use. Many features for larger teams are part of our %{link_start}paid products%{link_end}. You can try Ultimate for free without any obligation or payment details."
+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 ""
@@ -16287,7 +16537,7 @@ msgstr ""
msgid "GitLabPages|When enabled, all attempts to visit your website through HTTP are automatically redirected to HTTPS using a response with status code 301. Requires a valid certificate for all domains. %{docs_link_start}Learn more.%{link_end}"
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. %{docs_link_start}Learn more.%{link_end}"
+msgid "GitLabPages|When using Pages under the general domain of a GitLab instance (%{pages_host}), you cannot use HTTPS with subdomains of subdomains. If your namespace or groupname contains a dot, it does not work. This is a limitation of the HTTP Over TLS protocol. HTTP pages work if you don't redirect HTTP to HTTPS. %{docs_link_start}Learn more.%{link_end}"
msgstr ""
msgid "GitLabPages|With GitLab Pages you can host your static website directly from your GitLab repository. %{docs_link_start}Learn more.%{link_end}"
@@ -16464,9 +16714,6 @@ msgstr ""
msgid "Go to find file"
msgstr ""
-msgid "Go to fork"
-msgstr ""
-
msgid "Go to issue boards"
msgstr ""
@@ -16674,9 +16921,6 @@ msgstr ""
msgid "Group Hooks"
msgstr ""
-msgid "Group ID"
-msgstr ""
-
msgid "Group Owner must have signed in with SAML before enabling Group Managed Accounts"
msgstr ""
@@ -16704,9 +16948,6 @@ msgstr ""
msgid "Group by"
msgstr ""
-msgid "Group description"
-msgstr ""
-
msgid "Group description (optional)"
msgstr ""
@@ -16821,7 +17062,7 @@ msgstr ""
msgid "Group: %{name}"
msgstr ""
-msgid "GroupActivityMetrics|Issues opened"
+msgid "GroupActivityMetrics|Issues created"
msgstr ""
msgid "GroupActivityMetrics|Last 90 days"
@@ -16830,7 +17071,7 @@ msgstr ""
msgid "GroupActivityMetrics|Members added"
msgstr ""
-msgid "GroupActivityMetrics|Merge Requests opened"
+msgid "GroupActivityMetrics|Merge Requests created"
msgstr ""
msgid "GroupActivityMetrics|Recent activity"
@@ -17121,6 +17362,9 @@ msgstr ""
msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
+msgid "GroupSettings|Choose a group path that does not start with a dash or end with a period. It can also contain alphanumeric characters and underscores."
+msgstr ""
+
msgid "GroupSettings|Compliance frameworks"
msgstr ""
@@ -17154,7 +17398,7 @@ msgstr ""
msgid "GroupSettings|If not specified at the group or instance level, the default is %{default_initial_branch_name}. Does not affect existing repositories."
msgstr ""
-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."
+msgid "GroupSettings|If the parent group's visibility is lower than the group's current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility."
msgstr ""
msgid "GroupSettings|New runners registration token has been generated!"
@@ -17271,7 +17515,10 @@ msgstr ""
msgid "Groups and projects"
msgstr ""
-msgid "Groups and subgroups"
+msgid "Groups are a great way to organize projects and people."
+msgstr ""
+
+msgid "Groups are the best way to manage projects and members."
msgstr ""
msgid "Groups to synchronize"
@@ -17382,13 +17629,16 @@ msgstr ""
msgid "GroupsTree|Are you sure you want to leave the \"%{fullName}\" group?"
msgstr ""
-msgid "GroupsTree|Edit group"
+msgid "GroupsTree|Delete"
+msgstr ""
+
+msgid "GroupsTree|Edit"
msgstr ""
msgid "GroupsTree|Failed to leave the group. Please make sure you are not the only owner."
msgstr ""
-msgid "GroupsTree|Leave this group"
+msgid "GroupsTree|Leave group"
msgstr ""
msgid "GroupsTree|Loading groups"
@@ -17400,9 +17650,57 @@ msgstr ""
msgid "GroupsTree|No groups or projects matched your search"
msgstr ""
+msgid "GroupsTree|Options"
+msgstr ""
+
msgid "GroupsTree|Search by name"
msgstr ""
+msgid "Groups|Avatar will be removed. Are you sure?"
+msgstr ""
+
+msgid "Groups|Changing group URL can have unintended side effects."
+msgstr ""
+
+msgid "Groups|Checking group URL availability..."
+msgstr ""
+
+msgid "Groups|Enter a descriptive name for your group."
+msgstr ""
+
+msgid "Groups|Group ID"
+msgstr ""
+
+msgid "Groups|Group URL"
+msgstr ""
+
+msgid "Groups|Group avatar"
+msgstr ""
+
+msgid "Groups|Group description (optional)"
+msgstr ""
+
+msgid "Groups|Group name"
+msgstr ""
+
+msgid "Groups|Group path is available."
+msgstr ""
+
+msgid "Groups|Group path is unavailable. Path has been replaced with a suggested available path."
+msgstr ""
+
+msgid "Groups|Learn more"
+msgstr ""
+
+msgid "Groups|Must start with letter, digit, emoji, or underscore. Can also contain periods, dashes, spaces, and parentheses."
+msgstr ""
+
+msgid "Groups|Remove avatar"
+msgstr ""
+
+msgid "Groups|Save changes"
+msgstr ""
+
msgid "Guideline"
msgstr ""
@@ -17412,6 +17710,9 @@ msgstr ""
msgid "HAR file path or URL"
msgstr ""
+msgid "HTTP Archive (HAR)"
+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 ""
@@ -17810,6 +18111,9 @@ msgstr ""
msgid "INFO: Your SSH key is expiring soon. Please generate a new key."
msgstr ""
+msgid "IP"
+msgstr ""
+
msgid "IP Address"
msgstr ""
@@ -17846,6 +18150,9 @@ msgstr ""
msgid "IdentityVerification|Verify your identity"
msgstr ""
+msgid "IdentityVerification|You can always verify your account at a later time to create a group."
+msgstr ""
+
msgid "If any indexed field exceeds this limit, it is truncated to this number of characters. The rest of the content is neither indexed nor searchable. This does not apply to repository and wiki indexing. For unlimited characters, set this to 0."
msgstr ""
@@ -17903,6 +18210,9 @@ msgstr ""
msgid "If you add %{codeStart}needs%{codeEnd} to jobs in your pipeline you'll be able to view the %{codeStart}needs%{codeEnd} relationships between jobs in this tab as a %{linkStart}Directed Acyclic Graph (DAG)%{linkEnd}."
msgstr ""
+msgid "If you are added to a project, it will be displayed here."
+msgstr ""
+
msgid "If you did not initiate these sign-in attempts, please reach out to your administrator or enable two-factor authentication (2FA) on your account."
msgstr ""
@@ -18206,12 +18516,24 @@ msgstr ""
msgid "InProductMarketing|3 ways to dive into GitLab CI/CD"
msgstr ""
+msgid "InProductMarketing|A single application eliminates complex integrations, data chokepoints, and toolchain maintenance, resulting in greater productivity and lower cost."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features, build more efficiently, strengthen security and compliance."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features."
+msgstr ""
+
msgid "InProductMarketing|Actually, GitLab makes the team work (better)"
msgstr ""
msgid "InProductMarketing|And finally %{deploy_link} a Python application."
msgstr ""
+msgid "InProductMarketing|And many more..."
+msgstr ""
+
msgid "InProductMarketing|Are your runners ready?"
msgstr ""
@@ -18230,15 +18552,33 @@ msgstr ""
msgid "InProductMarketing|Blog"
msgstr ""
+msgid "InProductMarketing|Break down silos to coordinate seamlessly across development, operations, and security with a consistent experience across the development lifecycle."
+msgstr ""
+
+msgid "InProductMarketing|Burn up/down charts"
+msgstr ""
+
msgid "InProductMarketing|By enabling code owners and required merge approvals the right person will review the right MR. This is a win-win: cleaner code and a more efficient review process."
msgstr ""
msgid "InProductMarketing|Click on the number below that corresponds with your answer — 1 being very difficult, 5 being very easy."
msgstr ""
+msgid "InProductMarketing|Code owners"
+msgstr ""
+
msgid "InProductMarketing|Code owners and required merge approvals are part of the paid tiers of GitLab. You can start a free 30-day trial of GitLab Ultimate and enable these features in less than 5 minutes with no credit card required."
msgstr ""
+msgid "InProductMarketing|Code review analytics"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration across stages in GitLab"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration made easy"
+msgstr ""
+
msgid "InProductMarketing|Create a custom CI runner with just a few clicks"
msgstr ""
@@ -18248,12 +18588,21 @@ msgstr ""
msgid "InProductMarketing|Create a project in GitLab in 5 minutes"
msgstr ""
+msgid "InProductMarketing|Create well-defined workflows by using scoped labels on issues, merge requests, and epics. Labels with the same scope cannot be used together, which prevents conflicts."
+msgstr ""
+
msgid "InProductMarketing|Create your first project!"
msgstr ""
+msgid "InProductMarketing|Define who owns specific files or directories, so the right reviewers are suggested when a merge request introduces changes to those files."
+msgstr ""
+
msgid "InProductMarketing|Deliver Better Products Faster"
msgstr ""
+msgid "InProductMarketing|Dependency scanning"
+msgstr ""
+
msgid "InProductMarketing|Did you know teams that use GitLab are far more efficient?"
msgstr ""
@@ -18263,15 +18612,27 @@ msgstr ""
msgid "InProductMarketing|Dig in and create a project and a repo"
msgstr ""
+msgid "InProductMarketing|Discover Premium & Ultimate"
+msgstr ""
+
+msgid "InProductMarketing|Discover Premium & Ultimate."
+msgstr ""
+
msgid "InProductMarketing|Do you have a minute?"
msgstr ""
msgid "InProductMarketing|Do you have a teammate who would be perfect for this task?"
msgstr ""
+msgid "InProductMarketing|Dynamic application security testing"
+msgstr ""
+
msgid "InProductMarketing|Easy"
msgstr ""
+msgid "InProductMarketing|Epics"
+msgstr ""
+
msgid "InProductMarketing|Expand your DevOps journey with a free GitLab trial"
msgstr ""
@@ -18293,9 +18654,15 @@ msgstr ""
msgid "InProductMarketing|Feel the need for speed?"
msgstr ""
+msgid "InProductMarketing|Find and fix bottlenecks in your code review process by understanding how long open merge requests have been in review."
+msgstr ""
+
msgid "InProductMarketing|Find out how your teams are really doing"
msgstr ""
+msgid "InProductMarketing|Find out if your external libraries are safe. Run dependency scanning jobs that check for known vulnerabilities in your external libraries."
+msgstr ""
+
msgid "InProductMarketing|Follow our steps"
msgstr ""
@@ -18332,6 +18699,9 @@ msgstr ""
msgid "InProductMarketing|GitLab is better with teammates to help out!"
msgstr ""
+msgid "InProductMarketing|GitLab is infrastructure agnostic (supporting GCP, AWS, Azure, OpenShift, VMWare, On Prem, Bare Metal, and more), offering a consistent workflow experience – irrespective of the environment."
+msgstr ""
+
msgid "InProductMarketing|GitLab provides static application security testing (SAST), dynamic application security testing (DAST), container scanning, and dependency scanning to help you deliver secure applications along with license compliance."
msgstr ""
@@ -18422,21 +18792,36 @@ msgstr ""
msgid "InProductMarketing|It's also possible to simply %{external_repo_link} in order to take advantage of GitLab's CI/CD."
msgstr ""
+msgid "InProductMarketing|Keep your code quality high by defining who should approve merge requests and how many approvals are required."
+msgstr ""
+
msgid "InProductMarketing|Launch GitLab CI/CD in 20 minutes or less"
msgstr ""
+msgid "InProductMarketing|Lower cost of development"
+msgstr ""
+
+msgid "InProductMarketing|Make it easier to collaborate on high-level ideas by grouping related issues in an epic."
+msgstr ""
+
msgid "InProductMarketing|Making the switch? It's easier than you think to import your projects into GitLab. Move %{github_link}, or import something %{bitbucket_link}."
msgstr ""
msgid "InProductMarketing|Master the art of importing!"
msgstr ""
+msgid "InProductMarketing|Merge request approval rule"
+msgstr ""
+
msgid "InProductMarketing|Move on to easily creating a Pages website %{ci_template_link}"
msgstr ""
msgid "InProductMarketing|Multiple owners, confusing workstreams? We've got you covered"
msgstr ""
+msgid "InProductMarketing|Multiple required approvers"
+msgstr ""
+
msgid "InProductMarketing|Need an alternative to importing?"
msgstr ""
@@ -18449,18 +18834,33 @@ msgstr ""
msgid "InProductMarketing|Our tool brings all the things together"
msgstr ""
+msgid "InProductMarketing|Protect your web application by using DAST to examine for vulnerabilities in deployed environments."
+msgstr ""
+
msgid "InProductMarketing|Rapid development, simplified"
msgstr ""
msgid "InProductMarketing|Reduce Security & Compliance Risk"
msgstr ""
+msgid "InProductMarketing|Require multiple approvers on a merge request, so you know it's in good shape before it's merged."
+msgstr ""
+
+msgid "InProductMarketing|Roadmaps"
+msgstr ""
+
+msgid "InProductMarketing|Scoped labels"
+msgstr ""
+
msgid "InProductMarketing|Security that's integrated into your development lifecycle"
msgstr ""
msgid "InProductMarketing|Sometimes you're not ready to make a full transition to a new tool. If you're not ready to fully commit, %{mirroring_link} gives you a safe way to try out GitLab in parallel with your current tool."
msgstr ""
+msgid "InProductMarketing|Speed. Efficiency. Trust."
+msgstr ""
+
msgid "InProductMarketing|Spin up an autoscaling runner in GitLab"
msgstr ""
@@ -18470,6 +18870,9 @@ msgstr ""
msgid "InProductMarketing|Start a Self-Managed trial"
msgstr ""
+msgid "InProductMarketing|Start a free trial"
+msgstr ""
+
msgid "InProductMarketing|Start a free trial of GitLab Ultimate – no credit card required"
msgstr ""
@@ -18536,6 +18939,9 @@ msgstr ""
msgid "InProductMarketing|To understand and get the most out of GitLab, start at the beginning and %{project_link}. In GitLab, repositories are part of a project, so after you've created your project you can go ahead and %{repo_link}."
msgstr ""
+msgid "InProductMarketing|Track completed issues in a chart, so you can see how a milestone is progressing at a glance."
+msgstr ""
+
msgid "InProductMarketing|Try GitLab Ultimate for free"
msgstr ""
@@ -18572,6 +18978,9 @@ msgstr ""
msgid "InProductMarketing|Very easy"
msgstr ""
+msgid "InProductMarketing|Visualize your epics and milestones in a timeline."
+msgstr ""
+
msgid "InProductMarketing|Want to host GitLab on your servers?"
msgstr ""
@@ -18593,6 +19002,9 @@ msgstr ""
msgid "InProductMarketing|YouTube"
msgstr ""
+msgid "InProductMarketing|Your software, deployed your way"
+msgstr ""
+
msgid "InProductMarketing|Your teams can be more efficient"
msgstr ""
@@ -18713,9 +19125,18 @@ msgstr ""
msgid "IncidentManagement|No incidents to display."
msgstr ""
+msgid "IncidentManagement|None"
+msgstr ""
+
msgid "IncidentManagement|Open"
msgstr ""
+msgid "IncidentManagement|Page your team with escalation policies"
+msgstr ""
+
+msgid "IncidentManagement|Paged"
+msgstr ""
+
msgid "IncidentManagement|Published"
msgstr ""
@@ -18725,6 +19146,9 @@ msgstr ""
msgid "IncidentManagement|Severity"
msgstr ""
+msgid "IncidentManagement|Status"
+msgstr ""
+
msgid "IncidentManagement|There are no closed incidents"
msgstr ""
@@ -18743,6 +19167,9 @@ msgstr ""
msgid "IncidentManagement|Unpublished"
msgstr ""
+msgid "IncidentManagement|Use escalation policies to automatically page your team when incidents are created."
+msgstr ""
+
msgid "IncidentSettings|Activate \"time to SLA\" countdown timer"
msgstr ""
@@ -18788,7 +19215,10 @@ msgstr ""
msgid "Incidents"
msgstr ""
-msgid "Incidents|Add a URL"
+msgid "Incidents|Add image details"
+msgstr ""
+
+msgid "Incidents|Add text or a link to display with your image. If you don't add either, the file name displays instead."
msgstr ""
msgid "Incidents|Drop or %{linkStart}upload%{linkEnd} a metric screenshot to attach it to the incident"
@@ -18803,10 +19233,10 @@ msgstr ""
msgid "Incidents|There was an issue loading metric images."
msgstr ""
-msgid "Incidents|There was an issue uploading your image."
+msgid "Incidents|There was an issue updating your image."
msgstr ""
-msgid "Incidents|You can optionally add a URL to link users to the original graph."
+msgid "Incidents|There was an issue uploading your image."
msgstr ""
msgid "Incident|Alert details"
@@ -18815,9 +19245,18 @@ msgstr ""
msgid "Incident|Are you sure you wish to delete this image?"
msgstr ""
+msgid "Incident|Delete image"
+msgstr ""
+
msgid "Incident|Deleting %{filename}"
msgstr ""
+msgid "Incident|Edit image text or link"
+msgstr ""
+
+msgid "Incident|Editing %{filename}"
+msgstr ""
+
msgid "Incident|Metrics"
msgstr ""
@@ -19086,12 +19525,18 @@ msgstr ""
msgid "Integrations|Branches for which notifications are to be sent"
msgstr ""
+msgid "Integrations|Clear if using a self-signed certificate."
+msgstr ""
+
msgid "Integrations|Comment detail:"
msgstr ""
msgid "Integrations|Comment settings:"
msgstr ""
+msgid "Integrations|Connection details"
+msgstr ""
+
msgid "Integrations|Connection failed. Please check your settings."
msgstr ""
@@ -19116,6 +19561,9 @@ msgstr ""
msgid "Integrations|Enable GitLab.com slash commands in a Slack workspace."
msgstr ""
+msgid "Integrations|Enable SSL verification"
+msgstr ""
+
msgid "Integrations|Enable comments"
msgstr ""
@@ -19194,6 +19642,9 @@ msgstr ""
msgid "Integrations|Return to GitLab for Jira"
msgstr ""
+msgid "Integrations|SSL verification"
+msgstr ""
+
msgid "Integrations|Save settings?"
msgstr ""
@@ -19239,9 +19690,6 @@ msgstr ""
msgid "Integrations|Use default settings"
msgstr ""
-msgid "Integrations|When you mention a Jira issue in a commit or merge request, GitLab creates a remote link and comment (if enabled)."
-msgstr ""
-
msgid "Integrations|You can now close this window and return to the GitLab for Jira application."
msgstr ""
@@ -19266,9 +19714,6 @@ msgstr ""
msgid "Integrations|can't exceed %{recipients_limit}"
msgstr ""
-msgid "Interactive developer security education."
-msgstr ""
-
msgid "Interactive mode"
msgstr ""
@@ -19758,6 +20203,9 @@ msgstr ""
msgid "IssueAnalytics|Assignees"
msgstr ""
+msgid "IssueAnalytics|Created by"
+msgstr ""
+
msgid "IssueAnalytics|Due date"
msgstr ""
@@ -19770,9 +20218,6 @@ msgstr ""
msgid "IssueAnalytics|Milestone"
msgstr ""
-msgid "IssueAnalytics|Opened by"
-msgstr ""
-
msgid "IssueAnalytics|Status"
msgstr ""
@@ -19896,10 +20341,10 @@ msgstr ""
msgid "IssuesAnalytics|Avg/Month:"
msgstr ""
-msgid "IssuesAnalytics|Issues opened"
+msgid "IssuesAnalytics|Issues created"
msgstr ""
-msgid "IssuesAnalytics|Issues opened per month"
+msgid "IssuesAnalytics|Issues created per month"
msgstr ""
msgid "IssuesAnalytics|Last 12 months"
@@ -19926,6 +20371,9 @@ msgstr ""
msgid "It looks like you have some draft commits in this branch."
msgstr ""
+msgid "It looks like you're attempting to activate your subscription. Use %{a_start}the Subscription page%{a_end} instead."
+msgstr ""
+
msgid "It may be several days before you see feature usage data."
msgstr ""
@@ -20154,6 +20602,9 @@ msgstr ""
msgid "JiraConnect|You can now close this window and return to Jira."
msgstr ""
+msgid "JiraConnect|You don't have permission to create branches for this project. Select a different project or contact the project owner for access. %{linkStart}Learn more.%{linkEnd}"
+msgstr ""
+
msgid "JiraRequest|A connection error occurred while connecting to Jira. Try your request again."
msgstr ""
@@ -20202,13 +20653,13 @@ msgstr ""
msgid "JiraService|Define the type of Jira issue to create from a vulnerability."
msgstr ""
-msgid "JiraService|Displaying Jira issues while leaving the GitLab issue functionality enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
+msgid "JiraService|Displaying Jira issues while leaving GitLab issues also enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
msgstr ""
-msgid "JiraService|Enable Jira issues"
+msgid "JiraService|Enable Jira issue creation from vulnerabilities"
msgstr ""
-msgid "JiraService|Enable Jira issues creation from vulnerabilities"
+msgid "JiraService|Enable Jira issues"
msgstr ""
msgid "JiraService|Enable Jira transitions"
@@ -20325,16 +20776,19 @@ msgstr ""
msgid "JiraService|View Jira issues in GitLab"
msgstr ""
-msgid "JiraService|Warning: All GitLab users that have access to this GitLab project are able to view all issues from the Jira project specified below."
+msgid "JiraService|Warning: All GitLab users with access to this GitLab project can view all issues from the Jira project you select."
msgstr ""
msgid "JiraService|Web URL"
msgstr ""
-msgid "JiraService|Work on Jira issues without leaving GitLab. Adds a Jira menu to access your list of Jira issues and view any issue as read-only."
+msgid "JiraService|When a Jira issue is mentioned in a commit or merge request, a remote link and comment (if enabled) will be created."
+msgstr ""
+
+msgid "JiraService|Work on Jira issues without leaving GitLab. Add a Jira menu to access a read-only list of your Jira issues."
msgstr ""
-msgid "JiraService|You need to configure Jira before enabling this integration. For more details, read the %{jira_doc_link_start}Jira integration documentation%{link_end}."
+msgid "JiraService|You must configure Jira before enabling this integration. %{jira_doc_link_start}Learn more.%{link_end}"
msgstr ""
msgid "Job"
@@ -20346,9 +20800,6 @@ msgstr ""
msgid "Job Failed #%{build_id}"
msgstr ""
-msgid "Job ID"
-msgstr ""
-
msgid "Job artifact"
msgstr ""
@@ -20415,9 +20866,27 @@ msgstr ""
msgid "Jobs|You're about to retry a job that failed because it attempted to deploy code that is older than the latest deployment. Retrying this job could result in overwriting the environment with the older source code."
msgstr ""
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source} into %{target}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{ref}"
+msgstr ""
+
+msgid "Job|Are you sure you want to erase this job log and artifacts?"
+msgstr ""
+
msgid "Job|Browse"
msgstr ""
+msgid "Job|Cancel"
+msgstr ""
+
msgid "Job|Complete Raw"
msgstr ""
@@ -20427,6 +20896,9 @@ msgstr ""
msgid "Job|Erase job log and artifacts"
msgstr ""
+msgid "Job|Finished at"
+msgstr ""
+
msgid "Job|Job artifacts"
msgstr ""
@@ -20439,7 +20911,7 @@ msgstr ""
msgid "Job|Keep"
msgstr ""
-msgid "Job|Pipeline"
+msgid "Job|Retry"
msgstr ""
msgid "Job|Scroll to bottom"
@@ -20451,6 +20923,9 @@ msgstr ""
msgid "Job|Show complete raw"
msgstr ""
+msgid "Job|Status"
+msgstr ""
+
msgid "Job|The artifacts were removed"
msgstr ""
@@ -20478,21 +20953,12 @@ msgstr ""
msgid "Job|delayed"
msgstr ""
-msgid "Job|for"
-msgstr ""
-
-msgid "Job|into"
-msgstr ""
-
msgid "Job|manual"
msgstr ""
msgid "Job|triggered"
msgstr ""
-msgid "Job|with"
-msgstr ""
-
msgid "Join Zoom meeting"
msgstr ""
@@ -20595,9 +21061,6 @@ msgstr ""
msgid "Ki"
msgstr ""
-msgid "Kontra"
-msgstr ""
-
msgid "Kroki"
msgstr ""
@@ -20920,6 +21383,9 @@ msgstr ""
msgid "Learn more about Auto DevOps"
msgstr ""
+msgid "Learn more about GitLab"
+msgstr ""
+
msgid "Learn more about Needs relationships"
msgstr ""
@@ -21241,9 +21707,18 @@ msgstr ""
msgid "Licenses|Displays licenses detected in the project, based on the %{linkStart}latest successful%{linkEnd} scan"
msgstr ""
+msgid "Licenses|Drag your license file here or %{linkStart}click to upload%{linkEnd}."
+msgstr ""
+
+msgid "Licenses|Drop your license file to start the upload."
+msgstr ""
+
msgid "Licenses|Error fetching the license list. Please check your network connection and try again."
msgstr ""
+msgid "Licenses|Error: You are trying to upload something other than a file"
+msgstr ""
+
msgid "Licenses|License Compliance"
msgstr ""
@@ -21262,6 +21737,9 @@ msgstr ""
msgid "Licenses|Specified policies in this project"
msgstr ""
+msgid "Licenses|The file could not be uploaded."
+msgstr ""
+
msgid "Licenses|The license list details information about the licenses used within your project."
msgstr ""
@@ -21295,10 +21773,6 @@ msgstr ""
msgid "Limit the size of Sidekiq jobs stored in Redis."
msgstr ""
-msgid "Limited to showing %d event at most"
-msgid_plural "Limited to showing %d events at most"
-msgstr[0] ""
-
msgid "Limiting mode"
msgstr ""
@@ -21308,6 +21782,9 @@ msgstr ""
msgid "Link"
msgstr ""
+msgid "Link (optional)"
+msgstr ""
+
msgid "Link Prometheus monitoring to GitLab."
msgstr ""
@@ -21344,6 +21821,9 @@ msgstr ""
msgid "Linked emails (%{email_count})"
msgstr ""
+msgid "Linked epics"
+msgstr ""
+
msgid "Linked issues"
msgstr ""
@@ -21371,6 +21851,15 @@ msgstr ""
msgid "List of all merge commits"
msgstr ""
+msgid "List of environments for this project"
+msgstr ""
+
+msgid "List of suitable GCP locations"
+msgstr ""
+
+msgid "List of users allowed to exceed the rate limit."
+msgstr ""
+
msgid "List options"
msgstr ""
@@ -21590,6 +22079,9 @@ msgstr ""
msgid "Maintenance mode"
msgstr ""
+msgid "Make adjustments to how your GitLab instance is set up."
+msgstr ""
+
msgid "Make and review changes in the browser with the Web IDE"
msgstr ""
@@ -21734,6 +22226,12 @@ msgstr ""
msgid "MarkdownEditor|Add italic text (%{modifier_key}I)"
msgstr ""
+msgid "MarkdownEditor|Add strikethrough text (%{modifierKey}⇧X)"
+msgstr ""
+
+msgid "MarkdownEditor|Add strikethrough text (%{modifier_key}⇧X)"
+msgstr ""
+
msgid "Marked For Deletion At - %{deletion_time}"
msgstr ""
@@ -21995,6 +22493,9 @@ msgstr ""
msgid "Maximum push size (MB)"
msgstr ""
+msgid "Maximum requests per 10 minutes per user"
+msgstr ""
+
msgid "Maximum requests per minute"
msgstr ""
@@ -22085,6 +22586,17 @@ msgstr ""
msgid "Members of a group may only view projects they have permission to access"
msgstr ""
+msgid "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seat in use and will be billed for the overage."
+msgid_plural "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seats in use and will be billed for the overage."
+msgstr[0] ""
+
+msgid "MembersOverage|You are about to incur additional charges"
+msgstr ""
+
+msgid "MembersOverage|Your subscription includes %d seat."
+msgid_plural "MembersOverage|Your subscription includes %d seats."
+msgstr[0] ""
+
msgid "Membership"
msgstr ""
@@ -22289,9 +22801,6 @@ msgstr ""
msgid "Merge request not merged"
msgstr ""
-msgid "Merge request pipelines 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 merge request pipelines."
-msgstr ""
-
msgid "Merge request reports"
msgstr ""
@@ -22388,13 +22897,13 @@ msgstr ""
msgid "MergeRequests|Create issue to resolve thread"
msgstr ""
-msgid "MergeRequests|Failed to squash. Should be done manually."
+msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Saving the comment failed"
+msgid "MergeRequests|Squashing failed: Squash the commits locally, resolve any conflicts, then push the branch."
msgstr ""
-msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
+msgid "MergeRequests|Squashing not allowed: This project doesn't allow you to squash commits when merging."
msgstr ""
msgid "MergeRequests|Thread stays resolved"
@@ -23233,6 +23742,18 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "MrList|Assigned to %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from assignee %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from reviewer %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Review requested from %{name}, go to their profile."
+msgstr ""
+
msgid "Multi-project"
msgstr ""
@@ -23266,7 +23787,7 @@ msgstr ""
msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "My Awesome Group"
+msgid "My awesome group"
msgstr ""
msgid "My company or team"
@@ -23886,9 +24407,6 @@ msgstr ""
msgid "No available branches"
msgstr ""
-msgid "No available groups to fork the project."
-msgstr ""
-
msgid "No branches found"
msgstr ""
@@ -24099,6 +24617,9 @@ msgstr ""
msgid "No ref selected"
msgstr ""
+msgid "No regions configured"
+msgstr ""
+
msgid "No related merge requests found."
msgstr ""
@@ -24897,6 +25418,9 @@ msgstr ""
msgid "Only reCAPTCHA v2 is supported:"
msgstr ""
+msgid "Only required if not using role instance credentials."
+msgstr ""
+
msgid "Only use lowercase letters, numbers, and underscores."
msgstr ""
@@ -24921,9 +25445,6 @@ msgstr ""
msgid "Open a CLI and connect to the cluster you want to install the agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
-msgid "Open epics"
-msgstr ""
-
msgid "Open errors"
msgstr ""
@@ -24963,7 +25484,7 @@ msgstr ""
msgid "Opened issues"
msgstr ""
-msgid "OpenedNDaysAgo|Opened"
+msgid "OpenedNDaysAgo|Created"
msgstr ""
msgid "Opens in a new window"
@@ -25008,9 +25529,6 @@ msgstr ""
msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
-msgid "Optional."
-msgstr ""
-
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
msgstr ""
@@ -25798,6 +26316,9 @@ msgstr ""
msgid "PerformanceBar|Memory"
msgstr ""
+msgid "PerformanceBar|Memory report"
+msgstr ""
+
msgid "PerformanceBar|Redis calls"
msgstr ""
@@ -25831,18 +26352,12 @@ msgstr ""
msgid "PerformanceBar|wall"
msgstr ""
-msgid "Performs a rebase but skips triggering a new pipeline"
-msgstr ""
-
msgid "Period in seconds"
msgstr ""
msgid "Permalink"
msgstr ""
-msgid "Permanently delete project"
-msgstr ""
-
msgid "Permanently remove group"
msgstr ""
@@ -26113,6 +26628,51 @@ msgstr ""
msgid "PipelineStatusTooltip|Pipeline: %{ci_status}"
msgstr ""
+msgid "PipelineWizardDefaultCommitMessage|Add %{filename}"
+msgstr ""
+
+msgid "PipelineWizardDefaultCommitMessage|Update %{filename}"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|At least one entry is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This field is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This value is not valid"
+msgstr ""
+
+msgid "PipelineWizardListWidget|add another step"
+msgstr ""
+
+msgid "PipelineWizardListWidget|remove step"
+msgstr ""
+
+msgid "PipelineWizard|Commit"
+msgstr ""
+
+msgid "PipelineWizard|Commit Message"
+msgstr ""
+
+msgid "PipelineWizard|Commit changes to your file"
+msgstr ""
+
+msgid "PipelineWizard|Commit file to Branch"
+msgstr ""
+
+msgid "PipelineWizard|Commit your new file"
+msgstr ""
+
+msgid "PipelineWizard|The file has been committed."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem committing the changes."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem while checking whether your file already exists in the specified branch."
+msgstr ""
+
msgid "Pipelines"
msgstr ""
@@ -26227,7 +26787,7 @@ msgstr ""
msgid "Pipelines|Project cache successfully reset."
msgstr ""
-msgid "Pipelines|Revoke"
+msgid "Pipelines|Revoke trigger"
msgstr ""
msgid "Pipelines|Something went wrong while cleaning runners cache."
@@ -26272,6 +26832,12 @@ msgstr ""
msgid "Pipelines|This is a child pipeline within the parent pipeline"
msgstr ""
+msgid "Pipelines|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipelines|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipelines|This pipeline will run code originating from a forked project merge request. This means that the code can potentially have security considerations like exposing CI variables."
msgstr ""
@@ -26314,9 +26880,6 @@ msgstr ""
msgid "Pipelines|Your changes have been successfully committed. Now redirecting to the new merge request page."
msgstr ""
-msgid "Pipelines|detached"
-msgstr ""
-
msgid "Pipelines|error"
msgstr ""
@@ -26326,10 +26889,13 @@ msgstr ""
msgid "Pipelines|latest"
msgstr ""
-msgid "Pipelines|stuck"
+msgid "Pipelines|merge request"
msgstr ""
-msgid "Pipelines|train"
+msgid "Pipelines|merge train"
+msgstr ""
+
+msgid "Pipelines|stuck"
msgstr ""
msgid "Pipelines|yaml invalid"
@@ -26461,6 +27027,12 @@ msgstr ""
msgid "Pipeline|This change will not change the overall test coverage if merged."
msgstr ""
+msgid "Pipeline|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipeline|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipeline|Trigger author"
msgstr ""
@@ -26485,6 +27057,12 @@ msgstr ""
msgid "Pipeline|for"
msgstr ""
+msgid "Pipeline|merge request"
+msgstr ""
+
+msgid "Pipeline|merge train"
+msgstr ""
+
msgid "Pipeline|on"
msgstr ""
@@ -26623,9 +27201,6 @@ msgstr ""
msgid "Please enter a valid time interval"
msgstr ""
-msgid "Please enter or upload a valid license."
-msgstr ""
-
msgid "Please enter your current password."
msgstr ""
@@ -26734,9 +27309,6 @@ msgstr ""
msgid "Please type %{phrase_code} to proceed or close this modal to cancel."
msgstr ""
-msgid "Please type the following to confirm:"
-msgstr ""
-
msgid "Please use this form to report to the admin users who create spam issues, comments or behave inappropriately."
msgstr ""
@@ -26764,12 +27336,27 @@ msgstr ""
msgid "Policies"
msgstr ""
+msgid "Policy '%{escalation_policy_name}' does not exist."
+msgstr ""
+
msgid "Policy management project does have any policies in %{policy_path}"
msgstr ""
msgid "Policy project doesn't exist"
msgstr ""
+msgid "PolicyRuleMultiSelect|%{firstLabel} +%{numberOfAdditionalLabels} more"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|All %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select all"
+msgstr ""
+
msgid "Polling interval multiplier"
msgstr ""
@@ -26998,6 +27585,9 @@ msgstr ""
msgid "Private projects can be created in your personal namespace with:"
msgstr ""
+msgid "Problem with %{name} command: %{message}."
+msgstr ""
+
msgid "Proceed"
msgstr ""
@@ -27472,6 +28062,9 @@ msgstr ""
msgid "Progress"
msgstr ""
+msgid "Progress tracking"
+msgstr ""
+
msgid "Project"
msgstr ""
@@ -27703,6 +28296,9 @@ msgstr ""
msgid "ProjectQualitySummary|Failure"
msgstr ""
+msgid "ProjectQualitySummary|Get insight into the overall percentage of tests in your project that succeed, fail and are skipped."
+msgstr ""
+
msgid "ProjectQualitySummary|Latest pipeline results"
msgstr ""
@@ -27721,6 +28317,12 @@ msgstr ""
msgid "ProjectQualitySummary|See project Code Coverage Statistics"
msgstr ""
+msgid "ProjectQualitySummary|Set up test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|Set up test runs (opens in a new tab)"
+msgstr ""
+
msgid "ProjectQualitySummary|Skipped"
msgstr ""
@@ -27997,13 +28599,19 @@ msgstr ""
msgid "ProjectSettings|LFS objects from this repository are available to forks. %{linkStart}How do I remove them?%{linkEnd}"
msgstr ""
+msgid "ProjectSettings|Learn about commit history."
+msgstr ""
+
+msgid "ProjectSettings|Leave empty to use default template."
+msgstr ""
+
msgid "ProjectSettings|Manage who can see the project in the public access directory."
msgstr ""
msgid "ProjectSettings|Manages large files such as audio, video, and graphics files."
msgstr ""
-msgid "ProjectSettings|Maximum 500 characters."
+msgid "ProjectSettings|Maximum %{maxLength} characters."
msgstr ""
msgid "ProjectSettings|Merge checks"
@@ -28144,6 +28752,9 @@ msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
msgstr ""
+msgid "ProjectSettings|The default template will be applied on save."
+msgstr ""
+
msgid "ProjectSettings|These checks must pass before merge requests can be merged."
msgstr ""
@@ -28198,6 +28809,9 @@ msgstr ""
msgid "ProjectSettings|What are badges?"
msgstr ""
+msgid "ProjectSettings|What are merge trains?"
+msgstr ""
+
msgid "ProjectSettings|When merge request pipelines are enabled in the CI/CD configuration file, pipelines validate the combined results of the source and target branches. %{link_start}How to configure merge request pipelines?%{link_end}"
msgstr ""
@@ -28315,6 +28929,9 @@ msgstr ""
msgid "Projects are organized into groups"
msgstr ""
+msgid "Projects are where you store your code, access issues, wiki and other features of GitLab."
+msgstr ""
+
msgid "Projects contributed to"
msgstr ""
@@ -28330,12 +28947,6 @@ msgstr ""
msgid "Projects to index"
msgstr ""
-msgid "Projects will be permanently deleted after a %{waiting_period}-day waiting period."
-msgstr ""
-
-msgid "Projects will be permanently deleted immediately."
-msgstr ""
-
msgid "Projects with critical vulnerabilities"
msgstr ""
@@ -28420,6 +29031,9 @@ msgstr ""
msgid "ProjectsNew|Import project"
msgstr ""
+msgid "ProjectsNew|Include a Getting Started README"
+msgstr ""
+
msgid "ProjectsNew|Initialize repository with a README"
msgstr ""
@@ -28435,6 +29049,9 @@ msgstr ""
msgid "ProjectsNew|Project description %{tag_start}(optional)%{tag_end}"
msgstr ""
+msgid "ProjectsNew|Recommended if you're new to GitLab"
+msgstr ""
+
msgid "ProjectsNew|Run CI/CD for external repository"
msgstr ""
@@ -28852,6 +29469,9 @@ msgstr ""
msgid "ProtectedBranch|Unprotect"
msgstr ""
+msgid "ProtectedBranch|Unprotect branch"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
@@ -28879,6 +29499,9 @@ msgstr ""
msgid "ProtectedEnvironment|Protected Environment (%{protected_environments_count})"
msgstr ""
+msgid "ProtectedEnvironment|Required approvals"
+msgstr ""
+
msgid "ProtectedEnvironment|Select an environment"
msgstr ""
@@ -28900,10 +29523,13 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|Unprotect tag"
+msgstr ""
+
msgid "ProtectedTags|default"
msgstr ""
-msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
+msgid "ProtectedTag|By default, protected tags restrict who can modify the tag."
msgstr ""
msgid "ProtectedTag|Learn more."
@@ -28966,6 +29592,9 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Public projects are an easy way to allow everyone to have read-only access."
+msgstr ""
+
msgid "Publish to status page"
msgstr ""
@@ -29122,9 +29751,6 @@ msgstr ""
msgid "QualitySummary|Project quality"
msgstr ""
-msgid "Quarters"
-msgstr ""
-
msgid "Query"
msgstr ""
@@ -29209,6 +29835,9 @@ msgstr ""
msgid "Read more about project permissions %{help_link_open}here%{help_link_close}"
msgstr ""
+msgid "Read more about related epics"
+msgstr ""
+
msgid "Read more about related issues"
msgstr ""
@@ -29239,10 +29868,7 @@ msgstr ""
msgid "Rebase source branch on the target branch."
msgstr ""
-msgid "Rebase without CI"
-msgstr ""
-
-msgid "Rebases and triggers a pipeline"
+msgid "Rebase without pipeline"
msgstr ""
msgid "Recaptcha verified?"
@@ -29293,9 +29919,6 @@ msgstr ""
msgid "Reconfigure"
msgstr ""
-msgid "Recovering projects"
-msgstr ""
-
msgid "Recovery Codes"
msgstr ""
@@ -29354,6 +29977,12 @@ msgstr ""
msgid "Regex pattern"
msgstr ""
+msgid "Region"
+msgstr ""
+
+msgid "Regions"
+msgstr ""
+
msgid "Register"
msgstr ""
@@ -29583,9 +30212,6 @@ msgstr ""
msgid "Remove all or specific reviewer(s)"
msgstr ""
-msgid "Remove approver"
-msgstr ""
-
msgid "Remove approvers"
msgstr ""
@@ -29601,6 +30227,9 @@ msgstr ""
msgid "Remove attention request"
msgstr ""
+msgid "Remove attention request(s)"
+msgstr ""
+
msgid "Remove avatar"
msgstr ""
@@ -29739,6 +30368,9 @@ msgstr ""
msgid "Removed an issue from an epic."
msgstr ""
+msgid "Removed attention from %{users_sentence}."
+msgstr ""
+
msgid "Removed attention request from @%{username}"
msgstr ""
@@ -29790,6 +30422,9 @@ msgstr ""
msgid "Removes an issue from an epic."
msgstr ""
+msgid "Removes attention from %{users_sentence}."
+msgstr ""
+
msgid "Removes parent epic %{epic_ref}."
msgstr ""
@@ -29901,6 +30536,9 @@ msgstr ""
msgid "Report abuse to admin"
msgstr ""
+msgid "Report is generating and will be sent to your email address."
+msgstr ""
+
msgid "Reported %{timeAgo} by %{reportedBy}"
msgstr ""
@@ -30185,6 +30823,15 @@ msgstr ""
msgid "Request attention"
msgstr ""
+msgid "Request attention from %{users_sentence}."
+msgstr ""
+
+msgid "Request attention from assignee or reviewer"
+msgstr ""
+
+msgid "Request attention from assignee(s) or reviewer(s)"
+msgstr ""
+
msgid "Request attention to review"
msgstr ""
@@ -30209,6 +30856,9 @@ msgstr ""
msgid "Requested %{time_ago}"
msgstr ""
+msgid "Requested attention from %{users_sentence}."
+msgstr ""
+
msgid "Requested attention from @%{username}"
msgstr ""
@@ -30421,6 +31071,9 @@ msgstr ""
msgid "Restore project"
msgstr ""
+msgid "Restoring projects"
+msgstr ""
+
msgid "Restoring the group will prevent the group, its subgroups and projects from being removed on this date."
msgstr ""
@@ -30451,6 +31104,9 @@ msgstr ""
msgid "Retry"
msgstr ""
+msgid "Retry failed jobs"
+msgstr ""
+
msgid "Retry job"
msgstr ""
@@ -30497,9 +31153,6 @@ msgstr ""
msgid "Review changes"
msgstr ""
-msgid "Review requested from %{name}"
-msgstr ""
-
msgid "Review requests for you"
msgstr ""
@@ -30663,6 +31316,9 @@ msgstr ""
msgid "Runners|Assigned Group"
msgstr ""
+msgid "Runners|Assigned Projects (%{projectCount})"
+msgstr ""
+
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30732,6 +31388,9 @@ msgstr ""
msgid "Runners|Instance"
msgstr ""
+msgid "Runners|Jobs"
+msgstr ""
+
msgid "Runners|Last contact"
msgstr ""
@@ -30825,9 +31484,6 @@ msgstr ""
msgid "Runners|Runner %{name} was deleted"
msgstr ""
-msgid "Runners|Runner ID"
-msgstr ""
-
msgid "Runners|Runner assigned to project."
msgstr ""
@@ -30975,6 +31631,9 @@ msgstr ""
msgid "Runners|stale"
msgstr ""
+msgid "Runner|This runner has not run any jobs."
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -31089,6 +31748,24 @@ msgstr ""
msgid "Saving project."
msgstr ""
+msgid "ScanResultPolicy|%{ifLabelStart}if%{ifLabelEnd} %{scanners} scan in an open merge request targeting the %{branches} branch(es) finds %{vulnerabilitiesAllowed} or more %{severities} vulnerabilities that are %{vulnerabilityStates}"
+msgstr ""
+
+msgid "ScanResultPolicy|%{thenLabelStart}Then%{thenLabelEnd} Require approval from %{approvalsRequired} of the following approvers: %{approvers}"
+msgstr ""
+
+msgid "ScanResultPolicy|add an approver"
+msgstr ""
+
+msgid "ScanResultPolicy|scanners"
+msgstr ""
+
+msgid "ScanResultPolicy|severity levels"
+msgstr ""
+
+msgid "ScanResultPolicy|vulnerability states"
+msgstr ""
+
msgid "Scanner"
msgstr ""
@@ -31221,6 +31898,9 @@ msgstr ""
msgid "Search for a user"
msgstr ""
+msgid "Search for an emoji"
+msgstr ""
+
msgid "Search for projects, issues, etc."
msgstr ""
@@ -31397,18 +32077,12 @@ msgstr ""
msgid "Secret Detection"
msgstr ""
-msgid "Secret access key"
-msgstr ""
-
msgid "Secret token"
msgstr ""
msgid "Secure token that identifies an external storage request."
msgstr ""
-msgid "SecureCodeWarrior"
-msgstr ""
-
msgid "Security"
msgstr ""
@@ -31433,9 +32107,6 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "Security training with guide and learning pathways."
-msgstr ""
-
msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
@@ -31538,7 +32209,7 @@ msgstr ""
msgid "SecurityConfiguration|Manage corpus"
msgstr ""
-msgid "SecurityConfiguration|Manage corpus files used as mutation sources in coverage fuzzing."
+msgid "SecurityConfiguration|Manage corpus files used as seed inputs with coverage-guided fuzzing."
msgstr ""
msgid "SecurityConfiguration|Manage profiles for use by DAST scans."
@@ -31604,15 +32275,15 @@ msgstr ""
msgid "SecurityOrchestration|.yaml preview"
msgstr ""
-msgid "SecurityOrchestration|Action"
-msgstr ""
-
msgid "SecurityOrchestration|Actions"
msgstr ""
msgid "SecurityOrchestration|Add rule"
msgstr ""
+msgid "SecurityOrchestration|After dismissing the alert, the information will never be shown again."
+msgstr ""
+
msgid "SecurityOrchestration|All policies"
msgstr ""
@@ -31628,7 +32299,7 @@ msgstr ""
msgid "SecurityOrchestration|Description"
msgstr ""
-msgid "SecurityOrchestration|Disabled"
+msgid "SecurityOrchestration|Don't show the alert anymore"
msgstr ""
msgid "SecurityOrchestration|Edit policy"
@@ -31637,13 +32308,13 @@ msgstr ""
msgid "SecurityOrchestration|Edit policy project"
msgstr ""
-msgid "SecurityOrchestration|Enabled"
+msgid "SecurityOrchestration|Empty policy name"
msgstr ""
-msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Enabled"
msgstr ""
-msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
msgstr ""
msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
@@ -31652,7 +32323,7 @@ msgstr ""
msgid "SecurityOrchestration|Invalid policy type"
msgstr ""
-msgid "SecurityOrchestration|Latest scan"
+msgid "SecurityOrchestration|Latest scan run against %{agent}"
msgstr ""
msgid "SecurityOrchestration|Network"
@@ -31661,15 +32332,27 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No actions defined - policy will not run."
+msgstr ""
+
+msgid "SecurityOrchestration|No description"
+msgstr ""
+
msgid "SecurityOrchestration|No rules defined - policy will not run."
msgstr ""
+msgid "SecurityOrchestration|Not enabled"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
msgid "SecurityOrchestration|Policies"
msgstr ""
+msgid "SecurityOrchestration|Policy Type"
+msgstr ""
+
msgid "SecurityOrchestration|Policy cannot be enabled for non-existing branches (%{branches})"
msgstr ""
@@ -31694,10 +32377,13 @@ msgstr ""
msgid "SecurityOrchestration|Require %{approvals} %{plural} from %{approvers} if any of the following occur:"
msgstr ""
-msgid "SecurityOrchestration|Rule"
+msgid "SecurityOrchestration|Rules"
msgstr ""
-msgid "SecurityOrchestration|Rules"
+msgid "SecurityOrchestration|Runs %{actions} and %{lastAction} scans"
+msgstr ""
+
+msgid "SecurityOrchestration|Runs a %{action} scan"
msgstr ""
msgid "SecurityOrchestration|Scan Execution"
@@ -31757,6 +32443,9 @@ msgstr ""
msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
+msgid "SecurityOrchestration|This view only shows scan results for the agent %{agent}. You can view scan results for all agents in the %{linkStart}Operational Vulnerabilities tab of the vulnerability report%{linkEnd}."
+msgstr ""
+
msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
@@ -31811,9 +32500,6 @@ msgstr ""
msgid "SecurityOrchestration|users with ids"
msgstr ""
-msgid "SecurityOrchestration|view results"
-msgstr ""
-
msgid "SecurityOrchestration|vulnerabilities"
msgstr ""
@@ -32483,22 +33169,19 @@ 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|In order to start using functions as a service, you must first install Knative on your Kubernetes cluster. %{linkStart}More information%{linkEnd}"
-msgstr ""
-
msgid "Serverless|Learn more about Serverless"
msgstr ""
msgid "Serverless|No functions available"
msgstr ""
-msgid "Serverless|Sign up for First Look"
+msgid "Serverless|Serverless was %{linkStart}deprecated%{linkEnd} in GitLab 14.3."
+msgstr ""
+
+msgid "Serverless|Serverless was %{postLinkStart}deprecated%{postLinkEnd}. But if you opt to use it, you must install Knative in your Kubernetes cluster first. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "Serverless|The deploy job has not finished."
@@ -32510,9 +33193,6 @@ 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 ""
@@ -32528,9 +33208,6 @@ msgstr ""
msgid "Service Account Key"
msgstr ""
-msgid "Service Accounts"
-msgstr ""
-
msgid "Service Accounts keys authorize GitLab to deploy your Google Cloud project"
msgstr ""
@@ -32540,10 +33217,10 @@ msgstr ""
msgid "Service Desk allows people to create issues in your GitLab instance without their own user account. It provides a unique email address for end users to create issues in a project. Replies can be sent either through the GitLab interface or by email. End users only see threads through email."
msgstr ""
-msgid "Service Usage Data"
+msgid "Service account generated successfully"
msgstr ""
-msgid "Service account generated successfully"
+msgid "Service accounts"
msgstr ""
msgid "Service ping is disabled in your configuration file, and cannot be enabled through this form."
@@ -32687,6 +33364,9 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
+msgid "Set the per-user rate limit for getting a user by ID via the API."
+msgstr ""
+
msgid "Set the per-user rate limit for notes created by web or API requests."
msgstr ""
@@ -32865,6 +33545,9 @@ msgstr ""
msgid "Shared runners details"
msgstr ""
+msgid "Shared runners enabled cannot be enabled until a valid credit card is on file"
+msgstr ""
+
msgid "Shared runners help link"
msgstr ""
@@ -32922,6 +33605,9 @@ msgstr ""
msgid "Show all issues."
msgstr ""
+msgid "Show all milestones"
+msgstr ""
+
msgid "Show all test cases."
msgstr ""
@@ -32958,6 +33644,9 @@ msgstr ""
msgid "Show file contents"
msgstr ""
+msgid "Show group milestones"
+msgstr ""
+
msgid "Show labels"
msgstr ""
@@ -32973,6 +33662,12 @@ msgstr ""
msgid "Show open epics"
msgstr ""
+msgid "Show project milestones"
+msgstr ""
+
+msgid "Show sub-group milestones"
+msgstr ""
+
msgid "Show the Closed list"
msgstr ""
@@ -32982,10 +33677,6 @@ msgstr ""
msgid "Show whitespace changes"
msgstr ""
-msgid "Showing %d event"
-msgid_plural "Showing %d events"
-msgstr[0] ""
-
msgid "Showing %{conflict} between %{sourceBranch} and %{targetBranch}"
msgstr ""
@@ -33044,12 +33735,6 @@ msgstr ""
msgid "Sidebar|None"
msgstr ""
-msgid "Sidebar|Only numeral characters allowed"
-msgstr ""
-
-msgid "Sidebar|Weight"
-msgstr ""
-
msgid "Sidekiq job compression threshold (bytes)"
msgstr ""
@@ -33212,6 +33897,9 @@ msgstr ""
msgid "Slack logo"
msgstr ""
+msgid "SlackIntegration|Are you sure you want to remove this project from the Slack application?"
+msgstr ""
+
msgid "SlackIntegration|GitLab for Slack"
msgstr ""
@@ -33221,6 +33909,9 @@ msgstr ""
msgid "SlackIntegration|Project alias"
msgstr ""
+msgid "SlackIntegration|Remove project"
+msgstr ""
+
msgid "SlackIntegration|Select a GitLab project to link with your Slack workspace."
msgstr ""
@@ -33365,9 +34056,6 @@ msgstr ""
msgid "Something went wrong trying to load issue contacts."
msgstr ""
-msgid "Something went wrong when creating a work item. Please try again"
-msgstr ""
-
msgid "Something went wrong when reordering designs. Please try again"
msgstr ""
@@ -33461,9 +34149,6 @@ msgstr ""
msgid "Something went wrong while inserting your image. Please try again."
msgstr ""
-msgid "Something went wrong while merging this merge request. Please try again."
-msgstr ""
-
msgid "Something went wrong while obtaining the Let's Encrypt certificate."
msgstr ""
@@ -33785,10 +34470,10 @@ 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."
+msgid "SourcegraphAdmin|Learn more."
msgstr ""
-msgid "SourcegraphAdmin|More information"
+msgid "SourcegraphAdmin|Only public projects have code intelligence enabled and communicate with Sourcegraph."
msgstr ""
msgid "SourcegraphAdmin|Save changes"
@@ -33797,7 +34482,7 @@ msgstr ""
msgid "SourcegraphAdmin|Sourcegraph URL"
msgstr ""
-msgid "SourcegraphAdmin|e.g. https://sourcegraph.example.com"
+msgid "SourcegraphAdmin|https://sourcegraph.example.com"
msgstr ""
msgid "SourcegraphPreferences|This feature is experimental and currently limited to certain projects."
@@ -33932,6 +34617,9 @@ msgstr ""
msgid "Start date"
msgstr ""
+msgid "Start free trial"
+msgstr ""
+
msgid "Start merge train"
msgstr ""
@@ -33962,6 +34650,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started escalation for this incident."
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -33974,6 +34665,9 @@ msgstr ""
msgid "Starts at (UTC)"
msgstr ""
+msgid "Starts escalations for this incident"
+msgstr ""
+
msgid "Starts on"
msgstr ""
@@ -34235,6 +34929,9 @@ msgstr ""
msgid "Strikethrough"
msgstr ""
+msgid "Strikethrough text"
+msgstr ""
+
msgid "Subgroup information"
msgstr ""
@@ -34469,6 +35166,21 @@ msgstr ""
msgid "Subscriptions"
msgstr ""
+msgid "Subscriptions|Chat with sales"
+msgstr ""
+
+msgid "Subscriptions|Close"
+msgstr ""
+
+msgid "Subscriptions|Not ready to buy yet?"
+msgstr ""
+
+msgid "Subscriptions|Start a free trial"
+msgstr ""
+
+msgid "Subscriptions|We understand. Maybe you have some questions for our sales team, or maybe you'd like to try some of the paid features first. What would you like to do?"
+msgstr ""
+
msgid "Subscription|Your subscription for %{strong}%{namespace_name}%{strong_close} has expired and you are now on %{pricing_link_start}the GitLab Free tier%{pricing_link_end}. Don't worry, your data is safe. Get in touch with our support team (%{support_email}). They'll gladly help with your subscription renewal."
msgstr ""
@@ -34679,6 +35391,9 @@ msgstr ""
msgid "SuperSonics|Maximum users"
msgstr ""
+msgid "SuperSonics|Offline cloud"
+msgstr ""
+
msgid "SuperSonics|Paste your activation code"
msgstr ""
@@ -34745,6 +35460,12 @@ msgstr ""
msgid "SuperSonics|You do not have an active subscription"
msgstr ""
+msgid "SuperSonics|You have a future dated license"
+msgstr ""
+
+msgid "SuperSonics|You have added a license that activates on %{date}. Please see the subscription history table below for more details."
+msgstr ""
+
msgid "SuperSonics|You have successfully added a license that activates on %{date}. Please see the subscription history table below for more details."
msgstr ""
@@ -34904,6 +35625,9 @@ msgstr ""
msgid "Tag name is required"
msgstr ""
+msgid "Tag push"
+msgstr ""
+
msgid "Tag push events"
msgstr ""
@@ -35006,6 +35730,9 @@ msgstr ""
msgid "TagsPage|protected"
msgstr ""
+msgid "Take a look at the documentation to discover all of GitLab’s capabilities."
+msgstr ""
+
msgid "Target Branch"
msgstr ""
@@ -35402,6 +36129,9 @@ msgstr ""
msgid "Tests"
msgstr ""
+msgid "Text (optional)"
+msgstr ""
+
msgid "Text added to the body of all email messages. %{character_limit} character limit"
msgstr ""
@@ -35451,6 +36181,9 @@ msgstr ""
msgid "The CSV export will be created in the background. Once finished, it will be sent to %{email} in an attachment."
msgstr ""
+msgid "The CSV export you requested of all user memberships is attached to this email."
+msgstr ""
+
msgid "The GitLab subscription service (customers.gitlab.com) is currently experiencing an outage. You can monitor the status and get updates at %{linkStart}status.gitlab.com%{linkEnd}."
msgstr ""
@@ -35526,6 +36259,9 @@ 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 epic"
+msgstr ""
+
msgid "The current issue"
msgstr ""
@@ -35686,6 +36422,9 @@ msgstr ""
msgid "The latest pipeline for this merge request has failed."
msgstr ""
+msgid "The license key is invalid."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -35701,6 +36440,9 @@ msgstr ""
msgid "The license was successfully uploaded and will be active from %{starts_at}. You can see the details below."
msgstr ""
+msgid "The license you uploaded is invalid. If the issue persists, contact support at %{link}."
+msgstr ""
+
msgid "The list creation wizard is already open"
msgstr ""
@@ -36322,10 +37064,13 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} and everything this project contains. %{strongOpen}There is no going back%{strongClose}"
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}on %{date}%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains."
+msgstr ""
+
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains. %{strongOpen}There is no going back.%{strongClose}"
msgstr ""
msgid "This action will %{strongOpen}permanently remove%{strongClose} %{codeOpen}%{group}%{codeClose} %{strongOpen}immediately%{strongClose}."
@@ -36454,9 +37199,6 @@ msgstr ""
msgid "This file was modified for readability, and can't accept suggestions. Edit it directly."
msgstr ""
-msgid "This forked project has the following:"
-msgstr ""
-
msgid "This form is disabled in preview"
msgstr ""
@@ -36469,7 +37211,7 @@ msgstr ""
msgid "This group can't be removed because it is linked to a subscription. To remove this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
-msgid "This group can't be transfered because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
+msgid "This group can't be transferred because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
msgid "This group cannot be invited to a project inside a group with enforced SSO"
@@ -36496,6 +37238,9 @@ 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 incident is already escalated with '%{escalation_policy_name}'."
+msgstr ""
+
msgid "This invitation was sent to %{mail_to_invite_email}, but you are signed in as %{link_to_current_user} with email %{mail_to_current_user}."
msgstr ""
@@ -36514,9 +37259,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 merge train pipeline"
-msgstr ""
-
msgid "This is a private email address %{helpIcon} generated just for you. Anyone who has it can create issues or merge requests as if they were you. If that happens, %{resetLinkStart}reset this token%{resetLinkEnd}."
msgstr ""
@@ -36538,6 +37280,12 @@ msgstr ""
msgid "This is your current session"
msgstr ""
+msgid "This issue cannot be assigned to a confidential epic because it is public."
+msgstr ""
+
+msgid "This issue cannot be made public because it belongs to a confidential epic."
+msgstr ""
+
msgid "This issue is confidential and should only be visible to team members with at least Reporter access."
msgstr ""
@@ -36655,6 +37403,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 branch is protected from force push."
+msgstr ""
+
msgid "This merge request cannot be rebased while there are conflicts."
msgstr ""
@@ -36706,9 +37457,15 @@ msgstr ""
msgid "This pipeline was triggered by a schedule."
msgstr ""
+msgid "This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project"
msgstr ""
+msgid "This project can be restored until %{date}."
+msgstr ""
+
msgid "This project cannot be %{visibilityLevel} because the visibility of %{openShowLink}%{name}%{closeShowLink} is %{visibility}. To make this project %{visibilityLevel}, you must first %{openEditLink}change the visibility%{closeEditLink} of the parent group."
msgstr ""
@@ -36727,6 +37484,9 @@ msgstr ""
msgid "This project is %{strongStart}NOT%{strongEnd} a fork, and has the following:"
msgstr ""
+msgid "This project is %{strongStart}NOT%{strongEnd} a fork. This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -37416,6 +38176,9 @@ msgstr ""
msgid "Today"
msgstr ""
+msgid "Todos count"
+msgstr ""
+
msgid "Todos|Are you looking for things to do? Take a look at %{strongStart}%{openIssuesLinkStart}open issues%{openIssuesLinkEnd}%{strongEnd}, contribute to %{strongStart}%{mergeRequestLinkStart}a merge request%{mergeRequestLinkEnd}%{mergeRequestLinkEnd}%{strongEnd}, or mention someone in a comment to automatically assign them a new to-do item."
msgstr ""
@@ -37689,9 +38452,8 @@ msgstr ""
msgid "Trending"
msgstr ""
-msgid "Trials|%{planName} Trial %{enDash} %{num} day left"
-msgid_plural "Trials|%{planName} Trial %{enDash} %{num} days left"
-msgstr[0] ""
+msgid "Trials|%{planName} Trial"
+msgstr ""
msgid "Trials|Compare all plans"
msgstr ""
@@ -37699,6 +38461,9 @@ msgstr ""
msgid "Trials|Create a new group to start your GitLab Ultimate trial."
msgstr ""
+msgid "Trials|Day %{daysUsed}/%{duration}"
+msgstr ""
+
msgid "Trials|Go back to GitLab"
msgstr ""
@@ -37948,7 +38713,7 @@ msgstr ""
msgid "URL is triggered when repository is updated"
msgstr ""
-msgid "URL must be percent-encoded if neccessary."
+msgid "URL must be percent-encoded if necessary."
msgstr ""
msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
@@ -38167,6 +38932,9 @@ msgstr ""
msgid "Unlock account"
msgstr ""
+msgid "Unlock more features with GitLab Ultimate"
+msgstr ""
+
msgid "Unlock the discussion"
msgstr ""
@@ -38230,6 +38998,9 @@ msgstr ""
msgid "Unsubscribes from this %{quick_action_target}."
msgstr ""
+msgid "Unsupported sort value."
+msgstr ""
+
msgid "Unsupported todo type passed. Supported todo types are: %{todo_types}"
msgstr ""
@@ -38458,6 +39229,9 @@ msgstr ""
msgid "UsageQuota|File attachments and smaller design graphics."
msgstr ""
+msgid "UsageQuota|From %{storage_enforcement_date} storage limits will apply to this namespace. View and manage your usage in %{strong_start}Group Settings &gt; Usage quotas%{strong_end}."
+msgstr ""
+
msgid "UsageQuota|Git repository."
msgstr ""
@@ -38518,6 +39292,9 @@ msgstr ""
msgid "UsageQuota|Storage type"
msgstr ""
+msgid "UsageQuota|Storage used"
+msgstr ""
+
msgid "UsageQuota|This is the total amount of storage used across your projects within this namespace."
msgstr ""
@@ -38713,6 +39490,12 @@ msgstr ""
msgid "Use hashed storage paths for newly created and renamed repositories. Always enabled since 13.0."
msgstr ""
+msgid "Use issue count"
+msgstr ""
+
+msgid "Use issue weight"
+msgstr ""
+
msgid "Use one line per URI"
msgstr ""
@@ -39094,6 +39877,9 @@ msgstr ""
msgid "Users"
msgstr ""
+msgid "Users API rate limit"
+msgstr ""
+
msgid "Users can launch a development environment from a GitLab browser tab when the %{linkStart}Gitpod%{linkEnd} integration is enabled."
msgstr ""
@@ -39417,6 +40203,9 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View group pipeline usage quota"
+msgstr ""
+
msgid "View incident details at"
msgstr ""
@@ -39568,6 +40357,9 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
+msgid "Vulnerability"
+msgstr ""
+
msgid "Vulnerability Report"
msgstr ""
@@ -39619,6 +40411,9 @@ msgstr ""
msgid "VulnerabilityManagement|An unverified non-confirmed finding"
msgstr ""
+msgid "VulnerabilityManagement|At least one identifier is required"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -39628,12 +40423,24 @@ msgstr ""
msgid "VulnerabilityManagement|Create Jira issue"
msgstr ""
+msgid "VulnerabilityManagement|Enter a name"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE code"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE identifier URL"
+msgstr ""
+
msgid "VulnerabilityManagement|Fetching linked Jira issues"
msgstr ""
msgid "VulnerabilityManagement|Manually add a vulnerability entry into the vulnerability report."
msgstr ""
+msgid "VulnerabilityManagement|Name is a required field"
+msgstr ""
+
msgid "VulnerabilityManagement|Needs triage"
msgstr ""
@@ -39649,6 +40456,18 @@ msgstr ""
msgid "VulnerabilityManagement|Select a method"
msgstr ""
+msgid "VulnerabilityManagement|Select a severity level"
+msgstr ""
+
+msgid "VulnerabilityManagement|Select a status"
+msgstr ""
+
+msgid "VulnerabilityManagement|Severity is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Something went wrong while creating vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -39673,6 +40492,12 @@ msgstr ""
msgid "VulnerabilityManagement|Something went wrong, could not update vulnerability state."
msgstr ""
+msgid "VulnerabilityManagement|Status is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Submit vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Summary, detailed description, steps to reproduce, etc."
msgstr ""
@@ -39868,6 +40693,9 @@ msgstr ""
msgid "WARNING:"
msgstr ""
+msgid "WARNING: This snippet contains hidden files which might be used to mask malicious behavior. Exercise caution if cloning and executing code from this snippet."
+msgstr ""
+
msgid "Wait for the file to load to copy its contents"
msgstr ""
@@ -40087,6 +40915,15 @@ msgstr ""
msgid "Webhooks|An issue is created, updated, closed, or reopened."
msgstr ""
+msgid "Webhooks|Are you sure you want to delete this group hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this project hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this webhook?"
+msgstr ""
+
msgid "Webhooks|Comments"
msgstr ""
@@ -40096,6 +40933,9 @@ msgstr ""
msgid "Webhooks|Confidential issues events"
msgstr ""
+msgid "Webhooks|Delete webhook"
+msgstr ""
+
msgid "Webhooks|Deployment events"
msgstr ""
@@ -40328,6 +41168,9 @@ msgstr ""
msgid "Wiki"
msgstr ""
+msgid "Wiki page"
+msgstr ""
+
msgid "Wiki page was successfully created."
msgstr ""
@@ -40433,7 +41276,7 @@ msgstr ""
msgid "WikiPageConflictMessage|Someone edited the page the same time you did. Please check out %{wikiLinkStart}the page%{wikiLinkEnd} and make sure your changes will not unintentionally remove theirs."
msgstr ""
-msgid "WikiPage|An error occured while trying to render the content editor. Please try again later."
+msgid "WikiPage|An error occurred while trying to render the content editor. Please try again later."
msgstr ""
msgid "WikiPage|Are you sure you want to switch back to the classic editor?"
@@ -40592,6 +41435,18 @@ msgstr ""
msgid "WorkItem|New Task"
msgstr ""
+msgid "WorkItem|Something went wrong when creating a work item. Please try again"
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching the work item. Please try again."
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching work item types. Please try again"
+msgstr ""
+
+msgid "WorkItem|Type"
+msgstr ""
+
msgid "WorkItem|Work Items"
msgstr ""
@@ -40658,7 +41513,10 @@ msgstr ""
msgid "You are about to add %{usersTag} people to the discussion. They will all receive a notification."
msgstr ""
-msgid "You are about to permanently delete this project"
+msgid "You are about to delete this forked project containing:"
+msgstr ""
+
+msgid "You are about to delete this project containing:"
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."
@@ -40679,6 +41537,9 @@ msgstr ""
msgid "You are attempting to update a file that has changed since you started editing it."
msgstr ""
+msgid "You are billed if you exceed this number. %{qsrOverageLinkStart}How does billing work?%{qsrOverageLinkEnd}"
+msgstr ""
+
msgid "You are connected to the Prometheus server, but there is currently no data to display."
msgstr ""
@@ -40736,6 +41597,9 @@ msgstr ""
msgid "You are not authorized to update this scanner profile"
msgstr ""
+msgid "You are not authorized to upload metric images"
+msgstr ""
+
msgid "You are now impersonating %{username}"
msgstr ""
@@ -40889,9 +41753,6 @@ msgstr ""
msgid "You can only upload one design when dropping onto an existing design."
msgstr ""
-msgid "You can recover this project until %{date}"
-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 ""
@@ -40940,9 +41801,6 @@ msgstr ""
msgid "You cannot write to this read-only GitLab instance."
msgstr ""
-msgid "You can’t %{tag_start}edit%{tag_end} files directly in this project. Fork this project and submit a merge request with your changes."
-msgstr ""
-
msgid "You can’t edit files directly in this project. Fork this project and submit a merge request with your changes."
msgstr ""
@@ -41094,9 +41952,6 @@ 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 set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
@@ -41127,12 +41982,6 @@ msgstr ""
msgid "You must have maintainer access to force delete a lock"
msgstr ""
-msgid "You must have permission to create a project in a group before forking."
-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 ""
@@ -41538,7 +42387,7 @@ msgstr ""
msgid "Your public email will be displayed on your public profile."
msgstr ""
-msgid "Your request for access could not be processed: %{error_meesage}"
+msgid "Your request for access could not be processed: %{error_message}"
msgstr ""
msgid "Your request for access has been queued for review."
@@ -41718,6 +42567,9 @@ msgstr ""
msgid "archived:"
msgstr ""
+msgid "artifacts"
+msgstr ""
+
msgid "assign yourself"
msgstr ""
@@ -41746,6 +42598,9 @@ msgstr[0] ""
msgid "branch name"
msgstr ""
+msgid "builds"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -42166,6 +43021,9 @@ msgstr ""
msgid "contact with same email already exists in group hierarchy"
msgstr ""
+msgid "container registry images"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -42205,6 +43063,9 @@ msgstr ""
msgid "data"
msgstr ""
+msgid "database"
+msgstr ""
+
msgid "date must not be after 9999-12-31"
msgstr ""
@@ -42227,9 +43088,6 @@ msgstr ""
msgid "design"
msgstr ""
-msgid "detached"
-msgstr ""
-
msgid "disabled"
msgstr ""
@@ -42474,7 +43332,7 @@ msgstr ""
msgid "is not a valid X509 certificate."
msgstr ""
-msgid "is not allowed for sign-up."
+msgid "is not allowed for sign-up. Please use your regular email address."
msgstr ""
msgid "is not allowed for this group."
@@ -42486,7 +43344,7 @@ msgstr ""
msgid "is not allowed since the group is not top-level group."
msgstr ""
-msgid "is not allowed."
+msgid "is not allowed. Please use your regular email address."
msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
@@ -42573,6 +43431,9 @@ msgstr ""
msgid "level: %{level}"
msgstr ""
+msgid "lfs objects"
+msgstr ""
+
msgid "limit of %{project_limit} reached"
msgstr ""
@@ -42789,6 +43650,9 @@ msgstr ""
msgid "mrWidget|Merge blocked: pipeline must succeed. It's waiting for a manual action to continue."
msgstr ""
+msgid "mrWidget|Merge blocked: pipeline must succeed. Push a commit that fixes the failure, or %{linkStart}learn about other solutions.%{linkEnd}"
+msgstr ""
+
msgid "mrWidget|Merge blocked: this merge request must be approved."
msgstr ""
@@ -42906,9 +43770,6 @@ msgstr ""
msgid "mrWidget|The changes were not merged into"
msgstr ""
-msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -43056,9 +43917,6 @@ msgstr ""
msgid "open issue"
msgstr ""
-msgid "opened %{timeAgo}"
-msgstr ""
-
msgid "or"
msgstr ""
@@ -43069,6 +43927,12 @@ msgid "out of %d total test"
msgid_plural "out of %d total tests"
msgstr[0] ""
+msgid "packages"
+msgstr ""
+
+msgid "pages"
+msgstr ""
+
msgid "parent"
msgid_plural "parents"
msgstr[0] ""
@@ -43214,6 +44078,9 @@ msgid "reply"
msgid_plural "replies"
msgstr[0] ""
+msgid "repositories"
+msgstr ""
+
msgid "repository:"
msgstr ""
@@ -43334,12 +44201,18 @@ msgstr ""
msgid "tag name"
msgstr ""
+msgid "terraform states"
+msgstr ""
+
msgid "the correct format."
msgstr ""
msgid "the file"
msgstr ""
+msgid "the following epic(s)"
+msgstr ""
+
msgid "the following issue(s)"
msgstr ""
@@ -43352,21 +44225,12 @@ msgstr ""
msgid "this document"
msgstr ""
-msgid "this issue cannot be assigned to a confidential epic since it is public"
-msgstr ""
-
-msgid "this issue cannot be made public since it belongs to a confidential epic"
-msgstr ""
-
msgid "time summary"
msgstr ""
msgid "toggle collapse"
msgstr ""
-msgid "train"
-msgstr ""
-
msgid "triggered"
msgstr ""
@@ -43494,3 +44358,6 @@ msgstr ""
msgid "{project}"
msgstr ""
+msgid "✔"
+msgstr ""
+
diff --git a/locale/is_IS/gitlab.po b/locale/is_IS/gitlab.po
index 6efb1cc76b9..5eb703620d9 100644
--- a/locale/is_IS/gitlab.po
+++ b/locale/is_IS/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: is\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2022-02-02 15:43\n"
+"PO-Revision-Date: 2022-03-01 20:37\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -146,6 +146,11 @@ msgid_plural "%d approvers (you've approved)"
msgstr[0] ""
msgstr[1] ""
+msgid "%d assigned issue"
+msgid_plural "%d assigned issues"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -421,8 +426,23 @@ msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
msgstr[1] ""
-msgid "%d vulnerability updated"
-msgid_plural "%d vulnerabilities updated"
+msgid "%d vulnerability set to confirmed"
+msgid_plural "%d vulnerabilities set to confirmed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to dismissed"
+msgid_plural "%d vulnerabilities set to dismissed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to needs triage"
+msgid_plural "%d vulnerabilities set to needs triage"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to resolved"
+msgid_plural "%d vulnerabilities set to resolved"
msgstr[0] ""
msgstr[1] ""
@@ -510,6 +530,12 @@ msgstr[1] ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{completed} of %{total} issues closed"
+msgstr ""
+
+msgid "%{completed} of %{total} weight completed"
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -858,6 +884,9 @@ msgstr ""
msgid "%{openedIssues} open, %{closedIssues} closed"
msgstr ""
+msgid "%{percentage}%% issues closed"
+msgstr ""
+
msgid "%{percentage}%% weight completed"
msgstr ""
@@ -1287,6 +1316,9 @@ msgid_plural "- Users"
msgstr[0] ""
msgstr[1] ""
+msgid "- of - issues closed"
+msgstr ""
+
msgid "- of - weight completed"
msgstr ""
@@ -1429,7 +1461,7 @@ msgstr ""
msgid "1000+"
msgstr ""
-msgid "192.168.0.0/24"
+msgid "192.168.0.0/24 or 2001:0DB8:1234::/48"
msgstr ""
msgid "1st contribution!"
@@ -1741,13 +1773,13 @@ msgstr ""
msgid "AWS Access Key"
msgstr ""
-msgid "AWS Access Key. Only required if not using role instance credentials"
+msgid "AWS Secret Access Key"
msgstr ""
-msgid "AWS Secret Access Key"
+msgid "AWS access key ID (Optional)"
msgstr ""
-msgid "AWS Secret Access Key. Only required if not using role instance credentials"
+msgid "AWS secret access key (Optional)"
msgstr ""
msgid "AWS service error: %{error}"
@@ -1807,9 +1839,6 @@ msgstr ""
msgid "Access granted"
msgstr ""
-msgid "Access key ID"
-msgstr ""
-
msgid "Access requests"
msgstr ""
@@ -1984,7 +2013,7 @@ msgstr ""
msgid "Activity"
msgstr ""
-msgid "Activity|An error occured while retrieving activity. Reload the page to try again."
+msgid "Activity|An error occurred while retrieving activity. Reload the page to try again."
msgstr ""
msgid "Add"
@@ -2023,6 +2052,9 @@ msgstr ""
msgid "Add a %{type}"
msgstr ""
+msgid "Add a GCP region"
+msgstr ""
+
msgid "Add a GPG key"
msgstr ""
@@ -2074,6 +2106,9 @@ msgstr ""
msgid "Add a numbered list"
msgstr ""
+msgid "Add a related epic"
+msgstr ""
+
msgid "Add a related issue"
msgstr ""
@@ -2188,6 +2223,9 @@ msgstr ""
msgid "Add or subtract spent time"
msgstr ""
+msgid "Add people"
+msgstr ""
+
msgid "Add previously merged commits"
msgstr ""
@@ -2254,6 +2292,9 @@ msgstr ""
msgid "Add webhook"
msgstr ""
+msgid "Add your team members and others to GitLab."
+msgstr ""
+
msgid "Add/remove"
msgstr ""
@@ -3076,12 +3117,6 @@ msgstr ""
msgid "AdvancedSearch|Reindex required"
msgstr ""
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. Permanently deleting this project will %{strongStart}immediately delete%{strongEnd} its repositories and %{strongStart}all related resources%{strongEnd}, including issues, merge requests etc."
-msgstr ""
-
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. You will lose this project's repository and %{strongStart}all related resources%{strongEnd}, including issues and merge requests."
-msgstr ""
-
msgid "After a successful password update you will be redirected to login screen."
msgstr ""
@@ -3112,6 +3147,9 @@ msgstr ""
msgid "Akismet helps prevent the creation of spam issues in public projects."
msgstr ""
+msgid "Alert"
+msgstr ""
+
msgid "AlertManagement|Acknowledged"
msgstr ""
@@ -3484,9 +3522,6 @@ msgstr ""
msgid "All environments"
msgstr ""
-msgid "All epics"
-msgstr ""
-
msgid "All groups and projects"
msgstr ""
@@ -4223,12 +4258,15 @@ msgstr ""
msgid "ApplicationSettings|Approve users in the pending approval status?"
msgstr ""
-msgid "ApplicationSettings|By making this change, you will automatically approve %d user with the pending approval status."
-msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users with the pending approval status."
+msgid "ApplicationSettings|Approve users who are pending approval?"
+msgstr ""
+
+msgid "ApplicationSettings|By making this change, you will automatically approve %d user who is pending approval."
+msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users who are pending approval."
msgstr[0] ""
msgstr[1] ""
-msgid "ApplicationSettings|By making this change, you will automatically approve all users in pending approval status."
+msgid "ApplicationSettings|By making this change, you will automatically approve all users who are pending approval."
msgstr ""
msgid "ApplicationSettings|Denied domains for sign-ups"
@@ -4634,10 +4672,10 @@ msgstr ""
msgid "Archiving the project will make it entirely read-only. It is hidden from the dashboard and doesn't show up in searches. %{strong_start}The repository cannot be committed to, and no issues, comments, or other entities can be created.%{strong_end} %{link_start}Learn more.%{link_end}"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to delete this project?"
+msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
+msgid "Are you absolutely sure?"
msgstr ""
msgid "Are you sure that you want to archive this project?"
@@ -4673,12 +4711,18 @@ msgstr ""
msgid "Are you sure you want to delete this SSH key?"
msgstr ""
+msgid "Are you sure you want to delete this comment?"
+msgstr ""
+
msgid "Are you sure you want to delete this deploy key?"
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 label?"
+msgstr ""
+
msgid "Are you sure you want to delete this pipeline schedule?"
msgstr ""
@@ -4694,9 +4738,6 @@ msgstr ""
msgid "Are you sure you want to discard your changes?"
msgstr ""
-msgid "Are you sure you want to erase this build?"
-msgstr ""
-
msgid "Are you sure you want to import %d repository?"
msgid_plural "Are you sure you want to import %d repositories?"
msgstr[0] ""
@@ -4744,6 +4785,9 @@ msgstr ""
msgid "Are you sure you want to remove this list?"
msgstr ""
+msgid "Are you sure you want to remove this nickname?"
+msgstr ""
+
msgid "Are you sure you want to reset the health check token?"
msgstr ""
@@ -4756,10 +4800,10 @@ 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?"
+msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
msgstr ""
-msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
+msgid "Are you sure you want to revoke this project access token? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to stop this environment?"
@@ -4906,9 +4950,6 @@ msgstr ""
msgid "Assigned to %{assignee_name}"
msgstr ""
-msgid "Assigned to %{name}"
-msgstr ""
-
msgid "Assigned to me"
msgstr ""
@@ -4973,6 +5014,9 @@ msgstr[1] ""
msgid "Attaching the file failed."
msgstr ""
+msgid "Attention"
+msgstr ""
+
msgid "Audit Events"
msgstr ""
@@ -5135,6 +5179,12 @@ msgstr ""
msgid "Authorized applications (%{size})"
msgstr ""
+msgid "AuthorizedApplication|Are you sure you want to revoke this application?"
+msgstr ""
+
+msgid "AuthorizedApplication|Revoke application"
+msgstr ""
+
msgid "Authors: %{authors}"
msgstr ""
@@ -6328,6 +6378,9 @@ msgstr ""
msgid "CICDAnalytics|Shared Runners Usage"
msgstr ""
+msgid "CICDAnalytics|Shared runner pipeline minute duration by month"
+msgstr ""
+
msgid "CICDAnalytics|Shared runner usage"
msgstr ""
@@ -6469,6 +6522,9 @@ msgstr ""
msgid "Can create groups:"
msgstr ""
+msgid "Can not delete primary training"
+msgstr ""
+
msgid "Can't apply as the source branch was deleted."
msgstr ""
@@ -6802,9 +6858,6 @@ msgstr ""
msgid "Changing any setting here requires an application restart"
msgstr ""
-msgid "Changing group URL can have unintended side effects."
-msgstr ""
-
msgid "Charts can't be displayed as the request for data has timed out. %{documentationLink}"
msgstr ""
@@ -6892,9 +6945,6 @@ msgstr ""
msgid "Checking branch availability..."
msgstr ""
-msgid "Checking group URL availability..."
-msgstr ""
-
msgid "Checking group path availability..."
msgstr ""
@@ -7388,6 +7438,9 @@ msgstr ""
msgid "Clear recent searches"
msgstr ""
+msgid "Clear repository checks"
+msgstr ""
+
msgid "Clear search"
msgstr ""
@@ -7520,9 +7573,6 @@ msgstr ""
msgid "Closed MRs"
msgstr ""
-msgid "Closed epics"
-msgstr ""
-
msgid "Closed issues"
msgstr ""
@@ -7559,13 +7609,13 @@ msgstr ""
msgid "Cluster level"
msgstr ""
-msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
+msgid "Cluster type must be specified for Stages::ClusterEndpointInserter"
msgstr ""
msgid "ClusterAgents|%{name} successfully deleted"
msgstr ""
-msgid "ClusterAgents|%{number} of %{total} Agents"
+msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
@@ -7607,6 +7657,15 @@ msgstr ""
msgid "ClusterAgents|Agent never connected to GitLab"
msgstr ""
+msgid "ClusterAgents|Agent version mismatch"
+msgstr ""
+
+msgid "ClusterAgents|Agent version mismatch and update"
+msgstr ""
+
+msgid "ClusterAgents|Agent version update required"
+msgstr ""
+
msgid "ClusterAgents|All"
msgstr ""
@@ -7631,7 +7690,7 @@ msgstr ""
msgid "ClusterAgents|Configuration"
msgstr ""
-msgid "ClusterAgents|Connect a cluster through the Agent"
+msgid "ClusterAgents|Connect a cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connect existing cluster"
@@ -7640,13 +7699,13 @@ msgstr ""
msgid "ClusterAgents|Connect with a certificate"
msgstr ""
-msgid "ClusterAgents|Connect with agent"
+msgid "ClusterAgents|Connect with an agent"
msgstr ""
msgid "ClusterAgents|Connect with the GitLab Agent"
msgstr ""
-msgid "ClusterAgents|Connect your cluster through the Agent"
+msgid "ClusterAgents|Connect your cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connected"
@@ -7706,7 +7765,10 @@ msgstr ""
msgid "ClusterAgents|How to register an agent?"
msgstr ""
-msgid "ClusterAgents|Install new Agent"
+msgid "ClusterAgents|How to update an agent?"
+msgstr ""
+
+msgid "ClusterAgents|Install a new agent"
msgstr ""
msgid "ClusterAgents|Last connected %{timeAgo}."
@@ -7733,7 +7795,7 @@ msgstr ""
msgid "ClusterAgents|Never connected"
msgstr ""
-msgid "ClusterAgents|No Agents"
+msgid "ClusterAgents|No agents"
msgstr ""
msgid "ClusterAgents|No clusters connected through cluster certificates"
@@ -7793,6 +7855,9 @@ msgstr ""
msgid "ClusterAgents|The agent has not been connected in a long time. There might be a connectivity issue. Last contact was %{timeAgo}."
msgstr ""
+msgid "ClusterAgents|The agent version do not match each other across your cluster's pods. This can happen when a new agent version was just deployed and Kubernetes is shutting down the old pods."
+msgstr ""
+
msgid "ClusterAgents|The recommended installation method includes the token. If you want to follow the advanced installation method provided in the docs, make sure you save the token value before you close this window."
msgstr ""
@@ -7840,6 +7905,9 @@ msgstr ""
msgid "ClusterAgents|You will need to create a token to connect to your agent"
msgstr ""
+msgid "ClusterAgents|Your agent version is out of sync with your GitLab version (v%{version}), which might cause compatibility problems. Update the agent installed on your cluster to the most recent version."
+msgstr ""
+
msgid "ClusterAgents|Your instance doesn't have the %{linkStart}GitLab Agent Server (KAS)%{linkEnd} set up. Ask a GitLab Administrator to install it."
msgstr ""
@@ -8716,9 +8784,6 @@ msgstr ""
msgid "Comma-separated list of email addresses."
msgstr ""
-msgid "Comma-separated list of users allowed to exceed the rate limit."
-msgstr ""
-
msgid "Comma-separated, e.g. '1.1.1.1, 2.2.2.0/24'"
msgstr ""
@@ -9045,6 +9110,12 @@ msgstr ""
msgid "Confidential"
msgstr ""
+msgid "Confidential issue"
+msgstr ""
+
+msgid "Confidential note"
+msgstr ""
+
msgid "Confidentiality"
msgstr ""
@@ -9078,6 +9149,9 @@ msgstr ""
msgid "Configure Dependency Scanning in `.gitlab-ci.yml`, creating this file if it does not already exist"
msgstr ""
+msgid "Configure GitLab"
+msgstr ""
+
msgid "Configure GitLab runners to start using the Web Terminal. %{helpStart}Learn more.%{helpEnd}"
msgstr ""
@@ -9126,6 +9200,15 @@ msgstr ""
msgid "Configure pipelines to deploy web apps, backend services, APIs and static resources to Google Cloud"
msgstr ""
+msgid "Configure region"
+msgstr ""
+
+msgid "Configure region for environment"
+msgstr ""
+
+msgid "Configure regions"
+msgstr ""
+
msgid "Configure repository mirroring."
msgstr ""
@@ -9159,6 +9242,9 @@ msgstr ""
msgid "Configure which lists are shown for anyone who visits this board"
msgstr ""
+msgid "Configure your environments to be deployed to specific geographical regions"
+msgstr ""
+
msgid "Confirm"
msgstr ""
@@ -9861,10 +9947,10 @@ msgstr ""
msgid "CorpusManagement|Actions"
msgstr ""
-msgid "CorpusManagement|Corpus are used in fuzz testing as mutation source to Improve future testing."
+msgid "CorpusManagement|Corpus file"
msgstr ""
-msgid "CorpusManagement|Corpus file"
+msgid "CorpusManagement|Corpus files are used in coverage-guided fuzz testing as seed inputs to improve testing."
msgstr ""
msgid "CorpusManagement|Corpus files must be in *.zip format. Maximum 5 GB"
@@ -9918,6 +10004,9 @@ msgstr ""
msgid "Could not apply %{name} command."
msgstr ""
+msgid "Could not apply %{name} command. %{message}."
+msgstr ""
+
msgid "Could not authorize chat nickname. Try again!"
msgstr ""
@@ -10068,6 +10157,9 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
+msgid "Create a group"
+msgstr ""
+
msgid "Create a merge request"
msgstr ""
@@ -10092,6 +10184,9 @@ msgstr ""
msgid "Create a personal access token on your account to pull or push via %{protocol}."
msgstr ""
+msgid "Create a project"
+msgstr ""
+
msgid "Create an account using:"
msgstr ""
@@ -10455,6 +10550,9 @@ msgstr ""
msgid "Creation date"
msgstr ""
+msgid "Creator"
+msgstr ""
+
msgid "Credentials"
msgstr ""
@@ -10467,9 +10565,15 @@ msgstr ""
msgid "CredentialsInventory|Personal Access Tokens"
msgstr ""
+msgid "CredentialsInventory|Project Access Tokens"
+msgstr ""
+
msgid "CredentialsInventory|SSH Keys"
msgstr ""
+msgid "Credit card required to be on file in order to create a pipeline"
+msgstr ""
+
msgid "Credit card:"
msgstr ""
@@ -10653,9 +10757,6 @@ msgstr ""
msgid "Customer relations"
msgstr ""
-msgid "Customizable by an administrator."
-msgstr ""
-
msgid "Customizable by owners."
msgstr ""
@@ -10785,30 +10886,18 @@ msgstr ""
msgid "CycleAnalytics|%{selectedLabelsCount} selected (%{maxLabels} max)"
msgstr ""
-msgid "CycleAnalytics|%{stageCount} stages selected"
-msgstr ""
-
-msgid "CycleAnalytics|All stages"
-msgstr ""
-
-msgid "CycleAnalytics|Average days to completion"
+msgid "CycleAnalytics|Average time to completion"
msgstr ""
msgid "CycleAnalytics|Date"
msgstr ""
-msgid "CycleAnalytics|Days to completion"
-msgstr ""
-
msgid "CycleAnalytics|Display chart filters"
msgstr ""
msgid "CycleAnalytics|Lead Time for Changes"
msgstr ""
-msgid "CycleAnalytics|No stages selected"
-msgstr ""
-
msgid "CycleAnalytics|Number of tasks"
msgstr ""
@@ -10837,18 +10926,30 @@ msgstr ""
msgid "CycleAnalytics|Showing data for group '%{groupName}' from %{createdAfter} to %{createdBefore}"
msgstr ""
-msgid "CycleAnalytics|Stages"
+msgid "CycleAnalytics|Stage time: %{title}"
msgstr ""
msgid "CycleAnalytics|Tasks by type"
msgstr ""
-msgid "CycleAnalytics|The average time spent in the selected stage for the items that were completed on each date. Data limited to the last 500 items."
+msgid "CycleAnalytics|The average time items spent in this stage. Data limited to items completed within this date range."
msgstr ""
msgid "CycleAnalytics|The given date range is larger than 180 days"
msgstr ""
+msgid "CycleAnalytics|The total time items spent across each value stream stage. Data limited to items completed within this date range."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Stage time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Total time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|Total time"
+msgstr ""
+
msgid "CycleAnalytics|Type of work"
msgstr ""
@@ -10861,9 +10962,6 @@ msgstr ""
msgid "CycleAnalytics|project dropdown filter"
msgstr ""
-msgid "CycleAnalytics|stage dropdown"
-msgstr ""
-
msgid "DAG visualization requires at least 3 dependent jobs."
msgstr ""
@@ -10963,10 +11061,16 @@ msgstr ""
msgid "DastProfiles|AJAX spider"
msgstr ""
+msgid "DastProfiles|API"
+msgstr ""
+
+msgid "DastProfiles|API endpoint URL"
+msgstr ""
+
msgid "DastProfiles|Active"
msgstr ""
-msgid "DastProfiles|Additional request headers (Optional)"
+msgid "DastProfiles|Additional request headers (optional)"
msgstr ""
msgid "DastProfiles|Are you sure you want to delete this profile?"
@@ -10981,6 +11085,9 @@ msgstr ""
msgid "DastProfiles|Branch missing"
msgstr ""
+msgid "DastProfiles|Choose a scan method"
+msgstr ""
+
msgid "DastProfiles|Could not create the scanner profile. Please try again."
msgstr ""
@@ -11050,7 +11157,13 @@ msgstr ""
msgid "DastProfiles|Excluded URLs"
msgstr ""
-msgid "DastProfiles|Excluded URLs (Optional)"
+msgid "DastProfiles|Excluded URLs (optional)"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths (optional)"
msgstr ""
msgid "DastProfiles|Hide debug messages"
@@ -11107,9 +11220,6 @@ msgstr ""
msgid "DastProfiles|Request headers"
msgstr ""
-msgid "DastProfiles|Rest API"
-msgstr ""
-
msgid "DastProfiles|Run the AJAX spider, in addition to the traditional spider, to crawl the target site."
msgstr ""
@@ -11119,6 +11229,9 @@ msgstr ""
msgid "DastProfiles|Save profile"
msgstr ""
+msgid "DastProfiles|Scan method"
+msgstr ""
+
msgid "DastProfiles|Scan mode"
msgstr ""
@@ -11197,12 +11310,24 @@ msgstr ""
msgid "DastProfiles|Website"
msgstr ""
+msgid "DastProfiles|What does each method do?"
+msgstr ""
+
msgid "DastProfiles|You can either choose a passive scan or validate the target site from the site profile management page. %{docsLinkStart}Learn more about site validation.%{docsLinkEnd}"
msgstr ""
msgid "DastProfiles|You cannot run an active scan against an unvalidated site."
msgstr ""
+msgid "DastProfiles|folder/dast_example.har or https://example.com/dast_example.har"
+msgstr ""
+
+msgid "DastProfiles|folder/example.postman_collection.json or https://example.com/"
+msgstr ""
+
+msgid "DastProfiles|folder/openapi.json or https://example.com/openapi.json"
+msgstr ""
+
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
@@ -11310,6 +11435,9 @@ msgstr ""
msgid "DatadogIntegration|API URL"
msgstr ""
+msgid "DatadogIntegration|Custom tags in Datadog. Enter one tag per line in the %{codeOpen}key:value%{codeClose} format. %{linkOpen}How do I use tags?%{linkClose}"
+msgstr ""
+
msgid "DatadogIntegration|Environment"
msgstr ""
@@ -11328,12 +11456,18 @@ msgstr ""
msgid "DatadogIntegration|Tag all data from this GitLab instance in Datadog. Useful when managing several self-managed deployments."
msgstr ""
+msgid "DatadogIntegration|Tags"
+msgstr ""
+
msgid "DatadogIntegration|The Datadog site to send data to. To send data to the EU site, use %{codeOpen}datadoghq.eu%{codeClose}."
msgstr ""
msgid "DatadogIntegration|Trace your GitLab pipelines with Datadog."
msgstr ""
+msgid "DatadogIntegration|have an invalid format"
+msgstr ""
+
msgid "Datasource name not found"
msgstr ""
@@ -11343,9 +11477,6 @@ msgstr ""
msgid "Date merged"
msgstr ""
-msgid "Date picker"
-msgstr ""
-
msgid "Date range"
msgstr ""
@@ -11499,9 +11630,6 @@ msgstr ""
msgid "Definition"
msgstr ""
-msgid "Delayed Project Deletion (%{adjourned_deletion})"
-msgstr ""
-
msgid "DelayedJobs|Are you sure you want to run %{jobName} immediately? Otherwise this job will run automatically after its timer finishes."
msgstr ""
@@ -11580,10 +11708,10 @@ msgstr ""
msgid "Delete pipeline"
msgstr ""
-msgid "Delete project"
+msgid "Delete pipeline schedule"
msgstr ""
-msgid "Delete project. Are you ABSOLUTELY SURE?"
+msgid "Delete project"
msgstr ""
msgid "Delete row"
@@ -11613,6 +11741,9 @@ msgstr ""
msgid "Delete this epic and all descendants?"
msgstr ""
+msgid "Delete this project"
+msgstr ""
+
msgid "Delete user list"
msgstr ""
@@ -11871,6 +12002,12 @@ msgstr ""
msgid "Deploy to..."
msgstr ""
+msgid "DeployBoards|To see deployment progress for your environments, make sure you are deploying to %{codeStart}$KUBE_NAMESPACE%{codeEnd} and annotating with %{codeStart}app.gitlab.com/app=$CI_PROJECT_PATH_SLUG%{codeEnd} and %{codeStart}app.gitlab.com/env=$CI_ENVIRONMENT_SLUG%{codeEnd}."
+msgstr ""
+
+msgid "DeployBoard|Kubernetes Pods"
+msgstr ""
+
msgid "DeployFreeze|Add a freeze period to prevent unintended releases during a period of time for a given environment. You must update the deployment jobs in %{filename} according to the deploy freezes added here. %{freeze_period_link_start}Learn more.%{freeze_period_link_end}"
msgstr ""
@@ -11955,9 +12092,6 @@ msgstr ""
msgid "DeployTokens|Active Deploy Tokens (%{active_tokens})"
msgstr ""
-msgid "DeployTokens|Allows read and write access to registry images."
-msgstr ""
-
msgid "DeployTokens|Allows read and write access to the package registry."
msgstr ""
@@ -11970,6 +12104,9 @@ msgstr ""
msgid "DeployTokens|Allows read-only access to the repository."
msgstr ""
+msgid "DeployTokens|Allows write access to registry images."
+msgstr ""
+
msgid "DeployTokens|Copy deploy token"
msgstr ""
@@ -12063,12 +12200,57 @@ msgstr ""
msgid "Deploying to AWS is easy with GitLab"
msgstr ""
+msgid "Deployment"
+msgstr ""
+
msgid "Deployment Frequency"
msgstr ""
+msgid "Deployment Target|Project deployment target (optional)"
+msgstr ""
+
+msgid "Deployment Target|Select the deployment target"
+msgstr ""
+
msgid "Deployment frequency"
msgstr ""
+msgid "DeploymentTarget|GitLab Pages"
+msgstr ""
+
+msgid "DeploymentTarget|Heroku"
+msgstr ""
+
+msgid "DeploymentTarget|Infrastructure provider (Terraform, Cloudformation, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Kubernetes (GKE, EKS, OpenShift, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Managed container runtime (Fargate, Cloud Run, DigitalOcean App)"
+msgstr ""
+
+msgid "DeploymentTarget|Mobile app store"
+msgstr ""
+
+msgid "DeploymentTarget|No deployment planned"
+msgstr ""
+
+msgid "DeploymentTarget|Other hosting service"
+msgstr ""
+
+msgid "DeploymentTarget|Registry (package or container)"
+msgstr ""
+
+msgid "DeploymentTarget|Self-managed container runtime (Podman, Docker Swarm, Docker Compose)"
+msgstr ""
+
+msgid "DeploymentTarget|Serverless backend (Lambda, Cloud functions)"
+msgstr ""
+
+msgid "DeploymentTarget|Virtual machine (for example, EC2)"
+msgstr ""
+
msgid "Deployments"
msgstr ""
@@ -12107,6 +12289,9 @@ msgstr ""
msgid "Deployment|This deployment was created using the API"
msgstr ""
+msgid "Deployment|Triggerer"
+msgstr ""
+
msgid "Deployment|Waiting"
msgstr ""
@@ -12134,6 +12319,18 @@ msgstr ""
msgid "Deprecated API rate limits"
msgstr ""
+msgid "Deprecations|Feature deprecation and removal"
+msgstr ""
+
+msgid "Deprecations|For information on a possible replacement %{epicStart} learn more about Opstrace %{epicEnd}."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7 and are %{epicStart} scheduled for removal %{epicEnd} in GitLab 15.0."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7, and are %{removal_link_start} scheduled for removal %{link_end} in GitLab 15.0. For information on a possible replacement, %{opstrace_link_start} learn more about Opstrace %{link_end}."
+msgstr ""
+
msgid "Deprioritize label"
msgstr ""
@@ -12379,10 +12576,10 @@ msgstr ""
msgid "DevopsAdoption|At least one deploy"
msgstr ""
-msgid "DevopsAdoption|At least one issue opened"
+msgid "DevopsAdoption|At least one issue created"
msgstr ""
-msgid "DevopsAdoption|At least one merge request opened"
+msgid "DevopsAdoption|At least one merge request created"
msgstr ""
msgid "DevopsAdoption|At least one pipeline successfully run"
@@ -12583,6 +12780,9 @@ msgstr ""
msgid "Direct member"
msgstr ""
+msgid "Direct members"
+msgstr ""
+
msgid "Direct non-authenticated users to this page."
msgstr ""
@@ -12699,6 +12899,9 @@ msgid_plural "Dismiss %d selected vulnerabilities as"
msgstr[0] ""
msgstr[1] ""
+msgid "Dismiss Alert"
+msgstr ""
+
msgid "Dismiss merge request promotion"
msgstr ""
@@ -12726,9 +12929,15 @@ msgstr ""
msgid "Display alerts from all configured monitoring tools."
msgstr ""
+msgid "Display milestones"
+msgstr ""
+
msgid "Display name"
msgstr ""
+msgid "Display progress of child issues"
+msgstr ""
+
msgid "Display rendered file"
msgstr ""
@@ -12834,6 +13043,9 @@ msgstr ""
msgid "Download image"
msgstr ""
+msgid "Download payload"
+msgstr ""
+
msgid "Download raw data (.csv)"
msgstr ""
@@ -13011,6 +13223,9 @@ msgstr ""
msgid "Edit in Web IDE"
msgstr ""
+msgid "Edit in pipeline editor"
+msgstr ""
+
msgid "Edit in single-file editor"
msgstr ""
@@ -13053,6 +13268,9 @@ msgstr ""
msgid "Edit your most recent comment in a thread (from an empty textarea)"
msgstr ""
+msgid "Edit, lint, and visualize your pipeline."
+msgstr ""
+
msgid "Edited"
msgstr ""
@@ -13494,6 +13712,9 @@ msgstr ""
msgid "Enforce two-factor authentication for all user sign-ins."
msgstr ""
+msgid "Enhance security by storing service account keys in secret managers - learn more about %{docLinkStart}secret management with GitLab%{docLinkEnd}"
+msgstr ""
+
msgid "Ensure connectivity is available from the GitLab server to the Prometheus server"
msgstr ""
@@ -13554,6 +13775,9 @@ 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 following to confirm:"
+msgstr ""
+
msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
@@ -14084,9 +14308,6 @@ 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 ""
@@ -14222,6 +14443,9 @@ msgstr ""
msgid "Errors:"
msgstr ""
+msgid "Escalate this incident"
+msgstr ""
+
msgid "Escalation Policies"
msgstr ""
@@ -14234,6 +14458,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy"
+msgstr ""
+
msgid "Escalation policy:"
msgstr ""
@@ -14485,6 +14712,9 @@ msgstr ""
msgid "Existing sign in methods may be removed"
msgstr ""
+msgid "Exit."
+msgstr ""
+
msgid "Expand"
msgstr ""
@@ -14581,6 +14811,9 @@ msgstr ""
msgid "Explore public groups"
msgstr ""
+msgid "Explore public projects"
+msgstr ""
+
msgid "Explore snippets"
msgstr ""
@@ -14742,7 +14975,7 @@ msgid_plural "Failed to archive designs. Please try again."
msgstr[0] ""
msgstr[1] ""
-msgid "Failed to assign a reviewer because no user was found."
+msgid "Failed to assign a reviewer because no user was specified."
msgstr ""
msgid "Failed to assign a user because no user was found."
@@ -14808,10 +15041,10 @@ msgstr ""
msgid "Failed to find import label for Jira import."
msgstr ""
-msgid "Failed to generate export, please try again later."
+msgid "Failed to find users for %{missing}"
msgstr ""
-msgid "Failed to generate report, please try again after sometime"
+msgid "Failed to generate export, please try again later."
msgstr ""
msgid "Failed to get ref."
@@ -14910,6 +15143,9 @@ msgstr ""
msgid "Failed to remove a to-do item for the design."
msgstr ""
+msgid "Failed to remove attention because no user was found."
+msgstr ""
+
msgid "Failed to remove mirror."
msgstr ""
@@ -14922,6 +15158,9 @@ msgstr ""
msgid "Failed to remove user key."
msgstr ""
+msgid "Failed to request attention because no user was found."
+msgstr ""
+
msgid "Failed to reset key. Please try again."
msgstr ""
@@ -15003,6 +15242,9 @@ msgstr ""
msgid "Feature Flags"
msgstr ""
+msgid "Feature deprecation and removal"
+msgstr ""
+
msgid "Feature flag status"
msgstr ""
@@ -15500,7 +15742,7 @@ msgstr ""
msgid "For each job, re-use the project workspace. If the workspace doesn't exist, use %{code_open}git clone%{code_close}."
msgstr ""
-msgid "For example, the application using the token or the purpose of the token."
+msgid "For example, the application using the token or the purpose of the token. Do not give sensitive information for the name of the token, as it will be visible to all %{resource_type} members."
msgstr ""
msgid "For files larger than this limit, only index the file name. The file content is neither indexed nor searchable."
@@ -15584,9 +15826,6 @@ msgstr ""
msgid "ForkProject|Select a namespace"
msgstr ""
-msgid "ForkProject|Select a namespace to fork the project"
-msgstr ""
-
msgid "ForkProject|The project can be accessed by any logged in user."
msgstr ""
@@ -15683,6 +15922,9 @@ msgstr ""
msgid "Full name"
msgstr ""
+msgid "GCP region configured"
+msgstr ""
+
msgid "GPG Key ID:"
msgstr ""
@@ -15863,6 +16105,9 @@ msgstr ""
msgid "Geo|Failed"
msgstr ""
+msgid "Geo|Filter Geo sites"
+msgstr ""
+
msgid "Geo|Filter by name"
msgstr ""
@@ -16274,6 +16519,12 @@ msgstr ""
msgid "GitLab Issue"
msgstr ""
+msgid "GitLab KAS"
+msgstr ""
+
+msgid "GitLab Memberships CSV Export"
+msgstr ""
+
msgid "GitLab Pages"
msgstr ""
@@ -16322,6 +16573,9 @@ 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 free to use. Many features for larger teams are part of our %{link_start}paid products%{link_end}. You can try Ultimate for free without any obligation or payment details."
+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 ""
@@ -16448,7 +16702,7 @@ msgstr ""
msgid "GitLabPages|When enabled, all attempts to visit your website through HTTP are automatically redirected to HTTPS using a response with status code 301. Requires a valid certificate for all domains. %{docs_link_start}Learn more.%{link_end}"
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. %{docs_link_start}Learn more.%{link_end}"
+msgid "GitLabPages|When using Pages under the general domain of a GitLab instance (%{pages_host}), you cannot use HTTPS with subdomains of subdomains. If your namespace or groupname contains a dot, it does not work. This is a limitation of the HTTP Over TLS protocol. HTTP pages work if you don't redirect HTTP to HTTPS. %{docs_link_start}Learn more.%{link_end}"
msgstr ""
msgid "GitLabPages|With GitLab Pages you can host your static website directly from your GitLab repository. %{docs_link_start}Learn more.%{link_end}"
@@ -16625,9 +16879,6 @@ msgstr ""
msgid "Go to find file"
msgstr ""
-msgid "Go to fork"
-msgstr ""
-
msgid "Go to issue boards"
msgstr ""
@@ -16835,9 +17086,6 @@ msgstr ""
msgid "Group Hooks"
msgstr ""
-msgid "Group ID"
-msgstr ""
-
msgid "Group Owner must have signed in with SAML before enabling Group Managed Accounts"
msgstr ""
@@ -16865,9 +17113,6 @@ msgstr ""
msgid "Group by"
msgstr ""
-msgid "Group description"
-msgstr ""
-
msgid "Group description (optional)"
msgstr ""
@@ -16982,7 +17227,7 @@ msgstr ""
msgid "Group: %{name}"
msgstr ""
-msgid "GroupActivityMetrics|Issues opened"
+msgid "GroupActivityMetrics|Issues created"
msgstr ""
msgid "GroupActivityMetrics|Last 90 days"
@@ -16991,7 +17236,7 @@ msgstr ""
msgid "GroupActivityMetrics|Members added"
msgstr ""
-msgid "GroupActivityMetrics|Merge Requests opened"
+msgid "GroupActivityMetrics|Merge Requests created"
msgstr ""
msgid "GroupActivityMetrics|Recent activity"
@@ -17282,6 +17527,9 @@ msgstr ""
msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
+msgid "GroupSettings|Choose a group path that does not start with a dash or end with a period. It can also contain alphanumeric characters and underscores."
+msgstr ""
+
msgid "GroupSettings|Compliance frameworks"
msgstr ""
@@ -17315,7 +17563,7 @@ msgstr ""
msgid "GroupSettings|If not specified at the group or instance level, the default is %{default_initial_branch_name}. Does not affect existing repositories."
msgstr ""
-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."
+msgid "GroupSettings|If the parent group's visibility is lower than the group's current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility."
msgstr ""
msgid "GroupSettings|New runners registration token has been generated!"
@@ -17432,7 +17680,10 @@ msgstr ""
msgid "Groups and projects"
msgstr ""
-msgid "Groups and subgroups"
+msgid "Groups are a great way to organize projects and people."
+msgstr ""
+
+msgid "Groups are the best way to manage projects and members."
msgstr ""
msgid "Groups to synchronize"
@@ -17543,13 +17794,16 @@ msgstr ""
msgid "GroupsTree|Are you sure you want to leave the \"%{fullName}\" group?"
msgstr ""
-msgid "GroupsTree|Edit group"
+msgid "GroupsTree|Delete"
+msgstr ""
+
+msgid "GroupsTree|Edit"
msgstr ""
msgid "GroupsTree|Failed to leave the group. Please make sure you are not the only owner."
msgstr ""
-msgid "GroupsTree|Leave this group"
+msgid "GroupsTree|Leave group"
msgstr ""
msgid "GroupsTree|Loading groups"
@@ -17561,9 +17815,57 @@ msgstr ""
msgid "GroupsTree|No groups or projects matched your search"
msgstr ""
+msgid "GroupsTree|Options"
+msgstr ""
+
msgid "GroupsTree|Search by name"
msgstr ""
+msgid "Groups|Avatar will be removed. Are you sure?"
+msgstr ""
+
+msgid "Groups|Changing group URL can have unintended side effects."
+msgstr ""
+
+msgid "Groups|Checking group URL availability..."
+msgstr ""
+
+msgid "Groups|Enter a descriptive name for your group."
+msgstr ""
+
+msgid "Groups|Group ID"
+msgstr ""
+
+msgid "Groups|Group URL"
+msgstr ""
+
+msgid "Groups|Group avatar"
+msgstr ""
+
+msgid "Groups|Group description (optional)"
+msgstr ""
+
+msgid "Groups|Group name"
+msgstr ""
+
+msgid "Groups|Group path is available."
+msgstr ""
+
+msgid "Groups|Group path is unavailable. Path has been replaced with a suggested available path."
+msgstr ""
+
+msgid "Groups|Learn more"
+msgstr ""
+
+msgid "Groups|Must start with letter, digit, emoji, or underscore. Can also contain periods, dashes, spaces, and parentheses."
+msgstr ""
+
+msgid "Groups|Remove avatar"
+msgstr ""
+
+msgid "Groups|Save changes"
+msgstr ""
+
msgid "Guideline"
msgstr ""
@@ -17573,6 +17875,9 @@ msgstr ""
msgid "HAR file path or URL"
msgstr ""
+msgid "HTTP Archive (HAR)"
+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 ""
@@ -17973,6 +18278,9 @@ msgstr ""
msgid "INFO: Your SSH key is expiring soon. Please generate a new key."
msgstr ""
+msgid "IP"
+msgstr ""
+
msgid "IP Address"
msgstr ""
@@ -18009,6 +18317,9 @@ msgstr ""
msgid "IdentityVerification|Verify your identity"
msgstr ""
+msgid "IdentityVerification|You can always verify your account at a later time to create a group."
+msgstr ""
+
msgid "If any indexed field exceeds this limit, it is truncated to this number of characters. The rest of the content is neither indexed nor searchable. This does not apply to repository and wiki indexing. For unlimited characters, set this to 0."
msgstr ""
@@ -18066,6 +18377,9 @@ msgstr ""
msgid "If you add %{codeStart}needs%{codeEnd} to jobs in your pipeline you'll be able to view the %{codeStart}needs%{codeEnd} relationships between jobs in this tab as a %{linkStart}Directed Acyclic Graph (DAG)%{linkEnd}."
msgstr ""
+msgid "If you are added to a project, it will be displayed here."
+msgstr ""
+
msgid "If you did not initiate these sign-in attempts, please reach out to your administrator or enable two-factor authentication (2FA) on your account."
msgstr ""
@@ -18372,12 +18686,24 @@ msgstr ""
msgid "InProductMarketing|3 ways to dive into GitLab CI/CD"
msgstr ""
+msgid "InProductMarketing|A single application eliminates complex integrations, data chokepoints, and toolchain maintenance, resulting in greater productivity and lower cost."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features, build more efficiently, strengthen security and compliance."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features."
+msgstr ""
+
msgid "InProductMarketing|Actually, GitLab makes the team work (better)"
msgstr ""
msgid "InProductMarketing|And finally %{deploy_link} a Python application."
msgstr ""
+msgid "InProductMarketing|And many more..."
+msgstr ""
+
msgid "InProductMarketing|Are your runners ready?"
msgstr ""
@@ -18396,15 +18722,33 @@ msgstr ""
msgid "InProductMarketing|Blog"
msgstr ""
+msgid "InProductMarketing|Break down silos to coordinate seamlessly across development, operations, and security with a consistent experience across the development lifecycle."
+msgstr ""
+
+msgid "InProductMarketing|Burn up/down charts"
+msgstr ""
+
msgid "InProductMarketing|By enabling code owners and required merge approvals the right person will review the right MR. This is a win-win: cleaner code and a more efficient review process."
msgstr ""
msgid "InProductMarketing|Click on the number below that corresponds with your answer — 1 being very difficult, 5 being very easy."
msgstr ""
+msgid "InProductMarketing|Code owners"
+msgstr ""
+
msgid "InProductMarketing|Code owners and required merge approvals are part of the paid tiers of GitLab. You can start a free 30-day trial of GitLab Ultimate and enable these features in less than 5 minutes with no credit card required."
msgstr ""
+msgid "InProductMarketing|Code review analytics"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration across stages in GitLab"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration made easy"
+msgstr ""
+
msgid "InProductMarketing|Create a custom CI runner with just a few clicks"
msgstr ""
@@ -18414,12 +18758,21 @@ msgstr ""
msgid "InProductMarketing|Create a project in GitLab in 5 minutes"
msgstr ""
+msgid "InProductMarketing|Create well-defined workflows by using scoped labels on issues, merge requests, and epics. Labels with the same scope cannot be used together, which prevents conflicts."
+msgstr ""
+
msgid "InProductMarketing|Create your first project!"
msgstr ""
+msgid "InProductMarketing|Define who owns specific files or directories, so the right reviewers are suggested when a merge request introduces changes to those files."
+msgstr ""
+
msgid "InProductMarketing|Deliver Better Products Faster"
msgstr ""
+msgid "InProductMarketing|Dependency scanning"
+msgstr ""
+
msgid "InProductMarketing|Did you know teams that use GitLab are far more efficient?"
msgstr ""
@@ -18429,15 +18782,27 @@ msgstr ""
msgid "InProductMarketing|Dig in and create a project and a repo"
msgstr ""
+msgid "InProductMarketing|Discover Premium & Ultimate"
+msgstr ""
+
+msgid "InProductMarketing|Discover Premium & Ultimate."
+msgstr ""
+
msgid "InProductMarketing|Do you have a minute?"
msgstr ""
msgid "InProductMarketing|Do you have a teammate who would be perfect for this task?"
msgstr ""
+msgid "InProductMarketing|Dynamic application security testing"
+msgstr ""
+
msgid "InProductMarketing|Easy"
msgstr ""
+msgid "InProductMarketing|Epics"
+msgstr ""
+
msgid "InProductMarketing|Expand your DevOps journey with a free GitLab trial"
msgstr ""
@@ -18459,9 +18824,15 @@ msgstr ""
msgid "InProductMarketing|Feel the need for speed?"
msgstr ""
+msgid "InProductMarketing|Find and fix bottlenecks in your code review process by understanding how long open merge requests have been in review."
+msgstr ""
+
msgid "InProductMarketing|Find out how your teams are really doing"
msgstr ""
+msgid "InProductMarketing|Find out if your external libraries are safe. Run dependency scanning jobs that check for known vulnerabilities in your external libraries."
+msgstr ""
+
msgid "InProductMarketing|Follow our steps"
msgstr ""
@@ -18498,6 +18869,9 @@ msgstr ""
msgid "InProductMarketing|GitLab is better with teammates to help out!"
msgstr ""
+msgid "InProductMarketing|GitLab is infrastructure agnostic (supporting GCP, AWS, Azure, OpenShift, VMWare, On Prem, Bare Metal, and more), offering a consistent workflow experience – irrespective of the environment."
+msgstr ""
+
msgid "InProductMarketing|GitLab provides static application security testing (SAST), dynamic application security testing (DAST), container scanning, and dependency scanning to help you deliver secure applications along with license compliance."
msgstr ""
@@ -18588,21 +18962,36 @@ msgstr ""
msgid "InProductMarketing|It's also possible to simply %{external_repo_link} in order to take advantage of GitLab's CI/CD."
msgstr ""
+msgid "InProductMarketing|Keep your code quality high by defining who should approve merge requests and how many approvals are required."
+msgstr ""
+
msgid "InProductMarketing|Launch GitLab CI/CD in 20 minutes or less"
msgstr ""
+msgid "InProductMarketing|Lower cost of development"
+msgstr ""
+
+msgid "InProductMarketing|Make it easier to collaborate on high-level ideas by grouping related issues in an epic."
+msgstr ""
+
msgid "InProductMarketing|Making the switch? It's easier than you think to import your projects into GitLab. Move %{github_link}, or import something %{bitbucket_link}."
msgstr ""
msgid "InProductMarketing|Master the art of importing!"
msgstr ""
+msgid "InProductMarketing|Merge request approval rule"
+msgstr ""
+
msgid "InProductMarketing|Move on to easily creating a Pages website %{ci_template_link}"
msgstr ""
msgid "InProductMarketing|Multiple owners, confusing workstreams? We've got you covered"
msgstr ""
+msgid "InProductMarketing|Multiple required approvers"
+msgstr ""
+
msgid "InProductMarketing|Need an alternative to importing?"
msgstr ""
@@ -18615,18 +19004,33 @@ msgstr ""
msgid "InProductMarketing|Our tool brings all the things together"
msgstr ""
+msgid "InProductMarketing|Protect your web application by using DAST to examine for vulnerabilities in deployed environments."
+msgstr ""
+
msgid "InProductMarketing|Rapid development, simplified"
msgstr ""
msgid "InProductMarketing|Reduce Security & Compliance Risk"
msgstr ""
+msgid "InProductMarketing|Require multiple approvers on a merge request, so you know it's in good shape before it's merged."
+msgstr ""
+
+msgid "InProductMarketing|Roadmaps"
+msgstr ""
+
+msgid "InProductMarketing|Scoped labels"
+msgstr ""
+
msgid "InProductMarketing|Security that's integrated into your development lifecycle"
msgstr ""
msgid "InProductMarketing|Sometimes you're not ready to make a full transition to a new tool. If you're not ready to fully commit, %{mirroring_link} gives you a safe way to try out GitLab in parallel with your current tool."
msgstr ""
+msgid "InProductMarketing|Speed. Efficiency. Trust."
+msgstr ""
+
msgid "InProductMarketing|Spin up an autoscaling runner in GitLab"
msgstr ""
@@ -18636,6 +19040,9 @@ msgstr ""
msgid "InProductMarketing|Start a Self-Managed trial"
msgstr ""
+msgid "InProductMarketing|Start a free trial"
+msgstr ""
+
msgid "InProductMarketing|Start a free trial of GitLab Ultimate – no credit card required"
msgstr ""
@@ -18702,6 +19109,9 @@ msgstr ""
msgid "InProductMarketing|To understand and get the most out of GitLab, start at the beginning and %{project_link}. In GitLab, repositories are part of a project, so after you've created your project you can go ahead and %{repo_link}."
msgstr ""
+msgid "InProductMarketing|Track completed issues in a chart, so you can see how a milestone is progressing at a glance."
+msgstr ""
+
msgid "InProductMarketing|Try GitLab Ultimate for free"
msgstr ""
@@ -18738,6 +19148,9 @@ msgstr ""
msgid "InProductMarketing|Very easy"
msgstr ""
+msgid "InProductMarketing|Visualize your epics and milestones in a timeline."
+msgstr ""
+
msgid "InProductMarketing|Want to host GitLab on your servers?"
msgstr ""
@@ -18759,6 +19172,9 @@ msgstr ""
msgid "InProductMarketing|YouTube"
msgstr ""
+msgid "InProductMarketing|Your software, deployed your way"
+msgstr ""
+
msgid "InProductMarketing|Your teams can be more efficient"
msgstr ""
@@ -18879,9 +19295,18 @@ msgstr ""
msgid "IncidentManagement|No incidents to display."
msgstr ""
+msgid "IncidentManagement|None"
+msgstr ""
+
msgid "IncidentManagement|Open"
msgstr ""
+msgid "IncidentManagement|Page your team with escalation policies"
+msgstr ""
+
+msgid "IncidentManagement|Paged"
+msgstr ""
+
msgid "IncidentManagement|Published"
msgstr ""
@@ -18891,6 +19316,9 @@ msgstr ""
msgid "IncidentManagement|Severity"
msgstr ""
+msgid "IncidentManagement|Status"
+msgstr ""
+
msgid "IncidentManagement|There are no closed incidents"
msgstr ""
@@ -18909,6 +19337,9 @@ msgstr ""
msgid "IncidentManagement|Unpublished"
msgstr ""
+msgid "IncidentManagement|Use escalation policies to automatically page your team when incidents are created."
+msgstr ""
+
msgid "IncidentSettings|Activate \"time to SLA\" countdown timer"
msgstr ""
@@ -18954,7 +19385,10 @@ msgstr ""
msgid "Incidents"
msgstr ""
-msgid "Incidents|Add a URL"
+msgid "Incidents|Add image details"
+msgstr ""
+
+msgid "Incidents|Add text or a link to display with your image. If you don't add either, the file name displays instead."
msgstr ""
msgid "Incidents|Drop or %{linkStart}upload%{linkEnd} a metric screenshot to attach it to the incident"
@@ -18969,10 +19403,10 @@ msgstr ""
msgid "Incidents|There was an issue loading metric images."
msgstr ""
-msgid "Incidents|There was an issue uploading your image."
+msgid "Incidents|There was an issue updating your image."
msgstr ""
-msgid "Incidents|You can optionally add a URL to link users to the original graph."
+msgid "Incidents|There was an issue uploading your image."
msgstr ""
msgid "Incident|Alert details"
@@ -18981,9 +19415,18 @@ msgstr ""
msgid "Incident|Are you sure you wish to delete this image?"
msgstr ""
+msgid "Incident|Delete image"
+msgstr ""
+
msgid "Incident|Deleting %{filename}"
msgstr ""
+msgid "Incident|Edit image text or link"
+msgstr ""
+
+msgid "Incident|Editing %{filename}"
+msgstr ""
+
msgid "Incident|Metrics"
msgstr ""
@@ -19253,12 +19696,18 @@ msgstr ""
msgid "Integrations|Branches for which notifications are to be sent"
msgstr ""
+msgid "Integrations|Clear if using a self-signed certificate."
+msgstr ""
+
msgid "Integrations|Comment detail:"
msgstr ""
msgid "Integrations|Comment settings:"
msgstr ""
+msgid "Integrations|Connection details"
+msgstr ""
+
msgid "Integrations|Connection failed. Please check your settings."
msgstr ""
@@ -19283,6 +19732,9 @@ msgstr ""
msgid "Integrations|Enable GitLab.com slash commands in a Slack workspace."
msgstr ""
+msgid "Integrations|Enable SSL verification"
+msgstr ""
+
msgid "Integrations|Enable comments"
msgstr ""
@@ -19361,6 +19813,9 @@ msgstr ""
msgid "Integrations|Return to GitLab for Jira"
msgstr ""
+msgid "Integrations|SSL verification"
+msgstr ""
+
msgid "Integrations|Save settings?"
msgstr ""
@@ -19406,9 +19861,6 @@ msgstr ""
msgid "Integrations|Use default settings"
msgstr ""
-msgid "Integrations|When you mention a Jira issue in a commit or merge request, GitLab creates a remote link and comment (if enabled)."
-msgstr ""
-
msgid "Integrations|You can now close this window and return to the GitLab for Jira application."
msgstr ""
@@ -19433,9 +19885,6 @@ msgstr ""
msgid "Integrations|can't exceed %{recipients_limit}"
msgstr ""
-msgid "Interactive developer security education."
-msgstr ""
-
msgid "Interactive mode"
msgstr ""
@@ -19925,6 +20374,9 @@ msgstr ""
msgid "IssueAnalytics|Assignees"
msgstr ""
+msgid "IssueAnalytics|Created by"
+msgstr ""
+
msgid "IssueAnalytics|Due date"
msgstr ""
@@ -19937,9 +20389,6 @@ msgstr ""
msgid "IssueAnalytics|Milestone"
msgstr ""
-msgid "IssueAnalytics|Opened by"
-msgstr ""
-
msgid "IssueAnalytics|Status"
msgstr ""
@@ -20063,10 +20512,10 @@ msgstr ""
msgid "IssuesAnalytics|Avg/Month:"
msgstr ""
-msgid "IssuesAnalytics|Issues opened"
+msgid "IssuesAnalytics|Issues created"
msgstr ""
-msgid "IssuesAnalytics|Issues opened per month"
+msgid "IssuesAnalytics|Issues created per month"
msgstr ""
msgid "IssuesAnalytics|Last 12 months"
@@ -20093,6 +20542,9 @@ msgstr ""
msgid "It looks like you have some draft commits in this branch."
msgstr ""
+msgid "It looks like you're attempting to activate your subscription. Use %{a_start}the Subscription page%{a_end} instead."
+msgstr ""
+
msgid "It may be several days before you see feature usage data."
msgstr ""
@@ -20321,6 +20773,9 @@ msgstr ""
msgid "JiraConnect|You can now close this window and return to Jira."
msgstr ""
+msgid "JiraConnect|You don't have permission to create branches for this project. Select a different project or contact the project owner for access. %{linkStart}Learn more.%{linkEnd}"
+msgstr ""
+
msgid "JiraRequest|A connection error occurred while connecting to Jira. Try your request again."
msgstr ""
@@ -20369,13 +20824,13 @@ msgstr ""
msgid "JiraService|Define the type of Jira issue to create from a vulnerability."
msgstr ""
-msgid "JiraService|Displaying Jira issues while leaving the GitLab issue functionality enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
+msgid "JiraService|Displaying Jira issues while leaving GitLab issues also enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
msgstr ""
-msgid "JiraService|Enable Jira issues"
+msgid "JiraService|Enable Jira issue creation from vulnerabilities"
msgstr ""
-msgid "JiraService|Enable Jira issues creation from vulnerabilities"
+msgid "JiraService|Enable Jira issues"
msgstr ""
msgid "JiraService|Enable Jira transitions"
@@ -20492,16 +20947,19 @@ msgstr ""
msgid "JiraService|View Jira issues in GitLab"
msgstr ""
-msgid "JiraService|Warning: All GitLab users that have access to this GitLab project are able to view all issues from the Jira project specified below."
+msgid "JiraService|Warning: All GitLab users with access to this GitLab project can view all issues from the Jira project you select."
msgstr ""
msgid "JiraService|Web URL"
msgstr ""
-msgid "JiraService|Work on Jira issues without leaving GitLab. Adds a Jira menu to access your list of Jira issues and view any issue as read-only."
+msgid "JiraService|When a Jira issue is mentioned in a commit or merge request, a remote link and comment (if enabled) will be created."
+msgstr ""
+
+msgid "JiraService|Work on Jira issues without leaving GitLab. Add a Jira menu to access a read-only list of your Jira issues."
msgstr ""
-msgid "JiraService|You need to configure Jira before enabling this integration. For more details, read the %{jira_doc_link_start}Jira integration documentation%{link_end}."
+msgid "JiraService|You must configure Jira before enabling this integration. %{jira_doc_link_start}Learn more.%{link_end}"
msgstr ""
msgid "Job"
@@ -20513,9 +20971,6 @@ msgstr ""
msgid "Job Failed #%{build_id}"
msgstr ""
-msgid "Job ID"
-msgstr ""
-
msgid "Job artifact"
msgstr ""
@@ -20582,9 +21037,27 @@ msgstr ""
msgid "Jobs|You're about to retry a job that failed because it attempted to deploy code that is older than the latest deployment. Retrying this job could result in overwriting the environment with the older source code."
msgstr ""
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source} into %{target}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{ref}"
+msgstr ""
+
+msgid "Job|Are you sure you want to erase this job log and artifacts?"
+msgstr ""
+
msgid "Job|Browse"
msgstr ""
+msgid "Job|Cancel"
+msgstr ""
+
msgid "Job|Complete Raw"
msgstr ""
@@ -20594,6 +21067,9 @@ msgstr ""
msgid "Job|Erase job log and artifacts"
msgstr ""
+msgid "Job|Finished at"
+msgstr ""
+
msgid "Job|Job artifacts"
msgstr ""
@@ -20606,7 +21082,7 @@ msgstr ""
msgid "Job|Keep"
msgstr ""
-msgid "Job|Pipeline"
+msgid "Job|Retry"
msgstr ""
msgid "Job|Scroll to bottom"
@@ -20618,6 +21094,9 @@ msgstr ""
msgid "Job|Show complete raw"
msgstr ""
+msgid "Job|Status"
+msgstr ""
+
msgid "Job|The artifacts were removed"
msgstr ""
@@ -20645,21 +21124,12 @@ msgstr ""
msgid "Job|delayed"
msgstr ""
-msgid "Job|for"
-msgstr ""
-
-msgid "Job|into"
-msgstr ""
-
msgid "Job|manual"
msgstr ""
msgid "Job|triggered"
msgstr ""
-msgid "Job|with"
-msgstr ""
-
msgid "Join Zoom meeting"
msgstr ""
@@ -20762,9 +21232,6 @@ msgstr ""
msgid "Ki"
msgstr ""
-msgid "Kontra"
-msgstr ""
-
msgid "Kroki"
msgstr ""
@@ -21088,6 +21555,9 @@ msgstr ""
msgid "Learn more about Auto DevOps"
msgstr ""
+msgid "Learn more about GitLab"
+msgstr ""
+
msgid "Learn more about Needs relationships"
msgstr ""
@@ -21415,9 +21885,18 @@ msgstr ""
msgid "Licenses|Displays licenses detected in the project, based on the %{linkStart}latest successful%{linkEnd} scan"
msgstr ""
+msgid "Licenses|Drag your license file here or %{linkStart}click to upload%{linkEnd}."
+msgstr ""
+
+msgid "Licenses|Drop your license file to start the upload."
+msgstr ""
+
msgid "Licenses|Error fetching the license list. Please check your network connection and try again."
msgstr ""
+msgid "Licenses|Error: You are trying to upload something other than a file"
+msgstr ""
+
msgid "Licenses|License Compliance"
msgstr ""
@@ -21436,6 +21915,9 @@ msgstr ""
msgid "Licenses|Specified policies in this project"
msgstr ""
+msgid "Licenses|The file could not be uploaded."
+msgstr ""
+
msgid "Licenses|The license list details information about the licenses used within your project."
msgstr ""
@@ -21469,11 +21951,6 @@ msgstr ""
msgid "Limit the size of Sidekiq jobs stored in Redis."
msgstr ""
-msgid "Limited to showing %d event at most"
-msgid_plural "Limited to showing %d events at most"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Limiting mode"
msgstr ""
@@ -21483,6 +21960,9 @@ msgstr ""
msgid "Link"
msgstr ""
+msgid "Link (optional)"
+msgstr ""
+
msgid "Link Prometheus monitoring to GitLab."
msgstr ""
@@ -21519,6 +21999,9 @@ msgstr ""
msgid "Linked emails (%{email_count})"
msgstr ""
+msgid "Linked epics"
+msgstr ""
+
msgid "Linked issues"
msgstr ""
@@ -21546,6 +22029,15 @@ msgstr ""
msgid "List of all merge commits"
msgstr ""
+msgid "List of environments for this project"
+msgstr ""
+
+msgid "List of suitable GCP locations"
+msgstr ""
+
+msgid "List of users allowed to exceed the rate limit."
+msgstr ""
+
msgid "List options"
msgstr ""
@@ -21765,6 +22257,9 @@ msgstr ""
msgid "Maintenance mode"
msgstr ""
+msgid "Make adjustments to how your GitLab instance is set up."
+msgstr ""
+
msgid "Make and review changes in the browser with the Web IDE"
msgstr ""
@@ -21909,6 +22404,12 @@ msgstr ""
msgid "MarkdownEditor|Add italic text (%{modifier_key}I)"
msgstr ""
+msgid "MarkdownEditor|Add strikethrough text (%{modifierKey}⇧X)"
+msgstr ""
+
+msgid "MarkdownEditor|Add strikethrough text (%{modifier_key}⇧X)"
+msgstr ""
+
msgid "Marked For Deletion At - %{deletion_time}"
msgstr ""
@@ -22170,6 +22671,9 @@ msgstr ""
msgid "Maximum push size (MB)"
msgstr ""
+msgid "Maximum requests per 10 minutes per user"
+msgstr ""
+
msgid "Maximum requests per minute"
msgstr ""
@@ -22260,6 +22764,19 @@ msgstr ""
msgid "Members of a group may only view projects they have permission to access"
msgstr ""
+msgid "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seat in use and will be billed for the overage."
+msgid_plural "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seats in use and will be billed for the overage."
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "MembersOverage|You are about to incur additional charges"
+msgstr ""
+
+msgid "MembersOverage|Your subscription includes %d seat."
+msgid_plural "MembersOverage|Your subscription includes %d seats."
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Membership"
msgstr ""
@@ -22464,9 +22981,6 @@ msgstr ""
msgid "Merge request not merged"
msgstr ""
-msgid "Merge request pipelines 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 merge request pipelines."
-msgstr ""
-
msgid "Merge request reports"
msgstr ""
@@ -22563,13 +23077,13 @@ msgstr ""
msgid "MergeRequests|Create issue to resolve thread"
msgstr ""
-msgid "MergeRequests|Failed to squash. Should be done manually."
+msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Saving the comment failed"
+msgid "MergeRequests|Squashing failed: Squash the commits locally, resolve any conflicts, then push the branch."
msgstr ""
-msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
+msgid "MergeRequests|Squashing not allowed: This project doesn't allow you to squash commits when merging."
msgstr ""
msgid "MergeRequests|Thread stays resolved"
@@ -23410,6 +23924,18 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "MrList|Assigned to %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from assignee %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from reviewer %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Review requested from %{name}, go to their profile."
+msgstr ""
+
msgid "Multi-project"
msgstr ""
@@ -23443,7 +23969,7 @@ msgstr ""
msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "My Awesome Group"
+msgid "My awesome group"
msgstr ""
msgid "My company or team"
@@ -24065,9 +24591,6 @@ msgstr ""
msgid "No available branches"
msgstr ""
-msgid "No available groups to fork the project."
-msgstr ""
-
msgid "No branches found"
msgstr ""
@@ -24278,6 +24801,9 @@ msgstr ""
msgid "No ref selected"
msgstr ""
+msgid "No regions configured"
+msgstr ""
+
msgid "No related merge requests found."
msgstr ""
@@ -25082,6 +25608,9 @@ msgstr ""
msgid "Only reCAPTCHA v2 is supported:"
msgstr ""
+msgid "Only required if not using role instance credentials."
+msgstr ""
+
msgid "Only use lowercase letters, numbers, and underscores."
msgstr ""
@@ -25106,9 +25635,6 @@ msgstr ""
msgid "Open a CLI and connect to the cluster you want to install the agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
-msgid "Open epics"
-msgstr ""
-
msgid "Open errors"
msgstr ""
@@ -25148,7 +25674,7 @@ msgstr ""
msgid "Opened issues"
msgstr ""
-msgid "OpenedNDaysAgo|Opened"
+msgid "OpenedNDaysAgo|Created"
msgstr ""
msgid "Opens in a new window"
@@ -25193,9 +25719,6 @@ msgstr ""
msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
-msgid "Optional."
-msgstr ""
-
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
msgstr ""
@@ -25984,6 +26507,9 @@ msgstr ""
msgid "PerformanceBar|Memory"
msgstr ""
+msgid "PerformanceBar|Memory report"
+msgstr ""
+
msgid "PerformanceBar|Redis calls"
msgstr ""
@@ -26017,18 +26543,12 @@ msgstr ""
msgid "PerformanceBar|wall"
msgstr ""
-msgid "Performs a rebase but skips triggering a new pipeline"
-msgstr ""
-
msgid "Period in seconds"
msgstr ""
msgid "Permalink"
msgstr ""
-msgid "Permanently delete project"
-msgstr ""
-
msgid "Permanently remove group"
msgstr ""
@@ -26299,6 +26819,51 @@ msgstr ""
msgid "PipelineStatusTooltip|Pipeline: %{ci_status}"
msgstr ""
+msgid "PipelineWizardDefaultCommitMessage|Add %{filename}"
+msgstr ""
+
+msgid "PipelineWizardDefaultCommitMessage|Update %{filename}"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|At least one entry is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This field is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This value is not valid"
+msgstr ""
+
+msgid "PipelineWizardListWidget|add another step"
+msgstr ""
+
+msgid "PipelineWizardListWidget|remove step"
+msgstr ""
+
+msgid "PipelineWizard|Commit"
+msgstr ""
+
+msgid "PipelineWizard|Commit Message"
+msgstr ""
+
+msgid "PipelineWizard|Commit changes to your file"
+msgstr ""
+
+msgid "PipelineWizard|Commit file to Branch"
+msgstr ""
+
+msgid "PipelineWizard|Commit your new file"
+msgstr ""
+
+msgid "PipelineWizard|The file has been committed."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem committing the changes."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem while checking whether your file already exists in the specified branch."
+msgstr ""
+
msgid "Pipelines"
msgstr ""
@@ -26413,7 +26978,7 @@ msgstr ""
msgid "Pipelines|Project cache successfully reset."
msgstr ""
-msgid "Pipelines|Revoke"
+msgid "Pipelines|Revoke trigger"
msgstr ""
msgid "Pipelines|Something went wrong while cleaning runners cache."
@@ -26458,6 +27023,12 @@ msgstr ""
msgid "Pipelines|This is a child pipeline within the parent pipeline"
msgstr ""
+msgid "Pipelines|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipelines|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipelines|This pipeline will run code originating from a forked project merge request. This means that the code can potentially have security considerations like exposing CI variables."
msgstr ""
@@ -26500,9 +27071,6 @@ msgstr ""
msgid "Pipelines|Your changes have been successfully committed. Now redirecting to the new merge request page."
msgstr ""
-msgid "Pipelines|detached"
-msgstr ""
-
msgid "Pipelines|error"
msgstr ""
@@ -26512,10 +27080,13 @@ msgstr ""
msgid "Pipelines|latest"
msgstr ""
-msgid "Pipelines|stuck"
+msgid "Pipelines|merge request"
msgstr ""
-msgid "Pipelines|train"
+msgid "Pipelines|merge train"
+msgstr ""
+
+msgid "Pipelines|stuck"
msgstr ""
msgid "Pipelines|yaml invalid"
@@ -26647,6 +27218,12 @@ msgstr ""
msgid "Pipeline|This change will not change the overall test coverage if merged."
msgstr ""
+msgid "Pipeline|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipeline|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipeline|Trigger author"
msgstr ""
@@ -26671,6 +27248,12 @@ msgstr ""
msgid "Pipeline|for"
msgstr ""
+msgid "Pipeline|merge request"
+msgstr ""
+
+msgid "Pipeline|merge train"
+msgstr ""
+
msgid "Pipeline|on"
msgstr ""
@@ -26809,9 +27392,6 @@ msgstr ""
msgid "Please enter a valid time interval"
msgstr ""
-msgid "Please enter or upload a valid license."
-msgstr ""
-
msgid "Please enter your current password."
msgstr ""
@@ -26920,9 +27500,6 @@ msgstr ""
msgid "Please type %{phrase_code} to proceed or close this modal to cancel."
msgstr ""
-msgid "Please type the following to confirm:"
-msgstr ""
-
msgid "Please use this form to report to the admin users who create spam issues, comments or behave inappropriately."
msgstr ""
@@ -26950,12 +27527,27 @@ msgstr ""
msgid "Policies"
msgstr ""
+msgid "Policy '%{escalation_policy_name}' does not exist."
+msgstr ""
+
msgid "Policy management project does have any policies in %{policy_path}"
msgstr ""
msgid "Policy project doesn't exist"
msgstr ""
+msgid "PolicyRuleMultiSelect|%{firstLabel} +%{numberOfAdditionalLabels} more"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|All %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select all"
+msgstr ""
+
msgid "Polling interval multiplier"
msgstr ""
@@ -27184,6 +27776,9 @@ msgstr ""
msgid "Private projects can be created in your personal namespace with:"
msgstr ""
+msgid "Problem with %{name} command: %{message}."
+msgstr ""
+
msgid "Proceed"
msgstr ""
@@ -27658,6 +28253,9 @@ msgstr ""
msgid "Progress"
msgstr ""
+msgid "Progress tracking"
+msgstr ""
+
msgid "Project"
msgstr ""
@@ -27889,6 +28487,9 @@ msgstr ""
msgid "ProjectQualitySummary|Failure"
msgstr ""
+msgid "ProjectQualitySummary|Get insight into the overall percentage of tests in your project that succeed, fail and are skipped."
+msgstr ""
+
msgid "ProjectQualitySummary|Latest pipeline results"
msgstr ""
@@ -27907,6 +28508,12 @@ msgstr ""
msgid "ProjectQualitySummary|See project Code Coverage Statistics"
msgstr ""
+msgid "ProjectQualitySummary|Set up test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|Set up test runs (opens in a new tab)"
+msgstr ""
+
msgid "ProjectQualitySummary|Skipped"
msgstr ""
@@ -28183,13 +28790,19 @@ msgstr ""
msgid "ProjectSettings|LFS objects from this repository are available to forks. %{linkStart}How do I remove them?%{linkEnd}"
msgstr ""
+msgid "ProjectSettings|Learn about commit history."
+msgstr ""
+
+msgid "ProjectSettings|Leave empty to use default template."
+msgstr ""
+
msgid "ProjectSettings|Manage who can see the project in the public access directory."
msgstr ""
msgid "ProjectSettings|Manages large files such as audio, video, and graphics files."
msgstr ""
-msgid "ProjectSettings|Maximum 500 characters."
+msgid "ProjectSettings|Maximum %{maxLength} characters."
msgstr ""
msgid "ProjectSettings|Merge checks"
@@ -28330,6 +28943,9 @@ msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
msgstr ""
+msgid "ProjectSettings|The default template will be applied on save."
+msgstr ""
+
msgid "ProjectSettings|These checks must pass before merge requests can be merged."
msgstr ""
@@ -28384,6 +29000,9 @@ msgstr ""
msgid "ProjectSettings|What are badges?"
msgstr ""
+msgid "ProjectSettings|What are merge trains?"
+msgstr ""
+
msgid "ProjectSettings|When merge request pipelines are enabled in the CI/CD configuration file, pipelines validate the combined results of the source and target branches. %{link_start}How to configure merge request pipelines?%{link_end}"
msgstr ""
@@ -28501,6 +29120,9 @@ msgstr ""
msgid "Projects are organized into groups"
msgstr ""
+msgid "Projects are where you store your code, access issues, wiki and other features of GitLab."
+msgstr ""
+
msgid "Projects contributed to"
msgstr ""
@@ -28516,12 +29138,6 @@ msgstr ""
msgid "Projects to index"
msgstr ""
-msgid "Projects will be permanently deleted after a %{waiting_period}-day waiting period."
-msgstr ""
-
-msgid "Projects will be permanently deleted immediately."
-msgstr ""
-
msgid "Projects with critical vulnerabilities"
msgstr ""
@@ -28606,6 +29222,9 @@ msgstr ""
msgid "ProjectsNew|Import project"
msgstr ""
+msgid "ProjectsNew|Include a Getting Started README"
+msgstr ""
+
msgid "ProjectsNew|Initialize repository with a README"
msgstr ""
@@ -28621,6 +29240,9 @@ msgstr ""
msgid "ProjectsNew|Project description %{tag_start}(optional)%{tag_end}"
msgstr ""
+msgid "ProjectsNew|Recommended if you're new to GitLab"
+msgstr ""
+
msgid "ProjectsNew|Run CI/CD for external repository"
msgstr ""
@@ -29038,6 +29660,9 @@ msgstr ""
msgid "ProtectedBranch|Unprotect"
msgstr ""
+msgid "ProtectedBranch|Unprotect branch"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
@@ -29065,6 +29690,9 @@ msgstr ""
msgid "ProtectedEnvironment|Protected Environment (%{protected_environments_count})"
msgstr ""
+msgid "ProtectedEnvironment|Required approvals"
+msgstr ""
+
msgid "ProtectedEnvironment|Select an environment"
msgstr ""
@@ -29086,10 +29714,13 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|Unprotect tag"
+msgstr ""
+
msgid "ProtectedTags|default"
msgstr ""
-msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
+msgid "ProtectedTag|By default, protected tags restrict who can modify the tag."
msgstr ""
msgid "ProtectedTag|Learn more."
@@ -29152,6 +29783,9 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Public projects are an easy way to allow everyone to have read-only access."
+msgstr ""
+
msgid "Publish to status page"
msgstr ""
@@ -29308,9 +29942,6 @@ msgstr ""
msgid "QualitySummary|Project quality"
msgstr ""
-msgid "Quarters"
-msgstr ""
-
msgid "Query"
msgstr ""
@@ -29395,6 +30026,9 @@ msgstr ""
msgid "Read more about project permissions %{help_link_open}here%{help_link_close}"
msgstr ""
+msgid "Read more about related epics"
+msgstr ""
+
msgid "Read more about related issues"
msgstr ""
@@ -29425,10 +30059,7 @@ msgstr ""
msgid "Rebase source branch on the target branch."
msgstr ""
-msgid "Rebase without CI"
-msgstr ""
-
-msgid "Rebases and triggers a pipeline"
+msgid "Rebase without pipeline"
msgstr ""
msgid "Recaptcha verified?"
@@ -29479,9 +30110,6 @@ msgstr ""
msgid "Reconfigure"
msgstr ""
-msgid "Recovering projects"
-msgstr ""
-
msgid "Recovery Codes"
msgstr ""
@@ -29541,6 +30169,12 @@ msgstr ""
msgid "Regex pattern"
msgstr ""
+msgid "Region"
+msgstr ""
+
+msgid "Regions"
+msgstr ""
+
msgid "Register"
msgstr ""
@@ -29771,9 +30405,6 @@ msgstr ""
msgid "Remove all or specific reviewer(s)"
msgstr ""
-msgid "Remove approver"
-msgstr ""
-
msgid "Remove approvers"
msgstr ""
@@ -29789,6 +30420,9 @@ msgstr ""
msgid "Remove attention request"
msgstr ""
+msgid "Remove attention request(s)"
+msgstr ""
+
msgid "Remove avatar"
msgstr ""
@@ -29927,6 +30561,9 @@ msgstr ""
msgid "Removed an issue from an epic."
msgstr ""
+msgid "Removed attention from %{users_sentence}."
+msgstr ""
+
msgid "Removed attention request from @%{username}"
msgstr ""
@@ -29978,6 +30615,9 @@ msgstr ""
msgid "Removes an issue from an epic."
msgstr ""
+msgid "Removes attention from %{users_sentence}."
+msgstr ""
+
msgid "Removes parent epic %{epic_ref}."
msgstr ""
@@ -30089,6 +30729,9 @@ msgstr ""
msgid "Report abuse to admin"
msgstr ""
+msgid "Report is generating and will be sent to your email address."
+msgstr ""
+
msgid "Reported %{timeAgo} by %{reportedBy}"
msgstr ""
@@ -30378,6 +31021,15 @@ msgstr ""
msgid "Request attention"
msgstr ""
+msgid "Request attention from %{users_sentence}."
+msgstr ""
+
+msgid "Request attention from assignee or reviewer"
+msgstr ""
+
+msgid "Request attention from assignee(s) or reviewer(s)"
+msgstr ""
+
msgid "Request attention to review"
msgstr ""
@@ -30402,6 +31054,9 @@ msgstr ""
msgid "Requested %{time_ago}"
msgstr ""
+msgid "Requested attention from %{users_sentence}."
+msgstr ""
+
msgid "Requested attention from @%{username}"
msgstr ""
@@ -30616,6 +31271,9 @@ msgstr ""
msgid "Restore project"
msgstr ""
+msgid "Restoring projects"
+msgstr ""
+
msgid "Restoring the group will prevent the group, its subgroups and projects from being removed on this date."
msgstr ""
@@ -30646,6 +31304,9 @@ msgstr ""
msgid "Retry"
msgstr ""
+msgid "Retry failed jobs"
+msgstr ""
+
msgid "Retry job"
msgstr ""
@@ -30693,9 +31354,6 @@ msgstr ""
msgid "Review changes"
msgstr ""
-msgid "Review requested from %{name}"
-msgstr ""
-
msgid "Review requests for you"
msgstr ""
@@ -30860,6 +31518,9 @@ msgstr ""
msgid "Runners|Assigned Group"
msgstr ""
+msgid "Runners|Assigned Projects (%{projectCount})"
+msgstr ""
+
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30929,6 +31590,9 @@ msgstr ""
msgid "Runners|Instance"
msgstr ""
+msgid "Runners|Jobs"
+msgstr ""
+
msgid "Runners|Last contact"
msgstr ""
@@ -31022,9 +31686,6 @@ msgstr ""
msgid "Runners|Runner %{name} was deleted"
msgstr ""
-msgid "Runners|Runner ID"
-msgstr ""
-
msgid "Runners|Runner assigned to project."
msgstr ""
@@ -31172,6 +31833,9 @@ msgstr ""
msgid "Runners|stale"
msgstr ""
+msgid "Runner|This runner has not run any jobs."
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -31286,6 +31950,24 @@ msgstr ""
msgid "Saving project."
msgstr ""
+msgid "ScanResultPolicy|%{ifLabelStart}if%{ifLabelEnd} %{scanners} scan in an open merge request targeting the %{branches} branch(es) finds %{vulnerabilitiesAllowed} or more %{severities} vulnerabilities that are %{vulnerabilityStates}"
+msgstr ""
+
+msgid "ScanResultPolicy|%{thenLabelStart}Then%{thenLabelEnd} Require approval from %{approvalsRequired} of the following approvers: %{approvers}"
+msgstr ""
+
+msgid "ScanResultPolicy|add an approver"
+msgstr ""
+
+msgid "ScanResultPolicy|scanners"
+msgstr ""
+
+msgid "ScanResultPolicy|severity levels"
+msgstr ""
+
+msgid "ScanResultPolicy|vulnerability states"
+msgstr ""
+
msgid "Scanner"
msgstr ""
@@ -31418,6 +32100,9 @@ msgstr ""
msgid "Search for a user"
msgstr ""
+msgid "Search for an emoji"
+msgstr ""
+
msgid "Search for projects, issues, etc."
msgstr ""
@@ -31605,18 +32290,12 @@ msgstr ""
msgid "Secret Detection"
msgstr ""
-msgid "Secret access key"
-msgstr ""
-
msgid "Secret token"
msgstr ""
msgid "Secure token that identifies an external storage request."
msgstr ""
-msgid "SecureCodeWarrior"
-msgstr ""
-
msgid "Security"
msgstr ""
@@ -31641,9 +32320,6 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "Security training with guide and learning pathways."
-msgstr ""
-
msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
@@ -31746,7 +32422,7 @@ msgstr ""
msgid "SecurityConfiguration|Manage corpus"
msgstr ""
-msgid "SecurityConfiguration|Manage corpus files used as mutation sources in coverage fuzzing."
+msgid "SecurityConfiguration|Manage corpus files used as seed inputs with coverage-guided fuzzing."
msgstr ""
msgid "SecurityConfiguration|Manage profiles for use by DAST scans."
@@ -31812,15 +32488,15 @@ msgstr ""
msgid "SecurityOrchestration|.yaml preview"
msgstr ""
-msgid "SecurityOrchestration|Action"
-msgstr ""
-
msgid "SecurityOrchestration|Actions"
msgstr ""
msgid "SecurityOrchestration|Add rule"
msgstr ""
+msgid "SecurityOrchestration|After dismissing the alert, the information will never be shown again."
+msgstr ""
+
msgid "SecurityOrchestration|All policies"
msgstr ""
@@ -31836,7 +32512,7 @@ msgstr ""
msgid "SecurityOrchestration|Description"
msgstr ""
-msgid "SecurityOrchestration|Disabled"
+msgid "SecurityOrchestration|Don't show the alert anymore"
msgstr ""
msgid "SecurityOrchestration|Edit policy"
@@ -31845,13 +32521,13 @@ msgstr ""
msgid "SecurityOrchestration|Edit policy project"
msgstr ""
-msgid "SecurityOrchestration|Enabled"
+msgid "SecurityOrchestration|Empty policy name"
msgstr ""
-msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Enabled"
msgstr ""
-msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
msgstr ""
msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
@@ -31860,7 +32536,7 @@ msgstr ""
msgid "SecurityOrchestration|Invalid policy type"
msgstr ""
-msgid "SecurityOrchestration|Latest scan"
+msgid "SecurityOrchestration|Latest scan run against %{agent}"
msgstr ""
msgid "SecurityOrchestration|Network"
@@ -31869,15 +32545,27 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No actions defined - policy will not run."
+msgstr ""
+
+msgid "SecurityOrchestration|No description"
+msgstr ""
+
msgid "SecurityOrchestration|No rules defined - policy will not run."
msgstr ""
+msgid "SecurityOrchestration|Not enabled"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
msgid "SecurityOrchestration|Policies"
msgstr ""
+msgid "SecurityOrchestration|Policy Type"
+msgstr ""
+
msgid "SecurityOrchestration|Policy cannot be enabled for non-existing branches (%{branches})"
msgstr ""
@@ -31902,10 +32590,13 @@ msgstr ""
msgid "SecurityOrchestration|Require %{approvals} %{plural} from %{approvers} if any of the following occur:"
msgstr ""
-msgid "SecurityOrchestration|Rule"
+msgid "SecurityOrchestration|Rules"
msgstr ""
-msgid "SecurityOrchestration|Rules"
+msgid "SecurityOrchestration|Runs %{actions} and %{lastAction} scans"
+msgstr ""
+
+msgid "SecurityOrchestration|Runs a %{action} scan"
msgstr ""
msgid "SecurityOrchestration|Scan Execution"
@@ -31965,6 +32656,9 @@ msgstr ""
msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
+msgid "SecurityOrchestration|This view only shows scan results for the agent %{agent}. You can view scan results for all agents in the %{linkStart}Operational Vulnerabilities tab of the vulnerability report%{linkEnd}."
+msgstr ""
+
msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
@@ -32019,9 +32713,6 @@ msgstr ""
msgid "SecurityOrchestration|users with ids"
msgstr ""
-msgid "SecurityOrchestration|view results"
-msgstr ""
-
msgid "SecurityOrchestration|vulnerabilities"
msgstr ""
@@ -32691,22 +33382,19 @@ 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|In order to start using functions as a service, you must first install Knative on your Kubernetes cluster. %{linkStart}More information%{linkEnd}"
-msgstr ""
-
msgid "Serverless|Learn more about Serverless"
msgstr ""
msgid "Serverless|No functions available"
msgstr ""
-msgid "Serverless|Sign up for First Look"
+msgid "Serverless|Serverless was %{linkStart}deprecated%{linkEnd} in GitLab 14.3."
+msgstr ""
+
+msgid "Serverless|Serverless was %{postLinkStart}deprecated%{postLinkEnd}. But if you opt to use it, you must install Knative in your Kubernetes cluster first. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "Serverless|The deploy job has not finished."
@@ -32718,9 +33406,6 @@ 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 ""
@@ -32736,9 +33421,6 @@ msgstr ""
msgid "Service Account Key"
msgstr ""
-msgid "Service Accounts"
-msgstr ""
-
msgid "Service Accounts keys authorize GitLab to deploy your Google Cloud project"
msgstr ""
@@ -32748,10 +33430,10 @@ msgstr ""
msgid "Service Desk allows people to create issues in your GitLab instance without their own user account. It provides a unique email address for end users to create issues in a project. Replies can be sent either through the GitLab interface or by email. End users only see threads through email."
msgstr ""
-msgid "Service Usage Data"
+msgid "Service account generated successfully"
msgstr ""
-msgid "Service account generated successfully"
+msgid "Service accounts"
msgstr ""
msgid "Service ping is disabled in your configuration file, and cannot be enabled through this form."
@@ -32895,6 +33577,9 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
+msgid "Set the per-user rate limit for getting a user by ID via the API."
+msgstr ""
+
msgid "Set the per-user rate limit for notes created by web or API requests."
msgstr ""
@@ -33074,6 +33759,9 @@ msgstr ""
msgid "Shared runners details"
msgstr ""
+msgid "Shared runners enabled cannot be enabled until a valid credit card is on file"
+msgstr ""
+
msgid "Shared runners help link"
msgstr ""
@@ -33131,6 +33819,9 @@ msgstr ""
msgid "Show all issues."
msgstr ""
+msgid "Show all milestones"
+msgstr ""
+
msgid "Show all test cases."
msgstr ""
@@ -33167,6 +33858,9 @@ msgstr ""
msgid "Show file contents"
msgstr ""
+msgid "Show group milestones"
+msgstr ""
+
msgid "Show labels"
msgstr ""
@@ -33182,6 +33876,12 @@ msgstr ""
msgid "Show open epics"
msgstr ""
+msgid "Show project milestones"
+msgstr ""
+
+msgid "Show sub-group milestones"
+msgstr ""
+
msgid "Show the Closed list"
msgstr ""
@@ -33191,11 +33891,6 @@ msgstr ""
msgid "Show whitespace changes"
msgstr ""
-msgid "Showing %d event"
-msgid_plural "Showing %d events"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Showing %{conflict} between %{sourceBranch} and %{targetBranch}"
msgstr ""
@@ -33255,12 +33950,6 @@ msgstr ""
msgid "Sidebar|None"
msgstr ""
-msgid "Sidebar|Only numeral characters allowed"
-msgstr ""
-
-msgid "Sidebar|Weight"
-msgstr ""
-
msgid "Sidekiq job compression threshold (bytes)"
msgstr ""
@@ -33423,6 +34112,9 @@ msgstr ""
msgid "Slack logo"
msgstr ""
+msgid "SlackIntegration|Are you sure you want to remove this project from the Slack application?"
+msgstr ""
+
msgid "SlackIntegration|GitLab for Slack"
msgstr ""
@@ -33432,6 +34124,9 @@ msgstr ""
msgid "SlackIntegration|Project alias"
msgstr ""
+msgid "SlackIntegration|Remove project"
+msgstr ""
+
msgid "SlackIntegration|Select a GitLab project to link with your Slack workspace."
msgstr ""
@@ -33576,9 +34271,6 @@ msgstr ""
msgid "Something went wrong trying to load issue contacts."
msgstr ""
-msgid "Something went wrong when creating a work item. Please try again"
-msgstr ""
-
msgid "Something went wrong when reordering designs. Please try again"
msgstr ""
@@ -33672,9 +34364,6 @@ msgstr ""
msgid "Something went wrong while inserting your image. Please try again."
msgstr ""
-msgid "Something went wrong while merging this merge request. Please try again."
-msgstr ""
-
msgid "Something went wrong while obtaining the Let's Encrypt certificate."
msgstr ""
@@ -33996,10 +34685,10 @@ 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."
+msgid "SourcegraphAdmin|Learn more."
msgstr ""
-msgid "SourcegraphAdmin|More information"
+msgid "SourcegraphAdmin|Only public projects have code intelligence enabled and communicate with Sourcegraph."
msgstr ""
msgid "SourcegraphAdmin|Save changes"
@@ -34008,7 +34697,7 @@ msgstr ""
msgid "SourcegraphAdmin|Sourcegraph URL"
msgstr ""
-msgid "SourcegraphAdmin|e.g. https://sourcegraph.example.com"
+msgid "SourcegraphAdmin|https://sourcegraph.example.com"
msgstr ""
msgid "SourcegraphPreferences|This feature is experimental and currently limited to certain projects."
@@ -34143,6 +34832,9 @@ msgstr ""
msgid "Start date"
msgstr ""
+msgid "Start free trial"
+msgstr ""
+
msgid "Start merge train"
msgstr ""
@@ -34173,6 +34865,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started escalation for this incident."
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -34185,6 +34880,9 @@ msgstr ""
msgid "Starts at (UTC)"
msgstr ""
+msgid "Starts escalations for this incident"
+msgstr ""
+
msgid "Starts on"
msgstr ""
@@ -34446,6 +35144,9 @@ msgstr ""
msgid "Strikethrough"
msgstr ""
+msgid "Strikethrough text"
+msgstr ""
+
msgid "Subgroup information"
msgstr ""
@@ -34680,6 +35381,21 @@ msgstr ""
msgid "Subscriptions"
msgstr ""
+msgid "Subscriptions|Chat with sales"
+msgstr ""
+
+msgid "Subscriptions|Close"
+msgstr ""
+
+msgid "Subscriptions|Not ready to buy yet?"
+msgstr ""
+
+msgid "Subscriptions|Start a free trial"
+msgstr ""
+
+msgid "Subscriptions|We understand. Maybe you have some questions for our sales team, or maybe you'd like to try some of the paid features first. What would you like to do?"
+msgstr ""
+
msgid "Subscription|Your subscription for %{strong}%{namespace_name}%{strong_close} has expired and you are now on %{pricing_link_start}the GitLab Free tier%{pricing_link_end}. Don't worry, your data is safe. Get in touch with our support team (%{support_email}). They'll gladly help with your subscription renewal."
msgstr ""
@@ -34890,6 +35606,9 @@ msgstr ""
msgid "SuperSonics|Maximum users"
msgstr ""
+msgid "SuperSonics|Offline cloud"
+msgstr ""
+
msgid "SuperSonics|Paste your activation code"
msgstr ""
@@ -34956,6 +35675,12 @@ msgstr ""
msgid "SuperSonics|You do not have an active subscription"
msgstr ""
+msgid "SuperSonics|You have a future dated license"
+msgstr ""
+
+msgid "SuperSonics|You have added a license that activates on %{date}. Please see the subscription history table below for more details."
+msgstr ""
+
msgid "SuperSonics|You have successfully added a license that activates on %{date}. Please see the subscription history table below for more details."
msgstr ""
@@ -35115,6 +35840,9 @@ msgstr ""
msgid "Tag name is required"
msgstr ""
+msgid "Tag push"
+msgstr ""
+
msgid "Tag push events"
msgstr ""
@@ -35217,6 +35945,9 @@ msgstr ""
msgid "TagsPage|protected"
msgstr ""
+msgid "Take a look at the documentation to discover all of GitLab’s capabilities."
+msgstr ""
+
msgid "Target Branch"
msgstr ""
@@ -35619,6 +36350,9 @@ msgstr ""
msgid "Tests"
msgstr ""
+msgid "Text (optional)"
+msgstr ""
+
msgid "Text added to the body of all email messages. %{character_limit} character limit"
msgstr ""
@@ -35669,6 +36403,9 @@ msgstr ""
msgid "The CSV export will be created in the background. Once finished, it will be sent to %{email} in an attachment."
msgstr ""
+msgid "The CSV export you requested of all user memberships is attached to this email."
+msgstr ""
+
msgid "The GitLab subscription service (customers.gitlab.com) is currently experiencing an outage. You can monitor the status and get updates at %{linkStart}status.gitlab.com%{linkEnd}."
msgstr ""
@@ -35744,6 +36481,9 @@ 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 epic"
+msgstr ""
+
msgid "The current issue"
msgstr ""
@@ -35905,6 +36645,9 @@ msgstr ""
msgid "The latest pipeline for this merge request has failed."
msgstr ""
+msgid "The license key is invalid."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -35920,6 +36663,9 @@ msgstr ""
msgid "The license was successfully uploaded and will be active from %{starts_at}. You can see the details below."
msgstr ""
+msgid "The license you uploaded is invalid. If the issue persists, contact support at %{link}."
+msgstr ""
+
msgid "The list creation wizard is already open"
msgstr ""
@@ -36541,10 +37287,13 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} and everything this project contains. %{strongOpen}There is no going back%{strongClose}"
+msgstr ""
+
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains."
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}on %{date}%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains. %{strongOpen}There is no going back.%{strongClose}"
msgstr ""
msgid "This action will %{strongOpen}permanently remove%{strongClose} %{codeOpen}%{group}%{codeClose} %{strongOpen}immediately%{strongClose}."
@@ -36673,9 +37422,6 @@ msgstr ""
msgid "This file was modified for readability, and can't accept suggestions. Edit it directly."
msgstr ""
-msgid "This forked project has the following:"
-msgstr ""
-
msgid "This form is disabled in preview"
msgstr ""
@@ -36688,7 +37434,7 @@ msgstr ""
msgid "This group can't be removed because it is linked to a subscription. To remove this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
-msgid "This group can't be transfered because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
+msgid "This group can't be transferred because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
msgid "This group cannot be invited to a project inside a group with enforced SSO"
@@ -36715,6 +37461,9 @@ 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 incident is already escalated with '%{escalation_policy_name}'."
+msgstr ""
+
msgid "This invitation was sent to %{mail_to_invite_email}, but you are signed in as %{link_to_current_user} with email %{mail_to_current_user}."
msgstr ""
@@ -36733,9 +37482,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 merge train pipeline"
-msgstr ""
-
msgid "This is a private email address %{helpIcon} generated just for you. Anyone who has it can create issues or merge requests as if they were you. If that happens, %{resetLinkStart}reset this token%{resetLinkEnd}."
msgstr ""
@@ -36757,6 +37503,12 @@ msgstr ""
msgid "This is your current session"
msgstr ""
+msgid "This issue cannot be assigned to a confidential epic because it is public."
+msgstr ""
+
+msgid "This issue cannot be made public because it belongs to a confidential epic."
+msgstr ""
+
msgid "This issue is confidential and should only be visible to team members with at least Reporter access."
msgstr ""
@@ -36874,6 +37626,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 branch is protected from force push."
+msgstr ""
+
msgid "This merge request cannot be rebased while there are conflicts."
msgstr ""
@@ -36925,9 +37680,15 @@ msgstr ""
msgid "This pipeline was triggered by a schedule."
msgstr ""
+msgid "This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project"
msgstr ""
+msgid "This project can be restored until %{date}."
+msgstr ""
+
msgid "This project cannot be %{visibilityLevel} because the visibility of %{openShowLink}%{name}%{closeShowLink} is %{visibility}. To make this project %{visibilityLevel}, you must first %{openEditLink}change the visibility%{closeEditLink} of the parent group."
msgstr ""
@@ -36946,6 +37707,9 @@ msgstr ""
msgid "This project is %{strongStart}NOT%{strongEnd} a fork, and has the following:"
msgstr ""
+msgid "This project is %{strongStart}NOT%{strongEnd} a fork. This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -37637,6 +38401,9 @@ msgstr ""
msgid "Today"
msgstr ""
+msgid "Todos count"
+msgstr ""
+
msgid "Todos|Are you looking for things to do? Take a look at %{strongStart}%{openIssuesLinkStart}open issues%{openIssuesLinkEnd}%{strongEnd}, contribute to %{strongStart}%{mergeRequestLinkStart}a merge request%{mergeRequestLinkEnd}%{mergeRequestLinkEnd}%{strongEnd}, or mention someone in a comment to automatically assign them a new to-do item."
msgstr ""
@@ -37910,10 +38677,8 @@ msgstr ""
msgid "Trending"
msgstr ""
-msgid "Trials|%{planName} Trial %{enDash} %{num} day left"
-msgid_plural "Trials|%{planName} Trial %{enDash} %{num} days left"
-msgstr[0] ""
-msgstr[1] ""
+msgid "Trials|%{planName} Trial"
+msgstr ""
msgid "Trials|Compare all plans"
msgstr ""
@@ -37921,6 +38686,9 @@ msgstr ""
msgid "Trials|Create a new group to start your GitLab Ultimate trial."
msgstr ""
+msgid "Trials|Day %{daysUsed}/%{duration}"
+msgstr ""
+
msgid "Trials|Go back to GitLab"
msgstr ""
@@ -38170,7 +38938,7 @@ msgstr ""
msgid "URL is triggered when repository is updated"
msgstr ""
-msgid "URL must be percent-encoded if neccessary."
+msgid "URL must be percent-encoded if necessary."
msgstr ""
msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
@@ -38389,6 +39157,9 @@ msgstr ""
msgid "Unlock account"
msgstr ""
+msgid "Unlock more features with GitLab Ultimate"
+msgstr ""
+
msgid "Unlock the discussion"
msgstr ""
@@ -38452,6 +39223,9 @@ msgstr ""
msgid "Unsubscribes from this %{quick_action_target}."
msgstr ""
+msgid "Unsupported sort value."
+msgstr ""
+
msgid "Unsupported todo type passed. Supported todo types are: %{todo_types}"
msgstr ""
@@ -38680,6 +39454,9 @@ msgstr ""
msgid "UsageQuota|File attachments and smaller design graphics."
msgstr ""
+msgid "UsageQuota|From %{storage_enforcement_date} storage limits will apply to this namespace. View and manage your usage in %{strong_start}Group Settings &gt; Usage quotas%{strong_end}."
+msgstr ""
+
msgid "UsageQuota|Git repository."
msgstr ""
@@ -38740,6 +39517,9 @@ msgstr ""
msgid "UsageQuota|Storage type"
msgstr ""
+msgid "UsageQuota|Storage used"
+msgstr ""
+
msgid "UsageQuota|This is the total amount of storage used across your projects within this namespace."
msgstr ""
@@ -38935,6 +39715,12 @@ msgstr ""
msgid "Use hashed storage paths for newly created and renamed repositories. Always enabled since 13.0."
msgstr ""
+msgid "Use issue count"
+msgstr ""
+
+msgid "Use issue weight"
+msgstr ""
+
msgid "Use one line per URI"
msgstr ""
@@ -39316,6 +40102,9 @@ msgstr ""
msgid "Users"
msgstr ""
+msgid "Users API rate limit"
+msgstr ""
+
msgid "Users can launch a development environment from a GitLab browser tab when the %{linkStart}Gitpod%{linkEnd} integration is enabled."
msgstr ""
@@ -39641,6 +40430,9 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View group pipeline usage quota"
+msgstr ""
+
msgid "View incident details at"
msgstr ""
@@ -39793,6 +40585,9 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
+msgid "Vulnerability"
+msgstr ""
+
msgid "Vulnerability Report"
msgstr ""
@@ -39844,6 +40639,9 @@ msgstr ""
msgid "VulnerabilityManagement|An unverified non-confirmed finding"
msgstr ""
+msgid "VulnerabilityManagement|At least one identifier is required"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -39853,12 +40651,24 @@ msgstr ""
msgid "VulnerabilityManagement|Create Jira issue"
msgstr ""
+msgid "VulnerabilityManagement|Enter a name"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE code"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE identifier URL"
+msgstr ""
+
msgid "VulnerabilityManagement|Fetching linked Jira issues"
msgstr ""
msgid "VulnerabilityManagement|Manually add a vulnerability entry into the vulnerability report."
msgstr ""
+msgid "VulnerabilityManagement|Name is a required field"
+msgstr ""
+
msgid "VulnerabilityManagement|Needs triage"
msgstr ""
@@ -39874,6 +40684,18 @@ msgstr ""
msgid "VulnerabilityManagement|Select a method"
msgstr ""
+msgid "VulnerabilityManagement|Select a severity level"
+msgstr ""
+
+msgid "VulnerabilityManagement|Select a status"
+msgstr ""
+
+msgid "VulnerabilityManagement|Severity is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Something went wrong while creating vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -39898,6 +40720,12 @@ msgstr ""
msgid "VulnerabilityManagement|Something went wrong, could not update vulnerability state."
msgstr ""
+msgid "VulnerabilityManagement|Status is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Submit vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Summary, detailed description, steps to reproduce, etc."
msgstr ""
@@ -40093,6 +40921,9 @@ msgstr ""
msgid "WARNING:"
msgstr ""
+msgid "WARNING: This snippet contains hidden files which might be used to mask malicious behavior. Exercise caution if cloning and executing code from this snippet."
+msgstr ""
+
msgid "Wait for the file to load to copy its contents"
msgstr ""
@@ -40312,6 +41143,15 @@ msgstr ""
msgid "Webhooks|An issue is created, updated, closed, or reopened."
msgstr ""
+msgid "Webhooks|Are you sure you want to delete this group hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this project hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this webhook?"
+msgstr ""
+
msgid "Webhooks|Comments"
msgstr ""
@@ -40321,6 +41161,9 @@ msgstr ""
msgid "Webhooks|Confidential issues events"
msgstr ""
+msgid "Webhooks|Delete webhook"
+msgstr ""
+
msgid "Webhooks|Deployment events"
msgstr ""
@@ -40554,6 +41397,9 @@ msgstr ""
msgid "Wiki"
msgstr ""
+msgid "Wiki page"
+msgstr ""
+
msgid "Wiki page was successfully created."
msgstr ""
@@ -40659,7 +41505,7 @@ msgstr ""
msgid "WikiPageConflictMessage|Someone edited the page the same time you did. Please check out %{wikiLinkStart}the page%{wikiLinkEnd} and make sure your changes will not unintentionally remove theirs."
msgstr ""
-msgid "WikiPage|An error occured while trying to render the content editor. Please try again later."
+msgid "WikiPage|An error occurred while trying to render the content editor. Please try again later."
msgstr ""
msgid "WikiPage|Are you sure you want to switch back to the classic editor?"
@@ -40818,6 +41664,18 @@ msgstr ""
msgid "WorkItem|New Task"
msgstr ""
+msgid "WorkItem|Something went wrong when creating a work item. Please try again"
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching the work item. Please try again."
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching work item types. Please try again"
+msgstr ""
+
+msgid "WorkItem|Type"
+msgstr ""
+
msgid "WorkItem|Work Items"
msgstr ""
@@ -40884,7 +41742,10 @@ msgstr ""
msgid "You are about to add %{usersTag} people to the discussion. They will all receive a notification."
msgstr ""
-msgid "You are about to permanently delete this project"
+msgid "You are about to delete this forked project containing:"
+msgstr ""
+
+msgid "You are about to delete this project containing:"
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."
@@ -40905,6 +41766,9 @@ msgstr ""
msgid "You are attempting to update a file that has changed since you started editing it."
msgstr ""
+msgid "You are billed if you exceed this number. %{qsrOverageLinkStart}How does billing work?%{qsrOverageLinkEnd}"
+msgstr ""
+
msgid "You are connected to the Prometheus server, but there is currently no data to display."
msgstr ""
@@ -40962,6 +41826,9 @@ msgstr ""
msgid "You are not authorized to update this scanner profile"
msgstr ""
+msgid "You are not authorized to upload metric images"
+msgstr ""
+
msgid "You are now impersonating %{username}"
msgstr ""
@@ -41115,9 +41982,6 @@ msgstr ""
msgid "You can only upload one design when dropping onto an existing design."
msgstr ""
-msgid "You can recover this project until %{date}"
-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 ""
@@ -41166,9 +42030,6 @@ msgstr ""
msgid "You cannot write to this read-only GitLab instance."
msgstr ""
-msgid "You can’t %{tag_start}edit%{tag_end} files directly in this project. Fork this project and submit a merge request with your changes."
-msgstr ""
-
msgid "You can’t edit files directly in this project. Fork this project and submit a merge request with your changes."
msgstr ""
@@ -41321,9 +42182,6 @@ 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 set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
@@ -41354,12 +42212,6 @@ msgstr ""
msgid "You must have maintainer access to force delete a lock"
msgstr ""
-msgid "You must have permission to create a project in a group before forking."
-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 ""
@@ -41765,7 +42617,7 @@ msgstr ""
msgid "Your public email will be displayed on your public profile."
msgstr ""
-msgid "Your request for access could not be processed: %{error_meesage}"
+msgid "Your request for access could not be processed: %{error_message}"
msgstr ""
msgid "Your request for access has been queued for review."
@@ -41948,6 +42800,9 @@ msgstr ""
msgid "archived:"
msgstr ""
+msgid "artifacts"
+msgstr ""
+
msgid "assign yourself"
msgstr ""
@@ -41977,6 +42832,9 @@ msgstr[1] ""
msgid "branch name"
msgstr ""
+msgid "builds"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -42400,6 +43258,9 @@ msgstr ""
msgid "contact with same email already exists in group hierarchy"
msgstr ""
+msgid "container registry images"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -42439,6 +43300,9 @@ msgstr ""
msgid "data"
msgstr ""
+msgid "database"
+msgstr ""
+
msgid "date must not be after 9999-12-31"
msgstr ""
@@ -42462,9 +43326,6 @@ msgstr ""
msgid "design"
msgstr ""
-msgid "detached"
-msgstr ""
-
msgid "disabled"
msgstr ""
@@ -42713,7 +43574,7 @@ msgstr ""
msgid "is not a valid X509 certificate."
msgstr ""
-msgid "is not allowed for sign-up."
+msgid "is not allowed for sign-up. Please use your regular email address."
msgstr ""
msgid "is not allowed for this group."
@@ -42725,7 +43586,7 @@ msgstr ""
msgid "is not allowed since the group is not top-level group."
msgstr ""
-msgid "is not allowed."
+msgid "is not allowed. Please use your regular email address."
msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
@@ -42812,6 +43673,9 @@ msgstr ""
msgid "level: %{level}"
msgstr ""
+msgid "lfs objects"
+msgstr ""
+
msgid "limit of %{project_limit} reached"
msgstr ""
@@ -43031,6 +43895,9 @@ msgstr ""
msgid "mrWidget|Merge blocked: pipeline must succeed. It's waiting for a manual action to continue."
msgstr ""
+msgid "mrWidget|Merge blocked: pipeline must succeed. Push a commit that fixes the failure, or %{linkStart}learn about other solutions.%{linkEnd}"
+msgstr ""
+
msgid "mrWidget|Merge blocked: this merge request must be approved."
msgstr ""
@@ -43148,9 +44015,6 @@ msgstr ""
msgid "mrWidget|The changes were not merged into"
msgstr ""
-msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -43298,9 +44162,6 @@ msgstr ""
msgid "open issue"
msgstr ""
-msgid "opened %{timeAgo}"
-msgstr ""
-
msgid "or"
msgstr ""
@@ -43312,6 +44173,12 @@ msgid_plural "out of %d total tests"
msgstr[0] ""
msgstr[1] ""
+msgid "packages"
+msgstr ""
+
+msgid "pages"
+msgstr ""
+
msgid "parent"
msgid_plural "parents"
msgstr[0] ""
@@ -43461,6 +44328,9 @@ msgid_plural "replies"
msgstr[0] ""
msgstr[1] ""
+msgid "repositories"
+msgstr ""
+
msgid "repository:"
msgstr ""
@@ -43581,12 +44451,18 @@ msgstr ""
msgid "tag name"
msgstr ""
+msgid "terraform states"
+msgstr ""
+
msgid "the correct format."
msgstr ""
msgid "the file"
msgstr ""
+msgid "the following epic(s)"
+msgstr ""
+
msgid "the following issue(s)"
msgstr ""
@@ -43599,21 +44475,12 @@ msgstr ""
msgid "this document"
msgstr ""
-msgid "this issue cannot be assigned to a confidential epic since it is public"
-msgstr ""
-
-msgid "this issue cannot be made public since it belongs to a confidential epic"
-msgstr ""
-
msgid "time summary"
msgstr ""
msgid "toggle collapse"
msgstr ""
-msgid "train"
-msgstr ""
-
msgid "triggered"
msgstr ""
@@ -43742,3 +44609,6 @@ msgstr ""
msgid "{project}"
msgstr ""
+msgid "✔"
+msgstr ""
+
diff --git a/locale/it/gitlab.po b/locale/it/gitlab.po
index d3847f8a6ec..9d7adc17011 100644
--- a/locale/it/gitlab.po
+++ b/locale/it/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: it\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2022-02-02 15:45\n"
+"PO-Revision-Date: 2022-03-01 20:39\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -146,6 +146,11 @@ msgid_plural "%d approvers (you've approved)"
msgstr[0] ""
msgstr[1] ""
+msgid "%d assigned issue"
+msgid_plural "%d assigned issues"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -421,8 +426,23 @@ msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
msgstr[1] ""
-msgid "%d vulnerability updated"
-msgid_plural "%d vulnerabilities updated"
+msgid "%d vulnerability set to confirmed"
+msgid_plural "%d vulnerabilities set to confirmed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to dismissed"
+msgid_plural "%d vulnerabilities set to dismissed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to needs triage"
+msgid_plural "%d vulnerabilities set to needs triage"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to resolved"
+msgid_plural "%d vulnerabilities set to resolved"
msgstr[0] ""
msgstr[1] ""
@@ -510,6 +530,12 @@ msgstr[1] ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{completed} of %{total} issues closed"
+msgstr ""
+
+msgid "%{completed} of %{total} weight completed"
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -858,6 +884,9 @@ msgstr ""
msgid "%{openedIssues} open, %{closedIssues} closed"
msgstr ""
+msgid "%{percentage}%% issues closed"
+msgstr ""
+
msgid "%{percentage}%% weight completed"
msgstr ""
@@ -1287,6 +1316,9 @@ msgid_plural "- Users"
msgstr[0] ""
msgstr[1] ""
+msgid "- of - issues closed"
+msgstr ""
+
msgid "- of - weight completed"
msgstr ""
@@ -1429,7 +1461,7 @@ msgstr "10-19 contributi"
msgid "1000+"
msgstr ""
-msgid "192.168.0.0/24"
+msgid "192.168.0.0/24 or 2001:0DB8:1234::/48"
msgstr ""
msgid "1st contribution!"
@@ -1741,13 +1773,13 @@ msgstr ""
msgid "AWS Access Key"
msgstr ""
-msgid "AWS Access Key. Only required if not using role instance credentials"
+msgid "AWS Secret Access Key"
msgstr ""
-msgid "AWS Secret Access Key"
+msgid "AWS access key ID (Optional)"
msgstr ""
-msgid "AWS Secret Access Key. Only required if not using role instance credentials"
+msgid "AWS secret access key (Optional)"
msgstr ""
msgid "AWS service error: %{error}"
@@ -1807,9 +1839,6 @@ msgstr ""
msgid "Access granted"
msgstr ""
-msgid "Access key ID"
-msgstr ""
-
msgid "Access requests"
msgstr ""
@@ -1984,7 +2013,7 @@ msgstr ""
msgid "Activity"
msgstr "Attività"
-msgid "Activity|An error occured while retrieving activity. Reload the page to try again."
+msgid "Activity|An error occurred while retrieving activity. Reload the page to try again."
msgstr ""
msgid "Add"
@@ -2023,6 +2052,9 @@ msgstr ""
msgid "Add a %{type}"
msgstr ""
+msgid "Add a GCP region"
+msgstr ""
+
msgid "Add a GPG key"
msgstr ""
@@ -2074,6 +2106,9 @@ msgstr ""
msgid "Add a numbered list"
msgstr ""
+msgid "Add a related epic"
+msgstr ""
+
msgid "Add a related issue"
msgstr ""
@@ -2188,6 +2223,9 @@ msgstr ""
msgid "Add or subtract spent time"
msgstr ""
+msgid "Add people"
+msgstr ""
+
msgid "Add previously merged commits"
msgstr ""
@@ -2254,6 +2292,9 @@ msgstr ""
msgid "Add webhook"
msgstr ""
+msgid "Add your team members and others to GitLab."
+msgstr ""
+
msgid "Add/remove"
msgstr ""
@@ -3076,12 +3117,6 @@ msgstr ""
msgid "AdvancedSearch|Reindex required"
msgstr ""
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. Permanently deleting this project will %{strongStart}immediately delete%{strongEnd} its repositories and %{strongStart}all related resources%{strongEnd}, including issues, merge requests etc."
-msgstr ""
-
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. You will lose this project's repository and %{strongStart}all related resources%{strongEnd}, including issues and merge requests."
-msgstr ""
-
msgid "After a successful password update you will be redirected to login screen."
msgstr ""
@@ -3112,6 +3147,9 @@ msgstr ""
msgid "Akismet helps prevent the creation of spam issues in public projects."
msgstr ""
+msgid "Alert"
+msgstr ""
+
msgid "AlertManagement|Acknowledged"
msgstr ""
@@ -3484,9 +3522,6 @@ msgstr ""
msgid "All environments"
msgstr ""
-msgid "All epics"
-msgstr ""
-
msgid "All groups and projects"
msgstr ""
@@ -4223,12 +4258,15 @@ msgstr ""
msgid "ApplicationSettings|Approve users in the pending approval status?"
msgstr ""
-msgid "ApplicationSettings|By making this change, you will automatically approve %d user with the pending approval status."
-msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users with the pending approval status."
+msgid "ApplicationSettings|Approve users who are pending approval?"
+msgstr ""
+
+msgid "ApplicationSettings|By making this change, you will automatically approve %d user who is pending approval."
+msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users who are pending approval."
msgstr[0] ""
msgstr[1] ""
-msgid "ApplicationSettings|By making this change, you will automatically approve all users in pending approval status."
+msgid "ApplicationSettings|By making this change, you will automatically approve all users who are pending approval."
msgstr ""
msgid "ApplicationSettings|Denied domains for sign-ups"
@@ -4634,10 +4672,10 @@ msgstr ""
msgid "Archiving the project will make it entirely read-only. It is hidden from the dashboard and doesn't show up in searches. %{strong_start}The repository cannot be committed to, and no issues, comments, or other entities can be created.%{strong_end} %{link_start}Learn more.%{link_end}"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to delete this project?"
+msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
+msgid "Are you absolutely sure?"
msgstr ""
msgid "Are you sure that you want to archive this project?"
@@ -4673,12 +4711,18 @@ msgstr ""
msgid "Are you sure you want to delete this SSH key?"
msgstr ""
+msgid "Are you sure you want to delete this comment?"
+msgstr ""
+
msgid "Are you sure you want to delete this deploy key?"
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 label?"
+msgstr ""
+
msgid "Are you sure you want to delete this pipeline schedule?"
msgstr "Sei sicuro di voler cancellare questa pipeline programmata?"
@@ -4694,9 +4738,6 @@ msgstr ""
msgid "Are you sure you want to discard your changes?"
msgstr ""
-msgid "Are you sure you want to erase this build?"
-msgstr ""
-
msgid "Are you sure you want to import %d repository?"
msgid_plural "Are you sure you want to import %d repositories?"
msgstr[0] ""
@@ -4744,6 +4785,9 @@ msgstr ""
msgid "Are you sure you want to remove this list?"
msgstr ""
+msgid "Are you sure you want to remove this nickname?"
+msgstr ""
+
msgid "Are you sure you want to reset the health check token?"
msgstr "Confermi di voler resettare il token di controllo di stato?"
@@ -4756,10 +4800,10 @@ 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?"
+msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
msgstr ""
-msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
+msgid "Are you sure you want to revoke this project access token? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to stop this environment?"
@@ -4906,9 +4950,6 @@ msgstr ""
msgid "Assigned to %{assignee_name}"
msgstr ""
-msgid "Assigned to %{name}"
-msgstr ""
-
msgid "Assigned to me"
msgstr ""
@@ -4973,6 +5014,9 @@ msgstr[1] ""
msgid "Attaching the file failed."
msgstr ""
+msgid "Attention"
+msgstr ""
+
msgid "Audit Events"
msgstr ""
@@ -5135,6 +5179,12 @@ msgstr ""
msgid "Authorized applications (%{size})"
msgstr ""
+msgid "AuthorizedApplication|Are you sure you want to revoke this application?"
+msgstr ""
+
+msgid "AuthorizedApplication|Revoke application"
+msgstr ""
+
msgid "Authors: %{authors}"
msgstr ""
@@ -6328,6 +6378,9 @@ msgstr ""
msgid "CICDAnalytics|Shared Runners Usage"
msgstr ""
+msgid "CICDAnalytics|Shared runner pipeline minute duration by month"
+msgstr ""
+
msgid "CICDAnalytics|Shared runner usage"
msgstr ""
@@ -6469,6 +6522,9 @@ msgstr ""
msgid "Can create groups:"
msgstr ""
+msgid "Can not delete primary training"
+msgstr ""
+
msgid "Can't apply as the source branch was deleted."
msgstr ""
@@ -6802,9 +6858,6 @@ msgstr ""
msgid "Changing any setting here requires an application restart"
msgstr ""
-msgid "Changing group URL can have unintended side effects."
-msgstr ""
-
msgid "Charts can't be displayed as the request for data has timed out. %{documentationLink}"
msgstr ""
@@ -6892,9 +6945,6 @@ msgstr ""
msgid "Checking branch availability..."
msgstr "Controllo disponibilità branch..."
-msgid "Checking group URL availability..."
-msgstr ""
-
msgid "Checking group path availability..."
msgstr ""
@@ -7388,6 +7438,9 @@ msgstr ""
msgid "Clear recent searches"
msgstr ""
+msgid "Clear repository checks"
+msgstr ""
+
msgid "Clear search"
msgstr ""
@@ -7520,9 +7573,6 @@ msgstr ""
msgid "Closed MRs"
msgstr ""
-msgid "Closed epics"
-msgstr ""
-
msgid "Closed issues"
msgstr ""
@@ -7559,13 +7609,13 @@ msgstr ""
msgid "Cluster level"
msgstr ""
-msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
+msgid "Cluster type must be specified for Stages::ClusterEndpointInserter"
msgstr ""
msgid "ClusterAgents|%{name} successfully deleted"
msgstr ""
-msgid "ClusterAgents|%{number} of %{total} Agents"
+msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
@@ -7607,6 +7657,15 @@ msgstr ""
msgid "ClusterAgents|Agent never connected to GitLab"
msgstr ""
+msgid "ClusterAgents|Agent version mismatch"
+msgstr ""
+
+msgid "ClusterAgents|Agent version mismatch and update"
+msgstr ""
+
+msgid "ClusterAgents|Agent version update required"
+msgstr ""
+
msgid "ClusterAgents|All"
msgstr ""
@@ -7631,7 +7690,7 @@ msgstr ""
msgid "ClusterAgents|Configuration"
msgstr ""
-msgid "ClusterAgents|Connect a cluster through the Agent"
+msgid "ClusterAgents|Connect a cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connect existing cluster"
@@ -7640,13 +7699,13 @@ msgstr ""
msgid "ClusterAgents|Connect with a certificate"
msgstr ""
-msgid "ClusterAgents|Connect with agent"
+msgid "ClusterAgents|Connect with an agent"
msgstr ""
msgid "ClusterAgents|Connect with the GitLab Agent"
msgstr ""
-msgid "ClusterAgents|Connect your cluster through the Agent"
+msgid "ClusterAgents|Connect your cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connected"
@@ -7706,7 +7765,10 @@ msgstr ""
msgid "ClusterAgents|How to register an agent?"
msgstr ""
-msgid "ClusterAgents|Install new Agent"
+msgid "ClusterAgents|How to update an agent?"
+msgstr ""
+
+msgid "ClusterAgents|Install a new agent"
msgstr ""
msgid "ClusterAgents|Last connected %{timeAgo}."
@@ -7733,7 +7795,7 @@ msgstr ""
msgid "ClusterAgents|Never connected"
msgstr ""
-msgid "ClusterAgents|No Agents"
+msgid "ClusterAgents|No agents"
msgstr ""
msgid "ClusterAgents|No clusters connected through cluster certificates"
@@ -7793,6 +7855,9 @@ msgstr ""
msgid "ClusterAgents|The agent has not been connected in a long time. There might be a connectivity issue. Last contact was %{timeAgo}."
msgstr ""
+msgid "ClusterAgents|The agent version do not match each other across your cluster's pods. This can happen when a new agent version was just deployed and Kubernetes is shutting down the old pods."
+msgstr ""
+
msgid "ClusterAgents|The recommended installation method includes the token. If you want to follow the advanced installation method provided in the docs, make sure you save the token value before you close this window."
msgstr ""
@@ -7840,6 +7905,9 @@ msgstr ""
msgid "ClusterAgents|You will need to create a token to connect to your agent"
msgstr ""
+msgid "ClusterAgents|Your agent version is out of sync with your GitLab version (v%{version}), which might cause compatibility problems. Update the agent installed on your cluster to the most recent version."
+msgstr ""
+
msgid "ClusterAgents|Your instance doesn't have the %{linkStart}GitLab Agent Server (KAS)%{linkEnd} set up. Ask a GitLab Administrator to install it."
msgstr ""
@@ -8716,9 +8784,6 @@ msgstr ""
msgid "Comma-separated list of email addresses."
msgstr ""
-msgid "Comma-separated list of users allowed to exceed the rate limit."
-msgstr ""
-
msgid "Comma-separated, e.g. '1.1.1.1, 2.2.2.0/24'"
msgstr ""
@@ -9045,6 +9110,12 @@ msgstr ""
msgid "Confidential"
msgstr ""
+msgid "Confidential issue"
+msgstr ""
+
+msgid "Confidential note"
+msgstr ""
+
msgid "Confidentiality"
msgstr ""
@@ -9078,6 +9149,9 @@ msgstr ""
msgid "Configure Dependency Scanning in `.gitlab-ci.yml`, creating this file if it does not already exist"
msgstr ""
+msgid "Configure GitLab"
+msgstr ""
+
msgid "Configure GitLab runners to start using the Web Terminal. %{helpStart}Learn more.%{helpEnd}"
msgstr ""
@@ -9126,6 +9200,15 @@ msgstr ""
msgid "Configure pipelines to deploy web apps, backend services, APIs and static resources to Google Cloud"
msgstr ""
+msgid "Configure region"
+msgstr ""
+
+msgid "Configure region for environment"
+msgstr ""
+
+msgid "Configure regions"
+msgstr ""
+
msgid "Configure repository mirroring."
msgstr ""
@@ -9159,6 +9242,9 @@ msgstr ""
msgid "Configure which lists are shown for anyone who visits this board"
msgstr ""
+msgid "Configure your environments to be deployed to specific geographical regions"
+msgstr ""
+
msgid "Confirm"
msgstr ""
@@ -9861,10 +9947,10 @@ msgstr ""
msgid "CorpusManagement|Actions"
msgstr ""
-msgid "CorpusManagement|Corpus are used in fuzz testing as mutation source to Improve future testing."
+msgid "CorpusManagement|Corpus file"
msgstr ""
-msgid "CorpusManagement|Corpus file"
+msgid "CorpusManagement|Corpus files are used in coverage-guided fuzz testing as seed inputs to improve testing."
msgstr ""
msgid "CorpusManagement|Corpus files must be in *.zip format. Maximum 5 GB"
@@ -9918,6 +10004,9 @@ msgstr ""
msgid "Could not apply %{name} command."
msgstr ""
+msgid "Could not apply %{name} command. %{message}."
+msgstr ""
+
msgid "Could not authorize chat nickname. Try again!"
msgstr ""
@@ -10068,6 +10157,9 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
+msgid "Create a group"
+msgstr ""
+
msgid "Create a merge request"
msgstr ""
@@ -10092,6 +10184,9 @@ msgstr ""
msgid "Create a personal access token on your account to pull or push via %{protocol}."
msgstr "Creare un token di accesso sul tuo account per eseguire pull o push tramite %{protocol}"
+msgid "Create a project"
+msgstr ""
+
msgid "Create an account using:"
msgstr ""
@@ -10455,6 +10550,9 @@ msgstr ""
msgid "Creation date"
msgstr ""
+msgid "Creator"
+msgstr ""
+
msgid "Credentials"
msgstr ""
@@ -10467,9 +10565,15 @@ msgstr ""
msgid "CredentialsInventory|Personal Access Tokens"
msgstr ""
+msgid "CredentialsInventory|Project Access Tokens"
+msgstr ""
+
msgid "CredentialsInventory|SSH Keys"
msgstr ""
+msgid "Credit card required to be on file in order to create a pipeline"
+msgstr ""
+
msgid "Credit card:"
msgstr ""
@@ -10653,9 +10757,6 @@ msgstr ""
msgid "Customer relations"
msgstr ""
-msgid "Customizable by an administrator."
-msgstr ""
-
msgid "Customizable by owners."
msgstr ""
@@ -10785,30 +10886,18 @@ msgstr ""
msgid "CycleAnalytics|%{selectedLabelsCount} selected (%{maxLabels} max)"
msgstr ""
-msgid "CycleAnalytics|%{stageCount} stages selected"
-msgstr ""
-
-msgid "CycleAnalytics|All stages"
-msgstr ""
-
-msgid "CycleAnalytics|Average days to completion"
+msgid "CycleAnalytics|Average time to completion"
msgstr ""
msgid "CycleAnalytics|Date"
msgstr ""
-msgid "CycleAnalytics|Days to completion"
-msgstr ""
-
msgid "CycleAnalytics|Display chart filters"
msgstr ""
msgid "CycleAnalytics|Lead Time for Changes"
msgstr ""
-msgid "CycleAnalytics|No stages selected"
-msgstr ""
-
msgid "CycleAnalytics|Number of tasks"
msgstr ""
@@ -10837,18 +10926,30 @@ msgstr ""
msgid "CycleAnalytics|Showing data for group '%{groupName}' from %{createdAfter} to %{createdBefore}"
msgstr ""
-msgid "CycleAnalytics|Stages"
+msgid "CycleAnalytics|Stage time: %{title}"
msgstr ""
msgid "CycleAnalytics|Tasks by type"
msgstr ""
-msgid "CycleAnalytics|The average time spent in the selected stage for the items that were completed on each date. Data limited to the last 500 items."
+msgid "CycleAnalytics|The average time items spent in this stage. Data limited to items completed within this date range."
msgstr ""
msgid "CycleAnalytics|The given date range is larger than 180 days"
msgstr ""
+msgid "CycleAnalytics|The total time items spent across each value stream stage. Data limited to items completed within this date range."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Stage time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Total time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|Total time"
+msgstr ""
+
msgid "CycleAnalytics|Type of work"
msgstr ""
@@ -10861,9 +10962,6 @@ msgstr ""
msgid "CycleAnalytics|project dropdown filter"
msgstr ""
-msgid "CycleAnalytics|stage dropdown"
-msgstr ""
-
msgid "DAG visualization requires at least 3 dependent jobs."
msgstr ""
@@ -10963,10 +11061,16 @@ msgstr ""
msgid "DastProfiles|AJAX spider"
msgstr ""
+msgid "DastProfiles|API"
+msgstr ""
+
+msgid "DastProfiles|API endpoint URL"
+msgstr ""
+
msgid "DastProfiles|Active"
msgstr ""
-msgid "DastProfiles|Additional request headers (Optional)"
+msgid "DastProfiles|Additional request headers (optional)"
msgstr ""
msgid "DastProfiles|Are you sure you want to delete this profile?"
@@ -10981,6 +11085,9 @@ msgstr ""
msgid "DastProfiles|Branch missing"
msgstr ""
+msgid "DastProfiles|Choose a scan method"
+msgstr ""
+
msgid "DastProfiles|Could not create the scanner profile. Please try again."
msgstr ""
@@ -11050,7 +11157,13 @@ msgstr ""
msgid "DastProfiles|Excluded URLs"
msgstr ""
-msgid "DastProfiles|Excluded URLs (Optional)"
+msgid "DastProfiles|Excluded URLs (optional)"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths (optional)"
msgstr ""
msgid "DastProfiles|Hide debug messages"
@@ -11107,9 +11220,6 @@ msgstr ""
msgid "DastProfiles|Request headers"
msgstr ""
-msgid "DastProfiles|Rest API"
-msgstr ""
-
msgid "DastProfiles|Run the AJAX spider, in addition to the traditional spider, to crawl the target site."
msgstr ""
@@ -11119,6 +11229,9 @@ msgstr ""
msgid "DastProfiles|Save profile"
msgstr ""
+msgid "DastProfiles|Scan method"
+msgstr ""
+
msgid "DastProfiles|Scan mode"
msgstr ""
@@ -11197,12 +11310,24 @@ msgstr ""
msgid "DastProfiles|Website"
msgstr ""
+msgid "DastProfiles|What does each method do?"
+msgstr ""
+
msgid "DastProfiles|You can either choose a passive scan or validate the target site from the site profile management page. %{docsLinkStart}Learn more about site validation.%{docsLinkEnd}"
msgstr ""
msgid "DastProfiles|You cannot run an active scan against an unvalidated site."
msgstr ""
+msgid "DastProfiles|folder/dast_example.har or https://example.com/dast_example.har"
+msgstr ""
+
+msgid "DastProfiles|folder/example.postman_collection.json or https://example.com/"
+msgstr ""
+
+msgid "DastProfiles|folder/openapi.json or https://example.com/openapi.json"
+msgstr ""
+
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
@@ -11310,6 +11435,9 @@ msgstr ""
msgid "DatadogIntegration|API URL"
msgstr ""
+msgid "DatadogIntegration|Custom tags in Datadog. Enter one tag per line in the %{codeOpen}key:value%{codeClose} format. %{linkOpen}How do I use tags?%{linkClose}"
+msgstr ""
+
msgid "DatadogIntegration|Environment"
msgstr ""
@@ -11328,12 +11456,18 @@ msgstr ""
msgid "DatadogIntegration|Tag all data from this GitLab instance in Datadog. Useful when managing several self-managed deployments."
msgstr ""
+msgid "DatadogIntegration|Tags"
+msgstr ""
+
msgid "DatadogIntegration|The Datadog site to send data to. To send data to the EU site, use %{codeOpen}datadoghq.eu%{codeClose}."
msgstr ""
msgid "DatadogIntegration|Trace your GitLab pipelines with Datadog."
msgstr ""
+msgid "DatadogIntegration|have an invalid format"
+msgstr ""
+
msgid "Datasource name not found"
msgstr ""
@@ -11343,9 +11477,6 @@ msgstr ""
msgid "Date merged"
msgstr ""
-msgid "Date picker"
-msgstr ""
-
msgid "Date range"
msgstr ""
@@ -11499,9 +11630,6 @@ msgstr ""
msgid "Definition"
msgstr ""
-msgid "Delayed Project Deletion (%{adjourned_deletion})"
-msgstr ""
-
msgid "DelayedJobs|Are you sure you want to run %{jobName} immediately? Otherwise this job will run automatically after its timer finishes."
msgstr ""
@@ -11580,10 +11708,10 @@ msgstr ""
msgid "Delete pipeline"
msgstr ""
-msgid "Delete project"
+msgid "Delete pipeline schedule"
msgstr ""
-msgid "Delete project. Are you ABSOLUTELY SURE?"
+msgid "Delete project"
msgstr ""
msgid "Delete row"
@@ -11613,6 +11741,9 @@ msgstr ""
msgid "Delete this epic and all descendants?"
msgstr ""
+msgid "Delete this project"
+msgstr ""
+
msgid "Delete user list"
msgstr ""
@@ -11871,6 +12002,12 @@ msgstr ""
msgid "Deploy to..."
msgstr ""
+msgid "DeployBoards|To see deployment progress for your environments, make sure you are deploying to %{codeStart}$KUBE_NAMESPACE%{codeEnd} and annotating with %{codeStart}app.gitlab.com/app=$CI_PROJECT_PATH_SLUG%{codeEnd} and %{codeStart}app.gitlab.com/env=$CI_ENVIRONMENT_SLUG%{codeEnd}."
+msgstr ""
+
+msgid "DeployBoard|Kubernetes Pods"
+msgstr ""
+
msgid "DeployFreeze|Add a freeze period to prevent unintended releases during a period of time for a given environment. You must update the deployment jobs in %{filename} according to the deploy freezes added here. %{freeze_period_link_start}Learn more.%{freeze_period_link_end}"
msgstr ""
@@ -11955,9 +12092,6 @@ msgstr ""
msgid "DeployTokens|Active Deploy Tokens (%{active_tokens})"
msgstr ""
-msgid "DeployTokens|Allows read and write access to registry images."
-msgstr ""
-
msgid "DeployTokens|Allows read and write access to the package registry."
msgstr ""
@@ -11970,6 +12104,9 @@ msgstr ""
msgid "DeployTokens|Allows read-only access to the repository."
msgstr ""
+msgid "DeployTokens|Allows write access to registry images."
+msgstr ""
+
msgid "DeployTokens|Copy deploy token"
msgstr ""
@@ -12063,12 +12200,57 @@ msgstr ""
msgid "Deploying to AWS is easy with GitLab"
msgstr ""
+msgid "Deployment"
+msgstr ""
+
msgid "Deployment Frequency"
msgstr ""
+msgid "Deployment Target|Project deployment target (optional)"
+msgstr ""
+
+msgid "Deployment Target|Select the deployment target"
+msgstr ""
+
msgid "Deployment frequency"
msgstr ""
+msgid "DeploymentTarget|GitLab Pages"
+msgstr ""
+
+msgid "DeploymentTarget|Heroku"
+msgstr ""
+
+msgid "DeploymentTarget|Infrastructure provider (Terraform, Cloudformation, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Kubernetes (GKE, EKS, OpenShift, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Managed container runtime (Fargate, Cloud Run, DigitalOcean App)"
+msgstr ""
+
+msgid "DeploymentTarget|Mobile app store"
+msgstr ""
+
+msgid "DeploymentTarget|No deployment planned"
+msgstr ""
+
+msgid "DeploymentTarget|Other hosting service"
+msgstr ""
+
+msgid "DeploymentTarget|Registry (package or container)"
+msgstr ""
+
+msgid "DeploymentTarget|Self-managed container runtime (Podman, Docker Swarm, Docker Compose)"
+msgstr ""
+
+msgid "DeploymentTarget|Serverless backend (Lambda, Cloud functions)"
+msgstr ""
+
+msgid "DeploymentTarget|Virtual machine (for example, EC2)"
+msgstr ""
+
msgid "Deployments"
msgstr ""
@@ -12107,6 +12289,9 @@ msgstr ""
msgid "Deployment|This deployment was created using the API"
msgstr ""
+msgid "Deployment|Triggerer"
+msgstr ""
+
msgid "Deployment|Waiting"
msgstr ""
@@ -12134,6 +12319,18 @@ msgstr ""
msgid "Deprecated API rate limits"
msgstr ""
+msgid "Deprecations|Feature deprecation and removal"
+msgstr ""
+
+msgid "Deprecations|For information on a possible replacement %{epicStart} learn more about Opstrace %{epicEnd}."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7 and are %{epicStart} scheduled for removal %{epicEnd} in GitLab 15.0."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7, and are %{removal_link_start} scheduled for removal %{link_end} in GitLab 15.0. For information on a possible replacement, %{opstrace_link_start} learn more about Opstrace %{link_end}."
+msgstr ""
+
msgid "Deprioritize label"
msgstr ""
@@ -12379,10 +12576,10 @@ msgstr ""
msgid "DevopsAdoption|At least one deploy"
msgstr ""
-msgid "DevopsAdoption|At least one issue opened"
+msgid "DevopsAdoption|At least one issue created"
msgstr ""
-msgid "DevopsAdoption|At least one merge request opened"
+msgid "DevopsAdoption|At least one merge request created"
msgstr ""
msgid "DevopsAdoption|At least one pipeline successfully run"
@@ -12583,6 +12780,9 @@ msgstr ""
msgid "Direct member"
msgstr ""
+msgid "Direct members"
+msgstr ""
+
msgid "Direct non-authenticated users to this page."
msgstr ""
@@ -12699,6 +12899,9 @@ msgid_plural "Dismiss %d selected vulnerabilities as"
msgstr[0] ""
msgstr[1] ""
+msgid "Dismiss Alert"
+msgstr ""
+
msgid "Dismiss merge request promotion"
msgstr ""
@@ -12726,9 +12929,15 @@ msgstr ""
msgid "Display alerts from all configured monitoring tools."
msgstr ""
+msgid "Display milestones"
+msgstr ""
+
msgid "Display name"
msgstr ""
+msgid "Display progress of child issues"
+msgstr ""
+
msgid "Display rendered file"
msgstr ""
@@ -12834,6 +13043,9 @@ msgstr ""
msgid "Download image"
msgstr ""
+msgid "Download payload"
+msgstr ""
+
msgid "Download raw data (.csv)"
msgstr ""
@@ -13011,6 +13223,9 @@ msgstr ""
msgid "Edit in Web IDE"
msgstr ""
+msgid "Edit in pipeline editor"
+msgstr ""
+
msgid "Edit in single-file editor"
msgstr ""
@@ -13053,6 +13268,9 @@ msgstr ""
msgid "Edit your most recent comment in a thread (from an empty textarea)"
msgstr ""
+msgid "Edit, lint, and visualize your pipeline."
+msgstr ""
+
msgid "Edited"
msgstr ""
@@ -13494,6 +13712,9 @@ msgstr ""
msgid "Enforce two-factor authentication for all user sign-ins."
msgstr ""
+msgid "Enhance security by storing service account keys in secret managers - learn more about %{docLinkStart}secret management with GitLab%{docLinkEnd}"
+msgstr ""
+
msgid "Ensure connectivity is available from the GitLab server to the Prometheus server"
msgstr ""
@@ -13554,6 +13775,9 @@ 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 following to confirm:"
+msgstr ""
+
msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
@@ -14084,9 +14308,6 @@ 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 ""
@@ -14222,6 +14443,9 @@ msgstr ""
msgid "Errors:"
msgstr ""
+msgid "Escalate this incident"
+msgstr ""
+
msgid "Escalation Policies"
msgstr ""
@@ -14234,6 +14458,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy"
+msgstr ""
+
msgid "Escalation policy:"
msgstr ""
@@ -14485,6 +14712,9 @@ msgstr ""
msgid "Existing sign in methods may be removed"
msgstr ""
+msgid "Exit."
+msgstr ""
+
msgid "Expand"
msgstr ""
@@ -14581,6 +14811,9 @@ msgstr "Esplora progetti"
msgid "Explore public groups"
msgstr "Esplora gruppi pubblici"
+msgid "Explore public projects"
+msgstr ""
+
msgid "Explore snippets"
msgstr ""
@@ -14742,7 +14975,7 @@ msgid_plural "Failed to archive designs. Please try again."
msgstr[0] ""
msgstr[1] ""
-msgid "Failed to assign a reviewer because no user was found."
+msgid "Failed to assign a reviewer because no user was specified."
msgstr ""
msgid "Failed to assign a user because no user was found."
@@ -14808,10 +15041,10 @@ msgstr ""
msgid "Failed to find import label for Jira import."
msgstr ""
-msgid "Failed to generate export, please try again later."
+msgid "Failed to find users for %{missing}"
msgstr ""
-msgid "Failed to generate report, please try again after sometime"
+msgid "Failed to generate export, please try again later."
msgstr ""
msgid "Failed to get ref."
@@ -14910,6 +15143,9 @@ msgstr ""
msgid "Failed to remove a to-do item for the design."
msgstr ""
+msgid "Failed to remove attention because no user was found."
+msgstr ""
+
msgid "Failed to remove mirror."
msgstr ""
@@ -14922,6 +15158,9 @@ msgstr ""
msgid "Failed to remove user key."
msgstr ""
+msgid "Failed to request attention because no user was found."
+msgstr ""
+
msgid "Failed to reset key. Please try again."
msgstr ""
@@ -15003,6 +15242,9 @@ msgstr ""
msgid "Feature Flags"
msgstr ""
+msgid "Feature deprecation and removal"
+msgstr ""
+
msgid "Feature flag status"
msgstr ""
@@ -15500,7 +15742,7 @@ msgstr ""
msgid "For each job, re-use the project workspace. If the workspace doesn't exist, use %{code_open}git clone%{code_close}."
msgstr ""
-msgid "For example, the application using the token or the purpose of the token."
+msgid "For example, the application using the token or the purpose of the token. Do not give sensitive information for the name of the token, as it will be visible to all %{resource_type} members."
msgstr ""
msgid "For files larger than this limit, only index the file name. The file content is neither indexed nor searchable."
@@ -15584,9 +15826,6 @@ msgstr ""
msgid "ForkProject|Select a namespace"
msgstr ""
-msgid "ForkProject|Select a namespace to fork the project"
-msgstr ""
-
msgid "ForkProject|The project can be accessed by any logged in user."
msgstr ""
@@ -15683,6 +15922,9 @@ msgstr ""
msgid "Full name"
msgstr ""
+msgid "GCP region configured"
+msgstr ""
+
msgid "GPG Key ID:"
msgstr ""
@@ -15863,6 +16105,9 @@ msgstr ""
msgid "Geo|Failed"
msgstr ""
+msgid "Geo|Filter Geo sites"
+msgstr ""
+
msgid "Geo|Filter by name"
msgstr ""
@@ -16274,6 +16519,12 @@ msgstr ""
msgid "GitLab Issue"
msgstr ""
+msgid "GitLab KAS"
+msgstr ""
+
+msgid "GitLab Memberships CSV Export"
+msgstr ""
+
msgid "GitLab Pages"
msgstr ""
@@ -16322,6 +16573,9 @@ 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 free to use. Many features for larger teams are part of our %{link_start}paid products%{link_end}. You can try Ultimate for free without any obligation or payment details."
+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 ""
@@ -16448,7 +16702,7 @@ msgstr ""
msgid "GitLabPages|When enabled, all attempts to visit your website through HTTP are automatically redirected to HTTPS using a response with status code 301. Requires a valid certificate for all domains. %{docs_link_start}Learn more.%{link_end}"
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. %{docs_link_start}Learn more.%{link_end}"
+msgid "GitLabPages|When using Pages under the general domain of a GitLab instance (%{pages_host}), you cannot use HTTPS with subdomains of subdomains. If your namespace or groupname contains a dot, it does not work. This is a limitation of the HTTP Over TLS protocol. HTTP pages work if you don't redirect HTTP to HTTPS. %{docs_link_start}Learn more.%{link_end}"
msgstr ""
msgid "GitLabPages|With GitLab Pages you can host your static website directly from your GitLab repository. %{docs_link_start}Learn more.%{link_end}"
@@ -16625,9 +16879,6 @@ msgstr ""
msgid "Go to find file"
msgstr ""
-msgid "Go to fork"
-msgstr ""
-
msgid "Go to issue boards"
msgstr ""
@@ -16835,9 +17086,6 @@ msgstr ""
msgid "Group Hooks"
msgstr ""
-msgid "Group ID"
-msgstr ""
-
msgid "Group Owner must have signed in with SAML before enabling Group Managed Accounts"
msgstr ""
@@ -16865,9 +17113,6 @@ msgstr ""
msgid "Group by"
msgstr ""
-msgid "Group description"
-msgstr ""
-
msgid "Group description (optional)"
msgstr ""
@@ -16982,7 +17227,7 @@ msgstr ""
msgid "Group: %{name}"
msgstr ""
-msgid "GroupActivityMetrics|Issues opened"
+msgid "GroupActivityMetrics|Issues created"
msgstr ""
msgid "GroupActivityMetrics|Last 90 days"
@@ -16991,7 +17236,7 @@ msgstr ""
msgid "GroupActivityMetrics|Members added"
msgstr ""
-msgid "GroupActivityMetrics|Merge Requests opened"
+msgid "GroupActivityMetrics|Merge Requests created"
msgstr ""
msgid "GroupActivityMetrics|Recent activity"
@@ -17282,6 +17527,9 @@ msgstr ""
msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
+msgid "GroupSettings|Choose a group path that does not start with a dash or end with a period. It can also contain alphanumeric characters and underscores."
+msgstr ""
+
msgid "GroupSettings|Compliance frameworks"
msgstr ""
@@ -17315,7 +17563,7 @@ msgstr ""
msgid "GroupSettings|If not specified at the group or instance level, the default is %{default_initial_branch_name}. Does not affect existing repositories."
msgstr ""
-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."
+msgid "GroupSettings|If the parent group's visibility is lower than the group's current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility."
msgstr ""
msgid "GroupSettings|New runners registration token has been generated!"
@@ -17432,7 +17680,10 @@ msgstr ""
msgid "Groups and projects"
msgstr ""
-msgid "Groups and subgroups"
+msgid "Groups are a great way to organize projects and people."
+msgstr ""
+
+msgid "Groups are the best way to manage projects and members."
msgstr ""
msgid "Groups to synchronize"
@@ -17543,13 +17794,16 @@ msgstr ""
msgid "GroupsTree|Are you sure you want to leave the \"%{fullName}\" group?"
msgstr ""
-msgid "GroupsTree|Edit group"
+msgid "GroupsTree|Delete"
+msgstr ""
+
+msgid "GroupsTree|Edit"
msgstr ""
msgid "GroupsTree|Failed to leave the group. Please make sure you are not the only owner."
msgstr ""
-msgid "GroupsTree|Leave this group"
+msgid "GroupsTree|Leave group"
msgstr ""
msgid "GroupsTree|Loading groups"
@@ -17561,9 +17815,57 @@ msgstr ""
msgid "GroupsTree|No groups or projects matched your search"
msgstr ""
+msgid "GroupsTree|Options"
+msgstr ""
+
msgid "GroupsTree|Search by name"
msgstr ""
+msgid "Groups|Avatar will be removed. Are you sure?"
+msgstr ""
+
+msgid "Groups|Changing group URL can have unintended side effects."
+msgstr ""
+
+msgid "Groups|Checking group URL availability..."
+msgstr ""
+
+msgid "Groups|Enter a descriptive name for your group."
+msgstr ""
+
+msgid "Groups|Group ID"
+msgstr ""
+
+msgid "Groups|Group URL"
+msgstr ""
+
+msgid "Groups|Group avatar"
+msgstr ""
+
+msgid "Groups|Group description (optional)"
+msgstr ""
+
+msgid "Groups|Group name"
+msgstr ""
+
+msgid "Groups|Group path is available."
+msgstr ""
+
+msgid "Groups|Group path is unavailable. Path has been replaced with a suggested available path."
+msgstr ""
+
+msgid "Groups|Learn more"
+msgstr ""
+
+msgid "Groups|Must start with letter, digit, emoji, or underscore. Can also contain periods, dashes, spaces, and parentheses."
+msgstr ""
+
+msgid "Groups|Remove avatar"
+msgstr ""
+
+msgid "Groups|Save changes"
+msgstr ""
+
msgid "Guideline"
msgstr ""
@@ -17573,6 +17875,9 @@ msgstr ""
msgid "HAR file path or URL"
msgstr ""
+msgid "HTTP Archive (HAR)"
+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 ""
@@ -17973,6 +18278,9 @@ msgstr ""
msgid "INFO: Your SSH key is expiring soon. Please generate a new key."
msgstr ""
+msgid "IP"
+msgstr ""
+
msgid "IP Address"
msgstr ""
@@ -18009,6 +18317,9 @@ msgstr ""
msgid "IdentityVerification|Verify your identity"
msgstr ""
+msgid "IdentityVerification|You can always verify your account at a later time to create a group."
+msgstr ""
+
msgid "If any indexed field exceeds this limit, it is truncated to this number of characters. The rest of the content is neither indexed nor searchable. This does not apply to repository and wiki indexing. For unlimited characters, set this to 0."
msgstr ""
@@ -18066,6 +18377,9 @@ msgstr ""
msgid "If you add %{codeStart}needs%{codeEnd} to jobs in your pipeline you'll be able to view the %{codeStart}needs%{codeEnd} relationships between jobs in this tab as a %{linkStart}Directed Acyclic Graph (DAG)%{linkEnd}."
msgstr ""
+msgid "If you are added to a project, it will be displayed here."
+msgstr ""
+
msgid "If you did not initiate these sign-in attempts, please reach out to your administrator or enable two-factor authentication (2FA) on your account."
msgstr ""
@@ -18372,12 +18686,24 @@ msgstr ""
msgid "InProductMarketing|3 ways to dive into GitLab CI/CD"
msgstr ""
+msgid "InProductMarketing|A single application eliminates complex integrations, data chokepoints, and toolchain maintenance, resulting in greater productivity and lower cost."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features, build more efficiently, strengthen security and compliance."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features."
+msgstr ""
+
msgid "InProductMarketing|Actually, GitLab makes the team work (better)"
msgstr ""
msgid "InProductMarketing|And finally %{deploy_link} a Python application."
msgstr ""
+msgid "InProductMarketing|And many more..."
+msgstr ""
+
msgid "InProductMarketing|Are your runners ready?"
msgstr ""
@@ -18396,15 +18722,33 @@ msgstr ""
msgid "InProductMarketing|Blog"
msgstr ""
+msgid "InProductMarketing|Break down silos to coordinate seamlessly across development, operations, and security with a consistent experience across the development lifecycle."
+msgstr ""
+
+msgid "InProductMarketing|Burn up/down charts"
+msgstr ""
+
msgid "InProductMarketing|By enabling code owners and required merge approvals the right person will review the right MR. This is a win-win: cleaner code and a more efficient review process."
msgstr ""
msgid "InProductMarketing|Click on the number below that corresponds with your answer — 1 being very difficult, 5 being very easy."
msgstr ""
+msgid "InProductMarketing|Code owners"
+msgstr ""
+
msgid "InProductMarketing|Code owners and required merge approvals are part of the paid tiers of GitLab. You can start a free 30-day trial of GitLab Ultimate and enable these features in less than 5 minutes with no credit card required."
msgstr ""
+msgid "InProductMarketing|Code review analytics"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration across stages in GitLab"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration made easy"
+msgstr ""
+
msgid "InProductMarketing|Create a custom CI runner with just a few clicks"
msgstr ""
@@ -18414,12 +18758,21 @@ msgstr ""
msgid "InProductMarketing|Create a project in GitLab in 5 minutes"
msgstr ""
+msgid "InProductMarketing|Create well-defined workflows by using scoped labels on issues, merge requests, and epics. Labels with the same scope cannot be used together, which prevents conflicts."
+msgstr ""
+
msgid "InProductMarketing|Create your first project!"
msgstr ""
+msgid "InProductMarketing|Define who owns specific files or directories, so the right reviewers are suggested when a merge request introduces changes to those files."
+msgstr ""
+
msgid "InProductMarketing|Deliver Better Products Faster"
msgstr ""
+msgid "InProductMarketing|Dependency scanning"
+msgstr ""
+
msgid "InProductMarketing|Did you know teams that use GitLab are far more efficient?"
msgstr ""
@@ -18429,15 +18782,27 @@ msgstr ""
msgid "InProductMarketing|Dig in and create a project and a repo"
msgstr ""
+msgid "InProductMarketing|Discover Premium & Ultimate"
+msgstr ""
+
+msgid "InProductMarketing|Discover Premium & Ultimate."
+msgstr ""
+
msgid "InProductMarketing|Do you have a minute?"
msgstr ""
msgid "InProductMarketing|Do you have a teammate who would be perfect for this task?"
msgstr ""
+msgid "InProductMarketing|Dynamic application security testing"
+msgstr ""
+
msgid "InProductMarketing|Easy"
msgstr ""
+msgid "InProductMarketing|Epics"
+msgstr ""
+
msgid "InProductMarketing|Expand your DevOps journey with a free GitLab trial"
msgstr ""
@@ -18459,9 +18824,15 @@ msgstr ""
msgid "InProductMarketing|Feel the need for speed?"
msgstr ""
+msgid "InProductMarketing|Find and fix bottlenecks in your code review process by understanding how long open merge requests have been in review."
+msgstr ""
+
msgid "InProductMarketing|Find out how your teams are really doing"
msgstr ""
+msgid "InProductMarketing|Find out if your external libraries are safe. Run dependency scanning jobs that check for known vulnerabilities in your external libraries."
+msgstr ""
+
msgid "InProductMarketing|Follow our steps"
msgstr ""
@@ -18498,6 +18869,9 @@ msgstr ""
msgid "InProductMarketing|GitLab is better with teammates to help out!"
msgstr ""
+msgid "InProductMarketing|GitLab is infrastructure agnostic (supporting GCP, AWS, Azure, OpenShift, VMWare, On Prem, Bare Metal, and more), offering a consistent workflow experience – irrespective of the environment."
+msgstr ""
+
msgid "InProductMarketing|GitLab provides static application security testing (SAST), dynamic application security testing (DAST), container scanning, and dependency scanning to help you deliver secure applications along with license compliance."
msgstr ""
@@ -18588,21 +18962,36 @@ msgstr ""
msgid "InProductMarketing|It's also possible to simply %{external_repo_link} in order to take advantage of GitLab's CI/CD."
msgstr ""
+msgid "InProductMarketing|Keep your code quality high by defining who should approve merge requests and how many approvals are required."
+msgstr ""
+
msgid "InProductMarketing|Launch GitLab CI/CD in 20 minutes or less"
msgstr ""
+msgid "InProductMarketing|Lower cost of development"
+msgstr ""
+
+msgid "InProductMarketing|Make it easier to collaborate on high-level ideas by grouping related issues in an epic."
+msgstr ""
+
msgid "InProductMarketing|Making the switch? It's easier than you think to import your projects into GitLab. Move %{github_link}, or import something %{bitbucket_link}."
msgstr ""
msgid "InProductMarketing|Master the art of importing!"
msgstr ""
+msgid "InProductMarketing|Merge request approval rule"
+msgstr ""
+
msgid "InProductMarketing|Move on to easily creating a Pages website %{ci_template_link}"
msgstr ""
msgid "InProductMarketing|Multiple owners, confusing workstreams? We've got you covered"
msgstr ""
+msgid "InProductMarketing|Multiple required approvers"
+msgstr ""
+
msgid "InProductMarketing|Need an alternative to importing?"
msgstr ""
@@ -18615,18 +19004,33 @@ msgstr ""
msgid "InProductMarketing|Our tool brings all the things together"
msgstr ""
+msgid "InProductMarketing|Protect your web application by using DAST to examine for vulnerabilities in deployed environments."
+msgstr ""
+
msgid "InProductMarketing|Rapid development, simplified"
msgstr ""
msgid "InProductMarketing|Reduce Security & Compliance Risk"
msgstr ""
+msgid "InProductMarketing|Require multiple approvers on a merge request, so you know it's in good shape before it's merged."
+msgstr ""
+
+msgid "InProductMarketing|Roadmaps"
+msgstr ""
+
+msgid "InProductMarketing|Scoped labels"
+msgstr ""
+
msgid "InProductMarketing|Security that's integrated into your development lifecycle"
msgstr ""
msgid "InProductMarketing|Sometimes you're not ready to make a full transition to a new tool. If you're not ready to fully commit, %{mirroring_link} gives you a safe way to try out GitLab in parallel with your current tool."
msgstr ""
+msgid "InProductMarketing|Speed. Efficiency. Trust."
+msgstr ""
+
msgid "InProductMarketing|Spin up an autoscaling runner in GitLab"
msgstr ""
@@ -18636,6 +19040,9 @@ msgstr ""
msgid "InProductMarketing|Start a Self-Managed trial"
msgstr ""
+msgid "InProductMarketing|Start a free trial"
+msgstr ""
+
msgid "InProductMarketing|Start a free trial of GitLab Ultimate – no credit card required"
msgstr ""
@@ -18702,6 +19109,9 @@ msgstr ""
msgid "InProductMarketing|To understand and get the most out of GitLab, start at the beginning and %{project_link}. In GitLab, repositories are part of a project, so after you've created your project you can go ahead and %{repo_link}."
msgstr ""
+msgid "InProductMarketing|Track completed issues in a chart, so you can see how a milestone is progressing at a glance."
+msgstr ""
+
msgid "InProductMarketing|Try GitLab Ultimate for free"
msgstr ""
@@ -18738,6 +19148,9 @@ msgstr ""
msgid "InProductMarketing|Very easy"
msgstr ""
+msgid "InProductMarketing|Visualize your epics and milestones in a timeline."
+msgstr ""
+
msgid "InProductMarketing|Want to host GitLab on your servers?"
msgstr ""
@@ -18759,6 +19172,9 @@ msgstr ""
msgid "InProductMarketing|YouTube"
msgstr ""
+msgid "InProductMarketing|Your software, deployed your way"
+msgstr ""
+
msgid "InProductMarketing|Your teams can be more efficient"
msgstr ""
@@ -18879,9 +19295,18 @@ msgstr ""
msgid "IncidentManagement|No incidents to display."
msgstr ""
+msgid "IncidentManagement|None"
+msgstr ""
+
msgid "IncidentManagement|Open"
msgstr ""
+msgid "IncidentManagement|Page your team with escalation policies"
+msgstr ""
+
+msgid "IncidentManagement|Paged"
+msgstr ""
+
msgid "IncidentManagement|Published"
msgstr ""
@@ -18891,6 +19316,9 @@ msgstr ""
msgid "IncidentManagement|Severity"
msgstr ""
+msgid "IncidentManagement|Status"
+msgstr ""
+
msgid "IncidentManagement|There are no closed incidents"
msgstr ""
@@ -18909,6 +19337,9 @@ msgstr ""
msgid "IncidentManagement|Unpublished"
msgstr ""
+msgid "IncidentManagement|Use escalation policies to automatically page your team when incidents are created."
+msgstr ""
+
msgid "IncidentSettings|Activate \"time to SLA\" countdown timer"
msgstr ""
@@ -18954,7 +19385,10 @@ msgstr ""
msgid "Incidents"
msgstr ""
-msgid "Incidents|Add a URL"
+msgid "Incidents|Add image details"
+msgstr ""
+
+msgid "Incidents|Add text or a link to display with your image. If you don't add either, the file name displays instead."
msgstr ""
msgid "Incidents|Drop or %{linkStart}upload%{linkEnd} a metric screenshot to attach it to the incident"
@@ -18969,10 +19403,10 @@ msgstr ""
msgid "Incidents|There was an issue loading metric images."
msgstr ""
-msgid "Incidents|There was an issue uploading your image."
+msgid "Incidents|There was an issue updating your image."
msgstr ""
-msgid "Incidents|You can optionally add a URL to link users to the original graph."
+msgid "Incidents|There was an issue uploading your image."
msgstr ""
msgid "Incident|Alert details"
@@ -18981,9 +19415,18 @@ msgstr ""
msgid "Incident|Are you sure you wish to delete this image?"
msgstr ""
+msgid "Incident|Delete image"
+msgstr ""
+
msgid "Incident|Deleting %{filename}"
msgstr ""
+msgid "Incident|Edit image text or link"
+msgstr ""
+
+msgid "Incident|Editing %{filename}"
+msgstr ""
+
msgid "Incident|Metrics"
msgstr ""
@@ -19253,12 +19696,18 @@ msgstr ""
msgid "Integrations|Branches for which notifications are to be sent"
msgstr ""
+msgid "Integrations|Clear if using a self-signed certificate."
+msgstr ""
+
msgid "Integrations|Comment detail:"
msgstr ""
msgid "Integrations|Comment settings:"
msgstr ""
+msgid "Integrations|Connection details"
+msgstr ""
+
msgid "Integrations|Connection failed. Please check your settings."
msgstr ""
@@ -19283,6 +19732,9 @@ msgstr ""
msgid "Integrations|Enable GitLab.com slash commands in a Slack workspace."
msgstr ""
+msgid "Integrations|Enable SSL verification"
+msgstr ""
+
msgid "Integrations|Enable comments"
msgstr ""
@@ -19361,6 +19813,9 @@ msgstr ""
msgid "Integrations|Return to GitLab for Jira"
msgstr ""
+msgid "Integrations|SSL verification"
+msgstr ""
+
msgid "Integrations|Save settings?"
msgstr ""
@@ -19406,9 +19861,6 @@ msgstr ""
msgid "Integrations|Use default settings"
msgstr ""
-msgid "Integrations|When you mention a Jira issue in a commit or merge request, GitLab creates a remote link and comment (if enabled)."
-msgstr ""
-
msgid "Integrations|You can now close this window and return to the GitLab for Jira application."
msgstr ""
@@ -19433,9 +19885,6 @@ msgstr ""
msgid "Integrations|can't exceed %{recipients_limit}"
msgstr ""
-msgid "Interactive developer security education."
-msgstr ""
-
msgid "Interactive mode"
msgstr ""
@@ -19925,6 +20374,9 @@ msgstr ""
msgid "IssueAnalytics|Assignees"
msgstr ""
+msgid "IssueAnalytics|Created by"
+msgstr ""
+
msgid "IssueAnalytics|Due date"
msgstr ""
@@ -19937,9 +20389,6 @@ msgstr ""
msgid "IssueAnalytics|Milestone"
msgstr ""
-msgid "IssueAnalytics|Opened by"
-msgstr ""
-
msgid "IssueAnalytics|Status"
msgstr ""
@@ -20063,10 +20512,10 @@ msgstr ""
msgid "IssuesAnalytics|Avg/Month:"
msgstr ""
-msgid "IssuesAnalytics|Issues opened"
+msgid "IssuesAnalytics|Issues created"
msgstr ""
-msgid "IssuesAnalytics|Issues opened per month"
+msgid "IssuesAnalytics|Issues created per month"
msgstr ""
msgid "IssuesAnalytics|Last 12 months"
@@ -20093,6 +20542,9 @@ msgstr ""
msgid "It looks like you have some draft commits in this branch."
msgstr ""
+msgid "It looks like you're attempting to activate your subscription. Use %{a_start}the Subscription page%{a_end} instead."
+msgstr ""
+
msgid "It may be several days before you see feature usage data."
msgstr ""
@@ -20321,6 +20773,9 @@ msgstr ""
msgid "JiraConnect|You can now close this window and return to Jira."
msgstr ""
+msgid "JiraConnect|You don't have permission to create branches for this project. Select a different project or contact the project owner for access. %{linkStart}Learn more.%{linkEnd}"
+msgstr ""
+
msgid "JiraRequest|A connection error occurred while connecting to Jira. Try your request again."
msgstr ""
@@ -20369,13 +20824,13 @@ msgstr ""
msgid "JiraService|Define the type of Jira issue to create from a vulnerability."
msgstr ""
-msgid "JiraService|Displaying Jira issues while leaving the GitLab issue functionality enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
+msgid "JiraService|Displaying Jira issues while leaving GitLab issues also enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
msgstr ""
-msgid "JiraService|Enable Jira issues"
+msgid "JiraService|Enable Jira issue creation from vulnerabilities"
msgstr ""
-msgid "JiraService|Enable Jira issues creation from vulnerabilities"
+msgid "JiraService|Enable Jira issues"
msgstr ""
msgid "JiraService|Enable Jira transitions"
@@ -20492,16 +20947,19 @@ msgstr ""
msgid "JiraService|View Jira issues in GitLab"
msgstr ""
-msgid "JiraService|Warning: All GitLab users that have access to this GitLab project are able to view all issues from the Jira project specified below."
+msgid "JiraService|Warning: All GitLab users with access to this GitLab project can view all issues from the Jira project you select."
msgstr ""
msgid "JiraService|Web URL"
msgstr ""
-msgid "JiraService|Work on Jira issues without leaving GitLab. Adds a Jira menu to access your list of Jira issues and view any issue as read-only."
+msgid "JiraService|When a Jira issue is mentioned in a commit or merge request, a remote link and comment (if enabled) will be created."
+msgstr ""
+
+msgid "JiraService|Work on Jira issues without leaving GitLab. Add a Jira menu to access a read-only list of your Jira issues."
msgstr ""
-msgid "JiraService|You need to configure Jira before enabling this integration. For more details, read the %{jira_doc_link_start}Jira integration documentation%{link_end}."
+msgid "JiraService|You must configure Jira before enabling this integration. %{jira_doc_link_start}Learn more.%{link_end}"
msgstr ""
msgid "Job"
@@ -20513,9 +20971,6 @@ msgstr ""
msgid "Job Failed #%{build_id}"
msgstr ""
-msgid "Job ID"
-msgstr ""
-
msgid "Job artifact"
msgstr ""
@@ -20582,9 +21037,27 @@ msgstr ""
msgid "Jobs|You're about to retry a job that failed because it attempted to deploy code that is older than the latest deployment. Retrying this job could result in overwriting the environment with the older source code."
msgstr ""
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source} into %{target}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{ref}"
+msgstr ""
+
+msgid "Job|Are you sure you want to erase this job log and artifacts?"
+msgstr ""
+
msgid "Job|Browse"
msgstr ""
+msgid "Job|Cancel"
+msgstr ""
+
msgid "Job|Complete Raw"
msgstr ""
@@ -20594,6 +21067,9 @@ msgstr ""
msgid "Job|Erase job log and artifacts"
msgstr ""
+msgid "Job|Finished at"
+msgstr ""
+
msgid "Job|Job artifacts"
msgstr ""
@@ -20606,7 +21082,7 @@ msgstr ""
msgid "Job|Keep"
msgstr ""
-msgid "Job|Pipeline"
+msgid "Job|Retry"
msgstr ""
msgid "Job|Scroll to bottom"
@@ -20618,6 +21094,9 @@ msgstr ""
msgid "Job|Show complete raw"
msgstr ""
+msgid "Job|Status"
+msgstr ""
+
msgid "Job|The artifacts were removed"
msgstr ""
@@ -20645,21 +21124,12 @@ msgstr ""
msgid "Job|delayed"
msgstr ""
-msgid "Job|for"
-msgstr ""
-
-msgid "Job|into"
-msgstr ""
-
msgid "Job|manual"
msgstr ""
msgid "Job|triggered"
msgstr ""
-msgid "Job|with"
-msgstr ""
-
msgid "Join Zoom meeting"
msgstr ""
@@ -20762,9 +21232,6 @@ msgstr ""
msgid "Ki"
msgstr ""
-msgid "Kontra"
-msgstr ""
-
msgid "Kroki"
msgstr ""
@@ -21088,6 +21555,9 @@ msgstr ""
msgid "Learn more about Auto DevOps"
msgstr ""
+msgid "Learn more about GitLab"
+msgstr ""
+
msgid "Learn more about Needs relationships"
msgstr ""
@@ -21415,9 +21885,18 @@ msgstr ""
msgid "Licenses|Displays licenses detected in the project, based on the %{linkStart}latest successful%{linkEnd} scan"
msgstr ""
+msgid "Licenses|Drag your license file here or %{linkStart}click to upload%{linkEnd}."
+msgstr ""
+
+msgid "Licenses|Drop your license file to start the upload."
+msgstr ""
+
msgid "Licenses|Error fetching the license list. Please check your network connection and try again."
msgstr ""
+msgid "Licenses|Error: You are trying to upload something other than a file"
+msgstr ""
+
msgid "Licenses|License Compliance"
msgstr ""
@@ -21436,6 +21915,9 @@ msgstr ""
msgid "Licenses|Specified policies in this project"
msgstr ""
+msgid "Licenses|The file could not be uploaded."
+msgstr ""
+
msgid "Licenses|The license list details information about the licenses used within your project."
msgstr ""
@@ -21469,11 +21951,6 @@ msgstr ""
msgid "Limit the size of Sidekiq jobs stored in Redis."
msgstr ""
-msgid "Limited to showing %d event at most"
-msgid_plural "Limited to showing %d events at most"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Limiting mode"
msgstr ""
@@ -21483,6 +21960,9 @@ msgstr ""
msgid "Link"
msgstr ""
+msgid "Link (optional)"
+msgstr ""
+
msgid "Link Prometheus monitoring to GitLab."
msgstr ""
@@ -21519,6 +21999,9 @@ msgstr ""
msgid "Linked emails (%{email_count})"
msgstr ""
+msgid "Linked epics"
+msgstr ""
+
msgid "Linked issues"
msgstr ""
@@ -21546,6 +22029,15 @@ msgstr ""
msgid "List of all merge commits"
msgstr ""
+msgid "List of environments for this project"
+msgstr ""
+
+msgid "List of suitable GCP locations"
+msgstr ""
+
+msgid "List of users allowed to exceed the rate limit."
+msgstr ""
+
msgid "List options"
msgstr ""
@@ -21765,6 +22257,9 @@ msgstr ""
msgid "Maintenance mode"
msgstr ""
+msgid "Make adjustments to how your GitLab instance is set up."
+msgstr ""
+
msgid "Make and review changes in the browser with the Web IDE"
msgstr ""
@@ -21909,6 +22404,12 @@ msgstr ""
msgid "MarkdownEditor|Add italic text (%{modifier_key}I)"
msgstr ""
+msgid "MarkdownEditor|Add strikethrough text (%{modifierKey}⇧X)"
+msgstr ""
+
+msgid "MarkdownEditor|Add strikethrough text (%{modifier_key}⇧X)"
+msgstr ""
+
msgid "Marked For Deletion At - %{deletion_time}"
msgstr ""
@@ -22170,6 +22671,9 @@ msgstr ""
msgid "Maximum push size (MB)"
msgstr ""
+msgid "Maximum requests per 10 minutes per user"
+msgstr ""
+
msgid "Maximum requests per minute"
msgstr ""
@@ -22260,6 +22764,19 @@ msgstr ""
msgid "Members of a group may only view projects they have permission to access"
msgstr ""
+msgid "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seat in use and will be billed for the overage."
+msgid_plural "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seats in use and will be billed for the overage."
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "MembersOverage|You are about to incur additional charges"
+msgstr ""
+
+msgid "MembersOverage|Your subscription includes %d seat."
+msgid_plural "MembersOverage|Your subscription includes %d seats."
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Membership"
msgstr ""
@@ -22464,9 +22981,6 @@ msgstr ""
msgid "Merge request not merged"
msgstr ""
-msgid "Merge request pipelines 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 merge request pipelines."
-msgstr ""
-
msgid "Merge request reports"
msgstr ""
@@ -22563,13 +23077,13 @@ msgstr ""
msgid "MergeRequests|Create issue to resolve thread"
msgstr ""
-msgid "MergeRequests|Failed to squash. Should be done manually."
+msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Saving the comment failed"
+msgid "MergeRequests|Squashing failed: Squash the commits locally, resolve any conflicts, then push the branch."
msgstr ""
-msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
+msgid "MergeRequests|Squashing not allowed: This project doesn't allow you to squash commits when merging."
msgstr ""
msgid "MergeRequests|Thread stays resolved"
@@ -23410,6 +23924,18 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "MrList|Assigned to %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from assignee %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from reviewer %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Review requested from %{name}, go to their profile."
+msgstr ""
+
msgid "Multi-project"
msgstr ""
@@ -23443,7 +23969,7 @@ msgstr ""
msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "My Awesome Group"
+msgid "My awesome group"
msgstr ""
msgid "My company or team"
@@ -24065,9 +24591,6 @@ msgstr ""
msgid "No available branches"
msgstr ""
-msgid "No available groups to fork the project."
-msgstr ""
-
msgid "No branches found"
msgstr ""
@@ -24278,6 +24801,9 @@ msgstr ""
msgid "No ref selected"
msgstr ""
+msgid "No regions configured"
+msgstr ""
+
msgid "No related merge requests found."
msgstr ""
@@ -25082,6 +25608,9 @@ msgstr ""
msgid "Only reCAPTCHA v2 is supported:"
msgstr ""
+msgid "Only required if not using role instance credentials."
+msgstr ""
+
msgid "Only use lowercase letters, numbers, and underscores."
msgstr ""
@@ -25106,9 +25635,6 @@ msgstr ""
msgid "Open a CLI and connect to the cluster you want to install the agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
-msgid "Open epics"
-msgstr ""
-
msgid "Open errors"
msgstr ""
@@ -25148,8 +25674,8 @@ msgstr ""
msgid "Opened issues"
msgstr ""
-msgid "OpenedNDaysAgo|Opened"
-msgstr "Aperto"
+msgid "OpenedNDaysAgo|Created"
+msgstr ""
msgid "Opens in a new window"
msgstr "Si apre in una nuova finestra"
@@ -25193,9 +25719,6 @@ msgstr ""
msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
-msgid "Optional."
-msgstr ""
-
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
msgstr ""
@@ -25984,6 +26507,9 @@ msgstr ""
msgid "PerformanceBar|Memory"
msgstr ""
+msgid "PerformanceBar|Memory report"
+msgstr ""
+
msgid "PerformanceBar|Redis calls"
msgstr ""
@@ -26017,18 +26543,12 @@ msgstr ""
msgid "PerformanceBar|wall"
msgstr ""
-msgid "Performs a rebase but skips triggering a new pipeline"
-msgstr ""
-
msgid "Period in seconds"
msgstr ""
msgid "Permalink"
msgstr ""
-msgid "Permanently delete project"
-msgstr ""
-
msgid "Permanently remove group"
msgstr ""
@@ -26299,6 +26819,51 @@ msgstr ""
msgid "PipelineStatusTooltip|Pipeline: %{ci_status}"
msgstr ""
+msgid "PipelineWizardDefaultCommitMessage|Add %{filename}"
+msgstr ""
+
+msgid "PipelineWizardDefaultCommitMessage|Update %{filename}"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|At least one entry is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This field is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This value is not valid"
+msgstr ""
+
+msgid "PipelineWizardListWidget|add another step"
+msgstr ""
+
+msgid "PipelineWizardListWidget|remove step"
+msgstr ""
+
+msgid "PipelineWizard|Commit"
+msgstr ""
+
+msgid "PipelineWizard|Commit Message"
+msgstr ""
+
+msgid "PipelineWizard|Commit changes to your file"
+msgstr ""
+
+msgid "PipelineWizard|Commit file to Branch"
+msgstr ""
+
+msgid "PipelineWizard|Commit your new file"
+msgstr ""
+
+msgid "PipelineWizard|The file has been committed."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem committing the changes."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem while checking whether your file already exists in the specified branch."
+msgstr ""
+
msgid "Pipelines"
msgstr "Pipeline"
@@ -26413,7 +26978,7 @@ msgstr ""
msgid "Pipelines|Project cache successfully reset."
msgstr ""
-msgid "Pipelines|Revoke"
+msgid "Pipelines|Revoke trigger"
msgstr ""
msgid "Pipelines|Something went wrong while cleaning runners cache."
@@ -26458,6 +27023,12 @@ msgstr ""
msgid "Pipelines|This is a child pipeline within the parent pipeline"
msgstr ""
+msgid "Pipelines|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipelines|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipelines|This pipeline will run code originating from a forked project merge request. This means that the code can potentially have security considerations like exposing CI variables."
msgstr ""
@@ -26500,9 +27071,6 @@ msgstr ""
msgid "Pipelines|Your changes have been successfully committed. Now redirecting to the new merge request page."
msgstr ""
-msgid "Pipelines|detached"
-msgstr ""
-
msgid "Pipelines|error"
msgstr ""
@@ -26512,10 +27080,13 @@ msgstr ""
msgid "Pipelines|latest"
msgstr ""
-msgid "Pipelines|stuck"
+msgid "Pipelines|merge request"
msgstr ""
-msgid "Pipelines|train"
+msgid "Pipelines|merge train"
+msgstr ""
+
+msgid "Pipelines|stuck"
msgstr ""
msgid "Pipelines|yaml invalid"
@@ -26647,6 +27218,12 @@ msgstr ""
msgid "Pipeline|This change will not change the overall test coverage if merged."
msgstr ""
+msgid "Pipeline|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipeline|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipeline|Trigger author"
msgstr ""
@@ -26671,6 +27248,12 @@ msgstr ""
msgid "Pipeline|for"
msgstr ""
+msgid "Pipeline|merge request"
+msgstr ""
+
+msgid "Pipeline|merge train"
+msgstr ""
+
msgid "Pipeline|on"
msgstr ""
@@ -26809,9 +27392,6 @@ msgstr ""
msgid "Please enter a valid time interval"
msgstr ""
-msgid "Please enter or upload a valid license."
-msgstr ""
-
msgid "Please enter your current password."
msgstr ""
@@ -26920,9 +27500,6 @@ msgstr ""
msgid "Please type %{phrase_code} to proceed or close this modal to cancel."
msgstr ""
-msgid "Please type the following to confirm:"
-msgstr ""
-
msgid "Please use this form to report to the admin users who create spam issues, comments or behave inappropriately."
msgstr ""
@@ -26950,12 +27527,27 @@ msgstr ""
msgid "Policies"
msgstr ""
+msgid "Policy '%{escalation_policy_name}' does not exist."
+msgstr ""
+
msgid "Policy management project does have any policies in %{policy_path}"
msgstr ""
msgid "Policy project doesn't exist"
msgstr ""
+msgid "PolicyRuleMultiSelect|%{firstLabel} +%{numberOfAdditionalLabels} more"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|All %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select all"
+msgstr ""
+
msgid "Polling interval multiplier"
msgstr ""
@@ -27184,6 +27776,9 @@ msgstr ""
msgid "Private projects can be created in your personal namespace with:"
msgstr ""
+msgid "Problem with %{name} command: %{message}."
+msgstr ""
+
msgid "Proceed"
msgstr ""
@@ -27658,6 +28253,9 @@ msgstr ""
msgid "Progress"
msgstr ""
+msgid "Progress tracking"
+msgstr ""
+
msgid "Project"
msgstr ""
@@ -27889,6 +28487,9 @@ msgstr ""
msgid "ProjectQualitySummary|Failure"
msgstr ""
+msgid "ProjectQualitySummary|Get insight into the overall percentage of tests in your project that succeed, fail and are skipped."
+msgstr ""
+
msgid "ProjectQualitySummary|Latest pipeline results"
msgstr ""
@@ -27907,6 +28508,12 @@ msgstr ""
msgid "ProjectQualitySummary|See project Code Coverage Statistics"
msgstr ""
+msgid "ProjectQualitySummary|Set up test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|Set up test runs (opens in a new tab)"
+msgstr ""
+
msgid "ProjectQualitySummary|Skipped"
msgstr ""
@@ -28183,13 +28790,19 @@ msgstr ""
msgid "ProjectSettings|LFS objects from this repository are available to forks. %{linkStart}How do I remove them?%{linkEnd}"
msgstr ""
+msgid "ProjectSettings|Learn about commit history."
+msgstr ""
+
+msgid "ProjectSettings|Leave empty to use default template."
+msgstr ""
+
msgid "ProjectSettings|Manage who can see the project in the public access directory."
msgstr ""
msgid "ProjectSettings|Manages large files such as audio, video, and graphics files."
msgstr ""
-msgid "ProjectSettings|Maximum 500 characters."
+msgid "ProjectSettings|Maximum %{maxLength} characters."
msgstr ""
msgid "ProjectSettings|Merge checks"
@@ -28330,6 +28943,9 @@ msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
msgstr ""
+msgid "ProjectSettings|The default template will be applied on save."
+msgstr ""
+
msgid "ProjectSettings|These checks must pass before merge requests can be merged."
msgstr ""
@@ -28384,6 +29000,9 @@ msgstr ""
msgid "ProjectSettings|What are badges?"
msgstr ""
+msgid "ProjectSettings|What are merge trains?"
+msgstr ""
+
msgid "ProjectSettings|When merge request pipelines are enabled in the CI/CD configuration file, pipelines validate the combined results of the source and target branches. %{link_start}How to configure merge request pipelines?%{link_end}"
msgstr ""
@@ -28501,6 +29120,9 @@ msgstr ""
msgid "Projects are organized into groups"
msgstr ""
+msgid "Projects are where you store your code, access issues, wiki and other features of GitLab."
+msgstr ""
+
msgid "Projects contributed to"
msgstr ""
@@ -28516,12 +29138,6 @@ msgstr ""
msgid "Projects to index"
msgstr ""
-msgid "Projects will be permanently deleted after a %{waiting_period}-day waiting period."
-msgstr ""
-
-msgid "Projects will be permanently deleted immediately."
-msgstr ""
-
msgid "Projects with critical vulnerabilities"
msgstr ""
@@ -28606,6 +29222,9 @@ msgstr ""
msgid "ProjectsNew|Import project"
msgstr ""
+msgid "ProjectsNew|Include a Getting Started README"
+msgstr ""
+
msgid "ProjectsNew|Initialize repository with a README"
msgstr ""
@@ -28621,6 +29240,9 @@ msgstr ""
msgid "ProjectsNew|Project description %{tag_start}(optional)%{tag_end}"
msgstr ""
+msgid "ProjectsNew|Recommended if you're new to GitLab"
+msgstr ""
+
msgid "ProjectsNew|Run CI/CD for external repository"
msgstr ""
@@ -29038,6 +29660,9 @@ msgstr ""
msgid "ProtectedBranch|Unprotect"
msgstr ""
+msgid "ProtectedBranch|Unprotect branch"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
@@ -29065,6 +29690,9 @@ msgstr ""
msgid "ProtectedEnvironment|Protected Environment (%{protected_environments_count})"
msgstr ""
+msgid "ProtectedEnvironment|Required approvals"
+msgstr ""
+
msgid "ProtectedEnvironment|Select an environment"
msgstr ""
@@ -29086,10 +29714,13 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|Unprotect tag"
+msgstr ""
+
msgid "ProtectedTags|default"
msgstr ""
-msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
+msgid "ProtectedTag|By default, protected tags restrict who can modify the tag."
msgstr ""
msgid "ProtectedTag|Learn more."
@@ -29152,6 +29783,9 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Public projects are an easy way to allow everyone to have read-only access."
+msgstr ""
+
msgid "Publish to status page"
msgstr ""
@@ -29308,9 +29942,6 @@ msgstr ""
msgid "QualitySummary|Project quality"
msgstr ""
-msgid "Quarters"
-msgstr ""
-
msgid "Query"
msgstr ""
@@ -29395,6 +30026,9 @@ msgstr ""
msgid "Read more about project permissions %{help_link_open}here%{help_link_close}"
msgstr ""
+msgid "Read more about related epics"
+msgstr ""
+
msgid "Read more about related issues"
msgstr ""
@@ -29425,10 +30059,7 @@ msgstr ""
msgid "Rebase source branch on the target branch."
msgstr ""
-msgid "Rebase without CI"
-msgstr ""
-
-msgid "Rebases and triggers a pipeline"
+msgid "Rebase without pipeline"
msgstr ""
msgid "Recaptcha verified?"
@@ -29479,9 +30110,6 @@ msgstr ""
msgid "Reconfigure"
msgstr ""
-msgid "Recovering projects"
-msgstr ""
-
msgid "Recovery Codes"
msgstr ""
@@ -29541,6 +30169,12 @@ msgstr ""
msgid "Regex pattern"
msgstr ""
+msgid "Region"
+msgstr ""
+
+msgid "Regions"
+msgstr ""
+
msgid "Register"
msgstr ""
@@ -29771,9 +30405,6 @@ msgstr ""
msgid "Remove all or specific reviewer(s)"
msgstr ""
-msgid "Remove approver"
-msgstr ""
-
msgid "Remove approvers"
msgstr ""
@@ -29789,6 +30420,9 @@ msgstr ""
msgid "Remove attention request"
msgstr ""
+msgid "Remove attention request(s)"
+msgstr ""
+
msgid "Remove avatar"
msgstr ""
@@ -29927,6 +30561,9 @@ msgstr ""
msgid "Removed an issue from an epic."
msgstr ""
+msgid "Removed attention from %{users_sentence}."
+msgstr ""
+
msgid "Removed attention request from @%{username}"
msgstr ""
@@ -29978,6 +30615,9 @@ msgstr ""
msgid "Removes an issue from an epic."
msgstr ""
+msgid "Removes attention from %{users_sentence}."
+msgstr ""
+
msgid "Removes parent epic %{epic_ref}."
msgstr ""
@@ -30089,6 +30729,9 @@ msgstr ""
msgid "Report abuse to admin"
msgstr ""
+msgid "Report is generating and will be sent to your email address."
+msgstr ""
+
msgid "Reported %{timeAgo} by %{reportedBy}"
msgstr ""
@@ -30378,6 +31021,15 @@ msgstr ""
msgid "Request attention"
msgstr ""
+msgid "Request attention from %{users_sentence}."
+msgstr ""
+
+msgid "Request attention from assignee or reviewer"
+msgstr ""
+
+msgid "Request attention from assignee(s) or reviewer(s)"
+msgstr ""
+
msgid "Request attention to review"
msgstr ""
@@ -30402,6 +31054,9 @@ msgstr ""
msgid "Requested %{time_ago}"
msgstr ""
+msgid "Requested attention from %{users_sentence}."
+msgstr ""
+
msgid "Requested attention from @%{username}"
msgstr ""
@@ -30616,6 +31271,9 @@ msgstr ""
msgid "Restore project"
msgstr ""
+msgid "Restoring projects"
+msgstr ""
+
msgid "Restoring the group will prevent the group, its subgroups and projects from being removed on this date."
msgstr ""
@@ -30646,6 +31304,9 @@ msgstr ""
msgid "Retry"
msgstr ""
+msgid "Retry failed jobs"
+msgstr ""
+
msgid "Retry job"
msgstr ""
@@ -30693,9 +31354,6 @@ msgstr ""
msgid "Review changes"
msgstr ""
-msgid "Review requested from %{name}"
-msgstr ""
-
msgid "Review requests for you"
msgstr ""
@@ -30860,6 +31518,9 @@ msgstr ""
msgid "Runners|Assigned Group"
msgstr ""
+msgid "Runners|Assigned Projects (%{projectCount})"
+msgstr ""
+
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30929,6 +31590,9 @@ msgstr ""
msgid "Runners|Instance"
msgstr ""
+msgid "Runners|Jobs"
+msgstr ""
+
msgid "Runners|Last contact"
msgstr ""
@@ -31022,9 +31686,6 @@ msgstr ""
msgid "Runners|Runner %{name} was deleted"
msgstr ""
-msgid "Runners|Runner ID"
-msgstr ""
-
msgid "Runners|Runner assigned to project."
msgstr ""
@@ -31172,6 +31833,9 @@ msgstr ""
msgid "Runners|stale"
msgstr ""
+msgid "Runner|This runner has not run any jobs."
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -31286,6 +31950,24 @@ msgstr ""
msgid "Saving project."
msgstr ""
+msgid "ScanResultPolicy|%{ifLabelStart}if%{ifLabelEnd} %{scanners} scan in an open merge request targeting the %{branches} branch(es) finds %{vulnerabilitiesAllowed} or more %{severities} vulnerabilities that are %{vulnerabilityStates}"
+msgstr ""
+
+msgid "ScanResultPolicy|%{thenLabelStart}Then%{thenLabelEnd} Require approval from %{approvalsRequired} of the following approvers: %{approvers}"
+msgstr ""
+
+msgid "ScanResultPolicy|add an approver"
+msgstr ""
+
+msgid "ScanResultPolicy|scanners"
+msgstr ""
+
+msgid "ScanResultPolicy|severity levels"
+msgstr ""
+
+msgid "ScanResultPolicy|vulnerability states"
+msgstr ""
+
msgid "Scanner"
msgstr ""
@@ -31418,6 +32100,9 @@ msgstr ""
msgid "Search for a user"
msgstr ""
+msgid "Search for an emoji"
+msgstr ""
+
msgid "Search for projects, issues, etc."
msgstr ""
@@ -31605,18 +32290,12 @@ msgstr ""
msgid "Secret Detection"
msgstr ""
-msgid "Secret access key"
-msgstr ""
-
msgid "Secret token"
msgstr ""
msgid "Secure token that identifies an external storage request."
msgstr ""
-msgid "SecureCodeWarrior"
-msgstr ""
-
msgid "Security"
msgstr ""
@@ -31641,9 +32320,6 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "Security training with guide and learning pathways."
-msgstr ""
-
msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
@@ -31746,7 +32422,7 @@ msgstr ""
msgid "SecurityConfiguration|Manage corpus"
msgstr ""
-msgid "SecurityConfiguration|Manage corpus files used as mutation sources in coverage fuzzing."
+msgid "SecurityConfiguration|Manage corpus files used as seed inputs with coverage-guided fuzzing."
msgstr ""
msgid "SecurityConfiguration|Manage profiles for use by DAST scans."
@@ -31812,15 +32488,15 @@ msgstr ""
msgid "SecurityOrchestration|.yaml preview"
msgstr ""
-msgid "SecurityOrchestration|Action"
-msgstr ""
-
msgid "SecurityOrchestration|Actions"
msgstr ""
msgid "SecurityOrchestration|Add rule"
msgstr ""
+msgid "SecurityOrchestration|After dismissing the alert, the information will never be shown again."
+msgstr ""
+
msgid "SecurityOrchestration|All policies"
msgstr ""
@@ -31836,7 +32512,7 @@ msgstr ""
msgid "SecurityOrchestration|Description"
msgstr ""
-msgid "SecurityOrchestration|Disabled"
+msgid "SecurityOrchestration|Don't show the alert anymore"
msgstr ""
msgid "SecurityOrchestration|Edit policy"
@@ -31845,13 +32521,13 @@ msgstr ""
msgid "SecurityOrchestration|Edit policy project"
msgstr ""
-msgid "SecurityOrchestration|Enabled"
+msgid "SecurityOrchestration|Empty policy name"
msgstr ""
-msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Enabled"
msgstr ""
-msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
msgstr ""
msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
@@ -31860,7 +32536,7 @@ msgstr ""
msgid "SecurityOrchestration|Invalid policy type"
msgstr ""
-msgid "SecurityOrchestration|Latest scan"
+msgid "SecurityOrchestration|Latest scan run against %{agent}"
msgstr ""
msgid "SecurityOrchestration|Network"
@@ -31869,15 +32545,27 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No actions defined - policy will not run."
+msgstr ""
+
+msgid "SecurityOrchestration|No description"
+msgstr ""
+
msgid "SecurityOrchestration|No rules defined - policy will not run."
msgstr ""
+msgid "SecurityOrchestration|Not enabled"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
msgid "SecurityOrchestration|Policies"
msgstr ""
+msgid "SecurityOrchestration|Policy Type"
+msgstr ""
+
msgid "SecurityOrchestration|Policy cannot be enabled for non-existing branches (%{branches})"
msgstr ""
@@ -31902,10 +32590,13 @@ msgstr ""
msgid "SecurityOrchestration|Require %{approvals} %{plural} from %{approvers} if any of the following occur:"
msgstr ""
-msgid "SecurityOrchestration|Rule"
+msgid "SecurityOrchestration|Rules"
msgstr ""
-msgid "SecurityOrchestration|Rules"
+msgid "SecurityOrchestration|Runs %{actions} and %{lastAction} scans"
+msgstr ""
+
+msgid "SecurityOrchestration|Runs a %{action} scan"
msgstr ""
msgid "SecurityOrchestration|Scan Execution"
@@ -31965,6 +32656,9 @@ msgstr ""
msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
+msgid "SecurityOrchestration|This view only shows scan results for the agent %{agent}. You can view scan results for all agents in the %{linkStart}Operational Vulnerabilities tab of the vulnerability report%{linkEnd}."
+msgstr ""
+
msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
@@ -32019,9 +32713,6 @@ msgstr ""
msgid "SecurityOrchestration|users with ids"
msgstr ""
-msgid "SecurityOrchestration|view results"
-msgstr ""
-
msgid "SecurityOrchestration|vulnerabilities"
msgstr ""
@@ -32691,22 +33382,19 @@ 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|In order to start using functions as a service, you must first install Knative on your Kubernetes cluster. %{linkStart}More information%{linkEnd}"
-msgstr ""
-
msgid "Serverless|Learn more about Serverless"
msgstr ""
msgid "Serverless|No functions available"
msgstr ""
-msgid "Serverless|Sign up for First Look"
+msgid "Serverless|Serverless was %{linkStart}deprecated%{linkEnd} in GitLab 14.3."
+msgstr ""
+
+msgid "Serverless|Serverless was %{postLinkStart}deprecated%{postLinkEnd}. But if you opt to use it, you must install Knative in your Kubernetes cluster first. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "Serverless|The deploy job has not finished."
@@ -32718,9 +33406,6 @@ 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 ""
@@ -32736,9 +33421,6 @@ msgstr ""
msgid "Service Account Key"
msgstr ""
-msgid "Service Accounts"
-msgstr ""
-
msgid "Service Accounts keys authorize GitLab to deploy your Google Cloud project"
msgstr ""
@@ -32748,10 +33430,10 @@ msgstr ""
msgid "Service Desk allows people to create issues in your GitLab instance without their own user account. It provides a unique email address for end users to create issues in a project. Replies can be sent either through the GitLab interface or by email. End users only see threads through email."
msgstr ""
-msgid "Service Usage Data"
+msgid "Service account generated successfully"
msgstr ""
-msgid "Service account generated successfully"
+msgid "Service accounts"
msgstr ""
msgid "Service ping is disabled in your configuration file, and cannot be enabled through this form."
@@ -32895,6 +33577,9 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
+msgid "Set the per-user rate limit for getting a user by ID via the API."
+msgstr ""
+
msgid "Set the per-user rate limit for notes created by web or API requests."
msgstr ""
@@ -33074,6 +33759,9 @@ msgstr ""
msgid "Shared runners details"
msgstr ""
+msgid "Shared runners enabled cannot be enabled until a valid credit card is on file"
+msgstr ""
+
msgid "Shared runners help link"
msgstr ""
@@ -33131,6 +33819,9 @@ msgstr ""
msgid "Show all issues."
msgstr ""
+msgid "Show all milestones"
+msgstr ""
+
msgid "Show all test cases."
msgstr ""
@@ -33167,6 +33858,9 @@ msgstr ""
msgid "Show file contents"
msgstr ""
+msgid "Show group milestones"
+msgstr ""
+
msgid "Show labels"
msgstr ""
@@ -33182,6 +33876,12 @@ msgstr ""
msgid "Show open epics"
msgstr ""
+msgid "Show project milestones"
+msgstr ""
+
+msgid "Show sub-group milestones"
+msgstr ""
+
msgid "Show the Closed list"
msgstr ""
@@ -33191,11 +33891,6 @@ msgstr ""
msgid "Show whitespace changes"
msgstr ""
-msgid "Showing %d event"
-msgid_plural "Showing %d events"
-msgstr[0] "Visualizza %d evento"
-msgstr[1] "Visualizza %d eventi"
-
msgid "Showing %{conflict} between %{sourceBranch} and %{targetBranch}"
msgstr ""
@@ -33255,12 +33950,6 @@ msgstr ""
msgid "Sidebar|None"
msgstr ""
-msgid "Sidebar|Only numeral characters allowed"
-msgstr ""
-
-msgid "Sidebar|Weight"
-msgstr ""
-
msgid "Sidekiq job compression threshold (bytes)"
msgstr ""
@@ -33423,6 +34112,9 @@ msgstr ""
msgid "Slack logo"
msgstr ""
+msgid "SlackIntegration|Are you sure you want to remove this project from the Slack application?"
+msgstr ""
+
msgid "SlackIntegration|GitLab for Slack"
msgstr ""
@@ -33432,6 +34124,9 @@ msgstr ""
msgid "SlackIntegration|Project alias"
msgstr ""
+msgid "SlackIntegration|Remove project"
+msgstr ""
+
msgid "SlackIntegration|Select a GitLab project to link with your Slack workspace."
msgstr ""
@@ -33576,9 +34271,6 @@ msgstr ""
msgid "Something went wrong trying to load issue contacts."
msgstr ""
-msgid "Something went wrong when creating a work item. Please try again"
-msgstr ""
-
msgid "Something went wrong when reordering designs. Please try again"
msgstr ""
@@ -33672,9 +34364,6 @@ msgstr ""
msgid "Something went wrong while inserting your image. Please try again."
msgstr ""
-msgid "Something went wrong while merging this merge request. Please try again."
-msgstr ""
-
msgid "Something went wrong while obtaining the Let's Encrypt certificate."
msgstr ""
@@ -33996,10 +34685,10 @@ 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."
+msgid "SourcegraphAdmin|Learn more."
msgstr ""
-msgid "SourcegraphAdmin|More information"
+msgid "SourcegraphAdmin|Only public projects have code intelligence enabled and communicate with Sourcegraph."
msgstr ""
msgid "SourcegraphAdmin|Save changes"
@@ -34008,7 +34697,7 @@ msgstr ""
msgid "SourcegraphAdmin|Sourcegraph URL"
msgstr ""
-msgid "SourcegraphAdmin|e.g. https://sourcegraph.example.com"
+msgid "SourcegraphAdmin|https://sourcegraph.example.com"
msgstr ""
msgid "SourcegraphPreferences|This feature is experimental and currently limited to certain projects."
@@ -34143,6 +34832,9 @@ msgstr ""
msgid "Start date"
msgstr ""
+msgid "Start free trial"
+msgstr ""
+
msgid "Start merge train"
msgstr ""
@@ -34173,6 +34865,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started escalation for this incident."
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -34185,6 +34880,9 @@ msgstr ""
msgid "Starts at (UTC)"
msgstr ""
+msgid "Starts escalations for this incident"
+msgstr ""
+
msgid "Starts on"
msgstr ""
@@ -34446,6 +35144,9 @@ msgstr ""
msgid "Strikethrough"
msgstr ""
+msgid "Strikethrough text"
+msgstr ""
+
msgid "Subgroup information"
msgstr ""
@@ -34680,6 +35381,21 @@ msgstr ""
msgid "Subscriptions"
msgstr ""
+msgid "Subscriptions|Chat with sales"
+msgstr ""
+
+msgid "Subscriptions|Close"
+msgstr ""
+
+msgid "Subscriptions|Not ready to buy yet?"
+msgstr ""
+
+msgid "Subscriptions|Start a free trial"
+msgstr ""
+
+msgid "Subscriptions|We understand. Maybe you have some questions for our sales team, or maybe you'd like to try some of the paid features first. What would you like to do?"
+msgstr ""
+
msgid "Subscription|Your subscription for %{strong}%{namespace_name}%{strong_close} has expired and you are now on %{pricing_link_start}the GitLab Free tier%{pricing_link_end}. Don't worry, your data is safe. Get in touch with our support team (%{support_email}). They'll gladly help with your subscription renewal."
msgstr ""
@@ -34890,6 +35606,9 @@ msgstr ""
msgid "SuperSonics|Maximum users"
msgstr ""
+msgid "SuperSonics|Offline cloud"
+msgstr ""
+
msgid "SuperSonics|Paste your activation code"
msgstr ""
@@ -34956,6 +35675,12 @@ msgstr ""
msgid "SuperSonics|You do not have an active subscription"
msgstr ""
+msgid "SuperSonics|You have a future dated license"
+msgstr ""
+
+msgid "SuperSonics|You have added a license that activates on %{date}. Please see the subscription history table below for more details."
+msgstr ""
+
msgid "SuperSonics|You have successfully added a license that activates on %{date}. Please see the subscription history table below for more details."
msgstr ""
@@ -35115,6 +35840,9 @@ msgstr ""
msgid "Tag name is required"
msgstr ""
+msgid "Tag push"
+msgstr ""
+
msgid "Tag push events"
msgstr ""
@@ -35217,6 +35945,9 @@ msgstr ""
msgid "TagsPage|protected"
msgstr ""
+msgid "Take a look at the documentation to discover all of GitLab’s capabilities."
+msgstr ""
+
msgid "Target Branch"
msgstr "Branch di destinazione"
@@ -35619,6 +36350,9 @@ msgstr ""
msgid "Tests"
msgstr ""
+msgid "Text (optional)"
+msgstr ""
+
msgid "Text added to the body of all email messages. %{character_limit} character limit"
msgstr ""
@@ -35669,6 +36403,9 @@ msgstr ""
msgid "The CSV export will be created in the background. Once finished, it will be sent to %{email} in an attachment."
msgstr ""
+msgid "The CSV export you requested of all user memberships is attached to this email."
+msgstr ""
+
msgid "The GitLab subscription service (customers.gitlab.com) is currently experiencing an outage. You can monitor the status and get updates at %{linkStart}status.gitlab.com%{linkEnd}."
msgstr ""
@@ -35744,6 +36481,9 @@ 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 epic"
+msgstr ""
+
msgid "The current issue"
msgstr ""
@@ -35905,6 +36645,9 @@ msgstr ""
msgid "The latest pipeline for this merge request has failed."
msgstr ""
+msgid "The license key is invalid."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -35920,6 +36663,9 @@ msgstr ""
msgid "The license was successfully uploaded and will be active from %{starts_at}. You can see the details below."
msgstr ""
+msgid "The license you uploaded is invalid. If the issue persists, contact support at %{link}."
+msgstr ""
+
msgid "The list creation wizard is already open"
msgstr ""
@@ -36541,10 +37287,13 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} and everything this project contains. %{strongOpen}There is no going back%{strongClose}"
+msgstr ""
+
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains."
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}on %{date}%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains. %{strongOpen}There is no going back.%{strongClose}"
msgstr ""
msgid "This action will %{strongOpen}permanently remove%{strongClose} %{codeOpen}%{group}%{codeClose} %{strongOpen}immediately%{strongClose}."
@@ -36673,9 +37422,6 @@ msgstr ""
msgid "This file was modified for readability, and can't accept suggestions. Edit it directly."
msgstr ""
-msgid "This forked project has the following:"
-msgstr ""
-
msgid "This form is disabled in preview"
msgstr ""
@@ -36688,7 +37434,7 @@ msgstr ""
msgid "This group can't be removed because it is linked to a subscription. To remove this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
-msgid "This group can't be transfered because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
+msgid "This group can't be transferred because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
msgid "This group cannot be invited to a project inside a group with enforced SSO"
@@ -36715,6 +37461,9 @@ 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 incident is already escalated with '%{escalation_policy_name}'."
+msgstr ""
+
msgid "This invitation was sent to %{mail_to_invite_email}, but you are signed in as %{link_to_current_user} with email %{mail_to_current_user}."
msgstr ""
@@ -36733,9 +37482,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 merge train pipeline"
-msgstr ""
-
msgid "This is a private email address %{helpIcon} generated just for you. Anyone who has it can create issues or merge requests as if they were you. If that happens, %{resetLinkStart}reset this token%{resetLinkEnd}."
msgstr ""
@@ -36757,6 +37503,12 @@ msgstr ""
msgid "This is your current session"
msgstr ""
+msgid "This issue cannot be assigned to a confidential epic because it is public."
+msgstr ""
+
+msgid "This issue cannot be made public because it belongs to a confidential epic."
+msgstr ""
+
msgid "This issue is confidential and should only be visible to team members with at least Reporter access."
msgstr ""
@@ -36874,6 +37626,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 branch is protected from force push."
+msgstr ""
+
msgid "This merge request cannot be rebased while there are conflicts."
msgstr ""
@@ -36925,9 +37680,15 @@ msgstr ""
msgid "This pipeline was triggered by a schedule."
msgstr ""
+msgid "This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project"
msgstr ""
+msgid "This project can be restored until %{date}."
+msgstr ""
+
msgid "This project cannot be %{visibilityLevel} because the visibility of %{openShowLink}%{name}%{closeShowLink} is %{visibility}. To make this project %{visibilityLevel}, you must first %{openEditLink}change the visibility%{closeEditLink} of the parent group."
msgstr ""
@@ -36946,6 +37707,9 @@ msgstr ""
msgid "This project is %{strongStart}NOT%{strongEnd} a fork, and has the following:"
msgstr ""
+msgid "This project is %{strongStart}NOT%{strongEnd} a fork. This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -37637,6 +38401,9 @@ msgstr ""
msgid "Today"
msgstr ""
+msgid "Todos count"
+msgstr ""
+
msgid "Todos|Are you looking for things to do? Take a look at %{strongStart}%{openIssuesLinkStart}open issues%{openIssuesLinkEnd}%{strongEnd}, contribute to %{strongStart}%{mergeRequestLinkStart}a merge request%{mergeRequestLinkEnd}%{mergeRequestLinkEnd}%{strongEnd}, or mention someone in a comment to automatically assign them a new to-do item."
msgstr ""
@@ -37910,10 +38677,8 @@ msgstr ""
msgid "Trending"
msgstr ""
-msgid "Trials|%{planName} Trial %{enDash} %{num} day left"
-msgid_plural "Trials|%{planName} Trial %{enDash} %{num} days left"
-msgstr[0] ""
-msgstr[1] ""
+msgid "Trials|%{planName} Trial"
+msgstr ""
msgid "Trials|Compare all plans"
msgstr ""
@@ -37921,6 +38686,9 @@ msgstr ""
msgid "Trials|Create a new group to start your GitLab Ultimate trial."
msgstr ""
+msgid "Trials|Day %{daysUsed}/%{duration}"
+msgstr ""
+
msgid "Trials|Go back to GitLab"
msgstr ""
@@ -38170,7 +38938,7 @@ msgstr ""
msgid "URL is triggered when repository is updated"
msgstr ""
-msgid "URL must be percent-encoded if neccessary."
+msgid "URL must be percent-encoded if necessary."
msgstr ""
msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
@@ -38389,6 +39157,9 @@ msgstr ""
msgid "Unlock account"
msgstr ""
+msgid "Unlock more features with GitLab Ultimate"
+msgstr ""
+
msgid "Unlock the discussion"
msgstr ""
@@ -38452,6 +39223,9 @@ msgstr ""
msgid "Unsubscribes from this %{quick_action_target}."
msgstr ""
+msgid "Unsupported sort value."
+msgstr ""
+
msgid "Unsupported todo type passed. Supported todo types are: %{todo_types}"
msgstr ""
@@ -38680,6 +39454,9 @@ msgstr ""
msgid "UsageQuota|File attachments and smaller design graphics."
msgstr ""
+msgid "UsageQuota|From %{storage_enforcement_date} storage limits will apply to this namespace. View and manage your usage in %{strong_start}Group Settings &gt; Usage quotas%{strong_end}."
+msgstr ""
+
msgid "UsageQuota|Git repository."
msgstr ""
@@ -38740,6 +39517,9 @@ msgstr ""
msgid "UsageQuota|Storage type"
msgstr ""
+msgid "UsageQuota|Storage used"
+msgstr ""
+
msgid "UsageQuota|This is the total amount of storage used across your projects within this namespace."
msgstr ""
@@ -38935,6 +39715,12 @@ msgstr ""
msgid "Use hashed storage paths for newly created and renamed repositories. Always enabled since 13.0."
msgstr ""
+msgid "Use issue count"
+msgstr ""
+
+msgid "Use issue weight"
+msgstr ""
+
msgid "Use one line per URI"
msgstr ""
@@ -39316,6 +40102,9 @@ msgstr ""
msgid "Users"
msgstr ""
+msgid "Users API rate limit"
+msgstr ""
+
msgid "Users can launch a development environment from a GitLab browser tab when the %{linkStart}Gitpod%{linkEnd} integration is enabled."
msgstr ""
@@ -39641,6 +40430,9 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View group pipeline usage quota"
+msgstr ""
+
msgid "View incident details at"
msgstr ""
@@ -39793,6 +40585,9 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
+msgid "Vulnerability"
+msgstr ""
+
msgid "Vulnerability Report"
msgstr ""
@@ -39844,6 +40639,9 @@ msgstr ""
msgid "VulnerabilityManagement|An unverified non-confirmed finding"
msgstr ""
+msgid "VulnerabilityManagement|At least one identifier is required"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -39853,12 +40651,24 @@ msgstr ""
msgid "VulnerabilityManagement|Create Jira issue"
msgstr ""
+msgid "VulnerabilityManagement|Enter a name"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE code"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE identifier URL"
+msgstr ""
+
msgid "VulnerabilityManagement|Fetching linked Jira issues"
msgstr ""
msgid "VulnerabilityManagement|Manually add a vulnerability entry into the vulnerability report."
msgstr ""
+msgid "VulnerabilityManagement|Name is a required field"
+msgstr ""
+
msgid "VulnerabilityManagement|Needs triage"
msgstr ""
@@ -39874,6 +40684,18 @@ msgstr ""
msgid "VulnerabilityManagement|Select a method"
msgstr ""
+msgid "VulnerabilityManagement|Select a severity level"
+msgstr ""
+
+msgid "VulnerabilityManagement|Select a status"
+msgstr ""
+
+msgid "VulnerabilityManagement|Severity is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Something went wrong while creating vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -39898,6 +40720,12 @@ msgstr ""
msgid "VulnerabilityManagement|Something went wrong, could not update vulnerability state."
msgstr ""
+msgid "VulnerabilityManagement|Status is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Submit vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Summary, detailed description, steps to reproduce, etc."
msgstr ""
@@ -40093,6 +40921,9 @@ msgstr ""
msgid "WARNING:"
msgstr ""
+msgid "WARNING: This snippet contains hidden files which might be used to mask malicious behavior. Exercise caution if cloning and executing code from this snippet."
+msgstr ""
+
msgid "Wait for the file to load to copy its contents"
msgstr ""
@@ -40312,6 +41143,15 @@ msgstr ""
msgid "Webhooks|An issue is created, updated, closed, or reopened."
msgstr ""
+msgid "Webhooks|Are you sure you want to delete this group hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this project hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this webhook?"
+msgstr ""
+
msgid "Webhooks|Comments"
msgstr ""
@@ -40321,6 +41161,9 @@ msgstr ""
msgid "Webhooks|Confidential issues events"
msgstr ""
+msgid "Webhooks|Delete webhook"
+msgstr ""
+
msgid "Webhooks|Deployment events"
msgstr ""
@@ -40554,6 +41397,9 @@ msgstr ""
msgid "Wiki"
msgstr ""
+msgid "Wiki page"
+msgstr ""
+
msgid "Wiki page was successfully created."
msgstr ""
@@ -40659,7 +41505,7 @@ msgstr ""
msgid "WikiPageConflictMessage|Someone edited the page the same time you did. Please check out %{wikiLinkStart}the page%{wikiLinkEnd} and make sure your changes will not unintentionally remove theirs."
msgstr ""
-msgid "WikiPage|An error occured while trying to render the content editor. Please try again later."
+msgid "WikiPage|An error occurred while trying to render the content editor. Please try again later."
msgstr ""
msgid "WikiPage|Are you sure you want to switch back to the classic editor?"
@@ -40818,6 +41664,18 @@ msgstr ""
msgid "WorkItem|New Task"
msgstr ""
+msgid "WorkItem|Something went wrong when creating a work item. Please try again"
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching the work item. Please try again."
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching work item types. Please try again"
+msgstr ""
+
+msgid "WorkItem|Type"
+msgstr ""
+
msgid "WorkItem|Work Items"
msgstr ""
@@ -40884,7 +41742,10 @@ msgstr ""
msgid "You are about to add %{usersTag} people to the discussion. They will all receive a notification."
msgstr ""
-msgid "You are about to permanently delete this project"
+msgid "You are about to delete this forked project containing:"
+msgstr ""
+
+msgid "You are about to delete this project containing:"
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."
@@ -40905,6 +41766,9 @@ msgstr ""
msgid "You are attempting to update a file that has changed since you started editing it."
msgstr ""
+msgid "You are billed if you exceed this number. %{qsrOverageLinkStart}How does billing work?%{qsrOverageLinkEnd}"
+msgstr ""
+
msgid "You are connected to the Prometheus server, but there is currently no data to display."
msgstr ""
@@ -40962,6 +41826,9 @@ msgstr ""
msgid "You are not authorized to update this scanner profile"
msgstr ""
+msgid "You are not authorized to upload metric images"
+msgstr ""
+
msgid "You are now impersonating %{username}"
msgstr ""
@@ -41115,9 +41982,6 @@ msgstr ""
msgid "You can only upload one design when dropping onto an existing design."
msgstr ""
-msgid "You can recover this project until %{date}"
-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 ""
@@ -41166,9 +42030,6 @@ msgstr "Non puoi scrivere su un'istanza di GitLab Geo secondaria di sola lettura
msgid "You cannot write to this read-only GitLab instance."
msgstr ""
-msgid "You can’t %{tag_start}edit%{tag_end} files directly in this project. Fork this project and submit a merge request with your changes."
-msgstr ""
-
msgid "You can’t edit files directly in this project. Fork this project and submit a merge request with your changes."
msgstr ""
@@ -41321,9 +42182,6 @@ msgstr ""
msgid "You have not added any approvers. Start by adding users or groups."
msgstr ""
-msgid "You have reached your project limit"
-msgstr "Hai raggiunto il tuo limite di progetto"
-
msgid "You have set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
@@ -41354,12 +42212,6 @@ msgstr ""
msgid "You must have maintainer access to force delete a lock"
msgstr ""
-msgid "You must have permission to create a project in a group before forking."
-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 ""
@@ -41765,7 +42617,7 @@ msgstr ""
msgid "Your public email will be displayed on your public profile."
msgstr ""
-msgid "Your request for access could not be processed: %{error_meesage}"
+msgid "Your request for access could not be processed: %{error_message}"
msgstr ""
msgid "Your request for access has been queued for review."
@@ -41948,6 +42800,9 @@ msgstr ""
msgid "archived:"
msgstr ""
+msgid "artifacts"
+msgstr ""
+
msgid "assign yourself"
msgstr ""
@@ -41977,6 +42832,9 @@ msgstr[1] ""
msgid "branch name"
msgstr ""
+msgid "builds"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -42400,6 +43258,9 @@ msgstr ""
msgid "contact with same email already exists in group hierarchy"
msgstr ""
+msgid "container registry images"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -42439,6 +43300,9 @@ msgstr ""
msgid "data"
msgstr ""
+msgid "database"
+msgstr ""
+
msgid "date must not be after 9999-12-31"
msgstr ""
@@ -42462,9 +43326,6 @@ msgstr ""
msgid "design"
msgstr ""
-msgid "detached"
-msgstr ""
-
msgid "disabled"
msgstr ""
@@ -42713,7 +43574,7 @@ msgstr ""
msgid "is not a valid X509 certificate."
msgstr ""
-msgid "is not allowed for sign-up."
+msgid "is not allowed for sign-up. Please use your regular email address."
msgstr ""
msgid "is not allowed for this group."
@@ -42725,7 +43586,7 @@ msgstr ""
msgid "is not allowed since the group is not top-level group."
msgstr ""
-msgid "is not allowed."
+msgid "is not allowed. Please use your regular email address."
msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
@@ -42812,6 +43673,9 @@ msgstr ""
msgid "level: %{level}"
msgstr ""
+msgid "lfs objects"
+msgstr ""
+
msgid "limit of %{project_limit} reached"
msgstr ""
@@ -43031,6 +43895,9 @@ msgstr ""
msgid "mrWidget|Merge blocked: pipeline must succeed. It's waiting for a manual action to continue."
msgstr ""
+msgid "mrWidget|Merge blocked: pipeline must succeed. Push a commit that fixes the failure, or %{linkStart}learn about other solutions.%{linkEnd}"
+msgstr ""
+
msgid "mrWidget|Merge blocked: this merge request must be approved."
msgstr ""
@@ -43148,9 +44015,6 @@ msgstr ""
msgid "mrWidget|The changes were not merged into"
msgstr ""
-msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -43298,9 +44162,6 @@ msgstr ""
msgid "open issue"
msgstr ""
-msgid "opened %{timeAgo}"
-msgstr ""
-
msgid "or"
msgstr ""
@@ -43312,6 +44173,12 @@ msgid_plural "out of %d total tests"
msgstr[0] ""
msgstr[1] ""
+msgid "packages"
+msgstr ""
+
+msgid "pages"
+msgstr ""
+
msgid "parent"
msgid_plural "parents"
msgstr[0] ""
@@ -43461,6 +44328,9 @@ msgid_plural "replies"
msgstr[0] ""
msgstr[1] ""
+msgid "repositories"
+msgstr ""
+
msgid "repository:"
msgstr ""
@@ -43581,12 +44451,18 @@ msgstr ""
msgid "tag name"
msgstr ""
+msgid "terraform states"
+msgstr ""
+
msgid "the correct format."
msgstr ""
msgid "the file"
msgstr ""
+msgid "the following epic(s)"
+msgstr ""
+
msgid "the following issue(s)"
msgstr ""
@@ -43599,21 +44475,12 @@ msgstr ""
msgid "this document"
msgstr ""
-msgid "this issue cannot be assigned to a confidential epic since it is public"
-msgstr ""
-
-msgid "this issue cannot be made public since it belongs to a confidential epic"
-msgstr ""
-
msgid "time summary"
msgstr ""
msgid "toggle collapse"
msgstr ""
-msgid "train"
-msgstr ""
-
msgid "triggered"
msgstr ""
@@ -43742,3 +44609,6 @@ msgstr ""
msgid "{project}"
msgstr ""
+msgid "✔"
+msgstr ""
+
diff --git a/locale/ja/gitlab.po b/locale/ja/gitlab.po
index ab14b7fb064..92cb6be15d8 100644
--- a/locale/ja/gitlab.po
+++ b/locale/ja/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: ja\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2022-02-02 15:45\n"
+"PO-Revision-Date: 2022-03-01 20:39\n"
msgid " %{start} to %{end}"
msgstr " %{start} ã‹ã‚‰ %{end} ã¾ã§"
@@ -132,6 +132,10 @@ msgid "%d approver (you've approved)"
msgid_plural "%d approvers (you've approved)"
msgstr[0] "%d 人ã®æ‰¿èªè€… (ã‚ãªãŸã‚‚承èªæ¸ˆ)"
+msgid "%d assigned issue"
+msgid_plural "%d assigned issues"
+msgstr[0] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] "%d 個ã®å¤‰æ›´ã•ã‚ŒãŸãƒ•ã‚¡ã‚¤ãƒ«"
@@ -352,9 +356,21 @@ msgid "%d vulnerability dismissed"
msgid_plural "%d vulnerabilities dismissed"
msgstr[0] "%d 件ã®è„†å¼±æ€§ãŒç„¡è¦–ã•ã‚Œã¾ã—ãŸ"
-msgid "%d vulnerability updated"
-msgid_plural "%d vulnerabilities updated"
-msgstr[0] "%d 件ã®è„†å¼±æ€§ãŒæ›´æ–°ã•ã‚Œã¾ã—ãŸ"
+msgid "%d vulnerability set to confirmed"
+msgid_plural "%d vulnerabilities set to confirmed"
+msgstr[0] ""
+
+msgid "%d vulnerability set to dismissed"
+msgid_plural "%d vulnerabilities set to dismissed"
+msgstr[0] ""
+
+msgid "%d vulnerability set to needs triage"
+msgid_plural "%d vulnerabilities set to needs triage"
+msgstr[0] ""
+
+msgid "%d vulnerability set to resolved"
+msgid_plural "%d vulnerabilities set to resolved"
+msgstr[0] ""
msgid "%d warning found:"
msgid_plural "%d warnings found:"
@@ -434,6 +450,12 @@ msgstr[0] "%{count} 件中 %{completedCount} 件ã®ã‚¿ã‚¹ã‚¯ãŒå®Œäº†ã—ã¾ã—ã
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr "%{completedWeight}/%{totalWeight} ウェイトãŒå®Œäº†ã—ã¾ã—ãŸ"
+msgid "%{completed} of %{total} issues closed"
+msgstr ""
+
+msgid "%{completed} of %{total} weight completed"
+msgstr ""
+
msgid "%{cores} cores"
msgstr "%{cores} コア"
@@ -776,6 +798,9 @@ msgstr "%{openedEpics} オープン, %{closedEpics} 完了"
msgid "%{openedIssues} open, %{closedIssues} closed"
msgstr "%{openedIssues} オープン, %{closedIssues} 完了"
+msgid "%{percentage}%% issues closed"
+msgstr ""
+
msgid "%{percentage}%% weight completed"
msgstr "ウェイト㮠%{percentage}%% ãŒå®Œäº†ã—ã¾ã—ãŸ"
@@ -1190,6 +1215,9 @@ msgid "- User"
msgid_plural "- Users"
msgstr[0] "- ユーザー"
+msgid "- of - issues closed"
+msgstr ""
+
msgid "- of - weight completed"
msgstr "-/- ウェイト完了ã—ã¾ã—ãŸ"
@@ -1309,8 +1337,8 @@ msgstr "貢献 10-19 件"
msgid "1000+"
msgstr "1000 以上"
-msgid "192.168.0.0/24"
-msgstr "192.168.0.0/24"
+msgid "192.168.0.0/24 or 2001:0DB8:1234::/48"
+msgstr ""
msgid "1st contribution!"
msgstr "最åˆã®è²¢çŒ®!"
@@ -1621,14 +1649,14 @@ msgstr "folder/openapi.json"
msgid "AWS Access Key"
msgstr "AWS アクセスキー"
-msgid "AWS Access Key. Only required if not using role instance credentials"
-msgstr "AWSアクセスキー。ロールインスタンスã®è³‡æ ¼æƒ…報を使用ã—ãªã„å ´åˆã«ã®ã¿å¿…è¦"
-
msgid "AWS Secret Access Key"
msgstr "AWS 秘密アクセスキー"
-msgid "AWS Secret Access Key. Only required if not using role instance credentials"
-msgstr "AWSã®ã‚·ãƒ¼ã‚¯ãƒ¬ãƒƒãƒˆã‚¢ã‚¯ã‚»ã‚¹ã‚­ãƒ¼ã€‚ロールインスタンスã®è³‡æ ¼æƒ…報を使用ã—ãªã„å ´åˆã«ã®ã¿å¿…è¦"
+msgid "AWS access key ID (Optional)"
+msgstr ""
+
+msgid "AWS secret access key (Optional)"
+msgstr ""
msgid "AWS service error: %{error}"
msgstr "AWS サービスエラー: %{error}"
@@ -1687,9 +1715,6 @@ msgstr "アクセスã¯ç¦æ­¢ã•ã‚Œã¦ã„ã¾ã™ã€‚アクセスレベルを確èª
msgid "Access granted"
msgstr "アクセスãŒè¨±å¯ã•ã‚Œã¾ã—ãŸ"
-msgid "Access key ID"
-msgstr "アクセスキーID"
-
msgid "Access requests"
msgstr "アクセスリクエスト"
@@ -1864,8 +1889,8 @@ msgstr ""
msgid "Activity"
msgstr "アクティビティー"
-msgid "Activity|An error occured while retrieving activity. Reload the page to try again."
-msgstr "アクティビティã®å–得中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚ページをå†èª­ã¿è¾¼ã¿ã—ã¦å†è©¦è¡Œã—ã¦ãã ã•ã„。"
+msgid "Activity|An error occurred while retrieving activity. Reload the page to try again."
+msgstr ""
msgid "Add"
msgstr "追加"
@@ -1903,6 +1928,9 @@ msgstr "Zoom ミーティングを追加"
msgid "Add a %{type}"
msgstr "%{type} を追加"
+msgid "Add a GCP region"
+msgstr ""
+
msgid "Add a GPG key"
msgstr "GPGキーを追加"
@@ -1954,6 +1982,9 @@ msgstr "æ–°ã—ã„イシューを作æˆã™ã‚‹"
msgid "Add a numbered list"
msgstr "番å·ä»˜ãリストを追加"
+msgid "Add a related epic"
+msgstr ""
+
msgid "Add a related issue"
msgstr "関連ã™ã‚‹ã‚¤ã‚·ãƒ¥ãƒ¼ã‚’追加"
@@ -2068,6 +2099,9 @@ msgstr "以å‰ã«ãƒžãƒ¼ã‚¸ã—ãŸã‚³ãƒŸãƒƒãƒˆã‚’追加ã¾ãŸã¯å‰Šé™¤"
msgid "Add or subtract spent time"
msgstr "作業時間を追加ã¾ãŸã¯æ¸›ã‚‰ã™"
+msgid "Add people"
+msgstr ""
+
msgid "Add previously merged commits"
msgstr "以å‰ã«ãƒžãƒ¼ã‚¸ã—ãŸã‚³ãƒŸãƒƒãƒˆã‚’追加"
@@ -2134,6 +2168,9 @@ msgstr "発見ã—ãŸè„†å¼±æ€§ã‚’追加ã™ã‚‹"
msgid "Add webhook"
msgstr "Webhook ã®è¿½åŠ "
+msgid "Add your team members and others to GitLab."
+msgstr ""
+
msgid "Add/remove"
msgstr "追加ã¨å‰Šé™¤"
@@ -2956,12 +2993,6 @@ msgstr ""
msgid "AdvancedSearch|Reindex required"
msgstr ""
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. Permanently deleting this project will %{strongStart}immediately delete%{strongEnd} its repositories and %{strongStart}all related resources%{strongEnd}, including issues, merge requests etc."
-msgstr ""
-
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. You will lose this project's repository and %{strongStart}all related resources%{strongEnd}, including issues and merge requests."
-msgstr ""
-
msgid "After a successful password update you will be redirected to login screen."
msgstr "パスワードã®æ›´æ–°ã«æˆåŠŸã™ã‚‹ã¨ã€ãƒ­ã‚°ã‚¤ãƒ³ç”»é¢ã«ãƒªãƒ€ã‚¤ãƒ¬ã‚¯ãƒˆã•ã‚Œã¾ã™ã€‚"
@@ -2992,6 +3023,9 @@ msgstr ""
msgid "Akismet helps prevent the creation of spam issues in public projects."
msgstr ""
+msgid "Alert"
+msgstr ""
+
msgid "AlertManagement|Acknowledged"
msgstr "確èªæ¸ˆã¿"
@@ -3364,9 +3398,6 @@ msgstr "ã™ã¹ã¦ã®ãƒ¡ãƒ¼ãƒ«ã‚¢ãƒ‰ãƒ¬ã‚¹ã¯ã‚ãªãŸã®ã‚³ãƒŸãƒƒãƒˆã‚’識別ã™
msgid "All environments"
msgstr "ã™ã¹ã¦ã®ç’°å¢ƒ"
-msgid "All epics"
-msgstr ""
-
msgid "All groups and projects"
msgstr "全グループã¨ãƒ—ロジェクト"
@@ -4101,11 +4132,14 @@ msgstr ""
msgid "ApplicationSettings|Approve users in the pending approval status?"
msgstr ""
-msgid "ApplicationSettings|By making this change, you will automatically approve %d user with the pending approval status."
-msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users with the pending approval status."
-msgstr[0] "ã“ã®å¤‰æ›´ã‚’è¡Œã†ã“ã¨ã«ã‚ˆã‚Šã€ä¿ç•™ä¸­ã®æ‰¿èªã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹ã‚’æŒã¤%dユーザーを自動的ã«æ‰¿èªã—ã¾ã™ã€‚"
+msgid "ApplicationSettings|Approve users who are pending approval?"
+msgstr ""
-msgid "ApplicationSettings|By making this change, you will automatically approve all users in pending approval status."
+msgid "ApplicationSettings|By making this change, you will automatically approve %d user who is pending approval."
+msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users who are pending approval."
+msgstr[0] ""
+
+msgid "ApplicationSettings|By making this change, you will automatically approve all users who are pending approval."
msgstr ""
msgid "ApplicationSettings|Denied domains for sign-ups"
@@ -4506,12 +4540,12 @@ msgstr "アーカイブã•ã‚ŒãŸãƒ—ロジェクト"
msgid "Archiving the project will make it entirely read-only. It is hidden from the dashboard and doesn't show up in searches. %{strong_start}The repository cannot be committed to, and no issues, comments, or other entities can be created.%{strong_end} %{link_start}Learn more.%{link_end}"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to delete this project?"
-msgstr "本当ã«ã“ã®ãƒ—ロジェクトを削除ã—ã¦ã‚‚よã‚ã—ã„ã§ã™ã‹ï¼Ÿ"
-
msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
msgstr ""
+msgid "Are you absolutely sure?"
+msgstr ""
+
msgid "Are you sure that you want to archive this project?"
msgstr "本当ã«ã“ã®ãƒ—ロジェクトをアーカイブã—ã¾ã™ã‹ï¼Ÿ"
@@ -4545,12 +4579,18 @@ msgstr "本当ã«ã“ã® %{typeOfComment} を削除ã—ã¾ã™ã‹ï¼Ÿ"
msgid "Are you sure you want to delete this SSH key?"
msgstr ""
+msgid "Are you sure you want to delete this comment?"
+msgstr ""
+
msgid "Are you sure you want to delete this deploy key?"
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 label?"
+msgstr ""
+
msgid "Are you sure you want to delete this pipeline schedule?"
msgstr "ã“ã®ãƒ‘イプラインスケジュールを削除ã—ã¾ã™ã‹ï¼Ÿ"
@@ -4566,9 +4606,6 @@ msgstr ""
msgid "Are you sure you want to discard your changes?"
msgstr ""
-msgid "Are you sure you want to erase this build?"
-msgstr "ã“ã®ãƒ“ルドを削除ã—ã¦ã‚‚よã‚ã—ã„ã§ã™ã‹ï¼Ÿ"
-
msgid "Are you sure you want to import %d repository?"
msgid_plural "Are you sure you want to import %d repositories?"
msgstr[0] ""
@@ -4615,6 +4652,9 @@ msgstr "ã“ã® ID を削除ã—ã¦ã‚‚よã‚ã—ã„ã§ã™ã‹ï¼Ÿ"
msgid "Are you sure you want to remove this list?"
msgstr ""
+msgid "Are you sure you want to remove this nickname?"
+msgstr ""
+
msgid "Are you sure you want to reset the health check token?"
msgstr "本当ã«ãƒ˜ãƒ«ã‚¹ãƒã‚§ãƒƒã‚¯ãƒˆãƒ¼ã‚¯ãƒ³ã‚’リセットã—ã¾ã™ã‹ï¼Ÿ"
@@ -4627,12 +4667,12 @@ 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 revoke this personal access token? This action cannot be undone."
msgstr ""
+msgid "Are you sure you want to revoke this project access token? This action cannot be undone."
+msgstr ""
+
msgid "Are you sure you want to stop this environment?"
msgstr "ã“ã®ç’°å¢ƒã‚’åœæ­¢ã—ã¦ã‚‚よã‚ã—ã„ã§ã™ã‹ï¼Ÿ"
@@ -4777,9 +4817,6 @@ msgstr "%{assigneeName} ã«å‰²ã‚Šå½“ã¦"
msgid "Assigned to %{assignee_name}"
msgstr "%{assignee_name} ã«å‰²ã‚Šå½“ã¦"
-msgid "Assigned to %{name}"
-msgstr "%{name} ã«å‰²ã‚Šå½“ã¦"
-
msgid "Assigned to me"
msgstr "自分ã«å‰²ã‚Šå½“ã¦ã‚‹"
@@ -4842,6 +4879,9 @@ msgstr[0] "%d 個ã®ãƒ•ã‚¡ã‚¤ãƒ«ã‚’添付"
msgid "Attaching the file failed."
msgstr "ファイルã®æ·»ä»˜ã«å¤±æ•—ã—ã¾ã—ãŸã€‚"
+msgid "Attention"
+msgstr ""
+
msgid "Audit Events"
msgstr "監査イベント"
@@ -5004,6 +5044,12 @@ msgstr "èªè¨¼æ—¥æ™‚"
msgid "Authorized applications (%{size})"
msgstr "承èªã•ã‚ŒãŸã‚¢ãƒ—リケーション(%{size})"
+msgid "AuthorizedApplication|Are you sure you want to revoke this application?"
+msgstr ""
+
+msgid "AuthorizedApplication|Revoke application"
+msgstr ""
+
msgid "Authors: %{authors}"
msgstr "作æˆè€…: %{authors}"
@@ -6193,6 +6239,9 @@ msgstr ""
msgid "CICDAnalytics|Shared Runners Usage"
msgstr ""
+msgid "CICDAnalytics|Shared runner pipeline minute duration by month"
+msgstr ""
+
msgid "CICDAnalytics|Shared runner usage"
msgstr ""
@@ -6334,6 +6383,9 @@ msgstr ""
msgid "Can create groups:"
msgstr ""
+msgid "Can not delete primary training"
+msgstr ""
+
msgid "Can't apply as the source branch was deleted."
msgstr ""
@@ -6667,9 +6719,6 @@ msgstr ""
msgid "Changing any setting here requires an application restart"
msgstr ""
-msgid "Changing group URL can have unintended side effects."
-msgstr "グループ㮠URL を変更ã™ã‚‹ã¨ã€æ„図ã—ãªã„副作用ãŒç™ºç”Ÿã™ã‚‹å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚"
-
msgid "Charts can't be displayed as the request for data has timed out. %{documentationLink}"
msgstr "グラフを表示ã§ãã¾ã›ã‚“。データリクエストãŒã‚¿ã‚¤ãƒ ã‚¢ã‚¦ãƒˆã—ãŸãŸã‚ã§ã™ã€‚%{documentationLink}"
@@ -6757,9 +6806,6 @@ msgstr "承èªã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹ã‚’確èªã—ã¦ã„ã¾ã™"
msgid "Checking branch availability..."
msgstr "ブランãƒãŒåˆ©ç”¨å¯èƒ½ã‹ç¢ºèªã—ã¦ã„ã¾ã™â€¦"
-msgid "Checking group URL availability..."
-msgstr ""
-
msgid "Checking group path availability..."
msgstr "グループパスãŒåˆ©ç”¨å¯èƒ½ã‹ç¢ºèªã—ã¦ã„ã¾ã™..."
@@ -7251,6 +7297,9 @@ msgstr ""
msgid "Clear recent searches"
msgstr "最近検索をクリアー"
+msgid "Clear repository checks"
+msgstr ""
+
msgid "Clear search"
msgstr "検索をクリア"
@@ -7383,9 +7432,6 @@ msgstr ""
msgid "Closed MRs"
msgstr ""
-msgid "Closed epics"
-msgstr ""
-
msgid "Closed issues"
msgstr "クローズã—ãŸã‚¤ã‚·ãƒ¥ãƒ¼"
@@ -7422,13 +7468,13 @@ msgstr ""
msgid "Cluster level"
msgstr "クラスターã®ãƒ¬ãƒ™ãƒ«"
-msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
+msgid "Cluster type must be specified for Stages::ClusterEndpointInserter"
msgstr ""
msgid "ClusterAgents|%{name} successfully deleted"
msgstr ""
-msgid "ClusterAgents|%{number} of %{total} Agents"
+msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
@@ -7470,6 +7516,15 @@ msgstr ""
msgid "ClusterAgents|Agent never connected to GitLab"
msgstr ""
+msgid "ClusterAgents|Agent version mismatch"
+msgstr ""
+
+msgid "ClusterAgents|Agent version mismatch and update"
+msgstr ""
+
+msgid "ClusterAgents|Agent version update required"
+msgstr ""
+
msgid "ClusterAgents|All"
msgstr ""
@@ -7494,7 +7549,7 @@ msgstr ""
msgid "ClusterAgents|Configuration"
msgstr ""
-msgid "ClusterAgents|Connect a cluster through the Agent"
+msgid "ClusterAgents|Connect a cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connect existing cluster"
@@ -7503,13 +7558,13 @@ msgstr ""
msgid "ClusterAgents|Connect with a certificate"
msgstr ""
-msgid "ClusterAgents|Connect with agent"
+msgid "ClusterAgents|Connect with an agent"
msgstr ""
msgid "ClusterAgents|Connect with the GitLab Agent"
msgstr ""
-msgid "ClusterAgents|Connect your cluster through the Agent"
+msgid "ClusterAgents|Connect your cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connected"
@@ -7569,7 +7624,10 @@ msgstr ""
msgid "ClusterAgents|How to register an agent?"
msgstr ""
-msgid "ClusterAgents|Install new Agent"
+msgid "ClusterAgents|How to update an agent?"
+msgstr ""
+
+msgid "ClusterAgents|Install a new agent"
msgstr ""
msgid "ClusterAgents|Last connected %{timeAgo}."
@@ -7596,7 +7654,7 @@ msgstr ""
msgid "ClusterAgents|Never connected"
msgstr ""
-msgid "ClusterAgents|No Agents"
+msgid "ClusterAgents|No agents"
msgstr ""
msgid "ClusterAgents|No clusters connected through cluster certificates"
@@ -7656,6 +7714,9 @@ msgstr ""
msgid "ClusterAgents|The agent has not been connected in a long time. There might be a connectivity issue. Last contact was %{timeAgo}."
msgstr ""
+msgid "ClusterAgents|The agent version do not match each other across your cluster's pods. This can happen when a new agent version was just deployed and Kubernetes is shutting down the old pods."
+msgstr ""
+
msgid "ClusterAgents|The recommended installation method includes the token. If you want to follow the advanced installation method provided in the docs, make sure you save the token value before you close this window."
msgstr ""
@@ -7702,6 +7763,9 @@ msgstr ""
msgid "ClusterAgents|You will need to create a token to connect to your agent"
msgstr ""
+msgid "ClusterAgents|Your agent version is out of sync with your GitLab version (v%{version}), which might cause compatibility problems. Update the agent installed on your cluster to the most recent version."
+msgstr ""
+
msgid "ClusterAgents|Your instance doesn't have the %{linkStart}GitLab Agent Server (KAS)%{linkEnd} set up. Ask a GitLab Administrator to install it."
msgstr ""
@@ -8578,9 +8642,6 @@ msgstr "ComboSearch ãŒå®šç¾©ã•ã‚Œã¦ã„ã¾ã›ã‚“"
msgid "Comma-separated list of email addresses."
msgstr ""
-msgid "Comma-separated list of users allowed to exceed the rate limit."
-msgstr ""
-
msgid "Comma-separated, e.g. '1.1.1.1, 2.2.2.0/24'"
msgstr ""
@@ -8906,6 +8967,12 @@ msgstr ""
msgid "Confidential"
msgstr "éžå…¬é–‹"
+msgid "Confidential issue"
+msgstr ""
+
+msgid "Confidential note"
+msgstr ""
+
msgid "Confidentiality"
msgstr "機密性"
@@ -8939,6 +9006,9 @@ msgstr ""
msgid "Configure Dependency Scanning in `.gitlab-ci.yml`, creating this file if it does not already exist"
msgstr ""
+msgid "Configure GitLab"
+msgstr ""
+
msgid "Configure GitLab runners to start using the Web Terminal. %{helpStart}Learn more.%{helpEnd}"
msgstr "GitLab Runner を設定ã—ã¦Web端末を使ã„始ã‚ã¾ã™ã€‚ 詳細ã¯%{helpStart} ã“ã¡ã‚‰%{helpEnd}ã‚’å‚照。"
@@ -8987,6 +9057,15 @@ msgstr "既存ã®ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã‚’設定ã™ã‚‹"
msgid "Configure pipelines to deploy web apps, backend services, APIs and static resources to Google Cloud"
msgstr ""
+msgid "Configure region"
+msgstr ""
+
+msgid "Configure region for environment"
+msgstr ""
+
+msgid "Configure regions"
+msgstr ""
+
msgid "Configure repository mirroring."
msgstr "リãƒã‚¸ãƒˆãƒªã®ãƒŸãƒ©ãƒ¼ãƒªãƒ³ã‚°ã‚’設定ã—ã¾ã™ã€‚"
@@ -9020,6 +9099,9 @@ msgstr ""
msgid "Configure which lists are shown for anyone who visits this board"
msgstr ""
+msgid "Configure your environments to be deployed to specific geographical regions"
+msgstr ""
+
msgid "Confirm"
msgstr "確èª"
@@ -9719,10 +9801,10 @@ msgstr ""
msgid "CorpusManagement|Actions"
msgstr ""
-msgid "CorpusManagement|Corpus are used in fuzz testing as mutation source to Improve future testing."
+msgid "CorpusManagement|Corpus file"
msgstr ""
-msgid "CorpusManagement|Corpus file"
+msgid "CorpusManagement|Corpus files are used in coverage-guided fuzz testing as seed inputs to improve testing."
msgstr ""
msgid "CorpusManagement|Corpus files must be in *.zip format. Maximum 5 GB"
@@ -9776,6 +9858,9 @@ msgstr "管ç†è€…ã¯ãƒ¡ãƒ³ãƒãƒ¼ã¨ã—ã¦è¿½åŠ ã§ãã¾ã›ã‚“。"
msgid "Could not apply %{name} command."
msgstr ""
+msgid "Could not apply %{name} command. %{message}."
+msgstr ""
+
msgid "Could not authorize chat nickname. Try again!"
msgstr "ãƒãƒ£ãƒƒãƒˆã®ãƒ‹ãƒƒã‚¯ãƒãƒ¼ãƒ ã‚’承èªã§ãã¾ã›ã‚“ã§ã—ãŸã€‚ã‚‚ã†ä¸€åº¦ã‚„ã‚Šç›´ã—ã¦ãã ã•ã„。"
@@ -9926,6 +10011,9 @@ msgstr "ã¯ã˜ã‚ã«GitLabアカウントを作æˆã—ã€ãã®å¾Œ %{label} ã®ã‚
msgid "Create a Mattermost team for this group"
msgstr "ã“ã®ã‚°ãƒ«ãƒ¼ãƒ—ã® Mattermost ãƒãƒ¼ãƒ ã‚’作æˆã—ã¾ã™"
+msgid "Create a group"
+msgstr ""
+
msgid "Create a merge request"
msgstr "マージリクエストを作æˆ"
@@ -9950,6 +10038,9 @@ msgstr "æ–°ã—ã„リãƒã‚¸ãƒˆãƒªã‚’作æˆ"
msgid "Create a personal access token on your account to pull or push via %{protocol}."
msgstr "%{protocol} ã§ãƒ—ッシュやプルã™ã‚‹ãŸã‚ã®ã‚ãªãŸå€‹äººç”¨ã‚¢ã‚¯ã‚»ã‚¹ãƒˆãƒ¼ã‚¯ãƒ³ã‚’作æˆ"
+msgid "Create a project"
+msgstr ""
+
msgid "Create an account using:"
msgstr "アカウントを作æˆã™ã‚‹ã€‚ãã®æ–¹æ³•:"
@@ -10313,6 +10404,9 @@ msgstr "グラフを作æˆã™ã‚‹ã«ã¯ã€Prometheusサーãƒãƒ¼ã‹ã‚‰ã®ãƒ‡ãƒ¼ã‚
msgid "Creation date"
msgstr "作æˆæ—¥æ™‚"
+msgid "Creator"
+msgstr ""
+
msgid "Credentials"
msgstr "èªè¨¼æƒ…å ±"
@@ -10325,9 +10419,15 @@ msgstr ""
msgid "CredentialsInventory|Personal Access Tokens"
msgstr ""
+msgid "CredentialsInventory|Project Access Tokens"
+msgstr ""
+
msgid "CredentialsInventory|SSH Keys"
msgstr "SSH éµ"
+msgid "Credit card required to be on file in order to create a pipeline"
+msgstr ""
+
msgid "Credit card:"
msgstr ""
@@ -10511,9 +10611,6 @@ msgstr ""
msgid "Customer relations"
msgstr ""
-msgid "Customizable by an administrator."
-msgstr ""
-
msgid "Customizable by owners."
msgstr ""
@@ -10643,30 +10740,18 @@ msgstr "グループã®ä¸‹ã«ã‚ã‚‹ã¹ãã§ã™"
msgid "CycleAnalytics|%{selectedLabelsCount} selected (%{maxLabels} max)"
msgstr "%{selectedLabelsCount} 件é¸æŠžæ¸ˆã¿ (最大 %{maxLabels} 件)"
-msgid "CycleAnalytics|%{stageCount} stages selected"
-msgstr "%{stageCount} ステージãŒé¸æŠžã•ã‚Œã¾ã—ãŸ"
-
-msgid "CycleAnalytics|All stages"
-msgstr "全ステージ"
-
-msgid "CycleAnalytics|Average days to completion"
+msgid "CycleAnalytics|Average time to completion"
msgstr ""
msgid "CycleAnalytics|Date"
msgstr "日付"
-msgid "CycleAnalytics|Days to completion"
-msgstr "完了ã¾ã§ã®æ—¥æ•°"
-
msgid "CycleAnalytics|Display chart filters"
msgstr "ãƒãƒ£ãƒ¼ãƒˆãƒ•ã‚£ãƒ«ã‚¿ãƒ¼ã®è¡¨ç¤º"
msgid "CycleAnalytics|Lead Time for Changes"
msgstr ""
-msgid "CycleAnalytics|No stages selected"
-msgstr "ステージã¯é¸æŠžã•ã‚Œã¦ã„ã¾ã›ã‚“"
-
msgid "CycleAnalytics|Number of tasks"
msgstr "タスク数"
@@ -10693,18 +10778,30 @@ msgstr ""
msgid "CycleAnalytics|Showing data for group '%{groupName}' from %{createdAfter} to %{createdBefore}"
msgstr ""
-msgid "CycleAnalytics|Stages"
-msgstr "ステージ"
+msgid "CycleAnalytics|Stage time: %{title}"
+msgstr ""
msgid "CycleAnalytics|Tasks by type"
msgstr "タイプ別ã®ã‚¿ã‚¹ã‚¯"
-msgid "CycleAnalytics|The average time spent in the selected stage for the items that were completed on each date. Data limited to the last 500 items."
+msgid "CycleAnalytics|The average time items spent in this stage. Data limited to items completed within this date range."
msgstr ""
msgid "CycleAnalytics|The given date range is larger than 180 days"
msgstr "指定ã•ã‚ŒãŸæ—¥ä»˜ã®ç¯„囲ãŒ180日を超ãˆã¦ã„ã¾ã™ã€‚"
+msgid "CycleAnalytics|The total time items spent across each value stream stage. Data limited to items completed within this date range."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Stage time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Total time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|Total time"
+msgstr ""
+
msgid "CycleAnalytics|Type of work"
msgstr "仕事ã®ç¨®é¡ž"
@@ -10717,9 +10814,6 @@ msgstr "指定ã•ã‚ŒãŸé–‹å§‹ã‚¤ãƒ™ãƒ³ãƒˆã«ã¯è¨±å¯ã•ã‚Œã¦ã„ã¾ã›ã‚“"
msgid "CycleAnalytics|project dropdown filter"
msgstr "プロジェクトドロップダウンフィルター"
-msgid "CycleAnalytics|stage dropdown"
-msgstr "ステージドロップダウン"
-
msgid "DAG visualization requires at least 3 dependent jobs."
msgstr "DAGã®å¯è¦–化ã«ã¯ã€å°‘ãªãã¨ã‚‚3ã¤ã®ä¾å­˜æ€§ã®ã‚るジョブãŒå¿…è¦ã§ã™ã€‚"
@@ -10819,10 +10913,16 @@ msgstr ""
msgid "DastProfiles|AJAX spider"
msgstr ""
+msgid "DastProfiles|API"
+msgstr ""
+
+msgid "DastProfiles|API endpoint URL"
+msgstr ""
+
msgid "DastProfiles|Active"
msgstr ""
-msgid "DastProfiles|Additional request headers (Optional)"
+msgid "DastProfiles|Additional request headers (optional)"
msgstr ""
msgid "DastProfiles|Are you sure you want to delete this profile?"
@@ -10837,6 +10937,9 @@ msgstr ""
msgid "DastProfiles|Branch missing"
msgstr ""
+msgid "DastProfiles|Choose a scan method"
+msgstr ""
+
msgid "DastProfiles|Could not create the scanner profile. Please try again."
msgstr ""
@@ -10906,7 +11009,13 @@ msgstr ""
msgid "DastProfiles|Excluded URLs"
msgstr ""
-msgid "DastProfiles|Excluded URLs (Optional)"
+msgid "DastProfiles|Excluded URLs (optional)"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths (optional)"
msgstr ""
msgid "DastProfiles|Hide debug messages"
@@ -10963,9 +11072,6 @@ msgstr ""
msgid "DastProfiles|Request headers"
msgstr ""
-msgid "DastProfiles|Rest API"
-msgstr ""
-
msgid "DastProfiles|Run the AJAX spider, in addition to the traditional spider, to crawl the target site."
msgstr ""
@@ -10975,6 +11081,9 @@ msgstr "ターゲットサイトãŠã‚ˆã³ã‚¹ã‚­ãƒ£ãƒ³ä»•æ§˜ã§ä¸€èˆ¬çš„ã«ä½¿ç”¨
msgid "DastProfiles|Save profile"
msgstr ""
+msgid "DastProfiles|Scan method"
+msgstr ""
+
msgid "DastProfiles|Scan mode"
msgstr ""
@@ -11053,12 +11162,24 @@ msgstr ""
msgid "DastProfiles|Website"
msgstr ""
+msgid "DastProfiles|What does each method do?"
+msgstr ""
+
msgid "DastProfiles|You can either choose a passive scan or validate the target site from the site profile management page. %{docsLinkStart}Learn more about site validation.%{docsLinkEnd}"
msgstr ""
msgid "DastProfiles|You cannot run an active scan against an unvalidated site."
msgstr ""
+msgid "DastProfiles|folder/dast_example.har or https://example.com/dast_example.har"
+msgstr ""
+
+msgid "DastProfiles|folder/example.postman_collection.json or https://example.com/"
+msgstr ""
+
+msgid "DastProfiles|folder/openapi.json or https://example.com/openapi.json"
+msgstr ""
+
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
@@ -11165,6 +11286,9 @@ msgstr ""
msgid "DatadogIntegration|API URL"
msgstr ""
+msgid "DatadogIntegration|Custom tags in Datadog. Enter one tag per line in the %{codeOpen}key:value%{codeClose} format. %{linkOpen}How do I use tags?%{linkClose}"
+msgstr ""
+
msgid "DatadogIntegration|Environment"
msgstr ""
@@ -11183,12 +11307,18 @@ msgstr ""
msgid "DatadogIntegration|Tag all data from this GitLab instance in Datadog. Useful when managing several self-managed deployments."
msgstr ""
+msgid "DatadogIntegration|Tags"
+msgstr ""
+
msgid "DatadogIntegration|The Datadog site to send data to. To send data to the EU site, use %{codeOpen}datadoghq.eu%{codeClose}."
msgstr ""
msgid "DatadogIntegration|Trace your GitLab pipelines with Datadog."
msgstr ""
+msgid "DatadogIntegration|have an invalid format"
+msgstr ""
+
msgid "Datasource name not found"
msgstr ""
@@ -11198,9 +11328,6 @@ msgstr "日付"
msgid "Date merged"
msgstr ""
-msgid "Date picker"
-msgstr "日付é¸æŠž"
-
msgid "Date range"
msgstr ""
@@ -11354,9 +11481,6 @@ msgstr ""
msgid "Definition"
msgstr ""
-msgid "Delayed Project Deletion (%{adjourned_deletion})"
-msgstr ""
-
msgid "DelayedJobs|Are you sure you want to run %{jobName} immediately? Otherwise this job will run automatically after its timer finishes."
msgstr ""
@@ -11435,12 +11559,12 @@ msgstr ""
msgid "Delete pipeline"
msgstr "パイプラインã®å‰Šé™¤"
+msgid "Delete pipeline schedule"
+msgstr ""
+
msgid "Delete project"
msgstr "プロジェクトã®å‰Šé™¤"
-msgid "Delete project. Are you ABSOLUTELY SURE?"
-msgstr ""
-
msgid "Delete row"
msgstr ""
@@ -11468,6 +11592,9 @@ msgstr "ã“ã®æ·»ä»˜ãƒ•ã‚¡ã‚¤ãƒ«ã‚’削除"
msgid "Delete this epic and all descendants?"
msgstr ""
+msgid "Delete this project"
+msgstr ""
+
msgid "Delete user list"
msgstr ""
@@ -11720,6 +11847,12 @@ msgstr ""
msgid "Deploy to..."
msgstr "デプロイ先..."
+msgid "DeployBoards|To see deployment progress for your environments, make sure you are deploying to %{codeStart}$KUBE_NAMESPACE%{codeEnd} and annotating with %{codeStart}app.gitlab.com/app=$CI_PROJECT_PATH_SLUG%{codeEnd} and %{codeStart}app.gitlab.com/env=$CI_ENVIRONMENT_SLUG%{codeEnd}."
+msgstr ""
+
+msgid "DeployBoard|Kubernetes Pods"
+msgstr ""
+
msgid "DeployFreeze|Add a freeze period to prevent unintended releases during a period of time for a given environment. You must update the deployment jobs in %{filename} according to the deploy freezes added here. %{freeze_period_link_start}Learn more.%{freeze_period_link_end}"
msgstr ""
@@ -11804,9 +11937,6 @@ msgstr "読ã¿å–り専用"
msgid "DeployTokens|Active Deploy Tokens (%{active_tokens})"
msgstr "アクティブãªãƒ‡ãƒ—ロイトークン (%{active_tokens})"
-msgid "DeployTokens|Allows read and write access to registry images."
-msgstr ""
-
msgid "DeployTokens|Allows read and write access to the package registry."
msgstr ""
@@ -11819,6 +11949,9 @@ msgstr ""
msgid "DeployTokens|Allows read-only access to the repository."
msgstr ""
+msgid "DeployTokens|Allows write access to registry images."
+msgstr ""
+
msgid "DeployTokens|Copy deploy token"
msgstr "デプロイトークンをコピー"
@@ -11912,12 +12045,57 @@ msgstr "デプロイ先"
msgid "Deploying to AWS is easy with GitLab"
msgstr ""
+msgid "Deployment"
+msgstr ""
+
msgid "Deployment Frequency"
msgstr "デプロイ頻度"
+msgid "Deployment Target|Project deployment target (optional)"
+msgstr ""
+
+msgid "Deployment Target|Select the deployment target"
+msgstr ""
+
msgid "Deployment frequency"
msgstr ""
+msgid "DeploymentTarget|GitLab Pages"
+msgstr ""
+
+msgid "DeploymentTarget|Heroku"
+msgstr ""
+
+msgid "DeploymentTarget|Infrastructure provider (Terraform, Cloudformation, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Kubernetes (GKE, EKS, OpenShift, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Managed container runtime (Fargate, Cloud Run, DigitalOcean App)"
+msgstr ""
+
+msgid "DeploymentTarget|Mobile app store"
+msgstr ""
+
+msgid "DeploymentTarget|No deployment planned"
+msgstr ""
+
+msgid "DeploymentTarget|Other hosting service"
+msgstr ""
+
+msgid "DeploymentTarget|Registry (package or container)"
+msgstr ""
+
+msgid "DeploymentTarget|Self-managed container runtime (Podman, Docker Swarm, Docker Compose)"
+msgstr ""
+
+msgid "DeploymentTarget|Serverless backend (Lambda, Cloud functions)"
+msgstr ""
+
+msgid "DeploymentTarget|Virtual machine (for example, EC2)"
+msgstr ""
+
msgid "Deployments"
msgstr ""
@@ -11955,6 +12133,9 @@ msgstr ""
msgid "Deployment|This deployment was created using the API"
msgstr "ã“ã®ãƒ‡ãƒ—ロイã¯APIを使用ã—ã¦ä½œæˆã•ã‚Œã¾ã—ãŸ"
+msgid "Deployment|Triggerer"
+msgstr ""
+
msgid "Deployment|Waiting"
msgstr ""
@@ -11982,6 +12163,18 @@ msgstr "æˆåŠŸ"
msgid "Deprecated API rate limits"
msgstr ""
+msgid "Deprecations|Feature deprecation and removal"
+msgstr ""
+
+msgid "Deprecations|For information on a possible replacement %{epicStart} learn more about Opstrace %{epicEnd}."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7 and are %{epicStart} scheduled for removal %{epicEnd} in GitLab 15.0."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7, and are %{removal_link_start} scheduled for removal %{link_end} in GitLab 15.0. For information on a possible replacement, %{opstrace_link_start} learn more about Opstrace %{link_end}."
+msgstr ""
+
msgid "Deprioritize label"
msgstr "éžå„ªå…ˆãƒ©ãƒ™ãƒ«"
@@ -12226,10 +12419,10 @@ msgstr ""
msgid "DevopsAdoption|At least one deploy"
msgstr ""
-msgid "DevopsAdoption|At least one issue opened"
+msgid "DevopsAdoption|At least one issue created"
msgstr ""
-msgid "DevopsAdoption|At least one merge request opened"
+msgid "DevopsAdoption|At least one merge request created"
msgstr ""
msgid "DevopsAdoption|At least one pipeline successfully run"
@@ -12427,6 +12620,9 @@ msgstr ""
msgid "Direct member"
msgstr ""
+msgid "Direct members"
+msgstr ""
+
msgid "Direct non-authenticated users to this page."
msgstr ""
@@ -12542,6 +12738,9 @@ msgid "Dismiss %d selected vulnerability as"
msgid_plural "Dismiss %d selected vulnerabilities as"
msgstr[0] "é¸æŠžã—㟠%d 件脆弱性を無視。ç†ç”±: "
+msgid "Dismiss Alert"
+msgstr ""
+
msgid "Dismiss merge request promotion"
msgstr ""
@@ -12569,9 +12768,15 @@ msgstr "%{projectLink} ã®ãƒ‘イプライン %{pipelineLink} ã§å´ä¸‹ã•ã‚ŒãŸ"
msgid "Display alerts from all configured monitoring tools."
msgstr ""
+msgid "Display milestones"
+msgstr ""
+
msgid "Display name"
msgstr "表示å"
+msgid "Display progress of child issues"
+msgstr ""
+
msgid "Display rendered file"
msgstr ""
@@ -12677,6 +12882,9 @@ msgstr "エクスãƒãƒ¼ãƒˆã‚’ダウンロード"
msgid "Download image"
msgstr "イメージをダウンロード"
+msgid "Download payload"
+msgstr ""
+
msgid "Download raw data (.csv)"
msgstr ""
@@ -12854,6 +13062,9 @@ msgstr "%{user_name} ã® ID を編集ã™ã‚‹"
msgid "Edit in Web IDE"
msgstr ""
+msgid "Edit in pipeline editor"
+msgstr ""
+
msgid "Edit in single-file editor"
msgstr ""
@@ -12896,6 +13107,9 @@ msgstr "Wikiページã®ç·¨é›†"
msgid "Edit your most recent comment in a thread (from an empty textarea)"
msgstr "スレッド内ã®æœ€æ–°ã®ã‚ãªãŸã®ã‚³ãƒ¡ãƒ³ãƒˆã‚’編集 (空ã®ãƒ†ã‚­ã‚¹ãƒˆé ˜åŸŸã‹ã‚‰)"
+msgid "Edit, lint, and visualize your pipeline."
+msgstr ""
+
msgid "Edited"
msgstr ""
@@ -13337,6 +13551,9 @@ msgstr ""
msgid "Enforce two-factor authentication for all user sign-ins."
msgstr ""
+msgid "Enhance security by storing service account keys in secret managers - learn more about %{docLinkStart}secret management with GitLab%{docLinkEnd}"
+msgstr ""
+
msgid "Ensure connectivity is available from the GitLab server to the Prometheus server"
msgstr "GitLab サーãƒãƒ¼ã‹ã‚‰ Prometheus サーãƒãƒ¼ã¸ã®æŽ¥ç¶šãŒåˆ©ç”¨ã§ãã‚‹ã“ã¨ã‚’確èªã—ã¾ã™ã€‚"
@@ -13397,6 +13614,9 @@ 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 "モãƒã‚¤ãƒ«ç«¯æœ«ã®2è¦ç´ èªè¨¼ã‚¢ãƒ—リã‹ã‚‰ã‚³ãƒ¼ãƒ‰ã‚’入力ã—ã¾ã™ã€‚デãƒã‚¤ã‚¹ã‚’紛失ã—ãŸå ´åˆã¯ã€ãƒªã‚«ãƒãƒªãƒ¼ã‚³ãƒ¼ãƒ‰ã®ã„ãšã‚Œã‹ã‚’入力ã—ã¦ãã ã•ã„。"
+msgid "Enter the following to confirm:"
+msgstr ""
+
msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
@@ -13926,9 +14146,6 @@ 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 "エラーãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚ブロックã•ã‚ŒãŸãƒ¦ãƒ¼ã‚¶ãƒ¼ã¯éžæœ‰åŠ¹åŒ–ã§ãã¾ã›ã‚“。"
@@ -14064,6 +14281,9 @@ msgstr ""
msgid "Errors:"
msgstr ""
+msgid "Escalate this incident"
+msgstr ""
+
msgid "Escalation Policies"
msgstr ""
@@ -14076,6 +14296,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy"
+msgstr ""
+
msgid "Escalation policy:"
msgstr ""
@@ -14326,6 +14549,9 @@ msgstr ""
msgid "Existing sign in methods may be removed"
msgstr ""
+msgid "Exit."
+msgstr ""
+
msgid "Expand"
msgstr "展開"
@@ -14422,6 +14648,9 @@ msgstr "プロジェクトを探ã™"
msgid "Explore public groups"
msgstr "公開グループを検索"
+msgid "Explore public projects"
+msgstr ""
+
msgid "Explore snippets"
msgstr ""
@@ -14582,8 +14811,8 @@ msgid "Failed to archive a design. Please try again."
msgid_plural "Failed to archive designs. Please try again."
msgstr[0] ""
-msgid "Failed to assign a reviewer because no user was found."
-msgstr "ユーザãŒè¦‹ã¤ã‹ã‚‰ãªã„ãŸã‚ã€ãƒ¬ãƒ“ュアーを割り当ã¦ã‚‹ã“ã¨ãŒã§ãã¾ã›ã‚“ã§ã—ãŸã€‚"
+msgid "Failed to assign a reviewer because no user was specified."
+msgstr ""
msgid "Failed to assign a user because no user was found."
msgstr "ユーザーã®å‰²ã‚Šå½“ã¦ã«å¤±æ•—ã—ã¾ã—ãŸã€‚見ã¤ã‹ã‚‰ãªã‹ã£ãŸã‹ã‚‰ã§ã™ã€‚"
@@ -14648,10 +14877,10 @@ msgstr ""
msgid "Failed to find import label for Jira import."
msgstr ""
-msgid "Failed to generate export, please try again later."
+msgid "Failed to find users for %{missing}"
msgstr ""
-msgid "Failed to generate report, please try again after sometime"
+msgid "Failed to generate export, please try again later."
msgstr ""
msgid "Failed to get ref."
@@ -14750,6 +14979,9 @@ msgstr "Zoom ミーティングã®å‰Šé™¤ã«å¤±æ•—ã—ã¾ã—ãŸ"
msgid "Failed to remove a to-do item for the design."
msgstr ""
+msgid "Failed to remove attention because no user was found."
+msgstr ""
+
msgid "Failed to remove mirror."
msgstr "ミラーã®å‰Šé™¤ã«å¤±æ•—ã—ã¾ã—ãŸã€‚"
@@ -14762,6 +14994,9 @@ msgstr "ユーザー識別å­ã‚’削除ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚"
msgid "Failed to remove user key."
msgstr "ユーザーキーを削除ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚"
+msgid "Failed to request attention because no user was found."
+msgstr ""
+
msgid "Failed to reset key. Please try again."
msgstr "キーをリセットã§ãã¾ã›ã‚“ã§ã—ãŸã€‚ã‚‚ã†ä¸€åº¦ãŠè©¦ã—下ã•ã„。"
@@ -14843,6 +15078,9 @@ msgstr ""
msgid "Feature Flags"
msgstr "機能フラグ"
+msgid "Feature deprecation and removal"
+msgstr ""
+
msgid "Feature flag status"
msgstr ""
@@ -15339,7 +15577,7 @@ msgstr ""
msgid "For each job, re-use the project workspace. If the workspace doesn't exist, use %{code_open}git clone%{code_close}."
msgstr ""
-msgid "For example, the application using the token or the purpose of the token."
+msgid "For example, the application using the token or the purpose of the token. Do not give sensitive information for the name of the token, as it will be visible to all %{resource_type} members."
msgstr ""
msgid "For files larger than this limit, only index the file name. The file content is neither indexed nor searchable."
@@ -15423,9 +15661,6 @@ msgstr ""
msgid "ForkProject|Select a namespace"
msgstr ""
-msgid "ForkProject|Select a namespace to fork the project"
-msgstr ""
-
msgid "ForkProject|The project can be accessed by any logged in user."
msgstr ""
@@ -15522,6 +15757,9 @@ msgstr ""
msgid "Full name"
msgstr "æ°å"
+msgid "GCP region configured"
+msgstr ""
+
msgid "GPG Key ID:"
msgstr "GPG キー ID:"
@@ -15702,6 +15940,9 @@ msgstr ""
msgid "Geo|Failed"
msgstr "失敗"
+msgid "Geo|Filter Geo sites"
+msgstr ""
+
msgid "Geo|Filter by name"
msgstr ""
@@ -16113,6 +16354,12 @@ msgstr "GitLab インãƒãƒ¼ãƒˆ"
msgid "GitLab Issue"
msgstr "GitLabイシュー"
+msgid "GitLab KAS"
+msgstr ""
+
+msgid "GitLab Memberships CSV Export"
+msgstr ""
+
msgid "GitLab Pages"
msgstr ""
@@ -16161,6 +16408,9 @@ 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 free to use. Many features for larger teams are part of our %{link_start}paid products%{link_end}. You can try Ultimate for free without any obligation or payment details."
+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 "GitLab ã¯ã€ã“ã®ãƒ‰ãƒ¡ã‚¤ãƒ³ã® Let's Encrypt ã® SSL 証明書をå–å¾—ã—よã†ã¨ã—ã¦ã„ã¾ã™ã€‚ã“ã®ãƒ—ロセスã«ã¯æ™‚é–“ãŒã‹ã‹ã‚‹å ´åˆãŒã‚ã‚Šã¾ã™ã€‚後ã§ã‚‚ã†ä¸€åº¦ã‚„ã‚Šç›´ã—ã¦ãã ã•ã„。"
@@ -16287,7 +16537,7 @@ msgstr "確èªæ¸ˆ"
msgid "GitLabPages|When enabled, all attempts to visit your website through HTTP are automatically redirected to HTTPS using a response with status code 301. Requires a valid certificate for all domains. %{docs_link_start}Learn more.%{link_end}"
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. %{docs_link_start}Learn more.%{link_end}"
+msgid "GitLabPages|When using Pages under the general domain of a GitLab instance (%{pages_host}), you cannot use HTTPS with subdomains of subdomains. If your namespace or groupname contains a dot, it does not work. This is a limitation of the HTTP Over TLS protocol. HTTP pages work if you don't redirect HTTP to HTTPS. %{docs_link_start}Learn more.%{link_end}"
msgstr ""
msgid "GitLabPages|With GitLab Pages you can host your static website directly from your GitLab repository. %{docs_link_start}Learn more.%{link_end}"
@@ -16464,9 +16714,6 @@ msgstr "ファイルã«ç§»å‹•"
msgid "Go to find file"
msgstr "ファイルã®æ¤œç´¢ã«ç§»å‹•"
-msgid "Go to fork"
-msgstr ""
-
msgid "Go to issue boards"
msgstr "イシューボードã¸ç§»å‹•"
@@ -16674,9 +16921,6 @@ msgstr "グループ Git LFS ã®ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹:"
msgid "Group Hooks"
msgstr "グループフック"
-msgid "Group ID"
-msgstr "グループ ID"
-
msgid "Group Owner must have signed in with SAML before enabling Group Managed Accounts"
msgstr "グループ管ç†ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã‚’有効ã«ã™ã‚‹å‰ã«ã€ã‚°ãƒ«ãƒ¼ãƒ—所有者ãŒSAMLã§ã‚µã‚¤ãƒ³ã‚¤ãƒ³ã—ã¦ã„ã‚‹å¿…è¦ãŒã‚ã‚Šã¾ã™"
@@ -16704,9 +16948,6 @@ msgstr "グループアãƒã‚¿ãƒ¼"
msgid "Group by"
msgstr ""
-msgid "Group description"
-msgstr ""
-
msgid "Group description (optional)"
msgstr "グループã®èª¬æ˜Ž(ä»»æ„)"
@@ -16821,7 +17062,7 @@ msgstr "グループ:%{group_name}"
msgid "Group: %{name}"
msgstr "グループ: %{name}"
-msgid "GroupActivityMetrics|Issues opened"
+msgid "GroupActivityMetrics|Issues created"
msgstr ""
msgid "GroupActivityMetrics|Last 90 days"
@@ -16830,7 +17071,7 @@ msgstr ""
msgid "GroupActivityMetrics|Members added"
msgstr ""
-msgid "GroupActivityMetrics|Merge Requests opened"
+msgid "GroupActivityMetrics|Merge Requests created"
msgstr ""
msgid "GroupActivityMetrics|Recent activity"
@@ -17121,6 +17362,9 @@ msgstr ""
msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
+msgid "GroupSettings|Choose a group path that does not start with a dash or end with a period. It can also contain alphanumeric characters and underscores."
+msgstr ""
+
msgid "GroupSettings|Compliance frameworks"
msgstr ""
@@ -17154,8 +17398,8 @@ msgstr ""
msgid "GroupSettings|If not specified at the group or instance level, the default is %{default_initial_branch_name}. Does not affect existing repositories."
msgstr ""
-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|If the parent group's visibility is lower than the group's current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility."
+msgstr ""
msgid "GroupSettings|New runners registration token has been generated!"
msgstr "æ–°ã—ã„ランナー登録トークンを生æˆã—ã¾ã—ãŸï¼"
@@ -17271,7 +17515,10 @@ msgstr "グループ (%{count})"
msgid "Groups and projects"
msgstr ""
-msgid "Groups and subgroups"
+msgid "Groups are a great way to organize projects and people."
+msgstr ""
+
+msgid "Groups are the best way to manage projects and members."
msgstr ""
msgid "Groups to synchronize"
@@ -17382,14 +17629,17 @@ msgstr ""
msgid "GroupsTree|Are you sure you want to leave the \"%{fullName}\" group?"
msgstr "\"%{fullName}\" グループã‹ã‚‰é›¢è„±ã—よã†ã¨ã—ã¦ã„ã¾ã™ã€‚よã‚ã—ã„ã§ã™ã‹ï¼Ÿ"
-msgid "GroupsTree|Edit group"
-msgstr "グループを編集"
+msgid "GroupsTree|Delete"
+msgstr ""
+
+msgid "GroupsTree|Edit"
+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|Leave group"
+msgstr ""
msgid "GroupsTree|Loading groups"
msgstr "グループã®èª­ã¿è¾¼ã¿ä¸­"
@@ -17400,9 +17650,57 @@ msgstr "検索ã«é©åˆã™ã‚‹ã‚°ãƒ«ãƒ¼ãƒ—ã¯ã‚ã‚Šã¾ã›ã‚“"
msgid "GroupsTree|No groups or projects matched your search"
msgstr "検索ã«é©åˆã™ã‚‹ãƒ—ロジェクトã€ã‚°ãƒ«ãƒ¼ãƒ—ãŒã‚ã‚Šã¾ã›ã‚“"
+msgid "GroupsTree|Options"
+msgstr ""
+
msgid "GroupsTree|Search by name"
msgstr "åå‰ã§æ¤œç´¢"
+msgid "Groups|Avatar will be removed. Are you sure?"
+msgstr ""
+
+msgid "Groups|Changing group URL can have unintended side effects."
+msgstr ""
+
+msgid "Groups|Checking group URL availability..."
+msgstr ""
+
+msgid "Groups|Enter a descriptive name for your group."
+msgstr ""
+
+msgid "Groups|Group ID"
+msgstr ""
+
+msgid "Groups|Group URL"
+msgstr ""
+
+msgid "Groups|Group avatar"
+msgstr ""
+
+msgid "Groups|Group description (optional)"
+msgstr ""
+
+msgid "Groups|Group name"
+msgstr ""
+
+msgid "Groups|Group path is available."
+msgstr ""
+
+msgid "Groups|Group path is unavailable. Path has been replaced with a suggested available path."
+msgstr ""
+
+msgid "Groups|Learn more"
+msgstr ""
+
+msgid "Groups|Must start with letter, digit, emoji, or underscore. Can also contain periods, dashes, spaces, and parentheses."
+msgstr ""
+
+msgid "Groups|Remove avatar"
+msgstr ""
+
+msgid "Groups|Save changes"
+msgstr ""
+
msgid "Guideline"
msgstr "ガイドライン"
@@ -17412,6 +17710,9 @@ msgstr ""
msgid "HAR file path or URL"
msgstr ""
+msgid "HTTP Archive (HAR)"
+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} ã§ç”Ÿæˆã§ãã¾ã™"
@@ -17810,6 +18111,9 @@ msgstr "情報: SSH éµã®æœ‰åŠ¹æœŸé™ãŒåˆ‡ã‚Œã¦ã„ã¾ã™ã€‚æ–°ã—ã„ SSH éµã
msgid "INFO: Your SSH key is expiring soon. Please generate a new key."
msgstr "情報: SSHéµãŒã¾ã‚‚ãªã期é™åˆ‡ã‚Œã«ãªã‚Šã¾ã™ã€‚æ–°ã—ã„ SSHéµ ã‚’ç”Ÿæˆã—ã¦ãã ã•ã„。"
+msgid "IP"
+msgstr ""
+
msgid "IP Address"
msgstr "IP アドレス"
@@ -17846,6 +18150,9 @@ msgstr ""
msgid "IdentityVerification|Verify your identity"
msgstr ""
+msgid "IdentityVerification|You can always verify your account at a later time to create a group."
+msgstr ""
+
msgid "If any indexed field exceeds this limit, it is truncated to this number of characters. The rest of the content is neither indexed nor searchable. This does not apply to repository and wiki indexing. For unlimited characters, set this to 0."
msgstr ""
@@ -17903,6 +18210,9 @@ msgstr "GitHub を使用ã—ã¦ã„ã‚‹å ´åˆã€GitHub 上ã®ã‚³ãƒŸãƒƒãƒˆã‚„プルã
msgid "If you add %{codeStart}needs%{codeEnd} to jobs in your pipeline you'll be able to view the %{codeStart}needs%{codeEnd} relationships between jobs in this tab as a %{linkStart}Directed Acyclic Graph (DAG)%{linkEnd}."
msgstr ""
+msgid "If you are added to a project, it will be displayed here."
+msgstr ""
+
msgid "If you did not initiate these sign-in attempts, please reach out to your administrator or enable two-factor authentication (2FA) on your account."
msgstr ""
@@ -18206,12 +18516,24 @@ msgstr ""
msgid "InProductMarketing|3 ways to dive into GitLab CI/CD"
msgstr ""
+msgid "InProductMarketing|A single application eliminates complex integrations, data chokepoints, and toolchain maintenance, resulting in greater productivity and lower cost."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features, build more efficiently, strengthen security and compliance."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features."
+msgstr ""
+
msgid "InProductMarketing|Actually, GitLab makes the team work (better)"
msgstr ""
msgid "InProductMarketing|And finally %{deploy_link} a Python application."
msgstr ""
+msgid "InProductMarketing|And many more..."
+msgstr ""
+
msgid "InProductMarketing|Are your runners ready?"
msgstr ""
@@ -18230,15 +18552,33 @@ msgstr ""
msgid "InProductMarketing|Blog"
msgstr ""
+msgid "InProductMarketing|Break down silos to coordinate seamlessly across development, operations, and security with a consistent experience across the development lifecycle."
+msgstr ""
+
+msgid "InProductMarketing|Burn up/down charts"
+msgstr ""
+
msgid "InProductMarketing|By enabling code owners and required merge approvals the right person will review the right MR. This is a win-win: cleaner code and a more efficient review process."
msgstr "コードオーナーã¨ãƒžãƒ¼ã‚¸æ‰¿èªå¿…須化を有効化ã™ã‚‹ã“ã¨ã§ã€å€‹ã€…ã®MRã‚’é©åˆ‡ãªäººãŒãƒ¬ãƒ“ューã§ãるよã†ã«ãªã‚Šã¾ã™ã€‚ã“ã‚Œã«ã‚ˆã‚Šç°¡æ½”ãªã‚³ãƒ¼ãƒ‰ã¨åŠ¹çŽ‡çš„ãªãƒ¬ãƒ“ュープロセスãŒå®Ÿç¾ã—ã¾ã™ã€‚"
msgid "InProductMarketing|Click on the number below that corresponds with your answer — 1 being very difficult, 5 being very easy."
msgstr ""
+msgid "InProductMarketing|Code owners"
+msgstr ""
+
msgid "InProductMarketing|Code owners and required merge approvals are part of the paid tiers of GitLab. You can start a free 30-day trial of GitLab Ultimate and enable these features in less than 5 minutes with no credit card required."
msgstr ""
+msgid "InProductMarketing|Code review analytics"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration across stages in GitLab"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration made easy"
+msgstr ""
+
msgid "InProductMarketing|Create a custom CI runner with just a few clicks"
msgstr ""
@@ -18248,12 +18588,21 @@ msgstr ""
msgid "InProductMarketing|Create a project in GitLab in 5 minutes"
msgstr ""
+msgid "InProductMarketing|Create well-defined workflows by using scoped labels on issues, merge requests, and epics. Labels with the same scope cannot be used together, which prevents conflicts."
+msgstr ""
+
msgid "InProductMarketing|Create your first project!"
msgstr ""
+msgid "InProductMarketing|Define who owns specific files or directories, so the right reviewers are suggested when a merge request introduces changes to those files."
+msgstr ""
+
msgid "InProductMarketing|Deliver Better Products Faster"
msgstr ""
+msgid "InProductMarketing|Dependency scanning"
+msgstr ""
+
msgid "InProductMarketing|Did you know teams that use GitLab are far more efficient?"
msgstr ""
@@ -18263,15 +18612,27 @@ msgstr ""
msgid "InProductMarketing|Dig in and create a project and a repo"
msgstr ""
+msgid "InProductMarketing|Discover Premium & Ultimate"
+msgstr ""
+
+msgid "InProductMarketing|Discover Premium & Ultimate."
+msgstr ""
+
msgid "InProductMarketing|Do you have a minute?"
msgstr ""
msgid "InProductMarketing|Do you have a teammate who would be perfect for this task?"
msgstr ""
+msgid "InProductMarketing|Dynamic application security testing"
+msgstr ""
+
msgid "InProductMarketing|Easy"
msgstr ""
+msgid "InProductMarketing|Epics"
+msgstr ""
+
msgid "InProductMarketing|Expand your DevOps journey with a free GitLab trial"
msgstr ""
@@ -18293,9 +18654,15 @@ msgstr ""
msgid "InProductMarketing|Feel the need for speed?"
msgstr ""
+msgid "InProductMarketing|Find and fix bottlenecks in your code review process by understanding how long open merge requests have been in review."
+msgstr ""
+
msgid "InProductMarketing|Find out how your teams are really doing"
msgstr ""
+msgid "InProductMarketing|Find out if your external libraries are safe. Run dependency scanning jobs that check for known vulnerabilities in your external libraries."
+msgstr ""
+
msgid "InProductMarketing|Follow our steps"
msgstr ""
@@ -18332,6 +18699,9 @@ msgstr ""
msgid "InProductMarketing|GitLab is better with teammates to help out!"
msgstr ""
+msgid "InProductMarketing|GitLab is infrastructure agnostic (supporting GCP, AWS, Azure, OpenShift, VMWare, On Prem, Bare Metal, and more), offering a consistent workflow experience – irrespective of the environment."
+msgstr ""
+
msgid "InProductMarketing|GitLab provides static application security testing (SAST), dynamic application security testing (DAST), container scanning, and dependency scanning to help you deliver secure applications along with license compliance."
msgstr ""
@@ -18422,21 +18792,36 @@ msgstr ""
msgid "InProductMarketing|It's also possible to simply %{external_repo_link} in order to take advantage of GitLab's CI/CD."
msgstr ""
+msgid "InProductMarketing|Keep your code quality high by defining who should approve merge requests and how many approvals are required."
+msgstr ""
+
msgid "InProductMarketing|Launch GitLab CI/CD in 20 minutes or less"
msgstr ""
+msgid "InProductMarketing|Lower cost of development"
+msgstr ""
+
+msgid "InProductMarketing|Make it easier to collaborate on high-level ideas by grouping related issues in an epic."
+msgstr ""
+
msgid "InProductMarketing|Making the switch? It's easier than you think to import your projects into GitLab. Move %{github_link}, or import something %{bitbucket_link}."
msgstr ""
msgid "InProductMarketing|Master the art of importing!"
msgstr ""
+msgid "InProductMarketing|Merge request approval rule"
+msgstr ""
+
msgid "InProductMarketing|Move on to easily creating a Pages website %{ci_template_link}"
msgstr ""
msgid "InProductMarketing|Multiple owners, confusing workstreams? We've got you covered"
msgstr ""
+msgid "InProductMarketing|Multiple required approvers"
+msgstr ""
+
msgid "InProductMarketing|Need an alternative to importing?"
msgstr ""
@@ -18449,18 +18834,33 @@ msgstr ""
msgid "InProductMarketing|Our tool brings all the things together"
msgstr ""
+msgid "InProductMarketing|Protect your web application by using DAST to examine for vulnerabilities in deployed environments."
+msgstr ""
+
msgid "InProductMarketing|Rapid development, simplified"
msgstr ""
msgid "InProductMarketing|Reduce Security & Compliance Risk"
msgstr ""
+msgid "InProductMarketing|Require multiple approvers on a merge request, so you know it's in good shape before it's merged."
+msgstr ""
+
+msgid "InProductMarketing|Roadmaps"
+msgstr ""
+
+msgid "InProductMarketing|Scoped labels"
+msgstr ""
+
msgid "InProductMarketing|Security that's integrated into your development lifecycle"
msgstr ""
msgid "InProductMarketing|Sometimes you're not ready to make a full transition to a new tool. If you're not ready to fully commit, %{mirroring_link} gives you a safe way to try out GitLab in parallel with your current tool."
msgstr ""
+msgid "InProductMarketing|Speed. Efficiency. Trust."
+msgstr ""
+
msgid "InProductMarketing|Spin up an autoscaling runner in GitLab"
msgstr ""
@@ -18470,6 +18870,9 @@ msgstr ""
msgid "InProductMarketing|Start a Self-Managed trial"
msgstr ""
+msgid "InProductMarketing|Start a free trial"
+msgstr ""
+
msgid "InProductMarketing|Start a free trial of GitLab Ultimate – no credit card required"
msgstr ""
@@ -18536,6 +18939,9 @@ msgstr ""
msgid "InProductMarketing|To understand and get the most out of GitLab, start at the beginning and %{project_link}. In GitLab, repositories are part of a project, so after you've created your project you can go ahead and %{repo_link}."
msgstr ""
+msgid "InProductMarketing|Track completed issues in a chart, so you can see how a milestone is progressing at a glance."
+msgstr ""
+
msgid "InProductMarketing|Try GitLab Ultimate for free"
msgstr ""
@@ -18572,6 +18978,9 @@ msgstr ""
msgid "InProductMarketing|Very easy"
msgstr ""
+msgid "InProductMarketing|Visualize your epics and milestones in a timeline."
+msgstr ""
+
msgid "InProductMarketing|Want to host GitLab on your servers?"
msgstr ""
@@ -18593,6 +19002,9 @@ msgstr ""
msgid "InProductMarketing|YouTube"
msgstr ""
+msgid "InProductMarketing|Your software, deployed your way"
+msgstr ""
+
msgid "InProductMarketing|Your teams can be more efficient"
msgstr ""
@@ -18713,9 +19125,18 @@ msgstr ""
msgid "IncidentManagement|No incidents to display."
msgstr ""
+msgid "IncidentManagement|None"
+msgstr ""
+
msgid "IncidentManagement|Open"
msgstr ""
+msgid "IncidentManagement|Page your team with escalation policies"
+msgstr ""
+
+msgid "IncidentManagement|Paged"
+msgstr ""
+
msgid "IncidentManagement|Published"
msgstr ""
@@ -18725,6 +19146,9 @@ msgstr ""
msgid "IncidentManagement|Severity"
msgstr ""
+msgid "IncidentManagement|Status"
+msgstr ""
+
msgid "IncidentManagement|There are no closed incidents"
msgstr ""
@@ -18743,6 +19167,9 @@ msgstr ""
msgid "IncidentManagement|Unpublished"
msgstr ""
+msgid "IncidentManagement|Use escalation policies to automatically page your team when incidents are created."
+msgstr ""
+
msgid "IncidentSettings|Activate \"time to SLA\" countdown timer"
msgstr ""
@@ -18788,7 +19215,10 @@ msgstr ""
msgid "Incidents"
msgstr "インシデント"
-msgid "Incidents|Add a URL"
+msgid "Incidents|Add image details"
+msgstr ""
+
+msgid "Incidents|Add text or a link to display with your image. If you don't add either, the file name displays instead."
msgstr ""
msgid "Incidents|Drop or %{linkStart}upload%{linkEnd} a metric screenshot to attach it to the incident"
@@ -18803,10 +19233,10 @@ msgstr ""
msgid "Incidents|There was an issue loading metric images."
msgstr ""
-msgid "Incidents|There was an issue uploading your image."
+msgid "Incidents|There was an issue updating your image."
msgstr ""
-msgid "Incidents|You can optionally add a URL to link users to the original graph."
+msgid "Incidents|There was an issue uploading your image."
msgstr ""
msgid "Incident|Alert details"
@@ -18815,9 +19245,18 @@ msgstr ""
msgid "Incident|Are you sure you wish to delete this image?"
msgstr ""
+msgid "Incident|Delete image"
+msgstr ""
+
msgid "Incident|Deleting %{filename}"
msgstr ""
+msgid "Incident|Edit image text or link"
+msgstr ""
+
+msgid "Incident|Editing %{filename}"
+msgstr ""
+
msgid "Incident|Metrics"
msgstr ""
@@ -19086,12 +19525,18 @@ msgstr ""
msgid "Integrations|Branches for which notifications are to be sent"
msgstr ""
+msgid "Integrations|Clear if using a self-signed certificate."
+msgstr ""
+
msgid "Integrations|Comment detail:"
msgstr ""
msgid "Integrations|Comment settings:"
msgstr ""
+msgid "Integrations|Connection details"
+msgstr ""
+
msgid "Integrations|Connection failed. Please check your settings."
msgstr ""
@@ -19116,6 +19561,9 @@ msgstr ""
msgid "Integrations|Enable GitLab.com slash commands in a Slack workspace."
msgstr ""
+msgid "Integrations|Enable SSL verification"
+msgstr ""
+
msgid "Integrations|Enable comments"
msgstr ""
@@ -19194,6 +19642,9 @@ msgstr ""
msgid "Integrations|Return to GitLab for Jira"
msgstr ""
+msgid "Integrations|SSL verification"
+msgstr ""
+
msgid "Integrations|Save settings?"
msgstr ""
@@ -19239,9 +19690,6 @@ msgstr ""
msgid "Integrations|Use default settings"
msgstr ""
-msgid "Integrations|When you mention a Jira issue in a commit or merge request, GitLab creates a remote link and comment (if enabled)."
-msgstr ""
-
msgid "Integrations|You can now close this window and return to the GitLab for Jira application."
msgstr ""
@@ -19266,9 +19714,6 @@ msgstr ""
msgid "Integrations|can't exceed %{recipients_limit}"
msgstr ""
-msgid "Interactive developer security education."
-msgstr ""
-
msgid "Interactive mode"
msgstr ""
@@ -19758,6 +20203,9 @@ msgstr ""
msgid "IssueAnalytics|Assignees"
msgstr "担当者"
+msgid "IssueAnalytics|Created by"
+msgstr ""
+
msgid "IssueAnalytics|Due date"
msgstr "期日"
@@ -19770,9 +20218,6 @@ msgstr ""
msgid "IssueAnalytics|Milestone"
msgstr "マイルストーン"
-msgid "IssueAnalytics|Opened by"
-msgstr ""
-
msgid "IssueAnalytics|Status"
msgstr "ステータス"
@@ -19896,11 +20341,11 @@ msgstr "プロジェクトã®ã‚¤ã‚·ãƒ¥ãƒ¼ã®ä½œæˆã‚’開始ã—ãŸã‚‰ã€ãƒ—ロジ
msgid "IssuesAnalytics|Avg/Month:"
msgstr "月平å‡:"
-msgid "IssuesAnalytics|Issues opened"
-msgstr "オープンã—ãŸã‚¤ã‚·ãƒ¥ãƒ¼"
+msgid "IssuesAnalytics|Issues created"
+msgstr ""
-msgid "IssuesAnalytics|Issues opened per month"
-msgstr "オープンã—ãŸã‚¤ã‚·ãƒ¥ãƒ¼æ•°/月"
+msgid "IssuesAnalytics|Issues created per month"
+msgstr ""
msgid "IssuesAnalytics|Last 12 months"
msgstr "éŽåŽ»12ヶ月間"
@@ -19926,6 +20371,9 @@ msgstr ""
msgid "It looks like you have some draft commits in this branch."
msgstr ""
+msgid "It looks like you're attempting to activate your subscription. Use %{a_start}the Subscription page%{a_end} instead."
+msgstr ""
+
msgid "It may be several days before you see feature usage data."
msgstr ""
@@ -20154,6 +20602,9 @@ msgstr ""
msgid "JiraConnect|You can now close this window and return to Jira."
msgstr ""
+msgid "JiraConnect|You don't have permission to create branches for this project. Select a different project or contact the project owner for access. %{linkStart}Learn more.%{linkEnd}"
+msgstr ""
+
msgid "JiraRequest|A connection error occurred while connecting to Jira. Try your request again."
msgstr ""
@@ -20202,13 +20653,13 @@ msgstr ""
msgid "JiraService|Define the type of Jira issue to create from a vulnerability."
msgstr ""
-msgid "JiraService|Displaying Jira issues while leaving the GitLab issue functionality enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
+msgid "JiraService|Displaying Jira issues while leaving GitLab issues also enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
msgstr ""
-msgid "JiraService|Enable Jira issues"
+msgid "JiraService|Enable Jira issue creation from vulnerabilities"
msgstr ""
-msgid "JiraService|Enable Jira issues creation from vulnerabilities"
+msgid "JiraService|Enable Jira issues"
msgstr ""
msgid "JiraService|Enable Jira transitions"
@@ -20325,16 +20776,19 @@ msgstr ""
msgid "JiraService|View Jira issues in GitLab"
msgstr ""
-msgid "JiraService|Warning: All GitLab users that have access to this GitLab project are able to view all issues from the Jira project specified below."
+msgid "JiraService|Warning: All GitLab users with access to this GitLab project can view all issues from the Jira project you select."
msgstr ""
msgid "JiraService|Web URL"
msgstr "Web URL"
-msgid "JiraService|Work on Jira issues without leaving GitLab. Adds a Jira menu to access your list of Jira issues and view any issue as read-only."
+msgid "JiraService|When a Jira issue is mentioned in a commit or merge request, a remote link and comment (if enabled) will be created."
+msgstr ""
+
+msgid "JiraService|Work on Jira issues without leaving GitLab. Add a Jira menu to access a read-only list of your Jira issues."
msgstr ""
-msgid "JiraService|You need to configure Jira before enabling this integration. For more details, read the %{jira_doc_link_start}Jira integration documentation%{link_end}."
+msgid "JiraService|You must configure Jira before enabling this integration. %{jira_doc_link_start}Learn more.%{link_end}"
msgstr ""
msgid "Job"
@@ -20346,9 +20800,6 @@ msgstr ""
msgid "Job Failed #%{build_id}"
msgstr "#%{build_id} ã®ã‚¸ãƒ§ãƒ–ãŒå¤±æ•—"
-msgid "Job ID"
-msgstr "ジョブ ID"
-
msgid "Job artifact"
msgstr ""
@@ -20415,9 +20866,27 @@ msgstr ""
msgid "Jobs|You're about to retry a job that failed because it attempted to deploy code that is older than the latest deployment. Retrying this job could result in overwriting the environment with the older source code."
msgstr ""
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source} into %{target}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{ref}"
+msgstr ""
+
+msgid "Job|Are you sure you want to erase this job log and artifacts?"
+msgstr ""
+
msgid "Job|Browse"
msgstr "ブラウズ"
+msgid "Job|Cancel"
+msgstr ""
+
msgid "Job|Complete Raw"
msgstr "完全㪠Raw"
@@ -20427,6 +20896,9 @@ msgstr "ダウンロード"
msgid "Job|Erase job log and artifacts"
msgstr ""
+msgid "Job|Finished at"
+msgstr ""
+
msgid "Job|Job artifacts"
msgstr "ジョブã®ã‚¢ãƒ¼ãƒ†ã‚£ãƒ•ã‚¡ã‚¯ãƒˆ"
@@ -20439,8 +20911,8 @@ msgstr ""
msgid "Job|Keep"
msgstr "維æŒ"
-msgid "Job|Pipeline"
-msgstr "パイプライン"
+msgid "Job|Retry"
+msgstr ""
msgid "Job|Scroll to bottom"
msgstr "最下部ã«ã‚¹ã‚¯ãƒ­ãƒ¼ãƒ«"
@@ -20451,6 +20923,9 @@ msgstr "最上部ã«ã‚¹ã‚¯ãƒ­ãƒ¼ãƒ«"
msgid "Job|Show complete raw"
msgstr "完全㪠Raw を表示ã™ã‚‹"
+msgid "Job|Status"
+msgstr ""
+
msgid "Job|The artifacts were removed"
msgstr "アーティファクトã¯å‰Šé™¤ã•ã‚Œã¾ã—ãŸ"
@@ -20478,21 +20953,12 @@ msgstr ""
msgid "Job|delayed"
msgstr ""
-msgid "Job|for"
-msgstr "対象"
-
-msgid "Job|into"
-msgstr "ターゲット:"
-
msgid "Job|manual"
msgstr ""
msgid "Job|triggered"
msgstr ""
-msgid "Job|with"
-msgstr "ソースブランãƒ:"
-
msgid "Join Zoom meeting"
msgstr "Zoom ミーティングã«å‚加ã™ã‚‹"
@@ -20595,9 +21061,6 @@ msgstr ""
msgid "Ki"
msgstr ""
-msgid "Kontra"
-msgstr ""
-
msgid "Kroki"
msgstr ""
@@ -20920,6 +21383,9 @@ msgstr ""
msgid "Learn more about Auto DevOps"
msgstr "Auto DevOps ã®è©³ç´°"
+msgid "Learn more about GitLab"
+msgstr ""
+
msgid "Learn more about Needs relationships"
msgstr ""
@@ -21241,9 +21707,18 @@ msgstr "プロジェクトã«å‰²ã‚Šå½“ã¦ã‚‰ã‚ŒãŸãƒãƒªã‚·ãƒ¼ã«æº–æ‹ ã—ã¦ã„
msgid "Licenses|Displays licenses detected in the project, based on the %{linkStart}latest successful%{linkEnd} scan"
msgstr ""
+msgid "Licenses|Drag your license file here or %{linkStart}click to upload%{linkEnd}."
+msgstr ""
+
+msgid "Licenses|Drop your license file to start the upload."
+msgstr ""
+
msgid "Licenses|Error fetching the license list. Please check your network connection and try again."
msgstr "ライセンスリストãŒå–å¾—ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯æŽ¥ç¶šçŠ¶æ³ã‚’確èªã—ã¦å†è©¦è¡Œã—ã¦ãã ã•ã„。"
+msgid "Licenses|Error: You are trying to upload something other than a file"
+msgstr ""
+
msgid "Licenses|License Compliance"
msgstr "ライセンスコンプライアンス"
@@ -21262,6 +21737,9 @@ msgstr "ãƒãƒªã‚·ãƒ¼é•å:æ‹’å¦"
msgid "Licenses|Specified policies in this project"
msgstr ""
+msgid "Licenses|The file could not be uploaded."
+msgstr ""
+
msgid "Licenses|The license list details information about the licenses used within your project."
msgstr "ライセンスリストã«ã¯ãƒ—ロジェクト内ã§ä½¿ç”¨ã•ã‚Œã¦ã„るライセンスã«é–¢ã™ã‚‹è©³ç´°æƒ…å ±ãŒè¨˜è¼‰ã•ã‚Œã¦ã„ã¾ã™ã€‚"
@@ -21295,10 +21773,6 @@ msgstr ""
msgid "Limit the size of Sidekiq jobs stored in Redis."
msgstr ""
-msgid "Limited to showing %d event at most"
-msgid_plural "Limited to showing %d events at most"
-msgstr[0] "イベント表示数を最大 %d 個ã«åˆ¶é™"
-
msgid "Limiting mode"
msgstr ""
@@ -21308,6 +21782,9 @@ msgstr ""
msgid "Link"
msgstr ""
+msgid "Link (optional)"
+msgstr ""
+
msgid "Link Prometheus monitoring to GitLab."
msgstr ""
@@ -21344,6 +21821,9 @@ msgstr ""
msgid "Linked emails (%{email_count})"
msgstr "リンクã•ã‚ŒãŸãƒ¡ãƒ¼ãƒ« (%{email_count})"
+msgid "Linked epics"
+msgstr ""
+
msgid "Linked issues"
msgstr "リンクã•ã‚ŒãŸã‚¤ã‚·ãƒ¥ãƒ¼"
@@ -21371,6 +21851,15 @@ msgstr "利用å¯èƒ½ãªãƒªãƒã‚¸ãƒˆãƒªã®ä¸€è¦§"
msgid "List of all merge commits"
msgstr ""
+msgid "List of environments for this project"
+msgstr ""
+
+msgid "List of suitable GCP locations"
+msgstr ""
+
+msgid "List of users allowed to exceed the rate limit."
+msgstr ""
+
msgid "List options"
msgstr ""
@@ -21590,6 +22079,9 @@ msgstr ""
msgid "Maintenance mode"
msgstr ""
+msgid "Make adjustments to how your GitLab instance is set up."
+msgstr ""
+
msgid "Make and review changes in the browser with the Web IDE"
msgstr "Web IDEを使用ã—ã¦ãƒ–ラウザ内ã§å¤‰æ›´ã—レビューã™ã‚‹"
@@ -21734,6 +22226,12 @@ msgstr ""
msgid "MarkdownEditor|Add italic text (%{modifier_key}I)"
msgstr ""
+msgid "MarkdownEditor|Add strikethrough text (%{modifierKey}⇧X)"
+msgstr ""
+
+msgid "MarkdownEditor|Add strikethrough text (%{modifier_key}⇧X)"
+msgstr ""
+
msgid "Marked For Deletion At - %{deletion_time}"
msgstr ""
@@ -21995,6 +22493,9 @@ msgstr ""
msgid "Maximum push size (MB)"
msgstr "最大プッシュサイズ (MB)"
+msgid "Maximum requests per 10 minutes per user"
+msgstr ""
+
msgid "Maximum requests per minute"
msgstr ""
@@ -22085,6 +22586,17 @@ msgstr ""
msgid "Members of a group may only view projects they have permission to access"
msgstr ""
+msgid "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seat in use and will be billed for the overage."
+msgid_plural "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seats in use and will be billed for the overage."
+msgstr[0] ""
+
+msgid "MembersOverage|You are about to incur additional charges"
+msgstr ""
+
+msgid "MembersOverage|Your subscription includes %d seat."
+msgid_plural "MembersOverage|Your subscription includes %d seats."
+msgstr[0] ""
+
msgid "Membership"
msgstr ""
@@ -22289,9 +22801,6 @@ msgstr ""
msgid "Merge request not merged"
msgstr ""
-msgid "Merge request pipelines 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 merge request pipelines."
-msgstr ""
-
msgid "Merge request reports"
msgstr ""
@@ -22388,14 +22897,14 @@ msgstr "下書ãコメントã®ä¿å­˜ä¸­ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
msgid "MergeRequests|Create issue to resolve thread"
msgstr ""
-msgid "MergeRequests|Failed to squash. Should be done manually."
-msgstr "スカッシュã«å¤±æ•—ã—ã¾ã—ãŸã€‚手動ã§è¡Œã†å¿…è¦ãŒã‚ã‚Šã¾ã™ã€‚"
-
msgid "MergeRequests|Saving the comment failed"
msgstr "コメントã®ä¿å­˜ã«å¤±æ•—ã—ã¾ã—ãŸ"
-msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
-msgstr "ã“ã®ãƒ—ロジェクトã§ã¯ã€ãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆã‚’å—ã‘付ã‘ãŸã¨ãã«ã‚³ãƒŸãƒƒãƒˆã‚’スカッシュã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。"
+msgid "MergeRequests|Squashing failed: Squash the commits locally, resolve any conflicts, then push the branch."
+msgstr ""
+
+msgid "MergeRequests|Squashing not allowed: This project doesn't allow you to squash commits when merging."
+msgstr ""
msgid "MergeRequests|Thread stays resolved"
msgstr "スレッドã¯è§£æ±ºæ¸ˆã¿ã®ã¾ã¾ã§ã™"
@@ -23233,6 +23742,18 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "MrList|Assigned to %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from assignee %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from reviewer %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Review requested from %{name}, go to their profile."
+msgstr ""
+
msgid "Multi-project"
msgstr ""
@@ -23266,7 +23787,7 @@ msgstr ""
msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "My Awesome Group"
+msgid "My awesome group"
msgstr ""
msgid "My company or team"
@@ -23886,9 +24407,6 @@ msgstr "èªè¨¼æ–¹æ³•ãŒè¨­å®šã•ã‚Œã¦ã„ã¾ã›ã‚“。"
msgid "No available branches"
msgstr ""
-msgid "No available groups to fork the project."
-msgstr ""
-
msgid "No branches found"
msgstr "ブランãƒãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“。"
@@ -24099,6 +24617,9 @@ msgstr "パブリック グループãŒã‚ã‚Šã¾ã›ã‚“"
msgid "No ref selected"
msgstr ""
+msgid "No regions configured"
+msgstr ""
+
msgid "No related merge requests found."
msgstr ""
@@ -24897,6 +25418,9 @@ msgstr ""
msgid "Only reCAPTCHA v2 is supported:"
msgstr ""
+msgid "Only required if not using role instance credentials."
+msgstr ""
+
msgid "Only use lowercase letters, numbers, and underscores."
msgstr ""
@@ -24921,9 +25445,6 @@ msgstr "é¸æŠžæ¸ˆã¿ã®ã‚‚ã®ã‚’é–‹ã"
msgid "Open a CLI and connect to the cluster you want to install the agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
-msgid "Open epics"
-msgstr ""
-
msgid "Open errors"
msgstr "エラーを開ã"
@@ -24963,8 +25484,8 @@ msgstr ""
msgid "Opened issues"
msgstr "オープン中ã®ã‚¤ã‚·ãƒ¥ãƒ¼"
-msgid "OpenedNDaysAgo|Opened"
-msgstr "オープンã•ã‚ŒãŸã®ã¯"
+msgid "OpenedNDaysAgo|Created"
+msgstr ""
msgid "Opens in a new window"
msgstr "æ–°è¦ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã§é–‹ã"
@@ -25008,9 +25529,6 @@ msgstr "オプション"
msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
-msgid "Optional."
-msgstr ""
-
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
msgstr "オプションã¨ã—ã¦ã€ã‚ãªãŸã¯ã€%{link_to_customize} 㧠FogBugz ã®ãƒ¡ãƒ¼ãƒ«ã‚¢ãƒ‰ãƒ¬ã‚¹ã¨ãƒ¦ãƒ¼ã‚¶ãƒ¼åã‚’ GitLab ã«ã‚¤ãƒ³ãƒãƒ¼ãƒˆã§ãã¾ã™ã€‚"
@@ -25798,6 +26316,9 @@ msgstr "Gitalyリクエスト"
msgid "PerformanceBar|Memory"
msgstr ""
+msgid "PerformanceBar|Memory report"
+msgstr ""
+
msgid "PerformanceBar|Redis calls"
msgstr "Redis呼ã³å‡ºã—"
@@ -25831,18 +26352,12 @@ msgstr ""
msgid "PerformanceBar|wall"
msgstr ""
-msgid "Performs a rebase but skips triggering a new pipeline"
-msgstr ""
-
msgid "Period in seconds"
msgstr ""
msgid "Permalink"
msgstr ""
-msgid "Permanently delete project"
-msgstr ""
-
msgid "Permanently remove group"
msgstr ""
@@ -26113,6 +26628,51 @@ msgstr "パイプライン: %{ciStatus}"
msgid "PipelineStatusTooltip|Pipeline: %{ci_status}"
msgstr "パイプライン:%{ci_status}"
+msgid "PipelineWizardDefaultCommitMessage|Add %{filename}"
+msgstr ""
+
+msgid "PipelineWizardDefaultCommitMessage|Update %{filename}"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|At least one entry is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This field is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This value is not valid"
+msgstr ""
+
+msgid "PipelineWizardListWidget|add another step"
+msgstr ""
+
+msgid "PipelineWizardListWidget|remove step"
+msgstr ""
+
+msgid "PipelineWizard|Commit"
+msgstr ""
+
+msgid "PipelineWizard|Commit Message"
+msgstr ""
+
+msgid "PipelineWizard|Commit changes to your file"
+msgstr ""
+
+msgid "PipelineWizard|Commit file to Branch"
+msgstr ""
+
+msgid "PipelineWizard|Commit your new file"
+msgstr ""
+
+msgid "PipelineWizard|The file has been committed."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem committing the changes."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem while checking whether your file already exists in the specified branch."
+msgstr ""
+
msgid "Pipelines"
msgstr "パイプライン"
@@ -26227,7 +26787,7 @@ msgstr ""
msgid "Pipelines|Project cache successfully reset."
msgstr "プロジェクトã®ã‚­ãƒ£ãƒƒã‚·ãƒ¥ã‚’正常ã«ãƒªã‚»ãƒƒãƒˆã—ã¾ã—ãŸã€‚"
-msgid "Pipelines|Revoke"
+msgid "Pipelines|Revoke trigger"
msgstr ""
msgid "Pipelines|Something went wrong while cleaning runners cache."
@@ -26272,6 +26832,12 @@ msgstr ""
msgid "Pipelines|This is a child pipeline within the parent pipeline"
msgstr "ã“ã‚Œã¯è¦ªãƒ‘イプライン内ã«ã‚ã‚‹å­ãƒ‘イプラインã§ã™"
+msgid "Pipelines|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipelines|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipelines|This pipeline will run code originating from a forked project merge request. This means that the code can potentially have security considerations like exposing CI variables."
msgstr ""
@@ -26314,9 +26880,6 @@ msgstr ""
msgid "Pipelines|Your changes have been successfully committed. Now redirecting to the new merge request page."
msgstr ""
-msgid "Pipelines|detached"
-msgstr ""
-
msgid "Pipelines|error"
msgstr ""
@@ -26326,10 +26889,13 @@ msgstr ""
msgid "Pipelines|latest"
msgstr ""
-msgid "Pipelines|stuck"
+msgid "Pipelines|merge request"
+msgstr ""
+
+msgid "Pipelines|merge train"
msgstr ""
-msgid "Pipelines|train"
+msgid "Pipelines|stuck"
msgstr ""
msgid "Pipelines|yaml invalid"
@@ -26461,6 +27027,12 @@ msgstr ""
msgid "Pipeline|This change will not change the overall test coverage if merged."
msgstr ""
+msgid "Pipeline|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipeline|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipeline|Trigger author"
msgstr ""
@@ -26485,6 +27057,12 @@ msgstr ""
msgid "Pipeline|for"
msgstr ""
+msgid "Pipeline|merge request"
+msgstr ""
+
+msgid "Pipeline|merge train"
+msgstr ""
+
msgid "Pipeline|on"
msgstr ""
@@ -26623,9 +27201,6 @@ msgstr "有効ãªæ•°å€¤ã‚’入力ã—ã¦ãã ã•ã„"
msgid "Please enter a valid time interval"
msgstr ""
-msgid "Please enter or upload a valid license."
-msgstr ""
-
msgid "Please enter your current password."
msgstr ""
@@ -26734,9 +27309,6 @@ msgstr ""
msgid "Please type %{phrase_code} to proceed or close this modal to cancel."
msgstr "続行ã™ã‚‹ã«ã¯ %{phrase_code} を入力ã—ã¦ãã ã•ã„。キャンセルã™ã‚‹å ´åˆã¯ã“ã®ãƒ¢ãƒ¼ãƒ€ãƒ«ã‚’é–‰ã˜ã¦ãã ã•ã„。"
-msgid "Please type the following to confirm:"
-msgstr ""
-
msgid "Please use this form to report to the admin users who create spam issues, comments or behave inappropriately."
msgstr "イシューやコメントã¸ã®ã‚¹ãƒ‘ム行為ã€ã¾ãŸä¸é©åˆ‡ãªæŒ™å‹•ã‚’ã™ã‚‹ãƒ¦ãƒ¼ã‚¶ãƒ¼ã«ã¤ã„ã¦ã¯ã€ã“ã¡ã‚‰ã®ãƒ•ã‚©ãƒ¼ãƒ ã‹ã‚‰ç®¡ç†è€…ã«å ±å‘Šã—ã¦ãã ã•ã„。"
@@ -26764,12 +27336,27 @@ msgstr "ドキュメントã€ãƒ“ルドã—ãŸãƒã‚¤ãƒŠãƒªã€ãã®ä»–ã®é–¢é€£è³‡
msgid "Policies"
msgstr ""
+msgid "Policy '%{escalation_policy_name}' does not exist."
+msgstr ""
+
msgid "Policy management project does have any policies in %{policy_path}"
msgstr ""
msgid "Policy project doesn't exist"
msgstr ""
+msgid "PolicyRuleMultiSelect|%{firstLabel} +%{numberOfAdditionalLabels} more"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|All %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select all"
+msgstr ""
+
msgid "Polling interval multiplier"
msgstr ""
@@ -26998,6 +27585,9 @@ msgstr ""
msgid "Private projects can be created in your personal namespace with:"
msgstr "ã‚ãªãŸå€‹äººã®åå‰ç©ºé–“ã«ãƒ—ライベートプロジェクトを作æˆã§ãã¾ã™:"
+msgid "Problem with %{name} command: %{message}."
+msgstr ""
+
msgid "Proceed"
msgstr "続行"
@@ -27472,6 +28062,9 @@ msgstr "ã“ã®ãƒªãƒã‚¸ãƒˆãƒªã§ä½¿ç”¨ã•ã‚Œã¦ã„るプログラミング言語
msgid "Progress"
msgstr "進行状æ³"
+msgid "Progress tracking"
+msgstr ""
+
msgid "Project"
msgstr "プロジェクト"
@@ -27703,6 +28296,9 @@ msgstr ""
msgid "ProjectQualitySummary|Failure"
msgstr ""
+msgid "ProjectQualitySummary|Get insight into the overall percentage of tests in your project that succeed, fail and are skipped."
+msgstr ""
+
msgid "ProjectQualitySummary|Latest pipeline results"
msgstr ""
@@ -27721,6 +28317,12 @@ msgstr ""
msgid "ProjectQualitySummary|See project Code Coverage Statistics"
msgstr ""
+msgid "ProjectQualitySummary|Set up test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|Set up test runs (opens in a new tab)"
+msgstr ""
+
msgid "ProjectQualitySummary|Skipped"
msgstr ""
@@ -27997,13 +28599,19 @@ msgstr "イシュー"
msgid "ProjectSettings|LFS objects from this repository are available to forks. %{linkStart}How do I remove them?%{linkEnd}"
msgstr ""
+msgid "ProjectSettings|Learn about commit history."
+msgstr ""
+
+msgid "ProjectSettings|Leave empty to use default template."
+msgstr ""
+
msgid "ProjectSettings|Manage who can see the project in the public access directory."
msgstr ""
msgid "ProjectSettings|Manages large files such as audio, video, and graphics files."
msgstr ""
-msgid "ProjectSettings|Maximum 500 characters."
+msgid "ProjectSettings|Maximum %{maxLength} characters."
msgstr ""
msgid "ProjectSettings|Merge checks"
@@ -28144,6 +28752,9 @@ msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
msgstr ""
+msgid "ProjectSettings|The default template will be applied on save."
+msgstr ""
+
msgid "ProjectSettings|These checks must pass before merge requests can be merged."
msgstr ""
@@ -28198,6 +28809,9 @@ msgstr ""
msgid "ProjectSettings|What are badges?"
msgstr ""
+msgid "ProjectSettings|What are merge trains?"
+msgstr ""
+
msgid "ProjectSettings|When merge request pipelines are enabled in the CI/CD configuration file, pipelines validate the combined results of the source and target branches. %{link_start}How to configure merge request pipelines?%{link_end}"
msgstr ""
@@ -28315,6 +28929,9 @@ msgstr "プロジェクトã¯ã€å­˜åœ¨ã™ã‚‹æœ€ã‚‚é‡è¦åº¦ã®é«˜ã„脆弱性ã«
msgid "Projects are organized into groups"
msgstr ""
+msgid "Projects are where you store your code, access issues, wiki and other features of GitLab."
+msgstr ""
+
msgid "Projects contributed to"
msgstr ""
@@ -28330,12 +28947,6 @@ msgstr ""
msgid "Projects to index"
msgstr "インデックスを作æˆã™ã‚‹ãƒ—ロジェクト"
-msgid "Projects will be permanently deleted after a %{waiting_period}-day waiting period."
-msgstr ""
-
-msgid "Projects will be permanently deleted immediately."
-msgstr ""
-
msgid "Projects with critical vulnerabilities"
msgstr "致命的ãªè„†å¼±æ€§ã®ã‚るプロジェクト"
@@ -28420,6 +29031,9 @@ msgstr "インãƒãƒ¼ãƒˆ"
msgid "ProjectsNew|Import project"
msgstr "プロジェクトã®ã‚¤ãƒ³ãƒãƒ¼ãƒˆ"
+msgid "ProjectsNew|Include a Getting Started README"
+msgstr ""
+
msgid "ProjectsNew|Initialize repository with a README"
msgstr "リãƒã‚¸ãƒˆãƒªã‚’åˆæœŸåŒ–ã—READMEファイルを生æˆã™ã‚‹"
@@ -28435,6 +29049,9 @@ msgstr ""
msgid "ProjectsNew|Project description %{tag_start}(optional)%{tag_end}"
msgstr "プロジェクトã®èª¬æ˜Ž%{tag_start}(オプション)%{tag_end}"
+msgid "ProjectsNew|Recommended if you're new to GitLab"
+msgstr ""
+
msgid "ProjectsNew|Run CI/CD for external repository"
msgstr ""
@@ -28852,6 +29469,9 @@ msgstr "コード所有者ã®æ‰¿èªã®åˆ‡ã‚Šæ›¿ãˆ"
msgid "ProtectedBranch|Unprotect"
msgstr ""
+msgid "ProtectedBranch|Unprotect branch"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
@@ -28879,6 +29499,9 @@ msgstr "環境をä¿è­·"
msgid "ProtectedEnvironment|Protected Environment (%{protected_environments_count})"
msgstr "ä¿è­·ç’°å¢ƒ (%{protected_environments_count})"
+msgid "ProtectedEnvironment|Required approvals"
+msgstr ""
+
msgid "ProtectedEnvironment|Select an environment"
msgstr "環境をé¸æŠž"
@@ -28900,10 +29523,13 @@ msgstr "ã‚ãªãŸã®ç’°å¢ƒã¯ä¿è­·ã•ã‚Œã¦ã„ã¾ã™ã€‚"
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr "ã‚ãªãŸã®ç’°å¢ƒã¯ä¿è­·ã•ã‚Œã¦ã„ã¾ã›ã‚“。ã¾ãŸã¯ä¿è­·ãŒè§£é™¤ã•ã‚Œã¦ã„ã¾ã™ã€‚"
+msgid "ProtectedTags|Unprotect tag"
+msgstr ""
+
msgid "ProtectedTags|default"
msgstr ""
-msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
+msgid "ProtectedTag|By default, protected tags restrict who can modify the tag."
msgstr ""
msgid "ProtectedTag|Learn more."
@@ -28966,6 +29592,9 @@ msgstr "公開パイプライン"
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Public projects are an easy way to allow everyone to have read-only access."
+msgstr ""
+
msgid "Publish to status page"
msgstr ""
@@ -29122,9 +29751,6 @@ msgstr "ç·ã‚³ãƒŸãƒƒãƒˆæ•°ï¼š %{total_commits_count}"
msgid "QualitySummary|Project quality"
msgstr ""
-msgid "Quarters"
-msgstr "クォーター"
-
msgid "Query"
msgstr "クエリ"
@@ -29209,6 +29835,9 @@ msgstr ""
msgid "Read more about project permissions %{help_link_open}here%{help_link_close}"
msgstr ""
+msgid "Read more about related epics"
+msgstr ""
+
msgid "Read more about related issues"
msgstr "関連ã™ã‚‹ã‚¤ã‚·ãƒ¥ãƒ¼ã«ã¤ã„ã¦ã‚‚ã£ã¨èª­ã‚€"
@@ -29239,10 +29868,7 @@ msgstr ""
msgid "Rebase source branch on the target branch."
msgstr ""
-msgid "Rebase without CI"
-msgstr ""
-
-msgid "Rebases and triggers a pipeline"
+msgid "Rebase without pipeline"
msgstr ""
msgid "Recaptcha verified?"
@@ -29293,9 +29919,6 @@ msgstr ""
msgid "Reconfigure"
msgstr ""
-msgid "Recovering projects"
-msgstr ""
-
msgid "Recovery Codes"
msgstr "リカãƒãƒªãƒ¼ã‚³ãƒ¼ãƒ‰"
@@ -29354,6 +29977,12 @@ msgstr "インスタンスIDã‚’å†ç”Ÿæˆã™ã‚‹ã¨ã€ä½¿ç”¨ã—ã¦ã„るクライã
msgid "Regex pattern"
msgstr "æ­£è¦è¡¨ç¾ãƒ‘ターン"
+msgid "Region"
+msgstr ""
+
+msgid "Regions"
+msgstr ""
+
msgid "Register"
msgstr "登録"
@@ -29583,9 +30212,6 @@ msgstr "ã™ã¹ã¦ã®ãƒ©ãƒ™ãƒ«ã¾ãŸã¯ç‰¹å®šã®ãƒ©ãƒ™ãƒ«ã‚’削除ã™ã‚‹"
msgid "Remove all or specific reviewer(s)"
msgstr "ã™ã¹ã¦ã®ã€ã¾ãŸã¯ç‰¹å®šã®ãƒ¬ãƒ“ュアーを削除"
-msgid "Remove approver"
-msgstr ""
-
msgid "Remove approvers"
msgstr "承èªè€…を削除"
@@ -29601,6 +30227,9 @@ msgstr "担当者ã®å‰Šé™¤"
msgid "Remove attention request"
msgstr ""
+msgid "Remove attention request(s)"
+msgstr ""
+
msgid "Remove avatar"
msgstr "ã‚¢ãƒã‚¿ãƒ¼ã‚’削除"
@@ -29739,6 +30368,9 @@ msgstr "ã™ã¹ã¦ã®ãƒ©ãƒ™ãƒ«ã‚’削除済ã¿"
msgid "Removed an issue from an epic."
msgstr "イシューをエピックã‹ã‚‰å‰Šé™¤ã—ã¾ã—ãŸã€‚"
+msgid "Removed attention from %{users_sentence}."
+msgstr ""
+
msgid "Removed attention request from @%{username}"
msgstr ""
@@ -29790,6 +30422,9 @@ msgstr "ã™ã¹ã¦ã®ãƒ©ãƒ™ãƒ«ã‚’削除"
msgid "Removes an issue from an epic."
msgstr "エピックã‹ã‚‰ã‚¤ã‚·ãƒ¥ãƒ¼ã‚’削除"
+msgid "Removes attention from %{users_sentence}."
+msgstr ""
+
msgid "Removes parent epic %{epic_ref}."
msgstr "親エピック %{epic_ref} を削除ã—ã¾ã™ã€‚"
@@ -29901,6 +30536,9 @@ msgstr "ä¸æ­£åˆ©ç”¨ã‚’報告"
msgid "Report abuse to admin"
msgstr "管ç†è€…ã«ä¸æ­£åˆ©ç”¨ã‚’報告"
+msgid "Report is generating and will be sent to your email address."
+msgstr ""
+
msgid "Reported %{timeAgo} by %{reportedBy}"
msgstr "%{timeAgo} ã« %{reportedBy} ã«ã‚ˆã‚Šå ±å‘Š"
@@ -30185,6 +30823,15 @@ msgstr ""
msgid "Request attention"
msgstr ""
+msgid "Request attention from %{users_sentence}."
+msgstr ""
+
+msgid "Request attention from assignee or reviewer"
+msgstr ""
+
+msgid "Request attention from assignee(s) or reviewer(s)"
+msgstr ""
+
msgid "Request attention to review"
msgstr ""
@@ -30209,6 +30856,9 @@ msgstr ""
msgid "Requested %{time_ago}"
msgstr "%{time_ago} ã«ãƒªã‚¯ã‚¨ã‚¹ãƒˆ"
+msgid "Requested attention from %{users_sentence}."
+msgstr ""
+
msgid "Requested attention from @%{username}"
msgstr ""
@@ -30421,6 +31071,9 @@ msgstr "グループをレストア"
msgid "Restore project"
msgstr "プロジェクトを復元ã™ã‚‹"
+msgid "Restoring projects"
+msgstr ""
+
msgid "Restoring the group will prevent the group, its subgroups and projects from being removed on this date."
msgstr "グループを復元ã™ã‚‹ã¨ã€ã‚°ãƒ«ãƒ¼ãƒ—ã€ãã®ã‚µãƒ–グループã¨ãƒ—ロジェクトã¯ã“ã®æ—¥ã«ã¯å‰Šé™¤ã•ã‚Œãªããªã‚Šã¾ã™ã€‚"
@@ -30451,6 +31104,9 @@ msgstr ""
msgid "Retry"
msgstr "å†è©¦è¡Œ"
+msgid "Retry failed jobs"
+msgstr ""
+
msgid "Retry job"
msgstr ""
@@ -30497,9 +31153,6 @@ msgstr "最新ã®ã‚¢ãƒ—リを表示"
msgid "Review changes"
msgstr ""
-msgid "Review requested from %{name}"
-msgstr ""
-
msgid "Review requests for you"
msgstr ""
@@ -30663,6 +31316,9 @@ msgstr ""
msgid "Runners|Assigned Group"
msgstr ""
+msgid "Runners|Assigned Projects (%{projectCount})"
+msgstr ""
+
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30732,6 +31388,9 @@ msgstr ""
msgid "Runners|Instance"
msgstr ""
+msgid "Runners|Jobs"
+msgstr ""
+
msgid "Runners|Last contact"
msgstr ""
@@ -30825,9 +31484,6 @@ msgstr ""
msgid "Runners|Runner %{name} was deleted"
msgstr ""
-msgid "Runners|Runner ID"
-msgstr ""
-
msgid "Runners|Runner assigned to project."
msgstr ""
@@ -30975,6 +31631,9 @@ msgstr ""
msgid "Runners|stale"
msgstr ""
+msgid "Runner|This runner has not run any jobs."
+msgstr ""
+
msgid "Running"
msgstr "稼åƒä¸­"
@@ -31089,6 +31748,24 @@ msgstr "ä¿å­˜ä¸­"
msgid "Saving project."
msgstr "プロジェクトをä¿å­˜"
+msgid "ScanResultPolicy|%{ifLabelStart}if%{ifLabelEnd} %{scanners} scan in an open merge request targeting the %{branches} branch(es) finds %{vulnerabilitiesAllowed} or more %{severities} vulnerabilities that are %{vulnerabilityStates}"
+msgstr ""
+
+msgid "ScanResultPolicy|%{thenLabelStart}Then%{thenLabelEnd} Require approval from %{approvalsRequired} of the following approvers: %{approvers}"
+msgstr ""
+
+msgid "ScanResultPolicy|add an approver"
+msgstr ""
+
+msgid "ScanResultPolicy|scanners"
+msgstr ""
+
+msgid "ScanResultPolicy|severity levels"
+msgstr ""
+
+msgid "ScanResultPolicy|vulnerability states"
+msgstr ""
+
msgid "Scanner"
msgstr ""
@@ -31221,6 +31898,9 @@ msgstr "グループを検索"
msgid "Search for a user"
msgstr "ユーザーを検索"
+msgid "Search for an emoji"
+msgstr ""
+
msgid "Search for projects, issues, etc."
msgstr "プロジェクトやイシューãªã©ã‚’検索ã™ã‚‹ã€‚"
@@ -31397,18 +32077,12 @@ msgstr "秘密"
msgid "Secret Detection"
msgstr ""
-msgid "Secret access key"
-msgstr ""
-
msgid "Secret token"
msgstr ""
msgid "Secure token that identifies an external storage request."
msgstr ""
-msgid "SecureCodeWarrior"
-msgstr ""
-
msgid "Security"
msgstr "セキュリティ"
@@ -31433,9 +32107,6 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "Security training with guide and learning pathways."
-msgstr ""
-
msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
@@ -31538,7 +32209,7 @@ msgstr ""
msgid "SecurityConfiguration|Manage corpus"
msgstr ""
-msgid "SecurityConfiguration|Manage corpus files used as mutation sources in coverage fuzzing."
+msgid "SecurityConfiguration|Manage corpus files used as seed inputs with coverage-guided fuzzing."
msgstr ""
msgid "SecurityConfiguration|Manage profiles for use by DAST scans."
@@ -31604,15 +32275,15 @@ msgstr ""
msgid "SecurityOrchestration|.yaml preview"
msgstr ""
-msgid "SecurityOrchestration|Action"
-msgstr ""
-
msgid "SecurityOrchestration|Actions"
msgstr ""
msgid "SecurityOrchestration|Add rule"
msgstr ""
+msgid "SecurityOrchestration|After dismissing the alert, the information will never be shown again."
+msgstr ""
+
msgid "SecurityOrchestration|All policies"
msgstr ""
@@ -31628,7 +32299,7 @@ msgstr ""
msgid "SecurityOrchestration|Description"
msgstr ""
-msgid "SecurityOrchestration|Disabled"
+msgid "SecurityOrchestration|Don't show the alert anymore"
msgstr ""
msgid "SecurityOrchestration|Edit policy"
@@ -31637,13 +32308,13 @@ msgstr ""
msgid "SecurityOrchestration|Edit policy project"
msgstr ""
-msgid "SecurityOrchestration|Enabled"
+msgid "SecurityOrchestration|Empty policy name"
msgstr ""
-msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Enabled"
msgstr ""
-msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
msgstr ""
msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
@@ -31652,7 +32323,7 @@ msgstr ""
msgid "SecurityOrchestration|Invalid policy type"
msgstr ""
-msgid "SecurityOrchestration|Latest scan"
+msgid "SecurityOrchestration|Latest scan run against %{agent}"
msgstr ""
msgid "SecurityOrchestration|Network"
@@ -31661,15 +32332,27 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No actions defined - policy will not run."
+msgstr ""
+
+msgid "SecurityOrchestration|No description"
+msgstr ""
+
msgid "SecurityOrchestration|No rules defined - policy will not run."
msgstr ""
+msgid "SecurityOrchestration|Not enabled"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
msgid "SecurityOrchestration|Policies"
msgstr ""
+msgid "SecurityOrchestration|Policy Type"
+msgstr ""
+
msgid "SecurityOrchestration|Policy cannot be enabled for non-existing branches (%{branches})"
msgstr ""
@@ -31694,10 +32377,13 @@ msgstr ""
msgid "SecurityOrchestration|Require %{approvals} %{plural} from %{approvers} if any of the following occur:"
msgstr ""
-msgid "SecurityOrchestration|Rule"
+msgid "SecurityOrchestration|Rules"
msgstr ""
-msgid "SecurityOrchestration|Rules"
+msgid "SecurityOrchestration|Runs %{actions} and %{lastAction} scans"
+msgstr ""
+
+msgid "SecurityOrchestration|Runs a %{action} scan"
msgstr ""
msgid "SecurityOrchestration|Scan Execution"
@@ -31757,6 +32443,9 @@ msgstr ""
msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
+msgid "SecurityOrchestration|This view only shows scan results for the agent %{agent}. You can view scan results for all agents in the %{linkStart}Operational Vulnerabilities tab of the vulnerability report%{linkEnd}."
+msgstr ""
+
msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
@@ -31811,9 +32500,6 @@ msgstr ""
msgid "SecurityOrchestration|users with ids"
msgstr ""
-msgid "SecurityOrchestration|view results"
-msgstr ""
-
msgid "SecurityOrchestration|vulnerabilities"
msgstr ""
@@ -32483,22 +33169,19 @@ msgstr "URLをコピー"
msgid "Serverless|Getting started with serverless"
msgstr "Serverless を始ã‚よã†"
-msgid "Serverless|Help shape the future of Serverless at GitLab"
-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 "上記ã®ã©ã‚Œã‚‚当ã¦ã¯ã¾ã‚‰ãªã„ã¨æ€ã‚れる場åˆã¯ã€functionデータãŒä½¿ç”¨å¯èƒ½ã«ãªã‚‹éŽç¨‹ã«å•é¡ŒãŒã‚ã‚‹å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™ã€‚ã‚ã¨ã§ã‚‚ã†ä¸€åº¦ç¢ºèªã—ã¦ãã ã•ã„。"
-msgid "Serverless|In order to start using functions as a service, you must first install Knative on your Kubernetes cluster. %{linkStart}More information%{linkEnd}"
-msgstr ""
-
msgid "Serverless|Learn more about Serverless"
msgstr "Serverless ã«ã¤ã„ã¦"
msgid "Serverless|No functions available"
msgstr "利用å¯èƒ½ãªfunctionã¯ã‚ã‚Šã¾ã›ã‚“"
-msgid "Serverless|Sign up for First Look"
+msgid "Serverless|Serverless was %{linkStart}deprecated%{linkEnd} in GitLab 14.3."
+msgstr ""
+
+msgid "Serverless|Serverless was %{postLinkStart}deprecated%{postLinkEnd}. But if you opt to use it, you must install Knative in your Kubernetes cluster first. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "Serverless|The deploy job has not finished."
@@ -32510,9 +33193,6 @@ 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 ã‹ã‚‰å…¥æ‰‹å¯èƒ½ãªfunctionデータã¯ã‚ã‚Šã¾ã›ã‚“。ã“ã‚Œã¯ã„ãã¤ã‹ç†ç”±ãŒè€ƒãˆã‚‰ã‚Œã¾ã™:"
-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 "%{startTag}.gitlab-ci.yml%{endTag} ファイルãŒé©åˆ‡ã«è¨­å®šã•ã‚Œã¦ã„ã¾ã›ã‚“。"
@@ -32528,9 +33208,6 @@ msgstr ""
msgid "Service Account Key"
msgstr ""
-msgid "Service Accounts"
-msgstr ""
-
msgid "Service Accounts keys authorize GitLab to deploy your Google Cloud project"
msgstr ""
@@ -32540,10 +33217,10 @@ msgstr "サービスデスク"
msgid "Service Desk allows people to create issues in your GitLab instance without their own user account. It provides a unique email address for end users to create issues in a project. Replies can be sent either through the GitLab interface or by email. End users only see threads through email."
msgstr ""
-msgid "Service Usage Data"
+msgid "Service account generated successfully"
msgstr ""
-msgid "Service account generated successfully"
+msgid "Service accounts"
msgstr ""
msgid "Service ping is disabled in your configuration file, and cannot be enabled through this form."
@@ -32687,6 +33364,9 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr "マイルストーンを %{milestone_reference} ã«è¨­å®šã€‚"
+msgid "Set the per-user rate limit for getting a user by ID via the API."
+msgstr ""
+
msgid "Set the per-user rate limit for notes created by web or API requests."
msgstr ""
@@ -32865,6 +33545,9 @@ msgstr ""
msgid "Shared runners details"
msgstr ""
+msgid "Shared runners enabled cannot be enabled until a valid credit card is on file"
+msgstr ""
+
msgid "Shared runners help link"
msgstr "共有Runnerã®ãƒ˜ãƒ«ãƒ—リンク"
@@ -32922,6 +33605,9 @@ msgstr ""
msgid "Show all issues."
msgstr ""
+msgid "Show all milestones"
+msgstr ""
+
msgid "Show all test cases."
msgstr ""
@@ -32958,6 +33644,9 @@ msgstr "ファイルブラウザを表示"
msgid "Show file contents"
msgstr ""
+msgid "Show group milestones"
+msgstr ""
+
msgid "Show labels"
msgstr ""
@@ -32973,6 +33662,12 @@ msgstr ""
msgid "Show open epics"
msgstr ""
+msgid "Show project milestones"
+msgstr ""
+
+msgid "Show sub-group milestones"
+msgstr ""
+
msgid "Show the Closed list"
msgstr ""
@@ -32982,10 +33677,6 @@ msgstr ""
msgid "Show whitespace changes"
msgstr "空白 (éžè¡¨ç¤ºæ–‡å­—) ã®å¤‰æ›´ã‚’表示ã™ã‚‹"
-msgid "Showing %d event"
-msgid_plural "Showing %d events"
-msgstr[0] "%d ã®ã‚¤ãƒ™ãƒ³ãƒˆã‚’表示中"
-
msgid "Showing %{conflict} between %{sourceBranch} and %{targetBranch}"
msgstr ""
@@ -33044,12 +33735,6 @@ msgstr ""
msgid "Sidebar|None"
msgstr "ãªã—"
-msgid "Sidebar|Only numeral characters allowed"
-msgstr "æ•°å­—ã®ã¿ä½¿ç”¨ã§ãã¾ã™"
-
-msgid "Sidebar|Weight"
-msgstr "ウェイト"
-
msgid "Sidekiq job compression threshold (bytes)"
msgstr ""
@@ -33212,6 +33897,9 @@ msgstr "Slackçµ±åˆã§ã¯ã€Slackã®ãƒãƒ£ãƒƒãƒˆã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã‹ã‚‰ slash コã
msgid "Slack logo"
msgstr ""
+msgid "SlackIntegration|Are you sure you want to remove this project from the Slack application?"
+msgstr ""
+
msgid "SlackIntegration|GitLab for Slack"
msgstr ""
@@ -33221,6 +33909,9 @@ msgstr ""
msgid "SlackIntegration|Project alias"
msgstr ""
+msgid "SlackIntegration|Remove project"
+msgstr ""
+
msgid "SlackIntegration|Select a GitLab project to link with your Slack workspace."
msgstr ""
@@ -33365,9 +34056,6 @@ msgstr "%{issuableDisplayName} をロック状態ã«ã™ã‚‹ã®ã«å¤±æ•—ã—ã¾ã—ã
msgid "Something went wrong trying to load issue contacts."
msgstr ""
-msgid "Something went wrong when creating a work item. Please try again"
-msgstr ""
-
msgid "Something went wrong when reordering designs. Please try again"
msgstr ""
@@ -33461,9 +34149,6 @@ msgstr "OpenAPI ビューアã®åˆæœŸåŒ–中ã«å•é¡ŒãŒç™ºç”Ÿã—ã¾ã—ãŸ"
msgid "Something went wrong while inserting your image. Please try again."
msgstr ""
-msgid "Something went wrong while merging this merge request. Please try again."
-msgstr "ã“ã®ãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆã®ãƒžãƒ¼ã‚¸ä¸­ã«å•é¡ŒãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚ã‚‚ã†ä¸€åº¦ã‚„ã‚Šç›´ã—ã¦ãã ã•ã„。"
-
msgid "Something went wrong while obtaining the Let's Encrypt certificate."
msgstr "Let's Encrypt ã®è¨¼æ˜Žæ›¸ã‚’å–å¾—ã™ã‚‹éš›ã«å•é¡ŒãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚"
@@ -33785,11 +34470,11 @@ 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 "GitLab インスタンスã®ã‚³ãƒ¼ãƒ‰ãƒ“ューã¨ãƒžãƒ¼ã‚¸ãƒªã‚¯ã‚¨ã‚¹ãƒˆã§ %{link_start}Sourcegraph%{link_end} ã®ã‚³ãƒ¼ãƒ‰ã‚¤ãƒ³ãƒ†ãƒªã‚¸ã‚§ãƒ³ã‚¹ã‚’有効ã«ã—ã¾ã™ã€‚"
-msgid "SourcegraphAdmin|If checked, only public projects will have code intelligence and communicate with Sourcegraph."
-msgstr "ãƒã‚§ãƒƒã‚¯ã—ãŸå ´åˆã€å…¬é–‹ãƒ—ロジェクトã ã‘ãŒã‚³ãƒ¼ãƒ‰ã‚¤ãƒ³ãƒ†ãƒªã‚¸ã‚§ãƒ³ã‚¹ã‚’使用ã§ãã€Sourcegraph ã¨é€šä¿¡ã§ãã¾ã™ã€‚"
+msgid "SourcegraphAdmin|Learn more."
+msgstr ""
-msgid "SourcegraphAdmin|More information"
-msgstr "詳細情報"
+msgid "SourcegraphAdmin|Only public projects have code intelligence enabled and communicate with Sourcegraph."
+msgstr ""
msgid "SourcegraphAdmin|Save changes"
msgstr "変更をä¿å­˜"
@@ -33797,8 +34482,8 @@ msgstr "変更をä¿å­˜"
msgid "SourcegraphAdmin|Sourcegraph URL"
msgstr "Sourcegraph URL"
-msgid "SourcegraphAdmin|e.g. https://sourcegraph.example.com"
-msgstr "例: https://sourcegraph.example.com"
+msgid "SourcegraphAdmin|https://sourcegraph.example.com"
+msgstr ""
msgid "SourcegraphPreferences|This feature is experimental and currently limited to certain projects."
msgstr "ã“ã®æ©Ÿèƒ½ã¯å®Ÿé¨“çš„ã§ã‚ã‚Šã€ç¾åœ¨ã¯ç‰¹å®šã®ãƒ—ロジェクトã®ã¿ã«é™å®šã•ã‚Œã¦ã„ã¾ã™ã€‚"
@@ -33932,6 +34617,9 @@ msgstr "クリーンアップ開始"
msgid "Start date"
msgstr "開始日"
+msgid "Start free trial"
+msgstr ""
+
msgid "Start merge train"
msgstr "マージトレインを開始"
@@ -33962,6 +34650,9 @@ msgstr "%{startsIn} を開始ã—ã¾ã—ãŸ"
msgid "Started asynchronous removal of all repository check states."
msgstr "ã™ã¹ã¦ã®ãƒªãƒã‚¸ãƒˆãƒªãƒã‚§ãƒƒã‚¯çŠ¶æ…‹ã®éžåŒæœŸå‰Šé™¤ã‚’開始ã—ã¾ã—ãŸã€‚"
+msgid "Started escalation for this incident."
+msgstr ""
+
msgid "Starting..."
msgstr "開始中..."
@@ -33974,6 +34665,9 @@ msgstr "%{startsIn} を開始ã—ã¾ã™"
msgid "Starts at (UTC)"
msgstr "開始時刻 (UTC)"
+msgid "Starts escalations for this incident"
+msgstr ""
+
msgid "Starts on"
msgstr ""
@@ -34235,6 +34929,9 @@ msgstr "ä¸æ˜Ž"
msgid "Strikethrough"
msgstr ""
+msgid "Strikethrough text"
+msgstr ""
+
msgid "Subgroup information"
msgstr ""
@@ -34469,6 +35166,21 @@ msgstr "使用数ã®ã‚«ã‚¦ãƒ³ãƒˆã¯1æ—¥1回ã€åˆå¾Œ12:00ã«å®Ÿè¡Œã•ã‚Œã¾ã™ã€
msgid "Subscriptions"
msgstr "サブスクリプション"
+msgid "Subscriptions|Chat with sales"
+msgstr ""
+
+msgid "Subscriptions|Close"
+msgstr ""
+
+msgid "Subscriptions|Not ready to buy yet?"
+msgstr ""
+
+msgid "Subscriptions|Start a free trial"
+msgstr ""
+
+msgid "Subscriptions|We understand. Maybe you have some questions for our sales team, or maybe you'd like to try some of the paid features first. What would you like to do?"
+msgstr ""
+
msgid "Subscription|Your subscription for %{strong}%{namespace_name}%{strong_close} has expired and you are now on %{pricing_link_start}the GitLab Free tier%{pricing_link_end}. Don't worry, your data is safe. Get in touch with our support team (%{support_email}). They'll gladly help with your subscription renewal."
msgstr ""
@@ -34679,6 +35391,9 @@ msgstr ""
msgid "SuperSonics|Maximum users"
msgstr ""
+msgid "SuperSonics|Offline cloud"
+msgstr ""
+
msgid "SuperSonics|Paste your activation code"
msgstr ""
@@ -34745,6 +35460,12 @@ msgstr ""
msgid "SuperSonics|You do not have an active subscription"
msgstr ""
+msgid "SuperSonics|You have a future dated license"
+msgstr ""
+
+msgid "SuperSonics|You have added a license that activates on %{date}. Please see the subscription history table below for more details."
+msgstr ""
+
msgid "SuperSonics|You have successfully added a license that activates on %{date}. Please see the subscription history table below for more details."
msgstr ""
@@ -34904,6 +35625,9 @@ msgstr "ã‚¿ã‚°å"
msgid "Tag name is required"
msgstr ""
+msgid "Tag push"
+msgstr ""
+
msgid "Tag push events"
msgstr ""
@@ -35006,6 +35730,9 @@ msgstr "リリースノートを書ãã‹ã€ã“ã“ã«ãƒ•ã‚¡ã‚¤ãƒ«ã‚’ドラッグ
msgid "TagsPage|protected"
msgstr "ä¿è­·"
+msgid "Take a look at the documentation to discover all of GitLab’s capabilities."
+msgstr ""
+
msgid "Target Branch"
msgstr "ターゲットブランãƒ"
@@ -35402,6 +36129,9 @@ msgstr ""
msgid "Tests"
msgstr "テスト"
+msgid "Text (optional)"
+msgstr ""
+
msgid "Text added to the body of all email messages. %{character_limit} character limit"
msgstr ""
@@ -35451,6 +36181,9 @@ msgstr ""
msgid "The CSV export will be created in the background. Once finished, it will be sent to %{email} in an attachment."
msgstr ""
+msgid "The CSV export you requested of all user memberships is attached to this email."
+msgstr ""
+
msgid "The GitLab subscription service (customers.gitlab.com) is currently experiencing an outage. You can monitor the status and get updates at %{linkStart}status.gitlab.com%{linkEnd}."
msgstr ""
@@ -35526,6 +36259,9 @@ msgstr "ã“ã®ãƒšãƒ¼ã‚¸ã¯UTF-8ã§ã‚¨ãƒ³ã‚³ãƒ¼ãƒ‰ã•ã‚Œã¦ã„ã¾ã›ã‚“。編集ã
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 epic"
+msgstr ""
+
msgid "The current issue"
msgstr "ç¾åœ¨ã®ã‚¤ã‚·ãƒ¥ãƒ¼"
@@ -35686,6 +36422,9 @@ msgstr ""
msgid "The latest pipeline for this merge request has failed."
msgstr ""
+msgid "The license key is invalid."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -35701,6 +36440,9 @@ msgstr "ライセンスã¯æ­£å¸¸ã«ã‚¢ãƒƒãƒ—ロードã•ã‚Œã€ã‚¢ã‚¯ãƒ†ã‚£ãƒ–ã«
msgid "The license was successfully uploaded and will be active from %{starts_at}. You can see the details below."
msgstr ""
+msgid "The license you uploaded is invalid. If the issue persists, contact support at %{link}."
+msgstr ""
+
msgid "The list creation wizard is already open"
msgstr ""
@@ -36322,10 +37064,13 @@ msgstr "ã“ã®å‹•ä½œã«ã‚ˆã£ã¦ãƒ‡ãƒ¼ã‚¿ãŒå¤±ã‚れるå¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} and everything this project contains. %{strongOpen}There is no going back%{strongClose}"
+msgstr ""
+
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains."
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}on %{date}%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains. %{strongOpen}There is no going back.%{strongClose}"
msgstr ""
msgid "This action will %{strongOpen}permanently remove%{strongClose} %{codeOpen}%{group}%{codeClose} %{strongOpen}immediately%{strongClose}."
@@ -36454,9 +37199,6 @@ msgstr "ã“ã®ãƒ•ã‚£ãƒ¼ãƒ«ãƒ‰ã¯å¿…é ˆã§ã™ã€‚"
msgid "This file was modified for readability, and can't accept suggestions. Edit it directly."
msgstr ""
-msgid "This forked project has the following:"
-msgstr ""
-
msgid "This form is disabled in preview"
msgstr ""
@@ -36469,7 +37211,7 @@ msgstr ""
msgid "This group can't be removed because it is linked to a subscription. To remove this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
-msgid "This group can't be transfered because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
+msgid "This group can't be transferred because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
msgid "This group cannot be invited to a project inside a group with enforced SSO"
@@ -36496,6 +37238,9 @@ 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 incident is already escalated with '%{escalation_policy_name}'."
+msgstr ""
+
msgid "This invitation was sent to %{mail_to_invite_email}, but you are signed in as %{link_to_current_user} with email %{mail_to_current_user}."
msgstr ""
@@ -36514,9 +37259,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 merge train pipeline"
-msgstr ""
-
msgid "This is a private email address %{helpIcon} generated just for you. Anyone who has it can create issues or merge requests as if they were you. If that happens, %{resetLinkStart}reset this token%{resetLinkEnd}."
msgstr ""
@@ -36538,6 +37280,12 @@ msgstr ""
msgid "This is your current session"
msgstr "ã“ã‚Œã¯ã‚ãªãŸã®ç¾åœ¨ã®ã‚»ãƒƒã‚·ãƒ§ãƒ³ã§ã™"
+msgid "This issue cannot be assigned to a confidential epic because it is public."
+msgstr ""
+
+msgid "This issue cannot be made public because it belongs to a confidential epic."
+msgstr ""
+
msgid "This issue is confidential and should only be visible to team members with at least Reporter access."
msgstr ""
@@ -36655,6 +37403,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 branch is protected from force push."
+msgstr ""
+
msgid "This merge request cannot be rebased while there are conflicts."
msgstr ""
@@ -36706,9 +37457,15 @@ msgstr "ã“ã®ãƒ‘イプラインã¯ã€ %{strongStart}Auto DevOps%{strongEnd}ã«ã
msgid "This pipeline was triggered by a schedule."
msgstr ""
+msgid "This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project"
msgstr "プロジェクト"
+msgid "This project can be restored until %{date}."
+msgstr ""
+
msgid "This project cannot be %{visibilityLevel} because the visibility of %{openShowLink}%{name}%{closeShowLink} is %{visibility}. To make this project %{visibilityLevel}, you must first %{openEditLink}change the visibility%{closeEditLink} of the parent group."
msgstr ""
@@ -36727,6 +37484,9 @@ msgstr ""
msgid "This project is %{strongStart}NOT%{strongEnd} a fork, and has the following:"
msgstr ""
+msgid "This project is %{strongStart}NOT%{strongEnd} a fork. This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr "ã“ã®ãƒ—ロジェクトã¯ã‚¢ãƒ¼ã‚«ã‚¤ãƒ–ã•ã‚Œã¦ãŠã‚Šã€ã‚³ãƒ¡ãƒ³ãƒˆã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。"
@@ -37416,6 +38176,9 @@ msgstr "Todo ã‚’ 完了ã¨ãƒžãƒ¼ã‚¯ã—ã¾ã—ãŸã€‚"
msgid "Today"
msgstr "今日"
+msgid "Todos count"
+msgstr ""
+
msgid "Todos|Are you looking for things to do? Take a look at %{strongStart}%{openIssuesLinkStart}open issues%{openIssuesLinkEnd}%{strongEnd}, contribute to %{strongStart}%{mergeRequestLinkStart}a merge request%{mergeRequestLinkEnd}%{mergeRequestLinkEnd}%{strongEnd}, or mention someone in a comment to automatically assign them a new to-do item."
msgstr ""
@@ -37689,9 +38452,8 @@ msgstr "ツリービュー"
msgid "Trending"
msgstr "トレンド分æž"
-msgid "Trials|%{planName} Trial %{enDash} %{num} day left"
-msgid_plural "Trials|%{planName} Trial %{enDash} %{num} days left"
-msgstr[0] ""
+msgid "Trials|%{planName} Trial"
+msgstr ""
msgid "Trials|Compare all plans"
msgstr ""
@@ -37699,6 +38461,9 @@ msgstr ""
msgid "Trials|Create a new group to start your GitLab Ultimate trial."
msgstr ""
+msgid "Trials|Day %{daysUsed}/%{duration}"
+msgstr ""
+
msgid "Trials|Go back to GitLab"
msgstr ""
@@ -37948,7 +38713,7 @@ msgstr ""
msgid "URL is triggered when repository is updated"
msgstr ""
-msgid "URL must be percent-encoded if neccessary."
+msgid "URL must be percent-encoded if necessary."
msgstr ""
msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
@@ -38167,6 +38932,9 @@ msgstr "アンロック"
msgid "Unlock account"
msgstr ""
+msgid "Unlock more features with GitLab Ultimate"
+msgstr ""
+
msgid "Unlock the discussion"
msgstr "ディスカッションã®ãƒ­ãƒƒã‚¯ã‚’解除ã™ã‚‹"
@@ -38230,6 +38998,9 @@ msgstr "ã“ã®%{quick_action_target} ã‹ã‚‰é€€ä¼šã—ã¾ã—ãŸã€‚"
msgid "Unsubscribes from this %{quick_action_target}."
msgstr "ã“ã®%{quick_action_target} ã‹ã‚‰é€€ä¼šã—ã¾ã™ã€‚"
+msgid "Unsupported sort value."
+msgstr ""
+
msgid "Unsupported todo type passed. Supported todo types are: %{todo_types}"
msgstr ""
@@ -38458,6 +39229,9 @@ msgstr "ç¾åœ¨ã®ä½¿ç”¨çŠ¶æ³"
msgid "UsageQuota|File attachments and smaller design graphics."
msgstr ""
+msgid "UsageQuota|From %{storage_enforcement_date} storage limits will apply to this namespace. View and manage your usage in %{strong_start}Group Settings &gt; Usage quotas%{strong_end}."
+msgstr ""
+
msgid "UsageQuota|Git repository."
msgstr ""
@@ -38518,6 +39292,9 @@ msgstr "ストレージ"
msgid "UsageQuota|Storage type"
msgstr ""
+msgid "UsageQuota|Storage used"
+msgstr ""
+
msgid "UsageQuota|This is the total amount of storage used across your projects within this namespace."
msgstr ""
@@ -38713,6 +39490,12 @@ msgstr "ãƒãƒƒã‚·ãƒ¥ã‚¹ãƒˆãƒ¬ãƒ¼ã‚¸ã‚’使ã†"
msgid "Use hashed storage paths for newly created and renamed repositories. Always enabled since 13.0."
msgstr ""
+msgid "Use issue count"
+msgstr ""
+
+msgid "Use issue weight"
+msgstr ""
+
msgid "Use one line per URI"
msgstr "URI ã”ã¨ã«1行使用"
@@ -39094,6 +39877,9 @@ msgstr ""
msgid "Users"
msgstr "ユーザー"
+msgid "Users API rate limit"
+msgstr ""
+
msgid "Users can launch a development environment from a GitLab browser tab when the %{linkStart}Gitpod%{linkEnd} integration is enabled."
msgstr ""
@@ -39417,6 +40203,9 @@ msgstr ""
msgid "View group labels"
msgstr "グループラベルを表示"
+msgid "View group pipeline usage quota"
+msgstr ""
+
msgid "View incident details at"
msgstr ""
@@ -39568,6 +40357,9 @@ msgstr "脆弱性"
msgid "Vulnerabilities over time"
msgstr "長期ã«ã‚ãŸã‚‹è„†å¼±æ€§"
+msgid "Vulnerability"
+msgstr ""
+
msgid "Vulnerability Report"
msgstr "脆弱性レãƒãƒ¼ãƒˆ"
@@ -39619,6 +40411,9 @@ msgstr ""
msgid "VulnerabilityManagement|An unverified non-confirmed finding"
msgstr ""
+msgid "VulnerabilityManagement|At least one identifier is required"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -39628,12 +40423,24 @@ msgstr ""
msgid "VulnerabilityManagement|Create Jira issue"
msgstr ""
+msgid "VulnerabilityManagement|Enter a name"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE code"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE identifier URL"
+msgstr ""
+
msgid "VulnerabilityManagement|Fetching linked Jira issues"
msgstr ""
msgid "VulnerabilityManagement|Manually add a vulnerability entry into the vulnerability report."
msgstr ""
+msgid "VulnerabilityManagement|Name is a required field"
+msgstr ""
+
msgid "VulnerabilityManagement|Needs triage"
msgstr ""
@@ -39649,6 +40456,18 @@ msgstr ""
msgid "VulnerabilityManagement|Select a method"
msgstr ""
+msgid "VulnerabilityManagement|Select a severity level"
+msgstr ""
+
+msgid "VulnerabilityManagement|Select a status"
+msgstr ""
+
+msgid "VulnerabilityManagement|Severity is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Something went wrong while creating vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -39673,6 +40492,12 @@ msgstr ""
msgid "VulnerabilityManagement|Something went wrong, could not update vulnerability state."
msgstr ""
+msgid "VulnerabilityManagement|Status is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Submit vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Summary, detailed description, steps to reproduce, etc."
msgstr ""
@@ -39868,6 +40693,9 @@ msgstr ""
msgid "WARNING:"
msgstr ""
+msgid "WARNING: This snippet contains hidden files which might be used to mask malicious behavior. Exercise caution if cloning and executing code from this snippet."
+msgstr ""
+
msgid "Wait for the file to load to copy its contents"
msgstr "ファイルをロードã—ã€ãã®å†…容をコピーã—ã¦ã„ã¾ã™ã€‚ãŠå¾…ã¡ãã ã•ã„。"
@@ -40087,6 +40915,15 @@ msgstr ""
msgid "Webhooks|An issue is created, updated, closed, or reopened."
msgstr ""
+msgid "Webhooks|Are you sure you want to delete this group hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this project hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this webhook?"
+msgstr ""
+
msgid "Webhooks|Comments"
msgstr "コメント"
@@ -40096,6 +40933,9 @@ msgstr ""
msgid "Webhooks|Confidential issues events"
msgstr ""
+msgid "Webhooks|Delete webhook"
+msgstr ""
+
msgid "Webhooks|Deployment events"
msgstr "デプロイイベント"
@@ -40328,6 +41168,9 @@ msgstr ""
msgid "Wiki"
msgstr "Wiki"
+msgid "Wiki page"
+msgstr ""
+
msgid "Wiki page was successfully created."
msgstr ""
@@ -40433,7 +41276,7 @@ msgstr "%{pageTitle} ページを削除ã—ã¾ã™ã‹ï¼Ÿ"
msgid "WikiPageConflictMessage|Someone edited the page the same time you did. Please check out %{wikiLinkStart}the page%{wikiLinkEnd} and make sure your changes will not unintentionally remove theirs."
msgstr ""
-msgid "WikiPage|An error occured while trying to render the content editor. Please try again later."
+msgid "WikiPage|An error occurred while trying to render the content editor. Please try again later."
msgstr ""
msgid "WikiPage|Are you sure you want to switch back to the classic editor?"
@@ -40592,6 +41435,18 @@ msgstr ""
msgid "WorkItem|New Task"
msgstr ""
+msgid "WorkItem|Something went wrong when creating a work item. Please try again"
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching the work item. Please try again."
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching work item types. Please try again"
+msgstr ""
+
+msgid "WorkItem|Type"
+msgstr ""
+
msgid "WorkItem|Work Items"
msgstr ""
@@ -40658,7 +41513,10 @@ msgstr ""
msgid "You are about to add %{usersTag} people to the discussion. They will all receive a notification."
msgstr ""
-msgid "You are about to permanently delete this project"
+msgid "You are about to delete this forked project containing:"
+msgstr ""
+
+msgid "You are about to delete this project containing:"
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."
@@ -40679,6 +41537,9 @@ msgstr "ã‚ãªãŸã¯ã€ä»¥å‰ã«æ›´æ–°ã—ãŸãƒ•ã‚¡ã‚¤ãƒ«ã‚’削除ã—よã†ã¨ã—
msgid "You are attempting to update a file that has changed since you started editing it."
msgstr "編集ã—ãŸãƒ•ã‚¡ã‚¤ãƒ«ã‚’æ›´æ–°ã—よã†ã¨ã—ã¦ã„ã¾ã™ã€‚"
+msgid "You are billed if you exceed this number. %{qsrOverageLinkStart}How does billing work?%{qsrOverageLinkEnd}"
+msgstr ""
+
msgid "You are connected to the Prometheus server, but there is currently no data to display."
msgstr "Prometheusサーãƒãƒ¼ã«æŽ¥ç¶šã§ãã¾ã—ãŸãŒã€ç¾åœ¨è¡¨ç¤ºã§ãるデータã¯ã‚ã‚Šã¾ã›ã‚“。"
@@ -40736,6 +41597,9 @@ msgstr ""
msgid "You are not authorized to update this scanner profile"
msgstr ""
+msgid "You are not authorized to upload metric images"
+msgstr ""
+
msgid "You are now impersonating %{username}"
msgstr "ã‚ãªãŸã¯ %{username} アカウントを代用ã—ã¦ã„ã¾ã™ã€‚"
@@ -40889,9 +41753,6 @@ msgstr "プロジェクトã¯è‡ªåˆ†ãŒç®¡ç†ã™ã‚‹åå‰ç©ºé–“ã«ã®ã¿è»¢é€ã§
msgid "You can only upload one design when dropping onto an existing design."
msgstr "既存ã®ãƒ‡ã‚¶ã‚¤ãƒ³ã«ç ´æ£„ã—ãŸã¨ãã«ã‚¢ãƒƒãƒ—ロードã§ãるデザインã¯1ã¤ã ã‘ã§ã™ã€‚"
-msgid "You can recover this project until %{date}"
-msgstr "%{date} ã¾ã§ã“ã®ãƒ—ロジェクトを復元ã§ãã¾ã™"
-
msgid "You can resolve the merge conflict using either the Interactive mode, by choosing %{use_ours} or %{use_theirs} buttons, or by editing the files directly. Commit these changes into %{branch_name}"
msgstr "対話モードã§ã¯ã€%{use_ours} ボタンã¾ãŸã¯%{use_theirs} ボタンã§ã®é¸æŠžã¨ã€ãã®ä»–ファイルã®ç›´æŽ¥ç·¨é›†ã§ç«¶åˆã‚’解決ã§ãã¾ã™ã€‚ãã‚Œã‹ã‚‰ã“れらã®å¤‰æ›´ã‚’ %{branch_name} ã«ã‚³ãƒŸãƒƒãƒˆã—ã¾ã™ã€‚"
@@ -40940,9 +41801,6 @@ msgstr "読ã¿å–り専用ã®ã‚»ã‚«ãƒ³ãƒ€ãƒª GitLab Geo インスタンスã«æ›¸
msgid "You cannot write to this read-only GitLab instance."
msgstr "ã“ã®èª­ã¿å–り専用 GitLab インスタンスã«ã¯æ›¸ã込むã“ã¨ãŒã§ãã¾ã›ã‚“。"
-msgid "You can’t %{tag_start}edit%{tag_end} files directly in this project. Fork this project and submit a merge request with your changes."
-msgstr ""
-
msgid "You can’t edit files directly in this project. Fork this project and submit a merge request with your changes."
msgstr ""
@@ -41094,9 +41952,6 @@ 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 set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
@@ -41127,12 +41982,6 @@ msgstr ""
msgid "You must have maintainer access to force delete a lock"
msgstr "ロックを強制的ã«å‰Šé™¤ã™ã‚‹ã«ã¯ã€Maintainer ã®ã‚¢ã‚¯ã‚»ã‚¹æ¨©ãŒå¿…è¦ã§ã™"
-msgid "You must have permission to create a project in a group before forking."
-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 "ç¾åœ¨ã®æ­£ã—ã„パスワードを入力ã—ã¦ãã ã•ã„"
@@ -41538,7 +42387,7 @@ msgstr "ã‚ãªãŸã®ãƒ—ロジェクト"
msgid "Your public email will be displayed on your public profile."
msgstr ""
-msgid "Your request for access could not be processed: %{error_meesage}"
+msgid "Your request for access could not be processed: %{error_message}"
msgstr ""
msgid "Your request for access has been queued for review."
@@ -41718,6 +42567,9 @@ msgstr "アーカイブ済ã¿"
msgid "archived:"
msgstr ""
+msgid "artifacts"
+msgstr ""
+
msgid "assign yourself"
msgstr "自分ã«å‰²ã‚Šå½“ã¦"
@@ -41746,6 +42598,9 @@ msgstr[0] ""
msgid "branch name"
msgstr "ブランãƒå"
+msgid "builds"
+msgstr ""
+
msgid "by"
msgstr "by"
@@ -42166,6 +43021,9 @@ msgstr ""
msgid "contact with same email already exists in group hierarchy"
msgstr ""
+msgid "container registry images"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -42205,6 +43063,9 @@ msgstr ""
msgid "data"
msgstr ""
+msgid "database"
+msgstr ""
+
msgid "date must not be after 9999-12-31"
msgstr "日付㯠9999-12-31 よりå‰ã‚’指定ã—ã¦ä¸‹ã•ã„"
@@ -42227,9 +43088,6 @@ msgstr "デプロイ"
msgid "design"
msgstr "デザイン"
-msgid "detached"
-msgstr "デタッãƒ"
-
msgid "disabled"
msgstr "無効"
@@ -42474,7 +43332,7 @@ msgstr "ã¯ãƒ†ãƒ³ãƒ—レートを利用ã§ãるグループã«æ‰€å±žã—ã¦ã„ã¾
msgid "is not a valid X509 certificate."
msgstr "ã¯æœ‰åŠ¹ãª X509 証明書ã§ã¯ã‚ã‚Šã¾ã›ã‚“。"
-msgid "is not allowed for sign-up."
+msgid "is not allowed for sign-up. Please use your regular email address."
msgstr ""
msgid "is not allowed for this group."
@@ -42486,7 +43344,7 @@ msgstr ""
msgid "is not allowed since the group is not top-level group."
msgstr ""
-msgid "is not allowed."
+msgid "is not allowed. Please use your regular email address."
msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
@@ -42573,6 +43431,9 @@ msgstr "1分未満"
msgid "level: %{level}"
msgstr "レベル: %{level}"
+msgid "lfs objects"
+msgstr ""
+
msgid "limit of %{project_limit} reached"
msgstr "%{project_limit} ã®åˆ¶é™ã«é”ã—ã¾ã—ãŸ"
@@ -42789,6 +43650,9 @@ msgstr ""
msgid "mrWidget|Merge blocked: pipeline must succeed. It's waiting for a manual action to continue."
msgstr ""
+msgid "mrWidget|Merge blocked: pipeline must succeed. Push a commit that fixes the failure, or %{linkStart}learn about other solutions.%{linkEnd}"
+msgstr ""
+
msgid "mrWidget|Merge blocked: this merge request must be approved."
msgstr ""
@@ -42906,9 +43770,6 @@ msgstr "ã“ã®å¤‰æ›´ã¯æ¬¡ã®ãƒ–ランãƒã«ãƒžãƒ¼ã‚¸ã•ã‚Œã¾ã—ãŸ"
msgid "mrWidget|The changes were not merged into"
msgstr "ã“ã®å¤‰æ›´ã¯æ¬¡ã®ãƒ–ランãƒã«ãƒžãƒ¼ã‚¸ã•ã‚Œã¾ã›ã‚“ã§ã—ãŸ"
-msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr "ã“ã®ã‚½ãƒ¼ã‚¹ãƒ–ランãƒã¯å‰Šé™¤ã•ã‚Œã¾ã—ãŸ"
@@ -43056,9 +43917,6 @@ msgstr ""
msgid "open issue"
msgstr ""
-msgid "opened %{timeAgo}"
-msgstr "%{timeAgo}ã«ã‚ªãƒ¼ãƒ—ン"
-
msgid "or"
msgstr "ã¾ãŸã¯"
@@ -43069,6 +43927,12 @@ msgid "out of %d total test"
msgid_plural "out of %d total tests"
msgstr[0] "テスト全件数 %d ã®ã†ã¡"
+msgid "packages"
+msgstr ""
+
+msgid "pages"
+msgstr ""
+
msgid "parent"
msgid_plural "parents"
msgstr[0] "親"
@@ -43214,6 +44078,9 @@ msgid "reply"
msgid_plural "replies"
msgstr[0] "返信"
+msgid "repositories"
+msgstr ""
+
msgid "repository:"
msgstr ""
@@ -43334,12 +44201,18 @@ msgstr ""
msgid "tag name"
msgstr "ã‚¿ã‚°å"
+msgid "terraform states"
+msgstr ""
+
msgid "the correct format."
msgstr ""
msgid "the file"
msgstr ""
+msgid "the following epic(s)"
+msgstr ""
+
msgid "the following issue(s)"
msgstr "次ã®ã‚¤ã‚·ãƒ¥ãƒ¼"
@@ -43352,21 +44225,12 @@ msgstr ""
msgid "this document"
msgstr "ã“ã®ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆ"
-msgid "this issue cannot be assigned to a confidential epic since it is public"
-msgstr ""
-
-msgid "this issue cannot be made public since it belongs to a confidential epic"
-msgstr ""
-
msgid "time summary"
msgstr ""
msgid "toggle collapse"
msgstr "表示・éžè¡¨ç¤ºåˆ‡ã‚Šæ›¿ãˆ"
-msgid "train"
-msgstr ""
-
msgid "triggered"
msgstr "トリガーã•ã‚ŒãŸ"
@@ -43494,3 +44358,6 @@ msgstr ""
msgid "{project}"
msgstr ""
+msgid "✔"
+msgstr ""
+
diff --git a/locale/ka_GE/gitlab.po b/locale/ka_GE/gitlab.po
index cd051bceb14..c056dbeacca 100644
--- a/locale/ka_GE/gitlab.po
+++ b/locale/ka_GE/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: ka\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2022-02-02 15:46\n"
+"PO-Revision-Date: 2022-03-01 20:39\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -146,6 +146,11 @@ msgid_plural "%d approvers (you've approved)"
msgstr[0] ""
msgstr[1] ""
+msgid "%d assigned issue"
+msgid_plural "%d assigned issues"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -421,8 +426,23 @@ msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
msgstr[1] ""
-msgid "%d vulnerability updated"
-msgid_plural "%d vulnerabilities updated"
+msgid "%d vulnerability set to confirmed"
+msgid_plural "%d vulnerabilities set to confirmed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to dismissed"
+msgid_plural "%d vulnerabilities set to dismissed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to needs triage"
+msgid_plural "%d vulnerabilities set to needs triage"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to resolved"
+msgid_plural "%d vulnerabilities set to resolved"
msgstr[0] ""
msgstr[1] ""
@@ -510,6 +530,12 @@ msgstr[1] ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{completed} of %{total} issues closed"
+msgstr ""
+
+msgid "%{completed} of %{total} weight completed"
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -858,6 +884,9 @@ msgstr ""
msgid "%{openedIssues} open, %{closedIssues} closed"
msgstr ""
+msgid "%{percentage}%% issues closed"
+msgstr ""
+
msgid "%{percentage}%% weight completed"
msgstr ""
@@ -1287,6 +1316,9 @@ msgid_plural "- Users"
msgstr[0] ""
msgstr[1] ""
+msgid "- of - issues closed"
+msgstr ""
+
msgid "- of - weight completed"
msgstr ""
@@ -1429,7 +1461,7 @@ msgstr ""
msgid "1000+"
msgstr ""
-msgid "192.168.0.0/24"
+msgid "192.168.0.0/24 or 2001:0DB8:1234::/48"
msgstr ""
msgid "1st contribution!"
@@ -1741,13 +1773,13 @@ msgstr ""
msgid "AWS Access Key"
msgstr ""
-msgid "AWS Access Key. Only required if not using role instance credentials"
+msgid "AWS Secret Access Key"
msgstr ""
-msgid "AWS Secret Access Key"
+msgid "AWS access key ID (Optional)"
msgstr ""
-msgid "AWS Secret Access Key. Only required if not using role instance credentials"
+msgid "AWS secret access key (Optional)"
msgstr ""
msgid "AWS service error: %{error}"
@@ -1807,9 +1839,6 @@ msgstr ""
msgid "Access granted"
msgstr ""
-msgid "Access key ID"
-msgstr ""
-
msgid "Access requests"
msgstr ""
@@ -1984,7 +2013,7 @@ msgstr ""
msgid "Activity"
msgstr ""
-msgid "Activity|An error occured while retrieving activity. Reload the page to try again."
+msgid "Activity|An error occurred while retrieving activity. Reload the page to try again."
msgstr ""
msgid "Add"
@@ -2023,6 +2052,9 @@ msgstr ""
msgid "Add a %{type}"
msgstr ""
+msgid "Add a GCP region"
+msgstr ""
+
msgid "Add a GPG key"
msgstr ""
@@ -2074,6 +2106,9 @@ msgstr ""
msgid "Add a numbered list"
msgstr ""
+msgid "Add a related epic"
+msgstr ""
+
msgid "Add a related issue"
msgstr ""
@@ -2188,6 +2223,9 @@ msgstr ""
msgid "Add or subtract spent time"
msgstr ""
+msgid "Add people"
+msgstr ""
+
msgid "Add previously merged commits"
msgstr ""
@@ -2254,6 +2292,9 @@ msgstr ""
msgid "Add webhook"
msgstr ""
+msgid "Add your team members and others to GitLab."
+msgstr ""
+
msgid "Add/remove"
msgstr ""
@@ -3076,12 +3117,6 @@ msgstr ""
msgid "AdvancedSearch|Reindex required"
msgstr ""
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. Permanently deleting this project will %{strongStart}immediately delete%{strongEnd} its repositories and %{strongStart}all related resources%{strongEnd}, including issues, merge requests etc."
-msgstr ""
-
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. You will lose this project's repository and %{strongStart}all related resources%{strongEnd}, including issues and merge requests."
-msgstr ""
-
msgid "After a successful password update you will be redirected to login screen."
msgstr ""
@@ -3112,6 +3147,9 @@ msgstr ""
msgid "Akismet helps prevent the creation of spam issues in public projects."
msgstr ""
+msgid "Alert"
+msgstr ""
+
msgid "AlertManagement|Acknowledged"
msgstr ""
@@ -3484,9 +3522,6 @@ msgstr ""
msgid "All environments"
msgstr ""
-msgid "All epics"
-msgstr ""
-
msgid "All groups and projects"
msgstr ""
@@ -4223,12 +4258,15 @@ msgstr ""
msgid "ApplicationSettings|Approve users in the pending approval status?"
msgstr ""
-msgid "ApplicationSettings|By making this change, you will automatically approve %d user with the pending approval status."
-msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users with the pending approval status."
+msgid "ApplicationSettings|Approve users who are pending approval?"
+msgstr ""
+
+msgid "ApplicationSettings|By making this change, you will automatically approve %d user who is pending approval."
+msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users who are pending approval."
msgstr[0] ""
msgstr[1] ""
-msgid "ApplicationSettings|By making this change, you will automatically approve all users in pending approval status."
+msgid "ApplicationSettings|By making this change, you will automatically approve all users who are pending approval."
msgstr ""
msgid "ApplicationSettings|Denied domains for sign-ups"
@@ -4634,10 +4672,10 @@ msgstr ""
msgid "Archiving the project will make it entirely read-only. It is hidden from the dashboard and doesn't show up in searches. %{strong_start}The repository cannot be committed to, and no issues, comments, or other entities can be created.%{strong_end} %{link_start}Learn more.%{link_end}"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to delete this project?"
+msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
+msgid "Are you absolutely sure?"
msgstr ""
msgid "Are you sure that you want to archive this project?"
@@ -4673,12 +4711,18 @@ msgstr ""
msgid "Are you sure you want to delete this SSH key?"
msgstr ""
+msgid "Are you sure you want to delete this comment?"
+msgstr ""
+
msgid "Are you sure you want to delete this deploy key?"
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 label?"
+msgstr ""
+
msgid "Are you sure you want to delete this pipeline schedule?"
msgstr ""
@@ -4694,9 +4738,6 @@ msgstr ""
msgid "Are you sure you want to discard your changes?"
msgstr ""
-msgid "Are you sure you want to erase this build?"
-msgstr ""
-
msgid "Are you sure you want to import %d repository?"
msgid_plural "Are you sure you want to import %d repositories?"
msgstr[0] ""
@@ -4744,6 +4785,9 @@ msgstr ""
msgid "Are you sure you want to remove this list?"
msgstr ""
+msgid "Are you sure you want to remove this nickname?"
+msgstr ""
+
msgid "Are you sure you want to reset the health check token?"
msgstr ""
@@ -4756,10 +4800,10 @@ 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?"
+msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
msgstr ""
-msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
+msgid "Are you sure you want to revoke this project access token? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to stop this environment?"
@@ -4906,9 +4950,6 @@ msgstr ""
msgid "Assigned to %{assignee_name}"
msgstr ""
-msgid "Assigned to %{name}"
-msgstr ""
-
msgid "Assigned to me"
msgstr ""
@@ -4973,6 +5014,9 @@ msgstr[1] ""
msgid "Attaching the file failed."
msgstr ""
+msgid "Attention"
+msgstr ""
+
msgid "Audit Events"
msgstr ""
@@ -5135,6 +5179,12 @@ msgstr ""
msgid "Authorized applications (%{size})"
msgstr ""
+msgid "AuthorizedApplication|Are you sure you want to revoke this application?"
+msgstr ""
+
+msgid "AuthorizedApplication|Revoke application"
+msgstr ""
+
msgid "Authors: %{authors}"
msgstr ""
@@ -6328,6 +6378,9 @@ msgstr ""
msgid "CICDAnalytics|Shared Runners Usage"
msgstr ""
+msgid "CICDAnalytics|Shared runner pipeline minute duration by month"
+msgstr ""
+
msgid "CICDAnalytics|Shared runner usage"
msgstr ""
@@ -6469,6 +6522,9 @@ msgstr ""
msgid "Can create groups:"
msgstr ""
+msgid "Can not delete primary training"
+msgstr ""
+
msgid "Can't apply as the source branch was deleted."
msgstr ""
@@ -6802,9 +6858,6 @@ msgstr ""
msgid "Changing any setting here requires an application restart"
msgstr ""
-msgid "Changing group URL can have unintended side effects."
-msgstr ""
-
msgid "Charts can't be displayed as the request for data has timed out. %{documentationLink}"
msgstr ""
@@ -6892,9 +6945,6 @@ msgstr ""
msgid "Checking branch availability..."
msgstr ""
-msgid "Checking group URL availability..."
-msgstr ""
-
msgid "Checking group path availability..."
msgstr ""
@@ -7388,6 +7438,9 @@ msgstr ""
msgid "Clear recent searches"
msgstr ""
+msgid "Clear repository checks"
+msgstr ""
+
msgid "Clear search"
msgstr ""
@@ -7520,9 +7573,6 @@ msgstr ""
msgid "Closed MRs"
msgstr ""
-msgid "Closed epics"
-msgstr ""
-
msgid "Closed issues"
msgstr ""
@@ -7559,13 +7609,13 @@ msgstr ""
msgid "Cluster level"
msgstr ""
-msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
+msgid "Cluster type must be specified for Stages::ClusterEndpointInserter"
msgstr ""
msgid "ClusterAgents|%{name} successfully deleted"
msgstr ""
-msgid "ClusterAgents|%{number} of %{total} Agents"
+msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
@@ -7607,6 +7657,15 @@ msgstr ""
msgid "ClusterAgents|Agent never connected to GitLab"
msgstr ""
+msgid "ClusterAgents|Agent version mismatch"
+msgstr ""
+
+msgid "ClusterAgents|Agent version mismatch and update"
+msgstr ""
+
+msgid "ClusterAgents|Agent version update required"
+msgstr ""
+
msgid "ClusterAgents|All"
msgstr ""
@@ -7631,7 +7690,7 @@ msgstr ""
msgid "ClusterAgents|Configuration"
msgstr ""
-msgid "ClusterAgents|Connect a cluster through the Agent"
+msgid "ClusterAgents|Connect a cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connect existing cluster"
@@ -7640,13 +7699,13 @@ msgstr ""
msgid "ClusterAgents|Connect with a certificate"
msgstr ""
-msgid "ClusterAgents|Connect with agent"
+msgid "ClusterAgents|Connect with an agent"
msgstr ""
msgid "ClusterAgents|Connect with the GitLab Agent"
msgstr ""
-msgid "ClusterAgents|Connect your cluster through the Agent"
+msgid "ClusterAgents|Connect your cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connected"
@@ -7706,7 +7765,10 @@ msgstr ""
msgid "ClusterAgents|How to register an agent?"
msgstr ""
-msgid "ClusterAgents|Install new Agent"
+msgid "ClusterAgents|How to update an agent?"
+msgstr ""
+
+msgid "ClusterAgents|Install a new agent"
msgstr ""
msgid "ClusterAgents|Last connected %{timeAgo}."
@@ -7733,7 +7795,7 @@ msgstr ""
msgid "ClusterAgents|Never connected"
msgstr ""
-msgid "ClusterAgents|No Agents"
+msgid "ClusterAgents|No agents"
msgstr ""
msgid "ClusterAgents|No clusters connected through cluster certificates"
@@ -7793,6 +7855,9 @@ msgstr ""
msgid "ClusterAgents|The agent has not been connected in a long time. There might be a connectivity issue. Last contact was %{timeAgo}."
msgstr ""
+msgid "ClusterAgents|The agent version do not match each other across your cluster's pods. This can happen when a new agent version was just deployed and Kubernetes is shutting down the old pods."
+msgstr ""
+
msgid "ClusterAgents|The recommended installation method includes the token. If you want to follow the advanced installation method provided in the docs, make sure you save the token value before you close this window."
msgstr ""
@@ -7840,6 +7905,9 @@ msgstr ""
msgid "ClusterAgents|You will need to create a token to connect to your agent"
msgstr ""
+msgid "ClusterAgents|Your agent version is out of sync with your GitLab version (v%{version}), which might cause compatibility problems. Update the agent installed on your cluster to the most recent version."
+msgstr ""
+
msgid "ClusterAgents|Your instance doesn't have the %{linkStart}GitLab Agent Server (KAS)%{linkEnd} set up. Ask a GitLab Administrator to install it."
msgstr ""
@@ -8716,9 +8784,6 @@ msgstr ""
msgid "Comma-separated list of email addresses."
msgstr ""
-msgid "Comma-separated list of users allowed to exceed the rate limit."
-msgstr ""
-
msgid "Comma-separated, e.g. '1.1.1.1, 2.2.2.0/24'"
msgstr ""
@@ -9045,6 +9110,12 @@ msgstr ""
msgid "Confidential"
msgstr ""
+msgid "Confidential issue"
+msgstr ""
+
+msgid "Confidential note"
+msgstr ""
+
msgid "Confidentiality"
msgstr ""
@@ -9078,6 +9149,9 @@ msgstr ""
msgid "Configure Dependency Scanning in `.gitlab-ci.yml`, creating this file if it does not already exist"
msgstr ""
+msgid "Configure GitLab"
+msgstr ""
+
msgid "Configure GitLab runners to start using the Web Terminal. %{helpStart}Learn more.%{helpEnd}"
msgstr ""
@@ -9126,6 +9200,15 @@ msgstr ""
msgid "Configure pipelines to deploy web apps, backend services, APIs and static resources to Google Cloud"
msgstr ""
+msgid "Configure region"
+msgstr ""
+
+msgid "Configure region for environment"
+msgstr ""
+
+msgid "Configure regions"
+msgstr ""
+
msgid "Configure repository mirroring."
msgstr ""
@@ -9159,6 +9242,9 @@ msgstr ""
msgid "Configure which lists are shown for anyone who visits this board"
msgstr ""
+msgid "Configure your environments to be deployed to specific geographical regions"
+msgstr ""
+
msgid "Confirm"
msgstr ""
@@ -9861,10 +9947,10 @@ msgstr ""
msgid "CorpusManagement|Actions"
msgstr ""
-msgid "CorpusManagement|Corpus are used in fuzz testing as mutation source to Improve future testing."
+msgid "CorpusManagement|Corpus file"
msgstr ""
-msgid "CorpusManagement|Corpus file"
+msgid "CorpusManagement|Corpus files are used in coverage-guided fuzz testing as seed inputs to improve testing."
msgstr ""
msgid "CorpusManagement|Corpus files must be in *.zip format. Maximum 5 GB"
@@ -9918,6 +10004,9 @@ msgstr ""
msgid "Could not apply %{name} command."
msgstr ""
+msgid "Could not apply %{name} command. %{message}."
+msgstr ""
+
msgid "Could not authorize chat nickname. Try again!"
msgstr ""
@@ -10068,6 +10157,9 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
+msgid "Create a group"
+msgstr ""
+
msgid "Create a merge request"
msgstr ""
@@ -10092,6 +10184,9 @@ msgstr ""
msgid "Create a personal access token on your account to pull or push via %{protocol}."
msgstr ""
+msgid "Create a project"
+msgstr ""
+
msgid "Create an account using:"
msgstr ""
@@ -10455,6 +10550,9 @@ msgstr ""
msgid "Creation date"
msgstr ""
+msgid "Creator"
+msgstr ""
+
msgid "Credentials"
msgstr ""
@@ -10467,9 +10565,15 @@ msgstr ""
msgid "CredentialsInventory|Personal Access Tokens"
msgstr ""
+msgid "CredentialsInventory|Project Access Tokens"
+msgstr ""
+
msgid "CredentialsInventory|SSH Keys"
msgstr ""
+msgid "Credit card required to be on file in order to create a pipeline"
+msgstr ""
+
msgid "Credit card:"
msgstr ""
@@ -10653,9 +10757,6 @@ msgstr ""
msgid "Customer relations"
msgstr ""
-msgid "Customizable by an administrator."
-msgstr ""
-
msgid "Customizable by owners."
msgstr ""
@@ -10785,30 +10886,18 @@ msgstr ""
msgid "CycleAnalytics|%{selectedLabelsCount} selected (%{maxLabels} max)"
msgstr ""
-msgid "CycleAnalytics|%{stageCount} stages selected"
-msgstr ""
-
-msgid "CycleAnalytics|All stages"
-msgstr ""
-
-msgid "CycleAnalytics|Average days to completion"
+msgid "CycleAnalytics|Average time to completion"
msgstr ""
msgid "CycleAnalytics|Date"
msgstr ""
-msgid "CycleAnalytics|Days to completion"
-msgstr ""
-
msgid "CycleAnalytics|Display chart filters"
msgstr ""
msgid "CycleAnalytics|Lead Time for Changes"
msgstr ""
-msgid "CycleAnalytics|No stages selected"
-msgstr ""
-
msgid "CycleAnalytics|Number of tasks"
msgstr ""
@@ -10837,18 +10926,30 @@ msgstr ""
msgid "CycleAnalytics|Showing data for group '%{groupName}' from %{createdAfter} to %{createdBefore}"
msgstr ""
-msgid "CycleAnalytics|Stages"
+msgid "CycleAnalytics|Stage time: %{title}"
msgstr ""
msgid "CycleAnalytics|Tasks by type"
msgstr ""
-msgid "CycleAnalytics|The average time spent in the selected stage for the items that were completed on each date. Data limited to the last 500 items."
+msgid "CycleAnalytics|The average time items spent in this stage. Data limited to items completed within this date range."
msgstr ""
msgid "CycleAnalytics|The given date range is larger than 180 days"
msgstr ""
+msgid "CycleAnalytics|The total time items spent across each value stream stage. Data limited to items completed within this date range."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Stage time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Total time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|Total time"
+msgstr ""
+
msgid "CycleAnalytics|Type of work"
msgstr ""
@@ -10861,9 +10962,6 @@ msgstr ""
msgid "CycleAnalytics|project dropdown filter"
msgstr ""
-msgid "CycleAnalytics|stage dropdown"
-msgstr ""
-
msgid "DAG visualization requires at least 3 dependent jobs."
msgstr ""
@@ -10963,10 +11061,16 @@ msgstr ""
msgid "DastProfiles|AJAX spider"
msgstr ""
+msgid "DastProfiles|API"
+msgstr ""
+
+msgid "DastProfiles|API endpoint URL"
+msgstr ""
+
msgid "DastProfiles|Active"
msgstr ""
-msgid "DastProfiles|Additional request headers (Optional)"
+msgid "DastProfiles|Additional request headers (optional)"
msgstr ""
msgid "DastProfiles|Are you sure you want to delete this profile?"
@@ -10981,6 +11085,9 @@ msgstr ""
msgid "DastProfiles|Branch missing"
msgstr ""
+msgid "DastProfiles|Choose a scan method"
+msgstr ""
+
msgid "DastProfiles|Could not create the scanner profile. Please try again."
msgstr ""
@@ -11050,7 +11157,13 @@ msgstr ""
msgid "DastProfiles|Excluded URLs"
msgstr ""
-msgid "DastProfiles|Excluded URLs (Optional)"
+msgid "DastProfiles|Excluded URLs (optional)"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths (optional)"
msgstr ""
msgid "DastProfiles|Hide debug messages"
@@ -11107,9 +11220,6 @@ msgstr ""
msgid "DastProfiles|Request headers"
msgstr ""
-msgid "DastProfiles|Rest API"
-msgstr ""
-
msgid "DastProfiles|Run the AJAX spider, in addition to the traditional spider, to crawl the target site."
msgstr ""
@@ -11119,6 +11229,9 @@ msgstr ""
msgid "DastProfiles|Save profile"
msgstr ""
+msgid "DastProfiles|Scan method"
+msgstr ""
+
msgid "DastProfiles|Scan mode"
msgstr ""
@@ -11197,12 +11310,24 @@ msgstr ""
msgid "DastProfiles|Website"
msgstr ""
+msgid "DastProfiles|What does each method do?"
+msgstr ""
+
msgid "DastProfiles|You can either choose a passive scan or validate the target site from the site profile management page. %{docsLinkStart}Learn more about site validation.%{docsLinkEnd}"
msgstr ""
msgid "DastProfiles|You cannot run an active scan against an unvalidated site."
msgstr ""
+msgid "DastProfiles|folder/dast_example.har or https://example.com/dast_example.har"
+msgstr ""
+
+msgid "DastProfiles|folder/example.postman_collection.json or https://example.com/"
+msgstr ""
+
+msgid "DastProfiles|folder/openapi.json or https://example.com/openapi.json"
+msgstr ""
+
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
@@ -11310,6 +11435,9 @@ msgstr ""
msgid "DatadogIntegration|API URL"
msgstr ""
+msgid "DatadogIntegration|Custom tags in Datadog. Enter one tag per line in the %{codeOpen}key:value%{codeClose} format. %{linkOpen}How do I use tags?%{linkClose}"
+msgstr ""
+
msgid "DatadogIntegration|Environment"
msgstr ""
@@ -11328,12 +11456,18 @@ msgstr ""
msgid "DatadogIntegration|Tag all data from this GitLab instance in Datadog. Useful when managing several self-managed deployments."
msgstr ""
+msgid "DatadogIntegration|Tags"
+msgstr ""
+
msgid "DatadogIntegration|The Datadog site to send data to. To send data to the EU site, use %{codeOpen}datadoghq.eu%{codeClose}."
msgstr ""
msgid "DatadogIntegration|Trace your GitLab pipelines with Datadog."
msgstr ""
+msgid "DatadogIntegration|have an invalid format"
+msgstr ""
+
msgid "Datasource name not found"
msgstr ""
@@ -11343,9 +11477,6 @@ msgstr ""
msgid "Date merged"
msgstr ""
-msgid "Date picker"
-msgstr ""
-
msgid "Date range"
msgstr ""
@@ -11499,9 +11630,6 @@ msgstr ""
msgid "Definition"
msgstr ""
-msgid "Delayed Project Deletion (%{adjourned_deletion})"
-msgstr ""
-
msgid "DelayedJobs|Are you sure you want to run %{jobName} immediately? Otherwise this job will run automatically after its timer finishes."
msgstr ""
@@ -11580,10 +11708,10 @@ msgstr ""
msgid "Delete pipeline"
msgstr ""
-msgid "Delete project"
+msgid "Delete pipeline schedule"
msgstr ""
-msgid "Delete project. Are you ABSOLUTELY SURE?"
+msgid "Delete project"
msgstr ""
msgid "Delete row"
@@ -11613,6 +11741,9 @@ msgstr ""
msgid "Delete this epic and all descendants?"
msgstr ""
+msgid "Delete this project"
+msgstr ""
+
msgid "Delete user list"
msgstr ""
@@ -11871,6 +12002,12 @@ msgstr ""
msgid "Deploy to..."
msgstr ""
+msgid "DeployBoards|To see deployment progress for your environments, make sure you are deploying to %{codeStart}$KUBE_NAMESPACE%{codeEnd} and annotating with %{codeStart}app.gitlab.com/app=$CI_PROJECT_PATH_SLUG%{codeEnd} and %{codeStart}app.gitlab.com/env=$CI_ENVIRONMENT_SLUG%{codeEnd}."
+msgstr ""
+
+msgid "DeployBoard|Kubernetes Pods"
+msgstr ""
+
msgid "DeployFreeze|Add a freeze period to prevent unintended releases during a period of time for a given environment. You must update the deployment jobs in %{filename} according to the deploy freezes added here. %{freeze_period_link_start}Learn more.%{freeze_period_link_end}"
msgstr ""
@@ -11955,9 +12092,6 @@ msgstr ""
msgid "DeployTokens|Active Deploy Tokens (%{active_tokens})"
msgstr ""
-msgid "DeployTokens|Allows read and write access to registry images."
-msgstr ""
-
msgid "DeployTokens|Allows read and write access to the package registry."
msgstr ""
@@ -11970,6 +12104,9 @@ msgstr ""
msgid "DeployTokens|Allows read-only access to the repository."
msgstr ""
+msgid "DeployTokens|Allows write access to registry images."
+msgstr ""
+
msgid "DeployTokens|Copy deploy token"
msgstr ""
@@ -12063,12 +12200,57 @@ msgstr ""
msgid "Deploying to AWS is easy with GitLab"
msgstr ""
+msgid "Deployment"
+msgstr ""
+
msgid "Deployment Frequency"
msgstr ""
+msgid "Deployment Target|Project deployment target (optional)"
+msgstr ""
+
+msgid "Deployment Target|Select the deployment target"
+msgstr ""
+
msgid "Deployment frequency"
msgstr ""
+msgid "DeploymentTarget|GitLab Pages"
+msgstr ""
+
+msgid "DeploymentTarget|Heroku"
+msgstr ""
+
+msgid "DeploymentTarget|Infrastructure provider (Terraform, Cloudformation, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Kubernetes (GKE, EKS, OpenShift, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Managed container runtime (Fargate, Cloud Run, DigitalOcean App)"
+msgstr ""
+
+msgid "DeploymentTarget|Mobile app store"
+msgstr ""
+
+msgid "DeploymentTarget|No deployment planned"
+msgstr ""
+
+msgid "DeploymentTarget|Other hosting service"
+msgstr ""
+
+msgid "DeploymentTarget|Registry (package or container)"
+msgstr ""
+
+msgid "DeploymentTarget|Self-managed container runtime (Podman, Docker Swarm, Docker Compose)"
+msgstr ""
+
+msgid "DeploymentTarget|Serverless backend (Lambda, Cloud functions)"
+msgstr ""
+
+msgid "DeploymentTarget|Virtual machine (for example, EC2)"
+msgstr ""
+
msgid "Deployments"
msgstr ""
@@ -12107,6 +12289,9 @@ msgstr ""
msgid "Deployment|This deployment was created using the API"
msgstr ""
+msgid "Deployment|Triggerer"
+msgstr ""
+
msgid "Deployment|Waiting"
msgstr ""
@@ -12134,6 +12319,18 @@ msgstr ""
msgid "Deprecated API rate limits"
msgstr ""
+msgid "Deprecations|Feature deprecation and removal"
+msgstr ""
+
+msgid "Deprecations|For information on a possible replacement %{epicStart} learn more about Opstrace %{epicEnd}."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7 and are %{epicStart} scheduled for removal %{epicEnd} in GitLab 15.0."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7, and are %{removal_link_start} scheduled for removal %{link_end} in GitLab 15.0. For information on a possible replacement, %{opstrace_link_start} learn more about Opstrace %{link_end}."
+msgstr ""
+
msgid "Deprioritize label"
msgstr ""
@@ -12379,10 +12576,10 @@ msgstr ""
msgid "DevopsAdoption|At least one deploy"
msgstr ""
-msgid "DevopsAdoption|At least one issue opened"
+msgid "DevopsAdoption|At least one issue created"
msgstr ""
-msgid "DevopsAdoption|At least one merge request opened"
+msgid "DevopsAdoption|At least one merge request created"
msgstr ""
msgid "DevopsAdoption|At least one pipeline successfully run"
@@ -12583,6 +12780,9 @@ msgstr ""
msgid "Direct member"
msgstr ""
+msgid "Direct members"
+msgstr ""
+
msgid "Direct non-authenticated users to this page."
msgstr ""
@@ -12699,6 +12899,9 @@ msgid_plural "Dismiss %d selected vulnerabilities as"
msgstr[0] ""
msgstr[1] ""
+msgid "Dismiss Alert"
+msgstr ""
+
msgid "Dismiss merge request promotion"
msgstr ""
@@ -12726,9 +12929,15 @@ msgstr ""
msgid "Display alerts from all configured monitoring tools."
msgstr ""
+msgid "Display milestones"
+msgstr ""
+
msgid "Display name"
msgstr ""
+msgid "Display progress of child issues"
+msgstr ""
+
msgid "Display rendered file"
msgstr ""
@@ -12834,6 +13043,9 @@ msgstr ""
msgid "Download image"
msgstr ""
+msgid "Download payload"
+msgstr ""
+
msgid "Download raw data (.csv)"
msgstr ""
@@ -13011,6 +13223,9 @@ msgstr ""
msgid "Edit in Web IDE"
msgstr ""
+msgid "Edit in pipeline editor"
+msgstr ""
+
msgid "Edit in single-file editor"
msgstr ""
@@ -13053,6 +13268,9 @@ msgstr ""
msgid "Edit your most recent comment in a thread (from an empty textarea)"
msgstr ""
+msgid "Edit, lint, and visualize your pipeline."
+msgstr ""
+
msgid "Edited"
msgstr ""
@@ -13494,6 +13712,9 @@ msgstr ""
msgid "Enforce two-factor authentication for all user sign-ins."
msgstr ""
+msgid "Enhance security by storing service account keys in secret managers - learn more about %{docLinkStart}secret management with GitLab%{docLinkEnd}"
+msgstr ""
+
msgid "Ensure connectivity is available from the GitLab server to the Prometheus server"
msgstr ""
@@ -13554,6 +13775,9 @@ 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 following to confirm:"
+msgstr ""
+
msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
@@ -14084,9 +14308,6 @@ 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 ""
@@ -14222,6 +14443,9 @@ msgstr ""
msgid "Errors:"
msgstr ""
+msgid "Escalate this incident"
+msgstr ""
+
msgid "Escalation Policies"
msgstr ""
@@ -14234,6 +14458,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy"
+msgstr ""
+
msgid "Escalation policy:"
msgstr ""
@@ -14485,6 +14712,9 @@ msgstr ""
msgid "Existing sign in methods may be removed"
msgstr ""
+msgid "Exit."
+msgstr ""
+
msgid "Expand"
msgstr ""
@@ -14581,6 +14811,9 @@ msgstr ""
msgid "Explore public groups"
msgstr ""
+msgid "Explore public projects"
+msgstr ""
+
msgid "Explore snippets"
msgstr ""
@@ -14742,7 +14975,7 @@ msgid_plural "Failed to archive designs. Please try again."
msgstr[0] ""
msgstr[1] ""
-msgid "Failed to assign a reviewer because no user was found."
+msgid "Failed to assign a reviewer because no user was specified."
msgstr ""
msgid "Failed to assign a user because no user was found."
@@ -14808,10 +15041,10 @@ msgstr ""
msgid "Failed to find import label for Jira import."
msgstr ""
-msgid "Failed to generate export, please try again later."
+msgid "Failed to find users for %{missing}"
msgstr ""
-msgid "Failed to generate report, please try again after sometime"
+msgid "Failed to generate export, please try again later."
msgstr ""
msgid "Failed to get ref."
@@ -14910,6 +15143,9 @@ msgstr ""
msgid "Failed to remove a to-do item for the design."
msgstr ""
+msgid "Failed to remove attention because no user was found."
+msgstr ""
+
msgid "Failed to remove mirror."
msgstr ""
@@ -14922,6 +15158,9 @@ msgstr ""
msgid "Failed to remove user key."
msgstr ""
+msgid "Failed to request attention because no user was found."
+msgstr ""
+
msgid "Failed to reset key. Please try again."
msgstr ""
@@ -15003,6 +15242,9 @@ msgstr ""
msgid "Feature Flags"
msgstr ""
+msgid "Feature deprecation and removal"
+msgstr ""
+
msgid "Feature flag status"
msgstr ""
@@ -15500,7 +15742,7 @@ msgstr ""
msgid "For each job, re-use the project workspace. If the workspace doesn't exist, use %{code_open}git clone%{code_close}."
msgstr ""
-msgid "For example, the application using the token or the purpose of the token."
+msgid "For example, the application using the token or the purpose of the token. Do not give sensitive information for the name of the token, as it will be visible to all %{resource_type} members."
msgstr ""
msgid "For files larger than this limit, only index the file name. The file content is neither indexed nor searchable."
@@ -15584,9 +15826,6 @@ msgstr ""
msgid "ForkProject|Select a namespace"
msgstr ""
-msgid "ForkProject|Select a namespace to fork the project"
-msgstr ""
-
msgid "ForkProject|The project can be accessed by any logged in user."
msgstr ""
@@ -15683,6 +15922,9 @@ msgstr ""
msgid "Full name"
msgstr ""
+msgid "GCP region configured"
+msgstr ""
+
msgid "GPG Key ID:"
msgstr ""
@@ -15863,6 +16105,9 @@ msgstr ""
msgid "Geo|Failed"
msgstr ""
+msgid "Geo|Filter Geo sites"
+msgstr ""
+
msgid "Geo|Filter by name"
msgstr ""
@@ -16274,6 +16519,12 @@ msgstr ""
msgid "GitLab Issue"
msgstr ""
+msgid "GitLab KAS"
+msgstr ""
+
+msgid "GitLab Memberships CSV Export"
+msgstr ""
+
msgid "GitLab Pages"
msgstr ""
@@ -16322,6 +16573,9 @@ 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 free to use. Many features for larger teams are part of our %{link_start}paid products%{link_end}. You can try Ultimate for free without any obligation or payment details."
+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 ""
@@ -16448,7 +16702,7 @@ msgstr ""
msgid "GitLabPages|When enabled, all attempts to visit your website through HTTP are automatically redirected to HTTPS using a response with status code 301. Requires a valid certificate for all domains. %{docs_link_start}Learn more.%{link_end}"
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. %{docs_link_start}Learn more.%{link_end}"
+msgid "GitLabPages|When using Pages under the general domain of a GitLab instance (%{pages_host}), you cannot use HTTPS with subdomains of subdomains. If your namespace or groupname contains a dot, it does not work. This is a limitation of the HTTP Over TLS protocol. HTTP pages work if you don't redirect HTTP to HTTPS. %{docs_link_start}Learn more.%{link_end}"
msgstr ""
msgid "GitLabPages|With GitLab Pages you can host your static website directly from your GitLab repository. %{docs_link_start}Learn more.%{link_end}"
@@ -16625,9 +16879,6 @@ msgstr ""
msgid "Go to find file"
msgstr ""
-msgid "Go to fork"
-msgstr ""
-
msgid "Go to issue boards"
msgstr ""
@@ -16835,9 +17086,6 @@ msgstr ""
msgid "Group Hooks"
msgstr ""
-msgid "Group ID"
-msgstr ""
-
msgid "Group Owner must have signed in with SAML before enabling Group Managed Accounts"
msgstr ""
@@ -16865,9 +17113,6 @@ msgstr ""
msgid "Group by"
msgstr ""
-msgid "Group description"
-msgstr ""
-
msgid "Group description (optional)"
msgstr ""
@@ -16982,7 +17227,7 @@ msgstr ""
msgid "Group: %{name}"
msgstr ""
-msgid "GroupActivityMetrics|Issues opened"
+msgid "GroupActivityMetrics|Issues created"
msgstr ""
msgid "GroupActivityMetrics|Last 90 days"
@@ -16991,7 +17236,7 @@ msgstr ""
msgid "GroupActivityMetrics|Members added"
msgstr ""
-msgid "GroupActivityMetrics|Merge Requests opened"
+msgid "GroupActivityMetrics|Merge Requests created"
msgstr ""
msgid "GroupActivityMetrics|Recent activity"
@@ -17282,6 +17527,9 @@ msgstr ""
msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
+msgid "GroupSettings|Choose a group path that does not start with a dash or end with a period. It can also contain alphanumeric characters and underscores."
+msgstr ""
+
msgid "GroupSettings|Compliance frameworks"
msgstr ""
@@ -17315,7 +17563,7 @@ msgstr ""
msgid "GroupSettings|If not specified at the group or instance level, the default is %{default_initial_branch_name}. Does not affect existing repositories."
msgstr ""
-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."
+msgid "GroupSettings|If the parent group's visibility is lower than the group's current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility."
msgstr ""
msgid "GroupSettings|New runners registration token has been generated!"
@@ -17432,7 +17680,10 @@ msgstr ""
msgid "Groups and projects"
msgstr ""
-msgid "Groups and subgroups"
+msgid "Groups are a great way to organize projects and people."
+msgstr ""
+
+msgid "Groups are the best way to manage projects and members."
msgstr ""
msgid "Groups to synchronize"
@@ -17543,13 +17794,16 @@ msgstr ""
msgid "GroupsTree|Are you sure you want to leave the \"%{fullName}\" group?"
msgstr ""
-msgid "GroupsTree|Edit group"
+msgid "GroupsTree|Delete"
+msgstr ""
+
+msgid "GroupsTree|Edit"
msgstr ""
msgid "GroupsTree|Failed to leave the group. Please make sure you are not the only owner."
msgstr ""
-msgid "GroupsTree|Leave this group"
+msgid "GroupsTree|Leave group"
msgstr ""
msgid "GroupsTree|Loading groups"
@@ -17561,9 +17815,57 @@ msgstr ""
msgid "GroupsTree|No groups or projects matched your search"
msgstr ""
+msgid "GroupsTree|Options"
+msgstr ""
+
msgid "GroupsTree|Search by name"
msgstr ""
+msgid "Groups|Avatar will be removed. Are you sure?"
+msgstr ""
+
+msgid "Groups|Changing group URL can have unintended side effects."
+msgstr ""
+
+msgid "Groups|Checking group URL availability..."
+msgstr ""
+
+msgid "Groups|Enter a descriptive name for your group."
+msgstr ""
+
+msgid "Groups|Group ID"
+msgstr ""
+
+msgid "Groups|Group URL"
+msgstr ""
+
+msgid "Groups|Group avatar"
+msgstr ""
+
+msgid "Groups|Group description (optional)"
+msgstr ""
+
+msgid "Groups|Group name"
+msgstr ""
+
+msgid "Groups|Group path is available."
+msgstr ""
+
+msgid "Groups|Group path is unavailable. Path has been replaced with a suggested available path."
+msgstr ""
+
+msgid "Groups|Learn more"
+msgstr ""
+
+msgid "Groups|Must start with letter, digit, emoji, or underscore. Can also contain periods, dashes, spaces, and parentheses."
+msgstr ""
+
+msgid "Groups|Remove avatar"
+msgstr ""
+
+msgid "Groups|Save changes"
+msgstr ""
+
msgid "Guideline"
msgstr ""
@@ -17573,6 +17875,9 @@ msgstr ""
msgid "HAR file path or URL"
msgstr ""
+msgid "HTTP Archive (HAR)"
+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 ""
@@ -17973,6 +18278,9 @@ msgstr ""
msgid "INFO: Your SSH key is expiring soon. Please generate a new key."
msgstr ""
+msgid "IP"
+msgstr ""
+
msgid "IP Address"
msgstr ""
@@ -18009,6 +18317,9 @@ msgstr ""
msgid "IdentityVerification|Verify your identity"
msgstr ""
+msgid "IdentityVerification|You can always verify your account at a later time to create a group."
+msgstr ""
+
msgid "If any indexed field exceeds this limit, it is truncated to this number of characters. The rest of the content is neither indexed nor searchable. This does not apply to repository and wiki indexing. For unlimited characters, set this to 0."
msgstr ""
@@ -18066,6 +18377,9 @@ msgstr ""
msgid "If you add %{codeStart}needs%{codeEnd} to jobs in your pipeline you'll be able to view the %{codeStart}needs%{codeEnd} relationships between jobs in this tab as a %{linkStart}Directed Acyclic Graph (DAG)%{linkEnd}."
msgstr ""
+msgid "If you are added to a project, it will be displayed here."
+msgstr ""
+
msgid "If you did not initiate these sign-in attempts, please reach out to your administrator or enable two-factor authentication (2FA) on your account."
msgstr ""
@@ -18372,12 +18686,24 @@ msgstr ""
msgid "InProductMarketing|3 ways to dive into GitLab CI/CD"
msgstr ""
+msgid "InProductMarketing|A single application eliminates complex integrations, data chokepoints, and toolchain maintenance, resulting in greater productivity and lower cost."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features, build more efficiently, strengthen security and compliance."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features."
+msgstr ""
+
msgid "InProductMarketing|Actually, GitLab makes the team work (better)"
msgstr ""
msgid "InProductMarketing|And finally %{deploy_link} a Python application."
msgstr ""
+msgid "InProductMarketing|And many more..."
+msgstr ""
+
msgid "InProductMarketing|Are your runners ready?"
msgstr ""
@@ -18396,15 +18722,33 @@ msgstr ""
msgid "InProductMarketing|Blog"
msgstr ""
+msgid "InProductMarketing|Break down silos to coordinate seamlessly across development, operations, and security with a consistent experience across the development lifecycle."
+msgstr ""
+
+msgid "InProductMarketing|Burn up/down charts"
+msgstr ""
+
msgid "InProductMarketing|By enabling code owners and required merge approvals the right person will review the right MR. This is a win-win: cleaner code and a more efficient review process."
msgstr ""
msgid "InProductMarketing|Click on the number below that corresponds with your answer — 1 being very difficult, 5 being very easy."
msgstr ""
+msgid "InProductMarketing|Code owners"
+msgstr ""
+
msgid "InProductMarketing|Code owners and required merge approvals are part of the paid tiers of GitLab. You can start a free 30-day trial of GitLab Ultimate and enable these features in less than 5 minutes with no credit card required."
msgstr ""
+msgid "InProductMarketing|Code review analytics"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration across stages in GitLab"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration made easy"
+msgstr ""
+
msgid "InProductMarketing|Create a custom CI runner with just a few clicks"
msgstr ""
@@ -18414,12 +18758,21 @@ msgstr ""
msgid "InProductMarketing|Create a project in GitLab in 5 minutes"
msgstr ""
+msgid "InProductMarketing|Create well-defined workflows by using scoped labels on issues, merge requests, and epics. Labels with the same scope cannot be used together, which prevents conflicts."
+msgstr ""
+
msgid "InProductMarketing|Create your first project!"
msgstr ""
+msgid "InProductMarketing|Define who owns specific files or directories, so the right reviewers are suggested when a merge request introduces changes to those files."
+msgstr ""
+
msgid "InProductMarketing|Deliver Better Products Faster"
msgstr ""
+msgid "InProductMarketing|Dependency scanning"
+msgstr ""
+
msgid "InProductMarketing|Did you know teams that use GitLab are far more efficient?"
msgstr ""
@@ -18429,15 +18782,27 @@ msgstr ""
msgid "InProductMarketing|Dig in and create a project and a repo"
msgstr ""
+msgid "InProductMarketing|Discover Premium & Ultimate"
+msgstr ""
+
+msgid "InProductMarketing|Discover Premium & Ultimate."
+msgstr ""
+
msgid "InProductMarketing|Do you have a minute?"
msgstr ""
msgid "InProductMarketing|Do you have a teammate who would be perfect for this task?"
msgstr ""
+msgid "InProductMarketing|Dynamic application security testing"
+msgstr ""
+
msgid "InProductMarketing|Easy"
msgstr ""
+msgid "InProductMarketing|Epics"
+msgstr ""
+
msgid "InProductMarketing|Expand your DevOps journey with a free GitLab trial"
msgstr ""
@@ -18459,9 +18824,15 @@ msgstr ""
msgid "InProductMarketing|Feel the need for speed?"
msgstr ""
+msgid "InProductMarketing|Find and fix bottlenecks in your code review process by understanding how long open merge requests have been in review."
+msgstr ""
+
msgid "InProductMarketing|Find out how your teams are really doing"
msgstr ""
+msgid "InProductMarketing|Find out if your external libraries are safe. Run dependency scanning jobs that check for known vulnerabilities in your external libraries."
+msgstr ""
+
msgid "InProductMarketing|Follow our steps"
msgstr ""
@@ -18498,6 +18869,9 @@ msgstr ""
msgid "InProductMarketing|GitLab is better with teammates to help out!"
msgstr ""
+msgid "InProductMarketing|GitLab is infrastructure agnostic (supporting GCP, AWS, Azure, OpenShift, VMWare, On Prem, Bare Metal, and more), offering a consistent workflow experience – irrespective of the environment."
+msgstr ""
+
msgid "InProductMarketing|GitLab provides static application security testing (SAST), dynamic application security testing (DAST), container scanning, and dependency scanning to help you deliver secure applications along with license compliance."
msgstr ""
@@ -18588,21 +18962,36 @@ msgstr ""
msgid "InProductMarketing|It's also possible to simply %{external_repo_link} in order to take advantage of GitLab's CI/CD."
msgstr ""
+msgid "InProductMarketing|Keep your code quality high by defining who should approve merge requests and how many approvals are required."
+msgstr ""
+
msgid "InProductMarketing|Launch GitLab CI/CD in 20 minutes or less"
msgstr ""
+msgid "InProductMarketing|Lower cost of development"
+msgstr ""
+
+msgid "InProductMarketing|Make it easier to collaborate on high-level ideas by grouping related issues in an epic."
+msgstr ""
+
msgid "InProductMarketing|Making the switch? It's easier than you think to import your projects into GitLab. Move %{github_link}, or import something %{bitbucket_link}."
msgstr ""
msgid "InProductMarketing|Master the art of importing!"
msgstr ""
+msgid "InProductMarketing|Merge request approval rule"
+msgstr ""
+
msgid "InProductMarketing|Move on to easily creating a Pages website %{ci_template_link}"
msgstr ""
msgid "InProductMarketing|Multiple owners, confusing workstreams? We've got you covered"
msgstr ""
+msgid "InProductMarketing|Multiple required approvers"
+msgstr ""
+
msgid "InProductMarketing|Need an alternative to importing?"
msgstr ""
@@ -18615,18 +19004,33 @@ msgstr ""
msgid "InProductMarketing|Our tool brings all the things together"
msgstr ""
+msgid "InProductMarketing|Protect your web application by using DAST to examine for vulnerabilities in deployed environments."
+msgstr ""
+
msgid "InProductMarketing|Rapid development, simplified"
msgstr ""
msgid "InProductMarketing|Reduce Security & Compliance Risk"
msgstr ""
+msgid "InProductMarketing|Require multiple approvers on a merge request, so you know it's in good shape before it's merged."
+msgstr ""
+
+msgid "InProductMarketing|Roadmaps"
+msgstr ""
+
+msgid "InProductMarketing|Scoped labels"
+msgstr ""
+
msgid "InProductMarketing|Security that's integrated into your development lifecycle"
msgstr ""
msgid "InProductMarketing|Sometimes you're not ready to make a full transition to a new tool. If you're not ready to fully commit, %{mirroring_link} gives you a safe way to try out GitLab in parallel with your current tool."
msgstr ""
+msgid "InProductMarketing|Speed. Efficiency. Trust."
+msgstr ""
+
msgid "InProductMarketing|Spin up an autoscaling runner in GitLab"
msgstr ""
@@ -18636,6 +19040,9 @@ msgstr ""
msgid "InProductMarketing|Start a Self-Managed trial"
msgstr ""
+msgid "InProductMarketing|Start a free trial"
+msgstr ""
+
msgid "InProductMarketing|Start a free trial of GitLab Ultimate – no credit card required"
msgstr ""
@@ -18702,6 +19109,9 @@ msgstr ""
msgid "InProductMarketing|To understand and get the most out of GitLab, start at the beginning and %{project_link}. In GitLab, repositories are part of a project, so after you've created your project you can go ahead and %{repo_link}."
msgstr ""
+msgid "InProductMarketing|Track completed issues in a chart, so you can see how a milestone is progressing at a glance."
+msgstr ""
+
msgid "InProductMarketing|Try GitLab Ultimate for free"
msgstr ""
@@ -18738,6 +19148,9 @@ msgstr ""
msgid "InProductMarketing|Very easy"
msgstr ""
+msgid "InProductMarketing|Visualize your epics and milestones in a timeline."
+msgstr ""
+
msgid "InProductMarketing|Want to host GitLab on your servers?"
msgstr ""
@@ -18759,6 +19172,9 @@ msgstr ""
msgid "InProductMarketing|YouTube"
msgstr ""
+msgid "InProductMarketing|Your software, deployed your way"
+msgstr ""
+
msgid "InProductMarketing|Your teams can be more efficient"
msgstr ""
@@ -18879,9 +19295,18 @@ msgstr ""
msgid "IncidentManagement|No incidents to display."
msgstr ""
+msgid "IncidentManagement|None"
+msgstr ""
+
msgid "IncidentManagement|Open"
msgstr ""
+msgid "IncidentManagement|Page your team with escalation policies"
+msgstr ""
+
+msgid "IncidentManagement|Paged"
+msgstr ""
+
msgid "IncidentManagement|Published"
msgstr ""
@@ -18891,6 +19316,9 @@ msgstr ""
msgid "IncidentManagement|Severity"
msgstr ""
+msgid "IncidentManagement|Status"
+msgstr ""
+
msgid "IncidentManagement|There are no closed incidents"
msgstr ""
@@ -18909,6 +19337,9 @@ msgstr ""
msgid "IncidentManagement|Unpublished"
msgstr ""
+msgid "IncidentManagement|Use escalation policies to automatically page your team when incidents are created."
+msgstr ""
+
msgid "IncidentSettings|Activate \"time to SLA\" countdown timer"
msgstr ""
@@ -18954,7 +19385,10 @@ msgstr ""
msgid "Incidents"
msgstr ""
-msgid "Incidents|Add a URL"
+msgid "Incidents|Add image details"
+msgstr ""
+
+msgid "Incidents|Add text or a link to display with your image. If you don't add either, the file name displays instead."
msgstr ""
msgid "Incidents|Drop or %{linkStart}upload%{linkEnd} a metric screenshot to attach it to the incident"
@@ -18969,10 +19403,10 @@ msgstr ""
msgid "Incidents|There was an issue loading metric images."
msgstr ""
-msgid "Incidents|There was an issue uploading your image."
+msgid "Incidents|There was an issue updating your image."
msgstr ""
-msgid "Incidents|You can optionally add a URL to link users to the original graph."
+msgid "Incidents|There was an issue uploading your image."
msgstr ""
msgid "Incident|Alert details"
@@ -18981,9 +19415,18 @@ msgstr ""
msgid "Incident|Are you sure you wish to delete this image?"
msgstr ""
+msgid "Incident|Delete image"
+msgstr ""
+
msgid "Incident|Deleting %{filename}"
msgstr ""
+msgid "Incident|Edit image text or link"
+msgstr ""
+
+msgid "Incident|Editing %{filename}"
+msgstr ""
+
msgid "Incident|Metrics"
msgstr ""
@@ -19253,12 +19696,18 @@ msgstr ""
msgid "Integrations|Branches for which notifications are to be sent"
msgstr ""
+msgid "Integrations|Clear if using a self-signed certificate."
+msgstr ""
+
msgid "Integrations|Comment detail:"
msgstr ""
msgid "Integrations|Comment settings:"
msgstr ""
+msgid "Integrations|Connection details"
+msgstr ""
+
msgid "Integrations|Connection failed. Please check your settings."
msgstr ""
@@ -19283,6 +19732,9 @@ msgstr ""
msgid "Integrations|Enable GitLab.com slash commands in a Slack workspace."
msgstr ""
+msgid "Integrations|Enable SSL verification"
+msgstr ""
+
msgid "Integrations|Enable comments"
msgstr ""
@@ -19361,6 +19813,9 @@ msgstr ""
msgid "Integrations|Return to GitLab for Jira"
msgstr ""
+msgid "Integrations|SSL verification"
+msgstr ""
+
msgid "Integrations|Save settings?"
msgstr ""
@@ -19406,9 +19861,6 @@ msgstr ""
msgid "Integrations|Use default settings"
msgstr ""
-msgid "Integrations|When you mention a Jira issue in a commit or merge request, GitLab creates a remote link and comment (if enabled)."
-msgstr ""
-
msgid "Integrations|You can now close this window and return to the GitLab for Jira application."
msgstr ""
@@ -19433,9 +19885,6 @@ msgstr ""
msgid "Integrations|can't exceed %{recipients_limit}"
msgstr ""
-msgid "Interactive developer security education."
-msgstr ""
-
msgid "Interactive mode"
msgstr ""
@@ -19925,6 +20374,9 @@ msgstr ""
msgid "IssueAnalytics|Assignees"
msgstr ""
+msgid "IssueAnalytics|Created by"
+msgstr ""
+
msgid "IssueAnalytics|Due date"
msgstr ""
@@ -19937,9 +20389,6 @@ msgstr ""
msgid "IssueAnalytics|Milestone"
msgstr ""
-msgid "IssueAnalytics|Opened by"
-msgstr ""
-
msgid "IssueAnalytics|Status"
msgstr ""
@@ -20063,10 +20512,10 @@ msgstr ""
msgid "IssuesAnalytics|Avg/Month:"
msgstr ""
-msgid "IssuesAnalytics|Issues opened"
+msgid "IssuesAnalytics|Issues created"
msgstr ""
-msgid "IssuesAnalytics|Issues opened per month"
+msgid "IssuesAnalytics|Issues created per month"
msgstr ""
msgid "IssuesAnalytics|Last 12 months"
@@ -20093,6 +20542,9 @@ msgstr ""
msgid "It looks like you have some draft commits in this branch."
msgstr ""
+msgid "It looks like you're attempting to activate your subscription. Use %{a_start}the Subscription page%{a_end} instead."
+msgstr ""
+
msgid "It may be several days before you see feature usage data."
msgstr ""
@@ -20321,6 +20773,9 @@ msgstr ""
msgid "JiraConnect|You can now close this window and return to Jira."
msgstr ""
+msgid "JiraConnect|You don't have permission to create branches for this project. Select a different project or contact the project owner for access. %{linkStart}Learn more.%{linkEnd}"
+msgstr ""
+
msgid "JiraRequest|A connection error occurred while connecting to Jira. Try your request again."
msgstr ""
@@ -20369,13 +20824,13 @@ msgstr ""
msgid "JiraService|Define the type of Jira issue to create from a vulnerability."
msgstr ""
-msgid "JiraService|Displaying Jira issues while leaving the GitLab issue functionality enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
+msgid "JiraService|Displaying Jira issues while leaving GitLab issues also enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
msgstr ""
-msgid "JiraService|Enable Jira issues"
+msgid "JiraService|Enable Jira issue creation from vulnerabilities"
msgstr ""
-msgid "JiraService|Enable Jira issues creation from vulnerabilities"
+msgid "JiraService|Enable Jira issues"
msgstr ""
msgid "JiraService|Enable Jira transitions"
@@ -20492,16 +20947,19 @@ msgstr ""
msgid "JiraService|View Jira issues in GitLab"
msgstr ""
-msgid "JiraService|Warning: All GitLab users that have access to this GitLab project are able to view all issues from the Jira project specified below."
+msgid "JiraService|Warning: All GitLab users with access to this GitLab project can view all issues from the Jira project you select."
msgstr ""
msgid "JiraService|Web URL"
msgstr ""
-msgid "JiraService|Work on Jira issues without leaving GitLab. Adds a Jira menu to access your list of Jira issues and view any issue as read-only."
+msgid "JiraService|When a Jira issue is mentioned in a commit or merge request, a remote link and comment (if enabled) will be created."
+msgstr ""
+
+msgid "JiraService|Work on Jira issues without leaving GitLab. Add a Jira menu to access a read-only list of your Jira issues."
msgstr ""
-msgid "JiraService|You need to configure Jira before enabling this integration. For more details, read the %{jira_doc_link_start}Jira integration documentation%{link_end}."
+msgid "JiraService|You must configure Jira before enabling this integration. %{jira_doc_link_start}Learn more.%{link_end}"
msgstr ""
msgid "Job"
@@ -20513,9 +20971,6 @@ msgstr ""
msgid "Job Failed #%{build_id}"
msgstr ""
-msgid "Job ID"
-msgstr ""
-
msgid "Job artifact"
msgstr ""
@@ -20582,9 +21037,27 @@ msgstr ""
msgid "Jobs|You're about to retry a job that failed because it attempted to deploy code that is older than the latest deployment. Retrying this job could result in overwriting the environment with the older source code."
msgstr ""
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source} into %{target}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{ref}"
+msgstr ""
+
+msgid "Job|Are you sure you want to erase this job log and artifacts?"
+msgstr ""
+
msgid "Job|Browse"
msgstr ""
+msgid "Job|Cancel"
+msgstr ""
+
msgid "Job|Complete Raw"
msgstr ""
@@ -20594,6 +21067,9 @@ msgstr ""
msgid "Job|Erase job log and artifacts"
msgstr ""
+msgid "Job|Finished at"
+msgstr ""
+
msgid "Job|Job artifacts"
msgstr ""
@@ -20606,7 +21082,7 @@ msgstr ""
msgid "Job|Keep"
msgstr ""
-msgid "Job|Pipeline"
+msgid "Job|Retry"
msgstr ""
msgid "Job|Scroll to bottom"
@@ -20618,6 +21094,9 @@ msgstr ""
msgid "Job|Show complete raw"
msgstr ""
+msgid "Job|Status"
+msgstr ""
+
msgid "Job|The artifacts were removed"
msgstr ""
@@ -20645,21 +21124,12 @@ msgstr ""
msgid "Job|delayed"
msgstr ""
-msgid "Job|for"
-msgstr ""
-
-msgid "Job|into"
-msgstr ""
-
msgid "Job|manual"
msgstr ""
msgid "Job|triggered"
msgstr ""
-msgid "Job|with"
-msgstr ""
-
msgid "Join Zoom meeting"
msgstr ""
@@ -20762,9 +21232,6 @@ msgstr ""
msgid "Ki"
msgstr ""
-msgid "Kontra"
-msgstr ""
-
msgid "Kroki"
msgstr ""
@@ -21088,6 +21555,9 @@ msgstr ""
msgid "Learn more about Auto DevOps"
msgstr ""
+msgid "Learn more about GitLab"
+msgstr ""
+
msgid "Learn more about Needs relationships"
msgstr ""
@@ -21415,9 +21885,18 @@ msgstr ""
msgid "Licenses|Displays licenses detected in the project, based on the %{linkStart}latest successful%{linkEnd} scan"
msgstr ""
+msgid "Licenses|Drag your license file here or %{linkStart}click to upload%{linkEnd}."
+msgstr ""
+
+msgid "Licenses|Drop your license file to start the upload."
+msgstr ""
+
msgid "Licenses|Error fetching the license list. Please check your network connection and try again."
msgstr ""
+msgid "Licenses|Error: You are trying to upload something other than a file"
+msgstr ""
+
msgid "Licenses|License Compliance"
msgstr ""
@@ -21436,6 +21915,9 @@ msgstr ""
msgid "Licenses|Specified policies in this project"
msgstr ""
+msgid "Licenses|The file could not be uploaded."
+msgstr ""
+
msgid "Licenses|The license list details information about the licenses used within your project."
msgstr ""
@@ -21469,11 +21951,6 @@ msgstr ""
msgid "Limit the size of Sidekiq jobs stored in Redis."
msgstr ""
-msgid "Limited to showing %d event at most"
-msgid_plural "Limited to showing %d events at most"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Limiting mode"
msgstr ""
@@ -21483,6 +21960,9 @@ msgstr ""
msgid "Link"
msgstr ""
+msgid "Link (optional)"
+msgstr ""
+
msgid "Link Prometheus monitoring to GitLab."
msgstr ""
@@ -21519,6 +21999,9 @@ msgstr ""
msgid "Linked emails (%{email_count})"
msgstr ""
+msgid "Linked epics"
+msgstr ""
+
msgid "Linked issues"
msgstr ""
@@ -21546,6 +22029,15 @@ msgstr ""
msgid "List of all merge commits"
msgstr ""
+msgid "List of environments for this project"
+msgstr ""
+
+msgid "List of suitable GCP locations"
+msgstr ""
+
+msgid "List of users allowed to exceed the rate limit."
+msgstr ""
+
msgid "List options"
msgstr ""
@@ -21765,6 +22257,9 @@ msgstr ""
msgid "Maintenance mode"
msgstr ""
+msgid "Make adjustments to how your GitLab instance is set up."
+msgstr ""
+
msgid "Make and review changes in the browser with the Web IDE"
msgstr ""
@@ -21909,6 +22404,12 @@ msgstr ""
msgid "MarkdownEditor|Add italic text (%{modifier_key}I)"
msgstr ""
+msgid "MarkdownEditor|Add strikethrough text (%{modifierKey}⇧X)"
+msgstr ""
+
+msgid "MarkdownEditor|Add strikethrough text (%{modifier_key}⇧X)"
+msgstr ""
+
msgid "Marked For Deletion At - %{deletion_time}"
msgstr ""
@@ -22170,6 +22671,9 @@ msgstr ""
msgid "Maximum push size (MB)"
msgstr ""
+msgid "Maximum requests per 10 minutes per user"
+msgstr ""
+
msgid "Maximum requests per minute"
msgstr ""
@@ -22260,6 +22764,19 @@ msgstr ""
msgid "Members of a group may only view projects they have permission to access"
msgstr ""
+msgid "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seat in use and will be billed for the overage."
+msgid_plural "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seats in use and will be billed for the overage."
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "MembersOverage|You are about to incur additional charges"
+msgstr ""
+
+msgid "MembersOverage|Your subscription includes %d seat."
+msgid_plural "MembersOverage|Your subscription includes %d seats."
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Membership"
msgstr ""
@@ -22464,9 +22981,6 @@ msgstr ""
msgid "Merge request not merged"
msgstr ""
-msgid "Merge request pipelines 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 merge request pipelines."
-msgstr ""
-
msgid "Merge request reports"
msgstr ""
@@ -22563,13 +23077,13 @@ msgstr ""
msgid "MergeRequests|Create issue to resolve thread"
msgstr ""
-msgid "MergeRequests|Failed to squash. Should be done manually."
+msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Saving the comment failed"
+msgid "MergeRequests|Squashing failed: Squash the commits locally, resolve any conflicts, then push the branch."
msgstr ""
-msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
+msgid "MergeRequests|Squashing not allowed: This project doesn't allow you to squash commits when merging."
msgstr ""
msgid "MergeRequests|Thread stays resolved"
@@ -23410,6 +23924,18 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "MrList|Assigned to %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from assignee %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from reviewer %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Review requested from %{name}, go to their profile."
+msgstr ""
+
msgid "Multi-project"
msgstr ""
@@ -23443,7 +23969,7 @@ msgstr ""
msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "My Awesome Group"
+msgid "My awesome group"
msgstr ""
msgid "My company or team"
@@ -24065,9 +24591,6 @@ msgstr ""
msgid "No available branches"
msgstr ""
-msgid "No available groups to fork the project."
-msgstr ""
-
msgid "No branches found"
msgstr ""
@@ -24278,6 +24801,9 @@ msgstr ""
msgid "No ref selected"
msgstr ""
+msgid "No regions configured"
+msgstr ""
+
msgid "No related merge requests found."
msgstr ""
@@ -25082,6 +25608,9 @@ msgstr ""
msgid "Only reCAPTCHA v2 is supported:"
msgstr ""
+msgid "Only required if not using role instance credentials."
+msgstr ""
+
msgid "Only use lowercase letters, numbers, and underscores."
msgstr ""
@@ -25106,9 +25635,6 @@ msgstr ""
msgid "Open a CLI and connect to the cluster you want to install the agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
-msgid "Open epics"
-msgstr ""
-
msgid "Open errors"
msgstr ""
@@ -25148,7 +25674,7 @@ msgstr ""
msgid "Opened issues"
msgstr ""
-msgid "OpenedNDaysAgo|Opened"
+msgid "OpenedNDaysAgo|Created"
msgstr ""
msgid "Opens in a new window"
@@ -25193,9 +25719,6 @@ msgstr ""
msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
-msgid "Optional."
-msgstr ""
-
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
msgstr ""
@@ -25984,6 +26507,9 @@ msgstr ""
msgid "PerformanceBar|Memory"
msgstr ""
+msgid "PerformanceBar|Memory report"
+msgstr ""
+
msgid "PerformanceBar|Redis calls"
msgstr ""
@@ -26017,18 +26543,12 @@ msgstr ""
msgid "PerformanceBar|wall"
msgstr ""
-msgid "Performs a rebase but skips triggering a new pipeline"
-msgstr ""
-
msgid "Period in seconds"
msgstr ""
msgid "Permalink"
msgstr ""
-msgid "Permanently delete project"
-msgstr ""
-
msgid "Permanently remove group"
msgstr ""
@@ -26299,6 +26819,51 @@ msgstr ""
msgid "PipelineStatusTooltip|Pipeline: %{ci_status}"
msgstr ""
+msgid "PipelineWizardDefaultCommitMessage|Add %{filename}"
+msgstr ""
+
+msgid "PipelineWizardDefaultCommitMessage|Update %{filename}"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|At least one entry is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This field is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This value is not valid"
+msgstr ""
+
+msgid "PipelineWizardListWidget|add another step"
+msgstr ""
+
+msgid "PipelineWizardListWidget|remove step"
+msgstr ""
+
+msgid "PipelineWizard|Commit"
+msgstr ""
+
+msgid "PipelineWizard|Commit Message"
+msgstr ""
+
+msgid "PipelineWizard|Commit changes to your file"
+msgstr ""
+
+msgid "PipelineWizard|Commit file to Branch"
+msgstr ""
+
+msgid "PipelineWizard|Commit your new file"
+msgstr ""
+
+msgid "PipelineWizard|The file has been committed."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem committing the changes."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem while checking whether your file already exists in the specified branch."
+msgstr ""
+
msgid "Pipelines"
msgstr ""
@@ -26413,7 +26978,7 @@ msgstr ""
msgid "Pipelines|Project cache successfully reset."
msgstr ""
-msgid "Pipelines|Revoke"
+msgid "Pipelines|Revoke trigger"
msgstr ""
msgid "Pipelines|Something went wrong while cleaning runners cache."
@@ -26458,6 +27023,12 @@ msgstr ""
msgid "Pipelines|This is a child pipeline within the parent pipeline"
msgstr ""
+msgid "Pipelines|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipelines|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipelines|This pipeline will run code originating from a forked project merge request. This means that the code can potentially have security considerations like exposing CI variables."
msgstr ""
@@ -26500,9 +27071,6 @@ msgstr ""
msgid "Pipelines|Your changes have been successfully committed. Now redirecting to the new merge request page."
msgstr ""
-msgid "Pipelines|detached"
-msgstr ""
-
msgid "Pipelines|error"
msgstr ""
@@ -26512,10 +27080,13 @@ msgstr ""
msgid "Pipelines|latest"
msgstr ""
-msgid "Pipelines|stuck"
+msgid "Pipelines|merge request"
msgstr ""
-msgid "Pipelines|train"
+msgid "Pipelines|merge train"
+msgstr ""
+
+msgid "Pipelines|stuck"
msgstr ""
msgid "Pipelines|yaml invalid"
@@ -26647,6 +27218,12 @@ msgstr ""
msgid "Pipeline|This change will not change the overall test coverage if merged."
msgstr ""
+msgid "Pipeline|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipeline|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipeline|Trigger author"
msgstr ""
@@ -26671,6 +27248,12 @@ msgstr ""
msgid "Pipeline|for"
msgstr ""
+msgid "Pipeline|merge request"
+msgstr ""
+
+msgid "Pipeline|merge train"
+msgstr ""
+
msgid "Pipeline|on"
msgstr ""
@@ -26809,9 +27392,6 @@ msgstr ""
msgid "Please enter a valid time interval"
msgstr ""
-msgid "Please enter or upload a valid license."
-msgstr ""
-
msgid "Please enter your current password."
msgstr ""
@@ -26920,9 +27500,6 @@ msgstr ""
msgid "Please type %{phrase_code} to proceed or close this modal to cancel."
msgstr ""
-msgid "Please type the following to confirm:"
-msgstr ""
-
msgid "Please use this form to report to the admin users who create spam issues, comments or behave inappropriately."
msgstr ""
@@ -26950,12 +27527,27 @@ msgstr ""
msgid "Policies"
msgstr ""
+msgid "Policy '%{escalation_policy_name}' does not exist."
+msgstr ""
+
msgid "Policy management project does have any policies in %{policy_path}"
msgstr ""
msgid "Policy project doesn't exist"
msgstr ""
+msgid "PolicyRuleMultiSelect|%{firstLabel} +%{numberOfAdditionalLabels} more"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|All %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select all"
+msgstr ""
+
msgid "Polling interval multiplier"
msgstr ""
@@ -27184,6 +27776,9 @@ msgstr ""
msgid "Private projects can be created in your personal namespace with:"
msgstr ""
+msgid "Problem with %{name} command: %{message}."
+msgstr ""
+
msgid "Proceed"
msgstr ""
@@ -27658,6 +28253,9 @@ msgstr ""
msgid "Progress"
msgstr ""
+msgid "Progress tracking"
+msgstr ""
+
msgid "Project"
msgstr ""
@@ -27889,6 +28487,9 @@ msgstr ""
msgid "ProjectQualitySummary|Failure"
msgstr ""
+msgid "ProjectQualitySummary|Get insight into the overall percentage of tests in your project that succeed, fail and are skipped."
+msgstr ""
+
msgid "ProjectQualitySummary|Latest pipeline results"
msgstr ""
@@ -27907,6 +28508,12 @@ msgstr ""
msgid "ProjectQualitySummary|See project Code Coverage Statistics"
msgstr ""
+msgid "ProjectQualitySummary|Set up test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|Set up test runs (opens in a new tab)"
+msgstr ""
+
msgid "ProjectQualitySummary|Skipped"
msgstr ""
@@ -28183,13 +28790,19 @@ msgstr ""
msgid "ProjectSettings|LFS objects from this repository are available to forks. %{linkStart}How do I remove them?%{linkEnd}"
msgstr ""
+msgid "ProjectSettings|Learn about commit history."
+msgstr ""
+
+msgid "ProjectSettings|Leave empty to use default template."
+msgstr ""
+
msgid "ProjectSettings|Manage who can see the project in the public access directory."
msgstr ""
msgid "ProjectSettings|Manages large files such as audio, video, and graphics files."
msgstr ""
-msgid "ProjectSettings|Maximum 500 characters."
+msgid "ProjectSettings|Maximum %{maxLength} characters."
msgstr ""
msgid "ProjectSettings|Merge checks"
@@ -28330,6 +28943,9 @@ msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
msgstr ""
+msgid "ProjectSettings|The default template will be applied on save."
+msgstr ""
+
msgid "ProjectSettings|These checks must pass before merge requests can be merged."
msgstr ""
@@ -28384,6 +29000,9 @@ msgstr ""
msgid "ProjectSettings|What are badges?"
msgstr ""
+msgid "ProjectSettings|What are merge trains?"
+msgstr ""
+
msgid "ProjectSettings|When merge request pipelines are enabled in the CI/CD configuration file, pipelines validate the combined results of the source and target branches. %{link_start}How to configure merge request pipelines?%{link_end}"
msgstr ""
@@ -28501,6 +29120,9 @@ msgstr ""
msgid "Projects are organized into groups"
msgstr ""
+msgid "Projects are where you store your code, access issues, wiki and other features of GitLab."
+msgstr ""
+
msgid "Projects contributed to"
msgstr ""
@@ -28516,12 +29138,6 @@ msgstr ""
msgid "Projects to index"
msgstr ""
-msgid "Projects will be permanently deleted after a %{waiting_period}-day waiting period."
-msgstr ""
-
-msgid "Projects will be permanently deleted immediately."
-msgstr ""
-
msgid "Projects with critical vulnerabilities"
msgstr ""
@@ -28606,6 +29222,9 @@ msgstr ""
msgid "ProjectsNew|Import project"
msgstr ""
+msgid "ProjectsNew|Include a Getting Started README"
+msgstr ""
+
msgid "ProjectsNew|Initialize repository with a README"
msgstr ""
@@ -28621,6 +29240,9 @@ msgstr ""
msgid "ProjectsNew|Project description %{tag_start}(optional)%{tag_end}"
msgstr ""
+msgid "ProjectsNew|Recommended if you're new to GitLab"
+msgstr ""
+
msgid "ProjectsNew|Run CI/CD for external repository"
msgstr ""
@@ -29038,6 +29660,9 @@ msgstr ""
msgid "ProtectedBranch|Unprotect"
msgstr ""
+msgid "ProtectedBranch|Unprotect branch"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
@@ -29065,6 +29690,9 @@ msgstr ""
msgid "ProtectedEnvironment|Protected Environment (%{protected_environments_count})"
msgstr ""
+msgid "ProtectedEnvironment|Required approvals"
+msgstr ""
+
msgid "ProtectedEnvironment|Select an environment"
msgstr ""
@@ -29086,10 +29714,13 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|Unprotect tag"
+msgstr ""
+
msgid "ProtectedTags|default"
msgstr ""
-msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
+msgid "ProtectedTag|By default, protected tags restrict who can modify the tag."
msgstr ""
msgid "ProtectedTag|Learn more."
@@ -29152,6 +29783,9 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Public projects are an easy way to allow everyone to have read-only access."
+msgstr ""
+
msgid "Publish to status page"
msgstr ""
@@ -29308,9 +29942,6 @@ msgstr ""
msgid "QualitySummary|Project quality"
msgstr ""
-msgid "Quarters"
-msgstr ""
-
msgid "Query"
msgstr ""
@@ -29395,6 +30026,9 @@ msgstr ""
msgid "Read more about project permissions %{help_link_open}here%{help_link_close}"
msgstr ""
+msgid "Read more about related epics"
+msgstr ""
+
msgid "Read more about related issues"
msgstr ""
@@ -29425,10 +30059,7 @@ msgstr ""
msgid "Rebase source branch on the target branch."
msgstr ""
-msgid "Rebase without CI"
-msgstr ""
-
-msgid "Rebases and triggers a pipeline"
+msgid "Rebase without pipeline"
msgstr ""
msgid "Recaptcha verified?"
@@ -29479,9 +30110,6 @@ msgstr ""
msgid "Reconfigure"
msgstr ""
-msgid "Recovering projects"
-msgstr ""
-
msgid "Recovery Codes"
msgstr ""
@@ -29541,6 +30169,12 @@ msgstr ""
msgid "Regex pattern"
msgstr ""
+msgid "Region"
+msgstr ""
+
+msgid "Regions"
+msgstr ""
+
msgid "Register"
msgstr ""
@@ -29771,9 +30405,6 @@ msgstr ""
msgid "Remove all or specific reviewer(s)"
msgstr ""
-msgid "Remove approver"
-msgstr ""
-
msgid "Remove approvers"
msgstr ""
@@ -29789,6 +30420,9 @@ msgstr ""
msgid "Remove attention request"
msgstr ""
+msgid "Remove attention request(s)"
+msgstr ""
+
msgid "Remove avatar"
msgstr ""
@@ -29927,6 +30561,9 @@ msgstr ""
msgid "Removed an issue from an epic."
msgstr ""
+msgid "Removed attention from %{users_sentence}."
+msgstr ""
+
msgid "Removed attention request from @%{username}"
msgstr ""
@@ -29978,6 +30615,9 @@ msgstr ""
msgid "Removes an issue from an epic."
msgstr ""
+msgid "Removes attention from %{users_sentence}."
+msgstr ""
+
msgid "Removes parent epic %{epic_ref}."
msgstr ""
@@ -30089,6 +30729,9 @@ msgstr ""
msgid "Report abuse to admin"
msgstr ""
+msgid "Report is generating and will be sent to your email address."
+msgstr ""
+
msgid "Reported %{timeAgo} by %{reportedBy}"
msgstr ""
@@ -30378,6 +31021,15 @@ msgstr ""
msgid "Request attention"
msgstr ""
+msgid "Request attention from %{users_sentence}."
+msgstr ""
+
+msgid "Request attention from assignee or reviewer"
+msgstr ""
+
+msgid "Request attention from assignee(s) or reviewer(s)"
+msgstr ""
+
msgid "Request attention to review"
msgstr ""
@@ -30402,6 +31054,9 @@ msgstr ""
msgid "Requested %{time_ago}"
msgstr ""
+msgid "Requested attention from %{users_sentence}."
+msgstr ""
+
msgid "Requested attention from @%{username}"
msgstr ""
@@ -30616,6 +31271,9 @@ msgstr ""
msgid "Restore project"
msgstr ""
+msgid "Restoring projects"
+msgstr ""
+
msgid "Restoring the group will prevent the group, its subgroups and projects from being removed on this date."
msgstr ""
@@ -30646,6 +31304,9 @@ msgstr ""
msgid "Retry"
msgstr ""
+msgid "Retry failed jobs"
+msgstr ""
+
msgid "Retry job"
msgstr ""
@@ -30693,9 +31354,6 @@ msgstr ""
msgid "Review changes"
msgstr ""
-msgid "Review requested from %{name}"
-msgstr ""
-
msgid "Review requests for you"
msgstr ""
@@ -30860,6 +31518,9 @@ msgstr ""
msgid "Runners|Assigned Group"
msgstr ""
+msgid "Runners|Assigned Projects (%{projectCount})"
+msgstr ""
+
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30929,6 +31590,9 @@ msgstr ""
msgid "Runners|Instance"
msgstr ""
+msgid "Runners|Jobs"
+msgstr ""
+
msgid "Runners|Last contact"
msgstr ""
@@ -31022,9 +31686,6 @@ msgstr ""
msgid "Runners|Runner %{name} was deleted"
msgstr ""
-msgid "Runners|Runner ID"
-msgstr ""
-
msgid "Runners|Runner assigned to project."
msgstr ""
@@ -31172,6 +31833,9 @@ msgstr ""
msgid "Runners|stale"
msgstr ""
+msgid "Runner|This runner has not run any jobs."
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -31286,6 +31950,24 @@ msgstr ""
msgid "Saving project."
msgstr ""
+msgid "ScanResultPolicy|%{ifLabelStart}if%{ifLabelEnd} %{scanners} scan in an open merge request targeting the %{branches} branch(es) finds %{vulnerabilitiesAllowed} or more %{severities} vulnerabilities that are %{vulnerabilityStates}"
+msgstr ""
+
+msgid "ScanResultPolicy|%{thenLabelStart}Then%{thenLabelEnd} Require approval from %{approvalsRequired} of the following approvers: %{approvers}"
+msgstr ""
+
+msgid "ScanResultPolicy|add an approver"
+msgstr ""
+
+msgid "ScanResultPolicy|scanners"
+msgstr ""
+
+msgid "ScanResultPolicy|severity levels"
+msgstr ""
+
+msgid "ScanResultPolicy|vulnerability states"
+msgstr ""
+
msgid "Scanner"
msgstr ""
@@ -31418,6 +32100,9 @@ msgstr ""
msgid "Search for a user"
msgstr ""
+msgid "Search for an emoji"
+msgstr ""
+
msgid "Search for projects, issues, etc."
msgstr ""
@@ -31605,18 +32290,12 @@ msgstr ""
msgid "Secret Detection"
msgstr ""
-msgid "Secret access key"
-msgstr ""
-
msgid "Secret token"
msgstr ""
msgid "Secure token that identifies an external storage request."
msgstr ""
-msgid "SecureCodeWarrior"
-msgstr ""
-
msgid "Security"
msgstr ""
@@ -31641,9 +32320,6 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "Security training with guide and learning pathways."
-msgstr ""
-
msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
@@ -31746,7 +32422,7 @@ msgstr ""
msgid "SecurityConfiguration|Manage corpus"
msgstr ""
-msgid "SecurityConfiguration|Manage corpus files used as mutation sources in coverage fuzzing."
+msgid "SecurityConfiguration|Manage corpus files used as seed inputs with coverage-guided fuzzing."
msgstr ""
msgid "SecurityConfiguration|Manage profiles for use by DAST scans."
@@ -31812,15 +32488,15 @@ msgstr ""
msgid "SecurityOrchestration|.yaml preview"
msgstr ""
-msgid "SecurityOrchestration|Action"
-msgstr ""
-
msgid "SecurityOrchestration|Actions"
msgstr ""
msgid "SecurityOrchestration|Add rule"
msgstr ""
+msgid "SecurityOrchestration|After dismissing the alert, the information will never be shown again."
+msgstr ""
+
msgid "SecurityOrchestration|All policies"
msgstr ""
@@ -31836,7 +32512,7 @@ msgstr ""
msgid "SecurityOrchestration|Description"
msgstr ""
-msgid "SecurityOrchestration|Disabled"
+msgid "SecurityOrchestration|Don't show the alert anymore"
msgstr ""
msgid "SecurityOrchestration|Edit policy"
@@ -31845,13 +32521,13 @@ msgstr ""
msgid "SecurityOrchestration|Edit policy project"
msgstr ""
-msgid "SecurityOrchestration|Enabled"
+msgid "SecurityOrchestration|Empty policy name"
msgstr ""
-msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Enabled"
msgstr ""
-msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
msgstr ""
msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
@@ -31860,7 +32536,7 @@ msgstr ""
msgid "SecurityOrchestration|Invalid policy type"
msgstr ""
-msgid "SecurityOrchestration|Latest scan"
+msgid "SecurityOrchestration|Latest scan run against %{agent}"
msgstr ""
msgid "SecurityOrchestration|Network"
@@ -31869,15 +32545,27 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No actions defined - policy will not run."
+msgstr ""
+
+msgid "SecurityOrchestration|No description"
+msgstr ""
+
msgid "SecurityOrchestration|No rules defined - policy will not run."
msgstr ""
+msgid "SecurityOrchestration|Not enabled"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
msgid "SecurityOrchestration|Policies"
msgstr ""
+msgid "SecurityOrchestration|Policy Type"
+msgstr ""
+
msgid "SecurityOrchestration|Policy cannot be enabled for non-existing branches (%{branches})"
msgstr ""
@@ -31902,10 +32590,13 @@ msgstr ""
msgid "SecurityOrchestration|Require %{approvals} %{plural} from %{approvers} if any of the following occur:"
msgstr ""
-msgid "SecurityOrchestration|Rule"
+msgid "SecurityOrchestration|Rules"
msgstr ""
-msgid "SecurityOrchestration|Rules"
+msgid "SecurityOrchestration|Runs %{actions} and %{lastAction} scans"
+msgstr ""
+
+msgid "SecurityOrchestration|Runs a %{action} scan"
msgstr ""
msgid "SecurityOrchestration|Scan Execution"
@@ -31965,6 +32656,9 @@ msgstr ""
msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
+msgid "SecurityOrchestration|This view only shows scan results for the agent %{agent}. You can view scan results for all agents in the %{linkStart}Operational Vulnerabilities tab of the vulnerability report%{linkEnd}."
+msgstr ""
+
msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
@@ -32019,9 +32713,6 @@ msgstr ""
msgid "SecurityOrchestration|users with ids"
msgstr ""
-msgid "SecurityOrchestration|view results"
-msgstr ""
-
msgid "SecurityOrchestration|vulnerabilities"
msgstr ""
@@ -32691,22 +33382,19 @@ 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|In order to start using functions as a service, you must first install Knative on your Kubernetes cluster. %{linkStart}More information%{linkEnd}"
-msgstr ""
-
msgid "Serverless|Learn more about Serverless"
msgstr ""
msgid "Serverless|No functions available"
msgstr ""
-msgid "Serverless|Sign up for First Look"
+msgid "Serverless|Serverless was %{linkStart}deprecated%{linkEnd} in GitLab 14.3."
+msgstr ""
+
+msgid "Serverless|Serverless was %{postLinkStart}deprecated%{postLinkEnd}. But if you opt to use it, you must install Knative in your Kubernetes cluster first. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "Serverless|The deploy job has not finished."
@@ -32718,9 +33406,6 @@ 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 ""
@@ -32736,9 +33421,6 @@ msgstr ""
msgid "Service Account Key"
msgstr ""
-msgid "Service Accounts"
-msgstr ""
-
msgid "Service Accounts keys authorize GitLab to deploy your Google Cloud project"
msgstr ""
@@ -32748,10 +33430,10 @@ msgstr ""
msgid "Service Desk allows people to create issues in your GitLab instance without their own user account. It provides a unique email address for end users to create issues in a project. Replies can be sent either through the GitLab interface or by email. End users only see threads through email."
msgstr ""
-msgid "Service Usage Data"
+msgid "Service account generated successfully"
msgstr ""
-msgid "Service account generated successfully"
+msgid "Service accounts"
msgstr ""
msgid "Service ping is disabled in your configuration file, and cannot be enabled through this form."
@@ -32895,6 +33577,9 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
+msgid "Set the per-user rate limit for getting a user by ID via the API."
+msgstr ""
+
msgid "Set the per-user rate limit for notes created by web or API requests."
msgstr ""
@@ -33074,6 +33759,9 @@ msgstr ""
msgid "Shared runners details"
msgstr ""
+msgid "Shared runners enabled cannot be enabled until a valid credit card is on file"
+msgstr ""
+
msgid "Shared runners help link"
msgstr ""
@@ -33131,6 +33819,9 @@ msgstr ""
msgid "Show all issues."
msgstr ""
+msgid "Show all milestones"
+msgstr ""
+
msgid "Show all test cases."
msgstr ""
@@ -33167,6 +33858,9 @@ msgstr ""
msgid "Show file contents"
msgstr ""
+msgid "Show group milestones"
+msgstr ""
+
msgid "Show labels"
msgstr ""
@@ -33182,6 +33876,12 @@ msgstr ""
msgid "Show open epics"
msgstr ""
+msgid "Show project milestones"
+msgstr ""
+
+msgid "Show sub-group milestones"
+msgstr ""
+
msgid "Show the Closed list"
msgstr ""
@@ -33191,11 +33891,6 @@ msgstr ""
msgid "Show whitespace changes"
msgstr ""
-msgid "Showing %d event"
-msgid_plural "Showing %d events"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Showing %{conflict} between %{sourceBranch} and %{targetBranch}"
msgstr ""
@@ -33255,12 +33950,6 @@ msgstr ""
msgid "Sidebar|None"
msgstr ""
-msgid "Sidebar|Only numeral characters allowed"
-msgstr ""
-
-msgid "Sidebar|Weight"
-msgstr ""
-
msgid "Sidekiq job compression threshold (bytes)"
msgstr ""
@@ -33423,6 +34112,9 @@ msgstr ""
msgid "Slack logo"
msgstr ""
+msgid "SlackIntegration|Are you sure you want to remove this project from the Slack application?"
+msgstr ""
+
msgid "SlackIntegration|GitLab for Slack"
msgstr ""
@@ -33432,6 +34124,9 @@ msgstr ""
msgid "SlackIntegration|Project alias"
msgstr ""
+msgid "SlackIntegration|Remove project"
+msgstr ""
+
msgid "SlackIntegration|Select a GitLab project to link with your Slack workspace."
msgstr ""
@@ -33576,9 +34271,6 @@ msgstr ""
msgid "Something went wrong trying to load issue contacts."
msgstr ""
-msgid "Something went wrong when creating a work item. Please try again"
-msgstr ""
-
msgid "Something went wrong when reordering designs. Please try again"
msgstr ""
@@ -33672,9 +34364,6 @@ msgstr ""
msgid "Something went wrong while inserting your image. Please try again."
msgstr ""
-msgid "Something went wrong while merging this merge request. Please try again."
-msgstr ""
-
msgid "Something went wrong while obtaining the Let's Encrypt certificate."
msgstr ""
@@ -33996,10 +34685,10 @@ 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."
+msgid "SourcegraphAdmin|Learn more."
msgstr ""
-msgid "SourcegraphAdmin|More information"
+msgid "SourcegraphAdmin|Only public projects have code intelligence enabled and communicate with Sourcegraph."
msgstr ""
msgid "SourcegraphAdmin|Save changes"
@@ -34008,7 +34697,7 @@ msgstr ""
msgid "SourcegraphAdmin|Sourcegraph URL"
msgstr ""
-msgid "SourcegraphAdmin|e.g. https://sourcegraph.example.com"
+msgid "SourcegraphAdmin|https://sourcegraph.example.com"
msgstr ""
msgid "SourcegraphPreferences|This feature is experimental and currently limited to certain projects."
@@ -34143,6 +34832,9 @@ msgstr ""
msgid "Start date"
msgstr ""
+msgid "Start free trial"
+msgstr ""
+
msgid "Start merge train"
msgstr ""
@@ -34173,6 +34865,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started escalation for this incident."
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -34185,6 +34880,9 @@ msgstr ""
msgid "Starts at (UTC)"
msgstr ""
+msgid "Starts escalations for this incident"
+msgstr ""
+
msgid "Starts on"
msgstr ""
@@ -34446,6 +35144,9 @@ msgstr ""
msgid "Strikethrough"
msgstr ""
+msgid "Strikethrough text"
+msgstr ""
+
msgid "Subgroup information"
msgstr ""
@@ -34680,6 +35381,21 @@ msgstr ""
msgid "Subscriptions"
msgstr ""
+msgid "Subscriptions|Chat with sales"
+msgstr ""
+
+msgid "Subscriptions|Close"
+msgstr ""
+
+msgid "Subscriptions|Not ready to buy yet?"
+msgstr ""
+
+msgid "Subscriptions|Start a free trial"
+msgstr ""
+
+msgid "Subscriptions|We understand. Maybe you have some questions for our sales team, or maybe you'd like to try some of the paid features first. What would you like to do?"
+msgstr ""
+
msgid "Subscription|Your subscription for %{strong}%{namespace_name}%{strong_close} has expired and you are now on %{pricing_link_start}the GitLab Free tier%{pricing_link_end}. Don't worry, your data is safe. Get in touch with our support team (%{support_email}). They'll gladly help with your subscription renewal."
msgstr ""
@@ -34890,6 +35606,9 @@ msgstr ""
msgid "SuperSonics|Maximum users"
msgstr ""
+msgid "SuperSonics|Offline cloud"
+msgstr ""
+
msgid "SuperSonics|Paste your activation code"
msgstr ""
@@ -34956,6 +35675,12 @@ msgstr ""
msgid "SuperSonics|You do not have an active subscription"
msgstr ""
+msgid "SuperSonics|You have a future dated license"
+msgstr ""
+
+msgid "SuperSonics|You have added a license that activates on %{date}. Please see the subscription history table below for more details."
+msgstr ""
+
msgid "SuperSonics|You have successfully added a license that activates on %{date}. Please see the subscription history table below for more details."
msgstr ""
@@ -35115,6 +35840,9 @@ msgstr ""
msgid "Tag name is required"
msgstr ""
+msgid "Tag push"
+msgstr ""
+
msgid "Tag push events"
msgstr ""
@@ -35217,6 +35945,9 @@ msgstr ""
msgid "TagsPage|protected"
msgstr ""
+msgid "Take a look at the documentation to discover all of GitLab’s capabilities."
+msgstr ""
+
msgid "Target Branch"
msgstr ""
@@ -35619,6 +36350,9 @@ msgstr ""
msgid "Tests"
msgstr ""
+msgid "Text (optional)"
+msgstr ""
+
msgid "Text added to the body of all email messages. %{character_limit} character limit"
msgstr ""
@@ -35669,6 +36403,9 @@ msgstr ""
msgid "The CSV export will be created in the background. Once finished, it will be sent to %{email} in an attachment."
msgstr ""
+msgid "The CSV export you requested of all user memberships is attached to this email."
+msgstr ""
+
msgid "The GitLab subscription service (customers.gitlab.com) is currently experiencing an outage. You can monitor the status and get updates at %{linkStart}status.gitlab.com%{linkEnd}."
msgstr ""
@@ -35744,6 +36481,9 @@ 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 epic"
+msgstr ""
+
msgid "The current issue"
msgstr ""
@@ -35905,6 +36645,9 @@ msgstr ""
msgid "The latest pipeline for this merge request has failed."
msgstr ""
+msgid "The license key is invalid."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -35920,6 +36663,9 @@ msgstr ""
msgid "The license was successfully uploaded and will be active from %{starts_at}. You can see the details below."
msgstr ""
+msgid "The license you uploaded is invalid. If the issue persists, contact support at %{link}."
+msgstr ""
+
msgid "The list creation wizard is already open"
msgstr ""
@@ -36541,10 +37287,13 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} and everything this project contains. %{strongOpen}There is no going back%{strongClose}"
+msgstr ""
+
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains."
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}on %{date}%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains. %{strongOpen}There is no going back.%{strongClose}"
msgstr ""
msgid "This action will %{strongOpen}permanently remove%{strongClose} %{codeOpen}%{group}%{codeClose} %{strongOpen}immediately%{strongClose}."
@@ -36673,9 +37422,6 @@ msgstr ""
msgid "This file was modified for readability, and can't accept suggestions. Edit it directly."
msgstr ""
-msgid "This forked project has the following:"
-msgstr ""
-
msgid "This form is disabled in preview"
msgstr ""
@@ -36688,7 +37434,7 @@ msgstr ""
msgid "This group can't be removed because it is linked to a subscription. To remove this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
-msgid "This group can't be transfered because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
+msgid "This group can't be transferred because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
msgid "This group cannot be invited to a project inside a group with enforced SSO"
@@ -36715,6 +37461,9 @@ 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 incident is already escalated with '%{escalation_policy_name}'."
+msgstr ""
+
msgid "This invitation was sent to %{mail_to_invite_email}, but you are signed in as %{link_to_current_user} with email %{mail_to_current_user}."
msgstr ""
@@ -36733,9 +37482,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 merge train pipeline"
-msgstr ""
-
msgid "This is a private email address %{helpIcon} generated just for you. Anyone who has it can create issues or merge requests as if they were you. If that happens, %{resetLinkStart}reset this token%{resetLinkEnd}."
msgstr ""
@@ -36757,6 +37503,12 @@ msgstr ""
msgid "This is your current session"
msgstr ""
+msgid "This issue cannot be assigned to a confidential epic because it is public."
+msgstr ""
+
+msgid "This issue cannot be made public because it belongs to a confidential epic."
+msgstr ""
+
msgid "This issue is confidential and should only be visible to team members with at least Reporter access."
msgstr ""
@@ -36874,6 +37626,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 branch is protected from force push."
+msgstr ""
+
msgid "This merge request cannot be rebased while there are conflicts."
msgstr ""
@@ -36925,9 +37680,15 @@ msgstr ""
msgid "This pipeline was triggered by a schedule."
msgstr ""
+msgid "This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project"
msgstr ""
+msgid "This project can be restored until %{date}."
+msgstr ""
+
msgid "This project cannot be %{visibilityLevel} because the visibility of %{openShowLink}%{name}%{closeShowLink} is %{visibility}. To make this project %{visibilityLevel}, you must first %{openEditLink}change the visibility%{closeEditLink} of the parent group."
msgstr ""
@@ -36946,6 +37707,9 @@ msgstr ""
msgid "This project is %{strongStart}NOT%{strongEnd} a fork, and has the following:"
msgstr ""
+msgid "This project is %{strongStart}NOT%{strongEnd} a fork. This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -37637,6 +38401,9 @@ msgstr ""
msgid "Today"
msgstr ""
+msgid "Todos count"
+msgstr ""
+
msgid "Todos|Are you looking for things to do? Take a look at %{strongStart}%{openIssuesLinkStart}open issues%{openIssuesLinkEnd}%{strongEnd}, contribute to %{strongStart}%{mergeRequestLinkStart}a merge request%{mergeRequestLinkEnd}%{mergeRequestLinkEnd}%{strongEnd}, or mention someone in a comment to automatically assign them a new to-do item."
msgstr ""
@@ -37910,10 +38677,8 @@ msgstr ""
msgid "Trending"
msgstr ""
-msgid "Trials|%{planName} Trial %{enDash} %{num} day left"
-msgid_plural "Trials|%{planName} Trial %{enDash} %{num} days left"
-msgstr[0] ""
-msgstr[1] ""
+msgid "Trials|%{planName} Trial"
+msgstr ""
msgid "Trials|Compare all plans"
msgstr ""
@@ -37921,6 +38686,9 @@ msgstr ""
msgid "Trials|Create a new group to start your GitLab Ultimate trial."
msgstr ""
+msgid "Trials|Day %{daysUsed}/%{duration}"
+msgstr ""
+
msgid "Trials|Go back to GitLab"
msgstr ""
@@ -38170,7 +38938,7 @@ msgstr ""
msgid "URL is triggered when repository is updated"
msgstr ""
-msgid "URL must be percent-encoded if neccessary."
+msgid "URL must be percent-encoded if necessary."
msgstr ""
msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
@@ -38389,6 +39157,9 @@ msgstr ""
msgid "Unlock account"
msgstr ""
+msgid "Unlock more features with GitLab Ultimate"
+msgstr ""
+
msgid "Unlock the discussion"
msgstr ""
@@ -38452,6 +39223,9 @@ msgstr ""
msgid "Unsubscribes from this %{quick_action_target}."
msgstr ""
+msgid "Unsupported sort value."
+msgstr ""
+
msgid "Unsupported todo type passed. Supported todo types are: %{todo_types}"
msgstr ""
@@ -38680,6 +39454,9 @@ msgstr ""
msgid "UsageQuota|File attachments and smaller design graphics."
msgstr ""
+msgid "UsageQuota|From %{storage_enforcement_date} storage limits will apply to this namespace. View and manage your usage in %{strong_start}Group Settings &gt; Usage quotas%{strong_end}."
+msgstr ""
+
msgid "UsageQuota|Git repository."
msgstr ""
@@ -38740,6 +39517,9 @@ msgstr ""
msgid "UsageQuota|Storage type"
msgstr ""
+msgid "UsageQuota|Storage used"
+msgstr ""
+
msgid "UsageQuota|This is the total amount of storage used across your projects within this namespace."
msgstr ""
@@ -38935,6 +39715,12 @@ msgstr ""
msgid "Use hashed storage paths for newly created and renamed repositories. Always enabled since 13.0."
msgstr ""
+msgid "Use issue count"
+msgstr ""
+
+msgid "Use issue weight"
+msgstr ""
+
msgid "Use one line per URI"
msgstr ""
@@ -39316,6 +40102,9 @@ msgstr ""
msgid "Users"
msgstr ""
+msgid "Users API rate limit"
+msgstr ""
+
msgid "Users can launch a development environment from a GitLab browser tab when the %{linkStart}Gitpod%{linkEnd} integration is enabled."
msgstr ""
@@ -39641,6 +40430,9 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View group pipeline usage quota"
+msgstr ""
+
msgid "View incident details at"
msgstr ""
@@ -39793,6 +40585,9 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
+msgid "Vulnerability"
+msgstr ""
+
msgid "Vulnerability Report"
msgstr ""
@@ -39844,6 +40639,9 @@ msgstr ""
msgid "VulnerabilityManagement|An unverified non-confirmed finding"
msgstr ""
+msgid "VulnerabilityManagement|At least one identifier is required"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -39853,12 +40651,24 @@ msgstr ""
msgid "VulnerabilityManagement|Create Jira issue"
msgstr ""
+msgid "VulnerabilityManagement|Enter a name"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE code"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE identifier URL"
+msgstr ""
+
msgid "VulnerabilityManagement|Fetching linked Jira issues"
msgstr ""
msgid "VulnerabilityManagement|Manually add a vulnerability entry into the vulnerability report."
msgstr ""
+msgid "VulnerabilityManagement|Name is a required field"
+msgstr ""
+
msgid "VulnerabilityManagement|Needs triage"
msgstr ""
@@ -39874,6 +40684,18 @@ msgstr ""
msgid "VulnerabilityManagement|Select a method"
msgstr ""
+msgid "VulnerabilityManagement|Select a severity level"
+msgstr ""
+
+msgid "VulnerabilityManagement|Select a status"
+msgstr ""
+
+msgid "VulnerabilityManagement|Severity is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Something went wrong while creating vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -39898,6 +40720,12 @@ msgstr ""
msgid "VulnerabilityManagement|Something went wrong, could not update vulnerability state."
msgstr ""
+msgid "VulnerabilityManagement|Status is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Submit vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Summary, detailed description, steps to reproduce, etc."
msgstr ""
@@ -40093,6 +40921,9 @@ msgstr ""
msgid "WARNING:"
msgstr ""
+msgid "WARNING: This snippet contains hidden files which might be used to mask malicious behavior. Exercise caution if cloning and executing code from this snippet."
+msgstr ""
+
msgid "Wait for the file to load to copy its contents"
msgstr ""
@@ -40312,6 +41143,15 @@ msgstr ""
msgid "Webhooks|An issue is created, updated, closed, or reopened."
msgstr ""
+msgid "Webhooks|Are you sure you want to delete this group hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this project hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this webhook?"
+msgstr ""
+
msgid "Webhooks|Comments"
msgstr ""
@@ -40321,6 +41161,9 @@ msgstr ""
msgid "Webhooks|Confidential issues events"
msgstr ""
+msgid "Webhooks|Delete webhook"
+msgstr ""
+
msgid "Webhooks|Deployment events"
msgstr ""
@@ -40554,6 +41397,9 @@ msgstr ""
msgid "Wiki"
msgstr ""
+msgid "Wiki page"
+msgstr ""
+
msgid "Wiki page was successfully created."
msgstr ""
@@ -40659,7 +41505,7 @@ msgstr ""
msgid "WikiPageConflictMessage|Someone edited the page the same time you did. Please check out %{wikiLinkStart}the page%{wikiLinkEnd} and make sure your changes will not unintentionally remove theirs."
msgstr ""
-msgid "WikiPage|An error occured while trying to render the content editor. Please try again later."
+msgid "WikiPage|An error occurred while trying to render the content editor. Please try again later."
msgstr ""
msgid "WikiPage|Are you sure you want to switch back to the classic editor?"
@@ -40818,6 +41664,18 @@ msgstr ""
msgid "WorkItem|New Task"
msgstr ""
+msgid "WorkItem|Something went wrong when creating a work item. Please try again"
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching the work item. Please try again."
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching work item types. Please try again"
+msgstr ""
+
+msgid "WorkItem|Type"
+msgstr ""
+
msgid "WorkItem|Work Items"
msgstr ""
@@ -40884,7 +41742,10 @@ msgstr ""
msgid "You are about to add %{usersTag} people to the discussion. They will all receive a notification."
msgstr ""
-msgid "You are about to permanently delete this project"
+msgid "You are about to delete this forked project containing:"
+msgstr ""
+
+msgid "You are about to delete this project containing:"
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."
@@ -40905,6 +41766,9 @@ msgstr ""
msgid "You are attempting to update a file that has changed since you started editing it."
msgstr ""
+msgid "You are billed if you exceed this number. %{qsrOverageLinkStart}How does billing work?%{qsrOverageLinkEnd}"
+msgstr ""
+
msgid "You are connected to the Prometheus server, but there is currently no data to display."
msgstr ""
@@ -40962,6 +41826,9 @@ msgstr ""
msgid "You are not authorized to update this scanner profile"
msgstr ""
+msgid "You are not authorized to upload metric images"
+msgstr ""
+
msgid "You are now impersonating %{username}"
msgstr ""
@@ -41115,9 +41982,6 @@ msgstr ""
msgid "You can only upload one design when dropping onto an existing design."
msgstr ""
-msgid "You can recover this project until %{date}"
-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 ""
@@ -41166,9 +42030,6 @@ msgstr ""
msgid "You cannot write to this read-only GitLab instance."
msgstr ""
-msgid "You can’t %{tag_start}edit%{tag_end} files directly in this project. Fork this project and submit a merge request with your changes."
-msgstr ""
-
msgid "You can’t edit files directly in this project. Fork this project and submit a merge request with your changes."
msgstr ""
@@ -41321,9 +42182,6 @@ 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 set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
@@ -41354,12 +42212,6 @@ msgstr ""
msgid "You must have maintainer access to force delete a lock"
msgstr ""
-msgid "You must have permission to create a project in a group before forking."
-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 ""
@@ -41765,7 +42617,7 @@ msgstr ""
msgid "Your public email will be displayed on your public profile."
msgstr ""
-msgid "Your request for access could not be processed: %{error_meesage}"
+msgid "Your request for access could not be processed: %{error_message}"
msgstr ""
msgid "Your request for access has been queued for review."
@@ -41948,6 +42800,9 @@ msgstr ""
msgid "archived:"
msgstr ""
+msgid "artifacts"
+msgstr ""
+
msgid "assign yourself"
msgstr ""
@@ -41977,6 +42832,9 @@ msgstr[1] ""
msgid "branch name"
msgstr ""
+msgid "builds"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -42400,6 +43258,9 @@ msgstr ""
msgid "contact with same email already exists in group hierarchy"
msgstr ""
+msgid "container registry images"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -42439,6 +43300,9 @@ msgstr ""
msgid "data"
msgstr ""
+msgid "database"
+msgstr ""
+
msgid "date must not be after 9999-12-31"
msgstr ""
@@ -42462,9 +43326,6 @@ msgstr ""
msgid "design"
msgstr ""
-msgid "detached"
-msgstr ""
-
msgid "disabled"
msgstr ""
@@ -42713,7 +43574,7 @@ msgstr ""
msgid "is not a valid X509 certificate."
msgstr ""
-msgid "is not allowed for sign-up."
+msgid "is not allowed for sign-up. Please use your regular email address."
msgstr ""
msgid "is not allowed for this group."
@@ -42725,7 +43586,7 @@ msgstr ""
msgid "is not allowed since the group is not top-level group."
msgstr ""
-msgid "is not allowed."
+msgid "is not allowed. Please use your regular email address."
msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
@@ -42812,6 +43673,9 @@ msgstr ""
msgid "level: %{level}"
msgstr ""
+msgid "lfs objects"
+msgstr ""
+
msgid "limit of %{project_limit} reached"
msgstr ""
@@ -43031,6 +43895,9 @@ msgstr ""
msgid "mrWidget|Merge blocked: pipeline must succeed. It's waiting for a manual action to continue."
msgstr ""
+msgid "mrWidget|Merge blocked: pipeline must succeed. Push a commit that fixes the failure, or %{linkStart}learn about other solutions.%{linkEnd}"
+msgstr ""
+
msgid "mrWidget|Merge blocked: this merge request must be approved."
msgstr ""
@@ -43148,9 +44015,6 @@ msgstr ""
msgid "mrWidget|The changes were not merged into"
msgstr ""
-msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -43298,9 +44162,6 @@ msgstr ""
msgid "open issue"
msgstr ""
-msgid "opened %{timeAgo}"
-msgstr ""
-
msgid "or"
msgstr ""
@@ -43312,6 +44173,12 @@ msgid_plural "out of %d total tests"
msgstr[0] ""
msgstr[1] ""
+msgid "packages"
+msgstr ""
+
+msgid "pages"
+msgstr ""
+
msgid "parent"
msgid_plural "parents"
msgstr[0] ""
@@ -43461,6 +44328,9 @@ msgid_plural "replies"
msgstr[0] ""
msgstr[1] ""
+msgid "repositories"
+msgstr ""
+
msgid "repository:"
msgstr ""
@@ -43581,12 +44451,18 @@ msgstr ""
msgid "tag name"
msgstr ""
+msgid "terraform states"
+msgstr ""
+
msgid "the correct format."
msgstr ""
msgid "the file"
msgstr ""
+msgid "the following epic(s)"
+msgstr ""
+
msgid "the following issue(s)"
msgstr ""
@@ -43599,21 +44475,12 @@ msgstr ""
msgid "this document"
msgstr ""
-msgid "this issue cannot be assigned to a confidential epic since it is public"
-msgstr ""
-
-msgid "this issue cannot be made public since it belongs to a confidential epic"
-msgstr ""
-
msgid "time summary"
msgstr ""
msgid "toggle collapse"
msgstr ""
-msgid "train"
-msgstr ""
-
msgid "triggered"
msgstr ""
@@ -43742,3 +44609,6 @@ msgstr ""
msgid "{project}"
msgstr ""
+msgid "✔"
+msgstr ""
+
diff --git a/locale/kab/gitlab.po b/locale/kab/gitlab.po
index 0916e772d41..b93d8cfc8da 100644
--- a/locale/kab/gitlab.po
+++ b/locale/kab/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: kab\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2022-02-02 15:49\n"
+"PO-Revision-Date: 2022-03-01 20:41\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -146,6 +146,11 @@ msgid_plural "%d approvers (you've approved)"
msgstr[0] ""
msgstr[1] ""
+msgid "%d assigned issue"
+msgid_plural "%d assigned issues"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -421,8 +426,23 @@ msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
msgstr[1] ""
-msgid "%d vulnerability updated"
-msgid_plural "%d vulnerabilities updated"
+msgid "%d vulnerability set to confirmed"
+msgid_plural "%d vulnerabilities set to confirmed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to dismissed"
+msgid_plural "%d vulnerabilities set to dismissed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to needs triage"
+msgid_plural "%d vulnerabilities set to needs triage"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to resolved"
+msgid_plural "%d vulnerabilities set to resolved"
msgstr[0] ""
msgstr[1] ""
@@ -510,6 +530,12 @@ msgstr[1] ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{completed} of %{total} issues closed"
+msgstr ""
+
+msgid "%{completed} of %{total} weight completed"
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -858,6 +884,9 @@ msgstr ""
msgid "%{openedIssues} open, %{closedIssues} closed"
msgstr ""
+msgid "%{percentage}%% issues closed"
+msgstr ""
+
msgid "%{percentage}%% weight completed"
msgstr ""
@@ -1287,6 +1316,9 @@ msgid_plural "- Users"
msgstr[0] ""
msgstr[1] ""
+msgid "- of - issues closed"
+msgstr ""
+
msgid "- of - weight completed"
msgstr ""
@@ -1429,7 +1461,7 @@ msgstr ""
msgid "1000+"
msgstr ""
-msgid "192.168.0.0/24"
+msgid "192.168.0.0/24 or 2001:0DB8:1234::/48"
msgstr ""
msgid "1st contribution!"
@@ -1741,13 +1773,13 @@ msgstr ""
msgid "AWS Access Key"
msgstr ""
-msgid "AWS Access Key. Only required if not using role instance credentials"
+msgid "AWS Secret Access Key"
msgstr ""
-msgid "AWS Secret Access Key"
+msgid "AWS access key ID (Optional)"
msgstr ""
-msgid "AWS Secret Access Key. Only required if not using role instance credentials"
+msgid "AWS secret access key (Optional)"
msgstr ""
msgid "AWS service error: %{error}"
@@ -1807,9 +1839,6 @@ msgstr ""
msgid "Access granted"
msgstr ""
-msgid "Access key ID"
-msgstr ""
-
msgid "Access requests"
msgstr ""
@@ -1984,7 +2013,7 @@ msgstr ""
msgid "Activity"
msgstr ""
-msgid "Activity|An error occured while retrieving activity. Reload the page to try again."
+msgid "Activity|An error occurred while retrieving activity. Reload the page to try again."
msgstr ""
msgid "Add"
@@ -2023,6 +2052,9 @@ msgstr ""
msgid "Add a %{type}"
msgstr ""
+msgid "Add a GCP region"
+msgstr ""
+
msgid "Add a GPG key"
msgstr ""
@@ -2074,6 +2106,9 @@ msgstr ""
msgid "Add a numbered list"
msgstr ""
+msgid "Add a related epic"
+msgstr ""
+
msgid "Add a related issue"
msgstr ""
@@ -2188,6 +2223,9 @@ msgstr ""
msgid "Add or subtract spent time"
msgstr ""
+msgid "Add people"
+msgstr ""
+
msgid "Add previously merged commits"
msgstr ""
@@ -2254,6 +2292,9 @@ msgstr ""
msgid "Add webhook"
msgstr ""
+msgid "Add your team members and others to GitLab."
+msgstr ""
+
msgid "Add/remove"
msgstr ""
@@ -3076,12 +3117,6 @@ msgstr ""
msgid "AdvancedSearch|Reindex required"
msgstr ""
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. Permanently deleting this project will %{strongStart}immediately delete%{strongEnd} its repositories and %{strongStart}all related resources%{strongEnd}, including issues, merge requests etc."
-msgstr ""
-
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. You will lose this project's repository and %{strongStart}all related resources%{strongEnd}, including issues and merge requests."
-msgstr ""
-
msgid "After a successful password update you will be redirected to login screen."
msgstr ""
@@ -3112,6 +3147,9 @@ msgstr ""
msgid "Akismet helps prevent the creation of spam issues in public projects."
msgstr ""
+msgid "Alert"
+msgstr ""
+
msgid "AlertManagement|Acknowledged"
msgstr ""
@@ -3484,9 +3522,6 @@ msgstr ""
msgid "All environments"
msgstr ""
-msgid "All epics"
-msgstr ""
-
msgid "All groups and projects"
msgstr ""
@@ -4223,12 +4258,15 @@ msgstr ""
msgid "ApplicationSettings|Approve users in the pending approval status?"
msgstr ""
-msgid "ApplicationSettings|By making this change, you will automatically approve %d user with the pending approval status."
-msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users with the pending approval status."
+msgid "ApplicationSettings|Approve users who are pending approval?"
+msgstr ""
+
+msgid "ApplicationSettings|By making this change, you will automatically approve %d user who is pending approval."
+msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users who are pending approval."
msgstr[0] ""
msgstr[1] ""
-msgid "ApplicationSettings|By making this change, you will automatically approve all users in pending approval status."
+msgid "ApplicationSettings|By making this change, you will automatically approve all users who are pending approval."
msgstr ""
msgid "ApplicationSettings|Denied domains for sign-ups"
@@ -4634,10 +4672,10 @@ msgstr ""
msgid "Archiving the project will make it entirely read-only. It is hidden from the dashboard and doesn't show up in searches. %{strong_start}The repository cannot be committed to, and no issues, comments, or other entities can be created.%{strong_end} %{link_start}Learn more.%{link_end}"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to delete this project?"
+msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
+msgid "Are you absolutely sure?"
msgstr ""
msgid "Are you sure that you want to archive this project?"
@@ -4673,12 +4711,18 @@ msgstr ""
msgid "Are you sure you want to delete this SSH key?"
msgstr ""
+msgid "Are you sure you want to delete this comment?"
+msgstr ""
+
msgid "Are you sure you want to delete this deploy key?"
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 label?"
+msgstr ""
+
msgid "Are you sure you want to delete this pipeline schedule?"
msgstr ""
@@ -4694,9 +4738,6 @@ msgstr ""
msgid "Are you sure you want to discard your changes?"
msgstr ""
-msgid "Are you sure you want to erase this build?"
-msgstr ""
-
msgid "Are you sure you want to import %d repository?"
msgid_plural "Are you sure you want to import %d repositories?"
msgstr[0] ""
@@ -4744,6 +4785,9 @@ msgstr ""
msgid "Are you sure you want to remove this list?"
msgstr ""
+msgid "Are you sure you want to remove this nickname?"
+msgstr ""
+
msgid "Are you sure you want to reset the health check token?"
msgstr ""
@@ -4756,10 +4800,10 @@ 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?"
+msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
msgstr ""
-msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
+msgid "Are you sure you want to revoke this project access token? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to stop this environment?"
@@ -4906,9 +4950,6 @@ msgstr ""
msgid "Assigned to %{assignee_name}"
msgstr ""
-msgid "Assigned to %{name}"
-msgstr ""
-
msgid "Assigned to me"
msgstr ""
@@ -4973,6 +5014,9 @@ msgstr[1] ""
msgid "Attaching the file failed."
msgstr ""
+msgid "Attention"
+msgstr ""
+
msgid "Audit Events"
msgstr ""
@@ -5135,6 +5179,12 @@ msgstr ""
msgid "Authorized applications (%{size})"
msgstr ""
+msgid "AuthorizedApplication|Are you sure you want to revoke this application?"
+msgstr ""
+
+msgid "AuthorizedApplication|Revoke application"
+msgstr ""
+
msgid "Authors: %{authors}"
msgstr ""
@@ -6328,6 +6378,9 @@ msgstr ""
msgid "CICDAnalytics|Shared Runners Usage"
msgstr ""
+msgid "CICDAnalytics|Shared runner pipeline minute duration by month"
+msgstr ""
+
msgid "CICDAnalytics|Shared runner usage"
msgstr ""
@@ -6469,6 +6522,9 @@ msgstr ""
msgid "Can create groups:"
msgstr ""
+msgid "Can not delete primary training"
+msgstr ""
+
msgid "Can't apply as the source branch was deleted."
msgstr ""
@@ -6802,9 +6858,6 @@ msgstr ""
msgid "Changing any setting here requires an application restart"
msgstr ""
-msgid "Changing group URL can have unintended side effects."
-msgstr ""
-
msgid "Charts can't be displayed as the request for data has timed out. %{documentationLink}"
msgstr ""
@@ -6892,9 +6945,6 @@ msgstr ""
msgid "Checking branch availability..."
msgstr ""
-msgid "Checking group URL availability..."
-msgstr ""
-
msgid "Checking group path availability..."
msgstr ""
@@ -7388,6 +7438,9 @@ msgstr ""
msgid "Clear recent searches"
msgstr ""
+msgid "Clear repository checks"
+msgstr ""
+
msgid "Clear search"
msgstr ""
@@ -7520,9 +7573,6 @@ msgstr ""
msgid "Closed MRs"
msgstr ""
-msgid "Closed epics"
-msgstr ""
-
msgid "Closed issues"
msgstr ""
@@ -7559,13 +7609,13 @@ msgstr ""
msgid "Cluster level"
msgstr ""
-msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
+msgid "Cluster type must be specified for Stages::ClusterEndpointInserter"
msgstr ""
msgid "ClusterAgents|%{name} successfully deleted"
msgstr ""
-msgid "ClusterAgents|%{number} of %{total} Agents"
+msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
@@ -7607,6 +7657,15 @@ msgstr ""
msgid "ClusterAgents|Agent never connected to GitLab"
msgstr ""
+msgid "ClusterAgents|Agent version mismatch"
+msgstr ""
+
+msgid "ClusterAgents|Agent version mismatch and update"
+msgstr ""
+
+msgid "ClusterAgents|Agent version update required"
+msgstr ""
+
msgid "ClusterAgents|All"
msgstr ""
@@ -7631,7 +7690,7 @@ msgstr ""
msgid "ClusterAgents|Configuration"
msgstr ""
-msgid "ClusterAgents|Connect a cluster through the Agent"
+msgid "ClusterAgents|Connect a cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connect existing cluster"
@@ -7640,13 +7699,13 @@ msgstr ""
msgid "ClusterAgents|Connect with a certificate"
msgstr ""
-msgid "ClusterAgents|Connect with agent"
+msgid "ClusterAgents|Connect with an agent"
msgstr ""
msgid "ClusterAgents|Connect with the GitLab Agent"
msgstr ""
-msgid "ClusterAgents|Connect your cluster through the Agent"
+msgid "ClusterAgents|Connect your cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connected"
@@ -7706,7 +7765,10 @@ msgstr ""
msgid "ClusterAgents|How to register an agent?"
msgstr ""
-msgid "ClusterAgents|Install new Agent"
+msgid "ClusterAgents|How to update an agent?"
+msgstr ""
+
+msgid "ClusterAgents|Install a new agent"
msgstr ""
msgid "ClusterAgents|Last connected %{timeAgo}."
@@ -7733,7 +7795,7 @@ msgstr ""
msgid "ClusterAgents|Never connected"
msgstr ""
-msgid "ClusterAgents|No Agents"
+msgid "ClusterAgents|No agents"
msgstr ""
msgid "ClusterAgents|No clusters connected through cluster certificates"
@@ -7793,6 +7855,9 @@ msgstr ""
msgid "ClusterAgents|The agent has not been connected in a long time. There might be a connectivity issue. Last contact was %{timeAgo}."
msgstr ""
+msgid "ClusterAgents|The agent version do not match each other across your cluster's pods. This can happen when a new agent version was just deployed and Kubernetes is shutting down the old pods."
+msgstr ""
+
msgid "ClusterAgents|The recommended installation method includes the token. If you want to follow the advanced installation method provided in the docs, make sure you save the token value before you close this window."
msgstr ""
@@ -7840,6 +7905,9 @@ msgstr ""
msgid "ClusterAgents|You will need to create a token to connect to your agent"
msgstr ""
+msgid "ClusterAgents|Your agent version is out of sync with your GitLab version (v%{version}), which might cause compatibility problems. Update the agent installed on your cluster to the most recent version."
+msgstr ""
+
msgid "ClusterAgents|Your instance doesn't have the %{linkStart}GitLab Agent Server (KAS)%{linkEnd} set up. Ask a GitLab Administrator to install it."
msgstr ""
@@ -8716,9 +8784,6 @@ msgstr ""
msgid "Comma-separated list of email addresses."
msgstr ""
-msgid "Comma-separated list of users allowed to exceed the rate limit."
-msgstr ""
-
msgid "Comma-separated, e.g. '1.1.1.1, 2.2.2.0/24'"
msgstr ""
@@ -9045,6 +9110,12 @@ msgstr ""
msgid "Confidential"
msgstr ""
+msgid "Confidential issue"
+msgstr ""
+
+msgid "Confidential note"
+msgstr ""
+
msgid "Confidentiality"
msgstr ""
@@ -9078,6 +9149,9 @@ msgstr ""
msgid "Configure Dependency Scanning in `.gitlab-ci.yml`, creating this file if it does not already exist"
msgstr ""
+msgid "Configure GitLab"
+msgstr ""
+
msgid "Configure GitLab runners to start using the Web Terminal. %{helpStart}Learn more.%{helpEnd}"
msgstr ""
@@ -9126,6 +9200,15 @@ msgstr ""
msgid "Configure pipelines to deploy web apps, backend services, APIs and static resources to Google Cloud"
msgstr ""
+msgid "Configure region"
+msgstr ""
+
+msgid "Configure region for environment"
+msgstr ""
+
+msgid "Configure regions"
+msgstr ""
+
msgid "Configure repository mirroring."
msgstr ""
@@ -9159,6 +9242,9 @@ msgstr ""
msgid "Configure which lists are shown for anyone who visits this board"
msgstr ""
+msgid "Configure your environments to be deployed to specific geographical regions"
+msgstr ""
+
msgid "Confirm"
msgstr ""
@@ -9861,10 +9947,10 @@ msgstr ""
msgid "CorpusManagement|Actions"
msgstr ""
-msgid "CorpusManagement|Corpus are used in fuzz testing as mutation source to Improve future testing."
+msgid "CorpusManagement|Corpus file"
msgstr ""
-msgid "CorpusManagement|Corpus file"
+msgid "CorpusManagement|Corpus files are used in coverage-guided fuzz testing as seed inputs to improve testing."
msgstr ""
msgid "CorpusManagement|Corpus files must be in *.zip format. Maximum 5 GB"
@@ -9918,6 +10004,9 @@ msgstr ""
msgid "Could not apply %{name} command."
msgstr ""
+msgid "Could not apply %{name} command. %{message}."
+msgstr ""
+
msgid "Could not authorize chat nickname. Try again!"
msgstr ""
@@ -10068,6 +10157,9 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
+msgid "Create a group"
+msgstr ""
+
msgid "Create a merge request"
msgstr ""
@@ -10092,6 +10184,9 @@ msgstr ""
msgid "Create a personal access token on your account to pull or push via %{protocol}."
msgstr ""
+msgid "Create a project"
+msgstr ""
+
msgid "Create an account using:"
msgstr ""
@@ -10455,6 +10550,9 @@ msgstr ""
msgid "Creation date"
msgstr ""
+msgid "Creator"
+msgstr ""
+
msgid "Credentials"
msgstr ""
@@ -10467,9 +10565,15 @@ msgstr ""
msgid "CredentialsInventory|Personal Access Tokens"
msgstr ""
+msgid "CredentialsInventory|Project Access Tokens"
+msgstr ""
+
msgid "CredentialsInventory|SSH Keys"
msgstr ""
+msgid "Credit card required to be on file in order to create a pipeline"
+msgstr ""
+
msgid "Credit card:"
msgstr ""
@@ -10653,9 +10757,6 @@ msgstr ""
msgid "Customer relations"
msgstr ""
-msgid "Customizable by an administrator."
-msgstr ""
-
msgid "Customizable by owners."
msgstr ""
@@ -10785,30 +10886,18 @@ msgstr ""
msgid "CycleAnalytics|%{selectedLabelsCount} selected (%{maxLabels} max)"
msgstr ""
-msgid "CycleAnalytics|%{stageCount} stages selected"
-msgstr ""
-
-msgid "CycleAnalytics|All stages"
-msgstr ""
-
-msgid "CycleAnalytics|Average days to completion"
+msgid "CycleAnalytics|Average time to completion"
msgstr ""
msgid "CycleAnalytics|Date"
msgstr ""
-msgid "CycleAnalytics|Days to completion"
-msgstr ""
-
msgid "CycleAnalytics|Display chart filters"
msgstr ""
msgid "CycleAnalytics|Lead Time for Changes"
msgstr ""
-msgid "CycleAnalytics|No stages selected"
-msgstr ""
-
msgid "CycleAnalytics|Number of tasks"
msgstr ""
@@ -10837,18 +10926,30 @@ msgstr ""
msgid "CycleAnalytics|Showing data for group '%{groupName}' from %{createdAfter} to %{createdBefore}"
msgstr ""
-msgid "CycleAnalytics|Stages"
+msgid "CycleAnalytics|Stage time: %{title}"
msgstr ""
msgid "CycleAnalytics|Tasks by type"
msgstr ""
-msgid "CycleAnalytics|The average time spent in the selected stage for the items that were completed on each date. Data limited to the last 500 items."
+msgid "CycleAnalytics|The average time items spent in this stage. Data limited to items completed within this date range."
msgstr ""
msgid "CycleAnalytics|The given date range is larger than 180 days"
msgstr ""
+msgid "CycleAnalytics|The total time items spent across each value stream stage. Data limited to items completed within this date range."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Stage time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Total time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|Total time"
+msgstr ""
+
msgid "CycleAnalytics|Type of work"
msgstr ""
@@ -10861,9 +10962,6 @@ msgstr ""
msgid "CycleAnalytics|project dropdown filter"
msgstr ""
-msgid "CycleAnalytics|stage dropdown"
-msgstr ""
-
msgid "DAG visualization requires at least 3 dependent jobs."
msgstr ""
@@ -10963,10 +11061,16 @@ msgstr ""
msgid "DastProfiles|AJAX spider"
msgstr ""
+msgid "DastProfiles|API"
+msgstr ""
+
+msgid "DastProfiles|API endpoint URL"
+msgstr ""
+
msgid "DastProfiles|Active"
msgstr ""
-msgid "DastProfiles|Additional request headers (Optional)"
+msgid "DastProfiles|Additional request headers (optional)"
msgstr ""
msgid "DastProfiles|Are you sure you want to delete this profile?"
@@ -10981,6 +11085,9 @@ msgstr ""
msgid "DastProfiles|Branch missing"
msgstr ""
+msgid "DastProfiles|Choose a scan method"
+msgstr ""
+
msgid "DastProfiles|Could not create the scanner profile. Please try again."
msgstr ""
@@ -11050,7 +11157,13 @@ msgstr ""
msgid "DastProfiles|Excluded URLs"
msgstr ""
-msgid "DastProfiles|Excluded URLs (Optional)"
+msgid "DastProfiles|Excluded URLs (optional)"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths (optional)"
msgstr ""
msgid "DastProfiles|Hide debug messages"
@@ -11107,9 +11220,6 @@ msgstr ""
msgid "DastProfiles|Request headers"
msgstr ""
-msgid "DastProfiles|Rest API"
-msgstr ""
-
msgid "DastProfiles|Run the AJAX spider, in addition to the traditional spider, to crawl the target site."
msgstr ""
@@ -11119,6 +11229,9 @@ msgstr ""
msgid "DastProfiles|Save profile"
msgstr ""
+msgid "DastProfiles|Scan method"
+msgstr ""
+
msgid "DastProfiles|Scan mode"
msgstr ""
@@ -11197,12 +11310,24 @@ msgstr ""
msgid "DastProfiles|Website"
msgstr ""
+msgid "DastProfiles|What does each method do?"
+msgstr ""
+
msgid "DastProfiles|You can either choose a passive scan or validate the target site from the site profile management page. %{docsLinkStart}Learn more about site validation.%{docsLinkEnd}"
msgstr ""
msgid "DastProfiles|You cannot run an active scan against an unvalidated site."
msgstr ""
+msgid "DastProfiles|folder/dast_example.har or https://example.com/dast_example.har"
+msgstr ""
+
+msgid "DastProfiles|folder/example.postman_collection.json or https://example.com/"
+msgstr ""
+
+msgid "DastProfiles|folder/openapi.json or https://example.com/openapi.json"
+msgstr ""
+
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
@@ -11310,6 +11435,9 @@ msgstr ""
msgid "DatadogIntegration|API URL"
msgstr ""
+msgid "DatadogIntegration|Custom tags in Datadog. Enter one tag per line in the %{codeOpen}key:value%{codeClose} format. %{linkOpen}How do I use tags?%{linkClose}"
+msgstr ""
+
msgid "DatadogIntegration|Environment"
msgstr ""
@@ -11328,12 +11456,18 @@ msgstr ""
msgid "DatadogIntegration|Tag all data from this GitLab instance in Datadog. Useful when managing several self-managed deployments."
msgstr ""
+msgid "DatadogIntegration|Tags"
+msgstr ""
+
msgid "DatadogIntegration|The Datadog site to send data to. To send data to the EU site, use %{codeOpen}datadoghq.eu%{codeClose}."
msgstr ""
msgid "DatadogIntegration|Trace your GitLab pipelines with Datadog."
msgstr ""
+msgid "DatadogIntegration|have an invalid format"
+msgstr ""
+
msgid "Datasource name not found"
msgstr ""
@@ -11343,9 +11477,6 @@ msgstr ""
msgid "Date merged"
msgstr ""
-msgid "Date picker"
-msgstr ""
-
msgid "Date range"
msgstr ""
@@ -11499,9 +11630,6 @@ msgstr ""
msgid "Definition"
msgstr ""
-msgid "Delayed Project Deletion (%{adjourned_deletion})"
-msgstr ""
-
msgid "DelayedJobs|Are you sure you want to run %{jobName} immediately? Otherwise this job will run automatically after its timer finishes."
msgstr ""
@@ -11580,10 +11708,10 @@ msgstr ""
msgid "Delete pipeline"
msgstr ""
-msgid "Delete project"
+msgid "Delete pipeline schedule"
msgstr ""
-msgid "Delete project. Are you ABSOLUTELY SURE?"
+msgid "Delete project"
msgstr ""
msgid "Delete row"
@@ -11613,6 +11741,9 @@ msgstr ""
msgid "Delete this epic and all descendants?"
msgstr ""
+msgid "Delete this project"
+msgstr ""
+
msgid "Delete user list"
msgstr ""
@@ -11871,6 +12002,12 @@ msgstr ""
msgid "Deploy to..."
msgstr ""
+msgid "DeployBoards|To see deployment progress for your environments, make sure you are deploying to %{codeStart}$KUBE_NAMESPACE%{codeEnd} and annotating with %{codeStart}app.gitlab.com/app=$CI_PROJECT_PATH_SLUG%{codeEnd} and %{codeStart}app.gitlab.com/env=$CI_ENVIRONMENT_SLUG%{codeEnd}."
+msgstr ""
+
+msgid "DeployBoard|Kubernetes Pods"
+msgstr ""
+
msgid "DeployFreeze|Add a freeze period to prevent unintended releases during a period of time for a given environment. You must update the deployment jobs in %{filename} according to the deploy freezes added here. %{freeze_period_link_start}Learn more.%{freeze_period_link_end}"
msgstr ""
@@ -11955,9 +12092,6 @@ msgstr ""
msgid "DeployTokens|Active Deploy Tokens (%{active_tokens})"
msgstr ""
-msgid "DeployTokens|Allows read and write access to registry images."
-msgstr ""
-
msgid "DeployTokens|Allows read and write access to the package registry."
msgstr ""
@@ -11970,6 +12104,9 @@ msgstr ""
msgid "DeployTokens|Allows read-only access to the repository."
msgstr ""
+msgid "DeployTokens|Allows write access to registry images."
+msgstr ""
+
msgid "DeployTokens|Copy deploy token"
msgstr ""
@@ -12063,12 +12200,57 @@ msgstr ""
msgid "Deploying to AWS is easy with GitLab"
msgstr ""
+msgid "Deployment"
+msgstr ""
+
msgid "Deployment Frequency"
msgstr ""
+msgid "Deployment Target|Project deployment target (optional)"
+msgstr ""
+
+msgid "Deployment Target|Select the deployment target"
+msgstr ""
+
msgid "Deployment frequency"
msgstr ""
+msgid "DeploymentTarget|GitLab Pages"
+msgstr ""
+
+msgid "DeploymentTarget|Heroku"
+msgstr ""
+
+msgid "DeploymentTarget|Infrastructure provider (Terraform, Cloudformation, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Kubernetes (GKE, EKS, OpenShift, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Managed container runtime (Fargate, Cloud Run, DigitalOcean App)"
+msgstr ""
+
+msgid "DeploymentTarget|Mobile app store"
+msgstr ""
+
+msgid "DeploymentTarget|No deployment planned"
+msgstr ""
+
+msgid "DeploymentTarget|Other hosting service"
+msgstr ""
+
+msgid "DeploymentTarget|Registry (package or container)"
+msgstr ""
+
+msgid "DeploymentTarget|Self-managed container runtime (Podman, Docker Swarm, Docker Compose)"
+msgstr ""
+
+msgid "DeploymentTarget|Serverless backend (Lambda, Cloud functions)"
+msgstr ""
+
+msgid "DeploymentTarget|Virtual machine (for example, EC2)"
+msgstr ""
+
msgid "Deployments"
msgstr ""
@@ -12107,6 +12289,9 @@ msgstr ""
msgid "Deployment|This deployment was created using the API"
msgstr ""
+msgid "Deployment|Triggerer"
+msgstr ""
+
msgid "Deployment|Waiting"
msgstr ""
@@ -12134,6 +12319,18 @@ msgstr ""
msgid "Deprecated API rate limits"
msgstr ""
+msgid "Deprecations|Feature deprecation and removal"
+msgstr ""
+
+msgid "Deprecations|For information on a possible replacement %{epicStart} learn more about Opstrace %{epicEnd}."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7 and are %{epicStart} scheduled for removal %{epicEnd} in GitLab 15.0."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7, and are %{removal_link_start} scheduled for removal %{link_end} in GitLab 15.0. For information on a possible replacement, %{opstrace_link_start} learn more about Opstrace %{link_end}."
+msgstr ""
+
msgid "Deprioritize label"
msgstr ""
@@ -12379,10 +12576,10 @@ msgstr ""
msgid "DevopsAdoption|At least one deploy"
msgstr ""
-msgid "DevopsAdoption|At least one issue opened"
+msgid "DevopsAdoption|At least one issue created"
msgstr ""
-msgid "DevopsAdoption|At least one merge request opened"
+msgid "DevopsAdoption|At least one merge request created"
msgstr ""
msgid "DevopsAdoption|At least one pipeline successfully run"
@@ -12583,6 +12780,9 @@ msgstr ""
msgid "Direct member"
msgstr ""
+msgid "Direct members"
+msgstr ""
+
msgid "Direct non-authenticated users to this page."
msgstr ""
@@ -12699,6 +12899,9 @@ msgid_plural "Dismiss %d selected vulnerabilities as"
msgstr[0] ""
msgstr[1] ""
+msgid "Dismiss Alert"
+msgstr ""
+
msgid "Dismiss merge request promotion"
msgstr ""
@@ -12726,9 +12929,15 @@ msgstr ""
msgid "Display alerts from all configured monitoring tools."
msgstr ""
+msgid "Display milestones"
+msgstr ""
+
msgid "Display name"
msgstr ""
+msgid "Display progress of child issues"
+msgstr ""
+
msgid "Display rendered file"
msgstr ""
@@ -12834,6 +13043,9 @@ msgstr ""
msgid "Download image"
msgstr ""
+msgid "Download payload"
+msgstr ""
+
msgid "Download raw data (.csv)"
msgstr ""
@@ -13011,6 +13223,9 @@ msgstr ""
msgid "Edit in Web IDE"
msgstr ""
+msgid "Edit in pipeline editor"
+msgstr ""
+
msgid "Edit in single-file editor"
msgstr ""
@@ -13053,6 +13268,9 @@ msgstr ""
msgid "Edit your most recent comment in a thread (from an empty textarea)"
msgstr ""
+msgid "Edit, lint, and visualize your pipeline."
+msgstr ""
+
msgid "Edited"
msgstr ""
@@ -13494,6 +13712,9 @@ msgstr ""
msgid "Enforce two-factor authentication for all user sign-ins."
msgstr ""
+msgid "Enhance security by storing service account keys in secret managers - learn more about %{docLinkStart}secret management with GitLab%{docLinkEnd}"
+msgstr ""
+
msgid "Ensure connectivity is available from the GitLab server to the Prometheus server"
msgstr ""
@@ -13554,6 +13775,9 @@ 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 following to confirm:"
+msgstr ""
+
msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
@@ -14084,9 +14308,6 @@ 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 ""
@@ -14222,6 +14443,9 @@ msgstr ""
msgid "Errors:"
msgstr ""
+msgid "Escalate this incident"
+msgstr ""
+
msgid "Escalation Policies"
msgstr ""
@@ -14234,6 +14458,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy"
+msgstr ""
+
msgid "Escalation policy:"
msgstr ""
@@ -14485,6 +14712,9 @@ msgstr ""
msgid "Existing sign in methods may be removed"
msgstr ""
+msgid "Exit."
+msgstr ""
+
msgid "Expand"
msgstr ""
@@ -14581,6 +14811,9 @@ msgstr ""
msgid "Explore public groups"
msgstr ""
+msgid "Explore public projects"
+msgstr ""
+
msgid "Explore snippets"
msgstr ""
@@ -14742,7 +14975,7 @@ msgid_plural "Failed to archive designs. Please try again."
msgstr[0] ""
msgstr[1] ""
-msgid "Failed to assign a reviewer because no user was found."
+msgid "Failed to assign a reviewer because no user was specified."
msgstr ""
msgid "Failed to assign a user because no user was found."
@@ -14808,10 +15041,10 @@ msgstr ""
msgid "Failed to find import label for Jira import."
msgstr ""
-msgid "Failed to generate export, please try again later."
+msgid "Failed to find users for %{missing}"
msgstr ""
-msgid "Failed to generate report, please try again after sometime"
+msgid "Failed to generate export, please try again later."
msgstr ""
msgid "Failed to get ref."
@@ -14910,6 +15143,9 @@ msgstr ""
msgid "Failed to remove a to-do item for the design."
msgstr ""
+msgid "Failed to remove attention because no user was found."
+msgstr ""
+
msgid "Failed to remove mirror."
msgstr ""
@@ -14922,6 +15158,9 @@ msgstr ""
msgid "Failed to remove user key."
msgstr ""
+msgid "Failed to request attention because no user was found."
+msgstr ""
+
msgid "Failed to reset key. Please try again."
msgstr ""
@@ -15003,6 +15242,9 @@ msgstr ""
msgid "Feature Flags"
msgstr ""
+msgid "Feature deprecation and removal"
+msgstr ""
+
msgid "Feature flag status"
msgstr ""
@@ -15500,7 +15742,7 @@ msgstr ""
msgid "For each job, re-use the project workspace. If the workspace doesn't exist, use %{code_open}git clone%{code_close}."
msgstr ""
-msgid "For example, the application using the token or the purpose of the token."
+msgid "For example, the application using the token or the purpose of the token. Do not give sensitive information for the name of the token, as it will be visible to all %{resource_type} members."
msgstr ""
msgid "For files larger than this limit, only index the file name. The file content is neither indexed nor searchable."
@@ -15584,9 +15826,6 @@ msgstr ""
msgid "ForkProject|Select a namespace"
msgstr ""
-msgid "ForkProject|Select a namespace to fork the project"
-msgstr ""
-
msgid "ForkProject|The project can be accessed by any logged in user."
msgstr ""
@@ -15683,6 +15922,9 @@ msgstr ""
msgid "Full name"
msgstr ""
+msgid "GCP region configured"
+msgstr ""
+
msgid "GPG Key ID:"
msgstr ""
@@ -15863,6 +16105,9 @@ msgstr ""
msgid "Geo|Failed"
msgstr ""
+msgid "Geo|Filter Geo sites"
+msgstr ""
+
msgid "Geo|Filter by name"
msgstr ""
@@ -16274,6 +16519,12 @@ msgstr ""
msgid "GitLab Issue"
msgstr ""
+msgid "GitLab KAS"
+msgstr ""
+
+msgid "GitLab Memberships CSV Export"
+msgstr ""
+
msgid "GitLab Pages"
msgstr ""
@@ -16322,6 +16573,9 @@ 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 free to use. Many features for larger teams are part of our %{link_start}paid products%{link_end}. You can try Ultimate for free without any obligation or payment details."
+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 ""
@@ -16448,7 +16702,7 @@ msgstr ""
msgid "GitLabPages|When enabled, all attempts to visit your website through HTTP are automatically redirected to HTTPS using a response with status code 301. Requires a valid certificate for all domains. %{docs_link_start}Learn more.%{link_end}"
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. %{docs_link_start}Learn more.%{link_end}"
+msgid "GitLabPages|When using Pages under the general domain of a GitLab instance (%{pages_host}), you cannot use HTTPS with subdomains of subdomains. If your namespace or groupname contains a dot, it does not work. This is a limitation of the HTTP Over TLS protocol. HTTP pages work if you don't redirect HTTP to HTTPS. %{docs_link_start}Learn more.%{link_end}"
msgstr ""
msgid "GitLabPages|With GitLab Pages you can host your static website directly from your GitLab repository. %{docs_link_start}Learn more.%{link_end}"
@@ -16625,9 +16879,6 @@ msgstr ""
msgid "Go to find file"
msgstr ""
-msgid "Go to fork"
-msgstr ""
-
msgid "Go to issue boards"
msgstr ""
@@ -16835,9 +17086,6 @@ msgstr ""
msgid "Group Hooks"
msgstr ""
-msgid "Group ID"
-msgstr ""
-
msgid "Group Owner must have signed in with SAML before enabling Group Managed Accounts"
msgstr ""
@@ -16865,9 +17113,6 @@ msgstr ""
msgid "Group by"
msgstr ""
-msgid "Group description"
-msgstr ""
-
msgid "Group description (optional)"
msgstr ""
@@ -16982,7 +17227,7 @@ msgstr ""
msgid "Group: %{name}"
msgstr ""
-msgid "GroupActivityMetrics|Issues opened"
+msgid "GroupActivityMetrics|Issues created"
msgstr ""
msgid "GroupActivityMetrics|Last 90 days"
@@ -16991,7 +17236,7 @@ msgstr ""
msgid "GroupActivityMetrics|Members added"
msgstr ""
-msgid "GroupActivityMetrics|Merge Requests opened"
+msgid "GroupActivityMetrics|Merge Requests created"
msgstr ""
msgid "GroupActivityMetrics|Recent activity"
@@ -17282,6 +17527,9 @@ msgstr ""
msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
+msgid "GroupSettings|Choose a group path that does not start with a dash or end with a period. It can also contain alphanumeric characters and underscores."
+msgstr ""
+
msgid "GroupSettings|Compliance frameworks"
msgstr ""
@@ -17315,7 +17563,7 @@ msgstr ""
msgid "GroupSettings|If not specified at the group or instance level, the default is %{default_initial_branch_name}. Does not affect existing repositories."
msgstr ""
-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."
+msgid "GroupSettings|If the parent group's visibility is lower than the group's current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility."
msgstr ""
msgid "GroupSettings|New runners registration token has been generated!"
@@ -17432,7 +17680,10 @@ msgstr ""
msgid "Groups and projects"
msgstr ""
-msgid "Groups and subgroups"
+msgid "Groups are a great way to organize projects and people."
+msgstr ""
+
+msgid "Groups are the best way to manage projects and members."
msgstr ""
msgid "Groups to synchronize"
@@ -17543,13 +17794,16 @@ msgstr ""
msgid "GroupsTree|Are you sure you want to leave the \"%{fullName}\" group?"
msgstr ""
-msgid "GroupsTree|Edit group"
+msgid "GroupsTree|Delete"
+msgstr ""
+
+msgid "GroupsTree|Edit"
msgstr ""
msgid "GroupsTree|Failed to leave the group. Please make sure you are not the only owner."
msgstr ""
-msgid "GroupsTree|Leave this group"
+msgid "GroupsTree|Leave group"
msgstr ""
msgid "GroupsTree|Loading groups"
@@ -17561,9 +17815,57 @@ msgstr ""
msgid "GroupsTree|No groups or projects matched your search"
msgstr ""
+msgid "GroupsTree|Options"
+msgstr ""
+
msgid "GroupsTree|Search by name"
msgstr ""
+msgid "Groups|Avatar will be removed. Are you sure?"
+msgstr ""
+
+msgid "Groups|Changing group URL can have unintended side effects."
+msgstr ""
+
+msgid "Groups|Checking group URL availability..."
+msgstr ""
+
+msgid "Groups|Enter a descriptive name for your group."
+msgstr ""
+
+msgid "Groups|Group ID"
+msgstr ""
+
+msgid "Groups|Group URL"
+msgstr ""
+
+msgid "Groups|Group avatar"
+msgstr ""
+
+msgid "Groups|Group description (optional)"
+msgstr ""
+
+msgid "Groups|Group name"
+msgstr ""
+
+msgid "Groups|Group path is available."
+msgstr ""
+
+msgid "Groups|Group path is unavailable. Path has been replaced with a suggested available path."
+msgstr ""
+
+msgid "Groups|Learn more"
+msgstr ""
+
+msgid "Groups|Must start with letter, digit, emoji, or underscore. Can also contain periods, dashes, spaces, and parentheses."
+msgstr ""
+
+msgid "Groups|Remove avatar"
+msgstr ""
+
+msgid "Groups|Save changes"
+msgstr ""
+
msgid "Guideline"
msgstr ""
@@ -17573,6 +17875,9 @@ msgstr ""
msgid "HAR file path or URL"
msgstr ""
+msgid "HTTP Archive (HAR)"
+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 ""
@@ -17973,6 +18278,9 @@ msgstr ""
msgid "INFO: Your SSH key is expiring soon. Please generate a new key."
msgstr ""
+msgid "IP"
+msgstr ""
+
msgid "IP Address"
msgstr ""
@@ -18009,6 +18317,9 @@ msgstr ""
msgid "IdentityVerification|Verify your identity"
msgstr ""
+msgid "IdentityVerification|You can always verify your account at a later time to create a group."
+msgstr ""
+
msgid "If any indexed field exceeds this limit, it is truncated to this number of characters. The rest of the content is neither indexed nor searchable. This does not apply to repository and wiki indexing. For unlimited characters, set this to 0."
msgstr ""
@@ -18066,6 +18377,9 @@ msgstr ""
msgid "If you add %{codeStart}needs%{codeEnd} to jobs in your pipeline you'll be able to view the %{codeStart}needs%{codeEnd} relationships between jobs in this tab as a %{linkStart}Directed Acyclic Graph (DAG)%{linkEnd}."
msgstr ""
+msgid "If you are added to a project, it will be displayed here."
+msgstr ""
+
msgid "If you did not initiate these sign-in attempts, please reach out to your administrator or enable two-factor authentication (2FA) on your account."
msgstr ""
@@ -18372,12 +18686,24 @@ msgstr ""
msgid "InProductMarketing|3 ways to dive into GitLab CI/CD"
msgstr ""
+msgid "InProductMarketing|A single application eliminates complex integrations, data chokepoints, and toolchain maintenance, resulting in greater productivity and lower cost."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features, build more efficiently, strengthen security and compliance."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features."
+msgstr ""
+
msgid "InProductMarketing|Actually, GitLab makes the team work (better)"
msgstr ""
msgid "InProductMarketing|And finally %{deploy_link} a Python application."
msgstr ""
+msgid "InProductMarketing|And many more..."
+msgstr ""
+
msgid "InProductMarketing|Are your runners ready?"
msgstr ""
@@ -18396,15 +18722,33 @@ msgstr ""
msgid "InProductMarketing|Blog"
msgstr ""
+msgid "InProductMarketing|Break down silos to coordinate seamlessly across development, operations, and security with a consistent experience across the development lifecycle."
+msgstr ""
+
+msgid "InProductMarketing|Burn up/down charts"
+msgstr ""
+
msgid "InProductMarketing|By enabling code owners and required merge approvals the right person will review the right MR. This is a win-win: cleaner code and a more efficient review process."
msgstr ""
msgid "InProductMarketing|Click on the number below that corresponds with your answer — 1 being very difficult, 5 being very easy."
msgstr ""
+msgid "InProductMarketing|Code owners"
+msgstr ""
+
msgid "InProductMarketing|Code owners and required merge approvals are part of the paid tiers of GitLab. You can start a free 30-day trial of GitLab Ultimate and enable these features in less than 5 minutes with no credit card required."
msgstr ""
+msgid "InProductMarketing|Code review analytics"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration across stages in GitLab"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration made easy"
+msgstr ""
+
msgid "InProductMarketing|Create a custom CI runner with just a few clicks"
msgstr ""
@@ -18414,12 +18758,21 @@ msgstr ""
msgid "InProductMarketing|Create a project in GitLab in 5 minutes"
msgstr ""
+msgid "InProductMarketing|Create well-defined workflows by using scoped labels on issues, merge requests, and epics. Labels with the same scope cannot be used together, which prevents conflicts."
+msgstr ""
+
msgid "InProductMarketing|Create your first project!"
msgstr ""
+msgid "InProductMarketing|Define who owns specific files or directories, so the right reviewers are suggested when a merge request introduces changes to those files."
+msgstr ""
+
msgid "InProductMarketing|Deliver Better Products Faster"
msgstr ""
+msgid "InProductMarketing|Dependency scanning"
+msgstr ""
+
msgid "InProductMarketing|Did you know teams that use GitLab are far more efficient?"
msgstr ""
@@ -18429,15 +18782,27 @@ msgstr ""
msgid "InProductMarketing|Dig in and create a project and a repo"
msgstr ""
+msgid "InProductMarketing|Discover Premium & Ultimate"
+msgstr ""
+
+msgid "InProductMarketing|Discover Premium & Ultimate."
+msgstr ""
+
msgid "InProductMarketing|Do you have a minute?"
msgstr ""
msgid "InProductMarketing|Do you have a teammate who would be perfect for this task?"
msgstr ""
+msgid "InProductMarketing|Dynamic application security testing"
+msgstr ""
+
msgid "InProductMarketing|Easy"
msgstr ""
+msgid "InProductMarketing|Epics"
+msgstr ""
+
msgid "InProductMarketing|Expand your DevOps journey with a free GitLab trial"
msgstr ""
@@ -18459,9 +18824,15 @@ msgstr ""
msgid "InProductMarketing|Feel the need for speed?"
msgstr ""
+msgid "InProductMarketing|Find and fix bottlenecks in your code review process by understanding how long open merge requests have been in review."
+msgstr ""
+
msgid "InProductMarketing|Find out how your teams are really doing"
msgstr ""
+msgid "InProductMarketing|Find out if your external libraries are safe. Run dependency scanning jobs that check for known vulnerabilities in your external libraries."
+msgstr ""
+
msgid "InProductMarketing|Follow our steps"
msgstr ""
@@ -18498,6 +18869,9 @@ msgstr ""
msgid "InProductMarketing|GitLab is better with teammates to help out!"
msgstr ""
+msgid "InProductMarketing|GitLab is infrastructure agnostic (supporting GCP, AWS, Azure, OpenShift, VMWare, On Prem, Bare Metal, and more), offering a consistent workflow experience – irrespective of the environment."
+msgstr ""
+
msgid "InProductMarketing|GitLab provides static application security testing (SAST), dynamic application security testing (DAST), container scanning, and dependency scanning to help you deliver secure applications along with license compliance."
msgstr ""
@@ -18588,21 +18962,36 @@ msgstr ""
msgid "InProductMarketing|It's also possible to simply %{external_repo_link} in order to take advantage of GitLab's CI/CD."
msgstr ""
+msgid "InProductMarketing|Keep your code quality high by defining who should approve merge requests and how many approvals are required."
+msgstr ""
+
msgid "InProductMarketing|Launch GitLab CI/CD in 20 minutes or less"
msgstr ""
+msgid "InProductMarketing|Lower cost of development"
+msgstr ""
+
+msgid "InProductMarketing|Make it easier to collaborate on high-level ideas by grouping related issues in an epic."
+msgstr ""
+
msgid "InProductMarketing|Making the switch? It's easier than you think to import your projects into GitLab. Move %{github_link}, or import something %{bitbucket_link}."
msgstr ""
msgid "InProductMarketing|Master the art of importing!"
msgstr ""
+msgid "InProductMarketing|Merge request approval rule"
+msgstr ""
+
msgid "InProductMarketing|Move on to easily creating a Pages website %{ci_template_link}"
msgstr ""
msgid "InProductMarketing|Multiple owners, confusing workstreams? We've got you covered"
msgstr ""
+msgid "InProductMarketing|Multiple required approvers"
+msgstr ""
+
msgid "InProductMarketing|Need an alternative to importing?"
msgstr ""
@@ -18615,18 +19004,33 @@ msgstr ""
msgid "InProductMarketing|Our tool brings all the things together"
msgstr ""
+msgid "InProductMarketing|Protect your web application by using DAST to examine for vulnerabilities in deployed environments."
+msgstr ""
+
msgid "InProductMarketing|Rapid development, simplified"
msgstr ""
msgid "InProductMarketing|Reduce Security & Compliance Risk"
msgstr ""
+msgid "InProductMarketing|Require multiple approvers on a merge request, so you know it's in good shape before it's merged."
+msgstr ""
+
+msgid "InProductMarketing|Roadmaps"
+msgstr ""
+
+msgid "InProductMarketing|Scoped labels"
+msgstr ""
+
msgid "InProductMarketing|Security that's integrated into your development lifecycle"
msgstr ""
msgid "InProductMarketing|Sometimes you're not ready to make a full transition to a new tool. If you're not ready to fully commit, %{mirroring_link} gives you a safe way to try out GitLab in parallel with your current tool."
msgstr ""
+msgid "InProductMarketing|Speed. Efficiency. Trust."
+msgstr ""
+
msgid "InProductMarketing|Spin up an autoscaling runner in GitLab"
msgstr ""
@@ -18636,6 +19040,9 @@ msgstr ""
msgid "InProductMarketing|Start a Self-Managed trial"
msgstr ""
+msgid "InProductMarketing|Start a free trial"
+msgstr ""
+
msgid "InProductMarketing|Start a free trial of GitLab Ultimate – no credit card required"
msgstr ""
@@ -18702,6 +19109,9 @@ msgstr ""
msgid "InProductMarketing|To understand and get the most out of GitLab, start at the beginning and %{project_link}. In GitLab, repositories are part of a project, so after you've created your project you can go ahead and %{repo_link}."
msgstr ""
+msgid "InProductMarketing|Track completed issues in a chart, so you can see how a milestone is progressing at a glance."
+msgstr ""
+
msgid "InProductMarketing|Try GitLab Ultimate for free"
msgstr ""
@@ -18738,6 +19148,9 @@ msgstr ""
msgid "InProductMarketing|Very easy"
msgstr ""
+msgid "InProductMarketing|Visualize your epics and milestones in a timeline."
+msgstr ""
+
msgid "InProductMarketing|Want to host GitLab on your servers?"
msgstr ""
@@ -18759,6 +19172,9 @@ msgstr ""
msgid "InProductMarketing|YouTube"
msgstr ""
+msgid "InProductMarketing|Your software, deployed your way"
+msgstr ""
+
msgid "InProductMarketing|Your teams can be more efficient"
msgstr ""
@@ -18879,9 +19295,18 @@ msgstr ""
msgid "IncidentManagement|No incidents to display."
msgstr ""
+msgid "IncidentManagement|None"
+msgstr ""
+
msgid "IncidentManagement|Open"
msgstr ""
+msgid "IncidentManagement|Page your team with escalation policies"
+msgstr ""
+
+msgid "IncidentManagement|Paged"
+msgstr ""
+
msgid "IncidentManagement|Published"
msgstr ""
@@ -18891,6 +19316,9 @@ msgstr ""
msgid "IncidentManagement|Severity"
msgstr ""
+msgid "IncidentManagement|Status"
+msgstr ""
+
msgid "IncidentManagement|There are no closed incidents"
msgstr ""
@@ -18909,6 +19337,9 @@ msgstr ""
msgid "IncidentManagement|Unpublished"
msgstr ""
+msgid "IncidentManagement|Use escalation policies to automatically page your team when incidents are created."
+msgstr ""
+
msgid "IncidentSettings|Activate \"time to SLA\" countdown timer"
msgstr ""
@@ -18954,7 +19385,10 @@ msgstr ""
msgid "Incidents"
msgstr ""
-msgid "Incidents|Add a URL"
+msgid "Incidents|Add image details"
+msgstr ""
+
+msgid "Incidents|Add text or a link to display with your image. If you don't add either, the file name displays instead."
msgstr ""
msgid "Incidents|Drop or %{linkStart}upload%{linkEnd} a metric screenshot to attach it to the incident"
@@ -18969,10 +19403,10 @@ msgstr ""
msgid "Incidents|There was an issue loading metric images."
msgstr ""
-msgid "Incidents|There was an issue uploading your image."
+msgid "Incidents|There was an issue updating your image."
msgstr ""
-msgid "Incidents|You can optionally add a URL to link users to the original graph."
+msgid "Incidents|There was an issue uploading your image."
msgstr ""
msgid "Incident|Alert details"
@@ -18981,9 +19415,18 @@ msgstr ""
msgid "Incident|Are you sure you wish to delete this image?"
msgstr ""
+msgid "Incident|Delete image"
+msgstr ""
+
msgid "Incident|Deleting %{filename}"
msgstr ""
+msgid "Incident|Edit image text or link"
+msgstr ""
+
+msgid "Incident|Editing %{filename}"
+msgstr ""
+
msgid "Incident|Metrics"
msgstr ""
@@ -19253,12 +19696,18 @@ msgstr ""
msgid "Integrations|Branches for which notifications are to be sent"
msgstr ""
+msgid "Integrations|Clear if using a self-signed certificate."
+msgstr ""
+
msgid "Integrations|Comment detail:"
msgstr ""
msgid "Integrations|Comment settings:"
msgstr ""
+msgid "Integrations|Connection details"
+msgstr ""
+
msgid "Integrations|Connection failed. Please check your settings."
msgstr ""
@@ -19283,6 +19732,9 @@ msgstr ""
msgid "Integrations|Enable GitLab.com slash commands in a Slack workspace."
msgstr ""
+msgid "Integrations|Enable SSL verification"
+msgstr ""
+
msgid "Integrations|Enable comments"
msgstr ""
@@ -19361,6 +19813,9 @@ msgstr ""
msgid "Integrations|Return to GitLab for Jira"
msgstr ""
+msgid "Integrations|SSL verification"
+msgstr ""
+
msgid "Integrations|Save settings?"
msgstr ""
@@ -19406,9 +19861,6 @@ msgstr ""
msgid "Integrations|Use default settings"
msgstr ""
-msgid "Integrations|When you mention a Jira issue in a commit or merge request, GitLab creates a remote link and comment (if enabled)."
-msgstr ""
-
msgid "Integrations|You can now close this window and return to the GitLab for Jira application."
msgstr ""
@@ -19433,9 +19885,6 @@ msgstr ""
msgid "Integrations|can't exceed %{recipients_limit}"
msgstr ""
-msgid "Interactive developer security education."
-msgstr ""
-
msgid "Interactive mode"
msgstr ""
@@ -19925,6 +20374,9 @@ msgstr ""
msgid "IssueAnalytics|Assignees"
msgstr ""
+msgid "IssueAnalytics|Created by"
+msgstr ""
+
msgid "IssueAnalytics|Due date"
msgstr ""
@@ -19937,9 +20389,6 @@ msgstr ""
msgid "IssueAnalytics|Milestone"
msgstr ""
-msgid "IssueAnalytics|Opened by"
-msgstr ""
-
msgid "IssueAnalytics|Status"
msgstr ""
@@ -20063,10 +20512,10 @@ msgstr ""
msgid "IssuesAnalytics|Avg/Month:"
msgstr ""
-msgid "IssuesAnalytics|Issues opened"
+msgid "IssuesAnalytics|Issues created"
msgstr ""
-msgid "IssuesAnalytics|Issues opened per month"
+msgid "IssuesAnalytics|Issues created per month"
msgstr ""
msgid "IssuesAnalytics|Last 12 months"
@@ -20093,6 +20542,9 @@ msgstr ""
msgid "It looks like you have some draft commits in this branch."
msgstr ""
+msgid "It looks like you're attempting to activate your subscription. Use %{a_start}the Subscription page%{a_end} instead."
+msgstr ""
+
msgid "It may be several days before you see feature usage data."
msgstr ""
@@ -20321,6 +20773,9 @@ msgstr ""
msgid "JiraConnect|You can now close this window and return to Jira."
msgstr ""
+msgid "JiraConnect|You don't have permission to create branches for this project. Select a different project or contact the project owner for access. %{linkStart}Learn more.%{linkEnd}"
+msgstr ""
+
msgid "JiraRequest|A connection error occurred while connecting to Jira. Try your request again."
msgstr ""
@@ -20369,13 +20824,13 @@ msgstr ""
msgid "JiraService|Define the type of Jira issue to create from a vulnerability."
msgstr ""
-msgid "JiraService|Displaying Jira issues while leaving the GitLab issue functionality enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
+msgid "JiraService|Displaying Jira issues while leaving GitLab issues also enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
msgstr ""
-msgid "JiraService|Enable Jira issues"
+msgid "JiraService|Enable Jira issue creation from vulnerabilities"
msgstr ""
-msgid "JiraService|Enable Jira issues creation from vulnerabilities"
+msgid "JiraService|Enable Jira issues"
msgstr ""
msgid "JiraService|Enable Jira transitions"
@@ -20492,16 +20947,19 @@ msgstr ""
msgid "JiraService|View Jira issues in GitLab"
msgstr ""
-msgid "JiraService|Warning: All GitLab users that have access to this GitLab project are able to view all issues from the Jira project specified below."
+msgid "JiraService|Warning: All GitLab users with access to this GitLab project can view all issues from the Jira project you select."
msgstr ""
msgid "JiraService|Web URL"
msgstr ""
-msgid "JiraService|Work on Jira issues without leaving GitLab. Adds a Jira menu to access your list of Jira issues and view any issue as read-only."
+msgid "JiraService|When a Jira issue is mentioned in a commit or merge request, a remote link and comment (if enabled) will be created."
+msgstr ""
+
+msgid "JiraService|Work on Jira issues without leaving GitLab. Add a Jira menu to access a read-only list of your Jira issues."
msgstr ""
-msgid "JiraService|You need to configure Jira before enabling this integration. For more details, read the %{jira_doc_link_start}Jira integration documentation%{link_end}."
+msgid "JiraService|You must configure Jira before enabling this integration. %{jira_doc_link_start}Learn more.%{link_end}"
msgstr ""
msgid "Job"
@@ -20513,9 +20971,6 @@ msgstr ""
msgid "Job Failed #%{build_id}"
msgstr ""
-msgid "Job ID"
-msgstr ""
-
msgid "Job artifact"
msgstr ""
@@ -20582,9 +21037,27 @@ msgstr ""
msgid "Jobs|You're about to retry a job that failed because it attempted to deploy code that is older than the latest deployment. Retrying this job could result in overwriting the environment with the older source code."
msgstr ""
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source} into %{target}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{ref}"
+msgstr ""
+
+msgid "Job|Are you sure you want to erase this job log and artifacts?"
+msgstr ""
+
msgid "Job|Browse"
msgstr ""
+msgid "Job|Cancel"
+msgstr ""
+
msgid "Job|Complete Raw"
msgstr ""
@@ -20594,6 +21067,9 @@ msgstr ""
msgid "Job|Erase job log and artifacts"
msgstr ""
+msgid "Job|Finished at"
+msgstr ""
+
msgid "Job|Job artifacts"
msgstr ""
@@ -20606,7 +21082,7 @@ msgstr ""
msgid "Job|Keep"
msgstr ""
-msgid "Job|Pipeline"
+msgid "Job|Retry"
msgstr ""
msgid "Job|Scroll to bottom"
@@ -20618,6 +21094,9 @@ msgstr ""
msgid "Job|Show complete raw"
msgstr ""
+msgid "Job|Status"
+msgstr ""
+
msgid "Job|The artifacts were removed"
msgstr ""
@@ -20645,21 +21124,12 @@ msgstr ""
msgid "Job|delayed"
msgstr ""
-msgid "Job|for"
-msgstr ""
-
-msgid "Job|into"
-msgstr ""
-
msgid "Job|manual"
msgstr ""
msgid "Job|triggered"
msgstr ""
-msgid "Job|with"
-msgstr ""
-
msgid "Join Zoom meeting"
msgstr ""
@@ -20762,9 +21232,6 @@ msgstr ""
msgid "Ki"
msgstr ""
-msgid "Kontra"
-msgstr ""
-
msgid "Kroki"
msgstr ""
@@ -21088,6 +21555,9 @@ msgstr ""
msgid "Learn more about Auto DevOps"
msgstr ""
+msgid "Learn more about GitLab"
+msgstr ""
+
msgid "Learn more about Needs relationships"
msgstr ""
@@ -21415,9 +21885,18 @@ msgstr ""
msgid "Licenses|Displays licenses detected in the project, based on the %{linkStart}latest successful%{linkEnd} scan"
msgstr ""
+msgid "Licenses|Drag your license file here or %{linkStart}click to upload%{linkEnd}."
+msgstr ""
+
+msgid "Licenses|Drop your license file to start the upload."
+msgstr ""
+
msgid "Licenses|Error fetching the license list. Please check your network connection and try again."
msgstr ""
+msgid "Licenses|Error: You are trying to upload something other than a file"
+msgstr ""
+
msgid "Licenses|License Compliance"
msgstr ""
@@ -21436,6 +21915,9 @@ msgstr ""
msgid "Licenses|Specified policies in this project"
msgstr ""
+msgid "Licenses|The file could not be uploaded."
+msgstr ""
+
msgid "Licenses|The license list details information about the licenses used within your project."
msgstr ""
@@ -21469,11 +21951,6 @@ msgstr ""
msgid "Limit the size of Sidekiq jobs stored in Redis."
msgstr ""
-msgid "Limited to showing %d event at most"
-msgid_plural "Limited to showing %d events at most"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Limiting mode"
msgstr ""
@@ -21483,6 +21960,9 @@ msgstr ""
msgid "Link"
msgstr ""
+msgid "Link (optional)"
+msgstr ""
+
msgid "Link Prometheus monitoring to GitLab."
msgstr ""
@@ -21519,6 +21999,9 @@ msgstr ""
msgid "Linked emails (%{email_count})"
msgstr ""
+msgid "Linked epics"
+msgstr ""
+
msgid "Linked issues"
msgstr ""
@@ -21546,6 +22029,15 @@ msgstr ""
msgid "List of all merge commits"
msgstr ""
+msgid "List of environments for this project"
+msgstr ""
+
+msgid "List of suitable GCP locations"
+msgstr ""
+
+msgid "List of users allowed to exceed the rate limit."
+msgstr ""
+
msgid "List options"
msgstr ""
@@ -21765,6 +22257,9 @@ msgstr ""
msgid "Maintenance mode"
msgstr ""
+msgid "Make adjustments to how your GitLab instance is set up."
+msgstr ""
+
msgid "Make and review changes in the browser with the Web IDE"
msgstr ""
@@ -21909,6 +22404,12 @@ msgstr ""
msgid "MarkdownEditor|Add italic text (%{modifier_key}I)"
msgstr ""
+msgid "MarkdownEditor|Add strikethrough text (%{modifierKey}⇧X)"
+msgstr ""
+
+msgid "MarkdownEditor|Add strikethrough text (%{modifier_key}⇧X)"
+msgstr ""
+
msgid "Marked For Deletion At - %{deletion_time}"
msgstr ""
@@ -22170,6 +22671,9 @@ msgstr ""
msgid "Maximum push size (MB)"
msgstr ""
+msgid "Maximum requests per 10 minutes per user"
+msgstr ""
+
msgid "Maximum requests per minute"
msgstr ""
@@ -22260,6 +22764,19 @@ msgstr ""
msgid "Members of a group may only view projects they have permission to access"
msgstr ""
+msgid "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seat in use and will be billed for the overage."
+msgid_plural "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seats in use and will be billed for the overage."
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "MembersOverage|You are about to incur additional charges"
+msgstr ""
+
+msgid "MembersOverage|Your subscription includes %d seat."
+msgid_plural "MembersOverage|Your subscription includes %d seats."
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Membership"
msgstr ""
@@ -22464,9 +22981,6 @@ msgstr ""
msgid "Merge request not merged"
msgstr ""
-msgid "Merge request pipelines 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 merge request pipelines."
-msgstr ""
-
msgid "Merge request reports"
msgstr ""
@@ -22563,13 +23077,13 @@ msgstr ""
msgid "MergeRequests|Create issue to resolve thread"
msgstr ""
-msgid "MergeRequests|Failed to squash. Should be done manually."
+msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Saving the comment failed"
+msgid "MergeRequests|Squashing failed: Squash the commits locally, resolve any conflicts, then push the branch."
msgstr ""
-msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
+msgid "MergeRequests|Squashing not allowed: This project doesn't allow you to squash commits when merging."
msgstr ""
msgid "MergeRequests|Thread stays resolved"
@@ -23410,6 +23924,18 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "MrList|Assigned to %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from assignee %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from reviewer %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Review requested from %{name}, go to their profile."
+msgstr ""
+
msgid "Multi-project"
msgstr ""
@@ -23443,7 +23969,7 @@ msgstr ""
msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "My Awesome Group"
+msgid "My awesome group"
msgstr ""
msgid "My company or team"
@@ -24065,9 +24591,6 @@ msgstr ""
msgid "No available branches"
msgstr ""
-msgid "No available groups to fork the project."
-msgstr ""
-
msgid "No branches found"
msgstr ""
@@ -24278,6 +24801,9 @@ msgstr ""
msgid "No ref selected"
msgstr ""
+msgid "No regions configured"
+msgstr ""
+
msgid "No related merge requests found."
msgstr ""
@@ -25082,6 +25608,9 @@ msgstr ""
msgid "Only reCAPTCHA v2 is supported:"
msgstr ""
+msgid "Only required if not using role instance credentials."
+msgstr ""
+
msgid "Only use lowercase letters, numbers, and underscores."
msgstr ""
@@ -25106,9 +25635,6 @@ msgstr ""
msgid "Open a CLI and connect to the cluster you want to install the agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
-msgid "Open epics"
-msgstr ""
-
msgid "Open errors"
msgstr ""
@@ -25148,7 +25674,7 @@ msgstr ""
msgid "Opened issues"
msgstr ""
-msgid "OpenedNDaysAgo|Opened"
+msgid "OpenedNDaysAgo|Created"
msgstr ""
msgid "Opens in a new window"
@@ -25193,9 +25719,6 @@ msgstr ""
msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
-msgid "Optional."
-msgstr ""
-
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
msgstr ""
@@ -25984,6 +26507,9 @@ msgstr ""
msgid "PerformanceBar|Memory"
msgstr ""
+msgid "PerformanceBar|Memory report"
+msgstr ""
+
msgid "PerformanceBar|Redis calls"
msgstr ""
@@ -26017,18 +26543,12 @@ msgstr ""
msgid "PerformanceBar|wall"
msgstr ""
-msgid "Performs a rebase but skips triggering a new pipeline"
-msgstr ""
-
msgid "Period in seconds"
msgstr ""
msgid "Permalink"
msgstr ""
-msgid "Permanently delete project"
-msgstr ""
-
msgid "Permanently remove group"
msgstr ""
@@ -26299,6 +26819,51 @@ msgstr ""
msgid "PipelineStatusTooltip|Pipeline: %{ci_status}"
msgstr ""
+msgid "PipelineWizardDefaultCommitMessage|Add %{filename}"
+msgstr ""
+
+msgid "PipelineWizardDefaultCommitMessage|Update %{filename}"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|At least one entry is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This field is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This value is not valid"
+msgstr ""
+
+msgid "PipelineWizardListWidget|add another step"
+msgstr ""
+
+msgid "PipelineWizardListWidget|remove step"
+msgstr ""
+
+msgid "PipelineWizard|Commit"
+msgstr ""
+
+msgid "PipelineWizard|Commit Message"
+msgstr ""
+
+msgid "PipelineWizard|Commit changes to your file"
+msgstr ""
+
+msgid "PipelineWizard|Commit file to Branch"
+msgstr ""
+
+msgid "PipelineWizard|Commit your new file"
+msgstr ""
+
+msgid "PipelineWizard|The file has been committed."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem committing the changes."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem while checking whether your file already exists in the specified branch."
+msgstr ""
+
msgid "Pipelines"
msgstr ""
@@ -26413,7 +26978,7 @@ msgstr ""
msgid "Pipelines|Project cache successfully reset."
msgstr ""
-msgid "Pipelines|Revoke"
+msgid "Pipelines|Revoke trigger"
msgstr ""
msgid "Pipelines|Something went wrong while cleaning runners cache."
@@ -26458,6 +27023,12 @@ msgstr ""
msgid "Pipelines|This is a child pipeline within the parent pipeline"
msgstr ""
+msgid "Pipelines|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipelines|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipelines|This pipeline will run code originating from a forked project merge request. This means that the code can potentially have security considerations like exposing CI variables."
msgstr ""
@@ -26500,9 +27071,6 @@ msgstr ""
msgid "Pipelines|Your changes have been successfully committed. Now redirecting to the new merge request page."
msgstr ""
-msgid "Pipelines|detached"
-msgstr ""
-
msgid "Pipelines|error"
msgstr ""
@@ -26512,10 +27080,13 @@ msgstr ""
msgid "Pipelines|latest"
msgstr ""
-msgid "Pipelines|stuck"
+msgid "Pipelines|merge request"
msgstr ""
-msgid "Pipelines|train"
+msgid "Pipelines|merge train"
+msgstr ""
+
+msgid "Pipelines|stuck"
msgstr ""
msgid "Pipelines|yaml invalid"
@@ -26647,6 +27218,12 @@ msgstr ""
msgid "Pipeline|This change will not change the overall test coverage if merged."
msgstr ""
+msgid "Pipeline|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipeline|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipeline|Trigger author"
msgstr ""
@@ -26671,6 +27248,12 @@ msgstr ""
msgid "Pipeline|for"
msgstr ""
+msgid "Pipeline|merge request"
+msgstr ""
+
+msgid "Pipeline|merge train"
+msgstr ""
+
msgid "Pipeline|on"
msgstr ""
@@ -26809,9 +27392,6 @@ msgstr ""
msgid "Please enter a valid time interval"
msgstr ""
-msgid "Please enter or upload a valid license."
-msgstr ""
-
msgid "Please enter your current password."
msgstr ""
@@ -26920,9 +27500,6 @@ msgstr ""
msgid "Please type %{phrase_code} to proceed or close this modal to cancel."
msgstr ""
-msgid "Please type the following to confirm:"
-msgstr ""
-
msgid "Please use this form to report to the admin users who create spam issues, comments or behave inappropriately."
msgstr ""
@@ -26950,12 +27527,27 @@ msgstr ""
msgid "Policies"
msgstr ""
+msgid "Policy '%{escalation_policy_name}' does not exist."
+msgstr ""
+
msgid "Policy management project does have any policies in %{policy_path}"
msgstr ""
msgid "Policy project doesn't exist"
msgstr ""
+msgid "PolicyRuleMultiSelect|%{firstLabel} +%{numberOfAdditionalLabels} more"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|All %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select all"
+msgstr ""
+
msgid "Polling interval multiplier"
msgstr ""
@@ -27184,6 +27776,9 @@ msgstr ""
msgid "Private projects can be created in your personal namespace with:"
msgstr ""
+msgid "Problem with %{name} command: %{message}."
+msgstr ""
+
msgid "Proceed"
msgstr ""
@@ -27658,6 +28253,9 @@ msgstr ""
msgid "Progress"
msgstr ""
+msgid "Progress tracking"
+msgstr ""
+
msgid "Project"
msgstr ""
@@ -27889,6 +28487,9 @@ msgstr ""
msgid "ProjectQualitySummary|Failure"
msgstr ""
+msgid "ProjectQualitySummary|Get insight into the overall percentage of tests in your project that succeed, fail and are skipped."
+msgstr ""
+
msgid "ProjectQualitySummary|Latest pipeline results"
msgstr ""
@@ -27907,6 +28508,12 @@ msgstr ""
msgid "ProjectQualitySummary|See project Code Coverage Statistics"
msgstr ""
+msgid "ProjectQualitySummary|Set up test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|Set up test runs (opens in a new tab)"
+msgstr ""
+
msgid "ProjectQualitySummary|Skipped"
msgstr ""
@@ -28183,13 +28790,19 @@ msgstr ""
msgid "ProjectSettings|LFS objects from this repository are available to forks. %{linkStart}How do I remove them?%{linkEnd}"
msgstr ""
+msgid "ProjectSettings|Learn about commit history."
+msgstr ""
+
+msgid "ProjectSettings|Leave empty to use default template."
+msgstr ""
+
msgid "ProjectSettings|Manage who can see the project in the public access directory."
msgstr ""
msgid "ProjectSettings|Manages large files such as audio, video, and graphics files."
msgstr ""
-msgid "ProjectSettings|Maximum 500 characters."
+msgid "ProjectSettings|Maximum %{maxLength} characters."
msgstr ""
msgid "ProjectSettings|Merge checks"
@@ -28330,6 +28943,9 @@ msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
msgstr ""
+msgid "ProjectSettings|The default template will be applied on save."
+msgstr ""
+
msgid "ProjectSettings|These checks must pass before merge requests can be merged."
msgstr ""
@@ -28384,6 +29000,9 @@ msgstr ""
msgid "ProjectSettings|What are badges?"
msgstr ""
+msgid "ProjectSettings|What are merge trains?"
+msgstr ""
+
msgid "ProjectSettings|When merge request pipelines are enabled in the CI/CD configuration file, pipelines validate the combined results of the source and target branches. %{link_start}How to configure merge request pipelines?%{link_end}"
msgstr ""
@@ -28501,6 +29120,9 @@ msgstr ""
msgid "Projects are organized into groups"
msgstr ""
+msgid "Projects are where you store your code, access issues, wiki and other features of GitLab."
+msgstr ""
+
msgid "Projects contributed to"
msgstr ""
@@ -28516,12 +29138,6 @@ msgstr ""
msgid "Projects to index"
msgstr ""
-msgid "Projects will be permanently deleted after a %{waiting_period}-day waiting period."
-msgstr ""
-
-msgid "Projects will be permanently deleted immediately."
-msgstr ""
-
msgid "Projects with critical vulnerabilities"
msgstr ""
@@ -28606,6 +29222,9 @@ msgstr ""
msgid "ProjectsNew|Import project"
msgstr ""
+msgid "ProjectsNew|Include a Getting Started README"
+msgstr ""
+
msgid "ProjectsNew|Initialize repository with a README"
msgstr ""
@@ -28621,6 +29240,9 @@ msgstr ""
msgid "ProjectsNew|Project description %{tag_start}(optional)%{tag_end}"
msgstr ""
+msgid "ProjectsNew|Recommended if you're new to GitLab"
+msgstr ""
+
msgid "ProjectsNew|Run CI/CD for external repository"
msgstr ""
@@ -29038,6 +29660,9 @@ msgstr ""
msgid "ProtectedBranch|Unprotect"
msgstr ""
+msgid "ProtectedBranch|Unprotect branch"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
@@ -29065,6 +29690,9 @@ msgstr ""
msgid "ProtectedEnvironment|Protected Environment (%{protected_environments_count})"
msgstr ""
+msgid "ProtectedEnvironment|Required approvals"
+msgstr ""
+
msgid "ProtectedEnvironment|Select an environment"
msgstr ""
@@ -29086,10 +29714,13 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|Unprotect tag"
+msgstr ""
+
msgid "ProtectedTags|default"
msgstr ""
-msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
+msgid "ProtectedTag|By default, protected tags restrict who can modify the tag."
msgstr ""
msgid "ProtectedTag|Learn more."
@@ -29152,6 +29783,9 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Public projects are an easy way to allow everyone to have read-only access."
+msgstr ""
+
msgid "Publish to status page"
msgstr ""
@@ -29308,9 +29942,6 @@ msgstr ""
msgid "QualitySummary|Project quality"
msgstr ""
-msgid "Quarters"
-msgstr ""
-
msgid "Query"
msgstr ""
@@ -29395,6 +30026,9 @@ msgstr ""
msgid "Read more about project permissions %{help_link_open}here%{help_link_close}"
msgstr ""
+msgid "Read more about related epics"
+msgstr ""
+
msgid "Read more about related issues"
msgstr ""
@@ -29425,10 +30059,7 @@ msgstr ""
msgid "Rebase source branch on the target branch."
msgstr ""
-msgid "Rebase without CI"
-msgstr ""
-
-msgid "Rebases and triggers a pipeline"
+msgid "Rebase without pipeline"
msgstr ""
msgid "Recaptcha verified?"
@@ -29479,9 +30110,6 @@ msgstr ""
msgid "Reconfigure"
msgstr ""
-msgid "Recovering projects"
-msgstr ""
-
msgid "Recovery Codes"
msgstr ""
@@ -29541,6 +30169,12 @@ msgstr ""
msgid "Regex pattern"
msgstr ""
+msgid "Region"
+msgstr ""
+
+msgid "Regions"
+msgstr ""
+
msgid "Register"
msgstr ""
@@ -29771,9 +30405,6 @@ msgstr ""
msgid "Remove all or specific reviewer(s)"
msgstr ""
-msgid "Remove approver"
-msgstr ""
-
msgid "Remove approvers"
msgstr ""
@@ -29789,6 +30420,9 @@ msgstr ""
msgid "Remove attention request"
msgstr ""
+msgid "Remove attention request(s)"
+msgstr ""
+
msgid "Remove avatar"
msgstr ""
@@ -29927,6 +30561,9 @@ msgstr ""
msgid "Removed an issue from an epic."
msgstr ""
+msgid "Removed attention from %{users_sentence}."
+msgstr ""
+
msgid "Removed attention request from @%{username}"
msgstr ""
@@ -29978,6 +30615,9 @@ msgstr ""
msgid "Removes an issue from an epic."
msgstr ""
+msgid "Removes attention from %{users_sentence}."
+msgstr ""
+
msgid "Removes parent epic %{epic_ref}."
msgstr ""
@@ -30089,6 +30729,9 @@ msgstr ""
msgid "Report abuse to admin"
msgstr ""
+msgid "Report is generating and will be sent to your email address."
+msgstr ""
+
msgid "Reported %{timeAgo} by %{reportedBy}"
msgstr ""
@@ -30378,6 +31021,15 @@ msgstr ""
msgid "Request attention"
msgstr ""
+msgid "Request attention from %{users_sentence}."
+msgstr ""
+
+msgid "Request attention from assignee or reviewer"
+msgstr ""
+
+msgid "Request attention from assignee(s) or reviewer(s)"
+msgstr ""
+
msgid "Request attention to review"
msgstr ""
@@ -30402,6 +31054,9 @@ msgstr ""
msgid "Requested %{time_ago}"
msgstr ""
+msgid "Requested attention from %{users_sentence}."
+msgstr ""
+
msgid "Requested attention from @%{username}"
msgstr ""
@@ -30616,6 +31271,9 @@ msgstr ""
msgid "Restore project"
msgstr ""
+msgid "Restoring projects"
+msgstr ""
+
msgid "Restoring the group will prevent the group, its subgroups and projects from being removed on this date."
msgstr ""
@@ -30646,6 +31304,9 @@ msgstr ""
msgid "Retry"
msgstr ""
+msgid "Retry failed jobs"
+msgstr ""
+
msgid "Retry job"
msgstr ""
@@ -30693,9 +31354,6 @@ msgstr ""
msgid "Review changes"
msgstr ""
-msgid "Review requested from %{name}"
-msgstr ""
-
msgid "Review requests for you"
msgstr ""
@@ -30860,6 +31518,9 @@ msgstr ""
msgid "Runners|Assigned Group"
msgstr ""
+msgid "Runners|Assigned Projects (%{projectCount})"
+msgstr ""
+
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30929,6 +31590,9 @@ msgstr ""
msgid "Runners|Instance"
msgstr ""
+msgid "Runners|Jobs"
+msgstr ""
+
msgid "Runners|Last contact"
msgstr ""
@@ -31022,9 +31686,6 @@ msgstr ""
msgid "Runners|Runner %{name} was deleted"
msgstr ""
-msgid "Runners|Runner ID"
-msgstr ""
-
msgid "Runners|Runner assigned to project."
msgstr ""
@@ -31172,6 +31833,9 @@ msgstr ""
msgid "Runners|stale"
msgstr ""
+msgid "Runner|This runner has not run any jobs."
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -31286,6 +31950,24 @@ msgstr ""
msgid "Saving project."
msgstr ""
+msgid "ScanResultPolicy|%{ifLabelStart}if%{ifLabelEnd} %{scanners} scan in an open merge request targeting the %{branches} branch(es) finds %{vulnerabilitiesAllowed} or more %{severities} vulnerabilities that are %{vulnerabilityStates}"
+msgstr ""
+
+msgid "ScanResultPolicy|%{thenLabelStart}Then%{thenLabelEnd} Require approval from %{approvalsRequired} of the following approvers: %{approvers}"
+msgstr ""
+
+msgid "ScanResultPolicy|add an approver"
+msgstr ""
+
+msgid "ScanResultPolicy|scanners"
+msgstr ""
+
+msgid "ScanResultPolicy|severity levels"
+msgstr ""
+
+msgid "ScanResultPolicy|vulnerability states"
+msgstr ""
+
msgid "Scanner"
msgstr ""
@@ -31418,6 +32100,9 @@ msgstr ""
msgid "Search for a user"
msgstr ""
+msgid "Search for an emoji"
+msgstr ""
+
msgid "Search for projects, issues, etc."
msgstr ""
@@ -31605,18 +32290,12 @@ msgstr ""
msgid "Secret Detection"
msgstr ""
-msgid "Secret access key"
-msgstr ""
-
msgid "Secret token"
msgstr ""
msgid "Secure token that identifies an external storage request."
msgstr ""
-msgid "SecureCodeWarrior"
-msgstr ""
-
msgid "Security"
msgstr ""
@@ -31641,9 +32320,6 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "Security training with guide and learning pathways."
-msgstr ""
-
msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
@@ -31746,7 +32422,7 @@ msgstr ""
msgid "SecurityConfiguration|Manage corpus"
msgstr ""
-msgid "SecurityConfiguration|Manage corpus files used as mutation sources in coverage fuzzing."
+msgid "SecurityConfiguration|Manage corpus files used as seed inputs with coverage-guided fuzzing."
msgstr ""
msgid "SecurityConfiguration|Manage profiles for use by DAST scans."
@@ -31812,15 +32488,15 @@ msgstr ""
msgid "SecurityOrchestration|.yaml preview"
msgstr ""
-msgid "SecurityOrchestration|Action"
-msgstr ""
-
msgid "SecurityOrchestration|Actions"
msgstr ""
msgid "SecurityOrchestration|Add rule"
msgstr ""
+msgid "SecurityOrchestration|After dismissing the alert, the information will never be shown again."
+msgstr ""
+
msgid "SecurityOrchestration|All policies"
msgstr ""
@@ -31836,7 +32512,7 @@ msgstr ""
msgid "SecurityOrchestration|Description"
msgstr ""
-msgid "SecurityOrchestration|Disabled"
+msgid "SecurityOrchestration|Don't show the alert anymore"
msgstr ""
msgid "SecurityOrchestration|Edit policy"
@@ -31845,13 +32521,13 @@ msgstr ""
msgid "SecurityOrchestration|Edit policy project"
msgstr ""
-msgid "SecurityOrchestration|Enabled"
+msgid "SecurityOrchestration|Empty policy name"
msgstr ""
-msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Enabled"
msgstr ""
-msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
msgstr ""
msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
@@ -31860,7 +32536,7 @@ msgstr ""
msgid "SecurityOrchestration|Invalid policy type"
msgstr ""
-msgid "SecurityOrchestration|Latest scan"
+msgid "SecurityOrchestration|Latest scan run against %{agent}"
msgstr ""
msgid "SecurityOrchestration|Network"
@@ -31869,15 +32545,27 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No actions defined - policy will not run."
+msgstr ""
+
+msgid "SecurityOrchestration|No description"
+msgstr ""
+
msgid "SecurityOrchestration|No rules defined - policy will not run."
msgstr ""
+msgid "SecurityOrchestration|Not enabled"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
msgid "SecurityOrchestration|Policies"
msgstr ""
+msgid "SecurityOrchestration|Policy Type"
+msgstr ""
+
msgid "SecurityOrchestration|Policy cannot be enabled for non-existing branches (%{branches})"
msgstr ""
@@ -31902,10 +32590,13 @@ msgstr ""
msgid "SecurityOrchestration|Require %{approvals} %{plural} from %{approvers} if any of the following occur:"
msgstr ""
-msgid "SecurityOrchestration|Rule"
+msgid "SecurityOrchestration|Rules"
msgstr ""
-msgid "SecurityOrchestration|Rules"
+msgid "SecurityOrchestration|Runs %{actions} and %{lastAction} scans"
+msgstr ""
+
+msgid "SecurityOrchestration|Runs a %{action} scan"
msgstr ""
msgid "SecurityOrchestration|Scan Execution"
@@ -31965,6 +32656,9 @@ msgstr ""
msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
+msgid "SecurityOrchestration|This view only shows scan results for the agent %{agent}. You can view scan results for all agents in the %{linkStart}Operational Vulnerabilities tab of the vulnerability report%{linkEnd}."
+msgstr ""
+
msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
@@ -32019,9 +32713,6 @@ msgstr ""
msgid "SecurityOrchestration|users with ids"
msgstr ""
-msgid "SecurityOrchestration|view results"
-msgstr ""
-
msgid "SecurityOrchestration|vulnerabilities"
msgstr ""
@@ -32691,22 +33382,19 @@ 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|In order to start using functions as a service, you must first install Knative on your Kubernetes cluster. %{linkStart}More information%{linkEnd}"
-msgstr ""
-
msgid "Serverless|Learn more about Serverless"
msgstr ""
msgid "Serverless|No functions available"
msgstr ""
-msgid "Serverless|Sign up for First Look"
+msgid "Serverless|Serverless was %{linkStart}deprecated%{linkEnd} in GitLab 14.3."
+msgstr ""
+
+msgid "Serverless|Serverless was %{postLinkStart}deprecated%{postLinkEnd}. But if you opt to use it, you must install Knative in your Kubernetes cluster first. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "Serverless|The deploy job has not finished."
@@ -32718,9 +33406,6 @@ 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 ""
@@ -32736,9 +33421,6 @@ msgstr ""
msgid "Service Account Key"
msgstr ""
-msgid "Service Accounts"
-msgstr ""
-
msgid "Service Accounts keys authorize GitLab to deploy your Google Cloud project"
msgstr ""
@@ -32748,10 +33430,10 @@ msgstr ""
msgid "Service Desk allows people to create issues in your GitLab instance without their own user account. It provides a unique email address for end users to create issues in a project. Replies can be sent either through the GitLab interface or by email. End users only see threads through email."
msgstr ""
-msgid "Service Usage Data"
+msgid "Service account generated successfully"
msgstr ""
-msgid "Service account generated successfully"
+msgid "Service accounts"
msgstr ""
msgid "Service ping is disabled in your configuration file, and cannot be enabled through this form."
@@ -32895,6 +33577,9 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
+msgid "Set the per-user rate limit for getting a user by ID via the API."
+msgstr ""
+
msgid "Set the per-user rate limit for notes created by web or API requests."
msgstr ""
@@ -33074,6 +33759,9 @@ msgstr ""
msgid "Shared runners details"
msgstr ""
+msgid "Shared runners enabled cannot be enabled until a valid credit card is on file"
+msgstr ""
+
msgid "Shared runners help link"
msgstr ""
@@ -33131,6 +33819,9 @@ msgstr ""
msgid "Show all issues."
msgstr ""
+msgid "Show all milestones"
+msgstr ""
+
msgid "Show all test cases."
msgstr ""
@@ -33167,6 +33858,9 @@ msgstr ""
msgid "Show file contents"
msgstr ""
+msgid "Show group milestones"
+msgstr ""
+
msgid "Show labels"
msgstr ""
@@ -33182,6 +33876,12 @@ msgstr ""
msgid "Show open epics"
msgstr ""
+msgid "Show project milestones"
+msgstr ""
+
+msgid "Show sub-group milestones"
+msgstr ""
+
msgid "Show the Closed list"
msgstr ""
@@ -33191,11 +33891,6 @@ msgstr ""
msgid "Show whitespace changes"
msgstr ""
-msgid "Showing %d event"
-msgid_plural "Showing %d events"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Showing %{conflict} between %{sourceBranch} and %{targetBranch}"
msgstr ""
@@ -33255,12 +33950,6 @@ msgstr ""
msgid "Sidebar|None"
msgstr ""
-msgid "Sidebar|Only numeral characters allowed"
-msgstr ""
-
-msgid "Sidebar|Weight"
-msgstr ""
-
msgid "Sidekiq job compression threshold (bytes)"
msgstr ""
@@ -33423,6 +34112,9 @@ msgstr ""
msgid "Slack logo"
msgstr ""
+msgid "SlackIntegration|Are you sure you want to remove this project from the Slack application?"
+msgstr ""
+
msgid "SlackIntegration|GitLab for Slack"
msgstr ""
@@ -33432,6 +34124,9 @@ msgstr ""
msgid "SlackIntegration|Project alias"
msgstr ""
+msgid "SlackIntegration|Remove project"
+msgstr ""
+
msgid "SlackIntegration|Select a GitLab project to link with your Slack workspace."
msgstr ""
@@ -33576,9 +34271,6 @@ msgstr ""
msgid "Something went wrong trying to load issue contacts."
msgstr ""
-msgid "Something went wrong when creating a work item. Please try again"
-msgstr ""
-
msgid "Something went wrong when reordering designs. Please try again"
msgstr ""
@@ -33672,9 +34364,6 @@ msgstr ""
msgid "Something went wrong while inserting your image. Please try again."
msgstr ""
-msgid "Something went wrong while merging this merge request. Please try again."
-msgstr ""
-
msgid "Something went wrong while obtaining the Let's Encrypt certificate."
msgstr ""
@@ -33996,10 +34685,10 @@ 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."
+msgid "SourcegraphAdmin|Learn more."
msgstr ""
-msgid "SourcegraphAdmin|More information"
+msgid "SourcegraphAdmin|Only public projects have code intelligence enabled and communicate with Sourcegraph."
msgstr ""
msgid "SourcegraphAdmin|Save changes"
@@ -34008,7 +34697,7 @@ msgstr ""
msgid "SourcegraphAdmin|Sourcegraph URL"
msgstr ""
-msgid "SourcegraphAdmin|e.g. https://sourcegraph.example.com"
+msgid "SourcegraphAdmin|https://sourcegraph.example.com"
msgstr ""
msgid "SourcegraphPreferences|This feature is experimental and currently limited to certain projects."
@@ -34143,6 +34832,9 @@ msgstr ""
msgid "Start date"
msgstr ""
+msgid "Start free trial"
+msgstr ""
+
msgid "Start merge train"
msgstr ""
@@ -34173,6 +34865,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started escalation for this incident."
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -34185,6 +34880,9 @@ msgstr ""
msgid "Starts at (UTC)"
msgstr ""
+msgid "Starts escalations for this incident"
+msgstr ""
+
msgid "Starts on"
msgstr ""
@@ -34446,6 +35144,9 @@ msgstr ""
msgid "Strikethrough"
msgstr ""
+msgid "Strikethrough text"
+msgstr ""
+
msgid "Subgroup information"
msgstr ""
@@ -34680,6 +35381,21 @@ msgstr ""
msgid "Subscriptions"
msgstr ""
+msgid "Subscriptions|Chat with sales"
+msgstr ""
+
+msgid "Subscriptions|Close"
+msgstr ""
+
+msgid "Subscriptions|Not ready to buy yet?"
+msgstr ""
+
+msgid "Subscriptions|Start a free trial"
+msgstr ""
+
+msgid "Subscriptions|We understand. Maybe you have some questions for our sales team, or maybe you'd like to try some of the paid features first. What would you like to do?"
+msgstr ""
+
msgid "Subscription|Your subscription for %{strong}%{namespace_name}%{strong_close} has expired and you are now on %{pricing_link_start}the GitLab Free tier%{pricing_link_end}. Don't worry, your data is safe. Get in touch with our support team (%{support_email}). They'll gladly help with your subscription renewal."
msgstr ""
@@ -34890,6 +35606,9 @@ msgstr ""
msgid "SuperSonics|Maximum users"
msgstr ""
+msgid "SuperSonics|Offline cloud"
+msgstr ""
+
msgid "SuperSonics|Paste your activation code"
msgstr ""
@@ -34956,6 +35675,12 @@ msgstr ""
msgid "SuperSonics|You do not have an active subscription"
msgstr ""
+msgid "SuperSonics|You have a future dated license"
+msgstr ""
+
+msgid "SuperSonics|You have added a license that activates on %{date}. Please see the subscription history table below for more details."
+msgstr ""
+
msgid "SuperSonics|You have successfully added a license that activates on %{date}. Please see the subscription history table below for more details."
msgstr ""
@@ -35115,6 +35840,9 @@ msgstr ""
msgid "Tag name is required"
msgstr ""
+msgid "Tag push"
+msgstr ""
+
msgid "Tag push events"
msgstr ""
@@ -35217,6 +35945,9 @@ msgstr ""
msgid "TagsPage|protected"
msgstr ""
+msgid "Take a look at the documentation to discover all of GitLab’s capabilities."
+msgstr ""
+
msgid "Target Branch"
msgstr ""
@@ -35619,6 +36350,9 @@ msgstr ""
msgid "Tests"
msgstr ""
+msgid "Text (optional)"
+msgstr ""
+
msgid "Text added to the body of all email messages. %{character_limit} character limit"
msgstr ""
@@ -35669,6 +36403,9 @@ msgstr ""
msgid "The CSV export will be created in the background. Once finished, it will be sent to %{email} in an attachment."
msgstr ""
+msgid "The CSV export you requested of all user memberships is attached to this email."
+msgstr ""
+
msgid "The GitLab subscription service (customers.gitlab.com) is currently experiencing an outage. You can monitor the status and get updates at %{linkStart}status.gitlab.com%{linkEnd}."
msgstr ""
@@ -35744,6 +36481,9 @@ 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 epic"
+msgstr ""
+
msgid "The current issue"
msgstr ""
@@ -35905,6 +36645,9 @@ msgstr ""
msgid "The latest pipeline for this merge request has failed."
msgstr ""
+msgid "The license key is invalid."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -35920,6 +36663,9 @@ msgstr ""
msgid "The license was successfully uploaded and will be active from %{starts_at}. You can see the details below."
msgstr ""
+msgid "The license you uploaded is invalid. If the issue persists, contact support at %{link}."
+msgstr ""
+
msgid "The list creation wizard is already open"
msgstr ""
@@ -36541,10 +37287,13 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} and everything this project contains. %{strongOpen}There is no going back%{strongClose}"
+msgstr ""
+
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains."
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}on %{date}%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains. %{strongOpen}There is no going back.%{strongClose}"
msgstr ""
msgid "This action will %{strongOpen}permanently remove%{strongClose} %{codeOpen}%{group}%{codeClose} %{strongOpen}immediately%{strongClose}."
@@ -36673,9 +37422,6 @@ msgstr ""
msgid "This file was modified for readability, and can't accept suggestions. Edit it directly."
msgstr ""
-msgid "This forked project has the following:"
-msgstr ""
-
msgid "This form is disabled in preview"
msgstr ""
@@ -36688,7 +37434,7 @@ msgstr ""
msgid "This group can't be removed because it is linked to a subscription. To remove this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
-msgid "This group can't be transfered because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
+msgid "This group can't be transferred because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
msgid "This group cannot be invited to a project inside a group with enforced SSO"
@@ -36715,6 +37461,9 @@ 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 incident is already escalated with '%{escalation_policy_name}'."
+msgstr ""
+
msgid "This invitation was sent to %{mail_to_invite_email}, but you are signed in as %{link_to_current_user} with email %{mail_to_current_user}."
msgstr ""
@@ -36733,9 +37482,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 merge train pipeline"
-msgstr ""
-
msgid "This is a private email address %{helpIcon} generated just for you. Anyone who has it can create issues or merge requests as if they were you. If that happens, %{resetLinkStart}reset this token%{resetLinkEnd}."
msgstr ""
@@ -36757,6 +37503,12 @@ msgstr ""
msgid "This is your current session"
msgstr ""
+msgid "This issue cannot be assigned to a confidential epic because it is public."
+msgstr ""
+
+msgid "This issue cannot be made public because it belongs to a confidential epic."
+msgstr ""
+
msgid "This issue is confidential and should only be visible to team members with at least Reporter access."
msgstr ""
@@ -36874,6 +37626,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 branch is protected from force push."
+msgstr ""
+
msgid "This merge request cannot be rebased while there are conflicts."
msgstr ""
@@ -36925,9 +37680,15 @@ msgstr ""
msgid "This pipeline was triggered by a schedule."
msgstr ""
+msgid "This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project"
msgstr ""
+msgid "This project can be restored until %{date}."
+msgstr ""
+
msgid "This project cannot be %{visibilityLevel} because the visibility of %{openShowLink}%{name}%{closeShowLink} is %{visibility}. To make this project %{visibilityLevel}, you must first %{openEditLink}change the visibility%{closeEditLink} of the parent group."
msgstr ""
@@ -36946,6 +37707,9 @@ msgstr ""
msgid "This project is %{strongStart}NOT%{strongEnd} a fork, and has the following:"
msgstr ""
+msgid "This project is %{strongStart}NOT%{strongEnd} a fork. This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -37637,6 +38401,9 @@ msgstr ""
msgid "Today"
msgstr ""
+msgid "Todos count"
+msgstr ""
+
msgid "Todos|Are you looking for things to do? Take a look at %{strongStart}%{openIssuesLinkStart}open issues%{openIssuesLinkEnd}%{strongEnd}, contribute to %{strongStart}%{mergeRequestLinkStart}a merge request%{mergeRequestLinkEnd}%{mergeRequestLinkEnd}%{strongEnd}, or mention someone in a comment to automatically assign them a new to-do item."
msgstr ""
@@ -37910,10 +38677,8 @@ msgstr ""
msgid "Trending"
msgstr ""
-msgid "Trials|%{planName} Trial %{enDash} %{num} day left"
-msgid_plural "Trials|%{planName} Trial %{enDash} %{num} days left"
-msgstr[0] ""
-msgstr[1] ""
+msgid "Trials|%{planName} Trial"
+msgstr ""
msgid "Trials|Compare all plans"
msgstr ""
@@ -37921,6 +38686,9 @@ msgstr ""
msgid "Trials|Create a new group to start your GitLab Ultimate trial."
msgstr ""
+msgid "Trials|Day %{daysUsed}/%{duration}"
+msgstr ""
+
msgid "Trials|Go back to GitLab"
msgstr ""
@@ -38170,7 +38938,7 @@ msgstr ""
msgid "URL is triggered when repository is updated"
msgstr ""
-msgid "URL must be percent-encoded if neccessary."
+msgid "URL must be percent-encoded if necessary."
msgstr ""
msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
@@ -38389,6 +39157,9 @@ msgstr ""
msgid "Unlock account"
msgstr ""
+msgid "Unlock more features with GitLab Ultimate"
+msgstr ""
+
msgid "Unlock the discussion"
msgstr ""
@@ -38452,6 +39223,9 @@ msgstr ""
msgid "Unsubscribes from this %{quick_action_target}."
msgstr ""
+msgid "Unsupported sort value."
+msgstr ""
+
msgid "Unsupported todo type passed. Supported todo types are: %{todo_types}"
msgstr ""
@@ -38680,6 +39454,9 @@ msgstr ""
msgid "UsageQuota|File attachments and smaller design graphics."
msgstr ""
+msgid "UsageQuota|From %{storage_enforcement_date} storage limits will apply to this namespace. View and manage your usage in %{strong_start}Group Settings &gt; Usage quotas%{strong_end}."
+msgstr ""
+
msgid "UsageQuota|Git repository."
msgstr ""
@@ -38740,6 +39517,9 @@ msgstr ""
msgid "UsageQuota|Storage type"
msgstr ""
+msgid "UsageQuota|Storage used"
+msgstr ""
+
msgid "UsageQuota|This is the total amount of storage used across your projects within this namespace."
msgstr ""
@@ -38935,6 +39715,12 @@ msgstr ""
msgid "Use hashed storage paths for newly created and renamed repositories. Always enabled since 13.0."
msgstr ""
+msgid "Use issue count"
+msgstr ""
+
+msgid "Use issue weight"
+msgstr ""
+
msgid "Use one line per URI"
msgstr ""
@@ -39316,6 +40102,9 @@ msgstr ""
msgid "Users"
msgstr ""
+msgid "Users API rate limit"
+msgstr ""
+
msgid "Users can launch a development environment from a GitLab browser tab when the %{linkStart}Gitpod%{linkEnd} integration is enabled."
msgstr ""
@@ -39641,6 +40430,9 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View group pipeline usage quota"
+msgstr ""
+
msgid "View incident details at"
msgstr ""
@@ -39793,6 +40585,9 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
+msgid "Vulnerability"
+msgstr ""
+
msgid "Vulnerability Report"
msgstr ""
@@ -39844,6 +40639,9 @@ msgstr ""
msgid "VulnerabilityManagement|An unverified non-confirmed finding"
msgstr ""
+msgid "VulnerabilityManagement|At least one identifier is required"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -39853,12 +40651,24 @@ msgstr ""
msgid "VulnerabilityManagement|Create Jira issue"
msgstr ""
+msgid "VulnerabilityManagement|Enter a name"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE code"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE identifier URL"
+msgstr ""
+
msgid "VulnerabilityManagement|Fetching linked Jira issues"
msgstr ""
msgid "VulnerabilityManagement|Manually add a vulnerability entry into the vulnerability report."
msgstr ""
+msgid "VulnerabilityManagement|Name is a required field"
+msgstr ""
+
msgid "VulnerabilityManagement|Needs triage"
msgstr ""
@@ -39874,6 +40684,18 @@ msgstr ""
msgid "VulnerabilityManagement|Select a method"
msgstr ""
+msgid "VulnerabilityManagement|Select a severity level"
+msgstr ""
+
+msgid "VulnerabilityManagement|Select a status"
+msgstr ""
+
+msgid "VulnerabilityManagement|Severity is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Something went wrong while creating vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -39898,6 +40720,12 @@ msgstr ""
msgid "VulnerabilityManagement|Something went wrong, could not update vulnerability state."
msgstr ""
+msgid "VulnerabilityManagement|Status is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Submit vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Summary, detailed description, steps to reproduce, etc."
msgstr ""
@@ -40093,6 +40921,9 @@ msgstr ""
msgid "WARNING:"
msgstr ""
+msgid "WARNING: This snippet contains hidden files which might be used to mask malicious behavior. Exercise caution if cloning and executing code from this snippet."
+msgstr ""
+
msgid "Wait for the file to load to copy its contents"
msgstr ""
@@ -40312,6 +41143,15 @@ msgstr ""
msgid "Webhooks|An issue is created, updated, closed, or reopened."
msgstr ""
+msgid "Webhooks|Are you sure you want to delete this group hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this project hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this webhook?"
+msgstr ""
+
msgid "Webhooks|Comments"
msgstr ""
@@ -40321,6 +41161,9 @@ msgstr ""
msgid "Webhooks|Confidential issues events"
msgstr ""
+msgid "Webhooks|Delete webhook"
+msgstr ""
+
msgid "Webhooks|Deployment events"
msgstr ""
@@ -40554,6 +41397,9 @@ msgstr ""
msgid "Wiki"
msgstr ""
+msgid "Wiki page"
+msgstr ""
+
msgid "Wiki page was successfully created."
msgstr ""
@@ -40659,7 +41505,7 @@ msgstr ""
msgid "WikiPageConflictMessage|Someone edited the page the same time you did. Please check out %{wikiLinkStart}the page%{wikiLinkEnd} and make sure your changes will not unintentionally remove theirs."
msgstr ""
-msgid "WikiPage|An error occured while trying to render the content editor. Please try again later."
+msgid "WikiPage|An error occurred while trying to render the content editor. Please try again later."
msgstr ""
msgid "WikiPage|Are you sure you want to switch back to the classic editor?"
@@ -40818,6 +41664,18 @@ msgstr ""
msgid "WorkItem|New Task"
msgstr ""
+msgid "WorkItem|Something went wrong when creating a work item. Please try again"
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching the work item. Please try again."
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching work item types. Please try again"
+msgstr ""
+
+msgid "WorkItem|Type"
+msgstr ""
+
msgid "WorkItem|Work Items"
msgstr ""
@@ -40884,7 +41742,10 @@ msgstr ""
msgid "You are about to add %{usersTag} people to the discussion. They will all receive a notification."
msgstr ""
-msgid "You are about to permanently delete this project"
+msgid "You are about to delete this forked project containing:"
+msgstr ""
+
+msgid "You are about to delete this project containing:"
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."
@@ -40905,6 +41766,9 @@ msgstr ""
msgid "You are attempting to update a file that has changed since you started editing it."
msgstr ""
+msgid "You are billed if you exceed this number. %{qsrOverageLinkStart}How does billing work?%{qsrOverageLinkEnd}"
+msgstr ""
+
msgid "You are connected to the Prometheus server, but there is currently no data to display."
msgstr ""
@@ -40962,6 +41826,9 @@ msgstr ""
msgid "You are not authorized to update this scanner profile"
msgstr ""
+msgid "You are not authorized to upload metric images"
+msgstr ""
+
msgid "You are now impersonating %{username}"
msgstr ""
@@ -41115,9 +41982,6 @@ msgstr ""
msgid "You can only upload one design when dropping onto an existing design."
msgstr ""
-msgid "You can recover this project until %{date}"
-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 ""
@@ -41166,9 +42030,6 @@ msgstr ""
msgid "You cannot write to this read-only GitLab instance."
msgstr ""
-msgid "You can’t %{tag_start}edit%{tag_end} files directly in this project. Fork this project and submit a merge request with your changes."
-msgstr ""
-
msgid "You can’t edit files directly in this project. Fork this project and submit a merge request with your changes."
msgstr ""
@@ -41321,9 +42182,6 @@ 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 set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
@@ -41354,12 +42212,6 @@ msgstr ""
msgid "You must have maintainer access to force delete a lock"
msgstr ""
-msgid "You must have permission to create a project in a group before forking."
-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 ""
@@ -41765,7 +42617,7 @@ msgstr ""
msgid "Your public email will be displayed on your public profile."
msgstr ""
-msgid "Your request for access could not be processed: %{error_meesage}"
+msgid "Your request for access could not be processed: %{error_message}"
msgstr ""
msgid "Your request for access has been queued for review."
@@ -41948,6 +42800,9 @@ msgstr ""
msgid "archived:"
msgstr ""
+msgid "artifacts"
+msgstr ""
+
msgid "assign yourself"
msgstr ""
@@ -41977,6 +42832,9 @@ msgstr[1] ""
msgid "branch name"
msgstr ""
+msgid "builds"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -42400,6 +43258,9 @@ msgstr ""
msgid "contact with same email already exists in group hierarchy"
msgstr ""
+msgid "container registry images"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -42439,6 +43300,9 @@ msgstr ""
msgid "data"
msgstr ""
+msgid "database"
+msgstr ""
+
msgid "date must not be after 9999-12-31"
msgstr ""
@@ -42462,9 +43326,6 @@ msgstr ""
msgid "design"
msgstr ""
-msgid "detached"
-msgstr ""
-
msgid "disabled"
msgstr ""
@@ -42713,7 +43574,7 @@ msgstr ""
msgid "is not a valid X509 certificate."
msgstr ""
-msgid "is not allowed for sign-up."
+msgid "is not allowed for sign-up. Please use your regular email address."
msgstr ""
msgid "is not allowed for this group."
@@ -42725,7 +43586,7 @@ msgstr ""
msgid "is not allowed since the group is not top-level group."
msgstr ""
-msgid "is not allowed."
+msgid "is not allowed. Please use your regular email address."
msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
@@ -42812,6 +43673,9 @@ msgstr ""
msgid "level: %{level}"
msgstr ""
+msgid "lfs objects"
+msgstr ""
+
msgid "limit of %{project_limit} reached"
msgstr ""
@@ -43031,6 +43895,9 @@ msgstr ""
msgid "mrWidget|Merge blocked: pipeline must succeed. It's waiting for a manual action to continue."
msgstr ""
+msgid "mrWidget|Merge blocked: pipeline must succeed. Push a commit that fixes the failure, or %{linkStart}learn about other solutions.%{linkEnd}"
+msgstr ""
+
msgid "mrWidget|Merge blocked: this merge request must be approved."
msgstr ""
@@ -43148,9 +44015,6 @@ msgstr ""
msgid "mrWidget|The changes were not merged into"
msgstr ""
-msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -43298,9 +44162,6 @@ msgstr ""
msgid "open issue"
msgstr ""
-msgid "opened %{timeAgo}"
-msgstr ""
-
msgid "or"
msgstr ""
@@ -43312,6 +44173,12 @@ msgid_plural "out of %d total tests"
msgstr[0] ""
msgstr[1] ""
+msgid "packages"
+msgstr ""
+
+msgid "pages"
+msgstr ""
+
msgid "parent"
msgid_plural "parents"
msgstr[0] ""
@@ -43461,6 +44328,9 @@ msgid_plural "replies"
msgstr[0] ""
msgstr[1] ""
+msgid "repositories"
+msgstr ""
+
msgid "repository:"
msgstr ""
@@ -43581,12 +44451,18 @@ msgstr ""
msgid "tag name"
msgstr ""
+msgid "terraform states"
+msgstr ""
+
msgid "the correct format."
msgstr ""
msgid "the file"
msgstr ""
+msgid "the following epic(s)"
+msgstr ""
+
msgid "the following issue(s)"
msgstr ""
@@ -43599,21 +44475,12 @@ msgstr ""
msgid "this document"
msgstr ""
-msgid "this issue cannot be assigned to a confidential epic since it is public"
-msgstr ""
-
-msgid "this issue cannot be made public since it belongs to a confidential epic"
-msgstr ""
-
msgid "time summary"
msgstr ""
msgid "toggle collapse"
msgstr ""
-msgid "train"
-msgstr ""
-
msgid "triggered"
msgstr ""
@@ -43742,3 +44609,6 @@ msgstr ""
msgid "{project}"
msgstr ""
+msgid "✔"
+msgstr ""
+
diff --git a/locale/ko/gitlab.po b/locale/ko/gitlab.po
index cf64ff655a3..004f4e41218 100644
--- a/locale/ko/gitlab.po
+++ b/locale/ko/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: ko\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2022-02-02 15:46\n"
+"PO-Revision-Date: 2022-03-01 20:39\n"
msgid " %{start} to %{end}"
msgstr " %{start}부터 %{end}까지"
@@ -132,6 +132,10 @@ msgid "%d approver (you've approved)"
msgid_plural "%d approvers (you've approved)"
msgstr[0] "%dëª…ì˜ ìŠ¹ì¸ìž (ë‚´ê°€ 승ì¸í•¨)"
+msgid "%d assigned issue"
+msgid_plural "%d assigned issues"
+msgstr[0] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] "%dê°œì˜ ë³€ê²½ëœ íŒŒì¼"
@@ -352,9 +356,21 @@ msgid "%d vulnerability dismissed"
msgid_plural "%d vulnerabilities dismissed"
msgstr[0] "%dê°œì˜ ì·¨ì•½ì  ë¬´ì‹œë¨"
-msgid "%d vulnerability updated"
-msgid_plural "%d vulnerabilities updated"
-msgstr[0] "%dê°œì˜ ì·¨ì•½ì ì´ ì—…ë°ì´íŠ¸ë¨"
+msgid "%d vulnerability set to confirmed"
+msgid_plural "%d vulnerabilities set to confirmed"
+msgstr[0] ""
+
+msgid "%d vulnerability set to dismissed"
+msgid_plural "%d vulnerabilities set to dismissed"
+msgstr[0] ""
+
+msgid "%d vulnerability set to needs triage"
+msgid_plural "%d vulnerabilities set to needs triage"
+msgstr[0] ""
+
+msgid "%d vulnerability set to resolved"
+msgid_plural "%d vulnerabilities set to resolved"
+msgstr[0] ""
msgid "%d warning found:"
msgid_plural "%d warnings found:"
@@ -434,6 +450,12 @@ msgstr[0] ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{completed} of %{total} issues closed"
+msgstr ""
+
+msgid "%{completed} of %{total} weight completed"
+msgstr ""
+
msgid "%{cores} cores"
msgstr "%{cores} 코어"
@@ -776,6 +798,9 @@ msgstr "%{openedEpics}개 열림, %{closedEpics}개 닫힘"
msgid "%{openedIssues} open, %{closedIssues} closed"
msgstr "%{openedIssues}개 열림, %{closedIssues}개 닫힘"
+msgid "%{percentage}%% issues closed"
+msgstr ""
+
msgid "%{percentage}%% weight completed"
msgstr ""
@@ -1190,6 +1215,9 @@ msgid "- User"
msgid_plural "- Users"
msgstr[0] "- 사용ìž"
+msgid "- of - issues closed"
+msgstr ""
+
msgid "- of - weight completed"
msgstr ""
@@ -1309,8 +1337,8 @@ msgstr "10 ê°œ ì´ìƒ 참여"
msgid "1000+"
msgstr "1000+"
-msgid "192.168.0.0/24"
-msgstr "192.168.0.0/24"
+msgid "192.168.0.0/24 or 2001:0DB8:1234::/48"
+msgstr ""
msgid "1st contribution!"
msgstr "첫번째 기여!"
@@ -1621,14 +1649,14 @@ msgstr ""
msgid "AWS Access Key"
msgstr "AWS 엑세스 키"
-msgid "AWS Access Key. Only required if not using role instance credentials"
-msgstr "AWS 액세스 키. ì—­í•  ì¸ìŠ¤í„´ìŠ¤ ìžê²© ì¦ëª…ì„ ì‚¬ìš©í•˜ì§€ 않는 경우ì—만 í•„ìš”"
-
msgid "AWS Secret Access Key"
msgstr "AWS 비밀 액세스 키"
-msgid "AWS Secret Access Key. Only required if not using role instance credentials"
-msgstr "AWS 비밀 액세스 키. ì—­í•  ì¸ìŠ¤í„´ìŠ¤ ìžê²© ì¦ëª…ì„ ì‚¬ìš©í•˜ì§€ 않는 경우ì—만 í•„ìš”"
+msgid "AWS access key ID (Optional)"
+msgstr ""
+
+msgid "AWS secret access key (Optional)"
+msgstr ""
msgid "AWS service error: %{error}"
msgstr "AWS 서비스 ì—러 : %{error}"
@@ -1687,9 +1715,6 @@ msgstr "액세스 금지. ì ‘ê·¼ ê¶Œí•œì„ í™•ì¸í•˜ì„¸ìš”."
msgid "Access granted"
msgstr ""
-msgid "Access key ID"
-msgstr ""
-
msgid "Access requests"
msgstr ""
@@ -1864,7 +1889,7 @@ msgstr ""
msgid "Activity"
msgstr "활ë™"
-msgid "Activity|An error occured while retrieving activity. Reload the page to try again."
+msgid "Activity|An error occurred while retrieving activity. Reload the page to try again."
msgstr ""
msgid "Add"
@@ -1903,6 +1928,9 @@ msgstr "Zoom 미팅 추가"
msgid "Add a %{type}"
msgstr ""
+msgid "Add a GCP region"
+msgstr ""
+
msgid "Add a GPG key"
msgstr "GPG 키 추가"
@@ -1954,6 +1982,9 @@ msgstr "ì´ìŠˆ 추가"
msgid "Add a numbered list"
msgstr "번호 매기기 ëª©ë¡ ì¶”ê°€"
+msgid "Add a related epic"
+msgstr ""
+
msgid "Add a related issue"
msgstr "관련 ì´ìŠˆ 추가"
@@ -2068,6 +2099,9 @@ msgstr ""
msgid "Add or subtract spent time"
msgstr ""
+msgid "Add people"
+msgstr ""
+
msgid "Add previously merged commits"
msgstr "ì´ì „ì— ë¨¸ì§€ëœ ì»¤ë°‹ 추가"
@@ -2134,6 +2168,9 @@ msgstr ""
msgid "Add webhook"
msgstr "웹훅 추가"
+msgid "Add your team members and others to GitLab."
+msgstr ""
+
msgid "Add/remove"
msgstr "추가/제거"
@@ -2956,12 +2993,6 @@ msgstr ""
msgid "AdvancedSearch|Reindex required"
msgstr ""
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. Permanently deleting this project will %{strongStart}immediately delete%{strongEnd} its repositories and %{strongStart}all related resources%{strongEnd}, including issues, merge requests etc."
-msgstr ""
-
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. You will lose this project's repository and %{strongStart}all related resources%{strongEnd}, including issues and merge requests."
-msgstr ""
-
msgid "After a successful password update you will be redirected to login screen."
msgstr "비밀번호가 성공ì ìœ¼ë¡œ ë³€ê²½ëœ ë’¤ì— ë¡œê·¸ì¸ í™”ë©´ìœ¼ë¡œ ì´ë™ 합니다."
@@ -2992,6 +3023,9 @@ msgstr ""
msgid "Akismet helps prevent the creation of spam issues in public projects."
msgstr ""
+msgid "Alert"
+msgstr ""
+
msgid "AlertManagement|Acknowledged"
msgstr ""
@@ -3364,9 +3398,6 @@ msgstr "모든 ì´ë©”ì¼ ì£¼ì†ŒëŠ” ì»¤ë°‹ì„ ì‹ë³„하는 ë° ì‚¬ìš©ë©ë‹ˆë‹¤."
msgid "All environments"
msgstr ""
-msgid "All epics"
-msgstr "모든 ì—픽"
-
msgid "All groups and projects"
msgstr "모든 그룹과 프로ì íŠ¸"
@@ -4101,11 +4132,14 @@ msgstr ""
msgid "ApplicationSettings|Approve users in the pending approval status?"
msgstr ""
-msgid "ApplicationSettings|By making this change, you will automatically approve %d user with the pending approval status."
-msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users with the pending approval status."
+msgid "ApplicationSettings|Approve users who are pending approval?"
+msgstr ""
+
+msgid "ApplicationSettings|By making this change, you will automatically approve %d user who is pending approval."
+msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users who are pending approval."
msgstr[0] ""
-msgid "ApplicationSettings|By making this change, you will automatically approve all users in pending approval status."
+msgid "ApplicationSettings|By making this change, you will automatically approve all users who are pending approval."
msgstr ""
msgid "ApplicationSettings|Denied domains for sign-ups"
@@ -4506,10 +4540,10 @@ msgstr "ì•„ì¹´ì´ë¸Œëœ 프로ì íŠ¸"
msgid "Archiving the project will make it entirely read-only. It is hidden from the dashboard and doesn't show up in searches. %{strong_start}The repository cannot be committed to, and no issues, comments, or other entities can be created.%{strong_end} %{link_start}Learn more.%{link_end}"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to delete this project?"
+msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
+msgid "Are you absolutely sure?"
msgstr ""
msgid "Are you sure that you want to archive this project?"
@@ -4545,12 +4579,18 @@ msgstr ""
msgid "Are you sure you want to delete this SSH key?"
msgstr ""
+msgid "Are you sure you want to delete this comment?"
+msgstr ""
+
msgid "Are you sure you want to delete this deploy key?"
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 label?"
+msgstr ""
+
msgid "Are you sure you want to delete this pipeline schedule?"
msgstr "ì´ íŒŒì´í”„ë¼ì¸ ìŠ¤ì¼€ì¥´ì„ ì‚­ì œ 하시겠습니까?"
@@ -4566,9 +4606,6 @@ msgstr ""
msgid "Are you sure you want to discard your changes?"
msgstr ""
-msgid "Are you sure you want to erase this build?"
-msgstr "ì •ë§ë¡œ ì´ ë¹Œë“œë¥¼ 지우시겠습니까?"
-
msgid "Are you sure you want to import %d repository?"
msgid_plural "Are you sure you want to import %d repositories?"
msgstr[0] ""
@@ -4615,6 +4652,9 @@ msgstr "ì •ë§ë¡œ 해당 í•­ëª©ì„ ì‚­ì œí•˜ì‹œê² ìŠµë‹ˆê¹Œ?"
msgid "Are you sure you want to remove this list?"
msgstr ""
+msgid "Are you sure you want to remove this nickname?"
+msgstr ""
+
msgid "Are you sure you want to reset the health check token?"
msgstr "헬스 ì²´í¬ í† í°ì„ 초기화 하시겠습니까?"
@@ -4627,10 +4667,10 @@ 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?"
+msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
msgstr ""
-msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
+msgid "Are you sure you want to revoke this project access token? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to stop this environment?"
@@ -4777,9 +4817,6 @@ msgstr ""
msgid "Assigned to %{assignee_name}"
msgstr ""
-msgid "Assigned to %{name}"
-msgstr ""
-
msgid "Assigned to me"
msgstr "나ì—게 할당 ë¨"
@@ -4842,6 +4879,9 @@ msgstr[0] ""
msgid "Attaching the file failed."
msgstr "íŒŒì¼ ì²¨ë¶€ê°€ 실패했습니다."
+msgid "Attention"
+msgstr ""
+
msgid "Audit Events"
msgstr "ê°ì‚¬ ì´ë²¤íŠ¸"
@@ -5004,6 +5044,12 @@ msgstr ""
msgid "Authorized applications (%{size})"
msgstr "ì¸ì¦ëœ 애플리케ì´ì…˜ (%{size})"
+msgid "AuthorizedApplication|Are you sure you want to revoke this application?"
+msgstr ""
+
+msgid "AuthorizedApplication|Revoke application"
+msgstr ""
+
msgid "Authors: %{authors}"
msgstr "작성ìž: %{authors}"
@@ -6193,6 +6239,9 @@ msgstr ""
msgid "CICDAnalytics|Shared Runners Usage"
msgstr ""
+msgid "CICDAnalytics|Shared runner pipeline minute duration by month"
+msgstr ""
+
msgid "CICDAnalytics|Shared runner usage"
msgstr ""
@@ -6334,6 +6383,9 @@ msgstr ""
msgid "Can create groups:"
msgstr "그룹 ìƒì„± 가능:"
+msgid "Can not delete primary training"
+msgstr ""
+
msgid "Can't apply as the source branch was deleted."
msgstr ""
@@ -6667,9 +6719,6 @@ msgstr ""
msgid "Changing any setting here requires an application restart"
msgstr ""
-msgid "Changing group URL can have unintended side effects."
-msgstr ""
-
msgid "Charts can't be displayed as the request for data has timed out. %{documentationLink}"
msgstr ""
@@ -6757,9 +6806,6 @@ msgstr "ìŠ¹ì¸ ìƒí™©ì„ ì²´í¬í•©ë‹ˆë‹¤."
msgid "Checking branch availability..."
msgstr "브랜치가 사용 가능한지 í™•ì¸ ì¤‘..."
-msgid "Checking group URL availability..."
-msgstr ""
-
msgid "Checking group path availability..."
msgstr ""
@@ -7251,6 +7297,9 @@ msgstr ""
msgid "Clear recent searches"
msgstr "최근 검색 지우기"
+msgid "Clear repository checks"
+msgstr ""
+
msgid "Clear search"
msgstr "검색 지우기"
@@ -7383,9 +7432,6 @@ msgstr ""
msgid "Closed MRs"
msgstr ""
-msgid "Closed epics"
-msgstr ""
-
msgid "Closed issues"
msgstr "닫힌 ì´ìŠˆ"
@@ -7422,13 +7468,13 @@ msgstr ""
msgid "Cluster level"
msgstr ""
-msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
+msgid "Cluster type must be specified for Stages::ClusterEndpointInserter"
msgstr ""
msgid "ClusterAgents|%{name} successfully deleted"
msgstr ""
-msgid "ClusterAgents|%{number} of %{total} Agents"
+msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
@@ -7470,6 +7516,15 @@ msgstr ""
msgid "ClusterAgents|Agent never connected to GitLab"
msgstr ""
+msgid "ClusterAgents|Agent version mismatch"
+msgstr ""
+
+msgid "ClusterAgents|Agent version mismatch and update"
+msgstr ""
+
+msgid "ClusterAgents|Agent version update required"
+msgstr ""
+
msgid "ClusterAgents|All"
msgstr ""
@@ -7494,7 +7549,7 @@ msgstr ""
msgid "ClusterAgents|Configuration"
msgstr ""
-msgid "ClusterAgents|Connect a cluster through the Agent"
+msgid "ClusterAgents|Connect a cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connect existing cluster"
@@ -7503,13 +7558,13 @@ msgstr ""
msgid "ClusterAgents|Connect with a certificate"
msgstr ""
-msgid "ClusterAgents|Connect with agent"
+msgid "ClusterAgents|Connect with an agent"
msgstr ""
msgid "ClusterAgents|Connect with the GitLab Agent"
msgstr ""
-msgid "ClusterAgents|Connect your cluster through the Agent"
+msgid "ClusterAgents|Connect your cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connected"
@@ -7569,7 +7624,10 @@ msgstr ""
msgid "ClusterAgents|How to register an agent?"
msgstr ""
-msgid "ClusterAgents|Install new Agent"
+msgid "ClusterAgents|How to update an agent?"
+msgstr ""
+
+msgid "ClusterAgents|Install a new agent"
msgstr ""
msgid "ClusterAgents|Last connected %{timeAgo}."
@@ -7596,7 +7654,7 @@ msgstr ""
msgid "ClusterAgents|Never connected"
msgstr ""
-msgid "ClusterAgents|No Agents"
+msgid "ClusterAgents|No agents"
msgstr ""
msgid "ClusterAgents|No clusters connected through cluster certificates"
@@ -7656,6 +7714,9 @@ msgstr ""
msgid "ClusterAgents|The agent has not been connected in a long time. There might be a connectivity issue. Last contact was %{timeAgo}."
msgstr ""
+msgid "ClusterAgents|The agent version do not match each other across your cluster's pods. This can happen when a new agent version was just deployed and Kubernetes is shutting down the old pods."
+msgstr ""
+
msgid "ClusterAgents|The recommended installation method includes the token. If you want to follow the advanced installation method provided in the docs, make sure you save the token value before you close this window."
msgstr ""
@@ -7702,6 +7763,9 @@ msgstr ""
msgid "ClusterAgents|You will need to create a token to connect to your agent"
msgstr ""
+msgid "ClusterAgents|Your agent version is out of sync with your GitLab version (v%{version}), which might cause compatibility problems. Update the agent installed on your cluster to the most recent version."
+msgstr ""
+
msgid "ClusterAgents|Your instance doesn't have the %{linkStart}GitLab Agent Server (KAS)%{linkEnd} set up. Ask a GitLab Administrator to install it."
msgstr ""
@@ -8578,9 +8642,6 @@ msgstr ""
msgid "Comma-separated list of email addresses."
msgstr ""
-msgid "Comma-separated list of users allowed to exceed the rate limit."
-msgstr ""
-
msgid "Comma-separated, e.g. '1.1.1.1, 2.2.2.0/24'"
msgstr ""
@@ -8906,6 +8967,12 @@ msgstr ""
msgid "Confidential"
msgstr "비밀"
+msgid "Confidential issue"
+msgstr ""
+
+msgid "Confidential note"
+msgstr ""
+
msgid "Confidentiality"
msgstr "비밀"
@@ -8939,6 +9006,9 @@ msgstr ""
msgid "Configure Dependency Scanning in `.gitlab-ci.yml`, creating this file if it does not already exist"
msgstr ""
+msgid "Configure GitLab"
+msgstr ""
+
msgid "Configure GitLab runners to start using the Web Terminal. %{helpStart}Learn more.%{helpEnd}"
msgstr "웹 í„°ë¯¸ë„ ì‚¬ìš©ì„ ì‹œìž‘í•˜ë„ë¡ GitLab 러너를 구성하십시오. %{helpStart}ìžì„¸ížˆ 알아보십시오.%{helpEnd}"
@@ -8987,6 +9057,15 @@ msgstr ""
msgid "Configure pipelines to deploy web apps, backend services, APIs and static resources to Google Cloud"
msgstr ""
+msgid "Configure region"
+msgstr ""
+
+msgid "Configure region for environment"
+msgstr ""
+
+msgid "Configure regions"
+msgstr ""
+
msgid "Configure repository mirroring."
msgstr ""
@@ -9020,6 +9099,9 @@ msgstr ""
msgid "Configure which lists are shown for anyone who visits this board"
msgstr ""
+msgid "Configure your environments to be deployed to specific geographical regions"
+msgstr ""
+
msgid "Confirm"
msgstr "확ì¸"
@@ -9719,10 +9801,10 @@ msgstr ""
msgid "CorpusManagement|Actions"
msgstr ""
-msgid "CorpusManagement|Corpus are used in fuzz testing as mutation source to Improve future testing."
+msgid "CorpusManagement|Corpus file"
msgstr ""
-msgid "CorpusManagement|Corpus file"
+msgid "CorpusManagement|Corpus files are used in coverage-guided fuzz testing as seed inputs to improve testing."
msgstr ""
msgid "CorpusManagement|Corpus files must be in *.zip format. Maximum 5 GB"
@@ -9776,6 +9858,9 @@ msgstr ""
msgid "Could not apply %{name} command."
msgstr ""
+msgid "Could not apply %{name} command. %{message}."
+msgstr ""
+
msgid "Could not authorize chat nickname. Try again!"
msgstr "채팅 ë‹‰ë„¤ìž„ì„ ì¸ì¦í•˜ì§€ 못했습니다. 다시 ì‹œë„하세요!"
@@ -9926,6 +10011,9 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
+msgid "Create a group"
+msgstr ""
+
msgid "Create a merge request"
msgstr ""
@@ -9950,6 +10038,9 @@ msgstr "새 저장소 만들기"
msgid "Create a personal access token on your account to pull or push via %{protocol}."
msgstr "%{protocol}ì„ (를) 통해 Pull 하거나 Push í•  ê°œì¸ ì•¡ì„¸ìŠ¤ 토í°ì„ 만드십시오."
+msgid "Create a project"
+msgstr ""
+
msgid "Create an account using:"
msgstr ""
@@ -10313,6 +10404,9 @@ msgstr ""
msgid "Creation date"
msgstr "ìƒì„± 날짜"
+msgid "Creator"
+msgstr ""
+
msgid "Credentials"
msgstr ""
@@ -10325,9 +10419,15 @@ msgstr ""
msgid "CredentialsInventory|Personal Access Tokens"
msgstr ""
+msgid "CredentialsInventory|Project Access Tokens"
+msgstr ""
+
msgid "CredentialsInventory|SSH Keys"
msgstr ""
+msgid "Credit card required to be on file in order to create a pipeline"
+msgstr ""
+
msgid "Credit card:"
msgstr ""
@@ -10511,9 +10611,6 @@ msgstr ""
msgid "Customer relations"
msgstr ""
-msgid "Customizable by an administrator."
-msgstr ""
-
msgid "Customizable by owners."
msgstr ""
@@ -10643,30 +10740,18 @@ msgstr ""
msgid "CycleAnalytics|%{selectedLabelsCount} selected (%{maxLabels} max)"
msgstr ""
-msgid "CycleAnalytics|%{stageCount} stages selected"
-msgstr ""
-
-msgid "CycleAnalytics|All stages"
-msgstr ""
-
-msgid "CycleAnalytics|Average days to completion"
+msgid "CycleAnalytics|Average time to completion"
msgstr ""
msgid "CycleAnalytics|Date"
msgstr ""
-msgid "CycleAnalytics|Days to completion"
-msgstr ""
-
msgid "CycleAnalytics|Display chart filters"
msgstr ""
msgid "CycleAnalytics|Lead Time for Changes"
msgstr ""
-msgid "CycleAnalytics|No stages selected"
-msgstr ""
-
msgid "CycleAnalytics|Number of tasks"
msgstr ""
@@ -10693,18 +10778,30 @@ msgstr ""
msgid "CycleAnalytics|Showing data for group '%{groupName}' from %{createdAfter} to %{createdBefore}"
msgstr ""
-msgid "CycleAnalytics|Stages"
+msgid "CycleAnalytics|Stage time: %{title}"
msgstr ""
msgid "CycleAnalytics|Tasks by type"
msgstr ""
-msgid "CycleAnalytics|The average time spent in the selected stage for the items that were completed on each date. Data limited to the last 500 items."
+msgid "CycleAnalytics|The average time items spent in this stage. Data limited to items completed within this date range."
msgstr ""
msgid "CycleAnalytics|The given date range is larger than 180 days"
msgstr ""
+msgid "CycleAnalytics|The total time items spent across each value stream stage. Data limited to items completed within this date range."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Stage time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Total time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|Total time"
+msgstr ""
+
msgid "CycleAnalytics|Type of work"
msgstr ""
@@ -10717,9 +10814,6 @@ msgstr ""
msgid "CycleAnalytics|project dropdown filter"
msgstr ""
-msgid "CycleAnalytics|stage dropdown"
-msgstr ""
-
msgid "DAG visualization requires at least 3 dependent jobs."
msgstr ""
@@ -10819,10 +10913,16 @@ msgstr ""
msgid "DastProfiles|AJAX spider"
msgstr ""
+msgid "DastProfiles|API"
+msgstr ""
+
+msgid "DastProfiles|API endpoint URL"
+msgstr ""
+
msgid "DastProfiles|Active"
msgstr ""
-msgid "DastProfiles|Additional request headers (Optional)"
+msgid "DastProfiles|Additional request headers (optional)"
msgstr ""
msgid "DastProfiles|Are you sure you want to delete this profile?"
@@ -10837,6 +10937,9 @@ msgstr ""
msgid "DastProfiles|Branch missing"
msgstr ""
+msgid "DastProfiles|Choose a scan method"
+msgstr ""
+
msgid "DastProfiles|Could not create the scanner profile. Please try again."
msgstr ""
@@ -10906,7 +11009,13 @@ msgstr ""
msgid "DastProfiles|Excluded URLs"
msgstr ""
-msgid "DastProfiles|Excluded URLs (Optional)"
+msgid "DastProfiles|Excluded URLs (optional)"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths (optional)"
msgstr ""
msgid "DastProfiles|Hide debug messages"
@@ -10963,9 +11072,6 @@ msgstr ""
msgid "DastProfiles|Request headers"
msgstr ""
-msgid "DastProfiles|Rest API"
-msgstr ""
-
msgid "DastProfiles|Run the AJAX spider, in addition to the traditional spider, to crawl the target site."
msgstr ""
@@ -10975,6 +11081,9 @@ msgstr ""
msgid "DastProfiles|Save profile"
msgstr ""
+msgid "DastProfiles|Scan method"
+msgstr ""
+
msgid "DastProfiles|Scan mode"
msgstr ""
@@ -11053,12 +11162,24 @@ msgstr ""
msgid "DastProfiles|Website"
msgstr ""
+msgid "DastProfiles|What does each method do?"
+msgstr ""
+
msgid "DastProfiles|You can either choose a passive scan or validate the target site from the site profile management page. %{docsLinkStart}Learn more about site validation.%{docsLinkEnd}"
msgstr ""
msgid "DastProfiles|You cannot run an active scan against an unvalidated site."
msgstr ""
+msgid "DastProfiles|folder/dast_example.har or https://example.com/dast_example.har"
+msgstr ""
+
+msgid "DastProfiles|folder/example.postman_collection.json or https://example.com/"
+msgstr ""
+
+msgid "DastProfiles|folder/openapi.json or https://example.com/openapi.json"
+msgstr ""
+
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
@@ -11165,6 +11286,9 @@ msgstr ""
msgid "DatadogIntegration|API URL"
msgstr ""
+msgid "DatadogIntegration|Custom tags in Datadog. Enter one tag per line in the %{codeOpen}key:value%{codeClose} format. %{linkOpen}How do I use tags?%{linkClose}"
+msgstr ""
+
msgid "DatadogIntegration|Environment"
msgstr ""
@@ -11183,12 +11307,18 @@ msgstr ""
msgid "DatadogIntegration|Tag all data from this GitLab instance in Datadog. Useful when managing several self-managed deployments."
msgstr ""
+msgid "DatadogIntegration|Tags"
+msgstr ""
+
msgid "DatadogIntegration|The Datadog site to send data to. To send data to the EU site, use %{codeOpen}datadoghq.eu%{codeClose}."
msgstr ""
msgid "DatadogIntegration|Trace your GitLab pipelines with Datadog."
msgstr ""
+msgid "DatadogIntegration|have an invalid format"
+msgstr ""
+
msgid "Datasource name not found"
msgstr ""
@@ -11198,9 +11328,6 @@ msgstr "날짜"
msgid "Date merged"
msgstr ""
-msgid "Date picker"
-msgstr "날짜 ì„ íƒ"
-
msgid "Date range"
msgstr ""
@@ -11354,9 +11481,6 @@ msgstr ""
msgid "Definition"
msgstr ""
-msgid "Delayed Project Deletion (%{adjourned_deletion})"
-msgstr ""
-
msgid "DelayedJobs|Are you sure you want to run %{jobName} immediately? Otherwise this job will run automatically after its timer finishes."
msgstr ""
@@ -11435,12 +11559,12 @@ msgstr ""
msgid "Delete pipeline"
msgstr "파ì´í”„ë¼ì¸ ì‚­ì œ"
+msgid "Delete pipeline schedule"
+msgstr ""
+
msgid "Delete project"
msgstr "프로ì íŠ¸ ì‚­ì œ"
-msgid "Delete project. Are you ABSOLUTELY SURE?"
-msgstr ""
-
msgid "Delete row"
msgstr ""
@@ -11468,6 +11592,9 @@ msgstr ""
msgid "Delete this epic and all descendants?"
msgstr ""
+msgid "Delete this project"
+msgstr ""
+
msgid "Delete user list"
msgstr ""
@@ -11720,6 +11847,12 @@ msgstr ""
msgid "Deploy to..."
msgstr ""
+msgid "DeployBoards|To see deployment progress for your environments, make sure you are deploying to %{codeStart}$KUBE_NAMESPACE%{codeEnd} and annotating with %{codeStart}app.gitlab.com/app=$CI_PROJECT_PATH_SLUG%{codeEnd} and %{codeStart}app.gitlab.com/env=$CI_ENVIRONMENT_SLUG%{codeEnd}."
+msgstr ""
+
+msgid "DeployBoard|Kubernetes Pods"
+msgstr ""
+
msgid "DeployFreeze|Add a freeze period to prevent unintended releases during a period of time for a given environment. You must update the deployment jobs in %{filename} according to the deploy freezes added here. %{freeze_period_link_start}Learn more.%{freeze_period_link_end}"
msgstr ""
@@ -11804,9 +11937,6 @@ msgstr "ì½ê¸° 엑세스 ì „ìš©"
msgid "DeployTokens|Active Deploy Tokens (%{active_tokens})"
msgstr "활성 ë°°í¬ í† í° (%{active_tokens})"
-msgid "DeployTokens|Allows read and write access to registry images."
-msgstr ""
-
msgid "DeployTokens|Allows read and write access to the package registry."
msgstr ""
@@ -11819,6 +11949,9 @@ msgstr ""
msgid "DeployTokens|Allows read-only access to the repository."
msgstr ""
+msgid "DeployTokens|Allows write access to registry images."
+msgstr ""
+
msgid "DeployTokens|Copy deploy token"
msgstr ""
@@ -11912,12 +12045,57 @@ msgstr ""
msgid "Deploying to AWS is easy with GitLab"
msgstr ""
+msgid "Deployment"
+msgstr ""
+
msgid "Deployment Frequency"
msgstr ""
+msgid "Deployment Target|Project deployment target (optional)"
+msgstr ""
+
+msgid "Deployment Target|Select the deployment target"
+msgstr ""
+
msgid "Deployment frequency"
msgstr ""
+msgid "DeploymentTarget|GitLab Pages"
+msgstr ""
+
+msgid "DeploymentTarget|Heroku"
+msgstr ""
+
+msgid "DeploymentTarget|Infrastructure provider (Terraform, Cloudformation, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Kubernetes (GKE, EKS, OpenShift, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Managed container runtime (Fargate, Cloud Run, DigitalOcean App)"
+msgstr ""
+
+msgid "DeploymentTarget|Mobile app store"
+msgstr ""
+
+msgid "DeploymentTarget|No deployment planned"
+msgstr ""
+
+msgid "DeploymentTarget|Other hosting service"
+msgstr ""
+
+msgid "DeploymentTarget|Registry (package or container)"
+msgstr ""
+
+msgid "DeploymentTarget|Self-managed container runtime (Podman, Docker Swarm, Docker Compose)"
+msgstr ""
+
+msgid "DeploymentTarget|Serverless backend (Lambda, Cloud functions)"
+msgstr ""
+
+msgid "DeploymentTarget|Virtual machine (for example, EC2)"
+msgstr ""
+
msgid "Deployments"
msgstr ""
@@ -11955,6 +12133,9 @@ msgstr ""
msgid "Deployment|This deployment was created using the API"
msgstr ""
+msgid "Deployment|Triggerer"
+msgstr ""
+
msgid "Deployment|Waiting"
msgstr ""
@@ -11982,6 +12163,18 @@ msgstr ""
msgid "Deprecated API rate limits"
msgstr ""
+msgid "Deprecations|Feature deprecation and removal"
+msgstr ""
+
+msgid "Deprecations|For information on a possible replacement %{epicStart} learn more about Opstrace %{epicEnd}."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7 and are %{epicStart} scheduled for removal %{epicEnd} in GitLab 15.0."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7, and are %{removal_link_start} scheduled for removal %{link_end} in GitLab 15.0. For information on a possible replacement, %{opstrace_link_start} learn more about Opstrace %{link_end}."
+msgstr ""
+
msgid "Deprioritize label"
msgstr "ë¼ë²¨ ìš°ì„  순위 낮추기"
@@ -12226,10 +12419,10 @@ msgstr ""
msgid "DevopsAdoption|At least one deploy"
msgstr ""
-msgid "DevopsAdoption|At least one issue opened"
+msgid "DevopsAdoption|At least one issue created"
msgstr ""
-msgid "DevopsAdoption|At least one merge request opened"
+msgid "DevopsAdoption|At least one merge request created"
msgstr ""
msgid "DevopsAdoption|At least one pipeline successfully run"
@@ -12427,6 +12620,9 @@ msgstr ""
msgid "Direct member"
msgstr ""
+msgid "Direct members"
+msgstr ""
+
msgid "Direct non-authenticated users to this page."
msgstr ""
@@ -12542,6 +12738,9 @@ msgid "Dismiss %d selected vulnerability as"
msgid_plural "Dismiss %d selected vulnerabilities as"
msgstr[0] ""
+msgid "Dismiss Alert"
+msgstr ""
+
msgid "Dismiss merge request promotion"
msgstr ""
@@ -12569,9 +12768,15 @@ msgstr ""
msgid "Display alerts from all configured monitoring tools."
msgstr ""
+msgid "Display milestones"
+msgstr ""
+
msgid "Display name"
msgstr ""
+msgid "Display progress of child issues"
+msgstr ""
+
msgid "Display rendered file"
msgstr ""
@@ -12677,6 +12882,9 @@ msgstr ""
msgid "Download image"
msgstr "ì´ë¯¸ì§€ 다운로드"
+msgid "Download payload"
+msgstr ""
+
msgid "Download raw data (.csv)"
msgstr ""
@@ -12854,6 +13062,9 @@ msgstr "%{user_name}ì˜ ì‹ ì› íŽ¸ì§‘"
msgid "Edit in Web IDE"
msgstr ""
+msgid "Edit in pipeline editor"
+msgstr ""
+
msgid "Edit in single-file editor"
msgstr ""
@@ -12896,6 +13107,9 @@ msgstr "위키 페ì´ì§€ 편집"
msgid "Edit your most recent comment in a thread (from an empty textarea)"
msgstr ""
+msgid "Edit, lint, and visualize your pipeline."
+msgstr ""
+
msgid "Edited"
msgstr ""
@@ -13337,6 +13551,9 @@ msgstr ""
msgid "Enforce two-factor authentication for all user sign-ins."
msgstr ""
+msgid "Enhance security by storing service account keys in secret managers - learn more about %{docLinkStart}secret management with GitLab%{docLinkEnd}"
+msgstr ""
+
msgid "Ensure connectivity is available from the GitLab server to the Prometheus server"
msgstr ""
@@ -13397,6 +13614,9 @@ 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 following to confirm:"
+msgstr ""
+
msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
@@ -13926,9 +14146,6 @@ 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 "ì—러가 ë°œìƒí–ˆìŠµë‹ˆë‹¤. ì°¨ë‹¨ëœ ì‚¬ìš©ìžëŠ” 비활성화할 수 없습니다."
@@ -14064,6 +14281,9 @@ msgstr ""
msgid "Errors:"
msgstr ""
+msgid "Escalate this incident"
+msgstr ""
+
msgid "Escalation Policies"
msgstr ""
@@ -14076,6 +14296,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy"
+msgstr ""
+
msgid "Escalation policy:"
msgstr ""
@@ -14326,6 +14549,9 @@ msgstr ""
msgid "Existing sign in methods may be removed"
msgstr ""
+msgid "Exit."
+msgstr ""
+
msgid "Expand"
msgstr "펼치기"
@@ -14422,6 +14648,9 @@ msgstr "프로ì íŠ¸ 둘러보기"
msgid "Explore public groups"
msgstr "공개 그룹 íƒìƒ‰"
+msgid "Explore public projects"
+msgstr ""
+
msgid "Explore snippets"
msgstr ""
@@ -14582,8 +14811,8 @@ msgid "Failed to archive a design. Please try again."
msgid_plural "Failed to archive designs. Please try again."
msgstr[0] ""
-msgid "Failed to assign a reviewer because no user was found."
-msgstr "사용ìžë¥¼ ì°¾ì„ ìˆ˜ 없기 ë•Œë¬¸ì— ë¦¬ë·°ì–´ë¥¼ 지정하지 못했습니다."
+msgid "Failed to assign a reviewer because no user was specified."
+msgstr ""
msgid "Failed to assign a user because no user was found."
msgstr ""
@@ -14648,10 +14877,10 @@ msgstr ""
msgid "Failed to find import label for Jira import."
msgstr ""
-msgid "Failed to generate export, please try again later."
+msgid "Failed to find users for %{missing}"
msgstr ""
-msgid "Failed to generate report, please try again after sometime"
+msgid "Failed to generate export, please try again later."
msgstr ""
msgid "Failed to get ref."
@@ -14750,6 +14979,9 @@ msgstr ""
msgid "Failed to remove a to-do item for the design."
msgstr ""
+msgid "Failed to remove attention because no user was found."
+msgstr ""
+
msgid "Failed to remove mirror."
msgstr "미러를 제거하지 못했습니다."
@@ -14762,6 +14994,9 @@ msgstr ""
msgid "Failed to remove user key."
msgstr ""
+msgid "Failed to request attention because no user was found."
+msgstr ""
+
msgid "Failed to reset key. Please try again."
msgstr ""
@@ -14843,6 +15078,9 @@ msgstr ""
msgid "Feature Flags"
msgstr "기능 플래그"
+msgid "Feature deprecation and removal"
+msgstr ""
+
msgid "Feature flag status"
msgstr ""
@@ -15339,7 +15577,7 @@ msgstr ""
msgid "For each job, re-use the project workspace. If the workspace doesn't exist, use %{code_open}git clone%{code_close}."
msgstr ""
-msgid "For example, the application using the token or the purpose of the token."
+msgid "For example, the application using the token or the purpose of the token. Do not give sensitive information for the name of the token, as it will be visible to all %{resource_type} members."
msgstr ""
msgid "For files larger than this limit, only index the file name. The file content is neither indexed nor searchable."
@@ -15423,9 +15661,6 @@ msgstr ""
msgid "ForkProject|Select a namespace"
msgstr ""
-msgid "ForkProject|Select a namespace to fork the project"
-msgstr ""
-
msgid "ForkProject|The project can be accessed by any logged in user."
msgstr ""
@@ -15522,6 +15757,9 @@ msgstr ""
msgid "Full name"
msgstr ""
+msgid "GCP region configured"
+msgstr ""
+
msgid "GPG Key ID:"
msgstr ""
@@ -15702,6 +15940,9 @@ msgstr ""
msgid "Geo|Failed"
msgstr "실패"
+msgid "Geo|Filter Geo sites"
+msgstr ""
+
msgid "Geo|Filter by name"
msgstr ""
@@ -16113,6 +16354,12 @@ msgstr "GitLab 가져오기"
msgid "GitLab Issue"
msgstr ""
+msgid "GitLab KAS"
+msgstr ""
+
+msgid "GitLab Memberships CSV Export"
+msgstr ""
+
msgid "GitLab Pages"
msgstr ""
@@ -16161,6 +16408,9 @@ 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 free to use. Many features for larger teams are part of our %{link_start}paid products%{link_end}. You can try Ultimate for free without any obligation or payment details."
+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 ""
@@ -16287,7 +16537,7 @@ msgstr ""
msgid "GitLabPages|When enabled, all attempts to visit your website through HTTP are automatically redirected to HTTPS using a response with status code 301. Requires a valid certificate for all domains. %{docs_link_start}Learn more.%{link_end}"
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. %{docs_link_start}Learn more.%{link_end}"
+msgid "GitLabPages|When using Pages under the general domain of a GitLab instance (%{pages_host}), you cannot use HTTPS with subdomains of subdomains. If your namespace or groupname contains a dot, it does not work. This is a limitation of the HTTP Over TLS protocol. HTTP pages work if you don't redirect HTTP to HTTPS. %{docs_link_start}Learn more.%{link_end}"
msgstr ""
msgid "GitLabPages|With GitLab Pages you can host your static website directly from your GitLab repository. %{docs_link_start}Learn more.%{link_end}"
@@ -16464,9 +16714,6 @@ msgstr "파ì¼ë¡œ ì´ë™"
msgid "Go to find file"
msgstr ""
-msgid "Go to fork"
-msgstr ""
-
msgid "Go to issue boards"
msgstr ""
@@ -16674,9 +16921,6 @@ msgstr "그룹 Git LFS ìƒíƒœ:"
msgid "Group Hooks"
msgstr ""
-msgid "Group ID"
-msgstr "그룹 ID"
-
msgid "Group Owner must have signed in with SAML before enabling Group Managed Accounts"
msgstr ""
@@ -16704,9 +16948,6 @@ msgstr "그룹 아바타"
msgid "Group by"
msgstr ""
-msgid "Group description"
-msgstr ""
-
msgid "Group description (optional)"
msgstr "그룹 설명 (ì„ íƒ ì‚¬í•­)"
@@ -16821,7 +17062,7 @@ msgstr "그룹: %{group_name}"
msgid "Group: %{name}"
msgstr ""
-msgid "GroupActivityMetrics|Issues opened"
+msgid "GroupActivityMetrics|Issues created"
msgstr ""
msgid "GroupActivityMetrics|Last 90 days"
@@ -16830,7 +17071,7 @@ msgstr ""
msgid "GroupActivityMetrics|Members added"
msgstr ""
-msgid "GroupActivityMetrics|Merge Requests opened"
+msgid "GroupActivityMetrics|Merge Requests created"
msgstr ""
msgid "GroupActivityMetrics|Recent activity"
@@ -17121,6 +17362,9 @@ msgstr ""
msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
+msgid "GroupSettings|Choose a group path that does not start with a dash or end with a period. It can also contain alphanumeric characters and underscores."
+msgstr ""
+
msgid "GroupSettings|Compliance frameworks"
msgstr ""
@@ -17154,7 +17398,7 @@ msgstr ""
msgid "GroupSettings|If not specified at the group or instance level, the default is %{default_initial_branch_name}. Does not affect existing repositories."
msgstr ""
-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."
+msgid "GroupSettings|If the parent group's visibility is lower than the group's current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility."
msgstr ""
msgid "GroupSettings|New runners registration token has been generated!"
@@ -17271,7 +17515,10 @@ msgstr ""
msgid "Groups and projects"
msgstr "그룹 ë° í”„ë¡œì íŠ¸"
-msgid "Groups and subgroups"
+msgid "Groups are a great way to organize projects and people."
+msgstr ""
+
+msgid "Groups are the best way to manage projects and members."
msgstr ""
msgid "Groups to synchronize"
@@ -17382,14 +17629,17 @@ msgstr ""
msgid "GroupsTree|Are you sure you want to leave the \"%{fullName}\" group?"
msgstr ""
-msgid "GroupsTree|Edit group"
-msgstr "그룹 편집"
+msgid "GroupsTree|Delete"
+msgstr ""
+
+msgid "GroupsTree|Edit"
+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|Leave group"
+msgstr ""
msgid "GroupsTree|Loading groups"
msgstr "그룹 로딩중입니다"
@@ -17400,9 +17650,57 @@ msgstr ""
msgid "GroupsTree|No groups or projects matched your search"
msgstr ""
+msgid "GroupsTree|Options"
+msgstr ""
+
msgid "GroupsTree|Search by name"
msgstr "ì´ë¦„으로 검색"
+msgid "Groups|Avatar will be removed. Are you sure?"
+msgstr ""
+
+msgid "Groups|Changing group URL can have unintended side effects."
+msgstr ""
+
+msgid "Groups|Checking group URL availability..."
+msgstr ""
+
+msgid "Groups|Enter a descriptive name for your group."
+msgstr ""
+
+msgid "Groups|Group ID"
+msgstr ""
+
+msgid "Groups|Group URL"
+msgstr ""
+
+msgid "Groups|Group avatar"
+msgstr ""
+
+msgid "Groups|Group description (optional)"
+msgstr ""
+
+msgid "Groups|Group name"
+msgstr ""
+
+msgid "Groups|Group path is available."
+msgstr ""
+
+msgid "Groups|Group path is unavailable. Path has been replaced with a suggested available path."
+msgstr ""
+
+msgid "Groups|Learn more"
+msgstr ""
+
+msgid "Groups|Must start with letter, digit, emoji, or underscore. Can also contain periods, dashes, spaces, and parentheses."
+msgstr ""
+
+msgid "Groups|Remove avatar"
+msgstr ""
+
+msgid "Groups|Save changes"
+msgstr ""
+
msgid "Guideline"
msgstr "ê°€ì´ë“œë¼ì¸"
@@ -17412,6 +17710,9 @@ msgstr ""
msgid "HAR file path or URL"
msgstr ""
+msgid "HTTP Archive (HAR)"
+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: ì ‘ê·¼ 거부\\nGit over HTTPì—서는 'api' 스코프를 가진 ê°œì¸ ì—‘ì„¸ìŠ¤ 토í°ì„ 사용해야 합니다.\\n%{profile_personal_access_tokens_url}ì—ì„œ ìƒì„±í•  수 있습니다."
@@ -17810,6 +18111,9 @@ msgstr ""
msgid "INFO: Your SSH key is expiring soon. Please generate a new key."
msgstr ""
+msgid "IP"
+msgstr ""
+
msgid "IP Address"
msgstr "IP 주소"
@@ -17846,6 +18150,9 @@ msgstr ""
msgid "IdentityVerification|Verify your identity"
msgstr ""
+msgid "IdentityVerification|You can always verify your account at a later time to create a group."
+msgstr ""
+
msgid "If any indexed field exceeds this limit, it is truncated to this number of characters. The rest of the content is neither indexed nor searchable. This does not apply to repository and wiki indexing. For unlimited characters, set this to 0."
msgstr ""
@@ -17903,6 +18210,9 @@ msgstr ""
msgid "If you add %{codeStart}needs%{codeEnd} to jobs in your pipeline you'll be able to view the %{codeStart}needs%{codeEnd} relationships between jobs in this tab as a %{linkStart}Directed Acyclic Graph (DAG)%{linkEnd}."
msgstr ""
+msgid "If you are added to a project, it will be displayed here."
+msgstr ""
+
msgid "If you did not initiate these sign-in attempts, please reach out to your administrator or enable two-factor authentication (2FA) on your account."
msgstr ""
@@ -18206,12 +18516,24 @@ msgstr ""
msgid "InProductMarketing|3 ways to dive into GitLab CI/CD"
msgstr ""
+msgid "InProductMarketing|A single application eliminates complex integrations, data chokepoints, and toolchain maintenance, resulting in greater productivity and lower cost."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features, build more efficiently, strengthen security and compliance."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features."
+msgstr ""
+
msgid "InProductMarketing|Actually, GitLab makes the team work (better)"
msgstr ""
msgid "InProductMarketing|And finally %{deploy_link} a Python application."
msgstr ""
+msgid "InProductMarketing|And many more..."
+msgstr ""
+
msgid "InProductMarketing|Are your runners ready?"
msgstr ""
@@ -18230,15 +18552,33 @@ msgstr ""
msgid "InProductMarketing|Blog"
msgstr ""
+msgid "InProductMarketing|Break down silos to coordinate seamlessly across development, operations, and security with a consistent experience across the development lifecycle."
+msgstr ""
+
+msgid "InProductMarketing|Burn up/down charts"
+msgstr ""
+
msgid "InProductMarketing|By enabling code owners and required merge approvals the right person will review the right MR. This is a win-win: cleaner code and a more efficient review process."
msgstr ""
msgid "InProductMarketing|Click on the number below that corresponds with your answer — 1 being very difficult, 5 being very easy."
msgstr ""
+msgid "InProductMarketing|Code owners"
+msgstr ""
+
msgid "InProductMarketing|Code owners and required merge approvals are part of the paid tiers of GitLab. You can start a free 30-day trial of GitLab Ultimate and enable these features in less than 5 minutes with no credit card required."
msgstr ""
+msgid "InProductMarketing|Code review analytics"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration across stages in GitLab"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration made easy"
+msgstr ""
+
msgid "InProductMarketing|Create a custom CI runner with just a few clicks"
msgstr ""
@@ -18248,12 +18588,21 @@ msgstr ""
msgid "InProductMarketing|Create a project in GitLab in 5 minutes"
msgstr ""
+msgid "InProductMarketing|Create well-defined workflows by using scoped labels on issues, merge requests, and epics. Labels with the same scope cannot be used together, which prevents conflicts."
+msgstr ""
+
msgid "InProductMarketing|Create your first project!"
msgstr ""
+msgid "InProductMarketing|Define who owns specific files or directories, so the right reviewers are suggested when a merge request introduces changes to those files."
+msgstr ""
+
msgid "InProductMarketing|Deliver Better Products Faster"
msgstr ""
+msgid "InProductMarketing|Dependency scanning"
+msgstr ""
+
msgid "InProductMarketing|Did you know teams that use GitLab are far more efficient?"
msgstr ""
@@ -18263,15 +18612,27 @@ msgstr ""
msgid "InProductMarketing|Dig in and create a project and a repo"
msgstr ""
+msgid "InProductMarketing|Discover Premium & Ultimate"
+msgstr ""
+
+msgid "InProductMarketing|Discover Premium & Ultimate."
+msgstr ""
+
msgid "InProductMarketing|Do you have a minute?"
msgstr ""
msgid "InProductMarketing|Do you have a teammate who would be perfect for this task?"
msgstr ""
+msgid "InProductMarketing|Dynamic application security testing"
+msgstr ""
+
msgid "InProductMarketing|Easy"
msgstr ""
+msgid "InProductMarketing|Epics"
+msgstr ""
+
msgid "InProductMarketing|Expand your DevOps journey with a free GitLab trial"
msgstr ""
@@ -18293,9 +18654,15 @@ msgstr ""
msgid "InProductMarketing|Feel the need for speed?"
msgstr ""
+msgid "InProductMarketing|Find and fix bottlenecks in your code review process by understanding how long open merge requests have been in review."
+msgstr ""
+
msgid "InProductMarketing|Find out how your teams are really doing"
msgstr ""
+msgid "InProductMarketing|Find out if your external libraries are safe. Run dependency scanning jobs that check for known vulnerabilities in your external libraries."
+msgstr ""
+
msgid "InProductMarketing|Follow our steps"
msgstr ""
@@ -18332,6 +18699,9 @@ msgstr ""
msgid "InProductMarketing|GitLab is better with teammates to help out!"
msgstr ""
+msgid "InProductMarketing|GitLab is infrastructure agnostic (supporting GCP, AWS, Azure, OpenShift, VMWare, On Prem, Bare Metal, and more), offering a consistent workflow experience – irrespective of the environment."
+msgstr ""
+
msgid "InProductMarketing|GitLab provides static application security testing (SAST), dynamic application security testing (DAST), container scanning, and dependency scanning to help you deliver secure applications along with license compliance."
msgstr ""
@@ -18422,21 +18792,36 @@ msgstr ""
msgid "InProductMarketing|It's also possible to simply %{external_repo_link} in order to take advantage of GitLab's CI/CD."
msgstr ""
+msgid "InProductMarketing|Keep your code quality high by defining who should approve merge requests and how many approvals are required."
+msgstr ""
+
msgid "InProductMarketing|Launch GitLab CI/CD in 20 minutes or less"
msgstr ""
+msgid "InProductMarketing|Lower cost of development"
+msgstr ""
+
+msgid "InProductMarketing|Make it easier to collaborate on high-level ideas by grouping related issues in an epic."
+msgstr ""
+
msgid "InProductMarketing|Making the switch? It's easier than you think to import your projects into GitLab. Move %{github_link}, or import something %{bitbucket_link}."
msgstr ""
msgid "InProductMarketing|Master the art of importing!"
msgstr ""
+msgid "InProductMarketing|Merge request approval rule"
+msgstr ""
+
msgid "InProductMarketing|Move on to easily creating a Pages website %{ci_template_link}"
msgstr ""
msgid "InProductMarketing|Multiple owners, confusing workstreams? We've got you covered"
msgstr ""
+msgid "InProductMarketing|Multiple required approvers"
+msgstr ""
+
msgid "InProductMarketing|Need an alternative to importing?"
msgstr ""
@@ -18449,18 +18834,33 @@ msgstr ""
msgid "InProductMarketing|Our tool brings all the things together"
msgstr ""
+msgid "InProductMarketing|Protect your web application by using DAST to examine for vulnerabilities in deployed environments."
+msgstr ""
+
msgid "InProductMarketing|Rapid development, simplified"
msgstr ""
msgid "InProductMarketing|Reduce Security & Compliance Risk"
msgstr ""
+msgid "InProductMarketing|Require multiple approvers on a merge request, so you know it's in good shape before it's merged."
+msgstr ""
+
+msgid "InProductMarketing|Roadmaps"
+msgstr ""
+
+msgid "InProductMarketing|Scoped labels"
+msgstr ""
+
msgid "InProductMarketing|Security that's integrated into your development lifecycle"
msgstr ""
msgid "InProductMarketing|Sometimes you're not ready to make a full transition to a new tool. If you're not ready to fully commit, %{mirroring_link} gives you a safe way to try out GitLab in parallel with your current tool."
msgstr ""
+msgid "InProductMarketing|Speed. Efficiency. Trust."
+msgstr ""
+
msgid "InProductMarketing|Spin up an autoscaling runner in GitLab"
msgstr ""
@@ -18470,6 +18870,9 @@ msgstr ""
msgid "InProductMarketing|Start a Self-Managed trial"
msgstr ""
+msgid "InProductMarketing|Start a free trial"
+msgstr ""
+
msgid "InProductMarketing|Start a free trial of GitLab Ultimate – no credit card required"
msgstr ""
@@ -18536,6 +18939,9 @@ msgstr ""
msgid "InProductMarketing|To understand and get the most out of GitLab, start at the beginning and %{project_link}. In GitLab, repositories are part of a project, so after you've created your project you can go ahead and %{repo_link}."
msgstr ""
+msgid "InProductMarketing|Track completed issues in a chart, so you can see how a milestone is progressing at a glance."
+msgstr ""
+
msgid "InProductMarketing|Try GitLab Ultimate for free"
msgstr ""
@@ -18572,6 +18978,9 @@ msgstr ""
msgid "InProductMarketing|Very easy"
msgstr ""
+msgid "InProductMarketing|Visualize your epics and milestones in a timeline."
+msgstr ""
+
msgid "InProductMarketing|Want to host GitLab on your servers?"
msgstr ""
@@ -18593,6 +19002,9 @@ msgstr ""
msgid "InProductMarketing|YouTube"
msgstr ""
+msgid "InProductMarketing|Your software, deployed your way"
+msgstr ""
+
msgid "InProductMarketing|Your teams can be more efficient"
msgstr ""
@@ -18713,9 +19125,18 @@ msgstr ""
msgid "IncidentManagement|No incidents to display."
msgstr ""
+msgid "IncidentManagement|None"
+msgstr ""
+
msgid "IncidentManagement|Open"
msgstr ""
+msgid "IncidentManagement|Page your team with escalation policies"
+msgstr ""
+
+msgid "IncidentManagement|Paged"
+msgstr ""
+
msgid "IncidentManagement|Published"
msgstr ""
@@ -18725,6 +19146,9 @@ msgstr ""
msgid "IncidentManagement|Severity"
msgstr ""
+msgid "IncidentManagement|Status"
+msgstr ""
+
msgid "IncidentManagement|There are no closed incidents"
msgstr ""
@@ -18743,6 +19167,9 @@ msgstr ""
msgid "IncidentManagement|Unpublished"
msgstr ""
+msgid "IncidentManagement|Use escalation policies to automatically page your team when incidents are created."
+msgstr ""
+
msgid "IncidentSettings|Activate \"time to SLA\" countdown timer"
msgstr ""
@@ -18788,7 +19215,10 @@ msgstr ""
msgid "Incidents"
msgstr ""
-msgid "Incidents|Add a URL"
+msgid "Incidents|Add image details"
+msgstr ""
+
+msgid "Incidents|Add text or a link to display with your image. If you don't add either, the file name displays instead."
msgstr ""
msgid "Incidents|Drop or %{linkStart}upload%{linkEnd} a metric screenshot to attach it to the incident"
@@ -18803,10 +19233,10 @@ msgstr ""
msgid "Incidents|There was an issue loading metric images."
msgstr ""
-msgid "Incidents|There was an issue uploading your image."
+msgid "Incidents|There was an issue updating your image."
msgstr ""
-msgid "Incidents|You can optionally add a URL to link users to the original graph."
+msgid "Incidents|There was an issue uploading your image."
msgstr ""
msgid "Incident|Alert details"
@@ -18815,9 +19245,18 @@ msgstr ""
msgid "Incident|Are you sure you wish to delete this image?"
msgstr ""
+msgid "Incident|Delete image"
+msgstr ""
+
msgid "Incident|Deleting %{filename}"
msgstr ""
+msgid "Incident|Edit image text or link"
+msgstr ""
+
+msgid "Incident|Editing %{filename}"
+msgstr ""
+
msgid "Incident|Metrics"
msgstr ""
@@ -19086,12 +19525,18 @@ msgstr ""
msgid "Integrations|Branches for which notifications are to be sent"
msgstr ""
+msgid "Integrations|Clear if using a self-signed certificate."
+msgstr ""
+
msgid "Integrations|Comment detail:"
msgstr ""
msgid "Integrations|Comment settings:"
msgstr ""
+msgid "Integrations|Connection details"
+msgstr ""
+
msgid "Integrations|Connection failed. Please check your settings."
msgstr ""
@@ -19116,6 +19561,9 @@ msgstr ""
msgid "Integrations|Enable GitLab.com slash commands in a Slack workspace."
msgstr ""
+msgid "Integrations|Enable SSL verification"
+msgstr ""
+
msgid "Integrations|Enable comments"
msgstr ""
@@ -19194,6 +19642,9 @@ msgstr ""
msgid "Integrations|Return to GitLab for Jira"
msgstr ""
+msgid "Integrations|SSL verification"
+msgstr ""
+
msgid "Integrations|Save settings?"
msgstr ""
@@ -19239,9 +19690,6 @@ msgstr ""
msgid "Integrations|Use default settings"
msgstr ""
-msgid "Integrations|When you mention a Jira issue in a commit or merge request, GitLab creates a remote link and comment (if enabled)."
-msgstr ""
-
msgid "Integrations|You can now close this window and return to the GitLab for Jira application."
msgstr ""
@@ -19266,9 +19714,6 @@ msgstr ""
msgid "Integrations|can't exceed %{recipients_limit}"
msgstr ""
-msgid "Interactive developer security education."
-msgstr ""
-
msgid "Interactive mode"
msgstr ""
@@ -19758,6 +20203,9 @@ msgstr ""
msgid "IssueAnalytics|Assignees"
msgstr ""
+msgid "IssueAnalytics|Created by"
+msgstr ""
+
msgid "IssueAnalytics|Due date"
msgstr ""
@@ -19770,9 +20218,6 @@ msgstr ""
msgid "IssueAnalytics|Milestone"
msgstr ""
-msgid "IssueAnalytics|Opened by"
-msgstr ""
-
msgid "IssueAnalytics|Status"
msgstr ""
@@ -19896,10 +20341,10 @@ msgstr ""
msgid "IssuesAnalytics|Avg/Month:"
msgstr ""
-msgid "IssuesAnalytics|Issues opened"
+msgid "IssuesAnalytics|Issues created"
msgstr ""
-msgid "IssuesAnalytics|Issues opened per month"
+msgid "IssuesAnalytics|Issues created per month"
msgstr ""
msgid "IssuesAnalytics|Last 12 months"
@@ -19926,6 +20371,9 @@ msgstr ""
msgid "It looks like you have some draft commits in this branch."
msgstr ""
+msgid "It looks like you're attempting to activate your subscription. Use %{a_start}the Subscription page%{a_end} instead."
+msgstr ""
+
msgid "It may be several days before you see feature usage data."
msgstr ""
@@ -20154,6 +20602,9 @@ msgstr ""
msgid "JiraConnect|You can now close this window and return to Jira."
msgstr ""
+msgid "JiraConnect|You don't have permission to create branches for this project. Select a different project or contact the project owner for access. %{linkStart}Learn more.%{linkEnd}"
+msgstr ""
+
msgid "JiraRequest|A connection error occurred while connecting to Jira. Try your request again."
msgstr ""
@@ -20202,13 +20653,13 @@ msgstr ""
msgid "JiraService|Define the type of Jira issue to create from a vulnerability."
msgstr ""
-msgid "JiraService|Displaying Jira issues while leaving the GitLab issue functionality enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
+msgid "JiraService|Displaying Jira issues while leaving GitLab issues also enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
msgstr ""
-msgid "JiraService|Enable Jira issues"
+msgid "JiraService|Enable Jira issue creation from vulnerabilities"
msgstr ""
-msgid "JiraService|Enable Jira issues creation from vulnerabilities"
+msgid "JiraService|Enable Jira issues"
msgstr ""
msgid "JiraService|Enable Jira transitions"
@@ -20325,16 +20776,19 @@ msgstr ""
msgid "JiraService|View Jira issues in GitLab"
msgstr ""
-msgid "JiraService|Warning: All GitLab users that have access to this GitLab project are able to view all issues from the Jira project specified below."
+msgid "JiraService|Warning: All GitLab users with access to this GitLab project can view all issues from the Jira project you select."
msgstr ""
msgid "JiraService|Web URL"
msgstr ""
-msgid "JiraService|Work on Jira issues without leaving GitLab. Adds a Jira menu to access your list of Jira issues and view any issue as read-only."
+msgid "JiraService|When a Jira issue is mentioned in a commit or merge request, a remote link and comment (if enabled) will be created."
msgstr ""
-msgid "JiraService|You need to configure Jira before enabling this integration. For more details, read the %{jira_doc_link_start}Jira integration documentation%{link_end}."
+msgid "JiraService|Work on Jira issues without leaving GitLab. Add a Jira menu to access a read-only list of your Jira issues."
+msgstr ""
+
+msgid "JiraService|You must configure Jira before enabling this integration. %{jira_doc_link_start}Learn more.%{link_end}"
msgstr ""
msgid "Job"
@@ -20346,9 +20800,6 @@ msgstr ""
msgid "Job Failed #%{build_id}"
msgstr ""
-msgid "Job ID"
-msgstr ""
-
msgid "Job artifact"
msgstr ""
@@ -20415,9 +20866,27 @@ msgstr ""
msgid "Jobs|You're about to retry a job that failed because it attempted to deploy code that is older than the latest deployment. Retrying this job could result in overwriting the environment with the older source code."
msgstr ""
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source} into %{target}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{ref}"
+msgstr ""
+
+msgid "Job|Are you sure you want to erase this job log and artifacts?"
+msgstr ""
+
msgid "Job|Browse"
msgstr "íƒìƒ‰"
+msgid "Job|Cancel"
+msgstr ""
+
msgid "Job|Complete Raw"
msgstr ""
@@ -20427,6 +20896,9 @@ msgstr "다운로드"
msgid "Job|Erase job log and artifacts"
msgstr ""
+msgid "Job|Finished at"
+msgstr ""
+
msgid "Job|Job artifacts"
msgstr ""
@@ -20439,7 +20911,7 @@ msgstr ""
msgid "Job|Keep"
msgstr "유지"
-msgid "Job|Pipeline"
+msgid "Job|Retry"
msgstr ""
msgid "Job|Scroll to bottom"
@@ -20451,6 +20923,9 @@ msgstr "맨 위로 스í¬ë¡¤"
msgid "Job|Show complete raw"
msgstr ""
+msgid "Job|Status"
+msgstr ""
+
msgid "Job|The artifacts were removed"
msgstr ""
@@ -20478,21 +20953,12 @@ msgstr ""
msgid "Job|delayed"
msgstr ""
-msgid "Job|for"
-msgstr ""
-
-msgid "Job|into"
-msgstr ""
-
msgid "Job|manual"
msgstr ""
msgid "Job|triggered"
msgstr ""
-msgid "Job|with"
-msgstr ""
-
msgid "Join Zoom meeting"
msgstr ""
@@ -20595,9 +21061,6 @@ msgstr ""
msgid "Ki"
msgstr ""
-msgid "Kontra"
-msgstr ""
-
msgid "Kroki"
msgstr ""
@@ -20920,6 +21383,9 @@ msgstr ""
msgid "Learn more about Auto DevOps"
msgstr ""
+msgid "Learn more about GitLab"
+msgstr ""
+
msgid "Learn more about Needs relationships"
msgstr ""
@@ -21241,9 +21707,18 @@ msgstr ""
msgid "Licenses|Displays licenses detected in the project, based on the %{linkStart}latest successful%{linkEnd} scan"
msgstr ""
+msgid "Licenses|Drag your license file here or %{linkStart}click to upload%{linkEnd}."
+msgstr ""
+
+msgid "Licenses|Drop your license file to start the upload."
+msgstr ""
+
msgid "Licenses|Error fetching the license list. Please check your network connection and try again."
msgstr ""
+msgid "Licenses|Error: You are trying to upload something other than a file"
+msgstr ""
+
msgid "Licenses|License Compliance"
msgstr ""
@@ -21262,6 +21737,9 @@ msgstr ""
msgid "Licenses|Specified policies in this project"
msgstr ""
+msgid "Licenses|The file could not be uploaded."
+msgstr ""
+
msgid "Licenses|The license list details information about the licenses used within your project."
msgstr ""
@@ -21295,10 +21773,6 @@ msgstr ""
msgid "Limit the size of Sidekiq jobs stored in Redis."
msgstr ""
-msgid "Limited to showing %d event at most"
-msgid_plural "Limited to showing %d events at most"
-msgstr[0] "최대 %d ì´ë²¤íŠ¸ 만 표시하는 것으로 제한ë©ë‹ˆë‹¤."
-
msgid "Limiting mode"
msgstr ""
@@ -21308,6 +21782,9 @@ msgstr ""
msgid "Link"
msgstr ""
+msgid "Link (optional)"
+msgstr ""
+
msgid "Link Prometheus monitoring to GitLab."
msgstr ""
@@ -21344,6 +21821,9 @@ msgstr ""
msgid "Linked emails (%{email_count})"
msgstr ""
+msgid "Linked epics"
+msgstr ""
+
msgid "Linked issues"
msgstr ""
@@ -21371,6 +21851,15 @@ msgstr "사용 가능한 저장소 목ë¡"
msgid "List of all merge commits"
msgstr ""
+msgid "List of environments for this project"
+msgstr ""
+
+msgid "List of suitable GCP locations"
+msgstr ""
+
+msgid "List of users allowed to exceed the rate limit."
+msgstr ""
+
msgid "List options"
msgstr ""
@@ -21590,6 +22079,9 @@ msgstr ""
msgid "Maintenance mode"
msgstr ""
+msgid "Make adjustments to how your GitLab instance is set up."
+msgstr ""
+
msgid "Make and review changes in the browser with the Web IDE"
msgstr "웹 IDE를 사용하여 브ë¼ìš°ì €ì—ì„œ 변경 ì‚¬í•­ì„ ìž‘ì„±í•˜ê³  검토하세요."
@@ -21734,6 +22226,12 @@ msgstr ""
msgid "MarkdownEditor|Add italic text (%{modifier_key}I)"
msgstr ""
+msgid "MarkdownEditor|Add strikethrough text (%{modifierKey}⇧X)"
+msgstr ""
+
+msgid "MarkdownEditor|Add strikethrough text (%{modifier_key}⇧X)"
+msgstr ""
+
msgid "Marked For Deletion At - %{deletion_time}"
msgstr ""
@@ -21995,6 +22493,9 @@ msgstr ""
msgid "Maximum push size (MB)"
msgstr ""
+msgid "Maximum requests per 10 minutes per user"
+msgstr ""
+
msgid "Maximum requests per minute"
msgstr ""
@@ -22085,6 +22586,17 @@ msgstr ""
msgid "Members of a group may only view projects they have permission to access"
msgstr ""
+msgid "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seat in use and will be billed for the overage."
+msgid_plural "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seats in use and will be billed for the overage."
+msgstr[0] ""
+
+msgid "MembersOverage|You are about to incur additional charges"
+msgstr ""
+
+msgid "MembersOverage|Your subscription includes %d seat."
+msgid_plural "MembersOverage|Your subscription includes %d seats."
+msgstr[0] ""
+
msgid "Membership"
msgstr ""
@@ -22289,9 +22801,6 @@ msgstr ""
msgid "Merge request not merged"
msgstr ""
-msgid "Merge request pipelines 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 merge request pipelines."
-msgstr ""
-
msgid "Merge request reports"
msgstr ""
@@ -22388,13 +22897,13 @@ msgstr ""
msgid "MergeRequests|Create issue to resolve thread"
msgstr ""
-msgid "MergeRequests|Failed to squash. Should be done manually."
-msgstr ""
-
msgid "MergeRequests|Saving the comment failed"
msgstr "댓글 저장 실패"
-msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
+msgid "MergeRequests|Squashing failed: Squash the commits locally, resolve any conflicts, then push the branch."
+msgstr ""
+
+msgid "MergeRequests|Squashing not allowed: This project doesn't allow you to squash commits when merging."
msgstr ""
msgid "MergeRequests|Thread stays resolved"
@@ -23233,6 +23742,18 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "MrList|Assigned to %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from assignee %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from reviewer %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Review requested from %{name}, go to their profile."
+msgstr ""
+
msgid "Multi-project"
msgstr ""
@@ -23266,7 +23787,7 @@ msgstr ""
msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "My Awesome Group"
+msgid "My awesome group"
msgstr ""
msgid "My company or team"
@@ -23886,9 +24407,6 @@ msgstr ""
msgid "No available branches"
msgstr ""
-msgid "No available groups to fork the project."
-msgstr ""
-
msgid "No branches found"
msgstr "브랜치가 존재하지 않습니다."
@@ -24099,6 +24617,9 @@ msgstr "공개 ê·¸ë£¹ì´ ì—†ìŠµë‹ˆë‹¤."
msgid "No ref selected"
msgstr ""
+msgid "No regions configured"
+msgstr ""
+
msgid "No related merge requests found."
msgstr ""
@@ -24897,6 +25418,9 @@ msgstr ""
msgid "Only reCAPTCHA v2 is supported:"
msgstr ""
+msgid "Only required if not using role instance credentials."
+msgstr ""
+
msgid "Only use lowercase letters, numbers, and underscores."
msgstr ""
@@ -24921,9 +25445,6 @@ msgstr ""
msgid "Open a CLI and connect to the cluster you want to install the agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
-msgid "Open epics"
-msgstr ""
-
msgid "Open errors"
msgstr ""
@@ -24963,8 +25484,8 @@ msgstr ""
msgid "Opened issues"
msgstr "열린 ì´ìŠˆ"
-msgid "OpenedNDaysAgo|Opened"
-msgstr "열린"
+msgid "OpenedNDaysAgo|Created"
+msgstr ""
msgid "Opens in a new window"
msgstr "새 창으로 열기"
@@ -25008,9 +25529,6 @@ msgstr ""
msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
-msgid "Optional."
-msgstr ""
-
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
msgstr ""
@@ -25798,6 +26316,9 @@ msgstr ""
msgid "PerformanceBar|Memory"
msgstr ""
+msgid "PerformanceBar|Memory report"
+msgstr ""
+
msgid "PerformanceBar|Redis calls"
msgstr ""
@@ -25831,18 +26352,12 @@ msgstr ""
msgid "PerformanceBar|wall"
msgstr ""
-msgid "Performs a rebase but skips triggering a new pipeline"
-msgstr ""
-
msgid "Period in seconds"
msgstr ""
msgid "Permalink"
msgstr ""
-msgid "Permanently delete project"
-msgstr ""
-
msgid "Permanently remove group"
msgstr ""
@@ -26113,6 +26628,51 @@ msgstr ""
msgid "PipelineStatusTooltip|Pipeline: %{ci_status}"
msgstr ""
+msgid "PipelineWizardDefaultCommitMessage|Add %{filename}"
+msgstr ""
+
+msgid "PipelineWizardDefaultCommitMessage|Update %{filename}"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|At least one entry is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This field is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This value is not valid"
+msgstr ""
+
+msgid "PipelineWizardListWidget|add another step"
+msgstr ""
+
+msgid "PipelineWizardListWidget|remove step"
+msgstr ""
+
+msgid "PipelineWizard|Commit"
+msgstr ""
+
+msgid "PipelineWizard|Commit Message"
+msgstr ""
+
+msgid "PipelineWizard|Commit changes to your file"
+msgstr ""
+
+msgid "PipelineWizard|Commit file to Branch"
+msgstr ""
+
+msgid "PipelineWizard|Commit your new file"
+msgstr ""
+
+msgid "PipelineWizard|The file has been committed."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem committing the changes."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem while checking whether your file already exists in the specified branch."
+msgstr ""
+
msgid "Pipelines"
msgstr "파ì´í”„ë¼ì¸"
@@ -26227,7 +26787,7 @@ msgstr ""
msgid "Pipelines|Project cache successfully reset."
msgstr "프로ì íŠ¸ ìºì‹œê°€ 성공ì ìœ¼ë¡œ 재설정ë˜ì—ˆìŠµë‹ˆë‹¤."
-msgid "Pipelines|Revoke"
+msgid "Pipelines|Revoke trigger"
msgstr ""
msgid "Pipelines|Something went wrong while cleaning runners cache."
@@ -26272,6 +26832,12 @@ msgstr ""
msgid "Pipelines|This is a child pipeline within the parent pipeline"
msgstr ""
+msgid "Pipelines|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipelines|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipelines|This pipeline will run code originating from a forked project merge request. This means that the code can potentially have security considerations like exposing CI variables."
msgstr ""
@@ -26314,9 +26880,6 @@ msgstr ""
msgid "Pipelines|Your changes have been successfully committed. Now redirecting to the new merge request page."
msgstr ""
-msgid "Pipelines|detached"
-msgstr ""
-
msgid "Pipelines|error"
msgstr ""
@@ -26326,10 +26889,13 @@ msgstr ""
msgid "Pipelines|latest"
msgstr ""
-msgid "Pipelines|stuck"
+msgid "Pipelines|merge request"
+msgstr ""
+
+msgid "Pipelines|merge train"
msgstr ""
-msgid "Pipelines|train"
+msgid "Pipelines|stuck"
msgstr ""
msgid "Pipelines|yaml invalid"
@@ -26461,6 +27027,12 @@ msgstr ""
msgid "Pipeline|This change will not change the overall test coverage if merged."
msgstr ""
+msgid "Pipeline|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipeline|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipeline|Trigger author"
msgstr ""
@@ -26485,6 +27057,12 @@ msgstr ""
msgid "Pipeline|for"
msgstr ""
+msgid "Pipeline|merge request"
+msgstr ""
+
+msgid "Pipeline|merge train"
+msgstr ""
+
msgid "Pipeline|on"
msgstr ""
@@ -26623,9 +27201,6 @@ msgstr ""
msgid "Please enter a valid time interval"
msgstr ""
-msgid "Please enter or upload a valid license."
-msgstr ""
-
msgid "Please enter your current password."
msgstr ""
@@ -26734,9 +27309,6 @@ msgstr ""
msgid "Please type %{phrase_code} to proceed or close this modal to cancel."
msgstr ""
-msgid "Please type the following to confirm:"
-msgstr "다ìŒì— 있는 ë‚´ìš©ì„ ìž…ë ¥í•˜ì—¬ 확ì¸í•˜ì„¸ìš”."
-
msgid "Please use this form to report to the admin users who create spam issues, comments or behave inappropriately."
msgstr ""
@@ -26764,12 +27336,27 @@ msgstr ""
msgid "Policies"
msgstr ""
+msgid "Policy '%{escalation_policy_name}' does not exist."
+msgstr ""
+
msgid "Policy management project does have any policies in %{policy_path}"
msgstr ""
msgid "Policy project doesn't exist"
msgstr ""
+msgid "PolicyRuleMultiSelect|%{firstLabel} +%{numberOfAdditionalLabels} more"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|All %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select all"
+msgstr ""
+
msgid "Polling interval multiplier"
msgstr ""
@@ -26998,6 +27585,9 @@ msgstr ""
msgid "Private projects can be created in your personal namespace with:"
msgstr "비공개 프로ì íŠ¸ëŠ” ê°œì¸ ë„¤ìž„ìŠ¤íŽ˜ì´ìŠ¤ì—ì„œ 만들어집니다:"
+msgid "Problem with %{name} command: %{message}."
+msgstr ""
+
msgid "Proceed"
msgstr ""
@@ -27472,6 +28062,9 @@ msgstr "ì´ ì €ìž¥ì†Œì— ì‚¬ìš© ëœ í”„ë¡œê·¸ëž˜ë° ì–¸ì–´"
msgid "Progress"
msgstr "진행률"
+msgid "Progress tracking"
+msgstr ""
+
msgid "Project"
msgstr "프로ì íŠ¸"
@@ -27703,6 +28296,9 @@ msgstr ""
msgid "ProjectQualitySummary|Failure"
msgstr ""
+msgid "ProjectQualitySummary|Get insight into the overall percentage of tests in your project that succeed, fail and are skipped."
+msgstr ""
+
msgid "ProjectQualitySummary|Latest pipeline results"
msgstr ""
@@ -27721,6 +28317,12 @@ msgstr ""
msgid "ProjectQualitySummary|See project Code Coverage Statistics"
msgstr ""
+msgid "ProjectQualitySummary|Set up test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|Set up test runs (opens in a new tab)"
+msgstr ""
+
msgid "ProjectQualitySummary|Skipped"
msgstr ""
@@ -27997,13 +28599,19 @@ msgstr ""
msgid "ProjectSettings|LFS objects from this repository are available to forks. %{linkStart}How do I remove them?%{linkEnd}"
msgstr ""
+msgid "ProjectSettings|Learn about commit history."
+msgstr ""
+
+msgid "ProjectSettings|Leave empty to use default template."
+msgstr ""
+
msgid "ProjectSettings|Manage who can see the project in the public access directory."
msgstr ""
msgid "ProjectSettings|Manages large files such as audio, video, and graphics files."
msgstr ""
-msgid "ProjectSettings|Maximum 500 characters."
+msgid "ProjectSettings|Maximum %{maxLength} characters."
msgstr ""
msgid "ProjectSettings|Merge checks"
@@ -28144,6 +28752,9 @@ msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
msgstr ""
+msgid "ProjectSettings|The default template will be applied on save."
+msgstr ""
+
msgid "ProjectSettings|These checks must pass before merge requests can be merged."
msgstr ""
@@ -28198,6 +28809,9 @@ msgstr ""
msgid "ProjectSettings|What are badges?"
msgstr ""
+msgid "ProjectSettings|What are merge trains?"
+msgstr ""
+
msgid "ProjectSettings|When merge request pipelines are enabled in the CI/CD configuration file, pipelines validate the combined results of the source and target branches. %{link_start}How to configure merge request pipelines?%{link_end}"
msgstr ""
@@ -28315,6 +28929,9 @@ msgstr ""
msgid "Projects are organized into groups"
msgstr ""
+msgid "Projects are where you store your code, access issues, wiki and other features of GitLab."
+msgstr ""
+
msgid "Projects contributed to"
msgstr ""
@@ -28330,12 +28947,6 @@ msgstr ""
msgid "Projects to index"
msgstr ""
-msgid "Projects will be permanently deleted after a %{waiting_period}-day waiting period."
-msgstr ""
-
-msgid "Projects will be permanently deleted immediately."
-msgstr ""
-
msgid "Projects with critical vulnerabilities"
msgstr ""
@@ -28420,6 +29031,9 @@ msgstr ""
msgid "ProjectsNew|Import project"
msgstr ""
+msgid "ProjectsNew|Include a Getting Started README"
+msgstr ""
+
msgid "ProjectsNew|Initialize repository with a README"
msgstr ""
@@ -28435,6 +29049,9 @@ msgstr ""
msgid "ProjectsNew|Project description %{tag_start}(optional)%{tag_end}"
msgstr ""
+msgid "ProjectsNew|Recommended if you're new to GitLab"
+msgstr ""
+
msgid "ProjectsNew|Run CI/CD for external repository"
msgstr ""
@@ -28852,6 +29469,9 @@ msgstr ""
msgid "ProtectedBranch|Unprotect"
msgstr ""
+msgid "ProtectedBranch|Unprotect branch"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
@@ -28879,6 +29499,9 @@ msgstr ""
msgid "ProtectedEnvironment|Protected Environment (%{protected_environments_count})"
msgstr ""
+msgid "ProtectedEnvironment|Required approvals"
+msgstr ""
+
msgid "ProtectedEnvironment|Select an environment"
msgstr ""
@@ -28900,10 +29523,13 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|Unprotect tag"
+msgstr ""
+
msgid "ProtectedTags|default"
msgstr ""
-msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
+msgid "ProtectedTag|By default, protected tags restrict who can modify the tag."
msgstr ""
msgid "ProtectedTag|Learn more."
@@ -28966,6 +29592,9 @@ msgstr "공용 파ì´í”„ ë¼ì¸"
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Public projects are an easy way to allow everyone to have read-only access."
+msgstr ""
+
msgid "Publish to status page"
msgstr ""
@@ -29122,9 +29751,6 @@ msgstr ""
msgid "QualitySummary|Project quality"
msgstr ""
-msgid "Quarters"
-msgstr "분기별"
-
msgid "Query"
msgstr ""
@@ -29209,6 +29835,9 @@ msgstr ""
msgid "Read more about project permissions %{help_link_open}here%{help_link_close}"
msgstr ""
+msgid "Read more about related epics"
+msgstr ""
+
msgid "Read more about related issues"
msgstr ""
@@ -29239,10 +29868,7 @@ msgstr ""
msgid "Rebase source branch on the target branch."
msgstr ""
-msgid "Rebase without CI"
-msgstr ""
-
-msgid "Rebases and triggers a pipeline"
+msgid "Rebase without pipeline"
msgstr ""
msgid "Recaptcha verified?"
@@ -29293,9 +29919,6 @@ msgstr ""
msgid "Reconfigure"
msgstr ""
-msgid "Recovering projects"
-msgstr ""
-
msgid "Recovery Codes"
msgstr "복구 코드"
@@ -29354,6 +29977,12 @@ msgstr ""
msgid "Regex pattern"
msgstr "ì •ê·œ í‘œí˜„ì‹ íŒ¨í„´"
+msgid "Region"
+msgstr ""
+
+msgid "Regions"
+msgstr ""
+
msgid "Register"
msgstr "회ì›ê°€ìž…"
@@ -29583,9 +30212,6 @@ msgstr ""
msgid "Remove all or specific reviewer(s)"
msgstr "ì „ì²´ ë˜ëŠ” 특정 리뷰어 제거"
-msgid "Remove approver"
-msgstr ""
-
msgid "Remove approvers"
msgstr ""
@@ -29601,6 +30227,9 @@ msgstr ""
msgid "Remove attention request"
msgstr ""
+msgid "Remove attention request(s)"
+msgstr ""
+
msgid "Remove avatar"
msgstr "아바타 제거"
@@ -29739,6 +30368,9 @@ msgstr ""
msgid "Removed an issue from an epic."
msgstr ""
+msgid "Removed attention from %{users_sentence}."
+msgstr ""
+
msgid "Removed attention request from @%{username}"
msgstr ""
@@ -29790,6 +30422,9 @@ msgstr ""
msgid "Removes an issue from an epic."
msgstr ""
+msgid "Removes attention from %{users_sentence}."
+msgstr ""
+
msgid "Removes parent epic %{epic_ref}."
msgstr ""
@@ -29901,6 +30536,9 @@ msgstr ""
msgid "Report abuse to admin"
msgstr ""
+msgid "Report is generating and will be sent to your email address."
+msgstr ""
+
msgid "Reported %{timeAgo} by %{reportedBy}"
msgstr ""
@@ -30185,6 +30823,15 @@ msgstr ""
msgid "Request attention"
msgstr ""
+msgid "Request attention from %{users_sentence}."
+msgstr ""
+
+msgid "Request attention from assignee or reviewer"
+msgstr ""
+
+msgid "Request attention from assignee(s) or reviewer(s)"
+msgstr ""
+
msgid "Request attention to review"
msgstr ""
@@ -30209,6 +30856,9 @@ msgstr ""
msgid "Requested %{time_ago}"
msgstr ""
+msgid "Requested attention from %{users_sentence}."
+msgstr ""
+
msgid "Requested attention from @%{username}"
msgstr ""
@@ -30421,6 +31071,9 @@ msgstr ""
msgid "Restore project"
msgstr ""
+msgid "Restoring projects"
+msgstr ""
+
msgid "Restoring the group will prevent the group, its subgroups and projects from being removed on this date."
msgstr ""
@@ -30451,6 +31104,9 @@ msgstr ""
msgid "Retry"
msgstr "재시ë„"
+msgid "Retry failed jobs"
+msgstr ""
+
msgid "Retry job"
msgstr ""
@@ -30497,9 +31153,6 @@ msgstr ""
msgid "Review changes"
msgstr ""
-msgid "Review requested from %{name}"
-msgstr ""
-
msgid "Review requests for you"
msgstr ""
@@ -30663,6 +31316,9 @@ msgstr ""
msgid "Runners|Assigned Group"
msgstr ""
+msgid "Runners|Assigned Projects (%{projectCount})"
+msgstr ""
+
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30732,6 +31388,9 @@ msgstr ""
msgid "Runners|Instance"
msgstr ""
+msgid "Runners|Jobs"
+msgstr ""
+
msgid "Runners|Last contact"
msgstr ""
@@ -30825,9 +31484,6 @@ msgstr ""
msgid "Runners|Runner %{name} was deleted"
msgstr ""
-msgid "Runners|Runner ID"
-msgstr ""
-
msgid "Runners|Runner assigned to project."
msgstr ""
@@ -30975,6 +31631,9 @@ msgstr ""
msgid "Runners|stale"
msgstr ""
+msgid "Runner|This runner has not run any jobs."
+msgstr ""
+
msgid "Running"
msgstr "실행중"
@@ -31089,6 +31748,24 @@ msgstr ""
msgid "Saving project."
msgstr ""
+msgid "ScanResultPolicy|%{ifLabelStart}if%{ifLabelEnd} %{scanners} scan in an open merge request targeting the %{branches} branch(es) finds %{vulnerabilitiesAllowed} or more %{severities} vulnerabilities that are %{vulnerabilityStates}"
+msgstr ""
+
+msgid "ScanResultPolicy|%{thenLabelStart}Then%{thenLabelEnd} Require approval from %{approvalsRequired} of the following approvers: %{approvers}"
+msgstr ""
+
+msgid "ScanResultPolicy|add an approver"
+msgstr ""
+
+msgid "ScanResultPolicy|scanners"
+msgstr ""
+
+msgid "ScanResultPolicy|severity levels"
+msgstr ""
+
+msgid "ScanResultPolicy|vulnerability states"
+msgstr ""
+
msgid "Scanner"
msgstr ""
@@ -31221,6 +31898,9 @@ msgstr ""
msgid "Search for a user"
msgstr ""
+msgid "Search for an emoji"
+msgstr ""
+
msgid "Search for projects, issues, etc."
msgstr "프로ì íŠ¸, 문제 등 검색"
@@ -31397,18 +32077,12 @@ msgstr "비밀"
msgid "Secret Detection"
msgstr ""
-msgid "Secret access key"
-msgstr ""
-
msgid "Secret token"
msgstr ""
msgid "Secure token that identifies an external storage request."
msgstr ""
-msgid "SecureCodeWarrior"
-msgstr ""
-
msgid "Security"
msgstr "보안"
@@ -31433,9 +32107,6 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "Security training with guide and learning pathways."
-msgstr ""
-
msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
@@ -31538,7 +32209,7 @@ msgstr ""
msgid "SecurityConfiguration|Manage corpus"
msgstr ""
-msgid "SecurityConfiguration|Manage corpus files used as mutation sources in coverage fuzzing."
+msgid "SecurityConfiguration|Manage corpus files used as seed inputs with coverage-guided fuzzing."
msgstr ""
msgid "SecurityConfiguration|Manage profiles for use by DAST scans."
@@ -31604,15 +32275,15 @@ msgstr ""
msgid "SecurityOrchestration|.yaml preview"
msgstr ""
-msgid "SecurityOrchestration|Action"
-msgstr ""
-
msgid "SecurityOrchestration|Actions"
msgstr ""
msgid "SecurityOrchestration|Add rule"
msgstr ""
+msgid "SecurityOrchestration|After dismissing the alert, the information will never be shown again."
+msgstr ""
+
msgid "SecurityOrchestration|All policies"
msgstr ""
@@ -31628,7 +32299,7 @@ msgstr ""
msgid "SecurityOrchestration|Description"
msgstr ""
-msgid "SecurityOrchestration|Disabled"
+msgid "SecurityOrchestration|Don't show the alert anymore"
msgstr ""
msgid "SecurityOrchestration|Edit policy"
@@ -31637,13 +32308,13 @@ msgstr ""
msgid "SecurityOrchestration|Edit policy project"
msgstr ""
-msgid "SecurityOrchestration|Enabled"
+msgid "SecurityOrchestration|Empty policy name"
msgstr ""
-msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Enabled"
msgstr ""
-msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
msgstr ""
msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
@@ -31652,7 +32323,7 @@ msgstr ""
msgid "SecurityOrchestration|Invalid policy type"
msgstr ""
-msgid "SecurityOrchestration|Latest scan"
+msgid "SecurityOrchestration|Latest scan run against %{agent}"
msgstr ""
msgid "SecurityOrchestration|Network"
@@ -31661,15 +32332,27 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No actions defined - policy will not run."
+msgstr ""
+
+msgid "SecurityOrchestration|No description"
+msgstr ""
+
msgid "SecurityOrchestration|No rules defined - policy will not run."
msgstr ""
+msgid "SecurityOrchestration|Not enabled"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
msgid "SecurityOrchestration|Policies"
msgstr ""
+msgid "SecurityOrchestration|Policy Type"
+msgstr ""
+
msgid "SecurityOrchestration|Policy cannot be enabled for non-existing branches (%{branches})"
msgstr ""
@@ -31694,10 +32377,13 @@ msgstr ""
msgid "SecurityOrchestration|Require %{approvals} %{plural} from %{approvers} if any of the following occur:"
msgstr ""
-msgid "SecurityOrchestration|Rule"
+msgid "SecurityOrchestration|Rules"
msgstr ""
-msgid "SecurityOrchestration|Rules"
+msgid "SecurityOrchestration|Runs %{actions} and %{lastAction} scans"
+msgstr ""
+
+msgid "SecurityOrchestration|Runs a %{action} scan"
msgstr ""
msgid "SecurityOrchestration|Scan Execution"
@@ -31757,6 +32443,9 @@ msgstr ""
msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
+msgid "SecurityOrchestration|This view only shows scan results for the agent %{agent}. You can view scan results for all agents in the %{linkStart}Operational Vulnerabilities tab of the vulnerability report%{linkEnd}."
+msgstr ""
+
msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
@@ -31811,9 +32500,6 @@ msgstr ""
msgid "SecurityOrchestration|users with ids"
msgstr ""
-msgid "SecurityOrchestration|view results"
-msgstr ""
-
msgid "SecurityOrchestration|vulnerabilities"
msgstr ""
@@ -32483,22 +33169,19 @@ 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|In order to start using functions as a service, you must first install Knative on your Kubernetes cluster. %{linkStart}More information%{linkEnd}"
-msgstr ""
-
msgid "Serverless|Learn more about Serverless"
msgstr ""
msgid "Serverless|No functions available"
msgstr ""
-msgid "Serverless|Sign up for First Look"
+msgid "Serverless|Serverless was %{linkStart}deprecated%{linkEnd} in GitLab 14.3."
+msgstr ""
+
+msgid "Serverless|Serverless was %{postLinkStart}deprecated%{postLinkEnd}. But if you opt to use it, you must install Knative in your Kubernetes cluster first. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "Serverless|The deploy job has not finished."
@@ -32510,9 +33193,6 @@ 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 ""
@@ -32528,9 +33208,6 @@ msgstr ""
msgid "Service Account Key"
msgstr ""
-msgid "Service Accounts"
-msgstr ""
-
msgid "Service Accounts keys authorize GitLab to deploy your Google Cloud project"
msgstr ""
@@ -32540,10 +33217,10 @@ msgstr "서비스 ë°ìŠ¤í¬"
msgid "Service Desk allows people to create issues in your GitLab instance without their own user account. It provides a unique email address for end users to create issues in a project. Replies can be sent either through the GitLab interface or by email. End users only see threads through email."
msgstr ""
-msgid "Service Usage Data"
+msgid "Service account generated successfully"
msgstr ""
-msgid "Service account generated successfully"
+msgid "Service accounts"
msgstr ""
msgid "Service ping is disabled in your configuration file, and cannot be enabled through this form."
@@ -32687,6 +33364,9 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
+msgid "Set the per-user rate limit for getting a user by ID via the API."
+msgstr ""
+
msgid "Set the per-user rate limit for notes created by web or API requests."
msgstr ""
@@ -32865,6 +33545,9 @@ msgstr ""
msgid "Shared runners details"
msgstr ""
+msgid "Shared runners enabled cannot be enabled until a valid credit card is on file"
+msgstr ""
+
msgid "Shared runners help link"
msgstr ""
@@ -32922,6 +33605,9 @@ msgstr ""
msgid "Show all issues."
msgstr ""
+msgid "Show all milestones"
+msgstr ""
+
msgid "Show all test cases."
msgstr ""
@@ -32958,6 +33644,9 @@ msgstr ""
msgid "Show file contents"
msgstr ""
+msgid "Show group milestones"
+msgstr ""
+
msgid "Show labels"
msgstr ""
@@ -32973,6 +33662,12 @@ msgstr ""
msgid "Show open epics"
msgstr ""
+msgid "Show project milestones"
+msgstr ""
+
+msgid "Show sub-group milestones"
+msgstr ""
+
msgid "Show the Closed list"
msgstr ""
@@ -32982,10 +33677,6 @@ msgstr ""
msgid "Show whitespace changes"
msgstr ""
-msgid "Showing %d event"
-msgid_plural "Showing %d events"
-msgstr[0] "%d ê°œì˜ ì´ë²¤íŠ¸ 표시 중"
-
msgid "Showing %{conflict} between %{sourceBranch} and %{targetBranch}"
msgstr ""
@@ -33044,12 +33735,6 @@ msgstr ""
msgid "Sidebar|None"
msgstr "ì—†ìŒ"
-msgid "Sidebar|Only numeral characters allowed"
-msgstr ""
-
-msgid "Sidebar|Weight"
-msgstr "중요ë„"
-
msgid "Sidekiq job compression threshold (bytes)"
msgstr ""
@@ -33212,6 +33897,9 @@ msgstr ""
msgid "Slack logo"
msgstr ""
+msgid "SlackIntegration|Are you sure you want to remove this project from the Slack application?"
+msgstr ""
+
msgid "SlackIntegration|GitLab for Slack"
msgstr ""
@@ -33221,6 +33909,9 @@ msgstr ""
msgid "SlackIntegration|Project alias"
msgstr ""
+msgid "SlackIntegration|Remove project"
+msgstr ""
+
msgid "SlackIntegration|Select a GitLab project to link with your Slack workspace."
msgstr ""
@@ -33365,9 +34056,6 @@ msgstr ""
msgid "Something went wrong trying to load issue contacts."
msgstr ""
-msgid "Something went wrong when creating a work item. Please try again"
-msgstr ""
-
msgid "Something went wrong when reordering designs. Please try again"
msgstr ""
@@ -33461,9 +34149,6 @@ msgstr ""
msgid "Something went wrong while inserting your image. Please try again."
msgstr ""
-msgid "Something went wrong while merging this merge request. Please try again."
-msgstr ""
-
msgid "Something went wrong while obtaining the Let's Encrypt certificate."
msgstr ""
@@ -33785,10 +34470,10 @@ 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."
+msgid "SourcegraphAdmin|Learn more."
msgstr ""
-msgid "SourcegraphAdmin|More information"
+msgid "SourcegraphAdmin|Only public projects have code intelligence enabled and communicate with Sourcegraph."
msgstr ""
msgid "SourcegraphAdmin|Save changes"
@@ -33797,7 +34482,7 @@ msgstr ""
msgid "SourcegraphAdmin|Sourcegraph URL"
msgstr ""
-msgid "SourcegraphAdmin|e.g. https://sourcegraph.example.com"
+msgid "SourcegraphAdmin|https://sourcegraph.example.com"
msgstr ""
msgid "SourcegraphPreferences|This feature is experimental and currently limited to certain projects."
@@ -33932,6 +34617,9 @@ msgstr ""
msgid "Start date"
msgstr "시작 날짜"
+msgid "Start free trial"
+msgstr ""
+
msgid "Start merge train"
msgstr ""
@@ -33962,6 +34650,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started escalation for this incident."
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -33974,6 +34665,9 @@ msgstr ""
msgid "Starts at (UTC)"
msgstr "(UTC)ì— ì‹œìž‘"
+msgid "Starts escalations for this incident"
+msgstr ""
+
msgid "Starts on"
msgstr ""
@@ -34235,6 +34929,9 @@ msgstr ""
msgid "Strikethrough"
msgstr ""
+msgid "Strikethrough text"
+msgstr ""
+
msgid "Subgroup information"
msgstr ""
@@ -34469,6 +35166,21 @@ msgstr ""
msgid "Subscriptions"
msgstr ""
+msgid "Subscriptions|Chat with sales"
+msgstr ""
+
+msgid "Subscriptions|Close"
+msgstr ""
+
+msgid "Subscriptions|Not ready to buy yet?"
+msgstr ""
+
+msgid "Subscriptions|Start a free trial"
+msgstr ""
+
+msgid "Subscriptions|We understand. Maybe you have some questions for our sales team, or maybe you'd like to try some of the paid features first. What would you like to do?"
+msgstr ""
+
msgid "Subscription|Your subscription for %{strong}%{namespace_name}%{strong_close} has expired and you are now on %{pricing_link_start}the GitLab Free tier%{pricing_link_end}. Don't worry, your data is safe. Get in touch with our support team (%{support_email}). They'll gladly help with your subscription renewal."
msgstr ""
@@ -34679,6 +35391,9 @@ msgstr ""
msgid "SuperSonics|Maximum users"
msgstr ""
+msgid "SuperSonics|Offline cloud"
+msgstr ""
+
msgid "SuperSonics|Paste your activation code"
msgstr ""
@@ -34745,6 +35460,12 @@ msgstr ""
msgid "SuperSonics|You do not have an active subscription"
msgstr ""
+msgid "SuperSonics|You have a future dated license"
+msgstr ""
+
+msgid "SuperSonics|You have added a license that activates on %{date}. Please see the subscription history table below for more details."
+msgstr ""
+
msgid "SuperSonics|You have successfully added a license that activates on %{date}. Please see the subscription history table below for more details."
msgstr ""
@@ -34904,6 +35625,9 @@ msgstr "태그 ì´ë¦„"
msgid "Tag name is required"
msgstr "태그 ì´ë¦„ì´ í•„ìš”í•©ë‹ˆë‹¤."
+msgid "Tag push"
+msgstr ""
+
msgid "Tag push events"
msgstr ""
@@ -35006,6 +35730,9 @@ msgstr ""
msgid "TagsPage|protected"
msgstr "보호ë¨"
+msgid "Take a look at the documentation to discover all of GitLab’s capabilities."
+msgstr ""
+
msgid "Target Branch"
msgstr "ëŒ€ìƒ ë¸Œëžœì¹˜"
@@ -35402,6 +36129,9 @@ msgstr ""
msgid "Tests"
msgstr ""
+msgid "Text (optional)"
+msgstr ""
+
msgid "Text added to the body of all email messages. %{character_limit} character limit"
msgstr ""
@@ -35451,6 +36181,9 @@ msgstr ""
msgid "The CSV export will be created in the background. Once finished, it will be sent to %{email} in an attachment."
msgstr ""
+msgid "The CSV export you requested of all user memberships is attached to this email."
+msgstr ""
+
msgid "The GitLab subscription service (customers.gitlab.com) is currently experiencing an outage. You can monitor the status and get updates at %{linkStart}status.gitlab.com%{linkEnd}."
msgstr ""
@@ -35526,6 +36259,9 @@ 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 epic"
+msgstr ""
+
msgid "The current issue"
msgstr "현재 ì´ìŠˆ"
@@ -35686,6 +36422,9 @@ msgstr ""
msgid "The latest pipeline for this merge request has failed."
msgstr ""
+msgid "The license key is invalid."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -35701,6 +36440,9 @@ msgstr ""
msgid "The license was successfully uploaded and will be active from %{starts_at}. You can see the details below."
msgstr ""
+msgid "The license you uploaded is invalid. If the issue persists, contact support at %{link}."
+msgstr ""
+
msgid "The list creation wizard is already open"
msgstr ""
@@ -36322,10 +37064,13 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} and everything this project contains. %{strongOpen}There is no going back%{strongClose}"
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}on %{date}%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains."
+msgstr ""
+
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains. %{strongOpen}There is no going back.%{strongClose}"
msgstr ""
msgid "This action will %{strongOpen}permanently remove%{strongClose} %{codeOpen}%{group}%{codeClose} %{strongOpen}immediately%{strongClose}."
@@ -36454,9 +37199,6 @@ msgstr ""
msgid "This file was modified for readability, and can't accept suggestions. Edit it directly."
msgstr ""
-msgid "This forked project has the following:"
-msgstr ""
-
msgid "This form is disabled in preview"
msgstr ""
@@ -36469,7 +37211,7 @@ msgstr ""
msgid "This group can't be removed because it is linked to a subscription. To remove this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
-msgid "This group can't be transfered because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
+msgid "This group can't be transferred because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
msgid "This group cannot be invited to a project inside a group with enforced SSO"
@@ -36496,6 +37238,9 @@ 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 incident is already escalated with '%{escalation_policy_name}'."
+msgstr ""
+
msgid "This invitation was sent to %{mail_to_invite_email}, but you are signed in as %{link_to_current_user} with email %{mail_to_current_user}."
msgstr ""
@@ -36514,9 +37259,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 merge train pipeline"
-msgstr ""
-
msgid "This is a private email address %{helpIcon} generated just for you. Anyone who has it can create issues or merge requests as if they were you. If that happens, %{resetLinkStart}reset this token%{resetLinkEnd}."
msgstr ""
@@ -36538,6 +37280,12 @@ msgstr ""
msgid "This is your current session"
msgstr ""
+msgid "This issue cannot be assigned to a confidential epic because it is public."
+msgstr ""
+
+msgid "This issue cannot be made public because it belongs to a confidential epic."
+msgstr ""
+
msgid "This issue is confidential and should only be visible to team members with at least Reporter access."
msgstr ""
@@ -36655,6 +37403,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 branch is protected from force push."
+msgstr ""
+
msgid "This merge request cannot be rebased while there are conflicts."
msgstr ""
@@ -36706,9 +37457,15 @@ msgstr ""
msgid "This pipeline was triggered by a schedule."
msgstr ""
+msgid "This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project"
msgstr "ì´ í”„ë¡œì íŠ¸"
+msgid "This project can be restored until %{date}."
+msgstr ""
+
msgid "This project cannot be %{visibilityLevel} because the visibility of %{openShowLink}%{name}%{closeShowLink} is %{visibility}. To make this project %{visibilityLevel}, you must first %{openEditLink}change the visibility%{closeEditLink} of the parent group."
msgstr ""
@@ -36727,6 +37484,9 @@ msgstr ""
msgid "This project is %{strongStart}NOT%{strongEnd} a fork, and has the following:"
msgstr ""
+msgid "This project is %{strongStart}NOT%{strongEnd} a fork. This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -37416,6 +38176,9 @@ msgstr "í•  ì¼ í•­ëª©ì´ ì„±ê³µì ìœ¼ë¡œ 완료로 표시ë˜ì—ˆìŠµë‹ˆë‹¤."
msgid "Today"
msgstr "오늘"
+msgid "Todos count"
+msgstr ""
+
msgid "Todos|Are you looking for things to do? Take a look at %{strongStart}%{openIssuesLinkStart}open issues%{openIssuesLinkEnd}%{strongEnd}, contribute to %{strongStart}%{mergeRequestLinkStart}a merge request%{mergeRequestLinkEnd}%{mergeRequestLinkEnd}%{strongEnd}, or mention someone in a comment to automatically assign them a new to-do item."
msgstr ""
@@ -37689,9 +38452,8 @@ msgstr ""
msgid "Trending"
msgstr "ì¸ê¸°"
-msgid "Trials|%{planName} Trial %{enDash} %{num} day left"
-msgid_plural "Trials|%{planName} Trial %{enDash} %{num} days left"
-msgstr[0] ""
+msgid "Trials|%{planName} Trial"
+msgstr ""
msgid "Trials|Compare all plans"
msgstr ""
@@ -37699,6 +38461,9 @@ msgstr ""
msgid "Trials|Create a new group to start your GitLab Ultimate trial."
msgstr ""
+msgid "Trials|Day %{daysUsed}/%{duration}"
+msgstr ""
+
msgid "Trials|Go back to GitLab"
msgstr ""
@@ -37948,8 +38713,8 @@ msgstr "새 태그가 ì €ìž¥ì†Œì— í‘¸ì‰¬ë˜ë©´ URLì´ íŠ¸ë¦¬ê±°ë©ë‹ˆë‹¤."
msgid "URL is triggered when repository is updated"
msgstr ""
-msgid "URL must be percent-encoded if neccessary."
-msgstr "필요한 경우 URLì„ í¼ì„¼íŠ¸ ì¸ì½”ë”©ì„ í•´ì•¼í•©ë‹ˆë‹¤."
+msgid "URL must be percent-encoded if necessary."
+msgstr ""
msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
msgstr ""
@@ -38167,6 +38932,9 @@ msgstr "잠금 해제"
msgid "Unlock account"
msgstr ""
+msgid "Unlock more features with GitLab Ultimate"
+msgstr ""
+
msgid "Unlock the discussion"
msgstr ""
@@ -38230,6 +38998,9 @@ msgstr ""
msgid "Unsubscribes from this %{quick_action_target}."
msgstr ""
+msgid "Unsupported sort value."
+msgstr ""
+
msgid "Unsupported todo type passed. Supported todo types are: %{todo_types}"
msgstr ""
@@ -38458,6 +39229,9 @@ msgstr "ì´ë²ˆ ê²°ì œ 주기 사용량"
msgid "UsageQuota|File attachments and smaller design graphics."
msgstr ""
+msgid "UsageQuota|From %{storage_enforcement_date} storage limits will apply to this namespace. View and manage your usage in %{strong_start}Group Settings &gt; Usage quotas%{strong_end}."
+msgstr ""
+
msgid "UsageQuota|Git repository."
msgstr ""
@@ -38518,6 +39292,9 @@ msgstr "저장 공간"
msgid "UsageQuota|Storage type"
msgstr ""
+msgid "UsageQuota|Storage used"
+msgstr ""
+
msgid "UsageQuota|This is the total amount of storage used across your projects within this namespace."
msgstr "ì´ ë„¤ìž„ìŠ¤íŽ˜ì´ìŠ¤ì˜ 프로ì íŠ¸ì—ì„œ ì´ ì‚¬ìš©ì¤‘ì¸ ì €ìž¥ 공간입니다."
@@ -38713,6 +39490,12 @@ msgstr ""
msgid "Use hashed storage paths for newly created and renamed repositories. Always enabled since 13.0."
msgstr ""
+msgid "Use issue count"
+msgstr ""
+
+msgid "Use issue weight"
+msgstr ""
+
msgid "Use one line per URI"
msgstr ""
@@ -39094,6 +39877,9 @@ msgstr ""
msgid "Users"
msgstr "사용ìžë“¤"
+msgid "Users API rate limit"
+msgstr ""
+
msgid "Users can launch a development environment from a GitLab browser tab when the %{linkStart}Gitpod%{linkEnd} integration is enabled."
msgstr ""
@@ -39417,6 +40203,9 @@ msgstr ""
msgid "View group labels"
msgstr "그룹 ë¼ë²¨ 보기"
+msgid "View group pipeline usage quota"
+msgstr ""
+
msgid "View incident details at"
msgstr ""
@@ -39568,6 +40357,9 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
+msgid "Vulnerability"
+msgstr ""
+
msgid "Vulnerability Report"
msgstr ""
@@ -39619,6 +40411,9 @@ msgstr ""
msgid "VulnerabilityManagement|An unverified non-confirmed finding"
msgstr ""
+msgid "VulnerabilityManagement|At least one identifier is required"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -39628,12 +40423,24 @@ msgstr ""
msgid "VulnerabilityManagement|Create Jira issue"
msgstr ""
+msgid "VulnerabilityManagement|Enter a name"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE code"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE identifier URL"
+msgstr ""
+
msgid "VulnerabilityManagement|Fetching linked Jira issues"
msgstr ""
msgid "VulnerabilityManagement|Manually add a vulnerability entry into the vulnerability report."
msgstr ""
+msgid "VulnerabilityManagement|Name is a required field"
+msgstr ""
+
msgid "VulnerabilityManagement|Needs triage"
msgstr ""
@@ -39649,6 +40456,18 @@ msgstr ""
msgid "VulnerabilityManagement|Select a method"
msgstr ""
+msgid "VulnerabilityManagement|Select a severity level"
+msgstr ""
+
+msgid "VulnerabilityManagement|Select a status"
+msgstr ""
+
+msgid "VulnerabilityManagement|Severity is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Something went wrong while creating vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -39673,6 +40492,12 @@ msgstr ""
msgid "VulnerabilityManagement|Something went wrong, could not update vulnerability state."
msgstr ""
+msgid "VulnerabilityManagement|Status is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Submit vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Summary, detailed description, steps to reproduce, etc."
msgstr ""
@@ -39868,6 +40693,9 @@ msgstr ""
msgid "WARNING:"
msgstr "경고:"
+msgid "WARNING: This snippet contains hidden files which might be used to mask malicious behavior. Exercise caution if cloning and executing code from this snippet."
+msgstr ""
+
msgid "Wait for the file to load to copy its contents"
msgstr ""
@@ -40087,6 +40915,15 @@ msgstr ""
msgid "Webhooks|An issue is created, updated, closed, or reopened."
msgstr ""
+msgid "Webhooks|Are you sure you want to delete this group hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this project hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this webhook?"
+msgstr ""
+
msgid "Webhooks|Comments"
msgstr ""
@@ -40096,6 +40933,9 @@ msgstr ""
msgid "Webhooks|Confidential issues events"
msgstr ""
+msgid "Webhooks|Delete webhook"
+msgstr ""
+
msgid "Webhooks|Deployment events"
msgstr ""
@@ -40328,6 +41168,9 @@ msgstr ""
msgid "Wiki"
msgstr "위키"
+msgid "Wiki page"
+msgstr ""
+
msgid "Wiki page was successfully created."
msgstr ""
@@ -40433,7 +41276,7 @@ msgstr ""
msgid "WikiPageConflictMessage|Someone edited the page the same time you did. Please check out %{wikiLinkStart}the page%{wikiLinkEnd} and make sure your changes will not unintentionally remove theirs."
msgstr ""
-msgid "WikiPage|An error occured while trying to render the content editor. Please try again later."
+msgid "WikiPage|An error occurred while trying to render the content editor. Please try again later."
msgstr ""
msgid "WikiPage|Are you sure you want to switch back to the classic editor?"
@@ -40592,6 +41435,18 @@ msgstr ""
msgid "WorkItem|New Task"
msgstr ""
+msgid "WorkItem|Something went wrong when creating a work item. Please try again"
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching the work item. Please try again."
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching work item types. Please try again"
+msgstr ""
+
+msgid "WorkItem|Type"
+msgstr ""
+
msgid "WorkItem|Work Items"
msgstr ""
@@ -40658,7 +41513,10 @@ msgstr ""
msgid "You are about to add %{usersTag} people to the discussion. They will all receive a notification."
msgstr ""
-msgid "You are about to permanently delete this project"
+msgid "You are about to delete this forked project containing:"
+msgstr ""
+
+msgid "You are about to delete this project containing:"
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."
@@ -40679,6 +41537,9 @@ msgstr ""
msgid "You are attempting to update a file that has changed since you started editing it."
msgstr ""
+msgid "You are billed if you exceed this number. %{qsrOverageLinkStart}How does billing work?%{qsrOverageLinkEnd}"
+msgstr ""
+
msgid "You are connected to the Prometheus server, but there is currently no data to display."
msgstr ""
@@ -40736,6 +41597,9 @@ msgstr ""
msgid "You are not authorized to update this scanner profile"
msgstr ""
+msgid "You are not authorized to upload metric images"
+msgstr ""
+
msgid "You are now impersonating %{username}"
msgstr ""
@@ -40889,9 +41753,6 @@ msgstr ""
msgid "You can only upload one design when dropping onto an existing design."
msgstr ""
-msgid "You can recover this project until %{date}"
-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 ""
@@ -40940,9 +41801,6 @@ msgstr ""
msgid "You cannot write to this read-only GitLab instance."
msgstr "ì½ê¸° ì „ìš© GitLab ì¸ìŠ¤í„´ìŠ¤ì—는 쓰기가 불가능합니다."
-msgid "You can’t %{tag_start}edit%{tag_end} files directly in this project. Fork this project and submit a merge request with your changes."
-msgstr ""
-
msgid "You can’t edit files directly in this project. Fork this project and submit a merge request with your changes."
msgstr ""
@@ -41094,9 +41952,6 @@ 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 set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
@@ -41127,12 +41982,6 @@ msgstr ""
msgid "You must have maintainer access to force delete a lock"
msgstr "강제로 ìž ê¸ˆì„ ì œê±°í•˜ë ¤ë©´ ê´€ë¦¬ìž ê¶Œí•œì´ ìžˆì–´ì•¼í•©ë‹ˆë‹¤."
-msgid "You must have permission to create a project in a group before forking."
-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 "정확한 현재 비밀번호를 제공해야 합니다."
@@ -41538,7 +42387,7 @@ msgstr "ë‚´ 프로ì íŠ¸"
msgid "Your public email will be displayed on your public profile."
msgstr ""
-msgid "Your request for access could not be processed: %{error_meesage}"
+msgid "Your request for access could not be processed: %{error_message}"
msgstr ""
msgid "Your request for access has been queued for review."
@@ -41718,6 +42567,9 @@ msgstr ""
msgid "archived:"
msgstr ""
+msgid "artifacts"
+msgstr ""
+
msgid "assign yourself"
msgstr ""
@@ -41746,6 +42598,9 @@ msgstr[0] "브랜치"
msgid "branch name"
msgstr "브랜치 ì´ë¦„"
+msgid "builds"
+msgstr ""
+
msgid "by"
msgstr "by"
@@ -42166,6 +43021,9 @@ msgstr ""
msgid "contact with same email already exists in group hierarchy"
msgstr ""
+msgid "container registry images"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -42205,6 +43063,9 @@ msgstr ""
msgid "data"
msgstr ""
+msgid "database"
+msgstr ""
+
msgid "date must not be after 9999-12-31"
msgstr ""
@@ -42227,9 +43088,6 @@ msgstr ""
msgid "design"
msgstr "ë””ìžì¸"
-msgid "detached"
-msgstr ""
-
msgid "disabled"
msgstr "사용 안 함"
@@ -42474,7 +43332,7 @@ msgstr ""
msgid "is not a valid X509 certificate."
msgstr "올바른 X509 ì¸ì¦ì„œê°€ 아닙니다."
-msgid "is not allowed for sign-up."
+msgid "is not allowed for sign-up. Please use your regular email address."
msgstr ""
msgid "is not allowed for this group."
@@ -42486,7 +43344,7 @@ msgstr ""
msgid "is not allowed since the group is not top-level group."
msgstr ""
-msgid "is not allowed."
+msgid "is not allowed. Please use your regular email address."
msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
@@ -42573,6 +43431,9 @@ msgstr ""
msgid "level: %{level}"
msgstr ""
+msgid "lfs objects"
+msgstr ""
+
msgid "limit of %{project_limit} reached"
msgstr ""
@@ -42789,6 +43650,9 @@ msgstr ""
msgid "mrWidget|Merge blocked: pipeline must succeed. It's waiting for a manual action to continue."
msgstr ""
+msgid "mrWidget|Merge blocked: pipeline must succeed. Push a commit that fixes the failure, or %{linkStart}learn about other solutions.%{linkEnd}"
+msgstr ""
+
msgid "mrWidget|Merge blocked: this merge request must be approved."
msgstr ""
@@ -42906,9 +43770,6 @@ msgstr "변경 ì‚¬í•­ì´ ë¨¸ì§€ë˜ì—ˆìŠµë‹ˆë‹¤."
msgid "mrWidget|The changes were not merged into"
msgstr "변경 ì‚¬í•­ì´ ë¨¸ì§€ë˜ì§€ 않았습니다."
-msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
-msgstr "ì´ ë¨¸ì§€ ë¦¬í€˜ìŠ¤íŠ¸ì— ëŒ€í•œ 파ì´í”„ë¼ì¸ì´ 완료ë˜ì§€ 않았습니다. 새 ì»¤ë°‹ì„ í‘¸ì‹œí•˜ì—¬ 오류를 수정하거나 %{linkStart}문제 í•´ê²° 문서%{linkEnd}를 확ì¸í•˜ì—¬ 가능한 다른 ìž‘ì—…ì„ í™•ì¸í•˜ì„¸ìš”."
-
msgid "mrWidget|The source branch has been deleted"
msgstr "소스 브랜치가 제거ë˜ì—ˆìŠµë‹ˆë‹¤."
@@ -43056,9 +43917,6 @@ msgstr "최ìƒìœ„ 그룹ì—서만 사용 가능합니다."
msgid "open issue"
msgstr "ì´ìŠˆ 열기"
-msgid "opened %{timeAgo}"
-msgstr "%{timeAgo}ì— ì—´ë¦¼"
-
msgid "or"
msgstr ""
@@ -43069,6 +43927,12 @@ msgid "out of %d total test"
msgid_plural "out of %d total tests"
msgstr[0] "전체 테스트 중 %d"
+msgid "packages"
+msgstr ""
+
+msgid "pages"
+msgstr ""
+
msgid "parent"
msgid_plural "parents"
msgstr[0] "부모"
@@ -43214,6 +44078,9 @@ msgid "reply"
msgid_plural "replies"
msgstr[0] "답변"
+msgid "repositories"
+msgstr ""
+
msgid "repository:"
msgstr "저장소:"
@@ -43334,12 +44201,18 @@ msgstr ""
msgid "tag name"
msgstr ""
+msgid "terraform states"
+msgstr ""
+
msgid "the correct format."
msgstr ""
msgid "the file"
msgstr ""
+msgid "the following epic(s)"
+msgstr ""
+
msgid "the following issue(s)"
msgstr ""
@@ -43352,21 +44225,12 @@ msgstr ""
msgid "this document"
msgstr "ì´ ë¬¸ì„œ"
-msgid "this issue cannot be assigned to a confidential epic since it is public"
-msgstr ""
-
-msgid "this issue cannot be made public since it belongs to a confidential epic"
-msgstr ""
-
msgid "time summary"
msgstr ""
msgid "toggle collapse"
msgstr ""
-msgid "train"
-msgstr ""
-
msgid "triggered"
msgstr ""
@@ -43494,3 +44358,6 @@ msgstr "{그룹}"
msgid "{project}"
msgstr "{프로ì íŠ¸}"
+msgid "✔"
+msgstr ""
+
diff --git a/locale/ku_TR/gitlab.po b/locale/ku_TR/gitlab.po
index 037e73633d7..42b1fbfaad4 100644
--- a/locale/ku_TR/gitlab.po
+++ b/locale/ku_TR/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: ku\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2022-02-02 15:46\n"
+"PO-Revision-Date: 2022-03-01 20:39\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -146,6 +146,11 @@ msgid_plural "%d approvers (you've approved)"
msgstr[0] ""
msgstr[1] ""
+msgid "%d assigned issue"
+msgid_plural "%d assigned issues"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -421,8 +426,23 @@ msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
msgstr[1] ""
-msgid "%d vulnerability updated"
-msgid_plural "%d vulnerabilities updated"
+msgid "%d vulnerability set to confirmed"
+msgid_plural "%d vulnerabilities set to confirmed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to dismissed"
+msgid_plural "%d vulnerabilities set to dismissed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to needs triage"
+msgid_plural "%d vulnerabilities set to needs triage"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to resolved"
+msgid_plural "%d vulnerabilities set to resolved"
msgstr[0] ""
msgstr[1] ""
@@ -510,6 +530,12 @@ msgstr[1] ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{completed} of %{total} issues closed"
+msgstr ""
+
+msgid "%{completed} of %{total} weight completed"
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -858,6 +884,9 @@ msgstr ""
msgid "%{openedIssues} open, %{closedIssues} closed"
msgstr ""
+msgid "%{percentage}%% issues closed"
+msgstr ""
+
msgid "%{percentage}%% weight completed"
msgstr ""
@@ -1287,6 +1316,9 @@ msgid_plural "- Users"
msgstr[0] ""
msgstr[1] ""
+msgid "- of - issues closed"
+msgstr ""
+
msgid "- of - weight completed"
msgstr ""
@@ -1429,7 +1461,7 @@ msgstr ""
msgid "1000+"
msgstr ""
-msgid "192.168.0.0/24"
+msgid "192.168.0.0/24 or 2001:0DB8:1234::/48"
msgstr ""
msgid "1st contribution!"
@@ -1741,13 +1773,13 @@ msgstr ""
msgid "AWS Access Key"
msgstr ""
-msgid "AWS Access Key. Only required if not using role instance credentials"
+msgid "AWS Secret Access Key"
msgstr ""
-msgid "AWS Secret Access Key"
+msgid "AWS access key ID (Optional)"
msgstr ""
-msgid "AWS Secret Access Key. Only required if not using role instance credentials"
+msgid "AWS secret access key (Optional)"
msgstr ""
msgid "AWS service error: %{error}"
@@ -1807,9 +1839,6 @@ msgstr ""
msgid "Access granted"
msgstr ""
-msgid "Access key ID"
-msgstr ""
-
msgid "Access requests"
msgstr ""
@@ -1984,7 +2013,7 @@ msgstr ""
msgid "Activity"
msgstr ""
-msgid "Activity|An error occured while retrieving activity. Reload the page to try again."
+msgid "Activity|An error occurred while retrieving activity. Reload the page to try again."
msgstr ""
msgid "Add"
@@ -2023,6 +2052,9 @@ msgstr ""
msgid "Add a %{type}"
msgstr ""
+msgid "Add a GCP region"
+msgstr ""
+
msgid "Add a GPG key"
msgstr ""
@@ -2074,6 +2106,9 @@ msgstr ""
msgid "Add a numbered list"
msgstr ""
+msgid "Add a related epic"
+msgstr ""
+
msgid "Add a related issue"
msgstr ""
@@ -2188,6 +2223,9 @@ msgstr ""
msgid "Add or subtract spent time"
msgstr ""
+msgid "Add people"
+msgstr ""
+
msgid "Add previously merged commits"
msgstr ""
@@ -2254,6 +2292,9 @@ msgstr ""
msgid "Add webhook"
msgstr ""
+msgid "Add your team members and others to GitLab."
+msgstr ""
+
msgid "Add/remove"
msgstr ""
@@ -3076,12 +3117,6 @@ msgstr ""
msgid "AdvancedSearch|Reindex required"
msgstr ""
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. Permanently deleting this project will %{strongStart}immediately delete%{strongEnd} its repositories and %{strongStart}all related resources%{strongEnd}, including issues, merge requests etc."
-msgstr ""
-
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. You will lose this project's repository and %{strongStart}all related resources%{strongEnd}, including issues and merge requests."
-msgstr ""
-
msgid "After a successful password update you will be redirected to login screen."
msgstr ""
@@ -3112,6 +3147,9 @@ msgstr ""
msgid "Akismet helps prevent the creation of spam issues in public projects."
msgstr ""
+msgid "Alert"
+msgstr ""
+
msgid "AlertManagement|Acknowledged"
msgstr ""
@@ -3484,9 +3522,6 @@ msgstr ""
msgid "All environments"
msgstr ""
-msgid "All epics"
-msgstr ""
-
msgid "All groups and projects"
msgstr ""
@@ -4223,12 +4258,15 @@ msgstr ""
msgid "ApplicationSettings|Approve users in the pending approval status?"
msgstr ""
-msgid "ApplicationSettings|By making this change, you will automatically approve %d user with the pending approval status."
-msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users with the pending approval status."
+msgid "ApplicationSettings|Approve users who are pending approval?"
+msgstr ""
+
+msgid "ApplicationSettings|By making this change, you will automatically approve %d user who is pending approval."
+msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users who are pending approval."
msgstr[0] ""
msgstr[1] ""
-msgid "ApplicationSettings|By making this change, you will automatically approve all users in pending approval status."
+msgid "ApplicationSettings|By making this change, you will automatically approve all users who are pending approval."
msgstr ""
msgid "ApplicationSettings|Denied domains for sign-ups"
@@ -4634,10 +4672,10 @@ msgstr ""
msgid "Archiving the project will make it entirely read-only. It is hidden from the dashboard and doesn't show up in searches. %{strong_start}The repository cannot be committed to, and no issues, comments, or other entities can be created.%{strong_end} %{link_start}Learn more.%{link_end}"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to delete this project?"
+msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
+msgid "Are you absolutely sure?"
msgstr ""
msgid "Are you sure that you want to archive this project?"
@@ -4673,12 +4711,18 @@ msgstr ""
msgid "Are you sure you want to delete this SSH key?"
msgstr ""
+msgid "Are you sure you want to delete this comment?"
+msgstr ""
+
msgid "Are you sure you want to delete this deploy key?"
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 label?"
+msgstr ""
+
msgid "Are you sure you want to delete this pipeline schedule?"
msgstr ""
@@ -4694,9 +4738,6 @@ msgstr ""
msgid "Are you sure you want to discard your changes?"
msgstr ""
-msgid "Are you sure you want to erase this build?"
-msgstr ""
-
msgid "Are you sure you want to import %d repository?"
msgid_plural "Are you sure you want to import %d repositories?"
msgstr[0] ""
@@ -4744,6 +4785,9 @@ msgstr ""
msgid "Are you sure you want to remove this list?"
msgstr ""
+msgid "Are you sure you want to remove this nickname?"
+msgstr ""
+
msgid "Are you sure you want to reset the health check token?"
msgstr ""
@@ -4756,10 +4800,10 @@ 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?"
+msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
msgstr ""
-msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
+msgid "Are you sure you want to revoke this project access token? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to stop this environment?"
@@ -4906,9 +4950,6 @@ msgstr ""
msgid "Assigned to %{assignee_name}"
msgstr ""
-msgid "Assigned to %{name}"
-msgstr ""
-
msgid "Assigned to me"
msgstr ""
@@ -4973,6 +5014,9 @@ msgstr[1] ""
msgid "Attaching the file failed."
msgstr ""
+msgid "Attention"
+msgstr ""
+
msgid "Audit Events"
msgstr ""
@@ -5135,6 +5179,12 @@ msgstr ""
msgid "Authorized applications (%{size})"
msgstr ""
+msgid "AuthorizedApplication|Are you sure you want to revoke this application?"
+msgstr ""
+
+msgid "AuthorizedApplication|Revoke application"
+msgstr ""
+
msgid "Authors: %{authors}"
msgstr ""
@@ -6328,6 +6378,9 @@ msgstr ""
msgid "CICDAnalytics|Shared Runners Usage"
msgstr ""
+msgid "CICDAnalytics|Shared runner pipeline minute duration by month"
+msgstr ""
+
msgid "CICDAnalytics|Shared runner usage"
msgstr ""
@@ -6469,6 +6522,9 @@ msgstr ""
msgid "Can create groups:"
msgstr ""
+msgid "Can not delete primary training"
+msgstr ""
+
msgid "Can't apply as the source branch was deleted."
msgstr ""
@@ -6802,9 +6858,6 @@ msgstr ""
msgid "Changing any setting here requires an application restart"
msgstr ""
-msgid "Changing group URL can have unintended side effects."
-msgstr ""
-
msgid "Charts can't be displayed as the request for data has timed out. %{documentationLink}"
msgstr ""
@@ -6892,9 +6945,6 @@ msgstr ""
msgid "Checking branch availability..."
msgstr ""
-msgid "Checking group URL availability..."
-msgstr ""
-
msgid "Checking group path availability..."
msgstr ""
@@ -7388,6 +7438,9 @@ msgstr ""
msgid "Clear recent searches"
msgstr ""
+msgid "Clear repository checks"
+msgstr ""
+
msgid "Clear search"
msgstr ""
@@ -7520,9 +7573,6 @@ msgstr ""
msgid "Closed MRs"
msgstr ""
-msgid "Closed epics"
-msgstr ""
-
msgid "Closed issues"
msgstr ""
@@ -7559,13 +7609,13 @@ msgstr ""
msgid "Cluster level"
msgstr ""
-msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
+msgid "Cluster type must be specified for Stages::ClusterEndpointInserter"
msgstr ""
msgid "ClusterAgents|%{name} successfully deleted"
msgstr ""
-msgid "ClusterAgents|%{number} of %{total} Agents"
+msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
@@ -7607,6 +7657,15 @@ msgstr ""
msgid "ClusterAgents|Agent never connected to GitLab"
msgstr ""
+msgid "ClusterAgents|Agent version mismatch"
+msgstr ""
+
+msgid "ClusterAgents|Agent version mismatch and update"
+msgstr ""
+
+msgid "ClusterAgents|Agent version update required"
+msgstr ""
+
msgid "ClusterAgents|All"
msgstr ""
@@ -7631,7 +7690,7 @@ msgstr ""
msgid "ClusterAgents|Configuration"
msgstr ""
-msgid "ClusterAgents|Connect a cluster through the Agent"
+msgid "ClusterAgents|Connect a cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connect existing cluster"
@@ -7640,13 +7699,13 @@ msgstr ""
msgid "ClusterAgents|Connect with a certificate"
msgstr ""
-msgid "ClusterAgents|Connect with agent"
+msgid "ClusterAgents|Connect with an agent"
msgstr ""
msgid "ClusterAgents|Connect with the GitLab Agent"
msgstr ""
-msgid "ClusterAgents|Connect your cluster through the Agent"
+msgid "ClusterAgents|Connect your cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connected"
@@ -7706,7 +7765,10 @@ msgstr ""
msgid "ClusterAgents|How to register an agent?"
msgstr ""
-msgid "ClusterAgents|Install new Agent"
+msgid "ClusterAgents|How to update an agent?"
+msgstr ""
+
+msgid "ClusterAgents|Install a new agent"
msgstr ""
msgid "ClusterAgents|Last connected %{timeAgo}."
@@ -7733,7 +7795,7 @@ msgstr ""
msgid "ClusterAgents|Never connected"
msgstr ""
-msgid "ClusterAgents|No Agents"
+msgid "ClusterAgents|No agents"
msgstr ""
msgid "ClusterAgents|No clusters connected through cluster certificates"
@@ -7793,6 +7855,9 @@ msgstr ""
msgid "ClusterAgents|The agent has not been connected in a long time. There might be a connectivity issue. Last contact was %{timeAgo}."
msgstr ""
+msgid "ClusterAgents|The agent version do not match each other across your cluster's pods. This can happen when a new agent version was just deployed and Kubernetes is shutting down the old pods."
+msgstr ""
+
msgid "ClusterAgents|The recommended installation method includes the token. If you want to follow the advanced installation method provided in the docs, make sure you save the token value before you close this window."
msgstr ""
@@ -7840,6 +7905,9 @@ msgstr ""
msgid "ClusterAgents|You will need to create a token to connect to your agent"
msgstr ""
+msgid "ClusterAgents|Your agent version is out of sync with your GitLab version (v%{version}), which might cause compatibility problems. Update the agent installed on your cluster to the most recent version."
+msgstr ""
+
msgid "ClusterAgents|Your instance doesn't have the %{linkStart}GitLab Agent Server (KAS)%{linkEnd} set up. Ask a GitLab Administrator to install it."
msgstr ""
@@ -8716,9 +8784,6 @@ msgstr ""
msgid "Comma-separated list of email addresses."
msgstr ""
-msgid "Comma-separated list of users allowed to exceed the rate limit."
-msgstr ""
-
msgid "Comma-separated, e.g. '1.1.1.1, 2.2.2.0/24'"
msgstr ""
@@ -9045,6 +9110,12 @@ msgstr ""
msgid "Confidential"
msgstr ""
+msgid "Confidential issue"
+msgstr ""
+
+msgid "Confidential note"
+msgstr ""
+
msgid "Confidentiality"
msgstr ""
@@ -9078,6 +9149,9 @@ msgstr ""
msgid "Configure Dependency Scanning in `.gitlab-ci.yml`, creating this file if it does not already exist"
msgstr ""
+msgid "Configure GitLab"
+msgstr ""
+
msgid "Configure GitLab runners to start using the Web Terminal. %{helpStart}Learn more.%{helpEnd}"
msgstr ""
@@ -9126,6 +9200,15 @@ msgstr ""
msgid "Configure pipelines to deploy web apps, backend services, APIs and static resources to Google Cloud"
msgstr ""
+msgid "Configure region"
+msgstr ""
+
+msgid "Configure region for environment"
+msgstr ""
+
+msgid "Configure regions"
+msgstr ""
+
msgid "Configure repository mirroring."
msgstr ""
@@ -9159,6 +9242,9 @@ msgstr ""
msgid "Configure which lists are shown for anyone who visits this board"
msgstr ""
+msgid "Configure your environments to be deployed to specific geographical regions"
+msgstr ""
+
msgid "Confirm"
msgstr ""
@@ -9861,10 +9947,10 @@ msgstr ""
msgid "CorpusManagement|Actions"
msgstr ""
-msgid "CorpusManagement|Corpus are used in fuzz testing as mutation source to Improve future testing."
+msgid "CorpusManagement|Corpus file"
msgstr ""
-msgid "CorpusManagement|Corpus file"
+msgid "CorpusManagement|Corpus files are used in coverage-guided fuzz testing as seed inputs to improve testing."
msgstr ""
msgid "CorpusManagement|Corpus files must be in *.zip format. Maximum 5 GB"
@@ -9918,6 +10004,9 @@ msgstr ""
msgid "Could not apply %{name} command."
msgstr ""
+msgid "Could not apply %{name} command. %{message}."
+msgstr ""
+
msgid "Could not authorize chat nickname. Try again!"
msgstr ""
@@ -10068,6 +10157,9 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
+msgid "Create a group"
+msgstr ""
+
msgid "Create a merge request"
msgstr ""
@@ -10092,6 +10184,9 @@ msgstr ""
msgid "Create a personal access token on your account to pull or push via %{protocol}."
msgstr ""
+msgid "Create a project"
+msgstr ""
+
msgid "Create an account using:"
msgstr ""
@@ -10455,6 +10550,9 @@ msgstr ""
msgid "Creation date"
msgstr ""
+msgid "Creator"
+msgstr ""
+
msgid "Credentials"
msgstr ""
@@ -10467,9 +10565,15 @@ msgstr ""
msgid "CredentialsInventory|Personal Access Tokens"
msgstr ""
+msgid "CredentialsInventory|Project Access Tokens"
+msgstr ""
+
msgid "CredentialsInventory|SSH Keys"
msgstr ""
+msgid "Credit card required to be on file in order to create a pipeline"
+msgstr ""
+
msgid "Credit card:"
msgstr ""
@@ -10653,9 +10757,6 @@ msgstr ""
msgid "Customer relations"
msgstr ""
-msgid "Customizable by an administrator."
-msgstr ""
-
msgid "Customizable by owners."
msgstr ""
@@ -10785,30 +10886,18 @@ msgstr ""
msgid "CycleAnalytics|%{selectedLabelsCount} selected (%{maxLabels} max)"
msgstr ""
-msgid "CycleAnalytics|%{stageCount} stages selected"
-msgstr ""
-
-msgid "CycleAnalytics|All stages"
-msgstr ""
-
-msgid "CycleAnalytics|Average days to completion"
+msgid "CycleAnalytics|Average time to completion"
msgstr ""
msgid "CycleAnalytics|Date"
msgstr ""
-msgid "CycleAnalytics|Days to completion"
-msgstr ""
-
msgid "CycleAnalytics|Display chart filters"
msgstr ""
msgid "CycleAnalytics|Lead Time for Changes"
msgstr ""
-msgid "CycleAnalytics|No stages selected"
-msgstr ""
-
msgid "CycleAnalytics|Number of tasks"
msgstr ""
@@ -10837,18 +10926,30 @@ msgstr ""
msgid "CycleAnalytics|Showing data for group '%{groupName}' from %{createdAfter} to %{createdBefore}"
msgstr ""
-msgid "CycleAnalytics|Stages"
+msgid "CycleAnalytics|Stage time: %{title}"
msgstr ""
msgid "CycleAnalytics|Tasks by type"
msgstr ""
-msgid "CycleAnalytics|The average time spent in the selected stage for the items that were completed on each date. Data limited to the last 500 items."
+msgid "CycleAnalytics|The average time items spent in this stage. Data limited to items completed within this date range."
msgstr ""
msgid "CycleAnalytics|The given date range is larger than 180 days"
msgstr ""
+msgid "CycleAnalytics|The total time items spent across each value stream stage. Data limited to items completed within this date range."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Stage time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Total time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|Total time"
+msgstr ""
+
msgid "CycleAnalytics|Type of work"
msgstr ""
@@ -10861,9 +10962,6 @@ msgstr ""
msgid "CycleAnalytics|project dropdown filter"
msgstr ""
-msgid "CycleAnalytics|stage dropdown"
-msgstr ""
-
msgid "DAG visualization requires at least 3 dependent jobs."
msgstr ""
@@ -10963,10 +11061,16 @@ msgstr ""
msgid "DastProfiles|AJAX spider"
msgstr ""
+msgid "DastProfiles|API"
+msgstr ""
+
+msgid "DastProfiles|API endpoint URL"
+msgstr ""
+
msgid "DastProfiles|Active"
msgstr ""
-msgid "DastProfiles|Additional request headers (Optional)"
+msgid "DastProfiles|Additional request headers (optional)"
msgstr ""
msgid "DastProfiles|Are you sure you want to delete this profile?"
@@ -10981,6 +11085,9 @@ msgstr ""
msgid "DastProfiles|Branch missing"
msgstr ""
+msgid "DastProfiles|Choose a scan method"
+msgstr ""
+
msgid "DastProfiles|Could not create the scanner profile. Please try again."
msgstr ""
@@ -11050,7 +11157,13 @@ msgstr ""
msgid "DastProfiles|Excluded URLs"
msgstr ""
-msgid "DastProfiles|Excluded URLs (Optional)"
+msgid "DastProfiles|Excluded URLs (optional)"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths (optional)"
msgstr ""
msgid "DastProfiles|Hide debug messages"
@@ -11107,9 +11220,6 @@ msgstr ""
msgid "DastProfiles|Request headers"
msgstr ""
-msgid "DastProfiles|Rest API"
-msgstr ""
-
msgid "DastProfiles|Run the AJAX spider, in addition to the traditional spider, to crawl the target site."
msgstr ""
@@ -11119,6 +11229,9 @@ msgstr ""
msgid "DastProfiles|Save profile"
msgstr ""
+msgid "DastProfiles|Scan method"
+msgstr ""
+
msgid "DastProfiles|Scan mode"
msgstr ""
@@ -11197,12 +11310,24 @@ msgstr ""
msgid "DastProfiles|Website"
msgstr ""
+msgid "DastProfiles|What does each method do?"
+msgstr ""
+
msgid "DastProfiles|You can either choose a passive scan or validate the target site from the site profile management page. %{docsLinkStart}Learn more about site validation.%{docsLinkEnd}"
msgstr ""
msgid "DastProfiles|You cannot run an active scan against an unvalidated site."
msgstr ""
+msgid "DastProfiles|folder/dast_example.har or https://example.com/dast_example.har"
+msgstr ""
+
+msgid "DastProfiles|folder/example.postman_collection.json or https://example.com/"
+msgstr ""
+
+msgid "DastProfiles|folder/openapi.json or https://example.com/openapi.json"
+msgstr ""
+
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
@@ -11310,6 +11435,9 @@ msgstr ""
msgid "DatadogIntegration|API URL"
msgstr ""
+msgid "DatadogIntegration|Custom tags in Datadog. Enter one tag per line in the %{codeOpen}key:value%{codeClose} format. %{linkOpen}How do I use tags?%{linkClose}"
+msgstr ""
+
msgid "DatadogIntegration|Environment"
msgstr ""
@@ -11328,12 +11456,18 @@ msgstr ""
msgid "DatadogIntegration|Tag all data from this GitLab instance in Datadog. Useful when managing several self-managed deployments."
msgstr ""
+msgid "DatadogIntegration|Tags"
+msgstr ""
+
msgid "DatadogIntegration|The Datadog site to send data to. To send data to the EU site, use %{codeOpen}datadoghq.eu%{codeClose}."
msgstr ""
msgid "DatadogIntegration|Trace your GitLab pipelines with Datadog."
msgstr ""
+msgid "DatadogIntegration|have an invalid format"
+msgstr ""
+
msgid "Datasource name not found"
msgstr ""
@@ -11343,9 +11477,6 @@ msgstr ""
msgid "Date merged"
msgstr ""
-msgid "Date picker"
-msgstr ""
-
msgid "Date range"
msgstr ""
@@ -11499,9 +11630,6 @@ msgstr ""
msgid "Definition"
msgstr ""
-msgid "Delayed Project Deletion (%{adjourned_deletion})"
-msgstr ""
-
msgid "DelayedJobs|Are you sure you want to run %{jobName} immediately? Otherwise this job will run automatically after its timer finishes."
msgstr ""
@@ -11580,10 +11708,10 @@ msgstr ""
msgid "Delete pipeline"
msgstr ""
-msgid "Delete project"
+msgid "Delete pipeline schedule"
msgstr ""
-msgid "Delete project. Are you ABSOLUTELY SURE?"
+msgid "Delete project"
msgstr ""
msgid "Delete row"
@@ -11613,6 +11741,9 @@ msgstr ""
msgid "Delete this epic and all descendants?"
msgstr ""
+msgid "Delete this project"
+msgstr ""
+
msgid "Delete user list"
msgstr ""
@@ -11871,6 +12002,12 @@ msgstr ""
msgid "Deploy to..."
msgstr ""
+msgid "DeployBoards|To see deployment progress for your environments, make sure you are deploying to %{codeStart}$KUBE_NAMESPACE%{codeEnd} and annotating with %{codeStart}app.gitlab.com/app=$CI_PROJECT_PATH_SLUG%{codeEnd} and %{codeStart}app.gitlab.com/env=$CI_ENVIRONMENT_SLUG%{codeEnd}."
+msgstr ""
+
+msgid "DeployBoard|Kubernetes Pods"
+msgstr ""
+
msgid "DeployFreeze|Add a freeze period to prevent unintended releases during a period of time for a given environment. You must update the deployment jobs in %{filename} according to the deploy freezes added here. %{freeze_period_link_start}Learn more.%{freeze_period_link_end}"
msgstr ""
@@ -11955,9 +12092,6 @@ msgstr ""
msgid "DeployTokens|Active Deploy Tokens (%{active_tokens})"
msgstr ""
-msgid "DeployTokens|Allows read and write access to registry images."
-msgstr ""
-
msgid "DeployTokens|Allows read and write access to the package registry."
msgstr ""
@@ -11970,6 +12104,9 @@ msgstr ""
msgid "DeployTokens|Allows read-only access to the repository."
msgstr ""
+msgid "DeployTokens|Allows write access to registry images."
+msgstr ""
+
msgid "DeployTokens|Copy deploy token"
msgstr ""
@@ -12063,12 +12200,57 @@ msgstr ""
msgid "Deploying to AWS is easy with GitLab"
msgstr ""
+msgid "Deployment"
+msgstr ""
+
msgid "Deployment Frequency"
msgstr ""
+msgid "Deployment Target|Project deployment target (optional)"
+msgstr ""
+
+msgid "Deployment Target|Select the deployment target"
+msgstr ""
+
msgid "Deployment frequency"
msgstr ""
+msgid "DeploymentTarget|GitLab Pages"
+msgstr ""
+
+msgid "DeploymentTarget|Heroku"
+msgstr ""
+
+msgid "DeploymentTarget|Infrastructure provider (Terraform, Cloudformation, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Kubernetes (GKE, EKS, OpenShift, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Managed container runtime (Fargate, Cloud Run, DigitalOcean App)"
+msgstr ""
+
+msgid "DeploymentTarget|Mobile app store"
+msgstr ""
+
+msgid "DeploymentTarget|No deployment planned"
+msgstr ""
+
+msgid "DeploymentTarget|Other hosting service"
+msgstr ""
+
+msgid "DeploymentTarget|Registry (package or container)"
+msgstr ""
+
+msgid "DeploymentTarget|Self-managed container runtime (Podman, Docker Swarm, Docker Compose)"
+msgstr ""
+
+msgid "DeploymentTarget|Serverless backend (Lambda, Cloud functions)"
+msgstr ""
+
+msgid "DeploymentTarget|Virtual machine (for example, EC2)"
+msgstr ""
+
msgid "Deployments"
msgstr ""
@@ -12107,6 +12289,9 @@ msgstr ""
msgid "Deployment|This deployment was created using the API"
msgstr ""
+msgid "Deployment|Triggerer"
+msgstr ""
+
msgid "Deployment|Waiting"
msgstr ""
@@ -12134,6 +12319,18 @@ msgstr ""
msgid "Deprecated API rate limits"
msgstr ""
+msgid "Deprecations|Feature deprecation and removal"
+msgstr ""
+
+msgid "Deprecations|For information on a possible replacement %{epicStart} learn more about Opstrace %{epicEnd}."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7 and are %{epicStart} scheduled for removal %{epicEnd} in GitLab 15.0."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7, and are %{removal_link_start} scheduled for removal %{link_end} in GitLab 15.0. For information on a possible replacement, %{opstrace_link_start} learn more about Opstrace %{link_end}."
+msgstr ""
+
msgid "Deprioritize label"
msgstr ""
@@ -12379,10 +12576,10 @@ msgstr ""
msgid "DevopsAdoption|At least one deploy"
msgstr ""
-msgid "DevopsAdoption|At least one issue opened"
+msgid "DevopsAdoption|At least one issue created"
msgstr ""
-msgid "DevopsAdoption|At least one merge request opened"
+msgid "DevopsAdoption|At least one merge request created"
msgstr ""
msgid "DevopsAdoption|At least one pipeline successfully run"
@@ -12583,6 +12780,9 @@ msgstr ""
msgid "Direct member"
msgstr ""
+msgid "Direct members"
+msgstr ""
+
msgid "Direct non-authenticated users to this page."
msgstr ""
@@ -12699,6 +12899,9 @@ msgid_plural "Dismiss %d selected vulnerabilities as"
msgstr[0] ""
msgstr[1] ""
+msgid "Dismiss Alert"
+msgstr ""
+
msgid "Dismiss merge request promotion"
msgstr ""
@@ -12726,9 +12929,15 @@ msgstr ""
msgid "Display alerts from all configured monitoring tools."
msgstr ""
+msgid "Display milestones"
+msgstr ""
+
msgid "Display name"
msgstr ""
+msgid "Display progress of child issues"
+msgstr ""
+
msgid "Display rendered file"
msgstr ""
@@ -12834,6 +13043,9 @@ msgstr ""
msgid "Download image"
msgstr ""
+msgid "Download payload"
+msgstr ""
+
msgid "Download raw data (.csv)"
msgstr ""
@@ -13011,6 +13223,9 @@ msgstr ""
msgid "Edit in Web IDE"
msgstr ""
+msgid "Edit in pipeline editor"
+msgstr ""
+
msgid "Edit in single-file editor"
msgstr ""
@@ -13053,6 +13268,9 @@ msgstr ""
msgid "Edit your most recent comment in a thread (from an empty textarea)"
msgstr ""
+msgid "Edit, lint, and visualize your pipeline."
+msgstr ""
+
msgid "Edited"
msgstr ""
@@ -13494,6 +13712,9 @@ msgstr ""
msgid "Enforce two-factor authentication for all user sign-ins."
msgstr ""
+msgid "Enhance security by storing service account keys in secret managers - learn more about %{docLinkStart}secret management with GitLab%{docLinkEnd}"
+msgstr ""
+
msgid "Ensure connectivity is available from the GitLab server to the Prometheus server"
msgstr ""
@@ -13554,6 +13775,9 @@ 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 following to confirm:"
+msgstr ""
+
msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
@@ -14084,9 +14308,6 @@ 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 ""
@@ -14222,6 +14443,9 @@ msgstr ""
msgid "Errors:"
msgstr ""
+msgid "Escalate this incident"
+msgstr ""
+
msgid "Escalation Policies"
msgstr ""
@@ -14234,6 +14458,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy"
+msgstr ""
+
msgid "Escalation policy:"
msgstr ""
@@ -14485,6 +14712,9 @@ msgstr ""
msgid "Existing sign in methods may be removed"
msgstr ""
+msgid "Exit."
+msgstr ""
+
msgid "Expand"
msgstr ""
@@ -14581,6 +14811,9 @@ msgstr ""
msgid "Explore public groups"
msgstr ""
+msgid "Explore public projects"
+msgstr ""
+
msgid "Explore snippets"
msgstr ""
@@ -14742,7 +14975,7 @@ msgid_plural "Failed to archive designs. Please try again."
msgstr[0] ""
msgstr[1] ""
-msgid "Failed to assign a reviewer because no user was found."
+msgid "Failed to assign a reviewer because no user was specified."
msgstr ""
msgid "Failed to assign a user because no user was found."
@@ -14808,10 +15041,10 @@ msgstr ""
msgid "Failed to find import label for Jira import."
msgstr ""
-msgid "Failed to generate export, please try again later."
+msgid "Failed to find users for %{missing}"
msgstr ""
-msgid "Failed to generate report, please try again after sometime"
+msgid "Failed to generate export, please try again later."
msgstr ""
msgid "Failed to get ref."
@@ -14910,6 +15143,9 @@ msgstr ""
msgid "Failed to remove a to-do item for the design."
msgstr ""
+msgid "Failed to remove attention because no user was found."
+msgstr ""
+
msgid "Failed to remove mirror."
msgstr ""
@@ -14922,6 +15158,9 @@ msgstr ""
msgid "Failed to remove user key."
msgstr ""
+msgid "Failed to request attention because no user was found."
+msgstr ""
+
msgid "Failed to reset key. Please try again."
msgstr ""
@@ -15003,6 +15242,9 @@ msgstr ""
msgid "Feature Flags"
msgstr ""
+msgid "Feature deprecation and removal"
+msgstr ""
+
msgid "Feature flag status"
msgstr ""
@@ -15500,7 +15742,7 @@ msgstr ""
msgid "For each job, re-use the project workspace. If the workspace doesn't exist, use %{code_open}git clone%{code_close}."
msgstr ""
-msgid "For example, the application using the token or the purpose of the token."
+msgid "For example, the application using the token or the purpose of the token. Do not give sensitive information for the name of the token, as it will be visible to all %{resource_type} members."
msgstr ""
msgid "For files larger than this limit, only index the file name. The file content is neither indexed nor searchable."
@@ -15584,9 +15826,6 @@ msgstr ""
msgid "ForkProject|Select a namespace"
msgstr ""
-msgid "ForkProject|Select a namespace to fork the project"
-msgstr ""
-
msgid "ForkProject|The project can be accessed by any logged in user."
msgstr ""
@@ -15683,6 +15922,9 @@ msgstr ""
msgid "Full name"
msgstr ""
+msgid "GCP region configured"
+msgstr ""
+
msgid "GPG Key ID:"
msgstr ""
@@ -15863,6 +16105,9 @@ msgstr ""
msgid "Geo|Failed"
msgstr ""
+msgid "Geo|Filter Geo sites"
+msgstr ""
+
msgid "Geo|Filter by name"
msgstr ""
@@ -16274,6 +16519,12 @@ msgstr ""
msgid "GitLab Issue"
msgstr ""
+msgid "GitLab KAS"
+msgstr ""
+
+msgid "GitLab Memberships CSV Export"
+msgstr ""
+
msgid "GitLab Pages"
msgstr ""
@@ -16322,6 +16573,9 @@ 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 free to use. Many features for larger teams are part of our %{link_start}paid products%{link_end}. You can try Ultimate for free without any obligation or payment details."
+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 ""
@@ -16448,7 +16702,7 @@ msgstr ""
msgid "GitLabPages|When enabled, all attempts to visit your website through HTTP are automatically redirected to HTTPS using a response with status code 301. Requires a valid certificate for all domains. %{docs_link_start}Learn more.%{link_end}"
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. %{docs_link_start}Learn more.%{link_end}"
+msgid "GitLabPages|When using Pages under the general domain of a GitLab instance (%{pages_host}), you cannot use HTTPS with subdomains of subdomains. If your namespace or groupname contains a dot, it does not work. This is a limitation of the HTTP Over TLS protocol. HTTP pages work if you don't redirect HTTP to HTTPS. %{docs_link_start}Learn more.%{link_end}"
msgstr ""
msgid "GitLabPages|With GitLab Pages you can host your static website directly from your GitLab repository. %{docs_link_start}Learn more.%{link_end}"
@@ -16625,9 +16879,6 @@ msgstr ""
msgid "Go to find file"
msgstr ""
-msgid "Go to fork"
-msgstr ""
-
msgid "Go to issue boards"
msgstr ""
@@ -16835,9 +17086,6 @@ msgstr ""
msgid "Group Hooks"
msgstr ""
-msgid "Group ID"
-msgstr ""
-
msgid "Group Owner must have signed in with SAML before enabling Group Managed Accounts"
msgstr ""
@@ -16865,9 +17113,6 @@ msgstr ""
msgid "Group by"
msgstr ""
-msgid "Group description"
-msgstr ""
-
msgid "Group description (optional)"
msgstr ""
@@ -16982,7 +17227,7 @@ msgstr ""
msgid "Group: %{name}"
msgstr ""
-msgid "GroupActivityMetrics|Issues opened"
+msgid "GroupActivityMetrics|Issues created"
msgstr ""
msgid "GroupActivityMetrics|Last 90 days"
@@ -16991,7 +17236,7 @@ msgstr ""
msgid "GroupActivityMetrics|Members added"
msgstr ""
-msgid "GroupActivityMetrics|Merge Requests opened"
+msgid "GroupActivityMetrics|Merge Requests created"
msgstr ""
msgid "GroupActivityMetrics|Recent activity"
@@ -17282,6 +17527,9 @@ msgstr ""
msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
+msgid "GroupSettings|Choose a group path that does not start with a dash or end with a period. It can also contain alphanumeric characters and underscores."
+msgstr ""
+
msgid "GroupSettings|Compliance frameworks"
msgstr ""
@@ -17315,7 +17563,7 @@ msgstr ""
msgid "GroupSettings|If not specified at the group or instance level, the default is %{default_initial_branch_name}. Does not affect existing repositories."
msgstr ""
-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."
+msgid "GroupSettings|If the parent group's visibility is lower than the group's current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility."
msgstr ""
msgid "GroupSettings|New runners registration token has been generated!"
@@ -17432,7 +17680,10 @@ msgstr ""
msgid "Groups and projects"
msgstr ""
-msgid "Groups and subgroups"
+msgid "Groups are a great way to organize projects and people."
+msgstr ""
+
+msgid "Groups are the best way to manage projects and members."
msgstr ""
msgid "Groups to synchronize"
@@ -17543,13 +17794,16 @@ msgstr ""
msgid "GroupsTree|Are you sure you want to leave the \"%{fullName}\" group?"
msgstr ""
-msgid "GroupsTree|Edit group"
+msgid "GroupsTree|Delete"
+msgstr ""
+
+msgid "GroupsTree|Edit"
msgstr ""
msgid "GroupsTree|Failed to leave the group. Please make sure you are not the only owner."
msgstr ""
-msgid "GroupsTree|Leave this group"
+msgid "GroupsTree|Leave group"
msgstr ""
msgid "GroupsTree|Loading groups"
@@ -17561,9 +17815,57 @@ msgstr ""
msgid "GroupsTree|No groups or projects matched your search"
msgstr ""
+msgid "GroupsTree|Options"
+msgstr ""
+
msgid "GroupsTree|Search by name"
msgstr ""
+msgid "Groups|Avatar will be removed. Are you sure?"
+msgstr ""
+
+msgid "Groups|Changing group URL can have unintended side effects."
+msgstr ""
+
+msgid "Groups|Checking group URL availability..."
+msgstr ""
+
+msgid "Groups|Enter a descriptive name for your group."
+msgstr ""
+
+msgid "Groups|Group ID"
+msgstr ""
+
+msgid "Groups|Group URL"
+msgstr ""
+
+msgid "Groups|Group avatar"
+msgstr ""
+
+msgid "Groups|Group description (optional)"
+msgstr ""
+
+msgid "Groups|Group name"
+msgstr ""
+
+msgid "Groups|Group path is available."
+msgstr ""
+
+msgid "Groups|Group path is unavailable. Path has been replaced with a suggested available path."
+msgstr ""
+
+msgid "Groups|Learn more"
+msgstr ""
+
+msgid "Groups|Must start with letter, digit, emoji, or underscore. Can also contain periods, dashes, spaces, and parentheses."
+msgstr ""
+
+msgid "Groups|Remove avatar"
+msgstr ""
+
+msgid "Groups|Save changes"
+msgstr ""
+
msgid "Guideline"
msgstr ""
@@ -17573,6 +17875,9 @@ msgstr ""
msgid "HAR file path or URL"
msgstr ""
+msgid "HTTP Archive (HAR)"
+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 ""
@@ -17973,6 +18278,9 @@ msgstr ""
msgid "INFO: Your SSH key is expiring soon. Please generate a new key."
msgstr ""
+msgid "IP"
+msgstr ""
+
msgid "IP Address"
msgstr ""
@@ -18009,6 +18317,9 @@ msgstr ""
msgid "IdentityVerification|Verify your identity"
msgstr ""
+msgid "IdentityVerification|You can always verify your account at a later time to create a group."
+msgstr ""
+
msgid "If any indexed field exceeds this limit, it is truncated to this number of characters. The rest of the content is neither indexed nor searchable. This does not apply to repository and wiki indexing. For unlimited characters, set this to 0."
msgstr ""
@@ -18066,6 +18377,9 @@ msgstr ""
msgid "If you add %{codeStart}needs%{codeEnd} to jobs in your pipeline you'll be able to view the %{codeStart}needs%{codeEnd} relationships between jobs in this tab as a %{linkStart}Directed Acyclic Graph (DAG)%{linkEnd}."
msgstr ""
+msgid "If you are added to a project, it will be displayed here."
+msgstr ""
+
msgid "If you did not initiate these sign-in attempts, please reach out to your administrator or enable two-factor authentication (2FA) on your account."
msgstr ""
@@ -18372,12 +18686,24 @@ msgstr ""
msgid "InProductMarketing|3 ways to dive into GitLab CI/CD"
msgstr ""
+msgid "InProductMarketing|A single application eliminates complex integrations, data chokepoints, and toolchain maintenance, resulting in greater productivity and lower cost."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features, build more efficiently, strengthen security and compliance."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features."
+msgstr ""
+
msgid "InProductMarketing|Actually, GitLab makes the team work (better)"
msgstr ""
msgid "InProductMarketing|And finally %{deploy_link} a Python application."
msgstr ""
+msgid "InProductMarketing|And many more..."
+msgstr ""
+
msgid "InProductMarketing|Are your runners ready?"
msgstr ""
@@ -18396,15 +18722,33 @@ msgstr ""
msgid "InProductMarketing|Blog"
msgstr ""
+msgid "InProductMarketing|Break down silos to coordinate seamlessly across development, operations, and security with a consistent experience across the development lifecycle."
+msgstr ""
+
+msgid "InProductMarketing|Burn up/down charts"
+msgstr ""
+
msgid "InProductMarketing|By enabling code owners and required merge approvals the right person will review the right MR. This is a win-win: cleaner code and a more efficient review process."
msgstr ""
msgid "InProductMarketing|Click on the number below that corresponds with your answer — 1 being very difficult, 5 being very easy."
msgstr ""
+msgid "InProductMarketing|Code owners"
+msgstr ""
+
msgid "InProductMarketing|Code owners and required merge approvals are part of the paid tiers of GitLab. You can start a free 30-day trial of GitLab Ultimate and enable these features in less than 5 minutes with no credit card required."
msgstr ""
+msgid "InProductMarketing|Code review analytics"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration across stages in GitLab"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration made easy"
+msgstr ""
+
msgid "InProductMarketing|Create a custom CI runner with just a few clicks"
msgstr ""
@@ -18414,12 +18758,21 @@ msgstr ""
msgid "InProductMarketing|Create a project in GitLab in 5 minutes"
msgstr ""
+msgid "InProductMarketing|Create well-defined workflows by using scoped labels on issues, merge requests, and epics. Labels with the same scope cannot be used together, which prevents conflicts."
+msgstr ""
+
msgid "InProductMarketing|Create your first project!"
msgstr ""
+msgid "InProductMarketing|Define who owns specific files or directories, so the right reviewers are suggested when a merge request introduces changes to those files."
+msgstr ""
+
msgid "InProductMarketing|Deliver Better Products Faster"
msgstr ""
+msgid "InProductMarketing|Dependency scanning"
+msgstr ""
+
msgid "InProductMarketing|Did you know teams that use GitLab are far more efficient?"
msgstr ""
@@ -18429,15 +18782,27 @@ msgstr ""
msgid "InProductMarketing|Dig in and create a project and a repo"
msgstr ""
+msgid "InProductMarketing|Discover Premium & Ultimate"
+msgstr ""
+
+msgid "InProductMarketing|Discover Premium & Ultimate."
+msgstr ""
+
msgid "InProductMarketing|Do you have a minute?"
msgstr ""
msgid "InProductMarketing|Do you have a teammate who would be perfect for this task?"
msgstr ""
+msgid "InProductMarketing|Dynamic application security testing"
+msgstr ""
+
msgid "InProductMarketing|Easy"
msgstr ""
+msgid "InProductMarketing|Epics"
+msgstr ""
+
msgid "InProductMarketing|Expand your DevOps journey with a free GitLab trial"
msgstr ""
@@ -18459,9 +18824,15 @@ msgstr ""
msgid "InProductMarketing|Feel the need for speed?"
msgstr ""
+msgid "InProductMarketing|Find and fix bottlenecks in your code review process by understanding how long open merge requests have been in review."
+msgstr ""
+
msgid "InProductMarketing|Find out how your teams are really doing"
msgstr ""
+msgid "InProductMarketing|Find out if your external libraries are safe. Run dependency scanning jobs that check for known vulnerabilities in your external libraries."
+msgstr ""
+
msgid "InProductMarketing|Follow our steps"
msgstr ""
@@ -18498,6 +18869,9 @@ msgstr ""
msgid "InProductMarketing|GitLab is better with teammates to help out!"
msgstr ""
+msgid "InProductMarketing|GitLab is infrastructure agnostic (supporting GCP, AWS, Azure, OpenShift, VMWare, On Prem, Bare Metal, and more), offering a consistent workflow experience – irrespective of the environment."
+msgstr ""
+
msgid "InProductMarketing|GitLab provides static application security testing (SAST), dynamic application security testing (DAST), container scanning, and dependency scanning to help you deliver secure applications along with license compliance."
msgstr ""
@@ -18588,21 +18962,36 @@ msgstr ""
msgid "InProductMarketing|It's also possible to simply %{external_repo_link} in order to take advantage of GitLab's CI/CD."
msgstr ""
+msgid "InProductMarketing|Keep your code quality high by defining who should approve merge requests and how many approvals are required."
+msgstr ""
+
msgid "InProductMarketing|Launch GitLab CI/CD in 20 minutes or less"
msgstr ""
+msgid "InProductMarketing|Lower cost of development"
+msgstr ""
+
+msgid "InProductMarketing|Make it easier to collaborate on high-level ideas by grouping related issues in an epic."
+msgstr ""
+
msgid "InProductMarketing|Making the switch? It's easier than you think to import your projects into GitLab. Move %{github_link}, or import something %{bitbucket_link}."
msgstr ""
msgid "InProductMarketing|Master the art of importing!"
msgstr ""
+msgid "InProductMarketing|Merge request approval rule"
+msgstr ""
+
msgid "InProductMarketing|Move on to easily creating a Pages website %{ci_template_link}"
msgstr ""
msgid "InProductMarketing|Multiple owners, confusing workstreams? We've got you covered"
msgstr ""
+msgid "InProductMarketing|Multiple required approvers"
+msgstr ""
+
msgid "InProductMarketing|Need an alternative to importing?"
msgstr ""
@@ -18615,18 +19004,33 @@ msgstr ""
msgid "InProductMarketing|Our tool brings all the things together"
msgstr ""
+msgid "InProductMarketing|Protect your web application by using DAST to examine for vulnerabilities in deployed environments."
+msgstr ""
+
msgid "InProductMarketing|Rapid development, simplified"
msgstr ""
msgid "InProductMarketing|Reduce Security & Compliance Risk"
msgstr ""
+msgid "InProductMarketing|Require multiple approvers on a merge request, so you know it's in good shape before it's merged."
+msgstr ""
+
+msgid "InProductMarketing|Roadmaps"
+msgstr ""
+
+msgid "InProductMarketing|Scoped labels"
+msgstr ""
+
msgid "InProductMarketing|Security that's integrated into your development lifecycle"
msgstr ""
msgid "InProductMarketing|Sometimes you're not ready to make a full transition to a new tool. If you're not ready to fully commit, %{mirroring_link} gives you a safe way to try out GitLab in parallel with your current tool."
msgstr ""
+msgid "InProductMarketing|Speed. Efficiency. Trust."
+msgstr ""
+
msgid "InProductMarketing|Spin up an autoscaling runner in GitLab"
msgstr ""
@@ -18636,6 +19040,9 @@ msgstr ""
msgid "InProductMarketing|Start a Self-Managed trial"
msgstr ""
+msgid "InProductMarketing|Start a free trial"
+msgstr ""
+
msgid "InProductMarketing|Start a free trial of GitLab Ultimate – no credit card required"
msgstr ""
@@ -18702,6 +19109,9 @@ msgstr ""
msgid "InProductMarketing|To understand and get the most out of GitLab, start at the beginning and %{project_link}. In GitLab, repositories are part of a project, so after you've created your project you can go ahead and %{repo_link}."
msgstr ""
+msgid "InProductMarketing|Track completed issues in a chart, so you can see how a milestone is progressing at a glance."
+msgstr ""
+
msgid "InProductMarketing|Try GitLab Ultimate for free"
msgstr ""
@@ -18738,6 +19148,9 @@ msgstr ""
msgid "InProductMarketing|Very easy"
msgstr ""
+msgid "InProductMarketing|Visualize your epics and milestones in a timeline."
+msgstr ""
+
msgid "InProductMarketing|Want to host GitLab on your servers?"
msgstr ""
@@ -18759,6 +19172,9 @@ msgstr ""
msgid "InProductMarketing|YouTube"
msgstr ""
+msgid "InProductMarketing|Your software, deployed your way"
+msgstr ""
+
msgid "InProductMarketing|Your teams can be more efficient"
msgstr ""
@@ -18879,9 +19295,18 @@ msgstr ""
msgid "IncidentManagement|No incidents to display."
msgstr ""
+msgid "IncidentManagement|None"
+msgstr ""
+
msgid "IncidentManagement|Open"
msgstr ""
+msgid "IncidentManagement|Page your team with escalation policies"
+msgstr ""
+
+msgid "IncidentManagement|Paged"
+msgstr ""
+
msgid "IncidentManagement|Published"
msgstr ""
@@ -18891,6 +19316,9 @@ msgstr ""
msgid "IncidentManagement|Severity"
msgstr ""
+msgid "IncidentManagement|Status"
+msgstr ""
+
msgid "IncidentManagement|There are no closed incidents"
msgstr ""
@@ -18909,6 +19337,9 @@ msgstr ""
msgid "IncidentManagement|Unpublished"
msgstr ""
+msgid "IncidentManagement|Use escalation policies to automatically page your team when incidents are created."
+msgstr ""
+
msgid "IncidentSettings|Activate \"time to SLA\" countdown timer"
msgstr ""
@@ -18954,7 +19385,10 @@ msgstr ""
msgid "Incidents"
msgstr ""
-msgid "Incidents|Add a URL"
+msgid "Incidents|Add image details"
+msgstr ""
+
+msgid "Incidents|Add text or a link to display with your image. If you don't add either, the file name displays instead."
msgstr ""
msgid "Incidents|Drop or %{linkStart}upload%{linkEnd} a metric screenshot to attach it to the incident"
@@ -18969,10 +19403,10 @@ msgstr ""
msgid "Incidents|There was an issue loading metric images."
msgstr ""
-msgid "Incidents|There was an issue uploading your image."
+msgid "Incidents|There was an issue updating your image."
msgstr ""
-msgid "Incidents|You can optionally add a URL to link users to the original graph."
+msgid "Incidents|There was an issue uploading your image."
msgstr ""
msgid "Incident|Alert details"
@@ -18981,9 +19415,18 @@ msgstr ""
msgid "Incident|Are you sure you wish to delete this image?"
msgstr ""
+msgid "Incident|Delete image"
+msgstr ""
+
msgid "Incident|Deleting %{filename}"
msgstr ""
+msgid "Incident|Edit image text or link"
+msgstr ""
+
+msgid "Incident|Editing %{filename}"
+msgstr ""
+
msgid "Incident|Metrics"
msgstr ""
@@ -19253,12 +19696,18 @@ msgstr ""
msgid "Integrations|Branches for which notifications are to be sent"
msgstr ""
+msgid "Integrations|Clear if using a self-signed certificate."
+msgstr ""
+
msgid "Integrations|Comment detail:"
msgstr ""
msgid "Integrations|Comment settings:"
msgstr ""
+msgid "Integrations|Connection details"
+msgstr ""
+
msgid "Integrations|Connection failed. Please check your settings."
msgstr ""
@@ -19283,6 +19732,9 @@ msgstr ""
msgid "Integrations|Enable GitLab.com slash commands in a Slack workspace."
msgstr ""
+msgid "Integrations|Enable SSL verification"
+msgstr ""
+
msgid "Integrations|Enable comments"
msgstr ""
@@ -19361,6 +19813,9 @@ msgstr ""
msgid "Integrations|Return to GitLab for Jira"
msgstr ""
+msgid "Integrations|SSL verification"
+msgstr ""
+
msgid "Integrations|Save settings?"
msgstr ""
@@ -19406,9 +19861,6 @@ msgstr ""
msgid "Integrations|Use default settings"
msgstr ""
-msgid "Integrations|When you mention a Jira issue in a commit or merge request, GitLab creates a remote link and comment (if enabled)."
-msgstr ""
-
msgid "Integrations|You can now close this window and return to the GitLab for Jira application."
msgstr ""
@@ -19433,9 +19885,6 @@ msgstr ""
msgid "Integrations|can't exceed %{recipients_limit}"
msgstr ""
-msgid "Interactive developer security education."
-msgstr ""
-
msgid "Interactive mode"
msgstr ""
@@ -19925,6 +20374,9 @@ msgstr ""
msgid "IssueAnalytics|Assignees"
msgstr ""
+msgid "IssueAnalytics|Created by"
+msgstr ""
+
msgid "IssueAnalytics|Due date"
msgstr ""
@@ -19937,9 +20389,6 @@ msgstr ""
msgid "IssueAnalytics|Milestone"
msgstr ""
-msgid "IssueAnalytics|Opened by"
-msgstr ""
-
msgid "IssueAnalytics|Status"
msgstr ""
@@ -20063,10 +20512,10 @@ msgstr ""
msgid "IssuesAnalytics|Avg/Month:"
msgstr ""
-msgid "IssuesAnalytics|Issues opened"
+msgid "IssuesAnalytics|Issues created"
msgstr ""
-msgid "IssuesAnalytics|Issues opened per month"
+msgid "IssuesAnalytics|Issues created per month"
msgstr ""
msgid "IssuesAnalytics|Last 12 months"
@@ -20093,6 +20542,9 @@ msgstr ""
msgid "It looks like you have some draft commits in this branch."
msgstr ""
+msgid "It looks like you're attempting to activate your subscription. Use %{a_start}the Subscription page%{a_end} instead."
+msgstr ""
+
msgid "It may be several days before you see feature usage data."
msgstr ""
@@ -20321,6 +20773,9 @@ msgstr ""
msgid "JiraConnect|You can now close this window and return to Jira."
msgstr ""
+msgid "JiraConnect|You don't have permission to create branches for this project. Select a different project or contact the project owner for access. %{linkStart}Learn more.%{linkEnd}"
+msgstr ""
+
msgid "JiraRequest|A connection error occurred while connecting to Jira. Try your request again."
msgstr ""
@@ -20369,13 +20824,13 @@ msgstr ""
msgid "JiraService|Define the type of Jira issue to create from a vulnerability."
msgstr ""
-msgid "JiraService|Displaying Jira issues while leaving the GitLab issue functionality enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
+msgid "JiraService|Displaying Jira issues while leaving GitLab issues also enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
msgstr ""
-msgid "JiraService|Enable Jira issues"
+msgid "JiraService|Enable Jira issue creation from vulnerabilities"
msgstr ""
-msgid "JiraService|Enable Jira issues creation from vulnerabilities"
+msgid "JiraService|Enable Jira issues"
msgstr ""
msgid "JiraService|Enable Jira transitions"
@@ -20492,16 +20947,19 @@ msgstr ""
msgid "JiraService|View Jira issues in GitLab"
msgstr ""
-msgid "JiraService|Warning: All GitLab users that have access to this GitLab project are able to view all issues from the Jira project specified below."
+msgid "JiraService|Warning: All GitLab users with access to this GitLab project can view all issues from the Jira project you select."
msgstr ""
msgid "JiraService|Web URL"
msgstr ""
-msgid "JiraService|Work on Jira issues without leaving GitLab. Adds a Jira menu to access your list of Jira issues and view any issue as read-only."
+msgid "JiraService|When a Jira issue is mentioned in a commit or merge request, a remote link and comment (if enabled) will be created."
+msgstr ""
+
+msgid "JiraService|Work on Jira issues without leaving GitLab. Add a Jira menu to access a read-only list of your Jira issues."
msgstr ""
-msgid "JiraService|You need to configure Jira before enabling this integration. For more details, read the %{jira_doc_link_start}Jira integration documentation%{link_end}."
+msgid "JiraService|You must configure Jira before enabling this integration. %{jira_doc_link_start}Learn more.%{link_end}"
msgstr ""
msgid "Job"
@@ -20513,9 +20971,6 @@ msgstr ""
msgid "Job Failed #%{build_id}"
msgstr ""
-msgid "Job ID"
-msgstr ""
-
msgid "Job artifact"
msgstr ""
@@ -20582,9 +21037,27 @@ msgstr ""
msgid "Jobs|You're about to retry a job that failed because it attempted to deploy code that is older than the latest deployment. Retrying this job could result in overwriting the environment with the older source code."
msgstr ""
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source} into %{target}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{ref}"
+msgstr ""
+
+msgid "Job|Are you sure you want to erase this job log and artifacts?"
+msgstr ""
+
msgid "Job|Browse"
msgstr ""
+msgid "Job|Cancel"
+msgstr ""
+
msgid "Job|Complete Raw"
msgstr ""
@@ -20594,6 +21067,9 @@ msgstr ""
msgid "Job|Erase job log and artifacts"
msgstr ""
+msgid "Job|Finished at"
+msgstr ""
+
msgid "Job|Job artifacts"
msgstr ""
@@ -20606,7 +21082,7 @@ msgstr ""
msgid "Job|Keep"
msgstr ""
-msgid "Job|Pipeline"
+msgid "Job|Retry"
msgstr ""
msgid "Job|Scroll to bottom"
@@ -20618,6 +21094,9 @@ msgstr ""
msgid "Job|Show complete raw"
msgstr ""
+msgid "Job|Status"
+msgstr ""
+
msgid "Job|The artifacts were removed"
msgstr ""
@@ -20645,21 +21124,12 @@ msgstr ""
msgid "Job|delayed"
msgstr ""
-msgid "Job|for"
-msgstr ""
-
-msgid "Job|into"
-msgstr ""
-
msgid "Job|manual"
msgstr ""
msgid "Job|triggered"
msgstr ""
-msgid "Job|with"
-msgstr ""
-
msgid "Join Zoom meeting"
msgstr ""
@@ -20762,9 +21232,6 @@ msgstr ""
msgid "Ki"
msgstr ""
-msgid "Kontra"
-msgstr ""
-
msgid "Kroki"
msgstr ""
@@ -21088,6 +21555,9 @@ msgstr ""
msgid "Learn more about Auto DevOps"
msgstr ""
+msgid "Learn more about GitLab"
+msgstr ""
+
msgid "Learn more about Needs relationships"
msgstr ""
@@ -21415,9 +21885,18 @@ msgstr ""
msgid "Licenses|Displays licenses detected in the project, based on the %{linkStart}latest successful%{linkEnd} scan"
msgstr ""
+msgid "Licenses|Drag your license file here or %{linkStart}click to upload%{linkEnd}."
+msgstr ""
+
+msgid "Licenses|Drop your license file to start the upload."
+msgstr ""
+
msgid "Licenses|Error fetching the license list. Please check your network connection and try again."
msgstr ""
+msgid "Licenses|Error: You are trying to upload something other than a file"
+msgstr ""
+
msgid "Licenses|License Compliance"
msgstr ""
@@ -21436,6 +21915,9 @@ msgstr ""
msgid "Licenses|Specified policies in this project"
msgstr ""
+msgid "Licenses|The file could not be uploaded."
+msgstr ""
+
msgid "Licenses|The license list details information about the licenses used within your project."
msgstr ""
@@ -21469,11 +21951,6 @@ msgstr ""
msgid "Limit the size of Sidekiq jobs stored in Redis."
msgstr ""
-msgid "Limited to showing %d event at most"
-msgid_plural "Limited to showing %d events at most"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Limiting mode"
msgstr ""
@@ -21483,6 +21960,9 @@ msgstr ""
msgid "Link"
msgstr ""
+msgid "Link (optional)"
+msgstr ""
+
msgid "Link Prometheus monitoring to GitLab."
msgstr ""
@@ -21519,6 +21999,9 @@ msgstr ""
msgid "Linked emails (%{email_count})"
msgstr ""
+msgid "Linked epics"
+msgstr ""
+
msgid "Linked issues"
msgstr ""
@@ -21546,6 +22029,15 @@ msgstr ""
msgid "List of all merge commits"
msgstr ""
+msgid "List of environments for this project"
+msgstr ""
+
+msgid "List of suitable GCP locations"
+msgstr ""
+
+msgid "List of users allowed to exceed the rate limit."
+msgstr ""
+
msgid "List options"
msgstr ""
@@ -21765,6 +22257,9 @@ msgstr ""
msgid "Maintenance mode"
msgstr ""
+msgid "Make adjustments to how your GitLab instance is set up."
+msgstr ""
+
msgid "Make and review changes in the browser with the Web IDE"
msgstr ""
@@ -21909,6 +22404,12 @@ msgstr ""
msgid "MarkdownEditor|Add italic text (%{modifier_key}I)"
msgstr ""
+msgid "MarkdownEditor|Add strikethrough text (%{modifierKey}⇧X)"
+msgstr ""
+
+msgid "MarkdownEditor|Add strikethrough text (%{modifier_key}⇧X)"
+msgstr ""
+
msgid "Marked For Deletion At - %{deletion_time}"
msgstr ""
@@ -22170,6 +22671,9 @@ msgstr ""
msgid "Maximum push size (MB)"
msgstr ""
+msgid "Maximum requests per 10 minutes per user"
+msgstr ""
+
msgid "Maximum requests per minute"
msgstr ""
@@ -22260,6 +22764,19 @@ msgstr ""
msgid "Members of a group may only view projects they have permission to access"
msgstr ""
+msgid "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seat in use and will be billed for the overage."
+msgid_plural "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seats in use and will be billed for the overage."
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "MembersOverage|You are about to incur additional charges"
+msgstr ""
+
+msgid "MembersOverage|Your subscription includes %d seat."
+msgid_plural "MembersOverage|Your subscription includes %d seats."
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Membership"
msgstr ""
@@ -22464,9 +22981,6 @@ msgstr ""
msgid "Merge request not merged"
msgstr ""
-msgid "Merge request pipelines 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 merge request pipelines."
-msgstr ""
-
msgid "Merge request reports"
msgstr ""
@@ -22563,13 +23077,13 @@ msgstr ""
msgid "MergeRequests|Create issue to resolve thread"
msgstr ""
-msgid "MergeRequests|Failed to squash. Should be done manually."
+msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Saving the comment failed"
+msgid "MergeRequests|Squashing failed: Squash the commits locally, resolve any conflicts, then push the branch."
msgstr ""
-msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
+msgid "MergeRequests|Squashing not allowed: This project doesn't allow you to squash commits when merging."
msgstr ""
msgid "MergeRequests|Thread stays resolved"
@@ -23410,6 +23924,18 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "MrList|Assigned to %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from assignee %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from reviewer %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Review requested from %{name}, go to their profile."
+msgstr ""
+
msgid "Multi-project"
msgstr ""
@@ -23443,7 +23969,7 @@ msgstr ""
msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "My Awesome Group"
+msgid "My awesome group"
msgstr ""
msgid "My company or team"
@@ -24065,9 +24591,6 @@ msgstr ""
msgid "No available branches"
msgstr ""
-msgid "No available groups to fork the project."
-msgstr ""
-
msgid "No branches found"
msgstr ""
@@ -24278,6 +24801,9 @@ msgstr ""
msgid "No ref selected"
msgstr ""
+msgid "No regions configured"
+msgstr ""
+
msgid "No related merge requests found."
msgstr ""
@@ -25082,6 +25608,9 @@ msgstr ""
msgid "Only reCAPTCHA v2 is supported:"
msgstr ""
+msgid "Only required if not using role instance credentials."
+msgstr ""
+
msgid "Only use lowercase letters, numbers, and underscores."
msgstr ""
@@ -25106,9 +25635,6 @@ msgstr ""
msgid "Open a CLI and connect to the cluster you want to install the agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
-msgid "Open epics"
-msgstr ""
-
msgid "Open errors"
msgstr ""
@@ -25148,7 +25674,7 @@ msgstr ""
msgid "Opened issues"
msgstr ""
-msgid "OpenedNDaysAgo|Opened"
+msgid "OpenedNDaysAgo|Created"
msgstr ""
msgid "Opens in a new window"
@@ -25193,9 +25719,6 @@ msgstr ""
msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
-msgid "Optional."
-msgstr ""
-
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
msgstr ""
@@ -25984,6 +26507,9 @@ msgstr ""
msgid "PerformanceBar|Memory"
msgstr ""
+msgid "PerformanceBar|Memory report"
+msgstr ""
+
msgid "PerformanceBar|Redis calls"
msgstr ""
@@ -26017,18 +26543,12 @@ msgstr ""
msgid "PerformanceBar|wall"
msgstr ""
-msgid "Performs a rebase but skips triggering a new pipeline"
-msgstr ""
-
msgid "Period in seconds"
msgstr ""
msgid "Permalink"
msgstr ""
-msgid "Permanently delete project"
-msgstr ""
-
msgid "Permanently remove group"
msgstr ""
@@ -26299,6 +26819,51 @@ msgstr ""
msgid "PipelineStatusTooltip|Pipeline: %{ci_status}"
msgstr ""
+msgid "PipelineWizardDefaultCommitMessage|Add %{filename}"
+msgstr ""
+
+msgid "PipelineWizardDefaultCommitMessage|Update %{filename}"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|At least one entry is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This field is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This value is not valid"
+msgstr ""
+
+msgid "PipelineWizardListWidget|add another step"
+msgstr ""
+
+msgid "PipelineWizardListWidget|remove step"
+msgstr ""
+
+msgid "PipelineWizard|Commit"
+msgstr ""
+
+msgid "PipelineWizard|Commit Message"
+msgstr ""
+
+msgid "PipelineWizard|Commit changes to your file"
+msgstr ""
+
+msgid "PipelineWizard|Commit file to Branch"
+msgstr ""
+
+msgid "PipelineWizard|Commit your new file"
+msgstr ""
+
+msgid "PipelineWizard|The file has been committed."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem committing the changes."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem while checking whether your file already exists in the specified branch."
+msgstr ""
+
msgid "Pipelines"
msgstr ""
@@ -26413,7 +26978,7 @@ msgstr ""
msgid "Pipelines|Project cache successfully reset."
msgstr ""
-msgid "Pipelines|Revoke"
+msgid "Pipelines|Revoke trigger"
msgstr ""
msgid "Pipelines|Something went wrong while cleaning runners cache."
@@ -26458,6 +27023,12 @@ msgstr ""
msgid "Pipelines|This is a child pipeline within the parent pipeline"
msgstr ""
+msgid "Pipelines|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipelines|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipelines|This pipeline will run code originating from a forked project merge request. This means that the code can potentially have security considerations like exposing CI variables."
msgstr ""
@@ -26500,9 +27071,6 @@ msgstr ""
msgid "Pipelines|Your changes have been successfully committed. Now redirecting to the new merge request page."
msgstr ""
-msgid "Pipelines|detached"
-msgstr ""
-
msgid "Pipelines|error"
msgstr ""
@@ -26512,10 +27080,13 @@ msgstr ""
msgid "Pipelines|latest"
msgstr ""
-msgid "Pipelines|stuck"
+msgid "Pipelines|merge request"
msgstr ""
-msgid "Pipelines|train"
+msgid "Pipelines|merge train"
+msgstr ""
+
+msgid "Pipelines|stuck"
msgstr ""
msgid "Pipelines|yaml invalid"
@@ -26647,6 +27218,12 @@ msgstr ""
msgid "Pipeline|This change will not change the overall test coverage if merged."
msgstr ""
+msgid "Pipeline|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipeline|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipeline|Trigger author"
msgstr ""
@@ -26671,6 +27248,12 @@ msgstr ""
msgid "Pipeline|for"
msgstr ""
+msgid "Pipeline|merge request"
+msgstr ""
+
+msgid "Pipeline|merge train"
+msgstr ""
+
msgid "Pipeline|on"
msgstr ""
@@ -26809,9 +27392,6 @@ msgstr ""
msgid "Please enter a valid time interval"
msgstr ""
-msgid "Please enter or upload a valid license."
-msgstr ""
-
msgid "Please enter your current password."
msgstr ""
@@ -26920,9 +27500,6 @@ msgstr ""
msgid "Please type %{phrase_code} to proceed or close this modal to cancel."
msgstr ""
-msgid "Please type the following to confirm:"
-msgstr ""
-
msgid "Please use this form to report to the admin users who create spam issues, comments or behave inappropriately."
msgstr ""
@@ -26950,12 +27527,27 @@ msgstr ""
msgid "Policies"
msgstr ""
+msgid "Policy '%{escalation_policy_name}' does not exist."
+msgstr ""
+
msgid "Policy management project does have any policies in %{policy_path}"
msgstr ""
msgid "Policy project doesn't exist"
msgstr ""
+msgid "PolicyRuleMultiSelect|%{firstLabel} +%{numberOfAdditionalLabels} more"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|All %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select all"
+msgstr ""
+
msgid "Polling interval multiplier"
msgstr ""
@@ -27184,6 +27776,9 @@ msgstr ""
msgid "Private projects can be created in your personal namespace with:"
msgstr ""
+msgid "Problem with %{name} command: %{message}."
+msgstr ""
+
msgid "Proceed"
msgstr ""
@@ -27658,6 +28253,9 @@ msgstr ""
msgid "Progress"
msgstr ""
+msgid "Progress tracking"
+msgstr ""
+
msgid "Project"
msgstr ""
@@ -27889,6 +28487,9 @@ msgstr ""
msgid "ProjectQualitySummary|Failure"
msgstr ""
+msgid "ProjectQualitySummary|Get insight into the overall percentage of tests in your project that succeed, fail and are skipped."
+msgstr ""
+
msgid "ProjectQualitySummary|Latest pipeline results"
msgstr ""
@@ -27907,6 +28508,12 @@ msgstr ""
msgid "ProjectQualitySummary|See project Code Coverage Statistics"
msgstr ""
+msgid "ProjectQualitySummary|Set up test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|Set up test runs (opens in a new tab)"
+msgstr ""
+
msgid "ProjectQualitySummary|Skipped"
msgstr ""
@@ -28183,13 +28790,19 @@ msgstr ""
msgid "ProjectSettings|LFS objects from this repository are available to forks. %{linkStart}How do I remove them?%{linkEnd}"
msgstr ""
+msgid "ProjectSettings|Learn about commit history."
+msgstr ""
+
+msgid "ProjectSettings|Leave empty to use default template."
+msgstr ""
+
msgid "ProjectSettings|Manage who can see the project in the public access directory."
msgstr ""
msgid "ProjectSettings|Manages large files such as audio, video, and graphics files."
msgstr ""
-msgid "ProjectSettings|Maximum 500 characters."
+msgid "ProjectSettings|Maximum %{maxLength} characters."
msgstr ""
msgid "ProjectSettings|Merge checks"
@@ -28330,6 +28943,9 @@ msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
msgstr ""
+msgid "ProjectSettings|The default template will be applied on save."
+msgstr ""
+
msgid "ProjectSettings|These checks must pass before merge requests can be merged."
msgstr ""
@@ -28384,6 +29000,9 @@ msgstr ""
msgid "ProjectSettings|What are badges?"
msgstr ""
+msgid "ProjectSettings|What are merge trains?"
+msgstr ""
+
msgid "ProjectSettings|When merge request pipelines are enabled in the CI/CD configuration file, pipelines validate the combined results of the source and target branches. %{link_start}How to configure merge request pipelines?%{link_end}"
msgstr ""
@@ -28501,6 +29120,9 @@ msgstr ""
msgid "Projects are organized into groups"
msgstr ""
+msgid "Projects are where you store your code, access issues, wiki and other features of GitLab."
+msgstr ""
+
msgid "Projects contributed to"
msgstr ""
@@ -28516,12 +29138,6 @@ msgstr ""
msgid "Projects to index"
msgstr ""
-msgid "Projects will be permanently deleted after a %{waiting_period}-day waiting period."
-msgstr ""
-
-msgid "Projects will be permanently deleted immediately."
-msgstr ""
-
msgid "Projects with critical vulnerabilities"
msgstr ""
@@ -28606,6 +29222,9 @@ msgstr ""
msgid "ProjectsNew|Import project"
msgstr ""
+msgid "ProjectsNew|Include a Getting Started README"
+msgstr ""
+
msgid "ProjectsNew|Initialize repository with a README"
msgstr ""
@@ -28621,6 +29240,9 @@ msgstr ""
msgid "ProjectsNew|Project description %{tag_start}(optional)%{tag_end}"
msgstr ""
+msgid "ProjectsNew|Recommended if you're new to GitLab"
+msgstr ""
+
msgid "ProjectsNew|Run CI/CD for external repository"
msgstr ""
@@ -29038,6 +29660,9 @@ msgstr ""
msgid "ProtectedBranch|Unprotect"
msgstr ""
+msgid "ProtectedBranch|Unprotect branch"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
@@ -29065,6 +29690,9 @@ msgstr ""
msgid "ProtectedEnvironment|Protected Environment (%{protected_environments_count})"
msgstr ""
+msgid "ProtectedEnvironment|Required approvals"
+msgstr ""
+
msgid "ProtectedEnvironment|Select an environment"
msgstr ""
@@ -29086,10 +29714,13 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|Unprotect tag"
+msgstr ""
+
msgid "ProtectedTags|default"
msgstr ""
-msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
+msgid "ProtectedTag|By default, protected tags restrict who can modify the tag."
msgstr ""
msgid "ProtectedTag|Learn more."
@@ -29152,6 +29783,9 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Public projects are an easy way to allow everyone to have read-only access."
+msgstr ""
+
msgid "Publish to status page"
msgstr ""
@@ -29308,9 +29942,6 @@ msgstr ""
msgid "QualitySummary|Project quality"
msgstr ""
-msgid "Quarters"
-msgstr ""
-
msgid "Query"
msgstr ""
@@ -29395,6 +30026,9 @@ msgstr ""
msgid "Read more about project permissions %{help_link_open}here%{help_link_close}"
msgstr ""
+msgid "Read more about related epics"
+msgstr ""
+
msgid "Read more about related issues"
msgstr ""
@@ -29425,10 +30059,7 @@ msgstr ""
msgid "Rebase source branch on the target branch."
msgstr ""
-msgid "Rebase without CI"
-msgstr ""
-
-msgid "Rebases and triggers a pipeline"
+msgid "Rebase without pipeline"
msgstr ""
msgid "Recaptcha verified?"
@@ -29479,9 +30110,6 @@ msgstr ""
msgid "Reconfigure"
msgstr ""
-msgid "Recovering projects"
-msgstr ""
-
msgid "Recovery Codes"
msgstr ""
@@ -29541,6 +30169,12 @@ msgstr ""
msgid "Regex pattern"
msgstr ""
+msgid "Region"
+msgstr ""
+
+msgid "Regions"
+msgstr ""
+
msgid "Register"
msgstr ""
@@ -29771,9 +30405,6 @@ msgstr ""
msgid "Remove all or specific reviewer(s)"
msgstr ""
-msgid "Remove approver"
-msgstr ""
-
msgid "Remove approvers"
msgstr ""
@@ -29789,6 +30420,9 @@ msgstr ""
msgid "Remove attention request"
msgstr ""
+msgid "Remove attention request(s)"
+msgstr ""
+
msgid "Remove avatar"
msgstr ""
@@ -29927,6 +30561,9 @@ msgstr ""
msgid "Removed an issue from an epic."
msgstr ""
+msgid "Removed attention from %{users_sentence}."
+msgstr ""
+
msgid "Removed attention request from @%{username}"
msgstr ""
@@ -29978,6 +30615,9 @@ msgstr ""
msgid "Removes an issue from an epic."
msgstr ""
+msgid "Removes attention from %{users_sentence}."
+msgstr ""
+
msgid "Removes parent epic %{epic_ref}."
msgstr ""
@@ -30089,6 +30729,9 @@ msgstr ""
msgid "Report abuse to admin"
msgstr ""
+msgid "Report is generating and will be sent to your email address."
+msgstr ""
+
msgid "Reported %{timeAgo} by %{reportedBy}"
msgstr ""
@@ -30378,6 +31021,15 @@ msgstr ""
msgid "Request attention"
msgstr ""
+msgid "Request attention from %{users_sentence}."
+msgstr ""
+
+msgid "Request attention from assignee or reviewer"
+msgstr ""
+
+msgid "Request attention from assignee(s) or reviewer(s)"
+msgstr ""
+
msgid "Request attention to review"
msgstr ""
@@ -30402,6 +31054,9 @@ msgstr ""
msgid "Requested %{time_ago}"
msgstr ""
+msgid "Requested attention from %{users_sentence}."
+msgstr ""
+
msgid "Requested attention from @%{username}"
msgstr ""
@@ -30616,6 +31271,9 @@ msgstr ""
msgid "Restore project"
msgstr ""
+msgid "Restoring projects"
+msgstr ""
+
msgid "Restoring the group will prevent the group, its subgroups and projects from being removed on this date."
msgstr ""
@@ -30646,6 +31304,9 @@ msgstr ""
msgid "Retry"
msgstr ""
+msgid "Retry failed jobs"
+msgstr ""
+
msgid "Retry job"
msgstr ""
@@ -30693,9 +31354,6 @@ msgstr ""
msgid "Review changes"
msgstr ""
-msgid "Review requested from %{name}"
-msgstr ""
-
msgid "Review requests for you"
msgstr ""
@@ -30860,6 +31518,9 @@ msgstr ""
msgid "Runners|Assigned Group"
msgstr ""
+msgid "Runners|Assigned Projects (%{projectCount})"
+msgstr ""
+
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30929,6 +31590,9 @@ msgstr ""
msgid "Runners|Instance"
msgstr ""
+msgid "Runners|Jobs"
+msgstr ""
+
msgid "Runners|Last contact"
msgstr ""
@@ -31022,9 +31686,6 @@ msgstr ""
msgid "Runners|Runner %{name} was deleted"
msgstr ""
-msgid "Runners|Runner ID"
-msgstr ""
-
msgid "Runners|Runner assigned to project."
msgstr ""
@@ -31172,6 +31833,9 @@ msgstr ""
msgid "Runners|stale"
msgstr ""
+msgid "Runner|This runner has not run any jobs."
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -31286,6 +31950,24 @@ msgstr ""
msgid "Saving project."
msgstr ""
+msgid "ScanResultPolicy|%{ifLabelStart}if%{ifLabelEnd} %{scanners} scan in an open merge request targeting the %{branches} branch(es) finds %{vulnerabilitiesAllowed} or more %{severities} vulnerabilities that are %{vulnerabilityStates}"
+msgstr ""
+
+msgid "ScanResultPolicy|%{thenLabelStart}Then%{thenLabelEnd} Require approval from %{approvalsRequired} of the following approvers: %{approvers}"
+msgstr ""
+
+msgid "ScanResultPolicy|add an approver"
+msgstr ""
+
+msgid "ScanResultPolicy|scanners"
+msgstr ""
+
+msgid "ScanResultPolicy|severity levels"
+msgstr ""
+
+msgid "ScanResultPolicy|vulnerability states"
+msgstr ""
+
msgid "Scanner"
msgstr ""
@@ -31418,6 +32100,9 @@ msgstr ""
msgid "Search for a user"
msgstr ""
+msgid "Search for an emoji"
+msgstr ""
+
msgid "Search for projects, issues, etc."
msgstr ""
@@ -31605,18 +32290,12 @@ msgstr ""
msgid "Secret Detection"
msgstr ""
-msgid "Secret access key"
-msgstr ""
-
msgid "Secret token"
msgstr ""
msgid "Secure token that identifies an external storage request."
msgstr ""
-msgid "SecureCodeWarrior"
-msgstr ""
-
msgid "Security"
msgstr ""
@@ -31641,9 +32320,6 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "Security training with guide and learning pathways."
-msgstr ""
-
msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
@@ -31746,7 +32422,7 @@ msgstr ""
msgid "SecurityConfiguration|Manage corpus"
msgstr ""
-msgid "SecurityConfiguration|Manage corpus files used as mutation sources in coverage fuzzing."
+msgid "SecurityConfiguration|Manage corpus files used as seed inputs with coverage-guided fuzzing."
msgstr ""
msgid "SecurityConfiguration|Manage profiles for use by DAST scans."
@@ -31812,15 +32488,15 @@ msgstr ""
msgid "SecurityOrchestration|.yaml preview"
msgstr ""
-msgid "SecurityOrchestration|Action"
-msgstr ""
-
msgid "SecurityOrchestration|Actions"
msgstr ""
msgid "SecurityOrchestration|Add rule"
msgstr ""
+msgid "SecurityOrchestration|After dismissing the alert, the information will never be shown again."
+msgstr ""
+
msgid "SecurityOrchestration|All policies"
msgstr ""
@@ -31836,7 +32512,7 @@ msgstr ""
msgid "SecurityOrchestration|Description"
msgstr ""
-msgid "SecurityOrchestration|Disabled"
+msgid "SecurityOrchestration|Don't show the alert anymore"
msgstr ""
msgid "SecurityOrchestration|Edit policy"
@@ -31845,13 +32521,13 @@ msgstr ""
msgid "SecurityOrchestration|Edit policy project"
msgstr ""
-msgid "SecurityOrchestration|Enabled"
+msgid "SecurityOrchestration|Empty policy name"
msgstr ""
-msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Enabled"
msgstr ""
-msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
msgstr ""
msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
@@ -31860,7 +32536,7 @@ msgstr ""
msgid "SecurityOrchestration|Invalid policy type"
msgstr ""
-msgid "SecurityOrchestration|Latest scan"
+msgid "SecurityOrchestration|Latest scan run against %{agent}"
msgstr ""
msgid "SecurityOrchestration|Network"
@@ -31869,15 +32545,27 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No actions defined - policy will not run."
+msgstr ""
+
+msgid "SecurityOrchestration|No description"
+msgstr ""
+
msgid "SecurityOrchestration|No rules defined - policy will not run."
msgstr ""
+msgid "SecurityOrchestration|Not enabled"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
msgid "SecurityOrchestration|Policies"
msgstr ""
+msgid "SecurityOrchestration|Policy Type"
+msgstr ""
+
msgid "SecurityOrchestration|Policy cannot be enabled for non-existing branches (%{branches})"
msgstr ""
@@ -31902,10 +32590,13 @@ msgstr ""
msgid "SecurityOrchestration|Require %{approvals} %{plural} from %{approvers} if any of the following occur:"
msgstr ""
-msgid "SecurityOrchestration|Rule"
+msgid "SecurityOrchestration|Rules"
msgstr ""
-msgid "SecurityOrchestration|Rules"
+msgid "SecurityOrchestration|Runs %{actions} and %{lastAction} scans"
+msgstr ""
+
+msgid "SecurityOrchestration|Runs a %{action} scan"
msgstr ""
msgid "SecurityOrchestration|Scan Execution"
@@ -31965,6 +32656,9 @@ msgstr ""
msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
+msgid "SecurityOrchestration|This view only shows scan results for the agent %{agent}. You can view scan results for all agents in the %{linkStart}Operational Vulnerabilities tab of the vulnerability report%{linkEnd}."
+msgstr ""
+
msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
@@ -32019,9 +32713,6 @@ msgstr ""
msgid "SecurityOrchestration|users with ids"
msgstr ""
-msgid "SecurityOrchestration|view results"
-msgstr ""
-
msgid "SecurityOrchestration|vulnerabilities"
msgstr ""
@@ -32691,22 +33382,19 @@ 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|In order to start using functions as a service, you must first install Knative on your Kubernetes cluster. %{linkStart}More information%{linkEnd}"
-msgstr ""
-
msgid "Serverless|Learn more about Serverless"
msgstr ""
msgid "Serverless|No functions available"
msgstr ""
-msgid "Serverless|Sign up for First Look"
+msgid "Serverless|Serverless was %{linkStart}deprecated%{linkEnd} in GitLab 14.3."
+msgstr ""
+
+msgid "Serverless|Serverless was %{postLinkStart}deprecated%{postLinkEnd}. But if you opt to use it, you must install Knative in your Kubernetes cluster first. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "Serverless|The deploy job has not finished."
@@ -32718,9 +33406,6 @@ 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 ""
@@ -32736,9 +33421,6 @@ msgstr ""
msgid "Service Account Key"
msgstr ""
-msgid "Service Accounts"
-msgstr ""
-
msgid "Service Accounts keys authorize GitLab to deploy your Google Cloud project"
msgstr ""
@@ -32748,10 +33430,10 @@ msgstr ""
msgid "Service Desk allows people to create issues in your GitLab instance without their own user account. It provides a unique email address for end users to create issues in a project. Replies can be sent either through the GitLab interface or by email. End users only see threads through email."
msgstr ""
-msgid "Service Usage Data"
+msgid "Service account generated successfully"
msgstr ""
-msgid "Service account generated successfully"
+msgid "Service accounts"
msgstr ""
msgid "Service ping is disabled in your configuration file, and cannot be enabled through this form."
@@ -32895,6 +33577,9 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
+msgid "Set the per-user rate limit for getting a user by ID via the API."
+msgstr ""
+
msgid "Set the per-user rate limit for notes created by web or API requests."
msgstr ""
@@ -33074,6 +33759,9 @@ msgstr ""
msgid "Shared runners details"
msgstr ""
+msgid "Shared runners enabled cannot be enabled until a valid credit card is on file"
+msgstr ""
+
msgid "Shared runners help link"
msgstr ""
@@ -33131,6 +33819,9 @@ msgstr ""
msgid "Show all issues."
msgstr ""
+msgid "Show all milestones"
+msgstr ""
+
msgid "Show all test cases."
msgstr ""
@@ -33167,6 +33858,9 @@ msgstr ""
msgid "Show file contents"
msgstr ""
+msgid "Show group milestones"
+msgstr ""
+
msgid "Show labels"
msgstr ""
@@ -33182,6 +33876,12 @@ msgstr ""
msgid "Show open epics"
msgstr ""
+msgid "Show project milestones"
+msgstr ""
+
+msgid "Show sub-group milestones"
+msgstr ""
+
msgid "Show the Closed list"
msgstr ""
@@ -33191,11 +33891,6 @@ msgstr ""
msgid "Show whitespace changes"
msgstr ""
-msgid "Showing %d event"
-msgid_plural "Showing %d events"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Showing %{conflict} between %{sourceBranch} and %{targetBranch}"
msgstr ""
@@ -33255,12 +33950,6 @@ msgstr ""
msgid "Sidebar|None"
msgstr ""
-msgid "Sidebar|Only numeral characters allowed"
-msgstr ""
-
-msgid "Sidebar|Weight"
-msgstr ""
-
msgid "Sidekiq job compression threshold (bytes)"
msgstr ""
@@ -33423,6 +34112,9 @@ msgstr ""
msgid "Slack logo"
msgstr ""
+msgid "SlackIntegration|Are you sure you want to remove this project from the Slack application?"
+msgstr ""
+
msgid "SlackIntegration|GitLab for Slack"
msgstr ""
@@ -33432,6 +34124,9 @@ msgstr ""
msgid "SlackIntegration|Project alias"
msgstr ""
+msgid "SlackIntegration|Remove project"
+msgstr ""
+
msgid "SlackIntegration|Select a GitLab project to link with your Slack workspace."
msgstr ""
@@ -33576,9 +34271,6 @@ msgstr ""
msgid "Something went wrong trying to load issue contacts."
msgstr ""
-msgid "Something went wrong when creating a work item. Please try again"
-msgstr ""
-
msgid "Something went wrong when reordering designs. Please try again"
msgstr ""
@@ -33672,9 +34364,6 @@ msgstr ""
msgid "Something went wrong while inserting your image. Please try again."
msgstr ""
-msgid "Something went wrong while merging this merge request. Please try again."
-msgstr ""
-
msgid "Something went wrong while obtaining the Let's Encrypt certificate."
msgstr ""
@@ -33996,10 +34685,10 @@ 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."
+msgid "SourcegraphAdmin|Learn more."
msgstr ""
-msgid "SourcegraphAdmin|More information"
+msgid "SourcegraphAdmin|Only public projects have code intelligence enabled and communicate with Sourcegraph."
msgstr ""
msgid "SourcegraphAdmin|Save changes"
@@ -34008,7 +34697,7 @@ msgstr ""
msgid "SourcegraphAdmin|Sourcegraph URL"
msgstr ""
-msgid "SourcegraphAdmin|e.g. https://sourcegraph.example.com"
+msgid "SourcegraphAdmin|https://sourcegraph.example.com"
msgstr ""
msgid "SourcegraphPreferences|This feature is experimental and currently limited to certain projects."
@@ -34143,6 +34832,9 @@ msgstr ""
msgid "Start date"
msgstr ""
+msgid "Start free trial"
+msgstr ""
+
msgid "Start merge train"
msgstr ""
@@ -34173,6 +34865,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started escalation for this incident."
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -34185,6 +34880,9 @@ msgstr ""
msgid "Starts at (UTC)"
msgstr ""
+msgid "Starts escalations for this incident"
+msgstr ""
+
msgid "Starts on"
msgstr ""
@@ -34446,6 +35144,9 @@ msgstr ""
msgid "Strikethrough"
msgstr ""
+msgid "Strikethrough text"
+msgstr ""
+
msgid "Subgroup information"
msgstr ""
@@ -34680,6 +35381,21 @@ msgstr ""
msgid "Subscriptions"
msgstr ""
+msgid "Subscriptions|Chat with sales"
+msgstr ""
+
+msgid "Subscriptions|Close"
+msgstr ""
+
+msgid "Subscriptions|Not ready to buy yet?"
+msgstr ""
+
+msgid "Subscriptions|Start a free trial"
+msgstr ""
+
+msgid "Subscriptions|We understand. Maybe you have some questions for our sales team, or maybe you'd like to try some of the paid features first. What would you like to do?"
+msgstr ""
+
msgid "Subscription|Your subscription for %{strong}%{namespace_name}%{strong_close} has expired and you are now on %{pricing_link_start}the GitLab Free tier%{pricing_link_end}. Don't worry, your data is safe. Get in touch with our support team (%{support_email}). They'll gladly help with your subscription renewal."
msgstr ""
@@ -34890,6 +35606,9 @@ msgstr ""
msgid "SuperSonics|Maximum users"
msgstr ""
+msgid "SuperSonics|Offline cloud"
+msgstr ""
+
msgid "SuperSonics|Paste your activation code"
msgstr ""
@@ -34956,6 +35675,12 @@ msgstr ""
msgid "SuperSonics|You do not have an active subscription"
msgstr ""
+msgid "SuperSonics|You have a future dated license"
+msgstr ""
+
+msgid "SuperSonics|You have added a license that activates on %{date}. Please see the subscription history table below for more details."
+msgstr ""
+
msgid "SuperSonics|You have successfully added a license that activates on %{date}. Please see the subscription history table below for more details."
msgstr ""
@@ -35115,6 +35840,9 @@ msgstr ""
msgid "Tag name is required"
msgstr ""
+msgid "Tag push"
+msgstr ""
+
msgid "Tag push events"
msgstr ""
@@ -35217,6 +35945,9 @@ msgstr ""
msgid "TagsPage|protected"
msgstr ""
+msgid "Take a look at the documentation to discover all of GitLab’s capabilities."
+msgstr ""
+
msgid "Target Branch"
msgstr ""
@@ -35619,6 +36350,9 @@ msgstr ""
msgid "Tests"
msgstr ""
+msgid "Text (optional)"
+msgstr ""
+
msgid "Text added to the body of all email messages. %{character_limit} character limit"
msgstr ""
@@ -35669,6 +36403,9 @@ msgstr ""
msgid "The CSV export will be created in the background. Once finished, it will be sent to %{email} in an attachment."
msgstr ""
+msgid "The CSV export you requested of all user memberships is attached to this email."
+msgstr ""
+
msgid "The GitLab subscription service (customers.gitlab.com) is currently experiencing an outage. You can monitor the status and get updates at %{linkStart}status.gitlab.com%{linkEnd}."
msgstr ""
@@ -35744,6 +36481,9 @@ 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 epic"
+msgstr ""
+
msgid "The current issue"
msgstr ""
@@ -35905,6 +36645,9 @@ msgstr ""
msgid "The latest pipeline for this merge request has failed."
msgstr ""
+msgid "The license key is invalid."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -35920,6 +36663,9 @@ msgstr ""
msgid "The license was successfully uploaded and will be active from %{starts_at}. You can see the details below."
msgstr ""
+msgid "The license you uploaded is invalid. If the issue persists, contact support at %{link}."
+msgstr ""
+
msgid "The list creation wizard is already open"
msgstr ""
@@ -36541,10 +37287,13 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} and everything this project contains. %{strongOpen}There is no going back%{strongClose}"
+msgstr ""
+
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains."
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}on %{date}%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains. %{strongOpen}There is no going back.%{strongClose}"
msgstr ""
msgid "This action will %{strongOpen}permanently remove%{strongClose} %{codeOpen}%{group}%{codeClose} %{strongOpen}immediately%{strongClose}."
@@ -36673,9 +37422,6 @@ msgstr ""
msgid "This file was modified for readability, and can't accept suggestions. Edit it directly."
msgstr ""
-msgid "This forked project has the following:"
-msgstr ""
-
msgid "This form is disabled in preview"
msgstr ""
@@ -36688,7 +37434,7 @@ msgstr ""
msgid "This group can't be removed because it is linked to a subscription. To remove this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
-msgid "This group can't be transfered because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
+msgid "This group can't be transferred because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
msgid "This group cannot be invited to a project inside a group with enforced SSO"
@@ -36715,6 +37461,9 @@ 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 incident is already escalated with '%{escalation_policy_name}'."
+msgstr ""
+
msgid "This invitation was sent to %{mail_to_invite_email}, but you are signed in as %{link_to_current_user} with email %{mail_to_current_user}."
msgstr ""
@@ -36733,9 +37482,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 merge train pipeline"
-msgstr ""
-
msgid "This is a private email address %{helpIcon} generated just for you. Anyone who has it can create issues or merge requests as if they were you. If that happens, %{resetLinkStart}reset this token%{resetLinkEnd}."
msgstr ""
@@ -36757,6 +37503,12 @@ msgstr ""
msgid "This is your current session"
msgstr ""
+msgid "This issue cannot be assigned to a confidential epic because it is public."
+msgstr ""
+
+msgid "This issue cannot be made public because it belongs to a confidential epic."
+msgstr ""
+
msgid "This issue is confidential and should only be visible to team members with at least Reporter access."
msgstr ""
@@ -36874,6 +37626,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 branch is protected from force push."
+msgstr ""
+
msgid "This merge request cannot be rebased while there are conflicts."
msgstr ""
@@ -36925,9 +37680,15 @@ msgstr ""
msgid "This pipeline was triggered by a schedule."
msgstr ""
+msgid "This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project"
msgstr ""
+msgid "This project can be restored until %{date}."
+msgstr ""
+
msgid "This project cannot be %{visibilityLevel} because the visibility of %{openShowLink}%{name}%{closeShowLink} is %{visibility}. To make this project %{visibilityLevel}, you must first %{openEditLink}change the visibility%{closeEditLink} of the parent group."
msgstr ""
@@ -36946,6 +37707,9 @@ msgstr ""
msgid "This project is %{strongStart}NOT%{strongEnd} a fork, and has the following:"
msgstr ""
+msgid "This project is %{strongStart}NOT%{strongEnd} a fork. This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -37637,6 +38401,9 @@ msgstr ""
msgid "Today"
msgstr ""
+msgid "Todos count"
+msgstr ""
+
msgid "Todos|Are you looking for things to do? Take a look at %{strongStart}%{openIssuesLinkStart}open issues%{openIssuesLinkEnd}%{strongEnd}, contribute to %{strongStart}%{mergeRequestLinkStart}a merge request%{mergeRequestLinkEnd}%{mergeRequestLinkEnd}%{strongEnd}, or mention someone in a comment to automatically assign them a new to-do item."
msgstr ""
@@ -37910,10 +38677,8 @@ msgstr ""
msgid "Trending"
msgstr ""
-msgid "Trials|%{planName} Trial %{enDash} %{num} day left"
-msgid_plural "Trials|%{planName} Trial %{enDash} %{num} days left"
-msgstr[0] ""
-msgstr[1] ""
+msgid "Trials|%{planName} Trial"
+msgstr ""
msgid "Trials|Compare all plans"
msgstr ""
@@ -37921,6 +38686,9 @@ msgstr ""
msgid "Trials|Create a new group to start your GitLab Ultimate trial."
msgstr ""
+msgid "Trials|Day %{daysUsed}/%{duration}"
+msgstr ""
+
msgid "Trials|Go back to GitLab"
msgstr ""
@@ -38170,7 +38938,7 @@ msgstr ""
msgid "URL is triggered when repository is updated"
msgstr ""
-msgid "URL must be percent-encoded if neccessary."
+msgid "URL must be percent-encoded if necessary."
msgstr ""
msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
@@ -38389,6 +39157,9 @@ msgstr ""
msgid "Unlock account"
msgstr ""
+msgid "Unlock more features with GitLab Ultimate"
+msgstr ""
+
msgid "Unlock the discussion"
msgstr ""
@@ -38452,6 +39223,9 @@ msgstr ""
msgid "Unsubscribes from this %{quick_action_target}."
msgstr ""
+msgid "Unsupported sort value."
+msgstr ""
+
msgid "Unsupported todo type passed. Supported todo types are: %{todo_types}"
msgstr ""
@@ -38680,6 +39454,9 @@ msgstr ""
msgid "UsageQuota|File attachments and smaller design graphics."
msgstr ""
+msgid "UsageQuota|From %{storage_enforcement_date} storage limits will apply to this namespace. View and manage your usage in %{strong_start}Group Settings &gt; Usage quotas%{strong_end}."
+msgstr ""
+
msgid "UsageQuota|Git repository."
msgstr ""
@@ -38740,6 +39517,9 @@ msgstr ""
msgid "UsageQuota|Storage type"
msgstr ""
+msgid "UsageQuota|Storage used"
+msgstr ""
+
msgid "UsageQuota|This is the total amount of storage used across your projects within this namespace."
msgstr ""
@@ -38935,6 +39715,12 @@ msgstr ""
msgid "Use hashed storage paths for newly created and renamed repositories. Always enabled since 13.0."
msgstr ""
+msgid "Use issue count"
+msgstr ""
+
+msgid "Use issue weight"
+msgstr ""
+
msgid "Use one line per URI"
msgstr ""
@@ -39316,6 +40102,9 @@ msgstr ""
msgid "Users"
msgstr ""
+msgid "Users API rate limit"
+msgstr ""
+
msgid "Users can launch a development environment from a GitLab browser tab when the %{linkStart}Gitpod%{linkEnd} integration is enabled."
msgstr ""
@@ -39641,6 +40430,9 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View group pipeline usage quota"
+msgstr ""
+
msgid "View incident details at"
msgstr ""
@@ -39793,6 +40585,9 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
+msgid "Vulnerability"
+msgstr ""
+
msgid "Vulnerability Report"
msgstr ""
@@ -39844,6 +40639,9 @@ msgstr ""
msgid "VulnerabilityManagement|An unverified non-confirmed finding"
msgstr ""
+msgid "VulnerabilityManagement|At least one identifier is required"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -39853,12 +40651,24 @@ msgstr ""
msgid "VulnerabilityManagement|Create Jira issue"
msgstr ""
+msgid "VulnerabilityManagement|Enter a name"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE code"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE identifier URL"
+msgstr ""
+
msgid "VulnerabilityManagement|Fetching linked Jira issues"
msgstr ""
msgid "VulnerabilityManagement|Manually add a vulnerability entry into the vulnerability report."
msgstr ""
+msgid "VulnerabilityManagement|Name is a required field"
+msgstr ""
+
msgid "VulnerabilityManagement|Needs triage"
msgstr ""
@@ -39874,6 +40684,18 @@ msgstr ""
msgid "VulnerabilityManagement|Select a method"
msgstr ""
+msgid "VulnerabilityManagement|Select a severity level"
+msgstr ""
+
+msgid "VulnerabilityManagement|Select a status"
+msgstr ""
+
+msgid "VulnerabilityManagement|Severity is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Something went wrong while creating vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -39898,6 +40720,12 @@ msgstr ""
msgid "VulnerabilityManagement|Something went wrong, could not update vulnerability state."
msgstr ""
+msgid "VulnerabilityManagement|Status is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Submit vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Summary, detailed description, steps to reproduce, etc."
msgstr ""
@@ -40093,6 +40921,9 @@ msgstr ""
msgid "WARNING:"
msgstr ""
+msgid "WARNING: This snippet contains hidden files which might be used to mask malicious behavior. Exercise caution if cloning and executing code from this snippet."
+msgstr ""
+
msgid "Wait for the file to load to copy its contents"
msgstr ""
@@ -40312,6 +41143,15 @@ msgstr ""
msgid "Webhooks|An issue is created, updated, closed, or reopened."
msgstr ""
+msgid "Webhooks|Are you sure you want to delete this group hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this project hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this webhook?"
+msgstr ""
+
msgid "Webhooks|Comments"
msgstr ""
@@ -40321,6 +41161,9 @@ msgstr ""
msgid "Webhooks|Confidential issues events"
msgstr ""
+msgid "Webhooks|Delete webhook"
+msgstr ""
+
msgid "Webhooks|Deployment events"
msgstr ""
@@ -40554,6 +41397,9 @@ msgstr ""
msgid "Wiki"
msgstr ""
+msgid "Wiki page"
+msgstr ""
+
msgid "Wiki page was successfully created."
msgstr ""
@@ -40659,7 +41505,7 @@ msgstr ""
msgid "WikiPageConflictMessage|Someone edited the page the same time you did. Please check out %{wikiLinkStart}the page%{wikiLinkEnd} and make sure your changes will not unintentionally remove theirs."
msgstr ""
-msgid "WikiPage|An error occured while trying to render the content editor. Please try again later."
+msgid "WikiPage|An error occurred while trying to render the content editor. Please try again later."
msgstr ""
msgid "WikiPage|Are you sure you want to switch back to the classic editor?"
@@ -40818,6 +41664,18 @@ msgstr ""
msgid "WorkItem|New Task"
msgstr ""
+msgid "WorkItem|Something went wrong when creating a work item. Please try again"
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching the work item. Please try again."
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching work item types. Please try again"
+msgstr ""
+
+msgid "WorkItem|Type"
+msgstr ""
+
msgid "WorkItem|Work Items"
msgstr ""
@@ -40884,7 +41742,10 @@ msgstr ""
msgid "You are about to add %{usersTag} people to the discussion. They will all receive a notification."
msgstr ""
-msgid "You are about to permanently delete this project"
+msgid "You are about to delete this forked project containing:"
+msgstr ""
+
+msgid "You are about to delete this project containing:"
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."
@@ -40905,6 +41766,9 @@ msgstr ""
msgid "You are attempting to update a file that has changed since you started editing it."
msgstr ""
+msgid "You are billed if you exceed this number. %{qsrOverageLinkStart}How does billing work?%{qsrOverageLinkEnd}"
+msgstr ""
+
msgid "You are connected to the Prometheus server, but there is currently no data to display."
msgstr ""
@@ -40962,6 +41826,9 @@ msgstr ""
msgid "You are not authorized to update this scanner profile"
msgstr ""
+msgid "You are not authorized to upload metric images"
+msgstr ""
+
msgid "You are now impersonating %{username}"
msgstr ""
@@ -41115,9 +41982,6 @@ msgstr ""
msgid "You can only upload one design when dropping onto an existing design."
msgstr ""
-msgid "You can recover this project until %{date}"
-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 ""
@@ -41166,9 +42030,6 @@ msgstr ""
msgid "You cannot write to this read-only GitLab instance."
msgstr ""
-msgid "You can’t %{tag_start}edit%{tag_end} files directly in this project. Fork this project and submit a merge request with your changes."
-msgstr ""
-
msgid "You can’t edit files directly in this project. Fork this project and submit a merge request with your changes."
msgstr ""
@@ -41321,9 +42182,6 @@ 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 set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
@@ -41354,12 +42212,6 @@ msgstr ""
msgid "You must have maintainer access to force delete a lock"
msgstr ""
-msgid "You must have permission to create a project in a group before forking."
-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 ""
@@ -41765,7 +42617,7 @@ msgstr ""
msgid "Your public email will be displayed on your public profile."
msgstr ""
-msgid "Your request for access could not be processed: %{error_meesage}"
+msgid "Your request for access could not be processed: %{error_message}"
msgstr ""
msgid "Your request for access has been queued for review."
@@ -41948,6 +42800,9 @@ msgstr ""
msgid "archived:"
msgstr ""
+msgid "artifacts"
+msgstr ""
+
msgid "assign yourself"
msgstr ""
@@ -41977,6 +42832,9 @@ msgstr[1] ""
msgid "branch name"
msgstr ""
+msgid "builds"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -42400,6 +43258,9 @@ msgstr ""
msgid "contact with same email already exists in group hierarchy"
msgstr ""
+msgid "container registry images"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -42439,6 +43300,9 @@ msgstr ""
msgid "data"
msgstr ""
+msgid "database"
+msgstr ""
+
msgid "date must not be after 9999-12-31"
msgstr ""
@@ -42462,9 +43326,6 @@ msgstr ""
msgid "design"
msgstr ""
-msgid "detached"
-msgstr ""
-
msgid "disabled"
msgstr ""
@@ -42713,7 +43574,7 @@ msgstr ""
msgid "is not a valid X509 certificate."
msgstr ""
-msgid "is not allowed for sign-up."
+msgid "is not allowed for sign-up. Please use your regular email address."
msgstr ""
msgid "is not allowed for this group."
@@ -42725,7 +43586,7 @@ msgstr ""
msgid "is not allowed since the group is not top-level group."
msgstr ""
-msgid "is not allowed."
+msgid "is not allowed. Please use your regular email address."
msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
@@ -42812,6 +43673,9 @@ msgstr ""
msgid "level: %{level}"
msgstr ""
+msgid "lfs objects"
+msgstr ""
+
msgid "limit of %{project_limit} reached"
msgstr ""
@@ -43031,6 +43895,9 @@ msgstr ""
msgid "mrWidget|Merge blocked: pipeline must succeed. It's waiting for a manual action to continue."
msgstr ""
+msgid "mrWidget|Merge blocked: pipeline must succeed. Push a commit that fixes the failure, or %{linkStart}learn about other solutions.%{linkEnd}"
+msgstr ""
+
msgid "mrWidget|Merge blocked: this merge request must be approved."
msgstr ""
@@ -43148,9 +44015,6 @@ msgstr ""
msgid "mrWidget|The changes were not merged into"
msgstr ""
-msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -43298,9 +44162,6 @@ msgstr ""
msgid "open issue"
msgstr ""
-msgid "opened %{timeAgo}"
-msgstr ""
-
msgid "or"
msgstr ""
@@ -43312,6 +44173,12 @@ msgid_plural "out of %d total tests"
msgstr[0] ""
msgstr[1] ""
+msgid "packages"
+msgstr ""
+
+msgid "pages"
+msgstr ""
+
msgid "parent"
msgid_plural "parents"
msgstr[0] ""
@@ -43461,6 +44328,9 @@ msgid_plural "replies"
msgstr[0] ""
msgstr[1] ""
+msgid "repositories"
+msgstr ""
+
msgid "repository:"
msgstr ""
@@ -43581,12 +44451,18 @@ msgstr ""
msgid "tag name"
msgstr ""
+msgid "terraform states"
+msgstr ""
+
msgid "the correct format."
msgstr ""
msgid "the file"
msgstr ""
+msgid "the following epic(s)"
+msgstr ""
+
msgid "the following issue(s)"
msgstr ""
@@ -43599,21 +44475,12 @@ msgstr ""
msgid "this document"
msgstr ""
-msgid "this issue cannot be assigned to a confidential epic since it is public"
-msgstr ""
-
-msgid "this issue cannot be made public since it belongs to a confidential epic"
-msgstr ""
-
msgid "time summary"
msgstr ""
msgid "toggle collapse"
msgstr ""
-msgid "train"
-msgstr ""
-
msgid "triggered"
msgstr ""
@@ -43742,3 +44609,6 @@ msgstr ""
msgid "{project}"
msgstr ""
+msgid "✔"
+msgstr ""
+
diff --git a/locale/ky_KG/gitlab.po b/locale/ky_KG/gitlab.po
index e7520f63696..d3913b8077d 100644
--- a/locale/ky_KG/gitlab.po
+++ b/locale/ky_KG/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: ky\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2022-02-02 15:46\n"
+"PO-Revision-Date: 2022-03-01 20:40\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -146,6 +146,11 @@ msgid_plural "%d approvers (you've approved)"
msgstr[0] ""
msgstr[1] ""
+msgid "%d assigned issue"
+msgid_plural "%d assigned issues"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -421,8 +426,23 @@ msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
msgstr[1] ""
-msgid "%d vulnerability updated"
-msgid_plural "%d vulnerabilities updated"
+msgid "%d vulnerability set to confirmed"
+msgid_plural "%d vulnerabilities set to confirmed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to dismissed"
+msgid_plural "%d vulnerabilities set to dismissed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to needs triage"
+msgid_plural "%d vulnerabilities set to needs triage"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to resolved"
+msgid_plural "%d vulnerabilities set to resolved"
msgstr[0] ""
msgstr[1] ""
@@ -510,6 +530,12 @@ msgstr[1] ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{completed} of %{total} issues closed"
+msgstr ""
+
+msgid "%{completed} of %{total} weight completed"
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -858,6 +884,9 @@ msgstr ""
msgid "%{openedIssues} open, %{closedIssues} closed"
msgstr ""
+msgid "%{percentage}%% issues closed"
+msgstr ""
+
msgid "%{percentage}%% weight completed"
msgstr ""
@@ -1287,6 +1316,9 @@ msgid_plural "- Users"
msgstr[0] ""
msgstr[1] ""
+msgid "- of - issues closed"
+msgstr ""
+
msgid "- of - weight completed"
msgstr ""
@@ -1429,7 +1461,7 @@ msgstr ""
msgid "1000+"
msgstr ""
-msgid "192.168.0.0/24"
+msgid "192.168.0.0/24 or 2001:0DB8:1234::/48"
msgstr ""
msgid "1st contribution!"
@@ -1741,13 +1773,13 @@ msgstr ""
msgid "AWS Access Key"
msgstr ""
-msgid "AWS Access Key. Only required if not using role instance credentials"
+msgid "AWS Secret Access Key"
msgstr ""
-msgid "AWS Secret Access Key"
+msgid "AWS access key ID (Optional)"
msgstr ""
-msgid "AWS Secret Access Key. Only required if not using role instance credentials"
+msgid "AWS secret access key (Optional)"
msgstr ""
msgid "AWS service error: %{error}"
@@ -1807,9 +1839,6 @@ msgstr ""
msgid "Access granted"
msgstr ""
-msgid "Access key ID"
-msgstr ""
-
msgid "Access requests"
msgstr ""
@@ -1984,7 +2013,7 @@ msgstr ""
msgid "Activity"
msgstr ""
-msgid "Activity|An error occured while retrieving activity. Reload the page to try again."
+msgid "Activity|An error occurred while retrieving activity. Reload the page to try again."
msgstr ""
msgid "Add"
@@ -2023,6 +2052,9 @@ msgstr ""
msgid "Add a %{type}"
msgstr ""
+msgid "Add a GCP region"
+msgstr ""
+
msgid "Add a GPG key"
msgstr ""
@@ -2074,6 +2106,9 @@ msgstr ""
msgid "Add a numbered list"
msgstr ""
+msgid "Add a related epic"
+msgstr ""
+
msgid "Add a related issue"
msgstr ""
@@ -2188,6 +2223,9 @@ msgstr ""
msgid "Add or subtract spent time"
msgstr ""
+msgid "Add people"
+msgstr ""
+
msgid "Add previously merged commits"
msgstr ""
@@ -2254,6 +2292,9 @@ msgstr ""
msgid "Add webhook"
msgstr ""
+msgid "Add your team members and others to GitLab."
+msgstr ""
+
msgid "Add/remove"
msgstr ""
@@ -3076,12 +3117,6 @@ msgstr ""
msgid "AdvancedSearch|Reindex required"
msgstr ""
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. Permanently deleting this project will %{strongStart}immediately delete%{strongEnd} its repositories and %{strongStart}all related resources%{strongEnd}, including issues, merge requests etc."
-msgstr ""
-
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. You will lose this project's repository and %{strongStart}all related resources%{strongEnd}, including issues and merge requests."
-msgstr ""
-
msgid "After a successful password update you will be redirected to login screen."
msgstr ""
@@ -3112,6 +3147,9 @@ msgstr ""
msgid "Akismet helps prevent the creation of spam issues in public projects."
msgstr ""
+msgid "Alert"
+msgstr ""
+
msgid "AlertManagement|Acknowledged"
msgstr ""
@@ -3484,9 +3522,6 @@ msgstr ""
msgid "All environments"
msgstr ""
-msgid "All epics"
-msgstr ""
-
msgid "All groups and projects"
msgstr ""
@@ -4223,12 +4258,15 @@ msgstr ""
msgid "ApplicationSettings|Approve users in the pending approval status?"
msgstr ""
-msgid "ApplicationSettings|By making this change, you will automatically approve %d user with the pending approval status."
-msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users with the pending approval status."
+msgid "ApplicationSettings|Approve users who are pending approval?"
+msgstr ""
+
+msgid "ApplicationSettings|By making this change, you will automatically approve %d user who is pending approval."
+msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users who are pending approval."
msgstr[0] ""
msgstr[1] ""
-msgid "ApplicationSettings|By making this change, you will automatically approve all users in pending approval status."
+msgid "ApplicationSettings|By making this change, you will automatically approve all users who are pending approval."
msgstr ""
msgid "ApplicationSettings|Denied domains for sign-ups"
@@ -4634,10 +4672,10 @@ msgstr ""
msgid "Archiving the project will make it entirely read-only. It is hidden from the dashboard and doesn't show up in searches. %{strong_start}The repository cannot be committed to, and no issues, comments, or other entities can be created.%{strong_end} %{link_start}Learn more.%{link_end}"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to delete this project?"
+msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
+msgid "Are you absolutely sure?"
msgstr ""
msgid "Are you sure that you want to archive this project?"
@@ -4673,12 +4711,18 @@ msgstr ""
msgid "Are you sure you want to delete this SSH key?"
msgstr ""
+msgid "Are you sure you want to delete this comment?"
+msgstr ""
+
msgid "Are you sure you want to delete this deploy key?"
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 label?"
+msgstr ""
+
msgid "Are you sure you want to delete this pipeline schedule?"
msgstr ""
@@ -4694,9 +4738,6 @@ msgstr ""
msgid "Are you sure you want to discard your changes?"
msgstr ""
-msgid "Are you sure you want to erase this build?"
-msgstr ""
-
msgid "Are you sure you want to import %d repository?"
msgid_plural "Are you sure you want to import %d repositories?"
msgstr[0] ""
@@ -4744,6 +4785,9 @@ msgstr ""
msgid "Are you sure you want to remove this list?"
msgstr ""
+msgid "Are you sure you want to remove this nickname?"
+msgstr ""
+
msgid "Are you sure you want to reset the health check token?"
msgstr ""
@@ -4756,10 +4800,10 @@ 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?"
+msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
msgstr ""
-msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
+msgid "Are you sure you want to revoke this project access token? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to stop this environment?"
@@ -4906,9 +4950,6 @@ msgstr ""
msgid "Assigned to %{assignee_name}"
msgstr ""
-msgid "Assigned to %{name}"
-msgstr ""
-
msgid "Assigned to me"
msgstr ""
@@ -4973,6 +5014,9 @@ msgstr[1] ""
msgid "Attaching the file failed."
msgstr ""
+msgid "Attention"
+msgstr ""
+
msgid "Audit Events"
msgstr ""
@@ -5135,6 +5179,12 @@ msgstr ""
msgid "Authorized applications (%{size})"
msgstr ""
+msgid "AuthorizedApplication|Are you sure you want to revoke this application?"
+msgstr ""
+
+msgid "AuthorizedApplication|Revoke application"
+msgstr ""
+
msgid "Authors: %{authors}"
msgstr ""
@@ -6328,6 +6378,9 @@ msgstr ""
msgid "CICDAnalytics|Shared Runners Usage"
msgstr ""
+msgid "CICDAnalytics|Shared runner pipeline minute duration by month"
+msgstr ""
+
msgid "CICDAnalytics|Shared runner usage"
msgstr ""
@@ -6469,6 +6522,9 @@ msgstr ""
msgid "Can create groups:"
msgstr ""
+msgid "Can not delete primary training"
+msgstr ""
+
msgid "Can't apply as the source branch was deleted."
msgstr ""
@@ -6802,9 +6858,6 @@ msgstr ""
msgid "Changing any setting here requires an application restart"
msgstr ""
-msgid "Changing group URL can have unintended side effects."
-msgstr ""
-
msgid "Charts can't be displayed as the request for data has timed out. %{documentationLink}"
msgstr ""
@@ -6892,9 +6945,6 @@ msgstr ""
msgid "Checking branch availability..."
msgstr ""
-msgid "Checking group URL availability..."
-msgstr ""
-
msgid "Checking group path availability..."
msgstr ""
@@ -7388,6 +7438,9 @@ msgstr ""
msgid "Clear recent searches"
msgstr ""
+msgid "Clear repository checks"
+msgstr ""
+
msgid "Clear search"
msgstr ""
@@ -7520,9 +7573,6 @@ msgstr ""
msgid "Closed MRs"
msgstr ""
-msgid "Closed epics"
-msgstr ""
-
msgid "Closed issues"
msgstr ""
@@ -7559,13 +7609,13 @@ msgstr ""
msgid "Cluster level"
msgstr ""
-msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
+msgid "Cluster type must be specified for Stages::ClusterEndpointInserter"
msgstr ""
msgid "ClusterAgents|%{name} successfully deleted"
msgstr ""
-msgid "ClusterAgents|%{number} of %{total} Agents"
+msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
@@ -7607,6 +7657,15 @@ msgstr ""
msgid "ClusterAgents|Agent never connected to GitLab"
msgstr ""
+msgid "ClusterAgents|Agent version mismatch"
+msgstr ""
+
+msgid "ClusterAgents|Agent version mismatch and update"
+msgstr ""
+
+msgid "ClusterAgents|Agent version update required"
+msgstr ""
+
msgid "ClusterAgents|All"
msgstr ""
@@ -7631,7 +7690,7 @@ msgstr ""
msgid "ClusterAgents|Configuration"
msgstr ""
-msgid "ClusterAgents|Connect a cluster through the Agent"
+msgid "ClusterAgents|Connect a cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connect existing cluster"
@@ -7640,13 +7699,13 @@ msgstr ""
msgid "ClusterAgents|Connect with a certificate"
msgstr ""
-msgid "ClusterAgents|Connect with agent"
+msgid "ClusterAgents|Connect with an agent"
msgstr ""
msgid "ClusterAgents|Connect with the GitLab Agent"
msgstr ""
-msgid "ClusterAgents|Connect your cluster through the Agent"
+msgid "ClusterAgents|Connect your cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connected"
@@ -7706,7 +7765,10 @@ msgstr ""
msgid "ClusterAgents|How to register an agent?"
msgstr ""
-msgid "ClusterAgents|Install new Agent"
+msgid "ClusterAgents|How to update an agent?"
+msgstr ""
+
+msgid "ClusterAgents|Install a new agent"
msgstr ""
msgid "ClusterAgents|Last connected %{timeAgo}."
@@ -7733,7 +7795,7 @@ msgstr ""
msgid "ClusterAgents|Never connected"
msgstr ""
-msgid "ClusterAgents|No Agents"
+msgid "ClusterAgents|No agents"
msgstr ""
msgid "ClusterAgents|No clusters connected through cluster certificates"
@@ -7793,6 +7855,9 @@ msgstr ""
msgid "ClusterAgents|The agent has not been connected in a long time. There might be a connectivity issue. Last contact was %{timeAgo}."
msgstr ""
+msgid "ClusterAgents|The agent version do not match each other across your cluster's pods. This can happen when a new agent version was just deployed and Kubernetes is shutting down the old pods."
+msgstr ""
+
msgid "ClusterAgents|The recommended installation method includes the token. If you want to follow the advanced installation method provided in the docs, make sure you save the token value before you close this window."
msgstr ""
@@ -7840,6 +7905,9 @@ msgstr ""
msgid "ClusterAgents|You will need to create a token to connect to your agent"
msgstr ""
+msgid "ClusterAgents|Your agent version is out of sync with your GitLab version (v%{version}), which might cause compatibility problems. Update the agent installed on your cluster to the most recent version."
+msgstr ""
+
msgid "ClusterAgents|Your instance doesn't have the %{linkStart}GitLab Agent Server (KAS)%{linkEnd} set up. Ask a GitLab Administrator to install it."
msgstr ""
@@ -8716,9 +8784,6 @@ msgstr ""
msgid "Comma-separated list of email addresses."
msgstr ""
-msgid "Comma-separated list of users allowed to exceed the rate limit."
-msgstr ""
-
msgid "Comma-separated, e.g. '1.1.1.1, 2.2.2.0/24'"
msgstr ""
@@ -9045,6 +9110,12 @@ msgstr ""
msgid "Confidential"
msgstr ""
+msgid "Confidential issue"
+msgstr ""
+
+msgid "Confidential note"
+msgstr ""
+
msgid "Confidentiality"
msgstr ""
@@ -9078,6 +9149,9 @@ msgstr ""
msgid "Configure Dependency Scanning in `.gitlab-ci.yml`, creating this file if it does not already exist"
msgstr ""
+msgid "Configure GitLab"
+msgstr ""
+
msgid "Configure GitLab runners to start using the Web Terminal. %{helpStart}Learn more.%{helpEnd}"
msgstr ""
@@ -9126,6 +9200,15 @@ msgstr ""
msgid "Configure pipelines to deploy web apps, backend services, APIs and static resources to Google Cloud"
msgstr ""
+msgid "Configure region"
+msgstr ""
+
+msgid "Configure region for environment"
+msgstr ""
+
+msgid "Configure regions"
+msgstr ""
+
msgid "Configure repository mirroring."
msgstr ""
@@ -9159,6 +9242,9 @@ msgstr ""
msgid "Configure which lists are shown for anyone who visits this board"
msgstr ""
+msgid "Configure your environments to be deployed to specific geographical regions"
+msgstr ""
+
msgid "Confirm"
msgstr ""
@@ -9861,10 +9947,10 @@ msgstr ""
msgid "CorpusManagement|Actions"
msgstr ""
-msgid "CorpusManagement|Corpus are used in fuzz testing as mutation source to Improve future testing."
+msgid "CorpusManagement|Corpus file"
msgstr ""
-msgid "CorpusManagement|Corpus file"
+msgid "CorpusManagement|Corpus files are used in coverage-guided fuzz testing as seed inputs to improve testing."
msgstr ""
msgid "CorpusManagement|Corpus files must be in *.zip format. Maximum 5 GB"
@@ -9918,6 +10004,9 @@ msgstr ""
msgid "Could not apply %{name} command."
msgstr ""
+msgid "Could not apply %{name} command. %{message}."
+msgstr ""
+
msgid "Could not authorize chat nickname. Try again!"
msgstr ""
@@ -10068,6 +10157,9 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
+msgid "Create a group"
+msgstr ""
+
msgid "Create a merge request"
msgstr ""
@@ -10092,6 +10184,9 @@ msgstr ""
msgid "Create a personal access token on your account to pull or push via %{protocol}."
msgstr ""
+msgid "Create a project"
+msgstr ""
+
msgid "Create an account using:"
msgstr ""
@@ -10455,6 +10550,9 @@ msgstr ""
msgid "Creation date"
msgstr ""
+msgid "Creator"
+msgstr ""
+
msgid "Credentials"
msgstr ""
@@ -10467,9 +10565,15 @@ msgstr ""
msgid "CredentialsInventory|Personal Access Tokens"
msgstr ""
+msgid "CredentialsInventory|Project Access Tokens"
+msgstr ""
+
msgid "CredentialsInventory|SSH Keys"
msgstr ""
+msgid "Credit card required to be on file in order to create a pipeline"
+msgstr ""
+
msgid "Credit card:"
msgstr ""
@@ -10653,9 +10757,6 @@ msgstr ""
msgid "Customer relations"
msgstr ""
-msgid "Customizable by an administrator."
-msgstr ""
-
msgid "Customizable by owners."
msgstr ""
@@ -10785,30 +10886,18 @@ msgstr ""
msgid "CycleAnalytics|%{selectedLabelsCount} selected (%{maxLabels} max)"
msgstr ""
-msgid "CycleAnalytics|%{stageCount} stages selected"
-msgstr ""
-
-msgid "CycleAnalytics|All stages"
-msgstr ""
-
-msgid "CycleAnalytics|Average days to completion"
+msgid "CycleAnalytics|Average time to completion"
msgstr ""
msgid "CycleAnalytics|Date"
msgstr ""
-msgid "CycleAnalytics|Days to completion"
-msgstr ""
-
msgid "CycleAnalytics|Display chart filters"
msgstr ""
msgid "CycleAnalytics|Lead Time for Changes"
msgstr ""
-msgid "CycleAnalytics|No stages selected"
-msgstr ""
-
msgid "CycleAnalytics|Number of tasks"
msgstr ""
@@ -10837,18 +10926,30 @@ msgstr ""
msgid "CycleAnalytics|Showing data for group '%{groupName}' from %{createdAfter} to %{createdBefore}"
msgstr ""
-msgid "CycleAnalytics|Stages"
+msgid "CycleAnalytics|Stage time: %{title}"
msgstr ""
msgid "CycleAnalytics|Tasks by type"
msgstr ""
-msgid "CycleAnalytics|The average time spent in the selected stage for the items that were completed on each date. Data limited to the last 500 items."
+msgid "CycleAnalytics|The average time items spent in this stage. Data limited to items completed within this date range."
msgstr ""
msgid "CycleAnalytics|The given date range is larger than 180 days"
msgstr ""
+msgid "CycleAnalytics|The total time items spent across each value stream stage. Data limited to items completed within this date range."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Stage time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Total time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|Total time"
+msgstr ""
+
msgid "CycleAnalytics|Type of work"
msgstr ""
@@ -10861,9 +10962,6 @@ msgstr ""
msgid "CycleAnalytics|project dropdown filter"
msgstr ""
-msgid "CycleAnalytics|stage dropdown"
-msgstr ""
-
msgid "DAG visualization requires at least 3 dependent jobs."
msgstr ""
@@ -10963,10 +11061,16 @@ msgstr ""
msgid "DastProfiles|AJAX spider"
msgstr ""
+msgid "DastProfiles|API"
+msgstr ""
+
+msgid "DastProfiles|API endpoint URL"
+msgstr ""
+
msgid "DastProfiles|Active"
msgstr ""
-msgid "DastProfiles|Additional request headers (Optional)"
+msgid "DastProfiles|Additional request headers (optional)"
msgstr ""
msgid "DastProfiles|Are you sure you want to delete this profile?"
@@ -10981,6 +11085,9 @@ msgstr ""
msgid "DastProfiles|Branch missing"
msgstr ""
+msgid "DastProfiles|Choose a scan method"
+msgstr ""
+
msgid "DastProfiles|Could not create the scanner profile. Please try again."
msgstr ""
@@ -11050,7 +11157,13 @@ msgstr ""
msgid "DastProfiles|Excluded URLs"
msgstr ""
-msgid "DastProfiles|Excluded URLs (Optional)"
+msgid "DastProfiles|Excluded URLs (optional)"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths (optional)"
msgstr ""
msgid "DastProfiles|Hide debug messages"
@@ -11107,9 +11220,6 @@ msgstr ""
msgid "DastProfiles|Request headers"
msgstr ""
-msgid "DastProfiles|Rest API"
-msgstr ""
-
msgid "DastProfiles|Run the AJAX spider, in addition to the traditional spider, to crawl the target site."
msgstr ""
@@ -11119,6 +11229,9 @@ msgstr ""
msgid "DastProfiles|Save profile"
msgstr ""
+msgid "DastProfiles|Scan method"
+msgstr ""
+
msgid "DastProfiles|Scan mode"
msgstr ""
@@ -11197,12 +11310,24 @@ msgstr ""
msgid "DastProfiles|Website"
msgstr ""
+msgid "DastProfiles|What does each method do?"
+msgstr ""
+
msgid "DastProfiles|You can either choose a passive scan or validate the target site from the site profile management page. %{docsLinkStart}Learn more about site validation.%{docsLinkEnd}"
msgstr ""
msgid "DastProfiles|You cannot run an active scan against an unvalidated site."
msgstr ""
+msgid "DastProfiles|folder/dast_example.har or https://example.com/dast_example.har"
+msgstr ""
+
+msgid "DastProfiles|folder/example.postman_collection.json or https://example.com/"
+msgstr ""
+
+msgid "DastProfiles|folder/openapi.json or https://example.com/openapi.json"
+msgstr ""
+
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
@@ -11310,6 +11435,9 @@ msgstr ""
msgid "DatadogIntegration|API URL"
msgstr ""
+msgid "DatadogIntegration|Custom tags in Datadog. Enter one tag per line in the %{codeOpen}key:value%{codeClose} format. %{linkOpen}How do I use tags?%{linkClose}"
+msgstr ""
+
msgid "DatadogIntegration|Environment"
msgstr ""
@@ -11328,12 +11456,18 @@ msgstr ""
msgid "DatadogIntegration|Tag all data from this GitLab instance in Datadog. Useful when managing several self-managed deployments."
msgstr ""
+msgid "DatadogIntegration|Tags"
+msgstr ""
+
msgid "DatadogIntegration|The Datadog site to send data to. To send data to the EU site, use %{codeOpen}datadoghq.eu%{codeClose}."
msgstr ""
msgid "DatadogIntegration|Trace your GitLab pipelines with Datadog."
msgstr ""
+msgid "DatadogIntegration|have an invalid format"
+msgstr ""
+
msgid "Datasource name not found"
msgstr ""
@@ -11343,9 +11477,6 @@ msgstr ""
msgid "Date merged"
msgstr ""
-msgid "Date picker"
-msgstr ""
-
msgid "Date range"
msgstr ""
@@ -11499,9 +11630,6 @@ msgstr ""
msgid "Definition"
msgstr ""
-msgid "Delayed Project Deletion (%{adjourned_deletion})"
-msgstr ""
-
msgid "DelayedJobs|Are you sure you want to run %{jobName} immediately? Otherwise this job will run automatically after its timer finishes."
msgstr ""
@@ -11580,10 +11708,10 @@ msgstr ""
msgid "Delete pipeline"
msgstr ""
-msgid "Delete project"
+msgid "Delete pipeline schedule"
msgstr ""
-msgid "Delete project. Are you ABSOLUTELY SURE?"
+msgid "Delete project"
msgstr ""
msgid "Delete row"
@@ -11613,6 +11741,9 @@ msgstr ""
msgid "Delete this epic and all descendants?"
msgstr ""
+msgid "Delete this project"
+msgstr ""
+
msgid "Delete user list"
msgstr ""
@@ -11871,6 +12002,12 @@ msgstr ""
msgid "Deploy to..."
msgstr ""
+msgid "DeployBoards|To see deployment progress for your environments, make sure you are deploying to %{codeStart}$KUBE_NAMESPACE%{codeEnd} and annotating with %{codeStart}app.gitlab.com/app=$CI_PROJECT_PATH_SLUG%{codeEnd} and %{codeStart}app.gitlab.com/env=$CI_ENVIRONMENT_SLUG%{codeEnd}."
+msgstr ""
+
+msgid "DeployBoard|Kubernetes Pods"
+msgstr ""
+
msgid "DeployFreeze|Add a freeze period to prevent unintended releases during a period of time for a given environment. You must update the deployment jobs in %{filename} according to the deploy freezes added here. %{freeze_period_link_start}Learn more.%{freeze_period_link_end}"
msgstr ""
@@ -11955,9 +12092,6 @@ msgstr ""
msgid "DeployTokens|Active Deploy Tokens (%{active_tokens})"
msgstr ""
-msgid "DeployTokens|Allows read and write access to registry images."
-msgstr ""
-
msgid "DeployTokens|Allows read and write access to the package registry."
msgstr ""
@@ -11970,6 +12104,9 @@ msgstr ""
msgid "DeployTokens|Allows read-only access to the repository."
msgstr ""
+msgid "DeployTokens|Allows write access to registry images."
+msgstr ""
+
msgid "DeployTokens|Copy deploy token"
msgstr ""
@@ -12063,12 +12200,57 @@ msgstr ""
msgid "Deploying to AWS is easy with GitLab"
msgstr ""
+msgid "Deployment"
+msgstr ""
+
msgid "Deployment Frequency"
msgstr ""
+msgid "Deployment Target|Project deployment target (optional)"
+msgstr ""
+
+msgid "Deployment Target|Select the deployment target"
+msgstr ""
+
msgid "Deployment frequency"
msgstr ""
+msgid "DeploymentTarget|GitLab Pages"
+msgstr ""
+
+msgid "DeploymentTarget|Heroku"
+msgstr ""
+
+msgid "DeploymentTarget|Infrastructure provider (Terraform, Cloudformation, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Kubernetes (GKE, EKS, OpenShift, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Managed container runtime (Fargate, Cloud Run, DigitalOcean App)"
+msgstr ""
+
+msgid "DeploymentTarget|Mobile app store"
+msgstr ""
+
+msgid "DeploymentTarget|No deployment planned"
+msgstr ""
+
+msgid "DeploymentTarget|Other hosting service"
+msgstr ""
+
+msgid "DeploymentTarget|Registry (package or container)"
+msgstr ""
+
+msgid "DeploymentTarget|Self-managed container runtime (Podman, Docker Swarm, Docker Compose)"
+msgstr ""
+
+msgid "DeploymentTarget|Serverless backend (Lambda, Cloud functions)"
+msgstr ""
+
+msgid "DeploymentTarget|Virtual machine (for example, EC2)"
+msgstr ""
+
msgid "Deployments"
msgstr ""
@@ -12107,6 +12289,9 @@ msgstr ""
msgid "Deployment|This deployment was created using the API"
msgstr ""
+msgid "Deployment|Triggerer"
+msgstr ""
+
msgid "Deployment|Waiting"
msgstr ""
@@ -12134,6 +12319,18 @@ msgstr ""
msgid "Deprecated API rate limits"
msgstr ""
+msgid "Deprecations|Feature deprecation and removal"
+msgstr ""
+
+msgid "Deprecations|For information on a possible replacement %{epicStart} learn more about Opstrace %{epicEnd}."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7 and are %{epicStart} scheduled for removal %{epicEnd} in GitLab 15.0."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7, and are %{removal_link_start} scheduled for removal %{link_end} in GitLab 15.0. For information on a possible replacement, %{opstrace_link_start} learn more about Opstrace %{link_end}."
+msgstr ""
+
msgid "Deprioritize label"
msgstr ""
@@ -12379,10 +12576,10 @@ msgstr ""
msgid "DevopsAdoption|At least one deploy"
msgstr ""
-msgid "DevopsAdoption|At least one issue opened"
+msgid "DevopsAdoption|At least one issue created"
msgstr ""
-msgid "DevopsAdoption|At least one merge request opened"
+msgid "DevopsAdoption|At least one merge request created"
msgstr ""
msgid "DevopsAdoption|At least one pipeline successfully run"
@@ -12583,6 +12780,9 @@ msgstr ""
msgid "Direct member"
msgstr ""
+msgid "Direct members"
+msgstr ""
+
msgid "Direct non-authenticated users to this page."
msgstr ""
@@ -12699,6 +12899,9 @@ msgid_plural "Dismiss %d selected vulnerabilities as"
msgstr[0] ""
msgstr[1] ""
+msgid "Dismiss Alert"
+msgstr ""
+
msgid "Dismiss merge request promotion"
msgstr ""
@@ -12726,9 +12929,15 @@ msgstr ""
msgid "Display alerts from all configured monitoring tools."
msgstr ""
+msgid "Display milestones"
+msgstr ""
+
msgid "Display name"
msgstr ""
+msgid "Display progress of child issues"
+msgstr ""
+
msgid "Display rendered file"
msgstr ""
@@ -12834,6 +13043,9 @@ msgstr ""
msgid "Download image"
msgstr ""
+msgid "Download payload"
+msgstr ""
+
msgid "Download raw data (.csv)"
msgstr ""
@@ -13011,6 +13223,9 @@ msgstr ""
msgid "Edit in Web IDE"
msgstr ""
+msgid "Edit in pipeline editor"
+msgstr ""
+
msgid "Edit in single-file editor"
msgstr ""
@@ -13053,6 +13268,9 @@ msgstr ""
msgid "Edit your most recent comment in a thread (from an empty textarea)"
msgstr ""
+msgid "Edit, lint, and visualize your pipeline."
+msgstr ""
+
msgid "Edited"
msgstr ""
@@ -13494,6 +13712,9 @@ msgstr ""
msgid "Enforce two-factor authentication for all user sign-ins."
msgstr ""
+msgid "Enhance security by storing service account keys in secret managers - learn more about %{docLinkStart}secret management with GitLab%{docLinkEnd}"
+msgstr ""
+
msgid "Ensure connectivity is available from the GitLab server to the Prometheus server"
msgstr ""
@@ -13554,6 +13775,9 @@ 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 following to confirm:"
+msgstr ""
+
msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
@@ -14084,9 +14308,6 @@ 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 ""
@@ -14222,6 +14443,9 @@ msgstr ""
msgid "Errors:"
msgstr ""
+msgid "Escalate this incident"
+msgstr ""
+
msgid "Escalation Policies"
msgstr ""
@@ -14234,6 +14458,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy"
+msgstr ""
+
msgid "Escalation policy:"
msgstr ""
@@ -14485,6 +14712,9 @@ msgstr ""
msgid "Existing sign in methods may be removed"
msgstr ""
+msgid "Exit."
+msgstr ""
+
msgid "Expand"
msgstr ""
@@ -14581,6 +14811,9 @@ msgstr ""
msgid "Explore public groups"
msgstr ""
+msgid "Explore public projects"
+msgstr ""
+
msgid "Explore snippets"
msgstr ""
@@ -14742,7 +14975,7 @@ msgid_plural "Failed to archive designs. Please try again."
msgstr[0] ""
msgstr[1] ""
-msgid "Failed to assign a reviewer because no user was found."
+msgid "Failed to assign a reviewer because no user was specified."
msgstr ""
msgid "Failed to assign a user because no user was found."
@@ -14808,10 +15041,10 @@ msgstr ""
msgid "Failed to find import label for Jira import."
msgstr ""
-msgid "Failed to generate export, please try again later."
+msgid "Failed to find users for %{missing}"
msgstr ""
-msgid "Failed to generate report, please try again after sometime"
+msgid "Failed to generate export, please try again later."
msgstr ""
msgid "Failed to get ref."
@@ -14910,6 +15143,9 @@ msgstr ""
msgid "Failed to remove a to-do item for the design."
msgstr ""
+msgid "Failed to remove attention because no user was found."
+msgstr ""
+
msgid "Failed to remove mirror."
msgstr ""
@@ -14922,6 +15158,9 @@ msgstr ""
msgid "Failed to remove user key."
msgstr ""
+msgid "Failed to request attention because no user was found."
+msgstr ""
+
msgid "Failed to reset key. Please try again."
msgstr ""
@@ -15003,6 +15242,9 @@ msgstr ""
msgid "Feature Flags"
msgstr ""
+msgid "Feature deprecation and removal"
+msgstr ""
+
msgid "Feature flag status"
msgstr ""
@@ -15500,7 +15742,7 @@ msgstr ""
msgid "For each job, re-use the project workspace. If the workspace doesn't exist, use %{code_open}git clone%{code_close}."
msgstr ""
-msgid "For example, the application using the token or the purpose of the token."
+msgid "For example, the application using the token or the purpose of the token. Do not give sensitive information for the name of the token, as it will be visible to all %{resource_type} members."
msgstr ""
msgid "For files larger than this limit, only index the file name. The file content is neither indexed nor searchable."
@@ -15584,9 +15826,6 @@ msgstr ""
msgid "ForkProject|Select a namespace"
msgstr ""
-msgid "ForkProject|Select a namespace to fork the project"
-msgstr ""
-
msgid "ForkProject|The project can be accessed by any logged in user."
msgstr ""
@@ -15683,6 +15922,9 @@ msgstr ""
msgid "Full name"
msgstr ""
+msgid "GCP region configured"
+msgstr ""
+
msgid "GPG Key ID:"
msgstr ""
@@ -15863,6 +16105,9 @@ msgstr ""
msgid "Geo|Failed"
msgstr ""
+msgid "Geo|Filter Geo sites"
+msgstr ""
+
msgid "Geo|Filter by name"
msgstr ""
@@ -16274,6 +16519,12 @@ msgstr ""
msgid "GitLab Issue"
msgstr ""
+msgid "GitLab KAS"
+msgstr ""
+
+msgid "GitLab Memberships CSV Export"
+msgstr ""
+
msgid "GitLab Pages"
msgstr ""
@@ -16322,6 +16573,9 @@ 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 free to use. Many features for larger teams are part of our %{link_start}paid products%{link_end}. You can try Ultimate for free without any obligation or payment details."
+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 ""
@@ -16448,7 +16702,7 @@ msgstr ""
msgid "GitLabPages|When enabled, all attempts to visit your website through HTTP are automatically redirected to HTTPS using a response with status code 301. Requires a valid certificate for all domains. %{docs_link_start}Learn more.%{link_end}"
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. %{docs_link_start}Learn more.%{link_end}"
+msgid "GitLabPages|When using Pages under the general domain of a GitLab instance (%{pages_host}), you cannot use HTTPS with subdomains of subdomains. If your namespace or groupname contains a dot, it does not work. This is a limitation of the HTTP Over TLS protocol. HTTP pages work if you don't redirect HTTP to HTTPS. %{docs_link_start}Learn more.%{link_end}"
msgstr ""
msgid "GitLabPages|With GitLab Pages you can host your static website directly from your GitLab repository. %{docs_link_start}Learn more.%{link_end}"
@@ -16625,9 +16879,6 @@ msgstr ""
msgid "Go to find file"
msgstr ""
-msgid "Go to fork"
-msgstr ""
-
msgid "Go to issue boards"
msgstr ""
@@ -16835,9 +17086,6 @@ msgstr ""
msgid "Group Hooks"
msgstr ""
-msgid "Group ID"
-msgstr ""
-
msgid "Group Owner must have signed in with SAML before enabling Group Managed Accounts"
msgstr ""
@@ -16865,9 +17113,6 @@ msgstr ""
msgid "Group by"
msgstr ""
-msgid "Group description"
-msgstr ""
-
msgid "Group description (optional)"
msgstr ""
@@ -16982,7 +17227,7 @@ msgstr ""
msgid "Group: %{name}"
msgstr ""
-msgid "GroupActivityMetrics|Issues opened"
+msgid "GroupActivityMetrics|Issues created"
msgstr ""
msgid "GroupActivityMetrics|Last 90 days"
@@ -16991,7 +17236,7 @@ msgstr ""
msgid "GroupActivityMetrics|Members added"
msgstr ""
-msgid "GroupActivityMetrics|Merge Requests opened"
+msgid "GroupActivityMetrics|Merge Requests created"
msgstr ""
msgid "GroupActivityMetrics|Recent activity"
@@ -17282,6 +17527,9 @@ msgstr ""
msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
+msgid "GroupSettings|Choose a group path that does not start with a dash or end with a period. It can also contain alphanumeric characters and underscores."
+msgstr ""
+
msgid "GroupSettings|Compliance frameworks"
msgstr ""
@@ -17315,7 +17563,7 @@ msgstr ""
msgid "GroupSettings|If not specified at the group or instance level, the default is %{default_initial_branch_name}. Does not affect existing repositories."
msgstr ""
-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."
+msgid "GroupSettings|If the parent group's visibility is lower than the group's current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility."
msgstr ""
msgid "GroupSettings|New runners registration token has been generated!"
@@ -17432,7 +17680,10 @@ msgstr ""
msgid "Groups and projects"
msgstr ""
-msgid "Groups and subgroups"
+msgid "Groups are a great way to organize projects and people."
+msgstr ""
+
+msgid "Groups are the best way to manage projects and members."
msgstr ""
msgid "Groups to synchronize"
@@ -17543,13 +17794,16 @@ msgstr ""
msgid "GroupsTree|Are you sure you want to leave the \"%{fullName}\" group?"
msgstr ""
-msgid "GroupsTree|Edit group"
+msgid "GroupsTree|Delete"
+msgstr ""
+
+msgid "GroupsTree|Edit"
msgstr ""
msgid "GroupsTree|Failed to leave the group. Please make sure you are not the only owner."
msgstr ""
-msgid "GroupsTree|Leave this group"
+msgid "GroupsTree|Leave group"
msgstr ""
msgid "GroupsTree|Loading groups"
@@ -17561,9 +17815,57 @@ msgstr ""
msgid "GroupsTree|No groups or projects matched your search"
msgstr ""
+msgid "GroupsTree|Options"
+msgstr ""
+
msgid "GroupsTree|Search by name"
msgstr ""
+msgid "Groups|Avatar will be removed. Are you sure?"
+msgstr ""
+
+msgid "Groups|Changing group URL can have unintended side effects."
+msgstr ""
+
+msgid "Groups|Checking group URL availability..."
+msgstr ""
+
+msgid "Groups|Enter a descriptive name for your group."
+msgstr ""
+
+msgid "Groups|Group ID"
+msgstr ""
+
+msgid "Groups|Group URL"
+msgstr ""
+
+msgid "Groups|Group avatar"
+msgstr ""
+
+msgid "Groups|Group description (optional)"
+msgstr ""
+
+msgid "Groups|Group name"
+msgstr ""
+
+msgid "Groups|Group path is available."
+msgstr ""
+
+msgid "Groups|Group path is unavailable. Path has been replaced with a suggested available path."
+msgstr ""
+
+msgid "Groups|Learn more"
+msgstr ""
+
+msgid "Groups|Must start with letter, digit, emoji, or underscore. Can also contain periods, dashes, spaces, and parentheses."
+msgstr ""
+
+msgid "Groups|Remove avatar"
+msgstr ""
+
+msgid "Groups|Save changes"
+msgstr ""
+
msgid "Guideline"
msgstr ""
@@ -17573,6 +17875,9 @@ msgstr ""
msgid "HAR file path or URL"
msgstr ""
+msgid "HTTP Archive (HAR)"
+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 ""
@@ -17973,6 +18278,9 @@ msgstr ""
msgid "INFO: Your SSH key is expiring soon. Please generate a new key."
msgstr ""
+msgid "IP"
+msgstr ""
+
msgid "IP Address"
msgstr ""
@@ -18009,6 +18317,9 @@ msgstr ""
msgid "IdentityVerification|Verify your identity"
msgstr ""
+msgid "IdentityVerification|You can always verify your account at a later time to create a group."
+msgstr ""
+
msgid "If any indexed field exceeds this limit, it is truncated to this number of characters. The rest of the content is neither indexed nor searchable. This does not apply to repository and wiki indexing. For unlimited characters, set this to 0."
msgstr ""
@@ -18066,6 +18377,9 @@ msgstr ""
msgid "If you add %{codeStart}needs%{codeEnd} to jobs in your pipeline you'll be able to view the %{codeStart}needs%{codeEnd} relationships between jobs in this tab as a %{linkStart}Directed Acyclic Graph (DAG)%{linkEnd}."
msgstr ""
+msgid "If you are added to a project, it will be displayed here."
+msgstr ""
+
msgid "If you did not initiate these sign-in attempts, please reach out to your administrator or enable two-factor authentication (2FA) on your account."
msgstr ""
@@ -18372,12 +18686,24 @@ msgstr ""
msgid "InProductMarketing|3 ways to dive into GitLab CI/CD"
msgstr ""
+msgid "InProductMarketing|A single application eliminates complex integrations, data chokepoints, and toolchain maintenance, resulting in greater productivity and lower cost."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features, build more efficiently, strengthen security and compliance."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features."
+msgstr ""
+
msgid "InProductMarketing|Actually, GitLab makes the team work (better)"
msgstr ""
msgid "InProductMarketing|And finally %{deploy_link} a Python application."
msgstr ""
+msgid "InProductMarketing|And many more..."
+msgstr ""
+
msgid "InProductMarketing|Are your runners ready?"
msgstr ""
@@ -18396,15 +18722,33 @@ msgstr ""
msgid "InProductMarketing|Blog"
msgstr ""
+msgid "InProductMarketing|Break down silos to coordinate seamlessly across development, operations, and security with a consistent experience across the development lifecycle."
+msgstr ""
+
+msgid "InProductMarketing|Burn up/down charts"
+msgstr ""
+
msgid "InProductMarketing|By enabling code owners and required merge approvals the right person will review the right MR. This is a win-win: cleaner code and a more efficient review process."
msgstr ""
msgid "InProductMarketing|Click on the number below that corresponds with your answer — 1 being very difficult, 5 being very easy."
msgstr ""
+msgid "InProductMarketing|Code owners"
+msgstr ""
+
msgid "InProductMarketing|Code owners and required merge approvals are part of the paid tiers of GitLab. You can start a free 30-day trial of GitLab Ultimate and enable these features in less than 5 minutes with no credit card required."
msgstr ""
+msgid "InProductMarketing|Code review analytics"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration across stages in GitLab"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration made easy"
+msgstr ""
+
msgid "InProductMarketing|Create a custom CI runner with just a few clicks"
msgstr ""
@@ -18414,12 +18758,21 @@ msgstr ""
msgid "InProductMarketing|Create a project in GitLab in 5 minutes"
msgstr ""
+msgid "InProductMarketing|Create well-defined workflows by using scoped labels on issues, merge requests, and epics. Labels with the same scope cannot be used together, which prevents conflicts."
+msgstr ""
+
msgid "InProductMarketing|Create your first project!"
msgstr ""
+msgid "InProductMarketing|Define who owns specific files or directories, so the right reviewers are suggested when a merge request introduces changes to those files."
+msgstr ""
+
msgid "InProductMarketing|Deliver Better Products Faster"
msgstr ""
+msgid "InProductMarketing|Dependency scanning"
+msgstr ""
+
msgid "InProductMarketing|Did you know teams that use GitLab are far more efficient?"
msgstr ""
@@ -18429,15 +18782,27 @@ msgstr ""
msgid "InProductMarketing|Dig in and create a project and a repo"
msgstr ""
+msgid "InProductMarketing|Discover Premium & Ultimate"
+msgstr ""
+
+msgid "InProductMarketing|Discover Premium & Ultimate."
+msgstr ""
+
msgid "InProductMarketing|Do you have a minute?"
msgstr ""
msgid "InProductMarketing|Do you have a teammate who would be perfect for this task?"
msgstr ""
+msgid "InProductMarketing|Dynamic application security testing"
+msgstr ""
+
msgid "InProductMarketing|Easy"
msgstr ""
+msgid "InProductMarketing|Epics"
+msgstr ""
+
msgid "InProductMarketing|Expand your DevOps journey with a free GitLab trial"
msgstr ""
@@ -18459,9 +18824,15 @@ msgstr ""
msgid "InProductMarketing|Feel the need for speed?"
msgstr ""
+msgid "InProductMarketing|Find and fix bottlenecks in your code review process by understanding how long open merge requests have been in review."
+msgstr ""
+
msgid "InProductMarketing|Find out how your teams are really doing"
msgstr ""
+msgid "InProductMarketing|Find out if your external libraries are safe. Run dependency scanning jobs that check for known vulnerabilities in your external libraries."
+msgstr ""
+
msgid "InProductMarketing|Follow our steps"
msgstr ""
@@ -18498,6 +18869,9 @@ msgstr ""
msgid "InProductMarketing|GitLab is better with teammates to help out!"
msgstr ""
+msgid "InProductMarketing|GitLab is infrastructure agnostic (supporting GCP, AWS, Azure, OpenShift, VMWare, On Prem, Bare Metal, and more), offering a consistent workflow experience – irrespective of the environment."
+msgstr ""
+
msgid "InProductMarketing|GitLab provides static application security testing (SAST), dynamic application security testing (DAST), container scanning, and dependency scanning to help you deliver secure applications along with license compliance."
msgstr ""
@@ -18588,21 +18962,36 @@ msgstr ""
msgid "InProductMarketing|It's also possible to simply %{external_repo_link} in order to take advantage of GitLab's CI/CD."
msgstr ""
+msgid "InProductMarketing|Keep your code quality high by defining who should approve merge requests and how many approvals are required."
+msgstr ""
+
msgid "InProductMarketing|Launch GitLab CI/CD in 20 minutes or less"
msgstr ""
+msgid "InProductMarketing|Lower cost of development"
+msgstr ""
+
+msgid "InProductMarketing|Make it easier to collaborate on high-level ideas by grouping related issues in an epic."
+msgstr ""
+
msgid "InProductMarketing|Making the switch? It's easier than you think to import your projects into GitLab. Move %{github_link}, or import something %{bitbucket_link}."
msgstr ""
msgid "InProductMarketing|Master the art of importing!"
msgstr ""
+msgid "InProductMarketing|Merge request approval rule"
+msgstr ""
+
msgid "InProductMarketing|Move on to easily creating a Pages website %{ci_template_link}"
msgstr ""
msgid "InProductMarketing|Multiple owners, confusing workstreams? We've got you covered"
msgstr ""
+msgid "InProductMarketing|Multiple required approvers"
+msgstr ""
+
msgid "InProductMarketing|Need an alternative to importing?"
msgstr ""
@@ -18615,18 +19004,33 @@ msgstr ""
msgid "InProductMarketing|Our tool brings all the things together"
msgstr ""
+msgid "InProductMarketing|Protect your web application by using DAST to examine for vulnerabilities in deployed environments."
+msgstr ""
+
msgid "InProductMarketing|Rapid development, simplified"
msgstr ""
msgid "InProductMarketing|Reduce Security & Compliance Risk"
msgstr ""
+msgid "InProductMarketing|Require multiple approvers on a merge request, so you know it's in good shape before it's merged."
+msgstr ""
+
+msgid "InProductMarketing|Roadmaps"
+msgstr ""
+
+msgid "InProductMarketing|Scoped labels"
+msgstr ""
+
msgid "InProductMarketing|Security that's integrated into your development lifecycle"
msgstr ""
msgid "InProductMarketing|Sometimes you're not ready to make a full transition to a new tool. If you're not ready to fully commit, %{mirroring_link} gives you a safe way to try out GitLab in parallel with your current tool."
msgstr ""
+msgid "InProductMarketing|Speed. Efficiency. Trust."
+msgstr ""
+
msgid "InProductMarketing|Spin up an autoscaling runner in GitLab"
msgstr ""
@@ -18636,6 +19040,9 @@ msgstr ""
msgid "InProductMarketing|Start a Self-Managed trial"
msgstr ""
+msgid "InProductMarketing|Start a free trial"
+msgstr ""
+
msgid "InProductMarketing|Start a free trial of GitLab Ultimate – no credit card required"
msgstr ""
@@ -18702,6 +19109,9 @@ msgstr ""
msgid "InProductMarketing|To understand and get the most out of GitLab, start at the beginning and %{project_link}. In GitLab, repositories are part of a project, so after you've created your project you can go ahead and %{repo_link}."
msgstr ""
+msgid "InProductMarketing|Track completed issues in a chart, so you can see how a milestone is progressing at a glance."
+msgstr ""
+
msgid "InProductMarketing|Try GitLab Ultimate for free"
msgstr ""
@@ -18738,6 +19148,9 @@ msgstr ""
msgid "InProductMarketing|Very easy"
msgstr ""
+msgid "InProductMarketing|Visualize your epics and milestones in a timeline."
+msgstr ""
+
msgid "InProductMarketing|Want to host GitLab on your servers?"
msgstr ""
@@ -18759,6 +19172,9 @@ msgstr ""
msgid "InProductMarketing|YouTube"
msgstr ""
+msgid "InProductMarketing|Your software, deployed your way"
+msgstr ""
+
msgid "InProductMarketing|Your teams can be more efficient"
msgstr ""
@@ -18879,9 +19295,18 @@ msgstr ""
msgid "IncidentManagement|No incidents to display."
msgstr ""
+msgid "IncidentManagement|None"
+msgstr ""
+
msgid "IncidentManagement|Open"
msgstr ""
+msgid "IncidentManagement|Page your team with escalation policies"
+msgstr ""
+
+msgid "IncidentManagement|Paged"
+msgstr ""
+
msgid "IncidentManagement|Published"
msgstr ""
@@ -18891,6 +19316,9 @@ msgstr ""
msgid "IncidentManagement|Severity"
msgstr ""
+msgid "IncidentManagement|Status"
+msgstr ""
+
msgid "IncidentManagement|There are no closed incidents"
msgstr ""
@@ -18909,6 +19337,9 @@ msgstr ""
msgid "IncidentManagement|Unpublished"
msgstr ""
+msgid "IncidentManagement|Use escalation policies to automatically page your team when incidents are created."
+msgstr ""
+
msgid "IncidentSettings|Activate \"time to SLA\" countdown timer"
msgstr ""
@@ -18954,7 +19385,10 @@ msgstr ""
msgid "Incidents"
msgstr ""
-msgid "Incidents|Add a URL"
+msgid "Incidents|Add image details"
+msgstr ""
+
+msgid "Incidents|Add text or a link to display with your image. If you don't add either, the file name displays instead."
msgstr ""
msgid "Incidents|Drop or %{linkStart}upload%{linkEnd} a metric screenshot to attach it to the incident"
@@ -18969,10 +19403,10 @@ msgstr ""
msgid "Incidents|There was an issue loading metric images."
msgstr ""
-msgid "Incidents|There was an issue uploading your image."
+msgid "Incidents|There was an issue updating your image."
msgstr ""
-msgid "Incidents|You can optionally add a URL to link users to the original graph."
+msgid "Incidents|There was an issue uploading your image."
msgstr ""
msgid "Incident|Alert details"
@@ -18981,9 +19415,18 @@ msgstr ""
msgid "Incident|Are you sure you wish to delete this image?"
msgstr ""
+msgid "Incident|Delete image"
+msgstr ""
+
msgid "Incident|Deleting %{filename}"
msgstr ""
+msgid "Incident|Edit image text or link"
+msgstr ""
+
+msgid "Incident|Editing %{filename}"
+msgstr ""
+
msgid "Incident|Metrics"
msgstr ""
@@ -19253,12 +19696,18 @@ msgstr ""
msgid "Integrations|Branches for which notifications are to be sent"
msgstr ""
+msgid "Integrations|Clear if using a self-signed certificate."
+msgstr ""
+
msgid "Integrations|Comment detail:"
msgstr ""
msgid "Integrations|Comment settings:"
msgstr ""
+msgid "Integrations|Connection details"
+msgstr ""
+
msgid "Integrations|Connection failed. Please check your settings."
msgstr ""
@@ -19283,6 +19732,9 @@ msgstr ""
msgid "Integrations|Enable GitLab.com slash commands in a Slack workspace."
msgstr ""
+msgid "Integrations|Enable SSL verification"
+msgstr ""
+
msgid "Integrations|Enable comments"
msgstr ""
@@ -19361,6 +19813,9 @@ msgstr ""
msgid "Integrations|Return to GitLab for Jira"
msgstr ""
+msgid "Integrations|SSL verification"
+msgstr ""
+
msgid "Integrations|Save settings?"
msgstr ""
@@ -19406,9 +19861,6 @@ msgstr ""
msgid "Integrations|Use default settings"
msgstr ""
-msgid "Integrations|When you mention a Jira issue in a commit or merge request, GitLab creates a remote link and comment (if enabled)."
-msgstr ""
-
msgid "Integrations|You can now close this window and return to the GitLab for Jira application."
msgstr ""
@@ -19433,9 +19885,6 @@ msgstr ""
msgid "Integrations|can't exceed %{recipients_limit}"
msgstr ""
-msgid "Interactive developer security education."
-msgstr ""
-
msgid "Interactive mode"
msgstr ""
@@ -19925,6 +20374,9 @@ msgstr ""
msgid "IssueAnalytics|Assignees"
msgstr ""
+msgid "IssueAnalytics|Created by"
+msgstr ""
+
msgid "IssueAnalytics|Due date"
msgstr ""
@@ -19937,9 +20389,6 @@ msgstr ""
msgid "IssueAnalytics|Milestone"
msgstr ""
-msgid "IssueAnalytics|Opened by"
-msgstr ""
-
msgid "IssueAnalytics|Status"
msgstr ""
@@ -20063,10 +20512,10 @@ msgstr ""
msgid "IssuesAnalytics|Avg/Month:"
msgstr ""
-msgid "IssuesAnalytics|Issues opened"
+msgid "IssuesAnalytics|Issues created"
msgstr ""
-msgid "IssuesAnalytics|Issues opened per month"
+msgid "IssuesAnalytics|Issues created per month"
msgstr ""
msgid "IssuesAnalytics|Last 12 months"
@@ -20093,6 +20542,9 @@ msgstr ""
msgid "It looks like you have some draft commits in this branch."
msgstr ""
+msgid "It looks like you're attempting to activate your subscription. Use %{a_start}the Subscription page%{a_end} instead."
+msgstr ""
+
msgid "It may be several days before you see feature usage data."
msgstr ""
@@ -20321,6 +20773,9 @@ msgstr ""
msgid "JiraConnect|You can now close this window and return to Jira."
msgstr ""
+msgid "JiraConnect|You don't have permission to create branches for this project. Select a different project or contact the project owner for access. %{linkStart}Learn more.%{linkEnd}"
+msgstr ""
+
msgid "JiraRequest|A connection error occurred while connecting to Jira. Try your request again."
msgstr ""
@@ -20369,13 +20824,13 @@ msgstr ""
msgid "JiraService|Define the type of Jira issue to create from a vulnerability."
msgstr ""
-msgid "JiraService|Displaying Jira issues while leaving the GitLab issue functionality enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
+msgid "JiraService|Displaying Jira issues while leaving GitLab issues also enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
msgstr ""
-msgid "JiraService|Enable Jira issues"
+msgid "JiraService|Enable Jira issue creation from vulnerabilities"
msgstr ""
-msgid "JiraService|Enable Jira issues creation from vulnerabilities"
+msgid "JiraService|Enable Jira issues"
msgstr ""
msgid "JiraService|Enable Jira transitions"
@@ -20492,16 +20947,19 @@ msgstr ""
msgid "JiraService|View Jira issues in GitLab"
msgstr ""
-msgid "JiraService|Warning: All GitLab users that have access to this GitLab project are able to view all issues from the Jira project specified below."
+msgid "JiraService|Warning: All GitLab users with access to this GitLab project can view all issues from the Jira project you select."
msgstr ""
msgid "JiraService|Web URL"
msgstr ""
-msgid "JiraService|Work on Jira issues without leaving GitLab. Adds a Jira menu to access your list of Jira issues and view any issue as read-only."
+msgid "JiraService|When a Jira issue is mentioned in a commit or merge request, a remote link and comment (if enabled) will be created."
+msgstr ""
+
+msgid "JiraService|Work on Jira issues without leaving GitLab. Add a Jira menu to access a read-only list of your Jira issues."
msgstr ""
-msgid "JiraService|You need to configure Jira before enabling this integration. For more details, read the %{jira_doc_link_start}Jira integration documentation%{link_end}."
+msgid "JiraService|You must configure Jira before enabling this integration. %{jira_doc_link_start}Learn more.%{link_end}"
msgstr ""
msgid "Job"
@@ -20513,9 +20971,6 @@ msgstr ""
msgid "Job Failed #%{build_id}"
msgstr ""
-msgid "Job ID"
-msgstr ""
-
msgid "Job artifact"
msgstr ""
@@ -20582,9 +21037,27 @@ msgstr ""
msgid "Jobs|You're about to retry a job that failed because it attempted to deploy code that is older than the latest deployment. Retrying this job could result in overwriting the environment with the older source code."
msgstr ""
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source} into %{target}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{ref}"
+msgstr ""
+
+msgid "Job|Are you sure you want to erase this job log and artifacts?"
+msgstr ""
+
msgid "Job|Browse"
msgstr ""
+msgid "Job|Cancel"
+msgstr ""
+
msgid "Job|Complete Raw"
msgstr ""
@@ -20594,6 +21067,9 @@ msgstr ""
msgid "Job|Erase job log and artifacts"
msgstr ""
+msgid "Job|Finished at"
+msgstr ""
+
msgid "Job|Job artifacts"
msgstr ""
@@ -20606,7 +21082,7 @@ msgstr ""
msgid "Job|Keep"
msgstr ""
-msgid "Job|Pipeline"
+msgid "Job|Retry"
msgstr ""
msgid "Job|Scroll to bottom"
@@ -20618,6 +21094,9 @@ msgstr ""
msgid "Job|Show complete raw"
msgstr ""
+msgid "Job|Status"
+msgstr ""
+
msgid "Job|The artifacts were removed"
msgstr ""
@@ -20645,21 +21124,12 @@ msgstr ""
msgid "Job|delayed"
msgstr ""
-msgid "Job|for"
-msgstr ""
-
-msgid "Job|into"
-msgstr ""
-
msgid "Job|manual"
msgstr ""
msgid "Job|triggered"
msgstr ""
-msgid "Job|with"
-msgstr ""
-
msgid "Join Zoom meeting"
msgstr ""
@@ -20762,9 +21232,6 @@ msgstr ""
msgid "Ki"
msgstr ""
-msgid "Kontra"
-msgstr ""
-
msgid "Kroki"
msgstr ""
@@ -21088,6 +21555,9 @@ msgstr ""
msgid "Learn more about Auto DevOps"
msgstr ""
+msgid "Learn more about GitLab"
+msgstr ""
+
msgid "Learn more about Needs relationships"
msgstr ""
@@ -21415,9 +21885,18 @@ msgstr ""
msgid "Licenses|Displays licenses detected in the project, based on the %{linkStart}latest successful%{linkEnd} scan"
msgstr ""
+msgid "Licenses|Drag your license file here or %{linkStart}click to upload%{linkEnd}."
+msgstr ""
+
+msgid "Licenses|Drop your license file to start the upload."
+msgstr ""
+
msgid "Licenses|Error fetching the license list. Please check your network connection and try again."
msgstr ""
+msgid "Licenses|Error: You are trying to upload something other than a file"
+msgstr ""
+
msgid "Licenses|License Compliance"
msgstr ""
@@ -21436,6 +21915,9 @@ msgstr ""
msgid "Licenses|Specified policies in this project"
msgstr ""
+msgid "Licenses|The file could not be uploaded."
+msgstr ""
+
msgid "Licenses|The license list details information about the licenses used within your project."
msgstr ""
@@ -21469,11 +21951,6 @@ msgstr ""
msgid "Limit the size of Sidekiq jobs stored in Redis."
msgstr ""
-msgid "Limited to showing %d event at most"
-msgid_plural "Limited to showing %d events at most"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Limiting mode"
msgstr ""
@@ -21483,6 +21960,9 @@ msgstr ""
msgid "Link"
msgstr ""
+msgid "Link (optional)"
+msgstr ""
+
msgid "Link Prometheus monitoring to GitLab."
msgstr ""
@@ -21519,6 +21999,9 @@ msgstr ""
msgid "Linked emails (%{email_count})"
msgstr ""
+msgid "Linked epics"
+msgstr ""
+
msgid "Linked issues"
msgstr ""
@@ -21546,6 +22029,15 @@ msgstr ""
msgid "List of all merge commits"
msgstr ""
+msgid "List of environments for this project"
+msgstr ""
+
+msgid "List of suitable GCP locations"
+msgstr ""
+
+msgid "List of users allowed to exceed the rate limit."
+msgstr ""
+
msgid "List options"
msgstr ""
@@ -21765,6 +22257,9 @@ msgstr ""
msgid "Maintenance mode"
msgstr ""
+msgid "Make adjustments to how your GitLab instance is set up."
+msgstr ""
+
msgid "Make and review changes in the browser with the Web IDE"
msgstr ""
@@ -21909,6 +22404,12 @@ msgstr ""
msgid "MarkdownEditor|Add italic text (%{modifier_key}I)"
msgstr ""
+msgid "MarkdownEditor|Add strikethrough text (%{modifierKey}⇧X)"
+msgstr ""
+
+msgid "MarkdownEditor|Add strikethrough text (%{modifier_key}⇧X)"
+msgstr ""
+
msgid "Marked For Deletion At - %{deletion_time}"
msgstr ""
@@ -22170,6 +22671,9 @@ msgstr ""
msgid "Maximum push size (MB)"
msgstr ""
+msgid "Maximum requests per 10 minutes per user"
+msgstr ""
+
msgid "Maximum requests per minute"
msgstr ""
@@ -22260,6 +22764,19 @@ msgstr ""
msgid "Members of a group may only view projects they have permission to access"
msgstr ""
+msgid "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seat in use and will be billed for the overage."
+msgid_plural "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seats in use and will be billed for the overage."
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "MembersOverage|You are about to incur additional charges"
+msgstr ""
+
+msgid "MembersOverage|Your subscription includes %d seat."
+msgid_plural "MembersOverage|Your subscription includes %d seats."
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Membership"
msgstr ""
@@ -22464,9 +22981,6 @@ msgstr ""
msgid "Merge request not merged"
msgstr ""
-msgid "Merge request pipelines 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 merge request pipelines."
-msgstr ""
-
msgid "Merge request reports"
msgstr ""
@@ -22563,13 +23077,13 @@ msgstr ""
msgid "MergeRequests|Create issue to resolve thread"
msgstr ""
-msgid "MergeRequests|Failed to squash. Should be done manually."
+msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Saving the comment failed"
+msgid "MergeRequests|Squashing failed: Squash the commits locally, resolve any conflicts, then push the branch."
msgstr ""
-msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
+msgid "MergeRequests|Squashing not allowed: This project doesn't allow you to squash commits when merging."
msgstr ""
msgid "MergeRequests|Thread stays resolved"
@@ -23410,6 +23924,18 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "MrList|Assigned to %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from assignee %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from reviewer %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Review requested from %{name}, go to their profile."
+msgstr ""
+
msgid "Multi-project"
msgstr ""
@@ -23443,7 +23969,7 @@ msgstr ""
msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "My Awesome Group"
+msgid "My awesome group"
msgstr ""
msgid "My company or team"
@@ -24065,9 +24591,6 @@ msgstr ""
msgid "No available branches"
msgstr ""
-msgid "No available groups to fork the project."
-msgstr ""
-
msgid "No branches found"
msgstr ""
@@ -24278,6 +24801,9 @@ msgstr ""
msgid "No ref selected"
msgstr ""
+msgid "No regions configured"
+msgstr ""
+
msgid "No related merge requests found."
msgstr ""
@@ -25082,6 +25608,9 @@ msgstr ""
msgid "Only reCAPTCHA v2 is supported:"
msgstr ""
+msgid "Only required if not using role instance credentials."
+msgstr ""
+
msgid "Only use lowercase letters, numbers, and underscores."
msgstr ""
@@ -25106,9 +25635,6 @@ msgstr ""
msgid "Open a CLI and connect to the cluster you want to install the agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
-msgid "Open epics"
-msgstr ""
-
msgid "Open errors"
msgstr ""
@@ -25148,7 +25674,7 @@ msgstr ""
msgid "Opened issues"
msgstr ""
-msgid "OpenedNDaysAgo|Opened"
+msgid "OpenedNDaysAgo|Created"
msgstr ""
msgid "Opens in a new window"
@@ -25193,9 +25719,6 @@ msgstr ""
msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
-msgid "Optional."
-msgstr ""
-
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
msgstr ""
@@ -25984,6 +26507,9 @@ msgstr ""
msgid "PerformanceBar|Memory"
msgstr ""
+msgid "PerformanceBar|Memory report"
+msgstr ""
+
msgid "PerformanceBar|Redis calls"
msgstr ""
@@ -26017,18 +26543,12 @@ msgstr ""
msgid "PerformanceBar|wall"
msgstr ""
-msgid "Performs a rebase but skips triggering a new pipeline"
-msgstr ""
-
msgid "Period in seconds"
msgstr ""
msgid "Permalink"
msgstr ""
-msgid "Permanently delete project"
-msgstr ""
-
msgid "Permanently remove group"
msgstr ""
@@ -26299,6 +26819,51 @@ msgstr ""
msgid "PipelineStatusTooltip|Pipeline: %{ci_status}"
msgstr ""
+msgid "PipelineWizardDefaultCommitMessage|Add %{filename}"
+msgstr ""
+
+msgid "PipelineWizardDefaultCommitMessage|Update %{filename}"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|At least one entry is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This field is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This value is not valid"
+msgstr ""
+
+msgid "PipelineWizardListWidget|add another step"
+msgstr ""
+
+msgid "PipelineWizardListWidget|remove step"
+msgstr ""
+
+msgid "PipelineWizard|Commit"
+msgstr ""
+
+msgid "PipelineWizard|Commit Message"
+msgstr ""
+
+msgid "PipelineWizard|Commit changes to your file"
+msgstr ""
+
+msgid "PipelineWizard|Commit file to Branch"
+msgstr ""
+
+msgid "PipelineWizard|Commit your new file"
+msgstr ""
+
+msgid "PipelineWizard|The file has been committed."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem committing the changes."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem while checking whether your file already exists in the specified branch."
+msgstr ""
+
msgid "Pipelines"
msgstr ""
@@ -26413,7 +26978,7 @@ msgstr ""
msgid "Pipelines|Project cache successfully reset."
msgstr ""
-msgid "Pipelines|Revoke"
+msgid "Pipelines|Revoke trigger"
msgstr ""
msgid "Pipelines|Something went wrong while cleaning runners cache."
@@ -26458,6 +27023,12 @@ msgstr ""
msgid "Pipelines|This is a child pipeline within the parent pipeline"
msgstr ""
+msgid "Pipelines|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipelines|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipelines|This pipeline will run code originating from a forked project merge request. This means that the code can potentially have security considerations like exposing CI variables."
msgstr ""
@@ -26500,9 +27071,6 @@ msgstr ""
msgid "Pipelines|Your changes have been successfully committed. Now redirecting to the new merge request page."
msgstr ""
-msgid "Pipelines|detached"
-msgstr ""
-
msgid "Pipelines|error"
msgstr ""
@@ -26512,10 +27080,13 @@ msgstr ""
msgid "Pipelines|latest"
msgstr ""
-msgid "Pipelines|stuck"
+msgid "Pipelines|merge request"
msgstr ""
-msgid "Pipelines|train"
+msgid "Pipelines|merge train"
+msgstr ""
+
+msgid "Pipelines|stuck"
msgstr ""
msgid "Pipelines|yaml invalid"
@@ -26647,6 +27218,12 @@ msgstr ""
msgid "Pipeline|This change will not change the overall test coverage if merged."
msgstr ""
+msgid "Pipeline|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipeline|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipeline|Trigger author"
msgstr ""
@@ -26671,6 +27248,12 @@ msgstr ""
msgid "Pipeline|for"
msgstr ""
+msgid "Pipeline|merge request"
+msgstr ""
+
+msgid "Pipeline|merge train"
+msgstr ""
+
msgid "Pipeline|on"
msgstr ""
@@ -26809,9 +27392,6 @@ msgstr ""
msgid "Please enter a valid time interval"
msgstr ""
-msgid "Please enter or upload a valid license."
-msgstr ""
-
msgid "Please enter your current password."
msgstr ""
@@ -26920,9 +27500,6 @@ msgstr ""
msgid "Please type %{phrase_code} to proceed or close this modal to cancel."
msgstr ""
-msgid "Please type the following to confirm:"
-msgstr ""
-
msgid "Please use this form to report to the admin users who create spam issues, comments or behave inappropriately."
msgstr ""
@@ -26950,12 +27527,27 @@ msgstr ""
msgid "Policies"
msgstr ""
+msgid "Policy '%{escalation_policy_name}' does not exist."
+msgstr ""
+
msgid "Policy management project does have any policies in %{policy_path}"
msgstr ""
msgid "Policy project doesn't exist"
msgstr ""
+msgid "PolicyRuleMultiSelect|%{firstLabel} +%{numberOfAdditionalLabels} more"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|All %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select all"
+msgstr ""
+
msgid "Polling interval multiplier"
msgstr ""
@@ -27184,6 +27776,9 @@ msgstr ""
msgid "Private projects can be created in your personal namespace with:"
msgstr ""
+msgid "Problem with %{name} command: %{message}."
+msgstr ""
+
msgid "Proceed"
msgstr ""
@@ -27658,6 +28253,9 @@ msgstr ""
msgid "Progress"
msgstr ""
+msgid "Progress tracking"
+msgstr ""
+
msgid "Project"
msgstr ""
@@ -27889,6 +28487,9 @@ msgstr ""
msgid "ProjectQualitySummary|Failure"
msgstr ""
+msgid "ProjectQualitySummary|Get insight into the overall percentage of tests in your project that succeed, fail and are skipped."
+msgstr ""
+
msgid "ProjectQualitySummary|Latest pipeline results"
msgstr ""
@@ -27907,6 +28508,12 @@ msgstr ""
msgid "ProjectQualitySummary|See project Code Coverage Statistics"
msgstr ""
+msgid "ProjectQualitySummary|Set up test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|Set up test runs (opens in a new tab)"
+msgstr ""
+
msgid "ProjectQualitySummary|Skipped"
msgstr ""
@@ -28183,13 +28790,19 @@ msgstr ""
msgid "ProjectSettings|LFS objects from this repository are available to forks. %{linkStart}How do I remove them?%{linkEnd}"
msgstr ""
+msgid "ProjectSettings|Learn about commit history."
+msgstr ""
+
+msgid "ProjectSettings|Leave empty to use default template."
+msgstr ""
+
msgid "ProjectSettings|Manage who can see the project in the public access directory."
msgstr ""
msgid "ProjectSettings|Manages large files such as audio, video, and graphics files."
msgstr ""
-msgid "ProjectSettings|Maximum 500 characters."
+msgid "ProjectSettings|Maximum %{maxLength} characters."
msgstr ""
msgid "ProjectSettings|Merge checks"
@@ -28330,6 +28943,9 @@ msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
msgstr ""
+msgid "ProjectSettings|The default template will be applied on save."
+msgstr ""
+
msgid "ProjectSettings|These checks must pass before merge requests can be merged."
msgstr ""
@@ -28384,6 +29000,9 @@ msgstr ""
msgid "ProjectSettings|What are badges?"
msgstr ""
+msgid "ProjectSettings|What are merge trains?"
+msgstr ""
+
msgid "ProjectSettings|When merge request pipelines are enabled in the CI/CD configuration file, pipelines validate the combined results of the source and target branches. %{link_start}How to configure merge request pipelines?%{link_end}"
msgstr ""
@@ -28501,6 +29120,9 @@ msgstr ""
msgid "Projects are organized into groups"
msgstr ""
+msgid "Projects are where you store your code, access issues, wiki and other features of GitLab."
+msgstr ""
+
msgid "Projects contributed to"
msgstr ""
@@ -28516,12 +29138,6 @@ msgstr ""
msgid "Projects to index"
msgstr ""
-msgid "Projects will be permanently deleted after a %{waiting_period}-day waiting period."
-msgstr ""
-
-msgid "Projects will be permanently deleted immediately."
-msgstr ""
-
msgid "Projects with critical vulnerabilities"
msgstr ""
@@ -28606,6 +29222,9 @@ msgstr ""
msgid "ProjectsNew|Import project"
msgstr ""
+msgid "ProjectsNew|Include a Getting Started README"
+msgstr ""
+
msgid "ProjectsNew|Initialize repository with a README"
msgstr ""
@@ -28621,6 +29240,9 @@ msgstr ""
msgid "ProjectsNew|Project description %{tag_start}(optional)%{tag_end}"
msgstr ""
+msgid "ProjectsNew|Recommended if you're new to GitLab"
+msgstr ""
+
msgid "ProjectsNew|Run CI/CD for external repository"
msgstr ""
@@ -29038,6 +29660,9 @@ msgstr ""
msgid "ProtectedBranch|Unprotect"
msgstr ""
+msgid "ProtectedBranch|Unprotect branch"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
@@ -29065,6 +29690,9 @@ msgstr ""
msgid "ProtectedEnvironment|Protected Environment (%{protected_environments_count})"
msgstr ""
+msgid "ProtectedEnvironment|Required approvals"
+msgstr ""
+
msgid "ProtectedEnvironment|Select an environment"
msgstr ""
@@ -29086,10 +29714,13 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|Unprotect tag"
+msgstr ""
+
msgid "ProtectedTags|default"
msgstr ""
-msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
+msgid "ProtectedTag|By default, protected tags restrict who can modify the tag."
msgstr ""
msgid "ProtectedTag|Learn more."
@@ -29152,6 +29783,9 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Public projects are an easy way to allow everyone to have read-only access."
+msgstr ""
+
msgid "Publish to status page"
msgstr ""
@@ -29308,9 +29942,6 @@ msgstr ""
msgid "QualitySummary|Project quality"
msgstr ""
-msgid "Quarters"
-msgstr ""
-
msgid "Query"
msgstr ""
@@ -29395,6 +30026,9 @@ msgstr ""
msgid "Read more about project permissions %{help_link_open}here%{help_link_close}"
msgstr ""
+msgid "Read more about related epics"
+msgstr ""
+
msgid "Read more about related issues"
msgstr ""
@@ -29425,10 +30059,7 @@ msgstr ""
msgid "Rebase source branch on the target branch."
msgstr ""
-msgid "Rebase without CI"
-msgstr ""
-
-msgid "Rebases and triggers a pipeline"
+msgid "Rebase without pipeline"
msgstr ""
msgid "Recaptcha verified?"
@@ -29479,9 +30110,6 @@ msgstr ""
msgid "Reconfigure"
msgstr ""
-msgid "Recovering projects"
-msgstr ""
-
msgid "Recovery Codes"
msgstr ""
@@ -29541,6 +30169,12 @@ msgstr ""
msgid "Regex pattern"
msgstr ""
+msgid "Region"
+msgstr ""
+
+msgid "Regions"
+msgstr ""
+
msgid "Register"
msgstr ""
@@ -29771,9 +30405,6 @@ msgstr ""
msgid "Remove all or specific reviewer(s)"
msgstr ""
-msgid "Remove approver"
-msgstr ""
-
msgid "Remove approvers"
msgstr ""
@@ -29789,6 +30420,9 @@ msgstr ""
msgid "Remove attention request"
msgstr ""
+msgid "Remove attention request(s)"
+msgstr ""
+
msgid "Remove avatar"
msgstr ""
@@ -29927,6 +30561,9 @@ msgstr ""
msgid "Removed an issue from an epic."
msgstr ""
+msgid "Removed attention from %{users_sentence}."
+msgstr ""
+
msgid "Removed attention request from @%{username}"
msgstr ""
@@ -29978,6 +30615,9 @@ msgstr ""
msgid "Removes an issue from an epic."
msgstr ""
+msgid "Removes attention from %{users_sentence}."
+msgstr ""
+
msgid "Removes parent epic %{epic_ref}."
msgstr ""
@@ -30089,6 +30729,9 @@ msgstr ""
msgid "Report abuse to admin"
msgstr ""
+msgid "Report is generating and will be sent to your email address."
+msgstr ""
+
msgid "Reported %{timeAgo} by %{reportedBy}"
msgstr ""
@@ -30378,6 +31021,15 @@ msgstr ""
msgid "Request attention"
msgstr ""
+msgid "Request attention from %{users_sentence}."
+msgstr ""
+
+msgid "Request attention from assignee or reviewer"
+msgstr ""
+
+msgid "Request attention from assignee(s) or reviewer(s)"
+msgstr ""
+
msgid "Request attention to review"
msgstr ""
@@ -30402,6 +31054,9 @@ msgstr ""
msgid "Requested %{time_ago}"
msgstr ""
+msgid "Requested attention from %{users_sentence}."
+msgstr ""
+
msgid "Requested attention from @%{username}"
msgstr ""
@@ -30616,6 +31271,9 @@ msgstr ""
msgid "Restore project"
msgstr ""
+msgid "Restoring projects"
+msgstr ""
+
msgid "Restoring the group will prevent the group, its subgroups and projects from being removed on this date."
msgstr ""
@@ -30646,6 +31304,9 @@ msgstr ""
msgid "Retry"
msgstr ""
+msgid "Retry failed jobs"
+msgstr ""
+
msgid "Retry job"
msgstr ""
@@ -30693,9 +31354,6 @@ msgstr ""
msgid "Review changes"
msgstr ""
-msgid "Review requested from %{name}"
-msgstr ""
-
msgid "Review requests for you"
msgstr ""
@@ -30860,6 +31518,9 @@ msgstr ""
msgid "Runners|Assigned Group"
msgstr ""
+msgid "Runners|Assigned Projects (%{projectCount})"
+msgstr ""
+
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30929,6 +31590,9 @@ msgstr ""
msgid "Runners|Instance"
msgstr ""
+msgid "Runners|Jobs"
+msgstr ""
+
msgid "Runners|Last contact"
msgstr ""
@@ -31022,9 +31686,6 @@ msgstr ""
msgid "Runners|Runner %{name} was deleted"
msgstr ""
-msgid "Runners|Runner ID"
-msgstr ""
-
msgid "Runners|Runner assigned to project."
msgstr ""
@@ -31172,6 +31833,9 @@ msgstr ""
msgid "Runners|stale"
msgstr ""
+msgid "Runner|This runner has not run any jobs."
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -31286,6 +31950,24 @@ msgstr ""
msgid "Saving project."
msgstr ""
+msgid "ScanResultPolicy|%{ifLabelStart}if%{ifLabelEnd} %{scanners} scan in an open merge request targeting the %{branches} branch(es) finds %{vulnerabilitiesAllowed} or more %{severities} vulnerabilities that are %{vulnerabilityStates}"
+msgstr ""
+
+msgid "ScanResultPolicy|%{thenLabelStart}Then%{thenLabelEnd} Require approval from %{approvalsRequired} of the following approvers: %{approvers}"
+msgstr ""
+
+msgid "ScanResultPolicy|add an approver"
+msgstr ""
+
+msgid "ScanResultPolicy|scanners"
+msgstr ""
+
+msgid "ScanResultPolicy|severity levels"
+msgstr ""
+
+msgid "ScanResultPolicy|vulnerability states"
+msgstr ""
+
msgid "Scanner"
msgstr ""
@@ -31418,6 +32100,9 @@ msgstr ""
msgid "Search for a user"
msgstr ""
+msgid "Search for an emoji"
+msgstr ""
+
msgid "Search for projects, issues, etc."
msgstr ""
@@ -31605,18 +32290,12 @@ msgstr ""
msgid "Secret Detection"
msgstr ""
-msgid "Secret access key"
-msgstr ""
-
msgid "Secret token"
msgstr ""
msgid "Secure token that identifies an external storage request."
msgstr ""
-msgid "SecureCodeWarrior"
-msgstr ""
-
msgid "Security"
msgstr ""
@@ -31641,9 +32320,6 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "Security training with guide and learning pathways."
-msgstr ""
-
msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
@@ -31746,7 +32422,7 @@ msgstr ""
msgid "SecurityConfiguration|Manage corpus"
msgstr ""
-msgid "SecurityConfiguration|Manage corpus files used as mutation sources in coverage fuzzing."
+msgid "SecurityConfiguration|Manage corpus files used as seed inputs with coverage-guided fuzzing."
msgstr ""
msgid "SecurityConfiguration|Manage profiles for use by DAST scans."
@@ -31812,15 +32488,15 @@ msgstr ""
msgid "SecurityOrchestration|.yaml preview"
msgstr ""
-msgid "SecurityOrchestration|Action"
-msgstr ""
-
msgid "SecurityOrchestration|Actions"
msgstr ""
msgid "SecurityOrchestration|Add rule"
msgstr ""
+msgid "SecurityOrchestration|After dismissing the alert, the information will never be shown again."
+msgstr ""
+
msgid "SecurityOrchestration|All policies"
msgstr ""
@@ -31836,7 +32512,7 @@ msgstr ""
msgid "SecurityOrchestration|Description"
msgstr ""
-msgid "SecurityOrchestration|Disabled"
+msgid "SecurityOrchestration|Don't show the alert anymore"
msgstr ""
msgid "SecurityOrchestration|Edit policy"
@@ -31845,13 +32521,13 @@ msgstr ""
msgid "SecurityOrchestration|Edit policy project"
msgstr ""
-msgid "SecurityOrchestration|Enabled"
+msgid "SecurityOrchestration|Empty policy name"
msgstr ""
-msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Enabled"
msgstr ""
-msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
msgstr ""
msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
@@ -31860,7 +32536,7 @@ msgstr ""
msgid "SecurityOrchestration|Invalid policy type"
msgstr ""
-msgid "SecurityOrchestration|Latest scan"
+msgid "SecurityOrchestration|Latest scan run against %{agent}"
msgstr ""
msgid "SecurityOrchestration|Network"
@@ -31869,15 +32545,27 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No actions defined - policy will not run."
+msgstr ""
+
+msgid "SecurityOrchestration|No description"
+msgstr ""
+
msgid "SecurityOrchestration|No rules defined - policy will not run."
msgstr ""
+msgid "SecurityOrchestration|Not enabled"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
msgid "SecurityOrchestration|Policies"
msgstr ""
+msgid "SecurityOrchestration|Policy Type"
+msgstr ""
+
msgid "SecurityOrchestration|Policy cannot be enabled for non-existing branches (%{branches})"
msgstr ""
@@ -31902,10 +32590,13 @@ msgstr ""
msgid "SecurityOrchestration|Require %{approvals} %{plural} from %{approvers} if any of the following occur:"
msgstr ""
-msgid "SecurityOrchestration|Rule"
+msgid "SecurityOrchestration|Rules"
msgstr ""
-msgid "SecurityOrchestration|Rules"
+msgid "SecurityOrchestration|Runs %{actions} and %{lastAction} scans"
+msgstr ""
+
+msgid "SecurityOrchestration|Runs a %{action} scan"
msgstr ""
msgid "SecurityOrchestration|Scan Execution"
@@ -31965,6 +32656,9 @@ msgstr ""
msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
+msgid "SecurityOrchestration|This view only shows scan results for the agent %{agent}. You can view scan results for all agents in the %{linkStart}Operational Vulnerabilities tab of the vulnerability report%{linkEnd}."
+msgstr ""
+
msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
@@ -32019,9 +32713,6 @@ msgstr ""
msgid "SecurityOrchestration|users with ids"
msgstr ""
-msgid "SecurityOrchestration|view results"
-msgstr ""
-
msgid "SecurityOrchestration|vulnerabilities"
msgstr ""
@@ -32691,22 +33382,19 @@ 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|In order to start using functions as a service, you must first install Knative on your Kubernetes cluster. %{linkStart}More information%{linkEnd}"
-msgstr ""
-
msgid "Serverless|Learn more about Serverless"
msgstr ""
msgid "Serverless|No functions available"
msgstr ""
-msgid "Serverless|Sign up for First Look"
+msgid "Serverless|Serverless was %{linkStart}deprecated%{linkEnd} in GitLab 14.3."
+msgstr ""
+
+msgid "Serverless|Serverless was %{postLinkStart}deprecated%{postLinkEnd}. But if you opt to use it, you must install Knative in your Kubernetes cluster first. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "Serverless|The deploy job has not finished."
@@ -32718,9 +33406,6 @@ 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 ""
@@ -32736,9 +33421,6 @@ msgstr ""
msgid "Service Account Key"
msgstr ""
-msgid "Service Accounts"
-msgstr ""
-
msgid "Service Accounts keys authorize GitLab to deploy your Google Cloud project"
msgstr ""
@@ -32748,10 +33430,10 @@ msgstr ""
msgid "Service Desk allows people to create issues in your GitLab instance without their own user account. It provides a unique email address for end users to create issues in a project. Replies can be sent either through the GitLab interface or by email. End users only see threads through email."
msgstr ""
-msgid "Service Usage Data"
+msgid "Service account generated successfully"
msgstr ""
-msgid "Service account generated successfully"
+msgid "Service accounts"
msgstr ""
msgid "Service ping is disabled in your configuration file, and cannot be enabled through this form."
@@ -32895,6 +33577,9 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
+msgid "Set the per-user rate limit for getting a user by ID via the API."
+msgstr ""
+
msgid "Set the per-user rate limit for notes created by web or API requests."
msgstr ""
@@ -33074,6 +33759,9 @@ msgstr ""
msgid "Shared runners details"
msgstr ""
+msgid "Shared runners enabled cannot be enabled until a valid credit card is on file"
+msgstr ""
+
msgid "Shared runners help link"
msgstr ""
@@ -33131,6 +33819,9 @@ msgstr ""
msgid "Show all issues."
msgstr ""
+msgid "Show all milestones"
+msgstr ""
+
msgid "Show all test cases."
msgstr ""
@@ -33167,6 +33858,9 @@ msgstr ""
msgid "Show file contents"
msgstr ""
+msgid "Show group milestones"
+msgstr ""
+
msgid "Show labels"
msgstr ""
@@ -33182,6 +33876,12 @@ msgstr ""
msgid "Show open epics"
msgstr ""
+msgid "Show project milestones"
+msgstr ""
+
+msgid "Show sub-group milestones"
+msgstr ""
+
msgid "Show the Closed list"
msgstr ""
@@ -33191,11 +33891,6 @@ msgstr ""
msgid "Show whitespace changes"
msgstr ""
-msgid "Showing %d event"
-msgid_plural "Showing %d events"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Showing %{conflict} between %{sourceBranch} and %{targetBranch}"
msgstr ""
@@ -33255,12 +33950,6 @@ msgstr ""
msgid "Sidebar|None"
msgstr ""
-msgid "Sidebar|Only numeral characters allowed"
-msgstr ""
-
-msgid "Sidebar|Weight"
-msgstr ""
-
msgid "Sidekiq job compression threshold (bytes)"
msgstr ""
@@ -33423,6 +34112,9 @@ msgstr ""
msgid "Slack logo"
msgstr ""
+msgid "SlackIntegration|Are you sure you want to remove this project from the Slack application?"
+msgstr ""
+
msgid "SlackIntegration|GitLab for Slack"
msgstr ""
@@ -33432,6 +34124,9 @@ msgstr ""
msgid "SlackIntegration|Project alias"
msgstr ""
+msgid "SlackIntegration|Remove project"
+msgstr ""
+
msgid "SlackIntegration|Select a GitLab project to link with your Slack workspace."
msgstr ""
@@ -33576,9 +34271,6 @@ msgstr ""
msgid "Something went wrong trying to load issue contacts."
msgstr ""
-msgid "Something went wrong when creating a work item. Please try again"
-msgstr ""
-
msgid "Something went wrong when reordering designs. Please try again"
msgstr ""
@@ -33672,9 +34364,6 @@ msgstr ""
msgid "Something went wrong while inserting your image. Please try again."
msgstr ""
-msgid "Something went wrong while merging this merge request. Please try again."
-msgstr ""
-
msgid "Something went wrong while obtaining the Let's Encrypt certificate."
msgstr ""
@@ -33996,10 +34685,10 @@ 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."
+msgid "SourcegraphAdmin|Learn more."
msgstr ""
-msgid "SourcegraphAdmin|More information"
+msgid "SourcegraphAdmin|Only public projects have code intelligence enabled and communicate with Sourcegraph."
msgstr ""
msgid "SourcegraphAdmin|Save changes"
@@ -34008,7 +34697,7 @@ msgstr ""
msgid "SourcegraphAdmin|Sourcegraph URL"
msgstr ""
-msgid "SourcegraphAdmin|e.g. https://sourcegraph.example.com"
+msgid "SourcegraphAdmin|https://sourcegraph.example.com"
msgstr ""
msgid "SourcegraphPreferences|This feature is experimental and currently limited to certain projects."
@@ -34143,6 +34832,9 @@ msgstr ""
msgid "Start date"
msgstr ""
+msgid "Start free trial"
+msgstr ""
+
msgid "Start merge train"
msgstr ""
@@ -34173,6 +34865,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started escalation for this incident."
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -34185,6 +34880,9 @@ msgstr ""
msgid "Starts at (UTC)"
msgstr ""
+msgid "Starts escalations for this incident"
+msgstr ""
+
msgid "Starts on"
msgstr ""
@@ -34446,6 +35144,9 @@ msgstr ""
msgid "Strikethrough"
msgstr ""
+msgid "Strikethrough text"
+msgstr ""
+
msgid "Subgroup information"
msgstr ""
@@ -34680,6 +35381,21 @@ msgstr ""
msgid "Subscriptions"
msgstr ""
+msgid "Subscriptions|Chat with sales"
+msgstr ""
+
+msgid "Subscriptions|Close"
+msgstr ""
+
+msgid "Subscriptions|Not ready to buy yet?"
+msgstr ""
+
+msgid "Subscriptions|Start a free trial"
+msgstr ""
+
+msgid "Subscriptions|We understand. Maybe you have some questions for our sales team, or maybe you'd like to try some of the paid features first. What would you like to do?"
+msgstr ""
+
msgid "Subscription|Your subscription for %{strong}%{namespace_name}%{strong_close} has expired and you are now on %{pricing_link_start}the GitLab Free tier%{pricing_link_end}. Don't worry, your data is safe. Get in touch with our support team (%{support_email}). They'll gladly help with your subscription renewal."
msgstr ""
@@ -34890,6 +35606,9 @@ msgstr ""
msgid "SuperSonics|Maximum users"
msgstr ""
+msgid "SuperSonics|Offline cloud"
+msgstr ""
+
msgid "SuperSonics|Paste your activation code"
msgstr ""
@@ -34956,6 +35675,12 @@ msgstr ""
msgid "SuperSonics|You do not have an active subscription"
msgstr ""
+msgid "SuperSonics|You have a future dated license"
+msgstr ""
+
+msgid "SuperSonics|You have added a license that activates on %{date}. Please see the subscription history table below for more details."
+msgstr ""
+
msgid "SuperSonics|You have successfully added a license that activates on %{date}. Please see the subscription history table below for more details."
msgstr ""
@@ -35115,6 +35840,9 @@ msgstr ""
msgid "Tag name is required"
msgstr ""
+msgid "Tag push"
+msgstr ""
+
msgid "Tag push events"
msgstr ""
@@ -35217,6 +35945,9 @@ msgstr ""
msgid "TagsPage|protected"
msgstr ""
+msgid "Take a look at the documentation to discover all of GitLab’s capabilities."
+msgstr ""
+
msgid "Target Branch"
msgstr ""
@@ -35619,6 +36350,9 @@ msgstr ""
msgid "Tests"
msgstr ""
+msgid "Text (optional)"
+msgstr ""
+
msgid "Text added to the body of all email messages. %{character_limit} character limit"
msgstr ""
@@ -35669,6 +36403,9 @@ msgstr ""
msgid "The CSV export will be created in the background. Once finished, it will be sent to %{email} in an attachment."
msgstr ""
+msgid "The CSV export you requested of all user memberships is attached to this email."
+msgstr ""
+
msgid "The GitLab subscription service (customers.gitlab.com) is currently experiencing an outage. You can monitor the status and get updates at %{linkStart}status.gitlab.com%{linkEnd}."
msgstr ""
@@ -35744,6 +36481,9 @@ 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 epic"
+msgstr ""
+
msgid "The current issue"
msgstr ""
@@ -35905,6 +36645,9 @@ msgstr ""
msgid "The latest pipeline for this merge request has failed."
msgstr ""
+msgid "The license key is invalid."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -35920,6 +36663,9 @@ msgstr ""
msgid "The license was successfully uploaded and will be active from %{starts_at}. You can see the details below."
msgstr ""
+msgid "The license you uploaded is invalid. If the issue persists, contact support at %{link}."
+msgstr ""
+
msgid "The list creation wizard is already open"
msgstr ""
@@ -36541,10 +37287,13 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} and everything this project contains. %{strongOpen}There is no going back%{strongClose}"
+msgstr ""
+
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains."
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}on %{date}%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains. %{strongOpen}There is no going back.%{strongClose}"
msgstr ""
msgid "This action will %{strongOpen}permanently remove%{strongClose} %{codeOpen}%{group}%{codeClose} %{strongOpen}immediately%{strongClose}."
@@ -36673,9 +37422,6 @@ msgstr ""
msgid "This file was modified for readability, and can't accept suggestions. Edit it directly."
msgstr ""
-msgid "This forked project has the following:"
-msgstr ""
-
msgid "This form is disabled in preview"
msgstr ""
@@ -36688,7 +37434,7 @@ msgstr ""
msgid "This group can't be removed because it is linked to a subscription. To remove this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
-msgid "This group can't be transfered because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
+msgid "This group can't be transferred because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
msgid "This group cannot be invited to a project inside a group with enforced SSO"
@@ -36715,6 +37461,9 @@ 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 incident is already escalated with '%{escalation_policy_name}'."
+msgstr ""
+
msgid "This invitation was sent to %{mail_to_invite_email}, but you are signed in as %{link_to_current_user} with email %{mail_to_current_user}."
msgstr ""
@@ -36733,9 +37482,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 merge train pipeline"
-msgstr ""
-
msgid "This is a private email address %{helpIcon} generated just for you. Anyone who has it can create issues or merge requests as if they were you. If that happens, %{resetLinkStart}reset this token%{resetLinkEnd}."
msgstr ""
@@ -36757,6 +37503,12 @@ msgstr ""
msgid "This is your current session"
msgstr ""
+msgid "This issue cannot be assigned to a confidential epic because it is public."
+msgstr ""
+
+msgid "This issue cannot be made public because it belongs to a confidential epic."
+msgstr ""
+
msgid "This issue is confidential and should only be visible to team members with at least Reporter access."
msgstr ""
@@ -36874,6 +37626,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 branch is protected from force push."
+msgstr ""
+
msgid "This merge request cannot be rebased while there are conflicts."
msgstr ""
@@ -36925,9 +37680,15 @@ msgstr ""
msgid "This pipeline was triggered by a schedule."
msgstr ""
+msgid "This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project"
msgstr ""
+msgid "This project can be restored until %{date}."
+msgstr ""
+
msgid "This project cannot be %{visibilityLevel} because the visibility of %{openShowLink}%{name}%{closeShowLink} is %{visibility}. To make this project %{visibilityLevel}, you must first %{openEditLink}change the visibility%{closeEditLink} of the parent group."
msgstr ""
@@ -36946,6 +37707,9 @@ msgstr ""
msgid "This project is %{strongStart}NOT%{strongEnd} a fork, and has the following:"
msgstr ""
+msgid "This project is %{strongStart}NOT%{strongEnd} a fork. This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -37637,6 +38401,9 @@ msgstr ""
msgid "Today"
msgstr ""
+msgid "Todos count"
+msgstr ""
+
msgid "Todos|Are you looking for things to do? Take a look at %{strongStart}%{openIssuesLinkStart}open issues%{openIssuesLinkEnd}%{strongEnd}, contribute to %{strongStart}%{mergeRequestLinkStart}a merge request%{mergeRequestLinkEnd}%{mergeRequestLinkEnd}%{strongEnd}, or mention someone in a comment to automatically assign them a new to-do item."
msgstr ""
@@ -37910,10 +38677,8 @@ msgstr ""
msgid "Trending"
msgstr ""
-msgid "Trials|%{planName} Trial %{enDash} %{num} day left"
-msgid_plural "Trials|%{planName} Trial %{enDash} %{num} days left"
-msgstr[0] ""
-msgstr[1] ""
+msgid "Trials|%{planName} Trial"
+msgstr ""
msgid "Trials|Compare all plans"
msgstr ""
@@ -37921,6 +38686,9 @@ msgstr ""
msgid "Trials|Create a new group to start your GitLab Ultimate trial."
msgstr ""
+msgid "Trials|Day %{daysUsed}/%{duration}"
+msgstr ""
+
msgid "Trials|Go back to GitLab"
msgstr ""
@@ -38170,7 +38938,7 @@ msgstr ""
msgid "URL is triggered when repository is updated"
msgstr ""
-msgid "URL must be percent-encoded if neccessary."
+msgid "URL must be percent-encoded if necessary."
msgstr ""
msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
@@ -38389,6 +39157,9 @@ msgstr ""
msgid "Unlock account"
msgstr ""
+msgid "Unlock more features with GitLab Ultimate"
+msgstr ""
+
msgid "Unlock the discussion"
msgstr ""
@@ -38452,6 +39223,9 @@ msgstr ""
msgid "Unsubscribes from this %{quick_action_target}."
msgstr ""
+msgid "Unsupported sort value."
+msgstr ""
+
msgid "Unsupported todo type passed. Supported todo types are: %{todo_types}"
msgstr ""
@@ -38680,6 +39454,9 @@ msgstr ""
msgid "UsageQuota|File attachments and smaller design graphics."
msgstr ""
+msgid "UsageQuota|From %{storage_enforcement_date} storage limits will apply to this namespace. View and manage your usage in %{strong_start}Group Settings &gt; Usage quotas%{strong_end}."
+msgstr ""
+
msgid "UsageQuota|Git repository."
msgstr ""
@@ -38740,6 +39517,9 @@ msgstr ""
msgid "UsageQuota|Storage type"
msgstr ""
+msgid "UsageQuota|Storage used"
+msgstr ""
+
msgid "UsageQuota|This is the total amount of storage used across your projects within this namespace."
msgstr ""
@@ -38935,6 +39715,12 @@ msgstr ""
msgid "Use hashed storage paths for newly created and renamed repositories. Always enabled since 13.0."
msgstr ""
+msgid "Use issue count"
+msgstr ""
+
+msgid "Use issue weight"
+msgstr ""
+
msgid "Use one line per URI"
msgstr ""
@@ -39316,6 +40102,9 @@ msgstr ""
msgid "Users"
msgstr ""
+msgid "Users API rate limit"
+msgstr ""
+
msgid "Users can launch a development environment from a GitLab browser tab when the %{linkStart}Gitpod%{linkEnd} integration is enabled."
msgstr ""
@@ -39641,6 +40430,9 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View group pipeline usage quota"
+msgstr ""
+
msgid "View incident details at"
msgstr ""
@@ -39793,6 +40585,9 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
+msgid "Vulnerability"
+msgstr ""
+
msgid "Vulnerability Report"
msgstr ""
@@ -39844,6 +40639,9 @@ msgstr ""
msgid "VulnerabilityManagement|An unverified non-confirmed finding"
msgstr ""
+msgid "VulnerabilityManagement|At least one identifier is required"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -39853,12 +40651,24 @@ msgstr ""
msgid "VulnerabilityManagement|Create Jira issue"
msgstr ""
+msgid "VulnerabilityManagement|Enter a name"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE code"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE identifier URL"
+msgstr ""
+
msgid "VulnerabilityManagement|Fetching linked Jira issues"
msgstr ""
msgid "VulnerabilityManagement|Manually add a vulnerability entry into the vulnerability report."
msgstr ""
+msgid "VulnerabilityManagement|Name is a required field"
+msgstr ""
+
msgid "VulnerabilityManagement|Needs triage"
msgstr ""
@@ -39874,6 +40684,18 @@ msgstr ""
msgid "VulnerabilityManagement|Select a method"
msgstr ""
+msgid "VulnerabilityManagement|Select a severity level"
+msgstr ""
+
+msgid "VulnerabilityManagement|Select a status"
+msgstr ""
+
+msgid "VulnerabilityManagement|Severity is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Something went wrong while creating vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -39898,6 +40720,12 @@ msgstr ""
msgid "VulnerabilityManagement|Something went wrong, could not update vulnerability state."
msgstr ""
+msgid "VulnerabilityManagement|Status is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Submit vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Summary, detailed description, steps to reproduce, etc."
msgstr ""
@@ -40093,6 +40921,9 @@ msgstr ""
msgid "WARNING:"
msgstr ""
+msgid "WARNING: This snippet contains hidden files which might be used to mask malicious behavior. Exercise caution if cloning and executing code from this snippet."
+msgstr ""
+
msgid "Wait for the file to load to copy its contents"
msgstr ""
@@ -40312,6 +41143,15 @@ msgstr ""
msgid "Webhooks|An issue is created, updated, closed, or reopened."
msgstr ""
+msgid "Webhooks|Are you sure you want to delete this group hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this project hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this webhook?"
+msgstr ""
+
msgid "Webhooks|Comments"
msgstr ""
@@ -40321,6 +41161,9 @@ msgstr ""
msgid "Webhooks|Confidential issues events"
msgstr ""
+msgid "Webhooks|Delete webhook"
+msgstr ""
+
msgid "Webhooks|Deployment events"
msgstr ""
@@ -40554,6 +41397,9 @@ msgstr ""
msgid "Wiki"
msgstr ""
+msgid "Wiki page"
+msgstr ""
+
msgid "Wiki page was successfully created."
msgstr ""
@@ -40659,7 +41505,7 @@ msgstr ""
msgid "WikiPageConflictMessage|Someone edited the page the same time you did. Please check out %{wikiLinkStart}the page%{wikiLinkEnd} and make sure your changes will not unintentionally remove theirs."
msgstr ""
-msgid "WikiPage|An error occured while trying to render the content editor. Please try again later."
+msgid "WikiPage|An error occurred while trying to render the content editor. Please try again later."
msgstr ""
msgid "WikiPage|Are you sure you want to switch back to the classic editor?"
@@ -40818,6 +41664,18 @@ msgstr ""
msgid "WorkItem|New Task"
msgstr ""
+msgid "WorkItem|Something went wrong when creating a work item. Please try again"
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching the work item. Please try again."
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching work item types. Please try again"
+msgstr ""
+
+msgid "WorkItem|Type"
+msgstr ""
+
msgid "WorkItem|Work Items"
msgstr ""
@@ -40884,7 +41742,10 @@ msgstr ""
msgid "You are about to add %{usersTag} people to the discussion. They will all receive a notification."
msgstr ""
-msgid "You are about to permanently delete this project"
+msgid "You are about to delete this forked project containing:"
+msgstr ""
+
+msgid "You are about to delete this project containing:"
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."
@@ -40905,6 +41766,9 @@ msgstr ""
msgid "You are attempting to update a file that has changed since you started editing it."
msgstr ""
+msgid "You are billed if you exceed this number. %{qsrOverageLinkStart}How does billing work?%{qsrOverageLinkEnd}"
+msgstr ""
+
msgid "You are connected to the Prometheus server, but there is currently no data to display."
msgstr ""
@@ -40962,6 +41826,9 @@ msgstr ""
msgid "You are not authorized to update this scanner profile"
msgstr ""
+msgid "You are not authorized to upload metric images"
+msgstr ""
+
msgid "You are now impersonating %{username}"
msgstr ""
@@ -41115,9 +41982,6 @@ msgstr ""
msgid "You can only upload one design when dropping onto an existing design."
msgstr ""
-msgid "You can recover this project until %{date}"
-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 ""
@@ -41166,9 +42030,6 @@ msgstr ""
msgid "You cannot write to this read-only GitLab instance."
msgstr ""
-msgid "You can’t %{tag_start}edit%{tag_end} files directly in this project. Fork this project and submit a merge request with your changes."
-msgstr ""
-
msgid "You can’t edit files directly in this project. Fork this project and submit a merge request with your changes."
msgstr ""
@@ -41321,9 +42182,6 @@ 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 set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
@@ -41354,12 +42212,6 @@ msgstr ""
msgid "You must have maintainer access to force delete a lock"
msgstr ""
-msgid "You must have permission to create a project in a group before forking."
-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 ""
@@ -41765,7 +42617,7 @@ msgstr ""
msgid "Your public email will be displayed on your public profile."
msgstr ""
-msgid "Your request for access could not be processed: %{error_meesage}"
+msgid "Your request for access could not be processed: %{error_message}"
msgstr ""
msgid "Your request for access has been queued for review."
@@ -41948,6 +42800,9 @@ msgstr ""
msgid "archived:"
msgstr ""
+msgid "artifacts"
+msgstr ""
+
msgid "assign yourself"
msgstr ""
@@ -41977,6 +42832,9 @@ msgstr[1] ""
msgid "branch name"
msgstr ""
+msgid "builds"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -42400,6 +43258,9 @@ msgstr ""
msgid "contact with same email already exists in group hierarchy"
msgstr ""
+msgid "container registry images"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -42439,6 +43300,9 @@ msgstr ""
msgid "data"
msgstr ""
+msgid "database"
+msgstr ""
+
msgid "date must not be after 9999-12-31"
msgstr ""
@@ -42462,9 +43326,6 @@ msgstr ""
msgid "design"
msgstr ""
-msgid "detached"
-msgstr ""
-
msgid "disabled"
msgstr ""
@@ -42713,7 +43574,7 @@ msgstr ""
msgid "is not a valid X509 certificate."
msgstr ""
-msgid "is not allowed for sign-up."
+msgid "is not allowed for sign-up. Please use your regular email address."
msgstr ""
msgid "is not allowed for this group."
@@ -42725,7 +43586,7 @@ msgstr ""
msgid "is not allowed since the group is not top-level group."
msgstr ""
-msgid "is not allowed."
+msgid "is not allowed. Please use your regular email address."
msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
@@ -42812,6 +43673,9 @@ msgstr ""
msgid "level: %{level}"
msgstr ""
+msgid "lfs objects"
+msgstr ""
+
msgid "limit of %{project_limit} reached"
msgstr ""
@@ -43031,6 +43895,9 @@ msgstr ""
msgid "mrWidget|Merge blocked: pipeline must succeed. It's waiting for a manual action to continue."
msgstr ""
+msgid "mrWidget|Merge blocked: pipeline must succeed. Push a commit that fixes the failure, or %{linkStart}learn about other solutions.%{linkEnd}"
+msgstr ""
+
msgid "mrWidget|Merge blocked: this merge request must be approved."
msgstr ""
@@ -43148,9 +44015,6 @@ msgstr ""
msgid "mrWidget|The changes were not merged into"
msgstr ""
-msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -43298,9 +44162,6 @@ msgstr ""
msgid "open issue"
msgstr ""
-msgid "opened %{timeAgo}"
-msgstr ""
-
msgid "or"
msgstr ""
@@ -43312,6 +44173,12 @@ msgid_plural "out of %d total tests"
msgstr[0] ""
msgstr[1] ""
+msgid "packages"
+msgstr ""
+
+msgid "pages"
+msgstr ""
+
msgid "parent"
msgid_plural "parents"
msgstr[0] ""
@@ -43461,6 +44328,9 @@ msgid_plural "replies"
msgstr[0] ""
msgstr[1] ""
+msgid "repositories"
+msgstr ""
+
msgid "repository:"
msgstr ""
@@ -43581,12 +44451,18 @@ msgstr ""
msgid "tag name"
msgstr ""
+msgid "terraform states"
+msgstr ""
+
msgid "the correct format."
msgstr ""
msgid "the file"
msgstr ""
+msgid "the following epic(s)"
+msgstr ""
+
msgid "the following issue(s)"
msgstr ""
@@ -43599,21 +44475,12 @@ msgstr ""
msgid "this document"
msgstr ""
-msgid "this issue cannot be assigned to a confidential epic since it is public"
-msgstr ""
-
-msgid "this issue cannot be made public since it belongs to a confidential epic"
-msgstr ""
-
msgid "time summary"
msgstr ""
msgid "toggle collapse"
msgstr ""
-msgid "train"
-msgstr ""
-
msgid "triggered"
msgstr ""
@@ -43742,3 +44609,6 @@ msgstr ""
msgid "{project}"
msgstr ""
+msgid "✔"
+msgstr ""
+
diff --git a/locale/lt_LT/gitlab.po b/locale/lt_LT/gitlab.po
index 472482312a1..5524a91bd45 100644
--- a/locale/lt_LT/gitlab.po
+++ b/locale/lt_LT/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: lt\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2022-02-02 15:46\n"
+"PO-Revision-Date: 2022-03-01 20:39\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -174,6 +174,13 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "%d assigned issue"
+msgid_plural "%d assigned issues"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -559,8 +566,29 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
-msgid "%d vulnerability updated"
-msgid_plural "%d vulnerabilities updated"
+msgid "%d vulnerability set to confirmed"
+msgid_plural "%d vulnerabilities set to confirmed"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
+msgid "%d vulnerability set to dismissed"
+msgid_plural "%d vulnerabilities set to dismissed"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
+msgid "%d vulnerability set to needs triage"
+msgid_plural "%d vulnerabilities set to needs triage"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
+msgid "%d vulnerability set to resolved"
+msgid_plural "%d vulnerabilities set to resolved"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
@@ -662,6 +690,12 @@ msgstr[3] ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{completed} of %{total} issues closed"
+msgstr ""
+
+msgid "%{completed} of %{total} weight completed"
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -1022,6 +1056,9 @@ msgstr ""
msgid "%{openedIssues} open, %{closedIssues} closed"
msgstr ""
+msgid "%{percentage}%% issues closed"
+msgstr ""
+
msgid "%{percentage}%% weight completed"
msgstr ""
@@ -1481,6 +1518,9 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "- of - issues closed"
+msgstr ""
+
msgid "- of - weight completed"
msgstr ""
@@ -1669,7 +1709,7 @@ msgstr ""
msgid "1000+"
msgstr ""
-msgid "192.168.0.0/24"
+msgid "192.168.0.0/24 or 2001:0DB8:1234::/48"
msgstr ""
msgid "1st contribution!"
@@ -1981,13 +2021,13 @@ msgstr ""
msgid "AWS Access Key"
msgstr ""
-msgid "AWS Access Key. Only required if not using role instance credentials"
+msgid "AWS Secret Access Key"
msgstr ""
-msgid "AWS Secret Access Key"
+msgid "AWS access key ID (Optional)"
msgstr ""
-msgid "AWS Secret Access Key. Only required if not using role instance credentials"
+msgid "AWS secret access key (Optional)"
msgstr ""
msgid "AWS service error: %{error}"
@@ -2047,9 +2087,6 @@ msgstr ""
msgid "Access granted"
msgstr ""
-msgid "Access key ID"
-msgstr ""
-
msgid "Access requests"
msgstr ""
@@ -2224,7 +2261,7 @@ msgstr ""
msgid "Activity"
msgstr ""
-msgid "Activity|An error occured while retrieving activity. Reload the page to try again."
+msgid "Activity|An error occurred while retrieving activity. Reload the page to try again."
msgstr ""
msgid "Add"
@@ -2263,6 +2300,9 @@ msgstr ""
msgid "Add a %{type}"
msgstr ""
+msgid "Add a GCP region"
+msgstr ""
+
msgid "Add a GPG key"
msgstr ""
@@ -2314,6 +2354,9 @@ msgstr ""
msgid "Add a numbered list"
msgstr ""
+msgid "Add a related epic"
+msgstr ""
+
msgid "Add a related issue"
msgstr ""
@@ -2428,6 +2471,9 @@ msgstr ""
msgid "Add or subtract spent time"
msgstr ""
+msgid "Add people"
+msgstr ""
+
msgid "Add previously merged commits"
msgstr ""
@@ -2494,6 +2540,9 @@ msgstr ""
msgid "Add webhook"
msgstr ""
+msgid "Add your team members and others to GitLab."
+msgstr ""
+
msgid "Add/remove"
msgstr ""
@@ -3316,12 +3365,6 @@ msgstr ""
msgid "AdvancedSearch|Reindex required"
msgstr ""
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. Permanently deleting this project will %{strongStart}immediately delete%{strongEnd} its repositories and %{strongStart}all related resources%{strongEnd}, including issues, merge requests etc."
-msgstr ""
-
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. You will lose this project's repository and %{strongStart}all related resources%{strongEnd}, including issues and merge requests."
-msgstr ""
-
msgid "After a successful password update you will be redirected to login screen."
msgstr ""
@@ -3352,6 +3395,9 @@ msgstr ""
msgid "Akismet helps prevent the creation of spam issues in public projects."
msgstr ""
+msgid "Alert"
+msgstr ""
+
msgid "AlertManagement|Acknowledged"
msgstr ""
@@ -3724,9 +3770,6 @@ msgstr ""
msgid "All environments"
msgstr ""
-msgid "All epics"
-msgstr ""
-
msgid "All groups and projects"
msgstr ""
@@ -4467,14 +4510,17 @@ msgstr ""
msgid "ApplicationSettings|Approve users in the pending approval status?"
msgstr ""
-msgid "ApplicationSettings|By making this change, you will automatically approve %d user with the pending approval status."
-msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users with the pending approval status."
+msgid "ApplicationSettings|Approve users who are pending approval?"
+msgstr ""
+
+msgid "ApplicationSettings|By making this change, you will automatically approve %d user who is pending approval."
+msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users who are pending approval."
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
-msgid "ApplicationSettings|By making this change, you will automatically approve all users in pending approval status."
+msgid "ApplicationSettings|By making this change, you will automatically approve all users who are pending approval."
msgstr ""
msgid "ApplicationSettings|Denied domains for sign-ups"
@@ -4890,10 +4936,10 @@ msgstr ""
msgid "Archiving the project will make it entirely read-only. It is hidden from the dashboard and doesn't show up in searches. %{strong_start}The repository cannot be committed to, and no issues, comments, or other entities can be created.%{strong_end} %{link_start}Learn more.%{link_end}"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to delete this project?"
+msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
+msgid "Are you absolutely sure?"
msgstr ""
msgid "Are you sure that you want to archive this project?"
@@ -4929,12 +4975,18 @@ msgstr ""
msgid "Are you sure you want to delete this SSH key?"
msgstr ""
+msgid "Are you sure you want to delete this comment?"
+msgstr ""
+
msgid "Are you sure you want to delete this deploy key?"
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 label?"
+msgstr ""
+
msgid "Are you sure you want to delete this pipeline schedule?"
msgstr ""
@@ -4950,9 +5002,6 @@ msgstr ""
msgid "Are you sure you want to discard your changes?"
msgstr ""
-msgid "Are you sure you want to erase this build?"
-msgstr ""
-
msgid "Are you sure you want to import %d repository?"
msgid_plural "Are you sure you want to import %d repositories?"
msgstr[0] ""
@@ -5002,6 +5051,9 @@ msgstr ""
msgid "Are you sure you want to remove this list?"
msgstr ""
+msgid "Are you sure you want to remove this nickname?"
+msgstr ""
+
msgid "Are you sure you want to reset the health check token?"
msgstr ""
@@ -5014,10 +5066,10 @@ 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?"
+msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
msgstr ""
-msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
+msgid "Are you sure you want to revoke this project access token? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to stop this environment?"
@@ -5164,9 +5216,6 @@ msgstr ""
msgid "Assigned to %{assignee_name}"
msgstr ""
-msgid "Assigned to %{name}"
-msgstr ""
-
msgid "Assigned to me"
msgstr ""
@@ -5235,6 +5284,9 @@ msgstr[3] ""
msgid "Attaching the file failed."
msgstr ""
+msgid "Attention"
+msgstr ""
+
msgid "Audit Events"
msgstr ""
@@ -5397,6 +5449,12 @@ msgstr ""
msgid "Authorized applications (%{size})"
msgstr ""
+msgid "AuthorizedApplication|Are you sure you want to revoke this application?"
+msgstr ""
+
+msgid "AuthorizedApplication|Revoke application"
+msgstr ""
+
msgid "Authors: %{authors}"
msgstr ""
@@ -6598,6 +6656,9 @@ msgstr ""
msgid "CICDAnalytics|Shared Runners Usage"
msgstr ""
+msgid "CICDAnalytics|Shared runner pipeline minute duration by month"
+msgstr ""
+
msgid "CICDAnalytics|Shared runner usage"
msgstr ""
@@ -6739,6 +6800,9 @@ msgstr ""
msgid "Can create groups:"
msgstr ""
+msgid "Can not delete primary training"
+msgstr ""
+
msgid "Can't apply as the source branch was deleted."
msgstr ""
@@ -7072,9 +7136,6 @@ msgstr ""
msgid "Changing any setting here requires an application restart"
msgstr ""
-msgid "Changing group URL can have unintended side effects."
-msgstr ""
-
msgid "Charts can't be displayed as the request for data has timed out. %{documentationLink}"
msgstr ""
@@ -7162,9 +7223,6 @@ msgstr ""
msgid "Checking branch availability..."
msgstr ""
-msgid "Checking group URL availability..."
-msgstr ""
-
msgid "Checking group path availability..."
msgstr ""
@@ -7662,6 +7720,9 @@ msgstr ""
msgid "Clear recent searches"
msgstr ""
+msgid "Clear repository checks"
+msgstr ""
+
msgid "Clear search"
msgstr ""
@@ -7794,9 +7855,6 @@ msgstr ""
msgid "Closed MRs"
msgstr ""
-msgid "Closed epics"
-msgstr ""
-
msgid "Closed issues"
msgstr ""
@@ -7833,13 +7891,13 @@ msgstr ""
msgid "Cluster level"
msgstr ""
-msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
+msgid "Cluster type must be specified for Stages::ClusterEndpointInserter"
msgstr ""
msgid "ClusterAgents|%{name} successfully deleted"
msgstr ""
-msgid "ClusterAgents|%{number} of %{total} Agents"
+msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
@@ -7881,6 +7939,15 @@ msgstr ""
msgid "ClusterAgents|Agent never connected to GitLab"
msgstr ""
+msgid "ClusterAgents|Agent version mismatch"
+msgstr ""
+
+msgid "ClusterAgents|Agent version mismatch and update"
+msgstr ""
+
+msgid "ClusterAgents|Agent version update required"
+msgstr ""
+
msgid "ClusterAgents|All"
msgstr ""
@@ -7905,7 +7972,7 @@ msgstr ""
msgid "ClusterAgents|Configuration"
msgstr ""
-msgid "ClusterAgents|Connect a cluster through the Agent"
+msgid "ClusterAgents|Connect a cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connect existing cluster"
@@ -7914,13 +7981,13 @@ msgstr ""
msgid "ClusterAgents|Connect with a certificate"
msgstr ""
-msgid "ClusterAgents|Connect with agent"
+msgid "ClusterAgents|Connect with an agent"
msgstr ""
msgid "ClusterAgents|Connect with the GitLab Agent"
msgstr ""
-msgid "ClusterAgents|Connect your cluster through the Agent"
+msgid "ClusterAgents|Connect your cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connected"
@@ -7980,7 +8047,10 @@ msgstr ""
msgid "ClusterAgents|How to register an agent?"
msgstr ""
-msgid "ClusterAgents|Install new Agent"
+msgid "ClusterAgents|How to update an agent?"
+msgstr ""
+
+msgid "ClusterAgents|Install a new agent"
msgstr ""
msgid "ClusterAgents|Last connected %{timeAgo}."
@@ -8007,7 +8077,7 @@ msgstr ""
msgid "ClusterAgents|Never connected"
msgstr ""
-msgid "ClusterAgents|No Agents"
+msgid "ClusterAgents|No agents"
msgstr ""
msgid "ClusterAgents|No clusters connected through cluster certificates"
@@ -8067,6 +8137,9 @@ msgstr ""
msgid "ClusterAgents|The agent has not been connected in a long time. There might be a connectivity issue. Last contact was %{timeAgo}."
msgstr ""
+msgid "ClusterAgents|The agent version do not match each other across your cluster's pods. This can happen when a new agent version was just deployed and Kubernetes is shutting down the old pods."
+msgstr ""
+
msgid "ClusterAgents|The recommended installation method includes the token. If you want to follow the advanced installation method provided in the docs, make sure you save the token value before you close this window."
msgstr ""
@@ -8116,6 +8189,9 @@ msgstr ""
msgid "ClusterAgents|You will need to create a token to connect to your agent"
msgstr ""
+msgid "ClusterAgents|Your agent version is out of sync with your GitLab version (v%{version}), which might cause compatibility problems. Update the agent installed on your cluster to the most recent version."
+msgstr ""
+
msgid "ClusterAgents|Your instance doesn't have the %{linkStart}GitLab Agent Server (KAS)%{linkEnd} set up. Ask a GitLab Administrator to install it."
msgstr ""
@@ -8992,9 +9068,6 @@ msgstr ""
msgid "Comma-separated list of email addresses."
msgstr ""
-msgid "Comma-separated list of users allowed to exceed the rate limit."
-msgstr ""
-
msgid "Comma-separated, e.g. '1.1.1.1, 2.2.2.0/24'"
msgstr ""
@@ -9323,6 +9396,12 @@ msgstr ""
msgid "Confidential"
msgstr ""
+msgid "Confidential issue"
+msgstr ""
+
+msgid "Confidential note"
+msgstr ""
+
msgid "Confidentiality"
msgstr ""
@@ -9356,6 +9435,9 @@ msgstr ""
msgid "Configure Dependency Scanning in `.gitlab-ci.yml`, creating this file if it does not already exist"
msgstr ""
+msgid "Configure GitLab"
+msgstr ""
+
msgid "Configure GitLab runners to start using the Web Terminal. %{helpStart}Learn more.%{helpEnd}"
msgstr ""
@@ -9404,6 +9486,15 @@ msgstr ""
msgid "Configure pipelines to deploy web apps, backend services, APIs and static resources to Google Cloud"
msgstr ""
+msgid "Configure region"
+msgstr ""
+
+msgid "Configure region for environment"
+msgstr ""
+
+msgid "Configure regions"
+msgstr ""
+
msgid "Configure repository mirroring."
msgstr ""
@@ -9437,6 +9528,9 @@ msgstr ""
msgid "Configure which lists are shown for anyone who visits this board"
msgstr ""
+msgid "Configure your environments to be deployed to specific geographical regions"
+msgstr ""
+
msgid "Confirm"
msgstr ""
@@ -10145,10 +10239,10 @@ msgstr ""
msgid "CorpusManagement|Actions"
msgstr ""
-msgid "CorpusManagement|Corpus are used in fuzz testing as mutation source to Improve future testing."
+msgid "CorpusManagement|Corpus file"
msgstr ""
-msgid "CorpusManagement|Corpus file"
+msgid "CorpusManagement|Corpus files are used in coverage-guided fuzz testing as seed inputs to improve testing."
msgstr ""
msgid "CorpusManagement|Corpus files must be in *.zip format. Maximum 5 GB"
@@ -10202,6 +10296,9 @@ msgstr ""
msgid "Could not apply %{name} command."
msgstr ""
+msgid "Could not apply %{name} command. %{message}."
+msgstr ""
+
msgid "Could not authorize chat nickname. Try again!"
msgstr ""
@@ -10352,6 +10449,9 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
+msgid "Create a group"
+msgstr ""
+
msgid "Create a merge request"
msgstr ""
@@ -10376,6 +10476,9 @@ msgstr ""
msgid "Create a personal access token on your account to pull or push via %{protocol}."
msgstr ""
+msgid "Create a project"
+msgstr ""
+
msgid "Create an account using:"
msgstr ""
@@ -10739,6 +10842,9 @@ msgstr ""
msgid "Creation date"
msgstr ""
+msgid "Creator"
+msgstr ""
+
msgid "Credentials"
msgstr ""
@@ -10751,9 +10857,15 @@ msgstr ""
msgid "CredentialsInventory|Personal Access Tokens"
msgstr ""
+msgid "CredentialsInventory|Project Access Tokens"
+msgstr ""
+
msgid "CredentialsInventory|SSH Keys"
msgstr ""
+msgid "Credit card required to be on file in order to create a pipeline"
+msgstr ""
+
msgid "Credit card:"
msgstr ""
@@ -10937,9 +11049,6 @@ msgstr ""
msgid "Customer relations"
msgstr ""
-msgid "Customizable by an administrator."
-msgstr ""
-
msgid "Customizable by owners."
msgstr ""
@@ -11069,30 +11178,18 @@ msgstr ""
msgid "CycleAnalytics|%{selectedLabelsCount} selected (%{maxLabels} max)"
msgstr ""
-msgid "CycleAnalytics|%{stageCount} stages selected"
-msgstr ""
-
-msgid "CycleAnalytics|All stages"
-msgstr ""
-
-msgid "CycleAnalytics|Average days to completion"
+msgid "CycleAnalytics|Average time to completion"
msgstr ""
msgid "CycleAnalytics|Date"
msgstr ""
-msgid "CycleAnalytics|Days to completion"
-msgstr ""
-
msgid "CycleAnalytics|Display chart filters"
msgstr ""
msgid "CycleAnalytics|Lead Time for Changes"
msgstr ""
-msgid "CycleAnalytics|No stages selected"
-msgstr ""
-
msgid "CycleAnalytics|Number of tasks"
msgstr ""
@@ -11125,18 +11222,30 @@ msgstr ""
msgid "CycleAnalytics|Showing data for group '%{groupName}' from %{createdAfter} to %{createdBefore}"
msgstr ""
-msgid "CycleAnalytics|Stages"
+msgid "CycleAnalytics|Stage time: %{title}"
msgstr ""
msgid "CycleAnalytics|Tasks by type"
msgstr ""
-msgid "CycleAnalytics|The average time spent in the selected stage for the items that were completed on each date. Data limited to the last 500 items."
+msgid "CycleAnalytics|The average time items spent in this stage. Data limited to items completed within this date range."
msgstr ""
msgid "CycleAnalytics|The given date range is larger than 180 days"
msgstr ""
+msgid "CycleAnalytics|The total time items spent across each value stream stage. Data limited to items completed within this date range."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Stage time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Total time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|Total time"
+msgstr ""
+
msgid "CycleAnalytics|Type of work"
msgstr ""
@@ -11149,9 +11258,6 @@ msgstr ""
msgid "CycleAnalytics|project dropdown filter"
msgstr ""
-msgid "CycleAnalytics|stage dropdown"
-msgstr ""
-
msgid "DAG visualization requires at least 3 dependent jobs."
msgstr ""
@@ -11251,10 +11357,16 @@ msgstr ""
msgid "DastProfiles|AJAX spider"
msgstr ""
+msgid "DastProfiles|API"
+msgstr ""
+
+msgid "DastProfiles|API endpoint URL"
+msgstr ""
+
msgid "DastProfiles|Active"
msgstr ""
-msgid "DastProfiles|Additional request headers (Optional)"
+msgid "DastProfiles|Additional request headers (optional)"
msgstr ""
msgid "DastProfiles|Are you sure you want to delete this profile?"
@@ -11269,6 +11381,9 @@ msgstr ""
msgid "DastProfiles|Branch missing"
msgstr ""
+msgid "DastProfiles|Choose a scan method"
+msgstr ""
+
msgid "DastProfiles|Could not create the scanner profile. Please try again."
msgstr ""
@@ -11338,7 +11453,13 @@ msgstr ""
msgid "DastProfiles|Excluded URLs"
msgstr ""
-msgid "DastProfiles|Excluded URLs (Optional)"
+msgid "DastProfiles|Excluded URLs (optional)"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths (optional)"
msgstr ""
msgid "DastProfiles|Hide debug messages"
@@ -11395,9 +11516,6 @@ msgstr ""
msgid "DastProfiles|Request headers"
msgstr ""
-msgid "DastProfiles|Rest API"
-msgstr ""
-
msgid "DastProfiles|Run the AJAX spider, in addition to the traditional spider, to crawl the target site."
msgstr ""
@@ -11407,6 +11525,9 @@ msgstr ""
msgid "DastProfiles|Save profile"
msgstr ""
+msgid "DastProfiles|Scan method"
+msgstr ""
+
msgid "DastProfiles|Scan mode"
msgstr ""
@@ -11485,12 +11606,24 @@ msgstr ""
msgid "DastProfiles|Website"
msgstr ""
+msgid "DastProfiles|What does each method do?"
+msgstr ""
+
msgid "DastProfiles|You can either choose a passive scan or validate the target site from the site profile management page. %{docsLinkStart}Learn more about site validation.%{docsLinkEnd}"
msgstr ""
msgid "DastProfiles|You cannot run an active scan against an unvalidated site."
msgstr ""
+msgid "DastProfiles|folder/dast_example.har or https://example.com/dast_example.har"
+msgstr ""
+
+msgid "DastProfiles|folder/example.postman_collection.json or https://example.com/"
+msgstr ""
+
+msgid "DastProfiles|folder/openapi.json or https://example.com/openapi.json"
+msgstr ""
+
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
@@ -11600,6 +11733,9 @@ msgstr ""
msgid "DatadogIntegration|API URL"
msgstr ""
+msgid "DatadogIntegration|Custom tags in Datadog. Enter one tag per line in the %{codeOpen}key:value%{codeClose} format. %{linkOpen}How do I use tags?%{linkClose}"
+msgstr ""
+
msgid "DatadogIntegration|Environment"
msgstr ""
@@ -11618,12 +11754,18 @@ msgstr ""
msgid "DatadogIntegration|Tag all data from this GitLab instance in Datadog. Useful when managing several self-managed deployments."
msgstr ""
+msgid "DatadogIntegration|Tags"
+msgstr ""
+
msgid "DatadogIntegration|The Datadog site to send data to. To send data to the EU site, use %{codeOpen}datadoghq.eu%{codeClose}."
msgstr ""
msgid "DatadogIntegration|Trace your GitLab pipelines with Datadog."
msgstr ""
+msgid "DatadogIntegration|have an invalid format"
+msgstr ""
+
msgid "Datasource name not found"
msgstr ""
@@ -11633,9 +11775,6 @@ msgstr ""
msgid "Date merged"
msgstr ""
-msgid "Date picker"
-msgstr ""
-
msgid "Date range"
msgstr ""
@@ -11789,9 +11928,6 @@ msgstr ""
msgid "Definition"
msgstr ""
-msgid "Delayed Project Deletion (%{adjourned_deletion})"
-msgstr ""
-
msgid "DelayedJobs|Are you sure you want to run %{jobName} immediately? Otherwise this job will run automatically after its timer finishes."
msgstr ""
@@ -11870,10 +12006,10 @@ msgstr ""
msgid "Delete pipeline"
msgstr ""
-msgid "Delete project"
+msgid "Delete pipeline schedule"
msgstr ""
-msgid "Delete project. Are you ABSOLUTELY SURE?"
+msgid "Delete project"
msgstr ""
msgid "Delete row"
@@ -11903,6 +12039,9 @@ msgstr ""
msgid "Delete this epic and all descendants?"
msgstr ""
+msgid "Delete this project"
+msgstr ""
+
msgid "Delete user list"
msgstr ""
@@ -12173,6 +12312,12 @@ msgstr ""
msgid "Deploy to..."
msgstr ""
+msgid "DeployBoards|To see deployment progress for your environments, make sure you are deploying to %{codeStart}$KUBE_NAMESPACE%{codeEnd} and annotating with %{codeStart}app.gitlab.com/app=$CI_PROJECT_PATH_SLUG%{codeEnd} and %{codeStart}app.gitlab.com/env=$CI_ENVIRONMENT_SLUG%{codeEnd}."
+msgstr ""
+
+msgid "DeployBoard|Kubernetes Pods"
+msgstr ""
+
msgid "DeployFreeze|Add a freeze period to prevent unintended releases during a period of time for a given environment. You must update the deployment jobs in %{filename} according to the deploy freezes added here. %{freeze_period_link_start}Learn more.%{freeze_period_link_end}"
msgstr ""
@@ -12257,9 +12402,6 @@ msgstr ""
msgid "DeployTokens|Active Deploy Tokens (%{active_tokens})"
msgstr ""
-msgid "DeployTokens|Allows read and write access to registry images."
-msgstr ""
-
msgid "DeployTokens|Allows read and write access to the package registry."
msgstr ""
@@ -12272,6 +12414,9 @@ msgstr ""
msgid "DeployTokens|Allows read-only access to the repository."
msgstr ""
+msgid "DeployTokens|Allows write access to registry images."
+msgstr ""
+
msgid "DeployTokens|Copy deploy token"
msgstr ""
@@ -12365,12 +12510,57 @@ msgstr ""
msgid "Deploying to AWS is easy with GitLab"
msgstr ""
+msgid "Deployment"
+msgstr ""
+
msgid "Deployment Frequency"
msgstr ""
+msgid "Deployment Target|Project deployment target (optional)"
+msgstr ""
+
+msgid "Deployment Target|Select the deployment target"
+msgstr ""
+
msgid "Deployment frequency"
msgstr ""
+msgid "DeploymentTarget|GitLab Pages"
+msgstr ""
+
+msgid "DeploymentTarget|Heroku"
+msgstr ""
+
+msgid "DeploymentTarget|Infrastructure provider (Terraform, Cloudformation, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Kubernetes (GKE, EKS, OpenShift, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Managed container runtime (Fargate, Cloud Run, DigitalOcean App)"
+msgstr ""
+
+msgid "DeploymentTarget|Mobile app store"
+msgstr ""
+
+msgid "DeploymentTarget|No deployment planned"
+msgstr ""
+
+msgid "DeploymentTarget|Other hosting service"
+msgstr ""
+
+msgid "DeploymentTarget|Registry (package or container)"
+msgstr ""
+
+msgid "DeploymentTarget|Self-managed container runtime (Podman, Docker Swarm, Docker Compose)"
+msgstr ""
+
+msgid "DeploymentTarget|Serverless backend (Lambda, Cloud functions)"
+msgstr ""
+
+msgid "DeploymentTarget|Virtual machine (for example, EC2)"
+msgstr ""
+
msgid "Deployments"
msgstr ""
@@ -12411,6 +12601,9 @@ msgstr ""
msgid "Deployment|This deployment was created using the API"
msgstr ""
+msgid "Deployment|Triggerer"
+msgstr ""
+
msgid "Deployment|Waiting"
msgstr ""
@@ -12438,6 +12631,18 @@ msgstr ""
msgid "Deprecated API rate limits"
msgstr ""
+msgid "Deprecations|Feature deprecation and removal"
+msgstr ""
+
+msgid "Deprecations|For information on a possible replacement %{epicStart} learn more about Opstrace %{epicEnd}."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7 and are %{epicStart} scheduled for removal %{epicEnd} in GitLab 15.0."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7, and are %{removal_link_start} scheduled for removal %{link_end} in GitLab 15.0. For information on a possible replacement, %{opstrace_link_start} learn more about Opstrace %{link_end}."
+msgstr ""
+
msgid "Deprioritize label"
msgstr ""
@@ -12685,10 +12890,10 @@ msgstr ""
msgid "DevopsAdoption|At least one deploy"
msgstr ""
-msgid "DevopsAdoption|At least one issue opened"
+msgid "DevopsAdoption|At least one issue created"
msgstr ""
-msgid "DevopsAdoption|At least one merge request opened"
+msgid "DevopsAdoption|At least one merge request created"
msgstr ""
msgid "DevopsAdoption|At least one pipeline successfully run"
@@ -12895,6 +13100,9 @@ msgstr ""
msgid "Direct member"
msgstr ""
+msgid "Direct members"
+msgstr ""
+
msgid "Direct non-authenticated users to this page."
msgstr ""
@@ -13013,6 +13221,9 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "Dismiss Alert"
+msgstr ""
+
msgid "Dismiss merge request promotion"
msgstr ""
@@ -13040,9 +13251,15 @@ msgstr ""
msgid "Display alerts from all configured monitoring tools."
msgstr ""
+msgid "Display milestones"
+msgstr ""
+
msgid "Display name"
msgstr ""
+msgid "Display progress of child issues"
+msgstr ""
+
msgid "Display rendered file"
msgstr ""
@@ -13148,6 +13365,9 @@ msgstr ""
msgid "Download image"
msgstr ""
+msgid "Download payload"
+msgstr ""
+
msgid "Download raw data (.csv)"
msgstr ""
@@ -13325,6 +13545,9 @@ msgstr ""
msgid "Edit in Web IDE"
msgstr ""
+msgid "Edit in pipeline editor"
+msgstr ""
+
msgid "Edit in single-file editor"
msgstr ""
@@ -13367,6 +13590,9 @@ msgstr ""
msgid "Edit your most recent comment in a thread (from an empty textarea)"
msgstr ""
+msgid "Edit, lint, and visualize your pipeline."
+msgstr ""
+
msgid "Edited"
msgstr ""
@@ -13808,6 +14034,9 @@ msgstr ""
msgid "Enforce two-factor authentication for all user sign-ins."
msgstr ""
+msgid "Enhance security by storing service account keys in secret managers - learn more about %{docLinkStart}secret management with GitLab%{docLinkEnd}"
+msgstr ""
+
msgid "Ensure connectivity is available from the GitLab server to the Prometheus server"
msgstr ""
@@ -13868,6 +14097,9 @@ 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 following to confirm:"
+msgstr ""
+
msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
@@ -14400,9 +14632,6 @@ 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 ""
@@ -14538,6 +14767,9 @@ msgstr ""
msgid "Errors:"
msgstr ""
+msgid "Escalate this incident"
+msgstr ""
+
msgid "Escalation Policies"
msgstr ""
@@ -14550,6 +14782,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy"
+msgstr ""
+
msgid "Escalation policy:"
msgstr ""
@@ -14803,6 +15038,9 @@ msgstr ""
msgid "Existing sign in methods may be removed"
msgstr ""
+msgid "Exit."
+msgstr ""
+
msgid "Expand"
msgstr ""
@@ -14899,6 +15137,9 @@ msgstr ""
msgid "Explore public groups"
msgstr ""
+msgid "Explore public projects"
+msgstr ""
+
msgid "Explore snippets"
msgstr ""
@@ -15062,7 +15303,7 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
-msgid "Failed to assign a reviewer because no user was found."
+msgid "Failed to assign a reviewer because no user was specified."
msgstr ""
msgid "Failed to assign a user because no user was found."
@@ -15128,10 +15369,10 @@ msgstr ""
msgid "Failed to find import label for Jira import."
msgstr ""
-msgid "Failed to generate export, please try again later."
+msgid "Failed to find users for %{missing}"
msgstr ""
-msgid "Failed to generate report, please try again after sometime"
+msgid "Failed to generate export, please try again later."
msgstr ""
msgid "Failed to get ref."
@@ -15230,6 +15471,9 @@ msgstr ""
msgid "Failed to remove a to-do item for the design."
msgstr ""
+msgid "Failed to remove attention because no user was found."
+msgstr ""
+
msgid "Failed to remove mirror."
msgstr ""
@@ -15242,6 +15486,9 @@ msgstr ""
msgid "Failed to remove user key."
msgstr ""
+msgid "Failed to request attention because no user was found."
+msgstr ""
+
msgid "Failed to reset key. Please try again."
msgstr ""
@@ -15323,6 +15570,9 @@ msgstr ""
msgid "Feature Flags"
msgstr ""
+msgid "Feature deprecation and removal"
+msgstr ""
+
msgid "Feature flag status"
msgstr ""
@@ -15822,7 +16072,7 @@ msgstr ""
msgid "For each job, re-use the project workspace. If the workspace doesn't exist, use %{code_open}git clone%{code_close}."
msgstr ""
-msgid "For example, the application using the token or the purpose of the token."
+msgid "For example, the application using the token or the purpose of the token. Do not give sensitive information for the name of the token, as it will be visible to all %{resource_type} members."
msgstr ""
msgid "For files larger than this limit, only index the file name. The file content is neither indexed nor searchable."
@@ -15906,9 +16156,6 @@ msgstr ""
msgid "ForkProject|Select a namespace"
msgstr ""
-msgid "ForkProject|Select a namespace to fork the project"
-msgstr ""
-
msgid "ForkProject|The project can be accessed by any logged in user."
msgstr ""
@@ -16005,6 +16252,9 @@ msgstr ""
msgid "Full name"
msgstr ""
+msgid "GCP region configured"
+msgstr ""
+
msgid "GPG Key ID:"
msgstr ""
@@ -16185,6 +16435,9 @@ msgstr ""
msgid "Geo|Failed"
msgstr ""
+msgid "Geo|Filter Geo sites"
+msgstr ""
+
msgid "Geo|Filter by name"
msgstr ""
@@ -16596,6 +16849,12 @@ msgstr ""
msgid "GitLab Issue"
msgstr ""
+msgid "GitLab KAS"
+msgstr ""
+
+msgid "GitLab Memberships CSV Export"
+msgstr ""
+
msgid "GitLab Pages"
msgstr ""
@@ -16644,6 +16903,9 @@ 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 free to use. Many features for larger teams are part of our %{link_start}paid products%{link_end}. You can try Ultimate for free without any obligation or payment details."
+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 ""
@@ -16770,7 +17032,7 @@ msgstr ""
msgid "GitLabPages|When enabled, all attempts to visit your website through HTTP are automatically redirected to HTTPS using a response with status code 301. Requires a valid certificate for all domains. %{docs_link_start}Learn more.%{link_end}"
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. %{docs_link_start}Learn more.%{link_end}"
+msgid "GitLabPages|When using Pages under the general domain of a GitLab instance (%{pages_host}), you cannot use HTTPS with subdomains of subdomains. If your namespace or groupname contains a dot, it does not work. This is a limitation of the HTTP Over TLS protocol. HTTP pages work if you don't redirect HTTP to HTTPS. %{docs_link_start}Learn more.%{link_end}"
msgstr ""
msgid "GitLabPages|With GitLab Pages you can host your static website directly from your GitLab repository. %{docs_link_start}Learn more.%{link_end}"
@@ -16947,9 +17209,6 @@ msgstr ""
msgid "Go to find file"
msgstr ""
-msgid "Go to fork"
-msgstr ""
-
msgid "Go to issue boards"
msgstr ""
@@ -17157,9 +17416,6 @@ msgstr ""
msgid "Group Hooks"
msgstr ""
-msgid "Group ID"
-msgstr ""
-
msgid "Group Owner must have signed in with SAML before enabling Group Managed Accounts"
msgstr ""
@@ -17187,9 +17443,6 @@ msgstr ""
msgid "Group by"
msgstr ""
-msgid "Group description"
-msgstr ""
-
msgid "Group description (optional)"
msgstr ""
@@ -17304,7 +17557,7 @@ msgstr ""
msgid "Group: %{name}"
msgstr ""
-msgid "GroupActivityMetrics|Issues opened"
+msgid "GroupActivityMetrics|Issues created"
msgstr ""
msgid "GroupActivityMetrics|Last 90 days"
@@ -17313,7 +17566,7 @@ msgstr ""
msgid "GroupActivityMetrics|Members added"
msgstr ""
-msgid "GroupActivityMetrics|Merge Requests opened"
+msgid "GroupActivityMetrics|Merge Requests created"
msgstr ""
msgid "GroupActivityMetrics|Recent activity"
@@ -17604,6 +17857,9 @@ msgstr ""
msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
+msgid "GroupSettings|Choose a group path that does not start with a dash or end with a period. It can also contain alphanumeric characters and underscores."
+msgstr ""
+
msgid "GroupSettings|Compliance frameworks"
msgstr ""
@@ -17637,7 +17893,7 @@ msgstr ""
msgid "GroupSettings|If not specified at the group or instance level, the default is %{default_initial_branch_name}. Does not affect existing repositories."
msgstr ""
-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."
+msgid "GroupSettings|If the parent group's visibility is lower than the group's current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility."
msgstr ""
msgid "GroupSettings|New runners registration token has been generated!"
@@ -17754,7 +18010,10 @@ msgstr ""
msgid "Groups and projects"
msgstr ""
-msgid "Groups and subgroups"
+msgid "Groups are a great way to organize projects and people."
+msgstr ""
+
+msgid "Groups are the best way to manage projects and members."
msgstr ""
msgid "Groups to synchronize"
@@ -17865,13 +18124,16 @@ msgstr ""
msgid "GroupsTree|Are you sure you want to leave the \"%{fullName}\" group?"
msgstr ""
-msgid "GroupsTree|Edit group"
+msgid "GroupsTree|Delete"
+msgstr ""
+
+msgid "GroupsTree|Edit"
msgstr ""
msgid "GroupsTree|Failed to leave the group. Please make sure you are not the only owner."
msgstr ""
-msgid "GroupsTree|Leave this group"
+msgid "GroupsTree|Leave group"
msgstr ""
msgid "GroupsTree|Loading groups"
@@ -17883,9 +18145,57 @@ msgstr ""
msgid "GroupsTree|No groups or projects matched your search"
msgstr ""
+msgid "GroupsTree|Options"
+msgstr ""
+
msgid "GroupsTree|Search by name"
msgstr ""
+msgid "Groups|Avatar will be removed. Are you sure?"
+msgstr ""
+
+msgid "Groups|Changing group URL can have unintended side effects."
+msgstr ""
+
+msgid "Groups|Checking group URL availability..."
+msgstr ""
+
+msgid "Groups|Enter a descriptive name for your group."
+msgstr ""
+
+msgid "Groups|Group ID"
+msgstr ""
+
+msgid "Groups|Group URL"
+msgstr ""
+
+msgid "Groups|Group avatar"
+msgstr ""
+
+msgid "Groups|Group description (optional)"
+msgstr ""
+
+msgid "Groups|Group name"
+msgstr ""
+
+msgid "Groups|Group path is available."
+msgstr ""
+
+msgid "Groups|Group path is unavailable. Path has been replaced with a suggested available path."
+msgstr ""
+
+msgid "Groups|Learn more"
+msgstr ""
+
+msgid "Groups|Must start with letter, digit, emoji, or underscore. Can also contain periods, dashes, spaces, and parentheses."
+msgstr ""
+
+msgid "Groups|Remove avatar"
+msgstr ""
+
+msgid "Groups|Save changes"
+msgstr ""
+
msgid "Guideline"
msgstr ""
@@ -17895,6 +18205,9 @@ msgstr ""
msgid "HAR file path or URL"
msgstr ""
+msgid "HTTP Archive (HAR)"
+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 ""
@@ -18299,6 +18612,9 @@ msgstr ""
msgid "INFO: Your SSH key is expiring soon. Please generate a new key."
msgstr ""
+msgid "IP"
+msgstr ""
+
msgid "IP Address"
msgstr ""
@@ -18335,6 +18651,9 @@ msgstr ""
msgid "IdentityVerification|Verify your identity"
msgstr ""
+msgid "IdentityVerification|You can always verify your account at a later time to create a group."
+msgstr ""
+
msgid "If any indexed field exceeds this limit, it is truncated to this number of characters. The rest of the content is neither indexed nor searchable. This does not apply to repository and wiki indexing. For unlimited characters, set this to 0."
msgstr ""
@@ -18392,6 +18711,9 @@ msgstr ""
msgid "If you add %{codeStart}needs%{codeEnd} to jobs in your pipeline you'll be able to view the %{codeStart}needs%{codeEnd} relationships between jobs in this tab as a %{linkStart}Directed Acyclic Graph (DAG)%{linkEnd}."
msgstr ""
+msgid "If you are added to a project, it will be displayed here."
+msgstr ""
+
msgid "If you did not initiate these sign-in attempts, please reach out to your administrator or enable two-factor authentication (2FA) on your account."
msgstr ""
@@ -18704,12 +19026,24 @@ msgstr ""
msgid "InProductMarketing|3 ways to dive into GitLab CI/CD"
msgstr ""
+msgid "InProductMarketing|A single application eliminates complex integrations, data chokepoints, and toolchain maintenance, resulting in greater productivity and lower cost."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features, build more efficiently, strengthen security and compliance."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features."
+msgstr ""
+
msgid "InProductMarketing|Actually, GitLab makes the team work (better)"
msgstr ""
msgid "InProductMarketing|And finally %{deploy_link} a Python application."
msgstr ""
+msgid "InProductMarketing|And many more..."
+msgstr ""
+
msgid "InProductMarketing|Are your runners ready?"
msgstr ""
@@ -18728,15 +19062,33 @@ msgstr ""
msgid "InProductMarketing|Blog"
msgstr ""
+msgid "InProductMarketing|Break down silos to coordinate seamlessly across development, operations, and security with a consistent experience across the development lifecycle."
+msgstr ""
+
+msgid "InProductMarketing|Burn up/down charts"
+msgstr ""
+
msgid "InProductMarketing|By enabling code owners and required merge approvals the right person will review the right MR. This is a win-win: cleaner code and a more efficient review process."
msgstr ""
msgid "InProductMarketing|Click on the number below that corresponds with your answer — 1 being very difficult, 5 being very easy."
msgstr ""
+msgid "InProductMarketing|Code owners"
+msgstr ""
+
msgid "InProductMarketing|Code owners and required merge approvals are part of the paid tiers of GitLab. You can start a free 30-day trial of GitLab Ultimate and enable these features in less than 5 minutes with no credit card required."
msgstr ""
+msgid "InProductMarketing|Code review analytics"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration across stages in GitLab"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration made easy"
+msgstr ""
+
msgid "InProductMarketing|Create a custom CI runner with just a few clicks"
msgstr ""
@@ -18746,12 +19098,21 @@ msgstr ""
msgid "InProductMarketing|Create a project in GitLab in 5 minutes"
msgstr ""
+msgid "InProductMarketing|Create well-defined workflows by using scoped labels on issues, merge requests, and epics. Labels with the same scope cannot be used together, which prevents conflicts."
+msgstr ""
+
msgid "InProductMarketing|Create your first project!"
msgstr ""
+msgid "InProductMarketing|Define who owns specific files or directories, so the right reviewers are suggested when a merge request introduces changes to those files."
+msgstr ""
+
msgid "InProductMarketing|Deliver Better Products Faster"
msgstr ""
+msgid "InProductMarketing|Dependency scanning"
+msgstr ""
+
msgid "InProductMarketing|Did you know teams that use GitLab are far more efficient?"
msgstr ""
@@ -18761,15 +19122,27 @@ msgstr ""
msgid "InProductMarketing|Dig in and create a project and a repo"
msgstr ""
+msgid "InProductMarketing|Discover Premium & Ultimate"
+msgstr ""
+
+msgid "InProductMarketing|Discover Premium & Ultimate."
+msgstr ""
+
msgid "InProductMarketing|Do you have a minute?"
msgstr ""
msgid "InProductMarketing|Do you have a teammate who would be perfect for this task?"
msgstr ""
+msgid "InProductMarketing|Dynamic application security testing"
+msgstr ""
+
msgid "InProductMarketing|Easy"
msgstr ""
+msgid "InProductMarketing|Epics"
+msgstr ""
+
msgid "InProductMarketing|Expand your DevOps journey with a free GitLab trial"
msgstr ""
@@ -18791,9 +19164,15 @@ msgstr ""
msgid "InProductMarketing|Feel the need for speed?"
msgstr ""
+msgid "InProductMarketing|Find and fix bottlenecks in your code review process by understanding how long open merge requests have been in review."
+msgstr ""
+
msgid "InProductMarketing|Find out how your teams are really doing"
msgstr ""
+msgid "InProductMarketing|Find out if your external libraries are safe. Run dependency scanning jobs that check for known vulnerabilities in your external libraries."
+msgstr ""
+
msgid "InProductMarketing|Follow our steps"
msgstr ""
@@ -18830,6 +19209,9 @@ msgstr ""
msgid "InProductMarketing|GitLab is better with teammates to help out!"
msgstr ""
+msgid "InProductMarketing|GitLab is infrastructure agnostic (supporting GCP, AWS, Azure, OpenShift, VMWare, On Prem, Bare Metal, and more), offering a consistent workflow experience – irrespective of the environment."
+msgstr ""
+
msgid "InProductMarketing|GitLab provides static application security testing (SAST), dynamic application security testing (DAST), container scanning, and dependency scanning to help you deliver secure applications along with license compliance."
msgstr ""
@@ -18920,21 +19302,36 @@ msgstr ""
msgid "InProductMarketing|It's also possible to simply %{external_repo_link} in order to take advantage of GitLab's CI/CD."
msgstr ""
+msgid "InProductMarketing|Keep your code quality high by defining who should approve merge requests and how many approvals are required."
+msgstr ""
+
msgid "InProductMarketing|Launch GitLab CI/CD in 20 minutes or less"
msgstr ""
+msgid "InProductMarketing|Lower cost of development"
+msgstr ""
+
+msgid "InProductMarketing|Make it easier to collaborate on high-level ideas by grouping related issues in an epic."
+msgstr ""
+
msgid "InProductMarketing|Making the switch? It's easier than you think to import your projects into GitLab. Move %{github_link}, or import something %{bitbucket_link}."
msgstr ""
msgid "InProductMarketing|Master the art of importing!"
msgstr ""
+msgid "InProductMarketing|Merge request approval rule"
+msgstr ""
+
msgid "InProductMarketing|Move on to easily creating a Pages website %{ci_template_link}"
msgstr ""
msgid "InProductMarketing|Multiple owners, confusing workstreams? We've got you covered"
msgstr ""
+msgid "InProductMarketing|Multiple required approvers"
+msgstr ""
+
msgid "InProductMarketing|Need an alternative to importing?"
msgstr ""
@@ -18947,18 +19344,33 @@ msgstr ""
msgid "InProductMarketing|Our tool brings all the things together"
msgstr ""
+msgid "InProductMarketing|Protect your web application by using DAST to examine for vulnerabilities in deployed environments."
+msgstr ""
+
msgid "InProductMarketing|Rapid development, simplified"
msgstr ""
msgid "InProductMarketing|Reduce Security & Compliance Risk"
msgstr ""
+msgid "InProductMarketing|Require multiple approvers on a merge request, so you know it's in good shape before it's merged."
+msgstr ""
+
+msgid "InProductMarketing|Roadmaps"
+msgstr ""
+
+msgid "InProductMarketing|Scoped labels"
+msgstr ""
+
msgid "InProductMarketing|Security that's integrated into your development lifecycle"
msgstr ""
msgid "InProductMarketing|Sometimes you're not ready to make a full transition to a new tool. If you're not ready to fully commit, %{mirroring_link} gives you a safe way to try out GitLab in parallel with your current tool."
msgstr ""
+msgid "InProductMarketing|Speed. Efficiency. Trust."
+msgstr ""
+
msgid "InProductMarketing|Spin up an autoscaling runner in GitLab"
msgstr ""
@@ -18968,6 +19380,9 @@ msgstr ""
msgid "InProductMarketing|Start a Self-Managed trial"
msgstr ""
+msgid "InProductMarketing|Start a free trial"
+msgstr ""
+
msgid "InProductMarketing|Start a free trial of GitLab Ultimate – no credit card required"
msgstr ""
@@ -19034,6 +19449,9 @@ msgstr ""
msgid "InProductMarketing|To understand and get the most out of GitLab, start at the beginning and %{project_link}. In GitLab, repositories are part of a project, so after you've created your project you can go ahead and %{repo_link}."
msgstr ""
+msgid "InProductMarketing|Track completed issues in a chart, so you can see how a milestone is progressing at a glance."
+msgstr ""
+
msgid "InProductMarketing|Try GitLab Ultimate for free"
msgstr ""
@@ -19070,6 +19488,9 @@ msgstr ""
msgid "InProductMarketing|Very easy"
msgstr ""
+msgid "InProductMarketing|Visualize your epics and milestones in a timeline."
+msgstr ""
+
msgid "InProductMarketing|Want to host GitLab on your servers?"
msgstr ""
@@ -19091,6 +19512,9 @@ msgstr ""
msgid "InProductMarketing|YouTube"
msgstr ""
+msgid "InProductMarketing|Your software, deployed your way"
+msgstr ""
+
msgid "InProductMarketing|Your teams can be more efficient"
msgstr ""
@@ -19211,9 +19635,18 @@ msgstr ""
msgid "IncidentManagement|No incidents to display."
msgstr ""
+msgid "IncidentManagement|None"
+msgstr ""
+
msgid "IncidentManagement|Open"
msgstr ""
+msgid "IncidentManagement|Page your team with escalation policies"
+msgstr ""
+
+msgid "IncidentManagement|Paged"
+msgstr ""
+
msgid "IncidentManagement|Published"
msgstr ""
@@ -19223,6 +19656,9 @@ msgstr ""
msgid "IncidentManagement|Severity"
msgstr ""
+msgid "IncidentManagement|Status"
+msgstr ""
+
msgid "IncidentManagement|There are no closed incidents"
msgstr ""
@@ -19241,6 +19677,9 @@ msgstr ""
msgid "IncidentManagement|Unpublished"
msgstr ""
+msgid "IncidentManagement|Use escalation policies to automatically page your team when incidents are created."
+msgstr ""
+
msgid "IncidentSettings|Activate \"time to SLA\" countdown timer"
msgstr ""
@@ -19286,7 +19725,10 @@ msgstr ""
msgid "Incidents"
msgstr ""
-msgid "Incidents|Add a URL"
+msgid "Incidents|Add image details"
+msgstr ""
+
+msgid "Incidents|Add text or a link to display with your image. If you don't add either, the file name displays instead."
msgstr ""
msgid "Incidents|Drop or %{linkStart}upload%{linkEnd} a metric screenshot to attach it to the incident"
@@ -19301,10 +19743,10 @@ msgstr ""
msgid "Incidents|There was an issue loading metric images."
msgstr ""
-msgid "Incidents|There was an issue uploading your image."
+msgid "Incidents|There was an issue updating your image."
msgstr ""
-msgid "Incidents|You can optionally add a URL to link users to the original graph."
+msgid "Incidents|There was an issue uploading your image."
msgstr ""
msgid "Incident|Alert details"
@@ -19313,9 +19755,18 @@ msgstr ""
msgid "Incident|Are you sure you wish to delete this image?"
msgstr ""
+msgid "Incident|Delete image"
+msgstr ""
+
msgid "Incident|Deleting %{filename}"
msgstr ""
+msgid "Incident|Edit image text or link"
+msgstr ""
+
+msgid "Incident|Editing %{filename}"
+msgstr ""
+
msgid "Incident|Metrics"
msgstr ""
@@ -19587,12 +20038,18 @@ msgstr ""
msgid "Integrations|Branches for which notifications are to be sent"
msgstr ""
+msgid "Integrations|Clear if using a self-signed certificate."
+msgstr ""
+
msgid "Integrations|Comment detail:"
msgstr ""
msgid "Integrations|Comment settings:"
msgstr ""
+msgid "Integrations|Connection details"
+msgstr ""
+
msgid "Integrations|Connection failed. Please check your settings."
msgstr ""
@@ -19617,6 +20074,9 @@ msgstr ""
msgid "Integrations|Enable GitLab.com slash commands in a Slack workspace."
msgstr ""
+msgid "Integrations|Enable SSL verification"
+msgstr ""
+
msgid "Integrations|Enable comments"
msgstr ""
@@ -19695,6 +20155,9 @@ msgstr ""
msgid "Integrations|Return to GitLab for Jira"
msgstr ""
+msgid "Integrations|SSL verification"
+msgstr ""
+
msgid "Integrations|Save settings?"
msgstr ""
@@ -19740,9 +20203,6 @@ msgstr ""
msgid "Integrations|Use default settings"
msgstr ""
-msgid "Integrations|When you mention a Jira issue in a commit or merge request, GitLab creates a remote link and comment (if enabled)."
-msgstr ""
-
msgid "Integrations|You can now close this window and return to the GitLab for Jira application."
msgstr ""
@@ -19767,9 +20227,6 @@ msgstr ""
msgid "Integrations|can't exceed %{recipients_limit}"
msgstr ""
-msgid "Interactive developer security education."
-msgstr ""
-
msgid "Interactive mode"
msgstr ""
@@ -20259,6 +20716,9 @@ msgstr ""
msgid "IssueAnalytics|Assignees"
msgstr ""
+msgid "IssueAnalytics|Created by"
+msgstr ""
+
msgid "IssueAnalytics|Due date"
msgstr ""
@@ -20271,9 +20731,6 @@ msgstr ""
msgid "IssueAnalytics|Milestone"
msgstr ""
-msgid "IssueAnalytics|Opened by"
-msgstr ""
-
msgid "IssueAnalytics|Status"
msgstr ""
@@ -20397,10 +20854,10 @@ msgstr ""
msgid "IssuesAnalytics|Avg/Month:"
msgstr ""
-msgid "IssuesAnalytics|Issues opened"
+msgid "IssuesAnalytics|Issues created"
msgstr ""
-msgid "IssuesAnalytics|Issues opened per month"
+msgid "IssuesAnalytics|Issues created per month"
msgstr ""
msgid "IssuesAnalytics|Last 12 months"
@@ -20427,6 +20884,9 @@ msgstr ""
msgid "It looks like you have some draft commits in this branch."
msgstr ""
+msgid "It looks like you're attempting to activate your subscription. Use %{a_start}the Subscription page%{a_end} instead."
+msgstr ""
+
msgid "It may be several days before you see feature usage data."
msgstr ""
@@ -20655,6 +21115,9 @@ msgstr ""
msgid "JiraConnect|You can now close this window and return to Jira."
msgstr ""
+msgid "JiraConnect|You don't have permission to create branches for this project. Select a different project or contact the project owner for access. %{linkStart}Learn more.%{linkEnd}"
+msgstr ""
+
msgid "JiraRequest|A connection error occurred while connecting to Jira. Try your request again."
msgstr ""
@@ -20703,13 +21166,13 @@ msgstr ""
msgid "JiraService|Define the type of Jira issue to create from a vulnerability."
msgstr ""
-msgid "JiraService|Displaying Jira issues while leaving the GitLab issue functionality enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
+msgid "JiraService|Displaying Jira issues while leaving GitLab issues also enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
msgstr ""
-msgid "JiraService|Enable Jira issues"
+msgid "JiraService|Enable Jira issue creation from vulnerabilities"
msgstr ""
-msgid "JiraService|Enable Jira issues creation from vulnerabilities"
+msgid "JiraService|Enable Jira issues"
msgstr ""
msgid "JiraService|Enable Jira transitions"
@@ -20826,16 +21289,19 @@ msgstr ""
msgid "JiraService|View Jira issues in GitLab"
msgstr ""
-msgid "JiraService|Warning: All GitLab users that have access to this GitLab project are able to view all issues from the Jira project specified below."
+msgid "JiraService|Warning: All GitLab users with access to this GitLab project can view all issues from the Jira project you select."
msgstr ""
msgid "JiraService|Web URL"
msgstr ""
-msgid "JiraService|Work on Jira issues without leaving GitLab. Adds a Jira menu to access your list of Jira issues and view any issue as read-only."
+msgid "JiraService|When a Jira issue is mentioned in a commit or merge request, a remote link and comment (if enabled) will be created."
+msgstr ""
+
+msgid "JiraService|Work on Jira issues without leaving GitLab. Add a Jira menu to access a read-only list of your Jira issues."
msgstr ""
-msgid "JiraService|You need to configure Jira before enabling this integration. For more details, read the %{jira_doc_link_start}Jira integration documentation%{link_end}."
+msgid "JiraService|You must configure Jira before enabling this integration. %{jira_doc_link_start}Learn more.%{link_end}"
msgstr ""
msgid "Job"
@@ -20847,9 +21313,6 @@ msgstr ""
msgid "Job Failed #%{build_id}"
msgstr ""
-msgid "Job ID"
-msgstr ""
-
msgid "Job artifact"
msgstr ""
@@ -20916,9 +21379,27 @@ msgstr ""
msgid "Jobs|You're about to retry a job that failed because it attempted to deploy code that is older than the latest deployment. Retrying this job could result in overwriting the environment with the older source code."
msgstr ""
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source} into %{target}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{ref}"
+msgstr ""
+
+msgid "Job|Are you sure you want to erase this job log and artifacts?"
+msgstr ""
+
msgid "Job|Browse"
msgstr ""
+msgid "Job|Cancel"
+msgstr ""
+
msgid "Job|Complete Raw"
msgstr ""
@@ -20928,6 +21409,9 @@ msgstr ""
msgid "Job|Erase job log and artifacts"
msgstr ""
+msgid "Job|Finished at"
+msgstr ""
+
msgid "Job|Job artifacts"
msgstr ""
@@ -20940,7 +21424,7 @@ msgstr ""
msgid "Job|Keep"
msgstr ""
-msgid "Job|Pipeline"
+msgid "Job|Retry"
msgstr ""
msgid "Job|Scroll to bottom"
@@ -20952,6 +21436,9 @@ msgstr ""
msgid "Job|Show complete raw"
msgstr ""
+msgid "Job|Status"
+msgstr ""
+
msgid "Job|The artifacts were removed"
msgstr ""
@@ -20979,21 +21466,12 @@ msgstr ""
msgid "Job|delayed"
msgstr ""
-msgid "Job|for"
-msgstr ""
-
-msgid "Job|into"
-msgstr ""
-
msgid "Job|manual"
msgstr ""
msgid "Job|triggered"
msgstr ""
-msgid "Job|with"
-msgstr ""
-
msgid "Join Zoom meeting"
msgstr ""
@@ -21096,9 +21574,6 @@ msgstr ""
msgid "Ki"
msgstr ""
-msgid "Kontra"
-msgstr ""
-
msgid "Kroki"
msgstr ""
@@ -21424,6 +21899,9 @@ msgstr ""
msgid "Learn more about Auto DevOps"
msgstr ""
+msgid "Learn more about GitLab"
+msgstr ""
+
msgid "Learn more about Needs relationships"
msgstr ""
@@ -21763,9 +22241,18 @@ msgstr ""
msgid "Licenses|Displays licenses detected in the project, based on the %{linkStart}latest successful%{linkEnd} scan"
msgstr ""
+msgid "Licenses|Drag your license file here or %{linkStart}click to upload%{linkEnd}."
+msgstr ""
+
+msgid "Licenses|Drop your license file to start the upload."
+msgstr ""
+
msgid "Licenses|Error fetching the license list. Please check your network connection and try again."
msgstr ""
+msgid "Licenses|Error: You are trying to upload something other than a file"
+msgstr ""
+
msgid "Licenses|License Compliance"
msgstr ""
@@ -21784,6 +22271,9 @@ msgstr ""
msgid "Licenses|Specified policies in this project"
msgstr ""
+msgid "Licenses|The file could not be uploaded."
+msgstr ""
+
msgid "Licenses|The license list details information about the licenses used within your project."
msgstr ""
@@ -21817,13 +22307,6 @@ msgstr ""
msgid "Limit the size of Sidekiq jobs stored in Redis."
msgstr ""
-msgid "Limited to showing %d event at most"
-msgid_plural "Limited to showing %d events at most"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-msgstr[3] ""
-
msgid "Limiting mode"
msgstr ""
@@ -21833,6 +22316,9 @@ msgstr ""
msgid "Link"
msgstr ""
+msgid "Link (optional)"
+msgstr ""
+
msgid "Link Prometheus monitoring to GitLab."
msgstr ""
@@ -21869,6 +22355,9 @@ msgstr ""
msgid "Linked emails (%{email_count})"
msgstr ""
+msgid "Linked epics"
+msgstr ""
+
msgid "Linked issues"
msgstr ""
@@ -21896,6 +22385,15 @@ msgstr ""
msgid "List of all merge commits"
msgstr ""
+msgid "List of environments for this project"
+msgstr ""
+
+msgid "List of suitable GCP locations"
+msgstr ""
+
+msgid "List of users allowed to exceed the rate limit."
+msgstr ""
+
msgid "List options"
msgstr ""
@@ -22115,6 +22613,9 @@ msgstr ""
msgid "Maintenance mode"
msgstr ""
+msgid "Make adjustments to how your GitLab instance is set up."
+msgstr ""
+
msgid "Make and review changes in the browser with the Web IDE"
msgstr ""
@@ -22259,6 +22760,12 @@ msgstr ""
msgid "MarkdownEditor|Add italic text (%{modifier_key}I)"
msgstr ""
+msgid "MarkdownEditor|Add strikethrough text (%{modifierKey}⇧X)"
+msgstr ""
+
+msgid "MarkdownEditor|Add strikethrough text (%{modifier_key}⇧X)"
+msgstr ""
+
msgid "Marked For Deletion At - %{deletion_time}"
msgstr ""
@@ -22520,6 +23027,9 @@ msgstr ""
msgid "Maximum push size (MB)"
msgstr ""
+msgid "Maximum requests per 10 minutes per user"
+msgstr ""
+
msgid "Maximum requests per minute"
msgstr ""
@@ -22610,6 +23120,23 @@ msgstr ""
msgid "Members of a group may only view projects they have permission to access"
msgstr ""
+msgid "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seat in use and will be billed for the overage."
+msgid_plural "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seats in use and will be billed for the overage."
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
+msgid "MembersOverage|You are about to incur additional charges"
+msgstr ""
+
+msgid "MembersOverage|Your subscription includes %d seat."
+msgid_plural "MembersOverage|Your subscription includes %d seats."
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "Membership"
msgstr ""
@@ -22814,9 +23341,6 @@ msgstr ""
msgid "Merge request not merged"
msgstr ""
-msgid "Merge request pipelines 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 merge request pipelines."
-msgstr ""
-
msgid "Merge request reports"
msgstr ""
@@ -22913,13 +23437,13 @@ msgstr ""
msgid "MergeRequests|Create issue to resolve thread"
msgstr ""
-msgid "MergeRequests|Failed to squash. Should be done manually."
+msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Saving the comment failed"
+msgid "MergeRequests|Squashing failed: Squash the commits locally, resolve any conflicts, then push the branch."
msgstr ""
-msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
+msgid "MergeRequests|Squashing not allowed: This project doesn't allow you to squash commits when merging."
msgstr ""
msgid "MergeRequests|Thread stays resolved"
@@ -23764,6 +24288,18 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "MrList|Assigned to %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from assignee %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from reviewer %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Review requested from %{name}, go to their profile."
+msgstr ""
+
msgid "Multi-project"
msgstr ""
@@ -23797,7 +24333,7 @@ msgstr ""
msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "My Awesome Group"
+msgid "My awesome group"
msgstr ""
msgid "My company or team"
@@ -24423,9 +24959,6 @@ msgstr ""
msgid "No available branches"
msgstr ""
-msgid "No available groups to fork the project."
-msgstr ""
-
msgid "No branches found"
msgstr ""
@@ -24636,6 +25169,9 @@ msgstr ""
msgid "No ref selected"
msgstr ""
+msgid "No regions configured"
+msgstr ""
+
msgid "No related merge requests found."
msgstr ""
@@ -25452,6 +25988,9 @@ msgstr ""
msgid "Only reCAPTCHA v2 is supported:"
msgstr ""
+msgid "Only required if not using role instance credentials."
+msgstr ""
+
msgid "Only use lowercase letters, numbers, and underscores."
msgstr ""
@@ -25476,9 +26015,6 @@ msgstr ""
msgid "Open a CLI and connect to the cluster you want to install the agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
-msgid "Open epics"
-msgstr ""
-
msgid "Open errors"
msgstr ""
@@ -25518,7 +26054,7 @@ msgstr ""
msgid "Opened issues"
msgstr ""
-msgid "OpenedNDaysAgo|Opened"
+msgid "OpenedNDaysAgo|Created"
msgstr ""
msgid "Opens in a new window"
@@ -25563,9 +26099,6 @@ msgstr ""
msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
-msgid "Optional."
-msgstr ""
-
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
msgstr ""
@@ -26356,6 +26889,9 @@ msgstr ""
msgid "PerformanceBar|Memory"
msgstr ""
+msgid "PerformanceBar|Memory report"
+msgstr ""
+
msgid "PerformanceBar|Redis calls"
msgstr ""
@@ -26389,18 +26925,12 @@ msgstr ""
msgid "PerformanceBar|wall"
msgstr ""
-msgid "Performs a rebase but skips triggering a new pipeline"
-msgstr ""
-
msgid "Period in seconds"
msgstr ""
msgid "Permalink"
msgstr ""
-msgid "Permanently delete project"
-msgstr ""
-
msgid "Permanently remove group"
msgstr ""
@@ -26671,6 +27201,51 @@ msgstr ""
msgid "PipelineStatusTooltip|Pipeline: %{ci_status}"
msgstr ""
+msgid "PipelineWizardDefaultCommitMessage|Add %{filename}"
+msgstr ""
+
+msgid "PipelineWizardDefaultCommitMessage|Update %{filename}"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|At least one entry is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This field is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This value is not valid"
+msgstr ""
+
+msgid "PipelineWizardListWidget|add another step"
+msgstr ""
+
+msgid "PipelineWizardListWidget|remove step"
+msgstr ""
+
+msgid "PipelineWizard|Commit"
+msgstr ""
+
+msgid "PipelineWizard|Commit Message"
+msgstr ""
+
+msgid "PipelineWizard|Commit changes to your file"
+msgstr ""
+
+msgid "PipelineWizard|Commit file to Branch"
+msgstr ""
+
+msgid "PipelineWizard|Commit your new file"
+msgstr ""
+
+msgid "PipelineWizard|The file has been committed."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem committing the changes."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem while checking whether your file already exists in the specified branch."
+msgstr ""
+
msgid "Pipelines"
msgstr ""
@@ -26785,7 +27360,7 @@ msgstr ""
msgid "Pipelines|Project cache successfully reset."
msgstr ""
-msgid "Pipelines|Revoke"
+msgid "Pipelines|Revoke trigger"
msgstr ""
msgid "Pipelines|Something went wrong while cleaning runners cache."
@@ -26830,6 +27405,12 @@ msgstr ""
msgid "Pipelines|This is a child pipeline within the parent pipeline"
msgstr ""
+msgid "Pipelines|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipelines|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipelines|This pipeline will run code originating from a forked project merge request. This means that the code can potentially have security considerations like exposing CI variables."
msgstr ""
@@ -26872,9 +27453,6 @@ msgstr ""
msgid "Pipelines|Your changes have been successfully committed. Now redirecting to the new merge request page."
msgstr ""
-msgid "Pipelines|detached"
-msgstr ""
-
msgid "Pipelines|error"
msgstr ""
@@ -26884,10 +27462,13 @@ msgstr ""
msgid "Pipelines|latest"
msgstr ""
-msgid "Pipelines|stuck"
+msgid "Pipelines|merge request"
msgstr ""
-msgid "Pipelines|train"
+msgid "Pipelines|merge train"
+msgstr ""
+
+msgid "Pipelines|stuck"
msgstr ""
msgid "Pipelines|yaml invalid"
@@ -27019,6 +27600,12 @@ msgstr ""
msgid "Pipeline|This change will not change the overall test coverage if merged."
msgstr ""
+msgid "Pipeline|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipeline|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipeline|Trigger author"
msgstr ""
@@ -27043,6 +27630,12 @@ msgstr ""
msgid "Pipeline|for"
msgstr ""
+msgid "Pipeline|merge request"
+msgstr ""
+
+msgid "Pipeline|merge train"
+msgstr ""
+
msgid "Pipeline|on"
msgstr ""
@@ -27181,9 +27774,6 @@ msgstr ""
msgid "Please enter a valid time interval"
msgstr ""
-msgid "Please enter or upload a valid license."
-msgstr ""
-
msgid "Please enter your current password."
msgstr ""
@@ -27292,9 +27882,6 @@ msgstr ""
msgid "Please type %{phrase_code} to proceed or close this modal to cancel."
msgstr ""
-msgid "Please type the following to confirm:"
-msgstr ""
-
msgid "Please use this form to report to the admin users who create spam issues, comments or behave inappropriately."
msgstr ""
@@ -27322,12 +27909,27 @@ msgstr ""
msgid "Policies"
msgstr ""
+msgid "Policy '%{escalation_policy_name}' does not exist."
+msgstr ""
+
msgid "Policy management project does have any policies in %{policy_path}"
msgstr ""
msgid "Policy project doesn't exist"
msgstr ""
+msgid "PolicyRuleMultiSelect|%{firstLabel} +%{numberOfAdditionalLabels} more"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|All %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select all"
+msgstr ""
+
msgid "Polling interval multiplier"
msgstr ""
@@ -27556,6 +28158,9 @@ msgstr ""
msgid "Private projects can be created in your personal namespace with:"
msgstr ""
+msgid "Problem with %{name} command: %{message}."
+msgstr ""
+
msgid "Proceed"
msgstr ""
@@ -28030,6 +28635,9 @@ msgstr ""
msgid "Progress"
msgstr ""
+msgid "Progress tracking"
+msgstr ""
+
msgid "Project"
msgstr ""
@@ -28261,6 +28869,9 @@ msgstr ""
msgid "ProjectQualitySummary|Failure"
msgstr ""
+msgid "ProjectQualitySummary|Get insight into the overall percentage of tests in your project that succeed, fail and are skipped."
+msgstr ""
+
msgid "ProjectQualitySummary|Latest pipeline results"
msgstr ""
@@ -28279,6 +28890,12 @@ msgstr ""
msgid "ProjectQualitySummary|See project Code Coverage Statistics"
msgstr ""
+msgid "ProjectQualitySummary|Set up test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|Set up test runs (opens in a new tab)"
+msgstr ""
+
msgid "ProjectQualitySummary|Skipped"
msgstr ""
@@ -28555,13 +29172,19 @@ msgstr ""
msgid "ProjectSettings|LFS objects from this repository are available to forks. %{linkStart}How do I remove them?%{linkEnd}"
msgstr ""
+msgid "ProjectSettings|Learn about commit history."
+msgstr ""
+
+msgid "ProjectSettings|Leave empty to use default template."
+msgstr ""
+
msgid "ProjectSettings|Manage who can see the project in the public access directory."
msgstr ""
msgid "ProjectSettings|Manages large files such as audio, video, and graphics files."
msgstr ""
-msgid "ProjectSettings|Maximum 500 characters."
+msgid "ProjectSettings|Maximum %{maxLength} characters."
msgstr ""
msgid "ProjectSettings|Merge checks"
@@ -28702,6 +29325,9 @@ msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
msgstr ""
+msgid "ProjectSettings|The default template will be applied on save."
+msgstr ""
+
msgid "ProjectSettings|These checks must pass before merge requests can be merged."
msgstr ""
@@ -28756,6 +29382,9 @@ msgstr ""
msgid "ProjectSettings|What are badges?"
msgstr ""
+msgid "ProjectSettings|What are merge trains?"
+msgstr ""
+
msgid "ProjectSettings|When merge request pipelines are enabled in the CI/CD configuration file, pipelines validate the combined results of the source and target branches. %{link_start}How to configure merge request pipelines?%{link_end}"
msgstr ""
@@ -28873,6 +29502,9 @@ msgstr ""
msgid "Projects are organized into groups"
msgstr ""
+msgid "Projects are where you store your code, access issues, wiki and other features of GitLab."
+msgstr ""
+
msgid "Projects contributed to"
msgstr ""
@@ -28888,12 +29520,6 @@ msgstr ""
msgid "Projects to index"
msgstr ""
-msgid "Projects will be permanently deleted after a %{waiting_period}-day waiting period."
-msgstr ""
-
-msgid "Projects will be permanently deleted immediately."
-msgstr ""
-
msgid "Projects with critical vulnerabilities"
msgstr ""
@@ -28978,6 +29604,9 @@ msgstr ""
msgid "ProjectsNew|Import project"
msgstr ""
+msgid "ProjectsNew|Include a Getting Started README"
+msgstr ""
+
msgid "ProjectsNew|Initialize repository with a README"
msgstr ""
@@ -28993,6 +29622,9 @@ msgstr ""
msgid "ProjectsNew|Project description %{tag_start}(optional)%{tag_end}"
msgstr ""
+msgid "ProjectsNew|Recommended if you're new to GitLab"
+msgstr ""
+
msgid "ProjectsNew|Run CI/CD for external repository"
msgstr ""
@@ -29410,6 +30042,9 @@ msgstr ""
msgid "ProtectedBranch|Unprotect"
msgstr ""
+msgid "ProtectedBranch|Unprotect branch"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
@@ -29437,6 +30072,9 @@ msgstr ""
msgid "ProtectedEnvironment|Protected Environment (%{protected_environments_count})"
msgstr ""
+msgid "ProtectedEnvironment|Required approvals"
+msgstr ""
+
msgid "ProtectedEnvironment|Select an environment"
msgstr ""
@@ -29458,10 +30096,13 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|Unprotect tag"
+msgstr ""
+
msgid "ProtectedTags|default"
msgstr ""
-msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
+msgid "ProtectedTag|By default, protected tags restrict who can modify the tag."
msgstr ""
msgid "ProtectedTag|Learn more."
@@ -29524,6 +30165,9 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Public projects are an easy way to allow everyone to have read-only access."
+msgstr ""
+
msgid "Publish to status page"
msgstr ""
@@ -29680,9 +30324,6 @@ msgstr ""
msgid "QualitySummary|Project quality"
msgstr ""
-msgid "Quarters"
-msgstr ""
-
msgid "Query"
msgstr ""
@@ -29767,6 +30408,9 @@ msgstr ""
msgid "Read more about project permissions %{help_link_open}here%{help_link_close}"
msgstr ""
+msgid "Read more about related epics"
+msgstr ""
+
msgid "Read more about related issues"
msgstr ""
@@ -29797,10 +30441,7 @@ msgstr ""
msgid "Rebase source branch on the target branch."
msgstr ""
-msgid "Rebase without CI"
-msgstr ""
-
-msgid "Rebases and triggers a pipeline"
+msgid "Rebase without pipeline"
msgstr ""
msgid "Recaptcha verified?"
@@ -29851,9 +30492,6 @@ msgstr ""
msgid "Reconfigure"
msgstr ""
-msgid "Recovering projects"
-msgstr ""
-
msgid "Recovery Codes"
msgstr ""
@@ -29915,6 +30553,12 @@ msgstr ""
msgid "Regex pattern"
msgstr ""
+msgid "Region"
+msgstr ""
+
+msgid "Regions"
+msgstr ""
+
msgid "Register"
msgstr ""
@@ -30147,9 +30791,6 @@ msgstr ""
msgid "Remove all or specific reviewer(s)"
msgstr ""
-msgid "Remove approver"
-msgstr ""
-
msgid "Remove approvers"
msgstr ""
@@ -30165,6 +30806,9 @@ msgstr ""
msgid "Remove attention request"
msgstr ""
+msgid "Remove attention request(s)"
+msgstr ""
+
msgid "Remove avatar"
msgstr ""
@@ -30303,6 +30947,9 @@ msgstr ""
msgid "Removed an issue from an epic."
msgstr ""
+msgid "Removed attention from %{users_sentence}."
+msgstr ""
+
msgid "Removed attention request from @%{username}"
msgstr ""
@@ -30354,6 +31001,9 @@ msgstr ""
msgid "Removes an issue from an epic."
msgstr ""
+msgid "Removes attention from %{users_sentence}."
+msgstr ""
+
msgid "Removes parent epic %{epic_ref}."
msgstr ""
@@ -30465,6 +31115,9 @@ msgstr ""
msgid "Report abuse to admin"
msgstr ""
+msgid "Report is generating and will be sent to your email address."
+msgstr ""
+
msgid "Reported %{timeAgo} by %{reportedBy}"
msgstr ""
@@ -30764,6 +31417,15 @@ msgstr ""
msgid "Request attention"
msgstr ""
+msgid "Request attention from %{users_sentence}."
+msgstr ""
+
+msgid "Request attention from assignee or reviewer"
+msgstr ""
+
+msgid "Request attention from assignee(s) or reviewer(s)"
+msgstr ""
+
msgid "Request attention to review"
msgstr ""
@@ -30788,6 +31450,9 @@ msgstr ""
msgid "Requested %{time_ago}"
msgstr ""
+msgid "Requested attention from %{users_sentence}."
+msgstr ""
+
msgid "Requested attention from @%{username}"
msgstr ""
@@ -31006,6 +31671,9 @@ msgstr ""
msgid "Restore project"
msgstr ""
+msgid "Restoring projects"
+msgstr ""
+
msgid "Restoring the group will prevent the group, its subgroups and projects from being removed on this date."
msgstr ""
@@ -31036,6 +31704,9 @@ msgstr ""
msgid "Retry"
msgstr ""
+msgid "Retry failed jobs"
+msgstr ""
+
msgid "Retry job"
msgstr ""
@@ -31085,9 +31756,6 @@ msgstr ""
msgid "Review changes"
msgstr ""
-msgid "Review requested from %{name}"
-msgstr ""
-
msgid "Review requests for you"
msgstr ""
@@ -31254,6 +31922,9 @@ msgstr ""
msgid "Runners|Assigned Group"
msgstr ""
+msgid "Runners|Assigned Projects (%{projectCount})"
+msgstr ""
+
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -31323,6 +31994,9 @@ msgstr ""
msgid "Runners|Instance"
msgstr ""
+msgid "Runners|Jobs"
+msgstr ""
+
msgid "Runners|Last contact"
msgstr ""
@@ -31416,9 +32090,6 @@ msgstr ""
msgid "Runners|Runner %{name} was deleted"
msgstr ""
-msgid "Runners|Runner ID"
-msgstr ""
-
msgid "Runners|Runner assigned to project."
msgstr ""
@@ -31566,6 +32237,9 @@ msgstr ""
msgid "Runners|stale"
msgstr ""
+msgid "Runner|This runner has not run any jobs."
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -31680,6 +32354,24 @@ msgstr ""
msgid "Saving project."
msgstr ""
+msgid "ScanResultPolicy|%{ifLabelStart}if%{ifLabelEnd} %{scanners} scan in an open merge request targeting the %{branches} branch(es) finds %{vulnerabilitiesAllowed} or more %{severities} vulnerabilities that are %{vulnerabilityStates}"
+msgstr ""
+
+msgid "ScanResultPolicy|%{thenLabelStart}Then%{thenLabelEnd} Require approval from %{approvalsRequired} of the following approvers: %{approvers}"
+msgstr ""
+
+msgid "ScanResultPolicy|add an approver"
+msgstr ""
+
+msgid "ScanResultPolicy|scanners"
+msgstr ""
+
+msgid "ScanResultPolicy|severity levels"
+msgstr ""
+
+msgid "ScanResultPolicy|vulnerability states"
+msgstr ""
+
msgid "Scanner"
msgstr ""
@@ -31812,6 +32504,9 @@ msgstr ""
msgid "Search for a user"
msgstr ""
+msgid "Search for an emoji"
+msgstr ""
+
msgid "Search for projects, issues, etc."
msgstr ""
@@ -32021,18 +32716,12 @@ msgstr ""
msgid "Secret Detection"
msgstr ""
-msgid "Secret access key"
-msgstr ""
-
msgid "Secret token"
msgstr ""
msgid "Secure token that identifies an external storage request."
msgstr ""
-msgid "SecureCodeWarrior"
-msgstr ""
-
msgid "Security"
msgstr ""
@@ -32057,9 +32746,6 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "Security training with guide and learning pathways."
-msgstr ""
-
msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
@@ -32162,7 +32848,7 @@ msgstr ""
msgid "SecurityConfiguration|Manage corpus"
msgstr ""
-msgid "SecurityConfiguration|Manage corpus files used as mutation sources in coverage fuzzing."
+msgid "SecurityConfiguration|Manage corpus files used as seed inputs with coverage-guided fuzzing."
msgstr ""
msgid "SecurityConfiguration|Manage profiles for use by DAST scans."
@@ -32228,15 +32914,15 @@ msgstr ""
msgid "SecurityOrchestration|.yaml preview"
msgstr ""
-msgid "SecurityOrchestration|Action"
-msgstr ""
-
msgid "SecurityOrchestration|Actions"
msgstr ""
msgid "SecurityOrchestration|Add rule"
msgstr ""
+msgid "SecurityOrchestration|After dismissing the alert, the information will never be shown again."
+msgstr ""
+
msgid "SecurityOrchestration|All policies"
msgstr ""
@@ -32252,7 +32938,7 @@ msgstr ""
msgid "SecurityOrchestration|Description"
msgstr ""
-msgid "SecurityOrchestration|Disabled"
+msgid "SecurityOrchestration|Don't show the alert anymore"
msgstr ""
msgid "SecurityOrchestration|Edit policy"
@@ -32261,13 +32947,13 @@ msgstr ""
msgid "SecurityOrchestration|Edit policy project"
msgstr ""
-msgid "SecurityOrchestration|Enabled"
+msgid "SecurityOrchestration|Empty policy name"
msgstr ""
-msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Enabled"
msgstr ""
-msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
msgstr ""
msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
@@ -32276,7 +32962,7 @@ msgstr ""
msgid "SecurityOrchestration|Invalid policy type"
msgstr ""
-msgid "SecurityOrchestration|Latest scan"
+msgid "SecurityOrchestration|Latest scan run against %{agent}"
msgstr ""
msgid "SecurityOrchestration|Network"
@@ -32285,15 +32971,27 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No actions defined - policy will not run."
+msgstr ""
+
+msgid "SecurityOrchestration|No description"
+msgstr ""
+
msgid "SecurityOrchestration|No rules defined - policy will not run."
msgstr ""
+msgid "SecurityOrchestration|Not enabled"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
msgid "SecurityOrchestration|Policies"
msgstr ""
+msgid "SecurityOrchestration|Policy Type"
+msgstr ""
+
msgid "SecurityOrchestration|Policy cannot be enabled for non-existing branches (%{branches})"
msgstr ""
@@ -32318,10 +33016,13 @@ msgstr ""
msgid "SecurityOrchestration|Require %{approvals} %{plural} from %{approvers} if any of the following occur:"
msgstr ""
-msgid "SecurityOrchestration|Rule"
+msgid "SecurityOrchestration|Rules"
msgstr ""
-msgid "SecurityOrchestration|Rules"
+msgid "SecurityOrchestration|Runs %{actions} and %{lastAction} scans"
+msgstr ""
+
+msgid "SecurityOrchestration|Runs a %{action} scan"
msgstr ""
msgid "SecurityOrchestration|Scan Execution"
@@ -32381,6 +33082,9 @@ msgstr ""
msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
+msgid "SecurityOrchestration|This view only shows scan results for the agent %{agent}. You can view scan results for all agents in the %{linkStart}Operational Vulnerabilities tab of the vulnerability report%{linkEnd}."
+msgstr ""
+
msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
@@ -32435,9 +33139,6 @@ msgstr ""
msgid "SecurityOrchestration|users with ids"
msgstr ""
-msgid "SecurityOrchestration|view results"
-msgstr ""
-
msgid "SecurityOrchestration|vulnerabilities"
msgstr ""
@@ -33107,22 +33808,19 @@ 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|In order to start using functions as a service, you must first install Knative on your Kubernetes cluster. %{linkStart}More information%{linkEnd}"
-msgstr ""
-
msgid "Serverless|Learn more about Serverless"
msgstr ""
msgid "Serverless|No functions available"
msgstr ""
-msgid "Serverless|Sign up for First Look"
+msgid "Serverless|Serverless was %{linkStart}deprecated%{linkEnd} in GitLab 14.3."
+msgstr ""
+
+msgid "Serverless|Serverless was %{postLinkStart}deprecated%{postLinkEnd}. But if you opt to use it, you must install Knative in your Kubernetes cluster first. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "Serverless|The deploy job has not finished."
@@ -33134,9 +33832,6 @@ 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 ""
@@ -33152,9 +33847,6 @@ msgstr ""
msgid "Service Account Key"
msgstr ""
-msgid "Service Accounts"
-msgstr ""
-
msgid "Service Accounts keys authorize GitLab to deploy your Google Cloud project"
msgstr ""
@@ -33164,10 +33856,10 @@ msgstr ""
msgid "Service Desk allows people to create issues in your GitLab instance without their own user account. It provides a unique email address for end users to create issues in a project. Replies can be sent either through the GitLab interface or by email. End users only see threads through email."
msgstr ""
-msgid "Service Usage Data"
+msgid "Service account generated successfully"
msgstr ""
-msgid "Service account generated successfully"
+msgid "Service accounts"
msgstr ""
msgid "Service ping is disabled in your configuration file, and cannot be enabled through this form."
@@ -33311,6 +34003,9 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
+msgid "Set the per-user rate limit for getting a user by ID via the API."
+msgstr ""
+
msgid "Set the per-user rate limit for notes created by web or API requests."
msgstr ""
@@ -33492,6 +34187,9 @@ msgstr ""
msgid "Shared runners details"
msgstr ""
+msgid "Shared runners enabled cannot be enabled until a valid credit card is on file"
+msgstr ""
+
msgid "Shared runners help link"
msgstr ""
@@ -33549,6 +34247,9 @@ msgstr ""
msgid "Show all issues."
msgstr ""
+msgid "Show all milestones"
+msgstr ""
+
msgid "Show all test cases."
msgstr ""
@@ -33585,6 +34286,9 @@ msgstr ""
msgid "Show file contents"
msgstr ""
+msgid "Show group milestones"
+msgstr ""
+
msgid "Show labels"
msgstr ""
@@ -33600,6 +34304,12 @@ msgstr ""
msgid "Show open epics"
msgstr ""
+msgid "Show project milestones"
+msgstr ""
+
+msgid "Show sub-group milestones"
+msgstr ""
+
msgid "Show the Closed list"
msgstr ""
@@ -33609,13 +34319,6 @@ msgstr ""
msgid "Show whitespace changes"
msgstr ""
-msgid "Showing %d event"
-msgid_plural "Showing %d events"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-msgstr[3] ""
-
msgid "Showing %{conflict} between %{sourceBranch} and %{targetBranch}"
msgstr ""
@@ -33677,12 +34380,6 @@ msgstr ""
msgid "Sidebar|None"
msgstr ""
-msgid "Sidebar|Only numeral characters allowed"
-msgstr ""
-
-msgid "Sidebar|Weight"
-msgstr ""
-
msgid "Sidekiq job compression threshold (bytes)"
msgstr ""
@@ -33845,6 +34542,9 @@ msgstr ""
msgid "Slack logo"
msgstr ""
+msgid "SlackIntegration|Are you sure you want to remove this project from the Slack application?"
+msgstr ""
+
msgid "SlackIntegration|GitLab for Slack"
msgstr ""
@@ -33854,6 +34554,9 @@ msgstr ""
msgid "SlackIntegration|Project alias"
msgstr ""
+msgid "SlackIntegration|Remove project"
+msgstr ""
+
msgid "SlackIntegration|Select a GitLab project to link with your Slack workspace."
msgstr ""
@@ -33998,9 +34701,6 @@ msgstr ""
msgid "Something went wrong trying to load issue contacts."
msgstr ""
-msgid "Something went wrong when creating a work item. Please try again"
-msgstr ""
-
msgid "Something went wrong when reordering designs. Please try again"
msgstr ""
@@ -34094,9 +34794,6 @@ msgstr ""
msgid "Something went wrong while inserting your image. Please try again."
msgstr ""
-msgid "Something went wrong while merging this merge request. Please try again."
-msgstr ""
-
msgid "Something went wrong while obtaining the Let's Encrypt certificate."
msgstr ""
@@ -34418,10 +35115,10 @@ 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."
+msgid "SourcegraphAdmin|Learn more."
msgstr ""
-msgid "SourcegraphAdmin|More information"
+msgid "SourcegraphAdmin|Only public projects have code intelligence enabled and communicate with Sourcegraph."
msgstr ""
msgid "SourcegraphAdmin|Save changes"
@@ -34430,7 +35127,7 @@ msgstr ""
msgid "SourcegraphAdmin|Sourcegraph URL"
msgstr ""
-msgid "SourcegraphAdmin|e.g. https://sourcegraph.example.com"
+msgid "SourcegraphAdmin|https://sourcegraph.example.com"
msgstr ""
msgid "SourcegraphPreferences|This feature is experimental and currently limited to certain projects."
@@ -34565,6 +35262,9 @@ msgstr ""
msgid "Start date"
msgstr ""
+msgid "Start free trial"
+msgstr ""
+
msgid "Start merge train"
msgstr ""
@@ -34595,6 +35295,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started escalation for this incident."
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -34607,6 +35310,9 @@ msgstr ""
msgid "Starts at (UTC)"
msgstr ""
+msgid "Starts escalations for this incident"
+msgstr ""
+
msgid "Starts on"
msgstr ""
@@ -34868,6 +35574,9 @@ msgstr ""
msgid "Strikethrough"
msgstr ""
+msgid "Strikethrough text"
+msgstr ""
+
msgid "Subgroup information"
msgstr ""
@@ -35102,6 +35811,21 @@ msgstr ""
msgid "Subscriptions"
msgstr ""
+msgid "Subscriptions|Chat with sales"
+msgstr ""
+
+msgid "Subscriptions|Close"
+msgstr ""
+
+msgid "Subscriptions|Not ready to buy yet?"
+msgstr ""
+
+msgid "Subscriptions|Start a free trial"
+msgstr ""
+
+msgid "Subscriptions|We understand. Maybe you have some questions for our sales team, or maybe you'd like to try some of the paid features first. What would you like to do?"
+msgstr ""
+
msgid "Subscription|Your subscription for %{strong}%{namespace_name}%{strong_close} has expired and you are now on %{pricing_link_start}the GitLab Free tier%{pricing_link_end}. Don't worry, your data is safe. Get in touch with our support team (%{support_email}). They'll gladly help with your subscription renewal."
msgstr ""
@@ -35312,6 +36036,9 @@ msgstr ""
msgid "SuperSonics|Maximum users"
msgstr ""
+msgid "SuperSonics|Offline cloud"
+msgstr ""
+
msgid "SuperSonics|Paste your activation code"
msgstr ""
@@ -35378,6 +36105,12 @@ msgstr ""
msgid "SuperSonics|You do not have an active subscription"
msgstr ""
+msgid "SuperSonics|You have a future dated license"
+msgstr ""
+
+msgid "SuperSonics|You have added a license that activates on %{date}. Please see the subscription history table below for more details."
+msgstr ""
+
msgid "SuperSonics|You have successfully added a license that activates on %{date}. Please see the subscription history table below for more details."
msgstr ""
@@ -35537,6 +36270,9 @@ msgstr ""
msgid "Tag name is required"
msgstr ""
+msgid "Tag push"
+msgstr ""
+
msgid "Tag push events"
msgstr ""
@@ -35639,6 +36375,9 @@ msgstr ""
msgid "TagsPage|protected"
msgstr ""
+msgid "Take a look at the documentation to discover all of GitLab’s capabilities."
+msgstr ""
+
msgid "Target Branch"
msgstr ""
@@ -36053,6 +36792,9 @@ msgstr ""
msgid "Tests"
msgstr ""
+msgid "Text (optional)"
+msgstr ""
+
msgid "Text added to the body of all email messages. %{character_limit} character limit"
msgstr ""
@@ -36105,6 +36847,9 @@ msgstr ""
msgid "The CSV export will be created in the background. Once finished, it will be sent to %{email} in an attachment."
msgstr ""
+msgid "The CSV export you requested of all user memberships is attached to this email."
+msgstr ""
+
msgid "The GitLab subscription service (customers.gitlab.com) is currently experiencing an outage. You can monitor the status and get updates at %{linkStart}status.gitlab.com%{linkEnd}."
msgstr ""
@@ -36180,6 +36925,9 @@ 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 epic"
+msgstr ""
+
msgid "The current issue"
msgstr ""
@@ -36343,6 +37091,9 @@ msgstr ""
msgid "The latest pipeline for this merge request has failed."
msgstr ""
+msgid "The license key is invalid."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -36358,6 +37109,9 @@ msgstr ""
msgid "The license was successfully uploaded and will be active from %{starts_at}. You can see the details below."
msgstr ""
+msgid "The license you uploaded is invalid. If the issue persists, contact support at %{link}."
+msgstr ""
+
msgid "The list creation wizard is already open"
msgstr ""
@@ -36979,10 +37733,13 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} and everything this project contains. %{strongOpen}There is no going back%{strongClose}"
+msgstr ""
+
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains."
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}on %{date}%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains. %{strongOpen}There is no going back.%{strongClose}"
msgstr ""
msgid "This action will %{strongOpen}permanently remove%{strongClose} %{codeOpen}%{group}%{codeClose} %{strongOpen}immediately%{strongClose}."
@@ -37111,9 +37868,6 @@ msgstr ""
msgid "This file was modified for readability, and can't accept suggestions. Edit it directly."
msgstr ""
-msgid "This forked project has the following:"
-msgstr ""
-
msgid "This form is disabled in preview"
msgstr ""
@@ -37126,7 +37880,7 @@ msgstr ""
msgid "This group can't be removed because it is linked to a subscription. To remove this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
-msgid "This group can't be transfered because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
+msgid "This group can't be transferred because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
msgid "This group cannot be invited to a project inside a group with enforced SSO"
@@ -37153,6 +37907,9 @@ 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 incident is already escalated with '%{escalation_policy_name}'."
+msgstr ""
+
msgid "This invitation was sent to %{mail_to_invite_email}, but you are signed in as %{link_to_current_user} with email %{mail_to_current_user}."
msgstr ""
@@ -37171,9 +37928,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 merge train pipeline"
-msgstr ""
-
msgid "This is a private email address %{helpIcon} generated just for you. Anyone who has it can create issues or merge requests as if they were you. If that happens, %{resetLinkStart}reset this token%{resetLinkEnd}."
msgstr ""
@@ -37195,6 +37949,12 @@ msgstr ""
msgid "This is your current session"
msgstr ""
+msgid "This issue cannot be assigned to a confidential epic because it is public."
+msgstr ""
+
+msgid "This issue cannot be made public because it belongs to a confidential epic."
+msgstr ""
+
msgid "This issue is confidential and should only be visible to team members with at least Reporter access."
msgstr ""
@@ -37312,6 +38072,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 branch is protected from force push."
+msgstr ""
+
msgid "This merge request cannot be rebased while there are conflicts."
msgstr ""
@@ -37363,9 +38126,15 @@ msgstr ""
msgid "This pipeline was triggered by a schedule."
msgstr ""
+msgid "This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project"
msgstr ""
+msgid "This project can be restored until %{date}."
+msgstr ""
+
msgid "This project cannot be %{visibilityLevel} because the visibility of %{openShowLink}%{name}%{closeShowLink} is %{visibility}. To make this project %{visibilityLevel}, you must first %{openEditLink}change the visibility%{closeEditLink} of the parent group."
msgstr ""
@@ -37384,6 +38153,9 @@ msgstr ""
msgid "This project is %{strongStart}NOT%{strongEnd} a fork, and has the following:"
msgstr ""
+msgid "This project is %{strongStart}NOT%{strongEnd} a fork. This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -38079,6 +38851,9 @@ msgstr ""
msgid "Today"
msgstr ""
+msgid "Todos count"
+msgstr ""
+
msgid "Todos|Are you looking for things to do? Take a look at %{strongStart}%{openIssuesLinkStart}open issues%{openIssuesLinkEnd}%{strongEnd}, contribute to %{strongStart}%{mergeRequestLinkStart}a merge request%{mergeRequestLinkEnd}%{mergeRequestLinkEnd}%{strongEnd}, or mention someone in a comment to automatically assign them a new to-do item."
msgstr ""
@@ -38352,12 +39127,8 @@ msgstr ""
msgid "Trending"
msgstr ""
-msgid "Trials|%{planName} Trial %{enDash} %{num} day left"
-msgid_plural "Trials|%{planName} Trial %{enDash} %{num} days left"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-msgstr[3] ""
+msgid "Trials|%{planName} Trial"
+msgstr ""
msgid "Trials|Compare all plans"
msgstr ""
@@ -38365,6 +39136,9 @@ msgstr ""
msgid "Trials|Create a new group to start your GitLab Ultimate trial."
msgstr ""
+msgid "Trials|Day %{daysUsed}/%{duration}"
+msgstr ""
+
msgid "Trials|Go back to GitLab"
msgstr ""
@@ -38614,7 +39388,7 @@ msgstr ""
msgid "URL is triggered when repository is updated"
msgstr ""
-msgid "URL must be percent-encoded if neccessary."
+msgid "URL must be percent-encoded if necessary."
msgstr ""
msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
@@ -38833,6 +39607,9 @@ msgstr ""
msgid "Unlock account"
msgstr ""
+msgid "Unlock more features with GitLab Ultimate"
+msgstr ""
+
msgid "Unlock the discussion"
msgstr ""
@@ -38896,6 +39673,9 @@ msgstr ""
msgid "Unsubscribes from this %{quick_action_target}."
msgstr ""
+msgid "Unsupported sort value."
+msgstr ""
+
msgid "Unsupported todo type passed. Supported todo types are: %{todo_types}"
msgstr ""
@@ -39124,6 +39904,9 @@ msgstr ""
msgid "UsageQuota|File attachments and smaller design graphics."
msgstr ""
+msgid "UsageQuota|From %{storage_enforcement_date} storage limits will apply to this namespace. View and manage your usage in %{strong_start}Group Settings &gt; Usage quotas%{strong_end}."
+msgstr ""
+
msgid "UsageQuota|Git repository."
msgstr ""
@@ -39184,6 +39967,9 @@ msgstr ""
msgid "UsageQuota|Storage type"
msgstr ""
+msgid "UsageQuota|Storage used"
+msgstr ""
+
msgid "UsageQuota|This is the total amount of storage used across your projects within this namespace."
msgstr ""
@@ -39379,6 +40165,12 @@ msgstr ""
msgid "Use hashed storage paths for newly created and renamed repositories. Always enabled since 13.0."
msgstr ""
+msgid "Use issue count"
+msgstr ""
+
+msgid "Use issue weight"
+msgstr ""
+
msgid "Use one line per URI"
msgstr ""
@@ -39760,6 +40552,9 @@ msgstr ""
msgid "Users"
msgstr ""
+msgid "Users API rate limit"
+msgstr ""
+
msgid "Users can launch a development environment from a GitLab browser tab when the %{linkStart}Gitpod%{linkEnd} integration is enabled."
msgstr ""
@@ -40089,6 +40884,9 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View group pipeline usage quota"
+msgstr ""
+
msgid "View incident details at"
msgstr ""
@@ -40243,6 +41041,9 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
+msgid "Vulnerability"
+msgstr ""
+
msgid "Vulnerability Report"
msgstr ""
@@ -40294,6 +41095,9 @@ msgstr ""
msgid "VulnerabilityManagement|An unverified non-confirmed finding"
msgstr ""
+msgid "VulnerabilityManagement|At least one identifier is required"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -40303,12 +41107,24 @@ msgstr ""
msgid "VulnerabilityManagement|Create Jira issue"
msgstr ""
+msgid "VulnerabilityManagement|Enter a name"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE code"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE identifier URL"
+msgstr ""
+
msgid "VulnerabilityManagement|Fetching linked Jira issues"
msgstr ""
msgid "VulnerabilityManagement|Manually add a vulnerability entry into the vulnerability report."
msgstr ""
+msgid "VulnerabilityManagement|Name is a required field"
+msgstr ""
+
msgid "VulnerabilityManagement|Needs triage"
msgstr ""
@@ -40324,6 +41140,18 @@ msgstr ""
msgid "VulnerabilityManagement|Select a method"
msgstr ""
+msgid "VulnerabilityManagement|Select a severity level"
+msgstr ""
+
+msgid "VulnerabilityManagement|Select a status"
+msgstr ""
+
+msgid "VulnerabilityManagement|Severity is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Something went wrong while creating vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -40348,6 +41176,12 @@ msgstr ""
msgid "VulnerabilityManagement|Something went wrong, could not update vulnerability state."
msgstr ""
+msgid "VulnerabilityManagement|Status is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Submit vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Summary, detailed description, steps to reproduce, etc."
msgstr ""
@@ -40543,6 +41377,9 @@ msgstr ""
msgid "WARNING:"
msgstr ""
+msgid "WARNING: This snippet contains hidden files which might be used to mask malicious behavior. Exercise caution if cloning and executing code from this snippet."
+msgstr ""
+
msgid "Wait for the file to load to copy its contents"
msgstr ""
@@ -40762,6 +41599,15 @@ msgstr ""
msgid "Webhooks|An issue is created, updated, closed, or reopened."
msgstr ""
+msgid "Webhooks|Are you sure you want to delete this group hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this project hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this webhook?"
+msgstr ""
+
msgid "Webhooks|Comments"
msgstr ""
@@ -40771,6 +41617,9 @@ msgstr ""
msgid "Webhooks|Confidential issues events"
msgstr ""
+msgid "Webhooks|Delete webhook"
+msgstr ""
+
msgid "Webhooks|Deployment events"
msgstr ""
@@ -41006,6 +41855,9 @@ msgstr ""
msgid "Wiki"
msgstr ""
+msgid "Wiki page"
+msgstr ""
+
msgid "Wiki page was successfully created."
msgstr ""
@@ -41111,7 +41963,7 @@ msgstr ""
msgid "WikiPageConflictMessage|Someone edited the page the same time you did. Please check out %{wikiLinkStart}the page%{wikiLinkEnd} and make sure your changes will not unintentionally remove theirs."
msgstr ""
-msgid "WikiPage|An error occured while trying to render the content editor. Please try again later."
+msgid "WikiPage|An error occurred while trying to render the content editor. Please try again later."
msgstr ""
msgid "WikiPage|Are you sure you want to switch back to the classic editor?"
@@ -41270,6 +42122,18 @@ msgstr ""
msgid "WorkItem|New Task"
msgstr ""
+msgid "WorkItem|Something went wrong when creating a work item. Please try again"
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching the work item. Please try again."
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching work item types. Please try again"
+msgstr ""
+
+msgid "WorkItem|Type"
+msgstr ""
+
msgid "WorkItem|Work Items"
msgstr ""
@@ -41336,7 +42200,10 @@ msgstr ""
msgid "You are about to add %{usersTag} people to the discussion. They will all receive a notification."
msgstr ""
-msgid "You are about to permanently delete this project"
+msgid "You are about to delete this forked project containing:"
+msgstr ""
+
+msgid "You are about to delete this project containing:"
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."
@@ -41357,6 +42224,9 @@ msgstr ""
msgid "You are attempting to update a file that has changed since you started editing it."
msgstr ""
+msgid "You are billed if you exceed this number. %{qsrOverageLinkStart}How does billing work?%{qsrOverageLinkEnd}"
+msgstr ""
+
msgid "You are connected to the Prometheus server, but there is currently no data to display."
msgstr ""
@@ -41414,6 +42284,9 @@ msgstr ""
msgid "You are not authorized to update this scanner profile"
msgstr ""
+msgid "You are not authorized to upload metric images"
+msgstr ""
+
msgid "You are now impersonating %{username}"
msgstr ""
@@ -41567,9 +42440,6 @@ msgstr ""
msgid "You can only upload one design when dropping onto an existing design."
msgstr ""
-msgid "You can recover this project until %{date}"
-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 ""
@@ -41618,9 +42488,6 @@ msgstr ""
msgid "You cannot write to this read-only GitLab instance."
msgstr ""
-msgid "You can’t %{tag_start}edit%{tag_end} files directly in this project. Fork this project and submit a merge request with your changes."
-msgstr ""
-
msgid "You can’t edit files directly in this project. Fork this project and submit a merge request with your changes."
msgstr ""
@@ -41775,9 +42642,6 @@ 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 set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
@@ -41808,12 +42672,6 @@ msgstr ""
msgid "You must have maintainer access to force delete a lock"
msgstr ""
-msgid "You must have permission to create a project in a group before forking."
-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 ""
@@ -42219,7 +43077,7 @@ msgstr ""
msgid "Your public email will be displayed on your public profile."
msgstr ""
-msgid "Your request for access could not be processed: %{error_meesage}"
+msgid "Your request for access could not be processed: %{error_message}"
msgstr ""
msgid "Your request for access has been queued for review."
@@ -42408,6 +43266,9 @@ msgstr ""
msgid "archived:"
msgstr ""
+msgid "artifacts"
+msgstr ""
+
msgid "assign yourself"
msgstr ""
@@ -42439,6 +43300,9 @@ msgstr[3] ""
msgid "branch name"
msgstr ""
+msgid "builds"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -42868,6 +43732,9 @@ msgstr ""
msgid "contact with same email already exists in group hierarchy"
msgstr ""
+msgid "container registry images"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -42907,6 +43774,9 @@ msgstr ""
msgid "data"
msgstr ""
+msgid "database"
+msgstr ""
+
msgid "date must not be after 9999-12-31"
msgstr ""
@@ -42932,9 +43802,6 @@ msgstr ""
msgid "design"
msgstr ""
-msgid "detached"
-msgstr ""
-
msgid "disabled"
msgstr ""
@@ -43191,7 +44058,7 @@ msgstr ""
msgid "is not a valid X509 certificate."
msgstr ""
-msgid "is not allowed for sign-up."
+msgid "is not allowed for sign-up. Please use your regular email address."
msgstr ""
msgid "is not allowed for this group."
@@ -43203,7 +44070,7 @@ msgstr ""
msgid "is not allowed since the group is not top-level group."
msgstr ""
-msgid "is not allowed."
+msgid "is not allowed. Please use your regular email address."
msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
@@ -43290,6 +44157,9 @@ msgstr ""
msgid "level: %{level}"
msgstr ""
+msgid "lfs objects"
+msgstr ""
+
msgid "limit of %{project_limit} reached"
msgstr ""
@@ -43515,6 +44385,9 @@ msgstr ""
msgid "mrWidget|Merge blocked: pipeline must succeed. It's waiting for a manual action to continue."
msgstr ""
+msgid "mrWidget|Merge blocked: pipeline must succeed. Push a commit that fixes the failure, or %{linkStart}learn about other solutions.%{linkEnd}"
+msgstr ""
+
msgid "mrWidget|Merge blocked: this merge request must be approved."
msgstr ""
@@ -43632,9 +44505,6 @@ msgstr ""
msgid "mrWidget|The changes were not merged into"
msgstr ""
-msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -43782,9 +44652,6 @@ msgstr ""
msgid "open issue"
msgstr ""
-msgid "opened %{timeAgo}"
-msgstr ""
-
msgid "or"
msgstr ""
@@ -43798,6 +44665,12 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "packages"
+msgstr ""
+
+msgid "pages"
+msgstr ""
+
msgid "parent"
msgid_plural "parents"
msgstr[0] ""
@@ -43955,6 +44828,9 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "repositories"
+msgstr ""
+
msgid "repository:"
msgstr ""
@@ -44075,12 +44951,18 @@ msgstr ""
msgid "tag name"
msgstr ""
+msgid "terraform states"
+msgstr ""
+
msgid "the correct format."
msgstr ""
msgid "the file"
msgstr ""
+msgid "the following epic(s)"
+msgstr ""
+
msgid "the following issue(s)"
msgstr ""
@@ -44093,21 +44975,12 @@ msgstr ""
msgid "this document"
msgstr ""
-msgid "this issue cannot be assigned to a confidential epic since it is public"
-msgstr ""
-
-msgid "this issue cannot be made public since it belongs to a confidential epic"
-msgstr ""
-
msgid "time summary"
msgstr ""
msgid "toggle collapse"
msgstr ""
-msgid "train"
-msgstr ""
-
msgid "triggered"
msgstr ""
@@ -44238,3 +45111,6 @@ msgstr ""
msgid "{project}"
msgstr ""
+msgid "✔"
+msgstr ""
+
diff --git a/locale/mk_MK/gitlab.po b/locale/mk_MK/gitlab.po
index 1c43fe1fd20..f9f56c2f423 100644
--- a/locale/mk_MK/gitlab.po
+++ b/locale/mk_MK/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: mk\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2022-02-02 15:46\n"
+"PO-Revision-Date: 2022-03-01 20:39\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -146,6 +146,11 @@ msgid_plural "%d approvers (you've approved)"
msgstr[0] ""
msgstr[1] ""
+msgid "%d assigned issue"
+msgid_plural "%d assigned issues"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -421,8 +426,23 @@ msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
msgstr[1] ""
-msgid "%d vulnerability updated"
-msgid_plural "%d vulnerabilities updated"
+msgid "%d vulnerability set to confirmed"
+msgid_plural "%d vulnerabilities set to confirmed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to dismissed"
+msgid_plural "%d vulnerabilities set to dismissed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to needs triage"
+msgid_plural "%d vulnerabilities set to needs triage"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to resolved"
+msgid_plural "%d vulnerabilities set to resolved"
msgstr[0] ""
msgstr[1] ""
@@ -510,6 +530,12 @@ msgstr[1] ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{completed} of %{total} issues closed"
+msgstr ""
+
+msgid "%{completed} of %{total} weight completed"
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -858,6 +884,9 @@ msgstr ""
msgid "%{openedIssues} open, %{closedIssues} closed"
msgstr ""
+msgid "%{percentage}%% issues closed"
+msgstr ""
+
msgid "%{percentage}%% weight completed"
msgstr ""
@@ -1287,6 +1316,9 @@ msgid_plural "- Users"
msgstr[0] ""
msgstr[1] ""
+msgid "- of - issues closed"
+msgstr ""
+
msgid "- of - weight completed"
msgstr ""
@@ -1429,7 +1461,7 @@ msgstr ""
msgid "1000+"
msgstr ""
-msgid "192.168.0.0/24"
+msgid "192.168.0.0/24 or 2001:0DB8:1234::/48"
msgstr ""
msgid "1st contribution!"
@@ -1741,13 +1773,13 @@ msgstr ""
msgid "AWS Access Key"
msgstr ""
-msgid "AWS Access Key. Only required if not using role instance credentials"
+msgid "AWS Secret Access Key"
msgstr ""
-msgid "AWS Secret Access Key"
+msgid "AWS access key ID (Optional)"
msgstr ""
-msgid "AWS Secret Access Key. Only required if not using role instance credentials"
+msgid "AWS secret access key (Optional)"
msgstr ""
msgid "AWS service error: %{error}"
@@ -1807,9 +1839,6 @@ msgstr ""
msgid "Access granted"
msgstr ""
-msgid "Access key ID"
-msgstr ""
-
msgid "Access requests"
msgstr ""
@@ -1984,7 +2013,7 @@ msgstr ""
msgid "Activity"
msgstr ""
-msgid "Activity|An error occured while retrieving activity. Reload the page to try again."
+msgid "Activity|An error occurred while retrieving activity. Reload the page to try again."
msgstr ""
msgid "Add"
@@ -2023,6 +2052,9 @@ msgstr ""
msgid "Add a %{type}"
msgstr ""
+msgid "Add a GCP region"
+msgstr ""
+
msgid "Add a GPG key"
msgstr ""
@@ -2074,6 +2106,9 @@ msgstr ""
msgid "Add a numbered list"
msgstr ""
+msgid "Add a related epic"
+msgstr ""
+
msgid "Add a related issue"
msgstr ""
@@ -2188,6 +2223,9 @@ msgstr ""
msgid "Add or subtract spent time"
msgstr ""
+msgid "Add people"
+msgstr ""
+
msgid "Add previously merged commits"
msgstr ""
@@ -2254,6 +2292,9 @@ msgstr ""
msgid "Add webhook"
msgstr ""
+msgid "Add your team members and others to GitLab."
+msgstr ""
+
msgid "Add/remove"
msgstr ""
@@ -3076,12 +3117,6 @@ msgstr ""
msgid "AdvancedSearch|Reindex required"
msgstr ""
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. Permanently deleting this project will %{strongStart}immediately delete%{strongEnd} its repositories and %{strongStart}all related resources%{strongEnd}, including issues, merge requests etc."
-msgstr ""
-
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. You will lose this project's repository and %{strongStart}all related resources%{strongEnd}, including issues and merge requests."
-msgstr ""
-
msgid "After a successful password update you will be redirected to login screen."
msgstr ""
@@ -3112,6 +3147,9 @@ msgstr ""
msgid "Akismet helps prevent the creation of spam issues in public projects."
msgstr ""
+msgid "Alert"
+msgstr ""
+
msgid "AlertManagement|Acknowledged"
msgstr ""
@@ -3484,9 +3522,6 @@ msgstr ""
msgid "All environments"
msgstr ""
-msgid "All epics"
-msgstr ""
-
msgid "All groups and projects"
msgstr ""
@@ -4223,12 +4258,15 @@ msgstr ""
msgid "ApplicationSettings|Approve users in the pending approval status?"
msgstr ""
-msgid "ApplicationSettings|By making this change, you will automatically approve %d user with the pending approval status."
-msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users with the pending approval status."
+msgid "ApplicationSettings|Approve users who are pending approval?"
+msgstr ""
+
+msgid "ApplicationSettings|By making this change, you will automatically approve %d user who is pending approval."
+msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users who are pending approval."
msgstr[0] ""
msgstr[1] ""
-msgid "ApplicationSettings|By making this change, you will automatically approve all users in pending approval status."
+msgid "ApplicationSettings|By making this change, you will automatically approve all users who are pending approval."
msgstr ""
msgid "ApplicationSettings|Denied domains for sign-ups"
@@ -4634,10 +4672,10 @@ msgstr ""
msgid "Archiving the project will make it entirely read-only. It is hidden from the dashboard and doesn't show up in searches. %{strong_start}The repository cannot be committed to, and no issues, comments, or other entities can be created.%{strong_end} %{link_start}Learn more.%{link_end}"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to delete this project?"
+msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
+msgid "Are you absolutely sure?"
msgstr ""
msgid "Are you sure that you want to archive this project?"
@@ -4673,12 +4711,18 @@ msgstr ""
msgid "Are you sure you want to delete this SSH key?"
msgstr ""
+msgid "Are you sure you want to delete this comment?"
+msgstr ""
+
msgid "Are you sure you want to delete this deploy key?"
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 label?"
+msgstr ""
+
msgid "Are you sure you want to delete this pipeline schedule?"
msgstr ""
@@ -4694,9 +4738,6 @@ msgstr ""
msgid "Are you sure you want to discard your changes?"
msgstr ""
-msgid "Are you sure you want to erase this build?"
-msgstr ""
-
msgid "Are you sure you want to import %d repository?"
msgid_plural "Are you sure you want to import %d repositories?"
msgstr[0] ""
@@ -4744,6 +4785,9 @@ msgstr ""
msgid "Are you sure you want to remove this list?"
msgstr ""
+msgid "Are you sure you want to remove this nickname?"
+msgstr ""
+
msgid "Are you sure you want to reset the health check token?"
msgstr ""
@@ -4756,10 +4800,10 @@ 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?"
+msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
msgstr ""
-msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
+msgid "Are you sure you want to revoke this project access token? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to stop this environment?"
@@ -4906,9 +4950,6 @@ msgstr ""
msgid "Assigned to %{assignee_name}"
msgstr ""
-msgid "Assigned to %{name}"
-msgstr ""
-
msgid "Assigned to me"
msgstr ""
@@ -4973,6 +5014,9 @@ msgstr[1] ""
msgid "Attaching the file failed."
msgstr ""
+msgid "Attention"
+msgstr ""
+
msgid "Audit Events"
msgstr ""
@@ -5135,6 +5179,12 @@ msgstr ""
msgid "Authorized applications (%{size})"
msgstr ""
+msgid "AuthorizedApplication|Are you sure you want to revoke this application?"
+msgstr ""
+
+msgid "AuthorizedApplication|Revoke application"
+msgstr ""
+
msgid "Authors: %{authors}"
msgstr ""
@@ -6328,6 +6378,9 @@ msgstr ""
msgid "CICDAnalytics|Shared Runners Usage"
msgstr ""
+msgid "CICDAnalytics|Shared runner pipeline minute duration by month"
+msgstr ""
+
msgid "CICDAnalytics|Shared runner usage"
msgstr ""
@@ -6469,6 +6522,9 @@ msgstr ""
msgid "Can create groups:"
msgstr ""
+msgid "Can not delete primary training"
+msgstr ""
+
msgid "Can't apply as the source branch was deleted."
msgstr ""
@@ -6802,9 +6858,6 @@ msgstr ""
msgid "Changing any setting here requires an application restart"
msgstr ""
-msgid "Changing group URL can have unintended side effects."
-msgstr ""
-
msgid "Charts can't be displayed as the request for data has timed out. %{documentationLink}"
msgstr ""
@@ -6892,9 +6945,6 @@ msgstr ""
msgid "Checking branch availability..."
msgstr ""
-msgid "Checking group URL availability..."
-msgstr ""
-
msgid "Checking group path availability..."
msgstr ""
@@ -7388,6 +7438,9 @@ msgstr ""
msgid "Clear recent searches"
msgstr ""
+msgid "Clear repository checks"
+msgstr ""
+
msgid "Clear search"
msgstr ""
@@ -7520,9 +7573,6 @@ msgstr ""
msgid "Closed MRs"
msgstr ""
-msgid "Closed epics"
-msgstr ""
-
msgid "Closed issues"
msgstr ""
@@ -7559,13 +7609,13 @@ msgstr ""
msgid "Cluster level"
msgstr ""
-msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
+msgid "Cluster type must be specified for Stages::ClusterEndpointInserter"
msgstr ""
msgid "ClusterAgents|%{name} successfully deleted"
msgstr ""
-msgid "ClusterAgents|%{number} of %{total} Agents"
+msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
@@ -7607,6 +7657,15 @@ msgstr ""
msgid "ClusterAgents|Agent never connected to GitLab"
msgstr ""
+msgid "ClusterAgents|Agent version mismatch"
+msgstr ""
+
+msgid "ClusterAgents|Agent version mismatch and update"
+msgstr ""
+
+msgid "ClusterAgents|Agent version update required"
+msgstr ""
+
msgid "ClusterAgents|All"
msgstr ""
@@ -7631,7 +7690,7 @@ msgstr ""
msgid "ClusterAgents|Configuration"
msgstr ""
-msgid "ClusterAgents|Connect a cluster through the Agent"
+msgid "ClusterAgents|Connect a cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connect existing cluster"
@@ -7640,13 +7699,13 @@ msgstr ""
msgid "ClusterAgents|Connect with a certificate"
msgstr ""
-msgid "ClusterAgents|Connect with agent"
+msgid "ClusterAgents|Connect with an agent"
msgstr ""
msgid "ClusterAgents|Connect with the GitLab Agent"
msgstr ""
-msgid "ClusterAgents|Connect your cluster through the Agent"
+msgid "ClusterAgents|Connect your cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connected"
@@ -7706,7 +7765,10 @@ msgstr ""
msgid "ClusterAgents|How to register an agent?"
msgstr ""
-msgid "ClusterAgents|Install new Agent"
+msgid "ClusterAgents|How to update an agent?"
+msgstr ""
+
+msgid "ClusterAgents|Install a new agent"
msgstr ""
msgid "ClusterAgents|Last connected %{timeAgo}."
@@ -7733,7 +7795,7 @@ msgstr ""
msgid "ClusterAgents|Never connected"
msgstr ""
-msgid "ClusterAgents|No Agents"
+msgid "ClusterAgents|No agents"
msgstr ""
msgid "ClusterAgents|No clusters connected through cluster certificates"
@@ -7793,6 +7855,9 @@ msgstr ""
msgid "ClusterAgents|The agent has not been connected in a long time. There might be a connectivity issue. Last contact was %{timeAgo}."
msgstr ""
+msgid "ClusterAgents|The agent version do not match each other across your cluster's pods. This can happen when a new agent version was just deployed and Kubernetes is shutting down the old pods."
+msgstr ""
+
msgid "ClusterAgents|The recommended installation method includes the token. If you want to follow the advanced installation method provided in the docs, make sure you save the token value before you close this window."
msgstr ""
@@ -7840,6 +7905,9 @@ msgstr ""
msgid "ClusterAgents|You will need to create a token to connect to your agent"
msgstr ""
+msgid "ClusterAgents|Your agent version is out of sync with your GitLab version (v%{version}), which might cause compatibility problems. Update the agent installed on your cluster to the most recent version."
+msgstr ""
+
msgid "ClusterAgents|Your instance doesn't have the %{linkStart}GitLab Agent Server (KAS)%{linkEnd} set up. Ask a GitLab Administrator to install it."
msgstr ""
@@ -8716,9 +8784,6 @@ msgstr ""
msgid "Comma-separated list of email addresses."
msgstr ""
-msgid "Comma-separated list of users allowed to exceed the rate limit."
-msgstr ""
-
msgid "Comma-separated, e.g. '1.1.1.1, 2.2.2.0/24'"
msgstr ""
@@ -9045,6 +9110,12 @@ msgstr ""
msgid "Confidential"
msgstr ""
+msgid "Confidential issue"
+msgstr ""
+
+msgid "Confidential note"
+msgstr ""
+
msgid "Confidentiality"
msgstr ""
@@ -9078,6 +9149,9 @@ msgstr ""
msgid "Configure Dependency Scanning in `.gitlab-ci.yml`, creating this file if it does not already exist"
msgstr ""
+msgid "Configure GitLab"
+msgstr ""
+
msgid "Configure GitLab runners to start using the Web Terminal. %{helpStart}Learn more.%{helpEnd}"
msgstr ""
@@ -9126,6 +9200,15 @@ msgstr ""
msgid "Configure pipelines to deploy web apps, backend services, APIs and static resources to Google Cloud"
msgstr ""
+msgid "Configure region"
+msgstr ""
+
+msgid "Configure region for environment"
+msgstr ""
+
+msgid "Configure regions"
+msgstr ""
+
msgid "Configure repository mirroring."
msgstr ""
@@ -9159,6 +9242,9 @@ msgstr ""
msgid "Configure which lists are shown for anyone who visits this board"
msgstr ""
+msgid "Configure your environments to be deployed to specific geographical regions"
+msgstr ""
+
msgid "Confirm"
msgstr ""
@@ -9861,10 +9947,10 @@ msgstr ""
msgid "CorpusManagement|Actions"
msgstr ""
-msgid "CorpusManagement|Corpus are used in fuzz testing as mutation source to Improve future testing."
+msgid "CorpusManagement|Corpus file"
msgstr ""
-msgid "CorpusManagement|Corpus file"
+msgid "CorpusManagement|Corpus files are used in coverage-guided fuzz testing as seed inputs to improve testing."
msgstr ""
msgid "CorpusManagement|Corpus files must be in *.zip format. Maximum 5 GB"
@@ -9918,6 +10004,9 @@ msgstr ""
msgid "Could not apply %{name} command."
msgstr ""
+msgid "Could not apply %{name} command. %{message}."
+msgstr ""
+
msgid "Could not authorize chat nickname. Try again!"
msgstr ""
@@ -10068,6 +10157,9 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
+msgid "Create a group"
+msgstr ""
+
msgid "Create a merge request"
msgstr ""
@@ -10092,6 +10184,9 @@ msgstr ""
msgid "Create a personal access token on your account to pull or push via %{protocol}."
msgstr ""
+msgid "Create a project"
+msgstr ""
+
msgid "Create an account using:"
msgstr ""
@@ -10455,6 +10550,9 @@ msgstr ""
msgid "Creation date"
msgstr ""
+msgid "Creator"
+msgstr ""
+
msgid "Credentials"
msgstr ""
@@ -10467,9 +10565,15 @@ msgstr ""
msgid "CredentialsInventory|Personal Access Tokens"
msgstr ""
+msgid "CredentialsInventory|Project Access Tokens"
+msgstr ""
+
msgid "CredentialsInventory|SSH Keys"
msgstr ""
+msgid "Credit card required to be on file in order to create a pipeline"
+msgstr ""
+
msgid "Credit card:"
msgstr ""
@@ -10653,9 +10757,6 @@ msgstr ""
msgid "Customer relations"
msgstr ""
-msgid "Customizable by an administrator."
-msgstr ""
-
msgid "Customizable by owners."
msgstr ""
@@ -10785,30 +10886,18 @@ msgstr ""
msgid "CycleAnalytics|%{selectedLabelsCount} selected (%{maxLabels} max)"
msgstr ""
-msgid "CycleAnalytics|%{stageCount} stages selected"
-msgstr ""
-
-msgid "CycleAnalytics|All stages"
-msgstr ""
-
-msgid "CycleAnalytics|Average days to completion"
+msgid "CycleAnalytics|Average time to completion"
msgstr ""
msgid "CycleAnalytics|Date"
msgstr ""
-msgid "CycleAnalytics|Days to completion"
-msgstr ""
-
msgid "CycleAnalytics|Display chart filters"
msgstr ""
msgid "CycleAnalytics|Lead Time for Changes"
msgstr ""
-msgid "CycleAnalytics|No stages selected"
-msgstr ""
-
msgid "CycleAnalytics|Number of tasks"
msgstr ""
@@ -10837,18 +10926,30 @@ msgstr ""
msgid "CycleAnalytics|Showing data for group '%{groupName}' from %{createdAfter} to %{createdBefore}"
msgstr ""
-msgid "CycleAnalytics|Stages"
+msgid "CycleAnalytics|Stage time: %{title}"
msgstr ""
msgid "CycleAnalytics|Tasks by type"
msgstr ""
-msgid "CycleAnalytics|The average time spent in the selected stage for the items that were completed on each date. Data limited to the last 500 items."
+msgid "CycleAnalytics|The average time items spent in this stage. Data limited to items completed within this date range."
msgstr ""
msgid "CycleAnalytics|The given date range is larger than 180 days"
msgstr ""
+msgid "CycleAnalytics|The total time items spent across each value stream stage. Data limited to items completed within this date range."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Stage time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Total time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|Total time"
+msgstr ""
+
msgid "CycleAnalytics|Type of work"
msgstr ""
@@ -10861,9 +10962,6 @@ msgstr ""
msgid "CycleAnalytics|project dropdown filter"
msgstr ""
-msgid "CycleAnalytics|stage dropdown"
-msgstr ""
-
msgid "DAG visualization requires at least 3 dependent jobs."
msgstr ""
@@ -10963,10 +11061,16 @@ msgstr ""
msgid "DastProfiles|AJAX spider"
msgstr ""
+msgid "DastProfiles|API"
+msgstr ""
+
+msgid "DastProfiles|API endpoint URL"
+msgstr ""
+
msgid "DastProfiles|Active"
msgstr ""
-msgid "DastProfiles|Additional request headers (Optional)"
+msgid "DastProfiles|Additional request headers (optional)"
msgstr ""
msgid "DastProfiles|Are you sure you want to delete this profile?"
@@ -10981,6 +11085,9 @@ msgstr ""
msgid "DastProfiles|Branch missing"
msgstr ""
+msgid "DastProfiles|Choose a scan method"
+msgstr ""
+
msgid "DastProfiles|Could not create the scanner profile. Please try again."
msgstr ""
@@ -11050,7 +11157,13 @@ msgstr ""
msgid "DastProfiles|Excluded URLs"
msgstr ""
-msgid "DastProfiles|Excluded URLs (Optional)"
+msgid "DastProfiles|Excluded URLs (optional)"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths (optional)"
msgstr ""
msgid "DastProfiles|Hide debug messages"
@@ -11107,9 +11220,6 @@ msgstr ""
msgid "DastProfiles|Request headers"
msgstr ""
-msgid "DastProfiles|Rest API"
-msgstr ""
-
msgid "DastProfiles|Run the AJAX spider, in addition to the traditional spider, to crawl the target site."
msgstr ""
@@ -11119,6 +11229,9 @@ msgstr ""
msgid "DastProfiles|Save profile"
msgstr ""
+msgid "DastProfiles|Scan method"
+msgstr ""
+
msgid "DastProfiles|Scan mode"
msgstr ""
@@ -11197,12 +11310,24 @@ msgstr ""
msgid "DastProfiles|Website"
msgstr ""
+msgid "DastProfiles|What does each method do?"
+msgstr ""
+
msgid "DastProfiles|You can either choose a passive scan or validate the target site from the site profile management page. %{docsLinkStart}Learn more about site validation.%{docsLinkEnd}"
msgstr ""
msgid "DastProfiles|You cannot run an active scan against an unvalidated site."
msgstr ""
+msgid "DastProfiles|folder/dast_example.har or https://example.com/dast_example.har"
+msgstr ""
+
+msgid "DastProfiles|folder/example.postman_collection.json or https://example.com/"
+msgstr ""
+
+msgid "DastProfiles|folder/openapi.json or https://example.com/openapi.json"
+msgstr ""
+
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
@@ -11310,6 +11435,9 @@ msgstr ""
msgid "DatadogIntegration|API URL"
msgstr ""
+msgid "DatadogIntegration|Custom tags in Datadog. Enter one tag per line in the %{codeOpen}key:value%{codeClose} format. %{linkOpen}How do I use tags?%{linkClose}"
+msgstr ""
+
msgid "DatadogIntegration|Environment"
msgstr ""
@@ -11328,12 +11456,18 @@ msgstr ""
msgid "DatadogIntegration|Tag all data from this GitLab instance in Datadog. Useful when managing several self-managed deployments."
msgstr ""
+msgid "DatadogIntegration|Tags"
+msgstr ""
+
msgid "DatadogIntegration|The Datadog site to send data to. To send data to the EU site, use %{codeOpen}datadoghq.eu%{codeClose}."
msgstr ""
msgid "DatadogIntegration|Trace your GitLab pipelines with Datadog."
msgstr ""
+msgid "DatadogIntegration|have an invalid format"
+msgstr ""
+
msgid "Datasource name not found"
msgstr ""
@@ -11343,9 +11477,6 @@ msgstr ""
msgid "Date merged"
msgstr ""
-msgid "Date picker"
-msgstr ""
-
msgid "Date range"
msgstr ""
@@ -11499,9 +11630,6 @@ msgstr ""
msgid "Definition"
msgstr ""
-msgid "Delayed Project Deletion (%{adjourned_deletion})"
-msgstr ""
-
msgid "DelayedJobs|Are you sure you want to run %{jobName} immediately? Otherwise this job will run automatically after its timer finishes."
msgstr ""
@@ -11580,10 +11708,10 @@ msgstr ""
msgid "Delete pipeline"
msgstr ""
-msgid "Delete project"
+msgid "Delete pipeline schedule"
msgstr ""
-msgid "Delete project. Are you ABSOLUTELY SURE?"
+msgid "Delete project"
msgstr ""
msgid "Delete row"
@@ -11613,6 +11741,9 @@ msgstr ""
msgid "Delete this epic and all descendants?"
msgstr ""
+msgid "Delete this project"
+msgstr ""
+
msgid "Delete user list"
msgstr ""
@@ -11871,6 +12002,12 @@ msgstr ""
msgid "Deploy to..."
msgstr ""
+msgid "DeployBoards|To see deployment progress for your environments, make sure you are deploying to %{codeStart}$KUBE_NAMESPACE%{codeEnd} and annotating with %{codeStart}app.gitlab.com/app=$CI_PROJECT_PATH_SLUG%{codeEnd} and %{codeStart}app.gitlab.com/env=$CI_ENVIRONMENT_SLUG%{codeEnd}."
+msgstr ""
+
+msgid "DeployBoard|Kubernetes Pods"
+msgstr ""
+
msgid "DeployFreeze|Add a freeze period to prevent unintended releases during a period of time for a given environment. You must update the deployment jobs in %{filename} according to the deploy freezes added here. %{freeze_period_link_start}Learn more.%{freeze_period_link_end}"
msgstr ""
@@ -11955,9 +12092,6 @@ msgstr ""
msgid "DeployTokens|Active Deploy Tokens (%{active_tokens})"
msgstr ""
-msgid "DeployTokens|Allows read and write access to registry images."
-msgstr ""
-
msgid "DeployTokens|Allows read and write access to the package registry."
msgstr ""
@@ -11970,6 +12104,9 @@ msgstr ""
msgid "DeployTokens|Allows read-only access to the repository."
msgstr ""
+msgid "DeployTokens|Allows write access to registry images."
+msgstr ""
+
msgid "DeployTokens|Copy deploy token"
msgstr ""
@@ -12063,12 +12200,57 @@ msgstr ""
msgid "Deploying to AWS is easy with GitLab"
msgstr ""
+msgid "Deployment"
+msgstr ""
+
msgid "Deployment Frequency"
msgstr ""
+msgid "Deployment Target|Project deployment target (optional)"
+msgstr ""
+
+msgid "Deployment Target|Select the deployment target"
+msgstr ""
+
msgid "Deployment frequency"
msgstr ""
+msgid "DeploymentTarget|GitLab Pages"
+msgstr ""
+
+msgid "DeploymentTarget|Heroku"
+msgstr ""
+
+msgid "DeploymentTarget|Infrastructure provider (Terraform, Cloudformation, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Kubernetes (GKE, EKS, OpenShift, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Managed container runtime (Fargate, Cloud Run, DigitalOcean App)"
+msgstr ""
+
+msgid "DeploymentTarget|Mobile app store"
+msgstr ""
+
+msgid "DeploymentTarget|No deployment planned"
+msgstr ""
+
+msgid "DeploymentTarget|Other hosting service"
+msgstr ""
+
+msgid "DeploymentTarget|Registry (package or container)"
+msgstr ""
+
+msgid "DeploymentTarget|Self-managed container runtime (Podman, Docker Swarm, Docker Compose)"
+msgstr ""
+
+msgid "DeploymentTarget|Serverless backend (Lambda, Cloud functions)"
+msgstr ""
+
+msgid "DeploymentTarget|Virtual machine (for example, EC2)"
+msgstr ""
+
msgid "Deployments"
msgstr ""
@@ -12107,6 +12289,9 @@ msgstr ""
msgid "Deployment|This deployment was created using the API"
msgstr ""
+msgid "Deployment|Triggerer"
+msgstr ""
+
msgid "Deployment|Waiting"
msgstr ""
@@ -12134,6 +12319,18 @@ msgstr ""
msgid "Deprecated API rate limits"
msgstr ""
+msgid "Deprecations|Feature deprecation and removal"
+msgstr ""
+
+msgid "Deprecations|For information on a possible replacement %{epicStart} learn more about Opstrace %{epicEnd}."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7 and are %{epicStart} scheduled for removal %{epicEnd} in GitLab 15.0."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7, and are %{removal_link_start} scheduled for removal %{link_end} in GitLab 15.0. For information on a possible replacement, %{opstrace_link_start} learn more about Opstrace %{link_end}."
+msgstr ""
+
msgid "Deprioritize label"
msgstr ""
@@ -12379,10 +12576,10 @@ msgstr ""
msgid "DevopsAdoption|At least one deploy"
msgstr ""
-msgid "DevopsAdoption|At least one issue opened"
+msgid "DevopsAdoption|At least one issue created"
msgstr ""
-msgid "DevopsAdoption|At least one merge request opened"
+msgid "DevopsAdoption|At least one merge request created"
msgstr ""
msgid "DevopsAdoption|At least one pipeline successfully run"
@@ -12583,6 +12780,9 @@ msgstr ""
msgid "Direct member"
msgstr ""
+msgid "Direct members"
+msgstr ""
+
msgid "Direct non-authenticated users to this page."
msgstr ""
@@ -12699,6 +12899,9 @@ msgid_plural "Dismiss %d selected vulnerabilities as"
msgstr[0] ""
msgstr[1] ""
+msgid "Dismiss Alert"
+msgstr ""
+
msgid "Dismiss merge request promotion"
msgstr ""
@@ -12726,9 +12929,15 @@ msgstr ""
msgid "Display alerts from all configured monitoring tools."
msgstr ""
+msgid "Display milestones"
+msgstr ""
+
msgid "Display name"
msgstr ""
+msgid "Display progress of child issues"
+msgstr ""
+
msgid "Display rendered file"
msgstr ""
@@ -12834,6 +13043,9 @@ msgstr ""
msgid "Download image"
msgstr ""
+msgid "Download payload"
+msgstr ""
+
msgid "Download raw data (.csv)"
msgstr ""
@@ -13011,6 +13223,9 @@ msgstr ""
msgid "Edit in Web IDE"
msgstr ""
+msgid "Edit in pipeline editor"
+msgstr ""
+
msgid "Edit in single-file editor"
msgstr ""
@@ -13053,6 +13268,9 @@ msgstr ""
msgid "Edit your most recent comment in a thread (from an empty textarea)"
msgstr ""
+msgid "Edit, lint, and visualize your pipeline."
+msgstr ""
+
msgid "Edited"
msgstr ""
@@ -13494,6 +13712,9 @@ msgstr ""
msgid "Enforce two-factor authentication for all user sign-ins."
msgstr ""
+msgid "Enhance security by storing service account keys in secret managers - learn more about %{docLinkStart}secret management with GitLab%{docLinkEnd}"
+msgstr ""
+
msgid "Ensure connectivity is available from the GitLab server to the Prometheus server"
msgstr ""
@@ -13554,6 +13775,9 @@ 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 following to confirm:"
+msgstr ""
+
msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
@@ -14084,9 +14308,6 @@ 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 ""
@@ -14222,6 +14443,9 @@ msgstr ""
msgid "Errors:"
msgstr ""
+msgid "Escalate this incident"
+msgstr ""
+
msgid "Escalation Policies"
msgstr ""
@@ -14234,6 +14458,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy"
+msgstr ""
+
msgid "Escalation policy:"
msgstr ""
@@ -14485,6 +14712,9 @@ msgstr ""
msgid "Existing sign in methods may be removed"
msgstr ""
+msgid "Exit."
+msgstr ""
+
msgid "Expand"
msgstr ""
@@ -14581,6 +14811,9 @@ msgstr ""
msgid "Explore public groups"
msgstr ""
+msgid "Explore public projects"
+msgstr ""
+
msgid "Explore snippets"
msgstr ""
@@ -14742,7 +14975,7 @@ msgid_plural "Failed to archive designs. Please try again."
msgstr[0] ""
msgstr[1] ""
-msgid "Failed to assign a reviewer because no user was found."
+msgid "Failed to assign a reviewer because no user was specified."
msgstr ""
msgid "Failed to assign a user because no user was found."
@@ -14808,10 +15041,10 @@ msgstr ""
msgid "Failed to find import label for Jira import."
msgstr ""
-msgid "Failed to generate export, please try again later."
+msgid "Failed to find users for %{missing}"
msgstr ""
-msgid "Failed to generate report, please try again after sometime"
+msgid "Failed to generate export, please try again later."
msgstr ""
msgid "Failed to get ref."
@@ -14910,6 +15143,9 @@ msgstr ""
msgid "Failed to remove a to-do item for the design."
msgstr ""
+msgid "Failed to remove attention because no user was found."
+msgstr ""
+
msgid "Failed to remove mirror."
msgstr ""
@@ -14922,6 +15158,9 @@ msgstr ""
msgid "Failed to remove user key."
msgstr ""
+msgid "Failed to request attention because no user was found."
+msgstr ""
+
msgid "Failed to reset key. Please try again."
msgstr ""
@@ -15003,6 +15242,9 @@ msgstr ""
msgid "Feature Flags"
msgstr ""
+msgid "Feature deprecation and removal"
+msgstr ""
+
msgid "Feature flag status"
msgstr ""
@@ -15500,7 +15742,7 @@ msgstr ""
msgid "For each job, re-use the project workspace. If the workspace doesn't exist, use %{code_open}git clone%{code_close}."
msgstr ""
-msgid "For example, the application using the token or the purpose of the token."
+msgid "For example, the application using the token or the purpose of the token. Do not give sensitive information for the name of the token, as it will be visible to all %{resource_type} members."
msgstr ""
msgid "For files larger than this limit, only index the file name. The file content is neither indexed nor searchable."
@@ -15584,9 +15826,6 @@ msgstr ""
msgid "ForkProject|Select a namespace"
msgstr ""
-msgid "ForkProject|Select a namespace to fork the project"
-msgstr ""
-
msgid "ForkProject|The project can be accessed by any logged in user."
msgstr ""
@@ -15683,6 +15922,9 @@ msgstr ""
msgid "Full name"
msgstr ""
+msgid "GCP region configured"
+msgstr ""
+
msgid "GPG Key ID:"
msgstr ""
@@ -15863,6 +16105,9 @@ msgstr ""
msgid "Geo|Failed"
msgstr ""
+msgid "Geo|Filter Geo sites"
+msgstr ""
+
msgid "Geo|Filter by name"
msgstr ""
@@ -16274,6 +16519,12 @@ msgstr ""
msgid "GitLab Issue"
msgstr ""
+msgid "GitLab KAS"
+msgstr ""
+
+msgid "GitLab Memberships CSV Export"
+msgstr ""
+
msgid "GitLab Pages"
msgstr ""
@@ -16322,6 +16573,9 @@ 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 free to use. Many features for larger teams are part of our %{link_start}paid products%{link_end}. You can try Ultimate for free without any obligation or payment details."
+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 ""
@@ -16448,7 +16702,7 @@ msgstr ""
msgid "GitLabPages|When enabled, all attempts to visit your website through HTTP are automatically redirected to HTTPS using a response with status code 301. Requires a valid certificate for all domains. %{docs_link_start}Learn more.%{link_end}"
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. %{docs_link_start}Learn more.%{link_end}"
+msgid "GitLabPages|When using Pages under the general domain of a GitLab instance (%{pages_host}), you cannot use HTTPS with subdomains of subdomains. If your namespace or groupname contains a dot, it does not work. This is a limitation of the HTTP Over TLS protocol. HTTP pages work if you don't redirect HTTP to HTTPS. %{docs_link_start}Learn more.%{link_end}"
msgstr ""
msgid "GitLabPages|With GitLab Pages you can host your static website directly from your GitLab repository. %{docs_link_start}Learn more.%{link_end}"
@@ -16625,9 +16879,6 @@ msgstr ""
msgid "Go to find file"
msgstr ""
-msgid "Go to fork"
-msgstr ""
-
msgid "Go to issue boards"
msgstr ""
@@ -16835,9 +17086,6 @@ msgstr ""
msgid "Group Hooks"
msgstr ""
-msgid "Group ID"
-msgstr ""
-
msgid "Group Owner must have signed in with SAML before enabling Group Managed Accounts"
msgstr ""
@@ -16865,9 +17113,6 @@ msgstr ""
msgid "Group by"
msgstr ""
-msgid "Group description"
-msgstr ""
-
msgid "Group description (optional)"
msgstr ""
@@ -16982,7 +17227,7 @@ msgstr ""
msgid "Group: %{name}"
msgstr ""
-msgid "GroupActivityMetrics|Issues opened"
+msgid "GroupActivityMetrics|Issues created"
msgstr ""
msgid "GroupActivityMetrics|Last 90 days"
@@ -16991,7 +17236,7 @@ msgstr ""
msgid "GroupActivityMetrics|Members added"
msgstr ""
-msgid "GroupActivityMetrics|Merge Requests opened"
+msgid "GroupActivityMetrics|Merge Requests created"
msgstr ""
msgid "GroupActivityMetrics|Recent activity"
@@ -17282,6 +17527,9 @@ msgstr ""
msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
+msgid "GroupSettings|Choose a group path that does not start with a dash or end with a period. It can also contain alphanumeric characters and underscores."
+msgstr ""
+
msgid "GroupSettings|Compliance frameworks"
msgstr ""
@@ -17315,7 +17563,7 @@ msgstr ""
msgid "GroupSettings|If not specified at the group or instance level, the default is %{default_initial_branch_name}. Does not affect existing repositories."
msgstr ""
-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."
+msgid "GroupSettings|If the parent group's visibility is lower than the group's current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility."
msgstr ""
msgid "GroupSettings|New runners registration token has been generated!"
@@ -17432,7 +17680,10 @@ msgstr ""
msgid "Groups and projects"
msgstr ""
-msgid "Groups and subgroups"
+msgid "Groups are a great way to organize projects and people."
+msgstr ""
+
+msgid "Groups are the best way to manage projects and members."
msgstr ""
msgid "Groups to synchronize"
@@ -17543,13 +17794,16 @@ msgstr ""
msgid "GroupsTree|Are you sure you want to leave the \"%{fullName}\" group?"
msgstr ""
-msgid "GroupsTree|Edit group"
+msgid "GroupsTree|Delete"
+msgstr ""
+
+msgid "GroupsTree|Edit"
msgstr ""
msgid "GroupsTree|Failed to leave the group. Please make sure you are not the only owner."
msgstr ""
-msgid "GroupsTree|Leave this group"
+msgid "GroupsTree|Leave group"
msgstr ""
msgid "GroupsTree|Loading groups"
@@ -17561,9 +17815,57 @@ msgstr ""
msgid "GroupsTree|No groups or projects matched your search"
msgstr ""
+msgid "GroupsTree|Options"
+msgstr ""
+
msgid "GroupsTree|Search by name"
msgstr ""
+msgid "Groups|Avatar will be removed. Are you sure?"
+msgstr ""
+
+msgid "Groups|Changing group URL can have unintended side effects."
+msgstr ""
+
+msgid "Groups|Checking group URL availability..."
+msgstr ""
+
+msgid "Groups|Enter a descriptive name for your group."
+msgstr ""
+
+msgid "Groups|Group ID"
+msgstr ""
+
+msgid "Groups|Group URL"
+msgstr ""
+
+msgid "Groups|Group avatar"
+msgstr ""
+
+msgid "Groups|Group description (optional)"
+msgstr ""
+
+msgid "Groups|Group name"
+msgstr ""
+
+msgid "Groups|Group path is available."
+msgstr ""
+
+msgid "Groups|Group path is unavailable. Path has been replaced with a suggested available path."
+msgstr ""
+
+msgid "Groups|Learn more"
+msgstr ""
+
+msgid "Groups|Must start with letter, digit, emoji, or underscore. Can also contain periods, dashes, spaces, and parentheses."
+msgstr ""
+
+msgid "Groups|Remove avatar"
+msgstr ""
+
+msgid "Groups|Save changes"
+msgstr ""
+
msgid "Guideline"
msgstr ""
@@ -17573,6 +17875,9 @@ msgstr ""
msgid "HAR file path or URL"
msgstr ""
+msgid "HTTP Archive (HAR)"
+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 ""
@@ -17973,6 +18278,9 @@ msgstr ""
msgid "INFO: Your SSH key is expiring soon. Please generate a new key."
msgstr ""
+msgid "IP"
+msgstr ""
+
msgid "IP Address"
msgstr ""
@@ -18009,6 +18317,9 @@ msgstr ""
msgid "IdentityVerification|Verify your identity"
msgstr ""
+msgid "IdentityVerification|You can always verify your account at a later time to create a group."
+msgstr ""
+
msgid "If any indexed field exceeds this limit, it is truncated to this number of characters. The rest of the content is neither indexed nor searchable. This does not apply to repository and wiki indexing. For unlimited characters, set this to 0."
msgstr ""
@@ -18066,6 +18377,9 @@ msgstr ""
msgid "If you add %{codeStart}needs%{codeEnd} to jobs in your pipeline you'll be able to view the %{codeStart}needs%{codeEnd} relationships between jobs in this tab as a %{linkStart}Directed Acyclic Graph (DAG)%{linkEnd}."
msgstr ""
+msgid "If you are added to a project, it will be displayed here."
+msgstr ""
+
msgid "If you did not initiate these sign-in attempts, please reach out to your administrator or enable two-factor authentication (2FA) on your account."
msgstr ""
@@ -18372,12 +18686,24 @@ msgstr ""
msgid "InProductMarketing|3 ways to dive into GitLab CI/CD"
msgstr ""
+msgid "InProductMarketing|A single application eliminates complex integrations, data chokepoints, and toolchain maintenance, resulting in greater productivity and lower cost."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features, build more efficiently, strengthen security and compliance."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features."
+msgstr ""
+
msgid "InProductMarketing|Actually, GitLab makes the team work (better)"
msgstr ""
msgid "InProductMarketing|And finally %{deploy_link} a Python application."
msgstr ""
+msgid "InProductMarketing|And many more..."
+msgstr ""
+
msgid "InProductMarketing|Are your runners ready?"
msgstr ""
@@ -18396,15 +18722,33 @@ msgstr ""
msgid "InProductMarketing|Blog"
msgstr ""
+msgid "InProductMarketing|Break down silos to coordinate seamlessly across development, operations, and security with a consistent experience across the development lifecycle."
+msgstr ""
+
+msgid "InProductMarketing|Burn up/down charts"
+msgstr ""
+
msgid "InProductMarketing|By enabling code owners and required merge approvals the right person will review the right MR. This is a win-win: cleaner code and a more efficient review process."
msgstr ""
msgid "InProductMarketing|Click on the number below that corresponds with your answer — 1 being very difficult, 5 being very easy."
msgstr ""
+msgid "InProductMarketing|Code owners"
+msgstr ""
+
msgid "InProductMarketing|Code owners and required merge approvals are part of the paid tiers of GitLab. You can start a free 30-day trial of GitLab Ultimate and enable these features in less than 5 minutes with no credit card required."
msgstr ""
+msgid "InProductMarketing|Code review analytics"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration across stages in GitLab"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration made easy"
+msgstr ""
+
msgid "InProductMarketing|Create a custom CI runner with just a few clicks"
msgstr ""
@@ -18414,12 +18758,21 @@ msgstr ""
msgid "InProductMarketing|Create a project in GitLab in 5 minutes"
msgstr ""
+msgid "InProductMarketing|Create well-defined workflows by using scoped labels on issues, merge requests, and epics. Labels with the same scope cannot be used together, which prevents conflicts."
+msgstr ""
+
msgid "InProductMarketing|Create your first project!"
msgstr ""
+msgid "InProductMarketing|Define who owns specific files or directories, so the right reviewers are suggested when a merge request introduces changes to those files."
+msgstr ""
+
msgid "InProductMarketing|Deliver Better Products Faster"
msgstr ""
+msgid "InProductMarketing|Dependency scanning"
+msgstr ""
+
msgid "InProductMarketing|Did you know teams that use GitLab are far more efficient?"
msgstr ""
@@ -18429,15 +18782,27 @@ msgstr ""
msgid "InProductMarketing|Dig in and create a project and a repo"
msgstr ""
+msgid "InProductMarketing|Discover Premium & Ultimate"
+msgstr ""
+
+msgid "InProductMarketing|Discover Premium & Ultimate."
+msgstr ""
+
msgid "InProductMarketing|Do you have a minute?"
msgstr ""
msgid "InProductMarketing|Do you have a teammate who would be perfect for this task?"
msgstr ""
+msgid "InProductMarketing|Dynamic application security testing"
+msgstr ""
+
msgid "InProductMarketing|Easy"
msgstr ""
+msgid "InProductMarketing|Epics"
+msgstr ""
+
msgid "InProductMarketing|Expand your DevOps journey with a free GitLab trial"
msgstr ""
@@ -18459,9 +18824,15 @@ msgstr ""
msgid "InProductMarketing|Feel the need for speed?"
msgstr ""
+msgid "InProductMarketing|Find and fix bottlenecks in your code review process by understanding how long open merge requests have been in review."
+msgstr ""
+
msgid "InProductMarketing|Find out how your teams are really doing"
msgstr ""
+msgid "InProductMarketing|Find out if your external libraries are safe. Run dependency scanning jobs that check for known vulnerabilities in your external libraries."
+msgstr ""
+
msgid "InProductMarketing|Follow our steps"
msgstr ""
@@ -18498,6 +18869,9 @@ msgstr ""
msgid "InProductMarketing|GitLab is better with teammates to help out!"
msgstr ""
+msgid "InProductMarketing|GitLab is infrastructure agnostic (supporting GCP, AWS, Azure, OpenShift, VMWare, On Prem, Bare Metal, and more), offering a consistent workflow experience – irrespective of the environment."
+msgstr ""
+
msgid "InProductMarketing|GitLab provides static application security testing (SAST), dynamic application security testing (DAST), container scanning, and dependency scanning to help you deliver secure applications along with license compliance."
msgstr ""
@@ -18588,21 +18962,36 @@ msgstr ""
msgid "InProductMarketing|It's also possible to simply %{external_repo_link} in order to take advantage of GitLab's CI/CD."
msgstr ""
+msgid "InProductMarketing|Keep your code quality high by defining who should approve merge requests and how many approvals are required."
+msgstr ""
+
msgid "InProductMarketing|Launch GitLab CI/CD in 20 minutes or less"
msgstr ""
+msgid "InProductMarketing|Lower cost of development"
+msgstr ""
+
+msgid "InProductMarketing|Make it easier to collaborate on high-level ideas by grouping related issues in an epic."
+msgstr ""
+
msgid "InProductMarketing|Making the switch? It's easier than you think to import your projects into GitLab. Move %{github_link}, or import something %{bitbucket_link}."
msgstr ""
msgid "InProductMarketing|Master the art of importing!"
msgstr ""
+msgid "InProductMarketing|Merge request approval rule"
+msgstr ""
+
msgid "InProductMarketing|Move on to easily creating a Pages website %{ci_template_link}"
msgstr ""
msgid "InProductMarketing|Multiple owners, confusing workstreams? We've got you covered"
msgstr ""
+msgid "InProductMarketing|Multiple required approvers"
+msgstr ""
+
msgid "InProductMarketing|Need an alternative to importing?"
msgstr ""
@@ -18615,18 +19004,33 @@ msgstr ""
msgid "InProductMarketing|Our tool brings all the things together"
msgstr ""
+msgid "InProductMarketing|Protect your web application by using DAST to examine for vulnerabilities in deployed environments."
+msgstr ""
+
msgid "InProductMarketing|Rapid development, simplified"
msgstr ""
msgid "InProductMarketing|Reduce Security & Compliance Risk"
msgstr ""
+msgid "InProductMarketing|Require multiple approvers on a merge request, so you know it's in good shape before it's merged."
+msgstr ""
+
+msgid "InProductMarketing|Roadmaps"
+msgstr ""
+
+msgid "InProductMarketing|Scoped labels"
+msgstr ""
+
msgid "InProductMarketing|Security that's integrated into your development lifecycle"
msgstr ""
msgid "InProductMarketing|Sometimes you're not ready to make a full transition to a new tool. If you're not ready to fully commit, %{mirroring_link} gives you a safe way to try out GitLab in parallel with your current tool."
msgstr ""
+msgid "InProductMarketing|Speed. Efficiency. Trust."
+msgstr ""
+
msgid "InProductMarketing|Spin up an autoscaling runner in GitLab"
msgstr ""
@@ -18636,6 +19040,9 @@ msgstr ""
msgid "InProductMarketing|Start a Self-Managed trial"
msgstr ""
+msgid "InProductMarketing|Start a free trial"
+msgstr ""
+
msgid "InProductMarketing|Start a free trial of GitLab Ultimate – no credit card required"
msgstr ""
@@ -18702,6 +19109,9 @@ msgstr ""
msgid "InProductMarketing|To understand and get the most out of GitLab, start at the beginning and %{project_link}. In GitLab, repositories are part of a project, so after you've created your project you can go ahead and %{repo_link}."
msgstr ""
+msgid "InProductMarketing|Track completed issues in a chart, so you can see how a milestone is progressing at a glance."
+msgstr ""
+
msgid "InProductMarketing|Try GitLab Ultimate for free"
msgstr ""
@@ -18738,6 +19148,9 @@ msgstr ""
msgid "InProductMarketing|Very easy"
msgstr ""
+msgid "InProductMarketing|Visualize your epics and milestones in a timeline."
+msgstr ""
+
msgid "InProductMarketing|Want to host GitLab on your servers?"
msgstr ""
@@ -18759,6 +19172,9 @@ msgstr ""
msgid "InProductMarketing|YouTube"
msgstr ""
+msgid "InProductMarketing|Your software, deployed your way"
+msgstr ""
+
msgid "InProductMarketing|Your teams can be more efficient"
msgstr ""
@@ -18879,9 +19295,18 @@ msgstr ""
msgid "IncidentManagement|No incidents to display."
msgstr ""
+msgid "IncidentManagement|None"
+msgstr ""
+
msgid "IncidentManagement|Open"
msgstr ""
+msgid "IncidentManagement|Page your team with escalation policies"
+msgstr ""
+
+msgid "IncidentManagement|Paged"
+msgstr ""
+
msgid "IncidentManagement|Published"
msgstr ""
@@ -18891,6 +19316,9 @@ msgstr ""
msgid "IncidentManagement|Severity"
msgstr ""
+msgid "IncidentManagement|Status"
+msgstr ""
+
msgid "IncidentManagement|There are no closed incidents"
msgstr ""
@@ -18909,6 +19337,9 @@ msgstr ""
msgid "IncidentManagement|Unpublished"
msgstr ""
+msgid "IncidentManagement|Use escalation policies to automatically page your team when incidents are created."
+msgstr ""
+
msgid "IncidentSettings|Activate \"time to SLA\" countdown timer"
msgstr ""
@@ -18954,7 +19385,10 @@ msgstr ""
msgid "Incidents"
msgstr ""
-msgid "Incidents|Add a URL"
+msgid "Incidents|Add image details"
+msgstr ""
+
+msgid "Incidents|Add text or a link to display with your image. If you don't add either, the file name displays instead."
msgstr ""
msgid "Incidents|Drop or %{linkStart}upload%{linkEnd} a metric screenshot to attach it to the incident"
@@ -18969,10 +19403,10 @@ msgstr ""
msgid "Incidents|There was an issue loading metric images."
msgstr ""
-msgid "Incidents|There was an issue uploading your image."
+msgid "Incidents|There was an issue updating your image."
msgstr ""
-msgid "Incidents|You can optionally add a URL to link users to the original graph."
+msgid "Incidents|There was an issue uploading your image."
msgstr ""
msgid "Incident|Alert details"
@@ -18981,9 +19415,18 @@ msgstr ""
msgid "Incident|Are you sure you wish to delete this image?"
msgstr ""
+msgid "Incident|Delete image"
+msgstr ""
+
msgid "Incident|Deleting %{filename}"
msgstr ""
+msgid "Incident|Edit image text or link"
+msgstr ""
+
+msgid "Incident|Editing %{filename}"
+msgstr ""
+
msgid "Incident|Metrics"
msgstr ""
@@ -19253,12 +19696,18 @@ msgstr ""
msgid "Integrations|Branches for which notifications are to be sent"
msgstr ""
+msgid "Integrations|Clear if using a self-signed certificate."
+msgstr ""
+
msgid "Integrations|Comment detail:"
msgstr ""
msgid "Integrations|Comment settings:"
msgstr ""
+msgid "Integrations|Connection details"
+msgstr ""
+
msgid "Integrations|Connection failed. Please check your settings."
msgstr ""
@@ -19283,6 +19732,9 @@ msgstr ""
msgid "Integrations|Enable GitLab.com slash commands in a Slack workspace."
msgstr ""
+msgid "Integrations|Enable SSL verification"
+msgstr ""
+
msgid "Integrations|Enable comments"
msgstr ""
@@ -19361,6 +19813,9 @@ msgstr ""
msgid "Integrations|Return to GitLab for Jira"
msgstr ""
+msgid "Integrations|SSL verification"
+msgstr ""
+
msgid "Integrations|Save settings?"
msgstr ""
@@ -19406,9 +19861,6 @@ msgstr ""
msgid "Integrations|Use default settings"
msgstr ""
-msgid "Integrations|When you mention a Jira issue in a commit or merge request, GitLab creates a remote link and comment (if enabled)."
-msgstr ""
-
msgid "Integrations|You can now close this window and return to the GitLab for Jira application."
msgstr ""
@@ -19433,9 +19885,6 @@ msgstr ""
msgid "Integrations|can't exceed %{recipients_limit}"
msgstr ""
-msgid "Interactive developer security education."
-msgstr ""
-
msgid "Interactive mode"
msgstr ""
@@ -19925,6 +20374,9 @@ msgstr ""
msgid "IssueAnalytics|Assignees"
msgstr ""
+msgid "IssueAnalytics|Created by"
+msgstr ""
+
msgid "IssueAnalytics|Due date"
msgstr ""
@@ -19937,9 +20389,6 @@ msgstr ""
msgid "IssueAnalytics|Milestone"
msgstr ""
-msgid "IssueAnalytics|Opened by"
-msgstr ""
-
msgid "IssueAnalytics|Status"
msgstr ""
@@ -20063,10 +20512,10 @@ msgstr ""
msgid "IssuesAnalytics|Avg/Month:"
msgstr ""
-msgid "IssuesAnalytics|Issues opened"
+msgid "IssuesAnalytics|Issues created"
msgstr ""
-msgid "IssuesAnalytics|Issues opened per month"
+msgid "IssuesAnalytics|Issues created per month"
msgstr ""
msgid "IssuesAnalytics|Last 12 months"
@@ -20093,6 +20542,9 @@ msgstr ""
msgid "It looks like you have some draft commits in this branch."
msgstr ""
+msgid "It looks like you're attempting to activate your subscription. Use %{a_start}the Subscription page%{a_end} instead."
+msgstr ""
+
msgid "It may be several days before you see feature usage data."
msgstr ""
@@ -20321,6 +20773,9 @@ msgstr ""
msgid "JiraConnect|You can now close this window and return to Jira."
msgstr ""
+msgid "JiraConnect|You don't have permission to create branches for this project. Select a different project or contact the project owner for access. %{linkStart}Learn more.%{linkEnd}"
+msgstr ""
+
msgid "JiraRequest|A connection error occurred while connecting to Jira. Try your request again."
msgstr ""
@@ -20369,13 +20824,13 @@ msgstr ""
msgid "JiraService|Define the type of Jira issue to create from a vulnerability."
msgstr ""
-msgid "JiraService|Displaying Jira issues while leaving the GitLab issue functionality enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
+msgid "JiraService|Displaying Jira issues while leaving GitLab issues also enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
msgstr ""
-msgid "JiraService|Enable Jira issues"
+msgid "JiraService|Enable Jira issue creation from vulnerabilities"
msgstr ""
-msgid "JiraService|Enable Jira issues creation from vulnerabilities"
+msgid "JiraService|Enable Jira issues"
msgstr ""
msgid "JiraService|Enable Jira transitions"
@@ -20492,16 +20947,19 @@ msgstr ""
msgid "JiraService|View Jira issues in GitLab"
msgstr ""
-msgid "JiraService|Warning: All GitLab users that have access to this GitLab project are able to view all issues from the Jira project specified below."
+msgid "JiraService|Warning: All GitLab users with access to this GitLab project can view all issues from the Jira project you select."
msgstr ""
msgid "JiraService|Web URL"
msgstr ""
-msgid "JiraService|Work on Jira issues without leaving GitLab. Adds a Jira menu to access your list of Jira issues and view any issue as read-only."
+msgid "JiraService|When a Jira issue is mentioned in a commit or merge request, a remote link and comment (if enabled) will be created."
+msgstr ""
+
+msgid "JiraService|Work on Jira issues without leaving GitLab. Add a Jira menu to access a read-only list of your Jira issues."
msgstr ""
-msgid "JiraService|You need to configure Jira before enabling this integration. For more details, read the %{jira_doc_link_start}Jira integration documentation%{link_end}."
+msgid "JiraService|You must configure Jira before enabling this integration. %{jira_doc_link_start}Learn more.%{link_end}"
msgstr ""
msgid "Job"
@@ -20513,9 +20971,6 @@ msgstr ""
msgid "Job Failed #%{build_id}"
msgstr ""
-msgid "Job ID"
-msgstr ""
-
msgid "Job artifact"
msgstr ""
@@ -20582,9 +21037,27 @@ msgstr ""
msgid "Jobs|You're about to retry a job that failed because it attempted to deploy code that is older than the latest deployment. Retrying this job could result in overwriting the environment with the older source code."
msgstr ""
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source} into %{target}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{ref}"
+msgstr ""
+
+msgid "Job|Are you sure you want to erase this job log and artifacts?"
+msgstr ""
+
msgid "Job|Browse"
msgstr ""
+msgid "Job|Cancel"
+msgstr ""
+
msgid "Job|Complete Raw"
msgstr ""
@@ -20594,6 +21067,9 @@ msgstr ""
msgid "Job|Erase job log and artifacts"
msgstr ""
+msgid "Job|Finished at"
+msgstr ""
+
msgid "Job|Job artifacts"
msgstr ""
@@ -20606,7 +21082,7 @@ msgstr ""
msgid "Job|Keep"
msgstr ""
-msgid "Job|Pipeline"
+msgid "Job|Retry"
msgstr ""
msgid "Job|Scroll to bottom"
@@ -20618,6 +21094,9 @@ msgstr ""
msgid "Job|Show complete raw"
msgstr ""
+msgid "Job|Status"
+msgstr ""
+
msgid "Job|The artifacts were removed"
msgstr ""
@@ -20645,21 +21124,12 @@ msgstr ""
msgid "Job|delayed"
msgstr ""
-msgid "Job|for"
-msgstr ""
-
-msgid "Job|into"
-msgstr ""
-
msgid "Job|manual"
msgstr ""
msgid "Job|triggered"
msgstr ""
-msgid "Job|with"
-msgstr ""
-
msgid "Join Zoom meeting"
msgstr ""
@@ -20762,9 +21232,6 @@ msgstr ""
msgid "Ki"
msgstr ""
-msgid "Kontra"
-msgstr ""
-
msgid "Kroki"
msgstr ""
@@ -21088,6 +21555,9 @@ msgstr ""
msgid "Learn more about Auto DevOps"
msgstr ""
+msgid "Learn more about GitLab"
+msgstr ""
+
msgid "Learn more about Needs relationships"
msgstr ""
@@ -21415,9 +21885,18 @@ msgstr ""
msgid "Licenses|Displays licenses detected in the project, based on the %{linkStart}latest successful%{linkEnd} scan"
msgstr ""
+msgid "Licenses|Drag your license file here or %{linkStart}click to upload%{linkEnd}."
+msgstr ""
+
+msgid "Licenses|Drop your license file to start the upload."
+msgstr ""
+
msgid "Licenses|Error fetching the license list. Please check your network connection and try again."
msgstr ""
+msgid "Licenses|Error: You are trying to upload something other than a file"
+msgstr ""
+
msgid "Licenses|License Compliance"
msgstr ""
@@ -21436,6 +21915,9 @@ msgstr ""
msgid "Licenses|Specified policies in this project"
msgstr ""
+msgid "Licenses|The file could not be uploaded."
+msgstr ""
+
msgid "Licenses|The license list details information about the licenses used within your project."
msgstr ""
@@ -21469,11 +21951,6 @@ msgstr ""
msgid "Limit the size of Sidekiq jobs stored in Redis."
msgstr ""
-msgid "Limited to showing %d event at most"
-msgid_plural "Limited to showing %d events at most"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Limiting mode"
msgstr ""
@@ -21483,6 +21960,9 @@ msgstr ""
msgid "Link"
msgstr ""
+msgid "Link (optional)"
+msgstr ""
+
msgid "Link Prometheus monitoring to GitLab."
msgstr ""
@@ -21519,6 +21999,9 @@ msgstr ""
msgid "Linked emails (%{email_count})"
msgstr ""
+msgid "Linked epics"
+msgstr ""
+
msgid "Linked issues"
msgstr ""
@@ -21546,6 +22029,15 @@ msgstr ""
msgid "List of all merge commits"
msgstr ""
+msgid "List of environments for this project"
+msgstr ""
+
+msgid "List of suitable GCP locations"
+msgstr ""
+
+msgid "List of users allowed to exceed the rate limit."
+msgstr ""
+
msgid "List options"
msgstr ""
@@ -21765,6 +22257,9 @@ msgstr ""
msgid "Maintenance mode"
msgstr ""
+msgid "Make adjustments to how your GitLab instance is set up."
+msgstr ""
+
msgid "Make and review changes in the browser with the Web IDE"
msgstr ""
@@ -21909,6 +22404,12 @@ msgstr ""
msgid "MarkdownEditor|Add italic text (%{modifier_key}I)"
msgstr ""
+msgid "MarkdownEditor|Add strikethrough text (%{modifierKey}⇧X)"
+msgstr ""
+
+msgid "MarkdownEditor|Add strikethrough text (%{modifier_key}⇧X)"
+msgstr ""
+
msgid "Marked For Deletion At - %{deletion_time}"
msgstr ""
@@ -22170,6 +22671,9 @@ msgstr ""
msgid "Maximum push size (MB)"
msgstr ""
+msgid "Maximum requests per 10 minutes per user"
+msgstr ""
+
msgid "Maximum requests per minute"
msgstr ""
@@ -22260,6 +22764,19 @@ msgstr ""
msgid "Members of a group may only view projects they have permission to access"
msgstr ""
+msgid "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seat in use and will be billed for the overage."
+msgid_plural "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seats in use and will be billed for the overage."
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "MembersOverage|You are about to incur additional charges"
+msgstr ""
+
+msgid "MembersOverage|Your subscription includes %d seat."
+msgid_plural "MembersOverage|Your subscription includes %d seats."
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Membership"
msgstr ""
@@ -22464,9 +22981,6 @@ msgstr ""
msgid "Merge request not merged"
msgstr ""
-msgid "Merge request pipelines 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 merge request pipelines."
-msgstr ""
-
msgid "Merge request reports"
msgstr ""
@@ -22563,13 +23077,13 @@ msgstr ""
msgid "MergeRequests|Create issue to resolve thread"
msgstr ""
-msgid "MergeRequests|Failed to squash. Should be done manually."
+msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Saving the comment failed"
+msgid "MergeRequests|Squashing failed: Squash the commits locally, resolve any conflicts, then push the branch."
msgstr ""
-msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
+msgid "MergeRequests|Squashing not allowed: This project doesn't allow you to squash commits when merging."
msgstr ""
msgid "MergeRequests|Thread stays resolved"
@@ -23410,6 +23924,18 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "MrList|Assigned to %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from assignee %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from reviewer %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Review requested from %{name}, go to their profile."
+msgstr ""
+
msgid "Multi-project"
msgstr ""
@@ -23443,7 +23969,7 @@ msgstr ""
msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "My Awesome Group"
+msgid "My awesome group"
msgstr ""
msgid "My company or team"
@@ -24065,9 +24591,6 @@ msgstr ""
msgid "No available branches"
msgstr ""
-msgid "No available groups to fork the project."
-msgstr ""
-
msgid "No branches found"
msgstr ""
@@ -24278,6 +24801,9 @@ msgstr ""
msgid "No ref selected"
msgstr ""
+msgid "No regions configured"
+msgstr ""
+
msgid "No related merge requests found."
msgstr ""
@@ -25082,6 +25608,9 @@ msgstr ""
msgid "Only reCAPTCHA v2 is supported:"
msgstr ""
+msgid "Only required if not using role instance credentials."
+msgstr ""
+
msgid "Only use lowercase letters, numbers, and underscores."
msgstr ""
@@ -25106,9 +25635,6 @@ msgstr ""
msgid "Open a CLI and connect to the cluster you want to install the agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
-msgid "Open epics"
-msgstr ""
-
msgid "Open errors"
msgstr ""
@@ -25148,7 +25674,7 @@ msgstr ""
msgid "Opened issues"
msgstr ""
-msgid "OpenedNDaysAgo|Opened"
+msgid "OpenedNDaysAgo|Created"
msgstr ""
msgid "Opens in a new window"
@@ -25193,9 +25719,6 @@ msgstr ""
msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
-msgid "Optional."
-msgstr ""
-
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
msgstr ""
@@ -25984,6 +26507,9 @@ msgstr ""
msgid "PerformanceBar|Memory"
msgstr ""
+msgid "PerformanceBar|Memory report"
+msgstr ""
+
msgid "PerformanceBar|Redis calls"
msgstr ""
@@ -26017,18 +26543,12 @@ msgstr ""
msgid "PerformanceBar|wall"
msgstr ""
-msgid "Performs a rebase but skips triggering a new pipeline"
-msgstr ""
-
msgid "Period in seconds"
msgstr ""
msgid "Permalink"
msgstr ""
-msgid "Permanently delete project"
-msgstr ""
-
msgid "Permanently remove group"
msgstr ""
@@ -26299,6 +26819,51 @@ msgstr ""
msgid "PipelineStatusTooltip|Pipeline: %{ci_status}"
msgstr ""
+msgid "PipelineWizardDefaultCommitMessage|Add %{filename}"
+msgstr ""
+
+msgid "PipelineWizardDefaultCommitMessage|Update %{filename}"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|At least one entry is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This field is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This value is not valid"
+msgstr ""
+
+msgid "PipelineWizardListWidget|add another step"
+msgstr ""
+
+msgid "PipelineWizardListWidget|remove step"
+msgstr ""
+
+msgid "PipelineWizard|Commit"
+msgstr ""
+
+msgid "PipelineWizard|Commit Message"
+msgstr ""
+
+msgid "PipelineWizard|Commit changes to your file"
+msgstr ""
+
+msgid "PipelineWizard|Commit file to Branch"
+msgstr ""
+
+msgid "PipelineWizard|Commit your new file"
+msgstr ""
+
+msgid "PipelineWizard|The file has been committed."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem committing the changes."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem while checking whether your file already exists in the specified branch."
+msgstr ""
+
msgid "Pipelines"
msgstr ""
@@ -26413,7 +26978,7 @@ msgstr ""
msgid "Pipelines|Project cache successfully reset."
msgstr ""
-msgid "Pipelines|Revoke"
+msgid "Pipelines|Revoke trigger"
msgstr ""
msgid "Pipelines|Something went wrong while cleaning runners cache."
@@ -26458,6 +27023,12 @@ msgstr ""
msgid "Pipelines|This is a child pipeline within the parent pipeline"
msgstr ""
+msgid "Pipelines|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipelines|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipelines|This pipeline will run code originating from a forked project merge request. This means that the code can potentially have security considerations like exposing CI variables."
msgstr ""
@@ -26500,9 +27071,6 @@ msgstr ""
msgid "Pipelines|Your changes have been successfully committed. Now redirecting to the new merge request page."
msgstr ""
-msgid "Pipelines|detached"
-msgstr ""
-
msgid "Pipelines|error"
msgstr ""
@@ -26512,10 +27080,13 @@ msgstr ""
msgid "Pipelines|latest"
msgstr ""
-msgid "Pipelines|stuck"
+msgid "Pipelines|merge request"
msgstr ""
-msgid "Pipelines|train"
+msgid "Pipelines|merge train"
+msgstr ""
+
+msgid "Pipelines|stuck"
msgstr ""
msgid "Pipelines|yaml invalid"
@@ -26647,6 +27218,12 @@ msgstr ""
msgid "Pipeline|This change will not change the overall test coverage if merged."
msgstr ""
+msgid "Pipeline|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipeline|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipeline|Trigger author"
msgstr ""
@@ -26671,6 +27248,12 @@ msgstr ""
msgid "Pipeline|for"
msgstr ""
+msgid "Pipeline|merge request"
+msgstr ""
+
+msgid "Pipeline|merge train"
+msgstr ""
+
msgid "Pipeline|on"
msgstr ""
@@ -26809,9 +27392,6 @@ msgstr ""
msgid "Please enter a valid time interval"
msgstr ""
-msgid "Please enter or upload a valid license."
-msgstr ""
-
msgid "Please enter your current password."
msgstr ""
@@ -26920,9 +27500,6 @@ msgstr ""
msgid "Please type %{phrase_code} to proceed or close this modal to cancel."
msgstr ""
-msgid "Please type the following to confirm:"
-msgstr ""
-
msgid "Please use this form to report to the admin users who create spam issues, comments or behave inappropriately."
msgstr ""
@@ -26950,12 +27527,27 @@ msgstr ""
msgid "Policies"
msgstr ""
+msgid "Policy '%{escalation_policy_name}' does not exist."
+msgstr ""
+
msgid "Policy management project does have any policies in %{policy_path}"
msgstr ""
msgid "Policy project doesn't exist"
msgstr ""
+msgid "PolicyRuleMultiSelect|%{firstLabel} +%{numberOfAdditionalLabels} more"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|All %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select all"
+msgstr ""
+
msgid "Polling interval multiplier"
msgstr ""
@@ -27184,6 +27776,9 @@ msgstr ""
msgid "Private projects can be created in your personal namespace with:"
msgstr ""
+msgid "Problem with %{name} command: %{message}."
+msgstr ""
+
msgid "Proceed"
msgstr ""
@@ -27658,6 +28253,9 @@ msgstr ""
msgid "Progress"
msgstr ""
+msgid "Progress tracking"
+msgstr ""
+
msgid "Project"
msgstr ""
@@ -27889,6 +28487,9 @@ msgstr ""
msgid "ProjectQualitySummary|Failure"
msgstr ""
+msgid "ProjectQualitySummary|Get insight into the overall percentage of tests in your project that succeed, fail and are skipped."
+msgstr ""
+
msgid "ProjectQualitySummary|Latest pipeline results"
msgstr ""
@@ -27907,6 +28508,12 @@ msgstr ""
msgid "ProjectQualitySummary|See project Code Coverage Statistics"
msgstr ""
+msgid "ProjectQualitySummary|Set up test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|Set up test runs (opens in a new tab)"
+msgstr ""
+
msgid "ProjectQualitySummary|Skipped"
msgstr ""
@@ -28183,13 +28790,19 @@ msgstr ""
msgid "ProjectSettings|LFS objects from this repository are available to forks. %{linkStart}How do I remove them?%{linkEnd}"
msgstr ""
+msgid "ProjectSettings|Learn about commit history."
+msgstr ""
+
+msgid "ProjectSettings|Leave empty to use default template."
+msgstr ""
+
msgid "ProjectSettings|Manage who can see the project in the public access directory."
msgstr ""
msgid "ProjectSettings|Manages large files such as audio, video, and graphics files."
msgstr ""
-msgid "ProjectSettings|Maximum 500 characters."
+msgid "ProjectSettings|Maximum %{maxLength} characters."
msgstr ""
msgid "ProjectSettings|Merge checks"
@@ -28330,6 +28943,9 @@ msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
msgstr ""
+msgid "ProjectSettings|The default template will be applied on save."
+msgstr ""
+
msgid "ProjectSettings|These checks must pass before merge requests can be merged."
msgstr ""
@@ -28384,6 +29000,9 @@ msgstr ""
msgid "ProjectSettings|What are badges?"
msgstr ""
+msgid "ProjectSettings|What are merge trains?"
+msgstr ""
+
msgid "ProjectSettings|When merge request pipelines are enabled in the CI/CD configuration file, pipelines validate the combined results of the source and target branches. %{link_start}How to configure merge request pipelines?%{link_end}"
msgstr ""
@@ -28501,6 +29120,9 @@ msgstr ""
msgid "Projects are organized into groups"
msgstr ""
+msgid "Projects are where you store your code, access issues, wiki and other features of GitLab."
+msgstr ""
+
msgid "Projects contributed to"
msgstr ""
@@ -28516,12 +29138,6 @@ msgstr ""
msgid "Projects to index"
msgstr ""
-msgid "Projects will be permanently deleted after a %{waiting_period}-day waiting period."
-msgstr ""
-
-msgid "Projects will be permanently deleted immediately."
-msgstr ""
-
msgid "Projects with critical vulnerabilities"
msgstr ""
@@ -28606,6 +29222,9 @@ msgstr ""
msgid "ProjectsNew|Import project"
msgstr ""
+msgid "ProjectsNew|Include a Getting Started README"
+msgstr ""
+
msgid "ProjectsNew|Initialize repository with a README"
msgstr ""
@@ -28621,6 +29240,9 @@ msgstr ""
msgid "ProjectsNew|Project description %{tag_start}(optional)%{tag_end}"
msgstr ""
+msgid "ProjectsNew|Recommended if you're new to GitLab"
+msgstr ""
+
msgid "ProjectsNew|Run CI/CD for external repository"
msgstr ""
@@ -29038,6 +29660,9 @@ msgstr ""
msgid "ProtectedBranch|Unprotect"
msgstr ""
+msgid "ProtectedBranch|Unprotect branch"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
@@ -29065,6 +29690,9 @@ msgstr ""
msgid "ProtectedEnvironment|Protected Environment (%{protected_environments_count})"
msgstr ""
+msgid "ProtectedEnvironment|Required approvals"
+msgstr ""
+
msgid "ProtectedEnvironment|Select an environment"
msgstr ""
@@ -29086,10 +29714,13 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|Unprotect tag"
+msgstr ""
+
msgid "ProtectedTags|default"
msgstr ""
-msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
+msgid "ProtectedTag|By default, protected tags restrict who can modify the tag."
msgstr ""
msgid "ProtectedTag|Learn more."
@@ -29152,6 +29783,9 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Public projects are an easy way to allow everyone to have read-only access."
+msgstr ""
+
msgid "Publish to status page"
msgstr ""
@@ -29308,9 +29942,6 @@ msgstr ""
msgid "QualitySummary|Project quality"
msgstr ""
-msgid "Quarters"
-msgstr ""
-
msgid "Query"
msgstr ""
@@ -29395,6 +30026,9 @@ msgstr ""
msgid "Read more about project permissions %{help_link_open}here%{help_link_close}"
msgstr ""
+msgid "Read more about related epics"
+msgstr ""
+
msgid "Read more about related issues"
msgstr ""
@@ -29425,10 +30059,7 @@ msgstr ""
msgid "Rebase source branch on the target branch."
msgstr ""
-msgid "Rebase without CI"
-msgstr ""
-
-msgid "Rebases and triggers a pipeline"
+msgid "Rebase without pipeline"
msgstr ""
msgid "Recaptcha verified?"
@@ -29479,9 +30110,6 @@ msgstr ""
msgid "Reconfigure"
msgstr ""
-msgid "Recovering projects"
-msgstr ""
-
msgid "Recovery Codes"
msgstr ""
@@ -29541,6 +30169,12 @@ msgstr ""
msgid "Regex pattern"
msgstr ""
+msgid "Region"
+msgstr ""
+
+msgid "Regions"
+msgstr ""
+
msgid "Register"
msgstr ""
@@ -29771,9 +30405,6 @@ msgstr ""
msgid "Remove all or specific reviewer(s)"
msgstr ""
-msgid "Remove approver"
-msgstr ""
-
msgid "Remove approvers"
msgstr ""
@@ -29789,6 +30420,9 @@ msgstr ""
msgid "Remove attention request"
msgstr ""
+msgid "Remove attention request(s)"
+msgstr ""
+
msgid "Remove avatar"
msgstr ""
@@ -29927,6 +30561,9 @@ msgstr ""
msgid "Removed an issue from an epic."
msgstr ""
+msgid "Removed attention from %{users_sentence}."
+msgstr ""
+
msgid "Removed attention request from @%{username}"
msgstr ""
@@ -29978,6 +30615,9 @@ msgstr ""
msgid "Removes an issue from an epic."
msgstr ""
+msgid "Removes attention from %{users_sentence}."
+msgstr ""
+
msgid "Removes parent epic %{epic_ref}."
msgstr ""
@@ -30089,6 +30729,9 @@ msgstr ""
msgid "Report abuse to admin"
msgstr ""
+msgid "Report is generating and will be sent to your email address."
+msgstr ""
+
msgid "Reported %{timeAgo} by %{reportedBy}"
msgstr ""
@@ -30378,6 +31021,15 @@ msgstr ""
msgid "Request attention"
msgstr ""
+msgid "Request attention from %{users_sentence}."
+msgstr ""
+
+msgid "Request attention from assignee or reviewer"
+msgstr ""
+
+msgid "Request attention from assignee(s) or reviewer(s)"
+msgstr ""
+
msgid "Request attention to review"
msgstr ""
@@ -30402,6 +31054,9 @@ msgstr ""
msgid "Requested %{time_ago}"
msgstr ""
+msgid "Requested attention from %{users_sentence}."
+msgstr ""
+
msgid "Requested attention from @%{username}"
msgstr ""
@@ -30616,6 +31271,9 @@ msgstr ""
msgid "Restore project"
msgstr ""
+msgid "Restoring projects"
+msgstr ""
+
msgid "Restoring the group will prevent the group, its subgroups and projects from being removed on this date."
msgstr ""
@@ -30646,6 +31304,9 @@ msgstr ""
msgid "Retry"
msgstr ""
+msgid "Retry failed jobs"
+msgstr ""
+
msgid "Retry job"
msgstr ""
@@ -30693,9 +31354,6 @@ msgstr ""
msgid "Review changes"
msgstr ""
-msgid "Review requested from %{name}"
-msgstr ""
-
msgid "Review requests for you"
msgstr ""
@@ -30860,6 +31518,9 @@ msgstr ""
msgid "Runners|Assigned Group"
msgstr ""
+msgid "Runners|Assigned Projects (%{projectCount})"
+msgstr ""
+
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30929,6 +31590,9 @@ msgstr ""
msgid "Runners|Instance"
msgstr ""
+msgid "Runners|Jobs"
+msgstr ""
+
msgid "Runners|Last contact"
msgstr ""
@@ -31022,9 +31686,6 @@ msgstr ""
msgid "Runners|Runner %{name} was deleted"
msgstr ""
-msgid "Runners|Runner ID"
-msgstr ""
-
msgid "Runners|Runner assigned to project."
msgstr ""
@@ -31172,6 +31833,9 @@ msgstr ""
msgid "Runners|stale"
msgstr ""
+msgid "Runner|This runner has not run any jobs."
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -31286,6 +31950,24 @@ msgstr ""
msgid "Saving project."
msgstr ""
+msgid "ScanResultPolicy|%{ifLabelStart}if%{ifLabelEnd} %{scanners} scan in an open merge request targeting the %{branches} branch(es) finds %{vulnerabilitiesAllowed} or more %{severities} vulnerabilities that are %{vulnerabilityStates}"
+msgstr ""
+
+msgid "ScanResultPolicy|%{thenLabelStart}Then%{thenLabelEnd} Require approval from %{approvalsRequired} of the following approvers: %{approvers}"
+msgstr ""
+
+msgid "ScanResultPolicy|add an approver"
+msgstr ""
+
+msgid "ScanResultPolicy|scanners"
+msgstr ""
+
+msgid "ScanResultPolicy|severity levels"
+msgstr ""
+
+msgid "ScanResultPolicy|vulnerability states"
+msgstr ""
+
msgid "Scanner"
msgstr ""
@@ -31418,6 +32100,9 @@ msgstr ""
msgid "Search for a user"
msgstr ""
+msgid "Search for an emoji"
+msgstr ""
+
msgid "Search for projects, issues, etc."
msgstr ""
@@ -31605,18 +32290,12 @@ msgstr ""
msgid "Secret Detection"
msgstr ""
-msgid "Secret access key"
-msgstr ""
-
msgid "Secret token"
msgstr ""
msgid "Secure token that identifies an external storage request."
msgstr ""
-msgid "SecureCodeWarrior"
-msgstr ""
-
msgid "Security"
msgstr ""
@@ -31641,9 +32320,6 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "Security training with guide and learning pathways."
-msgstr ""
-
msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
@@ -31746,7 +32422,7 @@ msgstr ""
msgid "SecurityConfiguration|Manage corpus"
msgstr ""
-msgid "SecurityConfiguration|Manage corpus files used as mutation sources in coverage fuzzing."
+msgid "SecurityConfiguration|Manage corpus files used as seed inputs with coverage-guided fuzzing."
msgstr ""
msgid "SecurityConfiguration|Manage profiles for use by DAST scans."
@@ -31812,15 +32488,15 @@ msgstr ""
msgid "SecurityOrchestration|.yaml preview"
msgstr ""
-msgid "SecurityOrchestration|Action"
-msgstr ""
-
msgid "SecurityOrchestration|Actions"
msgstr ""
msgid "SecurityOrchestration|Add rule"
msgstr ""
+msgid "SecurityOrchestration|After dismissing the alert, the information will never be shown again."
+msgstr ""
+
msgid "SecurityOrchestration|All policies"
msgstr ""
@@ -31836,7 +32512,7 @@ msgstr ""
msgid "SecurityOrchestration|Description"
msgstr ""
-msgid "SecurityOrchestration|Disabled"
+msgid "SecurityOrchestration|Don't show the alert anymore"
msgstr ""
msgid "SecurityOrchestration|Edit policy"
@@ -31845,13 +32521,13 @@ msgstr ""
msgid "SecurityOrchestration|Edit policy project"
msgstr ""
-msgid "SecurityOrchestration|Enabled"
+msgid "SecurityOrchestration|Empty policy name"
msgstr ""
-msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Enabled"
msgstr ""
-msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
msgstr ""
msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
@@ -31860,7 +32536,7 @@ msgstr ""
msgid "SecurityOrchestration|Invalid policy type"
msgstr ""
-msgid "SecurityOrchestration|Latest scan"
+msgid "SecurityOrchestration|Latest scan run against %{agent}"
msgstr ""
msgid "SecurityOrchestration|Network"
@@ -31869,15 +32545,27 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No actions defined - policy will not run."
+msgstr ""
+
+msgid "SecurityOrchestration|No description"
+msgstr ""
+
msgid "SecurityOrchestration|No rules defined - policy will not run."
msgstr ""
+msgid "SecurityOrchestration|Not enabled"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
msgid "SecurityOrchestration|Policies"
msgstr ""
+msgid "SecurityOrchestration|Policy Type"
+msgstr ""
+
msgid "SecurityOrchestration|Policy cannot be enabled for non-existing branches (%{branches})"
msgstr ""
@@ -31902,10 +32590,13 @@ msgstr ""
msgid "SecurityOrchestration|Require %{approvals} %{plural} from %{approvers} if any of the following occur:"
msgstr ""
-msgid "SecurityOrchestration|Rule"
+msgid "SecurityOrchestration|Rules"
msgstr ""
-msgid "SecurityOrchestration|Rules"
+msgid "SecurityOrchestration|Runs %{actions} and %{lastAction} scans"
+msgstr ""
+
+msgid "SecurityOrchestration|Runs a %{action} scan"
msgstr ""
msgid "SecurityOrchestration|Scan Execution"
@@ -31965,6 +32656,9 @@ msgstr ""
msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
+msgid "SecurityOrchestration|This view only shows scan results for the agent %{agent}. You can view scan results for all agents in the %{linkStart}Operational Vulnerabilities tab of the vulnerability report%{linkEnd}."
+msgstr ""
+
msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
@@ -32019,9 +32713,6 @@ msgstr ""
msgid "SecurityOrchestration|users with ids"
msgstr ""
-msgid "SecurityOrchestration|view results"
-msgstr ""
-
msgid "SecurityOrchestration|vulnerabilities"
msgstr ""
@@ -32691,22 +33382,19 @@ 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|In order to start using functions as a service, you must first install Knative on your Kubernetes cluster. %{linkStart}More information%{linkEnd}"
-msgstr ""
-
msgid "Serverless|Learn more about Serverless"
msgstr ""
msgid "Serverless|No functions available"
msgstr ""
-msgid "Serverless|Sign up for First Look"
+msgid "Serverless|Serverless was %{linkStart}deprecated%{linkEnd} in GitLab 14.3."
+msgstr ""
+
+msgid "Serverless|Serverless was %{postLinkStart}deprecated%{postLinkEnd}. But if you opt to use it, you must install Knative in your Kubernetes cluster first. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "Serverless|The deploy job has not finished."
@@ -32718,9 +33406,6 @@ 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 ""
@@ -32736,9 +33421,6 @@ msgstr ""
msgid "Service Account Key"
msgstr ""
-msgid "Service Accounts"
-msgstr ""
-
msgid "Service Accounts keys authorize GitLab to deploy your Google Cloud project"
msgstr ""
@@ -32748,10 +33430,10 @@ msgstr ""
msgid "Service Desk allows people to create issues in your GitLab instance without their own user account. It provides a unique email address for end users to create issues in a project. Replies can be sent either through the GitLab interface or by email. End users only see threads through email."
msgstr ""
-msgid "Service Usage Data"
+msgid "Service account generated successfully"
msgstr ""
-msgid "Service account generated successfully"
+msgid "Service accounts"
msgstr ""
msgid "Service ping is disabled in your configuration file, and cannot be enabled through this form."
@@ -32895,6 +33577,9 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
+msgid "Set the per-user rate limit for getting a user by ID via the API."
+msgstr ""
+
msgid "Set the per-user rate limit for notes created by web or API requests."
msgstr ""
@@ -33074,6 +33759,9 @@ msgstr ""
msgid "Shared runners details"
msgstr ""
+msgid "Shared runners enabled cannot be enabled until a valid credit card is on file"
+msgstr ""
+
msgid "Shared runners help link"
msgstr ""
@@ -33131,6 +33819,9 @@ msgstr ""
msgid "Show all issues."
msgstr ""
+msgid "Show all milestones"
+msgstr ""
+
msgid "Show all test cases."
msgstr ""
@@ -33167,6 +33858,9 @@ msgstr ""
msgid "Show file contents"
msgstr ""
+msgid "Show group milestones"
+msgstr ""
+
msgid "Show labels"
msgstr ""
@@ -33182,6 +33876,12 @@ msgstr ""
msgid "Show open epics"
msgstr ""
+msgid "Show project milestones"
+msgstr ""
+
+msgid "Show sub-group milestones"
+msgstr ""
+
msgid "Show the Closed list"
msgstr ""
@@ -33191,11 +33891,6 @@ msgstr ""
msgid "Show whitespace changes"
msgstr ""
-msgid "Showing %d event"
-msgid_plural "Showing %d events"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Showing %{conflict} between %{sourceBranch} and %{targetBranch}"
msgstr ""
@@ -33255,12 +33950,6 @@ msgstr ""
msgid "Sidebar|None"
msgstr ""
-msgid "Sidebar|Only numeral characters allowed"
-msgstr ""
-
-msgid "Sidebar|Weight"
-msgstr ""
-
msgid "Sidekiq job compression threshold (bytes)"
msgstr ""
@@ -33423,6 +34112,9 @@ msgstr ""
msgid "Slack logo"
msgstr ""
+msgid "SlackIntegration|Are you sure you want to remove this project from the Slack application?"
+msgstr ""
+
msgid "SlackIntegration|GitLab for Slack"
msgstr ""
@@ -33432,6 +34124,9 @@ msgstr ""
msgid "SlackIntegration|Project alias"
msgstr ""
+msgid "SlackIntegration|Remove project"
+msgstr ""
+
msgid "SlackIntegration|Select a GitLab project to link with your Slack workspace."
msgstr ""
@@ -33576,9 +34271,6 @@ msgstr ""
msgid "Something went wrong trying to load issue contacts."
msgstr ""
-msgid "Something went wrong when creating a work item. Please try again"
-msgstr ""
-
msgid "Something went wrong when reordering designs. Please try again"
msgstr ""
@@ -33672,9 +34364,6 @@ msgstr ""
msgid "Something went wrong while inserting your image. Please try again."
msgstr ""
-msgid "Something went wrong while merging this merge request. Please try again."
-msgstr ""
-
msgid "Something went wrong while obtaining the Let's Encrypt certificate."
msgstr ""
@@ -33996,10 +34685,10 @@ 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."
+msgid "SourcegraphAdmin|Learn more."
msgstr ""
-msgid "SourcegraphAdmin|More information"
+msgid "SourcegraphAdmin|Only public projects have code intelligence enabled and communicate with Sourcegraph."
msgstr ""
msgid "SourcegraphAdmin|Save changes"
@@ -34008,7 +34697,7 @@ msgstr ""
msgid "SourcegraphAdmin|Sourcegraph URL"
msgstr ""
-msgid "SourcegraphAdmin|e.g. https://sourcegraph.example.com"
+msgid "SourcegraphAdmin|https://sourcegraph.example.com"
msgstr ""
msgid "SourcegraphPreferences|This feature is experimental and currently limited to certain projects."
@@ -34143,6 +34832,9 @@ msgstr ""
msgid "Start date"
msgstr ""
+msgid "Start free trial"
+msgstr ""
+
msgid "Start merge train"
msgstr ""
@@ -34173,6 +34865,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started escalation for this incident."
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -34185,6 +34880,9 @@ msgstr ""
msgid "Starts at (UTC)"
msgstr ""
+msgid "Starts escalations for this incident"
+msgstr ""
+
msgid "Starts on"
msgstr ""
@@ -34446,6 +35144,9 @@ msgstr ""
msgid "Strikethrough"
msgstr ""
+msgid "Strikethrough text"
+msgstr ""
+
msgid "Subgroup information"
msgstr ""
@@ -34680,6 +35381,21 @@ msgstr ""
msgid "Subscriptions"
msgstr ""
+msgid "Subscriptions|Chat with sales"
+msgstr ""
+
+msgid "Subscriptions|Close"
+msgstr ""
+
+msgid "Subscriptions|Not ready to buy yet?"
+msgstr ""
+
+msgid "Subscriptions|Start a free trial"
+msgstr ""
+
+msgid "Subscriptions|We understand. Maybe you have some questions for our sales team, or maybe you'd like to try some of the paid features first. What would you like to do?"
+msgstr ""
+
msgid "Subscription|Your subscription for %{strong}%{namespace_name}%{strong_close} has expired and you are now on %{pricing_link_start}the GitLab Free tier%{pricing_link_end}. Don't worry, your data is safe. Get in touch with our support team (%{support_email}). They'll gladly help with your subscription renewal."
msgstr ""
@@ -34890,6 +35606,9 @@ msgstr ""
msgid "SuperSonics|Maximum users"
msgstr ""
+msgid "SuperSonics|Offline cloud"
+msgstr ""
+
msgid "SuperSonics|Paste your activation code"
msgstr ""
@@ -34956,6 +35675,12 @@ msgstr ""
msgid "SuperSonics|You do not have an active subscription"
msgstr ""
+msgid "SuperSonics|You have a future dated license"
+msgstr ""
+
+msgid "SuperSonics|You have added a license that activates on %{date}. Please see the subscription history table below for more details."
+msgstr ""
+
msgid "SuperSonics|You have successfully added a license that activates on %{date}. Please see the subscription history table below for more details."
msgstr ""
@@ -35115,6 +35840,9 @@ msgstr ""
msgid "Tag name is required"
msgstr ""
+msgid "Tag push"
+msgstr ""
+
msgid "Tag push events"
msgstr ""
@@ -35217,6 +35945,9 @@ msgstr ""
msgid "TagsPage|protected"
msgstr ""
+msgid "Take a look at the documentation to discover all of GitLab’s capabilities."
+msgstr ""
+
msgid "Target Branch"
msgstr ""
@@ -35619,6 +36350,9 @@ msgstr ""
msgid "Tests"
msgstr ""
+msgid "Text (optional)"
+msgstr ""
+
msgid "Text added to the body of all email messages. %{character_limit} character limit"
msgstr ""
@@ -35669,6 +36403,9 @@ msgstr ""
msgid "The CSV export will be created in the background. Once finished, it will be sent to %{email} in an attachment."
msgstr ""
+msgid "The CSV export you requested of all user memberships is attached to this email."
+msgstr ""
+
msgid "The GitLab subscription service (customers.gitlab.com) is currently experiencing an outage. You can monitor the status and get updates at %{linkStart}status.gitlab.com%{linkEnd}."
msgstr ""
@@ -35744,6 +36481,9 @@ 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 epic"
+msgstr ""
+
msgid "The current issue"
msgstr ""
@@ -35905,6 +36645,9 @@ msgstr ""
msgid "The latest pipeline for this merge request has failed."
msgstr ""
+msgid "The license key is invalid."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -35920,6 +36663,9 @@ msgstr ""
msgid "The license was successfully uploaded and will be active from %{starts_at}. You can see the details below."
msgstr ""
+msgid "The license you uploaded is invalid. If the issue persists, contact support at %{link}."
+msgstr ""
+
msgid "The list creation wizard is already open"
msgstr ""
@@ -36541,10 +37287,13 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} and everything this project contains. %{strongOpen}There is no going back%{strongClose}"
+msgstr ""
+
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains."
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}on %{date}%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains. %{strongOpen}There is no going back.%{strongClose}"
msgstr ""
msgid "This action will %{strongOpen}permanently remove%{strongClose} %{codeOpen}%{group}%{codeClose} %{strongOpen}immediately%{strongClose}."
@@ -36673,9 +37422,6 @@ msgstr ""
msgid "This file was modified for readability, and can't accept suggestions. Edit it directly."
msgstr ""
-msgid "This forked project has the following:"
-msgstr ""
-
msgid "This form is disabled in preview"
msgstr ""
@@ -36688,7 +37434,7 @@ msgstr ""
msgid "This group can't be removed because it is linked to a subscription. To remove this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
-msgid "This group can't be transfered because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
+msgid "This group can't be transferred because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
msgid "This group cannot be invited to a project inside a group with enforced SSO"
@@ -36715,6 +37461,9 @@ 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 incident is already escalated with '%{escalation_policy_name}'."
+msgstr ""
+
msgid "This invitation was sent to %{mail_to_invite_email}, but you are signed in as %{link_to_current_user} with email %{mail_to_current_user}."
msgstr ""
@@ -36733,9 +37482,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 merge train pipeline"
-msgstr ""
-
msgid "This is a private email address %{helpIcon} generated just for you. Anyone who has it can create issues or merge requests as if they were you. If that happens, %{resetLinkStart}reset this token%{resetLinkEnd}."
msgstr ""
@@ -36757,6 +37503,12 @@ msgstr ""
msgid "This is your current session"
msgstr ""
+msgid "This issue cannot be assigned to a confidential epic because it is public."
+msgstr ""
+
+msgid "This issue cannot be made public because it belongs to a confidential epic."
+msgstr ""
+
msgid "This issue is confidential and should only be visible to team members with at least Reporter access."
msgstr ""
@@ -36874,6 +37626,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 branch is protected from force push."
+msgstr ""
+
msgid "This merge request cannot be rebased while there are conflicts."
msgstr ""
@@ -36925,9 +37680,15 @@ msgstr ""
msgid "This pipeline was triggered by a schedule."
msgstr ""
+msgid "This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project"
msgstr ""
+msgid "This project can be restored until %{date}."
+msgstr ""
+
msgid "This project cannot be %{visibilityLevel} because the visibility of %{openShowLink}%{name}%{closeShowLink} is %{visibility}. To make this project %{visibilityLevel}, you must first %{openEditLink}change the visibility%{closeEditLink} of the parent group."
msgstr ""
@@ -36946,6 +37707,9 @@ msgstr ""
msgid "This project is %{strongStart}NOT%{strongEnd} a fork, and has the following:"
msgstr ""
+msgid "This project is %{strongStart}NOT%{strongEnd} a fork. This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -37637,6 +38401,9 @@ msgstr ""
msgid "Today"
msgstr ""
+msgid "Todos count"
+msgstr ""
+
msgid "Todos|Are you looking for things to do? Take a look at %{strongStart}%{openIssuesLinkStart}open issues%{openIssuesLinkEnd}%{strongEnd}, contribute to %{strongStart}%{mergeRequestLinkStart}a merge request%{mergeRequestLinkEnd}%{mergeRequestLinkEnd}%{strongEnd}, or mention someone in a comment to automatically assign them a new to-do item."
msgstr ""
@@ -37910,10 +38677,8 @@ msgstr ""
msgid "Trending"
msgstr ""
-msgid "Trials|%{planName} Trial %{enDash} %{num} day left"
-msgid_plural "Trials|%{planName} Trial %{enDash} %{num} days left"
-msgstr[0] ""
-msgstr[1] ""
+msgid "Trials|%{planName} Trial"
+msgstr ""
msgid "Trials|Compare all plans"
msgstr ""
@@ -37921,6 +38686,9 @@ msgstr ""
msgid "Trials|Create a new group to start your GitLab Ultimate trial."
msgstr ""
+msgid "Trials|Day %{daysUsed}/%{duration}"
+msgstr ""
+
msgid "Trials|Go back to GitLab"
msgstr ""
@@ -38170,7 +38938,7 @@ msgstr ""
msgid "URL is triggered when repository is updated"
msgstr ""
-msgid "URL must be percent-encoded if neccessary."
+msgid "URL must be percent-encoded if necessary."
msgstr ""
msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
@@ -38389,6 +39157,9 @@ msgstr ""
msgid "Unlock account"
msgstr ""
+msgid "Unlock more features with GitLab Ultimate"
+msgstr ""
+
msgid "Unlock the discussion"
msgstr ""
@@ -38452,6 +39223,9 @@ msgstr ""
msgid "Unsubscribes from this %{quick_action_target}."
msgstr ""
+msgid "Unsupported sort value."
+msgstr ""
+
msgid "Unsupported todo type passed. Supported todo types are: %{todo_types}"
msgstr ""
@@ -38680,6 +39454,9 @@ msgstr ""
msgid "UsageQuota|File attachments and smaller design graphics."
msgstr ""
+msgid "UsageQuota|From %{storage_enforcement_date} storage limits will apply to this namespace. View and manage your usage in %{strong_start}Group Settings &gt; Usage quotas%{strong_end}."
+msgstr ""
+
msgid "UsageQuota|Git repository."
msgstr ""
@@ -38740,6 +39517,9 @@ msgstr ""
msgid "UsageQuota|Storage type"
msgstr ""
+msgid "UsageQuota|Storage used"
+msgstr ""
+
msgid "UsageQuota|This is the total amount of storage used across your projects within this namespace."
msgstr ""
@@ -38935,6 +39715,12 @@ msgstr ""
msgid "Use hashed storage paths for newly created and renamed repositories. Always enabled since 13.0."
msgstr ""
+msgid "Use issue count"
+msgstr ""
+
+msgid "Use issue weight"
+msgstr ""
+
msgid "Use one line per URI"
msgstr ""
@@ -39316,6 +40102,9 @@ msgstr ""
msgid "Users"
msgstr ""
+msgid "Users API rate limit"
+msgstr ""
+
msgid "Users can launch a development environment from a GitLab browser tab when the %{linkStart}Gitpod%{linkEnd} integration is enabled."
msgstr ""
@@ -39641,6 +40430,9 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View group pipeline usage quota"
+msgstr ""
+
msgid "View incident details at"
msgstr ""
@@ -39793,6 +40585,9 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
+msgid "Vulnerability"
+msgstr ""
+
msgid "Vulnerability Report"
msgstr ""
@@ -39844,6 +40639,9 @@ msgstr ""
msgid "VulnerabilityManagement|An unverified non-confirmed finding"
msgstr ""
+msgid "VulnerabilityManagement|At least one identifier is required"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -39853,12 +40651,24 @@ msgstr ""
msgid "VulnerabilityManagement|Create Jira issue"
msgstr ""
+msgid "VulnerabilityManagement|Enter a name"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE code"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE identifier URL"
+msgstr ""
+
msgid "VulnerabilityManagement|Fetching linked Jira issues"
msgstr ""
msgid "VulnerabilityManagement|Manually add a vulnerability entry into the vulnerability report."
msgstr ""
+msgid "VulnerabilityManagement|Name is a required field"
+msgstr ""
+
msgid "VulnerabilityManagement|Needs triage"
msgstr ""
@@ -39874,6 +40684,18 @@ msgstr ""
msgid "VulnerabilityManagement|Select a method"
msgstr ""
+msgid "VulnerabilityManagement|Select a severity level"
+msgstr ""
+
+msgid "VulnerabilityManagement|Select a status"
+msgstr ""
+
+msgid "VulnerabilityManagement|Severity is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Something went wrong while creating vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -39898,6 +40720,12 @@ msgstr ""
msgid "VulnerabilityManagement|Something went wrong, could not update vulnerability state."
msgstr ""
+msgid "VulnerabilityManagement|Status is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Submit vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Summary, detailed description, steps to reproduce, etc."
msgstr ""
@@ -40093,6 +40921,9 @@ msgstr ""
msgid "WARNING:"
msgstr ""
+msgid "WARNING: This snippet contains hidden files which might be used to mask malicious behavior. Exercise caution if cloning and executing code from this snippet."
+msgstr ""
+
msgid "Wait for the file to load to copy its contents"
msgstr ""
@@ -40312,6 +41143,15 @@ msgstr ""
msgid "Webhooks|An issue is created, updated, closed, or reopened."
msgstr ""
+msgid "Webhooks|Are you sure you want to delete this group hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this project hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this webhook?"
+msgstr ""
+
msgid "Webhooks|Comments"
msgstr ""
@@ -40321,6 +41161,9 @@ msgstr ""
msgid "Webhooks|Confidential issues events"
msgstr ""
+msgid "Webhooks|Delete webhook"
+msgstr ""
+
msgid "Webhooks|Deployment events"
msgstr ""
@@ -40554,6 +41397,9 @@ msgstr ""
msgid "Wiki"
msgstr ""
+msgid "Wiki page"
+msgstr ""
+
msgid "Wiki page was successfully created."
msgstr ""
@@ -40659,7 +41505,7 @@ msgstr ""
msgid "WikiPageConflictMessage|Someone edited the page the same time you did. Please check out %{wikiLinkStart}the page%{wikiLinkEnd} and make sure your changes will not unintentionally remove theirs."
msgstr ""
-msgid "WikiPage|An error occured while trying to render the content editor. Please try again later."
+msgid "WikiPage|An error occurred while trying to render the content editor. Please try again later."
msgstr ""
msgid "WikiPage|Are you sure you want to switch back to the classic editor?"
@@ -40818,6 +41664,18 @@ msgstr ""
msgid "WorkItem|New Task"
msgstr ""
+msgid "WorkItem|Something went wrong when creating a work item. Please try again"
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching the work item. Please try again."
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching work item types. Please try again"
+msgstr ""
+
+msgid "WorkItem|Type"
+msgstr ""
+
msgid "WorkItem|Work Items"
msgstr ""
@@ -40884,7 +41742,10 @@ msgstr ""
msgid "You are about to add %{usersTag} people to the discussion. They will all receive a notification."
msgstr ""
-msgid "You are about to permanently delete this project"
+msgid "You are about to delete this forked project containing:"
+msgstr ""
+
+msgid "You are about to delete this project containing:"
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."
@@ -40905,6 +41766,9 @@ msgstr ""
msgid "You are attempting to update a file that has changed since you started editing it."
msgstr ""
+msgid "You are billed if you exceed this number. %{qsrOverageLinkStart}How does billing work?%{qsrOverageLinkEnd}"
+msgstr ""
+
msgid "You are connected to the Prometheus server, but there is currently no data to display."
msgstr ""
@@ -40962,6 +41826,9 @@ msgstr ""
msgid "You are not authorized to update this scanner profile"
msgstr ""
+msgid "You are not authorized to upload metric images"
+msgstr ""
+
msgid "You are now impersonating %{username}"
msgstr ""
@@ -41115,9 +41982,6 @@ msgstr ""
msgid "You can only upload one design when dropping onto an existing design."
msgstr ""
-msgid "You can recover this project until %{date}"
-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 ""
@@ -41166,9 +42030,6 @@ msgstr ""
msgid "You cannot write to this read-only GitLab instance."
msgstr ""
-msgid "You can’t %{tag_start}edit%{tag_end} files directly in this project. Fork this project and submit a merge request with your changes."
-msgstr ""
-
msgid "You can’t edit files directly in this project. Fork this project and submit a merge request with your changes."
msgstr ""
@@ -41321,9 +42182,6 @@ 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 set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
@@ -41354,12 +42212,6 @@ msgstr ""
msgid "You must have maintainer access to force delete a lock"
msgstr ""
-msgid "You must have permission to create a project in a group before forking."
-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 ""
@@ -41765,7 +42617,7 @@ msgstr ""
msgid "Your public email will be displayed on your public profile."
msgstr ""
-msgid "Your request for access could not be processed: %{error_meesage}"
+msgid "Your request for access could not be processed: %{error_message}"
msgstr ""
msgid "Your request for access has been queued for review."
@@ -41948,6 +42800,9 @@ msgstr ""
msgid "archived:"
msgstr ""
+msgid "artifacts"
+msgstr ""
+
msgid "assign yourself"
msgstr ""
@@ -41977,6 +42832,9 @@ msgstr[1] ""
msgid "branch name"
msgstr ""
+msgid "builds"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -42400,6 +43258,9 @@ msgstr ""
msgid "contact with same email already exists in group hierarchy"
msgstr ""
+msgid "container registry images"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -42439,6 +43300,9 @@ msgstr ""
msgid "data"
msgstr ""
+msgid "database"
+msgstr ""
+
msgid "date must not be after 9999-12-31"
msgstr ""
@@ -42462,9 +43326,6 @@ msgstr ""
msgid "design"
msgstr ""
-msgid "detached"
-msgstr ""
-
msgid "disabled"
msgstr ""
@@ -42713,7 +43574,7 @@ msgstr ""
msgid "is not a valid X509 certificate."
msgstr ""
-msgid "is not allowed for sign-up."
+msgid "is not allowed for sign-up. Please use your regular email address."
msgstr ""
msgid "is not allowed for this group."
@@ -42725,7 +43586,7 @@ msgstr ""
msgid "is not allowed since the group is not top-level group."
msgstr ""
-msgid "is not allowed."
+msgid "is not allowed. Please use your regular email address."
msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
@@ -42812,6 +43673,9 @@ msgstr ""
msgid "level: %{level}"
msgstr ""
+msgid "lfs objects"
+msgstr ""
+
msgid "limit of %{project_limit} reached"
msgstr ""
@@ -43031,6 +43895,9 @@ msgstr ""
msgid "mrWidget|Merge blocked: pipeline must succeed. It's waiting for a manual action to continue."
msgstr ""
+msgid "mrWidget|Merge blocked: pipeline must succeed. Push a commit that fixes the failure, or %{linkStart}learn about other solutions.%{linkEnd}"
+msgstr ""
+
msgid "mrWidget|Merge blocked: this merge request must be approved."
msgstr ""
@@ -43148,9 +44015,6 @@ msgstr ""
msgid "mrWidget|The changes were not merged into"
msgstr ""
-msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -43298,9 +44162,6 @@ msgstr ""
msgid "open issue"
msgstr ""
-msgid "opened %{timeAgo}"
-msgstr ""
-
msgid "or"
msgstr ""
@@ -43312,6 +44173,12 @@ msgid_plural "out of %d total tests"
msgstr[0] ""
msgstr[1] ""
+msgid "packages"
+msgstr ""
+
+msgid "pages"
+msgstr ""
+
msgid "parent"
msgid_plural "parents"
msgstr[0] ""
@@ -43461,6 +44328,9 @@ msgid_plural "replies"
msgstr[0] ""
msgstr[1] ""
+msgid "repositories"
+msgstr ""
+
msgid "repository:"
msgstr ""
@@ -43581,12 +44451,18 @@ msgstr ""
msgid "tag name"
msgstr ""
+msgid "terraform states"
+msgstr ""
+
msgid "the correct format."
msgstr ""
msgid "the file"
msgstr ""
+msgid "the following epic(s)"
+msgstr ""
+
msgid "the following issue(s)"
msgstr ""
@@ -43599,21 +44475,12 @@ msgstr ""
msgid "this document"
msgstr ""
-msgid "this issue cannot be assigned to a confidential epic since it is public"
-msgstr ""
-
-msgid "this issue cannot be made public since it belongs to a confidential epic"
-msgstr ""
-
msgid "time summary"
msgstr ""
msgid "toggle collapse"
msgstr ""
-msgid "train"
-msgstr ""
-
msgid "triggered"
msgstr ""
@@ -43742,3 +44609,6 @@ msgstr ""
msgid "{project}"
msgstr ""
+msgid "✔"
+msgstr ""
+
diff --git a/locale/mn_MN/gitlab.po b/locale/mn_MN/gitlab.po
index ec1d1e69b95..83c3063b6fb 100644
--- a/locale/mn_MN/gitlab.po
+++ b/locale/mn_MN/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: mn\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2022-02-02 15:46\n"
+"PO-Revision-Date: 2022-03-01 20:39\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -146,6 +146,11 @@ msgid_plural "%d approvers (you've approved)"
msgstr[0] ""
msgstr[1] ""
+msgid "%d assigned issue"
+msgid_plural "%d assigned issues"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -421,8 +426,23 @@ msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
msgstr[1] ""
-msgid "%d vulnerability updated"
-msgid_plural "%d vulnerabilities updated"
+msgid "%d vulnerability set to confirmed"
+msgid_plural "%d vulnerabilities set to confirmed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to dismissed"
+msgid_plural "%d vulnerabilities set to dismissed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to needs triage"
+msgid_plural "%d vulnerabilities set to needs triage"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to resolved"
+msgid_plural "%d vulnerabilities set to resolved"
msgstr[0] ""
msgstr[1] ""
@@ -510,6 +530,12 @@ msgstr[1] ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{completed} of %{total} issues closed"
+msgstr ""
+
+msgid "%{completed} of %{total} weight completed"
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -858,6 +884,9 @@ msgstr ""
msgid "%{openedIssues} open, %{closedIssues} closed"
msgstr ""
+msgid "%{percentage}%% issues closed"
+msgstr ""
+
msgid "%{percentage}%% weight completed"
msgstr ""
@@ -1287,6 +1316,9 @@ msgid_plural "- Users"
msgstr[0] ""
msgstr[1] ""
+msgid "- of - issues closed"
+msgstr ""
+
msgid "- of - weight completed"
msgstr ""
@@ -1429,7 +1461,7 @@ msgstr ""
msgid "1000+"
msgstr ""
-msgid "192.168.0.0/24"
+msgid "192.168.0.0/24 or 2001:0DB8:1234::/48"
msgstr ""
msgid "1st contribution!"
@@ -1741,13 +1773,13 @@ msgstr ""
msgid "AWS Access Key"
msgstr ""
-msgid "AWS Access Key. Only required if not using role instance credentials"
+msgid "AWS Secret Access Key"
msgstr ""
-msgid "AWS Secret Access Key"
+msgid "AWS access key ID (Optional)"
msgstr ""
-msgid "AWS Secret Access Key. Only required if not using role instance credentials"
+msgid "AWS secret access key (Optional)"
msgstr ""
msgid "AWS service error: %{error}"
@@ -1807,9 +1839,6 @@ msgstr ""
msgid "Access granted"
msgstr ""
-msgid "Access key ID"
-msgstr ""
-
msgid "Access requests"
msgstr ""
@@ -1984,7 +2013,7 @@ msgstr ""
msgid "Activity"
msgstr ""
-msgid "Activity|An error occured while retrieving activity. Reload the page to try again."
+msgid "Activity|An error occurred while retrieving activity. Reload the page to try again."
msgstr ""
msgid "Add"
@@ -2023,6 +2052,9 @@ msgstr ""
msgid "Add a %{type}"
msgstr ""
+msgid "Add a GCP region"
+msgstr ""
+
msgid "Add a GPG key"
msgstr ""
@@ -2074,6 +2106,9 @@ msgstr ""
msgid "Add a numbered list"
msgstr ""
+msgid "Add a related epic"
+msgstr ""
+
msgid "Add a related issue"
msgstr ""
@@ -2188,6 +2223,9 @@ msgstr ""
msgid "Add or subtract spent time"
msgstr ""
+msgid "Add people"
+msgstr ""
+
msgid "Add previously merged commits"
msgstr ""
@@ -2254,6 +2292,9 @@ msgstr ""
msgid "Add webhook"
msgstr ""
+msgid "Add your team members and others to GitLab."
+msgstr ""
+
msgid "Add/remove"
msgstr ""
@@ -3076,12 +3117,6 @@ msgstr ""
msgid "AdvancedSearch|Reindex required"
msgstr ""
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. Permanently deleting this project will %{strongStart}immediately delete%{strongEnd} its repositories and %{strongStart}all related resources%{strongEnd}, including issues, merge requests etc."
-msgstr ""
-
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. You will lose this project's repository and %{strongStart}all related resources%{strongEnd}, including issues and merge requests."
-msgstr ""
-
msgid "After a successful password update you will be redirected to login screen."
msgstr ""
@@ -3112,6 +3147,9 @@ msgstr ""
msgid "Akismet helps prevent the creation of spam issues in public projects."
msgstr ""
+msgid "Alert"
+msgstr ""
+
msgid "AlertManagement|Acknowledged"
msgstr ""
@@ -3484,9 +3522,6 @@ msgstr ""
msgid "All environments"
msgstr ""
-msgid "All epics"
-msgstr ""
-
msgid "All groups and projects"
msgstr ""
@@ -4223,12 +4258,15 @@ msgstr ""
msgid "ApplicationSettings|Approve users in the pending approval status?"
msgstr ""
-msgid "ApplicationSettings|By making this change, you will automatically approve %d user with the pending approval status."
-msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users with the pending approval status."
+msgid "ApplicationSettings|Approve users who are pending approval?"
+msgstr ""
+
+msgid "ApplicationSettings|By making this change, you will automatically approve %d user who is pending approval."
+msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users who are pending approval."
msgstr[0] ""
msgstr[1] ""
-msgid "ApplicationSettings|By making this change, you will automatically approve all users in pending approval status."
+msgid "ApplicationSettings|By making this change, you will automatically approve all users who are pending approval."
msgstr ""
msgid "ApplicationSettings|Denied domains for sign-ups"
@@ -4634,10 +4672,10 @@ msgstr ""
msgid "Archiving the project will make it entirely read-only. It is hidden from the dashboard and doesn't show up in searches. %{strong_start}The repository cannot be committed to, and no issues, comments, or other entities can be created.%{strong_end} %{link_start}Learn more.%{link_end}"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to delete this project?"
+msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
+msgid "Are you absolutely sure?"
msgstr ""
msgid "Are you sure that you want to archive this project?"
@@ -4673,12 +4711,18 @@ msgstr ""
msgid "Are you sure you want to delete this SSH key?"
msgstr ""
+msgid "Are you sure you want to delete this comment?"
+msgstr ""
+
msgid "Are you sure you want to delete this deploy key?"
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 label?"
+msgstr ""
+
msgid "Are you sure you want to delete this pipeline schedule?"
msgstr ""
@@ -4694,9 +4738,6 @@ msgstr ""
msgid "Are you sure you want to discard your changes?"
msgstr ""
-msgid "Are you sure you want to erase this build?"
-msgstr ""
-
msgid "Are you sure you want to import %d repository?"
msgid_plural "Are you sure you want to import %d repositories?"
msgstr[0] ""
@@ -4744,6 +4785,9 @@ msgstr ""
msgid "Are you sure you want to remove this list?"
msgstr ""
+msgid "Are you sure you want to remove this nickname?"
+msgstr ""
+
msgid "Are you sure you want to reset the health check token?"
msgstr ""
@@ -4756,10 +4800,10 @@ 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?"
+msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
msgstr ""
-msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
+msgid "Are you sure you want to revoke this project access token? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to stop this environment?"
@@ -4906,9 +4950,6 @@ msgstr ""
msgid "Assigned to %{assignee_name}"
msgstr ""
-msgid "Assigned to %{name}"
-msgstr ""
-
msgid "Assigned to me"
msgstr ""
@@ -4973,6 +5014,9 @@ msgstr[1] ""
msgid "Attaching the file failed."
msgstr ""
+msgid "Attention"
+msgstr ""
+
msgid "Audit Events"
msgstr ""
@@ -5135,6 +5179,12 @@ msgstr ""
msgid "Authorized applications (%{size})"
msgstr ""
+msgid "AuthorizedApplication|Are you sure you want to revoke this application?"
+msgstr ""
+
+msgid "AuthorizedApplication|Revoke application"
+msgstr ""
+
msgid "Authors: %{authors}"
msgstr ""
@@ -6328,6 +6378,9 @@ msgstr ""
msgid "CICDAnalytics|Shared Runners Usage"
msgstr ""
+msgid "CICDAnalytics|Shared runner pipeline minute duration by month"
+msgstr ""
+
msgid "CICDAnalytics|Shared runner usage"
msgstr ""
@@ -6469,6 +6522,9 @@ msgstr ""
msgid "Can create groups:"
msgstr ""
+msgid "Can not delete primary training"
+msgstr ""
+
msgid "Can't apply as the source branch was deleted."
msgstr ""
@@ -6802,9 +6858,6 @@ msgstr ""
msgid "Changing any setting here requires an application restart"
msgstr ""
-msgid "Changing group URL can have unintended side effects."
-msgstr ""
-
msgid "Charts can't be displayed as the request for data has timed out. %{documentationLink}"
msgstr ""
@@ -6892,9 +6945,6 @@ msgstr ""
msgid "Checking branch availability..."
msgstr ""
-msgid "Checking group URL availability..."
-msgstr ""
-
msgid "Checking group path availability..."
msgstr ""
@@ -7388,6 +7438,9 @@ msgstr ""
msgid "Clear recent searches"
msgstr ""
+msgid "Clear repository checks"
+msgstr ""
+
msgid "Clear search"
msgstr ""
@@ -7520,9 +7573,6 @@ msgstr ""
msgid "Closed MRs"
msgstr ""
-msgid "Closed epics"
-msgstr ""
-
msgid "Closed issues"
msgstr ""
@@ -7559,13 +7609,13 @@ msgstr ""
msgid "Cluster level"
msgstr ""
-msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
+msgid "Cluster type must be specified for Stages::ClusterEndpointInserter"
msgstr ""
msgid "ClusterAgents|%{name} successfully deleted"
msgstr ""
-msgid "ClusterAgents|%{number} of %{total} Agents"
+msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
@@ -7607,6 +7657,15 @@ msgstr ""
msgid "ClusterAgents|Agent never connected to GitLab"
msgstr ""
+msgid "ClusterAgents|Agent version mismatch"
+msgstr ""
+
+msgid "ClusterAgents|Agent version mismatch and update"
+msgstr ""
+
+msgid "ClusterAgents|Agent version update required"
+msgstr ""
+
msgid "ClusterAgents|All"
msgstr ""
@@ -7631,7 +7690,7 @@ msgstr ""
msgid "ClusterAgents|Configuration"
msgstr ""
-msgid "ClusterAgents|Connect a cluster through the Agent"
+msgid "ClusterAgents|Connect a cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connect existing cluster"
@@ -7640,13 +7699,13 @@ msgstr ""
msgid "ClusterAgents|Connect with a certificate"
msgstr ""
-msgid "ClusterAgents|Connect with agent"
+msgid "ClusterAgents|Connect with an agent"
msgstr ""
msgid "ClusterAgents|Connect with the GitLab Agent"
msgstr ""
-msgid "ClusterAgents|Connect your cluster through the Agent"
+msgid "ClusterAgents|Connect your cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connected"
@@ -7706,7 +7765,10 @@ msgstr ""
msgid "ClusterAgents|How to register an agent?"
msgstr ""
-msgid "ClusterAgents|Install new Agent"
+msgid "ClusterAgents|How to update an agent?"
+msgstr ""
+
+msgid "ClusterAgents|Install a new agent"
msgstr ""
msgid "ClusterAgents|Last connected %{timeAgo}."
@@ -7733,7 +7795,7 @@ msgstr ""
msgid "ClusterAgents|Never connected"
msgstr ""
-msgid "ClusterAgents|No Agents"
+msgid "ClusterAgents|No agents"
msgstr ""
msgid "ClusterAgents|No clusters connected through cluster certificates"
@@ -7793,6 +7855,9 @@ msgstr ""
msgid "ClusterAgents|The agent has not been connected in a long time. There might be a connectivity issue. Last contact was %{timeAgo}."
msgstr ""
+msgid "ClusterAgents|The agent version do not match each other across your cluster's pods. This can happen when a new agent version was just deployed and Kubernetes is shutting down the old pods."
+msgstr ""
+
msgid "ClusterAgents|The recommended installation method includes the token. If you want to follow the advanced installation method provided in the docs, make sure you save the token value before you close this window."
msgstr ""
@@ -7840,6 +7905,9 @@ msgstr ""
msgid "ClusterAgents|You will need to create a token to connect to your agent"
msgstr ""
+msgid "ClusterAgents|Your agent version is out of sync with your GitLab version (v%{version}), which might cause compatibility problems. Update the agent installed on your cluster to the most recent version."
+msgstr ""
+
msgid "ClusterAgents|Your instance doesn't have the %{linkStart}GitLab Agent Server (KAS)%{linkEnd} set up. Ask a GitLab Administrator to install it."
msgstr ""
@@ -8716,9 +8784,6 @@ msgstr ""
msgid "Comma-separated list of email addresses."
msgstr ""
-msgid "Comma-separated list of users allowed to exceed the rate limit."
-msgstr ""
-
msgid "Comma-separated, e.g. '1.1.1.1, 2.2.2.0/24'"
msgstr ""
@@ -9045,6 +9110,12 @@ msgstr ""
msgid "Confidential"
msgstr ""
+msgid "Confidential issue"
+msgstr ""
+
+msgid "Confidential note"
+msgstr ""
+
msgid "Confidentiality"
msgstr ""
@@ -9078,6 +9149,9 @@ msgstr ""
msgid "Configure Dependency Scanning in `.gitlab-ci.yml`, creating this file if it does not already exist"
msgstr ""
+msgid "Configure GitLab"
+msgstr ""
+
msgid "Configure GitLab runners to start using the Web Terminal. %{helpStart}Learn more.%{helpEnd}"
msgstr ""
@@ -9126,6 +9200,15 @@ msgstr ""
msgid "Configure pipelines to deploy web apps, backend services, APIs and static resources to Google Cloud"
msgstr ""
+msgid "Configure region"
+msgstr ""
+
+msgid "Configure region for environment"
+msgstr ""
+
+msgid "Configure regions"
+msgstr ""
+
msgid "Configure repository mirroring."
msgstr ""
@@ -9159,6 +9242,9 @@ msgstr ""
msgid "Configure which lists are shown for anyone who visits this board"
msgstr ""
+msgid "Configure your environments to be deployed to specific geographical regions"
+msgstr ""
+
msgid "Confirm"
msgstr ""
@@ -9861,10 +9947,10 @@ msgstr ""
msgid "CorpusManagement|Actions"
msgstr ""
-msgid "CorpusManagement|Corpus are used in fuzz testing as mutation source to Improve future testing."
+msgid "CorpusManagement|Corpus file"
msgstr ""
-msgid "CorpusManagement|Corpus file"
+msgid "CorpusManagement|Corpus files are used in coverage-guided fuzz testing as seed inputs to improve testing."
msgstr ""
msgid "CorpusManagement|Corpus files must be in *.zip format. Maximum 5 GB"
@@ -9918,6 +10004,9 @@ msgstr ""
msgid "Could not apply %{name} command."
msgstr ""
+msgid "Could not apply %{name} command. %{message}."
+msgstr ""
+
msgid "Could not authorize chat nickname. Try again!"
msgstr ""
@@ -10068,6 +10157,9 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
+msgid "Create a group"
+msgstr ""
+
msgid "Create a merge request"
msgstr ""
@@ -10092,6 +10184,9 @@ msgstr ""
msgid "Create a personal access token on your account to pull or push via %{protocol}."
msgstr ""
+msgid "Create a project"
+msgstr ""
+
msgid "Create an account using:"
msgstr ""
@@ -10455,6 +10550,9 @@ msgstr ""
msgid "Creation date"
msgstr ""
+msgid "Creator"
+msgstr ""
+
msgid "Credentials"
msgstr ""
@@ -10467,9 +10565,15 @@ msgstr ""
msgid "CredentialsInventory|Personal Access Tokens"
msgstr ""
+msgid "CredentialsInventory|Project Access Tokens"
+msgstr ""
+
msgid "CredentialsInventory|SSH Keys"
msgstr ""
+msgid "Credit card required to be on file in order to create a pipeline"
+msgstr ""
+
msgid "Credit card:"
msgstr ""
@@ -10653,9 +10757,6 @@ msgstr ""
msgid "Customer relations"
msgstr ""
-msgid "Customizable by an administrator."
-msgstr ""
-
msgid "Customizable by owners."
msgstr ""
@@ -10785,30 +10886,18 @@ msgstr ""
msgid "CycleAnalytics|%{selectedLabelsCount} selected (%{maxLabels} max)"
msgstr ""
-msgid "CycleAnalytics|%{stageCount} stages selected"
-msgstr ""
-
-msgid "CycleAnalytics|All stages"
-msgstr ""
-
-msgid "CycleAnalytics|Average days to completion"
+msgid "CycleAnalytics|Average time to completion"
msgstr ""
msgid "CycleAnalytics|Date"
msgstr ""
-msgid "CycleAnalytics|Days to completion"
-msgstr ""
-
msgid "CycleAnalytics|Display chart filters"
msgstr ""
msgid "CycleAnalytics|Lead Time for Changes"
msgstr ""
-msgid "CycleAnalytics|No stages selected"
-msgstr ""
-
msgid "CycleAnalytics|Number of tasks"
msgstr ""
@@ -10837,18 +10926,30 @@ msgstr ""
msgid "CycleAnalytics|Showing data for group '%{groupName}' from %{createdAfter} to %{createdBefore}"
msgstr ""
-msgid "CycleAnalytics|Stages"
+msgid "CycleAnalytics|Stage time: %{title}"
msgstr ""
msgid "CycleAnalytics|Tasks by type"
msgstr ""
-msgid "CycleAnalytics|The average time spent in the selected stage for the items that were completed on each date. Data limited to the last 500 items."
+msgid "CycleAnalytics|The average time items spent in this stage. Data limited to items completed within this date range."
msgstr ""
msgid "CycleAnalytics|The given date range is larger than 180 days"
msgstr ""
+msgid "CycleAnalytics|The total time items spent across each value stream stage. Data limited to items completed within this date range."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Stage time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Total time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|Total time"
+msgstr ""
+
msgid "CycleAnalytics|Type of work"
msgstr ""
@@ -10861,9 +10962,6 @@ msgstr ""
msgid "CycleAnalytics|project dropdown filter"
msgstr ""
-msgid "CycleAnalytics|stage dropdown"
-msgstr ""
-
msgid "DAG visualization requires at least 3 dependent jobs."
msgstr ""
@@ -10963,10 +11061,16 @@ msgstr ""
msgid "DastProfiles|AJAX spider"
msgstr ""
+msgid "DastProfiles|API"
+msgstr ""
+
+msgid "DastProfiles|API endpoint URL"
+msgstr ""
+
msgid "DastProfiles|Active"
msgstr ""
-msgid "DastProfiles|Additional request headers (Optional)"
+msgid "DastProfiles|Additional request headers (optional)"
msgstr ""
msgid "DastProfiles|Are you sure you want to delete this profile?"
@@ -10981,6 +11085,9 @@ msgstr ""
msgid "DastProfiles|Branch missing"
msgstr ""
+msgid "DastProfiles|Choose a scan method"
+msgstr ""
+
msgid "DastProfiles|Could not create the scanner profile. Please try again."
msgstr ""
@@ -11050,7 +11157,13 @@ msgstr ""
msgid "DastProfiles|Excluded URLs"
msgstr ""
-msgid "DastProfiles|Excluded URLs (Optional)"
+msgid "DastProfiles|Excluded URLs (optional)"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths (optional)"
msgstr ""
msgid "DastProfiles|Hide debug messages"
@@ -11107,9 +11220,6 @@ msgstr ""
msgid "DastProfiles|Request headers"
msgstr ""
-msgid "DastProfiles|Rest API"
-msgstr ""
-
msgid "DastProfiles|Run the AJAX spider, in addition to the traditional spider, to crawl the target site."
msgstr ""
@@ -11119,6 +11229,9 @@ msgstr ""
msgid "DastProfiles|Save profile"
msgstr ""
+msgid "DastProfiles|Scan method"
+msgstr ""
+
msgid "DastProfiles|Scan mode"
msgstr ""
@@ -11197,12 +11310,24 @@ msgstr ""
msgid "DastProfiles|Website"
msgstr ""
+msgid "DastProfiles|What does each method do?"
+msgstr ""
+
msgid "DastProfiles|You can either choose a passive scan or validate the target site from the site profile management page. %{docsLinkStart}Learn more about site validation.%{docsLinkEnd}"
msgstr ""
msgid "DastProfiles|You cannot run an active scan against an unvalidated site."
msgstr ""
+msgid "DastProfiles|folder/dast_example.har or https://example.com/dast_example.har"
+msgstr ""
+
+msgid "DastProfiles|folder/example.postman_collection.json or https://example.com/"
+msgstr ""
+
+msgid "DastProfiles|folder/openapi.json or https://example.com/openapi.json"
+msgstr ""
+
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
@@ -11310,6 +11435,9 @@ msgstr ""
msgid "DatadogIntegration|API URL"
msgstr ""
+msgid "DatadogIntegration|Custom tags in Datadog. Enter one tag per line in the %{codeOpen}key:value%{codeClose} format. %{linkOpen}How do I use tags?%{linkClose}"
+msgstr ""
+
msgid "DatadogIntegration|Environment"
msgstr ""
@@ -11328,12 +11456,18 @@ msgstr ""
msgid "DatadogIntegration|Tag all data from this GitLab instance in Datadog. Useful when managing several self-managed deployments."
msgstr ""
+msgid "DatadogIntegration|Tags"
+msgstr ""
+
msgid "DatadogIntegration|The Datadog site to send data to. To send data to the EU site, use %{codeOpen}datadoghq.eu%{codeClose}."
msgstr ""
msgid "DatadogIntegration|Trace your GitLab pipelines with Datadog."
msgstr ""
+msgid "DatadogIntegration|have an invalid format"
+msgstr ""
+
msgid "Datasource name not found"
msgstr ""
@@ -11343,9 +11477,6 @@ msgstr ""
msgid "Date merged"
msgstr ""
-msgid "Date picker"
-msgstr ""
-
msgid "Date range"
msgstr ""
@@ -11499,9 +11630,6 @@ msgstr ""
msgid "Definition"
msgstr ""
-msgid "Delayed Project Deletion (%{adjourned_deletion})"
-msgstr ""
-
msgid "DelayedJobs|Are you sure you want to run %{jobName} immediately? Otherwise this job will run automatically after its timer finishes."
msgstr ""
@@ -11580,10 +11708,10 @@ msgstr ""
msgid "Delete pipeline"
msgstr ""
-msgid "Delete project"
+msgid "Delete pipeline schedule"
msgstr ""
-msgid "Delete project. Are you ABSOLUTELY SURE?"
+msgid "Delete project"
msgstr ""
msgid "Delete row"
@@ -11613,6 +11741,9 @@ msgstr ""
msgid "Delete this epic and all descendants?"
msgstr ""
+msgid "Delete this project"
+msgstr ""
+
msgid "Delete user list"
msgstr ""
@@ -11871,6 +12002,12 @@ msgstr ""
msgid "Deploy to..."
msgstr ""
+msgid "DeployBoards|To see deployment progress for your environments, make sure you are deploying to %{codeStart}$KUBE_NAMESPACE%{codeEnd} and annotating with %{codeStart}app.gitlab.com/app=$CI_PROJECT_PATH_SLUG%{codeEnd} and %{codeStart}app.gitlab.com/env=$CI_ENVIRONMENT_SLUG%{codeEnd}."
+msgstr ""
+
+msgid "DeployBoard|Kubernetes Pods"
+msgstr ""
+
msgid "DeployFreeze|Add a freeze period to prevent unintended releases during a period of time for a given environment. You must update the deployment jobs in %{filename} according to the deploy freezes added here. %{freeze_period_link_start}Learn more.%{freeze_period_link_end}"
msgstr ""
@@ -11955,9 +12092,6 @@ msgstr ""
msgid "DeployTokens|Active Deploy Tokens (%{active_tokens})"
msgstr ""
-msgid "DeployTokens|Allows read and write access to registry images."
-msgstr ""
-
msgid "DeployTokens|Allows read and write access to the package registry."
msgstr ""
@@ -11970,6 +12104,9 @@ msgstr ""
msgid "DeployTokens|Allows read-only access to the repository."
msgstr ""
+msgid "DeployTokens|Allows write access to registry images."
+msgstr ""
+
msgid "DeployTokens|Copy deploy token"
msgstr ""
@@ -12063,12 +12200,57 @@ msgstr ""
msgid "Deploying to AWS is easy with GitLab"
msgstr ""
+msgid "Deployment"
+msgstr ""
+
msgid "Deployment Frequency"
msgstr ""
+msgid "Deployment Target|Project deployment target (optional)"
+msgstr ""
+
+msgid "Deployment Target|Select the deployment target"
+msgstr ""
+
msgid "Deployment frequency"
msgstr ""
+msgid "DeploymentTarget|GitLab Pages"
+msgstr ""
+
+msgid "DeploymentTarget|Heroku"
+msgstr ""
+
+msgid "DeploymentTarget|Infrastructure provider (Terraform, Cloudformation, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Kubernetes (GKE, EKS, OpenShift, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Managed container runtime (Fargate, Cloud Run, DigitalOcean App)"
+msgstr ""
+
+msgid "DeploymentTarget|Mobile app store"
+msgstr ""
+
+msgid "DeploymentTarget|No deployment planned"
+msgstr ""
+
+msgid "DeploymentTarget|Other hosting service"
+msgstr ""
+
+msgid "DeploymentTarget|Registry (package or container)"
+msgstr ""
+
+msgid "DeploymentTarget|Self-managed container runtime (Podman, Docker Swarm, Docker Compose)"
+msgstr ""
+
+msgid "DeploymentTarget|Serverless backend (Lambda, Cloud functions)"
+msgstr ""
+
+msgid "DeploymentTarget|Virtual machine (for example, EC2)"
+msgstr ""
+
msgid "Deployments"
msgstr ""
@@ -12107,6 +12289,9 @@ msgstr ""
msgid "Deployment|This deployment was created using the API"
msgstr ""
+msgid "Deployment|Triggerer"
+msgstr ""
+
msgid "Deployment|Waiting"
msgstr ""
@@ -12134,6 +12319,18 @@ msgstr ""
msgid "Deprecated API rate limits"
msgstr ""
+msgid "Deprecations|Feature deprecation and removal"
+msgstr ""
+
+msgid "Deprecations|For information on a possible replacement %{epicStart} learn more about Opstrace %{epicEnd}."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7 and are %{epicStart} scheduled for removal %{epicEnd} in GitLab 15.0."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7, and are %{removal_link_start} scheduled for removal %{link_end} in GitLab 15.0. For information on a possible replacement, %{opstrace_link_start} learn more about Opstrace %{link_end}."
+msgstr ""
+
msgid "Deprioritize label"
msgstr ""
@@ -12379,10 +12576,10 @@ msgstr ""
msgid "DevopsAdoption|At least one deploy"
msgstr ""
-msgid "DevopsAdoption|At least one issue opened"
+msgid "DevopsAdoption|At least one issue created"
msgstr ""
-msgid "DevopsAdoption|At least one merge request opened"
+msgid "DevopsAdoption|At least one merge request created"
msgstr ""
msgid "DevopsAdoption|At least one pipeline successfully run"
@@ -12583,6 +12780,9 @@ msgstr ""
msgid "Direct member"
msgstr ""
+msgid "Direct members"
+msgstr ""
+
msgid "Direct non-authenticated users to this page."
msgstr ""
@@ -12699,6 +12899,9 @@ msgid_plural "Dismiss %d selected vulnerabilities as"
msgstr[0] ""
msgstr[1] ""
+msgid "Dismiss Alert"
+msgstr ""
+
msgid "Dismiss merge request promotion"
msgstr ""
@@ -12726,9 +12929,15 @@ msgstr ""
msgid "Display alerts from all configured monitoring tools."
msgstr ""
+msgid "Display milestones"
+msgstr ""
+
msgid "Display name"
msgstr ""
+msgid "Display progress of child issues"
+msgstr ""
+
msgid "Display rendered file"
msgstr ""
@@ -12834,6 +13043,9 @@ msgstr ""
msgid "Download image"
msgstr ""
+msgid "Download payload"
+msgstr ""
+
msgid "Download raw data (.csv)"
msgstr ""
@@ -13011,6 +13223,9 @@ msgstr ""
msgid "Edit in Web IDE"
msgstr ""
+msgid "Edit in pipeline editor"
+msgstr ""
+
msgid "Edit in single-file editor"
msgstr ""
@@ -13053,6 +13268,9 @@ msgstr ""
msgid "Edit your most recent comment in a thread (from an empty textarea)"
msgstr ""
+msgid "Edit, lint, and visualize your pipeline."
+msgstr ""
+
msgid "Edited"
msgstr ""
@@ -13494,6 +13712,9 @@ msgstr ""
msgid "Enforce two-factor authentication for all user sign-ins."
msgstr ""
+msgid "Enhance security by storing service account keys in secret managers - learn more about %{docLinkStart}secret management with GitLab%{docLinkEnd}"
+msgstr ""
+
msgid "Ensure connectivity is available from the GitLab server to the Prometheus server"
msgstr ""
@@ -13554,6 +13775,9 @@ 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 following to confirm:"
+msgstr ""
+
msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
@@ -14084,9 +14308,6 @@ 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 ""
@@ -14222,6 +14443,9 @@ msgstr ""
msgid "Errors:"
msgstr ""
+msgid "Escalate this incident"
+msgstr ""
+
msgid "Escalation Policies"
msgstr ""
@@ -14234,6 +14458,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy"
+msgstr ""
+
msgid "Escalation policy:"
msgstr ""
@@ -14485,6 +14712,9 @@ msgstr ""
msgid "Existing sign in methods may be removed"
msgstr ""
+msgid "Exit."
+msgstr ""
+
msgid "Expand"
msgstr ""
@@ -14581,6 +14811,9 @@ msgstr ""
msgid "Explore public groups"
msgstr ""
+msgid "Explore public projects"
+msgstr ""
+
msgid "Explore snippets"
msgstr ""
@@ -14742,7 +14975,7 @@ msgid_plural "Failed to archive designs. Please try again."
msgstr[0] ""
msgstr[1] ""
-msgid "Failed to assign a reviewer because no user was found."
+msgid "Failed to assign a reviewer because no user was specified."
msgstr ""
msgid "Failed to assign a user because no user was found."
@@ -14808,10 +15041,10 @@ msgstr ""
msgid "Failed to find import label for Jira import."
msgstr ""
-msgid "Failed to generate export, please try again later."
+msgid "Failed to find users for %{missing}"
msgstr ""
-msgid "Failed to generate report, please try again after sometime"
+msgid "Failed to generate export, please try again later."
msgstr ""
msgid "Failed to get ref."
@@ -14910,6 +15143,9 @@ msgstr ""
msgid "Failed to remove a to-do item for the design."
msgstr ""
+msgid "Failed to remove attention because no user was found."
+msgstr ""
+
msgid "Failed to remove mirror."
msgstr ""
@@ -14922,6 +15158,9 @@ msgstr ""
msgid "Failed to remove user key."
msgstr ""
+msgid "Failed to request attention because no user was found."
+msgstr ""
+
msgid "Failed to reset key. Please try again."
msgstr ""
@@ -15003,6 +15242,9 @@ msgstr ""
msgid "Feature Flags"
msgstr ""
+msgid "Feature deprecation and removal"
+msgstr ""
+
msgid "Feature flag status"
msgstr ""
@@ -15500,7 +15742,7 @@ msgstr ""
msgid "For each job, re-use the project workspace. If the workspace doesn't exist, use %{code_open}git clone%{code_close}."
msgstr ""
-msgid "For example, the application using the token or the purpose of the token."
+msgid "For example, the application using the token or the purpose of the token. Do not give sensitive information for the name of the token, as it will be visible to all %{resource_type} members."
msgstr ""
msgid "For files larger than this limit, only index the file name. The file content is neither indexed nor searchable."
@@ -15584,9 +15826,6 @@ msgstr ""
msgid "ForkProject|Select a namespace"
msgstr ""
-msgid "ForkProject|Select a namespace to fork the project"
-msgstr ""
-
msgid "ForkProject|The project can be accessed by any logged in user."
msgstr ""
@@ -15683,6 +15922,9 @@ msgstr ""
msgid "Full name"
msgstr ""
+msgid "GCP region configured"
+msgstr ""
+
msgid "GPG Key ID:"
msgstr ""
@@ -15863,6 +16105,9 @@ msgstr ""
msgid "Geo|Failed"
msgstr ""
+msgid "Geo|Filter Geo sites"
+msgstr ""
+
msgid "Geo|Filter by name"
msgstr ""
@@ -16274,6 +16519,12 @@ msgstr ""
msgid "GitLab Issue"
msgstr ""
+msgid "GitLab KAS"
+msgstr ""
+
+msgid "GitLab Memberships CSV Export"
+msgstr ""
+
msgid "GitLab Pages"
msgstr ""
@@ -16322,6 +16573,9 @@ 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 free to use. Many features for larger teams are part of our %{link_start}paid products%{link_end}. You can try Ultimate for free without any obligation or payment details."
+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 ""
@@ -16448,7 +16702,7 @@ msgstr ""
msgid "GitLabPages|When enabled, all attempts to visit your website through HTTP are automatically redirected to HTTPS using a response with status code 301. Requires a valid certificate for all domains. %{docs_link_start}Learn more.%{link_end}"
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. %{docs_link_start}Learn more.%{link_end}"
+msgid "GitLabPages|When using Pages under the general domain of a GitLab instance (%{pages_host}), you cannot use HTTPS with subdomains of subdomains. If your namespace or groupname contains a dot, it does not work. This is a limitation of the HTTP Over TLS protocol. HTTP pages work if you don't redirect HTTP to HTTPS. %{docs_link_start}Learn more.%{link_end}"
msgstr ""
msgid "GitLabPages|With GitLab Pages you can host your static website directly from your GitLab repository. %{docs_link_start}Learn more.%{link_end}"
@@ -16625,9 +16879,6 @@ msgstr ""
msgid "Go to find file"
msgstr ""
-msgid "Go to fork"
-msgstr ""
-
msgid "Go to issue boards"
msgstr ""
@@ -16835,9 +17086,6 @@ msgstr ""
msgid "Group Hooks"
msgstr ""
-msgid "Group ID"
-msgstr ""
-
msgid "Group Owner must have signed in with SAML before enabling Group Managed Accounts"
msgstr ""
@@ -16865,9 +17113,6 @@ msgstr ""
msgid "Group by"
msgstr ""
-msgid "Group description"
-msgstr ""
-
msgid "Group description (optional)"
msgstr ""
@@ -16982,7 +17227,7 @@ msgstr ""
msgid "Group: %{name}"
msgstr ""
-msgid "GroupActivityMetrics|Issues opened"
+msgid "GroupActivityMetrics|Issues created"
msgstr ""
msgid "GroupActivityMetrics|Last 90 days"
@@ -16991,7 +17236,7 @@ msgstr ""
msgid "GroupActivityMetrics|Members added"
msgstr ""
-msgid "GroupActivityMetrics|Merge Requests opened"
+msgid "GroupActivityMetrics|Merge Requests created"
msgstr ""
msgid "GroupActivityMetrics|Recent activity"
@@ -17282,6 +17527,9 @@ msgstr ""
msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
+msgid "GroupSettings|Choose a group path that does not start with a dash or end with a period. It can also contain alphanumeric characters and underscores."
+msgstr ""
+
msgid "GroupSettings|Compliance frameworks"
msgstr ""
@@ -17315,7 +17563,7 @@ msgstr ""
msgid "GroupSettings|If not specified at the group or instance level, the default is %{default_initial_branch_name}. Does not affect existing repositories."
msgstr ""
-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."
+msgid "GroupSettings|If the parent group's visibility is lower than the group's current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility."
msgstr ""
msgid "GroupSettings|New runners registration token has been generated!"
@@ -17432,7 +17680,10 @@ msgstr ""
msgid "Groups and projects"
msgstr ""
-msgid "Groups and subgroups"
+msgid "Groups are a great way to organize projects and people."
+msgstr ""
+
+msgid "Groups are the best way to manage projects and members."
msgstr ""
msgid "Groups to synchronize"
@@ -17543,13 +17794,16 @@ msgstr ""
msgid "GroupsTree|Are you sure you want to leave the \"%{fullName}\" group?"
msgstr ""
-msgid "GroupsTree|Edit group"
+msgid "GroupsTree|Delete"
+msgstr ""
+
+msgid "GroupsTree|Edit"
msgstr ""
msgid "GroupsTree|Failed to leave the group. Please make sure you are not the only owner."
msgstr ""
-msgid "GroupsTree|Leave this group"
+msgid "GroupsTree|Leave group"
msgstr ""
msgid "GroupsTree|Loading groups"
@@ -17561,9 +17815,57 @@ msgstr ""
msgid "GroupsTree|No groups or projects matched your search"
msgstr ""
+msgid "GroupsTree|Options"
+msgstr ""
+
msgid "GroupsTree|Search by name"
msgstr ""
+msgid "Groups|Avatar will be removed. Are you sure?"
+msgstr ""
+
+msgid "Groups|Changing group URL can have unintended side effects."
+msgstr ""
+
+msgid "Groups|Checking group URL availability..."
+msgstr ""
+
+msgid "Groups|Enter a descriptive name for your group."
+msgstr ""
+
+msgid "Groups|Group ID"
+msgstr ""
+
+msgid "Groups|Group URL"
+msgstr ""
+
+msgid "Groups|Group avatar"
+msgstr ""
+
+msgid "Groups|Group description (optional)"
+msgstr ""
+
+msgid "Groups|Group name"
+msgstr ""
+
+msgid "Groups|Group path is available."
+msgstr ""
+
+msgid "Groups|Group path is unavailable. Path has been replaced with a suggested available path."
+msgstr ""
+
+msgid "Groups|Learn more"
+msgstr ""
+
+msgid "Groups|Must start with letter, digit, emoji, or underscore. Can also contain periods, dashes, spaces, and parentheses."
+msgstr ""
+
+msgid "Groups|Remove avatar"
+msgstr ""
+
+msgid "Groups|Save changes"
+msgstr ""
+
msgid "Guideline"
msgstr ""
@@ -17573,6 +17875,9 @@ msgstr ""
msgid "HAR file path or URL"
msgstr ""
+msgid "HTTP Archive (HAR)"
+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 ""
@@ -17973,6 +18278,9 @@ msgstr ""
msgid "INFO: Your SSH key is expiring soon. Please generate a new key."
msgstr ""
+msgid "IP"
+msgstr ""
+
msgid "IP Address"
msgstr ""
@@ -18009,6 +18317,9 @@ msgstr ""
msgid "IdentityVerification|Verify your identity"
msgstr ""
+msgid "IdentityVerification|You can always verify your account at a later time to create a group."
+msgstr ""
+
msgid "If any indexed field exceeds this limit, it is truncated to this number of characters. The rest of the content is neither indexed nor searchable. This does not apply to repository and wiki indexing. For unlimited characters, set this to 0."
msgstr ""
@@ -18066,6 +18377,9 @@ msgstr ""
msgid "If you add %{codeStart}needs%{codeEnd} to jobs in your pipeline you'll be able to view the %{codeStart}needs%{codeEnd} relationships between jobs in this tab as a %{linkStart}Directed Acyclic Graph (DAG)%{linkEnd}."
msgstr ""
+msgid "If you are added to a project, it will be displayed here."
+msgstr ""
+
msgid "If you did not initiate these sign-in attempts, please reach out to your administrator or enable two-factor authentication (2FA) on your account."
msgstr ""
@@ -18372,12 +18686,24 @@ msgstr ""
msgid "InProductMarketing|3 ways to dive into GitLab CI/CD"
msgstr ""
+msgid "InProductMarketing|A single application eliminates complex integrations, data chokepoints, and toolchain maintenance, resulting in greater productivity and lower cost."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features, build more efficiently, strengthen security and compliance."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features."
+msgstr ""
+
msgid "InProductMarketing|Actually, GitLab makes the team work (better)"
msgstr ""
msgid "InProductMarketing|And finally %{deploy_link} a Python application."
msgstr ""
+msgid "InProductMarketing|And many more..."
+msgstr ""
+
msgid "InProductMarketing|Are your runners ready?"
msgstr ""
@@ -18396,15 +18722,33 @@ msgstr ""
msgid "InProductMarketing|Blog"
msgstr ""
+msgid "InProductMarketing|Break down silos to coordinate seamlessly across development, operations, and security with a consistent experience across the development lifecycle."
+msgstr ""
+
+msgid "InProductMarketing|Burn up/down charts"
+msgstr ""
+
msgid "InProductMarketing|By enabling code owners and required merge approvals the right person will review the right MR. This is a win-win: cleaner code and a more efficient review process."
msgstr ""
msgid "InProductMarketing|Click on the number below that corresponds with your answer — 1 being very difficult, 5 being very easy."
msgstr ""
+msgid "InProductMarketing|Code owners"
+msgstr ""
+
msgid "InProductMarketing|Code owners and required merge approvals are part of the paid tiers of GitLab. You can start a free 30-day trial of GitLab Ultimate and enable these features in less than 5 minutes with no credit card required."
msgstr ""
+msgid "InProductMarketing|Code review analytics"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration across stages in GitLab"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration made easy"
+msgstr ""
+
msgid "InProductMarketing|Create a custom CI runner with just a few clicks"
msgstr ""
@@ -18414,12 +18758,21 @@ msgstr ""
msgid "InProductMarketing|Create a project in GitLab in 5 minutes"
msgstr ""
+msgid "InProductMarketing|Create well-defined workflows by using scoped labels on issues, merge requests, and epics. Labels with the same scope cannot be used together, which prevents conflicts."
+msgstr ""
+
msgid "InProductMarketing|Create your first project!"
msgstr ""
+msgid "InProductMarketing|Define who owns specific files or directories, so the right reviewers are suggested when a merge request introduces changes to those files."
+msgstr ""
+
msgid "InProductMarketing|Deliver Better Products Faster"
msgstr ""
+msgid "InProductMarketing|Dependency scanning"
+msgstr ""
+
msgid "InProductMarketing|Did you know teams that use GitLab are far more efficient?"
msgstr ""
@@ -18429,15 +18782,27 @@ msgstr ""
msgid "InProductMarketing|Dig in and create a project and a repo"
msgstr ""
+msgid "InProductMarketing|Discover Premium & Ultimate"
+msgstr ""
+
+msgid "InProductMarketing|Discover Premium & Ultimate."
+msgstr ""
+
msgid "InProductMarketing|Do you have a minute?"
msgstr ""
msgid "InProductMarketing|Do you have a teammate who would be perfect for this task?"
msgstr ""
+msgid "InProductMarketing|Dynamic application security testing"
+msgstr ""
+
msgid "InProductMarketing|Easy"
msgstr ""
+msgid "InProductMarketing|Epics"
+msgstr ""
+
msgid "InProductMarketing|Expand your DevOps journey with a free GitLab trial"
msgstr ""
@@ -18459,9 +18824,15 @@ msgstr ""
msgid "InProductMarketing|Feel the need for speed?"
msgstr ""
+msgid "InProductMarketing|Find and fix bottlenecks in your code review process by understanding how long open merge requests have been in review."
+msgstr ""
+
msgid "InProductMarketing|Find out how your teams are really doing"
msgstr ""
+msgid "InProductMarketing|Find out if your external libraries are safe. Run dependency scanning jobs that check for known vulnerabilities in your external libraries."
+msgstr ""
+
msgid "InProductMarketing|Follow our steps"
msgstr ""
@@ -18498,6 +18869,9 @@ msgstr ""
msgid "InProductMarketing|GitLab is better with teammates to help out!"
msgstr ""
+msgid "InProductMarketing|GitLab is infrastructure agnostic (supporting GCP, AWS, Azure, OpenShift, VMWare, On Prem, Bare Metal, and more), offering a consistent workflow experience – irrespective of the environment."
+msgstr ""
+
msgid "InProductMarketing|GitLab provides static application security testing (SAST), dynamic application security testing (DAST), container scanning, and dependency scanning to help you deliver secure applications along with license compliance."
msgstr ""
@@ -18588,21 +18962,36 @@ msgstr ""
msgid "InProductMarketing|It's also possible to simply %{external_repo_link} in order to take advantage of GitLab's CI/CD."
msgstr ""
+msgid "InProductMarketing|Keep your code quality high by defining who should approve merge requests and how many approvals are required."
+msgstr ""
+
msgid "InProductMarketing|Launch GitLab CI/CD in 20 minutes or less"
msgstr ""
+msgid "InProductMarketing|Lower cost of development"
+msgstr ""
+
+msgid "InProductMarketing|Make it easier to collaborate on high-level ideas by grouping related issues in an epic."
+msgstr ""
+
msgid "InProductMarketing|Making the switch? It's easier than you think to import your projects into GitLab. Move %{github_link}, or import something %{bitbucket_link}."
msgstr ""
msgid "InProductMarketing|Master the art of importing!"
msgstr ""
+msgid "InProductMarketing|Merge request approval rule"
+msgstr ""
+
msgid "InProductMarketing|Move on to easily creating a Pages website %{ci_template_link}"
msgstr ""
msgid "InProductMarketing|Multiple owners, confusing workstreams? We've got you covered"
msgstr ""
+msgid "InProductMarketing|Multiple required approvers"
+msgstr ""
+
msgid "InProductMarketing|Need an alternative to importing?"
msgstr ""
@@ -18615,18 +19004,33 @@ msgstr ""
msgid "InProductMarketing|Our tool brings all the things together"
msgstr ""
+msgid "InProductMarketing|Protect your web application by using DAST to examine for vulnerabilities in deployed environments."
+msgstr ""
+
msgid "InProductMarketing|Rapid development, simplified"
msgstr ""
msgid "InProductMarketing|Reduce Security & Compliance Risk"
msgstr ""
+msgid "InProductMarketing|Require multiple approvers on a merge request, so you know it's in good shape before it's merged."
+msgstr ""
+
+msgid "InProductMarketing|Roadmaps"
+msgstr ""
+
+msgid "InProductMarketing|Scoped labels"
+msgstr ""
+
msgid "InProductMarketing|Security that's integrated into your development lifecycle"
msgstr ""
msgid "InProductMarketing|Sometimes you're not ready to make a full transition to a new tool. If you're not ready to fully commit, %{mirroring_link} gives you a safe way to try out GitLab in parallel with your current tool."
msgstr ""
+msgid "InProductMarketing|Speed. Efficiency. Trust."
+msgstr ""
+
msgid "InProductMarketing|Spin up an autoscaling runner in GitLab"
msgstr ""
@@ -18636,6 +19040,9 @@ msgstr ""
msgid "InProductMarketing|Start a Self-Managed trial"
msgstr ""
+msgid "InProductMarketing|Start a free trial"
+msgstr ""
+
msgid "InProductMarketing|Start a free trial of GitLab Ultimate – no credit card required"
msgstr ""
@@ -18702,6 +19109,9 @@ msgstr ""
msgid "InProductMarketing|To understand and get the most out of GitLab, start at the beginning and %{project_link}. In GitLab, repositories are part of a project, so after you've created your project you can go ahead and %{repo_link}."
msgstr ""
+msgid "InProductMarketing|Track completed issues in a chart, so you can see how a milestone is progressing at a glance."
+msgstr ""
+
msgid "InProductMarketing|Try GitLab Ultimate for free"
msgstr ""
@@ -18738,6 +19148,9 @@ msgstr ""
msgid "InProductMarketing|Very easy"
msgstr ""
+msgid "InProductMarketing|Visualize your epics and milestones in a timeline."
+msgstr ""
+
msgid "InProductMarketing|Want to host GitLab on your servers?"
msgstr ""
@@ -18759,6 +19172,9 @@ msgstr ""
msgid "InProductMarketing|YouTube"
msgstr ""
+msgid "InProductMarketing|Your software, deployed your way"
+msgstr ""
+
msgid "InProductMarketing|Your teams can be more efficient"
msgstr ""
@@ -18879,9 +19295,18 @@ msgstr ""
msgid "IncidentManagement|No incidents to display."
msgstr ""
+msgid "IncidentManagement|None"
+msgstr ""
+
msgid "IncidentManagement|Open"
msgstr ""
+msgid "IncidentManagement|Page your team with escalation policies"
+msgstr ""
+
+msgid "IncidentManagement|Paged"
+msgstr ""
+
msgid "IncidentManagement|Published"
msgstr ""
@@ -18891,6 +19316,9 @@ msgstr ""
msgid "IncidentManagement|Severity"
msgstr ""
+msgid "IncidentManagement|Status"
+msgstr ""
+
msgid "IncidentManagement|There are no closed incidents"
msgstr ""
@@ -18909,6 +19337,9 @@ msgstr ""
msgid "IncidentManagement|Unpublished"
msgstr ""
+msgid "IncidentManagement|Use escalation policies to automatically page your team when incidents are created."
+msgstr ""
+
msgid "IncidentSettings|Activate \"time to SLA\" countdown timer"
msgstr ""
@@ -18954,7 +19385,10 @@ msgstr ""
msgid "Incidents"
msgstr ""
-msgid "Incidents|Add a URL"
+msgid "Incidents|Add image details"
+msgstr ""
+
+msgid "Incidents|Add text or a link to display with your image. If you don't add either, the file name displays instead."
msgstr ""
msgid "Incidents|Drop or %{linkStart}upload%{linkEnd} a metric screenshot to attach it to the incident"
@@ -18969,10 +19403,10 @@ msgstr ""
msgid "Incidents|There was an issue loading metric images."
msgstr ""
-msgid "Incidents|There was an issue uploading your image."
+msgid "Incidents|There was an issue updating your image."
msgstr ""
-msgid "Incidents|You can optionally add a URL to link users to the original graph."
+msgid "Incidents|There was an issue uploading your image."
msgstr ""
msgid "Incident|Alert details"
@@ -18981,9 +19415,18 @@ msgstr ""
msgid "Incident|Are you sure you wish to delete this image?"
msgstr ""
+msgid "Incident|Delete image"
+msgstr ""
+
msgid "Incident|Deleting %{filename}"
msgstr ""
+msgid "Incident|Edit image text or link"
+msgstr ""
+
+msgid "Incident|Editing %{filename}"
+msgstr ""
+
msgid "Incident|Metrics"
msgstr ""
@@ -19253,12 +19696,18 @@ msgstr ""
msgid "Integrations|Branches for which notifications are to be sent"
msgstr ""
+msgid "Integrations|Clear if using a self-signed certificate."
+msgstr ""
+
msgid "Integrations|Comment detail:"
msgstr ""
msgid "Integrations|Comment settings:"
msgstr ""
+msgid "Integrations|Connection details"
+msgstr ""
+
msgid "Integrations|Connection failed. Please check your settings."
msgstr ""
@@ -19283,6 +19732,9 @@ msgstr ""
msgid "Integrations|Enable GitLab.com slash commands in a Slack workspace."
msgstr ""
+msgid "Integrations|Enable SSL verification"
+msgstr ""
+
msgid "Integrations|Enable comments"
msgstr ""
@@ -19361,6 +19813,9 @@ msgstr ""
msgid "Integrations|Return to GitLab for Jira"
msgstr ""
+msgid "Integrations|SSL verification"
+msgstr ""
+
msgid "Integrations|Save settings?"
msgstr ""
@@ -19406,9 +19861,6 @@ msgstr ""
msgid "Integrations|Use default settings"
msgstr ""
-msgid "Integrations|When you mention a Jira issue in a commit or merge request, GitLab creates a remote link and comment (if enabled)."
-msgstr ""
-
msgid "Integrations|You can now close this window and return to the GitLab for Jira application."
msgstr ""
@@ -19433,9 +19885,6 @@ msgstr ""
msgid "Integrations|can't exceed %{recipients_limit}"
msgstr ""
-msgid "Interactive developer security education."
-msgstr ""
-
msgid "Interactive mode"
msgstr ""
@@ -19925,6 +20374,9 @@ msgstr ""
msgid "IssueAnalytics|Assignees"
msgstr ""
+msgid "IssueAnalytics|Created by"
+msgstr ""
+
msgid "IssueAnalytics|Due date"
msgstr ""
@@ -19937,9 +20389,6 @@ msgstr ""
msgid "IssueAnalytics|Milestone"
msgstr ""
-msgid "IssueAnalytics|Opened by"
-msgstr ""
-
msgid "IssueAnalytics|Status"
msgstr ""
@@ -20063,10 +20512,10 @@ msgstr ""
msgid "IssuesAnalytics|Avg/Month:"
msgstr ""
-msgid "IssuesAnalytics|Issues opened"
+msgid "IssuesAnalytics|Issues created"
msgstr ""
-msgid "IssuesAnalytics|Issues opened per month"
+msgid "IssuesAnalytics|Issues created per month"
msgstr ""
msgid "IssuesAnalytics|Last 12 months"
@@ -20093,6 +20542,9 @@ msgstr ""
msgid "It looks like you have some draft commits in this branch."
msgstr ""
+msgid "It looks like you're attempting to activate your subscription. Use %{a_start}the Subscription page%{a_end} instead."
+msgstr ""
+
msgid "It may be several days before you see feature usage data."
msgstr ""
@@ -20321,6 +20773,9 @@ msgstr ""
msgid "JiraConnect|You can now close this window and return to Jira."
msgstr ""
+msgid "JiraConnect|You don't have permission to create branches for this project. Select a different project or contact the project owner for access. %{linkStart}Learn more.%{linkEnd}"
+msgstr ""
+
msgid "JiraRequest|A connection error occurred while connecting to Jira. Try your request again."
msgstr ""
@@ -20369,13 +20824,13 @@ msgstr ""
msgid "JiraService|Define the type of Jira issue to create from a vulnerability."
msgstr ""
-msgid "JiraService|Displaying Jira issues while leaving the GitLab issue functionality enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
+msgid "JiraService|Displaying Jira issues while leaving GitLab issues also enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
msgstr ""
-msgid "JiraService|Enable Jira issues"
+msgid "JiraService|Enable Jira issue creation from vulnerabilities"
msgstr ""
-msgid "JiraService|Enable Jira issues creation from vulnerabilities"
+msgid "JiraService|Enable Jira issues"
msgstr ""
msgid "JiraService|Enable Jira transitions"
@@ -20492,16 +20947,19 @@ msgstr ""
msgid "JiraService|View Jira issues in GitLab"
msgstr ""
-msgid "JiraService|Warning: All GitLab users that have access to this GitLab project are able to view all issues from the Jira project specified below."
+msgid "JiraService|Warning: All GitLab users with access to this GitLab project can view all issues from the Jira project you select."
msgstr ""
msgid "JiraService|Web URL"
msgstr ""
-msgid "JiraService|Work on Jira issues without leaving GitLab. Adds a Jira menu to access your list of Jira issues and view any issue as read-only."
+msgid "JiraService|When a Jira issue is mentioned in a commit or merge request, a remote link and comment (if enabled) will be created."
+msgstr ""
+
+msgid "JiraService|Work on Jira issues without leaving GitLab. Add a Jira menu to access a read-only list of your Jira issues."
msgstr ""
-msgid "JiraService|You need to configure Jira before enabling this integration. For more details, read the %{jira_doc_link_start}Jira integration documentation%{link_end}."
+msgid "JiraService|You must configure Jira before enabling this integration. %{jira_doc_link_start}Learn more.%{link_end}"
msgstr ""
msgid "Job"
@@ -20513,9 +20971,6 @@ msgstr ""
msgid "Job Failed #%{build_id}"
msgstr ""
-msgid "Job ID"
-msgstr ""
-
msgid "Job artifact"
msgstr ""
@@ -20582,9 +21037,27 @@ msgstr ""
msgid "Jobs|You're about to retry a job that failed because it attempted to deploy code that is older than the latest deployment. Retrying this job could result in overwriting the environment with the older source code."
msgstr ""
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source} into %{target}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{ref}"
+msgstr ""
+
+msgid "Job|Are you sure you want to erase this job log and artifacts?"
+msgstr ""
+
msgid "Job|Browse"
msgstr ""
+msgid "Job|Cancel"
+msgstr ""
+
msgid "Job|Complete Raw"
msgstr ""
@@ -20594,6 +21067,9 @@ msgstr ""
msgid "Job|Erase job log and artifacts"
msgstr ""
+msgid "Job|Finished at"
+msgstr ""
+
msgid "Job|Job artifacts"
msgstr ""
@@ -20606,7 +21082,7 @@ msgstr ""
msgid "Job|Keep"
msgstr ""
-msgid "Job|Pipeline"
+msgid "Job|Retry"
msgstr ""
msgid "Job|Scroll to bottom"
@@ -20618,6 +21094,9 @@ msgstr ""
msgid "Job|Show complete raw"
msgstr ""
+msgid "Job|Status"
+msgstr ""
+
msgid "Job|The artifacts were removed"
msgstr ""
@@ -20645,21 +21124,12 @@ msgstr ""
msgid "Job|delayed"
msgstr ""
-msgid "Job|for"
-msgstr ""
-
-msgid "Job|into"
-msgstr ""
-
msgid "Job|manual"
msgstr ""
msgid "Job|triggered"
msgstr ""
-msgid "Job|with"
-msgstr ""
-
msgid "Join Zoom meeting"
msgstr ""
@@ -20762,9 +21232,6 @@ msgstr ""
msgid "Ki"
msgstr ""
-msgid "Kontra"
-msgstr ""
-
msgid "Kroki"
msgstr ""
@@ -21088,6 +21555,9 @@ msgstr ""
msgid "Learn more about Auto DevOps"
msgstr ""
+msgid "Learn more about GitLab"
+msgstr ""
+
msgid "Learn more about Needs relationships"
msgstr ""
@@ -21415,9 +21885,18 @@ msgstr ""
msgid "Licenses|Displays licenses detected in the project, based on the %{linkStart}latest successful%{linkEnd} scan"
msgstr ""
+msgid "Licenses|Drag your license file here or %{linkStart}click to upload%{linkEnd}."
+msgstr ""
+
+msgid "Licenses|Drop your license file to start the upload."
+msgstr ""
+
msgid "Licenses|Error fetching the license list. Please check your network connection and try again."
msgstr ""
+msgid "Licenses|Error: You are trying to upload something other than a file"
+msgstr ""
+
msgid "Licenses|License Compliance"
msgstr ""
@@ -21436,6 +21915,9 @@ msgstr ""
msgid "Licenses|Specified policies in this project"
msgstr ""
+msgid "Licenses|The file could not be uploaded."
+msgstr ""
+
msgid "Licenses|The license list details information about the licenses used within your project."
msgstr ""
@@ -21469,11 +21951,6 @@ msgstr ""
msgid "Limit the size of Sidekiq jobs stored in Redis."
msgstr ""
-msgid "Limited to showing %d event at most"
-msgid_plural "Limited to showing %d events at most"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Limiting mode"
msgstr ""
@@ -21483,6 +21960,9 @@ msgstr ""
msgid "Link"
msgstr ""
+msgid "Link (optional)"
+msgstr ""
+
msgid "Link Prometheus monitoring to GitLab."
msgstr ""
@@ -21519,6 +21999,9 @@ msgstr ""
msgid "Linked emails (%{email_count})"
msgstr ""
+msgid "Linked epics"
+msgstr ""
+
msgid "Linked issues"
msgstr ""
@@ -21546,6 +22029,15 @@ msgstr ""
msgid "List of all merge commits"
msgstr ""
+msgid "List of environments for this project"
+msgstr ""
+
+msgid "List of suitable GCP locations"
+msgstr ""
+
+msgid "List of users allowed to exceed the rate limit."
+msgstr ""
+
msgid "List options"
msgstr ""
@@ -21765,6 +22257,9 @@ msgstr ""
msgid "Maintenance mode"
msgstr ""
+msgid "Make adjustments to how your GitLab instance is set up."
+msgstr ""
+
msgid "Make and review changes in the browser with the Web IDE"
msgstr ""
@@ -21909,6 +22404,12 @@ msgstr ""
msgid "MarkdownEditor|Add italic text (%{modifier_key}I)"
msgstr ""
+msgid "MarkdownEditor|Add strikethrough text (%{modifierKey}⇧X)"
+msgstr ""
+
+msgid "MarkdownEditor|Add strikethrough text (%{modifier_key}⇧X)"
+msgstr ""
+
msgid "Marked For Deletion At - %{deletion_time}"
msgstr ""
@@ -22170,6 +22671,9 @@ msgstr ""
msgid "Maximum push size (MB)"
msgstr ""
+msgid "Maximum requests per 10 minutes per user"
+msgstr ""
+
msgid "Maximum requests per minute"
msgstr ""
@@ -22260,6 +22764,19 @@ msgstr ""
msgid "Members of a group may only view projects they have permission to access"
msgstr ""
+msgid "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seat in use and will be billed for the overage."
+msgid_plural "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seats in use and will be billed for the overage."
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "MembersOverage|You are about to incur additional charges"
+msgstr ""
+
+msgid "MembersOverage|Your subscription includes %d seat."
+msgid_plural "MembersOverage|Your subscription includes %d seats."
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Membership"
msgstr ""
@@ -22464,9 +22981,6 @@ msgstr ""
msgid "Merge request not merged"
msgstr ""
-msgid "Merge request pipelines 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 merge request pipelines."
-msgstr ""
-
msgid "Merge request reports"
msgstr ""
@@ -22563,13 +23077,13 @@ msgstr ""
msgid "MergeRequests|Create issue to resolve thread"
msgstr ""
-msgid "MergeRequests|Failed to squash. Should be done manually."
+msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Saving the comment failed"
+msgid "MergeRequests|Squashing failed: Squash the commits locally, resolve any conflicts, then push the branch."
msgstr ""
-msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
+msgid "MergeRequests|Squashing not allowed: This project doesn't allow you to squash commits when merging."
msgstr ""
msgid "MergeRequests|Thread stays resolved"
@@ -23410,6 +23924,18 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "MrList|Assigned to %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from assignee %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from reviewer %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Review requested from %{name}, go to their profile."
+msgstr ""
+
msgid "Multi-project"
msgstr ""
@@ -23443,7 +23969,7 @@ msgstr ""
msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "My Awesome Group"
+msgid "My awesome group"
msgstr ""
msgid "My company or team"
@@ -24065,9 +24591,6 @@ msgstr ""
msgid "No available branches"
msgstr ""
-msgid "No available groups to fork the project."
-msgstr ""
-
msgid "No branches found"
msgstr ""
@@ -24278,6 +24801,9 @@ msgstr ""
msgid "No ref selected"
msgstr ""
+msgid "No regions configured"
+msgstr ""
+
msgid "No related merge requests found."
msgstr ""
@@ -25082,6 +25608,9 @@ msgstr ""
msgid "Only reCAPTCHA v2 is supported:"
msgstr ""
+msgid "Only required if not using role instance credentials."
+msgstr ""
+
msgid "Only use lowercase letters, numbers, and underscores."
msgstr ""
@@ -25106,9 +25635,6 @@ msgstr ""
msgid "Open a CLI and connect to the cluster you want to install the agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
-msgid "Open epics"
-msgstr ""
-
msgid "Open errors"
msgstr ""
@@ -25148,7 +25674,7 @@ msgstr ""
msgid "Opened issues"
msgstr ""
-msgid "OpenedNDaysAgo|Opened"
+msgid "OpenedNDaysAgo|Created"
msgstr ""
msgid "Opens in a new window"
@@ -25193,9 +25719,6 @@ msgstr ""
msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
-msgid "Optional."
-msgstr ""
-
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
msgstr ""
@@ -25984,6 +26507,9 @@ msgstr ""
msgid "PerformanceBar|Memory"
msgstr ""
+msgid "PerformanceBar|Memory report"
+msgstr ""
+
msgid "PerformanceBar|Redis calls"
msgstr ""
@@ -26017,18 +26543,12 @@ msgstr ""
msgid "PerformanceBar|wall"
msgstr ""
-msgid "Performs a rebase but skips triggering a new pipeline"
-msgstr ""
-
msgid "Period in seconds"
msgstr ""
msgid "Permalink"
msgstr ""
-msgid "Permanently delete project"
-msgstr ""
-
msgid "Permanently remove group"
msgstr ""
@@ -26299,6 +26819,51 @@ msgstr ""
msgid "PipelineStatusTooltip|Pipeline: %{ci_status}"
msgstr ""
+msgid "PipelineWizardDefaultCommitMessage|Add %{filename}"
+msgstr ""
+
+msgid "PipelineWizardDefaultCommitMessage|Update %{filename}"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|At least one entry is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This field is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This value is not valid"
+msgstr ""
+
+msgid "PipelineWizardListWidget|add another step"
+msgstr ""
+
+msgid "PipelineWizardListWidget|remove step"
+msgstr ""
+
+msgid "PipelineWizard|Commit"
+msgstr ""
+
+msgid "PipelineWizard|Commit Message"
+msgstr ""
+
+msgid "PipelineWizard|Commit changes to your file"
+msgstr ""
+
+msgid "PipelineWizard|Commit file to Branch"
+msgstr ""
+
+msgid "PipelineWizard|Commit your new file"
+msgstr ""
+
+msgid "PipelineWizard|The file has been committed."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem committing the changes."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem while checking whether your file already exists in the specified branch."
+msgstr ""
+
msgid "Pipelines"
msgstr ""
@@ -26413,7 +26978,7 @@ msgstr ""
msgid "Pipelines|Project cache successfully reset."
msgstr ""
-msgid "Pipelines|Revoke"
+msgid "Pipelines|Revoke trigger"
msgstr ""
msgid "Pipelines|Something went wrong while cleaning runners cache."
@@ -26458,6 +27023,12 @@ msgstr ""
msgid "Pipelines|This is a child pipeline within the parent pipeline"
msgstr ""
+msgid "Pipelines|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipelines|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipelines|This pipeline will run code originating from a forked project merge request. This means that the code can potentially have security considerations like exposing CI variables."
msgstr ""
@@ -26500,9 +27071,6 @@ msgstr ""
msgid "Pipelines|Your changes have been successfully committed. Now redirecting to the new merge request page."
msgstr ""
-msgid "Pipelines|detached"
-msgstr ""
-
msgid "Pipelines|error"
msgstr ""
@@ -26512,10 +27080,13 @@ msgstr ""
msgid "Pipelines|latest"
msgstr ""
-msgid "Pipelines|stuck"
+msgid "Pipelines|merge request"
msgstr ""
-msgid "Pipelines|train"
+msgid "Pipelines|merge train"
+msgstr ""
+
+msgid "Pipelines|stuck"
msgstr ""
msgid "Pipelines|yaml invalid"
@@ -26647,6 +27218,12 @@ msgstr ""
msgid "Pipeline|This change will not change the overall test coverage if merged."
msgstr ""
+msgid "Pipeline|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipeline|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipeline|Trigger author"
msgstr ""
@@ -26671,6 +27248,12 @@ msgstr ""
msgid "Pipeline|for"
msgstr ""
+msgid "Pipeline|merge request"
+msgstr ""
+
+msgid "Pipeline|merge train"
+msgstr ""
+
msgid "Pipeline|on"
msgstr ""
@@ -26809,9 +27392,6 @@ msgstr ""
msgid "Please enter a valid time interval"
msgstr ""
-msgid "Please enter or upload a valid license."
-msgstr ""
-
msgid "Please enter your current password."
msgstr ""
@@ -26920,9 +27500,6 @@ msgstr ""
msgid "Please type %{phrase_code} to proceed or close this modal to cancel."
msgstr ""
-msgid "Please type the following to confirm:"
-msgstr ""
-
msgid "Please use this form to report to the admin users who create spam issues, comments or behave inappropriately."
msgstr ""
@@ -26950,12 +27527,27 @@ msgstr ""
msgid "Policies"
msgstr ""
+msgid "Policy '%{escalation_policy_name}' does not exist."
+msgstr ""
+
msgid "Policy management project does have any policies in %{policy_path}"
msgstr ""
msgid "Policy project doesn't exist"
msgstr ""
+msgid "PolicyRuleMultiSelect|%{firstLabel} +%{numberOfAdditionalLabels} more"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|All %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select all"
+msgstr ""
+
msgid "Polling interval multiplier"
msgstr ""
@@ -27184,6 +27776,9 @@ msgstr ""
msgid "Private projects can be created in your personal namespace with:"
msgstr ""
+msgid "Problem with %{name} command: %{message}."
+msgstr ""
+
msgid "Proceed"
msgstr ""
@@ -27658,6 +28253,9 @@ msgstr ""
msgid "Progress"
msgstr ""
+msgid "Progress tracking"
+msgstr ""
+
msgid "Project"
msgstr ""
@@ -27889,6 +28487,9 @@ msgstr ""
msgid "ProjectQualitySummary|Failure"
msgstr ""
+msgid "ProjectQualitySummary|Get insight into the overall percentage of tests in your project that succeed, fail and are skipped."
+msgstr ""
+
msgid "ProjectQualitySummary|Latest pipeline results"
msgstr ""
@@ -27907,6 +28508,12 @@ msgstr ""
msgid "ProjectQualitySummary|See project Code Coverage Statistics"
msgstr ""
+msgid "ProjectQualitySummary|Set up test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|Set up test runs (opens in a new tab)"
+msgstr ""
+
msgid "ProjectQualitySummary|Skipped"
msgstr ""
@@ -28183,13 +28790,19 @@ msgstr ""
msgid "ProjectSettings|LFS objects from this repository are available to forks. %{linkStart}How do I remove them?%{linkEnd}"
msgstr ""
+msgid "ProjectSettings|Learn about commit history."
+msgstr ""
+
+msgid "ProjectSettings|Leave empty to use default template."
+msgstr ""
+
msgid "ProjectSettings|Manage who can see the project in the public access directory."
msgstr ""
msgid "ProjectSettings|Manages large files such as audio, video, and graphics files."
msgstr ""
-msgid "ProjectSettings|Maximum 500 characters."
+msgid "ProjectSettings|Maximum %{maxLength} characters."
msgstr ""
msgid "ProjectSettings|Merge checks"
@@ -28330,6 +28943,9 @@ msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
msgstr ""
+msgid "ProjectSettings|The default template will be applied on save."
+msgstr ""
+
msgid "ProjectSettings|These checks must pass before merge requests can be merged."
msgstr ""
@@ -28384,6 +29000,9 @@ msgstr ""
msgid "ProjectSettings|What are badges?"
msgstr ""
+msgid "ProjectSettings|What are merge trains?"
+msgstr ""
+
msgid "ProjectSettings|When merge request pipelines are enabled in the CI/CD configuration file, pipelines validate the combined results of the source and target branches. %{link_start}How to configure merge request pipelines?%{link_end}"
msgstr ""
@@ -28501,6 +29120,9 @@ msgstr ""
msgid "Projects are organized into groups"
msgstr ""
+msgid "Projects are where you store your code, access issues, wiki and other features of GitLab."
+msgstr ""
+
msgid "Projects contributed to"
msgstr ""
@@ -28516,12 +29138,6 @@ msgstr ""
msgid "Projects to index"
msgstr ""
-msgid "Projects will be permanently deleted after a %{waiting_period}-day waiting period."
-msgstr ""
-
-msgid "Projects will be permanently deleted immediately."
-msgstr ""
-
msgid "Projects with critical vulnerabilities"
msgstr ""
@@ -28606,6 +29222,9 @@ msgstr ""
msgid "ProjectsNew|Import project"
msgstr ""
+msgid "ProjectsNew|Include a Getting Started README"
+msgstr ""
+
msgid "ProjectsNew|Initialize repository with a README"
msgstr ""
@@ -28621,6 +29240,9 @@ msgstr ""
msgid "ProjectsNew|Project description %{tag_start}(optional)%{tag_end}"
msgstr ""
+msgid "ProjectsNew|Recommended if you're new to GitLab"
+msgstr ""
+
msgid "ProjectsNew|Run CI/CD for external repository"
msgstr ""
@@ -29038,6 +29660,9 @@ msgstr ""
msgid "ProtectedBranch|Unprotect"
msgstr ""
+msgid "ProtectedBranch|Unprotect branch"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
@@ -29065,6 +29690,9 @@ msgstr ""
msgid "ProtectedEnvironment|Protected Environment (%{protected_environments_count})"
msgstr ""
+msgid "ProtectedEnvironment|Required approvals"
+msgstr ""
+
msgid "ProtectedEnvironment|Select an environment"
msgstr ""
@@ -29086,10 +29714,13 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|Unprotect tag"
+msgstr ""
+
msgid "ProtectedTags|default"
msgstr ""
-msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
+msgid "ProtectedTag|By default, protected tags restrict who can modify the tag."
msgstr ""
msgid "ProtectedTag|Learn more."
@@ -29152,6 +29783,9 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Public projects are an easy way to allow everyone to have read-only access."
+msgstr ""
+
msgid "Publish to status page"
msgstr ""
@@ -29308,9 +29942,6 @@ msgstr ""
msgid "QualitySummary|Project quality"
msgstr ""
-msgid "Quarters"
-msgstr ""
-
msgid "Query"
msgstr ""
@@ -29395,6 +30026,9 @@ msgstr ""
msgid "Read more about project permissions %{help_link_open}here%{help_link_close}"
msgstr ""
+msgid "Read more about related epics"
+msgstr ""
+
msgid "Read more about related issues"
msgstr ""
@@ -29425,10 +30059,7 @@ msgstr ""
msgid "Rebase source branch on the target branch."
msgstr ""
-msgid "Rebase without CI"
-msgstr ""
-
-msgid "Rebases and triggers a pipeline"
+msgid "Rebase without pipeline"
msgstr ""
msgid "Recaptcha verified?"
@@ -29479,9 +30110,6 @@ msgstr ""
msgid "Reconfigure"
msgstr ""
-msgid "Recovering projects"
-msgstr ""
-
msgid "Recovery Codes"
msgstr ""
@@ -29541,6 +30169,12 @@ msgstr ""
msgid "Regex pattern"
msgstr ""
+msgid "Region"
+msgstr ""
+
+msgid "Regions"
+msgstr ""
+
msgid "Register"
msgstr ""
@@ -29771,9 +30405,6 @@ msgstr ""
msgid "Remove all or specific reviewer(s)"
msgstr ""
-msgid "Remove approver"
-msgstr ""
-
msgid "Remove approvers"
msgstr ""
@@ -29789,6 +30420,9 @@ msgstr ""
msgid "Remove attention request"
msgstr ""
+msgid "Remove attention request(s)"
+msgstr ""
+
msgid "Remove avatar"
msgstr ""
@@ -29927,6 +30561,9 @@ msgstr ""
msgid "Removed an issue from an epic."
msgstr ""
+msgid "Removed attention from %{users_sentence}."
+msgstr ""
+
msgid "Removed attention request from @%{username}"
msgstr ""
@@ -29978,6 +30615,9 @@ msgstr ""
msgid "Removes an issue from an epic."
msgstr ""
+msgid "Removes attention from %{users_sentence}."
+msgstr ""
+
msgid "Removes parent epic %{epic_ref}."
msgstr ""
@@ -30089,6 +30729,9 @@ msgstr ""
msgid "Report abuse to admin"
msgstr ""
+msgid "Report is generating and will be sent to your email address."
+msgstr ""
+
msgid "Reported %{timeAgo} by %{reportedBy}"
msgstr ""
@@ -30378,6 +31021,15 @@ msgstr ""
msgid "Request attention"
msgstr ""
+msgid "Request attention from %{users_sentence}."
+msgstr ""
+
+msgid "Request attention from assignee or reviewer"
+msgstr ""
+
+msgid "Request attention from assignee(s) or reviewer(s)"
+msgstr ""
+
msgid "Request attention to review"
msgstr ""
@@ -30402,6 +31054,9 @@ msgstr ""
msgid "Requested %{time_ago}"
msgstr ""
+msgid "Requested attention from %{users_sentence}."
+msgstr ""
+
msgid "Requested attention from @%{username}"
msgstr ""
@@ -30616,6 +31271,9 @@ msgstr ""
msgid "Restore project"
msgstr ""
+msgid "Restoring projects"
+msgstr ""
+
msgid "Restoring the group will prevent the group, its subgroups and projects from being removed on this date."
msgstr ""
@@ -30646,6 +31304,9 @@ msgstr ""
msgid "Retry"
msgstr ""
+msgid "Retry failed jobs"
+msgstr ""
+
msgid "Retry job"
msgstr ""
@@ -30693,9 +31354,6 @@ msgstr ""
msgid "Review changes"
msgstr ""
-msgid "Review requested from %{name}"
-msgstr ""
-
msgid "Review requests for you"
msgstr ""
@@ -30860,6 +31518,9 @@ msgstr ""
msgid "Runners|Assigned Group"
msgstr ""
+msgid "Runners|Assigned Projects (%{projectCount})"
+msgstr ""
+
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30929,6 +31590,9 @@ msgstr ""
msgid "Runners|Instance"
msgstr ""
+msgid "Runners|Jobs"
+msgstr ""
+
msgid "Runners|Last contact"
msgstr ""
@@ -31022,9 +31686,6 @@ msgstr ""
msgid "Runners|Runner %{name} was deleted"
msgstr ""
-msgid "Runners|Runner ID"
-msgstr ""
-
msgid "Runners|Runner assigned to project."
msgstr ""
@@ -31172,6 +31833,9 @@ msgstr ""
msgid "Runners|stale"
msgstr ""
+msgid "Runner|This runner has not run any jobs."
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -31286,6 +31950,24 @@ msgstr ""
msgid "Saving project."
msgstr ""
+msgid "ScanResultPolicy|%{ifLabelStart}if%{ifLabelEnd} %{scanners} scan in an open merge request targeting the %{branches} branch(es) finds %{vulnerabilitiesAllowed} or more %{severities} vulnerabilities that are %{vulnerabilityStates}"
+msgstr ""
+
+msgid "ScanResultPolicy|%{thenLabelStart}Then%{thenLabelEnd} Require approval from %{approvalsRequired} of the following approvers: %{approvers}"
+msgstr ""
+
+msgid "ScanResultPolicy|add an approver"
+msgstr ""
+
+msgid "ScanResultPolicy|scanners"
+msgstr ""
+
+msgid "ScanResultPolicy|severity levels"
+msgstr ""
+
+msgid "ScanResultPolicy|vulnerability states"
+msgstr ""
+
msgid "Scanner"
msgstr ""
@@ -31418,6 +32100,9 @@ msgstr ""
msgid "Search for a user"
msgstr ""
+msgid "Search for an emoji"
+msgstr ""
+
msgid "Search for projects, issues, etc."
msgstr ""
@@ -31605,18 +32290,12 @@ msgstr ""
msgid "Secret Detection"
msgstr ""
-msgid "Secret access key"
-msgstr ""
-
msgid "Secret token"
msgstr ""
msgid "Secure token that identifies an external storage request."
msgstr ""
-msgid "SecureCodeWarrior"
-msgstr ""
-
msgid "Security"
msgstr ""
@@ -31641,9 +32320,6 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "Security training with guide and learning pathways."
-msgstr ""
-
msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
@@ -31746,7 +32422,7 @@ msgstr ""
msgid "SecurityConfiguration|Manage corpus"
msgstr ""
-msgid "SecurityConfiguration|Manage corpus files used as mutation sources in coverage fuzzing."
+msgid "SecurityConfiguration|Manage corpus files used as seed inputs with coverage-guided fuzzing."
msgstr ""
msgid "SecurityConfiguration|Manage profiles for use by DAST scans."
@@ -31812,15 +32488,15 @@ msgstr ""
msgid "SecurityOrchestration|.yaml preview"
msgstr ""
-msgid "SecurityOrchestration|Action"
-msgstr ""
-
msgid "SecurityOrchestration|Actions"
msgstr ""
msgid "SecurityOrchestration|Add rule"
msgstr ""
+msgid "SecurityOrchestration|After dismissing the alert, the information will never be shown again."
+msgstr ""
+
msgid "SecurityOrchestration|All policies"
msgstr ""
@@ -31836,7 +32512,7 @@ msgstr ""
msgid "SecurityOrchestration|Description"
msgstr ""
-msgid "SecurityOrchestration|Disabled"
+msgid "SecurityOrchestration|Don't show the alert anymore"
msgstr ""
msgid "SecurityOrchestration|Edit policy"
@@ -31845,13 +32521,13 @@ msgstr ""
msgid "SecurityOrchestration|Edit policy project"
msgstr ""
-msgid "SecurityOrchestration|Enabled"
+msgid "SecurityOrchestration|Empty policy name"
msgstr ""
-msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Enabled"
msgstr ""
-msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
msgstr ""
msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
@@ -31860,7 +32536,7 @@ msgstr ""
msgid "SecurityOrchestration|Invalid policy type"
msgstr ""
-msgid "SecurityOrchestration|Latest scan"
+msgid "SecurityOrchestration|Latest scan run against %{agent}"
msgstr ""
msgid "SecurityOrchestration|Network"
@@ -31869,15 +32545,27 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No actions defined - policy will not run."
+msgstr ""
+
+msgid "SecurityOrchestration|No description"
+msgstr ""
+
msgid "SecurityOrchestration|No rules defined - policy will not run."
msgstr ""
+msgid "SecurityOrchestration|Not enabled"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
msgid "SecurityOrchestration|Policies"
msgstr ""
+msgid "SecurityOrchestration|Policy Type"
+msgstr ""
+
msgid "SecurityOrchestration|Policy cannot be enabled for non-existing branches (%{branches})"
msgstr ""
@@ -31902,10 +32590,13 @@ msgstr ""
msgid "SecurityOrchestration|Require %{approvals} %{plural} from %{approvers} if any of the following occur:"
msgstr ""
-msgid "SecurityOrchestration|Rule"
+msgid "SecurityOrchestration|Rules"
msgstr ""
-msgid "SecurityOrchestration|Rules"
+msgid "SecurityOrchestration|Runs %{actions} and %{lastAction} scans"
+msgstr ""
+
+msgid "SecurityOrchestration|Runs a %{action} scan"
msgstr ""
msgid "SecurityOrchestration|Scan Execution"
@@ -31965,6 +32656,9 @@ msgstr ""
msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
+msgid "SecurityOrchestration|This view only shows scan results for the agent %{agent}. You can view scan results for all agents in the %{linkStart}Operational Vulnerabilities tab of the vulnerability report%{linkEnd}."
+msgstr ""
+
msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
@@ -32019,9 +32713,6 @@ msgstr ""
msgid "SecurityOrchestration|users with ids"
msgstr ""
-msgid "SecurityOrchestration|view results"
-msgstr ""
-
msgid "SecurityOrchestration|vulnerabilities"
msgstr ""
@@ -32691,22 +33382,19 @@ 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|In order to start using functions as a service, you must first install Knative on your Kubernetes cluster. %{linkStart}More information%{linkEnd}"
-msgstr ""
-
msgid "Serverless|Learn more about Serverless"
msgstr ""
msgid "Serverless|No functions available"
msgstr ""
-msgid "Serverless|Sign up for First Look"
+msgid "Serverless|Serverless was %{linkStart}deprecated%{linkEnd} in GitLab 14.3."
+msgstr ""
+
+msgid "Serverless|Serverless was %{postLinkStart}deprecated%{postLinkEnd}. But if you opt to use it, you must install Knative in your Kubernetes cluster first. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "Serverless|The deploy job has not finished."
@@ -32718,9 +33406,6 @@ 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 ""
@@ -32736,9 +33421,6 @@ msgstr ""
msgid "Service Account Key"
msgstr ""
-msgid "Service Accounts"
-msgstr ""
-
msgid "Service Accounts keys authorize GitLab to deploy your Google Cloud project"
msgstr ""
@@ -32748,10 +33430,10 @@ msgstr ""
msgid "Service Desk allows people to create issues in your GitLab instance without their own user account. It provides a unique email address for end users to create issues in a project. Replies can be sent either through the GitLab interface or by email. End users only see threads through email."
msgstr ""
-msgid "Service Usage Data"
+msgid "Service account generated successfully"
msgstr ""
-msgid "Service account generated successfully"
+msgid "Service accounts"
msgstr ""
msgid "Service ping is disabled in your configuration file, and cannot be enabled through this form."
@@ -32895,6 +33577,9 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
+msgid "Set the per-user rate limit for getting a user by ID via the API."
+msgstr ""
+
msgid "Set the per-user rate limit for notes created by web or API requests."
msgstr ""
@@ -33074,6 +33759,9 @@ msgstr ""
msgid "Shared runners details"
msgstr ""
+msgid "Shared runners enabled cannot be enabled until a valid credit card is on file"
+msgstr ""
+
msgid "Shared runners help link"
msgstr ""
@@ -33131,6 +33819,9 @@ msgstr ""
msgid "Show all issues."
msgstr ""
+msgid "Show all milestones"
+msgstr ""
+
msgid "Show all test cases."
msgstr ""
@@ -33167,6 +33858,9 @@ msgstr ""
msgid "Show file contents"
msgstr ""
+msgid "Show group milestones"
+msgstr ""
+
msgid "Show labels"
msgstr ""
@@ -33182,6 +33876,12 @@ msgstr ""
msgid "Show open epics"
msgstr ""
+msgid "Show project milestones"
+msgstr ""
+
+msgid "Show sub-group milestones"
+msgstr ""
+
msgid "Show the Closed list"
msgstr ""
@@ -33191,11 +33891,6 @@ msgstr ""
msgid "Show whitespace changes"
msgstr ""
-msgid "Showing %d event"
-msgid_plural "Showing %d events"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Showing %{conflict} between %{sourceBranch} and %{targetBranch}"
msgstr ""
@@ -33255,12 +33950,6 @@ msgstr ""
msgid "Sidebar|None"
msgstr ""
-msgid "Sidebar|Only numeral characters allowed"
-msgstr ""
-
-msgid "Sidebar|Weight"
-msgstr ""
-
msgid "Sidekiq job compression threshold (bytes)"
msgstr ""
@@ -33423,6 +34112,9 @@ msgstr ""
msgid "Slack logo"
msgstr ""
+msgid "SlackIntegration|Are you sure you want to remove this project from the Slack application?"
+msgstr ""
+
msgid "SlackIntegration|GitLab for Slack"
msgstr ""
@@ -33432,6 +34124,9 @@ msgstr ""
msgid "SlackIntegration|Project alias"
msgstr ""
+msgid "SlackIntegration|Remove project"
+msgstr ""
+
msgid "SlackIntegration|Select a GitLab project to link with your Slack workspace."
msgstr ""
@@ -33576,9 +34271,6 @@ msgstr ""
msgid "Something went wrong trying to load issue contacts."
msgstr ""
-msgid "Something went wrong when creating a work item. Please try again"
-msgstr ""
-
msgid "Something went wrong when reordering designs. Please try again"
msgstr ""
@@ -33672,9 +34364,6 @@ msgstr ""
msgid "Something went wrong while inserting your image. Please try again."
msgstr ""
-msgid "Something went wrong while merging this merge request. Please try again."
-msgstr ""
-
msgid "Something went wrong while obtaining the Let's Encrypt certificate."
msgstr ""
@@ -33996,10 +34685,10 @@ 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."
+msgid "SourcegraphAdmin|Learn more."
msgstr ""
-msgid "SourcegraphAdmin|More information"
+msgid "SourcegraphAdmin|Only public projects have code intelligence enabled and communicate with Sourcegraph."
msgstr ""
msgid "SourcegraphAdmin|Save changes"
@@ -34008,7 +34697,7 @@ msgstr ""
msgid "SourcegraphAdmin|Sourcegraph URL"
msgstr ""
-msgid "SourcegraphAdmin|e.g. https://sourcegraph.example.com"
+msgid "SourcegraphAdmin|https://sourcegraph.example.com"
msgstr ""
msgid "SourcegraphPreferences|This feature is experimental and currently limited to certain projects."
@@ -34143,6 +34832,9 @@ msgstr ""
msgid "Start date"
msgstr ""
+msgid "Start free trial"
+msgstr ""
+
msgid "Start merge train"
msgstr ""
@@ -34173,6 +34865,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started escalation for this incident."
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -34185,6 +34880,9 @@ msgstr ""
msgid "Starts at (UTC)"
msgstr ""
+msgid "Starts escalations for this incident"
+msgstr ""
+
msgid "Starts on"
msgstr ""
@@ -34446,6 +35144,9 @@ msgstr ""
msgid "Strikethrough"
msgstr ""
+msgid "Strikethrough text"
+msgstr ""
+
msgid "Subgroup information"
msgstr ""
@@ -34680,6 +35381,21 @@ msgstr ""
msgid "Subscriptions"
msgstr ""
+msgid "Subscriptions|Chat with sales"
+msgstr ""
+
+msgid "Subscriptions|Close"
+msgstr ""
+
+msgid "Subscriptions|Not ready to buy yet?"
+msgstr ""
+
+msgid "Subscriptions|Start a free trial"
+msgstr ""
+
+msgid "Subscriptions|We understand. Maybe you have some questions for our sales team, or maybe you'd like to try some of the paid features first. What would you like to do?"
+msgstr ""
+
msgid "Subscription|Your subscription for %{strong}%{namespace_name}%{strong_close} has expired and you are now on %{pricing_link_start}the GitLab Free tier%{pricing_link_end}. Don't worry, your data is safe. Get in touch with our support team (%{support_email}). They'll gladly help with your subscription renewal."
msgstr ""
@@ -34890,6 +35606,9 @@ msgstr ""
msgid "SuperSonics|Maximum users"
msgstr ""
+msgid "SuperSonics|Offline cloud"
+msgstr ""
+
msgid "SuperSonics|Paste your activation code"
msgstr ""
@@ -34956,6 +35675,12 @@ msgstr ""
msgid "SuperSonics|You do not have an active subscription"
msgstr ""
+msgid "SuperSonics|You have a future dated license"
+msgstr ""
+
+msgid "SuperSonics|You have added a license that activates on %{date}. Please see the subscription history table below for more details."
+msgstr ""
+
msgid "SuperSonics|You have successfully added a license that activates on %{date}. Please see the subscription history table below for more details."
msgstr ""
@@ -35115,6 +35840,9 @@ msgstr ""
msgid "Tag name is required"
msgstr ""
+msgid "Tag push"
+msgstr ""
+
msgid "Tag push events"
msgstr ""
@@ -35217,6 +35945,9 @@ msgstr ""
msgid "TagsPage|protected"
msgstr ""
+msgid "Take a look at the documentation to discover all of GitLab’s capabilities."
+msgstr ""
+
msgid "Target Branch"
msgstr ""
@@ -35619,6 +36350,9 @@ msgstr ""
msgid "Tests"
msgstr ""
+msgid "Text (optional)"
+msgstr ""
+
msgid "Text added to the body of all email messages. %{character_limit} character limit"
msgstr ""
@@ -35669,6 +36403,9 @@ msgstr ""
msgid "The CSV export will be created in the background. Once finished, it will be sent to %{email} in an attachment."
msgstr ""
+msgid "The CSV export you requested of all user memberships is attached to this email."
+msgstr ""
+
msgid "The GitLab subscription service (customers.gitlab.com) is currently experiencing an outage. You can monitor the status and get updates at %{linkStart}status.gitlab.com%{linkEnd}."
msgstr ""
@@ -35744,6 +36481,9 @@ 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 epic"
+msgstr ""
+
msgid "The current issue"
msgstr ""
@@ -35905,6 +36645,9 @@ msgstr ""
msgid "The latest pipeline for this merge request has failed."
msgstr ""
+msgid "The license key is invalid."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -35920,6 +36663,9 @@ msgstr ""
msgid "The license was successfully uploaded and will be active from %{starts_at}. You can see the details below."
msgstr ""
+msgid "The license you uploaded is invalid. If the issue persists, contact support at %{link}."
+msgstr ""
+
msgid "The list creation wizard is already open"
msgstr ""
@@ -36541,10 +37287,13 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} and everything this project contains. %{strongOpen}There is no going back%{strongClose}"
+msgstr ""
+
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains."
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}on %{date}%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains. %{strongOpen}There is no going back.%{strongClose}"
msgstr ""
msgid "This action will %{strongOpen}permanently remove%{strongClose} %{codeOpen}%{group}%{codeClose} %{strongOpen}immediately%{strongClose}."
@@ -36673,9 +37422,6 @@ msgstr ""
msgid "This file was modified for readability, and can't accept suggestions. Edit it directly."
msgstr ""
-msgid "This forked project has the following:"
-msgstr ""
-
msgid "This form is disabled in preview"
msgstr ""
@@ -36688,7 +37434,7 @@ msgstr ""
msgid "This group can't be removed because it is linked to a subscription. To remove this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
-msgid "This group can't be transfered because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
+msgid "This group can't be transferred because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
msgid "This group cannot be invited to a project inside a group with enforced SSO"
@@ -36715,6 +37461,9 @@ 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 incident is already escalated with '%{escalation_policy_name}'."
+msgstr ""
+
msgid "This invitation was sent to %{mail_to_invite_email}, but you are signed in as %{link_to_current_user} with email %{mail_to_current_user}."
msgstr ""
@@ -36733,9 +37482,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 merge train pipeline"
-msgstr ""
-
msgid "This is a private email address %{helpIcon} generated just for you. Anyone who has it can create issues or merge requests as if they were you. If that happens, %{resetLinkStart}reset this token%{resetLinkEnd}."
msgstr ""
@@ -36757,6 +37503,12 @@ msgstr ""
msgid "This is your current session"
msgstr ""
+msgid "This issue cannot be assigned to a confidential epic because it is public."
+msgstr ""
+
+msgid "This issue cannot be made public because it belongs to a confidential epic."
+msgstr ""
+
msgid "This issue is confidential and should only be visible to team members with at least Reporter access."
msgstr ""
@@ -36874,6 +37626,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 branch is protected from force push."
+msgstr ""
+
msgid "This merge request cannot be rebased while there are conflicts."
msgstr ""
@@ -36925,9 +37680,15 @@ msgstr ""
msgid "This pipeline was triggered by a schedule."
msgstr ""
+msgid "This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project"
msgstr ""
+msgid "This project can be restored until %{date}."
+msgstr ""
+
msgid "This project cannot be %{visibilityLevel} because the visibility of %{openShowLink}%{name}%{closeShowLink} is %{visibility}. To make this project %{visibilityLevel}, you must first %{openEditLink}change the visibility%{closeEditLink} of the parent group."
msgstr ""
@@ -36946,6 +37707,9 @@ msgstr ""
msgid "This project is %{strongStart}NOT%{strongEnd} a fork, and has the following:"
msgstr ""
+msgid "This project is %{strongStart}NOT%{strongEnd} a fork. This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -37637,6 +38401,9 @@ msgstr ""
msgid "Today"
msgstr ""
+msgid "Todos count"
+msgstr ""
+
msgid "Todos|Are you looking for things to do? Take a look at %{strongStart}%{openIssuesLinkStart}open issues%{openIssuesLinkEnd}%{strongEnd}, contribute to %{strongStart}%{mergeRequestLinkStart}a merge request%{mergeRequestLinkEnd}%{mergeRequestLinkEnd}%{strongEnd}, or mention someone in a comment to automatically assign them a new to-do item."
msgstr ""
@@ -37910,10 +38677,8 @@ msgstr ""
msgid "Trending"
msgstr ""
-msgid "Trials|%{planName} Trial %{enDash} %{num} day left"
-msgid_plural "Trials|%{planName} Trial %{enDash} %{num} days left"
-msgstr[0] ""
-msgstr[1] ""
+msgid "Trials|%{planName} Trial"
+msgstr ""
msgid "Trials|Compare all plans"
msgstr ""
@@ -37921,6 +38686,9 @@ msgstr ""
msgid "Trials|Create a new group to start your GitLab Ultimate trial."
msgstr ""
+msgid "Trials|Day %{daysUsed}/%{duration}"
+msgstr ""
+
msgid "Trials|Go back to GitLab"
msgstr ""
@@ -38170,7 +38938,7 @@ msgstr ""
msgid "URL is triggered when repository is updated"
msgstr ""
-msgid "URL must be percent-encoded if neccessary."
+msgid "URL must be percent-encoded if necessary."
msgstr ""
msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
@@ -38389,6 +39157,9 @@ msgstr ""
msgid "Unlock account"
msgstr ""
+msgid "Unlock more features with GitLab Ultimate"
+msgstr ""
+
msgid "Unlock the discussion"
msgstr ""
@@ -38452,6 +39223,9 @@ msgstr ""
msgid "Unsubscribes from this %{quick_action_target}."
msgstr ""
+msgid "Unsupported sort value."
+msgstr ""
+
msgid "Unsupported todo type passed. Supported todo types are: %{todo_types}"
msgstr ""
@@ -38680,6 +39454,9 @@ msgstr ""
msgid "UsageQuota|File attachments and smaller design graphics."
msgstr ""
+msgid "UsageQuota|From %{storage_enforcement_date} storage limits will apply to this namespace. View and manage your usage in %{strong_start}Group Settings &gt; Usage quotas%{strong_end}."
+msgstr ""
+
msgid "UsageQuota|Git repository."
msgstr ""
@@ -38740,6 +39517,9 @@ msgstr ""
msgid "UsageQuota|Storage type"
msgstr ""
+msgid "UsageQuota|Storage used"
+msgstr ""
+
msgid "UsageQuota|This is the total amount of storage used across your projects within this namespace."
msgstr ""
@@ -38935,6 +39715,12 @@ msgstr ""
msgid "Use hashed storage paths for newly created and renamed repositories. Always enabled since 13.0."
msgstr ""
+msgid "Use issue count"
+msgstr ""
+
+msgid "Use issue weight"
+msgstr ""
+
msgid "Use one line per URI"
msgstr ""
@@ -39316,6 +40102,9 @@ msgstr ""
msgid "Users"
msgstr ""
+msgid "Users API rate limit"
+msgstr ""
+
msgid "Users can launch a development environment from a GitLab browser tab when the %{linkStart}Gitpod%{linkEnd} integration is enabled."
msgstr ""
@@ -39641,6 +40430,9 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View group pipeline usage quota"
+msgstr ""
+
msgid "View incident details at"
msgstr ""
@@ -39793,6 +40585,9 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
+msgid "Vulnerability"
+msgstr ""
+
msgid "Vulnerability Report"
msgstr ""
@@ -39844,6 +40639,9 @@ msgstr ""
msgid "VulnerabilityManagement|An unverified non-confirmed finding"
msgstr ""
+msgid "VulnerabilityManagement|At least one identifier is required"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -39853,12 +40651,24 @@ msgstr ""
msgid "VulnerabilityManagement|Create Jira issue"
msgstr ""
+msgid "VulnerabilityManagement|Enter a name"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE code"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE identifier URL"
+msgstr ""
+
msgid "VulnerabilityManagement|Fetching linked Jira issues"
msgstr ""
msgid "VulnerabilityManagement|Manually add a vulnerability entry into the vulnerability report."
msgstr ""
+msgid "VulnerabilityManagement|Name is a required field"
+msgstr ""
+
msgid "VulnerabilityManagement|Needs triage"
msgstr ""
@@ -39874,6 +40684,18 @@ msgstr ""
msgid "VulnerabilityManagement|Select a method"
msgstr ""
+msgid "VulnerabilityManagement|Select a severity level"
+msgstr ""
+
+msgid "VulnerabilityManagement|Select a status"
+msgstr ""
+
+msgid "VulnerabilityManagement|Severity is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Something went wrong while creating vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -39898,6 +40720,12 @@ msgstr ""
msgid "VulnerabilityManagement|Something went wrong, could not update vulnerability state."
msgstr ""
+msgid "VulnerabilityManagement|Status is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Submit vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Summary, detailed description, steps to reproduce, etc."
msgstr ""
@@ -40093,6 +40921,9 @@ msgstr ""
msgid "WARNING:"
msgstr ""
+msgid "WARNING: This snippet contains hidden files which might be used to mask malicious behavior. Exercise caution if cloning and executing code from this snippet."
+msgstr ""
+
msgid "Wait for the file to load to copy its contents"
msgstr ""
@@ -40312,6 +41143,15 @@ msgstr ""
msgid "Webhooks|An issue is created, updated, closed, or reopened."
msgstr ""
+msgid "Webhooks|Are you sure you want to delete this group hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this project hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this webhook?"
+msgstr ""
+
msgid "Webhooks|Comments"
msgstr ""
@@ -40321,6 +41161,9 @@ msgstr ""
msgid "Webhooks|Confidential issues events"
msgstr ""
+msgid "Webhooks|Delete webhook"
+msgstr ""
+
msgid "Webhooks|Deployment events"
msgstr ""
@@ -40554,6 +41397,9 @@ msgstr ""
msgid "Wiki"
msgstr ""
+msgid "Wiki page"
+msgstr ""
+
msgid "Wiki page was successfully created."
msgstr ""
@@ -40659,7 +41505,7 @@ msgstr ""
msgid "WikiPageConflictMessage|Someone edited the page the same time you did. Please check out %{wikiLinkStart}the page%{wikiLinkEnd} and make sure your changes will not unintentionally remove theirs."
msgstr ""
-msgid "WikiPage|An error occured while trying to render the content editor. Please try again later."
+msgid "WikiPage|An error occurred while trying to render the content editor. Please try again later."
msgstr ""
msgid "WikiPage|Are you sure you want to switch back to the classic editor?"
@@ -40818,6 +41664,18 @@ msgstr ""
msgid "WorkItem|New Task"
msgstr ""
+msgid "WorkItem|Something went wrong when creating a work item. Please try again"
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching the work item. Please try again."
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching work item types. Please try again"
+msgstr ""
+
+msgid "WorkItem|Type"
+msgstr ""
+
msgid "WorkItem|Work Items"
msgstr ""
@@ -40884,7 +41742,10 @@ msgstr ""
msgid "You are about to add %{usersTag} people to the discussion. They will all receive a notification."
msgstr ""
-msgid "You are about to permanently delete this project"
+msgid "You are about to delete this forked project containing:"
+msgstr ""
+
+msgid "You are about to delete this project containing:"
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."
@@ -40905,6 +41766,9 @@ msgstr ""
msgid "You are attempting to update a file that has changed since you started editing it."
msgstr ""
+msgid "You are billed if you exceed this number. %{qsrOverageLinkStart}How does billing work?%{qsrOverageLinkEnd}"
+msgstr ""
+
msgid "You are connected to the Prometheus server, but there is currently no data to display."
msgstr ""
@@ -40962,6 +41826,9 @@ msgstr ""
msgid "You are not authorized to update this scanner profile"
msgstr ""
+msgid "You are not authorized to upload metric images"
+msgstr ""
+
msgid "You are now impersonating %{username}"
msgstr ""
@@ -41115,9 +41982,6 @@ msgstr ""
msgid "You can only upload one design when dropping onto an existing design."
msgstr ""
-msgid "You can recover this project until %{date}"
-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 ""
@@ -41166,9 +42030,6 @@ msgstr ""
msgid "You cannot write to this read-only GitLab instance."
msgstr ""
-msgid "You can’t %{tag_start}edit%{tag_end} files directly in this project. Fork this project and submit a merge request with your changes."
-msgstr ""
-
msgid "You can’t edit files directly in this project. Fork this project and submit a merge request with your changes."
msgstr ""
@@ -41321,9 +42182,6 @@ 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 set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
@@ -41354,12 +42212,6 @@ msgstr ""
msgid "You must have maintainer access to force delete a lock"
msgstr ""
-msgid "You must have permission to create a project in a group before forking."
-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 ""
@@ -41765,7 +42617,7 @@ msgstr ""
msgid "Your public email will be displayed on your public profile."
msgstr ""
-msgid "Your request for access could not be processed: %{error_meesage}"
+msgid "Your request for access could not be processed: %{error_message}"
msgstr ""
msgid "Your request for access has been queued for review."
@@ -41948,6 +42800,9 @@ msgstr ""
msgid "archived:"
msgstr ""
+msgid "artifacts"
+msgstr ""
+
msgid "assign yourself"
msgstr ""
@@ -41977,6 +42832,9 @@ msgstr[1] ""
msgid "branch name"
msgstr ""
+msgid "builds"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -42400,6 +43258,9 @@ msgstr ""
msgid "contact with same email already exists in group hierarchy"
msgstr ""
+msgid "container registry images"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -42439,6 +43300,9 @@ msgstr ""
msgid "data"
msgstr ""
+msgid "database"
+msgstr ""
+
msgid "date must not be after 9999-12-31"
msgstr ""
@@ -42462,9 +43326,6 @@ msgstr ""
msgid "design"
msgstr ""
-msgid "detached"
-msgstr ""
-
msgid "disabled"
msgstr ""
@@ -42713,7 +43574,7 @@ msgstr ""
msgid "is not a valid X509 certificate."
msgstr ""
-msgid "is not allowed for sign-up."
+msgid "is not allowed for sign-up. Please use your regular email address."
msgstr ""
msgid "is not allowed for this group."
@@ -42725,7 +43586,7 @@ msgstr ""
msgid "is not allowed since the group is not top-level group."
msgstr ""
-msgid "is not allowed."
+msgid "is not allowed. Please use your regular email address."
msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
@@ -42812,6 +43673,9 @@ msgstr ""
msgid "level: %{level}"
msgstr ""
+msgid "lfs objects"
+msgstr ""
+
msgid "limit of %{project_limit} reached"
msgstr ""
@@ -43031,6 +43895,9 @@ msgstr ""
msgid "mrWidget|Merge blocked: pipeline must succeed. It's waiting for a manual action to continue."
msgstr ""
+msgid "mrWidget|Merge blocked: pipeline must succeed. Push a commit that fixes the failure, or %{linkStart}learn about other solutions.%{linkEnd}"
+msgstr ""
+
msgid "mrWidget|Merge blocked: this merge request must be approved."
msgstr ""
@@ -43148,9 +44015,6 @@ msgstr ""
msgid "mrWidget|The changes were not merged into"
msgstr ""
-msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -43298,9 +44162,6 @@ msgstr ""
msgid "open issue"
msgstr ""
-msgid "opened %{timeAgo}"
-msgstr ""
-
msgid "or"
msgstr ""
@@ -43312,6 +44173,12 @@ msgid_plural "out of %d total tests"
msgstr[0] ""
msgstr[1] ""
+msgid "packages"
+msgstr ""
+
+msgid "pages"
+msgstr ""
+
msgid "parent"
msgid_plural "parents"
msgstr[0] ""
@@ -43461,6 +44328,9 @@ msgid_plural "replies"
msgstr[0] ""
msgstr[1] ""
+msgid "repositories"
+msgstr ""
+
msgid "repository:"
msgstr ""
@@ -43581,12 +44451,18 @@ msgstr ""
msgid "tag name"
msgstr ""
+msgid "terraform states"
+msgstr ""
+
msgid "the correct format."
msgstr ""
msgid "the file"
msgstr ""
+msgid "the following epic(s)"
+msgstr ""
+
msgid "the following issue(s)"
msgstr ""
@@ -43599,21 +44475,12 @@ msgstr ""
msgid "this document"
msgstr ""
-msgid "this issue cannot be assigned to a confidential epic since it is public"
-msgstr ""
-
-msgid "this issue cannot be made public since it belongs to a confidential epic"
-msgstr ""
-
msgid "time summary"
msgstr ""
msgid "toggle collapse"
msgstr ""
-msgid "train"
-msgstr ""
-
msgid "triggered"
msgstr ""
@@ -43742,3 +44609,6 @@ msgstr ""
msgid "{project}"
msgstr ""
+msgid "✔"
+msgstr ""
+
diff --git a/locale/nb_NO/gitlab.po b/locale/nb_NO/gitlab.po
index fd0a4e25ba1..c78e94aaa5f 100644
--- a/locale/nb_NO/gitlab.po
+++ b/locale/nb_NO/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: nb\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2022-02-02 15:48\n"
+"PO-Revision-Date: 2022-03-01 20:40\n"
msgid " %{start} to %{end}"
msgstr " %{start} til %{end}"
@@ -146,6 +146,11 @@ msgid_plural "%d approvers (you've approved)"
msgstr[0] "%d godkjenner (du har godkjent)"
msgstr[1] "%d godkjennere (du har godkjent)"
+msgid "%d assigned issue"
+msgid_plural "%d assigned issues"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] "%d endret fil"
@@ -421,10 +426,25 @@ msgid_plural "%d vulnerabilities dismissed"
msgstr[0] "%d sårbarhet avvist"
msgstr[1] "%d sårbarheter avvist"
-msgid "%d vulnerability updated"
-msgid_plural "%d vulnerabilities updated"
-msgstr[0] "%d sårbarhet oppdatert"
-msgstr[1] "%d sårbarheter oppdatert"
+msgid "%d vulnerability set to confirmed"
+msgid_plural "%d vulnerabilities set to confirmed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to dismissed"
+msgid_plural "%d vulnerabilities set to dismissed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to needs triage"
+msgid_plural "%d vulnerabilities set to needs triage"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to resolved"
+msgid_plural "%d vulnerabilities set to resolved"
+msgstr[0] ""
+msgstr[1] ""
msgid "%d warning found:"
msgid_plural "%d warnings found:"
@@ -510,6 +530,12 @@ msgstr[1] "%{completedCount} av %{count} oppgaver fullført"
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr "%{completedWeight} av %{totalWeight} vektlegging fullført"
+msgid "%{completed} of %{total} issues closed"
+msgstr ""
+
+msgid "%{completed} of %{total} weight completed"
+msgstr ""
+
msgid "%{cores} cores"
msgstr "%{cores} kjerner"
@@ -858,6 +884,9 @@ msgstr "%{openedEpics} åpne, %{closedEpics} lukket"
msgid "%{openedIssues} open, %{closedIssues} closed"
msgstr "%{openedIssues} åpne, %{closedIssues} lukket"
+msgid "%{percentage}%% issues closed"
+msgstr ""
+
msgid "%{percentage}%% weight completed"
msgstr "%{percentage}%% vektlegging fullført"
@@ -1287,6 +1316,9 @@ msgid_plural "- Users"
msgstr[0] "- Bruker"
msgstr[1] "- Brukere"
+msgid "- of - issues closed"
+msgstr ""
+
msgid "- of - weight completed"
msgstr "- av - vektlegging fullført"
@@ -1429,7 +1461,7 @@ msgstr "10-19 bidrag"
msgid "1000+"
msgstr "1000+"
-msgid "192.168.0.0/24"
+msgid "192.168.0.0/24 or 2001:0DB8:1234::/48"
msgstr ""
msgid "1st contribution!"
@@ -1741,13 +1773,13 @@ msgstr "folder/openapi.json"
msgid "AWS Access Key"
msgstr "AWS tilgangsnøkkel"
-msgid "AWS Access Key. Only required if not using role instance credentials"
-msgstr ""
-
msgid "AWS Secret Access Key"
msgstr "AWS hemmelig tilgangsnøkkel"
-msgid "AWS Secret Access Key. Only required if not using role instance credentials"
+msgid "AWS access key ID (Optional)"
+msgstr ""
+
+msgid "AWS secret access key (Optional)"
msgstr ""
msgid "AWS service error: %{error}"
@@ -1807,9 +1839,6 @@ msgstr "Tilgang nektet. Sjekk ditt tilgangsnivå."
msgid "Access granted"
msgstr "Tilgang gitt"
-msgid "Access key ID"
-msgstr ""
-
msgid "Access requests"
msgstr ""
@@ -1984,7 +2013,7 @@ msgstr ""
msgid "Activity"
msgstr "Aktivitet"
-msgid "Activity|An error occured while retrieving activity. Reload the page to try again."
+msgid "Activity|An error occurred while retrieving activity. Reload the page to try again."
msgstr ""
msgid "Add"
@@ -2023,6 +2052,9 @@ msgstr "Legg til Zoom-møte"
msgid "Add a %{type}"
msgstr "Legg til en %{type}"
+msgid "Add a GCP region"
+msgstr ""
+
msgid "Add a GPG key"
msgstr "Legg til en GPG-nøkkel"
@@ -2074,6 +2106,9 @@ msgstr "Legg til en ny sak"
msgid "Add a numbered list"
msgstr "Legg til en nummerert liste"
+msgid "Add a related epic"
+msgstr ""
+
msgid "Add a related issue"
msgstr "Legg til en related sak"
@@ -2188,6 +2223,9 @@ msgstr "Legg til eller fjern tidligere innflettede commits"
msgid "Add or subtract spent time"
msgstr "Legg til eller trekk fra brukt tid"
+msgid "Add people"
+msgstr ""
+
msgid "Add previously merged commits"
msgstr "Legg til tidligere innflettede commiter"
@@ -2254,6 +2292,9 @@ msgstr ""
msgid "Add webhook"
msgstr "Legg til Webhook"
+msgid "Add your team members and others to GitLab."
+msgstr ""
+
msgid "Add/remove"
msgstr "Legg til/Fjern"
@@ -3076,12 +3117,6 @@ msgstr "Avanserte eksportinnstillinger"
msgid "AdvancedSearch|Reindex required"
msgstr ""
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. Permanently deleting this project will %{strongStart}immediately delete%{strongEnd} its repositories and %{strongStart}all related resources%{strongEnd}, including issues, merge requests etc."
-msgstr ""
-
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. You will lose this project's repository and %{strongStart}all related resources%{strongEnd}, including issues and merge requests."
-msgstr ""
-
msgid "After a successful password update you will be redirected to login screen."
msgstr "Etter en vellykket passordoppdatering vil du bli omdirigert til påloggingsskjermen."
@@ -3112,6 +3147,9 @@ msgstr "Akismet-API-nøkkel"
msgid "Akismet helps prevent the creation of spam issues in public projects."
msgstr ""
+msgid "Alert"
+msgstr ""
+
msgid "AlertManagement|Acknowledged"
msgstr "Anerkjent"
@@ -3484,9 +3522,6 @@ msgstr "Alle e-postadressene vil bli brukt til å identifisere dine commiter."
msgid "All environments"
msgstr "Alle miljøer"
-msgid "All epics"
-msgstr "Alle eposer"
-
msgid "All groups and projects"
msgstr "Alle grupper og prosjekter"
@@ -4223,12 +4258,15 @@ msgstr ""
msgid "ApplicationSettings|Approve users in the pending approval status?"
msgstr ""
-msgid "ApplicationSettings|By making this change, you will automatically approve %d user with the pending approval status."
-msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users with the pending approval status."
+msgid "ApplicationSettings|Approve users who are pending approval?"
+msgstr ""
+
+msgid "ApplicationSettings|By making this change, you will automatically approve %d user who is pending approval."
+msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users who are pending approval."
msgstr[0] ""
msgstr[1] ""
-msgid "ApplicationSettings|By making this change, you will automatically approve all users in pending approval status."
+msgid "ApplicationSettings|By making this change, you will automatically approve all users who are pending approval."
msgstr ""
msgid "ApplicationSettings|Denied domains for sign-ups"
@@ -4634,12 +4672,12 @@ msgstr "Arkiverte prosjekter"
msgid "Archiving the project will make it entirely read-only. It is hidden from the dashboard and doesn't show up in searches. %{strong_start}The repository cannot be committed to, and no issues, comments, or other entities can be created.%{strong_end} %{link_start}Learn more.%{link_end}"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to delete this project?"
-msgstr "Er du HELT SIKKER på at du vil slette dette prosjektet?"
-
msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
msgstr "Er du HELT SIKKER på at du vil fjerne denne gruppen?"
+msgid "Are you absolutely sure?"
+msgstr ""
+
msgid "Are you sure that you want to archive this project?"
msgstr "Er du sikker på at du vil arkivere dette prosjektet?"
@@ -4673,12 +4711,18 @@ msgstr "Er du sikker på at du vil slette denne %{typeOfComment}?"
msgid "Are you sure you want to delete this SSH key?"
msgstr "Er du sikker på at du vil slette denne SSH-nøkkelen?"
+msgid "Are you sure you want to delete this comment?"
+msgstr ""
+
msgid "Are you sure you want to delete this deploy key?"
msgstr ""
msgid "Are you sure you want to delete this device? This action cannot be undone."
msgstr "Er du sikker på at du vil slette denne enheten? Denne handlingen kan ikke angres på."
+msgid "Are you sure you want to delete this label?"
+msgstr ""
+
msgid "Are you sure you want to delete this pipeline schedule?"
msgstr "Er du sikker på at du vil slette denne rørledningsplanleggingen?"
@@ -4694,9 +4738,6 @@ msgstr "Er du sikker på at du vil forkaste denne kommentaren?"
msgid "Are you sure you want to discard your changes?"
msgstr ""
-msgid "Are you sure you want to erase this build?"
-msgstr "Er du sikker på at du vil slette denne byggversjonen?"
-
msgid "Are you sure you want to import %d repository?"
msgid_plural "Are you sure you want to import %d repositories?"
msgstr[0] "Er du sikker på at du vil importere %d kodelager?"
@@ -4744,6 +4785,9 @@ msgstr "Er du sikker på at du vil fjerne denne identiteten?"
msgid "Are you sure you want to remove this list?"
msgstr "Er du sikker på at du vil fjerne denne listen?"
+msgid "Are you sure you want to remove this nickname?"
+msgstr ""
+
msgid "Are you sure you want to reset the health check token?"
msgstr "Er du sikker du vil tilbakestille helsesjekksjetongen?"
@@ -4756,12 +4800,12 @@ msgstr ""
msgid "Are you sure you want to revoke this %{type}? This action cannot be undone."
msgstr "Er du sikker på at du vil trekke tilbake denne %{type}? Denne handlingen kan ikke angres på."
-msgid "Are you sure you want to revoke this nickname?"
-msgstr "Er du sikker på at du vil trekke tilbake dette kallenavnet?"
-
msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
msgstr ""
+msgid "Are you sure you want to revoke this project access token? This action cannot be undone."
+msgstr ""
+
msgid "Are you sure you want to stop this environment?"
msgstr "Er du sikker på at du vil stoppe dette miljøet?"
@@ -4906,9 +4950,6 @@ msgstr "Tilordnet til %{assigneeName}"
msgid "Assigned to %{assignee_name}"
msgstr "Tilordnet til %{assignee_name}"
-msgid "Assigned to %{name}"
-msgstr "Tilordnet til %{name}"
-
msgid "Assigned to me"
msgstr "Tilordnet meg"
@@ -4973,6 +5014,9 @@ msgstr[1] "Legger ved %d filer"
msgid "Attaching the file failed."
msgstr "Vedlegging av filen mislyktes."
+msgid "Attention"
+msgstr ""
+
msgid "Audit Events"
msgstr ""
@@ -5135,6 +5179,12 @@ msgstr "Autorisert den"
msgid "Authorized applications (%{size})"
msgstr "Autoriserte applikasjoner (%{size})"
+msgid "AuthorizedApplication|Are you sure you want to revoke this application?"
+msgstr ""
+
+msgid "AuthorizedApplication|Revoke application"
+msgstr ""
+
msgid "Authors: %{authors}"
msgstr "Skapere: %{authors}"
@@ -6328,6 +6378,9 @@ msgstr "Utgivelser"
msgid "CICDAnalytics|Shared Runners Usage"
msgstr ""
+msgid "CICDAnalytics|Shared runner pipeline minute duration by month"
+msgstr ""
+
msgid "CICDAnalytics|Shared runner usage"
msgstr ""
@@ -6469,6 +6522,9 @@ msgstr ""
msgid "Can create groups:"
msgstr "Kan opprette grupper:"
+msgid "Can not delete primary training"
+msgstr ""
+
msgid "Can't apply as the source branch was deleted."
msgstr "Kan ikke benytte det, siden kildegrenen ble slettet."
@@ -6802,9 +6858,6 @@ msgstr ""
msgid "Changing any setting here requires an application restart"
msgstr ""
-msgid "Changing group URL can have unintended side effects."
-msgstr "Endring av gruppe-URL-en kan ha utilsiktede bivirkninger."
-
msgid "Charts can't be displayed as the request for data has timed out. %{documentationLink}"
msgstr ""
@@ -6892,9 +6945,6 @@ msgstr "Sjekker godkjenningsstatusen"
msgid "Checking branch availability..."
msgstr "Kontrollerer grenens tilgjengelighet …"
-msgid "Checking group URL availability..."
-msgstr ""
-
msgid "Checking group path availability..."
msgstr ""
@@ -7388,6 +7438,9 @@ msgstr ""
msgid "Clear recent searches"
msgstr "Tøm nylige søk"
+msgid "Clear repository checks"
+msgstr ""
+
msgid "Clear search"
msgstr "Tøm søket"
@@ -7520,9 +7573,6 @@ msgstr "Lukket %{epicTimeagoDate}"
msgid "Closed MRs"
msgstr ""
-msgid "Closed epics"
-msgstr "Lukkede eposer"
-
msgid "Closed issues"
msgstr "Lukkede saker"
@@ -7559,13 +7609,13 @@ msgstr ""
msgid "Cluster level"
msgstr "Klynge-nivå"
-msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
+msgid "Cluster type must be specified for Stages::ClusterEndpointInserter"
msgstr ""
msgid "ClusterAgents|%{name} successfully deleted"
msgstr ""
-msgid "ClusterAgents|%{number} of %{total} Agents"
+msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
@@ -7607,6 +7657,15 @@ msgstr ""
msgid "ClusterAgents|Agent never connected to GitLab"
msgstr ""
+msgid "ClusterAgents|Agent version mismatch"
+msgstr ""
+
+msgid "ClusterAgents|Agent version mismatch and update"
+msgstr ""
+
+msgid "ClusterAgents|Agent version update required"
+msgstr ""
+
msgid "ClusterAgents|All"
msgstr ""
@@ -7631,7 +7690,7 @@ msgstr ""
msgid "ClusterAgents|Configuration"
msgstr "Oppsett"
-msgid "ClusterAgents|Connect a cluster through the Agent"
+msgid "ClusterAgents|Connect a cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connect existing cluster"
@@ -7640,13 +7699,13 @@ msgstr ""
msgid "ClusterAgents|Connect with a certificate"
msgstr ""
-msgid "ClusterAgents|Connect with agent"
+msgid "ClusterAgents|Connect with an agent"
msgstr ""
msgid "ClusterAgents|Connect with the GitLab Agent"
msgstr ""
-msgid "ClusterAgents|Connect your cluster through the Agent"
+msgid "ClusterAgents|Connect your cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connected"
@@ -7706,7 +7765,10 @@ msgstr ""
msgid "ClusterAgents|How to register an agent?"
msgstr ""
-msgid "ClusterAgents|Install new Agent"
+msgid "ClusterAgents|How to update an agent?"
+msgstr ""
+
+msgid "ClusterAgents|Install a new agent"
msgstr ""
msgid "ClusterAgents|Last connected %{timeAgo}."
@@ -7733,7 +7795,7 @@ msgstr "Aldri"
msgid "ClusterAgents|Never connected"
msgstr ""
-msgid "ClusterAgents|No Agents"
+msgid "ClusterAgents|No agents"
msgstr ""
msgid "ClusterAgents|No clusters connected through cluster certificates"
@@ -7793,6 +7855,9 @@ msgstr ""
msgid "ClusterAgents|The agent has not been connected in a long time. There might be a connectivity issue. Last contact was %{timeAgo}."
msgstr ""
+msgid "ClusterAgents|The agent version do not match each other across your cluster's pods. This can happen when a new agent version was just deployed and Kubernetes is shutting down the old pods."
+msgstr ""
+
msgid "ClusterAgents|The recommended installation method includes the token. If you want to follow the advanced installation method provided in the docs, make sure you save the token value before you close this window."
msgstr ""
@@ -7840,6 +7905,9 @@ msgstr ""
msgid "ClusterAgents|You will need to create a token to connect to your agent"
msgstr ""
+msgid "ClusterAgents|Your agent version is out of sync with your GitLab version (v%{version}), which might cause compatibility problems. Update the agent installed on your cluster to the most recent version."
+msgstr ""
+
msgid "ClusterAgents|Your instance doesn't have the %{linkStart}GitLab Agent Server (KAS)%{linkEnd} set up. Ask a GitLab Administrator to install it."
msgstr ""
@@ -8716,9 +8784,6 @@ msgstr "ComboSearch er ikke definert"
msgid "Comma-separated list of email addresses."
msgstr ""
-msgid "Comma-separated list of users allowed to exceed the rate limit."
-msgstr ""
-
msgid "Comma-separated, e.g. '1.1.1.1, 2.2.2.0/24'"
msgstr "Kommaseparert, f.eks. '1.1.1.1, 2.2.2.0/24'"
@@ -9045,6 +9110,12 @@ msgstr "Tillit"
msgid "Confidential"
msgstr "Konfidensiell"
+msgid "Confidential issue"
+msgstr ""
+
+msgid "Confidential note"
+msgstr ""
+
msgid "Confidentiality"
msgstr "Konfidensialitet"
@@ -9078,6 +9149,9 @@ msgstr ""
msgid "Configure Dependency Scanning in `.gitlab-ci.yml`, creating this file if it does not already exist"
msgstr ""
+msgid "Configure GitLab"
+msgstr ""
+
msgid "Configure GitLab runners to start using the Web Terminal. %{helpStart}Learn more.%{helpEnd}"
msgstr ""
@@ -9126,6 +9200,15 @@ msgstr "Sett opp eksisterende installasjon"
msgid "Configure pipelines to deploy web apps, backend services, APIs and static resources to Google Cloud"
msgstr ""
+msgid "Configure region"
+msgstr ""
+
+msgid "Configure region for environment"
+msgstr ""
+
+msgid "Configure regions"
+msgstr ""
+
msgid "Configure repository mirroring."
msgstr "Sett opp kodelagerspeiling."
@@ -9159,6 +9242,9 @@ msgstr ""
msgid "Configure which lists are shown for anyone who visits this board"
msgstr "Konfigurer hvilke lister som skal vises for alle som besøker dette bordet"
+msgid "Configure your environments to be deployed to specific geographical regions"
+msgstr ""
+
msgid "Confirm"
msgstr "Bekreft"
@@ -9861,10 +9947,10 @@ msgstr ""
msgid "CorpusManagement|Actions"
msgstr "Handlinger"
-msgid "CorpusManagement|Corpus are used in fuzz testing as mutation source to Improve future testing."
+msgid "CorpusManagement|Corpus file"
msgstr ""
-msgid "CorpusManagement|Corpus file"
+msgid "CorpusManagement|Corpus files are used in coverage-guided fuzz testing as seed inputs to improve testing."
msgstr ""
msgid "CorpusManagement|Corpus files must be in *.zip format. Maximum 5 GB"
@@ -9918,6 +10004,9 @@ msgstr ""
msgid "Could not apply %{name} command."
msgstr ""
+msgid "Could not apply %{name} command. %{message}."
+msgstr ""
+
msgid "Could not authorize chat nickname. Try again!"
msgstr "Klarte ikke å autorisere chat-kallenavnet. Prøv igjen!"
@@ -10068,6 +10157,9 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr "Opprett et Mattermost-team for denne gruppen"
+msgid "Create a group"
+msgstr ""
+
msgid "Create a merge request"
msgstr "Opprett en fletteforespørsel"
@@ -10092,6 +10184,9 @@ msgstr "Opprett et nytt kodelager"
msgid "Create a personal access token on your account to pull or push via %{protocol}."
msgstr ""
+msgid "Create a project"
+msgstr ""
+
msgid "Create an account using:"
msgstr "Lag en konto med:"
@@ -10455,6 +10550,9 @@ msgstr ""
msgid "Creation date"
msgstr "Opprettelsesdato"
+msgid "Creator"
+msgstr ""
+
msgid "Credentials"
msgstr "Legitimasjon"
@@ -10467,9 +10565,15 @@ msgstr ""
msgid "CredentialsInventory|Personal Access Tokens"
msgstr "Personlige tilgangssjetonger"
+msgid "CredentialsInventory|Project Access Tokens"
+msgstr ""
+
msgid "CredentialsInventory|SSH Keys"
msgstr "SSH-nøkler"
+msgid "Credit card required to be on file in order to create a pipeline"
+msgstr ""
+
msgid "Credit card:"
msgstr ""
@@ -10653,9 +10757,6 @@ msgstr ""
msgid "Customer relations"
msgstr ""
-msgid "Customizable by an administrator."
-msgstr "Justerbar av en administrator."
-
msgid "Customizable by owners."
msgstr ""
@@ -10785,30 +10886,18 @@ msgstr ""
msgid "CycleAnalytics|%{selectedLabelsCount} selected (%{maxLabels} max)"
msgstr "%{selectedLabelsCount} valgt (%{maxLabels} max)"
-msgid "CycleAnalytics|%{stageCount} stages selected"
-msgstr "%{stageCount} trinn valgt"
-
-msgid "CycleAnalytics|All stages"
-msgstr "Alle trinn"
-
-msgid "CycleAnalytics|Average days to completion"
+msgid "CycleAnalytics|Average time to completion"
msgstr ""
msgid "CycleAnalytics|Date"
msgstr "Dato"
-msgid "CycleAnalytics|Days to completion"
-msgstr "Dager igjen til fullføring"
-
msgid "CycleAnalytics|Display chart filters"
msgstr "Vis diagramfiltre"
msgid "CycleAnalytics|Lead Time for Changes"
msgstr ""
-msgid "CycleAnalytics|No stages selected"
-msgstr "Ingen trinn er valgt"
-
msgid "CycleAnalytics|Number of tasks"
msgstr "Antall oppgaver"
@@ -10837,18 +10926,30 @@ msgstr ""
msgid "CycleAnalytics|Showing data for group '%{groupName}' from %{createdAfter} to %{createdBefore}"
msgstr ""
-msgid "CycleAnalytics|Stages"
-msgstr "Trinn"
+msgid "CycleAnalytics|Stage time: %{title}"
+msgstr ""
msgid "CycleAnalytics|Tasks by type"
msgstr "Oppgaver etter type"
-msgid "CycleAnalytics|The average time spent in the selected stage for the items that were completed on each date. Data limited to the last 500 items."
+msgid "CycleAnalytics|The average time items spent in this stage. Data limited to items completed within this date range."
msgstr ""
msgid "CycleAnalytics|The given date range is larger than 180 days"
msgstr ""
+msgid "CycleAnalytics|The total time items spent across each value stream stage. Data limited to items completed within this date range."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Stage time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Total time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|Total time"
+msgstr ""
+
msgid "CycleAnalytics|Type of work"
msgstr "Arbeidstype"
@@ -10861,9 +10962,6 @@ msgstr ""
msgid "CycleAnalytics|project dropdown filter"
msgstr ""
-msgid "CycleAnalytics|stage dropdown"
-msgstr ""
-
msgid "DAG visualization requires at least 3 dependent jobs."
msgstr ""
@@ -10963,10 +11061,16 @@ msgstr ""
msgid "DastProfiles|AJAX spider"
msgstr ""
+msgid "DastProfiles|API"
+msgstr ""
+
+msgid "DastProfiles|API endpoint URL"
+msgstr ""
+
msgid "DastProfiles|Active"
msgstr "Aktiv"
-msgid "DastProfiles|Additional request headers (Optional)"
+msgid "DastProfiles|Additional request headers (optional)"
msgstr ""
msgid "DastProfiles|Are you sure you want to delete this profile?"
@@ -10981,6 +11085,9 @@ msgstr "Autentiserings-URL"
msgid "DastProfiles|Branch missing"
msgstr "Grenen mangler"
+msgid "DastProfiles|Choose a scan method"
+msgstr ""
+
msgid "DastProfiles|Could not create the scanner profile. Please try again."
msgstr ""
@@ -11050,8 +11157,14 @@ msgstr "Detaljer om feilen"
msgid "DastProfiles|Excluded URLs"
msgstr "Ekskluderte URL-er"
-msgid "DastProfiles|Excluded URLs (Optional)"
-msgstr "Ekskluderte URL-er (valgfritt)"
+msgid "DastProfiles|Excluded URLs (optional)"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths (optional)"
+msgstr ""
msgid "DastProfiles|Hide debug messages"
msgstr ""
@@ -11107,9 +11220,6 @@ msgstr ""
msgid "DastProfiles|Request headers"
msgstr ""
-msgid "DastProfiles|Rest API"
-msgstr ""
-
msgid "DastProfiles|Run the AJAX spider, in addition to the traditional spider, to crawl the target site."
msgstr ""
@@ -11119,6 +11229,9 @@ msgstr ""
msgid "DastProfiles|Save profile"
msgstr "Lagre profil"
+msgid "DastProfiles|Scan method"
+msgstr ""
+
msgid "DastProfiles|Scan mode"
msgstr "Skannemodus"
@@ -11197,12 +11310,24 @@ msgstr "Valideringsstatus"
msgid "DastProfiles|Website"
msgstr "Nettsted"
+msgid "DastProfiles|What does each method do?"
+msgstr ""
+
msgid "DastProfiles|You can either choose a passive scan or validate the target site from the site profile management page. %{docsLinkStart}Learn more about site validation.%{docsLinkEnd}"
msgstr ""
msgid "DastProfiles|You cannot run an active scan against an unvalidated site."
msgstr ""
+msgid "DastProfiles|folder/dast_example.har or https://example.com/dast_example.har"
+msgstr ""
+
+msgid "DastProfiles|folder/example.postman_collection.json or https://example.com/"
+msgstr ""
+
+msgid "DastProfiles|folder/openapi.json or https://example.com/openapi.json"
+msgstr ""
+
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
@@ -11310,6 +11435,9 @@ msgstr ""
msgid "DatadogIntegration|API URL"
msgstr "API-URL"
+msgid "DatadogIntegration|Custom tags in Datadog. Enter one tag per line in the %{codeOpen}key:value%{codeClose} format. %{linkOpen}How do I use tags?%{linkClose}"
+msgstr ""
+
msgid "DatadogIntegration|Environment"
msgstr "Miljø"
@@ -11328,12 +11456,18 @@ msgstr "Tjeneste"
msgid "DatadogIntegration|Tag all data from this GitLab instance in Datadog. Useful when managing several self-managed deployments."
msgstr ""
+msgid "DatadogIntegration|Tags"
+msgstr ""
+
msgid "DatadogIntegration|The Datadog site to send data to. To send data to the EU site, use %{codeOpen}datadoghq.eu%{codeClose}."
msgstr ""
msgid "DatadogIntegration|Trace your GitLab pipelines with Datadog."
msgstr ""
+msgid "DatadogIntegration|have an invalid format"
+msgstr ""
+
msgid "Datasource name not found"
msgstr ""
@@ -11343,9 +11477,6 @@ msgstr "Dato"
msgid "Date merged"
msgstr ""
-msgid "Date picker"
-msgstr "Datovelger"
-
msgid "Date range"
msgstr "Datointervall"
@@ -11499,9 +11630,6 @@ msgstr ""
msgid "Definition"
msgstr "Definisjon"
-msgid "Delayed Project Deletion (%{adjourned_deletion})"
-msgstr ""
-
msgid "DelayedJobs|Are you sure you want to run %{jobName} immediately? Otherwise this job will run automatically after its timer finishes."
msgstr ""
@@ -11580,12 +11708,12 @@ msgstr "Slett stempel: %{labelName}"
msgid "Delete pipeline"
msgstr "Slett rørledning"
+msgid "Delete pipeline schedule"
+msgstr ""
+
msgid "Delete project"
msgstr "Slett prosjekt"
-msgid "Delete project. Are you ABSOLUTELY SURE?"
-msgstr "Slett prosjektet. Er du HELT SIKKER?"
-
msgid "Delete row"
msgstr "Slett rad"
@@ -11613,6 +11741,9 @@ msgstr "Slett dette vedlegget"
msgid "Delete this epic and all descendants?"
msgstr ""
+msgid "Delete this project"
+msgstr ""
+
msgid "Delete user list"
msgstr "Slett brukerliste"
@@ -11871,6 +12002,12 @@ msgstr ""
msgid "Deploy to..."
msgstr "Distribuer til …"
+msgid "DeployBoards|To see deployment progress for your environments, make sure you are deploying to %{codeStart}$KUBE_NAMESPACE%{codeEnd} and annotating with %{codeStart}app.gitlab.com/app=$CI_PROJECT_PATH_SLUG%{codeEnd} and %{codeStart}app.gitlab.com/env=$CI_ENVIRONMENT_SLUG%{codeEnd}."
+msgstr ""
+
+msgid "DeployBoard|Kubernetes Pods"
+msgstr ""
+
msgid "DeployFreeze|Add a freeze period to prevent unintended releases during a period of time for a given environment. You must update the deployment jobs in %{filename} according to the deploy freezes added here. %{freeze_period_link_start}Learn more.%{freeze_period_link_end}"
msgstr ""
@@ -11955,9 +12092,6 @@ msgstr "Kun lesetilgang"
msgid "DeployTokens|Active Deploy Tokens (%{active_tokens})"
msgstr ""
-msgid "DeployTokens|Allows read and write access to registry images."
-msgstr ""
-
msgid "DeployTokens|Allows read and write access to the package registry."
msgstr ""
@@ -11970,6 +12104,9 @@ msgstr ""
msgid "DeployTokens|Allows read-only access to the repository."
msgstr ""
+msgid "DeployTokens|Allows write access to registry images."
+msgstr ""
+
msgid "DeployTokens|Copy deploy token"
msgstr ""
@@ -12063,12 +12200,57 @@ msgstr ""
msgid "Deploying to AWS is easy with GitLab"
msgstr ""
+msgid "Deployment"
+msgstr ""
+
msgid "Deployment Frequency"
msgstr ""
+msgid "Deployment Target|Project deployment target (optional)"
+msgstr ""
+
+msgid "Deployment Target|Select the deployment target"
+msgstr ""
+
msgid "Deployment frequency"
msgstr ""
+msgid "DeploymentTarget|GitLab Pages"
+msgstr ""
+
+msgid "DeploymentTarget|Heroku"
+msgstr ""
+
+msgid "DeploymentTarget|Infrastructure provider (Terraform, Cloudformation, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Kubernetes (GKE, EKS, OpenShift, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Managed container runtime (Fargate, Cloud Run, DigitalOcean App)"
+msgstr ""
+
+msgid "DeploymentTarget|Mobile app store"
+msgstr ""
+
+msgid "DeploymentTarget|No deployment planned"
+msgstr ""
+
+msgid "DeploymentTarget|Other hosting service"
+msgstr ""
+
+msgid "DeploymentTarget|Registry (package or container)"
+msgstr ""
+
+msgid "DeploymentTarget|Self-managed container runtime (Podman, Docker Swarm, Docker Compose)"
+msgstr ""
+
+msgid "DeploymentTarget|Serverless backend (Lambda, Cloud functions)"
+msgstr ""
+
+msgid "DeploymentTarget|Virtual machine (for example, EC2)"
+msgstr ""
+
msgid "Deployments"
msgstr "Distribusjoner"
@@ -12107,6 +12289,9 @@ msgstr ""
msgid "Deployment|This deployment was created using the API"
msgstr ""
+msgid "Deployment|Triggerer"
+msgstr ""
+
msgid "Deployment|Waiting"
msgstr ""
@@ -12134,6 +12319,18 @@ msgstr "suksess"
msgid "Deprecated API rate limits"
msgstr ""
+msgid "Deprecations|Feature deprecation and removal"
+msgstr ""
+
+msgid "Deprecations|For information on a possible replacement %{epicStart} learn more about Opstrace %{epicEnd}."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7 and are %{epicStart} scheduled for removal %{epicEnd} in GitLab 15.0."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7, and are %{removal_link_start} scheduled for removal %{link_end} in GitLab 15.0. For information on a possible replacement, %{opstrace_link_start} learn more about Opstrace %{link_end}."
+msgstr ""
+
msgid "Deprioritize label"
msgstr ""
@@ -12379,11 +12576,11 @@ msgstr ""
msgid "DevopsAdoption|At least one deploy"
msgstr ""
-msgid "DevopsAdoption|At least one issue opened"
-msgstr "Minst én åpnet sak"
+msgid "DevopsAdoption|At least one issue created"
+msgstr ""
-msgid "DevopsAdoption|At least one merge request opened"
-msgstr "Minst én åpnet fletteforespørsel"
+msgid "DevopsAdoption|At least one merge request created"
+msgstr ""
msgid "DevopsAdoption|At least one pipeline successfully run"
msgstr ""
@@ -12583,6 +12780,9 @@ msgstr ""
msgid "Direct member"
msgstr "Direktemedlem"
+msgid "Direct members"
+msgstr ""
+
msgid "Direct non-authenticated users to this page."
msgstr ""
@@ -12699,6 +12899,9 @@ msgid_plural "Dismiss %d selected vulnerabilities as"
msgstr[0] "Avfei %d valgt sårbarhet som"
msgstr[1] "Avfei %d valgt sårbarheter som"
+msgid "Dismiss Alert"
+msgstr ""
+
msgid "Dismiss merge request promotion"
msgstr ""
@@ -12726,9 +12929,15 @@ msgstr ""
msgid "Display alerts from all configured monitoring tools."
msgstr ""
+msgid "Display milestones"
+msgstr ""
+
msgid "Display name"
msgstr "Visningsnavn"
+msgid "Display progress of child issues"
+msgstr ""
+
msgid "Display rendered file"
msgstr ""
@@ -12834,6 +13043,9 @@ msgstr "Last ned eksport"
msgid "Download image"
msgstr "Last ned bilde"
+msgid "Download payload"
+msgstr ""
+
msgid "Download raw data (.csv)"
msgstr "Last ned rå data (.csv)"
@@ -13011,6 +13223,9 @@ msgstr "Rediger identiteten til %{user_name}"
msgid "Edit in Web IDE"
msgstr "Rediger i nett-IDE"
+msgid "Edit in pipeline editor"
+msgstr ""
+
msgid "Edit in single-file editor"
msgstr "Rediger i enkeltfil-redigerer"
@@ -13053,6 +13268,9 @@ msgstr "Rediger wiki-side"
msgid "Edit your most recent comment in a thread (from an empty textarea)"
msgstr ""
+msgid "Edit, lint, and visualize your pipeline."
+msgstr ""
+
msgid "Edited"
msgstr "Redigert"
@@ -13494,6 +13712,9 @@ msgstr ""
msgid "Enforce two-factor authentication for all user sign-ins."
msgstr ""
+msgid "Enhance security by storing service account keys in secret managers - learn more about %{docLinkStart}secret management with GitLab%{docLinkEnd}"
+msgstr ""
+
msgid "Ensure connectivity is available from the GitLab server to the Prometheus server"
msgstr ""
@@ -13554,6 +13775,9 @@ 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 following to confirm:"
+msgstr ""
+
msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr "Skriv inn navnet til programmet ditt, så returnerer vi en unik %{type}."
@@ -14084,9 +14308,6 @@ msgstr ""
msgid "Error occurred while updating the issue status"
msgstr "En feil oppstod under oppdatering av sakens status"
-msgid "Error occurred while updating the issue weight"
-msgstr "En feil oppstod under oppdatering av sakens vektlegging"
-
msgid "Error occurred. A blocked user cannot be deactivated"
msgstr ""
@@ -14222,6 +14443,9 @@ msgstr ""
msgid "Errors:"
msgstr "Feil:"
+msgid "Escalate this incident"
+msgstr ""
+
msgid "Escalation Policies"
msgstr ""
@@ -14234,6 +14458,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy"
+msgstr ""
+
msgid "Escalation policy:"
msgstr ""
@@ -14485,6 +14712,9 @@ msgstr "Eksisterende prosjekter vil kunne bruke utløpsretningslinjer. Unngå å
msgid "Existing sign in methods may be removed"
msgstr ""
+msgid "Exit."
+msgstr ""
+
msgid "Expand"
msgstr "Utvid"
@@ -14581,6 +14811,9 @@ msgstr "Utforsk prosjekter"
msgid "Explore public groups"
msgstr "Utforsk offentlige grupper"
+msgid "Explore public projects"
+msgstr ""
+
msgid "Explore snippets"
msgstr ""
@@ -14742,7 +14975,7 @@ msgid_plural "Failed to archive designs. Please try again."
msgstr[0] ""
msgstr[1] ""
-msgid "Failed to assign a reviewer because no user was found."
+msgid "Failed to assign a reviewer because no user was specified."
msgstr ""
msgid "Failed to assign a user because no user was found."
@@ -14808,10 +15041,10 @@ msgstr ""
msgid "Failed to find import label for Jira import."
msgstr ""
-msgid "Failed to generate export, please try again later."
+msgid "Failed to find users for %{missing}"
msgstr ""
-msgid "Failed to generate report, please try again after sometime"
+msgid "Failed to generate export, please try again later."
msgstr ""
msgid "Failed to get ref."
@@ -14910,6 +15143,9 @@ msgstr "Mislyktes i å fjerne et Zoom-møte"
msgid "Failed to remove a to-do item for the design."
msgstr ""
+msgid "Failed to remove attention because no user was found."
+msgstr ""
+
msgid "Failed to remove mirror."
msgstr "Mislyktes i å fjerne speilvendingen."
@@ -14922,6 +15158,9 @@ msgstr "Mislyktes i å fjerne brukeridentitet."
msgid "Failed to remove user key."
msgstr "Mislyktes i å fjerne brukernøkkel."
+msgid "Failed to request attention because no user was found."
+msgstr ""
+
msgid "Failed to reset key. Please try again."
msgstr "Mislyktes i å tilbakestille nøkkel. Vennligst prøv igjen."
@@ -15003,6 +15242,9 @@ msgstr ""
msgid "Feature Flags"
msgstr "Funksjonsflagg"
+msgid "Feature deprecation and removal"
+msgstr ""
+
msgid "Feature flag status"
msgstr "Funksjonsflaggstatus"
@@ -15500,7 +15742,7 @@ msgstr ""
msgid "For each job, re-use the project workspace. If the workspace doesn't exist, use %{code_open}git clone%{code_close}."
msgstr ""
-msgid "For example, the application using the token or the purpose of the token."
+msgid "For example, the application using the token or the purpose of the token. Do not give sensitive information for the name of the token, as it will be visible to all %{resource_type} members."
msgstr ""
msgid "For files larger than this limit, only index the file name. The file content is neither indexed nor searchable."
@@ -15584,9 +15826,6 @@ msgstr "Offentlig"
msgid "ForkProject|Select a namespace"
msgstr ""
-msgid "ForkProject|Select a namespace to fork the project"
-msgstr ""
-
msgid "ForkProject|The project can be accessed by any logged in user."
msgstr ""
@@ -15683,6 +15922,9 @@ msgstr ""
msgid "Full name"
msgstr "Fullt navn"
+msgid "GCP region configured"
+msgstr ""
+
msgid "GPG Key ID:"
msgstr "GPG-nøkkel-ID:"
@@ -15863,6 +16105,9 @@ msgstr ""
msgid "Geo|Failed"
msgstr "Mislykket"
+msgid "Geo|Filter Geo sites"
+msgstr ""
+
msgid "Geo|Filter by name"
msgstr "Filtrer etter navn"
@@ -16274,6 +16519,12 @@ msgstr "GitLab-importering"
msgid "GitLab Issue"
msgstr "Gitlab-sak"
+msgid "GitLab KAS"
+msgstr ""
+
+msgid "GitLab Memberships CSV Export"
+msgstr ""
+
msgid "GitLab Pages"
msgstr "GitLab-sider"
@@ -16322,6 +16573,9 @@ 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 free to use. Many features for larger teams are part of our %{link_start}paid products%{link_end}. You can try Ultimate for free without any obligation or payment details."
+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 ""
@@ -16448,8 +16702,8 @@ msgstr "Verifisert"
msgid "GitLabPages|When enabled, all attempts to visit your website through HTTP are automatically redirected to HTTPS using a response with status code 301. Requires a valid certificate for all domains. %{docs_link_start}Learn more.%{link_end}"
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. %{docs_link_start}Learn more.%{link_end}"
-msgstr "Når du bruker Pages under det generelle domenet til en GitLab-instans (%{pages_host}), kan du ikke bruke HTTPS med under-underdomener. Dette betyr at hvis brukernavnet/gruppenavnet ditt inneholder en prikk, vil det ikke fungere. Dette er en begrensning for «HTTP-over-TLS»-protokollen. HTTP-sider vil fortsette å fungere, forutsatt at du ikke omdirigerer HTTP til HTTPS. %{docs_link_start}Lær mer.%{link_end}"
+msgid "GitLabPages|When using Pages under the general domain of a GitLab instance (%{pages_host}), you cannot use HTTPS with subdomains of subdomains. If your namespace or groupname contains a dot, it does not work. This is a limitation of the HTTP Over TLS protocol. HTTP pages work if you don't redirect HTTP to HTTPS. %{docs_link_start}Learn more.%{link_end}"
+msgstr ""
msgid "GitLabPages|With GitLab Pages you can host your static website directly from your GitLab repository. %{docs_link_start}Learn more.%{link_end}"
msgstr ""
@@ -16625,9 +16879,6 @@ msgstr "GÃ¥ til filer"
msgid "Go to find file"
msgstr ""
-msgid "Go to fork"
-msgstr "GÃ¥ til utgreiningen"
-
msgid "Go to issue boards"
msgstr "GÃ¥ til saksbordene"
@@ -16835,9 +17086,6 @@ msgstr "Gruppe-Git-LFS-status:"
msgid "Group Hooks"
msgstr "Gruppekroker"
-msgid "Group ID"
-msgstr "Gruppe-ID"
-
msgid "Group Owner must have signed in with SAML before enabling Group Managed Accounts"
msgstr ""
@@ -16865,9 +17113,6 @@ msgstr "Gruppeavatar"
msgid "Group by"
msgstr ""
-msgid "Group description"
-msgstr ""
-
msgid "Group description (optional)"
msgstr "Gruppebeskrivelse (valgfritt)"
@@ -16982,8 +17227,8 @@ msgstr "Gruppe: %{group_name}"
msgid "Group: %{name}"
msgstr "Gruppe: %{name}"
-msgid "GroupActivityMetrics|Issues opened"
-msgstr "Saker åpnet"
+msgid "GroupActivityMetrics|Issues created"
+msgstr ""
msgid "GroupActivityMetrics|Last 90 days"
msgstr "Seneste 90 dager"
@@ -16991,8 +17236,8 @@ msgstr "Seneste 90 dager"
msgid "GroupActivityMetrics|Members added"
msgstr "Medlemmer lagt til"
-msgid "GroupActivityMetrics|Merge Requests opened"
-msgstr "Fletteforespørsler åpnet"
+msgid "GroupActivityMetrics|Merge Requests created"
+msgstr ""
msgid "GroupActivityMetrics|Recent activity"
msgstr "Nylig aktivitet"
@@ -17282,6 +17527,9 @@ msgstr "Endre gruppe-URL"
msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
+msgid "GroupSettings|Choose a group path that does not start with a dash or end with a period. It can also contain alphanumeric characters and underscores."
+msgstr ""
+
msgid "GroupSettings|Compliance frameworks"
msgstr ""
@@ -17315,8 +17563,8 @@ msgstr "Eksporter gruppe"
msgid "GroupSettings|If not specified at the group or instance level, the default is %{default_initial_branch_name}. Does not affect existing repositories."
msgstr ""
-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 "Hvis overgruppens synlighet er lavere enn gruppens nåværende synlighet, vil synlighetsnivåer for undergrupper og prosjekter endres til å samsvare med den nye overgruppens synlighet."
+msgid "GroupSettings|If the parent group's visibility is lower than the group's current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility."
+msgstr ""
msgid "GroupSettings|New runners registration token has been generated!"
msgstr ""
@@ -17432,8 +17680,11 @@ msgstr "Grupper (%{count})"
msgid "Groups and projects"
msgstr "Grupper og prosjekter"
-msgid "Groups and subgroups"
-msgstr "Grupper og undergrupper"
+msgid "Groups are a great way to organize projects and people."
+msgstr ""
+
+msgid "Groups are the best way to manage projects and members."
+msgstr ""
msgid "Groups to synchronize"
msgstr "Grupper å synkronise"
@@ -17543,14 +17794,17 @@ msgstr "f.eks. h8d3f016698e …"
msgid "GroupsTree|Are you sure you want to leave the \"%{fullName}\" group?"
msgstr "Er du sikker på at du vil forlate «%{fullName}»-gruppen?"
-msgid "GroupsTree|Edit group"
-msgstr "Rediger gruppe"
+msgid "GroupsTree|Delete"
+msgstr ""
+
+msgid "GroupsTree|Edit"
+msgstr ""
msgid "GroupsTree|Failed to leave the group. Please make sure you are not the only owner."
msgstr "Klarte ikke å forlate gruppen. Forsikre deg om at du ikke er den eneste eieren."
-msgid "GroupsTree|Leave this group"
-msgstr "Forlat denne gruppen"
+msgid "GroupsTree|Leave group"
+msgstr ""
msgid "GroupsTree|Loading groups"
msgstr "Laster inn grupper"
@@ -17561,9 +17815,57 @@ msgstr "Ingen grupper samsvarte med søket ditt"
msgid "GroupsTree|No groups or projects matched your search"
msgstr "Ingen grupper eller prosjekter samsvarte med søket ditt"
+msgid "GroupsTree|Options"
+msgstr ""
+
msgid "GroupsTree|Search by name"
msgstr "Søk etter navn"
+msgid "Groups|Avatar will be removed. Are you sure?"
+msgstr ""
+
+msgid "Groups|Changing group URL can have unintended side effects."
+msgstr ""
+
+msgid "Groups|Checking group URL availability..."
+msgstr ""
+
+msgid "Groups|Enter a descriptive name for your group."
+msgstr ""
+
+msgid "Groups|Group ID"
+msgstr ""
+
+msgid "Groups|Group URL"
+msgstr ""
+
+msgid "Groups|Group avatar"
+msgstr ""
+
+msgid "Groups|Group description (optional)"
+msgstr ""
+
+msgid "Groups|Group name"
+msgstr ""
+
+msgid "Groups|Group path is available."
+msgstr ""
+
+msgid "Groups|Group path is unavailable. Path has been replaced with a suggested available path."
+msgstr ""
+
+msgid "Groups|Learn more"
+msgstr ""
+
+msgid "Groups|Must start with letter, digit, emoji, or underscore. Can also contain periods, dashes, spaces, and parentheses."
+msgstr ""
+
+msgid "Groups|Remove avatar"
+msgstr ""
+
+msgid "Groups|Save changes"
+msgstr ""
+
msgid "Guideline"
msgstr "Retningslinje"
@@ -17573,6 +17875,9 @@ msgstr "HAR (HTTP-arkiv)"
msgid "HAR file path or URL"
msgstr ""
+msgid "HTTP Archive (HAR)"
+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 ""
@@ -17973,6 +18278,9 @@ msgstr "SSH-nøkkelen din har utløpt. Vennligst generer en ny nøkkel."
msgid "INFO: Your SSH key is expiring soon. Please generate a new key."
msgstr "SSH-nøkkelen din utløper snart. Vennligst generer en ny nøkkel."
+msgid "IP"
+msgstr ""
+
msgid "IP Address"
msgstr "IP-adresse"
@@ -18009,6 +18317,9 @@ msgstr ""
msgid "IdentityVerification|Verify your identity"
msgstr ""
+msgid "IdentityVerification|You can always verify your account at a later time to create a group."
+msgstr ""
+
msgid "If any indexed field exceeds this limit, it is truncated to this number of characters. The rest of the content is neither indexed nor searchable. This does not apply to repository and wiki indexing. For unlimited characters, set this to 0."
msgstr ""
@@ -18066,6 +18377,9 @@ msgstr ""
msgid "If you add %{codeStart}needs%{codeEnd} to jobs in your pipeline you'll be able to view the %{codeStart}needs%{codeEnd} relationships between jobs in this tab as a %{linkStart}Directed Acyclic Graph (DAG)%{linkEnd}."
msgstr ""
+msgid "If you are added to a project, it will be displayed here."
+msgstr ""
+
msgid "If you did not initiate these sign-in attempts, please reach out to your administrator or enable two-factor authentication (2FA) on your account."
msgstr ""
@@ -18372,12 +18686,24 @@ msgstr ""
msgid "InProductMarketing|3 ways to dive into GitLab CI/CD"
msgstr ""
+msgid "InProductMarketing|A single application eliminates complex integrations, data chokepoints, and toolchain maintenance, resulting in greater productivity and lower cost."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features, build more efficiently, strengthen security and compliance."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features."
+msgstr ""
+
msgid "InProductMarketing|Actually, GitLab makes the team work (better)"
msgstr ""
msgid "InProductMarketing|And finally %{deploy_link} a Python application."
msgstr ""
+msgid "InProductMarketing|And many more..."
+msgstr ""
+
msgid "InProductMarketing|Are your runners ready?"
msgstr ""
@@ -18396,15 +18722,33 @@ msgstr "Bedre kode på mindre tid"
msgid "InProductMarketing|Blog"
msgstr "Blogg"
+msgid "InProductMarketing|Break down silos to coordinate seamlessly across development, operations, and security with a consistent experience across the development lifecycle."
+msgstr ""
+
+msgid "InProductMarketing|Burn up/down charts"
+msgstr ""
+
msgid "InProductMarketing|By enabling code owners and required merge approvals the right person will review the right MR. This is a win-win: cleaner code and a more efficient review process."
msgstr ""
msgid "InProductMarketing|Click on the number below that corresponds with your answer — 1 being very difficult, 5 being very easy."
msgstr ""
+msgid "InProductMarketing|Code owners"
+msgstr ""
+
msgid "InProductMarketing|Code owners and required merge approvals are part of the paid tiers of GitLab. You can start a free 30-day trial of GitLab Ultimate and enable these features in less than 5 minutes with no credit card required."
msgstr ""
+msgid "InProductMarketing|Code review analytics"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration across stages in GitLab"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration made easy"
+msgstr ""
+
msgid "InProductMarketing|Create a custom CI runner with just a few clicks"
msgstr ""
@@ -18414,12 +18758,21 @@ msgstr ""
msgid "InProductMarketing|Create a project in GitLab in 5 minutes"
msgstr ""
+msgid "InProductMarketing|Create well-defined workflows by using scoped labels on issues, merge requests, and epics. Labels with the same scope cannot be used together, which prevents conflicts."
+msgstr ""
+
msgid "InProductMarketing|Create your first project!"
msgstr ""
+msgid "InProductMarketing|Define who owns specific files or directories, so the right reviewers are suggested when a merge request introduces changes to those files."
+msgstr ""
+
msgid "InProductMarketing|Deliver Better Products Faster"
msgstr ""
+msgid "InProductMarketing|Dependency scanning"
+msgstr ""
+
msgid "InProductMarketing|Did you know teams that use GitLab are far more efficient?"
msgstr ""
@@ -18429,15 +18782,27 @@ msgstr "Vanskelig"
msgid "InProductMarketing|Dig in and create a project and a repo"
msgstr ""
+msgid "InProductMarketing|Discover Premium & Ultimate"
+msgstr ""
+
+msgid "InProductMarketing|Discover Premium & Ultimate."
+msgstr ""
+
msgid "InProductMarketing|Do you have a minute?"
msgstr "Har du et minutt?"
msgid "InProductMarketing|Do you have a teammate who would be perfect for this task?"
msgstr ""
+msgid "InProductMarketing|Dynamic application security testing"
+msgstr ""
+
msgid "InProductMarketing|Easy"
msgstr "Enkelt"
+msgid "InProductMarketing|Epics"
+msgstr ""
+
msgid "InProductMarketing|Expand your DevOps journey with a free GitLab trial"
msgstr ""
@@ -18459,9 +18824,15 @@ msgstr ""
msgid "InProductMarketing|Feel the need for speed?"
msgstr ""
+msgid "InProductMarketing|Find and fix bottlenecks in your code review process by understanding how long open merge requests have been in review."
+msgstr ""
+
msgid "InProductMarketing|Find out how your teams are really doing"
msgstr ""
+msgid "InProductMarketing|Find out if your external libraries are safe. Run dependency scanning jobs that check for known vulnerabilities in your external libraries."
+msgstr ""
+
msgid "InProductMarketing|Follow our steps"
msgstr "Følg våre trinn"
@@ -18498,6 +18869,9 @@ msgstr ""
msgid "InProductMarketing|GitLab is better with teammates to help out!"
msgstr ""
+msgid "InProductMarketing|GitLab is infrastructure agnostic (supporting GCP, AWS, Azure, OpenShift, VMWare, On Prem, Bare Metal, and more), offering a consistent workflow experience – irrespective of the environment."
+msgstr ""
+
msgid "InProductMarketing|GitLab provides static application security testing (SAST), dynamic application security testing (DAST), container scanning, and dependency scanning to help you deliver secure applications along with license compliance."
msgstr ""
@@ -18588,21 +18962,36 @@ msgstr ""
msgid "InProductMarketing|It's also possible to simply %{external_repo_link} in order to take advantage of GitLab's CI/CD."
msgstr ""
+msgid "InProductMarketing|Keep your code quality high by defining who should approve merge requests and how many approvals are required."
+msgstr ""
+
msgid "InProductMarketing|Launch GitLab CI/CD in 20 minutes or less"
msgstr ""
+msgid "InProductMarketing|Lower cost of development"
+msgstr ""
+
+msgid "InProductMarketing|Make it easier to collaborate on high-level ideas by grouping related issues in an epic."
+msgstr ""
+
msgid "InProductMarketing|Making the switch? It's easier than you think to import your projects into GitLab. Move %{github_link}, or import something %{bitbucket_link}."
msgstr ""
msgid "InProductMarketing|Master the art of importing!"
msgstr ""
+msgid "InProductMarketing|Merge request approval rule"
+msgstr ""
+
msgid "InProductMarketing|Move on to easily creating a Pages website %{ci_template_link}"
msgstr ""
msgid "InProductMarketing|Multiple owners, confusing workstreams? We've got you covered"
msgstr ""
+msgid "InProductMarketing|Multiple required approvers"
+msgstr ""
+
msgid "InProductMarketing|Need an alternative to importing?"
msgstr ""
@@ -18615,18 +19004,33 @@ msgstr "Ingen bankkort behøves."
msgid "InProductMarketing|Our tool brings all the things together"
msgstr ""
+msgid "InProductMarketing|Protect your web application by using DAST to examine for vulnerabilities in deployed environments."
+msgstr ""
+
msgid "InProductMarketing|Rapid development, simplified"
msgstr ""
msgid "InProductMarketing|Reduce Security & Compliance Risk"
msgstr ""
+msgid "InProductMarketing|Require multiple approvers on a merge request, so you know it's in good shape before it's merged."
+msgstr ""
+
+msgid "InProductMarketing|Roadmaps"
+msgstr ""
+
+msgid "InProductMarketing|Scoped labels"
+msgstr ""
+
msgid "InProductMarketing|Security that's integrated into your development lifecycle"
msgstr ""
msgid "InProductMarketing|Sometimes you're not ready to make a full transition to a new tool. If you're not ready to fully commit, %{mirroring_link} gives you a safe way to try out GitLab in parallel with your current tool."
msgstr ""
+msgid "InProductMarketing|Speed. Efficiency. Trust."
+msgstr ""
+
msgid "InProductMarketing|Spin up an autoscaling runner in GitLab"
msgstr ""
@@ -18636,6 +19040,9 @@ msgstr ""
msgid "InProductMarketing|Start a Self-Managed trial"
msgstr ""
+msgid "InProductMarketing|Start a free trial"
+msgstr ""
+
msgid "InProductMarketing|Start a free trial of GitLab Ultimate – no credit card required"
msgstr ""
@@ -18702,6 +19109,9 @@ msgstr ""
msgid "InProductMarketing|To understand and get the most out of GitLab, start at the beginning and %{project_link}. In GitLab, repositories are part of a project, so after you've created your project you can go ahead and %{repo_link}."
msgstr ""
+msgid "InProductMarketing|Track completed issues in a chart, so you can see how a milestone is progressing at a glance."
+msgstr ""
+
msgid "InProductMarketing|Try GitLab Ultimate for free"
msgstr ""
@@ -18738,6 +19148,9 @@ msgstr "Veldig vanskelig"
msgid "InProductMarketing|Very easy"
msgstr "Veldig enkelt"
+msgid "InProductMarketing|Visualize your epics and milestones in a timeline."
+msgstr ""
+
msgid "InProductMarketing|Want to host GitLab on your servers?"
msgstr ""
@@ -18759,6 +19172,9 @@ msgstr ""
msgid "InProductMarketing|YouTube"
msgstr "YouTube"
+msgid "InProductMarketing|Your software, deployed your way"
+msgstr ""
+
msgid "InProductMarketing|Your teams can be more efficient"
msgstr ""
@@ -18879,9 +19295,18 @@ msgstr ""
msgid "IncidentManagement|No incidents to display."
msgstr ""
+msgid "IncidentManagement|None"
+msgstr ""
+
msgid "IncidentManagement|Open"
msgstr "Ã…pen"
+msgid "IncidentManagement|Page your team with escalation policies"
+msgstr ""
+
+msgid "IncidentManagement|Paged"
+msgstr ""
+
msgid "IncidentManagement|Published"
msgstr "Publisert"
@@ -18891,6 +19316,9 @@ msgstr ""
msgid "IncidentManagement|Severity"
msgstr "Alvorlighetsgrad"
+msgid "IncidentManagement|Status"
+msgstr ""
+
msgid "IncidentManagement|There are no closed incidents"
msgstr ""
@@ -18909,6 +19337,9 @@ msgstr "Ukjent"
msgid "IncidentManagement|Unpublished"
msgstr "Upublisert"
+msgid "IncidentManagement|Use escalation policies to automatically page your team when incidents are created."
+msgstr ""
+
msgid "IncidentSettings|Activate \"time to SLA\" countdown timer"
msgstr ""
@@ -18954,8 +19385,11 @@ msgstr "minutter"
msgid "Incidents"
msgstr "Hendelser"
-msgid "Incidents|Add a URL"
-msgstr "Legg til en URL"
+msgid "Incidents|Add image details"
+msgstr ""
+
+msgid "Incidents|Add text or a link to display with your image. If you don't add either, the file name displays instead."
+msgstr ""
msgid "Incidents|Drop or %{linkStart}upload%{linkEnd} a metric screenshot to attach it to the incident"
msgstr ""
@@ -18969,21 +19403,30 @@ msgstr "Det oppstod et problem med å slette bildet."
msgid "Incidents|There was an issue loading metric images."
msgstr ""
+msgid "Incidents|There was an issue updating your image."
+msgstr ""
+
msgid "Incidents|There was an issue uploading your image."
msgstr "Det oppstod et problem med å laste opp bildet ditt."
-msgid "Incidents|You can optionally add a URL to link users to the original graph."
-msgstr ""
-
msgid "Incident|Alert details"
msgstr "Alarmdetaljer"
msgid "Incident|Are you sure you wish to delete this image?"
msgstr ""
+msgid "Incident|Delete image"
+msgstr ""
+
msgid "Incident|Deleting %{filename}"
msgstr "Sletter %{filename}"
+msgid "Incident|Edit image text or link"
+msgstr ""
+
+msgid "Incident|Editing %{filename}"
+msgstr ""
+
msgid "Incident|Metrics"
msgstr "MÃ¥ltall"
@@ -19253,12 +19696,18 @@ msgstr ""
msgid "Integrations|Branches for which notifications are to be sent"
msgstr ""
+msgid "Integrations|Clear if using a self-signed certificate."
+msgstr ""
+
msgid "Integrations|Comment detail:"
msgstr "Kommentardetalj:"
msgid "Integrations|Comment settings:"
msgstr "Kommentarinnstillinger"
+msgid "Integrations|Connection details"
+msgstr ""
+
msgid "Integrations|Connection failed. Please check your settings."
msgstr ""
@@ -19283,6 +19732,9 @@ msgstr ""
msgid "Integrations|Enable GitLab.com slash commands in a Slack workspace."
msgstr ""
+msgid "Integrations|Enable SSL verification"
+msgstr ""
+
msgid "Integrations|Enable comments"
msgstr "Skru på kommentarer"
@@ -19361,6 +19813,9 @@ msgstr ""
msgid "Integrations|Return to GitLab for Jira"
msgstr ""
+msgid "Integrations|SSL verification"
+msgstr ""
+
msgid "Integrations|Save settings?"
msgstr "Vil du lagre innstillingene?"
@@ -19406,9 +19861,6 @@ msgstr "Bruk tilpassede innstillinger"
msgid "Integrations|Use default settings"
msgstr "Bruk forvalgte innstillinger"
-msgid "Integrations|When you mention a Jira issue in a commit or merge request, GitLab creates a remote link and comment (if enabled)."
-msgstr ""
-
msgid "Integrations|You can now close this window and return to the GitLab for Jira application."
msgstr ""
@@ -19433,9 +19885,6 @@ msgstr ""
msgid "Integrations|can't exceed %{recipients_limit}"
msgstr ""
-msgid "Interactive developer security education."
-msgstr ""
-
msgid "Interactive mode"
msgstr "Interaktiv modus"
@@ -19925,6 +20374,9 @@ msgstr "Alder"
msgid "IssueAnalytics|Assignees"
msgstr "Tilordnede"
+msgid "IssueAnalytics|Created by"
+msgstr ""
+
msgid "IssueAnalytics|Due date"
msgstr "MÃ¥ldato"
@@ -19937,9 +20389,6 @@ msgstr "Sak"
msgid "IssueAnalytics|Milestone"
msgstr "Milepæl"
-msgid "IssueAnalytics|Opened by"
-msgstr "Ã…pnet av"
-
msgid "IssueAnalytics|Status"
msgstr "Status"
@@ -20063,11 +20512,11 @@ msgstr ""
msgid "IssuesAnalytics|Avg/Month:"
msgstr "Gj.snitt/måned:"
-msgid "IssuesAnalytics|Issues opened"
-msgstr "Saker åpnet"
+msgid "IssuesAnalytics|Issues created"
+msgstr ""
-msgid "IssuesAnalytics|Issues opened per month"
-msgstr "Saker åpnet per måned"
+msgid "IssuesAnalytics|Issues created per month"
+msgstr ""
msgid "IssuesAnalytics|Last 12 months"
msgstr "Seneste 12 måneder"
@@ -20093,6 +20542,9 @@ msgstr ""
msgid "It looks like you have some draft commits in this branch."
msgstr ""
+msgid "It looks like you're attempting to activate your subscription. Use %{a_start}the Subscription page%{a_end} instead."
+msgstr ""
+
msgid "It may be several days before you see feature usage data."
msgstr ""
@@ -20321,6 +20773,9 @@ msgstr ""
msgid "JiraConnect|You can now close this window and return to Jira."
msgstr ""
+msgid "JiraConnect|You don't have permission to create branches for this project. Select a different project or contact the project owner for access. %{linkStart}Learn more.%{linkEnd}"
+msgstr ""
+
msgid "JiraRequest|A connection error occurred while connecting to Jira. Try your request again."
msgstr ""
@@ -20369,15 +20824,15 @@ msgstr ""
msgid "JiraService|Define the type of Jira issue to create from a vulnerability."
msgstr ""
-msgid "JiraService|Displaying Jira issues while leaving the GitLab issue functionality enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
-msgstr "Å vise Jira-saker mens GitLab-saksfunksjonaliteten er aktivert, kan være forvirrende. Vurder å %{linkStart}deaktivere GitLab-saker%{linkEnd} hvis de ikke ellers blir brukt."
+msgid "JiraService|Displaying Jira issues while leaving GitLab issues also enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
+msgstr ""
+
+msgid "JiraService|Enable Jira issue creation from vulnerabilities"
+msgstr ""
msgid "JiraService|Enable Jira issues"
msgstr "Skru på Jira-saker"
-msgid "JiraService|Enable Jira issues creation from vulnerabilities"
-msgstr ""
-
msgid "JiraService|Enable Jira transitions"
msgstr ""
@@ -20492,16 +20947,19 @@ msgstr ""
msgid "JiraService|View Jira issues in GitLab"
msgstr "Vis Jira-saker i GitLab"
-msgid "JiraService|Warning: All GitLab users that have access to this GitLab project are able to view all issues from the Jira project specified below."
+msgid "JiraService|Warning: All GitLab users with access to this GitLab project can view all issues from the Jira project you select."
msgstr ""
msgid "JiraService|Web URL"
msgstr "Nett-URL"
-msgid "JiraService|Work on Jira issues without leaving GitLab. Adds a Jira menu to access your list of Jira issues and view any issue as read-only."
+msgid "JiraService|When a Jira issue is mentioned in a commit or merge request, a remote link and comment (if enabled) will be created."
+msgstr ""
+
+msgid "JiraService|Work on Jira issues without leaving GitLab. Add a Jira menu to access a read-only list of your Jira issues."
msgstr ""
-msgid "JiraService|You need to configure Jira before enabling this integration. For more details, read the %{jira_doc_link_start}Jira integration documentation%{link_end}."
+msgid "JiraService|You must configure Jira before enabling this integration. %{jira_doc_link_start}Learn more.%{link_end}"
msgstr ""
msgid "Job"
@@ -20513,9 +20971,6 @@ msgstr ""
msgid "Job Failed #%{build_id}"
msgstr "Jobben mislyktes #%{build_id}"
-msgid "Job ID"
-msgstr "Jobb-ID"
-
msgid "Job artifact"
msgstr "Jobb-artifakt"
@@ -20582,9 +21037,27 @@ msgstr ""
msgid "Jobs|You're about to retry a job that failed because it attempted to deploy code that is older than the latest deployment. Retrying this job could result in overwriting the environment with the older source code."
msgstr ""
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source} into %{target}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{ref}"
+msgstr ""
+
+msgid "Job|Are you sure you want to erase this job log and artifacts?"
+msgstr ""
+
msgid "Job|Browse"
msgstr "Bla"
+msgid "Job|Cancel"
+msgstr ""
+
msgid "Job|Complete Raw"
msgstr ""
@@ -20594,6 +21067,9 @@ msgstr "Last ned"
msgid "Job|Erase job log and artifacts"
msgstr ""
+msgid "Job|Finished at"
+msgstr ""
+
msgid "Job|Job artifacts"
msgstr "Jobb-artefakter"
@@ -20606,8 +21082,8 @@ msgstr ""
msgid "Job|Keep"
msgstr "Behold"
-msgid "Job|Pipeline"
-msgstr "Rørledning"
+msgid "Job|Retry"
+msgstr ""
msgid "Job|Scroll to bottom"
msgstr "Bla til bunn"
@@ -20618,6 +21094,9 @@ msgstr "Bla til toppen"
msgid "Job|Show complete raw"
msgstr ""
+msgid "Job|Status"
+msgstr ""
+
msgid "Job|The artifacts were removed"
msgstr "Artefaktene ble fjernet"
@@ -20645,21 +21124,12 @@ msgstr "tillatt å mislykkes"
msgid "Job|delayed"
msgstr "forsinket"
-msgid "Job|for"
-msgstr "for"
-
-msgid "Job|into"
-msgstr "inni"
-
msgid "Job|manual"
msgstr "manuell"
msgid "Job|triggered"
msgstr "utløst"
-msgid "Job|with"
-msgstr "med"
-
msgid "Join Zoom meeting"
msgstr "Bli med på Zoom-møte"
@@ -20762,9 +21232,6 @@ msgstr "Nøkler"
msgid "Ki"
msgstr "Ki"
-msgid "Kontra"
-msgstr ""
-
msgid "Kroki"
msgstr "Kroki"
@@ -21088,6 +21555,9 @@ msgstr "Lær mer om %{username}"
msgid "Learn more about Auto DevOps"
msgstr "Lær mer om Auto DevOps"
+msgid "Learn more about GitLab"
+msgstr ""
+
msgid "Learn more about Needs relationships"
msgstr ""
@@ -21415,9 +21885,18 @@ msgstr ""
msgid "Licenses|Displays licenses detected in the project, based on the %{linkStart}latest successful%{linkEnd} scan"
msgstr ""
+msgid "Licenses|Drag your license file here or %{linkStart}click to upload%{linkEnd}."
+msgstr ""
+
+msgid "Licenses|Drop your license file to start the upload."
+msgstr ""
+
msgid "Licenses|Error fetching the license list. Please check your network connection and try again."
msgstr ""
+msgid "Licenses|Error: You are trying to upload something other than a file"
+msgstr ""
+
msgid "Licenses|License Compliance"
msgstr "Lisens-overensstemmelse"
@@ -21436,6 +21915,9 @@ msgstr ""
msgid "Licenses|Specified policies in this project"
msgstr ""
+msgid "Licenses|The file could not be uploaded."
+msgstr ""
+
msgid "Licenses|The license list details information about the licenses used within your project."
msgstr ""
@@ -21469,11 +21951,6 @@ msgstr ""
msgid "Limit the size of Sidekiq jobs stored in Redis."
msgstr ""
-msgid "Limited to showing %d event at most"
-msgid_plural "Limited to showing %d events at most"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Limiting mode"
msgstr ""
@@ -21483,6 +21960,9 @@ msgstr "Linjeendringer"
msgid "Link"
msgstr "Lenke"
+msgid "Link (optional)"
+msgstr ""
+
msgid "Link Prometheus monitoring to GitLab."
msgstr ""
@@ -21519,6 +21999,9 @@ msgstr ""
msgid "Linked emails (%{email_count})"
msgstr "Lenkede e-postadresser (%{email_count})"
+msgid "Linked epics"
+msgstr ""
+
msgid "Linked issues"
msgstr "Lenkede saker"
@@ -21546,6 +22029,15 @@ msgstr "List opp tilgjengelige kodelagre"
msgid "List of all merge commits"
msgstr "Liste over alle innflettings-commits"
+msgid "List of environments for this project"
+msgstr ""
+
+msgid "List of suitable GCP locations"
+msgstr ""
+
+msgid "List of users allowed to exceed the rate limit."
+msgstr ""
+
msgid "List options"
msgstr "Listealternativer"
@@ -21765,6 +22257,9 @@ msgstr "Mailgun-hendelser"
msgid "Maintenance mode"
msgstr "Vedlikeholdsmodus"
+msgid "Make adjustments to how your GitLab instance is set up."
+msgstr ""
+
msgid "Make and review changes in the browser with the Web IDE"
msgstr ""
@@ -21909,6 +22404,12 @@ msgstr "Legg til kursiv tekst (%{modifierKey}I)"
msgid "MarkdownEditor|Add italic text (%{modifier_key}I)"
msgstr "Legg til kursiv tekst (%{modifier_key}I)"
+msgid "MarkdownEditor|Add strikethrough text (%{modifierKey}⇧X)"
+msgstr ""
+
+msgid "MarkdownEditor|Add strikethrough text (%{modifier_key}⇧X)"
+msgstr ""
+
msgid "Marked For Deletion At - %{deletion_time}"
msgstr ""
@@ -22170,6 +22671,9 @@ msgstr "Maks push-størrelse"
msgid "Maximum push size (MB)"
msgstr "Maksimal pushstørrelse (MB)"
+msgid "Maximum requests per 10 minutes per user"
+msgstr ""
+
msgid "Maximum requests per minute"
msgstr ""
@@ -22260,6 +22764,19 @@ msgstr ""
msgid "Members of a group may only view projects they have permission to access"
msgstr ""
+msgid "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seat in use and will be billed for the overage."
+msgid_plural "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seats in use and will be billed for the overage."
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "MembersOverage|You are about to incur additional charges"
+msgstr ""
+
+msgid "MembersOverage|Your subscription includes %d seat."
+msgid_plural "MembersOverage|Your subscription includes %d seats."
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Membership"
msgstr ""
@@ -22464,9 +22981,6 @@ msgstr "Fletteforespørselshendelser"
msgid "Merge request not merged"
msgstr ""
-msgid "Merge request pipelines 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 merge request pipelines."
-msgstr ""
-
msgid "Merge request reports"
msgstr ""
@@ -22563,13 +23077,13 @@ msgstr ""
msgid "MergeRequests|Create issue to resolve thread"
msgstr ""
-msgid "MergeRequests|Failed to squash. Should be done manually."
-msgstr ""
-
msgid "MergeRequests|Saving the comment failed"
msgstr "Lagring av kommentaren mislyktes"
-msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
+msgid "MergeRequests|Squashing failed: Squash the commits locally, resolve any conflicts, then push the branch."
+msgstr ""
+
+msgid "MergeRequests|Squashing not allowed: This project doesn't allow you to squash commits when merging."
msgstr ""
msgid "MergeRequests|Thread stays resolved"
@@ -23410,6 +23924,18 @@ msgstr "Distribuer på nytt"
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "MrList|Assigned to %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from assignee %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from reviewer %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Review requested from %{name}, go to their profile."
+msgstr ""
+
msgid "Multi-project"
msgstr "Multi-prosjekt"
@@ -23443,7 +23969,7 @@ msgstr ""
msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "My Awesome Group"
+msgid "My awesome group"
msgstr ""
msgid "My company or team"
@@ -24065,9 +24591,6 @@ msgstr "Ingen autentiseringsmetoder er satt opp."
msgid "No available branches"
msgstr "Ingen tilgjengelige grener"
-msgid "No available groups to fork the project."
-msgstr ""
-
msgid "No branches found"
msgstr "Ingen grener funnet"
@@ -24278,6 +24801,9 @@ msgstr "Ingen offentlige grupper"
msgid "No ref selected"
msgstr ""
+msgid "No regions configured"
+msgstr ""
+
msgid "No related merge requests found."
msgstr ""
@@ -25082,6 +25608,9 @@ msgstr ""
msgid "Only reCAPTCHA v2 is supported:"
msgstr ""
+msgid "Only required if not using role instance credentials."
+msgstr ""
+
msgid "Only use lowercase letters, numbers, and underscores."
msgstr ""
@@ -25106,9 +25635,6 @@ msgstr ""
msgid "Open a CLI and connect to the cluster you want to install the agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
-msgid "Open epics"
-msgstr "Ã…pne eposer"
-
msgid "Open errors"
msgstr "Ã…pne feil"
@@ -25148,8 +25674,8 @@ msgstr "Ã…pnede FF-er"
msgid "Opened issues"
msgstr "Ã…pnede saker"
-msgid "OpenedNDaysAgo|Opened"
-msgstr "Ã…pnet"
+msgid "OpenedNDaysAgo|Created"
+msgstr ""
msgid "Opens in a new window"
msgstr "Ã…pnes i et nytt vindu"
@@ -25193,9 +25719,6 @@ msgstr "Valgfritt"
msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
-msgid "Optional."
-msgstr ""
-
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
msgstr "Eventuelt kan du %{link_to_customize} hvordan FogBugz-e-postadresser og brukernavn importeres til GitLab."
@@ -25984,6 +26507,9 @@ msgstr ""
msgid "PerformanceBar|Memory"
msgstr "Minne"
+msgid "PerformanceBar|Memory report"
+msgstr ""
+
msgid "PerformanceBar|Redis calls"
msgstr ""
@@ -26017,18 +26543,12 @@ msgstr ""
msgid "PerformanceBar|wall"
msgstr ""
-msgid "Performs a rebase but skips triggering a new pipeline"
-msgstr ""
-
msgid "Period in seconds"
msgstr "Periode i sekunder"
msgid "Permalink"
msgstr ""
-msgid "Permanently delete project"
-msgstr ""
-
msgid "Permanently remove group"
msgstr ""
@@ -26299,6 +26819,51 @@ msgstr "Rørledning: %{ciStatus}"
msgid "PipelineStatusTooltip|Pipeline: %{ci_status}"
msgstr "Rørledning: %{ci_status}"
+msgid "PipelineWizardDefaultCommitMessage|Add %{filename}"
+msgstr ""
+
+msgid "PipelineWizardDefaultCommitMessage|Update %{filename}"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|At least one entry is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This field is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This value is not valid"
+msgstr ""
+
+msgid "PipelineWizardListWidget|add another step"
+msgstr ""
+
+msgid "PipelineWizardListWidget|remove step"
+msgstr ""
+
+msgid "PipelineWizard|Commit"
+msgstr ""
+
+msgid "PipelineWizard|Commit Message"
+msgstr ""
+
+msgid "PipelineWizard|Commit changes to your file"
+msgstr ""
+
+msgid "PipelineWizard|Commit file to Branch"
+msgstr ""
+
+msgid "PipelineWizard|Commit your new file"
+msgstr ""
+
+msgid "PipelineWizard|The file has been committed."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem committing the changes."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem while checking whether your file already exists in the specified branch."
+msgstr ""
+
msgid "Pipelines"
msgstr "Rørledninger"
@@ -26413,8 +26978,8 @@ msgstr ""
msgid "Pipelines|Project cache successfully reset."
msgstr ""
-msgid "Pipelines|Revoke"
-msgstr "Tilbakekall"
+msgid "Pipelines|Revoke trigger"
+msgstr ""
msgid "Pipelines|Something went wrong while cleaning runners cache."
msgstr ""
@@ -26458,6 +27023,12 @@ msgstr ""
msgid "Pipelines|This is a child pipeline within the parent pipeline"
msgstr ""
+msgid "Pipelines|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipelines|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipelines|This pipeline will run code originating from a forked project merge request. This means that the code can potentially have security considerations like exposing CI variables."
msgstr ""
@@ -26500,9 +27071,6 @@ msgstr ""
msgid "Pipelines|Your changes have been successfully committed. Now redirecting to the new merge request page."
msgstr ""
-msgid "Pipelines|detached"
-msgstr ""
-
msgid "Pipelines|error"
msgstr ""
@@ -26512,10 +27080,13 @@ msgstr "ugyldig"
msgid "Pipelines|latest"
msgstr ""
-msgid "Pipelines|stuck"
+msgid "Pipelines|merge request"
+msgstr ""
+
+msgid "Pipelines|merge train"
msgstr ""
-msgid "Pipelines|train"
+msgid "Pipelines|stuck"
msgstr ""
msgid "Pipelines|yaml invalid"
@@ -26647,6 +27218,12 @@ msgstr ""
msgid "Pipeline|This change will not change the overall test coverage if merged."
msgstr ""
+msgid "Pipeline|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipeline|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipeline|Trigger author"
msgstr ""
@@ -26671,6 +27248,12 @@ msgstr ""
msgid "Pipeline|for"
msgstr "for"
+msgid "Pipeline|merge request"
+msgstr ""
+
+msgid "Pipeline|merge train"
+msgstr ""
+
msgid "Pipeline|on"
msgstr "den"
@@ -26809,9 +27392,6 @@ msgstr "Vennligst skriv inn et gyldig nummer"
msgid "Please enter a valid time interval"
msgstr ""
-msgid "Please enter or upload a valid license."
-msgstr ""
-
msgid "Please enter your current password."
msgstr ""
@@ -26920,9 +27500,6 @@ msgstr ""
msgid "Please type %{phrase_code} to proceed or close this modal to cancel."
msgstr ""
-msgid "Please type the following to confirm:"
-msgstr "Vennligst skriv inn det følgende for å bekrefte:"
-
msgid "Please use this form to report to the admin users who create spam issues, comments or behave inappropriately."
msgstr ""
@@ -26950,12 +27527,27 @@ msgstr ""
msgid "Policies"
msgstr "Retningslinjer"
+msgid "Policy '%{escalation_policy_name}' does not exist."
+msgstr ""
+
msgid "Policy management project does have any policies in %{policy_path}"
msgstr ""
msgid "Policy project doesn't exist"
msgstr ""
+msgid "PolicyRuleMultiSelect|%{firstLabel} +%{numberOfAdditionalLabels} more"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|All %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select all"
+msgstr ""
+
msgid "Polling interval multiplier"
msgstr ""
@@ -27184,6 +27776,9 @@ msgstr ""
msgid "Private projects can be created in your personal namespace with:"
msgstr ""
+msgid "Problem with %{name} command: %{message}."
+msgstr ""
+
msgid "Proceed"
msgstr "Fortsett"
@@ -27658,6 +28253,9 @@ msgstr "Programmeringsspråk som brukes i dette kodelageret"
msgid "Progress"
msgstr "Fremdrift"
+msgid "Progress tracking"
+msgstr ""
+
msgid "Project"
msgstr "Prosjekt"
@@ -27889,6 +28487,9 @@ msgstr ""
msgid "ProjectQualitySummary|Failure"
msgstr ""
+msgid "ProjectQualitySummary|Get insight into the overall percentage of tests in your project that succeed, fail and are skipped."
+msgstr ""
+
msgid "ProjectQualitySummary|Latest pipeline results"
msgstr ""
@@ -27907,6 +28508,12 @@ msgstr ""
msgid "ProjectQualitySummary|See project Code Coverage Statistics"
msgstr ""
+msgid "ProjectQualitySummary|Set up test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|Set up test runs (opens in a new tab)"
+msgstr ""
+
msgid "ProjectQualitySummary|Skipped"
msgstr ""
@@ -28183,13 +28790,19 @@ msgstr "Saker"
msgid "ProjectSettings|LFS objects from this repository are available to forks. %{linkStart}How do I remove them?%{linkEnd}"
msgstr ""
+msgid "ProjectSettings|Learn about commit history."
+msgstr ""
+
+msgid "ProjectSettings|Leave empty to use default template."
+msgstr ""
+
msgid "ProjectSettings|Manage who can see the project in the public access directory."
msgstr ""
msgid "ProjectSettings|Manages large files such as audio, video, and graphics files."
msgstr ""
-msgid "ProjectSettings|Maximum 500 characters."
+msgid "ProjectSettings|Maximum %{maxLength} characters."
msgstr ""
msgid "ProjectSettings|Merge checks"
@@ -28330,6 +28943,9 @@ msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
msgstr ""
+msgid "ProjectSettings|The default template will be applied on save."
+msgstr ""
+
msgid "ProjectSettings|These checks must pass before merge requests can be merged."
msgstr ""
@@ -28384,6 +29000,9 @@ msgstr ""
msgid "ProjectSettings|What are badges?"
msgstr ""
+msgid "ProjectSettings|What are merge trains?"
+msgstr ""
+
msgid "ProjectSettings|When merge request pipelines are enabled in the CI/CD configuration file, pipelines validate the combined results of the source and target branches. %{link_start}How to configure merge request pipelines?%{link_end}"
msgstr ""
@@ -28501,6 +29120,9 @@ msgstr ""
msgid "Projects are organized into groups"
msgstr ""
+msgid "Projects are where you store your code, access issues, wiki and other features of GitLab."
+msgstr ""
+
msgid "Projects contributed to"
msgstr "Prosjekter bidratt til"
@@ -28516,12 +29138,6 @@ msgstr ""
msgid "Projects to index"
msgstr "Prosjekter å indeksere"
-msgid "Projects will be permanently deleted after a %{waiting_period}-day waiting period."
-msgstr ""
-
-msgid "Projects will be permanently deleted immediately."
-msgstr "Prosjekter vil bli permanent og umiddelbart slettet."
-
msgid "Projects with critical vulnerabilities"
msgstr "Prosjekter med kritiske sårbarheter"
@@ -28606,6 +29222,9 @@ msgstr "Importer"
msgid "ProjectsNew|Import project"
msgstr "Importer prosjekt"
+msgid "ProjectsNew|Include a Getting Started README"
+msgstr ""
+
msgid "ProjectsNew|Initialize repository with a README"
msgstr "Start i gang kodelageret med en README"
@@ -28621,6 +29240,9 @@ msgstr ""
msgid "ProjectsNew|Project description %{tag_start}(optional)%{tag_end}"
msgstr "Prosjektbeskrivelse %{tag_start}(valgfritt)%{tag_end}"
+msgid "ProjectsNew|Recommended if you're new to GitLab"
+msgstr ""
+
msgid "ProjectsNew|Run CI/CD for external repository"
msgstr "Kjør CI/CD for et eksternt kodelager"
@@ -29038,6 +29660,9 @@ msgstr ""
msgid "ProtectedBranch|Unprotect"
msgstr ""
+msgid "ProtectedBranch|Unprotect branch"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
@@ -29065,6 +29690,9 @@ msgstr "Beskytt et miljø"
msgid "ProtectedEnvironment|Protected Environment (%{protected_environments_count})"
msgstr "Beskyttet miljø (%{protected_environments_count})"
+msgid "ProtectedEnvironment|Required approvals"
+msgstr ""
+
msgid "ProtectedEnvironment|Select an environment"
msgstr "Velg et miljø"
@@ -29086,10 +29714,13 @@ msgstr "Miljøet ditt er beskyttet."
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr "Miljøet ditt er blitt ubeskyttet"
+msgid "ProtectedTags|Unprotect tag"
+msgstr ""
+
msgid "ProtectedTags|default"
msgstr ""
-msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
+msgid "ProtectedTag|By default, protected tags restrict who can modify the tag."
msgstr ""
msgid "ProtectedTag|Learn more."
@@ -29152,6 +29783,9 @@ msgstr "Offentlige rørledninger"
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Public projects are an easy way to allow everyone to have read-only access."
+msgstr ""
+
msgid "Publish to status page"
msgstr "Publiser på statussiden"
@@ -29308,9 +29942,6 @@ msgstr ""
msgid "QualitySummary|Project quality"
msgstr ""
-msgid "Quarters"
-msgstr "Kvartal"
-
msgid "Query"
msgstr "Spørring"
@@ -29395,6 +30026,9 @@ msgstr "Les mer om GitLab på %{link_to_promo}."
msgid "Read more about project permissions %{help_link_open}here%{help_link_close}"
msgstr ""
+msgid "Read more about related epics"
+msgstr ""
+
msgid "Read more about related issues"
msgstr ""
@@ -29425,10 +30059,7 @@ msgstr ""
msgid "Rebase source branch on the target branch."
msgstr ""
-msgid "Rebase without CI"
-msgstr ""
-
-msgid "Rebases and triggers a pipeline"
+msgid "Rebase without pipeline"
msgstr ""
msgid "Recaptcha verified?"
@@ -29479,9 +30110,6 @@ msgstr "Nylig brukt"
msgid "Reconfigure"
msgstr "Sett opp på nytt"
-msgid "Recovering projects"
-msgstr "Gjenoppretter prosjekter"
-
msgid "Recovery Codes"
msgstr "Gjenopprettingskoder"
@@ -29541,6 +30169,12 @@ msgstr ""
msgid "Regex pattern"
msgstr "Regex-mønster"
+msgid "Region"
+msgstr ""
+
+msgid "Regions"
+msgstr ""
+
msgid "Register"
msgstr "Register"
@@ -29771,9 +30405,6 @@ msgstr ""
msgid "Remove all or specific reviewer(s)"
msgstr ""
-msgid "Remove approver"
-msgstr "Fjern godkjenner"
-
msgid "Remove approvers"
msgstr "Fjern godkjennere"
@@ -29789,6 +30420,9 @@ msgstr "Fjern tilordnet"
msgid "Remove attention request"
msgstr ""
+msgid "Remove attention request(s)"
+msgstr ""
+
msgid "Remove avatar"
msgstr "Fjern avatar"
@@ -29927,6 +30561,9 @@ msgstr "Fjernet alle stempler."
msgid "Removed an issue from an epic."
msgstr "Fjernet en sak fra et epos."
+msgid "Removed attention from %{users_sentence}."
+msgstr ""
+
msgid "Removed attention request from @%{username}"
msgstr ""
@@ -29978,6 +30615,9 @@ msgstr "Fjerner alle stempler."
msgid "Removes an issue from an epic."
msgstr "Fjerner en sak fra et epos."
+msgid "Removes attention from %{users_sentence}."
+msgstr ""
+
msgid "Removes parent epic %{epic_ref}."
msgstr ""
@@ -30089,6 +30729,9 @@ msgstr "Rapporter misbruk"
msgid "Report abuse to admin"
msgstr "Rapporter misbruk til admin"
+msgid "Report is generating and will be sent to your email address."
+msgstr ""
+
msgid "Reported %{timeAgo} by %{reportedBy}"
msgstr "Rapportert %{timeAgo} av %{reportedBy}"
@@ -30378,6 +31021,15 @@ msgstr "Be om en ny en"
msgid "Request attention"
msgstr ""
+msgid "Request attention from %{users_sentence}."
+msgstr ""
+
+msgid "Request attention from assignee or reviewer"
+msgstr ""
+
+msgid "Request attention from assignee(s) or reviewer(s)"
+msgstr ""
+
msgid "Request attention to review"
msgstr ""
@@ -30402,6 +31054,9 @@ msgstr "Forespurt"
msgid "Requested %{time_ago}"
msgstr "Forespurt %{time_ago}"
+msgid "Requested attention from %{users_sentence}."
+msgstr ""
+
msgid "Requested attention from @%{username}"
msgstr ""
@@ -30616,6 +31271,9 @@ msgstr "Gjenopprett gruppe"
msgid "Restore project"
msgstr "Gjenopprett prosjekt"
+msgid "Restoring projects"
+msgstr ""
+
msgid "Restoring the group will prevent the group, its subgroups and projects from being removed on this date."
msgstr ""
@@ -30646,6 +31304,9 @@ msgstr ""
msgid "Retry"
msgstr "Forsøk igjen"
+msgid "Retry failed jobs"
+msgstr ""
+
msgid "Retry job"
msgstr ""
@@ -30693,9 +31354,6 @@ msgstr "Vis nyligste app"
msgid "Review changes"
msgstr "GÃ¥ gjennom endringer"
-msgid "Review requested from %{name}"
-msgstr ""
-
msgid "Review requests for you"
msgstr "Gjennomgangsforespørsler til deg"
@@ -30860,6 +31518,9 @@ msgstr "Arkitektur"
msgid "Runners|Assigned Group"
msgstr ""
+msgid "Runners|Assigned Projects (%{projectCount})"
+msgstr ""
+
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30929,6 +31590,9 @@ msgstr ""
msgid "Runners|Instance"
msgstr ""
+msgid "Runners|Jobs"
+msgstr ""
+
msgid "Runners|Last contact"
msgstr "Siste kontakt"
@@ -31022,9 +31686,6 @@ msgstr ""
msgid "Runners|Runner %{name} was deleted"
msgstr ""
-msgid "Runners|Runner ID"
-msgstr ""
-
msgid "Runners|Runner assigned to project."
msgstr ""
@@ -31172,6 +31833,9 @@ msgstr "spesifikk"
msgid "Runners|stale"
msgstr ""
+msgid "Runner|This runner has not run any jobs."
+msgstr ""
+
msgid "Running"
msgstr "Kjører"
@@ -31286,6 +31950,24 @@ msgstr "Lagrer"
msgid "Saving project."
msgstr "Lagrer prosjekt."
+msgid "ScanResultPolicy|%{ifLabelStart}if%{ifLabelEnd} %{scanners} scan in an open merge request targeting the %{branches} branch(es) finds %{vulnerabilitiesAllowed} or more %{severities} vulnerabilities that are %{vulnerabilityStates}"
+msgstr ""
+
+msgid "ScanResultPolicy|%{thenLabelStart}Then%{thenLabelEnd} Require approval from %{approvalsRequired} of the following approvers: %{approvers}"
+msgstr ""
+
+msgid "ScanResultPolicy|add an approver"
+msgstr ""
+
+msgid "ScanResultPolicy|scanners"
+msgstr ""
+
+msgid "ScanResultPolicy|severity levels"
+msgstr ""
+
+msgid "ScanResultPolicy|vulnerability states"
+msgstr ""
+
msgid "Scanner"
msgstr "Skanner"
@@ -31418,6 +32100,9 @@ msgstr "Søk etter en gruppe"
msgid "Search for a user"
msgstr "Søk etter en bruker"
+msgid "Search for an emoji"
+msgstr ""
+
msgid "Search for projects, issues, etc."
msgstr "Søk etter prosjekter, saker, etc."
@@ -31605,18 +32290,12 @@ msgstr "Hemmelig"
msgid "Secret Detection"
msgstr "Hemmelig oppdagelse"
-msgid "Secret access key"
-msgstr ""
-
msgid "Secret token"
msgstr "Hemmelig sjetong"
msgid "Secure token that identifies an external storage request."
msgstr ""
-msgid "SecureCodeWarrior"
-msgstr ""
-
msgid "Security"
msgstr "Sikkerhet"
@@ -31641,9 +32320,6 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "Security training with guide and learning pathways."
-msgstr ""
-
msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
@@ -31746,7 +32422,7 @@ msgstr ""
msgid "SecurityConfiguration|Manage corpus"
msgstr ""
-msgid "SecurityConfiguration|Manage corpus files used as mutation sources in coverage fuzzing."
+msgid "SecurityConfiguration|Manage corpus files used as seed inputs with coverage-guided fuzzing."
msgstr ""
msgid "SecurityConfiguration|Manage profiles for use by DAST scans."
@@ -31812,15 +32488,15 @@ msgstr "%{branches} og %{lastBranch} %{plural}"
msgid "SecurityOrchestration|.yaml preview"
msgstr ""
-msgid "SecurityOrchestration|Action"
-msgstr "Handling"
-
msgid "SecurityOrchestration|Actions"
msgstr ""
msgid "SecurityOrchestration|Add rule"
msgstr ""
+msgid "SecurityOrchestration|After dismissing the alert, the information will never be shown again."
+msgstr ""
+
msgid "SecurityOrchestration|All policies"
msgstr "Alle retningslinjer"
@@ -31836,7 +32512,7 @@ msgstr ""
msgid "SecurityOrchestration|Description"
msgstr "Beskrivelse"
-msgid "SecurityOrchestration|Disabled"
+msgid "SecurityOrchestration|Don't show the alert anymore"
msgstr ""
msgid "SecurityOrchestration|Edit policy"
@@ -31845,13 +32521,13 @@ msgstr ""
msgid "SecurityOrchestration|Edit policy project"
msgstr ""
-msgid "SecurityOrchestration|Enabled"
+msgid "SecurityOrchestration|Empty policy name"
msgstr ""
-msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Enabled"
msgstr ""
-msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
msgstr ""
msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
@@ -31860,8 +32536,8 @@ msgstr "Hvis du bruker Auto DevOps, vil ikke din %{monospacedStart}auto-deploy-v
msgid "SecurityOrchestration|Invalid policy type"
msgstr ""
-msgid "SecurityOrchestration|Latest scan"
-msgstr "Seneste skanning"
+msgid "SecurityOrchestration|Latest scan run against %{agent}"
+msgstr ""
msgid "SecurityOrchestration|Network"
msgstr "Nettverk"
@@ -31869,15 +32545,27 @@ msgstr "Nettverk"
msgid "SecurityOrchestration|New policy"
msgstr "Ny retningslinje"
+msgid "SecurityOrchestration|No actions defined - policy will not run."
+msgstr ""
+
+msgid "SecurityOrchestration|No description"
+msgstr ""
+
msgid "SecurityOrchestration|No rules defined - policy will not run."
msgstr ""
+msgid "SecurityOrchestration|Not enabled"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
msgid "SecurityOrchestration|Policies"
msgstr ""
+msgid "SecurityOrchestration|Policy Type"
+msgstr ""
+
msgid "SecurityOrchestration|Policy cannot be enabled for non-existing branches (%{branches})"
msgstr ""
@@ -31902,12 +32590,15 @@ msgstr ""
msgid "SecurityOrchestration|Require %{approvals} %{plural} from %{approvers} if any of the following occur:"
msgstr ""
-msgid "SecurityOrchestration|Rule"
-msgstr "Regel"
-
msgid "SecurityOrchestration|Rules"
msgstr ""
+msgid "SecurityOrchestration|Runs %{actions} and %{lastAction} scans"
+msgstr ""
+
+msgid "SecurityOrchestration|Runs a %{action} scan"
+msgstr ""
+
msgid "SecurityOrchestration|Scan Execution"
msgstr ""
@@ -31965,6 +32656,9 @@ msgstr ""
msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
+msgid "SecurityOrchestration|This view only shows scan results for the agent %{agent}. You can view scan results for all agents in the %{linkStart}Operational Vulnerabilities tab of the vulnerability report%{linkEnd}."
+msgstr ""
+
msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
@@ -32019,9 +32713,6 @@ msgstr ""
msgid "SecurityOrchestration|users with ids"
msgstr ""
-msgid "SecurityOrchestration|view results"
-msgstr "vis resultater"
-
msgid "SecurityOrchestration|vulnerabilities"
msgstr ""
@@ -32691,22 +33382,19 @@ msgstr "Kopier URL"
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|In order to start using functions as a service, you must first install Knative on your Kubernetes cluster. %{linkStart}More information%{linkEnd}"
-msgstr ""
-
msgid "Serverless|Learn more about Serverless"
msgstr ""
msgid "Serverless|No functions available"
msgstr "Ingen funksjoner er tilgjengelige"
-msgid "Serverless|Sign up for First Look"
+msgid "Serverless|Serverless was %{linkStart}deprecated%{linkEnd} in GitLab 14.3."
+msgstr ""
+
+msgid "Serverless|Serverless was %{postLinkStart}deprecated%{postLinkEnd}. But if you opt to use it, you must install Knative in your Kubernetes cluster first. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "Serverless|The deploy job has not finished."
@@ -32718,9 +33406,6 @@ 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 ""
@@ -32736,9 +33421,6 @@ msgstr ""
msgid "Service Account Key"
msgstr ""
-msgid "Service Accounts"
-msgstr ""
-
msgid "Service Accounts keys authorize GitLab to deploy your Google Cloud project"
msgstr ""
@@ -32748,10 +33430,10 @@ msgstr "Tjenestedesk"
msgid "Service Desk allows people to create issues in your GitLab instance without their own user account. It provides a unique email address for end users to create issues in a project. Replies can be sent either through the GitLab interface or by email. End users only see threads through email."
msgstr "Tjenestedesken lar folk opprette saksrapporter i din GitLab-forekomst uten å ha sin egen brukerkonto. Det sørger for en unik e-postadresse for sluttbrukere til å opprette saksrapporter i et prosjekt. Svar kan sendes enten via GitLab-grensesnittet eller via e-post. Sluttbrukere ser kun tråden via e-post."
-msgid "Service Usage Data"
+msgid "Service account generated successfully"
msgstr ""
-msgid "Service account generated successfully"
+msgid "Service accounts"
msgstr ""
msgid "Service ping is disabled in your configuration file, and cannot be enabled through this form."
@@ -32895,6 +33577,9 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr "Sett milepælen til %{milestone_reference}."
+msgid "Set the per-user rate limit for getting a user by ID via the API."
+msgstr ""
+
msgid "Set the per-user rate limit for notes created by web or API requests."
msgstr ""
@@ -33074,6 +33759,9 @@ msgstr ""
msgid "Shared runners details"
msgstr ""
+msgid "Shared runners enabled cannot be enabled until a valid credit card is on file"
+msgstr ""
+
msgid "Shared runners help link"
msgstr ""
@@ -33131,6 +33819,9 @@ msgstr ""
msgid "Show all issues."
msgstr "Vis alle saker."
+msgid "Show all milestones"
+msgstr ""
+
msgid "Show all test cases."
msgstr "Vis alle testsaker."
@@ -33167,6 +33858,9 @@ msgstr "Vis filutforsker"
msgid "Show file contents"
msgstr "Vis filens innhold"
+msgid "Show group milestones"
+msgstr ""
+
msgid "Show labels"
msgstr "Vis stempler"
@@ -33182,6 +33876,12 @@ msgstr "Vis én fil om gangen"
msgid "Show open epics"
msgstr ""
+msgid "Show project milestones"
+msgstr ""
+
+msgid "Show sub-group milestones"
+msgstr ""
+
msgid "Show the Closed list"
msgstr "Vis «Lukket»-listen"
@@ -33191,11 +33891,6 @@ msgstr "Vis «Åpne»-listen"
msgid "Show whitespace changes"
msgstr "Vis tomromsendringer"
-msgid "Showing %d event"
-msgid_plural "Showing %d events"
-msgstr[0] "Viser %d hendelse"
-msgstr[1] "Viser %d hendelser"
-
msgid "Showing %{conflict} between %{sourceBranch} and %{targetBranch}"
msgstr "Viser %{conflict} mellom %{sourceBranch} og %{targetBranch}"
@@ -33255,12 +33950,6 @@ msgstr "Ingen status"
msgid "Sidebar|None"
msgstr "Ingen"
-msgid "Sidebar|Only numeral characters allowed"
-msgstr ""
-
-msgid "Sidebar|Weight"
-msgstr "Vektlegging"
-
msgid "Sidekiq job compression threshold (bytes)"
msgstr ""
@@ -33423,6 +34112,9 @@ msgstr ""
msgid "Slack logo"
msgstr ""
+msgid "SlackIntegration|Are you sure you want to remove this project from the Slack application?"
+msgstr ""
+
msgid "SlackIntegration|GitLab for Slack"
msgstr ""
@@ -33432,6 +34124,9 @@ msgstr ""
msgid "SlackIntegration|Project alias"
msgstr ""
+msgid "SlackIntegration|Remove project"
+msgstr ""
+
msgid "SlackIntegration|Select a GitLab project to link with your Slack workspace."
msgstr ""
@@ -33576,9 +34271,6 @@ msgstr "Noe gikk galt under endring av låsestatus på denne %{issuableDisplayNa
msgid "Something went wrong trying to load issue contacts."
msgstr ""
-msgid "Something went wrong when creating a work item. Please try again"
-msgstr ""
-
msgid "Something went wrong when reordering designs. Please try again"
msgstr ""
@@ -33672,9 +34364,6 @@ msgstr "Noe gikk galt under oppstart av OpenAPI-visningen"
msgid "Something went wrong while inserting your image. Please try again."
msgstr "Noe gikk galt under redigering av innsetting av bildet ditt. Prøv igjen senere."
-msgid "Something went wrong while merging this merge request. Please try again."
-msgstr ""
-
msgid "Something went wrong while obtaining the Let's Encrypt certificate."
msgstr ""
@@ -33996,11 +34685,11 @@ msgstr "Skru på Sourcegraph"
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."
+msgid "SourcegraphAdmin|Learn more."
msgstr ""
-msgid "SourcegraphAdmin|More information"
-msgstr "Mer informasjon"
+msgid "SourcegraphAdmin|Only public projects have code intelligence enabled and communicate with Sourcegraph."
+msgstr ""
msgid "SourcegraphAdmin|Save changes"
msgstr "Lagre endringer"
@@ -34008,8 +34697,8 @@ msgstr "Lagre endringer"
msgid "SourcegraphAdmin|Sourcegraph URL"
msgstr "Sourcegraph-URL"
-msgid "SourcegraphAdmin|e.g. https://sourcegraph.example.com"
-msgstr "f.eks. https://sourcegraph.example.com"
+msgid "SourcegraphAdmin|https://sourcegraph.example.com"
+msgstr ""
msgid "SourcegraphPreferences|This feature is experimental and currently limited to certain projects."
msgstr "Denne funksjonen er eksperimentell og er for tiden begrenset til visse prosjekter."
@@ -34143,6 +34832,9 @@ msgstr "Start opprydding"
msgid "Start date"
msgstr "Startdato"
+msgid "Start free trial"
+msgstr ""
+
msgid "Start merge train"
msgstr ""
@@ -34173,6 +34865,9 @@ msgstr "Startet %{startsIn}"
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started escalation for this incident."
+msgstr ""
+
msgid "Starting..."
msgstr "Starter …"
@@ -34185,6 +34880,9 @@ msgstr "Starter %{startsIn}"
msgid "Starts at (UTC)"
msgstr "Starter (UTC)"
+msgid "Starts escalations for this incident"
+msgstr ""
+
msgid "Starts on"
msgstr "Starter den"
@@ -34446,6 +35144,9 @@ msgstr "Ukjent"
msgid "Strikethrough"
msgstr "Gjennomstrek"
+msgid "Strikethrough text"
+msgstr ""
+
msgid "Subgroup information"
msgstr "Undergruppe-informasjon"
@@ -34680,6 +35381,21 @@ msgstr ""
msgid "Subscriptions"
msgstr "Abonnementer"
+msgid "Subscriptions|Chat with sales"
+msgstr ""
+
+msgid "Subscriptions|Close"
+msgstr ""
+
+msgid "Subscriptions|Not ready to buy yet?"
+msgstr ""
+
+msgid "Subscriptions|Start a free trial"
+msgstr ""
+
+msgid "Subscriptions|We understand. Maybe you have some questions for our sales team, or maybe you'd like to try some of the paid features first. What would you like to do?"
+msgstr ""
+
msgid "Subscription|Your subscription for %{strong}%{namespace_name}%{strong_close} has expired and you are now on %{pricing_link_start}the GitLab Free tier%{pricing_link_end}. Don't worry, your data is safe. Get in touch with our support team (%{support_email}). They'll gladly help with your subscription renewal."
msgstr ""
@@ -34890,6 +35606,9 @@ msgstr "Behandle"
msgid "SuperSonics|Maximum users"
msgstr "Maks antall brukere"
+msgid "SuperSonics|Offline cloud"
+msgstr ""
+
msgid "SuperSonics|Paste your activation code"
msgstr "Lim inn aktiveringskoden din"
@@ -34956,6 +35675,12 @@ msgstr ""
msgid "SuperSonics|You do not have an active subscription"
msgstr ""
+msgid "SuperSonics|You have a future dated license"
+msgstr ""
+
+msgid "SuperSonics|You have added a license that activates on %{date}. Please see the subscription history table below for more details."
+msgstr ""
+
msgid "SuperSonics|You have successfully added a license that activates on %{date}. Please see the subscription history table below for more details."
msgstr ""
@@ -35115,6 +35840,9 @@ msgstr "Navn på tag"
msgid "Tag name is required"
msgstr "Etikettnavn er påkrevd"
+msgid "Tag push"
+msgstr ""
+
msgid "Tag push events"
msgstr ""
@@ -35217,6 +35945,9 @@ msgstr "Skriv inn dine utgivelsesbeskrivelser eller dra filer hit …"
msgid "TagsPage|protected"
msgstr "beskyttet"
+msgid "Take a look at the documentation to discover all of GitLab’s capabilities."
+msgstr ""
+
msgid "Target Branch"
msgstr "MÃ¥lgren"
@@ -35619,6 +36350,9 @@ msgstr ""
msgid "Tests"
msgstr "Tester"
+msgid "Text (optional)"
+msgstr ""
+
msgid "Text added to the body of all email messages. %{character_limit} character limit"
msgstr ""
@@ -35669,6 +36403,9 @@ msgstr ""
msgid "The CSV export will be created in the background. Once finished, it will be sent to %{email} in an attachment."
msgstr ""
+msgid "The CSV export you requested of all user memberships is attached to this email."
+msgstr ""
+
msgid "The GitLab subscription service (customers.gitlab.com) is currently experiencing an outage. You can monitor the status and get updates at %{linkStart}status.gitlab.com%{linkEnd}."
msgstr ""
@@ -35744,6 +36481,9 @@ 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 "Innholdet i denne gruppen, dens undergrupper og prosjekter blir fjernet permanent etter %{deletion_adjourned_period} dager den %{date}. Etter det kan ikke dataene dine gjenopprettes."
+msgid "The current epic"
+msgstr ""
+
msgid "The current issue"
msgstr "Den nåværende saken"
@@ -35905,6 +36645,9 @@ msgstr ""
msgid "The latest pipeline for this merge request has failed."
msgstr ""
+msgid "The license key is invalid."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -35920,6 +36663,9 @@ msgstr ""
msgid "The license was successfully uploaded and will be active from %{starts_at}. You can see the details below."
msgstr ""
+msgid "The license you uploaded is invalid. If the issue persists, contact support at %{link}."
+msgstr ""
+
msgid "The list creation wizard is already open"
msgstr ""
@@ -36541,10 +37287,13 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} and everything this project contains. %{strongOpen}There is no going back%{strongClose}"
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}on %{date}%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains."
+msgstr ""
+
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains. %{strongOpen}There is no going back.%{strongClose}"
msgstr ""
msgid "This action will %{strongOpen}permanently remove%{strongClose} %{codeOpen}%{group}%{codeClose} %{strongOpen}immediately%{strongClose}."
@@ -36673,9 +37422,6 @@ msgstr "Dette feltet er påkrevd."
msgid "This file was modified for readability, and can't accept suggestions. Edit it directly."
msgstr ""
-msgid "This forked project has the following:"
-msgstr ""
-
msgid "This form is disabled in preview"
msgstr ""
@@ -36688,7 +37434,7 @@ msgstr ""
msgid "This group can't be removed because it is linked to a subscription. To remove this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
-msgid "This group can't be transfered because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
+msgid "This group can't be transferred because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
msgid "This group cannot be invited to a project inside a group with enforced SSO"
@@ -36715,6 +37461,9 @@ 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 incident is already escalated with '%{escalation_policy_name}'."
+msgstr ""
+
msgid "This invitation was sent to %{mail_to_invite_email}, but you are signed in as %{link_to_current_user} with email %{mail_to_current_user}."
msgstr ""
@@ -36733,9 +37482,6 @@ msgstr ""
msgid "This is a list of devices that have logged into your account. Revoke any sessions that you do not recognize."
msgstr "Dette er en liste over enheter som har logget seg på kontoen din. Tilbakekall alle økter som du ikke kjenner igjen."
-msgid "This is a merge train pipeline"
-msgstr ""
-
msgid "This is a private email address %{helpIcon} generated just for you. Anyone who has it can create issues or merge requests as if they were you. If that happens, %{resetLinkStart}reset this token%{resetLinkEnd}."
msgstr ""
@@ -36757,6 +37503,12 @@ msgstr ""
msgid "This is your current session"
msgstr "Dette er din nåværende økt"
+msgid "This issue cannot be assigned to a confidential epic because it is public."
+msgstr ""
+
+msgid "This issue cannot be made public because it belongs to a confidential epic."
+msgstr ""
+
msgid "This issue is confidential and should only be visible to team members with at least Reporter access."
msgstr ""
@@ -36874,6 +37626,9 @@ msgstr "Dette kan avsløre konfidensiell informasjon, ettersom den valgte utgrei
msgid "This means you can not push code until you create an empty repository or import existing one."
msgstr ""
+msgid "This merge request branch is protected from force push."
+msgstr ""
+
msgid "This merge request cannot be rebased while there are conflicts."
msgstr ""
@@ -36925,9 +37680,15 @@ msgstr ""
msgid "This pipeline was triggered by a schedule."
msgstr ""
+msgid "This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project"
msgstr "Dette prosjektet"
+msgid "This project can be restored until %{date}."
+msgstr ""
+
msgid "This project cannot be %{visibilityLevel} because the visibility of %{openShowLink}%{name}%{closeShowLink} is %{visibility}. To make this project %{visibilityLevel}, you must first %{openEditLink}change the visibility%{closeEditLink} of the parent group."
msgstr ""
@@ -36946,6 +37707,9 @@ msgstr "Dette prosjektet har ingen aktive tilgangssjetonger."
msgid "This project is %{strongStart}NOT%{strongEnd} a fork, and has the following:"
msgstr ""
+msgid "This project is %{strongStart}NOT%{strongEnd} a fork. This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -37637,6 +38401,9 @@ msgstr ""
msgid "Today"
msgstr "I dag"
+msgid "Todos count"
+msgstr ""
+
msgid "Todos|Are you looking for things to do? Take a look at %{strongStart}%{openIssuesLinkStart}open issues%{openIssuesLinkEnd}%{strongEnd}, contribute to %{strongStart}%{mergeRequestLinkStart}a merge request%{mergeRequestLinkEnd}%{mergeRequestLinkEnd}%{strongEnd}, or mention someone in a comment to automatically assign them a new to-do item."
msgstr ""
@@ -37910,10 +38677,8 @@ msgstr "Tre-visning"
msgid "Trending"
msgstr "Populære"
-msgid "Trials|%{planName} Trial %{enDash} %{num} day left"
-msgid_plural "Trials|%{planName} Trial %{enDash} %{num} days left"
-msgstr[0] ""
-msgstr[1] ""
+msgid "Trials|%{planName} Trial"
+msgstr ""
msgid "Trials|Compare all plans"
msgstr "Sammenlign alle planer"
@@ -37921,6 +38686,9 @@ msgstr "Sammenlign alle planer"
msgid "Trials|Create a new group to start your GitLab Ultimate trial."
msgstr ""
+msgid "Trials|Day %{daysUsed}/%{duration}"
+msgstr ""
+
msgid "Trials|Go back to GitLab"
msgstr "GÃ¥ tilbake til GitLab"
@@ -38170,7 +38938,7 @@ msgstr ""
msgid "URL is triggered when repository is updated"
msgstr ""
-msgid "URL must be percent-encoded if neccessary."
+msgid "URL must be percent-encoded if necessary."
msgstr ""
msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
@@ -38389,6 +39157,9 @@ msgstr "LÃ¥s opp"
msgid "Unlock account"
msgstr "LÃ¥s opp konto"
+msgid "Unlock more features with GitLab Ultimate"
+msgstr ""
+
msgid "Unlock the discussion"
msgstr "LÃ¥s opp diskusjonen"
@@ -38452,6 +39223,9 @@ msgstr ""
msgid "Unsubscribes from this %{quick_action_target}."
msgstr ""
+msgid "Unsupported sort value."
+msgstr ""
+
msgid "Unsupported todo type passed. Supported todo types are: %{todo_types}"
msgstr ""
@@ -38680,6 +39454,9 @@ msgstr "Bruk i nåværende periode"
msgid "UsageQuota|File attachments and smaller design graphics."
msgstr ""
+msgid "UsageQuota|From %{storage_enforcement_date} storage limits will apply to this namespace. View and manage your usage in %{strong_start}Group Settings &gt; Usage quotas%{strong_end}."
+msgstr ""
+
msgid "UsageQuota|Git repository."
msgstr ""
@@ -38740,6 +39517,9 @@ msgstr "Lagring"
msgid "UsageQuota|Storage type"
msgstr ""
+msgid "UsageQuota|Storage used"
+msgstr ""
+
msgid "UsageQuota|This is the total amount of storage used across your projects within this namespace."
msgstr ""
@@ -38935,6 +39715,12 @@ msgstr "Bruk saltet lagring"
msgid "Use hashed storage paths for newly created and renamed repositories. Always enabled since 13.0."
msgstr ""
+msgid "Use issue count"
+msgstr ""
+
+msgid "Use issue weight"
+msgstr ""
+
msgid "Use one line per URI"
msgstr "Bruk en linje per URI"
@@ -39316,6 +40102,9 @@ msgstr "Brukernavn: %{username}"
msgid "Users"
msgstr "Brukere"
+msgid "Users API rate limit"
+msgstr ""
+
msgid "Users can launch a development environment from a GitLab browser tab when the %{linkStart}Gitpod%{linkEnd} integration is enabled."
msgstr "Brukere kan starte opp et utviklingsmiljø fra en GitLab-nettleserfane hvis %{linkStart}Gitpod%{linkEnd}-integrasjonen er skrudd på."
@@ -39641,6 +40430,9 @@ msgstr ""
msgid "View group labels"
msgstr "Vis gruppeetiketter"
+msgid "View group pipeline usage quota"
+msgstr ""
+
msgid "View incident details at"
msgstr ""
@@ -39793,6 +40585,9 @@ msgstr "SÃ¥rbarheter"
msgid "Vulnerabilities over time"
msgstr "SÃ¥rbarheter over tid"
+msgid "Vulnerability"
+msgstr ""
+
msgid "Vulnerability Report"
msgstr "SÃ¥rbarhetsrapport"
@@ -39844,6 +40639,9 @@ msgstr ""
msgid "VulnerabilityManagement|An unverified non-confirmed finding"
msgstr ""
+msgid "VulnerabilityManagement|At least one identifier is required"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr "Endre status"
@@ -39853,12 +40651,24 @@ msgstr "Kunne ikke behandle %{issueReference}: %{errorMessage}."
msgid "VulnerabilityManagement|Create Jira issue"
msgstr ""
+msgid "VulnerabilityManagement|Enter a name"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE code"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE identifier URL"
+msgstr ""
+
msgid "VulnerabilityManagement|Fetching linked Jira issues"
msgstr ""
msgid "VulnerabilityManagement|Manually add a vulnerability entry into the vulnerability report."
msgstr ""
+msgid "VulnerabilityManagement|Name is a required field"
+msgstr ""
+
msgid "VulnerabilityManagement|Needs triage"
msgstr ""
@@ -39874,6 +40684,18 @@ msgstr ""
msgid "VulnerabilityManagement|Select a method"
msgstr ""
+msgid "VulnerabilityManagement|Select a severity level"
+msgstr ""
+
+msgid "VulnerabilityManagement|Select a status"
+msgstr ""
+
+msgid "VulnerabilityManagement|Severity is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Something went wrong while creating vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr "Noe gikk galt under sletting av kommentaren. Prøv igjen senere."
@@ -39898,6 +40720,12 @@ msgstr "Noe gikk galt, kunne ikke hente bruker."
msgid "VulnerabilityManagement|Something went wrong, could not update vulnerability state."
msgstr "Noe gikk galt, kunne ikke oppdatere sårbarhetsstatusen."
+msgid "VulnerabilityManagement|Status is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Submit vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Summary, detailed description, steps to reproduce, etc."
msgstr ""
@@ -40093,6 +40921,9 @@ msgstr ""
msgid "WARNING:"
msgstr "ADVARSEL:"
+msgid "WARNING: This snippet contains hidden files which might be used to mask malicious behavior. Exercise caution if cloning and executing code from this snippet."
+msgstr ""
+
msgid "Wait for the file to load to copy its contents"
msgstr ""
@@ -40312,6 +41143,15 @@ msgstr ""
msgid "Webhooks|An issue is created, updated, closed, or reopened."
msgstr ""
+msgid "Webhooks|Are you sure you want to delete this group hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this project hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this webhook?"
+msgstr ""
+
msgid "Webhooks|Comments"
msgstr "Kommentarer"
@@ -40321,6 +41161,9 @@ msgstr ""
msgid "Webhooks|Confidential issues events"
msgstr ""
+msgid "Webhooks|Delete webhook"
+msgstr ""
+
msgid "Webhooks|Deployment events"
msgstr ""
@@ -40554,6 +41397,9 @@ msgstr ""
msgid "Wiki"
msgstr "Wiki"
+msgid "Wiki page"
+msgstr ""
+
msgid "Wiki page was successfully created."
msgstr ""
@@ -40659,7 +41505,7 @@ msgstr "Vil du slette siden %{pageTitle}?"
msgid "WikiPageConflictMessage|Someone edited the page the same time you did. Please check out %{wikiLinkStart}the page%{wikiLinkEnd} and make sure your changes will not unintentionally remove theirs."
msgstr ""
-msgid "WikiPage|An error occured while trying to render the content editor. Please try again later."
+msgid "WikiPage|An error occurred while trying to render the content editor. Please try again later."
msgstr ""
msgid "WikiPage|Are you sure you want to switch back to the classic editor?"
@@ -40818,6 +41664,18 @@ msgstr ""
msgid "WorkItem|New Task"
msgstr ""
+msgid "WorkItem|Something went wrong when creating a work item. Please try again"
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching the work item. Please try again."
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching work item types. Please try again"
+msgstr ""
+
+msgid "WorkItem|Type"
+msgstr ""
+
msgid "WorkItem|Work Items"
msgstr ""
@@ -40884,7 +41742,10 @@ msgstr ""
msgid "You are about to add %{usersTag} people to the discussion. They will all receive a notification."
msgstr ""
-msgid "You are about to permanently delete this project"
+msgid "You are about to delete this forked project containing:"
+msgstr ""
+
+msgid "You are about to delete this project containing:"
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."
@@ -40905,6 +41766,9 @@ msgstr ""
msgid "You are attempting to update a file that has changed since you started editing it."
msgstr ""
+msgid "You are billed if you exceed this number. %{qsrOverageLinkStart}How does billing work?%{qsrOverageLinkEnd}"
+msgstr ""
+
msgid "You are connected to the Prometheus server, but there is currently no data to display."
msgstr ""
@@ -40962,6 +41826,9 @@ msgstr ""
msgid "You are not authorized to update this scanner profile"
msgstr ""
+msgid "You are not authorized to upload metric images"
+msgstr ""
+
msgid "You are now impersonating %{username}"
msgstr ""
@@ -41115,9 +41982,6 @@ msgstr ""
msgid "You can only upload one design when dropping onto an existing design."
msgstr ""
-msgid "You can recover this project until %{date}"
-msgstr "Du kan gjenopprette dette prosjektet frem til %{date}"
-
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 ""
@@ -41166,9 +42030,6 @@ msgstr ""
msgid "You cannot write to this read-only GitLab instance."
msgstr ""
-msgid "You can’t %{tag_start}edit%{tag_end} files directly in this project. Fork this project and submit a merge request with your changes."
-msgstr ""
-
msgid "You can’t edit files directly in this project. Fork this project and submit a merge request with your changes."
msgstr ""
@@ -41321,9 +42182,6 @@ msgstr "Du har ingen tillatelser"
msgid "You have not added any approvers. Start by adding users or groups."
msgstr "Du har ikke lagt til noen godkjennere. Begynn med å legge til brukere eller grupper."
-msgid "You have reached your project limit"
-msgstr "Du har nådd prosjektgrensen"
-
msgid "You have set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
@@ -41354,12 +42212,6 @@ msgstr ""
msgid "You must have maintainer access to force delete a lock"
msgstr "Du må ha vedlikeholder-tilgang for å tvangsslette en lås"
-msgid "You must have permission to create a project in a group before forking."
-msgstr "Du må tillatelse til å opprette et prosjekt i en gruppe før utgreining."
-
-msgid "You must have permission to create a project in a namespace before forking."
-msgstr "Du må tillatelse til å opprette et prosjekt i et navneområde før utgreining."
-
msgid "You must provide a valid current password"
msgstr "Du må oppgi et gjeldende gyldig passord"
@@ -41765,8 +42617,8 @@ msgstr "Dine prosjekter"
msgid "Your public email will be displayed on your public profile."
msgstr ""
-msgid "Your request for access could not be processed: %{error_meesage}"
-msgstr "Din tilgangsforespørsel kunne ikke behandles: %{error_meesage}"
+msgid "Your request for access could not be processed: %{error_message}"
+msgstr ""
msgid "Your request for access has been queued for review."
msgstr ""
@@ -41948,6 +42800,9 @@ msgstr "arkivert"
msgid "archived:"
msgstr "arkivert:"
+msgid "artifacts"
+msgstr ""
+
msgid "assign yourself"
msgstr "tildel deg selv"
@@ -41977,6 +42832,9 @@ msgstr[1] "grener"
msgid "branch name"
msgstr "grennavn"
+msgid "builds"
+msgstr ""
+
msgid "by"
msgstr "av"
@@ -42400,6 +43258,9 @@ msgstr ""
msgid "contact with same email already exists in group hierarchy"
msgstr ""
+msgid "container registry images"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -42439,6 +43300,9 @@ msgstr "laget av"
msgid "data"
msgstr "data"
+msgid "database"
+msgstr ""
+
msgid "date must not be after 9999-12-31"
msgstr ""
@@ -42462,9 +43326,6 @@ msgstr "distribuering"
msgid "design"
msgstr "design"
-msgid "detached"
-msgstr "frakoblet"
-
msgid "disabled"
msgstr "ikke i bruk"
@@ -42713,7 +43574,7 @@ msgstr ""
msgid "is not a valid X509 certificate."
msgstr "er ikke et gyldig X509-sertifikat."
-msgid "is not allowed for sign-up."
+msgid "is not allowed for sign-up. Please use your regular email address."
msgstr ""
msgid "is not allowed for this group."
@@ -42725,7 +43586,7 @@ msgstr ""
msgid "is not allowed since the group is not top-level group."
msgstr ""
-msgid "is not allowed."
+msgid "is not allowed. Please use your regular email address."
msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
@@ -42812,6 +43673,9 @@ msgstr "mindre enn ett minutt"
msgid "level: %{level}"
msgstr "nivå: %{level}"
+msgid "lfs objects"
+msgstr ""
+
msgid "limit of %{project_limit} reached"
msgstr "grensen på %{project_limit} er nådd"
@@ -43031,6 +43895,9 @@ msgstr ""
msgid "mrWidget|Merge blocked: pipeline must succeed. It's waiting for a manual action to continue."
msgstr ""
+msgid "mrWidget|Merge blocked: pipeline must succeed. Push a commit that fixes the failure, or %{linkStart}learn about other solutions.%{linkEnd}"
+msgstr ""
+
msgid "mrWidget|Merge blocked: this merge request must be approved."
msgstr ""
@@ -43148,9 +44015,6 @@ msgstr "Endringene ble flettet inn i"
msgid "mrWidget|The changes were not merged into"
msgstr "Endringene ble ikke flettet inn i"
-msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr "Kildegrenen har blitt slettet"
@@ -43298,9 +44162,6 @@ msgstr ""
msgid "open issue"
msgstr "Ã¥pen sak"
-msgid "opened %{timeAgo}"
-msgstr "Ã¥pnet %{timeAgo}"
-
msgid "or"
msgstr "eller"
@@ -43312,6 +44173,12 @@ msgid_plural "out of %d total tests"
msgstr[0] ""
msgstr[1] ""
+msgid "packages"
+msgstr ""
+
+msgid "pages"
+msgstr ""
+
msgid "parent"
msgid_plural "parents"
msgstr[0] "overkategori"
@@ -43461,6 +44328,9 @@ msgid_plural "replies"
msgstr[0] "svar"
msgstr[1] "svar"
+msgid "repositories"
+msgstr ""
+
msgid "repository:"
msgstr "kodelager:"
@@ -43581,12 +44451,18 @@ msgstr "Vi legger til en GitLab CI-konfigurasjonsfil for å legge til en rørled
msgid "tag name"
msgstr "etikettnavn"
+msgid "terraform states"
+msgstr ""
+
msgid "the correct format."
msgstr "det riktige formatet."
msgid "the file"
msgstr "filen"
+msgid "the following epic(s)"
+msgstr ""
+
msgid "the following issue(s)"
msgstr "de(n) følgende sak(en)"
@@ -43599,21 +44475,12 @@ msgstr ""
msgid "this document"
msgstr "dette dokumentet"
-msgid "this issue cannot be assigned to a confidential epic since it is public"
-msgstr ""
-
-msgid "this issue cannot be made public since it belongs to a confidential epic"
-msgstr ""
-
msgid "time summary"
msgstr "tidsoppsummering"
msgid "toggle collapse"
msgstr ""
-msgid "train"
-msgstr ""
-
msgid "triggered"
msgstr "utløst"
@@ -43742,3 +44609,6 @@ msgstr ""
msgid "{project}"
msgstr ""
+msgid "✔"
+msgstr ""
+
diff --git a/locale/nl_NL/gitlab.po b/locale/nl_NL/gitlab.po
index 928cebf3594..c19d04d2e2d 100644
--- a/locale/nl_NL/gitlab.po
+++ b/locale/nl_NL/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: nl\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2022-02-02 15:46\n"
+"PO-Revision-Date: 2022-03-01 20:39\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -146,6 +146,11 @@ msgid_plural "%d approvers (you've approved)"
msgstr[0] ""
msgstr[1] ""
+msgid "%d assigned issue"
+msgid_plural "%d assigned issues"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -421,8 +426,23 @@ msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
msgstr[1] ""
-msgid "%d vulnerability updated"
-msgid_plural "%d vulnerabilities updated"
+msgid "%d vulnerability set to confirmed"
+msgid_plural "%d vulnerabilities set to confirmed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to dismissed"
+msgid_plural "%d vulnerabilities set to dismissed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to needs triage"
+msgid_plural "%d vulnerabilities set to needs triage"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to resolved"
+msgid_plural "%d vulnerabilities set to resolved"
msgstr[0] ""
msgstr[1] ""
@@ -510,6 +530,12 @@ msgstr[1] ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{completed} of %{total} issues closed"
+msgstr ""
+
+msgid "%{completed} of %{total} weight completed"
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -858,6 +884,9 @@ msgstr ""
msgid "%{openedIssues} open, %{closedIssues} closed"
msgstr ""
+msgid "%{percentage}%% issues closed"
+msgstr ""
+
msgid "%{percentage}%% weight completed"
msgstr ""
@@ -1287,6 +1316,9 @@ msgid_plural "- Users"
msgstr[0] ""
msgstr[1] ""
+msgid "- of - issues closed"
+msgstr ""
+
msgid "- of - weight completed"
msgstr ""
@@ -1429,7 +1461,7 @@ msgstr ""
msgid "1000+"
msgstr ""
-msgid "192.168.0.0/24"
+msgid "192.168.0.0/24 or 2001:0DB8:1234::/48"
msgstr ""
msgid "1st contribution!"
@@ -1741,13 +1773,13 @@ msgstr ""
msgid "AWS Access Key"
msgstr ""
-msgid "AWS Access Key. Only required if not using role instance credentials"
+msgid "AWS Secret Access Key"
msgstr ""
-msgid "AWS Secret Access Key"
+msgid "AWS access key ID (Optional)"
msgstr ""
-msgid "AWS Secret Access Key. Only required if not using role instance credentials"
+msgid "AWS secret access key (Optional)"
msgstr ""
msgid "AWS service error: %{error}"
@@ -1807,9 +1839,6 @@ msgstr ""
msgid "Access granted"
msgstr ""
-msgid "Access key ID"
-msgstr ""
-
msgid "Access requests"
msgstr ""
@@ -1984,7 +2013,7 @@ msgstr ""
msgid "Activity"
msgstr "Activiteit"
-msgid "Activity|An error occured while retrieving activity. Reload the page to try again."
+msgid "Activity|An error occurred while retrieving activity. Reload the page to try again."
msgstr ""
msgid "Add"
@@ -2023,6 +2052,9 @@ msgstr ""
msgid "Add a %{type}"
msgstr ""
+msgid "Add a GCP region"
+msgstr ""
+
msgid "Add a GPG key"
msgstr ""
@@ -2074,6 +2106,9 @@ msgstr ""
msgid "Add a numbered list"
msgstr ""
+msgid "Add a related epic"
+msgstr ""
+
msgid "Add a related issue"
msgstr ""
@@ -2188,6 +2223,9 @@ msgstr ""
msgid "Add or subtract spent time"
msgstr ""
+msgid "Add people"
+msgstr ""
+
msgid "Add previously merged commits"
msgstr ""
@@ -2254,6 +2292,9 @@ msgstr ""
msgid "Add webhook"
msgstr ""
+msgid "Add your team members and others to GitLab."
+msgstr ""
+
msgid "Add/remove"
msgstr ""
@@ -3076,12 +3117,6 @@ msgstr ""
msgid "AdvancedSearch|Reindex required"
msgstr ""
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. Permanently deleting this project will %{strongStart}immediately delete%{strongEnd} its repositories and %{strongStart}all related resources%{strongEnd}, including issues, merge requests etc."
-msgstr ""
-
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. You will lose this project's repository and %{strongStart}all related resources%{strongEnd}, including issues and merge requests."
-msgstr ""
-
msgid "After a successful password update you will be redirected to login screen."
msgstr ""
@@ -3112,6 +3147,9 @@ msgstr ""
msgid "Akismet helps prevent the creation of spam issues in public projects."
msgstr ""
+msgid "Alert"
+msgstr ""
+
msgid "AlertManagement|Acknowledged"
msgstr ""
@@ -3484,9 +3522,6 @@ msgstr ""
msgid "All environments"
msgstr ""
-msgid "All epics"
-msgstr ""
-
msgid "All groups and projects"
msgstr ""
@@ -4223,12 +4258,15 @@ msgstr ""
msgid "ApplicationSettings|Approve users in the pending approval status?"
msgstr ""
-msgid "ApplicationSettings|By making this change, you will automatically approve %d user with the pending approval status."
-msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users with the pending approval status."
+msgid "ApplicationSettings|Approve users who are pending approval?"
+msgstr ""
+
+msgid "ApplicationSettings|By making this change, you will automatically approve %d user who is pending approval."
+msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users who are pending approval."
msgstr[0] ""
msgstr[1] ""
-msgid "ApplicationSettings|By making this change, you will automatically approve all users in pending approval status."
+msgid "ApplicationSettings|By making this change, you will automatically approve all users who are pending approval."
msgstr ""
msgid "ApplicationSettings|Denied domains for sign-ups"
@@ -4634,10 +4672,10 @@ msgstr ""
msgid "Archiving the project will make it entirely read-only. It is hidden from the dashboard and doesn't show up in searches. %{strong_start}The repository cannot be committed to, and no issues, comments, or other entities can be created.%{strong_end} %{link_start}Learn more.%{link_end}"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to delete this project?"
+msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
+msgid "Are you absolutely sure?"
msgstr ""
msgid "Are you sure that you want to archive this project?"
@@ -4673,12 +4711,18 @@ msgstr ""
msgid "Are you sure you want to delete this SSH key?"
msgstr ""
+msgid "Are you sure you want to delete this comment?"
+msgstr ""
+
msgid "Are you sure you want to delete this deploy key?"
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 label?"
+msgstr ""
+
msgid "Are you sure you want to delete this pipeline schedule?"
msgstr ""
@@ -4694,9 +4738,6 @@ msgstr ""
msgid "Are you sure you want to discard your changes?"
msgstr ""
-msgid "Are you sure you want to erase this build?"
-msgstr ""
-
msgid "Are you sure you want to import %d repository?"
msgid_plural "Are you sure you want to import %d repositories?"
msgstr[0] ""
@@ -4744,6 +4785,9 @@ msgstr ""
msgid "Are you sure you want to remove this list?"
msgstr ""
+msgid "Are you sure you want to remove this nickname?"
+msgstr ""
+
msgid "Are you sure you want to reset the health check token?"
msgstr ""
@@ -4756,10 +4800,10 @@ 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?"
+msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
msgstr ""
-msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
+msgid "Are you sure you want to revoke this project access token? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to stop this environment?"
@@ -4906,9 +4950,6 @@ msgstr ""
msgid "Assigned to %{assignee_name}"
msgstr ""
-msgid "Assigned to %{name}"
-msgstr ""
-
msgid "Assigned to me"
msgstr ""
@@ -4973,6 +5014,9 @@ msgstr[1] ""
msgid "Attaching the file failed."
msgstr ""
+msgid "Attention"
+msgstr ""
+
msgid "Audit Events"
msgstr ""
@@ -5135,6 +5179,12 @@ msgstr ""
msgid "Authorized applications (%{size})"
msgstr ""
+msgid "AuthorizedApplication|Are you sure you want to revoke this application?"
+msgstr ""
+
+msgid "AuthorizedApplication|Revoke application"
+msgstr ""
+
msgid "Authors: %{authors}"
msgstr ""
@@ -6328,6 +6378,9 @@ msgstr ""
msgid "CICDAnalytics|Shared Runners Usage"
msgstr ""
+msgid "CICDAnalytics|Shared runner pipeline minute duration by month"
+msgstr ""
+
msgid "CICDAnalytics|Shared runner usage"
msgstr ""
@@ -6469,6 +6522,9 @@ msgstr ""
msgid "Can create groups:"
msgstr ""
+msgid "Can not delete primary training"
+msgstr ""
+
msgid "Can't apply as the source branch was deleted."
msgstr ""
@@ -6802,9 +6858,6 @@ msgstr ""
msgid "Changing any setting here requires an application restart"
msgstr ""
-msgid "Changing group URL can have unintended side effects."
-msgstr ""
-
msgid "Charts can't be displayed as the request for data has timed out. %{documentationLink}"
msgstr ""
@@ -6892,9 +6945,6 @@ msgstr ""
msgid "Checking branch availability..."
msgstr ""
-msgid "Checking group URL availability..."
-msgstr ""
-
msgid "Checking group path availability..."
msgstr ""
@@ -7388,6 +7438,9 @@ msgstr ""
msgid "Clear recent searches"
msgstr ""
+msgid "Clear repository checks"
+msgstr ""
+
msgid "Clear search"
msgstr ""
@@ -7520,9 +7573,6 @@ msgstr ""
msgid "Closed MRs"
msgstr ""
-msgid "Closed epics"
-msgstr ""
-
msgid "Closed issues"
msgstr ""
@@ -7559,13 +7609,13 @@ msgstr ""
msgid "Cluster level"
msgstr ""
-msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
+msgid "Cluster type must be specified for Stages::ClusterEndpointInserter"
msgstr ""
msgid "ClusterAgents|%{name} successfully deleted"
msgstr ""
-msgid "ClusterAgents|%{number} of %{total} Agents"
+msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
@@ -7607,6 +7657,15 @@ msgstr ""
msgid "ClusterAgents|Agent never connected to GitLab"
msgstr ""
+msgid "ClusterAgents|Agent version mismatch"
+msgstr ""
+
+msgid "ClusterAgents|Agent version mismatch and update"
+msgstr ""
+
+msgid "ClusterAgents|Agent version update required"
+msgstr ""
+
msgid "ClusterAgents|All"
msgstr ""
@@ -7631,7 +7690,7 @@ msgstr ""
msgid "ClusterAgents|Configuration"
msgstr ""
-msgid "ClusterAgents|Connect a cluster through the Agent"
+msgid "ClusterAgents|Connect a cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connect existing cluster"
@@ -7640,13 +7699,13 @@ msgstr ""
msgid "ClusterAgents|Connect with a certificate"
msgstr ""
-msgid "ClusterAgents|Connect with agent"
+msgid "ClusterAgents|Connect with an agent"
msgstr ""
msgid "ClusterAgents|Connect with the GitLab Agent"
msgstr ""
-msgid "ClusterAgents|Connect your cluster through the Agent"
+msgid "ClusterAgents|Connect your cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connected"
@@ -7706,7 +7765,10 @@ msgstr ""
msgid "ClusterAgents|How to register an agent?"
msgstr ""
-msgid "ClusterAgents|Install new Agent"
+msgid "ClusterAgents|How to update an agent?"
+msgstr ""
+
+msgid "ClusterAgents|Install a new agent"
msgstr ""
msgid "ClusterAgents|Last connected %{timeAgo}."
@@ -7733,7 +7795,7 @@ msgstr ""
msgid "ClusterAgents|Never connected"
msgstr ""
-msgid "ClusterAgents|No Agents"
+msgid "ClusterAgents|No agents"
msgstr ""
msgid "ClusterAgents|No clusters connected through cluster certificates"
@@ -7793,6 +7855,9 @@ msgstr ""
msgid "ClusterAgents|The agent has not been connected in a long time. There might be a connectivity issue. Last contact was %{timeAgo}."
msgstr ""
+msgid "ClusterAgents|The agent version do not match each other across your cluster's pods. This can happen when a new agent version was just deployed and Kubernetes is shutting down the old pods."
+msgstr ""
+
msgid "ClusterAgents|The recommended installation method includes the token. If you want to follow the advanced installation method provided in the docs, make sure you save the token value before you close this window."
msgstr ""
@@ -7840,6 +7905,9 @@ msgstr ""
msgid "ClusterAgents|You will need to create a token to connect to your agent"
msgstr ""
+msgid "ClusterAgents|Your agent version is out of sync with your GitLab version (v%{version}), which might cause compatibility problems. Update the agent installed on your cluster to the most recent version."
+msgstr ""
+
msgid "ClusterAgents|Your instance doesn't have the %{linkStart}GitLab Agent Server (KAS)%{linkEnd} set up. Ask a GitLab Administrator to install it."
msgstr ""
@@ -8716,9 +8784,6 @@ msgstr ""
msgid "Comma-separated list of email addresses."
msgstr ""
-msgid "Comma-separated list of users allowed to exceed the rate limit."
-msgstr ""
-
msgid "Comma-separated, e.g. '1.1.1.1, 2.2.2.0/24'"
msgstr ""
@@ -9045,6 +9110,12 @@ msgstr ""
msgid "Confidential"
msgstr ""
+msgid "Confidential issue"
+msgstr ""
+
+msgid "Confidential note"
+msgstr ""
+
msgid "Confidentiality"
msgstr ""
@@ -9078,6 +9149,9 @@ msgstr ""
msgid "Configure Dependency Scanning in `.gitlab-ci.yml`, creating this file if it does not already exist"
msgstr ""
+msgid "Configure GitLab"
+msgstr ""
+
msgid "Configure GitLab runners to start using the Web Terminal. %{helpStart}Learn more.%{helpEnd}"
msgstr ""
@@ -9126,6 +9200,15 @@ msgstr ""
msgid "Configure pipelines to deploy web apps, backend services, APIs and static resources to Google Cloud"
msgstr ""
+msgid "Configure region"
+msgstr ""
+
+msgid "Configure region for environment"
+msgstr ""
+
+msgid "Configure regions"
+msgstr ""
+
msgid "Configure repository mirroring."
msgstr ""
@@ -9159,6 +9242,9 @@ msgstr ""
msgid "Configure which lists are shown for anyone who visits this board"
msgstr ""
+msgid "Configure your environments to be deployed to specific geographical regions"
+msgstr ""
+
msgid "Confirm"
msgstr ""
@@ -9861,10 +9947,10 @@ msgstr ""
msgid "CorpusManagement|Actions"
msgstr ""
-msgid "CorpusManagement|Corpus are used in fuzz testing as mutation source to Improve future testing."
+msgid "CorpusManagement|Corpus file"
msgstr ""
-msgid "CorpusManagement|Corpus file"
+msgid "CorpusManagement|Corpus files are used in coverage-guided fuzz testing as seed inputs to improve testing."
msgstr ""
msgid "CorpusManagement|Corpus files must be in *.zip format. Maximum 5 GB"
@@ -9918,6 +10004,9 @@ msgstr ""
msgid "Could not apply %{name} command."
msgstr ""
+msgid "Could not apply %{name} command. %{message}."
+msgstr ""
+
msgid "Could not authorize chat nickname. Try again!"
msgstr ""
@@ -10068,6 +10157,9 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
+msgid "Create a group"
+msgstr ""
+
msgid "Create a merge request"
msgstr ""
@@ -10092,6 +10184,9 @@ msgstr ""
msgid "Create a personal access token on your account to pull or push via %{protocol}."
msgstr ""
+msgid "Create a project"
+msgstr ""
+
msgid "Create an account using:"
msgstr ""
@@ -10455,6 +10550,9 @@ msgstr ""
msgid "Creation date"
msgstr ""
+msgid "Creator"
+msgstr ""
+
msgid "Credentials"
msgstr ""
@@ -10467,9 +10565,15 @@ msgstr ""
msgid "CredentialsInventory|Personal Access Tokens"
msgstr ""
+msgid "CredentialsInventory|Project Access Tokens"
+msgstr ""
+
msgid "CredentialsInventory|SSH Keys"
msgstr ""
+msgid "Credit card required to be on file in order to create a pipeline"
+msgstr ""
+
msgid "Credit card:"
msgstr ""
@@ -10653,9 +10757,6 @@ msgstr ""
msgid "Customer relations"
msgstr ""
-msgid "Customizable by an administrator."
-msgstr ""
-
msgid "Customizable by owners."
msgstr ""
@@ -10785,30 +10886,18 @@ msgstr ""
msgid "CycleAnalytics|%{selectedLabelsCount} selected (%{maxLabels} max)"
msgstr ""
-msgid "CycleAnalytics|%{stageCount} stages selected"
-msgstr ""
-
-msgid "CycleAnalytics|All stages"
-msgstr ""
-
-msgid "CycleAnalytics|Average days to completion"
+msgid "CycleAnalytics|Average time to completion"
msgstr ""
msgid "CycleAnalytics|Date"
msgstr ""
-msgid "CycleAnalytics|Days to completion"
-msgstr ""
-
msgid "CycleAnalytics|Display chart filters"
msgstr ""
msgid "CycleAnalytics|Lead Time for Changes"
msgstr ""
-msgid "CycleAnalytics|No stages selected"
-msgstr ""
-
msgid "CycleAnalytics|Number of tasks"
msgstr ""
@@ -10837,18 +10926,30 @@ msgstr ""
msgid "CycleAnalytics|Showing data for group '%{groupName}' from %{createdAfter} to %{createdBefore}"
msgstr ""
-msgid "CycleAnalytics|Stages"
+msgid "CycleAnalytics|Stage time: %{title}"
msgstr ""
msgid "CycleAnalytics|Tasks by type"
msgstr ""
-msgid "CycleAnalytics|The average time spent in the selected stage for the items that were completed on each date. Data limited to the last 500 items."
+msgid "CycleAnalytics|The average time items spent in this stage. Data limited to items completed within this date range."
msgstr ""
msgid "CycleAnalytics|The given date range is larger than 180 days"
msgstr ""
+msgid "CycleAnalytics|The total time items spent across each value stream stage. Data limited to items completed within this date range."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Stage time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Total time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|Total time"
+msgstr ""
+
msgid "CycleAnalytics|Type of work"
msgstr ""
@@ -10861,9 +10962,6 @@ msgstr ""
msgid "CycleAnalytics|project dropdown filter"
msgstr ""
-msgid "CycleAnalytics|stage dropdown"
-msgstr ""
-
msgid "DAG visualization requires at least 3 dependent jobs."
msgstr ""
@@ -10963,10 +11061,16 @@ msgstr ""
msgid "DastProfiles|AJAX spider"
msgstr ""
+msgid "DastProfiles|API"
+msgstr ""
+
+msgid "DastProfiles|API endpoint URL"
+msgstr ""
+
msgid "DastProfiles|Active"
msgstr ""
-msgid "DastProfiles|Additional request headers (Optional)"
+msgid "DastProfiles|Additional request headers (optional)"
msgstr ""
msgid "DastProfiles|Are you sure you want to delete this profile?"
@@ -10981,6 +11085,9 @@ msgstr ""
msgid "DastProfiles|Branch missing"
msgstr ""
+msgid "DastProfiles|Choose a scan method"
+msgstr ""
+
msgid "DastProfiles|Could not create the scanner profile. Please try again."
msgstr ""
@@ -11050,7 +11157,13 @@ msgstr ""
msgid "DastProfiles|Excluded URLs"
msgstr ""
-msgid "DastProfiles|Excluded URLs (Optional)"
+msgid "DastProfiles|Excluded URLs (optional)"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths (optional)"
msgstr ""
msgid "DastProfiles|Hide debug messages"
@@ -11107,9 +11220,6 @@ msgstr ""
msgid "DastProfiles|Request headers"
msgstr ""
-msgid "DastProfiles|Rest API"
-msgstr ""
-
msgid "DastProfiles|Run the AJAX spider, in addition to the traditional spider, to crawl the target site."
msgstr ""
@@ -11119,6 +11229,9 @@ msgstr ""
msgid "DastProfiles|Save profile"
msgstr ""
+msgid "DastProfiles|Scan method"
+msgstr ""
+
msgid "DastProfiles|Scan mode"
msgstr ""
@@ -11197,12 +11310,24 @@ msgstr ""
msgid "DastProfiles|Website"
msgstr ""
+msgid "DastProfiles|What does each method do?"
+msgstr ""
+
msgid "DastProfiles|You can either choose a passive scan or validate the target site from the site profile management page. %{docsLinkStart}Learn more about site validation.%{docsLinkEnd}"
msgstr ""
msgid "DastProfiles|You cannot run an active scan against an unvalidated site."
msgstr ""
+msgid "DastProfiles|folder/dast_example.har or https://example.com/dast_example.har"
+msgstr ""
+
+msgid "DastProfiles|folder/example.postman_collection.json or https://example.com/"
+msgstr ""
+
+msgid "DastProfiles|folder/openapi.json or https://example.com/openapi.json"
+msgstr ""
+
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
@@ -11310,6 +11435,9 @@ msgstr ""
msgid "DatadogIntegration|API URL"
msgstr ""
+msgid "DatadogIntegration|Custom tags in Datadog. Enter one tag per line in the %{codeOpen}key:value%{codeClose} format. %{linkOpen}How do I use tags?%{linkClose}"
+msgstr ""
+
msgid "DatadogIntegration|Environment"
msgstr ""
@@ -11328,12 +11456,18 @@ msgstr ""
msgid "DatadogIntegration|Tag all data from this GitLab instance in Datadog. Useful when managing several self-managed deployments."
msgstr ""
+msgid "DatadogIntegration|Tags"
+msgstr ""
+
msgid "DatadogIntegration|The Datadog site to send data to. To send data to the EU site, use %{codeOpen}datadoghq.eu%{codeClose}."
msgstr ""
msgid "DatadogIntegration|Trace your GitLab pipelines with Datadog."
msgstr ""
+msgid "DatadogIntegration|have an invalid format"
+msgstr ""
+
msgid "Datasource name not found"
msgstr ""
@@ -11343,9 +11477,6 @@ msgstr ""
msgid "Date merged"
msgstr ""
-msgid "Date picker"
-msgstr ""
-
msgid "Date range"
msgstr ""
@@ -11499,9 +11630,6 @@ msgstr ""
msgid "Definition"
msgstr ""
-msgid "Delayed Project Deletion (%{adjourned_deletion})"
-msgstr ""
-
msgid "DelayedJobs|Are you sure you want to run %{jobName} immediately? Otherwise this job will run automatically after its timer finishes."
msgstr ""
@@ -11580,10 +11708,10 @@ msgstr ""
msgid "Delete pipeline"
msgstr ""
-msgid "Delete project"
+msgid "Delete pipeline schedule"
msgstr ""
-msgid "Delete project. Are you ABSOLUTELY SURE?"
+msgid "Delete project"
msgstr ""
msgid "Delete row"
@@ -11613,6 +11741,9 @@ msgstr ""
msgid "Delete this epic and all descendants?"
msgstr ""
+msgid "Delete this project"
+msgstr ""
+
msgid "Delete user list"
msgstr ""
@@ -11871,6 +12002,12 @@ msgstr ""
msgid "Deploy to..."
msgstr ""
+msgid "DeployBoards|To see deployment progress for your environments, make sure you are deploying to %{codeStart}$KUBE_NAMESPACE%{codeEnd} and annotating with %{codeStart}app.gitlab.com/app=$CI_PROJECT_PATH_SLUG%{codeEnd} and %{codeStart}app.gitlab.com/env=$CI_ENVIRONMENT_SLUG%{codeEnd}."
+msgstr ""
+
+msgid "DeployBoard|Kubernetes Pods"
+msgstr ""
+
msgid "DeployFreeze|Add a freeze period to prevent unintended releases during a period of time for a given environment. You must update the deployment jobs in %{filename} according to the deploy freezes added here. %{freeze_period_link_start}Learn more.%{freeze_period_link_end}"
msgstr ""
@@ -11955,9 +12092,6 @@ msgstr ""
msgid "DeployTokens|Active Deploy Tokens (%{active_tokens})"
msgstr ""
-msgid "DeployTokens|Allows read and write access to registry images."
-msgstr ""
-
msgid "DeployTokens|Allows read and write access to the package registry."
msgstr ""
@@ -11970,6 +12104,9 @@ msgstr ""
msgid "DeployTokens|Allows read-only access to the repository."
msgstr ""
+msgid "DeployTokens|Allows write access to registry images."
+msgstr ""
+
msgid "DeployTokens|Copy deploy token"
msgstr ""
@@ -12063,12 +12200,57 @@ msgstr ""
msgid "Deploying to AWS is easy with GitLab"
msgstr ""
+msgid "Deployment"
+msgstr ""
+
msgid "Deployment Frequency"
msgstr ""
+msgid "Deployment Target|Project deployment target (optional)"
+msgstr ""
+
+msgid "Deployment Target|Select the deployment target"
+msgstr ""
+
msgid "Deployment frequency"
msgstr ""
+msgid "DeploymentTarget|GitLab Pages"
+msgstr ""
+
+msgid "DeploymentTarget|Heroku"
+msgstr ""
+
+msgid "DeploymentTarget|Infrastructure provider (Terraform, Cloudformation, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Kubernetes (GKE, EKS, OpenShift, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Managed container runtime (Fargate, Cloud Run, DigitalOcean App)"
+msgstr ""
+
+msgid "DeploymentTarget|Mobile app store"
+msgstr ""
+
+msgid "DeploymentTarget|No deployment planned"
+msgstr ""
+
+msgid "DeploymentTarget|Other hosting service"
+msgstr ""
+
+msgid "DeploymentTarget|Registry (package or container)"
+msgstr ""
+
+msgid "DeploymentTarget|Self-managed container runtime (Podman, Docker Swarm, Docker Compose)"
+msgstr ""
+
+msgid "DeploymentTarget|Serverless backend (Lambda, Cloud functions)"
+msgstr ""
+
+msgid "DeploymentTarget|Virtual machine (for example, EC2)"
+msgstr ""
+
msgid "Deployments"
msgstr ""
@@ -12107,6 +12289,9 @@ msgstr ""
msgid "Deployment|This deployment was created using the API"
msgstr ""
+msgid "Deployment|Triggerer"
+msgstr ""
+
msgid "Deployment|Waiting"
msgstr ""
@@ -12134,6 +12319,18 @@ msgstr ""
msgid "Deprecated API rate limits"
msgstr ""
+msgid "Deprecations|Feature deprecation and removal"
+msgstr ""
+
+msgid "Deprecations|For information on a possible replacement %{epicStart} learn more about Opstrace %{epicEnd}."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7 and are %{epicStart} scheduled for removal %{epicEnd} in GitLab 15.0."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7, and are %{removal_link_start} scheduled for removal %{link_end} in GitLab 15.0. For information on a possible replacement, %{opstrace_link_start} learn more about Opstrace %{link_end}."
+msgstr ""
+
msgid "Deprioritize label"
msgstr ""
@@ -12379,10 +12576,10 @@ msgstr ""
msgid "DevopsAdoption|At least one deploy"
msgstr ""
-msgid "DevopsAdoption|At least one issue opened"
+msgid "DevopsAdoption|At least one issue created"
msgstr ""
-msgid "DevopsAdoption|At least one merge request opened"
+msgid "DevopsAdoption|At least one merge request created"
msgstr ""
msgid "DevopsAdoption|At least one pipeline successfully run"
@@ -12583,6 +12780,9 @@ msgstr ""
msgid "Direct member"
msgstr ""
+msgid "Direct members"
+msgstr ""
+
msgid "Direct non-authenticated users to this page."
msgstr ""
@@ -12699,6 +12899,9 @@ msgid_plural "Dismiss %d selected vulnerabilities as"
msgstr[0] ""
msgstr[1] ""
+msgid "Dismiss Alert"
+msgstr ""
+
msgid "Dismiss merge request promotion"
msgstr ""
@@ -12726,9 +12929,15 @@ msgstr ""
msgid "Display alerts from all configured monitoring tools."
msgstr ""
+msgid "Display milestones"
+msgstr ""
+
msgid "Display name"
msgstr ""
+msgid "Display progress of child issues"
+msgstr ""
+
msgid "Display rendered file"
msgstr ""
@@ -12834,6 +13043,9 @@ msgstr ""
msgid "Download image"
msgstr ""
+msgid "Download payload"
+msgstr ""
+
msgid "Download raw data (.csv)"
msgstr ""
@@ -13011,6 +13223,9 @@ msgstr ""
msgid "Edit in Web IDE"
msgstr ""
+msgid "Edit in pipeline editor"
+msgstr ""
+
msgid "Edit in single-file editor"
msgstr ""
@@ -13053,6 +13268,9 @@ msgstr ""
msgid "Edit your most recent comment in a thread (from an empty textarea)"
msgstr ""
+msgid "Edit, lint, and visualize your pipeline."
+msgstr ""
+
msgid "Edited"
msgstr ""
@@ -13494,6 +13712,9 @@ msgstr ""
msgid "Enforce two-factor authentication for all user sign-ins."
msgstr ""
+msgid "Enhance security by storing service account keys in secret managers - learn more about %{docLinkStart}secret management with GitLab%{docLinkEnd}"
+msgstr ""
+
msgid "Ensure connectivity is available from the GitLab server to the Prometheus server"
msgstr ""
@@ -13554,6 +13775,9 @@ 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 following to confirm:"
+msgstr ""
+
msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
@@ -14084,9 +14308,6 @@ 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 ""
@@ -14222,6 +14443,9 @@ msgstr ""
msgid "Errors:"
msgstr ""
+msgid "Escalate this incident"
+msgstr ""
+
msgid "Escalation Policies"
msgstr ""
@@ -14234,6 +14458,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy"
+msgstr ""
+
msgid "Escalation policy:"
msgstr ""
@@ -14485,6 +14712,9 @@ msgstr ""
msgid "Existing sign in methods may be removed"
msgstr ""
+msgid "Exit."
+msgstr ""
+
msgid "Expand"
msgstr ""
@@ -14581,6 +14811,9 @@ msgstr ""
msgid "Explore public groups"
msgstr ""
+msgid "Explore public projects"
+msgstr ""
+
msgid "Explore snippets"
msgstr ""
@@ -14742,7 +14975,7 @@ msgid_plural "Failed to archive designs. Please try again."
msgstr[0] ""
msgstr[1] ""
-msgid "Failed to assign a reviewer because no user was found."
+msgid "Failed to assign a reviewer because no user was specified."
msgstr ""
msgid "Failed to assign a user because no user was found."
@@ -14808,10 +15041,10 @@ msgstr ""
msgid "Failed to find import label for Jira import."
msgstr ""
-msgid "Failed to generate export, please try again later."
+msgid "Failed to find users for %{missing}"
msgstr ""
-msgid "Failed to generate report, please try again after sometime"
+msgid "Failed to generate export, please try again later."
msgstr ""
msgid "Failed to get ref."
@@ -14910,6 +15143,9 @@ msgstr ""
msgid "Failed to remove a to-do item for the design."
msgstr ""
+msgid "Failed to remove attention because no user was found."
+msgstr ""
+
msgid "Failed to remove mirror."
msgstr ""
@@ -14922,6 +15158,9 @@ msgstr ""
msgid "Failed to remove user key."
msgstr ""
+msgid "Failed to request attention because no user was found."
+msgstr ""
+
msgid "Failed to reset key. Please try again."
msgstr ""
@@ -15003,6 +15242,9 @@ msgstr ""
msgid "Feature Flags"
msgstr ""
+msgid "Feature deprecation and removal"
+msgstr ""
+
msgid "Feature flag status"
msgstr ""
@@ -15500,7 +15742,7 @@ msgstr ""
msgid "For each job, re-use the project workspace. If the workspace doesn't exist, use %{code_open}git clone%{code_close}."
msgstr ""
-msgid "For example, the application using the token or the purpose of the token."
+msgid "For example, the application using the token or the purpose of the token. Do not give sensitive information for the name of the token, as it will be visible to all %{resource_type} members."
msgstr ""
msgid "For files larger than this limit, only index the file name. The file content is neither indexed nor searchable."
@@ -15584,9 +15826,6 @@ msgstr ""
msgid "ForkProject|Select a namespace"
msgstr ""
-msgid "ForkProject|Select a namespace to fork the project"
-msgstr ""
-
msgid "ForkProject|The project can be accessed by any logged in user."
msgstr ""
@@ -15683,6 +15922,9 @@ msgstr ""
msgid "Full name"
msgstr ""
+msgid "GCP region configured"
+msgstr ""
+
msgid "GPG Key ID:"
msgstr ""
@@ -15863,6 +16105,9 @@ msgstr ""
msgid "Geo|Failed"
msgstr ""
+msgid "Geo|Filter Geo sites"
+msgstr ""
+
msgid "Geo|Filter by name"
msgstr ""
@@ -16274,6 +16519,12 @@ msgstr ""
msgid "GitLab Issue"
msgstr ""
+msgid "GitLab KAS"
+msgstr ""
+
+msgid "GitLab Memberships CSV Export"
+msgstr ""
+
msgid "GitLab Pages"
msgstr ""
@@ -16322,6 +16573,9 @@ 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 free to use. Many features for larger teams are part of our %{link_start}paid products%{link_end}. You can try Ultimate for free without any obligation or payment details."
+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 ""
@@ -16448,7 +16702,7 @@ msgstr ""
msgid "GitLabPages|When enabled, all attempts to visit your website through HTTP are automatically redirected to HTTPS using a response with status code 301. Requires a valid certificate for all domains. %{docs_link_start}Learn more.%{link_end}"
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. %{docs_link_start}Learn more.%{link_end}"
+msgid "GitLabPages|When using Pages under the general domain of a GitLab instance (%{pages_host}), you cannot use HTTPS with subdomains of subdomains. If your namespace or groupname contains a dot, it does not work. This is a limitation of the HTTP Over TLS protocol. HTTP pages work if you don't redirect HTTP to HTTPS. %{docs_link_start}Learn more.%{link_end}"
msgstr ""
msgid "GitLabPages|With GitLab Pages you can host your static website directly from your GitLab repository. %{docs_link_start}Learn more.%{link_end}"
@@ -16625,9 +16879,6 @@ msgstr ""
msgid "Go to find file"
msgstr ""
-msgid "Go to fork"
-msgstr ""
-
msgid "Go to issue boards"
msgstr ""
@@ -16835,9 +17086,6 @@ msgstr ""
msgid "Group Hooks"
msgstr ""
-msgid "Group ID"
-msgstr ""
-
msgid "Group Owner must have signed in with SAML before enabling Group Managed Accounts"
msgstr ""
@@ -16865,9 +17113,6 @@ msgstr ""
msgid "Group by"
msgstr ""
-msgid "Group description"
-msgstr ""
-
msgid "Group description (optional)"
msgstr ""
@@ -16982,7 +17227,7 @@ msgstr ""
msgid "Group: %{name}"
msgstr ""
-msgid "GroupActivityMetrics|Issues opened"
+msgid "GroupActivityMetrics|Issues created"
msgstr ""
msgid "GroupActivityMetrics|Last 90 days"
@@ -16991,7 +17236,7 @@ msgstr ""
msgid "GroupActivityMetrics|Members added"
msgstr ""
-msgid "GroupActivityMetrics|Merge Requests opened"
+msgid "GroupActivityMetrics|Merge Requests created"
msgstr ""
msgid "GroupActivityMetrics|Recent activity"
@@ -17282,6 +17527,9 @@ msgstr ""
msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
+msgid "GroupSettings|Choose a group path that does not start with a dash or end with a period. It can also contain alphanumeric characters and underscores."
+msgstr ""
+
msgid "GroupSettings|Compliance frameworks"
msgstr ""
@@ -17315,7 +17563,7 @@ msgstr ""
msgid "GroupSettings|If not specified at the group or instance level, the default is %{default_initial_branch_name}. Does not affect existing repositories."
msgstr ""
-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."
+msgid "GroupSettings|If the parent group's visibility is lower than the group's current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility."
msgstr ""
msgid "GroupSettings|New runners registration token has been generated!"
@@ -17432,7 +17680,10 @@ msgstr ""
msgid "Groups and projects"
msgstr ""
-msgid "Groups and subgroups"
+msgid "Groups are a great way to organize projects and people."
+msgstr ""
+
+msgid "Groups are the best way to manage projects and members."
msgstr ""
msgid "Groups to synchronize"
@@ -17543,13 +17794,16 @@ msgstr ""
msgid "GroupsTree|Are you sure you want to leave the \"%{fullName}\" group?"
msgstr ""
-msgid "GroupsTree|Edit group"
+msgid "GroupsTree|Delete"
+msgstr ""
+
+msgid "GroupsTree|Edit"
msgstr ""
msgid "GroupsTree|Failed to leave the group. Please make sure you are not the only owner."
msgstr ""
-msgid "GroupsTree|Leave this group"
+msgid "GroupsTree|Leave group"
msgstr ""
msgid "GroupsTree|Loading groups"
@@ -17561,9 +17815,57 @@ msgstr ""
msgid "GroupsTree|No groups or projects matched your search"
msgstr ""
+msgid "GroupsTree|Options"
+msgstr ""
+
msgid "GroupsTree|Search by name"
msgstr ""
+msgid "Groups|Avatar will be removed. Are you sure?"
+msgstr ""
+
+msgid "Groups|Changing group URL can have unintended side effects."
+msgstr ""
+
+msgid "Groups|Checking group URL availability..."
+msgstr ""
+
+msgid "Groups|Enter a descriptive name for your group."
+msgstr ""
+
+msgid "Groups|Group ID"
+msgstr ""
+
+msgid "Groups|Group URL"
+msgstr ""
+
+msgid "Groups|Group avatar"
+msgstr ""
+
+msgid "Groups|Group description (optional)"
+msgstr ""
+
+msgid "Groups|Group name"
+msgstr ""
+
+msgid "Groups|Group path is available."
+msgstr ""
+
+msgid "Groups|Group path is unavailable. Path has been replaced with a suggested available path."
+msgstr ""
+
+msgid "Groups|Learn more"
+msgstr ""
+
+msgid "Groups|Must start with letter, digit, emoji, or underscore. Can also contain periods, dashes, spaces, and parentheses."
+msgstr ""
+
+msgid "Groups|Remove avatar"
+msgstr ""
+
+msgid "Groups|Save changes"
+msgstr ""
+
msgid "Guideline"
msgstr ""
@@ -17573,6 +17875,9 @@ msgstr ""
msgid "HAR file path or URL"
msgstr ""
+msgid "HTTP Archive (HAR)"
+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 ""
@@ -17973,6 +18278,9 @@ msgstr ""
msgid "INFO: Your SSH key is expiring soon. Please generate a new key."
msgstr ""
+msgid "IP"
+msgstr ""
+
msgid "IP Address"
msgstr ""
@@ -18009,6 +18317,9 @@ msgstr ""
msgid "IdentityVerification|Verify your identity"
msgstr ""
+msgid "IdentityVerification|You can always verify your account at a later time to create a group."
+msgstr ""
+
msgid "If any indexed field exceeds this limit, it is truncated to this number of characters. The rest of the content is neither indexed nor searchable. This does not apply to repository and wiki indexing. For unlimited characters, set this to 0."
msgstr ""
@@ -18066,6 +18377,9 @@ msgstr ""
msgid "If you add %{codeStart}needs%{codeEnd} to jobs in your pipeline you'll be able to view the %{codeStart}needs%{codeEnd} relationships between jobs in this tab as a %{linkStart}Directed Acyclic Graph (DAG)%{linkEnd}."
msgstr ""
+msgid "If you are added to a project, it will be displayed here."
+msgstr ""
+
msgid "If you did not initiate these sign-in attempts, please reach out to your administrator or enable two-factor authentication (2FA) on your account."
msgstr ""
@@ -18372,12 +18686,24 @@ msgstr ""
msgid "InProductMarketing|3 ways to dive into GitLab CI/CD"
msgstr ""
+msgid "InProductMarketing|A single application eliminates complex integrations, data chokepoints, and toolchain maintenance, resulting in greater productivity and lower cost."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features, build more efficiently, strengthen security and compliance."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features."
+msgstr ""
+
msgid "InProductMarketing|Actually, GitLab makes the team work (better)"
msgstr ""
msgid "InProductMarketing|And finally %{deploy_link} a Python application."
msgstr ""
+msgid "InProductMarketing|And many more..."
+msgstr ""
+
msgid "InProductMarketing|Are your runners ready?"
msgstr ""
@@ -18396,15 +18722,33 @@ msgstr ""
msgid "InProductMarketing|Blog"
msgstr ""
+msgid "InProductMarketing|Break down silos to coordinate seamlessly across development, operations, and security with a consistent experience across the development lifecycle."
+msgstr ""
+
+msgid "InProductMarketing|Burn up/down charts"
+msgstr ""
+
msgid "InProductMarketing|By enabling code owners and required merge approvals the right person will review the right MR. This is a win-win: cleaner code and a more efficient review process."
msgstr ""
msgid "InProductMarketing|Click on the number below that corresponds with your answer — 1 being very difficult, 5 being very easy."
msgstr ""
+msgid "InProductMarketing|Code owners"
+msgstr ""
+
msgid "InProductMarketing|Code owners and required merge approvals are part of the paid tiers of GitLab. You can start a free 30-day trial of GitLab Ultimate and enable these features in less than 5 minutes with no credit card required."
msgstr ""
+msgid "InProductMarketing|Code review analytics"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration across stages in GitLab"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration made easy"
+msgstr ""
+
msgid "InProductMarketing|Create a custom CI runner with just a few clicks"
msgstr ""
@@ -18414,12 +18758,21 @@ msgstr ""
msgid "InProductMarketing|Create a project in GitLab in 5 minutes"
msgstr ""
+msgid "InProductMarketing|Create well-defined workflows by using scoped labels on issues, merge requests, and epics. Labels with the same scope cannot be used together, which prevents conflicts."
+msgstr ""
+
msgid "InProductMarketing|Create your first project!"
msgstr ""
+msgid "InProductMarketing|Define who owns specific files or directories, so the right reviewers are suggested when a merge request introduces changes to those files."
+msgstr ""
+
msgid "InProductMarketing|Deliver Better Products Faster"
msgstr ""
+msgid "InProductMarketing|Dependency scanning"
+msgstr ""
+
msgid "InProductMarketing|Did you know teams that use GitLab are far more efficient?"
msgstr ""
@@ -18429,15 +18782,27 @@ msgstr ""
msgid "InProductMarketing|Dig in and create a project and a repo"
msgstr ""
+msgid "InProductMarketing|Discover Premium & Ultimate"
+msgstr ""
+
+msgid "InProductMarketing|Discover Premium & Ultimate."
+msgstr ""
+
msgid "InProductMarketing|Do you have a minute?"
msgstr ""
msgid "InProductMarketing|Do you have a teammate who would be perfect for this task?"
msgstr ""
+msgid "InProductMarketing|Dynamic application security testing"
+msgstr ""
+
msgid "InProductMarketing|Easy"
msgstr ""
+msgid "InProductMarketing|Epics"
+msgstr ""
+
msgid "InProductMarketing|Expand your DevOps journey with a free GitLab trial"
msgstr ""
@@ -18459,9 +18824,15 @@ msgstr ""
msgid "InProductMarketing|Feel the need for speed?"
msgstr ""
+msgid "InProductMarketing|Find and fix bottlenecks in your code review process by understanding how long open merge requests have been in review."
+msgstr ""
+
msgid "InProductMarketing|Find out how your teams are really doing"
msgstr ""
+msgid "InProductMarketing|Find out if your external libraries are safe. Run dependency scanning jobs that check for known vulnerabilities in your external libraries."
+msgstr ""
+
msgid "InProductMarketing|Follow our steps"
msgstr ""
@@ -18498,6 +18869,9 @@ msgstr ""
msgid "InProductMarketing|GitLab is better with teammates to help out!"
msgstr ""
+msgid "InProductMarketing|GitLab is infrastructure agnostic (supporting GCP, AWS, Azure, OpenShift, VMWare, On Prem, Bare Metal, and more), offering a consistent workflow experience – irrespective of the environment."
+msgstr ""
+
msgid "InProductMarketing|GitLab provides static application security testing (SAST), dynamic application security testing (DAST), container scanning, and dependency scanning to help you deliver secure applications along with license compliance."
msgstr ""
@@ -18588,21 +18962,36 @@ msgstr ""
msgid "InProductMarketing|It's also possible to simply %{external_repo_link} in order to take advantage of GitLab's CI/CD."
msgstr ""
+msgid "InProductMarketing|Keep your code quality high by defining who should approve merge requests and how many approvals are required."
+msgstr ""
+
msgid "InProductMarketing|Launch GitLab CI/CD in 20 minutes or less"
msgstr ""
+msgid "InProductMarketing|Lower cost of development"
+msgstr ""
+
+msgid "InProductMarketing|Make it easier to collaborate on high-level ideas by grouping related issues in an epic."
+msgstr ""
+
msgid "InProductMarketing|Making the switch? It's easier than you think to import your projects into GitLab. Move %{github_link}, or import something %{bitbucket_link}."
msgstr ""
msgid "InProductMarketing|Master the art of importing!"
msgstr ""
+msgid "InProductMarketing|Merge request approval rule"
+msgstr ""
+
msgid "InProductMarketing|Move on to easily creating a Pages website %{ci_template_link}"
msgstr ""
msgid "InProductMarketing|Multiple owners, confusing workstreams? We've got you covered"
msgstr ""
+msgid "InProductMarketing|Multiple required approvers"
+msgstr ""
+
msgid "InProductMarketing|Need an alternative to importing?"
msgstr ""
@@ -18615,18 +19004,33 @@ msgstr ""
msgid "InProductMarketing|Our tool brings all the things together"
msgstr ""
+msgid "InProductMarketing|Protect your web application by using DAST to examine for vulnerabilities in deployed environments."
+msgstr ""
+
msgid "InProductMarketing|Rapid development, simplified"
msgstr ""
msgid "InProductMarketing|Reduce Security & Compliance Risk"
msgstr ""
+msgid "InProductMarketing|Require multiple approvers on a merge request, so you know it's in good shape before it's merged."
+msgstr ""
+
+msgid "InProductMarketing|Roadmaps"
+msgstr ""
+
+msgid "InProductMarketing|Scoped labels"
+msgstr ""
+
msgid "InProductMarketing|Security that's integrated into your development lifecycle"
msgstr ""
msgid "InProductMarketing|Sometimes you're not ready to make a full transition to a new tool. If you're not ready to fully commit, %{mirroring_link} gives you a safe way to try out GitLab in parallel with your current tool."
msgstr ""
+msgid "InProductMarketing|Speed. Efficiency. Trust."
+msgstr ""
+
msgid "InProductMarketing|Spin up an autoscaling runner in GitLab"
msgstr ""
@@ -18636,6 +19040,9 @@ msgstr ""
msgid "InProductMarketing|Start a Self-Managed trial"
msgstr ""
+msgid "InProductMarketing|Start a free trial"
+msgstr ""
+
msgid "InProductMarketing|Start a free trial of GitLab Ultimate – no credit card required"
msgstr ""
@@ -18702,6 +19109,9 @@ msgstr ""
msgid "InProductMarketing|To understand and get the most out of GitLab, start at the beginning and %{project_link}. In GitLab, repositories are part of a project, so after you've created your project you can go ahead and %{repo_link}."
msgstr ""
+msgid "InProductMarketing|Track completed issues in a chart, so you can see how a milestone is progressing at a glance."
+msgstr ""
+
msgid "InProductMarketing|Try GitLab Ultimate for free"
msgstr ""
@@ -18738,6 +19148,9 @@ msgstr ""
msgid "InProductMarketing|Very easy"
msgstr ""
+msgid "InProductMarketing|Visualize your epics and milestones in a timeline."
+msgstr ""
+
msgid "InProductMarketing|Want to host GitLab on your servers?"
msgstr ""
@@ -18759,6 +19172,9 @@ msgstr ""
msgid "InProductMarketing|YouTube"
msgstr ""
+msgid "InProductMarketing|Your software, deployed your way"
+msgstr ""
+
msgid "InProductMarketing|Your teams can be more efficient"
msgstr ""
@@ -18879,9 +19295,18 @@ msgstr ""
msgid "IncidentManagement|No incidents to display."
msgstr ""
+msgid "IncidentManagement|None"
+msgstr ""
+
msgid "IncidentManagement|Open"
msgstr ""
+msgid "IncidentManagement|Page your team with escalation policies"
+msgstr ""
+
+msgid "IncidentManagement|Paged"
+msgstr ""
+
msgid "IncidentManagement|Published"
msgstr ""
@@ -18891,6 +19316,9 @@ msgstr ""
msgid "IncidentManagement|Severity"
msgstr ""
+msgid "IncidentManagement|Status"
+msgstr ""
+
msgid "IncidentManagement|There are no closed incidents"
msgstr ""
@@ -18909,6 +19337,9 @@ msgstr ""
msgid "IncidentManagement|Unpublished"
msgstr ""
+msgid "IncidentManagement|Use escalation policies to automatically page your team when incidents are created."
+msgstr ""
+
msgid "IncidentSettings|Activate \"time to SLA\" countdown timer"
msgstr ""
@@ -18954,7 +19385,10 @@ msgstr ""
msgid "Incidents"
msgstr ""
-msgid "Incidents|Add a URL"
+msgid "Incidents|Add image details"
+msgstr ""
+
+msgid "Incidents|Add text or a link to display with your image. If you don't add either, the file name displays instead."
msgstr ""
msgid "Incidents|Drop or %{linkStart}upload%{linkEnd} a metric screenshot to attach it to the incident"
@@ -18969,10 +19403,10 @@ msgstr ""
msgid "Incidents|There was an issue loading metric images."
msgstr ""
-msgid "Incidents|There was an issue uploading your image."
+msgid "Incidents|There was an issue updating your image."
msgstr ""
-msgid "Incidents|You can optionally add a URL to link users to the original graph."
+msgid "Incidents|There was an issue uploading your image."
msgstr ""
msgid "Incident|Alert details"
@@ -18981,9 +19415,18 @@ msgstr ""
msgid "Incident|Are you sure you wish to delete this image?"
msgstr ""
+msgid "Incident|Delete image"
+msgstr ""
+
msgid "Incident|Deleting %{filename}"
msgstr ""
+msgid "Incident|Edit image text or link"
+msgstr ""
+
+msgid "Incident|Editing %{filename}"
+msgstr ""
+
msgid "Incident|Metrics"
msgstr ""
@@ -19253,12 +19696,18 @@ msgstr ""
msgid "Integrations|Branches for which notifications are to be sent"
msgstr ""
+msgid "Integrations|Clear if using a self-signed certificate."
+msgstr ""
+
msgid "Integrations|Comment detail:"
msgstr ""
msgid "Integrations|Comment settings:"
msgstr ""
+msgid "Integrations|Connection details"
+msgstr ""
+
msgid "Integrations|Connection failed. Please check your settings."
msgstr ""
@@ -19283,6 +19732,9 @@ msgstr ""
msgid "Integrations|Enable GitLab.com slash commands in a Slack workspace."
msgstr ""
+msgid "Integrations|Enable SSL verification"
+msgstr ""
+
msgid "Integrations|Enable comments"
msgstr ""
@@ -19361,6 +19813,9 @@ msgstr ""
msgid "Integrations|Return to GitLab for Jira"
msgstr ""
+msgid "Integrations|SSL verification"
+msgstr ""
+
msgid "Integrations|Save settings?"
msgstr ""
@@ -19406,9 +19861,6 @@ msgstr ""
msgid "Integrations|Use default settings"
msgstr ""
-msgid "Integrations|When you mention a Jira issue in a commit or merge request, GitLab creates a remote link and comment (if enabled)."
-msgstr ""
-
msgid "Integrations|You can now close this window and return to the GitLab for Jira application."
msgstr ""
@@ -19433,9 +19885,6 @@ msgstr ""
msgid "Integrations|can't exceed %{recipients_limit}"
msgstr ""
-msgid "Interactive developer security education."
-msgstr ""
-
msgid "Interactive mode"
msgstr ""
@@ -19925,6 +20374,9 @@ msgstr ""
msgid "IssueAnalytics|Assignees"
msgstr ""
+msgid "IssueAnalytics|Created by"
+msgstr ""
+
msgid "IssueAnalytics|Due date"
msgstr ""
@@ -19937,9 +20389,6 @@ msgstr ""
msgid "IssueAnalytics|Milestone"
msgstr ""
-msgid "IssueAnalytics|Opened by"
-msgstr ""
-
msgid "IssueAnalytics|Status"
msgstr ""
@@ -20063,10 +20512,10 @@ msgstr ""
msgid "IssuesAnalytics|Avg/Month:"
msgstr ""
-msgid "IssuesAnalytics|Issues opened"
+msgid "IssuesAnalytics|Issues created"
msgstr ""
-msgid "IssuesAnalytics|Issues opened per month"
+msgid "IssuesAnalytics|Issues created per month"
msgstr ""
msgid "IssuesAnalytics|Last 12 months"
@@ -20093,6 +20542,9 @@ msgstr ""
msgid "It looks like you have some draft commits in this branch."
msgstr ""
+msgid "It looks like you're attempting to activate your subscription. Use %{a_start}the Subscription page%{a_end} instead."
+msgstr ""
+
msgid "It may be several days before you see feature usage data."
msgstr ""
@@ -20321,6 +20773,9 @@ msgstr ""
msgid "JiraConnect|You can now close this window and return to Jira."
msgstr ""
+msgid "JiraConnect|You don't have permission to create branches for this project. Select a different project or contact the project owner for access. %{linkStart}Learn more.%{linkEnd}"
+msgstr ""
+
msgid "JiraRequest|A connection error occurred while connecting to Jira. Try your request again."
msgstr ""
@@ -20369,13 +20824,13 @@ msgstr ""
msgid "JiraService|Define the type of Jira issue to create from a vulnerability."
msgstr ""
-msgid "JiraService|Displaying Jira issues while leaving the GitLab issue functionality enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
+msgid "JiraService|Displaying Jira issues while leaving GitLab issues also enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
msgstr ""
-msgid "JiraService|Enable Jira issues"
+msgid "JiraService|Enable Jira issue creation from vulnerabilities"
msgstr ""
-msgid "JiraService|Enable Jira issues creation from vulnerabilities"
+msgid "JiraService|Enable Jira issues"
msgstr ""
msgid "JiraService|Enable Jira transitions"
@@ -20492,16 +20947,19 @@ msgstr ""
msgid "JiraService|View Jira issues in GitLab"
msgstr ""
-msgid "JiraService|Warning: All GitLab users that have access to this GitLab project are able to view all issues from the Jira project specified below."
+msgid "JiraService|Warning: All GitLab users with access to this GitLab project can view all issues from the Jira project you select."
msgstr ""
msgid "JiraService|Web URL"
msgstr ""
-msgid "JiraService|Work on Jira issues without leaving GitLab. Adds a Jira menu to access your list of Jira issues and view any issue as read-only."
+msgid "JiraService|When a Jira issue is mentioned in a commit or merge request, a remote link and comment (if enabled) will be created."
+msgstr ""
+
+msgid "JiraService|Work on Jira issues without leaving GitLab. Add a Jira menu to access a read-only list of your Jira issues."
msgstr ""
-msgid "JiraService|You need to configure Jira before enabling this integration. For more details, read the %{jira_doc_link_start}Jira integration documentation%{link_end}."
+msgid "JiraService|You must configure Jira before enabling this integration. %{jira_doc_link_start}Learn more.%{link_end}"
msgstr ""
msgid "Job"
@@ -20513,9 +20971,6 @@ msgstr ""
msgid "Job Failed #%{build_id}"
msgstr ""
-msgid "Job ID"
-msgstr ""
-
msgid "Job artifact"
msgstr ""
@@ -20582,9 +21037,27 @@ msgstr ""
msgid "Jobs|You're about to retry a job that failed because it attempted to deploy code that is older than the latest deployment. Retrying this job could result in overwriting the environment with the older source code."
msgstr ""
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source} into %{target}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{ref}"
+msgstr ""
+
+msgid "Job|Are you sure you want to erase this job log and artifacts?"
+msgstr ""
+
msgid "Job|Browse"
msgstr ""
+msgid "Job|Cancel"
+msgstr ""
+
msgid "Job|Complete Raw"
msgstr ""
@@ -20594,6 +21067,9 @@ msgstr ""
msgid "Job|Erase job log and artifacts"
msgstr ""
+msgid "Job|Finished at"
+msgstr ""
+
msgid "Job|Job artifacts"
msgstr ""
@@ -20606,7 +21082,7 @@ msgstr ""
msgid "Job|Keep"
msgstr ""
-msgid "Job|Pipeline"
+msgid "Job|Retry"
msgstr ""
msgid "Job|Scroll to bottom"
@@ -20618,6 +21094,9 @@ msgstr ""
msgid "Job|Show complete raw"
msgstr ""
+msgid "Job|Status"
+msgstr ""
+
msgid "Job|The artifacts were removed"
msgstr ""
@@ -20645,21 +21124,12 @@ msgstr ""
msgid "Job|delayed"
msgstr ""
-msgid "Job|for"
-msgstr ""
-
-msgid "Job|into"
-msgstr ""
-
msgid "Job|manual"
msgstr ""
msgid "Job|triggered"
msgstr ""
-msgid "Job|with"
-msgstr ""
-
msgid "Join Zoom meeting"
msgstr ""
@@ -20762,9 +21232,6 @@ msgstr ""
msgid "Ki"
msgstr ""
-msgid "Kontra"
-msgstr ""
-
msgid "Kroki"
msgstr ""
@@ -21088,6 +21555,9 @@ msgstr ""
msgid "Learn more about Auto DevOps"
msgstr ""
+msgid "Learn more about GitLab"
+msgstr ""
+
msgid "Learn more about Needs relationships"
msgstr ""
@@ -21415,9 +21885,18 @@ msgstr ""
msgid "Licenses|Displays licenses detected in the project, based on the %{linkStart}latest successful%{linkEnd} scan"
msgstr ""
+msgid "Licenses|Drag your license file here or %{linkStart}click to upload%{linkEnd}."
+msgstr ""
+
+msgid "Licenses|Drop your license file to start the upload."
+msgstr ""
+
msgid "Licenses|Error fetching the license list. Please check your network connection and try again."
msgstr ""
+msgid "Licenses|Error: You are trying to upload something other than a file"
+msgstr ""
+
msgid "Licenses|License Compliance"
msgstr ""
@@ -21436,6 +21915,9 @@ msgstr ""
msgid "Licenses|Specified policies in this project"
msgstr ""
+msgid "Licenses|The file could not be uploaded."
+msgstr ""
+
msgid "Licenses|The license list details information about the licenses used within your project."
msgstr ""
@@ -21469,11 +21951,6 @@ msgstr ""
msgid "Limit the size of Sidekiq jobs stored in Redis."
msgstr ""
-msgid "Limited to showing %d event at most"
-msgid_plural "Limited to showing %d events at most"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Limiting mode"
msgstr ""
@@ -21483,6 +21960,9 @@ msgstr ""
msgid "Link"
msgstr ""
+msgid "Link (optional)"
+msgstr ""
+
msgid "Link Prometheus monitoring to GitLab."
msgstr ""
@@ -21519,6 +21999,9 @@ msgstr ""
msgid "Linked emails (%{email_count})"
msgstr ""
+msgid "Linked epics"
+msgstr ""
+
msgid "Linked issues"
msgstr ""
@@ -21546,6 +22029,15 @@ msgstr ""
msgid "List of all merge commits"
msgstr ""
+msgid "List of environments for this project"
+msgstr ""
+
+msgid "List of suitable GCP locations"
+msgstr ""
+
+msgid "List of users allowed to exceed the rate limit."
+msgstr ""
+
msgid "List options"
msgstr ""
@@ -21765,6 +22257,9 @@ msgstr ""
msgid "Maintenance mode"
msgstr ""
+msgid "Make adjustments to how your GitLab instance is set up."
+msgstr ""
+
msgid "Make and review changes in the browser with the Web IDE"
msgstr ""
@@ -21909,6 +22404,12 @@ msgstr ""
msgid "MarkdownEditor|Add italic text (%{modifier_key}I)"
msgstr ""
+msgid "MarkdownEditor|Add strikethrough text (%{modifierKey}⇧X)"
+msgstr ""
+
+msgid "MarkdownEditor|Add strikethrough text (%{modifier_key}⇧X)"
+msgstr ""
+
msgid "Marked For Deletion At - %{deletion_time}"
msgstr ""
@@ -22170,6 +22671,9 @@ msgstr ""
msgid "Maximum push size (MB)"
msgstr ""
+msgid "Maximum requests per 10 minutes per user"
+msgstr ""
+
msgid "Maximum requests per minute"
msgstr ""
@@ -22260,6 +22764,19 @@ msgstr ""
msgid "Members of a group may only view projects they have permission to access"
msgstr ""
+msgid "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seat in use and will be billed for the overage."
+msgid_plural "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seats in use and will be billed for the overage."
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "MembersOverage|You are about to incur additional charges"
+msgstr ""
+
+msgid "MembersOverage|Your subscription includes %d seat."
+msgid_plural "MembersOverage|Your subscription includes %d seats."
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Membership"
msgstr ""
@@ -22464,9 +22981,6 @@ msgstr ""
msgid "Merge request not merged"
msgstr ""
-msgid "Merge request pipelines 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 merge request pipelines."
-msgstr ""
-
msgid "Merge request reports"
msgstr ""
@@ -22563,13 +23077,13 @@ msgstr ""
msgid "MergeRequests|Create issue to resolve thread"
msgstr ""
-msgid "MergeRequests|Failed to squash. Should be done manually."
+msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Saving the comment failed"
+msgid "MergeRequests|Squashing failed: Squash the commits locally, resolve any conflicts, then push the branch."
msgstr ""
-msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
+msgid "MergeRequests|Squashing not allowed: This project doesn't allow you to squash commits when merging."
msgstr ""
msgid "MergeRequests|Thread stays resolved"
@@ -23410,6 +23924,18 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "MrList|Assigned to %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from assignee %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from reviewer %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Review requested from %{name}, go to their profile."
+msgstr ""
+
msgid "Multi-project"
msgstr ""
@@ -23443,7 +23969,7 @@ msgstr ""
msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "My Awesome Group"
+msgid "My awesome group"
msgstr ""
msgid "My company or team"
@@ -24065,9 +24591,6 @@ msgstr ""
msgid "No available branches"
msgstr ""
-msgid "No available groups to fork the project."
-msgstr ""
-
msgid "No branches found"
msgstr ""
@@ -24278,6 +24801,9 @@ msgstr ""
msgid "No ref selected"
msgstr ""
+msgid "No regions configured"
+msgstr ""
+
msgid "No related merge requests found."
msgstr ""
@@ -25082,6 +25608,9 @@ msgstr ""
msgid "Only reCAPTCHA v2 is supported:"
msgstr ""
+msgid "Only required if not using role instance credentials."
+msgstr ""
+
msgid "Only use lowercase letters, numbers, and underscores."
msgstr ""
@@ -25106,9 +25635,6 @@ msgstr ""
msgid "Open a CLI and connect to the cluster you want to install the agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
-msgid "Open epics"
-msgstr ""
-
msgid "Open errors"
msgstr ""
@@ -25148,8 +25674,8 @@ msgstr ""
msgid "Opened issues"
msgstr ""
-msgid "OpenedNDaysAgo|Opened"
-msgstr "Geopend"
+msgid "OpenedNDaysAgo|Created"
+msgstr ""
msgid "Opens in a new window"
msgstr ""
@@ -25193,9 +25719,6 @@ msgstr ""
msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
-msgid "Optional."
-msgstr ""
-
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
msgstr ""
@@ -25984,6 +26507,9 @@ msgstr ""
msgid "PerformanceBar|Memory"
msgstr ""
+msgid "PerformanceBar|Memory report"
+msgstr ""
+
msgid "PerformanceBar|Redis calls"
msgstr ""
@@ -26017,18 +26543,12 @@ msgstr ""
msgid "PerformanceBar|wall"
msgstr ""
-msgid "Performs a rebase but skips triggering a new pipeline"
-msgstr ""
-
msgid "Period in seconds"
msgstr ""
msgid "Permalink"
msgstr ""
-msgid "Permanently delete project"
-msgstr ""
-
msgid "Permanently remove group"
msgstr ""
@@ -26299,6 +26819,51 @@ msgstr ""
msgid "PipelineStatusTooltip|Pipeline: %{ci_status}"
msgstr ""
+msgid "PipelineWizardDefaultCommitMessage|Add %{filename}"
+msgstr ""
+
+msgid "PipelineWizardDefaultCommitMessage|Update %{filename}"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|At least one entry is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This field is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This value is not valid"
+msgstr ""
+
+msgid "PipelineWizardListWidget|add another step"
+msgstr ""
+
+msgid "PipelineWizardListWidget|remove step"
+msgstr ""
+
+msgid "PipelineWizard|Commit"
+msgstr ""
+
+msgid "PipelineWizard|Commit Message"
+msgstr ""
+
+msgid "PipelineWizard|Commit changes to your file"
+msgstr ""
+
+msgid "PipelineWizard|Commit file to Branch"
+msgstr ""
+
+msgid "PipelineWizard|Commit your new file"
+msgstr ""
+
+msgid "PipelineWizard|The file has been committed."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem committing the changes."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem while checking whether your file already exists in the specified branch."
+msgstr ""
+
msgid "Pipelines"
msgstr ""
@@ -26413,7 +26978,7 @@ msgstr ""
msgid "Pipelines|Project cache successfully reset."
msgstr ""
-msgid "Pipelines|Revoke"
+msgid "Pipelines|Revoke trigger"
msgstr ""
msgid "Pipelines|Something went wrong while cleaning runners cache."
@@ -26458,6 +27023,12 @@ msgstr ""
msgid "Pipelines|This is a child pipeline within the parent pipeline"
msgstr ""
+msgid "Pipelines|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipelines|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipelines|This pipeline will run code originating from a forked project merge request. This means that the code can potentially have security considerations like exposing CI variables."
msgstr ""
@@ -26500,9 +27071,6 @@ msgstr ""
msgid "Pipelines|Your changes have been successfully committed. Now redirecting to the new merge request page."
msgstr ""
-msgid "Pipelines|detached"
-msgstr ""
-
msgid "Pipelines|error"
msgstr ""
@@ -26512,10 +27080,13 @@ msgstr ""
msgid "Pipelines|latest"
msgstr ""
-msgid "Pipelines|stuck"
+msgid "Pipelines|merge request"
msgstr ""
-msgid "Pipelines|train"
+msgid "Pipelines|merge train"
+msgstr ""
+
+msgid "Pipelines|stuck"
msgstr ""
msgid "Pipelines|yaml invalid"
@@ -26647,6 +27218,12 @@ msgstr ""
msgid "Pipeline|This change will not change the overall test coverage if merged."
msgstr ""
+msgid "Pipeline|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipeline|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipeline|Trigger author"
msgstr ""
@@ -26671,6 +27248,12 @@ msgstr ""
msgid "Pipeline|for"
msgstr ""
+msgid "Pipeline|merge request"
+msgstr ""
+
+msgid "Pipeline|merge train"
+msgstr ""
+
msgid "Pipeline|on"
msgstr ""
@@ -26809,9 +27392,6 @@ msgstr ""
msgid "Please enter a valid time interval"
msgstr ""
-msgid "Please enter or upload a valid license."
-msgstr ""
-
msgid "Please enter your current password."
msgstr ""
@@ -26920,9 +27500,6 @@ msgstr ""
msgid "Please type %{phrase_code} to proceed or close this modal to cancel."
msgstr ""
-msgid "Please type the following to confirm:"
-msgstr ""
-
msgid "Please use this form to report to the admin users who create spam issues, comments or behave inappropriately."
msgstr ""
@@ -26950,12 +27527,27 @@ msgstr ""
msgid "Policies"
msgstr ""
+msgid "Policy '%{escalation_policy_name}' does not exist."
+msgstr ""
+
msgid "Policy management project does have any policies in %{policy_path}"
msgstr ""
msgid "Policy project doesn't exist"
msgstr ""
+msgid "PolicyRuleMultiSelect|%{firstLabel} +%{numberOfAdditionalLabels} more"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|All %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select all"
+msgstr ""
+
msgid "Polling interval multiplier"
msgstr ""
@@ -27184,6 +27776,9 @@ msgstr ""
msgid "Private projects can be created in your personal namespace with:"
msgstr ""
+msgid "Problem with %{name} command: %{message}."
+msgstr ""
+
msgid "Proceed"
msgstr ""
@@ -27658,6 +28253,9 @@ msgstr ""
msgid "Progress"
msgstr ""
+msgid "Progress tracking"
+msgstr ""
+
msgid "Project"
msgstr ""
@@ -27889,6 +28487,9 @@ msgstr ""
msgid "ProjectQualitySummary|Failure"
msgstr ""
+msgid "ProjectQualitySummary|Get insight into the overall percentage of tests in your project that succeed, fail and are skipped."
+msgstr ""
+
msgid "ProjectQualitySummary|Latest pipeline results"
msgstr ""
@@ -27907,6 +28508,12 @@ msgstr ""
msgid "ProjectQualitySummary|See project Code Coverage Statistics"
msgstr ""
+msgid "ProjectQualitySummary|Set up test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|Set up test runs (opens in a new tab)"
+msgstr ""
+
msgid "ProjectQualitySummary|Skipped"
msgstr ""
@@ -28183,13 +28790,19 @@ msgstr ""
msgid "ProjectSettings|LFS objects from this repository are available to forks. %{linkStart}How do I remove them?%{linkEnd}"
msgstr ""
+msgid "ProjectSettings|Learn about commit history."
+msgstr ""
+
+msgid "ProjectSettings|Leave empty to use default template."
+msgstr ""
+
msgid "ProjectSettings|Manage who can see the project in the public access directory."
msgstr ""
msgid "ProjectSettings|Manages large files such as audio, video, and graphics files."
msgstr ""
-msgid "ProjectSettings|Maximum 500 characters."
+msgid "ProjectSettings|Maximum %{maxLength} characters."
msgstr ""
msgid "ProjectSettings|Merge checks"
@@ -28330,6 +28943,9 @@ msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
msgstr ""
+msgid "ProjectSettings|The default template will be applied on save."
+msgstr ""
+
msgid "ProjectSettings|These checks must pass before merge requests can be merged."
msgstr ""
@@ -28384,6 +29000,9 @@ msgstr ""
msgid "ProjectSettings|What are badges?"
msgstr ""
+msgid "ProjectSettings|What are merge trains?"
+msgstr ""
+
msgid "ProjectSettings|When merge request pipelines are enabled in the CI/CD configuration file, pipelines validate the combined results of the source and target branches. %{link_start}How to configure merge request pipelines?%{link_end}"
msgstr ""
@@ -28501,6 +29120,9 @@ msgstr ""
msgid "Projects are organized into groups"
msgstr ""
+msgid "Projects are where you store your code, access issues, wiki and other features of GitLab."
+msgstr ""
+
msgid "Projects contributed to"
msgstr ""
@@ -28516,12 +29138,6 @@ msgstr ""
msgid "Projects to index"
msgstr ""
-msgid "Projects will be permanently deleted after a %{waiting_period}-day waiting period."
-msgstr ""
-
-msgid "Projects will be permanently deleted immediately."
-msgstr ""
-
msgid "Projects with critical vulnerabilities"
msgstr ""
@@ -28606,6 +29222,9 @@ msgstr ""
msgid "ProjectsNew|Import project"
msgstr ""
+msgid "ProjectsNew|Include a Getting Started README"
+msgstr ""
+
msgid "ProjectsNew|Initialize repository with a README"
msgstr ""
@@ -28621,6 +29240,9 @@ msgstr ""
msgid "ProjectsNew|Project description %{tag_start}(optional)%{tag_end}"
msgstr ""
+msgid "ProjectsNew|Recommended if you're new to GitLab"
+msgstr ""
+
msgid "ProjectsNew|Run CI/CD for external repository"
msgstr ""
@@ -29038,6 +29660,9 @@ msgstr ""
msgid "ProtectedBranch|Unprotect"
msgstr ""
+msgid "ProtectedBranch|Unprotect branch"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
@@ -29065,6 +29690,9 @@ msgstr ""
msgid "ProtectedEnvironment|Protected Environment (%{protected_environments_count})"
msgstr ""
+msgid "ProtectedEnvironment|Required approvals"
+msgstr ""
+
msgid "ProtectedEnvironment|Select an environment"
msgstr ""
@@ -29086,10 +29714,13 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|Unprotect tag"
+msgstr ""
+
msgid "ProtectedTags|default"
msgstr ""
-msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
+msgid "ProtectedTag|By default, protected tags restrict who can modify the tag."
msgstr ""
msgid "ProtectedTag|Learn more."
@@ -29152,6 +29783,9 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Public projects are an easy way to allow everyone to have read-only access."
+msgstr ""
+
msgid "Publish to status page"
msgstr ""
@@ -29308,9 +29942,6 @@ msgstr ""
msgid "QualitySummary|Project quality"
msgstr ""
-msgid "Quarters"
-msgstr ""
-
msgid "Query"
msgstr ""
@@ -29395,6 +30026,9 @@ msgstr ""
msgid "Read more about project permissions %{help_link_open}here%{help_link_close}"
msgstr ""
+msgid "Read more about related epics"
+msgstr ""
+
msgid "Read more about related issues"
msgstr ""
@@ -29425,10 +30059,7 @@ msgstr ""
msgid "Rebase source branch on the target branch."
msgstr ""
-msgid "Rebase without CI"
-msgstr ""
-
-msgid "Rebases and triggers a pipeline"
+msgid "Rebase without pipeline"
msgstr ""
msgid "Recaptcha verified?"
@@ -29479,9 +30110,6 @@ msgstr ""
msgid "Reconfigure"
msgstr ""
-msgid "Recovering projects"
-msgstr ""
-
msgid "Recovery Codes"
msgstr ""
@@ -29541,6 +30169,12 @@ msgstr ""
msgid "Regex pattern"
msgstr ""
+msgid "Region"
+msgstr ""
+
+msgid "Regions"
+msgstr ""
+
msgid "Register"
msgstr ""
@@ -29771,9 +30405,6 @@ msgstr ""
msgid "Remove all or specific reviewer(s)"
msgstr ""
-msgid "Remove approver"
-msgstr ""
-
msgid "Remove approvers"
msgstr ""
@@ -29789,6 +30420,9 @@ msgstr ""
msgid "Remove attention request"
msgstr ""
+msgid "Remove attention request(s)"
+msgstr ""
+
msgid "Remove avatar"
msgstr ""
@@ -29927,6 +30561,9 @@ msgstr ""
msgid "Removed an issue from an epic."
msgstr ""
+msgid "Removed attention from %{users_sentence}."
+msgstr ""
+
msgid "Removed attention request from @%{username}"
msgstr ""
@@ -29978,6 +30615,9 @@ msgstr ""
msgid "Removes an issue from an epic."
msgstr ""
+msgid "Removes attention from %{users_sentence}."
+msgstr ""
+
msgid "Removes parent epic %{epic_ref}."
msgstr ""
@@ -30089,6 +30729,9 @@ msgstr ""
msgid "Report abuse to admin"
msgstr ""
+msgid "Report is generating and will be sent to your email address."
+msgstr ""
+
msgid "Reported %{timeAgo} by %{reportedBy}"
msgstr ""
@@ -30378,6 +31021,15 @@ msgstr ""
msgid "Request attention"
msgstr ""
+msgid "Request attention from %{users_sentence}."
+msgstr ""
+
+msgid "Request attention from assignee or reviewer"
+msgstr ""
+
+msgid "Request attention from assignee(s) or reviewer(s)"
+msgstr ""
+
msgid "Request attention to review"
msgstr ""
@@ -30402,6 +31054,9 @@ msgstr ""
msgid "Requested %{time_ago}"
msgstr ""
+msgid "Requested attention from %{users_sentence}."
+msgstr ""
+
msgid "Requested attention from @%{username}"
msgstr ""
@@ -30616,6 +31271,9 @@ msgstr ""
msgid "Restore project"
msgstr ""
+msgid "Restoring projects"
+msgstr ""
+
msgid "Restoring the group will prevent the group, its subgroups and projects from being removed on this date."
msgstr ""
@@ -30646,6 +31304,9 @@ msgstr ""
msgid "Retry"
msgstr ""
+msgid "Retry failed jobs"
+msgstr ""
+
msgid "Retry job"
msgstr ""
@@ -30693,9 +31354,6 @@ msgstr ""
msgid "Review changes"
msgstr ""
-msgid "Review requested from %{name}"
-msgstr ""
-
msgid "Review requests for you"
msgstr ""
@@ -30860,6 +31518,9 @@ msgstr ""
msgid "Runners|Assigned Group"
msgstr ""
+msgid "Runners|Assigned Projects (%{projectCount})"
+msgstr ""
+
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30929,6 +31590,9 @@ msgstr ""
msgid "Runners|Instance"
msgstr ""
+msgid "Runners|Jobs"
+msgstr ""
+
msgid "Runners|Last contact"
msgstr ""
@@ -31022,9 +31686,6 @@ msgstr ""
msgid "Runners|Runner %{name} was deleted"
msgstr ""
-msgid "Runners|Runner ID"
-msgstr ""
-
msgid "Runners|Runner assigned to project."
msgstr ""
@@ -31172,6 +31833,9 @@ msgstr ""
msgid "Runners|stale"
msgstr ""
+msgid "Runner|This runner has not run any jobs."
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -31286,6 +31950,24 @@ msgstr ""
msgid "Saving project."
msgstr ""
+msgid "ScanResultPolicy|%{ifLabelStart}if%{ifLabelEnd} %{scanners} scan in an open merge request targeting the %{branches} branch(es) finds %{vulnerabilitiesAllowed} or more %{severities} vulnerabilities that are %{vulnerabilityStates}"
+msgstr ""
+
+msgid "ScanResultPolicy|%{thenLabelStart}Then%{thenLabelEnd} Require approval from %{approvalsRequired} of the following approvers: %{approvers}"
+msgstr ""
+
+msgid "ScanResultPolicy|add an approver"
+msgstr ""
+
+msgid "ScanResultPolicy|scanners"
+msgstr ""
+
+msgid "ScanResultPolicy|severity levels"
+msgstr ""
+
+msgid "ScanResultPolicy|vulnerability states"
+msgstr ""
+
msgid "Scanner"
msgstr ""
@@ -31418,6 +32100,9 @@ msgstr ""
msgid "Search for a user"
msgstr ""
+msgid "Search for an emoji"
+msgstr ""
+
msgid "Search for projects, issues, etc."
msgstr ""
@@ -31605,18 +32290,12 @@ msgstr ""
msgid "Secret Detection"
msgstr ""
-msgid "Secret access key"
-msgstr ""
-
msgid "Secret token"
msgstr ""
msgid "Secure token that identifies an external storage request."
msgstr ""
-msgid "SecureCodeWarrior"
-msgstr ""
-
msgid "Security"
msgstr ""
@@ -31641,9 +32320,6 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "Security training with guide and learning pathways."
-msgstr ""
-
msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
@@ -31746,7 +32422,7 @@ msgstr ""
msgid "SecurityConfiguration|Manage corpus"
msgstr ""
-msgid "SecurityConfiguration|Manage corpus files used as mutation sources in coverage fuzzing."
+msgid "SecurityConfiguration|Manage corpus files used as seed inputs with coverage-guided fuzzing."
msgstr ""
msgid "SecurityConfiguration|Manage profiles for use by DAST scans."
@@ -31812,15 +32488,15 @@ msgstr ""
msgid "SecurityOrchestration|.yaml preview"
msgstr ""
-msgid "SecurityOrchestration|Action"
-msgstr ""
-
msgid "SecurityOrchestration|Actions"
msgstr ""
msgid "SecurityOrchestration|Add rule"
msgstr ""
+msgid "SecurityOrchestration|After dismissing the alert, the information will never be shown again."
+msgstr ""
+
msgid "SecurityOrchestration|All policies"
msgstr ""
@@ -31836,7 +32512,7 @@ msgstr ""
msgid "SecurityOrchestration|Description"
msgstr ""
-msgid "SecurityOrchestration|Disabled"
+msgid "SecurityOrchestration|Don't show the alert anymore"
msgstr ""
msgid "SecurityOrchestration|Edit policy"
@@ -31845,13 +32521,13 @@ msgstr ""
msgid "SecurityOrchestration|Edit policy project"
msgstr ""
-msgid "SecurityOrchestration|Enabled"
+msgid "SecurityOrchestration|Empty policy name"
msgstr ""
-msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Enabled"
msgstr ""
-msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
msgstr ""
msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
@@ -31860,7 +32536,7 @@ msgstr ""
msgid "SecurityOrchestration|Invalid policy type"
msgstr ""
-msgid "SecurityOrchestration|Latest scan"
+msgid "SecurityOrchestration|Latest scan run against %{agent}"
msgstr ""
msgid "SecurityOrchestration|Network"
@@ -31869,15 +32545,27 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No actions defined - policy will not run."
+msgstr ""
+
+msgid "SecurityOrchestration|No description"
+msgstr ""
+
msgid "SecurityOrchestration|No rules defined - policy will not run."
msgstr ""
+msgid "SecurityOrchestration|Not enabled"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
msgid "SecurityOrchestration|Policies"
msgstr ""
+msgid "SecurityOrchestration|Policy Type"
+msgstr ""
+
msgid "SecurityOrchestration|Policy cannot be enabled for non-existing branches (%{branches})"
msgstr ""
@@ -31902,10 +32590,13 @@ msgstr ""
msgid "SecurityOrchestration|Require %{approvals} %{plural} from %{approvers} if any of the following occur:"
msgstr ""
-msgid "SecurityOrchestration|Rule"
+msgid "SecurityOrchestration|Rules"
msgstr ""
-msgid "SecurityOrchestration|Rules"
+msgid "SecurityOrchestration|Runs %{actions} and %{lastAction} scans"
+msgstr ""
+
+msgid "SecurityOrchestration|Runs a %{action} scan"
msgstr ""
msgid "SecurityOrchestration|Scan Execution"
@@ -31965,6 +32656,9 @@ msgstr ""
msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
+msgid "SecurityOrchestration|This view only shows scan results for the agent %{agent}. You can view scan results for all agents in the %{linkStart}Operational Vulnerabilities tab of the vulnerability report%{linkEnd}."
+msgstr ""
+
msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
@@ -32019,9 +32713,6 @@ msgstr ""
msgid "SecurityOrchestration|users with ids"
msgstr ""
-msgid "SecurityOrchestration|view results"
-msgstr ""
-
msgid "SecurityOrchestration|vulnerabilities"
msgstr ""
@@ -32691,22 +33382,19 @@ 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|In order to start using functions as a service, you must first install Knative on your Kubernetes cluster. %{linkStart}More information%{linkEnd}"
-msgstr ""
-
msgid "Serverless|Learn more about Serverless"
msgstr ""
msgid "Serverless|No functions available"
msgstr ""
-msgid "Serverless|Sign up for First Look"
+msgid "Serverless|Serverless was %{linkStart}deprecated%{linkEnd} in GitLab 14.3."
+msgstr ""
+
+msgid "Serverless|Serverless was %{postLinkStart}deprecated%{postLinkEnd}. But if you opt to use it, you must install Knative in your Kubernetes cluster first. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "Serverless|The deploy job has not finished."
@@ -32718,9 +33406,6 @@ 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 ""
@@ -32736,9 +33421,6 @@ msgstr ""
msgid "Service Account Key"
msgstr ""
-msgid "Service Accounts"
-msgstr ""
-
msgid "Service Accounts keys authorize GitLab to deploy your Google Cloud project"
msgstr ""
@@ -32748,10 +33430,10 @@ msgstr ""
msgid "Service Desk allows people to create issues in your GitLab instance without their own user account. It provides a unique email address for end users to create issues in a project. Replies can be sent either through the GitLab interface or by email. End users only see threads through email."
msgstr ""
-msgid "Service Usage Data"
+msgid "Service account generated successfully"
msgstr ""
-msgid "Service account generated successfully"
+msgid "Service accounts"
msgstr ""
msgid "Service ping is disabled in your configuration file, and cannot be enabled through this form."
@@ -32895,6 +33577,9 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
+msgid "Set the per-user rate limit for getting a user by ID via the API."
+msgstr ""
+
msgid "Set the per-user rate limit for notes created by web or API requests."
msgstr ""
@@ -33074,6 +33759,9 @@ msgstr ""
msgid "Shared runners details"
msgstr ""
+msgid "Shared runners enabled cannot be enabled until a valid credit card is on file"
+msgstr ""
+
msgid "Shared runners help link"
msgstr ""
@@ -33131,6 +33819,9 @@ msgstr ""
msgid "Show all issues."
msgstr ""
+msgid "Show all milestones"
+msgstr ""
+
msgid "Show all test cases."
msgstr ""
@@ -33167,6 +33858,9 @@ msgstr ""
msgid "Show file contents"
msgstr ""
+msgid "Show group milestones"
+msgstr ""
+
msgid "Show labels"
msgstr ""
@@ -33182,6 +33876,12 @@ msgstr ""
msgid "Show open epics"
msgstr ""
+msgid "Show project milestones"
+msgstr ""
+
+msgid "Show sub-group milestones"
+msgstr ""
+
msgid "Show the Closed list"
msgstr ""
@@ -33191,11 +33891,6 @@ msgstr ""
msgid "Show whitespace changes"
msgstr ""
-msgid "Showing %d event"
-msgid_plural "Showing %d events"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Showing %{conflict} between %{sourceBranch} and %{targetBranch}"
msgstr ""
@@ -33255,12 +33950,6 @@ msgstr ""
msgid "Sidebar|None"
msgstr ""
-msgid "Sidebar|Only numeral characters allowed"
-msgstr ""
-
-msgid "Sidebar|Weight"
-msgstr ""
-
msgid "Sidekiq job compression threshold (bytes)"
msgstr ""
@@ -33423,6 +34112,9 @@ msgstr ""
msgid "Slack logo"
msgstr ""
+msgid "SlackIntegration|Are you sure you want to remove this project from the Slack application?"
+msgstr ""
+
msgid "SlackIntegration|GitLab for Slack"
msgstr ""
@@ -33432,6 +34124,9 @@ msgstr ""
msgid "SlackIntegration|Project alias"
msgstr ""
+msgid "SlackIntegration|Remove project"
+msgstr ""
+
msgid "SlackIntegration|Select a GitLab project to link with your Slack workspace."
msgstr ""
@@ -33576,9 +34271,6 @@ msgstr ""
msgid "Something went wrong trying to load issue contacts."
msgstr ""
-msgid "Something went wrong when creating a work item. Please try again"
-msgstr ""
-
msgid "Something went wrong when reordering designs. Please try again"
msgstr ""
@@ -33672,9 +34364,6 @@ msgstr ""
msgid "Something went wrong while inserting your image. Please try again."
msgstr ""
-msgid "Something went wrong while merging this merge request. Please try again."
-msgstr ""
-
msgid "Something went wrong while obtaining the Let's Encrypt certificate."
msgstr ""
@@ -33996,10 +34685,10 @@ 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."
+msgid "SourcegraphAdmin|Learn more."
msgstr ""
-msgid "SourcegraphAdmin|More information"
+msgid "SourcegraphAdmin|Only public projects have code intelligence enabled and communicate with Sourcegraph."
msgstr ""
msgid "SourcegraphAdmin|Save changes"
@@ -34008,7 +34697,7 @@ msgstr ""
msgid "SourcegraphAdmin|Sourcegraph URL"
msgstr ""
-msgid "SourcegraphAdmin|e.g. https://sourcegraph.example.com"
+msgid "SourcegraphAdmin|https://sourcegraph.example.com"
msgstr ""
msgid "SourcegraphPreferences|This feature is experimental and currently limited to certain projects."
@@ -34143,6 +34832,9 @@ msgstr ""
msgid "Start date"
msgstr ""
+msgid "Start free trial"
+msgstr ""
+
msgid "Start merge train"
msgstr ""
@@ -34173,6 +34865,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started escalation for this incident."
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -34185,6 +34880,9 @@ msgstr ""
msgid "Starts at (UTC)"
msgstr ""
+msgid "Starts escalations for this incident"
+msgstr ""
+
msgid "Starts on"
msgstr ""
@@ -34446,6 +35144,9 @@ msgstr ""
msgid "Strikethrough"
msgstr ""
+msgid "Strikethrough text"
+msgstr ""
+
msgid "Subgroup information"
msgstr ""
@@ -34680,6 +35381,21 @@ msgstr ""
msgid "Subscriptions"
msgstr ""
+msgid "Subscriptions|Chat with sales"
+msgstr ""
+
+msgid "Subscriptions|Close"
+msgstr ""
+
+msgid "Subscriptions|Not ready to buy yet?"
+msgstr ""
+
+msgid "Subscriptions|Start a free trial"
+msgstr ""
+
+msgid "Subscriptions|We understand. Maybe you have some questions for our sales team, or maybe you'd like to try some of the paid features first. What would you like to do?"
+msgstr ""
+
msgid "Subscription|Your subscription for %{strong}%{namespace_name}%{strong_close} has expired and you are now on %{pricing_link_start}the GitLab Free tier%{pricing_link_end}. Don't worry, your data is safe. Get in touch with our support team (%{support_email}). They'll gladly help with your subscription renewal."
msgstr ""
@@ -34890,6 +35606,9 @@ msgstr ""
msgid "SuperSonics|Maximum users"
msgstr ""
+msgid "SuperSonics|Offline cloud"
+msgstr ""
+
msgid "SuperSonics|Paste your activation code"
msgstr ""
@@ -34956,6 +35675,12 @@ msgstr ""
msgid "SuperSonics|You do not have an active subscription"
msgstr ""
+msgid "SuperSonics|You have a future dated license"
+msgstr ""
+
+msgid "SuperSonics|You have added a license that activates on %{date}. Please see the subscription history table below for more details."
+msgstr ""
+
msgid "SuperSonics|You have successfully added a license that activates on %{date}. Please see the subscription history table below for more details."
msgstr ""
@@ -35115,6 +35840,9 @@ msgstr ""
msgid "Tag name is required"
msgstr ""
+msgid "Tag push"
+msgstr ""
+
msgid "Tag push events"
msgstr ""
@@ -35217,6 +35945,9 @@ msgstr ""
msgid "TagsPage|protected"
msgstr ""
+msgid "Take a look at the documentation to discover all of GitLab’s capabilities."
+msgstr ""
+
msgid "Target Branch"
msgstr ""
@@ -35619,6 +36350,9 @@ msgstr ""
msgid "Tests"
msgstr ""
+msgid "Text (optional)"
+msgstr ""
+
msgid "Text added to the body of all email messages. %{character_limit} character limit"
msgstr ""
@@ -35669,6 +36403,9 @@ msgstr ""
msgid "The CSV export will be created in the background. Once finished, it will be sent to %{email} in an attachment."
msgstr ""
+msgid "The CSV export you requested of all user memberships is attached to this email."
+msgstr ""
+
msgid "The GitLab subscription service (customers.gitlab.com) is currently experiencing an outage. You can monitor the status and get updates at %{linkStart}status.gitlab.com%{linkEnd}."
msgstr ""
@@ -35744,6 +36481,9 @@ 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 epic"
+msgstr ""
+
msgid "The current issue"
msgstr ""
@@ -35905,6 +36645,9 @@ msgstr ""
msgid "The latest pipeline for this merge request has failed."
msgstr ""
+msgid "The license key is invalid."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -35920,6 +36663,9 @@ msgstr ""
msgid "The license was successfully uploaded and will be active from %{starts_at}. You can see the details below."
msgstr ""
+msgid "The license you uploaded is invalid. If the issue persists, contact support at %{link}."
+msgstr ""
+
msgid "The list creation wizard is already open"
msgstr ""
@@ -36541,10 +37287,13 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} and everything this project contains. %{strongOpen}There is no going back%{strongClose}"
+msgstr ""
+
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains."
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}on %{date}%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains. %{strongOpen}There is no going back.%{strongClose}"
msgstr ""
msgid "This action will %{strongOpen}permanently remove%{strongClose} %{codeOpen}%{group}%{codeClose} %{strongOpen}immediately%{strongClose}."
@@ -36673,9 +37422,6 @@ msgstr ""
msgid "This file was modified for readability, and can't accept suggestions. Edit it directly."
msgstr ""
-msgid "This forked project has the following:"
-msgstr ""
-
msgid "This form is disabled in preview"
msgstr ""
@@ -36688,7 +37434,7 @@ msgstr ""
msgid "This group can't be removed because it is linked to a subscription. To remove this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
-msgid "This group can't be transfered because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
+msgid "This group can't be transferred because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
msgid "This group cannot be invited to a project inside a group with enforced SSO"
@@ -36715,6 +37461,9 @@ 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 incident is already escalated with '%{escalation_policy_name}'."
+msgstr ""
+
msgid "This invitation was sent to %{mail_to_invite_email}, but you are signed in as %{link_to_current_user} with email %{mail_to_current_user}."
msgstr ""
@@ -36733,9 +37482,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 merge train pipeline"
-msgstr ""
-
msgid "This is a private email address %{helpIcon} generated just for you. Anyone who has it can create issues or merge requests as if they were you. If that happens, %{resetLinkStart}reset this token%{resetLinkEnd}."
msgstr ""
@@ -36757,6 +37503,12 @@ msgstr ""
msgid "This is your current session"
msgstr ""
+msgid "This issue cannot be assigned to a confidential epic because it is public."
+msgstr ""
+
+msgid "This issue cannot be made public because it belongs to a confidential epic."
+msgstr ""
+
msgid "This issue is confidential and should only be visible to team members with at least Reporter access."
msgstr ""
@@ -36874,6 +37626,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 branch is protected from force push."
+msgstr ""
+
msgid "This merge request cannot be rebased while there are conflicts."
msgstr ""
@@ -36925,9 +37680,15 @@ msgstr ""
msgid "This pipeline was triggered by a schedule."
msgstr ""
+msgid "This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project"
msgstr ""
+msgid "This project can be restored until %{date}."
+msgstr ""
+
msgid "This project cannot be %{visibilityLevel} because the visibility of %{openShowLink}%{name}%{closeShowLink} is %{visibility}. To make this project %{visibilityLevel}, you must first %{openEditLink}change the visibility%{closeEditLink} of the parent group."
msgstr ""
@@ -36946,6 +37707,9 @@ msgstr ""
msgid "This project is %{strongStart}NOT%{strongEnd} a fork, and has the following:"
msgstr ""
+msgid "This project is %{strongStart}NOT%{strongEnd} a fork. This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -37637,6 +38401,9 @@ msgstr ""
msgid "Today"
msgstr ""
+msgid "Todos count"
+msgstr ""
+
msgid "Todos|Are you looking for things to do? Take a look at %{strongStart}%{openIssuesLinkStart}open issues%{openIssuesLinkEnd}%{strongEnd}, contribute to %{strongStart}%{mergeRequestLinkStart}a merge request%{mergeRequestLinkEnd}%{mergeRequestLinkEnd}%{strongEnd}, or mention someone in a comment to automatically assign them a new to-do item."
msgstr ""
@@ -37910,10 +38677,8 @@ msgstr ""
msgid "Trending"
msgstr ""
-msgid "Trials|%{planName} Trial %{enDash} %{num} day left"
-msgid_plural "Trials|%{planName} Trial %{enDash} %{num} days left"
-msgstr[0] ""
-msgstr[1] ""
+msgid "Trials|%{planName} Trial"
+msgstr ""
msgid "Trials|Compare all plans"
msgstr ""
@@ -37921,6 +38686,9 @@ msgstr ""
msgid "Trials|Create a new group to start your GitLab Ultimate trial."
msgstr ""
+msgid "Trials|Day %{daysUsed}/%{duration}"
+msgstr ""
+
msgid "Trials|Go back to GitLab"
msgstr ""
@@ -38170,7 +38938,7 @@ msgstr ""
msgid "URL is triggered when repository is updated"
msgstr ""
-msgid "URL must be percent-encoded if neccessary."
+msgid "URL must be percent-encoded if necessary."
msgstr ""
msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
@@ -38389,6 +39157,9 @@ msgstr ""
msgid "Unlock account"
msgstr ""
+msgid "Unlock more features with GitLab Ultimate"
+msgstr ""
+
msgid "Unlock the discussion"
msgstr ""
@@ -38452,6 +39223,9 @@ msgstr ""
msgid "Unsubscribes from this %{quick_action_target}."
msgstr ""
+msgid "Unsupported sort value."
+msgstr ""
+
msgid "Unsupported todo type passed. Supported todo types are: %{todo_types}"
msgstr ""
@@ -38680,6 +39454,9 @@ msgstr ""
msgid "UsageQuota|File attachments and smaller design graphics."
msgstr ""
+msgid "UsageQuota|From %{storage_enforcement_date} storage limits will apply to this namespace. View and manage your usage in %{strong_start}Group Settings &gt; Usage quotas%{strong_end}."
+msgstr ""
+
msgid "UsageQuota|Git repository."
msgstr ""
@@ -38740,6 +39517,9 @@ msgstr ""
msgid "UsageQuota|Storage type"
msgstr ""
+msgid "UsageQuota|Storage used"
+msgstr ""
+
msgid "UsageQuota|This is the total amount of storage used across your projects within this namespace."
msgstr ""
@@ -38935,6 +39715,12 @@ msgstr ""
msgid "Use hashed storage paths for newly created and renamed repositories. Always enabled since 13.0."
msgstr ""
+msgid "Use issue count"
+msgstr ""
+
+msgid "Use issue weight"
+msgstr ""
+
msgid "Use one line per URI"
msgstr ""
@@ -39316,6 +40102,9 @@ msgstr ""
msgid "Users"
msgstr ""
+msgid "Users API rate limit"
+msgstr ""
+
msgid "Users can launch a development environment from a GitLab browser tab when the %{linkStart}Gitpod%{linkEnd} integration is enabled."
msgstr ""
@@ -39641,6 +40430,9 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View group pipeline usage quota"
+msgstr ""
+
msgid "View incident details at"
msgstr ""
@@ -39793,6 +40585,9 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
+msgid "Vulnerability"
+msgstr ""
+
msgid "Vulnerability Report"
msgstr ""
@@ -39844,6 +40639,9 @@ msgstr ""
msgid "VulnerabilityManagement|An unverified non-confirmed finding"
msgstr ""
+msgid "VulnerabilityManagement|At least one identifier is required"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -39853,12 +40651,24 @@ msgstr ""
msgid "VulnerabilityManagement|Create Jira issue"
msgstr ""
+msgid "VulnerabilityManagement|Enter a name"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE code"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE identifier URL"
+msgstr ""
+
msgid "VulnerabilityManagement|Fetching linked Jira issues"
msgstr ""
msgid "VulnerabilityManagement|Manually add a vulnerability entry into the vulnerability report."
msgstr ""
+msgid "VulnerabilityManagement|Name is a required field"
+msgstr ""
+
msgid "VulnerabilityManagement|Needs triage"
msgstr ""
@@ -39874,6 +40684,18 @@ msgstr ""
msgid "VulnerabilityManagement|Select a method"
msgstr ""
+msgid "VulnerabilityManagement|Select a severity level"
+msgstr ""
+
+msgid "VulnerabilityManagement|Select a status"
+msgstr ""
+
+msgid "VulnerabilityManagement|Severity is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Something went wrong while creating vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -39898,6 +40720,12 @@ msgstr ""
msgid "VulnerabilityManagement|Something went wrong, could not update vulnerability state."
msgstr ""
+msgid "VulnerabilityManagement|Status is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Submit vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Summary, detailed description, steps to reproduce, etc."
msgstr ""
@@ -40093,6 +40921,9 @@ msgstr ""
msgid "WARNING:"
msgstr ""
+msgid "WARNING: This snippet contains hidden files which might be used to mask malicious behavior. Exercise caution if cloning and executing code from this snippet."
+msgstr ""
+
msgid "Wait for the file to load to copy its contents"
msgstr ""
@@ -40312,6 +41143,15 @@ msgstr ""
msgid "Webhooks|An issue is created, updated, closed, or reopened."
msgstr ""
+msgid "Webhooks|Are you sure you want to delete this group hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this project hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this webhook?"
+msgstr ""
+
msgid "Webhooks|Comments"
msgstr ""
@@ -40321,6 +41161,9 @@ msgstr ""
msgid "Webhooks|Confidential issues events"
msgstr ""
+msgid "Webhooks|Delete webhook"
+msgstr ""
+
msgid "Webhooks|Deployment events"
msgstr ""
@@ -40554,6 +41397,9 @@ msgstr ""
msgid "Wiki"
msgstr ""
+msgid "Wiki page"
+msgstr ""
+
msgid "Wiki page was successfully created."
msgstr ""
@@ -40659,7 +41505,7 @@ msgstr ""
msgid "WikiPageConflictMessage|Someone edited the page the same time you did. Please check out %{wikiLinkStart}the page%{wikiLinkEnd} and make sure your changes will not unintentionally remove theirs."
msgstr ""
-msgid "WikiPage|An error occured while trying to render the content editor. Please try again later."
+msgid "WikiPage|An error occurred while trying to render the content editor. Please try again later."
msgstr ""
msgid "WikiPage|Are you sure you want to switch back to the classic editor?"
@@ -40818,6 +41664,18 @@ msgstr ""
msgid "WorkItem|New Task"
msgstr ""
+msgid "WorkItem|Something went wrong when creating a work item. Please try again"
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching the work item. Please try again."
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching work item types. Please try again"
+msgstr ""
+
+msgid "WorkItem|Type"
+msgstr ""
+
msgid "WorkItem|Work Items"
msgstr ""
@@ -40884,7 +41742,10 @@ msgstr ""
msgid "You are about to add %{usersTag} people to the discussion. They will all receive a notification."
msgstr ""
-msgid "You are about to permanently delete this project"
+msgid "You are about to delete this forked project containing:"
+msgstr ""
+
+msgid "You are about to delete this project containing:"
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."
@@ -40905,6 +41766,9 @@ msgstr ""
msgid "You are attempting to update a file that has changed since you started editing it."
msgstr ""
+msgid "You are billed if you exceed this number. %{qsrOverageLinkStart}How does billing work?%{qsrOverageLinkEnd}"
+msgstr ""
+
msgid "You are connected to the Prometheus server, but there is currently no data to display."
msgstr ""
@@ -40962,6 +41826,9 @@ msgstr ""
msgid "You are not authorized to update this scanner profile"
msgstr ""
+msgid "You are not authorized to upload metric images"
+msgstr ""
+
msgid "You are now impersonating %{username}"
msgstr ""
@@ -41115,9 +41982,6 @@ msgstr ""
msgid "You can only upload one design when dropping onto an existing design."
msgstr ""
-msgid "You can recover this project until %{date}"
-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 ""
@@ -41166,9 +42030,6 @@ msgstr ""
msgid "You cannot write to this read-only GitLab instance."
msgstr ""
-msgid "You can’t %{tag_start}edit%{tag_end} files directly in this project. Fork this project and submit a merge request with your changes."
-msgstr ""
-
msgid "You can’t edit files directly in this project. Fork this project and submit a merge request with your changes."
msgstr ""
@@ -41321,9 +42182,6 @@ 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 set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
@@ -41354,12 +42212,6 @@ msgstr ""
msgid "You must have maintainer access to force delete a lock"
msgstr ""
-msgid "You must have permission to create a project in a group before forking."
-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 ""
@@ -41765,7 +42617,7 @@ msgstr ""
msgid "Your public email will be displayed on your public profile."
msgstr ""
-msgid "Your request for access could not be processed: %{error_meesage}"
+msgid "Your request for access could not be processed: %{error_message}"
msgstr ""
msgid "Your request for access has been queued for review."
@@ -41948,6 +42800,9 @@ msgstr ""
msgid "archived:"
msgstr ""
+msgid "artifacts"
+msgstr ""
+
msgid "assign yourself"
msgstr ""
@@ -41977,6 +42832,9 @@ msgstr[1] ""
msgid "branch name"
msgstr ""
+msgid "builds"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -42400,6 +43258,9 @@ msgstr ""
msgid "contact with same email already exists in group hierarchy"
msgstr ""
+msgid "container registry images"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -42439,6 +43300,9 @@ msgstr ""
msgid "data"
msgstr ""
+msgid "database"
+msgstr ""
+
msgid "date must not be after 9999-12-31"
msgstr ""
@@ -42462,9 +43326,6 @@ msgstr ""
msgid "design"
msgstr ""
-msgid "detached"
-msgstr ""
-
msgid "disabled"
msgstr ""
@@ -42713,7 +43574,7 @@ msgstr ""
msgid "is not a valid X509 certificate."
msgstr ""
-msgid "is not allowed for sign-up."
+msgid "is not allowed for sign-up. Please use your regular email address."
msgstr ""
msgid "is not allowed for this group."
@@ -42725,7 +43586,7 @@ msgstr ""
msgid "is not allowed since the group is not top-level group."
msgstr ""
-msgid "is not allowed."
+msgid "is not allowed. Please use your regular email address."
msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
@@ -42812,6 +43673,9 @@ msgstr ""
msgid "level: %{level}"
msgstr ""
+msgid "lfs objects"
+msgstr ""
+
msgid "limit of %{project_limit} reached"
msgstr ""
@@ -43031,6 +43895,9 @@ msgstr ""
msgid "mrWidget|Merge blocked: pipeline must succeed. It's waiting for a manual action to continue."
msgstr ""
+msgid "mrWidget|Merge blocked: pipeline must succeed. Push a commit that fixes the failure, or %{linkStart}learn about other solutions.%{linkEnd}"
+msgstr ""
+
msgid "mrWidget|Merge blocked: this merge request must be approved."
msgstr ""
@@ -43148,9 +44015,6 @@ msgstr ""
msgid "mrWidget|The changes were not merged into"
msgstr ""
-msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -43298,9 +44162,6 @@ msgstr ""
msgid "open issue"
msgstr ""
-msgid "opened %{timeAgo}"
-msgstr ""
-
msgid "or"
msgstr ""
@@ -43312,6 +44173,12 @@ msgid_plural "out of %d total tests"
msgstr[0] ""
msgstr[1] ""
+msgid "packages"
+msgstr ""
+
+msgid "pages"
+msgstr ""
+
msgid "parent"
msgid_plural "parents"
msgstr[0] ""
@@ -43461,6 +44328,9 @@ msgid_plural "replies"
msgstr[0] ""
msgstr[1] ""
+msgid "repositories"
+msgstr ""
+
msgid "repository:"
msgstr ""
@@ -43581,12 +44451,18 @@ msgstr ""
msgid "tag name"
msgstr ""
+msgid "terraform states"
+msgstr ""
+
msgid "the correct format."
msgstr ""
msgid "the file"
msgstr ""
+msgid "the following epic(s)"
+msgstr ""
+
msgid "the following issue(s)"
msgstr ""
@@ -43599,21 +44475,12 @@ msgstr ""
msgid "this document"
msgstr ""
-msgid "this issue cannot be assigned to a confidential epic since it is public"
-msgstr ""
-
-msgid "this issue cannot be made public since it belongs to a confidential epic"
-msgstr ""
-
msgid "time summary"
msgstr ""
msgid "toggle collapse"
msgstr ""
-msgid "train"
-msgstr ""
-
msgid "triggered"
msgstr ""
@@ -43742,3 +44609,6 @@ msgstr ""
msgid "{project}"
msgstr ""
+msgid "✔"
+msgstr ""
+
diff --git a/locale/or_IN/gitlab.po b/locale/or_IN/gitlab.po
index 8690b4dbf35..aa04db3d8d5 100644
--- a/locale/or_IN/gitlab.po
+++ b/locale/or_IN/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: or\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2022-02-02 15:47\n"
+"PO-Revision-Date: 2022-03-01 20:40\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -146,6 +146,11 @@ msgid_plural "%d approvers (you've approved)"
msgstr[0] ""
msgstr[1] ""
+msgid "%d assigned issue"
+msgid_plural "%d assigned issues"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -421,8 +426,23 @@ msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
msgstr[1] ""
-msgid "%d vulnerability updated"
-msgid_plural "%d vulnerabilities updated"
+msgid "%d vulnerability set to confirmed"
+msgid_plural "%d vulnerabilities set to confirmed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to dismissed"
+msgid_plural "%d vulnerabilities set to dismissed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to needs triage"
+msgid_plural "%d vulnerabilities set to needs triage"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to resolved"
+msgid_plural "%d vulnerabilities set to resolved"
msgstr[0] ""
msgstr[1] ""
@@ -510,6 +530,12 @@ msgstr[1] ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{completed} of %{total} issues closed"
+msgstr ""
+
+msgid "%{completed} of %{total} weight completed"
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -858,6 +884,9 @@ msgstr ""
msgid "%{openedIssues} open, %{closedIssues} closed"
msgstr ""
+msgid "%{percentage}%% issues closed"
+msgstr ""
+
msgid "%{percentage}%% weight completed"
msgstr ""
@@ -1287,6 +1316,9 @@ msgid_plural "- Users"
msgstr[0] ""
msgstr[1] ""
+msgid "- of - issues closed"
+msgstr ""
+
msgid "- of - weight completed"
msgstr ""
@@ -1429,7 +1461,7 @@ msgstr ""
msgid "1000+"
msgstr ""
-msgid "192.168.0.0/24"
+msgid "192.168.0.0/24 or 2001:0DB8:1234::/48"
msgstr ""
msgid "1st contribution!"
@@ -1741,13 +1773,13 @@ msgstr ""
msgid "AWS Access Key"
msgstr ""
-msgid "AWS Access Key. Only required if not using role instance credentials"
+msgid "AWS Secret Access Key"
msgstr ""
-msgid "AWS Secret Access Key"
+msgid "AWS access key ID (Optional)"
msgstr ""
-msgid "AWS Secret Access Key. Only required if not using role instance credentials"
+msgid "AWS secret access key (Optional)"
msgstr ""
msgid "AWS service error: %{error}"
@@ -1807,9 +1839,6 @@ msgstr ""
msgid "Access granted"
msgstr ""
-msgid "Access key ID"
-msgstr ""
-
msgid "Access requests"
msgstr ""
@@ -1984,7 +2013,7 @@ msgstr ""
msgid "Activity"
msgstr ""
-msgid "Activity|An error occured while retrieving activity. Reload the page to try again."
+msgid "Activity|An error occurred while retrieving activity. Reload the page to try again."
msgstr ""
msgid "Add"
@@ -2023,6 +2052,9 @@ msgstr ""
msgid "Add a %{type}"
msgstr ""
+msgid "Add a GCP region"
+msgstr ""
+
msgid "Add a GPG key"
msgstr ""
@@ -2074,6 +2106,9 @@ msgstr ""
msgid "Add a numbered list"
msgstr ""
+msgid "Add a related epic"
+msgstr ""
+
msgid "Add a related issue"
msgstr ""
@@ -2188,6 +2223,9 @@ msgstr ""
msgid "Add or subtract spent time"
msgstr ""
+msgid "Add people"
+msgstr ""
+
msgid "Add previously merged commits"
msgstr ""
@@ -2254,6 +2292,9 @@ msgstr ""
msgid "Add webhook"
msgstr ""
+msgid "Add your team members and others to GitLab."
+msgstr ""
+
msgid "Add/remove"
msgstr ""
@@ -3076,12 +3117,6 @@ msgstr ""
msgid "AdvancedSearch|Reindex required"
msgstr ""
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. Permanently deleting this project will %{strongStart}immediately delete%{strongEnd} its repositories and %{strongStart}all related resources%{strongEnd}, including issues, merge requests etc."
-msgstr ""
-
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. You will lose this project's repository and %{strongStart}all related resources%{strongEnd}, including issues and merge requests."
-msgstr ""
-
msgid "After a successful password update you will be redirected to login screen."
msgstr ""
@@ -3112,6 +3147,9 @@ msgstr ""
msgid "Akismet helps prevent the creation of spam issues in public projects."
msgstr ""
+msgid "Alert"
+msgstr ""
+
msgid "AlertManagement|Acknowledged"
msgstr ""
@@ -3484,9 +3522,6 @@ msgstr ""
msgid "All environments"
msgstr ""
-msgid "All epics"
-msgstr ""
-
msgid "All groups and projects"
msgstr ""
@@ -4223,12 +4258,15 @@ msgstr ""
msgid "ApplicationSettings|Approve users in the pending approval status?"
msgstr ""
-msgid "ApplicationSettings|By making this change, you will automatically approve %d user with the pending approval status."
-msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users with the pending approval status."
+msgid "ApplicationSettings|Approve users who are pending approval?"
+msgstr ""
+
+msgid "ApplicationSettings|By making this change, you will automatically approve %d user who is pending approval."
+msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users who are pending approval."
msgstr[0] ""
msgstr[1] ""
-msgid "ApplicationSettings|By making this change, you will automatically approve all users in pending approval status."
+msgid "ApplicationSettings|By making this change, you will automatically approve all users who are pending approval."
msgstr ""
msgid "ApplicationSettings|Denied domains for sign-ups"
@@ -4634,10 +4672,10 @@ msgstr ""
msgid "Archiving the project will make it entirely read-only. It is hidden from the dashboard and doesn't show up in searches. %{strong_start}The repository cannot be committed to, and no issues, comments, or other entities can be created.%{strong_end} %{link_start}Learn more.%{link_end}"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to delete this project?"
+msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
+msgid "Are you absolutely sure?"
msgstr ""
msgid "Are you sure that you want to archive this project?"
@@ -4673,12 +4711,18 @@ msgstr ""
msgid "Are you sure you want to delete this SSH key?"
msgstr ""
+msgid "Are you sure you want to delete this comment?"
+msgstr ""
+
msgid "Are you sure you want to delete this deploy key?"
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 label?"
+msgstr ""
+
msgid "Are you sure you want to delete this pipeline schedule?"
msgstr ""
@@ -4694,9 +4738,6 @@ msgstr ""
msgid "Are you sure you want to discard your changes?"
msgstr ""
-msgid "Are you sure you want to erase this build?"
-msgstr ""
-
msgid "Are you sure you want to import %d repository?"
msgid_plural "Are you sure you want to import %d repositories?"
msgstr[0] ""
@@ -4744,6 +4785,9 @@ msgstr ""
msgid "Are you sure you want to remove this list?"
msgstr ""
+msgid "Are you sure you want to remove this nickname?"
+msgstr ""
+
msgid "Are you sure you want to reset the health check token?"
msgstr ""
@@ -4756,10 +4800,10 @@ 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?"
+msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
msgstr ""
-msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
+msgid "Are you sure you want to revoke this project access token? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to stop this environment?"
@@ -4906,9 +4950,6 @@ msgstr ""
msgid "Assigned to %{assignee_name}"
msgstr ""
-msgid "Assigned to %{name}"
-msgstr ""
-
msgid "Assigned to me"
msgstr ""
@@ -4973,6 +5014,9 @@ msgstr[1] ""
msgid "Attaching the file failed."
msgstr ""
+msgid "Attention"
+msgstr ""
+
msgid "Audit Events"
msgstr ""
@@ -5135,6 +5179,12 @@ msgstr ""
msgid "Authorized applications (%{size})"
msgstr ""
+msgid "AuthorizedApplication|Are you sure you want to revoke this application?"
+msgstr ""
+
+msgid "AuthorizedApplication|Revoke application"
+msgstr ""
+
msgid "Authors: %{authors}"
msgstr ""
@@ -6328,6 +6378,9 @@ msgstr ""
msgid "CICDAnalytics|Shared Runners Usage"
msgstr ""
+msgid "CICDAnalytics|Shared runner pipeline minute duration by month"
+msgstr ""
+
msgid "CICDAnalytics|Shared runner usage"
msgstr ""
@@ -6469,6 +6522,9 @@ msgstr ""
msgid "Can create groups:"
msgstr ""
+msgid "Can not delete primary training"
+msgstr ""
+
msgid "Can't apply as the source branch was deleted."
msgstr ""
@@ -6802,9 +6858,6 @@ msgstr ""
msgid "Changing any setting here requires an application restart"
msgstr ""
-msgid "Changing group URL can have unintended side effects."
-msgstr ""
-
msgid "Charts can't be displayed as the request for data has timed out. %{documentationLink}"
msgstr ""
@@ -6892,9 +6945,6 @@ msgstr ""
msgid "Checking branch availability..."
msgstr ""
-msgid "Checking group URL availability..."
-msgstr ""
-
msgid "Checking group path availability..."
msgstr ""
@@ -7388,6 +7438,9 @@ msgstr ""
msgid "Clear recent searches"
msgstr ""
+msgid "Clear repository checks"
+msgstr ""
+
msgid "Clear search"
msgstr ""
@@ -7520,9 +7573,6 @@ msgstr ""
msgid "Closed MRs"
msgstr ""
-msgid "Closed epics"
-msgstr ""
-
msgid "Closed issues"
msgstr ""
@@ -7559,13 +7609,13 @@ msgstr ""
msgid "Cluster level"
msgstr ""
-msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
+msgid "Cluster type must be specified for Stages::ClusterEndpointInserter"
msgstr ""
msgid "ClusterAgents|%{name} successfully deleted"
msgstr ""
-msgid "ClusterAgents|%{number} of %{total} Agents"
+msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
@@ -7607,6 +7657,15 @@ msgstr ""
msgid "ClusterAgents|Agent never connected to GitLab"
msgstr ""
+msgid "ClusterAgents|Agent version mismatch"
+msgstr ""
+
+msgid "ClusterAgents|Agent version mismatch and update"
+msgstr ""
+
+msgid "ClusterAgents|Agent version update required"
+msgstr ""
+
msgid "ClusterAgents|All"
msgstr ""
@@ -7631,7 +7690,7 @@ msgstr ""
msgid "ClusterAgents|Configuration"
msgstr ""
-msgid "ClusterAgents|Connect a cluster through the Agent"
+msgid "ClusterAgents|Connect a cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connect existing cluster"
@@ -7640,13 +7699,13 @@ msgstr ""
msgid "ClusterAgents|Connect with a certificate"
msgstr ""
-msgid "ClusterAgents|Connect with agent"
+msgid "ClusterAgents|Connect with an agent"
msgstr ""
msgid "ClusterAgents|Connect with the GitLab Agent"
msgstr ""
-msgid "ClusterAgents|Connect your cluster through the Agent"
+msgid "ClusterAgents|Connect your cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connected"
@@ -7706,7 +7765,10 @@ msgstr ""
msgid "ClusterAgents|How to register an agent?"
msgstr ""
-msgid "ClusterAgents|Install new Agent"
+msgid "ClusterAgents|How to update an agent?"
+msgstr ""
+
+msgid "ClusterAgents|Install a new agent"
msgstr ""
msgid "ClusterAgents|Last connected %{timeAgo}."
@@ -7733,7 +7795,7 @@ msgstr ""
msgid "ClusterAgents|Never connected"
msgstr ""
-msgid "ClusterAgents|No Agents"
+msgid "ClusterAgents|No agents"
msgstr ""
msgid "ClusterAgents|No clusters connected through cluster certificates"
@@ -7793,6 +7855,9 @@ msgstr ""
msgid "ClusterAgents|The agent has not been connected in a long time. There might be a connectivity issue. Last contact was %{timeAgo}."
msgstr ""
+msgid "ClusterAgents|The agent version do not match each other across your cluster's pods. This can happen when a new agent version was just deployed and Kubernetes is shutting down the old pods."
+msgstr ""
+
msgid "ClusterAgents|The recommended installation method includes the token. If you want to follow the advanced installation method provided in the docs, make sure you save the token value before you close this window."
msgstr ""
@@ -7840,6 +7905,9 @@ msgstr ""
msgid "ClusterAgents|You will need to create a token to connect to your agent"
msgstr ""
+msgid "ClusterAgents|Your agent version is out of sync with your GitLab version (v%{version}), which might cause compatibility problems. Update the agent installed on your cluster to the most recent version."
+msgstr ""
+
msgid "ClusterAgents|Your instance doesn't have the %{linkStart}GitLab Agent Server (KAS)%{linkEnd} set up. Ask a GitLab Administrator to install it."
msgstr ""
@@ -8716,9 +8784,6 @@ msgstr ""
msgid "Comma-separated list of email addresses."
msgstr ""
-msgid "Comma-separated list of users allowed to exceed the rate limit."
-msgstr ""
-
msgid "Comma-separated, e.g. '1.1.1.1, 2.2.2.0/24'"
msgstr ""
@@ -9045,6 +9110,12 @@ msgstr ""
msgid "Confidential"
msgstr ""
+msgid "Confidential issue"
+msgstr ""
+
+msgid "Confidential note"
+msgstr ""
+
msgid "Confidentiality"
msgstr ""
@@ -9078,6 +9149,9 @@ msgstr ""
msgid "Configure Dependency Scanning in `.gitlab-ci.yml`, creating this file if it does not already exist"
msgstr ""
+msgid "Configure GitLab"
+msgstr ""
+
msgid "Configure GitLab runners to start using the Web Terminal. %{helpStart}Learn more.%{helpEnd}"
msgstr ""
@@ -9126,6 +9200,15 @@ msgstr ""
msgid "Configure pipelines to deploy web apps, backend services, APIs and static resources to Google Cloud"
msgstr ""
+msgid "Configure region"
+msgstr ""
+
+msgid "Configure region for environment"
+msgstr ""
+
+msgid "Configure regions"
+msgstr ""
+
msgid "Configure repository mirroring."
msgstr ""
@@ -9159,6 +9242,9 @@ msgstr ""
msgid "Configure which lists are shown for anyone who visits this board"
msgstr ""
+msgid "Configure your environments to be deployed to specific geographical regions"
+msgstr ""
+
msgid "Confirm"
msgstr ""
@@ -9861,10 +9947,10 @@ msgstr ""
msgid "CorpusManagement|Actions"
msgstr ""
-msgid "CorpusManagement|Corpus are used in fuzz testing as mutation source to Improve future testing."
+msgid "CorpusManagement|Corpus file"
msgstr ""
-msgid "CorpusManagement|Corpus file"
+msgid "CorpusManagement|Corpus files are used in coverage-guided fuzz testing as seed inputs to improve testing."
msgstr ""
msgid "CorpusManagement|Corpus files must be in *.zip format. Maximum 5 GB"
@@ -9918,6 +10004,9 @@ msgstr ""
msgid "Could not apply %{name} command."
msgstr ""
+msgid "Could not apply %{name} command. %{message}."
+msgstr ""
+
msgid "Could not authorize chat nickname. Try again!"
msgstr ""
@@ -10068,6 +10157,9 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
+msgid "Create a group"
+msgstr ""
+
msgid "Create a merge request"
msgstr ""
@@ -10092,6 +10184,9 @@ msgstr ""
msgid "Create a personal access token on your account to pull or push via %{protocol}."
msgstr ""
+msgid "Create a project"
+msgstr ""
+
msgid "Create an account using:"
msgstr ""
@@ -10455,6 +10550,9 @@ msgstr ""
msgid "Creation date"
msgstr ""
+msgid "Creator"
+msgstr ""
+
msgid "Credentials"
msgstr ""
@@ -10467,9 +10565,15 @@ msgstr ""
msgid "CredentialsInventory|Personal Access Tokens"
msgstr ""
+msgid "CredentialsInventory|Project Access Tokens"
+msgstr ""
+
msgid "CredentialsInventory|SSH Keys"
msgstr ""
+msgid "Credit card required to be on file in order to create a pipeline"
+msgstr ""
+
msgid "Credit card:"
msgstr ""
@@ -10653,9 +10757,6 @@ msgstr ""
msgid "Customer relations"
msgstr ""
-msgid "Customizable by an administrator."
-msgstr ""
-
msgid "Customizable by owners."
msgstr ""
@@ -10785,30 +10886,18 @@ msgstr ""
msgid "CycleAnalytics|%{selectedLabelsCount} selected (%{maxLabels} max)"
msgstr ""
-msgid "CycleAnalytics|%{stageCount} stages selected"
-msgstr ""
-
-msgid "CycleAnalytics|All stages"
-msgstr ""
-
-msgid "CycleAnalytics|Average days to completion"
+msgid "CycleAnalytics|Average time to completion"
msgstr ""
msgid "CycleAnalytics|Date"
msgstr ""
-msgid "CycleAnalytics|Days to completion"
-msgstr ""
-
msgid "CycleAnalytics|Display chart filters"
msgstr ""
msgid "CycleAnalytics|Lead Time for Changes"
msgstr ""
-msgid "CycleAnalytics|No stages selected"
-msgstr ""
-
msgid "CycleAnalytics|Number of tasks"
msgstr ""
@@ -10837,18 +10926,30 @@ msgstr ""
msgid "CycleAnalytics|Showing data for group '%{groupName}' from %{createdAfter} to %{createdBefore}"
msgstr ""
-msgid "CycleAnalytics|Stages"
+msgid "CycleAnalytics|Stage time: %{title}"
msgstr ""
msgid "CycleAnalytics|Tasks by type"
msgstr ""
-msgid "CycleAnalytics|The average time spent in the selected stage for the items that were completed on each date. Data limited to the last 500 items."
+msgid "CycleAnalytics|The average time items spent in this stage. Data limited to items completed within this date range."
msgstr ""
msgid "CycleAnalytics|The given date range is larger than 180 days"
msgstr ""
+msgid "CycleAnalytics|The total time items spent across each value stream stage. Data limited to items completed within this date range."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Stage time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Total time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|Total time"
+msgstr ""
+
msgid "CycleAnalytics|Type of work"
msgstr ""
@@ -10861,9 +10962,6 @@ msgstr ""
msgid "CycleAnalytics|project dropdown filter"
msgstr ""
-msgid "CycleAnalytics|stage dropdown"
-msgstr ""
-
msgid "DAG visualization requires at least 3 dependent jobs."
msgstr ""
@@ -10963,10 +11061,16 @@ msgstr ""
msgid "DastProfiles|AJAX spider"
msgstr ""
+msgid "DastProfiles|API"
+msgstr ""
+
+msgid "DastProfiles|API endpoint URL"
+msgstr ""
+
msgid "DastProfiles|Active"
msgstr ""
-msgid "DastProfiles|Additional request headers (Optional)"
+msgid "DastProfiles|Additional request headers (optional)"
msgstr ""
msgid "DastProfiles|Are you sure you want to delete this profile?"
@@ -10981,6 +11085,9 @@ msgstr ""
msgid "DastProfiles|Branch missing"
msgstr ""
+msgid "DastProfiles|Choose a scan method"
+msgstr ""
+
msgid "DastProfiles|Could not create the scanner profile. Please try again."
msgstr ""
@@ -11050,7 +11157,13 @@ msgstr ""
msgid "DastProfiles|Excluded URLs"
msgstr ""
-msgid "DastProfiles|Excluded URLs (Optional)"
+msgid "DastProfiles|Excluded URLs (optional)"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths (optional)"
msgstr ""
msgid "DastProfiles|Hide debug messages"
@@ -11107,9 +11220,6 @@ msgstr ""
msgid "DastProfiles|Request headers"
msgstr ""
-msgid "DastProfiles|Rest API"
-msgstr ""
-
msgid "DastProfiles|Run the AJAX spider, in addition to the traditional spider, to crawl the target site."
msgstr ""
@@ -11119,6 +11229,9 @@ msgstr ""
msgid "DastProfiles|Save profile"
msgstr ""
+msgid "DastProfiles|Scan method"
+msgstr ""
+
msgid "DastProfiles|Scan mode"
msgstr ""
@@ -11197,12 +11310,24 @@ msgstr ""
msgid "DastProfiles|Website"
msgstr ""
+msgid "DastProfiles|What does each method do?"
+msgstr ""
+
msgid "DastProfiles|You can either choose a passive scan or validate the target site from the site profile management page. %{docsLinkStart}Learn more about site validation.%{docsLinkEnd}"
msgstr ""
msgid "DastProfiles|You cannot run an active scan against an unvalidated site."
msgstr ""
+msgid "DastProfiles|folder/dast_example.har or https://example.com/dast_example.har"
+msgstr ""
+
+msgid "DastProfiles|folder/example.postman_collection.json or https://example.com/"
+msgstr ""
+
+msgid "DastProfiles|folder/openapi.json or https://example.com/openapi.json"
+msgstr ""
+
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
@@ -11310,6 +11435,9 @@ msgstr ""
msgid "DatadogIntegration|API URL"
msgstr ""
+msgid "DatadogIntegration|Custom tags in Datadog. Enter one tag per line in the %{codeOpen}key:value%{codeClose} format. %{linkOpen}How do I use tags?%{linkClose}"
+msgstr ""
+
msgid "DatadogIntegration|Environment"
msgstr ""
@@ -11328,12 +11456,18 @@ msgstr ""
msgid "DatadogIntegration|Tag all data from this GitLab instance in Datadog. Useful when managing several self-managed deployments."
msgstr ""
+msgid "DatadogIntegration|Tags"
+msgstr ""
+
msgid "DatadogIntegration|The Datadog site to send data to. To send data to the EU site, use %{codeOpen}datadoghq.eu%{codeClose}."
msgstr ""
msgid "DatadogIntegration|Trace your GitLab pipelines with Datadog."
msgstr ""
+msgid "DatadogIntegration|have an invalid format"
+msgstr ""
+
msgid "Datasource name not found"
msgstr ""
@@ -11343,9 +11477,6 @@ msgstr ""
msgid "Date merged"
msgstr ""
-msgid "Date picker"
-msgstr ""
-
msgid "Date range"
msgstr ""
@@ -11499,9 +11630,6 @@ msgstr ""
msgid "Definition"
msgstr ""
-msgid "Delayed Project Deletion (%{adjourned_deletion})"
-msgstr ""
-
msgid "DelayedJobs|Are you sure you want to run %{jobName} immediately? Otherwise this job will run automatically after its timer finishes."
msgstr ""
@@ -11580,10 +11708,10 @@ msgstr ""
msgid "Delete pipeline"
msgstr ""
-msgid "Delete project"
+msgid "Delete pipeline schedule"
msgstr ""
-msgid "Delete project. Are you ABSOLUTELY SURE?"
+msgid "Delete project"
msgstr ""
msgid "Delete row"
@@ -11613,6 +11741,9 @@ msgstr ""
msgid "Delete this epic and all descendants?"
msgstr ""
+msgid "Delete this project"
+msgstr ""
+
msgid "Delete user list"
msgstr ""
@@ -11871,6 +12002,12 @@ msgstr ""
msgid "Deploy to..."
msgstr ""
+msgid "DeployBoards|To see deployment progress for your environments, make sure you are deploying to %{codeStart}$KUBE_NAMESPACE%{codeEnd} and annotating with %{codeStart}app.gitlab.com/app=$CI_PROJECT_PATH_SLUG%{codeEnd} and %{codeStart}app.gitlab.com/env=$CI_ENVIRONMENT_SLUG%{codeEnd}."
+msgstr ""
+
+msgid "DeployBoard|Kubernetes Pods"
+msgstr ""
+
msgid "DeployFreeze|Add a freeze period to prevent unintended releases during a period of time for a given environment. You must update the deployment jobs in %{filename} according to the deploy freezes added here. %{freeze_period_link_start}Learn more.%{freeze_period_link_end}"
msgstr ""
@@ -11955,9 +12092,6 @@ msgstr ""
msgid "DeployTokens|Active Deploy Tokens (%{active_tokens})"
msgstr ""
-msgid "DeployTokens|Allows read and write access to registry images."
-msgstr ""
-
msgid "DeployTokens|Allows read and write access to the package registry."
msgstr ""
@@ -11970,6 +12104,9 @@ msgstr ""
msgid "DeployTokens|Allows read-only access to the repository."
msgstr ""
+msgid "DeployTokens|Allows write access to registry images."
+msgstr ""
+
msgid "DeployTokens|Copy deploy token"
msgstr ""
@@ -12063,12 +12200,57 @@ msgstr ""
msgid "Deploying to AWS is easy with GitLab"
msgstr ""
+msgid "Deployment"
+msgstr ""
+
msgid "Deployment Frequency"
msgstr ""
+msgid "Deployment Target|Project deployment target (optional)"
+msgstr ""
+
+msgid "Deployment Target|Select the deployment target"
+msgstr ""
+
msgid "Deployment frequency"
msgstr ""
+msgid "DeploymentTarget|GitLab Pages"
+msgstr ""
+
+msgid "DeploymentTarget|Heroku"
+msgstr ""
+
+msgid "DeploymentTarget|Infrastructure provider (Terraform, Cloudformation, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Kubernetes (GKE, EKS, OpenShift, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Managed container runtime (Fargate, Cloud Run, DigitalOcean App)"
+msgstr ""
+
+msgid "DeploymentTarget|Mobile app store"
+msgstr ""
+
+msgid "DeploymentTarget|No deployment planned"
+msgstr ""
+
+msgid "DeploymentTarget|Other hosting service"
+msgstr ""
+
+msgid "DeploymentTarget|Registry (package or container)"
+msgstr ""
+
+msgid "DeploymentTarget|Self-managed container runtime (Podman, Docker Swarm, Docker Compose)"
+msgstr ""
+
+msgid "DeploymentTarget|Serverless backend (Lambda, Cloud functions)"
+msgstr ""
+
+msgid "DeploymentTarget|Virtual machine (for example, EC2)"
+msgstr ""
+
msgid "Deployments"
msgstr ""
@@ -12107,6 +12289,9 @@ msgstr ""
msgid "Deployment|This deployment was created using the API"
msgstr ""
+msgid "Deployment|Triggerer"
+msgstr ""
+
msgid "Deployment|Waiting"
msgstr ""
@@ -12134,6 +12319,18 @@ msgstr ""
msgid "Deprecated API rate limits"
msgstr ""
+msgid "Deprecations|Feature deprecation and removal"
+msgstr ""
+
+msgid "Deprecations|For information on a possible replacement %{epicStart} learn more about Opstrace %{epicEnd}."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7 and are %{epicStart} scheduled for removal %{epicEnd} in GitLab 15.0."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7, and are %{removal_link_start} scheduled for removal %{link_end} in GitLab 15.0. For information on a possible replacement, %{opstrace_link_start} learn more about Opstrace %{link_end}."
+msgstr ""
+
msgid "Deprioritize label"
msgstr ""
@@ -12379,10 +12576,10 @@ msgstr ""
msgid "DevopsAdoption|At least one deploy"
msgstr ""
-msgid "DevopsAdoption|At least one issue opened"
+msgid "DevopsAdoption|At least one issue created"
msgstr ""
-msgid "DevopsAdoption|At least one merge request opened"
+msgid "DevopsAdoption|At least one merge request created"
msgstr ""
msgid "DevopsAdoption|At least one pipeline successfully run"
@@ -12583,6 +12780,9 @@ msgstr ""
msgid "Direct member"
msgstr ""
+msgid "Direct members"
+msgstr ""
+
msgid "Direct non-authenticated users to this page."
msgstr ""
@@ -12699,6 +12899,9 @@ msgid_plural "Dismiss %d selected vulnerabilities as"
msgstr[0] ""
msgstr[1] ""
+msgid "Dismiss Alert"
+msgstr ""
+
msgid "Dismiss merge request promotion"
msgstr ""
@@ -12726,9 +12929,15 @@ msgstr ""
msgid "Display alerts from all configured monitoring tools."
msgstr ""
+msgid "Display milestones"
+msgstr ""
+
msgid "Display name"
msgstr ""
+msgid "Display progress of child issues"
+msgstr ""
+
msgid "Display rendered file"
msgstr ""
@@ -12834,6 +13043,9 @@ msgstr ""
msgid "Download image"
msgstr ""
+msgid "Download payload"
+msgstr ""
+
msgid "Download raw data (.csv)"
msgstr ""
@@ -13011,6 +13223,9 @@ msgstr ""
msgid "Edit in Web IDE"
msgstr ""
+msgid "Edit in pipeline editor"
+msgstr ""
+
msgid "Edit in single-file editor"
msgstr ""
@@ -13053,6 +13268,9 @@ msgstr ""
msgid "Edit your most recent comment in a thread (from an empty textarea)"
msgstr ""
+msgid "Edit, lint, and visualize your pipeline."
+msgstr ""
+
msgid "Edited"
msgstr ""
@@ -13494,6 +13712,9 @@ msgstr ""
msgid "Enforce two-factor authentication for all user sign-ins."
msgstr ""
+msgid "Enhance security by storing service account keys in secret managers - learn more about %{docLinkStart}secret management with GitLab%{docLinkEnd}"
+msgstr ""
+
msgid "Ensure connectivity is available from the GitLab server to the Prometheus server"
msgstr ""
@@ -13554,6 +13775,9 @@ 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 following to confirm:"
+msgstr ""
+
msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
@@ -14084,9 +14308,6 @@ 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 ""
@@ -14222,6 +14443,9 @@ msgstr ""
msgid "Errors:"
msgstr ""
+msgid "Escalate this incident"
+msgstr ""
+
msgid "Escalation Policies"
msgstr ""
@@ -14234,6 +14458,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy"
+msgstr ""
+
msgid "Escalation policy:"
msgstr ""
@@ -14485,6 +14712,9 @@ msgstr ""
msgid "Existing sign in methods may be removed"
msgstr ""
+msgid "Exit."
+msgstr ""
+
msgid "Expand"
msgstr ""
@@ -14581,6 +14811,9 @@ msgstr ""
msgid "Explore public groups"
msgstr ""
+msgid "Explore public projects"
+msgstr ""
+
msgid "Explore snippets"
msgstr ""
@@ -14742,7 +14975,7 @@ msgid_plural "Failed to archive designs. Please try again."
msgstr[0] ""
msgstr[1] ""
-msgid "Failed to assign a reviewer because no user was found."
+msgid "Failed to assign a reviewer because no user was specified."
msgstr ""
msgid "Failed to assign a user because no user was found."
@@ -14808,10 +15041,10 @@ msgstr ""
msgid "Failed to find import label for Jira import."
msgstr ""
-msgid "Failed to generate export, please try again later."
+msgid "Failed to find users for %{missing}"
msgstr ""
-msgid "Failed to generate report, please try again after sometime"
+msgid "Failed to generate export, please try again later."
msgstr ""
msgid "Failed to get ref."
@@ -14910,6 +15143,9 @@ msgstr ""
msgid "Failed to remove a to-do item for the design."
msgstr ""
+msgid "Failed to remove attention because no user was found."
+msgstr ""
+
msgid "Failed to remove mirror."
msgstr ""
@@ -14922,6 +15158,9 @@ msgstr ""
msgid "Failed to remove user key."
msgstr ""
+msgid "Failed to request attention because no user was found."
+msgstr ""
+
msgid "Failed to reset key. Please try again."
msgstr ""
@@ -15003,6 +15242,9 @@ msgstr ""
msgid "Feature Flags"
msgstr ""
+msgid "Feature deprecation and removal"
+msgstr ""
+
msgid "Feature flag status"
msgstr ""
@@ -15500,7 +15742,7 @@ msgstr ""
msgid "For each job, re-use the project workspace. If the workspace doesn't exist, use %{code_open}git clone%{code_close}."
msgstr ""
-msgid "For example, the application using the token or the purpose of the token."
+msgid "For example, the application using the token or the purpose of the token. Do not give sensitive information for the name of the token, as it will be visible to all %{resource_type} members."
msgstr ""
msgid "For files larger than this limit, only index the file name. The file content is neither indexed nor searchable."
@@ -15584,9 +15826,6 @@ msgstr ""
msgid "ForkProject|Select a namespace"
msgstr ""
-msgid "ForkProject|Select a namespace to fork the project"
-msgstr ""
-
msgid "ForkProject|The project can be accessed by any logged in user."
msgstr ""
@@ -15683,6 +15922,9 @@ msgstr ""
msgid "Full name"
msgstr ""
+msgid "GCP region configured"
+msgstr ""
+
msgid "GPG Key ID:"
msgstr ""
@@ -15863,6 +16105,9 @@ msgstr ""
msgid "Geo|Failed"
msgstr ""
+msgid "Geo|Filter Geo sites"
+msgstr ""
+
msgid "Geo|Filter by name"
msgstr ""
@@ -16274,6 +16519,12 @@ msgstr ""
msgid "GitLab Issue"
msgstr ""
+msgid "GitLab KAS"
+msgstr ""
+
+msgid "GitLab Memberships CSV Export"
+msgstr ""
+
msgid "GitLab Pages"
msgstr ""
@@ -16322,6 +16573,9 @@ 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 free to use. Many features for larger teams are part of our %{link_start}paid products%{link_end}. You can try Ultimate for free without any obligation or payment details."
+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 ""
@@ -16448,7 +16702,7 @@ msgstr ""
msgid "GitLabPages|When enabled, all attempts to visit your website through HTTP are automatically redirected to HTTPS using a response with status code 301. Requires a valid certificate for all domains. %{docs_link_start}Learn more.%{link_end}"
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. %{docs_link_start}Learn more.%{link_end}"
+msgid "GitLabPages|When using Pages under the general domain of a GitLab instance (%{pages_host}), you cannot use HTTPS with subdomains of subdomains. If your namespace or groupname contains a dot, it does not work. This is a limitation of the HTTP Over TLS protocol. HTTP pages work if you don't redirect HTTP to HTTPS. %{docs_link_start}Learn more.%{link_end}"
msgstr ""
msgid "GitLabPages|With GitLab Pages you can host your static website directly from your GitLab repository. %{docs_link_start}Learn more.%{link_end}"
@@ -16625,9 +16879,6 @@ msgstr ""
msgid "Go to find file"
msgstr ""
-msgid "Go to fork"
-msgstr ""
-
msgid "Go to issue boards"
msgstr ""
@@ -16835,9 +17086,6 @@ msgstr ""
msgid "Group Hooks"
msgstr ""
-msgid "Group ID"
-msgstr ""
-
msgid "Group Owner must have signed in with SAML before enabling Group Managed Accounts"
msgstr ""
@@ -16865,9 +17113,6 @@ msgstr ""
msgid "Group by"
msgstr ""
-msgid "Group description"
-msgstr ""
-
msgid "Group description (optional)"
msgstr ""
@@ -16982,7 +17227,7 @@ msgstr ""
msgid "Group: %{name}"
msgstr ""
-msgid "GroupActivityMetrics|Issues opened"
+msgid "GroupActivityMetrics|Issues created"
msgstr ""
msgid "GroupActivityMetrics|Last 90 days"
@@ -16991,7 +17236,7 @@ msgstr ""
msgid "GroupActivityMetrics|Members added"
msgstr ""
-msgid "GroupActivityMetrics|Merge Requests opened"
+msgid "GroupActivityMetrics|Merge Requests created"
msgstr ""
msgid "GroupActivityMetrics|Recent activity"
@@ -17282,6 +17527,9 @@ msgstr ""
msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
+msgid "GroupSettings|Choose a group path that does not start with a dash or end with a period. It can also contain alphanumeric characters and underscores."
+msgstr ""
+
msgid "GroupSettings|Compliance frameworks"
msgstr ""
@@ -17315,7 +17563,7 @@ msgstr ""
msgid "GroupSettings|If not specified at the group or instance level, the default is %{default_initial_branch_name}. Does not affect existing repositories."
msgstr ""
-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."
+msgid "GroupSettings|If the parent group's visibility is lower than the group's current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility."
msgstr ""
msgid "GroupSettings|New runners registration token has been generated!"
@@ -17432,7 +17680,10 @@ msgstr ""
msgid "Groups and projects"
msgstr ""
-msgid "Groups and subgroups"
+msgid "Groups are a great way to organize projects and people."
+msgstr ""
+
+msgid "Groups are the best way to manage projects and members."
msgstr ""
msgid "Groups to synchronize"
@@ -17543,13 +17794,16 @@ msgstr ""
msgid "GroupsTree|Are you sure you want to leave the \"%{fullName}\" group?"
msgstr ""
-msgid "GroupsTree|Edit group"
+msgid "GroupsTree|Delete"
+msgstr ""
+
+msgid "GroupsTree|Edit"
msgstr ""
msgid "GroupsTree|Failed to leave the group. Please make sure you are not the only owner."
msgstr ""
-msgid "GroupsTree|Leave this group"
+msgid "GroupsTree|Leave group"
msgstr ""
msgid "GroupsTree|Loading groups"
@@ -17561,9 +17815,57 @@ msgstr ""
msgid "GroupsTree|No groups or projects matched your search"
msgstr ""
+msgid "GroupsTree|Options"
+msgstr ""
+
msgid "GroupsTree|Search by name"
msgstr ""
+msgid "Groups|Avatar will be removed. Are you sure?"
+msgstr ""
+
+msgid "Groups|Changing group URL can have unintended side effects."
+msgstr ""
+
+msgid "Groups|Checking group URL availability..."
+msgstr ""
+
+msgid "Groups|Enter a descriptive name for your group."
+msgstr ""
+
+msgid "Groups|Group ID"
+msgstr ""
+
+msgid "Groups|Group URL"
+msgstr ""
+
+msgid "Groups|Group avatar"
+msgstr ""
+
+msgid "Groups|Group description (optional)"
+msgstr ""
+
+msgid "Groups|Group name"
+msgstr ""
+
+msgid "Groups|Group path is available."
+msgstr ""
+
+msgid "Groups|Group path is unavailable. Path has been replaced with a suggested available path."
+msgstr ""
+
+msgid "Groups|Learn more"
+msgstr ""
+
+msgid "Groups|Must start with letter, digit, emoji, or underscore. Can also contain periods, dashes, spaces, and parentheses."
+msgstr ""
+
+msgid "Groups|Remove avatar"
+msgstr ""
+
+msgid "Groups|Save changes"
+msgstr ""
+
msgid "Guideline"
msgstr ""
@@ -17573,6 +17875,9 @@ msgstr ""
msgid "HAR file path or URL"
msgstr ""
+msgid "HTTP Archive (HAR)"
+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 ""
@@ -17973,6 +18278,9 @@ msgstr ""
msgid "INFO: Your SSH key is expiring soon. Please generate a new key."
msgstr ""
+msgid "IP"
+msgstr ""
+
msgid "IP Address"
msgstr ""
@@ -18009,6 +18317,9 @@ msgstr ""
msgid "IdentityVerification|Verify your identity"
msgstr ""
+msgid "IdentityVerification|You can always verify your account at a later time to create a group."
+msgstr ""
+
msgid "If any indexed field exceeds this limit, it is truncated to this number of characters. The rest of the content is neither indexed nor searchable. This does not apply to repository and wiki indexing. For unlimited characters, set this to 0."
msgstr ""
@@ -18066,6 +18377,9 @@ msgstr ""
msgid "If you add %{codeStart}needs%{codeEnd} to jobs in your pipeline you'll be able to view the %{codeStart}needs%{codeEnd} relationships between jobs in this tab as a %{linkStart}Directed Acyclic Graph (DAG)%{linkEnd}."
msgstr ""
+msgid "If you are added to a project, it will be displayed here."
+msgstr ""
+
msgid "If you did not initiate these sign-in attempts, please reach out to your administrator or enable two-factor authentication (2FA) on your account."
msgstr ""
@@ -18372,12 +18686,24 @@ msgstr ""
msgid "InProductMarketing|3 ways to dive into GitLab CI/CD"
msgstr ""
+msgid "InProductMarketing|A single application eliminates complex integrations, data chokepoints, and toolchain maintenance, resulting in greater productivity and lower cost."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features, build more efficiently, strengthen security and compliance."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features."
+msgstr ""
+
msgid "InProductMarketing|Actually, GitLab makes the team work (better)"
msgstr ""
msgid "InProductMarketing|And finally %{deploy_link} a Python application."
msgstr ""
+msgid "InProductMarketing|And many more..."
+msgstr ""
+
msgid "InProductMarketing|Are your runners ready?"
msgstr ""
@@ -18396,15 +18722,33 @@ msgstr ""
msgid "InProductMarketing|Blog"
msgstr ""
+msgid "InProductMarketing|Break down silos to coordinate seamlessly across development, operations, and security with a consistent experience across the development lifecycle."
+msgstr ""
+
+msgid "InProductMarketing|Burn up/down charts"
+msgstr ""
+
msgid "InProductMarketing|By enabling code owners and required merge approvals the right person will review the right MR. This is a win-win: cleaner code and a more efficient review process."
msgstr ""
msgid "InProductMarketing|Click on the number below that corresponds with your answer — 1 being very difficult, 5 being very easy."
msgstr ""
+msgid "InProductMarketing|Code owners"
+msgstr ""
+
msgid "InProductMarketing|Code owners and required merge approvals are part of the paid tiers of GitLab. You can start a free 30-day trial of GitLab Ultimate and enable these features in less than 5 minutes with no credit card required."
msgstr ""
+msgid "InProductMarketing|Code review analytics"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration across stages in GitLab"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration made easy"
+msgstr ""
+
msgid "InProductMarketing|Create a custom CI runner with just a few clicks"
msgstr ""
@@ -18414,12 +18758,21 @@ msgstr ""
msgid "InProductMarketing|Create a project in GitLab in 5 minutes"
msgstr ""
+msgid "InProductMarketing|Create well-defined workflows by using scoped labels on issues, merge requests, and epics. Labels with the same scope cannot be used together, which prevents conflicts."
+msgstr ""
+
msgid "InProductMarketing|Create your first project!"
msgstr ""
+msgid "InProductMarketing|Define who owns specific files or directories, so the right reviewers are suggested when a merge request introduces changes to those files."
+msgstr ""
+
msgid "InProductMarketing|Deliver Better Products Faster"
msgstr ""
+msgid "InProductMarketing|Dependency scanning"
+msgstr ""
+
msgid "InProductMarketing|Did you know teams that use GitLab are far more efficient?"
msgstr ""
@@ -18429,15 +18782,27 @@ msgstr ""
msgid "InProductMarketing|Dig in and create a project and a repo"
msgstr ""
+msgid "InProductMarketing|Discover Premium & Ultimate"
+msgstr ""
+
+msgid "InProductMarketing|Discover Premium & Ultimate."
+msgstr ""
+
msgid "InProductMarketing|Do you have a minute?"
msgstr ""
msgid "InProductMarketing|Do you have a teammate who would be perfect for this task?"
msgstr ""
+msgid "InProductMarketing|Dynamic application security testing"
+msgstr ""
+
msgid "InProductMarketing|Easy"
msgstr ""
+msgid "InProductMarketing|Epics"
+msgstr ""
+
msgid "InProductMarketing|Expand your DevOps journey with a free GitLab trial"
msgstr ""
@@ -18459,9 +18824,15 @@ msgstr ""
msgid "InProductMarketing|Feel the need for speed?"
msgstr ""
+msgid "InProductMarketing|Find and fix bottlenecks in your code review process by understanding how long open merge requests have been in review."
+msgstr ""
+
msgid "InProductMarketing|Find out how your teams are really doing"
msgstr ""
+msgid "InProductMarketing|Find out if your external libraries are safe. Run dependency scanning jobs that check for known vulnerabilities in your external libraries."
+msgstr ""
+
msgid "InProductMarketing|Follow our steps"
msgstr ""
@@ -18498,6 +18869,9 @@ msgstr ""
msgid "InProductMarketing|GitLab is better with teammates to help out!"
msgstr ""
+msgid "InProductMarketing|GitLab is infrastructure agnostic (supporting GCP, AWS, Azure, OpenShift, VMWare, On Prem, Bare Metal, and more), offering a consistent workflow experience – irrespective of the environment."
+msgstr ""
+
msgid "InProductMarketing|GitLab provides static application security testing (SAST), dynamic application security testing (DAST), container scanning, and dependency scanning to help you deliver secure applications along with license compliance."
msgstr ""
@@ -18588,21 +18962,36 @@ msgstr ""
msgid "InProductMarketing|It's also possible to simply %{external_repo_link} in order to take advantage of GitLab's CI/CD."
msgstr ""
+msgid "InProductMarketing|Keep your code quality high by defining who should approve merge requests and how many approvals are required."
+msgstr ""
+
msgid "InProductMarketing|Launch GitLab CI/CD in 20 minutes or less"
msgstr ""
+msgid "InProductMarketing|Lower cost of development"
+msgstr ""
+
+msgid "InProductMarketing|Make it easier to collaborate on high-level ideas by grouping related issues in an epic."
+msgstr ""
+
msgid "InProductMarketing|Making the switch? It's easier than you think to import your projects into GitLab. Move %{github_link}, or import something %{bitbucket_link}."
msgstr ""
msgid "InProductMarketing|Master the art of importing!"
msgstr ""
+msgid "InProductMarketing|Merge request approval rule"
+msgstr ""
+
msgid "InProductMarketing|Move on to easily creating a Pages website %{ci_template_link}"
msgstr ""
msgid "InProductMarketing|Multiple owners, confusing workstreams? We've got you covered"
msgstr ""
+msgid "InProductMarketing|Multiple required approvers"
+msgstr ""
+
msgid "InProductMarketing|Need an alternative to importing?"
msgstr ""
@@ -18615,18 +19004,33 @@ msgstr ""
msgid "InProductMarketing|Our tool brings all the things together"
msgstr ""
+msgid "InProductMarketing|Protect your web application by using DAST to examine for vulnerabilities in deployed environments."
+msgstr ""
+
msgid "InProductMarketing|Rapid development, simplified"
msgstr ""
msgid "InProductMarketing|Reduce Security & Compliance Risk"
msgstr ""
+msgid "InProductMarketing|Require multiple approvers on a merge request, so you know it's in good shape before it's merged."
+msgstr ""
+
+msgid "InProductMarketing|Roadmaps"
+msgstr ""
+
+msgid "InProductMarketing|Scoped labels"
+msgstr ""
+
msgid "InProductMarketing|Security that's integrated into your development lifecycle"
msgstr ""
msgid "InProductMarketing|Sometimes you're not ready to make a full transition to a new tool. If you're not ready to fully commit, %{mirroring_link} gives you a safe way to try out GitLab in parallel with your current tool."
msgstr ""
+msgid "InProductMarketing|Speed. Efficiency. Trust."
+msgstr ""
+
msgid "InProductMarketing|Spin up an autoscaling runner in GitLab"
msgstr ""
@@ -18636,6 +19040,9 @@ msgstr ""
msgid "InProductMarketing|Start a Self-Managed trial"
msgstr ""
+msgid "InProductMarketing|Start a free trial"
+msgstr ""
+
msgid "InProductMarketing|Start a free trial of GitLab Ultimate – no credit card required"
msgstr ""
@@ -18702,6 +19109,9 @@ msgstr ""
msgid "InProductMarketing|To understand and get the most out of GitLab, start at the beginning and %{project_link}. In GitLab, repositories are part of a project, so after you've created your project you can go ahead and %{repo_link}."
msgstr ""
+msgid "InProductMarketing|Track completed issues in a chart, so you can see how a milestone is progressing at a glance."
+msgstr ""
+
msgid "InProductMarketing|Try GitLab Ultimate for free"
msgstr ""
@@ -18738,6 +19148,9 @@ msgstr ""
msgid "InProductMarketing|Very easy"
msgstr ""
+msgid "InProductMarketing|Visualize your epics and milestones in a timeline."
+msgstr ""
+
msgid "InProductMarketing|Want to host GitLab on your servers?"
msgstr ""
@@ -18759,6 +19172,9 @@ msgstr ""
msgid "InProductMarketing|YouTube"
msgstr ""
+msgid "InProductMarketing|Your software, deployed your way"
+msgstr ""
+
msgid "InProductMarketing|Your teams can be more efficient"
msgstr ""
@@ -18879,9 +19295,18 @@ msgstr ""
msgid "IncidentManagement|No incidents to display."
msgstr ""
+msgid "IncidentManagement|None"
+msgstr ""
+
msgid "IncidentManagement|Open"
msgstr ""
+msgid "IncidentManagement|Page your team with escalation policies"
+msgstr ""
+
+msgid "IncidentManagement|Paged"
+msgstr ""
+
msgid "IncidentManagement|Published"
msgstr ""
@@ -18891,6 +19316,9 @@ msgstr ""
msgid "IncidentManagement|Severity"
msgstr ""
+msgid "IncidentManagement|Status"
+msgstr ""
+
msgid "IncidentManagement|There are no closed incidents"
msgstr ""
@@ -18909,6 +19337,9 @@ msgstr ""
msgid "IncidentManagement|Unpublished"
msgstr ""
+msgid "IncidentManagement|Use escalation policies to automatically page your team when incidents are created."
+msgstr ""
+
msgid "IncidentSettings|Activate \"time to SLA\" countdown timer"
msgstr ""
@@ -18954,7 +19385,10 @@ msgstr ""
msgid "Incidents"
msgstr ""
-msgid "Incidents|Add a URL"
+msgid "Incidents|Add image details"
+msgstr ""
+
+msgid "Incidents|Add text or a link to display with your image. If you don't add either, the file name displays instead."
msgstr ""
msgid "Incidents|Drop or %{linkStart}upload%{linkEnd} a metric screenshot to attach it to the incident"
@@ -18969,10 +19403,10 @@ msgstr ""
msgid "Incidents|There was an issue loading metric images."
msgstr ""
-msgid "Incidents|There was an issue uploading your image."
+msgid "Incidents|There was an issue updating your image."
msgstr ""
-msgid "Incidents|You can optionally add a URL to link users to the original graph."
+msgid "Incidents|There was an issue uploading your image."
msgstr ""
msgid "Incident|Alert details"
@@ -18981,9 +19415,18 @@ msgstr ""
msgid "Incident|Are you sure you wish to delete this image?"
msgstr ""
+msgid "Incident|Delete image"
+msgstr ""
+
msgid "Incident|Deleting %{filename}"
msgstr ""
+msgid "Incident|Edit image text or link"
+msgstr ""
+
+msgid "Incident|Editing %{filename}"
+msgstr ""
+
msgid "Incident|Metrics"
msgstr ""
@@ -19253,12 +19696,18 @@ msgstr ""
msgid "Integrations|Branches for which notifications are to be sent"
msgstr ""
+msgid "Integrations|Clear if using a self-signed certificate."
+msgstr ""
+
msgid "Integrations|Comment detail:"
msgstr ""
msgid "Integrations|Comment settings:"
msgstr ""
+msgid "Integrations|Connection details"
+msgstr ""
+
msgid "Integrations|Connection failed. Please check your settings."
msgstr ""
@@ -19283,6 +19732,9 @@ msgstr ""
msgid "Integrations|Enable GitLab.com slash commands in a Slack workspace."
msgstr ""
+msgid "Integrations|Enable SSL verification"
+msgstr ""
+
msgid "Integrations|Enable comments"
msgstr ""
@@ -19361,6 +19813,9 @@ msgstr ""
msgid "Integrations|Return to GitLab for Jira"
msgstr ""
+msgid "Integrations|SSL verification"
+msgstr ""
+
msgid "Integrations|Save settings?"
msgstr ""
@@ -19406,9 +19861,6 @@ msgstr ""
msgid "Integrations|Use default settings"
msgstr ""
-msgid "Integrations|When you mention a Jira issue in a commit or merge request, GitLab creates a remote link and comment (if enabled)."
-msgstr ""
-
msgid "Integrations|You can now close this window and return to the GitLab for Jira application."
msgstr ""
@@ -19433,9 +19885,6 @@ msgstr ""
msgid "Integrations|can't exceed %{recipients_limit}"
msgstr ""
-msgid "Interactive developer security education."
-msgstr ""
-
msgid "Interactive mode"
msgstr ""
@@ -19925,6 +20374,9 @@ msgstr ""
msgid "IssueAnalytics|Assignees"
msgstr ""
+msgid "IssueAnalytics|Created by"
+msgstr ""
+
msgid "IssueAnalytics|Due date"
msgstr ""
@@ -19937,9 +20389,6 @@ msgstr ""
msgid "IssueAnalytics|Milestone"
msgstr ""
-msgid "IssueAnalytics|Opened by"
-msgstr ""
-
msgid "IssueAnalytics|Status"
msgstr ""
@@ -20063,10 +20512,10 @@ msgstr ""
msgid "IssuesAnalytics|Avg/Month:"
msgstr ""
-msgid "IssuesAnalytics|Issues opened"
+msgid "IssuesAnalytics|Issues created"
msgstr ""
-msgid "IssuesAnalytics|Issues opened per month"
+msgid "IssuesAnalytics|Issues created per month"
msgstr ""
msgid "IssuesAnalytics|Last 12 months"
@@ -20093,6 +20542,9 @@ msgstr ""
msgid "It looks like you have some draft commits in this branch."
msgstr ""
+msgid "It looks like you're attempting to activate your subscription. Use %{a_start}the Subscription page%{a_end} instead."
+msgstr ""
+
msgid "It may be several days before you see feature usage data."
msgstr ""
@@ -20321,6 +20773,9 @@ msgstr ""
msgid "JiraConnect|You can now close this window and return to Jira."
msgstr ""
+msgid "JiraConnect|You don't have permission to create branches for this project. Select a different project or contact the project owner for access. %{linkStart}Learn more.%{linkEnd}"
+msgstr ""
+
msgid "JiraRequest|A connection error occurred while connecting to Jira. Try your request again."
msgstr ""
@@ -20369,13 +20824,13 @@ msgstr ""
msgid "JiraService|Define the type of Jira issue to create from a vulnerability."
msgstr ""
-msgid "JiraService|Displaying Jira issues while leaving the GitLab issue functionality enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
+msgid "JiraService|Displaying Jira issues while leaving GitLab issues also enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
msgstr ""
-msgid "JiraService|Enable Jira issues"
+msgid "JiraService|Enable Jira issue creation from vulnerabilities"
msgstr ""
-msgid "JiraService|Enable Jira issues creation from vulnerabilities"
+msgid "JiraService|Enable Jira issues"
msgstr ""
msgid "JiraService|Enable Jira transitions"
@@ -20492,16 +20947,19 @@ msgstr ""
msgid "JiraService|View Jira issues in GitLab"
msgstr ""
-msgid "JiraService|Warning: All GitLab users that have access to this GitLab project are able to view all issues from the Jira project specified below."
+msgid "JiraService|Warning: All GitLab users with access to this GitLab project can view all issues from the Jira project you select."
msgstr ""
msgid "JiraService|Web URL"
msgstr ""
-msgid "JiraService|Work on Jira issues without leaving GitLab. Adds a Jira menu to access your list of Jira issues and view any issue as read-only."
+msgid "JiraService|When a Jira issue is mentioned in a commit or merge request, a remote link and comment (if enabled) will be created."
+msgstr ""
+
+msgid "JiraService|Work on Jira issues without leaving GitLab. Add a Jira menu to access a read-only list of your Jira issues."
msgstr ""
-msgid "JiraService|You need to configure Jira before enabling this integration. For more details, read the %{jira_doc_link_start}Jira integration documentation%{link_end}."
+msgid "JiraService|You must configure Jira before enabling this integration. %{jira_doc_link_start}Learn more.%{link_end}"
msgstr ""
msgid "Job"
@@ -20513,9 +20971,6 @@ msgstr ""
msgid "Job Failed #%{build_id}"
msgstr ""
-msgid "Job ID"
-msgstr ""
-
msgid "Job artifact"
msgstr ""
@@ -20582,9 +21037,27 @@ msgstr ""
msgid "Jobs|You're about to retry a job that failed because it attempted to deploy code that is older than the latest deployment. Retrying this job could result in overwriting the environment with the older source code."
msgstr ""
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source} into %{target}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{ref}"
+msgstr ""
+
+msgid "Job|Are you sure you want to erase this job log and artifacts?"
+msgstr ""
+
msgid "Job|Browse"
msgstr ""
+msgid "Job|Cancel"
+msgstr ""
+
msgid "Job|Complete Raw"
msgstr ""
@@ -20594,6 +21067,9 @@ msgstr ""
msgid "Job|Erase job log and artifacts"
msgstr ""
+msgid "Job|Finished at"
+msgstr ""
+
msgid "Job|Job artifacts"
msgstr ""
@@ -20606,7 +21082,7 @@ msgstr ""
msgid "Job|Keep"
msgstr ""
-msgid "Job|Pipeline"
+msgid "Job|Retry"
msgstr ""
msgid "Job|Scroll to bottom"
@@ -20618,6 +21094,9 @@ msgstr ""
msgid "Job|Show complete raw"
msgstr ""
+msgid "Job|Status"
+msgstr ""
+
msgid "Job|The artifacts were removed"
msgstr ""
@@ -20645,21 +21124,12 @@ msgstr ""
msgid "Job|delayed"
msgstr ""
-msgid "Job|for"
-msgstr ""
-
-msgid "Job|into"
-msgstr ""
-
msgid "Job|manual"
msgstr ""
msgid "Job|triggered"
msgstr ""
-msgid "Job|with"
-msgstr ""
-
msgid "Join Zoom meeting"
msgstr ""
@@ -20762,9 +21232,6 @@ msgstr ""
msgid "Ki"
msgstr ""
-msgid "Kontra"
-msgstr ""
-
msgid "Kroki"
msgstr ""
@@ -21088,6 +21555,9 @@ msgstr ""
msgid "Learn more about Auto DevOps"
msgstr ""
+msgid "Learn more about GitLab"
+msgstr ""
+
msgid "Learn more about Needs relationships"
msgstr ""
@@ -21415,9 +21885,18 @@ msgstr ""
msgid "Licenses|Displays licenses detected in the project, based on the %{linkStart}latest successful%{linkEnd} scan"
msgstr ""
+msgid "Licenses|Drag your license file here or %{linkStart}click to upload%{linkEnd}."
+msgstr ""
+
+msgid "Licenses|Drop your license file to start the upload."
+msgstr ""
+
msgid "Licenses|Error fetching the license list. Please check your network connection and try again."
msgstr ""
+msgid "Licenses|Error: You are trying to upload something other than a file"
+msgstr ""
+
msgid "Licenses|License Compliance"
msgstr ""
@@ -21436,6 +21915,9 @@ msgstr ""
msgid "Licenses|Specified policies in this project"
msgstr ""
+msgid "Licenses|The file could not be uploaded."
+msgstr ""
+
msgid "Licenses|The license list details information about the licenses used within your project."
msgstr ""
@@ -21469,11 +21951,6 @@ msgstr ""
msgid "Limit the size of Sidekiq jobs stored in Redis."
msgstr ""
-msgid "Limited to showing %d event at most"
-msgid_plural "Limited to showing %d events at most"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Limiting mode"
msgstr ""
@@ -21483,6 +21960,9 @@ msgstr ""
msgid "Link"
msgstr ""
+msgid "Link (optional)"
+msgstr ""
+
msgid "Link Prometheus monitoring to GitLab."
msgstr ""
@@ -21519,6 +21999,9 @@ msgstr ""
msgid "Linked emails (%{email_count})"
msgstr ""
+msgid "Linked epics"
+msgstr ""
+
msgid "Linked issues"
msgstr ""
@@ -21546,6 +22029,15 @@ msgstr ""
msgid "List of all merge commits"
msgstr ""
+msgid "List of environments for this project"
+msgstr ""
+
+msgid "List of suitable GCP locations"
+msgstr ""
+
+msgid "List of users allowed to exceed the rate limit."
+msgstr ""
+
msgid "List options"
msgstr ""
@@ -21765,6 +22257,9 @@ msgstr ""
msgid "Maintenance mode"
msgstr ""
+msgid "Make adjustments to how your GitLab instance is set up."
+msgstr ""
+
msgid "Make and review changes in the browser with the Web IDE"
msgstr ""
@@ -21909,6 +22404,12 @@ msgstr ""
msgid "MarkdownEditor|Add italic text (%{modifier_key}I)"
msgstr ""
+msgid "MarkdownEditor|Add strikethrough text (%{modifierKey}⇧X)"
+msgstr ""
+
+msgid "MarkdownEditor|Add strikethrough text (%{modifier_key}⇧X)"
+msgstr ""
+
msgid "Marked For Deletion At - %{deletion_time}"
msgstr ""
@@ -22170,6 +22671,9 @@ msgstr ""
msgid "Maximum push size (MB)"
msgstr ""
+msgid "Maximum requests per 10 minutes per user"
+msgstr ""
+
msgid "Maximum requests per minute"
msgstr ""
@@ -22260,6 +22764,19 @@ msgstr ""
msgid "Members of a group may only view projects they have permission to access"
msgstr ""
+msgid "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seat in use and will be billed for the overage."
+msgid_plural "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seats in use and will be billed for the overage."
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "MembersOverage|You are about to incur additional charges"
+msgstr ""
+
+msgid "MembersOverage|Your subscription includes %d seat."
+msgid_plural "MembersOverage|Your subscription includes %d seats."
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Membership"
msgstr ""
@@ -22464,9 +22981,6 @@ msgstr ""
msgid "Merge request not merged"
msgstr ""
-msgid "Merge request pipelines 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 merge request pipelines."
-msgstr ""
-
msgid "Merge request reports"
msgstr ""
@@ -22563,13 +23077,13 @@ msgstr ""
msgid "MergeRequests|Create issue to resolve thread"
msgstr ""
-msgid "MergeRequests|Failed to squash. Should be done manually."
+msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Saving the comment failed"
+msgid "MergeRequests|Squashing failed: Squash the commits locally, resolve any conflicts, then push the branch."
msgstr ""
-msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
+msgid "MergeRequests|Squashing not allowed: This project doesn't allow you to squash commits when merging."
msgstr ""
msgid "MergeRequests|Thread stays resolved"
@@ -23410,6 +23924,18 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "MrList|Assigned to %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from assignee %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from reviewer %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Review requested from %{name}, go to their profile."
+msgstr ""
+
msgid "Multi-project"
msgstr ""
@@ -23443,7 +23969,7 @@ msgstr ""
msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "My Awesome Group"
+msgid "My awesome group"
msgstr ""
msgid "My company or team"
@@ -24065,9 +24591,6 @@ msgstr ""
msgid "No available branches"
msgstr ""
-msgid "No available groups to fork the project."
-msgstr ""
-
msgid "No branches found"
msgstr ""
@@ -24278,6 +24801,9 @@ msgstr ""
msgid "No ref selected"
msgstr ""
+msgid "No regions configured"
+msgstr ""
+
msgid "No related merge requests found."
msgstr ""
@@ -25082,6 +25608,9 @@ msgstr ""
msgid "Only reCAPTCHA v2 is supported:"
msgstr ""
+msgid "Only required if not using role instance credentials."
+msgstr ""
+
msgid "Only use lowercase letters, numbers, and underscores."
msgstr ""
@@ -25106,9 +25635,6 @@ msgstr ""
msgid "Open a CLI and connect to the cluster you want to install the agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
-msgid "Open epics"
-msgstr ""
-
msgid "Open errors"
msgstr ""
@@ -25148,7 +25674,7 @@ msgstr ""
msgid "Opened issues"
msgstr ""
-msgid "OpenedNDaysAgo|Opened"
+msgid "OpenedNDaysAgo|Created"
msgstr ""
msgid "Opens in a new window"
@@ -25193,9 +25719,6 @@ msgstr ""
msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
-msgid "Optional."
-msgstr ""
-
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
msgstr ""
@@ -25984,6 +26507,9 @@ msgstr ""
msgid "PerformanceBar|Memory"
msgstr ""
+msgid "PerformanceBar|Memory report"
+msgstr ""
+
msgid "PerformanceBar|Redis calls"
msgstr ""
@@ -26017,18 +26543,12 @@ msgstr ""
msgid "PerformanceBar|wall"
msgstr ""
-msgid "Performs a rebase but skips triggering a new pipeline"
-msgstr ""
-
msgid "Period in seconds"
msgstr ""
msgid "Permalink"
msgstr ""
-msgid "Permanently delete project"
-msgstr ""
-
msgid "Permanently remove group"
msgstr ""
@@ -26299,6 +26819,51 @@ msgstr ""
msgid "PipelineStatusTooltip|Pipeline: %{ci_status}"
msgstr ""
+msgid "PipelineWizardDefaultCommitMessage|Add %{filename}"
+msgstr ""
+
+msgid "PipelineWizardDefaultCommitMessage|Update %{filename}"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|At least one entry is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This field is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This value is not valid"
+msgstr ""
+
+msgid "PipelineWizardListWidget|add another step"
+msgstr ""
+
+msgid "PipelineWizardListWidget|remove step"
+msgstr ""
+
+msgid "PipelineWizard|Commit"
+msgstr ""
+
+msgid "PipelineWizard|Commit Message"
+msgstr ""
+
+msgid "PipelineWizard|Commit changes to your file"
+msgstr ""
+
+msgid "PipelineWizard|Commit file to Branch"
+msgstr ""
+
+msgid "PipelineWizard|Commit your new file"
+msgstr ""
+
+msgid "PipelineWizard|The file has been committed."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem committing the changes."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem while checking whether your file already exists in the specified branch."
+msgstr ""
+
msgid "Pipelines"
msgstr ""
@@ -26413,7 +26978,7 @@ msgstr ""
msgid "Pipelines|Project cache successfully reset."
msgstr ""
-msgid "Pipelines|Revoke"
+msgid "Pipelines|Revoke trigger"
msgstr ""
msgid "Pipelines|Something went wrong while cleaning runners cache."
@@ -26458,6 +27023,12 @@ msgstr ""
msgid "Pipelines|This is a child pipeline within the parent pipeline"
msgstr ""
+msgid "Pipelines|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipelines|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipelines|This pipeline will run code originating from a forked project merge request. This means that the code can potentially have security considerations like exposing CI variables."
msgstr ""
@@ -26500,9 +27071,6 @@ msgstr ""
msgid "Pipelines|Your changes have been successfully committed. Now redirecting to the new merge request page."
msgstr ""
-msgid "Pipelines|detached"
-msgstr ""
-
msgid "Pipelines|error"
msgstr ""
@@ -26512,10 +27080,13 @@ msgstr ""
msgid "Pipelines|latest"
msgstr ""
-msgid "Pipelines|stuck"
+msgid "Pipelines|merge request"
msgstr ""
-msgid "Pipelines|train"
+msgid "Pipelines|merge train"
+msgstr ""
+
+msgid "Pipelines|stuck"
msgstr ""
msgid "Pipelines|yaml invalid"
@@ -26647,6 +27218,12 @@ msgstr ""
msgid "Pipeline|This change will not change the overall test coverage if merged."
msgstr ""
+msgid "Pipeline|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipeline|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipeline|Trigger author"
msgstr ""
@@ -26671,6 +27248,12 @@ msgstr ""
msgid "Pipeline|for"
msgstr ""
+msgid "Pipeline|merge request"
+msgstr ""
+
+msgid "Pipeline|merge train"
+msgstr ""
+
msgid "Pipeline|on"
msgstr ""
@@ -26809,9 +27392,6 @@ msgstr ""
msgid "Please enter a valid time interval"
msgstr ""
-msgid "Please enter or upload a valid license."
-msgstr ""
-
msgid "Please enter your current password."
msgstr ""
@@ -26920,9 +27500,6 @@ msgstr ""
msgid "Please type %{phrase_code} to proceed or close this modal to cancel."
msgstr ""
-msgid "Please type the following to confirm:"
-msgstr ""
-
msgid "Please use this form to report to the admin users who create spam issues, comments or behave inappropriately."
msgstr ""
@@ -26950,12 +27527,27 @@ msgstr ""
msgid "Policies"
msgstr ""
+msgid "Policy '%{escalation_policy_name}' does not exist."
+msgstr ""
+
msgid "Policy management project does have any policies in %{policy_path}"
msgstr ""
msgid "Policy project doesn't exist"
msgstr ""
+msgid "PolicyRuleMultiSelect|%{firstLabel} +%{numberOfAdditionalLabels} more"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|All %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select all"
+msgstr ""
+
msgid "Polling interval multiplier"
msgstr ""
@@ -27184,6 +27776,9 @@ msgstr ""
msgid "Private projects can be created in your personal namespace with:"
msgstr ""
+msgid "Problem with %{name} command: %{message}."
+msgstr ""
+
msgid "Proceed"
msgstr ""
@@ -27658,6 +28253,9 @@ msgstr ""
msgid "Progress"
msgstr ""
+msgid "Progress tracking"
+msgstr ""
+
msgid "Project"
msgstr ""
@@ -27889,6 +28487,9 @@ msgstr ""
msgid "ProjectQualitySummary|Failure"
msgstr ""
+msgid "ProjectQualitySummary|Get insight into the overall percentage of tests in your project that succeed, fail and are skipped."
+msgstr ""
+
msgid "ProjectQualitySummary|Latest pipeline results"
msgstr ""
@@ -27907,6 +28508,12 @@ msgstr ""
msgid "ProjectQualitySummary|See project Code Coverage Statistics"
msgstr ""
+msgid "ProjectQualitySummary|Set up test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|Set up test runs (opens in a new tab)"
+msgstr ""
+
msgid "ProjectQualitySummary|Skipped"
msgstr ""
@@ -28183,13 +28790,19 @@ msgstr ""
msgid "ProjectSettings|LFS objects from this repository are available to forks. %{linkStart}How do I remove them?%{linkEnd}"
msgstr ""
+msgid "ProjectSettings|Learn about commit history."
+msgstr ""
+
+msgid "ProjectSettings|Leave empty to use default template."
+msgstr ""
+
msgid "ProjectSettings|Manage who can see the project in the public access directory."
msgstr ""
msgid "ProjectSettings|Manages large files such as audio, video, and graphics files."
msgstr ""
-msgid "ProjectSettings|Maximum 500 characters."
+msgid "ProjectSettings|Maximum %{maxLength} characters."
msgstr ""
msgid "ProjectSettings|Merge checks"
@@ -28330,6 +28943,9 @@ msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
msgstr ""
+msgid "ProjectSettings|The default template will be applied on save."
+msgstr ""
+
msgid "ProjectSettings|These checks must pass before merge requests can be merged."
msgstr ""
@@ -28384,6 +29000,9 @@ msgstr ""
msgid "ProjectSettings|What are badges?"
msgstr ""
+msgid "ProjectSettings|What are merge trains?"
+msgstr ""
+
msgid "ProjectSettings|When merge request pipelines are enabled in the CI/CD configuration file, pipelines validate the combined results of the source and target branches. %{link_start}How to configure merge request pipelines?%{link_end}"
msgstr ""
@@ -28501,6 +29120,9 @@ msgstr ""
msgid "Projects are organized into groups"
msgstr ""
+msgid "Projects are where you store your code, access issues, wiki and other features of GitLab."
+msgstr ""
+
msgid "Projects contributed to"
msgstr ""
@@ -28516,12 +29138,6 @@ msgstr ""
msgid "Projects to index"
msgstr ""
-msgid "Projects will be permanently deleted after a %{waiting_period}-day waiting period."
-msgstr ""
-
-msgid "Projects will be permanently deleted immediately."
-msgstr ""
-
msgid "Projects with critical vulnerabilities"
msgstr ""
@@ -28606,6 +29222,9 @@ msgstr ""
msgid "ProjectsNew|Import project"
msgstr ""
+msgid "ProjectsNew|Include a Getting Started README"
+msgstr ""
+
msgid "ProjectsNew|Initialize repository with a README"
msgstr ""
@@ -28621,6 +29240,9 @@ msgstr ""
msgid "ProjectsNew|Project description %{tag_start}(optional)%{tag_end}"
msgstr ""
+msgid "ProjectsNew|Recommended if you're new to GitLab"
+msgstr ""
+
msgid "ProjectsNew|Run CI/CD for external repository"
msgstr ""
@@ -29038,6 +29660,9 @@ msgstr ""
msgid "ProtectedBranch|Unprotect"
msgstr ""
+msgid "ProtectedBranch|Unprotect branch"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
@@ -29065,6 +29690,9 @@ msgstr ""
msgid "ProtectedEnvironment|Protected Environment (%{protected_environments_count})"
msgstr ""
+msgid "ProtectedEnvironment|Required approvals"
+msgstr ""
+
msgid "ProtectedEnvironment|Select an environment"
msgstr ""
@@ -29086,10 +29714,13 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|Unprotect tag"
+msgstr ""
+
msgid "ProtectedTags|default"
msgstr ""
-msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
+msgid "ProtectedTag|By default, protected tags restrict who can modify the tag."
msgstr ""
msgid "ProtectedTag|Learn more."
@@ -29152,6 +29783,9 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Public projects are an easy way to allow everyone to have read-only access."
+msgstr ""
+
msgid "Publish to status page"
msgstr ""
@@ -29308,9 +29942,6 @@ msgstr ""
msgid "QualitySummary|Project quality"
msgstr ""
-msgid "Quarters"
-msgstr ""
-
msgid "Query"
msgstr ""
@@ -29395,6 +30026,9 @@ msgstr ""
msgid "Read more about project permissions %{help_link_open}here%{help_link_close}"
msgstr ""
+msgid "Read more about related epics"
+msgstr ""
+
msgid "Read more about related issues"
msgstr ""
@@ -29425,10 +30059,7 @@ msgstr ""
msgid "Rebase source branch on the target branch."
msgstr ""
-msgid "Rebase without CI"
-msgstr ""
-
-msgid "Rebases and triggers a pipeline"
+msgid "Rebase without pipeline"
msgstr ""
msgid "Recaptcha verified?"
@@ -29479,9 +30110,6 @@ msgstr ""
msgid "Reconfigure"
msgstr ""
-msgid "Recovering projects"
-msgstr ""
-
msgid "Recovery Codes"
msgstr ""
@@ -29541,6 +30169,12 @@ msgstr ""
msgid "Regex pattern"
msgstr ""
+msgid "Region"
+msgstr ""
+
+msgid "Regions"
+msgstr ""
+
msgid "Register"
msgstr ""
@@ -29771,9 +30405,6 @@ msgstr ""
msgid "Remove all or specific reviewer(s)"
msgstr ""
-msgid "Remove approver"
-msgstr ""
-
msgid "Remove approvers"
msgstr ""
@@ -29789,6 +30420,9 @@ msgstr ""
msgid "Remove attention request"
msgstr ""
+msgid "Remove attention request(s)"
+msgstr ""
+
msgid "Remove avatar"
msgstr ""
@@ -29927,6 +30561,9 @@ msgstr ""
msgid "Removed an issue from an epic."
msgstr ""
+msgid "Removed attention from %{users_sentence}."
+msgstr ""
+
msgid "Removed attention request from @%{username}"
msgstr ""
@@ -29978,6 +30615,9 @@ msgstr ""
msgid "Removes an issue from an epic."
msgstr ""
+msgid "Removes attention from %{users_sentence}."
+msgstr ""
+
msgid "Removes parent epic %{epic_ref}."
msgstr ""
@@ -30089,6 +30729,9 @@ msgstr ""
msgid "Report abuse to admin"
msgstr ""
+msgid "Report is generating and will be sent to your email address."
+msgstr ""
+
msgid "Reported %{timeAgo} by %{reportedBy}"
msgstr ""
@@ -30378,6 +31021,15 @@ msgstr ""
msgid "Request attention"
msgstr ""
+msgid "Request attention from %{users_sentence}."
+msgstr ""
+
+msgid "Request attention from assignee or reviewer"
+msgstr ""
+
+msgid "Request attention from assignee(s) or reviewer(s)"
+msgstr ""
+
msgid "Request attention to review"
msgstr ""
@@ -30402,6 +31054,9 @@ msgstr ""
msgid "Requested %{time_ago}"
msgstr ""
+msgid "Requested attention from %{users_sentence}."
+msgstr ""
+
msgid "Requested attention from @%{username}"
msgstr ""
@@ -30616,6 +31271,9 @@ msgstr ""
msgid "Restore project"
msgstr ""
+msgid "Restoring projects"
+msgstr ""
+
msgid "Restoring the group will prevent the group, its subgroups and projects from being removed on this date."
msgstr ""
@@ -30646,6 +31304,9 @@ msgstr ""
msgid "Retry"
msgstr ""
+msgid "Retry failed jobs"
+msgstr ""
+
msgid "Retry job"
msgstr ""
@@ -30693,9 +31354,6 @@ msgstr ""
msgid "Review changes"
msgstr ""
-msgid "Review requested from %{name}"
-msgstr ""
-
msgid "Review requests for you"
msgstr ""
@@ -30860,6 +31518,9 @@ msgstr ""
msgid "Runners|Assigned Group"
msgstr ""
+msgid "Runners|Assigned Projects (%{projectCount})"
+msgstr ""
+
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30929,6 +31590,9 @@ msgstr ""
msgid "Runners|Instance"
msgstr ""
+msgid "Runners|Jobs"
+msgstr ""
+
msgid "Runners|Last contact"
msgstr ""
@@ -31022,9 +31686,6 @@ msgstr ""
msgid "Runners|Runner %{name} was deleted"
msgstr ""
-msgid "Runners|Runner ID"
-msgstr ""
-
msgid "Runners|Runner assigned to project."
msgstr ""
@@ -31172,6 +31833,9 @@ msgstr ""
msgid "Runners|stale"
msgstr ""
+msgid "Runner|This runner has not run any jobs."
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -31286,6 +31950,24 @@ msgstr ""
msgid "Saving project."
msgstr ""
+msgid "ScanResultPolicy|%{ifLabelStart}if%{ifLabelEnd} %{scanners} scan in an open merge request targeting the %{branches} branch(es) finds %{vulnerabilitiesAllowed} or more %{severities} vulnerabilities that are %{vulnerabilityStates}"
+msgstr ""
+
+msgid "ScanResultPolicy|%{thenLabelStart}Then%{thenLabelEnd} Require approval from %{approvalsRequired} of the following approvers: %{approvers}"
+msgstr ""
+
+msgid "ScanResultPolicy|add an approver"
+msgstr ""
+
+msgid "ScanResultPolicy|scanners"
+msgstr ""
+
+msgid "ScanResultPolicy|severity levels"
+msgstr ""
+
+msgid "ScanResultPolicy|vulnerability states"
+msgstr ""
+
msgid "Scanner"
msgstr ""
@@ -31418,6 +32100,9 @@ msgstr ""
msgid "Search for a user"
msgstr ""
+msgid "Search for an emoji"
+msgstr ""
+
msgid "Search for projects, issues, etc."
msgstr ""
@@ -31605,18 +32290,12 @@ msgstr ""
msgid "Secret Detection"
msgstr ""
-msgid "Secret access key"
-msgstr ""
-
msgid "Secret token"
msgstr ""
msgid "Secure token that identifies an external storage request."
msgstr ""
-msgid "SecureCodeWarrior"
-msgstr ""
-
msgid "Security"
msgstr ""
@@ -31641,9 +32320,6 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "Security training with guide and learning pathways."
-msgstr ""
-
msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
@@ -31746,7 +32422,7 @@ msgstr ""
msgid "SecurityConfiguration|Manage corpus"
msgstr ""
-msgid "SecurityConfiguration|Manage corpus files used as mutation sources in coverage fuzzing."
+msgid "SecurityConfiguration|Manage corpus files used as seed inputs with coverage-guided fuzzing."
msgstr ""
msgid "SecurityConfiguration|Manage profiles for use by DAST scans."
@@ -31812,15 +32488,15 @@ msgstr ""
msgid "SecurityOrchestration|.yaml preview"
msgstr ""
-msgid "SecurityOrchestration|Action"
-msgstr ""
-
msgid "SecurityOrchestration|Actions"
msgstr ""
msgid "SecurityOrchestration|Add rule"
msgstr ""
+msgid "SecurityOrchestration|After dismissing the alert, the information will never be shown again."
+msgstr ""
+
msgid "SecurityOrchestration|All policies"
msgstr ""
@@ -31836,7 +32512,7 @@ msgstr ""
msgid "SecurityOrchestration|Description"
msgstr ""
-msgid "SecurityOrchestration|Disabled"
+msgid "SecurityOrchestration|Don't show the alert anymore"
msgstr ""
msgid "SecurityOrchestration|Edit policy"
@@ -31845,13 +32521,13 @@ msgstr ""
msgid "SecurityOrchestration|Edit policy project"
msgstr ""
-msgid "SecurityOrchestration|Enabled"
+msgid "SecurityOrchestration|Empty policy name"
msgstr ""
-msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Enabled"
msgstr ""
-msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
msgstr ""
msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
@@ -31860,7 +32536,7 @@ msgstr ""
msgid "SecurityOrchestration|Invalid policy type"
msgstr ""
-msgid "SecurityOrchestration|Latest scan"
+msgid "SecurityOrchestration|Latest scan run against %{agent}"
msgstr ""
msgid "SecurityOrchestration|Network"
@@ -31869,15 +32545,27 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No actions defined - policy will not run."
+msgstr ""
+
+msgid "SecurityOrchestration|No description"
+msgstr ""
+
msgid "SecurityOrchestration|No rules defined - policy will not run."
msgstr ""
+msgid "SecurityOrchestration|Not enabled"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
msgid "SecurityOrchestration|Policies"
msgstr ""
+msgid "SecurityOrchestration|Policy Type"
+msgstr ""
+
msgid "SecurityOrchestration|Policy cannot be enabled for non-existing branches (%{branches})"
msgstr ""
@@ -31902,10 +32590,13 @@ msgstr ""
msgid "SecurityOrchestration|Require %{approvals} %{plural} from %{approvers} if any of the following occur:"
msgstr ""
-msgid "SecurityOrchestration|Rule"
+msgid "SecurityOrchestration|Rules"
msgstr ""
-msgid "SecurityOrchestration|Rules"
+msgid "SecurityOrchestration|Runs %{actions} and %{lastAction} scans"
+msgstr ""
+
+msgid "SecurityOrchestration|Runs a %{action} scan"
msgstr ""
msgid "SecurityOrchestration|Scan Execution"
@@ -31965,6 +32656,9 @@ msgstr ""
msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
+msgid "SecurityOrchestration|This view only shows scan results for the agent %{agent}. You can view scan results for all agents in the %{linkStart}Operational Vulnerabilities tab of the vulnerability report%{linkEnd}."
+msgstr ""
+
msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
@@ -32019,9 +32713,6 @@ msgstr ""
msgid "SecurityOrchestration|users with ids"
msgstr ""
-msgid "SecurityOrchestration|view results"
-msgstr ""
-
msgid "SecurityOrchestration|vulnerabilities"
msgstr ""
@@ -32691,22 +33382,19 @@ 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|In order to start using functions as a service, you must first install Knative on your Kubernetes cluster. %{linkStart}More information%{linkEnd}"
-msgstr ""
-
msgid "Serverless|Learn more about Serverless"
msgstr ""
msgid "Serverless|No functions available"
msgstr ""
-msgid "Serverless|Sign up for First Look"
+msgid "Serverless|Serverless was %{linkStart}deprecated%{linkEnd} in GitLab 14.3."
+msgstr ""
+
+msgid "Serverless|Serverless was %{postLinkStart}deprecated%{postLinkEnd}. But if you opt to use it, you must install Knative in your Kubernetes cluster first. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "Serverless|The deploy job has not finished."
@@ -32718,9 +33406,6 @@ 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 ""
@@ -32736,9 +33421,6 @@ msgstr ""
msgid "Service Account Key"
msgstr ""
-msgid "Service Accounts"
-msgstr ""
-
msgid "Service Accounts keys authorize GitLab to deploy your Google Cloud project"
msgstr ""
@@ -32748,10 +33430,10 @@ msgstr ""
msgid "Service Desk allows people to create issues in your GitLab instance without their own user account. It provides a unique email address for end users to create issues in a project. Replies can be sent either through the GitLab interface or by email. End users only see threads through email."
msgstr ""
-msgid "Service Usage Data"
+msgid "Service account generated successfully"
msgstr ""
-msgid "Service account generated successfully"
+msgid "Service accounts"
msgstr ""
msgid "Service ping is disabled in your configuration file, and cannot be enabled through this form."
@@ -32895,6 +33577,9 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
+msgid "Set the per-user rate limit for getting a user by ID via the API."
+msgstr ""
+
msgid "Set the per-user rate limit for notes created by web or API requests."
msgstr ""
@@ -33074,6 +33759,9 @@ msgstr ""
msgid "Shared runners details"
msgstr ""
+msgid "Shared runners enabled cannot be enabled until a valid credit card is on file"
+msgstr ""
+
msgid "Shared runners help link"
msgstr ""
@@ -33131,6 +33819,9 @@ msgstr ""
msgid "Show all issues."
msgstr ""
+msgid "Show all milestones"
+msgstr ""
+
msgid "Show all test cases."
msgstr ""
@@ -33167,6 +33858,9 @@ msgstr ""
msgid "Show file contents"
msgstr ""
+msgid "Show group milestones"
+msgstr ""
+
msgid "Show labels"
msgstr ""
@@ -33182,6 +33876,12 @@ msgstr ""
msgid "Show open epics"
msgstr ""
+msgid "Show project milestones"
+msgstr ""
+
+msgid "Show sub-group milestones"
+msgstr ""
+
msgid "Show the Closed list"
msgstr ""
@@ -33191,11 +33891,6 @@ msgstr ""
msgid "Show whitespace changes"
msgstr ""
-msgid "Showing %d event"
-msgid_plural "Showing %d events"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Showing %{conflict} between %{sourceBranch} and %{targetBranch}"
msgstr ""
@@ -33255,12 +33950,6 @@ msgstr ""
msgid "Sidebar|None"
msgstr ""
-msgid "Sidebar|Only numeral characters allowed"
-msgstr ""
-
-msgid "Sidebar|Weight"
-msgstr ""
-
msgid "Sidekiq job compression threshold (bytes)"
msgstr ""
@@ -33423,6 +34112,9 @@ msgstr ""
msgid "Slack logo"
msgstr ""
+msgid "SlackIntegration|Are you sure you want to remove this project from the Slack application?"
+msgstr ""
+
msgid "SlackIntegration|GitLab for Slack"
msgstr ""
@@ -33432,6 +34124,9 @@ msgstr ""
msgid "SlackIntegration|Project alias"
msgstr ""
+msgid "SlackIntegration|Remove project"
+msgstr ""
+
msgid "SlackIntegration|Select a GitLab project to link with your Slack workspace."
msgstr ""
@@ -33576,9 +34271,6 @@ msgstr ""
msgid "Something went wrong trying to load issue contacts."
msgstr ""
-msgid "Something went wrong when creating a work item. Please try again"
-msgstr ""
-
msgid "Something went wrong when reordering designs. Please try again"
msgstr ""
@@ -33672,9 +34364,6 @@ msgstr ""
msgid "Something went wrong while inserting your image. Please try again."
msgstr ""
-msgid "Something went wrong while merging this merge request. Please try again."
-msgstr ""
-
msgid "Something went wrong while obtaining the Let's Encrypt certificate."
msgstr ""
@@ -33996,10 +34685,10 @@ 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."
+msgid "SourcegraphAdmin|Learn more."
msgstr ""
-msgid "SourcegraphAdmin|More information"
+msgid "SourcegraphAdmin|Only public projects have code intelligence enabled and communicate with Sourcegraph."
msgstr ""
msgid "SourcegraphAdmin|Save changes"
@@ -34008,7 +34697,7 @@ msgstr ""
msgid "SourcegraphAdmin|Sourcegraph URL"
msgstr ""
-msgid "SourcegraphAdmin|e.g. https://sourcegraph.example.com"
+msgid "SourcegraphAdmin|https://sourcegraph.example.com"
msgstr ""
msgid "SourcegraphPreferences|This feature is experimental and currently limited to certain projects."
@@ -34143,6 +34832,9 @@ msgstr ""
msgid "Start date"
msgstr ""
+msgid "Start free trial"
+msgstr ""
+
msgid "Start merge train"
msgstr ""
@@ -34173,6 +34865,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started escalation for this incident."
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -34185,6 +34880,9 @@ msgstr ""
msgid "Starts at (UTC)"
msgstr ""
+msgid "Starts escalations for this incident"
+msgstr ""
+
msgid "Starts on"
msgstr ""
@@ -34446,6 +35144,9 @@ msgstr ""
msgid "Strikethrough"
msgstr ""
+msgid "Strikethrough text"
+msgstr ""
+
msgid "Subgroup information"
msgstr ""
@@ -34680,6 +35381,21 @@ msgstr ""
msgid "Subscriptions"
msgstr ""
+msgid "Subscriptions|Chat with sales"
+msgstr ""
+
+msgid "Subscriptions|Close"
+msgstr ""
+
+msgid "Subscriptions|Not ready to buy yet?"
+msgstr ""
+
+msgid "Subscriptions|Start a free trial"
+msgstr ""
+
+msgid "Subscriptions|We understand. Maybe you have some questions for our sales team, or maybe you'd like to try some of the paid features first. What would you like to do?"
+msgstr ""
+
msgid "Subscription|Your subscription for %{strong}%{namespace_name}%{strong_close} has expired and you are now on %{pricing_link_start}the GitLab Free tier%{pricing_link_end}. Don't worry, your data is safe. Get in touch with our support team (%{support_email}). They'll gladly help with your subscription renewal."
msgstr ""
@@ -34890,6 +35606,9 @@ msgstr ""
msgid "SuperSonics|Maximum users"
msgstr ""
+msgid "SuperSonics|Offline cloud"
+msgstr ""
+
msgid "SuperSonics|Paste your activation code"
msgstr ""
@@ -34956,6 +35675,12 @@ msgstr ""
msgid "SuperSonics|You do not have an active subscription"
msgstr ""
+msgid "SuperSonics|You have a future dated license"
+msgstr ""
+
+msgid "SuperSonics|You have added a license that activates on %{date}. Please see the subscription history table below for more details."
+msgstr ""
+
msgid "SuperSonics|You have successfully added a license that activates on %{date}. Please see the subscription history table below for more details."
msgstr ""
@@ -35115,6 +35840,9 @@ msgstr ""
msgid "Tag name is required"
msgstr ""
+msgid "Tag push"
+msgstr ""
+
msgid "Tag push events"
msgstr ""
@@ -35217,6 +35945,9 @@ msgstr ""
msgid "TagsPage|protected"
msgstr ""
+msgid "Take a look at the documentation to discover all of GitLab’s capabilities."
+msgstr ""
+
msgid "Target Branch"
msgstr ""
@@ -35619,6 +36350,9 @@ msgstr ""
msgid "Tests"
msgstr ""
+msgid "Text (optional)"
+msgstr ""
+
msgid "Text added to the body of all email messages. %{character_limit} character limit"
msgstr ""
@@ -35669,6 +36403,9 @@ msgstr ""
msgid "The CSV export will be created in the background. Once finished, it will be sent to %{email} in an attachment."
msgstr ""
+msgid "The CSV export you requested of all user memberships is attached to this email."
+msgstr ""
+
msgid "The GitLab subscription service (customers.gitlab.com) is currently experiencing an outage. You can monitor the status and get updates at %{linkStart}status.gitlab.com%{linkEnd}."
msgstr ""
@@ -35744,6 +36481,9 @@ 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 epic"
+msgstr ""
+
msgid "The current issue"
msgstr ""
@@ -35905,6 +36645,9 @@ msgstr ""
msgid "The latest pipeline for this merge request has failed."
msgstr ""
+msgid "The license key is invalid."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -35920,6 +36663,9 @@ msgstr ""
msgid "The license was successfully uploaded and will be active from %{starts_at}. You can see the details below."
msgstr ""
+msgid "The license you uploaded is invalid. If the issue persists, contact support at %{link}."
+msgstr ""
+
msgid "The list creation wizard is already open"
msgstr ""
@@ -36541,10 +37287,13 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} and everything this project contains. %{strongOpen}There is no going back%{strongClose}"
+msgstr ""
+
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains."
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}on %{date}%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains. %{strongOpen}There is no going back.%{strongClose}"
msgstr ""
msgid "This action will %{strongOpen}permanently remove%{strongClose} %{codeOpen}%{group}%{codeClose} %{strongOpen}immediately%{strongClose}."
@@ -36673,9 +37422,6 @@ msgstr ""
msgid "This file was modified for readability, and can't accept suggestions. Edit it directly."
msgstr ""
-msgid "This forked project has the following:"
-msgstr ""
-
msgid "This form is disabled in preview"
msgstr ""
@@ -36688,7 +37434,7 @@ msgstr ""
msgid "This group can't be removed because it is linked to a subscription. To remove this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
-msgid "This group can't be transfered because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
+msgid "This group can't be transferred because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
msgid "This group cannot be invited to a project inside a group with enforced SSO"
@@ -36715,6 +37461,9 @@ 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 incident is already escalated with '%{escalation_policy_name}'."
+msgstr ""
+
msgid "This invitation was sent to %{mail_to_invite_email}, but you are signed in as %{link_to_current_user} with email %{mail_to_current_user}."
msgstr ""
@@ -36733,9 +37482,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 merge train pipeline"
-msgstr ""
-
msgid "This is a private email address %{helpIcon} generated just for you. Anyone who has it can create issues or merge requests as if they were you. If that happens, %{resetLinkStart}reset this token%{resetLinkEnd}."
msgstr ""
@@ -36757,6 +37503,12 @@ msgstr ""
msgid "This is your current session"
msgstr ""
+msgid "This issue cannot be assigned to a confidential epic because it is public."
+msgstr ""
+
+msgid "This issue cannot be made public because it belongs to a confidential epic."
+msgstr ""
+
msgid "This issue is confidential and should only be visible to team members with at least Reporter access."
msgstr ""
@@ -36874,6 +37626,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 branch is protected from force push."
+msgstr ""
+
msgid "This merge request cannot be rebased while there are conflicts."
msgstr ""
@@ -36925,9 +37680,15 @@ msgstr ""
msgid "This pipeline was triggered by a schedule."
msgstr ""
+msgid "This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project"
msgstr ""
+msgid "This project can be restored until %{date}."
+msgstr ""
+
msgid "This project cannot be %{visibilityLevel} because the visibility of %{openShowLink}%{name}%{closeShowLink} is %{visibility}. To make this project %{visibilityLevel}, you must first %{openEditLink}change the visibility%{closeEditLink} of the parent group."
msgstr ""
@@ -36946,6 +37707,9 @@ msgstr ""
msgid "This project is %{strongStart}NOT%{strongEnd} a fork, and has the following:"
msgstr ""
+msgid "This project is %{strongStart}NOT%{strongEnd} a fork. This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -37637,6 +38401,9 @@ msgstr ""
msgid "Today"
msgstr ""
+msgid "Todos count"
+msgstr ""
+
msgid "Todos|Are you looking for things to do? Take a look at %{strongStart}%{openIssuesLinkStart}open issues%{openIssuesLinkEnd}%{strongEnd}, contribute to %{strongStart}%{mergeRequestLinkStart}a merge request%{mergeRequestLinkEnd}%{mergeRequestLinkEnd}%{strongEnd}, or mention someone in a comment to automatically assign them a new to-do item."
msgstr ""
@@ -37910,10 +38677,8 @@ msgstr ""
msgid "Trending"
msgstr ""
-msgid "Trials|%{planName} Trial %{enDash} %{num} day left"
-msgid_plural "Trials|%{planName} Trial %{enDash} %{num} days left"
-msgstr[0] ""
-msgstr[1] ""
+msgid "Trials|%{planName} Trial"
+msgstr ""
msgid "Trials|Compare all plans"
msgstr ""
@@ -37921,6 +38686,9 @@ msgstr ""
msgid "Trials|Create a new group to start your GitLab Ultimate trial."
msgstr ""
+msgid "Trials|Day %{daysUsed}/%{duration}"
+msgstr ""
+
msgid "Trials|Go back to GitLab"
msgstr ""
@@ -38170,7 +38938,7 @@ msgstr ""
msgid "URL is triggered when repository is updated"
msgstr ""
-msgid "URL must be percent-encoded if neccessary."
+msgid "URL must be percent-encoded if necessary."
msgstr ""
msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
@@ -38389,6 +39157,9 @@ msgstr ""
msgid "Unlock account"
msgstr ""
+msgid "Unlock more features with GitLab Ultimate"
+msgstr ""
+
msgid "Unlock the discussion"
msgstr ""
@@ -38452,6 +39223,9 @@ msgstr ""
msgid "Unsubscribes from this %{quick_action_target}."
msgstr ""
+msgid "Unsupported sort value."
+msgstr ""
+
msgid "Unsupported todo type passed. Supported todo types are: %{todo_types}"
msgstr ""
@@ -38680,6 +39454,9 @@ msgstr ""
msgid "UsageQuota|File attachments and smaller design graphics."
msgstr ""
+msgid "UsageQuota|From %{storage_enforcement_date} storage limits will apply to this namespace. View and manage your usage in %{strong_start}Group Settings &gt; Usage quotas%{strong_end}."
+msgstr ""
+
msgid "UsageQuota|Git repository."
msgstr ""
@@ -38740,6 +39517,9 @@ msgstr ""
msgid "UsageQuota|Storage type"
msgstr ""
+msgid "UsageQuota|Storage used"
+msgstr ""
+
msgid "UsageQuota|This is the total amount of storage used across your projects within this namespace."
msgstr ""
@@ -38935,6 +39715,12 @@ msgstr ""
msgid "Use hashed storage paths for newly created and renamed repositories. Always enabled since 13.0."
msgstr ""
+msgid "Use issue count"
+msgstr ""
+
+msgid "Use issue weight"
+msgstr ""
+
msgid "Use one line per URI"
msgstr ""
@@ -39316,6 +40102,9 @@ msgstr ""
msgid "Users"
msgstr ""
+msgid "Users API rate limit"
+msgstr ""
+
msgid "Users can launch a development environment from a GitLab browser tab when the %{linkStart}Gitpod%{linkEnd} integration is enabled."
msgstr ""
@@ -39641,6 +40430,9 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View group pipeline usage quota"
+msgstr ""
+
msgid "View incident details at"
msgstr ""
@@ -39793,6 +40585,9 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
+msgid "Vulnerability"
+msgstr ""
+
msgid "Vulnerability Report"
msgstr ""
@@ -39844,6 +40639,9 @@ msgstr ""
msgid "VulnerabilityManagement|An unverified non-confirmed finding"
msgstr ""
+msgid "VulnerabilityManagement|At least one identifier is required"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -39853,12 +40651,24 @@ msgstr ""
msgid "VulnerabilityManagement|Create Jira issue"
msgstr ""
+msgid "VulnerabilityManagement|Enter a name"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE code"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE identifier URL"
+msgstr ""
+
msgid "VulnerabilityManagement|Fetching linked Jira issues"
msgstr ""
msgid "VulnerabilityManagement|Manually add a vulnerability entry into the vulnerability report."
msgstr ""
+msgid "VulnerabilityManagement|Name is a required field"
+msgstr ""
+
msgid "VulnerabilityManagement|Needs triage"
msgstr ""
@@ -39874,6 +40684,18 @@ msgstr ""
msgid "VulnerabilityManagement|Select a method"
msgstr ""
+msgid "VulnerabilityManagement|Select a severity level"
+msgstr ""
+
+msgid "VulnerabilityManagement|Select a status"
+msgstr ""
+
+msgid "VulnerabilityManagement|Severity is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Something went wrong while creating vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -39898,6 +40720,12 @@ msgstr ""
msgid "VulnerabilityManagement|Something went wrong, could not update vulnerability state."
msgstr ""
+msgid "VulnerabilityManagement|Status is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Submit vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Summary, detailed description, steps to reproduce, etc."
msgstr ""
@@ -40093,6 +40921,9 @@ msgstr ""
msgid "WARNING:"
msgstr ""
+msgid "WARNING: This snippet contains hidden files which might be used to mask malicious behavior. Exercise caution if cloning and executing code from this snippet."
+msgstr ""
+
msgid "Wait for the file to load to copy its contents"
msgstr ""
@@ -40312,6 +41143,15 @@ msgstr ""
msgid "Webhooks|An issue is created, updated, closed, or reopened."
msgstr ""
+msgid "Webhooks|Are you sure you want to delete this group hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this project hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this webhook?"
+msgstr ""
+
msgid "Webhooks|Comments"
msgstr ""
@@ -40321,6 +41161,9 @@ msgstr ""
msgid "Webhooks|Confidential issues events"
msgstr ""
+msgid "Webhooks|Delete webhook"
+msgstr ""
+
msgid "Webhooks|Deployment events"
msgstr ""
@@ -40554,6 +41397,9 @@ msgstr ""
msgid "Wiki"
msgstr ""
+msgid "Wiki page"
+msgstr ""
+
msgid "Wiki page was successfully created."
msgstr ""
@@ -40659,7 +41505,7 @@ msgstr ""
msgid "WikiPageConflictMessage|Someone edited the page the same time you did. Please check out %{wikiLinkStart}the page%{wikiLinkEnd} and make sure your changes will not unintentionally remove theirs."
msgstr ""
-msgid "WikiPage|An error occured while trying to render the content editor. Please try again later."
+msgid "WikiPage|An error occurred while trying to render the content editor. Please try again later."
msgstr ""
msgid "WikiPage|Are you sure you want to switch back to the classic editor?"
@@ -40818,6 +41664,18 @@ msgstr ""
msgid "WorkItem|New Task"
msgstr ""
+msgid "WorkItem|Something went wrong when creating a work item. Please try again"
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching the work item. Please try again."
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching work item types. Please try again"
+msgstr ""
+
+msgid "WorkItem|Type"
+msgstr ""
+
msgid "WorkItem|Work Items"
msgstr ""
@@ -40884,7 +41742,10 @@ msgstr ""
msgid "You are about to add %{usersTag} people to the discussion. They will all receive a notification."
msgstr ""
-msgid "You are about to permanently delete this project"
+msgid "You are about to delete this forked project containing:"
+msgstr ""
+
+msgid "You are about to delete this project containing:"
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."
@@ -40905,6 +41766,9 @@ msgstr ""
msgid "You are attempting to update a file that has changed since you started editing it."
msgstr ""
+msgid "You are billed if you exceed this number. %{qsrOverageLinkStart}How does billing work?%{qsrOverageLinkEnd}"
+msgstr ""
+
msgid "You are connected to the Prometheus server, but there is currently no data to display."
msgstr ""
@@ -40962,6 +41826,9 @@ msgstr ""
msgid "You are not authorized to update this scanner profile"
msgstr ""
+msgid "You are not authorized to upload metric images"
+msgstr ""
+
msgid "You are now impersonating %{username}"
msgstr ""
@@ -41115,9 +41982,6 @@ msgstr ""
msgid "You can only upload one design when dropping onto an existing design."
msgstr ""
-msgid "You can recover this project until %{date}"
-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 ""
@@ -41166,9 +42030,6 @@ msgstr ""
msgid "You cannot write to this read-only GitLab instance."
msgstr ""
-msgid "You can’t %{tag_start}edit%{tag_end} files directly in this project. Fork this project and submit a merge request with your changes."
-msgstr ""
-
msgid "You can’t edit files directly in this project. Fork this project and submit a merge request with your changes."
msgstr ""
@@ -41321,9 +42182,6 @@ 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 set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
@@ -41354,12 +42212,6 @@ msgstr ""
msgid "You must have maintainer access to force delete a lock"
msgstr ""
-msgid "You must have permission to create a project in a group before forking."
-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 ""
@@ -41765,7 +42617,7 @@ msgstr ""
msgid "Your public email will be displayed on your public profile."
msgstr ""
-msgid "Your request for access could not be processed: %{error_meesage}"
+msgid "Your request for access could not be processed: %{error_message}"
msgstr ""
msgid "Your request for access has been queued for review."
@@ -41948,6 +42800,9 @@ msgstr ""
msgid "archived:"
msgstr ""
+msgid "artifacts"
+msgstr ""
+
msgid "assign yourself"
msgstr ""
@@ -41977,6 +42832,9 @@ msgstr[1] ""
msgid "branch name"
msgstr ""
+msgid "builds"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -42400,6 +43258,9 @@ msgstr ""
msgid "contact with same email already exists in group hierarchy"
msgstr ""
+msgid "container registry images"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -42439,6 +43300,9 @@ msgstr ""
msgid "data"
msgstr ""
+msgid "database"
+msgstr ""
+
msgid "date must not be after 9999-12-31"
msgstr ""
@@ -42462,9 +43326,6 @@ msgstr ""
msgid "design"
msgstr ""
-msgid "detached"
-msgstr ""
-
msgid "disabled"
msgstr ""
@@ -42713,7 +43574,7 @@ msgstr ""
msgid "is not a valid X509 certificate."
msgstr ""
-msgid "is not allowed for sign-up."
+msgid "is not allowed for sign-up. Please use your regular email address."
msgstr ""
msgid "is not allowed for this group."
@@ -42725,7 +43586,7 @@ msgstr ""
msgid "is not allowed since the group is not top-level group."
msgstr ""
-msgid "is not allowed."
+msgid "is not allowed. Please use your regular email address."
msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
@@ -42812,6 +43673,9 @@ msgstr ""
msgid "level: %{level}"
msgstr ""
+msgid "lfs objects"
+msgstr ""
+
msgid "limit of %{project_limit} reached"
msgstr ""
@@ -43031,6 +43895,9 @@ msgstr ""
msgid "mrWidget|Merge blocked: pipeline must succeed. It's waiting for a manual action to continue."
msgstr ""
+msgid "mrWidget|Merge blocked: pipeline must succeed. Push a commit that fixes the failure, or %{linkStart}learn about other solutions.%{linkEnd}"
+msgstr ""
+
msgid "mrWidget|Merge blocked: this merge request must be approved."
msgstr ""
@@ -43148,9 +44015,6 @@ msgstr ""
msgid "mrWidget|The changes were not merged into"
msgstr ""
-msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -43298,9 +44162,6 @@ msgstr ""
msgid "open issue"
msgstr ""
-msgid "opened %{timeAgo}"
-msgstr ""
-
msgid "or"
msgstr ""
@@ -43312,6 +44173,12 @@ msgid_plural "out of %d total tests"
msgstr[0] ""
msgstr[1] ""
+msgid "packages"
+msgstr ""
+
+msgid "pages"
+msgstr ""
+
msgid "parent"
msgid_plural "parents"
msgstr[0] ""
@@ -43461,6 +44328,9 @@ msgid_plural "replies"
msgstr[0] ""
msgstr[1] ""
+msgid "repositories"
+msgstr ""
+
msgid "repository:"
msgstr ""
@@ -43581,12 +44451,18 @@ msgstr ""
msgid "tag name"
msgstr ""
+msgid "terraform states"
+msgstr ""
+
msgid "the correct format."
msgstr ""
msgid "the file"
msgstr ""
+msgid "the following epic(s)"
+msgstr ""
+
msgid "the following issue(s)"
msgstr ""
@@ -43599,21 +44475,12 @@ msgstr ""
msgid "this document"
msgstr ""
-msgid "this issue cannot be assigned to a confidential epic since it is public"
-msgstr ""
-
-msgid "this issue cannot be made public since it belongs to a confidential epic"
-msgstr ""
-
msgid "time summary"
msgstr ""
msgid "toggle collapse"
msgstr ""
-msgid "train"
-msgstr ""
-
msgid "triggered"
msgstr ""
@@ -43742,3 +44609,6 @@ msgstr ""
msgid "{project}"
msgstr ""
+msgid "✔"
+msgstr ""
+
diff --git a/locale/pa_IN/gitlab.po b/locale/pa_IN/gitlab.po
index 5627e5655ad..883bb20e85f 100644
--- a/locale/pa_IN/gitlab.po
+++ b/locale/pa_IN/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: pa-IN\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2022-02-02 15:46\n"
+"PO-Revision-Date: 2022-03-01 20:40\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -146,6 +146,11 @@ msgid_plural "%d approvers (you've approved)"
msgstr[0] ""
msgstr[1] ""
+msgid "%d assigned issue"
+msgid_plural "%d assigned issues"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -421,8 +426,23 @@ msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
msgstr[1] ""
-msgid "%d vulnerability updated"
-msgid_plural "%d vulnerabilities updated"
+msgid "%d vulnerability set to confirmed"
+msgid_plural "%d vulnerabilities set to confirmed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to dismissed"
+msgid_plural "%d vulnerabilities set to dismissed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to needs triage"
+msgid_plural "%d vulnerabilities set to needs triage"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to resolved"
+msgid_plural "%d vulnerabilities set to resolved"
msgstr[0] ""
msgstr[1] ""
@@ -510,6 +530,12 @@ msgstr[1] ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{completed} of %{total} issues closed"
+msgstr ""
+
+msgid "%{completed} of %{total} weight completed"
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -858,6 +884,9 @@ msgstr ""
msgid "%{openedIssues} open, %{closedIssues} closed"
msgstr ""
+msgid "%{percentage}%% issues closed"
+msgstr ""
+
msgid "%{percentage}%% weight completed"
msgstr ""
@@ -1287,6 +1316,9 @@ msgid_plural "- Users"
msgstr[0] ""
msgstr[1] ""
+msgid "- of - issues closed"
+msgstr ""
+
msgid "- of - weight completed"
msgstr ""
@@ -1429,7 +1461,7 @@ msgstr ""
msgid "1000+"
msgstr ""
-msgid "192.168.0.0/24"
+msgid "192.168.0.0/24 or 2001:0DB8:1234::/48"
msgstr ""
msgid "1st contribution!"
@@ -1741,13 +1773,13 @@ msgstr ""
msgid "AWS Access Key"
msgstr ""
-msgid "AWS Access Key. Only required if not using role instance credentials"
+msgid "AWS Secret Access Key"
msgstr ""
-msgid "AWS Secret Access Key"
+msgid "AWS access key ID (Optional)"
msgstr ""
-msgid "AWS Secret Access Key. Only required if not using role instance credentials"
+msgid "AWS secret access key (Optional)"
msgstr ""
msgid "AWS service error: %{error}"
@@ -1807,9 +1839,6 @@ msgstr ""
msgid "Access granted"
msgstr ""
-msgid "Access key ID"
-msgstr ""
-
msgid "Access requests"
msgstr ""
@@ -1984,7 +2013,7 @@ msgstr ""
msgid "Activity"
msgstr ""
-msgid "Activity|An error occured while retrieving activity. Reload the page to try again."
+msgid "Activity|An error occurred while retrieving activity. Reload the page to try again."
msgstr ""
msgid "Add"
@@ -2023,6 +2052,9 @@ msgstr ""
msgid "Add a %{type}"
msgstr ""
+msgid "Add a GCP region"
+msgstr ""
+
msgid "Add a GPG key"
msgstr ""
@@ -2074,6 +2106,9 @@ msgstr ""
msgid "Add a numbered list"
msgstr ""
+msgid "Add a related epic"
+msgstr ""
+
msgid "Add a related issue"
msgstr ""
@@ -2188,6 +2223,9 @@ msgstr ""
msgid "Add or subtract spent time"
msgstr ""
+msgid "Add people"
+msgstr ""
+
msgid "Add previously merged commits"
msgstr ""
@@ -2254,6 +2292,9 @@ msgstr ""
msgid "Add webhook"
msgstr ""
+msgid "Add your team members and others to GitLab."
+msgstr ""
+
msgid "Add/remove"
msgstr ""
@@ -3076,12 +3117,6 @@ msgstr ""
msgid "AdvancedSearch|Reindex required"
msgstr ""
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. Permanently deleting this project will %{strongStart}immediately delete%{strongEnd} its repositories and %{strongStart}all related resources%{strongEnd}, including issues, merge requests etc."
-msgstr ""
-
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. You will lose this project's repository and %{strongStart}all related resources%{strongEnd}, including issues and merge requests."
-msgstr ""
-
msgid "After a successful password update you will be redirected to login screen."
msgstr ""
@@ -3112,6 +3147,9 @@ msgstr ""
msgid "Akismet helps prevent the creation of spam issues in public projects."
msgstr ""
+msgid "Alert"
+msgstr ""
+
msgid "AlertManagement|Acknowledged"
msgstr ""
@@ -3484,9 +3522,6 @@ msgstr ""
msgid "All environments"
msgstr ""
-msgid "All epics"
-msgstr ""
-
msgid "All groups and projects"
msgstr ""
@@ -4223,12 +4258,15 @@ msgstr ""
msgid "ApplicationSettings|Approve users in the pending approval status?"
msgstr ""
-msgid "ApplicationSettings|By making this change, you will automatically approve %d user with the pending approval status."
-msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users with the pending approval status."
+msgid "ApplicationSettings|Approve users who are pending approval?"
+msgstr ""
+
+msgid "ApplicationSettings|By making this change, you will automatically approve %d user who is pending approval."
+msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users who are pending approval."
msgstr[0] ""
msgstr[1] ""
-msgid "ApplicationSettings|By making this change, you will automatically approve all users in pending approval status."
+msgid "ApplicationSettings|By making this change, you will automatically approve all users who are pending approval."
msgstr ""
msgid "ApplicationSettings|Denied domains for sign-ups"
@@ -4634,10 +4672,10 @@ msgstr ""
msgid "Archiving the project will make it entirely read-only. It is hidden from the dashboard and doesn't show up in searches. %{strong_start}The repository cannot be committed to, and no issues, comments, or other entities can be created.%{strong_end} %{link_start}Learn more.%{link_end}"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to delete this project?"
+msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
+msgid "Are you absolutely sure?"
msgstr ""
msgid "Are you sure that you want to archive this project?"
@@ -4673,12 +4711,18 @@ msgstr ""
msgid "Are you sure you want to delete this SSH key?"
msgstr ""
+msgid "Are you sure you want to delete this comment?"
+msgstr ""
+
msgid "Are you sure you want to delete this deploy key?"
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 label?"
+msgstr ""
+
msgid "Are you sure you want to delete this pipeline schedule?"
msgstr ""
@@ -4694,9 +4738,6 @@ msgstr ""
msgid "Are you sure you want to discard your changes?"
msgstr ""
-msgid "Are you sure you want to erase this build?"
-msgstr ""
-
msgid "Are you sure you want to import %d repository?"
msgid_plural "Are you sure you want to import %d repositories?"
msgstr[0] ""
@@ -4744,6 +4785,9 @@ msgstr ""
msgid "Are you sure you want to remove this list?"
msgstr ""
+msgid "Are you sure you want to remove this nickname?"
+msgstr ""
+
msgid "Are you sure you want to reset the health check token?"
msgstr ""
@@ -4756,10 +4800,10 @@ 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?"
+msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
msgstr ""
-msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
+msgid "Are you sure you want to revoke this project access token? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to stop this environment?"
@@ -4906,9 +4950,6 @@ msgstr ""
msgid "Assigned to %{assignee_name}"
msgstr ""
-msgid "Assigned to %{name}"
-msgstr ""
-
msgid "Assigned to me"
msgstr ""
@@ -4973,6 +5014,9 @@ msgstr[1] ""
msgid "Attaching the file failed."
msgstr ""
+msgid "Attention"
+msgstr ""
+
msgid "Audit Events"
msgstr ""
@@ -5135,6 +5179,12 @@ msgstr ""
msgid "Authorized applications (%{size})"
msgstr ""
+msgid "AuthorizedApplication|Are you sure you want to revoke this application?"
+msgstr ""
+
+msgid "AuthorizedApplication|Revoke application"
+msgstr ""
+
msgid "Authors: %{authors}"
msgstr ""
@@ -6328,6 +6378,9 @@ msgstr ""
msgid "CICDAnalytics|Shared Runners Usage"
msgstr ""
+msgid "CICDAnalytics|Shared runner pipeline minute duration by month"
+msgstr ""
+
msgid "CICDAnalytics|Shared runner usage"
msgstr ""
@@ -6469,6 +6522,9 @@ msgstr ""
msgid "Can create groups:"
msgstr ""
+msgid "Can not delete primary training"
+msgstr ""
+
msgid "Can't apply as the source branch was deleted."
msgstr ""
@@ -6802,9 +6858,6 @@ msgstr ""
msgid "Changing any setting here requires an application restart"
msgstr ""
-msgid "Changing group URL can have unintended side effects."
-msgstr ""
-
msgid "Charts can't be displayed as the request for data has timed out. %{documentationLink}"
msgstr ""
@@ -6892,9 +6945,6 @@ msgstr ""
msgid "Checking branch availability..."
msgstr ""
-msgid "Checking group URL availability..."
-msgstr ""
-
msgid "Checking group path availability..."
msgstr ""
@@ -7388,6 +7438,9 @@ msgstr ""
msgid "Clear recent searches"
msgstr ""
+msgid "Clear repository checks"
+msgstr ""
+
msgid "Clear search"
msgstr ""
@@ -7520,9 +7573,6 @@ msgstr ""
msgid "Closed MRs"
msgstr ""
-msgid "Closed epics"
-msgstr ""
-
msgid "Closed issues"
msgstr ""
@@ -7559,13 +7609,13 @@ msgstr ""
msgid "Cluster level"
msgstr ""
-msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
+msgid "Cluster type must be specified for Stages::ClusterEndpointInserter"
msgstr ""
msgid "ClusterAgents|%{name} successfully deleted"
msgstr ""
-msgid "ClusterAgents|%{number} of %{total} Agents"
+msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
@@ -7607,6 +7657,15 @@ msgstr ""
msgid "ClusterAgents|Agent never connected to GitLab"
msgstr ""
+msgid "ClusterAgents|Agent version mismatch"
+msgstr ""
+
+msgid "ClusterAgents|Agent version mismatch and update"
+msgstr ""
+
+msgid "ClusterAgents|Agent version update required"
+msgstr ""
+
msgid "ClusterAgents|All"
msgstr ""
@@ -7631,7 +7690,7 @@ msgstr ""
msgid "ClusterAgents|Configuration"
msgstr ""
-msgid "ClusterAgents|Connect a cluster through the Agent"
+msgid "ClusterAgents|Connect a cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connect existing cluster"
@@ -7640,13 +7699,13 @@ msgstr ""
msgid "ClusterAgents|Connect with a certificate"
msgstr ""
-msgid "ClusterAgents|Connect with agent"
+msgid "ClusterAgents|Connect with an agent"
msgstr ""
msgid "ClusterAgents|Connect with the GitLab Agent"
msgstr ""
-msgid "ClusterAgents|Connect your cluster through the Agent"
+msgid "ClusterAgents|Connect your cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connected"
@@ -7706,7 +7765,10 @@ msgstr ""
msgid "ClusterAgents|How to register an agent?"
msgstr ""
-msgid "ClusterAgents|Install new Agent"
+msgid "ClusterAgents|How to update an agent?"
+msgstr ""
+
+msgid "ClusterAgents|Install a new agent"
msgstr ""
msgid "ClusterAgents|Last connected %{timeAgo}."
@@ -7733,7 +7795,7 @@ msgstr ""
msgid "ClusterAgents|Never connected"
msgstr ""
-msgid "ClusterAgents|No Agents"
+msgid "ClusterAgents|No agents"
msgstr ""
msgid "ClusterAgents|No clusters connected through cluster certificates"
@@ -7793,6 +7855,9 @@ msgstr ""
msgid "ClusterAgents|The agent has not been connected in a long time. There might be a connectivity issue. Last contact was %{timeAgo}."
msgstr ""
+msgid "ClusterAgents|The agent version do not match each other across your cluster's pods. This can happen when a new agent version was just deployed and Kubernetes is shutting down the old pods."
+msgstr ""
+
msgid "ClusterAgents|The recommended installation method includes the token. If you want to follow the advanced installation method provided in the docs, make sure you save the token value before you close this window."
msgstr ""
@@ -7840,6 +7905,9 @@ msgstr ""
msgid "ClusterAgents|You will need to create a token to connect to your agent"
msgstr ""
+msgid "ClusterAgents|Your agent version is out of sync with your GitLab version (v%{version}), which might cause compatibility problems. Update the agent installed on your cluster to the most recent version."
+msgstr ""
+
msgid "ClusterAgents|Your instance doesn't have the %{linkStart}GitLab Agent Server (KAS)%{linkEnd} set up. Ask a GitLab Administrator to install it."
msgstr ""
@@ -8716,9 +8784,6 @@ msgstr ""
msgid "Comma-separated list of email addresses."
msgstr ""
-msgid "Comma-separated list of users allowed to exceed the rate limit."
-msgstr ""
-
msgid "Comma-separated, e.g. '1.1.1.1, 2.2.2.0/24'"
msgstr ""
@@ -9045,6 +9110,12 @@ msgstr ""
msgid "Confidential"
msgstr ""
+msgid "Confidential issue"
+msgstr ""
+
+msgid "Confidential note"
+msgstr ""
+
msgid "Confidentiality"
msgstr ""
@@ -9078,6 +9149,9 @@ msgstr ""
msgid "Configure Dependency Scanning in `.gitlab-ci.yml`, creating this file if it does not already exist"
msgstr ""
+msgid "Configure GitLab"
+msgstr ""
+
msgid "Configure GitLab runners to start using the Web Terminal. %{helpStart}Learn more.%{helpEnd}"
msgstr ""
@@ -9126,6 +9200,15 @@ msgstr ""
msgid "Configure pipelines to deploy web apps, backend services, APIs and static resources to Google Cloud"
msgstr ""
+msgid "Configure region"
+msgstr ""
+
+msgid "Configure region for environment"
+msgstr ""
+
+msgid "Configure regions"
+msgstr ""
+
msgid "Configure repository mirroring."
msgstr ""
@@ -9159,6 +9242,9 @@ msgstr ""
msgid "Configure which lists are shown for anyone who visits this board"
msgstr ""
+msgid "Configure your environments to be deployed to specific geographical regions"
+msgstr ""
+
msgid "Confirm"
msgstr ""
@@ -9861,10 +9947,10 @@ msgstr ""
msgid "CorpusManagement|Actions"
msgstr ""
-msgid "CorpusManagement|Corpus are used in fuzz testing as mutation source to Improve future testing."
+msgid "CorpusManagement|Corpus file"
msgstr ""
-msgid "CorpusManagement|Corpus file"
+msgid "CorpusManagement|Corpus files are used in coverage-guided fuzz testing as seed inputs to improve testing."
msgstr ""
msgid "CorpusManagement|Corpus files must be in *.zip format. Maximum 5 GB"
@@ -9918,6 +10004,9 @@ msgstr ""
msgid "Could not apply %{name} command."
msgstr ""
+msgid "Could not apply %{name} command. %{message}."
+msgstr ""
+
msgid "Could not authorize chat nickname. Try again!"
msgstr ""
@@ -10068,6 +10157,9 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
+msgid "Create a group"
+msgstr ""
+
msgid "Create a merge request"
msgstr ""
@@ -10092,6 +10184,9 @@ msgstr ""
msgid "Create a personal access token on your account to pull or push via %{protocol}."
msgstr ""
+msgid "Create a project"
+msgstr ""
+
msgid "Create an account using:"
msgstr ""
@@ -10455,6 +10550,9 @@ msgstr ""
msgid "Creation date"
msgstr ""
+msgid "Creator"
+msgstr ""
+
msgid "Credentials"
msgstr ""
@@ -10467,9 +10565,15 @@ msgstr ""
msgid "CredentialsInventory|Personal Access Tokens"
msgstr ""
+msgid "CredentialsInventory|Project Access Tokens"
+msgstr ""
+
msgid "CredentialsInventory|SSH Keys"
msgstr ""
+msgid "Credit card required to be on file in order to create a pipeline"
+msgstr ""
+
msgid "Credit card:"
msgstr ""
@@ -10653,9 +10757,6 @@ msgstr ""
msgid "Customer relations"
msgstr ""
-msgid "Customizable by an administrator."
-msgstr ""
-
msgid "Customizable by owners."
msgstr ""
@@ -10785,30 +10886,18 @@ msgstr ""
msgid "CycleAnalytics|%{selectedLabelsCount} selected (%{maxLabels} max)"
msgstr ""
-msgid "CycleAnalytics|%{stageCount} stages selected"
-msgstr ""
-
-msgid "CycleAnalytics|All stages"
-msgstr ""
-
-msgid "CycleAnalytics|Average days to completion"
+msgid "CycleAnalytics|Average time to completion"
msgstr ""
msgid "CycleAnalytics|Date"
msgstr ""
-msgid "CycleAnalytics|Days to completion"
-msgstr ""
-
msgid "CycleAnalytics|Display chart filters"
msgstr ""
msgid "CycleAnalytics|Lead Time for Changes"
msgstr ""
-msgid "CycleAnalytics|No stages selected"
-msgstr ""
-
msgid "CycleAnalytics|Number of tasks"
msgstr ""
@@ -10837,18 +10926,30 @@ msgstr ""
msgid "CycleAnalytics|Showing data for group '%{groupName}' from %{createdAfter} to %{createdBefore}"
msgstr ""
-msgid "CycleAnalytics|Stages"
+msgid "CycleAnalytics|Stage time: %{title}"
msgstr ""
msgid "CycleAnalytics|Tasks by type"
msgstr ""
-msgid "CycleAnalytics|The average time spent in the selected stage for the items that were completed on each date. Data limited to the last 500 items."
+msgid "CycleAnalytics|The average time items spent in this stage. Data limited to items completed within this date range."
msgstr ""
msgid "CycleAnalytics|The given date range is larger than 180 days"
msgstr ""
+msgid "CycleAnalytics|The total time items spent across each value stream stage. Data limited to items completed within this date range."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Stage time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Total time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|Total time"
+msgstr ""
+
msgid "CycleAnalytics|Type of work"
msgstr ""
@@ -10861,9 +10962,6 @@ msgstr ""
msgid "CycleAnalytics|project dropdown filter"
msgstr ""
-msgid "CycleAnalytics|stage dropdown"
-msgstr ""
-
msgid "DAG visualization requires at least 3 dependent jobs."
msgstr ""
@@ -10963,10 +11061,16 @@ msgstr ""
msgid "DastProfiles|AJAX spider"
msgstr ""
+msgid "DastProfiles|API"
+msgstr ""
+
+msgid "DastProfiles|API endpoint URL"
+msgstr ""
+
msgid "DastProfiles|Active"
msgstr ""
-msgid "DastProfiles|Additional request headers (Optional)"
+msgid "DastProfiles|Additional request headers (optional)"
msgstr ""
msgid "DastProfiles|Are you sure you want to delete this profile?"
@@ -10981,6 +11085,9 @@ msgstr ""
msgid "DastProfiles|Branch missing"
msgstr ""
+msgid "DastProfiles|Choose a scan method"
+msgstr ""
+
msgid "DastProfiles|Could not create the scanner profile. Please try again."
msgstr ""
@@ -11050,7 +11157,13 @@ msgstr ""
msgid "DastProfiles|Excluded URLs"
msgstr ""
-msgid "DastProfiles|Excluded URLs (Optional)"
+msgid "DastProfiles|Excluded URLs (optional)"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths (optional)"
msgstr ""
msgid "DastProfiles|Hide debug messages"
@@ -11107,9 +11220,6 @@ msgstr ""
msgid "DastProfiles|Request headers"
msgstr ""
-msgid "DastProfiles|Rest API"
-msgstr ""
-
msgid "DastProfiles|Run the AJAX spider, in addition to the traditional spider, to crawl the target site."
msgstr ""
@@ -11119,6 +11229,9 @@ msgstr ""
msgid "DastProfiles|Save profile"
msgstr ""
+msgid "DastProfiles|Scan method"
+msgstr ""
+
msgid "DastProfiles|Scan mode"
msgstr ""
@@ -11197,12 +11310,24 @@ msgstr ""
msgid "DastProfiles|Website"
msgstr ""
+msgid "DastProfiles|What does each method do?"
+msgstr ""
+
msgid "DastProfiles|You can either choose a passive scan or validate the target site from the site profile management page. %{docsLinkStart}Learn more about site validation.%{docsLinkEnd}"
msgstr ""
msgid "DastProfiles|You cannot run an active scan against an unvalidated site."
msgstr ""
+msgid "DastProfiles|folder/dast_example.har or https://example.com/dast_example.har"
+msgstr ""
+
+msgid "DastProfiles|folder/example.postman_collection.json or https://example.com/"
+msgstr ""
+
+msgid "DastProfiles|folder/openapi.json or https://example.com/openapi.json"
+msgstr ""
+
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
@@ -11310,6 +11435,9 @@ msgstr ""
msgid "DatadogIntegration|API URL"
msgstr ""
+msgid "DatadogIntegration|Custom tags in Datadog. Enter one tag per line in the %{codeOpen}key:value%{codeClose} format. %{linkOpen}How do I use tags?%{linkClose}"
+msgstr ""
+
msgid "DatadogIntegration|Environment"
msgstr ""
@@ -11328,12 +11456,18 @@ msgstr ""
msgid "DatadogIntegration|Tag all data from this GitLab instance in Datadog. Useful when managing several self-managed deployments."
msgstr ""
+msgid "DatadogIntegration|Tags"
+msgstr ""
+
msgid "DatadogIntegration|The Datadog site to send data to. To send data to the EU site, use %{codeOpen}datadoghq.eu%{codeClose}."
msgstr ""
msgid "DatadogIntegration|Trace your GitLab pipelines with Datadog."
msgstr ""
+msgid "DatadogIntegration|have an invalid format"
+msgstr ""
+
msgid "Datasource name not found"
msgstr ""
@@ -11343,9 +11477,6 @@ msgstr ""
msgid "Date merged"
msgstr ""
-msgid "Date picker"
-msgstr ""
-
msgid "Date range"
msgstr ""
@@ -11499,9 +11630,6 @@ msgstr ""
msgid "Definition"
msgstr ""
-msgid "Delayed Project Deletion (%{adjourned_deletion})"
-msgstr ""
-
msgid "DelayedJobs|Are you sure you want to run %{jobName} immediately? Otherwise this job will run automatically after its timer finishes."
msgstr ""
@@ -11580,10 +11708,10 @@ msgstr ""
msgid "Delete pipeline"
msgstr ""
-msgid "Delete project"
+msgid "Delete pipeline schedule"
msgstr ""
-msgid "Delete project. Are you ABSOLUTELY SURE?"
+msgid "Delete project"
msgstr ""
msgid "Delete row"
@@ -11613,6 +11741,9 @@ msgstr ""
msgid "Delete this epic and all descendants?"
msgstr ""
+msgid "Delete this project"
+msgstr ""
+
msgid "Delete user list"
msgstr ""
@@ -11871,6 +12002,12 @@ msgstr ""
msgid "Deploy to..."
msgstr ""
+msgid "DeployBoards|To see deployment progress for your environments, make sure you are deploying to %{codeStart}$KUBE_NAMESPACE%{codeEnd} and annotating with %{codeStart}app.gitlab.com/app=$CI_PROJECT_PATH_SLUG%{codeEnd} and %{codeStart}app.gitlab.com/env=$CI_ENVIRONMENT_SLUG%{codeEnd}."
+msgstr ""
+
+msgid "DeployBoard|Kubernetes Pods"
+msgstr ""
+
msgid "DeployFreeze|Add a freeze period to prevent unintended releases during a period of time for a given environment. You must update the deployment jobs in %{filename} according to the deploy freezes added here. %{freeze_period_link_start}Learn more.%{freeze_period_link_end}"
msgstr ""
@@ -11955,9 +12092,6 @@ msgstr ""
msgid "DeployTokens|Active Deploy Tokens (%{active_tokens})"
msgstr ""
-msgid "DeployTokens|Allows read and write access to registry images."
-msgstr ""
-
msgid "DeployTokens|Allows read and write access to the package registry."
msgstr ""
@@ -11970,6 +12104,9 @@ msgstr ""
msgid "DeployTokens|Allows read-only access to the repository."
msgstr ""
+msgid "DeployTokens|Allows write access to registry images."
+msgstr ""
+
msgid "DeployTokens|Copy deploy token"
msgstr ""
@@ -12063,12 +12200,57 @@ msgstr ""
msgid "Deploying to AWS is easy with GitLab"
msgstr ""
+msgid "Deployment"
+msgstr ""
+
msgid "Deployment Frequency"
msgstr ""
+msgid "Deployment Target|Project deployment target (optional)"
+msgstr ""
+
+msgid "Deployment Target|Select the deployment target"
+msgstr ""
+
msgid "Deployment frequency"
msgstr ""
+msgid "DeploymentTarget|GitLab Pages"
+msgstr ""
+
+msgid "DeploymentTarget|Heroku"
+msgstr ""
+
+msgid "DeploymentTarget|Infrastructure provider (Terraform, Cloudformation, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Kubernetes (GKE, EKS, OpenShift, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Managed container runtime (Fargate, Cloud Run, DigitalOcean App)"
+msgstr ""
+
+msgid "DeploymentTarget|Mobile app store"
+msgstr ""
+
+msgid "DeploymentTarget|No deployment planned"
+msgstr ""
+
+msgid "DeploymentTarget|Other hosting service"
+msgstr ""
+
+msgid "DeploymentTarget|Registry (package or container)"
+msgstr ""
+
+msgid "DeploymentTarget|Self-managed container runtime (Podman, Docker Swarm, Docker Compose)"
+msgstr ""
+
+msgid "DeploymentTarget|Serverless backend (Lambda, Cloud functions)"
+msgstr ""
+
+msgid "DeploymentTarget|Virtual machine (for example, EC2)"
+msgstr ""
+
msgid "Deployments"
msgstr ""
@@ -12107,6 +12289,9 @@ msgstr ""
msgid "Deployment|This deployment was created using the API"
msgstr ""
+msgid "Deployment|Triggerer"
+msgstr ""
+
msgid "Deployment|Waiting"
msgstr ""
@@ -12134,6 +12319,18 @@ msgstr ""
msgid "Deprecated API rate limits"
msgstr ""
+msgid "Deprecations|Feature deprecation and removal"
+msgstr ""
+
+msgid "Deprecations|For information on a possible replacement %{epicStart} learn more about Opstrace %{epicEnd}."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7 and are %{epicStart} scheduled for removal %{epicEnd} in GitLab 15.0."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7, and are %{removal_link_start} scheduled for removal %{link_end} in GitLab 15.0. For information on a possible replacement, %{opstrace_link_start} learn more about Opstrace %{link_end}."
+msgstr ""
+
msgid "Deprioritize label"
msgstr ""
@@ -12379,10 +12576,10 @@ msgstr ""
msgid "DevopsAdoption|At least one deploy"
msgstr ""
-msgid "DevopsAdoption|At least one issue opened"
+msgid "DevopsAdoption|At least one issue created"
msgstr ""
-msgid "DevopsAdoption|At least one merge request opened"
+msgid "DevopsAdoption|At least one merge request created"
msgstr ""
msgid "DevopsAdoption|At least one pipeline successfully run"
@@ -12583,6 +12780,9 @@ msgstr ""
msgid "Direct member"
msgstr ""
+msgid "Direct members"
+msgstr ""
+
msgid "Direct non-authenticated users to this page."
msgstr ""
@@ -12699,6 +12899,9 @@ msgid_plural "Dismiss %d selected vulnerabilities as"
msgstr[0] ""
msgstr[1] ""
+msgid "Dismiss Alert"
+msgstr ""
+
msgid "Dismiss merge request promotion"
msgstr ""
@@ -12726,9 +12929,15 @@ msgstr ""
msgid "Display alerts from all configured monitoring tools."
msgstr ""
+msgid "Display milestones"
+msgstr ""
+
msgid "Display name"
msgstr ""
+msgid "Display progress of child issues"
+msgstr ""
+
msgid "Display rendered file"
msgstr ""
@@ -12834,6 +13043,9 @@ msgstr ""
msgid "Download image"
msgstr ""
+msgid "Download payload"
+msgstr ""
+
msgid "Download raw data (.csv)"
msgstr ""
@@ -13011,6 +13223,9 @@ msgstr ""
msgid "Edit in Web IDE"
msgstr ""
+msgid "Edit in pipeline editor"
+msgstr ""
+
msgid "Edit in single-file editor"
msgstr ""
@@ -13053,6 +13268,9 @@ msgstr ""
msgid "Edit your most recent comment in a thread (from an empty textarea)"
msgstr ""
+msgid "Edit, lint, and visualize your pipeline."
+msgstr ""
+
msgid "Edited"
msgstr ""
@@ -13494,6 +13712,9 @@ msgstr ""
msgid "Enforce two-factor authentication for all user sign-ins."
msgstr ""
+msgid "Enhance security by storing service account keys in secret managers - learn more about %{docLinkStart}secret management with GitLab%{docLinkEnd}"
+msgstr ""
+
msgid "Ensure connectivity is available from the GitLab server to the Prometheus server"
msgstr ""
@@ -13554,6 +13775,9 @@ 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 following to confirm:"
+msgstr ""
+
msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
@@ -14084,9 +14308,6 @@ 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 ""
@@ -14222,6 +14443,9 @@ msgstr ""
msgid "Errors:"
msgstr ""
+msgid "Escalate this incident"
+msgstr ""
+
msgid "Escalation Policies"
msgstr ""
@@ -14234,6 +14458,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy"
+msgstr ""
+
msgid "Escalation policy:"
msgstr ""
@@ -14485,6 +14712,9 @@ msgstr ""
msgid "Existing sign in methods may be removed"
msgstr ""
+msgid "Exit."
+msgstr ""
+
msgid "Expand"
msgstr ""
@@ -14581,6 +14811,9 @@ msgstr ""
msgid "Explore public groups"
msgstr ""
+msgid "Explore public projects"
+msgstr ""
+
msgid "Explore snippets"
msgstr ""
@@ -14742,7 +14975,7 @@ msgid_plural "Failed to archive designs. Please try again."
msgstr[0] ""
msgstr[1] ""
-msgid "Failed to assign a reviewer because no user was found."
+msgid "Failed to assign a reviewer because no user was specified."
msgstr ""
msgid "Failed to assign a user because no user was found."
@@ -14808,10 +15041,10 @@ msgstr ""
msgid "Failed to find import label for Jira import."
msgstr ""
-msgid "Failed to generate export, please try again later."
+msgid "Failed to find users for %{missing}"
msgstr ""
-msgid "Failed to generate report, please try again after sometime"
+msgid "Failed to generate export, please try again later."
msgstr ""
msgid "Failed to get ref."
@@ -14910,6 +15143,9 @@ msgstr ""
msgid "Failed to remove a to-do item for the design."
msgstr ""
+msgid "Failed to remove attention because no user was found."
+msgstr ""
+
msgid "Failed to remove mirror."
msgstr ""
@@ -14922,6 +15158,9 @@ msgstr ""
msgid "Failed to remove user key."
msgstr ""
+msgid "Failed to request attention because no user was found."
+msgstr ""
+
msgid "Failed to reset key. Please try again."
msgstr ""
@@ -15003,6 +15242,9 @@ msgstr ""
msgid "Feature Flags"
msgstr ""
+msgid "Feature deprecation and removal"
+msgstr ""
+
msgid "Feature flag status"
msgstr ""
@@ -15500,7 +15742,7 @@ msgstr ""
msgid "For each job, re-use the project workspace. If the workspace doesn't exist, use %{code_open}git clone%{code_close}."
msgstr ""
-msgid "For example, the application using the token or the purpose of the token."
+msgid "For example, the application using the token or the purpose of the token. Do not give sensitive information for the name of the token, as it will be visible to all %{resource_type} members."
msgstr ""
msgid "For files larger than this limit, only index the file name. The file content is neither indexed nor searchable."
@@ -15584,9 +15826,6 @@ msgstr ""
msgid "ForkProject|Select a namespace"
msgstr ""
-msgid "ForkProject|Select a namespace to fork the project"
-msgstr ""
-
msgid "ForkProject|The project can be accessed by any logged in user."
msgstr ""
@@ -15683,6 +15922,9 @@ msgstr ""
msgid "Full name"
msgstr ""
+msgid "GCP region configured"
+msgstr ""
+
msgid "GPG Key ID:"
msgstr ""
@@ -15863,6 +16105,9 @@ msgstr ""
msgid "Geo|Failed"
msgstr ""
+msgid "Geo|Filter Geo sites"
+msgstr ""
+
msgid "Geo|Filter by name"
msgstr ""
@@ -16274,6 +16519,12 @@ msgstr ""
msgid "GitLab Issue"
msgstr ""
+msgid "GitLab KAS"
+msgstr ""
+
+msgid "GitLab Memberships CSV Export"
+msgstr ""
+
msgid "GitLab Pages"
msgstr ""
@@ -16322,6 +16573,9 @@ 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 free to use. Many features for larger teams are part of our %{link_start}paid products%{link_end}. You can try Ultimate for free without any obligation or payment details."
+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 ""
@@ -16448,7 +16702,7 @@ msgstr ""
msgid "GitLabPages|When enabled, all attempts to visit your website through HTTP are automatically redirected to HTTPS using a response with status code 301. Requires a valid certificate for all domains. %{docs_link_start}Learn more.%{link_end}"
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. %{docs_link_start}Learn more.%{link_end}"
+msgid "GitLabPages|When using Pages under the general domain of a GitLab instance (%{pages_host}), you cannot use HTTPS with subdomains of subdomains. If your namespace or groupname contains a dot, it does not work. This is a limitation of the HTTP Over TLS protocol. HTTP pages work if you don't redirect HTTP to HTTPS. %{docs_link_start}Learn more.%{link_end}"
msgstr ""
msgid "GitLabPages|With GitLab Pages you can host your static website directly from your GitLab repository. %{docs_link_start}Learn more.%{link_end}"
@@ -16625,9 +16879,6 @@ msgstr ""
msgid "Go to find file"
msgstr ""
-msgid "Go to fork"
-msgstr ""
-
msgid "Go to issue boards"
msgstr ""
@@ -16835,9 +17086,6 @@ msgstr ""
msgid "Group Hooks"
msgstr ""
-msgid "Group ID"
-msgstr ""
-
msgid "Group Owner must have signed in with SAML before enabling Group Managed Accounts"
msgstr ""
@@ -16865,9 +17113,6 @@ msgstr ""
msgid "Group by"
msgstr ""
-msgid "Group description"
-msgstr ""
-
msgid "Group description (optional)"
msgstr ""
@@ -16982,7 +17227,7 @@ msgstr ""
msgid "Group: %{name}"
msgstr ""
-msgid "GroupActivityMetrics|Issues opened"
+msgid "GroupActivityMetrics|Issues created"
msgstr ""
msgid "GroupActivityMetrics|Last 90 days"
@@ -16991,7 +17236,7 @@ msgstr ""
msgid "GroupActivityMetrics|Members added"
msgstr ""
-msgid "GroupActivityMetrics|Merge Requests opened"
+msgid "GroupActivityMetrics|Merge Requests created"
msgstr ""
msgid "GroupActivityMetrics|Recent activity"
@@ -17282,6 +17527,9 @@ msgstr ""
msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
+msgid "GroupSettings|Choose a group path that does not start with a dash or end with a period. It can also contain alphanumeric characters and underscores."
+msgstr ""
+
msgid "GroupSettings|Compliance frameworks"
msgstr ""
@@ -17315,7 +17563,7 @@ msgstr ""
msgid "GroupSettings|If not specified at the group or instance level, the default is %{default_initial_branch_name}. Does not affect existing repositories."
msgstr ""
-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."
+msgid "GroupSettings|If the parent group's visibility is lower than the group's current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility."
msgstr ""
msgid "GroupSettings|New runners registration token has been generated!"
@@ -17432,7 +17680,10 @@ msgstr ""
msgid "Groups and projects"
msgstr ""
-msgid "Groups and subgroups"
+msgid "Groups are a great way to organize projects and people."
+msgstr ""
+
+msgid "Groups are the best way to manage projects and members."
msgstr ""
msgid "Groups to synchronize"
@@ -17543,13 +17794,16 @@ msgstr ""
msgid "GroupsTree|Are you sure you want to leave the \"%{fullName}\" group?"
msgstr ""
-msgid "GroupsTree|Edit group"
+msgid "GroupsTree|Delete"
+msgstr ""
+
+msgid "GroupsTree|Edit"
msgstr ""
msgid "GroupsTree|Failed to leave the group. Please make sure you are not the only owner."
msgstr ""
-msgid "GroupsTree|Leave this group"
+msgid "GroupsTree|Leave group"
msgstr ""
msgid "GroupsTree|Loading groups"
@@ -17561,9 +17815,57 @@ msgstr ""
msgid "GroupsTree|No groups or projects matched your search"
msgstr ""
+msgid "GroupsTree|Options"
+msgstr ""
+
msgid "GroupsTree|Search by name"
msgstr ""
+msgid "Groups|Avatar will be removed. Are you sure?"
+msgstr ""
+
+msgid "Groups|Changing group URL can have unintended side effects."
+msgstr ""
+
+msgid "Groups|Checking group URL availability..."
+msgstr ""
+
+msgid "Groups|Enter a descriptive name for your group."
+msgstr ""
+
+msgid "Groups|Group ID"
+msgstr ""
+
+msgid "Groups|Group URL"
+msgstr ""
+
+msgid "Groups|Group avatar"
+msgstr ""
+
+msgid "Groups|Group description (optional)"
+msgstr ""
+
+msgid "Groups|Group name"
+msgstr ""
+
+msgid "Groups|Group path is available."
+msgstr ""
+
+msgid "Groups|Group path is unavailable. Path has been replaced with a suggested available path."
+msgstr ""
+
+msgid "Groups|Learn more"
+msgstr ""
+
+msgid "Groups|Must start with letter, digit, emoji, or underscore. Can also contain periods, dashes, spaces, and parentheses."
+msgstr ""
+
+msgid "Groups|Remove avatar"
+msgstr ""
+
+msgid "Groups|Save changes"
+msgstr ""
+
msgid "Guideline"
msgstr ""
@@ -17573,6 +17875,9 @@ msgstr ""
msgid "HAR file path or URL"
msgstr ""
+msgid "HTTP Archive (HAR)"
+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 ""
@@ -17973,6 +18278,9 @@ msgstr ""
msgid "INFO: Your SSH key is expiring soon. Please generate a new key."
msgstr ""
+msgid "IP"
+msgstr ""
+
msgid "IP Address"
msgstr ""
@@ -18009,6 +18317,9 @@ msgstr ""
msgid "IdentityVerification|Verify your identity"
msgstr ""
+msgid "IdentityVerification|You can always verify your account at a later time to create a group."
+msgstr ""
+
msgid "If any indexed field exceeds this limit, it is truncated to this number of characters. The rest of the content is neither indexed nor searchable. This does not apply to repository and wiki indexing. For unlimited characters, set this to 0."
msgstr ""
@@ -18066,6 +18377,9 @@ msgstr ""
msgid "If you add %{codeStart}needs%{codeEnd} to jobs in your pipeline you'll be able to view the %{codeStart}needs%{codeEnd} relationships between jobs in this tab as a %{linkStart}Directed Acyclic Graph (DAG)%{linkEnd}."
msgstr ""
+msgid "If you are added to a project, it will be displayed here."
+msgstr ""
+
msgid "If you did not initiate these sign-in attempts, please reach out to your administrator or enable two-factor authentication (2FA) on your account."
msgstr ""
@@ -18372,12 +18686,24 @@ msgstr ""
msgid "InProductMarketing|3 ways to dive into GitLab CI/CD"
msgstr ""
+msgid "InProductMarketing|A single application eliminates complex integrations, data chokepoints, and toolchain maintenance, resulting in greater productivity and lower cost."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features, build more efficiently, strengthen security and compliance."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features."
+msgstr ""
+
msgid "InProductMarketing|Actually, GitLab makes the team work (better)"
msgstr ""
msgid "InProductMarketing|And finally %{deploy_link} a Python application."
msgstr ""
+msgid "InProductMarketing|And many more..."
+msgstr ""
+
msgid "InProductMarketing|Are your runners ready?"
msgstr ""
@@ -18396,15 +18722,33 @@ msgstr ""
msgid "InProductMarketing|Blog"
msgstr ""
+msgid "InProductMarketing|Break down silos to coordinate seamlessly across development, operations, and security with a consistent experience across the development lifecycle."
+msgstr ""
+
+msgid "InProductMarketing|Burn up/down charts"
+msgstr ""
+
msgid "InProductMarketing|By enabling code owners and required merge approvals the right person will review the right MR. This is a win-win: cleaner code and a more efficient review process."
msgstr ""
msgid "InProductMarketing|Click on the number below that corresponds with your answer — 1 being very difficult, 5 being very easy."
msgstr ""
+msgid "InProductMarketing|Code owners"
+msgstr ""
+
msgid "InProductMarketing|Code owners and required merge approvals are part of the paid tiers of GitLab. You can start a free 30-day trial of GitLab Ultimate and enable these features in less than 5 minutes with no credit card required."
msgstr ""
+msgid "InProductMarketing|Code review analytics"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration across stages in GitLab"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration made easy"
+msgstr ""
+
msgid "InProductMarketing|Create a custom CI runner with just a few clicks"
msgstr ""
@@ -18414,12 +18758,21 @@ msgstr ""
msgid "InProductMarketing|Create a project in GitLab in 5 minutes"
msgstr ""
+msgid "InProductMarketing|Create well-defined workflows by using scoped labels on issues, merge requests, and epics. Labels with the same scope cannot be used together, which prevents conflicts."
+msgstr ""
+
msgid "InProductMarketing|Create your first project!"
msgstr ""
+msgid "InProductMarketing|Define who owns specific files or directories, so the right reviewers are suggested when a merge request introduces changes to those files."
+msgstr ""
+
msgid "InProductMarketing|Deliver Better Products Faster"
msgstr ""
+msgid "InProductMarketing|Dependency scanning"
+msgstr ""
+
msgid "InProductMarketing|Did you know teams that use GitLab are far more efficient?"
msgstr ""
@@ -18429,15 +18782,27 @@ msgstr ""
msgid "InProductMarketing|Dig in and create a project and a repo"
msgstr ""
+msgid "InProductMarketing|Discover Premium & Ultimate"
+msgstr ""
+
+msgid "InProductMarketing|Discover Premium & Ultimate."
+msgstr ""
+
msgid "InProductMarketing|Do you have a minute?"
msgstr ""
msgid "InProductMarketing|Do you have a teammate who would be perfect for this task?"
msgstr ""
+msgid "InProductMarketing|Dynamic application security testing"
+msgstr ""
+
msgid "InProductMarketing|Easy"
msgstr ""
+msgid "InProductMarketing|Epics"
+msgstr ""
+
msgid "InProductMarketing|Expand your DevOps journey with a free GitLab trial"
msgstr ""
@@ -18459,9 +18824,15 @@ msgstr ""
msgid "InProductMarketing|Feel the need for speed?"
msgstr ""
+msgid "InProductMarketing|Find and fix bottlenecks in your code review process by understanding how long open merge requests have been in review."
+msgstr ""
+
msgid "InProductMarketing|Find out how your teams are really doing"
msgstr ""
+msgid "InProductMarketing|Find out if your external libraries are safe. Run dependency scanning jobs that check for known vulnerabilities in your external libraries."
+msgstr ""
+
msgid "InProductMarketing|Follow our steps"
msgstr ""
@@ -18498,6 +18869,9 @@ msgstr ""
msgid "InProductMarketing|GitLab is better with teammates to help out!"
msgstr ""
+msgid "InProductMarketing|GitLab is infrastructure agnostic (supporting GCP, AWS, Azure, OpenShift, VMWare, On Prem, Bare Metal, and more), offering a consistent workflow experience – irrespective of the environment."
+msgstr ""
+
msgid "InProductMarketing|GitLab provides static application security testing (SAST), dynamic application security testing (DAST), container scanning, and dependency scanning to help you deliver secure applications along with license compliance."
msgstr ""
@@ -18588,21 +18962,36 @@ msgstr ""
msgid "InProductMarketing|It's also possible to simply %{external_repo_link} in order to take advantage of GitLab's CI/CD."
msgstr ""
+msgid "InProductMarketing|Keep your code quality high by defining who should approve merge requests and how many approvals are required."
+msgstr ""
+
msgid "InProductMarketing|Launch GitLab CI/CD in 20 minutes or less"
msgstr ""
+msgid "InProductMarketing|Lower cost of development"
+msgstr ""
+
+msgid "InProductMarketing|Make it easier to collaborate on high-level ideas by grouping related issues in an epic."
+msgstr ""
+
msgid "InProductMarketing|Making the switch? It's easier than you think to import your projects into GitLab. Move %{github_link}, or import something %{bitbucket_link}."
msgstr ""
msgid "InProductMarketing|Master the art of importing!"
msgstr ""
+msgid "InProductMarketing|Merge request approval rule"
+msgstr ""
+
msgid "InProductMarketing|Move on to easily creating a Pages website %{ci_template_link}"
msgstr ""
msgid "InProductMarketing|Multiple owners, confusing workstreams? We've got you covered"
msgstr ""
+msgid "InProductMarketing|Multiple required approvers"
+msgstr ""
+
msgid "InProductMarketing|Need an alternative to importing?"
msgstr ""
@@ -18615,18 +19004,33 @@ msgstr ""
msgid "InProductMarketing|Our tool brings all the things together"
msgstr ""
+msgid "InProductMarketing|Protect your web application by using DAST to examine for vulnerabilities in deployed environments."
+msgstr ""
+
msgid "InProductMarketing|Rapid development, simplified"
msgstr ""
msgid "InProductMarketing|Reduce Security & Compliance Risk"
msgstr ""
+msgid "InProductMarketing|Require multiple approvers on a merge request, so you know it's in good shape before it's merged."
+msgstr ""
+
+msgid "InProductMarketing|Roadmaps"
+msgstr ""
+
+msgid "InProductMarketing|Scoped labels"
+msgstr ""
+
msgid "InProductMarketing|Security that's integrated into your development lifecycle"
msgstr ""
msgid "InProductMarketing|Sometimes you're not ready to make a full transition to a new tool. If you're not ready to fully commit, %{mirroring_link} gives you a safe way to try out GitLab in parallel with your current tool."
msgstr ""
+msgid "InProductMarketing|Speed. Efficiency. Trust."
+msgstr ""
+
msgid "InProductMarketing|Spin up an autoscaling runner in GitLab"
msgstr ""
@@ -18636,6 +19040,9 @@ msgstr ""
msgid "InProductMarketing|Start a Self-Managed trial"
msgstr ""
+msgid "InProductMarketing|Start a free trial"
+msgstr ""
+
msgid "InProductMarketing|Start a free trial of GitLab Ultimate – no credit card required"
msgstr ""
@@ -18702,6 +19109,9 @@ msgstr ""
msgid "InProductMarketing|To understand and get the most out of GitLab, start at the beginning and %{project_link}. In GitLab, repositories are part of a project, so after you've created your project you can go ahead and %{repo_link}."
msgstr ""
+msgid "InProductMarketing|Track completed issues in a chart, so you can see how a milestone is progressing at a glance."
+msgstr ""
+
msgid "InProductMarketing|Try GitLab Ultimate for free"
msgstr ""
@@ -18738,6 +19148,9 @@ msgstr ""
msgid "InProductMarketing|Very easy"
msgstr ""
+msgid "InProductMarketing|Visualize your epics and milestones in a timeline."
+msgstr ""
+
msgid "InProductMarketing|Want to host GitLab on your servers?"
msgstr ""
@@ -18759,6 +19172,9 @@ msgstr ""
msgid "InProductMarketing|YouTube"
msgstr ""
+msgid "InProductMarketing|Your software, deployed your way"
+msgstr ""
+
msgid "InProductMarketing|Your teams can be more efficient"
msgstr ""
@@ -18879,9 +19295,18 @@ msgstr ""
msgid "IncidentManagement|No incidents to display."
msgstr ""
+msgid "IncidentManagement|None"
+msgstr ""
+
msgid "IncidentManagement|Open"
msgstr ""
+msgid "IncidentManagement|Page your team with escalation policies"
+msgstr ""
+
+msgid "IncidentManagement|Paged"
+msgstr ""
+
msgid "IncidentManagement|Published"
msgstr ""
@@ -18891,6 +19316,9 @@ msgstr ""
msgid "IncidentManagement|Severity"
msgstr ""
+msgid "IncidentManagement|Status"
+msgstr ""
+
msgid "IncidentManagement|There are no closed incidents"
msgstr ""
@@ -18909,6 +19337,9 @@ msgstr ""
msgid "IncidentManagement|Unpublished"
msgstr ""
+msgid "IncidentManagement|Use escalation policies to automatically page your team when incidents are created."
+msgstr ""
+
msgid "IncidentSettings|Activate \"time to SLA\" countdown timer"
msgstr ""
@@ -18954,7 +19385,10 @@ msgstr ""
msgid "Incidents"
msgstr ""
-msgid "Incidents|Add a URL"
+msgid "Incidents|Add image details"
+msgstr ""
+
+msgid "Incidents|Add text or a link to display with your image. If you don't add either, the file name displays instead."
msgstr ""
msgid "Incidents|Drop or %{linkStart}upload%{linkEnd} a metric screenshot to attach it to the incident"
@@ -18969,10 +19403,10 @@ msgstr ""
msgid "Incidents|There was an issue loading metric images."
msgstr ""
-msgid "Incidents|There was an issue uploading your image."
+msgid "Incidents|There was an issue updating your image."
msgstr ""
-msgid "Incidents|You can optionally add a URL to link users to the original graph."
+msgid "Incidents|There was an issue uploading your image."
msgstr ""
msgid "Incident|Alert details"
@@ -18981,9 +19415,18 @@ msgstr ""
msgid "Incident|Are you sure you wish to delete this image?"
msgstr ""
+msgid "Incident|Delete image"
+msgstr ""
+
msgid "Incident|Deleting %{filename}"
msgstr ""
+msgid "Incident|Edit image text or link"
+msgstr ""
+
+msgid "Incident|Editing %{filename}"
+msgstr ""
+
msgid "Incident|Metrics"
msgstr ""
@@ -19253,12 +19696,18 @@ msgstr ""
msgid "Integrations|Branches for which notifications are to be sent"
msgstr ""
+msgid "Integrations|Clear if using a self-signed certificate."
+msgstr ""
+
msgid "Integrations|Comment detail:"
msgstr ""
msgid "Integrations|Comment settings:"
msgstr ""
+msgid "Integrations|Connection details"
+msgstr ""
+
msgid "Integrations|Connection failed. Please check your settings."
msgstr ""
@@ -19283,6 +19732,9 @@ msgstr ""
msgid "Integrations|Enable GitLab.com slash commands in a Slack workspace."
msgstr ""
+msgid "Integrations|Enable SSL verification"
+msgstr ""
+
msgid "Integrations|Enable comments"
msgstr ""
@@ -19361,6 +19813,9 @@ msgstr ""
msgid "Integrations|Return to GitLab for Jira"
msgstr ""
+msgid "Integrations|SSL verification"
+msgstr ""
+
msgid "Integrations|Save settings?"
msgstr ""
@@ -19406,9 +19861,6 @@ msgstr ""
msgid "Integrations|Use default settings"
msgstr ""
-msgid "Integrations|When you mention a Jira issue in a commit or merge request, GitLab creates a remote link and comment (if enabled)."
-msgstr ""
-
msgid "Integrations|You can now close this window and return to the GitLab for Jira application."
msgstr ""
@@ -19433,9 +19885,6 @@ msgstr ""
msgid "Integrations|can't exceed %{recipients_limit}"
msgstr ""
-msgid "Interactive developer security education."
-msgstr ""
-
msgid "Interactive mode"
msgstr ""
@@ -19925,6 +20374,9 @@ msgstr ""
msgid "IssueAnalytics|Assignees"
msgstr ""
+msgid "IssueAnalytics|Created by"
+msgstr ""
+
msgid "IssueAnalytics|Due date"
msgstr ""
@@ -19937,9 +20389,6 @@ msgstr ""
msgid "IssueAnalytics|Milestone"
msgstr ""
-msgid "IssueAnalytics|Opened by"
-msgstr ""
-
msgid "IssueAnalytics|Status"
msgstr ""
@@ -20063,10 +20512,10 @@ msgstr ""
msgid "IssuesAnalytics|Avg/Month:"
msgstr ""
-msgid "IssuesAnalytics|Issues opened"
+msgid "IssuesAnalytics|Issues created"
msgstr ""
-msgid "IssuesAnalytics|Issues opened per month"
+msgid "IssuesAnalytics|Issues created per month"
msgstr ""
msgid "IssuesAnalytics|Last 12 months"
@@ -20093,6 +20542,9 @@ msgstr ""
msgid "It looks like you have some draft commits in this branch."
msgstr ""
+msgid "It looks like you're attempting to activate your subscription. Use %{a_start}the Subscription page%{a_end} instead."
+msgstr ""
+
msgid "It may be several days before you see feature usage data."
msgstr ""
@@ -20321,6 +20773,9 @@ msgstr ""
msgid "JiraConnect|You can now close this window and return to Jira."
msgstr ""
+msgid "JiraConnect|You don't have permission to create branches for this project. Select a different project or contact the project owner for access. %{linkStart}Learn more.%{linkEnd}"
+msgstr ""
+
msgid "JiraRequest|A connection error occurred while connecting to Jira. Try your request again."
msgstr ""
@@ -20369,13 +20824,13 @@ msgstr ""
msgid "JiraService|Define the type of Jira issue to create from a vulnerability."
msgstr ""
-msgid "JiraService|Displaying Jira issues while leaving the GitLab issue functionality enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
+msgid "JiraService|Displaying Jira issues while leaving GitLab issues also enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
msgstr ""
-msgid "JiraService|Enable Jira issues"
+msgid "JiraService|Enable Jira issue creation from vulnerabilities"
msgstr ""
-msgid "JiraService|Enable Jira issues creation from vulnerabilities"
+msgid "JiraService|Enable Jira issues"
msgstr ""
msgid "JiraService|Enable Jira transitions"
@@ -20492,16 +20947,19 @@ msgstr ""
msgid "JiraService|View Jira issues in GitLab"
msgstr ""
-msgid "JiraService|Warning: All GitLab users that have access to this GitLab project are able to view all issues from the Jira project specified below."
+msgid "JiraService|Warning: All GitLab users with access to this GitLab project can view all issues from the Jira project you select."
msgstr ""
msgid "JiraService|Web URL"
msgstr ""
-msgid "JiraService|Work on Jira issues without leaving GitLab. Adds a Jira menu to access your list of Jira issues and view any issue as read-only."
+msgid "JiraService|When a Jira issue is mentioned in a commit or merge request, a remote link and comment (if enabled) will be created."
+msgstr ""
+
+msgid "JiraService|Work on Jira issues without leaving GitLab. Add a Jira menu to access a read-only list of your Jira issues."
msgstr ""
-msgid "JiraService|You need to configure Jira before enabling this integration. For more details, read the %{jira_doc_link_start}Jira integration documentation%{link_end}."
+msgid "JiraService|You must configure Jira before enabling this integration. %{jira_doc_link_start}Learn more.%{link_end}"
msgstr ""
msgid "Job"
@@ -20513,9 +20971,6 @@ msgstr ""
msgid "Job Failed #%{build_id}"
msgstr ""
-msgid "Job ID"
-msgstr ""
-
msgid "Job artifact"
msgstr ""
@@ -20582,9 +21037,27 @@ msgstr ""
msgid "Jobs|You're about to retry a job that failed because it attempted to deploy code that is older than the latest deployment. Retrying this job could result in overwriting the environment with the older source code."
msgstr ""
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source} into %{target}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{ref}"
+msgstr ""
+
+msgid "Job|Are you sure you want to erase this job log and artifacts?"
+msgstr ""
+
msgid "Job|Browse"
msgstr ""
+msgid "Job|Cancel"
+msgstr ""
+
msgid "Job|Complete Raw"
msgstr ""
@@ -20594,6 +21067,9 @@ msgstr ""
msgid "Job|Erase job log and artifacts"
msgstr ""
+msgid "Job|Finished at"
+msgstr ""
+
msgid "Job|Job artifacts"
msgstr ""
@@ -20606,7 +21082,7 @@ msgstr ""
msgid "Job|Keep"
msgstr ""
-msgid "Job|Pipeline"
+msgid "Job|Retry"
msgstr ""
msgid "Job|Scroll to bottom"
@@ -20618,6 +21094,9 @@ msgstr ""
msgid "Job|Show complete raw"
msgstr ""
+msgid "Job|Status"
+msgstr ""
+
msgid "Job|The artifacts were removed"
msgstr ""
@@ -20645,21 +21124,12 @@ msgstr ""
msgid "Job|delayed"
msgstr ""
-msgid "Job|for"
-msgstr ""
-
-msgid "Job|into"
-msgstr ""
-
msgid "Job|manual"
msgstr ""
msgid "Job|triggered"
msgstr ""
-msgid "Job|with"
-msgstr ""
-
msgid "Join Zoom meeting"
msgstr ""
@@ -20762,9 +21232,6 @@ msgstr ""
msgid "Ki"
msgstr ""
-msgid "Kontra"
-msgstr ""
-
msgid "Kroki"
msgstr ""
@@ -21088,6 +21555,9 @@ msgstr ""
msgid "Learn more about Auto DevOps"
msgstr ""
+msgid "Learn more about GitLab"
+msgstr ""
+
msgid "Learn more about Needs relationships"
msgstr ""
@@ -21415,9 +21885,18 @@ msgstr ""
msgid "Licenses|Displays licenses detected in the project, based on the %{linkStart}latest successful%{linkEnd} scan"
msgstr ""
+msgid "Licenses|Drag your license file here or %{linkStart}click to upload%{linkEnd}."
+msgstr ""
+
+msgid "Licenses|Drop your license file to start the upload."
+msgstr ""
+
msgid "Licenses|Error fetching the license list. Please check your network connection and try again."
msgstr ""
+msgid "Licenses|Error: You are trying to upload something other than a file"
+msgstr ""
+
msgid "Licenses|License Compliance"
msgstr ""
@@ -21436,6 +21915,9 @@ msgstr ""
msgid "Licenses|Specified policies in this project"
msgstr ""
+msgid "Licenses|The file could not be uploaded."
+msgstr ""
+
msgid "Licenses|The license list details information about the licenses used within your project."
msgstr ""
@@ -21469,11 +21951,6 @@ msgstr ""
msgid "Limit the size of Sidekiq jobs stored in Redis."
msgstr ""
-msgid "Limited to showing %d event at most"
-msgid_plural "Limited to showing %d events at most"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Limiting mode"
msgstr ""
@@ -21483,6 +21960,9 @@ msgstr ""
msgid "Link"
msgstr ""
+msgid "Link (optional)"
+msgstr ""
+
msgid "Link Prometheus monitoring to GitLab."
msgstr ""
@@ -21519,6 +21999,9 @@ msgstr ""
msgid "Linked emails (%{email_count})"
msgstr ""
+msgid "Linked epics"
+msgstr ""
+
msgid "Linked issues"
msgstr ""
@@ -21546,6 +22029,15 @@ msgstr ""
msgid "List of all merge commits"
msgstr ""
+msgid "List of environments for this project"
+msgstr ""
+
+msgid "List of suitable GCP locations"
+msgstr ""
+
+msgid "List of users allowed to exceed the rate limit."
+msgstr ""
+
msgid "List options"
msgstr ""
@@ -21765,6 +22257,9 @@ msgstr ""
msgid "Maintenance mode"
msgstr ""
+msgid "Make adjustments to how your GitLab instance is set up."
+msgstr ""
+
msgid "Make and review changes in the browser with the Web IDE"
msgstr ""
@@ -21909,6 +22404,12 @@ msgstr ""
msgid "MarkdownEditor|Add italic text (%{modifier_key}I)"
msgstr ""
+msgid "MarkdownEditor|Add strikethrough text (%{modifierKey}⇧X)"
+msgstr ""
+
+msgid "MarkdownEditor|Add strikethrough text (%{modifier_key}⇧X)"
+msgstr ""
+
msgid "Marked For Deletion At - %{deletion_time}"
msgstr ""
@@ -22170,6 +22671,9 @@ msgstr ""
msgid "Maximum push size (MB)"
msgstr ""
+msgid "Maximum requests per 10 minutes per user"
+msgstr ""
+
msgid "Maximum requests per minute"
msgstr ""
@@ -22260,6 +22764,19 @@ msgstr ""
msgid "Members of a group may only view projects they have permission to access"
msgstr ""
+msgid "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seat in use and will be billed for the overage."
+msgid_plural "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seats in use and will be billed for the overage."
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "MembersOverage|You are about to incur additional charges"
+msgstr ""
+
+msgid "MembersOverage|Your subscription includes %d seat."
+msgid_plural "MembersOverage|Your subscription includes %d seats."
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Membership"
msgstr ""
@@ -22464,9 +22981,6 @@ msgstr ""
msgid "Merge request not merged"
msgstr ""
-msgid "Merge request pipelines 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 merge request pipelines."
-msgstr ""
-
msgid "Merge request reports"
msgstr ""
@@ -22563,13 +23077,13 @@ msgstr ""
msgid "MergeRequests|Create issue to resolve thread"
msgstr ""
-msgid "MergeRequests|Failed to squash. Should be done manually."
+msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Saving the comment failed"
+msgid "MergeRequests|Squashing failed: Squash the commits locally, resolve any conflicts, then push the branch."
msgstr ""
-msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
+msgid "MergeRequests|Squashing not allowed: This project doesn't allow you to squash commits when merging."
msgstr ""
msgid "MergeRequests|Thread stays resolved"
@@ -23410,6 +23924,18 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "MrList|Assigned to %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from assignee %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from reviewer %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Review requested from %{name}, go to their profile."
+msgstr ""
+
msgid "Multi-project"
msgstr ""
@@ -23443,7 +23969,7 @@ msgstr ""
msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "My Awesome Group"
+msgid "My awesome group"
msgstr ""
msgid "My company or team"
@@ -24065,9 +24591,6 @@ msgstr ""
msgid "No available branches"
msgstr ""
-msgid "No available groups to fork the project."
-msgstr ""
-
msgid "No branches found"
msgstr ""
@@ -24278,6 +24801,9 @@ msgstr ""
msgid "No ref selected"
msgstr ""
+msgid "No regions configured"
+msgstr ""
+
msgid "No related merge requests found."
msgstr ""
@@ -25082,6 +25608,9 @@ msgstr ""
msgid "Only reCAPTCHA v2 is supported:"
msgstr ""
+msgid "Only required if not using role instance credentials."
+msgstr ""
+
msgid "Only use lowercase letters, numbers, and underscores."
msgstr ""
@@ -25106,9 +25635,6 @@ msgstr ""
msgid "Open a CLI and connect to the cluster you want to install the agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
-msgid "Open epics"
-msgstr ""
-
msgid "Open errors"
msgstr ""
@@ -25148,7 +25674,7 @@ msgstr ""
msgid "Opened issues"
msgstr ""
-msgid "OpenedNDaysAgo|Opened"
+msgid "OpenedNDaysAgo|Created"
msgstr ""
msgid "Opens in a new window"
@@ -25193,9 +25719,6 @@ msgstr ""
msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
-msgid "Optional."
-msgstr ""
-
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
msgstr ""
@@ -25984,6 +26507,9 @@ msgstr ""
msgid "PerformanceBar|Memory"
msgstr ""
+msgid "PerformanceBar|Memory report"
+msgstr ""
+
msgid "PerformanceBar|Redis calls"
msgstr ""
@@ -26017,18 +26543,12 @@ msgstr ""
msgid "PerformanceBar|wall"
msgstr ""
-msgid "Performs a rebase but skips triggering a new pipeline"
-msgstr ""
-
msgid "Period in seconds"
msgstr ""
msgid "Permalink"
msgstr ""
-msgid "Permanently delete project"
-msgstr ""
-
msgid "Permanently remove group"
msgstr ""
@@ -26299,6 +26819,51 @@ msgstr ""
msgid "PipelineStatusTooltip|Pipeline: %{ci_status}"
msgstr ""
+msgid "PipelineWizardDefaultCommitMessage|Add %{filename}"
+msgstr ""
+
+msgid "PipelineWizardDefaultCommitMessage|Update %{filename}"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|At least one entry is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This field is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This value is not valid"
+msgstr ""
+
+msgid "PipelineWizardListWidget|add another step"
+msgstr ""
+
+msgid "PipelineWizardListWidget|remove step"
+msgstr ""
+
+msgid "PipelineWizard|Commit"
+msgstr ""
+
+msgid "PipelineWizard|Commit Message"
+msgstr ""
+
+msgid "PipelineWizard|Commit changes to your file"
+msgstr ""
+
+msgid "PipelineWizard|Commit file to Branch"
+msgstr ""
+
+msgid "PipelineWizard|Commit your new file"
+msgstr ""
+
+msgid "PipelineWizard|The file has been committed."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem committing the changes."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem while checking whether your file already exists in the specified branch."
+msgstr ""
+
msgid "Pipelines"
msgstr ""
@@ -26413,7 +26978,7 @@ msgstr ""
msgid "Pipelines|Project cache successfully reset."
msgstr ""
-msgid "Pipelines|Revoke"
+msgid "Pipelines|Revoke trigger"
msgstr ""
msgid "Pipelines|Something went wrong while cleaning runners cache."
@@ -26458,6 +27023,12 @@ msgstr ""
msgid "Pipelines|This is a child pipeline within the parent pipeline"
msgstr ""
+msgid "Pipelines|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipelines|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipelines|This pipeline will run code originating from a forked project merge request. This means that the code can potentially have security considerations like exposing CI variables."
msgstr ""
@@ -26500,9 +27071,6 @@ msgstr ""
msgid "Pipelines|Your changes have been successfully committed. Now redirecting to the new merge request page."
msgstr ""
-msgid "Pipelines|detached"
-msgstr ""
-
msgid "Pipelines|error"
msgstr ""
@@ -26512,10 +27080,13 @@ msgstr ""
msgid "Pipelines|latest"
msgstr ""
-msgid "Pipelines|stuck"
+msgid "Pipelines|merge request"
msgstr ""
-msgid "Pipelines|train"
+msgid "Pipelines|merge train"
+msgstr ""
+
+msgid "Pipelines|stuck"
msgstr ""
msgid "Pipelines|yaml invalid"
@@ -26647,6 +27218,12 @@ msgstr ""
msgid "Pipeline|This change will not change the overall test coverage if merged."
msgstr ""
+msgid "Pipeline|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipeline|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipeline|Trigger author"
msgstr ""
@@ -26671,6 +27248,12 @@ msgstr ""
msgid "Pipeline|for"
msgstr ""
+msgid "Pipeline|merge request"
+msgstr ""
+
+msgid "Pipeline|merge train"
+msgstr ""
+
msgid "Pipeline|on"
msgstr ""
@@ -26809,9 +27392,6 @@ msgstr ""
msgid "Please enter a valid time interval"
msgstr ""
-msgid "Please enter or upload a valid license."
-msgstr ""
-
msgid "Please enter your current password."
msgstr ""
@@ -26920,9 +27500,6 @@ msgstr ""
msgid "Please type %{phrase_code} to proceed or close this modal to cancel."
msgstr ""
-msgid "Please type the following to confirm:"
-msgstr ""
-
msgid "Please use this form to report to the admin users who create spam issues, comments or behave inappropriately."
msgstr ""
@@ -26950,12 +27527,27 @@ msgstr ""
msgid "Policies"
msgstr ""
+msgid "Policy '%{escalation_policy_name}' does not exist."
+msgstr ""
+
msgid "Policy management project does have any policies in %{policy_path}"
msgstr ""
msgid "Policy project doesn't exist"
msgstr ""
+msgid "PolicyRuleMultiSelect|%{firstLabel} +%{numberOfAdditionalLabels} more"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|All %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select all"
+msgstr ""
+
msgid "Polling interval multiplier"
msgstr ""
@@ -27184,6 +27776,9 @@ msgstr ""
msgid "Private projects can be created in your personal namespace with:"
msgstr ""
+msgid "Problem with %{name} command: %{message}."
+msgstr ""
+
msgid "Proceed"
msgstr ""
@@ -27658,6 +28253,9 @@ msgstr ""
msgid "Progress"
msgstr ""
+msgid "Progress tracking"
+msgstr ""
+
msgid "Project"
msgstr ""
@@ -27889,6 +28487,9 @@ msgstr ""
msgid "ProjectQualitySummary|Failure"
msgstr ""
+msgid "ProjectQualitySummary|Get insight into the overall percentage of tests in your project that succeed, fail and are skipped."
+msgstr ""
+
msgid "ProjectQualitySummary|Latest pipeline results"
msgstr ""
@@ -27907,6 +28508,12 @@ msgstr ""
msgid "ProjectQualitySummary|See project Code Coverage Statistics"
msgstr ""
+msgid "ProjectQualitySummary|Set up test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|Set up test runs (opens in a new tab)"
+msgstr ""
+
msgid "ProjectQualitySummary|Skipped"
msgstr ""
@@ -28183,13 +28790,19 @@ msgstr ""
msgid "ProjectSettings|LFS objects from this repository are available to forks. %{linkStart}How do I remove them?%{linkEnd}"
msgstr ""
+msgid "ProjectSettings|Learn about commit history."
+msgstr ""
+
+msgid "ProjectSettings|Leave empty to use default template."
+msgstr ""
+
msgid "ProjectSettings|Manage who can see the project in the public access directory."
msgstr ""
msgid "ProjectSettings|Manages large files such as audio, video, and graphics files."
msgstr ""
-msgid "ProjectSettings|Maximum 500 characters."
+msgid "ProjectSettings|Maximum %{maxLength} characters."
msgstr ""
msgid "ProjectSettings|Merge checks"
@@ -28330,6 +28943,9 @@ msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
msgstr ""
+msgid "ProjectSettings|The default template will be applied on save."
+msgstr ""
+
msgid "ProjectSettings|These checks must pass before merge requests can be merged."
msgstr ""
@@ -28384,6 +29000,9 @@ msgstr ""
msgid "ProjectSettings|What are badges?"
msgstr ""
+msgid "ProjectSettings|What are merge trains?"
+msgstr ""
+
msgid "ProjectSettings|When merge request pipelines are enabled in the CI/CD configuration file, pipelines validate the combined results of the source and target branches. %{link_start}How to configure merge request pipelines?%{link_end}"
msgstr ""
@@ -28501,6 +29120,9 @@ msgstr ""
msgid "Projects are organized into groups"
msgstr ""
+msgid "Projects are where you store your code, access issues, wiki and other features of GitLab."
+msgstr ""
+
msgid "Projects contributed to"
msgstr ""
@@ -28516,12 +29138,6 @@ msgstr ""
msgid "Projects to index"
msgstr ""
-msgid "Projects will be permanently deleted after a %{waiting_period}-day waiting period."
-msgstr ""
-
-msgid "Projects will be permanently deleted immediately."
-msgstr ""
-
msgid "Projects with critical vulnerabilities"
msgstr ""
@@ -28606,6 +29222,9 @@ msgstr ""
msgid "ProjectsNew|Import project"
msgstr ""
+msgid "ProjectsNew|Include a Getting Started README"
+msgstr ""
+
msgid "ProjectsNew|Initialize repository with a README"
msgstr ""
@@ -28621,6 +29240,9 @@ msgstr ""
msgid "ProjectsNew|Project description %{tag_start}(optional)%{tag_end}"
msgstr ""
+msgid "ProjectsNew|Recommended if you're new to GitLab"
+msgstr ""
+
msgid "ProjectsNew|Run CI/CD for external repository"
msgstr ""
@@ -29038,6 +29660,9 @@ msgstr ""
msgid "ProtectedBranch|Unprotect"
msgstr ""
+msgid "ProtectedBranch|Unprotect branch"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
@@ -29065,6 +29690,9 @@ msgstr ""
msgid "ProtectedEnvironment|Protected Environment (%{protected_environments_count})"
msgstr ""
+msgid "ProtectedEnvironment|Required approvals"
+msgstr ""
+
msgid "ProtectedEnvironment|Select an environment"
msgstr ""
@@ -29086,10 +29714,13 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|Unprotect tag"
+msgstr ""
+
msgid "ProtectedTags|default"
msgstr ""
-msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
+msgid "ProtectedTag|By default, protected tags restrict who can modify the tag."
msgstr ""
msgid "ProtectedTag|Learn more."
@@ -29152,6 +29783,9 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Public projects are an easy way to allow everyone to have read-only access."
+msgstr ""
+
msgid "Publish to status page"
msgstr ""
@@ -29308,9 +29942,6 @@ msgstr ""
msgid "QualitySummary|Project quality"
msgstr ""
-msgid "Quarters"
-msgstr ""
-
msgid "Query"
msgstr ""
@@ -29395,6 +30026,9 @@ msgstr ""
msgid "Read more about project permissions %{help_link_open}here%{help_link_close}"
msgstr ""
+msgid "Read more about related epics"
+msgstr ""
+
msgid "Read more about related issues"
msgstr ""
@@ -29425,10 +30059,7 @@ msgstr ""
msgid "Rebase source branch on the target branch."
msgstr ""
-msgid "Rebase without CI"
-msgstr ""
-
-msgid "Rebases and triggers a pipeline"
+msgid "Rebase without pipeline"
msgstr ""
msgid "Recaptcha verified?"
@@ -29479,9 +30110,6 @@ msgstr ""
msgid "Reconfigure"
msgstr ""
-msgid "Recovering projects"
-msgstr ""
-
msgid "Recovery Codes"
msgstr ""
@@ -29541,6 +30169,12 @@ msgstr ""
msgid "Regex pattern"
msgstr ""
+msgid "Region"
+msgstr ""
+
+msgid "Regions"
+msgstr ""
+
msgid "Register"
msgstr ""
@@ -29771,9 +30405,6 @@ msgstr ""
msgid "Remove all or specific reviewer(s)"
msgstr ""
-msgid "Remove approver"
-msgstr ""
-
msgid "Remove approvers"
msgstr ""
@@ -29789,6 +30420,9 @@ msgstr ""
msgid "Remove attention request"
msgstr ""
+msgid "Remove attention request(s)"
+msgstr ""
+
msgid "Remove avatar"
msgstr ""
@@ -29927,6 +30561,9 @@ msgstr ""
msgid "Removed an issue from an epic."
msgstr ""
+msgid "Removed attention from %{users_sentence}."
+msgstr ""
+
msgid "Removed attention request from @%{username}"
msgstr ""
@@ -29978,6 +30615,9 @@ msgstr ""
msgid "Removes an issue from an epic."
msgstr ""
+msgid "Removes attention from %{users_sentence}."
+msgstr ""
+
msgid "Removes parent epic %{epic_ref}."
msgstr ""
@@ -30089,6 +30729,9 @@ msgstr ""
msgid "Report abuse to admin"
msgstr ""
+msgid "Report is generating and will be sent to your email address."
+msgstr ""
+
msgid "Reported %{timeAgo} by %{reportedBy}"
msgstr ""
@@ -30378,6 +31021,15 @@ msgstr ""
msgid "Request attention"
msgstr ""
+msgid "Request attention from %{users_sentence}."
+msgstr ""
+
+msgid "Request attention from assignee or reviewer"
+msgstr ""
+
+msgid "Request attention from assignee(s) or reviewer(s)"
+msgstr ""
+
msgid "Request attention to review"
msgstr ""
@@ -30402,6 +31054,9 @@ msgstr ""
msgid "Requested %{time_ago}"
msgstr ""
+msgid "Requested attention from %{users_sentence}."
+msgstr ""
+
msgid "Requested attention from @%{username}"
msgstr ""
@@ -30616,6 +31271,9 @@ msgstr ""
msgid "Restore project"
msgstr ""
+msgid "Restoring projects"
+msgstr ""
+
msgid "Restoring the group will prevent the group, its subgroups and projects from being removed on this date."
msgstr ""
@@ -30646,6 +31304,9 @@ msgstr ""
msgid "Retry"
msgstr ""
+msgid "Retry failed jobs"
+msgstr ""
+
msgid "Retry job"
msgstr ""
@@ -30693,9 +31354,6 @@ msgstr ""
msgid "Review changes"
msgstr ""
-msgid "Review requested from %{name}"
-msgstr ""
-
msgid "Review requests for you"
msgstr ""
@@ -30860,6 +31518,9 @@ msgstr ""
msgid "Runners|Assigned Group"
msgstr ""
+msgid "Runners|Assigned Projects (%{projectCount})"
+msgstr ""
+
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30929,6 +31590,9 @@ msgstr ""
msgid "Runners|Instance"
msgstr ""
+msgid "Runners|Jobs"
+msgstr ""
+
msgid "Runners|Last contact"
msgstr ""
@@ -31022,9 +31686,6 @@ msgstr ""
msgid "Runners|Runner %{name} was deleted"
msgstr ""
-msgid "Runners|Runner ID"
-msgstr ""
-
msgid "Runners|Runner assigned to project."
msgstr ""
@@ -31172,6 +31833,9 @@ msgstr ""
msgid "Runners|stale"
msgstr ""
+msgid "Runner|This runner has not run any jobs."
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -31286,6 +31950,24 @@ msgstr ""
msgid "Saving project."
msgstr ""
+msgid "ScanResultPolicy|%{ifLabelStart}if%{ifLabelEnd} %{scanners} scan in an open merge request targeting the %{branches} branch(es) finds %{vulnerabilitiesAllowed} or more %{severities} vulnerabilities that are %{vulnerabilityStates}"
+msgstr ""
+
+msgid "ScanResultPolicy|%{thenLabelStart}Then%{thenLabelEnd} Require approval from %{approvalsRequired} of the following approvers: %{approvers}"
+msgstr ""
+
+msgid "ScanResultPolicy|add an approver"
+msgstr ""
+
+msgid "ScanResultPolicy|scanners"
+msgstr ""
+
+msgid "ScanResultPolicy|severity levels"
+msgstr ""
+
+msgid "ScanResultPolicy|vulnerability states"
+msgstr ""
+
msgid "Scanner"
msgstr ""
@@ -31418,6 +32100,9 @@ msgstr ""
msgid "Search for a user"
msgstr ""
+msgid "Search for an emoji"
+msgstr ""
+
msgid "Search for projects, issues, etc."
msgstr ""
@@ -31605,18 +32290,12 @@ msgstr ""
msgid "Secret Detection"
msgstr ""
-msgid "Secret access key"
-msgstr ""
-
msgid "Secret token"
msgstr ""
msgid "Secure token that identifies an external storage request."
msgstr ""
-msgid "SecureCodeWarrior"
-msgstr ""
-
msgid "Security"
msgstr ""
@@ -31641,9 +32320,6 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "Security training with guide and learning pathways."
-msgstr ""
-
msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
@@ -31746,7 +32422,7 @@ msgstr ""
msgid "SecurityConfiguration|Manage corpus"
msgstr ""
-msgid "SecurityConfiguration|Manage corpus files used as mutation sources in coverage fuzzing."
+msgid "SecurityConfiguration|Manage corpus files used as seed inputs with coverage-guided fuzzing."
msgstr ""
msgid "SecurityConfiguration|Manage profiles for use by DAST scans."
@@ -31812,15 +32488,15 @@ msgstr ""
msgid "SecurityOrchestration|.yaml preview"
msgstr ""
-msgid "SecurityOrchestration|Action"
-msgstr ""
-
msgid "SecurityOrchestration|Actions"
msgstr ""
msgid "SecurityOrchestration|Add rule"
msgstr ""
+msgid "SecurityOrchestration|After dismissing the alert, the information will never be shown again."
+msgstr ""
+
msgid "SecurityOrchestration|All policies"
msgstr ""
@@ -31836,7 +32512,7 @@ msgstr ""
msgid "SecurityOrchestration|Description"
msgstr ""
-msgid "SecurityOrchestration|Disabled"
+msgid "SecurityOrchestration|Don't show the alert anymore"
msgstr ""
msgid "SecurityOrchestration|Edit policy"
@@ -31845,13 +32521,13 @@ msgstr ""
msgid "SecurityOrchestration|Edit policy project"
msgstr ""
-msgid "SecurityOrchestration|Enabled"
+msgid "SecurityOrchestration|Empty policy name"
msgstr ""
-msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Enabled"
msgstr ""
-msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
msgstr ""
msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
@@ -31860,7 +32536,7 @@ msgstr ""
msgid "SecurityOrchestration|Invalid policy type"
msgstr ""
-msgid "SecurityOrchestration|Latest scan"
+msgid "SecurityOrchestration|Latest scan run against %{agent}"
msgstr ""
msgid "SecurityOrchestration|Network"
@@ -31869,15 +32545,27 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No actions defined - policy will not run."
+msgstr ""
+
+msgid "SecurityOrchestration|No description"
+msgstr ""
+
msgid "SecurityOrchestration|No rules defined - policy will not run."
msgstr ""
+msgid "SecurityOrchestration|Not enabled"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
msgid "SecurityOrchestration|Policies"
msgstr ""
+msgid "SecurityOrchestration|Policy Type"
+msgstr ""
+
msgid "SecurityOrchestration|Policy cannot be enabled for non-existing branches (%{branches})"
msgstr ""
@@ -31902,10 +32590,13 @@ msgstr ""
msgid "SecurityOrchestration|Require %{approvals} %{plural} from %{approvers} if any of the following occur:"
msgstr ""
-msgid "SecurityOrchestration|Rule"
+msgid "SecurityOrchestration|Rules"
msgstr ""
-msgid "SecurityOrchestration|Rules"
+msgid "SecurityOrchestration|Runs %{actions} and %{lastAction} scans"
+msgstr ""
+
+msgid "SecurityOrchestration|Runs a %{action} scan"
msgstr ""
msgid "SecurityOrchestration|Scan Execution"
@@ -31965,6 +32656,9 @@ msgstr ""
msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
+msgid "SecurityOrchestration|This view only shows scan results for the agent %{agent}. You can view scan results for all agents in the %{linkStart}Operational Vulnerabilities tab of the vulnerability report%{linkEnd}."
+msgstr ""
+
msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
@@ -32019,9 +32713,6 @@ msgstr ""
msgid "SecurityOrchestration|users with ids"
msgstr ""
-msgid "SecurityOrchestration|view results"
-msgstr ""
-
msgid "SecurityOrchestration|vulnerabilities"
msgstr ""
@@ -32691,22 +33382,19 @@ 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|In order to start using functions as a service, you must first install Knative on your Kubernetes cluster. %{linkStart}More information%{linkEnd}"
-msgstr ""
-
msgid "Serverless|Learn more about Serverless"
msgstr ""
msgid "Serverless|No functions available"
msgstr ""
-msgid "Serverless|Sign up for First Look"
+msgid "Serverless|Serverless was %{linkStart}deprecated%{linkEnd} in GitLab 14.3."
+msgstr ""
+
+msgid "Serverless|Serverless was %{postLinkStart}deprecated%{postLinkEnd}. But if you opt to use it, you must install Knative in your Kubernetes cluster first. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "Serverless|The deploy job has not finished."
@@ -32718,9 +33406,6 @@ 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 ""
@@ -32736,9 +33421,6 @@ msgstr ""
msgid "Service Account Key"
msgstr ""
-msgid "Service Accounts"
-msgstr ""
-
msgid "Service Accounts keys authorize GitLab to deploy your Google Cloud project"
msgstr ""
@@ -32748,10 +33430,10 @@ msgstr ""
msgid "Service Desk allows people to create issues in your GitLab instance without their own user account. It provides a unique email address for end users to create issues in a project. Replies can be sent either through the GitLab interface or by email. End users only see threads through email."
msgstr ""
-msgid "Service Usage Data"
+msgid "Service account generated successfully"
msgstr ""
-msgid "Service account generated successfully"
+msgid "Service accounts"
msgstr ""
msgid "Service ping is disabled in your configuration file, and cannot be enabled through this form."
@@ -32895,6 +33577,9 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
+msgid "Set the per-user rate limit for getting a user by ID via the API."
+msgstr ""
+
msgid "Set the per-user rate limit for notes created by web or API requests."
msgstr ""
@@ -33074,6 +33759,9 @@ msgstr ""
msgid "Shared runners details"
msgstr ""
+msgid "Shared runners enabled cannot be enabled until a valid credit card is on file"
+msgstr ""
+
msgid "Shared runners help link"
msgstr ""
@@ -33131,6 +33819,9 @@ msgstr ""
msgid "Show all issues."
msgstr ""
+msgid "Show all milestones"
+msgstr ""
+
msgid "Show all test cases."
msgstr ""
@@ -33167,6 +33858,9 @@ msgstr ""
msgid "Show file contents"
msgstr ""
+msgid "Show group milestones"
+msgstr ""
+
msgid "Show labels"
msgstr ""
@@ -33182,6 +33876,12 @@ msgstr ""
msgid "Show open epics"
msgstr ""
+msgid "Show project milestones"
+msgstr ""
+
+msgid "Show sub-group milestones"
+msgstr ""
+
msgid "Show the Closed list"
msgstr ""
@@ -33191,11 +33891,6 @@ msgstr ""
msgid "Show whitespace changes"
msgstr ""
-msgid "Showing %d event"
-msgid_plural "Showing %d events"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Showing %{conflict} between %{sourceBranch} and %{targetBranch}"
msgstr ""
@@ -33255,12 +33950,6 @@ msgstr ""
msgid "Sidebar|None"
msgstr ""
-msgid "Sidebar|Only numeral characters allowed"
-msgstr ""
-
-msgid "Sidebar|Weight"
-msgstr ""
-
msgid "Sidekiq job compression threshold (bytes)"
msgstr ""
@@ -33423,6 +34112,9 @@ msgstr ""
msgid "Slack logo"
msgstr ""
+msgid "SlackIntegration|Are you sure you want to remove this project from the Slack application?"
+msgstr ""
+
msgid "SlackIntegration|GitLab for Slack"
msgstr ""
@@ -33432,6 +34124,9 @@ msgstr ""
msgid "SlackIntegration|Project alias"
msgstr ""
+msgid "SlackIntegration|Remove project"
+msgstr ""
+
msgid "SlackIntegration|Select a GitLab project to link with your Slack workspace."
msgstr ""
@@ -33576,9 +34271,6 @@ msgstr ""
msgid "Something went wrong trying to load issue contacts."
msgstr ""
-msgid "Something went wrong when creating a work item. Please try again"
-msgstr ""
-
msgid "Something went wrong when reordering designs. Please try again"
msgstr ""
@@ -33672,9 +34364,6 @@ msgstr ""
msgid "Something went wrong while inserting your image. Please try again."
msgstr ""
-msgid "Something went wrong while merging this merge request. Please try again."
-msgstr ""
-
msgid "Something went wrong while obtaining the Let's Encrypt certificate."
msgstr ""
@@ -33996,10 +34685,10 @@ 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."
+msgid "SourcegraphAdmin|Learn more."
msgstr ""
-msgid "SourcegraphAdmin|More information"
+msgid "SourcegraphAdmin|Only public projects have code intelligence enabled and communicate with Sourcegraph."
msgstr ""
msgid "SourcegraphAdmin|Save changes"
@@ -34008,7 +34697,7 @@ msgstr ""
msgid "SourcegraphAdmin|Sourcegraph URL"
msgstr ""
-msgid "SourcegraphAdmin|e.g. https://sourcegraph.example.com"
+msgid "SourcegraphAdmin|https://sourcegraph.example.com"
msgstr ""
msgid "SourcegraphPreferences|This feature is experimental and currently limited to certain projects."
@@ -34143,6 +34832,9 @@ msgstr ""
msgid "Start date"
msgstr ""
+msgid "Start free trial"
+msgstr ""
+
msgid "Start merge train"
msgstr ""
@@ -34173,6 +34865,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started escalation for this incident."
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -34185,6 +34880,9 @@ msgstr ""
msgid "Starts at (UTC)"
msgstr ""
+msgid "Starts escalations for this incident"
+msgstr ""
+
msgid "Starts on"
msgstr ""
@@ -34446,6 +35144,9 @@ msgstr ""
msgid "Strikethrough"
msgstr ""
+msgid "Strikethrough text"
+msgstr ""
+
msgid "Subgroup information"
msgstr ""
@@ -34680,6 +35381,21 @@ msgstr ""
msgid "Subscriptions"
msgstr ""
+msgid "Subscriptions|Chat with sales"
+msgstr ""
+
+msgid "Subscriptions|Close"
+msgstr ""
+
+msgid "Subscriptions|Not ready to buy yet?"
+msgstr ""
+
+msgid "Subscriptions|Start a free trial"
+msgstr ""
+
+msgid "Subscriptions|We understand. Maybe you have some questions for our sales team, or maybe you'd like to try some of the paid features first. What would you like to do?"
+msgstr ""
+
msgid "Subscription|Your subscription for %{strong}%{namespace_name}%{strong_close} has expired and you are now on %{pricing_link_start}the GitLab Free tier%{pricing_link_end}. Don't worry, your data is safe. Get in touch with our support team (%{support_email}). They'll gladly help with your subscription renewal."
msgstr ""
@@ -34890,6 +35606,9 @@ msgstr ""
msgid "SuperSonics|Maximum users"
msgstr ""
+msgid "SuperSonics|Offline cloud"
+msgstr ""
+
msgid "SuperSonics|Paste your activation code"
msgstr ""
@@ -34956,6 +35675,12 @@ msgstr ""
msgid "SuperSonics|You do not have an active subscription"
msgstr ""
+msgid "SuperSonics|You have a future dated license"
+msgstr ""
+
+msgid "SuperSonics|You have added a license that activates on %{date}. Please see the subscription history table below for more details."
+msgstr ""
+
msgid "SuperSonics|You have successfully added a license that activates on %{date}. Please see the subscription history table below for more details."
msgstr ""
@@ -35115,6 +35840,9 @@ msgstr ""
msgid "Tag name is required"
msgstr ""
+msgid "Tag push"
+msgstr ""
+
msgid "Tag push events"
msgstr ""
@@ -35217,6 +35945,9 @@ msgstr ""
msgid "TagsPage|protected"
msgstr ""
+msgid "Take a look at the documentation to discover all of GitLab’s capabilities."
+msgstr ""
+
msgid "Target Branch"
msgstr ""
@@ -35619,6 +36350,9 @@ msgstr ""
msgid "Tests"
msgstr ""
+msgid "Text (optional)"
+msgstr ""
+
msgid "Text added to the body of all email messages. %{character_limit} character limit"
msgstr ""
@@ -35669,6 +36403,9 @@ msgstr ""
msgid "The CSV export will be created in the background. Once finished, it will be sent to %{email} in an attachment."
msgstr ""
+msgid "The CSV export you requested of all user memberships is attached to this email."
+msgstr ""
+
msgid "The GitLab subscription service (customers.gitlab.com) is currently experiencing an outage. You can monitor the status and get updates at %{linkStart}status.gitlab.com%{linkEnd}."
msgstr ""
@@ -35744,6 +36481,9 @@ 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 epic"
+msgstr ""
+
msgid "The current issue"
msgstr ""
@@ -35905,6 +36645,9 @@ msgstr ""
msgid "The latest pipeline for this merge request has failed."
msgstr ""
+msgid "The license key is invalid."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -35920,6 +36663,9 @@ msgstr ""
msgid "The license was successfully uploaded and will be active from %{starts_at}. You can see the details below."
msgstr ""
+msgid "The license you uploaded is invalid. If the issue persists, contact support at %{link}."
+msgstr ""
+
msgid "The list creation wizard is already open"
msgstr ""
@@ -36541,10 +37287,13 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} and everything this project contains. %{strongOpen}There is no going back%{strongClose}"
+msgstr ""
+
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains."
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}on %{date}%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains. %{strongOpen}There is no going back.%{strongClose}"
msgstr ""
msgid "This action will %{strongOpen}permanently remove%{strongClose} %{codeOpen}%{group}%{codeClose} %{strongOpen}immediately%{strongClose}."
@@ -36673,9 +37422,6 @@ msgstr ""
msgid "This file was modified for readability, and can't accept suggestions. Edit it directly."
msgstr ""
-msgid "This forked project has the following:"
-msgstr ""
-
msgid "This form is disabled in preview"
msgstr ""
@@ -36688,7 +37434,7 @@ msgstr ""
msgid "This group can't be removed because it is linked to a subscription. To remove this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
-msgid "This group can't be transfered because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
+msgid "This group can't be transferred because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
msgid "This group cannot be invited to a project inside a group with enforced SSO"
@@ -36715,6 +37461,9 @@ 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 incident is already escalated with '%{escalation_policy_name}'."
+msgstr ""
+
msgid "This invitation was sent to %{mail_to_invite_email}, but you are signed in as %{link_to_current_user} with email %{mail_to_current_user}."
msgstr ""
@@ -36733,9 +37482,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 merge train pipeline"
-msgstr ""
-
msgid "This is a private email address %{helpIcon} generated just for you. Anyone who has it can create issues or merge requests as if they were you. If that happens, %{resetLinkStart}reset this token%{resetLinkEnd}."
msgstr ""
@@ -36757,6 +37503,12 @@ msgstr ""
msgid "This is your current session"
msgstr ""
+msgid "This issue cannot be assigned to a confidential epic because it is public."
+msgstr ""
+
+msgid "This issue cannot be made public because it belongs to a confidential epic."
+msgstr ""
+
msgid "This issue is confidential and should only be visible to team members with at least Reporter access."
msgstr ""
@@ -36874,6 +37626,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 branch is protected from force push."
+msgstr ""
+
msgid "This merge request cannot be rebased while there are conflicts."
msgstr ""
@@ -36925,9 +37680,15 @@ msgstr ""
msgid "This pipeline was triggered by a schedule."
msgstr ""
+msgid "This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project"
msgstr ""
+msgid "This project can be restored until %{date}."
+msgstr ""
+
msgid "This project cannot be %{visibilityLevel} because the visibility of %{openShowLink}%{name}%{closeShowLink} is %{visibility}. To make this project %{visibilityLevel}, you must first %{openEditLink}change the visibility%{closeEditLink} of the parent group."
msgstr ""
@@ -36946,6 +37707,9 @@ msgstr ""
msgid "This project is %{strongStart}NOT%{strongEnd} a fork, and has the following:"
msgstr ""
+msgid "This project is %{strongStart}NOT%{strongEnd} a fork. This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -37637,6 +38401,9 @@ msgstr ""
msgid "Today"
msgstr ""
+msgid "Todos count"
+msgstr ""
+
msgid "Todos|Are you looking for things to do? Take a look at %{strongStart}%{openIssuesLinkStart}open issues%{openIssuesLinkEnd}%{strongEnd}, contribute to %{strongStart}%{mergeRequestLinkStart}a merge request%{mergeRequestLinkEnd}%{mergeRequestLinkEnd}%{strongEnd}, or mention someone in a comment to automatically assign them a new to-do item."
msgstr ""
@@ -37910,10 +38677,8 @@ msgstr ""
msgid "Trending"
msgstr ""
-msgid "Trials|%{planName} Trial %{enDash} %{num} day left"
-msgid_plural "Trials|%{planName} Trial %{enDash} %{num} days left"
-msgstr[0] ""
-msgstr[1] ""
+msgid "Trials|%{planName} Trial"
+msgstr ""
msgid "Trials|Compare all plans"
msgstr ""
@@ -37921,6 +38686,9 @@ msgstr ""
msgid "Trials|Create a new group to start your GitLab Ultimate trial."
msgstr ""
+msgid "Trials|Day %{daysUsed}/%{duration}"
+msgstr ""
+
msgid "Trials|Go back to GitLab"
msgstr ""
@@ -38170,7 +38938,7 @@ msgstr ""
msgid "URL is triggered when repository is updated"
msgstr ""
-msgid "URL must be percent-encoded if neccessary."
+msgid "URL must be percent-encoded if necessary."
msgstr ""
msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
@@ -38389,6 +39157,9 @@ msgstr ""
msgid "Unlock account"
msgstr ""
+msgid "Unlock more features with GitLab Ultimate"
+msgstr ""
+
msgid "Unlock the discussion"
msgstr ""
@@ -38452,6 +39223,9 @@ msgstr ""
msgid "Unsubscribes from this %{quick_action_target}."
msgstr ""
+msgid "Unsupported sort value."
+msgstr ""
+
msgid "Unsupported todo type passed. Supported todo types are: %{todo_types}"
msgstr ""
@@ -38680,6 +39454,9 @@ msgstr ""
msgid "UsageQuota|File attachments and smaller design graphics."
msgstr ""
+msgid "UsageQuota|From %{storage_enforcement_date} storage limits will apply to this namespace. View and manage your usage in %{strong_start}Group Settings &gt; Usage quotas%{strong_end}."
+msgstr ""
+
msgid "UsageQuota|Git repository."
msgstr ""
@@ -38740,6 +39517,9 @@ msgstr ""
msgid "UsageQuota|Storage type"
msgstr ""
+msgid "UsageQuota|Storage used"
+msgstr ""
+
msgid "UsageQuota|This is the total amount of storage used across your projects within this namespace."
msgstr ""
@@ -38935,6 +39715,12 @@ msgstr ""
msgid "Use hashed storage paths for newly created and renamed repositories. Always enabled since 13.0."
msgstr ""
+msgid "Use issue count"
+msgstr ""
+
+msgid "Use issue weight"
+msgstr ""
+
msgid "Use one line per URI"
msgstr ""
@@ -39316,6 +40102,9 @@ msgstr ""
msgid "Users"
msgstr ""
+msgid "Users API rate limit"
+msgstr ""
+
msgid "Users can launch a development environment from a GitLab browser tab when the %{linkStart}Gitpod%{linkEnd} integration is enabled."
msgstr ""
@@ -39641,6 +40430,9 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View group pipeline usage quota"
+msgstr ""
+
msgid "View incident details at"
msgstr ""
@@ -39793,6 +40585,9 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
+msgid "Vulnerability"
+msgstr ""
+
msgid "Vulnerability Report"
msgstr ""
@@ -39844,6 +40639,9 @@ msgstr ""
msgid "VulnerabilityManagement|An unverified non-confirmed finding"
msgstr ""
+msgid "VulnerabilityManagement|At least one identifier is required"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -39853,12 +40651,24 @@ msgstr ""
msgid "VulnerabilityManagement|Create Jira issue"
msgstr ""
+msgid "VulnerabilityManagement|Enter a name"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE code"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE identifier URL"
+msgstr ""
+
msgid "VulnerabilityManagement|Fetching linked Jira issues"
msgstr ""
msgid "VulnerabilityManagement|Manually add a vulnerability entry into the vulnerability report."
msgstr ""
+msgid "VulnerabilityManagement|Name is a required field"
+msgstr ""
+
msgid "VulnerabilityManagement|Needs triage"
msgstr ""
@@ -39874,6 +40684,18 @@ msgstr ""
msgid "VulnerabilityManagement|Select a method"
msgstr ""
+msgid "VulnerabilityManagement|Select a severity level"
+msgstr ""
+
+msgid "VulnerabilityManagement|Select a status"
+msgstr ""
+
+msgid "VulnerabilityManagement|Severity is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Something went wrong while creating vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -39898,6 +40720,12 @@ msgstr ""
msgid "VulnerabilityManagement|Something went wrong, could not update vulnerability state."
msgstr ""
+msgid "VulnerabilityManagement|Status is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Submit vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Summary, detailed description, steps to reproduce, etc."
msgstr ""
@@ -40093,6 +40921,9 @@ msgstr ""
msgid "WARNING:"
msgstr ""
+msgid "WARNING: This snippet contains hidden files which might be used to mask malicious behavior. Exercise caution if cloning and executing code from this snippet."
+msgstr ""
+
msgid "Wait for the file to load to copy its contents"
msgstr ""
@@ -40312,6 +41143,15 @@ msgstr ""
msgid "Webhooks|An issue is created, updated, closed, or reopened."
msgstr ""
+msgid "Webhooks|Are you sure you want to delete this group hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this project hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this webhook?"
+msgstr ""
+
msgid "Webhooks|Comments"
msgstr ""
@@ -40321,6 +41161,9 @@ msgstr ""
msgid "Webhooks|Confidential issues events"
msgstr ""
+msgid "Webhooks|Delete webhook"
+msgstr ""
+
msgid "Webhooks|Deployment events"
msgstr ""
@@ -40554,6 +41397,9 @@ msgstr ""
msgid "Wiki"
msgstr ""
+msgid "Wiki page"
+msgstr ""
+
msgid "Wiki page was successfully created."
msgstr ""
@@ -40659,7 +41505,7 @@ msgstr ""
msgid "WikiPageConflictMessage|Someone edited the page the same time you did. Please check out %{wikiLinkStart}the page%{wikiLinkEnd} and make sure your changes will not unintentionally remove theirs."
msgstr ""
-msgid "WikiPage|An error occured while trying to render the content editor. Please try again later."
+msgid "WikiPage|An error occurred while trying to render the content editor. Please try again later."
msgstr ""
msgid "WikiPage|Are you sure you want to switch back to the classic editor?"
@@ -40818,6 +41664,18 @@ msgstr ""
msgid "WorkItem|New Task"
msgstr ""
+msgid "WorkItem|Something went wrong when creating a work item. Please try again"
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching the work item. Please try again."
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching work item types. Please try again"
+msgstr ""
+
+msgid "WorkItem|Type"
+msgstr ""
+
msgid "WorkItem|Work Items"
msgstr ""
@@ -40884,7 +41742,10 @@ msgstr ""
msgid "You are about to add %{usersTag} people to the discussion. They will all receive a notification."
msgstr ""
-msgid "You are about to permanently delete this project"
+msgid "You are about to delete this forked project containing:"
+msgstr ""
+
+msgid "You are about to delete this project containing:"
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."
@@ -40905,6 +41766,9 @@ msgstr ""
msgid "You are attempting to update a file that has changed since you started editing it."
msgstr ""
+msgid "You are billed if you exceed this number. %{qsrOverageLinkStart}How does billing work?%{qsrOverageLinkEnd}"
+msgstr ""
+
msgid "You are connected to the Prometheus server, but there is currently no data to display."
msgstr ""
@@ -40962,6 +41826,9 @@ msgstr ""
msgid "You are not authorized to update this scanner profile"
msgstr ""
+msgid "You are not authorized to upload metric images"
+msgstr ""
+
msgid "You are now impersonating %{username}"
msgstr ""
@@ -41115,9 +41982,6 @@ msgstr ""
msgid "You can only upload one design when dropping onto an existing design."
msgstr ""
-msgid "You can recover this project until %{date}"
-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 ""
@@ -41166,9 +42030,6 @@ msgstr ""
msgid "You cannot write to this read-only GitLab instance."
msgstr ""
-msgid "You can’t %{tag_start}edit%{tag_end} files directly in this project. Fork this project and submit a merge request with your changes."
-msgstr ""
-
msgid "You can’t edit files directly in this project. Fork this project and submit a merge request with your changes."
msgstr ""
@@ -41321,9 +42182,6 @@ 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 set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
@@ -41354,12 +42212,6 @@ msgstr ""
msgid "You must have maintainer access to force delete a lock"
msgstr ""
-msgid "You must have permission to create a project in a group before forking."
-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 ""
@@ -41765,7 +42617,7 @@ msgstr ""
msgid "Your public email will be displayed on your public profile."
msgstr ""
-msgid "Your request for access could not be processed: %{error_meesage}"
+msgid "Your request for access could not be processed: %{error_message}"
msgstr ""
msgid "Your request for access has been queued for review."
@@ -41948,6 +42800,9 @@ msgstr ""
msgid "archived:"
msgstr ""
+msgid "artifacts"
+msgstr ""
+
msgid "assign yourself"
msgstr ""
@@ -41977,6 +42832,9 @@ msgstr[1] ""
msgid "branch name"
msgstr ""
+msgid "builds"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -42400,6 +43258,9 @@ msgstr ""
msgid "contact with same email already exists in group hierarchy"
msgstr ""
+msgid "container registry images"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -42439,6 +43300,9 @@ msgstr ""
msgid "data"
msgstr ""
+msgid "database"
+msgstr ""
+
msgid "date must not be after 9999-12-31"
msgstr ""
@@ -42462,9 +43326,6 @@ msgstr ""
msgid "design"
msgstr ""
-msgid "detached"
-msgstr ""
-
msgid "disabled"
msgstr ""
@@ -42713,7 +43574,7 @@ msgstr ""
msgid "is not a valid X509 certificate."
msgstr ""
-msgid "is not allowed for sign-up."
+msgid "is not allowed for sign-up. Please use your regular email address."
msgstr ""
msgid "is not allowed for this group."
@@ -42725,7 +43586,7 @@ msgstr ""
msgid "is not allowed since the group is not top-level group."
msgstr ""
-msgid "is not allowed."
+msgid "is not allowed. Please use your regular email address."
msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
@@ -42812,6 +43673,9 @@ msgstr ""
msgid "level: %{level}"
msgstr ""
+msgid "lfs objects"
+msgstr ""
+
msgid "limit of %{project_limit} reached"
msgstr ""
@@ -43031,6 +43895,9 @@ msgstr ""
msgid "mrWidget|Merge blocked: pipeline must succeed. It's waiting for a manual action to continue."
msgstr ""
+msgid "mrWidget|Merge blocked: pipeline must succeed. Push a commit that fixes the failure, or %{linkStart}learn about other solutions.%{linkEnd}"
+msgstr ""
+
msgid "mrWidget|Merge blocked: this merge request must be approved."
msgstr ""
@@ -43148,9 +44015,6 @@ msgstr ""
msgid "mrWidget|The changes were not merged into"
msgstr ""
-msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -43298,9 +44162,6 @@ msgstr ""
msgid "open issue"
msgstr ""
-msgid "opened %{timeAgo}"
-msgstr ""
-
msgid "or"
msgstr ""
@@ -43312,6 +44173,12 @@ msgid_plural "out of %d total tests"
msgstr[0] ""
msgstr[1] ""
+msgid "packages"
+msgstr ""
+
+msgid "pages"
+msgstr ""
+
msgid "parent"
msgid_plural "parents"
msgstr[0] ""
@@ -43461,6 +44328,9 @@ msgid_plural "replies"
msgstr[0] ""
msgstr[1] ""
+msgid "repositories"
+msgstr ""
+
msgid "repository:"
msgstr ""
@@ -43581,12 +44451,18 @@ msgstr ""
msgid "tag name"
msgstr ""
+msgid "terraform states"
+msgstr ""
+
msgid "the correct format."
msgstr ""
msgid "the file"
msgstr ""
+msgid "the following epic(s)"
+msgstr ""
+
msgid "the following issue(s)"
msgstr ""
@@ -43599,21 +44475,12 @@ msgstr ""
msgid "this document"
msgstr ""
-msgid "this issue cannot be assigned to a confidential epic since it is public"
-msgstr ""
-
-msgid "this issue cannot be made public since it belongs to a confidential epic"
-msgstr ""
-
msgid "time summary"
msgstr ""
msgid "toggle collapse"
msgstr ""
-msgid "train"
-msgstr ""
-
msgid "triggered"
msgstr ""
@@ -43742,3 +44609,6 @@ msgstr ""
msgid "{project}"
msgstr ""
+msgid "✔"
+msgstr ""
+
diff --git a/locale/pl_PL/gitlab.po b/locale/pl_PL/gitlab.po
index acead49e610..57dbfdbce7f 100644
--- a/locale/pl_PL/gitlab.po
+++ b/locale/pl_PL/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: pl\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2022-02-02 15:45\n"
+"PO-Revision-Date: 2022-03-01 20:39\n"
msgid " %{start} to %{end}"
msgstr " %{start} do %{end}"
@@ -174,6 +174,13 @@ msgstr[1] "%d zatwierdzających (zatwierdziłeś)"
msgstr[2] "%d zatwierdzających (zatwierdziłeś)"
msgstr[3] "%d zatwierdzającego (zatwierdziłeś)"
+msgid "%d assigned issue"
+msgid_plural "%d assigned issues"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] "%d zmieniony plik"
@@ -559,12 +566,33 @@ msgstr[1] "%d podatności odrzucone"
msgstr[2] "%d podatności odrzuconych"
msgstr[3] "%d podatności odrzuconej"
-msgid "%d vulnerability updated"
-msgid_plural "%d vulnerabilities updated"
-msgstr[0] "%d podatność zaktualizowana"
-msgstr[1] "%d podatności zaktualizowano"
-msgstr[2] "%d podatności zaktualizowano"
-msgstr[3] "%d podatności zaktualizowano"
+msgid "%d vulnerability set to confirmed"
+msgid_plural "%d vulnerabilities set to confirmed"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
+msgid "%d vulnerability set to dismissed"
+msgid_plural "%d vulnerabilities set to dismissed"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
+msgid "%d vulnerability set to needs triage"
+msgid_plural "%d vulnerabilities set to needs triage"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
+msgid "%d vulnerability set to resolved"
+msgid_plural "%d vulnerabilities set to resolved"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
msgid "%d warning found:"
msgid_plural "%d warnings found:"
@@ -662,6 +690,12 @@ msgstr[3] "%{completedCount} z %{count} zadania ukończono"
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr "Ukończono %{completedWeight} z %{totalWeight} wagi"
+msgid "%{completed} of %{total} issues closed"
+msgstr ""
+
+msgid "%{completed} of %{total} weight completed"
+msgstr ""
+
msgid "%{cores} cores"
msgstr "%{cores} rdzeni"
@@ -1022,6 +1056,9 @@ msgstr "%{openedEpics} otwarte, %{closedEpics} zamknięte"
msgid "%{openedIssues} open, %{closedIssues} closed"
msgstr "%{openedIssues} otwarte, %{closedIssues} zamknięte"
+msgid "%{percentage}%% issues closed"
+msgstr ""
+
msgid "%{percentage}%% weight completed"
msgstr "Ukończono %{percentage}%% wagi"
@@ -1481,6 +1518,9 @@ msgstr[1] "- Użytkowników"
msgstr[2] "- Użytkowników"
msgstr[3] "- Użytkownika"
+msgid "- of - issues closed"
+msgstr ""
+
msgid "- of - weight completed"
msgstr "- z - wagi zakończone"
@@ -1669,7 +1709,7 @@ msgstr ""
msgid "1000+"
msgstr "1000+"
-msgid "192.168.0.0/24"
+msgid "192.168.0.0/24 or 2001:0DB8:1234::/48"
msgstr ""
msgid "1st contribution!"
@@ -1981,13 +2021,13 @@ msgstr ""
msgid "AWS Access Key"
msgstr "Klucz dostępu AWS"
-msgid "AWS Access Key. Only required if not using role instance credentials"
-msgstr ""
-
msgid "AWS Secret Access Key"
msgstr "Tajny klucz dostępu AWS"
-msgid "AWS Secret Access Key. Only required if not using role instance credentials"
+msgid "AWS access key ID (Optional)"
+msgstr ""
+
+msgid "AWS secret access key (Optional)"
msgstr ""
msgid "AWS service error: %{error}"
@@ -2047,9 +2087,6 @@ msgstr "Dostęp zabroniony. Sprawdź swój poziom dostępu."
msgid "Access granted"
msgstr "Dostęp przyznany"
-msgid "Access key ID"
-msgstr ""
-
msgid "Access requests"
msgstr "Poproszono o dostęp"
@@ -2224,8 +2261,8 @@ msgstr ""
msgid "Activity"
msgstr "Aktywność"
-msgid "Activity|An error occured while retrieving activity. Reload the page to try again."
-msgstr "Wystąpił błąd podczas pobierania aktywności. Załaduj ponownie stronę, aby spróbować ponownie."
+msgid "Activity|An error occurred while retrieving activity. Reload the page to try again."
+msgstr ""
msgid "Add"
msgstr "Dodaj"
@@ -2263,6 +2300,9 @@ msgstr "Dodaj spotkanie Zoom"
msgid "Add a %{type}"
msgstr "Dodaj %{type}"
+msgid "Add a GCP region"
+msgstr ""
+
msgid "Add a GPG key"
msgstr "Dodaj klucz GPG"
@@ -2314,6 +2354,9 @@ msgstr "Dodaj nowe zgłoszenie"
msgid "Add a numbered list"
msgstr "Dodaj listÄ™ numerowanÄ…"
+msgid "Add a related epic"
+msgstr ""
+
msgid "Add a related issue"
msgstr "Dodaj powiązane zgłoszenie"
@@ -2428,6 +2471,9 @@ msgstr "Dodaj lub usuń poprzednio zmergowane commity"
msgid "Add or subtract spent time"
msgstr "Dodaj lub odejmij spędzony czas"
+msgid "Add people"
+msgstr ""
+
msgid "Add previously merged commits"
msgstr "Dodaj poprzednio zmergowane commity"
@@ -2494,6 +2540,9 @@ msgstr ""
msgid "Add webhook"
msgstr "Dodaj webhook"
+msgid "Add your team members and others to GitLab."
+msgstr ""
+
msgid "Add/remove"
msgstr "Dodaj/usuń"
@@ -3316,12 +3365,6 @@ msgstr ""
msgid "AdvancedSearch|Reindex required"
msgstr ""
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. Permanently deleting this project will %{strongStart}immediately delete%{strongEnd} its repositories and %{strongStart}all related resources%{strongEnd}, including issues, merge requests etc."
-msgstr ""
-
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. You will lose this project's repository and %{strongStart}all related resources%{strongEnd}, including issues and merge requests."
-msgstr ""
-
msgid "After a successful password update you will be redirected to login screen."
msgstr "Po udanej aktualizacji hasła zostaniesz przekierowany do ekranu logowania."
@@ -3352,6 +3395,9 @@ msgstr "Klucz API Akismet"
msgid "Akismet helps prevent the creation of spam issues in public projects."
msgstr ""
+msgid "Alert"
+msgstr ""
+
msgid "AlertManagement|Acknowledged"
msgstr ""
@@ -3724,9 +3770,6 @@ msgstr ""
msgid "All environments"
msgstr "Wszystkie środowiska"
-msgid "All epics"
-msgstr ""
-
msgid "All groups and projects"
msgstr "Wszystkie grupy i projekty"
@@ -4467,14 +4510,17 @@ msgstr ""
msgid "ApplicationSettings|Approve users in the pending approval status?"
msgstr ""
-msgid "ApplicationSettings|By making this change, you will automatically approve %d user with the pending approval status."
-msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users with the pending approval status."
+msgid "ApplicationSettings|Approve users who are pending approval?"
+msgstr ""
+
+msgid "ApplicationSettings|By making this change, you will automatically approve %d user who is pending approval."
+msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users who are pending approval."
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
-msgid "ApplicationSettings|By making this change, you will automatically approve all users in pending approval status."
+msgid "ApplicationSettings|By making this change, you will automatically approve all users who are pending approval."
msgstr ""
msgid "ApplicationSettings|Denied domains for sign-ups"
@@ -4890,10 +4936,10 @@ msgstr ""
msgid "Archiving the project will make it entirely read-only. It is hidden from the dashboard and doesn't show up in searches. %{strong_start}The repository cannot be committed to, and no issues, comments, or other entities can be created.%{strong_end} %{link_start}Learn more.%{link_end}"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to delete this project?"
+msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
+msgid "Are you absolutely sure?"
msgstr ""
msgid "Are you sure that you want to archive this project?"
@@ -4929,12 +4975,18 @@ msgstr ""
msgid "Are you sure you want to delete this SSH key?"
msgstr ""
+msgid "Are you sure you want to delete this comment?"
+msgstr ""
+
msgid "Are you sure you want to delete this deploy key?"
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 label?"
+msgstr ""
+
msgid "Are you sure you want to delete this pipeline schedule?"
msgstr ""
@@ -4950,9 +5002,6 @@ msgstr ""
msgid "Are you sure you want to discard your changes?"
msgstr ""
-msgid "Are you sure you want to erase this build?"
-msgstr "Czy na pewno chcesz usunąć tę kompilację?"
-
msgid "Are you sure you want to import %d repository?"
msgid_plural "Are you sure you want to import %d repositories?"
msgstr[0] ""
@@ -5002,6 +5051,9 @@ msgstr ""
msgid "Are you sure you want to remove this list?"
msgstr ""
+msgid "Are you sure you want to remove this nickname?"
+msgstr ""
+
msgid "Are you sure you want to reset the health check token?"
msgstr ""
@@ -5014,10 +5066,10 @@ 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?"
+msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
msgstr ""
-msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
+msgid "Are you sure you want to revoke this project access token? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to stop this environment?"
@@ -5164,9 +5216,6 @@ msgstr ""
msgid "Assigned to %{assignee_name}"
msgstr ""
-msgid "Assigned to %{name}"
-msgstr ""
-
msgid "Assigned to me"
msgstr ""
@@ -5235,6 +5284,9 @@ msgstr[3] ""
msgid "Attaching the file failed."
msgstr ""
+msgid "Attention"
+msgstr ""
+
msgid "Audit Events"
msgstr ""
@@ -5397,6 +5449,12 @@ msgstr ""
msgid "Authorized applications (%{size})"
msgstr ""
+msgid "AuthorizedApplication|Are you sure you want to revoke this application?"
+msgstr ""
+
+msgid "AuthorizedApplication|Revoke application"
+msgstr ""
+
msgid "Authors: %{authors}"
msgstr ""
@@ -6598,6 +6656,9 @@ msgstr ""
msgid "CICDAnalytics|Shared Runners Usage"
msgstr ""
+msgid "CICDAnalytics|Shared runner pipeline minute duration by month"
+msgstr ""
+
msgid "CICDAnalytics|Shared runner usage"
msgstr ""
@@ -6739,6 +6800,9 @@ msgstr ""
msgid "Can create groups:"
msgstr ""
+msgid "Can not delete primary training"
+msgstr ""
+
msgid "Can't apply as the source branch was deleted."
msgstr ""
@@ -7072,9 +7136,6 @@ msgstr ""
msgid "Changing any setting here requires an application restart"
msgstr ""
-msgid "Changing group URL can have unintended side effects."
-msgstr ""
-
msgid "Charts can't be displayed as the request for data has timed out. %{documentationLink}"
msgstr ""
@@ -7162,9 +7223,6 @@ msgstr ""
msgid "Checking branch availability..."
msgstr ""
-msgid "Checking group URL availability..."
-msgstr ""
-
msgid "Checking group path availability..."
msgstr ""
@@ -7662,6 +7720,9 @@ msgstr ""
msgid "Clear recent searches"
msgstr ""
+msgid "Clear repository checks"
+msgstr ""
+
msgid "Clear search"
msgstr ""
@@ -7794,9 +7855,6 @@ msgstr ""
msgid "Closed MRs"
msgstr ""
-msgid "Closed epics"
-msgstr ""
-
msgid "Closed issues"
msgstr ""
@@ -7833,13 +7891,13 @@ msgstr ""
msgid "Cluster level"
msgstr ""
-msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
+msgid "Cluster type must be specified for Stages::ClusterEndpointInserter"
msgstr ""
msgid "ClusterAgents|%{name} successfully deleted"
msgstr ""
-msgid "ClusterAgents|%{number} of %{total} Agents"
+msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
@@ -7881,6 +7939,15 @@ msgstr ""
msgid "ClusterAgents|Agent never connected to GitLab"
msgstr ""
+msgid "ClusterAgents|Agent version mismatch"
+msgstr ""
+
+msgid "ClusterAgents|Agent version mismatch and update"
+msgstr ""
+
+msgid "ClusterAgents|Agent version update required"
+msgstr ""
+
msgid "ClusterAgents|All"
msgstr ""
@@ -7905,7 +7972,7 @@ msgstr ""
msgid "ClusterAgents|Configuration"
msgstr ""
-msgid "ClusterAgents|Connect a cluster through the Agent"
+msgid "ClusterAgents|Connect a cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connect existing cluster"
@@ -7914,13 +7981,13 @@ msgstr ""
msgid "ClusterAgents|Connect with a certificate"
msgstr ""
-msgid "ClusterAgents|Connect with agent"
+msgid "ClusterAgents|Connect with an agent"
msgstr ""
msgid "ClusterAgents|Connect with the GitLab Agent"
msgstr ""
-msgid "ClusterAgents|Connect your cluster through the Agent"
+msgid "ClusterAgents|Connect your cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connected"
@@ -7980,7 +8047,10 @@ msgstr ""
msgid "ClusterAgents|How to register an agent?"
msgstr ""
-msgid "ClusterAgents|Install new Agent"
+msgid "ClusterAgents|How to update an agent?"
+msgstr ""
+
+msgid "ClusterAgents|Install a new agent"
msgstr ""
msgid "ClusterAgents|Last connected %{timeAgo}."
@@ -8007,7 +8077,7 @@ msgstr ""
msgid "ClusterAgents|Never connected"
msgstr ""
-msgid "ClusterAgents|No Agents"
+msgid "ClusterAgents|No agents"
msgstr ""
msgid "ClusterAgents|No clusters connected through cluster certificates"
@@ -8067,6 +8137,9 @@ msgstr ""
msgid "ClusterAgents|The agent has not been connected in a long time. There might be a connectivity issue. Last contact was %{timeAgo}."
msgstr ""
+msgid "ClusterAgents|The agent version do not match each other across your cluster's pods. This can happen when a new agent version was just deployed and Kubernetes is shutting down the old pods."
+msgstr ""
+
msgid "ClusterAgents|The recommended installation method includes the token. If you want to follow the advanced installation method provided in the docs, make sure you save the token value before you close this window."
msgstr ""
@@ -8116,6 +8189,9 @@ msgstr ""
msgid "ClusterAgents|You will need to create a token to connect to your agent"
msgstr ""
+msgid "ClusterAgents|Your agent version is out of sync with your GitLab version (v%{version}), which might cause compatibility problems. Update the agent installed on your cluster to the most recent version."
+msgstr ""
+
msgid "ClusterAgents|Your instance doesn't have the %{linkStart}GitLab Agent Server (KAS)%{linkEnd} set up. Ask a GitLab Administrator to install it."
msgstr ""
@@ -8992,9 +9068,6 @@ msgstr ""
msgid "Comma-separated list of email addresses."
msgstr ""
-msgid "Comma-separated list of users allowed to exceed the rate limit."
-msgstr ""
-
msgid "Comma-separated, e.g. '1.1.1.1, 2.2.2.0/24'"
msgstr ""
@@ -9323,6 +9396,12 @@ msgstr ""
msgid "Confidential"
msgstr ""
+msgid "Confidential issue"
+msgstr ""
+
+msgid "Confidential note"
+msgstr ""
+
msgid "Confidentiality"
msgstr ""
@@ -9356,6 +9435,9 @@ msgstr ""
msgid "Configure Dependency Scanning in `.gitlab-ci.yml`, creating this file if it does not already exist"
msgstr ""
+msgid "Configure GitLab"
+msgstr ""
+
msgid "Configure GitLab runners to start using the Web Terminal. %{helpStart}Learn more.%{helpEnd}"
msgstr ""
@@ -9404,6 +9486,15 @@ msgstr ""
msgid "Configure pipelines to deploy web apps, backend services, APIs and static resources to Google Cloud"
msgstr ""
+msgid "Configure region"
+msgstr ""
+
+msgid "Configure region for environment"
+msgstr ""
+
+msgid "Configure regions"
+msgstr ""
+
msgid "Configure repository mirroring."
msgstr ""
@@ -9437,6 +9528,9 @@ msgstr ""
msgid "Configure which lists are shown for anyone who visits this board"
msgstr ""
+msgid "Configure your environments to be deployed to specific geographical regions"
+msgstr ""
+
msgid "Confirm"
msgstr ""
@@ -10145,10 +10239,10 @@ msgstr ""
msgid "CorpusManagement|Actions"
msgstr ""
-msgid "CorpusManagement|Corpus are used in fuzz testing as mutation source to Improve future testing."
+msgid "CorpusManagement|Corpus file"
msgstr ""
-msgid "CorpusManagement|Corpus file"
+msgid "CorpusManagement|Corpus files are used in coverage-guided fuzz testing as seed inputs to improve testing."
msgstr ""
msgid "CorpusManagement|Corpus files must be in *.zip format. Maximum 5 GB"
@@ -10202,6 +10296,9 @@ msgstr ""
msgid "Could not apply %{name} command."
msgstr ""
+msgid "Could not apply %{name} command. %{message}."
+msgstr ""
+
msgid "Could not authorize chat nickname. Try again!"
msgstr ""
@@ -10352,6 +10449,9 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
+msgid "Create a group"
+msgstr ""
+
msgid "Create a merge request"
msgstr ""
@@ -10376,6 +10476,9 @@ msgstr ""
msgid "Create a personal access token on your account to pull or push via %{protocol}."
msgstr ""
+msgid "Create a project"
+msgstr ""
+
msgid "Create an account using:"
msgstr ""
@@ -10739,6 +10842,9 @@ msgstr ""
msgid "Creation date"
msgstr ""
+msgid "Creator"
+msgstr ""
+
msgid "Credentials"
msgstr ""
@@ -10751,9 +10857,15 @@ msgstr ""
msgid "CredentialsInventory|Personal Access Tokens"
msgstr ""
+msgid "CredentialsInventory|Project Access Tokens"
+msgstr ""
+
msgid "CredentialsInventory|SSH Keys"
msgstr ""
+msgid "Credit card required to be on file in order to create a pipeline"
+msgstr ""
+
msgid "Credit card:"
msgstr ""
@@ -10937,9 +11049,6 @@ msgstr ""
msgid "Customer relations"
msgstr ""
-msgid "Customizable by an administrator."
-msgstr ""
-
msgid "Customizable by owners."
msgstr ""
@@ -11069,30 +11178,18 @@ msgstr ""
msgid "CycleAnalytics|%{selectedLabelsCount} selected (%{maxLabels} max)"
msgstr ""
-msgid "CycleAnalytics|%{stageCount} stages selected"
-msgstr ""
-
-msgid "CycleAnalytics|All stages"
-msgstr ""
-
-msgid "CycleAnalytics|Average days to completion"
+msgid "CycleAnalytics|Average time to completion"
msgstr ""
msgid "CycleAnalytics|Date"
msgstr ""
-msgid "CycleAnalytics|Days to completion"
-msgstr ""
-
msgid "CycleAnalytics|Display chart filters"
msgstr ""
msgid "CycleAnalytics|Lead Time for Changes"
msgstr ""
-msgid "CycleAnalytics|No stages selected"
-msgstr ""
-
msgid "CycleAnalytics|Number of tasks"
msgstr ""
@@ -11125,18 +11222,30 @@ msgstr ""
msgid "CycleAnalytics|Showing data for group '%{groupName}' from %{createdAfter} to %{createdBefore}"
msgstr ""
-msgid "CycleAnalytics|Stages"
+msgid "CycleAnalytics|Stage time: %{title}"
msgstr ""
msgid "CycleAnalytics|Tasks by type"
msgstr ""
-msgid "CycleAnalytics|The average time spent in the selected stage for the items that were completed on each date. Data limited to the last 500 items."
+msgid "CycleAnalytics|The average time items spent in this stage. Data limited to items completed within this date range."
msgstr ""
msgid "CycleAnalytics|The given date range is larger than 180 days"
msgstr ""
+msgid "CycleAnalytics|The total time items spent across each value stream stage. Data limited to items completed within this date range."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Stage time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Total time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|Total time"
+msgstr ""
+
msgid "CycleAnalytics|Type of work"
msgstr ""
@@ -11149,9 +11258,6 @@ msgstr ""
msgid "CycleAnalytics|project dropdown filter"
msgstr ""
-msgid "CycleAnalytics|stage dropdown"
-msgstr ""
-
msgid "DAG visualization requires at least 3 dependent jobs."
msgstr ""
@@ -11251,10 +11357,16 @@ msgstr ""
msgid "DastProfiles|AJAX spider"
msgstr ""
+msgid "DastProfiles|API"
+msgstr ""
+
+msgid "DastProfiles|API endpoint URL"
+msgstr ""
+
msgid "DastProfiles|Active"
msgstr ""
-msgid "DastProfiles|Additional request headers (Optional)"
+msgid "DastProfiles|Additional request headers (optional)"
msgstr ""
msgid "DastProfiles|Are you sure you want to delete this profile?"
@@ -11269,6 +11381,9 @@ msgstr ""
msgid "DastProfiles|Branch missing"
msgstr ""
+msgid "DastProfiles|Choose a scan method"
+msgstr ""
+
msgid "DastProfiles|Could not create the scanner profile. Please try again."
msgstr ""
@@ -11338,7 +11453,13 @@ msgstr ""
msgid "DastProfiles|Excluded URLs"
msgstr ""
-msgid "DastProfiles|Excluded URLs (Optional)"
+msgid "DastProfiles|Excluded URLs (optional)"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths (optional)"
msgstr ""
msgid "DastProfiles|Hide debug messages"
@@ -11395,9 +11516,6 @@ msgstr ""
msgid "DastProfiles|Request headers"
msgstr ""
-msgid "DastProfiles|Rest API"
-msgstr ""
-
msgid "DastProfiles|Run the AJAX spider, in addition to the traditional spider, to crawl the target site."
msgstr ""
@@ -11407,6 +11525,9 @@ msgstr ""
msgid "DastProfiles|Save profile"
msgstr ""
+msgid "DastProfiles|Scan method"
+msgstr ""
+
msgid "DastProfiles|Scan mode"
msgstr ""
@@ -11485,12 +11606,24 @@ msgstr ""
msgid "DastProfiles|Website"
msgstr ""
+msgid "DastProfiles|What does each method do?"
+msgstr ""
+
msgid "DastProfiles|You can either choose a passive scan or validate the target site from the site profile management page. %{docsLinkStart}Learn more about site validation.%{docsLinkEnd}"
msgstr ""
msgid "DastProfiles|You cannot run an active scan against an unvalidated site."
msgstr ""
+msgid "DastProfiles|folder/dast_example.har or https://example.com/dast_example.har"
+msgstr ""
+
+msgid "DastProfiles|folder/example.postman_collection.json or https://example.com/"
+msgstr ""
+
+msgid "DastProfiles|folder/openapi.json or https://example.com/openapi.json"
+msgstr ""
+
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
@@ -11600,6 +11733,9 @@ msgstr ""
msgid "DatadogIntegration|API URL"
msgstr ""
+msgid "DatadogIntegration|Custom tags in Datadog. Enter one tag per line in the %{codeOpen}key:value%{codeClose} format. %{linkOpen}How do I use tags?%{linkClose}"
+msgstr ""
+
msgid "DatadogIntegration|Environment"
msgstr ""
@@ -11618,12 +11754,18 @@ msgstr ""
msgid "DatadogIntegration|Tag all data from this GitLab instance in Datadog. Useful when managing several self-managed deployments."
msgstr ""
+msgid "DatadogIntegration|Tags"
+msgstr ""
+
msgid "DatadogIntegration|The Datadog site to send data to. To send data to the EU site, use %{codeOpen}datadoghq.eu%{codeClose}."
msgstr ""
msgid "DatadogIntegration|Trace your GitLab pipelines with Datadog."
msgstr ""
+msgid "DatadogIntegration|have an invalid format"
+msgstr ""
+
msgid "Datasource name not found"
msgstr ""
@@ -11633,9 +11775,6 @@ msgstr ""
msgid "Date merged"
msgstr ""
-msgid "Date picker"
-msgstr ""
-
msgid "Date range"
msgstr ""
@@ -11789,9 +11928,6 @@ msgstr ""
msgid "Definition"
msgstr ""
-msgid "Delayed Project Deletion (%{adjourned_deletion})"
-msgstr ""
-
msgid "DelayedJobs|Are you sure you want to run %{jobName} immediately? Otherwise this job will run automatically after its timer finishes."
msgstr ""
@@ -11870,10 +12006,10 @@ msgstr ""
msgid "Delete pipeline"
msgstr ""
-msgid "Delete project"
+msgid "Delete pipeline schedule"
msgstr ""
-msgid "Delete project. Are you ABSOLUTELY SURE?"
+msgid "Delete project"
msgstr ""
msgid "Delete row"
@@ -11903,6 +12039,9 @@ msgstr ""
msgid "Delete this epic and all descendants?"
msgstr ""
+msgid "Delete this project"
+msgstr ""
+
msgid "Delete user list"
msgstr ""
@@ -12173,6 +12312,12 @@ msgstr ""
msgid "Deploy to..."
msgstr ""
+msgid "DeployBoards|To see deployment progress for your environments, make sure you are deploying to %{codeStart}$KUBE_NAMESPACE%{codeEnd} and annotating with %{codeStart}app.gitlab.com/app=$CI_PROJECT_PATH_SLUG%{codeEnd} and %{codeStart}app.gitlab.com/env=$CI_ENVIRONMENT_SLUG%{codeEnd}."
+msgstr ""
+
+msgid "DeployBoard|Kubernetes Pods"
+msgstr ""
+
msgid "DeployFreeze|Add a freeze period to prevent unintended releases during a period of time for a given environment. You must update the deployment jobs in %{filename} according to the deploy freezes added here. %{freeze_period_link_start}Learn more.%{freeze_period_link_end}"
msgstr ""
@@ -12257,9 +12402,6 @@ msgstr ""
msgid "DeployTokens|Active Deploy Tokens (%{active_tokens})"
msgstr ""
-msgid "DeployTokens|Allows read and write access to registry images."
-msgstr ""
-
msgid "DeployTokens|Allows read and write access to the package registry."
msgstr ""
@@ -12272,6 +12414,9 @@ msgstr ""
msgid "DeployTokens|Allows read-only access to the repository."
msgstr ""
+msgid "DeployTokens|Allows write access to registry images."
+msgstr ""
+
msgid "DeployTokens|Copy deploy token"
msgstr ""
@@ -12365,12 +12510,57 @@ msgstr ""
msgid "Deploying to AWS is easy with GitLab"
msgstr ""
+msgid "Deployment"
+msgstr ""
+
msgid "Deployment Frequency"
msgstr ""
+msgid "Deployment Target|Project deployment target (optional)"
+msgstr ""
+
+msgid "Deployment Target|Select the deployment target"
+msgstr ""
+
msgid "Deployment frequency"
msgstr ""
+msgid "DeploymentTarget|GitLab Pages"
+msgstr ""
+
+msgid "DeploymentTarget|Heroku"
+msgstr ""
+
+msgid "DeploymentTarget|Infrastructure provider (Terraform, Cloudformation, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Kubernetes (GKE, EKS, OpenShift, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Managed container runtime (Fargate, Cloud Run, DigitalOcean App)"
+msgstr ""
+
+msgid "DeploymentTarget|Mobile app store"
+msgstr ""
+
+msgid "DeploymentTarget|No deployment planned"
+msgstr ""
+
+msgid "DeploymentTarget|Other hosting service"
+msgstr ""
+
+msgid "DeploymentTarget|Registry (package or container)"
+msgstr ""
+
+msgid "DeploymentTarget|Self-managed container runtime (Podman, Docker Swarm, Docker Compose)"
+msgstr ""
+
+msgid "DeploymentTarget|Serverless backend (Lambda, Cloud functions)"
+msgstr ""
+
+msgid "DeploymentTarget|Virtual machine (for example, EC2)"
+msgstr ""
+
msgid "Deployments"
msgstr ""
@@ -12411,6 +12601,9 @@ msgstr ""
msgid "Deployment|This deployment was created using the API"
msgstr ""
+msgid "Deployment|Triggerer"
+msgstr ""
+
msgid "Deployment|Waiting"
msgstr ""
@@ -12438,6 +12631,18 @@ msgstr ""
msgid "Deprecated API rate limits"
msgstr ""
+msgid "Deprecations|Feature deprecation and removal"
+msgstr ""
+
+msgid "Deprecations|For information on a possible replacement %{epicStart} learn more about Opstrace %{epicEnd}."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7 and are %{epicStart} scheduled for removal %{epicEnd} in GitLab 15.0."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7, and are %{removal_link_start} scheduled for removal %{link_end} in GitLab 15.0. For information on a possible replacement, %{opstrace_link_start} learn more about Opstrace %{link_end}."
+msgstr ""
+
msgid "Deprioritize label"
msgstr ""
@@ -12685,10 +12890,10 @@ msgstr ""
msgid "DevopsAdoption|At least one deploy"
msgstr ""
-msgid "DevopsAdoption|At least one issue opened"
+msgid "DevopsAdoption|At least one issue created"
msgstr ""
-msgid "DevopsAdoption|At least one merge request opened"
+msgid "DevopsAdoption|At least one merge request created"
msgstr ""
msgid "DevopsAdoption|At least one pipeline successfully run"
@@ -12895,6 +13100,9 @@ msgstr ""
msgid "Direct member"
msgstr ""
+msgid "Direct members"
+msgstr ""
+
msgid "Direct non-authenticated users to this page."
msgstr ""
@@ -13013,6 +13221,9 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "Dismiss Alert"
+msgstr ""
+
msgid "Dismiss merge request promotion"
msgstr ""
@@ -13040,9 +13251,15 @@ msgstr ""
msgid "Display alerts from all configured monitoring tools."
msgstr ""
+msgid "Display milestones"
+msgstr ""
+
msgid "Display name"
msgstr ""
+msgid "Display progress of child issues"
+msgstr ""
+
msgid "Display rendered file"
msgstr ""
@@ -13148,6 +13365,9 @@ msgstr ""
msgid "Download image"
msgstr ""
+msgid "Download payload"
+msgstr ""
+
msgid "Download raw data (.csv)"
msgstr ""
@@ -13325,6 +13545,9 @@ msgstr ""
msgid "Edit in Web IDE"
msgstr ""
+msgid "Edit in pipeline editor"
+msgstr ""
+
msgid "Edit in single-file editor"
msgstr ""
@@ -13367,6 +13590,9 @@ msgstr ""
msgid "Edit your most recent comment in a thread (from an empty textarea)"
msgstr ""
+msgid "Edit, lint, and visualize your pipeline."
+msgstr ""
+
msgid "Edited"
msgstr ""
@@ -13808,6 +14034,9 @@ msgstr ""
msgid "Enforce two-factor authentication for all user sign-ins."
msgstr ""
+msgid "Enhance security by storing service account keys in secret managers - learn more about %{docLinkStart}secret management with GitLab%{docLinkEnd}"
+msgstr ""
+
msgid "Ensure connectivity is available from the GitLab server to the Prometheus server"
msgstr ""
@@ -13868,6 +14097,9 @@ 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 following to confirm:"
+msgstr ""
+
msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
@@ -14400,9 +14632,6 @@ 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 ""
@@ -14538,6 +14767,9 @@ msgstr ""
msgid "Errors:"
msgstr ""
+msgid "Escalate this incident"
+msgstr ""
+
msgid "Escalation Policies"
msgstr ""
@@ -14550,6 +14782,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy"
+msgstr ""
+
msgid "Escalation policy:"
msgstr ""
@@ -14803,6 +15038,9 @@ msgstr ""
msgid "Existing sign in methods may be removed"
msgstr ""
+msgid "Exit."
+msgstr ""
+
msgid "Expand"
msgstr ""
@@ -14899,6 +15137,9 @@ msgstr ""
msgid "Explore public groups"
msgstr ""
+msgid "Explore public projects"
+msgstr ""
+
msgid "Explore snippets"
msgstr ""
@@ -15062,7 +15303,7 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
-msgid "Failed to assign a reviewer because no user was found."
+msgid "Failed to assign a reviewer because no user was specified."
msgstr ""
msgid "Failed to assign a user because no user was found."
@@ -15128,10 +15369,10 @@ msgstr ""
msgid "Failed to find import label for Jira import."
msgstr ""
-msgid "Failed to generate export, please try again later."
+msgid "Failed to find users for %{missing}"
msgstr ""
-msgid "Failed to generate report, please try again after sometime"
+msgid "Failed to generate export, please try again later."
msgstr ""
msgid "Failed to get ref."
@@ -15230,6 +15471,9 @@ msgstr ""
msgid "Failed to remove a to-do item for the design."
msgstr ""
+msgid "Failed to remove attention because no user was found."
+msgstr ""
+
msgid "Failed to remove mirror."
msgstr ""
@@ -15242,6 +15486,9 @@ msgstr ""
msgid "Failed to remove user key."
msgstr ""
+msgid "Failed to request attention because no user was found."
+msgstr ""
+
msgid "Failed to reset key. Please try again."
msgstr ""
@@ -15323,6 +15570,9 @@ msgstr ""
msgid "Feature Flags"
msgstr ""
+msgid "Feature deprecation and removal"
+msgstr ""
+
msgid "Feature flag status"
msgstr ""
@@ -15822,7 +16072,7 @@ msgstr ""
msgid "For each job, re-use the project workspace. If the workspace doesn't exist, use %{code_open}git clone%{code_close}."
msgstr ""
-msgid "For example, the application using the token or the purpose of the token."
+msgid "For example, the application using the token or the purpose of the token. Do not give sensitive information for the name of the token, as it will be visible to all %{resource_type} members."
msgstr ""
msgid "For files larger than this limit, only index the file name. The file content is neither indexed nor searchable."
@@ -15906,9 +16156,6 @@ msgstr ""
msgid "ForkProject|Select a namespace"
msgstr ""
-msgid "ForkProject|Select a namespace to fork the project"
-msgstr ""
-
msgid "ForkProject|The project can be accessed by any logged in user."
msgstr ""
@@ -16005,6 +16252,9 @@ msgstr ""
msgid "Full name"
msgstr ""
+msgid "GCP region configured"
+msgstr ""
+
msgid "GPG Key ID:"
msgstr ""
@@ -16185,6 +16435,9 @@ msgstr ""
msgid "Geo|Failed"
msgstr ""
+msgid "Geo|Filter Geo sites"
+msgstr ""
+
msgid "Geo|Filter by name"
msgstr ""
@@ -16596,6 +16849,12 @@ msgstr ""
msgid "GitLab Issue"
msgstr ""
+msgid "GitLab KAS"
+msgstr ""
+
+msgid "GitLab Memberships CSV Export"
+msgstr ""
+
msgid "GitLab Pages"
msgstr ""
@@ -16644,6 +16903,9 @@ 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 free to use. Many features for larger teams are part of our %{link_start}paid products%{link_end}. You can try Ultimate for free without any obligation or payment details."
+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 ""
@@ -16770,7 +17032,7 @@ msgstr ""
msgid "GitLabPages|When enabled, all attempts to visit your website through HTTP are automatically redirected to HTTPS using a response with status code 301. Requires a valid certificate for all domains. %{docs_link_start}Learn more.%{link_end}"
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. %{docs_link_start}Learn more.%{link_end}"
+msgid "GitLabPages|When using Pages under the general domain of a GitLab instance (%{pages_host}), you cannot use HTTPS with subdomains of subdomains. If your namespace or groupname contains a dot, it does not work. This is a limitation of the HTTP Over TLS protocol. HTTP pages work if you don't redirect HTTP to HTTPS. %{docs_link_start}Learn more.%{link_end}"
msgstr ""
msgid "GitLabPages|With GitLab Pages you can host your static website directly from your GitLab repository. %{docs_link_start}Learn more.%{link_end}"
@@ -16947,9 +17209,6 @@ msgstr ""
msgid "Go to find file"
msgstr ""
-msgid "Go to fork"
-msgstr ""
-
msgid "Go to issue boards"
msgstr ""
@@ -17157,9 +17416,6 @@ msgstr ""
msgid "Group Hooks"
msgstr ""
-msgid "Group ID"
-msgstr ""
-
msgid "Group Owner must have signed in with SAML before enabling Group Managed Accounts"
msgstr ""
@@ -17187,9 +17443,6 @@ msgstr ""
msgid "Group by"
msgstr ""
-msgid "Group description"
-msgstr ""
-
msgid "Group description (optional)"
msgstr ""
@@ -17304,7 +17557,7 @@ msgstr ""
msgid "Group: %{name}"
msgstr ""
-msgid "GroupActivityMetrics|Issues opened"
+msgid "GroupActivityMetrics|Issues created"
msgstr ""
msgid "GroupActivityMetrics|Last 90 days"
@@ -17313,7 +17566,7 @@ msgstr ""
msgid "GroupActivityMetrics|Members added"
msgstr ""
-msgid "GroupActivityMetrics|Merge Requests opened"
+msgid "GroupActivityMetrics|Merge Requests created"
msgstr ""
msgid "GroupActivityMetrics|Recent activity"
@@ -17604,6 +17857,9 @@ msgstr ""
msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
+msgid "GroupSettings|Choose a group path that does not start with a dash or end with a period. It can also contain alphanumeric characters and underscores."
+msgstr ""
+
msgid "GroupSettings|Compliance frameworks"
msgstr ""
@@ -17637,7 +17893,7 @@ msgstr ""
msgid "GroupSettings|If not specified at the group or instance level, the default is %{default_initial_branch_name}. Does not affect existing repositories."
msgstr ""
-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."
+msgid "GroupSettings|If the parent group's visibility is lower than the group's current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility."
msgstr ""
msgid "GroupSettings|New runners registration token has been generated!"
@@ -17754,7 +18010,10 @@ msgstr ""
msgid "Groups and projects"
msgstr ""
-msgid "Groups and subgroups"
+msgid "Groups are a great way to organize projects and people."
+msgstr ""
+
+msgid "Groups are the best way to manage projects and members."
msgstr ""
msgid "Groups to synchronize"
@@ -17865,13 +18124,16 @@ msgstr ""
msgid "GroupsTree|Are you sure you want to leave the \"%{fullName}\" group?"
msgstr ""
-msgid "GroupsTree|Edit group"
+msgid "GroupsTree|Delete"
+msgstr ""
+
+msgid "GroupsTree|Edit"
msgstr ""
msgid "GroupsTree|Failed to leave the group. Please make sure you are not the only owner."
msgstr ""
-msgid "GroupsTree|Leave this group"
+msgid "GroupsTree|Leave group"
msgstr ""
msgid "GroupsTree|Loading groups"
@@ -17883,9 +18145,57 @@ msgstr ""
msgid "GroupsTree|No groups or projects matched your search"
msgstr ""
+msgid "GroupsTree|Options"
+msgstr ""
+
msgid "GroupsTree|Search by name"
msgstr ""
+msgid "Groups|Avatar will be removed. Are you sure?"
+msgstr ""
+
+msgid "Groups|Changing group URL can have unintended side effects."
+msgstr ""
+
+msgid "Groups|Checking group URL availability..."
+msgstr ""
+
+msgid "Groups|Enter a descriptive name for your group."
+msgstr ""
+
+msgid "Groups|Group ID"
+msgstr ""
+
+msgid "Groups|Group URL"
+msgstr ""
+
+msgid "Groups|Group avatar"
+msgstr ""
+
+msgid "Groups|Group description (optional)"
+msgstr ""
+
+msgid "Groups|Group name"
+msgstr ""
+
+msgid "Groups|Group path is available."
+msgstr ""
+
+msgid "Groups|Group path is unavailable. Path has been replaced with a suggested available path."
+msgstr ""
+
+msgid "Groups|Learn more"
+msgstr ""
+
+msgid "Groups|Must start with letter, digit, emoji, or underscore. Can also contain periods, dashes, spaces, and parentheses."
+msgstr ""
+
+msgid "Groups|Remove avatar"
+msgstr ""
+
+msgid "Groups|Save changes"
+msgstr ""
+
msgid "Guideline"
msgstr ""
@@ -17895,6 +18205,9 @@ msgstr ""
msgid "HAR file path or URL"
msgstr ""
+msgid "HTTP Archive (HAR)"
+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 ""
@@ -18299,6 +18612,9 @@ msgstr ""
msgid "INFO: Your SSH key is expiring soon. Please generate a new key."
msgstr ""
+msgid "IP"
+msgstr ""
+
msgid "IP Address"
msgstr ""
@@ -18335,6 +18651,9 @@ msgstr ""
msgid "IdentityVerification|Verify your identity"
msgstr ""
+msgid "IdentityVerification|You can always verify your account at a later time to create a group."
+msgstr ""
+
msgid "If any indexed field exceeds this limit, it is truncated to this number of characters. The rest of the content is neither indexed nor searchable. This does not apply to repository and wiki indexing. For unlimited characters, set this to 0."
msgstr ""
@@ -18392,6 +18711,9 @@ msgstr ""
msgid "If you add %{codeStart}needs%{codeEnd} to jobs in your pipeline you'll be able to view the %{codeStart}needs%{codeEnd} relationships between jobs in this tab as a %{linkStart}Directed Acyclic Graph (DAG)%{linkEnd}."
msgstr ""
+msgid "If you are added to a project, it will be displayed here."
+msgstr ""
+
msgid "If you did not initiate these sign-in attempts, please reach out to your administrator or enable two-factor authentication (2FA) on your account."
msgstr ""
@@ -18704,12 +19026,24 @@ msgstr ""
msgid "InProductMarketing|3 ways to dive into GitLab CI/CD"
msgstr ""
+msgid "InProductMarketing|A single application eliminates complex integrations, data chokepoints, and toolchain maintenance, resulting in greater productivity and lower cost."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features, build more efficiently, strengthen security and compliance."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features."
+msgstr ""
+
msgid "InProductMarketing|Actually, GitLab makes the team work (better)"
msgstr ""
msgid "InProductMarketing|And finally %{deploy_link} a Python application."
msgstr ""
+msgid "InProductMarketing|And many more..."
+msgstr ""
+
msgid "InProductMarketing|Are your runners ready?"
msgstr ""
@@ -18728,15 +19062,33 @@ msgstr ""
msgid "InProductMarketing|Blog"
msgstr ""
+msgid "InProductMarketing|Break down silos to coordinate seamlessly across development, operations, and security with a consistent experience across the development lifecycle."
+msgstr ""
+
+msgid "InProductMarketing|Burn up/down charts"
+msgstr ""
+
msgid "InProductMarketing|By enabling code owners and required merge approvals the right person will review the right MR. This is a win-win: cleaner code and a more efficient review process."
msgstr ""
msgid "InProductMarketing|Click on the number below that corresponds with your answer — 1 being very difficult, 5 being very easy."
msgstr ""
+msgid "InProductMarketing|Code owners"
+msgstr ""
+
msgid "InProductMarketing|Code owners and required merge approvals are part of the paid tiers of GitLab. You can start a free 30-day trial of GitLab Ultimate and enable these features in less than 5 minutes with no credit card required."
msgstr ""
+msgid "InProductMarketing|Code review analytics"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration across stages in GitLab"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration made easy"
+msgstr ""
+
msgid "InProductMarketing|Create a custom CI runner with just a few clicks"
msgstr ""
@@ -18746,12 +19098,21 @@ msgstr ""
msgid "InProductMarketing|Create a project in GitLab in 5 minutes"
msgstr ""
+msgid "InProductMarketing|Create well-defined workflows by using scoped labels on issues, merge requests, and epics. Labels with the same scope cannot be used together, which prevents conflicts."
+msgstr ""
+
msgid "InProductMarketing|Create your first project!"
msgstr ""
+msgid "InProductMarketing|Define who owns specific files or directories, so the right reviewers are suggested when a merge request introduces changes to those files."
+msgstr ""
+
msgid "InProductMarketing|Deliver Better Products Faster"
msgstr ""
+msgid "InProductMarketing|Dependency scanning"
+msgstr ""
+
msgid "InProductMarketing|Did you know teams that use GitLab are far more efficient?"
msgstr ""
@@ -18761,15 +19122,27 @@ msgstr ""
msgid "InProductMarketing|Dig in and create a project and a repo"
msgstr ""
+msgid "InProductMarketing|Discover Premium & Ultimate"
+msgstr ""
+
+msgid "InProductMarketing|Discover Premium & Ultimate."
+msgstr ""
+
msgid "InProductMarketing|Do you have a minute?"
msgstr ""
msgid "InProductMarketing|Do you have a teammate who would be perfect for this task?"
msgstr ""
+msgid "InProductMarketing|Dynamic application security testing"
+msgstr ""
+
msgid "InProductMarketing|Easy"
msgstr ""
+msgid "InProductMarketing|Epics"
+msgstr ""
+
msgid "InProductMarketing|Expand your DevOps journey with a free GitLab trial"
msgstr ""
@@ -18791,9 +19164,15 @@ msgstr ""
msgid "InProductMarketing|Feel the need for speed?"
msgstr ""
+msgid "InProductMarketing|Find and fix bottlenecks in your code review process by understanding how long open merge requests have been in review."
+msgstr ""
+
msgid "InProductMarketing|Find out how your teams are really doing"
msgstr ""
+msgid "InProductMarketing|Find out if your external libraries are safe. Run dependency scanning jobs that check for known vulnerabilities in your external libraries."
+msgstr ""
+
msgid "InProductMarketing|Follow our steps"
msgstr ""
@@ -18830,6 +19209,9 @@ msgstr ""
msgid "InProductMarketing|GitLab is better with teammates to help out!"
msgstr ""
+msgid "InProductMarketing|GitLab is infrastructure agnostic (supporting GCP, AWS, Azure, OpenShift, VMWare, On Prem, Bare Metal, and more), offering a consistent workflow experience – irrespective of the environment."
+msgstr ""
+
msgid "InProductMarketing|GitLab provides static application security testing (SAST), dynamic application security testing (DAST), container scanning, and dependency scanning to help you deliver secure applications along with license compliance."
msgstr ""
@@ -18920,21 +19302,36 @@ msgstr ""
msgid "InProductMarketing|It's also possible to simply %{external_repo_link} in order to take advantage of GitLab's CI/CD."
msgstr ""
+msgid "InProductMarketing|Keep your code quality high by defining who should approve merge requests and how many approvals are required."
+msgstr ""
+
msgid "InProductMarketing|Launch GitLab CI/CD in 20 minutes or less"
msgstr ""
+msgid "InProductMarketing|Lower cost of development"
+msgstr ""
+
+msgid "InProductMarketing|Make it easier to collaborate on high-level ideas by grouping related issues in an epic."
+msgstr ""
+
msgid "InProductMarketing|Making the switch? It's easier than you think to import your projects into GitLab. Move %{github_link}, or import something %{bitbucket_link}."
msgstr ""
msgid "InProductMarketing|Master the art of importing!"
msgstr ""
+msgid "InProductMarketing|Merge request approval rule"
+msgstr ""
+
msgid "InProductMarketing|Move on to easily creating a Pages website %{ci_template_link}"
msgstr ""
msgid "InProductMarketing|Multiple owners, confusing workstreams? We've got you covered"
msgstr ""
+msgid "InProductMarketing|Multiple required approvers"
+msgstr ""
+
msgid "InProductMarketing|Need an alternative to importing?"
msgstr ""
@@ -18947,18 +19344,33 @@ msgstr ""
msgid "InProductMarketing|Our tool brings all the things together"
msgstr ""
+msgid "InProductMarketing|Protect your web application by using DAST to examine for vulnerabilities in deployed environments."
+msgstr ""
+
msgid "InProductMarketing|Rapid development, simplified"
msgstr ""
msgid "InProductMarketing|Reduce Security & Compliance Risk"
msgstr ""
+msgid "InProductMarketing|Require multiple approvers on a merge request, so you know it's in good shape before it's merged."
+msgstr ""
+
+msgid "InProductMarketing|Roadmaps"
+msgstr ""
+
+msgid "InProductMarketing|Scoped labels"
+msgstr ""
+
msgid "InProductMarketing|Security that's integrated into your development lifecycle"
msgstr ""
msgid "InProductMarketing|Sometimes you're not ready to make a full transition to a new tool. If you're not ready to fully commit, %{mirroring_link} gives you a safe way to try out GitLab in parallel with your current tool."
msgstr ""
+msgid "InProductMarketing|Speed. Efficiency. Trust."
+msgstr ""
+
msgid "InProductMarketing|Spin up an autoscaling runner in GitLab"
msgstr ""
@@ -18968,6 +19380,9 @@ msgstr ""
msgid "InProductMarketing|Start a Self-Managed trial"
msgstr ""
+msgid "InProductMarketing|Start a free trial"
+msgstr ""
+
msgid "InProductMarketing|Start a free trial of GitLab Ultimate – no credit card required"
msgstr ""
@@ -19034,6 +19449,9 @@ msgstr ""
msgid "InProductMarketing|To understand and get the most out of GitLab, start at the beginning and %{project_link}. In GitLab, repositories are part of a project, so after you've created your project you can go ahead and %{repo_link}."
msgstr ""
+msgid "InProductMarketing|Track completed issues in a chart, so you can see how a milestone is progressing at a glance."
+msgstr ""
+
msgid "InProductMarketing|Try GitLab Ultimate for free"
msgstr ""
@@ -19070,6 +19488,9 @@ msgstr ""
msgid "InProductMarketing|Very easy"
msgstr ""
+msgid "InProductMarketing|Visualize your epics and milestones in a timeline."
+msgstr ""
+
msgid "InProductMarketing|Want to host GitLab on your servers?"
msgstr ""
@@ -19091,6 +19512,9 @@ msgstr ""
msgid "InProductMarketing|YouTube"
msgstr ""
+msgid "InProductMarketing|Your software, deployed your way"
+msgstr ""
+
msgid "InProductMarketing|Your teams can be more efficient"
msgstr ""
@@ -19211,9 +19635,18 @@ msgstr ""
msgid "IncidentManagement|No incidents to display."
msgstr ""
+msgid "IncidentManagement|None"
+msgstr ""
+
msgid "IncidentManagement|Open"
msgstr ""
+msgid "IncidentManagement|Page your team with escalation policies"
+msgstr ""
+
+msgid "IncidentManagement|Paged"
+msgstr ""
+
msgid "IncidentManagement|Published"
msgstr ""
@@ -19223,6 +19656,9 @@ msgstr ""
msgid "IncidentManagement|Severity"
msgstr ""
+msgid "IncidentManagement|Status"
+msgstr ""
+
msgid "IncidentManagement|There are no closed incidents"
msgstr ""
@@ -19241,6 +19677,9 @@ msgstr ""
msgid "IncidentManagement|Unpublished"
msgstr ""
+msgid "IncidentManagement|Use escalation policies to automatically page your team when incidents are created."
+msgstr ""
+
msgid "IncidentSettings|Activate \"time to SLA\" countdown timer"
msgstr ""
@@ -19286,7 +19725,10 @@ msgstr ""
msgid "Incidents"
msgstr ""
-msgid "Incidents|Add a URL"
+msgid "Incidents|Add image details"
+msgstr ""
+
+msgid "Incidents|Add text or a link to display with your image. If you don't add either, the file name displays instead."
msgstr ""
msgid "Incidents|Drop or %{linkStart}upload%{linkEnd} a metric screenshot to attach it to the incident"
@@ -19301,10 +19743,10 @@ msgstr ""
msgid "Incidents|There was an issue loading metric images."
msgstr ""
-msgid "Incidents|There was an issue uploading your image."
+msgid "Incidents|There was an issue updating your image."
msgstr ""
-msgid "Incidents|You can optionally add a URL to link users to the original graph."
+msgid "Incidents|There was an issue uploading your image."
msgstr ""
msgid "Incident|Alert details"
@@ -19313,9 +19755,18 @@ msgstr ""
msgid "Incident|Are you sure you wish to delete this image?"
msgstr ""
+msgid "Incident|Delete image"
+msgstr ""
+
msgid "Incident|Deleting %{filename}"
msgstr ""
+msgid "Incident|Edit image text or link"
+msgstr ""
+
+msgid "Incident|Editing %{filename}"
+msgstr ""
+
msgid "Incident|Metrics"
msgstr ""
@@ -19587,12 +20038,18 @@ msgstr ""
msgid "Integrations|Branches for which notifications are to be sent"
msgstr ""
+msgid "Integrations|Clear if using a self-signed certificate."
+msgstr ""
+
msgid "Integrations|Comment detail:"
msgstr ""
msgid "Integrations|Comment settings:"
msgstr ""
+msgid "Integrations|Connection details"
+msgstr ""
+
msgid "Integrations|Connection failed. Please check your settings."
msgstr ""
@@ -19617,6 +20074,9 @@ msgstr ""
msgid "Integrations|Enable GitLab.com slash commands in a Slack workspace."
msgstr ""
+msgid "Integrations|Enable SSL verification"
+msgstr ""
+
msgid "Integrations|Enable comments"
msgstr ""
@@ -19695,6 +20155,9 @@ msgstr ""
msgid "Integrations|Return to GitLab for Jira"
msgstr ""
+msgid "Integrations|SSL verification"
+msgstr ""
+
msgid "Integrations|Save settings?"
msgstr ""
@@ -19740,9 +20203,6 @@ msgstr ""
msgid "Integrations|Use default settings"
msgstr ""
-msgid "Integrations|When you mention a Jira issue in a commit or merge request, GitLab creates a remote link and comment (if enabled)."
-msgstr ""
-
msgid "Integrations|You can now close this window and return to the GitLab for Jira application."
msgstr ""
@@ -19767,9 +20227,6 @@ msgstr ""
msgid "Integrations|can't exceed %{recipients_limit}"
msgstr ""
-msgid "Interactive developer security education."
-msgstr ""
-
msgid "Interactive mode"
msgstr ""
@@ -20259,6 +20716,9 @@ msgstr ""
msgid "IssueAnalytics|Assignees"
msgstr ""
+msgid "IssueAnalytics|Created by"
+msgstr ""
+
msgid "IssueAnalytics|Due date"
msgstr ""
@@ -20271,9 +20731,6 @@ msgstr ""
msgid "IssueAnalytics|Milestone"
msgstr ""
-msgid "IssueAnalytics|Opened by"
-msgstr ""
-
msgid "IssueAnalytics|Status"
msgstr ""
@@ -20397,10 +20854,10 @@ msgstr ""
msgid "IssuesAnalytics|Avg/Month:"
msgstr ""
-msgid "IssuesAnalytics|Issues opened"
+msgid "IssuesAnalytics|Issues created"
msgstr ""
-msgid "IssuesAnalytics|Issues opened per month"
+msgid "IssuesAnalytics|Issues created per month"
msgstr ""
msgid "IssuesAnalytics|Last 12 months"
@@ -20427,6 +20884,9 @@ msgstr ""
msgid "It looks like you have some draft commits in this branch."
msgstr ""
+msgid "It looks like you're attempting to activate your subscription. Use %{a_start}the Subscription page%{a_end} instead."
+msgstr ""
+
msgid "It may be several days before you see feature usage data."
msgstr ""
@@ -20655,6 +21115,9 @@ msgstr ""
msgid "JiraConnect|You can now close this window and return to Jira."
msgstr ""
+msgid "JiraConnect|You don't have permission to create branches for this project. Select a different project or contact the project owner for access. %{linkStart}Learn more.%{linkEnd}"
+msgstr ""
+
msgid "JiraRequest|A connection error occurred while connecting to Jira. Try your request again."
msgstr ""
@@ -20703,13 +21166,13 @@ msgstr ""
msgid "JiraService|Define the type of Jira issue to create from a vulnerability."
msgstr ""
-msgid "JiraService|Displaying Jira issues while leaving the GitLab issue functionality enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
+msgid "JiraService|Displaying Jira issues while leaving GitLab issues also enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
msgstr ""
-msgid "JiraService|Enable Jira issues"
+msgid "JiraService|Enable Jira issue creation from vulnerabilities"
msgstr ""
-msgid "JiraService|Enable Jira issues creation from vulnerabilities"
+msgid "JiraService|Enable Jira issues"
msgstr ""
msgid "JiraService|Enable Jira transitions"
@@ -20826,16 +21289,19 @@ msgstr ""
msgid "JiraService|View Jira issues in GitLab"
msgstr ""
-msgid "JiraService|Warning: All GitLab users that have access to this GitLab project are able to view all issues from the Jira project specified below."
+msgid "JiraService|Warning: All GitLab users with access to this GitLab project can view all issues from the Jira project you select."
msgstr ""
msgid "JiraService|Web URL"
msgstr ""
-msgid "JiraService|Work on Jira issues without leaving GitLab. Adds a Jira menu to access your list of Jira issues and view any issue as read-only."
+msgid "JiraService|When a Jira issue is mentioned in a commit or merge request, a remote link and comment (if enabled) will be created."
msgstr ""
-msgid "JiraService|You need to configure Jira before enabling this integration. For more details, read the %{jira_doc_link_start}Jira integration documentation%{link_end}."
+msgid "JiraService|Work on Jira issues without leaving GitLab. Add a Jira menu to access a read-only list of your Jira issues."
+msgstr ""
+
+msgid "JiraService|You must configure Jira before enabling this integration. %{jira_doc_link_start}Learn more.%{link_end}"
msgstr ""
msgid "Job"
@@ -20847,9 +21313,6 @@ msgstr ""
msgid "Job Failed #%{build_id}"
msgstr ""
-msgid "Job ID"
-msgstr ""
-
msgid "Job artifact"
msgstr ""
@@ -20916,9 +21379,27 @@ msgstr ""
msgid "Jobs|You're about to retry a job that failed because it attempted to deploy code that is older than the latest deployment. Retrying this job could result in overwriting the environment with the older source code."
msgstr ""
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source} into %{target}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{ref}"
+msgstr ""
+
+msgid "Job|Are you sure you want to erase this job log and artifacts?"
+msgstr ""
+
msgid "Job|Browse"
msgstr ""
+msgid "Job|Cancel"
+msgstr ""
+
msgid "Job|Complete Raw"
msgstr ""
@@ -20928,6 +21409,9 @@ msgstr ""
msgid "Job|Erase job log and artifacts"
msgstr ""
+msgid "Job|Finished at"
+msgstr ""
+
msgid "Job|Job artifacts"
msgstr ""
@@ -20940,7 +21424,7 @@ msgstr ""
msgid "Job|Keep"
msgstr ""
-msgid "Job|Pipeline"
+msgid "Job|Retry"
msgstr ""
msgid "Job|Scroll to bottom"
@@ -20952,6 +21436,9 @@ msgstr ""
msgid "Job|Show complete raw"
msgstr ""
+msgid "Job|Status"
+msgstr ""
+
msgid "Job|The artifacts were removed"
msgstr ""
@@ -20979,21 +21466,12 @@ msgstr ""
msgid "Job|delayed"
msgstr ""
-msgid "Job|for"
-msgstr ""
-
-msgid "Job|into"
-msgstr ""
-
msgid "Job|manual"
msgstr ""
msgid "Job|triggered"
msgstr ""
-msgid "Job|with"
-msgstr ""
-
msgid "Join Zoom meeting"
msgstr ""
@@ -21096,9 +21574,6 @@ msgstr ""
msgid "Ki"
msgstr ""
-msgid "Kontra"
-msgstr ""
-
msgid "Kroki"
msgstr ""
@@ -21424,6 +21899,9 @@ msgstr ""
msgid "Learn more about Auto DevOps"
msgstr ""
+msgid "Learn more about GitLab"
+msgstr ""
+
msgid "Learn more about Needs relationships"
msgstr ""
@@ -21763,9 +22241,18 @@ msgstr ""
msgid "Licenses|Displays licenses detected in the project, based on the %{linkStart}latest successful%{linkEnd} scan"
msgstr ""
+msgid "Licenses|Drag your license file here or %{linkStart}click to upload%{linkEnd}."
+msgstr ""
+
+msgid "Licenses|Drop your license file to start the upload."
+msgstr ""
+
msgid "Licenses|Error fetching the license list. Please check your network connection and try again."
msgstr ""
+msgid "Licenses|Error: You are trying to upload something other than a file"
+msgstr ""
+
msgid "Licenses|License Compliance"
msgstr ""
@@ -21784,6 +22271,9 @@ msgstr ""
msgid "Licenses|Specified policies in this project"
msgstr ""
+msgid "Licenses|The file could not be uploaded."
+msgstr ""
+
msgid "Licenses|The license list details information about the licenses used within your project."
msgstr ""
@@ -21817,13 +22307,6 @@ msgstr ""
msgid "Limit the size of Sidekiq jobs stored in Redis."
msgstr ""
-msgid "Limited to showing %d event at most"
-msgid_plural "Limited to showing %d events at most"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-msgstr[3] ""
-
msgid "Limiting mode"
msgstr ""
@@ -21833,6 +22316,9 @@ msgstr ""
msgid "Link"
msgstr ""
+msgid "Link (optional)"
+msgstr ""
+
msgid "Link Prometheus monitoring to GitLab."
msgstr ""
@@ -21869,6 +22355,9 @@ msgstr ""
msgid "Linked emails (%{email_count})"
msgstr ""
+msgid "Linked epics"
+msgstr ""
+
msgid "Linked issues"
msgstr ""
@@ -21896,6 +22385,15 @@ msgstr ""
msgid "List of all merge commits"
msgstr ""
+msgid "List of environments for this project"
+msgstr ""
+
+msgid "List of suitable GCP locations"
+msgstr ""
+
+msgid "List of users allowed to exceed the rate limit."
+msgstr ""
+
msgid "List options"
msgstr ""
@@ -22115,6 +22613,9 @@ msgstr ""
msgid "Maintenance mode"
msgstr ""
+msgid "Make adjustments to how your GitLab instance is set up."
+msgstr ""
+
msgid "Make and review changes in the browser with the Web IDE"
msgstr ""
@@ -22259,6 +22760,12 @@ msgstr ""
msgid "MarkdownEditor|Add italic text (%{modifier_key}I)"
msgstr ""
+msgid "MarkdownEditor|Add strikethrough text (%{modifierKey}⇧X)"
+msgstr ""
+
+msgid "MarkdownEditor|Add strikethrough text (%{modifier_key}⇧X)"
+msgstr ""
+
msgid "Marked For Deletion At - %{deletion_time}"
msgstr ""
@@ -22520,6 +23027,9 @@ msgstr ""
msgid "Maximum push size (MB)"
msgstr ""
+msgid "Maximum requests per 10 minutes per user"
+msgstr ""
+
msgid "Maximum requests per minute"
msgstr ""
@@ -22610,6 +23120,23 @@ msgstr ""
msgid "Members of a group may only view projects they have permission to access"
msgstr ""
+msgid "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seat in use and will be billed for the overage."
+msgid_plural "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seats in use and will be billed for the overage."
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
+msgid "MembersOverage|You are about to incur additional charges"
+msgstr ""
+
+msgid "MembersOverage|Your subscription includes %d seat."
+msgid_plural "MembersOverage|Your subscription includes %d seats."
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "Membership"
msgstr ""
@@ -22814,9 +23341,6 @@ msgstr ""
msgid "Merge request not merged"
msgstr ""
-msgid "Merge request pipelines 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 merge request pipelines."
-msgstr ""
-
msgid "Merge request reports"
msgstr ""
@@ -22913,13 +23437,13 @@ msgstr ""
msgid "MergeRequests|Create issue to resolve thread"
msgstr ""
-msgid "MergeRequests|Failed to squash. Should be done manually."
+msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Saving the comment failed"
+msgid "MergeRequests|Squashing failed: Squash the commits locally, resolve any conflicts, then push the branch."
msgstr ""
-msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
+msgid "MergeRequests|Squashing not allowed: This project doesn't allow you to squash commits when merging."
msgstr ""
msgid "MergeRequests|Thread stays resolved"
@@ -23764,6 +24288,18 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "MrList|Assigned to %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from assignee %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from reviewer %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Review requested from %{name}, go to their profile."
+msgstr ""
+
msgid "Multi-project"
msgstr ""
@@ -23797,7 +24333,7 @@ msgstr ""
msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "My Awesome Group"
+msgid "My awesome group"
msgstr ""
msgid "My company or team"
@@ -24423,9 +24959,6 @@ msgstr ""
msgid "No available branches"
msgstr ""
-msgid "No available groups to fork the project."
-msgstr ""
-
msgid "No branches found"
msgstr ""
@@ -24636,6 +25169,9 @@ msgstr ""
msgid "No ref selected"
msgstr ""
+msgid "No regions configured"
+msgstr ""
+
msgid "No related merge requests found."
msgstr ""
@@ -25452,6 +25988,9 @@ msgstr ""
msgid "Only reCAPTCHA v2 is supported:"
msgstr ""
+msgid "Only required if not using role instance credentials."
+msgstr ""
+
msgid "Only use lowercase letters, numbers, and underscores."
msgstr ""
@@ -25476,9 +26015,6 @@ msgstr ""
msgid "Open a CLI and connect to the cluster you want to install the agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
-msgid "Open epics"
-msgstr ""
-
msgid "Open errors"
msgstr ""
@@ -25518,7 +26054,7 @@ msgstr ""
msgid "Opened issues"
msgstr ""
-msgid "OpenedNDaysAgo|Opened"
+msgid "OpenedNDaysAgo|Created"
msgstr ""
msgid "Opens in a new window"
@@ -25563,9 +26099,6 @@ msgstr ""
msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
-msgid "Optional."
-msgstr ""
-
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
msgstr ""
@@ -26356,6 +26889,9 @@ msgstr ""
msgid "PerformanceBar|Memory"
msgstr ""
+msgid "PerformanceBar|Memory report"
+msgstr ""
+
msgid "PerformanceBar|Redis calls"
msgstr ""
@@ -26389,18 +26925,12 @@ msgstr ""
msgid "PerformanceBar|wall"
msgstr ""
-msgid "Performs a rebase but skips triggering a new pipeline"
-msgstr ""
-
msgid "Period in seconds"
msgstr ""
msgid "Permalink"
msgstr ""
-msgid "Permanently delete project"
-msgstr ""
-
msgid "Permanently remove group"
msgstr ""
@@ -26671,6 +27201,51 @@ msgstr ""
msgid "PipelineStatusTooltip|Pipeline: %{ci_status}"
msgstr ""
+msgid "PipelineWizardDefaultCommitMessage|Add %{filename}"
+msgstr ""
+
+msgid "PipelineWizardDefaultCommitMessage|Update %{filename}"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|At least one entry is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This field is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This value is not valid"
+msgstr ""
+
+msgid "PipelineWizardListWidget|add another step"
+msgstr ""
+
+msgid "PipelineWizardListWidget|remove step"
+msgstr ""
+
+msgid "PipelineWizard|Commit"
+msgstr ""
+
+msgid "PipelineWizard|Commit Message"
+msgstr ""
+
+msgid "PipelineWizard|Commit changes to your file"
+msgstr ""
+
+msgid "PipelineWizard|Commit file to Branch"
+msgstr ""
+
+msgid "PipelineWizard|Commit your new file"
+msgstr ""
+
+msgid "PipelineWizard|The file has been committed."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem committing the changes."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem while checking whether your file already exists in the specified branch."
+msgstr ""
+
msgid "Pipelines"
msgstr ""
@@ -26785,7 +27360,7 @@ msgstr ""
msgid "Pipelines|Project cache successfully reset."
msgstr ""
-msgid "Pipelines|Revoke"
+msgid "Pipelines|Revoke trigger"
msgstr ""
msgid "Pipelines|Something went wrong while cleaning runners cache."
@@ -26830,6 +27405,12 @@ msgstr ""
msgid "Pipelines|This is a child pipeline within the parent pipeline"
msgstr ""
+msgid "Pipelines|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipelines|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipelines|This pipeline will run code originating from a forked project merge request. This means that the code can potentially have security considerations like exposing CI variables."
msgstr ""
@@ -26872,9 +27453,6 @@ msgstr ""
msgid "Pipelines|Your changes have been successfully committed. Now redirecting to the new merge request page."
msgstr ""
-msgid "Pipelines|detached"
-msgstr ""
-
msgid "Pipelines|error"
msgstr ""
@@ -26884,10 +27462,13 @@ msgstr ""
msgid "Pipelines|latest"
msgstr ""
-msgid "Pipelines|stuck"
+msgid "Pipelines|merge request"
+msgstr ""
+
+msgid "Pipelines|merge train"
msgstr ""
-msgid "Pipelines|train"
+msgid "Pipelines|stuck"
msgstr ""
msgid "Pipelines|yaml invalid"
@@ -27019,6 +27600,12 @@ msgstr ""
msgid "Pipeline|This change will not change the overall test coverage if merged."
msgstr ""
+msgid "Pipeline|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipeline|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipeline|Trigger author"
msgstr ""
@@ -27043,6 +27630,12 @@ msgstr ""
msgid "Pipeline|for"
msgstr ""
+msgid "Pipeline|merge request"
+msgstr ""
+
+msgid "Pipeline|merge train"
+msgstr ""
+
msgid "Pipeline|on"
msgstr ""
@@ -27181,9 +27774,6 @@ msgstr ""
msgid "Please enter a valid time interval"
msgstr ""
-msgid "Please enter or upload a valid license."
-msgstr ""
-
msgid "Please enter your current password."
msgstr ""
@@ -27292,9 +27882,6 @@ msgstr ""
msgid "Please type %{phrase_code} to proceed or close this modal to cancel."
msgstr ""
-msgid "Please type the following to confirm:"
-msgstr ""
-
msgid "Please use this form to report to the admin users who create spam issues, comments or behave inappropriately."
msgstr ""
@@ -27322,12 +27909,27 @@ msgstr ""
msgid "Policies"
msgstr ""
+msgid "Policy '%{escalation_policy_name}' does not exist."
+msgstr ""
+
msgid "Policy management project does have any policies in %{policy_path}"
msgstr ""
msgid "Policy project doesn't exist"
msgstr ""
+msgid "PolicyRuleMultiSelect|%{firstLabel} +%{numberOfAdditionalLabels} more"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|All %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select all"
+msgstr ""
+
msgid "Polling interval multiplier"
msgstr ""
@@ -27556,6 +28158,9 @@ msgstr ""
msgid "Private projects can be created in your personal namespace with:"
msgstr ""
+msgid "Problem with %{name} command: %{message}."
+msgstr ""
+
msgid "Proceed"
msgstr ""
@@ -28030,6 +28635,9 @@ msgstr ""
msgid "Progress"
msgstr ""
+msgid "Progress tracking"
+msgstr ""
+
msgid "Project"
msgstr ""
@@ -28261,6 +28869,9 @@ msgstr ""
msgid "ProjectQualitySummary|Failure"
msgstr ""
+msgid "ProjectQualitySummary|Get insight into the overall percentage of tests in your project that succeed, fail and are skipped."
+msgstr ""
+
msgid "ProjectQualitySummary|Latest pipeline results"
msgstr ""
@@ -28279,6 +28890,12 @@ msgstr ""
msgid "ProjectQualitySummary|See project Code Coverage Statistics"
msgstr ""
+msgid "ProjectQualitySummary|Set up test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|Set up test runs (opens in a new tab)"
+msgstr ""
+
msgid "ProjectQualitySummary|Skipped"
msgstr ""
@@ -28555,13 +29172,19 @@ msgstr ""
msgid "ProjectSettings|LFS objects from this repository are available to forks. %{linkStart}How do I remove them?%{linkEnd}"
msgstr ""
+msgid "ProjectSettings|Learn about commit history."
+msgstr ""
+
+msgid "ProjectSettings|Leave empty to use default template."
+msgstr ""
+
msgid "ProjectSettings|Manage who can see the project in the public access directory."
msgstr ""
msgid "ProjectSettings|Manages large files such as audio, video, and graphics files."
msgstr ""
-msgid "ProjectSettings|Maximum 500 characters."
+msgid "ProjectSettings|Maximum %{maxLength} characters."
msgstr ""
msgid "ProjectSettings|Merge checks"
@@ -28702,6 +29325,9 @@ msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
msgstr ""
+msgid "ProjectSettings|The default template will be applied on save."
+msgstr ""
+
msgid "ProjectSettings|These checks must pass before merge requests can be merged."
msgstr ""
@@ -28756,6 +29382,9 @@ msgstr ""
msgid "ProjectSettings|What are badges?"
msgstr ""
+msgid "ProjectSettings|What are merge trains?"
+msgstr ""
+
msgid "ProjectSettings|When merge request pipelines are enabled in the CI/CD configuration file, pipelines validate the combined results of the source and target branches. %{link_start}How to configure merge request pipelines?%{link_end}"
msgstr ""
@@ -28873,6 +29502,9 @@ msgstr ""
msgid "Projects are organized into groups"
msgstr ""
+msgid "Projects are where you store your code, access issues, wiki and other features of GitLab."
+msgstr ""
+
msgid "Projects contributed to"
msgstr ""
@@ -28888,12 +29520,6 @@ msgstr ""
msgid "Projects to index"
msgstr ""
-msgid "Projects will be permanently deleted after a %{waiting_period}-day waiting period."
-msgstr ""
-
-msgid "Projects will be permanently deleted immediately."
-msgstr ""
-
msgid "Projects with critical vulnerabilities"
msgstr ""
@@ -28978,6 +29604,9 @@ msgstr ""
msgid "ProjectsNew|Import project"
msgstr ""
+msgid "ProjectsNew|Include a Getting Started README"
+msgstr ""
+
msgid "ProjectsNew|Initialize repository with a README"
msgstr ""
@@ -28993,6 +29622,9 @@ msgstr ""
msgid "ProjectsNew|Project description %{tag_start}(optional)%{tag_end}"
msgstr ""
+msgid "ProjectsNew|Recommended if you're new to GitLab"
+msgstr ""
+
msgid "ProjectsNew|Run CI/CD for external repository"
msgstr ""
@@ -29410,6 +30042,9 @@ msgstr ""
msgid "ProtectedBranch|Unprotect"
msgstr ""
+msgid "ProtectedBranch|Unprotect branch"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
@@ -29437,6 +30072,9 @@ msgstr ""
msgid "ProtectedEnvironment|Protected Environment (%{protected_environments_count})"
msgstr ""
+msgid "ProtectedEnvironment|Required approvals"
+msgstr ""
+
msgid "ProtectedEnvironment|Select an environment"
msgstr ""
@@ -29458,10 +30096,13 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|Unprotect tag"
+msgstr ""
+
msgid "ProtectedTags|default"
msgstr ""
-msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
+msgid "ProtectedTag|By default, protected tags restrict who can modify the tag."
msgstr ""
msgid "ProtectedTag|Learn more."
@@ -29524,6 +30165,9 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Public projects are an easy way to allow everyone to have read-only access."
+msgstr ""
+
msgid "Publish to status page"
msgstr ""
@@ -29680,9 +30324,6 @@ msgstr ""
msgid "QualitySummary|Project quality"
msgstr ""
-msgid "Quarters"
-msgstr ""
-
msgid "Query"
msgstr ""
@@ -29767,6 +30408,9 @@ msgstr ""
msgid "Read more about project permissions %{help_link_open}here%{help_link_close}"
msgstr ""
+msgid "Read more about related epics"
+msgstr ""
+
msgid "Read more about related issues"
msgstr ""
@@ -29797,10 +30441,7 @@ msgstr ""
msgid "Rebase source branch on the target branch."
msgstr ""
-msgid "Rebase without CI"
-msgstr ""
-
-msgid "Rebases and triggers a pipeline"
+msgid "Rebase without pipeline"
msgstr ""
msgid "Recaptcha verified?"
@@ -29851,9 +30492,6 @@ msgstr ""
msgid "Reconfigure"
msgstr ""
-msgid "Recovering projects"
-msgstr ""
-
msgid "Recovery Codes"
msgstr ""
@@ -29915,6 +30553,12 @@ msgstr ""
msgid "Regex pattern"
msgstr ""
+msgid "Region"
+msgstr ""
+
+msgid "Regions"
+msgstr ""
+
msgid "Register"
msgstr ""
@@ -30147,9 +30791,6 @@ msgstr ""
msgid "Remove all or specific reviewer(s)"
msgstr ""
-msgid "Remove approver"
-msgstr ""
-
msgid "Remove approvers"
msgstr ""
@@ -30165,6 +30806,9 @@ msgstr ""
msgid "Remove attention request"
msgstr ""
+msgid "Remove attention request(s)"
+msgstr ""
+
msgid "Remove avatar"
msgstr ""
@@ -30303,6 +30947,9 @@ msgstr ""
msgid "Removed an issue from an epic."
msgstr ""
+msgid "Removed attention from %{users_sentence}."
+msgstr ""
+
msgid "Removed attention request from @%{username}"
msgstr ""
@@ -30354,6 +31001,9 @@ msgstr ""
msgid "Removes an issue from an epic."
msgstr ""
+msgid "Removes attention from %{users_sentence}."
+msgstr ""
+
msgid "Removes parent epic %{epic_ref}."
msgstr ""
@@ -30465,6 +31115,9 @@ msgstr ""
msgid "Report abuse to admin"
msgstr ""
+msgid "Report is generating and will be sent to your email address."
+msgstr ""
+
msgid "Reported %{timeAgo} by %{reportedBy}"
msgstr ""
@@ -30764,6 +31417,15 @@ msgstr ""
msgid "Request attention"
msgstr ""
+msgid "Request attention from %{users_sentence}."
+msgstr ""
+
+msgid "Request attention from assignee or reviewer"
+msgstr ""
+
+msgid "Request attention from assignee(s) or reviewer(s)"
+msgstr ""
+
msgid "Request attention to review"
msgstr ""
@@ -30788,6 +31450,9 @@ msgstr ""
msgid "Requested %{time_ago}"
msgstr ""
+msgid "Requested attention from %{users_sentence}."
+msgstr ""
+
msgid "Requested attention from @%{username}"
msgstr ""
@@ -31006,6 +31671,9 @@ msgstr ""
msgid "Restore project"
msgstr ""
+msgid "Restoring projects"
+msgstr ""
+
msgid "Restoring the group will prevent the group, its subgroups and projects from being removed on this date."
msgstr ""
@@ -31036,6 +31704,9 @@ msgstr ""
msgid "Retry"
msgstr ""
+msgid "Retry failed jobs"
+msgstr ""
+
msgid "Retry job"
msgstr ""
@@ -31085,9 +31756,6 @@ msgstr ""
msgid "Review changes"
msgstr ""
-msgid "Review requested from %{name}"
-msgstr ""
-
msgid "Review requests for you"
msgstr ""
@@ -31254,6 +31922,9 @@ msgstr ""
msgid "Runners|Assigned Group"
msgstr ""
+msgid "Runners|Assigned Projects (%{projectCount})"
+msgstr ""
+
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -31323,6 +31994,9 @@ msgstr ""
msgid "Runners|Instance"
msgstr ""
+msgid "Runners|Jobs"
+msgstr ""
+
msgid "Runners|Last contact"
msgstr ""
@@ -31416,9 +32090,6 @@ msgstr ""
msgid "Runners|Runner %{name} was deleted"
msgstr ""
-msgid "Runners|Runner ID"
-msgstr ""
-
msgid "Runners|Runner assigned to project."
msgstr ""
@@ -31566,6 +32237,9 @@ msgstr ""
msgid "Runners|stale"
msgstr ""
+msgid "Runner|This runner has not run any jobs."
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -31680,6 +32354,24 @@ msgstr ""
msgid "Saving project."
msgstr ""
+msgid "ScanResultPolicy|%{ifLabelStart}if%{ifLabelEnd} %{scanners} scan in an open merge request targeting the %{branches} branch(es) finds %{vulnerabilitiesAllowed} or more %{severities} vulnerabilities that are %{vulnerabilityStates}"
+msgstr ""
+
+msgid "ScanResultPolicy|%{thenLabelStart}Then%{thenLabelEnd} Require approval from %{approvalsRequired} of the following approvers: %{approvers}"
+msgstr ""
+
+msgid "ScanResultPolicy|add an approver"
+msgstr ""
+
+msgid "ScanResultPolicy|scanners"
+msgstr ""
+
+msgid "ScanResultPolicy|severity levels"
+msgstr ""
+
+msgid "ScanResultPolicy|vulnerability states"
+msgstr ""
+
msgid "Scanner"
msgstr ""
@@ -31812,6 +32504,9 @@ msgstr ""
msgid "Search for a user"
msgstr ""
+msgid "Search for an emoji"
+msgstr ""
+
msgid "Search for projects, issues, etc."
msgstr ""
@@ -32021,18 +32716,12 @@ msgstr ""
msgid "Secret Detection"
msgstr ""
-msgid "Secret access key"
-msgstr ""
-
msgid "Secret token"
msgstr ""
msgid "Secure token that identifies an external storage request."
msgstr ""
-msgid "SecureCodeWarrior"
-msgstr ""
-
msgid "Security"
msgstr ""
@@ -32057,9 +32746,6 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "Security training with guide and learning pathways."
-msgstr ""
-
msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
@@ -32162,7 +32848,7 @@ msgstr ""
msgid "SecurityConfiguration|Manage corpus"
msgstr ""
-msgid "SecurityConfiguration|Manage corpus files used as mutation sources in coverage fuzzing."
+msgid "SecurityConfiguration|Manage corpus files used as seed inputs with coverage-guided fuzzing."
msgstr ""
msgid "SecurityConfiguration|Manage profiles for use by DAST scans."
@@ -32228,15 +32914,15 @@ msgstr ""
msgid "SecurityOrchestration|.yaml preview"
msgstr ""
-msgid "SecurityOrchestration|Action"
-msgstr ""
-
msgid "SecurityOrchestration|Actions"
msgstr ""
msgid "SecurityOrchestration|Add rule"
msgstr ""
+msgid "SecurityOrchestration|After dismissing the alert, the information will never be shown again."
+msgstr ""
+
msgid "SecurityOrchestration|All policies"
msgstr ""
@@ -32252,7 +32938,7 @@ msgstr ""
msgid "SecurityOrchestration|Description"
msgstr ""
-msgid "SecurityOrchestration|Disabled"
+msgid "SecurityOrchestration|Don't show the alert anymore"
msgstr ""
msgid "SecurityOrchestration|Edit policy"
@@ -32261,13 +32947,13 @@ msgstr ""
msgid "SecurityOrchestration|Edit policy project"
msgstr ""
-msgid "SecurityOrchestration|Enabled"
+msgid "SecurityOrchestration|Empty policy name"
msgstr ""
-msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Enabled"
msgstr ""
-msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
msgstr ""
msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
@@ -32276,7 +32962,7 @@ msgstr ""
msgid "SecurityOrchestration|Invalid policy type"
msgstr ""
-msgid "SecurityOrchestration|Latest scan"
+msgid "SecurityOrchestration|Latest scan run against %{agent}"
msgstr ""
msgid "SecurityOrchestration|Network"
@@ -32285,15 +32971,27 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No actions defined - policy will not run."
+msgstr ""
+
+msgid "SecurityOrchestration|No description"
+msgstr ""
+
msgid "SecurityOrchestration|No rules defined - policy will not run."
msgstr ""
+msgid "SecurityOrchestration|Not enabled"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
msgid "SecurityOrchestration|Policies"
msgstr ""
+msgid "SecurityOrchestration|Policy Type"
+msgstr ""
+
msgid "SecurityOrchestration|Policy cannot be enabled for non-existing branches (%{branches})"
msgstr ""
@@ -32318,10 +33016,13 @@ msgstr ""
msgid "SecurityOrchestration|Require %{approvals} %{plural} from %{approvers} if any of the following occur:"
msgstr ""
-msgid "SecurityOrchestration|Rule"
+msgid "SecurityOrchestration|Rules"
msgstr ""
-msgid "SecurityOrchestration|Rules"
+msgid "SecurityOrchestration|Runs %{actions} and %{lastAction} scans"
+msgstr ""
+
+msgid "SecurityOrchestration|Runs a %{action} scan"
msgstr ""
msgid "SecurityOrchestration|Scan Execution"
@@ -32381,6 +33082,9 @@ msgstr ""
msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
+msgid "SecurityOrchestration|This view only shows scan results for the agent %{agent}. You can view scan results for all agents in the %{linkStart}Operational Vulnerabilities tab of the vulnerability report%{linkEnd}."
+msgstr ""
+
msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
@@ -32435,9 +33139,6 @@ msgstr ""
msgid "SecurityOrchestration|users with ids"
msgstr ""
-msgid "SecurityOrchestration|view results"
-msgstr ""
-
msgid "SecurityOrchestration|vulnerabilities"
msgstr ""
@@ -33107,22 +33808,19 @@ 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|In order to start using functions as a service, you must first install Knative on your Kubernetes cluster. %{linkStart}More information%{linkEnd}"
-msgstr ""
-
msgid "Serverless|Learn more about Serverless"
msgstr ""
msgid "Serverless|No functions available"
msgstr ""
-msgid "Serverless|Sign up for First Look"
+msgid "Serverless|Serverless was %{linkStart}deprecated%{linkEnd} in GitLab 14.3."
+msgstr ""
+
+msgid "Serverless|Serverless was %{postLinkStart}deprecated%{postLinkEnd}. But if you opt to use it, you must install Knative in your Kubernetes cluster first. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "Serverless|The deploy job has not finished."
@@ -33134,9 +33832,6 @@ 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 ""
@@ -33152,9 +33847,6 @@ msgstr ""
msgid "Service Account Key"
msgstr ""
-msgid "Service Accounts"
-msgstr ""
-
msgid "Service Accounts keys authorize GitLab to deploy your Google Cloud project"
msgstr ""
@@ -33164,10 +33856,10 @@ msgstr ""
msgid "Service Desk allows people to create issues in your GitLab instance without their own user account. It provides a unique email address for end users to create issues in a project. Replies can be sent either through the GitLab interface or by email. End users only see threads through email."
msgstr ""
-msgid "Service Usage Data"
+msgid "Service account generated successfully"
msgstr ""
-msgid "Service account generated successfully"
+msgid "Service accounts"
msgstr ""
msgid "Service ping is disabled in your configuration file, and cannot be enabled through this form."
@@ -33311,6 +34003,9 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
+msgid "Set the per-user rate limit for getting a user by ID via the API."
+msgstr ""
+
msgid "Set the per-user rate limit for notes created by web or API requests."
msgstr ""
@@ -33492,6 +34187,9 @@ msgstr ""
msgid "Shared runners details"
msgstr ""
+msgid "Shared runners enabled cannot be enabled until a valid credit card is on file"
+msgstr ""
+
msgid "Shared runners help link"
msgstr ""
@@ -33549,6 +34247,9 @@ msgstr ""
msgid "Show all issues."
msgstr ""
+msgid "Show all milestones"
+msgstr ""
+
msgid "Show all test cases."
msgstr ""
@@ -33585,6 +34286,9 @@ msgstr ""
msgid "Show file contents"
msgstr ""
+msgid "Show group milestones"
+msgstr ""
+
msgid "Show labels"
msgstr ""
@@ -33600,6 +34304,12 @@ msgstr ""
msgid "Show open epics"
msgstr ""
+msgid "Show project milestones"
+msgstr ""
+
+msgid "Show sub-group milestones"
+msgstr ""
+
msgid "Show the Closed list"
msgstr ""
@@ -33609,13 +34319,6 @@ msgstr ""
msgid "Show whitespace changes"
msgstr ""
-msgid "Showing %d event"
-msgid_plural "Showing %d events"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-msgstr[3] ""
-
msgid "Showing %{conflict} between %{sourceBranch} and %{targetBranch}"
msgstr ""
@@ -33677,12 +34380,6 @@ msgstr ""
msgid "Sidebar|None"
msgstr ""
-msgid "Sidebar|Only numeral characters allowed"
-msgstr ""
-
-msgid "Sidebar|Weight"
-msgstr ""
-
msgid "Sidekiq job compression threshold (bytes)"
msgstr ""
@@ -33845,6 +34542,9 @@ msgstr ""
msgid "Slack logo"
msgstr ""
+msgid "SlackIntegration|Are you sure you want to remove this project from the Slack application?"
+msgstr ""
+
msgid "SlackIntegration|GitLab for Slack"
msgstr ""
@@ -33854,6 +34554,9 @@ msgstr ""
msgid "SlackIntegration|Project alias"
msgstr ""
+msgid "SlackIntegration|Remove project"
+msgstr ""
+
msgid "SlackIntegration|Select a GitLab project to link with your Slack workspace."
msgstr ""
@@ -33998,9 +34701,6 @@ msgstr ""
msgid "Something went wrong trying to load issue contacts."
msgstr ""
-msgid "Something went wrong when creating a work item. Please try again"
-msgstr ""
-
msgid "Something went wrong when reordering designs. Please try again"
msgstr ""
@@ -34094,9 +34794,6 @@ msgstr ""
msgid "Something went wrong while inserting your image. Please try again."
msgstr ""
-msgid "Something went wrong while merging this merge request. Please try again."
-msgstr ""
-
msgid "Something went wrong while obtaining the Let's Encrypt certificate."
msgstr ""
@@ -34418,10 +35115,10 @@ 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."
+msgid "SourcegraphAdmin|Learn more."
msgstr ""
-msgid "SourcegraphAdmin|More information"
+msgid "SourcegraphAdmin|Only public projects have code intelligence enabled and communicate with Sourcegraph."
msgstr ""
msgid "SourcegraphAdmin|Save changes"
@@ -34430,7 +35127,7 @@ msgstr ""
msgid "SourcegraphAdmin|Sourcegraph URL"
msgstr ""
-msgid "SourcegraphAdmin|e.g. https://sourcegraph.example.com"
+msgid "SourcegraphAdmin|https://sourcegraph.example.com"
msgstr ""
msgid "SourcegraphPreferences|This feature is experimental and currently limited to certain projects."
@@ -34565,6 +35262,9 @@ msgstr ""
msgid "Start date"
msgstr ""
+msgid "Start free trial"
+msgstr ""
+
msgid "Start merge train"
msgstr ""
@@ -34595,6 +35295,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started escalation for this incident."
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -34607,6 +35310,9 @@ msgstr ""
msgid "Starts at (UTC)"
msgstr "Rozpoczyna siÄ™ o (UTC)"
+msgid "Starts escalations for this incident"
+msgstr ""
+
msgid "Starts on"
msgstr ""
@@ -34868,6 +35574,9 @@ msgstr ""
msgid "Strikethrough"
msgstr ""
+msgid "Strikethrough text"
+msgstr ""
+
msgid "Subgroup information"
msgstr ""
@@ -35102,6 +35811,21 @@ msgstr ""
msgid "Subscriptions"
msgstr ""
+msgid "Subscriptions|Chat with sales"
+msgstr ""
+
+msgid "Subscriptions|Close"
+msgstr ""
+
+msgid "Subscriptions|Not ready to buy yet?"
+msgstr ""
+
+msgid "Subscriptions|Start a free trial"
+msgstr ""
+
+msgid "Subscriptions|We understand. Maybe you have some questions for our sales team, or maybe you'd like to try some of the paid features first. What would you like to do?"
+msgstr ""
+
msgid "Subscription|Your subscription for %{strong}%{namespace_name}%{strong_close} has expired and you are now on %{pricing_link_start}the GitLab Free tier%{pricing_link_end}. Don't worry, your data is safe. Get in touch with our support team (%{support_email}). They'll gladly help with your subscription renewal."
msgstr ""
@@ -35312,6 +36036,9 @@ msgstr ""
msgid "SuperSonics|Maximum users"
msgstr ""
+msgid "SuperSonics|Offline cloud"
+msgstr ""
+
msgid "SuperSonics|Paste your activation code"
msgstr ""
@@ -35378,6 +36105,12 @@ msgstr ""
msgid "SuperSonics|You do not have an active subscription"
msgstr ""
+msgid "SuperSonics|You have a future dated license"
+msgstr ""
+
+msgid "SuperSonics|You have added a license that activates on %{date}. Please see the subscription history table below for more details."
+msgstr ""
+
msgid "SuperSonics|You have successfully added a license that activates on %{date}. Please see the subscription history table below for more details."
msgstr ""
@@ -35537,6 +36270,9 @@ msgstr ""
msgid "Tag name is required"
msgstr ""
+msgid "Tag push"
+msgstr ""
+
msgid "Tag push events"
msgstr ""
@@ -35639,6 +36375,9 @@ msgstr "Napisz swoje uwagi do wydania lub przeciągnij pliki tutaj…"
msgid "TagsPage|protected"
msgstr ""
+msgid "Take a look at the documentation to discover all of GitLab’s capabilities."
+msgstr ""
+
msgid "Target Branch"
msgstr ""
@@ -36053,6 +36792,9 @@ msgstr ""
msgid "Tests"
msgstr ""
+msgid "Text (optional)"
+msgstr ""
+
msgid "Text added to the body of all email messages. %{character_limit} character limit"
msgstr ""
@@ -36105,6 +36847,9 @@ msgstr ""
msgid "The CSV export will be created in the background. Once finished, it will be sent to %{email} in an attachment."
msgstr ""
+msgid "The CSV export you requested of all user memberships is attached to this email."
+msgstr ""
+
msgid "The GitLab subscription service (customers.gitlab.com) is currently experiencing an outage. You can monitor the status and get updates at %{linkStart}status.gitlab.com%{linkEnd}."
msgstr ""
@@ -36180,6 +36925,9 @@ 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 epic"
+msgstr ""
+
msgid "The current issue"
msgstr ""
@@ -36343,6 +37091,9 @@ msgstr ""
msgid "The latest pipeline for this merge request has failed."
msgstr ""
+msgid "The license key is invalid."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -36358,6 +37109,9 @@ msgstr ""
msgid "The license was successfully uploaded and will be active from %{starts_at}. You can see the details below."
msgstr ""
+msgid "The license you uploaded is invalid. If the issue persists, contact support at %{link}."
+msgstr ""
+
msgid "The list creation wizard is already open"
msgstr ""
@@ -36979,10 +37733,13 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} and everything this project contains. %{strongOpen}There is no going back%{strongClose}"
+msgstr ""
+
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains."
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}on %{date}%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains. %{strongOpen}There is no going back.%{strongClose}"
msgstr ""
msgid "This action will %{strongOpen}permanently remove%{strongClose} %{codeOpen}%{group}%{codeClose} %{strongOpen}immediately%{strongClose}."
@@ -37111,9 +37868,6 @@ msgstr ""
msgid "This file was modified for readability, and can't accept suggestions. Edit it directly."
msgstr ""
-msgid "This forked project has the following:"
-msgstr ""
-
msgid "This form is disabled in preview"
msgstr ""
@@ -37126,7 +37880,7 @@ msgstr ""
msgid "This group can't be removed because it is linked to a subscription. To remove this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
-msgid "This group can't be transfered because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
+msgid "This group can't be transferred because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
msgid "This group cannot be invited to a project inside a group with enforced SSO"
@@ -37153,6 +37907,9 @@ 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 incident is already escalated with '%{escalation_policy_name}'."
+msgstr ""
+
msgid "This invitation was sent to %{mail_to_invite_email}, but you are signed in as %{link_to_current_user} with email %{mail_to_current_user}."
msgstr ""
@@ -37171,9 +37928,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 merge train pipeline"
-msgstr ""
-
msgid "This is a private email address %{helpIcon} generated just for you. Anyone who has it can create issues or merge requests as if they were you. If that happens, %{resetLinkStart}reset this token%{resetLinkEnd}."
msgstr ""
@@ -37195,6 +37949,12 @@ msgstr ""
msgid "This is your current session"
msgstr ""
+msgid "This issue cannot be assigned to a confidential epic because it is public."
+msgstr ""
+
+msgid "This issue cannot be made public because it belongs to a confidential epic."
+msgstr ""
+
msgid "This issue is confidential and should only be visible to team members with at least Reporter access."
msgstr ""
@@ -37312,6 +38072,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 branch is protected from force push."
+msgstr ""
+
msgid "This merge request cannot be rebased while there are conflicts."
msgstr ""
@@ -37363,9 +38126,15 @@ msgstr ""
msgid "This pipeline was triggered by a schedule."
msgstr ""
+msgid "This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project"
msgstr ""
+msgid "This project can be restored until %{date}."
+msgstr ""
+
msgid "This project cannot be %{visibilityLevel} because the visibility of %{openShowLink}%{name}%{closeShowLink} is %{visibility}. To make this project %{visibilityLevel}, you must first %{openEditLink}change the visibility%{closeEditLink} of the parent group."
msgstr ""
@@ -37384,6 +38153,9 @@ msgstr ""
msgid "This project is %{strongStart}NOT%{strongEnd} a fork, and has the following:"
msgstr ""
+msgid "This project is %{strongStart}NOT%{strongEnd} a fork. This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -38079,6 +38851,9 @@ msgstr ""
msgid "Today"
msgstr ""
+msgid "Todos count"
+msgstr ""
+
msgid "Todos|Are you looking for things to do? Take a look at %{strongStart}%{openIssuesLinkStart}open issues%{openIssuesLinkEnd}%{strongEnd}, contribute to %{strongStart}%{mergeRequestLinkStart}a merge request%{mergeRequestLinkEnd}%{mergeRequestLinkEnd}%{strongEnd}, or mention someone in a comment to automatically assign them a new to-do item."
msgstr ""
@@ -38352,12 +39127,8 @@ msgstr ""
msgid "Trending"
msgstr ""
-msgid "Trials|%{planName} Trial %{enDash} %{num} day left"
-msgid_plural "Trials|%{planName} Trial %{enDash} %{num} days left"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-msgstr[3] ""
+msgid "Trials|%{planName} Trial"
+msgstr ""
msgid "Trials|Compare all plans"
msgstr ""
@@ -38365,6 +39136,9 @@ msgstr ""
msgid "Trials|Create a new group to start your GitLab Ultimate trial."
msgstr ""
+msgid "Trials|Day %{daysUsed}/%{duration}"
+msgstr ""
+
msgid "Trials|Go back to GitLab"
msgstr ""
@@ -38614,7 +39388,7 @@ msgstr ""
msgid "URL is triggered when repository is updated"
msgstr ""
-msgid "URL must be percent-encoded if neccessary."
+msgid "URL must be percent-encoded if necessary."
msgstr ""
msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
@@ -38833,6 +39607,9 @@ msgstr ""
msgid "Unlock account"
msgstr ""
+msgid "Unlock more features with GitLab Ultimate"
+msgstr ""
+
msgid "Unlock the discussion"
msgstr ""
@@ -38896,6 +39673,9 @@ msgstr ""
msgid "Unsubscribes from this %{quick_action_target}."
msgstr ""
+msgid "Unsupported sort value."
+msgstr ""
+
msgid "Unsupported todo type passed. Supported todo types are: %{todo_types}"
msgstr ""
@@ -39124,6 +39904,9 @@ msgstr ""
msgid "UsageQuota|File attachments and smaller design graphics."
msgstr ""
+msgid "UsageQuota|From %{storage_enforcement_date} storage limits will apply to this namespace. View and manage your usage in %{strong_start}Group Settings &gt; Usage quotas%{strong_end}."
+msgstr ""
+
msgid "UsageQuota|Git repository."
msgstr ""
@@ -39184,6 +39967,9 @@ msgstr ""
msgid "UsageQuota|Storage type"
msgstr ""
+msgid "UsageQuota|Storage used"
+msgstr ""
+
msgid "UsageQuota|This is the total amount of storage used across your projects within this namespace."
msgstr ""
@@ -39379,6 +40165,12 @@ msgstr ""
msgid "Use hashed storage paths for newly created and renamed repositories. Always enabled since 13.0."
msgstr ""
+msgid "Use issue count"
+msgstr ""
+
+msgid "Use issue weight"
+msgstr ""
+
msgid "Use one line per URI"
msgstr ""
@@ -39760,6 +40552,9 @@ msgstr ""
msgid "Users"
msgstr ""
+msgid "Users API rate limit"
+msgstr ""
+
msgid "Users can launch a development environment from a GitLab browser tab when the %{linkStart}Gitpod%{linkEnd} integration is enabled."
msgstr ""
@@ -40089,6 +40884,9 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View group pipeline usage quota"
+msgstr ""
+
msgid "View incident details at"
msgstr ""
@@ -40243,6 +41041,9 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
+msgid "Vulnerability"
+msgstr ""
+
msgid "Vulnerability Report"
msgstr ""
@@ -40294,6 +41095,9 @@ msgstr ""
msgid "VulnerabilityManagement|An unverified non-confirmed finding"
msgstr ""
+msgid "VulnerabilityManagement|At least one identifier is required"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -40303,12 +41107,24 @@ msgstr ""
msgid "VulnerabilityManagement|Create Jira issue"
msgstr ""
+msgid "VulnerabilityManagement|Enter a name"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE code"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE identifier URL"
+msgstr ""
+
msgid "VulnerabilityManagement|Fetching linked Jira issues"
msgstr ""
msgid "VulnerabilityManagement|Manually add a vulnerability entry into the vulnerability report."
msgstr ""
+msgid "VulnerabilityManagement|Name is a required field"
+msgstr ""
+
msgid "VulnerabilityManagement|Needs triage"
msgstr ""
@@ -40324,6 +41140,18 @@ msgstr ""
msgid "VulnerabilityManagement|Select a method"
msgstr ""
+msgid "VulnerabilityManagement|Select a severity level"
+msgstr ""
+
+msgid "VulnerabilityManagement|Select a status"
+msgstr ""
+
+msgid "VulnerabilityManagement|Severity is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Something went wrong while creating vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -40348,6 +41176,12 @@ msgstr ""
msgid "VulnerabilityManagement|Something went wrong, could not update vulnerability state."
msgstr ""
+msgid "VulnerabilityManagement|Status is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Submit vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Summary, detailed description, steps to reproduce, etc."
msgstr ""
@@ -40543,6 +41377,9 @@ msgstr ""
msgid "WARNING:"
msgstr ""
+msgid "WARNING: This snippet contains hidden files which might be used to mask malicious behavior. Exercise caution if cloning and executing code from this snippet."
+msgstr ""
+
msgid "Wait for the file to load to copy its contents"
msgstr ""
@@ -40762,6 +41599,15 @@ msgstr ""
msgid "Webhooks|An issue is created, updated, closed, or reopened."
msgstr ""
+msgid "Webhooks|Are you sure you want to delete this group hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this project hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this webhook?"
+msgstr ""
+
msgid "Webhooks|Comments"
msgstr ""
@@ -40771,6 +41617,9 @@ msgstr ""
msgid "Webhooks|Confidential issues events"
msgstr ""
+msgid "Webhooks|Delete webhook"
+msgstr ""
+
msgid "Webhooks|Deployment events"
msgstr ""
@@ -41006,6 +41855,9 @@ msgstr ""
msgid "Wiki"
msgstr ""
+msgid "Wiki page"
+msgstr ""
+
msgid "Wiki page was successfully created."
msgstr ""
@@ -41111,7 +41963,7 @@ msgstr ""
msgid "WikiPageConflictMessage|Someone edited the page the same time you did. Please check out %{wikiLinkStart}the page%{wikiLinkEnd} and make sure your changes will not unintentionally remove theirs."
msgstr ""
-msgid "WikiPage|An error occured while trying to render the content editor. Please try again later."
+msgid "WikiPage|An error occurred while trying to render the content editor. Please try again later."
msgstr ""
msgid "WikiPage|Are you sure you want to switch back to the classic editor?"
@@ -41270,6 +42122,18 @@ msgstr ""
msgid "WorkItem|New Task"
msgstr ""
+msgid "WorkItem|Something went wrong when creating a work item. Please try again"
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching the work item. Please try again."
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching work item types. Please try again"
+msgstr ""
+
+msgid "WorkItem|Type"
+msgstr ""
+
msgid "WorkItem|Work Items"
msgstr ""
@@ -41336,7 +42200,10 @@ msgstr ""
msgid "You are about to add %{usersTag} people to the discussion. They will all receive a notification."
msgstr ""
-msgid "You are about to permanently delete this project"
+msgid "You are about to delete this forked project containing:"
+msgstr ""
+
+msgid "You are about to delete this project containing:"
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."
@@ -41357,6 +42224,9 @@ msgstr ""
msgid "You are attempting to update a file that has changed since you started editing it."
msgstr ""
+msgid "You are billed if you exceed this number. %{qsrOverageLinkStart}How does billing work?%{qsrOverageLinkEnd}"
+msgstr ""
+
msgid "You are connected to the Prometheus server, but there is currently no data to display."
msgstr ""
@@ -41414,6 +42284,9 @@ msgstr ""
msgid "You are not authorized to update this scanner profile"
msgstr ""
+msgid "You are not authorized to upload metric images"
+msgstr ""
+
msgid "You are now impersonating %{username}"
msgstr ""
@@ -41567,9 +42440,6 @@ msgstr ""
msgid "You can only upload one design when dropping onto an existing design."
msgstr ""
-msgid "You can recover this project until %{date}"
-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 ""
@@ -41618,9 +42488,6 @@ msgstr ""
msgid "You cannot write to this read-only GitLab instance."
msgstr ""
-msgid "You can’t %{tag_start}edit%{tag_end} files directly in this project. Fork this project and submit a merge request with your changes."
-msgstr ""
-
msgid "You can’t edit files directly in this project. Fork this project and submit a merge request with your changes."
msgstr ""
@@ -41775,9 +42642,6 @@ 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 set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
@@ -41808,12 +42672,6 @@ msgstr ""
msgid "You must have maintainer access to force delete a lock"
msgstr ""
-msgid "You must have permission to create a project in a group before forking."
-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 ""
@@ -42219,7 +43077,7 @@ msgstr ""
msgid "Your public email will be displayed on your public profile."
msgstr ""
-msgid "Your request for access could not be processed: %{error_meesage}"
+msgid "Your request for access could not be processed: %{error_message}"
msgstr ""
msgid "Your request for access has been queued for review."
@@ -42408,6 +43266,9 @@ msgstr ""
msgid "archived:"
msgstr ""
+msgid "artifacts"
+msgstr ""
+
msgid "assign yourself"
msgstr ""
@@ -42439,6 +43300,9 @@ msgstr[3] ""
msgid "branch name"
msgstr ""
+msgid "builds"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -42868,6 +43732,9 @@ msgstr ""
msgid "contact with same email already exists in group hierarchy"
msgstr ""
+msgid "container registry images"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -42907,6 +43774,9 @@ msgstr ""
msgid "data"
msgstr ""
+msgid "database"
+msgstr ""
+
msgid "date must not be after 9999-12-31"
msgstr ""
@@ -42932,9 +43802,6 @@ msgstr ""
msgid "design"
msgstr ""
-msgid "detached"
-msgstr ""
-
msgid "disabled"
msgstr ""
@@ -43191,7 +44058,7 @@ msgstr ""
msgid "is not a valid X509 certificate."
msgstr ""
-msgid "is not allowed for sign-up."
+msgid "is not allowed for sign-up. Please use your regular email address."
msgstr ""
msgid "is not allowed for this group."
@@ -43203,7 +44070,7 @@ msgstr ""
msgid "is not allowed since the group is not top-level group."
msgstr ""
-msgid "is not allowed."
+msgid "is not allowed. Please use your regular email address."
msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
@@ -43290,6 +44157,9 @@ msgstr ""
msgid "level: %{level}"
msgstr ""
+msgid "lfs objects"
+msgstr ""
+
msgid "limit of %{project_limit} reached"
msgstr ""
@@ -43515,6 +44385,9 @@ msgstr ""
msgid "mrWidget|Merge blocked: pipeline must succeed. It's waiting for a manual action to continue."
msgstr ""
+msgid "mrWidget|Merge blocked: pipeline must succeed. Push a commit that fixes the failure, or %{linkStart}learn about other solutions.%{linkEnd}"
+msgstr ""
+
msgid "mrWidget|Merge blocked: this merge request must be approved."
msgstr ""
@@ -43632,9 +44505,6 @@ msgstr ""
msgid "mrWidget|The changes were not merged into"
msgstr ""
-msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -43782,9 +44652,6 @@ msgstr ""
msgid "open issue"
msgstr ""
-msgid "opened %{timeAgo}"
-msgstr ""
-
msgid "or"
msgstr ""
@@ -43798,6 +44665,12 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "packages"
+msgstr ""
+
+msgid "pages"
+msgstr ""
+
msgid "parent"
msgid_plural "parents"
msgstr[0] ""
@@ -43955,6 +44828,9 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "repositories"
+msgstr ""
+
msgid "repository:"
msgstr ""
@@ -44075,12 +44951,18 @@ msgstr ""
msgid "tag name"
msgstr ""
+msgid "terraform states"
+msgstr ""
+
msgid "the correct format."
msgstr ""
msgid "the file"
msgstr ""
+msgid "the following epic(s)"
+msgstr ""
+
msgid "the following issue(s)"
msgstr ""
@@ -44093,21 +44975,12 @@ msgstr ""
msgid "this document"
msgstr ""
-msgid "this issue cannot be assigned to a confidential epic since it is public"
-msgstr ""
-
-msgid "this issue cannot be made public since it belongs to a confidential epic"
-msgstr ""
-
msgid "time summary"
msgstr ""
msgid "toggle collapse"
msgstr ""
-msgid "train"
-msgstr ""
-
msgid "triggered"
msgstr ""
@@ -44238,3 +45111,6 @@ msgstr ""
msgid "{project}"
msgstr ""
+msgid "✔"
+msgstr ""
+
diff --git a/locale/pt_BR/gitlab.po b/locale/pt_BR/gitlab.po
index 652e52cacb9..6afec29258f 100644
--- a/locale/pt_BR/gitlab.po
+++ b/locale/pt_BR/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: pt-BR\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2022-02-02 15:43\n"
+"PO-Revision-Date: 2022-03-01 20:37\n"
msgid " %{start} to %{end}"
msgstr " %{start} até %{end}"
@@ -118,8 +118,8 @@ msgstr[1] "%d URLs verificadas"
msgid "%d additional approver"
msgid_plural "%d additional approvers"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d aprovador adicional"
+msgstr[1] "%d aprovadores adicionais"
msgid "%d additional assignee"
msgid_plural "%d additional assignees"
@@ -128,8 +128,8 @@ msgstr[1] ""
msgid "%d additional commenter"
msgid_plural "%d additional commenters"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d comentarista adicional"
+msgstr[1] "%d comentaristas adicionais"
msgid "%d additional committer"
msgid_plural "%d additional committers"
@@ -146,6 +146,11 @@ msgid_plural "%d approvers (you've approved)"
msgstr[0] "%d aprovador (você aprovou)"
msgstr[1] "%d aprovadores (você aprovou)"
+msgid "%d assigned issue"
+msgid_plural "%d assigned issues"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] "%d arquivo alterado"
@@ -421,10 +426,25 @@ msgid_plural "%d vulnerabilities dismissed"
msgstr[0] "%d vulnerabilidade dispensada"
msgstr[1] "%d vulnerabilidades dispensadas"
-msgid "%d vulnerability updated"
-msgid_plural "%d vulnerabilities updated"
-msgstr[0] "%d vulnerabilidade atualizada"
-msgstr[1] "%d vulnerabilidades atualizadas"
+msgid "%d vulnerability set to confirmed"
+msgid_plural "%d vulnerabilities set to confirmed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to dismissed"
+msgid_plural "%d vulnerabilities set to dismissed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to needs triage"
+msgid_plural "%d vulnerabilities set to needs triage"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to resolved"
+msgid_plural "%d vulnerabilities set to resolved"
+msgstr[0] ""
+msgstr[1] ""
msgid "%d warning found:"
msgid_plural "%d warnings found:"
@@ -482,10 +502,10 @@ msgstr[0] "%{bold_start}%{count}%{bold_end} solicitação de mesclagem aberta"
msgstr[1] "%{bold_start}%{count}%{bold_end} solicitações de mesclagem abertas"
msgid "%{codeStart}type%{codeEnd} is deprecated and will be removed in 15.0. Use %{codeStart}stage%{codeEnd} instead. %{linkStart}Learn More %{linkEnd}"
-msgstr ""
+msgstr "%{codeStart}type%{codeEnd} está obsoleto e será removido na versão 15.0. Use %{codeStart}stage%{codeEnd} em vez disso. %{linkStart}Saiba mais %{linkEnd}"
msgid "%{codeStart}types%{codeEnd} is deprecated and will be removed in 15.0. Use %{codeStart}stages%{codeEnd} instead. %{linkStart}Learn More %{linkEnd}"
-msgstr ""
+msgstr "%{codeStart}types%{codeEnd} está obsoleto e será removido na versão 15.0. Use %{codeStart}stages%{codeEnd} em vez disso. %{linkStart}Saiba mais %{linkEnd}"
msgid "%{code_open}Masked:%{code_close} Hidden in job logs. Must match masking requirements."
msgstr "%{code_open}Mascarado:%{code_close} Escondidos nos logs de tarefas. Deve corresponder a requisitos de mascaramento."
@@ -510,6 +530,12 @@ msgstr[1] "%{completedCount} de %{count} tarefas concluídas"
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr "%{completedWeight} de %{totalWeight} peso concluído"
+msgid "%{completed} of %{total} issues closed"
+msgstr ""
+
+msgid "%{completed} of %{total} weight completed"
+msgstr ""
+
msgid "%{cores} cores"
msgstr "%{cores} núcleos"
@@ -653,7 +679,7 @@ msgid "%{group_name} group members"
msgstr "Membros do grupo %{group_name}"
msgid "%{group_name} is approaching the limit of available seats"
-msgstr ""
+msgstr "%{group_name} está se aproximando do limite de assentos disponíveis"
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}."
@@ -752,7 +778,7 @@ msgid "%{level_name} is not allowed since the fork source project has lower visi
msgstr "%{level_name} não é permitido, pois o projeto de origem do fork possui menor visibilidade."
msgid "%{linkStart}Learn more.%{linkEnd}"
-msgstr ""
+msgstr "%{linkStart}Saiba mais.%{linkEnd}"
msgid "%{link_start}Learn more%{link_end} about roles."
msgstr "%{link_start}Saiba mais%{link_end} sobre cargos."
@@ -858,6 +884,9 @@ msgstr "%{openedEpics} abertos, %{closedEpics} fechados"
msgid "%{openedIssues} open, %{closedIssues} closed"
msgstr "%{openedIssues} aberta, %{closedIssues} fechada"
+msgid "%{percentage}%% issues closed"
+msgstr ""
+
msgid "%{percentage}%% weight completed"
msgstr "%{percentage}%% peso concluído"
@@ -909,7 +938,7 @@ msgid "%{rotation} has been recalculated with the remaining participants. Please
msgstr ""
msgid "%{runner} created %{timeago}"
-msgstr ""
+msgstr "%{runner} criou %{timeago}"
msgid "%{scope} results for term '%{term}'"
msgstr "%{scope} resultados para o termo '%{term}'"
@@ -1287,6 +1316,9 @@ msgid_plural "- Users"
msgstr[0] "- Usuário"
msgstr[1] "- Usuários"
+msgid "- of - issues closed"
+msgstr ""
+
msgid "- of - weight completed"
msgstr "- de - peso concluído"
@@ -1429,8 +1461,8 @@ msgstr "10-19 contribuições"
msgid "1000+"
msgstr "1000+"
-msgid "192.168.0.0/24"
-msgstr "192.168.0.0/24"
+msgid "192.168.0.0/24 or 2001:0DB8:1234::/48"
+msgstr ""
msgid "1st contribution!"
msgstr "1ª contribuição!"
@@ -1741,14 +1773,14 @@ msgstr "folder/openapi.json"
msgid "AWS Access Key"
msgstr "Chave de acesso AWS"
-msgid "AWS Access Key. Only required if not using role instance credentials"
-msgstr "Chave de acesso AWS. Apenas necessário se não usar credenciais de instância do papel"
-
msgid "AWS Secret Access Key"
msgstr "Chave de acesso secreta da AWS"
-msgid "AWS Secret Access Key. Only required if not using role instance credentials"
-msgstr "Chave de Acesso secreto AWS. Necessária apenas se não estiver usando credenciais de função da instância"
+msgid "AWS access key ID (Optional)"
+msgstr ""
+
+msgid "AWS secret access key (Optional)"
+msgstr ""
msgid "AWS service error: %{error}"
msgstr "Erro de serviço de AWS: %{error}"
@@ -1807,9 +1839,6 @@ msgstr "Acesso proibido. Verifique seu nível de acesso."
msgid "Access granted"
msgstr "Acesso concedido"
-msgid "Access key ID"
-msgstr "Chave ID de acesso"
-
msgid "Access requests"
msgstr "Solicitação de acesso"
@@ -1984,7 +2013,7 @@ msgstr "Nomes ativos no bate-papo (%{count})"
msgid "Activity"
msgstr "Atividade"
-msgid "Activity|An error occured while retrieving activity. Reload the page to try again."
+msgid "Activity|An error occurred while retrieving activity. Reload the page to try again."
msgstr ""
msgid "Add"
@@ -2012,7 +2041,7 @@ msgid "Add LICENSE"
msgstr "Adicionar LICENSE"
msgid "Add New Site"
-msgstr ""
+msgstr "Adicionar um novo site"
msgid "Add README"
msgstr "Adicionar README"
@@ -2023,11 +2052,14 @@ msgstr "Adicionar uma reunião do Zoom"
msgid "Add a %{type}"
msgstr "Adicionar um %{type}"
+msgid "Add a GCP region"
+msgstr ""
+
msgid "Add a GPG key"
msgstr "Adicionar chave GPG"
msgid "Add a GPG key for secure access to GitLab. %{help_link_start}Learn more.%{help_link_end}"
-msgstr ""
+msgstr "Adicionar uma chave GPG para acesso seguro ao GitLab. %{help_link_start}Saiba mais.%{help_link_end}"
msgid "Add a Jaeger URL to replace this page with a link to your Jaeger server. You first need to %{link_start_tag}install Jaeger%{link_end_tag}."
msgstr "Adicione uma URL Jaeger para substituir esta página com um link para seu servidor Jaeger. Você precisa primeiro %{link_start_tag}instalar Jaeger%{link_end_tag}"
@@ -2074,6 +2106,9 @@ msgstr "Adicionar uma nova issue"
msgid "Add a numbered list"
msgstr "Adicionar uma lista numerada"
+msgid "Add a related epic"
+msgstr ""
+
msgid "Add a related issue"
msgstr "Adicionar um issue relacionada"
@@ -2096,7 +2131,7 @@ msgid "Add an SSH key"
msgstr "Adicionar chave SSH"
msgid "Add an SSH key for secure access to GitLab. %{help_link_start}Learn more.%{help_link_end}"
-msgstr ""
+msgstr "Adicionar uma chave SSH para acesso seguro ao GitLab. %{help_link_start}Saiba mais.%{help_link_end}"
msgid "Add an existing issue"
msgstr "Adicionar uma issue existente"
@@ -2188,6 +2223,9 @@ msgstr ""
msgid "Add or subtract spent time"
msgstr "Adicionar ou subtrair tempo gasto"
+msgid "Add people"
+msgstr ""
+
msgid "Add previously merged commits"
msgstr ""
@@ -2254,6 +2292,9 @@ msgstr ""
msgid "Add webhook"
msgstr "Adicionar webhook"
+msgid "Add your team members and others to GitLab."
+msgstr ""
+
msgid "Add/remove"
msgstr "Adicionar/remover"
@@ -2675,7 +2716,7 @@ msgid "AdminUsers|(Internal)"
msgstr "(Interno)"
msgid "AdminUsers|(Locked)"
-msgstr ""
+msgstr "(Bloqueado)"
msgid "AdminUsers|(Pending approval)"
msgstr "(Aprovação pendente)"
@@ -2714,7 +2755,7 @@ msgid "AdminUsers|Admin"
msgstr "Administrador"
msgid "AdminUsers|Administrator"
-msgstr ""
+msgstr "Administrador"
msgid "AdminUsers|Admins"
msgstr "Administradores"
@@ -3011,7 +3052,7 @@ msgid "AdminUsers|You can unban their account in the future. Their data remains
msgstr "Você pode reverter o banimento dessas contas no futuro. Os dados permanecerão intactos."
msgid "AdminUsers|You cannot remove your own administrator access."
-msgstr ""
+msgstr "Você não pode remover seu próprio acesso de administrador."
msgid "AdminUsers|You must transfer ownership or delete the groups owned by this user before you can delete their account"
msgstr "Você deve transferir a propriedade ou excluir os grupos pertencentes a este usuário antes de excluir sua conta"
@@ -3076,12 +3117,6 @@ msgstr "Opções de exportação avançadas"
msgid "AdvancedSearch|Reindex required"
msgstr ""
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. Permanently deleting this project will %{strongStart}immediately delete%{strongEnd} its repositories and %{strongStart}all related resources%{strongEnd}, including issues, merge requests etc."
-msgstr "Depois que um projeto é excluído permanentemente, ele %{strongStart}não pode ser recuperado%{strongEnd}. A exclusão permanente deste projeto %{strongStart}excluirá imediatamente%{strongEnd} seus repositórios e %{strongStart}todos os recursos relacionados%{strongEnd}, incluindo problemas, solicitações de mesclagem etc."
-
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. You will lose this project's repository and %{strongStart}all related resources%{strongEnd}, including issues and merge requests."
-msgstr "Depois que um projeto é excluído permanentemente, ele %{strongStart}não pode ser recuperado%{strongEnd}. Você perderá o repositório deste projeto e %{strongStart}todos os recursos relacionados%{strongEnd}, incluindo problemas e solicitações de mesclagem."
-
msgid "After a successful password update you will be redirected to login screen."
msgstr "Após uma atualização de senha bem-sucedida, você será redirecionado para a tela de entrada."
@@ -3112,6 +3147,9 @@ msgstr "Clave de API de Akismet"
msgid "Akismet helps prevent the creation of spam issues in public projects."
msgstr ""
+msgid "Alert"
+msgstr ""
+
msgid "AlertManagement|Acknowledged"
msgstr "Reconhecido"
@@ -3484,9 +3522,6 @@ msgstr "Todos os endereços de e-mail serão usados para identificar seus commit
msgid "All environments"
msgstr "Todos os ambientes"
-msgid "All epics"
-msgstr "Todos os épicos"
-
msgid "All groups and projects"
msgstr "Todos os grupos e projetos"
@@ -4223,12 +4258,15 @@ msgstr "Aprovar usuários"
msgid "ApplicationSettings|Approve users in the pending approval status?"
msgstr ""
-msgid "ApplicationSettings|By making this change, you will automatically approve %d user with the pending approval status."
-msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users with the pending approval status."
+msgid "ApplicationSettings|Approve users who are pending approval?"
+msgstr ""
+
+msgid "ApplicationSettings|By making this change, you will automatically approve %d user who is pending approval."
+msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users who are pending approval."
msgstr[0] ""
msgstr[1] ""
-msgid "ApplicationSettings|By making this change, you will automatically approve all users in pending approval status."
+msgid "ApplicationSettings|By making this change, you will automatically approve all users who are pending approval."
msgstr ""
msgid "ApplicationSettings|Denied domains for sign-ups"
@@ -4440,7 +4478,7 @@ msgid "ApprovalRule|Improve your organization's code review with required approv
msgstr ""
msgid "ApprovalRule|Increase quality and maintain standards."
-msgstr ""
+msgstr "Melhore a qualidade e mantenha padrões."
msgid "ApprovalRule|Learn more about merge request approval rules."
msgstr ""
@@ -4503,7 +4541,7 @@ msgid "ApprovalRule|Target branch"
msgstr "Ramificação de destino"
msgid "ApprovalRule|Try for free"
-msgstr ""
+msgstr "Experimente gratuitamente"
msgid "ApprovalRule|Vulnerabilities allowed"
msgstr "Vulnerabilidades permitidas"
@@ -4515,28 +4553,28 @@ msgid "ApprovalSettings|Merge request approval settings have been updated."
msgstr "As configurações de solicitação de mesclagem foram atualizadas"
msgid "ApprovalSettings|Prevent approval by author"
-msgstr ""
+msgstr "Evitar a aprovação por autor"
msgid "ApprovalSettings|Prevent approval by author."
msgstr "Evitar a aprovação por autor."
msgid "ApprovalSettings|Prevent approvals by users who add commits"
-msgstr ""
+msgstr "Evitar aprovações por usuários que adicionarem commits"
msgid "ApprovalSettings|Prevent approvals by users who add commits."
msgstr "Evitar aprovações por usuários que adicionarem commits."
msgid "ApprovalSettings|Prevent editing approval rules in merge requests"
-msgstr ""
+msgstr "Evitar a edição de regras de aprovação em solicitações de mesclagem"
msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests."
msgstr "Evitar a edição de regras de aprovação em projetos e solicitações de mesclagem."
msgid "ApprovalSettings|Remove all approvals when commits are added to the source branch"
-msgstr ""
+msgstr "Remover todas as aprovações quando commits forem adicionados a ramificação de origem"
msgid "ApprovalSettings|Require user password to approve"
-msgstr ""
+msgstr "Exigir senha do usuário para aprovar"
msgid "ApprovalSettings|There was an error loading merge request approval settings."
msgstr ""
@@ -4634,12 +4672,12 @@ msgstr "Projetos arquivados"
msgid "Archiving the project will make it entirely read-only. It is hidden from the dashboard and doesn't show up in searches. %{strong_start}The repository cannot be committed to, and no issues, comments, or other entities can be created.%{strong_end} %{link_start}Learn more.%{link_end}"
msgstr "Arquivar o projeto fará com que ele seja apenas para leitura. Estará oculto do painel e não aparece nas pesquisas. %{strong_start}O repositório não pode ter novos commits, e nenhuma issues, comentário ou outras entidades que possam ser criadas.%{strong_end} %{link_start}Saiba mais.%{link_end}"
-msgid "Are you ABSOLUTELY SURE you wish to delete this project?"
-msgstr "VOCÊ TEM ABSOLUTA CERTEZA que deseja excluir esse projeto?"
-
msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
msgstr ""
+msgid "Are you absolutely sure?"
+msgstr ""
+
msgid "Are you sure that you want to archive this project?"
msgstr "Tem certeza que deseja arquivar este projeto?"
@@ -4650,7 +4688,7 @@ msgid "Are you sure you want to %{action} %{name}?"
msgstr ""
msgid "Are you sure you want to approve %{user}?"
-msgstr ""
+msgstr "Você tem certeza de que quer aprovar %{user}?"
msgid "Are you sure you want to attempt to merge?"
msgstr "Tem certeza de que deseja tentar mesclar?"
@@ -4673,12 +4711,18 @@ msgstr "Tem certeza de que deseja excluir este %{typeOfComment}?"
msgid "Are you sure you want to delete this SSH key?"
msgstr ""
+msgid "Are you sure you want to delete this comment?"
+msgstr ""
+
msgid "Are you sure you want to delete this deploy key?"
msgstr ""
msgid "Are you sure you want to delete this device? This action cannot be undone."
msgstr "Tem certeza de que deseja excluir este dispositivo? Esta ação não pode ser desfeita."
+msgid "Are you sure you want to delete this label?"
+msgstr ""
+
msgid "Are you sure you want to delete this pipeline schedule?"
msgstr "Tem certeza que deseja excluir este agendamento de pipeline?"
@@ -4694,9 +4738,6 @@ msgstr "Tem certeza de que deseja descartar este comentário?"
msgid "Are you sure you want to discard your changes?"
msgstr "Tem certeza de que deseja descartar suas alterações?"
-msgid "Are you sure you want to erase this build?"
-msgstr "Tem certeza de que deseja limpar este build?"
-
msgid "Are you sure you want to import %d repository?"
msgid_plural "Are you sure you want to import %d repositories?"
msgstr[0] ""
@@ -4744,6 +4785,9 @@ msgstr "Você tem certeza de que deseja excluir este item?"
msgid "Are you sure you want to remove this list?"
msgstr "Tem certeza que deseja remover esta lista?"
+msgid "Are you sure you want to remove this nickname?"
+msgstr ""
+
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?"
@@ -4756,12 +4800,12 @@ msgstr "Tem certeza de que deseja repetir esta migração?"
msgid "Are you sure you want to revoke this %{type}? This action cannot be undone."
msgstr "Tem certeza de que deseja revogar este %{type}? Essa ação não pode ser desfeita."
-msgid "Are you sure you want to revoke this nickname?"
-msgstr "Tem a certeza que deseja revogar este apelido?"
-
msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
msgstr "Tem certeza de que deseja revogar este token de acesso pessoal? Esta ação não pode ser desfeita."
+msgid "Are you sure you want to revoke this project access token? This action cannot be undone."
+msgstr ""
+
msgid "Are you sure you want to stop this environment?"
msgstr "Você tem certeza de que deseja parar este ambiente?"
@@ -4906,9 +4950,6 @@ msgstr "Atribuído a %{assigneeName}"
msgid "Assigned to %{assignee_name}"
msgstr "Atribuído a %{assignee_name}"
-msgid "Assigned to %{name}"
-msgstr "Atribuído a %{name}"
-
msgid "Assigned to me"
msgstr "Atribuído a mim"
@@ -4973,6 +5014,9 @@ msgstr[1] "Anexando %d arquivos"
msgid "Attaching the file failed."
msgstr "Falha ao anexar o arquivo."
+msgid "Attention"
+msgstr ""
+
msgid "Audit Events"
msgstr "Eventos de auditoria"
@@ -5135,6 +5179,12 @@ msgstr "Autorizado em"
msgid "Authorized applications (%{size})"
msgstr "Aplicativos autorizados (%{size})"
+msgid "AuthorizedApplication|Are you sure you want to revoke this application?"
+msgstr ""
+
+msgid "AuthorizedApplication|Revoke application"
+msgstr ""
+
msgid "Authors: %{authors}"
msgstr "Autores: %{authors}"
@@ -5271,7 +5321,7 @@ msgid "Average per day: %{average}"
msgstr "Média diária: %{average}"
msgid "Awaiting user signup"
-msgstr ""
+msgstr "Aguardando cadastro do usuário"
msgid "Award added"
msgstr "Prêmio adicionado"
@@ -5406,7 +5456,7 @@ msgid "Based on"
msgstr "Baseado em"
msgid "Basic information"
-msgstr ""
+msgstr "Informação básica"
msgid "Be careful. Changing the project's namespace can have unintended side effects."
msgstr "Cuidado. Alterar o espaço de nome do projeto pode ter efeitos colaterais indesejados."
@@ -5436,7 +5486,7 @@ msgid "Below you will find all the groups that are public."
msgstr "Abaixo você encontrará todos os grupos que são públicos."
msgid "Beta"
-msgstr ""
+msgstr "Beta"
msgid "Bi-weekly code coverage"
msgstr "Cobertura semestral de código"
@@ -5568,13 +5618,13 @@ msgid "Billings|Your account has been validated"
msgstr "A sua conta foi validada."
msgid "Billing|%{user} was successfully approved"
-msgstr ""
+msgstr "O %{user} foi aprovado com sucesso"
msgid "Billing|An email address is only visible for users with public emails."
msgstr "Um endereço de e-mail só é visível para usuários com e-mails públicos."
msgid "Billing|An error occurred while approving %{user}"
-msgstr ""
+msgstr "Ocorreu um erro ao aprovar o %{user}"
msgid "Billing|An error occurred while getting a billable member details"
msgstr ""
@@ -5655,7 +5705,7 @@ msgid "Blame"
msgstr ""
msgid "BlobViewer|View on %{environmentName}"
-msgstr ""
+msgstr "Ver em %{environmentName}"
msgid "Block user"
msgstr "Bloquear usuário"
@@ -6252,13 +6302,13 @@ msgid "By default, all projects and groups will use the global notifications set
msgstr "Por padrão, todos os projetos e grupos usarão as configurações de notificações globais."
msgid "By month"
-msgstr ""
+msgstr "Por mês"
msgid "By quarter"
-msgstr ""
+msgstr "por trimestre"
msgid "By week"
-msgstr ""
+msgstr "Por semana"
msgid "ByAuthor|by"
msgstr "por"
@@ -6326,10 +6376,13 @@ msgid "CICDAnalytics|Releases"
msgstr ""
msgid "CICDAnalytics|Shared Runners Usage"
+msgstr "Uso de executores compartilhados"
+
+msgid "CICDAnalytics|Shared runner pipeline minute duration by month"
msgstr ""
msgid "CICDAnalytics|Shared runner usage"
-msgstr ""
+msgstr "Uso de executor compartilhado"
msgid "CICDAnalytics|Shared runner usage is the total runtime of all jobs that ran on shared runners"
msgstr ""
@@ -6469,6 +6522,9 @@ msgstr "Pode ser substituído em cada projeto."
msgid "Can create groups:"
msgstr "Pode criar grupos:"
+msgid "Can not delete primary training"
+msgstr ""
+
msgid "Can't apply as the source branch was deleted."
msgstr ""
@@ -6802,9 +6858,6 @@ msgstr ""
msgid "Changing any setting here requires an application restart"
msgstr ""
-msgid "Changing group URL can have unintended side effects."
-msgstr "Alterar a URL do grupo pode ter efeitos colaterais indesejados."
-
msgid "Charts can't be displayed as the request for data has timed out. %{documentationLink}"
msgstr ""
@@ -6892,9 +6945,6 @@ msgstr "Verificando status de aprovação"
msgid "Checking branch availability..."
msgstr "Verificando disponibilidade de branch..."
-msgid "Checking group URL availability..."
-msgstr ""
-
msgid "Checking group path availability..."
msgstr ""
@@ -7388,6 +7438,9 @@ msgstr "Limpar estado de saúde"
msgid "Clear recent searches"
msgstr "Limpar pesquisas recentes"
+msgid "Clear repository checks"
+msgstr ""
+
msgid "Clear search"
msgstr "Limpar pesquisa"
@@ -7520,9 +7573,6 @@ msgstr "Fechado %{epicTimeagoDate}"
msgid "Closed MRs"
msgstr "MRs fechados"
-msgid "Closed epics"
-msgstr "Épicos fechados"
-
msgid "Closed issues"
msgstr "Issues fechadas"
@@ -7539,7 +7589,7 @@ msgid "Cloud Run"
msgstr ""
msgid "Cloud Storage"
-msgstr ""
+msgstr "Armazenamento em nuvem"
msgid "Cluster"
msgstr "Cluster"
@@ -7559,13 +7609,13 @@ msgstr ""
msgid "Cluster level"
msgstr "Nível de cluster"
-msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
+msgid "Cluster type must be specified for Stages::ClusterEndpointInserter"
msgstr ""
msgid "ClusterAgents|%{name} successfully deleted"
msgstr ""
-msgid "ClusterAgents|%{number} of %{total} Agents"
+msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
@@ -7607,6 +7657,15 @@ msgstr "O agente pode não estar conectado ao GitLab"
msgid "ClusterAgents|Agent never connected to GitLab"
msgstr "Agente nunca conectado ao GitLab"
+msgid "ClusterAgents|Agent version mismatch"
+msgstr ""
+
+msgid "ClusterAgents|Agent version mismatch and update"
+msgstr ""
+
+msgid "ClusterAgents|Agent version update required"
+msgstr ""
+
msgid "ClusterAgents|All"
msgstr "Todos"
@@ -7631,7 +7690,7 @@ msgstr "Certificado"
msgid "ClusterAgents|Configuration"
msgstr "Configuração"
-msgid "ClusterAgents|Connect a cluster through the Agent"
+msgid "ClusterAgents|Connect a cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connect existing cluster"
@@ -7640,14 +7699,14 @@ msgstr "Conectar um cluster existente"
msgid "ClusterAgents|Connect with a certificate"
msgstr "Conectar com o certificado"
-msgid "ClusterAgents|Connect with agent"
+msgid "ClusterAgents|Connect with an agent"
msgstr ""
msgid "ClusterAgents|Connect with the GitLab Agent"
msgstr "Conectar com o GitLab Agent"
-msgid "ClusterAgents|Connect your cluster through the Agent"
-msgstr "Conecte seu cluster através do agente"
+msgid "ClusterAgents|Connect your cluster through an agent"
+msgstr ""
msgid "ClusterAgents|Connected"
msgstr "Conectado"
@@ -7706,7 +7765,10 @@ msgstr "Ir para o repositório de arquivos"
msgid "ClusterAgents|How to register an agent?"
msgstr "Como registrar um agente?"
-msgid "ClusterAgents|Install new Agent"
+msgid "ClusterAgents|How to update an agent?"
+msgstr ""
+
+msgid "ClusterAgents|Install a new agent"
msgstr ""
msgid "ClusterAgents|Last connected %{timeAgo}."
@@ -7733,7 +7795,7 @@ msgstr "Nunca"
msgid "ClusterAgents|Never connected"
msgstr "Nunca conectado"
-msgid "ClusterAgents|No Agents"
+msgid "ClusterAgents|No agents"
msgstr ""
msgid "ClusterAgents|No clusters connected through cluster certificates"
@@ -7793,6 +7855,9 @@ msgstr ""
msgid "ClusterAgents|The agent has not been connected in a long time. There might be a connectivity issue. Last contact was %{timeAgo}."
msgstr ""
+msgid "ClusterAgents|The agent version do not match each other across your cluster's pods. This can happen when a new agent version was just deployed and Kubernetes is shutting down the old pods."
+msgstr ""
+
msgid "ClusterAgents|The recommended installation method includes the token. If you want to follow the advanced installation method provided in the docs, make sure you save the token value before you close this window."
msgstr ""
@@ -7840,6 +7905,9 @@ msgstr ""
msgid "ClusterAgents|You will need to create a token to connect to your agent"
msgstr "Você precisará criar um token para conectar ao seu agente"
+msgid "ClusterAgents|Your agent version is out of sync with your GitLab version (v%{version}), which might cause compatibility problems. Update the agent installed on your cluster to the most recent version."
+msgstr ""
+
msgid "ClusterAgents|Your instance doesn't have the %{linkStart}GitLab Agent Server (KAS)%{linkEnd} set up. Ask a GitLab Administrator to install it."
msgstr ""
@@ -8078,7 +8146,7 @@ msgid "ClusterIntegration|Enable or disable GitLab's connection to your Kubernet
msgstr "Ative ou desative conexão do GitLab com seu cluster Kubernetes."
msgid "ClusterIntegration|Enable this setting if using role-based access control (RBAC)."
-msgstr "Habilite esta configuração se estiver usando o controle de acesso baseado em função (RBAC)."
+msgstr "Ative esta configuração se estiver usando o controle de acesso baseado em função (RBAC)."
msgid "ClusterIntegration|Enter new Service Token"
msgstr ""
@@ -8315,7 +8383,7 @@ msgid "ClusterIntegration|Provision Role ARN"
msgstr "ARN de função de provisão"
msgid "ClusterIntegration|RBAC-enabled cluster"
-msgstr "Cluster habilitado para RBAC"
+msgstr "Cluster ativado para RBAC"
msgid "ClusterIntegration|Read our %{linkStart}help page%{linkEnd} on Kubernetes cluster integration."
msgstr "Leia nossa %{linkStart}página de ajuda%{linkEnd} sobre integração de cluster do Kubernetes."
@@ -8716,9 +8784,6 @@ msgstr "ComboSearch não está definido"
msgid "Comma-separated list of email addresses."
msgstr "Lista de endereços de e-mail separados por vírgula."
-msgid "Comma-separated list of users allowed to exceed the rate limit."
-msgstr ""
-
msgid "Comma-separated, e.g. '1.1.1.1, 2.2.2.0/24'"
msgstr ""
@@ -8782,7 +8847,7 @@ msgid "Commit Message"
msgstr "Mensagem de Commit"
msgid "Commit SHA"
-msgstr ""
+msgstr "SHA de commit"
msgid "Commit changes"
msgstr "Confirmar mudanças"
@@ -9034,7 +9099,7 @@ msgid "ComplianceReport|Less than 2 approvers"
msgstr ""
msgid "ComplianceReport|No violations found"
-msgstr ""
+msgstr "Nenhuma violação encontrada"
msgid "Component"
msgstr "Componente"
@@ -9045,6 +9110,12 @@ msgstr "Confiança"
msgid "Confidential"
msgstr "Confidencial"
+msgid "Confidential issue"
+msgstr ""
+
+msgid "Confidential note"
+msgstr ""
+
msgid "Confidentiality"
msgstr "Confidencialidade"
@@ -9067,10 +9138,10 @@ msgid "Configure CAPTCHAs, IP address limits, and other anti-spam measures."
msgstr ""
msgid "Configure Container Scanning in `.gitlab-ci.yml` using the GitLab managed template. You can [add variable overrides](https://docs.gitlab.com/ee/user/application_security/container_scanning/#customizing-the-container-scanning-settings) to customize Container Scanning settings."
-msgstr ""
+msgstr "Configure a varredura de contêiner no `.gitlab-ci.yml` usando o modelo gerenciado pelo GitLab. Você pode [adicionar sobreposições de variáveis](https://docs.gitlab.com/ee/user/application_security/container_scanning/#customizing-the-container-scanning-settings) para personalizar as configurações de varredura de contêiner."
msgid "Configure Container Scanning in `.gitlab-ci.yml`, creating this file if it does not already exist"
-msgstr ""
+msgstr "Configurar a verificação de contêiner em `.gitlab-ci.yml`, criando este arquivo se ele ainda não existir"
msgid "Configure Dependency Scanning in `.gitlab-ci.yml` using the GitLab managed template. You can [add variable overrides](https://docs.gitlab.com/ee/user/application_security/dependency_scanning/#customizing-the-dependency-scanning-settings) to customize Dependency Scanning settings."
msgstr ""
@@ -9078,6 +9149,9 @@ msgstr ""
msgid "Configure Dependency Scanning in `.gitlab-ci.yml`, creating this file if it does not already exist"
msgstr ""
+msgid "Configure GitLab"
+msgstr ""
+
msgid "Configure GitLab runners to start using the Web Terminal. %{helpStart}Learn more.%{helpEnd}"
msgstr "Configure os executores do GitLab para começar a usar o terminal da web. %{helpStart}Saiba mais.%{helpEnd}"
@@ -9126,6 +9200,15 @@ msgstr "Configurar instalação existente"
msgid "Configure pipelines to deploy web apps, backend services, APIs and static resources to Google Cloud"
msgstr ""
+msgid "Configure region"
+msgstr ""
+
+msgid "Configure region for environment"
+msgstr ""
+
+msgid "Configure regions"
+msgstr ""
+
msgid "Configure repository mirroring."
msgstr "Configurar espelhamento de repositório."
@@ -9154,16 +9237,19 @@ msgid "Configure the way a user creates a new account."
msgstr "Configurar a forma como o usuário cria uma nova conta."
msgid "Configure via Merge Request"
-msgstr ""
+msgstr "Configurar via solicitação de mesclagem"
msgid "Configure which lists are shown for anyone who visits this board"
msgstr "Configure quais listas são mostradas para qualquer pessoa que visita este painel"
+msgid "Configure your environments to be deployed to specific geographical regions"
+msgstr ""
+
msgid "Confirm"
msgstr "Confirmar"
msgid "Confirm approval"
-msgstr ""
+msgstr "Confirmar aprovação"
msgid "Confirm new password"
msgstr "Confirmar a nova senha"
@@ -9861,12 +9947,12 @@ msgstr "Tem certeza de que deseja excluir o corpus?"
msgid "CorpusManagement|Actions"
msgstr "Ações"
-msgid "CorpusManagement|Corpus are used in fuzz testing as mutation source to Improve future testing."
-msgstr "Corpus são usados em testes de fuzz como fonte de mutação para melhorar testes futuros."
-
msgid "CorpusManagement|Corpus file"
msgstr ""
+msgid "CorpusManagement|Corpus files are used in coverage-guided fuzz testing as seed inputs to improve testing."
+msgstr ""
+
msgid "CorpusManagement|Corpus files must be in *.zip format. Maximum 5 GB"
msgstr ""
@@ -9918,6 +10004,9 @@ msgstr "Não foi possível adicionar administradores como membros"
msgid "Could not apply %{name} command."
msgstr ""
+msgid "Could not apply %{name} command. %{message}."
+msgstr ""
+
msgid "Could not authorize chat nickname. Try again!"
msgstr "Não foi possível autorizar o apelido do bate-papo. Tente novamente!"
@@ -9997,7 +10086,7 @@ msgid "Could not restore the group"
msgstr "Não foi possível restaurar o grupo"
msgid "Could not revoke access token %{access_token_name}."
-msgstr ""
+msgstr "Não foi possível revogar o token de acesso %{access_token_name}."
msgid "Could not revoke impersonation token %{token_name}."
msgstr "Não foi possível revogar o token de representação %{token_name}."
@@ -10068,6 +10157,9 @@ 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"
+msgstr ""
+
msgid "Create a merge request"
msgstr ""
@@ -10092,6 +10184,9 @@ msgstr "Criar um novo repositório"
msgid "Create a personal access token on your account to pull or push via %{protocol}."
msgstr "Crie um token de acesso pessoal na sua conta para dar pull ou push via %{protocol}."
+msgid "Create a project"
+msgstr ""
+
msgid "Create an account using:"
msgstr "Criar uma conta usando:"
@@ -10150,7 +10245,7 @@ msgid "Create iteration"
msgstr "Criar interação"
msgid "Create label"
-msgstr ""
+msgstr "Criar etiqueta"
msgid "Create list"
msgstr "Criar lista"
@@ -10455,6 +10550,9 @@ msgstr "A criação de gráficos usa os dados do servidor Prometheus. Se isso le
msgid "Creation date"
msgstr "Data de criação"
+msgid "Creator"
+msgstr ""
+
msgid "Credentials"
msgstr "Credenciais"
@@ -10467,9 +10565,15 @@ msgstr "Nenhuma credencial encontrada"
msgid "CredentialsInventory|Personal Access Tokens"
msgstr "Tokens de acesso pessoal"
+msgid "CredentialsInventory|Project Access Tokens"
+msgstr ""
+
msgid "CredentialsInventory|SSH Keys"
msgstr "Chaves SSH"
+msgid "Credit card required to be on file in order to create a pipeline"
+msgstr ""
+
msgid "Credit card:"
msgstr "Cartão de crédito:"
@@ -10653,9 +10757,6 @@ msgstr ""
msgid "Customer relations"
msgstr ""
-msgid "Customizable by an administrator."
-msgstr "Personalizado por um administrador"
-
msgid "Customizable by owners."
msgstr "Personalizado por proprietários."
@@ -10785,30 +10886,18 @@ msgstr "deve estar em um grupo"
msgid "CycleAnalytics|%{selectedLabelsCount} selected (%{maxLabels} max)"
msgstr "%{selectedLabelsCount} selecionado (%{maxLabels} max)"
-msgid "CycleAnalytics|%{stageCount} stages selected"
-msgstr "%{stageCount} estágios selecionados"
-
-msgid "CycleAnalytics|All stages"
-msgstr "Todas os estágios"
-
-msgid "CycleAnalytics|Average days to completion"
-msgstr "Média de dias para conclusão"
+msgid "CycleAnalytics|Average time to completion"
+msgstr ""
msgid "CycleAnalytics|Date"
msgstr "Data"
-msgid "CycleAnalytics|Days to completion"
-msgstr "Dias para completar"
-
msgid "CycleAnalytics|Display chart filters"
msgstr "Mostrar filtros de gráficos"
msgid "CycleAnalytics|Lead Time for Changes"
msgstr ""
-msgid "CycleAnalytics|No stages selected"
-msgstr "Nenhum estágios selecionados"
-
msgid "CycleAnalytics|Number of tasks"
msgstr "Número de tarefas"
@@ -10837,18 +10926,30 @@ msgstr "Mostrando dados para o grupo '%{groupName}' e %{selectedProjectCount} pr
msgid "CycleAnalytics|Showing data for group '%{groupName}' from %{createdAfter} to %{createdBefore}"
msgstr "Mostrando dados para o grupo '%{groupName}' de %{createdAfter} a %{createdBefore}"
-msgid "CycleAnalytics|Stages"
-msgstr "Estágios"
+msgid "CycleAnalytics|Stage time: %{title}"
+msgstr ""
msgid "CycleAnalytics|Tasks by type"
msgstr "Tarefas por tipo"
-msgid "CycleAnalytics|The average time spent in the selected stage for the items that were completed on each date. Data limited to the last 500 items."
-msgstr "O tempo médio gasto no estágio selecionado para os itens que foram concluídos em cada data. Dados limitados aos últimos 500 itens."
+msgid "CycleAnalytics|The average time items spent in this stage. Data limited to items completed within this date range."
+msgstr ""
msgid "CycleAnalytics|The given date range is larger than 180 days"
msgstr "O intervalo de datas fornecido é superior a 180 dias"
+msgid "CycleAnalytics|The total time items spent across each value stream stage. Data limited to items completed within this date range."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Stage time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Total time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|Total time"
+msgstr ""
+
msgid "CycleAnalytics|Type of work"
msgstr "Tipo de trabalho"
@@ -10861,9 +10962,6 @@ msgstr ""
msgid "CycleAnalytics|project dropdown filter"
msgstr ""
-msgid "CycleAnalytics|stage dropdown"
-msgstr "estágio suspenso"
-
msgid "DAG visualization requires at least 3 dependent jobs."
msgstr ""
@@ -10963,11 +11061,17 @@ msgstr ""
msgid "DastProfiles|AJAX spider"
msgstr ""
+msgid "DastProfiles|API"
+msgstr ""
+
+msgid "DastProfiles|API endpoint URL"
+msgstr ""
+
msgid "DastProfiles|Active"
msgstr "Ativo"
-msgid "DastProfiles|Additional request headers (Optional)"
-msgstr "Cabeçalhos adicionais de requisição (Opcional)"
+msgid "DastProfiles|Additional request headers (optional)"
+msgstr ""
msgid "DastProfiles|Are you sure you want to delete this profile?"
msgstr ""
@@ -10981,6 +11085,9 @@ msgstr "URL de autenticação"
msgid "DastProfiles|Branch missing"
msgstr "Branch faltando"
+msgid "DastProfiles|Choose a scan method"
+msgstr ""
+
msgid "DastProfiles|Could not create the scanner profile. Please try again."
msgstr "Não foi possível criar o perfil da verificação. Por favor, tente novamente."
@@ -11050,8 +11157,14 @@ msgstr "Detalhes do erro"
msgid "DastProfiles|Excluded URLs"
msgstr "URLs excluídas"
-msgid "DastProfiles|Excluded URLs (Optional)"
-msgstr "URLs excluídas (Opcional)"
+msgid "DastProfiles|Excluded URLs (optional)"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths (optional)"
+msgstr ""
msgid "DastProfiles|Hide debug messages"
msgstr "Ocultar mensagens de depuração"
@@ -11107,9 +11220,6 @@ msgstr "Nomes e valores dos cabeçalhos de requisição. Cabeçalhos são adicio
msgid "DastProfiles|Request headers"
msgstr "Cabeçalhos de requisição"
-msgid "DastProfiles|Rest API"
-msgstr ""
-
msgid "DastProfiles|Run the AJAX spider, in addition to the traditional spider, to crawl the target site."
msgstr ""
@@ -11119,6 +11229,9 @@ msgstr "Salvar configurações comumente usadas para sites de destino e especifi
msgid "DastProfiles|Save profile"
msgstr "Salvar perfil"
+msgid "DastProfiles|Scan method"
+msgstr ""
+
msgid "DastProfiles|Scan mode"
msgstr "Modo de verificação"
@@ -11197,12 +11310,24 @@ msgstr "Status da validação"
msgid "DastProfiles|Website"
msgstr "Site"
+msgid "DastProfiles|What does each method do?"
+msgstr ""
+
msgid "DastProfiles|You can either choose a passive scan or validate the target site from the site profile management page. %{docsLinkStart}Learn more about site validation.%{docsLinkEnd}"
msgstr ""
msgid "DastProfiles|You cannot run an active scan against an unvalidated site."
msgstr ""
+msgid "DastProfiles|folder/dast_example.har or https://example.com/dast_example.har"
+msgstr ""
+
+msgid "DastProfiles|folder/example.postman_collection.json or https://example.com/"
+msgstr ""
+
+msgid "DastProfiles|folder/openapi.json or https://example.com/openapi.json"
+msgstr ""
+
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
@@ -11310,6 +11435,9 @@ msgstr "(Avançado) O URL completo do seu site de Datadog."
msgid "DatadogIntegration|API URL"
msgstr "URL da API"
+msgid "DatadogIntegration|Custom tags in Datadog. Enter one tag per line in the %{codeOpen}key:value%{codeClose} format. %{linkOpen}How do I use tags?%{linkClose}"
+msgstr ""
+
msgid "DatadogIntegration|Environment"
msgstr "Ambiente"
@@ -11328,12 +11456,18 @@ msgstr "Serviço"
msgid "DatadogIntegration|Tag all data from this GitLab instance in Datadog. Useful when managing several self-managed deployments."
msgstr ""
+msgid "DatadogIntegration|Tags"
+msgstr ""
+
msgid "DatadogIntegration|The Datadog site to send data to. To send data to the EU site, use %{codeOpen}datadoghq.eu%{codeClose}."
msgstr ""
msgid "DatadogIntegration|Trace your GitLab pipelines with Datadog."
msgstr "Rastreie seus pipelines GitLab com Datadog."
+msgid "DatadogIntegration|have an invalid format"
+msgstr ""
+
msgid "Datasource name not found"
msgstr ""
@@ -11343,9 +11477,6 @@ msgstr "Data"
msgid "Date merged"
msgstr ""
-msgid "Date picker"
-msgstr "Seletor de data"
-
msgid "Date range"
msgstr "Intervalo de datas"
@@ -11499,9 +11630,6 @@ msgstr "Defina como as regras de aprovação são aplicadas às solicitações d
msgid "Definition"
msgstr "Definição"
-msgid "Delayed Project Deletion (%{adjourned_deletion})"
-msgstr "Atraso para exclusão de projeto (%{adjourned_deletion})"
-
msgid "DelayedJobs|Are you sure you want to run %{jobName} immediately? Otherwise this job will run automatically after its timer finishes."
msgstr ""
@@ -11580,12 +11708,12 @@ msgstr "Excluir etiqueta: %{labelName}"
msgid "Delete pipeline"
msgstr "Excluir pipeline"
+msgid "Delete pipeline schedule"
+msgstr ""
+
msgid "Delete project"
msgstr "Excluir projeto"
-msgid "Delete project. Are you ABSOLUTELY SURE?"
-msgstr "Excluir projeto. VOCÊ TEM CERTEZA ABSOLUTA DISSO?"
-
msgid "Delete row"
msgstr "Excluir linha"
@@ -11613,6 +11741,9 @@ msgstr "Excluir este anexo"
msgid "Delete this epic and all descendants?"
msgstr "Excluir este épico e todos os descendentes?"
+msgid "Delete this project"
+msgstr ""
+
msgid "Delete user list"
msgstr "Excluir lista de usuário"
@@ -11620,7 +11751,7 @@ msgid "Delete variable"
msgstr "Excluir a variável"
msgid "DeleteProject|Failed to remove events. Please try again or contact administrator."
-msgstr ""
+msgstr "Falha ao remover os eventos. Por favor, tente novamente ou entre em contato com o administrador."
msgid "DeleteProject|Failed to remove project repository. Please try again or contact administrator."
msgstr "Falha ao remover o repositório do projeto. Por favor, tente novamente ou entre em contato com o administrador."
@@ -11677,7 +11808,7 @@ msgid "Deleting the project will delete its repository and all related resources
msgstr "Apagar o projeto irá apagar o repositório e todos os itens relacionados, como issues e solicitações de mesclagem."
msgid "Deletion pending. This project will be deleted on %{date}. Repository and other project resources are read-only."
-msgstr ""
+msgstr "Exclusão pendente. Este projeto será excluído em %{date}. Repositório e outros recursos do projeto são somente leitura."
msgid "Denied"
msgstr "Negado"
@@ -11871,6 +12002,12 @@ msgstr ""
msgid "Deploy to..."
msgstr "Implantar em..."
+msgid "DeployBoards|To see deployment progress for your environments, make sure you are deploying to %{codeStart}$KUBE_NAMESPACE%{codeEnd} and annotating with %{codeStart}app.gitlab.com/app=$CI_PROJECT_PATH_SLUG%{codeEnd} and %{codeStart}app.gitlab.com/env=$CI_ENVIRONMENT_SLUG%{codeEnd}."
+msgstr ""
+
+msgid "DeployBoard|Kubernetes Pods"
+msgstr ""
+
msgid "DeployFreeze|Add a freeze period to prevent unintended releases during a period of time for a given environment. You must update the deployment jobs in %{filename} according to the deploy freezes added here. %{freeze_period_link_start}Learn more.%{freeze_period_link_end}"
msgstr ""
@@ -11955,9 +12092,6 @@ msgstr "Apenas acesso de leitura"
msgid "DeployTokens|Active Deploy Tokens (%{active_tokens})"
msgstr "Tokens de implantação ativos (%{active_tokens})"
-msgid "DeployTokens|Allows read and write access to registry images."
-msgstr "Permite acesso de leitura e gravação às imagens de registro."
-
msgid "DeployTokens|Allows read and write access to the package registry."
msgstr "Permite acesso de leitura e gravação ao registro do pacote."
@@ -11970,6 +12104,9 @@ msgstr ""
msgid "DeployTokens|Allows read-only access to the repository."
msgstr "Permite acesso somente-leitura ao repositório."
+msgid "DeployTokens|Allows write access to registry images."
+msgstr ""
+
msgid "DeployTokens|Copy deploy token"
msgstr "Copiar token de implantação"
@@ -12063,12 +12200,57 @@ msgstr "Implantando para"
msgid "Deploying to AWS is easy with GitLab"
msgstr "Implantar em AWS é fácil com GitLab"
+msgid "Deployment"
+msgstr ""
+
msgid "Deployment Frequency"
msgstr "Frequência de implantação"
+msgid "Deployment Target|Project deployment target (optional)"
+msgstr ""
+
+msgid "Deployment Target|Select the deployment target"
+msgstr ""
+
msgid "Deployment frequency"
msgstr "Frequência de implantação"
+msgid "DeploymentTarget|GitLab Pages"
+msgstr ""
+
+msgid "DeploymentTarget|Heroku"
+msgstr ""
+
+msgid "DeploymentTarget|Infrastructure provider (Terraform, Cloudformation, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Kubernetes (GKE, EKS, OpenShift, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Managed container runtime (Fargate, Cloud Run, DigitalOcean App)"
+msgstr ""
+
+msgid "DeploymentTarget|Mobile app store"
+msgstr ""
+
+msgid "DeploymentTarget|No deployment planned"
+msgstr ""
+
+msgid "DeploymentTarget|Other hosting service"
+msgstr ""
+
+msgid "DeploymentTarget|Registry (package or container)"
+msgstr ""
+
+msgid "DeploymentTarget|Self-managed container runtime (Podman, Docker Swarm, Docker Compose)"
+msgstr ""
+
+msgid "DeploymentTarget|Serverless backend (Lambda, Cloud functions)"
+msgstr ""
+
+msgid "DeploymentTarget|Virtual machine (for example, EC2)"
+msgstr ""
+
msgid "Deployments"
msgstr "Implementações"
@@ -12081,35 +12263,38 @@ msgid "Deployment|API"
msgstr "API"
msgid "Deployment|Cancelled"
-msgstr ""
+msgstr "Cancelado"
msgid "Deployment|Created"
-msgstr ""
+msgstr "Criado"
msgid "Deployment|Deployment ID"
-msgstr ""
+msgstr "ID da implantação"
msgid "Deployment|Failed"
-msgstr ""
+msgstr "Falhado"
msgid "Deployment|Latest Deployed"
-msgstr ""
+msgstr "Última implantação"
msgid "Deployment|Running"
-msgstr ""
+msgstr "Em execução"
msgid "Deployment|Skipped"
-msgstr ""
+msgstr "Pulado"
msgid "Deployment|Success"
-msgstr ""
+msgstr "Sucesso"
msgid "Deployment|This deployment was created using the API"
msgstr ""
-msgid "Deployment|Waiting"
+msgid "Deployment|Triggerer"
msgstr ""
+msgid "Deployment|Waiting"
+msgstr "Aguardando"
+
msgid "Deployment|blocked"
msgstr ""
@@ -12134,6 +12319,18 @@ msgstr "sucesso"
msgid "Deprecated API rate limits"
msgstr ""
+msgid "Deprecations|Feature deprecation and removal"
+msgstr ""
+
+msgid "Deprecations|For information on a possible replacement %{epicStart} learn more about Opstrace %{epicEnd}."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7 and are %{epicStart} scheduled for removal %{epicEnd} in GitLab 15.0."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7, and are %{removal_link_start} scheduled for removal %{link_end} in GitLab 15.0. For information on a possible replacement, %{opstrace_link_start} learn more about Opstrace %{link_end}."
+msgstr ""
+
msgid "Deprioritize label"
msgstr "Despriorizar etiqueta"
@@ -12379,10 +12576,10 @@ msgstr ""
msgid "DevopsAdoption|At least one deploy"
msgstr ""
-msgid "DevopsAdoption|At least one issue opened"
+msgid "DevopsAdoption|At least one issue created"
msgstr ""
-msgid "DevopsAdoption|At least one merge request opened"
+msgid "DevopsAdoption|At least one merge request created"
msgstr ""
msgid "DevopsAdoption|At least one pipeline successfully run"
@@ -12583,6 +12780,9 @@ msgstr "com %{additions} e %{deletions}"
msgid "Direct member"
msgstr "Membro direto"
+msgid "Direct members"
+msgstr ""
+
msgid "Direct non-authenticated users to this page."
msgstr "Direcionar usuários não autenticados para esta página."
@@ -12699,6 +12899,9 @@ msgid_plural "Dismiss %d selected vulnerabilities as"
msgstr[0] ""
msgstr[1] ""
+msgid "Dismiss Alert"
+msgstr ""
+
msgid "Dismiss merge request promotion"
msgstr "Dispensar promoção de solicitação de mesclagem"
@@ -12726,9 +12929,15 @@ msgstr "Descartado no pipeline %{pipelineLink} em %{projectLink}"
msgid "Display alerts from all configured monitoring tools."
msgstr "Exibir alertas de todas as ferramentas de monitoramento configuradas."
+msgid "Display milestones"
+msgstr ""
+
msgid "Display name"
msgstr "Nome de exibição"
+msgid "Display progress of child issues"
+msgstr ""
+
msgid "Display rendered file"
msgstr "Exibir arquivo renderizado"
@@ -12834,6 +13043,9 @@ msgstr "Baixar exportação"
msgid "Download image"
msgstr "Baixar imagem"
+msgid "Download payload"
+msgstr ""
+
msgid "Download raw data (.csv)"
msgstr "Baixar dados raw (.csv)"
@@ -13011,6 +13223,9 @@ msgstr "Editar identidade para %{user_name}"
msgid "Edit in Web IDE"
msgstr "Editar no IDE Web"
+msgid "Edit in pipeline editor"
+msgstr ""
+
msgid "Edit in single-file editor"
msgstr ""
@@ -13053,6 +13268,9 @@ msgstr "Editar página da wiki"
msgid "Edit your most recent comment in a thread (from an empty textarea)"
msgstr "Editar seu comentário mais recente em um tópico (a partir de uma área de texto vazia)"
+msgid "Edit, lint, and visualize your pipeline."
+msgstr ""
+
msgid "Edited"
msgstr "Editado"
@@ -13303,7 +13521,7 @@ msgid "Enable access to the performance bar for non-administrators in a given gr
msgstr ""
msgid "Enable access tokens to expire after 2 hours. If disabled, tokens do not expire."
-msgstr ""
+msgstr "Ativar que os tokens de acesso expirem após 2 horas. Se desativado, os tokens não expiram."
msgid "Enable admin mode"
msgstr "Ativar modo administrativo"
@@ -13369,7 +13587,7 @@ msgid "Enable kuromoji custom analyzer: Search"
msgstr ""
msgid "Enable logs collection"
-msgstr ""
+msgstr "Ativar coleta de registros"
msgid "Enable maintenance mode"
msgstr "Ativar modo de manutenção"
@@ -13399,7 +13617,7 @@ msgid "Enable repository checks"
msgstr "Ativar as verificações de repositório"
msgid "Enable security training"
-msgstr ""
+msgstr "Ativar treinamento de segurança"
msgid "Enable security training to help your developers learn how to fix vulnerabilities. Developers can view security training from selected educational providers, relevant to the detected vulnerability."
msgstr ""
@@ -13494,6 +13712,9 @@ msgstr "Forçar autenticação de dois fatores"
msgid "Enforce two-factor authentication for all user sign-ins."
msgstr "Forçar Autenticação de dois fatores para todos os logins de usuários"
+msgid "Enhance security by storing service account keys in secret managers - learn more about %{docLinkStart}secret management with GitLab%{docLinkEnd}"
+msgstr ""
+
msgid "Ensure connectivity is available from the GitLab server to the Prometheus server"
msgstr ""
@@ -13531,7 +13752,7 @@ msgid "Enter in your Phabricator Server URL and personal access token below"
msgstr "Informe o URL do servidor do Phabricator e o token de acesso pessoal abaixo"
msgid "Enter license key"
-msgstr ""
+msgstr "Inserir chave da licença"
msgid "Enter merge request URLs"
msgstr "Digite as URLs de solicitações de mesclagem"
@@ -13554,6 +13775,9 @@ msgstr "Digite o título para %{name}"
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 following to confirm:"
+msgstr ""
+
msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr "Digite o nome da sua aplicação e devolveremos um %{type} único."
@@ -13573,7 +13797,7 @@ msgid "Enter your Packagist token."
msgstr ""
msgid "Enter your Packagist username."
-msgstr ""
+msgstr "Digite seu nome de usuário do Packagist."
msgid "Enter your password to approve"
msgstr "Digite sua senha para aprovar"
@@ -14084,9 +14308,6 @@ msgstr ""
msgid "Error occurred while updating the issue status"
msgstr "Ocorreu um erro ao atualizar o status da issue"
-msgid "Error occurred while updating the issue weight"
-msgstr "Ocorreu um erro ao atualizar o peso da issue"
-
msgid "Error occurred. A blocked user cannot be deactivated"
msgstr "Ocorreu um erro. Um usuário bloqueado não pode ser desativado"
@@ -14222,6 +14443,9 @@ msgstr ""
msgid "Errors:"
msgstr "Erros:"
+msgid "Escalate this incident"
+msgstr ""
+
msgid "Escalation Policies"
msgstr "Políticas de escalação"
@@ -14234,9 +14458,12 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr "As políticas de escalonamento devem ter pelo menos uma regra"
-msgid "Escalation policy:"
+msgid "Escalation policy"
msgstr ""
+msgid "Escalation policy:"
+msgstr "Política de escalação:"
+
msgid "EscalationPolicies|%{clockIcon} IF alert is not %{alertStatus} in %{minutes}"
msgstr ""
@@ -14485,6 +14712,9 @@ msgstr ""
msgid "Existing sign in methods may be removed"
msgstr ""
+msgid "Exit."
+msgstr ""
+
msgid "Expand"
msgstr "Expandir"
@@ -14581,6 +14811,9 @@ msgstr "Explorar projetos"
msgid "Explore public groups"
msgstr "Explorar grupos públicos"
+msgid "Explore public projects"
+msgstr ""
+
msgid "Explore snippets"
msgstr ""
@@ -14663,22 +14896,22 @@ msgid "ExternalAuthorization|Classification label to use when requesting authori
msgstr ""
msgid "ExternalAuthorization|Client authorization certificate"
-msgstr ""
+msgstr "Certificado de autorização do cliente"
msgid "ExternalAuthorization|Client authorization key"
-msgstr ""
+msgstr "Chave de autorização do cliente"
msgid "ExternalAuthorization|Client authorization key password (optional)"
msgstr ""
msgid "ExternalAuthorization|Default classification label"
-msgstr ""
+msgstr "Etiqueta de classificação padrão"
msgid "ExternalAuthorization|Enable classification control using an external service"
msgstr ""
msgid "ExternalAuthorization|External authorization"
-msgstr ""
+msgstr "Autorização externa"
msgid "ExternalAuthorization|External authorization request timeout (seconds)"
msgstr ""
@@ -14696,7 +14929,7 @@ msgid "ExternalAuthorization|Private key of client authentication certificate. E
msgstr ""
msgid "ExternalAuthorization|Service URL"
-msgstr ""
+msgstr "URL do serviço"
msgid "ExternalAuthorization|URL to which the projects make authorization requests. If the URL is blank, cross-project features are available and can still specify classification labels for projects."
msgstr ""
@@ -14714,7 +14947,7 @@ msgid "ExternalWikiService|External wiki URL"
msgstr "URL da wiki externa"
msgid "ExternalWikiService|Link to an external wiki from the sidebar."
-msgstr ""
+msgstr "Link para uma wiki externa para a barra lateral."
msgid "ExternalWikiService|https://example.com/xxx/wiki/..."
msgstr ""
@@ -14742,8 +14975,8 @@ msgid_plural "Failed to archive designs. Please try again."
msgstr[0] ""
msgstr[1] ""
-msgid "Failed to assign a reviewer because no user was found."
-msgstr "Falha ao atribuir um revisor porque nenhum usuário foi encontrado."
+msgid "Failed to assign a reviewer because no user was specified."
+msgstr ""
msgid "Failed to assign a user because no user was found."
msgstr "Falha ao associar um usuário porque nenhum usuário foi encontrado."
@@ -14782,7 +15015,7 @@ msgid "Failed to create import label for jira import."
msgstr ""
msgid "Failed to create new access token: %{token_response_message}"
-msgstr ""
+msgstr "Falha ao criar novo token de acesso: %{token_response_message}"
msgid "Failed to create repository"
msgstr "Falha ao criar o repositório"
@@ -14808,12 +15041,12 @@ msgstr ""
msgid "Failed to find import label for Jira import."
msgstr ""
+msgid "Failed to find users for %{missing}"
+msgstr ""
+
msgid "Failed to generate export, please try again later."
msgstr "Não foi possível exportar, tente novamente mais tarde"
-msgid "Failed to generate report, please try again after sometime"
-msgstr ""
-
msgid "Failed to get ref."
msgstr "Falha ao obter a ref."
@@ -14910,6 +15143,9 @@ msgstr "Falha ao remover uma reunião do Zoom"
msgid "Failed to remove a to-do item for the design."
msgstr ""
+msgid "Failed to remove attention because no user was found."
+msgstr ""
+
msgid "Failed to remove mirror."
msgstr "Falha ao remover a espelho."
@@ -14922,6 +15158,9 @@ msgstr "Falha ao remover a identidade do usuário."
msgid "Failed to remove user key."
msgstr "Falha ao remover a chave do usuário."
+msgid "Failed to request attention because no user was found."
+msgstr ""
+
msgid "Failed to reset key. Please try again."
msgstr "Falha ao redefinir a chave. Por favor, tente novamente."
@@ -15003,6 +15242,9 @@ msgstr "Favicon será removido. Você tem certeza?"
msgid "Feature Flags"
msgstr "Feature flag"
+msgid "Feature deprecation and removal"
+msgstr ""
+
msgid "Feature flag status"
msgstr "Status de feature flag"
@@ -15500,8 +15742,8 @@ msgstr "Para cada tarefa, clone o repositório."
msgid "For each job, re-use the project workspace. If the workspace doesn't exist, use %{code_open}git clone%{code_close}."
msgstr "Para cada tarefa, reutilize o espaço de tarefa do projeto. Se o espaço de tarefa não existir, use %{code_open}git clone%{code_close}."
-msgid "For example, the application using the token or the purpose of the token."
-msgstr "Por exemplo, a aplicação usando o token ou o propósito do token."
+msgid "For example, the application using the token or the purpose of the token. Do not give sensitive information for the name of the token, as it will be visible to all %{resource_type} members."
+msgstr ""
msgid "For files larger than this limit, only index the file name. The file content is neither indexed nor searchable."
msgstr "Para arquivos maiores que este limite indexam apenas o nome do arquivo. O conteúdo do arquivo não é indexado nem pesquisável."
@@ -15584,9 +15826,6 @@ msgstr "Público"
msgid "ForkProject|Select a namespace"
msgstr "Selecionar um espaço nominal"
-msgid "ForkProject|Select a namespace to fork the project"
-msgstr "Selecione um espaço de nome para realizar o fork do projeto"
-
msgid "ForkProject|The project can be accessed by any logged in user."
msgstr ""
@@ -15633,7 +15872,7 @@ msgid "Found errors in your .gitlab-ci.yml:"
msgstr "Erros encontrados em seu .gitlab-ci.yml:"
msgid "Found warning in your .gitlab-ci.yml"
-msgstr ""
+msgstr "Avisos encontrados em seu .gitlab-ci.yml"
msgid "Framework successfully deleted"
msgstr ""
@@ -15683,6 +15922,9 @@ msgstr "Registro completo"
msgid "Full name"
msgstr "Nome completo"
+msgid "GCP region configured"
+msgstr ""
+
msgid "GPG Key ID:"
msgstr "ID da chave GPG:"
@@ -15801,7 +16043,7 @@ msgid "Geo|Adjust your filters/search criteria above. If you believe this may be
msgstr ""
msgid "Geo|All"
-msgstr ""
+msgstr "Todos"
msgid "Geo|All %{replicable_name}"
msgstr ""
@@ -15828,7 +16070,7 @@ msgid "Geo|Checksummed"
msgstr ""
msgid "Geo|Connection timeout can't be blank"
-msgstr ""
+msgstr "O tempo limite de conexão não pode ficar em branco"
msgid "Geo|Connection timeout must be a number"
msgstr ""
@@ -15852,7 +16094,7 @@ msgid "Geo|Disabled"
msgstr "Desativado"
msgid "Geo|Discover GitLab Geo"
-msgstr ""
+msgstr "Descobrir o GitLab Geo"
msgid "Geo|Does not match the primary storage configuration"
msgstr ""
@@ -15863,6 +16105,9 @@ msgstr ""
msgid "Geo|Failed"
msgstr "Falha"
+msgid "Geo|Filter Geo sites"
+msgstr ""
+
msgid "Geo|Filter by name"
msgstr "Filtrar por nome"
@@ -15993,7 +16238,7 @@ msgid "Geo|Remove entry"
msgstr "Remover entrada"
msgid "Geo|Remove site"
-msgstr ""
+msgstr "Remover site"
msgid "Geo|Remove tracking database entry"
msgstr ""
@@ -16059,7 +16304,7 @@ msgid "Geo|Selective (%{syncLabel})"
msgstr ""
msgid "Geo|Site name can't be blank"
-msgstr ""
+msgstr "O nome do site não pode ficar em branco"
msgid "Geo|Site name should be between 1 and 255 characters"
msgstr ""
@@ -16182,7 +16427,7 @@ msgid "Get a free instance review"
msgstr "Obter gratuitamente uma instância de revisão"
msgid "Get a free trial"
-msgstr ""
+msgstr "Obtenha um teste gratuito"
msgid "Get a support subscription"
msgstr ""
@@ -16274,6 +16519,12 @@ msgstr "Importação do GitLab"
msgid "GitLab Issue"
msgstr "Issue do GitLab"
+msgid "GitLab KAS"
+msgstr ""
+
+msgid "GitLab Memberships CSV Export"
+msgstr ""
+
msgid "GitLab Pages"
msgstr "GitLab Pages"
@@ -16322,6 +16573,9 @@ msgstr "GitLab é uma plataforma completa de DevOps, entregue como uma única ap
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 free to use. Many features for larger teams are part of our %{link_start}paid products%{link_end}. You can try Ultimate for free without any obligation or payment details."
+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 "O GitLab está obtendo um certificado SSL Let's Encrypt para este domínio. Este processo pode levar algum tempo. Por favor, tente novamente mais tarde."
@@ -16332,7 +16586,7 @@ msgid "GitLab is undergoing maintenance and is operating in read-only mode."
msgstr ""
msgid "GitLab logo"
-msgstr ""
+msgstr "Logotipo do GitLab"
msgid "GitLab member or Email address"
msgstr "Membro do GitLab ou endereço de e-mail"
@@ -16448,7 +16702,7 @@ msgstr "Verificado"
msgid "GitLabPages|When enabled, all attempts to visit your website through HTTP are automatically redirected to HTTPS using a response with status code 301. Requires a valid certificate for all domains. %{docs_link_start}Learn more.%{link_end}"
msgstr "Quando ativado, todas as tentativas de visitar seu site através de HTTP são redirecionadas automaticamente para HTTPS usando uma resposta com o código de status 301. Requer um certificado válido para todos os domínios. %{docs_link_start}Saiba mais.%{link_end}"
-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. %{docs_link_start}Learn more.%{link_end}"
+msgid "GitLabPages|When using Pages under the general domain of a GitLab instance (%{pages_host}), you cannot use HTTPS with subdomains of subdomains. If your namespace or groupname contains a dot, it does not work. This is a limitation of the HTTP Over TLS protocol. HTTP pages work if you don't redirect HTTP to HTTPS. %{docs_link_start}Learn more.%{link_end}"
msgstr ""
msgid "GitLabPages|With GitLab Pages you can host your static website directly from your GitLab repository. %{docs_link_start}Learn more.%{link_end}"
@@ -16625,9 +16879,6 @@ msgstr "Ir para arquivos"
msgid "Go to find file"
msgstr "Ir para busca de arquivo"
-msgid "Go to fork"
-msgstr "Ir para fork"
-
msgid "Go to issue boards"
msgstr "Ir para os painéis"
@@ -16734,13 +16985,13 @@ msgid "Google Cloud"
msgstr "Google Cloud"
msgid "Google Cloud Project"
-msgstr ""
+msgstr "Projeto de Google Cloud"
msgid "Google Cloud authorizations required"
msgstr ""
msgid "Google Cloud project"
-msgstr ""
+msgstr "Projeto de Google Cloud"
msgid "Google Cloud project misconfigured"
msgstr ""
@@ -16827,7 +17078,7 @@ msgid "Group %{group_name} was successfully created."
msgstr "O grupo %{group_name} foi criado com sucesso."
msgid "Group Access Tokens"
-msgstr ""
+msgstr "Tokens de acesso de grupo"
msgid "Group Git LFS status:"
msgstr "Status do LFS do grupo Git:"
@@ -16835,9 +17086,6 @@ msgstr "Status do LFS do grupo Git:"
msgid "Group Hooks"
msgstr ""
-msgid "Group ID"
-msgstr "ID do grupo"
-
msgid "Group Owner must have signed in with SAML before enabling Group Managed Accounts"
msgstr ""
@@ -16865,9 +17113,6 @@ msgstr "Avatar do grupo"
msgid "Group by"
msgstr "Agrupar por"
-msgid "Group description"
-msgstr "Descrição do grupo"
-
msgid "Group description (optional)"
msgstr "Descrição do grupo (opcional)"
@@ -16982,8 +17227,8 @@ msgstr "Grupo: %{group_name}"
msgid "Group: %{name}"
msgstr "Grupo: %{name}"
-msgid "GroupActivityMetrics|Issues opened"
-msgstr "Issues abertas"
+msgid "GroupActivityMetrics|Issues created"
+msgstr ""
msgid "GroupActivityMetrics|Last 90 days"
msgstr "Últimos 90 dias"
@@ -16991,8 +17236,8 @@ msgstr "Últimos 90 dias"
msgid "GroupActivityMetrics|Members added"
msgstr "Membros adicionados"
-msgid "GroupActivityMetrics|Merge Requests opened"
-msgstr "Solicitações de mesclagem abertas"
+msgid "GroupActivityMetrics|Merge Requests created"
+msgstr ""
msgid "GroupActivityMetrics|Recent activity"
msgstr "Atividade recente"
@@ -17253,10 +17498,10 @@ msgid "GroupSelect|Select a group"
msgstr "Selecionar grupos"
msgid "GroupSettings|Allow project and group access token creation"
-msgstr ""
+msgstr "Permitir a criação de token de acesso ao projeto e grupo"
msgid "GroupSettings|Allows creating organizations and contacts and associating them with issues."
-msgstr ""
+msgstr "Permitir criar organizações e contatos e associá-los a issues."
msgid "GroupSettings|Applied to all subgroups unless overridden by a group owner. Groups already added to the project lose access."
msgstr "Aplicado a todos os subgrupos, a menos que seja substituído por um proprietário do grupo. Os grupos já adicionados ao projeto perdem o acesso."
@@ -17282,6 +17527,9 @@ msgstr "Alterar URL do grupo"
msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr "Alterar a URL do grupo pode ter efeitos colaterais indesejados."
+msgid "GroupSettings|Choose a group path that does not start with a dash or end with a period. It can also contain alphanumeric characters and underscores."
+msgstr ""
+
msgid "GroupSettings|Compliance frameworks"
msgstr "Frameworks de conformidade"
@@ -17315,8 +17563,8 @@ msgstr "Exportar grupo"
msgid "GroupSettings|If not specified at the group or instance level, the default is %{default_initial_branch_name}. Does not affect existing repositories."
msgstr "Se não for especificado no nível de grupo ou instância, o padrão é %{default_initial_branch_name}. Não afeta os repositórios existentes."
-msgid "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 "Se a visibilidade do grupo pai for menor que a visibilidade atual do grupo, os níveis de visibilidade para subgrupos e projetos serão mudados para corresponder à visibilidade do novo grupo pai."
+msgid "GroupSettings|If the parent group's visibility is lower than the group's current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility."
+msgstr ""
msgid "GroupSettings|New runners registration token has been generated!"
msgstr "Um novo token de registro de executores foi gerado!"
@@ -17394,7 +17642,7 @@ msgid "GroupSettings|Transfer group"
msgstr "Transferir grupo"
msgid "GroupSettings|Users can create %{link_start_project}project access tokens%{link_end} and %{link_start_group}group access tokens%{link_end} in this group."
-msgstr ""
+msgstr "Os usuários podem criar %{link_start_project}tokens de acesso de projeto%{link_end} e %%{link_start_group}tokens de acesso de grupo%{link_end} neste grupo."
msgid "GroupSettings|What are badges?"
msgstr "O que são selos?"
@@ -17432,8 +17680,11 @@ msgstr "Grupos (%{count})"
msgid "Groups and projects"
msgstr "Grupos e projetos"
-msgid "Groups and subgroups"
-msgstr "Grupos e subgrupos"
+msgid "Groups are a great way to organize projects and people."
+msgstr ""
+
+msgid "Groups are the best way to manage projects and members."
+msgstr ""
msgid "Groups to synchronize"
msgstr "Grupos para sincronizar"
@@ -17529,7 +17780,7 @@ msgid "GroupsNew|Provide credentials for another instance of GitLab to import yo
msgstr "Forneça as credenciais para outra instância do GitLab para importar seus grupos diretamente."
msgid "GroupsNew|This feature is deprecated and replaced by %{docs_link_start}group migration%{docs_link_end}."
-msgstr ""
+msgstr "Este recurso foi descontinuado e substituído por %{docs_link_start}migração de grupo%{docs_link_end}."
msgid "GroupsNew|To import a group, navigate to the group settings for the GitLab source instance, %{link_start}generate an export file%{link_end}, and upload it here."
msgstr ""
@@ -17543,14 +17794,17 @@ msgstr ""
msgid "GroupsTree|Are you sure you want to leave the \"%{fullName}\" group?"
msgstr "Tem certeza que deseja sair do grupo \"%{fullName}\"?"
-msgid "GroupsTree|Edit group"
-msgstr "Editar grupo"
+msgid "GroupsTree|Delete"
+msgstr ""
+
+msgid "GroupsTree|Edit"
+msgstr ""
msgid "GroupsTree|Failed to leave the group. Please make sure you are not the only owner."
msgstr "Falha ao deixar o grupo. Por favor, verifique se você é o único dono."
-msgid "GroupsTree|Leave this group"
-msgstr "Deixar o grupo"
+msgid "GroupsTree|Leave group"
+msgstr ""
msgid "GroupsTree|Loading groups"
msgstr "Carregando grupos"
@@ -17561,9 +17815,57 @@ msgstr "Nenhum grupo corresponde à sua pesquisa"
msgid "GroupsTree|No groups or projects matched your search"
msgstr "Desculpe, nenhum grupo ou projeto correspondem à sua pesquisa"
+msgid "GroupsTree|Options"
+msgstr ""
+
msgid "GroupsTree|Search by name"
msgstr "Procura por nome"
+msgid "Groups|Avatar will be removed. Are you sure?"
+msgstr ""
+
+msgid "Groups|Changing group URL can have unintended side effects."
+msgstr ""
+
+msgid "Groups|Checking group URL availability..."
+msgstr ""
+
+msgid "Groups|Enter a descriptive name for your group."
+msgstr ""
+
+msgid "Groups|Group ID"
+msgstr ""
+
+msgid "Groups|Group URL"
+msgstr ""
+
+msgid "Groups|Group avatar"
+msgstr ""
+
+msgid "Groups|Group description (optional)"
+msgstr ""
+
+msgid "Groups|Group name"
+msgstr ""
+
+msgid "Groups|Group path is available."
+msgstr ""
+
+msgid "Groups|Group path is unavailable. Path has been replaced with a suggested available path."
+msgstr ""
+
+msgid "Groups|Learn more"
+msgstr ""
+
+msgid "Groups|Must start with letter, digit, emoji, or underscore. Can also contain periods, dashes, spaces, and parentheses."
+msgstr ""
+
+msgid "Groups|Remove avatar"
+msgstr ""
+
+msgid "Groups|Save changes"
+msgstr ""
+
msgid "Guideline"
msgstr "Diretriz"
@@ -17573,6 +17875,9 @@ msgstr ""
msgid "HAR file path or URL"
msgstr "Caminho do arquivo HAR ou URL"
+msgid "HTTP Archive (HAR)"
+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 ""
@@ -17758,7 +18063,7 @@ msgid "Hide values"
msgstr "Ocultar valores"
msgid "Hierarchy|Current structure"
-msgstr ""
+msgstr "Estrutura atual"
msgid "Hierarchy|Deliver value more efficiently by breaking down necessary work into a hierarchical structure. This structure helps teams understand scope, priorities, and how work cascades up toward larger goals."
msgstr ""
@@ -17973,6 +18278,9 @@ msgstr ""
msgid "INFO: Your SSH key is expiring soon. Please generate a new key."
msgstr ""
+msgid "IP"
+msgstr ""
+
msgid "IP Address"
msgstr "Endereço IP"
@@ -18004,9 +18312,12 @@ msgid "IdentityVerification|Before you create your group, we need you to verify
msgstr ""
msgid "IdentityVerification|Create a project"
-msgstr ""
+msgstr "Criar um projeto"
msgid "IdentityVerification|Verify your identity"
+msgstr "Verificar sua identidade"
+
+msgid "IdentityVerification|You can always verify your account at a later time to create a group."
msgstr ""
msgid "If any indexed field exceeds this limit, it is truncated to this number of characters. The rest of the content is neither indexed nor searchable. This does not apply to repository and wiki indexing. For unlimited characters, set this to 0."
@@ -18066,6 +18377,9 @@ msgstr "Se estiver usando o GitHub, você verá os status do pipeline no GitHub
msgid "If you add %{codeStart}needs%{codeEnd} to jobs in your pipeline you'll be able to view the %{codeStart}needs%{codeEnd} relationships between jobs in this tab as a %{linkStart}Directed Acyclic Graph (DAG)%{linkEnd}."
msgstr ""
+msgid "If you are added to a project, it will be displayed here."
+msgstr ""
+
msgid "If you did not initiate these sign-in attempts, please reach out to your administrator or enable two-factor authentication (2FA) on your account."
msgstr ""
@@ -18372,12 +18686,24 @@ msgstr ""
msgid "InProductMarketing|3 ways to dive into GitLab CI/CD"
msgstr ""
+msgid "InProductMarketing|A single application eliminates complex integrations, data chokepoints, and toolchain maintenance, resulting in greater productivity and lower cost."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features, build more efficiently, strengthen security and compliance."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features."
+msgstr ""
+
msgid "InProductMarketing|Actually, GitLab makes the team work (better)"
msgstr ""
msgid "InProductMarketing|And finally %{deploy_link} a Python application."
msgstr ""
+msgid "InProductMarketing|And many more..."
+msgstr ""
+
msgid "InProductMarketing|Are your runners ready?"
msgstr ""
@@ -18396,15 +18722,33 @@ msgstr ""
msgid "InProductMarketing|Blog"
msgstr "Blog"
+msgid "InProductMarketing|Break down silos to coordinate seamlessly across development, operations, and security with a consistent experience across the development lifecycle."
+msgstr ""
+
+msgid "InProductMarketing|Burn up/down charts"
+msgstr ""
+
msgid "InProductMarketing|By enabling code owners and required merge approvals the right person will review the right MR. This is a win-win: cleaner code and a more efficient review process."
msgstr ""
msgid "InProductMarketing|Click on the number below that corresponds with your answer — 1 being very difficult, 5 being very easy."
msgstr ""
+msgid "InProductMarketing|Code owners"
+msgstr ""
+
msgid "InProductMarketing|Code owners and required merge approvals are part of the paid tiers of GitLab. You can start a free 30-day trial of GitLab Ultimate and enable these features in less than 5 minutes with no credit card required."
msgstr ""
+msgid "InProductMarketing|Code review analytics"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration across stages in GitLab"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration made easy"
+msgstr ""
+
msgid "InProductMarketing|Create a custom CI runner with just a few clicks"
msgstr ""
@@ -18414,12 +18758,21 @@ msgstr ""
msgid "InProductMarketing|Create a project in GitLab in 5 minutes"
msgstr ""
+msgid "InProductMarketing|Create well-defined workflows by using scoped labels on issues, merge requests, and epics. Labels with the same scope cannot be used together, which prevents conflicts."
+msgstr ""
+
msgid "InProductMarketing|Create your first project!"
msgstr ""
+msgid "InProductMarketing|Define who owns specific files or directories, so the right reviewers are suggested when a merge request introduces changes to those files."
+msgstr ""
+
msgid "InProductMarketing|Deliver Better Products Faster"
msgstr ""
+msgid "InProductMarketing|Dependency scanning"
+msgstr ""
+
msgid "InProductMarketing|Did you know teams that use GitLab are far more efficient?"
msgstr ""
@@ -18429,15 +18782,27 @@ msgstr "Difícil"
msgid "InProductMarketing|Dig in and create a project and a repo"
msgstr ""
+msgid "InProductMarketing|Discover Premium & Ultimate"
+msgstr ""
+
+msgid "InProductMarketing|Discover Premium & Ultimate."
+msgstr ""
+
msgid "InProductMarketing|Do you have a minute?"
msgstr "Você tem um minuto?"
msgid "InProductMarketing|Do you have a teammate who would be perfect for this task?"
msgstr ""
+msgid "InProductMarketing|Dynamic application security testing"
+msgstr ""
+
msgid "InProductMarketing|Easy"
msgstr "Fácil"
+msgid "InProductMarketing|Epics"
+msgstr ""
+
msgid "InProductMarketing|Expand your DevOps journey with a free GitLab trial"
msgstr ""
@@ -18459,9 +18824,15 @@ msgstr ""
msgid "InProductMarketing|Feel the need for speed?"
msgstr ""
+msgid "InProductMarketing|Find and fix bottlenecks in your code review process by understanding how long open merge requests have been in review."
+msgstr ""
+
msgid "InProductMarketing|Find out how your teams are really doing"
msgstr ""
+msgid "InProductMarketing|Find out if your external libraries are safe. Run dependency scanning jobs that check for known vulnerabilities in your external libraries."
+msgstr ""
+
msgid "InProductMarketing|Follow our steps"
msgstr "Siga nossos passos"
@@ -18498,6 +18869,9 @@ msgstr ""
msgid "InProductMarketing|GitLab is better with teammates to help out!"
msgstr ""
+msgid "InProductMarketing|GitLab is infrastructure agnostic (supporting GCP, AWS, Azure, OpenShift, VMWare, On Prem, Bare Metal, and more), offering a consistent workflow experience – irrespective of the environment."
+msgstr ""
+
msgid "InProductMarketing|GitLab provides static application security testing (SAST), dynamic application security testing (DAST), container scanning, and dependency scanning to help you deliver secure applications along with license compliance."
msgstr ""
@@ -18588,21 +18962,36 @@ msgstr ""
msgid "InProductMarketing|It's also possible to simply %{external_repo_link} in order to take advantage of GitLab's CI/CD."
msgstr ""
+msgid "InProductMarketing|Keep your code quality high by defining who should approve merge requests and how many approvals are required."
+msgstr ""
+
msgid "InProductMarketing|Launch GitLab CI/CD in 20 minutes or less"
msgstr ""
+msgid "InProductMarketing|Lower cost of development"
+msgstr ""
+
+msgid "InProductMarketing|Make it easier to collaborate on high-level ideas by grouping related issues in an epic."
+msgstr ""
+
msgid "InProductMarketing|Making the switch? It's easier than you think to import your projects into GitLab. Move %{github_link}, or import something %{bitbucket_link}."
msgstr ""
msgid "InProductMarketing|Master the art of importing!"
msgstr ""
+msgid "InProductMarketing|Merge request approval rule"
+msgstr ""
+
msgid "InProductMarketing|Move on to easily creating a Pages website %{ci_template_link}"
msgstr ""
msgid "InProductMarketing|Multiple owners, confusing workstreams? We've got you covered"
msgstr ""
+msgid "InProductMarketing|Multiple required approvers"
+msgstr ""
+
msgid "InProductMarketing|Need an alternative to importing?"
msgstr ""
@@ -18615,18 +19004,33 @@ msgstr ""
msgid "InProductMarketing|Our tool brings all the things together"
msgstr ""
+msgid "InProductMarketing|Protect your web application by using DAST to examine for vulnerabilities in deployed environments."
+msgstr ""
+
msgid "InProductMarketing|Rapid development, simplified"
msgstr ""
msgid "InProductMarketing|Reduce Security & Compliance Risk"
msgstr ""
+msgid "InProductMarketing|Require multiple approvers on a merge request, so you know it's in good shape before it's merged."
+msgstr ""
+
+msgid "InProductMarketing|Roadmaps"
+msgstr ""
+
+msgid "InProductMarketing|Scoped labels"
+msgstr ""
+
msgid "InProductMarketing|Security that's integrated into your development lifecycle"
msgstr ""
msgid "InProductMarketing|Sometimes you're not ready to make a full transition to a new tool. If you're not ready to fully commit, %{mirroring_link} gives you a safe way to try out GitLab in parallel with your current tool."
msgstr ""
+msgid "InProductMarketing|Speed. Efficiency. Trust."
+msgstr ""
+
msgid "InProductMarketing|Spin up an autoscaling runner in GitLab"
msgstr ""
@@ -18636,6 +19040,9 @@ msgstr ""
msgid "InProductMarketing|Start a Self-Managed trial"
msgstr ""
+msgid "InProductMarketing|Start a free trial"
+msgstr ""
+
msgid "InProductMarketing|Start a free trial of GitLab Ultimate – no credit card required"
msgstr ""
@@ -18702,6 +19109,9 @@ msgstr ""
msgid "InProductMarketing|To understand and get the most out of GitLab, start at the beginning and %{project_link}. In GitLab, repositories are part of a project, so after you've created your project you can go ahead and %{repo_link}."
msgstr ""
+msgid "InProductMarketing|Track completed issues in a chart, so you can see how a milestone is progressing at a glance."
+msgstr ""
+
msgid "InProductMarketing|Try GitLab Ultimate for free"
msgstr ""
@@ -18738,6 +19148,9 @@ msgstr "Muito difícil"
msgid "InProductMarketing|Very easy"
msgstr "Muito fácil"
+msgid "InProductMarketing|Visualize your epics and milestones in a timeline."
+msgstr ""
+
msgid "InProductMarketing|Want to host GitLab on your servers?"
msgstr ""
@@ -18759,6 +19172,9 @@ msgstr ""
msgid "InProductMarketing|YouTube"
msgstr "YouTube"
+msgid "InProductMarketing|Your software, deployed your way"
+msgstr ""
+
msgid "InProductMarketing|Your teams can be more efficient"
msgstr ""
@@ -18817,7 +19233,7 @@ msgid "Incident Management Limits"
msgstr ""
msgid "Incident details"
-msgstr ""
+msgstr "Detalhes do incidente"
msgid "Incident template (optional)."
msgstr ""
@@ -18879,9 +19295,18 @@ msgstr ""
msgid "IncidentManagement|No incidents to display."
msgstr ""
+msgid "IncidentManagement|None"
+msgstr ""
+
msgid "IncidentManagement|Open"
msgstr ""
+msgid "IncidentManagement|Page your team with escalation policies"
+msgstr ""
+
+msgid "IncidentManagement|Paged"
+msgstr ""
+
msgid "IncidentManagement|Published"
msgstr "Publicado"
@@ -18891,6 +19316,9 @@ msgstr ""
msgid "IncidentManagement|Severity"
msgstr "Severidade"
+msgid "IncidentManagement|Status"
+msgstr ""
+
msgid "IncidentManagement|There are no closed incidents"
msgstr ""
@@ -18909,6 +19337,9 @@ msgstr "Desconhecido"
msgid "IncidentManagement|Unpublished"
msgstr "Não publicado"
+msgid "IncidentManagement|Use escalation policies to automatically page your team when incidents are created."
+msgstr ""
+
msgid "IncidentSettings|Activate \"time to SLA\" countdown timer"
msgstr ""
@@ -18954,8 +19385,11 @@ msgstr "minutos"
msgid "Incidents"
msgstr "Incidentes"
-msgid "Incidents|Add a URL"
-msgstr "Adicionar uma URL"
+msgid "Incidents|Add image details"
+msgstr ""
+
+msgid "Incidents|Add text or a link to display with your image. If you don't add either, the file name displays instead."
+msgstr ""
msgid "Incidents|Drop or %{linkStart}upload%{linkEnd} a metric screenshot to attach it to the incident"
msgstr ""
@@ -18969,10 +19403,10 @@ msgstr ""
msgid "Incidents|There was an issue loading metric images."
msgstr ""
-msgid "Incidents|There was an issue uploading your image."
+msgid "Incidents|There was an issue updating your image."
msgstr ""
-msgid "Incidents|You can optionally add a URL to link users to the original graph."
+msgid "Incidents|There was an issue uploading your image."
msgstr ""
msgid "Incident|Alert details"
@@ -18981,9 +19415,18 @@ msgstr "Detalhes do alerta"
msgid "Incident|Are you sure you wish to delete this image?"
msgstr ""
+msgid "Incident|Delete image"
+msgstr ""
+
msgid "Incident|Deleting %{filename}"
msgstr ""
+msgid "Incident|Edit image text or link"
+msgstr ""
+
+msgid "Incident|Editing %{filename}"
+msgstr ""
+
msgid "Incident|Metrics"
msgstr "Métricas"
@@ -19253,12 +19696,18 @@ msgstr "Ocorreu um erro ao carregar projetos usando configurações personalizad
msgid "Integrations|Branches for which notifications are to be sent"
msgstr "Ramificações para as quais as notificações devem ser enviadas"
+msgid "Integrations|Clear if using a self-signed certificate."
+msgstr ""
+
msgid "Integrations|Comment detail:"
msgstr "Detalhe do comentário:"
msgid "Integrations|Comment settings:"
msgstr "Configurações de comentário:"
+msgid "Integrations|Connection details"
+msgstr ""
+
msgid "Integrations|Connection failed. Please check your settings."
msgstr ""
@@ -19281,7 +19730,10 @@ msgid "Integrations|Edit project alias"
msgstr "Editar o alias do projeto"
msgid "Integrations|Enable GitLab.com slash commands in a Slack workspace."
-msgstr "Ativae os comandos de barra do GitLab.com em um espaço de trabalho do Slack."
+msgstr "Ative os comandos de barra do GitLab.com em um espaço de trabalho do Slack."
+
+msgid "Integrations|Enable SSL verification"
+msgstr ""
msgid "Integrations|Enable comments"
msgstr "Ativar comentários"
@@ -19323,7 +19775,7 @@ msgid "Integrations|Keep your PHP dependencies updated on Packagist."
msgstr "Mantenha suas dependências de PHP atualizadas no Packagist."
msgid "Integrations|Known limitations"
-msgstr ""
+msgstr "Limitações conhecidas"
msgid "Integrations|Link namespaces"
msgstr ""
@@ -19361,6 +19813,9 @@ msgstr ""
msgid "Integrations|Return to GitLab for Jira"
msgstr "Voltar ao GitLab para Jira"
+msgid "Integrations|SSL verification"
+msgstr ""
+
msgid "Integrations|Save settings?"
msgstr "Salvar configurações?"
@@ -19380,7 +19835,7 @@ msgid "Integrations|Send notifications about project events to a Unify Circuit c
msgstr ""
msgid "Integrations|Sign in to GitLab"
-msgstr ""
+msgstr "Entrar no GitLab"
msgid "Integrations|Sign in to add namespaces"
msgstr "Entre para adicionar espaço de nome"
@@ -19406,9 +19861,6 @@ msgstr "Usar configurações personalizadas"
msgid "Integrations|Use default settings"
msgstr ""
-msgid "Integrations|When you mention a Jira issue in a commit or merge request, GitLab creates a remote link and comment (if enabled)."
-msgstr "Quando você menciona uma issue do Jira em uma solicitação de commit ou de mesclagem, o GitLab cria um link remoto e um comentário (se ativado)."
-
msgid "Integrations|You can now close this window and return to the GitLab for Jira application."
msgstr ""
@@ -19433,9 +19885,6 @@ msgstr ""
msgid "Integrations|can't exceed %{recipients_limit}"
msgstr ""
-msgid "Interactive developer security education."
-msgstr ""
-
msgid "Interactive mode"
msgstr "Modo interativo"
@@ -19809,7 +20258,7 @@ msgid "IrkerService|Recipients"
msgstr "Destinatários"
msgid "IrkerService|Send update messages to an irker server."
-msgstr ""
+msgstr "Envie mensagens de atualização para um servidor irker."
msgid "IrkerService|Send update messages to an irker server. Before you can use this, you need to set up the irker daemon. %{docs_link}"
msgstr ""
@@ -19827,10 +20276,10 @@ msgid "IrkerService|irker (IRC gateway)"
msgstr ""
msgid "IrkerService|irker daemon hostname (defaults to localhost)."
-msgstr ""
+msgstr "Nome do host do irker daemon (O padrão é localhost)"
msgid "IrkerService|irker daemon port (defaults to 6659)."
-msgstr ""
+msgstr "Porta do host do irker daemon (O padrão é 6659)"
msgid "Is blocked by"
msgstr "Está bloqueado por"
@@ -19925,6 +20374,9 @@ msgstr "Idade"
msgid "IssueAnalytics|Assignees"
msgstr "Responsáveis"
+msgid "IssueAnalytics|Created by"
+msgstr ""
+
msgid "IssueAnalytics|Due date"
msgstr "Validade"
@@ -19937,9 +20389,6 @@ msgstr "Issue"
msgid "IssueAnalytics|Milestone"
msgstr "Marcos"
-msgid "IssueAnalytics|Opened by"
-msgstr "Aberto por"
-
msgid "IssueAnalytics|Status"
msgstr "Status"
@@ -20063,11 +20512,11 @@ msgstr "Depois que você começa a criar issues para seus projetos, podemos come
msgid "IssuesAnalytics|Avg/Month:"
msgstr ""
-msgid "IssuesAnalytics|Issues opened"
-msgstr "Issues abertas"
+msgid "IssuesAnalytics|Issues created"
+msgstr ""
-msgid "IssuesAnalytics|Issues opened per month"
-msgstr "Issues abertas por mês"
+msgid "IssuesAnalytics|Issues created per month"
+msgstr ""
msgid "IssuesAnalytics|Last 12 months"
msgstr "Últimos 12 meses"
@@ -20093,6 +20542,9 @@ msgstr ""
msgid "It looks like you have some draft commits in this branch."
msgstr ""
+msgid "It looks like you're attempting to activate your subscription. Use %{a_start}the Subscription page%{a_end} instead."
+msgstr ""
+
msgid "It may be several days before you see feature usage data."
msgstr ""
@@ -20321,6 +20773,9 @@ msgstr ""
msgid "JiraConnect|You can now close this window and return to Jira."
msgstr ""
+msgid "JiraConnect|You don't have permission to create branches for this project. Select a different project or contact the project owner for access. %{linkStart}Learn more.%{linkEnd}"
+msgstr ""
+
msgid "JiraRequest|A connection error occurred while connecting to Jira. Try your request again."
msgstr ""
@@ -20369,15 +20824,15 @@ msgstr "URL base da instância do Jira."
msgid "JiraService|Define the type of Jira issue to create from a vulnerability."
msgstr ""
-msgid "JiraService|Displaying Jira issues while leaving the GitLab issue functionality enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
+msgid "JiraService|Displaying Jira issues while leaving GitLab issues also enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
+msgstr ""
+
+msgid "JiraService|Enable Jira issue creation from vulnerabilities"
msgstr ""
msgid "JiraService|Enable Jira issues"
msgstr "Ativar issues do Jira"
-msgid "JiraService|Enable Jira issues creation from vulnerabilities"
-msgstr ""
-
msgid "JiraService|Enable Jira transitions"
msgstr "Ativar transições do Jira"
@@ -20492,17 +20947,20 @@ msgstr "Usando Jira para rastreamento de issue?"
msgid "JiraService|View Jira issues in GitLab"
msgstr "Ver issues do Jira no GitLab"
-msgid "JiraService|Warning: All GitLab users that have access to this GitLab project are able to view all issues from the Jira project specified below."
-msgstr "Aviso: Todos os usuários do GitLab que têm acesso a este projeto no GitLab podem visualizar todos as issues do projeto do Jira especificados abaixo."
+msgid "JiraService|Warning: All GitLab users with access to this GitLab project can view all issues from the Jira project you select."
+msgstr ""
msgid "JiraService|Web URL"
msgstr "URL da Web"
-msgid "JiraService|Work on Jira issues without leaving GitLab. Adds a Jira menu to access your list of Jira issues and view any issue as read-only."
+msgid "JiraService|When a Jira issue is mentioned in a commit or merge request, a remote link and comment (if enabled) will be created."
+msgstr ""
+
+msgid "JiraService|Work on Jira issues without leaving GitLab. Add a Jira menu to access a read-only list of your Jira issues."
msgstr ""
-msgid "JiraService|You need to configure Jira before enabling this integration. For more details, read the %{jira_doc_link_start}Jira integration documentation%{link_end}."
-msgstr "Você precisa configurar o Jira antes de ativar esta integração. Para obter mais detalhes, leia a %{jira_doc_link_start}documentação de integração do Jira%{link_end}."
+msgid "JiraService|You must configure Jira before enabling this integration. %{jira_doc_link_start}Learn more.%{link_end}"
+msgstr ""
msgid "Job"
msgstr "Tarefa"
@@ -20513,9 +20971,6 @@ msgstr ""
msgid "Job Failed #%{build_id}"
msgstr "Tarefa falhou nº %{build_id}"
-msgid "Job ID"
-msgstr "ID da tarefa"
-
msgid "Job artifact"
msgstr ""
@@ -20582,9 +21037,27 @@ msgstr ""
msgid "Jobs|You're about to retry a job that failed because it attempted to deploy code that is older than the latest deployment. Retrying this job could result in overwriting the environment with the older source code."
msgstr ""
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source} into %{target}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{ref}"
+msgstr ""
+
+msgid "Job|Are you sure you want to erase this job log and artifacts?"
+msgstr ""
+
msgid "Job|Browse"
msgstr "Navegar"
+msgid "Job|Cancel"
+msgstr ""
+
msgid "Job|Complete Raw"
msgstr "Raw completo"
@@ -20594,6 +21067,9 @@ msgstr "Baixar"
msgid "Job|Erase job log and artifacts"
msgstr ""
+msgid "Job|Finished at"
+msgstr ""
+
msgid "Job|Job artifacts"
msgstr "Artefatos da tarefa"
@@ -20606,8 +21082,8 @@ msgstr "Ttarefa foi apagada por %{userLink}"
msgid "Job|Keep"
msgstr "Manter"
-msgid "Job|Pipeline"
-msgstr "Pipeline"
+msgid "Job|Retry"
+msgstr ""
msgid "Job|Scroll to bottom"
msgstr "Rolar para baixo"
@@ -20618,6 +21094,9 @@ msgstr "Rolar para o topo"
msgid "Job|Show complete raw"
msgstr "Mostrar raw completo"
+msgid "Job|Status"
+msgstr ""
+
msgid "Job|The artifacts were removed"
msgstr "Os artefatos foram removidos"
@@ -20645,21 +21124,12 @@ msgstr "permitido falhar"
msgid "Job|delayed"
msgstr "atrasado"
-msgid "Job|for"
-msgstr "para"
-
-msgid "Job|into"
-msgstr "para"
-
msgid "Job|manual"
msgstr "manual"
msgid "Job|triggered"
msgstr ""
-msgid "Job|with"
-msgstr "com"
-
msgid "Join Zoom meeting"
msgstr "Participe da reunião com Zoom"
@@ -20762,9 +21232,6 @@ msgstr "Chaves"
msgid "Ki"
msgstr ""
-msgid "Kontra"
-msgstr ""
-
msgid "Kroki"
msgstr ""
@@ -21088,6 +21555,9 @@ msgstr "Saiba mais sobre o %{username}"
msgid "Learn more about Auto DevOps"
msgstr "Saiba mais sobre o Auto DevOps"
+msgid "Learn more about GitLab"
+msgstr ""
+
msgid "Learn more about Needs relationships"
msgstr ""
@@ -21275,7 +21745,7 @@ msgid "License file"
msgstr "Arquivo de licença"
msgid "License key"
-msgstr ""
+msgstr "Chave de licença"
msgid "License overview"
msgstr ""
@@ -21415,9 +21885,18 @@ msgstr ""
msgid "Licenses|Displays licenses detected in the project, based on the %{linkStart}latest successful%{linkEnd} scan"
msgstr ""
+msgid "Licenses|Drag your license file here or %{linkStart}click to upload%{linkEnd}."
+msgstr ""
+
+msgid "Licenses|Drop your license file to start the upload."
+msgstr ""
+
msgid "Licenses|Error fetching the license list. Please check your network connection and try again."
msgstr ""
+msgid "Licenses|Error: You are trying to upload something other than a file"
+msgstr ""
+
msgid "Licenses|License Compliance"
msgstr "Conformidade de licença"
@@ -21436,6 +21915,9 @@ msgstr ""
msgid "Licenses|Specified policies in this project"
msgstr ""
+msgid "Licenses|The file could not be uploaded."
+msgstr ""
+
msgid "Licenses|The license list details information about the licenses used within your project."
msgstr "A lista de licenças detalha informações sobre as licenças usadas em seu projeto."
@@ -21469,11 +21951,6 @@ msgstr ""
msgid "Limit the size of Sidekiq jobs stored in Redis."
msgstr ""
-msgid "Limited to showing %d event at most"
-msgid_plural "Limited to showing %d events at most"
-msgstr[0] "Limitado a mostrar %d evento, no máximo"
-msgstr[1] "Limitado a mostrar %d eventos, no máximo"
-
msgid "Limiting mode"
msgstr "Modo de limitação"
@@ -21483,6 +21960,9 @@ msgstr "Alterações de linha"
msgid "Link"
msgstr ""
+msgid "Link (optional)"
+msgstr ""
+
msgid "Link Prometheus monitoring to GitLab."
msgstr ""
@@ -21519,6 +21999,9 @@ msgstr "Link para a sua instância do Grafana."
msgid "Linked emails (%{email_count})"
msgstr "E-mails vinculados (%{email_count})"
+msgid "Linked epics"
+msgstr ""
+
msgid "Linked issues"
msgstr "Issues vinculadas"
@@ -21546,6 +22029,15 @@ msgstr "Listar repositórios disponíveis"
msgid "List of all merge commits"
msgstr "Lista de todos commits de mesclagem"
+msgid "List of environments for this project"
+msgstr ""
+
+msgid "List of suitable GCP locations"
+msgstr ""
+
+msgid "List of users allowed to exceed the rate limit."
+msgstr ""
+
msgid "List options"
msgstr "Opções de lista"
@@ -21616,7 +22108,7 @@ msgid "Lock %{issuableDisplayName}"
msgstr "Bloquear %{issuableDisplayName}"
msgid "Lock File?"
-msgstr ""
+msgstr "Bloquear arquivo?"
msgid "Lock memberships to LDAP synchronization"
msgstr ""
@@ -21655,13 +22147,13 @@ msgid "Locks the discussion."
msgstr "Bloqueia a discussão."
msgid "LoggedOutMarketingHeader|About GitLab"
-msgstr ""
+msgstr "Sobre o GitLab"
msgid "LoggedOutMarketingHeader|Explore GitLab"
-msgstr ""
+msgstr "Explore o GitLab"
msgid "LoggedOutMarketingHeader|Get started"
-msgstr ""
+msgstr "Começar"
msgid "LoggedOutMarketingHeader|GitLab Learn"
msgstr ""
@@ -21676,16 +22168,16 @@ msgid "LoggedOutMarketingHeader|How GitLab compares"
msgstr ""
msgid "LoggedOutMarketingHeader|Install GitLab"
-msgstr ""
+msgstr "Instalar o GitLab"
msgid "LoggedOutMarketingHeader|Pricing"
-msgstr ""
+msgstr "Preço"
msgid "LoggedOutMarketingHeader|Talk to an expert"
msgstr ""
msgid "Login"
-msgstr ""
+msgstr "Entrar"
msgid "Login with smartcard"
msgstr "Entrar com cartão inteligente"
@@ -21765,6 +22257,9 @@ msgstr ""
msgid "Maintenance mode"
msgstr ""
+msgid "Make adjustments to how your GitLab instance is set up."
+msgstr ""
+
msgid "Make and review changes in the browser with the Web IDE"
msgstr "Faça e revise alterações no navegador com o IDE Web"
@@ -21909,6 +22404,12 @@ msgstr "Adicionar texto em itálico (%{modifierKey}I)"
msgid "MarkdownEditor|Add italic text (%{modifier_key}I)"
msgstr "Adicionar texto em itálico (%{modifier_key}I)"
+msgid "MarkdownEditor|Add strikethrough text (%{modifierKey}⇧X)"
+msgstr ""
+
+msgid "MarkdownEditor|Add strikethrough text (%{modifier_key}⇧X)"
+msgstr ""
+
msgid "Marked For Deletion At - %{deletion_time}"
msgstr ""
@@ -22170,6 +22671,9 @@ msgstr "Tamanho máximo de push"
msgid "Maximum push size (MB)"
msgstr "Tamanho máximo de push (MB)"
+msgid "Maximum requests per 10 minutes per user"
+msgstr ""
+
msgid "Maximum requests per minute"
msgstr "Requisições máximas por minuto"
@@ -22260,6 +22764,19 @@ msgstr ""
msgid "Members of a group may only view projects they have permission to access"
msgstr ""
+msgid "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seat in use and will be billed for the overage."
+msgid_plural "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seats in use and will be billed for the overage."
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "MembersOverage|You are about to incur additional charges"
+msgstr ""
+
+msgid "MembersOverage|Your subscription includes %d seat."
+msgid_plural "MembersOverage|Your subscription includes %d seats."
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Membership"
msgstr ""
@@ -22464,9 +22981,6 @@ msgstr "Eventos de solicitação de mesclagem"
msgid "Merge request not merged"
msgstr ""
-msgid "Merge request pipelines 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 merge request pipelines."
-msgstr ""
-
msgid "Merge request reports"
msgstr "Relatórios de solicitação de mesclagem"
@@ -22563,13 +23077,13 @@ msgstr "Ocorreu um erro ao salvar o rascunho do comentário."
msgid "MergeRequests|Create issue to resolve thread"
msgstr ""
-msgid "MergeRequests|Failed to squash. Should be done manually."
-msgstr ""
-
msgid "MergeRequests|Saving the comment failed"
msgstr "Falha ao salvar comentário"
-msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
+msgid "MergeRequests|Squashing failed: Squash the commits locally, resolve any conflicts, then push the branch."
+msgstr ""
+
+msgid "MergeRequests|Squashing not allowed: This project doesn't allow you to squash commits when merging."
msgstr ""
msgid "MergeRequests|Thread stays resolved"
@@ -23410,6 +23924,18 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr "Parar ambiente"
+msgid "MrList|Assigned to %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from assignee %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from reviewer %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Review requested from %{name}, go to their profile."
+msgstr ""
+
msgid "Multi-project"
msgstr ""
@@ -23443,8 +23969,8 @@ msgstr ""
msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "My Awesome Group"
-msgstr "Meu grupo incrível"
+msgid "My awesome group"
+msgstr ""
msgid "My company or team"
msgstr "Minha empresa ou equipe"
@@ -24065,9 +24591,6 @@ msgstr "Nenhum método de autenticação configurado."
msgid "No available branches"
msgstr "Nenhuma ramificação disponível"
-msgid "No available groups to fork the project."
-msgstr "Nenhum grupo disponível para fazer fork do projeto."
-
msgid "No branches found"
msgstr "Nenhuma ramificação encontrada"
@@ -24278,6 +24801,9 @@ msgstr "Nenhum grupo público"
msgid "No ref selected"
msgstr ""
+msgid "No regions configured"
+msgstr ""
+
msgid "No related merge requests found."
msgstr "Nenhuma solicitação de mesclagem relacionada foi encontrada."
@@ -25082,6 +25608,9 @@ msgstr ""
msgid "Only reCAPTCHA v2 is supported:"
msgstr ""
+msgid "Only required if not using role instance credentials."
+msgstr ""
+
msgid "Only use lowercase letters, numbers, and underscores."
msgstr ""
@@ -25106,9 +25635,6 @@ msgstr "Abrir seleção"
msgid "Open a CLI and connect to the cluster you want to install the agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
-msgid "Open epics"
-msgstr ""
-
msgid "Open errors"
msgstr "Abrir erros"
@@ -25148,8 +25674,8 @@ msgstr ""
msgid "Opened issues"
msgstr "Issues abertas"
-msgid "OpenedNDaysAgo|Opened"
-msgstr "Aberto"
+msgid "OpenedNDaysAgo|Created"
+msgstr ""
msgid "Opens in a new window"
msgstr "Abrir em nova janela"
@@ -25193,9 +25719,6 @@ msgstr "Opcional"
msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
-msgid "Optional."
-msgstr "Opcional."
-
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
msgstr "Opcionalmente, você pode %{link_to_customize} como os endereços de e-mail e nomes de usuários do FogBugz são importados para o GitLab."
@@ -25257,7 +25780,7 @@ msgid "OutboundRequests|Local IP addresses and domain names that hooks and servi
msgstr ""
msgid "OutboundRequests|Outbound requests"
-msgstr ""
+msgstr "Requisições de saída"
msgid "OutboundRequests|Requests to these domains and IP addresses are accessible to both system hooks and web hooks even when local requests are not allowed. IP ranges such as 1:0:0:0:0:0:0:0/124 and 127.0.0.0/28 are supported. Domain wildcards are not supported. To separate entries use commas, semicolons, or newlines. The allowlist can hold a maximum of 1000 entries. Domains must be IDNA encoded."
msgstr ""
@@ -25984,6 +26507,9 @@ msgstr ""
msgid "PerformanceBar|Memory"
msgstr "Memória"
+msgid "PerformanceBar|Memory report"
+msgstr ""
+
msgid "PerformanceBar|Redis calls"
msgstr ""
@@ -26017,18 +26543,12 @@ msgstr "objeto"
msgid "PerformanceBar|wall"
msgstr "parede"
-msgid "Performs a rebase but skips triggering a new pipeline"
-msgstr ""
-
msgid "Period in seconds"
msgstr "Período em segundos"
msgid "Permalink"
msgstr "Link permanente"
-msgid "Permanently delete project"
-msgstr "Excluir projeto permanentemente"
-
msgid "Permanently remove group"
msgstr "Remover grupo permanentemente"
@@ -26039,7 +26559,7 @@ msgid "Permissions Help"
msgstr ""
msgid "Permissions and group features"
-msgstr ""
+msgstr "Permissões e funcionalidade de grupo"
msgid "Personal Access Token"
msgstr "Token de acesso pessoal"
@@ -26299,6 +26819,51 @@ msgstr "Pipeline: %{ciStatus}"
msgid "PipelineStatusTooltip|Pipeline: %{ci_status}"
msgstr ""
+msgid "PipelineWizardDefaultCommitMessage|Add %{filename}"
+msgstr ""
+
+msgid "PipelineWizardDefaultCommitMessage|Update %{filename}"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|At least one entry is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This field is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This value is not valid"
+msgstr ""
+
+msgid "PipelineWizardListWidget|add another step"
+msgstr ""
+
+msgid "PipelineWizardListWidget|remove step"
+msgstr ""
+
+msgid "PipelineWizard|Commit"
+msgstr ""
+
+msgid "PipelineWizard|Commit Message"
+msgstr ""
+
+msgid "PipelineWizard|Commit changes to your file"
+msgstr ""
+
+msgid "PipelineWizard|Commit file to Branch"
+msgstr ""
+
+msgid "PipelineWizard|Commit your new file"
+msgstr ""
+
+msgid "PipelineWizard|The file has been committed."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem committing the changes."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem while checking whether your file already exists in the specified branch."
+msgstr ""
+
msgid "Pipelines"
msgstr "Pipelines"
@@ -26318,7 +26883,7 @@ msgid "Pipelines|Are you sure you want to run this pipeline?"
msgstr "Tem certeza de que deseja executar este pipeline?"
msgid "Pipelines|Auto DevOps"
-msgstr ""
+msgstr "Auto DevOps"
msgid "Pipelines|Build with confidence"
msgstr "Construa com confiança"
@@ -26413,8 +26978,8 @@ msgstr "Editor de pipeline"
msgid "Pipelines|Project cache successfully reset."
msgstr "Cache do projeto redefinido com sucesso."
-msgid "Pipelines|Revoke"
-msgstr "Revogar"
+msgid "Pipelines|Revoke trigger"
+msgstr ""
msgid "Pipelines|Something went wrong while cleaning runners cache."
msgstr "Algo deu errado ao limpar o cache dos executores."
@@ -26458,6 +27023,12 @@ msgstr "Essa configuração do GitLab CI é válida."
msgid "Pipelines|This is a child pipeline within the parent pipeline"
msgstr "Este é um pipeline filho dentro do pipeline pai"
+msgid "Pipelines|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipelines|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipelines|This pipeline will run code originating from a forked project merge request. This means that the code can potentially have security considerations like exposing CI variables."
msgstr ""
@@ -26500,11 +27071,8 @@ msgstr "Visualizar"
msgid "Pipelines|Your changes have been successfully committed. Now redirecting to the new merge request page."
msgstr ""
-msgid "Pipelines|detached"
-msgstr ""
-
msgid "Pipelines|error"
-msgstr ""
+msgstr "erro"
msgid "Pipelines|invalid"
msgstr "Inválido"
@@ -26512,10 +27080,13 @@ msgstr "Inválido"
msgid "Pipelines|latest"
msgstr ""
-msgid "Pipelines|stuck"
+msgid "Pipelines|merge request"
msgstr ""
-msgid "Pipelines|train"
+msgid "Pipelines|merge train"
+msgstr ""
+
+msgid "Pipelines|stuck"
msgstr ""
msgid "Pipelines|yaml invalid"
@@ -26647,6 +27218,12 @@ msgstr ""
msgid "Pipeline|This change will not change the overall test coverage if merged."
msgstr ""
+msgid "Pipeline|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipeline|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipeline|Trigger author"
msgstr ""
@@ -26671,6 +27248,12 @@ msgstr "Você está prestes a interromper o pipeline #%{pipelineId}."
msgid "Pipeline|for"
msgstr "para"
+msgid "Pipeline|merge request"
+msgstr ""
+
+msgid "Pipeline|merge train"
+msgstr ""
+
msgid "Pipeline|on"
msgstr "em"
@@ -26809,9 +27392,6 @@ msgstr "Digite um número válido"
msgid "Please enter a valid time interval"
msgstr ""
-msgid "Please enter or upload a valid license."
-msgstr ""
-
msgid "Please enter your current password."
msgstr "Por favor digite sua senha atual."
@@ -26920,9 +27500,6 @@ msgstr ""
msgid "Please type %{phrase_code} to proceed or close this modal to cancel."
msgstr "Por favor, digite %{phrase_code} para continuar ou feche este modal para cancelar."
-msgid "Please type the following to confirm:"
-msgstr "Por favor, digite o seguinte para confirmar"
-
msgid "Please use this form to report to the admin users who create spam issues, comments or behave inappropriately."
msgstr "Por favor, use este formulário para denunciar aos administradores as contas que criam spam em issues, comentários ou se comportam de maneira inapropriada."
@@ -26950,12 +27527,27 @@ msgstr ""
msgid "Policies"
msgstr "Políticas"
+msgid "Policy '%{escalation_policy_name}' does not exist."
+msgstr ""
+
msgid "Policy management project does have any policies in %{policy_path}"
msgstr ""
msgid "Policy project doesn't exist"
msgstr ""
+msgid "PolicyRuleMultiSelect|%{firstLabel} +%{numberOfAdditionalLabels} more"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|All %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select all"
+msgstr ""
+
msgid "Polling interval multiplier"
msgstr ""
@@ -27184,6 +27776,9 @@ msgstr ""
msgid "Private projects can be created in your personal namespace with:"
msgstr "Projetos privados podem ser criados em seu espaço de nome pessoal com:"
+msgid "Problem with %{name} command: %{message}."
+msgstr ""
+
msgid "Proceed"
msgstr "Prosseguir"
@@ -27308,7 +27903,7 @@ msgid "Profiles|Avatar will be removed. Are you sure?"
msgstr "O avatar será removido. Você tem certeza?"
msgid "Profiles|Begins with %{ssh_key_algorithms}."
-msgstr ""
+msgstr "Começa com %{ssh_key_algorithms}."
msgid "Profiles|Bio"
msgstr "Bio"
@@ -27512,7 +28107,7 @@ msgid "Profiles|Remove avatar"
msgstr "Remover avatar"
msgid "Profiles|Select a service to sign in with."
-msgstr ""
+msgstr "Selecionar um serviço para entrar."
msgid "Profiles|Set new profile picture"
msgstr "Definir nova foto de perfil"
@@ -27658,6 +28253,9 @@ msgstr "Linguagens de programação usadas nesse repositório"
msgid "Progress"
msgstr "Progresso"
+msgid "Progress tracking"
+msgstr ""
+
msgid "Project"
msgstr "Projeto"
@@ -27692,7 +28290,7 @@ msgid "Project '%{project_name}' will be deleted on %{date}"
msgstr ""
msgid "Project Access Tokens"
-msgstr ""
+msgstr "Tokens de acesso ao Projeto"
msgid "Project Badges"
msgstr "Selos de projeto"
@@ -27889,6 +28487,9 @@ msgstr ""
msgid "ProjectQualitySummary|Failure"
msgstr ""
+msgid "ProjectQualitySummary|Get insight into the overall percentage of tests in your project that succeed, fail and are skipped."
+msgstr ""
+
msgid "ProjectQualitySummary|Latest pipeline results"
msgstr ""
@@ -27907,6 +28508,12 @@ msgstr ""
msgid "ProjectQualitySummary|See project Code Coverage Statistics"
msgstr ""
+msgid "ProjectQualitySummary|Set up test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|Set up test runs (opens in a new tab)"
+msgstr ""
+
msgid "ProjectQualitySummary|Skipped"
msgstr ""
@@ -28088,7 +28695,7 @@ msgid "ProjectSettings|Choose your merge method, merge options, merge checks, an
msgstr "Escolha seu método de mesclagem, opções de mesclagem, verificações de mesclagem e sugestões de mesclagem."
msgid "ProjectSettings|Choose your merge method, options, checks, and squash options."
-msgstr ""
+msgstr "Escolha seu método de mesclagem, opções, verificações e opções de compactação."
msgid "ProjectSettings|Configure your project resources and monitor their health."
msgstr "Configure os recursos do projeto e monitore a saúde deles."
@@ -28166,7 +28773,7 @@ msgid "ProjectSettings|Highlight the usage of hidden unicode characters. These h
msgstr ""
msgid "ProjectSettings|Housekeeping, export, archive, change path, transfer, and delete."
-msgstr ""
+msgstr "Manutenção, exportação, arquivamento, alteração de caminho, transferência e exclusão."
msgid "ProjectSettings|If merge trains are enabled, merging is only possible if the branch can be rebased without conflicts."
msgstr ""
@@ -28183,14 +28790,20 @@ msgstr "Issues"
msgid "ProjectSettings|LFS objects from this repository are available to forks. %{linkStart}How do I remove them?%{linkEnd}"
msgstr ""
+msgid "ProjectSettings|Learn about commit history."
+msgstr ""
+
+msgid "ProjectSettings|Leave empty to use default template."
+msgstr ""
+
msgid "ProjectSettings|Manage who can see the project in the public access directory."
msgstr "Gerenciar quem pode ver o projeto no diretório de acesso público."
msgid "ProjectSettings|Manages large files such as audio, video, and graphics files."
msgstr "Gerencia arquivos grandes, como arquivos de áudio, vídeo e gráficos."
-msgid "ProjectSettings|Maximum 500 characters."
-msgstr "Máximo de 500 caracteres."
+msgid "ProjectSettings|Maximum %{maxLength} characters."
+msgstr ""
msgid "ProjectSettings|Merge checks"
msgstr "Verificações de mesclagem"
@@ -28289,7 +28902,7 @@ msgid "ProjectSettings|Share code with others outside the project."
msgstr "Compartilhe o código com outras pessoas de fora do projeto."
msgid "ProjectSettings|Show default award emojis"
-msgstr ""
+msgstr "Mostrar emojis de recopensa por padrão"
msgid "ProjectSettings|Show link to create or view a merge request when pushing from the command line"
msgstr "Mostrar link para criar ou ver uma solicitação de mesclagem ao fazer push da linha de comando"
@@ -28330,6 +28943,9 @@ msgstr "A mensagem de commit usada para squash de commits."
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
msgstr "O projeto de destino padrão para solicitações de mesclagem criadas neste projeto de fork."
+msgid "ProjectSettings|The default template will be applied on save."
+msgstr ""
+
msgid "ProjectSettings|These checks must pass before merge requests can be merged."
msgstr "Essas verificações devem passar antes que solicitações de mesclagem possam ter seus merge realizados."
@@ -28367,7 +28983,7 @@ msgid "ProjectSettings|View and edit files in this project."
msgstr "Visualize e edite arquivos neste projeto."
msgid "ProjectSettings|View and edit files in this project. Non-project members have only read access."
-msgstr ""
+msgstr "Veja e edite arquivos neste projeto. Não membros do projeto têm apenas acesso de leitura."
msgid "ProjectSettings|View project analytics."
msgstr "Ver análise de projeto."
@@ -28384,6 +29000,9 @@ msgstr "Avisar sobre caracteres potencialmente indesejados"
msgid "ProjectSettings|What are badges?"
msgstr "O que são selos?"
+msgid "ProjectSettings|What are merge trains?"
+msgstr ""
+
msgid "ProjectSettings|When merge request pipelines are enabled in the CI/CD configuration file, pipelines validate the combined results of the source and target branches. %{link_start}How to configure merge request pipelines?%{link_end}"
msgstr ""
@@ -28501,6 +29120,9 @@ msgstr "Os projetos são classificados com base na vulnerabilidade de maior seve
msgid "Projects are organized into groups"
msgstr "Os projetos são organizados em grupos"
+msgid "Projects are where you store your code, access issues, wiki and other features of GitLab."
+msgstr ""
+
msgid "Projects contributed to"
msgstr ""
@@ -28516,12 +29138,6 @@ msgstr "Projetos podem ser acessos"
msgid "Projects to index"
msgstr "Projetos para indexar"
-msgid "Projects will be permanently deleted after a %{waiting_period}-day waiting period."
-msgstr "Os projetos serão excluídos permanentemente após um %{waiting_period} atraso de dia(s)."
-
-msgid "Projects will be permanently deleted immediately."
-msgstr "Os projetos serão excluídos permanentemente imediatamente"
-
msgid "Projects with critical vulnerabilities"
msgstr ""
@@ -28606,6 +29222,9 @@ msgstr "Importar"
msgid "ProjectsNew|Import project"
msgstr "Importar projeto"
+msgid "ProjectsNew|Include a Getting Started README"
+msgstr ""
+
msgid "ProjectsNew|Initialize repository with a README"
msgstr "Inicializar repositório com um README"
@@ -28621,6 +29240,9 @@ msgstr "Configuração do projeto"
msgid "ProjectsNew|Project description %{tag_start}(optional)%{tag_end}"
msgstr "Descrição do projeto %{tag_start}(opcional)%{tag_end}"
+msgid "ProjectsNew|Recommended if you're new to GitLab"
+msgstr ""
+
msgid "ProjectsNew|Run CI/CD for external repository"
msgstr "Execute CI/CD para um repositório externo"
@@ -28715,7 +29337,7 @@ msgid "PrometheusService|The ID of the IAP-secured resource."
msgstr ""
msgid "PrometheusService|The Prometheus API base URL."
-msgstr ""
+msgstr "A URL da base da API do Prometheus."
msgid "PrometheusService|The contents of the credentials.json file of your service account."
msgstr "O conteúdo do arquivo credentials.json da sua conta de serviço."
@@ -29038,6 +29660,9 @@ msgstr ""
msgid "ProtectedBranch|Unprotect"
msgstr "Desproteger"
+msgid "ProtectedBranch|Unprotect branch"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr "O que são ramificações protegidas?"
@@ -29065,6 +29690,9 @@ msgstr "Proteger um ambiente"
msgid "ProtectedEnvironment|Protected Environment (%{protected_environments_count})"
msgstr "Ambiente Protegido (%{protected_environments_count})"
+msgid "ProtectedEnvironment|Required approvals"
+msgstr ""
+
msgid "ProtectedEnvironment|Select an environment"
msgstr "Selecione um ambiente"
@@ -29086,11 +29714,14 @@ msgstr "Seu ambiente foi protegido."
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr "Seu ambiente foi desprotegido"
+msgid "ProtectedTags|Unprotect tag"
+msgstr ""
+
msgid "ProtectedTags|default"
msgstr ""
-msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
-msgstr "Por padrão, ramificações protegidas restringem quem pode modificar a tag."
+msgid "ProtectedTag|By default, protected tags restrict who can modify the tag."
+msgstr ""
msgid "ProtectedTag|Learn more."
msgstr "Saiba mais."
@@ -29152,6 +29783,9 @@ msgstr "Pipelines públicos"
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Public projects are an easy way to allow everyone to have read-only access."
+msgstr ""
+
msgid "Publish to status page"
msgstr "Publicar na página de status"
@@ -29276,19 +29910,19 @@ msgid "PushoverService|%{user_name} pushed new branch \"%{ref}\"."
msgstr "%{user_name} efetuou push do novo branch \"%{ref}\"."
msgid "PushoverService|Enter your application key."
-msgstr ""
+msgstr "Digite a chave do seu aplicativo"
msgid "PushoverService|Enter your user key."
msgstr "Digite sua chave de usuário."
msgid "PushoverService|Get real-time notifications on your device."
-msgstr ""
+msgstr "Receba notificações em tempo real no seu dispositivo."
msgid "PushoverService|High priority"
msgstr "Alta prioridade"
msgid "PushoverService|Leave blank for all active devices."
-msgstr ""
+msgstr "Deixe em branco para todos os dispositivos ativos."
msgid "PushoverService|Low priority"
msgstr "Baixa prioridade"
@@ -29308,9 +29942,6 @@ msgstr "Contagem total de commits: %{total_commits_count}"
msgid "QualitySummary|Project quality"
msgstr ""
-msgid "Quarters"
-msgstr "Trimestres"
-
msgid "Query"
msgstr "Consulta"
@@ -29395,6 +30026,9 @@ msgstr ""
msgid "Read more about project permissions %{help_link_open}here%{help_link_close}"
msgstr ""
+msgid "Read more about related epics"
+msgstr ""
+
msgid "Read more about related issues"
msgstr "Leia mais sobre issues relacionadas"
@@ -29425,10 +30059,7 @@ msgstr "ramificação de origem de rebase"
msgid "Rebase source branch on the target branch."
msgstr ""
-msgid "Rebase without CI"
-msgstr ""
-
-msgid "Rebases and triggers a pipeline"
+msgid "Rebase without pipeline"
msgstr ""
msgid "Recaptcha verified?"
@@ -29479,9 +30110,6 @@ msgstr "Usado recentemente"
msgid "Reconfigure"
msgstr ""
-msgid "Recovering projects"
-msgstr ""
-
msgid "Recovery Codes"
msgstr "Códigos de recuperação"
@@ -29541,6 +30169,12 @@ msgstr "Regerar o ID de instância pode quebrar integração dependendo do clien
msgid "Regex pattern"
msgstr "Padrão Regex"
+msgid "Region"
+msgstr ""
+
+msgid "Regions"
+msgstr ""
+
msgid "Register"
msgstr "Registrar"
@@ -29771,9 +30405,6 @@ msgstr ""
msgid "Remove all or specific reviewer(s)"
msgstr ""
-msgid "Remove approver"
-msgstr ""
-
msgid "Remove approvers"
msgstr "Remover aprovadores"
@@ -29789,6 +30420,9 @@ msgstr "Remover responsável"
msgid "Remove attention request"
msgstr ""
+msgid "Remove attention request(s)"
+msgstr ""
+
msgid "Remove avatar"
msgstr "Remover imagem"
@@ -29927,6 +30561,9 @@ msgstr "Todas as etiquetas foram removidas."
msgid "Removed an issue from an epic."
msgstr "Uma issue foi removida de um épico."
+msgid "Removed attention from %{users_sentence}."
+msgstr ""
+
msgid "Removed attention request from @%{username}"
msgstr ""
@@ -29978,6 +30615,9 @@ msgstr "Remover todas etiquetas."
msgid "Removes an issue from an epic."
msgstr "Remover uma issue de um épico."
+msgid "Removes attention from %{users_sentence}."
+msgstr ""
+
msgid "Removes parent epic %{epic_ref}."
msgstr "Remove o épico pai %{epic_ref}."
@@ -30089,6 +30729,9 @@ msgstr "Denunciar abuso"
msgid "Report abuse to admin"
msgstr "Denunciar abuso ao administrador"
+msgid "Report is generating and will be sent to your email address."
+msgstr ""
+
msgid "Reported %{timeAgo} by %{reportedBy}"
msgstr "Denunciado em %{timeAgo} por %{reportedBy}"
@@ -30349,7 +30992,7 @@ msgid "Repository size is above the limit."
msgstr "O tamanho do repositório está acima do limite."
msgid "Repository size limit (MB)"
-msgstr ""
+msgstr "Limite de tamanho do repositório (MB)"
msgid "Repository storage"
msgstr "Armazenamento do Repositório"
@@ -30378,6 +31021,15 @@ msgstr ""
msgid "Request attention"
msgstr ""
+msgid "Request attention from %{users_sentence}."
+msgstr ""
+
+msgid "Request attention from assignee or reviewer"
+msgstr ""
+
+msgid "Request attention from assignee(s) or reviewer(s)"
+msgstr ""
+
msgid "Request attention to review"
msgstr ""
@@ -30402,6 +31054,9 @@ msgstr "Requisitado"
msgid "Requested %{time_ago}"
msgstr "Solicitado %{time_ago}"
+msgid "Requested attention from %{users_sentence}."
+msgstr ""
+
msgid "Requested attention from @%{username}"
msgstr ""
@@ -30445,7 +31100,7 @@ msgid "Required only if you are not using role instance credentials."
msgstr ""
msgid "Requirement"
-msgstr ""
+msgstr "Requisito"
msgid "Requirement %{reference} has been added"
msgstr "O requisito%{reference} foi adicionado"
@@ -30616,6 +31271,9 @@ msgstr ""
msgid "Restore project"
msgstr ""
+msgid "Restoring projects"
+msgstr ""
+
msgid "Restoring the group will prevent the group, its subgroups and projects from being removed on this date."
msgstr ""
@@ -30646,6 +31304,9 @@ msgstr ""
msgid "Retry"
msgstr "Tentar novamente"
+msgid "Retry failed jobs"
+msgstr ""
+
msgid "Retry job"
msgstr ""
@@ -30693,9 +31354,6 @@ msgstr "Ver último aplicativo"
msgid "Review changes"
msgstr "Revisar alterações"
-msgid "Review requested from %{name}"
-msgstr "Revisão requisitada por %{name}"
-
msgid "Review requests for you"
msgstr "Requisições de revisão atribuídos a você"
@@ -30858,6 +31516,9 @@ msgid "Runners|Architecture"
msgstr "Arquitetura"
msgid "Runners|Assigned Group"
+msgstr "Grupo Atribuído"
+
+msgid "Runners|Assigned Projects (%{projectCount})"
msgstr ""
msgid "Runners|Associated with one or more projects"
@@ -30879,7 +31540,7 @@ msgid "Runners|Command to register runner"
msgstr "Comando para registrar o executor"
msgid "Runners|Configuration"
-msgstr ""
+msgstr "Configuração"
msgid "Runners|Copy instructions"
msgstr "Copiar instruções"
@@ -30900,7 +31561,7 @@ msgid "Runners|Description"
msgstr "Descrição"
msgid "Runners|Details"
-msgstr ""
+msgstr "Detalhes"
msgid "Runners|Download and install binary"
msgstr "Baixar e instalar o binário"
@@ -30929,6 +31590,9 @@ msgstr "Instalar um executor"
msgid "Runners|Instance"
msgstr "Instância"
+msgid "Runners|Jobs"
+msgstr ""
+
msgid "Runners|Last contact"
msgstr "Último contato"
@@ -30966,13 +31630,13 @@ msgid "Runners|Offline"
msgstr ""
msgid "Runners|Offline runners"
-msgstr ""
+msgstr "Executores offline"
msgid "Runners|Online"
msgstr ""
msgid "Runners|Online runners"
-msgstr ""
+msgstr "Executores online"
msgid "Runners|Paused"
msgstr "Pausado"
@@ -31008,7 +31672,7 @@ msgid "Runners|Registration token copied!"
msgstr ""
msgid "Runners|Reset token"
-msgstr ""
+msgstr "Redefinir token"
msgid "Runners|Revision"
msgstr "Revisão"
@@ -31022,9 +31686,6 @@ msgstr "Executor #%{runner_id}"
msgid "Runners|Runner %{name} was deleted"
msgstr ""
-msgid "Runners|Runner ID"
-msgstr ""
-
msgid "Runners|Runner assigned to project."
msgstr ""
@@ -31172,6 +31833,9 @@ msgstr "específicos"
msgid "Runners|stale"
msgstr ""
+msgid "Runner|This runner has not run any jobs."
+msgstr ""
+
msgid "Running"
msgstr "Executando"
@@ -31286,6 +31950,24 @@ msgstr "Salvando"
msgid "Saving project."
msgstr "Salvando projeto."
+msgid "ScanResultPolicy|%{ifLabelStart}if%{ifLabelEnd} %{scanners} scan in an open merge request targeting the %{branches} branch(es) finds %{vulnerabilitiesAllowed} or more %{severities} vulnerabilities that are %{vulnerabilityStates}"
+msgstr ""
+
+msgid "ScanResultPolicy|%{thenLabelStart}Then%{thenLabelEnd} Require approval from %{approvalsRequired} of the following approvers: %{approvers}"
+msgstr ""
+
+msgid "ScanResultPolicy|add an approver"
+msgstr ""
+
+msgid "ScanResultPolicy|scanners"
+msgstr ""
+
+msgid "ScanResultPolicy|severity levels"
+msgstr ""
+
+msgid "ScanResultPolicy|vulnerability states"
+msgstr ""
+
msgid "Scanner"
msgstr ""
@@ -31418,6 +32100,9 @@ msgstr "Pesquisar por um grupo"
msgid "Search for a user"
msgstr "Pesquisar por um usuário"
+msgid "Search for an emoji"
+msgstr ""
+
msgid "Search for projects, issues, etc."
msgstr "Pesquise por projetos, issues, etc."
@@ -31605,18 +32290,12 @@ msgstr "Secreto"
msgid "Secret Detection"
msgstr "Detecção de secreto"
-msgid "Secret access key"
-msgstr "Chave de acesso secreta"
-
msgid "Secret token"
msgstr "Token secreto"
msgid "Secure token that identifies an external storage request."
msgstr ""
-msgid "SecureCodeWarrior"
-msgstr ""
-
msgid "Security"
msgstr "Segurança"
@@ -31641,9 +32320,6 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "Security training with guide and learning pathways."
-msgstr ""
-
msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
@@ -31746,7 +32422,7 @@ msgstr "Comece imediatamente a análise de risco e remediação com recursos de
msgid "SecurityConfiguration|Manage corpus"
msgstr "Gerenciar corpus"
-msgid "SecurityConfiguration|Manage corpus files used as mutation sources in coverage fuzzing."
+msgid "SecurityConfiguration|Manage corpus files used as seed inputs with coverage-guided fuzzing."
msgstr ""
msgid "SecurityConfiguration|Manage profiles for use by DAST scans."
@@ -31801,7 +32477,7 @@ msgid "SecurityConfiguration|Vulnerability details and statistics in the merge r
msgstr "Detalhes de vulnerabilidade e estatísticas na solicitação de mesclagem"
msgid "SecurityOrchestration| or "
-msgstr ""
+msgstr "ou "
msgid "SecurityOrchestration|%{branches} %{plural}"
msgstr ""
@@ -31812,15 +32488,15 @@ msgstr ""
msgid "SecurityOrchestration|.yaml preview"
msgstr ""
-msgid "SecurityOrchestration|Action"
-msgstr "Ação"
-
msgid "SecurityOrchestration|Actions"
msgstr "Ações"
msgid "SecurityOrchestration|Add rule"
msgstr "Adicionar regra"
+msgid "SecurityOrchestration|After dismissing the alert, the information will never be shown again."
+msgstr ""
+
msgid "SecurityOrchestration|All policies"
msgstr "Todas as políticas"
@@ -31836,8 +32512,8 @@ msgstr ""
msgid "SecurityOrchestration|Description"
msgstr "Descrição"
-msgid "SecurityOrchestration|Disabled"
-msgstr "Desativado"
+msgid "SecurityOrchestration|Don't show the alert anymore"
+msgstr ""
msgid "SecurityOrchestration|Edit policy"
msgstr "Editar política"
@@ -31845,23 +32521,23 @@ msgstr "Editar política"
msgid "SecurityOrchestration|Edit policy project"
msgstr "Editar projeto de política"
+msgid "SecurityOrchestration|Empty policy name"
+msgstr ""
+
msgid "SecurityOrchestration|Enabled"
msgstr "Ativado"
msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
msgstr "Aplicar segurança para este projeto. %{linkStart}Mais informações.%{linkEnd}"
-msgid "SecurityOrchestration|Executes a %{scanType} scan"
-msgstr "Executa uma verificação %{scanType}"
-
msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
msgstr ""
msgid "SecurityOrchestration|Invalid policy type"
msgstr ""
-msgid "SecurityOrchestration|Latest scan"
-msgstr "Última verificação"
+msgid "SecurityOrchestration|Latest scan run against %{agent}"
+msgstr ""
msgid "SecurityOrchestration|Network"
msgstr "Rede"
@@ -31869,15 +32545,27 @@ msgstr "Rede"
msgid "SecurityOrchestration|New policy"
msgstr "Nova política"
+msgid "SecurityOrchestration|No actions defined - policy will not run."
+msgstr ""
+
+msgid "SecurityOrchestration|No description"
+msgstr ""
+
msgid "SecurityOrchestration|No rules defined - policy will not run."
msgstr ""
+msgid "SecurityOrchestration|Not enabled"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
msgid "SecurityOrchestration|Policies"
msgstr "Políticas"
+msgid "SecurityOrchestration|Policy Type"
+msgstr ""
+
msgid "SecurityOrchestration|Policy cannot be enabled for non-existing branches (%{branches})"
msgstr ""
@@ -31902,17 +32590,20 @@ msgstr "Tipo de política"
msgid "SecurityOrchestration|Require %{approvals} %{plural} from %{approvers} if any of the following occur:"
msgstr ""
-msgid "SecurityOrchestration|Rule"
-msgstr "Regra"
-
msgid "SecurityOrchestration|Rules"
msgstr "Regras"
+msgid "SecurityOrchestration|Runs %{actions} and %{lastAction} scans"
+msgstr ""
+
+msgid "SecurityOrchestration|Runs a %{action} scan"
+msgstr ""
+
msgid "SecurityOrchestration|Scan Execution"
msgstr "Execução de verificação"
msgid "SecurityOrchestration|Scan Result"
-msgstr ""
+msgstr "Resultado da verificação"
msgid "SecurityOrchestration|Scan execution"
msgstr "Execução de verificação"
@@ -31921,7 +32612,7 @@ msgid "SecurityOrchestration|Scan execution policies can only be created by proj
msgstr ""
msgid "SecurityOrchestration|Scan result"
-msgstr ""
+msgstr "Resultado da verificação"
msgid "SecurityOrchestration|Scan result policies can only be created by project owners."
msgstr ""
@@ -31954,7 +32645,7 @@ msgid "SecurityOrchestration|Status"
msgstr "Status"
msgid "SecurityOrchestration|Summary"
-msgstr ""
+msgstr "Resumo"
msgid "SecurityOrchestration|The %{scanners} %{severities} in an open merge request targeting %{branches}."
msgstr ""
@@ -31965,6 +32656,9 @@ msgstr ""
msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr "Este projeto não contém nenhuma política de segurança."
+msgid "SecurityOrchestration|This view only shows scan results for the agent %{agent}. You can view scan results for all agents in the %{linkStart}Operational Vulnerabilities tab of the vulnerability report%{linkEnd}."
+msgstr ""
+
msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
@@ -31987,10 +32681,10 @@ msgid "SecurityOrchestration|an"
msgstr ""
msgid "SecurityOrchestration|branch"
-msgstr ""
+msgstr "ramificação"
msgid "SecurityOrchestration|branches"
-msgstr ""
+msgstr "ramificações"
msgid "SecurityOrchestration|members of groups"
msgstr ""
@@ -32019,9 +32713,6 @@ msgstr ""
msgid "SecurityOrchestration|users with ids"
msgstr ""
-msgid "SecurityOrchestration|view results"
-msgstr "ver resultados"
-
msgid "SecurityOrchestration|vulnerabilities"
msgstr ""
@@ -32691,23 +33382,20 @@ msgstr "Copiar URL"
msgid "Serverless|Getting started with serverless"
msgstr "Primeiros passos com serverless"
-msgid "Serverless|Help shape the future of Serverless at GitLab"
-msgstr "Ajude a moldar o futuro do Serverless no GitLab"
-
msgid "Serverless|If you believe none of these apply, please check back later as the function data may be in the process of becoming available."
msgstr "Se você acredita que nenhum destes se aplica, por favor, volte mais tarde, pois os dados da função podem estar no processo de se tornarem disponíveis."
-msgid "Serverless|In order to start using functions as a service, you must first install Knative on your Kubernetes cluster. %{linkStart}More information%{linkEnd}"
-msgstr "Para começar a usar funções como um serviço, você deve primeiro instalar Knative em seu cluster de Kubernetes. %{linkStart}Mais informações%{linkEnd}"
-
msgid "Serverless|Learn more about Serverless"
msgstr "Saiba mais sobre Serverless"
msgid "Serverless|No functions available"
msgstr "Nenhuma função disponível"
-msgid "Serverless|Sign up for First Look"
-msgstr "Inscreva-se para First Look"
+msgid "Serverless|Serverless was %{linkStart}deprecated%{linkEnd} in GitLab 14.3."
+msgstr ""
+
+msgid "Serverless|Serverless was %{postLinkStart}deprecated%{postLinkEnd}. But if you opt to use it, you must install Knative in your Kubernetes cluster first. %{linkStart}Learn more.%{linkEnd}"
+msgstr ""
msgid "Serverless|The deploy job has not finished."
msgstr "A tarefa de implantação ainda não terminou."
@@ -32718,9 +33406,6 @@ msgstr "As funções listadas no arquivo %{startTag}serverless.yml%{endTag} não
msgid "Serverless|There is currently no function data available from Knative. This could be for a variety of reasons including:"
msgstr "No momento não há dados de função disponíveis a partir do Knative. Isso pode ocorrer por uma variedade de motivos, incluindo:"
-msgid "Serverless|We are continually striving to improve our Serverless functionality. As a Knative user, we would love to hear how we can make this experience better for you. Sign up for GitLab First Look today and we will be in touch shortly."
-msgstr "Estamos continuamente nos esforçando para melhorar nossa funcionalidade de Serverless. Como usuário do Knative, adoraríamos saber como podemos tornar essa experiência melhor para você. Inscreva-se no GitLab First Look hoje e entraremos em contato em breve."
-
msgid "Serverless|Your %{startTag}.gitlab-ci.yml%{endTag} file is not properly configured."
msgstr "Seu arquivo %{startTag}.gitlab-ci,yml%{endTag} não está configurado adequadamente."
@@ -32736,9 +33421,6 @@ msgstr "Conta de serviço"
msgid "Service Account Key"
msgstr "Chave de conta de serviço"
-msgid "Service Accounts"
-msgstr "Contas de serviço"
-
msgid "Service Accounts keys authorize GitLab to deploy your Google Cloud project"
msgstr ""
@@ -32748,10 +33430,10 @@ msgstr "Central de serviços"
msgid "Service Desk allows people to create issues in your GitLab instance without their own user account. It provides a unique email address for end users to create issues in a project. Replies can be sent either through the GitLab interface or by email. End users only see threads through email."
msgstr ""
-msgid "Service Usage Data"
+msgid "Service account generated successfully"
msgstr ""
-msgid "Service account generated successfully"
+msgid "Service accounts"
msgstr ""
msgid "Service ping is disabled in your configuration file, and cannot be enabled through this form."
@@ -32895,6 +33577,9 @@ msgstr "Defina o tempo máximo de sessão para um terminal web."
msgid "Set the milestone to %{milestone_reference}."
msgstr "Definir o marco como %{milestone_reference}."
+msgid "Set the per-user rate limit for getting a user by ID via the API."
+msgstr ""
+
msgid "Set the per-user rate limit for notes created by web or API requests."
msgstr ""
@@ -32953,7 +33638,7 @@ msgid "SetStatusModal|An indicator appears next to your name and avatar"
msgstr "Um indicador aparece ao lado do seu nome e avatar"
msgid "SetStatusModal|Busy"
-msgstr ""
+msgstr "Ocupado"
msgid "SetStatusModal|Clear status"
msgstr "Limpar status"
@@ -33074,6 +33759,9 @@ msgstr ""
msgid "Shared runners details"
msgstr ""
+msgid "Shared runners enabled cannot be enabled until a valid credit card is on file"
+msgstr ""
+
msgid "Shared runners help link"
msgstr "Link de ajuda de executores compartilhados"
@@ -33126,11 +33814,14 @@ msgid "Show all breadcrumbs"
msgstr ""
msgid "Show all epics"
-msgstr ""
+msgstr "Mostrar todos os épicos"
msgid "Show all issues."
msgstr "Mostrar todas as issues"
+msgid "Show all milestones"
+msgstr ""
+
msgid "Show all test cases."
msgstr "Mostrar todos os casos de teste"
@@ -33141,7 +33832,7 @@ msgid "Show archived projects only"
msgstr "Mostrar somente projetos arquivados"
msgid "Show closed epics"
-msgstr ""
+msgstr "Mostrar épicos fechados"
msgid "Show command"
msgstr "Exibir comando"
@@ -33167,6 +33858,9 @@ msgstr "Mostrar navegador de arquivos"
msgid "Show file contents"
msgstr "Mostrar conteúdo do arquivo"
+msgid "Show group milestones"
+msgstr ""
+
msgid "Show labels"
msgstr "Mostrar etiquetas"
@@ -33180,6 +33874,12 @@ msgid "Show one file at a time"
msgstr ""
msgid "Show open epics"
+msgstr "Mostrar épicos abertos"
+
+msgid "Show project milestones"
+msgstr ""
+
+msgid "Show sub-group milestones"
msgstr ""
msgid "Show the Closed list"
@@ -33191,11 +33891,6 @@ msgstr "Mostrar a lista aberta"
msgid "Show whitespace changes"
msgstr "Mostrar as alterações de espaço em branco"
-msgid "Showing %d event"
-msgid_plural "Showing %d events"
-msgstr[0] "Mostrando %d evento"
-msgstr[1] "Mostrando %d eventos"
-
msgid "Showing %{conflict} between %{sourceBranch} and %{targetBranch}"
msgstr "Mostrando %{conflict} entre %{sourceBranch} e %{targetBranch}"
@@ -33255,12 +33950,6 @@ msgstr "Nenhum status"
msgid "Sidebar|None"
msgstr "Nenhum"
-msgid "Sidebar|Only numeral characters allowed"
-msgstr "Apenas caracteres numéricos permitidos"
-
-msgid "Sidebar|Weight"
-msgstr "Peso"
-
msgid "Sidekiq job compression threshold (bytes)"
msgstr ""
@@ -33421,10 +34110,13 @@ msgid "Slack integration allows you to interact with GitLab via slash commands i
msgstr "A integração com o Slack permite que você interaja com o GitLab por meio de comandos de barra em uma janela de bate-papo."
msgid "Slack logo"
+msgstr "Logotipo do Slack"
+
+msgid "SlackIntegration|Are you sure you want to remove this project from the Slack application?"
msgstr ""
msgid "SlackIntegration|GitLab for Slack"
-msgstr ""
+msgstr "GitLab para Slack"
msgid "SlackIntegration|GitLab for Slack was successfully installed."
msgstr ""
@@ -33432,11 +34124,14 @@ msgstr ""
msgid "SlackIntegration|Project alias"
msgstr ""
+msgid "SlackIntegration|Remove project"
+msgstr ""
+
msgid "SlackIntegration|Select a GitLab project to link with your Slack workspace."
msgstr ""
msgid "SlackIntegration|Sends notifications about project events to Slack channels."
-msgstr "Envia notificações sobre eventos do projeto para os canais do Slack."
+msgstr "Envie notificações sobre eventos do projeto para os canais do Slack."
msgid "SlackIntegration|Team name"
msgstr ""
@@ -33576,9 +34271,6 @@ msgstr "Algo deu errado ao tentar mudar o estado de bloqueio desse %{issuableDis
msgid "Something went wrong trying to load issue contacts."
msgstr ""
-msgid "Something went wrong when creating a work item. Please try again"
-msgstr ""
-
msgid "Something went wrong when reordering designs. Please try again"
msgstr ""
@@ -33672,9 +34364,6 @@ msgstr ""
msgid "Something went wrong while inserting your image. Please try again."
msgstr ""
-msgid "Something went wrong while merging this merge request. Please try again."
-msgstr ""
-
msgid "Something went wrong while obtaining the Let's Encrypt certificate."
msgstr "Ocorreu um erro ao obter o certificado Let's Encrypt."
@@ -33996,10 +34685,10 @@ 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."
+msgid "SourcegraphAdmin|Learn more."
msgstr ""
-msgid "SourcegraphAdmin|More information"
+msgid "SourcegraphAdmin|Only public projects have code intelligence enabled and communicate with Sourcegraph."
msgstr ""
msgid "SourcegraphAdmin|Save changes"
@@ -34008,7 +34697,7 @@ msgstr "Salvar alterações"
msgid "SourcegraphAdmin|Sourcegraph URL"
msgstr ""
-msgid "SourcegraphAdmin|e.g. https://sourcegraph.example.com"
+msgid "SourcegraphAdmin|https://sourcegraph.example.com"
msgstr ""
msgid "SourcegraphPreferences|This feature is experimental and currently limited to certain projects."
@@ -34078,7 +34767,7 @@ msgid "Star a label to make it a priority label. Order the prioritized labels to
msgstr "Coloque uma estrela em uma etiqueta para dar prioridade. Altere a ordem das etiquetas priorizadas arrastando-as para alterar sua prioridade."
msgid "Star labels to start sorting by priority"
-msgstr ""
+msgstr "Favorite etiquetas para começar a classificar por prioridade"
msgid "Star toggle failed. Try again later."
msgstr ""
@@ -34143,6 +34832,9 @@ msgstr "Iniciar limpeza"
msgid "Start date"
msgstr "Data de início"
+msgid "Start free trial"
+msgstr ""
+
msgid "Start merge train"
msgstr ""
@@ -34173,6 +34865,9 @@ msgstr "Iniciado %{startsIn}"
msgid "Started asynchronous removal of all repository check states."
msgstr "Iniciada a remoção assíncrona de todos os estados de verificação do repositório."
+msgid "Started escalation for this incident."
+msgstr ""
+
msgid "Starting..."
msgstr "Iniciando..."
@@ -34185,6 +34880,9 @@ msgstr "Inicia %{startsIn}"
msgid "Starts at (UTC)"
msgstr "Começa em (UTC)"
+msgid "Starts escalations for this incident"
+msgstr ""
+
msgid "Starts on"
msgstr ""
@@ -34195,7 +34893,7 @@ msgid "State your message to activate"
msgstr "Regitre sua mensagem para ativar"
msgid "State/Province"
-msgstr ""
+msgstr "Estado/Província"
msgid "State/Province/City"
msgstr "Estado/Província/Cidade"
@@ -34446,6 +35144,9 @@ msgstr "Desconhecido"
msgid "Strikethrough"
msgstr ""
+msgid "Strikethrough text"
+msgstr ""
+
msgid "Subgroup information"
msgstr "Informação do subgrupo"
@@ -34579,10 +35280,10 @@ msgid "SubscriptionEmail|Additional charges for your GitLab subscription"
msgstr ""
msgid "SubscriptionEmail|Dear %{customer_name},"
-msgstr ""
+msgstr "Caro %{customer_name},"
msgid "SubscriptionEmail|GitLab Billing Team"
-msgstr ""
+msgstr "Equipe de cobrança do GitLab"
msgid "SubscriptionEmail|Thank you for your business!"
msgstr ""
@@ -34680,6 +35381,21 @@ msgstr "A contagem de uso é realizada uma vez por dia às 12:00 PM."
msgid "Subscriptions"
msgstr ""
+msgid "Subscriptions|Chat with sales"
+msgstr ""
+
+msgid "Subscriptions|Close"
+msgstr ""
+
+msgid "Subscriptions|Not ready to buy yet?"
+msgstr ""
+
+msgid "Subscriptions|Start a free trial"
+msgstr ""
+
+msgid "Subscriptions|We understand. Maybe you have some questions for our sales team, or maybe you'd like to try some of the paid features first. What would you like to do?"
+msgstr ""
+
msgid "Subscription|Your subscription for %{strong}%{namespace_name}%{strong_close} has expired and you are now on %{pricing_link_start}the GitLab Free tier%{pricing_link_end}. Don't worry, your data is safe. Get in touch with our support team (%{support_email}). They'll gladly help with your subscription renewal."
msgstr ""
@@ -34890,6 +35606,9 @@ msgstr "Gerenciar"
msgid "SuperSonics|Maximum users"
msgstr ""
+msgid "SuperSonics|Offline cloud"
+msgstr ""
+
msgid "SuperSonics|Paste your activation code"
msgstr ""
@@ -34956,6 +35675,12 @@ msgstr ""
msgid "SuperSonics|You do not have an active subscription"
msgstr "Você não tem uma assinatura ativa"
+msgid "SuperSonics|You have a future dated license"
+msgstr ""
+
+msgid "SuperSonics|You have added a license that activates on %{date}. Please see the subscription history table below for more details."
+msgstr ""
+
msgid "SuperSonics|You have successfully added a license that activates on %{date}. Please see the subscription history table below for more details."
msgstr ""
@@ -35115,6 +35840,9 @@ msgstr "Nome da tag"
msgid "Tag name is required"
msgstr "Nome da tag é obrigatória"
+msgid "Tag push"
+msgstr ""
+
msgid "Tag push events"
msgstr ""
@@ -35217,6 +35945,9 @@ msgstr "Escreva suas notas de lançamento ou arraste arquivos aqui…"
msgid "TagsPage|protected"
msgstr "protegido"
+msgid "Take a look at the documentation to discover all of GitLab’s capabilities."
+msgstr ""
+
msgid "Target Branch"
msgstr "Ramificação de destino"
@@ -35305,7 +36036,7 @@ msgid "Terms of Service and Privacy Policy"
msgstr "Termos de Serviço e Política de Privacidade"
msgid "Terms of service"
-msgstr ""
+msgstr "Termos de serviço"
msgid "Terraform"
msgstr "Terraform"
@@ -35619,6 +36350,9 @@ msgstr "Você pode configurar sua tarefa para usar relatórios de teste de unida
msgid "Tests"
msgstr "Testes"
+msgid "Text (optional)"
+msgstr ""
+
msgid "Text added to the body of all email messages. %{character_limit} character limit"
msgstr ""
@@ -35669,6 +36403,9 @@ msgstr ""
msgid "The CSV export will be created in the background. Once finished, it will be sent to %{email} in an attachment."
msgstr "A exportação CSV será criada em segundo plano. Quando concluída, será enviada para %{email} em um anexo."
+msgid "The CSV export you requested of all user memberships is attached to this email."
+msgstr ""
+
msgid "The GitLab subscription service (customers.gitlab.com) is currently experiencing an outage. You can monitor the status and get updates at %{linkStart}status.gitlab.com%{linkEnd}."
msgstr ""
@@ -35744,6 +36481,9 @@ msgstr "O conteúdo desta página não está codificado em UTF-8. Edições só
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 epic"
+msgstr ""
+
msgid "The current issue"
msgstr ""
@@ -35905,6 +36645,9 @@ msgstr ""
msgid "The latest pipeline for this merge request has failed."
msgstr ""
+msgid "The license key is invalid."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -35920,6 +36663,9 @@ msgstr "A licença foi carregada com sucesso e agora está ativa. Você pode ver
msgid "The license was successfully uploaded and will be active from %{starts_at}. You can see the details below."
msgstr ""
+msgid "The license you uploaded is invalid. If the issue persists, contact support at %{link}."
+msgstr ""
+
msgid "The list creation wizard is already open"
msgstr ""
@@ -36541,11 +37287,14 @@ msgstr "Essa ação pode levar à perda de dados. Para evitar ações acidentais
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
-msgstr "Essa ação %{strongOpen}excluirá permanentemente%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}imediatamente%{strongClose}, incluindo seus repositórios e todos os recursos relacionados, incluindo problemas e solicitações de mesclagem."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} and everything this project contains. %{strongOpen}There is no going back%{strongClose}"
+msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}on %{date}%{strongClose}, including its repositories and all related resources, including issues and merge requests."
-msgstr "Essa ação %{strongOpen}excluirá permanentemente%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}na data %{date}%{strongClose}, incluindo seus repositórios e todos os recursos relacionados, incluindo problemas e solicitações de mesclagem."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains."
+msgstr ""
+
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains. %{strongOpen}There is no going back.%{strongClose}"
+msgstr ""
msgid "This action will %{strongOpen}permanently remove%{strongClose} %{codeOpen}%{group}%{codeClose} %{strongOpen}immediately%{strongClose}."
msgstr ""
@@ -36673,9 +37422,6 @@ msgstr "Este campo é obrigatório."
msgid "This file was modified for readability, and can't accept suggestions. Edit it directly."
msgstr ""
-msgid "This forked project has the following:"
-msgstr ""
-
msgid "This form is disabled in preview"
msgstr "Este formulário está desativado na pré-visualização"
@@ -36688,8 +37434,8 @@ msgstr ""
msgid "This group can't be removed because it is linked to a subscription. To remove this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr "Este grupo não pode ser transferido porque está vinculado a uma assinatura. Para transferir este grupo, %{linkStart}vincule a assinatura%{linkEnd} a um grupo diferente."
-msgid "This group can't be transfered because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
-msgstr "Este grupo não pode ser transferido porque está vinculado a uma assinatura. Para transferir este grupo, %{linkStart}vincule a assinatura%{linkEnd} a um grupo diferente."
+msgid "This group can't be transferred because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
+msgstr ""
msgid "This group cannot be invited to a project inside a group with enforced SSO"
msgstr ""
@@ -36715,6 +37461,9 @@ 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 incident is already escalated with '%{escalation_policy_name}'."
+msgstr ""
+
msgid "This invitation was sent to %{mail_to_invite_email}, but you are signed in as %{link_to_current_user} with email %{mail_to_current_user}."
msgstr ""
@@ -36733,14 +37482,11 @@ 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 merge train pipeline"
-msgstr ""
-
msgid "This is a private email address %{helpIcon} generated just for you. Anyone who has it can create issues or merge requests as if they were you. If that happens, %{resetLinkStart}reset this token%{resetLinkEnd}."
msgstr ""
msgid "This is a security log of authentication events involving your account."
-msgstr ""
+msgstr "Este é um registro de segurança de eventos de autenticação envolvendo a sua conta."
msgid "This is a self-managed instance of GitLab."
msgstr ""
@@ -36757,6 +37503,12 @@ msgstr ""
msgid "This is your current session"
msgstr "Esta é a sua sessão atual"
+msgid "This issue cannot be assigned to a confidential epic because it is public."
+msgstr ""
+
+msgid "This issue cannot be made public because it belongs to a confidential epic."
+msgstr ""
+
msgid "This issue is confidential and should only be visible to team members with at least Reporter access."
msgstr ""
@@ -36874,6 +37626,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 branch is protected from force push."
+msgstr ""
+
msgid "This merge request cannot be rebased while there are conflicts."
msgstr ""
@@ -36925,9 +37680,15 @@ msgstr "Este pipeline faz uso de uma configuração de CI/CD predefinida habilit
msgid "This pipeline was triggered by a schedule."
msgstr "Este pipeline foi disparando por um agendamento."
+msgid "This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project"
msgstr "Este projeto"
+msgid "This project can be restored until %{date}."
+msgstr ""
+
msgid "This project cannot be %{visibilityLevel} because the visibility of %{openShowLink}%{name}%{closeShowLink} is %{visibility}. To make this project %{visibilityLevel}, you must first %{openEditLink}change the visibility%{closeEditLink} of the parent group."
msgstr ""
@@ -36946,6 +37707,9 @@ msgstr ""
msgid "This project is %{strongStart}NOT%{strongEnd} a fork, and has the following:"
msgstr "Este projeto %{strongStart}NÃO%{strongEnd} tem um fork e tem o seguinte:"
+msgid "This project is %{strongStart}NOT%{strongEnd} a fork. This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr "Este projeto está arquivado e não pode ser comentado."
@@ -37637,6 +38401,9 @@ msgstr ""
msgid "Today"
msgstr "Hoje"
+msgid "Todos count"
+msgstr ""
+
msgid "Todos|Are you looking for things to do? Take a look at %{strongStart}%{openIssuesLinkStart}open issues%{openIssuesLinkEnd}%{strongEnd}, contribute to %{strongStart}%{mergeRequestLinkStart}a merge request%{mergeRequestLinkEnd}%{mergeRequestLinkEnd}%{strongEnd}, or mention someone in a comment to automatically assign them a new to-do item."
msgstr "Você está procurando coisas para fazer? Dê uma olhada em %{strongStart}%{openIssuesLinkStart}issues abertas%{openIssuesLinkEnd}%{strongEnd}, contribua para %{strongStart}%{mergeRequestLinkStart}uma solicitação de mesclagem%{mergeRequestLinkEnd}%{mergeRequestLinkEnd}%{strongEnd}ou mencione alguém em um comentário para atribuir automaticamente uma nova tarefa."
@@ -37910,10 +38677,8 @@ msgstr "Visão em árvore"
msgid "Trending"
msgstr "Mais populares"
-msgid "Trials|%{planName} Trial %{enDash} %{num} day left"
-msgid_plural "Trials|%{planName} Trial %{enDash} %{num} days left"
-msgstr[0] "Teste %{planName} %{enDash} %{num} dia restante"
-msgstr[1] "Teste %{planName} %{enDash} %{num} dias restantes"
+msgid "Trials|%{planName} Trial"
+msgstr ""
msgid "Trials|Compare all plans"
msgstr "Comparar todos os planos"
@@ -37921,6 +38686,9 @@ msgstr "Comparar todos os planos"
msgid "Trials|Create a new group to start your GitLab Ultimate trial."
msgstr "Crie um novo grupo para iniciar sua avaliação do GitLab Ultimate."
+msgid "Trials|Day %{daysUsed}/%{duration}"
+msgstr ""
+
msgid "Trials|Go back to GitLab"
msgstr "Voltar para o GitLab"
@@ -38036,7 +38804,7 @@ msgid "Trigger|Trigger user has insufficient permissions to project"
msgstr ""
msgid "Trigger|invalid"
-msgstr ""
+msgstr "inválido"
msgid "Troubleshoot and monitor your application with tracing"
msgstr "Solucionar problemas e monitorar sua aplicação com rastreamento"
@@ -38170,8 +38938,8 @@ msgstr ""
msgid "URL is triggered when repository is updated"
msgstr ""
-msgid "URL must be percent-encoded if neccessary."
-msgstr "O URL deve ser codificado em porcentagem, se necessário."
+msgid "URL must be percent-encoded if necessary."
+msgstr ""
msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
msgstr ""
@@ -38389,6 +39157,9 @@ msgstr "Desbloquear"
msgid "Unlock account"
msgstr "Desbloquear conta"
+msgid "Unlock more features with GitLab Ultimate"
+msgstr ""
+
msgid "Unlock the discussion"
msgstr "Desbloquear a discussão"
@@ -38452,6 +39223,9 @@ msgstr "cancelar subscrição de %{quick_action_target}."
msgid "Unsubscribes from this %{quick_action_target}."
msgstr ""
+msgid "Unsupported sort value."
+msgstr ""
+
msgid "Unsupported todo type passed. Supported todo types are: %{todo_types}"
msgstr ""
@@ -38558,7 +39332,7 @@ msgid "Updated %{updated_at} by %{updated_by}"
msgstr "Atualizado em %{updated_at} por %{updated_by}"
msgid "Updated date"
-msgstr ""
+msgstr "Data de atualização"
msgid "Updates"
msgstr "Atualizações"
@@ -38680,6 +39454,9 @@ msgstr "Uso do período atual"
msgid "UsageQuota|File attachments and smaller design graphics."
msgstr "Anexos de arquivo e gráficos de design menores."
+msgid "UsageQuota|From %{storage_enforcement_date} storage limits will apply to this namespace. View and manage your usage in %{strong_start}Group Settings &gt; Usage quotas%{strong_end}."
+msgstr ""
+
msgid "UsageQuota|Git repository."
msgstr "Repositório Gif."
@@ -38740,6 +39517,9 @@ msgstr "Armazenamento"
msgid "UsageQuota|Storage type"
msgstr "Tipo de armazenamento"
+msgid "UsageQuota|Storage used"
+msgstr ""
+
msgid "UsageQuota|This is the total amount of storage used across your projects within this namespace."
msgstr ""
@@ -38935,6 +39715,12 @@ msgstr "Usar armazenamento hash"
msgid "Use hashed storage paths for newly created and renamed repositories. Always enabled since 13.0."
msgstr ""
+msgid "Use issue count"
+msgstr ""
+
+msgid "Use issue weight"
+msgstr ""
+
msgid "Use one line per URI"
msgstr "Use uma linha por URI"
@@ -39080,7 +39866,7 @@ msgid "User-based escalation rules must have a user with access to the project"
msgstr ""
msgid "UserAvailability|%{author} %{spanStart}(Busy)%{spanEnd}"
-msgstr ""
+msgstr "%{author} %{spanStart}(Ocupado)%{spanEnd}"
msgid "UserAvailability|%{author} (Busy)"
msgstr "%{author} (Ocupado)"
@@ -39316,6 +40102,9 @@ msgstr "Nome de usuário: %{username}"
msgid "Users"
msgstr "Usuários"
+msgid "Users API rate limit"
+msgstr ""
+
msgid "Users can launch a development environment from a GitLab browser tab when the %{linkStart}Gitpod%{linkEnd} integration is enabled."
msgstr "Usuários podem iniciar um ambiente de desenvolvimento a partir de uma guia do GitLab quando a integração %{linkStart}Gitpod%{linkEnd} está ativada."
@@ -39641,6 +40430,9 @@ msgstr "Ver grupo na área do administrador"
msgid "View group labels"
msgstr "Visualizar etiquetas de grupo"
+msgid "View group pipeline usage quota"
+msgstr ""
+
msgid "View incident details at"
msgstr ""
@@ -39793,6 +40585,9 @@ msgstr "Vulnerabilidades"
msgid "Vulnerabilities over time"
msgstr "Vulnerabilidades ao longo do tempo"
+msgid "Vulnerability"
+msgstr ""
+
msgid "Vulnerability Report"
msgstr "Relatório de vulnerabilidade"
@@ -39844,6 +40639,9 @@ msgstr ""
msgid "VulnerabilityManagement|An unverified non-confirmed finding"
msgstr ""
+msgid "VulnerabilityManagement|At least one identifier is required"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -39853,12 +40651,24 @@ msgstr ""
msgid "VulnerabilityManagement|Create Jira issue"
msgstr ""
+msgid "VulnerabilityManagement|Enter a name"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE code"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE identifier URL"
+msgstr ""
+
msgid "VulnerabilityManagement|Fetching linked Jira issues"
msgstr ""
msgid "VulnerabilityManagement|Manually add a vulnerability entry into the vulnerability report."
msgstr ""
+msgid "VulnerabilityManagement|Name is a required field"
+msgstr ""
+
msgid "VulnerabilityManagement|Needs triage"
msgstr ""
@@ -39874,6 +40684,18 @@ msgstr ""
msgid "VulnerabilityManagement|Select a method"
msgstr ""
+msgid "VulnerabilityManagement|Select a severity level"
+msgstr ""
+
+msgid "VulnerabilityManagement|Select a status"
+msgstr ""
+
+msgid "VulnerabilityManagement|Severity is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Something went wrong while creating vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -39898,6 +40720,12 @@ msgstr ""
msgid "VulnerabilityManagement|Something went wrong, could not update vulnerability state."
msgstr ""
+msgid "VulnerabilityManagement|Status is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Submit vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Summary, detailed description, steps to reproduce, etc."
msgstr ""
@@ -40093,6 +40921,9 @@ msgstr ""
msgid "WARNING:"
msgstr "AVISO:"
+msgid "WARNING: This snippet contains hidden files which might be used to mask malicious behavior. Exercise caution if cloning and executing code from this snippet."
+msgstr ""
+
msgid "Wait for the file to load to copy its contents"
msgstr ""
@@ -40274,7 +41105,7 @@ msgid "Webhooks|A comment is added to a confidential issue."
msgstr ""
msgid "Webhooks|A comment is added to an issue."
-msgstr ""
+msgstr "Um comentário é adicionado a uma issue."
msgid "Webhooks|A confidential issue is created, updated, closed, or reopened."
msgstr ""
@@ -40295,7 +41126,7 @@ msgid "Webhooks|A merge request is created, updated, or merged."
msgstr ""
msgid "Webhooks|A new tag is pushed to the repository."
-msgstr ""
+msgstr "Uma nova tag é enviada para o repositório."
msgid "Webhooks|A pipeline's status changes."
msgstr ""
@@ -40307,11 +41138,20 @@ msgid "Webhooks|A subgroup is created or removed."
msgstr ""
msgid "Webhooks|A wiki page is created or updated."
-msgstr ""
+msgstr "Uma página de wiki é criada ou atualizada."
msgid "Webhooks|An issue is created, updated, closed, or reopened."
msgstr ""
+msgid "Webhooks|Are you sure you want to delete this group hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this project hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this webhook?"
+msgstr ""
+
msgid "Webhooks|Comments"
msgstr "Comentários"
@@ -40321,6 +41161,9 @@ msgstr "Comentários confidenciais"
msgid "Webhooks|Confidential issues events"
msgstr "Eventos de issue confidencial"
+msgid "Webhooks|Delete webhook"
+msgstr ""
+
msgid "Webhooks|Deployment events"
msgstr "Eventos de implantação"
@@ -40355,7 +41198,7 @@ msgid "Webhooks|Push events"
msgstr "Eventos de push"
msgid "Webhooks|Push to the repository."
-msgstr ""
+msgstr "Push para o repositório."
msgid "Webhooks|Releases events"
msgstr "Eventos de versões"
@@ -40554,6 +41397,9 @@ msgstr "Por que você está se inscrevendo? (Opcional)"
msgid "Wiki"
msgstr "Wiki"
+msgid "Wiki page"
+msgstr ""
+
msgid "Wiki page was successfully created."
msgstr "Página Wiki criada com sucesso."
@@ -40659,7 +41505,7 @@ msgstr "Excluir página %{pageTitle}?"
msgid "WikiPageConflictMessage|Someone edited the page the same time you did. Please check out %{wikiLinkStart}the page%{wikiLinkEnd} and make sure your changes will not unintentionally remove theirs."
msgstr ""
-msgid "WikiPage|An error occured while trying to render the content editor. Please try again later."
+msgid "WikiPage|An error occurred while trying to render the content editor. Please try again later."
msgstr ""
msgid "WikiPage|Are you sure you want to switch back to the classic editor?"
@@ -40818,6 +41664,18 @@ msgstr ""
msgid "WorkItem|New Task"
msgstr ""
+msgid "WorkItem|Something went wrong when creating a work item. Please try again"
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching the work item. Please try again."
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching work item types. Please try again"
+msgstr ""
+
+msgid "WorkItem|Type"
+msgstr ""
+
msgid "WorkItem|Work Items"
msgstr ""
@@ -40884,8 +41742,11 @@ msgstr ""
msgid "You are about to add %{usersTag} people to the discussion. They will all receive a notification."
msgstr ""
-msgid "You are about to permanently delete this project"
-msgstr "Você está prestes a excluir permanentemente este projeto"
+msgid "You are about to delete this forked project containing:"
+msgstr ""
+
+msgid "You are about to delete this project containing:"
+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 "Você está prestes a transferir o controle da sua conta para o grupo %{group_name} . Esta ação NÃO é reversível, você não poderá acessar nenhum dos seus grupos e projetos fora do %{group_name} assim que a transferência for concluída."
@@ -40905,6 +41766,9 @@ msgstr "Você está tentando excluir um arquivo que foi atualizado anteriormente
msgid "You are attempting to update a file that has changed since you started editing it."
msgstr "Você está tentando atualizar um arquivo que foi alterado desde que você começou a editá-lo."
+msgid "You are billed if you exceed this number. %{qsrOverageLinkStart}How does billing work?%{qsrOverageLinkEnd}"
+msgstr ""
+
msgid "You are connected to the Prometheus server, but there is currently no data to display."
msgstr "Você está conectado ao servidor Prometheus, mas atualmente não há dados para exibir."
@@ -40962,6 +41826,9 @@ msgstr "Você não está autorizado a atualizar este perfil"
msgid "You are not authorized to update this scanner profile"
msgstr ""
+msgid "You are not authorized to upload metric images"
+msgstr ""
+
msgid "You are now impersonating %{username}"
msgstr "Você está agora se passando por %{username}"
@@ -41115,9 +41982,6 @@ msgstr "Você só pode transferir o projeto para espaços de nome que você gere
msgid "You can only upload one design when dropping onto an existing design."
msgstr ""
-msgid "You can recover this project until %{date}"
-msgstr "Você pode recuperar este projeto até %{date}"
-
msgid "You can resolve the merge conflict using either the Interactive mode, by choosing %{use_ours} or %{use_theirs} buttons, or by editing the files directly. Commit these changes into %{branch_name}"
msgstr "Você pode resolver o conflito de mesclagem usando o modo Interativo, escolhendo os botões %{use_ours} ou %{use_theirs} ou editando os arquivos diretamente. Confirme essas mudanças em %{branch_name}"
@@ -41166,9 +42030,6 @@ msgstr "Você não pode escrever numa instância secundária de somente leitura
msgid "You cannot write to this read-only GitLab instance."
msgstr "Você não pode escrever nesta instância somente-leitura do GitLab."
-msgid "You can’t %{tag_start}edit%{tag_end} files directly in this project. Fork this project and submit a merge request with your changes."
-msgstr "Você não pode %{tag_start}editar%{tag_end} arquivos diretamente nesse projeto. Faça um fork nesse projeto e envie uma solicitação de mesclagem com suas alterações."
-
msgid "You can’t edit files directly in this project. Fork this project and submit a merge request with your changes."
msgstr ""
@@ -41321,9 +42182,6 @@ msgstr "Você não tem permissão"
msgid "You have not added any approvers. Start by adding users or groups."
msgstr "Você não adicionou qualquer aprovadores. Comece adicionando usuários ou grupos."
-msgid "You have reached your project limit"
-msgstr "Você atingiu o limite de seu projeto"
-
msgid "You have set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr "Você configurou o 2FA para sua conta! Se você perder o acesso ao seu dispositivo 2FA, poderá usar seus códigos de recuperação para acessar sua conta. Como alternativa, se você enviar uma chave SSH, poderá %{anchorOpen}usar essa chave para gerar códigos de recuperação adicionais%{anchorClose}."
@@ -41354,12 +42212,6 @@ msgstr ""
msgid "You must have maintainer access to force delete a lock"
msgstr "Você deve ter o acesso de mantenedor para apagar um bloqueio"
-msgid "You must have permission to create a project in a group before forking."
-msgstr "Você deve ter permissão para criar um projeto em um grupo antes de criar o fork."
-
-msgid "You must have permission to create a project in a namespace before forking."
-msgstr "Você deve ter permissão para criar um projeto em um espaço de nome antes de criar o fork."
-
msgid "You must provide a valid current password"
msgstr "Você deve fornecer uma senha atual válida"
@@ -41765,7 +42617,7 @@ msgstr "Seus projetos"
msgid "Your public email will be displayed on your public profile."
msgstr "Seu e-mail será exibido no seu perfil público."
-msgid "Your request for access could not be processed: %{error_meesage}"
+msgid "Your request for access could not be processed: %{error_message}"
msgstr ""
msgid "Your request for access has been queued for review."
@@ -41948,6 +42800,9 @@ msgstr ""
msgid "archived:"
msgstr ""
+msgid "artifacts"
+msgstr ""
+
msgid "assign yourself"
msgstr ""
@@ -41977,6 +42832,9 @@ msgstr[1] "ramificações"
msgid "branch name"
msgstr "nome da branch"
+msgid "builds"
+msgstr ""
+
msgid "by"
msgstr "por"
@@ -42400,6 +43258,9 @@ msgstr ""
msgid "contact with same email already exists in group hierarchy"
msgstr ""
+msgid "container registry images"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -42439,6 +43300,9 @@ msgstr "criado por"
msgid "data"
msgstr ""
+msgid "database"
+msgstr ""
+
msgid "date must not be after 9999-12-31"
msgstr "data não deve ser após 9999-12-31"
@@ -42462,9 +43326,6 @@ msgstr "implantar"
msgid "design"
msgstr "design"
-msgid "detached"
-msgstr ""
-
msgid "disabled"
msgstr "desabilitado"
@@ -42604,10 +43465,10 @@ msgid "group"
msgstr "grupo"
msgid "group access token"
-msgstr ""
+msgstr "token de acesso do grupo"
msgid "group access tokens"
-msgstr ""
+msgstr "tokens de acesso de grupo"
msgid "group members"
msgstr ""
@@ -42713,7 +43574,7 @@ msgstr ""
msgid "is not a valid X509 certificate."
msgstr "não é um certificado X509 válido."
-msgid "is not allowed for sign-up."
+msgid "is not allowed for sign-up. Please use your regular email address."
msgstr ""
msgid "is not allowed for this group."
@@ -42725,7 +43586,7 @@ msgstr "não é permitido para este projeto."
msgid "is not allowed since the group is not top-level group."
msgstr ""
-msgid "is not allowed."
+msgid "is not allowed. Please use your regular email address."
msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
@@ -42812,6 +43673,9 @@ msgstr "menos de um minuto"
msgid "level: %{level}"
msgstr ""
+msgid "lfs objects"
+msgstr ""
+
msgid "limit of %{project_limit} reached"
msgstr ""
@@ -43031,6 +43895,9 @@ msgstr ""
msgid "mrWidget|Merge blocked: pipeline must succeed. It's waiting for a manual action to continue."
msgstr ""
+msgid "mrWidget|Merge blocked: pipeline must succeed. Push a commit that fixes the failure, or %{linkStart}learn about other solutions.%{linkEnd}"
+msgstr ""
+
msgid "mrWidget|Merge blocked: this merge request must be approved."
msgstr ""
@@ -43148,9 +44015,6 @@ msgstr "Houve merge das alterações em"
msgid "mrWidget|The changes were not merged into"
msgstr "Não houve merge para as mudanças em"
-msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
-msgstr "O pipeline para essse merge request não foi concluído. Faça um push em um novo commit para corrigir a falha, ou verifique a %{linkStart}documentação de solução de problemas%{linkEnd} para ver as possíveis ações."
-
msgid "mrWidget|The source branch has been deleted"
msgstr "O branch de origem foi excluído"
@@ -43298,9 +44162,6 @@ msgstr ""
msgid "open issue"
msgstr "issue aberta"
-msgid "opened %{timeAgo}"
-msgstr "aberto em %{timeAgo}"
-
msgid "or"
msgstr "ou"
@@ -43312,6 +44173,12 @@ msgid_plural "out of %d total tests"
msgstr[0] "de um total de %d teste"
msgstr[1] "de um total de %d testes"
+msgid "packages"
+msgstr ""
+
+msgid "pages"
+msgstr ""
+
msgid "parent"
msgid_plural "parents"
msgstr[0] "pai"
@@ -43461,6 +44328,9 @@ msgid_plural "replies"
msgstr[0] "resposta"
msgstr[1] "respostas"
+msgid "repositories"
+msgstr ""
+
msgid "repository:"
msgstr "repositório:"
@@ -43581,12 +44451,18 @@ msgstr ""
msgid "tag name"
msgstr "nome da tag"
+msgid "terraform states"
+msgstr ""
+
msgid "the correct format."
msgstr ""
msgid "the file"
msgstr ""
+msgid "the following epic(s)"
+msgstr ""
+
msgid "the following issue(s)"
msgstr ""
@@ -43599,21 +44475,12 @@ msgstr "então"
msgid "this document"
msgstr "este documento"
-msgid "this issue cannot be assigned to a confidential epic since it is public"
-msgstr ""
-
-msgid "this issue cannot be made public since it belongs to a confidential epic"
-msgstr ""
-
msgid "time summary"
msgstr ""
msgid "toggle collapse"
msgstr "Ocultar/Expandir"
-msgid "train"
-msgstr ""
-
msgid "triggered"
msgstr ""
@@ -43742,3 +44609,6 @@ msgstr "{group}"
msgid "{project}"
msgstr "{project}"
+msgid "✔"
+msgstr ""
+
diff --git a/locale/pt_PT/gitlab.po b/locale/pt_PT/gitlab.po
index 1822427e306..3b5ea1b40f6 100644
--- a/locale/pt_PT/gitlab.po
+++ b/locale/pt_PT/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: pt-PT\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2022-02-02 15:44\n"
+"PO-Revision-Date: 2022-03-01 20:38\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -146,6 +146,11 @@ msgid_plural "%d approvers (you've approved)"
msgstr[0] ""
msgstr[1] ""
+msgid "%d assigned issue"
+msgid_plural "%d assigned issues"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -421,8 +426,23 @@ msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
msgstr[1] ""
-msgid "%d vulnerability updated"
-msgid_plural "%d vulnerabilities updated"
+msgid "%d vulnerability set to confirmed"
+msgid_plural "%d vulnerabilities set to confirmed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to dismissed"
+msgid_plural "%d vulnerabilities set to dismissed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to needs triage"
+msgid_plural "%d vulnerabilities set to needs triage"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to resolved"
+msgid_plural "%d vulnerabilities set to resolved"
msgstr[0] ""
msgstr[1] ""
@@ -510,6 +530,12 @@ msgstr[1] ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{completed} of %{total} issues closed"
+msgstr ""
+
+msgid "%{completed} of %{total} weight completed"
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -858,6 +884,9 @@ msgstr ""
msgid "%{openedIssues} open, %{closedIssues} closed"
msgstr ""
+msgid "%{percentage}%% issues closed"
+msgstr ""
+
msgid "%{percentage}%% weight completed"
msgstr ""
@@ -1287,6 +1316,9 @@ msgid_plural "- Users"
msgstr[0] ""
msgstr[1] ""
+msgid "- of - issues closed"
+msgstr ""
+
msgid "- of - weight completed"
msgstr ""
@@ -1429,7 +1461,7 @@ msgstr "10-19 contribuições"
msgid "1000+"
msgstr ""
-msgid "192.168.0.0/24"
+msgid "192.168.0.0/24 or 2001:0DB8:1234::/48"
msgstr ""
msgid "1st contribution!"
@@ -1741,13 +1773,13 @@ msgstr ""
msgid "AWS Access Key"
msgstr ""
-msgid "AWS Access Key. Only required if not using role instance credentials"
+msgid "AWS Secret Access Key"
msgstr ""
-msgid "AWS Secret Access Key"
+msgid "AWS access key ID (Optional)"
msgstr ""
-msgid "AWS Secret Access Key. Only required if not using role instance credentials"
+msgid "AWS secret access key (Optional)"
msgstr ""
msgid "AWS service error: %{error}"
@@ -1807,9 +1839,6 @@ msgstr "Acesso proibido. Verifica o teu nível de acesso."
msgid "Access granted"
msgstr ""
-msgid "Access key ID"
-msgstr ""
-
msgid "Access requests"
msgstr ""
@@ -1984,7 +2013,7 @@ msgstr ""
msgid "Activity"
msgstr "Atividade"
-msgid "Activity|An error occured while retrieving activity. Reload the page to try again."
+msgid "Activity|An error occurred while retrieving activity. Reload the page to try again."
msgstr ""
msgid "Add"
@@ -2023,6 +2052,9 @@ msgstr ""
msgid "Add a %{type}"
msgstr ""
+msgid "Add a GCP region"
+msgstr ""
+
msgid "Add a GPG key"
msgstr "Adicionar uma chave GPG"
@@ -2074,6 +2106,9 @@ msgstr ""
msgid "Add a numbered list"
msgstr "Adicionar uma lista numerada"
+msgid "Add a related epic"
+msgstr ""
+
msgid "Add a related issue"
msgstr ""
@@ -2188,6 +2223,9 @@ msgstr ""
msgid "Add or subtract spent time"
msgstr "Adicionar ou subtrair o tempo gasto"
+msgid "Add people"
+msgstr ""
+
msgid "Add previously merged commits"
msgstr ""
@@ -2254,6 +2292,9 @@ msgstr ""
msgid "Add webhook"
msgstr ""
+msgid "Add your team members and others to GitLab."
+msgstr ""
+
msgid "Add/remove"
msgstr ""
@@ -3076,12 +3117,6 @@ msgstr ""
msgid "AdvancedSearch|Reindex required"
msgstr ""
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. Permanently deleting this project will %{strongStart}immediately delete%{strongEnd} its repositories and %{strongStart}all related resources%{strongEnd}, including issues, merge requests etc."
-msgstr ""
-
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. You will lose this project's repository and %{strongStart}all related resources%{strongEnd}, including issues and merge requests."
-msgstr ""
-
msgid "After a successful password update you will be redirected to login screen."
msgstr "Após uma atualização de palavra-passe bem-sucedida, serás redirecionado à tela de início de sessão."
@@ -3112,6 +3147,9 @@ msgstr ""
msgid "Akismet helps prevent the creation of spam issues in public projects."
msgstr ""
+msgid "Alert"
+msgstr ""
+
msgid "AlertManagement|Acknowledged"
msgstr ""
@@ -3484,9 +3522,6 @@ msgstr "Todos os endereços de email serão usados para identificar os teus envi
msgid "All environments"
msgstr ""
-msgid "All epics"
-msgstr ""
-
msgid "All groups and projects"
msgstr "Todos os grupos e projetos"
@@ -4223,12 +4258,15 @@ msgstr ""
msgid "ApplicationSettings|Approve users in the pending approval status?"
msgstr ""
-msgid "ApplicationSettings|By making this change, you will automatically approve %d user with the pending approval status."
-msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users with the pending approval status."
+msgid "ApplicationSettings|Approve users who are pending approval?"
+msgstr ""
+
+msgid "ApplicationSettings|By making this change, you will automatically approve %d user who is pending approval."
+msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users who are pending approval."
msgstr[0] ""
msgstr[1] ""
-msgid "ApplicationSettings|By making this change, you will automatically approve all users in pending approval status."
+msgid "ApplicationSettings|By making this change, you will automatically approve all users who are pending approval."
msgstr ""
msgid "ApplicationSettings|Denied domains for sign-ups"
@@ -4634,10 +4672,10 @@ msgstr "Projetos arquivados"
msgid "Archiving the project will make it entirely read-only. It is hidden from the dashboard and doesn't show up in searches. %{strong_start}The repository cannot be committed to, and no issues, comments, or other entities can be created.%{strong_end} %{link_start}Learn more.%{link_end}"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to delete this project?"
+msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
+msgid "Are you absolutely sure?"
msgstr ""
msgid "Are you sure that you want to archive this project?"
@@ -4673,12 +4711,18 @@ msgstr ""
msgid "Are you sure you want to delete this SSH key?"
msgstr ""
+msgid "Are you sure you want to delete this comment?"
+msgstr ""
+
msgid "Are you sure you want to delete this deploy key?"
msgstr ""
msgid "Are you sure you want to delete this device? This action cannot be undone."
msgstr "Tens a certeza de que desejas apagar este dispositivo? Esta ação não pode ser desfeita."
+msgid "Are you sure you want to delete this label?"
+msgstr ""
+
msgid "Are you sure you want to delete this pipeline schedule?"
msgstr "Tens a certeza de que desejas apagar este agendamento de pipeline?"
@@ -4694,9 +4738,6 @@ msgstr ""
msgid "Are you sure you want to discard your changes?"
msgstr ""
-msgid "Are you sure you want to erase this build?"
-msgstr "Tens a certeza de que desejas apagar esta compilação?"
-
msgid "Are you sure you want to import %d repository?"
msgid_plural "Are you sure you want to import %d repositories?"
msgstr[0] ""
@@ -4744,6 +4785,9 @@ msgstr "Tens a certeza de que queres remover esta identidade?"
msgid "Are you sure you want to remove this list?"
msgstr ""
+msgid "Are you sure you want to remove this nickname?"
+msgstr ""
+
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?"
@@ -4756,12 +4800,12 @@ 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 "Tens a certeza de que desejas revogar este apelido?"
-
msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
msgstr ""
+msgid "Are you sure you want to revoke this project access token? This action cannot be undone."
+msgstr ""
+
msgid "Are you sure you want to stop this environment?"
msgstr "Tens a certeza de que desejas parar este ambiente?"
@@ -4906,9 +4950,6 @@ msgstr ""
msgid "Assigned to %{assignee_name}"
msgstr ""
-msgid "Assigned to %{name}"
-msgstr ""
-
msgid "Assigned to me"
msgstr "Atribuído a mim"
@@ -4973,6 +5014,9 @@ msgstr[1] "Anexar %d ficheiros"
msgid "Attaching the file failed."
msgstr "Falha ao anexar o ficheiro."
+msgid "Attention"
+msgstr ""
+
msgid "Audit Events"
msgstr "Eventos de Auditoria"
@@ -5135,6 +5179,12 @@ msgstr "Autorizado em"
msgid "Authorized applications (%{size})"
msgstr "Aplicações autorizadas (%{size})"
+msgid "AuthorizedApplication|Are you sure you want to revoke this application?"
+msgstr ""
+
+msgid "AuthorizedApplication|Revoke application"
+msgstr ""
+
msgid "Authors: %{authors}"
msgstr "Autores: %{authors}"
@@ -6328,6 +6378,9 @@ msgstr ""
msgid "CICDAnalytics|Shared Runners Usage"
msgstr ""
+msgid "CICDAnalytics|Shared runner pipeline minute duration by month"
+msgstr ""
+
msgid "CICDAnalytics|Shared runner usage"
msgstr ""
@@ -6469,6 +6522,9 @@ msgstr ""
msgid "Can create groups:"
msgstr ""
+msgid "Can not delete primary training"
+msgstr ""
+
msgid "Can't apply as the source branch was deleted."
msgstr ""
@@ -6802,9 +6858,6 @@ msgstr ""
msgid "Changing any setting here requires an application restart"
msgstr ""
-msgid "Changing group URL can have unintended side effects."
-msgstr ""
-
msgid "Charts can't be displayed as the request for data has timed out. %{documentationLink}"
msgstr ""
@@ -6892,9 +6945,6 @@ msgstr "A verificar o estado de aprovação"
msgid "Checking branch availability..."
msgstr "A verificar a disponibilidade do ramo..."
-msgid "Checking group URL availability..."
-msgstr ""
-
msgid "Checking group path availability..."
msgstr ""
@@ -7388,6 +7438,9 @@ msgstr ""
msgid "Clear recent searches"
msgstr ""
+msgid "Clear repository checks"
+msgstr ""
+
msgid "Clear search"
msgstr "Limpar Pesquisa"
@@ -7520,9 +7573,6 @@ msgstr ""
msgid "Closed MRs"
msgstr ""
-msgid "Closed epics"
-msgstr ""
-
msgid "Closed issues"
msgstr "Problemas Fechados"
@@ -7559,13 +7609,13 @@ msgstr ""
msgid "Cluster level"
msgstr ""
-msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
+msgid "Cluster type must be specified for Stages::ClusterEndpointInserter"
msgstr ""
msgid "ClusterAgents|%{name} successfully deleted"
msgstr ""
-msgid "ClusterAgents|%{number} of %{total} Agents"
+msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
@@ -7607,6 +7657,15 @@ msgstr ""
msgid "ClusterAgents|Agent never connected to GitLab"
msgstr ""
+msgid "ClusterAgents|Agent version mismatch"
+msgstr ""
+
+msgid "ClusterAgents|Agent version mismatch and update"
+msgstr ""
+
+msgid "ClusterAgents|Agent version update required"
+msgstr ""
+
msgid "ClusterAgents|All"
msgstr ""
@@ -7631,7 +7690,7 @@ msgstr ""
msgid "ClusterAgents|Configuration"
msgstr ""
-msgid "ClusterAgents|Connect a cluster through the Agent"
+msgid "ClusterAgents|Connect a cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connect existing cluster"
@@ -7640,13 +7699,13 @@ msgstr ""
msgid "ClusterAgents|Connect with a certificate"
msgstr ""
-msgid "ClusterAgents|Connect with agent"
+msgid "ClusterAgents|Connect with an agent"
msgstr ""
msgid "ClusterAgents|Connect with the GitLab Agent"
msgstr ""
-msgid "ClusterAgents|Connect your cluster through the Agent"
+msgid "ClusterAgents|Connect your cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connected"
@@ -7706,7 +7765,10 @@ msgstr ""
msgid "ClusterAgents|How to register an agent?"
msgstr ""
-msgid "ClusterAgents|Install new Agent"
+msgid "ClusterAgents|How to update an agent?"
+msgstr ""
+
+msgid "ClusterAgents|Install a new agent"
msgstr ""
msgid "ClusterAgents|Last connected %{timeAgo}."
@@ -7733,7 +7795,7 @@ msgstr ""
msgid "ClusterAgents|Never connected"
msgstr ""
-msgid "ClusterAgents|No Agents"
+msgid "ClusterAgents|No agents"
msgstr ""
msgid "ClusterAgents|No clusters connected through cluster certificates"
@@ -7793,6 +7855,9 @@ msgstr ""
msgid "ClusterAgents|The agent has not been connected in a long time. There might be a connectivity issue. Last contact was %{timeAgo}."
msgstr ""
+msgid "ClusterAgents|The agent version do not match each other across your cluster's pods. This can happen when a new agent version was just deployed and Kubernetes is shutting down the old pods."
+msgstr ""
+
msgid "ClusterAgents|The recommended installation method includes the token. If you want to follow the advanced installation method provided in the docs, make sure you save the token value before you close this window."
msgstr ""
@@ -7840,6 +7905,9 @@ msgstr ""
msgid "ClusterAgents|You will need to create a token to connect to your agent"
msgstr ""
+msgid "ClusterAgents|Your agent version is out of sync with your GitLab version (v%{version}), which might cause compatibility problems. Update the agent installed on your cluster to the most recent version."
+msgstr ""
+
msgid "ClusterAgents|Your instance doesn't have the %{linkStart}GitLab Agent Server (KAS)%{linkEnd} set up. Ask a GitLab Administrator to install it."
msgstr ""
@@ -8716,9 +8784,6 @@ msgstr ""
msgid "Comma-separated list of email addresses."
msgstr ""
-msgid "Comma-separated list of users allowed to exceed the rate limit."
-msgstr ""
-
msgid "Comma-separated, e.g. '1.1.1.1, 2.2.2.0/24'"
msgstr ""
@@ -9045,6 +9110,12 @@ msgstr ""
msgid "Confidential"
msgstr ""
+msgid "Confidential issue"
+msgstr ""
+
+msgid "Confidential note"
+msgstr ""
+
msgid "Confidentiality"
msgstr ""
@@ -9078,6 +9149,9 @@ msgstr ""
msgid "Configure Dependency Scanning in `.gitlab-ci.yml`, creating this file if it does not already exist"
msgstr ""
+msgid "Configure GitLab"
+msgstr ""
+
msgid "Configure GitLab runners to start using the Web Terminal. %{helpStart}Learn more.%{helpEnd}"
msgstr ""
@@ -9126,6 +9200,15 @@ msgstr "Configurar instalação existente"
msgid "Configure pipelines to deploy web apps, backend services, APIs and static resources to Google Cloud"
msgstr ""
+msgid "Configure region"
+msgstr ""
+
+msgid "Configure region for environment"
+msgstr ""
+
+msgid "Configure regions"
+msgstr ""
+
msgid "Configure repository mirroring."
msgstr ""
@@ -9159,6 +9242,9 @@ msgstr ""
msgid "Configure which lists are shown for anyone who visits this board"
msgstr ""
+msgid "Configure your environments to be deployed to specific geographical regions"
+msgstr ""
+
msgid "Confirm"
msgstr ""
@@ -9861,10 +9947,10 @@ msgstr ""
msgid "CorpusManagement|Actions"
msgstr ""
-msgid "CorpusManagement|Corpus are used in fuzz testing as mutation source to Improve future testing."
+msgid "CorpusManagement|Corpus file"
msgstr ""
-msgid "CorpusManagement|Corpus file"
+msgid "CorpusManagement|Corpus files are used in coverage-guided fuzz testing as seed inputs to improve testing."
msgstr ""
msgid "CorpusManagement|Corpus files must be in *.zip format. Maximum 5 GB"
@@ -9918,6 +10004,9 @@ msgstr ""
msgid "Could not apply %{name} command."
msgstr ""
+msgid "Could not apply %{name} command. %{message}."
+msgstr ""
+
msgid "Could not authorize chat nickname. Try again!"
msgstr ""
@@ -10068,6 +10157,9 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
+msgid "Create a group"
+msgstr ""
+
msgid "Create a merge request"
msgstr ""
@@ -10092,6 +10184,9 @@ msgstr ""
msgid "Create a personal access token on your account to pull or push via %{protocol}."
msgstr ""
+msgid "Create a project"
+msgstr ""
+
msgid "Create an account using:"
msgstr ""
@@ -10455,6 +10550,9 @@ msgstr ""
msgid "Creation date"
msgstr ""
+msgid "Creator"
+msgstr ""
+
msgid "Credentials"
msgstr ""
@@ -10467,9 +10565,15 @@ msgstr ""
msgid "CredentialsInventory|Personal Access Tokens"
msgstr ""
+msgid "CredentialsInventory|Project Access Tokens"
+msgstr ""
+
msgid "CredentialsInventory|SSH Keys"
msgstr ""
+msgid "Credit card required to be on file in order to create a pipeline"
+msgstr ""
+
msgid "Credit card:"
msgstr ""
@@ -10653,9 +10757,6 @@ msgstr ""
msgid "Customer relations"
msgstr ""
-msgid "Customizable by an administrator."
-msgstr ""
-
msgid "Customizable by owners."
msgstr ""
@@ -10785,30 +10886,18 @@ msgstr ""
msgid "CycleAnalytics|%{selectedLabelsCount} selected (%{maxLabels} max)"
msgstr ""
-msgid "CycleAnalytics|%{stageCount} stages selected"
-msgstr ""
-
-msgid "CycleAnalytics|All stages"
-msgstr ""
-
-msgid "CycleAnalytics|Average days to completion"
+msgid "CycleAnalytics|Average time to completion"
msgstr ""
msgid "CycleAnalytics|Date"
msgstr ""
-msgid "CycleAnalytics|Days to completion"
-msgstr ""
-
msgid "CycleAnalytics|Display chart filters"
msgstr ""
msgid "CycleAnalytics|Lead Time for Changes"
msgstr ""
-msgid "CycleAnalytics|No stages selected"
-msgstr ""
-
msgid "CycleAnalytics|Number of tasks"
msgstr ""
@@ -10837,18 +10926,30 @@ msgstr ""
msgid "CycleAnalytics|Showing data for group '%{groupName}' from %{createdAfter} to %{createdBefore}"
msgstr ""
-msgid "CycleAnalytics|Stages"
+msgid "CycleAnalytics|Stage time: %{title}"
msgstr ""
msgid "CycleAnalytics|Tasks by type"
msgstr ""
-msgid "CycleAnalytics|The average time spent in the selected stage for the items that were completed on each date. Data limited to the last 500 items."
+msgid "CycleAnalytics|The average time items spent in this stage. Data limited to items completed within this date range."
msgstr ""
msgid "CycleAnalytics|The given date range is larger than 180 days"
msgstr ""
+msgid "CycleAnalytics|The total time items spent across each value stream stage. Data limited to items completed within this date range."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Stage time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Total time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|Total time"
+msgstr ""
+
msgid "CycleAnalytics|Type of work"
msgstr ""
@@ -10861,9 +10962,6 @@ msgstr ""
msgid "CycleAnalytics|project dropdown filter"
msgstr ""
-msgid "CycleAnalytics|stage dropdown"
-msgstr ""
-
msgid "DAG visualization requires at least 3 dependent jobs."
msgstr ""
@@ -10963,10 +11061,16 @@ msgstr ""
msgid "DastProfiles|AJAX spider"
msgstr ""
+msgid "DastProfiles|API"
+msgstr ""
+
+msgid "DastProfiles|API endpoint URL"
+msgstr ""
+
msgid "DastProfiles|Active"
msgstr ""
-msgid "DastProfiles|Additional request headers (Optional)"
+msgid "DastProfiles|Additional request headers (optional)"
msgstr ""
msgid "DastProfiles|Are you sure you want to delete this profile?"
@@ -10981,6 +11085,9 @@ msgstr ""
msgid "DastProfiles|Branch missing"
msgstr ""
+msgid "DastProfiles|Choose a scan method"
+msgstr ""
+
msgid "DastProfiles|Could not create the scanner profile. Please try again."
msgstr ""
@@ -11050,7 +11157,13 @@ msgstr ""
msgid "DastProfiles|Excluded URLs"
msgstr ""
-msgid "DastProfiles|Excluded URLs (Optional)"
+msgid "DastProfiles|Excluded URLs (optional)"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths (optional)"
msgstr ""
msgid "DastProfiles|Hide debug messages"
@@ -11107,9 +11220,6 @@ msgstr ""
msgid "DastProfiles|Request headers"
msgstr ""
-msgid "DastProfiles|Rest API"
-msgstr ""
-
msgid "DastProfiles|Run the AJAX spider, in addition to the traditional spider, to crawl the target site."
msgstr ""
@@ -11119,6 +11229,9 @@ msgstr ""
msgid "DastProfiles|Save profile"
msgstr ""
+msgid "DastProfiles|Scan method"
+msgstr ""
+
msgid "DastProfiles|Scan mode"
msgstr ""
@@ -11197,12 +11310,24 @@ msgstr ""
msgid "DastProfiles|Website"
msgstr ""
+msgid "DastProfiles|What does each method do?"
+msgstr ""
+
msgid "DastProfiles|You can either choose a passive scan or validate the target site from the site profile management page. %{docsLinkStart}Learn more about site validation.%{docsLinkEnd}"
msgstr ""
msgid "DastProfiles|You cannot run an active scan against an unvalidated site."
msgstr ""
+msgid "DastProfiles|folder/dast_example.har or https://example.com/dast_example.har"
+msgstr ""
+
+msgid "DastProfiles|folder/example.postman_collection.json or https://example.com/"
+msgstr ""
+
+msgid "DastProfiles|folder/openapi.json or https://example.com/openapi.json"
+msgstr ""
+
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
@@ -11310,6 +11435,9 @@ msgstr ""
msgid "DatadogIntegration|API URL"
msgstr ""
+msgid "DatadogIntegration|Custom tags in Datadog. Enter one tag per line in the %{codeOpen}key:value%{codeClose} format. %{linkOpen}How do I use tags?%{linkClose}"
+msgstr ""
+
msgid "DatadogIntegration|Environment"
msgstr ""
@@ -11328,12 +11456,18 @@ msgstr ""
msgid "DatadogIntegration|Tag all data from this GitLab instance in Datadog. Useful when managing several self-managed deployments."
msgstr ""
+msgid "DatadogIntegration|Tags"
+msgstr ""
+
msgid "DatadogIntegration|The Datadog site to send data to. To send data to the EU site, use %{codeOpen}datadoghq.eu%{codeClose}."
msgstr ""
msgid "DatadogIntegration|Trace your GitLab pipelines with Datadog."
msgstr ""
+msgid "DatadogIntegration|have an invalid format"
+msgstr ""
+
msgid "Datasource name not found"
msgstr ""
@@ -11343,9 +11477,6 @@ msgstr ""
msgid "Date merged"
msgstr ""
-msgid "Date picker"
-msgstr ""
-
msgid "Date range"
msgstr ""
@@ -11499,9 +11630,6 @@ msgstr ""
msgid "Definition"
msgstr ""
-msgid "Delayed Project Deletion (%{adjourned_deletion})"
-msgstr ""
-
msgid "DelayedJobs|Are you sure you want to run %{jobName} immediately? Otherwise this job will run automatically after its timer finishes."
msgstr ""
@@ -11580,10 +11708,10 @@ msgstr ""
msgid "Delete pipeline"
msgstr ""
-msgid "Delete project"
+msgid "Delete pipeline schedule"
msgstr ""
-msgid "Delete project. Are you ABSOLUTELY SURE?"
+msgid "Delete project"
msgstr ""
msgid "Delete row"
@@ -11613,6 +11741,9 @@ msgstr ""
msgid "Delete this epic and all descendants?"
msgstr ""
+msgid "Delete this project"
+msgstr ""
+
msgid "Delete user list"
msgstr ""
@@ -11871,6 +12002,12 @@ msgstr ""
msgid "Deploy to..."
msgstr ""
+msgid "DeployBoards|To see deployment progress for your environments, make sure you are deploying to %{codeStart}$KUBE_NAMESPACE%{codeEnd} and annotating with %{codeStart}app.gitlab.com/app=$CI_PROJECT_PATH_SLUG%{codeEnd} and %{codeStart}app.gitlab.com/env=$CI_ENVIRONMENT_SLUG%{codeEnd}."
+msgstr ""
+
+msgid "DeployBoard|Kubernetes Pods"
+msgstr ""
+
msgid "DeployFreeze|Add a freeze period to prevent unintended releases during a period of time for a given environment. You must update the deployment jobs in %{filename} according to the deploy freezes added here. %{freeze_period_link_start}Learn more.%{freeze_period_link_end}"
msgstr ""
@@ -11955,9 +12092,6 @@ msgstr ""
msgid "DeployTokens|Active Deploy Tokens (%{active_tokens})"
msgstr ""
-msgid "DeployTokens|Allows read and write access to registry images."
-msgstr ""
-
msgid "DeployTokens|Allows read and write access to the package registry."
msgstr ""
@@ -11970,6 +12104,9 @@ msgstr ""
msgid "DeployTokens|Allows read-only access to the repository."
msgstr ""
+msgid "DeployTokens|Allows write access to registry images."
+msgstr ""
+
msgid "DeployTokens|Copy deploy token"
msgstr ""
@@ -12063,12 +12200,57 @@ msgstr ""
msgid "Deploying to AWS is easy with GitLab"
msgstr ""
+msgid "Deployment"
+msgstr ""
+
msgid "Deployment Frequency"
msgstr ""
+msgid "Deployment Target|Project deployment target (optional)"
+msgstr ""
+
+msgid "Deployment Target|Select the deployment target"
+msgstr ""
+
msgid "Deployment frequency"
msgstr ""
+msgid "DeploymentTarget|GitLab Pages"
+msgstr ""
+
+msgid "DeploymentTarget|Heroku"
+msgstr ""
+
+msgid "DeploymentTarget|Infrastructure provider (Terraform, Cloudformation, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Kubernetes (GKE, EKS, OpenShift, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Managed container runtime (Fargate, Cloud Run, DigitalOcean App)"
+msgstr ""
+
+msgid "DeploymentTarget|Mobile app store"
+msgstr ""
+
+msgid "DeploymentTarget|No deployment planned"
+msgstr ""
+
+msgid "DeploymentTarget|Other hosting service"
+msgstr ""
+
+msgid "DeploymentTarget|Registry (package or container)"
+msgstr ""
+
+msgid "DeploymentTarget|Self-managed container runtime (Podman, Docker Swarm, Docker Compose)"
+msgstr ""
+
+msgid "DeploymentTarget|Serverless backend (Lambda, Cloud functions)"
+msgstr ""
+
+msgid "DeploymentTarget|Virtual machine (for example, EC2)"
+msgstr ""
+
msgid "Deployments"
msgstr ""
@@ -12107,6 +12289,9 @@ msgstr ""
msgid "Deployment|This deployment was created using the API"
msgstr ""
+msgid "Deployment|Triggerer"
+msgstr ""
+
msgid "Deployment|Waiting"
msgstr ""
@@ -12134,6 +12319,18 @@ msgstr ""
msgid "Deprecated API rate limits"
msgstr ""
+msgid "Deprecations|Feature deprecation and removal"
+msgstr ""
+
+msgid "Deprecations|For information on a possible replacement %{epicStart} learn more about Opstrace %{epicEnd}."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7 and are %{epicStart} scheduled for removal %{epicEnd} in GitLab 15.0."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7, and are %{removal_link_start} scheduled for removal %{link_end} in GitLab 15.0. For information on a possible replacement, %{opstrace_link_start} learn more about Opstrace %{link_end}."
+msgstr ""
+
msgid "Deprioritize label"
msgstr ""
@@ -12379,10 +12576,10 @@ msgstr ""
msgid "DevopsAdoption|At least one deploy"
msgstr ""
-msgid "DevopsAdoption|At least one issue opened"
+msgid "DevopsAdoption|At least one issue created"
msgstr ""
-msgid "DevopsAdoption|At least one merge request opened"
+msgid "DevopsAdoption|At least one merge request created"
msgstr ""
msgid "DevopsAdoption|At least one pipeline successfully run"
@@ -12583,6 +12780,9 @@ msgstr ""
msgid "Direct member"
msgstr ""
+msgid "Direct members"
+msgstr ""
+
msgid "Direct non-authenticated users to this page."
msgstr ""
@@ -12699,6 +12899,9 @@ msgid_plural "Dismiss %d selected vulnerabilities as"
msgstr[0] ""
msgstr[1] ""
+msgid "Dismiss Alert"
+msgstr ""
+
msgid "Dismiss merge request promotion"
msgstr ""
@@ -12726,9 +12929,15 @@ msgstr ""
msgid "Display alerts from all configured monitoring tools."
msgstr ""
+msgid "Display milestones"
+msgstr ""
+
msgid "Display name"
msgstr ""
+msgid "Display progress of child issues"
+msgstr ""
+
msgid "Display rendered file"
msgstr ""
@@ -12834,6 +13043,9 @@ msgstr ""
msgid "Download image"
msgstr ""
+msgid "Download payload"
+msgstr ""
+
msgid "Download raw data (.csv)"
msgstr ""
@@ -13011,6 +13223,9 @@ msgstr ""
msgid "Edit in Web IDE"
msgstr ""
+msgid "Edit in pipeline editor"
+msgstr ""
+
msgid "Edit in single-file editor"
msgstr ""
@@ -13053,6 +13268,9 @@ msgstr ""
msgid "Edit your most recent comment in a thread (from an empty textarea)"
msgstr ""
+msgid "Edit, lint, and visualize your pipeline."
+msgstr ""
+
msgid "Edited"
msgstr ""
@@ -13494,6 +13712,9 @@ msgstr ""
msgid "Enforce two-factor authentication for all user sign-ins."
msgstr ""
+msgid "Enhance security by storing service account keys in secret managers - learn more about %{docLinkStart}secret management with GitLab%{docLinkEnd}"
+msgstr ""
+
msgid "Ensure connectivity is available from the GitLab server to the Prometheus server"
msgstr ""
@@ -13554,6 +13775,9 @@ 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 following to confirm:"
+msgstr ""
+
msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
@@ -14084,9 +14308,6 @@ 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 ""
@@ -14222,6 +14443,9 @@ msgstr ""
msgid "Errors:"
msgstr ""
+msgid "Escalate this incident"
+msgstr ""
+
msgid "Escalation Policies"
msgstr ""
@@ -14234,6 +14458,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy"
+msgstr ""
+
msgid "Escalation policy:"
msgstr ""
@@ -14485,6 +14712,9 @@ msgstr ""
msgid "Existing sign in methods may be removed"
msgstr ""
+msgid "Exit."
+msgstr ""
+
msgid "Expand"
msgstr ""
@@ -14581,6 +14811,9 @@ msgstr ""
msgid "Explore public groups"
msgstr ""
+msgid "Explore public projects"
+msgstr ""
+
msgid "Explore snippets"
msgstr ""
@@ -14742,7 +14975,7 @@ msgid_plural "Failed to archive designs. Please try again."
msgstr[0] ""
msgstr[1] ""
-msgid "Failed to assign a reviewer because no user was found."
+msgid "Failed to assign a reviewer because no user was specified."
msgstr ""
msgid "Failed to assign a user because no user was found."
@@ -14808,10 +15041,10 @@ msgstr ""
msgid "Failed to find import label for Jira import."
msgstr ""
-msgid "Failed to generate export, please try again later."
+msgid "Failed to find users for %{missing}"
msgstr ""
-msgid "Failed to generate report, please try again after sometime"
+msgid "Failed to generate export, please try again later."
msgstr ""
msgid "Failed to get ref."
@@ -14910,6 +15143,9 @@ msgstr ""
msgid "Failed to remove a to-do item for the design."
msgstr ""
+msgid "Failed to remove attention because no user was found."
+msgstr ""
+
msgid "Failed to remove mirror."
msgstr ""
@@ -14922,6 +15158,9 @@ msgstr ""
msgid "Failed to remove user key."
msgstr ""
+msgid "Failed to request attention because no user was found."
+msgstr ""
+
msgid "Failed to reset key. Please try again."
msgstr ""
@@ -15003,6 +15242,9 @@ msgstr ""
msgid "Feature Flags"
msgstr ""
+msgid "Feature deprecation and removal"
+msgstr ""
+
msgid "Feature flag status"
msgstr ""
@@ -15500,7 +15742,7 @@ msgstr ""
msgid "For each job, re-use the project workspace. If the workspace doesn't exist, use %{code_open}git clone%{code_close}."
msgstr ""
-msgid "For example, the application using the token or the purpose of the token."
+msgid "For example, the application using the token or the purpose of the token. Do not give sensitive information for the name of the token, as it will be visible to all %{resource_type} members."
msgstr ""
msgid "For files larger than this limit, only index the file name. The file content is neither indexed nor searchable."
@@ -15584,9 +15826,6 @@ msgstr ""
msgid "ForkProject|Select a namespace"
msgstr ""
-msgid "ForkProject|Select a namespace to fork the project"
-msgstr ""
-
msgid "ForkProject|The project can be accessed by any logged in user."
msgstr ""
@@ -15683,6 +15922,9 @@ msgstr ""
msgid "Full name"
msgstr ""
+msgid "GCP region configured"
+msgstr ""
+
msgid "GPG Key ID:"
msgstr ""
@@ -15863,6 +16105,9 @@ msgstr ""
msgid "Geo|Failed"
msgstr ""
+msgid "Geo|Filter Geo sites"
+msgstr ""
+
msgid "Geo|Filter by name"
msgstr ""
@@ -16274,6 +16519,12 @@ msgstr ""
msgid "GitLab Issue"
msgstr ""
+msgid "GitLab KAS"
+msgstr ""
+
+msgid "GitLab Memberships CSV Export"
+msgstr ""
+
msgid "GitLab Pages"
msgstr ""
@@ -16322,6 +16573,9 @@ 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 free to use. Many features for larger teams are part of our %{link_start}paid products%{link_end}. You can try Ultimate for free without any obligation or payment details."
+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 ""
@@ -16448,7 +16702,7 @@ msgstr ""
msgid "GitLabPages|When enabled, all attempts to visit your website through HTTP are automatically redirected to HTTPS using a response with status code 301. Requires a valid certificate for all domains. %{docs_link_start}Learn more.%{link_end}"
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. %{docs_link_start}Learn more.%{link_end}"
+msgid "GitLabPages|When using Pages under the general domain of a GitLab instance (%{pages_host}), you cannot use HTTPS with subdomains of subdomains. If your namespace or groupname contains a dot, it does not work. This is a limitation of the HTTP Over TLS protocol. HTTP pages work if you don't redirect HTTP to HTTPS. %{docs_link_start}Learn more.%{link_end}"
msgstr ""
msgid "GitLabPages|With GitLab Pages you can host your static website directly from your GitLab repository. %{docs_link_start}Learn more.%{link_end}"
@@ -16625,9 +16879,6 @@ msgstr ""
msgid "Go to find file"
msgstr ""
-msgid "Go to fork"
-msgstr ""
-
msgid "Go to issue boards"
msgstr ""
@@ -16835,9 +17086,6 @@ msgstr ""
msgid "Group Hooks"
msgstr ""
-msgid "Group ID"
-msgstr ""
-
msgid "Group Owner must have signed in with SAML before enabling Group Managed Accounts"
msgstr ""
@@ -16865,9 +17113,6 @@ msgstr ""
msgid "Group by"
msgstr ""
-msgid "Group description"
-msgstr ""
-
msgid "Group description (optional)"
msgstr ""
@@ -16982,7 +17227,7 @@ msgstr ""
msgid "Group: %{name}"
msgstr ""
-msgid "GroupActivityMetrics|Issues opened"
+msgid "GroupActivityMetrics|Issues created"
msgstr ""
msgid "GroupActivityMetrics|Last 90 days"
@@ -16991,7 +17236,7 @@ msgstr ""
msgid "GroupActivityMetrics|Members added"
msgstr ""
-msgid "GroupActivityMetrics|Merge Requests opened"
+msgid "GroupActivityMetrics|Merge Requests created"
msgstr ""
msgid "GroupActivityMetrics|Recent activity"
@@ -17282,6 +17527,9 @@ msgstr ""
msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
+msgid "GroupSettings|Choose a group path that does not start with a dash or end with a period. It can also contain alphanumeric characters and underscores."
+msgstr ""
+
msgid "GroupSettings|Compliance frameworks"
msgstr ""
@@ -17315,7 +17563,7 @@ msgstr ""
msgid "GroupSettings|If not specified at the group or instance level, the default is %{default_initial_branch_name}. Does not affect existing repositories."
msgstr ""
-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."
+msgid "GroupSettings|If the parent group's visibility is lower than the group's current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility."
msgstr ""
msgid "GroupSettings|New runners registration token has been generated!"
@@ -17432,7 +17680,10 @@ msgstr "Grupos (%{count})"
msgid "Groups and projects"
msgstr ""
-msgid "Groups and subgroups"
+msgid "Groups are a great way to organize projects and people."
+msgstr ""
+
+msgid "Groups are the best way to manage projects and members."
msgstr ""
msgid "Groups to synchronize"
@@ -17543,13 +17794,16 @@ msgstr ""
msgid "GroupsTree|Are you sure you want to leave the \"%{fullName}\" group?"
msgstr ""
-msgid "GroupsTree|Edit group"
+msgid "GroupsTree|Delete"
+msgstr ""
+
+msgid "GroupsTree|Edit"
msgstr ""
msgid "GroupsTree|Failed to leave the group. Please make sure you are not the only owner."
msgstr ""
-msgid "GroupsTree|Leave this group"
+msgid "GroupsTree|Leave group"
msgstr ""
msgid "GroupsTree|Loading groups"
@@ -17561,9 +17815,57 @@ msgstr ""
msgid "GroupsTree|No groups or projects matched your search"
msgstr ""
+msgid "GroupsTree|Options"
+msgstr ""
+
msgid "GroupsTree|Search by name"
msgstr ""
+msgid "Groups|Avatar will be removed. Are you sure?"
+msgstr ""
+
+msgid "Groups|Changing group URL can have unintended side effects."
+msgstr ""
+
+msgid "Groups|Checking group URL availability..."
+msgstr ""
+
+msgid "Groups|Enter a descriptive name for your group."
+msgstr ""
+
+msgid "Groups|Group ID"
+msgstr ""
+
+msgid "Groups|Group URL"
+msgstr ""
+
+msgid "Groups|Group avatar"
+msgstr ""
+
+msgid "Groups|Group description (optional)"
+msgstr ""
+
+msgid "Groups|Group name"
+msgstr ""
+
+msgid "Groups|Group path is available."
+msgstr ""
+
+msgid "Groups|Group path is unavailable. Path has been replaced with a suggested available path."
+msgstr ""
+
+msgid "Groups|Learn more"
+msgstr ""
+
+msgid "Groups|Must start with letter, digit, emoji, or underscore. Can also contain periods, dashes, spaces, and parentheses."
+msgstr ""
+
+msgid "Groups|Remove avatar"
+msgstr ""
+
+msgid "Groups|Save changes"
+msgstr ""
+
msgid "Guideline"
msgstr ""
@@ -17573,6 +17875,9 @@ msgstr ""
msgid "HAR file path or URL"
msgstr ""
+msgid "HTTP Archive (HAR)"
+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 ""
@@ -17973,6 +18278,9 @@ msgstr ""
msgid "INFO: Your SSH key is expiring soon. Please generate a new key."
msgstr ""
+msgid "IP"
+msgstr ""
+
msgid "IP Address"
msgstr ""
@@ -18009,6 +18317,9 @@ msgstr ""
msgid "IdentityVerification|Verify your identity"
msgstr ""
+msgid "IdentityVerification|You can always verify your account at a later time to create a group."
+msgstr ""
+
msgid "If any indexed field exceeds this limit, it is truncated to this number of characters. The rest of the content is neither indexed nor searchable. This does not apply to repository and wiki indexing. For unlimited characters, set this to 0."
msgstr ""
@@ -18066,6 +18377,9 @@ msgstr ""
msgid "If you add %{codeStart}needs%{codeEnd} to jobs in your pipeline you'll be able to view the %{codeStart}needs%{codeEnd} relationships between jobs in this tab as a %{linkStart}Directed Acyclic Graph (DAG)%{linkEnd}."
msgstr ""
+msgid "If you are added to a project, it will be displayed here."
+msgstr ""
+
msgid "If you did not initiate these sign-in attempts, please reach out to your administrator or enable two-factor authentication (2FA) on your account."
msgstr ""
@@ -18372,12 +18686,24 @@ msgstr ""
msgid "InProductMarketing|3 ways to dive into GitLab CI/CD"
msgstr ""
+msgid "InProductMarketing|A single application eliminates complex integrations, data chokepoints, and toolchain maintenance, resulting in greater productivity and lower cost."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features, build more efficiently, strengthen security and compliance."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features."
+msgstr ""
+
msgid "InProductMarketing|Actually, GitLab makes the team work (better)"
msgstr ""
msgid "InProductMarketing|And finally %{deploy_link} a Python application."
msgstr ""
+msgid "InProductMarketing|And many more..."
+msgstr ""
+
msgid "InProductMarketing|Are your runners ready?"
msgstr ""
@@ -18396,15 +18722,33 @@ msgstr ""
msgid "InProductMarketing|Blog"
msgstr ""
+msgid "InProductMarketing|Break down silos to coordinate seamlessly across development, operations, and security with a consistent experience across the development lifecycle."
+msgstr ""
+
+msgid "InProductMarketing|Burn up/down charts"
+msgstr ""
+
msgid "InProductMarketing|By enabling code owners and required merge approvals the right person will review the right MR. This is a win-win: cleaner code and a more efficient review process."
msgstr ""
msgid "InProductMarketing|Click on the number below that corresponds with your answer — 1 being very difficult, 5 being very easy."
msgstr ""
+msgid "InProductMarketing|Code owners"
+msgstr ""
+
msgid "InProductMarketing|Code owners and required merge approvals are part of the paid tiers of GitLab. You can start a free 30-day trial of GitLab Ultimate and enable these features in less than 5 minutes with no credit card required."
msgstr ""
+msgid "InProductMarketing|Code review analytics"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration across stages in GitLab"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration made easy"
+msgstr ""
+
msgid "InProductMarketing|Create a custom CI runner with just a few clicks"
msgstr ""
@@ -18414,12 +18758,21 @@ msgstr ""
msgid "InProductMarketing|Create a project in GitLab in 5 minutes"
msgstr ""
+msgid "InProductMarketing|Create well-defined workflows by using scoped labels on issues, merge requests, and epics. Labels with the same scope cannot be used together, which prevents conflicts."
+msgstr ""
+
msgid "InProductMarketing|Create your first project!"
msgstr ""
+msgid "InProductMarketing|Define who owns specific files or directories, so the right reviewers are suggested when a merge request introduces changes to those files."
+msgstr ""
+
msgid "InProductMarketing|Deliver Better Products Faster"
msgstr ""
+msgid "InProductMarketing|Dependency scanning"
+msgstr ""
+
msgid "InProductMarketing|Did you know teams that use GitLab are far more efficient?"
msgstr ""
@@ -18429,15 +18782,27 @@ msgstr ""
msgid "InProductMarketing|Dig in and create a project and a repo"
msgstr ""
+msgid "InProductMarketing|Discover Premium & Ultimate"
+msgstr ""
+
+msgid "InProductMarketing|Discover Premium & Ultimate."
+msgstr ""
+
msgid "InProductMarketing|Do you have a minute?"
msgstr ""
msgid "InProductMarketing|Do you have a teammate who would be perfect for this task?"
msgstr ""
+msgid "InProductMarketing|Dynamic application security testing"
+msgstr ""
+
msgid "InProductMarketing|Easy"
msgstr ""
+msgid "InProductMarketing|Epics"
+msgstr ""
+
msgid "InProductMarketing|Expand your DevOps journey with a free GitLab trial"
msgstr ""
@@ -18459,9 +18824,15 @@ msgstr ""
msgid "InProductMarketing|Feel the need for speed?"
msgstr ""
+msgid "InProductMarketing|Find and fix bottlenecks in your code review process by understanding how long open merge requests have been in review."
+msgstr ""
+
msgid "InProductMarketing|Find out how your teams are really doing"
msgstr ""
+msgid "InProductMarketing|Find out if your external libraries are safe. Run dependency scanning jobs that check for known vulnerabilities in your external libraries."
+msgstr ""
+
msgid "InProductMarketing|Follow our steps"
msgstr ""
@@ -18498,6 +18869,9 @@ msgstr ""
msgid "InProductMarketing|GitLab is better with teammates to help out!"
msgstr ""
+msgid "InProductMarketing|GitLab is infrastructure agnostic (supporting GCP, AWS, Azure, OpenShift, VMWare, On Prem, Bare Metal, and more), offering a consistent workflow experience – irrespective of the environment."
+msgstr ""
+
msgid "InProductMarketing|GitLab provides static application security testing (SAST), dynamic application security testing (DAST), container scanning, and dependency scanning to help you deliver secure applications along with license compliance."
msgstr ""
@@ -18588,21 +18962,36 @@ msgstr ""
msgid "InProductMarketing|It's also possible to simply %{external_repo_link} in order to take advantage of GitLab's CI/CD."
msgstr ""
+msgid "InProductMarketing|Keep your code quality high by defining who should approve merge requests and how many approvals are required."
+msgstr ""
+
msgid "InProductMarketing|Launch GitLab CI/CD in 20 minutes or less"
msgstr ""
+msgid "InProductMarketing|Lower cost of development"
+msgstr ""
+
+msgid "InProductMarketing|Make it easier to collaborate on high-level ideas by grouping related issues in an epic."
+msgstr ""
+
msgid "InProductMarketing|Making the switch? It's easier than you think to import your projects into GitLab. Move %{github_link}, or import something %{bitbucket_link}."
msgstr ""
msgid "InProductMarketing|Master the art of importing!"
msgstr ""
+msgid "InProductMarketing|Merge request approval rule"
+msgstr ""
+
msgid "InProductMarketing|Move on to easily creating a Pages website %{ci_template_link}"
msgstr ""
msgid "InProductMarketing|Multiple owners, confusing workstreams? We've got you covered"
msgstr ""
+msgid "InProductMarketing|Multiple required approvers"
+msgstr ""
+
msgid "InProductMarketing|Need an alternative to importing?"
msgstr ""
@@ -18615,18 +19004,33 @@ msgstr ""
msgid "InProductMarketing|Our tool brings all the things together"
msgstr ""
+msgid "InProductMarketing|Protect your web application by using DAST to examine for vulnerabilities in deployed environments."
+msgstr ""
+
msgid "InProductMarketing|Rapid development, simplified"
msgstr ""
msgid "InProductMarketing|Reduce Security & Compliance Risk"
msgstr ""
+msgid "InProductMarketing|Require multiple approvers on a merge request, so you know it's in good shape before it's merged."
+msgstr ""
+
+msgid "InProductMarketing|Roadmaps"
+msgstr ""
+
+msgid "InProductMarketing|Scoped labels"
+msgstr ""
+
msgid "InProductMarketing|Security that's integrated into your development lifecycle"
msgstr ""
msgid "InProductMarketing|Sometimes you're not ready to make a full transition to a new tool. If you're not ready to fully commit, %{mirroring_link} gives you a safe way to try out GitLab in parallel with your current tool."
msgstr ""
+msgid "InProductMarketing|Speed. Efficiency. Trust."
+msgstr ""
+
msgid "InProductMarketing|Spin up an autoscaling runner in GitLab"
msgstr ""
@@ -18636,6 +19040,9 @@ msgstr ""
msgid "InProductMarketing|Start a Self-Managed trial"
msgstr ""
+msgid "InProductMarketing|Start a free trial"
+msgstr ""
+
msgid "InProductMarketing|Start a free trial of GitLab Ultimate – no credit card required"
msgstr ""
@@ -18702,6 +19109,9 @@ msgstr ""
msgid "InProductMarketing|To understand and get the most out of GitLab, start at the beginning and %{project_link}. In GitLab, repositories are part of a project, so after you've created your project you can go ahead and %{repo_link}."
msgstr ""
+msgid "InProductMarketing|Track completed issues in a chart, so you can see how a milestone is progressing at a glance."
+msgstr ""
+
msgid "InProductMarketing|Try GitLab Ultimate for free"
msgstr ""
@@ -18738,6 +19148,9 @@ msgstr ""
msgid "InProductMarketing|Very easy"
msgstr ""
+msgid "InProductMarketing|Visualize your epics and milestones in a timeline."
+msgstr ""
+
msgid "InProductMarketing|Want to host GitLab on your servers?"
msgstr ""
@@ -18759,6 +19172,9 @@ msgstr ""
msgid "InProductMarketing|YouTube"
msgstr ""
+msgid "InProductMarketing|Your software, deployed your way"
+msgstr ""
+
msgid "InProductMarketing|Your teams can be more efficient"
msgstr ""
@@ -18879,9 +19295,18 @@ msgstr ""
msgid "IncidentManagement|No incidents to display."
msgstr ""
+msgid "IncidentManagement|None"
+msgstr ""
+
msgid "IncidentManagement|Open"
msgstr ""
+msgid "IncidentManagement|Page your team with escalation policies"
+msgstr ""
+
+msgid "IncidentManagement|Paged"
+msgstr ""
+
msgid "IncidentManagement|Published"
msgstr ""
@@ -18891,6 +19316,9 @@ msgstr ""
msgid "IncidentManagement|Severity"
msgstr ""
+msgid "IncidentManagement|Status"
+msgstr ""
+
msgid "IncidentManagement|There are no closed incidents"
msgstr ""
@@ -18909,6 +19337,9 @@ msgstr ""
msgid "IncidentManagement|Unpublished"
msgstr ""
+msgid "IncidentManagement|Use escalation policies to automatically page your team when incidents are created."
+msgstr ""
+
msgid "IncidentSettings|Activate \"time to SLA\" countdown timer"
msgstr ""
@@ -18954,7 +19385,10 @@ msgstr ""
msgid "Incidents"
msgstr ""
-msgid "Incidents|Add a URL"
+msgid "Incidents|Add image details"
+msgstr ""
+
+msgid "Incidents|Add text or a link to display with your image. If you don't add either, the file name displays instead."
msgstr ""
msgid "Incidents|Drop or %{linkStart}upload%{linkEnd} a metric screenshot to attach it to the incident"
@@ -18969,10 +19403,10 @@ msgstr ""
msgid "Incidents|There was an issue loading metric images."
msgstr ""
-msgid "Incidents|There was an issue uploading your image."
+msgid "Incidents|There was an issue updating your image."
msgstr ""
-msgid "Incidents|You can optionally add a URL to link users to the original graph."
+msgid "Incidents|There was an issue uploading your image."
msgstr ""
msgid "Incident|Alert details"
@@ -18981,9 +19415,18 @@ msgstr ""
msgid "Incident|Are you sure you wish to delete this image?"
msgstr ""
+msgid "Incident|Delete image"
+msgstr ""
+
msgid "Incident|Deleting %{filename}"
msgstr ""
+msgid "Incident|Edit image text or link"
+msgstr ""
+
+msgid "Incident|Editing %{filename}"
+msgstr ""
+
msgid "Incident|Metrics"
msgstr ""
@@ -19253,12 +19696,18 @@ msgstr ""
msgid "Integrations|Branches for which notifications are to be sent"
msgstr ""
+msgid "Integrations|Clear if using a self-signed certificate."
+msgstr ""
+
msgid "Integrations|Comment detail:"
msgstr ""
msgid "Integrations|Comment settings:"
msgstr ""
+msgid "Integrations|Connection details"
+msgstr ""
+
msgid "Integrations|Connection failed. Please check your settings."
msgstr ""
@@ -19283,6 +19732,9 @@ msgstr ""
msgid "Integrations|Enable GitLab.com slash commands in a Slack workspace."
msgstr ""
+msgid "Integrations|Enable SSL verification"
+msgstr ""
+
msgid "Integrations|Enable comments"
msgstr ""
@@ -19361,6 +19813,9 @@ msgstr ""
msgid "Integrations|Return to GitLab for Jira"
msgstr ""
+msgid "Integrations|SSL verification"
+msgstr ""
+
msgid "Integrations|Save settings?"
msgstr ""
@@ -19406,9 +19861,6 @@ msgstr ""
msgid "Integrations|Use default settings"
msgstr ""
-msgid "Integrations|When you mention a Jira issue in a commit or merge request, GitLab creates a remote link and comment (if enabled)."
-msgstr ""
-
msgid "Integrations|You can now close this window and return to the GitLab for Jira application."
msgstr ""
@@ -19433,9 +19885,6 @@ msgstr ""
msgid "Integrations|can't exceed %{recipients_limit}"
msgstr ""
-msgid "Interactive developer security education."
-msgstr ""
-
msgid "Interactive mode"
msgstr ""
@@ -19925,6 +20374,9 @@ msgstr ""
msgid "IssueAnalytics|Assignees"
msgstr ""
+msgid "IssueAnalytics|Created by"
+msgstr ""
+
msgid "IssueAnalytics|Due date"
msgstr ""
@@ -19937,9 +20389,6 @@ msgstr ""
msgid "IssueAnalytics|Milestone"
msgstr ""
-msgid "IssueAnalytics|Opened by"
-msgstr ""
-
msgid "IssueAnalytics|Status"
msgstr ""
@@ -20063,10 +20512,10 @@ msgstr ""
msgid "IssuesAnalytics|Avg/Month:"
msgstr ""
-msgid "IssuesAnalytics|Issues opened"
+msgid "IssuesAnalytics|Issues created"
msgstr ""
-msgid "IssuesAnalytics|Issues opened per month"
+msgid "IssuesAnalytics|Issues created per month"
msgstr ""
msgid "IssuesAnalytics|Last 12 months"
@@ -20093,6 +20542,9 @@ msgstr ""
msgid "It looks like you have some draft commits in this branch."
msgstr ""
+msgid "It looks like you're attempting to activate your subscription. Use %{a_start}the Subscription page%{a_end} instead."
+msgstr ""
+
msgid "It may be several days before you see feature usage data."
msgstr ""
@@ -20321,6 +20773,9 @@ msgstr ""
msgid "JiraConnect|You can now close this window and return to Jira."
msgstr ""
+msgid "JiraConnect|You don't have permission to create branches for this project. Select a different project or contact the project owner for access. %{linkStart}Learn more.%{linkEnd}"
+msgstr ""
+
msgid "JiraRequest|A connection error occurred while connecting to Jira. Try your request again."
msgstr ""
@@ -20369,13 +20824,13 @@ msgstr ""
msgid "JiraService|Define the type of Jira issue to create from a vulnerability."
msgstr ""
-msgid "JiraService|Displaying Jira issues while leaving the GitLab issue functionality enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
+msgid "JiraService|Displaying Jira issues while leaving GitLab issues also enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
msgstr ""
-msgid "JiraService|Enable Jira issues"
+msgid "JiraService|Enable Jira issue creation from vulnerabilities"
msgstr ""
-msgid "JiraService|Enable Jira issues creation from vulnerabilities"
+msgid "JiraService|Enable Jira issues"
msgstr ""
msgid "JiraService|Enable Jira transitions"
@@ -20492,16 +20947,19 @@ msgstr ""
msgid "JiraService|View Jira issues in GitLab"
msgstr ""
-msgid "JiraService|Warning: All GitLab users that have access to this GitLab project are able to view all issues from the Jira project specified below."
+msgid "JiraService|Warning: All GitLab users with access to this GitLab project can view all issues from the Jira project you select."
msgstr ""
msgid "JiraService|Web URL"
msgstr ""
-msgid "JiraService|Work on Jira issues without leaving GitLab. Adds a Jira menu to access your list of Jira issues and view any issue as read-only."
+msgid "JiraService|When a Jira issue is mentioned in a commit or merge request, a remote link and comment (if enabled) will be created."
+msgstr ""
+
+msgid "JiraService|Work on Jira issues without leaving GitLab. Add a Jira menu to access a read-only list of your Jira issues."
msgstr ""
-msgid "JiraService|You need to configure Jira before enabling this integration. For more details, read the %{jira_doc_link_start}Jira integration documentation%{link_end}."
+msgid "JiraService|You must configure Jira before enabling this integration. %{jira_doc_link_start}Learn more.%{link_end}"
msgstr ""
msgid "Job"
@@ -20513,9 +20971,6 @@ msgstr ""
msgid "Job Failed #%{build_id}"
msgstr ""
-msgid "Job ID"
-msgstr ""
-
msgid "Job artifact"
msgstr ""
@@ -20582,9 +21037,27 @@ msgstr ""
msgid "Jobs|You're about to retry a job that failed because it attempted to deploy code that is older than the latest deployment. Retrying this job could result in overwriting the environment with the older source code."
msgstr ""
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source} into %{target}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{ref}"
+msgstr ""
+
+msgid "Job|Are you sure you want to erase this job log and artifacts?"
+msgstr ""
+
msgid "Job|Browse"
msgstr ""
+msgid "Job|Cancel"
+msgstr ""
+
msgid "Job|Complete Raw"
msgstr ""
@@ -20594,6 +21067,9 @@ msgstr ""
msgid "Job|Erase job log and artifacts"
msgstr ""
+msgid "Job|Finished at"
+msgstr ""
+
msgid "Job|Job artifacts"
msgstr ""
@@ -20606,7 +21082,7 @@ msgstr ""
msgid "Job|Keep"
msgstr ""
-msgid "Job|Pipeline"
+msgid "Job|Retry"
msgstr ""
msgid "Job|Scroll to bottom"
@@ -20618,6 +21094,9 @@ msgstr ""
msgid "Job|Show complete raw"
msgstr ""
+msgid "Job|Status"
+msgstr ""
+
msgid "Job|The artifacts were removed"
msgstr ""
@@ -20645,21 +21124,12 @@ msgstr ""
msgid "Job|delayed"
msgstr ""
-msgid "Job|for"
-msgstr ""
-
-msgid "Job|into"
-msgstr ""
-
msgid "Job|manual"
msgstr ""
msgid "Job|triggered"
msgstr ""
-msgid "Job|with"
-msgstr ""
-
msgid "Join Zoom meeting"
msgstr ""
@@ -20762,9 +21232,6 @@ msgstr ""
msgid "Ki"
msgstr ""
-msgid "Kontra"
-msgstr ""
-
msgid "Kroki"
msgstr ""
@@ -21088,6 +21555,9 @@ msgstr ""
msgid "Learn more about Auto DevOps"
msgstr ""
+msgid "Learn more about GitLab"
+msgstr ""
+
msgid "Learn more about Needs relationships"
msgstr ""
@@ -21415,9 +21885,18 @@ msgstr ""
msgid "Licenses|Displays licenses detected in the project, based on the %{linkStart}latest successful%{linkEnd} scan"
msgstr ""
+msgid "Licenses|Drag your license file here or %{linkStart}click to upload%{linkEnd}."
+msgstr ""
+
+msgid "Licenses|Drop your license file to start the upload."
+msgstr ""
+
msgid "Licenses|Error fetching the license list. Please check your network connection and try again."
msgstr ""
+msgid "Licenses|Error: You are trying to upload something other than a file"
+msgstr ""
+
msgid "Licenses|License Compliance"
msgstr ""
@@ -21436,6 +21915,9 @@ msgstr ""
msgid "Licenses|Specified policies in this project"
msgstr ""
+msgid "Licenses|The file could not be uploaded."
+msgstr ""
+
msgid "Licenses|The license list details information about the licenses used within your project."
msgstr ""
@@ -21469,11 +21951,6 @@ msgstr ""
msgid "Limit the size of Sidekiq jobs stored in Redis."
msgstr ""
-msgid "Limited to showing %d event at most"
-msgid_plural "Limited to showing %d events at most"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Limiting mode"
msgstr ""
@@ -21483,6 +21960,9 @@ msgstr ""
msgid "Link"
msgstr ""
+msgid "Link (optional)"
+msgstr ""
+
msgid "Link Prometheus monitoring to GitLab."
msgstr ""
@@ -21519,6 +21999,9 @@ msgstr ""
msgid "Linked emails (%{email_count})"
msgstr ""
+msgid "Linked epics"
+msgstr ""
+
msgid "Linked issues"
msgstr ""
@@ -21546,6 +22029,15 @@ msgstr ""
msgid "List of all merge commits"
msgstr ""
+msgid "List of environments for this project"
+msgstr ""
+
+msgid "List of suitable GCP locations"
+msgstr ""
+
+msgid "List of users allowed to exceed the rate limit."
+msgstr ""
+
msgid "List options"
msgstr ""
@@ -21765,6 +22257,9 @@ msgstr ""
msgid "Maintenance mode"
msgstr ""
+msgid "Make adjustments to how your GitLab instance is set up."
+msgstr ""
+
msgid "Make and review changes in the browser with the Web IDE"
msgstr ""
@@ -21909,6 +22404,12 @@ msgstr ""
msgid "MarkdownEditor|Add italic text (%{modifier_key}I)"
msgstr ""
+msgid "MarkdownEditor|Add strikethrough text (%{modifierKey}⇧X)"
+msgstr ""
+
+msgid "MarkdownEditor|Add strikethrough text (%{modifier_key}⇧X)"
+msgstr ""
+
msgid "Marked For Deletion At - %{deletion_time}"
msgstr ""
@@ -22170,6 +22671,9 @@ msgstr ""
msgid "Maximum push size (MB)"
msgstr ""
+msgid "Maximum requests per 10 minutes per user"
+msgstr ""
+
msgid "Maximum requests per minute"
msgstr ""
@@ -22260,6 +22764,19 @@ msgstr ""
msgid "Members of a group may only view projects they have permission to access"
msgstr ""
+msgid "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seat in use and will be billed for the overage."
+msgid_plural "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seats in use and will be billed for the overage."
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "MembersOverage|You are about to incur additional charges"
+msgstr ""
+
+msgid "MembersOverage|Your subscription includes %d seat."
+msgid_plural "MembersOverage|Your subscription includes %d seats."
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Membership"
msgstr ""
@@ -22464,9 +22981,6 @@ msgstr ""
msgid "Merge request not merged"
msgstr ""
-msgid "Merge request pipelines 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 merge request pipelines."
-msgstr ""
-
msgid "Merge request reports"
msgstr ""
@@ -22563,13 +23077,13 @@ msgstr ""
msgid "MergeRequests|Create issue to resolve thread"
msgstr ""
-msgid "MergeRequests|Failed to squash. Should be done manually."
+msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Saving the comment failed"
+msgid "MergeRequests|Squashing failed: Squash the commits locally, resolve any conflicts, then push the branch."
msgstr ""
-msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
+msgid "MergeRequests|Squashing not allowed: This project doesn't allow you to squash commits when merging."
msgstr ""
msgid "MergeRequests|Thread stays resolved"
@@ -23410,6 +23924,18 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "MrList|Assigned to %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from assignee %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from reviewer %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Review requested from %{name}, go to their profile."
+msgstr ""
+
msgid "Multi-project"
msgstr ""
@@ -23443,7 +23969,7 @@ msgstr ""
msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "My Awesome Group"
+msgid "My awesome group"
msgstr ""
msgid "My company or team"
@@ -24065,9 +24591,6 @@ msgstr ""
msgid "No available branches"
msgstr ""
-msgid "No available groups to fork the project."
-msgstr ""
-
msgid "No branches found"
msgstr ""
@@ -24278,6 +24801,9 @@ msgstr ""
msgid "No ref selected"
msgstr ""
+msgid "No regions configured"
+msgstr ""
+
msgid "No related merge requests found."
msgstr ""
@@ -25082,6 +25608,9 @@ msgstr ""
msgid "Only reCAPTCHA v2 is supported:"
msgstr ""
+msgid "Only required if not using role instance credentials."
+msgstr ""
+
msgid "Only use lowercase letters, numbers, and underscores."
msgstr ""
@@ -25106,9 +25635,6 @@ msgstr ""
msgid "Open a CLI and connect to the cluster you want to install the agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
-msgid "Open epics"
-msgstr ""
-
msgid "Open errors"
msgstr ""
@@ -25148,7 +25674,7 @@ msgstr ""
msgid "Opened issues"
msgstr ""
-msgid "OpenedNDaysAgo|Opened"
+msgid "OpenedNDaysAgo|Created"
msgstr ""
msgid "Opens in a new window"
@@ -25193,9 +25719,6 @@ msgstr ""
msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
-msgid "Optional."
-msgstr ""
-
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
msgstr ""
@@ -25984,6 +26507,9 @@ msgstr ""
msgid "PerformanceBar|Memory"
msgstr ""
+msgid "PerformanceBar|Memory report"
+msgstr ""
+
msgid "PerformanceBar|Redis calls"
msgstr ""
@@ -26017,18 +26543,12 @@ msgstr ""
msgid "PerformanceBar|wall"
msgstr ""
-msgid "Performs a rebase but skips triggering a new pipeline"
-msgstr ""
-
msgid "Period in seconds"
msgstr ""
msgid "Permalink"
msgstr ""
-msgid "Permanently delete project"
-msgstr ""
-
msgid "Permanently remove group"
msgstr ""
@@ -26299,6 +26819,51 @@ msgstr ""
msgid "PipelineStatusTooltip|Pipeline: %{ci_status}"
msgstr ""
+msgid "PipelineWizardDefaultCommitMessage|Add %{filename}"
+msgstr ""
+
+msgid "PipelineWizardDefaultCommitMessage|Update %{filename}"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|At least one entry is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This field is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This value is not valid"
+msgstr ""
+
+msgid "PipelineWizardListWidget|add another step"
+msgstr ""
+
+msgid "PipelineWizardListWidget|remove step"
+msgstr ""
+
+msgid "PipelineWizard|Commit"
+msgstr ""
+
+msgid "PipelineWizard|Commit Message"
+msgstr ""
+
+msgid "PipelineWizard|Commit changes to your file"
+msgstr ""
+
+msgid "PipelineWizard|Commit file to Branch"
+msgstr ""
+
+msgid "PipelineWizard|Commit your new file"
+msgstr ""
+
+msgid "PipelineWizard|The file has been committed."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem committing the changes."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem while checking whether your file already exists in the specified branch."
+msgstr ""
+
msgid "Pipelines"
msgstr ""
@@ -26413,7 +26978,7 @@ msgstr ""
msgid "Pipelines|Project cache successfully reset."
msgstr ""
-msgid "Pipelines|Revoke"
+msgid "Pipelines|Revoke trigger"
msgstr ""
msgid "Pipelines|Something went wrong while cleaning runners cache."
@@ -26458,6 +27023,12 @@ msgstr ""
msgid "Pipelines|This is a child pipeline within the parent pipeline"
msgstr ""
+msgid "Pipelines|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipelines|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipelines|This pipeline will run code originating from a forked project merge request. This means that the code can potentially have security considerations like exposing CI variables."
msgstr ""
@@ -26500,9 +27071,6 @@ msgstr ""
msgid "Pipelines|Your changes have been successfully committed. Now redirecting to the new merge request page."
msgstr ""
-msgid "Pipelines|detached"
-msgstr ""
-
msgid "Pipelines|error"
msgstr ""
@@ -26512,10 +27080,13 @@ msgstr ""
msgid "Pipelines|latest"
msgstr ""
-msgid "Pipelines|stuck"
+msgid "Pipelines|merge request"
msgstr ""
-msgid "Pipelines|train"
+msgid "Pipelines|merge train"
+msgstr ""
+
+msgid "Pipelines|stuck"
msgstr ""
msgid "Pipelines|yaml invalid"
@@ -26647,6 +27218,12 @@ msgstr ""
msgid "Pipeline|This change will not change the overall test coverage if merged."
msgstr ""
+msgid "Pipeline|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipeline|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipeline|Trigger author"
msgstr ""
@@ -26671,6 +27248,12 @@ msgstr ""
msgid "Pipeline|for"
msgstr ""
+msgid "Pipeline|merge request"
+msgstr ""
+
+msgid "Pipeline|merge train"
+msgstr ""
+
msgid "Pipeline|on"
msgstr ""
@@ -26809,9 +27392,6 @@ msgstr ""
msgid "Please enter a valid time interval"
msgstr ""
-msgid "Please enter or upload a valid license."
-msgstr ""
-
msgid "Please enter your current password."
msgstr ""
@@ -26920,9 +27500,6 @@ msgstr ""
msgid "Please type %{phrase_code} to proceed or close this modal to cancel."
msgstr ""
-msgid "Please type the following to confirm:"
-msgstr ""
-
msgid "Please use this form to report to the admin users who create spam issues, comments or behave inappropriately."
msgstr ""
@@ -26950,12 +27527,27 @@ msgstr ""
msgid "Policies"
msgstr ""
+msgid "Policy '%{escalation_policy_name}' does not exist."
+msgstr ""
+
msgid "Policy management project does have any policies in %{policy_path}"
msgstr ""
msgid "Policy project doesn't exist"
msgstr ""
+msgid "PolicyRuleMultiSelect|%{firstLabel} +%{numberOfAdditionalLabels} more"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|All %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select all"
+msgstr ""
+
msgid "Polling interval multiplier"
msgstr ""
@@ -27184,6 +27776,9 @@ msgstr ""
msgid "Private projects can be created in your personal namespace with:"
msgstr ""
+msgid "Problem with %{name} command: %{message}."
+msgstr ""
+
msgid "Proceed"
msgstr ""
@@ -27658,6 +28253,9 @@ msgstr ""
msgid "Progress"
msgstr ""
+msgid "Progress tracking"
+msgstr ""
+
msgid "Project"
msgstr ""
@@ -27889,6 +28487,9 @@ msgstr ""
msgid "ProjectQualitySummary|Failure"
msgstr ""
+msgid "ProjectQualitySummary|Get insight into the overall percentage of tests in your project that succeed, fail and are skipped."
+msgstr ""
+
msgid "ProjectQualitySummary|Latest pipeline results"
msgstr ""
@@ -27907,6 +28508,12 @@ msgstr ""
msgid "ProjectQualitySummary|See project Code Coverage Statistics"
msgstr ""
+msgid "ProjectQualitySummary|Set up test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|Set up test runs (opens in a new tab)"
+msgstr ""
+
msgid "ProjectQualitySummary|Skipped"
msgstr ""
@@ -28183,13 +28790,19 @@ msgstr ""
msgid "ProjectSettings|LFS objects from this repository are available to forks. %{linkStart}How do I remove them?%{linkEnd}"
msgstr ""
+msgid "ProjectSettings|Learn about commit history."
+msgstr ""
+
+msgid "ProjectSettings|Leave empty to use default template."
+msgstr ""
+
msgid "ProjectSettings|Manage who can see the project in the public access directory."
msgstr ""
msgid "ProjectSettings|Manages large files such as audio, video, and graphics files."
msgstr ""
-msgid "ProjectSettings|Maximum 500 characters."
+msgid "ProjectSettings|Maximum %{maxLength} characters."
msgstr ""
msgid "ProjectSettings|Merge checks"
@@ -28330,6 +28943,9 @@ msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
msgstr ""
+msgid "ProjectSettings|The default template will be applied on save."
+msgstr ""
+
msgid "ProjectSettings|These checks must pass before merge requests can be merged."
msgstr ""
@@ -28384,6 +29000,9 @@ msgstr ""
msgid "ProjectSettings|What are badges?"
msgstr ""
+msgid "ProjectSettings|What are merge trains?"
+msgstr ""
+
msgid "ProjectSettings|When merge request pipelines are enabled in the CI/CD configuration file, pipelines validate the combined results of the source and target branches. %{link_start}How to configure merge request pipelines?%{link_end}"
msgstr ""
@@ -28501,6 +29120,9 @@ msgstr ""
msgid "Projects are organized into groups"
msgstr ""
+msgid "Projects are where you store your code, access issues, wiki and other features of GitLab."
+msgstr ""
+
msgid "Projects contributed to"
msgstr ""
@@ -28516,12 +29138,6 @@ msgstr ""
msgid "Projects to index"
msgstr ""
-msgid "Projects will be permanently deleted after a %{waiting_period}-day waiting period."
-msgstr ""
-
-msgid "Projects will be permanently deleted immediately."
-msgstr ""
-
msgid "Projects with critical vulnerabilities"
msgstr ""
@@ -28606,6 +29222,9 @@ msgstr ""
msgid "ProjectsNew|Import project"
msgstr ""
+msgid "ProjectsNew|Include a Getting Started README"
+msgstr ""
+
msgid "ProjectsNew|Initialize repository with a README"
msgstr ""
@@ -28621,6 +29240,9 @@ msgstr ""
msgid "ProjectsNew|Project description %{tag_start}(optional)%{tag_end}"
msgstr ""
+msgid "ProjectsNew|Recommended if you're new to GitLab"
+msgstr ""
+
msgid "ProjectsNew|Run CI/CD for external repository"
msgstr ""
@@ -29038,6 +29660,9 @@ msgstr ""
msgid "ProtectedBranch|Unprotect"
msgstr ""
+msgid "ProtectedBranch|Unprotect branch"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
@@ -29065,6 +29690,9 @@ msgstr ""
msgid "ProtectedEnvironment|Protected Environment (%{protected_environments_count})"
msgstr ""
+msgid "ProtectedEnvironment|Required approvals"
+msgstr ""
+
msgid "ProtectedEnvironment|Select an environment"
msgstr ""
@@ -29086,10 +29714,13 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|Unprotect tag"
+msgstr ""
+
msgid "ProtectedTags|default"
msgstr ""
-msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
+msgid "ProtectedTag|By default, protected tags restrict who can modify the tag."
msgstr ""
msgid "ProtectedTag|Learn more."
@@ -29152,6 +29783,9 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Public projects are an easy way to allow everyone to have read-only access."
+msgstr ""
+
msgid "Publish to status page"
msgstr ""
@@ -29308,9 +29942,6 @@ msgstr ""
msgid "QualitySummary|Project quality"
msgstr ""
-msgid "Quarters"
-msgstr ""
-
msgid "Query"
msgstr ""
@@ -29395,6 +30026,9 @@ msgstr ""
msgid "Read more about project permissions %{help_link_open}here%{help_link_close}"
msgstr ""
+msgid "Read more about related epics"
+msgstr ""
+
msgid "Read more about related issues"
msgstr ""
@@ -29425,10 +30059,7 @@ msgstr ""
msgid "Rebase source branch on the target branch."
msgstr ""
-msgid "Rebase without CI"
-msgstr ""
-
-msgid "Rebases and triggers a pipeline"
+msgid "Rebase without pipeline"
msgstr ""
msgid "Recaptcha verified?"
@@ -29479,9 +30110,6 @@ msgstr ""
msgid "Reconfigure"
msgstr ""
-msgid "Recovering projects"
-msgstr ""
-
msgid "Recovery Codes"
msgstr ""
@@ -29541,6 +30169,12 @@ msgstr ""
msgid "Regex pattern"
msgstr ""
+msgid "Region"
+msgstr ""
+
+msgid "Regions"
+msgstr ""
+
msgid "Register"
msgstr ""
@@ -29771,9 +30405,6 @@ msgstr ""
msgid "Remove all or specific reviewer(s)"
msgstr ""
-msgid "Remove approver"
-msgstr ""
-
msgid "Remove approvers"
msgstr ""
@@ -29789,6 +30420,9 @@ msgstr ""
msgid "Remove attention request"
msgstr ""
+msgid "Remove attention request(s)"
+msgstr ""
+
msgid "Remove avatar"
msgstr ""
@@ -29927,6 +30561,9 @@ msgstr ""
msgid "Removed an issue from an epic."
msgstr ""
+msgid "Removed attention from %{users_sentence}."
+msgstr ""
+
msgid "Removed attention request from @%{username}"
msgstr ""
@@ -29978,6 +30615,9 @@ msgstr ""
msgid "Removes an issue from an epic."
msgstr ""
+msgid "Removes attention from %{users_sentence}."
+msgstr ""
+
msgid "Removes parent epic %{epic_ref}."
msgstr ""
@@ -30089,6 +30729,9 @@ msgstr ""
msgid "Report abuse to admin"
msgstr ""
+msgid "Report is generating and will be sent to your email address."
+msgstr ""
+
msgid "Reported %{timeAgo} by %{reportedBy}"
msgstr ""
@@ -30378,6 +31021,15 @@ msgstr ""
msgid "Request attention"
msgstr ""
+msgid "Request attention from %{users_sentence}."
+msgstr ""
+
+msgid "Request attention from assignee or reviewer"
+msgstr ""
+
+msgid "Request attention from assignee(s) or reviewer(s)"
+msgstr ""
+
msgid "Request attention to review"
msgstr ""
@@ -30402,6 +31054,9 @@ msgstr ""
msgid "Requested %{time_ago}"
msgstr ""
+msgid "Requested attention from %{users_sentence}."
+msgstr ""
+
msgid "Requested attention from @%{username}"
msgstr ""
@@ -30616,6 +31271,9 @@ msgstr ""
msgid "Restore project"
msgstr ""
+msgid "Restoring projects"
+msgstr ""
+
msgid "Restoring the group will prevent the group, its subgroups and projects from being removed on this date."
msgstr ""
@@ -30646,6 +31304,9 @@ msgstr ""
msgid "Retry"
msgstr ""
+msgid "Retry failed jobs"
+msgstr ""
+
msgid "Retry job"
msgstr ""
@@ -30693,9 +31354,6 @@ msgstr ""
msgid "Review changes"
msgstr ""
-msgid "Review requested from %{name}"
-msgstr ""
-
msgid "Review requests for you"
msgstr ""
@@ -30860,6 +31518,9 @@ msgstr ""
msgid "Runners|Assigned Group"
msgstr ""
+msgid "Runners|Assigned Projects (%{projectCount})"
+msgstr ""
+
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30929,6 +31590,9 @@ msgstr ""
msgid "Runners|Instance"
msgstr ""
+msgid "Runners|Jobs"
+msgstr ""
+
msgid "Runners|Last contact"
msgstr ""
@@ -31022,9 +31686,6 @@ msgstr ""
msgid "Runners|Runner %{name} was deleted"
msgstr ""
-msgid "Runners|Runner ID"
-msgstr ""
-
msgid "Runners|Runner assigned to project."
msgstr ""
@@ -31172,6 +31833,9 @@ msgstr ""
msgid "Runners|stale"
msgstr ""
+msgid "Runner|This runner has not run any jobs."
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -31286,6 +31950,24 @@ msgstr ""
msgid "Saving project."
msgstr ""
+msgid "ScanResultPolicy|%{ifLabelStart}if%{ifLabelEnd} %{scanners} scan in an open merge request targeting the %{branches} branch(es) finds %{vulnerabilitiesAllowed} or more %{severities} vulnerabilities that are %{vulnerabilityStates}"
+msgstr ""
+
+msgid "ScanResultPolicy|%{thenLabelStart}Then%{thenLabelEnd} Require approval from %{approvalsRequired} of the following approvers: %{approvers}"
+msgstr ""
+
+msgid "ScanResultPolicy|add an approver"
+msgstr ""
+
+msgid "ScanResultPolicy|scanners"
+msgstr ""
+
+msgid "ScanResultPolicy|severity levels"
+msgstr ""
+
+msgid "ScanResultPolicy|vulnerability states"
+msgstr ""
+
msgid "Scanner"
msgstr ""
@@ -31418,6 +32100,9 @@ msgstr ""
msgid "Search for a user"
msgstr ""
+msgid "Search for an emoji"
+msgstr ""
+
msgid "Search for projects, issues, etc."
msgstr ""
@@ -31605,18 +32290,12 @@ msgstr ""
msgid "Secret Detection"
msgstr ""
-msgid "Secret access key"
-msgstr ""
-
msgid "Secret token"
msgstr ""
msgid "Secure token that identifies an external storage request."
msgstr ""
-msgid "SecureCodeWarrior"
-msgstr ""
-
msgid "Security"
msgstr ""
@@ -31641,9 +32320,6 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "Security training with guide and learning pathways."
-msgstr ""
-
msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
@@ -31746,7 +32422,7 @@ msgstr ""
msgid "SecurityConfiguration|Manage corpus"
msgstr ""
-msgid "SecurityConfiguration|Manage corpus files used as mutation sources in coverage fuzzing."
+msgid "SecurityConfiguration|Manage corpus files used as seed inputs with coverage-guided fuzzing."
msgstr ""
msgid "SecurityConfiguration|Manage profiles for use by DAST scans."
@@ -31812,15 +32488,15 @@ msgstr ""
msgid "SecurityOrchestration|.yaml preview"
msgstr ""
-msgid "SecurityOrchestration|Action"
-msgstr ""
-
msgid "SecurityOrchestration|Actions"
msgstr ""
msgid "SecurityOrchestration|Add rule"
msgstr ""
+msgid "SecurityOrchestration|After dismissing the alert, the information will never be shown again."
+msgstr ""
+
msgid "SecurityOrchestration|All policies"
msgstr ""
@@ -31836,7 +32512,7 @@ msgstr ""
msgid "SecurityOrchestration|Description"
msgstr ""
-msgid "SecurityOrchestration|Disabled"
+msgid "SecurityOrchestration|Don't show the alert anymore"
msgstr ""
msgid "SecurityOrchestration|Edit policy"
@@ -31845,13 +32521,13 @@ msgstr ""
msgid "SecurityOrchestration|Edit policy project"
msgstr ""
-msgid "SecurityOrchestration|Enabled"
+msgid "SecurityOrchestration|Empty policy name"
msgstr ""
-msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Enabled"
msgstr ""
-msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
msgstr ""
msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
@@ -31860,7 +32536,7 @@ msgstr ""
msgid "SecurityOrchestration|Invalid policy type"
msgstr ""
-msgid "SecurityOrchestration|Latest scan"
+msgid "SecurityOrchestration|Latest scan run against %{agent}"
msgstr ""
msgid "SecurityOrchestration|Network"
@@ -31869,15 +32545,27 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No actions defined - policy will not run."
+msgstr ""
+
+msgid "SecurityOrchestration|No description"
+msgstr ""
+
msgid "SecurityOrchestration|No rules defined - policy will not run."
msgstr ""
+msgid "SecurityOrchestration|Not enabled"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
msgid "SecurityOrchestration|Policies"
msgstr ""
+msgid "SecurityOrchestration|Policy Type"
+msgstr ""
+
msgid "SecurityOrchestration|Policy cannot be enabled for non-existing branches (%{branches})"
msgstr ""
@@ -31902,10 +32590,13 @@ msgstr ""
msgid "SecurityOrchestration|Require %{approvals} %{plural} from %{approvers} if any of the following occur:"
msgstr ""
-msgid "SecurityOrchestration|Rule"
+msgid "SecurityOrchestration|Rules"
msgstr ""
-msgid "SecurityOrchestration|Rules"
+msgid "SecurityOrchestration|Runs %{actions} and %{lastAction} scans"
+msgstr ""
+
+msgid "SecurityOrchestration|Runs a %{action} scan"
msgstr ""
msgid "SecurityOrchestration|Scan Execution"
@@ -31965,6 +32656,9 @@ msgstr ""
msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
+msgid "SecurityOrchestration|This view only shows scan results for the agent %{agent}. You can view scan results for all agents in the %{linkStart}Operational Vulnerabilities tab of the vulnerability report%{linkEnd}."
+msgstr ""
+
msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
@@ -32019,9 +32713,6 @@ msgstr ""
msgid "SecurityOrchestration|users with ids"
msgstr ""
-msgid "SecurityOrchestration|view results"
-msgstr ""
-
msgid "SecurityOrchestration|vulnerabilities"
msgstr ""
@@ -32691,22 +33382,19 @@ 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|In order to start using functions as a service, you must first install Knative on your Kubernetes cluster. %{linkStart}More information%{linkEnd}"
-msgstr ""
-
msgid "Serverless|Learn more about Serverless"
msgstr ""
msgid "Serverless|No functions available"
msgstr ""
-msgid "Serverless|Sign up for First Look"
+msgid "Serverless|Serverless was %{linkStart}deprecated%{linkEnd} in GitLab 14.3."
+msgstr ""
+
+msgid "Serverless|Serverless was %{postLinkStart}deprecated%{postLinkEnd}. But if you opt to use it, you must install Knative in your Kubernetes cluster first. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "Serverless|The deploy job has not finished."
@@ -32718,9 +33406,6 @@ 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 ""
@@ -32736,9 +33421,6 @@ msgstr ""
msgid "Service Account Key"
msgstr ""
-msgid "Service Accounts"
-msgstr ""
-
msgid "Service Accounts keys authorize GitLab to deploy your Google Cloud project"
msgstr ""
@@ -32748,10 +33430,10 @@ msgstr ""
msgid "Service Desk allows people to create issues in your GitLab instance without their own user account. It provides a unique email address for end users to create issues in a project. Replies can be sent either through the GitLab interface or by email. End users only see threads through email."
msgstr ""
-msgid "Service Usage Data"
+msgid "Service account generated successfully"
msgstr ""
-msgid "Service account generated successfully"
+msgid "Service accounts"
msgstr ""
msgid "Service ping is disabled in your configuration file, and cannot be enabled through this form."
@@ -32895,6 +33577,9 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
+msgid "Set the per-user rate limit for getting a user by ID via the API."
+msgstr ""
+
msgid "Set the per-user rate limit for notes created by web or API requests."
msgstr ""
@@ -33074,6 +33759,9 @@ msgstr ""
msgid "Shared runners details"
msgstr ""
+msgid "Shared runners enabled cannot be enabled until a valid credit card is on file"
+msgstr ""
+
msgid "Shared runners help link"
msgstr ""
@@ -33131,6 +33819,9 @@ msgstr ""
msgid "Show all issues."
msgstr ""
+msgid "Show all milestones"
+msgstr ""
+
msgid "Show all test cases."
msgstr ""
@@ -33167,6 +33858,9 @@ msgstr ""
msgid "Show file contents"
msgstr ""
+msgid "Show group milestones"
+msgstr ""
+
msgid "Show labels"
msgstr ""
@@ -33182,6 +33876,12 @@ msgstr ""
msgid "Show open epics"
msgstr ""
+msgid "Show project milestones"
+msgstr ""
+
+msgid "Show sub-group milestones"
+msgstr ""
+
msgid "Show the Closed list"
msgstr ""
@@ -33191,11 +33891,6 @@ msgstr ""
msgid "Show whitespace changes"
msgstr ""
-msgid "Showing %d event"
-msgid_plural "Showing %d events"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Showing %{conflict} between %{sourceBranch} and %{targetBranch}"
msgstr ""
@@ -33255,12 +33950,6 @@ msgstr ""
msgid "Sidebar|None"
msgstr ""
-msgid "Sidebar|Only numeral characters allowed"
-msgstr ""
-
-msgid "Sidebar|Weight"
-msgstr ""
-
msgid "Sidekiq job compression threshold (bytes)"
msgstr ""
@@ -33423,6 +34112,9 @@ msgstr ""
msgid "Slack logo"
msgstr ""
+msgid "SlackIntegration|Are you sure you want to remove this project from the Slack application?"
+msgstr ""
+
msgid "SlackIntegration|GitLab for Slack"
msgstr ""
@@ -33432,6 +34124,9 @@ msgstr ""
msgid "SlackIntegration|Project alias"
msgstr ""
+msgid "SlackIntegration|Remove project"
+msgstr ""
+
msgid "SlackIntegration|Select a GitLab project to link with your Slack workspace."
msgstr ""
@@ -33576,9 +34271,6 @@ msgstr ""
msgid "Something went wrong trying to load issue contacts."
msgstr ""
-msgid "Something went wrong when creating a work item. Please try again"
-msgstr ""
-
msgid "Something went wrong when reordering designs. Please try again"
msgstr ""
@@ -33672,9 +34364,6 @@ msgstr ""
msgid "Something went wrong while inserting your image. Please try again."
msgstr ""
-msgid "Something went wrong while merging this merge request. Please try again."
-msgstr ""
-
msgid "Something went wrong while obtaining the Let's Encrypt certificate."
msgstr ""
@@ -33996,10 +34685,10 @@ 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."
+msgid "SourcegraphAdmin|Learn more."
msgstr ""
-msgid "SourcegraphAdmin|More information"
+msgid "SourcegraphAdmin|Only public projects have code intelligence enabled and communicate with Sourcegraph."
msgstr ""
msgid "SourcegraphAdmin|Save changes"
@@ -34008,7 +34697,7 @@ msgstr ""
msgid "SourcegraphAdmin|Sourcegraph URL"
msgstr ""
-msgid "SourcegraphAdmin|e.g. https://sourcegraph.example.com"
+msgid "SourcegraphAdmin|https://sourcegraph.example.com"
msgstr ""
msgid "SourcegraphPreferences|This feature is experimental and currently limited to certain projects."
@@ -34143,6 +34832,9 @@ msgstr ""
msgid "Start date"
msgstr ""
+msgid "Start free trial"
+msgstr ""
+
msgid "Start merge train"
msgstr ""
@@ -34173,6 +34865,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started escalation for this incident."
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -34185,6 +34880,9 @@ msgstr ""
msgid "Starts at (UTC)"
msgstr ""
+msgid "Starts escalations for this incident"
+msgstr ""
+
msgid "Starts on"
msgstr ""
@@ -34446,6 +35144,9 @@ msgstr ""
msgid "Strikethrough"
msgstr ""
+msgid "Strikethrough text"
+msgstr ""
+
msgid "Subgroup information"
msgstr ""
@@ -34680,6 +35381,21 @@ msgstr ""
msgid "Subscriptions"
msgstr ""
+msgid "Subscriptions|Chat with sales"
+msgstr ""
+
+msgid "Subscriptions|Close"
+msgstr ""
+
+msgid "Subscriptions|Not ready to buy yet?"
+msgstr ""
+
+msgid "Subscriptions|Start a free trial"
+msgstr ""
+
+msgid "Subscriptions|We understand. Maybe you have some questions for our sales team, or maybe you'd like to try some of the paid features first. What would you like to do?"
+msgstr ""
+
msgid "Subscription|Your subscription for %{strong}%{namespace_name}%{strong_close} has expired and you are now on %{pricing_link_start}the GitLab Free tier%{pricing_link_end}. Don't worry, your data is safe. Get in touch with our support team (%{support_email}). They'll gladly help with your subscription renewal."
msgstr ""
@@ -34890,6 +35606,9 @@ msgstr ""
msgid "SuperSonics|Maximum users"
msgstr ""
+msgid "SuperSonics|Offline cloud"
+msgstr ""
+
msgid "SuperSonics|Paste your activation code"
msgstr ""
@@ -34956,6 +35675,12 @@ msgstr ""
msgid "SuperSonics|You do not have an active subscription"
msgstr ""
+msgid "SuperSonics|You have a future dated license"
+msgstr ""
+
+msgid "SuperSonics|You have added a license that activates on %{date}. Please see the subscription history table below for more details."
+msgstr ""
+
msgid "SuperSonics|You have successfully added a license that activates on %{date}. Please see the subscription history table below for more details."
msgstr ""
@@ -35115,6 +35840,9 @@ msgstr ""
msgid "Tag name is required"
msgstr ""
+msgid "Tag push"
+msgstr ""
+
msgid "Tag push events"
msgstr ""
@@ -35217,6 +35945,9 @@ msgstr ""
msgid "TagsPage|protected"
msgstr ""
+msgid "Take a look at the documentation to discover all of GitLab’s capabilities."
+msgstr ""
+
msgid "Target Branch"
msgstr ""
@@ -35619,6 +36350,9 @@ msgstr ""
msgid "Tests"
msgstr ""
+msgid "Text (optional)"
+msgstr ""
+
msgid "Text added to the body of all email messages. %{character_limit} character limit"
msgstr ""
@@ -35669,6 +36403,9 @@ msgstr ""
msgid "The CSV export will be created in the background. Once finished, it will be sent to %{email} in an attachment."
msgstr ""
+msgid "The CSV export you requested of all user memberships is attached to this email."
+msgstr ""
+
msgid "The GitLab subscription service (customers.gitlab.com) is currently experiencing an outage. You can monitor the status and get updates at %{linkStart}status.gitlab.com%{linkEnd}."
msgstr ""
@@ -35744,6 +36481,9 @@ 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 epic"
+msgstr ""
+
msgid "The current issue"
msgstr ""
@@ -35905,6 +36645,9 @@ msgstr ""
msgid "The latest pipeline for this merge request has failed."
msgstr ""
+msgid "The license key is invalid."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -35920,6 +36663,9 @@ msgstr ""
msgid "The license was successfully uploaded and will be active from %{starts_at}. You can see the details below."
msgstr ""
+msgid "The license you uploaded is invalid. If the issue persists, contact support at %{link}."
+msgstr ""
+
msgid "The list creation wizard is already open"
msgstr ""
@@ -36541,10 +37287,13 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} and everything this project contains. %{strongOpen}There is no going back%{strongClose}"
+msgstr ""
+
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains."
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}on %{date}%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains. %{strongOpen}There is no going back.%{strongClose}"
msgstr ""
msgid "This action will %{strongOpen}permanently remove%{strongClose} %{codeOpen}%{group}%{codeClose} %{strongOpen}immediately%{strongClose}."
@@ -36673,9 +37422,6 @@ msgstr ""
msgid "This file was modified for readability, and can't accept suggestions. Edit it directly."
msgstr ""
-msgid "This forked project has the following:"
-msgstr ""
-
msgid "This form is disabled in preview"
msgstr ""
@@ -36688,7 +37434,7 @@ msgstr ""
msgid "This group can't be removed because it is linked to a subscription. To remove this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
-msgid "This group can't be transfered because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
+msgid "This group can't be transferred because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
msgid "This group cannot be invited to a project inside a group with enforced SSO"
@@ -36715,6 +37461,9 @@ 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 incident is already escalated with '%{escalation_policy_name}'."
+msgstr ""
+
msgid "This invitation was sent to %{mail_to_invite_email}, but you are signed in as %{link_to_current_user} with email %{mail_to_current_user}."
msgstr ""
@@ -36733,9 +37482,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 merge train pipeline"
-msgstr ""
-
msgid "This is a private email address %{helpIcon} generated just for you. Anyone who has it can create issues or merge requests as if they were you. If that happens, %{resetLinkStart}reset this token%{resetLinkEnd}."
msgstr ""
@@ -36757,6 +37503,12 @@ msgstr ""
msgid "This is your current session"
msgstr ""
+msgid "This issue cannot be assigned to a confidential epic because it is public."
+msgstr ""
+
+msgid "This issue cannot be made public because it belongs to a confidential epic."
+msgstr ""
+
msgid "This issue is confidential and should only be visible to team members with at least Reporter access."
msgstr ""
@@ -36874,6 +37626,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 branch is protected from force push."
+msgstr ""
+
msgid "This merge request cannot be rebased while there are conflicts."
msgstr ""
@@ -36925,9 +37680,15 @@ msgstr ""
msgid "This pipeline was triggered by a schedule."
msgstr ""
+msgid "This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project"
msgstr ""
+msgid "This project can be restored until %{date}."
+msgstr ""
+
msgid "This project cannot be %{visibilityLevel} because the visibility of %{openShowLink}%{name}%{closeShowLink} is %{visibility}. To make this project %{visibilityLevel}, you must first %{openEditLink}change the visibility%{closeEditLink} of the parent group."
msgstr ""
@@ -36946,6 +37707,9 @@ msgstr ""
msgid "This project is %{strongStart}NOT%{strongEnd} a fork, and has the following:"
msgstr ""
+msgid "This project is %{strongStart}NOT%{strongEnd} a fork. This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -37637,6 +38401,9 @@ msgstr ""
msgid "Today"
msgstr ""
+msgid "Todos count"
+msgstr ""
+
msgid "Todos|Are you looking for things to do? Take a look at %{strongStart}%{openIssuesLinkStart}open issues%{openIssuesLinkEnd}%{strongEnd}, contribute to %{strongStart}%{mergeRequestLinkStart}a merge request%{mergeRequestLinkEnd}%{mergeRequestLinkEnd}%{strongEnd}, or mention someone in a comment to automatically assign them a new to-do item."
msgstr ""
@@ -37910,10 +38677,8 @@ msgstr ""
msgid "Trending"
msgstr ""
-msgid "Trials|%{planName} Trial %{enDash} %{num} day left"
-msgid_plural "Trials|%{planName} Trial %{enDash} %{num} days left"
-msgstr[0] ""
-msgstr[1] ""
+msgid "Trials|%{planName} Trial"
+msgstr ""
msgid "Trials|Compare all plans"
msgstr ""
@@ -37921,6 +38686,9 @@ msgstr ""
msgid "Trials|Create a new group to start your GitLab Ultimate trial."
msgstr ""
+msgid "Trials|Day %{daysUsed}/%{duration}"
+msgstr ""
+
msgid "Trials|Go back to GitLab"
msgstr ""
@@ -38170,7 +38938,7 @@ msgstr ""
msgid "URL is triggered when repository is updated"
msgstr ""
-msgid "URL must be percent-encoded if neccessary."
+msgid "URL must be percent-encoded if necessary."
msgstr ""
msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
@@ -38389,6 +39157,9 @@ msgstr ""
msgid "Unlock account"
msgstr ""
+msgid "Unlock more features with GitLab Ultimate"
+msgstr ""
+
msgid "Unlock the discussion"
msgstr ""
@@ -38452,6 +39223,9 @@ msgstr ""
msgid "Unsubscribes from this %{quick_action_target}."
msgstr ""
+msgid "Unsupported sort value."
+msgstr ""
+
msgid "Unsupported todo type passed. Supported todo types are: %{todo_types}"
msgstr ""
@@ -38680,6 +39454,9 @@ msgstr ""
msgid "UsageQuota|File attachments and smaller design graphics."
msgstr ""
+msgid "UsageQuota|From %{storage_enforcement_date} storage limits will apply to this namespace. View and manage your usage in %{strong_start}Group Settings &gt; Usage quotas%{strong_end}."
+msgstr ""
+
msgid "UsageQuota|Git repository."
msgstr ""
@@ -38740,6 +39517,9 @@ msgstr ""
msgid "UsageQuota|Storage type"
msgstr ""
+msgid "UsageQuota|Storage used"
+msgstr ""
+
msgid "UsageQuota|This is the total amount of storage used across your projects within this namespace."
msgstr ""
@@ -38935,6 +39715,12 @@ msgstr ""
msgid "Use hashed storage paths for newly created and renamed repositories. Always enabled since 13.0."
msgstr ""
+msgid "Use issue count"
+msgstr ""
+
+msgid "Use issue weight"
+msgstr ""
+
msgid "Use one line per URI"
msgstr ""
@@ -39316,6 +40102,9 @@ msgstr ""
msgid "Users"
msgstr ""
+msgid "Users API rate limit"
+msgstr ""
+
msgid "Users can launch a development environment from a GitLab browser tab when the %{linkStart}Gitpod%{linkEnd} integration is enabled."
msgstr ""
@@ -39641,6 +40430,9 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View group pipeline usage quota"
+msgstr ""
+
msgid "View incident details at"
msgstr ""
@@ -39793,6 +40585,9 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
+msgid "Vulnerability"
+msgstr ""
+
msgid "Vulnerability Report"
msgstr ""
@@ -39844,6 +40639,9 @@ msgstr ""
msgid "VulnerabilityManagement|An unverified non-confirmed finding"
msgstr ""
+msgid "VulnerabilityManagement|At least one identifier is required"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -39853,12 +40651,24 @@ msgstr ""
msgid "VulnerabilityManagement|Create Jira issue"
msgstr ""
+msgid "VulnerabilityManagement|Enter a name"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE code"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE identifier URL"
+msgstr ""
+
msgid "VulnerabilityManagement|Fetching linked Jira issues"
msgstr ""
msgid "VulnerabilityManagement|Manually add a vulnerability entry into the vulnerability report."
msgstr ""
+msgid "VulnerabilityManagement|Name is a required field"
+msgstr ""
+
msgid "VulnerabilityManagement|Needs triage"
msgstr ""
@@ -39874,6 +40684,18 @@ msgstr ""
msgid "VulnerabilityManagement|Select a method"
msgstr ""
+msgid "VulnerabilityManagement|Select a severity level"
+msgstr ""
+
+msgid "VulnerabilityManagement|Select a status"
+msgstr ""
+
+msgid "VulnerabilityManagement|Severity is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Something went wrong while creating vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -39898,6 +40720,12 @@ msgstr ""
msgid "VulnerabilityManagement|Something went wrong, could not update vulnerability state."
msgstr ""
+msgid "VulnerabilityManagement|Status is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Submit vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Summary, detailed description, steps to reproduce, etc."
msgstr ""
@@ -40093,6 +40921,9 @@ msgstr ""
msgid "WARNING:"
msgstr ""
+msgid "WARNING: This snippet contains hidden files which might be used to mask malicious behavior. Exercise caution if cloning and executing code from this snippet."
+msgstr ""
+
msgid "Wait for the file to load to copy its contents"
msgstr ""
@@ -40312,6 +41143,15 @@ msgstr ""
msgid "Webhooks|An issue is created, updated, closed, or reopened."
msgstr ""
+msgid "Webhooks|Are you sure you want to delete this group hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this project hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this webhook?"
+msgstr ""
+
msgid "Webhooks|Comments"
msgstr ""
@@ -40321,6 +41161,9 @@ msgstr ""
msgid "Webhooks|Confidential issues events"
msgstr ""
+msgid "Webhooks|Delete webhook"
+msgstr ""
+
msgid "Webhooks|Deployment events"
msgstr ""
@@ -40554,6 +41397,9 @@ msgstr ""
msgid "Wiki"
msgstr ""
+msgid "Wiki page"
+msgstr ""
+
msgid "Wiki page was successfully created."
msgstr ""
@@ -40659,7 +41505,7 @@ msgstr ""
msgid "WikiPageConflictMessage|Someone edited the page the same time you did. Please check out %{wikiLinkStart}the page%{wikiLinkEnd} and make sure your changes will not unintentionally remove theirs."
msgstr ""
-msgid "WikiPage|An error occured while trying to render the content editor. Please try again later."
+msgid "WikiPage|An error occurred while trying to render the content editor. Please try again later."
msgstr ""
msgid "WikiPage|Are you sure you want to switch back to the classic editor?"
@@ -40818,6 +41664,18 @@ msgstr ""
msgid "WorkItem|New Task"
msgstr ""
+msgid "WorkItem|Something went wrong when creating a work item. Please try again"
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching the work item. Please try again."
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching work item types. Please try again"
+msgstr ""
+
+msgid "WorkItem|Type"
+msgstr ""
+
msgid "WorkItem|Work Items"
msgstr ""
@@ -40884,7 +41742,10 @@ msgstr ""
msgid "You are about to add %{usersTag} people to the discussion. They will all receive a notification."
msgstr ""
-msgid "You are about to permanently delete this project"
+msgid "You are about to delete this forked project containing:"
+msgstr ""
+
+msgid "You are about to delete this project containing:"
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."
@@ -40905,6 +41766,9 @@ msgstr ""
msgid "You are attempting to update a file that has changed since you started editing it."
msgstr ""
+msgid "You are billed if you exceed this number. %{qsrOverageLinkStart}How does billing work?%{qsrOverageLinkEnd}"
+msgstr ""
+
msgid "You are connected to the Prometheus server, but there is currently no data to display."
msgstr ""
@@ -40962,6 +41826,9 @@ msgstr ""
msgid "You are not authorized to update this scanner profile"
msgstr ""
+msgid "You are not authorized to upload metric images"
+msgstr ""
+
msgid "You are now impersonating %{username}"
msgstr ""
@@ -41115,9 +41982,6 @@ msgstr ""
msgid "You can only upload one design when dropping onto an existing design."
msgstr ""
-msgid "You can recover this project until %{date}"
-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 ""
@@ -41166,9 +42030,6 @@ msgstr ""
msgid "You cannot write to this read-only GitLab instance."
msgstr ""
-msgid "You can’t %{tag_start}edit%{tag_end} files directly in this project. Fork this project and submit a merge request with your changes."
-msgstr ""
-
msgid "You can’t edit files directly in this project. Fork this project and submit a merge request with your changes."
msgstr ""
@@ -41321,9 +42182,6 @@ 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 set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
@@ -41354,12 +42212,6 @@ msgstr ""
msgid "You must have maintainer access to force delete a lock"
msgstr "Deves ter acesso de responsável para forçar o apagamento de um bloqueio"
-msgid "You must have permission to create a project in a group before forking."
-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 ""
@@ -41765,7 +42617,7 @@ msgstr ""
msgid "Your public email will be displayed on your public profile."
msgstr ""
-msgid "Your request for access could not be processed: %{error_meesage}"
+msgid "Your request for access could not be processed: %{error_message}"
msgstr ""
msgid "Your request for access has been queued for review."
@@ -41948,6 +42800,9 @@ msgstr ""
msgid "archived:"
msgstr ""
+msgid "artifacts"
+msgstr ""
+
msgid "assign yourself"
msgstr ""
@@ -41977,6 +42832,9 @@ msgstr[1] ""
msgid "branch name"
msgstr "nome do ramo"
+msgid "builds"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -42400,6 +43258,9 @@ msgstr ""
msgid "contact with same email already exists in group hierarchy"
msgstr ""
+msgid "container registry images"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -42439,6 +43300,9 @@ msgstr ""
msgid "data"
msgstr ""
+msgid "database"
+msgstr ""
+
msgid "date must not be after 9999-12-31"
msgstr ""
@@ -42462,9 +43326,6 @@ msgstr ""
msgid "design"
msgstr ""
-msgid "detached"
-msgstr ""
-
msgid "disabled"
msgstr ""
@@ -42713,7 +43574,7 @@ msgstr ""
msgid "is not a valid X509 certificate."
msgstr ""
-msgid "is not allowed for sign-up."
+msgid "is not allowed for sign-up. Please use your regular email address."
msgstr ""
msgid "is not allowed for this group."
@@ -42725,7 +43586,7 @@ msgstr ""
msgid "is not allowed since the group is not top-level group."
msgstr ""
-msgid "is not allowed."
+msgid "is not allowed. Please use your regular email address."
msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
@@ -42812,6 +43673,9 @@ msgstr ""
msgid "level: %{level}"
msgstr ""
+msgid "lfs objects"
+msgstr ""
+
msgid "limit of %{project_limit} reached"
msgstr ""
@@ -43031,6 +43895,9 @@ msgstr ""
msgid "mrWidget|Merge blocked: pipeline must succeed. It's waiting for a manual action to continue."
msgstr ""
+msgid "mrWidget|Merge blocked: pipeline must succeed. Push a commit that fixes the failure, or %{linkStart}learn about other solutions.%{linkEnd}"
+msgstr ""
+
msgid "mrWidget|Merge blocked: this merge request must be approved."
msgstr ""
@@ -43148,9 +44015,6 @@ msgstr ""
msgid "mrWidget|The changes were not merged into"
msgstr ""
-msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -43298,9 +44162,6 @@ msgstr ""
msgid "open issue"
msgstr ""
-msgid "opened %{timeAgo}"
-msgstr ""
-
msgid "or"
msgstr ""
@@ -43312,6 +44173,12 @@ msgid_plural "out of %d total tests"
msgstr[0] ""
msgstr[1] ""
+msgid "packages"
+msgstr ""
+
+msgid "pages"
+msgstr ""
+
msgid "parent"
msgid_plural "parents"
msgstr[0] ""
@@ -43461,6 +44328,9 @@ msgid_plural "replies"
msgstr[0] ""
msgstr[1] ""
+msgid "repositories"
+msgstr ""
+
msgid "repository:"
msgstr ""
@@ -43581,12 +44451,18 @@ msgstr ""
msgid "tag name"
msgstr ""
+msgid "terraform states"
+msgstr ""
+
msgid "the correct format."
msgstr ""
msgid "the file"
msgstr ""
+msgid "the following epic(s)"
+msgstr ""
+
msgid "the following issue(s)"
msgstr ""
@@ -43599,21 +44475,12 @@ msgstr ""
msgid "this document"
msgstr ""
-msgid "this issue cannot be assigned to a confidential epic since it is public"
-msgstr ""
-
-msgid "this issue cannot be made public since it belongs to a confidential epic"
-msgstr ""
-
msgid "time summary"
msgstr ""
msgid "toggle collapse"
msgstr ""
-msgid "train"
-msgstr ""
-
msgid "triggered"
msgstr ""
@@ -43742,3 +44609,6 @@ msgstr ""
msgid "{project}"
msgstr ""
+msgid "✔"
+msgstr ""
+
diff --git a/locale/ro_RO/gitlab.po b/locale/ro_RO/gitlab.po
index eeb6add7633..535f1d1bb2a 100644
--- a/locale/ro_RO/gitlab.po
+++ b/locale/ro_RO/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: ro\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2022-02-02 15:41\n"
+"PO-Revision-Date: 2022-03-01 20:35\n"
msgid " %{start} to %{end}"
msgstr " de la %{start} până la %{end}"
@@ -108,9 +108,9 @@ msgstr[2] "%d Altele"
msgid "%d Package"
msgid_plural "%d Packages"
-msgstr[0] "%d Pachet"
-msgstr[1] "%d Pachete"
-msgstr[2] "%d de Pachete"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
msgid "%d Scanned URL"
msgid_plural "%d Scanned URLs"
@@ -160,6 +160,12 @@ msgstr[0] "%d aprobator (ați aprobat)"
msgstr[1] "%d aprobatori (ați aprobat)"
msgstr[2] "%d de aprobatori (ați aprobat)"
+msgid "%d assigned issue"
+msgid_plural "%d assigned issues"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] "%d fișier modificat"
@@ -490,11 +496,29 @@ msgstr[0] "%d vulnerabilitate respinsă"
msgstr[1] "%d vulnerabilități respinse"
msgstr[2] "%d de vulnerabilități respinse"
-msgid "%d vulnerability updated"
-msgid_plural "%d vulnerabilities updated"
-msgstr[0] "%d vulnerabilitate actualizată"
-msgstr[1] "%d vulnerabilități actualizate"
-msgstr[2] "%d de vulnerabilități actualizate"
+msgid "%d vulnerability set to confirmed"
+msgid_plural "%d vulnerabilities set to confirmed"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
+msgid "%d vulnerability set to dismissed"
+msgid_plural "%d vulnerabilities set to dismissed"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
+msgid "%d vulnerability set to needs triage"
+msgid_plural "%d vulnerabilities set to needs triage"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
+msgid "%d vulnerability set to resolved"
+msgid_plural "%d vulnerabilities set to resolved"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
msgid "%d warning found:"
msgid_plural "%d warnings found:"
@@ -586,6 +610,12 @@ msgstr[2] "%{completedCount} din %{count} de sarcini completate"
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr "%{completedWeight} din %{totalWeight} greutate finalizată"
+msgid "%{completed} of %{total} issues closed"
+msgstr ""
+
+msgid "%{completed} of %{total} weight completed"
+msgstr ""
+
msgid "%{cores} cores"
msgstr "%{cores} nuclee"
@@ -940,6 +970,9 @@ msgstr "%{openedEpics} deschise, %{closedEpics} închise"
msgid "%{openedIssues} open, %{closedIssues} closed"
msgstr "%{openedIssues} deschis, %{closedIssues} închis"
+msgid "%{percentage}%% issues closed"
+msgstr ""
+
msgid "%{percentage}%% weight completed"
msgstr "%{percentage}%% greutate finalizată"
@@ -1384,6 +1417,9 @@ msgstr[0] "- Utilizator"
msgstr[1] "- Utilizatori"
msgstr[2] "- Utilizatori"
+msgid "- of - issues closed"
+msgstr ""
+
msgid "- of - weight completed"
msgstr "- de - greutate realizată"
@@ -1549,8 +1585,8 @@ msgstr "10-19 contribuții"
msgid "1000+"
msgstr "1000+"
-msgid "192.168.0.0/24"
-msgstr "192.168.0.0/24"
+msgid "192.168.0.0/24 or 2001:0DB8:1234::/48"
+msgstr ""
msgid "1st contribution!"
msgstr "Prima contribuție!"
@@ -1861,14 +1897,14 @@ msgstr "folder/openapi.json"
msgid "AWS Access Key"
msgstr "Cheia de acces AWS"
-msgid "AWS Access Key. Only required if not using role instance credentials"
-msgstr "Cheia de acces AWS. Necesară numai dacă nu se utilizează acreditările instanței de rol"
-
msgid "AWS Secret Access Key"
msgstr "Cheia secretă de acces AWS"
-msgid "AWS Secret Access Key. Only required if not using role instance credentials"
-msgstr "Cheia de acces secret AWS. Necesară numai dacă nu se utilizează acreditările instanței de rol"
+msgid "AWS access key ID (Optional)"
+msgstr ""
+
+msgid "AWS secret access key (Optional)"
+msgstr ""
msgid "AWS service error: %{error}"
msgstr "Eroare de serviciu AWS: %{error}"
@@ -1927,9 +1963,6 @@ msgstr "Accesul interzis. Verificați nivelul de acces."
msgid "Access granted"
msgstr "Acces acordat"
-msgid "Access key ID"
-msgstr ""
-
msgid "Access requests"
msgstr "Cereri de acces"
@@ -2104,8 +2137,8 @@ msgstr ""
msgid "Activity"
msgstr "Activitate"
-msgid "Activity|An error occured while retrieving activity. Reload the page to try again."
-msgstr "A apărut o eroare în timpul recuperării activității. Reîncărcați pagina pentru a încerca din nou."
+msgid "Activity|An error occurred while retrieving activity. Reload the page to try again."
+msgstr ""
msgid "Add"
msgstr "Adaugă"
@@ -2143,6 +2176,9 @@ msgstr "Adăugați o întâlnire Zoom"
msgid "Add a %{type}"
msgstr "Adăugați un %{type}"
+msgid "Add a GCP region"
+msgstr ""
+
msgid "Add a GPG key"
msgstr "Adăugați o cheie GPG"
@@ -2194,6 +2230,9 @@ msgstr "Adăugați o nouă problemă"
msgid "Add a numbered list"
msgstr "Adăugați o listă numerotată"
+msgid "Add a related epic"
+msgstr ""
+
msgid "Add a related issue"
msgstr "Adăugați o problemă conexă"
@@ -2308,6 +2347,9 @@ msgstr "Adăugați sau eliminați comiteri îmbinate anterior"
msgid "Add or subtract spent time"
msgstr "Adăugați sau scădeți timpul consumat"
+msgid "Add people"
+msgstr ""
+
msgid "Add previously merged commits"
msgstr "Adăugați commit-uri îmbinate anterior"
@@ -2374,6 +2416,9 @@ msgstr ""
msgid "Add webhook"
msgstr "Adăugare webhook"
+msgid "Add your team members and others to GitLab."
+msgstr ""
+
msgid "Add/remove"
msgstr "Adăugare/eliminare"
@@ -2507,7 +2552,7 @@ msgid "Admin mode enabled"
msgstr "Modul administrator activat"
msgid "Admin navigation"
-msgstr "Navigare administrator"
+msgstr ""
msgid "Admin notes"
msgstr "Note administrative"
@@ -3196,12 +3241,6 @@ msgstr "Opțiuni avansate de export"
msgid "AdvancedSearch|Reindex required"
msgstr ""
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. Permanently deleting this project will %{strongStart}immediately delete%{strongEnd} its repositories and %{strongStart}all related resources%{strongEnd}, including issues, merge requests etc."
-msgstr ""
-
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. You will lose this project's repository and %{strongStart}all related resources%{strongEnd}, including issues and merge requests."
-msgstr ""
-
msgid "After a successful password update you will be redirected to login screen."
msgstr "După o actualizare cu succes a parolei, veți fi redirecționat către ecranul de autentificare."
@@ -3232,6 +3271,9 @@ msgstr "Cheia API Akismet"
msgid "Akismet helps prevent the creation of spam issues in public projects."
msgstr ""
+msgid "Alert"
+msgstr ""
+
msgid "AlertManagement|Acknowledged"
msgstr "Recunoscut"
@@ -3604,9 +3646,6 @@ msgstr "Toate adresele de e-mail vor fi folosite pentru a vă identifica contrib
msgid "All environments"
msgstr "Toate mediile"
-msgid "All epics"
-msgstr "Toate epicele"
-
msgid "All groups and projects"
msgstr "Toate grupurile și proiectele"
@@ -4345,13 +4384,16 @@ msgstr ""
msgid "ApplicationSettings|Approve users in the pending approval status?"
msgstr "Aprobați utilizatorii în statusul de aprobare în așteptare?"
-msgid "ApplicationSettings|By making this change, you will automatically approve %d user with the pending approval status."
-msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users with the pending approval status."
-msgstr[0] "Făcând această modificare, veți aproba automat %d utilizator cu statusul de aprobare în așteptare."
-msgstr[1] "Făcând această modificare, veți aproba automat %d utilizatori cu statusul de aprobare în așteptare."
-msgstr[2] "Făcând această modificare, veți aproba automat %d de utilizatori cu statusul de aprobare în așteptare."
+msgid "ApplicationSettings|Approve users who are pending approval?"
+msgstr ""
-msgid "ApplicationSettings|By making this change, you will automatically approve all users in pending approval status."
+msgid "ApplicationSettings|By making this change, you will automatically approve %d user who is pending approval."
+msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users who are pending approval."
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
+msgid "ApplicationSettings|By making this change, you will automatically approve all users who are pending approval."
msgstr ""
msgid "ApplicationSettings|Denied domains for sign-ups"
@@ -4762,12 +4804,12 @@ msgstr "Proiecte arhivate"
msgid "Archiving the project will make it entirely read-only. It is hidden from the dashboard and doesn't show up in searches. %{strong_start}The repository cannot be committed to, and no issues, comments, or other entities can be created.%{strong_end} %{link_start}Learn more.%{link_end}"
msgstr "Arhivarea proiectului va face ca acesta să fie în întregime numai pentru citire. Acesta este ascuns din tabloul de bord și nu apare în căutări. %{strong_start}repozitoriul nu poate accepta commit-uri și nu pot fi create probleme, comentarii sau alte entități.%{strong_end} %{link_start}Aflați mai multe.%{link_end}"
-msgid "Are you ABSOLUTELY SURE you wish to delete this project?"
-msgstr "Sunteți ABSOLUT SIGUR că doriți să ștergeți acest proiect?"
-
msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
msgstr "Sunteți ABSOLUT SIGUR că doriți să ștergeți acest grup?"
+msgid "Are you absolutely sure?"
+msgstr ""
+
msgid "Are you sure that you want to archive this project?"
msgstr "Sunteți sigur că doriți să arhivați acest proiect?"
@@ -4801,12 +4843,18 @@ msgstr "Sunteți sigur că doriți să ștergeți acest %{typeOfComment}?"
msgid "Are you sure you want to delete this SSH key?"
msgstr "Sunteți sigur că doriți să ștergeți această cheie SSH?"
+msgid "Are you sure you want to delete this comment?"
+msgstr ""
+
msgid "Are you sure you want to delete this deploy key?"
msgstr ""
msgid "Are you sure you want to delete this device? This action cannot be undone."
msgstr "Sunteți sigur că doriți să ștergeți acest dispozitiv? Această acțiune nu poate fi anulată."
+msgid "Are you sure you want to delete this label?"
+msgstr ""
+
msgid "Are you sure you want to delete this pipeline schedule?"
msgstr "Sunteți sigur că doriți să ștergeți acest program al pipeline-ului?"
@@ -4822,9 +4870,6 @@ msgstr "Sunteți sigur că doriți să renunțați la acest comentariu?"
msgid "Are you sure you want to discard your changes?"
msgstr "Sunteți sigur că doriți să renunțați la modificările dvs.?"
-msgid "Are you sure you want to erase this build?"
-msgstr "Sigur doriți să ștergeți acest build?"
-
msgid "Are you sure you want to import %d repository?"
msgid_plural "Are you sure you want to import %d repositories?"
msgstr[0] "Sunteți sigur că doriți să importați repozitoriul %d?"
@@ -4873,6 +4918,9 @@ msgstr "Sunteți sigur că doriți să eliminați această identitate?"
msgid "Are you sure you want to remove this list?"
msgstr "Sunteți sigur că doriți să eliminați această listă?"
+msgid "Are you sure you want to remove this nickname?"
+msgstr ""
+
msgid "Are you sure you want to reset the health check token?"
msgstr "Sunteți sigur că doriți să resetați tokenul de verificare a sănătății?"
@@ -4885,12 +4933,12 @@ msgstr "Sunteți sigur că doriți să reîncercați această migrare?"
msgid "Are you sure you want to revoke this %{type}? This action cannot be undone."
msgstr "Sunteți sigur că doriți să revocați acest %{type}? Această acțiune nu poate fi anulată."
-msgid "Are you sure you want to revoke this nickname?"
-msgstr "Sunteți sigur că doriți să eliminați această poreclă?"
-
msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
msgstr "Sunteți sigur că doriți să revocați acest token de acces personal? Această acțiune nu poate fi anulată."
+msgid "Are you sure you want to revoke this project access token? This action cannot be undone."
+msgstr ""
+
msgid "Are you sure you want to stop this environment?"
msgstr "Sunteți sigur că doriți să opriți acest mediu?"
@@ -5035,9 +5083,6 @@ msgstr "Atribuit lui %{assigneeName}"
msgid "Assigned to %{assignee_name}"
msgstr "Atribuit lui %{assignee_name}"
-msgid "Assigned to %{name}"
-msgstr "Atribuit la %{name}"
-
msgid "Assigned to me"
msgstr "Atribuit mie"
@@ -5104,6 +5149,9 @@ msgstr[2] "Se atașează %d de fișiere"
msgid "Attaching the file failed."
msgstr "Atașarea fișierului a eșuat."
+msgid "Attention"
+msgstr ""
+
msgid "Audit Events"
msgstr "Evenimente de audit"
@@ -5266,6 +5314,12 @@ msgstr "Autorizat la"
msgid "Authorized applications (%{size})"
msgstr "Aplicații autorizate (%{size})"
+msgid "AuthorizedApplication|Are you sure you want to revoke this application?"
+msgstr ""
+
+msgid "AuthorizedApplication|Revoke application"
+msgstr ""
+
msgid "Authors: %{authors}"
msgstr "Autori: %{authors}"
@@ -6463,6 +6517,9 @@ msgstr "Lansări"
msgid "CICDAnalytics|Shared Runners Usage"
msgstr ""
+msgid "CICDAnalytics|Shared runner pipeline minute duration by month"
+msgstr ""
+
msgid "CICDAnalytics|Shared runner usage"
msgstr ""
@@ -6604,6 +6661,9 @@ msgstr "Poate fi suprascris în fiecare proiect."
msgid "Can create groups:"
msgstr "Poate crea grupuri:"
+msgid "Can not delete primary training"
+msgstr ""
+
msgid "Can't apply as the source branch was deleted."
msgstr "Nu se poate aplica deoarece ramura sursă a fost ștearsă."
@@ -6937,9 +6997,6 @@ msgstr "Schimbările aduse titlului nu au fost salvate"
msgid "Changing any setting here requires an application restart"
msgstr ""
-msgid "Changing group URL can have unintended side effects."
-msgstr "Schimbarea adresei URL a grupului poate avea efecte secundare neintenționate."
-
msgid "Charts can't be displayed as the request for data has timed out. %{documentationLink}"
msgstr ""
@@ -7027,9 +7084,6 @@ msgstr ""
msgid "Checking branch availability..."
msgstr "Verificarea disponibilității ramurilor…"
-msgid "Checking group URL availability..."
-msgstr ""
-
msgid "Checking group path availability..."
msgstr ""
@@ -7525,6 +7579,9 @@ msgstr ""
msgid "Clear recent searches"
msgstr ""
+msgid "Clear repository checks"
+msgstr ""
+
msgid "Clear search"
msgstr "Ștergeți căutarea"
@@ -7657,9 +7714,6 @@ msgstr "ÃŽnchis %{epicTimeagoDate}"
msgid "Closed MRs"
msgstr "Cereri de îmbinare închise"
-msgid "Closed epics"
-msgstr ""
-
msgid "Closed issues"
msgstr "Probleme închise"
@@ -7696,13 +7750,13 @@ msgstr ""
msgid "Cluster level"
msgstr ""
-msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
-msgstr "Tipul de cluster trebuie să fie specificat pentru Stages::ClusterEndpointInserter"
+msgid "Cluster type must be specified for Stages::ClusterEndpointInserter"
+msgstr ""
msgid "ClusterAgents|%{name} successfully deleted"
msgstr ""
-msgid "ClusterAgents|%{number} of %{total} Agents"
+msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
@@ -7744,6 +7798,15 @@ msgstr ""
msgid "ClusterAgents|Agent never connected to GitLab"
msgstr ""
+msgid "ClusterAgents|Agent version mismatch"
+msgstr ""
+
+msgid "ClusterAgents|Agent version mismatch and update"
+msgstr ""
+
+msgid "ClusterAgents|Agent version update required"
+msgstr ""
+
msgid "ClusterAgents|All"
msgstr ""
@@ -7768,7 +7831,7 @@ msgstr ""
msgid "ClusterAgents|Configuration"
msgstr ""
-msgid "ClusterAgents|Connect a cluster through the Agent"
+msgid "ClusterAgents|Connect a cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connect existing cluster"
@@ -7777,13 +7840,13 @@ msgstr ""
msgid "ClusterAgents|Connect with a certificate"
msgstr ""
-msgid "ClusterAgents|Connect with agent"
+msgid "ClusterAgents|Connect with an agent"
msgstr ""
msgid "ClusterAgents|Connect with the GitLab Agent"
msgstr ""
-msgid "ClusterAgents|Connect your cluster through the Agent"
+msgid "ClusterAgents|Connect your cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connected"
@@ -7843,7 +7906,10 @@ msgstr ""
msgid "ClusterAgents|How to register an agent?"
msgstr ""
-msgid "ClusterAgents|Install new Agent"
+msgid "ClusterAgents|How to update an agent?"
+msgstr ""
+
+msgid "ClusterAgents|Install a new agent"
msgstr ""
msgid "ClusterAgents|Last connected %{timeAgo}."
@@ -7870,7 +7936,7 @@ msgstr "Niciodată"
msgid "ClusterAgents|Never connected"
msgstr ""
-msgid "ClusterAgents|No Agents"
+msgid "ClusterAgents|No agents"
msgstr ""
msgid "ClusterAgents|No clusters connected through cluster certificates"
@@ -7930,6 +7996,9 @@ msgstr ""
msgid "ClusterAgents|The agent has not been connected in a long time. There might be a connectivity issue. Last contact was %{timeAgo}."
msgstr ""
+msgid "ClusterAgents|The agent version do not match each other across your cluster's pods. This can happen when a new agent version was just deployed and Kubernetes is shutting down the old pods."
+msgstr ""
+
msgid "ClusterAgents|The recommended installation method includes the token. If you want to follow the advanced installation method provided in the docs, make sure you save the token value before you close this window."
msgstr ""
@@ -7978,6 +8047,9 @@ msgstr ""
msgid "ClusterAgents|You will need to create a token to connect to your agent"
msgstr ""
+msgid "ClusterAgents|Your agent version is out of sync with your GitLab version (v%{version}), which might cause compatibility problems. Update the agent installed on your cluster to the most recent version."
+msgstr ""
+
msgid "ClusterAgents|Your instance doesn't have the %{linkStart}GitLab Agent Server (KAS)%{linkEnd} set up. Ask a GitLab Administrator to install it."
msgstr ""
@@ -8854,9 +8926,6 @@ msgstr "ComboSearch nu este definită"
msgid "Comma-separated list of email addresses."
msgstr "Lista adreselor de e-mail separate prin virgulă."
-msgid "Comma-separated list of users allowed to exceed the rate limit."
-msgstr ""
-
msgid "Comma-separated, e.g. '1.1.1.1, 2.2.2.0/24'"
msgstr "Separate prin virgulă, de exemplu '1.1.1.1, 2.2.0/24'"
@@ -9184,6 +9253,12 @@ msgstr "ÃŽncredere"
msgid "Confidential"
msgstr "Confidențial"
+msgid "Confidential issue"
+msgstr ""
+
+msgid "Confidential note"
+msgstr ""
+
msgid "Confidentiality"
msgstr "Confidențialitate"
@@ -9217,6 +9292,9 @@ msgstr ""
msgid "Configure Dependency Scanning in `.gitlab-ci.yml`, creating this file if it does not already exist"
msgstr "Configurați scanarea dependenței în `.gitlab-ci.yml`, creând acest fișier dacă nu există deja"
+msgid "Configure GitLab"
+msgstr ""
+
msgid "Configure GitLab runners to start using the Web Terminal. %{helpStart}Learn more.%{helpEnd}"
msgstr ""
@@ -9265,6 +9343,15 @@ msgstr ""
msgid "Configure pipelines to deploy web apps, backend services, APIs and static resources to Google Cloud"
msgstr ""
+msgid "Configure region"
+msgstr ""
+
+msgid "Configure region for environment"
+msgstr ""
+
+msgid "Configure regions"
+msgstr ""
+
msgid "Configure repository mirroring."
msgstr ""
@@ -9298,6 +9385,9 @@ msgstr ""
msgid "Configure which lists are shown for anyone who visits this board"
msgstr ""
+msgid "Configure your environments to be deployed to specific geographical regions"
+msgstr ""
+
msgid "Confirm"
msgstr ""
@@ -10003,10 +10093,10 @@ msgstr "Sunteți sigur că doriți să ștergeți corpusul?"
msgid "CorpusManagement|Actions"
msgstr ""
-msgid "CorpusManagement|Corpus are used in fuzz testing as mutation source to Improve future testing."
+msgid "CorpusManagement|Corpus file"
msgstr ""
-msgid "CorpusManagement|Corpus file"
+msgid "CorpusManagement|Corpus files are used in coverage-guided fuzz testing as seed inputs to improve testing."
msgstr ""
msgid "CorpusManagement|Corpus files must be in *.zip format. Maximum 5 GB"
@@ -10060,6 +10150,9 @@ msgstr ""
msgid "Could not apply %{name} command."
msgstr ""
+msgid "Could not apply %{name} command. %{message}."
+msgstr ""
+
msgid "Could not authorize chat nickname. Try again!"
msgstr ""
@@ -10210,6 +10303,9 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
+msgid "Create a group"
+msgstr ""
+
msgid "Create a merge request"
msgstr ""
@@ -10234,6 +10330,9 @@ msgstr ""
msgid "Create a personal access token on your account to pull or push via %{protocol}."
msgstr ""
+msgid "Create a project"
+msgstr ""
+
msgid "Create an account using:"
msgstr ""
@@ -10597,6 +10696,9 @@ msgstr ""
msgid "Creation date"
msgstr ""
+msgid "Creator"
+msgstr ""
+
msgid "Credentials"
msgstr ""
@@ -10609,9 +10711,15 @@ msgstr ""
msgid "CredentialsInventory|Personal Access Tokens"
msgstr ""
+msgid "CredentialsInventory|Project Access Tokens"
+msgstr ""
+
msgid "CredentialsInventory|SSH Keys"
msgstr ""
+msgid "Credit card required to be on file in order to create a pipeline"
+msgstr ""
+
msgid "Credit card:"
msgstr ""
@@ -10795,9 +10903,6 @@ msgstr ""
msgid "Customer relations"
msgstr ""
-msgid "Customizable by an administrator."
-msgstr ""
-
msgid "Customizable by owners."
msgstr ""
@@ -10927,30 +11032,18 @@ msgstr "ar trebui să fie sub un grup"
msgid "CycleAnalytics|%{selectedLabelsCount} selected (%{maxLabels} max)"
msgstr ""
-msgid "CycleAnalytics|%{stageCount} stages selected"
-msgstr ""
-
-msgid "CycleAnalytics|All stages"
-msgstr ""
-
-msgid "CycleAnalytics|Average days to completion"
+msgid "CycleAnalytics|Average time to completion"
msgstr ""
msgid "CycleAnalytics|Date"
msgstr ""
-msgid "CycleAnalytics|Days to completion"
-msgstr ""
-
msgid "CycleAnalytics|Display chart filters"
msgstr ""
msgid "CycleAnalytics|Lead Time for Changes"
msgstr ""
-msgid "CycleAnalytics|No stages selected"
-msgstr ""
-
msgid "CycleAnalytics|Number of tasks"
msgstr ""
@@ -10981,18 +11074,30 @@ msgstr ""
msgid "CycleAnalytics|Showing data for group '%{groupName}' from %{createdAfter} to %{createdBefore}"
msgstr ""
-msgid "CycleAnalytics|Stages"
+msgid "CycleAnalytics|Stage time: %{title}"
msgstr ""
msgid "CycleAnalytics|Tasks by type"
msgstr ""
-msgid "CycleAnalytics|The average time spent in the selected stage for the items that were completed on each date. Data limited to the last 500 items."
+msgid "CycleAnalytics|The average time items spent in this stage. Data limited to items completed within this date range."
msgstr ""
msgid "CycleAnalytics|The given date range is larger than 180 days"
msgstr ""
+msgid "CycleAnalytics|The total time items spent across each value stream stage. Data limited to items completed within this date range."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Stage time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Total time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|Total time"
+msgstr ""
+
msgid "CycleAnalytics|Type of work"
msgstr ""
@@ -11005,9 +11110,6 @@ msgstr ""
msgid "CycleAnalytics|project dropdown filter"
msgstr ""
-msgid "CycleAnalytics|stage dropdown"
-msgstr ""
-
msgid "DAG visualization requires at least 3 dependent jobs."
msgstr ""
@@ -11107,10 +11209,16 @@ msgstr ""
msgid "DastProfiles|AJAX spider"
msgstr ""
+msgid "DastProfiles|API"
+msgstr ""
+
+msgid "DastProfiles|API endpoint URL"
+msgstr ""
+
msgid "DastProfiles|Active"
msgstr ""
-msgid "DastProfiles|Additional request headers (Optional)"
+msgid "DastProfiles|Additional request headers (optional)"
msgstr ""
msgid "DastProfiles|Are you sure you want to delete this profile?"
@@ -11125,6 +11233,9 @@ msgstr ""
msgid "DastProfiles|Branch missing"
msgstr ""
+msgid "DastProfiles|Choose a scan method"
+msgstr ""
+
msgid "DastProfiles|Could not create the scanner profile. Please try again."
msgstr ""
@@ -11194,7 +11305,13 @@ msgstr ""
msgid "DastProfiles|Excluded URLs"
msgstr ""
-msgid "DastProfiles|Excluded URLs (Optional)"
+msgid "DastProfiles|Excluded URLs (optional)"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths (optional)"
msgstr ""
msgid "DastProfiles|Hide debug messages"
@@ -11251,9 +11368,6 @@ msgstr ""
msgid "DastProfiles|Request headers"
msgstr ""
-msgid "DastProfiles|Rest API"
-msgstr ""
-
msgid "DastProfiles|Run the AJAX spider, in addition to the traditional spider, to crawl the target site."
msgstr ""
@@ -11263,6 +11377,9 @@ msgstr ""
msgid "DastProfiles|Save profile"
msgstr ""
+msgid "DastProfiles|Scan method"
+msgstr ""
+
msgid "DastProfiles|Scan mode"
msgstr ""
@@ -11341,12 +11458,24 @@ msgstr ""
msgid "DastProfiles|Website"
msgstr ""
+msgid "DastProfiles|What does each method do?"
+msgstr ""
+
msgid "DastProfiles|You can either choose a passive scan or validate the target site from the site profile management page. %{docsLinkStart}Learn more about site validation.%{docsLinkEnd}"
msgstr ""
msgid "DastProfiles|You cannot run an active scan against an unvalidated site."
msgstr "Nu puteți rula o scanare activă pe un site nevalidat."
+msgid "DastProfiles|folder/dast_example.har or https://example.com/dast_example.har"
+msgstr ""
+
+msgid "DastProfiles|folder/example.postman_collection.json or https://example.com/"
+msgstr ""
+
+msgid "DastProfiles|folder/openapi.json or https://example.com/openapi.json"
+msgstr ""
+
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
@@ -11455,6 +11584,9 @@ msgstr "(Avansat) Adresa URL completă pentru site-ul dvs. Datadog."
msgid "DatadogIntegration|API URL"
msgstr "API URL"
+msgid "DatadogIntegration|Custom tags in Datadog. Enter one tag per line in the %{codeOpen}key:value%{codeClose} format. %{linkOpen}How do I use tags?%{linkClose}"
+msgstr ""
+
msgid "DatadogIntegration|Environment"
msgstr "Mediu"
@@ -11473,12 +11605,18 @@ msgstr "Serviciu"
msgid "DatadogIntegration|Tag all data from this GitLab instance in Datadog. Useful when managing several self-managed deployments."
msgstr "Etichetați toate datele din această instanță GitLab în Datadog. Util la gestionarea mai multor implementări autogestionate."
+msgid "DatadogIntegration|Tags"
+msgstr ""
+
msgid "DatadogIntegration|The Datadog site to send data to. To send data to the EU site, use %{codeOpen}datadoghq.eu%{codeClose}."
msgstr "Site-ul Datadog către care trimiteți date. Pentru a trimite date către site-ul UE, utilizați %{codeOpen}datadoghq.eu%{codeClose}."
msgid "DatadogIntegration|Trace your GitLab pipelines with Datadog."
msgstr "Urmăriți conductele GitLab cu Datadog."
+msgid "DatadogIntegration|have an invalid format"
+msgstr ""
+
msgid "Datasource name not found"
msgstr ""
@@ -11488,9 +11626,6 @@ msgstr ""
msgid "Date merged"
msgstr ""
-msgid "Date picker"
-msgstr ""
-
msgid "Date range"
msgstr ""
@@ -11644,9 +11779,6 @@ msgstr ""
msgid "Definition"
msgstr ""
-msgid "Delayed Project Deletion (%{adjourned_deletion})"
-msgstr ""
-
msgid "DelayedJobs|Are you sure you want to run %{jobName} immediately? Otherwise this job will run automatically after its timer finishes."
msgstr ""
@@ -11725,10 +11857,10 @@ msgstr ""
msgid "Delete pipeline"
msgstr ""
-msgid "Delete project"
+msgid "Delete pipeline schedule"
msgstr ""
-msgid "Delete project. Are you ABSOLUTELY SURE?"
+msgid "Delete project"
msgstr ""
msgid "Delete row"
@@ -11758,6 +11890,9 @@ msgstr ""
msgid "Delete this epic and all descendants?"
msgstr ""
+msgid "Delete this project"
+msgstr ""
+
msgid "Delete user list"
msgstr ""
@@ -12022,6 +12157,12 @@ msgstr ""
msgid "Deploy to..."
msgstr ""
+msgid "DeployBoards|To see deployment progress for your environments, make sure you are deploying to %{codeStart}$KUBE_NAMESPACE%{codeEnd} and annotating with %{codeStart}app.gitlab.com/app=$CI_PROJECT_PATH_SLUG%{codeEnd} and %{codeStart}app.gitlab.com/env=$CI_ENVIRONMENT_SLUG%{codeEnd}."
+msgstr ""
+
+msgid "DeployBoard|Kubernetes Pods"
+msgstr ""
+
msgid "DeployFreeze|Add a freeze period to prevent unintended releases during a period of time for a given environment. You must update the deployment jobs in %{filename} according to the deploy freezes added here. %{freeze_period_link_start}Learn more.%{freeze_period_link_end}"
msgstr ""
@@ -12106,9 +12247,6 @@ msgstr ""
msgid "DeployTokens|Active Deploy Tokens (%{active_tokens})"
msgstr ""
-msgid "DeployTokens|Allows read and write access to registry images."
-msgstr "Permite citire și scriere la imaginile din registru."
-
msgid "DeployTokens|Allows read and write access to the package registry."
msgstr "Permite acces de citire și scriere la registrul de pachete."
@@ -12121,6 +12259,9 @@ msgstr "Permite numai acces de citire la registrul de pachete."
msgid "DeployTokens|Allows read-only access to the repository."
msgstr ""
+msgid "DeployTokens|Allows write access to registry images."
+msgstr ""
+
msgid "DeployTokens|Copy deploy token"
msgstr ""
@@ -12214,12 +12355,57 @@ msgstr ""
msgid "Deploying to AWS is easy with GitLab"
msgstr ""
+msgid "Deployment"
+msgstr ""
+
msgid "Deployment Frequency"
msgstr ""
+msgid "Deployment Target|Project deployment target (optional)"
+msgstr ""
+
+msgid "Deployment Target|Select the deployment target"
+msgstr ""
+
msgid "Deployment frequency"
msgstr ""
+msgid "DeploymentTarget|GitLab Pages"
+msgstr ""
+
+msgid "DeploymentTarget|Heroku"
+msgstr ""
+
+msgid "DeploymentTarget|Infrastructure provider (Terraform, Cloudformation, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Kubernetes (GKE, EKS, OpenShift, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Managed container runtime (Fargate, Cloud Run, DigitalOcean App)"
+msgstr ""
+
+msgid "DeploymentTarget|Mobile app store"
+msgstr ""
+
+msgid "DeploymentTarget|No deployment planned"
+msgstr ""
+
+msgid "DeploymentTarget|Other hosting service"
+msgstr ""
+
+msgid "DeploymentTarget|Registry (package or container)"
+msgstr ""
+
+msgid "DeploymentTarget|Self-managed container runtime (Podman, Docker Swarm, Docker Compose)"
+msgstr ""
+
+msgid "DeploymentTarget|Serverless backend (Lambda, Cloud functions)"
+msgstr ""
+
+msgid "DeploymentTarget|Virtual machine (for example, EC2)"
+msgstr ""
+
msgid "Deployments"
msgstr ""
@@ -12259,6 +12445,9 @@ msgstr ""
msgid "Deployment|This deployment was created using the API"
msgstr ""
+msgid "Deployment|Triggerer"
+msgstr ""
+
msgid "Deployment|Waiting"
msgstr ""
@@ -12286,6 +12475,18 @@ msgstr ""
msgid "Deprecated API rate limits"
msgstr ""
+msgid "Deprecations|Feature deprecation and removal"
+msgstr ""
+
+msgid "Deprecations|For information on a possible replacement %{epicStart} learn more about Opstrace %{epicEnd}."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7 and are %{epicStart} scheduled for removal %{epicEnd} in GitLab 15.0."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7, and are %{removal_link_start} scheduled for removal %{link_end} in GitLab 15.0. For information on a possible replacement, %{opstrace_link_start} learn more about Opstrace %{link_end}."
+msgstr ""
+
msgid "Deprioritize label"
msgstr ""
@@ -12532,11 +12733,11 @@ msgstr "Măcar o aprobare pe o cerere de îmbinare"
msgid "DevopsAdoption|At least one deploy"
msgstr ""
-msgid "DevopsAdoption|At least one issue opened"
+msgid "DevopsAdoption|At least one issue created"
msgstr ""
-msgid "DevopsAdoption|At least one merge request opened"
-msgstr "Măcar o cerere de îmbinare deschisă"
+msgid "DevopsAdoption|At least one merge request created"
+msgstr ""
msgid "DevopsAdoption|At least one pipeline successfully run"
msgstr ""
@@ -12739,6 +12940,9 @@ msgstr ""
msgid "Direct member"
msgstr ""
+msgid "Direct members"
+msgstr ""
+
msgid "Direct non-authenticated users to this page."
msgstr "Direcționați utilizatorii neautentificați către această pagină."
@@ -12856,6 +13060,9 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
+msgid "Dismiss Alert"
+msgstr ""
+
msgid "Dismiss merge request promotion"
msgstr ""
@@ -12883,9 +13090,15 @@ msgstr ""
msgid "Display alerts from all configured monitoring tools."
msgstr ""
+msgid "Display milestones"
+msgstr ""
+
msgid "Display name"
msgstr ""
+msgid "Display progress of child issues"
+msgstr ""
+
msgid "Display rendered file"
msgstr ""
@@ -12991,6 +13204,9 @@ msgstr ""
msgid "Download image"
msgstr ""
+msgid "Download payload"
+msgstr ""
+
msgid "Download raw data (.csv)"
msgstr ""
@@ -13168,6 +13384,9 @@ msgstr ""
msgid "Edit in Web IDE"
msgstr ""
+msgid "Edit in pipeline editor"
+msgstr ""
+
msgid "Edit in single-file editor"
msgstr ""
@@ -13210,6 +13429,9 @@ msgstr ""
msgid "Edit your most recent comment in a thread (from an empty textarea)"
msgstr ""
+msgid "Edit, lint, and visualize your pipeline."
+msgstr ""
+
msgid "Edited"
msgstr ""
@@ -13651,6 +13873,9 @@ msgstr "Impuneți autentificarea în doi pași"
msgid "Enforce two-factor authentication for all user sign-ins."
msgstr "Impuneți autentificarea în doi pași pentru toate autentificările utilizatorilor."
+msgid "Enhance security by storing service account keys in secret managers - learn more about %{docLinkStart}secret management with GitLab%{docLinkEnd}"
+msgstr ""
+
msgid "Ensure connectivity is available from the GitLab server to the Prometheus server"
msgstr ""
@@ -13711,6 +13936,9 @@ 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 following to confirm:"
+msgstr ""
+
msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
@@ -14242,9 +14470,6 @@ msgstr "A apărut o eroare actualizând statusul %{issuableType}"
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 ""
@@ -14380,6 +14605,9 @@ msgstr "Erori găsite pe linia %{line_number}: %{error_lines}. Vă rugăm să ve
msgid "Errors:"
msgstr ""
+msgid "Escalate this incident"
+msgstr ""
+
msgid "Escalation Policies"
msgstr ""
@@ -14392,6 +14620,9 @@ msgstr "Politicile de escaladare nu pot avea mai mult de %{rule_count} reguli"
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy"
+msgstr ""
+
msgid "Escalation policy:"
msgstr ""
@@ -14644,6 +14875,9 @@ msgstr ""
msgid "Existing sign in methods may be removed"
msgstr ""
+msgid "Exit."
+msgstr ""
+
msgid "Expand"
msgstr ""
@@ -14740,6 +14974,9 @@ msgstr "Explorați proiectele"
msgid "Explore public groups"
msgstr "Explorați grupurile publice"
+msgid "Explore public projects"
+msgstr ""
+
msgid "Explore snippets"
msgstr ""
@@ -14902,7 +15139,7 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
-msgid "Failed to assign a reviewer because no user was found."
+msgid "Failed to assign a reviewer because no user was specified."
msgstr ""
msgid "Failed to assign a user because no user was found."
@@ -14968,12 +15205,12 @@ msgstr ""
msgid "Failed to find import label for Jira import."
msgstr ""
+msgid "Failed to find users for %{missing}"
+msgstr ""
+
msgid "Failed to generate export, please try again later."
msgstr "Generarea exportului a eșuat, vă rugăm încercați mai târziu."
-msgid "Failed to generate report, please try again after sometime"
-msgstr ""
-
msgid "Failed to get ref."
msgstr ""
@@ -15070,6 +15307,9 @@ msgstr ""
msgid "Failed to remove a to-do item for the design."
msgstr ""
+msgid "Failed to remove attention because no user was found."
+msgstr ""
+
msgid "Failed to remove mirror."
msgstr ""
@@ -15082,6 +15322,9 @@ msgstr ""
msgid "Failed to remove user key."
msgstr ""
+msgid "Failed to request attention because no user was found."
+msgstr ""
+
msgid "Failed to reset key. Please try again."
msgstr ""
@@ -15163,6 +15406,9 @@ msgstr ""
msgid "Feature Flags"
msgstr ""
+msgid "Feature deprecation and removal"
+msgstr ""
+
msgid "Feature flag status"
msgstr ""
@@ -15661,7 +15907,7 @@ msgstr ""
msgid "For each job, re-use the project workspace. If the workspace doesn't exist, use %{code_open}git clone%{code_close}."
msgstr ""
-msgid "For example, the application using the token or the purpose of the token."
+msgid "For example, the application using the token or the purpose of the token. Do not give sensitive information for the name of the token, as it will be visible to all %{resource_type} members."
msgstr ""
msgid "For files larger than this limit, only index the file name. The file content is neither indexed nor searchable."
@@ -15745,9 +15991,6 @@ msgstr ""
msgid "ForkProject|Select a namespace"
msgstr ""
-msgid "ForkProject|Select a namespace to fork the project"
-msgstr ""
-
msgid "ForkProject|The project can be accessed by any logged in user."
msgstr ""
@@ -15844,6 +16087,9 @@ msgstr ""
msgid "Full name"
msgstr ""
+msgid "GCP region configured"
+msgstr ""
+
msgid "GPG Key ID:"
msgstr ""
@@ -16024,6 +16270,9 @@ msgstr ""
msgid "Geo|Failed"
msgstr ""
+msgid "Geo|Filter Geo sites"
+msgstr ""
+
msgid "Geo|Filter by name"
msgstr ""
@@ -16435,6 +16684,12 @@ msgstr ""
msgid "GitLab Issue"
msgstr ""
+msgid "GitLab KAS"
+msgstr ""
+
+msgid "GitLab Memberships CSV Export"
+msgstr ""
+
msgid "GitLab Pages"
msgstr ""
@@ -16483,6 +16738,9 @@ 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 free to use. Many features for larger teams are part of our %{link_start}paid products%{link_end}. You can try Ultimate for free without any obligation or payment details."
+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 ""
@@ -16609,7 +16867,7 @@ msgstr ""
msgid "GitLabPages|When enabled, all attempts to visit your website through HTTP are automatically redirected to HTTPS using a response with status code 301. Requires a valid certificate for all domains. %{docs_link_start}Learn more.%{link_end}"
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. %{docs_link_start}Learn more.%{link_end}"
+msgid "GitLabPages|When using Pages under the general domain of a GitLab instance (%{pages_host}), you cannot use HTTPS with subdomains of subdomains. If your namespace or groupname contains a dot, it does not work. This is a limitation of the HTTP Over TLS protocol. HTTP pages work if you don't redirect HTTP to HTTPS. %{docs_link_start}Learn more.%{link_end}"
msgstr ""
msgid "GitLabPages|With GitLab Pages you can host your static website directly from your GitLab repository. %{docs_link_start}Learn more.%{link_end}"
@@ -16786,9 +17044,6 @@ msgstr ""
msgid "Go to find file"
msgstr ""
-msgid "Go to fork"
-msgstr ""
-
msgid "Go to issue boards"
msgstr ""
@@ -16996,9 +17251,6 @@ msgstr ""
msgid "Group Hooks"
msgstr ""
-msgid "Group ID"
-msgstr ""
-
msgid "Group Owner must have signed in with SAML before enabling Group Managed Accounts"
msgstr ""
@@ -17026,9 +17278,6 @@ msgstr ""
msgid "Group by"
msgstr ""
-msgid "Group description"
-msgstr ""
-
msgid "Group description (optional)"
msgstr ""
@@ -17143,7 +17392,7 @@ msgstr ""
msgid "Group: %{name}"
msgstr ""
-msgid "GroupActivityMetrics|Issues opened"
+msgid "GroupActivityMetrics|Issues created"
msgstr ""
msgid "GroupActivityMetrics|Last 90 days"
@@ -17152,7 +17401,7 @@ msgstr ""
msgid "GroupActivityMetrics|Members added"
msgstr ""
-msgid "GroupActivityMetrics|Merge Requests opened"
+msgid "GroupActivityMetrics|Merge Requests created"
msgstr ""
msgid "GroupActivityMetrics|Recent activity"
@@ -17443,6 +17692,9 @@ msgstr ""
msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
+msgid "GroupSettings|Choose a group path that does not start with a dash or end with a period. It can also contain alphanumeric characters and underscores."
+msgstr ""
+
msgid "GroupSettings|Compliance frameworks"
msgstr ""
@@ -17476,7 +17728,7 @@ msgstr ""
msgid "GroupSettings|If not specified at the group or instance level, the default is %{default_initial_branch_name}. Does not affect existing repositories."
msgstr "Dacă nespecificată la nivel de grup sau instanță, valoarea implicită este %{default_initial_branch_name}. Nu afectează repozitorii existente."
-msgid "GroupSettings|If the parent group's visibility is lower than the group current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility."
+msgid "GroupSettings|If the parent group's visibility is lower than the group's current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility."
msgstr ""
msgid "GroupSettings|New runners registration token has been generated!"
@@ -17593,7 +17845,10 @@ msgstr ""
msgid "Groups and projects"
msgstr ""
-msgid "Groups and subgroups"
+msgid "Groups are a great way to organize projects and people."
+msgstr ""
+
+msgid "Groups are the best way to manage projects and members."
msgstr ""
msgid "Groups to synchronize"
@@ -17704,14 +17959,17 @@ msgstr ""
msgid "GroupsTree|Are you sure you want to leave the \"%{fullName}\" group?"
msgstr ""
-msgid "GroupsTree|Edit group"
+msgid "GroupsTree|Delete"
+msgstr ""
+
+msgid "GroupsTree|Edit"
msgstr ""
msgid "GroupsTree|Failed to leave the group. Please make sure you are not the only owner."
msgstr ""
-msgid "GroupsTree|Leave this group"
-msgstr "Părăsiți acest grup"
+msgid "GroupsTree|Leave group"
+msgstr ""
msgid "GroupsTree|Loading groups"
msgstr ""
@@ -17722,9 +17980,57 @@ msgstr ""
msgid "GroupsTree|No groups or projects matched your search"
msgstr ""
+msgid "GroupsTree|Options"
+msgstr ""
+
msgid "GroupsTree|Search by name"
msgstr ""
+msgid "Groups|Avatar will be removed. Are you sure?"
+msgstr ""
+
+msgid "Groups|Changing group URL can have unintended side effects."
+msgstr ""
+
+msgid "Groups|Checking group URL availability..."
+msgstr ""
+
+msgid "Groups|Enter a descriptive name for your group."
+msgstr ""
+
+msgid "Groups|Group ID"
+msgstr ""
+
+msgid "Groups|Group URL"
+msgstr ""
+
+msgid "Groups|Group avatar"
+msgstr ""
+
+msgid "Groups|Group description (optional)"
+msgstr ""
+
+msgid "Groups|Group name"
+msgstr ""
+
+msgid "Groups|Group path is available."
+msgstr ""
+
+msgid "Groups|Group path is unavailable. Path has been replaced with a suggested available path."
+msgstr ""
+
+msgid "Groups|Learn more"
+msgstr ""
+
+msgid "Groups|Must start with letter, digit, emoji, or underscore. Can also contain periods, dashes, spaces, and parentheses."
+msgstr ""
+
+msgid "Groups|Remove avatar"
+msgstr ""
+
+msgid "Groups|Save changes"
+msgstr ""
+
msgid "Guideline"
msgstr ""
@@ -17734,6 +18040,9 @@ msgstr ""
msgid "HAR file path or URL"
msgstr "Traiectoria fișierului HAR sau URL-ul"
+msgid "HTTP Archive (HAR)"
+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 ""
@@ -18136,6 +18445,9 @@ msgstr ""
msgid "INFO: Your SSH key is expiring soon. Please generate a new key."
msgstr ""
+msgid "IP"
+msgstr ""
+
msgid "IP Address"
msgstr ""
@@ -18172,6 +18484,9 @@ msgstr ""
msgid "IdentityVerification|Verify your identity"
msgstr ""
+msgid "IdentityVerification|You can always verify your account at a later time to create a group."
+msgstr ""
+
msgid "If any indexed field exceeds this limit, it is truncated to this number of characters. The rest of the content is neither indexed nor searchable. This does not apply to repository and wiki indexing. For unlimited characters, set this to 0."
msgstr ""
@@ -18229,6 +18544,9 @@ msgstr ""
msgid "If you add %{codeStart}needs%{codeEnd} to jobs in your pipeline you'll be able to view the %{codeStart}needs%{codeEnd} relationships between jobs in this tab as a %{linkStart}Directed Acyclic Graph (DAG)%{linkEnd}."
msgstr ""
+msgid "If you are added to a project, it will be displayed here."
+msgstr ""
+
msgid "If you did not initiate these sign-in attempts, please reach out to your administrator or enable two-factor authentication (2FA) on your account."
msgstr ""
@@ -18538,12 +18856,24 @@ msgstr ""
msgid "InProductMarketing|3 ways to dive into GitLab CI/CD"
msgstr ""
+msgid "InProductMarketing|A single application eliminates complex integrations, data chokepoints, and toolchain maintenance, resulting in greater productivity and lower cost."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features, build more efficiently, strengthen security and compliance."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features."
+msgstr ""
+
msgid "InProductMarketing|Actually, GitLab makes the team work (better)"
msgstr ""
msgid "InProductMarketing|And finally %{deploy_link} a Python application."
msgstr ""
+msgid "InProductMarketing|And many more..."
+msgstr ""
+
msgid "InProductMarketing|Are your runners ready?"
msgstr ""
@@ -18562,15 +18892,33 @@ msgstr ""
msgid "InProductMarketing|Blog"
msgstr ""
+msgid "InProductMarketing|Break down silos to coordinate seamlessly across development, operations, and security with a consistent experience across the development lifecycle."
+msgstr ""
+
+msgid "InProductMarketing|Burn up/down charts"
+msgstr ""
+
msgid "InProductMarketing|By enabling code owners and required merge approvals the right person will review the right MR. This is a win-win: cleaner code and a more efficient review process."
msgstr ""
msgid "InProductMarketing|Click on the number below that corresponds with your answer — 1 being very difficult, 5 being very easy."
msgstr "Faceți clic pe numărul de mai jos care corespunde răspunsului dvs. - 1 fiind foarte dificil, 5 fiind foarte ușor."
+msgid "InProductMarketing|Code owners"
+msgstr ""
+
msgid "InProductMarketing|Code owners and required merge approvals are part of the paid tiers of GitLab. You can start a free 30-day trial of GitLab Ultimate and enable these features in less than 5 minutes with no credit card required."
msgstr ""
+msgid "InProductMarketing|Code review analytics"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration across stages in GitLab"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration made easy"
+msgstr ""
+
msgid "InProductMarketing|Create a custom CI runner with just a few clicks"
msgstr "Creați un executor CI personalizat cu doar câteva clicuri"
@@ -18580,12 +18928,21 @@ msgstr "Creați un executor personalizat"
msgid "InProductMarketing|Create a project in GitLab in 5 minutes"
msgstr ""
+msgid "InProductMarketing|Create well-defined workflows by using scoped labels on issues, merge requests, and epics. Labels with the same scope cannot be used together, which prevents conflicts."
+msgstr ""
+
msgid "InProductMarketing|Create your first project!"
msgstr ""
+msgid "InProductMarketing|Define who owns specific files or directories, so the right reviewers are suggested when a merge request introduces changes to those files."
+msgstr ""
+
msgid "InProductMarketing|Deliver Better Products Faster"
msgstr "Livrați Produse mai Bune, mai Repede"
+msgid "InProductMarketing|Dependency scanning"
+msgstr ""
+
msgid "InProductMarketing|Did you know teams that use GitLab are far more efficient?"
msgstr ""
@@ -18595,15 +18952,27 @@ msgstr "Dificil"
msgid "InProductMarketing|Dig in and create a project and a repo"
msgstr ""
+msgid "InProductMarketing|Discover Premium & Ultimate"
+msgstr ""
+
+msgid "InProductMarketing|Discover Premium & Ultimate."
+msgstr ""
+
msgid "InProductMarketing|Do you have a minute?"
msgstr "Aveți un minut?"
msgid "InProductMarketing|Do you have a teammate who would be perfect for this task?"
msgstr ""
+msgid "InProductMarketing|Dynamic application security testing"
+msgstr ""
+
msgid "InProductMarketing|Easy"
msgstr "Ușor"
+msgid "InProductMarketing|Epics"
+msgstr ""
+
msgid "InProductMarketing|Expand your DevOps journey with a free GitLab trial"
msgstr "Extindeți-vă parcursul DevOps cu o perioadă de încercare gratuită GitLab"
@@ -18625,9 +18994,15 @@ msgstr "Feedback-ul utilizatorilor ca dvs. îmbunătățește cu adevărat produ
msgid "InProductMarketing|Feel the need for speed?"
msgstr ""
+msgid "InProductMarketing|Find and fix bottlenecks in your code review process by understanding how long open merge requests have been in review."
+msgstr ""
+
msgid "InProductMarketing|Find out how your teams are really doing"
msgstr ""
+msgid "InProductMarketing|Find out if your external libraries are safe. Run dependency scanning jobs that check for known vulnerabilities in your external libraries."
+msgstr ""
+
msgid "InProductMarketing|Follow our steps"
msgstr ""
@@ -18664,6 +19039,9 @@ msgstr ""
msgid "InProductMarketing|GitLab is better with teammates to help out!"
msgstr ""
+msgid "InProductMarketing|GitLab is infrastructure agnostic (supporting GCP, AWS, Azure, OpenShift, VMWare, On Prem, Bare Metal, and more), offering a consistent workflow experience – irrespective of the environment."
+msgstr ""
+
msgid "InProductMarketing|GitLab provides static application security testing (SAST), dynamic application security testing (DAST), container scanning, and dependency scanning to help you deliver secure applications along with license compliance."
msgstr ""
@@ -18754,21 +19132,36 @@ msgstr ""
msgid "InProductMarketing|It's also possible to simply %{external_repo_link} in order to take advantage of GitLab's CI/CD."
msgstr ""
+msgid "InProductMarketing|Keep your code quality high by defining who should approve merge requests and how many approvals are required."
+msgstr ""
+
msgid "InProductMarketing|Launch GitLab CI/CD in 20 minutes or less"
msgstr ""
+msgid "InProductMarketing|Lower cost of development"
+msgstr ""
+
+msgid "InProductMarketing|Make it easier to collaborate on high-level ideas by grouping related issues in an epic."
+msgstr ""
+
msgid "InProductMarketing|Making the switch? It's easier than you think to import your projects into GitLab. Move %{github_link}, or import something %{bitbucket_link}."
msgstr ""
msgid "InProductMarketing|Master the art of importing!"
msgstr ""
+msgid "InProductMarketing|Merge request approval rule"
+msgstr ""
+
msgid "InProductMarketing|Move on to easily creating a Pages website %{ci_template_link}"
msgstr ""
msgid "InProductMarketing|Multiple owners, confusing workstreams? We've got you covered"
msgstr ""
+msgid "InProductMarketing|Multiple required approvers"
+msgstr ""
+
msgid "InProductMarketing|Need an alternative to importing?"
msgstr ""
@@ -18781,18 +19174,33 @@ msgstr "Nu este necesar un card de credit."
msgid "InProductMarketing|Our tool brings all the things together"
msgstr ""
+msgid "InProductMarketing|Protect your web application by using DAST to examine for vulnerabilities in deployed environments."
+msgstr ""
+
msgid "InProductMarketing|Rapid development, simplified"
msgstr ""
msgid "InProductMarketing|Reduce Security & Compliance Risk"
msgstr "Reduceți Riscul de Securitate și Conformitate"
+msgid "InProductMarketing|Require multiple approvers on a merge request, so you know it's in good shape before it's merged."
+msgstr ""
+
+msgid "InProductMarketing|Roadmaps"
+msgstr ""
+
+msgid "InProductMarketing|Scoped labels"
+msgstr ""
+
msgid "InProductMarketing|Security that's integrated into your development lifecycle"
msgstr ""
msgid "InProductMarketing|Sometimes you're not ready to make a full transition to a new tool. If you're not ready to fully commit, %{mirroring_link} gives you a safe way to try out GitLab in parallel with your current tool."
msgstr ""
+msgid "InProductMarketing|Speed. Efficiency. Trust."
+msgstr ""
+
msgid "InProductMarketing|Spin up an autoscaling runner in GitLab"
msgstr ""
@@ -18802,6 +19210,9 @@ msgstr ""
msgid "InProductMarketing|Start a Self-Managed trial"
msgstr ""
+msgid "InProductMarketing|Start a free trial"
+msgstr ""
+
msgid "InProductMarketing|Start a free trial of GitLab Ultimate – no credit card required"
msgstr ""
@@ -18868,6 +19279,9 @@ msgstr ""
msgid "InProductMarketing|To understand and get the most out of GitLab, start at the beginning and %{project_link}. In GitLab, repositories are part of a project, so after you've created your project you can go ahead and %{repo_link}."
msgstr ""
+msgid "InProductMarketing|Track completed issues in a chart, so you can see how a milestone is progressing at a glance."
+msgstr ""
+
msgid "InProductMarketing|Try GitLab Ultimate for free"
msgstr ""
@@ -18904,6 +19318,9 @@ msgstr ""
msgid "InProductMarketing|Very easy"
msgstr ""
+msgid "InProductMarketing|Visualize your epics and milestones in a timeline."
+msgstr ""
+
msgid "InProductMarketing|Want to host GitLab on your servers?"
msgstr ""
@@ -18925,6 +19342,9 @@ msgstr ""
msgid "InProductMarketing|YouTube"
msgstr ""
+msgid "InProductMarketing|Your software, deployed your way"
+msgstr ""
+
msgid "InProductMarketing|Your teams can be more efficient"
msgstr ""
@@ -19045,9 +19465,18 @@ msgstr ""
msgid "IncidentManagement|No incidents to display."
msgstr ""
+msgid "IncidentManagement|None"
+msgstr ""
+
msgid "IncidentManagement|Open"
msgstr ""
+msgid "IncidentManagement|Page your team with escalation policies"
+msgstr ""
+
+msgid "IncidentManagement|Paged"
+msgstr ""
+
msgid "IncidentManagement|Published"
msgstr ""
@@ -19057,6 +19486,9 @@ msgstr ""
msgid "IncidentManagement|Severity"
msgstr ""
+msgid "IncidentManagement|Status"
+msgstr ""
+
msgid "IncidentManagement|There are no closed incidents"
msgstr ""
@@ -19075,6 +19507,9 @@ msgstr ""
msgid "IncidentManagement|Unpublished"
msgstr ""
+msgid "IncidentManagement|Use escalation policies to automatically page your team when incidents are created."
+msgstr ""
+
msgid "IncidentSettings|Activate \"time to SLA\" countdown timer"
msgstr ""
@@ -19120,7 +19555,10 @@ msgstr ""
msgid "Incidents"
msgstr ""
-msgid "Incidents|Add a URL"
+msgid "Incidents|Add image details"
+msgstr ""
+
+msgid "Incidents|Add text or a link to display with your image. If you don't add either, the file name displays instead."
msgstr ""
msgid "Incidents|Drop or %{linkStart}upload%{linkEnd} a metric screenshot to attach it to the incident"
@@ -19135,10 +19573,10 @@ msgstr ""
msgid "Incidents|There was an issue loading metric images."
msgstr ""
-msgid "Incidents|There was an issue uploading your image."
+msgid "Incidents|There was an issue updating your image."
msgstr ""
-msgid "Incidents|You can optionally add a URL to link users to the original graph."
+msgid "Incidents|There was an issue uploading your image."
msgstr ""
msgid "Incident|Alert details"
@@ -19147,9 +19585,18 @@ msgstr ""
msgid "Incident|Are you sure you wish to delete this image?"
msgstr ""
+msgid "Incident|Delete image"
+msgstr ""
+
msgid "Incident|Deleting %{filename}"
msgstr ""
+msgid "Incident|Edit image text or link"
+msgstr ""
+
+msgid "Incident|Editing %{filename}"
+msgstr ""
+
msgid "Incident|Metrics"
msgstr ""
@@ -19420,12 +19867,18 @@ msgstr ""
msgid "Integrations|Branches for which notifications are to be sent"
msgstr ""
+msgid "Integrations|Clear if using a self-signed certificate."
+msgstr ""
+
msgid "Integrations|Comment detail:"
msgstr ""
msgid "Integrations|Comment settings:"
msgstr ""
+msgid "Integrations|Connection details"
+msgstr ""
+
msgid "Integrations|Connection failed. Please check your settings."
msgstr ""
@@ -19450,6 +19903,9 @@ msgstr ""
msgid "Integrations|Enable GitLab.com slash commands in a Slack workspace."
msgstr ""
+msgid "Integrations|Enable SSL verification"
+msgstr ""
+
msgid "Integrations|Enable comments"
msgstr ""
@@ -19528,6 +19984,9 @@ msgstr ""
msgid "Integrations|Return to GitLab for Jira"
msgstr ""
+msgid "Integrations|SSL verification"
+msgstr ""
+
msgid "Integrations|Save settings?"
msgstr ""
@@ -19573,9 +20032,6 @@ msgstr ""
msgid "Integrations|Use default settings"
msgstr ""
-msgid "Integrations|When you mention a Jira issue in a commit or merge request, GitLab creates a remote link and comment (if enabled)."
-msgstr ""
-
msgid "Integrations|You can now close this window and return to the GitLab for Jira application."
msgstr ""
@@ -19600,9 +20056,6 @@ msgstr ""
msgid "Integrations|can't exceed %{recipients_limit}"
msgstr ""
-msgid "Interactive developer security education."
-msgstr ""
-
msgid "Interactive mode"
msgstr ""
@@ -20092,6 +20545,9 @@ msgstr ""
msgid "IssueAnalytics|Assignees"
msgstr ""
+msgid "IssueAnalytics|Created by"
+msgstr ""
+
msgid "IssueAnalytics|Due date"
msgstr ""
@@ -20104,9 +20560,6 @@ msgstr ""
msgid "IssueAnalytics|Milestone"
msgstr ""
-msgid "IssueAnalytics|Opened by"
-msgstr ""
-
msgid "IssueAnalytics|Status"
msgstr ""
@@ -20230,10 +20683,10 @@ msgstr ""
msgid "IssuesAnalytics|Avg/Month:"
msgstr ""
-msgid "IssuesAnalytics|Issues opened"
+msgid "IssuesAnalytics|Issues created"
msgstr ""
-msgid "IssuesAnalytics|Issues opened per month"
+msgid "IssuesAnalytics|Issues created per month"
msgstr ""
msgid "IssuesAnalytics|Last 12 months"
@@ -20260,6 +20713,9 @@ msgstr ""
msgid "It looks like you have some draft commits in this branch."
msgstr ""
+msgid "It looks like you're attempting to activate your subscription. Use %{a_start}the Subscription page%{a_end} instead."
+msgstr ""
+
msgid "It may be several days before you see feature usage data."
msgstr ""
@@ -20488,6 +20944,9 @@ msgstr "Ramura nouă a fost creată cu succes."
msgid "JiraConnect|You can now close this window and return to Jira."
msgstr "Puteți închide această fereastră acum și să vă întoarceți la Jira."
+msgid "JiraConnect|You don't have permission to create branches for this project. Select a different project or contact the project owner for access. %{linkStart}Learn more.%{linkEnd}"
+msgstr ""
+
msgid "JiraRequest|A connection error occurred while connecting to Jira. Try your request again."
msgstr ""
@@ -20536,13 +20995,13 @@ msgstr ""
msgid "JiraService|Define the type of Jira issue to create from a vulnerability."
msgstr ""
-msgid "JiraService|Displaying Jira issues while leaving the GitLab issue functionality enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
+msgid "JiraService|Displaying Jira issues while leaving GitLab issues also enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
msgstr ""
-msgid "JiraService|Enable Jira issues"
+msgid "JiraService|Enable Jira issue creation from vulnerabilities"
msgstr ""
-msgid "JiraService|Enable Jira issues creation from vulnerabilities"
+msgid "JiraService|Enable Jira issues"
msgstr ""
msgid "JiraService|Enable Jira transitions"
@@ -20659,16 +21118,19 @@ msgstr ""
msgid "JiraService|View Jira issues in GitLab"
msgstr ""
-msgid "JiraService|Warning: All GitLab users that have access to this GitLab project are able to view all issues from the Jira project specified below."
+msgid "JiraService|Warning: All GitLab users with access to this GitLab project can view all issues from the Jira project you select."
msgstr ""
msgid "JiraService|Web URL"
msgstr ""
-msgid "JiraService|Work on Jira issues without leaving GitLab. Adds a Jira menu to access your list of Jira issues and view any issue as read-only."
+msgid "JiraService|When a Jira issue is mentioned in a commit or merge request, a remote link and comment (if enabled) will be created."
msgstr ""
-msgid "JiraService|You need to configure Jira before enabling this integration. For more details, read the %{jira_doc_link_start}Jira integration documentation%{link_end}."
+msgid "JiraService|Work on Jira issues without leaving GitLab. Add a Jira menu to access a read-only list of your Jira issues."
+msgstr ""
+
+msgid "JiraService|You must configure Jira before enabling this integration. %{jira_doc_link_start}Learn more.%{link_end}"
msgstr ""
msgid "Job"
@@ -20680,9 +21142,6 @@ msgstr ""
msgid "Job Failed #%{build_id}"
msgstr ""
-msgid "Job ID"
-msgstr ""
-
msgid "Job artifact"
msgstr ""
@@ -20749,9 +21208,27 @@ msgstr ""
msgid "Jobs|You're about to retry a job that failed because it attempted to deploy code that is older than the latest deployment. Retrying this job could result in overwriting the environment with the older source code."
msgstr ""
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source} into %{target}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{ref}"
+msgstr ""
+
+msgid "Job|Are you sure you want to erase this job log and artifacts?"
+msgstr ""
+
msgid "Job|Browse"
msgstr ""
+msgid "Job|Cancel"
+msgstr ""
+
msgid "Job|Complete Raw"
msgstr "Brut complet"
@@ -20761,6 +21238,9 @@ msgstr ""
msgid "Job|Erase job log and artifacts"
msgstr ""
+msgid "Job|Finished at"
+msgstr ""
+
msgid "Job|Job artifacts"
msgstr ""
@@ -20773,7 +21253,7 @@ msgstr "Jobul a fost șters de %{userLink}"
msgid "Job|Keep"
msgstr ""
-msgid "Job|Pipeline"
+msgid "Job|Retry"
msgstr ""
msgid "Job|Scroll to bottom"
@@ -20785,6 +21265,9 @@ msgstr ""
msgid "Job|Show complete raw"
msgstr "Afișați brut complet"
+msgid "Job|Status"
+msgstr ""
+
msgid "Job|The artifacts were removed"
msgstr ""
@@ -20812,21 +21295,12 @@ msgstr ""
msgid "Job|delayed"
msgstr ""
-msgid "Job|for"
-msgstr "pentru"
-
-msgid "Job|into"
-msgstr ""
-
msgid "Job|manual"
msgstr ""
msgid "Job|triggered"
msgstr ""
-msgid "Job|with"
-msgstr ""
-
msgid "Join Zoom meeting"
msgstr ""
@@ -20929,9 +21403,6 @@ msgstr ""
msgid "Ki"
msgstr "Ki"
-msgid "Kontra"
-msgstr ""
-
msgid "Kroki"
msgstr ""
@@ -21256,6 +21727,9 @@ msgstr ""
msgid "Learn more about Auto DevOps"
msgstr ""
+msgid "Learn more about GitLab"
+msgstr ""
+
msgid "Learn more about Needs relationships"
msgstr ""
@@ -21589,9 +22063,18 @@ msgstr ""
msgid "Licenses|Displays licenses detected in the project, based on the %{linkStart}latest successful%{linkEnd} scan"
msgstr ""
+msgid "Licenses|Drag your license file here or %{linkStart}click to upload%{linkEnd}."
+msgstr ""
+
+msgid "Licenses|Drop your license file to start the upload."
+msgstr ""
+
msgid "Licenses|Error fetching the license list. Please check your network connection and try again."
msgstr ""
+msgid "Licenses|Error: You are trying to upload something other than a file"
+msgstr ""
+
msgid "Licenses|License Compliance"
msgstr "Conformitatea licenței"
@@ -21610,6 +22093,9 @@ msgstr ""
msgid "Licenses|Specified policies in this project"
msgstr ""
+msgid "Licenses|The file could not be uploaded."
+msgstr ""
+
msgid "Licenses|The license list details information about the licenses used within your project."
msgstr ""
@@ -21643,12 +22129,6 @@ msgstr ""
msgid "Limit the size of Sidekiq jobs stored in Redis."
msgstr ""
-msgid "Limited to showing %d event at most"
-msgid_plural "Limited to showing %d events at most"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-
msgid "Limiting mode"
msgstr ""
@@ -21658,6 +22138,9 @@ msgstr ""
msgid "Link"
msgstr ""
+msgid "Link (optional)"
+msgstr ""
+
msgid "Link Prometheus monitoring to GitLab."
msgstr ""
@@ -21694,6 +22177,9 @@ msgstr "Link către instanța dvs. Grafana."
msgid "Linked emails (%{email_count})"
msgstr ""
+msgid "Linked epics"
+msgstr ""
+
msgid "Linked issues"
msgstr ""
@@ -21721,6 +22207,15 @@ msgstr ""
msgid "List of all merge commits"
msgstr ""
+msgid "List of environments for this project"
+msgstr ""
+
+msgid "List of suitable GCP locations"
+msgstr ""
+
+msgid "List of users allowed to exceed the rate limit."
+msgstr ""
+
msgid "List options"
msgstr ""
@@ -21940,6 +22435,9 @@ msgstr ""
msgid "Maintenance mode"
msgstr ""
+msgid "Make adjustments to how your GitLab instance is set up."
+msgstr ""
+
msgid "Make and review changes in the browser with the Web IDE"
msgstr ""
@@ -22084,6 +22582,12 @@ msgstr ""
msgid "MarkdownEditor|Add italic text (%{modifier_key}I)"
msgstr ""
+msgid "MarkdownEditor|Add strikethrough text (%{modifierKey}⇧X)"
+msgstr ""
+
+msgid "MarkdownEditor|Add strikethrough text (%{modifier_key}⇧X)"
+msgstr ""
+
msgid "Marked For Deletion At - %{deletion_time}"
msgstr ""
@@ -22345,6 +22849,9 @@ msgstr "Mărime maximă push"
msgid "Maximum push size (MB)"
msgstr ""
+msgid "Maximum requests per 10 minutes per user"
+msgstr ""
+
msgid "Maximum requests per minute"
msgstr ""
@@ -22435,6 +22942,21 @@ msgstr ""
msgid "Members of a group may only view projects they have permission to access"
msgstr ""
+msgid "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seat in use and will be billed for the overage."
+msgid_plural "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seats in use and will be billed for the overage."
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
+msgid "MembersOverage|You are about to incur additional charges"
+msgstr ""
+
+msgid "MembersOverage|Your subscription includes %d seat."
+msgid_plural "MembersOverage|Your subscription includes %d seats."
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
msgid "Membership"
msgstr ""
@@ -22639,9 +23161,6 @@ msgstr ""
msgid "Merge request not merged"
msgstr ""
-msgid "Merge request pipelines 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 merge request pipelines."
-msgstr ""
-
msgid "Merge request reports"
msgstr ""
@@ -22738,13 +23257,13 @@ msgstr ""
msgid "MergeRequests|Create issue to resolve thread"
msgstr ""
-msgid "MergeRequests|Failed to squash. Should be done manually."
+msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Saving the comment failed"
+msgid "MergeRequests|Squashing failed: Squash the commits locally, resolve any conflicts, then push the branch."
msgstr ""
-msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
+msgid "MergeRequests|Squashing not allowed: This project doesn't allow you to squash commits when merging."
msgstr ""
msgid "MergeRequests|Thread stays resolved"
@@ -23587,6 +24106,18 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "MrList|Assigned to %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from assignee %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from reviewer %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Review requested from %{name}, go to their profile."
+msgstr ""
+
msgid "Multi-project"
msgstr ""
@@ -23620,7 +24151,7 @@ msgstr ""
msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr "Trebuie să se potrivească cu %{codeStart}geo_code_name%{codeEnd} în %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Aflați mai multe%{linkEnd}"
-msgid "My Awesome Group"
+msgid "My awesome group"
msgstr ""
msgid "My company or team"
@@ -24244,9 +24775,6 @@ msgstr ""
msgid "No available branches"
msgstr ""
-msgid "No available groups to fork the project."
-msgstr ""
-
msgid "No branches found"
msgstr ""
@@ -24457,6 +24985,9 @@ msgstr ""
msgid "No ref selected"
msgstr ""
+msgid "No regions configured"
+msgstr ""
+
msgid "No related merge requests found."
msgstr ""
@@ -25267,6 +25798,9 @@ msgstr ""
msgid "Only reCAPTCHA v2 is supported:"
msgstr ""
+msgid "Only required if not using role instance credentials."
+msgstr ""
+
msgid "Only use lowercase letters, numbers, and underscores."
msgstr ""
@@ -25291,9 +25825,6 @@ msgstr ""
msgid "Open a CLI and connect to the cluster you want to install the agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
-msgid "Open epics"
-msgstr ""
-
msgid "Open errors"
msgstr ""
@@ -25333,7 +25864,7 @@ msgstr ""
msgid "Opened issues"
msgstr ""
-msgid "OpenedNDaysAgo|Opened"
+msgid "OpenedNDaysAgo|Created"
msgstr ""
msgid "Opens in a new window"
@@ -25378,9 +25909,6 @@ msgstr ""
msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
-msgid "Optional."
-msgstr ""
-
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
msgstr ""
@@ -26170,6 +26698,9 @@ msgstr ""
msgid "PerformanceBar|Memory"
msgstr ""
+msgid "PerformanceBar|Memory report"
+msgstr ""
+
msgid "PerformanceBar|Redis calls"
msgstr ""
@@ -26203,18 +26734,12 @@ msgstr "obiect"
msgid "PerformanceBar|wall"
msgstr "perete"
-msgid "Performs a rebase but skips triggering a new pipeline"
-msgstr ""
-
msgid "Period in seconds"
msgstr "Perioadă în secunde"
msgid "Permalink"
msgstr ""
-msgid "Permanently delete project"
-msgstr ""
-
msgid "Permanently remove group"
msgstr "Eliminați definitiv grupul"
@@ -26485,6 +27010,51 @@ msgstr ""
msgid "PipelineStatusTooltip|Pipeline: %{ci_status}"
msgstr ""
+msgid "PipelineWizardDefaultCommitMessage|Add %{filename}"
+msgstr ""
+
+msgid "PipelineWizardDefaultCommitMessage|Update %{filename}"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|At least one entry is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This field is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This value is not valid"
+msgstr ""
+
+msgid "PipelineWizardListWidget|add another step"
+msgstr ""
+
+msgid "PipelineWizardListWidget|remove step"
+msgstr ""
+
+msgid "PipelineWizard|Commit"
+msgstr ""
+
+msgid "PipelineWizard|Commit Message"
+msgstr ""
+
+msgid "PipelineWizard|Commit changes to your file"
+msgstr ""
+
+msgid "PipelineWizard|Commit file to Branch"
+msgstr ""
+
+msgid "PipelineWizard|Commit your new file"
+msgstr ""
+
+msgid "PipelineWizard|The file has been committed."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem committing the changes."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem while checking whether your file already exists in the specified branch."
+msgstr ""
+
msgid "Pipelines"
msgstr ""
@@ -26599,7 +27169,7 @@ msgstr ""
msgid "Pipelines|Project cache successfully reset."
msgstr ""
-msgid "Pipelines|Revoke"
+msgid "Pipelines|Revoke trigger"
msgstr ""
msgid "Pipelines|Something went wrong while cleaning runners cache."
@@ -26644,6 +27214,12 @@ msgstr ""
msgid "Pipelines|This is a child pipeline within the parent pipeline"
msgstr ""
+msgid "Pipelines|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipelines|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipelines|This pipeline will run code originating from a forked project merge request. This means that the code can potentially have security considerations like exposing CI variables."
msgstr ""
@@ -26686,9 +27262,6 @@ msgstr ""
msgid "Pipelines|Your changes have been successfully committed. Now redirecting to the new merge request page."
msgstr ""
-msgid "Pipelines|detached"
-msgstr ""
-
msgid "Pipelines|error"
msgstr ""
@@ -26698,10 +27271,13 @@ msgstr ""
msgid "Pipelines|latest"
msgstr ""
-msgid "Pipelines|stuck"
+msgid "Pipelines|merge request"
msgstr ""
-msgid "Pipelines|train"
+msgid "Pipelines|merge train"
+msgstr ""
+
+msgid "Pipelines|stuck"
msgstr ""
msgid "Pipelines|yaml invalid"
@@ -26833,6 +27409,12 @@ msgstr ""
msgid "Pipeline|This change will not change the overall test coverage if merged."
msgstr ""
+msgid "Pipeline|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipeline|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipeline|Trigger author"
msgstr ""
@@ -26857,6 +27439,12 @@ msgstr "Sunteți pe cale să opriți pipeline-ul #%{pipelineId}."
msgid "Pipeline|for"
msgstr ""
+msgid "Pipeline|merge request"
+msgstr ""
+
+msgid "Pipeline|merge train"
+msgstr ""
+
msgid "Pipeline|on"
msgstr ""
@@ -26995,9 +27583,6 @@ msgstr ""
msgid "Please enter a valid time interval"
msgstr ""
-msgid "Please enter or upload a valid license."
-msgstr ""
-
msgid "Please enter your current password."
msgstr ""
@@ -27106,9 +27691,6 @@ msgstr ""
msgid "Please type %{phrase_code} to proceed or close this modal to cancel."
msgstr ""
-msgid "Please type the following to confirm:"
-msgstr ""
-
msgid "Please use this form to report to the admin users who create spam issues, comments or behave inappropriately."
msgstr ""
@@ -27136,12 +27718,27 @@ msgstr ""
msgid "Policies"
msgstr "Politici"
+msgid "Policy '%{escalation_policy_name}' does not exist."
+msgstr ""
+
msgid "Policy management project does have any policies in %{policy_path}"
msgstr ""
msgid "Policy project doesn't exist"
msgstr ""
+msgid "PolicyRuleMultiSelect|%{firstLabel} +%{numberOfAdditionalLabels} more"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|All %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select all"
+msgstr ""
+
msgid "Polling interval multiplier"
msgstr ""
@@ -27370,6 +27967,9 @@ msgstr ""
msgid "Private projects can be created in your personal namespace with:"
msgstr ""
+msgid "Problem with %{name} command: %{message}."
+msgstr ""
+
msgid "Proceed"
msgstr ""
@@ -27844,6 +28444,9 @@ msgstr ""
msgid "Progress"
msgstr ""
+msgid "Progress tracking"
+msgstr ""
+
msgid "Project"
msgstr ""
@@ -28075,6 +28678,9 @@ msgstr ""
msgid "ProjectQualitySummary|Failure"
msgstr ""
+msgid "ProjectQualitySummary|Get insight into the overall percentage of tests in your project that succeed, fail and are skipped."
+msgstr ""
+
msgid "ProjectQualitySummary|Latest pipeline results"
msgstr ""
@@ -28093,6 +28699,12 @@ msgstr ""
msgid "ProjectQualitySummary|See project Code Coverage Statistics"
msgstr ""
+msgid "ProjectQualitySummary|Set up test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|Set up test runs (opens in a new tab)"
+msgstr ""
+
msgid "ProjectQualitySummary|Skipped"
msgstr ""
@@ -28369,13 +28981,19 @@ msgstr ""
msgid "ProjectSettings|LFS objects from this repository are available to forks. %{linkStart}How do I remove them?%{linkEnd}"
msgstr ""
+msgid "ProjectSettings|Learn about commit history."
+msgstr ""
+
+msgid "ProjectSettings|Leave empty to use default template."
+msgstr ""
+
msgid "ProjectSettings|Manage who can see the project in the public access directory."
msgstr ""
msgid "ProjectSettings|Manages large files such as audio, video, and graphics files."
msgstr ""
-msgid "ProjectSettings|Maximum 500 characters."
+msgid "ProjectSettings|Maximum %{maxLength} characters."
msgstr ""
msgid "ProjectSettings|Merge checks"
@@ -28516,6 +29134,9 @@ msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
msgstr ""
+msgid "ProjectSettings|The default template will be applied on save."
+msgstr ""
+
msgid "ProjectSettings|These checks must pass before merge requests can be merged."
msgstr ""
@@ -28570,6 +29191,9 @@ msgstr ""
msgid "ProjectSettings|What are badges?"
msgstr ""
+msgid "ProjectSettings|What are merge trains?"
+msgstr ""
+
msgid "ProjectSettings|When merge request pipelines are enabled in the CI/CD configuration file, pipelines validate the combined results of the source and target branches. %{link_start}How to configure merge request pipelines?%{link_end}"
msgstr ""
@@ -28687,6 +29311,9 @@ msgstr ""
msgid "Projects are organized into groups"
msgstr "Proiectele sunt organizate în grupuri"
+msgid "Projects are where you store your code, access issues, wiki and other features of GitLab."
+msgstr ""
+
msgid "Projects contributed to"
msgstr ""
@@ -28702,12 +29329,6 @@ msgstr "Proiecte ce pot fi accesate"
msgid "Projects to index"
msgstr ""
-msgid "Projects will be permanently deleted after a %{waiting_period}-day waiting period."
-msgstr ""
-
-msgid "Projects will be permanently deleted immediately."
-msgstr ""
-
msgid "Projects with critical vulnerabilities"
msgstr ""
@@ -28792,6 +29413,9 @@ msgstr ""
msgid "ProjectsNew|Import project"
msgstr ""
+msgid "ProjectsNew|Include a Getting Started README"
+msgstr ""
+
msgid "ProjectsNew|Initialize repository with a README"
msgstr ""
@@ -28807,6 +29431,9 @@ msgstr ""
msgid "ProjectsNew|Project description %{tag_start}(optional)%{tag_end}"
msgstr ""
+msgid "ProjectsNew|Recommended if you're new to GitLab"
+msgstr ""
+
msgid "ProjectsNew|Run CI/CD for external repository"
msgstr ""
@@ -29224,6 +29851,9 @@ msgstr ""
msgid "ProtectedBranch|Unprotect"
msgstr ""
+msgid "ProtectedBranch|Unprotect branch"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
@@ -29251,6 +29881,9 @@ msgstr ""
msgid "ProtectedEnvironment|Protected Environment (%{protected_environments_count})"
msgstr ""
+msgid "ProtectedEnvironment|Required approvals"
+msgstr ""
+
msgid "ProtectedEnvironment|Select an environment"
msgstr ""
@@ -29272,10 +29905,13 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|Unprotect tag"
+msgstr ""
+
msgid "ProtectedTags|default"
msgstr ""
-msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
+msgid "ProtectedTag|By default, protected tags restrict who can modify the tag."
msgstr ""
msgid "ProtectedTag|Learn more."
@@ -29338,6 +29974,9 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Public projects are an easy way to allow everyone to have read-only access."
+msgstr ""
+
msgid "Publish to status page"
msgstr ""
@@ -29494,9 +30133,6 @@ msgstr ""
msgid "QualitySummary|Project quality"
msgstr ""
-msgid "Quarters"
-msgstr ""
-
msgid "Query"
msgstr ""
@@ -29581,6 +30217,9 @@ msgstr ""
msgid "Read more about project permissions %{help_link_open}here%{help_link_close}"
msgstr ""
+msgid "Read more about related epics"
+msgstr ""
+
msgid "Read more about related issues"
msgstr ""
@@ -29611,10 +30250,7 @@ msgstr ""
msgid "Rebase source branch on the target branch."
msgstr ""
-msgid "Rebase without CI"
-msgstr ""
-
-msgid "Rebases and triggers a pipeline"
+msgid "Rebase without pipeline"
msgstr ""
msgid "Recaptcha verified?"
@@ -29665,9 +30301,6 @@ msgstr ""
msgid "Reconfigure"
msgstr ""
-msgid "Recovering projects"
-msgstr ""
-
msgid "Recovery Codes"
msgstr ""
@@ -29728,6 +30361,12 @@ msgstr ""
msgid "Regex pattern"
msgstr ""
+msgid "Region"
+msgstr ""
+
+msgid "Regions"
+msgstr ""
+
msgid "Register"
msgstr ""
@@ -29959,9 +30598,6 @@ msgstr ""
msgid "Remove all or specific reviewer(s)"
msgstr ""
-msgid "Remove approver"
-msgstr ""
-
msgid "Remove approvers"
msgstr ""
@@ -29977,6 +30613,9 @@ msgstr ""
msgid "Remove attention request"
msgstr ""
+msgid "Remove attention request(s)"
+msgstr ""
+
msgid "Remove avatar"
msgstr ""
@@ -30115,6 +30754,9 @@ msgstr ""
msgid "Removed an issue from an epic."
msgstr ""
+msgid "Removed attention from %{users_sentence}."
+msgstr ""
+
msgid "Removed attention request from @%{username}"
msgstr ""
@@ -30166,6 +30808,9 @@ msgstr ""
msgid "Removes an issue from an epic."
msgstr ""
+msgid "Removes attention from %{users_sentence}."
+msgstr ""
+
msgid "Removes parent epic %{epic_ref}."
msgstr ""
@@ -30277,6 +30922,9 @@ msgstr ""
msgid "Report abuse to admin"
msgstr ""
+msgid "Report is generating and will be sent to your email address."
+msgstr ""
+
msgid "Reported %{timeAgo} by %{reportedBy}"
msgstr ""
@@ -30571,6 +31219,15 @@ msgstr ""
msgid "Request attention"
msgstr ""
+msgid "Request attention from %{users_sentence}."
+msgstr ""
+
+msgid "Request attention from assignee or reviewer"
+msgstr ""
+
+msgid "Request attention from assignee(s) or reviewer(s)"
+msgstr ""
+
msgid "Request attention to review"
msgstr ""
@@ -30595,6 +31252,9 @@ msgstr ""
msgid "Requested %{time_ago}"
msgstr ""
+msgid "Requested attention from %{users_sentence}."
+msgstr ""
+
msgid "Requested attention from @%{username}"
msgstr ""
@@ -30811,6 +31471,9 @@ msgstr ""
msgid "Restore project"
msgstr ""
+msgid "Restoring projects"
+msgstr ""
+
msgid "Restoring the group will prevent the group, its subgroups and projects from being removed on this date."
msgstr ""
@@ -30841,6 +31504,9 @@ msgstr ""
msgid "Retry"
msgstr ""
+msgid "Retry failed jobs"
+msgstr ""
+
msgid "Retry job"
msgstr ""
@@ -30889,9 +31555,6 @@ msgstr ""
msgid "Review changes"
msgstr ""
-msgid "Review requested from %{name}"
-msgstr ""
-
msgid "Review requests for you"
msgstr ""
@@ -31057,6 +31720,9 @@ msgstr ""
msgid "Runners|Assigned Group"
msgstr ""
+msgid "Runners|Assigned Projects (%{projectCount})"
+msgstr ""
+
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -31126,6 +31792,9 @@ msgstr ""
msgid "Runners|Instance"
msgstr ""
+msgid "Runners|Jobs"
+msgstr ""
+
msgid "Runners|Last contact"
msgstr ""
@@ -31219,9 +31888,6 @@ msgstr ""
msgid "Runners|Runner %{name} was deleted"
msgstr ""
-msgid "Runners|Runner ID"
-msgstr ""
-
msgid "Runners|Runner assigned to project."
msgstr ""
@@ -31369,6 +32035,9 @@ msgstr ""
msgid "Runners|stale"
msgstr ""
+msgid "Runner|This runner has not run any jobs."
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -31483,6 +32152,24 @@ msgstr ""
msgid "Saving project."
msgstr ""
+msgid "ScanResultPolicy|%{ifLabelStart}if%{ifLabelEnd} %{scanners} scan in an open merge request targeting the %{branches} branch(es) finds %{vulnerabilitiesAllowed} or more %{severities} vulnerabilities that are %{vulnerabilityStates}"
+msgstr ""
+
+msgid "ScanResultPolicy|%{thenLabelStart}Then%{thenLabelEnd} Require approval from %{approvalsRequired} of the following approvers: %{approvers}"
+msgstr ""
+
+msgid "ScanResultPolicy|add an approver"
+msgstr ""
+
+msgid "ScanResultPolicy|scanners"
+msgstr ""
+
+msgid "ScanResultPolicy|severity levels"
+msgstr ""
+
+msgid "ScanResultPolicy|vulnerability states"
+msgstr ""
+
msgid "Scanner"
msgstr ""
@@ -31615,6 +32302,9 @@ msgstr ""
msgid "Search for a user"
msgstr ""
+msgid "Search for an emoji"
+msgstr ""
+
msgid "Search for projects, issues, etc."
msgstr ""
@@ -31813,18 +32503,12 @@ msgstr ""
msgid "Secret Detection"
msgstr ""
-msgid "Secret access key"
-msgstr ""
-
msgid "Secret token"
msgstr ""
msgid "Secure token that identifies an external storage request."
msgstr "Token sigur care identifică o solicitare stocare externă."
-msgid "SecureCodeWarrior"
-msgstr ""
-
msgid "Security"
msgstr ""
@@ -31849,9 +32533,6 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "Security training with guide and learning pathways."
-msgstr ""
-
msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
@@ -31954,7 +32635,7 @@ msgstr "Începeți imediat analiza riscului și remedierea cu funcții de securi
msgid "SecurityConfiguration|Manage corpus"
msgstr ""
-msgid "SecurityConfiguration|Manage corpus files used as mutation sources in coverage fuzzing."
+msgid "SecurityConfiguration|Manage corpus files used as seed inputs with coverage-guided fuzzing."
msgstr ""
msgid "SecurityConfiguration|Manage profiles for use by DAST scans."
@@ -32020,15 +32701,15 @@ msgstr "%{branches} și %{lastBranch}%{plural}"
msgid "SecurityOrchestration|.yaml preview"
msgstr ""
-msgid "SecurityOrchestration|Action"
-msgstr "Acțiune"
-
msgid "SecurityOrchestration|Actions"
msgstr ""
msgid "SecurityOrchestration|Add rule"
msgstr ""
+msgid "SecurityOrchestration|After dismissing the alert, the information will never be shown again."
+msgstr ""
+
msgid "SecurityOrchestration|All policies"
msgstr "Toate politicile"
@@ -32044,7 +32725,7 @@ msgstr ""
msgid "SecurityOrchestration|Description"
msgstr "Descriere"
-msgid "SecurityOrchestration|Disabled"
+msgid "SecurityOrchestration|Don't show the alert anymore"
msgstr ""
msgid "SecurityOrchestration|Edit policy"
@@ -32053,13 +32734,13 @@ msgstr "Editați politica"
msgid "SecurityOrchestration|Edit policy project"
msgstr ""
-msgid "SecurityOrchestration|Enabled"
+msgid "SecurityOrchestration|Empty policy name"
msgstr ""
-msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Enabled"
msgstr ""
-msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
msgstr ""
msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
@@ -32068,8 +32749,8 @@ msgstr ""
msgid "SecurityOrchestration|Invalid policy type"
msgstr ""
-msgid "SecurityOrchestration|Latest scan"
-msgstr "Ultima scanare"
+msgid "SecurityOrchestration|Latest scan run against %{agent}"
+msgstr ""
msgid "SecurityOrchestration|Network"
msgstr "Rețea"
@@ -32077,15 +32758,27 @@ msgstr "Rețea"
msgid "SecurityOrchestration|New policy"
msgstr "Politică nouă"
+msgid "SecurityOrchestration|No actions defined - policy will not run."
+msgstr ""
+
+msgid "SecurityOrchestration|No description"
+msgstr ""
+
msgid "SecurityOrchestration|No rules defined - policy will not run."
msgstr ""
+msgid "SecurityOrchestration|Not enabled"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr "Doar proprietarii pot actualiza Proiectul Politicii de Securitate"
msgid "SecurityOrchestration|Policies"
msgstr "Politici"
+msgid "SecurityOrchestration|Policy Type"
+msgstr ""
+
msgid "SecurityOrchestration|Policy cannot be enabled for non-existing branches (%{branches})"
msgstr ""
@@ -32110,12 +32803,15 @@ msgstr "Tip politică"
msgid "SecurityOrchestration|Require %{approvals} %{plural} from %{approvers} if any of the following occur:"
msgstr ""
-msgid "SecurityOrchestration|Rule"
-msgstr "Regulă"
-
msgid "SecurityOrchestration|Rules"
msgstr ""
+msgid "SecurityOrchestration|Runs %{actions} and %{lastAction} scans"
+msgstr ""
+
+msgid "SecurityOrchestration|Runs a %{action} scan"
+msgstr ""
+
msgid "SecurityOrchestration|Scan Execution"
msgstr ""
@@ -32173,6 +32869,9 @@ msgstr ""
msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
+msgid "SecurityOrchestration|This view only shows scan results for the agent %{agent}. You can view scan results for all agents in the %{linkStart}Operational Vulnerabilities tab of the vulnerability report%{linkEnd}."
+msgstr ""
+
msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
@@ -32227,9 +32926,6 @@ msgstr ""
msgid "SecurityOrchestration|users with ids"
msgstr ""
-msgid "SecurityOrchestration|view results"
-msgstr ""
-
msgid "SecurityOrchestration|vulnerabilities"
msgstr ""
@@ -32899,22 +33595,19 @@ 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|In order to start using functions as a service, you must first install Knative on your Kubernetes cluster. %{linkStart}More information%{linkEnd}"
-msgstr ""
-
msgid "Serverless|Learn more about Serverless"
msgstr ""
msgid "Serverless|No functions available"
msgstr ""
-msgid "Serverless|Sign up for First Look"
+msgid "Serverless|Serverless was %{linkStart}deprecated%{linkEnd} in GitLab 14.3."
+msgstr ""
+
+msgid "Serverless|Serverless was %{postLinkStart}deprecated%{postLinkEnd}. But if you opt to use it, you must install Knative in your Kubernetes cluster first. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "Serverless|The deploy job has not finished."
@@ -32926,9 +33619,6 @@ 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 ""
@@ -32944,9 +33634,6 @@ msgstr ""
msgid "Service Account Key"
msgstr ""
-msgid "Service Accounts"
-msgstr ""
-
msgid "Service Accounts keys authorize GitLab to deploy your Google Cloud project"
msgstr ""
@@ -32956,10 +33643,10 @@ msgstr ""
msgid "Service Desk allows people to create issues in your GitLab instance without their own user account. It provides a unique email address for end users to create issues in a project. Replies can be sent either through the GitLab interface or by email. End users only see threads through email."
msgstr ""
-msgid "Service Usage Data"
+msgid "Service account generated successfully"
msgstr ""
-msgid "Service account generated successfully"
+msgid "Service accounts"
msgstr ""
msgid "Service ping is disabled in your configuration file, and cannot be enabled through this form."
@@ -33103,6 +33790,9 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
+msgid "Set the per-user rate limit for getting a user by ID via the API."
+msgstr ""
+
msgid "Set the per-user rate limit for notes created by web or API requests."
msgstr ""
@@ -33283,6 +33973,9 @@ msgstr ""
msgid "Shared runners details"
msgstr ""
+msgid "Shared runners enabled cannot be enabled until a valid credit card is on file"
+msgstr ""
+
msgid "Shared runners help link"
msgstr ""
@@ -33340,6 +34033,9 @@ msgstr ""
msgid "Show all issues."
msgstr ""
+msgid "Show all milestones"
+msgstr ""
+
msgid "Show all test cases."
msgstr ""
@@ -33376,6 +34072,9 @@ msgstr ""
msgid "Show file contents"
msgstr ""
+msgid "Show group milestones"
+msgstr ""
+
msgid "Show labels"
msgstr ""
@@ -33391,6 +34090,12 @@ msgstr ""
msgid "Show open epics"
msgstr ""
+msgid "Show project milestones"
+msgstr ""
+
+msgid "Show sub-group milestones"
+msgstr ""
+
msgid "Show the Closed list"
msgstr ""
@@ -33400,12 +34105,6 @@ msgstr ""
msgid "Show whitespace changes"
msgstr ""
-msgid "Showing %d event"
-msgid_plural "Showing %d events"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-
msgid "Showing %{conflict} between %{sourceBranch} and %{targetBranch}"
msgstr ""
@@ -33466,12 +34165,6 @@ msgstr ""
msgid "Sidebar|None"
msgstr ""
-msgid "Sidebar|Only numeral characters allowed"
-msgstr ""
-
-msgid "Sidebar|Weight"
-msgstr ""
-
msgid "Sidekiq job compression threshold (bytes)"
msgstr ""
@@ -33634,6 +34327,9 @@ msgstr ""
msgid "Slack logo"
msgstr ""
+msgid "SlackIntegration|Are you sure you want to remove this project from the Slack application?"
+msgstr ""
+
msgid "SlackIntegration|GitLab for Slack"
msgstr ""
@@ -33643,6 +34339,9 @@ msgstr ""
msgid "SlackIntegration|Project alias"
msgstr ""
+msgid "SlackIntegration|Remove project"
+msgstr ""
+
msgid "SlackIntegration|Select a GitLab project to link with your Slack workspace."
msgstr ""
@@ -33787,9 +34486,6 @@ msgstr ""
msgid "Something went wrong trying to load issue contacts."
msgstr ""
-msgid "Something went wrong when creating a work item. Please try again"
-msgstr ""
-
msgid "Something went wrong when reordering designs. Please try again"
msgstr ""
@@ -33883,9 +34579,6 @@ msgstr ""
msgid "Something went wrong while inserting your image. Please try again."
msgstr ""
-msgid "Something went wrong while merging this merge request. Please try again."
-msgstr "Ceva nu a mers bine în timpul îmbinării acestui merge request. Vă rugăm încercați din nou."
-
msgid "Something went wrong while obtaining the Let's Encrypt certificate."
msgstr ""
@@ -34207,10 +34900,10 @@ 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."
+msgid "SourcegraphAdmin|Learn more."
msgstr ""
-msgid "SourcegraphAdmin|More information"
+msgid "SourcegraphAdmin|Only public projects have code intelligence enabled and communicate with Sourcegraph."
msgstr ""
msgid "SourcegraphAdmin|Save changes"
@@ -34219,7 +34912,7 @@ msgstr ""
msgid "SourcegraphAdmin|Sourcegraph URL"
msgstr ""
-msgid "SourcegraphAdmin|e.g. https://sourcegraph.example.com"
+msgid "SourcegraphAdmin|https://sourcegraph.example.com"
msgstr ""
msgid "SourcegraphPreferences|This feature is experimental and currently limited to certain projects."
@@ -34354,6 +35047,9 @@ msgstr ""
msgid "Start date"
msgstr ""
+msgid "Start free trial"
+msgstr ""
+
msgid "Start merge train"
msgstr ""
@@ -34384,6 +35080,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started escalation for this incident."
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -34396,6 +35095,9 @@ msgstr ""
msgid "Starts at (UTC)"
msgstr ""
+msgid "Starts escalations for this incident"
+msgstr ""
+
msgid "Starts on"
msgstr ""
@@ -34657,6 +35359,9 @@ msgstr ""
msgid "Strikethrough"
msgstr ""
+msgid "Strikethrough text"
+msgstr ""
+
msgid "Subgroup information"
msgstr ""
@@ -34891,6 +35596,21 @@ msgstr ""
msgid "Subscriptions"
msgstr ""
+msgid "Subscriptions|Chat with sales"
+msgstr ""
+
+msgid "Subscriptions|Close"
+msgstr ""
+
+msgid "Subscriptions|Not ready to buy yet?"
+msgstr ""
+
+msgid "Subscriptions|Start a free trial"
+msgstr ""
+
+msgid "Subscriptions|We understand. Maybe you have some questions for our sales team, or maybe you'd like to try some of the paid features first. What would you like to do?"
+msgstr ""
+
msgid "Subscription|Your subscription for %{strong}%{namespace_name}%{strong_close} has expired and you are now on %{pricing_link_start}the GitLab Free tier%{pricing_link_end}. Don't worry, your data is safe. Get in touch with our support team (%{support_email}). They'll gladly help with your subscription renewal."
msgstr ""
@@ -35101,6 +35821,9 @@ msgstr ""
msgid "SuperSonics|Maximum users"
msgstr ""
+msgid "SuperSonics|Offline cloud"
+msgstr ""
+
msgid "SuperSonics|Paste your activation code"
msgstr ""
@@ -35167,6 +35890,12 @@ msgstr ""
msgid "SuperSonics|You do not have an active subscription"
msgstr ""
+msgid "SuperSonics|You have a future dated license"
+msgstr ""
+
+msgid "SuperSonics|You have added a license that activates on %{date}. Please see the subscription history table below for more details."
+msgstr ""
+
msgid "SuperSonics|You have successfully added a license that activates on %{date}. Please see the subscription history table below for more details."
msgstr ""
@@ -35326,6 +36055,9 @@ msgstr ""
msgid "Tag name is required"
msgstr ""
+msgid "Tag push"
+msgstr ""
+
msgid "Tag push events"
msgstr ""
@@ -35428,6 +36160,9 @@ msgstr ""
msgid "TagsPage|protected"
msgstr ""
+msgid "Take a look at the documentation to discover all of GitLab’s capabilities."
+msgstr ""
+
msgid "Target Branch"
msgstr ""
@@ -35836,6 +36571,9 @@ msgstr ""
msgid "Tests"
msgstr ""
+msgid "Text (optional)"
+msgstr ""
+
msgid "Text added to the body of all email messages. %{character_limit} character limit"
msgstr ""
@@ -35887,6 +36625,9 @@ msgstr ""
msgid "The CSV export will be created in the background. Once finished, it will be sent to %{email} in an attachment."
msgstr ""
+msgid "The CSV export you requested of all user memberships is attached to this email."
+msgstr ""
+
msgid "The GitLab subscription service (customers.gitlab.com) is currently experiencing an outage. You can monitor the status and get updates at %{linkStart}status.gitlab.com%{linkEnd}."
msgstr ""
@@ -35962,6 +36703,9 @@ 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 epic"
+msgstr ""
+
msgid "The current issue"
msgstr ""
@@ -36124,6 +36868,9 @@ msgstr ""
msgid "The latest pipeline for this merge request has failed."
msgstr ""
+msgid "The license key is invalid."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -36139,6 +36886,9 @@ msgstr ""
msgid "The license was successfully uploaded and will be active from %{starts_at}. You can see the details below."
msgstr ""
+msgid "The license you uploaded is invalid. If the issue persists, contact support at %{link}."
+msgstr ""
+
msgid "The list creation wizard is already open"
msgstr ""
@@ -36760,11 +37510,14 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
-msgstr "Această acțiune va %{strongOpen}șterge definitiv%{strongClose}%{codeOpen}%{project}%{codeClose}%{strongOpen}imediat%{strongClose}, inclusiv toate repozitoriile și toate resursele asociate, inclusiv problemele și cererile de îmbinare."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} and everything this project contains. %{strongOpen}There is no going back%{strongClose}"
+msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}on %{date}%{strongClose}, including its repositories and all related resources, including issues and merge requests."
-msgstr "Această acțiune va %{strongOpen}șterge definitiv%{strongClose}%{codeOpen}%{project}%{codeClose}%{strongOpen}pe%{date}%{strongClose}, inclusiv toate repozitoriile și toate resursele asociate, inclusiv problemele și cererile de îmbinare."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains."
+msgstr ""
+
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains. %{strongOpen}There is no going back.%{strongClose}"
+msgstr ""
msgid "This action will %{strongOpen}permanently remove%{strongClose} %{codeOpen}%{group}%{codeClose} %{strongOpen}immediately%{strongClose}."
msgstr ""
@@ -36892,9 +37645,6 @@ msgstr ""
msgid "This file was modified for readability, and can't accept suggestions. Edit it directly."
msgstr ""
-msgid "This forked project has the following:"
-msgstr ""
-
msgid "This form is disabled in preview"
msgstr ""
@@ -36907,7 +37657,7 @@ msgstr ""
msgid "This group can't be removed because it is linked to a subscription. To remove this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
-msgid "This group can't be transfered because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
+msgid "This group can't be transferred because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
msgid "This group cannot be invited to a project inside a group with enforced SSO"
@@ -36934,6 +37684,9 @@ 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 incident is already escalated with '%{escalation_policy_name}'."
+msgstr ""
+
msgid "This invitation was sent to %{mail_to_invite_email}, but you are signed in as %{link_to_current_user} with email %{mail_to_current_user}."
msgstr ""
@@ -36952,9 +37705,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 merge train pipeline"
-msgstr ""
-
msgid "This is a private email address %{helpIcon} generated just for you. Anyone who has it can create issues or merge requests as if they were you. If that happens, %{resetLinkStart}reset this token%{resetLinkEnd}."
msgstr ""
@@ -36976,6 +37726,12 @@ msgstr ""
msgid "This is your current session"
msgstr ""
+msgid "This issue cannot be assigned to a confidential epic because it is public."
+msgstr ""
+
+msgid "This issue cannot be made public because it belongs to a confidential epic."
+msgstr ""
+
msgid "This issue is confidential and should only be visible to team members with at least Reporter access."
msgstr ""
@@ -37093,6 +37849,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 branch is protected from force push."
+msgstr ""
+
msgid "This merge request cannot be rebased while there are conflicts."
msgstr ""
@@ -37144,9 +37903,15 @@ msgstr ""
msgid "This pipeline was triggered by a schedule."
msgstr ""
+msgid "This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project"
msgstr ""
+msgid "This project can be restored until %{date}."
+msgstr ""
+
msgid "This project cannot be %{visibilityLevel} because the visibility of %{openShowLink}%{name}%{closeShowLink} is %{visibility}. To make this project %{visibilityLevel}, you must first %{openEditLink}change the visibility%{closeEditLink} of the parent group."
msgstr ""
@@ -37165,6 +37930,9 @@ msgstr ""
msgid "This project is %{strongStart}NOT%{strongEnd} a fork, and has the following:"
msgstr ""
+msgid "This project is %{strongStart}NOT%{strongEnd} a fork. This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -37858,6 +38626,9 @@ msgstr ""
msgid "Today"
msgstr ""
+msgid "Todos count"
+msgstr ""
+
msgid "Todos|Are you looking for things to do? Take a look at %{strongStart}%{openIssuesLinkStart}open issues%{openIssuesLinkEnd}%{strongEnd}, contribute to %{strongStart}%{mergeRequestLinkStart}a merge request%{mergeRequestLinkEnd}%{mergeRequestLinkEnd}%{strongEnd}, or mention someone in a comment to automatically assign them a new to-do item."
msgstr ""
@@ -38131,11 +38902,8 @@ msgstr ""
msgid "Trending"
msgstr ""
-msgid "Trials|%{planName} Trial %{enDash} %{num} day left"
-msgid_plural "Trials|%{planName} Trial %{enDash} %{num} days left"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgid "Trials|%{planName} Trial"
+msgstr ""
msgid "Trials|Compare all plans"
msgstr ""
@@ -38143,6 +38911,9 @@ msgstr ""
msgid "Trials|Create a new group to start your GitLab Ultimate trial."
msgstr ""
+msgid "Trials|Day %{daysUsed}/%{duration}"
+msgstr ""
+
msgid "Trials|Go back to GitLab"
msgstr ""
@@ -38392,7 +39163,7 @@ msgstr ""
msgid "URL is triggered when repository is updated"
msgstr ""
-msgid "URL must be percent-encoded if neccessary."
+msgid "URL must be percent-encoded if necessary."
msgstr ""
msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
@@ -38611,6 +39382,9 @@ msgstr ""
msgid "Unlock account"
msgstr ""
+msgid "Unlock more features with GitLab Ultimate"
+msgstr ""
+
msgid "Unlock the discussion"
msgstr ""
@@ -38674,6 +39448,9 @@ msgstr ""
msgid "Unsubscribes from this %{quick_action_target}."
msgstr ""
+msgid "Unsupported sort value."
+msgstr ""
+
msgid "Unsupported todo type passed. Supported todo types are: %{todo_types}"
msgstr ""
@@ -38902,6 +39679,9 @@ msgstr ""
msgid "UsageQuota|File attachments and smaller design graphics."
msgstr ""
+msgid "UsageQuota|From %{storage_enforcement_date} storage limits will apply to this namespace. View and manage your usage in %{strong_start}Group Settings &gt; Usage quotas%{strong_end}."
+msgstr ""
+
msgid "UsageQuota|Git repository."
msgstr ""
@@ -38962,6 +39742,9 @@ msgstr ""
msgid "UsageQuota|Storage type"
msgstr ""
+msgid "UsageQuota|Storage used"
+msgstr ""
+
msgid "UsageQuota|This is the total amount of storage used across your projects within this namespace."
msgstr ""
@@ -39157,6 +39940,12 @@ msgstr ""
msgid "Use hashed storage paths for newly created and renamed repositories. Always enabled since 13.0."
msgstr "Utilizați traiectorii de stocare hashed pentru repozitorii nou-create și redenumite. Activat mereu din versiunea 13.0."
+msgid "Use issue count"
+msgstr ""
+
+msgid "Use issue weight"
+msgstr ""
+
msgid "Use one line per URI"
msgstr ""
@@ -39538,6 +40327,9 @@ msgstr ""
msgid "Users"
msgstr ""
+msgid "Users API rate limit"
+msgstr ""
+
msgid "Users can launch a development environment from a GitLab browser tab when the %{linkStart}Gitpod%{linkEnd} integration is enabled."
msgstr ""
@@ -39865,6 +40657,9 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View group pipeline usage quota"
+msgstr ""
+
msgid "View incident details at"
msgstr ""
@@ -40018,6 +40813,9 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
+msgid "Vulnerability"
+msgstr ""
+
msgid "Vulnerability Report"
msgstr ""
@@ -40069,6 +40867,9 @@ msgstr ""
msgid "VulnerabilityManagement|An unverified non-confirmed finding"
msgstr ""
+msgid "VulnerabilityManagement|At least one identifier is required"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -40078,12 +40879,24 @@ msgstr "Nu s-a putut procesa %{issueReference}: %{errorMessage}."
msgid "VulnerabilityManagement|Create Jira issue"
msgstr ""
+msgid "VulnerabilityManagement|Enter a name"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE code"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE identifier URL"
+msgstr ""
+
msgid "VulnerabilityManagement|Fetching linked Jira issues"
msgstr ""
msgid "VulnerabilityManagement|Manually add a vulnerability entry into the vulnerability report."
msgstr ""
+msgid "VulnerabilityManagement|Name is a required field"
+msgstr ""
+
msgid "VulnerabilityManagement|Needs triage"
msgstr ""
@@ -40099,6 +40912,18 @@ msgstr ""
msgid "VulnerabilityManagement|Select a method"
msgstr ""
+msgid "VulnerabilityManagement|Select a severity level"
+msgstr ""
+
+msgid "VulnerabilityManagement|Select a status"
+msgstr ""
+
+msgid "VulnerabilityManagement|Severity is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Something went wrong while creating vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -40123,6 +40948,12 @@ msgstr ""
msgid "VulnerabilityManagement|Something went wrong, could not update vulnerability state."
msgstr ""
+msgid "VulnerabilityManagement|Status is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Submit vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Summary, detailed description, steps to reproduce, etc."
msgstr ""
@@ -40318,6 +41149,9 @@ msgstr ""
msgid "WARNING:"
msgstr "ATENÈšIE:"
+msgid "WARNING: This snippet contains hidden files which might be used to mask malicious behavior. Exercise caution if cloning and executing code from this snippet."
+msgstr ""
+
msgid "Wait for the file to load to copy its contents"
msgstr ""
@@ -40537,6 +41371,15 @@ msgstr ""
msgid "Webhooks|An issue is created, updated, closed, or reopened."
msgstr ""
+msgid "Webhooks|Are you sure you want to delete this group hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this project hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this webhook?"
+msgstr ""
+
msgid "Webhooks|Comments"
msgstr ""
@@ -40546,6 +41389,9 @@ msgstr ""
msgid "Webhooks|Confidential issues events"
msgstr ""
+msgid "Webhooks|Delete webhook"
+msgstr ""
+
msgid "Webhooks|Deployment events"
msgstr ""
@@ -40780,6 +41626,9 @@ msgstr ""
msgid "Wiki"
msgstr ""
+msgid "Wiki page"
+msgstr ""
+
msgid "Wiki page was successfully created."
msgstr ""
@@ -40885,7 +41734,7 @@ msgstr ""
msgid "WikiPageConflictMessage|Someone edited the page the same time you did. Please check out %{wikiLinkStart}the page%{wikiLinkEnd} and make sure your changes will not unintentionally remove theirs."
msgstr ""
-msgid "WikiPage|An error occured while trying to render the content editor. Please try again later."
+msgid "WikiPage|An error occurred while trying to render the content editor. Please try again later."
msgstr ""
msgid "WikiPage|Are you sure you want to switch back to the classic editor?"
@@ -41044,6 +41893,18 @@ msgstr ""
msgid "WorkItem|New Task"
msgstr ""
+msgid "WorkItem|Something went wrong when creating a work item. Please try again"
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching the work item. Please try again."
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching work item types. Please try again"
+msgstr ""
+
+msgid "WorkItem|Type"
+msgstr ""
+
msgid "WorkItem|Work Items"
msgstr ""
@@ -41110,7 +41971,10 @@ msgstr ""
msgid "You are about to add %{usersTag} people to the discussion. They will all receive a notification."
msgstr ""
-msgid "You are about to permanently delete this project"
+msgid "You are about to delete this forked project containing:"
+msgstr ""
+
+msgid "You are about to delete this project containing:"
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."
@@ -41131,6 +41995,9 @@ msgstr ""
msgid "You are attempting to update a file that has changed since you started editing it."
msgstr ""
+msgid "You are billed if you exceed this number. %{qsrOverageLinkStart}How does billing work?%{qsrOverageLinkEnd}"
+msgstr ""
+
msgid "You are connected to the Prometheus server, but there is currently no data to display."
msgstr ""
@@ -41188,6 +42055,9 @@ msgstr ""
msgid "You are not authorized to update this scanner profile"
msgstr ""
+msgid "You are not authorized to upload metric images"
+msgstr ""
+
msgid "You are now impersonating %{username}"
msgstr ""
@@ -41341,9 +42211,6 @@ msgstr "Puteți transfera proiectul numai în spațiile de nume pe care le gesti
msgid "You can only upload one design when dropping onto an existing design."
msgstr ""
-msgid "You can recover this project until %{date}"
-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 ""
@@ -41392,9 +42259,6 @@ msgstr ""
msgid "You cannot write to this read-only GitLab instance."
msgstr ""
-msgid "You can’t %{tag_start}edit%{tag_end} files directly in this project. Fork this project and submit a merge request with your changes."
-msgstr ""
-
msgid "You can’t edit files directly in this project. Fork this project and submit a merge request with your changes."
msgstr ""
@@ -41548,9 +42412,6 @@ 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 set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
@@ -41581,12 +42442,6 @@ msgstr ""
msgid "You must have maintainer access to force delete a lock"
msgstr ""
-msgid "You must have permission to create a project in a group before forking."
-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 ""
@@ -41992,8 +42847,8 @@ msgstr "Proiectele dvs."
msgid "Your public email will be displayed on your public profile."
msgstr "E-mail-ul dvs. public va fi afișat pe profilul dvs. public."
-msgid "Your request for access could not be processed: %{error_meesage}"
-msgstr "Solicitarea dvs. de acces nu a putut fi procesată: %{error_meesage}"
+msgid "Your request for access could not be processed: %{error_message}"
+msgstr ""
msgid "Your request for access has been queued for review."
msgstr "Solicitarea dvs. de acces a fost pusă în așteptare pentru examinare."
@@ -42178,6 +43033,9 @@ msgstr "arhivat"
msgid "archived:"
msgstr "arhivat:"
+msgid "artifacts"
+msgstr ""
+
msgid "assign yourself"
msgstr "atribuie-te"
@@ -42208,6 +43066,9 @@ msgstr[2] "ramurii"
msgid "branch name"
msgstr "numele ramurii"
+msgid "builds"
+msgstr ""
+
msgid "by"
msgstr "de"
@@ -42634,6 +43495,9 @@ msgstr ""
msgid "contact with same email already exists in group hierarchy"
msgstr ""
+msgid "container registry images"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr "container_name poate conține numai litere mici, cifre, '-' și '.' și trebuie să înceapă și să se termine cu un caracter alfanumeric"
@@ -42673,6 +43537,9 @@ msgstr "creat de"
msgid "data"
msgstr "date"
+msgid "database"
+msgstr ""
+
msgid "date must not be after 9999-12-31"
msgstr "data nu trebuie să fie după 9999-12-31"
@@ -42697,9 +43564,6 @@ msgstr ""
msgid "design"
msgstr "design"
-msgid "detached"
-msgstr "detașat"
-
msgid "disabled"
msgstr "dezactivat"
@@ -42952,7 +43816,7 @@ msgstr "nu este descendent al grupului care deține șablonul"
msgid "is not a valid X509 certificate."
msgstr "nu este un certificat X509 valid."
-msgid "is not allowed for sign-up."
+msgid "is not allowed for sign-up. Please use your regular email address."
msgstr ""
msgid "is not allowed for this group."
@@ -42964,7 +43828,7 @@ msgstr "nu este permis pentru acest proiect."
msgid "is not allowed since the group is not top-level group."
msgstr "nu este permis, deoarece grupul nu este un grup de nivel superior."
-msgid "is not allowed."
+msgid "is not allowed. Please use your regular email address."
msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
@@ -43051,6 +43915,9 @@ msgstr "mai putin de un minut"
msgid "level: %{level}"
msgstr "nivel: %{level}"
+msgid "lfs objects"
+msgstr ""
+
msgid "limit of %{project_limit} reached"
msgstr ""
@@ -43273,6 +44140,9 @@ msgstr ""
msgid "mrWidget|Merge blocked: pipeline must succeed. It's waiting for a manual action to continue."
msgstr ""
+msgid "mrWidget|Merge blocked: pipeline must succeed. Push a commit that fixes the failure, or %{linkStart}learn about other solutions.%{linkEnd}"
+msgstr ""
+
msgid "mrWidget|Merge blocked: this merge request must be approved."
msgstr ""
@@ -43390,9 +44260,6 @@ msgstr ""
msgid "mrWidget|The changes were not merged into"
msgstr ""
-msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr "Ramura sursă a fost ștearsă"
@@ -43540,9 +44407,6 @@ msgstr ""
msgid "open issue"
msgstr ""
-msgid "opened %{timeAgo}"
-msgstr "deschis %{timeAgo}"
-
msgid "or"
msgstr "sau"
@@ -43555,6 +44419,12 @@ msgstr[0] "din %d test total"
msgstr[1] "din %d teste totale"
msgstr[2] "din %d teste totale"
+msgid "packages"
+msgstr ""
+
+msgid "pages"
+msgstr ""
+
msgid "parent"
msgid_plural "parents"
msgstr[0] "părinte"
@@ -43708,6 +44578,9 @@ msgstr[0] "răspuns"
msgstr[1] "răspunsuri"
msgstr[2] "răspunsurile"
+msgid "repositories"
+msgstr ""
+
msgid "repository:"
msgstr "repozitoriu:"
@@ -43828,12 +44701,18 @@ msgstr ""
msgid "tag name"
msgstr "nume etichetă"
+msgid "terraform states"
+msgstr ""
+
msgid "the correct format."
msgstr "formatul corect."
msgid "the file"
msgstr "fișierul"
+msgid "the following epic(s)"
+msgstr ""
+
msgid "the following issue(s)"
msgstr "următoarea (următoarele) problemă(e)"
@@ -43846,21 +44725,12 @@ msgstr "atunci"
msgid "this document"
msgstr "acest document"
-msgid "this issue cannot be assigned to a confidential epic since it is public"
-msgstr "această problemă nu poate fi atribuită unui epic confidențial deoarece este publică"
-
-msgid "this issue cannot be made public since it belongs to a confidential epic"
-msgstr "această problemă nu poate fi făcută publică deoarece aparține unui epic confidențial"
-
msgid "time summary"
msgstr "sumar timp"
msgid "toggle collapse"
msgstr ""
-msgid "train"
-msgstr "tren"
-
msgid "triggered"
msgstr ""
@@ -43990,3 +44860,6 @@ msgstr "{group}"
msgid "{project}"
msgstr "{project}"
+msgid "✔"
+msgstr ""
+
diff --git a/locale/ru/gitlab.po b/locale/ru/gitlab.po
index be894296c2b..55409d05a9c 100644
--- a/locale/ru/gitlab.po
+++ b/locale/ru/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: ru\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2022-02-02 15:43\n"
+"PO-Revision-Date: 2022-03-01 20:37\n"
msgid " %{start} to %{end}"
msgstr " %{start} по %{end}"
@@ -174,6 +174,13 @@ msgstr[1] "%d утверждающих (вы утвердили)"
msgstr[2] "%d утверждающих (вы утвердили)"
msgstr[3] "%d утверждающих (вы утвердили)"
+msgid "%d assigned issue"
+msgid_plural "%d assigned issues"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] "%d измененный файл"
@@ -559,12 +566,33 @@ msgstr[1] "%d уÑзвимоÑти отклонено"
msgstr[2] "%d уÑзвимоÑтей отклонено"
msgstr[3] "%d уÑзвимоÑтей отклонено"
-msgid "%d vulnerability updated"
-msgid_plural "%d vulnerabilities updated"
-msgstr[0] "%d уÑзвимоÑÑ‚ÑŒ обновлена"
-msgstr[1] "%d уÑзвимоÑти обновлено"
-msgstr[2] "%d уÑзвимоÑтей обновлено"
-msgstr[3] "%d уÑзвимоÑтей обновлено"
+msgid "%d vulnerability set to confirmed"
+msgid_plural "%d vulnerabilities set to confirmed"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
+msgid "%d vulnerability set to dismissed"
+msgid_plural "%d vulnerabilities set to dismissed"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
+msgid "%d vulnerability set to needs triage"
+msgid_plural "%d vulnerabilities set to needs triage"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
+msgid "%d vulnerability set to resolved"
+msgid_plural "%d vulnerabilities set to resolved"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
msgid "%d warning found:"
msgid_plural "%d warnings found:"
@@ -662,6 +690,12 @@ msgstr[3] "%{completedCount} из %{count} задач выполнено"
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr "Завершено %{completedWeight} из %{totalWeight} приоритета"
+msgid "%{completed} of %{total} issues closed"
+msgstr ""
+
+msgid "%{completed} of %{total} weight completed"
+msgstr ""
+
msgid "%{cores} cores"
msgstr "%{cores} Ñдер"
@@ -1022,6 +1056,9 @@ msgstr "%{openedEpics} открыто, %{closedEpics} закрыто"
msgid "%{openedIssues} open, %{closedIssues} closed"
msgstr "%{openedIssues} открыто, %{closedIssues} закрыто"
+msgid "%{percentage}%% issues closed"
+msgstr ""
+
msgid "%{percentage}%% weight completed"
msgstr "%{percentage}%% приоритета завершено"
@@ -1481,6 +1518,9 @@ msgstr[1] "- Пользователи"
msgstr[2] "- Пользователи"
msgstr[3] "- Пользователи"
+msgid "- of - issues closed"
+msgstr ""
+
msgid "- of - weight completed"
msgstr "- из - приоритета завершено"
@@ -1669,8 +1709,8 @@ msgstr "10-19 ÑодейÑтвий"
msgid "1000+"
msgstr "1000+"
-msgid "192.168.0.0/24"
-msgstr "192.168.0.0/24"
+msgid "192.168.0.0/24 or 2001:0DB8:1234::/48"
+msgstr ""
msgid "1st contribution!"
msgstr "Первый вклад!"
@@ -1981,13 +2021,13 @@ msgstr "folder/openapi.json"
msgid "AWS Access Key"
msgstr "Ключ доÑтупа AWS"
-msgid "AWS Access Key. Only required if not using role instance credentials"
-msgstr ""
-
msgid "AWS Secret Access Key"
msgstr "Секретный ключ доÑтупа AWS"
-msgid "AWS Secret Access Key. Only required if not using role instance credentials"
+msgid "AWS access key ID (Optional)"
+msgstr ""
+
+msgid "AWS secret access key (Optional)"
msgstr ""
msgid "AWS service error: %{error}"
@@ -2047,9 +2087,6 @@ msgstr "ДоÑтуп запрещен. Проверьте Ñвой уровенÑ
msgid "Access granted"
msgstr "ДоÑтуп предоÑтавлен"
-msgid "Access key ID"
-msgstr "ID ключа доÑтупа"
-
msgid "Access requests"
msgstr "ЗапроÑÑ‹ доÑтупа"
@@ -2224,8 +2261,8 @@ msgstr ""
msgid "Activity"
msgstr "ÐктивноÑÑ‚ÑŒ"
-msgid "Activity|An error occured while retrieving activity. Reload the page to try again."
-msgstr "Произошла ошибка при получении активноÑти. Перезагрузите Ñтраницу, чтобы повторить попытку."
+msgid "Activity|An error occurred while retrieving activity. Reload the page to try again."
+msgstr ""
msgid "Add"
msgstr "Добавить"
@@ -2263,6 +2300,9 @@ msgstr "ПриÑоединитьÑÑ Ðº вÑтрече в Zoom"
msgid "Add a %{type}"
msgstr "Добавить %{type}"
+msgid "Add a GCP region"
+msgstr ""
+
msgid "Add a GPG key"
msgstr "Добавить ключ GPG"
@@ -2314,6 +2354,9 @@ msgstr "Добавить новое обÑуждение"
msgid "Add a numbered list"
msgstr "Добавить нумерованный ÑпиÑок"
+msgid "Add a related epic"
+msgstr ""
+
msgid "Add a related issue"
msgstr ""
@@ -2428,6 +2471,9 @@ msgstr "Добавить или удалить коммиты, Ñлитые ра
msgid "Add or subtract spent time"
msgstr "Добавить или вычеÑÑ‚ÑŒ потраченное времÑ"
+msgid "Add people"
+msgstr ""
+
msgid "Add previously merged commits"
msgstr "Добавить ранее Ñлитые коммиты"
@@ -2494,6 +2540,9 @@ msgstr ""
msgid "Add webhook"
msgstr "Добавить веб-обработчик"
+msgid "Add your team members and others to GitLab."
+msgstr ""
+
msgid "Add/remove"
msgstr "Добавить/удалить"
@@ -3316,12 +3365,6 @@ msgstr "РаÑширенные параметры ÑкÑпорта"
msgid "AdvancedSearch|Reindex required"
msgstr "ТребуетÑÑ Ð¿Ð¾Ð²Ñ‚Ð¾Ñ€Ð½Ð°Ñ Ð¸Ð½Ð´ÐµÐºÑациÑ"
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. Permanently deleting this project will %{strongStart}immediately delete%{strongEnd} its repositories and %{strongStart}all related resources%{strongEnd}, including issues, merge requests etc."
-msgstr ""
-
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. You will lose this project's repository and %{strongStart}all related resources%{strongEnd}, including issues and merge requests."
-msgstr ""
-
msgid "After a successful password update you will be redirected to login screen."
msgstr "ПоÑле уÑпешного Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ð¿Ð°Ñ€Ð¾Ð»Ñ Ð²Ñ‹ будете перенаправлены на Ñкран входа в ÑиÑтему."
@@ -3352,6 +3395,9 @@ msgstr "API-ключ Akismet:"
msgid "Akismet helps prevent the creation of spam issues in public projects."
msgstr "Akismet помогает боротьÑÑ Ñо Ñпамом в публичных проектах."
+msgid "Alert"
+msgstr ""
+
msgid "AlertManagement|Acknowledged"
msgstr "Прочитано"
@@ -3724,9 +3770,6 @@ msgstr "Ð’Ñе адреÑа Ñлектронной почты будут иÑпÐ
msgid "All environments"
msgstr "Ð’Ñе окружениÑ"
-msgid "All epics"
-msgstr "Ð’Ñе цели"
-
msgid "All groups and projects"
msgstr "Ð’Ñе группы и проекты"
@@ -4052,7 +4095,7 @@ msgid "An error occurred while fetching projects autocomplete."
msgstr "Произошла ошибка при загрузке Ð°Ð²Ñ‚Ð¾Ð´Ð¾Ð¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð¾Ð²."
msgid "An error occurred while fetching reference"
-msgstr ""
+msgstr "Ошибка при получении ÑÑылки"
msgid "An error occurred while fetching tags. Retry the search."
msgstr "Произошла ошибка при получении тегов. Повторите поиÑк."
@@ -4076,7 +4119,7 @@ msgid "An error occurred while fetching the latest pipeline."
msgstr "Произошла ошибка при извлечении поÑледней Ñборочной линии."
msgid "An error occurred while fetching the pipelines jobs."
-msgstr ""
+msgstr "Произошла ошибка при получении заданий Ñборочной линии."
msgid "An error occurred while fetching the releases. Please try again."
msgstr "Произошла ошибка при выборке релизов. ПожалуйÑта, попробуйте ещё раз."
@@ -4094,19 +4137,19 @@ msgid "An error occurred while getting projects"
msgstr "Произошла ошибка при получении ÑпиÑка проектов"
msgid "An error occurred while initializing path locks"
-msgstr ""
+msgstr "Произошла ошибка при инициализации блокировок пути"
msgid "An error occurred while loading a section of this page."
-msgstr ""
+msgstr "Произошла ошибка при загрузке раздела Ñтой Ñтраницы."
msgid "An error occurred while loading all the files."
msgstr "Произошла ошибка при загрузке вÑех файлов."
msgid "An error occurred while loading chart data"
-msgstr ""
+msgstr "Произошла ошибка при загрузке данных диаграммы"
msgid "An error occurred while loading code owners."
-msgstr ""
+msgstr "Произошла ошибка при загрузке владельцев кода."
msgid "An error occurred while loading commit signatures"
msgstr "Произошла ошибка при загрузке подпиÑей коммита"
@@ -4130,19 +4173,19 @@ msgid "An error occurred while loading merge requests."
msgstr "Произошла ошибка при загрузке запроÑов на ÑлиÑние."
msgid "An error occurred while loading projects."
-msgstr ""
+msgstr "При получении ÑпиÑка проектов произошла ошибка."
msgid "An error occurred while loading the Jobs tab."
-msgstr ""
+msgstr "Произошла ошибка при загрузке вкладки \"ЗаданиÑ\"."
msgid "An error occurred while loading the Needs tab."
-msgstr ""
+msgstr "Произошла ошибка при загрузке вкладки \"ПотребноÑти\"."
msgid "An error occurred while loading the Test Reports tab."
-msgstr ""
+msgstr "Произошла ошибка при загрузке вкладки \"Отчеты по теÑтам\"."
msgid "An error occurred while loading the access tokens form, please try again."
-msgstr ""
+msgstr "Произошла ошибка при загрузке формы токенов доÑтупа. ПожалуйÑта, повторите попытку."
msgid "An error occurred while loading the blob controls."
msgstr ""
@@ -4163,28 +4206,28 @@ msgid "An error occurred while loading the file. Please try again later."
msgstr "Произошла ошибка при загрузке файла. ПожалуйÑта, попробуйте ещё раз позже."
msgid "An error occurred while loading the file. Please try again."
-msgstr ""
+msgstr "Произошла ошибка при загрузке файла. ПожалуйÑта, попробуйте ещё раз."
msgid "An error occurred while loading the merge request changes."
msgstr "Произошла ошибка при загрузке изменений запроÑа на ÑлиÑние."
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 notification settings. Please try again."
-msgstr ""
+msgstr "Произошла ошибка при загрузке наÑтроек уведомлений. ПожалуйÑта, попробуйте ещё раз."
msgid "An error occurred while loading the pipeline."
msgstr "Произошла ошибка при загрузке Ñборочной линии."
msgid "An error occurred while loading the pipelines jobs."
-msgstr ""
+msgstr "Произошла ошибка при загрузке заданий Ñборочных линий."
msgid "An error occurred while loading your content. Please try again."
-msgstr ""
+msgstr "Произошла ошибка при загрузке Ñодержимого. ПожалуйÑта, попробуйте ещё раз."
msgid "An error occurred while making the request."
msgstr "Произошла ошибка при выполнении запроÑа."
@@ -4193,7 +4236,7 @@ msgid "An error occurred while moving the issue."
msgstr "Произошла ошибка при перемещении обÑуждениÑ."
msgid "An error occurred while parsing recent searches"
-msgstr ""
+msgstr "Произошла ошибка при обработке недавнего поиÑка"
msgid "An error occurred while parsing the file."
msgstr "Произошла ошибка при обработке файла."
@@ -4208,7 +4251,7 @@ msgid "An error occurred while rendering preview broadcast message"
msgstr "Произошла ошибка при визуализации проÑмотра широковещательного ÑообщениÑ"
msgid "An error occurred while rendering the editor"
-msgstr ""
+msgstr "Произошла ошибка при отображении редактора"
msgid "An error occurred while reordering issues."
msgstr "Произошла ошибка при переназначении задач."
@@ -4220,13 +4263,13 @@ msgid "An error occurred while retrieving diff"
msgstr "Произошла ошибка при получении различий"
msgid "An error occurred while retrieving diff files"
-msgstr ""
+msgstr "Произошла ошибка при получении diff-файлов"
msgid "An error occurred while retrieving projects."
-msgstr ""
+msgstr "Произошла ошибка при получении проектов."
msgid "An error occurred while saving changes: %{error}"
-msgstr ""
+msgstr "Произошла ошибка при Ñохранении изменений: %{error}"
msgid "An error occurred while saving the setting"
msgid_plural "An error occurred while saving the settings"
@@ -4242,10 +4285,10 @@ msgid "An error occurred while triggering the job."
msgstr "Произошла ошибка при запуÑке заданиÑ."
msgid "An error occurred while trying to generate the report. Please try again later."
-msgstr ""
+msgstr "Произошла ошибка при попытке Ñоздать отчёт. ПожалуйÑта, повторите попытку позже."
msgid "An error occurred while trying to run a new pipeline for this merge request."
-msgstr ""
+msgstr "Произошла ошибка при попытке запуÑтить новую Ñборочную линию Ð´Ð»Ñ Ñтого запроÑа на ÑлиÑние."
msgid "An error occurred while unsubscribing to notifications."
msgstr "При отпиÑке от уведомлений произошла ошибка."
@@ -4254,10 +4297,10 @@ msgid "An error occurred while updating approvers"
msgstr "Произошла ошибка при обновлении утверждающих"
msgid "An error occurred while updating assignees."
-msgstr ""
+msgstr "Произошла ошибка при обновлении назначенных."
msgid "An error occurred while updating configuration."
-msgstr ""
+msgstr "Произошла ошибка при обновлении конфигурации."
msgid "An error occurred while updating labels."
msgstr ""
@@ -4467,14 +4510,17 @@ msgstr ""
msgid "ApplicationSettings|Approve users in the pending approval status?"
msgstr ""
-msgid "ApplicationSettings|By making this change, you will automatically approve %d user with the pending approval status."
-msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users with the pending approval status."
+msgid "ApplicationSettings|Approve users who are pending approval?"
+msgstr ""
+
+msgid "ApplicationSettings|By making this change, you will automatically approve %d user who is pending approval."
+msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users who are pending approval."
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
-msgid "ApplicationSettings|By making this change, you will automatically approve all users in pending approval status."
+msgid "ApplicationSettings|By making this change, you will automatically approve all users who are pending approval."
msgstr ""
msgid "ApplicationSettings|Denied domains for sign-ups"
@@ -4890,12 +4936,12 @@ msgstr "Ðрхивные проекты"
msgid "Archiving the project will make it entirely read-only. It is hidden from the dashboard and doesn't show up in searches. %{strong_start}The repository cannot be committed to, and no issues, comments, or other entities can be created.%{strong_end} %{link_start}Learn more.%{link_end}"
msgstr "ÐÑ€Ñ…Ð¸Ð²Ð°Ñ†Ð¸Ñ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð° Ñделает его Ñовершенно недоÑтупным Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñи. Он не будет отображатьÑÑ Ð½Ð° панели ÑƒÐ¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð¸ в результатах поиÑка. %{strong_start}Ð’ репозиторий Ð½ÐµÐ»ÑŒÐ·Ñ Ð±ÑƒÐ´ÐµÑ‚ вноÑить изменениÑ, Ñоздавать обÑуждениÑ, комментарии, а также другие ÑущноÑти.%{strong_end} %{link_start}Узнать подробнее.%{link_end}"
-msgid "Are you ABSOLUTELY SURE you wish to delete this project?"
-msgstr "Ð’Ñ‹ ÐБСОЛЮТÐО УВЕРЕÐЫ, что хотите удалить Ñтот проект?"
-
msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
msgstr "Ð’Ñ‹ ÐБСОЛЮТÐО УВЕРЕÐЫ, что хотите удалить Ñту группу?"
+msgid "Are you absolutely sure?"
+msgstr ""
+
msgid "Are you sure that you want to archive this project?"
msgstr "Ð’Ñ‹ уверены, что хотите архивировать Ñтот проект?"
@@ -4929,12 +4975,18 @@ msgstr "Ð’Ñ‹ уверены что дейÑтвительно хотите удÐ
msgid "Are you sure you want to delete this SSH key?"
msgstr "Ð’Ñ‹ уверены, что хотите удалить Ñтот SSH ключ?"
+msgid "Are you sure you want to delete this comment?"
+msgstr ""
+
msgid "Are you sure you want to delete this deploy key?"
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 label?"
+msgstr ""
+
msgid "Are you sure you want to delete this pipeline schedule?"
msgstr "Ð’Ñ‹ уверены, что вы хотите удалить Ñто раÑпиÑание Ñборочной линии?"
@@ -4950,9 +5002,6 @@ msgstr "Ð’Ñ‹ уверены, что хотите отменить Ñтот коÐ
msgid "Are you sure you want to discard your changes?"
msgstr "Ð’Ñ‹ уверены, что хотите отменить изменениÑ?"
-msgid "Are you sure you want to erase this build?"
-msgstr "Ð’Ñ‹ уверены, что вы хотите удалить Ñту Ñборку?"
-
msgid "Are you sure you want to import %d repository?"
msgid_plural "Are you sure you want to import %d repositories?"
msgstr[0] "Вы уверены, что хотите импортировать %d репозиторий?"
@@ -5002,6 +5051,9 @@ msgstr "Ð’Ñ‹ уверены, что вы хотите удалить Ñту ид
msgid "Are you sure you want to remove this list?"
msgstr "Ð’Ñ‹ уверены, что хотите удалить Ñтот ÑпиÑок?"
+msgid "Are you sure you want to remove this nickname?"
+msgstr ""
+
msgid "Are you sure you want to reset the health check token?"
msgstr "Ð’Ñ‹ уверены, что хотите ÑброÑить Ñтот токен проверки работоÑпоÑобноÑти?"
@@ -5014,12 +5066,12 @@ msgstr "Вы уверены, что хотите попробовать повт
msgid "Are you sure you want to revoke this %{type}? This action cannot be undone."
msgstr "Ð’Ñ‹ уверены, что хотите отозвать %{type}? Это дейÑтвие Ð½ÐµÐ»ÑŒÐ·Ñ Ð¾Ñ‚Ð¼ÐµÐ½Ð¸Ñ‚ÑŒ."
-msgid "Are you sure you want to revoke this nickname?"
-msgstr "Ð’Ñ‹ уверены, что хотите отменить Ñтот ник?"
-
msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
msgstr "Ð’Ñ‹ уверены, что хотите отозвать Ñтот перÑональный токен доÑтупа? Это дейÑтвие не может быть отменено."
+msgid "Are you sure you want to revoke this project access token? This action cannot be undone."
+msgstr ""
+
msgid "Are you sure you want to stop this environment?"
msgstr "Ð’Ñ‹ уверены, что вы хотите оÑтановить Ñто окружение?"
@@ -5164,9 +5216,6 @@ msgstr "Ðазначено %{assigneeName}"
msgid "Assigned to %{assignee_name}"
msgstr "Ðазначен %{assignee_name}"
-msgid "Assigned to %{name}"
-msgstr "Ðазначено %{name}"
-
msgid "Assigned to me"
msgstr "Ðазначить мне"
@@ -5235,6 +5284,9 @@ msgstr[3] "Прикрепить %d файлов"
msgid "Attaching the file failed."
msgstr "Ðе удалоÑÑŒ прикрепить файл."
+msgid "Attention"
+msgstr ""
+
msgid "Audit Events"
msgstr "Ðудит Ñобытий"
@@ -5397,6 +5449,12 @@ msgstr "Ðвторизован в"
msgid "Authorized applications (%{size})"
msgstr "Ðвторизованные Ð¿Ñ€Ð¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ (%{size})"
+msgid "AuthorizedApplication|Are you sure you want to revoke this application?"
+msgstr ""
+
+msgid "AuthorizedApplication|Revoke application"
+msgstr ""
+
msgid "Authors: %{authors}"
msgstr "Ðвторы: %{authors}"
@@ -6598,6 +6656,9 @@ msgstr "Релизы"
msgid "CICDAnalytics|Shared Runners Usage"
msgstr ""
+msgid "CICDAnalytics|Shared runner pipeline minute duration by month"
+msgstr ""
+
msgid "CICDAnalytics|Shared runner usage"
msgstr ""
@@ -6739,6 +6800,9 @@ msgstr ""
msgid "Can create groups:"
msgstr "Может Ñоздавать группы:"
+msgid "Can not delete primary training"
+msgstr ""
+
msgid "Can't apply as the source branch was deleted."
msgstr "Ðевозможно применить, так как иÑÑ…Ð¾Ð´Ð½Ð°Ñ Ð²ÐµÑ‚ÐºÐ° была удалена."
@@ -7072,9 +7136,6 @@ msgstr "Ð˜Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð² заголовке не были ÑохраненÑ
msgid "Changing any setting here requires an application restart"
msgstr ""
-msgid "Changing group URL can have unintended side effects."
-msgstr ""
-
msgid "Charts can't be displayed as the request for data has timed out. %{documentationLink}"
msgstr "Ðе удалоÑÑŒ отобразить диаграммы, так как Ð²Ñ€ÐµÐ¼Ñ Ð·Ð°Ð¿Ñ€Ð¾Ñа данных иÑтекло. %{documentationLink}"
@@ -7162,9 +7223,6 @@ msgstr "Проверка ÑтатуÑа утверждениÑ"
msgid "Checking branch availability..."
msgstr "Проверка доÑтупноÑти ветви..."
-msgid "Checking group URL availability..."
-msgstr "Проверка доÑтупноÑти URL группы..."
-
msgid "Checking group path availability..."
msgstr "Проверка доÑтупноÑти пути группы..."
@@ -7662,6 +7720,9 @@ msgstr ""
msgid "Clear recent searches"
msgstr "ОчиÑтить поÑледние запроÑÑ‹"
+msgid "Clear repository checks"
+msgstr ""
+
msgid "Clear search"
msgstr "ОчиÑтить поиÑк"
@@ -7794,9 +7855,6 @@ msgstr "Закрыто %{epicTimeagoDate}"
msgid "Closed MRs"
msgstr ""
-msgid "Closed epics"
-msgstr ""
-
msgid "Closed issues"
msgstr "Закрытые обÑуждениÑ"
@@ -7833,13 +7891,13 @@ msgstr ""
msgid "Cluster level"
msgstr ""
-msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
+msgid "Cluster type must be specified for Stages::ClusterEndpointInserter"
msgstr ""
msgid "ClusterAgents|%{name} successfully deleted"
msgstr ""
-msgid "ClusterAgents|%{number} of %{total} Agents"
+msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
@@ -7881,6 +7939,15 @@ msgstr ""
msgid "ClusterAgents|Agent never connected to GitLab"
msgstr ""
+msgid "ClusterAgents|Agent version mismatch"
+msgstr ""
+
+msgid "ClusterAgents|Agent version mismatch and update"
+msgstr ""
+
+msgid "ClusterAgents|Agent version update required"
+msgstr ""
+
msgid "ClusterAgents|All"
msgstr ""
@@ -7905,7 +7972,7 @@ msgstr ""
msgid "ClusterAgents|Configuration"
msgstr "КонфигурациÑ"
-msgid "ClusterAgents|Connect a cluster through the Agent"
+msgid "ClusterAgents|Connect a cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connect existing cluster"
@@ -7914,13 +7981,13 @@ msgstr ""
msgid "ClusterAgents|Connect with a certificate"
msgstr ""
-msgid "ClusterAgents|Connect with agent"
+msgid "ClusterAgents|Connect with an agent"
msgstr ""
msgid "ClusterAgents|Connect with the GitLab Agent"
msgstr ""
-msgid "ClusterAgents|Connect your cluster through the Agent"
+msgid "ClusterAgents|Connect your cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connected"
@@ -7980,7 +8047,10 @@ msgstr ""
msgid "ClusterAgents|How to register an agent?"
msgstr ""
-msgid "ClusterAgents|Install new Agent"
+msgid "ClusterAgents|How to update an agent?"
+msgstr ""
+
+msgid "ClusterAgents|Install a new agent"
msgstr ""
msgid "ClusterAgents|Last connected %{timeAgo}."
@@ -8007,7 +8077,7 @@ msgstr ""
msgid "ClusterAgents|Never connected"
msgstr ""
-msgid "ClusterAgents|No Agents"
+msgid "ClusterAgents|No agents"
msgstr ""
msgid "ClusterAgents|No clusters connected through cluster certificates"
@@ -8067,6 +8137,9 @@ msgstr ""
msgid "ClusterAgents|The agent has not been connected in a long time. There might be a connectivity issue. Last contact was %{timeAgo}."
msgstr ""
+msgid "ClusterAgents|The agent version do not match each other across your cluster's pods. This can happen when a new agent version was just deployed and Kubernetes is shutting down the old pods."
+msgstr ""
+
msgid "ClusterAgents|The recommended installation method includes the token. If you want to follow the advanced installation method provided in the docs, make sure you save the token value before you close this window."
msgstr ""
@@ -8116,6 +8189,9 @@ msgstr ""
msgid "ClusterAgents|You will need to create a token to connect to your agent"
msgstr "Вам необходимо Ñоздать токен Ð´Ð»Ñ Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ðº агенту"
+msgid "ClusterAgents|Your agent version is out of sync with your GitLab version (v%{version}), which might cause compatibility problems. Update the agent installed on your cluster to the most recent version."
+msgstr ""
+
msgid "ClusterAgents|Your instance doesn't have the %{linkStart}GitLab Agent Server (KAS)%{linkEnd} set up. Ask a GitLab Administrator to install it."
msgstr ""
@@ -8992,9 +9068,6 @@ msgstr "ComboSearch не определен"
msgid "Comma-separated list of email addresses."
msgstr ""
-msgid "Comma-separated list of users allowed to exceed the rate limit."
-msgstr ""
-
msgid "Comma-separated, e.g. '1.1.1.1, 2.2.2.0/24'"
msgstr ""
@@ -9323,6 +9396,12 @@ msgstr ""
msgid "Confidential"
msgstr "Конфиденциально"
+msgid "Confidential issue"
+msgstr ""
+
+msgid "Confidential note"
+msgstr ""
+
msgid "Confidentiality"
msgstr "КонфиденциальноÑÑ‚ÑŒ"
@@ -9356,6 +9435,9 @@ msgstr ""
msgid "Configure Dependency Scanning in `.gitlab-ci.yml`, creating this file if it does not already exist"
msgstr ""
+msgid "Configure GitLab"
+msgstr ""
+
msgid "Configure GitLab runners to start using the Web Terminal. %{helpStart}Learn more.%{helpEnd}"
msgstr "ÐаÑтройте GitLab runner'Ñ‹ Ð´Ð»Ñ Ð½Ð°Ñ‡Ð°Ð»Ð° иÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð’ÐµÐ±-терминала. %{helpStart}Подробнее.%{helpEnd}"
@@ -9404,6 +9486,15 @@ msgstr "ÐаÑтроить ÑущеÑтвующую уÑтановку"
msgid "Configure pipelines to deploy web apps, backend services, APIs and static resources to Google Cloud"
msgstr ""
+msgid "Configure region"
+msgstr ""
+
+msgid "Configure region for environment"
+msgstr ""
+
+msgid "Configure regions"
+msgstr ""
+
msgid "Configure repository mirroring."
msgstr ""
@@ -9437,6 +9528,9 @@ msgstr ""
msgid "Configure which lists are shown for anyone who visits this board"
msgstr ""
+msgid "Configure your environments to be deployed to specific geographical regions"
+msgstr ""
+
msgid "Confirm"
msgstr "Подтвердить"
@@ -9891,7 +9985,7 @@ msgid "ContainerRegistry|To widen your search, change or remove the filters abov
msgstr "Чтобы раÑширить облаÑÑ‚ÑŒ поиÑка, измените или удалите фильтры выше."
msgid "ContainerRegistry|We are having trouble connecting to the Container Registry. Please try refreshing the page. If this error persists, please review %{docLinkStart}the troubleshooting documentation%{docLinkEnd}."
-msgstr ""
+msgstr "У Ð½Ð°Ñ Ð²Ð¾Ð·Ð½Ð¸ÐºÐ»Ð¸ проблемы Ñ Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸ÐµÐ¼ к РееÑтру контейнеров. ПожалуйÑта, попробуйте обновить Ñтраницу. ЕÑли Ñта ошибка повторÑетÑÑ, пожалуйÑта, проÑмотрите %{docLinkStart}документацию по уÑтранению неполадок%{docLinkEnd}."
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}"
@@ -10145,10 +10239,10 @@ msgstr ""
msgid "CorpusManagement|Actions"
msgstr ""
-msgid "CorpusManagement|Corpus are used in fuzz testing as mutation source to Improve future testing."
+msgid "CorpusManagement|Corpus file"
msgstr ""
-msgid "CorpusManagement|Corpus file"
+msgid "CorpusManagement|Corpus files are used in coverage-guided fuzz testing as seed inputs to improve testing."
msgstr ""
msgid "CorpusManagement|Corpus files must be in *.zip format. Maximum 5 GB"
@@ -10202,6 +10296,9 @@ msgstr ""
msgid "Could not apply %{name} command."
msgstr ""
+msgid "Could not apply %{name} command. %{message}."
+msgstr ""
+
msgid "Could not authorize chat nickname. Try again!"
msgstr "Ðе удалоÑÑŒ авторизовать никнейм чата. Попробуйте еще раз!"
@@ -10352,6 +10449,9 @@ msgstr "Сначала Ñоздайте учетную запиÑÑŒ GitLab, а Ð
msgid "Create a Mattermost team for this group"
msgstr "Создать команду в Mattermost Ð´Ð»Ñ Ñтой группы"
+msgid "Create a group"
+msgstr ""
+
msgid "Create a merge request"
msgstr "Создать Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð½Ð° ÑлиÑние"
@@ -10376,6 +10476,9 @@ msgstr "Создать новый репозиторий"
msgid "Create a personal access token on your account to pull or push via %{protocol}."
msgstr "Создать личный токен на аккаунте Ð´Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ð¸Ð»Ð¸ отправки через %{protocol}."
+msgid "Create a project"
+msgstr ""
+
msgid "Create an account using:"
msgstr "Создать аккаунт Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ:"
@@ -10739,6 +10842,9 @@ msgstr ""
msgid "Creation date"
msgstr "Дата ÑозданиÑ"
+msgid "Creator"
+msgstr ""
+
msgid "Credentials"
msgstr ""
@@ -10751,9 +10857,15 @@ msgstr ""
msgid "CredentialsInventory|Personal Access Tokens"
msgstr ""
+msgid "CredentialsInventory|Project Access Tokens"
+msgstr ""
+
msgid "CredentialsInventory|SSH Keys"
msgstr "Ключи SSH"
+msgid "Credit card required to be on file in order to create a pipeline"
+msgstr ""
+
msgid "Credit card:"
msgstr ""
@@ -10937,9 +11049,6 @@ msgstr ""
msgid "Customer relations"
msgstr ""
-msgid "Customizable by an administrator."
-msgstr ""
-
msgid "Customizable by owners."
msgstr ""
@@ -11069,30 +11178,18 @@ msgstr "должен быть в группе"
msgid "CycleAnalytics|%{selectedLabelsCount} selected (%{maxLabels} max)"
msgstr "%{selectedLabelsCount} выбрано (макÑимум — %{maxLabels})"
-msgid "CycleAnalytics|%{stageCount} stages selected"
-msgstr "%{stageCount} Ñтапов выбрано"
-
-msgid "CycleAnalytics|All stages"
-msgstr "Ð’Ñе Ñтапы"
-
-msgid "CycleAnalytics|Average days to completion"
+msgid "CycleAnalytics|Average time to completion"
msgstr ""
msgid "CycleAnalytics|Date"
msgstr ""
-msgid "CycleAnalytics|Days to completion"
-msgstr ""
-
msgid "CycleAnalytics|Display chart filters"
msgstr ""
msgid "CycleAnalytics|Lead Time for Changes"
msgstr ""
-msgid "CycleAnalytics|No stages selected"
-msgstr "Этапы не выбраны"
-
msgid "CycleAnalytics|Number of tasks"
msgstr ""
@@ -11125,18 +11222,30 @@ msgstr ""
msgid "CycleAnalytics|Showing data for group '%{groupName}' from %{createdAfter} to %{createdBefore}"
msgstr ""
-msgid "CycleAnalytics|Stages"
-msgstr "Этапы"
+msgid "CycleAnalytics|Stage time: %{title}"
+msgstr ""
msgid "CycleAnalytics|Tasks by type"
msgstr ""
-msgid "CycleAnalytics|The average time spent in the selected stage for the items that were completed on each date. Data limited to the last 500 items."
+msgid "CycleAnalytics|The average time items spent in this stage. Data limited to items completed within this date range."
msgstr ""
msgid "CycleAnalytics|The given date range is larger than 180 days"
msgstr ""
+msgid "CycleAnalytics|The total time items spent across each value stream stage. Data limited to items completed within this date range."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Stage time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Total time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|Total time"
+msgstr ""
+
msgid "CycleAnalytics|Type of work"
msgstr ""
@@ -11149,9 +11258,6 @@ msgstr ""
msgid "CycleAnalytics|project dropdown filter"
msgstr "Выпадающий фильтр проекта"
-msgid "CycleAnalytics|stage dropdown"
-msgstr "Выпадающий ÑпиÑок Ñтапов"
-
msgid "DAG visualization requires at least 3 dependent jobs."
msgstr ""
@@ -11251,10 +11357,16 @@ msgstr ""
msgid "DastProfiles|AJAX spider"
msgstr ""
+msgid "DastProfiles|API"
+msgstr ""
+
+msgid "DastProfiles|API endpoint URL"
+msgstr ""
+
msgid "DastProfiles|Active"
msgstr ""
-msgid "DastProfiles|Additional request headers (Optional)"
+msgid "DastProfiles|Additional request headers (optional)"
msgstr ""
msgid "DastProfiles|Are you sure you want to delete this profile?"
@@ -11269,6 +11381,9 @@ msgstr ""
msgid "DastProfiles|Branch missing"
msgstr ""
+msgid "DastProfiles|Choose a scan method"
+msgstr ""
+
msgid "DastProfiles|Could not create the scanner profile. Please try again."
msgstr ""
@@ -11338,7 +11453,13 @@ msgstr ""
msgid "DastProfiles|Excluded URLs"
msgstr ""
-msgid "DastProfiles|Excluded URLs (Optional)"
+msgid "DastProfiles|Excluded URLs (optional)"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths (optional)"
msgstr ""
msgid "DastProfiles|Hide debug messages"
@@ -11395,9 +11516,6 @@ msgstr ""
msgid "DastProfiles|Request headers"
msgstr ""
-msgid "DastProfiles|Rest API"
-msgstr ""
-
msgid "DastProfiles|Run the AJAX spider, in addition to the traditional spider, to crawl the target site."
msgstr ""
@@ -11407,6 +11525,9 @@ msgstr ""
msgid "DastProfiles|Save profile"
msgstr ""
+msgid "DastProfiles|Scan method"
+msgstr ""
+
msgid "DastProfiles|Scan mode"
msgstr ""
@@ -11485,12 +11606,24 @@ msgstr ""
msgid "DastProfiles|Website"
msgstr ""
+msgid "DastProfiles|What does each method do?"
+msgstr ""
+
msgid "DastProfiles|You can either choose a passive scan or validate the target site from the site profile management page. %{docsLinkStart}Learn more about site validation.%{docsLinkEnd}"
msgstr ""
msgid "DastProfiles|You cannot run an active scan against an unvalidated site."
msgstr ""
+msgid "DastProfiles|folder/dast_example.har or https://example.com/dast_example.har"
+msgstr ""
+
+msgid "DastProfiles|folder/example.postman_collection.json or https://example.com/"
+msgstr ""
+
+msgid "DastProfiles|folder/openapi.json or https://example.com/openapi.json"
+msgstr ""
+
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
@@ -11600,6 +11733,9 @@ msgstr ""
msgid "DatadogIntegration|API URL"
msgstr "URL-Ð°Ð´Ñ€ÐµÑ API"
+msgid "DatadogIntegration|Custom tags in Datadog. Enter one tag per line in the %{codeOpen}key:value%{codeClose} format. %{linkOpen}How do I use tags?%{linkClose}"
+msgstr ""
+
msgid "DatadogIntegration|Environment"
msgstr "Окружение"
@@ -11618,12 +11754,18 @@ msgstr ""
msgid "DatadogIntegration|Tag all data from this GitLab instance in Datadog. Useful when managing several self-managed deployments."
msgstr ""
+msgid "DatadogIntegration|Tags"
+msgstr ""
+
msgid "DatadogIntegration|The Datadog site to send data to. To send data to the EU site, use %{codeOpen}datadoghq.eu%{codeClose}."
msgstr ""
msgid "DatadogIntegration|Trace your GitLab pipelines with Datadog."
msgstr ""
+msgid "DatadogIntegration|have an invalid format"
+msgstr ""
+
msgid "Datasource name not found"
msgstr "Ð˜Ð¼Ñ Ð¸Ñточника данных не найдено"
@@ -11633,9 +11775,6 @@ msgstr "Дата"
msgid "Date merged"
msgstr ""
-msgid "Date picker"
-msgstr "Выбор даты"
-
msgid "Date range"
msgstr "Диапазон дат"
@@ -11789,9 +11928,6 @@ msgstr ""
msgid "Definition"
msgstr ""
-msgid "Delayed Project Deletion (%{adjourned_deletion})"
-msgstr ""
-
msgid "DelayedJobs|Are you sure you want to run %{jobName} immediately? Otherwise this job will run automatically after its timer finishes."
msgstr ""
@@ -11870,12 +12006,12 @@ msgstr "Удалить метку: %{labelName}"
msgid "Delete pipeline"
msgstr "Удалить Ñборочную линию"
+msgid "Delete pipeline schedule"
+msgstr ""
+
msgid "Delete project"
msgstr "Удалить проект"
-msgid "Delete project. Are you ABSOLUTELY SURE?"
-msgstr "Удалить проект. Ð’Ñ‹ ÐБСОЛЮТÐО УВЕРЕÐЫ?"
-
msgid "Delete row"
msgstr "Удалить Ñтроку"
@@ -11903,6 +12039,9 @@ msgstr "Удалить вложение"
msgid "Delete this epic and all descendants?"
msgstr ""
+msgid "Delete this project"
+msgstr ""
+
msgid "Delete user list"
msgstr "Удалить ÑпиÑок пользователей"
@@ -12173,6 +12312,12 @@ msgstr ""
msgid "Deploy to..."
msgstr "Развернуть в..."
+msgid "DeployBoards|To see deployment progress for your environments, make sure you are deploying to %{codeStart}$KUBE_NAMESPACE%{codeEnd} and annotating with %{codeStart}app.gitlab.com/app=$CI_PROJECT_PATH_SLUG%{codeEnd} and %{codeStart}app.gitlab.com/env=$CI_ENVIRONMENT_SLUG%{codeEnd}."
+msgstr ""
+
+msgid "DeployBoard|Kubernetes Pods"
+msgstr ""
+
msgid "DeployFreeze|Add a freeze period to prevent unintended releases during a period of time for a given environment. You must update the deployment jobs in %{filename} according to the deploy freezes added here. %{freeze_period_link_start}Learn more.%{freeze_period_link_end}"
msgstr ""
@@ -12257,9 +12402,6 @@ msgstr "ДоÑтуп только на чтение"
msgid "DeployTokens|Active Deploy Tokens (%{active_tokens})"
msgstr "Ðктивные токены Ñ€Ð°Ð·Ð²ÐµÑ€Ñ‚Ñ‹Ð²Ð°Ð½Ð¸Ñ (%{active_tokens})"
-msgid "DeployTokens|Allows read and write access to registry images."
-msgstr "Разрешает чтение и запиÑÑŒ в образы рееÑтра."
-
msgid "DeployTokens|Allows read and write access to the package registry."
msgstr "Разрешает чтение и запиÑÑŒ в рееÑÑ‚Ñ€ пакетов."
@@ -12272,6 +12414,9 @@ msgstr ""
msgid "DeployTokens|Allows read-only access to the repository."
msgstr ""
+msgid "DeployTokens|Allows write access to registry images."
+msgstr ""
+
msgid "DeployTokens|Copy deploy token"
msgstr "Копировать токен развёртываниÑ"
@@ -12365,12 +12510,57 @@ msgstr ""
msgid "Deploying to AWS is easy with GitLab"
msgstr ""
+msgid "Deployment"
+msgstr ""
+
msgid "Deployment Frequency"
msgstr ""
+msgid "Deployment Target|Project deployment target (optional)"
+msgstr ""
+
+msgid "Deployment Target|Select the deployment target"
+msgstr ""
+
msgid "Deployment frequency"
msgstr ""
+msgid "DeploymentTarget|GitLab Pages"
+msgstr ""
+
+msgid "DeploymentTarget|Heroku"
+msgstr ""
+
+msgid "DeploymentTarget|Infrastructure provider (Terraform, Cloudformation, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Kubernetes (GKE, EKS, OpenShift, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Managed container runtime (Fargate, Cloud Run, DigitalOcean App)"
+msgstr ""
+
+msgid "DeploymentTarget|Mobile app store"
+msgstr ""
+
+msgid "DeploymentTarget|No deployment planned"
+msgstr ""
+
+msgid "DeploymentTarget|Other hosting service"
+msgstr ""
+
+msgid "DeploymentTarget|Registry (package or container)"
+msgstr ""
+
+msgid "DeploymentTarget|Self-managed container runtime (Podman, Docker Swarm, Docker Compose)"
+msgstr ""
+
+msgid "DeploymentTarget|Serverless backend (Lambda, Cloud functions)"
+msgstr ""
+
+msgid "DeploymentTarget|Virtual machine (for example, EC2)"
+msgstr ""
+
msgid "Deployments"
msgstr ""
@@ -12411,6 +12601,9 @@ msgstr ""
msgid "Deployment|This deployment was created using the API"
msgstr "Это развёртывание было Ñоздано Ñ Ð¸Ñпользованием API"
+msgid "Deployment|Triggerer"
+msgstr ""
+
msgid "Deployment|Waiting"
msgstr ""
@@ -12438,6 +12631,18 @@ msgstr "уÑпешно"
msgid "Deprecated API rate limits"
msgstr ""
+msgid "Deprecations|Feature deprecation and removal"
+msgstr ""
+
+msgid "Deprecations|For information on a possible replacement %{epicStart} learn more about Opstrace %{epicEnd}."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7 and are %{epicStart} scheduled for removal %{epicEnd} in GitLab 15.0."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7, and are %{removal_link_start} scheduled for removal %{link_end} in GitLab 15.0. For information on a possible replacement, %{opstrace_link_start} learn more about Opstrace %{link_end}."
+msgstr ""
+
msgid "Deprioritize label"
msgstr "Понизить приоритет метки"
@@ -12685,10 +12890,10 @@ msgstr ""
msgid "DevopsAdoption|At least one deploy"
msgstr ""
-msgid "DevopsAdoption|At least one issue opened"
+msgid "DevopsAdoption|At least one issue created"
msgstr ""
-msgid "DevopsAdoption|At least one merge request opened"
+msgid "DevopsAdoption|At least one merge request created"
msgstr ""
msgid "DevopsAdoption|At least one pipeline successfully run"
@@ -12895,6 +13100,9 @@ msgstr ""
msgid "Direct member"
msgstr ""
+msgid "Direct members"
+msgstr ""
+
msgid "Direct non-authenticated users to this page."
msgstr ""
@@ -13013,6 +13221,9 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "Dismiss Alert"
+msgstr ""
+
msgid "Dismiss merge request promotion"
msgstr ""
@@ -13040,9 +13251,15 @@ msgstr "Отклонено в Ñборке %{pipelineLink} в %{projectLink}"
msgid "Display alerts from all configured monitoring tools."
msgstr ""
+msgid "Display milestones"
+msgstr ""
+
msgid "Display name"
msgstr "Отображаемое имÑ"
+msgid "Display progress of child issues"
+msgstr ""
+
msgid "Display rendered file"
msgstr ""
@@ -13148,6 +13365,9 @@ msgstr ""
msgid "Download image"
msgstr "Загрузить изображение"
+msgid "Download payload"
+msgstr ""
+
msgid "Download raw data (.csv)"
msgstr ""
@@ -13325,6 +13545,9 @@ msgstr "Изменить идентификацию Ð´Ð»Ñ %{user_name}"
msgid "Edit in Web IDE"
msgstr ""
+msgid "Edit in pipeline editor"
+msgstr ""
+
msgid "Edit in single-file editor"
msgstr ""
@@ -13367,6 +13590,9 @@ msgstr "Изменить wiki Ñтраницу"
msgid "Edit your most recent comment in a thread (from an empty textarea)"
msgstr "Редактировать Ñвой поÑледний комментарий в теме (в пуÑтом текÑтовом поле)"
+msgid "Edit, lint, and visualize your pipeline."
+msgstr ""
+
msgid "Edited"
msgstr ""
@@ -13808,6 +14034,9 @@ msgstr ""
msgid "Enforce two-factor authentication for all user sign-ins."
msgstr ""
+msgid "Enhance security by storing service account keys in secret managers - learn more about %{docLinkStart}secret management with GitLab%{docLinkEnd}"
+msgstr ""
+
msgid "Ensure connectivity is available from the GitLab server to the Prometheus server"
msgstr ""
@@ -13868,6 +14097,9 @@ 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 following to confirm:"
+msgstr ""
+
msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr "Введите Ð¸Ð¼Ñ Ð²Ð°ÑˆÐµÐ³Ð¾ приложениÑ, и мы вернем уникальный %{type}."
@@ -14400,9 +14632,6 @@ 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 "Произошла ошибка. Заблокированный пользователь не может быть деактивирован"
@@ -14431,7 +14660,7 @@ msgid "Error parsing CSV file. Please make sure it has"
msgstr ""
msgid "Error rendering Markdown preview"
-msgstr ""
+msgstr "Ошибка предпроÑмотра Markdown"
msgid "Error saving label update."
msgstr "Ошибка при обновлении метки."
@@ -14538,6 +14767,9 @@ msgstr ""
msgid "Errors:"
msgstr "Ошибки:"
+msgid "Escalate this incident"
+msgstr ""
+
msgid "Escalation Policies"
msgstr ""
@@ -14550,6 +14782,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy"
+msgstr ""
+
msgid "Escalation policy:"
msgstr ""
@@ -14803,6 +15038,9 @@ msgstr ""
msgid "Existing sign in methods may be removed"
msgstr ""
+msgid "Exit."
+msgstr ""
+
msgid "Expand"
msgstr "Развернуть"
@@ -14899,6 +15137,9 @@ msgstr "Обзор проектов"
msgid "Explore public groups"
msgstr "Обзор публичных групп"
+msgid "Explore public projects"
+msgstr ""
+
msgid "Explore snippets"
msgstr ""
@@ -15062,7 +15303,7 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
-msgid "Failed to assign a reviewer because no user was found."
+msgid "Failed to assign a reviewer because no user was specified."
msgstr ""
msgid "Failed to assign a user because no user was found."
@@ -15128,10 +15369,10 @@ msgstr ""
msgid "Failed to find import label for Jira import."
msgstr ""
-msgid "Failed to generate export, please try again later."
+msgid "Failed to find users for %{missing}"
msgstr ""
-msgid "Failed to generate report, please try again after sometime"
+msgid "Failed to generate export, please try again later."
msgstr ""
msgid "Failed to get ref."
@@ -15230,6 +15471,9 @@ msgstr ""
msgid "Failed to remove a to-do item for the design."
msgstr ""
+msgid "Failed to remove attention because no user was found."
+msgstr ""
+
msgid "Failed to remove mirror."
msgstr ""
@@ -15242,6 +15486,9 @@ msgstr ""
msgid "Failed to remove user key."
msgstr ""
+msgid "Failed to request attention because no user was found."
+msgstr ""
+
msgid "Failed to reset key. Please try again."
msgstr "Ðе удалоÑÑŒ ÑброÑить ключ. ПожалуйÑта, попробуйте ещё раз."
@@ -15323,6 +15570,9 @@ msgstr ""
msgid "Feature Flags"
msgstr "Функциональные опции"
+msgid "Feature deprecation and removal"
+msgstr ""
+
msgid "Feature flag status"
msgstr ""
@@ -15811,10 +16061,10 @@ msgid "For a faster browsing experience, some files are collapsed by default."
msgstr ""
msgid "For additional information, review your %{link_to} or contact your group owner."
-msgstr ""
+msgstr "Ð”Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð¾Ð¹ информации, проÑмотрите %{link_to} или ÑвÑжитеÑÑŒ Ñ Ð²Ð»Ð°Ð´ÐµÐ»ÑŒÑ†ÐµÐ¼ вашей группы."
msgid "For additional information, review your group membership: %{link_to} or contact your group owner."
-msgstr ""
+msgstr "Ð”Ð»Ñ Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð¾Ð¹ информации проÑмотрите Ñвоё учаÑтие в группе: %{link_to} или ÑвÑжитеÑÑŒ Ñ ÐµÑ‘ владельцем."
msgid "For each job, clone the repository."
msgstr ""
@@ -15822,7 +16072,7 @@ msgstr ""
msgid "For each job, re-use the project workspace. If the workspace doesn't exist, use %{code_open}git clone%{code_close}."
msgstr ""
-msgid "For example, the application using the token or the purpose of the token."
+msgid "For example, the application using the token or the purpose of the token. Do not give sensitive information for the name of the token, as it will be visible to all %{resource_type} members."
msgstr ""
msgid "For files larger than this limit, only index the file name. The file content is neither indexed nor searchable."
@@ -15906,9 +16156,6 @@ msgstr "Публичный"
msgid "ForkProject|Select a namespace"
msgstr ""
-msgid "ForkProject|Select a namespace to fork the project"
-msgstr ""
-
msgid "ForkProject|The project can be accessed by any logged in user."
msgstr ""
@@ -16005,6 +16252,9 @@ msgstr ""
msgid "Full name"
msgstr "Полное имÑ"
+msgid "GCP region configured"
+msgstr ""
+
msgid "GPG Key ID:"
msgstr "ID ключа GPG:"
@@ -16185,6 +16435,9 @@ msgstr ""
msgid "Geo|Failed"
msgstr "Ðе удалоÑÑŒ"
+msgid "Geo|Filter Geo sites"
+msgstr ""
+
msgid "Geo|Filter by name"
msgstr ""
@@ -16596,6 +16849,12 @@ msgstr ""
msgid "GitLab Issue"
msgstr ""
+msgid "GitLab KAS"
+msgstr ""
+
+msgid "GitLab Memberships CSV Export"
+msgstr ""
+
msgid "GitLab Pages"
msgstr ""
@@ -16644,6 +16903,9 @@ 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 free to use. Many features for larger teams are part of our %{link_start}paid products%{link_end}. You can try Ultimate for free without any obligation or payment details."
+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 ""
@@ -16770,7 +17032,7 @@ msgstr "Проверенные"
msgid "GitLabPages|When enabled, all attempts to visit your website through HTTP are automatically redirected to HTTPS using a response with status code 301. Requires a valid certificate for all domains. %{docs_link_start}Learn more.%{link_end}"
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. %{docs_link_start}Learn more.%{link_end}"
+msgid "GitLabPages|When using Pages under the general domain of a GitLab instance (%{pages_host}), you cannot use HTTPS with subdomains of subdomains. If your namespace or groupname contains a dot, it does not work. This is a limitation of the HTTP Over TLS protocol. HTTP pages work if you don't redirect HTTP to HTTPS. %{docs_link_start}Learn more.%{link_end}"
msgstr ""
msgid "GitLabPages|With GitLab Pages you can host your static website directly from your GitLab repository. %{docs_link_start}Learn more.%{link_end}"
@@ -16947,9 +17209,6 @@ msgstr "Перейти к файлам"
msgid "Go to find file"
msgstr "Перейти к поиÑку файла"
-msgid "Go to fork"
-msgstr ""
-
msgid "Go to issue boards"
msgstr "Перейти к доÑкам обÑуждений"
@@ -17157,9 +17416,6 @@ msgstr ""
msgid "Group Hooks"
msgstr ""
-msgid "Group ID"
-msgstr "ID группы"
-
msgid "Group Owner must have signed in with SAML before enabling Group Managed Accounts"
msgstr ""
@@ -17187,9 +17443,6 @@ msgstr "Ðватар группы"
msgid "Group by"
msgstr ""
-msgid "Group description"
-msgstr ""
-
msgid "Group description (optional)"
msgstr "ОпиÑание группы (необÑзательно)"
@@ -17304,7 +17557,7 @@ msgstr "Группа: %{group_name}"
msgid "Group: %{name}"
msgstr "Группа: %{name}"
-msgid "GroupActivityMetrics|Issues opened"
+msgid "GroupActivityMetrics|Issues created"
msgstr ""
msgid "GroupActivityMetrics|Last 90 days"
@@ -17313,7 +17566,7 @@ msgstr ""
msgid "GroupActivityMetrics|Members added"
msgstr ""
-msgid "GroupActivityMetrics|Merge Requests opened"
+msgid "GroupActivityMetrics|Merge Requests created"
msgstr ""
msgid "GroupActivityMetrics|Recent activity"
@@ -17604,6 +17857,9 @@ msgstr ""
msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
+msgid "GroupSettings|Choose a group path that does not start with a dash or end with a period. It can also contain alphanumeric characters and underscores."
+msgstr ""
+
msgid "GroupSettings|Compliance frameworks"
msgstr ""
@@ -17637,8 +17893,8 @@ msgstr ""
msgid "GroupSettings|If not specified at the group or instance level, the default is %{default_initial_branch_name}. Does not affect existing repositories."
msgstr ""
-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|If the parent group's visibility is lower than the group's current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility."
+msgstr ""
msgid "GroupSettings|New runners registration token has been generated!"
msgstr "Ðовый региÑтрационный токен обработчика заданий Ñгенерирован!"
@@ -17754,8 +18010,11 @@ msgstr "Группы (%{count})"
msgid "Groups and projects"
msgstr "Группы и проекты"
-msgid "Groups and subgroups"
-msgstr "Группы и подгруппы"
+msgid "Groups are a great way to organize projects and people."
+msgstr ""
+
+msgid "Groups are the best way to manage projects and members."
+msgstr ""
msgid "Groups to synchronize"
msgstr "Группы Ð´Ð»Ñ Ñинхронизации"
@@ -17865,14 +18124,17 @@ msgstr ""
msgid "GroupsTree|Are you sure you want to leave the \"%{fullName}\" group?"
msgstr "Вы уверены, что вы хотите покинуть группу \"%{fullName}\"?"
-msgid "GroupsTree|Edit group"
-msgstr "Редактировать группу"
+msgid "GroupsTree|Delete"
+msgstr ""
+
+msgid "GroupsTree|Edit"
+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|Leave group"
+msgstr ""
msgid "GroupsTree|Loading groups"
msgstr "Загрузка групп"
@@ -17883,9 +18145,57 @@ msgstr "ПоиÑк групп не дал результатов"
msgid "GroupsTree|No groups or projects matched your search"
msgstr "ПоиÑк групп или проектов не дал результатов"
+msgid "GroupsTree|Options"
+msgstr ""
+
msgid "GroupsTree|Search by name"
msgstr "ПоиÑк по имени"
+msgid "Groups|Avatar will be removed. Are you sure?"
+msgstr ""
+
+msgid "Groups|Changing group URL can have unintended side effects."
+msgstr ""
+
+msgid "Groups|Checking group URL availability..."
+msgstr ""
+
+msgid "Groups|Enter a descriptive name for your group."
+msgstr ""
+
+msgid "Groups|Group ID"
+msgstr ""
+
+msgid "Groups|Group URL"
+msgstr ""
+
+msgid "Groups|Group avatar"
+msgstr ""
+
+msgid "Groups|Group description (optional)"
+msgstr ""
+
+msgid "Groups|Group name"
+msgstr ""
+
+msgid "Groups|Group path is available."
+msgstr ""
+
+msgid "Groups|Group path is unavailable. Path has been replaced with a suggested available path."
+msgstr ""
+
+msgid "Groups|Learn more"
+msgstr ""
+
+msgid "Groups|Must start with letter, digit, emoji, or underscore. Can also contain periods, dashes, spaces, and parentheses."
+msgstr ""
+
+msgid "Groups|Remove avatar"
+msgstr ""
+
+msgid "Groups|Save changes"
+msgstr ""
+
msgid "Guideline"
msgstr "РуководÑтво"
@@ -17895,6 +18205,9 @@ msgstr "HAR (HTTP Ðрхив)"
msgid "HAR file path or URL"
msgstr ""
+msgid "HTTP Archive (HAR)"
+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Ð’Ñ‹ должны иÑпользовать личный токен Ñ Ð´Ð¾Ñтупом к «api» Ð´Ð»Ñ Ð¸ÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Git через HTTP.\\nÐ’Ñ‹ можете Ñоздать его на %{profile_personal_access_tokens_url}"
@@ -18299,6 +18612,9 @@ msgstr "ИÐФОРМÐЦИЯ: Срок дейÑÑ‚Ð²Ð¸Ñ Ð²Ð°ÑˆÐµÐ³Ð¾ SSH-клюÑ
msgid "INFO: Your SSH key is expiring soon. Please generate a new key."
msgstr "ИÐФОРМÐЦИЯ: Срок дейÑÑ‚Ð²Ð¸Ñ Ð²Ð°ÑˆÐµÐ³Ð¾ SSH-ключа иÑтекает. ПожалуйÑта, Ñоздайте новый."
+msgid "IP"
+msgstr ""
+
msgid "IP Address"
msgstr "IP-адреÑ"
@@ -18335,6 +18651,9 @@ msgstr ""
msgid "IdentityVerification|Verify your identity"
msgstr ""
+msgid "IdentityVerification|You can always verify your account at a later time to create a group."
+msgstr ""
+
msgid "If any indexed field exceeds this limit, it is truncated to this number of characters. The rest of the content is neither indexed nor searchable. This does not apply to repository and wiki indexing. For unlimited characters, set this to 0."
msgstr ""
@@ -18392,6 +18711,9 @@ msgstr "ЕÑли вы иÑпользуете GitHub, вы увидите ÑтаÑ
msgid "If you add %{codeStart}needs%{codeEnd} to jobs in your pipeline you'll be able to view the %{codeStart}needs%{codeEnd} relationships between jobs in this tab as a %{linkStart}Directed Acyclic Graph (DAG)%{linkEnd}."
msgstr ""
+msgid "If you are added to a project, it will be displayed here."
+msgstr ""
+
msgid "If you did not initiate these sign-in attempts, please reach out to your administrator or enable two-factor authentication (2FA) on your account."
msgstr "ЕÑли вы не делали попыток войти, пожалуйÑта, ÑвÑжитеÑÑŒ Ñ Ð°Ð´Ð¼Ð¸Ð½Ð¸Ñтратором или включите двухфакторную аутентификацию (2FA) Ð´Ð»Ñ Ñвоей учётной запиÑи."
@@ -18704,12 +19026,24 @@ msgstr ""
msgid "InProductMarketing|3 ways to dive into GitLab CI/CD"
msgstr ""
+msgid "InProductMarketing|A single application eliminates complex integrations, data chokepoints, and toolchain maintenance, resulting in greater productivity and lower cost."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features, build more efficiently, strengthen security and compliance."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features."
+msgstr ""
+
msgid "InProductMarketing|Actually, GitLab makes the team work (better)"
msgstr ""
msgid "InProductMarketing|And finally %{deploy_link} a Python application."
msgstr ""
+msgid "InProductMarketing|And many more..."
+msgstr ""
+
msgid "InProductMarketing|Are your runners ready?"
msgstr ""
@@ -18728,15 +19062,33 @@ msgstr ""
msgid "InProductMarketing|Blog"
msgstr ""
+msgid "InProductMarketing|Break down silos to coordinate seamlessly across development, operations, and security with a consistent experience across the development lifecycle."
+msgstr ""
+
+msgid "InProductMarketing|Burn up/down charts"
+msgstr ""
+
msgid "InProductMarketing|By enabling code owners and required merge approvals the right person will review the right MR. This is a win-win: cleaner code and a more efficient review process."
msgstr ""
msgid "InProductMarketing|Click on the number below that corresponds with your answer — 1 being very difficult, 5 being very easy."
msgstr ""
+msgid "InProductMarketing|Code owners"
+msgstr ""
+
msgid "InProductMarketing|Code owners and required merge approvals are part of the paid tiers of GitLab. You can start a free 30-day trial of GitLab Ultimate and enable these features in less than 5 minutes with no credit card required."
msgstr ""
+msgid "InProductMarketing|Code review analytics"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration across stages in GitLab"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration made easy"
+msgstr ""
+
msgid "InProductMarketing|Create a custom CI runner with just a few clicks"
msgstr ""
@@ -18746,12 +19098,21 @@ msgstr ""
msgid "InProductMarketing|Create a project in GitLab in 5 minutes"
msgstr ""
+msgid "InProductMarketing|Create well-defined workflows by using scoped labels on issues, merge requests, and epics. Labels with the same scope cannot be used together, which prevents conflicts."
+msgstr ""
+
msgid "InProductMarketing|Create your first project!"
msgstr ""
+msgid "InProductMarketing|Define who owns specific files or directories, so the right reviewers are suggested when a merge request introduces changes to those files."
+msgstr ""
+
msgid "InProductMarketing|Deliver Better Products Faster"
msgstr ""
+msgid "InProductMarketing|Dependency scanning"
+msgstr ""
+
msgid "InProductMarketing|Did you know teams that use GitLab are far more efficient?"
msgstr ""
@@ -18761,15 +19122,27 @@ msgstr ""
msgid "InProductMarketing|Dig in and create a project and a repo"
msgstr ""
+msgid "InProductMarketing|Discover Premium & Ultimate"
+msgstr ""
+
+msgid "InProductMarketing|Discover Premium & Ultimate."
+msgstr ""
+
msgid "InProductMarketing|Do you have a minute?"
msgstr ""
msgid "InProductMarketing|Do you have a teammate who would be perfect for this task?"
msgstr ""
+msgid "InProductMarketing|Dynamic application security testing"
+msgstr ""
+
msgid "InProductMarketing|Easy"
msgstr ""
+msgid "InProductMarketing|Epics"
+msgstr ""
+
msgid "InProductMarketing|Expand your DevOps journey with a free GitLab trial"
msgstr ""
@@ -18791,9 +19164,15 @@ msgstr ""
msgid "InProductMarketing|Feel the need for speed?"
msgstr ""
+msgid "InProductMarketing|Find and fix bottlenecks in your code review process by understanding how long open merge requests have been in review."
+msgstr ""
+
msgid "InProductMarketing|Find out how your teams are really doing"
msgstr ""
+msgid "InProductMarketing|Find out if your external libraries are safe. Run dependency scanning jobs that check for known vulnerabilities in your external libraries."
+msgstr ""
+
msgid "InProductMarketing|Follow our steps"
msgstr ""
@@ -18830,6 +19209,9 @@ msgstr ""
msgid "InProductMarketing|GitLab is better with teammates to help out!"
msgstr ""
+msgid "InProductMarketing|GitLab is infrastructure agnostic (supporting GCP, AWS, Azure, OpenShift, VMWare, On Prem, Bare Metal, and more), offering a consistent workflow experience – irrespective of the environment."
+msgstr ""
+
msgid "InProductMarketing|GitLab provides static application security testing (SAST), dynamic application security testing (DAST), container scanning, and dependency scanning to help you deliver secure applications along with license compliance."
msgstr ""
@@ -18920,21 +19302,36 @@ msgstr ""
msgid "InProductMarketing|It's also possible to simply %{external_repo_link} in order to take advantage of GitLab's CI/CD."
msgstr ""
+msgid "InProductMarketing|Keep your code quality high by defining who should approve merge requests and how many approvals are required."
+msgstr ""
+
msgid "InProductMarketing|Launch GitLab CI/CD in 20 minutes or less"
msgstr ""
+msgid "InProductMarketing|Lower cost of development"
+msgstr ""
+
+msgid "InProductMarketing|Make it easier to collaborate on high-level ideas by grouping related issues in an epic."
+msgstr ""
+
msgid "InProductMarketing|Making the switch? It's easier than you think to import your projects into GitLab. Move %{github_link}, or import something %{bitbucket_link}."
msgstr ""
msgid "InProductMarketing|Master the art of importing!"
msgstr ""
+msgid "InProductMarketing|Merge request approval rule"
+msgstr ""
+
msgid "InProductMarketing|Move on to easily creating a Pages website %{ci_template_link}"
msgstr ""
msgid "InProductMarketing|Multiple owners, confusing workstreams? We've got you covered"
msgstr ""
+msgid "InProductMarketing|Multiple required approvers"
+msgstr ""
+
msgid "InProductMarketing|Need an alternative to importing?"
msgstr ""
@@ -18947,18 +19344,33 @@ msgstr ""
msgid "InProductMarketing|Our tool brings all the things together"
msgstr ""
+msgid "InProductMarketing|Protect your web application by using DAST to examine for vulnerabilities in deployed environments."
+msgstr ""
+
msgid "InProductMarketing|Rapid development, simplified"
msgstr ""
msgid "InProductMarketing|Reduce Security & Compliance Risk"
msgstr ""
+msgid "InProductMarketing|Require multiple approvers on a merge request, so you know it's in good shape before it's merged."
+msgstr ""
+
+msgid "InProductMarketing|Roadmaps"
+msgstr ""
+
+msgid "InProductMarketing|Scoped labels"
+msgstr ""
+
msgid "InProductMarketing|Security that's integrated into your development lifecycle"
msgstr ""
msgid "InProductMarketing|Sometimes you're not ready to make a full transition to a new tool. If you're not ready to fully commit, %{mirroring_link} gives you a safe way to try out GitLab in parallel with your current tool."
msgstr ""
+msgid "InProductMarketing|Speed. Efficiency. Trust."
+msgstr ""
+
msgid "InProductMarketing|Spin up an autoscaling runner in GitLab"
msgstr ""
@@ -18968,6 +19380,9 @@ msgstr ""
msgid "InProductMarketing|Start a Self-Managed trial"
msgstr ""
+msgid "InProductMarketing|Start a free trial"
+msgstr ""
+
msgid "InProductMarketing|Start a free trial of GitLab Ultimate – no credit card required"
msgstr ""
@@ -19034,6 +19449,9 @@ msgstr ""
msgid "InProductMarketing|To understand and get the most out of GitLab, start at the beginning and %{project_link}. In GitLab, repositories are part of a project, so after you've created your project you can go ahead and %{repo_link}."
msgstr ""
+msgid "InProductMarketing|Track completed issues in a chart, so you can see how a milestone is progressing at a glance."
+msgstr ""
+
msgid "InProductMarketing|Try GitLab Ultimate for free"
msgstr ""
@@ -19070,6 +19488,9 @@ msgstr ""
msgid "InProductMarketing|Very easy"
msgstr ""
+msgid "InProductMarketing|Visualize your epics and milestones in a timeline."
+msgstr ""
+
msgid "InProductMarketing|Want to host GitLab on your servers?"
msgstr ""
@@ -19091,6 +19512,9 @@ msgstr ""
msgid "InProductMarketing|YouTube"
msgstr ""
+msgid "InProductMarketing|Your software, deployed your way"
+msgstr ""
+
msgid "InProductMarketing|Your teams can be more efficient"
msgstr ""
@@ -19211,9 +19635,18 @@ msgstr ""
msgid "IncidentManagement|No incidents to display."
msgstr ""
+msgid "IncidentManagement|None"
+msgstr ""
+
msgid "IncidentManagement|Open"
msgstr ""
+msgid "IncidentManagement|Page your team with escalation policies"
+msgstr ""
+
+msgid "IncidentManagement|Paged"
+msgstr ""
+
msgid "IncidentManagement|Published"
msgstr ""
@@ -19223,6 +19656,9 @@ msgstr ""
msgid "IncidentManagement|Severity"
msgstr ""
+msgid "IncidentManagement|Status"
+msgstr ""
+
msgid "IncidentManagement|There are no closed incidents"
msgstr ""
@@ -19241,6 +19677,9 @@ msgstr ""
msgid "IncidentManagement|Unpublished"
msgstr ""
+msgid "IncidentManagement|Use escalation policies to automatically page your team when incidents are created."
+msgstr ""
+
msgid "IncidentSettings|Activate \"time to SLA\" countdown timer"
msgstr ""
@@ -19286,7 +19725,10 @@ msgstr ""
msgid "Incidents"
msgstr "Инциденты"
-msgid "Incidents|Add a URL"
+msgid "Incidents|Add image details"
+msgstr ""
+
+msgid "Incidents|Add text or a link to display with your image. If you don't add either, the file name displays instead."
msgstr ""
msgid "Incidents|Drop or %{linkStart}upload%{linkEnd} a metric screenshot to attach it to the incident"
@@ -19301,10 +19743,10 @@ msgstr ""
msgid "Incidents|There was an issue loading metric images."
msgstr ""
-msgid "Incidents|There was an issue uploading your image."
+msgid "Incidents|There was an issue updating your image."
msgstr ""
-msgid "Incidents|You can optionally add a URL to link users to the original graph."
+msgid "Incidents|There was an issue uploading your image."
msgstr ""
msgid "Incident|Alert details"
@@ -19313,9 +19755,18 @@ msgstr ""
msgid "Incident|Are you sure you wish to delete this image?"
msgstr ""
+msgid "Incident|Delete image"
+msgstr ""
+
msgid "Incident|Deleting %{filename}"
msgstr ""
+msgid "Incident|Edit image text or link"
+msgstr ""
+
+msgid "Incident|Editing %{filename}"
+msgstr ""
+
msgid "Incident|Metrics"
msgstr ""
@@ -19587,12 +20038,18 @@ msgstr ""
msgid "Integrations|Branches for which notifications are to be sent"
msgstr ""
+msgid "Integrations|Clear if using a self-signed certificate."
+msgstr ""
+
msgid "Integrations|Comment detail:"
msgstr ""
msgid "Integrations|Comment settings:"
msgstr ""
+msgid "Integrations|Connection details"
+msgstr ""
+
msgid "Integrations|Connection failed. Please check your settings."
msgstr ""
@@ -19617,6 +20074,9 @@ msgstr ""
msgid "Integrations|Enable GitLab.com slash commands in a Slack workspace."
msgstr ""
+msgid "Integrations|Enable SSL verification"
+msgstr ""
+
msgid "Integrations|Enable comments"
msgstr ""
@@ -19695,6 +20155,9 @@ msgstr "Ð¡Ð±Ñ€Ð¾Ñ Ð¸Ð½Ñ‚ÐµÐ³Ñ€Ð°Ñ†Ð¸Ð¸ очиÑтит наÑтройки и дÐ
msgid "Integrations|Return to GitLab for Jira"
msgstr ""
+msgid "Integrations|SSL verification"
+msgstr ""
+
msgid "Integrations|Save settings?"
msgstr ""
@@ -19740,9 +20203,6 @@ msgstr ""
msgid "Integrations|Use default settings"
msgstr ""
-msgid "Integrations|When you mention a Jira issue in a commit or merge request, GitLab creates a remote link and comment (if enabled)."
-msgstr ""
-
msgid "Integrations|You can now close this window and return to the GitLab for Jira application."
msgstr ""
@@ -19767,9 +20227,6 @@ msgstr ""
msgid "Integrations|can't exceed %{recipients_limit}"
msgstr ""
-msgid "Interactive developer security education."
-msgstr ""
-
msgid "Interactive mode"
msgstr ""
@@ -20259,6 +20716,9 @@ msgstr ""
msgid "IssueAnalytics|Assignees"
msgstr "ОтветÑтвенные"
+msgid "IssueAnalytics|Created by"
+msgstr ""
+
msgid "IssueAnalytics|Due date"
msgstr ""
@@ -20271,9 +20731,6 @@ msgstr ""
msgid "IssueAnalytics|Milestone"
msgstr ""
-msgid "IssueAnalytics|Opened by"
-msgstr ""
-
msgid "IssueAnalytics|Status"
msgstr ""
@@ -20397,10 +20854,10 @@ msgstr "ПоÑле того как вы начнёте Ñоздавать обÑ
msgid "IssuesAnalytics|Avg/Month:"
msgstr ""
-msgid "IssuesAnalytics|Issues opened"
+msgid "IssuesAnalytics|Issues created"
msgstr ""
-msgid "IssuesAnalytics|Issues opened per month"
+msgid "IssuesAnalytics|Issues created per month"
msgstr ""
msgid "IssuesAnalytics|Last 12 months"
@@ -20427,6 +20884,9 @@ msgstr ""
msgid "It looks like you have some draft commits in this branch."
msgstr ""
+msgid "It looks like you're attempting to activate your subscription. Use %{a_start}the Subscription page%{a_end} instead."
+msgstr ""
+
msgid "It may be several days before you see feature usage data."
msgstr ""
@@ -20655,6 +21115,9 @@ msgstr ""
msgid "JiraConnect|You can now close this window and return to Jira."
msgstr ""
+msgid "JiraConnect|You don't have permission to create branches for this project. Select a different project or contact the project owner for access. %{linkStart}Learn more.%{linkEnd}"
+msgstr ""
+
msgid "JiraRequest|A connection error occurred while connecting to Jira. Try your request again."
msgstr ""
@@ -20703,13 +21166,13 @@ msgstr ""
msgid "JiraService|Define the type of Jira issue to create from a vulnerability."
msgstr ""
-msgid "JiraService|Displaying Jira issues while leaving the GitLab issue functionality enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
+msgid "JiraService|Displaying Jira issues while leaving GitLab issues also enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
msgstr ""
-msgid "JiraService|Enable Jira issues"
+msgid "JiraService|Enable Jira issue creation from vulnerabilities"
msgstr ""
-msgid "JiraService|Enable Jira issues creation from vulnerabilities"
+msgid "JiraService|Enable Jira issues"
msgstr ""
msgid "JiraService|Enable Jira transitions"
@@ -20826,16 +21289,19 @@ msgstr ""
msgid "JiraService|View Jira issues in GitLab"
msgstr ""
-msgid "JiraService|Warning: All GitLab users that have access to this GitLab project are able to view all issues from the Jira project specified below."
+msgid "JiraService|Warning: All GitLab users with access to this GitLab project can view all issues from the Jira project you select."
msgstr ""
msgid "JiraService|Web URL"
msgstr "URL-адреÑ"
-msgid "JiraService|Work on Jira issues without leaving GitLab. Adds a Jira menu to access your list of Jira issues and view any issue as read-only."
+msgid "JiraService|When a Jira issue is mentioned in a commit or merge request, a remote link and comment (if enabled) will be created."
msgstr ""
-msgid "JiraService|You need to configure Jira before enabling this integration. For more details, read the %{jira_doc_link_start}Jira integration documentation%{link_end}."
+msgid "JiraService|Work on Jira issues without leaving GitLab. Add a Jira menu to access a read-only list of your Jira issues."
+msgstr ""
+
+msgid "JiraService|You must configure Jira before enabling this integration. %{jira_doc_link_start}Learn more.%{link_end}"
msgstr ""
msgid "Job"
@@ -20847,9 +21313,6 @@ msgstr ""
msgid "Job Failed #%{build_id}"
msgstr "Ошибка Ð·Ð°Ð´Ð°Ð½Ð¸Ñ #%{build_id}"
-msgid "Job ID"
-msgstr "ID заданиÑ"
-
msgid "Job artifact"
msgstr ""
@@ -20916,9 +21379,27 @@ msgstr ""
msgid "Jobs|You're about to retry a job that failed because it attempted to deploy code that is older than the latest deployment. Retrying this job could result in overwriting the environment with the older source code."
msgstr ""
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source} into %{target}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{ref}"
+msgstr ""
+
+msgid "Job|Are you sure you want to erase this job log and artifacts?"
+msgstr ""
+
msgid "Job|Browse"
msgstr "ПроÑмотр"
+msgid "Job|Cancel"
+msgstr ""
+
msgid "Job|Complete Raw"
msgstr ""
@@ -20928,6 +21409,9 @@ msgstr "Скачать"
msgid "Job|Erase job log and artifacts"
msgstr ""
+msgid "Job|Finished at"
+msgstr ""
+
msgid "Job|Job artifacts"
msgstr "Ðртефакты заданиÑ"
@@ -20940,8 +21424,8 @@ msgstr ""
msgid "Job|Keep"
msgstr "ОÑтавить"
-msgid "Job|Pipeline"
-msgstr "Ð¡Ð±Ð¾Ñ€Ð¾Ñ‡Ð½Ð°Ñ Ð»Ð¸Ð½Ð¸Ñ"
+msgid "Job|Retry"
+msgstr ""
msgid "Job|Scroll to bottom"
msgstr "Прокрутить вниз"
@@ -20952,6 +21436,9 @@ msgstr "Прокрутить вверх"
msgid "Job|Show complete raw"
msgstr "Показать полный иÑходный текÑÑ‚"
+msgid "Job|Status"
+msgstr ""
+
msgid "Job|The artifacts were removed"
msgstr "Ðртефакты Ð·Ð°Ð´Ð°Ð½Ð¸Ñ Ð±Ñ‹Ð»Ð¸ удалены"
@@ -20979,21 +21466,12 @@ msgstr ""
msgid "Job|delayed"
msgstr ""
-msgid "Job|for"
-msgstr ""
-
-msgid "Job|into"
-msgstr "в"
-
msgid "Job|manual"
msgstr ""
msgid "Job|triggered"
msgstr ""
-msgid "Job|with"
-msgstr "Ñ"
-
msgid "Join Zoom meeting"
msgstr ""
@@ -21096,9 +21574,6 @@ msgstr "Ключи"
msgid "Ki"
msgstr "Ки"
-msgid "Kontra"
-msgstr ""
-
msgid "Kroki"
msgstr ""
@@ -21424,6 +21899,9 @@ msgstr ""
msgid "Learn more about Auto DevOps"
msgstr "Узнайте больше об \"Auto DevOps\""
+msgid "Learn more about GitLab"
+msgstr ""
+
msgid "Learn more about Needs relationships"
msgstr ""
@@ -21515,7 +21993,7 @@ msgid "LearnGitLab|Ready to get started with GitLab? Follow these steps to set u
msgstr ""
msgid "LearnGitLab|Review and edit proposed changes to source code."
-msgstr ""
+msgstr "ПроÑмотрите и отредактируйте предлагаемые Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð¸Ñходного кода."
msgid "LearnGitLab|Route code reviews to the right reviewers, every time."
msgstr ""
@@ -21763,9 +22241,18 @@ msgstr "Обнаружены лицензии Ñ Ð½ÐµÐ¾Ð¿Ñ€ÐµÐ´ÐµÐ»ÐµÐ½Ð½Ñ‹Ð¼ Ñ
msgid "Licenses|Displays licenses detected in the project, based on the %{linkStart}latest successful%{linkEnd} scan"
msgstr "Показывает лицензии, обнаруженные в проекте при %{linkStart}поÑледнем уÑпешном%{linkEnd} Ñканировании"
+msgid "Licenses|Drag your license file here or %{linkStart}click to upload%{linkEnd}."
+msgstr ""
+
+msgid "Licenses|Drop your license file to start the upload."
+msgstr ""
+
msgid "Licenses|Error fetching the license list. Please check your network connection and try again."
msgstr ""
+msgid "Licenses|Error: You are trying to upload something other than a file"
+msgstr ""
+
msgid "Licenses|License Compliance"
msgstr "Служба комплаенÑа лицензий"
@@ -21784,6 +22271,9 @@ msgstr "Ðарушение политики: отказано"
msgid "Licenses|Specified policies in this project"
msgstr ""
+msgid "Licenses|The file could not be uploaded."
+msgstr ""
+
msgid "Licenses|The license list details information about the licenses used within your project."
msgstr ""
@@ -21817,13 +22307,6 @@ msgstr ""
msgid "Limit the size of Sidekiq jobs stored in Redis."
msgstr ""
-msgid "Limited to showing %d event at most"
-msgid_plural "Limited to showing %d events at most"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-msgstr[3] ""
-
msgid "Limiting mode"
msgstr ""
@@ -21833,6 +22316,9 @@ msgstr ""
msgid "Link"
msgstr ""
+msgid "Link (optional)"
+msgstr ""
+
msgid "Link Prometheus monitoring to GitLab."
msgstr ""
@@ -21869,6 +22355,9 @@ msgstr ""
msgid "Linked emails (%{email_count})"
msgstr "ПривÑзанные адреÑа Ñлектронной почты (%{email_count})"
+msgid "Linked epics"
+msgstr ""
+
msgid "Linked issues"
msgstr ""
@@ -21896,6 +22385,15 @@ msgstr ""
msgid "List of all merge commits"
msgstr ""
+msgid "List of environments for this project"
+msgstr ""
+
+msgid "List of suitable GCP locations"
+msgstr ""
+
+msgid "List of users allowed to exceed the rate limit."
+msgstr ""
+
msgid "List options"
msgstr ""
@@ -22115,6 +22613,9 @@ msgstr ""
msgid "Maintenance mode"
msgstr "Режим обÑлуживаниÑ"
+msgid "Make adjustments to how your GitLab instance is set up."
+msgstr ""
+
msgid "Make and review changes in the browser with the Web IDE"
msgstr "ВнеÑите и проÑмотрите Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð² браузере Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ Web IDE"
@@ -22259,6 +22760,12 @@ msgstr ""
msgid "MarkdownEditor|Add italic text (%{modifier_key}I)"
msgstr ""
+msgid "MarkdownEditor|Add strikethrough text (%{modifierKey}⇧X)"
+msgstr ""
+
+msgid "MarkdownEditor|Add strikethrough text (%{modifier_key}⇧X)"
+msgstr ""
+
msgid "Marked For Deletion At - %{deletion_time}"
msgstr ""
@@ -22520,6 +23027,9 @@ msgstr ""
msgid "Maximum push size (MB)"
msgstr "МакÑимальный размер отправки (Мбайт)"
+msgid "Maximum requests per 10 minutes per user"
+msgstr ""
+
msgid "Maximum requests per minute"
msgstr ""
@@ -22610,6 +23120,23 @@ msgstr ""
msgid "Members of a group may only view projects they have permission to access"
msgstr ""
+msgid "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seat in use and will be billed for the overage."
+msgid_plural "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seats in use and will be billed for the overage."
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
+msgid "MembersOverage|You are about to incur additional charges"
+msgstr ""
+
+msgid "MembersOverage|Your subscription includes %d seat."
+msgid_plural "MembersOverage|Your subscription includes %d seats."
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "Membership"
msgstr ""
@@ -22814,9 +23341,6 @@ msgstr ""
msgid "Merge request not merged"
msgstr ""
-msgid "Merge request pipelines 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 merge request pipelines."
-msgstr ""
-
msgid "Merge request reports"
msgstr ""
@@ -22913,13 +23437,13 @@ msgstr ""
msgid "MergeRequests|Create issue to resolve thread"
msgstr ""
-msgid "MergeRequests|Failed to squash. Should be done manually."
-msgstr "Ðе удалоÑÑŒ объединить коммиты. Это должно быть выполнено вручную."
-
msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
+msgid "MergeRequests|Squashing failed: Squash the commits locally, resolve any conflicts, then push the branch."
+msgstr ""
+
+msgid "MergeRequests|Squashing not allowed: This project doesn't allow you to squash commits when merging."
msgstr ""
msgid "MergeRequests|Thread stays resolved"
@@ -23764,6 +24288,18 @@ msgstr "Развернуть повторно"
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "MrList|Assigned to %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from assignee %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from reviewer %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Review requested from %{name}, go to their profile."
+msgstr ""
+
msgid "Multi-project"
msgstr ""
@@ -23797,7 +24333,7 @@ msgstr ""
msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "My Awesome Group"
+msgid "My awesome group"
msgstr ""
msgid "My company or team"
@@ -23871,7 +24407,7 @@ msgid "NamespaceStorageSize|push to your repository, create pipelines, create is
msgstr ""
msgid "NamespaceUserCap|Pending users must be reviewed and approved by a group owner. Learn more about %{user_caps_link_start}user caps%{link_end} and %{users_pending_approval_link_start}users pending approval%{link_end}."
-msgstr ""
+msgstr "Ожидающие Ð¿Ð¾Ð´Ñ‚Ð²ÐµÑ€Ð¶Ð´ÐµÐ½Ð¸Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ð¸ должны быть проверены и одобрены владельцем группы. Узнайте больше о %{user_caps_link_start}пользовательÑкой вмеÑтимоÑти%{link_end} и об %{users_pending_approval_link_start}одобрении пользователей%{link_end}."
msgid "NamespaceUserCap|View pending approvals"
msgstr ""
@@ -24423,9 +24959,6 @@ msgstr "Методы аутентификации не наÑтроены."
msgid "No available branches"
msgstr ""
-msgid "No available groups to fork the project."
-msgstr ""
-
msgid "No branches found"
msgstr ""
@@ -24636,6 +25169,9 @@ msgstr "Ðет публичных групп"
msgid "No ref selected"
msgstr ""
+msgid "No regions configured"
+msgstr ""
+
msgid "No related merge requests found."
msgstr "СвÑзанные запроÑÑ‹ на ÑлиÑние не найдены."
@@ -25452,6 +25988,9 @@ msgstr ""
msgid "Only reCAPTCHA v2 is supported:"
msgstr ""
+msgid "Only required if not using role instance credentials."
+msgstr ""
+
msgid "Only use lowercase letters, numbers, and underscores."
msgstr ""
@@ -25476,9 +26015,6 @@ msgstr "Открыть выбранное"
msgid "Open a CLI and connect to the cluster you want to install the agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
-msgid "Open epics"
-msgstr ""
-
msgid "Open errors"
msgstr ""
@@ -25518,8 +26054,8 @@ msgstr ""
msgid "Opened issues"
msgstr "Открытые обÑуждениÑ"
-msgid "OpenedNDaysAgo|Opened"
-msgstr "Открыто"
+msgid "OpenedNDaysAgo|Created"
+msgstr ""
msgid "Opens in a new window"
msgstr "ОткроетÑÑ Ð² новом окне"
@@ -25563,9 +26099,6 @@ msgstr ""
msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
-msgid "Optional."
-msgstr ""
-
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
msgstr ""
@@ -25930,7 +26463,7 @@ msgid "PackageRegistry|Invalid Package: failed metadata extraction"
msgstr ""
msgid "PackageRegistry|Learn how to %{noPackagesLinkStart}publish and share your packages%{noPackagesLinkEnd} with GitLab."
-msgstr ""
+msgstr "Узнайте, как %{noPackagesLinkStart}публиковать и делитьÑÑ Ñвоими пакетами%{noPackagesLinkEnd} в GitLab."
msgid "PackageRegistry|License information located at %{link}"
msgstr ""
@@ -25954,7 +26487,7 @@ msgid "PackageRegistry|NuGet Command"
msgstr "Команда NuGet"
msgid "PackageRegistry|Package Registry"
-msgstr ""
+msgstr "РееÑÑ‚Ñ€ пакетов"
msgid "PackageRegistry|Package deleted successfully"
msgstr ""
@@ -26093,7 +26626,7 @@ msgid "Packages & Registries"
msgstr "Пакеты и рееÑтры"
msgid "Page not found"
-msgstr ""
+msgstr "Страница не найдена"
msgid "Page settings"
msgstr ""
@@ -26159,7 +26692,7 @@ 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 ""
@@ -26356,6 +26889,9 @@ msgstr "Вызовы Gitaly"
msgid "PerformanceBar|Memory"
msgstr ""
+msgid "PerformanceBar|Memory report"
+msgstr ""
+
msgid "PerformanceBar|Redis calls"
msgstr "Вызовы Redis"
@@ -26389,18 +26925,12 @@ msgstr ""
msgid "PerformanceBar|wall"
msgstr ""
-msgid "Performs a rebase but skips triggering a new pipeline"
-msgstr ""
-
msgid "Period in seconds"
msgstr ""
msgid "Permalink"
msgstr ""
-msgid "Permanently delete project"
-msgstr ""
-
msgid "Permanently remove group"
msgstr ""
@@ -26462,10 +26992,10 @@ msgid "Pipeline Editor|Are you sure you want to reset the file to its last commi
msgstr ""
msgid "Pipeline ID"
-msgstr ""
+msgstr "ID Ñборочной линии"
msgid "Pipeline IID"
-msgstr ""
+msgstr "IID Ñборочной линии"
msgid "Pipeline Schedule"
msgstr "РаÑпиÑание Сборочной Линии"
@@ -26474,7 +27004,7 @@ msgid "Pipeline Schedules"
msgstr "РаÑпиÑÐ°Ð½Ð¸Ñ Ð¡Ð±Ð¾Ñ€Ð¾Ñ‡Ð½Ñ‹Ñ… Линий"
msgid "Pipeline URL"
-msgstr ""
+msgstr "URL Ñборочной линии"
msgid "Pipeline durations for the last 30 commits"
msgstr ""
@@ -26486,7 +27016,7 @@ msgid "Pipeline status emails"
msgstr ""
msgid "Pipeline subscriptions"
-msgstr ""
+msgstr "ПодпиÑки Ñборочной линии"
msgid "Pipeline subscriptions trigger a new pipeline on the default branch of this project when a pipeline successfully completes for a new tag on the %{default_branch_docs} of the subscribed project."
msgstr ""
@@ -26498,10 +27028,10 @@ msgid "Pipeline: %{status}"
msgstr "Ð¡Ð±Ð¾Ñ€Ð¾Ñ‡Ð½Ð°Ñ Ð»Ð¸Ð½Ð¸Ñ:%{status}"
msgid "PipelineCharts|An error has occurred when retrieving the analytics data"
-msgstr ""
+msgstr "Произошла ошибка при получении данных аналитики"
msgid "PipelineCharts|An error has occurred when retrieving the pipelines data"
-msgstr ""
+msgstr "Произошла ошибка при получении информации о Ñборочных линиÑÑ…"
msgid "PipelineCharts|An unknown error occurred while processing CI/CD analytics."
msgstr ""
@@ -26522,7 +27052,7 @@ msgid "PipelineCharts|Successful:"
msgstr "УÑпех:"
msgid "PipelineCharts|There was an error parsing the data for the charts."
-msgstr ""
+msgstr "Возникла ошибка при разборе данных Ð´Ð»Ñ Ð³Ñ€Ð°Ñ„Ð¸ÐºÐ¾Ð²."
msgid "PipelineCharts|Total:"
msgstr "Ð’Ñего:"
@@ -26534,7 +27064,7 @@ msgid "PipelineEditorTutorial|Commit the file to your repository. The pipeline t
msgstr ""
msgid "PipelineEditorTutorial|Get started with GitLab CI/CD"
-msgstr ""
+msgstr "Ðачать работу Ñ GitLab CI/CD"
msgid "PipelineEditorTutorial|GitLab CI/CD can automatically build, test, and deploy your application."
msgstr ""
@@ -26582,7 +27112,7 @@ msgid "PipelineEditor|The CI/CD configuration is continuously validated. Errors
msgstr ""
msgid "PipelineEditor|The merged YAML view is displayed when the CI/CD configuration file has valid syntax."
-msgstr ""
+msgstr "Объединённый вид YAML отображаетÑÑ, когда файл конфигурации CI/CD имеет корректный ÑинтакÑиÑ."
msgid "PipelineEditor|The pipeline visualization is displayed when the CI/CD configuration file has valid syntax."
msgstr ""
@@ -26671,6 +27201,51 @@ msgstr "Ð¡Ð±Ð¾Ñ€Ð¾Ñ‡Ð½Ð°Ñ Ð»Ð¸Ð½Ð¸Ñ: %{ciStatus}"
msgid "PipelineStatusTooltip|Pipeline: %{ci_status}"
msgstr "Ð¡Ð±Ð¾Ñ€Ð¾Ñ‡Ð½Ð°Ñ Ð»Ð¸Ð½Ð¸Ñ:%{ci_status}"
+msgid "PipelineWizardDefaultCommitMessage|Add %{filename}"
+msgstr ""
+
+msgid "PipelineWizardDefaultCommitMessage|Update %{filename}"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|At least one entry is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This field is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This value is not valid"
+msgstr ""
+
+msgid "PipelineWizardListWidget|add another step"
+msgstr ""
+
+msgid "PipelineWizardListWidget|remove step"
+msgstr ""
+
+msgid "PipelineWizard|Commit"
+msgstr ""
+
+msgid "PipelineWizard|Commit Message"
+msgstr ""
+
+msgid "PipelineWizard|Commit changes to your file"
+msgstr ""
+
+msgid "PipelineWizard|Commit file to Branch"
+msgstr ""
+
+msgid "PipelineWizard|Commit your new file"
+msgstr ""
+
+msgid "PipelineWizard|The file has been committed."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem committing the changes."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem while checking whether your file already exists in the specified branch."
+msgstr ""
+
msgid "Pipelines"
msgstr "Сборочные линии"
@@ -26720,13 +27295,13 @@ msgid "Pipelines|Could not load artifacts."
msgstr ""
msgid "Pipelines|Could not load merged YAML content"
-msgstr ""
+msgstr "Ðе удалоÑÑŒ загрузить Ñодержимое объединённого YAML"
msgid "Pipelines|Description"
msgstr ""
msgid "Pipelines|Edit"
-msgstr ""
+msgstr "Правка"
msgid "Pipelines|Editor"
msgstr "Редактор"
@@ -26735,7 +27310,7 @@ msgid "Pipelines|Get familiar with GitLab CI/CD syntax by starting with a basic
msgstr "ОзнакомьтеÑÑŒ Ñ ÑинтакÑиÑом GitLab CI/CD, начав Ñ Ð±Ð°Ð·Ð¾Ð²Ð¾Ð¹ трёхÑтапной Ñборочной линии."
msgid "Pipelines|Get started with GitLab CI/CD"
-msgstr ""
+msgstr "Ðачать работу Ñ GitLab CI/CD"
msgid "Pipelines|GitLab CI/CD can automatically build, test, and deploy your code. Let GitLab take care of time consuming tasks, so you can spend more time creating."
msgstr ""
@@ -26744,7 +27319,7 @@ msgid "Pipelines|If you are unsure, please ask a project maintainer to review it
msgstr ""
msgid "Pipelines|Improve code quality with GitLab CI/CD"
-msgstr ""
+msgstr "ПовыÑьте качеÑтво кода Ñ Ð¿Ð¾Ð¼Ð¾Ñ‰ÑŒÑŽ GitLab CI/CD"
msgid "Pipelines|Install GitLab Runners"
msgstr ""
@@ -26759,19 +27334,19 @@ msgid "Pipelines|Learn about Runners"
msgstr ""
msgid "Pipelines|Lint"
-msgstr ""
+msgstr "Lint"
msgid "Pipelines|Loading Pipelines"
msgstr "ЗагружаютÑÑ Ñборочные линии"
msgid "Pipelines|Loading pipelines"
-msgstr ""
+msgstr "Загрузка Ñборочных линий"
msgid "Pipelines|Merged YAML is view only"
-msgstr ""
+msgstr "Объединённый YAML доÑтупен только Ð´Ð»Ñ Ð¿Ñ€Ð¾Ñмотра"
msgid "Pipelines|More Information"
-msgstr ""
+msgstr "Больше информации"
msgid "Pipelines|No triggers have been created yet. Add one using the form above."
msgstr ""
@@ -26780,12 +27355,12 @@ msgid "Pipelines|Owner"
msgstr ""
msgid "Pipelines|Pipeline Editor"
-msgstr ""
+msgstr "Редактор Ñборочных линий"
msgid "Pipelines|Project cache successfully reset."
msgstr "КÑш проекта уÑпешно очищен."
-msgid "Pipelines|Revoke"
+msgid "Pipelines|Revoke trigger"
msgstr ""
msgid "Pipelines|Something went wrong while cleaning runners cache."
@@ -26798,10 +27373,10 @@ msgid "Pipelines|The %{namespace_name} namespace has exceeded its pipeline minut
msgstr ""
msgid "Pipelines|The CI configuration was not loaded, please try again."
-msgstr ""
+msgstr "ÐšÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð°Ñ†Ð¸Ñ CI не загружена, попробуйте ещё раз."
msgid "Pipelines|The GitLab CI configuration could not be updated."
-msgstr ""
+msgstr "Ðе удалоÑÑŒ обновить конфигурацию GitLab CI."
msgid "Pipelines|There are currently no finished pipelines."
msgstr ""
@@ -26810,10 +27385,10 @@ msgid "Pipelines|There are currently no pipelines."
msgstr "Ð’ наÑтоÑщее Ð²Ñ€ÐµÐ¼Ñ Ð½ÐµÑ‚ Ñборочных линий."
msgid "Pipelines|There was a problem with loading the pipeline data."
-msgstr ""
+msgstr "Возникла проблема при загрузке данных Ñборочных линий."
msgid "Pipelines|There was an error fetching the pipelines. Try again in a few moments or contact your support team."
-msgstr ""
+msgstr "При получении Ñборочных линий произошла ошибка. Повторите попытку через некоторое Ð²Ñ€ÐµÐ¼Ñ Ð¸Ð»Ð¸ обратитеÑÑŒ в Ñлужбу поддержки."
msgid "Pipelines|This GitLab CI configuration is invalid."
msgstr ""
@@ -26828,6 +27403,12 @@ msgid "Pipelines|This GitLab CI configuration is valid."
msgstr ""
msgid "Pipelines|This is a child pipeline within the parent pipeline"
+msgstr "Это дочернÑÑ ÑÐ±Ð¾Ñ€Ð¾Ñ‡Ð½Ð°Ñ Ð»Ð¸Ð½Ð¸Ñ Ð² ÑоÑтаве родительÑкой"
+
+msgid "Pipelines|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipelines|This pipeline ran on the contents of this merge request's source branch, not the target branch."
msgstr ""
msgid "Pipelines|This pipeline will run code originating from a forked project merge request. This means that the code can potentially have security considerations like exposing CI variables."
@@ -26840,16 +27421,16 @@ msgid "Pipelines|To keep your codebase simple, readable, and accessible to contr
msgstr ""
msgid "Pipelines|Token"
-msgstr ""
+msgstr "Токен"
msgid "Pipelines|Trigger user has insufficient permissions to project"
msgstr ""
msgid "Pipelines|Use a CI/CD template"
-msgstr ""
+msgstr "ИÑпользовать шаблон CI/CD"
msgid "Pipelines|Use a sample %{codeStart}.gitlab-ci.yml%{codeEnd} template file to explore how CI/CD works."
-msgstr ""
+msgstr "ИÑпользуйте шаблон %{codeStart}.gitlab-ci.yml%{codeEnd}, чтобы изучить, как работает CI/CD."
msgid "Pipelines|Use a sample CI/CD template"
msgstr ""
@@ -26858,23 +27439,20 @@ msgid "Pipelines|Use a template based on your project's language or framework to
msgstr ""
msgid "Pipelines|Use template"
-msgstr ""
+msgstr "ИÑпользовать шаблон"
msgid "Pipelines|Validating GitLab CI configuration…"
-msgstr ""
+msgstr "Проверка конфигурации GitLab CI…"
msgid "Pipelines|View merged YAML"
-msgstr ""
+msgstr "ПроÑмотреть объединённый YAML"
msgid "Pipelines|Visualize"
-msgstr ""
+msgstr "ВизуализациÑ"
msgid "Pipelines|Your changes have been successfully committed. Now redirecting to the new merge request page."
msgstr ""
-msgid "Pipelines|detached"
-msgstr ""
-
msgid "Pipelines|error"
msgstr ""
@@ -26884,32 +27462,35 @@ msgstr ""
msgid "Pipelines|latest"
msgstr ""
-msgid "Pipelines|stuck"
+msgid "Pipelines|merge request"
msgstr ""
-msgid "Pipelines|train"
+msgid "Pipelines|merge train"
+msgstr ""
+
+msgid "Pipelines|stuck"
msgstr ""
msgid "Pipelines|yaml invalid"
msgstr ""
msgid "Pipeline|Actions"
-msgstr ""
+msgstr "ДейÑтвиÑ"
msgid "Pipeline|Branch name"
-msgstr ""
+msgstr "Ð˜Ð¼Ñ Ð²ÐµÑ‚ÐºÐ¸"
msgid "Pipeline|Branches or tags could not be loaded."
msgstr "Ðе удалоÑÑŒ загрузить ветки или теги."
msgid "Pipeline|Canceled"
-msgstr ""
+msgstr "Отменено"
msgid "Pipeline|Checking pipeline status"
-msgstr ""
+msgstr "Проверка ÑоÑтоÑÐ½Ð¸Ñ Ñборочной линии"
msgid "Pipeline|Checking pipeline status."
-msgstr ""
+msgstr "Проверка ÑоÑтоÑÐ½Ð¸Ñ Ñборочной линии."
msgid "Pipeline|Commit"
msgstr ""
@@ -27019,6 +27600,12 @@ msgstr ""
msgid "Pipeline|This change will not change the overall test coverage if merged."
msgstr ""
+msgid "Pipeline|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipeline|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipeline|Trigger author"
msgstr ""
@@ -27043,6 +27630,12 @@ msgstr ""
msgid "Pipeline|for"
msgstr "длÑ"
+msgid "Pipeline|merge request"
+msgstr ""
+
+msgid "Pipeline|merge train"
+msgstr ""
+
msgid "Pipeline|on"
msgstr ""
@@ -27181,9 +27774,6 @@ msgstr "ПожалуйÑта введите правильное чиÑло"
msgid "Please enter a valid time interval"
msgstr ""
-msgid "Please enter or upload a valid license."
-msgstr ""
-
msgid "Please enter your current password."
msgstr ""
@@ -27292,9 +27882,6 @@ msgstr ""
msgid "Please type %{phrase_code} to proceed or close this modal to cancel."
msgstr "ПожалуйÑта, введите %{phrase_code} чтобы продолжить, или закройте Ñто окно Ð´Ð»Ñ Ð¾Ñ‚Ð¼ÐµÐ½Ñ‹."
-msgid "Please type the following to confirm:"
-msgstr ""
-
msgid "Please use this form to report to the admin users who create spam issues, comments or behave inappropriately."
msgstr "ПожалуйÑта, иÑпользуйте Ñту форму Ð´Ð»Ñ Ð¾Ð¿Ð¾Ð²ÐµÑ‰ÐµÐ½Ð¸Ñ Ð°Ð´Ð¼Ð¸Ð½Ð¸Ñтраторов о пользователÑÑ…, Ñоздающих задачи и комментарии, Ñодержащие Ñпам или ведущих ÑÐµÐ±Ñ Ð½ÐµÐ°Ð´ÐµÐºÐ²Ð°Ñ‚Ð½Ð¾."
@@ -27322,12 +27909,27 @@ msgstr ""
msgid "Policies"
msgstr ""
+msgid "Policy '%{escalation_policy_name}' does not exist."
+msgstr ""
+
msgid "Policy management project does have any policies in %{policy_path}"
msgstr ""
msgid "Policy project doesn't exist"
msgstr ""
+msgid "PolicyRuleMultiSelect|%{firstLabel} +%{numberOfAdditionalLabels} more"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|All %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select all"
+msgstr ""
+
msgid "Polling interval multiplier"
msgstr ""
@@ -27556,6 +28158,9 @@ msgstr ""
msgid "Private projects can be created in your personal namespace with:"
msgstr "Личные проекты могут быть Ñозданы в вашем перÑональном проÑтранÑтве Ñ:"
+msgid "Problem with %{name} command: %{message}."
+msgstr ""
+
msgid "Proceed"
msgstr "Продолжить"
@@ -28030,6 +28635,9 @@ msgstr "Языки программированиÑ, иÑпользуемые в
msgid "Progress"
msgstr "ПрогреÑÑ"
+msgid "Progress tracking"
+msgstr ""
+
msgid "Project"
msgstr "Проект"
@@ -28261,6 +28869,9 @@ msgstr ""
msgid "ProjectQualitySummary|Failure"
msgstr ""
+msgid "ProjectQualitySummary|Get insight into the overall percentage of tests in your project that succeed, fail and are skipped."
+msgstr ""
+
msgid "ProjectQualitySummary|Latest pipeline results"
msgstr ""
@@ -28279,6 +28890,12 @@ msgstr ""
msgid "ProjectQualitySummary|See project Code Coverage Statistics"
msgstr ""
+msgid "ProjectQualitySummary|Set up test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|Set up test runs (opens in a new tab)"
+msgstr ""
+
msgid "ProjectQualitySummary|Skipped"
msgstr ""
@@ -28457,7 +29074,7 @@ msgid "ProjectSettings|Choose the method, options, checks, and squash options fo
msgstr ""
msgid "ProjectSettings|Choose your merge method, merge options, merge checks, and merge suggestions."
-msgstr "Выберите ваш метод, наÑтройки, проверки и Ð¿Ñ€ÐµÐ´Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ ÑлиÑниÑ."
+msgstr "Выберите методы ÑлиÑниÑ, наÑтройки, проверки и предложениÑ."
msgid "ProjectSettings|Choose your merge method, options, checks, and squash options."
msgstr ""
@@ -28555,14 +29172,20 @@ msgstr "ОбÑуждениÑ"
msgid "ProjectSettings|LFS objects from this repository are available to forks. %{linkStart}How do I remove them?%{linkEnd}"
msgstr ""
+msgid "ProjectSettings|Learn about commit history."
+msgstr ""
+
+msgid "ProjectSettings|Leave empty to use default template."
+msgstr ""
+
msgid "ProjectSettings|Manage who can see the project in the public access directory."
msgstr ""
msgid "ProjectSettings|Manages large files such as audio, video, and graphics files."
msgstr "УправлÑет большими файлами, такими как аудио, видео и графичеÑкие."
-msgid "ProjectSettings|Maximum 500 characters."
-msgstr "МакÑимум 500 Ñимволов."
+msgid "ProjectSettings|Maximum %{maxLength} characters."
+msgstr ""
msgid "ProjectSettings|Merge checks"
msgstr "Проверки ÑлиÑниÑ"
@@ -28702,6 +29325,9 @@ msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
msgstr ""
+msgid "ProjectSettings|The default template will be applied on save."
+msgstr ""
+
msgid "ProjectSettings|These checks must pass before merge requests can be merged."
msgstr ""
@@ -28756,6 +29382,9 @@ msgstr "Предупреждать о потенциально нежелатеÐ
msgid "ProjectSettings|What are badges?"
msgstr "Что такое значки?"
+msgid "ProjectSettings|What are merge trains?"
+msgstr ""
+
msgid "ProjectSettings|When merge request pipelines are enabled in the CI/CD configuration file, pipelines validate the combined results of the source and target branches. %{link_start}How to configure merge request pipelines?%{link_end}"
msgstr ""
@@ -28873,6 +29502,9 @@ msgstr ""
msgid "Projects are organized into groups"
msgstr ""
+msgid "Projects are where you store your code, access issues, wiki and other features of GitLab."
+msgstr ""
+
msgid "Projects contributed to"
msgstr ""
@@ -28888,12 +29520,6 @@ msgstr ""
msgid "Projects to index"
msgstr "Проекты Ð´Ð»Ñ Ð¸Ð½Ð´ÐµÐºÑированиÑ"
-msgid "Projects will be permanently deleted after a %{waiting_period}-day waiting period."
-msgstr ""
-
-msgid "Projects will be permanently deleted immediately."
-msgstr ""
-
msgid "Projects with critical vulnerabilities"
msgstr ""
@@ -28978,6 +29604,9 @@ msgstr "Импорт"
msgid "ProjectsNew|Import project"
msgstr "Импортировать проект"
+msgid "ProjectsNew|Include a Getting Started README"
+msgstr ""
+
msgid "ProjectsNew|Initialize repository with a README"
msgstr "Добавить README файл"
@@ -28993,6 +29622,9 @@ msgstr ""
msgid "ProjectsNew|Project description %{tag_start}(optional)%{tag_end}"
msgstr "ОпиÑание проекта %{tag_start}(необÑзательно)%{tag_end}"
+msgid "ProjectsNew|Recommended if you're new to GitLab"
+msgstr ""
+
msgid "ProjectsNew|Run CI/CD for external repository"
msgstr "ЗапуÑтить CI/CD Ð´Ð»Ñ Ð²Ð½ÐµÑˆÐ½ÐµÐ³Ð¾ репозиториÑ"
@@ -29410,6 +30042,9 @@ msgstr "Переключить утверждение владельцами кÐ
msgid "ProtectedBranch|Unprotect"
msgstr ""
+msgid "ProtectedBranch|Unprotect branch"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
@@ -29437,6 +30072,9 @@ msgstr ""
msgid "ProtectedEnvironment|Protected Environment (%{protected_environments_count})"
msgstr ""
+msgid "ProtectedEnvironment|Required approvals"
+msgstr ""
+
msgid "ProtectedEnvironment|Select an environment"
msgstr ""
@@ -29458,10 +30096,13 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|Unprotect tag"
+msgstr ""
+
msgid "ProtectedTags|default"
msgstr ""
-msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
+msgid "ProtectedTag|By default, protected tags restrict who can modify the tag."
msgstr ""
msgid "ProtectedTag|Learn more."
@@ -29524,6 +30165,9 @@ msgstr "Открытые Ñборочные линии"
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Public projects are an easy way to allow everyone to have read-only access."
+msgstr ""
+
msgid "Publish to status page"
msgstr ""
@@ -29680,9 +30324,6 @@ msgstr "Ð’Ñего коммитов: %{total_commits_count}"
msgid "QualitySummary|Project quality"
msgstr ""
-msgid "Quarters"
-msgstr ""
-
msgid "Query"
msgstr "ЗапроÑ"
@@ -29767,6 +30408,9 @@ msgstr ""
msgid "Read more about project permissions %{help_link_open}here%{help_link_close}"
msgstr ""
+msgid "Read more about related epics"
+msgstr ""
+
msgid "Read more about related issues"
msgstr ""
@@ -29797,10 +30441,7 @@ msgstr ""
msgid "Rebase source branch on the target branch."
msgstr ""
-msgid "Rebase without CI"
-msgstr ""
-
-msgid "Rebases and triggers a pipeline"
+msgid "Rebase without pipeline"
msgstr ""
msgid "Recaptcha verified?"
@@ -29851,9 +30492,6 @@ msgstr ""
msgid "Reconfigure"
msgstr ""
-msgid "Recovering projects"
-msgstr ""
-
msgid "Recovery Codes"
msgstr "Коды воÑÑтановлениÑ"
@@ -29915,6 +30553,12 @@ msgstr ""
msgid "Regex pattern"
msgstr ""
+msgid "Region"
+msgstr ""
+
+msgid "Regions"
+msgstr ""
+
msgid "Register"
msgstr ""
@@ -30147,9 +30791,6 @@ msgstr "Удалить вÑе или конкретные метки(и)"
msgid "Remove all or specific reviewer(s)"
msgstr ""
-msgid "Remove approver"
-msgstr ""
-
msgid "Remove approvers"
msgstr "Удалить утверждающих"
@@ -30165,6 +30806,9 @@ msgstr "Удалить ответÑтвенного"
msgid "Remove attention request"
msgstr ""
+msgid "Remove attention request(s)"
+msgstr ""
+
msgid "Remove avatar"
msgstr "Удалить аватар"
@@ -30303,6 +30947,9 @@ msgstr "Ð’Ñе метки удалены."
msgid "Removed an issue from an epic."
msgstr "ОбÑуждение удалено из цели."
+msgid "Removed attention from %{users_sentence}."
+msgstr ""
+
msgid "Removed attention request from @%{username}"
msgstr ""
@@ -30354,6 +31001,9 @@ msgstr "УдалÑет вÑе метки."
msgid "Removes an issue from an epic."
msgstr "УдалÑет обÑуждение из цели."
+msgid "Removes attention from %{users_sentence}."
+msgstr ""
+
msgid "Removes parent epic %{epic_ref}."
msgstr "УдалÑет родительÑкую цель %{epic_ref}."
@@ -30465,6 +31115,9 @@ msgstr "ПожаловатьÑÑ"
msgid "Report abuse to admin"
msgstr "Сообщить о нарушении админиÑтратору"
+msgid "Report is generating and will be sent to your email address."
+msgstr ""
+
msgid "Reported %{timeAgo} by %{reportedBy}"
msgstr "Сообщил %{reportedBy} %{timeAgo}"
@@ -30764,6 +31417,15 @@ msgstr ""
msgid "Request attention"
msgstr ""
+msgid "Request attention from %{users_sentence}."
+msgstr ""
+
+msgid "Request attention from assignee or reviewer"
+msgstr ""
+
+msgid "Request attention from assignee(s) or reviewer(s)"
+msgstr ""
+
msgid "Request attention to review"
msgstr ""
@@ -30788,6 +31450,9 @@ msgstr ""
msgid "Requested %{time_ago}"
msgstr "Запрошено %{time_ago}"
+msgid "Requested attention from %{users_sentence}."
+msgstr ""
+
msgid "Requested attention from @%{username}"
msgstr ""
@@ -31006,6 +31671,9 @@ msgstr ""
msgid "Restore project"
msgstr ""
+msgid "Restoring projects"
+msgstr ""
+
msgid "Restoring the group will prevent the group, its subgroups and projects from being removed on this date."
msgstr ""
@@ -31036,6 +31704,9 @@ msgstr ""
msgid "Retry"
msgstr "Повторить"
+msgid "Retry failed jobs"
+msgstr ""
+
msgid "Retry job"
msgstr ""
@@ -31085,9 +31756,6 @@ msgstr "ПроÑмотр поÑледнего приложениÑ"
msgid "Review changes"
msgstr ""
-msgid "Review requested from %{name}"
-msgstr "%{name} запроÑил рецензию"
-
msgid "Review requests for you"
msgstr "ЗапроÑÑ‹ рецензий Ð´Ð»Ñ Ð²Ð°Ñ"
@@ -31254,6 +31922,9 @@ msgstr ""
msgid "Runners|Assigned Group"
msgstr ""
+msgid "Runners|Assigned Projects (%{projectCount})"
+msgstr ""
+
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -31323,6 +31994,9 @@ msgstr ""
msgid "Runners|Instance"
msgstr ""
+msgid "Runners|Jobs"
+msgstr ""
+
msgid "Runners|Last contact"
msgstr ""
@@ -31416,9 +32090,6 @@ msgstr ""
msgid "Runners|Runner %{name} was deleted"
msgstr ""
-msgid "Runners|Runner ID"
-msgstr ""
-
msgid "Runners|Runner assigned to project."
msgstr ""
@@ -31566,6 +32237,9 @@ msgstr ""
msgid "Runners|stale"
msgstr ""
+msgid "Runner|This runner has not run any jobs."
+msgstr ""
+
msgid "Running"
msgstr "ВыполнÑетÑÑ"
@@ -31680,6 +32354,24 @@ msgstr ""
msgid "Saving project."
msgstr ""
+msgid "ScanResultPolicy|%{ifLabelStart}if%{ifLabelEnd} %{scanners} scan in an open merge request targeting the %{branches} branch(es) finds %{vulnerabilitiesAllowed} or more %{severities} vulnerabilities that are %{vulnerabilityStates}"
+msgstr ""
+
+msgid "ScanResultPolicy|%{thenLabelStart}Then%{thenLabelEnd} Require approval from %{approvalsRequired} of the following approvers: %{approvers}"
+msgstr ""
+
+msgid "ScanResultPolicy|add an approver"
+msgstr ""
+
+msgid "ScanResultPolicy|scanners"
+msgstr ""
+
+msgid "ScanResultPolicy|severity levels"
+msgstr ""
+
+msgid "ScanResultPolicy|vulnerability states"
+msgstr ""
+
msgid "Scanner"
msgstr ""
@@ -31812,6 +32504,9 @@ msgstr ""
msgid "Search for a user"
msgstr "ПоиÑк пользователÑ"
+msgid "Search for an emoji"
+msgstr ""
+
msgid "Search for projects, issues, etc."
msgstr "ПоиÑк проектов, обÑуждений и Ñ‚.д."
@@ -32021,18 +32716,12 @@ msgstr ""
msgid "Secret Detection"
msgstr ""
-msgid "Secret access key"
-msgstr ""
-
msgid "Secret token"
msgstr ""
msgid "Secure token that identifies an external storage request."
msgstr ""
-msgid "SecureCodeWarrior"
-msgstr ""
-
msgid "Security"
msgstr "БезопаÑноÑÑ‚ÑŒ"
@@ -32057,9 +32746,6 @@ msgstr "Отчет безопаÑноÑти уÑтарел. ПожалуйÑта
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr "Отчет о безопаÑноÑти уÑтарел. ЗапуÑтите %{newPipelineLinkStart}новую Ñборочную линию%{newPipelineLinkEnd} в целевой ветке (%{targetBranchName})"
-msgid "Security training with guide and learning pathways."
-msgstr ""
-
msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
@@ -32162,7 +32848,7 @@ msgstr ""
msgid "SecurityConfiguration|Manage corpus"
msgstr ""
-msgid "SecurityConfiguration|Manage corpus files used as mutation sources in coverage fuzzing."
+msgid "SecurityConfiguration|Manage corpus files used as seed inputs with coverage-guided fuzzing."
msgstr ""
msgid "SecurityConfiguration|Manage profiles for use by DAST scans."
@@ -32228,15 +32914,15 @@ msgstr ""
msgid "SecurityOrchestration|.yaml preview"
msgstr ""
-msgid "SecurityOrchestration|Action"
-msgstr ""
-
msgid "SecurityOrchestration|Actions"
msgstr ""
msgid "SecurityOrchestration|Add rule"
msgstr ""
+msgid "SecurityOrchestration|After dismissing the alert, the information will never be shown again."
+msgstr ""
+
msgid "SecurityOrchestration|All policies"
msgstr ""
@@ -32252,7 +32938,7 @@ msgstr ""
msgid "SecurityOrchestration|Description"
msgstr ""
-msgid "SecurityOrchestration|Disabled"
+msgid "SecurityOrchestration|Don't show the alert anymore"
msgstr ""
msgid "SecurityOrchestration|Edit policy"
@@ -32261,13 +32947,13 @@ msgstr ""
msgid "SecurityOrchestration|Edit policy project"
msgstr ""
-msgid "SecurityOrchestration|Enabled"
+msgid "SecurityOrchestration|Empty policy name"
msgstr ""
-msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Enabled"
msgstr ""
-msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
msgstr ""
msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
@@ -32276,7 +32962,7 @@ msgstr ""
msgid "SecurityOrchestration|Invalid policy type"
msgstr ""
-msgid "SecurityOrchestration|Latest scan"
+msgid "SecurityOrchestration|Latest scan run against %{agent}"
msgstr ""
msgid "SecurityOrchestration|Network"
@@ -32285,15 +32971,27 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No actions defined - policy will not run."
+msgstr ""
+
+msgid "SecurityOrchestration|No description"
+msgstr ""
+
msgid "SecurityOrchestration|No rules defined - policy will not run."
msgstr ""
+msgid "SecurityOrchestration|Not enabled"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
msgid "SecurityOrchestration|Policies"
msgstr ""
+msgid "SecurityOrchestration|Policy Type"
+msgstr ""
+
msgid "SecurityOrchestration|Policy cannot be enabled for non-existing branches (%{branches})"
msgstr ""
@@ -32318,10 +33016,13 @@ msgstr ""
msgid "SecurityOrchestration|Require %{approvals} %{plural} from %{approvers} if any of the following occur:"
msgstr ""
-msgid "SecurityOrchestration|Rule"
+msgid "SecurityOrchestration|Rules"
+msgstr ""
+
+msgid "SecurityOrchestration|Runs %{actions} and %{lastAction} scans"
msgstr ""
-msgid "SecurityOrchestration|Rules"
+msgid "SecurityOrchestration|Runs a %{action} scan"
msgstr ""
msgid "SecurityOrchestration|Scan Execution"
@@ -32381,6 +33082,9 @@ msgstr ""
msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
+msgid "SecurityOrchestration|This view only shows scan results for the agent %{agent}. You can view scan results for all agents in the %{linkStart}Operational Vulnerabilities tab of the vulnerability report%{linkEnd}."
+msgstr ""
+
msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
@@ -32435,9 +33139,6 @@ msgstr ""
msgid "SecurityOrchestration|users with ids"
msgstr ""
-msgid "SecurityOrchestration|view results"
-msgstr ""
-
msgid "SecurityOrchestration|vulnerabilities"
msgstr ""
@@ -33107,22 +33808,19 @@ msgstr ""
msgid "Serverless|Getting started with serverless"
msgstr "Ðачало работы Ñ serverless"
-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|In order to start using functions as a service, you must first install Knative on your Kubernetes cluster. %{linkStart}More information%{linkEnd}"
-msgstr ""
-
msgid "Serverless|Learn more about Serverless"
msgstr "Подробнее о Serverless"
msgid "Serverless|No functions available"
msgstr "Ðет доÑтупных функций"
-msgid "Serverless|Sign up for First Look"
+msgid "Serverless|Serverless was %{linkStart}deprecated%{linkEnd} in GitLab 14.3."
+msgstr ""
+
+msgid "Serverless|Serverless was %{postLinkStart}deprecated%{postLinkEnd}. But if you opt to use it, you must install Knative in your Kubernetes cluster first. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "Serverless|The deploy job has not finished."
@@ -33134,9 +33832,6 @@ msgstr ""
msgid "Serverless|There is currently no function data available from Knative. This could be for a variety of reasons including:"
msgstr "Ð’ наÑтоÑщее Ð²Ñ€ÐµÐ¼Ñ Ð½ÐµÑ‚ данных о функциÑÑ…, доÑтупных от Knative. Это может быть по целому Ñ€Ñду причин, включаÑ:"
-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 ""
@@ -33152,9 +33847,6 @@ msgstr ""
msgid "Service Account Key"
msgstr ""
-msgid "Service Accounts"
-msgstr ""
-
msgid "Service Accounts keys authorize GitLab to deploy your Google Cloud project"
msgstr ""
@@ -33164,10 +33856,10 @@ msgstr "Служба поддержки"
msgid "Service Desk allows people to create issues in your GitLab instance without their own user account. It provides a unique email address for end users to create issues in a project. Replies can be sent either through the GitLab interface or by email. End users only see threads through email."
msgstr ""
-msgid "Service Usage Data"
+msgid "Service account generated successfully"
msgstr ""
-msgid "Service account generated successfully"
+msgid "Service accounts"
msgstr ""
msgid "Service ping is disabled in your configuration file, and cannot be enabled through this form."
@@ -33311,6 +34003,9 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
+msgid "Set the per-user rate limit for getting a user by ID via the API."
+msgstr ""
+
msgid "Set the per-user rate limit for notes created by web or API requests."
msgstr ""
@@ -33492,6 +34187,9 @@ msgstr ""
msgid "Shared runners details"
msgstr ""
+msgid "Shared runners enabled cannot be enabled until a valid credit card is on file"
+msgstr ""
+
msgid "Shared runners help link"
msgstr "Справка по общим Runner'ам"
@@ -33549,6 +34247,9 @@ msgstr ""
msgid "Show all issues."
msgstr ""
+msgid "Show all milestones"
+msgstr ""
+
msgid "Show all test cases."
msgstr ""
@@ -33585,6 +34286,9 @@ msgstr ""
msgid "Show file contents"
msgstr ""
+msgid "Show group milestones"
+msgstr ""
+
msgid "Show labels"
msgstr ""
@@ -33600,6 +34304,12 @@ msgstr ""
msgid "Show open epics"
msgstr ""
+msgid "Show project milestones"
+msgstr ""
+
+msgid "Show sub-group milestones"
+msgstr ""
+
msgid "Show the Closed list"
msgstr ""
@@ -33609,13 +34319,6 @@ msgstr ""
msgid "Show whitespace changes"
msgstr "Показать Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð¿Ñ€Ð¾Ð±ÐµÐ»Ð¾Ð²"
-msgid "Showing %d event"
-msgid_plural "Showing %d events"
-msgstr[0] "Показано %d Ñобытие"
-msgstr[1] "Показано %d ÑобытиÑ"
-msgstr[2] "Показано %d Ñобытий"
-msgstr[3] "Показано %d Ñобытий"
-
msgid "Showing %{conflict} between %{sourceBranch} and %{targetBranch}"
msgstr ""
@@ -33677,12 +34380,6 @@ msgstr ""
msgid "Sidebar|None"
msgstr ""
-msgid "Sidebar|Only numeral characters allowed"
-msgstr ""
-
-msgid "Sidebar|Weight"
-msgstr "Приоритет"
-
msgid "Sidekiq job compression threshold (bytes)"
msgstr ""
@@ -33845,6 +34542,9 @@ msgstr ""
msgid "Slack logo"
msgstr ""
+msgid "SlackIntegration|Are you sure you want to remove this project from the Slack application?"
+msgstr ""
+
msgid "SlackIntegration|GitLab for Slack"
msgstr ""
@@ -33854,6 +34554,9 @@ msgstr ""
msgid "SlackIntegration|Project alias"
msgstr ""
+msgid "SlackIntegration|Remove project"
+msgstr ""
+
msgid "SlackIntegration|Select a GitLab project to link with your Slack workspace."
msgstr ""
@@ -33998,9 +34701,6 @@ msgstr ""
msgid "Something went wrong trying to load issue contacts."
msgstr ""
-msgid "Something went wrong when creating a work item. Please try again"
-msgstr ""
-
msgid "Something went wrong when reordering designs. Please try again"
msgstr ""
@@ -34094,9 +34794,6 @@ msgstr ""
msgid "Something went wrong while inserting your image. Please try again."
msgstr ""
-msgid "Something went wrong while merging this merge request. Please try again."
-msgstr ""
-
msgid "Something went wrong while obtaining the Let's Encrypt certificate."
msgstr ""
@@ -34418,11 +35115,11 @@ 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 ""
-msgid "SourcegraphAdmin|If checked, only public projects will have code intelligence and communicate with Sourcegraph."
+msgid "SourcegraphAdmin|Learn more."
msgstr ""
-msgid "SourcegraphAdmin|More information"
-msgstr "Больше данных"
+msgid "SourcegraphAdmin|Only public projects have code intelligence enabled and communicate with Sourcegraph."
+msgstr ""
msgid "SourcegraphAdmin|Save changes"
msgstr "Сохранить изменениÑ"
@@ -34430,7 +35127,7 @@ msgstr "Сохранить изменениÑ"
msgid "SourcegraphAdmin|Sourcegraph URL"
msgstr ""
-msgid "SourcegraphAdmin|e.g. https://sourcegraph.example.com"
+msgid "SourcegraphAdmin|https://sourcegraph.example.com"
msgstr ""
msgid "SourcegraphPreferences|This feature is experimental and currently limited to certain projects."
@@ -34565,6 +35262,9 @@ msgstr "Ðачать очиÑтку"
msgid "Start date"
msgstr "Дата начала"
+msgid "Start free trial"
+msgstr ""
+
msgid "Start merge train"
msgstr ""
@@ -34595,6 +35295,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started escalation for this incident."
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -34607,6 +35310,9 @@ msgstr "Будет запущен %{startsIn}"
msgid "Starts at (UTC)"
msgstr "Опубликовать (UTC)"
+msgid "Starts escalations for this incident"
+msgstr ""
+
msgid "Starts on"
msgstr ""
@@ -34868,6 +35574,9 @@ msgstr "ÐеизвеÑтный"
msgid "Strikethrough"
msgstr ""
+msgid "Strikethrough text"
+msgstr ""
+
msgid "Subgroup information"
msgstr ""
@@ -35102,6 +35811,21 @@ msgstr "ПодÑчет иÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ Ð²Ñ‹Ð¿Ð¾Ð»Ð½ÑетÑÑ Ð¾Ð´Ð¸Ð
msgid "Subscriptions"
msgstr ""
+msgid "Subscriptions|Chat with sales"
+msgstr ""
+
+msgid "Subscriptions|Close"
+msgstr ""
+
+msgid "Subscriptions|Not ready to buy yet?"
+msgstr ""
+
+msgid "Subscriptions|Start a free trial"
+msgstr ""
+
+msgid "Subscriptions|We understand. Maybe you have some questions for our sales team, or maybe you'd like to try some of the paid features first. What would you like to do?"
+msgstr ""
+
msgid "Subscription|Your subscription for %{strong}%{namespace_name}%{strong_close} has expired and you are now on %{pricing_link_start}the GitLab Free tier%{pricing_link_end}. Don't worry, your data is safe. Get in touch with our support team (%{support_email}). They'll gladly help with your subscription renewal."
msgstr ""
@@ -35312,6 +36036,9 @@ msgstr ""
msgid "SuperSonics|Maximum users"
msgstr ""
+msgid "SuperSonics|Offline cloud"
+msgstr ""
+
msgid "SuperSonics|Paste your activation code"
msgstr ""
@@ -35378,6 +36105,12 @@ msgstr ""
msgid "SuperSonics|You do not have an active subscription"
msgstr ""
+msgid "SuperSonics|You have a future dated license"
+msgstr ""
+
+msgid "SuperSonics|You have added a license that activates on %{date}. Please see the subscription history table below for more details."
+msgstr ""
+
msgid "SuperSonics|You have successfully added a license that activates on %{date}. Please see the subscription history table below for more details."
msgstr ""
@@ -35537,6 +36270,9 @@ msgstr "Ðазвание тега"
msgid "Tag name is required"
msgstr ""
+msgid "Tag push"
+msgstr ""
+
msgid "Tag push events"
msgstr ""
@@ -35639,6 +36375,9 @@ msgstr "Ðапишите заметки к релизу или перетащиÑ
msgid "TagsPage|protected"
msgstr "защищенный"
+msgid "Take a look at the documentation to discover all of GitLab’s capabilities."
+msgstr ""
+
msgid "Target Branch"
msgstr "Ветка"
@@ -36053,6 +36792,9 @@ msgstr ""
msgid "Tests"
msgstr "ТеÑÑ‚Ñ‹"
+msgid "Text (optional)"
+msgstr ""
+
msgid "Text added to the body of all email messages. %{character_limit} character limit"
msgstr ""
@@ -36105,6 +36847,9 @@ msgstr ""
msgid "The CSV export will be created in the background. Once finished, it will be sent to %{email} in an attachment."
msgstr ""
+msgid "The CSV export you requested of all user memberships is attached to this email."
+msgstr ""
+
msgid "The GitLab subscription service (customers.gitlab.com) is currently experiencing an outage. You can monitor the status and get updates at %{linkStart}status.gitlab.com%{linkEnd}."
msgstr ""
@@ -36180,6 +36925,9 @@ 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 epic"
+msgstr ""
+
msgid "The current issue"
msgstr "Текущее обÑуждение"
@@ -36343,6 +37091,9 @@ msgstr ""
msgid "The latest pipeline for this merge request has failed."
msgstr ""
+msgid "The license key is invalid."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr "Лицензионный ключ недейÑтвителен. УдоÑтоверьтеÑÑŒ, что он Ñовпадает Ñ Ñ‚ÐµÐ¼, что вы получили от GitLab Inc."
@@ -36358,6 +37109,9 @@ msgstr "Ð›Ð¸Ñ†ÐµÐ½Ð·Ð¸Ñ Ð±Ñ‹Ð»Ð° уÑпешно загружена и тепеÑ
msgid "The license was successfully uploaded and will be active from %{starts_at}. You can see the details below."
msgstr ""
+msgid "The license you uploaded is invalid. If the issue persists, contact support at %{link}."
+msgstr ""
+
msgid "The list creation wizard is already open"
msgstr ""
@@ -36979,10 +37733,13 @@ msgstr "Это дейÑтвие может привеÑти к потере да
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} and everything this project contains. %{strongOpen}There is no going back%{strongClose}"
+msgstr ""
+
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains."
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}on %{date}%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains. %{strongOpen}There is no going back.%{strongClose}"
msgstr ""
msgid "This action will %{strongOpen}permanently remove%{strongClose} %{codeOpen}%{group}%{codeClose} %{strongOpen}immediately%{strongClose}."
@@ -37111,9 +37868,6 @@ msgstr ""
msgid "This file was modified for readability, and can't accept suggestions. Edit it directly."
msgstr ""
-msgid "This forked project has the following:"
-msgstr ""
-
msgid "This form is disabled in preview"
msgstr ""
@@ -37126,7 +37880,7 @@ msgstr ""
msgid "This group can't be removed because it is linked to a subscription. To remove this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
-msgid "This group can't be transfered because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
+msgid "This group can't be transferred because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
msgid "This group cannot be invited to a project inside a group with enforced SSO"
@@ -37153,6 +37907,9 @@ 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 incident is already escalated with '%{escalation_policy_name}'."
+msgstr ""
+
msgid "This invitation was sent to %{mail_to_invite_email}, but you are signed in as %{link_to_current_user} with email %{mail_to_current_user}."
msgstr ""
@@ -37171,9 +37928,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 merge train pipeline"
-msgstr ""
-
msgid "This is a private email address %{helpIcon} generated just for you. Anyone who has it can create issues or merge requests as if they were you. If that happens, %{resetLinkStart}reset this token%{resetLinkEnd}."
msgstr ""
@@ -37195,6 +37949,12 @@ msgstr ""
msgid "This is your current session"
msgstr "Это ваша Ñ‚ÐµÐºÑƒÑ‰Ð°Ñ ÑеÑÑиÑ"
+msgid "This issue cannot be assigned to a confidential epic because it is public."
+msgstr ""
+
+msgid "This issue cannot be made public because it belongs to a confidential epic."
+msgstr ""
+
msgid "This issue is confidential and should only be visible to team members with at least Reporter access."
msgstr ""
@@ -37312,6 +38072,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 branch is protected from force push."
+msgstr ""
+
msgid "This merge request cannot be rebased while there are conflicts."
msgstr ""
@@ -37363,9 +38126,15 @@ msgstr ""
msgid "This pipeline was triggered by a schedule."
msgstr ""
+msgid "This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project"
msgstr "Этот проект"
+msgid "This project can be restored until %{date}."
+msgstr ""
+
msgid "This project cannot be %{visibilityLevel} because the visibility of %{openShowLink}%{name}%{closeShowLink} is %{visibility}. To make this project %{visibilityLevel}, you must first %{openEditLink}change the visibility%{closeEditLink} of the parent group."
msgstr ""
@@ -37384,6 +38153,9 @@ msgstr "Ð’ Ñтом проекте нет активных токенов доÑ
msgid "This project is %{strongStart}NOT%{strongEnd} a fork, and has the following:"
msgstr ""
+msgid "This project is %{strongStart}NOT%{strongEnd} a fork. This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -38079,6 +38851,9 @@ msgstr "Задача отмечена как выполненнаÑ."
msgid "Today"
msgstr "СегоднÑ"
+msgid "Todos count"
+msgstr ""
+
msgid "Todos|Are you looking for things to do? Take a look at %{strongStart}%{openIssuesLinkStart}open issues%{openIssuesLinkEnd}%{strongEnd}, contribute to %{strongStart}%{mergeRequestLinkStart}a merge request%{mergeRequestLinkEnd}%{mergeRequestLinkEnd}%{strongEnd}, or mention someone in a comment to automatically assign them a new to-do item."
msgstr ""
@@ -38352,12 +39127,8 @@ msgstr ""
msgid "Trending"
msgstr "ПопулÑрные"
-msgid "Trials|%{planName} Trial %{enDash} %{num} day left"
-msgid_plural "Trials|%{planName} Trial %{enDash} %{num} days left"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-msgstr[3] ""
+msgid "Trials|%{planName} Trial"
+msgstr ""
msgid "Trials|Compare all plans"
msgstr ""
@@ -38365,6 +39136,9 @@ msgstr ""
msgid "Trials|Create a new group to start your GitLab Ultimate trial."
msgstr ""
+msgid "Trials|Day %{daysUsed}/%{duration}"
+msgstr ""
+
msgid "Trials|Go back to GitLab"
msgstr ""
@@ -38614,7 +39388,7 @@ msgstr ""
msgid "URL is triggered when repository is updated"
msgstr ""
-msgid "URL must be percent-encoded if neccessary."
+msgid "URL must be percent-encoded if necessary."
msgstr ""
msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
@@ -38833,6 +39607,9 @@ msgstr "Разблокировать"
msgid "Unlock account"
msgstr ""
+msgid "Unlock more features with GitLab Ultimate"
+msgstr ""
+
msgid "Unlock the discussion"
msgstr "Разблокировать диÑкуÑÑию"
@@ -38896,6 +39673,9 @@ msgstr "Отменена подпиÑка на %{quick_action_target}."
msgid "Unsubscribes from this %{quick_action_target}."
msgstr "ОтменÑет подпиÑку от на %{quick_action_target}."
+msgid "Unsupported sort value."
+msgstr ""
+
msgid "Unsupported todo type passed. Supported todo types are: %{todo_types}"
msgstr ""
@@ -39124,6 +39904,9 @@ msgstr "Текущий период иÑпользованиÑ"
msgid "UsageQuota|File attachments and smaller design graphics."
msgstr ""
+msgid "UsageQuota|From %{storage_enforcement_date} storage limits will apply to this namespace. View and manage your usage in %{strong_start}Group Settings &gt; Usage quotas%{strong_end}."
+msgstr ""
+
msgid "UsageQuota|Git repository."
msgstr ""
@@ -39184,6 +39967,9 @@ msgstr "Хранилище"
msgid "UsageQuota|Storage type"
msgstr ""
+msgid "UsageQuota|Storage used"
+msgstr ""
+
msgid "UsageQuota|This is the total amount of storage used across your projects within this namespace."
msgstr ""
@@ -39379,6 +40165,12 @@ msgstr ""
msgid "Use hashed storage paths for newly created and renamed repositories. Always enabled since 13.0."
msgstr ""
+msgid "Use issue count"
+msgstr ""
+
+msgid "Use issue weight"
+msgstr ""
+
msgid "Use one line per URI"
msgstr ""
@@ -39760,6 +40552,9 @@ msgstr "Ð˜Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ: %{username}"
msgid "Users"
msgstr "Пользователи"
+msgid "Users API rate limit"
+msgstr ""
+
msgid "Users can launch a development environment from a GitLab browser tab when the %{linkStart}Gitpod%{linkEnd} integration is enabled."
msgstr ""
@@ -40089,6 +40884,9 @@ msgstr ""
msgid "View group labels"
msgstr "ПроÑмотр меток группы"
+msgid "View group pipeline usage quota"
+msgstr ""
+
msgid "View incident details at"
msgstr ""
@@ -40243,6 +41041,9 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
+msgid "Vulnerability"
+msgstr ""
+
msgid "Vulnerability Report"
msgstr ""
@@ -40294,6 +41095,9 @@ msgstr ""
msgid "VulnerabilityManagement|An unverified non-confirmed finding"
msgstr ""
+msgid "VulnerabilityManagement|At least one identifier is required"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -40303,12 +41107,24 @@ msgstr ""
msgid "VulnerabilityManagement|Create Jira issue"
msgstr ""
+msgid "VulnerabilityManagement|Enter a name"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE code"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE identifier URL"
+msgstr ""
+
msgid "VulnerabilityManagement|Fetching linked Jira issues"
msgstr ""
msgid "VulnerabilityManagement|Manually add a vulnerability entry into the vulnerability report."
msgstr ""
+msgid "VulnerabilityManagement|Name is a required field"
+msgstr ""
+
msgid "VulnerabilityManagement|Needs triage"
msgstr ""
@@ -40324,6 +41140,18 @@ msgstr ""
msgid "VulnerabilityManagement|Select a method"
msgstr ""
+msgid "VulnerabilityManagement|Select a severity level"
+msgstr ""
+
+msgid "VulnerabilityManagement|Select a status"
+msgstr ""
+
+msgid "VulnerabilityManagement|Severity is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Something went wrong while creating vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -40348,6 +41176,12 @@ msgstr ""
msgid "VulnerabilityManagement|Something went wrong, could not update vulnerability state."
msgstr ""
+msgid "VulnerabilityManagement|Status is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Submit vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Summary, detailed description, steps to reproduce, etc."
msgstr ""
@@ -40543,6 +41377,9 @@ msgstr ""
msgid "WARNING:"
msgstr ""
+msgid "WARNING: This snippet contains hidden files which might be used to mask malicious behavior. Exercise caution if cloning and executing code from this snippet."
+msgstr ""
+
msgid "Wait for the file to load to copy its contents"
msgstr ""
@@ -40762,6 +41599,15 @@ msgstr ""
msgid "Webhooks|An issue is created, updated, closed, or reopened."
msgstr ""
+msgid "Webhooks|Are you sure you want to delete this group hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this project hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this webhook?"
+msgstr ""
+
msgid "Webhooks|Comments"
msgstr ""
@@ -40771,6 +41617,9 @@ msgstr ""
msgid "Webhooks|Confidential issues events"
msgstr ""
+msgid "Webhooks|Delete webhook"
+msgstr ""
+
msgid "Webhooks|Deployment events"
msgstr ""
@@ -41006,6 +41855,9 @@ msgstr ""
msgid "Wiki"
msgstr "Wiki"
+msgid "Wiki page"
+msgstr ""
+
msgid "Wiki page was successfully created."
msgstr ""
@@ -41111,7 +41963,7 @@ msgstr "Удалить Ñтраницу %{pageTitle}?"
msgid "WikiPageConflictMessage|Someone edited the page the same time you did. Please check out %{wikiLinkStart}the page%{wikiLinkEnd} and make sure your changes will not unintentionally remove theirs."
msgstr ""
-msgid "WikiPage|An error occured while trying to render the content editor. Please try again later."
+msgid "WikiPage|An error occurred while trying to render the content editor. Please try again later."
msgstr ""
msgid "WikiPage|Are you sure you want to switch back to the classic editor?"
@@ -41270,6 +42122,18 @@ msgstr ""
msgid "WorkItem|New Task"
msgstr ""
+msgid "WorkItem|Something went wrong when creating a work item. Please try again"
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching the work item. Please try again."
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching work item types. Please try again"
+msgstr ""
+
+msgid "WorkItem|Type"
+msgstr ""
+
msgid "WorkItem|Work Items"
msgstr ""
@@ -41336,7 +42200,10 @@ msgstr ""
msgid "You are about to add %{usersTag} people to the discussion. They will all receive a notification."
msgstr "Ð’Ñ‹ ÑобираетеÑÑŒ добавить учаÑтников %{usersTag} в диÑкуÑÑию. Каждый из них получит уведомление."
-msgid "You are about to permanently delete this project"
+msgid "You are about to delete this forked project containing:"
+msgstr ""
+
+msgid "You are about to delete this project containing:"
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."
@@ -41357,6 +42224,9 @@ msgstr "Ð’Ñ‹ пытаетеÑÑŒ удалить файл, который был Ñ
msgid "You are attempting to update a file that has changed since you started editing it."
msgstr "Ð’Ñ‹ пытаетеÑÑŒ обновить файл, который изменилÑÑ Ñ Ñ‚ÐµÑ… пор, как вы начали его редактировать."
+msgid "You are billed if you exceed this number. %{qsrOverageLinkStart}How does billing work?%{qsrOverageLinkEnd}"
+msgstr ""
+
msgid "You are connected to the Prometheus server, but there is currently no data to display."
msgstr "Ð’Ñ‹ подключены к Ñерверу Prometheus, но в наÑтоÑщее Ð²Ñ€ÐµÐ¼Ñ Ð½ÐµÑ‚ данных Ð´Ð»Ñ Ð¾Ñ‚Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ."
@@ -41414,6 +42284,9 @@ msgstr ""
msgid "You are not authorized to update this scanner profile"
msgstr ""
+msgid "You are not authorized to upload metric images"
+msgstr ""
+
msgid "You are now impersonating %{username}"
msgstr ""
@@ -41567,9 +42440,6 @@ msgstr "Ð’Ñ‹ можете перенеÑти проект только в те Ð
msgid "You can only upload one design when dropping onto an existing design."
msgstr ""
-msgid "You can recover this project until %{date}"
-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 "Ð’Ñ‹ можете разрешить конфликт ÑлиÑниÑ, иÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÑ Ð»Ð¸Ð±Ð¾ интерактивный режим, выбрав кнопки %{use_ours} или %{use_theirs}, либо отредактировав файлы напрÑмую. Примите Ñти Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð² %{branch_name}"
@@ -41618,9 +42488,6 @@ msgstr "Ð’Ñ‹ не можете вноÑить Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð²Ð¾ втори
msgid "You cannot write to this read-only GitLab instance."
msgstr "Ð’Ñ‹ не можете запиÑывать на Ñтот ÑкземплÑÑ€ \"только Ð´Ð»Ñ Ñ‡Ñ‚ÐµÐ½Ð¸Ñ\" клаÑтера GitLab."
-msgid "You can’t %{tag_start}edit%{tag_end} files directly in this project. Fork this project and submit a merge request with your changes."
-msgstr ""
-
msgid "You can’t edit files directly in this project. Fork this project and submit a merge request with your changes."
msgstr ""
@@ -41775,9 +42642,6 @@ 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 set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
@@ -41808,12 +42672,6 @@ msgstr ""
msgid "You must have maintainer access to force delete a lock"
msgstr ""
-msgid "You must have permission to create a project in a group before forking."
-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 "Ð’Ñ‹ должны ввеÑти правильный текущий пароль"
@@ -42219,7 +43077,7 @@ msgstr "Ваши проекты"
msgid "Your public email will be displayed on your public profile."
msgstr ""
-msgid "Your request for access could not be processed: %{error_meesage}"
+msgid "Your request for access could not be processed: %{error_message}"
msgstr ""
msgid "Your request for access has been queued for review."
@@ -42408,6 +43266,9 @@ msgstr ""
msgid "archived:"
msgstr ""
+msgid "artifacts"
+msgstr ""
+
msgid "assign yourself"
msgstr "назначить ÑебÑ"
@@ -42439,6 +43300,9 @@ msgstr[3] ""
msgid "branch name"
msgstr "Ð¸Ð¼Ñ Ð²ÐµÑ‚Ð²Ð¸"
+msgid "builds"
+msgstr ""
+
msgid "by"
msgstr "по"
@@ -42868,6 +43732,9 @@ msgstr ""
msgid "contact with same email already exists in group hierarchy"
msgstr ""
+msgid "container registry images"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -42907,6 +43774,9 @@ msgstr ""
msgid "data"
msgstr "данные"
+msgid "database"
+msgstr ""
+
msgid "date must not be after 9999-12-31"
msgstr ""
@@ -42932,9 +43802,6 @@ msgstr "развернуть"
msgid "design"
msgstr "дизайн"
-msgid "detached"
-msgstr ""
-
msgid "disabled"
msgstr "отключено"
@@ -43191,7 +44058,7 @@ msgstr ""
msgid "is not a valid X509 certificate."
msgstr ""
-msgid "is not allowed for sign-up."
+msgid "is not allowed for sign-up. Please use your regular email address."
msgstr ""
msgid "is not allowed for this group."
@@ -43203,7 +44070,7 @@ msgstr ""
msgid "is not allowed since the group is not top-level group."
msgstr ""
-msgid "is not allowed."
+msgid "is not allowed. Please use your regular email address."
msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
@@ -43290,6 +44157,9 @@ msgstr "меньше минуты"
msgid "level: %{level}"
msgstr "уровень: %{level}"
+msgid "lfs objects"
+msgstr ""
+
msgid "limit of %{project_limit} reached"
msgstr ""
@@ -43515,6 +44385,9 @@ msgstr ""
msgid "mrWidget|Merge blocked: pipeline must succeed. It's waiting for a manual action to continue."
msgstr ""
+msgid "mrWidget|Merge blocked: pipeline must succeed. Push a commit that fixes the failure, or %{linkStart}learn about other solutions.%{linkEnd}"
+msgstr ""
+
msgid "mrWidget|Merge blocked: this merge request must be approved."
msgstr ""
@@ -43632,9 +44505,6 @@ msgstr "Ð˜Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð±Ñ‹Ð»Ð¸ Ñлиты в"
msgid "mrWidget|The changes were not merged into"
msgstr "Ð˜Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð½Ðµ были Ñлиты в"
-msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -43782,9 +44652,6 @@ msgstr ""
msgid "open issue"
msgstr ""
-msgid "opened %{timeAgo}"
-msgstr ""
-
msgid "or"
msgstr "или"
@@ -43798,6 +44665,12 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "packages"
+msgstr ""
+
+msgid "pages"
+msgstr ""
+
msgid "parent"
msgid_plural "parents"
msgstr[0] "владелец"
@@ -43955,6 +44828,9 @@ msgstr[1] "ответа"
msgstr[2] "ответов"
msgstr[3] "ответов"
+msgid "repositories"
+msgstr ""
+
msgid "repository:"
msgstr "репозиторий:"
@@ -44075,12 +44951,18 @@ msgstr ""
msgid "tag name"
msgstr "название тега"
+msgid "terraform states"
+msgstr ""
+
msgid "the correct format."
msgstr ""
msgid "the file"
msgstr ""
+msgid "the following epic(s)"
+msgstr ""
+
msgid "the following issue(s)"
msgstr "Ñледующее(ие) обÑуждение(Ñ)"
@@ -44093,21 +44975,12 @@ msgstr ""
msgid "this document"
msgstr "Ñтот документ"
-msgid "this issue cannot be assigned to a confidential epic since it is public"
-msgstr ""
-
-msgid "this issue cannot be made public since it belongs to a confidential epic"
-msgstr ""
-
msgid "time summary"
msgstr "Ñводка по времени"
msgid "toggle collapse"
msgstr "Ñвернуть/развернуть"
-msgid "train"
-msgstr ""
-
msgid "triggered"
msgstr "запущено"
@@ -44238,3 +45111,6 @@ msgstr ""
msgid "{project}"
msgstr ""
+msgid "✔"
+msgstr ""
+
diff --git a/locale/si_LK/gitlab.po b/locale/si_LK/gitlab.po
index ac845aeffac..e8298febc0c 100644
--- a/locale/si_LK/gitlab.po
+++ b/locale/si_LK/gitlab.po
@@ -14,10 +14,10 @@ msgstr ""
"X-Crowdin-Language: si-LK\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2022-02-02 15:48\n"
+"PO-Revision-Date: 2022-03-01 20:41\n"
msgid " %{start} to %{end}"
-msgstr ""
+msgstr " %{start} සිට %{end}"
msgid " (from %{timeoutSource})"
msgstr ""
@@ -26,7 +26,7 @@ msgid " Collected %{time}"
msgstr ""
msgid " Please sign in."
-msgstr ""
+msgstr " කරුණà·à¶šà¶» ඇතුළු වන්න."
msgid " Target Path"
msgstr ""
@@ -35,19 +35,19 @@ msgid " Try to %{action} this file again."
msgstr ""
msgid " Type"
-msgstr ""
+msgstr " වර්ගය"
msgid " You need to do this before %{grace_period_deadline}."
msgstr ""
msgid " and "
-msgstr ""
+msgstr " සහ "
msgid " and %{sliced}"
-msgstr ""
+msgstr " සහ %{sliced}"
msgid " or "
-msgstr ""
+msgstr " à·„à· "
msgid " or %{emphasisStart}!merge request id%{emphasisEnd}"
msgstr ""
@@ -98,13 +98,13 @@ msgstr[1] ""
msgid "%d Other"
msgid_plural "%d Others"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "වෙනත් %d"
+msgstr[1] "වෙනත් %d"
msgid "%d Package"
msgid_plural "%d Packages"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "ඇසුරුම් %d"
+msgstr[1] "ඇසුරුම් %d"
msgid "%d Scanned URL"
msgid_plural "%d Scanned URLs"
@@ -146,11 +146,16 @@ msgid_plural "%d approvers (you've approved)"
msgstr[0] ""
msgstr[1] ""
-msgid "%d changed file"
-msgid_plural "%d changed files"
+msgid "%d assigned issue"
+msgid_plural "%d assigned issues"
msgstr[0] ""
msgstr[1] ""
+msgid "%d changed file"
+msgid_plural "%d changed files"
+msgstr[0] "වෙනස්කළ ගොනු %d"
+msgstr[1] "වෙනස්කළ ගොනු %d"
+
msgid "%d character remaining"
msgid_plural "%d characters remaining"
msgstr[0] ""
@@ -168,8 +173,8 @@ msgstr[1] ""
msgid "%d comment"
msgid_plural "%d comments"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "අදහස් %d"
+msgstr[1] "අදහස් %d"
msgid "%d comment on this commit"
msgid_plural "%d comments on this commit"
@@ -213,8 +218,8 @@ msgstr[1] ""
msgid "%d day"
msgid_plural "%d days"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "දවස් %d"
+msgstr[1] "දවස් %d"
msgid "%d epic"
msgid_plural "%d epics"
@@ -223,8 +228,8 @@ msgstr[1] ""
msgid "%d error"
msgid_plural "%d errors"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "දà·à·‚ %d"
+msgstr[1] "දà·à·‚ %d"
msgid "%d error found:"
msgid_plural "%d errors found:"
@@ -238,8 +243,8 @@ msgstr[1] ""
msgid "%d failed"
msgid_plural "%d failed"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%d අසමත් විය"
+msgstr[1] "%d අසමත් විය"
msgid "%d failed security job"
msgid_plural "%d failed security jobs"
@@ -248,8 +253,8 @@ msgstr[1] ""
msgid "%d file"
msgid_plural "%d files"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "ගොනු %d"
+msgstr[1] "ගොනු %d"
msgid "%d fixed test result"
msgid_plural "%d fixed test results"
@@ -263,8 +268,8 @@ msgstr[1] ""
msgid "%d group"
msgid_plural "%d groups"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "සමූහ %d"
+msgstr[1] "සමූහ %d"
msgid "%d group selected"
msgid_plural "%d groups selected"
@@ -273,8 +278,8 @@ msgstr[1] ""
msgid "%d hour"
msgid_plural "%d hours"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "පà·à¶º %d"
+msgstr[1] "පà·à¶º %d"
msgid "%d inaccessible merge request"
msgid_plural "%d inaccessible merge requests"
@@ -298,8 +303,8 @@ msgstr[1] ""
msgid "%d layer"
msgid_plural "%d layers"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "ස්ථර %d"
+msgstr[1] "ස්ථර %d"
msgid "%d merge request"
msgid_plural "%d merge requests"
@@ -313,8 +318,8 @@ msgstr[1] ""
msgid "%d merge requests"
msgid_plural "%d merge requests"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "සංයුක්ත ඉල්ලීම් %d"
+msgstr[1] "සංයුක්ත ඉල්ලීම් %d"
msgid "%d metric"
msgid_plural "%d metrics"
@@ -328,13 +333,13 @@ msgstr[1] ""
msgid "%d minute"
msgid_plural "%d minutes"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "විනà·à¶©à·’ %d"
+msgstr[1] "විනà·à¶©à·’ %d"
msgid "%d more comment"
msgid_plural "%d more comments"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "තවත් අදහස් %d"
+msgstr[1] "තවත් අදහස් %d"
msgid "%d open issue"
msgid_plural "%d open issues"
@@ -358,8 +363,8 @@ msgstr[1] ""
msgid "%d project"
msgid_plural "%d projects"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "ව්â€à¶ºà·à¶´à·˜à¶­à·’ %d"
+msgstr[1] "ව්â€à¶ºà·à¶´à·˜à¶­à·’ %d"
msgid "%d project selected"
msgid_plural "%d projects selected"
@@ -373,8 +378,8 @@ msgstr[1] ""
msgid "%d second"
msgid_plural "%d seconds"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "තත්පර %d"
+msgstr[1] "තත්පර %d"
msgid "%d shard selected"
msgid_plural "%d shards selected"
@@ -421,8 +426,23 @@ msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
msgstr[1] ""
-msgid "%d vulnerability updated"
-msgid_plural "%d vulnerabilities updated"
+msgid "%d vulnerability set to confirmed"
+msgid_plural "%d vulnerabilities set to confirmed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to dismissed"
+msgid_plural "%d vulnerabilities set to dismissed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to needs triage"
+msgid_plural "%d vulnerabilities set to needs triage"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to resolved"
+msgid_plural "%d vulnerabilities set to resolved"
msgstr[0] ""
msgstr[1] ""
@@ -458,7 +478,7 @@ msgid "%{author_link} cloned %{original_issue}. You don't have access to the new
msgstr ""
msgid "%{author_link} wrote:"
-msgstr ""
+msgstr "%{author_link} ලිවීය:"
msgid "%{authorsName}'s thread"
msgstr ""
@@ -510,6 +530,12 @@ msgstr[1] ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{completed} of %{total} issues closed"
+msgstr ""
+
+msgid "%{completed} of %{total} weight completed"
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -544,7 +570,7 @@ msgid "%{count} items per page"
msgstr ""
msgid "%{count} more"
-msgstr ""
+msgstr "තවත් %{count}"
msgid "%{count} more assignees"
msgstr ""
@@ -623,7 +649,7 @@ msgid "%{edit_in_new_fork_notice} Try to upload a file again."
msgstr ""
msgid "%{emailPrefix}@company.com"
-msgstr ""
+msgstr "%{emailPrefix}@සමà·à¶œà¶¸.ලංකà·"
msgid "%{extra} more downstream pipelines"
msgstr ""
@@ -647,10 +673,10 @@ msgid "%{global_id} is not a valid ID for %{expected_types}."
msgstr ""
msgid "%{group_name} activity"
-msgstr ""
+msgstr "%{group_name} ක්â€à¶»à·’යà·à¶šà·à¶»à¶šà¶¸"
msgid "%{group_name} group members"
-msgstr ""
+msgstr "%{group_name} සමූහයේ à·ƒà·à¶¸à·à¶¢à·’කයින්"
msgid "%{group_name} is approaching the limit of available seats"
msgstr ""
@@ -668,7 +694,7 @@ msgid "%{hook_type} was scheduled for deletion"
msgstr ""
msgid "%{host} sign-in from new location"
-msgstr ""
+msgstr "%{host} නව ස්ථà·à¶±à¶ºà¶šà·’න් ඇතුළුව ඇත"
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 ""
@@ -737,7 +763,7 @@ msgid "%{label_for_message} unavailable"
msgstr ""
msgid "%{learn_more_link}."
-msgstr ""
+msgstr "%{learn_more_link}."
msgid "%{lessThan} 1 hour"
msgstr ""
@@ -794,7 +820,7 @@ msgid "%{milliseconds}ms"
msgstr ""
msgid "%{model_name} not found"
-msgstr ""
+msgstr "%{model_name} හමු නොවිණි"
msgid "%{mrText}, this issue will be closed automatically."
msgstr ""
@@ -806,7 +832,7 @@ msgid "%{name_with_link} namespace has run out of Shared Runner Pipeline minutes
msgstr ""
msgid "%{name} (Busy)"
-msgstr ""
+msgstr "%{name} (කà·à¶»à·Šà¶ºà¶¶à·„ුලයි)"
msgid "%{name} contained %{resultsString}"
msgstr ""
@@ -837,20 +863,20 @@ msgstr ""
msgid "%{no_of_days} day"
msgid_plural "%{no_of_days} days"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "දවස් %{no_of_days}"
+msgstr[1] "දවස් %{no_of_days}"
msgid "%{number_commits_behind} commits behind %{default_branch}, %{number_commits_ahead} commits ahead"
msgstr ""
msgid "%{oneMonthAgo} - %{today}"
-msgstr ""
+msgstr "%{oneMonthAgo} - %{today}"
msgid "%{oneWeekAgo} - %{today}"
-msgstr ""
+msgstr "%{oneWeekAgo} - %{today}"
msgid "%{oneYearAgo} - %{today}"
-msgstr ""
+msgstr "%{oneYearAgo} - %{today}"
msgid "%{openedEpics} open, %{closedEpics} closed"
msgstr ""
@@ -858,20 +884,23 @@ msgstr ""
msgid "%{openedIssues} open, %{closedIssues} closed"
msgstr ""
+msgid "%{percentage}%% issues closed"
+msgstr ""
+
msgid "%{percentage}%% weight completed"
msgstr ""
msgid "%{percent}%% complete"
-msgstr ""
+msgstr "%{percent}%% සම්පූර්ණයි"
msgid "%{percent}%{percentSymbol} complete"
-msgstr ""
+msgstr "%{percent}%{percentSymbol} සම්පූර්ණයි"
msgid "%{placeholder} is not a valid color scheme"
msgstr ""
msgid "%{placeholder} is not a valid theme"
-msgstr ""
+msgstr "%{placeholder} වලංගු තේමà·à·€à¶šà·Š නොවේ"
msgid "%{policy_link} (notifying after %{elapsed_time} minutes unless %{status})"
msgstr ""
@@ -880,18 +909,18 @@ msgid "%{project_path} is a project that you can use to add a README to your Git
msgstr ""
msgid "%{ref} cannot be added: %{error}"
-msgstr ""
+msgstr "%{ref} එකතු කළ නොහà·à¶šà·’ියි: %{error}"
msgid "%{releases} release"
msgid_plural "%{releases} releases"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "නිකුතු %{releases}"
+msgstr[1] "නිකුතු %{releases}"
msgid "%{remaining_approvals} left"
msgstr ""
msgid "%{reportType} %{status}"
-msgstr ""
+msgstr "%{reportType} %{status}"
msgid "%{reportType} detected %{totalStart}%{total}%{totalEnd} potential %{vulnMessage}"
msgstr ""
@@ -915,15 +944,15 @@ msgid "%{scope} results for term '%{term}'"
msgstr ""
msgid "%{search} %{description} %{scope}"
-msgstr ""
+msgstr "%{search} %{description} %{scope}"
msgid "%{seconds}s"
-msgstr ""
+msgstr "තත්.%{seconds}"
msgid "%{securityScanner} is not enabled for this project. %{linkStart}More information%{linkEnd}"
msgid_plural "%{securityScanner} are not enabled for this project. %{linkStart}More information%{linkEnd}"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "%{securityScanner} සබල කර නà·à¶­. %{linkStart}තව තොරතුරු%{linkEnd}"
+msgstr[1] "%{securityScanner} සබල කර නà·à¶­. %{linkStart}තව තොරතුරු%{linkEnd}"
msgid "%{securityScanner} result is not available because a pipeline has not been run since it was enabled. %{linkStart}Run a pipeline%{linkEnd}"
msgid_plural "%{securityScanner} results are not available because a pipeline has not been run since it was enabled. %{linkStart}Run a pipeline%{linkEnd}"
@@ -934,19 +963,19 @@ msgid "%{service_ping_link_start}What information is shared with GitLab Inc.?%{s
msgstr ""
msgid "%{size} %{unit}"
-msgstr ""
+msgstr "%{size} %{unit}"
msgid "%{size} GiB"
-msgstr ""
+msgstr "ගිබි. %{size}"
msgid "%{size} KiB"
-msgstr ""
+msgstr "කිබි. %{size}"
msgid "%{size} MiB"
-msgstr ""
+msgstr "මෙබි. %{size}"
msgid "%{size} bytes"
-msgstr ""
+msgstr "බයිට %{size}"
msgid "%{sourceBranch} into %{targetBranch}"
msgstr ""
@@ -961,7 +990,7 @@ msgid "%{spanStart}in%{spanEnd} %{errorFn}"
msgstr ""
msgid "%{start} to %{end}"
-msgstr ""
+msgstr "%{start} සිට %{end}"
msgid "%{strongOpen}Warning:%{strongClose} SAML group links can cause GitLab to automatically remove members from groups."
msgstr ""
@@ -995,7 +1024,7 @@ msgstr[0] ""
msgstr[1] ""
msgid "%{strong_start}%{human_size}%{strong_end} Files"
-msgstr ""
+msgstr "ගොනු %{strong_start}%{human_size}%{strong_end}"
msgid "%{strong_start}%{human_size}%{strong_end} Storage"
msgstr ""
@@ -1011,7 +1040,7 @@ msgstr[0] ""
msgstr[1] ""
msgid "%{tabname} changed"
-msgstr ""
+msgstr "%{tabname} වෙනස් කෙරිණි"
msgid "%{tags} tag per image name"
msgstr ""
@@ -1020,7 +1049,7 @@ msgid "%{tags} tags per image name"
msgstr ""
msgid "%{tag}-%{evidence}-%{filename}"
-msgstr ""
+msgstr "%{tag}-%{evidence}-%{filename}"
msgid "%{template_project_id} is unknown or invalid"
msgstr ""
@@ -1038,16 +1067,16 @@ msgid "%{timebox_type} must have a start and due date"
msgstr ""
msgid "%{title} %{operator} %{threshold}"
-msgstr ""
+msgstr "%{title} %{operator} %{threshold}"
msgid "%{title} changes"
msgstr ""
msgid "%{totalCpu} (%{freeSpacePercentage}%{percentSymbol} free)"
-msgstr ""
+msgstr "%{totalCpu} (%{freeSpacePercentage}%{percentSymbol} නොමිලේ)"
msgid "%{totalMemory} (%{freeSpacePercentage}%{percentSymbol} free)"
-msgstr ""
+msgstr "%{totalMemory} (%{freeSpacePercentage}%{percentSymbol} නොමිලේ)"
msgid "%{totalWeight} total weight"
msgstr ""
@@ -1065,7 +1094,7 @@ msgid "%{type} only supports %{name} name"
msgstr ""
msgid "%{userName} (cannot merge)"
-msgstr ""
+msgstr "%{userName} (සංයුක්ත කළ නොහà·à¶šà·’ය)"
msgid "%{userName}'s avatar"
msgstr ""
@@ -1080,7 +1109,7 @@ msgid "%{user_name} (%{user_username}) was removed from the following escalation
msgstr ""
msgid "%{user_name} profile page"
-msgstr ""
+msgstr "%{user_name} පà·à¶­à·’කඩ පිටුව"
msgid "%{username} changed the draft status of merge request %{mr_link}"
msgstr ""
@@ -1175,7 +1204,7 @@ msgid "(Group Managed Account)"
msgstr ""
msgid "(No changes)"
-msgstr ""
+msgstr "(වෙනස්කම් නà·à¶­)"
msgid "(UTC %{offset}) %{timezone}"
msgstr ""
@@ -1193,10 +1222,10 @@ msgid "(leave blank if you don't want to change it)"
msgstr ""
msgid "(max size 15 MB)"
-msgstr ""
+msgstr "(උ. ප්â€à¶»à¶¸à·à¶«à¶º මෙ.බ. 15)"
msgid "(optional)"
-msgstr ""
+msgstr "(වෛකල්පිතයි)"
msgid "(removed)"
msgstr ""
@@ -1210,7 +1239,7 @@ msgstr[0] ""
msgstr[1] ""
msgid "(this user)"
-msgstr ""
+msgstr "(මෙම පරිà·à·“ලකයà·)"
msgid "(we need your current password to confirm your changes)"
msgstr ""
@@ -1219,7 +1248,7 @@ msgid "* All times are in UTC unless specified"
msgstr ""
msgid "*Required"
-msgstr ""
+msgstr "*ඇවà·à·ƒà·’ය"
msgid "+ %{amount} more"
msgstr ""
@@ -1260,10 +1289,10 @@ msgid "+%{tags} more"
msgstr ""
msgid ", and "
-msgstr ""
+msgstr ", සහ "
msgid ", or "
-msgstr ""
+msgstr ", à·„à· "
msgid "- %{policy_name} (notifying after %{elapsed_time} minutes unless %{status})"
msgstr ""
@@ -1284,31 +1313,34 @@ msgstr ""
msgid "- User"
msgid_plural "- Users"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "- පරිà·à·“ලක"
+msgstr[1] "- පරිà·à·“ලකයින්"
+
+msgid "- of - issues closed"
+msgstr ""
msgid "- of - weight completed"
msgstr ""
msgid "- show less"
-msgstr ""
+msgstr "- අඩුවෙන් පෙන්වන්න"
msgid "."
-msgstr ""
+msgstr "."
msgid "/"
-msgstr ""
+msgstr "/"
msgid "0 bytes"
-msgstr ""
+msgstr "බයිට 0"
msgid "0t1DgySidms"
-msgstr ""
+msgstr "0t1DgySidms"
msgid "1 Day"
msgid_plural "%d Days"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "දවස් 1"
+msgstr[1] "දවස් %d"
msgid "1 Issue"
msgid_plural "%d Issues"
@@ -1327,8 +1359,8 @@ msgstr[1] ""
msgid "1 day"
msgid_plural "%d days"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "දවස් 1"
+msgstr[1] "දවස් %d"
msgid "1 day remaining"
msgid_plural "%d days remaining"
@@ -1352,13 +1384,13 @@ msgstr[1] ""
msgid "1 group"
msgid_plural "%d groups"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "සමූහ 1"
+msgstr[1] "සමූහ %d"
msgid "1 hour"
msgid_plural "%d hours"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "පà·à¶º 1"
+msgstr[1] "පà·à¶º %d"
msgid "1 issue selected"
msgid_plural "%d issues selected"
@@ -1377,8 +1409,8 @@ msgstr[1] ""
msgid "1 minute"
msgid_plural "%d minutes"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "විනà·à¶©à·’ 1"
+msgstr[1] "විනà·à¶©à·’ %d"
msgid "1 month remaining"
msgid_plural "%d months remaining"
@@ -1402,13 +1434,13 @@ msgstr[1] ""
msgid "1 role"
msgid_plural "%d roles"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "භූමික෠1"
+msgstr[1] "භූමික෠%d"
msgid "1 user"
msgid_plural "%{num} users"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "පරිà·à·“ලකයින් 1"
+msgstr[1] "පරිà·à·“ලකයින් %{num}"
msgid "1 week remaining"
msgid_plural "%d weeks remaining"
@@ -1427,9 +1459,9 @@ msgid "10-19 contributions"
msgstr ""
msgid "1000+"
-msgstr ""
+msgstr "1000+"
-msgid "192.168.0.0/24"
+msgid "192.168.0.0/24 or 2001:0DB8:1234::/48"
msgstr ""
msgid "1st contribution!"
@@ -1445,16 +1477,16 @@ msgid "2FADevice|Registered On"
msgstr ""
msgid "3 days"
-msgstr ""
+msgstr "දවස් 3"
msgid "3 hours"
-msgstr ""
+msgstr "පà·à¶º 3"
msgid "30 days"
-msgstr ""
+msgstr "දවස් 30"
msgid "30 minutes"
-msgstr ""
+msgstr "විනà·à¶©à·’ 30"
msgid "30+ contributions"
msgstr ""
@@ -1469,16 +1501,16 @@ msgid "404|Make sure the address is correct and the page hasn't moved."
msgstr ""
msgid "404|Page Not Found"
-msgstr ""
+msgstr "පිටුව හමු නොවිණි"
msgid "404|Please contact your GitLab administrator if you think this is a mistake."
msgstr ""
msgid "7 days"
-msgstr ""
+msgstr "දවස් 7"
msgid "8 hours"
-msgstr ""
+msgstr "පà·à¶º 8"
msgid ":%{startLine} to %{endLine}"
msgstr ""
@@ -1529,16 +1561,16 @@ msgid "A deleted user"
msgstr ""
msgid "A different reason"
-msgstr ""
+msgstr "වෙනස් හේතුවක්"
msgid "A file has been changed."
msgstr ""
msgid "A file was not found."
-msgstr ""
+msgstr "ගොනුවක් හමු නොවිණි."
msgid "A file with '%{file_name}' already exists in %{branch} branch"
-msgstr ""
+msgstr "'%{file_name}' සහිත ගොනුවක් දà·à¶±à¶§à¶¸à¶­à·Š %{branch} à·à·à¶›à·à·€ තුළ පවතී"
msgid "A group is a collection of several projects"
msgstr ""
@@ -1610,7 +1642,7 @@ msgid "A sign-in to your account has been made from the following IP address: %{
msgstr ""
msgid "A title is required"
-msgstr ""
+msgstr "සිරà·à·ƒà·’යක් ඇවà·à·ƒà·’ය"
msgid "A user with write access to the source branch selected this option"
msgstr ""
@@ -1628,22 +1660,22 @@ msgid "API Fuzzing Configuration"
msgstr ""
msgid "API Help"
-msgstr ""
+msgstr "යෙ.ක්â€à¶».මු. උදව්"
msgid "API Token"
msgstr ""
msgid "API key"
-msgstr ""
+msgstr "යෙ.ක්â€à¶».මු. යතුර"
msgid "API?"
-msgstr ""
+msgstr "යෙ.ක්â€à¶».මු.?"
msgid "APIFuzzing|$VARIABLE_WITH_PASSWORD"
-msgstr ""
+msgstr "$VARIABLE_WITH_PASSWORD"
msgid "APIFuzzing|$VARIABLE_WITH_USERNAME"
-msgstr ""
+msgstr "$VARIABLE_WITH_USERNAME"
msgid "APIFuzzing|API Fuzzing Configuration"
msgstr ""
@@ -1739,15 +1771,15 @@ msgid "APIFuzzing|folder/openapi.json"
msgstr ""
msgid "AWS Access Key"
-msgstr ""
+msgstr "AWS ප්â€à¶»à·€à·šà· යතුර"
-msgid "AWS Access Key. Only required if not using role instance credentials"
+msgid "AWS Secret Access Key"
msgstr ""
-msgid "AWS Secret Access Key"
+msgid "AWS access key ID (Optional)"
msgstr ""
-msgid "AWS Secret Access Key. Only required if not using role instance credentials"
+msgid "AWS secret access key (Optional)"
msgstr ""
msgid "AWS service error: %{error}"
@@ -1757,13 +1789,13 @@ msgid "Abort"
msgstr ""
msgid "About GitLab"
-msgstr ""
+msgstr "ගිට්ලà·à¶¶à·Š ගà·à¶±"
msgid "About auto deploy"
msgstr ""
msgid "About this feature"
-msgstr ""
+msgstr "මෙම විà·à·šà·‚à·à¶‚ගය ගà·à¶±"
msgid "Abuse Reports"
msgstr ""
@@ -1775,10 +1807,10 @@ msgid "Abuse reports notification email"
msgstr ""
msgid "Accept invitation"
-msgstr ""
+msgstr "ආරà·à¶°à¶±à·à·€ පිළිගන්න"
msgid "Accept terms"
-msgstr ""
+msgstr "නියම පිළිගන්න"
msgid "Acceptable for use in this project"
msgstr ""
@@ -1807,11 +1839,8 @@ msgstr ""
msgid "Access granted"
msgstr ""
-msgid "Access key ID"
-msgstr ""
-
msgid "Access requests"
-msgstr ""
+msgstr "ප්â€à¶»à·€à·šà· ඉල්ලීම්"
msgid "Access to '%{classification_label}' not allowed"
msgstr ""
@@ -1823,19 +1852,19 @@ msgid "AccessDropdown|Deploy Keys"
msgstr ""
msgid "AccessDropdown|Groups"
-msgstr ""
+msgstr "සමූහ"
msgid "AccessDropdown|Roles"
-msgstr ""
+msgstr "භූමිකà·"
msgid "AccessDropdown|Users"
-msgstr ""
+msgstr "පරිà·à·“ලකයින්"
msgid "AccessTokens|Access Tokens"
msgstr ""
msgid "AccessTokens|Are you sure?"
-msgstr ""
+msgstr "ඔබට විà·à·Šà·€à·à·ƒà¶¯?"
msgid "AccessTokens|Are you sure? Any RSS or calendar URLs currently in use will stop working."
msgstr ""
@@ -1853,7 +1882,7 @@ msgid "AccessTokens|Copy static object token"
msgstr ""
msgid "AccessTokens|Created"
-msgstr ""
+msgstr "සෑදිණි"
msgid "AccessTokens|Feed token"
msgstr ""
@@ -1898,31 +1927,31 @@ msgid "AccessTokens|Your static object token authenticates you when repository s
msgstr ""
msgid "AccessibilityReport|Learn more"
-msgstr ""
+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 ""
msgid "Account"
-msgstr ""
+msgstr "ගිණුම"
msgid "Account ID"
-msgstr ""
+msgstr "ගිණුමේ à·„à·à¶³à·”."
msgid "Account and limit"
-msgstr ""
+msgstr "ගිණුම සහ සීමà·à·€"
msgid "Account:"
-msgstr ""
+msgstr "ගිණුම:"
msgid "Account: %{account}"
-msgstr ""
+msgstr "ගිණුම: %{account}"
msgid "AccountValidation|Fix your pipelines by validating your account"
msgstr ""
@@ -1937,7 +1966,7 @@ msgid "AccountValidation|In order to use free CI/CD minutes on shared runners, y
msgstr ""
msgid "AccountValidation|Learn more."
-msgstr ""
+msgstr "තව දà·à¶±à¶œà¶±à·Šà¶±."
msgid "AccountValidation|Looks like you’ll need to validate your account to use free CI/CD minutes"
msgstr ""
@@ -1955,13 +1984,13 @@ msgid "AccountValidation|you may %{unsubscribe_link} at any time."
msgstr ""
msgid "Action"
-msgstr ""
+msgstr "ක්â€à¶»à·’යà·à¶¸à·à¶»à·Šà¶œà¶º"
msgid "Action to take when receiving an alert. %{docsLink}"
msgstr ""
msgid "Actions"
-msgstr ""
+msgstr "ක්â€à¶»à·’යà·à¶¸à·à¶»à·Šà¶œ"
msgid "Activate Service Desk"
msgstr ""
@@ -1982,13 +2011,13 @@ msgid "Active chat names (%{count})"
msgstr ""
msgid "Activity"
-msgstr ""
+msgstr "ක්â€à¶»à·’යà·à¶šà·à¶»à¶šà¶¸"
-msgid "Activity|An error occured while retrieving activity. Reload the page to try again."
+msgid "Activity|An error occurred while retrieving activity. Reload the page to try again."
msgstr ""
msgid "Add"
-msgstr ""
+msgstr "එකතු"
msgid "Add \"%{value}\""
msgstr ""
@@ -2023,6 +2052,9 @@ msgstr ""
msgid "Add a %{type}"
msgstr ""
+msgid "Add a GCP region"
+msgstr ""
+
msgid "Add a GPG key"
msgstr ""
@@ -2074,6 +2106,9 @@ msgstr ""
msgid "Add a numbered list"
msgstr ""
+msgid "Add a related epic"
+msgstr ""
+
msgid "Add a related issue"
msgstr ""
@@ -2087,7 +2122,7 @@ msgid "Add a task list"
msgstr ""
msgid "Add a title..."
-msgstr ""
+msgstr "සිරà·à·ƒà·’යක් එක්කරන්න…"
msgid "Add a to do"
msgstr ""
@@ -2188,6 +2223,9 @@ msgstr ""
msgid "Add or subtract spent time"
msgstr ""
+msgid "Add people"
+msgstr ""
+
msgid "Add previously merged commits"
msgstr ""
@@ -2254,9 +2292,12 @@ msgstr ""
msgid "Add webhook"
msgstr ""
-msgid "Add/remove"
+msgid "Add your team members and others to GitLab."
msgstr ""
+msgid "Add/remove"
+msgstr "එකතු/ඉවත් කරන්න"
+
msgid "AddContextCommits|Add previously merged commits"
msgstr ""
@@ -2282,7 +2323,7 @@ msgid "AddMember|Too many users specified (limit is %{user_limit})"
msgstr ""
msgid "Added"
-msgstr ""
+msgstr "එකතු කෙරිණි"
msgid "Added %{epic_ref} as a child epic."
msgstr ""
@@ -2306,13 +2347,13 @@ msgid "Adding new applications is disabled in your GitLab instance. Please conta
msgstr ""
msgid "Additional Metadata"
-msgstr ""
+msgstr "අතිරේක පà·à¶»-දත්ත"
msgid "Additional minutes"
-msgstr ""
+msgstr "අතිරේක විනà·à¶©à·’"
msgid "Additional minutes:"
-msgstr ""
+msgstr "අතිරේක විනà·à¶©à·’:"
msgid "Additional text"
msgstr ""
@@ -2327,7 +2368,7 @@ msgid "Additional text to show on the sign-in page"
msgstr ""
msgid "Address"
-msgstr ""
+msgstr "ලිපිනය"
msgid "Adds"
msgstr ""
@@ -2339,7 +2380,7 @@ msgid "Adds %{labels} %{label_text}."
msgstr ""
msgid "Adds a Zoom meeting."
-msgstr ""
+msgstr "සූම් රà·à·ƒà·Šà·€à·“මක් එක් කරයි"
msgid "Adds a to do."
msgstr ""
@@ -2357,7 +2398,7 @@ msgid "Adjust your filters/search criteria above. If you believe this may be an
msgstr ""
msgid "Admin"
-msgstr ""
+msgstr "පරිපà·à¶½à¶š"
msgid "Admin Area"
msgstr ""
@@ -2366,13 +2407,13 @@ msgid "Admin Mode"
msgstr ""
msgid "Admin Note"
-msgstr ""
+msgstr "පරිපà·à¶½à¶šà¶œà·š සටහන"
msgid "Admin Notifications"
-msgstr ""
+msgstr "පරිපà·à¶½à¶šà¶œà·š දà·à¶±à·”ම්දීම්"
msgid "Admin Overview"
-msgstr ""
+msgstr "පරිපà·à¶½à¶š දළ විà·à·Šà¶½à·šà·‚ණය"
msgid "Admin Section"
msgstr ""
@@ -2390,7 +2431,7 @@ msgid "Admin navigation"
msgstr ""
msgid "Admin notes"
-msgstr ""
+msgstr "පරිපà·à¶½à¶šà¶œà·š සටහන්"
msgid "AdminArea|%{billable_users_link_start}Learn more%{billable_users_link_end} about what defines a billable user"
msgstr ""
@@ -2405,31 +2446,31 @@ msgid "AdminArea|Billable users"
msgstr ""
msgid "AdminArea|Blocked users"
-msgstr ""
+msgstr "අවහිර කළ පරිà·à·“ලකයින්"
msgid "AdminArea|Bots"
-msgstr ""
+msgstr "ස්වයංක්â€à¶»à¶¸à¶½à·šà¶›"
msgid "AdminArea|Components"
-msgstr ""
+msgstr "සංරචක"
msgid "AdminArea|Developer"
-msgstr ""
+msgstr "සංවර්ධක"
msgid "AdminArea|Features"
-msgstr ""
+msgstr "විà·à·šà·‚à·à¶‚ග"
msgid "AdminArea|Get security updates from GitLab and stay up to date"
msgstr ""
msgid "AdminArea|Groups"
-msgstr ""
+msgstr "සමූහ"
msgid "AdminArea|Guest"
-msgstr ""
+msgstr "අමුත්තà·"
msgid "AdminArea|Included Free in license"
-msgstr ""
+msgstr "බලපත්â€à¶»à¶ºà·™à·„à·’ නොමිලේ ඇතුළත්ය"
msgid "AdminArea|Latest groups"
msgstr ""
@@ -2441,28 +2482,28 @@ msgid "AdminArea|Latest users"
msgstr ""
msgid "AdminArea|Maintainer"
-msgstr ""
+msgstr "නඩත්තුකරු"
msgid "AdminArea|Minimal access"
msgstr ""
msgid "AdminArea|New group"
-msgstr ""
+msgstr "නව සමූහය"
msgid "AdminArea|New project"
-msgstr ""
+msgstr "නව ව්â€à¶ºà·à¶´à·˜à¶­à·’ය"
msgid "AdminArea|New user"
-msgstr ""
+msgstr "නව පරිà·à·“ලක"
msgid "AdminArea|Owner"
-msgstr ""
+msgstr "හිමිකරු"
msgid "AdminArea|Projects"
-msgstr ""
+msgstr "ව්â€à¶ºà·à¶´à·˜à¶­à·’"
msgid "AdminArea|Reporter"
-msgstr ""
+msgstr "à·€à·à¶»à·Šà¶­à·à¶šà¶»à·”"
msgid "AdminArea|Sign up for the GitLab Security Newsletter to get notified for security updates."
msgstr ""
@@ -2483,13 +2524,13 @@ msgid "AdminArea|Stopping jobs failed"
msgstr ""
msgid "AdminArea|Total users"
-msgstr ""
+msgstr "මුළු පරිà·à·“ලකයින්"
msgid "AdminArea|Users"
-msgstr ""
+msgstr "පරිà·à·“ලකයින්"
msgid "AdminArea|Users statistics"
-msgstr ""
+msgstr "පරිà·à·“ලක සංඛ්â€à¶ºà·à¶½à·šà¶›à¶±"
msgid "AdminArea|Users with highest role"
msgstr ""
@@ -2546,7 +2587,7 @@ msgid "AdminSettings|Auto DevOps domain"
msgstr ""
msgid "AdminSettings|Configure Let's Encrypt"
-msgstr ""
+msgstr "ලෙට්'ස් එන්ක්â€à¶»à·’ප්ට් වින්â€à¶ºà·à·ƒà¶œà¶­ කරන්න"
msgid "AdminSettings|Disable feed token"
msgstr ""
@@ -2579,7 +2620,7 @@ msgid "AdminSettings|Keep the latest artifacts for all jobs in the latest succes
msgstr ""
msgid "AdminSettings|Let's Encrypt email"
-msgstr ""
+msgstr "ලෙට්'ස් එන්ක්â€à¶»à·’ප්ට් වි-තà·à¶´à·‘ල"
msgid "AdminSettings|Maximum duration of a session for Git operations when 2FA is enabled."
msgstr ""
@@ -2645,22 +2686,22 @@ msgid "AdminStatistics|Issues"
msgstr ""
msgid "AdminStatistics|Merge requests"
-msgstr ""
+msgstr "සංයුක්ත ඉල්ලීම්"
msgid "AdminStatistics|Milestones"
msgstr ""
msgid "AdminStatistics|Notes"
-msgstr ""
+msgstr "සටහන්"
msgid "AdminStatistics|SSH Keys"
-msgstr ""
+msgstr "SSH යතුරු"
msgid "AdminStatistics|Snippets"
msgstr ""
msgid "AdminUsers|(Admin)"
-msgstr ""
+msgstr "(පරිපà·à¶½à¶š)"
msgid "AdminUsers|(Banned)"
msgstr ""
@@ -2672,7 +2713,7 @@ msgid "AdminUsers|(Deactivated)"
msgstr ""
msgid "AdminUsers|(Internal)"
-msgstr ""
+msgstr "(අභ්â€à¶ºà¶±à·Šà¶­à¶»)"
msgid "AdminUsers|(Locked)"
msgstr ""
@@ -2690,10 +2731,10 @@ msgid "AdminUsers|A user can validate themselves by inputting a credit/debit car
msgstr ""
msgid "AdminUsers|Access"
-msgstr ""
+msgstr "ප්â€à¶»à·€à·šà·à¶º"
msgid "AdminUsers|Access Git repositories"
-msgstr ""
+msgstr "ගිට් කà·à·‚්ඨවලට ප්â€à¶»à·€à·šà·à¶º"
msgid "AdminUsers|Access the API"
msgstr ""
@@ -2711,16 +2752,16 @@ msgid "AdminUsers|Adjust the user cap setting on your instance"
msgstr ""
msgid "AdminUsers|Admin"
-msgstr ""
+msgstr "පරිපà·à¶½à¶š"
msgid "AdminUsers|Administrator"
msgstr ""
msgid "AdminUsers|Admins"
-msgstr ""
+msgstr "පරිපà·à¶½à¶šà¶ºà·’න්"
msgid "AdminUsers|Approve"
-msgstr ""
+msgstr "අනුමත"
msgid "AdminUsers|Approve user %{username}?"
msgstr ""
@@ -2750,7 +2791,7 @@ msgid "AdminUsers|Be added to groups and projects"
msgstr ""
msgid "AdminUsers|Block"
-msgstr ""
+msgstr "අවහිර"
msgid "AdminUsers|Block user"
msgstr ""
@@ -2810,7 +2851,7 @@ msgid "AdminUsers|Export permissions as CSV (max 100,000 users)"
msgstr ""
msgid "AdminUsers|External"
-msgstr ""
+msgstr "බà·à·„ිර"
msgid "AdminUsers|External users cannot see internal or private projects unless access is explicitly granted. Also, external users cannot create projects, groups, or personal snippets."
msgstr ""
@@ -2834,7 +2875,7 @@ msgid "AdminUsers|Issues authored by this user are hidden from other users."
msgstr ""
msgid "AdminUsers|It's you!"
-msgstr ""
+msgstr "ඒ ඔබයි!"
msgid "AdminUsers|Learn more about %{link_start}banned users.%{link_end}"
msgstr ""
@@ -2843,16 +2884,16 @@ msgid "AdminUsers|Locked"
msgstr ""
msgid "AdminUsers|Log in"
-msgstr ""
+msgstr "ඇතුළු වන්න"
msgid "AdminUsers|Manage (accept/reject) pending user sign ups"
msgstr ""
msgid "AdminUsers|New user"
-msgstr ""
+msgstr "නව පරිà·à·“ලක"
msgid "AdminUsers|No users found"
-msgstr ""
+msgstr "පරිà·à·“ලකයින් හමු නොවිණි"
msgid "AdminUsers|Owned groups will be left"
msgstr ""
@@ -2945,7 +2986,7 @@ msgid "AdminUsers|Unlock user %{username}?"
msgstr ""
msgid "AdminUsers|User administration"
-msgstr ""
+msgstr "පරිà·à·“ලක පරිපà·à¶½à¶±à¶º"
msgid "AdminUsers|User is validated and can use free CI minutes on shared runners."
msgstr ""
@@ -2984,7 +3025,7 @@ msgid "AdminUsers|Will be deleted"
msgstr ""
msgid "AdminUsers|Without projects"
-msgstr ""
+msgstr "ව්â€à¶ºà·à¶´à·˜à¶­à·’ නà·à¶­à·’à·€"
msgid "AdminUsers|You are about to permanently delete the user %{username}. Issues, merge requests, and groups linked to them will be transferred to a system-wide \"Ghost-user\". To avoid data loss, consider using the %{strongStart}block user%{strongEnd} feature instead. Once you %{strongStart}Delete user%{strongEnd}, it cannot be undone or recovered."
msgstr ""
@@ -3026,7 +3067,7 @@ msgid "AdminUsers|contact our support team"
msgstr ""
msgid "AdminUsers|docs"
-msgstr ""
+msgstr "ප්â€à¶»à¶½à·šà¶›à¶±"
msgid "AdminUsers|user cap"
msgstr ""
@@ -3038,13 +3079,13 @@ msgid "Admin|Additional users must be reviewed and approved by a system administ
msgstr ""
msgid "Admin|Admin notes"
-msgstr ""
+msgstr "පරිපà·à¶½à¶šà¶œà·š සටහන්"
msgid "Admin|Learn more about quarterly reconciliation"
msgstr ""
msgid "Admin|Note"
-msgstr ""
+msgstr "සටහන"
msgid "Admin|Quarterly reconciliation will occur on %{qrtlyDate}"
msgstr ""
@@ -3062,26 +3103,20 @@ msgid "Admin|Your instance has reached its user cap"
msgstr ""
msgid "Advanced"
-msgstr ""
+msgstr "à·€à·à¶©à·’දුර"
msgid "Advanced Search"
-msgstr ""
+msgstr "à·€à·à¶©à·’දුර සෙවුම"
msgid "Advanced Settings"
-msgstr ""
+msgstr "à·€à·à¶©à·’දුර à·ƒà·à¶šà·ƒà·”ම්"
msgid "Advanced export options"
-msgstr ""
+msgstr "à·€à·à¶©à·’දුර ආයà·à¶­ විකල්ප"
msgid "AdvancedSearch|Reindex required"
msgstr ""
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. Permanently deleting this project will %{strongStart}immediately delete%{strongEnd} its repositories and %{strongStart}all related resources%{strongEnd}, including issues, merge requests etc."
-msgstr ""
-
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. You will lose this project's repository and %{strongStart}all related resources%{strongEnd}, including issues and merge requests."
-msgstr ""
-
msgid "After a successful password update you will be redirected to login screen."
msgstr ""
@@ -3104,14 +3139,17 @@ msgid "After you've reviewed these contribution guidelines, you'll be all set to
msgstr ""
msgid "Akismet"
-msgstr ""
+msgstr "අකිස්මෙට්"
msgid "Akismet API Key"
-msgstr ""
+msgstr "අකිස්මෙට් යෙ.ක්â€à¶».මු. යතුර"
msgid "Akismet helps prevent the creation of spam issues in public projects."
msgstr ""
+msgid "Alert"
+msgstr ""
+
msgid "AlertManagement|Acknowledged"
msgstr ""
@@ -3155,19 +3193,19 @@ msgid "AlertManagement|Display alerts from all your monitoring tools directly wi
msgstr ""
msgid "AlertManagement|Edit"
-msgstr ""
+msgstr "සංස්කරණය"
msgid "AlertManagement|Environment"
-msgstr ""
+msgstr "පරිසරය"
msgid "AlertManagement|Events"
-msgstr ""
+msgstr "සිදුවීම්"
msgid "AlertManagement|Incident"
msgstr ""
msgid "AlertManagement|Key"
-msgstr ""
+msgstr "යතුර"
msgid "AlertManagement|Metrics"
msgstr ""
@@ -3176,7 +3214,7 @@ msgid "AlertManagement|Metrics weren't available in the alerts payload."
msgstr ""
msgid "AlertManagement|More information"
-msgstr ""
+msgstr "තව තොරතුරු"
msgid "AlertManagement|No alert data to display."
msgstr ""
@@ -3188,13 +3226,13 @@ msgid "AlertManagement|No alerts to display."
msgstr ""
msgid "AlertManagement|None"
-msgstr ""
+msgstr "කිසිවක් නà·à¶­"
msgid "AlertManagement|Open"
-msgstr ""
+msgstr "විවෘත"
msgid "AlertManagement|Please try again."
-msgstr ""
+msgstr "යළි උත්සà·à·„ කරන්න."
msgid "AlertManagement|Reported %{when}"
msgstr ""
@@ -3209,16 +3247,16 @@ msgid "AlertManagement|Runbook"
msgstr ""
msgid "AlertManagement|Service"
-msgstr ""
+msgstr "සේවà·à·€"
msgid "AlertManagement|Severity"
msgstr ""
msgid "AlertManagement|Start time"
-msgstr ""
+msgstr "ආරම්භක වේලà·à·€"
msgid "AlertManagement|Status"
-msgstr ""
+msgstr "තත්â€à·€à¶º"
msgid "AlertManagement|Surface alerts in GitLab"
msgstr ""
@@ -3245,13 +3283,13 @@ msgid "AlertManagement|This assignee cannot be assigned to this alert."
msgstr ""
msgid "AlertManagement|Tool"
-msgstr ""
+msgstr "මෙවලම"
msgid "AlertManagement|Triggered"
msgstr ""
msgid "AlertManagement|Value"
-msgstr ""
+msgstr "ඇඟවීම් කළමනà·à¶šà¶»à¶«à¶ºà·€à¶§à·’නà·à¶šà¶¸"
msgid "AlertManagement|View incident"
msgstr ""
@@ -3407,28 +3445,28 @@ msgid "AlertSettings|You can now set up alert endpoints for manually configured
msgstr ""
msgid "AlertSettings|{ \"events\": [{ \"application\": \"Name of application\" }] }"
-msgstr ""
+msgstr "{ \"සිදුවීම්\": [{ \"යෙදුම\": \"යෙදුමේ නම\" }] }"
msgid "Alerts"
msgstr ""
msgid "AlertsIntegrations|Alerts will be created through this integration"
-msgstr ""
+msgstr "ඇඟවීම් මෙම අනුකලනය හරහ෠සෑදෙනු ඇත"
msgid "AlertsIntegrations|Alerts will not be created through this integration"
-msgstr ""
+msgstr "මෙම අනුකලනය හරහ෠ඇඟවීම් නොසෑදෙනු ඇත"
msgid "AlertsIntegrations|If you delete the %{integrationName} integration, alerts are no longer sent from this endpoint. This action cannot be undone."
msgstr ""
msgid "AlertsIntegrations|Integration Name"
-msgstr ""
+msgstr "අනුකලනයේ නම"
msgid "AlertsIntegrations|Integration payload is invalid."
msgstr ""
msgid "AlertsIntegrations|No integrations have been added yet."
-msgstr ""
+msgstr "තවම කිසිදු අනුකලනයක් එක් කර නà·à¶­."
msgid "AlertsIntegrations|The current integration could not be updated. Please try again."
msgstr ""
@@ -3484,9 +3522,6 @@ msgstr ""
msgid "All environments"
msgstr ""
-msgid "All epics"
-msgstr ""
-
msgid "All groups and projects"
msgstr ""
@@ -3509,7 +3544,7 @@ msgid "All paths are relative to the GitLab URL. Do not include %{relative_url_l
msgstr ""
msgid "All projects"
-msgstr ""
+msgstr "සියළුම ව්â€à¶ºà·à¶´à·˜à¶­à·’"
msgid "All projects selected"
msgstr ""
@@ -3521,7 +3556,7 @@ msgid "All users must accept the Terms of Service and Privacy Policy to access G
msgstr ""
msgid "All users must have a name."
-msgstr ""
+msgstr "සියළුම පරිà·à·“ලකයින්ට නමක් තිබිය යුතුය."
msgid "All users with matching cards"
msgstr ""
@@ -3647,7 +3682,7 @@ msgid "Alternatively, you can convert your account to a managed account by the %
msgstr ""
msgid "Amazon EKS"
-msgstr ""
+msgstr "ඇමසන් ඊකේඑස්"
msgid "Amazon EKS integration allows you to provision EKS clusters from GitLab."
msgstr ""
@@ -4114,7 +4149,7 @@ msgid "Analyze your source code for known vulnerabilities."
msgstr ""
msgid "Analyzing file…"
-msgstr ""
+msgstr "ගොනුව විà·à·Šà¶½à·šà·‚ණය වෙමින්…"
msgid "Ancestors"
msgstr ""
@@ -4123,7 +4158,7 @@ msgid "And this registration token:"
msgstr ""
msgid "Anonymous"
-msgstr ""
+msgstr "නිර්නà·à¶¸à·’ක"
msgid "Another action is currently in progress"
msgstr ""
@@ -4162,7 +4197,7 @@ msgid "Any namespace"
msgstr ""
msgid "App ID"
-msgstr ""
+msgstr "යෙදුමේ à·„à·à¶³à·”."
msgid "Appearance"
msgstr ""
@@ -4180,10 +4215,10 @@ msgid "Append the comment with %{tableflip}"
msgstr ""
msgid "Application"
-msgstr ""
+msgstr "යෙදුම"
msgid "Application ID"
-msgstr ""
+msgstr "යෙදුමේ à·„à·à¶³à·”."
msgid "Application limits saved successfully"
msgstr ""
@@ -4223,12 +4258,15 @@ msgstr ""
msgid "ApplicationSettings|Approve users in the pending approval status?"
msgstr ""
-msgid "ApplicationSettings|By making this change, you will automatically approve %d user with the pending approval status."
-msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users with the pending approval status."
+msgid "ApplicationSettings|Approve users who are pending approval?"
+msgstr ""
+
+msgid "ApplicationSettings|By making this change, you will automatically approve %d user who is pending approval."
+msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users who are pending approval."
msgstr[0] ""
msgstr[1] ""
-msgid "ApplicationSettings|By making this change, you will automatically approve all users in pending approval status."
+msgid "ApplicationSettings|By making this change, you will automatically approve all users who are pending approval."
msgstr ""
msgid "ApplicationSettings|Denied domains for sign-ups"
@@ -4307,13 +4345,13 @@ msgid "ApplicationSettings|domain.com"
msgstr ""
msgid "Applications"
-msgstr ""
+msgstr "යෙදුම්"
msgid "Applied"
msgstr ""
msgid "Apply"
-msgstr ""
+msgstr "යොදන්න"
msgid "Apply %d suggestion"
msgid_plural "Apply %d suggestions"
@@ -4342,7 +4380,7 @@ msgid "Applying a template will replace the existing issue description. Any chan
msgstr ""
msgid "Applying command"
-msgstr ""
+msgstr "විධà·à¶±à¶º යෙà·à¶¯à¶¸à·’න්"
msgid "Applying command to %{commandDescription}"
msgstr ""
@@ -4596,10 +4634,10 @@ msgid "Approvers from private group(s) not shown"
msgstr ""
msgid "Apr"
-msgstr ""
+msgstr "බක්"
msgid "April"
-msgstr ""
+msgstr "බක්"
msgid "Architecture not found for OS"
msgstr ""
@@ -4634,10 +4672,10 @@ msgstr ""
msgid "Archiving the project will make it entirely read-only. It is hidden from the dashboard and doesn't show up in searches. %{strong_start}The repository cannot be committed to, and no issues, comments, or other entities can be created.%{strong_end} %{link_start}Learn more.%{link_end}"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to delete this project?"
+msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
+msgid "Are you absolutely sure?"
msgstr ""
msgid "Are you sure that you want to archive this project?"
@@ -4673,12 +4711,18 @@ msgstr ""
msgid "Are you sure you want to delete this SSH key?"
msgstr ""
+msgid "Are you sure you want to delete this comment?"
+msgstr ""
+
msgid "Are you sure you want to delete this deploy key?"
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 label?"
+msgstr ""
+
msgid "Are you sure you want to delete this pipeline schedule?"
msgstr ""
@@ -4694,9 +4738,6 @@ msgstr ""
msgid "Are you sure you want to discard your changes?"
msgstr ""
-msgid "Are you sure you want to erase this build?"
-msgstr ""
-
msgid "Are you sure you want to import %d repository?"
msgid_plural "Are you sure you want to import %d repositories?"
msgstr[0] ""
@@ -4744,6 +4785,9 @@ msgstr ""
msgid "Are you sure you want to remove this list?"
msgstr ""
+msgid "Are you sure you want to remove this nickname?"
+msgstr ""
+
msgid "Are you sure you want to reset the health check token?"
msgstr ""
@@ -4756,10 +4800,10 @@ 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?"
+msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
msgstr ""
-msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
+msgid "Are you sure you want to revoke this project access token? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to stop this environment?"
@@ -4906,9 +4950,6 @@ msgstr ""
msgid "Assigned to %{assignee_name}"
msgstr ""
-msgid "Assigned to %{name}"
-msgstr ""
-
msgid "Assigned to me"
msgstr ""
@@ -4973,6 +5014,9 @@ msgstr[1] ""
msgid "Attaching the file failed."
msgstr ""
+msgid "Attention"
+msgstr ""
+
msgid "Audit Events"
msgstr ""
@@ -5025,10 +5069,10 @@ msgid "AuditLogs|User Events"
msgstr ""
msgid "Aug"
-msgstr ""
+msgstr "නිකිණි"
msgid "August"
-msgstr ""
+msgstr "නිකිණි"
msgid "Authenticate"
msgstr ""
@@ -5135,6 +5179,12 @@ msgstr ""
msgid "Authorized applications (%{size})"
msgstr ""
+msgid "AuthorizedApplication|Are you sure you want to revoke this application?"
+msgstr ""
+
+msgid "AuthorizedApplication|Revoke application"
+msgstr ""
+
msgid "Authors: %{authors}"
msgstr ""
@@ -5616,7 +5666,7 @@ msgid "Billing|No users to display."
msgstr ""
msgid "Billing|Private"
-msgstr ""
+msgstr "පෞද්ගලික"
msgid "Billing|Project invite"
msgstr ""
@@ -5705,7 +5755,7 @@ msgid "BoardNewEpic|Select a group"
msgstr ""
msgid "BoardNewIssue|No matching results"
-msgstr ""
+msgstr "ගà·à·…පෙන ප්â€à¶»à¶­à·’ඵල නà·à¶­"
msgid "BoardNewIssue|Projects"
msgstr ""
@@ -6328,6 +6378,9 @@ msgstr ""
msgid "CICDAnalytics|Shared Runners Usage"
msgstr ""
+msgid "CICDAnalytics|Shared runner pipeline minute duration by month"
+msgstr ""
+
msgid "CICDAnalytics|Shared runner usage"
msgstr ""
@@ -6469,6 +6522,9 @@ msgstr ""
msgid "Can create groups:"
msgstr ""
+msgid "Can not delete primary training"
+msgstr ""
+
msgid "Can't apply as the source branch was deleted."
msgstr ""
@@ -6752,10 +6808,10 @@ msgid "ChangeTypeAction|Revert in branch"
msgstr ""
msgid "ChangeTypeAction|Search branches"
-msgstr ""
+msgstr "à·à·à¶›à· සොයන්න"
msgid "ChangeTypeAction|Search projects"
-msgstr ""
+msgstr "ව්â€à¶ºà·à¶´à·˜à¶­à·’ සොයන්න"
msgid "ChangeTypeAction|Start a %{newMergeRequest} with these changes"
msgstr ""
@@ -6802,9 +6858,6 @@ msgstr ""
msgid "Changing any setting here requires an application restart"
msgstr ""
-msgid "Changing group URL can have unintended side effects."
-msgstr ""
-
msgid "Charts can't be displayed as the request for data has timed out. %{documentationLink}"
msgstr ""
@@ -6892,9 +6945,6 @@ msgstr ""
msgid "Checking branch availability..."
msgstr ""
-msgid "Checking group URL availability..."
-msgstr ""
-
msgid "Checking group path availability..."
msgstr ""
@@ -6975,7 +7025,7 @@ msgid "Checkout|Checkout"
msgstr ""
msgid "Checkout|City"
-msgstr ""
+msgstr "නගරය"
msgid "Checkout|Confirm purchase"
msgstr ""
@@ -6993,7 +7043,7 @@ msgid "Checkout|Country"
msgstr ""
msgid "Checkout|Create a new group"
-msgstr ""
+msgstr "නව සමූහයක් à·ƒà·à¶¯à¶±à·Šà¶±"
msgid "Checkout|Credit card form failed to load. Please try again."
msgstr ""
@@ -7005,7 +7055,7 @@ msgid "Checkout|Edit"
msgstr ""
msgid "Checkout|Enter a number greater than 0"
-msgstr ""
+msgstr "0 ට වඩ෠වà·à¶©à·’ අංකයක් ඇතුල් කරන්න"
msgid "Checkout|Exp %{expirationMonth}/%{expirationYear}"
msgstr ""
@@ -7242,16 +7292,16 @@ msgid "CiStatusText|blocked"
msgstr ""
msgid "CiStatusText|canceled"
-msgstr ""
+msgstr "අවලංගු කෙරිණි"
msgid "CiStatusText|created"
-msgstr ""
+msgstr "සෑදිණි"
msgid "CiStatusText|delayed"
msgstr ""
msgid "CiStatusText|failed"
-msgstr ""
+msgstr "අසමත් විය"
msgid "CiStatusText|manual"
msgstr ""
@@ -7269,7 +7319,7 @@ msgid "CiStatusText|skipped"
msgstr ""
msgid "CiStatusText|waiting"
-msgstr ""
+msgstr "රà·à¶³à·™à¶¸à·’න්"
msgid "CiStatus|running"
msgstr ""
@@ -7278,7 +7328,7 @@ msgid "CiVariables|Cannot use Masked Variable with current value"
msgstr ""
msgid "CiVariables|Environments"
-msgstr ""
+msgstr "පරිසර"
msgid "CiVariables|Input variable key"
msgstr ""
@@ -7287,7 +7337,7 @@ msgid "CiVariables|Input variable value"
msgstr ""
msgid "CiVariables|Key"
-msgstr ""
+msgstr "යතුර"
msgid "CiVariables|Masked"
msgstr ""
@@ -7311,19 +7361,19 @@ msgid "CiVariables|State"
msgstr ""
msgid "CiVariables|Type"
-msgstr ""
+msgstr "වර්ගය"
msgid "CiVariables|Value"
-msgstr ""
+msgstr "අගය"
msgid "CiVariables|Variables"
msgstr ""
msgid "CiVariable|* (All environments)"
-msgstr ""
+msgstr "* (සියළු පරිසර)"
msgid "CiVariable|All environments"
-msgstr ""
+msgstr "සියළු පරිසර"
msgid "CiVariable|Create wildcard"
msgstr ""
@@ -7332,13 +7382,13 @@ msgid "CiVariable|Masked"
msgstr ""
msgid "CiVariable|New environment"
-msgstr ""
+msgstr "නව පරිසරය"
msgid "CiVariable|Protected"
msgstr ""
msgid "CiVariable|Search environments"
-msgstr ""
+msgstr "පරිසර සොයන්න"
msgid "CiVariable|Toggle masked"
msgstr ""
@@ -7388,6 +7438,9 @@ msgstr ""
msgid "Clear recent searches"
msgstr ""
+msgid "Clear repository checks"
+msgstr ""
+
msgid "Clear search"
msgstr ""
@@ -7491,7 +7544,7 @@ msgid "Close %{issueType}"
msgstr ""
msgid "Close %{noteable}"
-msgstr ""
+msgstr "%{noteable} වසන්න"
msgid "Close %{tabname}"
msgstr ""
@@ -7520,9 +7573,6 @@ msgstr ""
msgid "Closed MRs"
msgstr ""
-msgid "Closed epics"
-msgstr ""
-
msgid "Closed issues"
msgstr ""
@@ -7559,13 +7609,13 @@ msgstr ""
msgid "Cluster level"
msgstr ""
-msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
+msgid "Cluster type must be specified for Stages::ClusterEndpointInserter"
msgstr ""
msgid "ClusterAgents|%{name} successfully deleted"
msgstr ""
-msgid "ClusterAgents|%{number} of %{total} Agents"
+msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
@@ -7607,6 +7657,15 @@ msgstr ""
msgid "ClusterAgents|Agent never connected to GitLab"
msgstr ""
+msgid "ClusterAgents|Agent version mismatch"
+msgstr ""
+
+msgid "ClusterAgents|Agent version mismatch and update"
+msgstr ""
+
+msgid "ClusterAgents|Agent version update required"
+msgstr ""
+
msgid "ClusterAgents|All"
msgstr ""
@@ -7626,12 +7685,12 @@ msgid "ClusterAgents|Are you sure you want to delete this agent? You cannot undo
msgstr ""
msgid "ClusterAgents|Certificate"
-msgstr ""
+msgstr "සහතිකය"
msgid "ClusterAgents|Configuration"
msgstr ""
-msgid "ClusterAgents|Connect a cluster through the Agent"
+msgid "ClusterAgents|Connect a cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connect existing cluster"
@@ -7640,13 +7699,13 @@ msgstr ""
msgid "ClusterAgents|Connect with a certificate"
msgstr ""
-msgid "ClusterAgents|Connect with agent"
+msgid "ClusterAgents|Connect with an agent"
msgstr ""
msgid "ClusterAgents|Connect with the GitLab Agent"
msgstr ""
-msgid "ClusterAgents|Connect your cluster through the Agent"
+msgid "ClusterAgents|Connect your cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connected"
@@ -7706,7 +7765,10 @@ msgstr ""
msgid "ClusterAgents|How to register an agent?"
msgstr ""
-msgid "ClusterAgents|Install new Agent"
+msgid "ClusterAgents|How to update an agent?"
+msgstr ""
+
+msgid "ClusterAgents|Install a new agent"
msgstr ""
msgid "ClusterAgents|Last connected %{timeAgo}."
@@ -7733,7 +7795,7 @@ msgstr ""
msgid "ClusterAgents|Never connected"
msgstr ""
-msgid "ClusterAgents|No Agents"
+msgid "ClusterAgents|No agents"
msgstr ""
msgid "ClusterAgents|No clusters connected through cluster certificates"
@@ -7743,13 +7805,13 @@ msgid "ClusterAgents|Not connected"
msgstr ""
msgid "ClusterAgents|Recommended"
-msgstr ""
+msgstr "නිර්දේà·à·’ත"
msgid "ClusterAgents|Recommended installation method"
msgstr ""
msgid "ClusterAgents|Register"
-msgstr ""
+msgstr "ලියà·à¶´à¶¯à·’ංචිය"
msgid "ClusterAgents|Register an agent to generate a token that will be used to install the agent on your cluster in the next step."
msgstr ""
@@ -7773,7 +7835,7 @@ msgid "ClusterAgents|Requires a maintainer or greater role to connect existing c
msgstr ""
msgid "ClusterAgents|Security"
-msgstr ""
+msgstr "ආරක්â€à·‚à·à·€"
msgid "ClusterAgents|See Agent activity updates such as tokens created or revoked and clusters connected or not connected."
msgstr ""
@@ -7793,6 +7855,9 @@ msgstr ""
msgid "ClusterAgents|The agent has not been connected in a long time. There might be a connectivity issue. Last contact was %{timeAgo}."
msgstr ""
+msgid "ClusterAgents|The agent version do not match each other across your cluster's pods. This can happen when a new agent version was just deployed and Kubernetes is shutting down the old pods."
+msgstr ""
+
msgid "ClusterAgents|The recommended installation method includes the token. If you want to follow the advanced installation method provided in the docs, make sure you save the token value before you close this window."
msgstr ""
@@ -7840,6 +7905,9 @@ msgstr ""
msgid "ClusterAgents|You will need to create a token to connect to your agent"
msgstr ""
+msgid "ClusterAgents|Your agent version is out of sync with your GitLab version (v%{version}), which might cause compatibility problems. Update the agent installed on your cluster to the most recent version."
+msgstr ""
+
msgid "ClusterAgents|Your instance doesn't have the %{linkStart}GitLab Agent Server (KAS)%{linkEnd} set up. Ask a GitLab Administrator to install it."
msgstr ""
@@ -8168,10 +8236,10 @@ msgid "ClusterIntegration|Instance type"
msgstr ""
msgid "ClusterIntegration|Integration disabled"
-msgstr ""
+msgstr "අනුකලනය අබලයි"
msgid "ClusterIntegration|Integration enabled"
-msgstr ""
+msgstr "අනුකලනය සබලයි"
msgid "ClusterIntegration|Integrations allow you to use applications installed in your cluster as part of your GitLab workflow."
msgstr ""
@@ -8189,10 +8257,10 @@ msgid "ClusterIntegration|Kubernetes cluster was successfully created."
msgstr ""
msgid "ClusterIntegration|Kubernetes version"
-msgstr ""
+msgstr "කුබර්නෙට්ස් අනුවà·à¶¯à¶º"
msgid "ClusterIntegration|Kubernetes version not found"
-msgstr ""
+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 ""
@@ -8327,16 +8395,16 @@ msgid "ClusterIntegration|Remove Kubernetes cluster integration"
msgstr ""
msgid "ClusterIntegration|Remove integration"
-msgstr ""
+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 ""
@@ -8366,10 +8434,10 @@ msgid "ClusterIntegration|Search networks"
msgstr ""
msgid "ClusterIntegration|Search projects"
-msgstr ""
+msgstr "ව්â€à¶ºà·à¶´à·˜à¶­à·’ සොයන්න"
msgid "ClusterIntegration|Search security groups"
-msgstr ""
+msgstr "ආරක්â€à·‚ණ සමූහ සොයන්න"
msgid "ClusterIntegration|Search subnets"
msgstr ""
@@ -8543,7 +8611,7 @@ msgid "ClusterIntegration|Unable to Connect"
msgstr ""
msgid "ClusterIntegration|Unknown Error"
-msgstr ""
+msgstr "නොදන්න෠දà·à·‚යකි"
msgid "ClusterIntegration|Use the %{linkStart}GitLab Agent%{linkEnd} to safely connect your Kubernetes clusters to GitLab. You can deploy your applications, run your pipelines, use Review Apps, and much more."
msgstr ""
@@ -8716,9 +8784,6 @@ msgstr ""
msgid "Comma-separated list of email addresses."
msgstr ""
-msgid "Comma-separated list of users allowed to exceed the rate limit."
-msgstr ""
-
msgid "Comma-separated, e.g. '1.1.1.1, 2.2.2.0/24'"
msgstr ""
@@ -8920,7 +8985,7 @@ msgid "CompareRevisions|Swap revisions"
msgstr ""
msgid "CompareRevisions|Tags"
-msgstr ""
+msgstr "අනන්â€à¶ºà¶±"
msgid "CompareRevisions|There was an error while loading the branch/tag list. Please try again."
msgstr ""
@@ -9045,6 +9110,12 @@ msgstr ""
msgid "Confidential"
msgstr ""
+msgid "Confidential issue"
+msgstr ""
+
+msgid "Confidential note"
+msgstr ""
+
msgid "Confidentiality"
msgstr ""
@@ -9078,6 +9149,9 @@ msgstr ""
msgid "Configure Dependency Scanning in `.gitlab-ci.yml`, creating this file if it does not already exist"
msgstr ""
+msgid "Configure GitLab"
+msgstr ""
+
msgid "Configure GitLab runners to start using the Web Terminal. %{helpStart}Learn more.%{helpEnd}"
msgstr ""
@@ -9126,6 +9200,15 @@ msgstr ""
msgid "Configure pipelines to deploy web apps, backend services, APIs and static resources to Google Cloud"
msgstr ""
+msgid "Configure region"
+msgstr ""
+
+msgid "Configure region for environment"
+msgstr ""
+
+msgid "Configure regions"
+msgstr ""
+
msgid "Configure repository mirroring."
msgstr ""
@@ -9159,6 +9242,9 @@ msgstr ""
msgid "Configure which lists are shown for anyone who visits this board"
msgstr ""
+msgid "Configure your environments to be deployed to specific geographical regions"
+msgstr ""
+
msgid "Confirm"
msgstr ""
@@ -9859,12 +9945,12 @@ msgid "Corpus Management|Are you sure you want to delete the corpus?"
msgstr ""
msgid "CorpusManagement|Actions"
-msgstr ""
+msgstr "ක්â€à¶»à·’යà·à¶¸à·à¶»à·Šà¶œ"
-msgid "CorpusManagement|Corpus are used in fuzz testing as mutation source to Improve future testing."
+msgid "CorpusManagement|Corpus file"
msgstr ""
-msgid "CorpusManagement|Corpus file"
+msgid "CorpusManagement|Corpus files are used in coverage-guided fuzz testing as seed inputs to improve testing."
msgstr ""
msgid "CorpusManagement|Corpus files must be in *.zip format. Maximum 5 GB"
@@ -9898,10 +9984,10 @@ msgid "CorpusManagement|New upload"
msgstr ""
msgid "CorpusManagement|Not Set"
-msgstr ""
+msgstr "සකස෠නà·à¶­"
msgid "CorpusManagement|Target"
-msgstr ""
+msgstr "ඉලක්කය"
msgid "CorpusManagement|To use this corpus, edit the corresponding YAML file"
msgstr ""
@@ -9918,6 +10004,9 @@ msgstr ""
msgid "Could not apply %{name} command."
msgstr ""
+msgid "Could not apply %{name} command. %{message}."
+msgstr ""
+
msgid "Could not authorize chat nickname. Try again!"
msgstr ""
@@ -10068,6 +10157,9 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
+msgid "Create a group"
+msgstr ""
+
msgid "Create a merge request"
msgstr ""
@@ -10092,6 +10184,9 @@ msgstr ""
msgid "Create a personal access token on your account to pull or push via %{protocol}."
msgstr ""
+msgid "Create a project"
+msgstr ""
+
msgid "Create an account using:"
msgstr ""
@@ -10216,7 +10311,7 @@ msgid "Create requirement"
msgstr ""
msgid "Create service account"
-msgstr ""
+msgstr "සේව෠ගිණුමක් à·ƒà·à¶¯à¶±à·Šà¶±"
msgid "Create snippet"
msgstr ""
@@ -10455,6 +10550,9 @@ msgstr ""
msgid "Creation date"
msgstr ""
+msgid "Creator"
+msgstr ""
+
msgid "Credentials"
msgstr ""
@@ -10467,9 +10565,15 @@ msgstr ""
msgid "CredentialsInventory|Personal Access Tokens"
msgstr ""
+msgid "CredentialsInventory|Project Access Tokens"
+msgstr ""
+
msgid "CredentialsInventory|SSH Keys"
msgstr ""
+msgid "Credit card required to be on file in order to create a pipeline"
+msgstr ""
+
msgid "Credit card:"
msgstr ""
@@ -10483,10 +10587,10 @@ msgid "Crm|Contact has been updated"
msgstr ""
msgid "Crm|Create new contact"
-msgstr ""
+msgstr "නව සබඳතà·à·€à¶ºà¶šà·Š à·ƒà·à¶¯à¶±à·Šà¶±"
msgid "Crm|Create organization"
-msgstr ""
+msgstr "සංවිධà·à¶±à¶ºà¶šà·Š à·ƒà·à¶¯à¶±à·Šà¶±"
msgid "Crm|Customer Relations Contacts"
msgstr ""
@@ -10501,31 +10605,31 @@ msgid "Crm|Description (optional)"
msgstr ""
msgid "Crm|Edit contact"
-msgstr ""
+msgstr "සබඳතà·à·€à¶º සංස්කරණය"
msgid "Crm|Email"
-msgstr ""
+msgstr "වි-තà·à¶´à·‘ල"
msgid "Crm|First name"
-msgstr ""
+msgstr "පළමු නම"
msgid "Crm|Last name"
-msgstr ""
+msgstr "අවසà·à¶± නම"
msgid "Crm|New Organization"
-msgstr ""
+msgstr "නව සංවිධà·à¶±à¶º"
msgid "Crm|New contact"
-msgstr ""
+msgstr "නව සබඳතà·à·€à¶º"
msgid "Crm|New organization"
-msgstr ""
+msgstr "නව සංවිධà·à¶±à¶º"
msgid "Crm|No contacts found"
-msgstr ""
+msgstr "කිසිදු සබඳතà·à·€à¶ºà¶šà·Š හමු නොවිණි"
msgid "Crm|No organizations found"
-msgstr ""
+msgstr "සංවිධà·à¶± කිසිවක් හමු නොවිණි"
msgid "Crm|Organization has been added"
msgstr ""
@@ -10549,10 +10653,10 @@ msgid "CsvParser|Quoted field unterminated"
msgstr ""
msgid "CsvParser|Too few fields"
-msgstr ""
+msgstr "ක්â€à·‚ේත්â€à¶» ඉත෠අඩුයි"
msgid "CsvParser|Too many fields"
-msgstr ""
+msgstr "ක්â€à·‚ේත්â€à¶» බොහà·à¶º"
msgid "CsvParser|Trailing quote on quoted field is malformed"
msgstr ""
@@ -10653,9 +10757,6 @@ msgstr ""
msgid "Customer relations"
msgstr ""
-msgid "Customizable by an administrator."
-msgstr ""
-
msgid "Customizable by owners."
msgstr ""
@@ -10756,13 +10857,13 @@ msgid "CycleAnalyticsEvent|Merge request merged"
msgstr ""
msgid "CycleAnalyticsStage|Code"
-msgstr ""
+msgstr "කේතය"
msgid "CycleAnalyticsStage|Issue"
msgstr ""
msgid "CycleAnalyticsStage|Plan"
-msgstr ""
+msgstr "à·ƒà·à¶½à·ƒà·”ම"
msgid "CycleAnalyticsStage|Review"
msgstr ""
@@ -10785,30 +10886,18 @@ msgstr ""
msgid "CycleAnalytics|%{selectedLabelsCount} selected (%{maxLabels} max)"
msgstr ""
-msgid "CycleAnalytics|%{stageCount} stages selected"
-msgstr ""
-
-msgid "CycleAnalytics|All stages"
-msgstr ""
-
-msgid "CycleAnalytics|Average days to completion"
+msgid "CycleAnalytics|Average time to completion"
msgstr ""
msgid "CycleAnalytics|Date"
msgstr ""
-msgid "CycleAnalytics|Days to completion"
-msgstr ""
-
msgid "CycleAnalytics|Display chart filters"
msgstr ""
msgid "CycleAnalytics|Lead Time for Changes"
msgstr ""
-msgid "CycleAnalytics|No stages selected"
-msgstr ""
-
msgid "CycleAnalytics|Number of tasks"
msgstr ""
@@ -10837,18 +10926,30 @@ msgstr ""
msgid "CycleAnalytics|Showing data for group '%{groupName}' from %{createdAfter} to %{createdBefore}"
msgstr ""
-msgid "CycleAnalytics|Stages"
+msgid "CycleAnalytics|Stage time: %{title}"
msgstr ""
msgid "CycleAnalytics|Tasks by type"
msgstr ""
-msgid "CycleAnalytics|The average time spent in the selected stage for the items that were completed on each date. Data limited to the last 500 items."
+msgid "CycleAnalytics|The average time items spent in this stage. Data limited to items completed within this date range."
msgstr ""
msgid "CycleAnalytics|The given date range is larger than 180 days"
msgstr ""
+msgid "CycleAnalytics|The total time items spent across each value stream stage. Data limited to items completed within this date range."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Stage time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Total time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|Total time"
+msgstr ""
+
msgid "CycleAnalytics|Type of work"
msgstr ""
@@ -10861,9 +10962,6 @@ msgstr ""
msgid "CycleAnalytics|project dropdown filter"
msgstr ""
-msgid "CycleAnalytics|stage dropdown"
-msgstr ""
-
msgid "DAG visualization requires at least 3 dependent jobs."
msgstr ""
@@ -10963,10 +11061,16 @@ msgstr ""
msgid "DastProfiles|AJAX spider"
msgstr ""
+msgid "DastProfiles|API"
+msgstr ""
+
+msgid "DastProfiles|API endpoint URL"
+msgstr ""
+
msgid "DastProfiles|Active"
msgstr ""
-msgid "DastProfiles|Additional request headers (Optional)"
+msgid "DastProfiles|Additional request headers (optional)"
msgstr ""
msgid "DastProfiles|Are you sure you want to delete this profile?"
@@ -10981,6 +11085,9 @@ msgstr ""
msgid "DastProfiles|Branch missing"
msgstr ""
+msgid "DastProfiles|Choose a scan method"
+msgstr ""
+
msgid "DastProfiles|Could not create the scanner profile. Please try again."
msgstr ""
@@ -11050,7 +11157,13 @@ msgstr ""
msgid "DastProfiles|Excluded URLs"
msgstr ""
-msgid "DastProfiles|Excluded URLs (Optional)"
+msgid "DastProfiles|Excluded URLs (optional)"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths (optional)"
msgstr ""
msgid "DastProfiles|Hide debug messages"
@@ -11107,9 +11220,6 @@ msgstr ""
msgid "DastProfiles|Request headers"
msgstr ""
-msgid "DastProfiles|Rest API"
-msgstr ""
-
msgid "DastProfiles|Run the AJAX spider, in addition to the traditional spider, to crawl the target site."
msgstr ""
@@ -11119,6 +11229,9 @@ msgstr ""
msgid "DastProfiles|Save profile"
msgstr ""
+msgid "DastProfiles|Scan method"
+msgstr ""
+
msgid "DastProfiles|Scan mode"
msgstr ""
@@ -11197,12 +11310,24 @@ msgstr ""
msgid "DastProfiles|Website"
msgstr ""
+msgid "DastProfiles|What does each method do?"
+msgstr ""
+
msgid "DastProfiles|You can either choose a passive scan or validate the target site from the site profile management page. %{docsLinkStart}Learn more about site validation.%{docsLinkEnd}"
msgstr ""
msgid "DastProfiles|You cannot run an active scan against an unvalidated site."
msgstr ""
+msgid "DastProfiles|folder/dast_example.har or https://example.com/dast_example.har"
+msgstr ""
+
+msgid "DastProfiles|folder/example.postman_collection.json or https://example.com/"
+msgstr ""
+
+msgid "DastProfiles|folder/openapi.json or https://example.com/openapi.json"
+msgstr ""
+
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
@@ -11310,6 +11435,9 @@ msgstr ""
msgid "DatadogIntegration|API URL"
msgstr ""
+msgid "DatadogIntegration|Custom tags in Datadog. Enter one tag per line in the %{codeOpen}key:value%{codeClose} format. %{linkOpen}How do I use tags?%{linkClose}"
+msgstr ""
+
msgid "DatadogIntegration|Environment"
msgstr ""
@@ -11328,12 +11456,18 @@ msgstr ""
msgid "DatadogIntegration|Tag all data from this GitLab instance in Datadog. Useful when managing several self-managed deployments."
msgstr ""
+msgid "DatadogIntegration|Tags"
+msgstr ""
+
msgid "DatadogIntegration|The Datadog site to send data to. To send data to the EU site, use %{codeOpen}datadoghq.eu%{codeClose}."
msgstr ""
msgid "DatadogIntegration|Trace your GitLab pipelines with Datadog."
msgstr ""
+msgid "DatadogIntegration|have an invalid format"
+msgstr ""
+
msgid "Datasource name not found"
msgstr ""
@@ -11343,9 +11477,6 @@ msgstr ""
msgid "Date merged"
msgstr ""
-msgid "Date picker"
-msgstr ""
-
msgid "Date range"
msgstr ""
@@ -11389,10 +11520,10 @@ msgid "Debug"
msgstr ""
msgid "Dec"
-msgstr ""
+msgstr "උඳු"
msgid "December"
-msgstr ""
+msgstr "උඳුවප්"
msgid "Decline"
msgstr ""
@@ -11499,9 +11630,6 @@ msgstr ""
msgid "Definition"
msgstr ""
-msgid "Delayed Project Deletion (%{adjourned_deletion})"
-msgstr ""
-
msgid "DelayedJobs|Are you sure you want to run %{jobName} immediately? Otherwise this job will run automatically after its timer finishes."
msgstr ""
@@ -11580,10 +11708,10 @@ msgstr ""
msgid "Delete pipeline"
msgstr ""
-msgid "Delete project"
+msgid "Delete pipeline schedule"
msgstr ""
-msgid "Delete project. Are you ABSOLUTELY SURE?"
+msgid "Delete project"
msgstr ""
msgid "Delete row"
@@ -11613,6 +11741,9 @@ msgstr ""
msgid "Delete this epic and all descendants?"
msgstr ""
+msgid "Delete this project"
+msgstr ""
+
msgid "Delete user list"
msgstr ""
@@ -11871,6 +12002,12 @@ msgstr ""
msgid "Deploy to..."
msgstr ""
+msgid "DeployBoards|To see deployment progress for your environments, make sure you are deploying to %{codeStart}$KUBE_NAMESPACE%{codeEnd} and annotating with %{codeStart}app.gitlab.com/app=$CI_PROJECT_PATH_SLUG%{codeEnd} and %{codeStart}app.gitlab.com/env=$CI_ENVIRONMENT_SLUG%{codeEnd}."
+msgstr ""
+
+msgid "DeployBoard|Kubernetes Pods"
+msgstr ""
+
msgid "DeployFreeze|Add a freeze period to prevent unintended releases during a period of time for a given environment. You must update the deployment jobs in %{filename} according to the deploy freezes added here. %{freeze_period_link_start}Learn more.%{freeze_period_link_end}"
msgstr ""
@@ -11955,9 +12092,6 @@ msgstr ""
msgid "DeployTokens|Active Deploy Tokens (%{active_tokens})"
msgstr ""
-msgid "DeployTokens|Allows read and write access to registry images."
-msgstr ""
-
msgid "DeployTokens|Allows read and write access to the package registry."
msgstr ""
@@ -11970,6 +12104,9 @@ msgstr ""
msgid "DeployTokens|Allows read-only access to the repository."
msgstr ""
+msgid "DeployTokens|Allows write access to registry images."
+msgstr ""
+
msgid "DeployTokens|Copy deploy token"
msgstr ""
@@ -12063,12 +12200,57 @@ msgstr ""
msgid "Deploying to AWS is easy with GitLab"
msgstr ""
+msgid "Deployment"
+msgstr ""
+
msgid "Deployment Frequency"
msgstr ""
+msgid "Deployment Target|Project deployment target (optional)"
+msgstr ""
+
+msgid "Deployment Target|Select the deployment target"
+msgstr ""
+
msgid "Deployment frequency"
msgstr ""
+msgid "DeploymentTarget|GitLab Pages"
+msgstr ""
+
+msgid "DeploymentTarget|Heroku"
+msgstr ""
+
+msgid "DeploymentTarget|Infrastructure provider (Terraform, Cloudformation, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Kubernetes (GKE, EKS, OpenShift, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Managed container runtime (Fargate, Cloud Run, DigitalOcean App)"
+msgstr ""
+
+msgid "DeploymentTarget|Mobile app store"
+msgstr ""
+
+msgid "DeploymentTarget|No deployment planned"
+msgstr ""
+
+msgid "DeploymentTarget|Other hosting service"
+msgstr ""
+
+msgid "DeploymentTarget|Registry (package or container)"
+msgstr ""
+
+msgid "DeploymentTarget|Self-managed container runtime (Podman, Docker Swarm, Docker Compose)"
+msgstr ""
+
+msgid "DeploymentTarget|Serverless backend (Lambda, Cloud functions)"
+msgstr ""
+
+msgid "DeploymentTarget|Virtual machine (for example, EC2)"
+msgstr ""
+
msgid "Deployments"
msgstr ""
@@ -12107,6 +12289,9 @@ msgstr ""
msgid "Deployment|This deployment was created using the API"
msgstr ""
+msgid "Deployment|Triggerer"
+msgstr ""
+
msgid "Deployment|Waiting"
msgstr ""
@@ -12134,6 +12319,18 @@ msgstr ""
msgid "Deprecated API rate limits"
msgstr ""
+msgid "Deprecations|Feature deprecation and removal"
+msgstr ""
+
+msgid "Deprecations|For information on a possible replacement %{epicStart} learn more about Opstrace %{epicEnd}."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7 and are %{epicStart} scheduled for removal %{epicEnd} in GitLab 15.0."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7, and are %{removal_link_start} scheduled for removal %{link_end} in GitLab 15.0. For information on a possible replacement, %{opstrace_link_start} learn more about Opstrace %{link_end}."
+msgstr ""
+
msgid "Deprioritize label"
msgstr ""
@@ -12379,10 +12576,10 @@ msgstr ""
msgid "DevopsAdoption|At least one deploy"
msgstr ""
-msgid "DevopsAdoption|At least one issue opened"
+msgid "DevopsAdoption|At least one issue created"
msgstr ""
-msgid "DevopsAdoption|At least one merge request opened"
+msgid "DevopsAdoption|At least one merge request created"
msgstr ""
msgid "DevopsAdoption|At least one pipeline successfully run"
@@ -12583,6 +12780,9 @@ msgstr ""
msgid "Direct member"
msgstr ""
+msgid "Direct members"
+msgstr ""
+
msgid "Direct non-authenticated users to this page."
msgstr ""
@@ -12689,7 +12889,7 @@ msgid "Discussion to reply to cannot be found"
msgstr ""
msgid "Disk Usage"
-msgstr ""
+msgstr "තà·à¶§à·’ය භà·à·€à·’තය"
msgid "Dismiss"
msgstr ""
@@ -12699,6 +12899,9 @@ msgid_plural "Dismiss %d selected vulnerabilities as"
msgstr[0] ""
msgstr[1] ""
+msgid "Dismiss Alert"
+msgstr ""
+
msgid "Dismiss merge request promotion"
msgstr ""
@@ -12726,9 +12929,15 @@ msgstr ""
msgid "Display alerts from all configured monitoring tools."
msgstr ""
+msgid "Display milestones"
+msgstr ""
+
msgid "Display name"
msgstr ""
+msgid "Display progress of child issues"
+msgstr ""
+
msgid "Display rendered file"
msgstr ""
@@ -12748,7 +12957,7 @@ msgid "Do you want to remove this deploy key?"
msgstr ""
msgid "Dockerfile"
-msgstr ""
+msgstr "ඩෝකර්ගොනුව"
msgid "Documentation"
msgstr ""
@@ -12769,10 +12978,10 @@ msgid "Does not delete the source branch."
msgstr ""
msgid "Domain"
-msgstr ""
+msgstr "වසම"
msgid "Domain Name"
-msgstr ""
+msgstr "වසමේ නම"
msgid "Don't have an account yet?"
msgstr ""
@@ -12787,7 +12996,7 @@ msgid "Don't send service data"
msgstr ""
msgid "Don't show again"
-msgstr ""
+msgstr "යළි පෙන්වන්න එපà·"
msgid "Done"
msgstr ""
@@ -12796,7 +13005,7 @@ msgid "Dormant users"
msgstr ""
msgid "Download"
-msgstr ""
+msgstr "බà·à¶œà¶±à·Šà¶±"
msgid "Download %{format}"
msgstr ""
@@ -12820,20 +13029,23 @@ msgid "Download artifacts"
msgstr ""
msgid "Download as"
-msgstr ""
+msgstr "ලෙස බà·à¶œà¶±à·Šà¶±"
msgid "Download codes"
-msgstr ""
+msgstr "කේත බà·à¶œà¶±à·Šà¶±"
msgid "Download evidence JSON"
msgstr ""
msgid "Download export"
-msgstr ""
+msgstr "නිර්යà·à¶­à¶º බà·à¶œà¶±à·Šà¶±"
msgid "Download image"
msgstr ""
+msgid "Download payload"
+msgstr ""
+
msgid "Download raw data (.csv)"
msgstr ""
@@ -12913,22 +13125,22 @@ msgid "Dynamic Application Security Testing (DAST)"
msgstr ""
msgid "E-mail:"
-msgstr ""
+msgstr "වි-තà·à¶´à·‘ල:"
msgid "Each project can also have an issue tracker and a wiki."
msgstr ""
msgid "Edit"
-msgstr ""
+msgstr "සංස්කරණය"
msgid "Edit %{issuable}"
-msgstr ""
+msgstr "%{issuable} සංස්කරණය"
msgid "Edit %{name}"
-msgstr ""
+msgstr "%{name} සංස්කරණය"
msgid "Edit Comment"
-msgstr ""
+msgstr "අදහස සංස්කරණය"
msgid "Edit Deploy Key"
msgstr ""
@@ -12949,7 +13161,7 @@ msgid "Edit Milestone"
msgstr ""
msgid "Edit Password"
-msgstr ""
+msgstr "මුරපදය සංස්කරණය"
msgid "Edit Pipeline Schedule"
msgstr ""
@@ -12958,7 +13170,7 @@ msgid "Edit Release"
msgstr ""
msgid "Edit Requirement"
-msgstr ""
+msgstr "අවà·à·Šâ€à¶ºà¶­à·à·€ සංස්කරණය"
msgid "Edit Slack integration"
msgstr ""
@@ -13011,6 +13223,9 @@ msgstr ""
msgid "Edit in Web IDE"
msgstr ""
+msgid "Edit in pipeline editor"
+msgstr ""
+
msgid "Edit in single-file editor"
msgstr ""
@@ -13033,19 +13248,19 @@ msgid "Edit table"
msgstr ""
msgid "Edit this file only."
-msgstr ""
+msgstr "මෙම ගොනුව පමණක් සංස්කරණය කරන්න."
msgid "Edit this release"
-msgstr ""
+msgstr "මෙම නිකුතුව සංස්කරණය කරන්න"
msgid "Edit title and description"
-msgstr ""
+msgstr "සිරà·à·ƒà·’ය සහ සවිස්තරය සංස්කරණය කරන්න"
msgid "Edit topic: %{topic_name}"
msgstr ""
msgid "Edit user: %{user_name}"
-msgstr ""
+msgstr "පරිà·à·“ලක සංස්කරණය: %{user_name}"
msgid "Edit wiki page"
msgstr ""
@@ -13053,6 +13268,9 @@ msgstr ""
msgid "Edit your most recent comment in a thread (from an empty textarea)"
msgstr ""
+msgid "Edit, lint, and visualize your pipeline."
+msgstr ""
+
msgid "Edited"
msgstr ""
@@ -13111,13 +13329,13 @@ msgid "Eligible users"
msgstr ""
msgid "Email"
-msgstr ""
+msgstr "වි-තà·à¶´à·‘ල"
msgid "Email %{number}"
-msgstr ""
+msgstr "වි-තà·à¶´à·à¶½à·Š %{number}"
msgid "Email Notification"
-msgstr ""
+msgstr "වි-තà·à¶´à·à¶½à·Š දà·à¶±à·”ම්දීම"
msgid "Email a new %{name} to this project"
msgstr ""
@@ -13159,7 +13377,7 @@ msgid "Email:"
msgstr ""
msgid "Email: %{email}"
-msgstr ""
+msgstr "වි-තà·à¶´à·‘ල: %{email}"
msgid "EmailError|It appears that the email is blank. Make sure your reply is at the top of the email, we can't process inline replies."
msgstr ""
@@ -13252,16 +13470,16 @@ msgid "Enable Git pack file bitmap creation"
msgstr ""
msgid "Enable Gitpod"
-msgstr ""
+msgstr "ගිට්පොඩ් සබල කරන්න"
msgid "Enable Gitpod?"
-msgstr ""
+msgstr "ගිට්පොඩ් සබල කරන්නද?"
msgid "Enable Invisible Captcha during sign up"
msgstr ""
msgid "Enable Kroki"
-msgstr ""
+msgstr "ක්â€à¶»à·œà·Šà¶šà·’ සබල කරන්න"
msgid "Enable Mailgun event receiver"
msgstr ""
@@ -13342,7 +13560,7 @@ msgid "Enable feature to choose access level"
msgstr ""
msgid "Enable for this project"
-msgstr ""
+msgstr "මෙම ව්â€à¶ºà·à¶´à·˜à¶­à·’ය සඳහ෠සබල කරන්න"
msgid "Enable group runners"
msgstr ""
@@ -13494,6 +13712,9 @@ msgstr ""
msgid "Enforce two-factor authentication for all user sign-ins."
msgstr ""
+msgid "Enhance security by storing service account keys in secret managers - learn more about %{docLinkStart}secret management with GitLab%{docLinkEnd}"
+msgstr ""
+
msgid "Ensure connectivity is available from the GitLab server to the Prometheus server"
msgstr ""
@@ -13554,6 +13775,9 @@ 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 following to confirm:"
+msgstr ""
+
msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
@@ -14084,9 +14308,6 @@ 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 ""
@@ -14222,6 +14443,9 @@ msgstr ""
msgid "Errors:"
msgstr ""
+msgid "Escalate this incident"
+msgstr ""
+
msgid "Escalation Policies"
msgstr ""
@@ -14234,6 +14458,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy"
+msgstr ""
+
msgid "Escalation policy:"
msgstr ""
@@ -14485,6 +14712,9 @@ msgstr ""
msgid "Existing sign in methods may be removed"
msgstr ""
+msgid "Exit."
+msgstr ""
+
msgid "Expand"
msgstr ""
@@ -14581,6 +14811,9 @@ msgstr ""
msgid "Explore public groups"
msgstr ""
+msgid "Explore public projects"
+msgstr ""
+
msgid "Explore snippets"
msgstr ""
@@ -14742,7 +14975,7 @@ msgid_plural "Failed to archive designs. Please try again."
msgstr[0] ""
msgstr[1] ""
-msgid "Failed to assign a reviewer because no user was found."
+msgid "Failed to assign a reviewer because no user was specified."
msgstr ""
msgid "Failed to assign a user because no user was found."
@@ -14808,10 +15041,10 @@ msgstr ""
msgid "Failed to find import label for Jira import."
msgstr ""
-msgid "Failed to generate export, please try again later."
+msgid "Failed to find users for %{missing}"
msgstr ""
-msgid "Failed to generate report, please try again after sometime"
+msgid "Failed to generate export, please try again later."
msgstr ""
msgid "Failed to get ref."
@@ -14910,6 +15143,9 @@ msgstr ""
msgid "Failed to remove a to-do item for the design."
msgstr ""
+msgid "Failed to remove attention because no user was found."
+msgstr ""
+
msgid "Failed to remove mirror."
msgstr ""
@@ -14922,6 +15158,9 @@ msgstr ""
msgid "Failed to remove user key."
msgstr ""
+msgid "Failed to request attention because no user was found."
+msgstr ""
+
msgid "Failed to reset key. Please try again."
msgstr ""
@@ -15003,6 +15242,9 @@ msgstr ""
msgid "Feature Flags"
msgstr ""
+msgid "Feature deprecation and removal"
+msgstr ""
+
msgid "Feature flag status"
msgstr ""
@@ -15222,10 +15464,10 @@ msgid "FeatureFlag|User List"
msgstr ""
msgid "Feb"
-msgstr ""
+msgstr "නවම්"
msgid "February"
-msgstr ""
+msgstr "නවම්"
msgid "Fetch and check out the branch for this merge request"
msgstr ""
@@ -15468,7 +15710,7 @@ msgid "FogBugz import"
msgstr ""
msgid "Folder/%{name}"
-msgstr ""
+msgstr "බහà·à¶½à·”ම/%{name}"
msgid "Follow"
msgstr ""
@@ -15500,7 +15742,7 @@ msgstr ""
msgid "For each job, re-use the project workspace. If the workspace doesn't exist, use %{code_open}git clone%{code_close}."
msgstr ""
-msgid "For example, the application using the token or the purpose of the token."
+msgid "For example, the application using the token or the purpose of the token. Do not give sensitive information for the name of the token, as it will be visible to all %{resource_type} members."
msgstr ""
msgid "For files larger than this limit, only index the file name. The file content is neither indexed nor searchable."
@@ -15584,9 +15826,6 @@ msgstr ""
msgid "ForkProject|Select a namespace"
msgstr ""
-msgid "ForkProject|Select a namespace to fork the project"
-msgstr ""
-
msgid "ForkProject|The project can be accessed by any logged in user."
msgstr ""
@@ -15683,6 +15922,9 @@ msgstr ""
msgid "Full name"
msgstr ""
+msgid "GCP region configured"
+msgstr ""
+
msgid "GPG Key ID:"
msgstr ""
@@ -15863,6 +16105,9 @@ msgstr ""
msgid "Geo|Failed"
msgstr ""
+msgid "Geo|Filter Geo sites"
+msgstr ""
+
msgid "Geo|Filter by name"
msgstr ""
@@ -16274,6 +16519,12 @@ msgstr ""
msgid "GitLab Issue"
msgstr ""
+msgid "GitLab KAS"
+msgstr ""
+
+msgid "GitLab Memberships CSV Export"
+msgstr ""
+
msgid "GitLab Pages"
msgstr ""
@@ -16322,6 +16573,9 @@ 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 free to use. Many features for larger teams are part of our %{link_start}paid products%{link_end}. You can try Ultimate for free without any obligation or payment details."
+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 ""
@@ -16448,7 +16702,7 @@ msgstr ""
msgid "GitLabPages|When enabled, all attempts to visit your website through HTTP are automatically redirected to HTTPS using a response with status code 301. Requires a valid certificate for all domains. %{docs_link_start}Learn more.%{link_end}"
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. %{docs_link_start}Learn more.%{link_end}"
+msgid "GitLabPages|When using Pages under the general domain of a GitLab instance (%{pages_host}), you cannot use HTTPS with subdomains of subdomains. If your namespace or groupname contains a dot, it does not work. This is a limitation of the HTTP Over TLS protocol. HTTP pages work if you don't redirect HTTP to HTTPS. %{docs_link_start}Learn more.%{link_end}"
msgstr ""
msgid "GitLabPages|With GitLab Pages you can host your static website directly from your GitLab repository. %{docs_link_start}Learn more.%{link_end}"
@@ -16625,9 +16879,6 @@ msgstr ""
msgid "Go to find file"
msgstr ""
-msgid "Go to fork"
-msgstr ""
-
msgid "Go to issue boards"
msgstr ""
@@ -16835,9 +17086,6 @@ msgstr ""
msgid "Group Hooks"
msgstr ""
-msgid "Group ID"
-msgstr ""
-
msgid "Group Owner must have signed in with SAML before enabling Group Managed Accounts"
msgstr ""
@@ -16865,9 +17113,6 @@ msgstr ""
msgid "Group by"
msgstr ""
-msgid "Group description"
-msgstr ""
-
msgid "Group description (optional)"
msgstr ""
@@ -16982,7 +17227,7 @@ msgstr ""
msgid "Group: %{name}"
msgstr ""
-msgid "GroupActivityMetrics|Issues opened"
+msgid "GroupActivityMetrics|Issues created"
msgstr ""
msgid "GroupActivityMetrics|Last 90 days"
@@ -16991,7 +17236,7 @@ msgstr ""
msgid "GroupActivityMetrics|Members added"
msgstr ""
-msgid "GroupActivityMetrics|Merge Requests opened"
+msgid "GroupActivityMetrics|Merge Requests created"
msgstr ""
msgid "GroupActivityMetrics|Recent activity"
@@ -17282,6 +17527,9 @@ msgstr ""
msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
+msgid "GroupSettings|Choose a group path that does not start with a dash or end with a period. It can also contain alphanumeric characters and underscores."
+msgstr ""
+
msgid "GroupSettings|Compliance frameworks"
msgstr ""
@@ -17315,7 +17563,7 @@ msgstr ""
msgid "GroupSettings|If not specified at the group or instance level, the default is %{default_initial_branch_name}. Does not affect existing repositories."
msgstr ""
-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."
+msgid "GroupSettings|If the parent group's visibility is lower than the group's current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility."
msgstr ""
msgid "GroupSettings|New runners registration token has been generated!"
@@ -17432,7 +17680,10 @@ msgstr ""
msgid "Groups and projects"
msgstr ""
-msgid "Groups and subgroups"
+msgid "Groups are a great way to organize projects and people."
+msgstr ""
+
+msgid "Groups are the best way to manage projects and members."
msgstr ""
msgid "Groups to synchronize"
@@ -17543,13 +17794,16 @@ msgstr ""
msgid "GroupsTree|Are you sure you want to leave the \"%{fullName}\" group?"
msgstr ""
-msgid "GroupsTree|Edit group"
+msgid "GroupsTree|Delete"
+msgstr ""
+
+msgid "GroupsTree|Edit"
msgstr ""
msgid "GroupsTree|Failed to leave the group. Please make sure you are not the only owner."
msgstr ""
-msgid "GroupsTree|Leave this group"
+msgid "GroupsTree|Leave group"
msgstr ""
msgid "GroupsTree|Loading groups"
@@ -17561,9 +17815,57 @@ msgstr ""
msgid "GroupsTree|No groups or projects matched your search"
msgstr ""
+msgid "GroupsTree|Options"
+msgstr ""
+
msgid "GroupsTree|Search by name"
msgstr ""
+msgid "Groups|Avatar will be removed. Are you sure?"
+msgstr ""
+
+msgid "Groups|Changing group URL can have unintended side effects."
+msgstr ""
+
+msgid "Groups|Checking group URL availability..."
+msgstr ""
+
+msgid "Groups|Enter a descriptive name for your group."
+msgstr ""
+
+msgid "Groups|Group ID"
+msgstr ""
+
+msgid "Groups|Group URL"
+msgstr ""
+
+msgid "Groups|Group avatar"
+msgstr ""
+
+msgid "Groups|Group description (optional)"
+msgstr ""
+
+msgid "Groups|Group name"
+msgstr ""
+
+msgid "Groups|Group path is available."
+msgstr ""
+
+msgid "Groups|Group path is unavailable. Path has been replaced with a suggested available path."
+msgstr ""
+
+msgid "Groups|Learn more"
+msgstr ""
+
+msgid "Groups|Must start with letter, digit, emoji, or underscore. Can also contain periods, dashes, spaces, and parentheses."
+msgstr ""
+
+msgid "Groups|Remove avatar"
+msgstr ""
+
+msgid "Groups|Save changes"
+msgstr ""
+
msgid "Guideline"
msgstr ""
@@ -17573,6 +17875,9 @@ msgstr ""
msgid "HAR file path or URL"
msgstr ""
+msgid "HTTP Archive (HAR)"
+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 ""
@@ -17923,7 +18228,7 @@ msgid "ID"
msgstr ""
msgid "ID:"
-msgstr ""
+msgstr "à·„à·à¶³à·”.:"
msgid "IDE"
msgstr ""
@@ -17973,6 +18278,9 @@ msgstr ""
msgid "INFO: Your SSH key is expiring soon. Please generate a new key."
msgstr ""
+msgid "IP"
+msgstr ""
+
msgid "IP Address"
msgstr ""
@@ -18009,6 +18317,9 @@ msgstr ""
msgid "IdentityVerification|Verify your identity"
msgstr ""
+msgid "IdentityVerification|You can always verify your account at a later time to create a group."
+msgstr ""
+
msgid "If any indexed field exceeds this limit, it is truncated to this number of characters. The rest of the content is neither indexed nor searchable. This does not apply to repository and wiki indexing. For unlimited characters, set this to 0."
msgstr ""
@@ -18066,6 +18377,9 @@ msgstr ""
msgid "If you add %{codeStart}needs%{codeEnd} to jobs in your pipeline you'll be able to view the %{codeStart}needs%{codeEnd} relationships between jobs in this tab as a %{linkStart}Directed Acyclic Graph (DAG)%{linkEnd}."
msgstr ""
+msgid "If you are added to a project, it will be displayed here."
+msgstr ""
+
msgid "If you did not initiate these sign-in attempts, please reach out to your administrator or enable two-factor authentication (2FA) on your account."
msgstr ""
@@ -18372,12 +18686,24 @@ msgstr ""
msgid "InProductMarketing|3 ways to dive into GitLab CI/CD"
msgstr ""
+msgid "InProductMarketing|A single application eliminates complex integrations, data chokepoints, and toolchain maintenance, resulting in greater productivity and lower cost."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features, build more efficiently, strengthen security and compliance."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features."
+msgstr ""
+
msgid "InProductMarketing|Actually, GitLab makes the team work (better)"
msgstr ""
msgid "InProductMarketing|And finally %{deploy_link} a Python application."
msgstr ""
+msgid "InProductMarketing|And many more..."
+msgstr ""
+
msgid "InProductMarketing|Are your runners ready?"
msgstr ""
@@ -18396,15 +18722,33 @@ msgstr ""
msgid "InProductMarketing|Blog"
msgstr ""
+msgid "InProductMarketing|Break down silos to coordinate seamlessly across development, operations, and security with a consistent experience across the development lifecycle."
+msgstr ""
+
+msgid "InProductMarketing|Burn up/down charts"
+msgstr ""
+
msgid "InProductMarketing|By enabling code owners and required merge approvals the right person will review the right MR. This is a win-win: cleaner code and a more efficient review process."
msgstr ""
msgid "InProductMarketing|Click on the number below that corresponds with your answer — 1 being very difficult, 5 being very easy."
msgstr ""
+msgid "InProductMarketing|Code owners"
+msgstr ""
+
msgid "InProductMarketing|Code owners and required merge approvals are part of the paid tiers of GitLab. You can start a free 30-day trial of GitLab Ultimate and enable these features in less than 5 minutes with no credit card required."
msgstr ""
+msgid "InProductMarketing|Code review analytics"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration across stages in GitLab"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration made easy"
+msgstr ""
+
msgid "InProductMarketing|Create a custom CI runner with just a few clicks"
msgstr ""
@@ -18414,12 +18758,21 @@ msgstr ""
msgid "InProductMarketing|Create a project in GitLab in 5 minutes"
msgstr ""
+msgid "InProductMarketing|Create well-defined workflows by using scoped labels on issues, merge requests, and epics. Labels with the same scope cannot be used together, which prevents conflicts."
+msgstr ""
+
msgid "InProductMarketing|Create your first project!"
msgstr ""
+msgid "InProductMarketing|Define who owns specific files or directories, so the right reviewers are suggested when a merge request introduces changes to those files."
+msgstr ""
+
msgid "InProductMarketing|Deliver Better Products Faster"
msgstr ""
+msgid "InProductMarketing|Dependency scanning"
+msgstr ""
+
msgid "InProductMarketing|Did you know teams that use GitLab are far more efficient?"
msgstr ""
@@ -18429,15 +18782,27 @@ msgstr ""
msgid "InProductMarketing|Dig in and create a project and a repo"
msgstr ""
+msgid "InProductMarketing|Discover Premium & Ultimate"
+msgstr ""
+
+msgid "InProductMarketing|Discover Premium & Ultimate."
+msgstr ""
+
msgid "InProductMarketing|Do you have a minute?"
msgstr ""
msgid "InProductMarketing|Do you have a teammate who would be perfect for this task?"
msgstr ""
+msgid "InProductMarketing|Dynamic application security testing"
+msgstr ""
+
msgid "InProductMarketing|Easy"
msgstr ""
+msgid "InProductMarketing|Epics"
+msgstr ""
+
msgid "InProductMarketing|Expand your DevOps journey with a free GitLab trial"
msgstr ""
@@ -18459,9 +18824,15 @@ msgstr ""
msgid "InProductMarketing|Feel the need for speed?"
msgstr ""
+msgid "InProductMarketing|Find and fix bottlenecks in your code review process by understanding how long open merge requests have been in review."
+msgstr ""
+
msgid "InProductMarketing|Find out how your teams are really doing"
msgstr ""
+msgid "InProductMarketing|Find out if your external libraries are safe. Run dependency scanning jobs that check for known vulnerabilities in your external libraries."
+msgstr ""
+
msgid "InProductMarketing|Follow our steps"
msgstr ""
@@ -18498,6 +18869,9 @@ msgstr ""
msgid "InProductMarketing|GitLab is better with teammates to help out!"
msgstr ""
+msgid "InProductMarketing|GitLab is infrastructure agnostic (supporting GCP, AWS, Azure, OpenShift, VMWare, On Prem, Bare Metal, and more), offering a consistent workflow experience – irrespective of the environment."
+msgstr ""
+
msgid "InProductMarketing|GitLab provides static application security testing (SAST), dynamic application security testing (DAST), container scanning, and dependency scanning to help you deliver secure applications along with license compliance."
msgstr ""
@@ -18588,21 +18962,36 @@ msgstr ""
msgid "InProductMarketing|It's also possible to simply %{external_repo_link} in order to take advantage of GitLab's CI/CD."
msgstr ""
+msgid "InProductMarketing|Keep your code quality high by defining who should approve merge requests and how many approvals are required."
+msgstr ""
+
msgid "InProductMarketing|Launch GitLab CI/CD in 20 minutes or less"
msgstr ""
+msgid "InProductMarketing|Lower cost of development"
+msgstr ""
+
+msgid "InProductMarketing|Make it easier to collaborate on high-level ideas by grouping related issues in an epic."
+msgstr ""
+
msgid "InProductMarketing|Making the switch? It's easier than you think to import your projects into GitLab. Move %{github_link}, or import something %{bitbucket_link}."
msgstr ""
msgid "InProductMarketing|Master the art of importing!"
msgstr ""
+msgid "InProductMarketing|Merge request approval rule"
+msgstr ""
+
msgid "InProductMarketing|Move on to easily creating a Pages website %{ci_template_link}"
msgstr ""
msgid "InProductMarketing|Multiple owners, confusing workstreams? We've got you covered"
msgstr ""
+msgid "InProductMarketing|Multiple required approvers"
+msgstr ""
+
msgid "InProductMarketing|Need an alternative to importing?"
msgstr ""
@@ -18615,18 +19004,33 @@ msgstr ""
msgid "InProductMarketing|Our tool brings all the things together"
msgstr ""
+msgid "InProductMarketing|Protect your web application by using DAST to examine for vulnerabilities in deployed environments."
+msgstr ""
+
msgid "InProductMarketing|Rapid development, simplified"
msgstr ""
msgid "InProductMarketing|Reduce Security & Compliance Risk"
msgstr ""
+msgid "InProductMarketing|Require multiple approvers on a merge request, so you know it's in good shape before it's merged."
+msgstr ""
+
+msgid "InProductMarketing|Roadmaps"
+msgstr ""
+
+msgid "InProductMarketing|Scoped labels"
+msgstr ""
+
msgid "InProductMarketing|Security that's integrated into your development lifecycle"
msgstr ""
msgid "InProductMarketing|Sometimes you're not ready to make a full transition to a new tool. If you're not ready to fully commit, %{mirroring_link} gives you a safe way to try out GitLab in parallel with your current tool."
msgstr ""
+msgid "InProductMarketing|Speed. Efficiency. Trust."
+msgstr ""
+
msgid "InProductMarketing|Spin up an autoscaling runner in GitLab"
msgstr ""
@@ -18636,6 +19040,9 @@ msgstr ""
msgid "InProductMarketing|Start a Self-Managed trial"
msgstr ""
+msgid "InProductMarketing|Start a free trial"
+msgstr ""
+
msgid "InProductMarketing|Start a free trial of GitLab Ultimate – no credit card required"
msgstr ""
@@ -18702,6 +19109,9 @@ msgstr ""
msgid "InProductMarketing|To understand and get the most out of GitLab, start at the beginning and %{project_link}. In GitLab, repositories are part of a project, so after you've created your project you can go ahead and %{repo_link}."
msgstr ""
+msgid "InProductMarketing|Track completed issues in a chart, so you can see how a milestone is progressing at a glance."
+msgstr ""
+
msgid "InProductMarketing|Try GitLab Ultimate for free"
msgstr ""
@@ -18738,6 +19148,9 @@ msgstr ""
msgid "InProductMarketing|Very easy"
msgstr ""
+msgid "InProductMarketing|Visualize your epics and milestones in a timeline."
+msgstr ""
+
msgid "InProductMarketing|Want to host GitLab on your servers?"
msgstr ""
@@ -18759,6 +19172,9 @@ msgstr ""
msgid "InProductMarketing|YouTube"
msgstr ""
+msgid "InProductMarketing|Your software, deployed your way"
+msgstr ""
+
msgid "InProductMarketing|Your teams can be more efficient"
msgstr ""
@@ -18879,9 +19295,18 @@ msgstr ""
msgid "IncidentManagement|No incidents to display."
msgstr ""
+msgid "IncidentManagement|None"
+msgstr ""
+
msgid "IncidentManagement|Open"
msgstr ""
+msgid "IncidentManagement|Page your team with escalation policies"
+msgstr ""
+
+msgid "IncidentManagement|Paged"
+msgstr ""
+
msgid "IncidentManagement|Published"
msgstr ""
@@ -18891,6 +19316,9 @@ msgstr ""
msgid "IncidentManagement|Severity"
msgstr ""
+msgid "IncidentManagement|Status"
+msgstr ""
+
msgid "IncidentManagement|There are no closed incidents"
msgstr ""
@@ -18909,6 +19337,9 @@ msgstr ""
msgid "IncidentManagement|Unpublished"
msgstr ""
+msgid "IncidentManagement|Use escalation policies to automatically page your team when incidents are created."
+msgstr ""
+
msgid "IncidentSettings|Activate \"time to SLA\" countdown timer"
msgstr ""
@@ -18954,7 +19385,10 @@ msgstr ""
msgid "Incidents"
msgstr ""
-msgid "Incidents|Add a URL"
+msgid "Incidents|Add image details"
+msgstr ""
+
+msgid "Incidents|Add text or a link to display with your image. If you don't add either, the file name displays instead."
msgstr ""
msgid "Incidents|Drop or %{linkStart}upload%{linkEnd} a metric screenshot to attach it to the incident"
@@ -18969,10 +19403,10 @@ msgstr ""
msgid "Incidents|There was an issue loading metric images."
msgstr ""
-msgid "Incidents|There was an issue uploading your image."
+msgid "Incidents|There was an issue updating your image."
msgstr ""
-msgid "Incidents|You can optionally add a URL to link users to the original graph."
+msgid "Incidents|There was an issue uploading your image."
msgstr ""
msgid "Incident|Alert details"
@@ -18981,9 +19415,18 @@ msgstr ""
msgid "Incident|Are you sure you wish to delete this image?"
msgstr ""
+msgid "Incident|Delete image"
+msgstr ""
+
msgid "Incident|Deleting %{filename}"
msgstr ""
+msgid "Incident|Edit image text or link"
+msgstr ""
+
+msgid "Incident|Editing %{filename}"
+msgstr ""
+
msgid "Incident|Metrics"
msgstr ""
@@ -19253,12 +19696,18 @@ msgstr ""
msgid "Integrations|Branches for which notifications are to be sent"
msgstr ""
+msgid "Integrations|Clear if using a self-signed certificate."
+msgstr ""
+
msgid "Integrations|Comment detail:"
msgstr ""
msgid "Integrations|Comment settings:"
msgstr ""
+msgid "Integrations|Connection details"
+msgstr ""
+
msgid "Integrations|Connection failed. Please check your settings."
msgstr ""
@@ -19283,6 +19732,9 @@ msgstr ""
msgid "Integrations|Enable GitLab.com slash commands in a Slack workspace."
msgstr ""
+msgid "Integrations|Enable SSL verification"
+msgstr ""
+
msgid "Integrations|Enable comments"
msgstr ""
@@ -19361,6 +19813,9 @@ msgstr ""
msgid "Integrations|Return to GitLab for Jira"
msgstr ""
+msgid "Integrations|SSL verification"
+msgstr ""
+
msgid "Integrations|Save settings?"
msgstr ""
@@ -19406,9 +19861,6 @@ msgstr ""
msgid "Integrations|Use default settings"
msgstr ""
-msgid "Integrations|When you mention a Jira issue in a commit or merge request, GitLab creates a remote link and comment (if enabled)."
-msgstr ""
-
msgid "Integrations|You can now close this window and return to the GitLab for Jira application."
msgstr ""
@@ -19433,9 +19885,6 @@ msgstr ""
msgid "Integrations|can't exceed %{recipients_limit}"
msgstr ""
-msgid "Interactive developer security education."
-msgstr ""
-
msgid "Interactive mode"
msgstr ""
@@ -19925,6 +20374,9 @@ msgstr ""
msgid "IssueAnalytics|Assignees"
msgstr ""
+msgid "IssueAnalytics|Created by"
+msgstr ""
+
msgid "IssueAnalytics|Due date"
msgstr ""
@@ -19937,9 +20389,6 @@ msgstr ""
msgid "IssueAnalytics|Milestone"
msgstr ""
-msgid "IssueAnalytics|Opened by"
-msgstr ""
-
msgid "IssueAnalytics|Status"
msgstr ""
@@ -20063,10 +20512,10 @@ msgstr ""
msgid "IssuesAnalytics|Avg/Month:"
msgstr ""
-msgid "IssuesAnalytics|Issues opened"
+msgid "IssuesAnalytics|Issues created"
msgstr ""
-msgid "IssuesAnalytics|Issues opened per month"
+msgid "IssuesAnalytics|Issues created per month"
msgstr ""
msgid "IssuesAnalytics|Last 12 months"
@@ -20093,6 +20542,9 @@ msgstr ""
msgid "It looks like you have some draft commits in this branch."
msgstr ""
+msgid "It looks like you're attempting to activate your subscription. Use %{a_start}the Subscription page%{a_end} instead."
+msgstr ""
+
msgid "It may be several days before you see feature usage data."
msgstr ""
@@ -20271,10 +20723,10 @@ msgid "Jaeger URL"
msgstr ""
msgid "Jan"
-msgstr ""
+msgstr "දුරුතු"
msgid "January"
-msgstr ""
+msgstr "දුරුතු"
msgid "Japanese language support using"
msgstr ""
@@ -20321,6 +20773,9 @@ msgstr ""
msgid "JiraConnect|You can now close this window and return to Jira."
msgstr ""
+msgid "JiraConnect|You don't have permission to create branches for this project. Select a different project or contact the project owner for access. %{linkStart}Learn more.%{linkEnd}"
+msgstr ""
+
msgid "JiraRequest|A connection error occurred while connecting to Jira. Try your request again."
msgstr ""
@@ -20369,13 +20824,13 @@ msgstr ""
msgid "JiraService|Define the type of Jira issue to create from a vulnerability."
msgstr ""
-msgid "JiraService|Displaying Jira issues while leaving the GitLab issue functionality enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
+msgid "JiraService|Displaying Jira issues while leaving GitLab issues also enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
msgstr ""
-msgid "JiraService|Enable Jira issues"
+msgid "JiraService|Enable Jira issue creation from vulnerabilities"
msgstr ""
-msgid "JiraService|Enable Jira issues creation from vulnerabilities"
+msgid "JiraService|Enable Jira issues"
msgstr ""
msgid "JiraService|Enable Jira transitions"
@@ -20492,16 +20947,19 @@ msgstr ""
msgid "JiraService|View Jira issues in GitLab"
msgstr ""
-msgid "JiraService|Warning: All GitLab users that have access to this GitLab project are able to view all issues from the Jira project specified below."
+msgid "JiraService|Warning: All GitLab users with access to this GitLab project can view all issues from the Jira project you select."
msgstr ""
msgid "JiraService|Web URL"
msgstr ""
-msgid "JiraService|Work on Jira issues without leaving GitLab. Adds a Jira menu to access your list of Jira issues and view any issue as read-only."
+msgid "JiraService|When a Jira issue is mentioned in a commit or merge request, a remote link and comment (if enabled) will be created."
msgstr ""
-msgid "JiraService|You need to configure Jira before enabling this integration. For more details, read the %{jira_doc_link_start}Jira integration documentation%{link_end}."
+msgid "JiraService|Work on Jira issues without leaving GitLab. Add a Jira menu to access a read-only list of your Jira issues."
+msgstr ""
+
+msgid "JiraService|You must configure Jira before enabling this integration. %{jira_doc_link_start}Learn more.%{link_end}"
msgstr ""
msgid "Job"
@@ -20513,9 +20971,6 @@ msgstr ""
msgid "Job Failed #%{build_id}"
msgstr ""
-msgid "Job ID"
-msgstr ""
-
msgid "Job artifact"
msgstr ""
@@ -20582,9 +21037,27 @@ msgstr ""
msgid "Jobs|You're about to retry a job that failed because it attempted to deploy code that is older than the latest deployment. Retrying this job could result in overwriting the environment with the older source code."
msgstr ""
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source} into %{target}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{ref}"
+msgstr ""
+
+msgid "Job|Are you sure you want to erase this job log and artifacts?"
+msgstr ""
+
msgid "Job|Browse"
msgstr ""
+msgid "Job|Cancel"
+msgstr ""
+
msgid "Job|Complete Raw"
msgstr ""
@@ -20594,6 +21067,9 @@ msgstr ""
msgid "Job|Erase job log and artifacts"
msgstr ""
+msgid "Job|Finished at"
+msgstr ""
+
msgid "Job|Job artifacts"
msgstr ""
@@ -20606,7 +21082,7 @@ msgstr ""
msgid "Job|Keep"
msgstr ""
-msgid "Job|Pipeline"
+msgid "Job|Retry"
msgstr ""
msgid "Job|Scroll to bottom"
@@ -20618,6 +21094,9 @@ msgstr ""
msgid "Job|Show complete raw"
msgstr ""
+msgid "Job|Status"
+msgstr ""
+
msgid "Job|The artifacts were removed"
msgstr ""
@@ -20645,21 +21124,12 @@ msgstr ""
msgid "Job|delayed"
msgstr ""
-msgid "Job|for"
-msgstr ""
-
-msgid "Job|into"
-msgstr ""
-
msgid "Job|manual"
msgstr ""
msgid "Job|triggered"
msgstr ""
-msgid "Job|with"
-msgstr ""
-
msgid "Join Zoom meeting"
msgstr ""
@@ -20679,19 +21149,19 @@ msgid "Joined projects (%{projects_count})"
msgstr ""
msgid "Jul"
-msgstr ""
+msgstr "ඇසළ"
msgid "July"
-msgstr ""
+msgstr "ඇසළ"
msgid "Jump to next unresolved thread"
msgstr ""
msgid "Jun"
-msgstr ""
+msgstr "පොසොන්"
msgid "June"
-msgstr ""
+msgstr "පොසොන්"
msgid "Just me"
msgstr ""
@@ -20762,9 +21232,6 @@ msgstr ""
msgid "Ki"
msgstr ""
-msgid "Kontra"
-msgstr ""
-
msgid "Kroki"
msgstr ""
@@ -21088,6 +21555,9 @@ msgstr ""
msgid "Learn more about Auto DevOps"
msgstr ""
+msgid "Learn more about GitLab"
+msgstr ""
+
msgid "Learn more about Needs relationships"
msgstr ""
@@ -21415,9 +21885,18 @@ msgstr ""
msgid "Licenses|Displays licenses detected in the project, based on the %{linkStart}latest successful%{linkEnd} scan"
msgstr ""
+msgid "Licenses|Drag your license file here or %{linkStart}click to upload%{linkEnd}."
+msgstr ""
+
+msgid "Licenses|Drop your license file to start the upload."
+msgstr ""
+
msgid "Licenses|Error fetching the license list. Please check your network connection and try again."
msgstr ""
+msgid "Licenses|Error: You are trying to upload something other than a file"
+msgstr ""
+
msgid "Licenses|License Compliance"
msgstr ""
@@ -21436,6 +21915,9 @@ msgstr ""
msgid "Licenses|Specified policies in this project"
msgstr ""
+msgid "Licenses|The file could not be uploaded."
+msgstr ""
+
msgid "Licenses|The license list details information about the licenses used within your project."
msgstr ""
@@ -21469,11 +21951,6 @@ msgstr ""
msgid "Limit the size of Sidekiq jobs stored in Redis."
msgstr ""
-msgid "Limited to showing %d event at most"
-msgid_plural "Limited to showing %d events at most"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Limiting mode"
msgstr ""
@@ -21483,6 +21960,9 @@ msgstr ""
msgid "Link"
msgstr ""
+msgid "Link (optional)"
+msgstr ""
+
msgid "Link Prometheus monitoring to GitLab."
msgstr ""
@@ -21519,6 +21999,9 @@ msgstr ""
msgid "Linked emails (%{email_count})"
msgstr ""
+msgid "Linked epics"
+msgstr ""
+
msgid "Linked issues"
msgstr ""
@@ -21546,6 +22029,15 @@ msgstr ""
msgid "List of all merge commits"
msgstr ""
+msgid "List of environments for this project"
+msgstr ""
+
+msgid "List of suitable GCP locations"
+msgstr ""
+
+msgid "List of users allowed to exceed the rate limit."
+msgstr ""
+
msgid "List options"
msgstr ""
@@ -21765,6 +22257,9 @@ msgstr ""
msgid "Maintenance mode"
msgstr ""
+msgid "Make adjustments to how your GitLab instance is set up."
+msgstr ""
+
msgid "Make and review changes in the browser with the Web IDE"
msgstr ""
@@ -21853,10 +22348,10 @@ msgid "Map a FogBugz account ID to a GitLab user"
msgstr ""
msgid "Mar"
-msgstr ""
+msgstr "මà·à¶¯à·’න්"
msgid "March"
-msgstr ""
+msgstr "මà·à¶¯à·’න්"
msgid "Mark as done"
msgstr ""
@@ -21909,6 +22404,12 @@ msgstr ""
msgid "MarkdownEditor|Add italic text (%{modifier_key}I)"
msgstr ""
+msgid "MarkdownEditor|Add strikethrough text (%{modifierKey}⇧X)"
+msgstr ""
+
+msgid "MarkdownEditor|Add strikethrough text (%{modifier_key}⇧X)"
+msgstr ""
+
msgid "Marked For Deletion At - %{deletion_time}"
msgstr ""
@@ -22170,6 +22671,9 @@ msgstr ""
msgid "Maximum push size (MB)"
msgstr ""
+msgid "Maximum requests per 10 minutes per user"
+msgstr ""
+
msgid "Maximum requests per minute"
msgstr ""
@@ -22213,7 +22717,7 @@ msgid "Maximum unauthenticated web requests per rate limit period per IP"
msgstr ""
msgid "May"
-msgstr ""
+msgstr "වෙසක්"
msgid "Mean time to merge"
msgstr ""
@@ -22260,6 +22764,19 @@ msgstr ""
msgid "Members of a group may only view projects they have permission to access"
msgstr ""
+msgid "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seat in use and will be billed for the overage."
+msgid_plural "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seats in use and will be billed for the overage."
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "MembersOverage|You are about to incur additional charges"
+msgstr ""
+
+msgid "MembersOverage|Your subscription includes %d seat."
+msgid_plural "MembersOverage|Your subscription includes %d seats."
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Membership"
msgstr ""
@@ -22464,9 +22981,6 @@ msgstr ""
msgid "Merge request not merged"
msgstr ""
-msgid "Merge request pipelines 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 merge request pipelines."
-msgstr ""
-
msgid "Merge request reports"
msgstr ""
@@ -22563,13 +23077,13 @@ msgstr ""
msgid "MergeRequests|Create issue to resolve thread"
msgstr ""
-msgid "MergeRequests|Failed to squash. Should be done manually."
+msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Saving the comment failed"
+msgid "MergeRequests|Squashing failed: Squash the commits locally, resolve any conflicts, then push the branch."
msgstr ""
-msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
+msgid "MergeRequests|Squashing not allowed: This project doesn't allow you to squash commits when merging."
msgstr ""
msgid "MergeRequests|Thread stays resolved"
@@ -23410,6 +23924,18 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "MrList|Assigned to %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from assignee %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from reviewer %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Review requested from %{name}, go to their profile."
+msgstr ""
+
msgid "Multi-project"
msgstr ""
@@ -23443,7 +23969,7 @@ msgstr ""
msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "My Awesome Group"
+msgid "My awesome group"
msgstr ""
msgid "My company or team"
@@ -23456,7 +23982,7 @@ msgid "My-Reaction"
msgstr ""
msgid "N/A"
-msgstr ""
+msgstr "අ/නොවේ"
msgid "Name"
msgstr ""
@@ -24065,9 +24591,6 @@ msgstr ""
msgid "No available branches"
msgstr ""
-msgid "No available groups to fork the project."
-msgstr ""
-
msgid "No branches found"
msgstr ""
@@ -24278,6 +24801,9 @@ msgstr ""
msgid "No ref selected"
msgstr ""
+msgid "No regions configured"
+msgstr ""
+
msgid "No related merge requests found."
msgstr ""
@@ -24601,10 +25127,10 @@ msgid "Notify users by email when sign-in location is not recognized."
msgstr ""
msgid "Nov"
-msgstr ""
+msgstr "ඉල්"
msgid "November"
-msgstr ""
+msgstr "ඉල්"
msgid "Now, personalize your GitLab experience"
msgstr ""
@@ -24661,10 +25187,10 @@ msgid "Object does not exist on the server or you don't have permissions to acce
msgstr ""
msgid "Oct"
-msgstr ""
+msgstr "වප්"
msgid "October"
-msgstr ""
+msgstr "වප්"
msgid "OfSearchInADropdown|Filter"
msgstr ""
@@ -25082,6 +25608,9 @@ msgstr ""
msgid "Only reCAPTCHA v2 is supported:"
msgstr ""
+msgid "Only required if not using role instance credentials."
+msgstr ""
+
msgid "Only use lowercase letters, numbers, and underscores."
msgstr ""
@@ -25106,9 +25635,6 @@ msgstr ""
msgid "Open a CLI and connect to the cluster you want to install the agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
-msgid "Open epics"
-msgstr ""
-
msgid "Open errors"
msgstr ""
@@ -25148,7 +25674,7 @@ msgstr ""
msgid "Opened issues"
msgstr ""
-msgid "OpenedNDaysAgo|Opened"
+msgid "OpenedNDaysAgo|Created"
msgstr ""
msgid "Opens in a new window"
@@ -25193,9 +25719,6 @@ msgstr ""
msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
-msgid "Optional."
-msgstr ""
-
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
msgstr ""
@@ -25984,6 +26507,9 @@ msgstr ""
msgid "PerformanceBar|Memory"
msgstr ""
+msgid "PerformanceBar|Memory report"
+msgstr ""
+
msgid "PerformanceBar|Redis calls"
msgstr ""
@@ -26017,18 +26543,12 @@ msgstr ""
msgid "PerformanceBar|wall"
msgstr ""
-msgid "Performs a rebase but skips triggering a new pipeline"
-msgstr ""
-
msgid "Period in seconds"
msgstr ""
msgid "Permalink"
msgstr ""
-msgid "Permanently delete project"
-msgstr ""
-
msgid "Permanently remove group"
msgstr ""
@@ -26299,6 +26819,51 @@ msgstr ""
msgid "PipelineStatusTooltip|Pipeline: %{ci_status}"
msgstr ""
+msgid "PipelineWizardDefaultCommitMessage|Add %{filename}"
+msgstr ""
+
+msgid "PipelineWizardDefaultCommitMessage|Update %{filename}"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|At least one entry is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This field is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This value is not valid"
+msgstr ""
+
+msgid "PipelineWizardListWidget|add another step"
+msgstr ""
+
+msgid "PipelineWizardListWidget|remove step"
+msgstr ""
+
+msgid "PipelineWizard|Commit"
+msgstr ""
+
+msgid "PipelineWizard|Commit Message"
+msgstr ""
+
+msgid "PipelineWizard|Commit changes to your file"
+msgstr ""
+
+msgid "PipelineWizard|Commit file to Branch"
+msgstr ""
+
+msgid "PipelineWizard|Commit your new file"
+msgstr ""
+
+msgid "PipelineWizard|The file has been committed."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem committing the changes."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem while checking whether your file already exists in the specified branch."
+msgstr ""
+
msgid "Pipelines"
msgstr ""
@@ -26413,7 +26978,7 @@ msgstr ""
msgid "Pipelines|Project cache successfully reset."
msgstr ""
-msgid "Pipelines|Revoke"
+msgid "Pipelines|Revoke trigger"
msgstr ""
msgid "Pipelines|Something went wrong while cleaning runners cache."
@@ -26458,6 +27023,12 @@ msgstr ""
msgid "Pipelines|This is a child pipeline within the parent pipeline"
msgstr ""
+msgid "Pipelines|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipelines|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipelines|This pipeline will run code originating from a forked project merge request. This means that the code can potentially have security considerations like exposing CI variables."
msgstr ""
@@ -26500,9 +27071,6 @@ msgstr ""
msgid "Pipelines|Your changes have been successfully committed. Now redirecting to the new merge request page."
msgstr ""
-msgid "Pipelines|detached"
-msgstr ""
-
msgid "Pipelines|error"
msgstr ""
@@ -26512,10 +27080,13 @@ msgstr ""
msgid "Pipelines|latest"
msgstr ""
-msgid "Pipelines|stuck"
+msgid "Pipelines|merge request"
msgstr ""
-msgid "Pipelines|train"
+msgid "Pipelines|merge train"
+msgstr ""
+
+msgid "Pipelines|stuck"
msgstr ""
msgid "Pipelines|yaml invalid"
@@ -26647,6 +27218,12 @@ msgstr ""
msgid "Pipeline|This change will not change the overall test coverage if merged."
msgstr ""
+msgid "Pipeline|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipeline|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipeline|Trigger author"
msgstr ""
@@ -26671,6 +27248,12 @@ msgstr ""
msgid "Pipeline|for"
msgstr ""
+msgid "Pipeline|merge request"
+msgstr ""
+
+msgid "Pipeline|merge train"
+msgstr ""
+
msgid "Pipeline|on"
msgstr ""
@@ -26809,9 +27392,6 @@ msgstr ""
msgid "Please enter a valid time interval"
msgstr ""
-msgid "Please enter or upload a valid license."
-msgstr ""
-
msgid "Please enter your current password."
msgstr ""
@@ -26920,9 +27500,6 @@ msgstr ""
msgid "Please type %{phrase_code} to proceed or close this modal to cancel."
msgstr ""
-msgid "Please type the following to confirm:"
-msgstr ""
-
msgid "Please use this form to report to the admin users who create spam issues, comments or behave inappropriately."
msgstr ""
@@ -26950,12 +27527,27 @@ msgstr ""
msgid "Policies"
msgstr ""
+msgid "Policy '%{escalation_policy_name}' does not exist."
+msgstr ""
+
msgid "Policy management project does have any policies in %{policy_path}"
msgstr ""
msgid "Policy project doesn't exist"
msgstr ""
+msgid "PolicyRuleMultiSelect|%{firstLabel} +%{numberOfAdditionalLabels} more"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|All %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select all"
+msgstr ""
+
msgid "Polling interval multiplier"
msgstr ""
@@ -27184,6 +27776,9 @@ msgstr ""
msgid "Private projects can be created in your personal namespace with:"
msgstr ""
+msgid "Problem with %{name} command: %{message}."
+msgstr ""
+
msgid "Proceed"
msgstr ""
@@ -27658,6 +28253,9 @@ msgstr ""
msgid "Progress"
msgstr ""
+msgid "Progress tracking"
+msgstr ""
+
msgid "Project"
msgstr ""
@@ -27889,6 +28487,9 @@ msgstr ""
msgid "ProjectQualitySummary|Failure"
msgstr ""
+msgid "ProjectQualitySummary|Get insight into the overall percentage of tests in your project that succeed, fail and are skipped."
+msgstr ""
+
msgid "ProjectQualitySummary|Latest pipeline results"
msgstr ""
@@ -27907,6 +28508,12 @@ msgstr ""
msgid "ProjectQualitySummary|See project Code Coverage Statistics"
msgstr ""
+msgid "ProjectQualitySummary|Set up test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|Set up test runs (opens in a new tab)"
+msgstr ""
+
msgid "ProjectQualitySummary|Skipped"
msgstr ""
@@ -28183,13 +28790,19 @@ msgstr ""
msgid "ProjectSettings|LFS objects from this repository are available to forks. %{linkStart}How do I remove them?%{linkEnd}"
msgstr ""
+msgid "ProjectSettings|Learn about commit history."
+msgstr ""
+
+msgid "ProjectSettings|Leave empty to use default template."
+msgstr ""
+
msgid "ProjectSettings|Manage who can see the project in the public access directory."
msgstr ""
msgid "ProjectSettings|Manages large files such as audio, video, and graphics files."
msgstr ""
-msgid "ProjectSettings|Maximum 500 characters."
+msgid "ProjectSettings|Maximum %{maxLength} characters."
msgstr ""
msgid "ProjectSettings|Merge checks"
@@ -28330,6 +28943,9 @@ msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
msgstr ""
+msgid "ProjectSettings|The default template will be applied on save."
+msgstr ""
+
msgid "ProjectSettings|These checks must pass before merge requests can be merged."
msgstr ""
@@ -28384,6 +29000,9 @@ msgstr ""
msgid "ProjectSettings|What are badges?"
msgstr ""
+msgid "ProjectSettings|What are merge trains?"
+msgstr ""
+
msgid "ProjectSettings|When merge request pipelines are enabled in the CI/CD configuration file, pipelines validate the combined results of the source and target branches. %{link_start}How to configure merge request pipelines?%{link_end}"
msgstr ""
@@ -28501,6 +29120,9 @@ msgstr ""
msgid "Projects are organized into groups"
msgstr ""
+msgid "Projects are where you store your code, access issues, wiki and other features of GitLab."
+msgstr ""
+
msgid "Projects contributed to"
msgstr ""
@@ -28516,12 +29138,6 @@ msgstr ""
msgid "Projects to index"
msgstr ""
-msgid "Projects will be permanently deleted after a %{waiting_period}-day waiting period."
-msgstr ""
-
-msgid "Projects will be permanently deleted immediately."
-msgstr ""
-
msgid "Projects with critical vulnerabilities"
msgstr ""
@@ -28606,6 +29222,9 @@ msgstr ""
msgid "ProjectsNew|Import project"
msgstr ""
+msgid "ProjectsNew|Include a Getting Started README"
+msgstr ""
+
msgid "ProjectsNew|Initialize repository with a README"
msgstr ""
@@ -28621,6 +29240,9 @@ msgstr ""
msgid "ProjectsNew|Project description %{tag_start}(optional)%{tag_end}"
msgstr ""
+msgid "ProjectsNew|Recommended if you're new to GitLab"
+msgstr ""
+
msgid "ProjectsNew|Run CI/CD for external repository"
msgstr ""
@@ -29038,6 +29660,9 @@ msgstr ""
msgid "ProtectedBranch|Unprotect"
msgstr ""
+msgid "ProtectedBranch|Unprotect branch"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
@@ -29065,6 +29690,9 @@ msgstr ""
msgid "ProtectedEnvironment|Protected Environment (%{protected_environments_count})"
msgstr ""
+msgid "ProtectedEnvironment|Required approvals"
+msgstr ""
+
msgid "ProtectedEnvironment|Select an environment"
msgstr ""
@@ -29086,10 +29714,13 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|Unprotect tag"
+msgstr ""
+
msgid "ProtectedTags|default"
msgstr ""
-msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
+msgid "ProtectedTag|By default, protected tags restrict who can modify the tag."
msgstr ""
msgid "ProtectedTag|Learn more."
@@ -29152,6 +29783,9 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Public projects are an easy way to allow everyone to have read-only access."
+msgstr ""
+
msgid "Publish to status page"
msgstr ""
@@ -29308,9 +29942,6 @@ msgstr ""
msgid "QualitySummary|Project quality"
msgstr ""
-msgid "Quarters"
-msgstr ""
-
msgid "Query"
msgstr ""
@@ -29395,6 +30026,9 @@ msgstr ""
msgid "Read more about project permissions %{help_link_open}here%{help_link_close}"
msgstr ""
+msgid "Read more about related epics"
+msgstr ""
+
msgid "Read more about related issues"
msgstr ""
@@ -29425,10 +30059,7 @@ msgstr ""
msgid "Rebase source branch on the target branch."
msgstr ""
-msgid "Rebase without CI"
-msgstr ""
-
-msgid "Rebases and triggers a pipeline"
+msgid "Rebase without pipeline"
msgstr ""
msgid "Recaptcha verified?"
@@ -29479,9 +30110,6 @@ msgstr ""
msgid "Reconfigure"
msgstr ""
-msgid "Recovering projects"
-msgstr ""
-
msgid "Recovery Codes"
msgstr ""
@@ -29541,6 +30169,12 @@ msgstr ""
msgid "Regex pattern"
msgstr ""
+msgid "Region"
+msgstr ""
+
+msgid "Regions"
+msgstr ""
+
msgid "Register"
msgstr ""
@@ -29771,9 +30405,6 @@ msgstr ""
msgid "Remove all or specific reviewer(s)"
msgstr ""
-msgid "Remove approver"
-msgstr ""
-
msgid "Remove approvers"
msgstr ""
@@ -29789,6 +30420,9 @@ msgstr ""
msgid "Remove attention request"
msgstr ""
+msgid "Remove attention request(s)"
+msgstr ""
+
msgid "Remove avatar"
msgstr ""
@@ -29927,6 +30561,9 @@ msgstr ""
msgid "Removed an issue from an epic."
msgstr ""
+msgid "Removed attention from %{users_sentence}."
+msgstr ""
+
msgid "Removed attention request from @%{username}"
msgstr ""
@@ -29978,6 +30615,9 @@ msgstr ""
msgid "Removes an issue from an epic."
msgstr ""
+msgid "Removes attention from %{users_sentence}."
+msgstr ""
+
msgid "Removes parent epic %{epic_ref}."
msgstr ""
@@ -30089,6 +30729,9 @@ msgstr ""
msgid "Report abuse to admin"
msgstr ""
+msgid "Report is generating and will be sent to your email address."
+msgstr ""
+
msgid "Reported %{timeAgo} by %{reportedBy}"
msgstr ""
@@ -30378,6 +31021,15 @@ msgstr ""
msgid "Request attention"
msgstr ""
+msgid "Request attention from %{users_sentence}."
+msgstr ""
+
+msgid "Request attention from assignee or reviewer"
+msgstr ""
+
+msgid "Request attention from assignee(s) or reviewer(s)"
+msgstr ""
+
msgid "Request attention to review"
msgstr ""
@@ -30402,6 +31054,9 @@ msgstr ""
msgid "Requested %{time_ago}"
msgstr ""
+msgid "Requested attention from %{users_sentence}."
+msgstr ""
+
msgid "Requested attention from @%{username}"
msgstr ""
@@ -30616,6 +31271,9 @@ msgstr ""
msgid "Restore project"
msgstr ""
+msgid "Restoring projects"
+msgstr ""
+
msgid "Restoring the group will prevent the group, its subgroups and projects from being removed on this date."
msgstr ""
@@ -30646,6 +31304,9 @@ msgstr ""
msgid "Retry"
msgstr ""
+msgid "Retry failed jobs"
+msgstr ""
+
msgid "Retry job"
msgstr ""
@@ -30693,9 +31354,6 @@ msgstr ""
msgid "Review changes"
msgstr ""
-msgid "Review requested from %{name}"
-msgstr ""
-
msgid "Review requests for you"
msgstr ""
@@ -30860,6 +31518,9 @@ msgstr ""
msgid "Runners|Assigned Group"
msgstr ""
+msgid "Runners|Assigned Projects (%{projectCount})"
+msgstr ""
+
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30929,6 +31590,9 @@ msgstr ""
msgid "Runners|Instance"
msgstr ""
+msgid "Runners|Jobs"
+msgstr ""
+
msgid "Runners|Last contact"
msgstr ""
@@ -31022,9 +31686,6 @@ msgstr ""
msgid "Runners|Runner %{name} was deleted"
msgstr ""
-msgid "Runners|Runner ID"
-msgstr ""
-
msgid "Runners|Runner assigned to project."
msgstr ""
@@ -31172,6 +31833,9 @@ msgstr ""
msgid "Runners|stale"
msgstr ""
+msgid "Runner|This runner has not run any jobs."
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -31286,6 +31950,24 @@ msgstr ""
msgid "Saving project."
msgstr ""
+msgid "ScanResultPolicy|%{ifLabelStart}if%{ifLabelEnd} %{scanners} scan in an open merge request targeting the %{branches} branch(es) finds %{vulnerabilitiesAllowed} or more %{severities} vulnerabilities that are %{vulnerabilityStates}"
+msgstr ""
+
+msgid "ScanResultPolicy|%{thenLabelStart}Then%{thenLabelEnd} Require approval from %{approvalsRequired} of the following approvers: %{approvers}"
+msgstr ""
+
+msgid "ScanResultPolicy|add an approver"
+msgstr ""
+
+msgid "ScanResultPolicy|scanners"
+msgstr ""
+
+msgid "ScanResultPolicy|severity levels"
+msgstr ""
+
+msgid "ScanResultPolicy|vulnerability states"
+msgstr ""
+
msgid "Scanner"
msgstr ""
@@ -31418,6 +32100,9 @@ msgstr ""
msgid "Search for a user"
msgstr ""
+msgid "Search for an emoji"
+msgstr ""
+
msgid "Search for projects, issues, etc."
msgstr ""
@@ -31605,18 +32290,12 @@ msgstr ""
msgid "Secret Detection"
msgstr ""
-msgid "Secret access key"
-msgstr ""
-
msgid "Secret token"
msgstr ""
msgid "Secure token that identifies an external storage request."
msgstr ""
-msgid "SecureCodeWarrior"
-msgstr ""
-
msgid "Security"
msgstr ""
@@ -31641,9 +32320,6 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "Security training with guide and learning pathways."
-msgstr ""
-
msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
@@ -31746,7 +32422,7 @@ msgstr ""
msgid "SecurityConfiguration|Manage corpus"
msgstr ""
-msgid "SecurityConfiguration|Manage corpus files used as mutation sources in coverage fuzzing."
+msgid "SecurityConfiguration|Manage corpus files used as seed inputs with coverage-guided fuzzing."
msgstr ""
msgid "SecurityConfiguration|Manage profiles for use by DAST scans."
@@ -31812,15 +32488,15 @@ msgstr ""
msgid "SecurityOrchestration|.yaml preview"
msgstr ""
-msgid "SecurityOrchestration|Action"
-msgstr ""
-
msgid "SecurityOrchestration|Actions"
msgstr ""
msgid "SecurityOrchestration|Add rule"
msgstr ""
+msgid "SecurityOrchestration|After dismissing the alert, the information will never be shown again."
+msgstr ""
+
msgid "SecurityOrchestration|All policies"
msgstr ""
@@ -31836,7 +32512,7 @@ msgstr ""
msgid "SecurityOrchestration|Description"
msgstr ""
-msgid "SecurityOrchestration|Disabled"
+msgid "SecurityOrchestration|Don't show the alert anymore"
msgstr ""
msgid "SecurityOrchestration|Edit policy"
@@ -31845,13 +32521,13 @@ msgstr ""
msgid "SecurityOrchestration|Edit policy project"
msgstr ""
-msgid "SecurityOrchestration|Enabled"
+msgid "SecurityOrchestration|Empty policy name"
msgstr ""
-msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Enabled"
msgstr ""
-msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
msgstr ""
msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
@@ -31860,7 +32536,7 @@ msgstr ""
msgid "SecurityOrchestration|Invalid policy type"
msgstr ""
-msgid "SecurityOrchestration|Latest scan"
+msgid "SecurityOrchestration|Latest scan run against %{agent}"
msgstr ""
msgid "SecurityOrchestration|Network"
@@ -31869,15 +32545,27 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No actions defined - policy will not run."
+msgstr ""
+
+msgid "SecurityOrchestration|No description"
+msgstr ""
+
msgid "SecurityOrchestration|No rules defined - policy will not run."
msgstr ""
+msgid "SecurityOrchestration|Not enabled"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
msgid "SecurityOrchestration|Policies"
msgstr ""
+msgid "SecurityOrchestration|Policy Type"
+msgstr ""
+
msgid "SecurityOrchestration|Policy cannot be enabled for non-existing branches (%{branches})"
msgstr ""
@@ -31902,10 +32590,13 @@ msgstr ""
msgid "SecurityOrchestration|Require %{approvals} %{plural} from %{approvers} if any of the following occur:"
msgstr ""
-msgid "SecurityOrchestration|Rule"
+msgid "SecurityOrchestration|Rules"
+msgstr ""
+
+msgid "SecurityOrchestration|Runs %{actions} and %{lastAction} scans"
msgstr ""
-msgid "SecurityOrchestration|Rules"
+msgid "SecurityOrchestration|Runs a %{action} scan"
msgstr ""
msgid "SecurityOrchestration|Scan Execution"
@@ -31965,6 +32656,9 @@ msgstr ""
msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
+msgid "SecurityOrchestration|This view only shows scan results for the agent %{agent}. You can view scan results for all agents in the %{linkStart}Operational Vulnerabilities tab of the vulnerability report%{linkEnd}."
+msgstr ""
+
msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
@@ -32019,9 +32713,6 @@ msgstr ""
msgid "SecurityOrchestration|users with ids"
msgstr ""
-msgid "SecurityOrchestration|view results"
-msgstr ""
-
msgid "SecurityOrchestration|vulnerabilities"
msgstr ""
@@ -32629,10 +33320,10 @@ msgid "Sentry event"
msgstr ""
msgid "Sep"
-msgstr ""
+msgstr "බිනර"
msgid "September"
-msgstr ""
+msgstr "බිනර"
msgid "SeriesFinalConjunction|and"
msgstr ""
@@ -32691,22 +33382,19 @@ 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|In order to start using functions as a service, you must first install Knative on your Kubernetes cluster. %{linkStart}More information%{linkEnd}"
-msgstr ""
-
msgid "Serverless|Learn more about Serverless"
msgstr ""
msgid "Serverless|No functions available"
msgstr ""
-msgid "Serverless|Sign up for First Look"
+msgid "Serverless|Serverless was %{linkStart}deprecated%{linkEnd} in GitLab 14.3."
+msgstr ""
+
+msgid "Serverless|Serverless was %{postLinkStart}deprecated%{postLinkEnd}. But if you opt to use it, you must install Knative in your Kubernetes cluster first. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "Serverless|The deploy job has not finished."
@@ -32718,9 +33406,6 @@ 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 ""
@@ -32736,9 +33421,6 @@ msgstr ""
msgid "Service Account Key"
msgstr ""
-msgid "Service Accounts"
-msgstr ""
-
msgid "Service Accounts keys authorize GitLab to deploy your Google Cloud project"
msgstr ""
@@ -32748,10 +33430,10 @@ msgstr ""
msgid "Service Desk allows people to create issues in your GitLab instance without their own user account. It provides a unique email address for end users to create issues in a project. Replies can be sent either through the GitLab interface or by email. End users only see threads through email."
msgstr ""
-msgid "Service Usage Data"
+msgid "Service account generated successfully"
msgstr ""
-msgid "Service account generated successfully"
+msgid "Service accounts"
msgstr ""
msgid "Service ping is disabled in your configuration file, and cannot be enabled through this form."
@@ -32895,6 +33577,9 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
+msgid "Set the per-user rate limit for getting a user by ID via the API."
+msgstr ""
+
msgid "Set the per-user rate limit for notes created by web or API requests."
msgstr ""
@@ -33074,6 +33759,9 @@ msgstr ""
msgid "Shared runners details"
msgstr ""
+msgid "Shared runners enabled cannot be enabled until a valid credit card is on file"
+msgstr ""
+
msgid "Shared runners help link"
msgstr ""
@@ -33131,6 +33819,9 @@ msgstr ""
msgid "Show all issues."
msgstr ""
+msgid "Show all milestones"
+msgstr ""
+
msgid "Show all test cases."
msgstr ""
@@ -33167,6 +33858,9 @@ msgstr ""
msgid "Show file contents"
msgstr ""
+msgid "Show group milestones"
+msgstr ""
+
msgid "Show labels"
msgstr ""
@@ -33182,6 +33876,12 @@ msgstr ""
msgid "Show open epics"
msgstr ""
+msgid "Show project milestones"
+msgstr ""
+
+msgid "Show sub-group milestones"
+msgstr ""
+
msgid "Show the Closed list"
msgstr ""
@@ -33191,11 +33891,6 @@ msgstr ""
msgid "Show whitespace changes"
msgstr ""
-msgid "Showing %d event"
-msgid_plural "Showing %d events"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Showing %{conflict} between %{sourceBranch} and %{targetBranch}"
msgstr ""
@@ -33255,12 +33950,6 @@ msgstr ""
msgid "Sidebar|None"
msgstr ""
-msgid "Sidebar|Only numeral characters allowed"
-msgstr ""
-
-msgid "Sidebar|Weight"
-msgstr ""
-
msgid "Sidekiq job compression threshold (bytes)"
msgstr ""
@@ -33423,6 +34112,9 @@ msgstr ""
msgid "Slack logo"
msgstr ""
+msgid "SlackIntegration|Are you sure you want to remove this project from the Slack application?"
+msgstr ""
+
msgid "SlackIntegration|GitLab for Slack"
msgstr ""
@@ -33432,6 +34124,9 @@ msgstr ""
msgid "SlackIntegration|Project alias"
msgstr ""
+msgid "SlackIntegration|Remove project"
+msgstr ""
+
msgid "SlackIntegration|Select a GitLab project to link with your Slack workspace."
msgstr ""
@@ -33576,9 +34271,6 @@ msgstr ""
msgid "Something went wrong trying to load issue contacts."
msgstr ""
-msgid "Something went wrong when creating a work item. Please try again"
-msgstr ""
-
msgid "Something went wrong when reordering designs. Please try again"
msgstr ""
@@ -33672,9 +34364,6 @@ msgstr ""
msgid "Something went wrong while inserting your image. Please try again."
msgstr ""
-msgid "Something went wrong while merging this merge request. Please try again."
-msgstr ""
-
msgid "Something went wrong while obtaining the Let's Encrypt certificate."
msgstr ""
@@ -33996,10 +34685,10 @@ 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."
+msgid "SourcegraphAdmin|Learn more."
msgstr ""
-msgid "SourcegraphAdmin|More information"
+msgid "SourcegraphAdmin|Only public projects have code intelligence enabled and communicate with Sourcegraph."
msgstr ""
msgid "SourcegraphAdmin|Save changes"
@@ -34008,7 +34697,7 @@ msgstr ""
msgid "SourcegraphAdmin|Sourcegraph URL"
msgstr ""
-msgid "SourcegraphAdmin|e.g. https://sourcegraph.example.com"
+msgid "SourcegraphAdmin|https://sourcegraph.example.com"
msgstr ""
msgid "SourcegraphPreferences|This feature is experimental and currently limited to certain projects."
@@ -34143,6 +34832,9 @@ msgstr ""
msgid "Start date"
msgstr ""
+msgid "Start free trial"
+msgstr ""
+
msgid "Start merge train"
msgstr ""
@@ -34173,6 +34865,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started escalation for this incident."
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -34185,6 +34880,9 @@ msgstr ""
msgid "Starts at (UTC)"
msgstr ""
+msgid "Starts escalations for this incident"
+msgstr ""
+
msgid "Starts on"
msgstr ""
@@ -34446,6 +35144,9 @@ msgstr ""
msgid "Strikethrough"
msgstr ""
+msgid "Strikethrough text"
+msgstr ""
+
msgid "Subgroup information"
msgstr ""
@@ -34680,6 +35381,21 @@ msgstr ""
msgid "Subscriptions"
msgstr ""
+msgid "Subscriptions|Chat with sales"
+msgstr ""
+
+msgid "Subscriptions|Close"
+msgstr ""
+
+msgid "Subscriptions|Not ready to buy yet?"
+msgstr ""
+
+msgid "Subscriptions|Start a free trial"
+msgstr ""
+
+msgid "Subscriptions|We understand. Maybe you have some questions for our sales team, or maybe you'd like to try some of the paid features first. What would you like to do?"
+msgstr ""
+
msgid "Subscription|Your subscription for %{strong}%{namespace_name}%{strong_close} has expired and you are now on %{pricing_link_start}the GitLab Free tier%{pricing_link_end}. Don't worry, your data is safe. Get in touch with our support team (%{support_email}). They'll gladly help with your subscription renewal."
msgstr ""
@@ -34890,6 +35606,9 @@ msgstr ""
msgid "SuperSonics|Maximum users"
msgstr ""
+msgid "SuperSonics|Offline cloud"
+msgstr ""
+
msgid "SuperSonics|Paste your activation code"
msgstr ""
@@ -34956,6 +35675,12 @@ msgstr ""
msgid "SuperSonics|You do not have an active subscription"
msgstr ""
+msgid "SuperSonics|You have a future dated license"
+msgstr ""
+
+msgid "SuperSonics|You have added a license that activates on %{date}. Please see the subscription history table below for more details."
+msgstr ""
+
msgid "SuperSonics|You have successfully added a license that activates on %{date}. Please see the subscription history table below for more details."
msgstr ""
@@ -35115,6 +35840,9 @@ msgstr ""
msgid "Tag name is required"
msgstr ""
+msgid "Tag push"
+msgstr ""
+
msgid "Tag push events"
msgstr ""
@@ -35217,6 +35945,9 @@ msgstr ""
msgid "TagsPage|protected"
msgstr ""
+msgid "Take a look at the documentation to discover all of GitLab’s capabilities."
+msgstr ""
+
msgid "Target Branch"
msgstr ""
@@ -35619,6 +36350,9 @@ msgstr ""
msgid "Tests"
msgstr ""
+msgid "Text (optional)"
+msgstr ""
+
msgid "Text added to the body of all email messages. %{character_limit} character limit"
msgstr ""
@@ -35669,6 +36403,9 @@ msgstr ""
msgid "The CSV export will be created in the background. Once finished, it will be sent to %{email} in an attachment."
msgstr ""
+msgid "The CSV export you requested of all user memberships is attached to this email."
+msgstr ""
+
msgid "The GitLab subscription service (customers.gitlab.com) is currently experiencing an outage. You can monitor the status and get updates at %{linkStart}status.gitlab.com%{linkEnd}."
msgstr ""
@@ -35744,6 +36481,9 @@ 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 epic"
+msgstr ""
+
msgid "The current issue"
msgstr ""
@@ -35905,6 +36645,9 @@ msgstr ""
msgid "The latest pipeline for this merge request has failed."
msgstr ""
+msgid "The license key is invalid."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -35920,6 +36663,9 @@ msgstr ""
msgid "The license was successfully uploaded and will be active from %{starts_at}. You can see the details below."
msgstr ""
+msgid "The license you uploaded is invalid. If the issue persists, contact support at %{link}."
+msgstr ""
+
msgid "The list creation wizard is already open"
msgstr ""
@@ -36541,10 +37287,13 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} and everything this project contains. %{strongOpen}There is no going back%{strongClose}"
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}on %{date}%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains."
+msgstr ""
+
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains. %{strongOpen}There is no going back.%{strongClose}"
msgstr ""
msgid "This action will %{strongOpen}permanently remove%{strongClose} %{codeOpen}%{group}%{codeClose} %{strongOpen}immediately%{strongClose}."
@@ -36635,7 +37384,7 @@ msgid "This diff is collapsed."
msgstr ""
msgid "This directory"
-msgstr ""
+msgstr "මෙම නà·à¶¸à·à·€à¶½à·’ය"
msgid "This domain is not verified. You will need to verify ownership before access is enabled."
msgstr ""
@@ -36665,22 +37414,19 @@ msgid "This feature requires local storage to be enabled"
msgstr ""
msgid "This field is required"
-msgstr ""
+msgstr "මෙම ක්â€à·‚ේත්â€à¶»à¶º ඇවà·à·ƒà·’ය"
msgid "This field is required."
-msgstr ""
+msgstr "මෙම ක්â€à·‚ේත්â€à¶»à¶º ඇවà·à·ƒà·’ය."
msgid "This file was modified for readability, and can't accept suggestions. Edit it directly."
msgstr ""
-msgid "This forked project has the following:"
-msgstr ""
-
msgid "This form is disabled in preview"
msgstr ""
msgid "This group"
-msgstr ""
+msgstr "මෙම සමූහය"
msgid "This group and its subgroups and projects will be placed in a 'pending deletion' state for %{deletion_adjourned_period} days, then permanently deleted on %{date}. The group can be fully restored before that date."
msgstr ""
@@ -36688,7 +37434,7 @@ msgstr ""
msgid "This group can't be removed because it is linked to a subscription. To remove this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
-msgid "This group can't be transfered because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
+msgid "This group can't be transferred because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
msgid "This group cannot be invited to a project inside a group with enforced SSO"
@@ -36715,6 +37461,9 @@ 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 incident is already escalated with '%{escalation_policy_name}'."
+msgstr ""
+
msgid "This invitation was sent to %{mail_to_invite_email}, but you are signed in as %{link_to_current_user} with email %{mail_to_current_user}."
msgstr ""
@@ -36722,7 +37471,7 @@ msgid "This is a \"Ghost User\", created to hold all issues authored by users th
msgstr ""
msgid "This is a Jira user."
-msgstr ""
+msgstr "මේ ජිර෠පරිà·à·“ලකයෙකි."
msgid "This is a confidential %{noteableTypeText}."
msgstr ""
@@ -36733,9 +37482,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 merge train pipeline"
-msgstr ""
-
msgid "This is a private email address %{helpIcon} generated just for you. Anyone who has it can create issues or merge requests as if they were you. If that happens, %{resetLinkStart}reset this token%{resetLinkEnd}."
msgstr ""
@@ -36757,6 +37503,12 @@ msgstr ""
msgid "This is your current session"
msgstr ""
+msgid "This issue cannot be assigned to a confidential epic because it is public."
+msgstr ""
+
+msgid "This issue cannot be made public because it belongs to a confidential epic."
+msgstr ""
+
msgid "This issue is confidential and should only be visible to team members with at least Reporter access."
msgstr ""
@@ -36874,6 +37626,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 branch is protected from force push."
+msgstr ""
+
msgid "This merge request cannot be rebased while there are conflicts."
msgstr ""
@@ -36925,7 +37680,13 @@ msgstr ""
msgid "This pipeline was triggered by a schedule."
msgstr ""
+msgid "This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project"
+msgstr "මෙම ව්â€à¶ºà·à¶´à·˜à¶­à·’ය"
+
+msgid "This project can be restored until %{date}."
msgstr ""
msgid "This project cannot be %{visibilityLevel} because the visibility of %{openShowLink}%{name}%{closeShowLink} is %{visibility}. To make this project %{visibilityLevel}, you must first %{openEditLink}change the visibility%{closeEditLink} of the parent group."
@@ -36946,6 +37707,9 @@ msgstr ""
msgid "This project is %{strongStart}NOT%{strongEnd} a fork, and has the following:"
msgstr ""
+msgid "This project is %{strongStart}NOT%{strongEnd} a fork. This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -36971,7 +37735,7 @@ msgid "This project will live in your group %{strong_open}%{namespace}%{strong_c
msgstr ""
msgid "This repository"
-msgstr ""
+msgstr "මෙම කà·à·‚්ඨය"
msgid "This repository has never been checked."
msgstr ""
@@ -37055,13 +37819,13 @@ msgid "Threat monitoring"
msgstr ""
msgid "ThreatMonitoring|Alert Details"
-msgstr ""
+msgstr "ඇඟවීමේ විස්තර"
msgid "ThreatMonitoring|Alerts"
-msgstr ""
+msgstr "ඇඟවීම්"
msgid "ThreatMonitoring|All Environments"
-msgstr ""
+msgstr "සියළු පරිසර"
msgid "ThreatMonitoring|Anomalous Requests"
msgstr ""
@@ -37076,7 +37840,7 @@ msgid "ThreatMonitoring|Container NetworkPolicies not detected"
msgstr ""
msgid "ThreatMonitoring|Date and time"
-msgstr ""
+msgstr "දිනය සහ වේලà·à·€"
msgid "ThreatMonitoring|Dismissed"
msgstr ""
@@ -37085,10 +37849,10 @@ msgid "ThreatMonitoring|Dropped Packets"
msgstr ""
msgid "ThreatMonitoring|Environment"
-msgstr ""
+msgstr "පරිසරය"
msgid "ThreatMonitoring|Events"
-msgstr ""
+msgstr "සිදුවීම්"
msgid "ThreatMonitoring|Failed to create incident, please try again."
msgstr ""
@@ -37103,7 +37867,7 @@ msgid "ThreatMonitoring|Incident"
msgstr ""
msgid "ThreatMonitoring|Name"
-msgstr ""
+msgstr "නම"
msgid "ThreatMonitoring|No alerts available to display. See %{linkStart}enabling threat alerts%{linkEnd} for more information on adding alerts to the list."
msgstr ""
@@ -37115,13 +37879,13 @@ msgid "ThreatMonitoring|No environments detected"
msgstr ""
msgid "ThreatMonitoring|Operations Per Second"
-msgstr ""
+msgstr "තත්පරයට මෙහෙයුම්"
msgid "ThreatMonitoring|Packet Activity"
msgstr ""
msgid "ThreatMonitoring|Requests"
-msgstr ""
+msgstr "ඉල්ලීම්"
msgid "ThreatMonitoring|Resolved"
msgstr ""
@@ -37136,10 +37900,10 @@ msgid "ThreatMonitoring|Something went wrong, unable to fetch statistics"
msgstr ""
msgid "ThreatMonitoring|Statistics"
-msgstr ""
+msgstr "සංඛ්â€à¶ºà·à¶½à·šà¶›à¶±"
msgid "ThreatMonitoring|Status"
-msgstr ""
+msgstr "තත්â€à·€à¶º"
msgid "ThreatMonitoring|There was an error displaying the alerts. Confirm your endpoint's configuration details to ensure alerts appear."
msgstr ""
@@ -37154,7 +37918,7 @@ msgid "ThreatMonitoring|Threat Monitoring help page link"
msgstr ""
msgid "ThreatMonitoring|Time"
-msgstr ""
+msgstr "වේලà·à·€"
msgid "ThreatMonitoring|To view this data, ensure you have configured an environment for this project and that at least one threat monitoring feature is enabled. %{linkStart}More information%{linkEnd}"
msgstr ""
@@ -37163,13 +37927,13 @@ msgid "ThreatMonitoring|Total Packets"
msgstr ""
msgid "ThreatMonitoring|Total Requests"
-msgstr ""
+msgstr "මුළු ඉල්ලීම්"
msgid "ThreatMonitoring|Unreviewed"
msgstr ""
msgid "ThreatMonitoring|View documentation"
-msgstr ""
+msgstr "ප්â€à¶»à¶½à·šà¶›à¶±à¶º දකින්න"
msgid "Threshold in bytes at which to compress Sidekiq job arguments."
msgstr ""
@@ -37184,10 +37948,10 @@ msgid "Throughput"
msgstr ""
msgid "Thursday"
-msgstr ""
+msgstr "බ්â€à¶»à·„ස්පතින්දà·"
msgid "Time"
-msgstr ""
+msgstr "වේලà·à·€"
msgid "Time (in hours) that users are allowed to skip forced configuration of two-factor authentication."
msgstr ""
@@ -37196,7 +37960,7 @@ msgid "Time Spent"
msgstr ""
msgid "Time based: Yes"
-msgstr ""
+msgstr "කà·à¶½à¶º පà·à¶¯à¶š: ඔව්"
msgid "Time before an issue gets scheduled"
msgstr ""
@@ -37250,7 +38014,7 @@ msgid "Time until first merge request"
msgstr ""
msgid "Time zone"
-msgstr ""
+msgstr "වේල෠කලà·à¶´à¶º"
msgid "TimeTrackingEstimated|Est"
msgstr ""
@@ -37271,79 +38035,79 @@ msgid "TimeTracking|Time remaining: %{timeRemainingHumanReadable}"
msgstr ""
msgid "Timeago|%s days ago"
-msgstr ""
+msgstr "දවස් %s කට පෙර"
msgid "Timeago|%s days remaining"
-msgstr ""
+msgstr "දවස් %s ක් ඉතිරිය"
msgid "Timeago|%s hours ago"
-msgstr ""
+msgstr "පà·à¶º %s කට පෙර"
msgid "Timeago|%s hours remaining"
-msgstr ""
+msgstr "පà·à¶º %s ක් ඉතිරිය"
msgid "Timeago|%s minutes ago"
-msgstr ""
+msgstr "විනà·à¶©à·’ %s කට පෙර"
msgid "Timeago|%s minutes remaining"
-msgstr ""
+msgstr "විනà·à¶©à·’ %s ක් ඉතිරිය"
msgid "Timeago|%s months ago"
-msgstr ""
+msgstr "මà·à·ƒ %s කට පෙර"
msgid "Timeago|%s months remaining"
-msgstr ""
+msgstr "මà·à·ƒ %s ක් ඉතිරිය"
msgid "Timeago|%s seconds remaining"
-msgstr ""
+msgstr "තත්පර %s ක් ඉතිරිය"
msgid "Timeago|%s weeks ago"
-msgstr ""
+msgstr "සති %s කට පෙර"
msgid "Timeago|%s weeks remaining"
msgstr ""
msgid "Timeago|%s years ago"
-msgstr ""
+msgstr "අවුරුදු %s කට පෙර"
msgid "Timeago|%s years remaining"
-msgstr ""
+msgstr "අවුරුදු %s ක් ඉතිරිය"
msgid "Timeago|1 day ago"
-msgstr ""
+msgstr "දවසකට පෙර"
msgid "Timeago|1 day remaining"
-msgstr ""
+msgstr "දවසක් ඉතිරිය"
msgid "Timeago|1 hour ago"
-msgstr ""
+msgstr "පà·à¶ºà¶šà¶§ පෙර"
msgid "Timeago|1 hour remaining"
-msgstr ""
+msgstr "පà·à¶ºà¶šà·Š ඉතිරිය"
msgid "Timeago|1 minute ago"
-msgstr ""
+msgstr "විනà·à¶©à·’යකට පෙර"
msgid "Timeago|1 minute remaining"
-msgstr ""
+msgstr "විනà·à¶©à·’යක් ඉතිරිය"
msgid "Timeago|1 month ago"
-msgstr ""
+msgstr "මà·à·ƒà¶ºà¶šà¶§ පෙර"
msgid "Timeago|1 month remaining"
-msgstr ""
+msgstr "මà·à·ƒà¶ºà¶šà·Š ඉතිරිය"
msgid "Timeago|1 week ago"
-msgstr ""
+msgstr "සතියකට පෙර"
msgid "Timeago|1 week remaining"
-msgstr ""
+msgstr "සතියක් ඉතිරිය"
msgid "Timeago|1 year ago"
-msgstr ""
+msgstr "අවුරුද්දකට පෙර"
msgid "Timeago|1 year remaining"
-msgstr ""
+msgstr "අවුරුද්දක් ඉතිරිය"
msgid "Timeago|Past due"
msgstr ""
@@ -37388,10 +38152,10 @@ msgid "Timeago|in 1 year"
msgstr ""
msgid "Timeago|just now"
-msgstr ""
+msgstr "මේ දà·à¶±à·Š"
msgid "Timeago|right now"
-msgstr ""
+msgstr "හරියටම දà·à¶±à·Š"
msgid "Timeline|Turn timeline view off"
msgstr ""
@@ -37415,20 +38179,20 @@ msgid "Timeout for the fastest Gitaly operations (in seconds)."
msgstr ""
msgid "Timezone"
-msgstr ""
+msgstr "වේල෠කලà·à¶´à¶º"
msgid "Time|hr"
msgid_plural "Time|hrs"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "පà·à¶º"
+msgstr[1] "පà·à¶º"
msgid "Time|min"
msgid_plural "Time|mins"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "විනà·à¶©à·’"
+msgstr[1] "විනà·à¶©à·’"
msgid "Time|s"
-msgstr ""
+msgstr "තත්."
msgid "Tip: Hover over a job to see the jobs it depends on to run."
msgstr ""
@@ -37437,37 +38201,37 @@ msgid "Tip: add a %{linkStart}CODEOWNERS%{linkEnd} to automatically add approver
msgstr ""
msgid "Title"
-msgstr ""
+msgstr "සිරà·à·ƒà·’ය"
msgid "Title:"
-msgstr ""
+msgstr "සිරà·à·ƒà·’ය:"
msgid "Titles and Descriptions"
-msgstr ""
+msgstr "සිරà·à·ƒà·’ සහ සවිස්තර"
msgid "To"
-msgstr ""
+msgstr "වෙත"
msgid "To %{link_to_help} of your domain, add the above key to a TXT record within your DNS configuration."
msgstr ""
msgid "To Do"
-msgstr ""
+msgstr "කිරීමට"
msgid "To GitLab"
-msgstr ""
+msgstr "ගිට්ලà·à¶¶à·Š වෙත"
msgid "To accept this invitation, create an account or sign in."
-msgstr ""
+msgstr "මෙම ඇරයුම පිළිගà·à¶±à·“මට, ගිණුමක් à·ƒà·à¶¯à¶±à·Šà¶± හ෠ඇතුළු වන්න."
msgid "To accept this invitation, sign in or create an account."
-msgstr ""
+msgstr "මෙම ඇරයුම පිළිගà·à¶±à·“මට, ඇතුළු වන්න හ෠ගිණුමක් à·ƒà·à¶¯à¶±à·Šà¶±."
msgid "To accept this invitation, sign in."
-msgstr ""
+msgstr "මෙම ඇරයුම පිළිගà·à¶±à·“මට, ඇතුළු වන්න."
msgid "To access this domain create a new DNS record"
-msgstr ""
+msgstr "මෙම වසමට ප්â€à¶»à·€à·šà· වීමට නව à·€.නà·.ප. à·€à·à¶»à·Šà¶­à·à·€à¶šà·Š à·ƒà·à¶¯à¶±à·Šà¶±"
msgid "To add a custom suffix, set up a Service Desk email address. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
@@ -37635,6 +38399,9 @@ msgid "To-do item successfully marked as done."
msgstr ""
msgid "Today"
+msgstr "අද"
+
+msgid "Todos count"
msgstr ""
msgid "Todos|Are you looking for things to do? Take a look at %{strongStart}%{openIssuesLinkStart}open issues%{openIssuesLinkEnd}%{strongEnd}, contribute to %{strongStart}%{mergeRequestLinkStart}a merge request%{mergeRequestLinkEnd}%{mergeRequestLinkEnd}%{strongEnd}, or mention someone in a comment to automatically assign them a new to-do item."
@@ -37749,7 +38516,7 @@ msgid "Tokens|Select scopes"
msgstr ""
msgid "Tomorrow"
-msgstr ""
+msgstr "හෙට"
msgid "Too many changes to show."
msgstr ""
@@ -37761,7 +38528,7 @@ msgid "Too many projects enabled. Manage them through the console or the API."
msgstr ""
msgid "TopNav|Go back"
-msgstr ""
+msgstr "ආපසු යන්න"
msgid "Topic %{topic_name} was successfully created."
msgstr ""
@@ -37770,22 +38537,22 @@ msgid "Topic avatar"
msgstr ""
msgid "Topic name"
-msgstr ""
+msgstr "මà·à¶­à·˜à¶šà·à·€à·š නම"
msgid "Topic was successfully updated."
-msgstr ""
+msgstr "මà·à¶­à·˜à¶šà·à·€ à·ƒà·à¶»à·Šà¶®à¶šà·€ යà·à·€à¶­à·Šà¶šà·à¶½ කෙරිණි."
msgid "Topics"
-msgstr ""
+msgstr "මà·à¶­à·˜à¶šà·"
msgid "Total"
-msgstr ""
+msgstr "මුළු"
msgid "Total Contributions"
-msgstr ""
+msgstr "මුළු දà·à¶ºà¶šà¶­à·Šà·€"
msgid "Total Score"
-msgstr ""
+msgstr "මුළු ලකුණු"
msgid "Total artifacts size: %{total_size}"
msgstr ""
@@ -37797,25 +38564,25 @@ msgid "Total issues"
msgstr ""
msgid "Total memory (GB)"
-msgstr ""
+msgstr "මුළු මතකය (ගි.බ.)"
msgid "Total test time for all commits/merges"
msgstr ""
msgid "Total users"
-msgstr ""
+msgstr "මුළු පරිà·à·“ලකයින්"
msgid "Total weight"
msgstr ""
msgid "Total: %{total}"
-msgstr ""
+msgstr "මුළු: %{total}"
msgid "TotalMilestonesIndicator|1000+"
-msgstr ""
+msgstr "1000+"
msgid "TotalRefCountIndicator|1000+"
-msgstr ""
+msgstr "1000+"
msgid "Tracing"
msgstr ""
@@ -37910,22 +38677,23 @@ msgstr ""
msgid "Trending"
msgstr ""
-msgid "Trials|%{planName} Trial %{enDash} %{num} day left"
-msgid_plural "Trials|%{planName} Trial %{enDash} %{num} days left"
-msgstr[0] ""
-msgstr[1] ""
+msgid "Trials|%{planName} Trial"
+msgstr ""
msgid "Trials|Compare all plans"
-msgstr ""
+msgstr "සියළු à·ƒà·à¶½à·ƒà·”ම් සසඳන්න"
msgid "Trials|Create a new group to start your GitLab Ultimate trial."
msgstr ""
-msgid "Trials|Go back to GitLab"
+msgid "Trials|Day %{daysUsed}/%{duration}"
msgstr ""
+msgid "Trials|Go back to GitLab"
+msgstr "ගිට්ලà·à¶¶à·Š වෙත ආපසු යන්න"
+
msgid "Trials|Hey there"
-msgstr ""
+msgstr "ආයුබà·"
msgid "Trials|Skip Trial"
msgstr ""
@@ -37949,25 +38717,25 @@ msgid "Trial|Allowed characters: +, 0-9, -, and spaces."
msgstr ""
msgid "Trial|Company name"
-msgstr ""
+msgstr "සමà·à¶œà¶¸à·š නම"
msgid "Trial|Continue"
-msgstr ""
+msgstr "ඉදිරියට"
msgid "Trial|Continue using the basic features of GitLab for free."
-msgstr ""
+msgstr "ගිට්ලà·à¶¶à·Š à·„à·’ මූලික විà·à·šà·‚à·à¶‚ග දිගටම නොමිලේ භà·à·€à·’ත෠කරන්න."
msgid "Trial|Country"
-msgstr ""
+msgstr "රට"
msgid "Trial|Dismiss"
-msgstr ""
+msgstr "ඉවත ලන්න"
msgid "Trial|GitLab Ultimate trial (optional)"
msgstr ""
msgid "Trial|Number of employees"
-msgstr ""
+msgstr "සේවක සංඛ්â€à¶ºà·à·€"
msgid "Trial|Please select a country"
msgstr ""
@@ -37976,7 +38744,7 @@ msgid "Trial|Successful trial activation image"
msgstr ""
msgid "Trial|Telephone number"
-msgstr ""
+msgstr "දුරකථන අංකය"
msgid "Trial|Upgrade to Ultimate to keep using GitLab with advanced features."
msgstr ""
@@ -38042,7 +38810,7 @@ msgid "Troubleshoot and monitor your application with tracing"
msgstr ""
msgid "Trusted"
-msgstr ""
+msgstr "විà·à·Šà·€à·à·ƒà·“"
msgid "Try again"
msgstr ""
@@ -38081,7 +38849,7 @@ msgid "Trying to communicate with your device. Plug it in (if you haven't alread
msgstr ""
msgid "Tuesday"
-msgstr ""
+msgstr "අඟහරුවà·à¶¯à·"
msgid "Tuning settings"
msgstr ""
@@ -38093,10 +38861,10 @@ msgid "Turn on"
msgstr ""
msgid "Twitter"
-msgstr ""
+msgstr "ට්විටර්"
msgid "Twitter:"
-msgstr ""
+msgstr "ට්විටර්:"
msgid "Two-Factor Authentication"
msgstr ""
@@ -38135,10 +38903,10 @@ msgid "Two-factor grace period"
msgstr ""
msgid "Type"
-msgstr ""
+msgstr "වර්ගය"
msgid "Type/State"
-msgstr ""
+msgstr "වර්ගය/තත්â€à·€à¶º"
msgid "U2F Devices (%{length})"
msgstr ""
@@ -38147,7 +38915,7 @@ msgid "U2F only works with HTTPS-enabled websites. Contact your administrator fo
msgstr ""
msgid "URL"
-msgstr ""
+msgstr "ඒ.ස.නි."
msgid "URL cannot be blank"
msgstr ""
@@ -38170,7 +38938,7 @@ msgstr ""
msgid "URL is triggered when repository is updated"
msgstr ""
-msgid "URL must be percent-encoded if neccessary."
+msgid "URL must be percent-encoded if necessary."
msgstr ""
msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
@@ -38300,7 +39068,7 @@ msgid "Unapproved the current merge request."
msgstr ""
msgid "Unarchive project"
-msgstr ""
+msgstr "ව්â€à¶ºà·à¶´à·˜à¶­à·’ය අසංරක්â€à·‚ණය"
msgid "Unarchiving the project will restore its members' 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} %{link_start}Learn more.%{link_end}"
msgstr ""
@@ -38324,7 +39092,7 @@ msgid "Uncommitted changes will be lost if you change branches. Do you want to c
msgstr ""
msgid "Undo"
-msgstr ""
+msgstr "පෙරසේ"
msgid "Undo Ignore"
msgstr ""
@@ -38333,7 +39101,7 @@ msgid "Undo ignore"
msgstr ""
msgid "Unexpected error"
-msgstr ""
+msgstr "අනපේක්â€à·‚ිත දà·à·‚යකි"
msgid "Unfollow"
msgstr ""
@@ -38351,19 +39119,19 @@ msgid "Units|s"
msgstr ""
msgid "Unknown"
-msgstr ""
+msgstr "නොදනී"
msgid "Unknown Error"
-msgstr ""
+msgstr "නොදන්න෠දà·à·‚යකි"
msgid "Unknown cache key"
-msgstr ""
+msgstr "නොදන්න෠නිහිත යතුරකි"
msgid "Unknown encryption strategy: %{encrypted_strategy}!"
msgstr ""
msgid "Unknown format"
-msgstr ""
+msgstr "නොදන්න෠ආකෘතියකි"
msgid "Unknown response text"
msgstr ""
@@ -38372,37 +39140,40 @@ msgid "Unknown screen"
msgstr ""
msgid "Unknown user"
-msgstr ""
+msgstr "නොදන්න෠පරිà·à·“ලකයෙකි"
msgid "Unless otherwise agreed to in writing with GitLab, by clicking \"Upload License\" you agree that your use of GitLab Software is subject to the %{eula_link_start}Terms of Service%{eula_link_end}."
msgstr ""
msgid "Unlimited"
-msgstr ""
+msgstr "අසීමිත"
msgid "Unlink"
msgstr ""
msgid "Unlock"
-msgstr ""
+msgstr "අගුළු හරින්න"
msgid "Unlock account"
+msgstr "ගිණුම අගුළු හරින්න"
+
+msgid "Unlock more features with GitLab Ultimate"
msgstr ""
msgid "Unlock the discussion"
-msgstr ""
+msgstr "à·ƒà·à¶šà¶ à·Šà¶¡à·à·€ අගුළු හරින්න"
msgid "Unlock this %{issuableDisplayName}? %{strongStart}Everyone%{strongEnd} will be able to comment."
msgstr ""
msgid "Unlocked"
-msgstr ""
+msgstr "අගුළු à·„à·à¶» ඇත"
msgid "Unlocked the discussion."
-msgstr ""
+msgstr "à·ƒà·à¶šà¶ à·Šà¶¡à·à·€ අගුළු à·„à·à¶» ඇත."
msgid "Unlocks the discussion."
-msgstr ""
+msgstr "à·ƒà·à¶šà¶ à·Šà¶¡à·à·€ අගුළු හරියි."
msgid "Unmarked this %{noun} as a draft."
msgstr ""
@@ -38411,7 +39182,7 @@ msgid "Unmarks this %{noun} as a draft."
msgstr ""
msgid "Unreachable"
-msgstr ""
+msgstr "ළඟ෠විය නොහà·à¶šà·’ය"
msgid "Unrecognized cluster type"
msgstr ""
@@ -38432,7 +39203,7 @@ msgid "Unstar"
msgstr ""
msgid "Unstarted"
-msgstr ""
+msgstr "ආරම්භ නොකළ"
msgid "Unsubscribe"
msgstr ""
@@ -38452,6 +39223,9 @@ msgstr ""
msgid "Unsubscribes from this %{quick_action_target}."
msgstr ""
+msgid "Unsupported sort value."
+msgstr ""
+
msgid "Unsupported todo type passed. Supported todo types are: %{todo_types}"
msgstr ""
@@ -38459,7 +39233,7 @@ msgid "Until revoked, expired personal access tokens pose a security risk."
msgstr ""
msgid "Unused"
-msgstr ""
+msgstr "භà·à·€à·’ත෠නොකළ"
msgid "Unused, previous indices: %{index_names} will be deleted after %{time} automatically."
msgstr ""
@@ -38468,7 +39242,7 @@ msgid "Unverified"
msgstr ""
msgid "Up to date"
-msgstr ""
+msgstr "යà·à·€à¶­à·Šà¶šà·à¶½à·“නයි"
msgid "Upcoming"
msgstr ""
@@ -38477,19 +39251,19 @@ msgid "Upcoming Release"
msgstr ""
msgid "Update"
-msgstr ""
+msgstr "යà·à·€à¶­à·Šà¶šà·à¶½"
msgid "Update %{sourcePath} file"
msgstr ""
msgid "Update Now"
-msgstr ""
+msgstr "දà·à¶±à·Š යà·à·€à¶­à·Šà¶šà·à¶½ කරන්න"
msgid "Update Scheduled…"
msgstr ""
msgid "Update all"
-msgstr ""
+msgstr "සියල්ල යà·à·€à¶­à·Šà¶šà·à¶½ කරන්න"
msgid "Update appearance settings"
msgstr ""
@@ -38507,7 +39281,7 @@ msgid "Update failed"
msgstr ""
msgid "Update it"
-msgstr ""
+msgstr "එය යà·à·€à¶­à·Šà¶šà·à¶½ කරන්න"
msgid "Update iteration"
msgstr ""
@@ -38516,10 +39290,10 @@ msgid "Update milestone"
msgstr ""
msgid "Update now"
-msgstr ""
+msgstr "දà·à¶±à·Š යà·à·€à¶­à·Šà¶šà·à¶½ කරන්න"
msgid "Update username"
-msgstr ""
+msgstr "පරිà·à·“ලක නà·à¶¸à¶º යà·à·€à¶­à·Šà¶šà·à¶½ කරන්න"
msgid "Update variable"
msgstr ""
@@ -38561,16 +39335,16 @@ msgid "Updated date"
msgstr ""
msgid "Updates"
-msgstr ""
+msgstr "යà·à·€à¶­à·Šà¶šà·à¶½"
msgid "Updating"
-msgstr ""
+msgstr "යà·à·€à¶­à·Šà¶šà·à¶½ වෙමින්"
msgid "Updating the attention request for %{username} failed."
msgstr ""
msgid "Updating…"
-msgstr ""
+msgstr "යà·à·€à¶­à·Šà¶šà·à¶½ වෙමින්…"
msgid "Upgrade offers available!"
msgstr ""
@@ -38579,22 +39353,22 @@ msgid "Upgrade your plan"
msgstr ""
msgid "Upload"
-msgstr ""
+msgstr "උඩුගත කරන්න"
msgid "Upload %{file_name} file"
msgstr ""
msgid "Upload CSV file"
-msgstr ""
+msgstr "CSV ගොනුව උඩුගත කරන්න"
msgid "Upload File"
-msgstr ""
+msgstr "ගොනුව උඩුගත කරන්න"
msgid "Upload License"
-msgstr ""
+msgstr "බලපත්â€à¶»à¶º උඩුගත කරන්න"
msgid "Upload New File"
-msgstr ""
+msgstr "නව ගොනුව උඩුගත කරන්න"
msgid "Upload a certificate for your domain with all intermediates"
msgstr ""
@@ -38606,7 +39380,7 @@ msgid "Upload an image"
msgstr ""
msgid "Upload file"
-msgstr ""
+msgstr "ගොනුව උඩුගත කරන්න"
msgid "Upload image"
msgstr ""
@@ -38680,9 +39454,12 @@ msgstr ""
msgid "UsageQuota|File attachments and smaller design graphics."
msgstr ""
-msgid "UsageQuota|Git repository."
+msgid "UsageQuota|From %{storage_enforcement_date} storage limits will apply to this namespace. View and manage your usage in %{strong_start}Group Settings &gt; Usage quotas%{strong_end}."
msgstr ""
+msgid "UsageQuota|Git repository."
+msgstr "ගිට් කà·à·‚්ඨය."
+
msgid "UsageQuota|Includes artifacts, repositories, wiki, uploads, and other items."
msgstr ""
@@ -38702,7 +39479,7 @@ msgid "UsageQuota|No CI minutes usage data available."
msgstr ""
msgid "UsageQuota|Packages"
-msgstr ""
+msgstr "ඇසුරුම්"
msgid "UsageQuota|Pending Members"
msgstr ""
@@ -38720,7 +39497,7 @@ msgid "UsageQuota|Purchased storage available"
msgstr ""
msgid "UsageQuota|Repository"
-msgstr ""
+msgstr "කà·à·‚්ඨය"
msgid "UsageQuota|Seats"
msgstr ""
@@ -38735,9 +39512,12 @@ msgid "UsageQuota|Something went wrong while fetching project storage statistics
msgstr ""
msgid "UsageQuota|Storage"
-msgstr ""
+msgstr "ආචයනය"
msgid "UsageQuota|Storage type"
+msgstr "ආචයන වර්ගය"
+
+msgid "UsageQuota|Storage used"
msgstr ""
msgid "UsageQuota|This is the total amount of storage used across your projects within this namespace."
@@ -38759,13 +39539,13 @@ msgid "UsageQuota|Total namespace storage used"
msgstr ""
msgid "UsageQuota|Unlimited"
-msgstr ""
+msgstr "අසීමිත"
msgid "UsageQuota|Uploads"
-msgstr ""
+msgstr "උඩුගත කිරීම්"
msgid "UsageQuota|Usage"
-msgstr ""
+msgstr "භà·à·€à·’තය"
msgid "UsageQuota|Usage Quotas"
msgstr ""
@@ -38822,7 +39602,7 @@ msgid "UsageTrends|Could not load the projects and groups chart. Please refresh
msgstr ""
msgid "UsageTrends|Groups"
-msgstr ""
+msgstr "සමූහ"
msgid "UsageTrends|Issues"
msgstr ""
@@ -38834,10 +39614,10 @@ msgid "UsageTrends|Items"
msgstr ""
msgid "UsageTrends|Merge requests"
-msgstr ""
+msgstr "සංයුක්ත ඉල්ලීම්"
msgid "UsageTrends|Month"
-msgstr ""
+msgstr "මà·à·ƒà¶º"
msgid "UsageTrends|No data available."
msgstr ""
@@ -38861,7 +39641,7 @@ msgid "UsageTrends|Pipelines total"
msgstr ""
msgid "UsageTrends|Projects"
-msgstr ""
+msgstr "ව්â€à¶ºà·à¶´à·˜à¶­à·’"
msgid "UsageTrends|There was an error fetching the cancelled pipelines. Please try again."
msgstr ""
@@ -38891,25 +39671,25 @@ msgid "UsageTrends|There was an error fetching the total pipelines. Please try a
msgstr ""
msgid "UsageTrends|Total groups"
-msgstr ""
+msgstr "මුළු සමූහ"
msgid "UsageTrends|Total projects"
-msgstr ""
+msgstr "මුළු ව්â€à¶ºà·à¶´à·˜à¶­à·’"
msgid "UsageTrends|Total projects & groups"
-msgstr ""
+msgstr "මුළු ව්â€à¶ºà·à¶´à·˜à¶­à·’ හ෠සමූහ"
msgid "UsageTrends|Users"
-msgstr ""
+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 .gitlab-ci.yml"
-msgstr ""
+msgstr ".gitlab-ci.yml භà·à·€à·’ත෠කරන්න"
msgid "Use GitLab Runner in AWS"
-msgstr ""
+msgstr "AWS à·„à·’ ගිට්ලà·à¶¶à·Š ධà·à·€à¶š භà·à·€à·’ත෠කරන්න"
msgid "Use a one-time password authenticator on your mobile device or computer to enable two-factor authentication (2FA)."
msgstr ""
@@ -38924,7 +39704,7 @@ msgid "Use cURL"
msgstr ""
msgid "Use custom color #FF0000"
-msgstr ""
+msgstr "#FF0000 අභිරුචි පà·à¶§ භà·à·€à·’ත෠කරන්න"
msgid "Use double quotes for multiple keywords, such as %{code_open}\"your search\"%{code_close}"
msgstr ""
@@ -38935,14 +39715,20 @@ msgstr ""
msgid "Use hashed storage paths for newly created and renamed repositories. Always enabled since 13.0."
msgstr ""
+msgid "Use issue count"
+msgstr ""
+
+msgid "Use issue weight"
+msgstr ""
+
msgid "Use one line per URI"
msgstr ""
msgid "Use primary email (%{email})"
-msgstr ""
+msgstr "ප්â€à¶»à·à¶®à¶¸à·’ක වි-තà·à¶´à·‘ල භà·à·€à·’ත෠කරන්න (%{email})"
msgid "Use shortcuts"
-msgstr ""
+msgstr "කෙටිමං භà·à·€à·’ත෠කරන්න"
msgid "Use slash commands."
msgstr ""
@@ -38993,7 +39779,7 @@ msgid "Used to help configure your identity provider"
msgstr ""
msgid "User"
-msgstr ""
+msgstr "පරිà·à·“ලක"
msgid "User %{current_user_username} has started impersonating %{username}"
msgstr ""
@@ -39005,16 +39791,16 @@ msgid "User %{user} was removed from %{group}."
msgstr ""
msgid "User ID"
-msgstr ""
+msgstr "පරිà·à·“ලක à·„à·à¶³à·”."
msgid "User OAuth applications"
msgstr ""
msgid "User Settings"
-msgstr ""
+msgstr "පරිà·à·“ලක à·ƒà·à¶šà·ƒà·”ම්"
msgid "User and IP rate limits"
-msgstr ""
+msgstr "පරිà·à·“ලක හ෠අ.ජà·.කෙ. අනුපà·à¶­ සීමà·"
msgid "User cap"
msgstr ""
@@ -39029,28 +39815,28 @@ msgid "User does not have a pending request"
msgstr ""
msgid "User identity was successfully created."
-msgstr ""
+msgstr "පරිà·à·“ලකයà·à¶œà·š අනන්â€à¶ºà¶­à·à·€à¶º à·ƒà·à¶»à·Šà¶®à¶šà·€ සෑදිණි."
msgid "User identity was successfully removed."
-msgstr ""
+msgstr "පරිà·à·“ලකයà·à¶œà·š අනන්â€à¶ºà¶­à·à·€à¶º à·ƒà·à¶»à·Šà¶®à¶šà·€ ඉවත් කෙරිණි."
msgid "User identity was successfully updated."
-msgstr ""
+msgstr "පරිà·à·“ලකයà·à¶œà·š අනන්â€à¶ºà¶­à·à·€à¶º à·ƒà·à¶»à·Šà¶®à¶šà·€ යà·à·€à¶­à·Šà¶šà·à¶½ කෙරිණි."
msgid "User is not allowed to resolve thread"
msgstr ""
msgid "User key"
-msgstr ""
+msgstr "පරිà·à·“ලක යතුර"
msgid "User key was successfully removed."
-msgstr ""
+msgstr "පරිà·à·“ලකයà·à¶œà·š යතුර à·ƒà·à¶»à·Šà¶®à¶šà·€ ඉවත් කෙරිණි."
msgid "User list %{name} will be removed. Are you sure?"
msgstr ""
msgid "User map"
-msgstr ""
+msgstr "පරිà·à·“ලක සිතියම"
msgid "User pipeline minutes were successfully reset."
msgstr ""
@@ -39059,7 +39845,7 @@ msgid "User restrictions"
msgstr ""
msgid "User settings"
-msgstr ""
+msgstr "පරිà·à·“ලක à·ƒà·à¶šà·ƒà·”ම්"
msgid "User was successfully created."
msgstr ""
@@ -39080,37 +39866,37 @@ msgid "User-based escalation rules must have a user with access to the project"
msgstr ""
msgid "UserAvailability|%{author} %{spanStart}(Busy)%{spanEnd}"
-msgstr ""
+msgstr "%{author} %{spanStart}(කà·à¶»à·Šà¶ºà¶¶à·„ුලයි)%{spanEnd}"
msgid "UserAvailability|%{author} (Busy)"
-msgstr ""
+msgstr "%{author} (කà·à¶»à·Šà¶ºà¶¶à·„ුලයි)"
msgid "UserAvailability|(Busy)"
-msgstr ""
+msgstr "(කà·à¶»à·Šà¶ºà¶¶à·„ුලයි)"
msgid "UserLists|Add"
-msgstr ""
+msgstr "එකතු"
msgid "UserLists|Add Users"
-msgstr ""
+msgstr "පරිà·à·“ලකයින් එක්කරන්න"
msgid "UserLists|Add users"
-msgstr ""
+msgstr "පරිà·à·“ලකයින් එක්කරන්න"
msgid "UserLists|Cancel"
-msgstr ""
+msgstr "අවලංගු කරන්න"
msgid "UserLists|Create"
-msgstr ""
+msgstr "à·ƒà·à¶¯à¶±à·Šà¶±"
msgid "UserLists|Define a set of users to be used within feature flag strategies"
msgstr ""
msgid "UserLists|Edit"
-msgstr ""
+msgstr "සංස්කරණය"
msgid "UserLists|Edit %{name}"
-msgstr ""
+msgstr "%{name} සංස්කරණය"
msgid "UserLists|Enter a comma separated list of user IDs. These IDs should be the users of the system in which the feature flag is set, not GitLab IDs"
msgstr ""
@@ -39128,7 +39914,7 @@ msgid "UserLists|Loading user lists"
msgstr ""
msgid "UserLists|Name"
-msgstr ""
+msgstr "නම"
msgid "UserLists|New list"
msgstr ""
@@ -39137,19 +39923,19 @@ msgid "UserLists|New user list"
msgstr ""
msgid "UserLists|Save"
-msgstr ""
+msgstr "සුරකින්න"
msgid "UserLists|There are no users"
-msgstr ""
+msgstr "පරිà·à·“ලකයින් නà·à¶­"
msgid "UserLists|There was an error fetching the user lists."
msgstr ""
msgid "UserLists|User ID"
-msgstr ""
+msgstr "පරිà·à·“ලක à·„à·à¶³à·”."
msgid "UserLists|User IDs"
-msgstr ""
+msgstr "පරිà·à·“ලක à·„à·à¶³à·”."
msgid "UserLists|User Lists"
msgstr ""
@@ -39164,28 +39950,28 @@ msgid "UserList|created %{timeago}"
msgstr ""
msgid "UserProfile|(Busy)"
-msgstr ""
+msgstr "(කà·à¶»à·Šà¶ºà¶¶à·„ුලයි)"
msgid "UserProfile|Activity"
-msgstr ""
+msgstr "ක්â€à¶»à·’යà·à¶šà·à¶»à¶šà¶¸"
msgid "UserProfile|Already reported for abuse"
msgstr ""
msgid "UserProfile|Blocked user"
-msgstr ""
+msgstr "අවහිර කළ පරිà·à·“ලක"
msgid "UserProfile|Bot activity"
-msgstr ""
+msgstr "ස්වයංක්â€à¶»à¶¸à¶½à·šà¶›à¶ºà·š ක්â€à¶»à·’යà·à¶šà·à¶»à¶šà¶¸"
msgid "UserProfile|Contributed projects"
-msgstr ""
+msgstr "දà·à¶ºà¶š වූ ව්â€à¶ºà·à¶´à·˜à¶­à·’"
msgid "UserProfile|Edit profile"
-msgstr ""
+msgstr "පà·à¶­à·’කඩ සංස්කරණය"
msgid "UserProfile|Explore public groups to find projects to contribute to."
-msgstr ""
+msgstr "දà·à¶ºà¶šà¶­à·Šà·€à¶ºà¶§ ව්â€à¶ºà·à¶´à·˜à¶­à·’ සොය෠ගà·à¶±à·“මට ප්â€à¶»à·ƒà·’ද්ධ සමූහ ගවේෂණය කරන්න."
msgid "UserProfile|Followers"
msgstr ""
@@ -39194,25 +39980,25 @@ msgid "UserProfile|Following"
msgstr ""
msgid "UserProfile|Groups"
-msgstr ""
+msgstr "සමූහ"
msgid "UserProfile|Groups are the best way to manage projects and members."
-msgstr ""
+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 ""
+msgstr "වඩà·à¶­à·Šà¶¸ මෑත ක්â€à¶»à·’යà·à¶šà·à¶»à¶šà¶¸"
msgid "UserProfile|No snippets found."
msgstr ""
msgid "UserProfile|Overview"
-msgstr ""
+msgstr "දළ විà·à·Šà¶½à·šà·‚ණය"
msgid "UserProfile|Personal projects"
-msgstr ""
+msgstr "පෞද්ගලික ව්â€à¶ºà·à¶´à·˜à¶­à·’"
msgid "UserProfile|Pronounced as: %{pronunciation}"
msgstr ""
@@ -39221,7 +40007,7 @@ msgid "UserProfile|Report abuse"
msgstr ""
msgid "UserProfile|Retry"
-msgstr ""
+msgstr "යළි උත්සà·à·„ය"
msgid "UserProfile|Snippets"
msgstr ""
@@ -39242,19 +40028,19 @@ msgid "UserProfile|This user doesn't have any followers."
msgstr ""
msgid "UserProfile|This user doesn't have any personal projects"
-msgstr ""
+msgstr "මෙම පරිà·à·“ලකයà·à¶§ කිසිදු පෞද්ගලික ව්â€à¶ºà·à¶´à·˜à¶­à·’යක් නà·à¶­"
msgid "UserProfile|This user has a private profile"
-msgstr ""
+msgstr "මෙම පරිà·à·“ලකයà·à¶§ පුද්ගලික පà·à¶­à·’කඩක් ඇත"
msgid "UserProfile|This user hasn't contributed to any projects"
-msgstr ""
+msgstr "මෙම පරිà·à·“ලකය෠කිසිදු ව්â€à¶ºà·à¶´à·˜à¶­à·’යකට දà·à¶ºà¶š වී නà·à¶­"
msgid "UserProfile|This user hasn't starred any projects"
msgstr ""
msgid "UserProfile|This user is blocked"
-msgstr ""
+msgstr "මෙම පරිà·à·“ලකය෠අවහිර කර ඇත"
msgid "UserProfile|This user isn't following other users."
msgstr ""
@@ -39263,7 +40049,7 @@ msgid "UserProfile|Unconfirmed user"
msgstr ""
msgid "UserProfile|View all"
-msgstr ""
+msgstr "සියල්ල දකින්න"
msgid "UserProfile|View user in admin area"
msgstr ""
@@ -39278,7 +40064,7 @@ msgid "UserProfile|You do not have any followers."
msgstr ""
msgid "UserProfile|You haven't created any personal projects."
-msgstr ""
+msgstr "ඔබ කිසිදු පෞද්ගලික ව්â€à¶ºà·à¶´à·˜à¶­à·’යක් à·ƒà·à¶¯à· නà·à¶­."
msgid "UserProfile|You haven't created any snippets."
msgstr ""
@@ -39293,27 +40079,30 @@ msgid "UserProfile|made a private contribution"
msgstr ""
msgid "Username"
-msgstr ""
+msgstr "පරිà·à·“ලක නà·à¶¸à¶º"
msgid "Username (optional)"
-msgstr ""
+msgstr "පරිà·à·“ලක නà·à¶¸à¶º (විකල්ප)"
msgid "Username is already taken."
-msgstr ""
+msgstr "පරිà·à·“ලක නà·à¶¸à¶º ගෙන ඇත."
msgid "Username is available."
msgstr ""
msgid "Username or email"
-msgstr ""
+msgstr "පරිà·à·“ලක නà·à¶¸à¶º හ෠වි-තà·à¶´à·‘ල"
msgid "Username:"
-msgstr ""
+msgstr "පරිà·à·“ලක නà·à¶¸à¶º:"
msgid "Username: %{username}"
-msgstr ""
+msgstr "පරිà·à·“ලක නà·à¶¸à¶º: %{username}"
msgid "Users"
+msgstr "පරිà·à·’ලකයින්"
+
+msgid "Users API rate limit"
msgstr ""
msgid "Users can launch a development environment from a GitLab browser tab when the %{linkStart}Gitpod%{linkEnd} integration is enabled."
@@ -39326,7 +40115,7 @@ msgid "Users can render diagrams in AsciiDoc, Markdown, reStructuredText, and Te
msgstr ""
msgid "Users in License"
-msgstr ""
+msgstr "බලපත්â€à¶»à¶ºà·™à·„à·’ පරිà·à·“ලකයින්"
msgid "Users or groups set as approvers in the project's or merge request's settings."
msgstr ""
@@ -39338,7 +40127,7 @@ msgid "Users requesting access to"
msgstr ""
msgid "Users to exclude from the rate limit"
-msgstr ""
+msgstr "අනුපà·à¶­ සීමà·à·€à·™à¶±à·Š බà·à·„à·à¶» කිරීමට පරිà·à·“ලකයින්"
msgid "Users were successfully added."
msgstr ""
@@ -39350,7 +40139,7 @@ msgid "UsersSelect|%{name} + %{length} more"
msgstr ""
msgid "UsersSelect|Any User"
-msgstr ""
+msgstr "ඕනෑම පරිà·à·“ලකයෙකු"
msgid "UsersSelect|Assignee"
msgstr ""
@@ -39398,7 +40187,7 @@ msgid "Validations failed."
msgstr ""
msgid "Value"
-msgstr ""
+msgstr "අගය"
msgid "Value Stream Analytics"
msgstr ""
@@ -39440,10 +40229,10 @@ msgid "ValueStreamAnalytics|Average number of deployments to production per day.
msgstr ""
msgid "ValueStreamAnalytics|Dashboard"
-msgstr ""
+msgstr "උපකරණ පුවරුව"
msgid "ValueStreamAnalytics|Go to docs"
-msgstr ""
+msgstr "ප්â€à¶»à¶½à·šà¶›à¶± වෙත යන්න"
msgid "ValueStreamAnalytics|Items in Value Stream Analytics are currently filtered by their creation time. There is an %{epic_link_start}epic%{epic_link_end} that will change the Value Stream Analytics date filter to use the end event time for the selected stage."
msgstr ""
@@ -39479,7 +40268,7 @@ msgid "ValueStreamEvent|Start"
msgstr ""
msgid "ValueStreamEvent|Stop"
-msgstr ""
+msgstr "නවත්වන්න"
msgid "ValueStream|The Default Value Stream cannot be deleted"
msgstr ""
@@ -39545,10 +40334,10 @@ msgid "Verify configuration"
msgstr ""
msgid "Version"
-msgstr ""
+msgstr "අනුවà·à¶¯à¶º"
msgid "Version %{versionNumber}"
-msgstr ""
+msgstr "අනුවà·à¶¯à¶º %{versionNumber}"
msgid "Version %{versionNumber} (latest)"
msgstr ""
@@ -39641,6 +40430,9 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View group pipeline usage quota"
+msgstr ""
+
msgid "View incident details at"
msgstr ""
@@ -39793,6 +40585,9 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
+msgid "Vulnerability"
+msgstr ""
+
msgid "Vulnerability Report"
msgstr ""
@@ -39844,21 +40639,36 @@ msgstr ""
msgid "VulnerabilityManagement|An unverified non-confirmed finding"
msgstr ""
-msgid "VulnerabilityManagement|Change status"
+msgid "VulnerabilityManagement|At least one identifier is required"
msgstr ""
+msgid "VulnerabilityManagement|Change status"
+msgstr "තත්â€à·€à¶º වෙනස් කරන්න"
+
msgid "VulnerabilityManagement|Could not process %{issueReference}: %{errorMessage}."
msgstr ""
msgid "VulnerabilityManagement|Create Jira issue"
msgstr ""
+msgid "VulnerabilityManagement|Enter a name"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE code"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE identifier URL"
+msgstr ""
+
msgid "VulnerabilityManagement|Fetching linked Jira issues"
msgstr ""
msgid "VulnerabilityManagement|Manually add a vulnerability entry into the vulnerability report."
msgstr ""
+msgid "VulnerabilityManagement|Name is a required field"
+msgstr ""
+
msgid "VulnerabilityManagement|Needs triage"
msgstr ""
@@ -39874,6 +40684,18 @@ msgstr ""
msgid "VulnerabilityManagement|Select a method"
msgstr ""
+msgid "VulnerabilityManagement|Select a severity level"
+msgstr ""
+
+msgid "VulnerabilityManagement|Select a status"
+msgstr ""
+
+msgid "VulnerabilityManagement|Severity is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Something went wrong while creating vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -39898,6 +40720,12 @@ msgstr ""
msgid "VulnerabilityManagement|Something went wrong, could not update vulnerability state."
msgstr ""
+msgid "VulnerabilityManagement|Status is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Submit vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Summary, detailed description, steps to reproduce, etc."
msgstr ""
@@ -39914,13 +40742,13 @@ msgid "VulnerabilityManagement|invalid issue link or ID"
msgstr ""
msgid "VulnerabilityStatusTypes|All statuses"
-msgstr ""
+msgstr "සියළු තත්ව"
msgid "VulnerabilityStatusTypes|Confirmed"
msgstr ""
msgid "VulnerabilityStatusTypes|Dismissed"
-msgstr ""
+msgstr "ඉවත ලූ"
msgid "VulnerabilityStatusTypes|Needs triage"
msgstr ""
@@ -39929,13 +40757,13 @@ msgid "VulnerabilityStatusTypes|Resolved"
msgstr ""
msgid "Vulnerability|%{scannerName} (version %{scannerVersion})"
-msgstr ""
+msgstr "%{scannerName} (අනුවà·à¶¯à¶º %{scannerVersion})"
msgid "Vulnerability|Activity"
-msgstr ""
+msgstr "ක්â€à¶»à·’යà·à¶šà·à¶»à¶šà¶¸"
msgid "Vulnerability|Actual Response"
-msgstr ""
+msgstr "à·ƒà·à¶¶à·‘ ප්â€à¶»à¶­à·’චà·à¶»à¶º"
msgid "Vulnerability|Actual received response is the one received when this fault was detected"
msgstr ""
@@ -39944,7 +40772,7 @@ msgid "Vulnerability|Add another identifier"
msgstr ""
msgid "Vulnerability|Additional Info"
-msgstr ""
+msgstr "අතිරේක තොරතුරු"
msgid "Vulnerability|Bug Bounty"
msgstr ""
@@ -39959,7 +40787,7 @@ msgid "Vulnerability|Code Review"
msgstr ""
msgid "Vulnerability|Comments"
-msgstr ""
+msgstr "අදහස්"
msgid "Vulnerability|Crash address"
msgstr ""
@@ -39971,7 +40799,7 @@ msgid "Vulnerability|Crash type"
msgstr ""
msgid "Vulnerability|Description"
-msgstr ""
+msgstr "සවිස්තරය"
msgid "Vulnerability|Details"
msgstr ""
@@ -39983,13 +40811,13 @@ msgid "Vulnerability|Detection method"
msgstr ""
msgid "Vulnerability|Download"
-msgstr ""
+msgstr "බà·à¶œà¶±à·Šà¶±"
msgid "Vulnerability|Enter the associated CVE or CWE entries for this vulnerability."
msgstr ""
msgid "Vulnerability|Evidence"
-msgstr ""
+msgstr "à·ƒà·à¶šà·Šâ€à·‚ිය"
msgid "Vulnerability|External Security Report"
msgstr ""
@@ -39998,7 +40826,7 @@ msgid "Vulnerability|False positive detected"
msgstr ""
msgid "Vulnerability|File"
-msgstr ""
+msgstr "ගොනුව"
msgid "Vulnerability|GitLab Security Report"
msgstr ""
@@ -40025,16 +40853,16 @@ msgid "Vulnerability|Learn more about this vulnerability and the best way to res
msgstr ""
msgid "Vulnerability|Links"
-msgstr ""
+msgstr "සබà·à¶³à·’"
msgid "Vulnerability|Method"
-msgstr ""
+msgstr "ක්â€à¶»à¶¸à¶º"
msgid "Vulnerability|Namespace"
msgstr ""
msgid "Vulnerability|Project"
-msgstr ""
+msgstr "ව්â€à¶ºà·à¶´à·˜à¶­à·’ය"
msgid "Vulnerability|Remove identifier row"
msgstr ""
@@ -40043,10 +40871,10 @@ msgid "Vulnerability|Reproduction Assets"
msgstr ""
msgid "Vulnerability|Request"
-msgstr ""
+msgstr "ඉල්ලීම"
msgid "Vulnerability|Request/Response"
-msgstr ""
+msgstr "ඉල්ලීම/ප්â€à¶»à¶­à·’චà·à¶»à¶º"
msgid "Vulnerability|Scanner Provider"
msgstr ""
@@ -40067,7 +40895,7 @@ msgid "Vulnerability|Severity"
msgstr ""
msgid "Vulnerability|Status"
-msgstr ""
+msgstr "තත්â€à·€à¶º"
msgid "Vulnerability|The scanner determined this vulnerability to be a false positive. Verify the evaluation before changing its status. %{linkStart}Learn more about false positive detection.%{linkEnd}"
msgstr ""
@@ -40076,7 +40904,7 @@ msgid "Vulnerability|The unmodified response is the original response that had n
msgstr ""
msgid "Vulnerability|Tool"
-msgstr ""
+msgstr "මෙවලම"
msgid "Vulnerability|Training"
msgstr ""
@@ -40091,10 +40919,13 @@ msgid "Vulnerability|View training"
msgstr ""
msgid "WARNING:"
+msgstr "අවවà·à¶¯à¶ºà¶ºà·’:"
+
+msgid "WARNING: This snippet contains hidden files which might be used to mask malicious behavior. Exercise caution if cloning and executing code from this snippet."
msgstr ""
msgid "Wait for the file to load to copy its contents"
-msgstr ""
+msgstr "ගොනුව එහි අන්තර්ගතය පිටපත් වීමට පූරණය වන තෙක් රà·à¶³à·™à¶±à·Šà¶±"
msgid "Waiting for merge (open and assigned)"
msgstr ""
@@ -40106,10 +40937,10 @@ msgid "Want to see the data? Please ask an administrator for access."
msgstr ""
msgid "Warning"
-msgstr ""
+msgstr "අවවà·à¶¯à¶ºà¶ºà·’"
msgid "Warning:"
-msgstr ""
+msgstr "අවවà·à¶¯à¶ºà¶ºà·’:"
msgid "Warning: Displaying this diagram might cause performance issues on this page."
msgstr ""
@@ -40151,10 +40982,10 @@ msgid "We detected potential spam in the %{humanized_resource_name}. Please solv
msgstr ""
msgid "We don't have enough data to show this stage."
-msgstr ""
+msgstr "මෙම අදියර පෙන්වීමට අපට ප්â€à¶»à¶¸à·à¶«à·€à¶­à·Š දත්ත නà·à¶­."
msgid "We have found the following errors:"
-msgstr ""
+msgstr "පහත සඳහන් දà·à·‚ අපට හමුව ඇත:"
msgid "We heard back from your device. You have been authenticated."
msgstr ""
@@ -40223,7 +41054,7 @@ msgid "WebIDE|Go to fork"
msgstr ""
msgid "WebIDE|Merge request"
-msgstr ""
+msgstr "සංයුක්ත ඉල්ලීම"
msgid "WebIDE|This project does not accept unsigned commits."
msgstr ""
@@ -40312,15 +41143,27 @@ msgstr ""
msgid "Webhooks|An issue is created, updated, closed, or reopened."
msgstr ""
-msgid "Webhooks|Comments"
+msgid "Webhooks|Are you sure you want to delete this group hook?"
msgstr ""
-msgid "Webhooks|Confidential comments"
+msgid "Webhooks|Are you sure you want to delete this project hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this webhook?"
msgstr ""
+msgid "Webhooks|Comments"
+msgstr "අදහස්"
+
+msgid "Webhooks|Confidential comments"
+msgstr "විà·à·Šà·€à·ƒà¶±à·“ය අදහස්"
+
msgid "Webhooks|Confidential issues events"
msgstr ""
+msgid "Webhooks|Delete webhook"
+msgstr ""
+
msgid "Webhooks|Deployment events"
msgstr ""
@@ -40358,7 +41201,7 @@ msgid "Webhooks|Push to the repository."
msgstr ""
msgid "Webhooks|Releases events"
-msgstr ""
+msgstr "නිකුතු සිදුවීම්"
msgid "Webhooks|SSL verification"
msgstr ""
@@ -40367,7 +41210,7 @@ msgid "Webhooks|Secret token"
msgstr ""
msgid "Webhooks|Subgroup events"
-msgstr ""
+msgstr "උපසමූහ සිදුවීම්"
msgid "Webhooks|Tag push events"
msgstr ""
@@ -40385,7 +41228,7 @@ msgid "Webhooks|Trigger"
msgstr ""
msgid "Webhooks|URL"
-msgstr ""
+msgstr "ඒ.ස.නි."
msgid "Webhooks|URL must be percent-encoded if it contains one or more special characters."
msgstr ""
@@ -40406,16 +41249,16 @@ msgid "Webhooks|Wiki page events"
msgstr ""
msgid "Website:"
-msgstr ""
+msgstr "වියමන අඩවිය:"
msgid "Wednesday"
-msgstr ""
+msgstr "බදà·à¶¯à·"
msgid "Weekday"
-msgstr ""
+msgstr "සතියේ දවස"
msgid "Weeks"
-msgstr ""
+msgstr "සති"
msgid "Weight"
msgstr ""
@@ -40427,16 +41270,16 @@ msgid "Welcome back! Your account had been deactivated due to inactivity but is
msgstr ""
msgid "Welcome to GitLab"
-msgstr ""
+msgstr "ගිට්ලà·à¶¶à·Š වෙත à·ƒà·à¶¯à¶»à¶ºà·™à¶±à·Š පිළිගනිමු"
msgid "Welcome to GitLab, %{first_name}!"
-msgstr ""
+msgstr "%{first_name}, ගිට්ලà·à¶¶à·Š වෙත à·ƒà·à¶¯à¶»à¶ºà·™à¶±à·Š පිළිගන්නවà·!"
msgid "Welcome to GitLab,%{br_tag}%{name}!"
-msgstr ""
+msgstr "%{br_tag}%{name}, ගිට්ලà·à¶¶à·Š වෙත à·ƒà·à¶¯à¶»à¶ºà·™à¶±à·Š පිළිගන්නවà·!"
msgid "Welcome, %{name}!"
-msgstr ""
+msgstr "ආයුබà·à·€à¶±à·Š, %{name}!"
msgid "What are CI/CD minutes?"
msgstr ""
@@ -40454,7 +41297,7 @@ msgid "What are you searching for?"
msgstr ""
msgid "What does this command do?"
-msgstr ""
+msgstr "මෙම විධà·à¶±à¶º කරන්නේ කුමක්ද?"
msgid "What is Auto DevOps?"
msgstr ""
@@ -40472,19 +41315,19 @@ msgid "What is time tracking?"
msgstr ""
msgid "What is your job title? (optional)"
-msgstr ""
+msgstr "ඔබගේ රà·à¶šà·’යà·à·€ කුමක්ද? (විකල්ප)"
msgid "What templates can I create?"
msgstr ""
msgid "What will you use this group for?"
-msgstr ""
+msgstr "ඔබ මෙම සමූහය භà·à·€à·’ත෠කරන්නේ කුමක් සඳහà·à¶¯?"
msgid "What would you like to do?"
-msgstr ""
+msgstr "ඔබ කිරීමට කà·à¶¸à¶­à·’ කුමක්ද?"
msgid "What's new"
-msgstr ""
+msgstr "මොනවà·à¶¯ අළුත්"
msgid "When a deployment job is successful, skip older deployment jobs that are still pending."
msgstr ""
@@ -40554,6 +41397,9 @@ msgstr ""
msgid "Wiki"
msgstr ""
+msgid "Wiki page"
+msgstr ""
+
msgid "Wiki page was successfully created."
msgstr ""
@@ -40567,16 +41413,16 @@ msgid "WikiClone|Clone your wiki"
msgstr ""
msgid "WikiClone|Git Access"
-msgstr ""
+msgstr "ගිට් ප්â€à¶»à·€à·šà·à¶º"
msgid "WikiClone|Install Gollum"
-msgstr ""
+msgstr "ගොලුම් ස්ථà·à¶´à¶±à¶º"
msgid "WikiClone|Start Gollum and edit locally"
-msgstr ""
+msgstr "ගොලුම් අරඹ෠ස්ථà·à¶±à·“යව සංස්කරණය කරන්න"
msgid "WikiEdit|There is already a page with the same title in that path."
-msgstr ""
+msgstr "සමà·à¶± සිරà·à·ƒà·’ය සහිත පිටුවක් දà·à¶±à¶§à¶¸à¶­à·Š එම මà·à¶»à·Šà¶œà¶ºà·š ඇත."
msgid "WikiEmptyIssueMessage|Suggest wiki improvement"
msgstr ""
@@ -40600,16 +41446,16 @@ msgid "WikiEmpty|A wiki is where you can store all the details about your projec
msgstr ""
msgid "WikiEmpty|Confluence is enabled"
-msgstr ""
+msgstr "කොන්ෆ්ලුවන්ස් සබල කර ඇත"
msgid "WikiEmpty|Create your first page"
-msgstr ""
+msgstr "ඔබගේ පළමු පිටුව à·ƒà·à¶¯à¶±à·Šà¶±"
msgid "WikiEmpty|Enable the Confluence Wiki integration"
msgstr ""
msgid "WikiEmpty|Go to Confluence"
-msgstr ""
+msgstr "කොන්ෆ්ලුවන්ස් වෙත යන්න"
msgid "WikiEmpty|Suggest wiki improvement"
msgstr ""
@@ -40636,16 +41482,16 @@ msgid "WikiEmpty|You've enabled the Confluence Workspace integration. Your wiki
msgstr ""
msgid "WikiHistoricalPage|This is an old version of this page."
-msgstr ""
+msgstr "මෙය මෙම පිටුවේ පරණ අනුවà·à¶¯à¶ºà¶šà·’."
msgid "WikiHistoricalPage|You can view the %{most_recent_link} or browse the %{history_link}."
-msgstr ""
+msgstr "ඔබට %{most_recent_link} දà·à¶šà·“මට à·„à· %{history_link} පිරික්සීමට à·„à·à¶šà·’ය."
msgid "WikiHistoricalPage|history"
-msgstr ""
+msgstr "ඉතිහà·à·ƒà¶º"
msgid "WikiHistoricalPage|most recent version"
-msgstr ""
+msgstr "වඩà·à¶­à·Šà¶¸ මෑත අනුවà·à¶¯à¶º"
msgid "WikiPageConfirmDelete|Are you sure you want to delete this page?"
msgstr ""
@@ -40659,26 +41505,26 @@ msgstr ""
msgid "WikiPageConflictMessage|Someone edited the page the same time you did. Please check out %{wikiLinkStart}the page%{wikiLinkEnd} and make sure your changes will not unintentionally remove theirs."
msgstr ""
-msgid "WikiPage|An error occured while trying to render the content editor. Please try again later."
+msgid "WikiPage|An error occurred while trying to render the content editor. Please try again later."
msgstr ""
msgid "WikiPage|Are you sure you want to switch back to the classic editor?"
msgstr ""
msgid "WikiPage|Cancel"
-msgstr ""
+msgstr "අවලංගු කරන්න"
msgid "WikiPage|Commit message"
msgstr ""
msgid "WikiPage|Content"
-msgstr ""
+msgstr "අන්තර්ගතය"
msgid "WikiPage|Create %{pageTitle}"
-msgstr ""
+msgstr "%{pageTitle} à·ƒà·à¶¯à¶±à·Šà¶±"
msgid "WikiPage|Create page"
-msgstr ""
+msgstr "පිටුව à·ƒà·à¶¯à¶±à·Šà¶±"
msgid "WikiPage|Edit rich text"
msgstr ""
@@ -40687,10 +41533,10 @@ msgid "WikiPage|Edit source"
msgstr ""
msgid "WikiPage|Format"
-msgstr ""
+msgstr "ආකෘතිය"
msgid "WikiPage|Get a richer editing experience"
-msgstr ""
+msgstr "පොහොසත් සංස්කරණ අත්දà·à¶šà·“මක් ගන්න"
msgid "WikiPage|Keep editing"
msgstr ""
@@ -40699,13 +41545,13 @@ msgid "WikiPage|Learn more."
msgstr ""
msgid "WikiPage|Page title"
-msgstr ""
+msgstr "පිටුවේ සිරà·à·ƒà·’ය"
msgid "WikiPage|Retry"
-msgstr ""
+msgstr "යළි උත්සà·à·„ය"
msgid "WikiPage|Save changes"
-msgstr ""
+msgstr "වෙනස්කම් සුරකින්න"
msgid "WikiPage|Switch me back to the classic editor."
msgstr ""
@@ -40726,7 +41572,7 @@ msgid "WikiPage|Tip: You can specify the full path for the new file. We will aut
msgstr ""
msgid "WikiPage|Title"
-msgstr ""
+msgstr "සිරà·à·ƒà·’ය"
msgid "WikiPage|To link to a (new) page, simply type %{linkExample}. More examples are in the %{linkStart}documentation%{linkEnd}."
msgstr ""
@@ -40735,49 +41581,49 @@ msgid "WikiPage|Try the new visual Markdown editor. Read the %{linkStart}documen
msgstr ""
msgid "WikiPage|Try this later"
-msgstr ""
+msgstr "පසුව උත්සà·à·„ කරන්න"
msgid "WikiPage|Update %{pageTitle}"
-msgstr ""
+msgstr "%{pageTitle} යà·à·€à¶­à·Šà¶šà·à¶½"
msgid "WikiPage|Use the new editor"
msgstr ""
msgid "WikiPage|Write your content or drag files here…"
-msgstr ""
+msgstr "ඔබගේ අන්තර්ගතය ලියන්න හ෠ගොනු මෙතà·à¶±à¶§ අදින්න…"
msgid "Wikis"
msgstr ""
msgid "Wiki|Create New Page"
-msgstr ""
+msgstr "නව පිටුවක් à·ƒà·à¶¯à¶±à·Šà¶±"
msgid "Wiki|Created date"
-msgstr ""
+msgstr "සෑදූ දිනය"
msgid "Wiki|Edit Page"
-msgstr ""
+msgstr "පිටුව සංස්කරණය"
msgid "Wiki|New page"
-msgstr ""
+msgstr "නව පිටුව"
msgid "Wiki|Page history"
-msgstr ""
+msgstr "පිටුවේ ඉතිහà·à·ƒà¶º"
msgid "Wiki|Page version"
-msgstr ""
+msgstr "පිටුවේ අනුවà·à¶¯à¶º"
msgid "Wiki|Pages"
-msgstr ""
+msgstr "පිටු"
msgid "Wiki|The sidebar failed to load. You can reload the page to try again."
msgstr ""
msgid "Wiki|Title"
-msgstr ""
+msgstr "සිරà·à·ƒà·’ය"
msgid "Wiki|View All Pages"
-msgstr ""
+msgstr "සියළු පිටු දකින්න"
msgid "Wiki|Wiki Pages"
msgstr ""
@@ -40818,6 +41664,18 @@ msgstr ""
msgid "WorkItem|New Task"
msgstr ""
+msgid "WorkItem|Something went wrong when creating a work item. Please try again"
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching the work item. Please try again."
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching work item types. Please try again"
+msgstr ""
+
+msgid "WorkItem|Type"
+msgstr ""
+
msgid "WorkItem|Work Items"
msgstr ""
@@ -40828,25 +41686,25 @@ msgid "Would you like to try auto-generating a branch name?"
msgstr ""
msgid "Write"
-msgstr ""
+msgstr "ලියන්න"
msgid "Write a comment or drag your files here…"
-msgstr ""
+msgstr "අදහසක් ලියන්න හ෠ඔබගේ ගොනු මෙතà·à¶±à¶§ අදින්න…"
msgid "Write a comment…"
-msgstr ""
+msgstr "අදහසක් ලියන්න…"
msgid "Write a description or drag your files here…"
-msgstr ""
+msgstr "සවිස්තරයක් ලියන්න හ෠ගොනු මෙතà·à¶±à¶§ අදින්න…"
msgid "Write a description…"
-msgstr ""
+msgstr "සවිස්තරයක් ලියන්න…"
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 ""
@@ -40858,13 +41716,13 @@ msgid "YYYY-MM-DD"
msgstr ""
msgid "Yes"
-msgstr ""
+msgstr "ඔව්"
msgid "Yes or No"
-msgstr ""
+msgstr "ඔව් හ෠නà·à·„à·"
msgid "Yes, add it"
-msgstr ""
+msgstr "ඔව්, එය එක්කරන්න"
msgid "Yes, close issue"
msgstr ""
@@ -40873,10 +41731,10 @@ msgid "Yes, delete project"
msgstr ""
msgid "Yesterday"
-msgstr ""
+msgstr "ඊයේ"
msgid "You"
-msgstr ""
+msgstr "ඔබ"
msgid "You already have pending todo for this alert"
msgstr ""
@@ -40884,7 +41742,10 @@ msgstr ""
msgid "You are about to add %{usersTag} people to the discussion. They will all receive a notification."
msgstr ""
-msgid "You are about to permanently delete this project"
+msgid "You are about to delete this forked project containing:"
+msgstr ""
+
+msgid "You are about to delete this project containing:"
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."
@@ -40905,6 +41766,9 @@ msgstr ""
msgid "You are attempting to update a file that has changed since you started editing it."
msgstr ""
+msgid "You are billed if you exceed this number. %{qsrOverageLinkStart}How does billing work?%{qsrOverageLinkEnd}"
+msgstr ""
+
msgid "You are connected to the Prometheus server, but there is currently no data to display."
msgstr ""
@@ -40962,6 +41826,9 @@ msgstr ""
msgid "You are not authorized to update this scanner profile"
msgstr ""
+msgid "You are not authorized to upload metric images"
+msgstr ""
+
msgid "You are now impersonating %{username}"
msgstr ""
@@ -41089,7 +41956,7 @@ msgid "You can notify the app / group or a project by sending them an email noti
msgstr ""
msgid "You can now close this window."
-msgstr ""
+msgstr "දà·à¶±à·Š ඔබට මෙම කවුළුව වස෠දà·à¶¸à·’ය à·„à·à¶šà·’ය."
msgid "You can now export your security dashboard to a CSV report."
msgstr ""
@@ -41115,9 +41982,6 @@ msgstr ""
msgid "You can only upload one design when dropping onto an existing design."
msgstr ""
-msgid "You can recover this project until %{date}"
-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 ""
@@ -41166,9 +42030,6 @@ msgstr ""
msgid "You cannot write to this read-only GitLab instance."
msgstr ""
-msgid "You can’t %{tag_start}edit%{tag_end} files directly in this project. Fork this project and submit a merge request with your changes."
-msgstr ""
-
msgid "You can’t edit files directly in this project. Fork this project and submit a merge request with your changes."
msgstr ""
@@ -41316,14 +42177,11 @@ msgid "You have more active users than are allowed by your license. GitLab must
msgstr ""
msgid "You have no permissions"
-msgstr ""
+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 set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
@@ -41354,12 +42212,6 @@ msgstr ""
msgid "You must have maintainer access to force delete a lock"
msgstr ""
-msgid "You must have permission to create a project in a group before forking."
-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 ""
@@ -41496,10 +42348,10 @@ msgid "You've rejected %{user}"
msgstr ""
msgid "YouTube"
-msgstr ""
+msgstr "යූටියුබ්"
msgid "YouTube URL or ID"
-msgstr ""
+msgstr "යූටියුබ් ඒ.à·ƒ.නි. à·„à· à·„à·à¶³à·”."
msgid "Your %{group} membership will now expire in %{days}."
msgstr ""
@@ -41547,19 +42399,19 @@ msgid "Your GitLab account request has been approved!"
msgstr ""
msgid "Your GitLab group"
-msgstr ""
+msgstr "ඔබගේ ගිට්ලà·à¶¶à·Š සමූහය"
msgid "Your Groups"
-msgstr ""
+msgstr "ඔබගේ සමූහය"
msgid "Your Personal Access Token was revoked"
msgstr ""
msgid "Your Projects (default)"
-msgstr ""
+msgstr "ඔබගේ ව්â€à¶ºà·à¶´à·˜à¶­à·’ (පෙරනිමි)"
msgid "Your Projects' Activity"
-msgstr ""
+msgstr "ඔබගේ ව්â€à¶ºà·à¶´à·˜à¶­à·’වල ක්â€à¶»à·’යà·à¶šà·à¶»à¶šà¶¸à·Š"
msgid "Your SSH key has expired"
msgstr ""
@@ -41607,7 +42459,7 @@ msgid "Your account is authenticated with SSO or SAML. To %{push_pull_link_start
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 ""
@@ -41685,10 +42537,10 @@ msgid "Your file must contain a column named %{codeStart}title%{codeEnd}. A %{co
msgstr ""
msgid "Your first project"
-msgstr ""
+msgstr "ඔබගේ පළමු ව්â€à¶ºà·à¶´à·˜à¶­à·’ය"
msgid "Your groups"
-msgstr ""
+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 ""
@@ -41718,19 +42570,19 @@ msgid "Your membership in %{group} no longer expires."
msgstr ""
msgid "Your message here"
-msgstr ""
+msgstr "ඔබගේ පණිවිඩය මෙතà·à¶±"
msgid "Your name"
-msgstr ""
+msgstr "ඔබගේ නම"
msgid "Your new %{type}"
-msgstr ""
+msgstr "ඔබගේ නව %{type}"
msgid "Your new access token has been created."
msgstr ""
msgid "Your new comment"
-msgstr ""
+msgstr "ඔබගේ නව අදහස"
msgid "Your new personal access token has been created."
msgstr ""
@@ -41751,21 +42603,21 @@ msgid "Your primary email is used for avatar detection. You can change it in you
msgstr ""
msgid "Your profile"
-msgstr ""
+msgstr "ඔබගේ පà·à¶­à·’කඩ"
msgid "Your project limit is %{limit} projects! Please contact your administrator to increase it"
msgstr ""
msgid "Your project will be created at:"
-msgstr ""
+msgstr "ඔබගේ ව්â€à¶ºà·à¶´à·˜à¶­à·’ය සෑදෙන්නේ:"
msgid "Your projects"
-msgstr ""
+msgstr "ඔබගේ ව්â€à¶ºà·à¶´à·˜à¶­à·’"
msgid "Your public email will be displayed on your public profile."
-msgstr ""
+msgstr "ඔබගේ ප්â€à¶»à·ƒà·’ද්ධ වි-තà·à¶´à·‘ල ප්â€à¶»à·ƒà·’ද්ධ පà·à¶­à·’කඩෙහි දර්à·à¶±à¶º වනු ඇත."
-msgid "Your request for access could not be processed: %{error_meesage}"
+msgid "Your request for access could not be processed: %{error_message}"
msgstr ""
msgid "Your request for access has been queued for review."
@@ -41813,19 +42665,19 @@ msgstr[0] ""
msgstr[1] ""
msgid "Your username is %{username}."
-msgstr ""
+msgstr "ඔබගේ පරිà·à·“ලක නà·à¶¸à¶º %{username}."
msgid "ZenTaoIntegration|Failed to load ZenTao issue. View the issue in ZenTao, or reload the page."
msgstr ""
msgid "ZenTaoIntegration|This is a ZenTao user."
-msgstr ""
+msgstr "මේ සෙන්ටà·à¶• පරිà·à·“ලකයෙකි."
msgid "ZenTaoIntegration|ZenTao user"
-msgstr ""
+msgstr "සෙන්ටà·à¶• පරිà·à·“ලකයà·"
msgid "ZentaoIntegration|An error occurred while requesting data from the ZenTao service."
-msgstr ""
+msgstr "සෙන්ටà·à¶• සේවයෙන් දත්ත ඉල්ලීමේදී දà·à·‚යක් සිදු විය."
msgid "ZentaoIntegration|Base URL of the ZenTao instance."
msgstr ""
@@ -41837,40 +42689,40 @@ msgid "ZentaoIntegration|Enter new ZenTao API token"
msgstr ""
msgid "ZentaoIntegration|If different from Web URL."
-msgstr ""
+msgstr "වියමන ඒ.ස.නි. ට වඩ෠වෙනස් නම්."
msgid "ZentaoIntegration|Issue list"
msgstr ""
msgid "ZentaoIntegration|Open ZenTao"
-msgstr ""
+msgstr "සෙන්ටà·à¶• විවෘත කරන්න"
msgid "ZentaoIntegration|Use ZenTao as this project's issue tracker."
msgstr ""
msgid "ZentaoIntegration|ZenTao API URL (optional)"
-msgstr ""
+msgstr "සෙන්ටà·à¶• යෙ.ක්â€à¶».මු. ඒ.à·ƒ.නි. (වෛකල්පිතයි)"
msgid "ZentaoIntegration|ZenTao API token"
msgstr ""
msgid "ZentaoIntegration|ZenTao Product ID"
-msgstr ""
+msgstr "සෙන්ටà·à¶• නිෂ්පà·à¶¯à¶±à¶ºà·š à·„à·à¶³à·”."
msgid "ZentaoIntegration|ZenTao Web URL"
-msgstr ""
+msgstr "සෙන්ටà·à¶• වියමන ඒ.à·ƒ.නි."
msgid "ZentaoIntegration|ZenTao issues"
msgstr ""
msgid "Zoom meeting added"
-msgstr ""
+msgstr "සූම් රà·à·ƒà·Šà·€à·“ම එක් කෙරිණි"
msgid "Zoom meeting removed"
-msgstr ""
+msgstr "සූම් රà·à·ƒà·Šà·€à·“ම ඉවත් කෙරිණි"
msgid "[No reason]"
-msgstr ""
+msgstr "[හේතුවක් නà·à¶­]"
msgid "[REDACTED]"
msgstr ""
@@ -41893,7 +42745,7 @@ msgstr[0] ""
msgstr[1] ""
msgid "access:"
-msgstr ""
+msgstr "ප්â€à¶»à·€à·šà·à¶º:"
msgid "added"
msgstr ""
@@ -41926,7 +42778,7 @@ msgid "already shared with this group"
msgstr ""
msgid "and"
-msgstr ""
+msgstr "සහ"
msgid "any-approver for the merge request already exists"
msgstr ""
@@ -41948,6 +42800,9 @@ msgstr ""
msgid "archived:"
msgstr ""
+msgid "artifacts"
+msgstr ""
+
msgid "assign yourself"
msgstr ""
@@ -41971,10 +42826,13 @@ msgstr ""
msgid "branch"
msgid_plural "branches"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "à·à·à¶›à·à·€"
+msgstr[1] "à·à·à¶›à·"
msgid "branch name"
+msgstr "à·à·à¶›à·à·€à·š නම"
+
+msgid "builds"
msgstr ""
msgid "by"
@@ -42053,7 +42911,7 @@ msgid "cannot itself be blocked"
msgstr ""
msgid "cannot merge"
-msgstr ""
+msgstr "සංයුක්ත කළ නොහà·à¶šà·’ය"
msgid "ciReport|%{danger_start}%{degradedNum} degraded%{danger_end}, %{same_start}%{sameNum} same%{same_end}, and %{success_start}%{improvedNum} improved%{success_end}"
msgstr ""
@@ -42095,7 +42953,7 @@ msgid "ciReport|%{remainingPackagesCount} more"
msgstr ""
msgid "ciReport|%{reportType} is loading"
-msgstr ""
+msgstr "%{reportType} පූරණය වෙමින්"
msgid "ciReport|%{reportType}: Loading resulted in an error"
msgstr ""
@@ -42113,13 +42971,13 @@ msgid "ciReport|API fuzzing"
msgstr ""
msgid "ciReport|All projects"
-msgstr ""
+msgstr "සියළු ව්â€à¶ºà·à¶´à·˜à¶­à·’"
msgid "ciReport|All severities"
msgstr ""
msgid "ciReport|All tools"
-msgstr ""
+msgstr "සියළු මෙවලම්"
msgid "ciReport|Automatically apply the patch in a new branch"
msgstr ""
@@ -42246,19 +43104,19 @@ msgid "ciReport|Load performance test metrics: No changes"
msgstr ""
msgid "ciReport|Loading %{reportName} report"
-msgstr ""
+msgstr "%{reportName} à·€à·à¶»à·Šà¶­à·à·€ පූරණය වෙමින්"
msgid "ciReport|Loading Code Quality report"
msgstr ""
msgid "ciReport|Manage licenses"
-msgstr ""
+msgstr "බලපත්â€à¶» කළමනà·à¶šà¶»à¶«à¶º"
msgid "ciReport|New"
-msgstr ""
+msgstr "නව"
msgid "ciReport|No changes to code quality"
-msgstr ""
+msgstr "කේතයේ ගුණත්වයට වෙනසක් නà·à¶­"
msgid "ciReport|No code quality issues found"
msgstr ""
@@ -42291,22 +43149,22 @@ msgid "ciReport|Showing %{fetchedItems} of %{totalItems} items"
msgstr ""
msgid "ciReport|Solution"
-msgstr ""
+msgstr "විසඳුම"
msgid "ciReport|Static Application Security Testing (SAST) detects known vulnerabilities in your source code."
msgstr ""
msgid "ciReport|TTFB P90"
-msgstr ""
+msgstr "TTFB P90"
msgid "ciReport|TTFB P95"
-msgstr ""
+msgstr "TTFB P95"
msgid "ciReport|There was an error creating the issue. Please try again."
msgstr ""
msgid "ciReport|There was an error creating the merge request. Please try again."
-msgstr ""
+msgstr "සංයුක්ත ඉල්ලීම සෑදීමේ දà·à·‚යකි. නà·à·€à¶­ උත්සà·à·„ කරන්න."
msgid "ciReport|There was an error dismissing the vulnerability. Please try again."
msgstr ""
@@ -42326,16 +43184,16 @@ msgstr[0] ""
msgstr[1] ""
msgid "ciReport|View full report"
-msgstr ""
+msgstr "පූර්ණ à·€à·à¶»à·Šà¶­à·à·€ දකින්න"
msgid "ciReport|is loading"
-msgstr ""
+msgstr "පූරණය වෙමින්"
msgid "ciReport|is loading, errors when loading results"
msgstr ""
msgid "closed"
-msgstr ""
+msgstr "වස෠ඇත"
msgid "closed issue"
msgstr ""
@@ -42383,7 +43241,7 @@ msgid "collect usage information"
msgstr ""
msgid "comment"
-msgstr ""
+msgstr "අදහස"
msgid "commented on %{link_to_project}"
msgstr ""
@@ -42400,6 +43258,9 @@ msgstr ""
msgid "contact with same email already exists in group hierarchy"
msgstr ""
+msgid "container registry images"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -42413,13 +43274,13 @@ msgid "contains invalid URLs (%{urls})"
msgstr ""
msgid "contribute to this project."
-msgstr ""
+msgstr "මෙම ව්â€à¶ºà·à¶´à·˜à¶­à·’යට දà·à¶ºà¶š වන්න."
msgid "could not read private key, is the passphrase correct?"
msgstr ""
msgid "created"
-msgstr ""
+msgstr "සෑදිණි"
msgid "created %{issuable_created} by %{author}"
msgstr ""
@@ -42437,6 +43298,9 @@ msgid "created by"
msgstr ""
msgid "data"
+msgstr "දත්ත"
+
+msgid "database"
msgstr ""
msgid "date must not be after 9999-12-31"
@@ -42444,14 +43308,14 @@ msgstr ""
msgid "day"
msgid_plural "days"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "දවස"
+msgstr[1] "දවස්"
msgid "days"
-msgstr ""
+msgstr "දවස්"
msgid "default branch"
-msgstr ""
+msgstr "පෙරනිමි à·à·à¶›à·à·€"
msgid "deleted"
msgstr ""
@@ -42462,14 +43326,11 @@ msgstr ""
msgid "design"
msgstr ""
-msgid "detached"
-msgstr ""
-
msgid "disabled"
-msgstr ""
+msgstr "අබල කර ඇත"
msgid "does not exist"
-msgstr ""
+msgstr "නොපවතී"
msgid "does not have a supported extension. Only %{extension_list} are supported"
msgstr ""
@@ -42481,15 +43342,15 @@ msgid "does not match dast_site_validation.project"
msgstr ""
msgid "download it"
-msgstr ""
+msgstr "එය බà·à¶œà¶±à·Šà¶±"
msgid "draft"
msgid_plural "drafts"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "කටුපිටපත"
+msgstr[1] "කටුපිටපත්"
msgid "e.g. %{token}"
-msgstr ""
+msgstr "උදà·. %{token}"
msgid "element is not a hierarchy"
msgstr ""
@@ -42501,7 +43362,7 @@ msgid "email '%{email}' is not a verified email."
msgstr ""
msgid "enabled"
-msgstr ""
+msgstr "සබල කර ඇත"
msgid "encrypted: needs to be a :required, :optional or :migrating!"
msgstr ""
@@ -42525,13 +43386,13 @@ msgid "epic"
msgstr ""
msgid "error"
-msgstr ""
+msgstr "දà·à·‚ය"
msgid "estimateCommand|%{slash_command} overwrites the total estimated time."
msgstr ""
msgid "example.com"
-msgstr ""
+msgstr "උදà·à·„රණය.ලංකà·"
msgid "exceeds the %{max_value_length} character limit"
msgstr ""
@@ -42562,8 +43423,8 @@ msgstr ""
msgid "file"
msgid_plural "files"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "ගොනුව"
+msgstr[1] "ගොනු"
msgid "finding is not found or is already attached to a vulnerability"
msgstr ""
@@ -42578,13 +43439,13 @@ msgid "for %{link_to_merge_request} with %{link_to_merge_request_source_branch}
msgstr ""
msgid "for %{link_to_pipeline_ref}"
-msgstr ""
+msgstr "%{link_to_pipeline_ref} සඳහà·"
msgid "for %{ref}"
-msgstr ""
+msgstr "%{ref} සඳහà·"
msgid "for this project"
-msgstr ""
+msgstr "මෙම ව්â€à¶ºà·à¶´à·˜à¶­à·’ය සඳහà·"
msgid "fork"
msgstr ""
@@ -42601,7 +43462,7 @@ msgid "frontmatter"
msgstr ""
msgid "group"
-msgstr ""
+msgstr "සමූහය"
msgid "group access token"
msgstr ""
@@ -42610,13 +43471,13 @@ msgid "group access tokens"
msgstr ""
msgid "group members"
-msgstr ""
+msgstr "සමූහයේ à·ƒà·à¶¸à·à¶¢à·’කයින්"
msgid "group's CI/CD settings."
msgstr ""
msgid "groups"
-msgstr ""
+msgstr "සමූහ"
msgid "has already been linked to another vulnerability"
msgstr ""
@@ -42637,19 +43498,19 @@ msgid "has too deep level of nesting"
msgstr ""
msgid "help"
-msgstr ""
+msgstr "උදව්"
msgid "http:"
-msgstr ""
+msgstr "http:"
msgid "http://www.example.com"
-msgstr ""
+msgstr "http://උදà·à·„රණය.ලංකà·"
msgid "https://bamboo.example.com"
-msgstr ""
+msgstr "https://බà·à¶¸à·Šà¶¶à·–.උදà·à·„රණය.ලංකà·"
msgid "https://your-bitbucket-server"
-msgstr ""
+msgstr "https://ඔබගේ-බිට්බකට්-සේවà·à¶¯à·à¶ºà¶šà¶º"
msgid "i18n|%{language} (%{percent_translated}%% translated)"
msgstr ""
@@ -42711,9 +43572,9 @@ msgid "is not a descendant of the Group owning the template"
msgstr ""
msgid "is not a valid X509 certificate."
-msgstr ""
+msgstr "වලංගු X509 සහතිකයක් නොවේ."
-msgid "is not allowed for sign-up."
+msgid "is not allowed for sign-up. Please use your regular email address."
msgstr ""
msgid "is not allowed for this group."
@@ -42725,7 +43586,7 @@ msgstr ""
msgid "is not allowed since the group is not top-level group."
msgstr ""
-msgid "is not allowed."
+msgid "is not allowed. Please use your regular email address."
msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
@@ -42744,7 +43605,7 @@ msgid "is not valid. The iteration group has to match the iteration cadence grou
msgstr ""
msgid "is read-only"
-msgstr ""
+msgstr "කියවීමට පමණි"
msgid "is too long (%{current_value}). The maximum size is %{max_size}."
msgstr ""
@@ -42810,6 +43671,9 @@ msgid "less than a minute"
msgstr ""
msgid "level: %{level}"
+msgstr "මට්ටම: %{level}"
+
+msgid "lfs objects"
msgstr ""
msgid "limit of %{project_limit} reached"
@@ -42819,7 +43683,7 @@ msgid "load it anyway"
msgstr ""
msgid "loading"
-msgstr ""
+msgstr "පූරණය â€â€à·€à·™à¶¸à·’න්"
msgid "locked by %{path_lock_user_name} %{created_at}"
msgstr ""
@@ -42835,8 +43699,8 @@ msgstr ""
msgid "merge request"
msgid_plural "merge requests"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "සංයුක්ත ඉල්ලීම"
+msgstr[1] "සංයුක්ත ඉල්ලීම්"
msgid "merged %{timeAgo}"
msgstr ""
@@ -42872,10 +43736,10 @@ msgid "mrWidget|%{linkStart}Set up now%{linkEnd} to analyze your source code for
msgstr ""
msgid "mrWidget|%{mergeError}."
-msgstr ""
+msgstr "%{mergeError}."
msgid "mrWidget|%{mergeError}. Try again."
-msgstr ""
+msgstr "%{mergeError}. යළි උත්සà·à·„ කරන්න."
msgid "mrWidget|%{metricsLinkStart} Memory %{metricsLinkEnd} usage %{emphasisStart} decreased %{emphasisEnd} from %{memoryFrom}MB to %{memoryTo}MB"
msgstr ""
@@ -42899,25 +43763,25 @@ msgid "mrWidget|Added to the merge train. There are %{mergeTrainPosition} merge
msgstr ""
msgid "mrWidget|An error occurred while removing your approval."
-msgstr ""
+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 ""
+msgstr "ඔබගේ අනුමà·à¶­à·’ය යොමු කෙරෙන අතරතුර දà·à·‚යක් සිදු විය."
msgid "mrWidget|Approval is optional"
-msgstr ""
+msgstr "අනුමà·à¶­à·’ය වෛකල්පිතයි"
msgid "mrWidget|Approval password is invalid."
-msgstr ""
+msgstr "අනුමත මුරපදය වලංගු නොවේ."
msgid "mrWidget|Approve"
-msgstr ""
+msgstr "අනුමත"
msgid "mrWidget|Approve additionally"
-msgstr ""
+msgstr "අතිරේකව අනුමත කරන්න"
msgid "mrWidget|Approved by"
msgstr ""
@@ -42929,13 +43793,13 @@ msgid "mrWidget|Approved by you and others"
msgstr ""
msgid "mrWidget|Cancel auto-merge"
-msgstr ""
+msgstr "ස්වයං සංයුක්තය අවලංගු කරන්න"
msgid "mrWidget|Check out branch"
msgstr ""
msgid "mrWidget|Checking if merge request can be merged…"
-msgstr ""
+msgstr "සංයුක්ත ඉල්ලීම සංයුක්ත කළ à·„à·à¶šà·’දà·à¶ºà·’ පරීක්â€à·‚෠වෙමින්…"
msgid "mrWidget|Cherry-pick"
msgstr ""
@@ -42985,7 +43849,7 @@ msgid "mrWidget|GitLab %{linkStart}CI/CD can automatically build, test, and depl
msgstr ""
msgid "mrWidget|Hide %{widget} details"
-msgstr ""
+msgstr "%{widget} විස්තර සඟවන්න"
msgid "mrWidget|If the %{type} branch exists in your local repository, you can merge this merge request manually using the command line."
msgstr ""
@@ -42997,13 +43861,13 @@ msgid "mrWidget|Jump to first unresolved thread"
msgstr ""
msgid "mrWidget|Learn more"
-msgstr ""
+msgstr "තව දà·à¶±à¶œà¶±à·Šà¶±"
msgid "mrWidget|Loading deployment statistics"
msgstr ""
msgid "mrWidget|Mark as ready"
-msgstr ""
+msgstr "සූදà·à¶±à¶¸à·Š ලෙස ලකුණු කරන්න"
msgid "mrWidget|Members who can merge are allowed to add commits."
msgstr ""
@@ -43014,7 +43878,7 @@ msgstr[0] ""
msgstr[1] ""
msgid "mrWidget|Merge"
-msgstr ""
+msgstr "සංයුක්ත"
msgid "mrWidget|Merge blocked: all threads must be resolved."
msgstr ""
@@ -43031,6 +43895,9 @@ msgstr ""
msgid "mrWidget|Merge blocked: pipeline must succeed. It's waiting for a manual action to continue."
msgstr ""
+msgid "mrWidget|Merge blocked: pipeline must succeed. Push a commit that fixes the failure, or %{linkStart}learn about other solutions.%{linkEnd}"
+msgstr ""
+
msgid "mrWidget|Merge blocked: this merge request must be approved."
msgstr ""
@@ -43038,10 +43905,10 @@ msgid "mrWidget|Merge blocked: you can only merge after the above items are reso
msgstr ""
msgid "mrWidget|Merge failed."
-msgstr ""
+msgstr "සංයුක්තය අසමත් විය."
msgid "mrWidget|Merge locally"
-msgstr ""
+msgstr "ස්ථà·à¶±à·“යව සංයුක්ත කරන්න"
msgid "mrWidget|Merge unavailable: merge requests are read-only on archived projects."
msgstr ""
@@ -43059,10 +43926,10 @@ msgid "mrWidget|Merging! Changes will land soon…"
msgstr ""
msgid "mrWidget|Merging! Drum roll, please…"
-msgstr ""
+msgstr "සංයුක්ත වෙමින්! කරුණà·à¶šà¶», බෙර වයන්න…"
msgid "mrWidget|Merging! Everything's good…"
-msgstr ""
+msgstr "සංයුක්ත වෙමින්! සියල්ල හොඳයි…"
msgid "mrWidget|Merging! Lift-off in 5… 4… 3…"
msgstr ""
@@ -43080,10 +43947,10 @@ msgid "mrWidget|Merging! We're almost there…"
msgstr ""
msgid "mrWidget|More information"
-msgstr ""
+msgstr "තව තොරතුරු"
msgid "mrWidget|Open in Gitpod"
-msgstr ""
+msgstr "ගිට්පොඩ් හි විවෘත කරන්න"
msgid "mrWidget|Open in Web IDE"
msgstr ""
@@ -43095,22 +43962,22 @@ msgid "mrWidget|Please restore it or use a different %{type} branch."
msgstr ""
msgid "mrWidget|Ready to be merged automatically. Ask someone with write access to this repository to merge this request"
-msgstr ""
+msgstr "ස්වයංක්â€à¶»à·“යව සංයුක්ත වීමට සූදà·à¶±à¶¸à·Š. ඉල්ලීම සංයුක්ත කිරීමට මෙම කà·à·‚්ඨයට ලිවීමේ ප්â€à¶»à·€à·šà·à¶º ඇති යමෙකුගෙන් අසන්න"
msgid "mrWidget|Refresh"
-msgstr ""
+msgstr "නà·à·€à·”ම් කරන්න"
msgid "mrWidget|Refresh now"
-msgstr ""
+msgstr "දà·à¶±à·Š නà·à·€à·”ම් කරන්න"
msgid "mrWidget|Refreshing now"
-msgstr ""
+msgstr "දà·à¶±à·Š නà·à·€à·”ම් වෙමින්"
msgid "mrWidget|Remove from merge train"
msgstr ""
msgid "mrWidget|Request to merge"
-msgstr ""
+msgstr "සංයුක්ත කිරීමට ඉල්ලන්න"
msgid "mrWidget|Resolve conflicts"
msgstr ""
@@ -43122,7 +43989,7 @@ msgid "mrWidget|Revert this merge request in a new merge request"
msgstr ""
msgid "mrWidget|Revoke approval"
-msgstr ""
+msgstr "අනුමà·à¶­à·’ය අහà·à·ƒà·’ කරන්න"
msgid "mrWidget|SAST and Secret Detection is not enabled."
msgstr ""
@@ -43137,7 +44004,7 @@ msgid "mrWidget|Set by %{merge_author} to start a merge train when the pipeline
msgstr ""
msgid "mrWidget|Show %{widget} details"
-msgstr ""
+msgstr "%{widget} විස්තර පෙන්වන්න"
msgid "mrWidget|The %{type} branch %{codeStart}%{name}%{codeEnd} does not exist."
msgstr ""
@@ -43148,9 +44015,6 @@ msgstr ""
msgid "mrWidget|The changes were not merged into"
msgstr ""
-msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -43161,7 +44025,7 @@ msgid "mrWidget|The source branch is being deleted"
msgstr ""
msgid "mrWidget|This merge request failed to be merged automatically"
-msgstr ""
+msgstr "මෙම සංයුක්ත ඉල්ලීම ස්වයංක්â€à¶»à·“යව සංයුක්ත වීමට අසමත් විය"
msgid "mrWidget|To approve this merge request, please enter your password. This project requires all approvals to be authenticated."
msgstr ""
@@ -43185,7 +44049,7 @@ msgid "mrWidget|What is a merge train?"
msgstr ""
msgid "mrWidget|Your password"
-msgstr ""
+msgstr "ඔබගේ මුරපදය"
msgid "mrWidget|into"
msgstr ""
@@ -43236,10 +44100,10 @@ msgid "my-awesome-group"
msgstr ""
msgid "my-channel"
-msgstr ""
+msgstr "මà·à¶œà·š-නà·à¶½à·’කà·à·€"
msgid "n/a"
-msgstr ""
+msgstr "අ/නොවේ"
msgid "need attention"
msgstr ""
@@ -43248,25 +44112,25 @@ msgid "needs to be between 10 minutes and 1 month"
msgstr ""
msgid "never"
-msgstr ""
+msgstr "කවදà·à·€à¶­à·Š"
msgid "never expires"
-msgstr ""
+msgstr "කිසිද෠කල් ඉකුත් නොවේ"
msgid "new merge request"
-msgstr ""
+msgstr "නව සංයුක්ත ඉල්ලීම"
msgid "no approvers"
msgstr ""
msgid "no expiration"
-msgstr ""
+msgstr "කල් ඉකුත්වීමක් නà·à¶­"
msgid "no name set"
-msgstr ""
+msgstr "නමක් සකස෠නà·à¶­"
msgid "no one can merge"
-msgstr ""
+msgstr "කිසිවෙකුට සංයුක්ත කළ නොහà·à¶šà·’ය"
msgid "no scopes selected"
msgstr ""
@@ -43275,19 +44139,19 @@ msgid "none"
msgstr ""
msgid "not found"
-msgstr ""
+msgstr "හමු නොවිණි"
msgid "nounSeries|%{firstItem} and %{lastItem}"
-msgstr ""
+msgstr "%{firstItem} සහ %{lastItem}"
msgid "nounSeries|%{item}"
-msgstr ""
+msgstr "%{item}"
msgid "nounSeries|%{item}, %{nextItem}"
-msgstr ""
+msgstr "%{item}, %{nextItem}"
msgid "nounSeries|%{item}, and %{lastItem}"
-msgstr ""
+msgstr "%{item}, සහ %{lastItem}"
msgid "on track"
msgstr ""
@@ -43298,11 +44162,8 @@ msgstr ""
msgid "open issue"
msgstr ""
-msgid "opened %{timeAgo}"
-msgstr ""
-
msgid "or"
-msgstr ""
+msgstr "à·„à·"
msgid "other card matches"
msgstr ""
@@ -43312,13 +44173,19 @@ msgid_plural "out of %d total tests"
msgstr[0] ""
msgstr[1] ""
+msgid "packages"
+msgstr ""
+
+msgid "pages"
+msgstr ""
+
msgid "parent"
msgid_plural "parents"
msgstr[0] ""
msgstr[1] ""
msgid "password"
-msgstr ""
+msgstr "මුරපදය"
msgid "pending comment"
msgstr ""
@@ -43374,12 +44241,12 @@ msgid "private key does not match certificate."
msgstr ""
msgid "processing"
-msgstr ""
+msgstr "à·ƒà·à¶šà·ƒà·™à¶¸à·’න්"
msgid "project"
msgid_plural "projects"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "ව්â€à¶ºà·à¶´à·˜à¶­à·’ය"
+msgstr[1] "ව්â€à¶ºà·à¶´à·˜à¶­à·’"
msgid "project access token"
msgstr ""
@@ -43394,22 +44261,22 @@ msgid "project bots cannot be added to other groups / projects"
msgstr ""
msgid "project is read-only"
-msgstr ""
+msgstr "ව්â€à¶ºà·à¶´à·˜à¶­à·’ය කියවීමට පමණි"
msgid "project members"
-msgstr ""
+msgstr "ව්â€à¶ºà·à¶´à·˜à¶­à·’යේ à·ƒà·à¶¸à·à¶¢à·’කයින්"
msgid "project name"
-msgstr ""
+msgstr "ව්â€à¶ºà·à¶´à·˜à¶­à·’යේ නම"
msgid "project namespace cannot be the parent of another namespace"
msgstr ""
msgid "projects"
-msgstr ""
+msgstr "ව්â€à¶ºà·à¶´à·˜à¶­à·’"
msgid "quick actions"
-msgstr ""
+msgstr "ඉක්මන් ක්â€à¶»à·’යà·à¶¸à·à¶»à·Šà¶œ"
msgid "reCAPTCHA"
msgstr ""
@@ -43424,10 +44291,10 @@ msgid "reCAPTCHA site key"
msgstr ""
msgid "recent activity"
-msgstr ""
+msgstr "මෑත ක්â€à¶»à·’යà·à¶šà·à¶»à¶šà¶¸"
msgid "register"
-msgstr ""
+msgstr "ලියà·à¶´à¶¯à·’ංචිය"
msgid "relates to"
msgstr ""
@@ -43436,13 +44303,13 @@ msgid "remaining"
msgstr ""
msgid "remove"
-msgstr ""
+msgstr "ඉවත් කරන්න"
msgid "remove due date"
-msgstr ""
+msgstr "නියමිත දිනය ඉවත් කරන්න"
msgid "remove start date"
-msgstr ""
+msgstr "ආරම්භක දිනය ඉවත් කරන්න"
msgid "remove weight"
msgstr ""
@@ -43458,14 +44325,17 @@ msgstr ""
msgid "reply"
msgid_plural "replies"
-msgstr[0] ""
-msgstr[1] ""
+msgstr[0] "පිළිතුර"
+msgstr[1] "පිළිතුරු"
-msgid "repository:"
+msgid "repositories"
msgstr ""
+msgid "repository:"
+msgstr "කà·à·‚්ඨය:"
+
msgid "required"
-msgstr ""
+msgstr "ඇවà·à·ƒà·’ය"
msgid "satisfied"
msgstr ""
@@ -43498,7 +44368,7 @@ msgid "severity|Major"
msgstr ""
msgid "severity|Medium"
-msgstr ""
+msgstr "මධ්â€à¶ºà¶¸"
msgid "severity|Minor"
msgstr ""
@@ -43507,7 +44377,7 @@ msgid "severity|None"
msgstr ""
msgid "severity|Unknown"
-msgstr ""
+msgstr "නොදනී"
msgid "should be an array of %{object_name} objects"
msgstr ""
@@ -43516,7 +44386,7 @@ msgid "should be greater than or equal to %{access} inherited membership from gr
msgstr ""
msgid "show %{count} more"
-msgstr ""
+msgstr "තවත් %{count} පෙන්වන්න"
msgid "show fewer"
msgstr ""
@@ -43525,13 +44395,13 @@ msgid "show less"
msgstr ""
msgid "sign in"
-msgstr ""
+msgstr "ඇතුළු වන්න"
msgid "smartcn custom analyzer"
msgstr ""
msgid "source"
-msgstr ""
+msgstr "මූලà·à·à·Šâ€à¶»à¶º"
msgid "source diff"
msgstr ""
@@ -43543,10 +44413,10 @@ msgid "spendCommand|%{slash_command} adds or subtracts time already spent."
msgstr ""
msgid "ssh:"
-msgstr ""
+msgstr "ssh:"
msgid "started a discussion on %{design_link}"
-msgstr ""
+msgstr "%{design_link} à·„à·’ à·ƒà·à¶šà¶ à·Šà¶¡à·à·€à¶šà·Š ආරම්භ කළà·"
msgid "started on %{timebox_start_date}"
msgstr ""
@@ -43581,10 +44451,16 @@ msgstr ""
msgid "tag name"
msgstr ""
-msgid "the correct format."
+msgid "terraform states"
msgstr ""
+msgid "the correct format."
+msgstr "නිවà·à¶»à¶¯à·’ ආකෘතිය."
+
msgid "the file"
+msgstr "ගොනුව"
+
+msgid "the following epic(s)"
msgstr ""
msgid "the following issue(s)"
@@ -43597,13 +44473,7 @@ msgid "then"
msgstr ""
msgid "this document"
-msgstr ""
-
-msgid "this issue cannot be assigned to a confidential epic since it is public"
-msgstr ""
-
-msgid "this issue cannot be made public since it belongs to a confidential epic"
-msgstr ""
+msgstr "මෙම ලේඛනය"
msgid "time summary"
msgstr ""
@@ -43611,9 +44481,6 @@ msgstr ""
msgid "toggle collapse"
msgstr ""
-msgid "train"
-msgstr ""
-
msgid "triggered"
msgstr ""
@@ -43639,7 +44506,7 @@ msgid "updated %{time_ago}"
msgstr ""
msgid "uploads"
-msgstr ""
+msgstr "උඩුගත කිරීම්"
msgid "user avatar"
msgstr ""
@@ -43648,7 +44515,7 @@ msgid "user namespace cannot be the parent of another namespace"
msgstr ""
msgid "username"
-msgstr ""
+msgstr "පරිà·à·“ලක නà·à¶¸à¶º"
msgid "v%{version} published %{timeAgo}"
msgstr ""
@@ -43672,13 +44539,13 @@ msgid "via merge request %{link}"
msgstr ""
msgid "view it on GitLab"
-msgstr ""
+msgstr "ගිට්ලà·à¶¶à·Š à·„à·’ දකින්න"
msgid "view the blob"
msgstr ""
msgid "view the source"
-msgstr ""
+msgstr "මූලà·à·à·Šâ€à¶»à¶º දකින්න"
msgid "visibility"
msgstr ""
@@ -43689,13 +44556,13 @@ msgstr[0] ""
msgstr[1] ""
msgid "vulnerability|Add a comment"
-msgstr ""
+msgstr "අදහසක් එක්කරන්න"
msgid "vulnerability|Add a comment or reason for dismissal"
msgstr ""
msgid "vulnerability|Add comment"
-msgstr ""
+msgstr "අදහස එක්කරන්න"
msgid "vulnerability|Add comment & dismiss"
msgstr ""
@@ -43707,7 +44574,7 @@ msgid "vulnerability|Dismiss vulnerability"
msgstr ""
msgid "vulnerability|Save comment"
-msgstr ""
+msgstr "අදහස සුරකින්න"
msgid "vulnerability|Undo dismiss"
msgstr ""
@@ -43731,14 +44598,17 @@ msgid "with expiry remaining unchanged at %{old_expiry}"
msgstr ""
msgid "yaml invalid"
-msgstr ""
+msgstr "yaml වලංගු නොවේ"
msgid "your settings"
-msgstr ""
+msgstr "ඔබගේ à·ƒà·à¶šà·ƒà·”ම්"
msgid "{group}"
-msgstr ""
+msgstr "{group}"
msgid "{project}"
+msgstr "{project}"
+
+msgid "✔"
msgstr ""
diff --git a/locale/sk_SK/gitlab.po b/locale/sk_SK/gitlab.po
index 9283a31c47a..b9a921402db 100644
--- a/locale/sk_SK/gitlab.po
+++ b/locale/sk_SK/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: sk\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2022-02-02 15:44\n"
+"PO-Revision-Date: 2022-03-01 20:38\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -174,6 +174,13 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "%d assigned issue"
+msgid_plural "%d assigned issues"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -559,8 +566,29 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
-msgid "%d vulnerability updated"
-msgid_plural "%d vulnerabilities updated"
+msgid "%d vulnerability set to confirmed"
+msgid_plural "%d vulnerabilities set to confirmed"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
+msgid "%d vulnerability set to dismissed"
+msgid_plural "%d vulnerabilities set to dismissed"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
+msgid "%d vulnerability set to needs triage"
+msgid_plural "%d vulnerabilities set to needs triage"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
+msgid "%d vulnerability set to resolved"
+msgid_plural "%d vulnerabilities set to resolved"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
@@ -662,6 +690,12 @@ msgstr[3] ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{completed} of %{total} issues closed"
+msgstr ""
+
+msgid "%{completed} of %{total} weight completed"
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -1022,6 +1056,9 @@ msgstr ""
msgid "%{openedIssues} open, %{closedIssues} closed"
msgstr ""
+msgid "%{percentage}%% issues closed"
+msgstr ""
+
msgid "%{percentage}%% weight completed"
msgstr ""
@@ -1481,6 +1518,9 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "- of - issues closed"
+msgstr ""
+
msgid "- of - weight completed"
msgstr ""
@@ -1669,7 +1709,7 @@ msgstr ""
msgid "1000+"
msgstr ""
-msgid "192.168.0.0/24"
+msgid "192.168.0.0/24 or 2001:0DB8:1234::/48"
msgstr ""
msgid "1st contribution!"
@@ -1981,13 +2021,13 @@ msgstr ""
msgid "AWS Access Key"
msgstr ""
-msgid "AWS Access Key. Only required if not using role instance credentials"
+msgid "AWS Secret Access Key"
msgstr ""
-msgid "AWS Secret Access Key"
+msgid "AWS access key ID (Optional)"
msgstr ""
-msgid "AWS Secret Access Key. Only required if not using role instance credentials"
+msgid "AWS secret access key (Optional)"
msgstr ""
msgid "AWS service error: %{error}"
@@ -2047,9 +2087,6 @@ msgstr ""
msgid "Access granted"
msgstr ""
-msgid "Access key ID"
-msgstr ""
-
msgid "Access requests"
msgstr ""
@@ -2224,7 +2261,7 @@ msgstr ""
msgid "Activity"
msgstr ""
-msgid "Activity|An error occured while retrieving activity. Reload the page to try again."
+msgid "Activity|An error occurred while retrieving activity. Reload the page to try again."
msgstr ""
msgid "Add"
@@ -2263,6 +2300,9 @@ msgstr ""
msgid "Add a %{type}"
msgstr ""
+msgid "Add a GCP region"
+msgstr ""
+
msgid "Add a GPG key"
msgstr ""
@@ -2314,6 +2354,9 @@ msgstr ""
msgid "Add a numbered list"
msgstr ""
+msgid "Add a related epic"
+msgstr ""
+
msgid "Add a related issue"
msgstr ""
@@ -2428,6 +2471,9 @@ msgstr ""
msgid "Add or subtract spent time"
msgstr ""
+msgid "Add people"
+msgstr ""
+
msgid "Add previously merged commits"
msgstr ""
@@ -2494,6 +2540,9 @@ msgstr ""
msgid "Add webhook"
msgstr ""
+msgid "Add your team members and others to GitLab."
+msgstr ""
+
msgid "Add/remove"
msgstr ""
@@ -3316,12 +3365,6 @@ msgstr ""
msgid "AdvancedSearch|Reindex required"
msgstr ""
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. Permanently deleting this project will %{strongStart}immediately delete%{strongEnd} its repositories and %{strongStart}all related resources%{strongEnd}, including issues, merge requests etc."
-msgstr ""
-
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. You will lose this project's repository and %{strongStart}all related resources%{strongEnd}, including issues and merge requests."
-msgstr ""
-
msgid "After a successful password update you will be redirected to login screen."
msgstr ""
@@ -3352,6 +3395,9 @@ msgstr ""
msgid "Akismet helps prevent the creation of spam issues in public projects."
msgstr ""
+msgid "Alert"
+msgstr ""
+
msgid "AlertManagement|Acknowledged"
msgstr ""
@@ -3724,9 +3770,6 @@ msgstr ""
msgid "All environments"
msgstr ""
-msgid "All epics"
-msgstr ""
-
msgid "All groups and projects"
msgstr ""
@@ -4467,14 +4510,17 @@ msgstr ""
msgid "ApplicationSettings|Approve users in the pending approval status?"
msgstr ""
-msgid "ApplicationSettings|By making this change, you will automatically approve %d user with the pending approval status."
-msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users with the pending approval status."
+msgid "ApplicationSettings|Approve users who are pending approval?"
+msgstr ""
+
+msgid "ApplicationSettings|By making this change, you will automatically approve %d user who is pending approval."
+msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users who are pending approval."
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
-msgid "ApplicationSettings|By making this change, you will automatically approve all users in pending approval status."
+msgid "ApplicationSettings|By making this change, you will automatically approve all users who are pending approval."
msgstr ""
msgid "ApplicationSettings|Denied domains for sign-ups"
@@ -4890,10 +4936,10 @@ msgstr ""
msgid "Archiving the project will make it entirely read-only. It is hidden from the dashboard and doesn't show up in searches. %{strong_start}The repository cannot be committed to, and no issues, comments, or other entities can be created.%{strong_end} %{link_start}Learn more.%{link_end}"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to delete this project?"
+msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
+msgid "Are you absolutely sure?"
msgstr ""
msgid "Are you sure that you want to archive this project?"
@@ -4929,12 +4975,18 @@ msgstr ""
msgid "Are you sure you want to delete this SSH key?"
msgstr ""
+msgid "Are you sure you want to delete this comment?"
+msgstr ""
+
msgid "Are you sure you want to delete this deploy key?"
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 label?"
+msgstr ""
+
msgid "Are you sure you want to delete this pipeline schedule?"
msgstr ""
@@ -4950,9 +5002,6 @@ msgstr ""
msgid "Are you sure you want to discard your changes?"
msgstr ""
-msgid "Are you sure you want to erase this build?"
-msgstr ""
-
msgid "Are you sure you want to import %d repository?"
msgid_plural "Are you sure you want to import %d repositories?"
msgstr[0] ""
@@ -5002,6 +5051,9 @@ msgstr ""
msgid "Are you sure you want to remove this list?"
msgstr ""
+msgid "Are you sure you want to remove this nickname?"
+msgstr ""
+
msgid "Are you sure you want to reset the health check token?"
msgstr ""
@@ -5014,10 +5066,10 @@ 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?"
+msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
msgstr ""
-msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
+msgid "Are you sure you want to revoke this project access token? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to stop this environment?"
@@ -5164,9 +5216,6 @@ msgstr ""
msgid "Assigned to %{assignee_name}"
msgstr ""
-msgid "Assigned to %{name}"
-msgstr ""
-
msgid "Assigned to me"
msgstr ""
@@ -5235,6 +5284,9 @@ msgstr[3] ""
msgid "Attaching the file failed."
msgstr ""
+msgid "Attention"
+msgstr ""
+
msgid "Audit Events"
msgstr ""
@@ -5397,6 +5449,12 @@ msgstr ""
msgid "Authorized applications (%{size})"
msgstr ""
+msgid "AuthorizedApplication|Are you sure you want to revoke this application?"
+msgstr ""
+
+msgid "AuthorizedApplication|Revoke application"
+msgstr ""
+
msgid "Authors: %{authors}"
msgstr ""
@@ -6598,6 +6656,9 @@ msgstr ""
msgid "CICDAnalytics|Shared Runners Usage"
msgstr ""
+msgid "CICDAnalytics|Shared runner pipeline minute duration by month"
+msgstr ""
+
msgid "CICDAnalytics|Shared runner usage"
msgstr ""
@@ -6739,6 +6800,9 @@ msgstr ""
msgid "Can create groups:"
msgstr ""
+msgid "Can not delete primary training"
+msgstr ""
+
msgid "Can't apply as the source branch was deleted."
msgstr ""
@@ -7072,9 +7136,6 @@ msgstr ""
msgid "Changing any setting here requires an application restart"
msgstr ""
-msgid "Changing group URL can have unintended side effects."
-msgstr ""
-
msgid "Charts can't be displayed as the request for data has timed out. %{documentationLink}"
msgstr ""
@@ -7162,9 +7223,6 @@ msgstr ""
msgid "Checking branch availability..."
msgstr ""
-msgid "Checking group URL availability..."
-msgstr ""
-
msgid "Checking group path availability..."
msgstr ""
@@ -7662,6 +7720,9 @@ msgstr ""
msgid "Clear recent searches"
msgstr ""
+msgid "Clear repository checks"
+msgstr ""
+
msgid "Clear search"
msgstr ""
@@ -7794,9 +7855,6 @@ msgstr ""
msgid "Closed MRs"
msgstr ""
-msgid "Closed epics"
-msgstr ""
-
msgid "Closed issues"
msgstr ""
@@ -7833,13 +7891,13 @@ msgstr ""
msgid "Cluster level"
msgstr ""
-msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
+msgid "Cluster type must be specified for Stages::ClusterEndpointInserter"
msgstr ""
msgid "ClusterAgents|%{name} successfully deleted"
msgstr ""
-msgid "ClusterAgents|%{number} of %{total} Agents"
+msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
@@ -7881,6 +7939,15 @@ msgstr ""
msgid "ClusterAgents|Agent never connected to GitLab"
msgstr ""
+msgid "ClusterAgents|Agent version mismatch"
+msgstr ""
+
+msgid "ClusterAgents|Agent version mismatch and update"
+msgstr ""
+
+msgid "ClusterAgents|Agent version update required"
+msgstr ""
+
msgid "ClusterAgents|All"
msgstr ""
@@ -7905,7 +7972,7 @@ msgstr ""
msgid "ClusterAgents|Configuration"
msgstr ""
-msgid "ClusterAgents|Connect a cluster through the Agent"
+msgid "ClusterAgents|Connect a cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connect existing cluster"
@@ -7914,13 +7981,13 @@ msgstr ""
msgid "ClusterAgents|Connect with a certificate"
msgstr ""
-msgid "ClusterAgents|Connect with agent"
+msgid "ClusterAgents|Connect with an agent"
msgstr ""
msgid "ClusterAgents|Connect with the GitLab Agent"
msgstr ""
-msgid "ClusterAgents|Connect your cluster through the Agent"
+msgid "ClusterAgents|Connect your cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connected"
@@ -7980,7 +8047,10 @@ msgstr ""
msgid "ClusterAgents|How to register an agent?"
msgstr ""
-msgid "ClusterAgents|Install new Agent"
+msgid "ClusterAgents|How to update an agent?"
+msgstr ""
+
+msgid "ClusterAgents|Install a new agent"
msgstr ""
msgid "ClusterAgents|Last connected %{timeAgo}."
@@ -8007,7 +8077,7 @@ msgstr ""
msgid "ClusterAgents|Never connected"
msgstr ""
-msgid "ClusterAgents|No Agents"
+msgid "ClusterAgents|No agents"
msgstr ""
msgid "ClusterAgents|No clusters connected through cluster certificates"
@@ -8067,6 +8137,9 @@ msgstr ""
msgid "ClusterAgents|The agent has not been connected in a long time. There might be a connectivity issue. Last contact was %{timeAgo}."
msgstr ""
+msgid "ClusterAgents|The agent version do not match each other across your cluster's pods. This can happen when a new agent version was just deployed and Kubernetes is shutting down the old pods."
+msgstr ""
+
msgid "ClusterAgents|The recommended installation method includes the token. If you want to follow the advanced installation method provided in the docs, make sure you save the token value before you close this window."
msgstr ""
@@ -8116,6 +8189,9 @@ msgstr ""
msgid "ClusterAgents|You will need to create a token to connect to your agent"
msgstr ""
+msgid "ClusterAgents|Your agent version is out of sync with your GitLab version (v%{version}), which might cause compatibility problems. Update the agent installed on your cluster to the most recent version."
+msgstr ""
+
msgid "ClusterAgents|Your instance doesn't have the %{linkStart}GitLab Agent Server (KAS)%{linkEnd} set up. Ask a GitLab Administrator to install it."
msgstr ""
@@ -8992,9 +9068,6 @@ msgstr ""
msgid "Comma-separated list of email addresses."
msgstr ""
-msgid "Comma-separated list of users allowed to exceed the rate limit."
-msgstr ""
-
msgid "Comma-separated, e.g. '1.1.1.1, 2.2.2.0/24'"
msgstr ""
@@ -9323,6 +9396,12 @@ msgstr ""
msgid "Confidential"
msgstr ""
+msgid "Confidential issue"
+msgstr ""
+
+msgid "Confidential note"
+msgstr ""
+
msgid "Confidentiality"
msgstr ""
@@ -9356,6 +9435,9 @@ msgstr ""
msgid "Configure Dependency Scanning in `.gitlab-ci.yml`, creating this file if it does not already exist"
msgstr ""
+msgid "Configure GitLab"
+msgstr ""
+
msgid "Configure GitLab runners to start using the Web Terminal. %{helpStart}Learn more.%{helpEnd}"
msgstr ""
@@ -9404,6 +9486,15 @@ msgstr ""
msgid "Configure pipelines to deploy web apps, backend services, APIs and static resources to Google Cloud"
msgstr ""
+msgid "Configure region"
+msgstr ""
+
+msgid "Configure region for environment"
+msgstr ""
+
+msgid "Configure regions"
+msgstr ""
+
msgid "Configure repository mirroring."
msgstr ""
@@ -9437,6 +9528,9 @@ msgstr ""
msgid "Configure which lists are shown for anyone who visits this board"
msgstr ""
+msgid "Configure your environments to be deployed to specific geographical regions"
+msgstr ""
+
msgid "Confirm"
msgstr ""
@@ -10145,10 +10239,10 @@ msgstr ""
msgid "CorpusManagement|Actions"
msgstr ""
-msgid "CorpusManagement|Corpus are used in fuzz testing as mutation source to Improve future testing."
+msgid "CorpusManagement|Corpus file"
msgstr ""
-msgid "CorpusManagement|Corpus file"
+msgid "CorpusManagement|Corpus files are used in coverage-guided fuzz testing as seed inputs to improve testing."
msgstr ""
msgid "CorpusManagement|Corpus files must be in *.zip format. Maximum 5 GB"
@@ -10202,6 +10296,9 @@ msgstr ""
msgid "Could not apply %{name} command."
msgstr ""
+msgid "Could not apply %{name} command. %{message}."
+msgstr ""
+
msgid "Could not authorize chat nickname. Try again!"
msgstr ""
@@ -10352,6 +10449,9 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
+msgid "Create a group"
+msgstr ""
+
msgid "Create a merge request"
msgstr ""
@@ -10376,6 +10476,9 @@ msgstr ""
msgid "Create a personal access token on your account to pull or push via %{protocol}."
msgstr ""
+msgid "Create a project"
+msgstr ""
+
msgid "Create an account using:"
msgstr ""
@@ -10739,6 +10842,9 @@ msgstr ""
msgid "Creation date"
msgstr ""
+msgid "Creator"
+msgstr ""
+
msgid "Credentials"
msgstr ""
@@ -10751,9 +10857,15 @@ msgstr ""
msgid "CredentialsInventory|Personal Access Tokens"
msgstr ""
+msgid "CredentialsInventory|Project Access Tokens"
+msgstr ""
+
msgid "CredentialsInventory|SSH Keys"
msgstr ""
+msgid "Credit card required to be on file in order to create a pipeline"
+msgstr ""
+
msgid "Credit card:"
msgstr ""
@@ -10937,9 +11049,6 @@ msgstr ""
msgid "Customer relations"
msgstr ""
-msgid "Customizable by an administrator."
-msgstr ""
-
msgid "Customizable by owners."
msgstr ""
@@ -11069,30 +11178,18 @@ msgstr ""
msgid "CycleAnalytics|%{selectedLabelsCount} selected (%{maxLabels} max)"
msgstr ""
-msgid "CycleAnalytics|%{stageCount} stages selected"
-msgstr ""
-
-msgid "CycleAnalytics|All stages"
-msgstr ""
-
-msgid "CycleAnalytics|Average days to completion"
+msgid "CycleAnalytics|Average time to completion"
msgstr ""
msgid "CycleAnalytics|Date"
msgstr ""
-msgid "CycleAnalytics|Days to completion"
-msgstr ""
-
msgid "CycleAnalytics|Display chart filters"
msgstr ""
msgid "CycleAnalytics|Lead Time for Changes"
msgstr ""
-msgid "CycleAnalytics|No stages selected"
-msgstr ""
-
msgid "CycleAnalytics|Number of tasks"
msgstr ""
@@ -11125,18 +11222,30 @@ msgstr ""
msgid "CycleAnalytics|Showing data for group '%{groupName}' from %{createdAfter} to %{createdBefore}"
msgstr ""
-msgid "CycleAnalytics|Stages"
+msgid "CycleAnalytics|Stage time: %{title}"
msgstr ""
msgid "CycleAnalytics|Tasks by type"
msgstr ""
-msgid "CycleAnalytics|The average time spent in the selected stage for the items that were completed on each date. Data limited to the last 500 items."
+msgid "CycleAnalytics|The average time items spent in this stage. Data limited to items completed within this date range."
msgstr ""
msgid "CycleAnalytics|The given date range is larger than 180 days"
msgstr ""
+msgid "CycleAnalytics|The total time items spent across each value stream stage. Data limited to items completed within this date range."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Stage time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Total time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|Total time"
+msgstr ""
+
msgid "CycleAnalytics|Type of work"
msgstr ""
@@ -11149,9 +11258,6 @@ msgstr ""
msgid "CycleAnalytics|project dropdown filter"
msgstr ""
-msgid "CycleAnalytics|stage dropdown"
-msgstr ""
-
msgid "DAG visualization requires at least 3 dependent jobs."
msgstr ""
@@ -11251,10 +11357,16 @@ msgstr ""
msgid "DastProfiles|AJAX spider"
msgstr ""
+msgid "DastProfiles|API"
+msgstr ""
+
+msgid "DastProfiles|API endpoint URL"
+msgstr ""
+
msgid "DastProfiles|Active"
msgstr ""
-msgid "DastProfiles|Additional request headers (Optional)"
+msgid "DastProfiles|Additional request headers (optional)"
msgstr ""
msgid "DastProfiles|Are you sure you want to delete this profile?"
@@ -11269,6 +11381,9 @@ msgstr ""
msgid "DastProfiles|Branch missing"
msgstr ""
+msgid "DastProfiles|Choose a scan method"
+msgstr ""
+
msgid "DastProfiles|Could not create the scanner profile. Please try again."
msgstr ""
@@ -11338,7 +11453,13 @@ msgstr ""
msgid "DastProfiles|Excluded URLs"
msgstr ""
-msgid "DastProfiles|Excluded URLs (Optional)"
+msgid "DastProfiles|Excluded URLs (optional)"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths (optional)"
msgstr ""
msgid "DastProfiles|Hide debug messages"
@@ -11395,9 +11516,6 @@ msgstr ""
msgid "DastProfiles|Request headers"
msgstr ""
-msgid "DastProfiles|Rest API"
-msgstr ""
-
msgid "DastProfiles|Run the AJAX spider, in addition to the traditional spider, to crawl the target site."
msgstr ""
@@ -11407,6 +11525,9 @@ msgstr ""
msgid "DastProfiles|Save profile"
msgstr ""
+msgid "DastProfiles|Scan method"
+msgstr ""
+
msgid "DastProfiles|Scan mode"
msgstr ""
@@ -11485,12 +11606,24 @@ msgstr ""
msgid "DastProfiles|Website"
msgstr ""
+msgid "DastProfiles|What does each method do?"
+msgstr ""
+
msgid "DastProfiles|You can either choose a passive scan or validate the target site from the site profile management page. %{docsLinkStart}Learn more about site validation.%{docsLinkEnd}"
msgstr ""
msgid "DastProfiles|You cannot run an active scan against an unvalidated site."
msgstr ""
+msgid "DastProfiles|folder/dast_example.har or https://example.com/dast_example.har"
+msgstr ""
+
+msgid "DastProfiles|folder/example.postman_collection.json or https://example.com/"
+msgstr ""
+
+msgid "DastProfiles|folder/openapi.json or https://example.com/openapi.json"
+msgstr ""
+
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
@@ -11600,6 +11733,9 @@ msgstr ""
msgid "DatadogIntegration|API URL"
msgstr ""
+msgid "DatadogIntegration|Custom tags in Datadog. Enter one tag per line in the %{codeOpen}key:value%{codeClose} format. %{linkOpen}How do I use tags?%{linkClose}"
+msgstr ""
+
msgid "DatadogIntegration|Environment"
msgstr ""
@@ -11618,12 +11754,18 @@ msgstr ""
msgid "DatadogIntegration|Tag all data from this GitLab instance in Datadog. Useful when managing several self-managed deployments."
msgstr ""
+msgid "DatadogIntegration|Tags"
+msgstr ""
+
msgid "DatadogIntegration|The Datadog site to send data to. To send data to the EU site, use %{codeOpen}datadoghq.eu%{codeClose}."
msgstr ""
msgid "DatadogIntegration|Trace your GitLab pipelines with Datadog."
msgstr ""
+msgid "DatadogIntegration|have an invalid format"
+msgstr ""
+
msgid "Datasource name not found"
msgstr ""
@@ -11633,9 +11775,6 @@ msgstr ""
msgid "Date merged"
msgstr ""
-msgid "Date picker"
-msgstr ""
-
msgid "Date range"
msgstr ""
@@ -11789,9 +11928,6 @@ msgstr ""
msgid "Definition"
msgstr ""
-msgid "Delayed Project Deletion (%{adjourned_deletion})"
-msgstr ""
-
msgid "DelayedJobs|Are you sure you want to run %{jobName} immediately? Otherwise this job will run automatically after its timer finishes."
msgstr ""
@@ -11870,10 +12006,10 @@ msgstr ""
msgid "Delete pipeline"
msgstr ""
-msgid "Delete project"
+msgid "Delete pipeline schedule"
msgstr ""
-msgid "Delete project. Are you ABSOLUTELY SURE?"
+msgid "Delete project"
msgstr ""
msgid "Delete row"
@@ -11903,6 +12039,9 @@ msgstr ""
msgid "Delete this epic and all descendants?"
msgstr ""
+msgid "Delete this project"
+msgstr ""
+
msgid "Delete user list"
msgstr ""
@@ -12173,6 +12312,12 @@ msgstr ""
msgid "Deploy to..."
msgstr ""
+msgid "DeployBoards|To see deployment progress for your environments, make sure you are deploying to %{codeStart}$KUBE_NAMESPACE%{codeEnd} and annotating with %{codeStart}app.gitlab.com/app=$CI_PROJECT_PATH_SLUG%{codeEnd} and %{codeStart}app.gitlab.com/env=$CI_ENVIRONMENT_SLUG%{codeEnd}."
+msgstr ""
+
+msgid "DeployBoard|Kubernetes Pods"
+msgstr ""
+
msgid "DeployFreeze|Add a freeze period to prevent unintended releases during a period of time for a given environment. You must update the deployment jobs in %{filename} according to the deploy freezes added here. %{freeze_period_link_start}Learn more.%{freeze_period_link_end}"
msgstr ""
@@ -12257,9 +12402,6 @@ msgstr ""
msgid "DeployTokens|Active Deploy Tokens (%{active_tokens})"
msgstr ""
-msgid "DeployTokens|Allows read and write access to registry images."
-msgstr ""
-
msgid "DeployTokens|Allows read and write access to the package registry."
msgstr ""
@@ -12272,6 +12414,9 @@ msgstr ""
msgid "DeployTokens|Allows read-only access to the repository."
msgstr ""
+msgid "DeployTokens|Allows write access to registry images."
+msgstr ""
+
msgid "DeployTokens|Copy deploy token"
msgstr ""
@@ -12365,12 +12510,57 @@ msgstr ""
msgid "Deploying to AWS is easy with GitLab"
msgstr ""
+msgid "Deployment"
+msgstr ""
+
msgid "Deployment Frequency"
msgstr ""
+msgid "Deployment Target|Project deployment target (optional)"
+msgstr ""
+
+msgid "Deployment Target|Select the deployment target"
+msgstr ""
+
msgid "Deployment frequency"
msgstr ""
+msgid "DeploymentTarget|GitLab Pages"
+msgstr ""
+
+msgid "DeploymentTarget|Heroku"
+msgstr ""
+
+msgid "DeploymentTarget|Infrastructure provider (Terraform, Cloudformation, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Kubernetes (GKE, EKS, OpenShift, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Managed container runtime (Fargate, Cloud Run, DigitalOcean App)"
+msgstr ""
+
+msgid "DeploymentTarget|Mobile app store"
+msgstr ""
+
+msgid "DeploymentTarget|No deployment planned"
+msgstr ""
+
+msgid "DeploymentTarget|Other hosting service"
+msgstr ""
+
+msgid "DeploymentTarget|Registry (package or container)"
+msgstr ""
+
+msgid "DeploymentTarget|Self-managed container runtime (Podman, Docker Swarm, Docker Compose)"
+msgstr ""
+
+msgid "DeploymentTarget|Serverless backend (Lambda, Cloud functions)"
+msgstr ""
+
+msgid "DeploymentTarget|Virtual machine (for example, EC2)"
+msgstr ""
+
msgid "Deployments"
msgstr ""
@@ -12411,6 +12601,9 @@ msgstr ""
msgid "Deployment|This deployment was created using the API"
msgstr ""
+msgid "Deployment|Triggerer"
+msgstr ""
+
msgid "Deployment|Waiting"
msgstr ""
@@ -12438,6 +12631,18 @@ msgstr ""
msgid "Deprecated API rate limits"
msgstr ""
+msgid "Deprecations|Feature deprecation and removal"
+msgstr ""
+
+msgid "Deprecations|For information on a possible replacement %{epicStart} learn more about Opstrace %{epicEnd}."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7 and are %{epicStart} scheduled for removal %{epicEnd} in GitLab 15.0."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7, and are %{removal_link_start} scheduled for removal %{link_end} in GitLab 15.0. For information on a possible replacement, %{opstrace_link_start} learn more about Opstrace %{link_end}."
+msgstr ""
+
msgid "Deprioritize label"
msgstr ""
@@ -12685,10 +12890,10 @@ msgstr ""
msgid "DevopsAdoption|At least one deploy"
msgstr ""
-msgid "DevopsAdoption|At least one issue opened"
+msgid "DevopsAdoption|At least one issue created"
msgstr ""
-msgid "DevopsAdoption|At least one merge request opened"
+msgid "DevopsAdoption|At least one merge request created"
msgstr ""
msgid "DevopsAdoption|At least one pipeline successfully run"
@@ -12895,6 +13100,9 @@ msgstr ""
msgid "Direct member"
msgstr ""
+msgid "Direct members"
+msgstr ""
+
msgid "Direct non-authenticated users to this page."
msgstr ""
@@ -13013,6 +13221,9 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "Dismiss Alert"
+msgstr ""
+
msgid "Dismiss merge request promotion"
msgstr ""
@@ -13040,9 +13251,15 @@ msgstr ""
msgid "Display alerts from all configured monitoring tools."
msgstr ""
+msgid "Display milestones"
+msgstr ""
+
msgid "Display name"
msgstr ""
+msgid "Display progress of child issues"
+msgstr ""
+
msgid "Display rendered file"
msgstr ""
@@ -13148,6 +13365,9 @@ msgstr ""
msgid "Download image"
msgstr ""
+msgid "Download payload"
+msgstr ""
+
msgid "Download raw data (.csv)"
msgstr ""
@@ -13325,6 +13545,9 @@ msgstr ""
msgid "Edit in Web IDE"
msgstr ""
+msgid "Edit in pipeline editor"
+msgstr ""
+
msgid "Edit in single-file editor"
msgstr ""
@@ -13367,6 +13590,9 @@ msgstr ""
msgid "Edit your most recent comment in a thread (from an empty textarea)"
msgstr ""
+msgid "Edit, lint, and visualize your pipeline."
+msgstr ""
+
msgid "Edited"
msgstr ""
@@ -13808,6 +14034,9 @@ msgstr ""
msgid "Enforce two-factor authentication for all user sign-ins."
msgstr ""
+msgid "Enhance security by storing service account keys in secret managers - learn more about %{docLinkStart}secret management with GitLab%{docLinkEnd}"
+msgstr ""
+
msgid "Ensure connectivity is available from the GitLab server to the Prometheus server"
msgstr ""
@@ -13868,6 +14097,9 @@ 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 following to confirm:"
+msgstr ""
+
msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
@@ -14400,9 +14632,6 @@ 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 ""
@@ -14538,6 +14767,9 @@ msgstr ""
msgid "Errors:"
msgstr ""
+msgid "Escalate this incident"
+msgstr ""
+
msgid "Escalation Policies"
msgstr ""
@@ -14550,6 +14782,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy"
+msgstr ""
+
msgid "Escalation policy:"
msgstr ""
@@ -14803,6 +15038,9 @@ msgstr ""
msgid "Existing sign in methods may be removed"
msgstr ""
+msgid "Exit."
+msgstr ""
+
msgid "Expand"
msgstr ""
@@ -14899,6 +15137,9 @@ msgstr ""
msgid "Explore public groups"
msgstr ""
+msgid "Explore public projects"
+msgstr ""
+
msgid "Explore snippets"
msgstr ""
@@ -15062,7 +15303,7 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
-msgid "Failed to assign a reviewer because no user was found."
+msgid "Failed to assign a reviewer because no user was specified."
msgstr ""
msgid "Failed to assign a user because no user was found."
@@ -15128,10 +15369,10 @@ msgstr ""
msgid "Failed to find import label for Jira import."
msgstr ""
-msgid "Failed to generate export, please try again later."
+msgid "Failed to find users for %{missing}"
msgstr ""
-msgid "Failed to generate report, please try again after sometime"
+msgid "Failed to generate export, please try again later."
msgstr ""
msgid "Failed to get ref."
@@ -15230,6 +15471,9 @@ msgstr ""
msgid "Failed to remove a to-do item for the design."
msgstr ""
+msgid "Failed to remove attention because no user was found."
+msgstr ""
+
msgid "Failed to remove mirror."
msgstr ""
@@ -15242,6 +15486,9 @@ msgstr ""
msgid "Failed to remove user key."
msgstr ""
+msgid "Failed to request attention because no user was found."
+msgstr ""
+
msgid "Failed to reset key. Please try again."
msgstr ""
@@ -15323,6 +15570,9 @@ msgstr ""
msgid "Feature Flags"
msgstr ""
+msgid "Feature deprecation and removal"
+msgstr ""
+
msgid "Feature flag status"
msgstr ""
@@ -15822,7 +16072,7 @@ msgstr ""
msgid "For each job, re-use the project workspace. If the workspace doesn't exist, use %{code_open}git clone%{code_close}."
msgstr ""
-msgid "For example, the application using the token or the purpose of the token."
+msgid "For example, the application using the token or the purpose of the token. Do not give sensitive information for the name of the token, as it will be visible to all %{resource_type} members."
msgstr ""
msgid "For files larger than this limit, only index the file name. The file content is neither indexed nor searchable."
@@ -15906,9 +16156,6 @@ msgstr ""
msgid "ForkProject|Select a namespace"
msgstr ""
-msgid "ForkProject|Select a namespace to fork the project"
-msgstr ""
-
msgid "ForkProject|The project can be accessed by any logged in user."
msgstr ""
@@ -16005,6 +16252,9 @@ msgstr ""
msgid "Full name"
msgstr ""
+msgid "GCP region configured"
+msgstr ""
+
msgid "GPG Key ID:"
msgstr ""
@@ -16185,6 +16435,9 @@ msgstr ""
msgid "Geo|Failed"
msgstr ""
+msgid "Geo|Filter Geo sites"
+msgstr ""
+
msgid "Geo|Filter by name"
msgstr ""
@@ -16596,6 +16849,12 @@ msgstr ""
msgid "GitLab Issue"
msgstr ""
+msgid "GitLab KAS"
+msgstr ""
+
+msgid "GitLab Memberships CSV Export"
+msgstr ""
+
msgid "GitLab Pages"
msgstr ""
@@ -16644,6 +16903,9 @@ 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 free to use. Many features for larger teams are part of our %{link_start}paid products%{link_end}. You can try Ultimate for free without any obligation or payment details."
+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 ""
@@ -16770,7 +17032,7 @@ msgstr ""
msgid "GitLabPages|When enabled, all attempts to visit your website through HTTP are automatically redirected to HTTPS using a response with status code 301. Requires a valid certificate for all domains. %{docs_link_start}Learn more.%{link_end}"
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. %{docs_link_start}Learn more.%{link_end}"
+msgid "GitLabPages|When using Pages under the general domain of a GitLab instance (%{pages_host}), you cannot use HTTPS with subdomains of subdomains. If your namespace or groupname contains a dot, it does not work. This is a limitation of the HTTP Over TLS protocol. HTTP pages work if you don't redirect HTTP to HTTPS. %{docs_link_start}Learn more.%{link_end}"
msgstr ""
msgid "GitLabPages|With GitLab Pages you can host your static website directly from your GitLab repository. %{docs_link_start}Learn more.%{link_end}"
@@ -16947,9 +17209,6 @@ msgstr ""
msgid "Go to find file"
msgstr ""
-msgid "Go to fork"
-msgstr ""
-
msgid "Go to issue boards"
msgstr ""
@@ -17157,9 +17416,6 @@ msgstr ""
msgid "Group Hooks"
msgstr ""
-msgid "Group ID"
-msgstr ""
-
msgid "Group Owner must have signed in with SAML before enabling Group Managed Accounts"
msgstr ""
@@ -17187,9 +17443,6 @@ msgstr ""
msgid "Group by"
msgstr ""
-msgid "Group description"
-msgstr ""
-
msgid "Group description (optional)"
msgstr ""
@@ -17304,7 +17557,7 @@ msgstr ""
msgid "Group: %{name}"
msgstr ""
-msgid "GroupActivityMetrics|Issues opened"
+msgid "GroupActivityMetrics|Issues created"
msgstr ""
msgid "GroupActivityMetrics|Last 90 days"
@@ -17313,7 +17566,7 @@ msgstr ""
msgid "GroupActivityMetrics|Members added"
msgstr ""
-msgid "GroupActivityMetrics|Merge Requests opened"
+msgid "GroupActivityMetrics|Merge Requests created"
msgstr ""
msgid "GroupActivityMetrics|Recent activity"
@@ -17604,6 +17857,9 @@ msgstr ""
msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
+msgid "GroupSettings|Choose a group path that does not start with a dash or end with a period. It can also contain alphanumeric characters and underscores."
+msgstr ""
+
msgid "GroupSettings|Compliance frameworks"
msgstr ""
@@ -17637,7 +17893,7 @@ msgstr ""
msgid "GroupSettings|If not specified at the group or instance level, the default is %{default_initial_branch_name}. Does not affect existing repositories."
msgstr ""
-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."
+msgid "GroupSettings|If the parent group's visibility is lower than the group's current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility."
msgstr ""
msgid "GroupSettings|New runners registration token has been generated!"
@@ -17754,7 +18010,10 @@ msgstr ""
msgid "Groups and projects"
msgstr ""
-msgid "Groups and subgroups"
+msgid "Groups are a great way to organize projects and people."
+msgstr ""
+
+msgid "Groups are the best way to manage projects and members."
msgstr ""
msgid "Groups to synchronize"
@@ -17865,13 +18124,16 @@ msgstr ""
msgid "GroupsTree|Are you sure you want to leave the \"%{fullName}\" group?"
msgstr ""
-msgid "GroupsTree|Edit group"
+msgid "GroupsTree|Delete"
+msgstr ""
+
+msgid "GroupsTree|Edit"
msgstr ""
msgid "GroupsTree|Failed to leave the group. Please make sure you are not the only owner."
msgstr ""
-msgid "GroupsTree|Leave this group"
+msgid "GroupsTree|Leave group"
msgstr ""
msgid "GroupsTree|Loading groups"
@@ -17883,9 +18145,57 @@ msgstr ""
msgid "GroupsTree|No groups or projects matched your search"
msgstr ""
+msgid "GroupsTree|Options"
+msgstr ""
+
msgid "GroupsTree|Search by name"
msgstr ""
+msgid "Groups|Avatar will be removed. Are you sure?"
+msgstr ""
+
+msgid "Groups|Changing group URL can have unintended side effects."
+msgstr ""
+
+msgid "Groups|Checking group URL availability..."
+msgstr ""
+
+msgid "Groups|Enter a descriptive name for your group."
+msgstr ""
+
+msgid "Groups|Group ID"
+msgstr ""
+
+msgid "Groups|Group URL"
+msgstr ""
+
+msgid "Groups|Group avatar"
+msgstr ""
+
+msgid "Groups|Group description (optional)"
+msgstr ""
+
+msgid "Groups|Group name"
+msgstr ""
+
+msgid "Groups|Group path is available."
+msgstr ""
+
+msgid "Groups|Group path is unavailable. Path has been replaced with a suggested available path."
+msgstr ""
+
+msgid "Groups|Learn more"
+msgstr ""
+
+msgid "Groups|Must start with letter, digit, emoji, or underscore. Can also contain periods, dashes, spaces, and parentheses."
+msgstr ""
+
+msgid "Groups|Remove avatar"
+msgstr ""
+
+msgid "Groups|Save changes"
+msgstr ""
+
msgid "Guideline"
msgstr ""
@@ -17895,6 +18205,9 @@ msgstr ""
msgid "HAR file path or URL"
msgstr ""
+msgid "HTTP Archive (HAR)"
+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 ""
@@ -18299,6 +18612,9 @@ msgstr ""
msgid "INFO: Your SSH key is expiring soon. Please generate a new key."
msgstr ""
+msgid "IP"
+msgstr ""
+
msgid "IP Address"
msgstr ""
@@ -18335,6 +18651,9 @@ msgstr ""
msgid "IdentityVerification|Verify your identity"
msgstr ""
+msgid "IdentityVerification|You can always verify your account at a later time to create a group."
+msgstr ""
+
msgid "If any indexed field exceeds this limit, it is truncated to this number of characters. The rest of the content is neither indexed nor searchable. This does not apply to repository and wiki indexing. For unlimited characters, set this to 0."
msgstr ""
@@ -18392,6 +18711,9 @@ msgstr ""
msgid "If you add %{codeStart}needs%{codeEnd} to jobs in your pipeline you'll be able to view the %{codeStart}needs%{codeEnd} relationships between jobs in this tab as a %{linkStart}Directed Acyclic Graph (DAG)%{linkEnd}."
msgstr ""
+msgid "If you are added to a project, it will be displayed here."
+msgstr ""
+
msgid "If you did not initiate these sign-in attempts, please reach out to your administrator or enable two-factor authentication (2FA) on your account."
msgstr ""
@@ -18704,12 +19026,24 @@ msgstr ""
msgid "InProductMarketing|3 ways to dive into GitLab CI/CD"
msgstr ""
+msgid "InProductMarketing|A single application eliminates complex integrations, data chokepoints, and toolchain maintenance, resulting in greater productivity and lower cost."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features, build more efficiently, strengthen security and compliance."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features."
+msgstr ""
+
msgid "InProductMarketing|Actually, GitLab makes the team work (better)"
msgstr ""
msgid "InProductMarketing|And finally %{deploy_link} a Python application."
msgstr ""
+msgid "InProductMarketing|And many more..."
+msgstr ""
+
msgid "InProductMarketing|Are your runners ready?"
msgstr ""
@@ -18728,15 +19062,33 @@ msgstr ""
msgid "InProductMarketing|Blog"
msgstr ""
+msgid "InProductMarketing|Break down silos to coordinate seamlessly across development, operations, and security with a consistent experience across the development lifecycle."
+msgstr ""
+
+msgid "InProductMarketing|Burn up/down charts"
+msgstr ""
+
msgid "InProductMarketing|By enabling code owners and required merge approvals the right person will review the right MR. This is a win-win: cleaner code and a more efficient review process."
msgstr ""
msgid "InProductMarketing|Click on the number below that corresponds with your answer — 1 being very difficult, 5 being very easy."
msgstr ""
+msgid "InProductMarketing|Code owners"
+msgstr ""
+
msgid "InProductMarketing|Code owners and required merge approvals are part of the paid tiers of GitLab. You can start a free 30-day trial of GitLab Ultimate and enable these features in less than 5 minutes with no credit card required."
msgstr ""
+msgid "InProductMarketing|Code review analytics"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration across stages in GitLab"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration made easy"
+msgstr ""
+
msgid "InProductMarketing|Create a custom CI runner with just a few clicks"
msgstr ""
@@ -18746,12 +19098,21 @@ msgstr ""
msgid "InProductMarketing|Create a project in GitLab in 5 minutes"
msgstr ""
+msgid "InProductMarketing|Create well-defined workflows by using scoped labels on issues, merge requests, and epics. Labels with the same scope cannot be used together, which prevents conflicts."
+msgstr ""
+
msgid "InProductMarketing|Create your first project!"
msgstr ""
+msgid "InProductMarketing|Define who owns specific files or directories, so the right reviewers are suggested when a merge request introduces changes to those files."
+msgstr ""
+
msgid "InProductMarketing|Deliver Better Products Faster"
msgstr ""
+msgid "InProductMarketing|Dependency scanning"
+msgstr ""
+
msgid "InProductMarketing|Did you know teams that use GitLab are far more efficient?"
msgstr ""
@@ -18761,15 +19122,27 @@ msgstr ""
msgid "InProductMarketing|Dig in and create a project and a repo"
msgstr ""
+msgid "InProductMarketing|Discover Premium & Ultimate"
+msgstr ""
+
+msgid "InProductMarketing|Discover Premium & Ultimate."
+msgstr ""
+
msgid "InProductMarketing|Do you have a minute?"
msgstr ""
msgid "InProductMarketing|Do you have a teammate who would be perfect for this task?"
msgstr ""
+msgid "InProductMarketing|Dynamic application security testing"
+msgstr ""
+
msgid "InProductMarketing|Easy"
msgstr ""
+msgid "InProductMarketing|Epics"
+msgstr ""
+
msgid "InProductMarketing|Expand your DevOps journey with a free GitLab trial"
msgstr ""
@@ -18791,9 +19164,15 @@ msgstr ""
msgid "InProductMarketing|Feel the need for speed?"
msgstr ""
+msgid "InProductMarketing|Find and fix bottlenecks in your code review process by understanding how long open merge requests have been in review."
+msgstr ""
+
msgid "InProductMarketing|Find out how your teams are really doing"
msgstr ""
+msgid "InProductMarketing|Find out if your external libraries are safe. Run dependency scanning jobs that check for known vulnerabilities in your external libraries."
+msgstr ""
+
msgid "InProductMarketing|Follow our steps"
msgstr ""
@@ -18830,6 +19209,9 @@ msgstr ""
msgid "InProductMarketing|GitLab is better with teammates to help out!"
msgstr ""
+msgid "InProductMarketing|GitLab is infrastructure agnostic (supporting GCP, AWS, Azure, OpenShift, VMWare, On Prem, Bare Metal, and more), offering a consistent workflow experience – irrespective of the environment."
+msgstr ""
+
msgid "InProductMarketing|GitLab provides static application security testing (SAST), dynamic application security testing (DAST), container scanning, and dependency scanning to help you deliver secure applications along with license compliance."
msgstr ""
@@ -18920,21 +19302,36 @@ msgstr ""
msgid "InProductMarketing|It's also possible to simply %{external_repo_link} in order to take advantage of GitLab's CI/CD."
msgstr ""
+msgid "InProductMarketing|Keep your code quality high by defining who should approve merge requests and how many approvals are required."
+msgstr ""
+
msgid "InProductMarketing|Launch GitLab CI/CD in 20 minutes or less"
msgstr ""
+msgid "InProductMarketing|Lower cost of development"
+msgstr ""
+
+msgid "InProductMarketing|Make it easier to collaborate on high-level ideas by grouping related issues in an epic."
+msgstr ""
+
msgid "InProductMarketing|Making the switch? It's easier than you think to import your projects into GitLab. Move %{github_link}, or import something %{bitbucket_link}."
msgstr ""
msgid "InProductMarketing|Master the art of importing!"
msgstr ""
+msgid "InProductMarketing|Merge request approval rule"
+msgstr ""
+
msgid "InProductMarketing|Move on to easily creating a Pages website %{ci_template_link}"
msgstr ""
msgid "InProductMarketing|Multiple owners, confusing workstreams? We've got you covered"
msgstr ""
+msgid "InProductMarketing|Multiple required approvers"
+msgstr ""
+
msgid "InProductMarketing|Need an alternative to importing?"
msgstr ""
@@ -18947,18 +19344,33 @@ msgstr ""
msgid "InProductMarketing|Our tool brings all the things together"
msgstr ""
+msgid "InProductMarketing|Protect your web application by using DAST to examine for vulnerabilities in deployed environments."
+msgstr ""
+
msgid "InProductMarketing|Rapid development, simplified"
msgstr ""
msgid "InProductMarketing|Reduce Security & Compliance Risk"
msgstr ""
+msgid "InProductMarketing|Require multiple approvers on a merge request, so you know it's in good shape before it's merged."
+msgstr ""
+
+msgid "InProductMarketing|Roadmaps"
+msgstr ""
+
+msgid "InProductMarketing|Scoped labels"
+msgstr ""
+
msgid "InProductMarketing|Security that's integrated into your development lifecycle"
msgstr ""
msgid "InProductMarketing|Sometimes you're not ready to make a full transition to a new tool. If you're not ready to fully commit, %{mirroring_link} gives you a safe way to try out GitLab in parallel with your current tool."
msgstr ""
+msgid "InProductMarketing|Speed. Efficiency. Trust."
+msgstr ""
+
msgid "InProductMarketing|Spin up an autoscaling runner in GitLab"
msgstr ""
@@ -18968,6 +19380,9 @@ msgstr ""
msgid "InProductMarketing|Start a Self-Managed trial"
msgstr ""
+msgid "InProductMarketing|Start a free trial"
+msgstr ""
+
msgid "InProductMarketing|Start a free trial of GitLab Ultimate – no credit card required"
msgstr ""
@@ -19034,6 +19449,9 @@ msgstr ""
msgid "InProductMarketing|To understand and get the most out of GitLab, start at the beginning and %{project_link}. In GitLab, repositories are part of a project, so after you've created your project you can go ahead and %{repo_link}."
msgstr ""
+msgid "InProductMarketing|Track completed issues in a chart, so you can see how a milestone is progressing at a glance."
+msgstr ""
+
msgid "InProductMarketing|Try GitLab Ultimate for free"
msgstr ""
@@ -19070,6 +19488,9 @@ msgstr ""
msgid "InProductMarketing|Very easy"
msgstr ""
+msgid "InProductMarketing|Visualize your epics and milestones in a timeline."
+msgstr ""
+
msgid "InProductMarketing|Want to host GitLab on your servers?"
msgstr ""
@@ -19091,6 +19512,9 @@ msgstr ""
msgid "InProductMarketing|YouTube"
msgstr ""
+msgid "InProductMarketing|Your software, deployed your way"
+msgstr ""
+
msgid "InProductMarketing|Your teams can be more efficient"
msgstr ""
@@ -19211,9 +19635,18 @@ msgstr ""
msgid "IncidentManagement|No incidents to display."
msgstr ""
+msgid "IncidentManagement|None"
+msgstr ""
+
msgid "IncidentManagement|Open"
msgstr ""
+msgid "IncidentManagement|Page your team with escalation policies"
+msgstr ""
+
+msgid "IncidentManagement|Paged"
+msgstr ""
+
msgid "IncidentManagement|Published"
msgstr ""
@@ -19223,6 +19656,9 @@ msgstr ""
msgid "IncidentManagement|Severity"
msgstr ""
+msgid "IncidentManagement|Status"
+msgstr ""
+
msgid "IncidentManagement|There are no closed incidents"
msgstr ""
@@ -19241,6 +19677,9 @@ msgstr ""
msgid "IncidentManagement|Unpublished"
msgstr ""
+msgid "IncidentManagement|Use escalation policies to automatically page your team when incidents are created."
+msgstr ""
+
msgid "IncidentSettings|Activate \"time to SLA\" countdown timer"
msgstr ""
@@ -19286,7 +19725,10 @@ msgstr ""
msgid "Incidents"
msgstr ""
-msgid "Incidents|Add a URL"
+msgid "Incidents|Add image details"
+msgstr ""
+
+msgid "Incidents|Add text or a link to display with your image. If you don't add either, the file name displays instead."
msgstr ""
msgid "Incidents|Drop or %{linkStart}upload%{linkEnd} a metric screenshot to attach it to the incident"
@@ -19301,10 +19743,10 @@ msgstr ""
msgid "Incidents|There was an issue loading metric images."
msgstr ""
-msgid "Incidents|There was an issue uploading your image."
+msgid "Incidents|There was an issue updating your image."
msgstr ""
-msgid "Incidents|You can optionally add a URL to link users to the original graph."
+msgid "Incidents|There was an issue uploading your image."
msgstr ""
msgid "Incident|Alert details"
@@ -19313,9 +19755,18 @@ msgstr ""
msgid "Incident|Are you sure you wish to delete this image?"
msgstr ""
+msgid "Incident|Delete image"
+msgstr ""
+
msgid "Incident|Deleting %{filename}"
msgstr ""
+msgid "Incident|Edit image text or link"
+msgstr ""
+
+msgid "Incident|Editing %{filename}"
+msgstr ""
+
msgid "Incident|Metrics"
msgstr ""
@@ -19587,12 +20038,18 @@ msgstr ""
msgid "Integrations|Branches for which notifications are to be sent"
msgstr ""
+msgid "Integrations|Clear if using a self-signed certificate."
+msgstr ""
+
msgid "Integrations|Comment detail:"
msgstr ""
msgid "Integrations|Comment settings:"
msgstr ""
+msgid "Integrations|Connection details"
+msgstr ""
+
msgid "Integrations|Connection failed. Please check your settings."
msgstr ""
@@ -19617,6 +20074,9 @@ msgstr ""
msgid "Integrations|Enable GitLab.com slash commands in a Slack workspace."
msgstr ""
+msgid "Integrations|Enable SSL verification"
+msgstr ""
+
msgid "Integrations|Enable comments"
msgstr ""
@@ -19695,6 +20155,9 @@ msgstr ""
msgid "Integrations|Return to GitLab for Jira"
msgstr ""
+msgid "Integrations|SSL verification"
+msgstr ""
+
msgid "Integrations|Save settings?"
msgstr ""
@@ -19740,9 +20203,6 @@ msgstr ""
msgid "Integrations|Use default settings"
msgstr ""
-msgid "Integrations|When you mention a Jira issue in a commit or merge request, GitLab creates a remote link and comment (if enabled)."
-msgstr ""
-
msgid "Integrations|You can now close this window and return to the GitLab for Jira application."
msgstr ""
@@ -19767,9 +20227,6 @@ msgstr ""
msgid "Integrations|can't exceed %{recipients_limit}"
msgstr ""
-msgid "Interactive developer security education."
-msgstr ""
-
msgid "Interactive mode"
msgstr ""
@@ -20259,6 +20716,9 @@ msgstr ""
msgid "IssueAnalytics|Assignees"
msgstr ""
+msgid "IssueAnalytics|Created by"
+msgstr ""
+
msgid "IssueAnalytics|Due date"
msgstr ""
@@ -20271,9 +20731,6 @@ msgstr ""
msgid "IssueAnalytics|Milestone"
msgstr ""
-msgid "IssueAnalytics|Opened by"
-msgstr ""
-
msgid "IssueAnalytics|Status"
msgstr ""
@@ -20397,10 +20854,10 @@ msgstr ""
msgid "IssuesAnalytics|Avg/Month:"
msgstr ""
-msgid "IssuesAnalytics|Issues opened"
+msgid "IssuesAnalytics|Issues created"
msgstr ""
-msgid "IssuesAnalytics|Issues opened per month"
+msgid "IssuesAnalytics|Issues created per month"
msgstr ""
msgid "IssuesAnalytics|Last 12 months"
@@ -20427,6 +20884,9 @@ msgstr ""
msgid "It looks like you have some draft commits in this branch."
msgstr ""
+msgid "It looks like you're attempting to activate your subscription. Use %{a_start}the Subscription page%{a_end} instead."
+msgstr ""
+
msgid "It may be several days before you see feature usage data."
msgstr ""
@@ -20655,6 +21115,9 @@ msgstr ""
msgid "JiraConnect|You can now close this window and return to Jira."
msgstr ""
+msgid "JiraConnect|You don't have permission to create branches for this project. Select a different project or contact the project owner for access. %{linkStart}Learn more.%{linkEnd}"
+msgstr ""
+
msgid "JiraRequest|A connection error occurred while connecting to Jira. Try your request again."
msgstr ""
@@ -20703,13 +21166,13 @@ msgstr ""
msgid "JiraService|Define the type of Jira issue to create from a vulnerability."
msgstr ""
-msgid "JiraService|Displaying Jira issues while leaving the GitLab issue functionality enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
+msgid "JiraService|Displaying Jira issues while leaving GitLab issues also enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
msgstr ""
-msgid "JiraService|Enable Jira issues"
+msgid "JiraService|Enable Jira issue creation from vulnerabilities"
msgstr ""
-msgid "JiraService|Enable Jira issues creation from vulnerabilities"
+msgid "JiraService|Enable Jira issues"
msgstr ""
msgid "JiraService|Enable Jira transitions"
@@ -20826,16 +21289,19 @@ msgstr ""
msgid "JiraService|View Jira issues in GitLab"
msgstr ""
-msgid "JiraService|Warning: All GitLab users that have access to this GitLab project are able to view all issues from the Jira project specified below."
+msgid "JiraService|Warning: All GitLab users with access to this GitLab project can view all issues from the Jira project you select."
msgstr ""
msgid "JiraService|Web URL"
msgstr ""
-msgid "JiraService|Work on Jira issues without leaving GitLab. Adds a Jira menu to access your list of Jira issues and view any issue as read-only."
+msgid "JiraService|When a Jira issue is mentioned in a commit or merge request, a remote link and comment (if enabled) will be created."
+msgstr ""
+
+msgid "JiraService|Work on Jira issues without leaving GitLab. Add a Jira menu to access a read-only list of your Jira issues."
msgstr ""
-msgid "JiraService|You need to configure Jira before enabling this integration. For more details, read the %{jira_doc_link_start}Jira integration documentation%{link_end}."
+msgid "JiraService|You must configure Jira before enabling this integration. %{jira_doc_link_start}Learn more.%{link_end}"
msgstr ""
msgid "Job"
@@ -20847,9 +21313,6 @@ msgstr ""
msgid "Job Failed #%{build_id}"
msgstr ""
-msgid "Job ID"
-msgstr ""
-
msgid "Job artifact"
msgstr ""
@@ -20916,9 +21379,27 @@ msgstr ""
msgid "Jobs|You're about to retry a job that failed because it attempted to deploy code that is older than the latest deployment. Retrying this job could result in overwriting the environment with the older source code."
msgstr ""
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source} into %{target}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{ref}"
+msgstr ""
+
+msgid "Job|Are you sure you want to erase this job log and artifacts?"
+msgstr ""
+
msgid "Job|Browse"
msgstr ""
+msgid "Job|Cancel"
+msgstr ""
+
msgid "Job|Complete Raw"
msgstr ""
@@ -20928,6 +21409,9 @@ msgstr ""
msgid "Job|Erase job log and artifacts"
msgstr ""
+msgid "Job|Finished at"
+msgstr ""
+
msgid "Job|Job artifacts"
msgstr ""
@@ -20940,7 +21424,7 @@ msgstr ""
msgid "Job|Keep"
msgstr ""
-msgid "Job|Pipeline"
+msgid "Job|Retry"
msgstr ""
msgid "Job|Scroll to bottom"
@@ -20952,6 +21436,9 @@ msgstr ""
msgid "Job|Show complete raw"
msgstr ""
+msgid "Job|Status"
+msgstr ""
+
msgid "Job|The artifacts were removed"
msgstr ""
@@ -20979,21 +21466,12 @@ msgstr ""
msgid "Job|delayed"
msgstr ""
-msgid "Job|for"
-msgstr ""
-
-msgid "Job|into"
-msgstr ""
-
msgid "Job|manual"
msgstr ""
msgid "Job|triggered"
msgstr ""
-msgid "Job|with"
-msgstr ""
-
msgid "Join Zoom meeting"
msgstr ""
@@ -21096,9 +21574,6 @@ msgstr ""
msgid "Ki"
msgstr ""
-msgid "Kontra"
-msgstr ""
-
msgid "Kroki"
msgstr ""
@@ -21424,6 +21899,9 @@ msgstr ""
msgid "Learn more about Auto DevOps"
msgstr ""
+msgid "Learn more about GitLab"
+msgstr ""
+
msgid "Learn more about Needs relationships"
msgstr ""
@@ -21763,9 +22241,18 @@ msgstr ""
msgid "Licenses|Displays licenses detected in the project, based on the %{linkStart}latest successful%{linkEnd} scan"
msgstr ""
+msgid "Licenses|Drag your license file here or %{linkStart}click to upload%{linkEnd}."
+msgstr ""
+
+msgid "Licenses|Drop your license file to start the upload."
+msgstr ""
+
msgid "Licenses|Error fetching the license list. Please check your network connection and try again."
msgstr ""
+msgid "Licenses|Error: You are trying to upload something other than a file"
+msgstr ""
+
msgid "Licenses|License Compliance"
msgstr ""
@@ -21784,6 +22271,9 @@ msgstr ""
msgid "Licenses|Specified policies in this project"
msgstr ""
+msgid "Licenses|The file could not be uploaded."
+msgstr ""
+
msgid "Licenses|The license list details information about the licenses used within your project."
msgstr ""
@@ -21817,13 +22307,6 @@ msgstr ""
msgid "Limit the size of Sidekiq jobs stored in Redis."
msgstr ""
-msgid "Limited to showing %d event at most"
-msgid_plural "Limited to showing %d events at most"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-msgstr[3] ""
-
msgid "Limiting mode"
msgstr ""
@@ -21833,6 +22316,9 @@ msgstr ""
msgid "Link"
msgstr ""
+msgid "Link (optional)"
+msgstr ""
+
msgid "Link Prometheus monitoring to GitLab."
msgstr ""
@@ -21869,6 +22355,9 @@ msgstr ""
msgid "Linked emails (%{email_count})"
msgstr ""
+msgid "Linked epics"
+msgstr ""
+
msgid "Linked issues"
msgstr ""
@@ -21896,6 +22385,15 @@ msgstr ""
msgid "List of all merge commits"
msgstr ""
+msgid "List of environments for this project"
+msgstr ""
+
+msgid "List of suitable GCP locations"
+msgstr ""
+
+msgid "List of users allowed to exceed the rate limit."
+msgstr ""
+
msgid "List options"
msgstr ""
@@ -22115,6 +22613,9 @@ msgstr ""
msgid "Maintenance mode"
msgstr ""
+msgid "Make adjustments to how your GitLab instance is set up."
+msgstr ""
+
msgid "Make and review changes in the browser with the Web IDE"
msgstr ""
@@ -22259,6 +22760,12 @@ msgstr ""
msgid "MarkdownEditor|Add italic text (%{modifier_key}I)"
msgstr ""
+msgid "MarkdownEditor|Add strikethrough text (%{modifierKey}⇧X)"
+msgstr ""
+
+msgid "MarkdownEditor|Add strikethrough text (%{modifier_key}⇧X)"
+msgstr ""
+
msgid "Marked For Deletion At - %{deletion_time}"
msgstr ""
@@ -22520,6 +23027,9 @@ msgstr ""
msgid "Maximum push size (MB)"
msgstr ""
+msgid "Maximum requests per 10 minutes per user"
+msgstr ""
+
msgid "Maximum requests per minute"
msgstr ""
@@ -22610,6 +23120,23 @@ msgstr ""
msgid "Members of a group may only view projects they have permission to access"
msgstr ""
+msgid "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seat in use and will be billed for the overage."
+msgid_plural "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seats in use and will be billed for the overage."
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
+msgid "MembersOverage|You are about to incur additional charges"
+msgstr ""
+
+msgid "MembersOverage|Your subscription includes %d seat."
+msgid_plural "MembersOverage|Your subscription includes %d seats."
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "Membership"
msgstr ""
@@ -22814,9 +23341,6 @@ msgstr ""
msgid "Merge request not merged"
msgstr ""
-msgid "Merge request pipelines 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 merge request pipelines."
-msgstr ""
-
msgid "Merge request reports"
msgstr ""
@@ -22913,13 +23437,13 @@ msgstr ""
msgid "MergeRequests|Create issue to resolve thread"
msgstr ""
-msgid "MergeRequests|Failed to squash. Should be done manually."
+msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Saving the comment failed"
+msgid "MergeRequests|Squashing failed: Squash the commits locally, resolve any conflicts, then push the branch."
msgstr ""
-msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
+msgid "MergeRequests|Squashing not allowed: This project doesn't allow you to squash commits when merging."
msgstr ""
msgid "MergeRequests|Thread stays resolved"
@@ -23764,6 +24288,18 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "MrList|Assigned to %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from assignee %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from reviewer %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Review requested from %{name}, go to their profile."
+msgstr ""
+
msgid "Multi-project"
msgstr ""
@@ -23797,7 +24333,7 @@ msgstr ""
msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "My Awesome Group"
+msgid "My awesome group"
msgstr ""
msgid "My company or team"
@@ -24423,9 +24959,6 @@ msgstr ""
msgid "No available branches"
msgstr ""
-msgid "No available groups to fork the project."
-msgstr ""
-
msgid "No branches found"
msgstr ""
@@ -24636,6 +25169,9 @@ msgstr ""
msgid "No ref selected"
msgstr ""
+msgid "No regions configured"
+msgstr ""
+
msgid "No related merge requests found."
msgstr ""
@@ -25452,6 +25988,9 @@ msgstr ""
msgid "Only reCAPTCHA v2 is supported:"
msgstr ""
+msgid "Only required if not using role instance credentials."
+msgstr ""
+
msgid "Only use lowercase letters, numbers, and underscores."
msgstr ""
@@ -25476,9 +26015,6 @@ msgstr ""
msgid "Open a CLI and connect to the cluster you want to install the agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
-msgid "Open epics"
-msgstr ""
-
msgid "Open errors"
msgstr ""
@@ -25518,7 +26054,7 @@ msgstr ""
msgid "Opened issues"
msgstr ""
-msgid "OpenedNDaysAgo|Opened"
+msgid "OpenedNDaysAgo|Created"
msgstr ""
msgid "Opens in a new window"
@@ -25563,9 +26099,6 @@ msgstr ""
msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
-msgid "Optional."
-msgstr ""
-
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
msgstr ""
@@ -26356,6 +26889,9 @@ msgstr ""
msgid "PerformanceBar|Memory"
msgstr ""
+msgid "PerformanceBar|Memory report"
+msgstr ""
+
msgid "PerformanceBar|Redis calls"
msgstr ""
@@ -26389,18 +26925,12 @@ msgstr ""
msgid "PerformanceBar|wall"
msgstr ""
-msgid "Performs a rebase but skips triggering a new pipeline"
-msgstr ""
-
msgid "Period in seconds"
msgstr ""
msgid "Permalink"
msgstr ""
-msgid "Permanently delete project"
-msgstr ""
-
msgid "Permanently remove group"
msgstr ""
@@ -26671,6 +27201,51 @@ msgstr ""
msgid "PipelineStatusTooltip|Pipeline: %{ci_status}"
msgstr ""
+msgid "PipelineWizardDefaultCommitMessage|Add %{filename}"
+msgstr ""
+
+msgid "PipelineWizardDefaultCommitMessage|Update %{filename}"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|At least one entry is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This field is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This value is not valid"
+msgstr ""
+
+msgid "PipelineWizardListWidget|add another step"
+msgstr ""
+
+msgid "PipelineWizardListWidget|remove step"
+msgstr ""
+
+msgid "PipelineWizard|Commit"
+msgstr ""
+
+msgid "PipelineWizard|Commit Message"
+msgstr ""
+
+msgid "PipelineWizard|Commit changes to your file"
+msgstr ""
+
+msgid "PipelineWizard|Commit file to Branch"
+msgstr ""
+
+msgid "PipelineWizard|Commit your new file"
+msgstr ""
+
+msgid "PipelineWizard|The file has been committed."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem committing the changes."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem while checking whether your file already exists in the specified branch."
+msgstr ""
+
msgid "Pipelines"
msgstr ""
@@ -26785,7 +27360,7 @@ msgstr ""
msgid "Pipelines|Project cache successfully reset."
msgstr ""
-msgid "Pipelines|Revoke"
+msgid "Pipelines|Revoke trigger"
msgstr ""
msgid "Pipelines|Something went wrong while cleaning runners cache."
@@ -26830,6 +27405,12 @@ msgstr ""
msgid "Pipelines|This is a child pipeline within the parent pipeline"
msgstr ""
+msgid "Pipelines|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipelines|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipelines|This pipeline will run code originating from a forked project merge request. This means that the code can potentially have security considerations like exposing CI variables."
msgstr ""
@@ -26872,9 +27453,6 @@ msgstr ""
msgid "Pipelines|Your changes have been successfully committed. Now redirecting to the new merge request page."
msgstr ""
-msgid "Pipelines|detached"
-msgstr ""
-
msgid "Pipelines|error"
msgstr ""
@@ -26884,10 +27462,13 @@ msgstr ""
msgid "Pipelines|latest"
msgstr ""
-msgid "Pipelines|stuck"
+msgid "Pipelines|merge request"
msgstr ""
-msgid "Pipelines|train"
+msgid "Pipelines|merge train"
+msgstr ""
+
+msgid "Pipelines|stuck"
msgstr ""
msgid "Pipelines|yaml invalid"
@@ -27019,6 +27600,12 @@ msgstr ""
msgid "Pipeline|This change will not change the overall test coverage if merged."
msgstr ""
+msgid "Pipeline|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipeline|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipeline|Trigger author"
msgstr ""
@@ -27043,6 +27630,12 @@ msgstr ""
msgid "Pipeline|for"
msgstr ""
+msgid "Pipeline|merge request"
+msgstr ""
+
+msgid "Pipeline|merge train"
+msgstr ""
+
msgid "Pipeline|on"
msgstr ""
@@ -27181,9 +27774,6 @@ msgstr ""
msgid "Please enter a valid time interval"
msgstr ""
-msgid "Please enter or upload a valid license."
-msgstr ""
-
msgid "Please enter your current password."
msgstr ""
@@ -27292,9 +27882,6 @@ msgstr ""
msgid "Please type %{phrase_code} to proceed or close this modal to cancel."
msgstr ""
-msgid "Please type the following to confirm:"
-msgstr ""
-
msgid "Please use this form to report to the admin users who create spam issues, comments or behave inappropriately."
msgstr ""
@@ -27322,12 +27909,27 @@ msgstr ""
msgid "Policies"
msgstr ""
+msgid "Policy '%{escalation_policy_name}' does not exist."
+msgstr ""
+
msgid "Policy management project does have any policies in %{policy_path}"
msgstr ""
msgid "Policy project doesn't exist"
msgstr ""
+msgid "PolicyRuleMultiSelect|%{firstLabel} +%{numberOfAdditionalLabels} more"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|All %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select all"
+msgstr ""
+
msgid "Polling interval multiplier"
msgstr ""
@@ -27556,6 +28158,9 @@ msgstr ""
msgid "Private projects can be created in your personal namespace with:"
msgstr ""
+msgid "Problem with %{name} command: %{message}."
+msgstr ""
+
msgid "Proceed"
msgstr ""
@@ -28030,6 +28635,9 @@ msgstr ""
msgid "Progress"
msgstr ""
+msgid "Progress tracking"
+msgstr ""
+
msgid "Project"
msgstr ""
@@ -28261,6 +28869,9 @@ msgstr ""
msgid "ProjectQualitySummary|Failure"
msgstr ""
+msgid "ProjectQualitySummary|Get insight into the overall percentage of tests in your project that succeed, fail and are skipped."
+msgstr ""
+
msgid "ProjectQualitySummary|Latest pipeline results"
msgstr ""
@@ -28279,6 +28890,12 @@ msgstr ""
msgid "ProjectQualitySummary|See project Code Coverage Statistics"
msgstr ""
+msgid "ProjectQualitySummary|Set up test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|Set up test runs (opens in a new tab)"
+msgstr ""
+
msgid "ProjectQualitySummary|Skipped"
msgstr ""
@@ -28555,13 +29172,19 @@ msgstr ""
msgid "ProjectSettings|LFS objects from this repository are available to forks. %{linkStart}How do I remove them?%{linkEnd}"
msgstr ""
+msgid "ProjectSettings|Learn about commit history."
+msgstr ""
+
+msgid "ProjectSettings|Leave empty to use default template."
+msgstr ""
+
msgid "ProjectSettings|Manage who can see the project in the public access directory."
msgstr ""
msgid "ProjectSettings|Manages large files such as audio, video, and graphics files."
msgstr ""
-msgid "ProjectSettings|Maximum 500 characters."
+msgid "ProjectSettings|Maximum %{maxLength} characters."
msgstr ""
msgid "ProjectSettings|Merge checks"
@@ -28702,6 +29325,9 @@ msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
msgstr ""
+msgid "ProjectSettings|The default template will be applied on save."
+msgstr ""
+
msgid "ProjectSettings|These checks must pass before merge requests can be merged."
msgstr ""
@@ -28756,6 +29382,9 @@ msgstr ""
msgid "ProjectSettings|What are badges?"
msgstr ""
+msgid "ProjectSettings|What are merge trains?"
+msgstr ""
+
msgid "ProjectSettings|When merge request pipelines are enabled in the CI/CD configuration file, pipelines validate the combined results of the source and target branches. %{link_start}How to configure merge request pipelines?%{link_end}"
msgstr ""
@@ -28873,6 +29502,9 @@ msgstr ""
msgid "Projects are organized into groups"
msgstr ""
+msgid "Projects are where you store your code, access issues, wiki and other features of GitLab."
+msgstr ""
+
msgid "Projects contributed to"
msgstr ""
@@ -28888,12 +29520,6 @@ msgstr ""
msgid "Projects to index"
msgstr ""
-msgid "Projects will be permanently deleted after a %{waiting_period}-day waiting period."
-msgstr ""
-
-msgid "Projects will be permanently deleted immediately."
-msgstr ""
-
msgid "Projects with critical vulnerabilities"
msgstr ""
@@ -28978,6 +29604,9 @@ msgstr ""
msgid "ProjectsNew|Import project"
msgstr ""
+msgid "ProjectsNew|Include a Getting Started README"
+msgstr ""
+
msgid "ProjectsNew|Initialize repository with a README"
msgstr ""
@@ -28993,6 +29622,9 @@ msgstr ""
msgid "ProjectsNew|Project description %{tag_start}(optional)%{tag_end}"
msgstr ""
+msgid "ProjectsNew|Recommended if you're new to GitLab"
+msgstr ""
+
msgid "ProjectsNew|Run CI/CD for external repository"
msgstr ""
@@ -29410,6 +30042,9 @@ msgstr ""
msgid "ProtectedBranch|Unprotect"
msgstr ""
+msgid "ProtectedBranch|Unprotect branch"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
@@ -29437,6 +30072,9 @@ msgstr ""
msgid "ProtectedEnvironment|Protected Environment (%{protected_environments_count})"
msgstr ""
+msgid "ProtectedEnvironment|Required approvals"
+msgstr ""
+
msgid "ProtectedEnvironment|Select an environment"
msgstr ""
@@ -29458,10 +30096,13 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|Unprotect tag"
+msgstr ""
+
msgid "ProtectedTags|default"
msgstr ""
-msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
+msgid "ProtectedTag|By default, protected tags restrict who can modify the tag."
msgstr ""
msgid "ProtectedTag|Learn more."
@@ -29524,6 +30165,9 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Public projects are an easy way to allow everyone to have read-only access."
+msgstr ""
+
msgid "Publish to status page"
msgstr ""
@@ -29680,9 +30324,6 @@ msgstr ""
msgid "QualitySummary|Project quality"
msgstr ""
-msgid "Quarters"
-msgstr ""
-
msgid "Query"
msgstr ""
@@ -29767,6 +30408,9 @@ msgstr ""
msgid "Read more about project permissions %{help_link_open}here%{help_link_close}"
msgstr ""
+msgid "Read more about related epics"
+msgstr ""
+
msgid "Read more about related issues"
msgstr ""
@@ -29797,10 +30441,7 @@ msgstr ""
msgid "Rebase source branch on the target branch."
msgstr ""
-msgid "Rebase without CI"
-msgstr ""
-
-msgid "Rebases and triggers a pipeline"
+msgid "Rebase without pipeline"
msgstr ""
msgid "Recaptcha verified?"
@@ -29851,9 +30492,6 @@ msgstr ""
msgid "Reconfigure"
msgstr ""
-msgid "Recovering projects"
-msgstr ""
-
msgid "Recovery Codes"
msgstr ""
@@ -29915,6 +30553,12 @@ msgstr ""
msgid "Regex pattern"
msgstr ""
+msgid "Region"
+msgstr ""
+
+msgid "Regions"
+msgstr ""
+
msgid "Register"
msgstr ""
@@ -30147,9 +30791,6 @@ msgstr ""
msgid "Remove all or specific reviewer(s)"
msgstr ""
-msgid "Remove approver"
-msgstr ""
-
msgid "Remove approvers"
msgstr ""
@@ -30165,6 +30806,9 @@ msgstr ""
msgid "Remove attention request"
msgstr ""
+msgid "Remove attention request(s)"
+msgstr ""
+
msgid "Remove avatar"
msgstr ""
@@ -30303,6 +30947,9 @@ msgstr ""
msgid "Removed an issue from an epic."
msgstr ""
+msgid "Removed attention from %{users_sentence}."
+msgstr ""
+
msgid "Removed attention request from @%{username}"
msgstr ""
@@ -30354,6 +31001,9 @@ msgstr ""
msgid "Removes an issue from an epic."
msgstr ""
+msgid "Removes attention from %{users_sentence}."
+msgstr ""
+
msgid "Removes parent epic %{epic_ref}."
msgstr ""
@@ -30465,6 +31115,9 @@ msgstr ""
msgid "Report abuse to admin"
msgstr ""
+msgid "Report is generating and will be sent to your email address."
+msgstr ""
+
msgid "Reported %{timeAgo} by %{reportedBy}"
msgstr ""
@@ -30764,6 +31417,15 @@ msgstr ""
msgid "Request attention"
msgstr ""
+msgid "Request attention from %{users_sentence}."
+msgstr ""
+
+msgid "Request attention from assignee or reviewer"
+msgstr ""
+
+msgid "Request attention from assignee(s) or reviewer(s)"
+msgstr ""
+
msgid "Request attention to review"
msgstr ""
@@ -30788,6 +31450,9 @@ msgstr ""
msgid "Requested %{time_ago}"
msgstr ""
+msgid "Requested attention from %{users_sentence}."
+msgstr ""
+
msgid "Requested attention from @%{username}"
msgstr ""
@@ -31006,6 +31671,9 @@ msgstr ""
msgid "Restore project"
msgstr ""
+msgid "Restoring projects"
+msgstr ""
+
msgid "Restoring the group will prevent the group, its subgroups and projects from being removed on this date."
msgstr ""
@@ -31036,6 +31704,9 @@ msgstr ""
msgid "Retry"
msgstr ""
+msgid "Retry failed jobs"
+msgstr ""
+
msgid "Retry job"
msgstr ""
@@ -31085,9 +31756,6 @@ msgstr ""
msgid "Review changes"
msgstr ""
-msgid "Review requested from %{name}"
-msgstr ""
-
msgid "Review requests for you"
msgstr ""
@@ -31254,6 +31922,9 @@ msgstr ""
msgid "Runners|Assigned Group"
msgstr ""
+msgid "Runners|Assigned Projects (%{projectCount})"
+msgstr ""
+
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -31323,6 +31994,9 @@ msgstr ""
msgid "Runners|Instance"
msgstr ""
+msgid "Runners|Jobs"
+msgstr ""
+
msgid "Runners|Last contact"
msgstr ""
@@ -31416,9 +32090,6 @@ msgstr ""
msgid "Runners|Runner %{name} was deleted"
msgstr ""
-msgid "Runners|Runner ID"
-msgstr ""
-
msgid "Runners|Runner assigned to project."
msgstr ""
@@ -31566,6 +32237,9 @@ msgstr ""
msgid "Runners|stale"
msgstr ""
+msgid "Runner|This runner has not run any jobs."
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -31680,6 +32354,24 @@ msgstr ""
msgid "Saving project."
msgstr ""
+msgid "ScanResultPolicy|%{ifLabelStart}if%{ifLabelEnd} %{scanners} scan in an open merge request targeting the %{branches} branch(es) finds %{vulnerabilitiesAllowed} or more %{severities} vulnerabilities that are %{vulnerabilityStates}"
+msgstr ""
+
+msgid "ScanResultPolicy|%{thenLabelStart}Then%{thenLabelEnd} Require approval from %{approvalsRequired} of the following approvers: %{approvers}"
+msgstr ""
+
+msgid "ScanResultPolicy|add an approver"
+msgstr ""
+
+msgid "ScanResultPolicy|scanners"
+msgstr ""
+
+msgid "ScanResultPolicy|severity levels"
+msgstr ""
+
+msgid "ScanResultPolicy|vulnerability states"
+msgstr ""
+
msgid "Scanner"
msgstr ""
@@ -31812,6 +32504,9 @@ msgstr ""
msgid "Search for a user"
msgstr ""
+msgid "Search for an emoji"
+msgstr ""
+
msgid "Search for projects, issues, etc."
msgstr ""
@@ -32021,18 +32716,12 @@ msgstr ""
msgid "Secret Detection"
msgstr ""
-msgid "Secret access key"
-msgstr ""
-
msgid "Secret token"
msgstr ""
msgid "Secure token that identifies an external storage request."
msgstr ""
-msgid "SecureCodeWarrior"
-msgstr ""
-
msgid "Security"
msgstr ""
@@ -32057,9 +32746,6 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "Security training with guide and learning pathways."
-msgstr ""
-
msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
@@ -32162,7 +32848,7 @@ msgstr ""
msgid "SecurityConfiguration|Manage corpus"
msgstr ""
-msgid "SecurityConfiguration|Manage corpus files used as mutation sources in coverage fuzzing."
+msgid "SecurityConfiguration|Manage corpus files used as seed inputs with coverage-guided fuzzing."
msgstr ""
msgid "SecurityConfiguration|Manage profiles for use by DAST scans."
@@ -32228,15 +32914,15 @@ msgstr ""
msgid "SecurityOrchestration|.yaml preview"
msgstr ""
-msgid "SecurityOrchestration|Action"
-msgstr ""
-
msgid "SecurityOrchestration|Actions"
msgstr ""
msgid "SecurityOrchestration|Add rule"
msgstr ""
+msgid "SecurityOrchestration|After dismissing the alert, the information will never be shown again."
+msgstr ""
+
msgid "SecurityOrchestration|All policies"
msgstr ""
@@ -32252,7 +32938,7 @@ msgstr ""
msgid "SecurityOrchestration|Description"
msgstr ""
-msgid "SecurityOrchestration|Disabled"
+msgid "SecurityOrchestration|Don't show the alert anymore"
msgstr ""
msgid "SecurityOrchestration|Edit policy"
@@ -32261,13 +32947,13 @@ msgstr ""
msgid "SecurityOrchestration|Edit policy project"
msgstr ""
-msgid "SecurityOrchestration|Enabled"
+msgid "SecurityOrchestration|Empty policy name"
msgstr ""
-msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Enabled"
msgstr ""
-msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
msgstr ""
msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
@@ -32276,7 +32962,7 @@ msgstr ""
msgid "SecurityOrchestration|Invalid policy type"
msgstr ""
-msgid "SecurityOrchestration|Latest scan"
+msgid "SecurityOrchestration|Latest scan run against %{agent}"
msgstr ""
msgid "SecurityOrchestration|Network"
@@ -32285,15 +32971,27 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No actions defined - policy will not run."
+msgstr ""
+
+msgid "SecurityOrchestration|No description"
+msgstr ""
+
msgid "SecurityOrchestration|No rules defined - policy will not run."
msgstr ""
+msgid "SecurityOrchestration|Not enabled"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
msgid "SecurityOrchestration|Policies"
msgstr ""
+msgid "SecurityOrchestration|Policy Type"
+msgstr ""
+
msgid "SecurityOrchestration|Policy cannot be enabled for non-existing branches (%{branches})"
msgstr ""
@@ -32318,10 +33016,13 @@ msgstr ""
msgid "SecurityOrchestration|Require %{approvals} %{plural} from %{approvers} if any of the following occur:"
msgstr ""
-msgid "SecurityOrchestration|Rule"
+msgid "SecurityOrchestration|Rules"
msgstr ""
-msgid "SecurityOrchestration|Rules"
+msgid "SecurityOrchestration|Runs %{actions} and %{lastAction} scans"
+msgstr ""
+
+msgid "SecurityOrchestration|Runs a %{action} scan"
msgstr ""
msgid "SecurityOrchestration|Scan Execution"
@@ -32381,6 +33082,9 @@ msgstr ""
msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
+msgid "SecurityOrchestration|This view only shows scan results for the agent %{agent}. You can view scan results for all agents in the %{linkStart}Operational Vulnerabilities tab of the vulnerability report%{linkEnd}."
+msgstr ""
+
msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
@@ -32435,9 +33139,6 @@ msgstr ""
msgid "SecurityOrchestration|users with ids"
msgstr ""
-msgid "SecurityOrchestration|view results"
-msgstr ""
-
msgid "SecurityOrchestration|vulnerabilities"
msgstr ""
@@ -33107,22 +33808,19 @@ 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|In order to start using functions as a service, you must first install Knative on your Kubernetes cluster. %{linkStart}More information%{linkEnd}"
-msgstr ""
-
msgid "Serverless|Learn more about Serverless"
msgstr ""
msgid "Serverless|No functions available"
msgstr ""
-msgid "Serverless|Sign up for First Look"
+msgid "Serverless|Serverless was %{linkStart}deprecated%{linkEnd} in GitLab 14.3."
+msgstr ""
+
+msgid "Serverless|Serverless was %{postLinkStart}deprecated%{postLinkEnd}. But if you opt to use it, you must install Knative in your Kubernetes cluster first. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "Serverless|The deploy job has not finished."
@@ -33134,9 +33832,6 @@ 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 ""
@@ -33152,9 +33847,6 @@ msgstr ""
msgid "Service Account Key"
msgstr ""
-msgid "Service Accounts"
-msgstr ""
-
msgid "Service Accounts keys authorize GitLab to deploy your Google Cloud project"
msgstr ""
@@ -33164,10 +33856,10 @@ msgstr ""
msgid "Service Desk allows people to create issues in your GitLab instance without their own user account. It provides a unique email address for end users to create issues in a project. Replies can be sent either through the GitLab interface or by email. End users only see threads through email."
msgstr ""
-msgid "Service Usage Data"
+msgid "Service account generated successfully"
msgstr ""
-msgid "Service account generated successfully"
+msgid "Service accounts"
msgstr ""
msgid "Service ping is disabled in your configuration file, and cannot be enabled through this form."
@@ -33311,6 +34003,9 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
+msgid "Set the per-user rate limit for getting a user by ID via the API."
+msgstr ""
+
msgid "Set the per-user rate limit for notes created by web or API requests."
msgstr ""
@@ -33492,6 +34187,9 @@ msgstr ""
msgid "Shared runners details"
msgstr ""
+msgid "Shared runners enabled cannot be enabled until a valid credit card is on file"
+msgstr ""
+
msgid "Shared runners help link"
msgstr ""
@@ -33549,6 +34247,9 @@ msgstr ""
msgid "Show all issues."
msgstr ""
+msgid "Show all milestones"
+msgstr ""
+
msgid "Show all test cases."
msgstr ""
@@ -33585,6 +34286,9 @@ msgstr ""
msgid "Show file contents"
msgstr ""
+msgid "Show group milestones"
+msgstr ""
+
msgid "Show labels"
msgstr ""
@@ -33600,6 +34304,12 @@ msgstr ""
msgid "Show open epics"
msgstr ""
+msgid "Show project milestones"
+msgstr ""
+
+msgid "Show sub-group milestones"
+msgstr ""
+
msgid "Show the Closed list"
msgstr ""
@@ -33609,13 +34319,6 @@ msgstr ""
msgid "Show whitespace changes"
msgstr ""
-msgid "Showing %d event"
-msgid_plural "Showing %d events"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-msgstr[3] ""
-
msgid "Showing %{conflict} between %{sourceBranch} and %{targetBranch}"
msgstr ""
@@ -33677,12 +34380,6 @@ msgstr ""
msgid "Sidebar|None"
msgstr ""
-msgid "Sidebar|Only numeral characters allowed"
-msgstr ""
-
-msgid "Sidebar|Weight"
-msgstr ""
-
msgid "Sidekiq job compression threshold (bytes)"
msgstr ""
@@ -33845,6 +34542,9 @@ msgstr ""
msgid "Slack logo"
msgstr ""
+msgid "SlackIntegration|Are you sure you want to remove this project from the Slack application?"
+msgstr ""
+
msgid "SlackIntegration|GitLab for Slack"
msgstr ""
@@ -33854,6 +34554,9 @@ msgstr ""
msgid "SlackIntegration|Project alias"
msgstr ""
+msgid "SlackIntegration|Remove project"
+msgstr ""
+
msgid "SlackIntegration|Select a GitLab project to link with your Slack workspace."
msgstr ""
@@ -33998,9 +34701,6 @@ msgstr ""
msgid "Something went wrong trying to load issue contacts."
msgstr ""
-msgid "Something went wrong when creating a work item. Please try again"
-msgstr ""
-
msgid "Something went wrong when reordering designs. Please try again"
msgstr ""
@@ -34094,9 +34794,6 @@ msgstr ""
msgid "Something went wrong while inserting your image. Please try again."
msgstr ""
-msgid "Something went wrong while merging this merge request. Please try again."
-msgstr ""
-
msgid "Something went wrong while obtaining the Let's Encrypt certificate."
msgstr ""
@@ -34418,10 +35115,10 @@ 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."
+msgid "SourcegraphAdmin|Learn more."
msgstr ""
-msgid "SourcegraphAdmin|More information"
+msgid "SourcegraphAdmin|Only public projects have code intelligence enabled and communicate with Sourcegraph."
msgstr ""
msgid "SourcegraphAdmin|Save changes"
@@ -34430,7 +35127,7 @@ msgstr ""
msgid "SourcegraphAdmin|Sourcegraph URL"
msgstr ""
-msgid "SourcegraphAdmin|e.g. https://sourcegraph.example.com"
+msgid "SourcegraphAdmin|https://sourcegraph.example.com"
msgstr ""
msgid "SourcegraphPreferences|This feature is experimental and currently limited to certain projects."
@@ -34565,6 +35262,9 @@ msgstr ""
msgid "Start date"
msgstr ""
+msgid "Start free trial"
+msgstr ""
+
msgid "Start merge train"
msgstr ""
@@ -34595,6 +35295,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started escalation for this incident."
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -34607,6 +35310,9 @@ msgstr ""
msgid "Starts at (UTC)"
msgstr ""
+msgid "Starts escalations for this incident"
+msgstr ""
+
msgid "Starts on"
msgstr ""
@@ -34868,6 +35574,9 @@ msgstr ""
msgid "Strikethrough"
msgstr ""
+msgid "Strikethrough text"
+msgstr ""
+
msgid "Subgroup information"
msgstr ""
@@ -35102,6 +35811,21 @@ msgstr ""
msgid "Subscriptions"
msgstr ""
+msgid "Subscriptions|Chat with sales"
+msgstr ""
+
+msgid "Subscriptions|Close"
+msgstr ""
+
+msgid "Subscriptions|Not ready to buy yet?"
+msgstr ""
+
+msgid "Subscriptions|Start a free trial"
+msgstr ""
+
+msgid "Subscriptions|We understand. Maybe you have some questions for our sales team, or maybe you'd like to try some of the paid features first. What would you like to do?"
+msgstr ""
+
msgid "Subscription|Your subscription for %{strong}%{namespace_name}%{strong_close} has expired and you are now on %{pricing_link_start}the GitLab Free tier%{pricing_link_end}. Don't worry, your data is safe. Get in touch with our support team (%{support_email}). They'll gladly help with your subscription renewal."
msgstr ""
@@ -35312,6 +36036,9 @@ msgstr ""
msgid "SuperSonics|Maximum users"
msgstr ""
+msgid "SuperSonics|Offline cloud"
+msgstr ""
+
msgid "SuperSonics|Paste your activation code"
msgstr ""
@@ -35378,6 +36105,12 @@ msgstr ""
msgid "SuperSonics|You do not have an active subscription"
msgstr ""
+msgid "SuperSonics|You have a future dated license"
+msgstr ""
+
+msgid "SuperSonics|You have added a license that activates on %{date}. Please see the subscription history table below for more details."
+msgstr ""
+
msgid "SuperSonics|You have successfully added a license that activates on %{date}. Please see the subscription history table below for more details."
msgstr ""
@@ -35537,6 +36270,9 @@ msgstr ""
msgid "Tag name is required"
msgstr ""
+msgid "Tag push"
+msgstr ""
+
msgid "Tag push events"
msgstr ""
@@ -35639,6 +36375,9 @@ msgstr ""
msgid "TagsPage|protected"
msgstr ""
+msgid "Take a look at the documentation to discover all of GitLab’s capabilities."
+msgstr ""
+
msgid "Target Branch"
msgstr ""
@@ -36053,6 +36792,9 @@ msgstr ""
msgid "Tests"
msgstr ""
+msgid "Text (optional)"
+msgstr ""
+
msgid "Text added to the body of all email messages. %{character_limit} character limit"
msgstr ""
@@ -36105,6 +36847,9 @@ msgstr ""
msgid "The CSV export will be created in the background. Once finished, it will be sent to %{email} in an attachment."
msgstr ""
+msgid "The CSV export you requested of all user memberships is attached to this email."
+msgstr ""
+
msgid "The GitLab subscription service (customers.gitlab.com) is currently experiencing an outage. You can monitor the status and get updates at %{linkStart}status.gitlab.com%{linkEnd}."
msgstr ""
@@ -36180,6 +36925,9 @@ 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 epic"
+msgstr ""
+
msgid "The current issue"
msgstr ""
@@ -36343,6 +37091,9 @@ msgstr ""
msgid "The latest pipeline for this merge request has failed."
msgstr ""
+msgid "The license key is invalid."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -36358,6 +37109,9 @@ msgstr ""
msgid "The license was successfully uploaded and will be active from %{starts_at}. You can see the details below."
msgstr ""
+msgid "The license you uploaded is invalid. If the issue persists, contact support at %{link}."
+msgstr ""
+
msgid "The list creation wizard is already open"
msgstr ""
@@ -36979,10 +37733,13 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} and everything this project contains. %{strongOpen}There is no going back%{strongClose}"
+msgstr ""
+
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains."
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}on %{date}%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains. %{strongOpen}There is no going back.%{strongClose}"
msgstr ""
msgid "This action will %{strongOpen}permanently remove%{strongClose} %{codeOpen}%{group}%{codeClose} %{strongOpen}immediately%{strongClose}."
@@ -37111,9 +37868,6 @@ msgstr ""
msgid "This file was modified for readability, and can't accept suggestions. Edit it directly."
msgstr ""
-msgid "This forked project has the following:"
-msgstr ""
-
msgid "This form is disabled in preview"
msgstr ""
@@ -37126,7 +37880,7 @@ msgstr ""
msgid "This group can't be removed because it is linked to a subscription. To remove this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
-msgid "This group can't be transfered because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
+msgid "This group can't be transferred because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
msgid "This group cannot be invited to a project inside a group with enforced SSO"
@@ -37153,6 +37907,9 @@ 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 incident is already escalated with '%{escalation_policy_name}'."
+msgstr ""
+
msgid "This invitation was sent to %{mail_to_invite_email}, but you are signed in as %{link_to_current_user} with email %{mail_to_current_user}."
msgstr ""
@@ -37171,9 +37928,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 merge train pipeline"
-msgstr ""
-
msgid "This is a private email address %{helpIcon} generated just for you. Anyone who has it can create issues or merge requests as if they were you. If that happens, %{resetLinkStart}reset this token%{resetLinkEnd}."
msgstr ""
@@ -37195,6 +37949,12 @@ msgstr ""
msgid "This is your current session"
msgstr ""
+msgid "This issue cannot be assigned to a confidential epic because it is public."
+msgstr ""
+
+msgid "This issue cannot be made public because it belongs to a confidential epic."
+msgstr ""
+
msgid "This issue is confidential and should only be visible to team members with at least Reporter access."
msgstr ""
@@ -37312,6 +38072,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 branch is protected from force push."
+msgstr ""
+
msgid "This merge request cannot be rebased while there are conflicts."
msgstr ""
@@ -37363,9 +38126,15 @@ msgstr ""
msgid "This pipeline was triggered by a schedule."
msgstr ""
+msgid "This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project"
msgstr ""
+msgid "This project can be restored until %{date}."
+msgstr ""
+
msgid "This project cannot be %{visibilityLevel} because the visibility of %{openShowLink}%{name}%{closeShowLink} is %{visibility}. To make this project %{visibilityLevel}, you must first %{openEditLink}change the visibility%{closeEditLink} of the parent group."
msgstr ""
@@ -37384,6 +38153,9 @@ msgstr ""
msgid "This project is %{strongStart}NOT%{strongEnd} a fork, and has the following:"
msgstr ""
+msgid "This project is %{strongStart}NOT%{strongEnd} a fork. This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -38079,6 +38851,9 @@ msgstr ""
msgid "Today"
msgstr ""
+msgid "Todos count"
+msgstr ""
+
msgid "Todos|Are you looking for things to do? Take a look at %{strongStart}%{openIssuesLinkStart}open issues%{openIssuesLinkEnd}%{strongEnd}, contribute to %{strongStart}%{mergeRequestLinkStart}a merge request%{mergeRequestLinkEnd}%{mergeRequestLinkEnd}%{strongEnd}, or mention someone in a comment to automatically assign them a new to-do item."
msgstr ""
@@ -38352,12 +39127,8 @@ msgstr ""
msgid "Trending"
msgstr ""
-msgid "Trials|%{planName} Trial %{enDash} %{num} day left"
-msgid_plural "Trials|%{planName} Trial %{enDash} %{num} days left"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-msgstr[3] ""
+msgid "Trials|%{planName} Trial"
+msgstr ""
msgid "Trials|Compare all plans"
msgstr ""
@@ -38365,6 +39136,9 @@ msgstr ""
msgid "Trials|Create a new group to start your GitLab Ultimate trial."
msgstr ""
+msgid "Trials|Day %{daysUsed}/%{duration}"
+msgstr ""
+
msgid "Trials|Go back to GitLab"
msgstr ""
@@ -38614,7 +39388,7 @@ msgstr ""
msgid "URL is triggered when repository is updated"
msgstr ""
-msgid "URL must be percent-encoded if neccessary."
+msgid "URL must be percent-encoded if necessary."
msgstr ""
msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
@@ -38833,6 +39607,9 @@ msgstr ""
msgid "Unlock account"
msgstr ""
+msgid "Unlock more features with GitLab Ultimate"
+msgstr ""
+
msgid "Unlock the discussion"
msgstr ""
@@ -38896,6 +39673,9 @@ msgstr ""
msgid "Unsubscribes from this %{quick_action_target}."
msgstr ""
+msgid "Unsupported sort value."
+msgstr ""
+
msgid "Unsupported todo type passed. Supported todo types are: %{todo_types}"
msgstr ""
@@ -39124,6 +39904,9 @@ msgstr ""
msgid "UsageQuota|File attachments and smaller design graphics."
msgstr ""
+msgid "UsageQuota|From %{storage_enforcement_date} storage limits will apply to this namespace. View and manage your usage in %{strong_start}Group Settings &gt; Usage quotas%{strong_end}."
+msgstr ""
+
msgid "UsageQuota|Git repository."
msgstr ""
@@ -39184,6 +39967,9 @@ msgstr ""
msgid "UsageQuota|Storage type"
msgstr ""
+msgid "UsageQuota|Storage used"
+msgstr ""
+
msgid "UsageQuota|This is the total amount of storage used across your projects within this namespace."
msgstr ""
@@ -39379,6 +40165,12 @@ msgstr ""
msgid "Use hashed storage paths for newly created and renamed repositories. Always enabled since 13.0."
msgstr ""
+msgid "Use issue count"
+msgstr ""
+
+msgid "Use issue weight"
+msgstr ""
+
msgid "Use one line per URI"
msgstr ""
@@ -39760,6 +40552,9 @@ msgstr ""
msgid "Users"
msgstr ""
+msgid "Users API rate limit"
+msgstr ""
+
msgid "Users can launch a development environment from a GitLab browser tab when the %{linkStart}Gitpod%{linkEnd} integration is enabled."
msgstr ""
@@ -40089,6 +40884,9 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View group pipeline usage quota"
+msgstr ""
+
msgid "View incident details at"
msgstr ""
@@ -40243,6 +41041,9 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
+msgid "Vulnerability"
+msgstr ""
+
msgid "Vulnerability Report"
msgstr ""
@@ -40294,6 +41095,9 @@ msgstr ""
msgid "VulnerabilityManagement|An unverified non-confirmed finding"
msgstr ""
+msgid "VulnerabilityManagement|At least one identifier is required"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -40303,12 +41107,24 @@ msgstr ""
msgid "VulnerabilityManagement|Create Jira issue"
msgstr ""
+msgid "VulnerabilityManagement|Enter a name"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE code"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE identifier URL"
+msgstr ""
+
msgid "VulnerabilityManagement|Fetching linked Jira issues"
msgstr ""
msgid "VulnerabilityManagement|Manually add a vulnerability entry into the vulnerability report."
msgstr ""
+msgid "VulnerabilityManagement|Name is a required field"
+msgstr ""
+
msgid "VulnerabilityManagement|Needs triage"
msgstr ""
@@ -40324,6 +41140,18 @@ msgstr ""
msgid "VulnerabilityManagement|Select a method"
msgstr ""
+msgid "VulnerabilityManagement|Select a severity level"
+msgstr ""
+
+msgid "VulnerabilityManagement|Select a status"
+msgstr ""
+
+msgid "VulnerabilityManagement|Severity is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Something went wrong while creating vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -40348,6 +41176,12 @@ msgstr ""
msgid "VulnerabilityManagement|Something went wrong, could not update vulnerability state."
msgstr ""
+msgid "VulnerabilityManagement|Status is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Submit vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Summary, detailed description, steps to reproduce, etc."
msgstr ""
@@ -40543,6 +41377,9 @@ msgstr ""
msgid "WARNING:"
msgstr ""
+msgid "WARNING: This snippet contains hidden files which might be used to mask malicious behavior. Exercise caution if cloning and executing code from this snippet."
+msgstr ""
+
msgid "Wait for the file to load to copy its contents"
msgstr ""
@@ -40762,6 +41599,15 @@ msgstr ""
msgid "Webhooks|An issue is created, updated, closed, or reopened."
msgstr ""
+msgid "Webhooks|Are you sure you want to delete this group hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this project hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this webhook?"
+msgstr ""
+
msgid "Webhooks|Comments"
msgstr ""
@@ -40771,6 +41617,9 @@ msgstr ""
msgid "Webhooks|Confidential issues events"
msgstr ""
+msgid "Webhooks|Delete webhook"
+msgstr ""
+
msgid "Webhooks|Deployment events"
msgstr ""
@@ -41006,6 +41855,9 @@ msgstr ""
msgid "Wiki"
msgstr ""
+msgid "Wiki page"
+msgstr ""
+
msgid "Wiki page was successfully created."
msgstr ""
@@ -41111,7 +41963,7 @@ msgstr ""
msgid "WikiPageConflictMessage|Someone edited the page the same time you did. Please check out %{wikiLinkStart}the page%{wikiLinkEnd} and make sure your changes will not unintentionally remove theirs."
msgstr ""
-msgid "WikiPage|An error occured while trying to render the content editor. Please try again later."
+msgid "WikiPage|An error occurred while trying to render the content editor. Please try again later."
msgstr ""
msgid "WikiPage|Are you sure you want to switch back to the classic editor?"
@@ -41270,6 +42122,18 @@ msgstr ""
msgid "WorkItem|New Task"
msgstr ""
+msgid "WorkItem|Something went wrong when creating a work item. Please try again"
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching the work item. Please try again."
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching work item types. Please try again"
+msgstr ""
+
+msgid "WorkItem|Type"
+msgstr ""
+
msgid "WorkItem|Work Items"
msgstr ""
@@ -41336,7 +42200,10 @@ msgstr ""
msgid "You are about to add %{usersTag} people to the discussion. They will all receive a notification."
msgstr ""
-msgid "You are about to permanently delete this project"
+msgid "You are about to delete this forked project containing:"
+msgstr ""
+
+msgid "You are about to delete this project containing:"
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."
@@ -41357,6 +42224,9 @@ msgstr ""
msgid "You are attempting to update a file that has changed since you started editing it."
msgstr ""
+msgid "You are billed if you exceed this number. %{qsrOverageLinkStart}How does billing work?%{qsrOverageLinkEnd}"
+msgstr ""
+
msgid "You are connected to the Prometheus server, but there is currently no data to display."
msgstr ""
@@ -41414,6 +42284,9 @@ msgstr ""
msgid "You are not authorized to update this scanner profile"
msgstr ""
+msgid "You are not authorized to upload metric images"
+msgstr ""
+
msgid "You are now impersonating %{username}"
msgstr ""
@@ -41567,9 +42440,6 @@ msgstr ""
msgid "You can only upload one design when dropping onto an existing design."
msgstr ""
-msgid "You can recover this project until %{date}"
-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 ""
@@ -41618,9 +42488,6 @@ msgstr ""
msgid "You cannot write to this read-only GitLab instance."
msgstr ""
-msgid "You can’t %{tag_start}edit%{tag_end} files directly in this project. Fork this project and submit a merge request with your changes."
-msgstr ""
-
msgid "You can’t edit files directly in this project. Fork this project and submit a merge request with your changes."
msgstr ""
@@ -41775,9 +42642,6 @@ 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 set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
@@ -41808,12 +42672,6 @@ msgstr ""
msgid "You must have maintainer access to force delete a lock"
msgstr ""
-msgid "You must have permission to create a project in a group before forking."
-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 ""
@@ -42219,7 +43077,7 @@ msgstr ""
msgid "Your public email will be displayed on your public profile."
msgstr ""
-msgid "Your request for access could not be processed: %{error_meesage}"
+msgid "Your request for access could not be processed: %{error_message}"
msgstr ""
msgid "Your request for access has been queued for review."
@@ -42408,6 +43266,9 @@ msgstr ""
msgid "archived:"
msgstr ""
+msgid "artifacts"
+msgstr ""
+
msgid "assign yourself"
msgstr ""
@@ -42439,6 +43300,9 @@ msgstr[3] ""
msgid "branch name"
msgstr ""
+msgid "builds"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -42868,6 +43732,9 @@ msgstr ""
msgid "contact with same email already exists in group hierarchy"
msgstr ""
+msgid "container registry images"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -42907,6 +43774,9 @@ msgstr ""
msgid "data"
msgstr ""
+msgid "database"
+msgstr ""
+
msgid "date must not be after 9999-12-31"
msgstr ""
@@ -42932,9 +43802,6 @@ msgstr ""
msgid "design"
msgstr ""
-msgid "detached"
-msgstr ""
-
msgid "disabled"
msgstr ""
@@ -43191,7 +44058,7 @@ msgstr ""
msgid "is not a valid X509 certificate."
msgstr ""
-msgid "is not allowed for sign-up."
+msgid "is not allowed for sign-up. Please use your regular email address."
msgstr ""
msgid "is not allowed for this group."
@@ -43203,7 +44070,7 @@ msgstr ""
msgid "is not allowed since the group is not top-level group."
msgstr ""
-msgid "is not allowed."
+msgid "is not allowed. Please use your regular email address."
msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
@@ -43290,6 +44157,9 @@ msgstr ""
msgid "level: %{level}"
msgstr ""
+msgid "lfs objects"
+msgstr ""
+
msgid "limit of %{project_limit} reached"
msgstr ""
@@ -43515,6 +44385,9 @@ msgstr ""
msgid "mrWidget|Merge blocked: pipeline must succeed. It's waiting for a manual action to continue."
msgstr ""
+msgid "mrWidget|Merge blocked: pipeline must succeed. Push a commit that fixes the failure, or %{linkStart}learn about other solutions.%{linkEnd}"
+msgstr ""
+
msgid "mrWidget|Merge blocked: this merge request must be approved."
msgstr ""
@@ -43632,9 +44505,6 @@ msgstr ""
msgid "mrWidget|The changes were not merged into"
msgstr ""
-msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -43782,9 +44652,6 @@ msgstr ""
msgid "open issue"
msgstr ""
-msgid "opened %{timeAgo}"
-msgstr ""
-
msgid "or"
msgstr ""
@@ -43798,6 +44665,12 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "packages"
+msgstr ""
+
+msgid "pages"
+msgstr ""
+
msgid "parent"
msgid_plural "parents"
msgstr[0] ""
@@ -43955,6 +44828,9 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "repositories"
+msgstr ""
+
msgid "repository:"
msgstr ""
@@ -44075,12 +44951,18 @@ msgstr ""
msgid "tag name"
msgstr ""
+msgid "terraform states"
+msgstr ""
+
msgid "the correct format."
msgstr ""
msgid "the file"
msgstr ""
+msgid "the following epic(s)"
+msgstr ""
+
msgid "the following issue(s)"
msgstr ""
@@ -44093,21 +44975,12 @@ msgstr ""
msgid "this document"
msgstr ""
-msgid "this issue cannot be assigned to a confidential epic since it is public"
-msgstr ""
-
-msgid "this issue cannot be made public since it belongs to a confidential epic"
-msgstr ""
-
msgid "time summary"
msgstr ""
msgid "toggle collapse"
msgstr ""
-msgid "train"
-msgstr ""
-
msgid "triggered"
msgstr ""
@@ -44238,3 +45111,6 @@ msgstr ""
msgid "{project}"
msgstr ""
+msgid "✔"
+msgstr ""
+
diff --git a/locale/sl_SI/gitlab.po b/locale/sl_SI/gitlab.po
index b51de9153d5..34d87747867 100644
--- a/locale/sl_SI/gitlab.po
+++ b/locale/sl_SI/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: sl\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2022-02-02 15:42\n"
+"PO-Revision-Date: 2022-03-01 20:36\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -174,6 +174,13 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "%d assigned issue"
+msgid_plural "%d assigned issues"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -559,8 +566,29 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
-msgid "%d vulnerability updated"
-msgid_plural "%d vulnerabilities updated"
+msgid "%d vulnerability set to confirmed"
+msgid_plural "%d vulnerabilities set to confirmed"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
+msgid "%d vulnerability set to dismissed"
+msgid_plural "%d vulnerabilities set to dismissed"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
+msgid "%d vulnerability set to needs triage"
+msgid_plural "%d vulnerabilities set to needs triage"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
+msgid "%d vulnerability set to resolved"
+msgid_plural "%d vulnerabilities set to resolved"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
@@ -662,6 +690,12 @@ msgstr[3] ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{completed} of %{total} issues closed"
+msgstr ""
+
+msgid "%{completed} of %{total} weight completed"
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -1022,6 +1056,9 @@ msgstr ""
msgid "%{openedIssues} open, %{closedIssues} closed"
msgstr ""
+msgid "%{percentage}%% issues closed"
+msgstr ""
+
msgid "%{percentage}%% weight completed"
msgstr ""
@@ -1481,6 +1518,9 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "- of - issues closed"
+msgstr ""
+
msgid "- of - weight completed"
msgstr ""
@@ -1669,7 +1709,7 @@ msgstr ""
msgid "1000+"
msgstr ""
-msgid "192.168.0.0/24"
+msgid "192.168.0.0/24 or 2001:0DB8:1234::/48"
msgstr ""
msgid "1st contribution!"
@@ -1981,13 +2021,13 @@ msgstr ""
msgid "AWS Access Key"
msgstr ""
-msgid "AWS Access Key. Only required if not using role instance credentials"
+msgid "AWS Secret Access Key"
msgstr ""
-msgid "AWS Secret Access Key"
+msgid "AWS access key ID (Optional)"
msgstr ""
-msgid "AWS Secret Access Key. Only required if not using role instance credentials"
+msgid "AWS secret access key (Optional)"
msgstr ""
msgid "AWS service error: %{error}"
@@ -2047,9 +2087,6 @@ msgstr ""
msgid "Access granted"
msgstr ""
-msgid "Access key ID"
-msgstr ""
-
msgid "Access requests"
msgstr ""
@@ -2224,7 +2261,7 @@ msgstr ""
msgid "Activity"
msgstr ""
-msgid "Activity|An error occured while retrieving activity. Reload the page to try again."
+msgid "Activity|An error occurred while retrieving activity. Reload the page to try again."
msgstr ""
msgid "Add"
@@ -2263,6 +2300,9 @@ msgstr ""
msgid "Add a %{type}"
msgstr ""
+msgid "Add a GCP region"
+msgstr ""
+
msgid "Add a GPG key"
msgstr ""
@@ -2314,6 +2354,9 @@ msgstr ""
msgid "Add a numbered list"
msgstr ""
+msgid "Add a related epic"
+msgstr ""
+
msgid "Add a related issue"
msgstr ""
@@ -2428,6 +2471,9 @@ msgstr ""
msgid "Add or subtract spent time"
msgstr ""
+msgid "Add people"
+msgstr ""
+
msgid "Add previously merged commits"
msgstr ""
@@ -2494,6 +2540,9 @@ msgstr ""
msgid "Add webhook"
msgstr ""
+msgid "Add your team members and others to GitLab."
+msgstr ""
+
msgid "Add/remove"
msgstr ""
@@ -3316,12 +3365,6 @@ msgstr ""
msgid "AdvancedSearch|Reindex required"
msgstr ""
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. Permanently deleting this project will %{strongStart}immediately delete%{strongEnd} its repositories and %{strongStart}all related resources%{strongEnd}, including issues, merge requests etc."
-msgstr ""
-
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. You will lose this project's repository and %{strongStart}all related resources%{strongEnd}, including issues and merge requests."
-msgstr ""
-
msgid "After a successful password update you will be redirected to login screen."
msgstr ""
@@ -3352,6 +3395,9 @@ msgstr ""
msgid "Akismet helps prevent the creation of spam issues in public projects."
msgstr ""
+msgid "Alert"
+msgstr ""
+
msgid "AlertManagement|Acknowledged"
msgstr ""
@@ -3724,9 +3770,6 @@ msgstr ""
msgid "All environments"
msgstr ""
-msgid "All epics"
-msgstr ""
-
msgid "All groups and projects"
msgstr ""
@@ -4467,14 +4510,17 @@ msgstr ""
msgid "ApplicationSettings|Approve users in the pending approval status?"
msgstr ""
-msgid "ApplicationSettings|By making this change, you will automatically approve %d user with the pending approval status."
-msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users with the pending approval status."
+msgid "ApplicationSettings|Approve users who are pending approval?"
+msgstr ""
+
+msgid "ApplicationSettings|By making this change, you will automatically approve %d user who is pending approval."
+msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users who are pending approval."
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
-msgid "ApplicationSettings|By making this change, you will automatically approve all users in pending approval status."
+msgid "ApplicationSettings|By making this change, you will automatically approve all users who are pending approval."
msgstr ""
msgid "ApplicationSettings|Denied domains for sign-ups"
@@ -4890,10 +4936,10 @@ msgstr ""
msgid "Archiving the project will make it entirely read-only. It is hidden from the dashboard and doesn't show up in searches. %{strong_start}The repository cannot be committed to, and no issues, comments, or other entities can be created.%{strong_end} %{link_start}Learn more.%{link_end}"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to delete this project?"
+msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
+msgid "Are you absolutely sure?"
msgstr ""
msgid "Are you sure that you want to archive this project?"
@@ -4929,12 +4975,18 @@ msgstr ""
msgid "Are you sure you want to delete this SSH key?"
msgstr ""
+msgid "Are you sure you want to delete this comment?"
+msgstr ""
+
msgid "Are you sure you want to delete this deploy key?"
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 label?"
+msgstr ""
+
msgid "Are you sure you want to delete this pipeline schedule?"
msgstr ""
@@ -4950,9 +5002,6 @@ msgstr ""
msgid "Are you sure you want to discard your changes?"
msgstr ""
-msgid "Are you sure you want to erase this build?"
-msgstr ""
-
msgid "Are you sure you want to import %d repository?"
msgid_plural "Are you sure you want to import %d repositories?"
msgstr[0] ""
@@ -5002,6 +5051,9 @@ msgstr ""
msgid "Are you sure you want to remove this list?"
msgstr ""
+msgid "Are you sure you want to remove this nickname?"
+msgstr ""
+
msgid "Are you sure you want to reset the health check token?"
msgstr ""
@@ -5014,10 +5066,10 @@ 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?"
+msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
msgstr ""
-msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
+msgid "Are you sure you want to revoke this project access token? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to stop this environment?"
@@ -5164,9 +5216,6 @@ msgstr ""
msgid "Assigned to %{assignee_name}"
msgstr ""
-msgid "Assigned to %{name}"
-msgstr ""
-
msgid "Assigned to me"
msgstr ""
@@ -5235,6 +5284,9 @@ msgstr[3] ""
msgid "Attaching the file failed."
msgstr ""
+msgid "Attention"
+msgstr ""
+
msgid "Audit Events"
msgstr ""
@@ -5397,6 +5449,12 @@ msgstr ""
msgid "Authorized applications (%{size})"
msgstr ""
+msgid "AuthorizedApplication|Are you sure you want to revoke this application?"
+msgstr ""
+
+msgid "AuthorizedApplication|Revoke application"
+msgstr ""
+
msgid "Authors: %{authors}"
msgstr ""
@@ -6598,6 +6656,9 @@ msgstr ""
msgid "CICDAnalytics|Shared Runners Usage"
msgstr ""
+msgid "CICDAnalytics|Shared runner pipeline minute duration by month"
+msgstr ""
+
msgid "CICDAnalytics|Shared runner usage"
msgstr ""
@@ -6739,6 +6800,9 @@ msgstr ""
msgid "Can create groups:"
msgstr ""
+msgid "Can not delete primary training"
+msgstr ""
+
msgid "Can't apply as the source branch was deleted."
msgstr ""
@@ -7072,9 +7136,6 @@ msgstr ""
msgid "Changing any setting here requires an application restart"
msgstr ""
-msgid "Changing group URL can have unintended side effects."
-msgstr ""
-
msgid "Charts can't be displayed as the request for data has timed out. %{documentationLink}"
msgstr ""
@@ -7162,9 +7223,6 @@ msgstr ""
msgid "Checking branch availability..."
msgstr ""
-msgid "Checking group URL availability..."
-msgstr ""
-
msgid "Checking group path availability..."
msgstr ""
@@ -7662,6 +7720,9 @@ msgstr ""
msgid "Clear recent searches"
msgstr ""
+msgid "Clear repository checks"
+msgstr ""
+
msgid "Clear search"
msgstr ""
@@ -7794,9 +7855,6 @@ msgstr ""
msgid "Closed MRs"
msgstr ""
-msgid "Closed epics"
-msgstr ""
-
msgid "Closed issues"
msgstr ""
@@ -7833,13 +7891,13 @@ msgstr ""
msgid "Cluster level"
msgstr ""
-msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
+msgid "Cluster type must be specified for Stages::ClusterEndpointInserter"
msgstr ""
msgid "ClusterAgents|%{name} successfully deleted"
msgstr ""
-msgid "ClusterAgents|%{number} of %{total} Agents"
+msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
@@ -7881,6 +7939,15 @@ msgstr ""
msgid "ClusterAgents|Agent never connected to GitLab"
msgstr ""
+msgid "ClusterAgents|Agent version mismatch"
+msgstr ""
+
+msgid "ClusterAgents|Agent version mismatch and update"
+msgstr ""
+
+msgid "ClusterAgents|Agent version update required"
+msgstr ""
+
msgid "ClusterAgents|All"
msgstr ""
@@ -7905,7 +7972,7 @@ msgstr ""
msgid "ClusterAgents|Configuration"
msgstr ""
-msgid "ClusterAgents|Connect a cluster through the Agent"
+msgid "ClusterAgents|Connect a cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connect existing cluster"
@@ -7914,13 +7981,13 @@ msgstr ""
msgid "ClusterAgents|Connect with a certificate"
msgstr ""
-msgid "ClusterAgents|Connect with agent"
+msgid "ClusterAgents|Connect with an agent"
msgstr ""
msgid "ClusterAgents|Connect with the GitLab Agent"
msgstr ""
-msgid "ClusterAgents|Connect your cluster through the Agent"
+msgid "ClusterAgents|Connect your cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connected"
@@ -7980,7 +8047,10 @@ msgstr ""
msgid "ClusterAgents|How to register an agent?"
msgstr ""
-msgid "ClusterAgents|Install new Agent"
+msgid "ClusterAgents|How to update an agent?"
+msgstr ""
+
+msgid "ClusterAgents|Install a new agent"
msgstr ""
msgid "ClusterAgents|Last connected %{timeAgo}."
@@ -8007,7 +8077,7 @@ msgstr ""
msgid "ClusterAgents|Never connected"
msgstr ""
-msgid "ClusterAgents|No Agents"
+msgid "ClusterAgents|No agents"
msgstr ""
msgid "ClusterAgents|No clusters connected through cluster certificates"
@@ -8067,6 +8137,9 @@ msgstr ""
msgid "ClusterAgents|The agent has not been connected in a long time. There might be a connectivity issue. Last contact was %{timeAgo}."
msgstr ""
+msgid "ClusterAgents|The agent version do not match each other across your cluster's pods. This can happen when a new agent version was just deployed and Kubernetes is shutting down the old pods."
+msgstr ""
+
msgid "ClusterAgents|The recommended installation method includes the token. If you want to follow the advanced installation method provided in the docs, make sure you save the token value before you close this window."
msgstr ""
@@ -8116,6 +8189,9 @@ msgstr ""
msgid "ClusterAgents|You will need to create a token to connect to your agent"
msgstr ""
+msgid "ClusterAgents|Your agent version is out of sync with your GitLab version (v%{version}), which might cause compatibility problems. Update the agent installed on your cluster to the most recent version."
+msgstr ""
+
msgid "ClusterAgents|Your instance doesn't have the %{linkStart}GitLab Agent Server (KAS)%{linkEnd} set up. Ask a GitLab Administrator to install it."
msgstr ""
@@ -8992,9 +9068,6 @@ msgstr ""
msgid "Comma-separated list of email addresses."
msgstr ""
-msgid "Comma-separated list of users allowed to exceed the rate limit."
-msgstr ""
-
msgid "Comma-separated, e.g. '1.1.1.1, 2.2.2.0/24'"
msgstr ""
@@ -9323,6 +9396,12 @@ msgstr ""
msgid "Confidential"
msgstr ""
+msgid "Confidential issue"
+msgstr ""
+
+msgid "Confidential note"
+msgstr ""
+
msgid "Confidentiality"
msgstr ""
@@ -9356,6 +9435,9 @@ msgstr ""
msgid "Configure Dependency Scanning in `.gitlab-ci.yml`, creating this file if it does not already exist"
msgstr ""
+msgid "Configure GitLab"
+msgstr ""
+
msgid "Configure GitLab runners to start using the Web Terminal. %{helpStart}Learn more.%{helpEnd}"
msgstr ""
@@ -9404,6 +9486,15 @@ msgstr ""
msgid "Configure pipelines to deploy web apps, backend services, APIs and static resources to Google Cloud"
msgstr ""
+msgid "Configure region"
+msgstr ""
+
+msgid "Configure region for environment"
+msgstr ""
+
+msgid "Configure regions"
+msgstr ""
+
msgid "Configure repository mirroring."
msgstr ""
@@ -9437,6 +9528,9 @@ msgstr ""
msgid "Configure which lists are shown for anyone who visits this board"
msgstr ""
+msgid "Configure your environments to be deployed to specific geographical regions"
+msgstr ""
+
msgid "Confirm"
msgstr ""
@@ -10145,10 +10239,10 @@ msgstr ""
msgid "CorpusManagement|Actions"
msgstr ""
-msgid "CorpusManagement|Corpus are used in fuzz testing as mutation source to Improve future testing."
+msgid "CorpusManagement|Corpus file"
msgstr ""
-msgid "CorpusManagement|Corpus file"
+msgid "CorpusManagement|Corpus files are used in coverage-guided fuzz testing as seed inputs to improve testing."
msgstr ""
msgid "CorpusManagement|Corpus files must be in *.zip format. Maximum 5 GB"
@@ -10202,6 +10296,9 @@ msgstr ""
msgid "Could not apply %{name} command."
msgstr ""
+msgid "Could not apply %{name} command. %{message}."
+msgstr ""
+
msgid "Could not authorize chat nickname. Try again!"
msgstr ""
@@ -10352,6 +10449,9 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
+msgid "Create a group"
+msgstr ""
+
msgid "Create a merge request"
msgstr ""
@@ -10376,6 +10476,9 @@ msgstr ""
msgid "Create a personal access token on your account to pull or push via %{protocol}."
msgstr ""
+msgid "Create a project"
+msgstr ""
+
msgid "Create an account using:"
msgstr ""
@@ -10739,6 +10842,9 @@ msgstr ""
msgid "Creation date"
msgstr ""
+msgid "Creator"
+msgstr ""
+
msgid "Credentials"
msgstr ""
@@ -10751,9 +10857,15 @@ msgstr ""
msgid "CredentialsInventory|Personal Access Tokens"
msgstr ""
+msgid "CredentialsInventory|Project Access Tokens"
+msgstr ""
+
msgid "CredentialsInventory|SSH Keys"
msgstr ""
+msgid "Credit card required to be on file in order to create a pipeline"
+msgstr ""
+
msgid "Credit card:"
msgstr ""
@@ -10937,9 +11049,6 @@ msgstr ""
msgid "Customer relations"
msgstr ""
-msgid "Customizable by an administrator."
-msgstr ""
-
msgid "Customizable by owners."
msgstr ""
@@ -11069,30 +11178,18 @@ msgstr ""
msgid "CycleAnalytics|%{selectedLabelsCount} selected (%{maxLabels} max)"
msgstr ""
-msgid "CycleAnalytics|%{stageCount} stages selected"
-msgstr ""
-
-msgid "CycleAnalytics|All stages"
-msgstr ""
-
-msgid "CycleAnalytics|Average days to completion"
+msgid "CycleAnalytics|Average time to completion"
msgstr ""
msgid "CycleAnalytics|Date"
msgstr ""
-msgid "CycleAnalytics|Days to completion"
-msgstr ""
-
msgid "CycleAnalytics|Display chart filters"
msgstr ""
msgid "CycleAnalytics|Lead Time for Changes"
msgstr ""
-msgid "CycleAnalytics|No stages selected"
-msgstr ""
-
msgid "CycleAnalytics|Number of tasks"
msgstr ""
@@ -11125,18 +11222,30 @@ msgstr ""
msgid "CycleAnalytics|Showing data for group '%{groupName}' from %{createdAfter} to %{createdBefore}"
msgstr ""
-msgid "CycleAnalytics|Stages"
+msgid "CycleAnalytics|Stage time: %{title}"
msgstr ""
msgid "CycleAnalytics|Tasks by type"
msgstr ""
-msgid "CycleAnalytics|The average time spent in the selected stage for the items that were completed on each date. Data limited to the last 500 items."
+msgid "CycleAnalytics|The average time items spent in this stage. Data limited to items completed within this date range."
msgstr ""
msgid "CycleAnalytics|The given date range is larger than 180 days"
msgstr ""
+msgid "CycleAnalytics|The total time items spent across each value stream stage. Data limited to items completed within this date range."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Stage time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Total time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|Total time"
+msgstr ""
+
msgid "CycleAnalytics|Type of work"
msgstr ""
@@ -11149,9 +11258,6 @@ msgstr ""
msgid "CycleAnalytics|project dropdown filter"
msgstr ""
-msgid "CycleAnalytics|stage dropdown"
-msgstr ""
-
msgid "DAG visualization requires at least 3 dependent jobs."
msgstr ""
@@ -11251,10 +11357,16 @@ msgstr ""
msgid "DastProfiles|AJAX spider"
msgstr ""
+msgid "DastProfiles|API"
+msgstr ""
+
+msgid "DastProfiles|API endpoint URL"
+msgstr ""
+
msgid "DastProfiles|Active"
msgstr ""
-msgid "DastProfiles|Additional request headers (Optional)"
+msgid "DastProfiles|Additional request headers (optional)"
msgstr ""
msgid "DastProfiles|Are you sure you want to delete this profile?"
@@ -11269,6 +11381,9 @@ msgstr ""
msgid "DastProfiles|Branch missing"
msgstr ""
+msgid "DastProfiles|Choose a scan method"
+msgstr ""
+
msgid "DastProfiles|Could not create the scanner profile. Please try again."
msgstr ""
@@ -11338,7 +11453,13 @@ msgstr ""
msgid "DastProfiles|Excluded URLs"
msgstr ""
-msgid "DastProfiles|Excluded URLs (Optional)"
+msgid "DastProfiles|Excluded URLs (optional)"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths (optional)"
msgstr ""
msgid "DastProfiles|Hide debug messages"
@@ -11395,9 +11516,6 @@ msgstr ""
msgid "DastProfiles|Request headers"
msgstr ""
-msgid "DastProfiles|Rest API"
-msgstr ""
-
msgid "DastProfiles|Run the AJAX spider, in addition to the traditional spider, to crawl the target site."
msgstr ""
@@ -11407,6 +11525,9 @@ msgstr ""
msgid "DastProfiles|Save profile"
msgstr ""
+msgid "DastProfiles|Scan method"
+msgstr ""
+
msgid "DastProfiles|Scan mode"
msgstr ""
@@ -11485,12 +11606,24 @@ msgstr ""
msgid "DastProfiles|Website"
msgstr ""
+msgid "DastProfiles|What does each method do?"
+msgstr ""
+
msgid "DastProfiles|You can either choose a passive scan or validate the target site from the site profile management page. %{docsLinkStart}Learn more about site validation.%{docsLinkEnd}"
msgstr ""
msgid "DastProfiles|You cannot run an active scan against an unvalidated site."
msgstr ""
+msgid "DastProfiles|folder/dast_example.har or https://example.com/dast_example.har"
+msgstr ""
+
+msgid "DastProfiles|folder/example.postman_collection.json or https://example.com/"
+msgstr ""
+
+msgid "DastProfiles|folder/openapi.json or https://example.com/openapi.json"
+msgstr ""
+
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
@@ -11600,6 +11733,9 @@ msgstr ""
msgid "DatadogIntegration|API URL"
msgstr ""
+msgid "DatadogIntegration|Custom tags in Datadog. Enter one tag per line in the %{codeOpen}key:value%{codeClose} format. %{linkOpen}How do I use tags?%{linkClose}"
+msgstr ""
+
msgid "DatadogIntegration|Environment"
msgstr ""
@@ -11618,12 +11754,18 @@ msgstr ""
msgid "DatadogIntegration|Tag all data from this GitLab instance in Datadog. Useful when managing several self-managed deployments."
msgstr ""
+msgid "DatadogIntegration|Tags"
+msgstr ""
+
msgid "DatadogIntegration|The Datadog site to send data to. To send data to the EU site, use %{codeOpen}datadoghq.eu%{codeClose}."
msgstr ""
msgid "DatadogIntegration|Trace your GitLab pipelines with Datadog."
msgstr ""
+msgid "DatadogIntegration|have an invalid format"
+msgstr ""
+
msgid "Datasource name not found"
msgstr ""
@@ -11633,9 +11775,6 @@ msgstr ""
msgid "Date merged"
msgstr ""
-msgid "Date picker"
-msgstr ""
-
msgid "Date range"
msgstr ""
@@ -11789,9 +11928,6 @@ msgstr ""
msgid "Definition"
msgstr ""
-msgid "Delayed Project Deletion (%{adjourned_deletion})"
-msgstr ""
-
msgid "DelayedJobs|Are you sure you want to run %{jobName} immediately? Otherwise this job will run automatically after its timer finishes."
msgstr ""
@@ -11870,10 +12006,10 @@ msgstr ""
msgid "Delete pipeline"
msgstr ""
-msgid "Delete project"
+msgid "Delete pipeline schedule"
msgstr ""
-msgid "Delete project. Are you ABSOLUTELY SURE?"
+msgid "Delete project"
msgstr ""
msgid "Delete row"
@@ -11903,6 +12039,9 @@ msgstr ""
msgid "Delete this epic and all descendants?"
msgstr ""
+msgid "Delete this project"
+msgstr ""
+
msgid "Delete user list"
msgstr ""
@@ -12173,6 +12312,12 @@ msgstr ""
msgid "Deploy to..."
msgstr ""
+msgid "DeployBoards|To see deployment progress for your environments, make sure you are deploying to %{codeStart}$KUBE_NAMESPACE%{codeEnd} and annotating with %{codeStart}app.gitlab.com/app=$CI_PROJECT_PATH_SLUG%{codeEnd} and %{codeStart}app.gitlab.com/env=$CI_ENVIRONMENT_SLUG%{codeEnd}."
+msgstr ""
+
+msgid "DeployBoard|Kubernetes Pods"
+msgstr ""
+
msgid "DeployFreeze|Add a freeze period to prevent unintended releases during a period of time for a given environment. You must update the deployment jobs in %{filename} according to the deploy freezes added here. %{freeze_period_link_start}Learn more.%{freeze_period_link_end}"
msgstr ""
@@ -12257,9 +12402,6 @@ msgstr ""
msgid "DeployTokens|Active Deploy Tokens (%{active_tokens})"
msgstr ""
-msgid "DeployTokens|Allows read and write access to registry images."
-msgstr ""
-
msgid "DeployTokens|Allows read and write access to the package registry."
msgstr ""
@@ -12272,6 +12414,9 @@ msgstr ""
msgid "DeployTokens|Allows read-only access to the repository."
msgstr ""
+msgid "DeployTokens|Allows write access to registry images."
+msgstr ""
+
msgid "DeployTokens|Copy deploy token"
msgstr ""
@@ -12365,12 +12510,57 @@ msgstr ""
msgid "Deploying to AWS is easy with GitLab"
msgstr ""
+msgid "Deployment"
+msgstr ""
+
msgid "Deployment Frequency"
msgstr ""
+msgid "Deployment Target|Project deployment target (optional)"
+msgstr ""
+
+msgid "Deployment Target|Select the deployment target"
+msgstr ""
+
msgid "Deployment frequency"
msgstr ""
+msgid "DeploymentTarget|GitLab Pages"
+msgstr ""
+
+msgid "DeploymentTarget|Heroku"
+msgstr ""
+
+msgid "DeploymentTarget|Infrastructure provider (Terraform, Cloudformation, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Kubernetes (GKE, EKS, OpenShift, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Managed container runtime (Fargate, Cloud Run, DigitalOcean App)"
+msgstr ""
+
+msgid "DeploymentTarget|Mobile app store"
+msgstr ""
+
+msgid "DeploymentTarget|No deployment planned"
+msgstr ""
+
+msgid "DeploymentTarget|Other hosting service"
+msgstr ""
+
+msgid "DeploymentTarget|Registry (package or container)"
+msgstr ""
+
+msgid "DeploymentTarget|Self-managed container runtime (Podman, Docker Swarm, Docker Compose)"
+msgstr ""
+
+msgid "DeploymentTarget|Serverless backend (Lambda, Cloud functions)"
+msgstr ""
+
+msgid "DeploymentTarget|Virtual machine (for example, EC2)"
+msgstr ""
+
msgid "Deployments"
msgstr ""
@@ -12411,6 +12601,9 @@ msgstr ""
msgid "Deployment|This deployment was created using the API"
msgstr ""
+msgid "Deployment|Triggerer"
+msgstr ""
+
msgid "Deployment|Waiting"
msgstr ""
@@ -12438,6 +12631,18 @@ msgstr ""
msgid "Deprecated API rate limits"
msgstr ""
+msgid "Deprecations|Feature deprecation and removal"
+msgstr ""
+
+msgid "Deprecations|For information on a possible replacement %{epicStart} learn more about Opstrace %{epicEnd}."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7 and are %{epicStart} scheduled for removal %{epicEnd} in GitLab 15.0."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7, and are %{removal_link_start} scheduled for removal %{link_end} in GitLab 15.0. For information on a possible replacement, %{opstrace_link_start} learn more about Opstrace %{link_end}."
+msgstr ""
+
msgid "Deprioritize label"
msgstr ""
@@ -12685,10 +12890,10 @@ msgstr ""
msgid "DevopsAdoption|At least one deploy"
msgstr ""
-msgid "DevopsAdoption|At least one issue opened"
+msgid "DevopsAdoption|At least one issue created"
msgstr ""
-msgid "DevopsAdoption|At least one merge request opened"
+msgid "DevopsAdoption|At least one merge request created"
msgstr ""
msgid "DevopsAdoption|At least one pipeline successfully run"
@@ -12895,6 +13100,9 @@ msgstr ""
msgid "Direct member"
msgstr ""
+msgid "Direct members"
+msgstr ""
+
msgid "Direct non-authenticated users to this page."
msgstr ""
@@ -13013,6 +13221,9 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "Dismiss Alert"
+msgstr ""
+
msgid "Dismiss merge request promotion"
msgstr ""
@@ -13040,9 +13251,15 @@ msgstr ""
msgid "Display alerts from all configured monitoring tools."
msgstr ""
+msgid "Display milestones"
+msgstr ""
+
msgid "Display name"
msgstr ""
+msgid "Display progress of child issues"
+msgstr ""
+
msgid "Display rendered file"
msgstr ""
@@ -13148,6 +13365,9 @@ msgstr ""
msgid "Download image"
msgstr ""
+msgid "Download payload"
+msgstr ""
+
msgid "Download raw data (.csv)"
msgstr ""
@@ -13325,6 +13545,9 @@ msgstr ""
msgid "Edit in Web IDE"
msgstr ""
+msgid "Edit in pipeline editor"
+msgstr ""
+
msgid "Edit in single-file editor"
msgstr ""
@@ -13367,6 +13590,9 @@ msgstr ""
msgid "Edit your most recent comment in a thread (from an empty textarea)"
msgstr ""
+msgid "Edit, lint, and visualize your pipeline."
+msgstr ""
+
msgid "Edited"
msgstr ""
@@ -13808,6 +14034,9 @@ msgstr ""
msgid "Enforce two-factor authentication for all user sign-ins."
msgstr ""
+msgid "Enhance security by storing service account keys in secret managers - learn more about %{docLinkStart}secret management with GitLab%{docLinkEnd}"
+msgstr ""
+
msgid "Ensure connectivity is available from the GitLab server to the Prometheus server"
msgstr ""
@@ -13868,6 +14097,9 @@ 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 following to confirm:"
+msgstr ""
+
msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
@@ -14400,9 +14632,6 @@ 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 ""
@@ -14538,6 +14767,9 @@ msgstr ""
msgid "Errors:"
msgstr ""
+msgid "Escalate this incident"
+msgstr ""
+
msgid "Escalation Policies"
msgstr ""
@@ -14550,6 +14782,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy"
+msgstr ""
+
msgid "Escalation policy:"
msgstr ""
@@ -14803,6 +15038,9 @@ msgstr ""
msgid "Existing sign in methods may be removed"
msgstr ""
+msgid "Exit."
+msgstr ""
+
msgid "Expand"
msgstr ""
@@ -14899,6 +15137,9 @@ msgstr ""
msgid "Explore public groups"
msgstr ""
+msgid "Explore public projects"
+msgstr ""
+
msgid "Explore snippets"
msgstr ""
@@ -15062,7 +15303,7 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
-msgid "Failed to assign a reviewer because no user was found."
+msgid "Failed to assign a reviewer because no user was specified."
msgstr ""
msgid "Failed to assign a user because no user was found."
@@ -15128,10 +15369,10 @@ msgstr ""
msgid "Failed to find import label for Jira import."
msgstr ""
-msgid "Failed to generate export, please try again later."
+msgid "Failed to find users for %{missing}"
msgstr ""
-msgid "Failed to generate report, please try again after sometime"
+msgid "Failed to generate export, please try again later."
msgstr ""
msgid "Failed to get ref."
@@ -15230,6 +15471,9 @@ msgstr ""
msgid "Failed to remove a to-do item for the design."
msgstr ""
+msgid "Failed to remove attention because no user was found."
+msgstr ""
+
msgid "Failed to remove mirror."
msgstr ""
@@ -15242,6 +15486,9 @@ msgstr ""
msgid "Failed to remove user key."
msgstr ""
+msgid "Failed to request attention because no user was found."
+msgstr ""
+
msgid "Failed to reset key. Please try again."
msgstr ""
@@ -15323,6 +15570,9 @@ msgstr ""
msgid "Feature Flags"
msgstr ""
+msgid "Feature deprecation and removal"
+msgstr ""
+
msgid "Feature flag status"
msgstr ""
@@ -15822,7 +16072,7 @@ msgstr ""
msgid "For each job, re-use the project workspace. If the workspace doesn't exist, use %{code_open}git clone%{code_close}."
msgstr ""
-msgid "For example, the application using the token or the purpose of the token."
+msgid "For example, the application using the token or the purpose of the token. Do not give sensitive information for the name of the token, as it will be visible to all %{resource_type} members."
msgstr ""
msgid "For files larger than this limit, only index the file name. The file content is neither indexed nor searchable."
@@ -15906,9 +16156,6 @@ msgstr ""
msgid "ForkProject|Select a namespace"
msgstr ""
-msgid "ForkProject|Select a namespace to fork the project"
-msgstr ""
-
msgid "ForkProject|The project can be accessed by any logged in user."
msgstr ""
@@ -16005,6 +16252,9 @@ msgstr ""
msgid "Full name"
msgstr ""
+msgid "GCP region configured"
+msgstr ""
+
msgid "GPG Key ID:"
msgstr ""
@@ -16185,6 +16435,9 @@ msgstr ""
msgid "Geo|Failed"
msgstr ""
+msgid "Geo|Filter Geo sites"
+msgstr ""
+
msgid "Geo|Filter by name"
msgstr ""
@@ -16596,6 +16849,12 @@ msgstr ""
msgid "GitLab Issue"
msgstr ""
+msgid "GitLab KAS"
+msgstr ""
+
+msgid "GitLab Memberships CSV Export"
+msgstr ""
+
msgid "GitLab Pages"
msgstr ""
@@ -16644,6 +16903,9 @@ 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 free to use. Many features for larger teams are part of our %{link_start}paid products%{link_end}. You can try Ultimate for free without any obligation or payment details."
+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 ""
@@ -16770,7 +17032,7 @@ msgstr ""
msgid "GitLabPages|When enabled, all attempts to visit your website through HTTP are automatically redirected to HTTPS using a response with status code 301. Requires a valid certificate for all domains. %{docs_link_start}Learn more.%{link_end}"
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. %{docs_link_start}Learn more.%{link_end}"
+msgid "GitLabPages|When using Pages under the general domain of a GitLab instance (%{pages_host}), you cannot use HTTPS with subdomains of subdomains. If your namespace or groupname contains a dot, it does not work. This is a limitation of the HTTP Over TLS protocol. HTTP pages work if you don't redirect HTTP to HTTPS. %{docs_link_start}Learn more.%{link_end}"
msgstr ""
msgid "GitLabPages|With GitLab Pages you can host your static website directly from your GitLab repository. %{docs_link_start}Learn more.%{link_end}"
@@ -16947,9 +17209,6 @@ msgstr ""
msgid "Go to find file"
msgstr ""
-msgid "Go to fork"
-msgstr ""
-
msgid "Go to issue boards"
msgstr ""
@@ -17157,9 +17416,6 @@ msgstr ""
msgid "Group Hooks"
msgstr ""
-msgid "Group ID"
-msgstr ""
-
msgid "Group Owner must have signed in with SAML before enabling Group Managed Accounts"
msgstr ""
@@ -17187,9 +17443,6 @@ msgstr ""
msgid "Group by"
msgstr ""
-msgid "Group description"
-msgstr ""
-
msgid "Group description (optional)"
msgstr ""
@@ -17304,7 +17557,7 @@ msgstr ""
msgid "Group: %{name}"
msgstr ""
-msgid "GroupActivityMetrics|Issues opened"
+msgid "GroupActivityMetrics|Issues created"
msgstr ""
msgid "GroupActivityMetrics|Last 90 days"
@@ -17313,7 +17566,7 @@ msgstr ""
msgid "GroupActivityMetrics|Members added"
msgstr ""
-msgid "GroupActivityMetrics|Merge Requests opened"
+msgid "GroupActivityMetrics|Merge Requests created"
msgstr ""
msgid "GroupActivityMetrics|Recent activity"
@@ -17604,6 +17857,9 @@ msgstr ""
msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
+msgid "GroupSettings|Choose a group path that does not start with a dash or end with a period. It can also contain alphanumeric characters and underscores."
+msgstr ""
+
msgid "GroupSettings|Compliance frameworks"
msgstr ""
@@ -17637,7 +17893,7 @@ msgstr ""
msgid "GroupSettings|If not specified at the group or instance level, the default is %{default_initial_branch_name}. Does not affect existing repositories."
msgstr ""
-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."
+msgid "GroupSettings|If the parent group's visibility is lower than the group's current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility."
msgstr ""
msgid "GroupSettings|New runners registration token has been generated!"
@@ -17754,7 +18010,10 @@ msgstr ""
msgid "Groups and projects"
msgstr ""
-msgid "Groups and subgroups"
+msgid "Groups are a great way to organize projects and people."
+msgstr ""
+
+msgid "Groups are the best way to manage projects and members."
msgstr ""
msgid "Groups to synchronize"
@@ -17865,13 +18124,16 @@ msgstr ""
msgid "GroupsTree|Are you sure you want to leave the \"%{fullName}\" group?"
msgstr ""
-msgid "GroupsTree|Edit group"
+msgid "GroupsTree|Delete"
+msgstr ""
+
+msgid "GroupsTree|Edit"
msgstr ""
msgid "GroupsTree|Failed to leave the group. Please make sure you are not the only owner."
msgstr ""
-msgid "GroupsTree|Leave this group"
+msgid "GroupsTree|Leave group"
msgstr ""
msgid "GroupsTree|Loading groups"
@@ -17883,9 +18145,57 @@ msgstr ""
msgid "GroupsTree|No groups or projects matched your search"
msgstr ""
+msgid "GroupsTree|Options"
+msgstr ""
+
msgid "GroupsTree|Search by name"
msgstr ""
+msgid "Groups|Avatar will be removed. Are you sure?"
+msgstr ""
+
+msgid "Groups|Changing group URL can have unintended side effects."
+msgstr ""
+
+msgid "Groups|Checking group URL availability..."
+msgstr ""
+
+msgid "Groups|Enter a descriptive name for your group."
+msgstr ""
+
+msgid "Groups|Group ID"
+msgstr ""
+
+msgid "Groups|Group URL"
+msgstr ""
+
+msgid "Groups|Group avatar"
+msgstr ""
+
+msgid "Groups|Group description (optional)"
+msgstr ""
+
+msgid "Groups|Group name"
+msgstr ""
+
+msgid "Groups|Group path is available."
+msgstr ""
+
+msgid "Groups|Group path is unavailable. Path has been replaced with a suggested available path."
+msgstr ""
+
+msgid "Groups|Learn more"
+msgstr ""
+
+msgid "Groups|Must start with letter, digit, emoji, or underscore. Can also contain periods, dashes, spaces, and parentheses."
+msgstr ""
+
+msgid "Groups|Remove avatar"
+msgstr ""
+
+msgid "Groups|Save changes"
+msgstr ""
+
msgid "Guideline"
msgstr ""
@@ -17895,6 +18205,9 @@ msgstr ""
msgid "HAR file path or URL"
msgstr ""
+msgid "HTTP Archive (HAR)"
+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 ""
@@ -18299,6 +18612,9 @@ msgstr ""
msgid "INFO: Your SSH key is expiring soon. Please generate a new key."
msgstr ""
+msgid "IP"
+msgstr ""
+
msgid "IP Address"
msgstr ""
@@ -18335,6 +18651,9 @@ msgstr ""
msgid "IdentityVerification|Verify your identity"
msgstr ""
+msgid "IdentityVerification|You can always verify your account at a later time to create a group."
+msgstr ""
+
msgid "If any indexed field exceeds this limit, it is truncated to this number of characters. The rest of the content is neither indexed nor searchable. This does not apply to repository and wiki indexing. For unlimited characters, set this to 0."
msgstr ""
@@ -18392,6 +18711,9 @@ msgstr ""
msgid "If you add %{codeStart}needs%{codeEnd} to jobs in your pipeline you'll be able to view the %{codeStart}needs%{codeEnd} relationships between jobs in this tab as a %{linkStart}Directed Acyclic Graph (DAG)%{linkEnd}."
msgstr ""
+msgid "If you are added to a project, it will be displayed here."
+msgstr ""
+
msgid "If you did not initiate these sign-in attempts, please reach out to your administrator or enable two-factor authentication (2FA) on your account."
msgstr ""
@@ -18704,12 +19026,24 @@ msgstr ""
msgid "InProductMarketing|3 ways to dive into GitLab CI/CD"
msgstr ""
+msgid "InProductMarketing|A single application eliminates complex integrations, data chokepoints, and toolchain maintenance, resulting in greater productivity and lower cost."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features, build more efficiently, strengthen security and compliance."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features."
+msgstr ""
+
msgid "InProductMarketing|Actually, GitLab makes the team work (better)"
msgstr ""
msgid "InProductMarketing|And finally %{deploy_link} a Python application."
msgstr ""
+msgid "InProductMarketing|And many more..."
+msgstr ""
+
msgid "InProductMarketing|Are your runners ready?"
msgstr ""
@@ -18728,15 +19062,33 @@ msgstr ""
msgid "InProductMarketing|Blog"
msgstr ""
+msgid "InProductMarketing|Break down silos to coordinate seamlessly across development, operations, and security with a consistent experience across the development lifecycle."
+msgstr ""
+
+msgid "InProductMarketing|Burn up/down charts"
+msgstr ""
+
msgid "InProductMarketing|By enabling code owners and required merge approvals the right person will review the right MR. This is a win-win: cleaner code and a more efficient review process."
msgstr ""
msgid "InProductMarketing|Click on the number below that corresponds with your answer — 1 being very difficult, 5 being very easy."
msgstr ""
+msgid "InProductMarketing|Code owners"
+msgstr ""
+
msgid "InProductMarketing|Code owners and required merge approvals are part of the paid tiers of GitLab. You can start a free 30-day trial of GitLab Ultimate and enable these features in less than 5 minutes with no credit card required."
msgstr ""
+msgid "InProductMarketing|Code review analytics"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration across stages in GitLab"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration made easy"
+msgstr ""
+
msgid "InProductMarketing|Create a custom CI runner with just a few clicks"
msgstr ""
@@ -18746,12 +19098,21 @@ msgstr ""
msgid "InProductMarketing|Create a project in GitLab in 5 minutes"
msgstr ""
+msgid "InProductMarketing|Create well-defined workflows by using scoped labels on issues, merge requests, and epics. Labels with the same scope cannot be used together, which prevents conflicts."
+msgstr ""
+
msgid "InProductMarketing|Create your first project!"
msgstr ""
+msgid "InProductMarketing|Define who owns specific files or directories, so the right reviewers are suggested when a merge request introduces changes to those files."
+msgstr ""
+
msgid "InProductMarketing|Deliver Better Products Faster"
msgstr ""
+msgid "InProductMarketing|Dependency scanning"
+msgstr ""
+
msgid "InProductMarketing|Did you know teams that use GitLab are far more efficient?"
msgstr ""
@@ -18761,15 +19122,27 @@ msgstr ""
msgid "InProductMarketing|Dig in and create a project and a repo"
msgstr ""
+msgid "InProductMarketing|Discover Premium & Ultimate"
+msgstr ""
+
+msgid "InProductMarketing|Discover Premium & Ultimate."
+msgstr ""
+
msgid "InProductMarketing|Do you have a minute?"
msgstr ""
msgid "InProductMarketing|Do you have a teammate who would be perfect for this task?"
msgstr ""
+msgid "InProductMarketing|Dynamic application security testing"
+msgstr ""
+
msgid "InProductMarketing|Easy"
msgstr ""
+msgid "InProductMarketing|Epics"
+msgstr ""
+
msgid "InProductMarketing|Expand your DevOps journey with a free GitLab trial"
msgstr ""
@@ -18791,9 +19164,15 @@ msgstr ""
msgid "InProductMarketing|Feel the need for speed?"
msgstr ""
+msgid "InProductMarketing|Find and fix bottlenecks in your code review process by understanding how long open merge requests have been in review."
+msgstr ""
+
msgid "InProductMarketing|Find out how your teams are really doing"
msgstr ""
+msgid "InProductMarketing|Find out if your external libraries are safe. Run dependency scanning jobs that check for known vulnerabilities in your external libraries."
+msgstr ""
+
msgid "InProductMarketing|Follow our steps"
msgstr ""
@@ -18830,6 +19209,9 @@ msgstr ""
msgid "InProductMarketing|GitLab is better with teammates to help out!"
msgstr ""
+msgid "InProductMarketing|GitLab is infrastructure agnostic (supporting GCP, AWS, Azure, OpenShift, VMWare, On Prem, Bare Metal, and more), offering a consistent workflow experience – irrespective of the environment."
+msgstr ""
+
msgid "InProductMarketing|GitLab provides static application security testing (SAST), dynamic application security testing (DAST), container scanning, and dependency scanning to help you deliver secure applications along with license compliance."
msgstr ""
@@ -18920,21 +19302,36 @@ msgstr ""
msgid "InProductMarketing|It's also possible to simply %{external_repo_link} in order to take advantage of GitLab's CI/CD."
msgstr ""
+msgid "InProductMarketing|Keep your code quality high by defining who should approve merge requests and how many approvals are required."
+msgstr ""
+
msgid "InProductMarketing|Launch GitLab CI/CD in 20 minutes or less"
msgstr ""
+msgid "InProductMarketing|Lower cost of development"
+msgstr ""
+
+msgid "InProductMarketing|Make it easier to collaborate on high-level ideas by grouping related issues in an epic."
+msgstr ""
+
msgid "InProductMarketing|Making the switch? It's easier than you think to import your projects into GitLab. Move %{github_link}, or import something %{bitbucket_link}."
msgstr ""
msgid "InProductMarketing|Master the art of importing!"
msgstr ""
+msgid "InProductMarketing|Merge request approval rule"
+msgstr ""
+
msgid "InProductMarketing|Move on to easily creating a Pages website %{ci_template_link}"
msgstr ""
msgid "InProductMarketing|Multiple owners, confusing workstreams? We've got you covered"
msgstr ""
+msgid "InProductMarketing|Multiple required approvers"
+msgstr ""
+
msgid "InProductMarketing|Need an alternative to importing?"
msgstr ""
@@ -18947,18 +19344,33 @@ msgstr ""
msgid "InProductMarketing|Our tool brings all the things together"
msgstr ""
+msgid "InProductMarketing|Protect your web application by using DAST to examine for vulnerabilities in deployed environments."
+msgstr ""
+
msgid "InProductMarketing|Rapid development, simplified"
msgstr ""
msgid "InProductMarketing|Reduce Security & Compliance Risk"
msgstr ""
+msgid "InProductMarketing|Require multiple approvers on a merge request, so you know it's in good shape before it's merged."
+msgstr ""
+
+msgid "InProductMarketing|Roadmaps"
+msgstr ""
+
+msgid "InProductMarketing|Scoped labels"
+msgstr ""
+
msgid "InProductMarketing|Security that's integrated into your development lifecycle"
msgstr ""
msgid "InProductMarketing|Sometimes you're not ready to make a full transition to a new tool. If you're not ready to fully commit, %{mirroring_link} gives you a safe way to try out GitLab in parallel with your current tool."
msgstr ""
+msgid "InProductMarketing|Speed. Efficiency. Trust."
+msgstr ""
+
msgid "InProductMarketing|Spin up an autoscaling runner in GitLab"
msgstr ""
@@ -18968,6 +19380,9 @@ msgstr ""
msgid "InProductMarketing|Start a Self-Managed trial"
msgstr ""
+msgid "InProductMarketing|Start a free trial"
+msgstr ""
+
msgid "InProductMarketing|Start a free trial of GitLab Ultimate – no credit card required"
msgstr ""
@@ -19034,6 +19449,9 @@ msgstr ""
msgid "InProductMarketing|To understand and get the most out of GitLab, start at the beginning and %{project_link}. In GitLab, repositories are part of a project, so after you've created your project you can go ahead and %{repo_link}."
msgstr ""
+msgid "InProductMarketing|Track completed issues in a chart, so you can see how a milestone is progressing at a glance."
+msgstr ""
+
msgid "InProductMarketing|Try GitLab Ultimate for free"
msgstr ""
@@ -19070,6 +19488,9 @@ msgstr ""
msgid "InProductMarketing|Very easy"
msgstr ""
+msgid "InProductMarketing|Visualize your epics and milestones in a timeline."
+msgstr ""
+
msgid "InProductMarketing|Want to host GitLab on your servers?"
msgstr ""
@@ -19091,6 +19512,9 @@ msgstr ""
msgid "InProductMarketing|YouTube"
msgstr ""
+msgid "InProductMarketing|Your software, deployed your way"
+msgstr ""
+
msgid "InProductMarketing|Your teams can be more efficient"
msgstr ""
@@ -19211,9 +19635,18 @@ msgstr ""
msgid "IncidentManagement|No incidents to display."
msgstr ""
+msgid "IncidentManagement|None"
+msgstr ""
+
msgid "IncidentManagement|Open"
msgstr ""
+msgid "IncidentManagement|Page your team with escalation policies"
+msgstr ""
+
+msgid "IncidentManagement|Paged"
+msgstr ""
+
msgid "IncidentManagement|Published"
msgstr ""
@@ -19223,6 +19656,9 @@ msgstr ""
msgid "IncidentManagement|Severity"
msgstr ""
+msgid "IncidentManagement|Status"
+msgstr ""
+
msgid "IncidentManagement|There are no closed incidents"
msgstr ""
@@ -19241,6 +19677,9 @@ msgstr ""
msgid "IncidentManagement|Unpublished"
msgstr ""
+msgid "IncidentManagement|Use escalation policies to automatically page your team when incidents are created."
+msgstr ""
+
msgid "IncidentSettings|Activate \"time to SLA\" countdown timer"
msgstr ""
@@ -19286,7 +19725,10 @@ msgstr ""
msgid "Incidents"
msgstr ""
-msgid "Incidents|Add a URL"
+msgid "Incidents|Add image details"
+msgstr ""
+
+msgid "Incidents|Add text or a link to display with your image. If you don't add either, the file name displays instead."
msgstr ""
msgid "Incidents|Drop or %{linkStart}upload%{linkEnd} a metric screenshot to attach it to the incident"
@@ -19301,10 +19743,10 @@ msgstr ""
msgid "Incidents|There was an issue loading metric images."
msgstr ""
-msgid "Incidents|There was an issue uploading your image."
+msgid "Incidents|There was an issue updating your image."
msgstr ""
-msgid "Incidents|You can optionally add a URL to link users to the original graph."
+msgid "Incidents|There was an issue uploading your image."
msgstr ""
msgid "Incident|Alert details"
@@ -19313,9 +19755,18 @@ msgstr ""
msgid "Incident|Are you sure you wish to delete this image?"
msgstr ""
+msgid "Incident|Delete image"
+msgstr ""
+
msgid "Incident|Deleting %{filename}"
msgstr ""
+msgid "Incident|Edit image text or link"
+msgstr ""
+
+msgid "Incident|Editing %{filename}"
+msgstr ""
+
msgid "Incident|Metrics"
msgstr ""
@@ -19587,12 +20038,18 @@ msgstr ""
msgid "Integrations|Branches for which notifications are to be sent"
msgstr ""
+msgid "Integrations|Clear if using a self-signed certificate."
+msgstr ""
+
msgid "Integrations|Comment detail:"
msgstr ""
msgid "Integrations|Comment settings:"
msgstr ""
+msgid "Integrations|Connection details"
+msgstr ""
+
msgid "Integrations|Connection failed. Please check your settings."
msgstr ""
@@ -19617,6 +20074,9 @@ msgstr ""
msgid "Integrations|Enable GitLab.com slash commands in a Slack workspace."
msgstr ""
+msgid "Integrations|Enable SSL verification"
+msgstr ""
+
msgid "Integrations|Enable comments"
msgstr ""
@@ -19695,6 +20155,9 @@ msgstr ""
msgid "Integrations|Return to GitLab for Jira"
msgstr ""
+msgid "Integrations|SSL verification"
+msgstr ""
+
msgid "Integrations|Save settings?"
msgstr ""
@@ -19740,9 +20203,6 @@ msgstr ""
msgid "Integrations|Use default settings"
msgstr ""
-msgid "Integrations|When you mention a Jira issue in a commit or merge request, GitLab creates a remote link and comment (if enabled)."
-msgstr ""
-
msgid "Integrations|You can now close this window and return to the GitLab for Jira application."
msgstr ""
@@ -19767,9 +20227,6 @@ msgstr ""
msgid "Integrations|can't exceed %{recipients_limit}"
msgstr ""
-msgid "Interactive developer security education."
-msgstr ""
-
msgid "Interactive mode"
msgstr ""
@@ -20259,6 +20716,9 @@ msgstr ""
msgid "IssueAnalytics|Assignees"
msgstr ""
+msgid "IssueAnalytics|Created by"
+msgstr ""
+
msgid "IssueAnalytics|Due date"
msgstr ""
@@ -20271,9 +20731,6 @@ msgstr ""
msgid "IssueAnalytics|Milestone"
msgstr ""
-msgid "IssueAnalytics|Opened by"
-msgstr ""
-
msgid "IssueAnalytics|Status"
msgstr ""
@@ -20397,10 +20854,10 @@ msgstr ""
msgid "IssuesAnalytics|Avg/Month:"
msgstr ""
-msgid "IssuesAnalytics|Issues opened"
+msgid "IssuesAnalytics|Issues created"
msgstr ""
-msgid "IssuesAnalytics|Issues opened per month"
+msgid "IssuesAnalytics|Issues created per month"
msgstr ""
msgid "IssuesAnalytics|Last 12 months"
@@ -20427,6 +20884,9 @@ msgstr ""
msgid "It looks like you have some draft commits in this branch."
msgstr ""
+msgid "It looks like you're attempting to activate your subscription. Use %{a_start}the Subscription page%{a_end} instead."
+msgstr ""
+
msgid "It may be several days before you see feature usage data."
msgstr ""
@@ -20655,6 +21115,9 @@ msgstr ""
msgid "JiraConnect|You can now close this window and return to Jira."
msgstr ""
+msgid "JiraConnect|You don't have permission to create branches for this project. Select a different project or contact the project owner for access. %{linkStart}Learn more.%{linkEnd}"
+msgstr ""
+
msgid "JiraRequest|A connection error occurred while connecting to Jira. Try your request again."
msgstr ""
@@ -20703,13 +21166,13 @@ msgstr ""
msgid "JiraService|Define the type of Jira issue to create from a vulnerability."
msgstr ""
-msgid "JiraService|Displaying Jira issues while leaving the GitLab issue functionality enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
+msgid "JiraService|Displaying Jira issues while leaving GitLab issues also enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
msgstr ""
-msgid "JiraService|Enable Jira issues"
+msgid "JiraService|Enable Jira issue creation from vulnerabilities"
msgstr ""
-msgid "JiraService|Enable Jira issues creation from vulnerabilities"
+msgid "JiraService|Enable Jira issues"
msgstr ""
msgid "JiraService|Enable Jira transitions"
@@ -20826,16 +21289,19 @@ msgstr ""
msgid "JiraService|View Jira issues in GitLab"
msgstr ""
-msgid "JiraService|Warning: All GitLab users that have access to this GitLab project are able to view all issues from the Jira project specified below."
+msgid "JiraService|Warning: All GitLab users with access to this GitLab project can view all issues from the Jira project you select."
msgstr ""
msgid "JiraService|Web URL"
msgstr ""
-msgid "JiraService|Work on Jira issues without leaving GitLab. Adds a Jira menu to access your list of Jira issues and view any issue as read-only."
+msgid "JiraService|When a Jira issue is mentioned in a commit or merge request, a remote link and comment (if enabled) will be created."
+msgstr ""
+
+msgid "JiraService|Work on Jira issues without leaving GitLab. Add a Jira menu to access a read-only list of your Jira issues."
msgstr ""
-msgid "JiraService|You need to configure Jira before enabling this integration. For more details, read the %{jira_doc_link_start}Jira integration documentation%{link_end}."
+msgid "JiraService|You must configure Jira before enabling this integration. %{jira_doc_link_start}Learn more.%{link_end}"
msgstr ""
msgid "Job"
@@ -20847,9 +21313,6 @@ msgstr ""
msgid "Job Failed #%{build_id}"
msgstr ""
-msgid "Job ID"
-msgstr ""
-
msgid "Job artifact"
msgstr ""
@@ -20916,9 +21379,27 @@ msgstr ""
msgid "Jobs|You're about to retry a job that failed because it attempted to deploy code that is older than the latest deployment. Retrying this job could result in overwriting the environment with the older source code."
msgstr ""
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source} into %{target}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{ref}"
+msgstr ""
+
+msgid "Job|Are you sure you want to erase this job log and artifacts?"
+msgstr ""
+
msgid "Job|Browse"
msgstr ""
+msgid "Job|Cancel"
+msgstr ""
+
msgid "Job|Complete Raw"
msgstr ""
@@ -20928,6 +21409,9 @@ msgstr ""
msgid "Job|Erase job log and artifacts"
msgstr ""
+msgid "Job|Finished at"
+msgstr ""
+
msgid "Job|Job artifacts"
msgstr ""
@@ -20940,7 +21424,7 @@ msgstr ""
msgid "Job|Keep"
msgstr ""
-msgid "Job|Pipeline"
+msgid "Job|Retry"
msgstr ""
msgid "Job|Scroll to bottom"
@@ -20952,6 +21436,9 @@ msgstr ""
msgid "Job|Show complete raw"
msgstr ""
+msgid "Job|Status"
+msgstr ""
+
msgid "Job|The artifacts were removed"
msgstr ""
@@ -20979,21 +21466,12 @@ msgstr ""
msgid "Job|delayed"
msgstr ""
-msgid "Job|for"
-msgstr ""
-
-msgid "Job|into"
-msgstr ""
-
msgid "Job|manual"
msgstr ""
msgid "Job|triggered"
msgstr ""
-msgid "Job|with"
-msgstr ""
-
msgid "Join Zoom meeting"
msgstr ""
@@ -21096,9 +21574,6 @@ msgstr ""
msgid "Ki"
msgstr ""
-msgid "Kontra"
-msgstr ""
-
msgid "Kroki"
msgstr ""
@@ -21424,6 +21899,9 @@ msgstr ""
msgid "Learn more about Auto DevOps"
msgstr ""
+msgid "Learn more about GitLab"
+msgstr ""
+
msgid "Learn more about Needs relationships"
msgstr ""
@@ -21763,9 +22241,18 @@ msgstr ""
msgid "Licenses|Displays licenses detected in the project, based on the %{linkStart}latest successful%{linkEnd} scan"
msgstr ""
+msgid "Licenses|Drag your license file here or %{linkStart}click to upload%{linkEnd}."
+msgstr ""
+
+msgid "Licenses|Drop your license file to start the upload."
+msgstr ""
+
msgid "Licenses|Error fetching the license list. Please check your network connection and try again."
msgstr ""
+msgid "Licenses|Error: You are trying to upload something other than a file"
+msgstr ""
+
msgid "Licenses|License Compliance"
msgstr ""
@@ -21784,6 +22271,9 @@ msgstr ""
msgid "Licenses|Specified policies in this project"
msgstr ""
+msgid "Licenses|The file could not be uploaded."
+msgstr ""
+
msgid "Licenses|The license list details information about the licenses used within your project."
msgstr ""
@@ -21817,13 +22307,6 @@ msgstr ""
msgid "Limit the size of Sidekiq jobs stored in Redis."
msgstr ""
-msgid "Limited to showing %d event at most"
-msgid_plural "Limited to showing %d events at most"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-msgstr[3] ""
-
msgid "Limiting mode"
msgstr ""
@@ -21833,6 +22316,9 @@ msgstr ""
msgid "Link"
msgstr ""
+msgid "Link (optional)"
+msgstr ""
+
msgid "Link Prometheus monitoring to GitLab."
msgstr ""
@@ -21869,6 +22355,9 @@ msgstr ""
msgid "Linked emails (%{email_count})"
msgstr ""
+msgid "Linked epics"
+msgstr ""
+
msgid "Linked issues"
msgstr ""
@@ -21896,6 +22385,15 @@ msgstr ""
msgid "List of all merge commits"
msgstr ""
+msgid "List of environments for this project"
+msgstr ""
+
+msgid "List of suitable GCP locations"
+msgstr ""
+
+msgid "List of users allowed to exceed the rate limit."
+msgstr ""
+
msgid "List options"
msgstr ""
@@ -22115,6 +22613,9 @@ msgstr ""
msgid "Maintenance mode"
msgstr ""
+msgid "Make adjustments to how your GitLab instance is set up."
+msgstr ""
+
msgid "Make and review changes in the browser with the Web IDE"
msgstr ""
@@ -22259,6 +22760,12 @@ msgstr ""
msgid "MarkdownEditor|Add italic text (%{modifier_key}I)"
msgstr ""
+msgid "MarkdownEditor|Add strikethrough text (%{modifierKey}⇧X)"
+msgstr ""
+
+msgid "MarkdownEditor|Add strikethrough text (%{modifier_key}⇧X)"
+msgstr ""
+
msgid "Marked For Deletion At - %{deletion_time}"
msgstr ""
@@ -22520,6 +23027,9 @@ msgstr ""
msgid "Maximum push size (MB)"
msgstr ""
+msgid "Maximum requests per 10 minutes per user"
+msgstr ""
+
msgid "Maximum requests per minute"
msgstr ""
@@ -22610,6 +23120,23 @@ msgstr ""
msgid "Members of a group may only view projects they have permission to access"
msgstr ""
+msgid "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seat in use and will be billed for the overage."
+msgid_plural "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seats in use and will be billed for the overage."
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
+msgid "MembersOverage|You are about to incur additional charges"
+msgstr ""
+
+msgid "MembersOverage|Your subscription includes %d seat."
+msgid_plural "MembersOverage|Your subscription includes %d seats."
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "Membership"
msgstr ""
@@ -22814,9 +23341,6 @@ msgstr ""
msgid "Merge request not merged"
msgstr ""
-msgid "Merge request pipelines 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 merge request pipelines."
-msgstr ""
-
msgid "Merge request reports"
msgstr ""
@@ -22913,13 +23437,13 @@ msgstr ""
msgid "MergeRequests|Create issue to resolve thread"
msgstr ""
-msgid "MergeRequests|Failed to squash. Should be done manually."
+msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Saving the comment failed"
+msgid "MergeRequests|Squashing failed: Squash the commits locally, resolve any conflicts, then push the branch."
msgstr ""
-msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
+msgid "MergeRequests|Squashing not allowed: This project doesn't allow you to squash commits when merging."
msgstr ""
msgid "MergeRequests|Thread stays resolved"
@@ -23764,6 +24288,18 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "MrList|Assigned to %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from assignee %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from reviewer %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Review requested from %{name}, go to their profile."
+msgstr ""
+
msgid "Multi-project"
msgstr ""
@@ -23797,7 +24333,7 @@ msgstr ""
msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "My Awesome Group"
+msgid "My awesome group"
msgstr ""
msgid "My company or team"
@@ -24423,9 +24959,6 @@ msgstr ""
msgid "No available branches"
msgstr ""
-msgid "No available groups to fork the project."
-msgstr ""
-
msgid "No branches found"
msgstr ""
@@ -24636,6 +25169,9 @@ msgstr ""
msgid "No ref selected"
msgstr ""
+msgid "No regions configured"
+msgstr ""
+
msgid "No related merge requests found."
msgstr ""
@@ -25452,6 +25988,9 @@ msgstr ""
msgid "Only reCAPTCHA v2 is supported:"
msgstr ""
+msgid "Only required if not using role instance credentials."
+msgstr ""
+
msgid "Only use lowercase letters, numbers, and underscores."
msgstr ""
@@ -25476,9 +26015,6 @@ msgstr ""
msgid "Open a CLI and connect to the cluster you want to install the agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
-msgid "Open epics"
-msgstr ""
-
msgid "Open errors"
msgstr ""
@@ -25518,7 +26054,7 @@ msgstr ""
msgid "Opened issues"
msgstr ""
-msgid "OpenedNDaysAgo|Opened"
+msgid "OpenedNDaysAgo|Created"
msgstr ""
msgid "Opens in a new window"
@@ -25563,9 +26099,6 @@ msgstr ""
msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
-msgid "Optional."
-msgstr ""
-
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
msgstr ""
@@ -26356,6 +26889,9 @@ msgstr ""
msgid "PerformanceBar|Memory"
msgstr ""
+msgid "PerformanceBar|Memory report"
+msgstr ""
+
msgid "PerformanceBar|Redis calls"
msgstr ""
@@ -26389,18 +26925,12 @@ msgstr ""
msgid "PerformanceBar|wall"
msgstr ""
-msgid "Performs a rebase but skips triggering a new pipeline"
-msgstr ""
-
msgid "Period in seconds"
msgstr ""
msgid "Permalink"
msgstr ""
-msgid "Permanently delete project"
-msgstr ""
-
msgid "Permanently remove group"
msgstr ""
@@ -26671,6 +27201,51 @@ msgstr ""
msgid "PipelineStatusTooltip|Pipeline: %{ci_status}"
msgstr ""
+msgid "PipelineWizardDefaultCommitMessage|Add %{filename}"
+msgstr ""
+
+msgid "PipelineWizardDefaultCommitMessage|Update %{filename}"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|At least one entry is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This field is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This value is not valid"
+msgstr ""
+
+msgid "PipelineWizardListWidget|add another step"
+msgstr ""
+
+msgid "PipelineWizardListWidget|remove step"
+msgstr ""
+
+msgid "PipelineWizard|Commit"
+msgstr ""
+
+msgid "PipelineWizard|Commit Message"
+msgstr ""
+
+msgid "PipelineWizard|Commit changes to your file"
+msgstr ""
+
+msgid "PipelineWizard|Commit file to Branch"
+msgstr ""
+
+msgid "PipelineWizard|Commit your new file"
+msgstr ""
+
+msgid "PipelineWizard|The file has been committed."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem committing the changes."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem while checking whether your file already exists in the specified branch."
+msgstr ""
+
msgid "Pipelines"
msgstr ""
@@ -26785,7 +27360,7 @@ msgstr ""
msgid "Pipelines|Project cache successfully reset."
msgstr ""
-msgid "Pipelines|Revoke"
+msgid "Pipelines|Revoke trigger"
msgstr ""
msgid "Pipelines|Something went wrong while cleaning runners cache."
@@ -26830,6 +27405,12 @@ msgstr ""
msgid "Pipelines|This is a child pipeline within the parent pipeline"
msgstr ""
+msgid "Pipelines|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipelines|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipelines|This pipeline will run code originating from a forked project merge request. This means that the code can potentially have security considerations like exposing CI variables."
msgstr ""
@@ -26872,9 +27453,6 @@ msgstr ""
msgid "Pipelines|Your changes have been successfully committed. Now redirecting to the new merge request page."
msgstr ""
-msgid "Pipelines|detached"
-msgstr ""
-
msgid "Pipelines|error"
msgstr ""
@@ -26884,10 +27462,13 @@ msgstr ""
msgid "Pipelines|latest"
msgstr ""
-msgid "Pipelines|stuck"
+msgid "Pipelines|merge request"
msgstr ""
-msgid "Pipelines|train"
+msgid "Pipelines|merge train"
+msgstr ""
+
+msgid "Pipelines|stuck"
msgstr ""
msgid "Pipelines|yaml invalid"
@@ -27019,6 +27600,12 @@ msgstr ""
msgid "Pipeline|This change will not change the overall test coverage if merged."
msgstr ""
+msgid "Pipeline|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipeline|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipeline|Trigger author"
msgstr ""
@@ -27043,6 +27630,12 @@ msgstr ""
msgid "Pipeline|for"
msgstr ""
+msgid "Pipeline|merge request"
+msgstr ""
+
+msgid "Pipeline|merge train"
+msgstr ""
+
msgid "Pipeline|on"
msgstr ""
@@ -27181,9 +27774,6 @@ msgstr ""
msgid "Please enter a valid time interval"
msgstr ""
-msgid "Please enter or upload a valid license."
-msgstr ""
-
msgid "Please enter your current password."
msgstr ""
@@ -27292,9 +27882,6 @@ msgstr ""
msgid "Please type %{phrase_code} to proceed or close this modal to cancel."
msgstr ""
-msgid "Please type the following to confirm:"
-msgstr ""
-
msgid "Please use this form to report to the admin users who create spam issues, comments or behave inappropriately."
msgstr ""
@@ -27322,12 +27909,27 @@ msgstr ""
msgid "Policies"
msgstr ""
+msgid "Policy '%{escalation_policy_name}' does not exist."
+msgstr ""
+
msgid "Policy management project does have any policies in %{policy_path}"
msgstr ""
msgid "Policy project doesn't exist"
msgstr ""
+msgid "PolicyRuleMultiSelect|%{firstLabel} +%{numberOfAdditionalLabels} more"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|All %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select all"
+msgstr ""
+
msgid "Polling interval multiplier"
msgstr ""
@@ -27556,6 +28158,9 @@ msgstr ""
msgid "Private projects can be created in your personal namespace with:"
msgstr ""
+msgid "Problem with %{name} command: %{message}."
+msgstr ""
+
msgid "Proceed"
msgstr ""
@@ -28030,6 +28635,9 @@ msgstr ""
msgid "Progress"
msgstr ""
+msgid "Progress tracking"
+msgstr ""
+
msgid "Project"
msgstr ""
@@ -28261,6 +28869,9 @@ msgstr ""
msgid "ProjectQualitySummary|Failure"
msgstr ""
+msgid "ProjectQualitySummary|Get insight into the overall percentage of tests in your project that succeed, fail and are skipped."
+msgstr ""
+
msgid "ProjectQualitySummary|Latest pipeline results"
msgstr ""
@@ -28279,6 +28890,12 @@ msgstr ""
msgid "ProjectQualitySummary|See project Code Coverage Statistics"
msgstr ""
+msgid "ProjectQualitySummary|Set up test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|Set up test runs (opens in a new tab)"
+msgstr ""
+
msgid "ProjectQualitySummary|Skipped"
msgstr ""
@@ -28555,13 +29172,19 @@ msgstr ""
msgid "ProjectSettings|LFS objects from this repository are available to forks. %{linkStart}How do I remove them?%{linkEnd}"
msgstr ""
+msgid "ProjectSettings|Learn about commit history."
+msgstr ""
+
+msgid "ProjectSettings|Leave empty to use default template."
+msgstr ""
+
msgid "ProjectSettings|Manage who can see the project in the public access directory."
msgstr ""
msgid "ProjectSettings|Manages large files such as audio, video, and graphics files."
msgstr ""
-msgid "ProjectSettings|Maximum 500 characters."
+msgid "ProjectSettings|Maximum %{maxLength} characters."
msgstr ""
msgid "ProjectSettings|Merge checks"
@@ -28702,6 +29325,9 @@ msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
msgstr ""
+msgid "ProjectSettings|The default template will be applied on save."
+msgstr ""
+
msgid "ProjectSettings|These checks must pass before merge requests can be merged."
msgstr ""
@@ -28756,6 +29382,9 @@ msgstr ""
msgid "ProjectSettings|What are badges?"
msgstr ""
+msgid "ProjectSettings|What are merge trains?"
+msgstr ""
+
msgid "ProjectSettings|When merge request pipelines are enabled in the CI/CD configuration file, pipelines validate the combined results of the source and target branches. %{link_start}How to configure merge request pipelines?%{link_end}"
msgstr ""
@@ -28873,6 +29502,9 @@ msgstr ""
msgid "Projects are organized into groups"
msgstr ""
+msgid "Projects are where you store your code, access issues, wiki and other features of GitLab."
+msgstr ""
+
msgid "Projects contributed to"
msgstr ""
@@ -28888,12 +29520,6 @@ msgstr ""
msgid "Projects to index"
msgstr ""
-msgid "Projects will be permanently deleted after a %{waiting_period}-day waiting period."
-msgstr ""
-
-msgid "Projects will be permanently deleted immediately."
-msgstr ""
-
msgid "Projects with critical vulnerabilities"
msgstr ""
@@ -28978,6 +29604,9 @@ msgstr ""
msgid "ProjectsNew|Import project"
msgstr ""
+msgid "ProjectsNew|Include a Getting Started README"
+msgstr ""
+
msgid "ProjectsNew|Initialize repository with a README"
msgstr ""
@@ -28993,6 +29622,9 @@ msgstr ""
msgid "ProjectsNew|Project description %{tag_start}(optional)%{tag_end}"
msgstr ""
+msgid "ProjectsNew|Recommended if you're new to GitLab"
+msgstr ""
+
msgid "ProjectsNew|Run CI/CD for external repository"
msgstr ""
@@ -29410,6 +30042,9 @@ msgstr ""
msgid "ProtectedBranch|Unprotect"
msgstr ""
+msgid "ProtectedBranch|Unprotect branch"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
@@ -29437,6 +30072,9 @@ msgstr ""
msgid "ProtectedEnvironment|Protected Environment (%{protected_environments_count})"
msgstr ""
+msgid "ProtectedEnvironment|Required approvals"
+msgstr ""
+
msgid "ProtectedEnvironment|Select an environment"
msgstr ""
@@ -29458,10 +30096,13 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|Unprotect tag"
+msgstr ""
+
msgid "ProtectedTags|default"
msgstr ""
-msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
+msgid "ProtectedTag|By default, protected tags restrict who can modify the tag."
msgstr ""
msgid "ProtectedTag|Learn more."
@@ -29524,6 +30165,9 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Public projects are an easy way to allow everyone to have read-only access."
+msgstr ""
+
msgid "Publish to status page"
msgstr ""
@@ -29680,9 +30324,6 @@ msgstr ""
msgid "QualitySummary|Project quality"
msgstr ""
-msgid "Quarters"
-msgstr ""
-
msgid "Query"
msgstr ""
@@ -29767,6 +30408,9 @@ msgstr ""
msgid "Read more about project permissions %{help_link_open}here%{help_link_close}"
msgstr ""
+msgid "Read more about related epics"
+msgstr ""
+
msgid "Read more about related issues"
msgstr ""
@@ -29797,10 +30441,7 @@ msgstr ""
msgid "Rebase source branch on the target branch."
msgstr ""
-msgid "Rebase without CI"
-msgstr ""
-
-msgid "Rebases and triggers a pipeline"
+msgid "Rebase without pipeline"
msgstr ""
msgid "Recaptcha verified?"
@@ -29851,9 +30492,6 @@ msgstr ""
msgid "Reconfigure"
msgstr ""
-msgid "Recovering projects"
-msgstr ""
-
msgid "Recovery Codes"
msgstr ""
@@ -29915,6 +30553,12 @@ msgstr ""
msgid "Regex pattern"
msgstr ""
+msgid "Region"
+msgstr ""
+
+msgid "Regions"
+msgstr ""
+
msgid "Register"
msgstr ""
@@ -30147,9 +30791,6 @@ msgstr ""
msgid "Remove all or specific reviewer(s)"
msgstr ""
-msgid "Remove approver"
-msgstr ""
-
msgid "Remove approvers"
msgstr ""
@@ -30165,6 +30806,9 @@ msgstr ""
msgid "Remove attention request"
msgstr ""
+msgid "Remove attention request(s)"
+msgstr ""
+
msgid "Remove avatar"
msgstr ""
@@ -30303,6 +30947,9 @@ msgstr ""
msgid "Removed an issue from an epic."
msgstr ""
+msgid "Removed attention from %{users_sentence}."
+msgstr ""
+
msgid "Removed attention request from @%{username}"
msgstr ""
@@ -30354,6 +31001,9 @@ msgstr ""
msgid "Removes an issue from an epic."
msgstr ""
+msgid "Removes attention from %{users_sentence}."
+msgstr ""
+
msgid "Removes parent epic %{epic_ref}."
msgstr ""
@@ -30465,6 +31115,9 @@ msgstr ""
msgid "Report abuse to admin"
msgstr ""
+msgid "Report is generating and will be sent to your email address."
+msgstr ""
+
msgid "Reported %{timeAgo} by %{reportedBy}"
msgstr ""
@@ -30764,6 +31417,15 @@ msgstr ""
msgid "Request attention"
msgstr ""
+msgid "Request attention from %{users_sentence}."
+msgstr ""
+
+msgid "Request attention from assignee or reviewer"
+msgstr ""
+
+msgid "Request attention from assignee(s) or reviewer(s)"
+msgstr ""
+
msgid "Request attention to review"
msgstr ""
@@ -30788,6 +31450,9 @@ msgstr ""
msgid "Requested %{time_ago}"
msgstr ""
+msgid "Requested attention from %{users_sentence}."
+msgstr ""
+
msgid "Requested attention from @%{username}"
msgstr ""
@@ -31006,6 +31671,9 @@ msgstr ""
msgid "Restore project"
msgstr ""
+msgid "Restoring projects"
+msgstr ""
+
msgid "Restoring the group will prevent the group, its subgroups and projects from being removed on this date."
msgstr ""
@@ -31036,6 +31704,9 @@ msgstr ""
msgid "Retry"
msgstr ""
+msgid "Retry failed jobs"
+msgstr ""
+
msgid "Retry job"
msgstr ""
@@ -31085,9 +31756,6 @@ msgstr ""
msgid "Review changes"
msgstr ""
-msgid "Review requested from %{name}"
-msgstr ""
-
msgid "Review requests for you"
msgstr ""
@@ -31254,6 +31922,9 @@ msgstr ""
msgid "Runners|Assigned Group"
msgstr ""
+msgid "Runners|Assigned Projects (%{projectCount})"
+msgstr ""
+
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -31323,6 +31994,9 @@ msgstr ""
msgid "Runners|Instance"
msgstr ""
+msgid "Runners|Jobs"
+msgstr ""
+
msgid "Runners|Last contact"
msgstr ""
@@ -31416,9 +32090,6 @@ msgstr ""
msgid "Runners|Runner %{name} was deleted"
msgstr ""
-msgid "Runners|Runner ID"
-msgstr ""
-
msgid "Runners|Runner assigned to project."
msgstr ""
@@ -31566,6 +32237,9 @@ msgstr ""
msgid "Runners|stale"
msgstr ""
+msgid "Runner|This runner has not run any jobs."
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -31680,6 +32354,24 @@ msgstr ""
msgid "Saving project."
msgstr ""
+msgid "ScanResultPolicy|%{ifLabelStart}if%{ifLabelEnd} %{scanners} scan in an open merge request targeting the %{branches} branch(es) finds %{vulnerabilitiesAllowed} or more %{severities} vulnerabilities that are %{vulnerabilityStates}"
+msgstr ""
+
+msgid "ScanResultPolicy|%{thenLabelStart}Then%{thenLabelEnd} Require approval from %{approvalsRequired} of the following approvers: %{approvers}"
+msgstr ""
+
+msgid "ScanResultPolicy|add an approver"
+msgstr ""
+
+msgid "ScanResultPolicy|scanners"
+msgstr ""
+
+msgid "ScanResultPolicy|severity levels"
+msgstr ""
+
+msgid "ScanResultPolicy|vulnerability states"
+msgstr ""
+
msgid "Scanner"
msgstr ""
@@ -31812,6 +32504,9 @@ msgstr ""
msgid "Search for a user"
msgstr ""
+msgid "Search for an emoji"
+msgstr ""
+
msgid "Search for projects, issues, etc."
msgstr ""
@@ -32021,18 +32716,12 @@ msgstr ""
msgid "Secret Detection"
msgstr ""
-msgid "Secret access key"
-msgstr ""
-
msgid "Secret token"
msgstr ""
msgid "Secure token that identifies an external storage request."
msgstr ""
-msgid "SecureCodeWarrior"
-msgstr ""
-
msgid "Security"
msgstr ""
@@ -32057,9 +32746,6 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "Security training with guide and learning pathways."
-msgstr ""
-
msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
@@ -32162,7 +32848,7 @@ msgstr ""
msgid "SecurityConfiguration|Manage corpus"
msgstr ""
-msgid "SecurityConfiguration|Manage corpus files used as mutation sources in coverage fuzzing."
+msgid "SecurityConfiguration|Manage corpus files used as seed inputs with coverage-guided fuzzing."
msgstr ""
msgid "SecurityConfiguration|Manage profiles for use by DAST scans."
@@ -32228,15 +32914,15 @@ msgstr ""
msgid "SecurityOrchestration|.yaml preview"
msgstr ""
-msgid "SecurityOrchestration|Action"
-msgstr ""
-
msgid "SecurityOrchestration|Actions"
msgstr ""
msgid "SecurityOrchestration|Add rule"
msgstr ""
+msgid "SecurityOrchestration|After dismissing the alert, the information will never be shown again."
+msgstr ""
+
msgid "SecurityOrchestration|All policies"
msgstr ""
@@ -32252,7 +32938,7 @@ msgstr ""
msgid "SecurityOrchestration|Description"
msgstr ""
-msgid "SecurityOrchestration|Disabled"
+msgid "SecurityOrchestration|Don't show the alert anymore"
msgstr ""
msgid "SecurityOrchestration|Edit policy"
@@ -32261,13 +32947,13 @@ msgstr ""
msgid "SecurityOrchestration|Edit policy project"
msgstr ""
-msgid "SecurityOrchestration|Enabled"
+msgid "SecurityOrchestration|Empty policy name"
msgstr ""
-msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Enabled"
msgstr ""
-msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
msgstr ""
msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
@@ -32276,7 +32962,7 @@ msgstr ""
msgid "SecurityOrchestration|Invalid policy type"
msgstr ""
-msgid "SecurityOrchestration|Latest scan"
+msgid "SecurityOrchestration|Latest scan run against %{agent}"
msgstr ""
msgid "SecurityOrchestration|Network"
@@ -32285,15 +32971,27 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No actions defined - policy will not run."
+msgstr ""
+
+msgid "SecurityOrchestration|No description"
+msgstr ""
+
msgid "SecurityOrchestration|No rules defined - policy will not run."
msgstr ""
+msgid "SecurityOrchestration|Not enabled"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
msgid "SecurityOrchestration|Policies"
msgstr ""
+msgid "SecurityOrchestration|Policy Type"
+msgstr ""
+
msgid "SecurityOrchestration|Policy cannot be enabled for non-existing branches (%{branches})"
msgstr ""
@@ -32318,10 +33016,13 @@ msgstr ""
msgid "SecurityOrchestration|Require %{approvals} %{plural} from %{approvers} if any of the following occur:"
msgstr ""
-msgid "SecurityOrchestration|Rule"
+msgid "SecurityOrchestration|Rules"
msgstr ""
-msgid "SecurityOrchestration|Rules"
+msgid "SecurityOrchestration|Runs %{actions} and %{lastAction} scans"
+msgstr ""
+
+msgid "SecurityOrchestration|Runs a %{action} scan"
msgstr ""
msgid "SecurityOrchestration|Scan Execution"
@@ -32381,6 +33082,9 @@ msgstr ""
msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
+msgid "SecurityOrchestration|This view only shows scan results for the agent %{agent}. You can view scan results for all agents in the %{linkStart}Operational Vulnerabilities tab of the vulnerability report%{linkEnd}."
+msgstr ""
+
msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
@@ -32435,9 +33139,6 @@ msgstr ""
msgid "SecurityOrchestration|users with ids"
msgstr ""
-msgid "SecurityOrchestration|view results"
-msgstr ""
-
msgid "SecurityOrchestration|vulnerabilities"
msgstr ""
@@ -33107,22 +33808,19 @@ 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|In order to start using functions as a service, you must first install Knative on your Kubernetes cluster. %{linkStart}More information%{linkEnd}"
-msgstr ""
-
msgid "Serverless|Learn more about Serverless"
msgstr ""
msgid "Serverless|No functions available"
msgstr ""
-msgid "Serverless|Sign up for First Look"
+msgid "Serverless|Serverless was %{linkStart}deprecated%{linkEnd} in GitLab 14.3."
+msgstr ""
+
+msgid "Serverless|Serverless was %{postLinkStart}deprecated%{postLinkEnd}. But if you opt to use it, you must install Knative in your Kubernetes cluster first. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "Serverless|The deploy job has not finished."
@@ -33134,9 +33832,6 @@ 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 ""
@@ -33152,9 +33847,6 @@ msgstr ""
msgid "Service Account Key"
msgstr ""
-msgid "Service Accounts"
-msgstr ""
-
msgid "Service Accounts keys authorize GitLab to deploy your Google Cloud project"
msgstr ""
@@ -33164,10 +33856,10 @@ msgstr ""
msgid "Service Desk allows people to create issues in your GitLab instance without their own user account. It provides a unique email address for end users to create issues in a project. Replies can be sent either through the GitLab interface or by email. End users only see threads through email."
msgstr ""
-msgid "Service Usage Data"
+msgid "Service account generated successfully"
msgstr ""
-msgid "Service account generated successfully"
+msgid "Service accounts"
msgstr ""
msgid "Service ping is disabled in your configuration file, and cannot be enabled through this form."
@@ -33311,6 +34003,9 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
+msgid "Set the per-user rate limit for getting a user by ID via the API."
+msgstr ""
+
msgid "Set the per-user rate limit for notes created by web or API requests."
msgstr ""
@@ -33492,6 +34187,9 @@ msgstr ""
msgid "Shared runners details"
msgstr ""
+msgid "Shared runners enabled cannot be enabled until a valid credit card is on file"
+msgstr ""
+
msgid "Shared runners help link"
msgstr ""
@@ -33549,6 +34247,9 @@ msgstr ""
msgid "Show all issues."
msgstr ""
+msgid "Show all milestones"
+msgstr ""
+
msgid "Show all test cases."
msgstr ""
@@ -33585,6 +34286,9 @@ msgstr ""
msgid "Show file contents"
msgstr ""
+msgid "Show group milestones"
+msgstr ""
+
msgid "Show labels"
msgstr ""
@@ -33600,6 +34304,12 @@ msgstr ""
msgid "Show open epics"
msgstr ""
+msgid "Show project milestones"
+msgstr ""
+
+msgid "Show sub-group milestones"
+msgstr ""
+
msgid "Show the Closed list"
msgstr ""
@@ -33609,13 +34319,6 @@ msgstr ""
msgid "Show whitespace changes"
msgstr ""
-msgid "Showing %d event"
-msgid_plural "Showing %d events"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-msgstr[3] ""
-
msgid "Showing %{conflict} between %{sourceBranch} and %{targetBranch}"
msgstr ""
@@ -33677,12 +34380,6 @@ msgstr ""
msgid "Sidebar|None"
msgstr ""
-msgid "Sidebar|Only numeral characters allowed"
-msgstr ""
-
-msgid "Sidebar|Weight"
-msgstr ""
-
msgid "Sidekiq job compression threshold (bytes)"
msgstr ""
@@ -33845,6 +34542,9 @@ msgstr ""
msgid "Slack logo"
msgstr ""
+msgid "SlackIntegration|Are you sure you want to remove this project from the Slack application?"
+msgstr ""
+
msgid "SlackIntegration|GitLab for Slack"
msgstr ""
@@ -33854,6 +34554,9 @@ msgstr ""
msgid "SlackIntegration|Project alias"
msgstr ""
+msgid "SlackIntegration|Remove project"
+msgstr ""
+
msgid "SlackIntegration|Select a GitLab project to link with your Slack workspace."
msgstr ""
@@ -33998,9 +34701,6 @@ msgstr ""
msgid "Something went wrong trying to load issue contacts."
msgstr ""
-msgid "Something went wrong when creating a work item. Please try again"
-msgstr ""
-
msgid "Something went wrong when reordering designs. Please try again"
msgstr ""
@@ -34094,9 +34794,6 @@ msgstr ""
msgid "Something went wrong while inserting your image. Please try again."
msgstr ""
-msgid "Something went wrong while merging this merge request. Please try again."
-msgstr ""
-
msgid "Something went wrong while obtaining the Let's Encrypt certificate."
msgstr ""
@@ -34418,10 +35115,10 @@ 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."
+msgid "SourcegraphAdmin|Learn more."
msgstr ""
-msgid "SourcegraphAdmin|More information"
+msgid "SourcegraphAdmin|Only public projects have code intelligence enabled and communicate with Sourcegraph."
msgstr ""
msgid "SourcegraphAdmin|Save changes"
@@ -34430,7 +35127,7 @@ msgstr ""
msgid "SourcegraphAdmin|Sourcegraph URL"
msgstr ""
-msgid "SourcegraphAdmin|e.g. https://sourcegraph.example.com"
+msgid "SourcegraphAdmin|https://sourcegraph.example.com"
msgstr ""
msgid "SourcegraphPreferences|This feature is experimental and currently limited to certain projects."
@@ -34565,6 +35262,9 @@ msgstr ""
msgid "Start date"
msgstr ""
+msgid "Start free trial"
+msgstr ""
+
msgid "Start merge train"
msgstr ""
@@ -34595,6 +35295,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started escalation for this incident."
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -34607,6 +35310,9 @@ msgstr ""
msgid "Starts at (UTC)"
msgstr ""
+msgid "Starts escalations for this incident"
+msgstr ""
+
msgid "Starts on"
msgstr ""
@@ -34868,6 +35574,9 @@ msgstr ""
msgid "Strikethrough"
msgstr ""
+msgid "Strikethrough text"
+msgstr ""
+
msgid "Subgroup information"
msgstr ""
@@ -35102,6 +35811,21 @@ msgstr ""
msgid "Subscriptions"
msgstr ""
+msgid "Subscriptions|Chat with sales"
+msgstr ""
+
+msgid "Subscriptions|Close"
+msgstr ""
+
+msgid "Subscriptions|Not ready to buy yet?"
+msgstr ""
+
+msgid "Subscriptions|Start a free trial"
+msgstr ""
+
+msgid "Subscriptions|We understand. Maybe you have some questions for our sales team, or maybe you'd like to try some of the paid features first. What would you like to do?"
+msgstr ""
+
msgid "Subscription|Your subscription for %{strong}%{namespace_name}%{strong_close} has expired and you are now on %{pricing_link_start}the GitLab Free tier%{pricing_link_end}. Don't worry, your data is safe. Get in touch with our support team (%{support_email}). They'll gladly help with your subscription renewal."
msgstr ""
@@ -35312,6 +36036,9 @@ msgstr ""
msgid "SuperSonics|Maximum users"
msgstr ""
+msgid "SuperSonics|Offline cloud"
+msgstr ""
+
msgid "SuperSonics|Paste your activation code"
msgstr ""
@@ -35378,6 +36105,12 @@ msgstr ""
msgid "SuperSonics|You do not have an active subscription"
msgstr ""
+msgid "SuperSonics|You have a future dated license"
+msgstr ""
+
+msgid "SuperSonics|You have added a license that activates on %{date}. Please see the subscription history table below for more details."
+msgstr ""
+
msgid "SuperSonics|You have successfully added a license that activates on %{date}. Please see the subscription history table below for more details."
msgstr ""
@@ -35537,6 +36270,9 @@ msgstr ""
msgid "Tag name is required"
msgstr ""
+msgid "Tag push"
+msgstr ""
+
msgid "Tag push events"
msgstr ""
@@ -35639,6 +36375,9 @@ msgstr ""
msgid "TagsPage|protected"
msgstr ""
+msgid "Take a look at the documentation to discover all of GitLab’s capabilities."
+msgstr ""
+
msgid "Target Branch"
msgstr ""
@@ -36053,6 +36792,9 @@ msgstr ""
msgid "Tests"
msgstr ""
+msgid "Text (optional)"
+msgstr ""
+
msgid "Text added to the body of all email messages. %{character_limit} character limit"
msgstr ""
@@ -36105,6 +36847,9 @@ msgstr ""
msgid "The CSV export will be created in the background. Once finished, it will be sent to %{email} in an attachment."
msgstr ""
+msgid "The CSV export you requested of all user memberships is attached to this email."
+msgstr ""
+
msgid "The GitLab subscription service (customers.gitlab.com) is currently experiencing an outage. You can monitor the status and get updates at %{linkStart}status.gitlab.com%{linkEnd}."
msgstr ""
@@ -36180,6 +36925,9 @@ 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 epic"
+msgstr ""
+
msgid "The current issue"
msgstr ""
@@ -36343,6 +37091,9 @@ msgstr ""
msgid "The latest pipeline for this merge request has failed."
msgstr ""
+msgid "The license key is invalid."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -36358,6 +37109,9 @@ msgstr ""
msgid "The license was successfully uploaded and will be active from %{starts_at}. You can see the details below."
msgstr ""
+msgid "The license you uploaded is invalid. If the issue persists, contact support at %{link}."
+msgstr ""
+
msgid "The list creation wizard is already open"
msgstr ""
@@ -36979,10 +37733,13 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} and everything this project contains. %{strongOpen}There is no going back%{strongClose}"
+msgstr ""
+
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains."
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}on %{date}%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains. %{strongOpen}There is no going back.%{strongClose}"
msgstr ""
msgid "This action will %{strongOpen}permanently remove%{strongClose} %{codeOpen}%{group}%{codeClose} %{strongOpen}immediately%{strongClose}."
@@ -37111,9 +37868,6 @@ msgstr ""
msgid "This file was modified for readability, and can't accept suggestions. Edit it directly."
msgstr ""
-msgid "This forked project has the following:"
-msgstr ""
-
msgid "This form is disabled in preview"
msgstr ""
@@ -37126,7 +37880,7 @@ msgstr ""
msgid "This group can't be removed because it is linked to a subscription. To remove this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
-msgid "This group can't be transfered because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
+msgid "This group can't be transferred because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
msgid "This group cannot be invited to a project inside a group with enforced SSO"
@@ -37153,6 +37907,9 @@ 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 incident is already escalated with '%{escalation_policy_name}'."
+msgstr ""
+
msgid "This invitation was sent to %{mail_to_invite_email}, but you are signed in as %{link_to_current_user} with email %{mail_to_current_user}."
msgstr ""
@@ -37171,9 +37928,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 merge train pipeline"
-msgstr ""
-
msgid "This is a private email address %{helpIcon} generated just for you. Anyone who has it can create issues or merge requests as if they were you. If that happens, %{resetLinkStart}reset this token%{resetLinkEnd}."
msgstr ""
@@ -37195,6 +37949,12 @@ msgstr ""
msgid "This is your current session"
msgstr ""
+msgid "This issue cannot be assigned to a confidential epic because it is public."
+msgstr ""
+
+msgid "This issue cannot be made public because it belongs to a confidential epic."
+msgstr ""
+
msgid "This issue is confidential and should only be visible to team members with at least Reporter access."
msgstr ""
@@ -37312,6 +38072,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 branch is protected from force push."
+msgstr ""
+
msgid "This merge request cannot be rebased while there are conflicts."
msgstr ""
@@ -37363,9 +38126,15 @@ msgstr ""
msgid "This pipeline was triggered by a schedule."
msgstr ""
+msgid "This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project"
msgstr ""
+msgid "This project can be restored until %{date}."
+msgstr ""
+
msgid "This project cannot be %{visibilityLevel} because the visibility of %{openShowLink}%{name}%{closeShowLink} is %{visibility}. To make this project %{visibilityLevel}, you must first %{openEditLink}change the visibility%{closeEditLink} of the parent group."
msgstr ""
@@ -37384,6 +38153,9 @@ msgstr ""
msgid "This project is %{strongStart}NOT%{strongEnd} a fork, and has the following:"
msgstr ""
+msgid "This project is %{strongStart}NOT%{strongEnd} a fork. This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -38079,6 +38851,9 @@ msgstr ""
msgid "Today"
msgstr ""
+msgid "Todos count"
+msgstr ""
+
msgid "Todos|Are you looking for things to do? Take a look at %{strongStart}%{openIssuesLinkStart}open issues%{openIssuesLinkEnd}%{strongEnd}, contribute to %{strongStart}%{mergeRequestLinkStart}a merge request%{mergeRequestLinkEnd}%{mergeRequestLinkEnd}%{strongEnd}, or mention someone in a comment to automatically assign them a new to-do item."
msgstr ""
@@ -38352,12 +39127,8 @@ msgstr ""
msgid "Trending"
msgstr ""
-msgid "Trials|%{planName} Trial %{enDash} %{num} day left"
-msgid_plural "Trials|%{planName} Trial %{enDash} %{num} days left"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-msgstr[3] ""
+msgid "Trials|%{planName} Trial"
+msgstr ""
msgid "Trials|Compare all plans"
msgstr ""
@@ -38365,6 +39136,9 @@ msgstr ""
msgid "Trials|Create a new group to start your GitLab Ultimate trial."
msgstr ""
+msgid "Trials|Day %{daysUsed}/%{duration}"
+msgstr ""
+
msgid "Trials|Go back to GitLab"
msgstr ""
@@ -38614,7 +39388,7 @@ msgstr ""
msgid "URL is triggered when repository is updated"
msgstr ""
-msgid "URL must be percent-encoded if neccessary."
+msgid "URL must be percent-encoded if necessary."
msgstr ""
msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
@@ -38833,6 +39607,9 @@ msgstr ""
msgid "Unlock account"
msgstr ""
+msgid "Unlock more features with GitLab Ultimate"
+msgstr ""
+
msgid "Unlock the discussion"
msgstr ""
@@ -38896,6 +39673,9 @@ msgstr ""
msgid "Unsubscribes from this %{quick_action_target}."
msgstr ""
+msgid "Unsupported sort value."
+msgstr ""
+
msgid "Unsupported todo type passed. Supported todo types are: %{todo_types}"
msgstr ""
@@ -39124,6 +39904,9 @@ msgstr ""
msgid "UsageQuota|File attachments and smaller design graphics."
msgstr ""
+msgid "UsageQuota|From %{storage_enforcement_date} storage limits will apply to this namespace. View and manage your usage in %{strong_start}Group Settings &gt; Usage quotas%{strong_end}."
+msgstr ""
+
msgid "UsageQuota|Git repository."
msgstr ""
@@ -39184,6 +39967,9 @@ msgstr ""
msgid "UsageQuota|Storage type"
msgstr ""
+msgid "UsageQuota|Storage used"
+msgstr ""
+
msgid "UsageQuota|This is the total amount of storage used across your projects within this namespace."
msgstr ""
@@ -39379,6 +40165,12 @@ msgstr ""
msgid "Use hashed storage paths for newly created and renamed repositories. Always enabled since 13.0."
msgstr ""
+msgid "Use issue count"
+msgstr ""
+
+msgid "Use issue weight"
+msgstr ""
+
msgid "Use one line per URI"
msgstr ""
@@ -39760,6 +40552,9 @@ msgstr ""
msgid "Users"
msgstr ""
+msgid "Users API rate limit"
+msgstr ""
+
msgid "Users can launch a development environment from a GitLab browser tab when the %{linkStart}Gitpod%{linkEnd} integration is enabled."
msgstr ""
@@ -40089,6 +40884,9 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View group pipeline usage quota"
+msgstr ""
+
msgid "View incident details at"
msgstr ""
@@ -40243,6 +41041,9 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
+msgid "Vulnerability"
+msgstr ""
+
msgid "Vulnerability Report"
msgstr ""
@@ -40294,6 +41095,9 @@ msgstr ""
msgid "VulnerabilityManagement|An unverified non-confirmed finding"
msgstr ""
+msgid "VulnerabilityManagement|At least one identifier is required"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -40303,12 +41107,24 @@ msgstr ""
msgid "VulnerabilityManagement|Create Jira issue"
msgstr ""
+msgid "VulnerabilityManagement|Enter a name"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE code"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE identifier URL"
+msgstr ""
+
msgid "VulnerabilityManagement|Fetching linked Jira issues"
msgstr ""
msgid "VulnerabilityManagement|Manually add a vulnerability entry into the vulnerability report."
msgstr ""
+msgid "VulnerabilityManagement|Name is a required field"
+msgstr ""
+
msgid "VulnerabilityManagement|Needs triage"
msgstr ""
@@ -40324,6 +41140,18 @@ msgstr ""
msgid "VulnerabilityManagement|Select a method"
msgstr ""
+msgid "VulnerabilityManagement|Select a severity level"
+msgstr ""
+
+msgid "VulnerabilityManagement|Select a status"
+msgstr ""
+
+msgid "VulnerabilityManagement|Severity is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Something went wrong while creating vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -40348,6 +41176,12 @@ msgstr ""
msgid "VulnerabilityManagement|Something went wrong, could not update vulnerability state."
msgstr ""
+msgid "VulnerabilityManagement|Status is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Submit vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Summary, detailed description, steps to reproduce, etc."
msgstr ""
@@ -40543,6 +41377,9 @@ msgstr ""
msgid "WARNING:"
msgstr ""
+msgid "WARNING: This snippet contains hidden files which might be used to mask malicious behavior. Exercise caution if cloning and executing code from this snippet."
+msgstr ""
+
msgid "Wait for the file to load to copy its contents"
msgstr ""
@@ -40762,6 +41599,15 @@ msgstr ""
msgid "Webhooks|An issue is created, updated, closed, or reopened."
msgstr ""
+msgid "Webhooks|Are you sure you want to delete this group hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this project hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this webhook?"
+msgstr ""
+
msgid "Webhooks|Comments"
msgstr ""
@@ -40771,6 +41617,9 @@ msgstr ""
msgid "Webhooks|Confidential issues events"
msgstr ""
+msgid "Webhooks|Delete webhook"
+msgstr ""
+
msgid "Webhooks|Deployment events"
msgstr ""
@@ -41006,6 +41855,9 @@ msgstr ""
msgid "Wiki"
msgstr ""
+msgid "Wiki page"
+msgstr ""
+
msgid "Wiki page was successfully created."
msgstr ""
@@ -41111,7 +41963,7 @@ msgstr ""
msgid "WikiPageConflictMessage|Someone edited the page the same time you did. Please check out %{wikiLinkStart}the page%{wikiLinkEnd} and make sure your changes will not unintentionally remove theirs."
msgstr ""
-msgid "WikiPage|An error occured while trying to render the content editor. Please try again later."
+msgid "WikiPage|An error occurred while trying to render the content editor. Please try again later."
msgstr ""
msgid "WikiPage|Are you sure you want to switch back to the classic editor?"
@@ -41270,6 +42122,18 @@ msgstr ""
msgid "WorkItem|New Task"
msgstr ""
+msgid "WorkItem|Something went wrong when creating a work item. Please try again"
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching the work item. Please try again."
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching work item types. Please try again"
+msgstr ""
+
+msgid "WorkItem|Type"
+msgstr ""
+
msgid "WorkItem|Work Items"
msgstr ""
@@ -41336,7 +42200,10 @@ msgstr ""
msgid "You are about to add %{usersTag} people to the discussion. They will all receive a notification."
msgstr ""
-msgid "You are about to permanently delete this project"
+msgid "You are about to delete this forked project containing:"
+msgstr ""
+
+msgid "You are about to delete this project containing:"
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."
@@ -41357,6 +42224,9 @@ msgstr ""
msgid "You are attempting to update a file that has changed since you started editing it."
msgstr ""
+msgid "You are billed if you exceed this number. %{qsrOverageLinkStart}How does billing work?%{qsrOverageLinkEnd}"
+msgstr ""
+
msgid "You are connected to the Prometheus server, but there is currently no data to display."
msgstr ""
@@ -41414,6 +42284,9 @@ msgstr ""
msgid "You are not authorized to update this scanner profile"
msgstr ""
+msgid "You are not authorized to upload metric images"
+msgstr ""
+
msgid "You are now impersonating %{username}"
msgstr ""
@@ -41567,9 +42440,6 @@ msgstr ""
msgid "You can only upload one design when dropping onto an existing design."
msgstr ""
-msgid "You can recover this project until %{date}"
-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 ""
@@ -41618,9 +42488,6 @@ msgstr ""
msgid "You cannot write to this read-only GitLab instance."
msgstr ""
-msgid "You can’t %{tag_start}edit%{tag_end} files directly in this project. Fork this project and submit a merge request with your changes."
-msgstr ""
-
msgid "You can’t edit files directly in this project. Fork this project and submit a merge request with your changes."
msgstr ""
@@ -41775,9 +42642,6 @@ 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 set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
@@ -41808,12 +42672,6 @@ msgstr ""
msgid "You must have maintainer access to force delete a lock"
msgstr ""
-msgid "You must have permission to create a project in a group before forking."
-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 ""
@@ -42219,7 +43077,7 @@ msgstr ""
msgid "Your public email will be displayed on your public profile."
msgstr ""
-msgid "Your request for access could not be processed: %{error_meesage}"
+msgid "Your request for access could not be processed: %{error_message}"
msgstr ""
msgid "Your request for access has been queued for review."
@@ -42408,6 +43266,9 @@ msgstr ""
msgid "archived:"
msgstr ""
+msgid "artifacts"
+msgstr ""
+
msgid "assign yourself"
msgstr ""
@@ -42439,6 +43300,9 @@ msgstr[3] ""
msgid "branch name"
msgstr ""
+msgid "builds"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -42868,6 +43732,9 @@ msgstr ""
msgid "contact with same email already exists in group hierarchy"
msgstr ""
+msgid "container registry images"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -42907,6 +43774,9 @@ msgstr ""
msgid "data"
msgstr ""
+msgid "database"
+msgstr ""
+
msgid "date must not be after 9999-12-31"
msgstr ""
@@ -42932,9 +43802,6 @@ msgstr ""
msgid "design"
msgstr ""
-msgid "detached"
-msgstr ""
-
msgid "disabled"
msgstr ""
@@ -43191,7 +44058,7 @@ msgstr ""
msgid "is not a valid X509 certificate."
msgstr ""
-msgid "is not allowed for sign-up."
+msgid "is not allowed for sign-up. Please use your regular email address."
msgstr ""
msgid "is not allowed for this group."
@@ -43203,7 +44070,7 @@ msgstr ""
msgid "is not allowed since the group is not top-level group."
msgstr ""
-msgid "is not allowed."
+msgid "is not allowed. Please use your regular email address."
msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
@@ -43290,6 +44157,9 @@ msgstr ""
msgid "level: %{level}"
msgstr ""
+msgid "lfs objects"
+msgstr ""
+
msgid "limit of %{project_limit} reached"
msgstr ""
@@ -43515,6 +44385,9 @@ msgstr ""
msgid "mrWidget|Merge blocked: pipeline must succeed. It's waiting for a manual action to continue."
msgstr ""
+msgid "mrWidget|Merge blocked: pipeline must succeed. Push a commit that fixes the failure, or %{linkStart}learn about other solutions.%{linkEnd}"
+msgstr ""
+
msgid "mrWidget|Merge blocked: this merge request must be approved."
msgstr ""
@@ -43632,9 +44505,6 @@ msgstr ""
msgid "mrWidget|The changes were not merged into"
msgstr ""
-msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -43782,9 +44652,6 @@ msgstr ""
msgid "open issue"
msgstr ""
-msgid "opened %{timeAgo}"
-msgstr ""
-
msgid "or"
msgstr ""
@@ -43798,6 +44665,12 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "packages"
+msgstr ""
+
+msgid "pages"
+msgstr ""
+
msgid "parent"
msgid_plural "parents"
msgstr[0] ""
@@ -43955,6 +44828,9 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
+msgid "repositories"
+msgstr ""
+
msgid "repository:"
msgstr ""
@@ -44075,12 +44951,18 @@ msgstr ""
msgid "tag name"
msgstr ""
+msgid "terraform states"
+msgstr ""
+
msgid "the correct format."
msgstr ""
msgid "the file"
msgstr ""
+msgid "the following epic(s)"
+msgstr ""
+
msgid "the following issue(s)"
msgstr ""
@@ -44093,21 +44975,12 @@ msgstr ""
msgid "this document"
msgstr ""
-msgid "this issue cannot be assigned to a confidential epic since it is public"
-msgstr ""
-
-msgid "this issue cannot be made public since it belongs to a confidential epic"
-msgstr ""
-
msgid "time summary"
msgstr ""
msgid "toggle collapse"
msgstr ""
-msgid "train"
-msgstr ""
-
msgid "triggered"
msgstr ""
@@ -44238,3 +45111,6 @@ msgstr ""
msgid "{project}"
msgstr ""
+msgid "✔"
+msgstr ""
+
diff --git a/locale/sq_AL/gitlab.po b/locale/sq_AL/gitlab.po
index ef3fdd1818c..32768125b2e 100644
--- a/locale/sq_AL/gitlab.po
+++ b/locale/sq_AL/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: sq\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2022-02-02 15:42\n"
+"PO-Revision-Date: 2022-03-01 20:36\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -146,6 +146,11 @@ msgid_plural "%d approvers (you've approved)"
msgstr[0] ""
msgstr[1] ""
+msgid "%d assigned issue"
+msgid_plural "%d assigned issues"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -421,8 +426,23 @@ msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
msgstr[1] ""
-msgid "%d vulnerability updated"
-msgid_plural "%d vulnerabilities updated"
+msgid "%d vulnerability set to confirmed"
+msgid_plural "%d vulnerabilities set to confirmed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to dismissed"
+msgid_plural "%d vulnerabilities set to dismissed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to needs triage"
+msgid_plural "%d vulnerabilities set to needs triage"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to resolved"
+msgid_plural "%d vulnerabilities set to resolved"
msgstr[0] ""
msgstr[1] ""
@@ -510,6 +530,12 @@ msgstr[1] ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{completed} of %{total} issues closed"
+msgstr ""
+
+msgid "%{completed} of %{total} weight completed"
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -858,6 +884,9 @@ msgstr ""
msgid "%{openedIssues} open, %{closedIssues} closed"
msgstr ""
+msgid "%{percentage}%% issues closed"
+msgstr ""
+
msgid "%{percentage}%% weight completed"
msgstr ""
@@ -1287,6 +1316,9 @@ msgid_plural "- Users"
msgstr[0] ""
msgstr[1] ""
+msgid "- of - issues closed"
+msgstr ""
+
msgid "- of - weight completed"
msgstr ""
@@ -1429,7 +1461,7 @@ msgstr ""
msgid "1000+"
msgstr ""
-msgid "192.168.0.0/24"
+msgid "192.168.0.0/24 or 2001:0DB8:1234::/48"
msgstr ""
msgid "1st contribution!"
@@ -1741,13 +1773,13 @@ msgstr ""
msgid "AWS Access Key"
msgstr ""
-msgid "AWS Access Key. Only required if not using role instance credentials"
+msgid "AWS Secret Access Key"
msgstr ""
-msgid "AWS Secret Access Key"
+msgid "AWS access key ID (Optional)"
msgstr ""
-msgid "AWS Secret Access Key. Only required if not using role instance credentials"
+msgid "AWS secret access key (Optional)"
msgstr ""
msgid "AWS service error: %{error}"
@@ -1807,9 +1839,6 @@ msgstr ""
msgid "Access granted"
msgstr ""
-msgid "Access key ID"
-msgstr ""
-
msgid "Access requests"
msgstr ""
@@ -1984,7 +2013,7 @@ msgstr ""
msgid "Activity"
msgstr ""
-msgid "Activity|An error occured while retrieving activity. Reload the page to try again."
+msgid "Activity|An error occurred while retrieving activity. Reload the page to try again."
msgstr ""
msgid "Add"
@@ -2023,6 +2052,9 @@ msgstr ""
msgid "Add a %{type}"
msgstr ""
+msgid "Add a GCP region"
+msgstr ""
+
msgid "Add a GPG key"
msgstr ""
@@ -2074,6 +2106,9 @@ msgstr ""
msgid "Add a numbered list"
msgstr ""
+msgid "Add a related epic"
+msgstr ""
+
msgid "Add a related issue"
msgstr ""
@@ -2188,6 +2223,9 @@ msgstr ""
msgid "Add or subtract spent time"
msgstr ""
+msgid "Add people"
+msgstr ""
+
msgid "Add previously merged commits"
msgstr ""
@@ -2254,6 +2292,9 @@ msgstr ""
msgid "Add webhook"
msgstr ""
+msgid "Add your team members and others to GitLab."
+msgstr ""
+
msgid "Add/remove"
msgstr ""
@@ -3076,12 +3117,6 @@ msgstr ""
msgid "AdvancedSearch|Reindex required"
msgstr ""
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. Permanently deleting this project will %{strongStart}immediately delete%{strongEnd} its repositories and %{strongStart}all related resources%{strongEnd}, including issues, merge requests etc."
-msgstr ""
-
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. You will lose this project's repository and %{strongStart}all related resources%{strongEnd}, including issues and merge requests."
-msgstr ""
-
msgid "After a successful password update you will be redirected to login screen."
msgstr ""
@@ -3112,6 +3147,9 @@ msgstr ""
msgid "Akismet helps prevent the creation of spam issues in public projects."
msgstr ""
+msgid "Alert"
+msgstr ""
+
msgid "AlertManagement|Acknowledged"
msgstr ""
@@ -3484,9 +3522,6 @@ msgstr ""
msgid "All environments"
msgstr ""
-msgid "All epics"
-msgstr ""
-
msgid "All groups and projects"
msgstr ""
@@ -4223,12 +4258,15 @@ msgstr ""
msgid "ApplicationSettings|Approve users in the pending approval status?"
msgstr ""
-msgid "ApplicationSettings|By making this change, you will automatically approve %d user with the pending approval status."
-msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users with the pending approval status."
+msgid "ApplicationSettings|Approve users who are pending approval?"
+msgstr ""
+
+msgid "ApplicationSettings|By making this change, you will automatically approve %d user who is pending approval."
+msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users who are pending approval."
msgstr[0] ""
msgstr[1] ""
-msgid "ApplicationSettings|By making this change, you will automatically approve all users in pending approval status."
+msgid "ApplicationSettings|By making this change, you will automatically approve all users who are pending approval."
msgstr ""
msgid "ApplicationSettings|Denied domains for sign-ups"
@@ -4634,10 +4672,10 @@ msgstr ""
msgid "Archiving the project will make it entirely read-only. It is hidden from the dashboard and doesn't show up in searches. %{strong_start}The repository cannot be committed to, and no issues, comments, or other entities can be created.%{strong_end} %{link_start}Learn more.%{link_end}"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to delete this project?"
+msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
+msgid "Are you absolutely sure?"
msgstr ""
msgid "Are you sure that you want to archive this project?"
@@ -4673,12 +4711,18 @@ msgstr ""
msgid "Are you sure you want to delete this SSH key?"
msgstr ""
+msgid "Are you sure you want to delete this comment?"
+msgstr ""
+
msgid "Are you sure you want to delete this deploy key?"
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 label?"
+msgstr ""
+
msgid "Are you sure you want to delete this pipeline schedule?"
msgstr ""
@@ -4694,9 +4738,6 @@ msgstr ""
msgid "Are you sure you want to discard your changes?"
msgstr ""
-msgid "Are you sure you want to erase this build?"
-msgstr ""
-
msgid "Are you sure you want to import %d repository?"
msgid_plural "Are you sure you want to import %d repositories?"
msgstr[0] ""
@@ -4744,6 +4785,9 @@ msgstr ""
msgid "Are you sure you want to remove this list?"
msgstr ""
+msgid "Are you sure you want to remove this nickname?"
+msgstr ""
+
msgid "Are you sure you want to reset the health check token?"
msgstr ""
@@ -4756,10 +4800,10 @@ 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?"
+msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
msgstr ""
-msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
+msgid "Are you sure you want to revoke this project access token? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to stop this environment?"
@@ -4906,9 +4950,6 @@ msgstr ""
msgid "Assigned to %{assignee_name}"
msgstr ""
-msgid "Assigned to %{name}"
-msgstr ""
-
msgid "Assigned to me"
msgstr ""
@@ -4973,6 +5014,9 @@ msgstr[1] ""
msgid "Attaching the file failed."
msgstr ""
+msgid "Attention"
+msgstr ""
+
msgid "Audit Events"
msgstr ""
@@ -5135,6 +5179,12 @@ msgstr ""
msgid "Authorized applications (%{size})"
msgstr ""
+msgid "AuthorizedApplication|Are you sure you want to revoke this application?"
+msgstr ""
+
+msgid "AuthorizedApplication|Revoke application"
+msgstr ""
+
msgid "Authors: %{authors}"
msgstr ""
@@ -6328,6 +6378,9 @@ msgstr ""
msgid "CICDAnalytics|Shared Runners Usage"
msgstr ""
+msgid "CICDAnalytics|Shared runner pipeline minute duration by month"
+msgstr ""
+
msgid "CICDAnalytics|Shared runner usage"
msgstr ""
@@ -6469,6 +6522,9 @@ msgstr ""
msgid "Can create groups:"
msgstr ""
+msgid "Can not delete primary training"
+msgstr ""
+
msgid "Can't apply as the source branch was deleted."
msgstr ""
@@ -6802,9 +6858,6 @@ msgstr ""
msgid "Changing any setting here requires an application restart"
msgstr ""
-msgid "Changing group URL can have unintended side effects."
-msgstr ""
-
msgid "Charts can't be displayed as the request for data has timed out. %{documentationLink}"
msgstr ""
@@ -6892,9 +6945,6 @@ msgstr ""
msgid "Checking branch availability..."
msgstr ""
-msgid "Checking group URL availability..."
-msgstr ""
-
msgid "Checking group path availability..."
msgstr ""
@@ -7388,6 +7438,9 @@ msgstr ""
msgid "Clear recent searches"
msgstr ""
+msgid "Clear repository checks"
+msgstr ""
+
msgid "Clear search"
msgstr ""
@@ -7520,9 +7573,6 @@ msgstr ""
msgid "Closed MRs"
msgstr ""
-msgid "Closed epics"
-msgstr ""
-
msgid "Closed issues"
msgstr ""
@@ -7559,13 +7609,13 @@ msgstr ""
msgid "Cluster level"
msgstr ""
-msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
+msgid "Cluster type must be specified for Stages::ClusterEndpointInserter"
msgstr ""
msgid "ClusterAgents|%{name} successfully deleted"
msgstr ""
-msgid "ClusterAgents|%{number} of %{total} Agents"
+msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
@@ -7607,6 +7657,15 @@ msgstr ""
msgid "ClusterAgents|Agent never connected to GitLab"
msgstr ""
+msgid "ClusterAgents|Agent version mismatch"
+msgstr ""
+
+msgid "ClusterAgents|Agent version mismatch and update"
+msgstr ""
+
+msgid "ClusterAgents|Agent version update required"
+msgstr ""
+
msgid "ClusterAgents|All"
msgstr ""
@@ -7631,7 +7690,7 @@ msgstr ""
msgid "ClusterAgents|Configuration"
msgstr ""
-msgid "ClusterAgents|Connect a cluster through the Agent"
+msgid "ClusterAgents|Connect a cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connect existing cluster"
@@ -7640,13 +7699,13 @@ msgstr ""
msgid "ClusterAgents|Connect with a certificate"
msgstr ""
-msgid "ClusterAgents|Connect with agent"
+msgid "ClusterAgents|Connect with an agent"
msgstr ""
msgid "ClusterAgents|Connect with the GitLab Agent"
msgstr ""
-msgid "ClusterAgents|Connect your cluster through the Agent"
+msgid "ClusterAgents|Connect your cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connected"
@@ -7706,7 +7765,10 @@ msgstr ""
msgid "ClusterAgents|How to register an agent?"
msgstr ""
-msgid "ClusterAgents|Install new Agent"
+msgid "ClusterAgents|How to update an agent?"
+msgstr ""
+
+msgid "ClusterAgents|Install a new agent"
msgstr ""
msgid "ClusterAgents|Last connected %{timeAgo}."
@@ -7733,7 +7795,7 @@ msgstr ""
msgid "ClusterAgents|Never connected"
msgstr ""
-msgid "ClusterAgents|No Agents"
+msgid "ClusterAgents|No agents"
msgstr ""
msgid "ClusterAgents|No clusters connected through cluster certificates"
@@ -7793,6 +7855,9 @@ msgstr ""
msgid "ClusterAgents|The agent has not been connected in a long time. There might be a connectivity issue. Last contact was %{timeAgo}."
msgstr ""
+msgid "ClusterAgents|The agent version do not match each other across your cluster's pods. This can happen when a new agent version was just deployed and Kubernetes is shutting down the old pods."
+msgstr ""
+
msgid "ClusterAgents|The recommended installation method includes the token. If you want to follow the advanced installation method provided in the docs, make sure you save the token value before you close this window."
msgstr ""
@@ -7840,6 +7905,9 @@ msgstr ""
msgid "ClusterAgents|You will need to create a token to connect to your agent"
msgstr ""
+msgid "ClusterAgents|Your agent version is out of sync with your GitLab version (v%{version}), which might cause compatibility problems. Update the agent installed on your cluster to the most recent version."
+msgstr ""
+
msgid "ClusterAgents|Your instance doesn't have the %{linkStart}GitLab Agent Server (KAS)%{linkEnd} set up. Ask a GitLab Administrator to install it."
msgstr ""
@@ -8716,9 +8784,6 @@ msgstr ""
msgid "Comma-separated list of email addresses."
msgstr ""
-msgid "Comma-separated list of users allowed to exceed the rate limit."
-msgstr ""
-
msgid "Comma-separated, e.g. '1.1.1.1, 2.2.2.0/24'"
msgstr ""
@@ -9045,6 +9110,12 @@ msgstr ""
msgid "Confidential"
msgstr ""
+msgid "Confidential issue"
+msgstr ""
+
+msgid "Confidential note"
+msgstr ""
+
msgid "Confidentiality"
msgstr ""
@@ -9078,6 +9149,9 @@ msgstr ""
msgid "Configure Dependency Scanning in `.gitlab-ci.yml`, creating this file if it does not already exist"
msgstr ""
+msgid "Configure GitLab"
+msgstr ""
+
msgid "Configure GitLab runners to start using the Web Terminal. %{helpStart}Learn more.%{helpEnd}"
msgstr ""
@@ -9126,6 +9200,15 @@ msgstr ""
msgid "Configure pipelines to deploy web apps, backend services, APIs and static resources to Google Cloud"
msgstr ""
+msgid "Configure region"
+msgstr ""
+
+msgid "Configure region for environment"
+msgstr ""
+
+msgid "Configure regions"
+msgstr ""
+
msgid "Configure repository mirroring."
msgstr ""
@@ -9159,6 +9242,9 @@ msgstr ""
msgid "Configure which lists are shown for anyone who visits this board"
msgstr ""
+msgid "Configure your environments to be deployed to specific geographical regions"
+msgstr ""
+
msgid "Confirm"
msgstr ""
@@ -9861,10 +9947,10 @@ msgstr ""
msgid "CorpusManagement|Actions"
msgstr ""
-msgid "CorpusManagement|Corpus are used in fuzz testing as mutation source to Improve future testing."
+msgid "CorpusManagement|Corpus file"
msgstr ""
-msgid "CorpusManagement|Corpus file"
+msgid "CorpusManagement|Corpus files are used in coverage-guided fuzz testing as seed inputs to improve testing."
msgstr ""
msgid "CorpusManagement|Corpus files must be in *.zip format. Maximum 5 GB"
@@ -9918,6 +10004,9 @@ msgstr ""
msgid "Could not apply %{name} command."
msgstr ""
+msgid "Could not apply %{name} command. %{message}."
+msgstr ""
+
msgid "Could not authorize chat nickname. Try again!"
msgstr ""
@@ -10068,6 +10157,9 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
+msgid "Create a group"
+msgstr ""
+
msgid "Create a merge request"
msgstr ""
@@ -10092,6 +10184,9 @@ msgstr ""
msgid "Create a personal access token on your account to pull or push via %{protocol}."
msgstr ""
+msgid "Create a project"
+msgstr ""
+
msgid "Create an account using:"
msgstr ""
@@ -10455,6 +10550,9 @@ msgstr ""
msgid "Creation date"
msgstr ""
+msgid "Creator"
+msgstr ""
+
msgid "Credentials"
msgstr ""
@@ -10467,9 +10565,15 @@ msgstr ""
msgid "CredentialsInventory|Personal Access Tokens"
msgstr ""
+msgid "CredentialsInventory|Project Access Tokens"
+msgstr ""
+
msgid "CredentialsInventory|SSH Keys"
msgstr ""
+msgid "Credit card required to be on file in order to create a pipeline"
+msgstr ""
+
msgid "Credit card:"
msgstr ""
@@ -10653,9 +10757,6 @@ msgstr ""
msgid "Customer relations"
msgstr ""
-msgid "Customizable by an administrator."
-msgstr ""
-
msgid "Customizable by owners."
msgstr ""
@@ -10785,30 +10886,18 @@ msgstr ""
msgid "CycleAnalytics|%{selectedLabelsCount} selected (%{maxLabels} max)"
msgstr ""
-msgid "CycleAnalytics|%{stageCount} stages selected"
-msgstr ""
-
-msgid "CycleAnalytics|All stages"
-msgstr ""
-
-msgid "CycleAnalytics|Average days to completion"
+msgid "CycleAnalytics|Average time to completion"
msgstr ""
msgid "CycleAnalytics|Date"
msgstr ""
-msgid "CycleAnalytics|Days to completion"
-msgstr ""
-
msgid "CycleAnalytics|Display chart filters"
msgstr ""
msgid "CycleAnalytics|Lead Time for Changes"
msgstr ""
-msgid "CycleAnalytics|No stages selected"
-msgstr ""
-
msgid "CycleAnalytics|Number of tasks"
msgstr ""
@@ -10837,18 +10926,30 @@ msgstr ""
msgid "CycleAnalytics|Showing data for group '%{groupName}' from %{createdAfter} to %{createdBefore}"
msgstr ""
-msgid "CycleAnalytics|Stages"
+msgid "CycleAnalytics|Stage time: %{title}"
msgstr ""
msgid "CycleAnalytics|Tasks by type"
msgstr ""
-msgid "CycleAnalytics|The average time spent in the selected stage for the items that were completed on each date. Data limited to the last 500 items."
+msgid "CycleAnalytics|The average time items spent in this stage. Data limited to items completed within this date range."
msgstr ""
msgid "CycleAnalytics|The given date range is larger than 180 days"
msgstr ""
+msgid "CycleAnalytics|The total time items spent across each value stream stage. Data limited to items completed within this date range."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Stage time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Total time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|Total time"
+msgstr ""
+
msgid "CycleAnalytics|Type of work"
msgstr ""
@@ -10861,9 +10962,6 @@ msgstr ""
msgid "CycleAnalytics|project dropdown filter"
msgstr ""
-msgid "CycleAnalytics|stage dropdown"
-msgstr ""
-
msgid "DAG visualization requires at least 3 dependent jobs."
msgstr ""
@@ -10963,10 +11061,16 @@ msgstr ""
msgid "DastProfiles|AJAX spider"
msgstr ""
+msgid "DastProfiles|API"
+msgstr ""
+
+msgid "DastProfiles|API endpoint URL"
+msgstr ""
+
msgid "DastProfiles|Active"
msgstr ""
-msgid "DastProfiles|Additional request headers (Optional)"
+msgid "DastProfiles|Additional request headers (optional)"
msgstr ""
msgid "DastProfiles|Are you sure you want to delete this profile?"
@@ -10981,6 +11085,9 @@ msgstr ""
msgid "DastProfiles|Branch missing"
msgstr ""
+msgid "DastProfiles|Choose a scan method"
+msgstr ""
+
msgid "DastProfiles|Could not create the scanner profile. Please try again."
msgstr ""
@@ -11050,7 +11157,13 @@ msgstr ""
msgid "DastProfiles|Excluded URLs"
msgstr ""
-msgid "DastProfiles|Excluded URLs (Optional)"
+msgid "DastProfiles|Excluded URLs (optional)"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths (optional)"
msgstr ""
msgid "DastProfiles|Hide debug messages"
@@ -11107,9 +11220,6 @@ msgstr ""
msgid "DastProfiles|Request headers"
msgstr ""
-msgid "DastProfiles|Rest API"
-msgstr ""
-
msgid "DastProfiles|Run the AJAX spider, in addition to the traditional spider, to crawl the target site."
msgstr ""
@@ -11119,6 +11229,9 @@ msgstr ""
msgid "DastProfiles|Save profile"
msgstr ""
+msgid "DastProfiles|Scan method"
+msgstr ""
+
msgid "DastProfiles|Scan mode"
msgstr ""
@@ -11197,12 +11310,24 @@ msgstr ""
msgid "DastProfiles|Website"
msgstr ""
+msgid "DastProfiles|What does each method do?"
+msgstr ""
+
msgid "DastProfiles|You can either choose a passive scan or validate the target site from the site profile management page. %{docsLinkStart}Learn more about site validation.%{docsLinkEnd}"
msgstr ""
msgid "DastProfiles|You cannot run an active scan against an unvalidated site."
msgstr ""
+msgid "DastProfiles|folder/dast_example.har or https://example.com/dast_example.har"
+msgstr ""
+
+msgid "DastProfiles|folder/example.postman_collection.json or https://example.com/"
+msgstr ""
+
+msgid "DastProfiles|folder/openapi.json or https://example.com/openapi.json"
+msgstr ""
+
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
@@ -11310,6 +11435,9 @@ msgstr ""
msgid "DatadogIntegration|API URL"
msgstr ""
+msgid "DatadogIntegration|Custom tags in Datadog. Enter one tag per line in the %{codeOpen}key:value%{codeClose} format. %{linkOpen}How do I use tags?%{linkClose}"
+msgstr ""
+
msgid "DatadogIntegration|Environment"
msgstr ""
@@ -11328,12 +11456,18 @@ msgstr ""
msgid "DatadogIntegration|Tag all data from this GitLab instance in Datadog. Useful when managing several self-managed deployments."
msgstr ""
+msgid "DatadogIntegration|Tags"
+msgstr ""
+
msgid "DatadogIntegration|The Datadog site to send data to. To send data to the EU site, use %{codeOpen}datadoghq.eu%{codeClose}."
msgstr ""
msgid "DatadogIntegration|Trace your GitLab pipelines with Datadog."
msgstr ""
+msgid "DatadogIntegration|have an invalid format"
+msgstr ""
+
msgid "Datasource name not found"
msgstr ""
@@ -11343,9 +11477,6 @@ msgstr ""
msgid "Date merged"
msgstr ""
-msgid "Date picker"
-msgstr ""
-
msgid "Date range"
msgstr ""
@@ -11499,9 +11630,6 @@ msgstr ""
msgid "Definition"
msgstr ""
-msgid "Delayed Project Deletion (%{adjourned_deletion})"
-msgstr ""
-
msgid "DelayedJobs|Are you sure you want to run %{jobName} immediately? Otherwise this job will run automatically after its timer finishes."
msgstr ""
@@ -11580,10 +11708,10 @@ msgstr ""
msgid "Delete pipeline"
msgstr ""
-msgid "Delete project"
+msgid "Delete pipeline schedule"
msgstr ""
-msgid "Delete project. Are you ABSOLUTELY SURE?"
+msgid "Delete project"
msgstr ""
msgid "Delete row"
@@ -11613,6 +11741,9 @@ msgstr ""
msgid "Delete this epic and all descendants?"
msgstr ""
+msgid "Delete this project"
+msgstr ""
+
msgid "Delete user list"
msgstr ""
@@ -11871,6 +12002,12 @@ msgstr ""
msgid "Deploy to..."
msgstr ""
+msgid "DeployBoards|To see deployment progress for your environments, make sure you are deploying to %{codeStart}$KUBE_NAMESPACE%{codeEnd} and annotating with %{codeStart}app.gitlab.com/app=$CI_PROJECT_PATH_SLUG%{codeEnd} and %{codeStart}app.gitlab.com/env=$CI_ENVIRONMENT_SLUG%{codeEnd}."
+msgstr ""
+
+msgid "DeployBoard|Kubernetes Pods"
+msgstr ""
+
msgid "DeployFreeze|Add a freeze period to prevent unintended releases during a period of time for a given environment. You must update the deployment jobs in %{filename} according to the deploy freezes added here. %{freeze_period_link_start}Learn more.%{freeze_period_link_end}"
msgstr ""
@@ -11955,9 +12092,6 @@ msgstr ""
msgid "DeployTokens|Active Deploy Tokens (%{active_tokens})"
msgstr ""
-msgid "DeployTokens|Allows read and write access to registry images."
-msgstr ""
-
msgid "DeployTokens|Allows read and write access to the package registry."
msgstr ""
@@ -11970,6 +12104,9 @@ msgstr ""
msgid "DeployTokens|Allows read-only access to the repository."
msgstr ""
+msgid "DeployTokens|Allows write access to registry images."
+msgstr ""
+
msgid "DeployTokens|Copy deploy token"
msgstr ""
@@ -12063,12 +12200,57 @@ msgstr ""
msgid "Deploying to AWS is easy with GitLab"
msgstr ""
+msgid "Deployment"
+msgstr ""
+
msgid "Deployment Frequency"
msgstr ""
+msgid "Deployment Target|Project deployment target (optional)"
+msgstr ""
+
+msgid "Deployment Target|Select the deployment target"
+msgstr ""
+
msgid "Deployment frequency"
msgstr ""
+msgid "DeploymentTarget|GitLab Pages"
+msgstr ""
+
+msgid "DeploymentTarget|Heroku"
+msgstr ""
+
+msgid "DeploymentTarget|Infrastructure provider (Terraform, Cloudformation, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Kubernetes (GKE, EKS, OpenShift, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Managed container runtime (Fargate, Cloud Run, DigitalOcean App)"
+msgstr ""
+
+msgid "DeploymentTarget|Mobile app store"
+msgstr ""
+
+msgid "DeploymentTarget|No deployment planned"
+msgstr ""
+
+msgid "DeploymentTarget|Other hosting service"
+msgstr ""
+
+msgid "DeploymentTarget|Registry (package or container)"
+msgstr ""
+
+msgid "DeploymentTarget|Self-managed container runtime (Podman, Docker Swarm, Docker Compose)"
+msgstr ""
+
+msgid "DeploymentTarget|Serverless backend (Lambda, Cloud functions)"
+msgstr ""
+
+msgid "DeploymentTarget|Virtual machine (for example, EC2)"
+msgstr ""
+
msgid "Deployments"
msgstr ""
@@ -12107,6 +12289,9 @@ msgstr ""
msgid "Deployment|This deployment was created using the API"
msgstr ""
+msgid "Deployment|Triggerer"
+msgstr ""
+
msgid "Deployment|Waiting"
msgstr ""
@@ -12134,6 +12319,18 @@ msgstr ""
msgid "Deprecated API rate limits"
msgstr ""
+msgid "Deprecations|Feature deprecation and removal"
+msgstr ""
+
+msgid "Deprecations|For information on a possible replacement %{epicStart} learn more about Opstrace %{epicEnd}."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7 and are %{epicStart} scheduled for removal %{epicEnd} in GitLab 15.0."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7, and are %{removal_link_start} scheduled for removal %{link_end} in GitLab 15.0. For information on a possible replacement, %{opstrace_link_start} learn more about Opstrace %{link_end}."
+msgstr ""
+
msgid "Deprioritize label"
msgstr ""
@@ -12379,10 +12576,10 @@ msgstr ""
msgid "DevopsAdoption|At least one deploy"
msgstr ""
-msgid "DevopsAdoption|At least one issue opened"
+msgid "DevopsAdoption|At least one issue created"
msgstr ""
-msgid "DevopsAdoption|At least one merge request opened"
+msgid "DevopsAdoption|At least one merge request created"
msgstr ""
msgid "DevopsAdoption|At least one pipeline successfully run"
@@ -12583,6 +12780,9 @@ msgstr ""
msgid "Direct member"
msgstr ""
+msgid "Direct members"
+msgstr ""
+
msgid "Direct non-authenticated users to this page."
msgstr ""
@@ -12699,6 +12899,9 @@ msgid_plural "Dismiss %d selected vulnerabilities as"
msgstr[0] ""
msgstr[1] ""
+msgid "Dismiss Alert"
+msgstr ""
+
msgid "Dismiss merge request promotion"
msgstr ""
@@ -12726,9 +12929,15 @@ msgstr ""
msgid "Display alerts from all configured monitoring tools."
msgstr ""
+msgid "Display milestones"
+msgstr ""
+
msgid "Display name"
msgstr ""
+msgid "Display progress of child issues"
+msgstr ""
+
msgid "Display rendered file"
msgstr ""
@@ -12834,6 +13043,9 @@ msgstr ""
msgid "Download image"
msgstr ""
+msgid "Download payload"
+msgstr ""
+
msgid "Download raw data (.csv)"
msgstr ""
@@ -13011,6 +13223,9 @@ msgstr ""
msgid "Edit in Web IDE"
msgstr ""
+msgid "Edit in pipeline editor"
+msgstr ""
+
msgid "Edit in single-file editor"
msgstr ""
@@ -13053,6 +13268,9 @@ msgstr ""
msgid "Edit your most recent comment in a thread (from an empty textarea)"
msgstr ""
+msgid "Edit, lint, and visualize your pipeline."
+msgstr ""
+
msgid "Edited"
msgstr ""
@@ -13494,6 +13712,9 @@ msgstr ""
msgid "Enforce two-factor authentication for all user sign-ins."
msgstr ""
+msgid "Enhance security by storing service account keys in secret managers - learn more about %{docLinkStart}secret management with GitLab%{docLinkEnd}"
+msgstr ""
+
msgid "Ensure connectivity is available from the GitLab server to the Prometheus server"
msgstr ""
@@ -13554,6 +13775,9 @@ 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 following to confirm:"
+msgstr ""
+
msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
@@ -14084,9 +14308,6 @@ 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 ""
@@ -14222,6 +14443,9 @@ msgstr ""
msgid "Errors:"
msgstr ""
+msgid "Escalate this incident"
+msgstr ""
+
msgid "Escalation Policies"
msgstr ""
@@ -14234,6 +14458,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy"
+msgstr ""
+
msgid "Escalation policy:"
msgstr ""
@@ -14485,6 +14712,9 @@ msgstr ""
msgid "Existing sign in methods may be removed"
msgstr ""
+msgid "Exit."
+msgstr ""
+
msgid "Expand"
msgstr ""
@@ -14581,6 +14811,9 @@ msgstr ""
msgid "Explore public groups"
msgstr ""
+msgid "Explore public projects"
+msgstr ""
+
msgid "Explore snippets"
msgstr ""
@@ -14742,7 +14975,7 @@ msgid_plural "Failed to archive designs. Please try again."
msgstr[0] ""
msgstr[1] ""
-msgid "Failed to assign a reviewer because no user was found."
+msgid "Failed to assign a reviewer because no user was specified."
msgstr ""
msgid "Failed to assign a user because no user was found."
@@ -14808,10 +15041,10 @@ msgstr ""
msgid "Failed to find import label for Jira import."
msgstr ""
-msgid "Failed to generate export, please try again later."
+msgid "Failed to find users for %{missing}"
msgstr ""
-msgid "Failed to generate report, please try again after sometime"
+msgid "Failed to generate export, please try again later."
msgstr ""
msgid "Failed to get ref."
@@ -14910,6 +15143,9 @@ msgstr ""
msgid "Failed to remove a to-do item for the design."
msgstr ""
+msgid "Failed to remove attention because no user was found."
+msgstr ""
+
msgid "Failed to remove mirror."
msgstr ""
@@ -14922,6 +15158,9 @@ msgstr ""
msgid "Failed to remove user key."
msgstr ""
+msgid "Failed to request attention because no user was found."
+msgstr ""
+
msgid "Failed to reset key. Please try again."
msgstr ""
@@ -15003,6 +15242,9 @@ msgstr ""
msgid "Feature Flags"
msgstr ""
+msgid "Feature deprecation and removal"
+msgstr ""
+
msgid "Feature flag status"
msgstr ""
@@ -15500,7 +15742,7 @@ msgstr ""
msgid "For each job, re-use the project workspace. If the workspace doesn't exist, use %{code_open}git clone%{code_close}."
msgstr ""
-msgid "For example, the application using the token or the purpose of the token."
+msgid "For example, the application using the token or the purpose of the token. Do not give sensitive information for the name of the token, as it will be visible to all %{resource_type} members."
msgstr ""
msgid "For files larger than this limit, only index the file name. The file content is neither indexed nor searchable."
@@ -15584,9 +15826,6 @@ msgstr ""
msgid "ForkProject|Select a namespace"
msgstr ""
-msgid "ForkProject|Select a namespace to fork the project"
-msgstr ""
-
msgid "ForkProject|The project can be accessed by any logged in user."
msgstr ""
@@ -15683,6 +15922,9 @@ msgstr ""
msgid "Full name"
msgstr ""
+msgid "GCP region configured"
+msgstr ""
+
msgid "GPG Key ID:"
msgstr ""
@@ -15863,6 +16105,9 @@ msgstr ""
msgid "Geo|Failed"
msgstr ""
+msgid "Geo|Filter Geo sites"
+msgstr ""
+
msgid "Geo|Filter by name"
msgstr ""
@@ -16274,6 +16519,12 @@ msgstr ""
msgid "GitLab Issue"
msgstr ""
+msgid "GitLab KAS"
+msgstr ""
+
+msgid "GitLab Memberships CSV Export"
+msgstr ""
+
msgid "GitLab Pages"
msgstr ""
@@ -16322,6 +16573,9 @@ 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 free to use. Many features for larger teams are part of our %{link_start}paid products%{link_end}. You can try Ultimate for free without any obligation or payment details."
+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 ""
@@ -16448,7 +16702,7 @@ msgstr ""
msgid "GitLabPages|When enabled, all attempts to visit your website through HTTP are automatically redirected to HTTPS using a response with status code 301. Requires a valid certificate for all domains. %{docs_link_start}Learn more.%{link_end}"
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. %{docs_link_start}Learn more.%{link_end}"
+msgid "GitLabPages|When using Pages under the general domain of a GitLab instance (%{pages_host}), you cannot use HTTPS with subdomains of subdomains. If your namespace or groupname contains a dot, it does not work. This is a limitation of the HTTP Over TLS protocol. HTTP pages work if you don't redirect HTTP to HTTPS. %{docs_link_start}Learn more.%{link_end}"
msgstr ""
msgid "GitLabPages|With GitLab Pages you can host your static website directly from your GitLab repository. %{docs_link_start}Learn more.%{link_end}"
@@ -16625,9 +16879,6 @@ msgstr ""
msgid "Go to find file"
msgstr ""
-msgid "Go to fork"
-msgstr ""
-
msgid "Go to issue boards"
msgstr ""
@@ -16835,9 +17086,6 @@ msgstr ""
msgid "Group Hooks"
msgstr ""
-msgid "Group ID"
-msgstr ""
-
msgid "Group Owner must have signed in with SAML before enabling Group Managed Accounts"
msgstr ""
@@ -16865,9 +17113,6 @@ msgstr ""
msgid "Group by"
msgstr ""
-msgid "Group description"
-msgstr ""
-
msgid "Group description (optional)"
msgstr ""
@@ -16982,7 +17227,7 @@ msgstr ""
msgid "Group: %{name}"
msgstr ""
-msgid "GroupActivityMetrics|Issues opened"
+msgid "GroupActivityMetrics|Issues created"
msgstr ""
msgid "GroupActivityMetrics|Last 90 days"
@@ -16991,7 +17236,7 @@ msgstr ""
msgid "GroupActivityMetrics|Members added"
msgstr ""
-msgid "GroupActivityMetrics|Merge Requests opened"
+msgid "GroupActivityMetrics|Merge Requests created"
msgstr ""
msgid "GroupActivityMetrics|Recent activity"
@@ -17282,6 +17527,9 @@ msgstr ""
msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
+msgid "GroupSettings|Choose a group path that does not start with a dash or end with a period. It can also contain alphanumeric characters and underscores."
+msgstr ""
+
msgid "GroupSettings|Compliance frameworks"
msgstr ""
@@ -17315,7 +17563,7 @@ msgstr ""
msgid "GroupSettings|If not specified at the group or instance level, the default is %{default_initial_branch_name}. Does not affect existing repositories."
msgstr ""
-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."
+msgid "GroupSettings|If the parent group's visibility is lower than the group's current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility."
msgstr ""
msgid "GroupSettings|New runners registration token has been generated!"
@@ -17432,7 +17680,10 @@ msgstr ""
msgid "Groups and projects"
msgstr ""
-msgid "Groups and subgroups"
+msgid "Groups are a great way to organize projects and people."
+msgstr ""
+
+msgid "Groups are the best way to manage projects and members."
msgstr ""
msgid "Groups to synchronize"
@@ -17543,13 +17794,16 @@ msgstr ""
msgid "GroupsTree|Are you sure you want to leave the \"%{fullName}\" group?"
msgstr ""
-msgid "GroupsTree|Edit group"
+msgid "GroupsTree|Delete"
+msgstr ""
+
+msgid "GroupsTree|Edit"
msgstr ""
msgid "GroupsTree|Failed to leave the group. Please make sure you are not the only owner."
msgstr ""
-msgid "GroupsTree|Leave this group"
+msgid "GroupsTree|Leave group"
msgstr ""
msgid "GroupsTree|Loading groups"
@@ -17561,9 +17815,57 @@ msgstr ""
msgid "GroupsTree|No groups or projects matched your search"
msgstr ""
+msgid "GroupsTree|Options"
+msgstr ""
+
msgid "GroupsTree|Search by name"
msgstr ""
+msgid "Groups|Avatar will be removed. Are you sure?"
+msgstr ""
+
+msgid "Groups|Changing group URL can have unintended side effects."
+msgstr ""
+
+msgid "Groups|Checking group URL availability..."
+msgstr ""
+
+msgid "Groups|Enter a descriptive name for your group."
+msgstr ""
+
+msgid "Groups|Group ID"
+msgstr ""
+
+msgid "Groups|Group URL"
+msgstr ""
+
+msgid "Groups|Group avatar"
+msgstr ""
+
+msgid "Groups|Group description (optional)"
+msgstr ""
+
+msgid "Groups|Group name"
+msgstr ""
+
+msgid "Groups|Group path is available."
+msgstr ""
+
+msgid "Groups|Group path is unavailable. Path has been replaced with a suggested available path."
+msgstr ""
+
+msgid "Groups|Learn more"
+msgstr ""
+
+msgid "Groups|Must start with letter, digit, emoji, or underscore. Can also contain periods, dashes, spaces, and parentheses."
+msgstr ""
+
+msgid "Groups|Remove avatar"
+msgstr ""
+
+msgid "Groups|Save changes"
+msgstr ""
+
msgid "Guideline"
msgstr ""
@@ -17573,6 +17875,9 @@ msgstr ""
msgid "HAR file path or URL"
msgstr ""
+msgid "HTTP Archive (HAR)"
+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 ""
@@ -17973,6 +18278,9 @@ msgstr ""
msgid "INFO: Your SSH key is expiring soon. Please generate a new key."
msgstr ""
+msgid "IP"
+msgstr ""
+
msgid "IP Address"
msgstr ""
@@ -18009,6 +18317,9 @@ msgstr ""
msgid "IdentityVerification|Verify your identity"
msgstr ""
+msgid "IdentityVerification|You can always verify your account at a later time to create a group."
+msgstr ""
+
msgid "If any indexed field exceeds this limit, it is truncated to this number of characters. The rest of the content is neither indexed nor searchable. This does not apply to repository and wiki indexing. For unlimited characters, set this to 0."
msgstr ""
@@ -18066,6 +18377,9 @@ msgstr ""
msgid "If you add %{codeStart}needs%{codeEnd} to jobs in your pipeline you'll be able to view the %{codeStart}needs%{codeEnd} relationships between jobs in this tab as a %{linkStart}Directed Acyclic Graph (DAG)%{linkEnd}."
msgstr ""
+msgid "If you are added to a project, it will be displayed here."
+msgstr ""
+
msgid "If you did not initiate these sign-in attempts, please reach out to your administrator or enable two-factor authentication (2FA) on your account."
msgstr ""
@@ -18372,12 +18686,24 @@ msgstr ""
msgid "InProductMarketing|3 ways to dive into GitLab CI/CD"
msgstr ""
+msgid "InProductMarketing|A single application eliminates complex integrations, data chokepoints, and toolchain maintenance, resulting in greater productivity and lower cost."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features, build more efficiently, strengthen security and compliance."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features."
+msgstr ""
+
msgid "InProductMarketing|Actually, GitLab makes the team work (better)"
msgstr ""
msgid "InProductMarketing|And finally %{deploy_link} a Python application."
msgstr ""
+msgid "InProductMarketing|And many more..."
+msgstr ""
+
msgid "InProductMarketing|Are your runners ready?"
msgstr ""
@@ -18396,15 +18722,33 @@ msgstr ""
msgid "InProductMarketing|Blog"
msgstr ""
+msgid "InProductMarketing|Break down silos to coordinate seamlessly across development, operations, and security with a consistent experience across the development lifecycle."
+msgstr ""
+
+msgid "InProductMarketing|Burn up/down charts"
+msgstr ""
+
msgid "InProductMarketing|By enabling code owners and required merge approvals the right person will review the right MR. This is a win-win: cleaner code and a more efficient review process."
msgstr ""
msgid "InProductMarketing|Click on the number below that corresponds with your answer — 1 being very difficult, 5 being very easy."
msgstr ""
+msgid "InProductMarketing|Code owners"
+msgstr ""
+
msgid "InProductMarketing|Code owners and required merge approvals are part of the paid tiers of GitLab. You can start a free 30-day trial of GitLab Ultimate and enable these features in less than 5 minutes with no credit card required."
msgstr ""
+msgid "InProductMarketing|Code review analytics"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration across stages in GitLab"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration made easy"
+msgstr ""
+
msgid "InProductMarketing|Create a custom CI runner with just a few clicks"
msgstr ""
@@ -18414,12 +18758,21 @@ msgstr ""
msgid "InProductMarketing|Create a project in GitLab in 5 minutes"
msgstr ""
+msgid "InProductMarketing|Create well-defined workflows by using scoped labels on issues, merge requests, and epics. Labels with the same scope cannot be used together, which prevents conflicts."
+msgstr ""
+
msgid "InProductMarketing|Create your first project!"
msgstr ""
+msgid "InProductMarketing|Define who owns specific files or directories, so the right reviewers are suggested when a merge request introduces changes to those files."
+msgstr ""
+
msgid "InProductMarketing|Deliver Better Products Faster"
msgstr ""
+msgid "InProductMarketing|Dependency scanning"
+msgstr ""
+
msgid "InProductMarketing|Did you know teams that use GitLab are far more efficient?"
msgstr ""
@@ -18429,15 +18782,27 @@ msgstr ""
msgid "InProductMarketing|Dig in and create a project and a repo"
msgstr ""
+msgid "InProductMarketing|Discover Premium & Ultimate"
+msgstr ""
+
+msgid "InProductMarketing|Discover Premium & Ultimate."
+msgstr ""
+
msgid "InProductMarketing|Do you have a minute?"
msgstr ""
msgid "InProductMarketing|Do you have a teammate who would be perfect for this task?"
msgstr ""
+msgid "InProductMarketing|Dynamic application security testing"
+msgstr ""
+
msgid "InProductMarketing|Easy"
msgstr ""
+msgid "InProductMarketing|Epics"
+msgstr ""
+
msgid "InProductMarketing|Expand your DevOps journey with a free GitLab trial"
msgstr ""
@@ -18459,9 +18824,15 @@ msgstr ""
msgid "InProductMarketing|Feel the need for speed?"
msgstr ""
+msgid "InProductMarketing|Find and fix bottlenecks in your code review process by understanding how long open merge requests have been in review."
+msgstr ""
+
msgid "InProductMarketing|Find out how your teams are really doing"
msgstr ""
+msgid "InProductMarketing|Find out if your external libraries are safe. Run dependency scanning jobs that check for known vulnerabilities in your external libraries."
+msgstr ""
+
msgid "InProductMarketing|Follow our steps"
msgstr ""
@@ -18498,6 +18869,9 @@ msgstr ""
msgid "InProductMarketing|GitLab is better with teammates to help out!"
msgstr ""
+msgid "InProductMarketing|GitLab is infrastructure agnostic (supporting GCP, AWS, Azure, OpenShift, VMWare, On Prem, Bare Metal, and more), offering a consistent workflow experience – irrespective of the environment."
+msgstr ""
+
msgid "InProductMarketing|GitLab provides static application security testing (SAST), dynamic application security testing (DAST), container scanning, and dependency scanning to help you deliver secure applications along with license compliance."
msgstr ""
@@ -18588,21 +18962,36 @@ msgstr ""
msgid "InProductMarketing|It's also possible to simply %{external_repo_link} in order to take advantage of GitLab's CI/CD."
msgstr ""
+msgid "InProductMarketing|Keep your code quality high by defining who should approve merge requests and how many approvals are required."
+msgstr ""
+
msgid "InProductMarketing|Launch GitLab CI/CD in 20 minutes or less"
msgstr ""
+msgid "InProductMarketing|Lower cost of development"
+msgstr ""
+
+msgid "InProductMarketing|Make it easier to collaborate on high-level ideas by grouping related issues in an epic."
+msgstr ""
+
msgid "InProductMarketing|Making the switch? It's easier than you think to import your projects into GitLab. Move %{github_link}, or import something %{bitbucket_link}."
msgstr ""
msgid "InProductMarketing|Master the art of importing!"
msgstr ""
+msgid "InProductMarketing|Merge request approval rule"
+msgstr ""
+
msgid "InProductMarketing|Move on to easily creating a Pages website %{ci_template_link}"
msgstr ""
msgid "InProductMarketing|Multiple owners, confusing workstreams? We've got you covered"
msgstr ""
+msgid "InProductMarketing|Multiple required approvers"
+msgstr ""
+
msgid "InProductMarketing|Need an alternative to importing?"
msgstr ""
@@ -18615,18 +19004,33 @@ msgstr ""
msgid "InProductMarketing|Our tool brings all the things together"
msgstr ""
+msgid "InProductMarketing|Protect your web application by using DAST to examine for vulnerabilities in deployed environments."
+msgstr ""
+
msgid "InProductMarketing|Rapid development, simplified"
msgstr ""
msgid "InProductMarketing|Reduce Security & Compliance Risk"
msgstr ""
+msgid "InProductMarketing|Require multiple approvers on a merge request, so you know it's in good shape before it's merged."
+msgstr ""
+
+msgid "InProductMarketing|Roadmaps"
+msgstr ""
+
+msgid "InProductMarketing|Scoped labels"
+msgstr ""
+
msgid "InProductMarketing|Security that's integrated into your development lifecycle"
msgstr ""
msgid "InProductMarketing|Sometimes you're not ready to make a full transition to a new tool. If you're not ready to fully commit, %{mirroring_link} gives you a safe way to try out GitLab in parallel with your current tool."
msgstr ""
+msgid "InProductMarketing|Speed. Efficiency. Trust."
+msgstr ""
+
msgid "InProductMarketing|Spin up an autoscaling runner in GitLab"
msgstr ""
@@ -18636,6 +19040,9 @@ msgstr ""
msgid "InProductMarketing|Start a Self-Managed trial"
msgstr ""
+msgid "InProductMarketing|Start a free trial"
+msgstr ""
+
msgid "InProductMarketing|Start a free trial of GitLab Ultimate – no credit card required"
msgstr ""
@@ -18702,6 +19109,9 @@ msgstr ""
msgid "InProductMarketing|To understand and get the most out of GitLab, start at the beginning and %{project_link}. In GitLab, repositories are part of a project, so after you've created your project you can go ahead and %{repo_link}."
msgstr ""
+msgid "InProductMarketing|Track completed issues in a chart, so you can see how a milestone is progressing at a glance."
+msgstr ""
+
msgid "InProductMarketing|Try GitLab Ultimate for free"
msgstr ""
@@ -18738,6 +19148,9 @@ msgstr ""
msgid "InProductMarketing|Very easy"
msgstr ""
+msgid "InProductMarketing|Visualize your epics and milestones in a timeline."
+msgstr ""
+
msgid "InProductMarketing|Want to host GitLab on your servers?"
msgstr ""
@@ -18759,6 +19172,9 @@ msgstr ""
msgid "InProductMarketing|YouTube"
msgstr ""
+msgid "InProductMarketing|Your software, deployed your way"
+msgstr ""
+
msgid "InProductMarketing|Your teams can be more efficient"
msgstr ""
@@ -18879,9 +19295,18 @@ msgstr ""
msgid "IncidentManagement|No incidents to display."
msgstr ""
+msgid "IncidentManagement|None"
+msgstr ""
+
msgid "IncidentManagement|Open"
msgstr ""
+msgid "IncidentManagement|Page your team with escalation policies"
+msgstr ""
+
+msgid "IncidentManagement|Paged"
+msgstr ""
+
msgid "IncidentManagement|Published"
msgstr ""
@@ -18891,6 +19316,9 @@ msgstr ""
msgid "IncidentManagement|Severity"
msgstr ""
+msgid "IncidentManagement|Status"
+msgstr ""
+
msgid "IncidentManagement|There are no closed incidents"
msgstr ""
@@ -18909,6 +19337,9 @@ msgstr ""
msgid "IncidentManagement|Unpublished"
msgstr ""
+msgid "IncidentManagement|Use escalation policies to automatically page your team when incidents are created."
+msgstr ""
+
msgid "IncidentSettings|Activate \"time to SLA\" countdown timer"
msgstr ""
@@ -18954,7 +19385,10 @@ msgstr ""
msgid "Incidents"
msgstr ""
-msgid "Incidents|Add a URL"
+msgid "Incidents|Add image details"
+msgstr ""
+
+msgid "Incidents|Add text or a link to display with your image. If you don't add either, the file name displays instead."
msgstr ""
msgid "Incidents|Drop or %{linkStart}upload%{linkEnd} a metric screenshot to attach it to the incident"
@@ -18969,10 +19403,10 @@ msgstr ""
msgid "Incidents|There was an issue loading metric images."
msgstr ""
-msgid "Incidents|There was an issue uploading your image."
+msgid "Incidents|There was an issue updating your image."
msgstr ""
-msgid "Incidents|You can optionally add a URL to link users to the original graph."
+msgid "Incidents|There was an issue uploading your image."
msgstr ""
msgid "Incident|Alert details"
@@ -18981,9 +19415,18 @@ msgstr ""
msgid "Incident|Are you sure you wish to delete this image?"
msgstr ""
+msgid "Incident|Delete image"
+msgstr ""
+
msgid "Incident|Deleting %{filename}"
msgstr ""
+msgid "Incident|Edit image text or link"
+msgstr ""
+
+msgid "Incident|Editing %{filename}"
+msgstr ""
+
msgid "Incident|Metrics"
msgstr ""
@@ -19253,12 +19696,18 @@ msgstr ""
msgid "Integrations|Branches for which notifications are to be sent"
msgstr ""
+msgid "Integrations|Clear if using a self-signed certificate."
+msgstr ""
+
msgid "Integrations|Comment detail:"
msgstr ""
msgid "Integrations|Comment settings:"
msgstr ""
+msgid "Integrations|Connection details"
+msgstr ""
+
msgid "Integrations|Connection failed. Please check your settings."
msgstr ""
@@ -19283,6 +19732,9 @@ msgstr ""
msgid "Integrations|Enable GitLab.com slash commands in a Slack workspace."
msgstr ""
+msgid "Integrations|Enable SSL verification"
+msgstr ""
+
msgid "Integrations|Enable comments"
msgstr ""
@@ -19361,6 +19813,9 @@ msgstr ""
msgid "Integrations|Return to GitLab for Jira"
msgstr ""
+msgid "Integrations|SSL verification"
+msgstr ""
+
msgid "Integrations|Save settings?"
msgstr ""
@@ -19406,9 +19861,6 @@ msgstr ""
msgid "Integrations|Use default settings"
msgstr ""
-msgid "Integrations|When you mention a Jira issue in a commit or merge request, GitLab creates a remote link and comment (if enabled)."
-msgstr ""
-
msgid "Integrations|You can now close this window and return to the GitLab for Jira application."
msgstr ""
@@ -19433,9 +19885,6 @@ msgstr ""
msgid "Integrations|can't exceed %{recipients_limit}"
msgstr ""
-msgid "Interactive developer security education."
-msgstr ""
-
msgid "Interactive mode"
msgstr ""
@@ -19925,6 +20374,9 @@ msgstr ""
msgid "IssueAnalytics|Assignees"
msgstr ""
+msgid "IssueAnalytics|Created by"
+msgstr ""
+
msgid "IssueAnalytics|Due date"
msgstr ""
@@ -19937,9 +20389,6 @@ msgstr ""
msgid "IssueAnalytics|Milestone"
msgstr ""
-msgid "IssueAnalytics|Opened by"
-msgstr ""
-
msgid "IssueAnalytics|Status"
msgstr ""
@@ -20063,10 +20512,10 @@ msgstr ""
msgid "IssuesAnalytics|Avg/Month:"
msgstr ""
-msgid "IssuesAnalytics|Issues opened"
+msgid "IssuesAnalytics|Issues created"
msgstr ""
-msgid "IssuesAnalytics|Issues opened per month"
+msgid "IssuesAnalytics|Issues created per month"
msgstr ""
msgid "IssuesAnalytics|Last 12 months"
@@ -20093,6 +20542,9 @@ msgstr ""
msgid "It looks like you have some draft commits in this branch."
msgstr ""
+msgid "It looks like you're attempting to activate your subscription. Use %{a_start}the Subscription page%{a_end} instead."
+msgstr ""
+
msgid "It may be several days before you see feature usage data."
msgstr ""
@@ -20321,6 +20773,9 @@ msgstr ""
msgid "JiraConnect|You can now close this window and return to Jira."
msgstr ""
+msgid "JiraConnect|You don't have permission to create branches for this project. Select a different project or contact the project owner for access. %{linkStart}Learn more.%{linkEnd}"
+msgstr ""
+
msgid "JiraRequest|A connection error occurred while connecting to Jira. Try your request again."
msgstr ""
@@ -20369,13 +20824,13 @@ msgstr ""
msgid "JiraService|Define the type of Jira issue to create from a vulnerability."
msgstr ""
-msgid "JiraService|Displaying Jira issues while leaving the GitLab issue functionality enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
+msgid "JiraService|Displaying Jira issues while leaving GitLab issues also enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
msgstr ""
-msgid "JiraService|Enable Jira issues"
+msgid "JiraService|Enable Jira issue creation from vulnerabilities"
msgstr ""
-msgid "JiraService|Enable Jira issues creation from vulnerabilities"
+msgid "JiraService|Enable Jira issues"
msgstr ""
msgid "JiraService|Enable Jira transitions"
@@ -20492,16 +20947,19 @@ msgstr ""
msgid "JiraService|View Jira issues in GitLab"
msgstr ""
-msgid "JiraService|Warning: All GitLab users that have access to this GitLab project are able to view all issues from the Jira project specified below."
+msgid "JiraService|Warning: All GitLab users with access to this GitLab project can view all issues from the Jira project you select."
msgstr ""
msgid "JiraService|Web URL"
msgstr ""
-msgid "JiraService|Work on Jira issues without leaving GitLab. Adds a Jira menu to access your list of Jira issues and view any issue as read-only."
+msgid "JiraService|When a Jira issue is mentioned in a commit or merge request, a remote link and comment (if enabled) will be created."
+msgstr ""
+
+msgid "JiraService|Work on Jira issues without leaving GitLab. Add a Jira menu to access a read-only list of your Jira issues."
msgstr ""
-msgid "JiraService|You need to configure Jira before enabling this integration. For more details, read the %{jira_doc_link_start}Jira integration documentation%{link_end}."
+msgid "JiraService|You must configure Jira before enabling this integration. %{jira_doc_link_start}Learn more.%{link_end}"
msgstr ""
msgid "Job"
@@ -20513,9 +20971,6 @@ msgstr ""
msgid "Job Failed #%{build_id}"
msgstr ""
-msgid "Job ID"
-msgstr ""
-
msgid "Job artifact"
msgstr ""
@@ -20582,9 +21037,27 @@ msgstr ""
msgid "Jobs|You're about to retry a job that failed because it attempted to deploy code that is older than the latest deployment. Retrying this job could result in overwriting the environment with the older source code."
msgstr ""
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source} into %{target}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{ref}"
+msgstr ""
+
+msgid "Job|Are you sure you want to erase this job log and artifacts?"
+msgstr ""
+
msgid "Job|Browse"
msgstr ""
+msgid "Job|Cancel"
+msgstr ""
+
msgid "Job|Complete Raw"
msgstr ""
@@ -20594,6 +21067,9 @@ msgstr ""
msgid "Job|Erase job log and artifacts"
msgstr ""
+msgid "Job|Finished at"
+msgstr ""
+
msgid "Job|Job artifacts"
msgstr ""
@@ -20606,7 +21082,7 @@ msgstr ""
msgid "Job|Keep"
msgstr ""
-msgid "Job|Pipeline"
+msgid "Job|Retry"
msgstr ""
msgid "Job|Scroll to bottom"
@@ -20618,6 +21094,9 @@ msgstr ""
msgid "Job|Show complete raw"
msgstr ""
+msgid "Job|Status"
+msgstr ""
+
msgid "Job|The artifacts were removed"
msgstr ""
@@ -20645,21 +21124,12 @@ msgstr ""
msgid "Job|delayed"
msgstr ""
-msgid "Job|for"
-msgstr ""
-
-msgid "Job|into"
-msgstr ""
-
msgid "Job|manual"
msgstr ""
msgid "Job|triggered"
msgstr ""
-msgid "Job|with"
-msgstr ""
-
msgid "Join Zoom meeting"
msgstr ""
@@ -20762,9 +21232,6 @@ msgstr ""
msgid "Ki"
msgstr ""
-msgid "Kontra"
-msgstr ""
-
msgid "Kroki"
msgstr ""
@@ -21088,6 +21555,9 @@ msgstr ""
msgid "Learn more about Auto DevOps"
msgstr ""
+msgid "Learn more about GitLab"
+msgstr ""
+
msgid "Learn more about Needs relationships"
msgstr ""
@@ -21415,9 +21885,18 @@ msgstr ""
msgid "Licenses|Displays licenses detected in the project, based on the %{linkStart}latest successful%{linkEnd} scan"
msgstr ""
+msgid "Licenses|Drag your license file here or %{linkStart}click to upload%{linkEnd}."
+msgstr ""
+
+msgid "Licenses|Drop your license file to start the upload."
+msgstr ""
+
msgid "Licenses|Error fetching the license list. Please check your network connection and try again."
msgstr ""
+msgid "Licenses|Error: You are trying to upload something other than a file"
+msgstr ""
+
msgid "Licenses|License Compliance"
msgstr ""
@@ -21436,6 +21915,9 @@ msgstr ""
msgid "Licenses|Specified policies in this project"
msgstr ""
+msgid "Licenses|The file could not be uploaded."
+msgstr ""
+
msgid "Licenses|The license list details information about the licenses used within your project."
msgstr ""
@@ -21469,11 +21951,6 @@ msgstr ""
msgid "Limit the size of Sidekiq jobs stored in Redis."
msgstr ""
-msgid "Limited to showing %d event at most"
-msgid_plural "Limited to showing %d events at most"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Limiting mode"
msgstr ""
@@ -21483,6 +21960,9 @@ msgstr ""
msgid "Link"
msgstr ""
+msgid "Link (optional)"
+msgstr ""
+
msgid "Link Prometheus monitoring to GitLab."
msgstr ""
@@ -21519,6 +21999,9 @@ msgstr ""
msgid "Linked emails (%{email_count})"
msgstr ""
+msgid "Linked epics"
+msgstr ""
+
msgid "Linked issues"
msgstr ""
@@ -21546,6 +22029,15 @@ msgstr ""
msgid "List of all merge commits"
msgstr ""
+msgid "List of environments for this project"
+msgstr ""
+
+msgid "List of suitable GCP locations"
+msgstr ""
+
+msgid "List of users allowed to exceed the rate limit."
+msgstr ""
+
msgid "List options"
msgstr ""
@@ -21765,6 +22257,9 @@ msgstr ""
msgid "Maintenance mode"
msgstr ""
+msgid "Make adjustments to how your GitLab instance is set up."
+msgstr ""
+
msgid "Make and review changes in the browser with the Web IDE"
msgstr ""
@@ -21909,6 +22404,12 @@ msgstr ""
msgid "MarkdownEditor|Add italic text (%{modifier_key}I)"
msgstr ""
+msgid "MarkdownEditor|Add strikethrough text (%{modifierKey}⇧X)"
+msgstr ""
+
+msgid "MarkdownEditor|Add strikethrough text (%{modifier_key}⇧X)"
+msgstr ""
+
msgid "Marked For Deletion At - %{deletion_time}"
msgstr ""
@@ -22170,6 +22671,9 @@ msgstr ""
msgid "Maximum push size (MB)"
msgstr ""
+msgid "Maximum requests per 10 minutes per user"
+msgstr ""
+
msgid "Maximum requests per minute"
msgstr ""
@@ -22260,6 +22764,19 @@ msgstr ""
msgid "Members of a group may only view projects they have permission to access"
msgstr ""
+msgid "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seat in use and will be billed for the overage."
+msgid_plural "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seats in use and will be billed for the overage."
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "MembersOverage|You are about to incur additional charges"
+msgstr ""
+
+msgid "MembersOverage|Your subscription includes %d seat."
+msgid_plural "MembersOverage|Your subscription includes %d seats."
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Membership"
msgstr ""
@@ -22464,9 +22981,6 @@ msgstr ""
msgid "Merge request not merged"
msgstr ""
-msgid "Merge request pipelines 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 merge request pipelines."
-msgstr ""
-
msgid "Merge request reports"
msgstr ""
@@ -22563,13 +23077,13 @@ msgstr ""
msgid "MergeRequests|Create issue to resolve thread"
msgstr ""
-msgid "MergeRequests|Failed to squash. Should be done manually."
+msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Saving the comment failed"
+msgid "MergeRequests|Squashing failed: Squash the commits locally, resolve any conflicts, then push the branch."
msgstr ""
-msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
+msgid "MergeRequests|Squashing not allowed: This project doesn't allow you to squash commits when merging."
msgstr ""
msgid "MergeRequests|Thread stays resolved"
@@ -23410,6 +23924,18 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "MrList|Assigned to %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from assignee %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from reviewer %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Review requested from %{name}, go to their profile."
+msgstr ""
+
msgid "Multi-project"
msgstr ""
@@ -23443,7 +23969,7 @@ msgstr ""
msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "My Awesome Group"
+msgid "My awesome group"
msgstr ""
msgid "My company or team"
@@ -24065,9 +24591,6 @@ msgstr ""
msgid "No available branches"
msgstr ""
-msgid "No available groups to fork the project."
-msgstr ""
-
msgid "No branches found"
msgstr ""
@@ -24278,6 +24801,9 @@ msgstr ""
msgid "No ref selected"
msgstr ""
+msgid "No regions configured"
+msgstr ""
+
msgid "No related merge requests found."
msgstr ""
@@ -25082,6 +25608,9 @@ msgstr ""
msgid "Only reCAPTCHA v2 is supported:"
msgstr ""
+msgid "Only required if not using role instance credentials."
+msgstr ""
+
msgid "Only use lowercase letters, numbers, and underscores."
msgstr ""
@@ -25106,9 +25635,6 @@ msgstr ""
msgid "Open a CLI and connect to the cluster you want to install the agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
-msgid "Open epics"
-msgstr ""
-
msgid "Open errors"
msgstr ""
@@ -25148,7 +25674,7 @@ msgstr ""
msgid "Opened issues"
msgstr ""
-msgid "OpenedNDaysAgo|Opened"
+msgid "OpenedNDaysAgo|Created"
msgstr ""
msgid "Opens in a new window"
@@ -25193,9 +25719,6 @@ msgstr ""
msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
-msgid "Optional."
-msgstr ""
-
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
msgstr ""
@@ -25984,6 +26507,9 @@ msgstr ""
msgid "PerformanceBar|Memory"
msgstr ""
+msgid "PerformanceBar|Memory report"
+msgstr ""
+
msgid "PerformanceBar|Redis calls"
msgstr ""
@@ -26017,18 +26543,12 @@ msgstr ""
msgid "PerformanceBar|wall"
msgstr ""
-msgid "Performs a rebase but skips triggering a new pipeline"
-msgstr ""
-
msgid "Period in seconds"
msgstr ""
msgid "Permalink"
msgstr ""
-msgid "Permanently delete project"
-msgstr ""
-
msgid "Permanently remove group"
msgstr ""
@@ -26299,6 +26819,51 @@ msgstr ""
msgid "PipelineStatusTooltip|Pipeline: %{ci_status}"
msgstr ""
+msgid "PipelineWizardDefaultCommitMessage|Add %{filename}"
+msgstr ""
+
+msgid "PipelineWizardDefaultCommitMessage|Update %{filename}"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|At least one entry is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This field is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This value is not valid"
+msgstr ""
+
+msgid "PipelineWizardListWidget|add another step"
+msgstr ""
+
+msgid "PipelineWizardListWidget|remove step"
+msgstr ""
+
+msgid "PipelineWizard|Commit"
+msgstr ""
+
+msgid "PipelineWizard|Commit Message"
+msgstr ""
+
+msgid "PipelineWizard|Commit changes to your file"
+msgstr ""
+
+msgid "PipelineWizard|Commit file to Branch"
+msgstr ""
+
+msgid "PipelineWizard|Commit your new file"
+msgstr ""
+
+msgid "PipelineWizard|The file has been committed."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem committing the changes."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem while checking whether your file already exists in the specified branch."
+msgstr ""
+
msgid "Pipelines"
msgstr ""
@@ -26413,7 +26978,7 @@ msgstr ""
msgid "Pipelines|Project cache successfully reset."
msgstr ""
-msgid "Pipelines|Revoke"
+msgid "Pipelines|Revoke trigger"
msgstr ""
msgid "Pipelines|Something went wrong while cleaning runners cache."
@@ -26458,6 +27023,12 @@ msgstr ""
msgid "Pipelines|This is a child pipeline within the parent pipeline"
msgstr ""
+msgid "Pipelines|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipelines|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipelines|This pipeline will run code originating from a forked project merge request. This means that the code can potentially have security considerations like exposing CI variables."
msgstr ""
@@ -26500,9 +27071,6 @@ msgstr ""
msgid "Pipelines|Your changes have been successfully committed. Now redirecting to the new merge request page."
msgstr ""
-msgid "Pipelines|detached"
-msgstr ""
-
msgid "Pipelines|error"
msgstr ""
@@ -26512,10 +27080,13 @@ msgstr ""
msgid "Pipelines|latest"
msgstr ""
-msgid "Pipelines|stuck"
+msgid "Pipelines|merge request"
msgstr ""
-msgid "Pipelines|train"
+msgid "Pipelines|merge train"
+msgstr ""
+
+msgid "Pipelines|stuck"
msgstr ""
msgid "Pipelines|yaml invalid"
@@ -26647,6 +27218,12 @@ msgstr ""
msgid "Pipeline|This change will not change the overall test coverage if merged."
msgstr ""
+msgid "Pipeline|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipeline|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipeline|Trigger author"
msgstr ""
@@ -26671,6 +27248,12 @@ msgstr ""
msgid "Pipeline|for"
msgstr ""
+msgid "Pipeline|merge request"
+msgstr ""
+
+msgid "Pipeline|merge train"
+msgstr ""
+
msgid "Pipeline|on"
msgstr ""
@@ -26809,9 +27392,6 @@ msgstr ""
msgid "Please enter a valid time interval"
msgstr ""
-msgid "Please enter or upload a valid license."
-msgstr ""
-
msgid "Please enter your current password."
msgstr ""
@@ -26920,9 +27500,6 @@ msgstr ""
msgid "Please type %{phrase_code} to proceed or close this modal to cancel."
msgstr ""
-msgid "Please type the following to confirm:"
-msgstr ""
-
msgid "Please use this form to report to the admin users who create spam issues, comments or behave inappropriately."
msgstr ""
@@ -26950,12 +27527,27 @@ msgstr ""
msgid "Policies"
msgstr ""
+msgid "Policy '%{escalation_policy_name}' does not exist."
+msgstr ""
+
msgid "Policy management project does have any policies in %{policy_path}"
msgstr ""
msgid "Policy project doesn't exist"
msgstr ""
+msgid "PolicyRuleMultiSelect|%{firstLabel} +%{numberOfAdditionalLabels} more"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|All %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select all"
+msgstr ""
+
msgid "Polling interval multiplier"
msgstr ""
@@ -27184,6 +27776,9 @@ msgstr ""
msgid "Private projects can be created in your personal namespace with:"
msgstr ""
+msgid "Problem with %{name} command: %{message}."
+msgstr ""
+
msgid "Proceed"
msgstr ""
@@ -27658,6 +28253,9 @@ msgstr ""
msgid "Progress"
msgstr ""
+msgid "Progress tracking"
+msgstr ""
+
msgid "Project"
msgstr ""
@@ -27889,6 +28487,9 @@ msgstr ""
msgid "ProjectQualitySummary|Failure"
msgstr ""
+msgid "ProjectQualitySummary|Get insight into the overall percentage of tests in your project that succeed, fail and are skipped."
+msgstr ""
+
msgid "ProjectQualitySummary|Latest pipeline results"
msgstr ""
@@ -27907,6 +28508,12 @@ msgstr ""
msgid "ProjectQualitySummary|See project Code Coverage Statistics"
msgstr ""
+msgid "ProjectQualitySummary|Set up test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|Set up test runs (opens in a new tab)"
+msgstr ""
+
msgid "ProjectQualitySummary|Skipped"
msgstr ""
@@ -28183,13 +28790,19 @@ msgstr ""
msgid "ProjectSettings|LFS objects from this repository are available to forks. %{linkStart}How do I remove them?%{linkEnd}"
msgstr ""
+msgid "ProjectSettings|Learn about commit history."
+msgstr ""
+
+msgid "ProjectSettings|Leave empty to use default template."
+msgstr ""
+
msgid "ProjectSettings|Manage who can see the project in the public access directory."
msgstr ""
msgid "ProjectSettings|Manages large files such as audio, video, and graphics files."
msgstr ""
-msgid "ProjectSettings|Maximum 500 characters."
+msgid "ProjectSettings|Maximum %{maxLength} characters."
msgstr ""
msgid "ProjectSettings|Merge checks"
@@ -28330,6 +28943,9 @@ msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
msgstr ""
+msgid "ProjectSettings|The default template will be applied on save."
+msgstr ""
+
msgid "ProjectSettings|These checks must pass before merge requests can be merged."
msgstr ""
@@ -28384,6 +29000,9 @@ msgstr ""
msgid "ProjectSettings|What are badges?"
msgstr ""
+msgid "ProjectSettings|What are merge trains?"
+msgstr ""
+
msgid "ProjectSettings|When merge request pipelines are enabled in the CI/CD configuration file, pipelines validate the combined results of the source and target branches. %{link_start}How to configure merge request pipelines?%{link_end}"
msgstr ""
@@ -28501,6 +29120,9 @@ msgstr ""
msgid "Projects are organized into groups"
msgstr ""
+msgid "Projects are where you store your code, access issues, wiki and other features of GitLab."
+msgstr ""
+
msgid "Projects contributed to"
msgstr ""
@@ -28516,12 +29138,6 @@ msgstr ""
msgid "Projects to index"
msgstr ""
-msgid "Projects will be permanently deleted after a %{waiting_period}-day waiting period."
-msgstr ""
-
-msgid "Projects will be permanently deleted immediately."
-msgstr ""
-
msgid "Projects with critical vulnerabilities"
msgstr ""
@@ -28606,6 +29222,9 @@ msgstr ""
msgid "ProjectsNew|Import project"
msgstr ""
+msgid "ProjectsNew|Include a Getting Started README"
+msgstr ""
+
msgid "ProjectsNew|Initialize repository with a README"
msgstr ""
@@ -28621,6 +29240,9 @@ msgstr ""
msgid "ProjectsNew|Project description %{tag_start}(optional)%{tag_end}"
msgstr ""
+msgid "ProjectsNew|Recommended if you're new to GitLab"
+msgstr ""
+
msgid "ProjectsNew|Run CI/CD for external repository"
msgstr ""
@@ -29038,6 +29660,9 @@ msgstr ""
msgid "ProtectedBranch|Unprotect"
msgstr ""
+msgid "ProtectedBranch|Unprotect branch"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
@@ -29065,6 +29690,9 @@ msgstr ""
msgid "ProtectedEnvironment|Protected Environment (%{protected_environments_count})"
msgstr ""
+msgid "ProtectedEnvironment|Required approvals"
+msgstr ""
+
msgid "ProtectedEnvironment|Select an environment"
msgstr ""
@@ -29086,10 +29714,13 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|Unprotect tag"
+msgstr ""
+
msgid "ProtectedTags|default"
msgstr ""
-msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
+msgid "ProtectedTag|By default, protected tags restrict who can modify the tag."
msgstr ""
msgid "ProtectedTag|Learn more."
@@ -29152,6 +29783,9 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Public projects are an easy way to allow everyone to have read-only access."
+msgstr ""
+
msgid "Publish to status page"
msgstr ""
@@ -29308,9 +29942,6 @@ msgstr ""
msgid "QualitySummary|Project quality"
msgstr ""
-msgid "Quarters"
-msgstr ""
-
msgid "Query"
msgstr ""
@@ -29395,6 +30026,9 @@ msgstr ""
msgid "Read more about project permissions %{help_link_open}here%{help_link_close}"
msgstr ""
+msgid "Read more about related epics"
+msgstr ""
+
msgid "Read more about related issues"
msgstr ""
@@ -29425,10 +30059,7 @@ msgstr ""
msgid "Rebase source branch on the target branch."
msgstr ""
-msgid "Rebase without CI"
-msgstr ""
-
-msgid "Rebases and triggers a pipeline"
+msgid "Rebase without pipeline"
msgstr ""
msgid "Recaptcha verified?"
@@ -29479,9 +30110,6 @@ msgstr ""
msgid "Reconfigure"
msgstr ""
-msgid "Recovering projects"
-msgstr ""
-
msgid "Recovery Codes"
msgstr ""
@@ -29541,6 +30169,12 @@ msgstr ""
msgid "Regex pattern"
msgstr ""
+msgid "Region"
+msgstr ""
+
+msgid "Regions"
+msgstr ""
+
msgid "Register"
msgstr ""
@@ -29771,9 +30405,6 @@ msgstr ""
msgid "Remove all or specific reviewer(s)"
msgstr ""
-msgid "Remove approver"
-msgstr ""
-
msgid "Remove approvers"
msgstr ""
@@ -29789,6 +30420,9 @@ msgstr ""
msgid "Remove attention request"
msgstr ""
+msgid "Remove attention request(s)"
+msgstr ""
+
msgid "Remove avatar"
msgstr ""
@@ -29927,6 +30561,9 @@ msgstr ""
msgid "Removed an issue from an epic."
msgstr ""
+msgid "Removed attention from %{users_sentence}."
+msgstr ""
+
msgid "Removed attention request from @%{username}"
msgstr ""
@@ -29978,6 +30615,9 @@ msgstr ""
msgid "Removes an issue from an epic."
msgstr ""
+msgid "Removes attention from %{users_sentence}."
+msgstr ""
+
msgid "Removes parent epic %{epic_ref}."
msgstr ""
@@ -30089,6 +30729,9 @@ msgstr ""
msgid "Report abuse to admin"
msgstr ""
+msgid "Report is generating and will be sent to your email address."
+msgstr ""
+
msgid "Reported %{timeAgo} by %{reportedBy}"
msgstr ""
@@ -30378,6 +31021,15 @@ msgstr ""
msgid "Request attention"
msgstr ""
+msgid "Request attention from %{users_sentence}."
+msgstr ""
+
+msgid "Request attention from assignee or reviewer"
+msgstr ""
+
+msgid "Request attention from assignee(s) or reviewer(s)"
+msgstr ""
+
msgid "Request attention to review"
msgstr ""
@@ -30402,6 +31054,9 @@ msgstr ""
msgid "Requested %{time_ago}"
msgstr ""
+msgid "Requested attention from %{users_sentence}."
+msgstr ""
+
msgid "Requested attention from @%{username}"
msgstr ""
@@ -30616,6 +31271,9 @@ msgstr ""
msgid "Restore project"
msgstr ""
+msgid "Restoring projects"
+msgstr ""
+
msgid "Restoring the group will prevent the group, its subgroups and projects from being removed on this date."
msgstr ""
@@ -30646,6 +31304,9 @@ msgstr ""
msgid "Retry"
msgstr ""
+msgid "Retry failed jobs"
+msgstr ""
+
msgid "Retry job"
msgstr ""
@@ -30693,9 +31354,6 @@ msgstr ""
msgid "Review changes"
msgstr ""
-msgid "Review requested from %{name}"
-msgstr ""
-
msgid "Review requests for you"
msgstr ""
@@ -30860,6 +31518,9 @@ msgstr ""
msgid "Runners|Assigned Group"
msgstr ""
+msgid "Runners|Assigned Projects (%{projectCount})"
+msgstr ""
+
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30929,6 +31590,9 @@ msgstr ""
msgid "Runners|Instance"
msgstr ""
+msgid "Runners|Jobs"
+msgstr ""
+
msgid "Runners|Last contact"
msgstr ""
@@ -31022,9 +31686,6 @@ msgstr ""
msgid "Runners|Runner %{name} was deleted"
msgstr ""
-msgid "Runners|Runner ID"
-msgstr ""
-
msgid "Runners|Runner assigned to project."
msgstr ""
@@ -31172,6 +31833,9 @@ msgstr ""
msgid "Runners|stale"
msgstr ""
+msgid "Runner|This runner has not run any jobs."
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -31286,6 +31950,24 @@ msgstr ""
msgid "Saving project."
msgstr ""
+msgid "ScanResultPolicy|%{ifLabelStart}if%{ifLabelEnd} %{scanners} scan in an open merge request targeting the %{branches} branch(es) finds %{vulnerabilitiesAllowed} or more %{severities} vulnerabilities that are %{vulnerabilityStates}"
+msgstr ""
+
+msgid "ScanResultPolicy|%{thenLabelStart}Then%{thenLabelEnd} Require approval from %{approvalsRequired} of the following approvers: %{approvers}"
+msgstr ""
+
+msgid "ScanResultPolicy|add an approver"
+msgstr ""
+
+msgid "ScanResultPolicy|scanners"
+msgstr ""
+
+msgid "ScanResultPolicy|severity levels"
+msgstr ""
+
+msgid "ScanResultPolicy|vulnerability states"
+msgstr ""
+
msgid "Scanner"
msgstr ""
@@ -31418,6 +32100,9 @@ msgstr ""
msgid "Search for a user"
msgstr ""
+msgid "Search for an emoji"
+msgstr ""
+
msgid "Search for projects, issues, etc."
msgstr ""
@@ -31605,18 +32290,12 @@ msgstr ""
msgid "Secret Detection"
msgstr ""
-msgid "Secret access key"
-msgstr ""
-
msgid "Secret token"
msgstr ""
msgid "Secure token that identifies an external storage request."
msgstr ""
-msgid "SecureCodeWarrior"
-msgstr ""
-
msgid "Security"
msgstr ""
@@ -31641,9 +32320,6 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "Security training with guide and learning pathways."
-msgstr ""
-
msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
@@ -31746,7 +32422,7 @@ msgstr ""
msgid "SecurityConfiguration|Manage corpus"
msgstr ""
-msgid "SecurityConfiguration|Manage corpus files used as mutation sources in coverage fuzzing."
+msgid "SecurityConfiguration|Manage corpus files used as seed inputs with coverage-guided fuzzing."
msgstr ""
msgid "SecurityConfiguration|Manage profiles for use by DAST scans."
@@ -31812,15 +32488,15 @@ msgstr ""
msgid "SecurityOrchestration|.yaml preview"
msgstr ""
-msgid "SecurityOrchestration|Action"
-msgstr ""
-
msgid "SecurityOrchestration|Actions"
msgstr ""
msgid "SecurityOrchestration|Add rule"
msgstr ""
+msgid "SecurityOrchestration|After dismissing the alert, the information will never be shown again."
+msgstr ""
+
msgid "SecurityOrchestration|All policies"
msgstr ""
@@ -31836,7 +32512,7 @@ msgstr ""
msgid "SecurityOrchestration|Description"
msgstr ""
-msgid "SecurityOrchestration|Disabled"
+msgid "SecurityOrchestration|Don't show the alert anymore"
msgstr ""
msgid "SecurityOrchestration|Edit policy"
@@ -31845,13 +32521,13 @@ msgstr ""
msgid "SecurityOrchestration|Edit policy project"
msgstr ""
-msgid "SecurityOrchestration|Enabled"
+msgid "SecurityOrchestration|Empty policy name"
msgstr ""
-msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Enabled"
msgstr ""
-msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
msgstr ""
msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
@@ -31860,7 +32536,7 @@ msgstr ""
msgid "SecurityOrchestration|Invalid policy type"
msgstr ""
-msgid "SecurityOrchestration|Latest scan"
+msgid "SecurityOrchestration|Latest scan run against %{agent}"
msgstr ""
msgid "SecurityOrchestration|Network"
@@ -31869,15 +32545,27 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No actions defined - policy will not run."
+msgstr ""
+
+msgid "SecurityOrchestration|No description"
+msgstr ""
+
msgid "SecurityOrchestration|No rules defined - policy will not run."
msgstr ""
+msgid "SecurityOrchestration|Not enabled"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
msgid "SecurityOrchestration|Policies"
msgstr ""
+msgid "SecurityOrchestration|Policy Type"
+msgstr ""
+
msgid "SecurityOrchestration|Policy cannot be enabled for non-existing branches (%{branches})"
msgstr ""
@@ -31902,10 +32590,13 @@ msgstr ""
msgid "SecurityOrchestration|Require %{approvals} %{plural} from %{approvers} if any of the following occur:"
msgstr ""
-msgid "SecurityOrchestration|Rule"
+msgid "SecurityOrchestration|Rules"
msgstr ""
-msgid "SecurityOrchestration|Rules"
+msgid "SecurityOrchestration|Runs %{actions} and %{lastAction} scans"
+msgstr ""
+
+msgid "SecurityOrchestration|Runs a %{action} scan"
msgstr ""
msgid "SecurityOrchestration|Scan Execution"
@@ -31965,6 +32656,9 @@ msgstr ""
msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
+msgid "SecurityOrchestration|This view only shows scan results for the agent %{agent}. You can view scan results for all agents in the %{linkStart}Operational Vulnerabilities tab of the vulnerability report%{linkEnd}."
+msgstr ""
+
msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
@@ -32019,9 +32713,6 @@ msgstr ""
msgid "SecurityOrchestration|users with ids"
msgstr ""
-msgid "SecurityOrchestration|view results"
-msgstr ""
-
msgid "SecurityOrchestration|vulnerabilities"
msgstr ""
@@ -32691,22 +33382,19 @@ 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|In order to start using functions as a service, you must first install Knative on your Kubernetes cluster. %{linkStart}More information%{linkEnd}"
-msgstr ""
-
msgid "Serverless|Learn more about Serverless"
msgstr ""
msgid "Serverless|No functions available"
msgstr ""
-msgid "Serverless|Sign up for First Look"
+msgid "Serverless|Serverless was %{linkStart}deprecated%{linkEnd} in GitLab 14.3."
+msgstr ""
+
+msgid "Serverless|Serverless was %{postLinkStart}deprecated%{postLinkEnd}. But if you opt to use it, you must install Knative in your Kubernetes cluster first. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "Serverless|The deploy job has not finished."
@@ -32718,9 +33406,6 @@ 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 ""
@@ -32736,9 +33421,6 @@ msgstr ""
msgid "Service Account Key"
msgstr ""
-msgid "Service Accounts"
-msgstr ""
-
msgid "Service Accounts keys authorize GitLab to deploy your Google Cloud project"
msgstr ""
@@ -32748,10 +33430,10 @@ msgstr ""
msgid "Service Desk allows people to create issues in your GitLab instance without their own user account. It provides a unique email address for end users to create issues in a project. Replies can be sent either through the GitLab interface or by email. End users only see threads through email."
msgstr ""
-msgid "Service Usage Data"
+msgid "Service account generated successfully"
msgstr ""
-msgid "Service account generated successfully"
+msgid "Service accounts"
msgstr ""
msgid "Service ping is disabled in your configuration file, and cannot be enabled through this form."
@@ -32895,6 +33577,9 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
+msgid "Set the per-user rate limit for getting a user by ID via the API."
+msgstr ""
+
msgid "Set the per-user rate limit for notes created by web or API requests."
msgstr ""
@@ -33074,6 +33759,9 @@ msgstr ""
msgid "Shared runners details"
msgstr ""
+msgid "Shared runners enabled cannot be enabled until a valid credit card is on file"
+msgstr ""
+
msgid "Shared runners help link"
msgstr ""
@@ -33131,6 +33819,9 @@ msgstr ""
msgid "Show all issues."
msgstr ""
+msgid "Show all milestones"
+msgstr ""
+
msgid "Show all test cases."
msgstr ""
@@ -33167,6 +33858,9 @@ msgstr ""
msgid "Show file contents"
msgstr ""
+msgid "Show group milestones"
+msgstr ""
+
msgid "Show labels"
msgstr ""
@@ -33182,6 +33876,12 @@ msgstr ""
msgid "Show open epics"
msgstr ""
+msgid "Show project milestones"
+msgstr ""
+
+msgid "Show sub-group milestones"
+msgstr ""
+
msgid "Show the Closed list"
msgstr ""
@@ -33191,11 +33891,6 @@ msgstr ""
msgid "Show whitespace changes"
msgstr ""
-msgid "Showing %d event"
-msgid_plural "Showing %d events"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Showing %{conflict} between %{sourceBranch} and %{targetBranch}"
msgstr ""
@@ -33255,12 +33950,6 @@ msgstr ""
msgid "Sidebar|None"
msgstr ""
-msgid "Sidebar|Only numeral characters allowed"
-msgstr ""
-
-msgid "Sidebar|Weight"
-msgstr ""
-
msgid "Sidekiq job compression threshold (bytes)"
msgstr ""
@@ -33423,6 +34112,9 @@ msgstr ""
msgid "Slack logo"
msgstr ""
+msgid "SlackIntegration|Are you sure you want to remove this project from the Slack application?"
+msgstr ""
+
msgid "SlackIntegration|GitLab for Slack"
msgstr ""
@@ -33432,6 +34124,9 @@ msgstr ""
msgid "SlackIntegration|Project alias"
msgstr ""
+msgid "SlackIntegration|Remove project"
+msgstr ""
+
msgid "SlackIntegration|Select a GitLab project to link with your Slack workspace."
msgstr ""
@@ -33576,9 +34271,6 @@ msgstr ""
msgid "Something went wrong trying to load issue contacts."
msgstr ""
-msgid "Something went wrong when creating a work item. Please try again"
-msgstr ""
-
msgid "Something went wrong when reordering designs. Please try again"
msgstr ""
@@ -33672,9 +34364,6 @@ msgstr ""
msgid "Something went wrong while inserting your image. Please try again."
msgstr ""
-msgid "Something went wrong while merging this merge request. Please try again."
-msgstr ""
-
msgid "Something went wrong while obtaining the Let's Encrypt certificate."
msgstr ""
@@ -33996,10 +34685,10 @@ 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."
+msgid "SourcegraphAdmin|Learn more."
msgstr ""
-msgid "SourcegraphAdmin|More information"
+msgid "SourcegraphAdmin|Only public projects have code intelligence enabled and communicate with Sourcegraph."
msgstr ""
msgid "SourcegraphAdmin|Save changes"
@@ -34008,7 +34697,7 @@ msgstr ""
msgid "SourcegraphAdmin|Sourcegraph URL"
msgstr ""
-msgid "SourcegraphAdmin|e.g. https://sourcegraph.example.com"
+msgid "SourcegraphAdmin|https://sourcegraph.example.com"
msgstr ""
msgid "SourcegraphPreferences|This feature is experimental and currently limited to certain projects."
@@ -34143,6 +34832,9 @@ msgstr ""
msgid "Start date"
msgstr ""
+msgid "Start free trial"
+msgstr ""
+
msgid "Start merge train"
msgstr ""
@@ -34173,6 +34865,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started escalation for this incident."
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -34185,6 +34880,9 @@ msgstr ""
msgid "Starts at (UTC)"
msgstr ""
+msgid "Starts escalations for this incident"
+msgstr ""
+
msgid "Starts on"
msgstr ""
@@ -34446,6 +35144,9 @@ msgstr ""
msgid "Strikethrough"
msgstr ""
+msgid "Strikethrough text"
+msgstr ""
+
msgid "Subgroup information"
msgstr ""
@@ -34680,6 +35381,21 @@ msgstr ""
msgid "Subscriptions"
msgstr ""
+msgid "Subscriptions|Chat with sales"
+msgstr ""
+
+msgid "Subscriptions|Close"
+msgstr ""
+
+msgid "Subscriptions|Not ready to buy yet?"
+msgstr ""
+
+msgid "Subscriptions|Start a free trial"
+msgstr ""
+
+msgid "Subscriptions|We understand. Maybe you have some questions for our sales team, or maybe you'd like to try some of the paid features first. What would you like to do?"
+msgstr ""
+
msgid "Subscription|Your subscription for %{strong}%{namespace_name}%{strong_close} has expired and you are now on %{pricing_link_start}the GitLab Free tier%{pricing_link_end}. Don't worry, your data is safe. Get in touch with our support team (%{support_email}). They'll gladly help with your subscription renewal."
msgstr ""
@@ -34890,6 +35606,9 @@ msgstr ""
msgid "SuperSonics|Maximum users"
msgstr ""
+msgid "SuperSonics|Offline cloud"
+msgstr ""
+
msgid "SuperSonics|Paste your activation code"
msgstr ""
@@ -34956,6 +35675,12 @@ msgstr ""
msgid "SuperSonics|You do not have an active subscription"
msgstr ""
+msgid "SuperSonics|You have a future dated license"
+msgstr ""
+
+msgid "SuperSonics|You have added a license that activates on %{date}. Please see the subscription history table below for more details."
+msgstr ""
+
msgid "SuperSonics|You have successfully added a license that activates on %{date}. Please see the subscription history table below for more details."
msgstr ""
@@ -35115,6 +35840,9 @@ msgstr ""
msgid "Tag name is required"
msgstr ""
+msgid "Tag push"
+msgstr ""
+
msgid "Tag push events"
msgstr ""
@@ -35217,6 +35945,9 @@ msgstr ""
msgid "TagsPage|protected"
msgstr ""
+msgid "Take a look at the documentation to discover all of GitLab’s capabilities."
+msgstr ""
+
msgid "Target Branch"
msgstr ""
@@ -35619,6 +36350,9 @@ msgstr ""
msgid "Tests"
msgstr ""
+msgid "Text (optional)"
+msgstr ""
+
msgid "Text added to the body of all email messages. %{character_limit} character limit"
msgstr ""
@@ -35669,6 +36403,9 @@ msgstr ""
msgid "The CSV export will be created in the background. Once finished, it will be sent to %{email} in an attachment."
msgstr ""
+msgid "The CSV export you requested of all user memberships is attached to this email."
+msgstr ""
+
msgid "The GitLab subscription service (customers.gitlab.com) is currently experiencing an outage. You can monitor the status and get updates at %{linkStart}status.gitlab.com%{linkEnd}."
msgstr ""
@@ -35744,6 +36481,9 @@ 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 epic"
+msgstr ""
+
msgid "The current issue"
msgstr ""
@@ -35905,6 +36645,9 @@ msgstr ""
msgid "The latest pipeline for this merge request has failed."
msgstr ""
+msgid "The license key is invalid."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -35920,6 +36663,9 @@ msgstr ""
msgid "The license was successfully uploaded and will be active from %{starts_at}. You can see the details below."
msgstr ""
+msgid "The license you uploaded is invalid. If the issue persists, contact support at %{link}."
+msgstr ""
+
msgid "The list creation wizard is already open"
msgstr ""
@@ -36541,10 +37287,13 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} and everything this project contains. %{strongOpen}There is no going back%{strongClose}"
+msgstr ""
+
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains."
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}on %{date}%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains. %{strongOpen}There is no going back.%{strongClose}"
msgstr ""
msgid "This action will %{strongOpen}permanently remove%{strongClose} %{codeOpen}%{group}%{codeClose} %{strongOpen}immediately%{strongClose}."
@@ -36673,9 +37422,6 @@ msgstr ""
msgid "This file was modified for readability, and can't accept suggestions. Edit it directly."
msgstr ""
-msgid "This forked project has the following:"
-msgstr ""
-
msgid "This form is disabled in preview"
msgstr ""
@@ -36688,7 +37434,7 @@ msgstr ""
msgid "This group can't be removed because it is linked to a subscription. To remove this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
-msgid "This group can't be transfered because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
+msgid "This group can't be transferred because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
msgid "This group cannot be invited to a project inside a group with enforced SSO"
@@ -36715,6 +37461,9 @@ 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 incident is already escalated with '%{escalation_policy_name}'."
+msgstr ""
+
msgid "This invitation was sent to %{mail_to_invite_email}, but you are signed in as %{link_to_current_user} with email %{mail_to_current_user}."
msgstr ""
@@ -36733,9 +37482,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 merge train pipeline"
-msgstr ""
-
msgid "This is a private email address %{helpIcon} generated just for you. Anyone who has it can create issues or merge requests as if they were you. If that happens, %{resetLinkStart}reset this token%{resetLinkEnd}."
msgstr ""
@@ -36757,6 +37503,12 @@ msgstr ""
msgid "This is your current session"
msgstr ""
+msgid "This issue cannot be assigned to a confidential epic because it is public."
+msgstr ""
+
+msgid "This issue cannot be made public because it belongs to a confidential epic."
+msgstr ""
+
msgid "This issue is confidential and should only be visible to team members with at least Reporter access."
msgstr ""
@@ -36874,6 +37626,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 branch is protected from force push."
+msgstr ""
+
msgid "This merge request cannot be rebased while there are conflicts."
msgstr ""
@@ -36925,9 +37680,15 @@ msgstr ""
msgid "This pipeline was triggered by a schedule."
msgstr ""
+msgid "This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project"
msgstr ""
+msgid "This project can be restored until %{date}."
+msgstr ""
+
msgid "This project cannot be %{visibilityLevel} because the visibility of %{openShowLink}%{name}%{closeShowLink} is %{visibility}. To make this project %{visibilityLevel}, you must first %{openEditLink}change the visibility%{closeEditLink} of the parent group."
msgstr ""
@@ -36946,6 +37707,9 @@ msgstr ""
msgid "This project is %{strongStart}NOT%{strongEnd} a fork, and has the following:"
msgstr ""
+msgid "This project is %{strongStart}NOT%{strongEnd} a fork. This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -37637,6 +38401,9 @@ msgstr ""
msgid "Today"
msgstr ""
+msgid "Todos count"
+msgstr ""
+
msgid "Todos|Are you looking for things to do? Take a look at %{strongStart}%{openIssuesLinkStart}open issues%{openIssuesLinkEnd}%{strongEnd}, contribute to %{strongStart}%{mergeRequestLinkStart}a merge request%{mergeRequestLinkEnd}%{mergeRequestLinkEnd}%{strongEnd}, or mention someone in a comment to automatically assign them a new to-do item."
msgstr ""
@@ -37910,10 +38677,8 @@ msgstr ""
msgid "Trending"
msgstr ""
-msgid "Trials|%{planName} Trial %{enDash} %{num} day left"
-msgid_plural "Trials|%{planName} Trial %{enDash} %{num} days left"
-msgstr[0] ""
-msgstr[1] ""
+msgid "Trials|%{planName} Trial"
+msgstr ""
msgid "Trials|Compare all plans"
msgstr ""
@@ -37921,6 +38686,9 @@ msgstr ""
msgid "Trials|Create a new group to start your GitLab Ultimate trial."
msgstr ""
+msgid "Trials|Day %{daysUsed}/%{duration}"
+msgstr ""
+
msgid "Trials|Go back to GitLab"
msgstr ""
@@ -38170,7 +38938,7 @@ msgstr ""
msgid "URL is triggered when repository is updated"
msgstr ""
-msgid "URL must be percent-encoded if neccessary."
+msgid "URL must be percent-encoded if necessary."
msgstr ""
msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
@@ -38389,6 +39157,9 @@ msgstr ""
msgid "Unlock account"
msgstr ""
+msgid "Unlock more features with GitLab Ultimate"
+msgstr ""
+
msgid "Unlock the discussion"
msgstr ""
@@ -38452,6 +39223,9 @@ msgstr ""
msgid "Unsubscribes from this %{quick_action_target}."
msgstr ""
+msgid "Unsupported sort value."
+msgstr ""
+
msgid "Unsupported todo type passed. Supported todo types are: %{todo_types}"
msgstr ""
@@ -38680,6 +39454,9 @@ msgstr ""
msgid "UsageQuota|File attachments and smaller design graphics."
msgstr ""
+msgid "UsageQuota|From %{storage_enforcement_date} storage limits will apply to this namespace. View and manage your usage in %{strong_start}Group Settings &gt; Usage quotas%{strong_end}."
+msgstr ""
+
msgid "UsageQuota|Git repository."
msgstr ""
@@ -38740,6 +39517,9 @@ msgstr ""
msgid "UsageQuota|Storage type"
msgstr ""
+msgid "UsageQuota|Storage used"
+msgstr ""
+
msgid "UsageQuota|This is the total amount of storage used across your projects within this namespace."
msgstr ""
@@ -38935,6 +39715,12 @@ msgstr ""
msgid "Use hashed storage paths for newly created and renamed repositories. Always enabled since 13.0."
msgstr ""
+msgid "Use issue count"
+msgstr ""
+
+msgid "Use issue weight"
+msgstr ""
+
msgid "Use one line per URI"
msgstr ""
@@ -39316,6 +40102,9 @@ msgstr ""
msgid "Users"
msgstr ""
+msgid "Users API rate limit"
+msgstr ""
+
msgid "Users can launch a development environment from a GitLab browser tab when the %{linkStart}Gitpod%{linkEnd} integration is enabled."
msgstr ""
@@ -39641,6 +40430,9 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View group pipeline usage quota"
+msgstr ""
+
msgid "View incident details at"
msgstr ""
@@ -39793,6 +40585,9 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
+msgid "Vulnerability"
+msgstr ""
+
msgid "Vulnerability Report"
msgstr ""
@@ -39844,6 +40639,9 @@ msgstr ""
msgid "VulnerabilityManagement|An unverified non-confirmed finding"
msgstr ""
+msgid "VulnerabilityManagement|At least one identifier is required"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -39853,12 +40651,24 @@ msgstr ""
msgid "VulnerabilityManagement|Create Jira issue"
msgstr ""
+msgid "VulnerabilityManagement|Enter a name"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE code"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE identifier URL"
+msgstr ""
+
msgid "VulnerabilityManagement|Fetching linked Jira issues"
msgstr ""
msgid "VulnerabilityManagement|Manually add a vulnerability entry into the vulnerability report."
msgstr ""
+msgid "VulnerabilityManagement|Name is a required field"
+msgstr ""
+
msgid "VulnerabilityManagement|Needs triage"
msgstr ""
@@ -39874,6 +40684,18 @@ msgstr ""
msgid "VulnerabilityManagement|Select a method"
msgstr ""
+msgid "VulnerabilityManagement|Select a severity level"
+msgstr ""
+
+msgid "VulnerabilityManagement|Select a status"
+msgstr ""
+
+msgid "VulnerabilityManagement|Severity is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Something went wrong while creating vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -39898,6 +40720,12 @@ msgstr ""
msgid "VulnerabilityManagement|Something went wrong, could not update vulnerability state."
msgstr ""
+msgid "VulnerabilityManagement|Status is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Submit vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Summary, detailed description, steps to reproduce, etc."
msgstr ""
@@ -40093,6 +40921,9 @@ msgstr ""
msgid "WARNING:"
msgstr ""
+msgid "WARNING: This snippet contains hidden files which might be used to mask malicious behavior. Exercise caution if cloning and executing code from this snippet."
+msgstr ""
+
msgid "Wait for the file to load to copy its contents"
msgstr ""
@@ -40312,6 +41143,15 @@ msgstr ""
msgid "Webhooks|An issue is created, updated, closed, or reopened."
msgstr ""
+msgid "Webhooks|Are you sure you want to delete this group hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this project hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this webhook?"
+msgstr ""
+
msgid "Webhooks|Comments"
msgstr ""
@@ -40321,6 +41161,9 @@ msgstr ""
msgid "Webhooks|Confidential issues events"
msgstr ""
+msgid "Webhooks|Delete webhook"
+msgstr ""
+
msgid "Webhooks|Deployment events"
msgstr ""
@@ -40554,6 +41397,9 @@ msgstr ""
msgid "Wiki"
msgstr ""
+msgid "Wiki page"
+msgstr ""
+
msgid "Wiki page was successfully created."
msgstr ""
@@ -40659,7 +41505,7 @@ msgstr ""
msgid "WikiPageConflictMessage|Someone edited the page the same time you did. Please check out %{wikiLinkStart}the page%{wikiLinkEnd} and make sure your changes will not unintentionally remove theirs."
msgstr ""
-msgid "WikiPage|An error occured while trying to render the content editor. Please try again later."
+msgid "WikiPage|An error occurred while trying to render the content editor. Please try again later."
msgstr ""
msgid "WikiPage|Are you sure you want to switch back to the classic editor?"
@@ -40818,6 +41664,18 @@ msgstr ""
msgid "WorkItem|New Task"
msgstr ""
+msgid "WorkItem|Something went wrong when creating a work item. Please try again"
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching the work item. Please try again."
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching work item types. Please try again"
+msgstr ""
+
+msgid "WorkItem|Type"
+msgstr ""
+
msgid "WorkItem|Work Items"
msgstr ""
@@ -40884,7 +41742,10 @@ msgstr ""
msgid "You are about to add %{usersTag} people to the discussion. They will all receive a notification."
msgstr ""
-msgid "You are about to permanently delete this project"
+msgid "You are about to delete this forked project containing:"
+msgstr ""
+
+msgid "You are about to delete this project containing:"
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."
@@ -40905,6 +41766,9 @@ msgstr ""
msgid "You are attempting to update a file that has changed since you started editing it."
msgstr ""
+msgid "You are billed if you exceed this number. %{qsrOverageLinkStart}How does billing work?%{qsrOverageLinkEnd}"
+msgstr ""
+
msgid "You are connected to the Prometheus server, but there is currently no data to display."
msgstr ""
@@ -40962,6 +41826,9 @@ msgstr ""
msgid "You are not authorized to update this scanner profile"
msgstr ""
+msgid "You are not authorized to upload metric images"
+msgstr ""
+
msgid "You are now impersonating %{username}"
msgstr ""
@@ -41115,9 +41982,6 @@ msgstr ""
msgid "You can only upload one design when dropping onto an existing design."
msgstr ""
-msgid "You can recover this project until %{date}"
-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 ""
@@ -41166,9 +42030,6 @@ msgstr ""
msgid "You cannot write to this read-only GitLab instance."
msgstr ""
-msgid "You can’t %{tag_start}edit%{tag_end} files directly in this project. Fork this project and submit a merge request with your changes."
-msgstr ""
-
msgid "You can’t edit files directly in this project. Fork this project and submit a merge request with your changes."
msgstr ""
@@ -41321,9 +42182,6 @@ 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 set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
@@ -41354,12 +42212,6 @@ msgstr ""
msgid "You must have maintainer access to force delete a lock"
msgstr ""
-msgid "You must have permission to create a project in a group before forking."
-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 ""
@@ -41765,7 +42617,7 @@ msgstr ""
msgid "Your public email will be displayed on your public profile."
msgstr ""
-msgid "Your request for access could not be processed: %{error_meesage}"
+msgid "Your request for access could not be processed: %{error_message}"
msgstr ""
msgid "Your request for access has been queued for review."
@@ -41948,6 +42800,9 @@ msgstr ""
msgid "archived:"
msgstr ""
+msgid "artifacts"
+msgstr ""
+
msgid "assign yourself"
msgstr ""
@@ -41977,6 +42832,9 @@ msgstr[1] ""
msgid "branch name"
msgstr ""
+msgid "builds"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -42400,6 +43258,9 @@ msgstr ""
msgid "contact with same email already exists in group hierarchy"
msgstr ""
+msgid "container registry images"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -42439,6 +43300,9 @@ msgstr ""
msgid "data"
msgstr ""
+msgid "database"
+msgstr ""
+
msgid "date must not be after 9999-12-31"
msgstr ""
@@ -42462,9 +43326,6 @@ msgstr ""
msgid "design"
msgstr ""
-msgid "detached"
-msgstr ""
-
msgid "disabled"
msgstr ""
@@ -42713,7 +43574,7 @@ msgstr ""
msgid "is not a valid X509 certificate."
msgstr ""
-msgid "is not allowed for sign-up."
+msgid "is not allowed for sign-up. Please use your regular email address."
msgstr ""
msgid "is not allowed for this group."
@@ -42725,7 +43586,7 @@ msgstr ""
msgid "is not allowed since the group is not top-level group."
msgstr ""
-msgid "is not allowed."
+msgid "is not allowed. Please use your regular email address."
msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
@@ -42812,6 +43673,9 @@ msgstr ""
msgid "level: %{level}"
msgstr ""
+msgid "lfs objects"
+msgstr ""
+
msgid "limit of %{project_limit} reached"
msgstr ""
@@ -43031,6 +43895,9 @@ msgstr ""
msgid "mrWidget|Merge blocked: pipeline must succeed. It's waiting for a manual action to continue."
msgstr ""
+msgid "mrWidget|Merge blocked: pipeline must succeed. Push a commit that fixes the failure, or %{linkStart}learn about other solutions.%{linkEnd}"
+msgstr ""
+
msgid "mrWidget|Merge blocked: this merge request must be approved."
msgstr ""
@@ -43148,9 +44015,6 @@ msgstr ""
msgid "mrWidget|The changes were not merged into"
msgstr ""
-msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -43298,9 +44162,6 @@ msgstr ""
msgid "open issue"
msgstr ""
-msgid "opened %{timeAgo}"
-msgstr ""
-
msgid "or"
msgstr ""
@@ -43312,6 +44173,12 @@ msgid_plural "out of %d total tests"
msgstr[0] ""
msgstr[1] ""
+msgid "packages"
+msgstr ""
+
+msgid "pages"
+msgstr ""
+
msgid "parent"
msgid_plural "parents"
msgstr[0] ""
@@ -43461,6 +44328,9 @@ msgid_plural "replies"
msgstr[0] ""
msgstr[1] ""
+msgid "repositories"
+msgstr ""
+
msgid "repository:"
msgstr ""
@@ -43581,12 +44451,18 @@ msgstr ""
msgid "tag name"
msgstr ""
+msgid "terraform states"
+msgstr ""
+
msgid "the correct format."
msgstr ""
msgid "the file"
msgstr ""
+msgid "the following epic(s)"
+msgstr ""
+
msgid "the following issue(s)"
msgstr ""
@@ -43599,21 +44475,12 @@ msgstr ""
msgid "this document"
msgstr ""
-msgid "this issue cannot be assigned to a confidential epic since it is public"
-msgstr ""
-
-msgid "this issue cannot be made public since it belongs to a confidential epic"
-msgstr ""
-
msgid "time summary"
msgstr ""
msgid "toggle collapse"
msgstr ""
-msgid "train"
-msgstr ""
-
msgid "triggered"
msgstr ""
@@ -43742,3 +44609,6 @@ msgstr ""
msgid "{project}"
msgstr ""
+msgid "✔"
+msgstr ""
+
diff --git a/locale/sr_CS/gitlab.po b/locale/sr_CS/gitlab.po
index 07712753e68..178d6dd0450 100644
--- a/locale/sr_CS/gitlab.po
+++ b/locale/sr_CS/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: sr-CS\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2022-02-02 15:47\n"
+"PO-Revision-Date: 2022-03-01 20:40\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -160,6 +160,12 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
+msgid "%d assigned issue"
+msgid_plural "%d assigned issues"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -490,8 +496,26 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
-msgid "%d vulnerability updated"
-msgid_plural "%d vulnerabilities updated"
+msgid "%d vulnerability set to confirmed"
+msgid_plural "%d vulnerabilities set to confirmed"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
+msgid "%d vulnerability set to dismissed"
+msgid_plural "%d vulnerabilities set to dismissed"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
+msgid "%d vulnerability set to needs triage"
+msgid_plural "%d vulnerabilities set to needs triage"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
+msgid "%d vulnerability set to resolved"
+msgid_plural "%d vulnerabilities set to resolved"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
@@ -586,6 +610,12 @@ msgstr[2] ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{completed} of %{total} issues closed"
+msgstr ""
+
+msgid "%{completed} of %{total} weight completed"
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -940,6 +970,9 @@ msgstr ""
msgid "%{openedIssues} open, %{closedIssues} closed"
msgstr ""
+msgid "%{percentage}%% issues closed"
+msgstr ""
+
msgid "%{percentage}%% weight completed"
msgstr ""
@@ -1384,6 +1417,9 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
+msgid "- of - issues closed"
+msgstr ""
+
msgid "- of - weight completed"
msgstr ""
@@ -1549,7 +1585,7 @@ msgstr ""
msgid "1000+"
msgstr ""
-msgid "192.168.0.0/24"
+msgid "192.168.0.0/24 or 2001:0DB8:1234::/48"
msgstr ""
msgid "1st contribution!"
@@ -1861,13 +1897,13 @@ msgstr ""
msgid "AWS Access Key"
msgstr ""
-msgid "AWS Access Key. Only required if not using role instance credentials"
+msgid "AWS Secret Access Key"
msgstr ""
-msgid "AWS Secret Access Key"
+msgid "AWS access key ID (Optional)"
msgstr ""
-msgid "AWS Secret Access Key. Only required if not using role instance credentials"
+msgid "AWS secret access key (Optional)"
msgstr ""
msgid "AWS service error: %{error}"
@@ -1927,9 +1963,6 @@ msgstr ""
msgid "Access granted"
msgstr ""
-msgid "Access key ID"
-msgstr ""
-
msgid "Access requests"
msgstr ""
@@ -2104,7 +2137,7 @@ msgstr ""
msgid "Activity"
msgstr ""
-msgid "Activity|An error occured while retrieving activity. Reload the page to try again."
+msgid "Activity|An error occurred while retrieving activity. Reload the page to try again."
msgstr ""
msgid "Add"
@@ -2143,6 +2176,9 @@ msgstr ""
msgid "Add a %{type}"
msgstr ""
+msgid "Add a GCP region"
+msgstr ""
+
msgid "Add a GPG key"
msgstr ""
@@ -2194,6 +2230,9 @@ msgstr ""
msgid "Add a numbered list"
msgstr ""
+msgid "Add a related epic"
+msgstr ""
+
msgid "Add a related issue"
msgstr ""
@@ -2308,6 +2347,9 @@ msgstr ""
msgid "Add or subtract spent time"
msgstr ""
+msgid "Add people"
+msgstr ""
+
msgid "Add previously merged commits"
msgstr ""
@@ -2374,6 +2416,9 @@ msgstr ""
msgid "Add webhook"
msgstr ""
+msgid "Add your team members and others to GitLab."
+msgstr ""
+
msgid "Add/remove"
msgstr ""
@@ -3196,12 +3241,6 @@ msgstr ""
msgid "AdvancedSearch|Reindex required"
msgstr ""
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. Permanently deleting this project will %{strongStart}immediately delete%{strongEnd} its repositories and %{strongStart}all related resources%{strongEnd}, including issues, merge requests etc."
-msgstr ""
-
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. You will lose this project's repository and %{strongStart}all related resources%{strongEnd}, including issues and merge requests."
-msgstr ""
-
msgid "After a successful password update you will be redirected to login screen."
msgstr ""
@@ -3232,6 +3271,9 @@ msgstr ""
msgid "Akismet helps prevent the creation of spam issues in public projects."
msgstr ""
+msgid "Alert"
+msgstr ""
+
msgid "AlertManagement|Acknowledged"
msgstr ""
@@ -3604,9 +3646,6 @@ msgstr ""
msgid "All environments"
msgstr ""
-msgid "All epics"
-msgstr ""
-
msgid "All groups and projects"
msgstr ""
@@ -4345,13 +4384,16 @@ msgstr ""
msgid "ApplicationSettings|Approve users in the pending approval status?"
msgstr ""
-msgid "ApplicationSettings|By making this change, you will automatically approve %d user with the pending approval status."
-msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users with the pending approval status."
+msgid "ApplicationSettings|Approve users who are pending approval?"
+msgstr ""
+
+msgid "ApplicationSettings|By making this change, you will automatically approve %d user who is pending approval."
+msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users who are pending approval."
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
-msgid "ApplicationSettings|By making this change, you will automatically approve all users in pending approval status."
+msgid "ApplicationSettings|By making this change, you will automatically approve all users who are pending approval."
msgstr ""
msgid "ApplicationSettings|Denied domains for sign-ups"
@@ -4762,10 +4804,10 @@ msgstr ""
msgid "Archiving the project will make it entirely read-only. It is hidden from the dashboard and doesn't show up in searches. %{strong_start}The repository cannot be committed to, and no issues, comments, or other entities can be created.%{strong_end} %{link_start}Learn more.%{link_end}"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to delete this project?"
+msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
+msgid "Are you absolutely sure?"
msgstr ""
msgid "Are you sure that you want to archive this project?"
@@ -4801,12 +4843,18 @@ msgstr ""
msgid "Are you sure you want to delete this SSH key?"
msgstr ""
+msgid "Are you sure you want to delete this comment?"
+msgstr ""
+
msgid "Are you sure you want to delete this deploy key?"
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 label?"
+msgstr ""
+
msgid "Are you sure you want to delete this pipeline schedule?"
msgstr ""
@@ -4822,9 +4870,6 @@ msgstr ""
msgid "Are you sure you want to discard your changes?"
msgstr ""
-msgid "Are you sure you want to erase this build?"
-msgstr ""
-
msgid "Are you sure you want to import %d repository?"
msgid_plural "Are you sure you want to import %d repositories?"
msgstr[0] ""
@@ -4873,6 +4918,9 @@ msgstr ""
msgid "Are you sure you want to remove this list?"
msgstr ""
+msgid "Are you sure you want to remove this nickname?"
+msgstr ""
+
msgid "Are you sure you want to reset the health check token?"
msgstr ""
@@ -4885,10 +4933,10 @@ 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?"
+msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
msgstr ""
-msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
+msgid "Are you sure you want to revoke this project access token? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to stop this environment?"
@@ -5035,9 +5083,6 @@ msgstr ""
msgid "Assigned to %{assignee_name}"
msgstr ""
-msgid "Assigned to %{name}"
-msgstr ""
-
msgid "Assigned to me"
msgstr ""
@@ -5104,6 +5149,9 @@ msgstr[2] ""
msgid "Attaching the file failed."
msgstr ""
+msgid "Attention"
+msgstr ""
+
msgid "Audit Events"
msgstr ""
@@ -5266,6 +5314,12 @@ msgstr ""
msgid "Authorized applications (%{size})"
msgstr ""
+msgid "AuthorizedApplication|Are you sure you want to revoke this application?"
+msgstr ""
+
+msgid "AuthorizedApplication|Revoke application"
+msgstr ""
+
msgid "Authors: %{authors}"
msgstr ""
@@ -6463,6 +6517,9 @@ msgstr ""
msgid "CICDAnalytics|Shared Runners Usage"
msgstr ""
+msgid "CICDAnalytics|Shared runner pipeline minute duration by month"
+msgstr ""
+
msgid "CICDAnalytics|Shared runner usage"
msgstr ""
@@ -6604,6 +6661,9 @@ msgstr ""
msgid "Can create groups:"
msgstr ""
+msgid "Can not delete primary training"
+msgstr ""
+
msgid "Can't apply as the source branch was deleted."
msgstr ""
@@ -6937,9 +6997,6 @@ msgstr ""
msgid "Changing any setting here requires an application restart"
msgstr ""
-msgid "Changing group URL can have unintended side effects."
-msgstr ""
-
msgid "Charts can't be displayed as the request for data has timed out. %{documentationLink}"
msgstr ""
@@ -7027,9 +7084,6 @@ msgstr ""
msgid "Checking branch availability..."
msgstr ""
-msgid "Checking group URL availability..."
-msgstr ""
-
msgid "Checking group path availability..."
msgstr ""
@@ -7525,6 +7579,9 @@ msgstr ""
msgid "Clear recent searches"
msgstr ""
+msgid "Clear repository checks"
+msgstr ""
+
msgid "Clear search"
msgstr ""
@@ -7657,9 +7714,6 @@ msgstr ""
msgid "Closed MRs"
msgstr ""
-msgid "Closed epics"
-msgstr ""
-
msgid "Closed issues"
msgstr ""
@@ -7696,13 +7750,13 @@ msgstr ""
msgid "Cluster level"
msgstr ""
-msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
+msgid "Cluster type must be specified for Stages::ClusterEndpointInserter"
msgstr ""
msgid "ClusterAgents|%{name} successfully deleted"
msgstr ""
-msgid "ClusterAgents|%{number} of %{total} Agents"
+msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
@@ -7744,6 +7798,15 @@ msgstr ""
msgid "ClusterAgents|Agent never connected to GitLab"
msgstr ""
+msgid "ClusterAgents|Agent version mismatch"
+msgstr ""
+
+msgid "ClusterAgents|Agent version mismatch and update"
+msgstr ""
+
+msgid "ClusterAgents|Agent version update required"
+msgstr ""
+
msgid "ClusterAgents|All"
msgstr ""
@@ -7768,7 +7831,7 @@ msgstr ""
msgid "ClusterAgents|Configuration"
msgstr ""
-msgid "ClusterAgents|Connect a cluster through the Agent"
+msgid "ClusterAgents|Connect a cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connect existing cluster"
@@ -7777,13 +7840,13 @@ msgstr ""
msgid "ClusterAgents|Connect with a certificate"
msgstr ""
-msgid "ClusterAgents|Connect with agent"
+msgid "ClusterAgents|Connect with an agent"
msgstr ""
msgid "ClusterAgents|Connect with the GitLab Agent"
msgstr ""
-msgid "ClusterAgents|Connect your cluster through the Agent"
+msgid "ClusterAgents|Connect your cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connected"
@@ -7843,7 +7906,10 @@ msgstr ""
msgid "ClusterAgents|How to register an agent?"
msgstr ""
-msgid "ClusterAgents|Install new Agent"
+msgid "ClusterAgents|How to update an agent?"
+msgstr ""
+
+msgid "ClusterAgents|Install a new agent"
msgstr ""
msgid "ClusterAgents|Last connected %{timeAgo}."
@@ -7870,7 +7936,7 @@ msgstr ""
msgid "ClusterAgents|Never connected"
msgstr ""
-msgid "ClusterAgents|No Agents"
+msgid "ClusterAgents|No agents"
msgstr ""
msgid "ClusterAgents|No clusters connected through cluster certificates"
@@ -7930,6 +7996,9 @@ msgstr ""
msgid "ClusterAgents|The agent has not been connected in a long time. There might be a connectivity issue. Last contact was %{timeAgo}."
msgstr ""
+msgid "ClusterAgents|The agent version do not match each other across your cluster's pods. This can happen when a new agent version was just deployed and Kubernetes is shutting down the old pods."
+msgstr ""
+
msgid "ClusterAgents|The recommended installation method includes the token. If you want to follow the advanced installation method provided in the docs, make sure you save the token value before you close this window."
msgstr ""
@@ -7978,6 +8047,9 @@ msgstr ""
msgid "ClusterAgents|You will need to create a token to connect to your agent"
msgstr ""
+msgid "ClusterAgents|Your agent version is out of sync with your GitLab version (v%{version}), which might cause compatibility problems. Update the agent installed on your cluster to the most recent version."
+msgstr ""
+
msgid "ClusterAgents|Your instance doesn't have the %{linkStart}GitLab Agent Server (KAS)%{linkEnd} set up. Ask a GitLab Administrator to install it."
msgstr ""
@@ -8854,9 +8926,6 @@ msgstr ""
msgid "Comma-separated list of email addresses."
msgstr ""
-msgid "Comma-separated list of users allowed to exceed the rate limit."
-msgstr ""
-
msgid "Comma-separated, e.g. '1.1.1.1, 2.2.2.0/24'"
msgstr ""
@@ -9184,6 +9253,12 @@ msgstr ""
msgid "Confidential"
msgstr ""
+msgid "Confidential issue"
+msgstr ""
+
+msgid "Confidential note"
+msgstr ""
+
msgid "Confidentiality"
msgstr ""
@@ -9217,6 +9292,9 @@ msgstr ""
msgid "Configure Dependency Scanning in `.gitlab-ci.yml`, creating this file if it does not already exist"
msgstr ""
+msgid "Configure GitLab"
+msgstr ""
+
msgid "Configure GitLab runners to start using the Web Terminal. %{helpStart}Learn more.%{helpEnd}"
msgstr ""
@@ -9265,6 +9343,15 @@ msgstr ""
msgid "Configure pipelines to deploy web apps, backend services, APIs and static resources to Google Cloud"
msgstr ""
+msgid "Configure region"
+msgstr ""
+
+msgid "Configure region for environment"
+msgstr ""
+
+msgid "Configure regions"
+msgstr ""
+
msgid "Configure repository mirroring."
msgstr ""
@@ -9298,6 +9385,9 @@ msgstr ""
msgid "Configure which lists are shown for anyone who visits this board"
msgstr ""
+msgid "Configure your environments to be deployed to specific geographical regions"
+msgstr ""
+
msgid "Confirm"
msgstr ""
@@ -10003,10 +10093,10 @@ msgstr ""
msgid "CorpusManagement|Actions"
msgstr ""
-msgid "CorpusManagement|Corpus are used in fuzz testing as mutation source to Improve future testing."
+msgid "CorpusManagement|Corpus file"
msgstr ""
-msgid "CorpusManagement|Corpus file"
+msgid "CorpusManagement|Corpus files are used in coverage-guided fuzz testing as seed inputs to improve testing."
msgstr ""
msgid "CorpusManagement|Corpus files must be in *.zip format. Maximum 5 GB"
@@ -10060,6 +10150,9 @@ msgstr ""
msgid "Could not apply %{name} command."
msgstr ""
+msgid "Could not apply %{name} command. %{message}."
+msgstr ""
+
msgid "Could not authorize chat nickname. Try again!"
msgstr ""
@@ -10210,6 +10303,9 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
+msgid "Create a group"
+msgstr ""
+
msgid "Create a merge request"
msgstr ""
@@ -10234,6 +10330,9 @@ msgstr ""
msgid "Create a personal access token on your account to pull or push via %{protocol}."
msgstr ""
+msgid "Create a project"
+msgstr ""
+
msgid "Create an account using:"
msgstr ""
@@ -10597,6 +10696,9 @@ msgstr ""
msgid "Creation date"
msgstr ""
+msgid "Creator"
+msgstr ""
+
msgid "Credentials"
msgstr ""
@@ -10609,9 +10711,15 @@ msgstr ""
msgid "CredentialsInventory|Personal Access Tokens"
msgstr ""
+msgid "CredentialsInventory|Project Access Tokens"
+msgstr ""
+
msgid "CredentialsInventory|SSH Keys"
msgstr ""
+msgid "Credit card required to be on file in order to create a pipeline"
+msgstr ""
+
msgid "Credit card:"
msgstr ""
@@ -10795,9 +10903,6 @@ msgstr ""
msgid "Customer relations"
msgstr ""
-msgid "Customizable by an administrator."
-msgstr ""
-
msgid "Customizable by owners."
msgstr ""
@@ -10927,30 +11032,18 @@ msgstr ""
msgid "CycleAnalytics|%{selectedLabelsCount} selected (%{maxLabels} max)"
msgstr ""
-msgid "CycleAnalytics|%{stageCount} stages selected"
-msgstr ""
-
-msgid "CycleAnalytics|All stages"
-msgstr ""
-
-msgid "CycleAnalytics|Average days to completion"
+msgid "CycleAnalytics|Average time to completion"
msgstr ""
msgid "CycleAnalytics|Date"
msgstr ""
-msgid "CycleAnalytics|Days to completion"
-msgstr ""
-
msgid "CycleAnalytics|Display chart filters"
msgstr ""
msgid "CycleAnalytics|Lead Time for Changes"
msgstr ""
-msgid "CycleAnalytics|No stages selected"
-msgstr ""
-
msgid "CycleAnalytics|Number of tasks"
msgstr ""
@@ -10981,18 +11074,30 @@ msgstr ""
msgid "CycleAnalytics|Showing data for group '%{groupName}' from %{createdAfter} to %{createdBefore}"
msgstr ""
-msgid "CycleAnalytics|Stages"
+msgid "CycleAnalytics|Stage time: %{title}"
msgstr ""
msgid "CycleAnalytics|Tasks by type"
msgstr ""
-msgid "CycleAnalytics|The average time spent in the selected stage for the items that were completed on each date. Data limited to the last 500 items."
+msgid "CycleAnalytics|The average time items spent in this stage. Data limited to items completed within this date range."
msgstr ""
msgid "CycleAnalytics|The given date range is larger than 180 days"
msgstr ""
+msgid "CycleAnalytics|The total time items spent across each value stream stage. Data limited to items completed within this date range."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Stage time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Total time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|Total time"
+msgstr ""
+
msgid "CycleAnalytics|Type of work"
msgstr ""
@@ -11005,9 +11110,6 @@ msgstr ""
msgid "CycleAnalytics|project dropdown filter"
msgstr ""
-msgid "CycleAnalytics|stage dropdown"
-msgstr ""
-
msgid "DAG visualization requires at least 3 dependent jobs."
msgstr ""
@@ -11107,10 +11209,16 @@ msgstr ""
msgid "DastProfiles|AJAX spider"
msgstr ""
+msgid "DastProfiles|API"
+msgstr ""
+
+msgid "DastProfiles|API endpoint URL"
+msgstr ""
+
msgid "DastProfiles|Active"
msgstr ""
-msgid "DastProfiles|Additional request headers (Optional)"
+msgid "DastProfiles|Additional request headers (optional)"
msgstr ""
msgid "DastProfiles|Are you sure you want to delete this profile?"
@@ -11125,6 +11233,9 @@ msgstr ""
msgid "DastProfiles|Branch missing"
msgstr ""
+msgid "DastProfiles|Choose a scan method"
+msgstr ""
+
msgid "DastProfiles|Could not create the scanner profile. Please try again."
msgstr ""
@@ -11194,7 +11305,13 @@ msgstr ""
msgid "DastProfiles|Excluded URLs"
msgstr ""
-msgid "DastProfiles|Excluded URLs (Optional)"
+msgid "DastProfiles|Excluded URLs (optional)"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths (optional)"
msgstr ""
msgid "DastProfiles|Hide debug messages"
@@ -11251,9 +11368,6 @@ msgstr ""
msgid "DastProfiles|Request headers"
msgstr ""
-msgid "DastProfiles|Rest API"
-msgstr ""
-
msgid "DastProfiles|Run the AJAX spider, in addition to the traditional spider, to crawl the target site."
msgstr ""
@@ -11263,6 +11377,9 @@ msgstr ""
msgid "DastProfiles|Save profile"
msgstr ""
+msgid "DastProfiles|Scan method"
+msgstr ""
+
msgid "DastProfiles|Scan mode"
msgstr ""
@@ -11341,12 +11458,24 @@ msgstr ""
msgid "DastProfiles|Website"
msgstr ""
+msgid "DastProfiles|What does each method do?"
+msgstr ""
+
msgid "DastProfiles|You can either choose a passive scan or validate the target site from the site profile management page. %{docsLinkStart}Learn more about site validation.%{docsLinkEnd}"
msgstr ""
msgid "DastProfiles|You cannot run an active scan against an unvalidated site."
msgstr ""
+msgid "DastProfiles|folder/dast_example.har or https://example.com/dast_example.har"
+msgstr ""
+
+msgid "DastProfiles|folder/example.postman_collection.json or https://example.com/"
+msgstr ""
+
+msgid "DastProfiles|folder/openapi.json or https://example.com/openapi.json"
+msgstr ""
+
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
@@ -11455,6 +11584,9 @@ msgstr ""
msgid "DatadogIntegration|API URL"
msgstr ""
+msgid "DatadogIntegration|Custom tags in Datadog. Enter one tag per line in the %{codeOpen}key:value%{codeClose} format. %{linkOpen}How do I use tags?%{linkClose}"
+msgstr ""
+
msgid "DatadogIntegration|Environment"
msgstr ""
@@ -11473,12 +11605,18 @@ msgstr ""
msgid "DatadogIntegration|Tag all data from this GitLab instance in Datadog. Useful when managing several self-managed deployments."
msgstr ""
+msgid "DatadogIntegration|Tags"
+msgstr ""
+
msgid "DatadogIntegration|The Datadog site to send data to. To send data to the EU site, use %{codeOpen}datadoghq.eu%{codeClose}."
msgstr ""
msgid "DatadogIntegration|Trace your GitLab pipelines with Datadog."
msgstr ""
+msgid "DatadogIntegration|have an invalid format"
+msgstr ""
+
msgid "Datasource name not found"
msgstr ""
@@ -11488,9 +11626,6 @@ msgstr ""
msgid "Date merged"
msgstr ""
-msgid "Date picker"
-msgstr ""
-
msgid "Date range"
msgstr ""
@@ -11644,9 +11779,6 @@ msgstr ""
msgid "Definition"
msgstr ""
-msgid "Delayed Project Deletion (%{adjourned_deletion})"
-msgstr ""
-
msgid "DelayedJobs|Are you sure you want to run %{jobName} immediately? Otherwise this job will run automatically after its timer finishes."
msgstr ""
@@ -11725,10 +11857,10 @@ msgstr ""
msgid "Delete pipeline"
msgstr ""
-msgid "Delete project"
+msgid "Delete pipeline schedule"
msgstr ""
-msgid "Delete project. Are you ABSOLUTELY SURE?"
+msgid "Delete project"
msgstr ""
msgid "Delete row"
@@ -11758,6 +11890,9 @@ msgstr ""
msgid "Delete this epic and all descendants?"
msgstr ""
+msgid "Delete this project"
+msgstr ""
+
msgid "Delete user list"
msgstr ""
@@ -12022,6 +12157,12 @@ msgstr ""
msgid "Deploy to..."
msgstr ""
+msgid "DeployBoards|To see deployment progress for your environments, make sure you are deploying to %{codeStart}$KUBE_NAMESPACE%{codeEnd} and annotating with %{codeStart}app.gitlab.com/app=$CI_PROJECT_PATH_SLUG%{codeEnd} and %{codeStart}app.gitlab.com/env=$CI_ENVIRONMENT_SLUG%{codeEnd}."
+msgstr ""
+
+msgid "DeployBoard|Kubernetes Pods"
+msgstr ""
+
msgid "DeployFreeze|Add a freeze period to prevent unintended releases during a period of time for a given environment. You must update the deployment jobs in %{filename} according to the deploy freezes added here. %{freeze_period_link_start}Learn more.%{freeze_period_link_end}"
msgstr ""
@@ -12106,9 +12247,6 @@ msgstr ""
msgid "DeployTokens|Active Deploy Tokens (%{active_tokens})"
msgstr ""
-msgid "DeployTokens|Allows read and write access to registry images."
-msgstr ""
-
msgid "DeployTokens|Allows read and write access to the package registry."
msgstr ""
@@ -12121,6 +12259,9 @@ msgstr ""
msgid "DeployTokens|Allows read-only access to the repository."
msgstr ""
+msgid "DeployTokens|Allows write access to registry images."
+msgstr ""
+
msgid "DeployTokens|Copy deploy token"
msgstr ""
@@ -12214,12 +12355,57 @@ msgstr ""
msgid "Deploying to AWS is easy with GitLab"
msgstr ""
+msgid "Deployment"
+msgstr ""
+
msgid "Deployment Frequency"
msgstr ""
+msgid "Deployment Target|Project deployment target (optional)"
+msgstr ""
+
+msgid "Deployment Target|Select the deployment target"
+msgstr ""
+
msgid "Deployment frequency"
msgstr ""
+msgid "DeploymentTarget|GitLab Pages"
+msgstr ""
+
+msgid "DeploymentTarget|Heroku"
+msgstr ""
+
+msgid "DeploymentTarget|Infrastructure provider (Terraform, Cloudformation, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Kubernetes (GKE, EKS, OpenShift, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Managed container runtime (Fargate, Cloud Run, DigitalOcean App)"
+msgstr ""
+
+msgid "DeploymentTarget|Mobile app store"
+msgstr ""
+
+msgid "DeploymentTarget|No deployment planned"
+msgstr ""
+
+msgid "DeploymentTarget|Other hosting service"
+msgstr ""
+
+msgid "DeploymentTarget|Registry (package or container)"
+msgstr ""
+
+msgid "DeploymentTarget|Self-managed container runtime (Podman, Docker Swarm, Docker Compose)"
+msgstr ""
+
+msgid "DeploymentTarget|Serverless backend (Lambda, Cloud functions)"
+msgstr ""
+
+msgid "DeploymentTarget|Virtual machine (for example, EC2)"
+msgstr ""
+
msgid "Deployments"
msgstr ""
@@ -12259,6 +12445,9 @@ msgstr ""
msgid "Deployment|This deployment was created using the API"
msgstr ""
+msgid "Deployment|Triggerer"
+msgstr ""
+
msgid "Deployment|Waiting"
msgstr ""
@@ -12286,6 +12475,18 @@ msgstr ""
msgid "Deprecated API rate limits"
msgstr ""
+msgid "Deprecations|Feature deprecation and removal"
+msgstr ""
+
+msgid "Deprecations|For information on a possible replacement %{epicStart} learn more about Opstrace %{epicEnd}."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7 and are %{epicStart} scheduled for removal %{epicEnd} in GitLab 15.0."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7, and are %{removal_link_start} scheduled for removal %{link_end} in GitLab 15.0. For information on a possible replacement, %{opstrace_link_start} learn more about Opstrace %{link_end}."
+msgstr ""
+
msgid "Deprioritize label"
msgstr ""
@@ -12532,10 +12733,10 @@ msgstr ""
msgid "DevopsAdoption|At least one deploy"
msgstr ""
-msgid "DevopsAdoption|At least one issue opened"
+msgid "DevopsAdoption|At least one issue created"
msgstr ""
-msgid "DevopsAdoption|At least one merge request opened"
+msgid "DevopsAdoption|At least one merge request created"
msgstr ""
msgid "DevopsAdoption|At least one pipeline successfully run"
@@ -12739,6 +12940,9 @@ msgstr ""
msgid "Direct member"
msgstr ""
+msgid "Direct members"
+msgstr ""
+
msgid "Direct non-authenticated users to this page."
msgstr ""
@@ -12856,6 +13060,9 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
+msgid "Dismiss Alert"
+msgstr ""
+
msgid "Dismiss merge request promotion"
msgstr ""
@@ -12883,9 +13090,15 @@ msgstr ""
msgid "Display alerts from all configured monitoring tools."
msgstr ""
+msgid "Display milestones"
+msgstr ""
+
msgid "Display name"
msgstr ""
+msgid "Display progress of child issues"
+msgstr ""
+
msgid "Display rendered file"
msgstr ""
@@ -12991,6 +13204,9 @@ msgstr ""
msgid "Download image"
msgstr ""
+msgid "Download payload"
+msgstr ""
+
msgid "Download raw data (.csv)"
msgstr ""
@@ -13168,6 +13384,9 @@ msgstr ""
msgid "Edit in Web IDE"
msgstr ""
+msgid "Edit in pipeline editor"
+msgstr ""
+
msgid "Edit in single-file editor"
msgstr ""
@@ -13210,6 +13429,9 @@ msgstr ""
msgid "Edit your most recent comment in a thread (from an empty textarea)"
msgstr ""
+msgid "Edit, lint, and visualize your pipeline."
+msgstr ""
+
msgid "Edited"
msgstr ""
@@ -13651,6 +13873,9 @@ msgstr ""
msgid "Enforce two-factor authentication for all user sign-ins."
msgstr ""
+msgid "Enhance security by storing service account keys in secret managers - learn more about %{docLinkStart}secret management with GitLab%{docLinkEnd}"
+msgstr ""
+
msgid "Ensure connectivity is available from the GitLab server to the Prometheus server"
msgstr ""
@@ -13711,6 +13936,9 @@ 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 following to confirm:"
+msgstr ""
+
msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
@@ -14242,9 +14470,6 @@ 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 ""
@@ -14380,6 +14605,9 @@ msgstr ""
msgid "Errors:"
msgstr ""
+msgid "Escalate this incident"
+msgstr ""
+
msgid "Escalation Policies"
msgstr ""
@@ -14392,6 +14620,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy"
+msgstr ""
+
msgid "Escalation policy:"
msgstr ""
@@ -14644,6 +14875,9 @@ msgstr ""
msgid "Existing sign in methods may be removed"
msgstr ""
+msgid "Exit."
+msgstr ""
+
msgid "Expand"
msgstr ""
@@ -14740,6 +14974,9 @@ msgstr ""
msgid "Explore public groups"
msgstr ""
+msgid "Explore public projects"
+msgstr ""
+
msgid "Explore snippets"
msgstr ""
@@ -14902,7 +15139,7 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
-msgid "Failed to assign a reviewer because no user was found."
+msgid "Failed to assign a reviewer because no user was specified."
msgstr ""
msgid "Failed to assign a user because no user was found."
@@ -14968,10 +15205,10 @@ msgstr ""
msgid "Failed to find import label for Jira import."
msgstr ""
-msgid "Failed to generate export, please try again later."
+msgid "Failed to find users for %{missing}"
msgstr ""
-msgid "Failed to generate report, please try again after sometime"
+msgid "Failed to generate export, please try again later."
msgstr ""
msgid "Failed to get ref."
@@ -15070,6 +15307,9 @@ msgstr ""
msgid "Failed to remove a to-do item for the design."
msgstr ""
+msgid "Failed to remove attention because no user was found."
+msgstr ""
+
msgid "Failed to remove mirror."
msgstr ""
@@ -15082,6 +15322,9 @@ msgstr ""
msgid "Failed to remove user key."
msgstr ""
+msgid "Failed to request attention because no user was found."
+msgstr ""
+
msgid "Failed to reset key. Please try again."
msgstr ""
@@ -15163,6 +15406,9 @@ msgstr ""
msgid "Feature Flags"
msgstr ""
+msgid "Feature deprecation and removal"
+msgstr ""
+
msgid "Feature flag status"
msgstr ""
@@ -15661,7 +15907,7 @@ msgstr ""
msgid "For each job, re-use the project workspace. If the workspace doesn't exist, use %{code_open}git clone%{code_close}."
msgstr ""
-msgid "For example, the application using the token or the purpose of the token."
+msgid "For example, the application using the token or the purpose of the token. Do not give sensitive information for the name of the token, as it will be visible to all %{resource_type} members."
msgstr ""
msgid "For files larger than this limit, only index the file name. The file content is neither indexed nor searchable."
@@ -15745,9 +15991,6 @@ msgstr ""
msgid "ForkProject|Select a namespace"
msgstr ""
-msgid "ForkProject|Select a namespace to fork the project"
-msgstr ""
-
msgid "ForkProject|The project can be accessed by any logged in user."
msgstr ""
@@ -15844,6 +16087,9 @@ msgstr ""
msgid "Full name"
msgstr ""
+msgid "GCP region configured"
+msgstr ""
+
msgid "GPG Key ID:"
msgstr ""
@@ -16024,6 +16270,9 @@ msgstr ""
msgid "Geo|Failed"
msgstr ""
+msgid "Geo|Filter Geo sites"
+msgstr ""
+
msgid "Geo|Filter by name"
msgstr ""
@@ -16435,6 +16684,12 @@ msgstr ""
msgid "GitLab Issue"
msgstr ""
+msgid "GitLab KAS"
+msgstr ""
+
+msgid "GitLab Memberships CSV Export"
+msgstr ""
+
msgid "GitLab Pages"
msgstr ""
@@ -16483,6 +16738,9 @@ 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 free to use. Many features for larger teams are part of our %{link_start}paid products%{link_end}. You can try Ultimate for free without any obligation or payment details."
+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 ""
@@ -16609,7 +16867,7 @@ msgstr ""
msgid "GitLabPages|When enabled, all attempts to visit your website through HTTP are automatically redirected to HTTPS using a response with status code 301. Requires a valid certificate for all domains. %{docs_link_start}Learn more.%{link_end}"
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. %{docs_link_start}Learn more.%{link_end}"
+msgid "GitLabPages|When using Pages under the general domain of a GitLab instance (%{pages_host}), you cannot use HTTPS with subdomains of subdomains. If your namespace or groupname contains a dot, it does not work. This is a limitation of the HTTP Over TLS protocol. HTTP pages work if you don't redirect HTTP to HTTPS. %{docs_link_start}Learn more.%{link_end}"
msgstr ""
msgid "GitLabPages|With GitLab Pages you can host your static website directly from your GitLab repository. %{docs_link_start}Learn more.%{link_end}"
@@ -16786,9 +17044,6 @@ msgstr ""
msgid "Go to find file"
msgstr ""
-msgid "Go to fork"
-msgstr ""
-
msgid "Go to issue boards"
msgstr ""
@@ -16996,9 +17251,6 @@ msgstr ""
msgid "Group Hooks"
msgstr ""
-msgid "Group ID"
-msgstr ""
-
msgid "Group Owner must have signed in with SAML before enabling Group Managed Accounts"
msgstr ""
@@ -17026,9 +17278,6 @@ msgstr ""
msgid "Group by"
msgstr ""
-msgid "Group description"
-msgstr ""
-
msgid "Group description (optional)"
msgstr ""
@@ -17143,7 +17392,7 @@ msgstr ""
msgid "Group: %{name}"
msgstr ""
-msgid "GroupActivityMetrics|Issues opened"
+msgid "GroupActivityMetrics|Issues created"
msgstr ""
msgid "GroupActivityMetrics|Last 90 days"
@@ -17152,7 +17401,7 @@ msgstr ""
msgid "GroupActivityMetrics|Members added"
msgstr ""
-msgid "GroupActivityMetrics|Merge Requests opened"
+msgid "GroupActivityMetrics|Merge Requests created"
msgstr ""
msgid "GroupActivityMetrics|Recent activity"
@@ -17443,6 +17692,9 @@ msgstr ""
msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
+msgid "GroupSettings|Choose a group path that does not start with a dash or end with a period. It can also contain alphanumeric characters and underscores."
+msgstr ""
+
msgid "GroupSettings|Compliance frameworks"
msgstr ""
@@ -17476,7 +17728,7 @@ msgstr ""
msgid "GroupSettings|If not specified at the group or instance level, the default is %{default_initial_branch_name}. Does not affect existing repositories."
msgstr ""
-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."
+msgid "GroupSettings|If the parent group's visibility is lower than the group's current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility."
msgstr ""
msgid "GroupSettings|New runners registration token has been generated!"
@@ -17593,7 +17845,10 @@ msgstr ""
msgid "Groups and projects"
msgstr ""
-msgid "Groups and subgroups"
+msgid "Groups are a great way to organize projects and people."
+msgstr ""
+
+msgid "Groups are the best way to manage projects and members."
msgstr ""
msgid "Groups to synchronize"
@@ -17704,13 +17959,16 @@ msgstr ""
msgid "GroupsTree|Are you sure you want to leave the \"%{fullName}\" group?"
msgstr ""
-msgid "GroupsTree|Edit group"
+msgid "GroupsTree|Delete"
+msgstr ""
+
+msgid "GroupsTree|Edit"
msgstr ""
msgid "GroupsTree|Failed to leave the group. Please make sure you are not the only owner."
msgstr ""
-msgid "GroupsTree|Leave this group"
+msgid "GroupsTree|Leave group"
msgstr ""
msgid "GroupsTree|Loading groups"
@@ -17722,9 +17980,57 @@ msgstr ""
msgid "GroupsTree|No groups or projects matched your search"
msgstr ""
+msgid "GroupsTree|Options"
+msgstr ""
+
msgid "GroupsTree|Search by name"
msgstr ""
+msgid "Groups|Avatar will be removed. Are you sure?"
+msgstr ""
+
+msgid "Groups|Changing group URL can have unintended side effects."
+msgstr ""
+
+msgid "Groups|Checking group URL availability..."
+msgstr ""
+
+msgid "Groups|Enter a descriptive name for your group."
+msgstr ""
+
+msgid "Groups|Group ID"
+msgstr ""
+
+msgid "Groups|Group URL"
+msgstr ""
+
+msgid "Groups|Group avatar"
+msgstr ""
+
+msgid "Groups|Group description (optional)"
+msgstr ""
+
+msgid "Groups|Group name"
+msgstr ""
+
+msgid "Groups|Group path is available."
+msgstr ""
+
+msgid "Groups|Group path is unavailable. Path has been replaced with a suggested available path."
+msgstr ""
+
+msgid "Groups|Learn more"
+msgstr ""
+
+msgid "Groups|Must start with letter, digit, emoji, or underscore. Can also contain periods, dashes, spaces, and parentheses."
+msgstr ""
+
+msgid "Groups|Remove avatar"
+msgstr ""
+
+msgid "Groups|Save changes"
+msgstr ""
+
msgid "Guideline"
msgstr ""
@@ -17734,6 +18040,9 @@ msgstr ""
msgid "HAR file path or URL"
msgstr ""
+msgid "HTTP Archive (HAR)"
+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 ""
@@ -18136,6 +18445,9 @@ msgstr ""
msgid "INFO: Your SSH key is expiring soon. Please generate a new key."
msgstr ""
+msgid "IP"
+msgstr ""
+
msgid "IP Address"
msgstr ""
@@ -18172,6 +18484,9 @@ msgstr ""
msgid "IdentityVerification|Verify your identity"
msgstr ""
+msgid "IdentityVerification|You can always verify your account at a later time to create a group."
+msgstr ""
+
msgid "If any indexed field exceeds this limit, it is truncated to this number of characters. The rest of the content is neither indexed nor searchable. This does not apply to repository and wiki indexing. For unlimited characters, set this to 0."
msgstr ""
@@ -18229,6 +18544,9 @@ msgstr ""
msgid "If you add %{codeStart}needs%{codeEnd} to jobs in your pipeline you'll be able to view the %{codeStart}needs%{codeEnd} relationships between jobs in this tab as a %{linkStart}Directed Acyclic Graph (DAG)%{linkEnd}."
msgstr ""
+msgid "If you are added to a project, it will be displayed here."
+msgstr ""
+
msgid "If you did not initiate these sign-in attempts, please reach out to your administrator or enable two-factor authentication (2FA) on your account."
msgstr ""
@@ -18538,12 +18856,24 @@ msgstr ""
msgid "InProductMarketing|3 ways to dive into GitLab CI/CD"
msgstr ""
+msgid "InProductMarketing|A single application eliminates complex integrations, data chokepoints, and toolchain maintenance, resulting in greater productivity and lower cost."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features, build more efficiently, strengthen security and compliance."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features."
+msgstr ""
+
msgid "InProductMarketing|Actually, GitLab makes the team work (better)"
msgstr ""
msgid "InProductMarketing|And finally %{deploy_link} a Python application."
msgstr ""
+msgid "InProductMarketing|And many more..."
+msgstr ""
+
msgid "InProductMarketing|Are your runners ready?"
msgstr ""
@@ -18562,15 +18892,33 @@ msgstr ""
msgid "InProductMarketing|Blog"
msgstr ""
+msgid "InProductMarketing|Break down silos to coordinate seamlessly across development, operations, and security with a consistent experience across the development lifecycle."
+msgstr ""
+
+msgid "InProductMarketing|Burn up/down charts"
+msgstr ""
+
msgid "InProductMarketing|By enabling code owners and required merge approvals the right person will review the right MR. This is a win-win: cleaner code and a more efficient review process."
msgstr ""
msgid "InProductMarketing|Click on the number below that corresponds with your answer — 1 being very difficult, 5 being very easy."
msgstr ""
+msgid "InProductMarketing|Code owners"
+msgstr ""
+
msgid "InProductMarketing|Code owners and required merge approvals are part of the paid tiers of GitLab. You can start a free 30-day trial of GitLab Ultimate and enable these features in less than 5 minutes with no credit card required."
msgstr ""
+msgid "InProductMarketing|Code review analytics"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration across stages in GitLab"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration made easy"
+msgstr ""
+
msgid "InProductMarketing|Create a custom CI runner with just a few clicks"
msgstr ""
@@ -18580,12 +18928,21 @@ msgstr ""
msgid "InProductMarketing|Create a project in GitLab in 5 minutes"
msgstr ""
+msgid "InProductMarketing|Create well-defined workflows by using scoped labels on issues, merge requests, and epics. Labels with the same scope cannot be used together, which prevents conflicts."
+msgstr ""
+
msgid "InProductMarketing|Create your first project!"
msgstr ""
+msgid "InProductMarketing|Define who owns specific files or directories, so the right reviewers are suggested when a merge request introduces changes to those files."
+msgstr ""
+
msgid "InProductMarketing|Deliver Better Products Faster"
msgstr ""
+msgid "InProductMarketing|Dependency scanning"
+msgstr ""
+
msgid "InProductMarketing|Did you know teams that use GitLab are far more efficient?"
msgstr ""
@@ -18595,15 +18952,27 @@ msgstr ""
msgid "InProductMarketing|Dig in and create a project and a repo"
msgstr ""
+msgid "InProductMarketing|Discover Premium & Ultimate"
+msgstr ""
+
+msgid "InProductMarketing|Discover Premium & Ultimate."
+msgstr ""
+
msgid "InProductMarketing|Do you have a minute?"
msgstr ""
msgid "InProductMarketing|Do you have a teammate who would be perfect for this task?"
msgstr ""
+msgid "InProductMarketing|Dynamic application security testing"
+msgstr ""
+
msgid "InProductMarketing|Easy"
msgstr ""
+msgid "InProductMarketing|Epics"
+msgstr ""
+
msgid "InProductMarketing|Expand your DevOps journey with a free GitLab trial"
msgstr ""
@@ -18625,9 +18994,15 @@ msgstr ""
msgid "InProductMarketing|Feel the need for speed?"
msgstr ""
+msgid "InProductMarketing|Find and fix bottlenecks in your code review process by understanding how long open merge requests have been in review."
+msgstr ""
+
msgid "InProductMarketing|Find out how your teams are really doing"
msgstr ""
+msgid "InProductMarketing|Find out if your external libraries are safe. Run dependency scanning jobs that check for known vulnerabilities in your external libraries."
+msgstr ""
+
msgid "InProductMarketing|Follow our steps"
msgstr ""
@@ -18664,6 +19039,9 @@ msgstr ""
msgid "InProductMarketing|GitLab is better with teammates to help out!"
msgstr ""
+msgid "InProductMarketing|GitLab is infrastructure agnostic (supporting GCP, AWS, Azure, OpenShift, VMWare, On Prem, Bare Metal, and more), offering a consistent workflow experience – irrespective of the environment."
+msgstr ""
+
msgid "InProductMarketing|GitLab provides static application security testing (SAST), dynamic application security testing (DAST), container scanning, and dependency scanning to help you deliver secure applications along with license compliance."
msgstr ""
@@ -18754,21 +19132,36 @@ msgstr ""
msgid "InProductMarketing|It's also possible to simply %{external_repo_link} in order to take advantage of GitLab's CI/CD."
msgstr ""
+msgid "InProductMarketing|Keep your code quality high by defining who should approve merge requests and how many approvals are required."
+msgstr ""
+
msgid "InProductMarketing|Launch GitLab CI/CD in 20 minutes or less"
msgstr ""
+msgid "InProductMarketing|Lower cost of development"
+msgstr ""
+
+msgid "InProductMarketing|Make it easier to collaborate on high-level ideas by grouping related issues in an epic."
+msgstr ""
+
msgid "InProductMarketing|Making the switch? It's easier than you think to import your projects into GitLab. Move %{github_link}, or import something %{bitbucket_link}."
msgstr ""
msgid "InProductMarketing|Master the art of importing!"
msgstr ""
+msgid "InProductMarketing|Merge request approval rule"
+msgstr ""
+
msgid "InProductMarketing|Move on to easily creating a Pages website %{ci_template_link}"
msgstr ""
msgid "InProductMarketing|Multiple owners, confusing workstreams? We've got you covered"
msgstr ""
+msgid "InProductMarketing|Multiple required approvers"
+msgstr ""
+
msgid "InProductMarketing|Need an alternative to importing?"
msgstr ""
@@ -18781,18 +19174,33 @@ msgstr ""
msgid "InProductMarketing|Our tool brings all the things together"
msgstr ""
+msgid "InProductMarketing|Protect your web application by using DAST to examine for vulnerabilities in deployed environments."
+msgstr ""
+
msgid "InProductMarketing|Rapid development, simplified"
msgstr ""
msgid "InProductMarketing|Reduce Security & Compliance Risk"
msgstr ""
+msgid "InProductMarketing|Require multiple approvers on a merge request, so you know it's in good shape before it's merged."
+msgstr ""
+
+msgid "InProductMarketing|Roadmaps"
+msgstr ""
+
+msgid "InProductMarketing|Scoped labels"
+msgstr ""
+
msgid "InProductMarketing|Security that's integrated into your development lifecycle"
msgstr ""
msgid "InProductMarketing|Sometimes you're not ready to make a full transition to a new tool. If you're not ready to fully commit, %{mirroring_link} gives you a safe way to try out GitLab in parallel with your current tool."
msgstr ""
+msgid "InProductMarketing|Speed. Efficiency. Trust."
+msgstr ""
+
msgid "InProductMarketing|Spin up an autoscaling runner in GitLab"
msgstr ""
@@ -18802,6 +19210,9 @@ msgstr ""
msgid "InProductMarketing|Start a Self-Managed trial"
msgstr ""
+msgid "InProductMarketing|Start a free trial"
+msgstr ""
+
msgid "InProductMarketing|Start a free trial of GitLab Ultimate – no credit card required"
msgstr ""
@@ -18868,6 +19279,9 @@ msgstr ""
msgid "InProductMarketing|To understand and get the most out of GitLab, start at the beginning and %{project_link}. In GitLab, repositories are part of a project, so after you've created your project you can go ahead and %{repo_link}."
msgstr ""
+msgid "InProductMarketing|Track completed issues in a chart, so you can see how a milestone is progressing at a glance."
+msgstr ""
+
msgid "InProductMarketing|Try GitLab Ultimate for free"
msgstr ""
@@ -18904,6 +19318,9 @@ msgstr ""
msgid "InProductMarketing|Very easy"
msgstr ""
+msgid "InProductMarketing|Visualize your epics and milestones in a timeline."
+msgstr ""
+
msgid "InProductMarketing|Want to host GitLab on your servers?"
msgstr ""
@@ -18925,6 +19342,9 @@ msgstr ""
msgid "InProductMarketing|YouTube"
msgstr ""
+msgid "InProductMarketing|Your software, deployed your way"
+msgstr ""
+
msgid "InProductMarketing|Your teams can be more efficient"
msgstr ""
@@ -19045,9 +19465,18 @@ msgstr ""
msgid "IncidentManagement|No incidents to display."
msgstr ""
+msgid "IncidentManagement|None"
+msgstr ""
+
msgid "IncidentManagement|Open"
msgstr ""
+msgid "IncidentManagement|Page your team with escalation policies"
+msgstr ""
+
+msgid "IncidentManagement|Paged"
+msgstr ""
+
msgid "IncidentManagement|Published"
msgstr ""
@@ -19057,6 +19486,9 @@ msgstr ""
msgid "IncidentManagement|Severity"
msgstr ""
+msgid "IncidentManagement|Status"
+msgstr ""
+
msgid "IncidentManagement|There are no closed incidents"
msgstr ""
@@ -19075,6 +19507,9 @@ msgstr ""
msgid "IncidentManagement|Unpublished"
msgstr ""
+msgid "IncidentManagement|Use escalation policies to automatically page your team when incidents are created."
+msgstr ""
+
msgid "IncidentSettings|Activate \"time to SLA\" countdown timer"
msgstr ""
@@ -19120,7 +19555,10 @@ msgstr ""
msgid "Incidents"
msgstr ""
-msgid "Incidents|Add a URL"
+msgid "Incidents|Add image details"
+msgstr ""
+
+msgid "Incidents|Add text or a link to display with your image. If you don't add either, the file name displays instead."
msgstr ""
msgid "Incidents|Drop or %{linkStart}upload%{linkEnd} a metric screenshot to attach it to the incident"
@@ -19135,10 +19573,10 @@ msgstr ""
msgid "Incidents|There was an issue loading metric images."
msgstr ""
-msgid "Incidents|There was an issue uploading your image."
+msgid "Incidents|There was an issue updating your image."
msgstr ""
-msgid "Incidents|You can optionally add a URL to link users to the original graph."
+msgid "Incidents|There was an issue uploading your image."
msgstr ""
msgid "Incident|Alert details"
@@ -19147,9 +19585,18 @@ msgstr ""
msgid "Incident|Are you sure you wish to delete this image?"
msgstr ""
+msgid "Incident|Delete image"
+msgstr ""
+
msgid "Incident|Deleting %{filename}"
msgstr ""
+msgid "Incident|Edit image text or link"
+msgstr ""
+
+msgid "Incident|Editing %{filename}"
+msgstr ""
+
msgid "Incident|Metrics"
msgstr ""
@@ -19420,12 +19867,18 @@ msgstr ""
msgid "Integrations|Branches for which notifications are to be sent"
msgstr ""
+msgid "Integrations|Clear if using a self-signed certificate."
+msgstr ""
+
msgid "Integrations|Comment detail:"
msgstr ""
msgid "Integrations|Comment settings:"
msgstr ""
+msgid "Integrations|Connection details"
+msgstr ""
+
msgid "Integrations|Connection failed. Please check your settings."
msgstr ""
@@ -19450,6 +19903,9 @@ msgstr ""
msgid "Integrations|Enable GitLab.com slash commands in a Slack workspace."
msgstr ""
+msgid "Integrations|Enable SSL verification"
+msgstr ""
+
msgid "Integrations|Enable comments"
msgstr ""
@@ -19528,6 +19984,9 @@ msgstr ""
msgid "Integrations|Return to GitLab for Jira"
msgstr ""
+msgid "Integrations|SSL verification"
+msgstr ""
+
msgid "Integrations|Save settings?"
msgstr ""
@@ -19573,9 +20032,6 @@ msgstr ""
msgid "Integrations|Use default settings"
msgstr ""
-msgid "Integrations|When you mention a Jira issue in a commit or merge request, GitLab creates a remote link and comment (if enabled)."
-msgstr ""
-
msgid "Integrations|You can now close this window and return to the GitLab for Jira application."
msgstr ""
@@ -19600,9 +20056,6 @@ msgstr ""
msgid "Integrations|can't exceed %{recipients_limit}"
msgstr ""
-msgid "Interactive developer security education."
-msgstr ""
-
msgid "Interactive mode"
msgstr ""
@@ -20092,6 +20545,9 @@ msgstr ""
msgid "IssueAnalytics|Assignees"
msgstr ""
+msgid "IssueAnalytics|Created by"
+msgstr ""
+
msgid "IssueAnalytics|Due date"
msgstr ""
@@ -20104,9 +20560,6 @@ msgstr ""
msgid "IssueAnalytics|Milestone"
msgstr ""
-msgid "IssueAnalytics|Opened by"
-msgstr ""
-
msgid "IssueAnalytics|Status"
msgstr ""
@@ -20230,10 +20683,10 @@ msgstr ""
msgid "IssuesAnalytics|Avg/Month:"
msgstr ""
-msgid "IssuesAnalytics|Issues opened"
+msgid "IssuesAnalytics|Issues created"
msgstr ""
-msgid "IssuesAnalytics|Issues opened per month"
+msgid "IssuesAnalytics|Issues created per month"
msgstr ""
msgid "IssuesAnalytics|Last 12 months"
@@ -20260,6 +20713,9 @@ msgstr ""
msgid "It looks like you have some draft commits in this branch."
msgstr ""
+msgid "It looks like you're attempting to activate your subscription. Use %{a_start}the Subscription page%{a_end} instead."
+msgstr ""
+
msgid "It may be several days before you see feature usage data."
msgstr ""
@@ -20488,6 +20944,9 @@ msgstr ""
msgid "JiraConnect|You can now close this window and return to Jira."
msgstr ""
+msgid "JiraConnect|You don't have permission to create branches for this project. Select a different project or contact the project owner for access. %{linkStart}Learn more.%{linkEnd}"
+msgstr ""
+
msgid "JiraRequest|A connection error occurred while connecting to Jira. Try your request again."
msgstr ""
@@ -20536,13 +20995,13 @@ msgstr ""
msgid "JiraService|Define the type of Jira issue to create from a vulnerability."
msgstr ""
-msgid "JiraService|Displaying Jira issues while leaving the GitLab issue functionality enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
+msgid "JiraService|Displaying Jira issues while leaving GitLab issues also enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
msgstr ""
-msgid "JiraService|Enable Jira issues"
+msgid "JiraService|Enable Jira issue creation from vulnerabilities"
msgstr ""
-msgid "JiraService|Enable Jira issues creation from vulnerabilities"
+msgid "JiraService|Enable Jira issues"
msgstr ""
msgid "JiraService|Enable Jira transitions"
@@ -20659,16 +21118,19 @@ msgstr ""
msgid "JiraService|View Jira issues in GitLab"
msgstr ""
-msgid "JiraService|Warning: All GitLab users that have access to this GitLab project are able to view all issues from the Jira project specified below."
+msgid "JiraService|Warning: All GitLab users with access to this GitLab project can view all issues from the Jira project you select."
msgstr ""
msgid "JiraService|Web URL"
msgstr ""
-msgid "JiraService|Work on Jira issues without leaving GitLab. Adds a Jira menu to access your list of Jira issues and view any issue as read-only."
+msgid "JiraService|When a Jira issue is mentioned in a commit or merge request, a remote link and comment (if enabled) will be created."
+msgstr ""
+
+msgid "JiraService|Work on Jira issues without leaving GitLab. Add a Jira menu to access a read-only list of your Jira issues."
msgstr ""
-msgid "JiraService|You need to configure Jira before enabling this integration. For more details, read the %{jira_doc_link_start}Jira integration documentation%{link_end}."
+msgid "JiraService|You must configure Jira before enabling this integration. %{jira_doc_link_start}Learn more.%{link_end}"
msgstr ""
msgid "Job"
@@ -20680,9 +21142,6 @@ msgstr ""
msgid "Job Failed #%{build_id}"
msgstr ""
-msgid "Job ID"
-msgstr ""
-
msgid "Job artifact"
msgstr ""
@@ -20749,9 +21208,27 @@ msgstr ""
msgid "Jobs|You're about to retry a job that failed because it attempted to deploy code that is older than the latest deployment. Retrying this job could result in overwriting the environment with the older source code."
msgstr ""
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source} into %{target}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{ref}"
+msgstr ""
+
+msgid "Job|Are you sure you want to erase this job log and artifacts?"
+msgstr ""
+
msgid "Job|Browse"
msgstr ""
+msgid "Job|Cancel"
+msgstr ""
+
msgid "Job|Complete Raw"
msgstr ""
@@ -20761,6 +21238,9 @@ msgstr ""
msgid "Job|Erase job log and artifacts"
msgstr ""
+msgid "Job|Finished at"
+msgstr ""
+
msgid "Job|Job artifacts"
msgstr ""
@@ -20773,7 +21253,7 @@ msgstr ""
msgid "Job|Keep"
msgstr ""
-msgid "Job|Pipeline"
+msgid "Job|Retry"
msgstr ""
msgid "Job|Scroll to bottom"
@@ -20785,6 +21265,9 @@ msgstr ""
msgid "Job|Show complete raw"
msgstr ""
+msgid "Job|Status"
+msgstr ""
+
msgid "Job|The artifacts were removed"
msgstr ""
@@ -20812,21 +21295,12 @@ msgstr ""
msgid "Job|delayed"
msgstr ""
-msgid "Job|for"
-msgstr ""
-
-msgid "Job|into"
-msgstr ""
-
msgid "Job|manual"
msgstr ""
msgid "Job|triggered"
msgstr ""
-msgid "Job|with"
-msgstr ""
-
msgid "Join Zoom meeting"
msgstr ""
@@ -20929,9 +21403,6 @@ msgstr ""
msgid "Ki"
msgstr ""
-msgid "Kontra"
-msgstr ""
-
msgid "Kroki"
msgstr ""
@@ -21256,6 +21727,9 @@ msgstr ""
msgid "Learn more about Auto DevOps"
msgstr ""
+msgid "Learn more about GitLab"
+msgstr ""
+
msgid "Learn more about Needs relationships"
msgstr ""
@@ -21589,9 +22063,18 @@ msgstr ""
msgid "Licenses|Displays licenses detected in the project, based on the %{linkStart}latest successful%{linkEnd} scan"
msgstr ""
+msgid "Licenses|Drag your license file here or %{linkStart}click to upload%{linkEnd}."
+msgstr ""
+
+msgid "Licenses|Drop your license file to start the upload."
+msgstr ""
+
msgid "Licenses|Error fetching the license list. Please check your network connection and try again."
msgstr ""
+msgid "Licenses|Error: You are trying to upload something other than a file"
+msgstr ""
+
msgid "Licenses|License Compliance"
msgstr ""
@@ -21610,6 +22093,9 @@ msgstr ""
msgid "Licenses|Specified policies in this project"
msgstr ""
+msgid "Licenses|The file could not be uploaded."
+msgstr ""
+
msgid "Licenses|The license list details information about the licenses used within your project."
msgstr ""
@@ -21643,12 +22129,6 @@ msgstr ""
msgid "Limit the size of Sidekiq jobs stored in Redis."
msgstr ""
-msgid "Limited to showing %d event at most"
-msgid_plural "Limited to showing %d events at most"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-
msgid "Limiting mode"
msgstr ""
@@ -21658,6 +22138,9 @@ msgstr ""
msgid "Link"
msgstr ""
+msgid "Link (optional)"
+msgstr ""
+
msgid "Link Prometheus monitoring to GitLab."
msgstr ""
@@ -21694,6 +22177,9 @@ msgstr ""
msgid "Linked emails (%{email_count})"
msgstr ""
+msgid "Linked epics"
+msgstr ""
+
msgid "Linked issues"
msgstr ""
@@ -21721,6 +22207,15 @@ msgstr ""
msgid "List of all merge commits"
msgstr ""
+msgid "List of environments for this project"
+msgstr ""
+
+msgid "List of suitable GCP locations"
+msgstr ""
+
+msgid "List of users allowed to exceed the rate limit."
+msgstr ""
+
msgid "List options"
msgstr ""
@@ -21940,6 +22435,9 @@ msgstr ""
msgid "Maintenance mode"
msgstr ""
+msgid "Make adjustments to how your GitLab instance is set up."
+msgstr ""
+
msgid "Make and review changes in the browser with the Web IDE"
msgstr ""
@@ -22084,6 +22582,12 @@ msgstr ""
msgid "MarkdownEditor|Add italic text (%{modifier_key}I)"
msgstr ""
+msgid "MarkdownEditor|Add strikethrough text (%{modifierKey}⇧X)"
+msgstr ""
+
+msgid "MarkdownEditor|Add strikethrough text (%{modifier_key}⇧X)"
+msgstr ""
+
msgid "Marked For Deletion At - %{deletion_time}"
msgstr ""
@@ -22345,6 +22849,9 @@ msgstr ""
msgid "Maximum push size (MB)"
msgstr ""
+msgid "Maximum requests per 10 minutes per user"
+msgstr ""
+
msgid "Maximum requests per minute"
msgstr ""
@@ -22435,6 +22942,21 @@ msgstr ""
msgid "Members of a group may only view projects they have permission to access"
msgstr ""
+msgid "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seat in use and will be billed for the overage."
+msgid_plural "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seats in use and will be billed for the overage."
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
+msgid "MembersOverage|You are about to incur additional charges"
+msgstr ""
+
+msgid "MembersOverage|Your subscription includes %d seat."
+msgid_plural "MembersOverage|Your subscription includes %d seats."
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
msgid "Membership"
msgstr ""
@@ -22639,9 +23161,6 @@ msgstr ""
msgid "Merge request not merged"
msgstr ""
-msgid "Merge request pipelines 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 merge request pipelines."
-msgstr ""
-
msgid "Merge request reports"
msgstr ""
@@ -22738,13 +23257,13 @@ msgstr ""
msgid "MergeRequests|Create issue to resolve thread"
msgstr ""
-msgid "MergeRequests|Failed to squash. Should be done manually."
+msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Saving the comment failed"
+msgid "MergeRequests|Squashing failed: Squash the commits locally, resolve any conflicts, then push the branch."
msgstr ""
-msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
+msgid "MergeRequests|Squashing not allowed: This project doesn't allow you to squash commits when merging."
msgstr ""
msgid "MergeRequests|Thread stays resolved"
@@ -23587,6 +24106,18 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "MrList|Assigned to %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from assignee %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from reviewer %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Review requested from %{name}, go to their profile."
+msgstr ""
+
msgid "Multi-project"
msgstr ""
@@ -23620,7 +24151,7 @@ msgstr ""
msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "My Awesome Group"
+msgid "My awesome group"
msgstr ""
msgid "My company or team"
@@ -24244,9 +24775,6 @@ msgstr ""
msgid "No available branches"
msgstr ""
-msgid "No available groups to fork the project."
-msgstr ""
-
msgid "No branches found"
msgstr ""
@@ -24457,6 +24985,9 @@ msgstr ""
msgid "No ref selected"
msgstr ""
+msgid "No regions configured"
+msgstr ""
+
msgid "No related merge requests found."
msgstr ""
@@ -25267,6 +25798,9 @@ msgstr ""
msgid "Only reCAPTCHA v2 is supported:"
msgstr ""
+msgid "Only required if not using role instance credentials."
+msgstr ""
+
msgid "Only use lowercase letters, numbers, and underscores."
msgstr ""
@@ -25291,9 +25825,6 @@ msgstr ""
msgid "Open a CLI and connect to the cluster you want to install the agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
-msgid "Open epics"
-msgstr ""
-
msgid "Open errors"
msgstr ""
@@ -25333,7 +25864,7 @@ msgstr ""
msgid "Opened issues"
msgstr ""
-msgid "OpenedNDaysAgo|Opened"
+msgid "OpenedNDaysAgo|Created"
msgstr ""
msgid "Opens in a new window"
@@ -25378,9 +25909,6 @@ msgstr ""
msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
-msgid "Optional."
-msgstr ""
-
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
msgstr ""
@@ -26170,6 +26698,9 @@ msgstr ""
msgid "PerformanceBar|Memory"
msgstr ""
+msgid "PerformanceBar|Memory report"
+msgstr ""
+
msgid "PerformanceBar|Redis calls"
msgstr ""
@@ -26203,18 +26734,12 @@ msgstr ""
msgid "PerformanceBar|wall"
msgstr ""
-msgid "Performs a rebase but skips triggering a new pipeline"
-msgstr ""
-
msgid "Period in seconds"
msgstr ""
msgid "Permalink"
msgstr ""
-msgid "Permanently delete project"
-msgstr ""
-
msgid "Permanently remove group"
msgstr ""
@@ -26485,6 +27010,51 @@ msgstr ""
msgid "PipelineStatusTooltip|Pipeline: %{ci_status}"
msgstr ""
+msgid "PipelineWizardDefaultCommitMessage|Add %{filename}"
+msgstr ""
+
+msgid "PipelineWizardDefaultCommitMessage|Update %{filename}"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|At least one entry is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This field is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This value is not valid"
+msgstr ""
+
+msgid "PipelineWizardListWidget|add another step"
+msgstr ""
+
+msgid "PipelineWizardListWidget|remove step"
+msgstr ""
+
+msgid "PipelineWizard|Commit"
+msgstr ""
+
+msgid "PipelineWizard|Commit Message"
+msgstr ""
+
+msgid "PipelineWizard|Commit changes to your file"
+msgstr ""
+
+msgid "PipelineWizard|Commit file to Branch"
+msgstr ""
+
+msgid "PipelineWizard|Commit your new file"
+msgstr ""
+
+msgid "PipelineWizard|The file has been committed."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem committing the changes."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem while checking whether your file already exists in the specified branch."
+msgstr ""
+
msgid "Pipelines"
msgstr ""
@@ -26599,7 +27169,7 @@ msgstr ""
msgid "Pipelines|Project cache successfully reset."
msgstr ""
-msgid "Pipelines|Revoke"
+msgid "Pipelines|Revoke trigger"
msgstr ""
msgid "Pipelines|Something went wrong while cleaning runners cache."
@@ -26644,6 +27214,12 @@ msgstr ""
msgid "Pipelines|This is a child pipeline within the parent pipeline"
msgstr ""
+msgid "Pipelines|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipelines|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipelines|This pipeline will run code originating from a forked project merge request. This means that the code can potentially have security considerations like exposing CI variables."
msgstr ""
@@ -26686,9 +27262,6 @@ msgstr ""
msgid "Pipelines|Your changes have been successfully committed. Now redirecting to the new merge request page."
msgstr ""
-msgid "Pipelines|detached"
-msgstr ""
-
msgid "Pipelines|error"
msgstr ""
@@ -26698,10 +27271,13 @@ msgstr ""
msgid "Pipelines|latest"
msgstr ""
-msgid "Pipelines|stuck"
+msgid "Pipelines|merge request"
msgstr ""
-msgid "Pipelines|train"
+msgid "Pipelines|merge train"
+msgstr ""
+
+msgid "Pipelines|stuck"
msgstr ""
msgid "Pipelines|yaml invalid"
@@ -26833,6 +27409,12 @@ msgstr ""
msgid "Pipeline|This change will not change the overall test coverage if merged."
msgstr ""
+msgid "Pipeline|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipeline|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipeline|Trigger author"
msgstr ""
@@ -26857,6 +27439,12 @@ msgstr ""
msgid "Pipeline|for"
msgstr ""
+msgid "Pipeline|merge request"
+msgstr ""
+
+msgid "Pipeline|merge train"
+msgstr ""
+
msgid "Pipeline|on"
msgstr ""
@@ -26995,9 +27583,6 @@ msgstr ""
msgid "Please enter a valid time interval"
msgstr ""
-msgid "Please enter or upload a valid license."
-msgstr ""
-
msgid "Please enter your current password."
msgstr ""
@@ -27106,9 +27691,6 @@ msgstr ""
msgid "Please type %{phrase_code} to proceed or close this modal to cancel."
msgstr ""
-msgid "Please type the following to confirm:"
-msgstr ""
-
msgid "Please use this form to report to the admin users who create spam issues, comments or behave inappropriately."
msgstr ""
@@ -27136,12 +27718,27 @@ msgstr ""
msgid "Policies"
msgstr ""
+msgid "Policy '%{escalation_policy_name}' does not exist."
+msgstr ""
+
msgid "Policy management project does have any policies in %{policy_path}"
msgstr ""
msgid "Policy project doesn't exist"
msgstr ""
+msgid "PolicyRuleMultiSelect|%{firstLabel} +%{numberOfAdditionalLabels} more"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|All %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select all"
+msgstr ""
+
msgid "Polling interval multiplier"
msgstr ""
@@ -27370,6 +27967,9 @@ msgstr ""
msgid "Private projects can be created in your personal namespace with:"
msgstr ""
+msgid "Problem with %{name} command: %{message}."
+msgstr ""
+
msgid "Proceed"
msgstr ""
@@ -27844,6 +28444,9 @@ msgstr ""
msgid "Progress"
msgstr ""
+msgid "Progress tracking"
+msgstr ""
+
msgid "Project"
msgstr ""
@@ -28075,6 +28678,9 @@ msgstr ""
msgid "ProjectQualitySummary|Failure"
msgstr ""
+msgid "ProjectQualitySummary|Get insight into the overall percentage of tests in your project that succeed, fail and are skipped."
+msgstr ""
+
msgid "ProjectQualitySummary|Latest pipeline results"
msgstr ""
@@ -28093,6 +28699,12 @@ msgstr ""
msgid "ProjectQualitySummary|See project Code Coverage Statistics"
msgstr ""
+msgid "ProjectQualitySummary|Set up test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|Set up test runs (opens in a new tab)"
+msgstr ""
+
msgid "ProjectQualitySummary|Skipped"
msgstr ""
@@ -28369,13 +28981,19 @@ msgstr ""
msgid "ProjectSettings|LFS objects from this repository are available to forks. %{linkStart}How do I remove them?%{linkEnd}"
msgstr ""
+msgid "ProjectSettings|Learn about commit history."
+msgstr ""
+
+msgid "ProjectSettings|Leave empty to use default template."
+msgstr ""
+
msgid "ProjectSettings|Manage who can see the project in the public access directory."
msgstr ""
msgid "ProjectSettings|Manages large files such as audio, video, and graphics files."
msgstr ""
-msgid "ProjectSettings|Maximum 500 characters."
+msgid "ProjectSettings|Maximum %{maxLength} characters."
msgstr ""
msgid "ProjectSettings|Merge checks"
@@ -28516,6 +29134,9 @@ msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
msgstr ""
+msgid "ProjectSettings|The default template will be applied on save."
+msgstr ""
+
msgid "ProjectSettings|These checks must pass before merge requests can be merged."
msgstr ""
@@ -28570,6 +29191,9 @@ msgstr ""
msgid "ProjectSettings|What are badges?"
msgstr ""
+msgid "ProjectSettings|What are merge trains?"
+msgstr ""
+
msgid "ProjectSettings|When merge request pipelines are enabled in the CI/CD configuration file, pipelines validate the combined results of the source and target branches. %{link_start}How to configure merge request pipelines?%{link_end}"
msgstr ""
@@ -28687,6 +29311,9 @@ msgstr ""
msgid "Projects are organized into groups"
msgstr ""
+msgid "Projects are where you store your code, access issues, wiki and other features of GitLab."
+msgstr ""
+
msgid "Projects contributed to"
msgstr ""
@@ -28702,12 +29329,6 @@ msgstr ""
msgid "Projects to index"
msgstr ""
-msgid "Projects will be permanently deleted after a %{waiting_period}-day waiting period."
-msgstr ""
-
-msgid "Projects will be permanently deleted immediately."
-msgstr ""
-
msgid "Projects with critical vulnerabilities"
msgstr ""
@@ -28792,6 +29413,9 @@ msgstr ""
msgid "ProjectsNew|Import project"
msgstr ""
+msgid "ProjectsNew|Include a Getting Started README"
+msgstr ""
+
msgid "ProjectsNew|Initialize repository with a README"
msgstr ""
@@ -28807,6 +29431,9 @@ msgstr ""
msgid "ProjectsNew|Project description %{tag_start}(optional)%{tag_end}"
msgstr ""
+msgid "ProjectsNew|Recommended if you're new to GitLab"
+msgstr ""
+
msgid "ProjectsNew|Run CI/CD for external repository"
msgstr ""
@@ -29224,6 +29851,9 @@ msgstr ""
msgid "ProtectedBranch|Unprotect"
msgstr ""
+msgid "ProtectedBranch|Unprotect branch"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
@@ -29251,6 +29881,9 @@ msgstr ""
msgid "ProtectedEnvironment|Protected Environment (%{protected_environments_count})"
msgstr ""
+msgid "ProtectedEnvironment|Required approvals"
+msgstr ""
+
msgid "ProtectedEnvironment|Select an environment"
msgstr ""
@@ -29272,10 +29905,13 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|Unprotect tag"
+msgstr ""
+
msgid "ProtectedTags|default"
msgstr ""
-msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
+msgid "ProtectedTag|By default, protected tags restrict who can modify the tag."
msgstr ""
msgid "ProtectedTag|Learn more."
@@ -29338,6 +29974,9 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Public projects are an easy way to allow everyone to have read-only access."
+msgstr ""
+
msgid "Publish to status page"
msgstr ""
@@ -29494,9 +30133,6 @@ msgstr ""
msgid "QualitySummary|Project quality"
msgstr ""
-msgid "Quarters"
-msgstr ""
-
msgid "Query"
msgstr ""
@@ -29581,6 +30217,9 @@ msgstr ""
msgid "Read more about project permissions %{help_link_open}here%{help_link_close}"
msgstr ""
+msgid "Read more about related epics"
+msgstr ""
+
msgid "Read more about related issues"
msgstr ""
@@ -29611,10 +30250,7 @@ msgstr ""
msgid "Rebase source branch on the target branch."
msgstr ""
-msgid "Rebase without CI"
-msgstr ""
-
-msgid "Rebases and triggers a pipeline"
+msgid "Rebase without pipeline"
msgstr ""
msgid "Recaptcha verified?"
@@ -29665,9 +30301,6 @@ msgstr ""
msgid "Reconfigure"
msgstr ""
-msgid "Recovering projects"
-msgstr ""
-
msgid "Recovery Codes"
msgstr ""
@@ -29728,6 +30361,12 @@ msgstr ""
msgid "Regex pattern"
msgstr ""
+msgid "Region"
+msgstr ""
+
+msgid "Regions"
+msgstr ""
+
msgid "Register"
msgstr ""
@@ -29959,9 +30598,6 @@ msgstr ""
msgid "Remove all or specific reviewer(s)"
msgstr ""
-msgid "Remove approver"
-msgstr ""
-
msgid "Remove approvers"
msgstr ""
@@ -29977,6 +30613,9 @@ msgstr ""
msgid "Remove attention request"
msgstr ""
+msgid "Remove attention request(s)"
+msgstr ""
+
msgid "Remove avatar"
msgstr ""
@@ -30115,6 +30754,9 @@ msgstr ""
msgid "Removed an issue from an epic."
msgstr ""
+msgid "Removed attention from %{users_sentence}."
+msgstr ""
+
msgid "Removed attention request from @%{username}"
msgstr ""
@@ -30166,6 +30808,9 @@ msgstr ""
msgid "Removes an issue from an epic."
msgstr ""
+msgid "Removes attention from %{users_sentence}."
+msgstr ""
+
msgid "Removes parent epic %{epic_ref}."
msgstr ""
@@ -30277,6 +30922,9 @@ msgstr ""
msgid "Report abuse to admin"
msgstr ""
+msgid "Report is generating and will be sent to your email address."
+msgstr ""
+
msgid "Reported %{timeAgo} by %{reportedBy}"
msgstr ""
@@ -30571,6 +31219,15 @@ msgstr ""
msgid "Request attention"
msgstr ""
+msgid "Request attention from %{users_sentence}."
+msgstr ""
+
+msgid "Request attention from assignee or reviewer"
+msgstr ""
+
+msgid "Request attention from assignee(s) or reviewer(s)"
+msgstr ""
+
msgid "Request attention to review"
msgstr ""
@@ -30595,6 +31252,9 @@ msgstr ""
msgid "Requested %{time_ago}"
msgstr ""
+msgid "Requested attention from %{users_sentence}."
+msgstr ""
+
msgid "Requested attention from @%{username}"
msgstr ""
@@ -30811,6 +31471,9 @@ msgstr ""
msgid "Restore project"
msgstr ""
+msgid "Restoring projects"
+msgstr ""
+
msgid "Restoring the group will prevent the group, its subgroups and projects from being removed on this date."
msgstr ""
@@ -30841,6 +31504,9 @@ msgstr ""
msgid "Retry"
msgstr ""
+msgid "Retry failed jobs"
+msgstr ""
+
msgid "Retry job"
msgstr ""
@@ -30889,9 +31555,6 @@ msgstr ""
msgid "Review changes"
msgstr ""
-msgid "Review requested from %{name}"
-msgstr ""
-
msgid "Review requests for you"
msgstr ""
@@ -31057,6 +31720,9 @@ msgstr ""
msgid "Runners|Assigned Group"
msgstr ""
+msgid "Runners|Assigned Projects (%{projectCount})"
+msgstr ""
+
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -31126,6 +31792,9 @@ msgstr ""
msgid "Runners|Instance"
msgstr ""
+msgid "Runners|Jobs"
+msgstr ""
+
msgid "Runners|Last contact"
msgstr ""
@@ -31219,9 +31888,6 @@ msgstr ""
msgid "Runners|Runner %{name} was deleted"
msgstr ""
-msgid "Runners|Runner ID"
-msgstr ""
-
msgid "Runners|Runner assigned to project."
msgstr ""
@@ -31369,6 +32035,9 @@ msgstr ""
msgid "Runners|stale"
msgstr ""
+msgid "Runner|This runner has not run any jobs."
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -31483,6 +32152,24 @@ msgstr ""
msgid "Saving project."
msgstr ""
+msgid "ScanResultPolicy|%{ifLabelStart}if%{ifLabelEnd} %{scanners} scan in an open merge request targeting the %{branches} branch(es) finds %{vulnerabilitiesAllowed} or more %{severities} vulnerabilities that are %{vulnerabilityStates}"
+msgstr ""
+
+msgid "ScanResultPolicy|%{thenLabelStart}Then%{thenLabelEnd} Require approval from %{approvalsRequired} of the following approvers: %{approvers}"
+msgstr ""
+
+msgid "ScanResultPolicy|add an approver"
+msgstr ""
+
+msgid "ScanResultPolicy|scanners"
+msgstr ""
+
+msgid "ScanResultPolicy|severity levels"
+msgstr ""
+
+msgid "ScanResultPolicy|vulnerability states"
+msgstr ""
+
msgid "Scanner"
msgstr ""
@@ -31615,6 +32302,9 @@ msgstr ""
msgid "Search for a user"
msgstr ""
+msgid "Search for an emoji"
+msgstr ""
+
msgid "Search for projects, issues, etc."
msgstr ""
@@ -31813,18 +32503,12 @@ msgstr ""
msgid "Secret Detection"
msgstr ""
-msgid "Secret access key"
-msgstr ""
-
msgid "Secret token"
msgstr ""
msgid "Secure token that identifies an external storage request."
msgstr ""
-msgid "SecureCodeWarrior"
-msgstr ""
-
msgid "Security"
msgstr ""
@@ -31849,9 +32533,6 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "Security training with guide and learning pathways."
-msgstr ""
-
msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
@@ -31954,7 +32635,7 @@ msgstr ""
msgid "SecurityConfiguration|Manage corpus"
msgstr ""
-msgid "SecurityConfiguration|Manage corpus files used as mutation sources in coverage fuzzing."
+msgid "SecurityConfiguration|Manage corpus files used as seed inputs with coverage-guided fuzzing."
msgstr ""
msgid "SecurityConfiguration|Manage profiles for use by DAST scans."
@@ -32020,15 +32701,15 @@ msgstr ""
msgid "SecurityOrchestration|.yaml preview"
msgstr ""
-msgid "SecurityOrchestration|Action"
-msgstr ""
-
msgid "SecurityOrchestration|Actions"
msgstr ""
msgid "SecurityOrchestration|Add rule"
msgstr ""
+msgid "SecurityOrchestration|After dismissing the alert, the information will never be shown again."
+msgstr ""
+
msgid "SecurityOrchestration|All policies"
msgstr ""
@@ -32044,7 +32725,7 @@ msgstr ""
msgid "SecurityOrchestration|Description"
msgstr ""
-msgid "SecurityOrchestration|Disabled"
+msgid "SecurityOrchestration|Don't show the alert anymore"
msgstr ""
msgid "SecurityOrchestration|Edit policy"
@@ -32053,13 +32734,13 @@ msgstr ""
msgid "SecurityOrchestration|Edit policy project"
msgstr ""
-msgid "SecurityOrchestration|Enabled"
+msgid "SecurityOrchestration|Empty policy name"
msgstr ""
-msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Enabled"
msgstr ""
-msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
msgstr ""
msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
@@ -32068,7 +32749,7 @@ msgstr ""
msgid "SecurityOrchestration|Invalid policy type"
msgstr ""
-msgid "SecurityOrchestration|Latest scan"
+msgid "SecurityOrchestration|Latest scan run against %{agent}"
msgstr ""
msgid "SecurityOrchestration|Network"
@@ -32077,15 +32758,27 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No actions defined - policy will not run."
+msgstr ""
+
+msgid "SecurityOrchestration|No description"
+msgstr ""
+
msgid "SecurityOrchestration|No rules defined - policy will not run."
msgstr ""
+msgid "SecurityOrchestration|Not enabled"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
msgid "SecurityOrchestration|Policies"
msgstr ""
+msgid "SecurityOrchestration|Policy Type"
+msgstr ""
+
msgid "SecurityOrchestration|Policy cannot be enabled for non-existing branches (%{branches})"
msgstr ""
@@ -32110,10 +32803,13 @@ msgstr ""
msgid "SecurityOrchestration|Require %{approvals} %{plural} from %{approvers} if any of the following occur:"
msgstr ""
-msgid "SecurityOrchestration|Rule"
+msgid "SecurityOrchestration|Rules"
msgstr ""
-msgid "SecurityOrchestration|Rules"
+msgid "SecurityOrchestration|Runs %{actions} and %{lastAction} scans"
+msgstr ""
+
+msgid "SecurityOrchestration|Runs a %{action} scan"
msgstr ""
msgid "SecurityOrchestration|Scan Execution"
@@ -32173,6 +32869,9 @@ msgstr ""
msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
+msgid "SecurityOrchestration|This view only shows scan results for the agent %{agent}. You can view scan results for all agents in the %{linkStart}Operational Vulnerabilities tab of the vulnerability report%{linkEnd}."
+msgstr ""
+
msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
@@ -32227,9 +32926,6 @@ msgstr ""
msgid "SecurityOrchestration|users with ids"
msgstr ""
-msgid "SecurityOrchestration|view results"
-msgstr ""
-
msgid "SecurityOrchestration|vulnerabilities"
msgstr ""
@@ -32899,22 +33595,19 @@ 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|In order to start using functions as a service, you must first install Knative on your Kubernetes cluster. %{linkStart}More information%{linkEnd}"
-msgstr ""
-
msgid "Serverless|Learn more about Serverless"
msgstr ""
msgid "Serverless|No functions available"
msgstr ""
-msgid "Serverless|Sign up for First Look"
+msgid "Serverless|Serverless was %{linkStart}deprecated%{linkEnd} in GitLab 14.3."
+msgstr ""
+
+msgid "Serverless|Serverless was %{postLinkStart}deprecated%{postLinkEnd}. But if you opt to use it, you must install Knative in your Kubernetes cluster first. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "Serverless|The deploy job has not finished."
@@ -32926,9 +33619,6 @@ 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 ""
@@ -32944,9 +33634,6 @@ msgstr ""
msgid "Service Account Key"
msgstr ""
-msgid "Service Accounts"
-msgstr ""
-
msgid "Service Accounts keys authorize GitLab to deploy your Google Cloud project"
msgstr ""
@@ -32956,10 +33643,10 @@ msgstr ""
msgid "Service Desk allows people to create issues in your GitLab instance without their own user account. It provides a unique email address for end users to create issues in a project. Replies can be sent either through the GitLab interface or by email. End users only see threads through email."
msgstr ""
-msgid "Service Usage Data"
+msgid "Service account generated successfully"
msgstr ""
-msgid "Service account generated successfully"
+msgid "Service accounts"
msgstr ""
msgid "Service ping is disabled in your configuration file, and cannot be enabled through this form."
@@ -33103,6 +33790,9 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
+msgid "Set the per-user rate limit for getting a user by ID via the API."
+msgstr ""
+
msgid "Set the per-user rate limit for notes created by web or API requests."
msgstr ""
@@ -33283,6 +33973,9 @@ msgstr ""
msgid "Shared runners details"
msgstr ""
+msgid "Shared runners enabled cannot be enabled until a valid credit card is on file"
+msgstr ""
+
msgid "Shared runners help link"
msgstr ""
@@ -33340,6 +34033,9 @@ msgstr ""
msgid "Show all issues."
msgstr ""
+msgid "Show all milestones"
+msgstr ""
+
msgid "Show all test cases."
msgstr ""
@@ -33376,6 +34072,9 @@ msgstr ""
msgid "Show file contents"
msgstr ""
+msgid "Show group milestones"
+msgstr ""
+
msgid "Show labels"
msgstr ""
@@ -33391,6 +34090,12 @@ msgstr ""
msgid "Show open epics"
msgstr ""
+msgid "Show project milestones"
+msgstr ""
+
+msgid "Show sub-group milestones"
+msgstr ""
+
msgid "Show the Closed list"
msgstr ""
@@ -33400,12 +34105,6 @@ msgstr ""
msgid "Show whitespace changes"
msgstr ""
-msgid "Showing %d event"
-msgid_plural "Showing %d events"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-
msgid "Showing %{conflict} between %{sourceBranch} and %{targetBranch}"
msgstr ""
@@ -33466,12 +34165,6 @@ msgstr ""
msgid "Sidebar|None"
msgstr ""
-msgid "Sidebar|Only numeral characters allowed"
-msgstr ""
-
-msgid "Sidebar|Weight"
-msgstr ""
-
msgid "Sidekiq job compression threshold (bytes)"
msgstr ""
@@ -33634,6 +34327,9 @@ msgstr ""
msgid "Slack logo"
msgstr ""
+msgid "SlackIntegration|Are you sure you want to remove this project from the Slack application?"
+msgstr ""
+
msgid "SlackIntegration|GitLab for Slack"
msgstr ""
@@ -33643,6 +34339,9 @@ msgstr ""
msgid "SlackIntegration|Project alias"
msgstr ""
+msgid "SlackIntegration|Remove project"
+msgstr ""
+
msgid "SlackIntegration|Select a GitLab project to link with your Slack workspace."
msgstr ""
@@ -33787,9 +34486,6 @@ msgstr ""
msgid "Something went wrong trying to load issue contacts."
msgstr ""
-msgid "Something went wrong when creating a work item. Please try again"
-msgstr ""
-
msgid "Something went wrong when reordering designs. Please try again"
msgstr ""
@@ -33883,9 +34579,6 @@ msgstr ""
msgid "Something went wrong while inserting your image. Please try again."
msgstr ""
-msgid "Something went wrong while merging this merge request. Please try again."
-msgstr ""
-
msgid "Something went wrong while obtaining the Let's Encrypt certificate."
msgstr ""
@@ -34207,10 +34900,10 @@ 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."
+msgid "SourcegraphAdmin|Learn more."
msgstr ""
-msgid "SourcegraphAdmin|More information"
+msgid "SourcegraphAdmin|Only public projects have code intelligence enabled and communicate with Sourcegraph."
msgstr ""
msgid "SourcegraphAdmin|Save changes"
@@ -34219,7 +34912,7 @@ msgstr ""
msgid "SourcegraphAdmin|Sourcegraph URL"
msgstr ""
-msgid "SourcegraphAdmin|e.g. https://sourcegraph.example.com"
+msgid "SourcegraphAdmin|https://sourcegraph.example.com"
msgstr ""
msgid "SourcegraphPreferences|This feature is experimental and currently limited to certain projects."
@@ -34354,6 +35047,9 @@ msgstr ""
msgid "Start date"
msgstr ""
+msgid "Start free trial"
+msgstr ""
+
msgid "Start merge train"
msgstr ""
@@ -34384,6 +35080,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started escalation for this incident."
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -34396,6 +35095,9 @@ msgstr ""
msgid "Starts at (UTC)"
msgstr ""
+msgid "Starts escalations for this incident"
+msgstr ""
+
msgid "Starts on"
msgstr ""
@@ -34657,6 +35359,9 @@ msgstr ""
msgid "Strikethrough"
msgstr ""
+msgid "Strikethrough text"
+msgstr ""
+
msgid "Subgroup information"
msgstr ""
@@ -34891,6 +35596,21 @@ msgstr ""
msgid "Subscriptions"
msgstr ""
+msgid "Subscriptions|Chat with sales"
+msgstr ""
+
+msgid "Subscriptions|Close"
+msgstr ""
+
+msgid "Subscriptions|Not ready to buy yet?"
+msgstr ""
+
+msgid "Subscriptions|Start a free trial"
+msgstr ""
+
+msgid "Subscriptions|We understand. Maybe you have some questions for our sales team, or maybe you'd like to try some of the paid features first. What would you like to do?"
+msgstr ""
+
msgid "Subscription|Your subscription for %{strong}%{namespace_name}%{strong_close} has expired and you are now on %{pricing_link_start}the GitLab Free tier%{pricing_link_end}. Don't worry, your data is safe. Get in touch with our support team (%{support_email}). They'll gladly help with your subscription renewal."
msgstr ""
@@ -35101,6 +35821,9 @@ msgstr ""
msgid "SuperSonics|Maximum users"
msgstr ""
+msgid "SuperSonics|Offline cloud"
+msgstr ""
+
msgid "SuperSonics|Paste your activation code"
msgstr ""
@@ -35167,6 +35890,12 @@ msgstr ""
msgid "SuperSonics|You do not have an active subscription"
msgstr ""
+msgid "SuperSonics|You have a future dated license"
+msgstr ""
+
+msgid "SuperSonics|You have added a license that activates on %{date}. Please see the subscription history table below for more details."
+msgstr ""
+
msgid "SuperSonics|You have successfully added a license that activates on %{date}. Please see the subscription history table below for more details."
msgstr ""
@@ -35326,6 +36055,9 @@ msgstr ""
msgid "Tag name is required"
msgstr ""
+msgid "Tag push"
+msgstr ""
+
msgid "Tag push events"
msgstr ""
@@ -35428,6 +36160,9 @@ msgstr ""
msgid "TagsPage|protected"
msgstr ""
+msgid "Take a look at the documentation to discover all of GitLab’s capabilities."
+msgstr ""
+
msgid "Target Branch"
msgstr ""
@@ -35836,6 +36571,9 @@ msgstr ""
msgid "Tests"
msgstr ""
+msgid "Text (optional)"
+msgstr ""
+
msgid "Text added to the body of all email messages. %{character_limit} character limit"
msgstr ""
@@ -35887,6 +36625,9 @@ msgstr ""
msgid "The CSV export will be created in the background. Once finished, it will be sent to %{email} in an attachment."
msgstr ""
+msgid "The CSV export you requested of all user memberships is attached to this email."
+msgstr ""
+
msgid "The GitLab subscription service (customers.gitlab.com) is currently experiencing an outage. You can monitor the status and get updates at %{linkStart}status.gitlab.com%{linkEnd}."
msgstr ""
@@ -35962,6 +36703,9 @@ 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 epic"
+msgstr ""
+
msgid "The current issue"
msgstr ""
@@ -36124,6 +36868,9 @@ msgstr ""
msgid "The latest pipeline for this merge request has failed."
msgstr ""
+msgid "The license key is invalid."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -36139,6 +36886,9 @@ msgstr ""
msgid "The license was successfully uploaded and will be active from %{starts_at}. You can see the details below."
msgstr ""
+msgid "The license you uploaded is invalid. If the issue persists, contact support at %{link}."
+msgstr ""
+
msgid "The list creation wizard is already open"
msgstr ""
@@ -36760,10 +37510,13 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} and everything this project contains. %{strongOpen}There is no going back%{strongClose}"
+msgstr ""
+
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains."
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}on %{date}%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains. %{strongOpen}There is no going back.%{strongClose}"
msgstr ""
msgid "This action will %{strongOpen}permanently remove%{strongClose} %{codeOpen}%{group}%{codeClose} %{strongOpen}immediately%{strongClose}."
@@ -36892,9 +37645,6 @@ msgstr ""
msgid "This file was modified for readability, and can't accept suggestions. Edit it directly."
msgstr ""
-msgid "This forked project has the following:"
-msgstr ""
-
msgid "This form is disabled in preview"
msgstr ""
@@ -36907,7 +37657,7 @@ msgstr ""
msgid "This group can't be removed because it is linked to a subscription. To remove this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
-msgid "This group can't be transfered because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
+msgid "This group can't be transferred because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
msgid "This group cannot be invited to a project inside a group with enforced SSO"
@@ -36934,6 +37684,9 @@ 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 incident is already escalated with '%{escalation_policy_name}'."
+msgstr ""
+
msgid "This invitation was sent to %{mail_to_invite_email}, but you are signed in as %{link_to_current_user} with email %{mail_to_current_user}."
msgstr ""
@@ -36952,9 +37705,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 merge train pipeline"
-msgstr ""
-
msgid "This is a private email address %{helpIcon} generated just for you. Anyone who has it can create issues or merge requests as if they were you. If that happens, %{resetLinkStart}reset this token%{resetLinkEnd}."
msgstr ""
@@ -36976,6 +37726,12 @@ msgstr ""
msgid "This is your current session"
msgstr ""
+msgid "This issue cannot be assigned to a confidential epic because it is public."
+msgstr ""
+
+msgid "This issue cannot be made public because it belongs to a confidential epic."
+msgstr ""
+
msgid "This issue is confidential and should only be visible to team members with at least Reporter access."
msgstr ""
@@ -37093,6 +37849,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 branch is protected from force push."
+msgstr ""
+
msgid "This merge request cannot be rebased while there are conflicts."
msgstr ""
@@ -37144,9 +37903,15 @@ msgstr ""
msgid "This pipeline was triggered by a schedule."
msgstr ""
+msgid "This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project"
msgstr ""
+msgid "This project can be restored until %{date}."
+msgstr ""
+
msgid "This project cannot be %{visibilityLevel} because the visibility of %{openShowLink}%{name}%{closeShowLink} is %{visibility}. To make this project %{visibilityLevel}, you must first %{openEditLink}change the visibility%{closeEditLink} of the parent group."
msgstr ""
@@ -37165,6 +37930,9 @@ msgstr ""
msgid "This project is %{strongStart}NOT%{strongEnd} a fork, and has the following:"
msgstr ""
+msgid "This project is %{strongStart}NOT%{strongEnd} a fork. This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -37858,6 +38626,9 @@ msgstr ""
msgid "Today"
msgstr ""
+msgid "Todos count"
+msgstr ""
+
msgid "Todos|Are you looking for things to do? Take a look at %{strongStart}%{openIssuesLinkStart}open issues%{openIssuesLinkEnd}%{strongEnd}, contribute to %{strongStart}%{mergeRequestLinkStart}a merge request%{mergeRequestLinkEnd}%{mergeRequestLinkEnd}%{strongEnd}, or mention someone in a comment to automatically assign them a new to-do item."
msgstr ""
@@ -38131,11 +38902,8 @@ msgstr ""
msgid "Trending"
msgstr ""
-msgid "Trials|%{planName} Trial %{enDash} %{num} day left"
-msgid_plural "Trials|%{planName} Trial %{enDash} %{num} days left"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgid "Trials|%{planName} Trial"
+msgstr ""
msgid "Trials|Compare all plans"
msgstr ""
@@ -38143,6 +38911,9 @@ msgstr ""
msgid "Trials|Create a new group to start your GitLab Ultimate trial."
msgstr ""
+msgid "Trials|Day %{daysUsed}/%{duration}"
+msgstr ""
+
msgid "Trials|Go back to GitLab"
msgstr ""
@@ -38392,7 +39163,7 @@ msgstr ""
msgid "URL is triggered when repository is updated"
msgstr ""
-msgid "URL must be percent-encoded if neccessary."
+msgid "URL must be percent-encoded if necessary."
msgstr ""
msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
@@ -38611,6 +39382,9 @@ msgstr ""
msgid "Unlock account"
msgstr ""
+msgid "Unlock more features with GitLab Ultimate"
+msgstr ""
+
msgid "Unlock the discussion"
msgstr ""
@@ -38674,6 +39448,9 @@ msgstr ""
msgid "Unsubscribes from this %{quick_action_target}."
msgstr ""
+msgid "Unsupported sort value."
+msgstr ""
+
msgid "Unsupported todo type passed. Supported todo types are: %{todo_types}"
msgstr ""
@@ -38902,6 +39679,9 @@ msgstr ""
msgid "UsageQuota|File attachments and smaller design graphics."
msgstr ""
+msgid "UsageQuota|From %{storage_enforcement_date} storage limits will apply to this namespace. View and manage your usage in %{strong_start}Group Settings &gt; Usage quotas%{strong_end}."
+msgstr ""
+
msgid "UsageQuota|Git repository."
msgstr ""
@@ -38962,6 +39742,9 @@ msgstr ""
msgid "UsageQuota|Storage type"
msgstr ""
+msgid "UsageQuota|Storage used"
+msgstr ""
+
msgid "UsageQuota|This is the total amount of storage used across your projects within this namespace."
msgstr ""
@@ -39157,6 +39940,12 @@ msgstr ""
msgid "Use hashed storage paths for newly created and renamed repositories. Always enabled since 13.0."
msgstr ""
+msgid "Use issue count"
+msgstr ""
+
+msgid "Use issue weight"
+msgstr ""
+
msgid "Use one line per URI"
msgstr ""
@@ -39538,6 +40327,9 @@ msgstr ""
msgid "Users"
msgstr ""
+msgid "Users API rate limit"
+msgstr ""
+
msgid "Users can launch a development environment from a GitLab browser tab when the %{linkStart}Gitpod%{linkEnd} integration is enabled."
msgstr ""
@@ -39865,6 +40657,9 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View group pipeline usage quota"
+msgstr ""
+
msgid "View incident details at"
msgstr ""
@@ -40018,6 +40813,9 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
+msgid "Vulnerability"
+msgstr ""
+
msgid "Vulnerability Report"
msgstr ""
@@ -40069,6 +40867,9 @@ msgstr ""
msgid "VulnerabilityManagement|An unverified non-confirmed finding"
msgstr ""
+msgid "VulnerabilityManagement|At least one identifier is required"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -40078,12 +40879,24 @@ msgstr ""
msgid "VulnerabilityManagement|Create Jira issue"
msgstr ""
+msgid "VulnerabilityManagement|Enter a name"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE code"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE identifier URL"
+msgstr ""
+
msgid "VulnerabilityManagement|Fetching linked Jira issues"
msgstr ""
msgid "VulnerabilityManagement|Manually add a vulnerability entry into the vulnerability report."
msgstr ""
+msgid "VulnerabilityManagement|Name is a required field"
+msgstr ""
+
msgid "VulnerabilityManagement|Needs triage"
msgstr ""
@@ -40099,6 +40912,18 @@ msgstr ""
msgid "VulnerabilityManagement|Select a method"
msgstr ""
+msgid "VulnerabilityManagement|Select a severity level"
+msgstr ""
+
+msgid "VulnerabilityManagement|Select a status"
+msgstr ""
+
+msgid "VulnerabilityManagement|Severity is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Something went wrong while creating vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -40123,6 +40948,12 @@ msgstr ""
msgid "VulnerabilityManagement|Something went wrong, could not update vulnerability state."
msgstr ""
+msgid "VulnerabilityManagement|Status is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Submit vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Summary, detailed description, steps to reproduce, etc."
msgstr ""
@@ -40318,6 +41149,9 @@ msgstr ""
msgid "WARNING:"
msgstr ""
+msgid "WARNING: This snippet contains hidden files which might be used to mask malicious behavior. Exercise caution if cloning and executing code from this snippet."
+msgstr ""
+
msgid "Wait for the file to load to copy its contents"
msgstr ""
@@ -40537,6 +41371,15 @@ msgstr ""
msgid "Webhooks|An issue is created, updated, closed, or reopened."
msgstr ""
+msgid "Webhooks|Are you sure you want to delete this group hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this project hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this webhook?"
+msgstr ""
+
msgid "Webhooks|Comments"
msgstr ""
@@ -40546,6 +41389,9 @@ msgstr ""
msgid "Webhooks|Confidential issues events"
msgstr ""
+msgid "Webhooks|Delete webhook"
+msgstr ""
+
msgid "Webhooks|Deployment events"
msgstr ""
@@ -40780,6 +41626,9 @@ msgstr ""
msgid "Wiki"
msgstr ""
+msgid "Wiki page"
+msgstr ""
+
msgid "Wiki page was successfully created."
msgstr ""
@@ -40885,7 +41734,7 @@ msgstr ""
msgid "WikiPageConflictMessage|Someone edited the page the same time you did. Please check out %{wikiLinkStart}the page%{wikiLinkEnd} and make sure your changes will not unintentionally remove theirs."
msgstr ""
-msgid "WikiPage|An error occured while trying to render the content editor. Please try again later."
+msgid "WikiPage|An error occurred while trying to render the content editor. Please try again later."
msgstr ""
msgid "WikiPage|Are you sure you want to switch back to the classic editor?"
@@ -41044,6 +41893,18 @@ msgstr ""
msgid "WorkItem|New Task"
msgstr ""
+msgid "WorkItem|Something went wrong when creating a work item. Please try again"
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching the work item. Please try again."
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching work item types. Please try again"
+msgstr ""
+
+msgid "WorkItem|Type"
+msgstr ""
+
msgid "WorkItem|Work Items"
msgstr ""
@@ -41110,7 +41971,10 @@ msgstr ""
msgid "You are about to add %{usersTag} people to the discussion. They will all receive a notification."
msgstr ""
-msgid "You are about to permanently delete this project"
+msgid "You are about to delete this forked project containing:"
+msgstr ""
+
+msgid "You are about to delete this project containing:"
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."
@@ -41131,6 +41995,9 @@ msgstr ""
msgid "You are attempting to update a file that has changed since you started editing it."
msgstr ""
+msgid "You are billed if you exceed this number. %{qsrOverageLinkStart}How does billing work?%{qsrOverageLinkEnd}"
+msgstr ""
+
msgid "You are connected to the Prometheus server, but there is currently no data to display."
msgstr ""
@@ -41188,6 +42055,9 @@ msgstr ""
msgid "You are not authorized to update this scanner profile"
msgstr ""
+msgid "You are not authorized to upload metric images"
+msgstr ""
+
msgid "You are now impersonating %{username}"
msgstr ""
@@ -41341,9 +42211,6 @@ msgstr ""
msgid "You can only upload one design when dropping onto an existing design."
msgstr ""
-msgid "You can recover this project until %{date}"
-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 ""
@@ -41392,9 +42259,6 @@ msgstr ""
msgid "You cannot write to this read-only GitLab instance."
msgstr ""
-msgid "You can’t %{tag_start}edit%{tag_end} files directly in this project. Fork this project and submit a merge request with your changes."
-msgstr ""
-
msgid "You can’t edit files directly in this project. Fork this project and submit a merge request with your changes."
msgstr ""
@@ -41548,9 +42412,6 @@ 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 set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
@@ -41581,12 +42442,6 @@ msgstr ""
msgid "You must have maintainer access to force delete a lock"
msgstr ""
-msgid "You must have permission to create a project in a group before forking."
-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 ""
@@ -41992,7 +42847,7 @@ msgstr ""
msgid "Your public email will be displayed on your public profile."
msgstr ""
-msgid "Your request for access could not be processed: %{error_meesage}"
+msgid "Your request for access could not be processed: %{error_message}"
msgstr ""
msgid "Your request for access has been queued for review."
@@ -42178,6 +43033,9 @@ msgstr ""
msgid "archived:"
msgstr ""
+msgid "artifacts"
+msgstr ""
+
msgid "assign yourself"
msgstr ""
@@ -42208,6 +43066,9 @@ msgstr[2] ""
msgid "branch name"
msgstr ""
+msgid "builds"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -42634,6 +43495,9 @@ msgstr ""
msgid "contact with same email already exists in group hierarchy"
msgstr ""
+msgid "container registry images"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -42673,6 +43537,9 @@ msgstr ""
msgid "data"
msgstr ""
+msgid "database"
+msgstr ""
+
msgid "date must not be after 9999-12-31"
msgstr ""
@@ -42697,9 +43564,6 @@ msgstr ""
msgid "design"
msgstr ""
-msgid "detached"
-msgstr ""
-
msgid "disabled"
msgstr ""
@@ -42952,7 +43816,7 @@ msgstr ""
msgid "is not a valid X509 certificate."
msgstr ""
-msgid "is not allowed for sign-up."
+msgid "is not allowed for sign-up. Please use your regular email address."
msgstr ""
msgid "is not allowed for this group."
@@ -42964,7 +43828,7 @@ msgstr ""
msgid "is not allowed since the group is not top-level group."
msgstr ""
-msgid "is not allowed."
+msgid "is not allowed. Please use your regular email address."
msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
@@ -43051,6 +43915,9 @@ msgstr ""
msgid "level: %{level}"
msgstr ""
+msgid "lfs objects"
+msgstr ""
+
msgid "limit of %{project_limit} reached"
msgstr ""
@@ -43273,6 +44140,9 @@ msgstr ""
msgid "mrWidget|Merge blocked: pipeline must succeed. It's waiting for a manual action to continue."
msgstr ""
+msgid "mrWidget|Merge blocked: pipeline must succeed. Push a commit that fixes the failure, or %{linkStart}learn about other solutions.%{linkEnd}"
+msgstr ""
+
msgid "mrWidget|Merge blocked: this merge request must be approved."
msgstr ""
@@ -43390,9 +44260,6 @@ msgstr ""
msgid "mrWidget|The changes were not merged into"
msgstr ""
-msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -43540,9 +44407,6 @@ msgstr ""
msgid "open issue"
msgstr ""
-msgid "opened %{timeAgo}"
-msgstr ""
-
msgid "or"
msgstr ""
@@ -43555,6 +44419,12 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
+msgid "packages"
+msgstr ""
+
+msgid "pages"
+msgstr ""
+
msgid "parent"
msgid_plural "parents"
msgstr[0] ""
@@ -43708,6 +44578,9 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
+msgid "repositories"
+msgstr ""
+
msgid "repository:"
msgstr ""
@@ -43828,12 +44701,18 @@ msgstr ""
msgid "tag name"
msgstr ""
+msgid "terraform states"
+msgstr ""
+
msgid "the correct format."
msgstr ""
msgid "the file"
msgstr ""
+msgid "the following epic(s)"
+msgstr ""
+
msgid "the following issue(s)"
msgstr ""
@@ -43846,21 +44725,12 @@ msgstr ""
msgid "this document"
msgstr ""
-msgid "this issue cannot be assigned to a confidential epic since it is public"
-msgstr ""
-
-msgid "this issue cannot be made public since it belongs to a confidential epic"
-msgstr ""
-
msgid "time summary"
msgstr ""
msgid "toggle collapse"
msgstr ""
-msgid "train"
-msgstr ""
-
msgid "triggered"
msgstr ""
@@ -43990,3 +44860,6 @@ msgstr ""
msgid "{project}"
msgstr ""
+msgid "✔"
+msgstr ""
+
diff --git a/locale/sr_SP/gitlab.po b/locale/sr_SP/gitlab.po
index 8475a4b362e..e250c32e8bf 100644
--- a/locale/sr_SP/gitlab.po
+++ b/locale/sr_SP/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: sr\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2022-02-02 15:42\n"
+"PO-Revision-Date: 2022-03-01 20:36\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -160,6 +160,12 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
+msgid "%d assigned issue"
+msgid_plural "%d assigned issues"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -490,8 +496,26 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
-msgid "%d vulnerability updated"
-msgid_plural "%d vulnerabilities updated"
+msgid "%d vulnerability set to confirmed"
+msgid_plural "%d vulnerabilities set to confirmed"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
+msgid "%d vulnerability set to dismissed"
+msgid_plural "%d vulnerabilities set to dismissed"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
+msgid "%d vulnerability set to needs triage"
+msgid_plural "%d vulnerabilities set to needs triage"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
+msgid "%d vulnerability set to resolved"
+msgid_plural "%d vulnerabilities set to resolved"
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
@@ -586,6 +610,12 @@ msgstr[2] ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{completed} of %{total} issues closed"
+msgstr ""
+
+msgid "%{completed} of %{total} weight completed"
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -940,6 +970,9 @@ msgstr ""
msgid "%{openedIssues} open, %{closedIssues} closed"
msgstr ""
+msgid "%{percentage}%% issues closed"
+msgstr ""
+
msgid "%{percentage}%% weight completed"
msgstr ""
@@ -1384,6 +1417,9 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
+msgid "- of - issues closed"
+msgstr ""
+
msgid "- of - weight completed"
msgstr ""
@@ -1549,7 +1585,7 @@ msgstr ""
msgid "1000+"
msgstr ""
-msgid "192.168.0.0/24"
+msgid "192.168.0.0/24 or 2001:0DB8:1234::/48"
msgstr ""
msgid "1st contribution!"
@@ -1861,13 +1897,13 @@ msgstr ""
msgid "AWS Access Key"
msgstr ""
-msgid "AWS Access Key. Only required if not using role instance credentials"
+msgid "AWS Secret Access Key"
msgstr ""
-msgid "AWS Secret Access Key"
+msgid "AWS access key ID (Optional)"
msgstr ""
-msgid "AWS Secret Access Key. Only required if not using role instance credentials"
+msgid "AWS secret access key (Optional)"
msgstr ""
msgid "AWS service error: %{error}"
@@ -1927,9 +1963,6 @@ msgstr ""
msgid "Access granted"
msgstr ""
-msgid "Access key ID"
-msgstr ""
-
msgid "Access requests"
msgstr ""
@@ -2104,7 +2137,7 @@ msgstr ""
msgid "Activity"
msgstr ""
-msgid "Activity|An error occured while retrieving activity. Reload the page to try again."
+msgid "Activity|An error occurred while retrieving activity. Reload the page to try again."
msgstr ""
msgid "Add"
@@ -2143,6 +2176,9 @@ msgstr ""
msgid "Add a %{type}"
msgstr ""
+msgid "Add a GCP region"
+msgstr ""
+
msgid "Add a GPG key"
msgstr ""
@@ -2194,6 +2230,9 @@ msgstr ""
msgid "Add a numbered list"
msgstr ""
+msgid "Add a related epic"
+msgstr ""
+
msgid "Add a related issue"
msgstr ""
@@ -2308,6 +2347,9 @@ msgstr ""
msgid "Add or subtract spent time"
msgstr ""
+msgid "Add people"
+msgstr ""
+
msgid "Add previously merged commits"
msgstr ""
@@ -2374,6 +2416,9 @@ msgstr ""
msgid "Add webhook"
msgstr ""
+msgid "Add your team members and others to GitLab."
+msgstr ""
+
msgid "Add/remove"
msgstr ""
@@ -3196,12 +3241,6 @@ msgstr ""
msgid "AdvancedSearch|Reindex required"
msgstr ""
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. Permanently deleting this project will %{strongStart}immediately delete%{strongEnd} its repositories and %{strongStart}all related resources%{strongEnd}, including issues, merge requests etc."
-msgstr ""
-
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. You will lose this project's repository and %{strongStart}all related resources%{strongEnd}, including issues and merge requests."
-msgstr ""
-
msgid "After a successful password update you will be redirected to login screen."
msgstr ""
@@ -3232,6 +3271,9 @@ msgstr ""
msgid "Akismet helps prevent the creation of spam issues in public projects."
msgstr ""
+msgid "Alert"
+msgstr ""
+
msgid "AlertManagement|Acknowledged"
msgstr ""
@@ -3604,9 +3646,6 @@ msgstr ""
msgid "All environments"
msgstr ""
-msgid "All epics"
-msgstr ""
-
msgid "All groups and projects"
msgstr ""
@@ -4345,13 +4384,16 @@ msgstr ""
msgid "ApplicationSettings|Approve users in the pending approval status?"
msgstr ""
-msgid "ApplicationSettings|By making this change, you will automatically approve %d user with the pending approval status."
-msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users with the pending approval status."
+msgid "ApplicationSettings|Approve users who are pending approval?"
+msgstr ""
+
+msgid "ApplicationSettings|By making this change, you will automatically approve %d user who is pending approval."
+msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users who are pending approval."
msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
-msgid "ApplicationSettings|By making this change, you will automatically approve all users in pending approval status."
+msgid "ApplicationSettings|By making this change, you will automatically approve all users who are pending approval."
msgstr ""
msgid "ApplicationSettings|Denied domains for sign-ups"
@@ -4762,10 +4804,10 @@ msgstr ""
msgid "Archiving the project will make it entirely read-only. It is hidden from the dashboard and doesn't show up in searches. %{strong_start}The repository cannot be committed to, and no issues, comments, or other entities can be created.%{strong_end} %{link_start}Learn more.%{link_end}"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to delete this project?"
+msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
+msgid "Are you absolutely sure?"
msgstr ""
msgid "Are you sure that you want to archive this project?"
@@ -4801,12 +4843,18 @@ msgstr ""
msgid "Are you sure you want to delete this SSH key?"
msgstr ""
+msgid "Are you sure you want to delete this comment?"
+msgstr ""
+
msgid "Are you sure you want to delete this deploy key?"
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 label?"
+msgstr ""
+
msgid "Are you sure you want to delete this pipeline schedule?"
msgstr ""
@@ -4822,9 +4870,6 @@ msgstr ""
msgid "Are you sure you want to discard your changes?"
msgstr ""
-msgid "Are you sure you want to erase this build?"
-msgstr ""
-
msgid "Are you sure you want to import %d repository?"
msgid_plural "Are you sure you want to import %d repositories?"
msgstr[0] ""
@@ -4873,6 +4918,9 @@ msgstr ""
msgid "Are you sure you want to remove this list?"
msgstr ""
+msgid "Are you sure you want to remove this nickname?"
+msgstr ""
+
msgid "Are you sure you want to reset the health check token?"
msgstr ""
@@ -4885,10 +4933,10 @@ 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?"
+msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
msgstr ""
-msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
+msgid "Are you sure you want to revoke this project access token? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to stop this environment?"
@@ -5035,9 +5083,6 @@ msgstr ""
msgid "Assigned to %{assignee_name}"
msgstr ""
-msgid "Assigned to %{name}"
-msgstr ""
-
msgid "Assigned to me"
msgstr ""
@@ -5104,6 +5149,9 @@ msgstr[2] ""
msgid "Attaching the file failed."
msgstr ""
+msgid "Attention"
+msgstr ""
+
msgid "Audit Events"
msgstr ""
@@ -5266,6 +5314,12 @@ msgstr ""
msgid "Authorized applications (%{size})"
msgstr ""
+msgid "AuthorizedApplication|Are you sure you want to revoke this application?"
+msgstr ""
+
+msgid "AuthorizedApplication|Revoke application"
+msgstr ""
+
msgid "Authors: %{authors}"
msgstr ""
@@ -6463,6 +6517,9 @@ msgstr ""
msgid "CICDAnalytics|Shared Runners Usage"
msgstr ""
+msgid "CICDAnalytics|Shared runner pipeline minute duration by month"
+msgstr ""
+
msgid "CICDAnalytics|Shared runner usage"
msgstr ""
@@ -6604,6 +6661,9 @@ msgstr ""
msgid "Can create groups:"
msgstr ""
+msgid "Can not delete primary training"
+msgstr ""
+
msgid "Can't apply as the source branch was deleted."
msgstr ""
@@ -6937,9 +6997,6 @@ msgstr ""
msgid "Changing any setting here requires an application restart"
msgstr ""
-msgid "Changing group URL can have unintended side effects."
-msgstr ""
-
msgid "Charts can't be displayed as the request for data has timed out. %{documentationLink}"
msgstr ""
@@ -7027,9 +7084,6 @@ msgstr ""
msgid "Checking branch availability..."
msgstr ""
-msgid "Checking group URL availability..."
-msgstr ""
-
msgid "Checking group path availability..."
msgstr ""
@@ -7525,6 +7579,9 @@ msgstr ""
msgid "Clear recent searches"
msgstr ""
+msgid "Clear repository checks"
+msgstr ""
+
msgid "Clear search"
msgstr ""
@@ -7657,9 +7714,6 @@ msgstr ""
msgid "Closed MRs"
msgstr ""
-msgid "Closed epics"
-msgstr ""
-
msgid "Closed issues"
msgstr ""
@@ -7696,13 +7750,13 @@ msgstr ""
msgid "Cluster level"
msgstr ""
-msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
+msgid "Cluster type must be specified for Stages::ClusterEndpointInserter"
msgstr ""
msgid "ClusterAgents|%{name} successfully deleted"
msgstr ""
-msgid "ClusterAgents|%{number} of %{total} Agents"
+msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
@@ -7744,6 +7798,15 @@ msgstr ""
msgid "ClusterAgents|Agent never connected to GitLab"
msgstr ""
+msgid "ClusterAgents|Agent version mismatch"
+msgstr ""
+
+msgid "ClusterAgents|Agent version mismatch and update"
+msgstr ""
+
+msgid "ClusterAgents|Agent version update required"
+msgstr ""
+
msgid "ClusterAgents|All"
msgstr ""
@@ -7768,7 +7831,7 @@ msgstr ""
msgid "ClusterAgents|Configuration"
msgstr ""
-msgid "ClusterAgents|Connect a cluster through the Agent"
+msgid "ClusterAgents|Connect a cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connect existing cluster"
@@ -7777,13 +7840,13 @@ msgstr ""
msgid "ClusterAgents|Connect with a certificate"
msgstr ""
-msgid "ClusterAgents|Connect with agent"
+msgid "ClusterAgents|Connect with an agent"
msgstr ""
msgid "ClusterAgents|Connect with the GitLab Agent"
msgstr ""
-msgid "ClusterAgents|Connect your cluster through the Agent"
+msgid "ClusterAgents|Connect your cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connected"
@@ -7843,7 +7906,10 @@ msgstr ""
msgid "ClusterAgents|How to register an agent?"
msgstr ""
-msgid "ClusterAgents|Install new Agent"
+msgid "ClusterAgents|How to update an agent?"
+msgstr ""
+
+msgid "ClusterAgents|Install a new agent"
msgstr ""
msgid "ClusterAgents|Last connected %{timeAgo}."
@@ -7870,7 +7936,7 @@ msgstr ""
msgid "ClusterAgents|Never connected"
msgstr ""
-msgid "ClusterAgents|No Agents"
+msgid "ClusterAgents|No agents"
msgstr ""
msgid "ClusterAgents|No clusters connected through cluster certificates"
@@ -7930,6 +7996,9 @@ msgstr ""
msgid "ClusterAgents|The agent has not been connected in a long time. There might be a connectivity issue. Last contact was %{timeAgo}."
msgstr ""
+msgid "ClusterAgents|The agent version do not match each other across your cluster's pods. This can happen when a new agent version was just deployed and Kubernetes is shutting down the old pods."
+msgstr ""
+
msgid "ClusterAgents|The recommended installation method includes the token. If you want to follow the advanced installation method provided in the docs, make sure you save the token value before you close this window."
msgstr ""
@@ -7978,6 +8047,9 @@ msgstr ""
msgid "ClusterAgents|You will need to create a token to connect to your agent"
msgstr ""
+msgid "ClusterAgents|Your agent version is out of sync with your GitLab version (v%{version}), which might cause compatibility problems. Update the agent installed on your cluster to the most recent version."
+msgstr ""
+
msgid "ClusterAgents|Your instance doesn't have the %{linkStart}GitLab Agent Server (KAS)%{linkEnd} set up. Ask a GitLab Administrator to install it."
msgstr ""
@@ -8854,9 +8926,6 @@ msgstr ""
msgid "Comma-separated list of email addresses."
msgstr ""
-msgid "Comma-separated list of users allowed to exceed the rate limit."
-msgstr ""
-
msgid "Comma-separated, e.g. '1.1.1.1, 2.2.2.0/24'"
msgstr ""
@@ -9184,6 +9253,12 @@ msgstr ""
msgid "Confidential"
msgstr ""
+msgid "Confidential issue"
+msgstr ""
+
+msgid "Confidential note"
+msgstr ""
+
msgid "Confidentiality"
msgstr ""
@@ -9217,6 +9292,9 @@ msgstr ""
msgid "Configure Dependency Scanning in `.gitlab-ci.yml`, creating this file if it does not already exist"
msgstr ""
+msgid "Configure GitLab"
+msgstr ""
+
msgid "Configure GitLab runners to start using the Web Terminal. %{helpStart}Learn more.%{helpEnd}"
msgstr ""
@@ -9265,6 +9343,15 @@ msgstr ""
msgid "Configure pipelines to deploy web apps, backend services, APIs and static resources to Google Cloud"
msgstr ""
+msgid "Configure region"
+msgstr ""
+
+msgid "Configure region for environment"
+msgstr ""
+
+msgid "Configure regions"
+msgstr ""
+
msgid "Configure repository mirroring."
msgstr ""
@@ -9298,6 +9385,9 @@ msgstr ""
msgid "Configure which lists are shown for anyone who visits this board"
msgstr ""
+msgid "Configure your environments to be deployed to specific geographical regions"
+msgstr ""
+
msgid "Confirm"
msgstr ""
@@ -10003,10 +10093,10 @@ msgstr ""
msgid "CorpusManagement|Actions"
msgstr ""
-msgid "CorpusManagement|Corpus are used in fuzz testing as mutation source to Improve future testing."
+msgid "CorpusManagement|Corpus file"
msgstr ""
-msgid "CorpusManagement|Corpus file"
+msgid "CorpusManagement|Corpus files are used in coverage-guided fuzz testing as seed inputs to improve testing."
msgstr ""
msgid "CorpusManagement|Corpus files must be in *.zip format. Maximum 5 GB"
@@ -10060,6 +10150,9 @@ msgstr ""
msgid "Could not apply %{name} command."
msgstr ""
+msgid "Could not apply %{name} command. %{message}."
+msgstr ""
+
msgid "Could not authorize chat nickname. Try again!"
msgstr ""
@@ -10210,6 +10303,9 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
+msgid "Create a group"
+msgstr ""
+
msgid "Create a merge request"
msgstr ""
@@ -10234,6 +10330,9 @@ msgstr ""
msgid "Create a personal access token on your account to pull or push via %{protocol}."
msgstr ""
+msgid "Create a project"
+msgstr ""
+
msgid "Create an account using:"
msgstr ""
@@ -10597,6 +10696,9 @@ msgstr ""
msgid "Creation date"
msgstr ""
+msgid "Creator"
+msgstr ""
+
msgid "Credentials"
msgstr ""
@@ -10609,9 +10711,15 @@ msgstr ""
msgid "CredentialsInventory|Personal Access Tokens"
msgstr ""
+msgid "CredentialsInventory|Project Access Tokens"
+msgstr ""
+
msgid "CredentialsInventory|SSH Keys"
msgstr ""
+msgid "Credit card required to be on file in order to create a pipeline"
+msgstr ""
+
msgid "Credit card:"
msgstr ""
@@ -10795,9 +10903,6 @@ msgstr ""
msgid "Customer relations"
msgstr ""
-msgid "Customizable by an administrator."
-msgstr ""
-
msgid "Customizable by owners."
msgstr ""
@@ -10927,30 +11032,18 @@ msgstr ""
msgid "CycleAnalytics|%{selectedLabelsCount} selected (%{maxLabels} max)"
msgstr ""
-msgid "CycleAnalytics|%{stageCount} stages selected"
-msgstr ""
-
-msgid "CycleAnalytics|All stages"
-msgstr ""
-
-msgid "CycleAnalytics|Average days to completion"
+msgid "CycleAnalytics|Average time to completion"
msgstr ""
msgid "CycleAnalytics|Date"
msgstr ""
-msgid "CycleAnalytics|Days to completion"
-msgstr ""
-
msgid "CycleAnalytics|Display chart filters"
msgstr ""
msgid "CycleAnalytics|Lead Time for Changes"
msgstr ""
-msgid "CycleAnalytics|No stages selected"
-msgstr ""
-
msgid "CycleAnalytics|Number of tasks"
msgstr ""
@@ -10981,18 +11074,30 @@ msgstr ""
msgid "CycleAnalytics|Showing data for group '%{groupName}' from %{createdAfter} to %{createdBefore}"
msgstr ""
-msgid "CycleAnalytics|Stages"
+msgid "CycleAnalytics|Stage time: %{title}"
msgstr ""
msgid "CycleAnalytics|Tasks by type"
msgstr ""
-msgid "CycleAnalytics|The average time spent in the selected stage for the items that were completed on each date. Data limited to the last 500 items."
+msgid "CycleAnalytics|The average time items spent in this stage. Data limited to items completed within this date range."
msgstr ""
msgid "CycleAnalytics|The given date range is larger than 180 days"
msgstr ""
+msgid "CycleAnalytics|The total time items spent across each value stream stage. Data limited to items completed within this date range."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Stage time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Total time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|Total time"
+msgstr ""
+
msgid "CycleAnalytics|Type of work"
msgstr ""
@@ -11005,9 +11110,6 @@ msgstr ""
msgid "CycleAnalytics|project dropdown filter"
msgstr ""
-msgid "CycleAnalytics|stage dropdown"
-msgstr ""
-
msgid "DAG visualization requires at least 3 dependent jobs."
msgstr ""
@@ -11107,10 +11209,16 @@ msgstr ""
msgid "DastProfiles|AJAX spider"
msgstr ""
+msgid "DastProfiles|API"
+msgstr ""
+
+msgid "DastProfiles|API endpoint URL"
+msgstr ""
+
msgid "DastProfiles|Active"
msgstr ""
-msgid "DastProfiles|Additional request headers (Optional)"
+msgid "DastProfiles|Additional request headers (optional)"
msgstr ""
msgid "DastProfiles|Are you sure you want to delete this profile?"
@@ -11125,6 +11233,9 @@ msgstr ""
msgid "DastProfiles|Branch missing"
msgstr ""
+msgid "DastProfiles|Choose a scan method"
+msgstr ""
+
msgid "DastProfiles|Could not create the scanner profile. Please try again."
msgstr ""
@@ -11194,7 +11305,13 @@ msgstr ""
msgid "DastProfiles|Excluded URLs"
msgstr ""
-msgid "DastProfiles|Excluded URLs (Optional)"
+msgid "DastProfiles|Excluded URLs (optional)"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths (optional)"
msgstr ""
msgid "DastProfiles|Hide debug messages"
@@ -11251,9 +11368,6 @@ msgstr ""
msgid "DastProfiles|Request headers"
msgstr ""
-msgid "DastProfiles|Rest API"
-msgstr ""
-
msgid "DastProfiles|Run the AJAX spider, in addition to the traditional spider, to crawl the target site."
msgstr ""
@@ -11263,6 +11377,9 @@ msgstr ""
msgid "DastProfiles|Save profile"
msgstr ""
+msgid "DastProfiles|Scan method"
+msgstr ""
+
msgid "DastProfiles|Scan mode"
msgstr ""
@@ -11341,12 +11458,24 @@ msgstr ""
msgid "DastProfiles|Website"
msgstr ""
+msgid "DastProfiles|What does each method do?"
+msgstr ""
+
msgid "DastProfiles|You can either choose a passive scan or validate the target site from the site profile management page. %{docsLinkStart}Learn more about site validation.%{docsLinkEnd}"
msgstr ""
msgid "DastProfiles|You cannot run an active scan against an unvalidated site."
msgstr ""
+msgid "DastProfiles|folder/dast_example.har or https://example.com/dast_example.har"
+msgstr ""
+
+msgid "DastProfiles|folder/example.postman_collection.json or https://example.com/"
+msgstr ""
+
+msgid "DastProfiles|folder/openapi.json or https://example.com/openapi.json"
+msgstr ""
+
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
@@ -11455,6 +11584,9 @@ msgstr ""
msgid "DatadogIntegration|API URL"
msgstr ""
+msgid "DatadogIntegration|Custom tags in Datadog. Enter one tag per line in the %{codeOpen}key:value%{codeClose} format. %{linkOpen}How do I use tags?%{linkClose}"
+msgstr ""
+
msgid "DatadogIntegration|Environment"
msgstr ""
@@ -11473,12 +11605,18 @@ msgstr ""
msgid "DatadogIntegration|Tag all data from this GitLab instance in Datadog. Useful when managing several self-managed deployments."
msgstr ""
+msgid "DatadogIntegration|Tags"
+msgstr ""
+
msgid "DatadogIntegration|The Datadog site to send data to. To send data to the EU site, use %{codeOpen}datadoghq.eu%{codeClose}."
msgstr ""
msgid "DatadogIntegration|Trace your GitLab pipelines with Datadog."
msgstr ""
+msgid "DatadogIntegration|have an invalid format"
+msgstr ""
+
msgid "Datasource name not found"
msgstr ""
@@ -11488,9 +11626,6 @@ msgstr ""
msgid "Date merged"
msgstr ""
-msgid "Date picker"
-msgstr ""
-
msgid "Date range"
msgstr ""
@@ -11644,9 +11779,6 @@ msgstr ""
msgid "Definition"
msgstr ""
-msgid "Delayed Project Deletion (%{adjourned_deletion})"
-msgstr ""
-
msgid "DelayedJobs|Are you sure you want to run %{jobName} immediately? Otherwise this job will run automatically after its timer finishes."
msgstr ""
@@ -11725,10 +11857,10 @@ msgstr ""
msgid "Delete pipeline"
msgstr ""
-msgid "Delete project"
+msgid "Delete pipeline schedule"
msgstr ""
-msgid "Delete project. Are you ABSOLUTELY SURE?"
+msgid "Delete project"
msgstr ""
msgid "Delete row"
@@ -11758,6 +11890,9 @@ msgstr ""
msgid "Delete this epic and all descendants?"
msgstr ""
+msgid "Delete this project"
+msgstr ""
+
msgid "Delete user list"
msgstr ""
@@ -12022,6 +12157,12 @@ msgstr ""
msgid "Deploy to..."
msgstr ""
+msgid "DeployBoards|To see deployment progress for your environments, make sure you are deploying to %{codeStart}$KUBE_NAMESPACE%{codeEnd} and annotating with %{codeStart}app.gitlab.com/app=$CI_PROJECT_PATH_SLUG%{codeEnd} and %{codeStart}app.gitlab.com/env=$CI_ENVIRONMENT_SLUG%{codeEnd}."
+msgstr ""
+
+msgid "DeployBoard|Kubernetes Pods"
+msgstr ""
+
msgid "DeployFreeze|Add a freeze period to prevent unintended releases during a period of time for a given environment. You must update the deployment jobs in %{filename} according to the deploy freezes added here. %{freeze_period_link_start}Learn more.%{freeze_period_link_end}"
msgstr ""
@@ -12106,9 +12247,6 @@ msgstr ""
msgid "DeployTokens|Active Deploy Tokens (%{active_tokens})"
msgstr ""
-msgid "DeployTokens|Allows read and write access to registry images."
-msgstr ""
-
msgid "DeployTokens|Allows read and write access to the package registry."
msgstr ""
@@ -12121,6 +12259,9 @@ msgstr ""
msgid "DeployTokens|Allows read-only access to the repository."
msgstr ""
+msgid "DeployTokens|Allows write access to registry images."
+msgstr ""
+
msgid "DeployTokens|Copy deploy token"
msgstr ""
@@ -12214,12 +12355,57 @@ msgstr ""
msgid "Deploying to AWS is easy with GitLab"
msgstr ""
+msgid "Deployment"
+msgstr ""
+
msgid "Deployment Frequency"
msgstr ""
+msgid "Deployment Target|Project deployment target (optional)"
+msgstr ""
+
+msgid "Deployment Target|Select the deployment target"
+msgstr ""
+
msgid "Deployment frequency"
msgstr ""
+msgid "DeploymentTarget|GitLab Pages"
+msgstr ""
+
+msgid "DeploymentTarget|Heroku"
+msgstr ""
+
+msgid "DeploymentTarget|Infrastructure provider (Terraform, Cloudformation, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Kubernetes (GKE, EKS, OpenShift, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Managed container runtime (Fargate, Cloud Run, DigitalOcean App)"
+msgstr ""
+
+msgid "DeploymentTarget|Mobile app store"
+msgstr ""
+
+msgid "DeploymentTarget|No deployment planned"
+msgstr ""
+
+msgid "DeploymentTarget|Other hosting service"
+msgstr ""
+
+msgid "DeploymentTarget|Registry (package or container)"
+msgstr ""
+
+msgid "DeploymentTarget|Self-managed container runtime (Podman, Docker Swarm, Docker Compose)"
+msgstr ""
+
+msgid "DeploymentTarget|Serverless backend (Lambda, Cloud functions)"
+msgstr ""
+
+msgid "DeploymentTarget|Virtual machine (for example, EC2)"
+msgstr ""
+
msgid "Deployments"
msgstr ""
@@ -12259,6 +12445,9 @@ msgstr ""
msgid "Deployment|This deployment was created using the API"
msgstr ""
+msgid "Deployment|Triggerer"
+msgstr ""
+
msgid "Deployment|Waiting"
msgstr ""
@@ -12286,6 +12475,18 @@ msgstr ""
msgid "Deprecated API rate limits"
msgstr ""
+msgid "Deprecations|Feature deprecation and removal"
+msgstr ""
+
+msgid "Deprecations|For information on a possible replacement %{epicStart} learn more about Opstrace %{epicEnd}."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7 and are %{epicStart} scheduled for removal %{epicEnd} in GitLab 15.0."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7, and are %{removal_link_start} scheduled for removal %{link_end} in GitLab 15.0. For information on a possible replacement, %{opstrace_link_start} learn more about Opstrace %{link_end}."
+msgstr ""
+
msgid "Deprioritize label"
msgstr ""
@@ -12532,10 +12733,10 @@ msgstr ""
msgid "DevopsAdoption|At least one deploy"
msgstr ""
-msgid "DevopsAdoption|At least one issue opened"
+msgid "DevopsAdoption|At least one issue created"
msgstr ""
-msgid "DevopsAdoption|At least one merge request opened"
+msgid "DevopsAdoption|At least one merge request created"
msgstr ""
msgid "DevopsAdoption|At least one pipeline successfully run"
@@ -12739,6 +12940,9 @@ msgstr ""
msgid "Direct member"
msgstr ""
+msgid "Direct members"
+msgstr ""
+
msgid "Direct non-authenticated users to this page."
msgstr ""
@@ -12856,6 +13060,9 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
+msgid "Dismiss Alert"
+msgstr ""
+
msgid "Dismiss merge request promotion"
msgstr ""
@@ -12883,9 +13090,15 @@ msgstr ""
msgid "Display alerts from all configured monitoring tools."
msgstr ""
+msgid "Display milestones"
+msgstr ""
+
msgid "Display name"
msgstr ""
+msgid "Display progress of child issues"
+msgstr ""
+
msgid "Display rendered file"
msgstr ""
@@ -12991,6 +13204,9 @@ msgstr ""
msgid "Download image"
msgstr ""
+msgid "Download payload"
+msgstr ""
+
msgid "Download raw data (.csv)"
msgstr ""
@@ -13168,6 +13384,9 @@ msgstr ""
msgid "Edit in Web IDE"
msgstr ""
+msgid "Edit in pipeline editor"
+msgstr ""
+
msgid "Edit in single-file editor"
msgstr ""
@@ -13210,6 +13429,9 @@ msgstr ""
msgid "Edit your most recent comment in a thread (from an empty textarea)"
msgstr ""
+msgid "Edit, lint, and visualize your pipeline."
+msgstr ""
+
msgid "Edited"
msgstr ""
@@ -13651,6 +13873,9 @@ msgstr ""
msgid "Enforce two-factor authentication for all user sign-ins."
msgstr ""
+msgid "Enhance security by storing service account keys in secret managers - learn more about %{docLinkStart}secret management with GitLab%{docLinkEnd}"
+msgstr ""
+
msgid "Ensure connectivity is available from the GitLab server to the Prometheus server"
msgstr ""
@@ -13711,6 +13936,9 @@ 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 following to confirm:"
+msgstr ""
+
msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
@@ -14242,9 +14470,6 @@ 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 ""
@@ -14380,6 +14605,9 @@ msgstr ""
msgid "Errors:"
msgstr ""
+msgid "Escalate this incident"
+msgstr ""
+
msgid "Escalation Policies"
msgstr ""
@@ -14392,6 +14620,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy"
+msgstr ""
+
msgid "Escalation policy:"
msgstr ""
@@ -14644,6 +14875,9 @@ msgstr ""
msgid "Existing sign in methods may be removed"
msgstr ""
+msgid "Exit."
+msgstr ""
+
msgid "Expand"
msgstr ""
@@ -14740,6 +14974,9 @@ msgstr ""
msgid "Explore public groups"
msgstr ""
+msgid "Explore public projects"
+msgstr ""
+
msgid "Explore snippets"
msgstr ""
@@ -14902,7 +15139,7 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
-msgid "Failed to assign a reviewer because no user was found."
+msgid "Failed to assign a reviewer because no user was specified."
msgstr ""
msgid "Failed to assign a user because no user was found."
@@ -14968,10 +15205,10 @@ msgstr ""
msgid "Failed to find import label for Jira import."
msgstr ""
-msgid "Failed to generate export, please try again later."
+msgid "Failed to find users for %{missing}"
msgstr ""
-msgid "Failed to generate report, please try again after sometime"
+msgid "Failed to generate export, please try again later."
msgstr ""
msgid "Failed to get ref."
@@ -15070,6 +15307,9 @@ msgstr ""
msgid "Failed to remove a to-do item for the design."
msgstr ""
+msgid "Failed to remove attention because no user was found."
+msgstr ""
+
msgid "Failed to remove mirror."
msgstr ""
@@ -15082,6 +15322,9 @@ msgstr ""
msgid "Failed to remove user key."
msgstr ""
+msgid "Failed to request attention because no user was found."
+msgstr ""
+
msgid "Failed to reset key. Please try again."
msgstr ""
@@ -15163,6 +15406,9 @@ msgstr ""
msgid "Feature Flags"
msgstr ""
+msgid "Feature deprecation and removal"
+msgstr ""
+
msgid "Feature flag status"
msgstr ""
@@ -15661,7 +15907,7 @@ msgstr ""
msgid "For each job, re-use the project workspace. If the workspace doesn't exist, use %{code_open}git clone%{code_close}."
msgstr ""
-msgid "For example, the application using the token or the purpose of the token."
+msgid "For example, the application using the token or the purpose of the token. Do not give sensitive information for the name of the token, as it will be visible to all %{resource_type} members."
msgstr ""
msgid "For files larger than this limit, only index the file name. The file content is neither indexed nor searchable."
@@ -15745,9 +15991,6 @@ msgstr ""
msgid "ForkProject|Select a namespace"
msgstr ""
-msgid "ForkProject|Select a namespace to fork the project"
-msgstr ""
-
msgid "ForkProject|The project can be accessed by any logged in user."
msgstr ""
@@ -15844,6 +16087,9 @@ msgstr ""
msgid "Full name"
msgstr ""
+msgid "GCP region configured"
+msgstr ""
+
msgid "GPG Key ID:"
msgstr ""
@@ -16024,6 +16270,9 @@ msgstr ""
msgid "Geo|Failed"
msgstr ""
+msgid "Geo|Filter Geo sites"
+msgstr ""
+
msgid "Geo|Filter by name"
msgstr ""
@@ -16435,6 +16684,12 @@ msgstr ""
msgid "GitLab Issue"
msgstr ""
+msgid "GitLab KAS"
+msgstr ""
+
+msgid "GitLab Memberships CSV Export"
+msgstr ""
+
msgid "GitLab Pages"
msgstr ""
@@ -16483,6 +16738,9 @@ 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 free to use. Many features for larger teams are part of our %{link_start}paid products%{link_end}. You can try Ultimate for free without any obligation or payment details."
+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 ""
@@ -16609,7 +16867,7 @@ msgstr ""
msgid "GitLabPages|When enabled, all attempts to visit your website through HTTP are automatically redirected to HTTPS using a response with status code 301. Requires a valid certificate for all domains. %{docs_link_start}Learn more.%{link_end}"
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. %{docs_link_start}Learn more.%{link_end}"
+msgid "GitLabPages|When using Pages under the general domain of a GitLab instance (%{pages_host}), you cannot use HTTPS with subdomains of subdomains. If your namespace or groupname contains a dot, it does not work. This is a limitation of the HTTP Over TLS protocol. HTTP pages work if you don't redirect HTTP to HTTPS. %{docs_link_start}Learn more.%{link_end}"
msgstr ""
msgid "GitLabPages|With GitLab Pages you can host your static website directly from your GitLab repository. %{docs_link_start}Learn more.%{link_end}"
@@ -16786,9 +17044,6 @@ msgstr ""
msgid "Go to find file"
msgstr ""
-msgid "Go to fork"
-msgstr ""
-
msgid "Go to issue boards"
msgstr ""
@@ -16996,9 +17251,6 @@ msgstr ""
msgid "Group Hooks"
msgstr ""
-msgid "Group ID"
-msgstr ""
-
msgid "Group Owner must have signed in with SAML before enabling Group Managed Accounts"
msgstr ""
@@ -17026,9 +17278,6 @@ msgstr ""
msgid "Group by"
msgstr ""
-msgid "Group description"
-msgstr ""
-
msgid "Group description (optional)"
msgstr ""
@@ -17143,7 +17392,7 @@ msgstr ""
msgid "Group: %{name}"
msgstr ""
-msgid "GroupActivityMetrics|Issues opened"
+msgid "GroupActivityMetrics|Issues created"
msgstr ""
msgid "GroupActivityMetrics|Last 90 days"
@@ -17152,7 +17401,7 @@ msgstr ""
msgid "GroupActivityMetrics|Members added"
msgstr ""
-msgid "GroupActivityMetrics|Merge Requests opened"
+msgid "GroupActivityMetrics|Merge Requests created"
msgstr ""
msgid "GroupActivityMetrics|Recent activity"
@@ -17443,6 +17692,9 @@ msgstr ""
msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
+msgid "GroupSettings|Choose a group path that does not start with a dash or end with a period. It can also contain alphanumeric characters and underscores."
+msgstr ""
+
msgid "GroupSettings|Compliance frameworks"
msgstr ""
@@ -17476,7 +17728,7 @@ msgstr ""
msgid "GroupSettings|If not specified at the group or instance level, the default is %{default_initial_branch_name}. Does not affect existing repositories."
msgstr ""
-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."
+msgid "GroupSettings|If the parent group's visibility is lower than the group's current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility."
msgstr ""
msgid "GroupSettings|New runners registration token has been generated!"
@@ -17593,7 +17845,10 @@ msgstr ""
msgid "Groups and projects"
msgstr ""
-msgid "Groups and subgroups"
+msgid "Groups are a great way to organize projects and people."
+msgstr ""
+
+msgid "Groups are the best way to manage projects and members."
msgstr ""
msgid "Groups to synchronize"
@@ -17704,13 +17959,16 @@ msgstr ""
msgid "GroupsTree|Are you sure you want to leave the \"%{fullName}\" group?"
msgstr ""
-msgid "GroupsTree|Edit group"
+msgid "GroupsTree|Delete"
+msgstr ""
+
+msgid "GroupsTree|Edit"
msgstr ""
msgid "GroupsTree|Failed to leave the group. Please make sure you are not the only owner."
msgstr ""
-msgid "GroupsTree|Leave this group"
+msgid "GroupsTree|Leave group"
msgstr ""
msgid "GroupsTree|Loading groups"
@@ -17722,9 +17980,57 @@ msgstr ""
msgid "GroupsTree|No groups or projects matched your search"
msgstr ""
+msgid "GroupsTree|Options"
+msgstr ""
+
msgid "GroupsTree|Search by name"
msgstr ""
+msgid "Groups|Avatar will be removed. Are you sure?"
+msgstr ""
+
+msgid "Groups|Changing group URL can have unintended side effects."
+msgstr ""
+
+msgid "Groups|Checking group URL availability..."
+msgstr ""
+
+msgid "Groups|Enter a descriptive name for your group."
+msgstr ""
+
+msgid "Groups|Group ID"
+msgstr ""
+
+msgid "Groups|Group URL"
+msgstr ""
+
+msgid "Groups|Group avatar"
+msgstr ""
+
+msgid "Groups|Group description (optional)"
+msgstr ""
+
+msgid "Groups|Group name"
+msgstr ""
+
+msgid "Groups|Group path is available."
+msgstr ""
+
+msgid "Groups|Group path is unavailable. Path has been replaced with a suggested available path."
+msgstr ""
+
+msgid "Groups|Learn more"
+msgstr ""
+
+msgid "Groups|Must start with letter, digit, emoji, or underscore. Can also contain periods, dashes, spaces, and parentheses."
+msgstr ""
+
+msgid "Groups|Remove avatar"
+msgstr ""
+
+msgid "Groups|Save changes"
+msgstr ""
+
msgid "Guideline"
msgstr ""
@@ -17734,6 +18040,9 @@ msgstr ""
msgid "HAR file path or URL"
msgstr ""
+msgid "HTTP Archive (HAR)"
+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 ""
@@ -18136,6 +18445,9 @@ msgstr ""
msgid "INFO: Your SSH key is expiring soon. Please generate a new key."
msgstr ""
+msgid "IP"
+msgstr ""
+
msgid "IP Address"
msgstr ""
@@ -18172,6 +18484,9 @@ msgstr ""
msgid "IdentityVerification|Verify your identity"
msgstr ""
+msgid "IdentityVerification|You can always verify your account at a later time to create a group."
+msgstr ""
+
msgid "If any indexed field exceeds this limit, it is truncated to this number of characters. The rest of the content is neither indexed nor searchable. This does not apply to repository and wiki indexing. For unlimited characters, set this to 0."
msgstr ""
@@ -18229,6 +18544,9 @@ msgstr ""
msgid "If you add %{codeStart}needs%{codeEnd} to jobs in your pipeline you'll be able to view the %{codeStart}needs%{codeEnd} relationships between jobs in this tab as a %{linkStart}Directed Acyclic Graph (DAG)%{linkEnd}."
msgstr ""
+msgid "If you are added to a project, it will be displayed here."
+msgstr ""
+
msgid "If you did not initiate these sign-in attempts, please reach out to your administrator or enable two-factor authentication (2FA) on your account."
msgstr ""
@@ -18538,12 +18856,24 @@ msgstr ""
msgid "InProductMarketing|3 ways to dive into GitLab CI/CD"
msgstr ""
+msgid "InProductMarketing|A single application eliminates complex integrations, data chokepoints, and toolchain maintenance, resulting in greater productivity and lower cost."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features, build more efficiently, strengthen security and compliance."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features."
+msgstr ""
+
msgid "InProductMarketing|Actually, GitLab makes the team work (better)"
msgstr ""
msgid "InProductMarketing|And finally %{deploy_link} a Python application."
msgstr ""
+msgid "InProductMarketing|And many more..."
+msgstr ""
+
msgid "InProductMarketing|Are your runners ready?"
msgstr ""
@@ -18562,15 +18892,33 @@ msgstr ""
msgid "InProductMarketing|Blog"
msgstr ""
+msgid "InProductMarketing|Break down silos to coordinate seamlessly across development, operations, and security with a consistent experience across the development lifecycle."
+msgstr ""
+
+msgid "InProductMarketing|Burn up/down charts"
+msgstr ""
+
msgid "InProductMarketing|By enabling code owners and required merge approvals the right person will review the right MR. This is a win-win: cleaner code and a more efficient review process."
msgstr ""
msgid "InProductMarketing|Click on the number below that corresponds with your answer — 1 being very difficult, 5 being very easy."
msgstr ""
+msgid "InProductMarketing|Code owners"
+msgstr ""
+
msgid "InProductMarketing|Code owners and required merge approvals are part of the paid tiers of GitLab. You can start a free 30-day trial of GitLab Ultimate and enable these features in less than 5 minutes with no credit card required."
msgstr ""
+msgid "InProductMarketing|Code review analytics"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration across stages in GitLab"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration made easy"
+msgstr ""
+
msgid "InProductMarketing|Create a custom CI runner with just a few clicks"
msgstr ""
@@ -18580,12 +18928,21 @@ msgstr ""
msgid "InProductMarketing|Create a project in GitLab in 5 minutes"
msgstr ""
+msgid "InProductMarketing|Create well-defined workflows by using scoped labels on issues, merge requests, and epics. Labels with the same scope cannot be used together, which prevents conflicts."
+msgstr ""
+
msgid "InProductMarketing|Create your first project!"
msgstr ""
+msgid "InProductMarketing|Define who owns specific files or directories, so the right reviewers are suggested when a merge request introduces changes to those files."
+msgstr ""
+
msgid "InProductMarketing|Deliver Better Products Faster"
msgstr ""
+msgid "InProductMarketing|Dependency scanning"
+msgstr ""
+
msgid "InProductMarketing|Did you know teams that use GitLab are far more efficient?"
msgstr ""
@@ -18595,15 +18952,27 @@ msgstr ""
msgid "InProductMarketing|Dig in and create a project and a repo"
msgstr ""
+msgid "InProductMarketing|Discover Premium & Ultimate"
+msgstr ""
+
+msgid "InProductMarketing|Discover Premium & Ultimate."
+msgstr ""
+
msgid "InProductMarketing|Do you have a minute?"
msgstr ""
msgid "InProductMarketing|Do you have a teammate who would be perfect for this task?"
msgstr ""
+msgid "InProductMarketing|Dynamic application security testing"
+msgstr ""
+
msgid "InProductMarketing|Easy"
msgstr ""
+msgid "InProductMarketing|Epics"
+msgstr ""
+
msgid "InProductMarketing|Expand your DevOps journey with a free GitLab trial"
msgstr ""
@@ -18625,9 +18994,15 @@ msgstr ""
msgid "InProductMarketing|Feel the need for speed?"
msgstr ""
+msgid "InProductMarketing|Find and fix bottlenecks in your code review process by understanding how long open merge requests have been in review."
+msgstr ""
+
msgid "InProductMarketing|Find out how your teams are really doing"
msgstr ""
+msgid "InProductMarketing|Find out if your external libraries are safe. Run dependency scanning jobs that check for known vulnerabilities in your external libraries."
+msgstr ""
+
msgid "InProductMarketing|Follow our steps"
msgstr ""
@@ -18664,6 +19039,9 @@ msgstr ""
msgid "InProductMarketing|GitLab is better with teammates to help out!"
msgstr ""
+msgid "InProductMarketing|GitLab is infrastructure agnostic (supporting GCP, AWS, Azure, OpenShift, VMWare, On Prem, Bare Metal, and more), offering a consistent workflow experience – irrespective of the environment."
+msgstr ""
+
msgid "InProductMarketing|GitLab provides static application security testing (SAST), dynamic application security testing (DAST), container scanning, and dependency scanning to help you deliver secure applications along with license compliance."
msgstr ""
@@ -18754,21 +19132,36 @@ msgstr ""
msgid "InProductMarketing|It's also possible to simply %{external_repo_link} in order to take advantage of GitLab's CI/CD."
msgstr ""
+msgid "InProductMarketing|Keep your code quality high by defining who should approve merge requests and how many approvals are required."
+msgstr ""
+
msgid "InProductMarketing|Launch GitLab CI/CD in 20 minutes or less"
msgstr ""
+msgid "InProductMarketing|Lower cost of development"
+msgstr ""
+
+msgid "InProductMarketing|Make it easier to collaborate on high-level ideas by grouping related issues in an epic."
+msgstr ""
+
msgid "InProductMarketing|Making the switch? It's easier than you think to import your projects into GitLab. Move %{github_link}, or import something %{bitbucket_link}."
msgstr ""
msgid "InProductMarketing|Master the art of importing!"
msgstr ""
+msgid "InProductMarketing|Merge request approval rule"
+msgstr ""
+
msgid "InProductMarketing|Move on to easily creating a Pages website %{ci_template_link}"
msgstr ""
msgid "InProductMarketing|Multiple owners, confusing workstreams? We've got you covered"
msgstr ""
+msgid "InProductMarketing|Multiple required approvers"
+msgstr ""
+
msgid "InProductMarketing|Need an alternative to importing?"
msgstr ""
@@ -18781,18 +19174,33 @@ msgstr ""
msgid "InProductMarketing|Our tool brings all the things together"
msgstr ""
+msgid "InProductMarketing|Protect your web application by using DAST to examine for vulnerabilities in deployed environments."
+msgstr ""
+
msgid "InProductMarketing|Rapid development, simplified"
msgstr ""
msgid "InProductMarketing|Reduce Security & Compliance Risk"
msgstr ""
+msgid "InProductMarketing|Require multiple approvers on a merge request, so you know it's in good shape before it's merged."
+msgstr ""
+
+msgid "InProductMarketing|Roadmaps"
+msgstr ""
+
+msgid "InProductMarketing|Scoped labels"
+msgstr ""
+
msgid "InProductMarketing|Security that's integrated into your development lifecycle"
msgstr ""
msgid "InProductMarketing|Sometimes you're not ready to make a full transition to a new tool. If you're not ready to fully commit, %{mirroring_link} gives you a safe way to try out GitLab in parallel with your current tool."
msgstr ""
+msgid "InProductMarketing|Speed. Efficiency. Trust."
+msgstr ""
+
msgid "InProductMarketing|Spin up an autoscaling runner in GitLab"
msgstr ""
@@ -18802,6 +19210,9 @@ msgstr ""
msgid "InProductMarketing|Start a Self-Managed trial"
msgstr ""
+msgid "InProductMarketing|Start a free trial"
+msgstr ""
+
msgid "InProductMarketing|Start a free trial of GitLab Ultimate – no credit card required"
msgstr ""
@@ -18868,6 +19279,9 @@ msgstr ""
msgid "InProductMarketing|To understand and get the most out of GitLab, start at the beginning and %{project_link}. In GitLab, repositories are part of a project, so after you've created your project you can go ahead and %{repo_link}."
msgstr ""
+msgid "InProductMarketing|Track completed issues in a chart, so you can see how a milestone is progressing at a glance."
+msgstr ""
+
msgid "InProductMarketing|Try GitLab Ultimate for free"
msgstr ""
@@ -18904,6 +19318,9 @@ msgstr ""
msgid "InProductMarketing|Very easy"
msgstr ""
+msgid "InProductMarketing|Visualize your epics and milestones in a timeline."
+msgstr ""
+
msgid "InProductMarketing|Want to host GitLab on your servers?"
msgstr ""
@@ -18925,6 +19342,9 @@ msgstr ""
msgid "InProductMarketing|YouTube"
msgstr ""
+msgid "InProductMarketing|Your software, deployed your way"
+msgstr ""
+
msgid "InProductMarketing|Your teams can be more efficient"
msgstr ""
@@ -19045,9 +19465,18 @@ msgstr ""
msgid "IncidentManagement|No incidents to display."
msgstr ""
+msgid "IncidentManagement|None"
+msgstr ""
+
msgid "IncidentManagement|Open"
msgstr ""
+msgid "IncidentManagement|Page your team with escalation policies"
+msgstr ""
+
+msgid "IncidentManagement|Paged"
+msgstr ""
+
msgid "IncidentManagement|Published"
msgstr ""
@@ -19057,6 +19486,9 @@ msgstr ""
msgid "IncidentManagement|Severity"
msgstr ""
+msgid "IncidentManagement|Status"
+msgstr ""
+
msgid "IncidentManagement|There are no closed incidents"
msgstr ""
@@ -19075,6 +19507,9 @@ msgstr ""
msgid "IncidentManagement|Unpublished"
msgstr ""
+msgid "IncidentManagement|Use escalation policies to automatically page your team when incidents are created."
+msgstr ""
+
msgid "IncidentSettings|Activate \"time to SLA\" countdown timer"
msgstr ""
@@ -19120,7 +19555,10 @@ msgstr ""
msgid "Incidents"
msgstr ""
-msgid "Incidents|Add a URL"
+msgid "Incidents|Add image details"
+msgstr ""
+
+msgid "Incidents|Add text or a link to display with your image. If you don't add either, the file name displays instead."
msgstr ""
msgid "Incidents|Drop or %{linkStart}upload%{linkEnd} a metric screenshot to attach it to the incident"
@@ -19135,10 +19573,10 @@ msgstr ""
msgid "Incidents|There was an issue loading metric images."
msgstr ""
-msgid "Incidents|There was an issue uploading your image."
+msgid "Incidents|There was an issue updating your image."
msgstr ""
-msgid "Incidents|You can optionally add a URL to link users to the original graph."
+msgid "Incidents|There was an issue uploading your image."
msgstr ""
msgid "Incident|Alert details"
@@ -19147,9 +19585,18 @@ msgstr ""
msgid "Incident|Are you sure you wish to delete this image?"
msgstr ""
+msgid "Incident|Delete image"
+msgstr ""
+
msgid "Incident|Deleting %{filename}"
msgstr ""
+msgid "Incident|Edit image text or link"
+msgstr ""
+
+msgid "Incident|Editing %{filename}"
+msgstr ""
+
msgid "Incident|Metrics"
msgstr ""
@@ -19420,12 +19867,18 @@ msgstr ""
msgid "Integrations|Branches for which notifications are to be sent"
msgstr ""
+msgid "Integrations|Clear if using a self-signed certificate."
+msgstr ""
+
msgid "Integrations|Comment detail:"
msgstr ""
msgid "Integrations|Comment settings:"
msgstr ""
+msgid "Integrations|Connection details"
+msgstr ""
+
msgid "Integrations|Connection failed. Please check your settings."
msgstr ""
@@ -19450,6 +19903,9 @@ msgstr ""
msgid "Integrations|Enable GitLab.com slash commands in a Slack workspace."
msgstr ""
+msgid "Integrations|Enable SSL verification"
+msgstr ""
+
msgid "Integrations|Enable comments"
msgstr ""
@@ -19528,6 +19984,9 @@ msgstr ""
msgid "Integrations|Return to GitLab for Jira"
msgstr ""
+msgid "Integrations|SSL verification"
+msgstr ""
+
msgid "Integrations|Save settings?"
msgstr ""
@@ -19573,9 +20032,6 @@ msgstr ""
msgid "Integrations|Use default settings"
msgstr ""
-msgid "Integrations|When you mention a Jira issue in a commit or merge request, GitLab creates a remote link and comment (if enabled)."
-msgstr ""
-
msgid "Integrations|You can now close this window and return to the GitLab for Jira application."
msgstr ""
@@ -19600,9 +20056,6 @@ msgstr ""
msgid "Integrations|can't exceed %{recipients_limit}"
msgstr ""
-msgid "Interactive developer security education."
-msgstr ""
-
msgid "Interactive mode"
msgstr ""
@@ -20092,6 +20545,9 @@ msgstr ""
msgid "IssueAnalytics|Assignees"
msgstr ""
+msgid "IssueAnalytics|Created by"
+msgstr ""
+
msgid "IssueAnalytics|Due date"
msgstr ""
@@ -20104,9 +20560,6 @@ msgstr ""
msgid "IssueAnalytics|Milestone"
msgstr ""
-msgid "IssueAnalytics|Opened by"
-msgstr ""
-
msgid "IssueAnalytics|Status"
msgstr ""
@@ -20230,10 +20683,10 @@ msgstr ""
msgid "IssuesAnalytics|Avg/Month:"
msgstr ""
-msgid "IssuesAnalytics|Issues opened"
+msgid "IssuesAnalytics|Issues created"
msgstr ""
-msgid "IssuesAnalytics|Issues opened per month"
+msgid "IssuesAnalytics|Issues created per month"
msgstr ""
msgid "IssuesAnalytics|Last 12 months"
@@ -20260,6 +20713,9 @@ msgstr ""
msgid "It looks like you have some draft commits in this branch."
msgstr ""
+msgid "It looks like you're attempting to activate your subscription. Use %{a_start}the Subscription page%{a_end} instead."
+msgstr ""
+
msgid "It may be several days before you see feature usage data."
msgstr ""
@@ -20488,6 +20944,9 @@ msgstr ""
msgid "JiraConnect|You can now close this window and return to Jira."
msgstr ""
+msgid "JiraConnect|You don't have permission to create branches for this project. Select a different project or contact the project owner for access. %{linkStart}Learn more.%{linkEnd}"
+msgstr ""
+
msgid "JiraRequest|A connection error occurred while connecting to Jira. Try your request again."
msgstr ""
@@ -20536,13 +20995,13 @@ msgstr ""
msgid "JiraService|Define the type of Jira issue to create from a vulnerability."
msgstr ""
-msgid "JiraService|Displaying Jira issues while leaving the GitLab issue functionality enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
+msgid "JiraService|Displaying Jira issues while leaving GitLab issues also enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
msgstr ""
-msgid "JiraService|Enable Jira issues"
+msgid "JiraService|Enable Jira issue creation from vulnerabilities"
msgstr ""
-msgid "JiraService|Enable Jira issues creation from vulnerabilities"
+msgid "JiraService|Enable Jira issues"
msgstr ""
msgid "JiraService|Enable Jira transitions"
@@ -20659,16 +21118,19 @@ msgstr ""
msgid "JiraService|View Jira issues in GitLab"
msgstr ""
-msgid "JiraService|Warning: All GitLab users that have access to this GitLab project are able to view all issues from the Jira project specified below."
+msgid "JiraService|Warning: All GitLab users with access to this GitLab project can view all issues from the Jira project you select."
msgstr ""
msgid "JiraService|Web URL"
msgstr ""
-msgid "JiraService|Work on Jira issues without leaving GitLab. Adds a Jira menu to access your list of Jira issues and view any issue as read-only."
+msgid "JiraService|When a Jira issue is mentioned in a commit or merge request, a remote link and comment (if enabled) will be created."
+msgstr ""
+
+msgid "JiraService|Work on Jira issues without leaving GitLab. Add a Jira menu to access a read-only list of your Jira issues."
msgstr ""
-msgid "JiraService|You need to configure Jira before enabling this integration. For more details, read the %{jira_doc_link_start}Jira integration documentation%{link_end}."
+msgid "JiraService|You must configure Jira before enabling this integration. %{jira_doc_link_start}Learn more.%{link_end}"
msgstr ""
msgid "Job"
@@ -20680,9 +21142,6 @@ msgstr ""
msgid "Job Failed #%{build_id}"
msgstr ""
-msgid "Job ID"
-msgstr ""
-
msgid "Job artifact"
msgstr ""
@@ -20749,9 +21208,27 @@ msgstr ""
msgid "Jobs|You're about to retry a job that failed because it attempted to deploy code that is older than the latest deployment. Retrying this job could result in overwriting the environment with the older source code."
msgstr ""
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source} into %{target}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{ref}"
+msgstr ""
+
+msgid "Job|Are you sure you want to erase this job log and artifacts?"
+msgstr ""
+
msgid "Job|Browse"
msgstr ""
+msgid "Job|Cancel"
+msgstr ""
+
msgid "Job|Complete Raw"
msgstr ""
@@ -20761,6 +21238,9 @@ msgstr ""
msgid "Job|Erase job log and artifacts"
msgstr ""
+msgid "Job|Finished at"
+msgstr ""
+
msgid "Job|Job artifacts"
msgstr ""
@@ -20773,7 +21253,7 @@ msgstr ""
msgid "Job|Keep"
msgstr ""
-msgid "Job|Pipeline"
+msgid "Job|Retry"
msgstr ""
msgid "Job|Scroll to bottom"
@@ -20785,6 +21265,9 @@ msgstr ""
msgid "Job|Show complete raw"
msgstr ""
+msgid "Job|Status"
+msgstr ""
+
msgid "Job|The artifacts were removed"
msgstr ""
@@ -20812,21 +21295,12 @@ msgstr ""
msgid "Job|delayed"
msgstr ""
-msgid "Job|for"
-msgstr ""
-
-msgid "Job|into"
-msgstr ""
-
msgid "Job|manual"
msgstr ""
msgid "Job|triggered"
msgstr ""
-msgid "Job|with"
-msgstr ""
-
msgid "Join Zoom meeting"
msgstr ""
@@ -20929,9 +21403,6 @@ msgstr ""
msgid "Ki"
msgstr ""
-msgid "Kontra"
-msgstr ""
-
msgid "Kroki"
msgstr ""
@@ -21256,6 +21727,9 @@ msgstr ""
msgid "Learn more about Auto DevOps"
msgstr ""
+msgid "Learn more about GitLab"
+msgstr ""
+
msgid "Learn more about Needs relationships"
msgstr ""
@@ -21589,9 +22063,18 @@ msgstr ""
msgid "Licenses|Displays licenses detected in the project, based on the %{linkStart}latest successful%{linkEnd} scan"
msgstr ""
+msgid "Licenses|Drag your license file here or %{linkStart}click to upload%{linkEnd}."
+msgstr ""
+
+msgid "Licenses|Drop your license file to start the upload."
+msgstr ""
+
msgid "Licenses|Error fetching the license list. Please check your network connection and try again."
msgstr ""
+msgid "Licenses|Error: You are trying to upload something other than a file"
+msgstr ""
+
msgid "Licenses|License Compliance"
msgstr ""
@@ -21610,6 +22093,9 @@ msgstr ""
msgid "Licenses|Specified policies in this project"
msgstr ""
+msgid "Licenses|The file could not be uploaded."
+msgstr ""
+
msgid "Licenses|The license list details information about the licenses used within your project."
msgstr ""
@@ -21643,12 +22129,6 @@ msgstr ""
msgid "Limit the size of Sidekiq jobs stored in Redis."
msgstr ""
-msgid "Limited to showing %d event at most"
-msgid_plural "Limited to showing %d events at most"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-
msgid "Limiting mode"
msgstr ""
@@ -21658,6 +22138,9 @@ msgstr ""
msgid "Link"
msgstr ""
+msgid "Link (optional)"
+msgstr ""
+
msgid "Link Prometheus monitoring to GitLab."
msgstr ""
@@ -21694,6 +22177,9 @@ msgstr ""
msgid "Linked emails (%{email_count})"
msgstr ""
+msgid "Linked epics"
+msgstr ""
+
msgid "Linked issues"
msgstr ""
@@ -21721,6 +22207,15 @@ msgstr ""
msgid "List of all merge commits"
msgstr ""
+msgid "List of environments for this project"
+msgstr ""
+
+msgid "List of suitable GCP locations"
+msgstr ""
+
+msgid "List of users allowed to exceed the rate limit."
+msgstr ""
+
msgid "List options"
msgstr ""
@@ -21940,6 +22435,9 @@ msgstr ""
msgid "Maintenance mode"
msgstr ""
+msgid "Make adjustments to how your GitLab instance is set up."
+msgstr ""
+
msgid "Make and review changes in the browser with the Web IDE"
msgstr ""
@@ -22084,6 +22582,12 @@ msgstr ""
msgid "MarkdownEditor|Add italic text (%{modifier_key}I)"
msgstr ""
+msgid "MarkdownEditor|Add strikethrough text (%{modifierKey}⇧X)"
+msgstr ""
+
+msgid "MarkdownEditor|Add strikethrough text (%{modifier_key}⇧X)"
+msgstr ""
+
msgid "Marked For Deletion At - %{deletion_time}"
msgstr ""
@@ -22345,6 +22849,9 @@ msgstr ""
msgid "Maximum push size (MB)"
msgstr ""
+msgid "Maximum requests per 10 minutes per user"
+msgstr ""
+
msgid "Maximum requests per minute"
msgstr ""
@@ -22435,6 +22942,21 @@ msgstr ""
msgid "Members of a group may only view projects they have permission to access"
msgstr ""
+msgid "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seat in use and will be billed for the overage."
+msgid_plural "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seats in use and will be billed for the overage."
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
+msgid "MembersOverage|You are about to incur additional charges"
+msgstr ""
+
+msgid "MembersOverage|Your subscription includes %d seat."
+msgid_plural "MembersOverage|Your subscription includes %d seats."
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+
msgid "Membership"
msgstr ""
@@ -22639,9 +23161,6 @@ msgstr ""
msgid "Merge request not merged"
msgstr ""
-msgid "Merge request pipelines 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 merge request pipelines."
-msgstr ""
-
msgid "Merge request reports"
msgstr ""
@@ -22738,13 +23257,13 @@ msgstr ""
msgid "MergeRequests|Create issue to resolve thread"
msgstr ""
-msgid "MergeRequests|Failed to squash. Should be done manually."
+msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Saving the comment failed"
+msgid "MergeRequests|Squashing failed: Squash the commits locally, resolve any conflicts, then push the branch."
msgstr ""
-msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
+msgid "MergeRequests|Squashing not allowed: This project doesn't allow you to squash commits when merging."
msgstr ""
msgid "MergeRequests|Thread stays resolved"
@@ -23587,6 +24106,18 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "MrList|Assigned to %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from assignee %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from reviewer %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Review requested from %{name}, go to their profile."
+msgstr ""
+
msgid "Multi-project"
msgstr ""
@@ -23620,7 +24151,7 @@ msgstr ""
msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "My Awesome Group"
+msgid "My awesome group"
msgstr ""
msgid "My company or team"
@@ -24244,9 +24775,6 @@ msgstr ""
msgid "No available branches"
msgstr ""
-msgid "No available groups to fork the project."
-msgstr ""
-
msgid "No branches found"
msgstr ""
@@ -24457,6 +24985,9 @@ msgstr ""
msgid "No ref selected"
msgstr ""
+msgid "No regions configured"
+msgstr ""
+
msgid "No related merge requests found."
msgstr ""
@@ -25267,6 +25798,9 @@ msgstr ""
msgid "Only reCAPTCHA v2 is supported:"
msgstr ""
+msgid "Only required if not using role instance credentials."
+msgstr ""
+
msgid "Only use lowercase letters, numbers, and underscores."
msgstr ""
@@ -25291,9 +25825,6 @@ msgstr ""
msgid "Open a CLI and connect to the cluster you want to install the agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
-msgid "Open epics"
-msgstr ""
-
msgid "Open errors"
msgstr ""
@@ -25333,7 +25864,7 @@ msgstr ""
msgid "Opened issues"
msgstr ""
-msgid "OpenedNDaysAgo|Opened"
+msgid "OpenedNDaysAgo|Created"
msgstr ""
msgid "Opens in a new window"
@@ -25378,9 +25909,6 @@ msgstr ""
msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
-msgid "Optional."
-msgstr ""
-
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
msgstr ""
@@ -26170,6 +26698,9 @@ msgstr ""
msgid "PerformanceBar|Memory"
msgstr ""
+msgid "PerformanceBar|Memory report"
+msgstr ""
+
msgid "PerformanceBar|Redis calls"
msgstr ""
@@ -26203,18 +26734,12 @@ msgstr ""
msgid "PerformanceBar|wall"
msgstr ""
-msgid "Performs a rebase but skips triggering a new pipeline"
-msgstr ""
-
msgid "Period in seconds"
msgstr ""
msgid "Permalink"
msgstr ""
-msgid "Permanently delete project"
-msgstr ""
-
msgid "Permanently remove group"
msgstr ""
@@ -26485,6 +27010,51 @@ msgstr ""
msgid "PipelineStatusTooltip|Pipeline: %{ci_status}"
msgstr ""
+msgid "PipelineWizardDefaultCommitMessage|Add %{filename}"
+msgstr ""
+
+msgid "PipelineWizardDefaultCommitMessage|Update %{filename}"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|At least one entry is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This field is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This value is not valid"
+msgstr ""
+
+msgid "PipelineWizardListWidget|add another step"
+msgstr ""
+
+msgid "PipelineWizardListWidget|remove step"
+msgstr ""
+
+msgid "PipelineWizard|Commit"
+msgstr ""
+
+msgid "PipelineWizard|Commit Message"
+msgstr ""
+
+msgid "PipelineWizard|Commit changes to your file"
+msgstr ""
+
+msgid "PipelineWizard|Commit file to Branch"
+msgstr ""
+
+msgid "PipelineWizard|Commit your new file"
+msgstr ""
+
+msgid "PipelineWizard|The file has been committed."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem committing the changes."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem while checking whether your file already exists in the specified branch."
+msgstr ""
+
msgid "Pipelines"
msgstr ""
@@ -26599,7 +27169,7 @@ msgstr ""
msgid "Pipelines|Project cache successfully reset."
msgstr ""
-msgid "Pipelines|Revoke"
+msgid "Pipelines|Revoke trigger"
msgstr ""
msgid "Pipelines|Something went wrong while cleaning runners cache."
@@ -26644,6 +27214,12 @@ msgstr ""
msgid "Pipelines|This is a child pipeline within the parent pipeline"
msgstr ""
+msgid "Pipelines|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipelines|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipelines|This pipeline will run code originating from a forked project merge request. This means that the code can potentially have security considerations like exposing CI variables."
msgstr ""
@@ -26686,9 +27262,6 @@ msgstr ""
msgid "Pipelines|Your changes have been successfully committed. Now redirecting to the new merge request page."
msgstr ""
-msgid "Pipelines|detached"
-msgstr ""
-
msgid "Pipelines|error"
msgstr ""
@@ -26698,10 +27271,13 @@ msgstr ""
msgid "Pipelines|latest"
msgstr ""
-msgid "Pipelines|stuck"
+msgid "Pipelines|merge request"
msgstr ""
-msgid "Pipelines|train"
+msgid "Pipelines|merge train"
+msgstr ""
+
+msgid "Pipelines|stuck"
msgstr ""
msgid "Pipelines|yaml invalid"
@@ -26833,6 +27409,12 @@ msgstr ""
msgid "Pipeline|This change will not change the overall test coverage if merged."
msgstr ""
+msgid "Pipeline|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipeline|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipeline|Trigger author"
msgstr ""
@@ -26857,6 +27439,12 @@ msgstr ""
msgid "Pipeline|for"
msgstr ""
+msgid "Pipeline|merge request"
+msgstr ""
+
+msgid "Pipeline|merge train"
+msgstr ""
+
msgid "Pipeline|on"
msgstr ""
@@ -26995,9 +27583,6 @@ msgstr ""
msgid "Please enter a valid time interval"
msgstr ""
-msgid "Please enter or upload a valid license."
-msgstr ""
-
msgid "Please enter your current password."
msgstr ""
@@ -27106,9 +27691,6 @@ msgstr ""
msgid "Please type %{phrase_code} to proceed or close this modal to cancel."
msgstr ""
-msgid "Please type the following to confirm:"
-msgstr ""
-
msgid "Please use this form to report to the admin users who create spam issues, comments or behave inappropriately."
msgstr ""
@@ -27136,12 +27718,27 @@ msgstr ""
msgid "Policies"
msgstr ""
+msgid "Policy '%{escalation_policy_name}' does not exist."
+msgstr ""
+
msgid "Policy management project does have any policies in %{policy_path}"
msgstr ""
msgid "Policy project doesn't exist"
msgstr ""
+msgid "PolicyRuleMultiSelect|%{firstLabel} +%{numberOfAdditionalLabels} more"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|All %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select all"
+msgstr ""
+
msgid "Polling interval multiplier"
msgstr ""
@@ -27370,6 +27967,9 @@ msgstr ""
msgid "Private projects can be created in your personal namespace with:"
msgstr ""
+msgid "Problem with %{name} command: %{message}."
+msgstr ""
+
msgid "Proceed"
msgstr ""
@@ -27844,6 +28444,9 @@ msgstr ""
msgid "Progress"
msgstr ""
+msgid "Progress tracking"
+msgstr ""
+
msgid "Project"
msgstr ""
@@ -28075,6 +28678,9 @@ msgstr ""
msgid "ProjectQualitySummary|Failure"
msgstr ""
+msgid "ProjectQualitySummary|Get insight into the overall percentage of tests in your project that succeed, fail and are skipped."
+msgstr ""
+
msgid "ProjectQualitySummary|Latest pipeline results"
msgstr ""
@@ -28093,6 +28699,12 @@ msgstr ""
msgid "ProjectQualitySummary|See project Code Coverage Statistics"
msgstr ""
+msgid "ProjectQualitySummary|Set up test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|Set up test runs (opens in a new tab)"
+msgstr ""
+
msgid "ProjectQualitySummary|Skipped"
msgstr ""
@@ -28369,13 +28981,19 @@ msgstr ""
msgid "ProjectSettings|LFS objects from this repository are available to forks. %{linkStart}How do I remove them?%{linkEnd}"
msgstr ""
+msgid "ProjectSettings|Learn about commit history."
+msgstr ""
+
+msgid "ProjectSettings|Leave empty to use default template."
+msgstr ""
+
msgid "ProjectSettings|Manage who can see the project in the public access directory."
msgstr ""
msgid "ProjectSettings|Manages large files such as audio, video, and graphics files."
msgstr ""
-msgid "ProjectSettings|Maximum 500 characters."
+msgid "ProjectSettings|Maximum %{maxLength} characters."
msgstr ""
msgid "ProjectSettings|Merge checks"
@@ -28516,6 +29134,9 @@ msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
msgstr ""
+msgid "ProjectSettings|The default template will be applied on save."
+msgstr ""
+
msgid "ProjectSettings|These checks must pass before merge requests can be merged."
msgstr ""
@@ -28570,6 +29191,9 @@ msgstr ""
msgid "ProjectSettings|What are badges?"
msgstr ""
+msgid "ProjectSettings|What are merge trains?"
+msgstr ""
+
msgid "ProjectSettings|When merge request pipelines are enabled in the CI/CD configuration file, pipelines validate the combined results of the source and target branches. %{link_start}How to configure merge request pipelines?%{link_end}"
msgstr ""
@@ -28687,6 +29311,9 @@ msgstr ""
msgid "Projects are organized into groups"
msgstr ""
+msgid "Projects are where you store your code, access issues, wiki and other features of GitLab."
+msgstr ""
+
msgid "Projects contributed to"
msgstr ""
@@ -28702,12 +29329,6 @@ msgstr ""
msgid "Projects to index"
msgstr ""
-msgid "Projects will be permanently deleted after a %{waiting_period}-day waiting period."
-msgstr ""
-
-msgid "Projects will be permanently deleted immediately."
-msgstr ""
-
msgid "Projects with critical vulnerabilities"
msgstr ""
@@ -28792,6 +29413,9 @@ msgstr ""
msgid "ProjectsNew|Import project"
msgstr ""
+msgid "ProjectsNew|Include a Getting Started README"
+msgstr ""
+
msgid "ProjectsNew|Initialize repository with a README"
msgstr ""
@@ -28807,6 +29431,9 @@ msgstr ""
msgid "ProjectsNew|Project description %{tag_start}(optional)%{tag_end}"
msgstr ""
+msgid "ProjectsNew|Recommended if you're new to GitLab"
+msgstr ""
+
msgid "ProjectsNew|Run CI/CD for external repository"
msgstr ""
@@ -29224,6 +29851,9 @@ msgstr ""
msgid "ProtectedBranch|Unprotect"
msgstr ""
+msgid "ProtectedBranch|Unprotect branch"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
@@ -29251,6 +29881,9 @@ msgstr ""
msgid "ProtectedEnvironment|Protected Environment (%{protected_environments_count})"
msgstr ""
+msgid "ProtectedEnvironment|Required approvals"
+msgstr ""
+
msgid "ProtectedEnvironment|Select an environment"
msgstr ""
@@ -29272,10 +29905,13 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|Unprotect tag"
+msgstr ""
+
msgid "ProtectedTags|default"
msgstr ""
-msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
+msgid "ProtectedTag|By default, protected tags restrict who can modify the tag."
msgstr ""
msgid "ProtectedTag|Learn more."
@@ -29338,6 +29974,9 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Public projects are an easy way to allow everyone to have read-only access."
+msgstr ""
+
msgid "Publish to status page"
msgstr ""
@@ -29494,9 +30133,6 @@ msgstr ""
msgid "QualitySummary|Project quality"
msgstr ""
-msgid "Quarters"
-msgstr ""
-
msgid "Query"
msgstr ""
@@ -29581,6 +30217,9 @@ msgstr ""
msgid "Read more about project permissions %{help_link_open}here%{help_link_close}"
msgstr ""
+msgid "Read more about related epics"
+msgstr ""
+
msgid "Read more about related issues"
msgstr ""
@@ -29611,10 +30250,7 @@ msgstr ""
msgid "Rebase source branch on the target branch."
msgstr ""
-msgid "Rebase without CI"
-msgstr ""
-
-msgid "Rebases and triggers a pipeline"
+msgid "Rebase without pipeline"
msgstr ""
msgid "Recaptcha verified?"
@@ -29665,9 +30301,6 @@ msgstr ""
msgid "Reconfigure"
msgstr ""
-msgid "Recovering projects"
-msgstr ""
-
msgid "Recovery Codes"
msgstr ""
@@ -29728,6 +30361,12 @@ msgstr ""
msgid "Regex pattern"
msgstr ""
+msgid "Region"
+msgstr ""
+
+msgid "Regions"
+msgstr ""
+
msgid "Register"
msgstr ""
@@ -29959,9 +30598,6 @@ msgstr ""
msgid "Remove all or specific reviewer(s)"
msgstr ""
-msgid "Remove approver"
-msgstr ""
-
msgid "Remove approvers"
msgstr ""
@@ -29977,6 +30613,9 @@ msgstr ""
msgid "Remove attention request"
msgstr ""
+msgid "Remove attention request(s)"
+msgstr ""
+
msgid "Remove avatar"
msgstr ""
@@ -30115,6 +30754,9 @@ msgstr ""
msgid "Removed an issue from an epic."
msgstr ""
+msgid "Removed attention from %{users_sentence}."
+msgstr ""
+
msgid "Removed attention request from @%{username}"
msgstr ""
@@ -30166,6 +30808,9 @@ msgstr ""
msgid "Removes an issue from an epic."
msgstr ""
+msgid "Removes attention from %{users_sentence}."
+msgstr ""
+
msgid "Removes parent epic %{epic_ref}."
msgstr ""
@@ -30277,6 +30922,9 @@ msgstr ""
msgid "Report abuse to admin"
msgstr ""
+msgid "Report is generating and will be sent to your email address."
+msgstr ""
+
msgid "Reported %{timeAgo} by %{reportedBy}"
msgstr ""
@@ -30571,6 +31219,15 @@ msgstr ""
msgid "Request attention"
msgstr ""
+msgid "Request attention from %{users_sentence}."
+msgstr ""
+
+msgid "Request attention from assignee or reviewer"
+msgstr ""
+
+msgid "Request attention from assignee(s) or reviewer(s)"
+msgstr ""
+
msgid "Request attention to review"
msgstr ""
@@ -30595,6 +31252,9 @@ msgstr ""
msgid "Requested %{time_ago}"
msgstr ""
+msgid "Requested attention from %{users_sentence}."
+msgstr ""
+
msgid "Requested attention from @%{username}"
msgstr ""
@@ -30811,6 +31471,9 @@ msgstr ""
msgid "Restore project"
msgstr ""
+msgid "Restoring projects"
+msgstr ""
+
msgid "Restoring the group will prevent the group, its subgroups and projects from being removed on this date."
msgstr ""
@@ -30841,6 +31504,9 @@ msgstr ""
msgid "Retry"
msgstr ""
+msgid "Retry failed jobs"
+msgstr ""
+
msgid "Retry job"
msgstr ""
@@ -30889,9 +31555,6 @@ msgstr ""
msgid "Review changes"
msgstr ""
-msgid "Review requested from %{name}"
-msgstr ""
-
msgid "Review requests for you"
msgstr ""
@@ -31057,6 +31720,9 @@ msgstr ""
msgid "Runners|Assigned Group"
msgstr ""
+msgid "Runners|Assigned Projects (%{projectCount})"
+msgstr ""
+
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -31126,6 +31792,9 @@ msgstr ""
msgid "Runners|Instance"
msgstr ""
+msgid "Runners|Jobs"
+msgstr ""
+
msgid "Runners|Last contact"
msgstr ""
@@ -31219,9 +31888,6 @@ msgstr ""
msgid "Runners|Runner %{name} was deleted"
msgstr ""
-msgid "Runners|Runner ID"
-msgstr ""
-
msgid "Runners|Runner assigned to project."
msgstr ""
@@ -31369,6 +32035,9 @@ msgstr ""
msgid "Runners|stale"
msgstr ""
+msgid "Runner|This runner has not run any jobs."
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -31483,6 +32152,24 @@ msgstr ""
msgid "Saving project."
msgstr ""
+msgid "ScanResultPolicy|%{ifLabelStart}if%{ifLabelEnd} %{scanners} scan in an open merge request targeting the %{branches} branch(es) finds %{vulnerabilitiesAllowed} or more %{severities} vulnerabilities that are %{vulnerabilityStates}"
+msgstr ""
+
+msgid "ScanResultPolicy|%{thenLabelStart}Then%{thenLabelEnd} Require approval from %{approvalsRequired} of the following approvers: %{approvers}"
+msgstr ""
+
+msgid "ScanResultPolicy|add an approver"
+msgstr ""
+
+msgid "ScanResultPolicy|scanners"
+msgstr ""
+
+msgid "ScanResultPolicy|severity levels"
+msgstr ""
+
+msgid "ScanResultPolicy|vulnerability states"
+msgstr ""
+
msgid "Scanner"
msgstr ""
@@ -31615,6 +32302,9 @@ msgstr ""
msgid "Search for a user"
msgstr ""
+msgid "Search for an emoji"
+msgstr ""
+
msgid "Search for projects, issues, etc."
msgstr ""
@@ -31813,18 +32503,12 @@ msgstr ""
msgid "Secret Detection"
msgstr ""
-msgid "Secret access key"
-msgstr ""
-
msgid "Secret token"
msgstr ""
msgid "Secure token that identifies an external storage request."
msgstr ""
-msgid "SecureCodeWarrior"
-msgstr ""
-
msgid "Security"
msgstr ""
@@ -31849,9 +32533,6 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "Security training with guide and learning pathways."
-msgstr ""
-
msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
@@ -31954,7 +32635,7 @@ msgstr ""
msgid "SecurityConfiguration|Manage corpus"
msgstr ""
-msgid "SecurityConfiguration|Manage corpus files used as mutation sources in coverage fuzzing."
+msgid "SecurityConfiguration|Manage corpus files used as seed inputs with coverage-guided fuzzing."
msgstr ""
msgid "SecurityConfiguration|Manage profiles for use by DAST scans."
@@ -32020,15 +32701,15 @@ msgstr ""
msgid "SecurityOrchestration|.yaml preview"
msgstr ""
-msgid "SecurityOrchestration|Action"
-msgstr ""
-
msgid "SecurityOrchestration|Actions"
msgstr ""
msgid "SecurityOrchestration|Add rule"
msgstr ""
+msgid "SecurityOrchestration|After dismissing the alert, the information will never be shown again."
+msgstr ""
+
msgid "SecurityOrchestration|All policies"
msgstr ""
@@ -32044,7 +32725,7 @@ msgstr ""
msgid "SecurityOrchestration|Description"
msgstr ""
-msgid "SecurityOrchestration|Disabled"
+msgid "SecurityOrchestration|Don't show the alert anymore"
msgstr ""
msgid "SecurityOrchestration|Edit policy"
@@ -32053,13 +32734,13 @@ msgstr ""
msgid "SecurityOrchestration|Edit policy project"
msgstr ""
-msgid "SecurityOrchestration|Enabled"
+msgid "SecurityOrchestration|Empty policy name"
msgstr ""
-msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Enabled"
msgstr ""
-msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
msgstr ""
msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
@@ -32068,7 +32749,7 @@ msgstr ""
msgid "SecurityOrchestration|Invalid policy type"
msgstr ""
-msgid "SecurityOrchestration|Latest scan"
+msgid "SecurityOrchestration|Latest scan run against %{agent}"
msgstr ""
msgid "SecurityOrchestration|Network"
@@ -32077,15 +32758,27 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No actions defined - policy will not run."
+msgstr ""
+
+msgid "SecurityOrchestration|No description"
+msgstr ""
+
msgid "SecurityOrchestration|No rules defined - policy will not run."
msgstr ""
+msgid "SecurityOrchestration|Not enabled"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
msgid "SecurityOrchestration|Policies"
msgstr ""
+msgid "SecurityOrchestration|Policy Type"
+msgstr ""
+
msgid "SecurityOrchestration|Policy cannot be enabled for non-existing branches (%{branches})"
msgstr ""
@@ -32110,10 +32803,13 @@ msgstr ""
msgid "SecurityOrchestration|Require %{approvals} %{plural} from %{approvers} if any of the following occur:"
msgstr ""
-msgid "SecurityOrchestration|Rule"
+msgid "SecurityOrchestration|Rules"
msgstr ""
-msgid "SecurityOrchestration|Rules"
+msgid "SecurityOrchestration|Runs %{actions} and %{lastAction} scans"
+msgstr ""
+
+msgid "SecurityOrchestration|Runs a %{action} scan"
msgstr ""
msgid "SecurityOrchestration|Scan Execution"
@@ -32173,6 +32869,9 @@ msgstr ""
msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
+msgid "SecurityOrchestration|This view only shows scan results for the agent %{agent}. You can view scan results for all agents in the %{linkStart}Operational Vulnerabilities tab of the vulnerability report%{linkEnd}."
+msgstr ""
+
msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
@@ -32227,9 +32926,6 @@ msgstr ""
msgid "SecurityOrchestration|users with ids"
msgstr ""
-msgid "SecurityOrchestration|view results"
-msgstr ""
-
msgid "SecurityOrchestration|vulnerabilities"
msgstr ""
@@ -32899,22 +33595,19 @@ 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|In order to start using functions as a service, you must first install Knative on your Kubernetes cluster. %{linkStart}More information%{linkEnd}"
-msgstr ""
-
msgid "Serverless|Learn more about Serverless"
msgstr ""
msgid "Serverless|No functions available"
msgstr ""
-msgid "Serverless|Sign up for First Look"
+msgid "Serverless|Serverless was %{linkStart}deprecated%{linkEnd} in GitLab 14.3."
+msgstr ""
+
+msgid "Serverless|Serverless was %{postLinkStart}deprecated%{postLinkEnd}. But if you opt to use it, you must install Knative in your Kubernetes cluster first. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "Serverless|The deploy job has not finished."
@@ -32926,9 +33619,6 @@ 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 ""
@@ -32944,9 +33634,6 @@ msgstr ""
msgid "Service Account Key"
msgstr ""
-msgid "Service Accounts"
-msgstr ""
-
msgid "Service Accounts keys authorize GitLab to deploy your Google Cloud project"
msgstr ""
@@ -32956,10 +33643,10 @@ msgstr ""
msgid "Service Desk allows people to create issues in your GitLab instance without their own user account. It provides a unique email address for end users to create issues in a project. Replies can be sent either through the GitLab interface or by email. End users only see threads through email."
msgstr ""
-msgid "Service Usage Data"
+msgid "Service account generated successfully"
msgstr ""
-msgid "Service account generated successfully"
+msgid "Service accounts"
msgstr ""
msgid "Service ping is disabled in your configuration file, and cannot be enabled through this form."
@@ -33103,6 +33790,9 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
+msgid "Set the per-user rate limit for getting a user by ID via the API."
+msgstr ""
+
msgid "Set the per-user rate limit for notes created by web or API requests."
msgstr ""
@@ -33283,6 +33973,9 @@ msgstr ""
msgid "Shared runners details"
msgstr ""
+msgid "Shared runners enabled cannot be enabled until a valid credit card is on file"
+msgstr ""
+
msgid "Shared runners help link"
msgstr ""
@@ -33340,6 +34033,9 @@ msgstr ""
msgid "Show all issues."
msgstr ""
+msgid "Show all milestones"
+msgstr ""
+
msgid "Show all test cases."
msgstr ""
@@ -33376,6 +34072,9 @@ msgstr ""
msgid "Show file contents"
msgstr ""
+msgid "Show group milestones"
+msgstr ""
+
msgid "Show labels"
msgstr ""
@@ -33391,6 +34090,12 @@ msgstr ""
msgid "Show open epics"
msgstr ""
+msgid "Show project milestones"
+msgstr ""
+
+msgid "Show sub-group milestones"
+msgstr ""
+
msgid "Show the Closed list"
msgstr ""
@@ -33400,12 +34105,6 @@ msgstr ""
msgid "Show whitespace changes"
msgstr ""
-msgid "Showing %d event"
-msgid_plural "Showing %d events"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-
msgid "Showing %{conflict} between %{sourceBranch} and %{targetBranch}"
msgstr ""
@@ -33466,12 +34165,6 @@ msgstr ""
msgid "Sidebar|None"
msgstr ""
-msgid "Sidebar|Only numeral characters allowed"
-msgstr ""
-
-msgid "Sidebar|Weight"
-msgstr ""
-
msgid "Sidekiq job compression threshold (bytes)"
msgstr ""
@@ -33634,6 +34327,9 @@ msgstr ""
msgid "Slack logo"
msgstr ""
+msgid "SlackIntegration|Are you sure you want to remove this project from the Slack application?"
+msgstr ""
+
msgid "SlackIntegration|GitLab for Slack"
msgstr ""
@@ -33643,6 +34339,9 @@ msgstr ""
msgid "SlackIntegration|Project alias"
msgstr ""
+msgid "SlackIntegration|Remove project"
+msgstr ""
+
msgid "SlackIntegration|Select a GitLab project to link with your Slack workspace."
msgstr ""
@@ -33787,9 +34486,6 @@ msgstr ""
msgid "Something went wrong trying to load issue contacts."
msgstr ""
-msgid "Something went wrong when creating a work item. Please try again"
-msgstr ""
-
msgid "Something went wrong when reordering designs. Please try again"
msgstr ""
@@ -33883,9 +34579,6 @@ msgstr ""
msgid "Something went wrong while inserting your image. Please try again."
msgstr ""
-msgid "Something went wrong while merging this merge request. Please try again."
-msgstr ""
-
msgid "Something went wrong while obtaining the Let's Encrypt certificate."
msgstr ""
@@ -34207,10 +34900,10 @@ 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."
+msgid "SourcegraphAdmin|Learn more."
msgstr ""
-msgid "SourcegraphAdmin|More information"
+msgid "SourcegraphAdmin|Only public projects have code intelligence enabled and communicate with Sourcegraph."
msgstr ""
msgid "SourcegraphAdmin|Save changes"
@@ -34219,7 +34912,7 @@ msgstr ""
msgid "SourcegraphAdmin|Sourcegraph URL"
msgstr ""
-msgid "SourcegraphAdmin|e.g. https://sourcegraph.example.com"
+msgid "SourcegraphAdmin|https://sourcegraph.example.com"
msgstr ""
msgid "SourcegraphPreferences|This feature is experimental and currently limited to certain projects."
@@ -34354,6 +35047,9 @@ msgstr ""
msgid "Start date"
msgstr ""
+msgid "Start free trial"
+msgstr ""
+
msgid "Start merge train"
msgstr ""
@@ -34384,6 +35080,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started escalation for this incident."
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -34396,6 +35095,9 @@ msgstr ""
msgid "Starts at (UTC)"
msgstr ""
+msgid "Starts escalations for this incident"
+msgstr ""
+
msgid "Starts on"
msgstr ""
@@ -34657,6 +35359,9 @@ msgstr ""
msgid "Strikethrough"
msgstr ""
+msgid "Strikethrough text"
+msgstr ""
+
msgid "Subgroup information"
msgstr ""
@@ -34891,6 +35596,21 @@ msgstr ""
msgid "Subscriptions"
msgstr ""
+msgid "Subscriptions|Chat with sales"
+msgstr ""
+
+msgid "Subscriptions|Close"
+msgstr ""
+
+msgid "Subscriptions|Not ready to buy yet?"
+msgstr ""
+
+msgid "Subscriptions|Start a free trial"
+msgstr ""
+
+msgid "Subscriptions|We understand. Maybe you have some questions for our sales team, or maybe you'd like to try some of the paid features first. What would you like to do?"
+msgstr ""
+
msgid "Subscription|Your subscription for %{strong}%{namespace_name}%{strong_close} has expired and you are now on %{pricing_link_start}the GitLab Free tier%{pricing_link_end}. Don't worry, your data is safe. Get in touch with our support team (%{support_email}). They'll gladly help with your subscription renewal."
msgstr ""
@@ -35101,6 +35821,9 @@ msgstr ""
msgid "SuperSonics|Maximum users"
msgstr ""
+msgid "SuperSonics|Offline cloud"
+msgstr ""
+
msgid "SuperSonics|Paste your activation code"
msgstr ""
@@ -35167,6 +35890,12 @@ msgstr ""
msgid "SuperSonics|You do not have an active subscription"
msgstr ""
+msgid "SuperSonics|You have a future dated license"
+msgstr ""
+
+msgid "SuperSonics|You have added a license that activates on %{date}. Please see the subscription history table below for more details."
+msgstr ""
+
msgid "SuperSonics|You have successfully added a license that activates on %{date}. Please see the subscription history table below for more details."
msgstr ""
@@ -35326,6 +36055,9 @@ msgstr ""
msgid "Tag name is required"
msgstr ""
+msgid "Tag push"
+msgstr ""
+
msgid "Tag push events"
msgstr ""
@@ -35428,6 +36160,9 @@ msgstr ""
msgid "TagsPage|protected"
msgstr ""
+msgid "Take a look at the documentation to discover all of GitLab’s capabilities."
+msgstr ""
+
msgid "Target Branch"
msgstr ""
@@ -35836,6 +36571,9 @@ msgstr ""
msgid "Tests"
msgstr ""
+msgid "Text (optional)"
+msgstr ""
+
msgid "Text added to the body of all email messages. %{character_limit} character limit"
msgstr ""
@@ -35887,6 +36625,9 @@ msgstr ""
msgid "The CSV export will be created in the background. Once finished, it will be sent to %{email} in an attachment."
msgstr ""
+msgid "The CSV export you requested of all user memberships is attached to this email."
+msgstr ""
+
msgid "The GitLab subscription service (customers.gitlab.com) is currently experiencing an outage. You can monitor the status and get updates at %{linkStart}status.gitlab.com%{linkEnd}."
msgstr ""
@@ -35962,6 +36703,9 @@ 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 epic"
+msgstr ""
+
msgid "The current issue"
msgstr ""
@@ -36124,6 +36868,9 @@ msgstr ""
msgid "The latest pipeline for this merge request has failed."
msgstr ""
+msgid "The license key is invalid."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -36139,6 +36886,9 @@ msgstr ""
msgid "The license was successfully uploaded and will be active from %{starts_at}. You can see the details below."
msgstr ""
+msgid "The license you uploaded is invalid. If the issue persists, contact support at %{link}."
+msgstr ""
+
msgid "The list creation wizard is already open"
msgstr ""
@@ -36760,10 +37510,13 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} and everything this project contains. %{strongOpen}There is no going back%{strongClose}"
+msgstr ""
+
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains."
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}on %{date}%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains. %{strongOpen}There is no going back.%{strongClose}"
msgstr ""
msgid "This action will %{strongOpen}permanently remove%{strongClose} %{codeOpen}%{group}%{codeClose} %{strongOpen}immediately%{strongClose}."
@@ -36892,9 +37645,6 @@ msgstr ""
msgid "This file was modified for readability, and can't accept suggestions. Edit it directly."
msgstr ""
-msgid "This forked project has the following:"
-msgstr ""
-
msgid "This form is disabled in preview"
msgstr ""
@@ -36907,7 +37657,7 @@ msgstr ""
msgid "This group can't be removed because it is linked to a subscription. To remove this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
-msgid "This group can't be transfered because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
+msgid "This group can't be transferred because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
msgid "This group cannot be invited to a project inside a group with enforced SSO"
@@ -36934,6 +37684,9 @@ 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 incident is already escalated with '%{escalation_policy_name}'."
+msgstr ""
+
msgid "This invitation was sent to %{mail_to_invite_email}, but you are signed in as %{link_to_current_user} with email %{mail_to_current_user}."
msgstr ""
@@ -36952,9 +37705,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 merge train pipeline"
-msgstr ""
-
msgid "This is a private email address %{helpIcon} generated just for you. Anyone who has it can create issues or merge requests as if they were you. If that happens, %{resetLinkStart}reset this token%{resetLinkEnd}."
msgstr ""
@@ -36976,6 +37726,12 @@ msgstr ""
msgid "This is your current session"
msgstr ""
+msgid "This issue cannot be assigned to a confidential epic because it is public."
+msgstr ""
+
+msgid "This issue cannot be made public because it belongs to a confidential epic."
+msgstr ""
+
msgid "This issue is confidential and should only be visible to team members with at least Reporter access."
msgstr ""
@@ -37093,6 +37849,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 branch is protected from force push."
+msgstr ""
+
msgid "This merge request cannot be rebased while there are conflicts."
msgstr ""
@@ -37144,9 +37903,15 @@ msgstr ""
msgid "This pipeline was triggered by a schedule."
msgstr ""
+msgid "This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project"
msgstr ""
+msgid "This project can be restored until %{date}."
+msgstr ""
+
msgid "This project cannot be %{visibilityLevel} because the visibility of %{openShowLink}%{name}%{closeShowLink} is %{visibility}. To make this project %{visibilityLevel}, you must first %{openEditLink}change the visibility%{closeEditLink} of the parent group."
msgstr ""
@@ -37165,6 +37930,9 @@ msgstr ""
msgid "This project is %{strongStart}NOT%{strongEnd} a fork, and has the following:"
msgstr ""
+msgid "This project is %{strongStart}NOT%{strongEnd} a fork. This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -37858,6 +38626,9 @@ msgstr ""
msgid "Today"
msgstr ""
+msgid "Todos count"
+msgstr ""
+
msgid "Todos|Are you looking for things to do? Take a look at %{strongStart}%{openIssuesLinkStart}open issues%{openIssuesLinkEnd}%{strongEnd}, contribute to %{strongStart}%{mergeRequestLinkStart}a merge request%{mergeRequestLinkEnd}%{mergeRequestLinkEnd}%{strongEnd}, or mention someone in a comment to automatically assign them a new to-do item."
msgstr ""
@@ -38131,11 +38902,8 @@ msgstr ""
msgid "Trending"
msgstr ""
-msgid "Trials|%{planName} Trial %{enDash} %{num} day left"
-msgid_plural "Trials|%{planName} Trial %{enDash} %{num} days left"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
+msgid "Trials|%{planName} Trial"
+msgstr ""
msgid "Trials|Compare all plans"
msgstr ""
@@ -38143,6 +38911,9 @@ msgstr ""
msgid "Trials|Create a new group to start your GitLab Ultimate trial."
msgstr ""
+msgid "Trials|Day %{daysUsed}/%{duration}"
+msgstr ""
+
msgid "Trials|Go back to GitLab"
msgstr ""
@@ -38392,7 +39163,7 @@ msgstr ""
msgid "URL is triggered when repository is updated"
msgstr ""
-msgid "URL must be percent-encoded if neccessary."
+msgid "URL must be percent-encoded if necessary."
msgstr ""
msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
@@ -38611,6 +39382,9 @@ msgstr ""
msgid "Unlock account"
msgstr ""
+msgid "Unlock more features with GitLab Ultimate"
+msgstr ""
+
msgid "Unlock the discussion"
msgstr ""
@@ -38674,6 +39448,9 @@ msgstr ""
msgid "Unsubscribes from this %{quick_action_target}."
msgstr ""
+msgid "Unsupported sort value."
+msgstr ""
+
msgid "Unsupported todo type passed. Supported todo types are: %{todo_types}"
msgstr ""
@@ -38902,6 +39679,9 @@ msgstr ""
msgid "UsageQuota|File attachments and smaller design graphics."
msgstr ""
+msgid "UsageQuota|From %{storage_enforcement_date} storage limits will apply to this namespace. View and manage your usage in %{strong_start}Group Settings &gt; Usage quotas%{strong_end}."
+msgstr ""
+
msgid "UsageQuota|Git repository."
msgstr ""
@@ -38962,6 +39742,9 @@ msgstr ""
msgid "UsageQuota|Storage type"
msgstr ""
+msgid "UsageQuota|Storage used"
+msgstr ""
+
msgid "UsageQuota|This is the total amount of storage used across your projects within this namespace."
msgstr ""
@@ -39157,6 +39940,12 @@ msgstr ""
msgid "Use hashed storage paths for newly created and renamed repositories. Always enabled since 13.0."
msgstr ""
+msgid "Use issue count"
+msgstr ""
+
+msgid "Use issue weight"
+msgstr ""
+
msgid "Use one line per URI"
msgstr ""
@@ -39538,6 +40327,9 @@ msgstr ""
msgid "Users"
msgstr ""
+msgid "Users API rate limit"
+msgstr ""
+
msgid "Users can launch a development environment from a GitLab browser tab when the %{linkStart}Gitpod%{linkEnd} integration is enabled."
msgstr ""
@@ -39865,6 +40657,9 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View group pipeline usage quota"
+msgstr ""
+
msgid "View incident details at"
msgstr ""
@@ -40018,6 +40813,9 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
+msgid "Vulnerability"
+msgstr ""
+
msgid "Vulnerability Report"
msgstr ""
@@ -40069,6 +40867,9 @@ msgstr ""
msgid "VulnerabilityManagement|An unverified non-confirmed finding"
msgstr ""
+msgid "VulnerabilityManagement|At least one identifier is required"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -40078,12 +40879,24 @@ msgstr ""
msgid "VulnerabilityManagement|Create Jira issue"
msgstr ""
+msgid "VulnerabilityManagement|Enter a name"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE code"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE identifier URL"
+msgstr ""
+
msgid "VulnerabilityManagement|Fetching linked Jira issues"
msgstr ""
msgid "VulnerabilityManagement|Manually add a vulnerability entry into the vulnerability report."
msgstr ""
+msgid "VulnerabilityManagement|Name is a required field"
+msgstr ""
+
msgid "VulnerabilityManagement|Needs triage"
msgstr ""
@@ -40099,6 +40912,18 @@ msgstr ""
msgid "VulnerabilityManagement|Select a method"
msgstr ""
+msgid "VulnerabilityManagement|Select a severity level"
+msgstr ""
+
+msgid "VulnerabilityManagement|Select a status"
+msgstr ""
+
+msgid "VulnerabilityManagement|Severity is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Something went wrong while creating vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -40123,6 +40948,12 @@ msgstr ""
msgid "VulnerabilityManagement|Something went wrong, could not update vulnerability state."
msgstr ""
+msgid "VulnerabilityManagement|Status is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Submit vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Summary, detailed description, steps to reproduce, etc."
msgstr ""
@@ -40318,6 +41149,9 @@ msgstr ""
msgid "WARNING:"
msgstr ""
+msgid "WARNING: This snippet contains hidden files which might be used to mask malicious behavior. Exercise caution if cloning and executing code from this snippet."
+msgstr ""
+
msgid "Wait for the file to load to copy its contents"
msgstr ""
@@ -40537,6 +41371,15 @@ msgstr ""
msgid "Webhooks|An issue is created, updated, closed, or reopened."
msgstr ""
+msgid "Webhooks|Are you sure you want to delete this group hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this project hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this webhook?"
+msgstr ""
+
msgid "Webhooks|Comments"
msgstr ""
@@ -40546,6 +41389,9 @@ msgstr ""
msgid "Webhooks|Confidential issues events"
msgstr ""
+msgid "Webhooks|Delete webhook"
+msgstr ""
+
msgid "Webhooks|Deployment events"
msgstr ""
@@ -40780,6 +41626,9 @@ msgstr ""
msgid "Wiki"
msgstr ""
+msgid "Wiki page"
+msgstr ""
+
msgid "Wiki page was successfully created."
msgstr ""
@@ -40885,7 +41734,7 @@ msgstr ""
msgid "WikiPageConflictMessage|Someone edited the page the same time you did. Please check out %{wikiLinkStart}the page%{wikiLinkEnd} and make sure your changes will not unintentionally remove theirs."
msgstr ""
-msgid "WikiPage|An error occured while trying to render the content editor. Please try again later."
+msgid "WikiPage|An error occurred while trying to render the content editor. Please try again later."
msgstr ""
msgid "WikiPage|Are you sure you want to switch back to the classic editor?"
@@ -41044,6 +41893,18 @@ msgstr ""
msgid "WorkItem|New Task"
msgstr ""
+msgid "WorkItem|Something went wrong when creating a work item. Please try again"
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching the work item. Please try again."
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching work item types. Please try again"
+msgstr ""
+
+msgid "WorkItem|Type"
+msgstr ""
+
msgid "WorkItem|Work Items"
msgstr ""
@@ -41110,7 +41971,10 @@ msgstr ""
msgid "You are about to add %{usersTag} people to the discussion. They will all receive a notification."
msgstr ""
-msgid "You are about to permanently delete this project"
+msgid "You are about to delete this forked project containing:"
+msgstr ""
+
+msgid "You are about to delete this project containing:"
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."
@@ -41131,6 +41995,9 @@ msgstr ""
msgid "You are attempting to update a file that has changed since you started editing it."
msgstr ""
+msgid "You are billed if you exceed this number. %{qsrOverageLinkStart}How does billing work?%{qsrOverageLinkEnd}"
+msgstr ""
+
msgid "You are connected to the Prometheus server, but there is currently no data to display."
msgstr ""
@@ -41188,6 +42055,9 @@ msgstr ""
msgid "You are not authorized to update this scanner profile"
msgstr ""
+msgid "You are not authorized to upload metric images"
+msgstr ""
+
msgid "You are now impersonating %{username}"
msgstr ""
@@ -41341,9 +42211,6 @@ msgstr ""
msgid "You can only upload one design when dropping onto an existing design."
msgstr ""
-msgid "You can recover this project until %{date}"
-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 ""
@@ -41392,9 +42259,6 @@ msgstr ""
msgid "You cannot write to this read-only GitLab instance."
msgstr ""
-msgid "You can’t %{tag_start}edit%{tag_end} files directly in this project. Fork this project and submit a merge request with your changes."
-msgstr ""
-
msgid "You can’t edit files directly in this project. Fork this project and submit a merge request with your changes."
msgstr ""
@@ -41548,9 +42412,6 @@ 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 set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
@@ -41581,12 +42442,6 @@ msgstr ""
msgid "You must have maintainer access to force delete a lock"
msgstr ""
-msgid "You must have permission to create a project in a group before forking."
-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 ""
@@ -41992,7 +42847,7 @@ msgstr ""
msgid "Your public email will be displayed on your public profile."
msgstr ""
-msgid "Your request for access could not be processed: %{error_meesage}"
+msgid "Your request for access could not be processed: %{error_message}"
msgstr ""
msgid "Your request for access has been queued for review."
@@ -42178,6 +43033,9 @@ msgstr ""
msgid "archived:"
msgstr ""
+msgid "artifacts"
+msgstr ""
+
msgid "assign yourself"
msgstr ""
@@ -42208,6 +43066,9 @@ msgstr[2] ""
msgid "branch name"
msgstr ""
+msgid "builds"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -42634,6 +43495,9 @@ msgstr ""
msgid "contact with same email already exists in group hierarchy"
msgstr ""
+msgid "container registry images"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -42673,6 +43537,9 @@ msgstr ""
msgid "data"
msgstr ""
+msgid "database"
+msgstr ""
+
msgid "date must not be after 9999-12-31"
msgstr ""
@@ -42697,9 +43564,6 @@ msgstr ""
msgid "design"
msgstr ""
-msgid "detached"
-msgstr ""
-
msgid "disabled"
msgstr ""
@@ -42952,7 +43816,7 @@ msgstr ""
msgid "is not a valid X509 certificate."
msgstr ""
-msgid "is not allowed for sign-up."
+msgid "is not allowed for sign-up. Please use your regular email address."
msgstr ""
msgid "is not allowed for this group."
@@ -42964,7 +43828,7 @@ msgstr ""
msgid "is not allowed since the group is not top-level group."
msgstr ""
-msgid "is not allowed."
+msgid "is not allowed. Please use your regular email address."
msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
@@ -43051,6 +43915,9 @@ msgstr ""
msgid "level: %{level}"
msgstr ""
+msgid "lfs objects"
+msgstr ""
+
msgid "limit of %{project_limit} reached"
msgstr ""
@@ -43273,6 +44140,9 @@ msgstr ""
msgid "mrWidget|Merge blocked: pipeline must succeed. It's waiting for a manual action to continue."
msgstr ""
+msgid "mrWidget|Merge blocked: pipeline must succeed. Push a commit that fixes the failure, or %{linkStart}learn about other solutions.%{linkEnd}"
+msgstr ""
+
msgid "mrWidget|Merge blocked: this merge request must be approved."
msgstr ""
@@ -43390,9 +44260,6 @@ msgstr ""
msgid "mrWidget|The changes were not merged into"
msgstr ""
-msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -43540,9 +44407,6 @@ msgstr ""
msgid "open issue"
msgstr ""
-msgid "opened %{timeAgo}"
-msgstr ""
-
msgid "or"
msgstr ""
@@ -43555,6 +44419,12 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
+msgid "packages"
+msgstr ""
+
+msgid "pages"
+msgstr ""
+
msgid "parent"
msgid_plural "parents"
msgstr[0] ""
@@ -43708,6 +44578,9 @@ msgstr[0] ""
msgstr[1] ""
msgstr[2] ""
+msgid "repositories"
+msgstr ""
+
msgid "repository:"
msgstr ""
@@ -43828,12 +44701,18 @@ msgstr ""
msgid "tag name"
msgstr ""
+msgid "terraform states"
+msgstr ""
+
msgid "the correct format."
msgstr ""
msgid "the file"
msgstr ""
+msgid "the following epic(s)"
+msgstr ""
+
msgid "the following issue(s)"
msgstr ""
@@ -43846,21 +44725,12 @@ msgstr ""
msgid "this document"
msgstr ""
-msgid "this issue cannot be assigned to a confidential epic since it is public"
-msgstr ""
-
-msgid "this issue cannot be made public since it belongs to a confidential epic"
-msgstr ""
-
msgid "time summary"
msgstr ""
msgid "toggle collapse"
msgstr ""
-msgid "train"
-msgstr ""
-
msgid "triggered"
msgstr ""
@@ -43990,3 +44860,6 @@ msgstr ""
msgid "{project}"
msgstr ""
+msgid "✔"
+msgstr ""
+
diff --git a/locale/sv_SE/gitlab.po b/locale/sv_SE/gitlab.po
index 10d1c88b0be..7a029eff528 100644
--- a/locale/sv_SE/gitlab.po
+++ b/locale/sv_SE/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: sv-SE\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2022-02-02 15:42\n"
+"PO-Revision-Date: 2022-03-01 20:36\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -146,6 +146,11 @@ msgid_plural "%d approvers (you've approved)"
msgstr[0] "%d godkännare (du har godkänt)"
msgstr[1] "%d godkännare (du har godkänt)"
+msgid "%d assigned issue"
+msgid_plural "%d assigned issues"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] "%d ändrad fil"
@@ -421,8 +426,23 @@ msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
msgstr[1] ""
-msgid "%d vulnerability updated"
-msgid_plural "%d vulnerabilities updated"
+msgid "%d vulnerability set to confirmed"
+msgid_plural "%d vulnerabilities set to confirmed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to dismissed"
+msgid_plural "%d vulnerabilities set to dismissed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to needs triage"
+msgid_plural "%d vulnerabilities set to needs triage"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to resolved"
+msgid_plural "%d vulnerabilities set to resolved"
msgstr[0] ""
msgstr[1] ""
@@ -510,6 +530,12 @@ msgstr[1] ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{completed} of %{total} issues closed"
+msgstr ""
+
+msgid "%{completed} of %{total} weight completed"
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -858,6 +884,9 @@ msgstr ""
msgid "%{openedIssues} open, %{closedIssues} closed"
msgstr ""
+msgid "%{percentage}%% issues closed"
+msgstr ""
+
msgid "%{percentage}%% weight completed"
msgstr ""
@@ -1287,6 +1316,9 @@ msgid_plural "- Users"
msgstr[0] ""
msgstr[1] ""
+msgid "- of - issues closed"
+msgstr ""
+
msgid "- of - weight completed"
msgstr ""
@@ -1429,7 +1461,7 @@ msgstr ""
msgid "1000+"
msgstr "1000+"
-msgid "192.168.0.0/24"
+msgid "192.168.0.0/24 or 2001:0DB8:1234::/48"
msgstr ""
msgid "1st contribution!"
@@ -1741,13 +1773,13 @@ msgstr ""
msgid "AWS Access Key"
msgstr ""
-msgid "AWS Access Key. Only required if not using role instance credentials"
+msgid "AWS Secret Access Key"
msgstr ""
-msgid "AWS Secret Access Key"
+msgid "AWS access key ID (Optional)"
msgstr ""
-msgid "AWS Secret Access Key. Only required if not using role instance credentials"
+msgid "AWS secret access key (Optional)"
msgstr ""
msgid "AWS service error: %{error}"
@@ -1807,9 +1839,6 @@ msgstr ""
msgid "Access granted"
msgstr ""
-msgid "Access key ID"
-msgstr ""
-
msgid "Access requests"
msgstr ""
@@ -1984,7 +2013,7 @@ msgstr ""
msgid "Activity"
msgstr ""
-msgid "Activity|An error occured while retrieving activity. Reload the page to try again."
+msgid "Activity|An error occurred while retrieving activity. Reload the page to try again."
msgstr ""
msgid "Add"
@@ -2023,6 +2052,9 @@ msgstr ""
msgid "Add a %{type}"
msgstr ""
+msgid "Add a GCP region"
+msgstr ""
+
msgid "Add a GPG key"
msgstr "Lägg till en GPG-nyckel"
@@ -2074,6 +2106,9 @@ msgstr ""
msgid "Add a numbered list"
msgstr ""
+msgid "Add a related epic"
+msgstr ""
+
msgid "Add a related issue"
msgstr ""
@@ -2188,6 +2223,9 @@ msgstr ""
msgid "Add or subtract spent time"
msgstr ""
+msgid "Add people"
+msgstr ""
+
msgid "Add previously merged commits"
msgstr ""
@@ -2254,6 +2292,9 @@ msgstr ""
msgid "Add webhook"
msgstr ""
+msgid "Add your team members and others to GitLab."
+msgstr ""
+
msgid "Add/remove"
msgstr ""
@@ -3076,12 +3117,6 @@ msgstr ""
msgid "AdvancedSearch|Reindex required"
msgstr ""
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. Permanently deleting this project will %{strongStart}immediately delete%{strongEnd} its repositories and %{strongStart}all related resources%{strongEnd}, including issues, merge requests etc."
-msgstr ""
-
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. You will lose this project's repository and %{strongStart}all related resources%{strongEnd}, including issues and merge requests."
-msgstr ""
-
msgid "After a successful password update you will be redirected to login screen."
msgstr ""
@@ -3112,6 +3147,9 @@ msgstr ""
msgid "Akismet helps prevent the creation of spam issues in public projects."
msgstr ""
+msgid "Alert"
+msgstr ""
+
msgid "AlertManagement|Acknowledged"
msgstr ""
@@ -3484,9 +3522,6 @@ msgstr ""
msgid "All environments"
msgstr ""
-msgid "All epics"
-msgstr ""
-
msgid "All groups and projects"
msgstr ""
@@ -4223,12 +4258,15 @@ msgstr ""
msgid "ApplicationSettings|Approve users in the pending approval status?"
msgstr ""
-msgid "ApplicationSettings|By making this change, you will automatically approve %d user with the pending approval status."
-msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users with the pending approval status."
+msgid "ApplicationSettings|Approve users who are pending approval?"
+msgstr ""
+
+msgid "ApplicationSettings|By making this change, you will automatically approve %d user who is pending approval."
+msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users who are pending approval."
msgstr[0] ""
msgstr[1] ""
-msgid "ApplicationSettings|By making this change, you will automatically approve all users in pending approval status."
+msgid "ApplicationSettings|By making this change, you will automatically approve all users who are pending approval."
msgstr ""
msgid "ApplicationSettings|Denied domains for sign-ups"
@@ -4634,10 +4672,10 @@ msgstr ""
msgid "Archiving the project will make it entirely read-only. It is hidden from the dashboard and doesn't show up in searches. %{strong_start}The repository cannot be committed to, and no issues, comments, or other entities can be created.%{strong_end} %{link_start}Learn more.%{link_end}"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to delete this project?"
+msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
+msgid "Are you absolutely sure?"
msgstr ""
msgid "Are you sure that you want to archive this project?"
@@ -4673,12 +4711,18 @@ msgstr ""
msgid "Are you sure you want to delete this SSH key?"
msgstr ""
+msgid "Are you sure you want to delete this comment?"
+msgstr ""
+
msgid "Are you sure you want to delete this deploy key?"
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 label?"
+msgstr ""
+
msgid "Are you sure you want to delete this pipeline schedule?"
msgstr ""
@@ -4694,9 +4738,6 @@ msgstr ""
msgid "Are you sure you want to discard your changes?"
msgstr ""
-msgid "Are you sure you want to erase this build?"
-msgstr ""
-
msgid "Are you sure you want to import %d repository?"
msgid_plural "Are you sure you want to import %d repositories?"
msgstr[0] ""
@@ -4744,6 +4785,9 @@ msgstr ""
msgid "Are you sure you want to remove this list?"
msgstr ""
+msgid "Are you sure you want to remove this nickname?"
+msgstr ""
+
msgid "Are you sure you want to reset the health check token?"
msgstr ""
@@ -4756,10 +4800,10 @@ 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?"
+msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
msgstr ""
-msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
+msgid "Are you sure you want to revoke this project access token? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to stop this environment?"
@@ -4906,9 +4950,6 @@ msgstr ""
msgid "Assigned to %{assignee_name}"
msgstr ""
-msgid "Assigned to %{name}"
-msgstr ""
-
msgid "Assigned to me"
msgstr ""
@@ -4973,6 +5014,9 @@ msgstr[1] ""
msgid "Attaching the file failed."
msgstr ""
+msgid "Attention"
+msgstr ""
+
msgid "Audit Events"
msgstr ""
@@ -5135,6 +5179,12 @@ msgstr ""
msgid "Authorized applications (%{size})"
msgstr ""
+msgid "AuthorizedApplication|Are you sure you want to revoke this application?"
+msgstr ""
+
+msgid "AuthorizedApplication|Revoke application"
+msgstr ""
+
msgid "Authors: %{authors}"
msgstr ""
@@ -6328,6 +6378,9 @@ msgstr ""
msgid "CICDAnalytics|Shared Runners Usage"
msgstr ""
+msgid "CICDAnalytics|Shared runner pipeline minute duration by month"
+msgstr ""
+
msgid "CICDAnalytics|Shared runner usage"
msgstr ""
@@ -6469,6 +6522,9 @@ msgstr ""
msgid "Can create groups:"
msgstr ""
+msgid "Can not delete primary training"
+msgstr ""
+
msgid "Can't apply as the source branch was deleted."
msgstr ""
@@ -6802,9 +6858,6 @@ msgstr ""
msgid "Changing any setting here requires an application restart"
msgstr ""
-msgid "Changing group URL can have unintended side effects."
-msgstr ""
-
msgid "Charts can't be displayed as the request for data has timed out. %{documentationLink}"
msgstr ""
@@ -6892,9 +6945,6 @@ msgstr ""
msgid "Checking branch availability..."
msgstr ""
-msgid "Checking group URL availability..."
-msgstr ""
-
msgid "Checking group path availability..."
msgstr ""
@@ -7388,6 +7438,9 @@ msgstr ""
msgid "Clear recent searches"
msgstr ""
+msgid "Clear repository checks"
+msgstr ""
+
msgid "Clear search"
msgstr ""
@@ -7520,9 +7573,6 @@ msgstr ""
msgid "Closed MRs"
msgstr ""
-msgid "Closed epics"
-msgstr ""
-
msgid "Closed issues"
msgstr ""
@@ -7559,13 +7609,13 @@ msgstr ""
msgid "Cluster level"
msgstr ""
-msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
+msgid "Cluster type must be specified for Stages::ClusterEndpointInserter"
msgstr ""
msgid "ClusterAgents|%{name} successfully deleted"
msgstr ""
-msgid "ClusterAgents|%{number} of %{total} Agents"
+msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
@@ -7607,6 +7657,15 @@ msgstr ""
msgid "ClusterAgents|Agent never connected to GitLab"
msgstr ""
+msgid "ClusterAgents|Agent version mismatch"
+msgstr ""
+
+msgid "ClusterAgents|Agent version mismatch and update"
+msgstr ""
+
+msgid "ClusterAgents|Agent version update required"
+msgstr ""
+
msgid "ClusterAgents|All"
msgstr ""
@@ -7631,7 +7690,7 @@ msgstr ""
msgid "ClusterAgents|Configuration"
msgstr ""
-msgid "ClusterAgents|Connect a cluster through the Agent"
+msgid "ClusterAgents|Connect a cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connect existing cluster"
@@ -7640,13 +7699,13 @@ msgstr ""
msgid "ClusterAgents|Connect with a certificate"
msgstr ""
-msgid "ClusterAgents|Connect with agent"
+msgid "ClusterAgents|Connect with an agent"
msgstr ""
msgid "ClusterAgents|Connect with the GitLab Agent"
msgstr ""
-msgid "ClusterAgents|Connect your cluster through the Agent"
+msgid "ClusterAgents|Connect your cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connected"
@@ -7706,7 +7765,10 @@ msgstr ""
msgid "ClusterAgents|How to register an agent?"
msgstr ""
-msgid "ClusterAgents|Install new Agent"
+msgid "ClusterAgents|How to update an agent?"
+msgstr ""
+
+msgid "ClusterAgents|Install a new agent"
msgstr ""
msgid "ClusterAgents|Last connected %{timeAgo}."
@@ -7733,7 +7795,7 @@ msgstr ""
msgid "ClusterAgents|Never connected"
msgstr ""
-msgid "ClusterAgents|No Agents"
+msgid "ClusterAgents|No agents"
msgstr ""
msgid "ClusterAgents|No clusters connected through cluster certificates"
@@ -7793,6 +7855,9 @@ msgstr ""
msgid "ClusterAgents|The agent has not been connected in a long time. There might be a connectivity issue. Last contact was %{timeAgo}."
msgstr ""
+msgid "ClusterAgents|The agent version do not match each other across your cluster's pods. This can happen when a new agent version was just deployed and Kubernetes is shutting down the old pods."
+msgstr ""
+
msgid "ClusterAgents|The recommended installation method includes the token. If you want to follow the advanced installation method provided in the docs, make sure you save the token value before you close this window."
msgstr ""
@@ -7840,6 +7905,9 @@ msgstr ""
msgid "ClusterAgents|You will need to create a token to connect to your agent"
msgstr ""
+msgid "ClusterAgents|Your agent version is out of sync with your GitLab version (v%{version}), which might cause compatibility problems. Update the agent installed on your cluster to the most recent version."
+msgstr ""
+
msgid "ClusterAgents|Your instance doesn't have the %{linkStart}GitLab Agent Server (KAS)%{linkEnd} set up. Ask a GitLab Administrator to install it."
msgstr ""
@@ -8716,9 +8784,6 @@ msgstr ""
msgid "Comma-separated list of email addresses."
msgstr ""
-msgid "Comma-separated list of users allowed to exceed the rate limit."
-msgstr ""
-
msgid "Comma-separated, e.g. '1.1.1.1, 2.2.2.0/24'"
msgstr ""
@@ -9045,6 +9110,12 @@ msgstr ""
msgid "Confidential"
msgstr "Konfidentiell"
+msgid "Confidential issue"
+msgstr ""
+
+msgid "Confidential note"
+msgstr ""
+
msgid "Confidentiality"
msgstr "Konfidentialitet"
@@ -9078,6 +9149,9 @@ msgstr ""
msgid "Configure Dependency Scanning in `.gitlab-ci.yml`, creating this file if it does not already exist"
msgstr ""
+msgid "Configure GitLab"
+msgstr ""
+
msgid "Configure GitLab runners to start using the Web Terminal. %{helpStart}Learn more.%{helpEnd}"
msgstr ""
@@ -9126,6 +9200,15 @@ msgstr ""
msgid "Configure pipelines to deploy web apps, backend services, APIs and static resources to Google Cloud"
msgstr ""
+msgid "Configure region"
+msgstr ""
+
+msgid "Configure region for environment"
+msgstr ""
+
+msgid "Configure regions"
+msgstr ""
+
msgid "Configure repository mirroring."
msgstr ""
@@ -9159,6 +9242,9 @@ msgstr ""
msgid "Configure which lists are shown for anyone who visits this board"
msgstr ""
+msgid "Configure your environments to be deployed to specific geographical regions"
+msgstr ""
+
msgid "Confirm"
msgstr ""
@@ -9861,10 +9947,10 @@ msgstr ""
msgid "CorpusManagement|Actions"
msgstr ""
-msgid "CorpusManagement|Corpus are used in fuzz testing as mutation source to Improve future testing."
+msgid "CorpusManagement|Corpus file"
msgstr ""
-msgid "CorpusManagement|Corpus file"
+msgid "CorpusManagement|Corpus files are used in coverage-guided fuzz testing as seed inputs to improve testing."
msgstr ""
msgid "CorpusManagement|Corpus files must be in *.zip format. Maximum 5 GB"
@@ -9918,6 +10004,9 @@ msgstr ""
msgid "Could not apply %{name} command."
msgstr ""
+msgid "Could not apply %{name} command. %{message}."
+msgstr ""
+
msgid "Could not authorize chat nickname. Try again!"
msgstr ""
@@ -10068,6 +10157,9 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
+msgid "Create a group"
+msgstr ""
+
msgid "Create a merge request"
msgstr ""
@@ -10092,6 +10184,9 @@ msgstr ""
msgid "Create a personal access token on your account to pull or push via %{protocol}."
msgstr ""
+msgid "Create a project"
+msgstr ""
+
msgid "Create an account using:"
msgstr ""
@@ -10455,6 +10550,9 @@ msgstr ""
msgid "Creation date"
msgstr ""
+msgid "Creator"
+msgstr ""
+
msgid "Credentials"
msgstr ""
@@ -10467,9 +10565,15 @@ msgstr ""
msgid "CredentialsInventory|Personal Access Tokens"
msgstr ""
+msgid "CredentialsInventory|Project Access Tokens"
+msgstr ""
+
msgid "CredentialsInventory|SSH Keys"
msgstr ""
+msgid "Credit card required to be on file in order to create a pipeline"
+msgstr ""
+
msgid "Credit card:"
msgstr ""
@@ -10653,9 +10757,6 @@ msgstr ""
msgid "Customer relations"
msgstr ""
-msgid "Customizable by an administrator."
-msgstr ""
-
msgid "Customizable by owners."
msgstr ""
@@ -10785,30 +10886,18 @@ msgstr ""
msgid "CycleAnalytics|%{selectedLabelsCount} selected (%{maxLabels} max)"
msgstr ""
-msgid "CycleAnalytics|%{stageCount} stages selected"
-msgstr ""
-
-msgid "CycleAnalytics|All stages"
-msgstr ""
-
-msgid "CycleAnalytics|Average days to completion"
+msgid "CycleAnalytics|Average time to completion"
msgstr ""
msgid "CycleAnalytics|Date"
msgstr ""
-msgid "CycleAnalytics|Days to completion"
-msgstr ""
-
msgid "CycleAnalytics|Display chart filters"
msgstr ""
msgid "CycleAnalytics|Lead Time for Changes"
msgstr ""
-msgid "CycleAnalytics|No stages selected"
-msgstr ""
-
msgid "CycleAnalytics|Number of tasks"
msgstr ""
@@ -10837,18 +10926,30 @@ msgstr ""
msgid "CycleAnalytics|Showing data for group '%{groupName}' from %{createdAfter} to %{createdBefore}"
msgstr ""
-msgid "CycleAnalytics|Stages"
+msgid "CycleAnalytics|Stage time: %{title}"
msgstr ""
msgid "CycleAnalytics|Tasks by type"
msgstr ""
-msgid "CycleAnalytics|The average time spent in the selected stage for the items that were completed on each date. Data limited to the last 500 items."
+msgid "CycleAnalytics|The average time items spent in this stage. Data limited to items completed within this date range."
msgstr ""
msgid "CycleAnalytics|The given date range is larger than 180 days"
msgstr ""
+msgid "CycleAnalytics|The total time items spent across each value stream stage. Data limited to items completed within this date range."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Stage time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Total time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|Total time"
+msgstr ""
+
msgid "CycleAnalytics|Type of work"
msgstr ""
@@ -10861,9 +10962,6 @@ msgstr ""
msgid "CycleAnalytics|project dropdown filter"
msgstr ""
-msgid "CycleAnalytics|stage dropdown"
-msgstr ""
-
msgid "DAG visualization requires at least 3 dependent jobs."
msgstr ""
@@ -10963,10 +11061,16 @@ msgstr ""
msgid "DastProfiles|AJAX spider"
msgstr ""
+msgid "DastProfiles|API"
+msgstr ""
+
+msgid "DastProfiles|API endpoint URL"
+msgstr ""
+
msgid "DastProfiles|Active"
msgstr ""
-msgid "DastProfiles|Additional request headers (Optional)"
+msgid "DastProfiles|Additional request headers (optional)"
msgstr ""
msgid "DastProfiles|Are you sure you want to delete this profile?"
@@ -10981,6 +11085,9 @@ msgstr ""
msgid "DastProfiles|Branch missing"
msgstr ""
+msgid "DastProfiles|Choose a scan method"
+msgstr ""
+
msgid "DastProfiles|Could not create the scanner profile. Please try again."
msgstr ""
@@ -11050,7 +11157,13 @@ msgstr ""
msgid "DastProfiles|Excluded URLs"
msgstr ""
-msgid "DastProfiles|Excluded URLs (Optional)"
+msgid "DastProfiles|Excluded URLs (optional)"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths (optional)"
msgstr ""
msgid "DastProfiles|Hide debug messages"
@@ -11107,9 +11220,6 @@ msgstr ""
msgid "DastProfiles|Request headers"
msgstr ""
-msgid "DastProfiles|Rest API"
-msgstr ""
-
msgid "DastProfiles|Run the AJAX spider, in addition to the traditional spider, to crawl the target site."
msgstr ""
@@ -11119,6 +11229,9 @@ msgstr ""
msgid "DastProfiles|Save profile"
msgstr ""
+msgid "DastProfiles|Scan method"
+msgstr ""
+
msgid "DastProfiles|Scan mode"
msgstr ""
@@ -11197,12 +11310,24 @@ msgstr ""
msgid "DastProfiles|Website"
msgstr ""
+msgid "DastProfiles|What does each method do?"
+msgstr ""
+
msgid "DastProfiles|You can either choose a passive scan or validate the target site from the site profile management page. %{docsLinkStart}Learn more about site validation.%{docsLinkEnd}"
msgstr ""
msgid "DastProfiles|You cannot run an active scan against an unvalidated site."
msgstr ""
+msgid "DastProfiles|folder/dast_example.har or https://example.com/dast_example.har"
+msgstr ""
+
+msgid "DastProfiles|folder/example.postman_collection.json or https://example.com/"
+msgstr ""
+
+msgid "DastProfiles|folder/openapi.json or https://example.com/openapi.json"
+msgstr ""
+
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
@@ -11310,6 +11435,9 @@ msgstr ""
msgid "DatadogIntegration|API URL"
msgstr ""
+msgid "DatadogIntegration|Custom tags in Datadog. Enter one tag per line in the %{codeOpen}key:value%{codeClose} format. %{linkOpen}How do I use tags?%{linkClose}"
+msgstr ""
+
msgid "DatadogIntegration|Environment"
msgstr ""
@@ -11328,12 +11456,18 @@ msgstr ""
msgid "DatadogIntegration|Tag all data from this GitLab instance in Datadog. Useful when managing several self-managed deployments."
msgstr ""
+msgid "DatadogIntegration|Tags"
+msgstr ""
+
msgid "DatadogIntegration|The Datadog site to send data to. To send data to the EU site, use %{codeOpen}datadoghq.eu%{codeClose}."
msgstr ""
msgid "DatadogIntegration|Trace your GitLab pipelines with Datadog."
msgstr ""
+msgid "DatadogIntegration|have an invalid format"
+msgstr ""
+
msgid "Datasource name not found"
msgstr ""
@@ -11343,9 +11477,6 @@ msgstr ""
msgid "Date merged"
msgstr ""
-msgid "Date picker"
-msgstr ""
-
msgid "Date range"
msgstr ""
@@ -11499,9 +11630,6 @@ msgstr ""
msgid "Definition"
msgstr ""
-msgid "Delayed Project Deletion (%{adjourned_deletion})"
-msgstr ""
-
msgid "DelayedJobs|Are you sure you want to run %{jobName} immediately? Otherwise this job will run automatically after its timer finishes."
msgstr ""
@@ -11580,10 +11708,10 @@ msgstr ""
msgid "Delete pipeline"
msgstr ""
-msgid "Delete project"
+msgid "Delete pipeline schedule"
msgstr ""
-msgid "Delete project. Are you ABSOLUTELY SURE?"
+msgid "Delete project"
msgstr ""
msgid "Delete row"
@@ -11613,6 +11741,9 @@ msgstr ""
msgid "Delete this epic and all descendants?"
msgstr ""
+msgid "Delete this project"
+msgstr ""
+
msgid "Delete user list"
msgstr ""
@@ -11871,6 +12002,12 @@ msgstr ""
msgid "Deploy to..."
msgstr ""
+msgid "DeployBoards|To see deployment progress for your environments, make sure you are deploying to %{codeStart}$KUBE_NAMESPACE%{codeEnd} and annotating with %{codeStart}app.gitlab.com/app=$CI_PROJECT_PATH_SLUG%{codeEnd} and %{codeStart}app.gitlab.com/env=$CI_ENVIRONMENT_SLUG%{codeEnd}."
+msgstr ""
+
+msgid "DeployBoard|Kubernetes Pods"
+msgstr ""
+
msgid "DeployFreeze|Add a freeze period to prevent unintended releases during a period of time for a given environment. You must update the deployment jobs in %{filename} according to the deploy freezes added here. %{freeze_period_link_start}Learn more.%{freeze_period_link_end}"
msgstr ""
@@ -11955,9 +12092,6 @@ msgstr ""
msgid "DeployTokens|Active Deploy Tokens (%{active_tokens})"
msgstr ""
-msgid "DeployTokens|Allows read and write access to registry images."
-msgstr ""
-
msgid "DeployTokens|Allows read and write access to the package registry."
msgstr ""
@@ -11970,6 +12104,9 @@ msgstr ""
msgid "DeployTokens|Allows read-only access to the repository."
msgstr ""
+msgid "DeployTokens|Allows write access to registry images."
+msgstr ""
+
msgid "DeployTokens|Copy deploy token"
msgstr ""
@@ -12063,12 +12200,57 @@ msgstr ""
msgid "Deploying to AWS is easy with GitLab"
msgstr ""
+msgid "Deployment"
+msgstr ""
+
msgid "Deployment Frequency"
msgstr ""
+msgid "Deployment Target|Project deployment target (optional)"
+msgstr ""
+
+msgid "Deployment Target|Select the deployment target"
+msgstr ""
+
msgid "Deployment frequency"
msgstr ""
+msgid "DeploymentTarget|GitLab Pages"
+msgstr ""
+
+msgid "DeploymentTarget|Heroku"
+msgstr ""
+
+msgid "DeploymentTarget|Infrastructure provider (Terraform, Cloudformation, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Kubernetes (GKE, EKS, OpenShift, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Managed container runtime (Fargate, Cloud Run, DigitalOcean App)"
+msgstr ""
+
+msgid "DeploymentTarget|Mobile app store"
+msgstr ""
+
+msgid "DeploymentTarget|No deployment planned"
+msgstr ""
+
+msgid "DeploymentTarget|Other hosting service"
+msgstr ""
+
+msgid "DeploymentTarget|Registry (package or container)"
+msgstr ""
+
+msgid "DeploymentTarget|Self-managed container runtime (Podman, Docker Swarm, Docker Compose)"
+msgstr ""
+
+msgid "DeploymentTarget|Serverless backend (Lambda, Cloud functions)"
+msgstr ""
+
+msgid "DeploymentTarget|Virtual machine (for example, EC2)"
+msgstr ""
+
msgid "Deployments"
msgstr ""
@@ -12107,6 +12289,9 @@ msgstr ""
msgid "Deployment|This deployment was created using the API"
msgstr ""
+msgid "Deployment|Triggerer"
+msgstr ""
+
msgid "Deployment|Waiting"
msgstr ""
@@ -12134,6 +12319,18 @@ msgstr ""
msgid "Deprecated API rate limits"
msgstr ""
+msgid "Deprecations|Feature deprecation and removal"
+msgstr ""
+
+msgid "Deprecations|For information on a possible replacement %{epicStart} learn more about Opstrace %{epicEnd}."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7 and are %{epicStart} scheduled for removal %{epicEnd} in GitLab 15.0."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7, and are %{removal_link_start} scheduled for removal %{link_end} in GitLab 15.0. For information on a possible replacement, %{opstrace_link_start} learn more about Opstrace %{link_end}."
+msgstr ""
+
msgid "Deprioritize label"
msgstr ""
@@ -12379,10 +12576,10 @@ msgstr ""
msgid "DevopsAdoption|At least one deploy"
msgstr ""
-msgid "DevopsAdoption|At least one issue opened"
+msgid "DevopsAdoption|At least one issue created"
msgstr ""
-msgid "DevopsAdoption|At least one merge request opened"
+msgid "DevopsAdoption|At least one merge request created"
msgstr ""
msgid "DevopsAdoption|At least one pipeline successfully run"
@@ -12583,6 +12780,9 @@ msgstr ""
msgid "Direct member"
msgstr ""
+msgid "Direct members"
+msgstr ""
+
msgid "Direct non-authenticated users to this page."
msgstr ""
@@ -12699,6 +12899,9 @@ msgid_plural "Dismiss %d selected vulnerabilities as"
msgstr[0] ""
msgstr[1] ""
+msgid "Dismiss Alert"
+msgstr ""
+
msgid "Dismiss merge request promotion"
msgstr ""
@@ -12726,9 +12929,15 @@ msgstr ""
msgid "Display alerts from all configured monitoring tools."
msgstr ""
+msgid "Display milestones"
+msgstr ""
+
msgid "Display name"
msgstr ""
+msgid "Display progress of child issues"
+msgstr ""
+
msgid "Display rendered file"
msgstr ""
@@ -12834,6 +13043,9 @@ msgstr ""
msgid "Download image"
msgstr ""
+msgid "Download payload"
+msgstr ""
+
msgid "Download raw data (.csv)"
msgstr ""
@@ -13011,6 +13223,9 @@ msgstr ""
msgid "Edit in Web IDE"
msgstr ""
+msgid "Edit in pipeline editor"
+msgstr ""
+
msgid "Edit in single-file editor"
msgstr ""
@@ -13053,6 +13268,9 @@ msgstr ""
msgid "Edit your most recent comment in a thread (from an empty textarea)"
msgstr ""
+msgid "Edit, lint, and visualize your pipeline."
+msgstr ""
+
msgid "Edited"
msgstr ""
@@ -13494,6 +13712,9 @@ msgstr ""
msgid "Enforce two-factor authentication for all user sign-ins."
msgstr ""
+msgid "Enhance security by storing service account keys in secret managers - learn more about %{docLinkStart}secret management with GitLab%{docLinkEnd}"
+msgstr ""
+
msgid "Ensure connectivity is available from the GitLab server to the Prometheus server"
msgstr ""
@@ -13554,6 +13775,9 @@ 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 following to confirm:"
+msgstr ""
+
msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
@@ -14084,9 +14308,6 @@ 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 ""
@@ -14222,6 +14443,9 @@ msgstr ""
msgid "Errors:"
msgstr ""
+msgid "Escalate this incident"
+msgstr ""
+
msgid "Escalation Policies"
msgstr ""
@@ -14234,6 +14458,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy"
+msgstr ""
+
msgid "Escalation policy:"
msgstr ""
@@ -14485,6 +14712,9 @@ msgstr ""
msgid "Existing sign in methods may be removed"
msgstr ""
+msgid "Exit."
+msgstr ""
+
msgid "Expand"
msgstr ""
@@ -14581,6 +14811,9 @@ msgstr ""
msgid "Explore public groups"
msgstr ""
+msgid "Explore public projects"
+msgstr ""
+
msgid "Explore snippets"
msgstr ""
@@ -14742,7 +14975,7 @@ msgid_plural "Failed to archive designs. Please try again."
msgstr[0] ""
msgstr[1] ""
-msgid "Failed to assign a reviewer because no user was found."
+msgid "Failed to assign a reviewer because no user was specified."
msgstr ""
msgid "Failed to assign a user because no user was found."
@@ -14808,10 +15041,10 @@ msgstr ""
msgid "Failed to find import label for Jira import."
msgstr ""
-msgid "Failed to generate export, please try again later."
+msgid "Failed to find users for %{missing}"
msgstr ""
-msgid "Failed to generate report, please try again after sometime"
+msgid "Failed to generate export, please try again later."
msgstr ""
msgid "Failed to get ref."
@@ -14910,6 +15143,9 @@ msgstr ""
msgid "Failed to remove a to-do item for the design."
msgstr ""
+msgid "Failed to remove attention because no user was found."
+msgstr ""
+
msgid "Failed to remove mirror."
msgstr ""
@@ -14922,6 +15158,9 @@ msgstr ""
msgid "Failed to remove user key."
msgstr ""
+msgid "Failed to request attention because no user was found."
+msgstr ""
+
msgid "Failed to reset key. Please try again."
msgstr ""
@@ -15003,6 +15242,9 @@ msgstr ""
msgid "Feature Flags"
msgstr ""
+msgid "Feature deprecation and removal"
+msgstr ""
+
msgid "Feature flag status"
msgstr ""
@@ -15500,7 +15742,7 @@ msgstr ""
msgid "For each job, re-use the project workspace. If the workspace doesn't exist, use %{code_open}git clone%{code_close}."
msgstr ""
-msgid "For example, the application using the token or the purpose of the token."
+msgid "For example, the application using the token or the purpose of the token. Do not give sensitive information for the name of the token, as it will be visible to all %{resource_type} members."
msgstr ""
msgid "For files larger than this limit, only index the file name. The file content is neither indexed nor searchable."
@@ -15584,9 +15826,6 @@ msgstr ""
msgid "ForkProject|Select a namespace"
msgstr ""
-msgid "ForkProject|Select a namespace to fork the project"
-msgstr ""
-
msgid "ForkProject|The project can be accessed by any logged in user."
msgstr ""
@@ -15683,6 +15922,9 @@ msgstr ""
msgid "Full name"
msgstr ""
+msgid "GCP region configured"
+msgstr ""
+
msgid "GPG Key ID:"
msgstr ""
@@ -15863,6 +16105,9 @@ msgstr ""
msgid "Geo|Failed"
msgstr ""
+msgid "Geo|Filter Geo sites"
+msgstr ""
+
msgid "Geo|Filter by name"
msgstr ""
@@ -16274,6 +16519,12 @@ msgstr ""
msgid "GitLab Issue"
msgstr ""
+msgid "GitLab KAS"
+msgstr ""
+
+msgid "GitLab Memberships CSV Export"
+msgstr ""
+
msgid "GitLab Pages"
msgstr ""
@@ -16322,6 +16573,9 @@ 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 free to use. Many features for larger teams are part of our %{link_start}paid products%{link_end}. You can try Ultimate for free without any obligation or payment details."
+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 ""
@@ -16448,7 +16702,7 @@ msgstr ""
msgid "GitLabPages|When enabled, all attempts to visit your website through HTTP are automatically redirected to HTTPS using a response with status code 301. Requires a valid certificate for all domains. %{docs_link_start}Learn more.%{link_end}"
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. %{docs_link_start}Learn more.%{link_end}"
+msgid "GitLabPages|When using Pages under the general domain of a GitLab instance (%{pages_host}), you cannot use HTTPS with subdomains of subdomains. If your namespace or groupname contains a dot, it does not work. This is a limitation of the HTTP Over TLS protocol. HTTP pages work if you don't redirect HTTP to HTTPS. %{docs_link_start}Learn more.%{link_end}"
msgstr ""
msgid "GitLabPages|With GitLab Pages you can host your static website directly from your GitLab repository. %{docs_link_start}Learn more.%{link_end}"
@@ -16625,9 +16879,6 @@ msgstr ""
msgid "Go to find file"
msgstr ""
-msgid "Go to fork"
-msgstr ""
-
msgid "Go to issue boards"
msgstr ""
@@ -16835,9 +17086,6 @@ msgstr ""
msgid "Group Hooks"
msgstr ""
-msgid "Group ID"
-msgstr ""
-
msgid "Group Owner must have signed in with SAML before enabling Group Managed Accounts"
msgstr ""
@@ -16865,9 +17113,6 @@ msgstr "Gruppavatar"
msgid "Group by"
msgstr ""
-msgid "Group description"
-msgstr ""
-
msgid "Group description (optional)"
msgstr ""
@@ -16982,7 +17227,7 @@ msgstr ""
msgid "Group: %{name}"
msgstr ""
-msgid "GroupActivityMetrics|Issues opened"
+msgid "GroupActivityMetrics|Issues created"
msgstr ""
msgid "GroupActivityMetrics|Last 90 days"
@@ -16991,7 +17236,7 @@ msgstr ""
msgid "GroupActivityMetrics|Members added"
msgstr ""
-msgid "GroupActivityMetrics|Merge Requests opened"
+msgid "GroupActivityMetrics|Merge Requests created"
msgstr ""
msgid "GroupActivityMetrics|Recent activity"
@@ -17282,6 +17527,9 @@ msgstr ""
msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
+msgid "GroupSettings|Choose a group path that does not start with a dash or end with a period. It can also contain alphanumeric characters and underscores."
+msgstr ""
+
msgid "GroupSettings|Compliance frameworks"
msgstr ""
@@ -17315,7 +17563,7 @@ msgstr ""
msgid "GroupSettings|If not specified at the group or instance level, the default is %{default_initial_branch_name}. Does not affect existing repositories."
msgstr ""
-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."
+msgid "GroupSettings|If the parent group's visibility is lower than the group's current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility."
msgstr ""
msgid "GroupSettings|New runners registration token has been generated!"
@@ -17432,7 +17680,10 @@ msgstr ""
msgid "Groups and projects"
msgstr ""
-msgid "Groups and subgroups"
+msgid "Groups are a great way to organize projects and people."
+msgstr ""
+
+msgid "Groups are the best way to manage projects and members."
msgstr ""
msgid "Groups to synchronize"
@@ -17543,13 +17794,16 @@ msgstr ""
msgid "GroupsTree|Are you sure you want to leave the \"%{fullName}\" group?"
msgstr ""
-msgid "GroupsTree|Edit group"
+msgid "GroupsTree|Delete"
+msgstr ""
+
+msgid "GroupsTree|Edit"
msgstr ""
msgid "GroupsTree|Failed to leave the group. Please make sure you are not the only owner."
msgstr ""
-msgid "GroupsTree|Leave this group"
+msgid "GroupsTree|Leave group"
msgstr ""
msgid "GroupsTree|Loading groups"
@@ -17561,9 +17815,57 @@ msgstr ""
msgid "GroupsTree|No groups or projects matched your search"
msgstr ""
+msgid "GroupsTree|Options"
+msgstr ""
+
msgid "GroupsTree|Search by name"
msgstr ""
+msgid "Groups|Avatar will be removed. Are you sure?"
+msgstr ""
+
+msgid "Groups|Changing group URL can have unintended side effects."
+msgstr ""
+
+msgid "Groups|Checking group URL availability..."
+msgstr ""
+
+msgid "Groups|Enter a descriptive name for your group."
+msgstr ""
+
+msgid "Groups|Group ID"
+msgstr ""
+
+msgid "Groups|Group URL"
+msgstr ""
+
+msgid "Groups|Group avatar"
+msgstr ""
+
+msgid "Groups|Group description (optional)"
+msgstr ""
+
+msgid "Groups|Group name"
+msgstr ""
+
+msgid "Groups|Group path is available."
+msgstr ""
+
+msgid "Groups|Group path is unavailable. Path has been replaced with a suggested available path."
+msgstr ""
+
+msgid "Groups|Learn more"
+msgstr ""
+
+msgid "Groups|Must start with letter, digit, emoji, or underscore. Can also contain periods, dashes, spaces, and parentheses."
+msgstr ""
+
+msgid "Groups|Remove avatar"
+msgstr ""
+
+msgid "Groups|Save changes"
+msgstr ""
+
msgid "Guideline"
msgstr ""
@@ -17573,6 +17875,9 @@ msgstr ""
msgid "HAR file path or URL"
msgstr ""
+msgid "HTTP Archive (HAR)"
+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 ""
@@ -17973,6 +18278,9 @@ msgstr ""
msgid "INFO: Your SSH key is expiring soon. Please generate a new key."
msgstr ""
+msgid "IP"
+msgstr ""
+
msgid "IP Address"
msgstr ""
@@ -18009,6 +18317,9 @@ msgstr ""
msgid "IdentityVerification|Verify your identity"
msgstr ""
+msgid "IdentityVerification|You can always verify your account at a later time to create a group."
+msgstr ""
+
msgid "If any indexed field exceeds this limit, it is truncated to this number of characters. The rest of the content is neither indexed nor searchable. This does not apply to repository and wiki indexing. For unlimited characters, set this to 0."
msgstr ""
@@ -18066,6 +18377,9 @@ msgstr ""
msgid "If you add %{codeStart}needs%{codeEnd} to jobs in your pipeline you'll be able to view the %{codeStart}needs%{codeEnd} relationships between jobs in this tab as a %{linkStart}Directed Acyclic Graph (DAG)%{linkEnd}."
msgstr ""
+msgid "If you are added to a project, it will be displayed here."
+msgstr ""
+
msgid "If you did not initiate these sign-in attempts, please reach out to your administrator or enable two-factor authentication (2FA) on your account."
msgstr ""
@@ -18372,12 +18686,24 @@ msgstr ""
msgid "InProductMarketing|3 ways to dive into GitLab CI/CD"
msgstr ""
+msgid "InProductMarketing|A single application eliminates complex integrations, data chokepoints, and toolchain maintenance, resulting in greater productivity and lower cost."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features, build more efficiently, strengthen security and compliance."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features."
+msgstr ""
+
msgid "InProductMarketing|Actually, GitLab makes the team work (better)"
msgstr ""
msgid "InProductMarketing|And finally %{deploy_link} a Python application."
msgstr ""
+msgid "InProductMarketing|And many more..."
+msgstr ""
+
msgid "InProductMarketing|Are your runners ready?"
msgstr ""
@@ -18396,15 +18722,33 @@ msgstr ""
msgid "InProductMarketing|Blog"
msgstr ""
+msgid "InProductMarketing|Break down silos to coordinate seamlessly across development, operations, and security with a consistent experience across the development lifecycle."
+msgstr ""
+
+msgid "InProductMarketing|Burn up/down charts"
+msgstr ""
+
msgid "InProductMarketing|By enabling code owners and required merge approvals the right person will review the right MR. This is a win-win: cleaner code and a more efficient review process."
msgstr ""
msgid "InProductMarketing|Click on the number below that corresponds with your answer — 1 being very difficult, 5 being very easy."
msgstr ""
+msgid "InProductMarketing|Code owners"
+msgstr ""
+
msgid "InProductMarketing|Code owners and required merge approvals are part of the paid tiers of GitLab. You can start a free 30-day trial of GitLab Ultimate and enable these features in less than 5 minutes with no credit card required."
msgstr ""
+msgid "InProductMarketing|Code review analytics"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration across stages in GitLab"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration made easy"
+msgstr ""
+
msgid "InProductMarketing|Create a custom CI runner with just a few clicks"
msgstr ""
@@ -18414,12 +18758,21 @@ msgstr ""
msgid "InProductMarketing|Create a project in GitLab in 5 minutes"
msgstr ""
+msgid "InProductMarketing|Create well-defined workflows by using scoped labels on issues, merge requests, and epics. Labels with the same scope cannot be used together, which prevents conflicts."
+msgstr ""
+
msgid "InProductMarketing|Create your first project!"
msgstr ""
+msgid "InProductMarketing|Define who owns specific files or directories, so the right reviewers are suggested when a merge request introduces changes to those files."
+msgstr ""
+
msgid "InProductMarketing|Deliver Better Products Faster"
msgstr ""
+msgid "InProductMarketing|Dependency scanning"
+msgstr ""
+
msgid "InProductMarketing|Did you know teams that use GitLab are far more efficient?"
msgstr ""
@@ -18429,15 +18782,27 @@ msgstr ""
msgid "InProductMarketing|Dig in and create a project and a repo"
msgstr ""
+msgid "InProductMarketing|Discover Premium & Ultimate"
+msgstr ""
+
+msgid "InProductMarketing|Discover Premium & Ultimate."
+msgstr ""
+
msgid "InProductMarketing|Do you have a minute?"
msgstr ""
msgid "InProductMarketing|Do you have a teammate who would be perfect for this task?"
msgstr ""
+msgid "InProductMarketing|Dynamic application security testing"
+msgstr ""
+
msgid "InProductMarketing|Easy"
msgstr ""
+msgid "InProductMarketing|Epics"
+msgstr ""
+
msgid "InProductMarketing|Expand your DevOps journey with a free GitLab trial"
msgstr ""
@@ -18459,9 +18824,15 @@ msgstr ""
msgid "InProductMarketing|Feel the need for speed?"
msgstr ""
+msgid "InProductMarketing|Find and fix bottlenecks in your code review process by understanding how long open merge requests have been in review."
+msgstr ""
+
msgid "InProductMarketing|Find out how your teams are really doing"
msgstr ""
+msgid "InProductMarketing|Find out if your external libraries are safe. Run dependency scanning jobs that check for known vulnerabilities in your external libraries."
+msgstr ""
+
msgid "InProductMarketing|Follow our steps"
msgstr ""
@@ -18498,6 +18869,9 @@ msgstr ""
msgid "InProductMarketing|GitLab is better with teammates to help out!"
msgstr ""
+msgid "InProductMarketing|GitLab is infrastructure agnostic (supporting GCP, AWS, Azure, OpenShift, VMWare, On Prem, Bare Metal, and more), offering a consistent workflow experience – irrespective of the environment."
+msgstr ""
+
msgid "InProductMarketing|GitLab provides static application security testing (SAST), dynamic application security testing (DAST), container scanning, and dependency scanning to help you deliver secure applications along with license compliance."
msgstr ""
@@ -18588,21 +18962,36 @@ msgstr ""
msgid "InProductMarketing|It's also possible to simply %{external_repo_link} in order to take advantage of GitLab's CI/CD."
msgstr ""
+msgid "InProductMarketing|Keep your code quality high by defining who should approve merge requests and how many approvals are required."
+msgstr ""
+
msgid "InProductMarketing|Launch GitLab CI/CD in 20 minutes or less"
msgstr ""
+msgid "InProductMarketing|Lower cost of development"
+msgstr ""
+
+msgid "InProductMarketing|Make it easier to collaborate on high-level ideas by grouping related issues in an epic."
+msgstr ""
+
msgid "InProductMarketing|Making the switch? It's easier than you think to import your projects into GitLab. Move %{github_link}, or import something %{bitbucket_link}."
msgstr ""
msgid "InProductMarketing|Master the art of importing!"
msgstr ""
+msgid "InProductMarketing|Merge request approval rule"
+msgstr ""
+
msgid "InProductMarketing|Move on to easily creating a Pages website %{ci_template_link}"
msgstr ""
msgid "InProductMarketing|Multiple owners, confusing workstreams? We've got you covered"
msgstr ""
+msgid "InProductMarketing|Multiple required approvers"
+msgstr ""
+
msgid "InProductMarketing|Need an alternative to importing?"
msgstr ""
@@ -18615,18 +19004,33 @@ msgstr ""
msgid "InProductMarketing|Our tool brings all the things together"
msgstr ""
+msgid "InProductMarketing|Protect your web application by using DAST to examine for vulnerabilities in deployed environments."
+msgstr ""
+
msgid "InProductMarketing|Rapid development, simplified"
msgstr ""
msgid "InProductMarketing|Reduce Security & Compliance Risk"
msgstr ""
+msgid "InProductMarketing|Require multiple approvers on a merge request, so you know it's in good shape before it's merged."
+msgstr ""
+
+msgid "InProductMarketing|Roadmaps"
+msgstr ""
+
+msgid "InProductMarketing|Scoped labels"
+msgstr ""
+
msgid "InProductMarketing|Security that's integrated into your development lifecycle"
msgstr ""
msgid "InProductMarketing|Sometimes you're not ready to make a full transition to a new tool. If you're not ready to fully commit, %{mirroring_link} gives you a safe way to try out GitLab in parallel with your current tool."
msgstr ""
+msgid "InProductMarketing|Speed. Efficiency. Trust."
+msgstr ""
+
msgid "InProductMarketing|Spin up an autoscaling runner in GitLab"
msgstr ""
@@ -18636,6 +19040,9 @@ msgstr ""
msgid "InProductMarketing|Start a Self-Managed trial"
msgstr ""
+msgid "InProductMarketing|Start a free trial"
+msgstr ""
+
msgid "InProductMarketing|Start a free trial of GitLab Ultimate – no credit card required"
msgstr ""
@@ -18702,6 +19109,9 @@ msgstr ""
msgid "InProductMarketing|To understand and get the most out of GitLab, start at the beginning and %{project_link}. In GitLab, repositories are part of a project, so after you've created your project you can go ahead and %{repo_link}."
msgstr ""
+msgid "InProductMarketing|Track completed issues in a chart, so you can see how a milestone is progressing at a glance."
+msgstr ""
+
msgid "InProductMarketing|Try GitLab Ultimate for free"
msgstr ""
@@ -18738,6 +19148,9 @@ msgstr ""
msgid "InProductMarketing|Very easy"
msgstr ""
+msgid "InProductMarketing|Visualize your epics and milestones in a timeline."
+msgstr ""
+
msgid "InProductMarketing|Want to host GitLab on your servers?"
msgstr ""
@@ -18759,6 +19172,9 @@ msgstr ""
msgid "InProductMarketing|YouTube"
msgstr ""
+msgid "InProductMarketing|Your software, deployed your way"
+msgstr ""
+
msgid "InProductMarketing|Your teams can be more efficient"
msgstr ""
@@ -18879,9 +19295,18 @@ msgstr ""
msgid "IncidentManagement|No incidents to display."
msgstr ""
+msgid "IncidentManagement|None"
+msgstr ""
+
msgid "IncidentManagement|Open"
msgstr ""
+msgid "IncidentManagement|Page your team with escalation policies"
+msgstr ""
+
+msgid "IncidentManagement|Paged"
+msgstr ""
+
msgid "IncidentManagement|Published"
msgstr ""
@@ -18891,6 +19316,9 @@ msgstr ""
msgid "IncidentManagement|Severity"
msgstr ""
+msgid "IncidentManagement|Status"
+msgstr ""
+
msgid "IncidentManagement|There are no closed incidents"
msgstr ""
@@ -18909,6 +19337,9 @@ msgstr ""
msgid "IncidentManagement|Unpublished"
msgstr ""
+msgid "IncidentManagement|Use escalation policies to automatically page your team when incidents are created."
+msgstr ""
+
msgid "IncidentSettings|Activate \"time to SLA\" countdown timer"
msgstr ""
@@ -18954,7 +19385,10 @@ msgstr ""
msgid "Incidents"
msgstr ""
-msgid "Incidents|Add a URL"
+msgid "Incidents|Add image details"
+msgstr ""
+
+msgid "Incidents|Add text or a link to display with your image. If you don't add either, the file name displays instead."
msgstr ""
msgid "Incidents|Drop or %{linkStart}upload%{linkEnd} a metric screenshot to attach it to the incident"
@@ -18969,10 +19403,10 @@ msgstr ""
msgid "Incidents|There was an issue loading metric images."
msgstr ""
-msgid "Incidents|There was an issue uploading your image."
+msgid "Incidents|There was an issue updating your image."
msgstr ""
-msgid "Incidents|You can optionally add a URL to link users to the original graph."
+msgid "Incidents|There was an issue uploading your image."
msgstr ""
msgid "Incident|Alert details"
@@ -18981,9 +19415,18 @@ msgstr ""
msgid "Incident|Are you sure you wish to delete this image?"
msgstr ""
+msgid "Incident|Delete image"
+msgstr ""
+
msgid "Incident|Deleting %{filename}"
msgstr ""
+msgid "Incident|Edit image text or link"
+msgstr ""
+
+msgid "Incident|Editing %{filename}"
+msgstr ""
+
msgid "Incident|Metrics"
msgstr ""
@@ -19253,12 +19696,18 @@ msgstr ""
msgid "Integrations|Branches for which notifications are to be sent"
msgstr ""
+msgid "Integrations|Clear if using a self-signed certificate."
+msgstr ""
+
msgid "Integrations|Comment detail:"
msgstr ""
msgid "Integrations|Comment settings:"
msgstr ""
+msgid "Integrations|Connection details"
+msgstr ""
+
msgid "Integrations|Connection failed. Please check your settings."
msgstr ""
@@ -19283,6 +19732,9 @@ msgstr ""
msgid "Integrations|Enable GitLab.com slash commands in a Slack workspace."
msgstr ""
+msgid "Integrations|Enable SSL verification"
+msgstr ""
+
msgid "Integrations|Enable comments"
msgstr ""
@@ -19361,6 +19813,9 @@ msgstr ""
msgid "Integrations|Return to GitLab for Jira"
msgstr ""
+msgid "Integrations|SSL verification"
+msgstr ""
+
msgid "Integrations|Save settings?"
msgstr ""
@@ -19406,9 +19861,6 @@ msgstr ""
msgid "Integrations|Use default settings"
msgstr ""
-msgid "Integrations|When you mention a Jira issue in a commit or merge request, GitLab creates a remote link and comment (if enabled)."
-msgstr ""
-
msgid "Integrations|You can now close this window and return to the GitLab for Jira application."
msgstr ""
@@ -19433,9 +19885,6 @@ msgstr ""
msgid "Integrations|can't exceed %{recipients_limit}"
msgstr ""
-msgid "Interactive developer security education."
-msgstr ""
-
msgid "Interactive mode"
msgstr ""
@@ -19925,6 +20374,9 @@ msgstr ""
msgid "IssueAnalytics|Assignees"
msgstr ""
+msgid "IssueAnalytics|Created by"
+msgstr ""
+
msgid "IssueAnalytics|Due date"
msgstr ""
@@ -19937,9 +20389,6 @@ msgstr ""
msgid "IssueAnalytics|Milestone"
msgstr ""
-msgid "IssueAnalytics|Opened by"
-msgstr ""
-
msgid "IssueAnalytics|Status"
msgstr ""
@@ -20063,10 +20512,10 @@ msgstr ""
msgid "IssuesAnalytics|Avg/Month:"
msgstr ""
-msgid "IssuesAnalytics|Issues opened"
+msgid "IssuesAnalytics|Issues created"
msgstr ""
-msgid "IssuesAnalytics|Issues opened per month"
+msgid "IssuesAnalytics|Issues created per month"
msgstr ""
msgid "IssuesAnalytics|Last 12 months"
@@ -20093,6 +20542,9 @@ msgstr ""
msgid "It looks like you have some draft commits in this branch."
msgstr ""
+msgid "It looks like you're attempting to activate your subscription. Use %{a_start}the Subscription page%{a_end} instead."
+msgstr ""
+
msgid "It may be several days before you see feature usage data."
msgstr ""
@@ -20321,6 +20773,9 @@ msgstr ""
msgid "JiraConnect|You can now close this window and return to Jira."
msgstr ""
+msgid "JiraConnect|You don't have permission to create branches for this project. Select a different project or contact the project owner for access. %{linkStart}Learn more.%{linkEnd}"
+msgstr ""
+
msgid "JiraRequest|A connection error occurred while connecting to Jira. Try your request again."
msgstr ""
@@ -20369,13 +20824,13 @@ msgstr ""
msgid "JiraService|Define the type of Jira issue to create from a vulnerability."
msgstr ""
-msgid "JiraService|Displaying Jira issues while leaving the GitLab issue functionality enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
+msgid "JiraService|Displaying Jira issues while leaving GitLab issues also enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
msgstr ""
-msgid "JiraService|Enable Jira issues"
+msgid "JiraService|Enable Jira issue creation from vulnerabilities"
msgstr ""
-msgid "JiraService|Enable Jira issues creation from vulnerabilities"
+msgid "JiraService|Enable Jira issues"
msgstr ""
msgid "JiraService|Enable Jira transitions"
@@ -20492,16 +20947,19 @@ msgstr ""
msgid "JiraService|View Jira issues in GitLab"
msgstr ""
-msgid "JiraService|Warning: All GitLab users that have access to this GitLab project are able to view all issues from the Jira project specified below."
+msgid "JiraService|Warning: All GitLab users with access to this GitLab project can view all issues from the Jira project you select."
msgstr ""
msgid "JiraService|Web URL"
msgstr ""
-msgid "JiraService|Work on Jira issues without leaving GitLab. Adds a Jira menu to access your list of Jira issues and view any issue as read-only."
+msgid "JiraService|When a Jira issue is mentioned in a commit or merge request, a remote link and comment (if enabled) will be created."
+msgstr ""
+
+msgid "JiraService|Work on Jira issues without leaving GitLab. Add a Jira menu to access a read-only list of your Jira issues."
msgstr ""
-msgid "JiraService|You need to configure Jira before enabling this integration. For more details, read the %{jira_doc_link_start}Jira integration documentation%{link_end}."
+msgid "JiraService|You must configure Jira before enabling this integration. %{jira_doc_link_start}Learn more.%{link_end}"
msgstr ""
msgid "Job"
@@ -20513,9 +20971,6 @@ msgstr ""
msgid "Job Failed #%{build_id}"
msgstr ""
-msgid "Job ID"
-msgstr ""
-
msgid "Job artifact"
msgstr ""
@@ -20582,9 +21037,27 @@ msgstr ""
msgid "Jobs|You're about to retry a job that failed because it attempted to deploy code that is older than the latest deployment. Retrying this job could result in overwriting the environment with the older source code."
msgstr ""
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source} into %{target}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{ref}"
+msgstr ""
+
+msgid "Job|Are you sure you want to erase this job log and artifacts?"
+msgstr ""
+
msgid "Job|Browse"
msgstr ""
+msgid "Job|Cancel"
+msgstr ""
+
msgid "Job|Complete Raw"
msgstr ""
@@ -20594,6 +21067,9 @@ msgstr ""
msgid "Job|Erase job log and artifacts"
msgstr ""
+msgid "Job|Finished at"
+msgstr ""
+
msgid "Job|Job artifacts"
msgstr ""
@@ -20606,7 +21082,7 @@ msgstr ""
msgid "Job|Keep"
msgstr ""
-msgid "Job|Pipeline"
+msgid "Job|Retry"
msgstr ""
msgid "Job|Scroll to bottom"
@@ -20618,6 +21094,9 @@ msgstr ""
msgid "Job|Show complete raw"
msgstr ""
+msgid "Job|Status"
+msgstr ""
+
msgid "Job|The artifacts were removed"
msgstr ""
@@ -20645,21 +21124,12 @@ msgstr ""
msgid "Job|delayed"
msgstr ""
-msgid "Job|for"
-msgstr ""
-
-msgid "Job|into"
-msgstr ""
-
msgid "Job|manual"
msgstr ""
msgid "Job|triggered"
msgstr ""
-msgid "Job|with"
-msgstr ""
-
msgid "Join Zoom meeting"
msgstr ""
@@ -20762,9 +21232,6 @@ msgstr ""
msgid "Ki"
msgstr ""
-msgid "Kontra"
-msgstr ""
-
msgid "Kroki"
msgstr ""
@@ -21088,6 +21555,9 @@ msgstr ""
msgid "Learn more about Auto DevOps"
msgstr ""
+msgid "Learn more about GitLab"
+msgstr ""
+
msgid "Learn more about Needs relationships"
msgstr ""
@@ -21415,9 +21885,18 @@ msgstr ""
msgid "Licenses|Displays licenses detected in the project, based on the %{linkStart}latest successful%{linkEnd} scan"
msgstr ""
+msgid "Licenses|Drag your license file here or %{linkStart}click to upload%{linkEnd}."
+msgstr ""
+
+msgid "Licenses|Drop your license file to start the upload."
+msgstr ""
+
msgid "Licenses|Error fetching the license list. Please check your network connection and try again."
msgstr ""
+msgid "Licenses|Error: You are trying to upload something other than a file"
+msgstr ""
+
msgid "Licenses|License Compliance"
msgstr ""
@@ -21436,6 +21915,9 @@ msgstr ""
msgid "Licenses|Specified policies in this project"
msgstr ""
+msgid "Licenses|The file could not be uploaded."
+msgstr ""
+
msgid "Licenses|The license list details information about the licenses used within your project."
msgstr ""
@@ -21469,11 +21951,6 @@ msgstr ""
msgid "Limit the size of Sidekiq jobs stored in Redis."
msgstr ""
-msgid "Limited to showing %d event at most"
-msgid_plural "Limited to showing %d events at most"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Limiting mode"
msgstr ""
@@ -21483,6 +21960,9 @@ msgstr ""
msgid "Link"
msgstr ""
+msgid "Link (optional)"
+msgstr ""
+
msgid "Link Prometheus monitoring to GitLab."
msgstr ""
@@ -21519,6 +21999,9 @@ msgstr ""
msgid "Linked emails (%{email_count})"
msgstr ""
+msgid "Linked epics"
+msgstr ""
+
msgid "Linked issues"
msgstr ""
@@ -21546,6 +22029,15 @@ msgstr ""
msgid "List of all merge commits"
msgstr ""
+msgid "List of environments for this project"
+msgstr ""
+
+msgid "List of suitable GCP locations"
+msgstr ""
+
+msgid "List of users allowed to exceed the rate limit."
+msgstr ""
+
msgid "List options"
msgstr ""
@@ -21765,6 +22257,9 @@ msgstr ""
msgid "Maintenance mode"
msgstr ""
+msgid "Make adjustments to how your GitLab instance is set up."
+msgstr ""
+
msgid "Make and review changes in the browser with the Web IDE"
msgstr ""
@@ -21909,6 +22404,12 @@ msgstr ""
msgid "MarkdownEditor|Add italic text (%{modifier_key}I)"
msgstr ""
+msgid "MarkdownEditor|Add strikethrough text (%{modifierKey}⇧X)"
+msgstr ""
+
+msgid "MarkdownEditor|Add strikethrough text (%{modifier_key}⇧X)"
+msgstr ""
+
msgid "Marked For Deletion At - %{deletion_time}"
msgstr ""
@@ -22170,6 +22671,9 @@ msgstr ""
msgid "Maximum push size (MB)"
msgstr ""
+msgid "Maximum requests per 10 minutes per user"
+msgstr ""
+
msgid "Maximum requests per minute"
msgstr ""
@@ -22260,6 +22764,19 @@ msgstr ""
msgid "Members of a group may only view projects they have permission to access"
msgstr ""
+msgid "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seat in use and will be billed for the overage."
+msgid_plural "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seats in use and will be billed for the overage."
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "MembersOverage|You are about to incur additional charges"
+msgstr ""
+
+msgid "MembersOverage|Your subscription includes %d seat."
+msgid_plural "MembersOverage|Your subscription includes %d seats."
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Membership"
msgstr ""
@@ -22464,9 +22981,6 @@ msgstr ""
msgid "Merge request not merged"
msgstr ""
-msgid "Merge request pipelines 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 merge request pipelines."
-msgstr ""
-
msgid "Merge request reports"
msgstr ""
@@ -22563,13 +23077,13 @@ msgstr ""
msgid "MergeRequests|Create issue to resolve thread"
msgstr ""
-msgid "MergeRequests|Failed to squash. Should be done manually."
+msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Saving the comment failed"
+msgid "MergeRequests|Squashing failed: Squash the commits locally, resolve any conflicts, then push the branch."
msgstr ""
-msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
+msgid "MergeRequests|Squashing not allowed: This project doesn't allow you to squash commits when merging."
msgstr ""
msgid "MergeRequests|Thread stays resolved"
@@ -23410,6 +23924,18 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "MrList|Assigned to %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from assignee %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from reviewer %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Review requested from %{name}, go to their profile."
+msgstr ""
+
msgid "Multi-project"
msgstr ""
@@ -23443,7 +23969,7 @@ msgstr ""
msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "My Awesome Group"
+msgid "My awesome group"
msgstr ""
msgid "My company or team"
@@ -24065,9 +24591,6 @@ msgstr ""
msgid "No available branches"
msgstr ""
-msgid "No available groups to fork the project."
-msgstr ""
-
msgid "No branches found"
msgstr ""
@@ -24278,6 +24801,9 @@ msgstr ""
msgid "No ref selected"
msgstr ""
+msgid "No regions configured"
+msgstr ""
+
msgid "No related merge requests found."
msgstr ""
@@ -25082,6 +25608,9 @@ msgstr ""
msgid "Only reCAPTCHA v2 is supported:"
msgstr ""
+msgid "Only required if not using role instance credentials."
+msgstr ""
+
msgid "Only use lowercase letters, numbers, and underscores."
msgstr ""
@@ -25106,9 +25635,6 @@ msgstr ""
msgid "Open a CLI and connect to the cluster you want to install the agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
-msgid "Open epics"
-msgstr ""
-
msgid "Open errors"
msgstr ""
@@ -25148,7 +25674,7 @@ msgstr ""
msgid "Opened issues"
msgstr ""
-msgid "OpenedNDaysAgo|Opened"
+msgid "OpenedNDaysAgo|Created"
msgstr ""
msgid "Opens in a new window"
@@ -25193,9 +25719,6 @@ msgstr ""
msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
-msgid "Optional."
-msgstr ""
-
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
msgstr ""
@@ -25984,6 +26507,9 @@ msgstr ""
msgid "PerformanceBar|Memory"
msgstr ""
+msgid "PerformanceBar|Memory report"
+msgstr ""
+
msgid "PerformanceBar|Redis calls"
msgstr ""
@@ -26017,18 +26543,12 @@ msgstr ""
msgid "PerformanceBar|wall"
msgstr ""
-msgid "Performs a rebase but skips triggering a new pipeline"
-msgstr ""
-
msgid "Period in seconds"
msgstr ""
msgid "Permalink"
msgstr ""
-msgid "Permanently delete project"
-msgstr ""
-
msgid "Permanently remove group"
msgstr ""
@@ -26299,6 +26819,51 @@ msgstr ""
msgid "PipelineStatusTooltip|Pipeline: %{ci_status}"
msgstr ""
+msgid "PipelineWizardDefaultCommitMessage|Add %{filename}"
+msgstr ""
+
+msgid "PipelineWizardDefaultCommitMessage|Update %{filename}"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|At least one entry is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This field is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This value is not valid"
+msgstr ""
+
+msgid "PipelineWizardListWidget|add another step"
+msgstr ""
+
+msgid "PipelineWizardListWidget|remove step"
+msgstr ""
+
+msgid "PipelineWizard|Commit"
+msgstr ""
+
+msgid "PipelineWizard|Commit Message"
+msgstr ""
+
+msgid "PipelineWizard|Commit changes to your file"
+msgstr ""
+
+msgid "PipelineWizard|Commit file to Branch"
+msgstr ""
+
+msgid "PipelineWizard|Commit your new file"
+msgstr ""
+
+msgid "PipelineWizard|The file has been committed."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem committing the changes."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem while checking whether your file already exists in the specified branch."
+msgstr ""
+
msgid "Pipelines"
msgstr ""
@@ -26413,7 +26978,7 @@ msgstr ""
msgid "Pipelines|Project cache successfully reset."
msgstr ""
-msgid "Pipelines|Revoke"
+msgid "Pipelines|Revoke trigger"
msgstr ""
msgid "Pipelines|Something went wrong while cleaning runners cache."
@@ -26458,6 +27023,12 @@ msgstr ""
msgid "Pipelines|This is a child pipeline within the parent pipeline"
msgstr ""
+msgid "Pipelines|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipelines|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipelines|This pipeline will run code originating from a forked project merge request. This means that the code can potentially have security considerations like exposing CI variables."
msgstr ""
@@ -26500,9 +27071,6 @@ msgstr ""
msgid "Pipelines|Your changes have been successfully committed. Now redirecting to the new merge request page."
msgstr ""
-msgid "Pipelines|detached"
-msgstr ""
-
msgid "Pipelines|error"
msgstr ""
@@ -26512,10 +27080,13 @@ msgstr ""
msgid "Pipelines|latest"
msgstr ""
-msgid "Pipelines|stuck"
+msgid "Pipelines|merge request"
msgstr ""
-msgid "Pipelines|train"
+msgid "Pipelines|merge train"
+msgstr ""
+
+msgid "Pipelines|stuck"
msgstr ""
msgid "Pipelines|yaml invalid"
@@ -26647,6 +27218,12 @@ msgstr ""
msgid "Pipeline|This change will not change the overall test coverage if merged."
msgstr ""
+msgid "Pipeline|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipeline|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipeline|Trigger author"
msgstr ""
@@ -26671,6 +27248,12 @@ msgstr ""
msgid "Pipeline|for"
msgstr ""
+msgid "Pipeline|merge request"
+msgstr ""
+
+msgid "Pipeline|merge train"
+msgstr ""
+
msgid "Pipeline|on"
msgstr ""
@@ -26809,9 +27392,6 @@ msgstr ""
msgid "Please enter a valid time interval"
msgstr ""
-msgid "Please enter or upload a valid license."
-msgstr ""
-
msgid "Please enter your current password."
msgstr ""
@@ -26920,9 +27500,6 @@ msgstr ""
msgid "Please type %{phrase_code} to proceed or close this modal to cancel."
msgstr ""
-msgid "Please type the following to confirm:"
-msgstr ""
-
msgid "Please use this form to report to the admin users who create spam issues, comments or behave inappropriately."
msgstr ""
@@ -26950,12 +27527,27 @@ msgstr ""
msgid "Policies"
msgstr ""
+msgid "Policy '%{escalation_policy_name}' does not exist."
+msgstr ""
+
msgid "Policy management project does have any policies in %{policy_path}"
msgstr ""
msgid "Policy project doesn't exist"
msgstr ""
+msgid "PolicyRuleMultiSelect|%{firstLabel} +%{numberOfAdditionalLabels} more"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|All %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select all"
+msgstr ""
+
msgid "Polling interval multiplier"
msgstr ""
@@ -27184,6 +27776,9 @@ msgstr ""
msgid "Private projects can be created in your personal namespace with:"
msgstr ""
+msgid "Problem with %{name} command: %{message}."
+msgstr ""
+
msgid "Proceed"
msgstr ""
@@ -27658,6 +28253,9 @@ msgstr ""
msgid "Progress"
msgstr ""
+msgid "Progress tracking"
+msgstr ""
+
msgid "Project"
msgstr ""
@@ -27889,6 +28487,9 @@ msgstr ""
msgid "ProjectQualitySummary|Failure"
msgstr ""
+msgid "ProjectQualitySummary|Get insight into the overall percentage of tests in your project that succeed, fail and are skipped."
+msgstr ""
+
msgid "ProjectQualitySummary|Latest pipeline results"
msgstr ""
@@ -27907,6 +28508,12 @@ msgstr ""
msgid "ProjectQualitySummary|See project Code Coverage Statistics"
msgstr ""
+msgid "ProjectQualitySummary|Set up test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|Set up test runs (opens in a new tab)"
+msgstr ""
+
msgid "ProjectQualitySummary|Skipped"
msgstr ""
@@ -28183,13 +28790,19 @@ msgstr ""
msgid "ProjectSettings|LFS objects from this repository are available to forks. %{linkStart}How do I remove them?%{linkEnd}"
msgstr ""
+msgid "ProjectSettings|Learn about commit history."
+msgstr ""
+
+msgid "ProjectSettings|Leave empty to use default template."
+msgstr ""
+
msgid "ProjectSettings|Manage who can see the project in the public access directory."
msgstr ""
msgid "ProjectSettings|Manages large files such as audio, video, and graphics files."
msgstr ""
-msgid "ProjectSettings|Maximum 500 characters."
+msgid "ProjectSettings|Maximum %{maxLength} characters."
msgstr ""
msgid "ProjectSettings|Merge checks"
@@ -28330,6 +28943,9 @@ msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
msgstr ""
+msgid "ProjectSettings|The default template will be applied on save."
+msgstr ""
+
msgid "ProjectSettings|These checks must pass before merge requests can be merged."
msgstr ""
@@ -28384,6 +29000,9 @@ msgstr ""
msgid "ProjectSettings|What are badges?"
msgstr ""
+msgid "ProjectSettings|What are merge trains?"
+msgstr ""
+
msgid "ProjectSettings|When merge request pipelines are enabled in the CI/CD configuration file, pipelines validate the combined results of the source and target branches. %{link_start}How to configure merge request pipelines?%{link_end}"
msgstr ""
@@ -28501,6 +29120,9 @@ msgstr ""
msgid "Projects are organized into groups"
msgstr ""
+msgid "Projects are where you store your code, access issues, wiki and other features of GitLab."
+msgstr ""
+
msgid "Projects contributed to"
msgstr ""
@@ -28516,12 +29138,6 @@ msgstr ""
msgid "Projects to index"
msgstr ""
-msgid "Projects will be permanently deleted after a %{waiting_period}-day waiting period."
-msgstr ""
-
-msgid "Projects will be permanently deleted immediately."
-msgstr ""
-
msgid "Projects with critical vulnerabilities"
msgstr ""
@@ -28606,6 +29222,9 @@ msgstr ""
msgid "ProjectsNew|Import project"
msgstr ""
+msgid "ProjectsNew|Include a Getting Started README"
+msgstr ""
+
msgid "ProjectsNew|Initialize repository with a README"
msgstr ""
@@ -28621,6 +29240,9 @@ msgstr ""
msgid "ProjectsNew|Project description %{tag_start}(optional)%{tag_end}"
msgstr ""
+msgid "ProjectsNew|Recommended if you're new to GitLab"
+msgstr ""
+
msgid "ProjectsNew|Run CI/CD for external repository"
msgstr ""
@@ -29038,6 +29660,9 @@ msgstr ""
msgid "ProtectedBranch|Unprotect"
msgstr ""
+msgid "ProtectedBranch|Unprotect branch"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
@@ -29065,6 +29690,9 @@ msgstr ""
msgid "ProtectedEnvironment|Protected Environment (%{protected_environments_count})"
msgstr ""
+msgid "ProtectedEnvironment|Required approvals"
+msgstr ""
+
msgid "ProtectedEnvironment|Select an environment"
msgstr ""
@@ -29086,10 +29714,13 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|Unprotect tag"
+msgstr ""
+
msgid "ProtectedTags|default"
msgstr ""
-msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
+msgid "ProtectedTag|By default, protected tags restrict who can modify the tag."
msgstr ""
msgid "ProtectedTag|Learn more."
@@ -29152,6 +29783,9 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Public projects are an easy way to allow everyone to have read-only access."
+msgstr ""
+
msgid "Publish to status page"
msgstr ""
@@ -29308,9 +29942,6 @@ msgstr ""
msgid "QualitySummary|Project quality"
msgstr ""
-msgid "Quarters"
-msgstr ""
-
msgid "Query"
msgstr ""
@@ -29395,6 +30026,9 @@ msgstr ""
msgid "Read more about project permissions %{help_link_open}here%{help_link_close}"
msgstr ""
+msgid "Read more about related epics"
+msgstr ""
+
msgid "Read more about related issues"
msgstr ""
@@ -29425,10 +30059,7 @@ msgstr ""
msgid "Rebase source branch on the target branch."
msgstr ""
-msgid "Rebase without CI"
-msgstr ""
-
-msgid "Rebases and triggers a pipeline"
+msgid "Rebase without pipeline"
msgstr ""
msgid "Recaptcha verified?"
@@ -29479,9 +30110,6 @@ msgstr ""
msgid "Reconfigure"
msgstr ""
-msgid "Recovering projects"
-msgstr ""
-
msgid "Recovery Codes"
msgstr ""
@@ -29541,6 +30169,12 @@ msgstr ""
msgid "Regex pattern"
msgstr ""
+msgid "Region"
+msgstr ""
+
+msgid "Regions"
+msgstr ""
+
msgid "Register"
msgstr ""
@@ -29771,9 +30405,6 @@ msgstr ""
msgid "Remove all or specific reviewer(s)"
msgstr ""
-msgid "Remove approver"
-msgstr ""
-
msgid "Remove approvers"
msgstr ""
@@ -29789,6 +30420,9 @@ msgstr ""
msgid "Remove attention request"
msgstr ""
+msgid "Remove attention request(s)"
+msgstr ""
+
msgid "Remove avatar"
msgstr ""
@@ -29927,6 +30561,9 @@ msgstr ""
msgid "Removed an issue from an epic."
msgstr ""
+msgid "Removed attention from %{users_sentence}."
+msgstr ""
+
msgid "Removed attention request from @%{username}"
msgstr ""
@@ -29978,6 +30615,9 @@ msgstr ""
msgid "Removes an issue from an epic."
msgstr ""
+msgid "Removes attention from %{users_sentence}."
+msgstr ""
+
msgid "Removes parent epic %{epic_ref}."
msgstr ""
@@ -30089,6 +30729,9 @@ msgstr ""
msgid "Report abuse to admin"
msgstr ""
+msgid "Report is generating and will be sent to your email address."
+msgstr ""
+
msgid "Reported %{timeAgo} by %{reportedBy}"
msgstr ""
@@ -30378,6 +31021,15 @@ msgstr ""
msgid "Request attention"
msgstr ""
+msgid "Request attention from %{users_sentence}."
+msgstr ""
+
+msgid "Request attention from assignee or reviewer"
+msgstr ""
+
+msgid "Request attention from assignee(s) or reviewer(s)"
+msgstr ""
+
msgid "Request attention to review"
msgstr ""
@@ -30402,6 +31054,9 @@ msgstr ""
msgid "Requested %{time_ago}"
msgstr ""
+msgid "Requested attention from %{users_sentence}."
+msgstr ""
+
msgid "Requested attention from @%{username}"
msgstr ""
@@ -30616,6 +31271,9 @@ msgstr ""
msgid "Restore project"
msgstr ""
+msgid "Restoring projects"
+msgstr ""
+
msgid "Restoring the group will prevent the group, its subgroups and projects from being removed on this date."
msgstr ""
@@ -30646,6 +31304,9 @@ msgstr ""
msgid "Retry"
msgstr ""
+msgid "Retry failed jobs"
+msgstr ""
+
msgid "Retry job"
msgstr ""
@@ -30693,9 +31354,6 @@ msgstr ""
msgid "Review changes"
msgstr ""
-msgid "Review requested from %{name}"
-msgstr ""
-
msgid "Review requests for you"
msgstr ""
@@ -30860,6 +31518,9 @@ msgstr ""
msgid "Runners|Assigned Group"
msgstr ""
+msgid "Runners|Assigned Projects (%{projectCount})"
+msgstr ""
+
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30929,6 +31590,9 @@ msgstr ""
msgid "Runners|Instance"
msgstr ""
+msgid "Runners|Jobs"
+msgstr ""
+
msgid "Runners|Last contact"
msgstr ""
@@ -31022,9 +31686,6 @@ msgstr ""
msgid "Runners|Runner %{name} was deleted"
msgstr ""
-msgid "Runners|Runner ID"
-msgstr ""
-
msgid "Runners|Runner assigned to project."
msgstr ""
@@ -31172,6 +31833,9 @@ msgstr ""
msgid "Runners|stale"
msgstr ""
+msgid "Runner|This runner has not run any jobs."
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -31286,6 +31950,24 @@ msgstr ""
msgid "Saving project."
msgstr ""
+msgid "ScanResultPolicy|%{ifLabelStart}if%{ifLabelEnd} %{scanners} scan in an open merge request targeting the %{branches} branch(es) finds %{vulnerabilitiesAllowed} or more %{severities} vulnerabilities that are %{vulnerabilityStates}"
+msgstr ""
+
+msgid "ScanResultPolicy|%{thenLabelStart}Then%{thenLabelEnd} Require approval from %{approvalsRequired} of the following approvers: %{approvers}"
+msgstr ""
+
+msgid "ScanResultPolicy|add an approver"
+msgstr ""
+
+msgid "ScanResultPolicy|scanners"
+msgstr ""
+
+msgid "ScanResultPolicy|severity levels"
+msgstr ""
+
+msgid "ScanResultPolicy|vulnerability states"
+msgstr ""
+
msgid "Scanner"
msgstr ""
@@ -31418,6 +32100,9 @@ msgstr ""
msgid "Search for a user"
msgstr ""
+msgid "Search for an emoji"
+msgstr ""
+
msgid "Search for projects, issues, etc."
msgstr ""
@@ -31605,18 +32290,12 @@ msgstr ""
msgid "Secret Detection"
msgstr ""
-msgid "Secret access key"
-msgstr ""
-
msgid "Secret token"
msgstr ""
msgid "Secure token that identifies an external storage request."
msgstr ""
-msgid "SecureCodeWarrior"
-msgstr ""
-
msgid "Security"
msgstr ""
@@ -31641,9 +32320,6 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "Security training with guide and learning pathways."
-msgstr ""
-
msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
@@ -31746,7 +32422,7 @@ msgstr ""
msgid "SecurityConfiguration|Manage corpus"
msgstr ""
-msgid "SecurityConfiguration|Manage corpus files used as mutation sources in coverage fuzzing."
+msgid "SecurityConfiguration|Manage corpus files used as seed inputs with coverage-guided fuzzing."
msgstr ""
msgid "SecurityConfiguration|Manage profiles for use by DAST scans."
@@ -31812,15 +32488,15 @@ msgstr ""
msgid "SecurityOrchestration|.yaml preview"
msgstr ""
-msgid "SecurityOrchestration|Action"
-msgstr ""
-
msgid "SecurityOrchestration|Actions"
msgstr ""
msgid "SecurityOrchestration|Add rule"
msgstr ""
+msgid "SecurityOrchestration|After dismissing the alert, the information will never be shown again."
+msgstr ""
+
msgid "SecurityOrchestration|All policies"
msgstr ""
@@ -31836,7 +32512,7 @@ msgstr ""
msgid "SecurityOrchestration|Description"
msgstr ""
-msgid "SecurityOrchestration|Disabled"
+msgid "SecurityOrchestration|Don't show the alert anymore"
msgstr ""
msgid "SecurityOrchestration|Edit policy"
@@ -31845,13 +32521,13 @@ msgstr ""
msgid "SecurityOrchestration|Edit policy project"
msgstr ""
-msgid "SecurityOrchestration|Enabled"
+msgid "SecurityOrchestration|Empty policy name"
msgstr ""
-msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Enabled"
msgstr ""
-msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
msgstr ""
msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
@@ -31860,7 +32536,7 @@ msgstr ""
msgid "SecurityOrchestration|Invalid policy type"
msgstr ""
-msgid "SecurityOrchestration|Latest scan"
+msgid "SecurityOrchestration|Latest scan run against %{agent}"
msgstr ""
msgid "SecurityOrchestration|Network"
@@ -31869,15 +32545,27 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No actions defined - policy will not run."
+msgstr ""
+
+msgid "SecurityOrchestration|No description"
+msgstr ""
+
msgid "SecurityOrchestration|No rules defined - policy will not run."
msgstr ""
+msgid "SecurityOrchestration|Not enabled"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
msgid "SecurityOrchestration|Policies"
msgstr ""
+msgid "SecurityOrchestration|Policy Type"
+msgstr ""
+
msgid "SecurityOrchestration|Policy cannot be enabled for non-existing branches (%{branches})"
msgstr ""
@@ -31902,10 +32590,13 @@ msgstr ""
msgid "SecurityOrchestration|Require %{approvals} %{plural} from %{approvers} if any of the following occur:"
msgstr ""
-msgid "SecurityOrchestration|Rule"
+msgid "SecurityOrchestration|Rules"
msgstr ""
-msgid "SecurityOrchestration|Rules"
+msgid "SecurityOrchestration|Runs %{actions} and %{lastAction} scans"
+msgstr ""
+
+msgid "SecurityOrchestration|Runs a %{action} scan"
msgstr ""
msgid "SecurityOrchestration|Scan Execution"
@@ -31965,6 +32656,9 @@ msgstr ""
msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
+msgid "SecurityOrchestration|This view only shows scan results for the agent %{agent}. You can view scan results for all agents in the %{linkStart}Operational Vulnerabilities tab of the vulnerability report%{linkEnd}."
+msgstr ""
+
msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
@@ -32019,9 +32713,6 @@ msgstr ""
msgid "SecurityOrchestration|users with ids"
msgstr ""
-msgid "SecurityOrchestration|view results"
-msgstr ""
-
msgid "SecurityOrchestration|vulnerabilities"
msgstr ""
@@ -32691,22 +33382,19 @@ 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|In order to start using functions as a service, you must first install Knative on your Kubernetes cluster. %{linkStart}More information%{linkEnd}"
-msgstr ""
-
msgid "Serverless|Learn more about Serverless"
msgstr ""
msgid "Serverless|No functions available"
msgstr ""
-msgid "Serverless|Sign up for First Look"
+msgid "Serverless|Serverless was %{linkStart}deprecated%{linkEnd} in GitLab 14.3."
+msgstr ""
+
+msgid "Serverless|Serverless was %{postLinkStart}deprecated%{postLinkEnd}. But if you opt to use it, you must install Knative in your Kubernetes cluster first. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "Serverless|The deploy job has not finished."
@@ -32718,9 +33406,6 @@ 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 ""
@@ -32736,9 +33421,6 @@ msgstr ""
msgid "Service Account Key"
msgstr ""
-msgid "Service Accounts"
-msgstr ""
-
msgid "Service Accounts keys authorize GitLab to deploy your Google Cloud project"
msgstr ""
@@ -32748,10 +33430,10 @@ msgstr ""
msgid "Service Desk allows people to create issues in your GitLab instance without their own user account. It provides a unique email address for end users to create issues in a project. Replies can be sent either through the GitLab interface or by email. End users only see threads through email."
msgstr ""
-msgid "Service Usage Data"
+msgid "Service account generated successfully"
msgstr ""
-msgid "Service account generated successfully"
+msgid "Service accounts"
msgstr ""
msgid "Service ping is disabled in your configuration file, and cannot be enabled through this form."
@@ -32895,6 +33577,9 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
+msgid "Set the per-user rate limit for getting a user by ID via the API."
+msgstr ""
+
msgid "Set the per-user rate limit for notes created by web or API requests."
msgstr ""
@@ -33074,6 +33759,9 @@ msgstr ""
msgid "Shared runners details"
msgstr ""
+msgid "Shared runners enabled cannot be enabled until a valid credit card is on file"
+msgstr ""
+
msgid "Shared runners help link"
msgstr ""
@@ -33131,6 +33819,9 @@ msgstr ""
msgid "Show all issues."
msgstr ""
+msgid "Show all milestones"
+msgstr ""
+
msgid "Show all test cases."
msgstr ""
@@ -33167,6 +33858,9 @@ msgstr ""
msgid "Show file contents"
msgstr ""
+msgid "Show group milestones"
+msgstr ""
+
msgid "Show labels"
msgstr ""
@@ -33182,6 +33876,12 @@ msgstr ""
msgid "Show open epics"
msgstr ""
+msgid "Show project milestones"
+msgstr ""
+
+msgid "Show sub-group milestones"
+msgstr ""
+
msgid "Show the Closed list"
msgstr ""
@@ -33191,11 +33891,6 @@ msgstr ""
msgid "Show whitespace changes"
msgstr ""
-msgid "Showing %d event"
-msgid_plural "Showing %d events"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Showing %{conflict} between %{sourceBranch} and %{targetBranch}"
msgstr ""
@@ -33255,12 +33950,6 @@ msgstr ""
msgid "Sidebar|None"
msgstr ""
-msgid "Sidebar|Only numeral characters allowed"
-msgstr ""
-
-msgid "Sidebar|Weight"
-msgstr ""
-
msgid "Sidekiq job compression threshold (bytes)"
msgstr ""
@@ -33423,6 +34112,9 @@ msgstr ""
msgid "Slack logo"
msgstr ""
+msgid "SlackIntegration|Are you sure you want to remove this project from the Slack application?"
+msgstr ""
+
msgid "SlackIntegration|GitLab for Slack"
msgstr ""
@@ -33432,6 +34124,9 @@ msgstr ""
msgid "SlackIntegration|Project alias"
msgstr ""
+msgid "SlackIntegration|Remove project"
+msgstr ""
+
msgid "SlackIntegration|Select a GitLab project to link with your Slack workspace."
msgstr ""
@@ -33576,9 +34271,6 @@ msgstr ""
msgid "Something went wrong trying to load issue contacts."
msgstr ""
-msgid "Something went wrong when creating a work item. Please try again"
-msgstr ""
-
msgid "Something went wrong when reordering designs. Please try again"
msgstr ""
@@ -33672,9 +34364,6 @@ msgstr ""
msgid "Something went wrong while inserting your image. Please try again."
msgstr ""
-msgid "Something went wrong while merging this merge request. Please try again."
-msgstr ""
-
msgid "Something went wrong while obtaining the Let's Encrypt certificate."
msgstr ""
@@ -33996,10 +34685,10 @@ 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."
+msgid "SourcegraphAdmin|Learn more."
msgstr ""
-msgid "SourcegraphAdmin|More information"
+msgid "SourcegraphAdmin|Only public projects have code intelligence enabled and communicate with Sourcegraph."
msgstr ""
msgid "SourcegraphAdmin|Save changes"
@@ -34008,7 +34697,7 @@ msgstr ""
msgid "SourcegraphAdmin|Sourcegraph URL"
msgstr ""
-msgid "SourcegraphAdmin|e.g. https://sourcegraph.example.com"
+msgid "SourcegraphAdmin|https://sourcegraph.example.com"
msgstr ""
msgid "SourcegraphPreferences|This feature is experimental and currently limited to certain projects."
@@ -34143,6 +34832,9 @@ msgstr ""
msgid "Start date"
msgstr ""
+msgid "Start free trial"
+msgstr ""
+
msgid "Start merge train"
msgstr ""
@@ -34173,6 +34865,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started escalation for this incident."
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -34185,6 +34880,9 @@ msgstr ""
msgid "Starts at (UTC)"
msgstr ""
+msgid "Starts escalations for this incident"
+msgstr ""
+
msgid "Starts on"
msgstr ""
@@ -34446,6 +35144,9 @@ msgstr ""
msgid "Strikethrough"
msgstr ""
+msgid "Strikethrough text"
+msgstr ""
+
msgid "Subgroup information"
msgstr ""
@@ -34680,6 +35381,21 @@ msgstr ""
msgid "Subscriptions"
msgstr ""
+msgid "Subscriptions|Chat with sales"
+msgstr ""
+
+msgid "Subscriptions|Close"
+msgstr ""
+
+msgid "Subscriptions|Not ready to buy yet?"
+msgstr ""
+
+msgid "Subscriptions|Start a free trial"
+msgstr ""
+
+msgid "Subscriptions|We understand. Maybe you have some questions for our sales team, or maybe you'd like to try some of the paid features first. What would you like to do?"
+msgstr ""
+
msgid "Subscription|Your subscription for %{strong}%{namespace_name}%{strong_close} has expired and you are now on %{pricing_link_start}the GitLab Free tier%{pricing_link_end}. Don't worry, your data is safe. Get in touch with our support team (%{support_email}). They'll gladly help with your subscription renewal."
msgstr ""
@@ -34890,6 +35606,9 @@ msgstr ""
msgid "SuperSonics|Maximum users"
msgstr ""
+msgid "SuperSonics|Offline cloud"
+msgstr ""
+
msgid "SuperSonics|Paste your activation code"
msgstr ""
@@ -34956,6 +35675,12 @@ msgstr ""
msgid "SuperSonics|You do not have an active subscription"
msgstr ""
+msgid "SuperSonics|You have a future dated license"
+msgstr ""
+
+msgid "SuperSonics|You have added a license that activates on %{date}. Please see the subscription history table below for more details."
+msgstr ""
+
msgid "SuperSonics|You have successfully added a license that activates on %{date}. Please see the subscription history table below for more details."
msgstr ""
@@ -35115,6 +35840,9 @@ msgstr ""
msgid "Tag name is required"
msgstr ""
+msgid "Tag push"
+msgstr ""
+
msgid "Tag push events"
msgstr ""
@@ -35217,6 +35945,9 @@ msgstr ""
msgid "TagsPage|protected"
msgstr ""
+msgid "Take a look at the documentation to discover all of GitLab’s capabilities."
+msgstr ""
+
msgid "Target Branch"
msgstr ""
@@ -35619,6 +36350,9 @@ msgstr ""
msgid "Tests"
msgstr ""
+msgid "Text (optional)"
+msgstr ""
+
msgid "Text added to the body of all email messages. %{character_limit} character limit"
msgstr ""
@@ -35669,6 +36403,9 @@ msgstr ""
msgid "The CSV export will be created in the background. Once finished, it will be sent to %{email} in an attachment."
msgstr ""
+msgid "The CSV export you requested of all user memberships is attached to this email."
+msgstr ""
+
msgid "The GitLab subscription service (customers.gitlab.com) is currently experiencing an outage. You can monitor the status and get updates at %{linkStart}status.gitlab.com%{linkEnd}."
msgstr ""
@@ -35744,6 +36481,9 @@ 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 epic"
+msgstr ""
+
msgid "The current issue"
msgstr ""
@@ -35905,6 +36645,9 @@ msgstr ""
msgid "The latest pipeline for this merge request has failed."
msgstr ""
+msgid "The license key is invalid."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -35920,6 +36663,9 @@ msgstr ""
msgid "The license was successfully uploaded and will be active from %{starts_at}. You can see the details below."
msgstr ""
+msgid "The license you uploaded is invalid. If the issue persists, contact support at %{link}."
+msgstr ""
+
msgid "The list creation wizard is already open"
msgstr ""
@@ -36541,10 +37287,13 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} and everything this project contains. %{strongOpen}There is no going back%{strongClose}"
+msgstr ""
+
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains."
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}on %{date}%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains. %{strongOpen}There is no going back.%{strongClose}"
msgstr ""
msgid "This action will %{strongOpen}permanently remove%{strongClose} %{codeOpen}%{group}%{codeClose} %{strongOpen}immediately%{strongClose}."
@@ -36673,9 +37422,6 @@ msgstr ""
msgid "This file was modified for readability, and can't accept suggestions. Edit it directly."
msgstr ""
-msgid "This forked project has the following:"
-msgstr ""
-
msgid "This form is disabled in preview"
msgstr ""
@@ -36688,7 +37434,7 @@ msgstr ""
msgid "This group can't be removed because it is linked to a subscription. To remove this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
-msgid "This group can't be transfered because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
+msgid "This group can't be transferred because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
msgid "This group cannot be invited to a project inside a group with enforced SSO"
@@ -36715,6 +37461,9 @@ 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 incident is already escalated with '%{escalation_policy_name}'."
+msgstr ""
+
msgid "This invitation was sent to %{mail_to_invite_email}, but you are signed in as %{link_to_current_user} with email %{mail_to_current_user}."
msgstr ""
@@ -36733,9 +37482,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 merge train pipeline"
-msgstr ""
-
msgid "This is a private email address %{helpIcon} generated just for you. Anyone who has it can create issues or merge requests as if they were you. If that happens, %{resetLinkStart}reset this token%{resetLinkEnd}."
msgstr ""
@@ -36757,6 +37503,12 @@ msgstr ""
msgid "This is your current session"
msgstr ""
+msgid "This issue cannot be assigned to a confidential epic because it is public."
+msgstr ""
+
+msgid "This issue cannot be made public because it belongs to a confidential epic."
+msgstr ""
+
msgid "This issue is confidential and should only be visible to team members with at least Reporter access."
msgstr ""
@@ -36874,6 +37626,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 branch is protected from force push."
+msgstr ""
+
msgid "This merge request cannot be rebased while there are conflicts."
msgstr ""
@@ -36925,9 +37680,15 @@ msgstr ""
msgid "This pipeline was triggered by a schedule."
msgstr ""
+msgid "This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project"
msgstr ""
+msgid "This project can be restored until %{date}."
+msgstr ""
+
msgid "This project cannot be %{visibilityLevel} because the visibility of %{openShowLink}%{name}%{closeShowLink} is %{visibility}. To make this project %{visibilityLevel}, you must first %{openEditLink}change the visibility%{closeEditLink} of the parent group."
msgstr ""
@@ -36946,6 +37707,9 @@ msgstr ""
msgid "This project is %{strongStart}NOT%{strongEnd} a fork, and has the following:"
msgstr ""
+msgid "This project is %{strongStart}NOT%{strongEnd} a fork. This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -37637,6 +38401,9 @@ msgstr ""
msgid "Today"
msgstr ""
+msgid "Todos count"
+msgstr ""
+
msgid "Todos|Are you looking for things to do? Take a look at %{strongStart}%{openIssuesLinkStart}open issues%{openIssuesLinkEnd}%{strongEnd}, contribute to %{strongStart}%{mergeRequestLinkStart}a merge request%{mergeRequestLinkEnd}%{mergeRequestLinkEnd}%{strongEnd}, or mention someone in a comment to automatically assign them a new to-do item."
msgstr ""
@@ -37910,10 +38677,8 @@ msgstr ""
msgid "Trending"
msgstr ""
-msgid "Trials|%{planName} Trial %{enDash} %{num} day left"
-msgid_plural "Trials|%{planName} Trial %{enDash} %{num} days left"
-msgstr[0] ""
-msgstr[1] ""
+msgid "Trials|%{planName} Trial"
+msgstr ""
msgid "Trials|Compare all plans"
msgstr ""
@@ -37921,6 +38686,9 @@ msgstr ""
msgid "Trials|Create a new group to start your GitLab Ultimate trial."
msgstr ""
+msgid "Trials|Day %{daysUsed}/%{duration}"
+msgstr ""
+
msgid "Trials|Go back to GitLab"
msgstr ""
@@ -38170,7 +38938,7 @@ msgstr ""
msgid "URL is triggered when repository is updated"
msgstr ""
-msgid "URL must be percent-encoded if neccessary."
+msgid "URL must be percent-encoded if necessary."
msgstr ""
msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
@@ -38389,6 +39157,9 @@ msgstr ""
msgid "Unlock account"
msgstr ""
+msgid "Unlock more features with GitLab Ultimate"
+msgstr ""
+
msgid "Unlock the discussion"
msgstr ""
@@ -38452,6 +39223,9 @@ msgstr ""
msgid "Unsubscribes from this %{quick_action_target}."
msgstr ""
+msgid "Unsupported sort value."
+msgstr ""
+
msgid "Unsupported todo type passed. Supported todo types are: %{todo_types}"
msgstr ""
@@ -38680,6 +39454,9 @@ msgstr ""
msgid "UsageQuota|File attachments and smaller design graphics."
msgstr ""
+msgid "UsageQuota|From %{storage_enforcement_date} storage limits will apply to this namespace. View and manage your usage in %{strong_start}Group Settings &gt; Usage quotas%{strong_end}."
+msgstr ""
+
msgid "UsageQuota|Git repository."
msgstr ""
@@ -38740,6 +39517,9 @@ msgstr ""
msgid "UsageQuota|Storage type"
msgstr ""
+msgid "UsageQuota|Storage used"
+msgstr ""
+
msgid "UsageQuota|This is the total amount of storage used across your projects within this namespace."
msgstr ""
@@ -38935,6 +39715,12 @@ msgstr ""
msgid "Use hashed storage paths for newly created and renamed repositories. Always enabled since 13.0."
msgstr ""
+msgid "Use issue count"
+msgstr ""
+
+msgid "Use issue weight"
+msgstr ""
+
msgid "Use one line per URI"
msgstr ""
@@ -39316,6 +40102,9 @@ msgstr ""
msgid "Users"
msgstr ""
+msgid "Users API rate limit"
+msgstr ""
+
msgid "Users can launch a development environment from a GitLab browser tab when the %{linkStart}Gitpod%{linkEnd} integration is enabled."
msgstr ""
@@ -39641,6 +40430,9 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View group pipeline usage quota"
+msgstr ""
+
msgid "View incident details at"
msgstr ""
@@ -39793,6 +40585,9 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
+msgid "Vulnerability"
+msgstr ""
+
msgid "Vulnerability Report"
msgstr ""
@@ -39844,6 +40639,9 @@ msgstr ""
msgid "VulnerabilityManagement|An unverified non-confirmed finding"
msgstr ""
+msgid "VulnerabilityManagement|At least one identifier is required"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -39853,12 +40651,24 @@ msgstr ""
msgid "VulnerabilityManagement|Create Jira issue"
msgstr ""
+msgid "VulnerabilityManagement|Enter a name"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE code"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE identifier URL"
+msgstr ""
+
msgid "VulnerabilityManagement|Fetching linked Jira issues"
msgstr ""
msgid "VulnerabilityManagement|Manually add a vulnerability entry into the vulnerability report."
msgstr ""
+msgid "VulnerabilityManagement|Name is a required field"
+msgstr ""
+
msgid "VulnerabilityManagement|Needs triage"
msgstr ""
@@ -39874,6 +40684,18 @@ msgstr ""
msgid "VulnerabilityManagement|Select a method"
msgstr ""
+msgid "VulnerabilityManagement|Select a severity level"
+msgstr ""
+
+msgid "VulnerabilityManagement|Select a status"
+msgstr ""
+
+msgid "VulnerabilityManagement|Severity is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Something went wrong while creating vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -39898,6 +40720,12 @@ msgstr ""
msgid "VulnerabilityManagement|Something went wrong, could not update vulnerability state."
msgstr ""
+msgid "VulnerabilityManagement|Status is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Submit vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Summary, detailed description, steps to reproduce, etc."
msgstr ""
@@ -40093,6 +40921,9 @@ msgstr ""
msgid "WARNING:"
msgstr ""
+msgid "WARNING: This snippet contains hidden files which might be used to mask malicious behavior. Exercise caution if cloning and executing code from this snippet."
+msgstr ""
+
msgid "Wait for the file to load to copy its contents"
msgstr ""
@@ -40312,6 +41143,15 @@ msgstr ""
msgid "Webhooks|An issue is created, updated, closed, or reopened."
msgstr ""
+msgid "Webhooks|Are you sure you want to delete this group hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this project hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this webhook?"
+msgstr ""
+
msgid "Webhooks|Comments"
msgstr ""
@@ -40321,6 +41161,9 @@ msgstr ""
msgid "Webhooks|Confidential issues events"
msgstr ""
+msgid "Webhooks|Delete webhook"
+msgstr ""
+
msgid "Webhooks|Deployment events"
msgstr ""
@@ -40554,6 +41397,9 @@ msgstr ""
msgid "Wiki"
msgstr ""
+msgid "Wiki page"
+msgstr ""
+
msgid "Wiki page was successfully created."
msgstr ""
@@ -40659,7 +41505,7 @@ msgstr ""
msgid "WikiPageConflictMessage|Someone edited the page the same time you did. Please check out %{wikiLinkStart}the page%{wikiLinkEnd} and make sure your changes will not unintentionally remove theirs."
msgstr ""
-msgid "WikiPage|An error occured while trying to render the content editor. Please try again later."
+msgid "WikiPage|An error occurred while trying to render the content editor. Please try again later."
msgstr ""
msgid "WikiPage|Are you sure you want to switch back to the classic editor?"
@@ -40818,6 +41664,18 @@ msgstr ""
msgid "WorkItem|New Task"
msgstr ""
+msgid "WorkItem|Something went wrong when creating a work item. Please try again"
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching the work item. Please try again."
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching work item types. Please try again"
+msgstr ""
+
+msgid "WorkItem|Type"
+msgstr ""
+
msgid "WorkItem|Work Items"
msgstr ""
@@ -40884,7 +41742,10 @@ msgstr ""
msgid "You are about to add %{usersTag} people to the discussion. They will all receive a notification."
msgstr ""
-msgid "You are about to permanently delete this project"
+msgid "You are about to delete this forked project containing:"
+msgstr ""
+
+msgid "You are about to delete this project containing:"
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."
@@ -40905,6 +41766,9 @@ msgstr ""
msgid "You are attempting to update a file that has changed since you started editing it."
msgstr ""
+msgid "You are billed if you exceed this number. %{qsrOverageLinkStart}How does billing work?%{qsrOverageLinkEnd}"
+msgstr ""
+
msgid "You are connected to the Prometheus server, but there is currently no data to display."
msgstr ""
@@ -40962,6 +41826,9 @@ msgstr ""
msgid "You are not authorized to update this scanner profile"
msgstr ""
+msgid "You are not authorized to upload metric images"
+msgstr ""
+
msgid "You are now impersonating %{username}"
msgstr ""
@@ -41115,9 +41982,6 @@ msgstr ""
msgid "You can only upload one design when dropping onto an existing design."
msgstr ""
-msgid "You can recover this project until %{date}"
-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 ""
@@ -41166,9 +42030,6 @@ msgstr ""
msgid "You cannot write to this read-only GitLab instance."
msgstr ""
-msgid "You can’t %{tag_start}edit%{tag_end} files directly in this project. Fork this project and submit a merge request with your changes."
-msgstr ""
-
msgid "You can’t edit files directly in this project. Fork this project and submit a merge request with your changes."
msgstr ""
@@ -41321,9 +42182,6 @@ 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 set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
@@ -41354,12 +42212,6 @@ msgstr ""
msgid "You must have maintainer access to force delete a lock"
msgstr ""
-msgid "You must have permission to create a project in a group before forking."
-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 ""
@@ -41765,7 +42617,7 @@ msgstr ""
msgid "Your public email will be displayed on your public profile."
msgstr ""
-msgid "Your request for access could not be processed: %{error_meesage}"
+msgid "Your request for access could not be processed: %{error_message}"
msgstr ""
msgid "Your request for access has been queued for review."
@@ -41948,6 +42800,9 @@ msgstr ""
msgid "archived:"
msgstr ""
+msgid "artifacts"
+msgstr ""
+
msgid "assign yourself"
msgstr ""
@@ -41977,6 +42832,9 @@ msgstr[1] ""
msgid "branch name"
msgstr ""
+msgid "builds"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -42400,6 +43258,9 @@ msgstr ""
msgid "contact with same email already exists in group hierarchy"
msgstr ""
+msgid "container registry images"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -42439,6 +43300,9 @@ msgstr ""
msgid "data"
msgstr ""
+msgid "database"
+msgstr ""
+
msgid "date must not be after 9999-12-31"
msgstr ""
@@ -42462,9 +43326,6 @@ msgstr ""
msgid "design"
msgstr ""
-msgid "detached"
-msgstr ""
-
msgid "disabled"
msgstr ""
@@ -42713,7 +43574,7 @@ msgstr ""
msgid "is not a valid X509 certificate."
msgstr ""
-msgid "is not allowed for sign-up."
+msgid "is not allowed for sign-up. Please use your regular email address."
msgstr ""
msgid "is not allowed for this group."
@@ -42725,7 +43586,7 @@ msgstr ""
msgid "is not allowed since the group is not top-level group."
msgstr ""
-msgid "is not allowed."
+msgid "is not allowed. Please use your regular email address."
msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
@@ -42812,6 +43673,9 @@ msgstr ""
msgid "level: %{level}"
msgstr ""
+msgid "lfs objects"
+msgstr ""
+
msgid "limit of %{project_limit} reached"
msgstr ""
@@ -43031,6 +43895,9 @@ msgstr ""
msgid "mrWidget|Merge blocked: pipeline must succeed. It's waiting for a manual action to continue."
msgstr ""
+msgid "mrWidget|Merge blocked: pipeline must succeed. Push a commit that fixes the failure, or %{linkStart}learn about other solutions.%{linkEnd}"
+msgstr ""
+
msgid "mrWidget|Merge blocked: this merge request must be approved."
msgstr ""
@@ -43148,9 +44015,6 @@ msgstr ""
msgid "mrWidget|The changes were not merged into"
msgstr ""
-msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -43298,9 +44162,6 @@ msgstr ""
msgid "open issue"
msgstr ""
-msgid "opened %{timeAgo}"
-msgstr ""
-
msgid "or"
msgstr ""
@@ -43312,6 +44173,12 @@ msgid_plural "out of %d total tests"
msgstr[0] ""
msgstr[1] ""
+msgid "packages"
+msgstr ""
+
+msgid "pages"
+msgstr ""
+
msgid "parent"
msgid_plural "parents"
msgstr[0] ""
@@ -43461,6 +44328,9 @@ msgid_plural "replies"
msgstr[0] ""
msgstr[1] ""
+msgid "repositories"
+msgstr ""
+
msgid "repository:"
msgstr ""
@@ -43581,12 +44451,18 @@ msgstr ""
msgid "tag name"
msgstr ""
+msgid "terraform states"
+msgstr ""
+
msgid "the correct format."
msgstr ""
msgid "the file"
msgstr ""
+msgid "the following epic(s)"
+msgstr ""
+
msgid "the following issue(s)"
msgstr ""
@@ -43599,21 +44475,12 @@ msgstr ""
msgid "this document"
msgstr ""
-msgid "this issue cannot be assigned to a confidential epic since it is public"
-msgstr ""
-
-msgid "this issue cannot be made public since it belongs to a confidential epic"
-msgstr ""
-
msgid "time summary"
msgstr ""
msgid "toggle collapse"
msgstr ""
-msgid "train"
-msgstr ""
-
msgid "triggered"
msgstr ""
@@ -43742,3 +44609,6 @@ msgstr ""
msgid "{project}"
msgstr ""
+msgid "✔"
+msgstr ""
+
diff --git a/locale/sw_KE/gitlab.po b/locale/sw_KE/gitlab.po
index d72301d07a6..f0bf366021c 100644
--- a/locale/sw_KE/gitlab.po
+++ b/locale/sw_KE/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: sw\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2022-02-02 15:48\n"
+"PO-Revision-Date: 2022-03-01 20:40\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -146,6 +146,11 @@ msgid_plural "%d approvers (you've approved)"
msgstr[0] ""
msgstr[1] ""
+msgid "%d assigned issue"
+msgid_plural "%d assigned issues"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -421,8 +426,23 @@ msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
msgstr[1] ""
-msgid "%d vulnerability updated"
-msgid_plural "%d vulnerabilities updated"
+msgid "%d vulnerability set to confirmed"
+msgid_plural "%d vulnerabilities set to confirmed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to dismissed"
+msgid_plural "%d vulnerabilities set to dismissed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to needs triage"
+msgid_plural "%d vulnerabilities set to needs triage"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to resolved"
+msgid_plural "%d vulnerabilities set to resolved"
msgstr[0] ""
msgstr[1] ""
@@ -510,6 +530,12 @@ msgstr[1] ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{completed} of %{total} issues closed"
+msgstr ""
+
+msgid "%{completed} of %{total} weight completed"
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -858,6 +884,9 @@ msgstr ""
msgid "%{openedIssues} open, %{closedIssues} closed"
msgstr ""
+msgid "%{percentage}%% issues closed"
+msgstr ""
+
msgid "%{percentage}%% weight completed"
msgstr ""
@@ -1287,6 +1316,9 @@ msgid_plural "- Users"
msgstr[0] ""
msgstr[1] ""
+msgid "- of - issues closed"
+msgstr ""
+
msgid "- of - weight completed"
msgstr ""
@@ -1429,7 +1461,7 @@ msgstr ""
msgid "1000+"
msgstr ""
-msgid "192.168.0.0/24"
+msgid "192.168.0.0/24 or 2001:0DB8:1234::/48"
msgstr ""
msgid "1st contribution!"
@@ -1741,13 +1773,13 @@ msgstr ""
msgid "AWS Access Key"
msgstr ""
-msgid "AWS Access Key. Only required if not using role instance credentials"
+msgid "AWS Secret Access Key"
msgstr ""
-msgid "AWS Secret Access Key"
+msgid "AWS access key ID (Optional)"
msgstr ""
-msgid "AWS Secret Access Key. Only required if not using role instance credentials"
+msgid "AWS secret access key (Optional)"
msgstr ""
msgid "AWS service error: %{error}"
@@ -1807,9 +1839,6 @@ msgstr ""
msgid "Access granted"
msgstr ""
-msgid "Access key ID"
-msgstr ""
-
msgid "Access requests"
msgstr ""
@@ -1984,7 +2013,7 @@ msgstr ""
msgid "Activity"
msgstr ""
-msgid "Activity|An error occured while retrieving activity. Reload the page to try again."
+msgid "Activity|An error occurred while retrieving activity. Reload the page to try again."
msgstr ""
msgid "Add"
@@ -2023,6 +2052,9 @@ msgstr ""
msgid "Add a %{type}"
msgstr ""
+msgid "Add a GCP region"
+msgstr ""
+
msgid "Add a GPG key"
msgstr ""
@@ -2074,6 +2106,9 @@ msgstr ""
msgid "Add a numbered list"
msgstr ""
+msgid "Add a related epic"
+msgstr ""
+
msgid "Add a related issue"
msgstr ""
@@ -2188,6 +2223,9 @@ msgstr ""
msgid "Add or subtract spent time"
msgstr ""
+msgid "Add people"
+msgstr ""
+
msgid "Add previously merged commits"
msgstr ""
@@ -2254,6 +2292,9 @@ msgstr ""
msgid "Add webhook"
msgstr ""
+msgid "Add your team members and others to GitLab."
+msgstr ""
+
msgid "Add/remove"
msgstr ""
@@ -3076,12 +3117,6 @@ msgstr ""
msgid "AdvancedSearch|Reindex required"
msgstr ""
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. Permanently deleting this project will %{strongStart}immediately delete%{strongEnd} its repositories and %{strongStart}all related resources%{strongEnd}, including issues, merge requests etc."
-msgstr ""
-
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. You will lose this project's repository and %{strongStart}all related resources%{strongEnd}, including issues and merge requests."
-msgstr ""
-
msgid "After a successful password update you will be redirected to login screen."
msgstr ""
@@ -3112,6 +3147,9 @@ msgstr ""
msgid "Akismet helps prevent the creation of spam issues in public projects."
msgstr ""
+msgid "Alert"
+msgstr ""
+
msgid "AlertManagement|Acknowledged"
msgstr ""
@@ -3484,9 +3522,6 @@ msgstr ""
msgid "All environments"
msgstr ""
-msgid "All epics"
-msgstr ""
-
msgid "All groups and projects"
msgstr ""
@@ -4223,12 +4258,15 @@ msgstr ""
msgid "ApplicationSettings|Approve users in the pending approval status?"
msgstr ""
-msgid "ApplicationSettings|By making this change, you will automatically approve %d user with the pending approval status."
-msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users with the pending approval status."
+msgid "ApplicationSettings|Approve users who are pending approval?"
+msgstr ""
+
+msgid "ApplicationSettings|By making this change, you will automatically approve %d user who is pending approval."
+msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users who are pending approval."
msgstr[0] ""
msgstr[1] ""
-msgid "ApplicationSettings|By making this change, you will automatically approve all users in pending approval status."
+msgid "ApplicationSettings|By making this change, you will automatically approve all users who are pending approval."
msgstr ""
msgid "ApplicationSettings|Denied domains for sign-ups"
@@ -4634,10 +4672,10 @@ msgstr ""
msgid "Archiving the project will make it entirely read-only. It is hidden from the dashboard and doesn't show up in searches. %{strong_start}The repository cannot be committed to, and no issues, comments, or other entities can be created.%{strong_end} %{link_start}Learn more.%{link_end}"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to delete this project?"
+msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
+msgid "Are you absolutely sure?"
msgstr ""
msgid "Are you sure that you want to archive this project?"
@@ -4673,12 +4711,18 @@ msgstr ""
msgid "Are you sure you want to delete this SSH key?"
msgstr ""
+msgid "Are you sure you want to delete this comment?"
+msgstr ""
+
msgid "Are you sure you want to delete this deploy key?"
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 label?"
+msgstr ""
+
msgid "Are you sure you want to delete this pipeline schedule?"
msgstr ""
@@ -4694,9 +4738,6 @@ msgstr ""
msgid "Are you sure you want to discard your changes?"
msgstr ""
-msgid "Are you sure you want to erase this build?"
-msgstr ""
-
msgid "Are you sure you want to import %d repository?"
msgid_plural "Are you sure you want to import %d repositories?"
msgstr[0] ""
@@ -4744,6 +4785,9 @@ msgstr ""
msgid "Are you sure you want to remove this list?"
msgstr ""
+msgid "Are you sure you want to remove this nickname?"
+msgstr ""
+
msgid "Are you sure you want to reset the health check token?"
msgstr ""
@@ -4756,10 +4800,10 @@ 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?"
+msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
msgstr ""
-msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
+msgid "Are you sure you want to revoke this project access token? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to stop this environment?"
@@ -4906,9 +4950,6 @@ msgstr ""
msgid "Assigned to %{assignee_name}"
msgstr ""
-msgid "Assigned to %{name}"
-msgstr ""
-
msgid "Assigned to me"
msgstr ""
@@ -4973,6 +5014,9 @@ msgstr[1] ""
msgid "Attaching the file failed."
msgstr ""
+msgid "Attention"
+msgstr ""
+
msgid "Audit Events"
msgstr ""
@@ -5135,6 +5179,12 @@ msgstr ""
msgid "Authorized applications (%{size})"
msgstr ""
+msgid "AuthorizedApplication|Are you sure you want to revoke this application?"
+msgstr ""
+
+msgid "AuthorizedApplication|Revoke application"
+msgstr ""
+
msgid "Authors: %{authors}"
msgstr ""
@@ -6328,6 +6378,9 @@ msgstr ""
msgid "CICDAnalytics|Shared Runners Usage"
msgstr ""
+msgid "CICDAnalytics|Shared runner pipeline minute duration by month"
+msgstr ""
+
msgid "CICDAnalytics|Shared runner usage"
msgstr ""
@@ -6469,6 +6522,9 @@ msgstr ""
msgid "Can create groups:"
msgstr ""
+msgid "Can not delete primary training"
+msgstr ""
+
msgid "Can't apply as the source branch was deleted."
msgstr ""
@@ -6802,9 +6858,6 @@ msgstr ""
msgid "Changing any setting here requires an application restart"
msgstr ""
-msgid "Changing group URL can have unintended side effects."
-msgstr ""
-
msgid "Charts can't be displayed as the request for data has timed out. %{documentationLink}"
msgstr ""
@@ -6892,9 +6945,6 @@ msgstr ""
msgid "Checking branch availability..."
msgstr ""
-msgid "Checking group URL availability..."
-msgstr ""
-
msgid "Checking group path availability..."
msgstr ""
@@ -7388,6 +7438,9 @@ msgstr ""
msgid "Clear recent searches"
msgstr ""
+msgid "Clear repository checks"
+msgstr ""
+
msgid "Clear search"
msgstr ""
@@ -7520,9 +7573,6 @@ msgstr ""
msgid "Closed MRs"
msgstr ""
-msgid "Closed epics"
-msgstr ""
-
msgid "Closed issues"
msgstr ""
@@ -7559,13 +7609,13 @@ msgstr ""
msgid "Cluster level"
msgstr ""
-msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
+msgid "Cluster type must be specified for Stages::ClusterEndpointInserter"
msgstr ""
msgid "ClusterAgents|%{name} successfully deleted"
msgstr ""
-msgid "ClusterAgents|%{number} of %{total} Agents"
+msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
@@ -7607,6 +7657,15 @@ msgstr ""
msgid "ClusterAgents|Agent never connected to GitLab"
msgstr ""
+msgid "ClusterAgents|Agent version mismatch"
+msgstr ""
+
+msgid "ClusterAgents|Agent version mismatch and update"
+msgstr ""
+
+msgid "ClusterAgents|Agent version update required"
+msgstr ""
+
msgid "ClusterAgents|All"
msgstr ""
@@ -7631,7 +7690,7 @@ msgstr ""
msgid "ClusterAgents|Configuration"
msgstr ""
-msgid "ClusterAgents|Connect a cluster through the Agent"
+msgid "ClusterAgents|Connect a cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connect existing cluster"
@@ -7640,13 +7699,13 @@ msgstr ""
msgid "ClusterAgents|Connect with a certificate"
msgstr ""
-msgid "ClusterAgents|Connect with agent"
+msgid "ClusterAgents|Connect with an agent"
msgstr ""
msgid "ClusterAgents|Connect with the GitLab Agent"
msgstr ""
-msgid "ClusterAgents|Connect your cluster through the Agent"
+msgid "ClusterAgents|Connect your cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connected"
@@ -7706,7 +7765,10 @@ msgstr ""
msgid "ClusterAgents|How to register an agent?"
msgstr ""
-msgid "ClusterAgents|Install new Agent"
+msgid "ClusterAgents|How to update an agent?"
+msgstr ""
+
+msgid "ClusterAgents|Install a new agent"
msgstr ""
msgid "ClusterAgents|Last connected %{timeAgo}."
@@ -7733,7 +7795,7 @@ msgstr ""
msgid "ClusterAgents|Never connected"
msgstr ""
-msgid "ClusterAgents|No Agents"
+msgid "ClusterAgents|No agents"
msgstr ""
msgid "ClusterAgents|No clusters connected through cluster certificates"
@@ -7793,6 +7855,9 @@ msgstr ""
msgid "ClusterAgents|The agent has not been connected in a long time. There might be a connectivity issue. Last contact was %{timeAgo}."
msgstr ""
+msgid "ClusterAgents|The agent version do not match each other across your cluster's pods. This can happen when a new agent version was just deployed and Kubernetes is shutting down the old pods."
+msgstr ""
+
msgid "ClusterAgents|The recommended installation method includes the token. If you want to follow the advanced installation method provided in the docs, make sure you save the token value before you close this window."
msgstr ""
@@ -7840,6 +7905,9 @@ msgstr ""
msgid "ClusterAgents|You will need to create a token to connect to your agent"
msgstr ""
+msgid "ClusterAgents|Your agent version is out of sync with your GitLab version (v%{version}), which might cause compatibility problems. Update the agent installed on your cluster to the most recent version."
+msgstr ""
+
msgid "ClusterAgents|Your instance doesn't have the %{linkStart}GitLab Agent Server (KAS)%{linkEnd} set up. Ask a GitLab Administrator to install it."
msgstr ""
@@ -8716,9 +8784,6 @@ msgstr ""
msgid "Comma-separated list of email addresses."
msgstr ""
-msgid "Comma-separated list of users allowed to exceed the rate limit."
-msgstr ""
-
msgid "Comma-separated, e.g. '1.1.1.1, 2.2.2.0/24'"
msgstr ""
@@ -9045,6 +9110,12 @@ msgstr ""
msgid "Confidential"
msgstr ""
+msgid "Confidential issue"
+msgstr ""
+
+msgid "Confidential note"
+msgstr ""
+
msgid "Confidentiality"
msgstr ""
@@ -9078,6 +9149,9 @@ msgstr ""
msgid "Configure Dependency Scanning in `.gitlab-ci.yml`, creating this file if it does not already exist"
msgstr ""
+msgid "Configure GitLab"
+msgstr ""
+
msgid "Configure GitLab runners to start using the Web Terminal. %{helpStart}Learn more.%{helpEnd}"
msgstr ""
@@ -9126,6 +9200,15 @@ msgstr ""
msgid "Configure pipelines to deploy web apps, backend services, APIs and static resources to Google Cloud"
msgstr ""
+msgid "Configure region"
+msgstr ""
+
+msgid "Configure region for environment"
+msgstr ""
+
+msgid "Configure regions"
+msgstr ""
+
msgid "Configure repository mirroring."
msgstr ""
@@ -9159,6 +9242,9 @@ msgstr ""
msgid "Configure which lists are shown for anyone who visits this board"
msgstr ""
+msgid "Configure your environments to be deployed to specific geographical regions"
+msgstr ""
+
msgid "Confirm"
msgstr ""
@@ -9861,10 +9947,10 @@ msgstr ""
msgid "CorpusManagement|Actions"
msgstr ""
-msgid "CorpusManagement|Corpus are used in fuzz testing as mutation source to Improve future testing."
+msgid "CorpusManagement|Corpus file"
msgstr ""
-msgid "CorpusManagement|Corpus file"
+msgid "CorpusManagement|Corpus files are used in coverage-guided fuzz testing as seed inputs to improve testing."
msgstr ""
msgid "CorpusManagement|Corpus files must be in *.zip format. Maximum 5 GB"
@@ -9918,6 +10004,9 @@ msgstr ""
msgid "Could not apply %{name} command."
msgstr ""
+msgid "Could not apply %{name} command. %{message}."
+msgstr ""
+
msgid "Could not authorize chat nickname. Try again!"
msgstr ""
@@ -10068,6 +10157,9 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
+msgid "Create a group"
+msgstr ""
+
msgid "Create a merge request"
msgstr ""
@@ -10092,6 +10184,9 @@ msgstr ""
msgid "Create a personal access token on your account to pull or push via %{protocol}."
msgstr ""
+msgid "Create a project"
+msgstr ""
+
msgid "Create an account using:"
msgstr ""
@@ -10455,6 +10550,9 @@ msgstr ""
msgid "Creation date"
msgstr ""
+msgid "Creator"
+msgstr ""
+
msgid "Credentials"
msgstr ""
@@ -10467,9 +10565,15 @@ msgstr ""
msgid "CredentialsInventory|Personal Access Tokens"
msgstr ""
+msgid "CredentialsInventory|Project Access Tokens"
+msgstr ""
+
msgid "CredentialsInventory|SSH Keys"
msgstr ""
+msgid "Credit card required to be on file in order to create a pipeline"
+msgstr ""
+
msgid "Credit card:"
msgstr ""
@@ -10653,9 +10757,6 @@ msgstr ""
msgid "Customer relations"
msgstr ""
-msgid "Customizable by an administrator."
-msgstr ""
-
msgid "Customizable by owners."
msgstr ""
@@ -10785,30 +10886,18 @@ msgstr ""
msgid "CycleAnalytics|%{selectedLabelsCount} selected (%{maxLabels} max)"
msgstr ""
-msgid "CycleAnalytics|%{stageCount} stages selected"
-msgstr ""
-
-msgid "CycleAnalytics|All stages"
-msgstr ""
-
-msgid "CycleAnalytics|Average days to completion"
+msgid "CycleAnalytics|Average time to completion"
msgstr ""
msgid "CycleAnalytics|Date"
msgstr ""
-msgid "CycleAnalytics|Days to completion"
-msgstr ""
-
msgid "CycleAnalytics|Display chart filters"
msgstr ""
msgid "CycleAnalytics|Lead Time for Changes"
msgstr ""
-msgid "CycleAnalytics|No stages selected"
-msgstr ""
-
msgid "CycleAnalytics|Number of tasks"
msgstr ""
@@ -10837,18 +10926,30 @@ msgstr ""
msgid "CycleAnalytics|Showing data for group '%{groupName}' from %{createdAfter} to %{createdBefore}"
msgstr ""
-msgid "CycleAnalytics|Stages"
+msgid "CycleAnalytics|Stage time: %{title}"
msgstr ""
msgid "CycleAnalytics|Tasks by type"
msgstr ""
-msgid "CycleAnalytics|The average time spent in the selected stage for the items that were completed on each date. Data limited to the last 500 items."
+msgid "CycleAnalytics|The average time items spent in this stage. Data limited to items completed within this date range."
msgstr ""
msgid "CycleAnalytics|The given date range is larger than 180 days"
msgstr ""
+msgid "CycleAnalytics|The total time items spent across each value stream stage. Data limited to items completed within this date range."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Stage time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Total time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|Total time"
+msgstr ""
+
msgid "CycleAnalytics|Type of work"
msgstr ""
@@ -10861,9 +10962,6 @@ msgstr ""
msgid "CycleAnalytics|project dropdown filter"
msgstr ""
-msgid "CycleAnalytics|stage dropdown"
-msgstr ""
-
msgid "DAG visualization requires at least 3 dependent jobs."
msgstr ""
@@ -10963,10 +11061,16 @@ msgstr ""
msgid "DastProfiles|AJAX spider"
msgstr ""
+msgid "DastProfiles|API"
+msgstr ""
+
+msgid "DastProfiles|API endpoint URL"
+msgstr ""
+
msgid "DastProfiles|Active"
msgstr ""
-msgid "DastProfiles|Additional request headers (Optional)"
+msgid "DastProfiles|Additional request headers (optional)"
msgstr ""
msgid "DastProfiles|Are you sure you want to delete this profile?"
@@ -10981,6 +11085,9 @@ msgstr ""
msgid "DastProfiles|Branch missing"
msgstr ""
+msgid "DastProfiles|Choose a scan method"
+msgstr ""
+
msgid "DastProfiles|Could not create the scanner profile. Please try again."
msgstr ""
@@ -11050,7 +11157,13 @@ msgstr ""
msgid "DastProfiles|Excluded URLs"
msgstr ""
-msgid "DastProfiles|Excluded URLs (Optional)"
+msgid "DastProfiles|Excluded URLs (optional)"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths (optional)"
msgstr ""
msgid "DastProfiles|Hide debug messages"
@@ -11107,9 +11220,6 @@ msgstr ""
msgid "DastProfiles|Request headers"
msgstr ""
-msgid "DastProfiles|Rest API"
-msgstr ""
-
msgid "DastProfiles|Run the AJAX spider, in addition to the traditional spider, to crawl the target site."
msgstr ""
@@ -11119,6 +11229,9 @@ msgstr ""
msgid "DastProfiles|Save profile"
msgstr ""
+msgid "DastProfiles|Scan method"
+msgstr ""
+
msgid "DastProfiles|Scan mode"
msgstr ""
@@ -11197,12 +11310,24 @@ msgstr ""
msgid "DastProfiles|Website"
msgstr ""
+msgid "DastProfiles|What does each method do?"
+msgstr ""
+
msgid "DastProfiles|You can either choose a passive scan or validate the target site from the site profile management page. %{docsLinkStart}Learn more about site validation.%{docsLinkEnd}"
msgstr ""
msgid "DastProfiles|You cannot run an active scan against an unvalidated site."
msgstr ""
+msgid "DastProfiles|folder/dast_example.har or https://example.com/dast_example.har"
+msgstr ""
+
+msgid "DastProfiles|folder/example.postman_collection.json or https://example.com/"
+msgstr ""
+
+msgid "DastProfiles|folder/openapi.json or https://example.com/openapi.json"
+msgstr ""
+
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
@@ -11310,6 +11435,9 @@ msgstr ""
msgid "DatadogIntegration|API URL"
msgstr ""
+msgid "DatadogIntegration|Custom tags in Datadog. Enter one tag per line in the %{codeOpen}key:value%{codeClose} format. %{linkOpen}How do I use tags?%{linkClose}"
+msgstr ""
+
msgid "DatadogIntegration|Environment"
msgstr ""
@@ -11328,12 +11456,18 @@ msgstr ""
msgid "DatadogIntegration|Tag all data from this GitLab instance in Datadog. Useful when managing several self-managed deployments."
msgstr ""
+msgid "DatadogIntegration|Tags"
+msgstr ""
+
msgid "DatadogIntegration|The Datadog site to send data to. To send data to the EU site, use %{codeOpen}datadoghq.eu%{codeClose}."
msgstr ""
msgid "DatadogIntegration|Trace your GitLab pipelines with Datadog."
msgstr ""
+msgid "DatadogIntegration|have an invalid format"
+msgstr ""
+
msgid "Datasource name not found"
msgstr ""
@@ -11343,9 +11477,6 @@ msgstr ""
msgid "Date merged"
msgstr ""
-msgid "Date picker"
-msgstr ""
-
msgid "Date range"
msgstr ""
@@ -11499,9 +11630,6 @@ msgstr ""
msgid "Definition"
msgstr ""
-msgid "Delayed Project Deletion (%{adjourned_deletion})"
-msgstr ""
-
msgid "DelayedJobs|Are you sure you want to run %{jobName} immediately? Otherwise this job will run automatically after its timer finishes."
msgstr ""
@@ -11580,10 +11708,10 @@ msgstr ""
msgid "Delete pipeline"
msgstr ""
-msgid "Delete project"
+msgid "Delete pipeline schedule"
msgstr ""
-msgid "Delete project. Are you ABSOLUTELY SURE?"
+msgid "Delete project"
msgstr ""
msgid "Delete row"
@@ -11613,6 +11741,9 @@ msgstr ""
msgid "Delete this epic and all descendants?"
msgstr ""
+msgid "Delete this project"
+msgstr ""
+
msgid "Delete user list"
msgstr ""
@@ -11871,6 +12002,12 @@ msgstr ""
msgid "Deploy to..."
msgstr ""
+msgid "DeployBoards|To see deployment progress for your environments, make sure you are deploying to %{codeStart}$KUBE_NAMESPACE%{codeEnd} and annotating with %{codeStart}app.gitlab.com/app=$CI_PROJECT_PATH_SLUG%{codeEnd} and %{codeStart}app.gitlab.com/env=$CI_ENVIRONMENT_SLUG%{codeEnd}."
+msgstr ""
+
+msgid "DeployBoard|Kubernetes Pods"
+msgstr ""
+
msgid "DeployFreeze|Add a freeze period to prevent unintended releases during a period of time for a given environment. You must update the deployment jobs in %{filename} according to the deploy freezes added here. %{freeze_period_link_start}Learn more.%{freeze_period_link_end}"
msgstr ""
@@ -11955,9 +12092,6 @@ msgstr ""
msgid "DeployTokens|Active Deploy Tokens (%{active_tokens})"
msgstr ""
-msgid "DeployTokens|Allows read and write access to registry images."
-msgstr ""
-
msgid "DeployTokens|Allows read and write access to the package registry."
msgstr ""
@@ -11970,6 +12104,9 @@ msgstr ""
msgid "DeployTokens|Allows read-only access to the repository."
msgstr ""
+msgid "DeployTokens|Allows write access to registry images."
+msgstr ""
+
msgid "DeployTokens|Copy deploy token"
msgstr ""
@@ -12063,12 +12200,57 @@ msgstr ""
msgid "Deploying to AWS is easy with GitLab"
msgstr ""
+msgid "Deployment"
+msgstr ""
+
msgid "Deployment Frequency"
msgstr ""
+msgid "Deployment Target|Project deployment target (optional)"
+msgstr ""
+
+msgid "Deployment Target|Select the deployment target"
+msgstr ""
+
msgid "Deployment frequency"
msgstr ""
+msgid "DeploymentTarget|GitLab Pages"
+msgstr ""
+
+msgid "DeploymentTarget|Heroku"
+msgstr ""
+
+msgid "DeploymentTarget|Infrastructure provider (Terraform, Cloudformation, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Kubernetes (GKE, EKS, OpenShift, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Managed container runtime (Fargate, Cloud Run, DigitalOcean App)"
+msgstr ""
+
+msgid "DeploymentTarget|Mobile app store"
+msgstr ""
+
+msgid "DeploymentTarget|No deployment planned"
+msgstr ""
+
+msgid "DeploymentTarget|Other hosting service"
+msgstr ""
+
+msgid "DeploymentTarget|Registry (package or container)"
+msgstr ""
+
+msgid "DeploymentTarget|Self-managed container runtime (Podman, Docker Swarm, Docker Compose)"
+msgstr ""
+
+msgid "DeploymentTarget|Serverless backend (Lambda, Cloud functions)"
+msgstr ""
+
+msgid "DeploymentTarget|Virtual machine (for example, EC2)"
+msgstr ""
+
msgid "Deployments"
msgstr ""
@@ -12107,6 +12289,9 @@ msgstr ""
msgid "Deployment|This deployment was created using the API"
msgstr ""
+msgid "Deployment|Triggerer"
+msgstr ""
+
msgid "Deployment|Waiting"
msgstr ""
@@ -12134,6 +12319,18 @@ msgstr ""
msgid "Deprecated API rate limits"
msgstr ""
+msgid "Deprecations|Feature deprecation and removal"
+msgstr ""
+
+msgid "Deprecations|For information on a possible replacement %{epicStart} learn more about Opstrace %{epicEnd}."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7 and are %{epicStart} scheduled for removal %{epicEnd} in GitLab 15.0."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7, and are %{removal_link_start} scheduled for removal %{link_end} in GitLab 15.0. For information on a possible replacement, %{opstrace_link_start} learn more about Opstrace %{link_end}."
+msgstr ""
+
msgid "Deprioritize label"
msgstr ""
@@ -12379,10 +12576,10 @@ msgstr ""
msgid "DevopsAdoption|At least one deploy"
msgstr ""
-msgid "DevopsAdoption|At least one issue opened"
+msgid "DevopsAdoption|At least one issue created"
msgstr ""
-msgid "DevopsAdoption|At least one merge request opened"
+msgid "DevopsAdoption|At least one merge request created"
msgstr ""
msgid "DevopsAdoption|At least one pipeline successfully run"
@@ -12583,6 +12780,9 @@ msgstr ""
msgid "Direct member"
msgstr ""
+msgid "Direct members"
+msgstr ""
+
msgid "Direct non-authenticated users to this page."
msgstr ""
@@ -12699,6 +12899,9 @@ msgid_plural "Dismiss %d selected vulnerabilities as"
msgstr[0] ""
msgstr[1] ""
+msgid "Dismiss Alert"
+msgstr ""
+
msgid "Dismiss merge request promotion"
msgstr ""
@@ -12726,9 +12929,15 @@ msgstr ""
msgid "Display alerts from all configured monitoring tools."
msgstr ""
+msgid "Display milestones"
+msgstr ""
+
msgid "Display name"
msgstr ""
+msgid "Display progress of child issues"
+msgstr ""
+
msgid "Display rendered file"
msgstr ""
@@ -12834,6 +13043,9 @@ msgstr ""
msgid "Download image"
msgstr ""
+msgid "Download payload"
+msgstr ""
+
msgid "Download raw data (.csv)"
msgstr ""
@@ -13011,6 +13223,9 @@ msgstr ""
msgid "Edit in Web IDE"
msgstr ""
+msgid "Edit in pipeline editor"
+msgstr ""
+
msgid "Edit in single-file editor"
msgstr ""
@@ -13053,6 +13268,9 @@ msgstr ""
msgid "Edit your most recent comment in a thread (from an empty textarea)"
msgstr ""
+msgid "Edit, lint, and visualize your pipeline."
+msgstr ""
+
msgid "Edited"
msgstr ""
@@ -13494,6 +13712,9 @@ msgstr ""
msgid "Enforce two-factor authentication for all user sign-ins."
msgstr ""
+msgid "Enhance security by storing service account keys in secret managers - learn more about %{docLinkStart}secret management with GitLab%{docLinkEnd}"
+msgstr ""
+
msgid "Ensure connectivity is available from the GitLab server to the Prometheus server"
msgstr ""
@@ -13554,6 +13775,9 @@ 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 following to confirm:"
+msgstr ""
+
msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
@@ -14084,9 +14308,6 @@ 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 ""
@@ -14222,6 +14443,9 @@ msgstr ""
msgid "Errors:"
msgstr ""
+msgid "Escalate this incident"
+msgstr ""
+
msgid "Escalation Policies"
msgstr ""
@@ -14234,6 +14458,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy"
+msgstr ""
+
msgid "Escalation policy:"
msgstr ""
@@ -14485,6 +14712,9 @@ msgstr ""
msgid "Existing sign in methods may be removed"
msgstr ""
+msgid "Exit."
+msgstr ""
+
msgid "Expand"
msgstr ""
@@ -14581,6 +14811,9 @@ msgstr ""
msgid "Explore public groups"
msgstr ""
+msgid "Explore public projects"
+msgstr ""
+
msgid "Explore snippets"
msgstr ""
@@ -14742,7 +14975,7 @@ msgid_plural "Failed to archive designs. Please try again."
msgstr[0] ""
msgstr[1] ""
-msgid "Failed to assign a reviewer because no user was found."
+msgid "Failed to assign a reviewer because no user was specified."
msgstr ""
msgid "Failed to assign a user because no user was found."
@@ -14808,10 +15041,10 @@ msgstr ""
msgid "Failed to find import label for Jira import."
msgstr ""
-msgid "Failed to generate export, please try again later."
+msgid "Failed to find users for %{missing}"
msgstr ""
-msgid "Failed to generate report, please try again after sometime"
+msgid "Failed to generate export, please try again later."
msgstr ""
msgid "Failed to get ref."
@@ -14910,6 +15143,9 @@ msgstr ""
msgid "Failed to remove a to-do item for the design."
msgstr ""
+msgid "Failed to remove attention because no user was found."
+msgstr ""
+
msgid "Failed to remove mirror."
msgstr ""
@@ -14922,6 +15158,9 @@ msgstr ""
msgid "Failed to remove user key."
msgstr ""
+msgid "Failed to request attention because no user was found."
+msgstr ""
+
msgid "Failed to reset key. Please try again."
msgstr ""
@@ -15003,6 +15242,9 @@ msgstr ""
msgid "Feature Flags"
msgstr ""
+msgid "Feature deprecation and removal"
+msgstr ""
+
msgid "Feature flag status"
msgstr ""
@@ -15500,7 +15742,7 @@ msgstr ""
msgid "For each job, re-use the project workspace. If the workspace doesn't exist, use %{code_open}git clone%{code_close}."
msgstr ""
-msgid "For example, the application using the token or the purpose of the token."
+msgid "For example, the application using the token or the purpose of the token. Do not give sensitive information for the name of the token, as it will be visible to all %{resource_type} members."
msgstr ""
msgid "For files larger than this limit, only index the file name. The file content is neither indexed nor searchable."
@@ -15584,9 +15826,6 @@ msgstr ""
msgid "ForkProject|Select a namespace"
msgstr ""
-msgid "ForkProject|Select a namespace to fork the project"
-msgstr ""
-
msgid "ForkProject|The project can be accessed by any logged in user."
msgstr ""
@@ -15683,6 +15922,9 @@ msgstr ""
msgid "Full name"
msgstr ""
+msgid "GCP region configured"
+msgstr ""
+
msgid "GPG Key ID:"
msgstr ""
@@ -15863,6 +16105,9 @@ msgstr ""
msgid "Geo|Failed"
msgstr ""
+msgid "Geo|Filter Geo sites"
+msgstr ""
+
msgid "Geo|Filter by name"
msgstr ""
@@ -16274,6 +16519,12 @@ msgstr ""
msgid "GitLab Issue"
msgstr ""
+msgid "GitLab KAS"
+msgstr ""
+
+msgid "GitLab Memberships CSV Export"
+msgstr ""
+
msgid "GitLab Pages"
msgstr ""
@@ -16322,6 +16573,9 @@ 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 free to use. Many features for larger teams are part of our %{link_start}paid products%{link_end}. You can try Ultimate for free without any obligation or payment details."
+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 ""
@@ -16448,7 +16702,7 @@ msgstr ""
msgid "GitLabPages|When enabled, all attempts to visit your website through HTTP are automatically redirected to HTTPS using a response with status code 301. Requires a valid certificate for all domains. %{docs_link_start}Learn more.%{link_end}"
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. %{docs_link_start}Learn more.%{link_end}"
+msgid "GitLabPages|When using Pages under the general domain of a GitLab instance (%{pages_host}), you cannot use HTTPS with subdomains of subdomains. If your namespace or groupname contains a dot, it does not work. This is a limitation of the HTTP Over TLS protocol. HTTP pages work if you don't redirect HTTP to HTTPS. %{docs_link_start}Learn more.%{link_end}"
msgstr ""
msgid "GitLabPages|With GitLab Pages you can host your static website directly from your GitLab repository. %{docs_link_start}Learn more.%{link_end}"
@@ -16625,9 +16879,6 @@ msgstr ""
msgid "Go to find file"
msgstr ""
-msgid "Go to fork"
-msgstr ""
-
msgid "Go to issue boards"
msgstr ""
@@ -16835,9 +17086,6 @@ msgstr ""
msgid "Group Hooks"
msgstr ""
-msgid "Group ID"
-msgstr ""
-
msgid "Group Owner must have signed in with SAML before enabling Group Managed Accounts"
msgstr ""
@@ -16865,9 +17113,6 @@ msgstr ""
msgid "Group by"
msgstr ""
-msgid "Group description"
-msgstr ""
-
msgid "Group description (optional)"
msgstr ""
@@ -16982,7 +17227,7 @@ msgstr ""
msgid "Group: %{name}"
msgstr ""
-msgid "GroupActivityMetrics|Issues opened"
+msgid "GroupActivityMetrics|Issues created"
msgstr ""
msgid "GroupActivityMetrics|Last 90 days"
@@ -16991,7 +17236,7 @@ msgstr ""
msgid "GroupActivityMetrics|Members added"
msgstr ""
-msgid "GroupActivityMetrics|Merge Requests opened"
+msgid "GroupActivityMetrics|Merge Requests created"
msgstr ""
msgid "GroupActivityMetrics|Recent activity"
@@ -17282,6 +17527,9 @@ msgstr ""
msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
+msgid "GroupSettings|Choose a group path that does not start with a dash or end with a period. It can also contain alphanumeric characters and underscores."
+msgstr ""
+
msgid "GroupSettings|Compliance frameworks"
msgstr ""
@@ -17315,7 +17563,7 @@ msgstr ""
msgid "GroupSettings|If not specified at the group or instance level, the default is %{default_initial_branch_name}. Does not affect existing repositories."
msgstr ""
-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."
+msgid "GroupSettings|If the parent group's visibility is lower than the group's current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility."
msgstr ""
msgid "GroupSettings|New runners registration token has been generated!"
@@ -17432,7 +17680,10 @@ msgstr ""
msgid "Groups and projects"
msgstr ""
-msgid "Groups and subgroups"
+msgid "Groups are a great way to organize projects and people."
+msgstr ""
+
+msgid "Groups are the best way to manage projects and members."
msgstr ""
msgid "Groups to synchronize"
@@ -17543,13 +17794,16 @@ msgstr ""
msgid "GroupsTree|Are you sure you want to leave the \"%{fullName}\" group?"
msgstr ""
-msgid "GroupsTree|Edit group"
+msgid "GroupsTree|Delete"
+msgstr ""
+
+msgid "GroupsTree|Edit"
msgstr ""
msgid "GroupsTree|Failed to leave the group. Please make sure you are not the only owner."
msgstr ""
-msgid "GroupsTree|Leave this group"
+msgid "GroupsTree|Leave group"
msgstr ""
msgid "GroupsTree|Loading groups"
@@ -17561,9 +17815,57 @@ msgstr ""
msgid "GroupsTree|No groups or projects matched your search"
msgstr ""
+msgid "GroupsTree|Options"
+msgstr ""
+
msgid "GroupsTree|Search by name"
msgstr ""
+msgid "Groups|Avatar will be removed. Are you sure?"
+msgstr ""
+
+msgid "Groups|Changing group URL can have unintended side effects."
+msgstr ""
+
+msgid "Groups|Checking group URL availability..."
+msgstr ""
+
+msgid "Groups|Enter a descriptive name for your group."
+msgstr ""
+
+msgid "Groups|Group ID"
+msgstr ""
+
+msgid "Groups|Group URL"
+msgstr ""
+
+msgid "Groups|Group avatar"
+msgstr ""
+
+msgid "Groups|Group description (optional)"
+msgstr ""
+
+msgid "Groups|Group name"
+msgstr ""
+
+msgid "Groups|Group path is available."
+msgstr ""
+
+msgid "Groups|Group path is unavailable. Path has been replaced with a suggested available path."
+msgstr ""
+
+msgid "Groups|Learn more"
+msgstr ""
+
+msgid "Groups|Must start with letter, digit, emoji, or underscore. Can also contain periods, dashes, spaces, and parentheses."
+msgstr ""
+
+msgid "Groups|Remove avatar"
+msgstr ""
+
+msgid "Groups|Save changes"
+msgstr ""
+
msgid "Guideline"
msgstr ""
@@ -17573,6 +17875,9 @@ msgstr ""
msgid "HAR file path or URL"
msgstr ""
+msgid "HTTP Archive (HAR)"
+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 ""
@@ -17973,6 +18278,9 @@ msgstr ""
msgid "INFO: Your SSH key is expiring soon. Please generate a new key."
msgstr ""
+msgid "IP"
+msgstr ""
+
msgid "IP Address"
msgstr ""
@@ -18009,6 +18317,9 @@ msgstr ""
msgid "IdentityVerification|Verify your identity"
msgstr ""
+msgid "IdentityVerification|You can always verify your account at a later time to create a group."
+msgstr ""
+
msgid "If any indexed field exceeds this limit, it is truncated to this number of characters. The rest of the content is neither indexed nor searchable. This does not apply to repository and wiki indexing. For unlimited characters, set this to 0."
msgstr ""
@@ -18066,6 +18377,9 @@ msgstr ""
msgid "If you add %{codeStart}needs%{codeEnd} to jobs in your pipeline you'll be able to view the %{codeStart}needs%{codeEnd} relationships between jobs in this tab as a %{linkStart}Directed Acyclic Graph (DAG)%{linkEnd}."
msgstr ""
+msgid "If you are added to a project, it will be displayed here."
+msgstr ""
+
msgid "If you did not initiate these sign-in attempts, please reach out to your administrator or enable two-factor authentication (2FA) on your account."
msgstr ""
@@ -18372,12 +18686,24 @@ msgstr ""
msgid "InProductMarketing|3 ways to dive into GitLab CI/CD"
msgstr ""
+msgid "InProductMarketing|A single application eliminates complex integrations, data chokepoints, and toolchain maintenance, resulting in greater productivity and lower cost."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features, build more efficiently, strengthen security and compliance."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features."
+msgstr ""
+
msgid "InProductMarketing|Actually, GitLab makes the team work (better)"
msgstr ""
msgid "InProductMarketing|And finally %{deploy_link} a Python application."
msgstr ""
+msgid "InProductMarketing|And many more..."
+msgstr ""
+
msgid "InProductMarketing|Are your runners ready?"
msgstr ""
@@ -18396,15 +18722,33 @@ msgstr ""
msgid "InProductMarketing|Blog"
msgstr ""
+msgid "InProductMarketing|Break down silos to coordinate seamlessly across development, operations, and security with a consistent experience across the development lifecycle."
+msgstr ""
+
+msgid "InProductMarketing|Burn up/down charts"
+msgstr ""
+
msgid "InProductMarketing|By enabling code owners and required merge approvals the right person will review the right MR. This is a win-win: cleaner code and a more efficient review process."
msgstr ""
msgid "InProductMarketing|Click on the number below that corresponds with your answer — 1 being very difficult, 5 being very easy."
msgstr ""
+msgid "InProductMarketing|Code owners"
+msgstr ""
+
msgid "InProductMarketing|Code owners and required merge approvals are part of the paid tiers of GitLab. You can start a free 30-day trial of GitLab Ultimate and enable these features in less than 5 minutes with no credit card required."
msgstr ""
+msgid "InProductMarketing|Code review analytics"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration across stages in GitLab"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration made easy"
+msgstr ""
+
msgid "InProductMarketing|Create a custom CI runner with just a few clicks"
msgstr ""
@@ -18414,12 +18758,21 @@ msgstr ""
msgid "InProductMarketing|Create a project in GitLab in 5 minutes"
msgstr ""
+msgid "InProductMarketing|Create well-defined workflows by using scoped labels on issues, merge requests, and epics. Labels with the same scope cannot be used together, which prevents conflicts."
+msgstr ""
+
msgid "InProductMarketing|Create your first project!"
msgstr ""
+msgid "InProductMarketing|Define who owns specific files or directories, so the right reviewers are suggested when a merge request introduces changes to those files."
+msgstr ""
+
msgid "InProductMarketing|Deliver Better Products Faster"
msgstr ""
+msgid "InProductMarketing|Dependency scanning"
+msgstr ""
+
msgid "InProductMarketing|Did you know teams that use GitLab are far more efficient?"
msgstr ""
@@ -18429,15 +18782,27 @@ msgstr ""
msgid "InProductMarketing|Dig in and create a project and a repo"
msgstr ""
+msgid "InProductMarketing|Discover Premium & Ultimate"
+msgstr ""
+
+msgid "InProductMarketing|Discover Premium & Ultimate."
+msgstr ""
+
msgid "InProductMarketing|Do you have a minute?"
msgstr ""
msgid "InProductMarketing|Do you have a teammate who would be perfect for this task?"
msgstr ""
+msgid "InProductMarketing|Dynamic application security testing"
+msgstr ""
+
msgid "InProductMarketing|Easy"
msgstr ""
+msgid "InProductMarketing|Epics"
+msgstr ""
+
msgid "InProductMarketing|Expand your DevOps journey with a free GitLab trial"
msgstr ""
@@ -18459,9 +18824,15 @@ msgstr ""
msgid "InProductMarketing|Feel the need for speed?"
msgstr ""
+msgid "InProductMarketing|Find and fix bottlenecks in your code review process by understanding how long open merge requests have been in review."
+msgstr ""
+
msgid "InProductMarketing|Find out how your teams are really doing"
msgstr ""
+msgid "InProductMarketing|Find out if your external libraries are safe. Run dependency scanning jobs that check for known vulnerabilities in your external libraries."
+msgstr ""
+
msgid "InProductMarketing|Follow our steps"
msgstr ""
@@ -18498,6 +18869,9 @@ msgstr ""
msgid "InProductMarketing|GitLab is better with teammates to help out!"
msgstr ""
+msgid "InProductMarketing|GitLab is infrastructure agnostic (supporting GCP, AWS, Azure, OpenShift, VMWare, On Prem, Bare Metal, and more), offering a consistent workflow experience – irrespective of the environment."
+msgstr ""
+
msgid "InProductMarketing|GitLab provides static application security testing (SAST), dynamic application security testing (DAST), container scanning, and dependency scanning to help you deliver secure applications along with license compliance."
msgstr ""
@@ -18588,21 +18962,36 @@ msgstr ""
msgid "InProductMarketing|It's also possible to simply %{external_repo_link} in order to take advantage of GitLab's CI/CD."
msgstr ""
+msgid "InProductMarketing|Keep your code quality high by defining who should approve merge requests and how many approvals are required."
+msgstr ""
+
msgid "InProductMarketing|Launch GitLab CI/CD in 20 minutes or less"
msgstr ""
+msgid "InProductMarketing|Lower cost of development"
+msgstr ""
+
+msgid "InProductMarketing|Make it easier to collaborate on high-level ideas by grouping related issues in an epic."
+msgstr ""
+
msgid "InProductMarketing|Making the switch? It's easier than you think to import your projects into GitLab. Move %{github_link}, or import something %{bitbucket_link}."
msgstr ""
msgid "InProductMarketing|Master the art of importing!"
msgstr ""
+msgid "InProductMarketing|Merge request approval rule"
+msgstr ""
+
msgid "InProductMarketing|Move on to easily creating a Pages website %{ci_template_link}"
msgstr ""
msgid "InProductMarketing|Multiple owners, confusing workstreams? We've got you covered"
msgstr ""
+msgid "InProductMarketing|Multiple required approvers"
+msgstr ""
+
msgid "InProductMarketing|Need an alternative to importing?"
msgstr ""
@@ -18615,18 +19004,33 @@ msgstr ""
msgid "InProductMarketing|Our tool brings all the things together"
msgstr ""
+msgid "InProductMarketing|Protect your web application by using DAST to examine for vulnerabilities in deployed environments."
+msgstr ""
+
msgid "InProductMarketing|Rapid development, simplified"
msgstr ""
msgid "InProductMarketing|Reduce Security & Compliance Risk"
msgstr ""
+msgid "InProductMarketing|Require multiple approvers on a merge request, so you know it's in good shape before it's merged."
+msgstr ""
+
+msgid "InProductMarketing|Roadmaps"
+msgstr ""
+
+msgid "InProductMarketing|Scoped labels"
+msgstr ""
+
msgid "InProductMarketing|Security that's integrated into your development lifecycle"
msgstr ""
msgid "InProductMarketing|Sometimes you're not ready to make a full transition to a new tool. If you're not ready to fully commit, %{mirroring_link} gives you a safe way to try out GitLab in parallel with your current tool."
msgstr ""
+msgid "InProductMarketing|Speed. Efficiency. Trust."
+msgstr ""
+
msgid "InProductMarketing|Spin up an autoscaling runner in GitLab"
msgstr ""
@@ -18636,6 +19040,9 @@ msgstr ""
msgid "InProductMarketing|Start a Self-Managed trial"
msgstr ""
+msgid "InProductMarketing|Start a free trial"
+msgstr ""
+
msgid "InProductMarketing|Start a free trial of GitLab Ultimate – no credit card required"
msgstr ""
@@ -18702,6 +19109,9 @@ msgstr ""
msgid "InProductMarketing|To understand and get the most out of GitLab, start at the beginning and %{project_link}. In GitLab, repositories are part of a project, so after you've created your project you can go ahead and %{repo_link}."
msgstr ""
+msgid "InProductMarketing|Track completed issues in a chart, so you can see how a milestone is progressing at a glance."
+msgstr ""
+
msgid "InProductMarketing|Try GitLab Ultimate for free"
msgstr ""
@@ -18738,6 +19148,9 @@ msgstr ""
msgid "InProductMarketing|Very easy"
msgstr ""
+msgid "InProductMarketing|Visualize your epics and milestones in a timeline."
+msgstr ""
+
msgid "InProductMarketing|Want to host GitLab on your servers?"
msgstr ""
@@ -18759,6 +19172,9 @@ msgstr ""
msgid "InProductMarketing|YouTube"
msgstr ""
+msgid "InProductMarketing|Your software, deployed your way"
+msgstr ""
+
msgid "InProductMarketing|Your teams can be more efficient"
msgstr ""
@@ -18879,9 +19295,18 @@ msgstr ""
msgid "IncidentManagement|No incidents to display."
msgstr ""
+msgid "IncidentManagement|None"
+msgstr ""
+
msgid "IncidentManagement|Open"
msgstr ""
+msgid "IncidentManagement|Page your team with escalation policies"
+msgstr ""
+
+msgid "IncidentManagement|Paged"
+msgstr ""
+
msgid "IncidentManagement|Published"
msgstr ""
@@ -18891,6 +19316,9 @@ msgstr ""
msgid "IncidentManagement|Severity"
msgstr ""
+msgid "IncidentManagement|Status"
+msgstr ""
+
msgid "IncidentManagement|There are no closed incidents"
msgstr ""
@@ -18909,6 +19337,9 @@ msgstr ""
msgid "IncidentManagement|Unpublished"
msgstr ""
+msgid "IncidentManagement|Use escalation policies to automatically page your team when incidents are created."
+msgstr ""
+
msgid "IncidentSettings|Activate \"time to SLA\" countdown timer"
msgstr ""
@@ -18954,7 +19385,10 @@ msgstr ""
msgid "Incidents"
msgstr ""
-msgid "Incidents|Add a URL"
+msgid "Incidents|Add image details"
+msgstr ""
+
+msgid "Incidents|Add text or a link to display with your image. If you don't add either, the file name displays instead."
msgstr ""
msgid "Incidents|Drop or %{linkStart}upload%{linkEnd} a metric screenshot to attach it to the incident"
@@ -18969,10 +19403,10 @@ msgstr ""
msgid "Incidents|There was an issue loading metric images."
msgstr ""
-msgid "Incidents|There was an issue uploading your image."
+msgid "Incidents|There was an issue updating your image."
msgstr ""
-msgid "Incidents|You can optionally add a URL to link users to the original graph."
+msgid "Incidents|There was an issue uploading your image."
msgstr ""
msgid "Incident|Alert details"
@@ -18981,9 +19415,18 @@ msgstr ""
msgid "Incident|Are you sure you wish to delete this image?"
msgstr ""
+msgid "Incident|Delete image"
+msgstr ""
+
msgid "Incident|Deleting %{filename}"
msgstr ""
+msgid "Incident|Edit image text or link"
+msgstr ""
+
+msgid "Incident|Editing %{filename}"
+msgstr ""
+
msgid "Incident|Metrics"
msgstr ""
@@ -19253,12 +19696,18 @@ msgstr ""
msgid "Integrations|Branches for which notifications are to be sent"
msgstr ""
+msgid "Integrations|Clear if using a self-signed certificate."
+msgstr ""
+
msgid "Integrations|Comment detail:"
msgstr ""
msgid "Integrations|Comment settings:"
msgstr ""
+msgid "Integrations|Connection details"
+msgstr ""
+
msgid "Integrations|Connection failed. Please check your settings."
msgstr ""
@@ -19283,6 +19732,9 @@ msgstr ""
msgid "Integrations|Enable GitLab.com slash commands in a Slack workspace."
msgstr ""
+msgid "Integrations|Enable SSL verification"
+msgstr ""
+
msgid "Integrations|Enable comments"
msgstr ""
@@ -19361,6 +19813,9 @@ msgstr ""
msgid "Integrations|Return to GitLab for Jira"
msgstr ""
+msgid "Integrations|SSL verification"
+msgstr ""
+
msgid "Integrations|Save settings?"
msgstr ""
@@ -19406,9 +19861,6 @@ msgstr ""
msgid "Integrations|Use default settings"
msgstr ""
-msgid "Integrations|When you mention a Jira issue in a commit or merge request, GitLab creates a remote link and comment (if enabled)."
-msgstr ""
-
msgid "Integrations|You can now close this window and return to the GitLab for Jira application."
msgstr ""
@@ -19433,9 +19885,6 @@ msgstr ""
msgid "Integrations|can't exceed %{recipients_limit}"
msgstr ""
-msgid "Interactive developer security education."
-msgstr ""
-
msgid "Interactive mode"
msgstr ""
@@ -19925,6 +20374,9 @@ msgstr ""
msgid "IssueAnalytics|Assignees"
msgstr ""
+msgid "IssueAnalytics|Created by"
+msgstr ""
+
msgid "IssueAnalytics|Due date"
msgstr ""
@@ -19937,9 +20389,6 @@ msgstr ""
msgid "IssueAnalytics|Milestone"
msgstr ""
-msgid "IssueAnalytics|Opened by"
-msgstr ""
-
msgid "IssueAnalytics|Status"
msgstr ""
@@ -20063,10 +20512,10 @@ msgstr ""
msgid "IssuesAnalytics|Avg/Month:"
msgstr ""
-msgid "IssuesAnalytics|Issues opened"
+msgid "IssuesAnalytics|Issues created"
msgstr ""
-msgid "IssuesAnalytics|Issues opened per month"
+msgid "IssuesAnalytics|Issues created per month"
msgstr ""
msgid "IssuesAnalytics|Last 12 months"
@@ -20093,6 +20542,9 @@ msgstr ""
msgid "It looks like you have some draft commits in this branch."
msgstr ""
+msgid "It looks like you're attempting to activate your subscription. Use %{a_start}the Subscription page%{a_end} instead."
+msgstr ""
+
msgid "It may be several days before you see feature usage data."
msgstr ""
@@ -20321,6 +20773,9 @@ msgstr ""
msgid "JiraConnect|You can now close this window and return to Jira."
msgstr ""
+msgid "JiraConnect|You don't have permission to create branches for this project. Select a different project or contact the project owner for access. %{linkStart}Learn more.%{linkEnd}"
+msgstr ""
+
msgid "JiraRequest|A connection error occurred while connecting to Jira. Try your request again."
msgstr ""
@@ -20369,13 +20824,13 @@ msgstr ""
msgid "JiraService|Define the type of Jira issue to create from a vulnerability."
msgstr ""
-msgid "JiraService|Displaying Jira issues while leaving the GitLab issue functionality enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
+msgid "JiraService|Displaying Jira issues while leaving GitLab issues also enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
msgstr ""
-msgid "JiraService|Enable Jira issues"
+msgid "JiraService|Enable Jira issue creation from vulnerabilities"
msgstr ""
-msgid "JiraService|Enable Jira issues creation from vulnerabilities"
+msgid "JiraService|Enable Jira issues"
msgstr ""
msgid "JiraService|Enable Jira transitions"
@@ -20492,16 +20947,19 @@ msgstr ""
msgid "JiraService|View Jira issues in GitLab"
msgstr ""
-msgid "JiraService|Warning: All GitLab users that have access to this GitLab project are able to view all issues from the Jira project specified below."
+msgid "JiraService|Warning: All GitLab users with access to this GitLab project can view all issues from the Jira project you select."
msgstr ""
msgid "JiraService|Web URL"
msgstr ""
-msgid "JiraService|Work on Jira issues without leaving GitLab. Adds a Jira menu to access your list of Jira issues and view any issue as read-only."
+msgid "JiraService|When a Jira issue is mentioned in a commit or merge request, a remote link and comment (if enabled) will be created."
+msgstr ""
+
+msgid "JiraService|Work on Jira issues without leaving GitLab. Add a Jira menu to access a read-only list of your Jira issues."
msgstr ""
-msgid "JiraService|You need to configure Jira before enabling this integration. For more details, read the %{jira_doc_link_start}Jira integration documentation%{link_end}."
+msgid "JiraService|You must configure Jira before enabling this integration. %{jira_doc_link_start}Learn more.%{link_end}"
msgstr ""
msgid "Job"
@@ -20513,9 +20971,6 @@ msgstr ""
msgid "Job Failed #%{build_id}"
msgstr ""
-msgid "Job ID"
-msgstr ""
-
msgid "Job artifact"
msgstr ""
@@ -20582,9 +21037,27 @@ msgstr ""
msgid "Jobs|You're about to retry a job that failed because it attempted to deploy code that is older than the latest deployment. Retrying this job could result in overwriting the environment with the older source code."
msgstr ""
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source} into %{target}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{ref}"
+msgstr ""
+
+msgid "Job|Are you sure you want to erase this job log and artifacts?"
+msgstr ""
+
msgid "Job|Browse"
msgstr ""
+msgid "Job|Cancel"
+msgstr ""
+
msgid "Job|Complete Raw"
msgstr ""
@@ -20594,6 +21067,9 @@ msgstr ""
msgid "Job|Erase job log and artifacts"
msgstr ""
+msgid "Job|Finished at"
+msgstr ""
+
msgid "Job|Job artifacts"
msgstr ""
@@ -20606,7 +21082,7 @@ msgstr ""
msgid "Job|Keep"
msgstr ""
-msgid "Job|Pipeline"
+msgid "Job|Retry"
msgstr ""
msgid "Job|Scroll to bottom"
@@ -20618,6 +21094,9 @@ msgstr ""
msgid "Job|Show complete raw"
msgstr ""
+msgid "Job|Status"
+msgstr ""
+
msgid "Job|The artifacts were removed"
msgstr ""
@@ -20645,21 +21124,12 @@ msgstr ""
msgid "Job|delayed"
msgstr ""
-msgid "Job|for"
-msgstr ""
-
-msgid "Job|into"
-msgstr ""
-
msgid "Job|manual"
msgstr ""
msgid "Job|triggered"
msgstr ""
-msgid "Job|with"
-msgstr ""
-
msgid "Join Zoom meeting"
msgstr ""
@@ -20762,9 +21232,6 @@ msgstr ""
msgid "Ki"
msgstr ""
-msgid "Kontra"
-msgstr ""
-
msgid "Kroki"
msgstr ""
@@ -21088,6 +21555,9 @@ msgstr ""
msgid "Learn more about Auto DevOps"
msgstr ""
+msgid "Learn more about GitLab"
+msgstr ""
+
msgid "Learn more about Needs relationships"
msgstr ""
@@ -21415,9 +21885,18 @@ msgstr ""
msgid "Licenses|Displays licenses detected in the project, based on the %{linkStart}latest successful%{linkEnd} scan"
msgstr ""
+msgid "Licenses|Drag your license file here or %{linkStart}click to upload%{linkEnd}."
+msgstr ""
+
+msgid "Licenses|Drop your license file to start the upload."
+msgstr ""
+
msgid "Licenses|Error fetching the license list. Please check your network connection and try again."
msgstr ""
+msgid "Licenses|Error: You are trying to upload something other than a file"
+msgstr ""
+
msgid "Licenses|License Compliance"
msgstr ""
@@ -21436,6 +21915,9 @@ msgstr ""
msgid "Licenses|Specified policies in this project"
msgstr ""
+msgid "Licenses|The file could not be uploaded."
+msgstr ""
+
msgid "Licenses|The license list details information about the licenses used within your project."
msgstr ""
@@ -21469,11 +21951,6 @@ msgstr ""
msgid "Limit the size of Sidekiq jobs stored in Redis."
msgstr ""
-msgid "Limited to showing %d event at most"
-msgid_plural "Limited to showing %d events at most"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Limiting mode"
msgstr ""
@@ -21483,6 +21960,9 @@ msgstr ""
msgid "Link"
msgstr ""
+msgid "Link (optional)"
+msgstr ""
+
msgid "Link Prometheus monitoring to GitLab."
msgstr ""
@@ -21519,6 +21999,9 @@ msgstr ""
msgid "Linked emails (%{email_count})"
msgstr ""
+msgid "Linked epics"
+msgstr ""
+
msgid "Linked issues"
msgstr ""
@@ -21546,6 +22029,15 @@ msgstr ""
msgid "List of all merge commits"
msgstr ""
+msgid "List of environments for this project"
+msgstr ""
+
+msgid "List of suitable GCP locations"
+msgstr ""
+
+msgid "List of users allowed to exceed the rate limit."
+msgstr ""
+
msgid "List options"
msgstr ""
@@ -21765,6 +22257,9 @@ msgstr ""
msgid "Maintenance mode"
msgstr ""
+msgid "Make adjustments to how your GitLab instance is set up."
+msgstr ""
+
msgid "Make and review changes in the browser with the Web IDE"
msgstr ""
@@ -21909,6 +22404,12 @@ msgstr ""
msgid "MarkdownEditor|Add italic text (%{modifier_key}I)"
msgstr ""
+msgid "MarkdownEditor|Add strikethrough text (%{modifierKey}⇧X)"
+msgstr ""
+
+msgid "MarkdownEditor|Add strikethrough text (%{modifier_key}⇧X)"
+msgstr ""
+
msgid "Marked For Deletion At - %{deletion_time}"
msgstr ""
@@ -22170,6 +22671,9 @@ msgstr ""
msgid "Maximum push size (MB)"
msgstr ""
+msgid "Maximum requests per 10 minutes per user"
+msgstr ""
+
msgid "Maximum requests per minute"
msgstr ""
@@ -22260,6 +22764,19 @@ msgstr ""
msgid "Members of a group may only view projects they have permission to access"
msgstr ""
+msgid "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seat in use and will be billed for the overage."
+msgid_plural "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seats in use and will be billed for the overage."
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "MembersOverage|You are about to incur additional charges"
+msgstr ""
+
+msgid "MembersOverage|Your subscription includes %d seat."
+msgid_plural "MembersOverage|Your subscription includes %d seats."
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Membership"
msgstr ""
@@ -22464,9 +22981,6 @@ msgstr ""
msgid "Merge request not merged"
msgstr ""
-msgid "Merge request pipelines 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 merge request pipelines."
-msgstr ""
-
msgid "Merge request reports"
msgstr ""
@@ -22563,13 +23077,13 @@ msgstr ""
msgid "MergeRequests|Create issue to resolve thread"
msgstr ""
-msgid "MergeRequests|Failed to squash. Should be done manually."
+msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Saving the comment failed"
+msgid "MergeRequests|Squashing failed: Squash the commits locally, resolve any conflicts, then push the branch."
msgstr ""
-msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
+msgid "MergeRequests|Squashing not allowed: This project doesn't allow you to squash commits when merging."
msgstr ""
msgid "MergeRequests|Thread stays resolved"
@@ -23410,6 +23924,18 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "MrList|Assigned to %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from assignee %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from reviewer %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Review requested from %{name}, go to their profile."
+msgstr ""
+
msgid "Multi-project"
msgstr ""
@@ -23443,7 +23969,7 @@ msgstr ""
msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "My Awesome Group"
+msgid "My awesome group"
msgstr ""
msgid "My company or team"
@@ -24065,9 +24591,6 @@ msgstr ""
msgid "No available branches"
msgstr ""
-msgid "No available groups to fork the project."
-msgstr ""
-
msgid "No branches found"
msgstr ""
@@ -24278,6 +24801,9 @@ msgstr ""
msgid "No ref selected"
msgstr ""
+msgid "No regions configured"
+msgstr ""
+
msgid "No related merge requests found."
msgstr ""
@@ -25082,6 +25608,9 @@ msgstr ""
msgid "Only reCAPTCHA v2 is supported:"
msgstr ""
+msgid "Only required if not using role instance credentials."
+msgstr ""
+
msgid "Only use lowercase letters, numbers, and underscores."
msgstr ""
@@ -25106,9 +25635,6 @@ msgstr ""
msgid "Open a CLI and connect to the cluster you want to install the agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
-msgid "Open epics"
-msgstr ""
-
msgid "Open errors"
msgstr ""
@@ -25148,7 +25674,7 @@ msgstr ""
msgid "Opened issues"
msgstr ""
-msgid "OpenedNDaysAgo|Opened"
+msgid "OpenedNDaysAgo|Created"
msgstr ""
msgid "Opens in a new window"
@@ -25193,9 +25719,6 @@ msgstr ""
msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
-msgid "Optional."
-msgstr ""
-
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
msgstr ""
@@ -25984,6 +26507,9 @@ msgstr ""
msgid "PerformanceBar|Memory"
msgstr ""
+msgid "PerformanceBar|Memory report"
+msgstr ""
+
msgid "PerformanceBar|Redis calls"
msgstr ""
@@ -26017,18 +26543,12 @@ msgstr ""
msgid "PerformanceBar|wall"
msgstr ""
-msgid "Performs a rebase but skips triggering a new pipeline"
-msgstr ""
-
msgid "Period in seconds"
msgstr ""
msgid "Permalink"
msgstr ""
-msgid "Permanently delete project"
-msgstr ""
-
msgid "Permanently remove group"
msgstr ""
@@ -26299,6 +26819,51 @@ msgstr ""
msgid "PipelineStatusTooltip|Pipeline: %{ci_status}"
msgstr ""
+msgid "PipelineWizardDefaultCommitMessage|Add %{filename}"
+msgstr ""
+
+msgid "PipelineWizardDefaultCommitMessage|Update %{filename}"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|At least one entry is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This field is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This value is not valid"
+msgstr ""
+
+msgid "PipelineWizardListWidget|add another step"
+msgstr ""
+
+msgid "PipelineWizardListWidget|remove step"
+msgstr ""
+
+msgid "PipelineWizard|Commit"
+msgstr ""
+
+msgid "PipelineWizard|Commit Message"
+msgstr ""
+
+msgid "PipelineWizard|Commit changes to your file"
+msgstr ""
+
+msgid "PipelineWizard|Commit file to Branch"
+msgstr ""
+
+msgid "PipelineWizard|Commit your new file"
+msgstr ""
+
+msgid "PipelineWizard|The file has been committed."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem committing the changes."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem while checking whether your file already exists in the specified branch."
+msgstr ""
+
msgid "Pipelines"
msgstr ""
@@ -26413,7 +26978,7 @@ msgstr ""
msgid "Pipelines|Project cache successfully reset."
msgstr ""
-msgid "Pipelines|Revoke"
+msgid "Pipelines|Revoke trigger"
msgstr ""
msgid "Pipelines|Something went wrong while cleaning runners cache."
@@ -26458,6 +27023,12 @@ msgstr ""
msgid "Pipelines|This is a child pipeline within the parent pipeline"
msgstr ""
+msgid "Pipelines|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipelines|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipelines|This pipeline will run code originating from a forked project merge request. This means that the code can potentially have security considerations like exposing CI variables."
msgstr ""
@@ -26500,9 +27071,6 @@ msgstr ""
msgid "Pipelines|Your changes have been successfully committed. Now redirecting to the new merge request page."
msgstr ""
-msgid "Pipelines|detached"
-msgstr ""
-
msgid "Pipelines|error"
msgstr ""
@@ -26512,10 +27080,13 @@ msgstr ""
msgid "Pipelines|latest"
msgstr ""
-msgid "Pipelines|stuck"
+msgid "Pipelines|merge request"
msgstr ""
-msgid "Pipelines|train"
+msgid "Pipelines|merge train"
+msgstr ""
+
+msgid "Pipelines|stuck"
msgstr ""
msgid "Pipelines|yaml invalid"
@@ -26647,6 +27218,12 @@ msgstr ""
msgid "Pipeline|This change will not change the overall test coverage if merged."
msgstr ""
+msgid "Pipeline|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipeline|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipeline|Trigger author"
msgstr ""
@@ -26671,6 +27248,12 @@ msgstr ""
msgid "Pipeline|for"
msgstr ""
+msgid "Pipeline|merge request"
+msgstr ""
+
+msgid "Pipeline|merge train"
+msgstr ""
+
msgid "Pipeline|on"
msgstr ""
@@ -26809,9 +27392,6 @@ msgstr ""
msgid "Please enter a valid time interval"
msgstr ""
-msgid "Please enter or upload a valid license."
-msgstr ""
-
msgid "Please enter your current password."
msgstr ""
@@ -26920,9 +27500,6 @@ msgstr ""
msgid "Please type %{phrase_code} to proceed or close this modal to cancel."
msgstr ""
-msgid "Please type the following to confirm:"
-msgstr ""
-
msgid "Please use this form to report to the admin users who create spam issues, comments or behave inappropriately."
msgstr ""
@@ -26950,12 +27527,27 @@ msgstr ""
msgid "Policies"
msgstr ""
+msgid "Policy '%{escalation_policy_name}' does not exist."
+msgstr ""
+
msgid "Policy management project does have any policies in %{policy_path}"
msgstr ""
msgid "Policy project doesn't exist"
msgstr ""
+msgid "PolicyRuleMultiSelect|%{firstLabel} +%{numberOfAdditionalLabels} more"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|All %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select all"
+msgstr ""
+
msgid "Polling interval multiplier"
msgstr ""
@@ -27184,6 +27776,9 @@ msgstr ""
msgid "Private projects can be created in your personal namespace with:"
msgstr ""
+msgid "Problem with %{name} command: %{message}."
+msgstr ""
+
msgid "Proceed"
msgstr ""
@@ -27658,6 +28253,9 @@ msgstr ""
msgid "Progress"
msgstr ""
+msgid "Progress tracking"
+msgstr ""
+
msgid "Project"
msgstr ""
@@ -27889,6 +28487,9 @@ msgstr ""
msgid "ProjectQualitySummary|Failure"
msgstr ""
+msgid "ProjectQualitySummary|Get insight into the overall percentage of tests in your project that succeed, fail and are skipped."
+msgstr ""
+
msgid "ProjectQualitySummary|Latest pipeline results"
msgstr ""
@@ -27907,6 +28508,12 @@ msgstr ""
msgid "ProjectQualitySummary|See project Code Coverage Statistics"
msgstr ""
+msgid "ProjectQualitySummary|Set up test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|Set up test runs (opens in a new tab)"
+msgstr ""
+
msgid "ProjectQualitySummary|Skipped"
msgstr ""
@@ -28183,13 +28790,19 @@ msgstr ""
msgid "ProjectSettings|LFS objects from this repository are available to forks. %{linkStart}How do I remove them?%{linkEnd}"
msgstr ""
+msgid "ProjectSettings|Learn about commit history."
+msgstr ""
+
+msgid "ProjectSettings|Leave empty to use default template."
+msgstr ""
+
msgid "ProjectSettings|Manage who can see the project in the public access directory."
msgstr ""
msgid "ProjectSettings|Manages large files such as audio, video, and graphics files."
msgstr ""
-msgid "ProjectSettings|Maximum 500 characters."
+msgid "ProjectSettings|Maximum %{maxLength} characters."
msgstr ""
msgid "ProjectSettings|Merge checks"
@@ -28330,6 +28943,9 @@ msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
msgstr ""
+msgid "ProjectSettings|The default template will be applied on save."
+msgstr ""
+
msgid "ProjectSettings|These checks must pass before merge requests can be merged."
msgstr ""
@@ -28384,6 +29000,9 @@ msgstr ""
msgid "ProjectSettings|What are badges?"
msgstr ""
+msgid "ProjectSettings|What are merge trains?"
+msgstr ""
+
msgid "ProjectSettings|When merge request pipelines are enabled in the CI/CD configuration file, pipelines validate the combined results of the source and target branches. %{link_start}How to configure merge request pipelines?%{link_end}"
msgstr ""
@@ -28501,6 +29120,9 @@ msgstr ""
msgid "Projects are organized into groups"
msgstr ""
+msgid "Projects are where you store your code, access issues, wiki and other features of GitLab."
+msgstr ""
+
msgid "Projects contributed to"
msgstr ""
@@ -28516,12 +29138,6 @@ msgstr ""
msgid "Projects to index"
msgstr ""
-msgid "Projects will be permanently deleted after a %{waiting_period}-day waiting period."
-msgstr ""
-
-msgid "Projects will be permanently deleted immediately."
-msgstr ""
-
msgid "Projects with critical vulnerabilities"
msgstr ""
@@ -28606,6 +29222,9 @@ msgstr ""
msgid "ProjectsNew|Import project"
msgstr ""
+msgid "ProjectsNew|Include a Getting Started README"
+msgstr ""
+
msgid "ProjectsNew|Initialize repository with a README"
msgstr ""
@@ -28621,6 +29240,9 @@ msgstr ""
msgid "ProjectsNew|Project description %{tag_start}(optional)%{tag_end}"
msgstr ""
+msgid "ProjectsNew|Recommended if you're new to GitLab"
+msgstr ""
+
msgid "ProjectsNew|Run CI/CD for external repository"
msgstr ""
@@ -29038,6 +29660,9 @@ msgstr ""
msgid "ProtectedBranch|Unprotect"
msgstr ""
+msgid "ProtectedBranch|Unprotect branch"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
@@ -29065,6 +29690,9 @@ msgstr ""
msgid "ProtectedEnvironment|Protected Environment (%{protected_environments_count})"
msgstr ""
+msgid "ProtectedEnvironment|Required approvals"
+msgstr ""
+
msgid "ProtectedEnvironment|Select an environment"
msgstr ""
@@ -29086,10 +29714,13 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|Unprotect tag"
+msgstr ""
+
msgid "ProtectedTags|default"
msgstr ""
-msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
+msgid "ProtectedTag|By default, protected tags restrict who can modify the tag."
msgstr ""
msgid "ProtectedTag|Learn more."
@@ -29152,6 +29783,9 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Public projects are an easy way to allow everyone to have read-only access."
+msgstr ""
+
msgid "Publish to status page"
msgstr ""
@@ -29308,9 +29942,6 @@ msgstr ""
msgid "QualitySummary|Project quality"
msgstr ""
-msgid "Quarters"
-msgstr ""
-
msgid "Query"
msgstr ""
@@ -29395,6 +30026,9 @@ msgstr ""
msgid "Read more about project permissions %{help_link_open}here%{help_link_close}"
msgstr ""
+msgid "Read more about related epics"
+msgstr ""
+
msgid "Read more about related issues"
msgstr ""
@@ -29425,10 +30059,7 @@ msgstr ""
msgid "Rebase source branch on the target branch."
msgstr ""
-msgid "Rebase without CI"
-msgstr ""
-
-msgid "Rebases and triggers a pipeline"
+msgid "Rebase without pipeline"
msgstr ""
msgid "Recaptcha verified?"
@@ -29479,9 +30110,6 @@ msgstr ""
msgid "Reconfigure"
msgstr ""
-msgid "Recovering projects"
-msgstr ""
-
msgid "Recovery Codes"
msgstr ""
@@ -29541,6 +30169,12 @@ msgstr ""
msgid "Regex pattern"
msgstr ""
+msgid "Region"
+msgstr ""
+
+msgid "Regions"
+msgstr ""
+
msgid "Register"
msgstr ""
@@ -29771,9 +30405,6 @@ msgstr ""
msgid "Remove all or specific reviewer(s)"
msgstr ""
-msgid "Remove approver"
-msgstr ""
-
msgid "Remove approvers"
msgstr ""
@@ -29789,6 +30420,9 @@ msgstr ""
msgid "Remove attention request"
msgstr ""
+msgid "Remove attention request(s)"
+msgstr ""
+
msgid "Remove avatar"
msgstr ""
@@ -29927,6 +30561,9 @@ msgstr ""
msgid "Removed an issue from an epic."
msgstr ""
+msgid "Removed attention from %{users_sentence}."
+msgstr ""
+
msgid "Removed attention request from @%{username}"
msgstr ""
@@ -29978,6 +30615,9 @@ msgstr ""
msgid "Removes an issue from an epic."
msgstr ""
+msgid "Removes attention from %{users_sentence}."
+msgstr ""
+
msgid "Removes parent epic %{epic_ref}."
msgstr ""
@@ -30089,6 +30729,9 @@ msgstr ""
msgid "Report abuse to admin"
msgstr ""
+msgid "Report is generating and will be sent to your email address."
+msgstr ""
+
msgid "Reported %{timeAgo} by %{reportedBy}"
msgstr ""
@@ -30378,6 +31021,15 @@ msgstr ""
msgid "Request attention"
msgstr ""
+msgid "Request attention from %{users_sentence}."
+msgstr ""
+
+msgid "Request attention from assignee or reviewer"
+msgstr ""
+
+msgid "Request attention from assignee(s) or reviewer(s)"
+msgstr ""
+
msgid "Request attention to review"
msgstr ""
@@ -30402,6 +31054,9 @@ msgstr ""
msgid "Requested %{time_ago}"
msgstr ""
+msgid "Requested attention from %{users_sentence}."
+msgstr ""
+
msgid "Requested attention from @%{username}"
msgstr ""
@@ -30616,6 +31271,9 @@ msgstr ""
msgid "Restore project"
msgstr ""
+msgid "Restoring projects"
+msgstr ""
+
msgid "Restoring the group will prevent the group, its subgroups and projects from being removed on this date."
msgstr ""
@@ -30646,6 +31304,9 @@ msgstr ""
msgid "Retry"
msgstr ""
+msgid "Retry failed jobs"
+msgstr ""
+
msgid "Retry job"
msgstr ""
@@ -30693,9 +31354,6 @@ msgstr ""
msgid "Review changes"
msgstr ""
-msgid "Review requested from %{name}"
-msgstr ""
-
msgid "Review requests for you"
msgstr ""
@@ -30860,6 +31518,9 @@ msgstr ""
msgid "Runners|Assigned Group"
msgstr ""
+msgid "Runners|Assigned Projects (%{projectCount})"
+msgstr ""
+
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30929,6 +31590,9 @@ msgstr ""
msgid "Runners|Instance"
msgstr ""
+msgid "Runners|Jobs"
+msgstr ""
+
msgid "Runners|Last contact"
msgstr ""
@@ -31022,9 +31686,6 @@ msgstr ""
msgid "Runners|Runner %{name} was deleted"
msgstr ""
-msgid "Runners|Runner ID"
-msgstr ""
-
msgid "Runners|Runner assigned to project."
msgstr ""
@@ -31172,6 +31833,9 @@ msgstr ""
msgid "Runners|stale"
msgstr ""
+msgid "Runner|This runner has not run any jobs."
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -31286,6 +31950,24 @@ msgstr ""
msgid "Saving project."
msgstr ""
+msgid "ScanResultPolicy|%{ifLabelStart}if%{ifLabelEnd} %{scanners} scan in an open merge request targeting the %{branches} branch(es) finds %{vulnerabilitiesAllowed} or more %{severities} vulnerabilities that are %{vulnerabilityStates}"
+msgstr ""
+
+msgid "ScanResultPolicy|%{thenLabelStart}Then%{thenLabelEnd} Require approval from %{approvalsRequired} of the following approvers: %{approvers}"
+msgstr ""
+
+msgid "ScanResultPolicy|add an approver"
+msgstr ""
+
+msgid "ScanResultPolicy|scanners"
+msgstr ""
+
+msgid "ScanResultPolicy|severity levels"
+msgstr ""
+
+msgid "ScanResultPolicy|vulnerability states"
+msgstr ""
+
msgid "Scanner"
msgstr ""
@@ -31418,6 +32100,9 @@ msgstr ""
msgid "Search for a user"
msgstr ""
+msgid "Search for an emoji"
+msgstr ""
+
msgid "Search for projects, issues, etc."
msgstr ""
@@ -31605,18 +32290,12 @@ msgstr ""
msgid "Secret Detection"
msgstr ""
-msgid "Secret access key"
-msgstr ""
-
msgid "Secret token"
msgstr ""
msgid "Secure token that identifies an external storage request."
msgstr ""
-msgid "SecureCodeWarrior"
-msgstr ""
-
msgid "Security"
msgstr ""
@@ -31641,9 +32320,6 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "Security training with guide and learning pathways."
-msgstr ""
-
msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
@@ -31746,7 +32422,7 @@ msgstr ""
msgid "SecurityConfiguration|Manage corpus"
msgstr ""
-msgid "SecurityConfiguration|Manage corpus files used as mutation sources in coverage fuzzing."
+msgid "SecurityConfiguration|Manage corpus files used as seed inputs with coverage-guided fuzzing."
msgstr ""
msgid "SecurityConfiguration|Manage profiles for use by DAST scans."
@@ -31812,15 +32488,15 @@ msgstr ""
msgid "SecurityOrchestration|.yaml preview"
msgstr ""
-msgid "SecurityOrchestration|Action"
-msgstr ""
-
msgid "SecurityOrchestration|Actions"
msgstr ""
msgid "SecurityOrchestration|Add rule"
msgstr ""
+msgid "SecurityOrchestration|After dismissing the alert, the information will never be shown again."
+msgstr ""
+
msgid "SecurityOrchestration|All policies"
msgstr ""
@@ -31836,7 +32512,7 @@ msgstr ""
msgid "SecurityOrchestration|Description"
msgstr ""
-msgid "SecurityOrchestration|Disabled"
+msgid "SecurityOrchestration|Don't show the alert anymore"
msgstr ""
msgid "SecurityOrchestration|Edit policy"
@@ -31845,13 +32521,13 @@ msgstr ""
msgid "SecurityOrchestration|Edit policy project"
msgstr ""
-msgid "SecurityOrchestration|Enabled"
+msgid "SecurityOrchestration|Empty policy name"
msgstr ""
-msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Enabled"
msgstr ""
-msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
msgstr ""
msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
@@ -31860,7 +32536,7 @@ msgstr ""
msgid "SecurityOrchestration|Invalid policy type"
msgstr ""
-msgid "SecurityOrchestration|Latest scan"
+msgid "SecurityOrchestration|Latest scan run against %{agent}"
msgstr ""
msgid "SecurityOrchestration|Network"
@@ -31869,15 +32545,27 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No actions defined - policy will not run."
+msgstr ""
+
+msgid "SecurityOrchestration|No description"
+msgstr ""
+
msgid "SecurityOrchestration|No rules defined - policy will not run."
msgstr ""
+msgid "SecurityOrchestration|Not enabled"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
msgid "SecurityOrchestration|Policies"
msgstr ""
+msgid "SecurityOrchestration|Policy Type"
+msgstr ""
+
msgid "SecurityOrchestration|Policy cannot be enabled for non-existing branches (%{branches})"
msgstr ""
@@ -31902,10 +32590,13 @@ msgstr ""
msgid "SecurityOrchestration|Require %{approvals} %{plural} from %{approvers} if any of the following occur:"
msgstr ""
-msgid "SecurityOrchestration|Rule"
+msgid "SecurityOrchestration|Rules"
msgstr ""
-msgid "SecurityOrchestration|Rules"
+msgid "SecurityOrchestration|Runs %{actions} and %{lastAction} scans"
+msgstr ""
+
+msgid "SecurityOrchestration|Runs a %{action} scan"
msgstr ""
msgid "SecurityOrchestration|Scan Execution"
@@ -31965,6 +32656,9 @@ msgstr ""
msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
+msgid "SecurityOrchestration|This view only shows scan results for the agent %{agent}. You can view scan results for all agents in the %{linkStart}Operational Vulnerabilities tab of the vulnerability report%{linkEnd}."
+msgstr ""
+
msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
@@ -32019,9 +32713,6 @@ msgstr ""
msgid "SecurityOrchestration|users with ids"
msgstr ""
-msgid "SecurityOrchestration|view results"
-msgstr ""
-
msgid "SecurityOrchestration|vulnerabilities"
msgstr ""
@@ -32691,22 +33382,19 @@ 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|In order to start using functions as a service, you must first install Knative on your Kubernetes cluster. %{linkStart}More information%{linkEnd}"
-msgstr ""
-
msgid "Serverless|Learn more about Serverless"
msgstr ""
msgid "Serverless|No functions available"
msgstr ""
-msgid "Serverless|Sign up for First Look"
+msgid "Serverless|Serverless was %{linkStart}deprecated%{linkEnd} in GitLab 14.3."
+msgstr ""
+
+msgid "Serverless|Serverless was %{postLinkStart}deprecated%{postLinkEnd}. But if you opt to use it, you must install Knative in your Kubernetes cluster first. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "Serverless|The deploy job has not finished."
@@ -32718,9 +33406,6 @@ 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 ""
@@ -32736,9 +33421,6 @@ msgstr ""
msgid "Service Account Key"
msgstr ""
-msgid "Service Accounts"
-msgstr ""
-
msgid "Service Accounts keys authorize GitLab to deploy your Google Cloud project"
msgstr ""
@@ -32748,10 +33430,10 @@ msgstr ""
msgid "Service Desk allows people to create issues in your GitLab instance without their own user account. It provides a unique email address for end users to create issues in a project. Replies can be sent either through the GitLab interface or by email. End users only see threads through email."
msgstr ""
-msgid "Service Usage Data"
+msgid "Service account generated successfully"
msgstr ""
-msgid "Service account generated successfully"
+msgid "Service accounts"
msgstr ""
msgid "Service ping is disabled in your configuration file, and cannot be enabled through this form."
@@ -32895,6 +33577,9 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
+msgid "Set the per-user rate limit for getting a user by ID via the API."
+msgstr ""
+
msgid "Set the per-user rate limit for notes created by web or API requests."
msgstr ""
@@ -33074,6 +33759,9 @@ msgstr ""
msgid "Shared runners details"
msgstr ""
+msgid "Shared runners enabled cannot be enabled until a valid credit card is on file"
+msgstr ""
+
msgid "Shared runners help link"
msgstr ""
@@ -33131,6 +33819,9 @@ msgstr ""
msgid "Show all issues."
msgstr ""
+msgid "Show all milestones"
+msgstr ""
+
msgid "Show all test cases."
msgstr ""
@@ -33167,6 +33858,9 @@ msgstr ""
msgid "Show file contents"
msgstr ""
+msgid "Show group milestones"
+msgstr ""
+
msgid "Show labels"
msgstr ""
@@ -33182,6 +33876,12 @@ msgstr ""
msgid "Show open epics"
msgstr ""
+msgid "Show project milestones"
+msgstr ""
+
+msgid "Show sub-group milestones"
+msgstr ""
+
msgid "Show the Closed list"
msgstr ""
@@ -33191,11 +33891,6 @@ msgstr ""
msgid "Show whitespace changes"
msgstr ""
-msgid "Showing %d event"
-msgid_plural "Showing %d events"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Showing %{conflict} between %{sourceBranch} and %{targetBranch}"
msgstr ""
@@ -33255,12 +33950,6 @@ msgstr ""
msgid "Sidebar|None"
msgstr ""
-msgid "Sidebar|Only numeral characters allowed"
-msgstr ""
-
-msgid "Sidebar|Weight"
-msgstr ""
-
msgid "Sidekiq job compression threshold (bytes)"
msgstr ""
@@ -33423,6 +34112,9 @@ msgstr ""
msgid "Slack logo"
msgstr ""
+msgid "SlackIntegration|Are you sure you want to remove this project from the Slack application?"
+msgstr ""
+
msgid "SlackIntegration|GitLab for Slack"
msgstr ""
@@ -33432,6 +34124,9 @@ msgstr ""
msgid "SlackIntegration|Project alias"
msgstr ""
+msgid "SlackIntegration|Remove project"
+msgstr ""
+
msgid "SlackIntegration|Select a GitLab project to link with your Slack workspace."
msgstr ""
@@ -33576,9 +34271,6 @@ msgstr ""
msgid "Something went wrong trying to load issue contacts."
msgstr ""
-msgid "Something went wrong when creating a work item. Please try again"
-msgstr ""
-
msgid "Something went wrong when reordering designs. Please try again"
msgstr ""
@@ -33672,9 +34364,6 @@ msgstr ""
msgid "Something went wrong while inserting your image. Please try again."
msgstr ""
-msgid "Something went wrong while merging this merge request. Please try again."
-msgstr ""
-
msgid "Something went wrong while obtaining the Let's Encrypt certificate."
msgstr ""
@@ -33996,10 +34685,10 @@ 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."
+msgid "SourcegraphAdmin|Learn more."
msgstr ""
-msgid "SourcegraphAdmin|More information"
+msgid "SourcegraphAdmin|Only public projects have code intelligence enabled and communicate with Sourcegraph."
msgstr ""
msgid "SourcegraphAdmin|Save changes"
@@ -34008,7 +34697,7 @@ msgstr ""
msgid "SourcegraphAdmin|Sourcegraph URL"
msgstr ""
-msgid "SourcegraphAdmin|e.g. https://sourcegraph.example.com"
+msgid "SourcegraphAdmin|https://sourcegraph.example.com"
msgstr ""
msgid "SourcegraphPreferences|This feature is experimental and currently limited to certain projects."
@@ -34143,6 +34832,9 @@ msgstr ""
msgid "Start date"
msgstr ""
+msgid "Start free trial"
+msgstr ""
+
msgid "Start merge train"
msgstr ""
@@ -34173,6 +34865,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started escalation for this incident."
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -34185,6 +34880,9 @@ msgstr ""
msgid "Starts at (UTC)"
msgstr ""
+msgid "Starts escalations for this incident"
+msgstr ""
+
msgid "Starts on"
msgstr ""
@@ -34446,6 +35144,9 @@ msgstr ""
msgid "Strikethrough"
msgstr ""
+msgid "Strikethrough text"
+msgstr ""
+
msgid "Subgroup information"
msgstr ""
@@ -34680,6 +35381,21 @@ msgstr ""
msgid "Subscriptions"
msgstr ""
+msgid "Subscriptions|Chat with sales"
+msgstr ""
+
+msgid "Subscriptions|Close"
+msgstr ""
+
+msgid "Subscriptions|Not ready to buy yet?"
+msgstr ""
+
+msgid "Subscriptions|Start a free trial"
+msgstr ""
+
+msgid "Subscriptions|We understand. Maybe you have some questions for our sales team, or maybe you'd like to try some of the paid features first. What would you like to do?"
+msgstr ""
+
msgid "Subscription|Your subscription for %{strong}%{namespace_name}%{strong_close} has expired and you are now on %{pricing_link_start}the GitLab Free tier%{pricing_link_end}. Don't worry, your data is safe. Get in touch with our support team (%{support_email}). They'll gladly help with your subscription renewal."
msgstr ""
@@ -34890,6 +35606,9 @@ msgstr ""
msgid "SuperSonics|Maximum users"
msgstr ""
+msgid "SuperSonics|Offline cloud"
+msgstr ""
+
msgid "SuperSonics|Paste your activation code"
msgstr ""
@@ -34956,6 +35675,12 @@ msgstr ""
msgid "SuperSonics|You do not have an active subscription"
msgstr ""
+msgid "SuperSonics|You have a future dated license"
+msgstr ""
+
+msgid "SuperSonics|You have added a license that activates on %{date}. Please see the subscription history table below for more details."
+msgstr ""
+
msgid "SuperSonics|You have successfully added a license that activates on %{date}. Please see the subscription history table below for more details."
msgstr ""
@@ -35115,6 +35840,9 @@ msgstr ""
msgid "Tag name is required"
msgstr ""
+msgid "Tag push"
+msgstr ""
+
msgid "Tag push events"
msgstr ""
@@ -35217,6 +35945,9 @@ msgstr ""
msgid "TagsPage|protected"
msgstr ""
+msgid "Take a look at the documentation to discover all of GitLab’s capabilities."
+msgstr ""
+
msgid "Target Branch"
msgstr ""
@@ -35619,6 +36350,9 @@ msgstr ""
msgid "Tests"
msgstr ""
+msgid "Text (optional)"
+msgstr ""
+
msgid "Text added to the body of all email messages. %{character_limit} character limit"
msgstr ""
@@ -35669,6 +36403,9 @@ msgstr ""
msgid "The CSV export will be created in the background. Once finished, it will be sent to %{email} in an attachment."
msgstr ""
+msgid "The CSV export you requested of all user memberships is attached to this email."
+msgstr ""
+
msgid "The GitLab subscription service (customers.gitlab.com) is currently experiencing an outage. You can monitor the status and get updates at %{linkStart}status.gitlab.com%{linkEnd}."
msgstr ""
@@ -35744,6 +36481,9 @@ 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 epic"
+msgstr ""
+
msgid "The current issue"
msgstr ""
@@ -35905,6 +36645,9 @@ msgstr ""
msgid "The latest pipeline for this merge request has failed."
msgstr ""
+msgid "The license key is invalid."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -35920,6 +36663,9 @@ msgstr ""
msgid "The license was successfully uploaded and will be active from %{starts_at}. You can see the details below."
msgstr ""
+msgid "The license you uploaded is invalid. If the issue persists, contact support at %{link}."
+msgstr ""
+
msgid "The list creation wizard is already open"
msgstr ""
@@ -36541,10 +37287,13 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} and everything this project contains. %{strongOpen}There is no going back%{strongClose}"
+msgstr ""
+
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains."
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}on %{date}%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains. %{strongOpen}There is no going back.%{strongClose}"
msgstr ""
msgid "This action will %{strongOpen}permanently remove%{strongClose} %{codeOpen}%{group}%{codeClose} %{strongOpen}immediately%{strongClose}."
@@ -36673,9 +37422,6 @@ msgstr ""
msgid "This file was modified for readability, and can't accept suggestions. Edit it directly."
msgstr ""
-msgid "This forked project has the following:"
-msgstr ""
-
msgid "This form is disabled in preview"
msgstr ""
@@ -36688,7 +37434,7 @@ msgstr ""
msgid "This group can't be removed because it is linked to a subscription. To remove this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
-msgid "This group can't be transfered because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
+msgid "This group can't be transferred because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
msgid "This group cannot be invited to a project inside a group with enforced SSO"
@@ -36715,6 +37461,9 @@ 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 incident is already escalated with '%{escalation_policy_name}'."
+msgstr ""
+
msgid "This invitation was sent to %{mail_to_invite_email}, but you are signed in as %{link_to_current_user} with email %{mail_to_current_user}."
msgstr ""
@@ -36733,9 +37482,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 merge train pipeline"
-msgstr ""
-
msgid "This is a private email address %{helpIcon} generated just for you. Anyone who has it can create issues or merge requests as if they were you. If that happens, %{resetLinkStart}reset this token%{resetLinkEnd}."
msgstr ""
@@ -36757,6 +37503,12 @@ msgstr ""
msgid "This is your current session"
msgstr ""
+msgid "This issue cannot be assigned to a confidential epic because it is public."
+msgstr ""
+
+msgid "This issue cannot be made public because it belongs to a confidential epic."
+msgstr ""
+
msgid "This issue is confidential and should only be visible to team members with at least Reporter access."
msgstr ""
@@ -36874,6 +37626,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 branch is protected from force push."
+msgstr ""
+
msgid "This merge request cannot be rebased while there are conflicts."
msgstr ""
@@ -36925,9 +37680,15 @@ msgstr ""
msgid "This pipeline was triggered by a schedule."
msgstr ""
+msgid "This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project"
msgstr ""
+msgid "This project can be restored until %{date}."
+msgstr ""
+
msgid "This project cannot be %{visibilityLevel} because the visibility of %{openShowLink}%{name}%{closeShowLink} is %{visibility}. To make this project %{visibilityLevel}, you must first %{openEditLink}change the visibility%{closeEditLink} of the parent group."
msgstr ""
@@ -36946,6 +37707,9 @@ msgstr ""
msgid "This project is %{strongStart}NOT%{strongEnd} a fork, and has the following:"
msgstr ""
+msgid "This project is %{strongStart}NOT%{strongEnd} a fork. This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -37637,6 +38401,9 @@ msgstr ""
msgid "Today"
msgstr ""
+msgid "Todos count"
+msgstr ""
+
msgid "Todos|Are you looking for things to do? Take a look at %{strongStart}%{openIssuesLinkStart}open issues%{openIssuesLinkEnd}%{strongEnd}, contribute to %{strongStart}%{mergeRequestLinkStart}a merge request%{mergeRequestLinkEnd}%{mergeRequestLinkEnd}%{strongEnd}, or mention someone in a comment to automatically assign them a new to-do item."
msgstr ""
@@ -37910,10 +38677,8 @@ msgstr ""
msgid "Trending"
msgstr ""
-msgid "Trials|%{planName} Trial %{enDash} %{num} day left"
-msgid_plural "Trials|%{planName} Trial %{enDash} %{num} days left"
-msgstr[0] ""
-msgstr[1] ""
+msgid "Trials|%{planName} Trial"
+msgstr ""
msgid "Trials|Compare all plans"
msgstr ""
@@ -37921,6 +38686,9 @@ msgstr ""
msgid "Trials|Create a new group to start your GitLab Ultimate trial."
msgstr ""
+msgid "Trials|Day %{daysUsed}/%{duration}"
+msgstr ""
+
msgid "Trials|Go back to GitLab"
msgstr ""
@@ -38170,7 +38938,7 @@ msgstr ""
msgid "URL is triggered when repository is updated"
msgstr ""
-msgid "URL must be percent-encoded if neccessary."
+msgid "URL must be percent-encoded if necessary."
msgstr ""
msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
@@ -38389,6 +39157,9 @@ msgstr ""
msgid "Unlock account"
msgstr ""
+msgid "Unlock more features with GitLab Ultimate"
+msgstr ""
+
msgid "Unlock the discussion"
msgstr ""
@@ -38452,6 +39223,9 @@ msgstr ""
msgid "Unsubscribes from this %{quick_action_target}."
msgstr ""
+msgid "Unsupported sort value."
+msgstr ""
+
msgid "Unsupported todo type passed. Supported todo types are: %{todo_types}"
msgstr ""
@@ -38680,6 +39454,9 @@ msgstr ""
msgid "UsageQuota|File attachments and smaller design graphics."
msgstr ""
+msgid "UsageQuota|From %{storage_enforcement_date} storage limits will apply to this namespace. View and manage your usage in %{strong_start}Group Settings &gt; Usage quotas%{strong_end}."
+msgstr ""
+
msgid "UsageQuota|Git repository."
msgstr ""
@@ -38740,6 +39517,9 @@ msgstr ""
msgid "UsageQuota|Storage type"
msgstr ""
+msgid "UsageQuota|Storage used"
+msgstr ""
+
msgid "UsageQuota|This is the total amount of storage used across your projects within this namespace."
msgstr ""
@@ -38935,6 +39715,12 @@ msgstr ""
msgid "Use hashed storage paths for newly created and renamed repositories. Always enabled since 13.0."
msgstr ""
+msgid "Use issue count"
+msgstr ""
+
+msgid "Use issue weight"
+msgstr ""
+
msgid "Use one line per URI"
msgstr ""
@@ -39316,6 +40102,9 @@ msgstr ""
msgid "Users"
msgstr ""
+msgid "Users API rate limit"
+msgstr ""
+
msgid "Users can launch a development environment from a GitLab browser tab when the %{linkStart}Gitpod%{linkEnd} integration is enabled."
msgstr ""
@@ -39641,6 +40430,9 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View group pipeline usage quota"
+msgstr ""
+
msgid "View incident details at"
msgstr ""
@@ -39793,6 +40585,9 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
+msgid "Vulnerability"
+msgstr ""
+
msgid "Vulnerability Report"
msgstr ""
@@ -39844,6 +40639,9 @@ msgstr ""
msgid "VulnerabilityManagement|An unverified non-confirmed finding"
msgstr ""
+msgid "VulnerabilityManagement|At least one identifier is required"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -39853,12 +40651,24 @@ msgstr ""
msgid "VulnerabilityManagement|Create Jira issue"
msgstr ""
+msgid "VulnerabilityManagement|Enter a name"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE code"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE identifier URL"
+msgstr ""
+
msgid "VulnerabilityManagement|Fetching linked Jira issues"
msgstr ""
msgid "VulnerabilityManagement|Manually add a vulnerability entry into the vulnerability report."
msgstr ""
+msgid "VulnerabilityManagement|Name is a required field"
+msgstr ""
+
msgid "VulnerabilityManagement|Needs triage"
msgstr ""
@@ -39874,6 +40684,18 @@ msgstr ""
msgid "VulnerabilityManagement|Select a method"
msgstr ""
+msgid "VulnerabilityManagement|Select a severity level"
+msgstr ""
+
+msgid "VulnerabilityManagement|Select a status"
+msgstr ""
+
+msgid "VulnerabilityManagement|Severity is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Something went wrong while creating vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -39898,6 +40720,12 @@ msgstr ""
msgid "VulnerabilityManagement|Something went wrong, could not update vulnerability state."
msgstr ""
+msgid "VulnerabilityManagement|Status is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Submit vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Summary, detailed description, steps to reproduce, etc."
msgstr ""
@@ -40093,6 +40921,9 @@ msgstr ""
msgid "WARNING:"
msgstr ""
+msgid "WARNING: This snippet contains hidden files which might be used to mask malicious behavior. Exercise caution if cloning and executing code from this snippet."
+msgstr ""
+
msgid "Wait for the file to load to copy its contents"
msgstr ""
@@ -40312,6 +41143,15 @@ msgstr ""
msgid "Webhooks|An issue is created, updated, closed, or reopened."
msgstr ""
+msgid "Webhooks|Are you sure you want to delete this group hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this project hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this webhook?"
+msgstr ""
+
msgid "Webhooks|Comments"
msgstr ""
@@ -40321,6 +41161,9 @@ msgstr ""
msgid "Webhooks|Confidential issues events"
msgstr ""
+msgid "Webhooks|Delete webhook"
+msgstr ""
+
msgid "Webhooks|Deployment events"
msgstr ""
@@ -40554,6 +41397,9 @@ msgstr ""
msgid "Wiki"
msgstr ""
+msgid "Wiki page"
+msgstr ""
+
msgid "Wiki page was successfully created."
msgstr ""
@@ -40659,7 +41505,7 @@ msgstr ""
msgid "WikiPageConflictMessage|Someone edited the page the same time you did. Please check out %{wikiLinkStart}the page%{wikiLinkEnd} and make sure your changes will not unintentionally remove theirs."
msgstr ""
-msgid "WikiPage|An error occured while trying to render the content editor. Please try again later."
+msgid "WikiPage|An error occurred while trying to render the content editor. Please try again later."
msgstr ""
msgid "WikiPage|Are you sure you want to switch back to the classic editor?"
@@ -40818,6 +41664,18 @@ msgstr ""
msgid "WorkItem|New Task"
msgstr ""
+msgid "WorkItem|Something went wrong when creating a work item. Please try again"
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching the work item. Please try again."
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching work item types. Please try again"
+msgstr ""
+
+msgid "WorkItem|Type"
+msgstr ""
+
msgid "WorkItem|Work Items"
msgstr ""
@@ -40884,7 +41742,10 @@ msgstr ""
msgid "You are about to add %{usersTag} people to the discussion. They will all receive a notification."
msgstr ""
-msgid "You are about to permanently delete this project"
+msgid "You are about to delete this forked project containing:"
+msgstr ""
+
+msgid "You are about to delete this project containing:"
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."
@@ -40905,6 +41766,9 @@ msgstr ""
msgid "You are attempting to update a file that has changed since you started editing it."
msgstr ""
+msgid "You are billed if you exceed this number. %{qsrOverageLinkStart}How does billing work?%{qsrOverageLinkEnd}"
+msgstr ""
+
msgid "You are connected to the Prometheus server, but there is currently no data to display."
msgstr ""
@@ -40962,6 +41826,9 @@ msgstr ""
msgid "You are not authorized to update this scanner profile"
msgstr ""
+msgid "You are not authorized to upload metric images"
+msgstr ""
+
msgid "You are now impersonating %{username}"
msgstr ""
@@ -41115,9 +41982,6 @@ msgstr ""
msgid "You can only upload one design when dropping onto an existing design."
msgstr ""
-msgid "You can recover this project until %{date}"
-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 ""
@@ -41166,9 +42030,6 @@ msgstr ""
msgid "You cannot write to this read-only GitLab instance."
msgstr ""
-msgid "You can’t %{tag_start}edit%{tag_end} files directly in this project. Fork this project and submit a merge request with your changes."
-msgstr ""
-
msgid "You can’t edit files directly in this project. Fork this project and submit a merge request with your changes."
msgstr ""
@@ -41321,9 +42182,6 @@ 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 set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
@@ -41354,12 +42212,6 @@ msgstr ""
msgid "You must have maintainer access to force delete a lock"
msgstr ""
-msgid "You must have permission to create a project in a group before forking."
-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 ""
@@ -41765,7 +42617,7 @@ msgstr ""
msgid "Your public email will be displayed on your public profile."
msgstr ""
-msgid "Your request for access could not be processed: %{error_meesage}"
+msgid "Your request for access could not be processed: %{error_message}"
msgstr ""
msgid "Your request for access has been queued for review."
@@ -41948,6 +42800,9 @@ msgstr ""
msgid "archived:"
msgstr ""
+msgid "artifacts"
+msgstr ""
+
msgid "assign yourself"
msgstr ""
@@ -41977,6 +42832,9 @@ msgstr[1] ""
msgid "branch name"
msgstr ""
+msgid "builds"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -42400,6 +43258,9 @@ msgstr ""
msgid "contact with same email already exists in group hierarchy"
msgstr ""
+msgid "container registry images"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -42439,6 +43300,9 @@ msgstr ""
msgid "data"
msgstr ""
+msgid "database"
+msgstr ""
+
msgid "date must not be after 9999-12-31"
msgstr ""
@@ -42462,9 +43326,6 @@ msgstr ""
msgid "design"
msgstr ""
-msgid "detached"
-msgstr ""
-
msgid "disabled"
msgstr ""
@@ -42713,7 +43574,7 @@ msgstr ""
msgid "is not a valid X509 certificate."
msgstr ""
-msgid "is not allowed for sign-up."
+msgid "is not allowed for sign-up. Please use your regular email address."
msgstr ""
msgid "is not allowed for this group."
@@ -42725,7 +43586,7 @@ msgstr ""
msgid "is not allowed since the group is not top-level group."
msgstr ""
-msgid "is not allowed."
+msgid "is not allowed. Please use your regular email address."
msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
@@ -42812,6 +43673,9 @@ msgstr ""
msgid "level: %{level}"
msgstr ""
+msgid "lfs objects"
+msgstr ""
+
msgid "limit of %{project_limit} reached"
msgstr ""
@@ -43031,6 +43895,9 @@ msgstr ""
msgid "mrWidget|Merge blocked: pipeline must succeed. It's waiting for a manual action to continue."
msgstr ""
+msgid "mrWidget|Merge blocked: pipeline must succeed. Push a commit that fixes the failure, or %{linkStart}learn about other solutions.%{linkEnd}"
+msgstr ""
+
msgid "mrWidget|Merge blocked: this merge request must be approved."
msgstr ""
@@ -43148,9 +44015,6 @@ msgstr ""
msgid "mrWidget|The changes were not merged into"
msgstr ""
-msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -43298,9 +44162,6 @@ msgstr ""
msgid "open issue"
msgstr ""
-msgid "opened %{timeAgo}"
-msgstr ""
-
msgid "or"
msgstr ""
@@ -43312,6 +44173,12 @@ msgid_plural "out of %d total tests"
msgstr[0] ""
msgstr[1] ""
+msgid "packages"
+msgstr ""
+
+msgid "pages"
+msgstr ""
+
msgid "parent"
msgid_plural "parents"
msgstr[0] ""
@@ -43461,6 +44328,9 @@ msgid_plural "replies"
msgstr[0] ""
msgstr[1] ""
+msgid "repositories"
+msgstr ""
+
msgid "repository:"
msgstr ""
@@ -43581,12 +44451,18 @@ msgstr ""
msgid "tag name"
msgstr ""
+msgid "terraform states"
+msgstr ""
+
msgid "the correct format."
msgstr ""
msgid "the file"
msgstr ""
+msgid "the following epic(s)"
+msgstr ""
+
msgid "the following issue(s)"
msgstr ""
@@ -43599,21 +44475,12 @@ msgstr ""
msgid "this document"
msgstr ""
-msgid "this issue cannot be assigned to a confidential epic since it is public"
-msgstr ""
-
-msgid "this issue cannot be made public since it belongs to a confidential epic"
-msgstr ""
-
msgid "time summary"
msgstr ""
msgid "toggle collapse"
msgstr ""
-msgid "train"
-msgstr ""
-
msgid "triggered"
msgstr ""
@@ -43742,3 +44609,6 @@ msgstr ""
msgid "{project}"
msgstr ""
+msgid "✔"
+msgstr ""
+
diff --git a/locale/ta_IN/gitlab.po b/locale/ta_IN/gitlab.po
index 83315a850f9..8f14762e477 100644
--- a/locale/ta_IN/gitlab.po
+++ b/locale/ta_IN/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: ta\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2022-02-02 15:43\n"
+"PO-Revision-Date: 2022-03-01 20:37\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -146,6 +146,11 @@ msgid_plural "%d approvers (you've approved)"
msgstr[0] ""
msgstr[1] ""
+msgid "%d assigned issue"
+msgid_plural "%d assigned issues"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -421,8 +426,23 @@ msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
msgstr[1] ""
-msgid "%d vulnerability updated"
-msgid_plural "%d vulnerabilities updated"
+msgid "%d vulnerability set to confirmed"
+msgid_plural "%d vulnerabilities set to confirmed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to dismissed"
+msgid_plural "%d vulnerabilities set to dismissed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to needs triage"
+msgid_plural "%d vulnerabilities set to needs triage"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to resolved"
+msgid_plural "%d vulnerabilities set to resolved"
msgstr[0] ""
msgstr[1] ""
@@ -510,6 +530,12 @@ msgstr[1] ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{completed} of %{total} issues closed"
+msgstr ""
+
+msgid "%{completed} of %{total} weight completed"
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -858,6 +884,9 @@ msgstr ""
msgid "%{openedIssues} open, %{closedIssues} closed"
msgstr ""
+msgid "%{percentage}%% issues closed"
+msgstr ""
+
msgid "%{percentage}%% weight completed"
msgstr ""
@@ -1287,6 +1316,9 @@ msgid_plural "- Users"
msgstr[0] ""
msgstr[1] ""
+msgid "- of - issues closed"
+msgstr ""
+
msgid "- of - weight completed"
msgstr ""
@@ -1429,7 +1461,7 @@ msgstr ""
msgid "1000+"
msgstr ""
-msgid "192.168.0.0/24"
+msgid "192.168.0.0/24 or 2001:0DB8:1234::/48"
msgstr ""
msgid "1st contribution!"
@@ -1741,13 +1773,13 @@ msgstr ""
msgid "AWS Access Key"
msgstr ""
-msgid "AWS Access Key. Only required if not using role instance credentials"
+msgid "AWS Secret Access Key"
msgstr ""
-msgid "AWS Secret Access Key"
+msgid "AWS access key ID (Optional)"
msgstr ""
-msgid "AWS Secret Access Key. Only required if not using role instance credentials"
+msgid "AWS secret access key (Optional)"
msgstr ""
msgid "AWS service error: %{error}"
@@ -1807,9 +1839,6 @@ msgstr ""
msgid "Access granted"
msgstr ""
-msgid "Access key ID"
-msgstr ""
-
msgid "Access requests"
msgstr ""
@@ -1984,7 +2013,7 @@ msgstr ""
msgid "Activity"
msgstr ""
-msgid "Activity|An error occured while retrieving activity. Reload the page to try again."
+msgid "Activity|An error occurred while retrieving activity. Reload the page to try again."
msgstr ""
msgid "Add"
@@ -2023,6 +2052,9 @@ msgstr ""
msgid "Add a %{type}"
msgstr ""
+msgid "Add a GCP region"
+msgstr ""
+
msgid "Add a GPG key"
msgstr ""
@@ -2074,6 +2106,9 @@ msgstr ""
msgid "Add a numbered list"
msgstr ""
+msgid "Add a related epic"
+msgstr ""
+
msgid "Add a related issue"
msgstr ""
@@ -2188,6 +2223,9 @@ msgstr ""
msgid "Add or subtract spent time"
msgstr ""
+msgid "Add people"
+msgstr ""
+
msgid "Add previously merged commits"
msgstr ""
@@ -2254,6 +2292,9 @@ msgstr ""
msgid "Add webhook"
msgstr ""
+msgid "Add your team members and others to GitLab."
+msgstr ""
+
msgid "Add/remove"
msgstr ""
@@ -3076,12 +3117,6 @@ msgstr ""
msgid "AdvancedSearch|Reindex required"
msgstr ""
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. Permanently deleting this project will %{strongStart}immediately delete%{strongEnd} its repositories and %{strongStart}all related resources%{strongEnd}, including issues, merge requests etc."
-msgstr ""
-
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. You will lose this project's repository and %{strongStart}all related resources%{strongEnd}, including issues and merge requests."
-msgstr ""
-
msgid "After a successful password update you will be redirected to login screen."
msgstr ""
@@ -3112,6 +3147,9 @@ msgstr ""
msgid "Akismet helps prevent the creation of spam issues in public projects."
msgstr ""
+msgid "Alert"
+msgstr ""
+
msgid "AlertManagement|Acknowledged"
msgstr ""
@@ -3484,9 +3522,6 @@ msgstr ""
msgid "All environments"
msgstr ""
-msgid "All epics"
-msgstr ""
-
msgid "All groups and projects"
msgstr ""
@@ -4223,12 +4258,15 @@ msgstr ""
msgid "ApplicationSettings|Approve users in the pending approval status?"
msgstr ""
-msgid "ApplicationSettings|By making this change, you will automatically approve %d user with the pending approval status."
-msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users with the pending approval status."
+msgid "ApplicationSettings|Approve users who are pending approval?"
+msgstr ""
+
+msgid "ApplicationSettings|By making this change, you will automatically approve %d user who is pending approval."
+msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users who are pending approval."
msgstr[0] ""
msgstr[1] ""
-msgid "ApplicationSettings|By making this change, you will automatically approve all users in pending approval status."
+msgid "ApplicationSettings|By making this change, you will automatically approve all users who are pending approval."
msgstr ""
msgid "ApplicationSettings|Denied domains for sign-ups"
@@ -4634,10 +4672,10 @@ msgstr ""
msgid "Archiving the project will make it entirely read-only. It is hidden from the dashboard and doesn't show up in searches. %{strong_start}The repository cannot be committed to, and no issues, comments, or other entities can be created.%{strong_end} %{link_start}Learn more.%{link_end}"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to delete this project?"
+msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
+msgid "Are you absolutely sure?"
msgstr ""
msgid "Are you sure that you want to archive this project?"
@@ -4673,12 +4711,18 @@ msgstr ""
msgid "Are you sure you want to delete this SSH key?"
msgstr ""
+msgid "Are you sure you want to delete this comment?"
+msgstr ""
+
msgid "Are you sure you want to delete this deploy key?"
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 label?"
+msgstr ""
+
msgid "Are you sure you want to delete this pipeline schedule?"
msgstr ""
@@ -4694,9 +4738,6 @@ msgstr ""
msgid "Are you sure you want to discard your changes?"
msgstr ""
-msgid "Are you sure you want to erase this build?"
-msgstr ""
-
msgid "Are you sure you want to import %d repository?"
msgid_plural "Are you sure you want to import %d repositories?"
msgstr[0] ""
@@ -4744,6 +4785,9 @@ msgstr ""
msgid "Are you sure you want to remove this list?"
msgstr ""
+msgid "Are you sure you want to remove this nickname?"
+msgstr ""
+
msgid "Are you sure you want to reset the health check token?"
msgstr ""
@@ -4756,10 +4800,10 @@ 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?"
+msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
msgstr ""
-msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
+msgid "Are you sure you want to revoke this project access token? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to stop this environment?"
@@ -4906,9 +4950,6 @@ msgstr ""
msgid "Assigned to %{assignee_name}"
msgstr ""
-msgid "Assigned to %{name}"
-msgstr ""
-
msgid "Assigned to me"
msgstr ""
@@ -4973,6 +5014,9 @@ msgstr[1] ""
msgid "Attaching the file failed."
msgstr ""
+msgid "Attention"
+msgstr ""
+
msgid "Audit Events"
msgstr ""
@@ -5135,6 +5179,12 @@ msgstr ""
msgid "Authorized applications (%{size})"
msgstr ""
+msgid "AuthorizedApplication|Are you sure you want to revoke this application?"
+msgstr ""
+
+msgid "AuthorizedApplication|Revoke application"
+msgstr ""
+
msgid "Authors: %{authors}"
msgstr ""
@@ -6328,6 +6378,9 @@ msgstr ""
msgid "CICDAnalytics|Shared Runners Usage"
msgstr ""
+msgid "CICDAnalytics|Shared runner pipeline minute duration by month"
+msgstr ""
+
msgid "CICDAnalytics|Shared runner usage"
msgstr ""
@@ -6469,6 +6522,9 @@ msgstr ""
msgid "Can create groups:"
msgstr ""
+msgid "Can not delete primary training"
+msgstr ""
+
msgid "Can't apply as the source branch was deleted."
msgstr ""
@@ -6802,9 +6858,6 @@ msgstr ""
msgid "Changing any setting here requires an application restart"
msgstr ""
-msgid "Changing group URL can have unintended side effects."
-msgstr ""
-
msgid "Charts can't be displayed as the request for data has timed out. %{documentationLink}"
msgstr ""
@@ -6892,9 +6945,6 @@ msgstr ""
msgid "Checking branch availability..."
msgstr ""
-msgid "Checking group URL availability..."
-msgstr ""
-
msgid "Checking group path availability..."
msgstr ""
@@ -7388,6 +7438,9 @@ msgstr ""
msgid "Clear recent searches"
msgstr ""
+msgid "Clear repository checks"
+msgstr ""
+
msgid "Clear search"
msgstr ""
@@ -7520,9 +7573,6 @@ msgstr ""
msgid "Closed MRs"
msgstr ""
-msgid "Closed epics"
-msgstr ""
-
msgid "Closed issues"
msgstr ""
@@ -7559,13 +7609,13 @@ msgstr ""
msgid "Cluster level"
msgstr ""
-msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
+msgid "Cluster type must be specified for Stages::ClusterEndpointInserter"
msgstr ""
msgid "ClusterAgents|%{name} successfully deleted"
msgstr ""
-msgid "ClusterAgents|%{number} of %{total} Agents"
+msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
@@ -7607,6 +7657,15 @@ msgstr ""
msgid "ClusterAgents|Agent never connected to GitLab"
msgstr ""
+msgid "ClusterAgents|Agent version mismatch"
+msgstr ""
+
+msgid "ClusterAgents|Agent version mismatch and update"
+msgstr ""
+
+msgid "ClusterAgents|Agent version update required"
+msgstr ""
+
msgid "ClusterAgents|All"
msgstr ""
@@ -7631,7 +7690,7 @@ msgstr ""
msgid "ClusterAgents|Configuration"
msgstr ""
-msgid "ClusterAgents|Connect a cluster through the Agent"
+msgid "ClusterAgents|Connect a cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connect existing cluster"
@@ -7640,13 +7699,13 @@ msgstr ""
msgid "ClusterAgents|Connect with a certificate"
msgstr ""
-msgid "ClusterAgents|Connect with agent"
+msgid "ClusterAgents|Connect with an agent"
msgstr ""
msgid "ClusterAgents|Connect with the GitLab Agent"
msgstr ""
-msgid "ClusterAgents|Connect your cluster through the Agent"
+msgid "ClusterAgents|Connect your cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connected"
@@ -7706,7 +7765,10 @@ msgstr ""
msgid "ClusterAgents|How to register an agent?"
msgstr ""
-msgid "ClusterAgents|Install new Agent"
+msgid "ClusterAgents|How to update an agent?"
+msgstr ""
+
+msgid "ClusterAgents|Install a new agent"
msgstr ""
msgid "ClusterAgents|Last connected %{timeAgo}."
@@ -7733,7 +7795,7 @@ msgstr ""
msgid "ClusterAgents|Never connected"
msgstr ""
-msgid "ClusterAgents|No Agents"
+msgid "ClusterAgents|No agents"
msgstr ""
msgid "ClusterAgents|No clusters connected through cluster certificates"
@@ -7793,6 +7855,9 @@ msgstr ""
msgid "ClusterAgents|The agent has not been connected in a long time. There might be a connectivity issue. Last contact was %{timeAgo}."
msgstr ""
+msgid "ClusterAgents|The agent version do not match each other across your cluster's pods. This can happen when a new agent version was just deployed and Kubernetes is shutting down the old pods."
+msgstr ""
+
msgid "ClusterAgents|The recommended installation method includes the token. If you want to follow the advanced installation method provided in the docs, make sure you save the token value before you close this window."
msgstr ""
@@ -7840,6 +7905,9 @@ msgstr ""
msgid "ClusterAgents|You will need to create a token to connect to your agent"
msgstr ""
+msgid "ClusterAgents|Your agent version is out of sync with your GitLab version (v%{version}), which might cause compatibility problems. Update the agent installed on your cluster to the most recent version."
+msgstr ""
+
msgid "ClusterAgents|Your instance doesn't have the %{linkStart}GitLab Agent Server (KAS)%{linkEnd} set up. Ask a GitLab Administrator to install it."
msgstr ""
@@ -8716,9 +8784,6 @@ msgstr ""
msgid "Comma-separated list of email addresses."
msgstr ""
-msgid "Comma-separated list of users allowed to exceed the rate limit."
-msgstr ""
-
msgid "Comma-separated, e.g. '1.1.1.1, 2.2.2.0/24'"
msgstr ""
@@ -9045,6 +9110,12 @@ msgstr ""
msgid "Confidential"
msgstr ""
+msgid "Confidential issue"
+msgstr ""
+
+msgid "Confidential note"
+msgstr ""
+
msgid "Confidentiality"
msgstr ""
@@ -9078,6 +9149,9 @@ msgstr ""
msgid "Configure Dependency Scanning in `.gitlab-ci.yml`, creating this file if it does not already exist"
msgstr ""
+msgid "Configure GitLab"
+msgstr ""
+
msgid "Configure GitLab runners to start using the Web Terminal. %{helpStart}Learn more.%{helpEnd}"
msgstr ""
@@ -9126,6 +9200,15 @@ msgstr ""
msgid "Configure pipelines to deploy web apps, backend services, APIs and static resources to Google Cloud"
msgstr ""
+msgid "Configure region"
+msgstr ""
+
+msgid "Configure region for environment"
+msgstr ""
+
+msgid "Configure regions"
+msgstr ""
+
msgid "Configure repository mirroring."
msgstr ""
@@ -9159,6 +9242,9 @@ msgstr ""
msgid "Configure which lists are shown for anyone who visits this board"
msgstr ""
+msgid "Configure your environments to be deployed to specific geographical regions"
+msgstr ""
+
msgid "Confirm"
msgstr ""
@@ -9861,10 +9947,10 @@ msgstr ""
msgid "CorpusManagement|Actions"
msgstr ""
-msgid "CorpusManagement|Corpus are used in fuzz testing as mutation source to Improve future testing."
+msgid "CorpusManagement|Corpus file"
msgstr ""
-msgid "CorpusManagement|Corpus file"
+msgid "CorpusManagement|Corpus files are used in coverage-guided fuzz testing as seed inputs to improve testing."
msgstr ""
msgid "CorpusManagement|Corpus files must be in *.zip format. Maximum 5 GB"
@@ -9918,6 +10004,9 @@ msgstr ""
msgid "Could not apply %{name} command."
msgstr ""
+msgid "Could not apply %{name} command. %{message}."
+msgstr ""
+
msgid "Could not authorize chat nickname. Try again!"
msgstr ""
@@ -10068,6 +10157,9 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
+msgid "Create a group"
+msgstr ""
+
msgid "Create a merge request"
msgstr ""
@@ -10092,6 +10184,9 @@ msgstr ""
msgid "Create a personal access token on your account to pull or push via %{protocol}."
msgstr ""
+msgid "Create a project"
+msgstr ""
+
msgid "Create an account using:"
msgstr ""
@@ -10455,6 +10550,9 @@ msgstr ""
msgid "Creation date"
msgstr ""
+msgid "Creator"
+msgstr ""
+
msgid "Credentials"
msgstr ""
@@ -10467,9 +10565,15 @@ msgstr ""
msgid "CredentialsInventory|Personal Access Tokens"
msgstr ""
+msgid "CredentialsInventory|Project Access Tokens"
+msgstr ""
+
msgid "CredentialsInventory|SSH Keys"
msgstr ""
+msgid "Credit card required to be on file in order to create a pipeline"
+msgstr ""
+
msgid "Credit card:"
msgstr ""
@@ -10653,9 +10757,6 @@ msgstr ""
msgid "Customer relations"
msgstr ""
-msgid "Customizable by an administrator."
-msgstr ""
-
msgid "Customizable by owners."
msgstr ""
@@ -10785,30 +10886,18 @@ msgstr ""
msgid "CycleAnalytics|%{selectedLabelsCount} selected (%{maxLabels} max)"
msgstr ""
-msgid "CycleAnalytics|%{stageCount} stages selected"
-msgstr ""
-
-msgid "CycleAnalytics|All stages"
-msgstr ""
-
-msgid "CycleAnalytics|Average days to completion"
+msgid "CycleAnalytics|Average time to completion"
msgstr ""
msgid "CycleAnalytics|Date"
msgstr ""
-msgid "CycleAnalytics|Days to completion"
-msgstr ""
-
msgid "CycleAnalytics|Display chart filters"
msgstr ""
msgid "CycleAnalytics|Lead Time for Changes"
msgstr ""
-msgid "CycleAnalytics|No stages selected"
-msgstr ""
-
msgid "CycleAnalytics|Number of tasks"
msgstr ""
@@ -10837,18 +10926,30 @@ msgstr ""
msgid "CycleAnalytics|Showing data for group '%{groupName}' from %{createdAfter} to %{createdBefore}"
msgstr ""
-msgid "CycleAnalytics|Stages"
+msgid "CycleAnalytics|Stage time: %{title}"
msgstr ""
msgid "CycleAnalytics|Tasks by type"
msgstr ""
-msgid "CycleAnalytics|The average time spent in the selected stage for the items that were completed on each date. Data limited to the last 500 items."
+msgid "CycleAnalytics|The average time items spent in this stage. Data limited to items completed within this date range."
msgstr ""
msgid "CycleAnalytics|The given date range is larger than 180 days"
msgstr ""
+msgid "CycleAnalytics|The total time items spent across each value stream stage. Data limited to items completed within this date range."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Stage time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Total time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|Total time"
+msgstr ""
+
msgid "CycleAnalytics|Type of work"
msgstr ""
@@ -10861,9 +10962,6 @@ msgstr ""
msgid "CycleAnalytics|project dropdown filter"
msgstr ""
-msgid "CycleAnalytics|stage dropdown"
-msgstr ""
-
msgid "DAG visualization requires at least 3 dependent jobs."
msgstr ""
@@ -10963,10 +11061,16 @@ msgstr ""
msgid "DastProfiles|AJAX spider"
msgstr ""
+msgid "DastProfiles|API"
+msgstr ""
+
+msgid "DastProfiles|API endpoint URL"
+msgstr ""
+
msgid "DastProfiles|Active"
msgstr ""
-msgid "DastProfiles|Additional request headers (Optional)"
+msgid "DastProfiles|Additional request headers (optional)"
msgstr ""
msgid "DastProfiles|Are you sure you want to delete this profile?"
@@ -10981,6 +11085,9 @@ msgstr ""
msgid "DastProfiles|Branch missing"
msgstr ""
+msgid "DastProfiles|Choose a scan method"
+msgstr ""
+
msgid "DastProfiles|Could not create the scanner profile. Please try again."
msgstr ""
@@ -11050,7 +11157,13 @@ msgstr ""
msgid "DastProfiles|Excluded URLs"
msgstr ""
-msgid "DastProfiles|Excluded URLs (Optional)"
+msgid "DastProfiles|Excluded URLs (optional)"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths (optional)"
msgstr ""
msgid "DastProfiles|Hide debug messages"
@@ -11107,9 +11220,6 @@ msgstr ""
msgid "DastProfiles|Request headers"
msgstr ""
-msgid "DastProfiles|Rest API"
-msgstr ""
-
msgid "DastProfiles|Run the AJAX spider, in addition to the traditional spider, to crawl the target site."
msgstr ""
@@ -11119,6 +11229,9 @@ msgstr ""
msgid "DastProfiles|Save profile"
msgstr ""
+msgid "DastProfiles|Scan method"
+msgstr ""
+
msgid "DastProfiles|Scan mode"
msgstr ""
@@ -11197,12 +11310,24 @@ msgstr ""
msgid "DastProfiles|Website"
msgstr ""
+msgid "DastProfiles|What does each method do?"
+msgstr ""
+
msgid "DastProfiles|You can either choose a passive scan or validate the target site from the site profile management page. %{docsLinkStart}Learn more about site validation.%{docsLinkEnd}"
msgstr ""
msgid "DastProfiles|You cannot run an active scan against an unvalidated site."
msgstr ""
+msgid "DastProfiles|folder/dast_example.har or https://example.com/dast_example.har"
+msgstr ""
+
+msgid "DastProfiles|folder/example.postman_collection.json or https://example.com/"
+msgstr ""
+
+msgid "DastProfiles|folder/openapi.json or https://example.com/openapi.json"
+msgstr ""
+
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
@@ -11310,6 +11435,9 @@ msgstr ""
msgid "DatadogIntegration|API URL"
msgstr ""
+msgid "DatadogIntegration|Custom tags in Datadog. Enter one tag per line in the %{codeOpen}key:value%{codeClose} format. %{linkOpen}How do I use tags?%{linkClose}"
+msgstr ""
+
msgid "DatadogIntegration|Environment"
msgstr ""
@@ -11328,12 +11456,18 @@ msgstr ""
msgid "DatadogIntegration|Tag all data from this GitLab instance in Datadog. Useful when managing several self-managed deployments."
msgstr ""
+msgid "DatadogIntegration|Tags"
+msgstr ""
+
msgid "DatadogIntegration|The Datadog site to send data to. To send data to the EU site, use %{codeOpen}datadoghq.eu%{codeClose}."
msgstr ""
msgid "DatadogIntegration|Trace your GitLab pipelines with Datadog."
msgstr ""
+msgid "DatadogIntegration|have an invalid format"
+msgstr ""
+
msgid "Datasource name not found"
msgstr ""
@@ -11343,9 +11477,6 @@ msgstr ""
msgid "Date merged"
msgstr ""
-msgid "Date picker"
-msgstr ""
-
msgid "Date range"
msgstr ""
@@ -11499,9 +11630,6 @@ msgstr ""
msgid "Definition"
msgstr ""
-msgid "Delayed Project Deletion (%{adjourned_deletion})"
-msgstr ""
-
msgid "DelayedJobs|Are you sure you want to run %{jobName} immediately? Otherwise this job will run automatically after its timer finishes."
msgstr ""
@@ -11580,10 +11708,10 @@ msgstr ""
msgid "Delete pipeline"
msgstr ""
-msgid "Delete project"
+msgid "Delete pipeline schedule"
msgstr ""
-msgid "Delete project. Are you ABSOLUTELY SURE?"
+msgid "Delete project"
msgstr ""
msgid "Delete row"
@@ -11613,6 +11741,9 @@ msgstr ""
msgid "Delete this epic and all descendants?"
msgstr ""
+msgid "Delete this project"
+msgstr ""
+
msgid "Delete user list"
msgstr ""
@@ -11871,6 +12002,12 @@ msgstr ""
msgid "Deploy to..."
msgstr ""
+msgid "DeployBoards|To see deployment progress for your environments, make sure you are deploying to %{codeStart}$KUBE_NAMESPACE%{codeEnd} and annotating with %{codeStart}app.gitlab.com/app=$CI_PROJECT_PATH_SLUG%{codeEnd} and %{codeStart}app.gitlab.com/env=$CI_ENVIRONMENT_SLUG%{codeEnd}."
+msgstr ""
+
+msgid "DeployBoard|Kubernetes Pods"
+msgstr ""
+
msgid "DeployFreeze|Add a freeze period to prevent unintended releases during a period of time for a given environment. You must update the deployment jobs in %{filename} according to the deploy freezes added here. %{freeze_period_link_start}Learn more.%{freeze_period_link_end}"
msgstr ""
@@ -11955,9 +12092,6 @@ msgstr ""
msgid "DeployTokens|Active Deploy Tokens (%{active_tokens})"
msgstr ""
-msgid "DeployTokens|Allows read and write access to registry images."
-msgstr ""
-
msgid "DeployTokens|Allows read and write access to the package registry."
msgstr ""
@@ -11970,6 +12104,9 @@ msgstr ""
msgid "DeployTokens|Allows read-only access to the repository."
msgstr ""
+msgid "DeployTokens|Allows write access to registry images."
+msgstr ""
+
msgid "DeployTokens|Copy deploy token"
msgstr ""
@@ -12063,12 +12200,57 @@ msgstr ""
msgid "Deploying to AWS is easy with GitLab"
msgstr ""
+msgid "Deployment"
+msgstr ""
+
msgid "Deployment Frequency"
msgstr ""
+msgid "Deployment Target|Project deployment target (optional)"
+msgstr ""
+
+msgid "Deployment Target|Select the deployment target"
+msgstr ""
+
msgid "Deployment frequency"
msgstr ""
+msgid "DeploymentTarget|GitLab Pages"
+msgstr ""
+
+msgid "DeploymentTarget|Heroku"
+msgstr ""
+
+msgid "DeploymentTarget|Infrastructure provider (Terraform, Cloudformation, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Kubernetes (GKE, EKS, OpenShift, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Managed container runtime (Fargate, Cloud Run, DigitalOcean App)"
+msgstr ""
+
+msgid "DeploymentTarget|Mobile app store"
+msgstr ""
+
+msgid "DeploymentTarget|No deployment planned"
+msgstr ""
+
+msgid "DeploymentTarget|Other hosting service"
+msgstr ""
+
+msgid "DeploymentTarget|Registry (package or container)"
+msgstr ""
+
+msgid "DeploymentTarget|Self-managed container runtime (Podman, Docker Swarm, Docker Compose)"
+msgstr ""
+
+msgid "DeploymentTarget|Serverless backend (Lambda, Cloud functions)"
+msgstr ""
+
+msgid "DeploymentTarget|Virtual machine (for example, EC2)"
+msgstr ""
+
msgid "Deployments"
msgstr ""
@@ -12107,6 +12289,9 @@ msgstr ""
msgid "Deployment|This deployment was created using the API"
msgstr ""
+msgid "Deployment|Triggerer"
+msgstr ""
+
msgid "Deployment|Waiting"
msgstr ""
@@ -12134,6 +12319,18 @@ msgstr ""
msgid "Deprecated API rate limits"
msgstr ""
+msgid "Deprecations|Feature deprecation and removal"
+msgstr ""
+
+msgid "Deprecations|For information on a possible replacement %{epicStart} learn more about Opstrace %{epicEnd}."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7 and are %{epicStart} scheduled for removal %{epicEnd} in GitLab 15.0."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7, and are %{removal_link_start} scheduled for removal %{link_end} in GitLab 15.0. For information on a possible replacement, %{opstrace_link_start} learn more about Opstrace %{link_end}."
+msgstr ""
+
msgid "Deprioritize label"
msgstr ""
@@ -12379,10 +12576,10 @@ msgstr ""
msgid "DevopsAdoption|At least one deploy"
msgstr ""
-msgid "DevopsAdoption|At least one issue opened"
+msgid "DevopsAdoption|At least one issue created"
msgstr ""
-msgid "DevopsAdoption|At least one merge request opened"
+msgid "DevopsAdoption|At least one merge request created"
msgstr ""
msgid "DevopsAdoption|At least one pipeline successfully run"
@@ -12583,6 +12780,9 @@ msgstr ""
msgid "Direct member"
msgstr ""
+msgid "Direct members"
+msgstr ""
+
msgid "Direct non-authenticated users to this page."
msgstr ""
@@ -12699,6 +12899,9 @@ msgid_plural "Dismiss %d selected vulnerabilities as"
msgstr[0] ""
msgstr[1] ""
+msgid "Dismiss Alert"
+msgstr ""
+
msgid "Dismiss merge request promotion"
msgstr ""
@@ -12726,9 +12929,15 @@ msgstr ""
msgid "Display alerts from all configured monitoring tools."
msgstr ""
+msgid "Display milestones"
+msgstr ""
+
msgid "Display name"
msgstr ""
+msgid "Display progress of child issues"
+msgstr ""
+
msgid "Display rendered file"
msgstr ""
@@ -12834,6 +13043,9 @@ msgstr ""
msgid "Download image"
msgstr ""
+msgid "Download payload"
+msgstr ""
+
msgid "Download raw data (.csv)"
msgstr ""
@@ -13011,6 +13223,9 @@ msgstr ""
msgid "Edit in Web IDE"
msgstr ""
+msgid "Edit in pipeline editor"
+msgstr ""
+
msgid "Edit in single-file editor"
msgstr ""
@@ -13053,6 +13268,9 @@ msgstr ""
msgid "Edit your most recent comment in a thread (from an empty textarea)"
msgstr ""
+msgid "Edit, lint, and visualize your pipeline."
+msgstr ""
+
msgid "Edited"
msgstr ""
@@ -13494,6 +13712,9 @@ msgstr ""
msgid "Enforce two-factor authentication for all user sign-ins."
msgstr ""
+msgid "Enhance security by storing service account keys in secret managers - learn more about %{docLinkStart}secret management with GitLab%{docLinkEnd}"
+msgstr ""
+
msgid "Ensure connectivity is available from the GitLab server to the Prometheus server"
msgstr ""
@@ -13554,6 +13775,9 @@ 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 following to confirm:"
+msgstr ""
+
msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
@@ -14084,9 +14308,6 @@ 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 ""
@@ -14222,6 +14443,9 @@ msgstr ""
msgid "Errors:"
msgstr ""
+msgid "Escalate this incident"
+msgstr ""
+
msgid "Escalation Policies"
msgstr ""
@@ -14234,6 +14458,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy"
+msgstr ""
+
msgid "Escalation policy:"
msgstr ""
@@ -14485,6 +14712,9 @@ msgstr ""
msgid "Existing sign in methods may be removed"
msgstr ""
+msgid "Exit."
+msgstr ""
+
msgid "Expand"
msgstr ""
@@ -14581,6 +14811,9 @@ msgstr ""
msgid "Explore public groups"
msgstr ""
+msgid "Explore public projects"
+msgstr ""
+
msgid "Explore snippets"
msgstr ""
@@ -14742,7 +14975,7 @@ msgid_plural "Failed to archive designs. Please try again."
msgstr[0] ""
msgstr[1] ""
-msgid "Failed to assign a reviewer because no user was found."
+msgid "Failed to assign a reviewer because no user was specified."
msgstr ""
msgid "Failed to assign a user because no user was found."
@@ -14808,10 +15041,10 @@ msgstr ""
msgid "Failed to find import label for Jira import."
msgstr ""
-msgid "Failed to generate export, please try again later."
+msgid "Failed to find users for %{missing}"
msgstr ""
-msgid "Failed to generate report, please try again after sometime"
+msgid "Failed to generate export, please try again later."
msgstr ""
msgid "Failed to get ref."
@@ -14910,6 +15143,9 @@ msgstr ""
msgid "Failed to remove a to-do item for the design."
msgstr ""
+msgid "Failed to remove attention because no user was found."
+msgstr ""
+
msgid "Failed to remove mirror."
msgstr ""
@@ -14922,6 +15158,9 @@ msgstr ""
msgid "Failed to remove user key."
msgstr ""
+msgid "Failed to request attention because no user was found."
+msgstr ""
+
msgid "Failed to reset key. Please try again."
msgstr ""
@@ -15003,6 +15242,9 @@ msgstr ""
msgid "Feature Flags"
msgstr ""
+msgid "Feature deprecation and removal"
+msgstr ""
+
msgid "Feature flag status"
msgstr ""
@@ -15500,7 +15742,7 @@ msgstr ""
msgid "For each job, re-use the project workspace. If the workspace doesn't exist, use %{code_open}git clone%{code_close}."
msgstr ""
-msgid "For example, the application using the token or the purpose of the token."
+msgid "For example, the application using the token or the purpose of the token. Do not give sensitive information for the name of the token, as it will be visible to all %{resource_type} members."
msgstr ""
msgid "For files larger than this limit, only index the file name. The file content is neither indexed nor searchable."
@@ -15584,9 +15826,6 @@ msgstr ""
msgid "ForkProject|Select a namespace"
msgstr ""
-msgid "ForkProject|Select a namespace to fork the project"
-msgstr ""
-
msgid "ForkProject|The project can be accessed by any logged in user."
msgstr ""
@@ -15683,6 +15922,9 @@ msgstr ""
msgid "Full name"
msgstr ""
+msgid "GCP region configured"
+msgstr ""
+
msgid "GPG Key ID:"
msgstr ""
@@ -15863,6 +16105,9 @@ msgstr ""
msgid "Geo|Failed"
msgstr ""
+msgid "Geo|Filter Geo sites"
+msgstr ""
+
msgid "Geo|Filter by name"
msgstr ""
@@ -16274,6 +16519,12 @@ msgstr ""
msgid "GitLab Issue"
msgstr ""
+msgid "GitLab KAS"
+msgstr ""
+
+msgid "GitLab Memberships CSV Export"
+msgstr ""
+
msgid "GitLab Pages"
msgstr ""
@@ -16322,6 +16573,9 @@ 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 free to use. Many features for larger teams are part of our %{link_start}paid products%{link_end}. You can try Ultimate for free without any obligation or payment details."
+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 ""
@@ -16448,7 +16702,7 @@ msgstr ""
msgid "GitLabPages|When enabled, all attempts to visit your website through HTTP are automatically redirected to HTTPS using a response with status code 301. Requires a valid certificate for all domains. %{docs_link_start}Learn more.%{link_end}"
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. %{docs_link_start}Learn more.%{link_end}"
+msgid "GitLabPages|When using Pages under the general domain of a GitLab instance (%{pages_host}), you cannot use HTTPS with subdomains of subdomains. If your namespace or groupname contains a dot, it does not work. This is a limitation of the HTTP Over TLS protocol. HTTP pages work if you don't redirect HTTP to HTTPS. %{docs_link_start}Learn more.%{link_end}"
msgstr ""
msgid "GitLabPages|With GitLab Pages you can host your static website directly from your GitLab repository. %{docs_link_start}Learn more.%{link_end}"
@@ -16625,9 +16879,6 @@ msgstr ""
msgid "Go to find file"
msgstr ""
-msgid "Go to fork"
-msgstr ""
-
msgid "Go to issue boards"
msgstr ""
@@ -16835,9 +17086,6 @@ msgstr ""
msgid "Group Hooks"
msgstr ""
-msgid "Group ID"
-msgstr ""
-
msgid "Group Owner must have signed in with SAML before enabling Group Managed Accounts"
msgstr ""
@@ -16865,9 +17113,6 @@ msgstr ""
msgid "Group by"
msgstr ""
-msgid "Group description"
-msgstr ""
-
msgid "Group description (optional)"
msgstr ""
@@ -16982,7 +17227,7 @@ msgstr ""
msgid "Group: %{name}"
msgstr ""
-msgid "GroupActivityMetrics|Issues opened"
+msgid "GroupActivityMetrics|Issues created"
msgstr ""
msgid "GroupActivityMetrics|Last 90 days"
@@ -16991,7 +17236,7 @@ msgstr ""
msgid "GroupActivityMetrics|Members added"
msgstr ""
-msgid "GroupActivityMetrics|Merge Requests opened"
+msgid "GroupActivityMetrics|Merge Requests created"
msgstr ""
msgid "GroupActivityMetrics|Recent activity"
@@ -17282,6 +17527,9 @@ msgstr ""
msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
+msgid "GroupSettings|Choose a group path that does not start with a dash or end with a period. It can also contain alphanumeric characters and underscores."
+msgstr ""
+
msgid "GroupSettings|Compliance frameworks"
msgstr ""
@@ -17315,7 +17563,7 @@ msgstr ""
msgid "GroupSettings|If not specified at the group or instance level, the default is %{default_initial_branch_name}. Does not affect existing repositories."
msgstr ""
-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."
+msgid "GroupSettings|If the parent group's visibility is lower than the group's current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility."
msgstr ""
msgid "GroupSettings|New runners registration token has been generated!"
@@ -17432,7 +17680,10 @@ msgstr ""
msgid "Groups and projects"
msgstr ""
-msgid "Groups and subgroups"
+msgid "Groups are a great way to organize projects and people."
+msgstr ""
+
+msgid "Groups are the best way to manage projects and members."
msgstr ""
msgid "Groups to synchronize"
@@ -17543,13 +17794,16 @@ msgstr ""
msgid "GroupsTree|Are you sure you want to leave the \"%{fullName}\" group?"
msgstr ""
-msgid "GroupsTree|Edit group"
+msgid "GroupsTree|Delete"
+msgstr ""
+
+msgid "GroupsTree|Edit"
msgstr ""
msgid "GroupsTree|Failed to leave the group. Please make sure you are not the only owner."
msgstr ""
-msgid "GroupsTree|Leave this group"
+msgid "GroupsTree|Leave group"
msgstr ""
msgid "GroupsTree|Loading groups"
@@ -17561,9 +17815,57 @@ msgstr ""
msgid "GroupsTree|No groups or projects matched your search"
msgstr ""
+msgid "GroupsTree|Options"
+msgstr ""
+
msgid "GroupsTree|Search by name"
msgstr ""
+msgid "Groups|Avatar will be removed. Are you sure?"
+msgstr ""
+
+msgid "Groups|Changing group URL can have unintended side effects."
+msgstr ""
+
+msgid "Groups|Checking group URL availability..."
+msgstr ""
+
+msgid "Groups|Enter a descriptive name for your group."
+msgstr ""
+
+msgid "Groups|Group ID"
+msgstr ""
+
+msgid "Groups|Group URL"
+msgstr ""
+
+msgid "Groups|Group avatar"
+msgstr ""
+
+msgid "Groups|Group description (optional)"
+msgstr ""
+
+msgid "Groups|Group name"
+msgstr ""
+
+msgid "Groups|Group path is available."
+msgstr ""
+
+msgid "Groups|Group path is unavailable. Path has been replaced with a suggested available path."
+msgstr ""
+
+msgid "Groups|Learn more"
+msgstr ""
+
+msgid "Groups|Must start with letter, digit, emoji, or underscore. Can also contain periods, dashes, spaces, and parentheses."
+msgstr ""
+
+msgid "Groups|Remove avatar"
+msgstr ""
+
+msgid "Groups|Save changes"
+msgstr ""
+
msgid "Guideline"
msgstr ""
@@ -17573,6 +17875,9 @@ msgstr ""
msgid "HAR file path or URL"
msgstr ""
+msgid "HTTP Archive (HAR)"
+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 ""
@@ -17973,6 +18278,9 @@ msgstr ""
msgid "INFO: Your SSH key is expiring soon. Please generate a new key."
msgstr ""
+msgid "IP"
+msgstr ""
+
msgid "IP Address"
msgstr ""
@@ -18009,6 +18317,9 @@ msgstr ""
msgid "IdentityVerification|Verify your identity"
msgstr ""
+msgid "IdentityVerification|You can always verify your account at a later time to create a group."
+msgstr ""
+
msgid "If any indexed field exceeds this limit, it is truncated to this number of characters. The rest of the content is neither indexed nor searchable. This does not apply to repository and wiki indexing. For unlimited characters, set this to 0."
msgstr ""
@@ -18066,6 +18377,9 @@ msgstr ""
msgid "If you add %{codeStart}needs%{codeEnd} to jobs in your pipeline you'll be able to view the %{codeStart}needs%{codeEnd} relationships between jobs in this tab as a %{linkStart}Directed Acyclic Graph (DAG)%{linkEnd}."
msgstr ""
+msgid "If you are added to a project, it will be displayed here."
+msgstr ""
+
msgid "If you did not initiate these sign-in attempts, please reach out to your administrator or enable two-factor authentication (2FA) on your account."
msgstr ""
@@ -18372,12 +18686,24 @@ msgstr ""
msgid "InProductMarketing|3 ways to dive into GitLab CI/CD"
msgstr ""
+msgid "InProductMarketing|A single application eliminates complex integrations, data chokepoints, and toolchain maintenance, resulting in greater productivity and lower cost."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features, build more efficiently, strengthen security and compliance."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features."
+msgstr ""
+
msgid "InProductMarketing|Actually, GitLab makes the team work (better)"
msgstr ""
msgid "InProductMarketing|And finally %{deploy_link} a Python application."
msgstr ""
+msgid "InProductMarketing|And many more..."
+msgstr ""
+
msgid "InProductMarketing|Are your runners ready?"
msgstr ""
@@ -18396,15 +18722,33 @@ msgstr ""
msgid "InProductMarketing|Blog"
msgstr ""
+msgid "InProductMarketing|Break down silos to coordinate seamlessly across development, operations, and security with a consistent experience across the development lifecycle."
+msgstr ""
+
+msgid "InProductMarketing|Burn up/down charts"
+msgstr ""
+
msgid "InProductMarketing|By enabling code owners and required merge approvals the right person will review the right MR. This is a win-win: cleaner code and a more efficient review process."
msgstr ""
msgid "InProductMarketing|Click on the number below that corresponds with your answer — 1 being very difficult, 5 being very easy."
msgstr ""
+msgid "InProductMarketing|Code owners"
+msgstr ""
+
msgid "InProductMarketing|Code owners and required merge approvals are part of the paid tiers of GitLab. You can start a free 30-day trial of GitLab Ultimate and enable these features in less than 5 minutes with no credit card required."
msgstr ""
+msgid "InProductMarketing|Code review analytics"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration across stages in GitLab"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration made easy"
+msgstr ""
+
msgid "InProductMarketing|Create a custom CI runner with just a few clicks"
msgstr ""
@@ -18414,12 +18758,21 @@ msgstr ""
msgid "InProductMarketing|Create a project in GitLab in 5 minutes"
msgstr ""
+msgid "InProductMarketing|Create well-defined workflows by using scoped labels on issues, merge requests, and epics. Labels with the same scope cannot be used together, which prevents conflicts."
+msgstr ""
+
msgid "InProductMarketing|Create your first project!"
msgstr ""
+msgid "InProductMarketing|Define who owns specific files or directories, so the right reviewers are suggested when a merge request introduces changes to those files."
+msgstr ""
+
msgid "InProductMarketing|Deliver Better Products Faster"
msgstr ""
+msgid "InProductMarketing|Dependency scanning"
+msgstr ""
+
msgid "InProductMarketing|Did you know teams that use GitLab are far more efficient?"
msgstr ""
@@ -18429,15 +18782,27 @@ msgstr ""
msgid "InProductMarketing|Dig in and create a project and a repo"
msgstr ""
+msgid "InProductMarketing|Discover Premium & Ultimate"
+msgstr ""
+
+msgid "InProductMarketing|Discover Premium & Ultimate."
+msgstr ""
+
msgid "InProductMarketing|Do you have a minute?"
msgstr ""
msgid "InProductMarketing|Do you have a teammate who would be perfect for this task?"
msgstr ""
+msgid "InProductMarketing|Dynamic application security testing"
+msgstr ""
+
msgid "InProductMarketing|Easy"
msgstr ""
+msgid "InProductMarketing|Epics"
+msgstr ""
+
msgid "InProductMarketing|Expand your DevOps journey with a free GitLab trial"
msgstr ""
@@ -18459,9 +18824,15 @@ msgstr ""
msgid "InProductMarketing|Feel the need for speed?"
msgstr ""
+msgid "InProductMarketing|Find and fix bottlenecks in your code review process by understanding how long open merge requests have been in review."
+msgstr ""
+
msgid "InProductMarketing|Find out how your teams are really doing"
msgstr ""
+msgid "InProductMarketing|Find out if your external libraries are safe. Run dependency scanning jobs that check for known vulnerabilities in your external libraries."
+msgstr ""
+
msgid "InProductMarketing|Follow our steps"
msgstr ""
@@ -18498,6 +18869,9 @@ msgstr ""
msgid "InProductMarketing|GitLab is better with teammates to help out!"
msgstr ""
+msgid "InProductMarketing|GitLab is infrastructure agnostic (supporting GCP, AWS, Azure, OpenShift, VMWare, On Prem, Bare Metal, and more), offering a consistent workflow experience – irrespective of the environment."
+msgstr ""
+
msgid "InProductMarketing|GitLab provides static application security testing (SAST), dynamic application security testing (DAST), container scanning, and dependency scanning to help you deliver secure applications along with license compliance."
msgstr ""
@@ -18588,21 +18962,36 @@ msgstr ""
msgid "InProductMarketing|It's also possible to simply %{external_repo_link} in order to take advantage of GitLab's CI/CD."
msgstr ""
+msgid "InProductMarketing|Keep your code quality high by defining who should approve merge requests and how many approvals are required."
+msgstr ""
+
msgid "InProductMarketing|Launch GitLab CI/CD in 20 minutes or less"
msgstr ""
+msgid "InProductMarketing|Lower cost of development"
+msgstr ""
+
+msgid "InProductMarketing|Make it easier to collaborate on high-level ideas by grouping related issues in an epic."
+msgstr ""
+
msgid "InProductMarketing|Making the switch? It's easier than you think to import your projects into GitLab. Move %{github_link}, or import something %{bitbucket_link}."
msgstr ""
msgid "InProductMarketing|Master the art of importing!"
msgstr ""
+msgid "InProductMarketing|Merge request approval rule"
+msgstr ""
+
msgid "InProductMarketing|Move on to easily creating a Pages website %{ci_template_link}"
msgstr ""
msgid "InProductMarketing|Multiple owners, confusing workstreams? We've got you covered"
msgstr ""
+msgid "InProductMarketing|Multiple required approvers"
+msgstr ""
+
msgid "InProductMarketing|Need an alternative to importing?"
msgstr ""
@@ -18615,18 +19004,33 @@ msgstr ""
msgid "InProductMarketing|Our tool brings all the things together"
msgstr ""
+msgid "InProductMarketing|Protect your web application by using DAST to examine for vulnerabilities in deployed environments."
+msgstr ""
+
msgid "InProductMarketing|Rapid development, simplified"
msgstr ""
msgid "InProductMarketing|Reduce Security & Compliance Risk"
msgstr ""
+msgid "InProductMarketing|Require multiple approvers on a merge request, so you know it's in good shape before it's merged."
+msgstr ""
+
+msgid "InProductMarketing|Roadmaps"
+msgstr ""
+
+msgid "InProductMarketing|Scoped labels"
+msgstr ""
+
msgid "InProductMarketing|Security that's integrated into your development lifecycle"
msgstr ""
msgid "InProductMarketing|Sometimes you're not ready to make a full transition to a new tool. If you're not ready to fully commit, %{mirroring_link} gives you a safe way to try out GitLab in parallel with your current tool."
msgstr ""
+msgid "InProductMarketing|Speed. Efficiency. Trust."
+msgstr ""
+
msgid "InProductMarketing|Spin up an autoscaling runner in GitLab"
msgstr ""
@@ -18636,6 +19040,9 @@ msgstr ""
msgid "InProductMarketing|Start a Self-Managed trial"
msgstr ""
+msgid "InProductMarketing|Start a free trial"
+msgstr ""
+
msgid "InProductMarketing|Start a free trial of GitLab Ultimate – no credit card required"
msgstr ""
@@ -18702,6 +19109,9 @@ msgstr ""
msgid "InProductMarketing|To understand and get the most out of GitLab, start at the beginning and %{project_link}. In GitLab, repositories are part of a project, so after you've created your project you can go ahead and %{repo_link}."
msgstr ""
+msgid "InProductMarketing|Track completed issues in a chart, so you can see how a milestone is progressing at a glance."
+msgstr ""
+
msgid "InProductMarketing|Try GitLab Ultimate for free"
msgstr ""
@@ -18738,6 +19148,9 @@ msgstr ""
msgid "InProductMarketing|Very easy"
msgstr ""
+msgid "InProductMarketing|Visualize your epics and milestones in a timeline."
+msgstr ""
+
msgid "InProductMarketing|Want to host GitLab on your servers?"
msgstr ""
@@ -18759,6 +19172,9 @@ msgstr ""
msgid "InProductMarketing|YouTube"
msgstr ""
+msgid "InProductMarketing|Your software, deployed your way"
+msgstr ""
+
msgid "InProductMarketing|Your teams can be more efficient"
msgstr ""
@@ -18879,9 +19295,18 @@ msgstr ""
msgid "IncidentManagement|No incidents to display."
msgstr ""
+msgid "IncidentManagement|None"
+msgstr ""
+
msgid "IncidentManagement|Open"
msgstr ""
+msgid "IncidentManagement|Page your team with escalation policies"
+msgstr ""
+
+msgid "IncidentManagement|Paged"
+msgstr ""
+
msgid "IncidentManagement|Published"
msgstr ""
@@ -18891,6 +19316,9 @@ msgstr ""
msgid "IncidentManagement|Severity"
msgstr ""
+msgid "IncidentManagement|Status"
+msgstr ""
+
msgid "IncidentManagement|There are no closed incidents"
msgstr ""
@@ -18909,6 +19337,9 @@ msgstr ""
msgid "IncidentManagement|Unpublished"
msgstr ""
+msgid "IncidentManagement|Use escalation policies to automatically page your team when incidents are created."
+msgstr ""
+
msgid "IncidentSettings|Activate \"time to SLA\" countdown timer"
msgstr ""
@@ -18954,7 +19385,10 @@ msgstr ""
msgid "Incidents"
msgstr ""
-msgid "Incidents|Add a URL"
+msgid "Incidents|Add image details"
+msgstr ""
+
+msgid "Incidents|Add text or a link to display with your image. If you don't add either, the file name displays instead."
msgstr ""
msgid "Incidents|Drop or %{linkStart}upload%{linkEnd} a metric screenshot to attach it to the incident"
@@ -18969,10 +19403,10 @@ msgstr ""
msgid "Incidents|There was an issue loading metric images."
msgstr ""
-msgid "Incidents|There was an issue uploading your image."
+msgid "Incidents|There was an issue updating your image."
msgstr ""
-msgid "Incidents|You can optionally add a URL to link users to the original graph."
+msgid "Incidents|There was an issue uploading your image."
msgstr ""
msgid "Incident|Alert details"
@@ -18981,9 +19415,18 @@ msgstr ""
msgid "Incident|Are you sure you wish to delete this image?"
msgstr ""
+msgid "Incident|Delete image"
+msgstr ""
+
msgid "Incident|Deleting %{filename}"
msgstr ""
+msgid "Incident|Edit image text or link"
+msgstr ""
+
+msgid "Incident|Editing %{filename}"
+msgstr ""
+
msgid "Incident|Metrics"
msgstr ""
@@ -19253,12 +19696,18 @@ msgstr ""
msgid "Integrations|Branches for which notifications are to be sent"
msgstr ""
+msgid "Integrations|Clear if using a self-signed certificate."
+msgstr ""
+
msgid "Integrations|Comment detail:"
msgstr ""
msgid "Integrations|Comment settings:"
msgstr ""
+msgid "Integrations|Connection details"
+msgstr ""
+
msgid "Integrations|Connection failed. Please check your settings."
msgstr ""
@@ -19283,6 +19732,9 @@ msgstr ""
msgid "Integrations|Enable GitLab.com slash commands in a Slack workspace."
msgstr ""
+msgid "Integrations|Enable SSL verification"
+msgstr ""
+
msgid "Integrations|Enable comments"
msgstr ""
@@ -19361,6 +19813,9 @@ msgstr ""
msgid "Integrations|Return to GitLab for Jira"
msgstr ""
+msgid "Integrations|SSL verification"
+msgstr ""
+
msgid "Integrations|Save settings?"
msgstr ""
@@ -19406,9 +19861,6 @@ msgstr ""
msgid "Integrations|Use default settings"
msgstr ""
-msgid "Integrations|When you mention a Jira issue in a commit or merge request, GitLab creates a remote link and comment (if enabled)."
-msgstr ""
-
msgid "Integrations|You can now close this window and return to the GitLab for Jira application."
msgstr ""
@@ -19433,9 +19885,6 @@ msgstr ""
msgid "Integrations|can't exceed %{recipients_limit}"
msgstr ""
-msgid "Interactive developer security education."
-msgstr ""
-
msgid "Interactive mode"
msgstr ""
@@ -19925,6 +20374,9 @@ msgstr ""
msgid "IssueAnalytics|Assignees"
msgstr ""
+msgid "IssueAnalytics|Created by"
+msgstr ""
+
msgid "IssueAnalytics|Due date"
msgstr ""
@@ -19937,9 +20389,6 @@ msgstr ""
msgid "IssueAnalytics|Milestone"
msgstr ""
-msgid "IssueAnalytics|Opened by"
-msgstr ""
-
msgid "IssueAnalytics|Status"
msgstr ""
@@ -20063,10 +20512,10 @@ msgstr ""
msgid "IssuesAnalytics|Avg/Month:"
msgstr ""
-msgid "IssuesAnalytics|Issues opened"
+msgid "IssuesAnalytics|Issues created"
msgstr ""
-msgid "IssuesAnalytics|Issues opened per month"
+msgid "IssuesAnalytics|Issues created per month"
msgstr ""
msgid "IssuesAnalytics|Last 12 months"
@@ -20093,6 +20542,9 @@ msgstr ""
msgid "It looks like you have some draft commits in this branch."
msgstr ""
+msgid "It looks like you're attempting to activate your subscription. Use %{a_start}the Subscription page%{a_end} instead."
+msgstr ""
+
msgid "It may be several days before you see feature usage data."
msgstr ""
@@ -20321,6 +20773,9 @@ msgstr ""
msgid "JiraConnect|You can now close this window and return to Jira."
msgstr ""
+msgid "JiraConnect|You don't have permission to create branches for this project. Select a different project or contact the project owner for access. %{linkStart}Learn more.%{linkEnd}"
+msgstr ""
+
msgid "JiraRequest|A connection error occurred while connecting to Jira. Try your request again."
msgstr ""
@@ -20369,13 +20824,13 @@ msgstr ""
msgid "JiraService|Define the type of Jira issue to create from a vulnerability."
msgstr ""
-msgid "JiraService|Displaying Jira issues while leaving the GitLab issue functionality enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
+msgid "JiraService|Displaying Jira issues while leaving GitLab issues also enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
msgstr ""
-msgid "JiraService|Enable Jira issues"
+msgid "JiraService|Enable Jira issue creation from vulnerabilities"
msgstr ""
-msgid "JiraService|Enable Jira issues creation from vulnerabilities"
+msgid "JiraService|Enable Jira issues"
msgstr ""
msgid "JiraService|Enable Jira transitions"
@@ -20492,16 +20947,19 @@ msgstr ""
msgid "JiraService|View Jira issues in GitLab"
msgstr ""
-msgid "JiraService|Warning: All GitLab users that have access to this GitLab project are able to view all issues from the Jira project specified below."
+msgid "JiraService|Warning: All GitLab users with access to this GitLab project can view all issues from the Jira project you select."
msgstr ""
msgid "JiraService|Web URL"
msgstr ""
-msgid "JiraService|Work on Jira issues without leaving GitLab. Adds a Jira menu to access your list of Jira issues and view any issue as read-only."
+msgid "JiraService|When a Jira issue is mentioned in a commit or merge request, a remote link and comment (if enabled) will be created."
+msgstr ""
+
+msgid "JiraService|Work on Jira issues without leaving GitLab. Add a Jira menu to access a read-only list of your Jira issues."
msgstr ""
-msgid "JiraService|You need to configure Jira before enabling this integration. For more details, read the %{jira_doc_link_start}Jira integration documentation%{link_end}."
+msgid "JiraService|You must configure Jira before enabling this integration. %{jira_doc_link_start}Learn more.%{link_end}"
msgstr ""
msgid "Job"
@@ -20513,9 +20971,6 @@ msgstr ""
msgid "Job Failed #%{build_id}"
msgstr ""
-msgid "Job ID"
-msgstr ""
-
msgid "Job artifact"
msgstr ""
@@ -20582,9 +21037,27 @@ msgstr ""
msgid "Jobs|You're about to retry a job that failed because it attempted to deploy code that is older than the latest deployment. Retrying this job could result in overwriting the environment with the older source code."
msgstr ""
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source} into %{target}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{ref}"
+msgstr ""
+
+msgid "Job|Are you sure you want to erase this job log and artifacts?"
+msgstr ""
+
msgid "Job|Browse"
msgstr ""
+msgid "Job|Cancel"
+msgstr ""
+
msgid "Job|Complete Raw"
msgstr ""
@@ -20594,6 +21067,9 @@ msgstr ""
msgid "Job|Erase job log and artifacts"
msgstr ""
+msgid "Job|Finished at"
+msgstr ""
+
msgid "Job|Job artifacts"
msgstr ""
@@ -20606,7 +21082,7 @@ msgstr ""
msgid "Job|Keep"
msgstr ""
-msgid "Job|Pipeline"
+msgid "Job|Retry"
msgstr ""
msgid "Job|Scroll to bottom"
@@ -20618,6 +21094,9 @@ msgstr ""
msgid "Job|Show complete raw"
msgstr ""
+msgid "Job|Status"
+msgstr ""
+
msgid "Job|The artifacts were removed"
msgstr ""
@@ -20645,21 +21124,12 @@ msgstr ""
msgid "Job|delayed"
msgstr ""
-msgid "Job|for"
-msgstr ""
-
-msgid "Job|into"
-msgstr ""
-
msgid "Job|manual"
msgstr ""
msgid "Job|triggered"
msgstr ""
-msgid "Job|with"
-msgstr ""
-
msgid "Join Zoom meeting"
msgstr ""
@@ -20762,9 +21232,6 @@ msgstr ""
msgid "Ki"
msgstr ""
-msgid "Kontra"
-msgstr ""
-
msgid "Kroki"
msgstr ""
@@ -21088,6 +21555,9 @@ msgstr ""
msgid "Learn more about Auto DevOps"
msgstr ""
+msgid "Learn more about GitLab"
+msgstr ""
+
msgid "Learn more about Needs relationships"
msgstr ""
@@ -21415,9 +21885,18 @@ msgstr ""
msgid "Licenses|Displays licenses detected in the project, based on the %{linkStart}latest successful%{linkEnd} scan"
msgstr ""
+msgid "Licenses|Drag your license file here or %{linkStart}click to upload%{linkEnd}."
+msgstr ""
+
+msgid "Licenses|Drop your license file to start the upload."
+msgstr ""
+
msgid "Licenses|Error fetching the license list. Please check your network connection and try again."
msgstr ""
+msgid "Licenses|Error: You are trying to upload something other than a file"
+msgstr ""
+
msgid "Licenses|License Compliance"
msgstr ""
@@ -21436,6 +21915,9 @@ msgstr ""
msgid "Licenses|Specified policies in this project"
msgstr ""
+msgid "Licenses|The file could not be uploaded."
+msgstr ""
+
msgid "Licenses|The license list details information about the licenses used within your project."
msgstr ""
@@ -21469,11 +21951,6 @@ msgstr ""
msgid "Limit the size of Sidekiq jobs stored in Redis."
msgstr ""
-msgid "Limited to showing %d event at most"
-msgid_plural "Limited to showing %d events at most"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Limiting mode"
msgstr ""
@@ -21483,6 +21960,9 @@ msgstr ""
msgid "Link"
msgstr ""
+msgid "Link (optional)"
+msgstr ""
+
msgid "Link Prometheus monitoring to GitLab."
msgstr ""
@@ -21519,6 +21999,9 @@ msgstr ""
msgid "Linked emails (%{email_count})"
msgstr ""
+msgid "Linked epics"
+msgstr ""
+
msgid "Linked issues"
msgstr ""
@@ -21546,6 +22029,15 @@ msgstr ""
msgid "List of all merge commits"
msgstr ""
+msgid "List of environments for this project"
+msgstr ""
+
+msgid "List of suitable GCP locations"
+msgstr ""
+
+msgid "List of users allowed to exceed the rate limit."
+msgstr ""
+
msgid "List options"
msgstr ""
@@ -21765,6 +22257,9 @@ msgstr ""
msgid "Maintenance mode"
msgstr ""
+msgid "Make adjustments to how your GitLab instance is set up."
+msgstr ""
+
msgid "Make and review changes in the browser with the Web IDE"
msgstr ""
@@ -21909,6 +22404,12 @@ msgstr ""
msgid "MarkdownEditor|Add italic text (%{modifier_key}I)"
msgstr ""
+msgid "MarkdownEditor|Add strikethrough text (%{modifierKey}⇧X)"
+msgstr ""
+
+msgid "MarkdownEditor|Add strikethrough text (%{modifier_key}⇧X)"
+msgstr ""
+
msgid "Marked For Deletion At - %{deletion_time}"
msgstr ""
@@ -22170,6 +22671,9 @@ msgstr ""
msgid "Maximum push size (MB)"
msgstr ""
+msgid "Maximum requests per 10 minutes per user"
+msgstr ""
+
msgid "Maximum requests per minute"
msgstr ""
@@ -22260,6 +22764,19 @@ msgstr ""
msgid "Members of a group may only view projects they have permission to access"
msgstr ""
+msgid "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seat in use and will be billed for the overage."
+msgid_plural "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seats in use and will be billed for the overage."
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "MembersOverage|You are about to incur additional charges"
+msgstr ""
+
+msgid "MembersOverage|Your subscription includes %d seat."
+msgid_plural "MembersOverage|Your subscription includes %d seats."
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Membership"
msgstr ""
@@ -22464,9 +22981,6 @@ msgstr ""
msgid "Merge request not merged"
msgstr ""
-msgid "Merge request pipelines 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 merge request pipelines."
-msgstr ""
-
msgid "Merge request reports"
msgstr ""
@@ -22563,13 +23077,13 @@ msgstr ""
msgid "MergeRequests|Create issue to resolve thread"
msgstr ""
-msgid "MergeRequests|Failed to squash. Should be done manually."
+msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Saving the comment failed"
+msgid "MergeRequests|Squashing failed: Squash the commits locally, resolve any conflicts, then push the branch."
msgstr ""
-msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
+msgid "MergeRequests|Squashing not allowed: This project doesn't allow you to squash commits when merging."
msgstr ""
msgid "MergeRequests|Thread stays resolved"
@@ -23410,6 +23924,18 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "MrList|Assigned to %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from assignee %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from reviewer %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Review requested from %{name}, go to their profile."
+msgstr ""
+
msgid "Multi-project"
msgstr ""
@@ -23443,7 +23969,7 @@ msgstr ""
msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "My Awesome Group"
+msgid "My awesome group"
msgstr ""
msgid "My company or team"
@@ -24065,9 +24591,6 @@ msgstr ""
msgid "No available branches"
msgstr ""
-msgid "No available groups to fork the project."
-msgstr ""
-
msgid "No branches found"
msgstr ""
@@ -24278,6 +24801,9 @@ msgstr ""
msgid "No ref selected"
msgstr ""
+msgid "No regions configured"
+msgstr ""
+
msgid "No related merge requests found."
msgstr ""
@@ -25082,6 +25608,9 @@ msgstr ""
msgid "Only reCAPTCHA v2 is supported:"
msgstr ""
+msgid "Only required if not using role instance credentials."
+msgstr ""
+
msgid "Only use lowercase letters, numbers, and underscores."
msgstr ""
@@ -25106,9 +25635,6 @@ msgstr ""
msgid "Open a CLI and connect to the cluster you want to install the agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
-msgid "Open epics"
-msgstr ""
-
msgid "Open errors"
msgstr ""
@@ -25148,7 +25674,7 @@ msgstr ""
msgid "Opened issues"
msgstr ""
-msgid "OpenedNDaysAgo|Opened"
+msgid "OpenedNDaysAgo|Created"
msgstr ""
msgid "Opens in a new window"
@@ -25193,9 +25719,6 @@ msgstr ""
msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
-msgid "Optional."
-msgstr ""
-
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
msgstr ""
@@ -25984,6 +26507,9 @@ msgstr ""
msgid "PerformanceBar|Memory"
msgstr ""
+msgid "PerformanceBar|Memory report"
+msgstr ""
+
msgid "PerformanceBar|Redis calls"
msgstr ""
@@ -26017,18 +26543,12 @@ msgstr ""
msgid "PerformanceBar|wall"
msgstr ""
-msgid "Performs a rebase but skips triggering a new pipeline"
-msgstr ""
-
msgid "Period in seconds"
msgstr ""
msgid "Permalink"
msgstr ""
-msgid "Permanently delete project"
-msgstr ""
-
msgid "Permanently remove group"
msgstr ""
@@ -26299,6 +26819,51 @@ msgstr ""
msgid "PipelineStatusTooltip|Pipeline: %{ci_status}"
msgstr ""
+msgid "PipelineWizardDefaultCommitMessage|Add %{filename}"
+msgstr ""
+
+msgid "PipelineWizardDefaultCommitMessage|Update %{filename}"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|At least one entry is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This field is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This value is not valid"
+msgstr ""
+
+msgid "PipelineWizardListWidget|add another step"
+msgstr ""
+
+msgid "PipelineWizardListWidget|remove step"
+msgstr ""
+
+msgid "PipelineWizard|Commit"
+msgstr ""
+
+msgid "PipelineWizard|Commit Message"
+msgstr ""
+
+msgid "PipelineWizard|Commit changes to your file"
+msgstr ""
+
+msgid "PipelineWizard|Commit file to Branch"
+msgstr ""
+
+msgid "PipelineWizard|Commit your new file"
+msgstr ""
+
+msgid "PipelineWizard|The file has been committed."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem committing the changes."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem while checking whether your file already exists in the specified branch."
+msgstr ""
+
msgid "Pipelines"
msgstr ""
@@ -26413,7 +26978,7 @@ msgstr ""
msgid "Pipelines|Project cache successfully reset."
msgstr ""
-msgid "Pipelines|Revoke"
+msgid "Pipelines|Revoke trigger"
msgstr ""
msgid "Pipelines|Something went wrong while cleaning runners cache."
@@ -26458,6 +27023,12 @@ msgstr ""
msgid "Pipelines|This is a child pipeline within the parent pipeline"
msgstr ""
+msgid "Pipelines|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipelines|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipelines|This pipeline will run code originating from a forked project merge request. This means that the code can potentially have security considerations like exposing CI variables."
msgstr ""
@@ -26500,9 +27071,6 @@ msgstr ""
msgid "Pipelines|Your changes have been successfully committed. Now redirecting to the new merge request page."
msgstr ""
-msgid "Pipelines|detached"
-msgstr ""
-
msgid "Pipelines|error"
msgstr ""
@@ -26512,10 +27080,13 @@ msgstr ""
msgid "Pipelines|latest"
msgstr ""
-msgid "Pipelines|stuck"
+msgid "Pipelines|merge request"
msgstr ""
-msgid "Pipelines|train"
+msgid "Pipelines|merge train"
+msgstr ""
+
+msgid "Pipelines|stuck"
msgstr ""
msgid "Pipelines|yaml invalid"
@@ -26647,6 +27218,12 @@ msgstr ""
msgid "Pipeline|This change will not change the overall test coverage if merged."
msgstr ""
+msgid "Pipeline|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipeline|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipeline|Trigger author"
msgstr ""
@@ -26671,6 +27248,12 @@ msgstr ""
msgid "Pipeline|for"
msgstr ""
+msgid "Pipeline|merge request"
+msgstr ""
+
+msgid "Pipeline|merge train"
+msgstr ""
+
msgid "Pipeline|on"
msgstr ""
@@ -26809,9 +27392,6 @@ msgstr ""
msgid "Please enter a valid time interval"
msgstr ""
-msgid "Please enter or upload a valid license."
-msgstr ""
-
msgid "Please enter your current password."
msgstr ""
@@ -26920,9 +27500,6 @@ msgstr ""
msgid "Please type %{phrase_code} to proceed or close this modal to cancel."
msgstr ""
-msgid "Please type the following to confirm:"
-msgstr ""
-
msgid "Please use this form to report to the admin users who create spam issues, comments or behave inappropriately."
msgstr ""
@@ -26950,12 +27527,27 @@ msgstr ""
msgid "Policies"
msgstr ""
+msgid "Policy '%{escalation_policy_name}' does not exist."
+msgstr ""
+
msgid "Policy management project does have any policies in %{policy_path}"
msgstr ""
msgid "Policy project doesn't exist"
msgstr ""
+msgid "PolicyRuleMultiSelect|%{firstLabel} +%{numberOfAdditionalLabels} more"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|All %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select all"
+msgstr ""
+
msgid "Polling interval multiplier"
msgstr ""
@@ -27184,6 +27776,9 @@ msgstr ""
msgid "Private projects can be created in your personal namespace with:"
msgstr ""
+msgid "Problem with %{name} command: %{message}."
+msgstr ""
+
msgid "Proceed"
msgstr ""
@@ -27658,6 +28253,9 @@ msgstr ""
msgid "Progress"
msgstr ""
+msgid "Progress tracking"
+msgstr ""
+
msgid "Project"
msgstr ""
@@ -27889,6 +28487,9 @@ msgstr ""
msgid "ProjectQualitySummary|Failure"
msgstr ""
+msgid "ProjectQualitySummary|Get insight into the overall percentage of tests in your project that succeed, fail and are skipped."
+msgstr ""
+
msgid "ProjectQualitySummary|Latest pipeline results"
msgstr ""
@@ -27907,6 +28508,12 @@ msgstr ""
msgid "ProjectQualitySummary|See project Code Coverage Statistics"
msgstr ""
+msgid "ProjectQualitySummary|Set up test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|Set up test runs (opens in a new tab)"
+msgstr ""
+
msgid "ProjectQualitySummary|Skipped"
msgstr ""
@@ -28183,13 +28790,19 @@ msgstr ""
msgid "ProjectSettings|LFS objects from this repository are available to forks. %{linkStart}How do I remove them?%{linkEnd}"
msgstr ""
+msgid "ProjectSettings|Learn about commit history."
+msgstr ""
+
+msgid "ProjectSettings|Leave empty to use default template."
+msgstr ""
+
msgid "ProjectSettings|Manage who can see the project in the public access directory."
msgstr ""
msgid "ProjectSettings|Manages large files such as audio, video, and graphics files."
msgstr ""
-msgid "ProjectSettings|Maximum 500 characters."
+msgid "ProjectSettings|Maximum %{maxLength} characters."
msgstr ""
msgid "ProjectSettings|Merge checks"
@@ -28330,6 +28943,9 @@ msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
msgstr ""
+msgid "ProjectSettings|The default template will be applied on save."
+msgstr ""
+
msgid "ProjectSettings|These checks must pass before merge requests can be merged."
msgstr ""
@@ -28384,6 +29000,9 @@ msgstr ""
msgid "ProjectSettings|What are badges?"
msgstr ""
+msgid "ProjectSettings|What are merge trains?"
+msgstr ""
+
msgid "ProjectSettings|When merge request pipelines are enabled in the CI/CD configuration file, pipelines validate the combined results of the source and target branches. %{link_start}How to configure merge request pipelines?%{link_end}"
msgstr ""
@@ -28501,6 +29120,9 @@ msgstr ""
msgid "Projects are organized into groups"
msgstr ""
+msgid "Projects are where you store your code, access issues, wiki and other features of GitLab."
+msgstr ""
+
msgid "Projects contributed to"
msgstr ""
@@ -28516,12 +29138,6 @@ msgstr ""
msgid "Projects to index"
msgstr ""
-msgid "Projects will be permanently deleted after a %{waiting_period}-day waiting period."
-msgstr ""
-
-msgid "Projects will be permanently deleted immediately."
-msgstr ""
-
msgid "Projects with critical vulnerabilities"
msgstr ""
@@ -28606,6 +29222,9 @@ msgstr ""
msgid "ProjectsNew|Import project"
msgstr ""
+msgid "ProjectsNew|Include a Getting Started README"
+msgstr ""
+
msgid "ProjectsNew|Initialize repository with a README"
msgstr ""
@@ -28621,6 +29240,9 @@ msgstr ""
msgid "ProjectsNew|Project description %{tag_start}(optional)%{tag_end}"
msgstr ""
+msgid "ProjectsNew|Recommended if you're new to GitLab"
+msgstr ""
+
msgid "ProjectsNew|Run CI/CD for external repository"
msgstr ""
@@ -29038,6 +29660,9 @@ msgstr ""
msgid "ProtectedBranch|Unprotect"
msgstr ""
+msgid "ProtectedBranch|Unprotect branch"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
@@ -29065,6 +29690,9 @@ msgstr ""
msgid "ProtectedEnvironment|Protected Environment (%{protected_environments_count})"
msgstr ""
+msgid "ProtectedEnvironment|Required approvals"
+msgstr ""
+
msgid "ProtectedEnvironment|Select an environment"
msgstr ""
@@ -29086,10 +29714,13 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|Unprotect tag"
+msgstr ""
+
msgid "ProtectedTags|default"
msgstr ""
-msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
+msgid "ProtectedTag|By default, protected tags restrict who can modify the tag."
msgstr ""
msgid "ProtectedTag|Learn more."
@@ -29152,6 +29783,9 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Public projects are an easy way to allow everyone to have read-only access."
+msgstr ""
+
msgid "Publish to status page"
msgstr ""
@@ -29308,9 +29942,6 @@ msgstr ""
msgid "QualitySummary|Project quality"
msgstr ""
-msgid "Quarters"
-msgstr ""
-
msgid "Query"
msgstr ""
@@ -29395,6 +30026,9 @@ msgstr ""
msgid "Read more about project permissions %{help_link_open}here%{help_link_close}"
msgstr ""
+msgid "Read more about related epics"
+msgstr ""
+
msgid "Read more about related issues"
msgstr ""
@@ -29425,10 +30059,7 @@ msgstr ""
msgid "Rebase source branch on the target branch."
msgstr ""
-msgid "Rebase without CI"
-msgstr ""
-
-msgid "Rebases and triggers a pipeline"
+msgid "Rebase without pipeline"
msgstr ""
msgid "Recaptcha verified?"
@@ -29479,9 +30110,6 @@ msgstr ""
msgid "Reconfigure"
msgstr ""
-msgid "Recovering projects"
-msgstr ""
-
msgid "Recovery Codes"
msgstr ""
@@ -29541,6 +30169,12 @@ msgstr ""
msgid "Regex pattern"
msgstr ""
+msgid "Region"
+msgstr ""
+
+msgid "Regions"
+msgstr ""
+
msgid "Register"
msgstr ""
@@ -29771,9 +30405,6 @@ msgstr ""
msgid "Remove all or specific reviewer(s)"
msgstr ""
-msgid "Remove approver"
-msgstr ""
-
msgid "Remove approvers"
msgstr ""
@@ -29789,6 +30420,9 @@ msgstr ""
msgid "Remove attention request"
msgstr ""
+msgid "Remove attention request(s)"
+msgstr ""
+
msgid "Remove avatar"
msgstr ""
@@ -29927,6 +30561,9 @@ msgstr ""
msgid "Removed an issue from an epic."
msgstr ""
+msgid "Removed attention from %{users_sentence}."
+msgstr ""
+
msgid "Removed attention request from @%{username}"
msgstr ""
@@ -29978,6 +30615,9 @@ msgstr ""
msgid "Removes an issue from an epic."
msgstr ""
+msgid "Removes attention from %{users_sentence}."
+msgstr ""
+
msgid "Removes parent epic %{epic_ref}."
msgstr ""
@@ -30089,6 +30729,9 @@ msgstr ""
msgid "Report abuse to admin"
msgstr ""
+msgid "Report is generating and will be sent to your email address."
+msgstr ""
+
msgid "Reported %{timeAgo} by %{reportedBy}"
msgstr ""
@@ -30378,6 +31021,15 @@ msgstr ""
msgid "Request attention"
msgstr ""
+msgid "Request attention from %{users_sentence}."
+msgstr ""
+
+msgid "Request attention from assignee or reviewer"
+msgstr ""
+
+msgid "Request attention from assignee(s) or reviewer(s)"
+msgstr ""
+
msgid "Request attention to review"
msgstr ""
@@ -30402,6 +31054,9 @@ msgstr ""
msgid "Requested %{time_ago}"
msgstr ""
+msgid "Requested attention from %{users_sentence}."
+msgstr ""
+
msgid "Requested attention from @%{username}"
msgstr ""
@@ -30616,6 +31271,9 @@ msgstr ""
msgid "Restore project"
msgstr ""
+msgid "Restoring projects"
+msgstr ""
+
msgid "Restoring the group will prevent the group, its subgroups and projects from being removed on this date."
msgstr ""
@@ -30646,6 +31304,9 @@ msgstr ""
msgid "Retry"
msgstr ""
+msgid "Retry failed jobs"
+msgstr ""
+
msgid "Retry job"
msgstr ""
@@ -30693,9 +31354,6 @@ msgstr ""
msgid "Review changes"
msgstr ""
-msgid "Review requested from %{name}"
-msgstr ""
-
msgid "Review requests for you"
msgstr ""
@@ -30860,6 +31518,9 @@ msgstr ""
msgid "Runners|Assigned Group"
msgstr ""
+msgid "Runners|Assigned Projects (%{projectCount})"
+msgstr ""
+
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30929,6 +31590,9 @@ msgstr ""
msgid "Runners|Instance"
msgstr ""
+msgid "Runners|Jobs"
+msgstr ""
+
msgid "Runners|Last contact"
msgstr ""
@@ -31022,9 +31686,6 @@ msgstr ""
msgid "Runners|Runner %{name} was deleted"
msgstr ""
-msgid "Runners|Runner ID"
-msgstr ""
-
msgid "Runners|Runner assigned to project."
msgstr ""
@@ -31172,6 +31833,9 @@ msgstr ""
msgid "Runners|stale"
msgstr ""
+msgid "Runner|This runner has not run any jobs."
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -31286,6 +31950,24 @@ msgstr ""
msgid "Saving project."
msgstr ""
+msgid "ScanResultPolicy|%{ifLabelStart}if%{ifLabelEnd} %{scanners} scan in an open merge request targeting the %{branches} branch(es) finds %{vulnerabilitiesAllowed} or more %{severities} vulnerabilities that are %{vulnerabilityStates}"
+msgstr ""
+
+msgid "ScanResultPolicy|%{thenLabelStart}Then%{thenLabelEnd} Require approval from %{approvalsRequired} of the following approvers: %{approvers}"
+msgstr ""
+
+msgid "ScanResultPolicy|add an approver"
+msgstr ""
+
+msgid "ScanResultPolicy|scanners"
+msgstr ""
+
+msgid "ScanResultPolicy|severity levels"
+msgstr ""
+
+msgid "ScanResultPolicy|vulnerability states"
+msgstr ""
+
msgid "Scanner"
msgstr ""
@@ -31418,6 +32100,9 @@ msgstr ""
msgid "Search for a user"
msgstr ""
+msgid "Search for an emoji"
+msgstr ""
+
msgid "Search for projects, issues, etc."
msgstr ""
@@ -31605,18 +32290,12 @@ msgstr ""
msgid "Secret Detection"
msgstr ""
-msgid "Secret access key"
-msgstr ""
-
msgid "Secret token"
msgstr ""
msgid "Secure token that identifies an external storage request."
msgstr ""
-msgid "SecureCodeWarrior"
-msgstr ""
-
msgid "Security"
msgstr ""
@@ -31641,9 +32320,6 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "Security training with guide and learning pathways."
-msgstr ""
-
msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
@@ -31746,7 +32422,7 @@ msgstr ""
msgid "SecurityConfiguration|Manage corpus"
msgstr ""
-msgid "SecurityConfiguration|Manage corpus files used as mutation sources in coverage fuzzing."
+msgid "SecurityConfiguration|Manage corpus files used as seed inputs with coverage-guided fuzzing."
msgstr ""
msgid "SecurityConfiguration|Manage profiles for use by DAST scans."
@@ -31812,15 +32488,15 @@ msgstr ""
msgid "SecurityOrchestration|.yaml preview"
msgstr ""
-msgid "SecurityOrchestration|Action"
-msgstr ""
-
msgid "SecurityOrchestration|Actions"
msgstr ""
msgid "SecurityOrchestration|Add rule"
msgstr ""
+msgid "SecurityOrchestration|After dismissing the alert, the information will never be shown again."
+msgstr ""
+
msgid "SecurityOrchestration|All policies"
msgstr ""
@@ -31836,7 +32512,7 @@ msgstr ""
msgid "SecurityOrchestration|Description"
msgstr ""
-msgid "SecurityOrchestration|Disabled"
+msgid "SecurityOrchestration|Don't show the alert anymore"
msgstr ""
msgid "SecurityOrchestration|Edit policy"
@@ -31845,13 +32521,13 @@ msgstr ""
msgid "SecurityOrchestration|Edit policy project"
msgstr ""
-msgid "SecurityOrchestration|Enabled"
+msgid "SecurityOrchestration|Empty policy name"
msgstr ""
-msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Enabled"
msgstr ""
-msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
msgstr ""
msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
@@ -31860,7 +32536,7 @@ msgstr ""
msgid "SecurityOrchestration|Invalid policy type"
msgstr ""
-msgid "SecurityOrchestration|Latest scan"
+msgid "SecurityOrchestration|Latest scan run against %{agent}"
msgstr ""
msgid "SecurityOrchestration|Network"
@@ -31869,15 +32545,27 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No actions defined - policy will not run."
+msgstr ""
+
+msgid "SecurityOrchestration|No description"
+msgstr ""
+
msgid "SecurityOrchestration|No rules defined - policy will not run."
msgstr ""
+msgid "SecurityOrchestration|Not enabled"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
msgid "SecurityOrchestration|Policies"
msgstr ""
+msgid "SecurityOrchestration|Policy Type"
+msgstr ""
+
msgid "SecurityOrchestration|Policy cannot be enabled for non-existing branches (%{branches})"
msgstr ""
@@ -31902,10 +32590,13 @@ msgstr ""
msgid "SecurityOrchestration|Require %{approvals} %{plural} from %{approvers} if any of the following occur:"
msgstr ""
-msgid "SecurityOrchestration|Rule"
+msgid "SecurityOrchestration|Rules"
msgstr ""
-msgid "SecurityOrchestration|Rules"
+msgid "SecurityOrchestration|Runs %{actions} and %{lastAction} scans"
+msgstr ""
+
+msgid "SecurityOrchestration|Runs a %{action} scan"
msgstr ""
msgid "SecurityOrchestration|Scan Execution"
@@ -31965,6 +32656,9 @@ msgstr ""
msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
+msgid "SecurityOrchestration|This view only shows scan results for the agent %{agent}. You can view scan results for all agents in the %{linkStart}Operational Vulnerabilities tab of the vulnerability report%{linkEnd}."
+msgstr ""
+
msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
@@ -32019,9 +32713,6 @@ msgstr ""
msgid "SecurityOrchestration|users with ids"
msgstr ""
-msgid "SecurityOrchestration|view results"
-msgstr ""
-
msgid "SecurityOrchestration|vulnerabilities"
msgstr ""
@@ -32691,22 +33382,19 @@ 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|In order to start using functions as a service, you must first install Knative on your Kubernetes cluster. %{linkStart}More information%{linkEnd}"
-msgstr ""
-
msgid "Serverless|Learn more about Serverless"
msgstr ""
msgid "Serverless|No functions available"
msgstr ""
-msgid "Serverless|Sign up for First Look"
+msgid "Serverless|Serverless was %{linkStart}deprecated%{linkEnd} in GitLab 14.3."
+msgstr ""
+
+msgid "Serverless|Serverless was %{postLinkStart}deprecated%{postLinkEnd}. But if you opt to use it, you must install Knative in your Kubernetes cluster first. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "Serverless|The deploy job has not finished."
@@ -32718,9 +33406,6 @@ 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 ""
@@ -32736,9 +33421,6 @@ msgstr ""
msgid "Service Account Key"
msgstr ""
-msgid "Service Accounts"
-msgstr ""
-
msgid "Service Accounts keys authorize GitLab to deploy your Google Cloud project"
msgstr ""
@@ -32748,10 +33430,10 @@ msgstr ""
msgid "Service Desk allows people to create issues in your GitLab instance without their own user account. It provides a unique email address for end users to create issues in a project. Replies can be sent either through the GitLab interface or by email. End users only see threads through email."
msgstr ""
-msgid "Service Usage Data"
+msgid "Service account generated successfully"
msgstr ""
-msgid "Service account generated successfully"
+msgid "Service accounts"
msgstr ""
msgid "Service ping is disabled in your configuration file, and cannot be enabled through this form."
@@ -32895,6 +33577,9 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
+msgid "Set the per-user rate limit for getting a user by ID via the API."
+msgstr ""
+
msgid "Set the per-user rate limit for notes created by web or API requests."
msgstr ""
@@ -33074,6 +33759,9 @@ msgstr ""
msgid "Shared runners details"
msgstr ""
+msgid "Shared runners enabled cannot be enabled until a valid credit card is on file"
+msgstr ""
+
msgid "Shared runners help link"
msgstr ""
@@ -33131,6 +33819,9 @@ msgstr ""
msgid "Show all issues."
msgstr ""
+msgid "Show all milestones"
+msgstr ""
+
msgid "Show all test cases."
msgstr ""
@@ -33167,6 +33858,9 @@ msgstr ""
msgid "Show file contents"
msgstr ""
+msgid "Show group milestones"
+msgstr ""
+
msgid "Show labels"
msgstr ""
@@ -33182,6 +33876,12 @@ msgstr ""
msgid "Show open epics"
msgstr ""
+msgid "Show project milestones"
+msgstr ""
+
+msgid "Show sub-group milestones"
+msgstr ""
+
msgid "Show the Closed list"
msgstr ""
@@ -33191,11 +33891,6 @@ msgstr ""
msgid "Show whitespace changes"
msgstr ""
-msgid "Showing %d event"
-msgid_plural "Showing %d events"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Showing %{conflict} between %{sourceBranch} and %{targetBranch}"
msgstr ""
@@ -33255,12 +33950,6 @@ msgstr ""
msgid "Sidebar|None"
msgstr ""
-msgid "Sidebar|Only numeral characters allowed"
-msgstr ""
-
-msgid "Sidebar|Weight"
-msgstr ""
-
msgid "Sidekiq job compression threshold (bytes)"
msgstr ""
@@ -33423,6 +34112,9 @@ msgstr ""
msgid "Slack logo"
msgstr ""
+msgid "SlackIntegration|Are you sure you want to remove this project from the Slack application?"
+msgstr ""
+
msgid "SlackIntegration|GitLab for Slack"
msgstr ""
@@ -33432,6 +34124,9 @@ msgstr ""
msgid "SlackIntegration|Project alias"
msgstr ""
+msgid "SlackIntegration|Remove project"
+msgstr ""
+
msgid "SlackIntegration|Select a GitLab project to link with your Slack workspace."
msgstr ""
@@ -33576,9 +34271,6 @@ msgstr ""
msgid "Something went wrong trying to load issue contacts."
msgstr ""
-msgid "Something went wrong when creating a work item. Please try again"
-msgstr ""
-
msgid "Something went wrong when reordering designs. Please try again"
msgstr ""
@@ -33672,9 +34364,6 @@ msgstr ""
msgid "Something went wrong while inserting your image. Please try again."
msgstr ""
-msgid "Something went wrong while merging this merge request. Please try again."
-msgstr ""
-
msgid "Something went wrong while obtaining the Let's Encrypt certificate."
msgstr ""
@@ -33996,10 +34685,10 @@ 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."
+msgid "SourcegraphAdmin|Learn more."
msgstr ""
-msgid "SourcegraphAdmin|More information"
+msgid "SourcegraphAdmin|Only public projects have code intelligence enabled and communicate with Sourcegraph."
msgstr ""
msgid "SourcegraphAdmin|Save changes"
@@ -34008,7 +34697,7 @@ msgstr ""
msgid "SourcegraphAdmin|Sourcegraph URL"
msgstr ""
-msgid "SourcegraphAdmin|e.g. https://sourcegraph.example.com"
+msgid "SourcegraphAdmin|https://sourcegraph.example.com"
msgstr ""
msgid "SourcegraphPreferences|This feature is experimental and currently limited to certain projects."
@@ -34143,6 +34832,9 @@ msgstr ""
msgid "Start date"
msgstr ""
+msgid "Start free trial"
+msgstr ""
+
msgid "Start merge train"
msgstr ""
@@ -34173,6 +34865,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started escalation for this incident."
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -34185,6 +34880,9 @@ msgstr ""
msgid "Starts at (UTC)"
msgstr ""
+msgid "Starts escalations for this incident"
+msgstr ""
+
msgid "Starts on"
msgstr ""
@@ -34446,6 +35144,9 @@ msgstr ""
msgid "Strikethrough"
msgstr ""
+msgid "Strikethrough text"
+msgstr ""
+
msgid "Subgroup information"
msgstr ""
@@ -34680,6 +35381,21 @@ msgstr ""
msgid "Subscriptions"
msgstr ""
+msgid "Subscriptions|Chat with sales"
+msgstr ""
+
+msgid "Subscriptions|Close"
+msgstr ""
+
+msgid "Subscriptions|Not ready to buy yet?"
+msgstr ""
+
+msgid "Subscriptions|Start a free trial"
+msgstr ""
+
+msgid "Subscriptions|We understand. Maybe you have some questions for our sales team, or maybe you'd like to try some of the paid features first. What would you like to do?"
+msgstr ""
+
msgid "Subscription|Your subscription for %{strong}%{namespace_name}%{strong_close} has expired and you are now on %{pricing_link_start}the GitLab Free tier%{pricing_link_end}. Don't worry, your data is safe. Get in touch with our support team (%{support_email}). They'll gladly help with your subscription renewal."
msgstr ""
@@ -34890,6 +35606,9 @@ msgstr ""
msgid "SuperSonics|Maximum users"
msgstr ""
+msgid "SuperSonics|Offline cloud"
+msgstr ""
+
msgid "SuperSonics|Paste your activation code"
msgstr ""
@@ -34956,6 +35675,12 @@ msgstr ""
msgid "SuperSonics|You do not have an active subscription"
msgstr ""
+msgid "SuperSonics|You have a future dated license"
+msgstr ""
+
+msgid "SuperSonics|You have added a license that activates on %{date}. Please see the subscription history table below for more details."
+msgstr ""
+
msgid "SuperSonics|You have successfully added a license that activates on %{date}. Please see the subscription history table below for more details."
msgstr ""
@@ -35115,6 +35840,9 @@ msgstr ""
msgid "Tag name is required"
msgstr ""
+msgid "Tag push"
+msgstr ""
+
msgid "Tag push events"
msgstr ""
@@ -35217,6 +35945,9 @@ msgstr ""
msgid "TagsPage|protected"
msgstr ""
+msgid "Take a look at the documentation to discover all of GitLab’s capabilities."
+msgstr ""
+
msgid "Target Branch"
msgstr ""
@@ -35619,6 +36350,9 @@ msgstr ""
msgid "Tests"
msgstr ""
+msgid "Text (optional)"
+msgstr ""
+
msgid "Text added to the body of all email messages. %{character_limit} character limit"
msgstr ""
@@ -35669,6 +36403,9 @@ msgstr ""
msgid "The CSV export will be created in the background. Once finished, it will be sent to %{email} in an attachment."
msgstr ""
+msgid "The CSV export you requested of all user memberships is attached to this email."
+msgstr ""
+
msgid "The GitLab subscription service (customers.gitlab.com) is currently experiencing an outage. You can monitor the status and get updates at %{linkStart}status.gitlab.com%{linkEnd}."
msgstr ""
@@ -35744,6 +36481,9 @@ 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 epic"
+msgstr ""
+
msgid "The current issue"
msgstr ""
@@ -35905,6 +36645,9 @@ msgstr ""
msgid "The latest pipeline for this merge request has failed."
msgstr ""
+msgid "The license key is invalid."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -35920,6 +36663,9 @@ msgstr ""
msgid "The license was successfully uploaded and will be active from %{starts_at}. You can see the details below."
msgstr ""
+msgid "The license you uploaded is invalid. If the issue persists, contact support at %{link}."
+msgstr ""
+
msgid "The list creation wizard is already open"
msgstr ""
@@ -36541,10 +37287,13 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} and everything this project contains. %{strongOpen}There is no going back%{strongClose}"
+msgstr ""
+
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains."
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}on %{date}%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains. %{strongOpen}There is no going back.%{strongClose}"
msgstr ""
msgid "This action will %{strongOpen}permanently remove%{strongClose} %{codeOpen}%{group}%{codeClose} %{strongOpen}immediately%{strongClose}."
@@ -36673,9 +37422,6 @@ msgstr ""
msgid "This file was modified for readability, and can't accept suggestions. Edit it directly."
msgstr ""
-msgid "This forked project has the following:"
-msgstr ""
-
msgid "This form is disabled in preview"
msgstr ""
@@ -36688,7 +37434,7 @@ msgstr ""
msgid "This group can't be removed because it is linked to a subscription. To remove this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
-msgid "This group can't be transfered because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
+msgid "This group can't be transferred because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
msgid "This group cannot be invited to a project inside a group with enforced SSO"
@@ -36715,6 +37461,9 @@ 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 incident is already escalated with '%{escalation_policy_name}'."
+msgstr ""
+
msgid "This invitation was sent to %{mail_to_invite_email}, but you are signed in as %{link_to_current_user} with email %{mail_to_current_user}."
msgstr ""
@@ -36733,9 +37482,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 merge train pipeline"
-msgstr ""
-
msgid "This is a private email address %{helpIcon} generated just for you. Anyone who has it can create issues or merge requests as if they were you. If that happens, %{resetLinkStart}reset this token%{resetLinkEnd}."
msgstr ""
@@ -36757,6 +37503,12 @@ msgstr ""
msgid "This is your current session"
msgstr ""
+msgid "This issue cannot be assigned to a confidential epic because it is public."
+msgstr ""
+
+msgid "This issue cannot be made public because it belongs to a confidential epic."
+msgstr ""
+
msgid "This issue is confidential and should only be visible to team members with at least Reporter access."
msgstr ""
@@ -36874,6 +37626,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 branch is protected from force push."
+msgstr ""
+
msgid "This merge request cannot be rebased while there are conflicts."
msgstr ""
@@ -36925,9 +37680,15 @@ msgstr ""
msgid "This pipeline was triggered by a schedule."
msgstr ""
+msgid "This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project"
msgstr ""
+msgid "This project can be restored until %{date}."
+msgstr ""
+
msgid "This project cannot be %{visibilityLevel} because the visibility of %{openShowLink}%{name}%{closeShowLink} is %{visibility}. To make this project %{visibilityLevel}, you must first %{openEditLink}change the visibility%{closeEditLink} of the parent group."
msgstr ""
@@ -36946,6 +37707,9 @@ msgstr ""
msgid "This project is %{strongStart}NOT%{strongEnd} a fork, and has the following:"
msgstr ""
+msgid "This project is %{strongStart}NOT%{strongEnd} a fork. This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -37637,6 +38401,9 @@ msgstr ""
msgid "Today"
msgstr ""
+msgid "Todos count"
+msgstr ""
+
msgid "Todos|Are you looking for things to do? Take a look at %{strongStart}%{openIssuesLinkStart}open issues%{openIssuesLinkEnd}%{strongEnd}, contribute to %{strongStart}%{mergeRequestLinkStart}a merge request%{mergeRequestLinkEnd}%{mergeRequestLinkEnd}%{strongEnd}, or mention someone in a comment to automatically assign them a new to-do item."
msgstr ""
@@ -37910,10 +38677,8 @@ msgstr ""
msgid "Trending"
msgstr ""
-msgid "Trials|%{planName} Trial %{enDash} %{num} day left"
-msgid_plural "Trials|%{planName} Trial %{enDash} %{num} days left"
-msgstr[0] ""
-msgstr[1] ""
+msgid "Trials|%{planName} Trial"
+msgstr ""
msgid "Trials|Compare all plans"
msgstr ""
@@ -37921,6 +38686,9 @@ msgstr ""
msgid "Trials|Create a new group to start your GitLab Ultimate trial."
msgstr ""
+msgid "Trials|Day %{daysUsed}/%{duration}"
+msgstr ""
+
msgid "Trials|Go back to GitLab"
msgstr ""
@@ -38170,7 +38938,7 @@ msgstr ""
msgid "URL is triggered when repository is updated"
msgstr ""
-msgid "URL must be percent-encoded if neccessary."
+msgid "URL must be percent-encoded if necessary."
msgstr ""
msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
@@ -38389,6 +39157,9 @@ msgstr ""
msgid "Unlock account"
msgstr ""
+msgid "Unlock more features with GitLab Ultimate"
+msgstr ""
+
msgid "Unlock the discussion"
msgstr ""
@@ -38452,6 +39223,9 @@ msgstr ""
msgid "Unsubscribes from this %{quick_action_target}."
msgstr ""
+msgid "Unsupported sort value."
+msgstr ""
+
msgid "Unsupported todo type passed. Supported todo types are: %{todo_types}"
msgstr ""
@@ -38680,6 +39454,9 @@ msgstr ""
msgid "UsageQuota|File attachments and smaller design graphics."
msgstr ""
+msgid "UsageQuota|From %{storage_enforcement_date} storage limits will apply to this namespace. View and manage your usage in %{strong_start}Group Settings &gt; Usage quotas%{strong_end}."
+msgstr ""
+
msgid "UsageQuota|Git repository."
msgstr ""
@@ -38740,6 +39517,9 @@ msgstr ""
msgid "UsageQuota|Storage type"
msgstr ""
+msgid "UsageQuota|Storage used"
+msgstr ""
+
msgid "UsageQuota|This is the total amount of storage used across your projects within this namespace."
msgstr ""
@@ -38935,6 +39715,12 @@ msgstr ""
msgid "Use hashed storage paths for newly created and renamed repositories. Always enabled since 13.0."
msgstr ""
+msgid "Use issue count"
+msgstr ""
+
+msgid "Use issue weight"
+msgstr ""
+
msgid "Use one line per URI"
msgstr ""
@@ -39316,6 +40102,9 @@ msgstr ""
msgid "Users"
msgstr ""
+msgid "Users API rate limit"
+msgstr ""
+
msgid "Users can launch a development environment from a GitLab browser tab when the %{linkStart}Gitpod%{linkEnd} integration is enabled."
msgstr ""
@@ -39641,6 +40430,9 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View group pipeline usage quota"
+msgstr ""
+
msgid "View incident details at"
msgstr ""
@@ -39793,6 +40585,9 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
+msgid "Vulnerability"
+msgstr ""
+
msgid "Vulnerability Report"
msgstr ""
@@ -39844,6 +40639,9 @@ msgstr ""
msgid "VulnerabilityManagement|An unverified non-confirmed finding"
msgstr ""
+msgid "VulnerabilityManagement|At least one identifier is required"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -39853,12 +40651,24 @@ msgstr ""
msgid "VulnerabilityManagement|Create Jira issue"
msgstr ""
+msgid "VulnerabilityManagement|Enter a name"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE code"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE identifier URL"
+msgstr ""
+
msgid "VulnerabilityManagement|Fetching linked Jira issues"
msgstr ""
msgid "VulnerabilityManagement|Manually add a vulnerability entry into the vulnerability report."
msgstr ""
+msgid "VulnerabilityManagement|Name is a required field"
+msgstr ""
+
msgid "VulnerabilityManagement|Needs triage"
msgstr ""
@@ -39874,6 +40684,18 @@ msgstr ""
msgid "VulnerabilityManagement|Select a method"
msgstr ""
+msgid "VulnerabilityManagement|Select a severity level"
+msgstr ""
+
+msgid "VulnerabilityManagement|Select a status"
+msgstr ""
+
+msgid "VulnerabilityManagement|Severity is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Something went wrong while creating vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -39898,6 +40720,12 @@ msgstr ""
msgid "VulnerabilityManagement|Something went wrong, could not update vulnerability state."
msgstr ""
+msgid "VulnerabilityManagement|Status is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Submit vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Summary, detailed description, steps to reproduce, etc."
msgstr ""
@@ -40093,6 +40921,9 @@ msgstr ""
msgid "WARNING:"
msgstr ""
+msgid "WARNING: This snippet contains hidden files which might be used to mask malicious behavior. Exercise caution if cloning and executing code from this snippet."
+msgstr ""
+
msgid "Wait for the file to load to copy its contents"
msgstr ""
@@ -40312,6 +41143,15 @@ msgstr ""
msgid "Webhooks|An issue is created, updated, closed, or reopened."
msgstr ""
+msgid "Webhooks|Are you sure you want to delete this group hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this project hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this webhook?"
+msgstr ""
+
msgid "Webhooks|Comments"
msgstr ""
@@ -40321,6 +41161,9 @@ msgstr ""
msgid "Webhooks|Confidential issues events"
msgstr ""
+msgid "Webhooks|Delete webhook"
+msgstr ""
+
msgid "Webhooks|Deployment events"
msgstr ""
@@ -40554,6 +41397,9 @@ msgstr ""
msgid "Wiki"
msgstr ""
+msgid "Wiki page"
+msgstr ""
+
msgid "Wiki page was successfully created."
msgstr ""
@@ -40659,7 +41505,7 @@ msgstr ""
msgid "WikiPageConflictMessage|Someone edited the page the same time you did. Please check out %{wikiLinkStart}the page%{wikiLinkEnd} and make sure your changes will not unintentionally remove theirs."
msgstr ""
-msgid "WikiPage|An error occured while trying to render the content editor. Please try again later."
+msgid "WikiPage|An error occurred while trying to render the content editor. Please try again later."
msgstr ""
msgid "WikiPage|Are you sure you want to switch back to the classic editor?"
@@ -40818,6 +41664,18 @@ msgstr ""
msgid "WorkItem|New Task"
msgstr ""
+msgid "WorkItem|Something went wrong when creating a work item. Please try again"
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching the work item. Please try again."
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching work item types. Please try again"
+msgstr ""
+
+msgid "WorkItem|Type"
+msgstr ""
+
msgid "WorkItem|Work Items"
msgstr ""
@@ -40884,7 +41742,10 @@ msgstr ""
msgid "You are about to add %{usersTag} people to the discussion. They will all receive a notification."
msgstr ""
-msgid "You are about to permanently delete this project"
+msgid "You are about to delete this forked project containing:"
+msgstr ""
+
+msgid "You are about to delete this project containing:"
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."
@@ -40905,6 +41766,9 @@ msgstr ""
msgid "You are attempting to update a file that has changed since you started editing it."
msgstr ""
+msgid "You are billed if you exceed this number. %{qsrOverageLinkStart}How does billing work?%{qsrOverageLinkEnd}"
+msgstr ""
+
msgid "You are connected to the Prometheus server, but there is currently no data to display."
msgstr ""
@@ -40962,6 +41826,9 @@ msgstr ""
msgid "You are not authorized to update this scanner profile"
msgstr ""
+msgid "You are not authorized to upload metric images"
+msgstr ""
+
msgid "You are now impersonating %{username}"
msgstr ""
@@ -41115,9 +41982,6 @@ msgstr ""
msgid "You can only upload one design when dropping onto an existing design."
msgstr ""
-msgid "You can recover this project until %{date}"
-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 ""
@@ -41166,9 +42030,6 @@ msgstr ""
msgid "You cannot write to this read-only GitLab instance."
msgstr ""
-msgid "You can’t %{tag_start}edit%{tag_end} files directly in this project. Fork this project and submit a merge request with your changes."
-msgstr ""
-
msgid "You can’t edit files directly in this project. Fork this project and submit a merge request with your changes."
msgstr ""
@@ -41321,9 +42182,6 @@ 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 set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
@@ -41354,12 +42212,6 @@ msgstr ""
msgid "You must have maintainer access to force delete a lock"
msgstr ""
-msgid "You must have permission to create a project in a group before forking."
-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 ""
@@ -41765,7 +42617,7 @@ msgstr ""
msgid "Your public email will be displayed on your public profile."
msgstr ""
-msgid "Your request for access could not be processed: %{error_meesage}"
+msgid "Your request for access could not be processed: %{error_message}"
msgstr ""
msgid "Your request for access has been queued for review."
@@ -41948,6 +42800,9 @@ msgstr ""
msgid "archived:"
msgstr ""
+msgid "artifacts"
+msgstr ""
+
msgid "assign yourself"
msgstr ""
@@ -41977,6 +42832,9 @@ msgstr[1] ""
msgid "branch name"
msgstr ""
+msgid "builds"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -42400,6 +43258,9 @@ msgstr ""
msgid "contact with same email already exists in group hierarchy"
msgstr ""
+msgid "container registry images"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -42439,6 +43300,9 @@ msgstr ""
msgid "data"
msgstr ""
+msgid "database"
+msgstr ""
+
msgid "date must not be after 9999-12-31"
msgstr ""
@@ -42462,9 +43326,6 @@ msgstr ""
msgid "design"
msgstr ""
-msgid "detached"
-msgstr ""
-
msgid "disabled"
msgstr ""
@@ -42713,7 +43574,7 @@ msgstr ""
msgid "is not a valid X509 certificate."
msgstr ""
-msgid "is not allowed for sign-up."
+msgid "is not allowed for sign-up. Please use your regular email address."
msgstr ""
msgid "is not allowed for this group."
@@ -42725,7 +43586,7 @@ msgstr ""
msgid "is not allowed since the group is not top-level group."
msgstr ""
-msgid "is not allowed."
+msgid "is not allowed. Please use your regular email address."
msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
@@ -42812,6 +43673,9 @@ msgstr ""
msgid "level: %{level}"
msgstr ""
+msgid "lfs objects"
+msgstr ""
+
msgid "limit of %{project_limit} reached"
msgstr ""
@@ -43031,6 +43895,9 @@ msgstr ""
msgid "mrWidget|Merge blocked: pipeline must succeed. It's waiting for a manual action to continue."
msgstr ""
+msgid "mrWidget|Merge blocked: pipeline must succeed. Push a commit that fixes the failure, or %{linkStart}learn about other solutions.%{linkEnd}"
+msgstr ""
+
msgid "mrWidget|Merge blocked: this merge request must be approved."
msgstr ""
@@ -43148,9 +44015,6 @@ msgstr ""
msgid "mrWidget|The changes were not merged into"
msgstr ""
-msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -43298,9 +44162,6 @@ msgstr ""
msgid "open issue"
msgstr ""
-msgid "opened %{timeAgo}"
-msgstr ""
-
msgid "or"
msgstr ""
@@ -43312,6 +44173,12 @@ msgid_plural "out of %d total tests"
msgstr[0] ""
msgstr[1] ""
+msgid "packages"
+msgstr ""
+
+msgid "pages"
+msgstr ""
+
msgid "parent"
msgid_plural "parents"
msgstr[0] ""
@@ -43461,6 +44328,9 @@ msgid_plural "replies"
msgstr[0] ""
msgstr[1] ""
+msgid "repositories"
+msgstr ""
+
msgid "repository:"
msgstr ""
@@ -43581,12 +44451,18 @@ msgstr ""
msgid "tag name"
msgstr ""
+msgid "terraform states"
+msgstr ""
+
msgid "the correct format."
msgstr ""
msgid "the file"
msgstr ""
+msgid "the following epic(s)"
+msgstr ""
+
msgid "the following issue(s)"
msgstr ""
@@ -43599,21 +44475,12 @@ msgstr ""
msgid "this document"
msgstr ""
-msgid "this issue cannot be assigned to a confidential epic since it is public"
-msgstr ""
-
-msgid "this issue cannot be made public since it belongs to a confidential epic"
-msgstr ""
-
msgid "time summary"
msgstr ""
msgid "toggle collapse"
msgstr ""
-msgid "train"
-msgstr ""
-
msgid "triggered"
msgstr ""
@@ -43742,3 +44609,6 @@ msgstr ""
msgid "{project}"
msgstr ""
+msgid "✔"
+msgstr ""
+
diff --git a/locale/tr_TR/gitlab.po b/locale/tr_TR/gitlab.po
index d4ee8db70c2..4713d33cf40 100644
--- a/locale/tr_TR/gitlab.po
+++ b/locale/tr_TR/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: tr\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2022-02-02 15:42\n"
+"PO-Revision-Date: 2022-03-01 20:36\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -146,6 +146,11 @@ msgid_plural "%d approvers (you've approved)"
msgstr[0] "%d onaylayan (onayladınız)"
msgstr[1] "%d onaylayan (onayladınız)"
+msgid "%d assigned issue"
+msgid_plural "%d assigned issues"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] "%d dosya deÄŸiÅŸtirildi"
@@ -421,8 +426,23 @@ msgid_plural "%d vulnerabilities dismissed"
msgstr[0] "%d güvenlik açığı kapatıldı"
msgstr[1] "%d güvenlik açığı kapatıldı"
-msgid "%d vulnerability updated"
-msgid_plural "%d vulnerabilities updated"
+msgid "%d vulnerability set to confirmed"
+msgid_plural "%d vulnerabilities set to confirmed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to dismissed"
+msgid_plural "%d vulnerabilities set to dismissed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to needs triage"
+msgid_plural "%d vulnerabilities set to needs triage"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to resolved"
+msgid_plural "%d vulnerabilities set to resolved"
msgstr[0] ""
msgstr[1] ""
@@ -510,6 +530,12 @@ msgstr[1] ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{completed} of %{total} issues closed"
+msgstr ""
+
+msgid "%{completed} of %{total} weight completed"
+msgstr ""
+
msgid "%{cores} cores"
msgstr "%{cores} çekirdek"
@@ -858,6 +884,9 @@ msgstr "%{openedEpics} açık, %{closedEpics} kapalı"
msgid "%{openedIssues} open, %{closedIssues} closed"
msgstr "%{openedIssues} açık, %{closedIssues} kapalı"
+msgid "%{percentage}%% issues closed"
+msgstr ""
+
msgid "%{percentage}%% weight completed"
msgstr "%%%{percentage} ağırlık tamamlandı"
@@ -1287,6 +1316,9 @@ msgid_plural "- Users"
msgstr[0] "- Kullanıcı"
msgstr[1] "- Kullanıcılar"
+msgid "- of - issues closed"
+msgstr ""
+
msgid "- of - weight completed"
msgstr ""
@@ -1429,7 +1461,7 @@ msgstr "10-19 katkı"
msgid "1000+"
msgstr "1000+"
-msgid "192.168.0.0/24"
+msgid "192.168.0.0/24 or 2001:0DB8:1234::/48"
msgstr ""
msgid "1st contribution!"
@@ -1741,13 +1773,13 @@ msgstr ""
msgid "AWS Access Key"
msgstr "AWS Erişim Anahtarı"
-msgid "AWS Access Key. Only required if not using role instance credentials"
-msgstr ""
-
msgid "AWS Secret Access Key"
msgstr "AWS Gizli Erişim Anahtarı"
-msgid "AWS Secret Access Key. Only required if not using role instance credentials"
+msgid "AWS access key ID (Optional)"
+msgstr ""
+
+msgid "AWS secret access key (Optional)"
msgstr ""
msgid "AWS service error: %{error}"
@@ -1807,9 +1839,6 @@ msgstr "Erişim yasaklandı. Erişim seviyenizi kontrol edin."
msgid "Access granted"
msgstr "Erişim onaylandı"
-msgid "Access key ID"
-msgstr ""
-
msgid "Access requests"
msgstr "EriÅŸim istekleri"
@@ -1984,7 +2013,7 @@ msgstr ""
msgid "Activity"
msgstr ""
-msgid "Activity|An error occured while retrieving activity. Reload the page to try again."
+msgid "Activity|An error occurred while retrieving activity. Reload the page to try again."
msgstr ""
msgid "Add"
@@ -2023,6 +2052,9 @@ msgstr "Zoom toplantısı ekle"
msgid "Add a %{type}"
msgstr "Bir %{type} ekle"
+msgid "Add a GCP region"
+msgstr ""
+
msgid "Add a GPG key"
msgstr "Bir GPG anahtarı ekle"
@@ -2074,6 +2106,9 @@ msgstr "Yeni sorun ekle"
msgid "Add a numbered list"
msgstr "Numaralı liste ekle"
+msgid "Add a related epic"
+msgstr ""
+
msgid "Add a related issue"
msgstr "Ä°lgili sorun ekle"
@@ -2188,6 +2223,9 @@ msgstr ""
msgid "Add or subtract spent time"
msgstr "Harcanan zamanı ekleyin veya çıkarın"
+msgid "Add people"
+msgstr ""
+
msgid "Add previously merged commits"
msgstr ""
@@ -2254,6 +2292,9 @@ msgstr ""
msgid "Add webhook"
msgstr "Web kancası ekle"
+msgid "Add your team members and others to GitLab."
+msgstr ""
+
msgid "Add/remove"
msgstr "Ekle/kaldır"
@@ -3076,12 +3117,6 @@ msgstr ""
msgid "AdvancedSearch|Reindex required"
msgstr ""
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. Permanently deleting this project will %{strongStart}immediately delete%{strongEnd} its repositories and %{strongStart}all related resources%{strongEnd}, including issues, merge requests etc."
-msgstr ""
-
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. You will lose this project's repository and %{strongStart}all related resources%{strongEnd}, including issues and merge requests."
-msgstr ""
-
msgid "After a successful password update you will be redirected to login screen."
msgstr "Başarılı bir şifre güncellemesinden sonra giriş ekranına yönlendirileceksiniz."
@@ -3112,6 +3147,9 @@ msgstr ""
msgid "Akismet helps prevent the creation of spam issues in public projects."
msgstr ""
+msgid "Alert"
+msgstr ""
+
msgid "AlertManagement|Acknowledged"
msgstr ""
@@ -3484,9 +3522,6 @@ msgstr "Tüm e-posta adresleri işlemlerinizi tanımlamak için kullanılacaktı
msgid "All environments"
msgstr "Tüm ortamlar"
-msgid "All epics"
-msgstr "Tüm epikler"
-
msgid "All groups and projects"
msgstr "Tüm gruplar ve projeler"
@@ -4223,12 +4258,15 @@ msgstr ""
msgid "ApplicationSettings|Approve users in the pending approval status?"
msgstr ""
-msgid "ApplicationSettings|By making this change, you will automatically approve %d user with the pending approval status."
-msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users with the pending approval status."
+msgid "ApplicationSettings|Approve users who are pending approval?"
+msgstr ""
+
+msgid "ApplicationSettings|By making this change, you will automatically approve %d user who is pending approval."
+msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users who are pending approval."
msgstr[0] ""
msgstr[1] ""
-msgid "ApplicationSettings|By making this change, you will automatically approve all users in pending approval status."
+msgid "ApplicationSettings|By making this change, you will automatically approve all users who are pending approval."
msgstr ""
msgid "ApplicationSettings|Denied domains for sign-ups"
@@ -4634,10 +4672,10 @@ msgstr "ArÅŸivlenmiÅŸ projeler"
msgid "Archiving the project will make it entirely read-only. It is hidden from the dashboard and doesn't show up in searches. %{strong_start}The repository cannot be committed to, and no issues, comments, or other entities can be created.%{strong_end} %{link_start}Learn more.%{link_end}"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to delete this project?"
+msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
+msgid "Are you absolutely sure?"
msgstr ""
msgid "Are you sure that you want to archive this project?"
@@ -4673,12 +4711,18 @@ msgstr "Bu %{typeOfComment} silmek istediÄŸinizden emin misiniz?"
msgid "Are you sure you want to delete this SSH key?"
msgstr ""
+msgid "Are you sure you want to delete this comment?"
+msgstr ""
+
msgid "Are you sure you want to delete this deploy key?"
msgstr ""
msgid "Are you sure you want to delete this device? This action cannot be undone."
msgstr "Bu cihazı silmek istediğinizden emin misiniz? Bu işlem geri alınamaz."
+msgid "Are you sure you want to delete this label?"
+msgstr ""
+
msgid "Are you sure you want to delete this pipeline schedule?"
msgstr "Bu iş hattı planını silmek istediğinizden emin misiniz?"
@@ -4694,9 +4738,6 @@ msgstr "Bu yorumu silmek istediÄŸinizden emin misiniz?"
msgid "Are you sure you want to discard your changes?"
msgstr ""
-msgid "Are you sure you want to erase this build?"
-msgstr "Bu yapıyı silmek istediğinizden emin misiniz?"
-
msgid "Are you sure you want to import %d repository?"
msgid_plural "Are you sure you want to import %d repositories?"
msgstr[0] ""
@@ -4744,6 +4785,9 @@ msgstr "Bu kimliği kaldırmak istediğinizden emin misiniz?"
msgid "Are you sure you want to remove this list?"
msgstr ""
+msgid "Are you sure you want to remove this nickname?"
+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?"
@@ -4756,10 +4800,10 @@ 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?"
+msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
msgstr ""
-msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
+msgid "Are you sure you want to revoke this project access token? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to stop this environment?"
@@ -4906,9 +4950,6 @@ msgstr ""
msgid "Assigned to %{assignee_name}"
msgstr "%{assignee_name} kişisine atandı."
-msgid "Assigned to %{name}"
-msgstr ""
-
msgid "Assigned to me"
msgstr "Bana atanan"
@@ -4973,6 +5014,9 @@ msgstr[1] "%d dosya ekleniyor"
msgid "Attaching the file failed."
msgstr "Dosya ekleme başarısız oldu."
+msgid "Attention"
+msgstr ""
+
msgid "Audit Events"
msgstr "Denetim Etkinlikleri"
@@ -5135,6 +5179,12 @@ msgstr "Yetkili"
msgid "Authorized applications (%{size})"
msgstr "Yetkili uygulamalar (%{size})"
+msgid "AuthorizedApplication|Are you sure you want to revoke this application?"
+msgstr ""
+
+msgid "AuthorizedApplication|Revoke application"
+msgstr ""
+
msgid "Authors: %{authors}"
msgstr "Yazarlar: %{authors}"
@@ -6328,6 +6378,9 @@ msgstr ""
msgid "CICDAnalytics|Shared Runners Usage"
msgstr ""
+msgid "CICDAnalytics|Shared runner pipeline minute duration by month"
+msgstr ""
+
msgid "CICDAnalytics|Shared runner usage"
msgstr ""
@@ -6469,6 +6522,9 @@ msgstr ""
msgid "Can create groups:"
msgstr ""
+msgid "Can not delete primary training"
+msgstr ""
+
msgid "Can't apply as the source branch was deleted."
msgstr ""
@@ -6802,9 +6858,6 @@ msgstr ""
msgid "Changing any setting here requires an application restart"
msgstr ""
-msgid "Changing group URL can have unintended side effects."
-msgstr ""
-
msgid "Charts can't be displayed as the request for data has timed out. %{documentationLink}"
msgstr ""
@@ -6892,9 +6945,6 @@ msgstr "Onay durumunu kontrol et"
msgid "Checking branch availability..."
msgstr "Dal uygunluÄŸu kontrol ediliyor..."
-msgid "Checking group URL availability..."
-msgstr ""
-
msgid "Checking group path availability..."
msgstr "Grup yolu uygunluÄŸu kontrol ediliyor..."
@@ -7388,6 +7438,9 @@ msgstr ""
msgid "Clear recent searches"
msgstr "Son aramaları temizle"
+msgid "Clear repository checks"
+msgstr ""
+
msgid "Clear search"
msgstr "Aramayı temizle"
@@ -7520,9 +7573,6 @@ msgstr "%{epicTimeagoDate} kapatıldı"
msgid "Closed MRs"
msgstr ""
-msgid "Closed epics"
-msgstr "Epikler kapatıldı"
-
msgid "Closed issues"
msgstr "Kapalı sorunlar"
@@ -7559,13 +7609,13 @@ msgstr ""
msgid "Cluster level"
msgstr ""
-msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
+msgid "Cluster type must be specified for Stages::ClusterEndpointInserter"
msgstr ""
msgid "ClusterAgents|%{name} successfully deleted"
msgstr ""
-msgid "ClusterAgents|%{number} of %{total} Agents"
+msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
@@ -7607,6 +7657,15 @@ msgstr ""
msgid "ClusterAgents|Agent never connected to GitLab"
msgstr ""
+msgid "ClusterAgents|Agent version mismatch"
+msgstr ""
+
+msgid "ClusterAgents|Agent version mismatch and update"
+msgstr ""
+
+msgid "ClusterAgents|Agent version update required"
+msgstr ""
+
msgid "ClusterAgents|All"
msgstr ""
@@ -7631,7 +7690,7 @@ msgstr ""
msgid "ClusterAgents|Configuration"
msgstr ""
-msgid "ClusterAgents|Connect a cluster through the Agent"
+msgid "ClusterAgents|Connect a cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connect existing cluster"
@@ -7640,13 +7699,13 @@ msgstr ""
msgid "ClusterAgents|Connect with a certificate"
msgstr ""
-msgid "ClusterAgents|Connect with agent"
+msgid "ClusterAgents|Connect with an agent"
msgstr ""
msgid "ClusterAgents|Connect with the GitLab Agent"
msgstr ""
-msgid "ClusterAgents|Connect your cluster through the Agent"
+msgid "ClusterAgents|Connect your cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connected"
@@ -7706,7 +7765,10 @@ msgstr ""
msgid "ClusterAgents|How to register an agent?"
msgstr ""
-msgid "ClusterAgents|Install new Agent"
+msgid "ClusterAgents|How to update an agent?"
+msgstr ""
+
+msgid "ClusterAgents|Install a new agent"
msgstr ""
msgid "ClusterAgents|Last connected %{timeAgo}."
@@ -7733,7 +7795,7 @@ msgstr ""
msgid "ClusterAgents|Never connected"
msgstr ""
-msgid "ClusterAgents|No Agents"
+msgid "ClusterAgents|No agents"
msgstr ""
msgid "ClusterAgents|No clusters connected through cluster certificates"
@@ -7793,6 +7855,9 @@ msgstr ""
msgid "ClusterAgents|The agent has not been connected in a long time. There might be a connectivity issue. Last contact was %{timeAgo}."
msgstr ""
+msgid "ClusterAgents|The agent version do not match each other across your cluster's pods. This can happen when a new agent version was just deployed and Kubernetes is shutting down the old pods."
+msgstr ""
+
msgid "ClusterAgents|The recommended installation method includes the token. If you want to follow the advanced installation method provided in the docs, make sure you save the token value before you close this window."
msgstr ""
@@ -7840,6 +7905,9 @@ msgstr ""
msgid "ClusterAgents|You will need to create a token to connect to your agent"
msgstr ""
+msgid "ClusterAgents|Your agent version is out of sync with your GitLab version (v%{version}), which might cause compatibility problems. Update the agent installed on your cluster to the most recent version."
+msgstr ""
+
msgid "ClusterAgents|Your instance doesn't have the %{linkStart}GitLab Agent Server (KAS)%{linkEnd} set up. Ask a GitLab Administrator to install it."
msgstr ""
@@ -8716,9 +8784,6 @@ msgstr ""
msgid "Comma-separated list of email addresses."
msgstr ""
-msgid "Comma-separated list of users allowed to exceed the rate limit."
-msgstr ""
-
msgid "Comma-separated, e.g. '1.1.1.1, 2.2.2.0/24'"
msgstr "Virgülle ayrılmış, örneğin '1.1.1.1, 2.2.2.0/24'"
@@ -9045,6 +9110,12 @@ msgstr ""
msgid "Confidential"
msgstr ""
+msgid "Confidential issue"
+msgstr ""
+
+msgid "Confidential note"
+msgstr ""
+
msgid "Confidentiality"
msgstr "Gizlilik"
@@ -9078,6 +9149,9 @@ msgstr ""
msgid "Configure Dependency Scanning in `.gitlab-ci.yml`, creating this file if it does not already exist"
msgstr ""
+msgid "Configure GitLab"
+msgstr ""
+
msgid "Configure GitLab runners to start using the Web Terminal. %{helpStart}Learn more.%{helpEnd}"
msgstr ""
@@ -9126,6 +9200,15 @@ msgstr ""
msgid "Configure pipelines to deploy web apps, backend services, APIs and static resources to Google Cloud"
msgstr ""
+msgid "Configure region"
+msgstr ""
+
+msgid "Configure region for environment"
+msgstr ""
+
+msgid "Configure regions"
+msgstr ""
+
msgid "Configure repository mirroring."
msgstr ""
@@ -9159,6 +9242,9 @@ msgstr ""
msgid "Configure which lists are shown for anyone who visits this board"
msgstr ""
+msgid "Configure your environments to be deployed to specific geographical regions"
+msgstr ""
+
msgid "Confirm"
msgstr "Onayla"
@@ -9861,10 +9947,10 @@ msgstr ""
msgid "CorpusManagement|Actions"
msgstr ""
-msgid "CorpusManagement|Corpus are used in fuzz testing as mutation source to Improve future testing."
+msgid "CorpusManagement|Corpus file"
msgstr ""
-msgid "CorpusManagement|Corpus file"
+msgid "CorpusManagement|Corpus files are used in coverage-guided fuzz testing as seed inputs to improve testing."
msgstr ""
msgid "CorpusManagement|Corpus files must be in *.zip format. Maximum 5 GB"
@@ -9918,6 +10004,9 @@ msgstr ""
msgid "Could not apply %{name} command."
msgstr ""
+msgid "Could not apply %{name} command. %{message}."
+msgstr ""
+
msgid "Could not authorize chat nickname. Try again!"
msgstr "Bu sohbet takma adı yetkilendirilemedi. Tekrar deneyin!"
@@ -10068,6 +10157,9 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
+msgid "Create a group"
+msgstr ""
+
msgid "Create a merge request"
msgstr "BirleÅŸtirme isteÄŸi oluÅŸtur"
@@ -10092,6 +10184,9 @@ msgstr "Yeni bir depo oluÅŸtur"
msgid "Create a personal access token on your account to pull or push via %{protocol}."
msgstr ""
+msgid "Create a project"
+msgstr ""
+
msgid "Create an account using:"
msgstr ""
@@ -10455,6 +10550,9 @@ msgstr ""
msgid "Creation date"
msgstr ""
+msgid "Creator"
+msgstr ""
+
msgid "Credentials"
msgstr "Kimlik Bilgileri"
@@ -10467,9 +10565,15 @@ msgstr ""
msgid "CredentialsInventory|Personal Access Tokens"
msgstr ""
+msgid "CredentialsInventory|Project Access Tokens"
+msgstr ""
+
msgid "CredentialsInventory|SSH Keys"
msgstr ""
+msgid "Credit card required to be on file in order to create a pipeline"
+msgstr ""
+
msgid "Credit card:"
msgstr ""
@@ -10653,9 +10757,6 @@ msgstr ""
msgid "Customer relations"
msgstr ""
-msgid "Customizable by an administrator."
-msgstr ""
-
msgid "Customizable by owners."
msgstr ""
@@ -10785,30 +10886,18 @@ msgstr ""
msgid "CycleAnalytics|%{selectedLabelsCount} selected (%{maxLabels} max)"
msgstr ""
-msgid "CycleAnalytics|%{stageCount} stages selected"
-msgstr ""
-
-msgid "CycleAnalytics|All stages"
-msgstr ""
-
-msgid "CycleAnalytics|Average days to completion"
+msgid "CycleAnalytics|Average time to completion"
msgstr ""
msgid "CycleAnalytics|Date"
msgstr ""
-msgid "CycleAnalytics|Days to completion"
-msgstr ""
-
msgid "CycleAnalytics|Display chart filters"
msgstr ""
msgid "CycleAnalytics|Lead Time for Changes"
msgstr ""
-msgid "CycleAnalytics|No stages selected"
-msgstr ""
-
msgid "CycleAnalytics|Number of tasks"
msgstr ""
@@ -10837,18 +10926,30 @@ msgstr ""
msgid "CycleAnalytics|Showing data for group '%{groupName}' from %{createdAfter} to %{createdBefore}"
msgstr ""
-msgid "CycleAnalytics|Stages"
+msgid "CycleAnalytics|Stage time: %{title}"
msgstr ""
msgid "CycleAnalytics|Tasks by type"
msgstr ""
-msgid "CycleAnalytics|The average time spent in the selected stage for the items that were completed on each date. Data limited to the last 500 items."
+msgid "CycleAnalytics|The average time items spent in this stage. Data limited to items completed within this date range."
msgstr ""
msgid "CycleAnalytics|The given date range is larger than 180 days"
msgstr ""
+msgid "CycleAnalytics|The total time items spent across each value stream stage. Data limited to items completed within this date range."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Stage time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Total time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|Total time"
+msgstr ""
+
msgid "CycleAnalytics|Type of work"
msgstr ""
@@ -10861,9 +10962,6 @@ msgstr ""
msgid "CycleAnalytics|project dropdown filter"
msgstr ""
-msgid "CycleAnalytics|stage dropdown"
-msgstr ""
-
msgid "DAG visualization requires at least 3 dependent jobs."
msgstr ""
@@ -10963,10 +11061,16 @@ msgstr ""
msgid "DastProfiles|AJAX spider"
msgstr ""
+msgid "DastProfiles|API"
+msgstr ""
+
+msgid "DastProfiles|API endpoint URL"
+msgstr ""
+
msgid "DastProfiles|Active"
msgstr ""
-msgid "DastProfiles|Additional request headers (Optional)"
+msgid "DastProfiles|Additional request headers (optional)"
msgstr ""
msgid "DastProfiles|Are you sure you want to delete this profile?"
@@ -10981,6 +11085,9 @@ msgstr ""
msgid "DastProfiles|Branch missing"
msgstr ""
+msgid "DastProfiles|Choose a scan method"
+msgstr ""
+
msgid "DastProfiles|Could not create the scanner profile. Please try again."
msgstr ""
@@ -11050,7 +11157,13 @@ msgstr ""
msgid "DastProfiles|Excluded URLs"
msgstr ""
-msgid "DastProfiles|Excluded URLs (Optional)"
+msgid "DastProfiles|Excluded URLs (optional)"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths (optional)"
msgstr ""
msgid "DastProfiles|Hide debug messages"
@@ -11107,9 +11220,6 @@ msgstr ""
msgid "DastProfiles|Request headers"
msgstr ""
-msgid "DastProfiles|Rest API"
-msgstr ""
-
msgid "DastProfiles|Run the AJAX spider, in addition to the traditional spider, to crawl the target site."
msgstr ""
@@ -11119,6 +11229,9 @@ msgstr ""
msgid "DastProfiles|Save profile"
msgstr ""
+msgid "DastProfiles|Scan method"
+msgstr ""
+
msgid "DastProfiles|Scan mode"
msgstr ""
@@ -11197,12 +11310,24 @@ msgstr ""
msgid "DastProfiles|Website"
msgstr ""
+msgid "DastProfiles|What does each method do?"
+msgstr ""
+
msgid "DastProfiles|You can either choose a passive scan or validate the target site from the site profile management page. %{docsLinkStart}Learn more about site validation.%{docsLinkEnd}"
msgstr ""
msgid "DastProfiles|You cannot run an active scan against an unvalidated site."
msgstr ""
+msgid "DastProfiles|folder/dast_example.har or https://example.com/dast_example.har"
+msgstr ""
+
+msgid "DastProfiles|folder/example.postman_collection.json or https://example.com/"
+msgstr ""
+
+msgid "DastProfiles|folder/openapi.json or https://example.com/openapi.json"
+msgstr ""
+
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
@@ -11310,6 +11435,9 @@ msgstr ""
msgid "DatadogIntegration|API URL"
msgstr ""
+msgid "DatadogIntegration|Custom tags in Datadog. Enter one tag per line in the %{codeOpen}key:value%{codeClose} format. %{linkOpen}How do I use tags?%{linkClose}"
+msgstr ""
+
msgid "DatadogIntegration|Environment"
msgstr ""
@@ -11328,12 +11456,18 @@ msgstr ""
msgid "DatadogIntegration|Tag all data from this GitLab instance in Datadog. Useful when managing several self-managed deployments."
msgstr ""
+msgid "DatadogIntegration|Tags"
+msgstr ""
+
msgid "DatadogIntegration|The Datadog site to send data to. To send data to the EU site, use %{codeOpen}datadoghq.eu%{codeClose}."
msgstr ""
msgid "DatadogIntegration|Trace your GitLab pipelines with Datadog."
msgstr ""
+msgid "DatadogIntegration|have an invalid format"
+msgstr ""
+
msgid "Datasource name not found"
msgstr "Veri kaynağı adı bulunamadı"
@@ -11343,9 +11477,6 @@ msgstr ""
msgid "Date merged"
msgstr ""
-msgid "Date picker"
-msgstr "Tarih seçici"
-
msgid "Date range"
msgstr ""
@@ -11499,9 +11630,6 @@ msgstr ""
msgid "Definition"
msgstr ""
-msgid "Delayed Project Deletion (%{adjourned_deletion})"
-msgstr ""
-
msgid "DelayedJobs|Are you sure you want to run %{jobName} immediately? Otherwise this job will run automatically after its timer finishes."
msgstr ""
@@ -11580,10 +11708,10 @@ msgstr ""
msgid "Delete pipeline"
msgstr ""
-msgid "Delete project"
+msgid "Delete pipeline schedule"
msgstr ""
-msgid "Delete project. Are you ABSOLUTELY SURE?"
+msgid "Delete project"
msgstr ""
msgid "Delete row"
@@ -11613,6 +11741,9 @@ msgstr "Bu eki sil"
msgid "Delete this epic and all descendants?"
msgstr ""
+msgid "Delete this project"
+msgstr ""
+
msgid "Delete user list"
msgstr "Kullanıcı listesini sil"
@@ -11871,6 +12002,12 @@ msgstr ""
msgid "Deploy to..."
msgstr "Şuna dağıt..."
+msgid "DeployBoards|To see deployment progress for your environments, make sure you are deploying to %{codeStart}$KUBE_NAMESPACE%{codeEnd} and annotating with %{codeStart}app.gitlab.com/app=$CI_PROJECT_PATH_SLUG%{codeEnd} and %{codeStart}app.gitlab.com/env=$CI_ENVIRONMENT_SLUG%{codeEnd}."
+msgstr ""
+
+msgid "DeployBoard|Kubernetes Pods"
+msgstr ""
+
msgid "DeployFreeze|Add a freeze period to prevent unintended releases during a period of time for a given environment. You must update the deployment jobs in %{filename} according to the deploy freezes added here. %{freeze_period_link_start}Learn more.%{freeze_period_link_end}"
msgstr ""
@@ -11955,9 +12092,6 @@ msgstr "Sadece okuma eriÅŸimi"
msgid "DeployTokens|Active Deploy Tokens (%{active_tokens})"
msgstr ""
-msgid "DeployTokens|Allows read and write access to registry images."
-msgstr ""
-
msgid "DeployTokens|Allows read and write access to the package registry."
msgstr ""
@@ -11970,6 +12104,9 @@ msgstr ""
msgid "DeployTokens|Allows read-only access to the repository."
msgstr ""
+msgid "DeployTokens|Allows write access to registry images."
+msgstr ""
+
msgid "DeployTokens|Copy deploy token"
msgstr "Dağıtıcı belirtecini kopyala"
@@ -12063,12 +12200,57 @@ msgstr ""
msgid "Deploying to AWS is easy with GitLab"
msgstr ""
+msgid "Deployment"
+msgstr ""
+
msgid "Deployment Frequency"
msgstr "Dağıtım Sıklığı"
+msgid "Deployment Target|Project deployment target (optional)"
+msgstr ""
+
+msgid "Deployment Target|Select the deployment target"
+msgstr ""
+
msgid "Deployment frequency"
msgstr ""
+msgid "DeploymentTarget|GitLab Pages"
+msgstr ""
+
+msgid "DeploymentTarget|Heroku"
+msgstr ""
+
+msgid "DeploymentTarget|Infrastructure provider (Terraform, Cloudformation, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Kubernetes (GKE, EKS, OpenShift, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Managed container runtime (Fargate, Cloud Run, DigitalOcean App)"
+msgstr ""
+
+msgid "DeploymentTarget|Mobile app store"
+msgstr ""
+
+msgid "DeploymentTarget|No deployment planned"
+msgstr ""
+
+msgid "DeploymentTarget|Other hosting service"
+msgstr ""
+
+msgid "DeploymentTarget|Registry (package or container)"
+msgstr ""
+
+msgid "DeploymentTarget|Self-managed container runtime (Podman, Docker Swarm, Docker Compose)"
+msgstr ""
+
+msgid "DeploymentTarget|Serverless backend (Lambda, Cloud functions)"
+msgstr ""
+
+msgid "DeploymentTarget|Virtual machine (for example, EC2)"
+msgstr ""
+
msgid "Deployments"
msgstr ""
@@ -12107,6 +12289,9 @@ msgstr ""
msgid "Deployment|This deployment was created using the API"
msgstr "Bu dağıtım, API kullanılarak oluşturuldu"
+msgid "Deployment|Triggerer"
+msgstr ""
+
msgid "Deployment|Waiting"
msgstr ""
@@ -12134,6 +12319,18 @@ msgstr "başarılı"
msgid "Deprecated API rate limits"
msgstr ""
+msgid "Deprecations|Feature deprecation and removal"
+msgstr ""
+
+msgid "Deprecations|For information on a possible replacement %{epicStart} learn more about Opstrace %{epicEnd}."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7 and are %{epicStart} scheduled for removal %{epicEnd} in GitLab 15.0."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7, and are %{removal_link_start} scheduled for removal %{link_end} in GitLab 15.0. For information on a possible replacement, %{opstrace_link_start} learn more about Opstrace %{link_end}."
+msgstr ""
+
msgid "Deprioritize label"
msgstr "Etiket önceliğini azalt"
@@ -12379,10 +12576,10 @@ msgstr ""
msgid "DevopsAdoption|At least one deploy"
msgstr ""
-msgid "DevopsAdoption|At least one issue opened"
+msgid "DevopsAdoption|At least one issue created"
msgstr ""
-msgid "DevopsAdoption|At least one merge request opened"
+msgid "DevopsAdoption|At least one merge request created"
msgstr ""
msgid "DevopsAdoption|At least one pipeline successfully run"
@@ -12583,6 +12780,9 @@ msgstr ""
msgid "Direct member"
msgstr ""
+msgid "Direct members"
+msgstr ""
+
msgid "Direct non-authenticated users to this page."
msgstr ""
@@ -12699,6 +12899,9 @@ msgid_plural "Dismiss %d selected vulnerabilities as"
msgstr[0] ""
msgstr[1] ""
+msgid "Dismiss Alert"
+msgstr ""
+
msgid "Dismiss merge request promotion"
msgstr ""
@@ -12726,9 +12929,15 @@ msgstr ""
msgid "Display alerts from all configured monitoring tools."
msgstr ""
+msgid "Display milestones"
+msgstr ""
+
msgid "Display name"
msgstr ""
+msgid "Display progress of child issues"
+msgstr ""
+
msgid "Display rendered file"
msgstr "Oluşturulan dosyayı görüntüle"
@@ -12834,6 +13043,9 @@ msgstr "Dışa aktarmayı indir"
msgid "Download image"
msgstr "Resmi indir"
+msgid "Download payload"
+msgstr ""
+
msgid "Download raw data (.csv)"
msgstr ""
@@ -13011,6 +13223,9 @@ msgstr ""
msgid "Edit in Web IDE"
msgstr ""
+msgid "Edit in pipeline editor"
+msgstr ""
+
msgid "Edit in single-file editor"
msgstr ""
@@ -13053,6 +13268,9 @@ msgstr "Viki sayfasını düzenle"
msgid "Edit your most recent comment in a thread (from an empty textarea)"
msgstr "Bir konudaki en son yorumunu düzenle (boş bir metin alanından)"
+msgid "Edit, lint, and visualize your pipeline."
+msgstr ""
+
msgid "Edited"
msgstr ""
@@ -13494,6 +13712,9 @@ msgstr ""
msgid "Enforce two-factor authentication for all user sign-ins."
msgstr ""
+msgid "Enhance security by storing service account keys in secret managers - learn more about %{docLinkStart}secret management with GitLab%{docLinkEnd}"
+msgstr ""
+
msgid "Ensure connectivity is available from the GitLab server to the Prometheus server"
msgstr ""
@@ -13554,6 +13775,9 @@ 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 following to confirm:"
+msgstr ""
+
msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
@@ -14084,9 +14308,6 @@ 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 ""
@@ -14222,6 +14443,9 @@ msgstr ""
msgid "Errors:"
msgstr ""
+msgid "Escalate this incident"
+msgstr ""
+
msgid "Escalation Policies"
msgstr ""
@@ -14234,6 +14458,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy"
+msgstr ""
+
msgid "Escalation policy:"
msgstr ""
@@ -14485,6 +14712,9 @@ msgstr ""
msgid "Existing sign in methods may be removed"
msgstr ""
+msgid "Exit."
+msgstr ""
+
msgid "Expand"
msgstr "GeniÅŸlet"
@@ -14581,6 +14811,9 @@ msgstr "Projeleri keÅŸfedin"
msgid "Explore public groups"
msgstr "Genel grupları keşfedin"
+msgid "Explore public projects"
+msgstr ""
+
msgid "Explore snippets"
msgstr ""
@@ -14742,7 +14975,7 @@ msgid_plural "Failed to archive designs. Please try again."
msgstr[0] ""
msgstr[1] ""
-msgid "Failed to assign a reviewer because no user was found."
+msgid "Failed to assign a reviewer because no user was specified."
msgstr ""
msgid "Failed to assign a user because no user was found."
@@ -14808,10 +15041,10 @@ msgstr ""
msgid "Failed to find import label for Jira import."
msgstr ""
-msgid "Failed to generate export, please try again later."
+msgid "Failed to find users for %{missing}"
msgstr ""
-msgid "Failed to generate report, please try again after sometime"
+msgid "Failed to generate export, please try again later."
msgstr ""
msgid "Failed to get ref."
@@ -14910,6 +15143,9 @@ msgstr ""
msgid "Failed to remove a to-do item for the design."
msgstr ""
+msgid "Failed to remove attention because no user was found."
+msgstr ""
+
msgid "Failed to remove mirror."
msgstr ""
@@ -14922,6 +15158,9 @@ msgstr ""
msgid "Failed to remove user key."
msgstr ""
+msgid "Failed to request attention because no user was found."
+msgstr ""
+
msgid "Failed to reset key. Please try again."
msgstr ""
@@ -15003,6 +15242,9 @@ msgstr ""
msgid "Feature Flags"
msgstr "Özellik Bayrakları"
+msgid "Feature deprecation and removal"
+msgstr ""
+
msgid "Feature flag status"
msgstr ""
@@ -15500,7 +15742,7 @@ msgstr ""
msgid "For each job, re-use the project workspace. If the workspace doesn't exist, use %{code_open}git clone%{code_close}."
msgstr ""
-msgid "For example, the application using the token or the purpose of the token."
+msgid "For example, the application using the token or the purpose of the token. Do not give sensitive information for the name of the token, as it will be visible to all %{resource_type} members."
msgstr ""
msgid "For files larger than this limit, only index the file name. The file content is neither indexed nor searchable."
@@ -15584,9 +15826,6 @@ msgstr ""
msgid "ForkProject|Select a namespace"
msgstr ""
-msgid "ForkProject|Select a namespace to fork the project"
-msgstr ""
-
msgid "ForkProject|The project can be accessed by any logged in user."
msgstr ""
@@ -15683,6 +15922,9 @@ msgstr ""
msgid "Full name"
msgstr "Tam isim"
+msgid "GCP region configured"
+msgstr ""
+
msgid "GPG Key ID:"
msgstr ""
@@ -15863,6 +16105,9 @@ msgstr ""
msgid "Geo|Failed"
msgstr ""
+msgid "Geo|Filter Geo sites"
+msgstr ""
+
msgid "Geo|Filter by name"
msgstr "İsme göre filtrele"
@@ -16274,6 +16519,12 @@ msgstr "GitLab içe aktarma"
msgid "GitLab Issue"
msgstr "GitLab Sorunu"
+msgid "GitLab KAS"
+msgstr ""
+
+msgid "GitLab Memberships CSV Export"
+msgstr ""
+
msgid "GitLab Pages"
msgstr ""
@@ -16322,6 +16573,9 @@ 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 free to use. Many features for larger teams are part of our %{link_start}paid products%{link_end}. You can try Ultimate for free without any obligation or payment details."
+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 ""
@@ -16448,7 +16702,7 @@ msgstr "Doğrulandı"
msgid "GitLabPages|When enabled, all attempts to visit your website through HTTP are automatically redirected to HTTPS using a response with status code 301. Requires a valid certificate for all domains. %{docs_link_start}Learn more.%{link_end}"
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. %{docs_link_start}Learn more.%{link_end}"
+msgid "GitLabPages|When using Pages under the general domain of a GitLab instance (%{pages_host}), you cannot use HTTPS with subdomains of subdomains. If your namespace or groupname contains a dot, it does not work. This is a limitation of the HTTP Over TLS protocol. HTTP pages work if you don't redirect HTTP to HTTPS. %{docs_link_start}Learn more.%{link_end}"
msgstr ""
msgid "GitLabPages|With GitLab Pages you can host your static website directly from your GitLab repository. %{docs_link_start}Learn more.%{link_end}"
@@ -16625,9 +16879,6 @@ msgstr "Dosyalara git"
msgid "Go to find file"
msgstr "Dosya bulmaya git"
-msgid "Go to fork"
-msgstr ""
-
msgid "Go to issue boards"
msgstr "Sorun panolarına git"
@@ -16835,9 +17086,6 @@ msgstr "Grup Git LFS durumu:"
msgid "Group Hooks"
msgstr ""
-msgid "Group ID"
-msgstr ""
-
msgid "Group Owner must have signed in with SAML before enabling Group Managed Accounts"
msgstr ""
@@ -16865,9 +17113,6 @@ msgstr "Grup profil resmi"
msgid "Group by"
msgstr ""
-msgid "Group description"
-msgstr ""
-
msgid "Group description (optional)"
msgstr "Grup açıklaması (isteğe bağlı)"
@@ -16982,7 +17227,7 @@ msgstr ""
msgid "Group: %{name}"
msgstr ""
-msgid "GroupActivityMetrics|Issues opened"
+msgid "GroupActivityMetrics|Issues created"
msgstr ""
msgid "GroupActivityMetrics|Last 90 days"
@@ -16991,7 +17236,7 @@ msgstr ""
msgid "GroupActivityMetrics|Members added"
msgstr ""
-msgid "GroupActivityMetrics|Merge Requests opened"
+msgid "GroupActivityMetrics|Merge Requests created"
msgstr ""
msgid "GroupActivityMetrics|Recent activity"
@@ -17282,6 +17527,9 @@ msgstr ""
msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
+msgid "GroupSettings|Choose a group path that does not start with a dash or end with a period. It can also contain alphanumeric characters and underscores."
+msgstr ""
+
msgid "GroupSettings|Compliance frameworks"
msgstr ""
@@ -17315,7 +17563,7 @@ msgstr ""
msgid "GroupSettings|If not specified at the group or instance level, the default is %{default_initial_branch_name}. Does not affect existing repositories."
msgstr ""
-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."
+msgid "GroupSettings|If the parent group's visibility is lower than the group's current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility."
msgstr ""
msgid "GroupSettings|New runners registration token has been generated!"
@@ -17432,8 +17680,11 @@ msgstr ""
msgid "Groups and projects"
msgstr "Gruplar ve projeler"
-msgid "Groups and subgroups"
-msgstr "Gruplar ve alt gruplar"
+msgid "Groups are a great way to organize projects and people."
+msgstr ""
+
+msgid "Groups are the best way to manage projects and members."
+msgstr ""
msgid "Groups to synchronize"
msgstr ""
@@ -17543,13 +17794,16 @@ msgstr ""
msgid "GroupsTree|Are you sure you want to leave the \"%{fullName}\" group?"
msgstr ""
-msgid "GroupsTree|Edit group"
-msgstr "Grubu düzenle"
+msgid "GroupsTree|Delete"
+msgstr ""
+
+msgid "GroupsTree|Edit"
+msgstr ""
msgid "GroupsTree|Failed to leave the group. Please make sure you are not the only owner."
msgstr ""
-msgid "GroupsTree|Leave this group"
+msgid "GroupsTree|Leave group"
msgstr ""
msgid "GroupsTree|Loading groups"
@@ -17561,9 +17815,57 @@ msgstr "Aramanızla eşleşen grup yok"
msgid "GroupsTree|No groups or projects matched your search"
msgstr "Aramanız ile eşleşen grup veya proje yok"
+msgid "GroupsTree|Options"
+msgstr ""
+
msgid "GroupsTree|Search by name"
msgstr "İsme göre arayın"
+msgid "Groups|Avatar will be removed. Are you sure?"
+msgstr ""
+
+msgid "Groups|Changing group URL can have unintended side effects."
+msgstr ""
+
+msgid "Groups|Checking group URL availability..."
+msgstr ""
+
+msgid "Groups|Enter a descriptive name for your group."
+msgstr ""
+
+msgid "Groups|Group ID"
+msgstr ""
+
+msgid "Groups|Group URL"
+msgstr ""
+
+msgid "Groups|Group avatar"
+msgstr ""
+
+msgid "Groups|Group description (optional)"
+msgstr ""
+
+msgid "Groups|Group name"
+msgstr ""
+
+msgid "Groups|Group path is available."
+msgstr ""
+
+msgid "Groups|Group path is unavailable. Path has been replaced with a suggested available path."
+msgstr ""
+
+msgid "Groups|Learn more"
+msgstr ""
+
+msgid "Groups|Must start with letter, digit, emoji, or underscore. Can also contain periods, dashes, spaces, and parentheses."
+msgstr ""
+
+msgid "Groups|Remove avatar"
+msgstr ""
+
+msgid "Groups|Save changes"
+msgstr ""
+
msgid "Guideline"
msgstr ""
@@ -17573,6 +17875,9 @@ msgstr ""
msgid "HAR file path or URL"
msgstr ""
+msgid "HTTP Archive (HAR)"
+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 ""
@@ -17973,6 +18278,9 @@ msgstr ""
msgid "INFO: Your SSH key is expiring soon. Please generate a new key."
msgstr ""
+msgid "IP"
+msgstr ""
+
msgid "IP Address"
msgstr "IP Adresi"
@@ -18009,6 +18317,9 @@ msgstr ""
msgid "IdentityVerification|Verify your identity"
msgstr ""
+msgid "IdentityVerification|You can always verify your account at a later time to create a group."
+msgstr ""
+
msgid "If any indexed field exceeds this limit, it is truncated to this number of characters. The rest of the content is neither indexed nor searchable. This does not apply to repository and wiki indexing. For unlimited characters, set this to 0."
msgstr ""
@@ -18066,6 +18377,9 @@ msgstr ""
msgid "If you add %{codeStart}needs%{codeEnd} to jobs in your pipeline you'll be able to view the %{codeStart}needs%{codeEnd} relationships between jobs in this tab as a %{linkStart}Directed Acyclic Graph (DAG)%{linkEnd}."
msgstr ""
+msgid "If you are added to a project, it will be displayed here."
+msgstr ""
+
msgid "If you did not initiate these sign-in attempts, please reach out to your administrator or enable two-factor authentication (2FA) on your account."
msgstr ""
@@ -18372,12 +18686,24 @@ msgstr ""
msgid "InProductMarketing|3 ways to dive into GitLab CI/CD"
msgstr ""
+msgid "InProductMarketing|A single application eliminates complex integrations, data chokepoints, and toolchain maintenance, resulting in greater productivity and lower cost."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features, build more efficiently, strengthen security and compliance."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features."
+msgstr ""
+
msgid "InProductMarketing|Actually, GitLab makes the team work (better)"
msgstr ""
msgid "InProductMarketing|And finally %{deploy_link} a Python application."
msgstr ""
+msgid "InProductMarketing|And many more..."
+msgstr ""
+
msgid "InProductMarketing|Are your runners ready?"
msgstr ""
@@ -18396,15 +18722,33 @@ msgstr ""
msgid "InProductMarketing|Blog"
msgstr ""
+msgid "InProductMarketing|Break down silos to coordinate seamlessly across development, operations, and security with a consistent experience across the development lifecycle."
+msgstr ""
+
+msgid "InProductMarketing|Burn up/down charts"
+msgstr ""
+
msgid "InProductMarketing|By enabling code owners and required merge approvals the right person will review the right MR. This is a win-win: cleaner code and a more efficient review process."
msgstr ""
msgid "InProductMarketing|Click on the number below that corresponds with your answer — 1 being very difficult, 5 being very easy."
msgstr ""
+msgid "InProductMarketing|Code owners"
+msgstr ""
+
msgid "InProductMarketing|Code owners and required merge approvals are part of the paid tiers of GitLab. You can start a free 30-day trial of GitLab Ultimate and enable these features in less than 5 minutes with no credit card required."
msgstr ""
+msgid "InProductMarketing|Code review analytics"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration across stages in GitLab"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration made easy"
+msgstr ""
+
msgid "InProductMarketing|Create a custom CI runner with just a few clicks"
msgstr ""
@@ -18414,12 +18758,21 @@ msgstr ""
msgid "InProductMarketing|Create a project in GitLab in 5 minutes"
msgstr "GitLab'da 5 dakikada bir proje oluÅŸturun"
+msgid "InProductMarketing|Create well-defined workflows by using scoped labels on issues, merge requests, and epics. Labels with the same scope cannot be used together, which prevents conflicts."
+msgstr ""
+
msgid "InProductMarketing|Create your first project!"
msgstr ""
+msgid "InProductMarketing|Define who owns specific files or directories, so the right reviewers are suggested when a merge request introduces changes to those files."
+msgstr ""
+
msgid "InProductMarketing|Deliver Better Products Faster"
msgstr ""
+msgid "InProductMarketing|Dependency scanning"
+msgstr ""
+
msgid "InProductMarketing|Did you know teams that use GitLab are far more efficient?"
msgstr ""
@@ -18429,15 +18782,27 @@ msgstr ""
msgid "InProductMarketing|Dig in and create a project and a repo"
msgstr ""
+msgid "InProductMarketing|Discover Premium & Ultimate"
+msgstr ""
+
+msgid "InProductMarketing|Discover Premium & Ultimate."
+msgstr ""
+
msgid "InProductMarketing|Do you have a minute?"
msgstr ""
msgid "InProductMarketing|Do you have a teammate who would be perfect for this task?"
msgstr ""
+msgid "InProductMarketing|Dynamic application security testing"
+msgstr ""
+
msgid "InProductMarketing|Easy"
msgstr ""
+msgid "InProductMarketing|Epics"
+msgstr ""
+
msgid "InProductMarketing|Expand your DevOps journey with a free GitLab trial"
msgstr ""
@@ -18459,9 +18824,15 @@ msgstr ""
msgid "InProductMarketing|Feel the need for speed?"
msgstr ""
+msgid "InProductMarketing|Find and fix bottlenecks in your code review process by understanding how long open merge requests have been in review."
+msgstr ""
+
msgid "InProductMarketing|Find out how your teams are really doing"
msgstr ""
+msgid "InProductMarketing|Find out if your external libraries are safe. Run dependency scanning jobs that check for known vulnerabilities in your external libraries."
+msgstr ""
+
msgid "InProductMarketing|Follow our steps"
msgstr ""
@@ -18498,6 +18869,9 @@ msgstr ""
msgid "InProductMarketing|GitLab is better with teammates to help out!"
msgstr ""
+msgid "InProductMarketing|GitLab is infrastructure agnostic (supporting GCP, AWS, Azure, OpenShift, VMWare, On Prem, Bare Metal, and more), offering a consistent workflow experience – irrespective of the environment."
+msgstr ""
+
msgid "InProductMarketing|GitLab provides static application security testing (SAST), dynamic application security testing (DAST), container scanning, and dependency scanning to help you deliver secure applications along with license compliance."
msgstr ""
@@ -18588,21 +18962,36 @@ msgstr ""
msgid "InProductMarketing|It's also possible to simply %{external_repo_link} in order to take advantage of GitLab's CI/CD."
msgstr ""
+msgid "InProductMarketing|Keep your code quality high by defining who should approve merge requests and how many approvals are required."
+msgstr ""
+
msgid "InProductMarketing|Launch GitLab CI/CD in 20 minutes or less"
msgstr ""
+msgid "InProductMarketing|Lower cost of development"
+msgstr ""
+
+msgid "InProductMarketing|Make it easier to collaborate on high-level ideas by grouping related issues in an epic."
+msgstr ""
+
msgid "InProductMarketing|Making the switch? It's easier than you think to import your projects into GitLab. Move %{github_link}, or import something %{bitbucket_link}."
msgstr ""
msgid "InProductMarketing|Master the art of importing!"
msgstr ""
+msgid "InProductMarketing|Merge request approval rule"
+msgstr ""
+
msgid "InProductMarketing|Move on to easily creating a Pages website %{ci_template_link}"
msgstr ""
msgid "InProductMarketing|Multiple owners, confusing workstreams? We've got you covered"
msgstr ""
+msgid "InProductMarketing|Multiple required approvers"
+msgstr ""
+
msgid "InProductMarketing|Need an alternative to importing?"
msgstr ""
@@ -18615,18 +19004,33 @@ msgstr ""
msgid "InProductMarketing|Our tool brings all the things together"
msgstr ""
+msgid "InProductMarketing|Protect your web application by using DAST to examine for vulnerabilities in deployed environments."
+msgstr ""
+
msgid "InProductMarketing|Rapid development, simplified"
msgstr ""
msgid "InProductMarketing|Reduce Security & Compliance Risk"
msgstr ""
+msgid "InProductMarketing|Require multiple approvers on a merge request, so you know it's in good shape before it's merged."
+msgstr ""
+
+msgid "InProductMarketing|Roadmaps"
+msgstr ""
+
+msgid "InProductMarketing|Scoped labels"
+msgstr ""
+
msgid "InProductMarketing|Security that's integrated into your development lifecycle"
msgstr ""
msgid "InProductMarketing|Sometimes you're not ready to make a full transition to a new tool. If you're not ready to fully commit, %{mirroring_link} gives you a safe way to try out GitLab in parallel with your current tool."
msgstr ""
+msgid "InProductMarketing|Speed. Efficiency. Trust."
+msgstr ""
+
msgid "InProductMarketing|Spin up an autoscaling runner in GitLab"
msgstr ""
@@ -18636,6 +19040,9 @@ msgstr ""
msgid "InProductMarketing|Start a Self-Managed trial"
msgstr ""
+msgid "InProductMarketing|Start a free trial"
+msgstr ""
+
msgid "InProductMarketing|Start a free trial of GitLab Ultimate – no credit card required"
msgstr ""
@@ -18702,6 +19109,9 @@ msgstr ""
msgid "InProductMarketing|To understand and get the most out of GitLab, start at the beginning and %{project_link}. In GitLab, repositories are part of a project, so after you've created your project you can go ahead and %{repo_link}."
msgstr ""
+msgid "InProductMarketing|Track completed issues in a chart, so you can see how a milestone is progressing at a glance."
+msgstr ""
+
msgid "InProductMarketing|Try GitLab Ultimate for free"
msgstr ""
@@ -18738,6 +19148,9 @@ msgstr ""
msgid "InProductMarketing|Very easy"
msgstr ""
+msgid "InProductMarketing|Visualize your epics and milestones in a timeline."
+msgstr ""
+
msgid "InProductMarketing|Want to host GitLab on your servers?"
msgstr ""
@@ -18759,6 +19172,9 @@ msgstr ""
msgid "InProductMarketing|YouTube"
msgstr ""
+msgid "InProductMarketing|Your software, deployed your way"
+msgstr ""
+
msgid "InProductMarketing|Your teams can be more efficient"
msgstr ""
@@ -18879,9 +19295,18 @@ msgstr ""
msgid "IncidentManagement|No incidents to display."
msgstr ""
+msgid "IncidentManagement|None"
+msgstr ""
+
msgid "IncidentManagement|Open"
msgstr "Açık"
+msgid "IncidentManagement|Page your team with escalation policies"
+msgstr ""
+
+msgid "IncidentManagement|Paged"
+msgstr ""
+
msgid "IncidentManagement|Published"
msgstr "Yayınlanma"
@@ -18891,6 +19316,9 @@ msgstr ""
msgid "IncidentManagement|Severity"
msgstr "Önem"
+msgid "IncidentManagement|Status"
+msgstr ""
+
msgid "IncidentManagement|There are no closed incidents"
msgstr ""
@@ -18909,6 +19337,9 @@ msgstr "Bilinmeyen"
msgid "IncidentManagement|Unpublished"
msgstr "Yayınlanmamış"
+msgid "IncidentManagement|Use escalation policies to automatically page your team when incidents are created."
+msgstr ""
+
msgid "IncidentSettings|Activate \"time to SLA\" countdown timer"
msgstr ""
@@ -18954,7 +19385,10 @@ msgstr "dakika"
msgid "Incidents"
msgstr "Olaylar"
-msgid "Incidents|Add a URL"
+msgid "Incidents|Add image details"
+msgstr ""
+
+msgid "Incidents|Add text or a link to display with your image. If you don't add either, the file name displays instead."
msgstr ""
msgid "Incidents|Drop or %{linkStart}upload%{linkEnd} a metric screenshot to attach it to the incident"
@@ -18969,10 +19403,10 @@ msgstr ""
msgid "Incidents|There was an issue loading metric images."
msgstr ""
-msgid "Incidents|There was an issue uploading your image."
+msgid "Incidents|There was an issue updating your image."
msgstr ""
-msgid "Incidents|You can optionally add a URL to link users to the original graph."
+msgid "Incidents|There was an issue uploading your image."
msgstr ""
msgid "Incident|Alert details"
@@ -18981,9 +19415,18 @@ msgstr ""
msgid "Incident|Are you sure you wish to delete this image?"
msgstr ""
+msgid "Incident|Delete image"
+msgstr ""
+
msgid "Incident|Deleting %{filename}"
msgstr ""
+msgid "Incident|Edit image text or link"
+msgstr ""
+
+msgid "Incident|Editing %{filename}"
+msgstr ""
+
msgid "Incident|Metrics"
msgstr ""
@@ -19253,12 +19696,18 @@ msgstr ""
msgid "Integrations|Branches for which notifications are to be sent"
msgstr ""
+msgid "Integrations|Clear if using a self-signed certificate."
+msgstr ""
+
msgid "Integrations|Comment detail:"
msgstr "Yorum ayrıntıları:"
msgid "Integrations|Comment settings:"
msgstr "Yorum ayarları:"
+msgid "Integrations|Connection details"
+msgstr ""
+
msgid "Integrations|Connection failed. Please check your settings."
msgstr ""
@@ -19283,6 +19732,9 @@ msgstr ""
msgid "Integrations|Enable GitLab.com slash commands in a Slack workspace."
msgstr ""
+msgid "Integrations|Enable SSL verification"
+msgstr ""
+
msgid "Integrations|Enable comments"
msgstr "Yorumları etkinleştir"
@@ -19361,6 +19813,9 @@ msgstr ""
msgid "Integrations|Return to GitLab for Jira"
msgstr ""
+msgid "Integrations|SSL verification"
+msgstr ""
+
msgid "Integrations|Save settings?"
msgstr "Ayarlar kaydedilsin mi?"
@@ -19406,9 +19861,6 @@ msgstr "Özel ayarları kullan"
msgid "Integrations|Use default settings"
msgstr "Varsayılan ayarları kullan"
-msgid "Integrations|When you mention a Jira issue in a commit or merge request, GitLab creates a remote link and comment (if enabled)."
-msgstr ""
-
msgid "Integrations|You can now close this window and return to the GitLab for Jira application."
msgstr ""
@@ -19433,9 +19885,6 @@ msgstr ""
msgid "Integrations|can't exceed %{recipients_limit}"
msgstr ""
-msgid "Interactive developer security education."
-msgstr ""
-
msgid "Interactive mode"
msgstr ""
@@ -19925,6 +20374,9 @@ msgstr ""
msgid "IssueAnalytics|Assignees"
msgstr ""
+msgid "IssueAnalytics|Created by"
+msgstr ""
+
msgid "IssueAnalytics|Due date"
msgstr ""
@@ -19937,9 +20389,6 @@ msgstr ""
msgid "IssueAnalytics|Milestone"
msgstr "Dönüm noktası"
-msgid "IssueAnalytics|Opened by"
-msgstr "Açıldı:"
-
msgid "IssueAnalytics|Status"
msgstr ""
@@ -20063,10 +20512,10 @@ msgstr ""
msgid "IssuesAnalytics|Avg/Month:"
msgstr "Ortalama/Ay:"
-msgid "IssuesAnalytics|Issues opened"
-msgstr "Sorun açıldı"
+msgid "IssuesAnalytics|Issues created"
+msgstr ""
-msgid "IssuesAnalytics|Issues opened per month"
+msgid "IssuesAnalytics|Issues created per month"
msgstr ""
msgid "IssuesAnalytics|Last 12 months"
@@ -20093,6 +20542,9 @@ msgstr ""
msgid "It looks like you have some draft commits in this branch."
msgstr ""
+msgid "It looks like you're attempting to activate your subscription. Use %{a_start}the Subscription page%{a_end} instead."
+msgstr ""
+
msgid "It may be several days before you see feature usage data."
msgstr ""
@@ -20321,6 +20773,9 @@ msgstr ""
msgid "JiraConnect|You can now close this window and return to Jira."
msgstr ""
+msgid "JiraConnect|You don't have permission to create branches for this project. Select a different project or contact the project owner for access. %{linkStart}Learn more.%{linkEnd}"
+msgstr ""
+
msgid "JiraRequest|A connection error occurred while connecting to Jira. Try your request again."
msgstr ""
@@ -20369,13 +20824,13 @@ msgstr ""
msgid "JiraService|Define the type of Jira issue to create from a vulnerability."
msgstr ""
-msgid "JiraService|Displaying Jira issues while leaving the GitLab issue functionality enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
+msgid "JiraService|Displaying Jira issues while leaving GitLab issues also enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
msgstr ""
-msgid "JiraService|Enable Jira issues"
+msgid "JiraService|Enable Jira issue creation from vulnerabilities"
msgstr ""
-msgid "JiraService|Enable Jira issues creation from vulnerabilities"
+msgid "JiraService|Enable Jira issues"
msgstr ""
msgid "JiraService|Enable Jira transitions"
@@ -20492,16 +20947,19 @@ msgstr ""
msgid "JiraService|View Jira issues in GitLab"
msgstr ""
-msgid "JiraService|Warning: All GitLab users that have access to this GitLab project are able to view all issues from the Jira project specified below."
+msgid "JiraService|Warning: All GitLab users with access to this GitLab project can view all issues from the Jira project you select."
msgstr ""
msgid "JiraService|Web URL"
msgstr "Web URL'si"
-msgid "JiraService|Work on Jira issues without leaving GitLab. Adds a Jira menu to access your list of Jira issues and view any issue as read-only."
+msgid "JiraService|When a Jira issue is mentioned in a commit or merge request, a remote link and comment (if enabled) will be created."
+msgstr ""
+
+msgid "JiraService|Work on Jira issues without leaving GitLab. Add a Jira menu to access a read-only list of your Jira issues."
msgstr ""
-msgid "JiraService|You need to configure Jira before enabling this integration. For more details, read the %{jira_doc_link_start}Jira integration documentation%{link_end}."
+msgid "JiraService|You must configure Jira before enabling this integration. %{jira_doc_link_start}Learn more.%{link_end}"
msgstr ""
msgid "Job"
@@ -20513,9 +20971,6 @@ msgstr ""
msgid "Job Failed #%{build_id}"
msgstr "İş Başarısız #%{build_id}"
-msgid "Job ID"
-msgstr ""
-
msgid "Job artifact"
msgstr ""
@@ -20582,9 +21037,27 @@ msgstr ""
msgid "Jobs|You're about to retry a job that failed because it attempted to deploy code that is older than the latest deployment. Retrying this job could result in overwriting the environment with the older source code."
msgstr ""
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source} into %{target}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{ref}"
+msgstr ""
+
+msgid "Job|Are you sure you want to erase this job log and artifacts?"
+msgstr ""
+
msgid "Job|Browse"
msgstr "Gözat"
+msgid "Job|Cancel"
+msgstr ""
+
msgid "Job|Complete Raw"
msgstr ""
@@ -20594,6 +21067,9 @@ msgstr "Ä°ndir"
msgid "Job|Erase job log and artifacts"
msgstr ""
+msgid "Job|Finished at"
+msgstr ""
+
msgid "Job|Job artifacts"
msgstr ""
@@ -20606,8 +21082,8 @@ msgstr ""
msgid "Job|Keep"
msgstr ""
-msgid "Job|Pipeline"
-msgstr "İş Hattı"
+msgid "Job|Retry"
+msgstr ""
msgid "Job|Scroll to bottom"
msgstr "En alta kaydır"
@@ -20618,6 +21094,9 @@ msgstr "En üste kaydır"
msgid "Job|Show complete raw"
msgstr ""
+msgid "Job|Status"
+msgstr ""
+
msgid "Job|The artifacts were removed"
msgstr ""
@@ -20645,21 +21124,12 @@ msgstr ""
msgid "Job|delayed"
msgstr ""
-msgid "Job|for"
-msgstr ""
-
-msgid "Job|into"
-msgstr ""
-
msgid "Job|manual"
msgstr ""
msgid "Job|triggered"
msgstr ""
-msgid "Job|with"
-msgstr ""
-
msgid "Join Zoom meeting"
msgstr ""
@@ -20762,9 +21232,6 @@ msgstr ""
msgid "Ki"
msgstr ""
-msgid "Kontra"
-msgstr ""
-
msgid "Kroki"
msgstr ""
@@ -21088,6 +21555,9 @@ msgstr ""
msgid "Learn more about Auto DevOps"
msgstr "Otomatik DevOps hakkında daha fazla bilgi edinin"
+msgid "Learn more about GitLab"
+msgstr ""
+
msgid "Learn more about Needs relationships"
msgstr ""
@@ -21415,9 +21885,18 @@ msgstr ""
msgid "Licenses|Displays licenses detected in the project, based on the %{linkStart}latest successful%{linkEnd} scan"
msgstr ""
+msgid "Licenses|Drag your license file here or %{linkStart}click to upload%{linkEnd}."
+msgstr ""
+
+msgid "Licenses|Drop your license file to start the upload."
+msgstr ""
+
msgid "Licenses|Error fetching the license list. Please check your network connection and try again."
msgstr ""
+msgid "Licenses|Error: You are trying to upload something other than a file"
+msgstr ""
+
msgid "Licenses|License Compliance"
msgstr ""
@@ -21436,6 +21915,9 @@ msgstr ""
msgid "Licenses|Specified policies in this project"
msgstr ""
+msgid "Licenses|The file could not be uploaded."
+msgstr ""
+
msgid "Licenses|The license list details information about the licenses used within your project."
msgstr ""
@@ -21469,11 +21951,6 @@ msgstr ""
msgid "Limit the size of Sidekiq jobs stored in Redis."
msgstr ""
-msgid "Limited to showing %d event at most"
-msgid_plural "Limited to showing %d events at most"
-msgstr[0] "En fazla %d olay gösterimiyle sınırlı"
-msgstr[1] "En fazla %d olay gösterimiyle sınırlı"
-
msgid "Limiting mode"
msgstr ""
@@ -21483,6 +21960,9 @@ msgstr ""
msgid "Link"
msgstr ""
+msgid "Link (optional)"
+msgstr ""
+
msgid "Link Prometheus monitoring to GitLab."
msgstr ""
@@ -21519,6 +21999,9 @@ msgstr ""
msgid "Linked emails (%{email_count})"
msgstr "Bağlantılı e-postalar (%{email_count})"
+msgid "Linked epics"
+msgstr ""
+
msgid "Linked issues"
msgstr ""
@@ -21546,6 +22029,15 @@ msgstr ""
msgid "List of all merge commits"
msgstr ""
+msgid "List of environments for this project"
+msgstr ""
+
+msgid "List of suitable GCP locations"
+msgstr ""
+
+msgid "List of users allowed to exceed the rate limit."
+msgstr ""
+
msgid "List options"
msgstr ""
@@ -21765,6 +22257,9 @@ msgstr ""
msgid "Maintenance mode"
msgstr ""
+msgid "Make adjustments to how your GitLab instance is set up."
+msgstr ""
+
msgid "Make and review changes in the browser with the Web IDE"
msgstr ""
@@ -21909,6 +22404,12 @@ msgstr ""
msgid "MarkdownEditor|Add italic text (%{modifier_key}I)"
msgstr ""
+msgid "MarkdownEditor|Add strikethrough text (%{modifierKey}⇧X)"
+msgstr ""
+
+msgid "MarkdownEditor|Add strikethrough text (%{modifier_key}⇧X)"
+msgstr ""
+
msgid "Marked For Deletion At - %{deletion_time}"
msgstr ""
@@ -22170,6 +22671,9 @@ msgstr ""
msgid "Maximum push size (MB)"
msgstr ""
+msgid "Maximum requests per 10 minutes per user"
+msgstr ""
+
msgid "Maximum requests per minute"
msgstr ""
@@ -22260,6 +22764,19 @@ msgstr ""
msgid "Members of a group may only view projects they have permission to access"
msgstr ""
+msgid "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seat in use and will be billed for the overage."
+msgid_plural "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seats in use and will be billed for the overage."
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "MembersOverage|You are about to incur additional charges"
+msgstr ""
+
+msgid "MembersOverage|Your subscription includes %d seat."
+msgid_plural "MembersOverage|Your subscription includes %d seats."
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Membership"
msgstr ""
@@ -22464,9 +22981,6 @@ msgstr ""
msgid "Merge request not merged"
msgstr ""
-msgid "Merge request pipelines 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 merge request pipelines."
-msgstr ""
-
msgid "Merge request reports"
msgstr ""
@@ -22563,13 +23077,13 @@ msgstr "Taslak yorum kaydedilirken bir hata oluÅŸtu."
msgid "MergeRequests|Create issue to resolve thread"
msgstr ""
-msgid "MergeRequests|Failed to squash. Should be done manually."
-msgstr ""
-
msgid "MergeRequests|Saving the comment failed"
msgstr "Yorum kaydedilemedi"
-msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
+msgid "MergeRequests|Squashing failed: Squash the commits locally, resolve any conflicts, then push the branch."
+msgstr ""
+
+msgid "MergeRequests|Squashing not allowed: This project doesn't allow you to squash commits when merging."
msgstr ""
msgid "MergeRequests|Thread stays resolved"
@@ -23410,6 +23924,18 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "MrList|Assigned to %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from assignee %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from reviewer %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Review requested from %{name}, go to their profile."
+msgstr ""
+
msgid "Multi-project"
msgstr ""
@@ -23443,7 +23969,7 @@ msgstr ""
msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "My Awesome Group"
+msgid "My awesome group"
msgstr ""
msgid "My company or team"
@@ -24065,9 +24591,6 @@ msgstr ""
msgid "No available branches"
msgstr ""
-msgid "No available groups to fork the project."
-msgstr ""
-
msgid "No branches found"
msgstr "Dal bulunamadı"
@@ -24278,6 +24801,9 @@ msgstr "Genel grup yok"
msgid "No ref selected"
msgstr ""
+msgid "No regions configured"
+msgstr ""
+
msgid "No related merge requests found."
msgstr ""
@@ -25082,6 +25608,9 @@ msgstr ""
msgid "Only reCAPTCHA v2 is supported:"
msgstr ""
+msgid "Only required if not using role instance credentials."
+msgstr ""
+
msgid "Only use lowercase letters, numbers, and underscores."
msgstr ""
@@ -25106,9 +25635,6 @@ msgstr "Seçimi Aç"
msgid "Open a CLI and connect to the cluster you want to install the agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
-msgid "Open epics"
-msgstr ""
-
msgid "Open errors"
msgstr "Açık hatalar"
@@ -25148,8 +25674,8 @@ msgstr ""
msgid "Opened issues"
msgstr "Açılan sorunlar"
-msgid "OpenedNDaysAgo|Opened"
-msgstr "Açıldı:"
+msgid "OpenedNDaysAgo|Created"
+msgstr ""
msgid "Opens in a new window"
msgstr "Yeni bir pencerede açılır"
@@ -25193,9 +25719,6 @@ msgstr ""
msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
-msgid "Optional."
-msgstr ""
-
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
msgstr ""
@@ -25984,6 +26507,9 @@ msgstr ""
msgid "PerformanceBar|Memory"
msgstr ""
+msgid "PerformanceBar|Memory report"
+msgstr ""
+
msgid "PerformanceBar|Redis calls"
msgstr ""
@@ -26017,18 +26543,12 @@ msgstr ""
msgid "PerformanceBar|wall"
msgstr ""
-msgid "Performs a rebase but skips triggering a new pipeline"
-msgstr ""
-
msgid "Period in seconds"
msgstr ""
msgid "Permalink"
msgstr ""
-msgid "Permanently delete project"
-msgstr ""
-
msgid "Permanently remove group"
msgstr ""
@@ -26299,6 +26819,51 @@ msgstr ""
msgid "PipelineStatusTooltip|Pipeline: %{ci_status}"
msgstr "İş hattı: %{ci_status}"
+msgid "PipelineWizardDefaultCommitMessage|Add %{filename}"
+msgstr ""
+
+msgid "PipelineWizardDefaultCommitMessage|Update %{filename}"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|At least one entry is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This field is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This value is not valid"
+msgstr ""
+
+msgid "PipelineWizardListWidget|add another step"
+msgstr ""
+
+msgid "PipelineWizardListWidget|remove step"
+msgstr ""
+
+msgid "PipelineWizard|Commit"
+msgstr ""
+
+msgid "PipelineWizard|Commit Message"
+msgstr ""
+
+msgid "PipelineWizard|Commit changes to your file"
+msgstr ""
+
+msgid "PipelineWizard|Commit file to Branch"
+msgstr ""
+
+msgid "PipelineWizard|Commit your new file"
+msgstr ""
+
+msgid "PipelineWizard|The file has been committed."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem committing the changes."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem while checking whether your file already exists in the specified branch."
+msgstr ""
+
msgid "Pipelines"
msgstr "İş hatları"
@@ -26413,7 +26978,7 @@ msgstr ""
msgid "Pipelines|Project cache successfully reset."
msgstr ""
-msgid "Pipelines|Revoke"
+msgid "Pipelines|Revoke trigger"
msgstr ""
msgid "Pipelines|Something went wrong while cleaning runners cache."
@@ -26458,6 +27023,12 @@ msgstr ""
msgid "Pipelines|This is a child pipeline within the parent pipeline"
msgstr ""
+msgid "Pipelines|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipelines|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipelines|This pipeline will run code originating from a forked project merge request. This means that the code can potentially have security considerations like exposing CI variables."
msgstr ""
@@ -26500,9 +27071,6 @@ msgstr ""
msgid "Pipelines|Your changes have been successfully committed. Now redirecting to the new merge request page."
msgstr ""
-msgid "Pipelines|detached"
-msgstr ""
-
msgid "Pipelines|error"
msgstr ""
@@ -26512,10 +27080,13 @@ msgstr ""
msgid "Pipelines|latest"
msgstr ""
-msgid "Pipelines|stuck"
+msgid "Pipelines|merge request"
msgstr ""
-msgid "Pipelines|train"
+msgid "Pipelines|merge train"
+msgstr ""
+
+msgid "Pipelines|stuck"
msgstr ""
msgid "Pipelines|yaml invalid"
@@ -26647,6 +27218,12 @@ msgstr ""
msgid "Pipeline|This change will not change the overall test coverage if merged."
msgstr ""
+msgid "Pipeline|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipeline|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipeline|Trigger author"
msgstr ""
@@ -26671,6 +27248,12 @@ msgstr ""
msgid "Pipeline|for"
msgstr ""
+msgid "Pipeline|merge request"
+msgstr ""
+
+msgid "Pipeline|merge train"
+msgstr ""
+
msgid "Pipeline|on"
msgstr ""
@@ -26809,9 +27392,6 @@ msgstr ""
msgid "Please enter a valid time interval"
msgstr ""
-msgid "Please enter or upload a valid license."
-msgstr ""
-
msgid "Please enter your current password."
msgstr ""
@@ -26920,9 +27500,6 @@ msgstr ""
msgid "Please type %{phrase_code} to proceed or close this modal to cancel."
msgstr "Lütfen devam etmek için %{phrase_code} yazın ya da iptal etmek için bu pencereyi kapatın."
-msgid "Please type the following to confirm:"
-msgstr ""
-
msgid "Please use this form to report to the admin users who create spam issues, comments or behave inappropriately."
msgstr ""
@@ -26950,12 +27527,27 @@ msgstr ""
msgid "Policies"
msgstr ""
+msgid "Policy '%{escalation_policy_name}' does not exist."
+msgstr ""
+
msgid "Policy management project does have any policies in %{policy_path}"
msgstr ""
msgid "Policy project doesn't exist"
msgstr ""
+msgid "PolicyRuleMultiSelect|%{firstLabel} +%{numberOfAdditionalLabels} more"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|All %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select all"
+msgstr ""
+
msgid "Polling interval multiplier"
msgstr ""
@@ -27184,6 +27776,9 @@ msgstr ""
msgid "Private projects can be created in your personal namespace with:"
msgstr ""
+msgid "Problem with %{name} command: %{message}."
+msgstr ""
+
msgid "Proceed"
msgstr ""
@@ -27658,6 +28253,9 @@ msgstr "Bu depoda kullanılan programlama dilleri"
msgid "Progress"
msgstr ""
+msgid "Progress tracking"
+msgstr ""
+
msgid "Project"
msgstr ""
@@ -27889,6 +28487,9 @@ msgstr ""
msgid "ProjectQualitySummary|Failure"
msgstr ""
+msgid "ProjectQualitySummary|Get insight into the overall percentage of tests in your project that succeed, fail and are skipped."
+msgstr ""
+
msgid "ProjectQualitySummary|Latest pipeline results"
msgstr ""
@@ -27907,6 +28508,12 @@ msgstr ""
msgid "ProjectQualitySummary|See project Code Coverage Statistics"
msgstr ""
+msgid "ProjectQualitySummary|Set up test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|Set up test runs (opens in a new tab)"
+msgstr ""
+
msgid "ProjectQualitySummary|Skipped"
msgstr ""
@@ -28183,13 +28790,19 @@ msgstr "Sorunlar"
msgid "ProjectSettings|LFS objects from this repository are available to forks. %{linkStart}How do I remove them?%{linkEnd}"
msgstr ""
+msgid "ProjectSettings|Learn about commit history."
+msgstr ""
+
+msgid "ProjectSettings|Leave empty to use default template."
+msgstr ""
+
msgid "ProjectSettings|Manage who can see the project in the public access directory."
msgstr ""
msgid "ProjectSettings|Manages large files such as audio, video, and graphics files."
msgstr ""
-msgid "ProjectSettings|Maximum 500 characters."
+msgid "ProjectSettings|Maximum %{maxLength} characters."
msgstr ""
msgid "ProjectSettings|Merge checks"
@@ -28330,6 +28943,9 @@ msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
msgstr ""
+msgid "ProjectSettings|The default template will be applied on save."
+msgstr ""
+
msgid "ProjectSettings|These checks must pass before merge requests can be merged."
msgstr ""
@@ -28384,6 +29000,9 @@ msgstr ""
msgid "ProjectSettings|What are badges?"
msgstr ""
+msgid "ProjectSettings|What are merge trains?"
+msgstr ""
+
msgid "ProjectSettings|When merge request pipelines are enabled in the CI/CD configuration file, pipelines validate the combined results of the source and target branches. %{link_start}How to configure merge request pipelines?%{link_end}"
msgstr ""
@@ -28501,6 +29120,9 @@ msgstr ""
msgid "Projects are organized into groups"
msgstr ""
+msgid "Projects are where you store your code, access issues, wiki and other features of GitLab."
+msgstr ""
+
msgid "Projects contributed to"
msgstr ""
@@ -28516,12 +29138,6 @@ msgstr ""
msgid "Projects to index"
msgstr ""
-msgid "Projects will be permanently deleted after a %{waiting_period}-day waiting period."
-msgstr ""
-
-msgid "Projects will be permanently deleted immediately."
-msgstr ""
-
msgid "Projects with critical vulnerabilities"
msgstr ""
@@ -28606,6 +29222,9 @@ msgstr "İçe aktar"
msgid "ProjectsNew|Import project"
msgstr "Projeyi içe aktar"
+msgid "ProjectsNew|Include a Getting Started README"
+msgstr ""
+
msgid "ProjectsNew|Initialize repository with a README"
msgstr "BENÄ°OKU ile depo baÅŸlat"
@@ -28621,6 +29240,9 @@ msgstr ""
msgid "ProjectsNew|Project description %{tag_start}(optional)%{tag_end}"
msgstr "Proje açıklaması %{tag_start}(isteğe bağlı)%{tag_end}"
+msgid "ProjectsNew|Recommended if you're new to GitLab"
+msgstr ""
+
msgid "ProjectsNew|Run CI/CD for external repository"
msgstr ""
@@ -29038,6 +29660,9 @@ msgstr ""
msgid "ProtectedBranch|Unprotect"
msgstr ""
+msgid "ProtectedBranch|Unprotect branch"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
@@ -29065,6 +29690,9 @@ msgstr ""
msgid "ProtectedEnvironment|Protected Environment (%{protected_environments_count})"
msgstr ""
+msgid "ProtectedEnvironment|Required approvals"
+msgstr ""
+
msgid "ProtectedEnvironment|Select an environment"
msgstr ""
@@ -29086,10 +29714,13 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|Unprotect tag"
+msgstr ""
+
msgid "ProtectedTags|default"
msgstr ""
-msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
+msgid "ProtectedTag|By default, protected tags restrict who can modify the tag."
msgstr ""
msgid "ProtectedTag|Learn more."
@@ -29152,6 +29783,9 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Public projects are an easy way to allow everyone to have read-only access."
+msgstr ""
+
msgid "Publish to status page"
msgstr ""
@@ -29308,9 +29942,6 @@ msgstr "Toplam işlemlerin sayısı: %{total_commits_count}"
msgid "QualitySummary|Project quality"
msgstr ""
-msgid "Quarters"
-msgstr ""
-
msgid "Query"
msgstr ""
@@ -29395,6 +30026,9 @@ msgstr ""
msgid "Read more about project permissions %{help_link_open}here%{help_link_close}"
msgstr ""
+msgid "Read more about related epics"
+msgstr ""
+
msgid "Read more about related issues"
msgstr "İlgili sorunlar hakkında daha fazla bilgi edinin"
@@ -29425,10 +30059,7 @@ msgstr ""
msgid "Rebase source branch on the target branch."
msgstr ""
-msgid "Rebase without CI"
-msgstr ""
-
-msgid "Rebases and triggers a pipeline"
+msgid "Rebase without pipeline"
msgstr ""
msgid "Recaptcha verified?"
@@ -29479,9 +30110,6 @@ msgstr ""
msgid "Reconfigure"
msgstr ""
-msgid "Recovering projects"
-msgstr ""
-
msgid "Recovery Codes"
msgstr ""
@@ -29541,6 +30169,12 @@ msgstr ""
msgid "Regex pattern"
msgstr ""
+msgid "Region"
+msgstr ""
+
+msgid "Regions"
+msgstr ""
+
msgid "Register"
msgstr ""
@@ -29771,9 +30405,6 @@ msgstr "Tüm veya belirli etiketleri kaldır"
msgid "Remove all or specific reviewer(s)"
msgstr ""
-msgid "Remove approver"
-msgstr ""
-
msgid "Remove approvers"
msgstr ""
@@ -29789,6 +30420,9 @@ msgstr ""
msgid "Remove attention request"
msgstr ""
+msgid "Remove attention request(s)"
+msgstr ""
+
msgid "Remove avatar"
msgstr "Profil resmini kaldır"
@@ -29927,6 +30561,9 @@ msgstr ""
msgid "Removed an issue from an epic."
msgstr "Epikten bir sorun kaldırıldı."
+msgid "Removed attention from %{users_sentence}."
+msgstr ""
+
msgid "Removed attention request from @%{username}"
msgstr ""
@@ -29978,6 +30615,9 @@ msgstr ""
msgid "Removes an issue from an epic."
msgstr "Epikten bir sorunu kaldırır."
+msgid "Removes attention from %{users_sentence}."
+msgstr ""
+
msgid "Removes parent epic %{epic_ref}."
msgstr "Üst epik %{epic_ref} kaldırır."
@@ -30089,6 +30729,9 @@ msgstr ""
msgid "Report abuse to admin"
msgstr "Kötüye kullanımı yöneticiye bildir"
+msgid "Report is generating and will be sent to your email address."
+msgstr ""
+
msgid "Reported %{timeAgo} by %{reportedBy}"
msgstr "%{reportedBy} tarafından %{timeAgo} bildirildi"
@@ -30378,6 +31021,15 @@ msgstr ""
msgid "Request attention"
msgstr ""
+msgid "Request attention from %{users_sentence}."
+msgstr ""
+
+msgid "Request attention from assignee or reviewer"
+msgstr ""
+
+msgid "Request attention from assignee(s) or reviewer(s)"
+msgstr ""
+
msgid "Request attention to review"
msgstr ""
@@ -30402,6 +31054,9 @@ msgstr ""
msgid "Requested %{time_ago}"
msgstr "%{time_ago} istendi"
+msgid "Requested attention from %{users_sentence}."
+msgstr ""
+
msgid "Requested attention from @%{username}"
msgstr ""
@@ -30616,6 +31271,9 @@ msgstr ""
msgid "Restore project"
msgstr "Projeyi geri yükle"
+msgid "Restoring projects"
+msgstr ""
+
msgid "Restoring the group will prevent the group, its subgroups and projects from being removed on this date."
msgstr ""
@@ -30646,6 +31304,9 @@ msgstr ""
msgid "Retry"
msgstr ""
+msgid "Retry failed jobs"
+msgstr ""
+
msgid "Retry job"
msgstr ""
@@ -30693,9 +31354,6 @@ msgstr ""
msgid "Review changes"
msgstr ""
-msgid "Review requested from %{name}"
-msgstr ""
-
msgid "Review requests for you"
msgstr "Ä°nceleme istekleriniz"
@@ -30860,6 +31518,9 @@ msgstr ""
msgid "Runners|Assigned Group"
msgstr ""
+msgid "Runners|Assigned Projects (%{projectCount})"
+msgstr ""
+
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30929,6 +31590,9 @@ msgstr ""
msgid "Runners|Instance"
msgstr ""
+msgid "Runners|Jobs"
+msgstr ""
+
msgid "Runners|Last contact"
msgstr ""
@@ -31022,9 +31686,6 @@ msgstr ""
msgid "Runners|Runner %{name} was deleted"
msgstr ""
-msgid "Runners|Runner ID"
-msgstr ""
-
msgid "Runners|Runner assigned to project."
msgstr ""
@@ -31172,6 +31833,9 @@ msgstr ""
msgid "Runners|stale"
msgstr ""
+msgid "Runner|This runner has not run any jobs."
+msgstr ""
+
msgid "Running"
msgstr "Çalışıyor"
@@ -31286,6 +31950,24 @@ msgstr ""
msgid "Saving project."
msgstr ""
+msgid "ScanResultPolicy|%{ifLabelStart}if%{ifLabelEnd} %{scanners} scan in an open merge request targeting the %{branches} branch(es) finds %{vulnerabilitiesAllowed} or more %{severities} vulnerabilities that are %{vulnerabilityStates}"
+msgstr ""
+
+msgid "ScanResultPolicy|%{thenLabelStart}Then%{thenLabelEnd} Require approval from %{approvalsRequired} of the following approvers: %{approvers}"
+msgstr ""
+
+msgid "ScanResultPolicy|add an approver"
+msgstr ""
+
+msgid "ScanResultPolicy|scanners"
+msgstr ""
+
+msgid "ScanResultPolicy|severity levels"
+msgstr ""
+
+msgid "ScanResultPolicy|vulnerability states"
+msgstr ""
+
msgid "Scanner"
msgstr ""
@@ -31418,6 +32100,9 @@ msgstr ""
msgid "Search for a user"
msgstr ""
+msgid "Search for an emoji"
+msgstr ""
+
msgid "Search for projects, issues, etc."
msgstr "Projeleri, sorunları vb. arayın."
@@ -31605,18 +32290,12 @@ msgstr ""
msgid "Secret Detection"
msgstr ""
-msgid "Secret access key"
-msgstr ""
-
msgid "Secret token"
msgstr ""
msgid "Secure token that identifies an external storage request."
msgstr ""
-msgid "SecureCodeWarrior"
-msgstr ""
-
msgid "Security"
msgstr "Güvenlik"
@@ -31641,9 +32320,6 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "Security training with guide and learning pathways."
-msgstr ""
-
msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
@@ -31746,7 +32422,7 @@ msgstr ""
msgid "SecurityConfiguration|Manage corpus"
msgstr ""
-msgid "SecurityConfiguration|Manage corpus files used as mutation sources in coverage fuzzing."
+msgid "SecurityConfiguration|Manage corpus files used as seed inputs with coverage-guided fuzzing."
msgstr ""
msgid "SecurityConfiguration|Manage profiles for use by DAST scans."
@@ -31812,15 +32488,15 @@ msgstr ""
msgid "SecurityOrchestration|.yaml preview"
msgstr ""
-msgid "SecurityOrchestration|Action"
-msgstr ""
-
msgid "SecurityOrchestration|Actions"
msgstr ""
msgid "SecurityOrchestration|Add rule"
msgstr ""
+msgid "SecurityOrchestration|After dismissing the alert, the information will never be shown again."
+msgstr ""
+
msgid "SecurityOrchestration|All policies"
msgstr ""
@@ -31836,7 +32512,7 @@ msgstr ""
msgid "SecurityOrchestration|Description"
msgstr ""
-msgid "SecurityOrchestration|Disabled"
+msgid "SecurityOrchestration|Don't show the alert anymore"
msgstr ""
msgid "SecurityOrchestration|Edit policy"
@@ -31845,13 +32521,13 @@ msgstr ""
msgid "SecurityOrchestration|Edit policy project"
msgstr ""
-msgid "SecurityOrchestration|Enabled"
+msgid "SecurityOrchestration|Empty policy name"
msgstr ""
-msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Enabled"
msgstr ""
-msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
msgstr ""
msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
@@ -31860,7 +32536,7 @@ msgstr ""
msgid "SecurityOrchestration|Invalid policy type"
msgstr ""
-msgid "SecurityOrchestration|Latest scan"
+msgid "SecurityOrchestration|Latest scan run against %{agent}"
msgstr ""
msgid "SecurityOrchestration|Network"
@@ -31869,15 +32545,27 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No actions defined - policy will not run."
+msgstr ""
+
+msgid "SecurityOrchestration|No description"
+msgstr ""
+
msgid "SecurityOrchestration|No rules defined - policy will not run."
msgstr ""
+msgid "SecurityOrchestration|Not enabled"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
msgid "SecurityOrchestration|Policies"
msgstr ""
+msgid "SecurityOrchestration|Policy Type"
+msgstr ""
+
msgid "SecurityOrchestration|Policy cannot be enabled for non-existing branches (%{branches})"
msgstr ""
@@ -31902,10 +32590,13 @@ msgstr ""
msgid "SecurityOrchestration|Require %{approvals} %{plural} from %{approvers} if any of the following occur:"
msgstr ""
-msgid "SecurityOrchestration|Rule"
+msgid "SecurityOrchestration|Rules"
msgstr ""
-msgid "SecurityOrchestration|Rules"
+msgid "SecurityOrchestration|Runs %{actions} and %{lastAction} scans"
+msgstr ""
+
+msgid "SecurityOrchestration|Runs a %{action} scan"
msgstr ""
msgid "SecurityOrchestration|Scan Execution"
@@ -31965,6 +32656,9 @@ msgstr ""
msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
+msgid "SecurityOrchestration|This view only shows scan results for the agent %{agent}. You can view scan results for all agents in the %{linkStart}Operational Vulnerabilities tab of the vulnerability report%{linkEnd}."
+msgstr ""
+
msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
@@ -32019,9 +32713,6 @@ msgstr ""
msgid "SecurityOrchestration|users with ids"
msgstr ""
-msgid "SecurityOrchestration|view results"
-msgstr ""
-
msgid "SecurityOrchestration|vulnerabilities"
msgstr ""
@@ -32691,22 +33382,19 @@ msgstr "URL'yi kopyala"
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|In order to start using functions as a service, you must first install Knative on your Kubernetes cluster. %{linkStart}More information%{linkEnd}"
-msgstr ""
-
msgid "Serverless|Learn more about Serverless"
msgstr ""
msgid "Serverless|No functions available"
msgstr ""
-msgid "Serverless|Sign up for First Look"
+msgid "Serverless|Serverless was %{linkStart}deprecated%{linkEnd} in GitLab 14.3."
+msgstr ""
+
+msgid "Serverless|Serverless was %{postLinkStart}deprecated%{postLinkEnd}. But if you opt to use it, you must install Knative in your Kubernetes cluster first. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "Serverless|The deploy job has not finished."
@@ -32718,9 +33406,6 @@ 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 ""
@@ -32736,9 +33421,6 @@ msgstr ""
msgid "Service Account Key"
msgstr ""
-msgid "Service Accounts"
-msgstr ""
-
msgid "Service Accounts keys authorize GitLab to deploy your Google Cloud project"
msgstr ""
@@ -32748,10 +33430,10 @@ msgstr "Servis Masası"
msgid "Service Desk allows people to create issues in your GitLab instance without their own user account. It provides a unique email address for end users to create issues in a project. Replies can be sent either through the GitLab interface or by email. End users only see threads through email."
msgstr ""
-msgid "Service Usage Data"
+msgid "Service account generated successfully"
msgstr ""
-msgid "Service account generated successfully"
+msgid "Service accounts"
msgstr ""
msgid "Service ping is disabled in your configuration file, and cannot be enabled through this form."
@@ -32895,6 +33577,9 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
+msgid "Set the per-user rate limit for getting a user by ID via the API."
+msgstr ""
+
msgid "Set the per-user rate limit for notes created by web or API requests."
msgstr ""
@@ -33074,6 +33759,9 @@ msgstr ""
msgid "Shared runners details"
msgstr ""
+msgid "Shared runners enabled cannot be enabled until a valid credit card is on file"
+msgstr ""
+
msgid "Shared runners help link"
msgstr ""
@@ -33131,6 +33819,9 @@ msgstr ""
msgid "Show all issues."
msgstr ""
+msgid "Show all milestones"
+msgstr ""
+
msgid "Show all test cases."
msgstr ""
@@ -33167,6 +33858,9 @@ msgstr ""
msgid "Show file contents"
msgstr ""
+msgid "Show group milestones"
+msgstr ""
+
msgid "Show labels"
msgstr ""
@@ -33182,6 +33876,12 @@ msgstr ""
msgid "Show open epics"
msgstr ""
+msgid "Show project milestones"
+msgstr ""
+
+msgid "Show sub-group milestones"
+msgstr ""
+
msgid "Show the Closed list"
msgstr ""
@@ -33191,11 +33891,6 @@ msgstr ""
msgid "Show whitespace changes"
msgstr "Boşluk değişikliklerini göster"
-msgid "Showing %d event"
-msgid_plural "Showing %d events"
-msgstr[0] "%d etkinliği gösteriliyor"
-msgstr[1] "%d etkinlikleri gösteriliyor"
-
msgid "Showing %{conflict} between %{sourceBranch} and %{targetBranch}"
msgstr ""
@@ -33255,12 +33950,6 @@ msgstr "Durum yok"
msgid "Sidebar|None"
msgstr "Yok"
-msgid "Sidebar|Only numeral characters allowed"
-msgstr "Yalnızca sayısal karakterlere izin verilir"
-
-msgid "Sidebar|Weight"
-msgstr "Ağırlık"
-
msgid "Sidekiq job compression threshold (bytes)"
msgstr ""
@@ -33423,6 +34112,9 @@ msgstr ""
msgid "Slack logo"
msgstr ""
+msgid "SlackIntegration|Are you sure you want to remove this project from the Slack application?"
+msgstr ""
+
msgid "SlackIntegration|GitLab for Slack"
msgstr ""
@@ -33432,6 +34124,9 @@ msgstr ""
msgid "SlackIntegration|Project alias"
msgstr ""
+msgid "SlackIntegration|Remove project"
+msgstr ""
+
msgid "SlackIntegration|Select a GitLab project to link with your Slack workspace."
msgstr ""
@@ -33576,9 +34271,6 @@ msgstr ""
msgid "Something went wrong trying to load issue contacts."
msgstr ""
-msgid "Something went wrong when creating a work item. Please try again"
-msgstr ""
-
msgid "Something went wrong when reordering designs. Please try again"
msgstr ""
@@ -33672,9 +34364,6 @@ msgstr ""
msgid "Something went wrong while inserting your image. Please try again."
msgstr ""
-msgid "Something went wrong while merging this merge request. Please try again."
-msgstr ""
-
msgid "Something went wrong while obtaining the Let's Encrypt certificate."
msgstr ""
@@ -33996,10 +34685,10 @@ 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."
+msgid "SourcegraphAdmin|Learn more."
msgstr ""
-msgid "SourcegraphAdmin|More information"
+msgid "SourcegraphAdmin|Only public projects have code intelligence enabled and communicate with Sourcegraph."
msgstr ""
msgid "SourcegraphAdmin|Save changes"
@@ -34008,7 +34697,7 @@ msgstr "DeÄŸiÅŸiklikleri kaydet"
msgid "SourcegraphAdmin|Sourcegraph URL"
msgstr ""
-msgid "SourcegraphAdmin|e.g. https://sourcegraph.example.com"
+msgid "SourcegraphAdmin|https://sourcegraph.example.com"
msgstr ""
msgid "SourcegraphPreferences|This feature is experimental and currently limited to certain projects."
@@ -34143,6 +34832,9 @@ msgstr "Temizlemeye baÅŸla"
msgid "Start date"
msgstr "BaÅŸlama tarihi"
+msgid "Start free trial"
+msgstr ""
+
msgid "Start merge train"
msgstr ""
@@ -34173,6 +34865,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started escalation for this incident."
+msgstr ""
+
msgid "Starting..."
msgstr "Başlatılıyor..."
@@ -34185,6 +34880,9 @@ msgstr ""
msgid "Starts at (UTC)"
msgstr ""
+msgid "Starts escalations for this incident"
+msgstr ""
+
msgid "Starts on"
msgstr ""
@@ -34446,6 +35144,9 @@ msgstr "Bilinmeyen"
msgid "Strikethrough"
msgstr ""
+msgid "Strikethrough text"
+msgstr ""
+
msgid "Subgroup information"
msgstr ""
@@ -34680,6 +35381,21 @@ msgstr "Kullanım sayımı günde bir kez 12:00 ÖS yapılır."
msgid "Subscriptions"
msgstr ""
+msgid "Subscriptions|Chat with sales"
+msgstr ""
+
+msgid "Subscriptions|Close"
+msgstr ""
+
+msgid "Subscriptions|Not ready to buy yet?"
+msgstr ""
+
+msgid "Subscriptions|Start a free trial"
+msgstr ""
+
+msgid "Subscriptions|We understand. Maybe you have some questions for our sales team, or maybe you'd like to try some of the paid features first. What would you like to do?"
+msgstr ""
+
msgid "Subscription|Your subscription for %{strong}%{namespace_name}%{strong_close} has expired and you are now on %{pricing_link_start}the GitLab Free tier%{pricing_link_end}. Don't worry, your data is safe. Get in touch with our support team (%{support_email}). They'll gladly help with your subscription renewal."
msgstr ""
@@ -34890,6 +35606,9 @@ msgstr ""
msgid "SuperSonics|Maximum users"
msgstr ""
+msgid "SuperSonics|Offline cloud"
+msgstr ""
+
msgid "SuperSonics|Paste your activation code"
msgstr ""
@@ -34956,6 +35675,12 @@ msgstr ""
msgid "SuperSonics|You do not have an active subscription"
msgstr ""
+msgid "SuperSonics|You have a future dated license"
+msgstr ""
+
+msgid "SuperSonics|You have added a license that activates on %{date}. Please see the subscription history table below for more details."
+msgstr ""
+
msgid "SuperSonics|You have successfully added a license that activates on %{date}. Please see the subscription history table below for more details."
msgstr ""
@@ -35115,6 +35840,9 @@ msgstr ""
msgid "Tag name is required"
msgstr ""
+msgid "Tag push"
+msgstr ""
+
msgid "Tag push events"
msgstr ""
@@ -35217,6 +35945,9 @@ msgstr "Sürüm notlarınızı yazın veya dosyaları buraya sürükleyin…"
msgid "TagsPage|protected"
msgstr "korumalı"
+msgid "Take a look at the documentation to discover all of GitLab’s capabilities."
+msgstr ""
+
msgid "Target Branch"
msgstr "Hedef Dal"
@@ -35619,6 +36350,9 @@ msgstr ""
msgid "Tests"
msgstr ""
+msgid "Text (optional)"
+msgstr ""
+
msgid "Text added to the body of all email messages. %{character_limit} character limit"
msgstr ""
@@ -35669,6 +36403,9 @@ msgstr ""
msgid "The CSV export will be created in the background. Once finished, it will be sent to %{email} in an attachment."
msgstr ""
+msgid "The CSV export you requested of all user memberships is attached to this email."
+msgstr ""
+
msgid "The GitLab subscription service (customers.gitlab.com) is currently experiencing an outage. You can monitor the status and get updates at %{linkStart}status.gitlab.com%{linkEnd}."
msgstr ""
@@ -35744,6 +36481,9 @@ 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 epic"
+msgstr ""
+
msgid "The current issue"
msgstr ""
@@ -35905,6 +36645,9 @@ msgstr ""
msgid "The latest pipeline for this merge request has failed."
msgstr ""
+msgid "The license key is invalid."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -35920,6 +36663,9 @@ msgstr ""
msgid "The license was successfully uploaded and will be active from %{starts_at}. You can see the details below."
msgstr ""
+msgid "The license you uploaded is invalid. If the issue persists, contact support at %{link}."
+msgstr ""
+
msgid "The list creation wizard is already open"
msgstr ""
@@ -36541,10 +37287,13 @@ msgstr "Bu işlem veri kaybına yol açabilir. Yanlışlıkla yapılacak işleml
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} and everything this project contains. %{strongOpen}There is no going back%{strongClose}"
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}on %{date}%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains."
+msgstr ""
+
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains. %{strongOpen}There is no going back.%{strongClose}"
msgstr ""
msgid "This action will %{strongOpen}permanently remove%{strongClose} %{codeOpen}%{group}%{codeClose} %{strongOpen}immediately%{strongClose}."
@@ -36673,9 +37422,6 @@ msgstr ""
msgid "This file was modified for readability, and can't accept suggestions. Edit it directly."
msgstr ""
-msgid "This forked project has the following:"
-msgstr ""
-
msgid "This form is disabled in preview"
msgstr ""
@@ -36688,7 +37434,7 @@ msgstr ""
msgid "This group can't be removed because it is linked to a subscription. To remove this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
-msgid "This group can't be transfered because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
+msgid "This group can't be transferred because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
msgid "This group cannot be invited to a project inside a group with enforced SSO"
@@ -36715,6 +37461,9 @@ 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 incident is already escalated with '%{escalation_policy_name}'."
+msgstr ""
+
msgid "This invitation was sent to %{mail_to_invite_email}, but you are signed in as %{link_to_current_user} with email %{mail_to_current_user}."
msgstr ""
@@ -36733,9 +37482,6 @@ 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ı sonlandırın."
-msgid "This is a merge train pipeline"
-msgstr ""
-
msgid "This is a private email address %{helpIcon} generated just for you. Anyone who has it can create issues or merge requests as if they were you. If that happens, %{resetLinkStart}reset this token%{resetLinkEnd}."
msgstr ""
@@ -36757,6 +37503,12 @@ msgstr ""
msgid "This is your current session"
msgstr "Bu sizin mevcut oturumunuz"
+msgid "This issue cannot be assigned to a confidential epic because it is public."
+msgstr ""
+
+msgid "This issue cannot be made public because it belongs to a confidential epic."
+msgstr ""
+
msgid "This issue is confidential and should only be visible to team members with at least Reporter access."
msgstr ""
@@ -36874,6 +37626,9 @@ msgstr ""
msgid "This means you can not push code until you create an empty repository or import existing one."
msgstr "Bu, boş bir havuz oluşturmadan veya mevcut olanı içe aktarmadan kodu zorlayamazsınız anlamına gelir."
+msgid "This merge request branch is protected from force push."
+msgstr ""
+
msgid "This merge request cannot be rebased while there are conflicts."
msgstr ""
@@ -36925,9 +37680,15 @@ msgstr ""
msgid "This pipeline was triggered by a schedule."
msgstr ""
+msgid "This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project"
msgstr "Bu proje"
+msgid "This project can be restored until %{date}."
+msgstr ""
+
msgid "This project cannot be %{visibilityLevel} because the visibility of %{openShowLink}%{name}%{closeShowLink} is %{visibility}. To make this project %{visibilityLevel}, you must first %{openEditLink}change the visibility%{closeEditLink} of the parent group."
msgstr ""
@@ -36946,6 +37707,9 @@ msgstr ""
msgid "This project is %{strongStart}NOT%{strongEnd} a fork, and has the following:"
msgstr ""
+msgid "This project is %{strongStart}NOT%{strongEnd} a fork. This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -37637,6 +38401,9 @@ msgstr "Yapılacaklar öğesi başarıyla bitti olarak işaretlendi."
msgid "Today"
msgstr "Bugün"
+msgid "Todos count"
+msgstr ""
+
msgid "Todos|Are you looking for things to do? Take a look at %{strongStart}%{openIssuesLinkStart}open issues%{openIssuesLinkEnd}%{strongEnd}, contribute to %{strongStart}%{mergeRequestLinkStart}a merge request%{mergeRequestLinkEnd}%{mergeRequestLinkEnd}%{strongEnd}, or mention someone in a comment to automatically assign them a new to-do item."
msgstr ""
@@ -37910,10 +38677,8 @@ msgstr ""
msgid "Trending"
msgstr "Öne Çıkanlar"
-msgid "Trials|%{planName} Trial %{enDash} %{num} day left"
-msgid_plural "Trials|%{planName} Trial %{enDash} %{num} days left"
-msgstr[0] ""
-msgstr[1] ""
+msgid "Trials|%{planName} Trial"
+msgstr ""
msgid "Trials|Compare all plans"
msgstr ""
@@ -37921,6 +38686,9 @@ msgstr ""
msgid "Trials|Create a new group to start your GitLab Ultimate trial."
msgstr ""
+msgid "Trials|Day %{daysUsed}/%{duration}"
+msgstr ""
+
msgid "Trials|Go back to GitLab"
msgstr ""
@@ -38170,7 +38938,7 @@ msgstr ""
msgid "URL is triggered when repository is updated"
msgstr ""
-msgid "URL must be percent-encoded if neccessary."
+msgid "URL must be percent-encoded if necessary."
msgstr ""
msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
@@ -38389,6 +39157,9 @@ msgstr "Kilidi aç"
msgid "Unlock account"
msgstr ""
+msgid "Unlock more features with GitLab Ultimate"
+msgstr ""
+
msgid "Unlock the discussion"
msgstr "Tartışmanın kilidini aç"
@@ -38452,6 +39223,9 @@ msgstr ""
msgid "Unsubscribes from this %{quick_action_target}."
msgstr ""
+msgid "Unsupported sort value."
+msgstr ""
+
msgid "Unsupported todo type passed. Supported todo types are: %{todo_types}"
msgstr ""
@@ -38680,6 +39454,9 @@ msgstr "Mevcut dönem kullanımı"
msgid "UsageQuota|File attachments and smaller design graphics."
msgstr ""
+msgid "UsageQuota|From %{storage_enforcement_date} storage limits will apply to this namespace. View and manage your usage in %{strong_start}Group Settings &gt; Usage quotas%{strong_end}."
+msgstr ""
+
msgid "UsageQuota|Git repository."
msgstr ""
@@ -38740,6 +39517,9 @@ msgstr "Depolama"
msgid "UsageQuota|Storage type"
msgstr ""
+msgid "UsageQuota|Storage used"
+msgstr ""
+
msgid "UsageQuota|This is the total amount of storage used across your projects within this namespace."
msgstr ""
@@ -38935,6 +39715,12 @@ msgstr ""
msgid "Use hashed storage paths for newly created and renamed repositories. Always enabled since 13.0."
msgstr ""
+msgid "Use issue count"
+msgstr ""
+
+msgid "Use issue weight"
+msgstr ""
+
msgid "Use one line per URI"
msgstr ""
@@ -39316,6 +40102,9 @@ msgstr ""
msgid "Users"
msgstr "Kullanıcılar"
+msgid "Users API rate limit"
+msgstr ""
+
msgid "Users can launch a development environment from a GitLab browser tab when the %{linkStart}Gitpod%{linkEnd} integration is enabled."
msgstr ""
@@ -39641,6 +40430,9 @@ msgstr ""
msgid "View group labels"
msgstr "Grup etiketlerini görüntüle"
+msgid "View group pipeline usage quota"
+msgstr ""
+
msgid "View incident details at"
msgstr ""
@@ -39793,6 +40585,9 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
+msgid "Vulnerability"
+msgstr ""
+
msgid "Vulnerability Report"
msgstr ""
@@ -39844,6 +40639,9 @@ msgstr ""
msgid "VulnerabilityManagement|An unverified non-confirmed finding"
msgstr ""
+msgid "VulnerabilityManagement|At least one identifier is required"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -39853,12 +40651,24 @@ msgstr ""
msgid "VulnerabilityManagement|Create Jira issue"
msgstr ""
+msgid "VulnerabilityManagement|Enter a name"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE code"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE identifier URL"
+msgstr ""
+
msgid "VulnerabilityManagement|Fetching linked Jira issues"
msgstr ""
msgid "VulnerabilityManagement|Manually add a vulnerability entry into the vulnerability report."
msgstr ""
+msgid "VulnerabilityManagement|Name is a required field"
+msgstr ""
+
msgid "VulnerabilityManagement|Needs triage"
msgstr ""
@@ -39874,6 +40684,18 @@ msgstr ""
msgid "VulnerabilityManagement|Select a method"
msgstr ""
+msgid "VulnerabilityManagement|Select a severity level"
+msgstr ""
+
+msgid "VulnerabilityManagement|Select a status"
+msgstr ""
+
+msgid "VulnerabilityManagement|Severity is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Something went wrong while creating vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -39898,6 +40720,12 @@ msgstr ""
msgid "VulnerabilityManagement|Something went wrong, could not update vulnerability state."
msgstr ""
+msgid "VulnerabilityManagement|Status is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Submit vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Summary, detailed description, steps to reproduce, etc."
msgstr ""
@@ -40093,6 +40921,9 @@ msgstr ""
msgid "WARNING:"
msgstr "UYARI:"
+msgid "WARNING: This snippet contains hidden files which might be used to mask malicious behavior. Exercise caution if cloning and executing code from this snippet."
+msgstr ""
+
msgid "Wait for the file to load to copy its contents"
msgstr ""
@@ -40312,6 +41143,15 @@ msgstr ""
msgid "Webhooks|An issue is created, updated, closed, or reopened."
msgstr ""
+msgid "Webhooks|Are you sure you want to delete this group hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this project hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this webhook?"
+msgstr ""
+
msgid "Webhooks|Comments"
msgstr ""
@@ -40321,6 +41161,9 @@ msgstr ""
msgid "Webhooks|Confidential issues events"
msgstr ""
+msgid "Webhooks|Delete webhook"
+msgstr ""
+
msgid "Webhooks|Deployment events"
msgstr ""
@@ -40554,6 +41397,9 @@ msgstr ""
msgid "Wiki"
msgstr "Viki"
+msgid "Wiki page"
+msgstr ""
+
msgid "Wiki page was successfully created."
msgstr ""
@@ -40659,7 +41505,7 @@ msgstr "%{pageTitle} sayfası silinsin mi?"
msgid "WikiPageConflictMessage|Someone edited the page the same time you did. Please check out %{wikiLinkStart}the page%{wikiLinkEnd} and make sure your changes will not unintentionally remove theirs."
msgstr ""
-msgid "WikiPage|An error occured while trying to render the content editor. Please try again later."
+msgid "WikiPage|An error occurred while trying to render the content editor. Please try again later."
msgstr ""
msgid "WikiPage|Are you sure you want to switch back to the classic editor?"
@@ -40818,6 +41664,18 @@ msgstr ""
msgid "WorkItem|New Task"
msgstr ""
+msgid "WorkItem|Something went wrong when creating a work item. Please try again"
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching the work item. Please try again."
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching work item types. Please try again"
+msgstr ""
+
+msgid "WorkItem|Type"
+msgstr ""
+
msgid "WorkItem|Work Items"
msgstr ""
@@ -40884,7 +41742,10 @@ msgstr ""
msgid "You are about to add %{usersTag} people to the discussion. They will all receive a notification."
msgstr ""
-msgid "You are about to permanently delete this project"
+msgid "You are about to delete this forked project containing:"
+msgstr ""
+
+msgid "You are about to delete this project containing:"
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."
@@ -40905,6 +41766,9 @@ msgstr ""
msgid "You are attempting to update a file that has changed since you started editing it."
msgstr ""
+msgid "You are billed if you exceed this number. %{qsrOverageLinkStart}How does billing work?%{qsrOverageLinkEnd}"
+msgstr ""
+
msgid "You are connected to the Prometheus server, but there is currently no data to display."
msgstr ""
@@ -40962,6 +41826,9 @@ msgstr ""
msgid "You are not authorized to update this scanner profile"
msgstr ""
+msgid "You are not authorized to upload metric images"
+msgstr ""
+
msgid "You are now impersonating %{username}"
msgstr ""
@@ -41115,9 +41982,6 @@ msgstr ""
msgid "You can only upload one design when dropping onto an existing design."
msgstr ""
-msgid "You can recover this project until %{date}"
-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 ""
@@ -41166,9 +42030,6 @@ msgstr ""
msgid "You cannot write to this read-only GitLab instance."
msgstr "Bu salt okunur GitLab örneğine yazamazsınız."
-msgid "You can’t %{tag_start}edit%{tag_end} files directly in this project. Fork this project and submit a merge request with your changes."
-msgstr ""
-
msgid "You can’t edit files directly in this project. Fork this project and submit a merge request with your changes."
msgstr ""
@@ -41321,9 +42182,6 @@ msgstr "Ä°zinleriniz yok"
msgid "You have not added any approvers. Start by adding users or groups."
msgstr ""
-msgid "You have reached your project limit"
-msgstr "Proje sınırınıza ulaştınız"
-
msgid "You have set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
@@ -41354,12 +42212,6 @@ msgstr ""
msgid "You must have maintainer access to force delete a lock"
msgstr "Bir kilidi silmeye zorlamak için sorumlu erişiminiz olmalıdır"
-msgid "You must have permission to create a project in a group before forking."
-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 "Geçerli bir mevcut şifre girmelisiniz"
@@ -41765,7 +42617,7 @@ msgstr "Projeleriniz"
msgid "Your public email will be displayed on your public profile."
msgstr ""
-msgid "Your request for access could not be processed: %{error_meesage}"
+msgid "Your request for access could not be processed: %{error_message}"
msgstr ""
msgid "Your request for access has been queued for review."
@@ -41948,6 +42800,9 @@ msgstr "arÅŸivlenmiÅŸ"
msgid "archived:"
msgstr ""
+msgid "artifacts"
+msgstr ""
+
msgid "assign yourself"
msgstr "kendinizi atayın"
@@ -41977,6 +42832,9 @@ msgstr[1] ""
msgid "branch name"
msgstr "dal adı"
+msgid "builds"
+msgstr ""
+
msgid "by"
msgstr "tarafından"
@@ -42400,6 +43258,9 @@ msgstr ""
msgid "contact with same email already exists in group hierarchy"
msgstr ""
+msgid "container registry images"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -42439,6 +43300,9 @@ msgstr ""
msgid "data"
msgstr ""
+msgid "database"
+msgstr ""
+
msgid "date must not be after 9999-12-31"
msgstr ""
@@ -42462,9 +43326,6 @@ msgstr "dağıt"
msgid "design"
msgstr ""
-msgid "detached"
-msgstr ""
-
msgid "disabled"
msgstr "devre dışı"
@@ -42713,7 +43574,7 @@ msgstr ""
msgid "is not a valid X509 certificate."
msgstr ""
-msgid "is not allowed for sign-up."
+msgid "is not allowed for sign-up. Please use your regular email address."
msgstr ""
msgid "is not allowed for this group."
@@ -42725,7 +43586,7 @@ msgstr ""
msgid "is not allowed since the group is not top-level group."
msgstr ""
-msgid "is not allowed."
+msgid "is not allowed. Please use your regular email address."
msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
@@ -42812,6 +43673,9 @@ msgstr "1 dakikadan az"
msgid "level: %{level}"
msgstr ""
+msgid "lfs objects"
+msgstr ""
+
msgid "limit of %{project_limit} reached"
msgstr ""
@@ -43031,6 +43895,9 @@ msgstr ""
msgid "mrWidget|Merge blocked: pipeline must succeed. It's waiting for a manual action to continue."
msgstr ""
+msgid "mrWidget|Merge blocked: pipeline must succeed. Push a commit that fixes the failure, or %{linkStart}learn about other solutions.%{linkEnd}"
+msgstr ""
+
msgid "mrWidget|Merge blocked: this merge request must be approved."
msgstr ""
@@ -43148,9 +44015,6 @@ msgstr ""
msgid "mrWidget|The changes were not merged into"
msgstr ""
-msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr "Kaynak dal silindi"
@@ -43298,9 +44162,6 @@ msgstr ""
msgid "open issue"
msgstr ""
-msgid "opened %{timeAgo}"
-msgstr "%{timeAgo} açıldı"
-
msgid "or"
msgstr "veya"
@@ -43312,6 +44173,12 @@ msgid_plural "out of %d total tests"
msgstr[0] ""
msgstr[1] ""
+msgid "packages"
+msgstr ""
+
+msgid "pages"
+msgstr ""
+
msgid "parent"
msgid_plural "parents"
msgstr[0] "ebeveyn"
@@ -43461,6 +44328,9 @@ msgid_plural "replies"
msgstr[0] "cevap"
msgstr[1] "cevap"
+msgid "repositories"
+msgstr ""
+
msgid "repository:"
msgstr ""
@@ -43581,12 +44451,18 @@ msgstr ""
msgid "tag name"
msgstr "etiket adı"
+msgid "terraform states"
+msgstr ""
+
msgid "the correct format."
msgstr ""
msgid "the file"
msgstr ""
+msgid "the following epic(s)"
+msgstr ""
+
msgid "the following issue(s)"
msgstr ""
@@ -43599,21 +44475,12 @@ msgstr ""
msgid "this document"
msgstr "bu belge"
-msgid "this issue cannot be assigned to a confidential epic since it is public"
-msgstr ""
-
-msgid "this issue cannot be made public since it belongs to a confidential epic"
-msgstr ""
-
msgid "time summary"
msgstr ""
msgid "toggle collapse"
msgstr "daraltmayı aç/kapat"
-msgid "train"
-msgstr ""
-
msgid "triggered"
msgstr "tetiklendi"
@@ -43742,3 +44609,6 @@ msgstr ""
msgid "{project}"
msgstr ""
+msgid "✔"
+msgstr ""
+
diff --git a/locale/uk/gitlab.po b/locale/uk/gitlab.po
index f7980b193c8..b714ffb61e0 100644
--- a/locale/uk/gitlab.po
+++ b/locale/uk/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: uk\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2022-02-02 15:42\n"
+"PO-Revision-Date: 2022-03-01 20:36\n"
msgid " %{start} to %{end}"
msgstr " %{start} до %{end}"
@@ -78,17 +78,17 @@ msgstr "#загальне, #розробка"
msgid "%d Alert"
msgid_plural "%d Alerts"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-msgstr[3] ""
+msgstr[0] "%d ПопередженнÑ"
+msgstr[1] "%d ПопередженнÑ"
+msgstr[2] "%d Попереджень"
+msgstr[3] "%d Попереджень"
msgid "%d Alert:"
msgid_plural "%d Alerts:"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-msgstr[3] ""
+msgstr[0] "%d ПопередженнÑ:"
+msgstr[1] "%d Попереджень:"
+msgstr[2] "%d Попереджень:"
+msgstr[3] "%d Попереджень:"
msgid "%d Approval"
msgid_plural "%d Approvals"
@@ -174,6 +174,13 @@ msgstr[1] "%d затверджуючі оÑоби (ви затвердили)"
msgstr[2] "%d затверджуючих оÑіб (ви затвердили)"
msgstr[3] "%d затверджуючих оÑіб (ви затвердили)"
+msgid "%d assigned issue"
+msgid_plural "%d assigned issues"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] "%d змінений файл"
@@ -449,10 +456,10 @@ msgstr[3] "%d відкритих задач"
msgid "%d pending comment"
msgid_plural "%d pending comments"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-msgstr[3] ""
+msgstr[0] "%d коментар в очікуванні"
+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."
@@ -559,12 +566,33 @@ msgstr[1] "%d вразливоÑÑ‚Ñ– відхилено"
msgstr[2] "%d вразливоÑтей відхилено"
msgstr[3] "%d вразливоÑтей відхилено"
-msgid "%d vulnerability updated"
-msgid_plural "%d vulnerabilities updated"
-msgstr[0] "%d вразливіÑÑ‚ÑŒ оновлено"
-msgstr[1] "%d вразливоÑÑ‚Ñ– оновлено"
-msgstr[2] "%d вразливоÑтей оновлено"
-msgstr[3] "%d вразливоÑтей оновлено"
+msgid "%d vulnerability set to confirmed"
+msgid_plural "%d vulnerabilities set to confirmed"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
+msgid "%d vulnerability set to dismissed"
+msgid_plural "%d vulnerabilities set to dismissed"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
+msgid "%d vulnerability set to needs triage"
+msgid_plural "%d vulnerabilities set to needs triage"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
+msgid "%d vulnerability set to resolved"
+msgid_plural "%d vulnerabilities set to resolved"
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
msgid "%d warning found:"
msgid_plural "%d warnings found:"
@@ -593,7 +621,7 @@ msgid "%{address} is an invalid IP address range"
msgstr "%{address} - недійÑний діапазон IP-адреÑ"
msgid "%{anchorOpen}Learn more%{anchorClose} about how you can customize / disable registration on your instance."
-msgstr "%{anchorOpen}ДізнайтеÑÑ Ð±Ñ–Ð»ÑŒÑˆÐµ%{anchorClose} про те, Ñк Ви можете налаштувати / вимкнути реєÑтрацію у Ñвоєму екземплÑрі."
+msgstr "%{anchorOpen}ДізнайтеÑÑ Ð±Ñ–Ð»ÑŒÑˆÐµ%{anchorClose} про те, Ñк Ви можете налаштувати / вимкнути реєÑтрацію у Ñвоєму інÑтанÑÑ–."
msgid "%{author_link} cloned %{original_issue} to %{new_issue}."
msgstr "%{author_link} клонув(-ла) %{original_issue} до %{new_issue}."
@@ -632,10 +660,10 @@ msgstr[2] ""
msgstr[3] ""
msgid "%{codeStart}type%{codeEnd} is deprecated and will be removed in 15.0. Use %{codeStart}stage%{codeEnd} instead. %{linkStart}Learn More %{linkEnd}"
-msgstr ""
+msgstr "%{codeStart}тип%{codeEnd} Ñ” заÑтарілим Ñ– буде видалений в 15.0. ÐатоміÑÑ‚ÑŒ викориÑтовуйте %{codeStart} етап%{codeEnd}. %{linkStart}ДізнатиÑÑ Ð±Ñ–Ð»ÑŒÑˆÐµ %{linkEnd}"
msgid "%{codeStart}types%{codeEnd} is deprecated and will be removed in 15.0. Use %{codeStart}stages%{codeEnd} instead. %{linkStart}Learn More %{linkEnd}"
-msgstr ""
+msgstr "%{codeStart}типи%{codeEnd} Ñ” заÑтарілими та будуть видалені в 15.0. ÐатоміÑÑ‚ÑŒ викориÑтовуйте %{codeStart}Ñтадії%{codeEnd}. %{linkStart}ДізнатиÑÑ Ð±Ñ–Ð»ÑŒÑˆÐµ %{linkEnd}"
msgid "%{code_open}Masked:%{code_close} Hidden in job logs. Must match masking requirements."
msgstr "%{code_open}ЗамаÑковано:%{code_close} Сховано в журналах завдань. Повинні відповідати вимогам до маÑкуваннÑ."
@@ -662,6 +690,12 @@ msgstr[3] "%{completedCount} з %{count} завдань завершено"
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr "%{completedWeight} з %{totalWeight} ваги виконано"
+msgid "%{completed} of %{total} issues closed"
+msgstr ""
+
+msgid "%{completed} of %{total} weight completed"
+msgstr ""
+
msgid "%{cores} cores"
msgstr "%{cores} Ñдер"
@@ -752,7 +786,7 @@ msgid "%{description}- Sentry event: %{errorUrl}- First seen: %{firstSeen}- Last
msgstr "%{description}- Ð¿Ð¾Ð´Ñ–Ñ Ñƒ Sentry: %{errorUrl}- Вперше помічено: %{firstSeen}- ВоÑтаннє помічено: %{lastSeen} %{countLabel}: %{count}%{userCountLabel}: %{userCount}"
msgid "%{doc_link_start}Advanced search%{doc_link_end} is disabled since %{ref_elem} is not the default branch. %{docs_link}"
-msgstr ""
+msgstr "%{doc_link_start}Розширений пошук%{doc_link_end} вимкнено, оÑкільки %{ref_elem} не Ñ” гілкою за замовчуваннÑм. %{docs_link}"
msgid "%{doc_link_start}Advanced search%{doc_link_end} is enabled."
msgstr "%{doc_link_start}Розширений пошук%{doc_link_end} увімкнено."
@@ -800,7 +834,7 @@ msgid "%{firstMilestoneName} + %{numberOfOtherMilestones} more"
msgstr "%{firstMilestoneName} + %{numberOfOtherMilestones} більше"
msgid "%{gitlab_experience_text}. Don't worry, this information isn't shared outside of your self-managed GitLab instance."
-msgstr "%{gitlab_experience_text}. Ðе хвилюйтеÑÑ, Ñ†Ñ Ñ–Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ Ð½Ðµ поширюєтьÑÑ Ð¿Ð¾Ð·Ð° вашим екземплÑром GitLab."
+msgstr "%{gitlab_experience_text}. Ðе хвилюйтеÑÑ, Ñ†Ñ Ñ–Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ Ð½Ðµ поширюєтьÑÑ Ð¿Ð¾Ð·Ð° вашим інÑтанÑом GitLab."
msgid "%{gitlab_experience_text}. We won't share this information with anyone."
msgstr "%{gitlab_experience_text}. Ми не ділитимемоÑÑ Ñ†Ð¸Ð¼Ð¸ даними ні з ким."
@@ -815,7 +849,7 @@ msgid "%{group_name} group members"
msgstr "кориÑтувачі групи %{group_name}"
msgid "%{group_name} is approaching the limit of available seats"
-msgstr ""
+msgstr "%{group_name} наближаєтьÑÑ Ð´Ð¾ Ð¾Ð±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ Ð²Ñ–Ð»ÑŒÐ½Ð¸Ñ… міÑць"
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}."
@@ -914,7 +948,7 @@ msgid "%{level_name} is not allowed since the fork source project has lower visi
msgstr "%{level_name} не допуÑкаєтьÑÑ, оÑкільки проєкт-джерело цього форку має нижчу видиміÑÑ‚ÑŒ."
msgid "%{linkStart}Learn more.%{linkEnd}"
-msgstr ""
+msgstr "%{linkStart}Докладніше:%{linkEnd}"
msgid "%{link_start}Learn more%{link_end} about roles."
msgstr "%{link_start}ДовідайтеÑÑŒ більше%{link_end} про ролі."
@@ -923,10 +957,10 @@ msgid "%{link_start}Remove the %{draft_snippet} prefix%{link_end} from the title
msgstr "%{link_start}Видаліть %{draft_snippet} префікÑ%{link_end} з назви , щоб зробити можливим Ð·Ð»Ð¸Ñ‚Ñ‚Ñ Ñ†ÑŒÐ¾Ð³Ð¾ запиту, коли він буде готовий."
msgid "%{link_start}Start the title with %{draft_snippet}%{link_end} to prevent a merge request draft from merging before it's ready."
-msgstr ""
+msgstr "%{link_start}Почніть заголовок з %{draft_snippet}%{link_end}, щоб запобігти злиттю чернетки запиту на злиттÑ, перш ніж він буде готовий."
msgid "%{link_start}Upload a license%{link_end} file or enter the license key you have received from GitLab Inc."
-msgstr ""
+msgstr "%{link_start}Завантажте ліцензійний файл%{link_end} або введіть ліцензійний ключ, Ñкий ви отримали від GitLab Inc."
msgid "%{link_start}What information does GitLab Inc. collect?%{link_end}"
msgstr "%{link_start}Яку інформацію збирає ÐºÐ¾Ð¼Ð¿Ð°Ð½Ñ–Ñ GitLab Inc.?%{link_end}"
@@ -980,7 +1014,7 @@ msgid "%{name} is already being used for another emoji"
msgstr "%{name} вже викориÑтовуєтьÑÑ Ð´Ð»Ñ Ñ–Ð½ÑˆÐ¾Ð³Ð¾ емодзі"
msgid "%{name} is reserved for %{type} report type"
-msgstr ""
+msgstr "%{name} зарезервовано на %{type} тип звіту"
msgid "%{name} is scheduled for %{action}"
msgstr "%{name} заплановано на %{action}"
@@ -1022,6 +1056,9 @@ msgstr "%{openedEpics} відкрито, %{closedEpics} закрито"
msgid "%{openedIssues} open, %{closedIssues} closed"
msgstr "%{openedIssues} відкрито, %{closedIssues} закрито"
+msgid "%{percentage}%% issues closed"
+msgstr ""
+
msgid "%{percentage}%% weight completed"
msgstr "%{percentage}%% вага завершено"
@@ -1038,10 +1075,10 @@ msgid "%{placeholder} is not a valid theme"
msgstr "%{placeholder} не є коректною темою"
msgid "%{policy_link} (notifying after %{elapsed_time} minutes unless %{status})"
-msgstr ""
+msgstr "%{policy_link} (Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ñ‡ÐµÑ€ÐµÐ· %{elapsed_time} хвилин(у), Ñкщо %{status})"
msgid "%{project_path} is a project that you can use to add a README to your GitLab profile. Create a public project and initialize the repository with a README to get started. %{help_link_start}Learn more.%{help_link_end}"
-msgstr ""
+msgstr "%{project_path} - це проєкт, Ñкий ви можете викориÑтати Ð´Ð»Ñ Ð´Ð¾Ð´Ð°Ð²Ð°Ð½Ð½Ñ README у ваш профіль GitLab. Створіть публічний проєкт та ініціалізуйте репозиторій за допомогою README, щоб почати. %{help_link_start}ДізнатиÑÑ Ð±Ñ–Ð»ÑŒÑˆÐµ.%{help_link_end}"
msgid "%{ref} cannot be added: %{error}"
msgstr "%{ref} неможливо додати: %{error}"
@@ -1072,10 +1109,10 @@ msgid "%{rotation} has been recalculated with the remaining participants. Please
msgstr ""
msgid "%{rotation} has been recalculated with the remaining participants. Please review the new setup for %{rotation}. It is recommended that you reach out to the current on-call responder to ensure continuity of on-call coverage."
-msgstr ""
+msgstr "%{rotation} було перераховано з іншими учаÑниками. Будь лаÑка, переглÑньте нове Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð´Ð»Ñ %{rotation}. РекомендуєтьÑÑ Ð·Ð²â€™ÑзатиÑÑ Ð· поточним відповідачем на виклик, щоб забезпечити безперервне Ð¿Ð¾ÐºÑ€Ð¸Ñ‚Ñ‚Ñ Ð²Ð¸ÐºÐ»Ð¸ÐºÑƒ."
msgid "%{runner} created %{timeago}"
-msgstr ""
+msgstr "%{runner} Ñтворено %{timeago}"
msgid "%{scope} results for term '%{term}'"
msgstr "%{scope} результати Ð´Ð»Ñ Ñ‚ÐµÑ€Ð¼Ñ–Ð½Ñƒ \"%{term}\""
@@ -1246,7 +1283,7 @@ msgid "%{total} warnings found: showing first %{warningsDisplayed}"
msgstr "%{total}знайдено Ð¿Ð¾Ð¿ÐµÑ€ÐµÐ´Ð¶ÐµÐ½Ð½Ñ : показано перше%{warningsDisplayed}"
msgid "%{type} only supports %{name} name"
-msgstr ""
+msgstr "%{type} підтримує лише %{name} ім'Ñ"
msgid "%{userName} (cannot merge)"
msgstr "%{userName} (не може виконувати злиттÑ)"
@@ -1258,10 +1295,10 @@ msgid "%{user_name} (%{user_username}) was removed from %{rotation} in %{schedul
msgstr "%{user_name} (%{user_username}) було видалено з %{rotation} в %{schedule} в %{project}. "
msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project_link}: "
-msgstr ""
+msgstr "%{user_name}%{user_username} було видалено з таких політик еÑкалації в%{project_link}: "
msgid "%{user_name} (%{user_username}) was removed from the following escalation policies in %{project}:"
-msgstr ""
+msgstr "%{user_name}%{user_username} було видалено з таких політик еÑкалації в %{project}:"
msgid "%{user_name} profile page"
msgstr "%{user_name} Ñторінка профілю"
@@ -1294,7 +1331,7 @@ msgid "%{verb} %{time_spent_value} spent time."
msgstr "%{verb} %{time_spent_value} витрачено чаÑу."
msgid "%{webhooks_link_start}%{webhook_type}%{link_end} enable you to send notifications to web applications in response to events in a group or project."
-msgstr ""
+msgstr "%{webhooks_link_start}%{webhook_type}%{link_end} надає можливіÑÑ‚ÑŒ надÑилати ÑÐ¿Ð¾Ð²Ñ–Ñ‰ÐµÐ½Ð½Ñ Ð½Ð° веб-заÑтоÑунки у відповідь на події у групі або в проєкті."
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 ""
@@ -1456,7 +1493,7 @@ msgid ", or "
msgstr ", або "
msgid "- %{policy_name} (notifying after %{elapsed_time} minutes unless %{status})"
-msgstr ""
+msgstr "- %{policy_name} (Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ñ‡ÐµÑ€ÐµÐ· %{elapsed_time} хвилин(у), Ñкщо не %{status})"
msgid "- Available to run jobs."
msgstr "- ДоÑтупний Ð´Ð»Ñ Ð·Ð°Ð¿ÑƒÑку завдань."
@@ -1481,6 +1518,9 @@ msgstr[1] "- КориÑтувачі"
msgstr[2] "- КориÑтувачів"
msgstr[3] "- КориÑтувачів"
+msgid "- of - issues closed"
+msgstr ""
+
msgid "- of - weight completed"
msgstr "- з - ваги виконано"
@@ -1543,17 +1583,17 @@ msgstr[3] "ЗалишилоÑÑ %d днів"
msgid "1 day selected"
msgid_plural "%d days selected"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-msgstr[3] ""
+msgstr[0] "1 день обрано"
+msgstr[1] "%d дні обрано"
+msgstr[2] "%d днів обрано"
+msgstr[3] "%d днів обрано"
msgid "1 deploy key"
msgid_plural "%d deploy keys"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-msgstr[3] ""
+msgstr[0] "1 ключ Ð´Ð»Ñ Ñ€Ð¾Ð·Ð³Ð¾Ñ€Ñ‚Ð°Ð½Ð½Ñ"
+msgstr[1] "%d ключі Ð´Ð»Ñ Ñ€Ð¾Ð·Ð³Ð¾Ñ€Ñ‚Ð°Ð½Ð½Ñ"
+msgstr[2] "%d ключів Ð´Ð»Ñ Ñ€Ð¾Ð·Ð³Ð¾Ñ€Ñ‚Ð°Ð½Ð½Ñ"
+msgstr[3] "%d ключів Ð´Ð»Ñ Ñ€Ð¾Ð·Ð³Ð¾Ñ€Ñ‚Ð°Ð½Ð½Ñ"
msgid "1 follower"
msgid_plural "%{count} followers"
@@ -1648,10 +1688,10 @@ msgstr[3] "%{num} кориÑтувачів"
msgid "1 week remaining"
msgid_plural "%d weeks remaining"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-msgstr[3] ""
+msgstr[0] "ЗалишивÑÑ 1 тиждень"
+msgstr[1] "ЗалишилоÑÑŒ %d тижні"
+msgstr[2] "ЗалишилоÑÑŒ %d тижнів"
+msgstr[3] "ЗалишилоÑÑŒ %d тижнів"
msgid "1 year remaining"
msgid_plural "%d years remaining"
@@ -1669,8 +1709,8 @@ msgstr "10-19 внеÑків"
msgid "1000+"
msgstr "1000+"
-msgid "192.168.0.0/24"
-msgstr "192.168.0.0/24"
+msgid "192.168.0.0/24 or 2001:0DB8:1234::/48"
+msgstr ""
msgid "1st contribution!"
msgstr "Перший внеÑок!"
@@ -1790,7 +1830,7 @@ msgid "A job artifact is an archive of files and directories saved by a job when
msgstr "Ðртефакт Ð·Ð°Ð²Ð´Ð°Ð½Ð½Ñ - це архів файлів та каталогів, збережених завданнÑм піÑÐ»Ñ Ð¹Ð¾Ð³Ð¾ завершеннÑ."
msgid "A limit of %{ci_project_subscriptions_limit} subscriptions to or from a project applies."
-msgstr ""
+msgstr "Ліміт %{ci_project_subscriptions_limit} підпиÑки на або з заÑтоÑованого проєкту."
msgid "A management, operational, or technical control (that is, safeguard or countermeasure) employed by an organization that provides equivalent or comparable protection for an information system."
msgstr ""
@@ -1814,7 +1854,7 @@ msgid "A new impersonation token has been created."
msgstr "Створено новий токен імітуваннÑ."
msgid "A non-confidential epic cannot be assigned to a confidential parent epic"
-msgstr ""
+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 "Сайт на HTML, Ñкий викориÑтовує Netlify Ð´Ð»Ñ CI/CD заміÑÑ‚ÑŒ GitLab, але вÑе ще з уÑіма іншими чудовими функціÑми GitLab"
@@ -1901,7 +1941,7 @@ msgid "APIFuzzing|Configure HTTP basic authentication values. Other authenticati
msgstr "ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð¾Ñновних значень автентифікації HTTP. ПідтримуютьÑÑ Ñ–Ð½ÑˆÑ– методи автентифікації. %{linkStart}Докладніше%{linkEnd}."
msgid "APIFuzzing|Customize your project's API fuzzing configuration options and copy the code snippet to your .gitlab-ci.yml file to apply any changes. Note that this tool does not reflect or update your .gitlab-ci.yml file automatically. For details of more advanced configuration options, see the %{docsLinkStart}GitLab API Fuzzing documentation%{docsLinkEnd}."
-msgstr ""
+msgstr "Ðалаштуйте параметри конфігурації нечіткого API вашого проєкту та Ñкопіюйте фрагмент коду у файл .gitlab-ci.yml, щоб заÑтоÑувати будь-Ñкі зміни. Зауважте, що цей інÑтрумент не відображає та не оновлює ваш файл .gitlab-ci.yml автоматично.ПереглÑньте більш детальну інформацію Ð´Ð»Ñ Ð·Ð½Ð°Ñ‡Ð½Ð¾ проÑунутих опцій конфігурації, %{docsLinkStart}документацію GitLab API Fuzzing%{docsLinkEnd}."
msgid "APIFuzzing|Enable authentication"
msgstr "Увімкнути автентифікацію"
@@ -1913,7 +1953,7 @@ msgid "APIFuzzing|Enter the name of the CI variable containing the username. For
msgstr "Введіть ім'Ñ Ð·Ð¼Ñ–Ð½Ð½Ð¾Ñ—, що міÑтить ім'Ñ ÐºÐ¾Ñ€Ð¸Ñтувача. Ðаприклад, $VARIABLE_WITH_USERNAME."
msgid "APIFuzzing|File path or URL to APIs to be tested. For example, folder/example_fuzz.har. HAR files may contain sensitive information such as authentication tokens, API keys, and session cookies. We recommend that you review the HAR files' contents before adding them to a repository."
-msgstr ""
+msgstr "Файл або URL-адреÑа Ð´Ð»Ñ Ñ‚ÐµÑÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ API. Ðаприклад, папка/example_fuzz.har. Файли HAR можуть міÑтити конфіденційну інформацію, а Ñаме: токени автентифікації, ключі API та файли cookie ÑеанÑу. Ми рекомендуємо вам переглÑнути вміÑÑ‚ файлів HAR, перш ніж додавати Ñ—Ñ… до репозиторію."
msgid "APIFuzzing|File path or URL to OpenAPI specification. For example, folder/openapi.json or http://www.example.com/openapi.json."
msgstr "ДоÑтуп до файлу або URL -адреÑа Ð´Ð»Ñ Ñпецифікації OpenAPI. Ðаприклад, папка/openapi.json або http://www.example.com/openapi.json."
@@ -1958,7 +1998,7 @@ msgid "APIFuzzing|Tip: Insert this part below all stages"
msgstr "Порада: вÑтавте цю чаÑтину під уÑÑ– Ñтадії"
msgid "APIFuzzing|To prevent a security leak, authentication info must be added as a %{ciVariablesLinkStart}CI variable%{ciVariablesLinkEnd}. A user with maintainer access rights can manage CI variables in the %{ciSettingsLinkStart}Settings%{ciSettingsLinkEnd} area. We detected that you are not a maintainer. Commit your changes and assign them to a maintainer to update the credentials before merging."
-msgstr ""
+msgstr "Щоб запобігти витоку безпеки, інформацію Ð´Ð»Ñ Ð°Ð²Ñ‚ÐµÐ½Ñ‚Ð¸Ñ„Ñ–ÐºÐ°Ñ†Ñ–Ñ— необхідно додати Ñк змінну %{ciVariablesLinkStart}CI%{ciVariablesLinkEnd}. КориÑтувач з правами доÑтупу керівника може керувати змінними CI в облаÑÑ‚Ñ– %{ciSettingsLinkStart}ÐалаштуваннÑ%{ciSettingsLinkEnd}. Ми виÑвили, що ви не Ñ” керівником. ЗафікÑуйте Ñвої зміни та призначте Ñ—Ñ… керівнику, щоб він оновив облікові дані перед об’єднаннÑм."
msgid "APIFuzzing|To prevent a security leak, authentication info must be added as a %{ciVariablesLinkStart}CI variable%{ciVariablesLinkEnd}. As a user with maintainer access rights, you can manage CI variables in the %{ciSettingsLinkStart}Settings%{ciSettingsLinkEnd} area."
msgstr ""
@@ -1981,14 +2021,14 @@ msgstr "folder/openapi.json"
msgid "AWS Access Key"
msgstr "Ключ доÑтупу AWS"
-msgid "AWS Access Key. Only required if not using role instance credentials"
-msgstr "Ключ доÑтупу AWS. Ðеобхідний лише Ñкщо не викориÑтовуютÑÑ Ñ€Ð¾Ð»ÑŒÐ¾Ð²Ñ– параметри доÑтупу до інÑтанÑу"
-
msgid "AWS Secret Access Key"
msgstr "Секретний ключ доÑтупу AWS"
-msgid "AWS Secret Access Key. Only required if not using role instance credentials"
-msgstr "Секретний ключ доÑтупу AWS. Ðеобхідний лише Ñкщо не викориÑтовуютÑÑ Ñ€Ð¾Ð»ÑŒÐ¾Ð²Ñ– параметри доÑтупу до інÑтанÑу"
+msgid "AWS access key ID (Optional)"
+msgstr ""
+
+msgid "AWS secret access key (Optional)"
+msgstr ""
msgid "AWS service error: %{error}"
msgstr "Помилка ÑервіÑу AWS: %{error}"
@@ -2012,7 +2052,7 @@ msgid "Abuse reports"
msgstr "Звіти про зловживаннÑ"
msgid "Abuse reports notification email"
-msgstr ""
+msgstr "Електронний лиÑÑ‚ із звітами про зловживаннÑ"
msgid "Accept invitation"
msgstr "ПрийнÑти запрошеннÑ"
@@ -2047,9 +2087,6 @@ msgstr "ДоÑтуп заборонено. Перевірте рівень доÑ
msgid "Access granted"
msgstr "ДоÑтуп дозволено"
-msgid "Access key ID"
-msgstr "Ідентифікатор ключа доÑтупу"
-
msgid "Access requests"
msgstr "Запити на доÑтуп"
@@ -2084,13 +2121,13 @@ msgid "AccessTokens|Are you sure? Any issue email addresses currently in use wil
msgstr "Ви впевнені? Будь-Ñкі поточні адреÑи електронної пошти Ð´Ð»Ñ Ð·Ð°Ð´Ð°Ñ‡ переÑтануть працювати."
msgid "AccessTokens|Copy feed token"
-msgstr ""
+msgstr "Скопіювати токен каналів"
msgid "AccessTokens|Copy incoming email token"
-msgstr ""
+msgstr "Скопіювати токен Ð´Ð»Ñ Ð²Ñ…Ñ–Ð´Ð½Ð¸Ñ… повідомлень електронної пошти"
msgid "AccessTokens|Copy static object token"
-msgstr ""
+msgstr "Скопіювати токен Ñтатичних об’єктів"
msgid "AccessTokens|Created"
msgstr "Створено"
@@ -2105,13 +2142,13 @@ msgid "AccessTokens|It cannot be used to access any other data."
msgstr "Ðе може бути викориÑтоно Ð´Ð»Ñ Ð´Ð¾Ñтупу до будь-Ñких інших даних."
msgid "AccessTokens|Keep this token secret. Anyone who has it can access repository static objects as if they were you. If that ever happens, %{linkStart}reset this token%{linkEnd}."
-msgstr ""
+msgstr "Зберігайте цей токен у Ñекреті. Кожен, хто має його, може отримати доÑтуп до Ñтатичних об’єктів репозиторію, ніби це були ви. Якщо це ÑтанетьÑÑ, %{linkStart}Ñкиньте цей токен%{linkEnd}."
msgid "AccessTokens|Keep this token secret. Anyone who has it can create issues as if they were you. If that happens, %{linkStart}reset this token%{linkEnd}."
-msgstr ""
+msgstr "Зберігайте цей токен у Ñекреті. Кожен, хто має його, може Ñтворювати задачі, ніби це були ви. Якщо це ÑтанетьÑÑ, %{linkStart}Ñкиньте цей токен%{linkEnd}."
msgid "AccessTokens|Keep this token secret. Anyone who has it can read activity and issue RSS feeds or your calendar feed as if they were you. If that happens, %{linkStart}reset this token%{linkEnd}."
-msgstr ""
+msgstr "Зберігайте цей токен в Ñекреті. Будь-хто, хто отримає до нього доÑтуп зможе читати RSS-канал активноÑÑ‚Ñ– та задач, а також канал вашого ÐºÐ°Ð»ÐµÐ½Ð´Ð°Ñ€Ñ Ð²Ñ–Ð´ вашого імені. Якщо це ÑтанетьÑÑ, %{linkStart}Ñкиньте цей токен%{linkEnd}."
msgid "AccessTokens|Personal Access Tokens"
msgstr "ОÑобиÑÑ‚Ñ– токени доÑтупу"
@@ -2135,7 +2172,7 @@ msgid "AccessTokens|Your incoming email token authenticates you when you create
msgstr "Ваш токен Ð´Ð»Ñ Ð²Ñ…Ñ–Ð´Ð½Ð¸Ñ… повідомлень електронної пошти викориÑтовуєтьÑÑ Ð´Ð»Ñ Ð°Ð²Ñ‚ÐµÐ½Ñ‚Ð¸Ñ„Ñ–ÐºÐ°Ñ†Ñ–Ñ—, коли ви Ñтворюєте нові задачі через електронну пошту Ñ– включаєтьÑÑ Ð´Ð¾ ваших оÑобиÑтих Ð°Ð´Ñ€ÐµÑ ÐµÐ»ÐµÑ‚Ñ€Ð¾Ð½Ð½Ð¾Ñ— пошти Ð´Ð»Ñ ÐºÐ¾Ð½ÐºÑ€ÐµÑ‚Ð½Ð¾Ð³Ð¾ проєкту."
msgid "AccessTokens|Your static object token authenticates you when repository static objects (such as archives or blobs) are served from an external storage."
-msgstr ""
+msgstr "Ваш токен Ñтатичного об'єкта аутентифікує ваÑ, коли Ñтатичні об'єкти репозиторію (наприклад, архіви або великі об'єкти) обÑлуговуютьÑÑ Ñ–Ð· зовнішнього Ñховища."
msgid "AccessibilityReport|Learn more"
msgstr "ДізнатиÑÑ Ð±Ñ–Ð»ÑŒÑˆÐµ"
@@ -2165,34 +2202,34 @@ msgid "Account: %{account}"
msgstr "Обліковий запиÑ: %{account}"
msgid "AccountValidation|Fix your pipelines by validating your account"
-msgstr ""
+msgstr "Виправте Ñвої конвеєри, підтвердивши Ñвій обліковий запиÑ"
msgid "AccountValidation|I'll bring my own runners"
-msgstr ""
+msgstr "Я зареєÑтрую мої влаÑні runner'и"
msgid "AccountValidation|If you no longer wish to receive marketing emails from us,"
-msgstr ""
+msgstr "Якщо ви більше не бажаєте отримувати маркетингові електронні лиÑти від наÑ,"
msgid "AccountValidation|In order to use free CI/CD minutes on shared runners, you'll need to validate your account using one of our verification options. If you prefer not to, you can run pipelines by bringing your own runners and disabling shared runners for your project."
-msgstr ""
+msgstr "Щоб викориÑтовувати безкоштовні хвилини CI/CD на Ñпільних Runner'ах, вам потрібно підтвердити Ñвій обліковий Ð·Ð°Ð¿Ð¸Ñ Ð·Ð° допомогою одного з наших варіантів підтвердженнÑ. Якщо ви віддаєте перевагу цьому не робити, ви можете запуÑкати конвеєри, додавши влаÑні runner'и та вимкнувши Ñпільні runner'и Ð´Ð»Ñ Ð²Ð°ÑˆÐ¾Ð³Ð¾ проєкту."
msgid "AccountValidation|Learn more."
msgstr "ДізнатиÑÑ Ð±Ñ–Ð»ÑŒÑˆÐµ."
msgid "AccountValidation|Looks like you’ll need to validate your account to use free CI/CD minutes"
-msgstr ""
+msgstr "Схоже, вам потрібно буде підтвердити Ñвій обліковий запиÑ, щоб викориÑтовувати безкоштовні хвилини CI/CD"
msgid "AccountValidation|Validate your account"
-msgstr ""
+msgstr "Перевірте ваш обліковий запиÑ"
msgid "AccountValidation|Verification is required to discourage and reduce the abuse on GitLab infrastructure. If you verify with a credit or debit card, %{strong_start}GitLab will not charge your card, it will only be used for validation.%{strong_end} %{learn_more_link}"
msgstr ""
msgid "AccountValidation|unsubscribe"
-msgstr ""
+msgstr "СкаÑувати підпиÑку"
msgid "AccountValidation|you may %{unsubscribe_link} at any time."
-msgstr ""
+msgstr "Ви можете %{unsubscribe_link} у будь-Ñкий чаÑ"
msgid "Action"
msgstr "ДіÑ"
@@ -2219,13 +2256,13 @@ msgid "Active Sessions"
msgstr "Ðктивні ÑеÑÑ–Ñ—"
msgid "Active chat names (%{count})"
-msgstr ""
+msgstr "Ðктивні імена чата %{count})"
msgid "Activity"
msgstr "ÐктивніÑÑ‚ÑŒ"
-msgid "Activity|An error occured while retrieving activity. Reload the page to try again."
-msgstr "При отриманні активноÑÑ‚Ñ– ÑталаÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ°. Перезавантажте Ñторінку, щоб Ñпробувати знову."
+msgid "Activity|An error occurred while retrieving activity. Reload the page to try again."
+msgstr ""
msgid "Add"
msgstr "Додати"
@@ -2252,7 +2289,7 @@ msgid "Add LICENSE"
msgstr "Додати файл ліцензії (LICENSE)"
msgid "Add New Site"
-msgstr ""
+msgstr "Додати новий Ñайт"
msgid "Add README"
msgstr "Додати інÑтрукцію (README)"
@@ -2263,17 +2300,20 @@ msgstr "Додати Zoom-зуÑтріч"
msgid "Add a %{type}"
msgstr "Додати %{type}"
+msgid "Add a GCP region"
+msgstr ""
+
msgid "Add a GPG key"
msgstr "Додати GPG ключ"
msgid "Add a GPG key for secure access to GitLab. %{help_link_start}Learn more.%{help_link_end}"
-msgstr ""
+msgstr "Додати ключ GPG Ð´Ð»Ñ Ð±ÐµÐ·Ð¿ÐµÑ‡Ð½Ð¾Ð³Ð¾ доÑтупу до GitLab. %{help_link_start}ДізнатиÑÑ Ð±Ñ–Ð»ÑŒÑˆÐµ.%{help_link_end}"
msgid "Add a Jaeger URL to replace this page with a link to your Jaeger server. You first need to %{link_start_tag}install Jaeger%{link_end_tag}."
msgstr "Додайте URL-адреÑу Jaeger, щоб замінити цю Ñторінку поÑиланнÑм на ваш Ñервер Jaeger. Спочатку вам потрібно %{link_start_tag} вÑтановити Jaeger%{link_end_tag}."
msgid "Add a Terms of Service agreement and Privacy Policy for users of this GitLab instance."
-msgstr "Додати угоду про умови Ð½Ð°Ð´Ð°Ð½Ð½Ñ Ð¿Ð¾Ñлуг Ñ– політику конфіденційноÑÑ‚Ñ– Ð´Ð»Ñ ÐºÐ¾Ñ€Ð¸Ñтувачів цього екземплÑра GitLab."
+msgstr "Додати угоду про умови Ð½Ð°Ð´Ð°Ð½Ð½Ñ Ð¿Ð¾Ñлуг Ñ– політику конфіденційноÑÑ‚Ñ– Ð´Ð»Ñ ÐºÐ¾Ñ€Ð¸Ñтувачів цього інÑтанÑа GitLab."
msgid "Add a bullet list"
msgstr "Додати ненумерований ÑпиÑок"
@@ -2314,11 +2354,14 @@ msgstr "Додати нову задачу"
msgid "Add a numbered list"
msgstr "Додати нумерований ÑпиÑок"
+msgid "Add a related epic"
+msgstr ""
+
msgid "Add a related issue"
msgstr "Додати пов'Ñзану задачу"
msgid "Add a suffix to Service Desk email address. %{linkStart}Learn more.%{linkEnd}"
-msgstr ""
+msgstr "Додати ÑÑƒÑ„Ñ–ÐºÑ Ð´Ð¾ електронної адреÑи Ñлужби підтримки. %{linkStart}Докладніше.%{linkEnd}"
msgid "Add a table"
msgstr "Додати таблицю"
@@ -2327,7 +2370,7 @@ msgid "Add a task list"
msgstr "Додати ÑпиÑок завдань"
msgid "Add a title..."
-msgstr ""
+msgstr "Додати назву..."
msgid "Add a to do"
msgstr "Додати нагадуваннÑ"
@@ -2336,7 +2379,7 @@ msgid "Add an SSH key"
msgstr "Додати SSH ключ"
msgid "Add an SSH key for secure access to GitLab. %{help_link_start}Learn more.%{help_link_end}"
-msgstr ""
+msgstr "Додати SSH-ключ Ð´Ð»Ñ Ð±ÐµÐ·Ð¿ÐµÑ‡Ð½Ð¾Ð³Ð¾ доÑтупу до GitLab. %{help_link_start}ДізнатиÑÑ Ð±Ñ–Ð»ÑŒÑˆÐµ.%{help_link_end}"
msgid "Add an existing issue"
msgstr "Додати Ñ–Ñнуючу задачу"
@@ -2378,7 +2421,7 @@ msgid "Add customer relation contact(s)."
msgstr ""
msgid "Add customer relation contacts"
-msgstr ""
+msgstr "Додати контакти по роботі з клієнтами."
msgid "Add deploy freeze"
msgstr "Додати Ð·Ð°Ð¼Ð¾Ñ€Ð¾Ð¶ÑƒÐ²Ð°Ð½Ð½Ñ Ñ€Ð¾Ð·Ð³Ð¾Ñ€Ñ‚Ð°Ð½Ð½Ñ"
@@ -2428,6 +2471,9 @@ msgstr "Ð”Ð¾Ð´Ð°Ð²Ð°Ð½Ð½Ñ Ð°Ð±Ð¾ Ð²Ð¸Ð´Ð°Ð»ÐµÐ½Ð½Ñ Ñ€Ð°Ð½Ñ–ÑˆÐµ злитих Ð
msgid "Add or subtract spent time"
msgstr "Додати або віднÑти витрачений чаÑ"
+msgid "Add people"
+msgstr ""
+
msgid "Add previously merged commits"
msgstr "Додати раніше злиті коміти"
@@ -2494,6 +2540,9 @@ msgstr "Додати пошук вразливоÑтей"
msgid "Add webhook"
msgstr "Додати вебхук"
+msgid "Add your team members and others to GitLab."
+msgstr ""
+
msgid "Add/remove"
msgstr "Додати/видалити"
@@ -2759,13 +2808,13 @@ msgid "AdminGeo|The URL of the secondary site that is used internally by the pri
msgstr ""
msgid "AdminLabels|Define your default set of project labels"
-msgstr ""
+msgstr "Визначте ваш набір проєктних міток за замовчуваннÑм"
msgid "AdminLabels|Labels created here will be automatically added to new projects."
-msgstr ""
+msgstr "Мітки, Ñтворені тут, будуть автоматично додані до нових проєктів."
msgid "AdminLabels|They can be used to categorize issues and merge requests."
-msgstr ""
+msgstr "Їх можна викориÑтати Ð´Ð»Ñ ÐºÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ð·Ð°Ñ†Ñ–Ñ— задач та запитів на злиттÑ."
msgid "AdminProjects| You’re about to permanently delete the project %{projectName}, its repository, and all related resources, including issues and merge requests. After you confirm and press %{strong_start}Delete project%{strong_end}, it cannot be undone or recovered."
msgstr ""
@@ -2777,10 +2826,10 @@ msgid "AdminProjects|Delete Project %{projectName}?"
msgstr "Видалити проєкт %{projectName}?"
msgid "AdminSettings|A Let's Encrypt account will be configured for this GitLab instance using this email address. You will receive emails to warn of expiring certificates. %{link_start}Learn more.%{link_end}"
-msgstr "Let's Encrypt буде налаштований Ð´Ð»Ñ Ñ†ÑŒÐ¾Ð³Ð¾ екземплÑра GitLab за допомогою цієї адреÑи електронної пошти. Ви отримуватимете повідомленнÑ, Ñкі попереджають про Ð·Ð°ÐºÑ–Ð½Ñ‡ÐµÐ½Ð½Ñ Ñ‚ÐµÑ€Ð¼Ñ–Ð½Ñƒ дії Ñертифікатів. %{link_start}ДізнайтеÑÑŒ більше. %{link_end}"
+msgstr "Let's Encrypt буде налаштований Ð´Ð»Ñ Ñ†ÑŒÐ¾Ð³Ð¾ інÑтанÑа GitLab за допомогою цієї адреÑи електронної пошти. Ви отримуватимете повідомленнÑ, Ñкі попереджають про Ð·Ð°ÐºÑ–Ð½Ñ‡ÐµÐ½Ð½Ñ Ñ‚ÐµÑ€Ð¼Ñ–Ð½Ñƒ дії Ñертифікатів. %{link_start}ДізнайтеÑÑŒ більше. %{link_end}"
msgid "AdminSettings|All new projects can use the instance's shared runners by default."
-msgstr "Ð’ÑÑ– нові проєкти за замовчуваннÑм можуть викориÑтовувати загальні ранери (Runner'и) інÑтанÑа."
+msgstr "Ð’ÑÑ– нові проєкти за замовчуваннÑм можуть викориÑтовувати загальні runner'и (Runner'и) інÑтанÑа."
msgid "AdminSettings|Auto DevOps domain"
msgstr "Домен Auto DevOps"
@@ -2915,7 +2964,7 @@ msgid "AdminUsers|(Internal)"
msgstr "(Внутрішні)"
msgid "AdminUsers|(Locked)"
-msgstr ""
+msgstr "(Заблоковано)"
msgid "AdminUsers|(Pending approval)"
msgstr "(Очікує ÑхваленнÑ)"
@@ -2954,7 +3003,7 @@ msgid "AdminUsers|Admin"
msgstr "ÐдмініÑтратор"
msgid "AdminUsers|Administrator"
-msgstr ""
+msgstr "ÐдмініÑтратор"
msgid "AdminUsers|Admins"
msgstr "ÐдмініÑтратори"
@@ -3047,7 +3096,7 @@ msgid "AdminUsers|Delete user and contributions"
msgstr "Видалити кориÑтувача Ñ– його внеÑки"
msgid "AdminUsers|Export permissions as CSV (max 100,000 users)"
-msgstr ""
+msgstr "ЕкÑпортуйте дозволи у форматі CSV (не більше ніж 100 000 кориÑтувачів)"
msgid "AdminUsers|External"
msgstr "Зовнішні"
@@ -3059,7 +3108,7 @@ msgid "AdminUsers|For more information, please refer to the %{link_start}user ac
msgstr "Ð”Ð»Ñ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ Ð±Ñ–Ð»ÑŒÑˆ детальної інформації звернітьÑÑ Ð´Ð¾ %{link_start} документації з Ð²Ð¸Ð´Ð°Ð»ÐµÐ½Ð½Ñ Ð¾Ð±Ð»Ñ–ÐºÐ¾Ð²Ð¾Ð³Ð¾ запиÑу кориÑтувача . %{link_end}"
msgid "AdminUsers|Here are some helpful links to help you manage your instance:"
-msgstr ""
+msgstr "ОÑÑŒ кілька кориÑних поÑилань, Ñкі допоможуть вам керувати Ñвоїм інÑтанÑом:"
msgid "AdminUsers|If you have any questions about this process please consult our %{doc_link} or %{support_link}."
msgstr "Якщо у Ð²Ð°Ñ Ñ” Ð¿Ð¸Ñ‚Ð°Ð½Ð½Ñ Ñ‰Ð¾Ð´Ð¾ цього процеÑу, звернітьÑÑ Ð´Ð¾ наших %{doc_link} або %{support_link}."
@@ -3080,7 +3129,7 @@ msgid "AdminUsers|Learn more about %{link_start}banned users.%{link_end}"
msgstr "Докладніше про %{link_start}забанених кориÑтувачів.%{link_end}"
msgid "AdminUsers|Locked"
-msgstr ""
+msgstr "Заблоковано"
msgid "AdminUsers|Log in"
msgstr "Вхід в ÑиÑтему"
@@ -3110,7 +3159,7 @@ msgid "AdminUsers|Reactivating a user will:"
msgstr "Повторна Ð°ÐºÑ‚Ð¸Ð²Ð°Ñ†Ñ–Ñ ÐºÐ¾Ñ€Ð¸Ñтувача зробить:"
msgid "AdminUsers|Regular"
-msgstr ""
+msgstr "Звичайні"
msgid "AdminUsers|Regular users have access to their groups and projects."
msgstr "Звичайні кориÑтувачі мають доÑтуп до Ñвоїх груп та проєктів."
@@ -3140,13 +3189,13 @@ msgid "AdminUsers|Sort by"
msgstr "Сортувати за"
msgid "AdminUsers|The user can't access git repositories."
-msgstr ""
+msgstr "КориÑтувач не може отримати доÑтуп до репозиторіїв git."
msgid "AdminUsers|The user can't log in."
msgstr "КориÑтувач не може увійти."
msgid "AdminUsers|The user has unlimited access to all groups, projects, users, and features."
-msgstr ""
+msgstr "КориÑтувач має необмежений доÑтуп до вÑÑ–Ñ… груп, проєктів, кориÑтувачів Ñ– функцій."
msgid "AdminUsers|The user will be logged out"
msgstr "КориÑтувач вийде із ÑиÑтеми"
@@ -3185,10 +3234,10 @@ msgid "AdminUsers|Unlock user %{username}?"
msgstr "Розблокувати кориÑтувача %{username}?"
msgid "AdminUsers|User administration"
-msgstr ""
+msgstr " Ð£Ð¿Ñ€Ð°Ð²Ð»Ñ–Ð½Ð½Ñ ÐºÐ¾Ñ€Ð¸Ñтувачами"
msgid "AdminUsers|User is validated and can use free CI minutes on shared runners."
-msgstr ""
+msgstr "КориÑтувач перевірений та може викориÑтовувати безкоштовні хвилини CI Ð´Ð»Ñ Ð·Ð°Ð³Ð°Ð»ÑŒÐ½Ð¸Ñ… runner'ів."
msgid "AdminUsers|User will not be able to access git repositories"
msgstr "КориÑтувач не зможе отримувати доÑтуп до репозиторіїв Git"
@@ -3206,7 +3255,7 @@ msgid "AdminUsers|Validate user account"
msgstr "Перевірити обліковий Ð·Ð°Ð¿Ð¸Ñ ÐºÐ¾Ñ€Ð¸Ñтувача"
msgid "AdminUsers|View pending member requests"
-msgstr ""
+msgstr "ПереглÑнути запити учаÑників в очікуванні"
msgid "AdminUsers|What can I do?"
msgstr "Що Ñ Ð¼Ð¾Ð¶Ñƒ зробити?"
@@ -3251,7 +3300,7 @@ msgid "AdminUsers|You can unban their account in the future. Their data remains
msgstr "Ви можете розблокувати Ñ—Ñ… обліковий Ð·Ð°Ð¿Ð¸Ñ Ñƒ майбутньому. Їхні дані залишаютьÑÑ Ð½ÐµÐ´Ð¾Ñ‚Ð¾Ñ€ÐºÐ°Ð½Ð¸Ð¼Ð¸."
msgid "AdminUsers|You cannot remove your own administrator access."
-msgstr ""
+msgstr "Ви не можете видалити Ñвій влаÑний доÑтуп адмініÑтратора."
msgid "AdminUsers|You must transfer ownership or delete the groups owned by this user before you can delete their account"
msgstr "Ви повинні передати право влаÑноÑÑ‚Ñ– або видалити групи, що належать цьому кориÑтувачу, перш ніж ви зможете видалити його обліковий запиÑ"
@@ -3290,10 +3339,10 @@ msgid "Admin|Quarterly reconciliation will occur on %{qrtlyDate}"
msgstr "Квартальна звірка відбудетьÑÑ %{qrtlyDate}"
msgid "Admin|The number of max seats in your namespace exceeds the number of seats in your subscription. On %{qrtlyDate}, quarterly reconciliation occurs and you are automatically billed a prorated amount for the overage. No action is needed from you. If you have a credit card on file, it will be charged. Otherwise, you will receive an invoice. For more information about the timing of the invoicing process, view the documentation."
-msgstr ""
+msgstr "МакÑимальна можлива кількіÑÑ‚ÑŒ міÑць у проÑторі імен перевищує кількіÑÑ‚ÑŒ міÑць у вашій підпиÑці. %{qrtlyDate} відбудетьÑÑ Ñ‰Ð¾ÐºÐ²Ð°Ñ€Ñ‚Ð°Ð»ÑŒÐ½Ð° перевірка Ñ– вам автоматично буде виÑтавлено рахунок за Ð¿ÐµÑ€ÐµÐ²Ð¸Ñ‰ÐµÐ½Ð½Ñ Ð½Ð° пропорціональну Ñуму. Від Ð²Ð°Ñ Ð½Ðµ очікуєтьÑÑ Ð¶Ð¾Ð´Ð½Ð¸Ñ… дій. Якщо у Ð²Ð°Ñ Ð¿Ñ€Ð¸Ð²'Ñзана кредитна картка, оплату буде ÑпиÑано з неї. У іншому випадку ви отримаєте рахунок на оплату. Ð”Ð»Ñ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ Ð´Ð¾Ð´Ð°Ñ‚ÐºÐ¾Ð²Ð¾Ñ— інформації про терміни виÑÑƒÐ½ÐµÐ½Ð½Ñ Ñ€Ð°Ñ…ÑƒÐ½ÐºÑ–Ð², ознайомтеÑÑ Ð· документацією."
msgid "Admin|The number of max users in your instance exceeds the number of users in your license. On %{qrtlyDate}, quarterly reconciliation occurs and you are automatically billed a prorated amount for the overage. No action is needed from you. If you have a credit card on file, it will be charged. Otherwise, you will receive an invoice. For more information about the timing of the invoicing process, view the documentation."
-msgstr ""
+msgstr "МакÑимальна кількіÑÑ‚ÑŒ кориÑтувачів Ð´Ð»Ñ Ð²Ð°ÑˆÐ¾Ð³Ð¾ екземплÑру зараз перевищує кількіÑÑ‚ÑŒ кориÑтувачів в ліцензії. %{qrtlyDate} відбудетьÑÑ Ñ‰Ð¾ÐºÐ²Ð°Ñ€Ñ‚Ð°Ð»ÑŒÐ½Ð° перевірка Ñ– вам буде автоматично виÑтавлено рахунок за Ð¿ÐµÑ€ÐµÐ²Ð¸Ñ‰ÐµÐ½Ð½Ñ Ð»Ñ–Ð¼Ñ–Ñ‚Ñƒ. Від Ð²Ð°Ñ Ð½Ðµ очікуєтьÑÑ Ð¶Ð¾Ð´Ð½Ð¸Ñ… дій. Якщо у Ð²Ð°Ñ Ð¿Ñ€Ð¸Ð²'Ñзана кредитна картка, оплату буде ÑпиÑано з неї. У інакшому випадку, ви отримаєте рахунок. Ð”Ð»Ñ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ Ð´ÐµÑ‚Ð°Ð»ÑŒÐ½Ñ–ÑˆÐ¾Ñ— інформації про терміни виÑÑƒÐ½ÐµÐ½Ð½Ñ Ñ€Ð°Ñ…ÑƒÐ½ÐºÑ–Ð², ознайомтеÑÑ Ð· документацією."
msgid "Admin|View pending user approvals"
msgstr "ПереглÑнути очікуючі Ð·Ð°Ñ‚Ð²ÐµÑ€Ð´Ð¶ÐµÐ½Ð½Ñ ÐºÐ¾Ñ€Ð¸Ñтувача"
@@ -3314,13 +3363,7 @@ msgid "Advanced export options"
msgstr "Розширені параметри екÑпорту"
msgid "AdvancedSearch|Reindex required"
-msgstr ""
-
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. Permanently deleting this project will %{strongStart}immediately delete%{strongEnd} its repositories and %{strongStart}all related resources%{strongEnd}, including issues, merge requests etc."
-msgstr ""
-
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. You will lose this project's repository and %{strongStart}all related resources%{strongEnd}, including issues and merge requests."
-msgstr ""
+msgstr "Потрібна повторна індекÑаціÑ"
msgid "After a successful password update you will be redirected to login screen."
msgstr "ПіÑÐ»Ñ ÑƒÑпішного Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð¿Ð°Ñ€Ð¾Ð»Ñ Ð²Ð¸ перейдете на екран входу."
@@ -3338,7 +3381,7 @@ msgid "After it expires, you can't use merge approvals, epics, or many security
msgstr ""
msgid "After the export is complete, download the data file from a notification email or from this page. You can then import the data file from the %{strong_text_start}Create new group%{strong_text_end} page of another GitLab instance."
-msgstr ""
+msgstr "ПіÑÐ»Ñ Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð½Ñ ÐµÐºÑпорту завантажте файл даних із Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ ÐµÐ»ÐµÐºÑ‚Ñ€Ð¾Ð½Ð½Ð¾Ñ— пошти або з цієї Ñторінки. Потім ви можете імпортувати файл даних із %{strong_text_start}Створити нову Ñторінку групи %{strong_text_end} іншого інÑтанÑа GitLab."
msgid "After you've reviewed these contribution guidelines, you'll be all set to"
msgstr ""
@@ -3352,6 +3395,9 @@ msgstr "Ключ API Akismet"
msgid "Akismet helps prevent the creation of spam issues in public projects."
msgstr "Akismet допомагає запобігти Ñтворенню проблем зі Ñпамом у публічних проєктах."
+msgid "Alert"
+msgstr ""
+
msgid "AlertManagement|Acknowledged"
msgstr "Підтверджено"
@@ -3638,7 +3684,7 @@ msgid "AlertSettings|View credentials"
msgstr "ПереглÑнути облікові дані"
msgid "AlertSettings|Webhook URL"
-msgstr ""
+msgstr "URL-адреÑа вебхука"
msgid "AlertSettings|You can map default GitLab alert fields to your payload keys in the dropdowns below."
msgstr ""
@@ -3724,14 +3770,11 @@ msgstr "Ð’ÑÑ– адреÑи електронної пошти будуть виÐ
msgid "All environments"
msgstr "Ð’ÑÑ– Ñередовища"
-msgid "All epics"
-msgstr "Ð’ÑÑ– епіки"
-
msgid "All groups and projects"
msgstr "Ð’ÑÑ– групи та проєкти"
msgid "All issues"
-msgstr ""
+msgstr "Ð’ÑÑ– задачі"
msgid "All issues for this milestone are closed."
msgstr "Ð’ÑÑ– задачі в цьому етапі закриті."
@@ -3818,7 +3861,7 @@ msgid "Allow this key to push to this repository"
msgstr "Дозволити відправлÑти ключ до цього репозиторію"
msgid "Allow this secondary site to replicate content on Object Storage"
-msgstr ""
+msgstr "Дозволити цьому додатковому Ñайту копіювати контент в об'єктному Ñховищі"
msgid "Allow use of licensed EE features"
msgstr "Дозволити викориÑÑ‚Ð°Ð½Ð½Ñ Ð»Ñ–Ñ†ÐµÐ½Ð·Ð¾Ð²Ð°Ð½Ð¸Ñ… функцій EE"
@@ -4076,7 +4119,7 @@ msgid "An error occurred while fetching the latest pipeline."
msgstr "Помилка при отриманні оÑтаннього конвеєра."
msgid "An error occurred while fetching the pipelines jobs."
-msgstr ""
+msgstr "Виникла помилка під Ñ‡Ð°Ñ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ Ð·Ð°Ð²Ð´Ð°Ð½ÑŒ конвеєра."
msgid "An error occurred while fetching the releases. Please try again."
msgstr "Помилка при отриманні релізів. Будь лаÑка, Ñпробуйте знову."
@@ -4133,7 +4176,7 @@ msgid "An error occurred while loading projects."
msgstr "Під Ñ‡Ð°Ñ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¾Ñ”ÐºÑ‚Ñ–Ð² ÑталаÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ°."
msgid "An error occurred while loading the Jobs tab."
-msgstr ""
+msgstr "Виникла помилка під Ñ‡Ð°Ñ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ð²ÐºÐ»Ð°Ð´ÐºÐ¸ завдань."
msgid "An error occurred while loading the Needs tab."
msgstr ""
@@ -4145,7 +4188,7 @@ msgid "An error occurred while loading the access tokens form, please try again.
msgstr "Виникла помилка під Ñ‡Ð°Ñ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ñ„Ð¾Ñ€Ð¼Ð¸ токенів доÑтупу. Повторіть Ñпробу."
msgid "An error occurred while loading the blob controls."
-msgstr ""
+msgstr "Виникла помилка під Ñ‡Ð°Ñ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ð±Ñ–Ð½Ð°Ñ€Ð½Ð¸Ñ… даних."
msgid "An error occurred while loading the data. Please try again."
msgstr "Під Ñ‡Ð°Ñ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ð´Ð°Ð½Ð¸Ñ… ÑталаÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ°. Будь лаÑка, Ñпробуйте ще раз."
@@ -4299,10 +4342,10 @@ msgid "An example showing how to use Jsonnet with GitLab dynamic child pipelines
msgstr "Приклад, що показує викориÑÑ‚Ð°Ð½Ð½Ñ Jsonnet з динамічними дочірніми конвеєрами GitLab"
msgid "An incident has been resolved in %{project_path}."
-msgstr ""
+msgstr "Інцидент було вирішено в %{project_path}."
msgid "An incident has been triggered in %{project_path}."
-msgstr ""
+msgstr "Інцидент ÑтавÑÑ Ð² %{project_path}."
msgid "An integer value is required for seconds"
msgstr ""
@@ -4467,14 +4510,17 @@ msgstr "Схвалити кориÑтувачів"
msgid "ApplicationSettings|Approve users in the pending approval status?"
msgstr "Затвердити кориÑтувачів у ÑтатуÑÑ– очікуваного затвердженнÑ?"
-msgid "ApplicationSettings|By making this change, you will automatically approve %d user with the pending approval status."
-msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users with the pending approval status."
-msgstr[0] "Зробивши цю зміну, ви автоматично Ñхвалите %d кориÑтувача зі ÑтатуÑом Ð¾Ñ‡Ñ–ÐºÑƒÐ²Ð°Ð½Ð½Ñ Ð½Ð° ÑхваленнÑ."
-msgstr[1] "Зробивши цю зміну, ви автоматично Ñхвалите %d кориÑтувачів із ÑтатуÑом Ð¾Ñ‡Ñ–ÐºÑƒÐ²Ð°Ð½Ð½Ñ Ð½Ð° ÑхваленнÑ."
-msgstr[2] "Зробивши цю зміну, ви автоматично Ñхвалите %d кориÑтувачів із ÑтатуÑом Ð¾Ñ‡Ñ–ÐºÑƒÐ²Ð°Ð½Ð½Ñ Ð½Ð° ÑхваленнÑ."
-msgstr[3] "Зробивши цю зміну, ви автоматично Ñхвалите %d кориÑтувачів із ÑтатуÑом Ð¾Ñ‡Ñ–ÐºÑƒÐ²Ð°Ð½Ð½Ñ Ð½Ð° ÑхваленнÑ."
+msgid "ApplicationSettings|Approve users who are pending approval?"
+msgstr ""
+
+msgid "ApplicationSettings|By making this change, you will automatically approve %d user who is pending approval."
+msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users who are pending approval."
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
-msgid "ApplicationSettings|By making this change, you will automatically approve all users in pending approval status."
+msgid "ApplicationSettings|By making this change, you will automatically approve all users who are pending approval."
msgstr ""
msgid "ApplicationSettings|Denied domains for sign-ups"
@@ -4511,7 +4557,7 @@ msgid "ApplicationSettings|ONLY users with e-mail addresses that match these dom
msgstr ""
msgid "ApplicationSettings|Once the instance reaches the user cap, any user who is added or requests access will have to be approved by an admin. Leave the field empty for unlimited."
-msgstr "Як тільки екземплÑÑ€ доÑÑгне Ð¾Ð±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ Ð·Ð° кількіÑÑ‚ÑŽ кориÑтувачів, будь-Ñкий доданий або запитуваний доÑтуп кориÑтувач повинен бути Ñхвалений адмініÑтратором. Залишіть поле порожнім на необмежений термін."
+msgstr "Як тільки інÑÑ‚Ð°Ð½Ñ Ð´Ð¾ÑÑгне Ð¾Ð±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ Ð·Ð° кількіÑÑ‚ÑŽ кориÑтувачів, будь-Ñкий доданий або запитуваний доÑтуп кориÑтувач повинен бути Ñхвалений адмініÑтратором. Залишіть поле порожнім на необмежений термін."
msgid "ApplicationSettings|Require admin approval for new sign-ups"
msgstr "Потрібне ÑÑ…Ð²Ð°Ð»ÐµÐ½Ð½Ñ Ð°Ð´Ð¼Ñ–Ð½Ñ–Ñтратора Ð´Ð»Ñ Ð½Ð¾Ð²Ð¸Ñ… реєÑтрацій"
@@ -4614,7 +4660,7 @@ msgid "Approval rules reset to project defaults"
msgstr "Відновлено типові Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ñ€Ð°Ð²Ð¸Ð» Ð·Ð°Ñ‚Ð²ÐµÑ€Ð´Ð¶ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¾Ñ”ÐºÑ‚Ñƒ"
msgid "Approval settings"
-msgstr "ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð·Ð°Ñ‚Ð²ÐµÑ€Ð´Ð¶ÐµÐ½Ð½Ñ"
+msgstr "Параметри затвердженнÑ"
msgid "ApprovalRuleRemove|%d member"
msgid_plural "ApprovalRuleRemove|%d members"
@@ -4648,7 +4694,7 @@ msgid "ApprovalRule|%{firstLabel} +%{numberOfAdditionalLabels} more"
msgstr "%{firstLabel} + ще %{numberOfAdditionalLabels}"
msgid "ApprovalRule|A merge request author collaborating with a merge request approver"
-msgstr ""
+msgstr "Ðвтор запиту на Ð·Ð»Ð¸Ñ‚Ñ‚Ñ Ñпівпрацює із затверджувачем запиту на злиттÑ."
msgid "ApprovalRule|Add approvers"
msgstr "Додати затверджувачів"
@@ -4693,13 +4739,13 @@ msgid "ApprovalRule|Examples: QA, Security."
msgstr "Приклади: QA, Security."
msgid "ApprovalRule|Improve your organization's code review with required approvals."
-msgstr ""
+msgstr "Покращте перевірку коду вашої організації за допомогою необхідних затверджень."
msgid "ApprovalRule|Increase quality and maintain standards."
-msgstr ""
+msgstr "Підвищуйте ÑкіÑÑ‚ÑŒ та підтримуйте Ñтандарти."
msgid "ApprovalRule|Learn more about merge request approval rules."
-msgstr ""
+msgstr "ДізнайтеÑÑ Ð±Ñ–Ð»ÑŒÑˆÐµ про правила Ð·Ð°Ñ‚Ð²ÐµÑ€Ð´Ð¶ÐµÐ½Ð½Ñ Ð·Ð°Ð¿Ð¸Ñ‚Ñ–Ð² на злиттÑ."
msgid "ApprovalRule|Name"
msgstr "Ім'Ñ"
@@ -4726,7 +4772,7 @@ msgid "ApprovalRule|Previously detected"
msgstr "Раніше виÑвлений"
msgid "ApprovalRule|Reduce your time to merge."
-msgstr ""
+msgstr "Зменште ваш Ñ‡Ð°Ñ Ð´Ð»Ñ Ð·Ð»Ð¸Ñ‚Ñ‚Ñ."
msgid "ApprovalRule|Resolved"
msgstr "Вирішений"
@@ -4741,7 +4787,7 @@ msgid "ApprovalRule|Select All"
msgstr "Вибрати вÑе"
msgid "ApprovalRule|Select eligible approvers by expertise or files changed."
-msgstr ""
+msgstr "Виберіть відповідних затверджувачів за компетентніÑÑ‚ÑŽ або зміненими файлами."
msgid "ApprovalRule|Select scanners"
msgstr "Вибрати Ñканери"
@@ -4759,7 +4805,7 @@ msgid "ApprovalRule|Target branch"
msgstr "Цільова гілка"
msgid "ApprovalRule|Try for free"
-msgstr ""
+msgstr "Спробувати безкоштовно"
msgid "ApprovalRule|Vulnerabilities allowed"
msgstr "Дозволені вразливоÑÑ‚Ñ–"
@@ -4771,28 +4817,28 @@ msgid "ApprovalSettings|Merge request approval settings have been updated."
msgstr "ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ ÑÑ…Ð²Ð°Ð»ÐµÐ½Ð½Ñ Ð·Ð°Ð¿Ð¸Ñ‚Ñƒ на Ð·Ð»Ð¸Ñ‚Ñ‚Ñ Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½Ð¾."
msgid "ApprovalSettings|Prevent approval by author"
-msgstr ""
+msgstr "Заборонити Ð·Ð°Ñ‚Ð²ÐµÑ€Ð´Ð¶ÐµÐ½Ð½Ñ Ð°Ð²Ñ‚Ð¾Ñ€Ð¾Ð¼"
msgid "ApprovalSettings|Prevent approval by author."
msgstr "Заборонити ÑÑ…Ð²Ð°Ð»ÐµÐ½Ð½Ñ Ð°Ð²Ñ‚Ð¾Ñ€Ð¾Ð¼."
msgid "ApprovalSettings|Prevent approvals by users who add commits"
-msgstr ""
+msgstr "Заборонити Ð·Ð°Ñ‚Ð²ÐµÑ€Ð´Ð¶ÐµÐ½Ð½Ñ ÐºÐ¾Ñ€Ð¸Ñтувачами, Ñкі додають коміти"
msgid "ApprovalSettings|Prevent approvals by users who add commits."
msgstr "Заборонити ÑÑ…Ð²Ð°Ð»ÐµÐ½Ð½Ñ ÐºÐ¾Ñ€Ð¸Ñтувачами, Ñкі додають коміти."
msgid "ApprovalSettings|Prevent editing approval rules in merge requests"
-msgstr ""
+msgstr "Заборонити Ñ€ÐµÐ´Ð°Ð³ÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ñ€Ð°Ð²Ð¸Ð» Ð·Ð°Ñ‚Ð²ÐµÑ€Ð´Ð¶ÐµÐ½Ð½Ñ Ñƒ запитах на злиттÑ"
msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests."
msgstr "Заборонити редагувати правила ÑÑ…Ð²Ð°Ð»ÐµÐ½Ð½Ñ Ñƒ проєктах та запитах на злиттÑ."
msgid "ApprovalSettings|Remove all approvals when commits are added to the source branch"
-msgstr ""
+msgstr "Видалити вÑÑ– затвердженнÑ, коли коміти додаютьÑÑ Ð´Ð¾ гілки-джерела"
msgid "ApprovalSettings|Require user password to approve"
-msgstr ""
+msgstr "Вимагати пароль кориÑтувача Ð´Ð»Ñ Ð·Ð°Ñ‚Ð²ÐµÑ€Ð´Ð¶ÐµÐ½Ð½Ñ"
msgid "ApprovalSettings|There was an error loading merge request approval settings."
msgstr "Під Ñ‡Ð°Ñ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½ÑŒ ÑÑ…Ð²Ð°Ð»ÐµÐ½Ð½Ñ Ð·Ð°Ð¿Ð¸Ñ‚Ñƒ на Ð·Ð»Ð¸Ñ‚Ñ‚Ñ ÑталаÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ°."
@@ -4804,7 +4850,7 @@ msgid "ApprovalSettings|This setting is configured at the instance level and can
msgstr "Цей параметр налаштований на рівні інÑтанÑу Ñ– може бути змінений тільки адмініÑтратором."
msgid "ApprovalSettings|This setting is configured in %{groupName} and can only be changed in the group settings by an administrator or group owner."
-msgstr ""
+msgstr "Цей параметр налаштовано в %{groupName} Ñ– може бути змінене в налаштуваннÑÑ… групи лише адмініÑтратором або влаÑником групи."
msgid "ApprovalStatusTooltip|Adheres to separation of duties"
msgstr "ДотримуєтьÑÑ Ñ€Ð¾Ð·Ð¿Ð¾Ð´Ñ–Ð»Ñƒ обов'Ñзків"
@@ -4890,12 +4936,12 @@ msgstr "Заархівовані проєкти"
msgid "Archiving the project will make it entirely read-only. It is hidden from the dashboard and doesn't show up in searches. %{strong_start}The repository cannot be committed to, and no issues, comments, or other entities can be created.%{strong_end} %{link_start}Learn more.%{link_end}"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to delete this project?"
-msgstr "Ви ÐБСОЛЮТÐО ВПЕВÐЕÐІ що бажаєте видалити цей проєкт?"
-
msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
msgstr "Ви ÐБСОЛЮТÐО ВПЕВÐЕÐІ що бажаєте видалити цю групу?"
+msgid "Are you absolutely sure?"
+msgstr ""
+
msgid "Are you sure that you want to archive this project?"
msgstr "Ви впевнені, що хочете заархівувати цей проєкт?"
@@ -4906,7 +4952,7 @@ msgid "Are you sure you want to %{action} %{name}?"
msgstr "Ви впевнені , що ви хочете %{action}%{name}?"
msgid "Are you sure you want to approve %{user}?"
-msgstr ""
+msgstr "Ви впевнені, що хочете затвердити %{user}?"
msgid "Are you sure you want to attempt to merge?"
msgstr "Ви впевнені, що бажаєте Ñпробувати об'єднатиÑÑ?"
@@ -4929,12 +4975,18 @@ msgstr "Ви впевнені що хочете видалити цей %{typeOf
msgid "Are you sure you want to delete this SSH key?"
msgstr "Ви впевнені, що хочете видалити цей SSH-ключ?"
+msgid "Are you sure you want to delete this comment?"
+msgstr ""
+
msgid "Are you sure you want to delete this deploy key?"
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 label?"
+msgstr ""
+
msgid "Are you sure you want to delete this pipeline schedule?"
msgstr "Ви впевнені, що хочете видалити цей розклад Ð´Ð»Ñ ÐºÐ¾Ð½Ð²ÐµÑ”Ñ€Ð°?"
@@ -4950,9 +5002,6 @@ msgstr "Ви впевнені, що хочете видалити цей комÐ
msgid "Are you sure you want to discard your changes?"
msgstr "Ви впевнені, що хочете відхилити ваші зміни?"
-msgid "Are you sure you want to erase this build?"
-msgstr "Ви впевнені, що хочете видалити цей білд?"
-
msgid "Are you sure you want to import %d repository?"
msgid_plural "Are you sure you want to import %d repositories?"
msgstr[0] ""
@@ -5002,6 +5051,9 @@ msgstr "Ви впевнені, що хочете видалити цю іденÑ
msgid "Are you sure you want to remove this list?"
msgstr "Ви впевнені, що хочете видалити цей ÑпиÑок?"
+msgid "Are you sure you want to remove this nickname?"
+msgstr ""
+
msgid "Are you sure you want to reset the health check token?"
msgstr "Ви впевнені, що Ви хочете перегенерувати цей ключ перевірки працездатноÑÑ‚Ñ–?"
@@ -5014,12 +5066,12 @@ msgstr ""
msgid "Are you sure you want to revoke this %{type}? This action cannot be undone."
msgstr "Ви впевнені, що бажаєте видалити цей %{type}? Ð¦Ñ Ð´Ñ–Ñ Ð½Ðµ може бути ÑкаÑована."
-msgid "Are you sure you want to revoke this nickname?"
-msgstr "Ви впевнені, що хочете ÑкаÑувати цей пÑевдонім?"
-
msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
msgstr "Ви впевнені, що хочете відкликати цей перÑональний токен доÑтупу? Ð¦Ñ Ð´Ñ–Ñ Ð½Ðµ може бути ÑкаÑована."
+msgid "Are you sure you want to revoke this project access token? This action cannot be undone."
+msgstr ""
+
msgid "Are you sure you want to stop this environment?"
msgstr "Ви впевнені що хочете зупинити це Ñередовище?"
@@ -5087,7 +5139,7 @@ msgid "Ask someone with write access to resolve it."
msgstr "ПопроÑÑ–Ñ‚ÑŒ когоÑÑŒ із правом запиÑу вирішити цю проблему."
msgid "Ask your group owner to set up a group runner."
-msgstr ""
+msgstr "ПопроÑÑ–Ñ‚ÑŒ керівника групи налаштувати груповий Runner."
msgid "Assertion consumer service URL"
msgstr "URL-адреÑа Ñлужби обробника тверджень"
@@ -5123,7 +5175,7 @@ msgid "Assign reviewer(s)"
msgstr ""
msgid "Assign severity"
-msgstr ""
+msgstr "Призначити рівень"
msgid "Assign some issues to this milestone."
msgstr "Призначити деÑкі задачі до цього етапу."
@@ -5164,9 +5216,6 @@ msgstr "Призначено %{assigneeName}"
msgid "Assigned to %{assignee_name}"
msgstr "Призначено %{assignee_name}"
-msgid "Assigned to %{name}"
-msgstr "Призначено %{name}"
-
msgid "Assigned to me"
msgstr "Призначено мені"
@@ -5235,6 +5284,9 @@ msgstr[3] "Ð”Ð¾Ð´Ð°Ð²Ð°Ð½Ð½Ñ %d файлів"
msgid "Attaching the file failed."
msgstr "Ðе вдалоÑÑ Ð¿Ñ€Ð¸ÐºÑ€Ñ–Ð¿Ð¸Ñ‚Ð¸ файл."
+msgid "Attention"
+msgstr ""
+
msgid "Audit Events"
msgstr "Події аудиту"
@@ -5397,6 +5449,12 @@ msgstr "Ðвторизовано у"
msgid "Authorized applications (%{size})"
msgstr "Ðвторизовані заÑтоÑунки: (%{size})"
+msgid "AuthorizedApplication|Are you sure you want to revoke this application?"
+msgstr ""
+
+msgid "AuthorizedApplication|Revoke application"
+msgstr ""
+
msgid "Authors: %{authors}"
msgstr "Ðвтори: %{authors}"
@@ -5413,7 +5471,7 @@ msgid "Auto-cancel redundant pipelines"
msgstr "Ðвтоматичне ÑкаÑÑƒÐ²Ð°Ð½Ð½Ñ Ð½Ð°Ð´Ð»Ð¸ÑˆÐºÐ¾Ð²Ð¸Ñ… конвеєрів"
msgid "Auto-close referenced issues on default branch"
-msgstr ""
+msgstr "Пов'Ñзані задачі в гілці за замовчуваннÑм автоматично закриті"
msgid "AutoDevOps|%{auto_devops_start}Automate building, testing, and deploying%{auto_devops_end} your applications based on your continuous integration and delivery configuration. %{quickstart_start}How do I get started?%{quickstart_end}"
msgstr "%{auto_devops_start}Ðвтоматизуйте ÑтвореннÑ, теÑÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ñ‚Ð° розгортаннÑ%{auto_devops_end} ваших заÑтоÑунків на оÑнові вашої безперервної інтеграції та конфігурації розгортаннÑ. %{quickstart_start}Як розпочати роботу?%{quickstart_end}"
@@ -5491,7 +5549,7 @@ msgid "Automatic deployment rollbacks"
msgstr ""
msgid "Automatic event tracking provides a traceable history for audits."
-msgstr ""
+msgstr "Ðвтоматичне відÑÑ‚ÐµÐ¶ÐµÐ½Ð½Ñ Ð¿Ð¾Ð´Ñ–Ð¹ надає Ñ–Ñторію відÑÑ‚ÐµÐ¶ÐµÐ½Ð½Ñ Ð´Ð»Ñ Ð°ÑƒÐ´Ð¸Ñ‚Ñ–Ð²."
msgid "Automatically close associated incident when a recovery alert notification resolves an alert"
msgstr ""
@@ -5533,7 +5591,7 @@ msgid "Average per day: %{average}"
msgstr "Ð’ Ñередньому за день: %{average}"
msgid "Awaiting user signup"
-msgstr ""
+msgstr "ÐžÑ‡Ñ–ÐºÑƒÐ²Ð°Ð½Ð½Ñ Ñ€ÐµÑ”Ñтрації кориÑтувача"
msgid "Award added"
msgstr ""
@@ -5668,7 +5726,7 @@ msgid "Based on"
msgstr "Ðа оÑнові"
msgid "Basic information"
-msgstr ""
+msgstr "ОÑновна інформаціÑ"
msgid "Be careful. Changing the project's namespace can have unintended side effects."
msgstr "Будьте обережні. Зміна проÑтору імен проєкту може мати небажані побічні ефекти."
@@ -5698,7 +5756,7 @@ msgid "Below you will find all the groups that are public."
msgstr "Ðижче ви знайдете вÑÑ– загальнодоÑтупні групи."
msgid "Beta"
-msgstr ""
+msgstr "Бета"
msgid "Bi-weekly code coverage"
msgstr ""
@@ -5809,34 +5867,34 @@ msgid "Billings|Shared runners cannot be enabled until a valid credit card is on
msgstr ""
msgid "Billings|To use free CI/CD minutes on shared runners, you’ll need to validate your account with a credit card. If you prefer not to provide one, you can run pipelines by bringing your own runners and disabling shared runners for your project. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge your card, it will only be used for validation.%{strongEnd} %{linkStart}Learn more%{linkEnd}."
-msgstr ""
+msgstr "Ð”Ð»Ñ Ð²Ð¸ÐºÐ¾Ñ€Ð¸ÑÑ‚Ð°Ð½Ð½Ñ Ð²Ñ–Ð»ÑŒÐ½Ð¸Ñ… хвилин CI/CD на Ñпільних runner'ах, вам необхідно підтвердити ваш обліковий Ð·Ð°Ð¿Ð¸Ñ Ð·Ð° допомогою кредитної картки. Якщо ви не бажаєте Ñ—Ñ— надавати, ви можете запуÑкати конвеєри, додаючи ваші влаÑні runner'и та вимикаючи Ñпільні runner'и Ð´Ð»Ñ Ð²Ð°ÑˆÐ¾Ð³Ð¾ проєкту. Це необхідно Ð´Ð»Ñ Ð·Ð°Ð¿Ð¾Ð±Ñ–Ð³Ð°Ð½Ð½Ñ Ñ‚Ð° Ð·Ð¼ÐµÐ½ÑˆÐµÐ½Ð½Ñ Ð·Ð»Ð¾Ð²Ð¶Ð¸Ð²Ð°Ð½Ð½Ñ Ñ–Ð½Ñ„Ñ€Ð°Ñтруктурою GitLab. %{strongStart} Gitlab не буде ÑÑ‚Ñгувати кошти з вашої картки, вона необхідна лише Ð´Ð»Ñ Ð¿Ñ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¶ÐµÐ½Ð½Ñ Ð¾Ð±Ð»Ñ–ÐºÐ¾Ð²Ð¾Ð³Ð¾ запиÑу. %{strongEnd}%{linkStart}ДізнатиÑÑ Ð±Ñ–Ð»ÑŒÑˆÐµ%{linkEnd}."
msgid "Billings|To use free CI/CD minutes on shared runners, you’ll need to validate your account with a credit card. This is required to discourage and reduce abuse on GitLab infrastructure. %{strongStart}GitLab will not charge your card, it will only be used for validation.%{strongEnd}"
-msgstr ""
+msgstr "Ð”Ð»Ñ Ð²Ð¸ÐºÐ¾Ñ€Ð¸ÑÑ‚Ð°Ð½Ð½Ñ Ð²Ñ–Ð»ÑŒÐ½Ð¸Ñ… хвилин CI/CD на Ñпільних runner'ах, вам необхідно перевірити ваш обліковий Ð·Ð°Ð¿Ð¸Ñ Ð·Ð° допомогою кредитної картки. Це необхідно Ð´Ð»Ñ Ð·Ð°Ð¿Ð¾Ð±Ñ–Ð³Ð°Ð½Ð½Ñ Ñ‚Ð° Ð·Ð¼ÐµÐ½ÑˆÐµÐ½Ð½Ñ Ð·Ð»Ð¾Ð²Ð¶Ð¸Ð²Ð°Ð½Ð½Ñ Ñ–Ð½Ñ„Ñ€Ð°Ñтруктурою GitLab. %{strongStart} Gitlab не буде ÑÑ‚Ñгувати кошти з вашої картки, вона необхідна лише Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ²Ñ–Ñ€ÐºÐ¸ облікового запиÑу. %{strongEnd}"
msgid "Billings|User validation required"
msgstr ""
msgid "Billings|Validate account"
-msgstr ""
+msgstr "Підтвердити обліковий запиÑ"
msgid "Billings|Validate user account"
msgstr ""
msgid "Billings|You'll now be able to take advantage of free CI/CD minutes on shared runners."
-msgstr ""
+msgstr "Тепер ви зможете ÑкориÑтатиÑÑ Ð²Ñ–Ð»ÑŒÐ½Ð¸Ð¼Ð¸ хвилинами CI/CD на Ñпільних runner'ах."
msgid "Billings|Your account has been validated"
-msgstr ""
+msgstr "Ваш обліковий Ð·Ð°Ð¿Ð¸Ñ Ð±ÑƒÐ»Ð¾ перевірено"
msgid "Billing|%{user} was successfully approved"
-msgstr ""
+msgstr "%{user} було уÑпішно затверджено"
msgid "Billing|An email address is only visible for users with public emails."
msgstr ""
msgid "Billing|An error occurred while approving %{user}"
-msgstr ""
+msgstr "Виникла помилка під Ñ‡Ð°Ñ Ð·Ð°Ñ‚Ð²ÐµÑ€Ð´Ð¶ÐµÐ½Ð½Ñ %{user}"
msgid "Billing|An error occurred while getting a billable member details"
msgstr ""
@@ -5845,13 +5903,13 @@ msgid "Billing|An error occurred while loading billable members list"
msgstr ""
msgid "Billing|An error occurred while loading pending members list"
-msgstr ""
+msgstr "Виникла помилка під Ñ‡Ð°Ñ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ ÑпиÑку учаÑників в очікуванні"
msgid "Billing|An error occurred while removing a billable member"
msgstr ""
msgid "Billing|Awaiting member signup"
-msgstr ""
+msgstr "ÐžÑ‡Ñ–ÐºÑƒÐ²Ð°Ð½Ð½Ñ Ñ€ÐµÑ”Ñтрації учаÑника"
msgid "Billing|Cannot remove user"
msgstr ""
@@ -5917,7 +5975,7 @@ msgid "Blame"
msgstr "ВідповідальніÑÑ‚ÑŒ"
msgid "BlobViewer|View on %{environmentName}"
-msgstr ""
+msgstr "ПереглÑнути на %{environmentName}"
msgid "Block user"
msgstr "Заблокувати кориÑтувача"
@@ -5939,7 +5997,7 @@ msgid "Blocking"
msgstr "БлокуваннÑ"
msgid "Blocking issues"
-msgstr ""
+msgstr "Заблоковані задачі"
msgid "Blocks"
msgstr "Блокує"
@@ -6044,7 +6102,7 @@ msgid "Boards"
msgstr "Дошки"
msgid "Boards and board lists"
-msgstr ""
+msgstr "Дошки та ÑпиÑки дошок"
msgid "Boards|+ %{displayedIssuablesCount} more %{issuableType}"
msgid_plural "Boards|+ %{displayedIssuablesCount} more %{issuableType}s"
@@ -6130,7 +6188,7 @@ msgid "Boards|Retrieving blocking %{issuableType}s"
msgstr ""
msgid "Boards|View all blocking %{issuableType}s"
-msgstr ""
+msgstr "ПереглÑнути вÑÑ– Ð±Ð»Ð¾ÐºÑƒÐ²Ð°Ð½Ð½Ñ %{issuableType}"
msgid "Boards|View scope"
msgstr "ПереглÑнути облаÑÑ‚ÑŒ видимоÑÑ‚Ñ–"
@@ -6139,13 +6197,13 @@ msgid "Board|An error occurred while fetching the board, please try again."
msgstr ""
msgid "Board|Are you sure you want to delete this board?"
-msgstr ""
+msgstr "Ви дійÑно бажаєте видалити цю дошку?"
msgid "Board|Board scope"
msgstr "ОблаÑÑ‚ÑŒ заÑтоÑÑƒÐ²Ð°Ð½Ð½Ñ Ð´Ð¾ÑˆÐºÐ¸"
msgid "Board|Create board"
-msgstr ""
+msgstr "Створити дошку"
msgid "Board|Create new board"
msgstr "Створити нову дошку"
@@ -6388,10 +6446,10 @@ msgid "Bulk update"
msgstr "МаÑове оновленнÑ"
msgid "BulkImport| %{host} is running outdated GitLab version (v%{version})"
-msgstr ""
+msgstr "%{host} працює із заÑтарілою верÑією GitLab (v%{version})"
msgid "BulkImport|%{feature} (require v%{version})"
-msgstr ""
+msgstr "%{feature} (потрібна v%{version})"
msgid "BulkImport|Existing groups"
msgstr "ІÑнуючі групи"
@@ -6400,7 +6458,7 @@ msgid "BulkImport|Filter by source group"
msgstr ""
msgid "BulkImport|Following data will not be migrated: %{bullets} Contact system administrator of %{host} to upgrade GitLab if you need this data in your migration"
-msgstr ""
+msgstr "Такі дані не будуть перенеÑені: %{bullets} ЗвернітьÑÑ Ð´Ð¾ ÑиÑтемного адмініÑтратора %{host} Ð´Ð»Ñ Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ GitLab, Ñкщо вам необхідно перенеÑти ці дані"
msgid "BulkImport|From source group"
msgstr "З групи джерел"
@@ -6442,7 +6500,7 @@ msgid "BulkImport|No parent"
msgstr "Ðемає батьківÑького елемента"
msgid "BulkImport|Re-import creates a new group. It does not sync with the existing group."
-msgstr ""
+msgstr "Повторний імпорт Ñтворює нову групу. Він не ÑинхронізуєтьÑÑ Ð· наÑвною групою."
msgid "BulkImport|Showing %{start}-%{end} of %{total}"
msgstr "Показано %{start}-%{end} із %{total}"
@@ -6520,13 +6578,13 @@ msgid "By default, all projects and groups will use the global notifications set
msgstr "За замовчуваннÑм уÑÑ– проєкти та групи будуть викориÑтовувати глобальні Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ñповіщень."
msgid "By month"
-msgstr ""
+msgstr "За міÑÑць"
msgid "By quarter"
-msgstr ""
+msgstr "Щоквартально"
msgid "By week"
-msgstr ""
+msgstr "За тиждень"
msgid "ByAuthor|by"
msgstr "від"
@@ -6541,7 +6599,7 @@ msgid "CI configuration validated, including all configuration added with the %{
msgstr ""
msgid "CI settings"
-msgstr "ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ CI"
+msgstr "Параметри CI"
msgid "CI variables"
msgstr "Змінні CI"
@@ -6596,19 +6654,22 @@ msgid "CICDAnalytics|Releases"
msgstr "Релізів"
msgid "CICDAnalytics|Shared Runners Usage"
+msgstr "ВикориÑÑ‚Ð°Ð½Ð½Ñ Ñпільних runner'ів"
+
+msgid "CICDAnalytics|Shared runner pipeline minute duration by month"
msgstr ""
msgid "CICDAnalytics|Shared runner usage"
-msgstr ""
+msgstr "ВикориÑÑ‚Ð°Ð½Ð½Ñ Ñпільних runner'ів"
msgid "CICDAnalytics|Shared runner usage is the total runtime of all jobs that ran on shared runners"
-msgstr ""
+msgstr "ВикориÑÑ‚Ð°Ð½Ð½Ñ Ñпільних runner'ів - це загальний Ñ‡Ð°Ñ Ð²Ð¸ÐºÐ¾Ð½Ð°Ð½Ð½Ñ Ð²ÑÑ–Ñ… завдань, що виконувалиÑÑŒ на Ñпільних runner'ах"
msgid "CICDAnalytics|Something went wrong while fetching release statistics"
msgstr ""
msgid "CICDAnalytics|What is shared runner usage?"
-msgstr ""
+msgstr "Що таке викориÑÑ‚Ð°Ð½Ð½Ñ Ñпільних runner'ів?"
msgid "CICD|Add a %{base_domain_link_start}base domain%{link_end} to your %{kubernetes_cluster_link_start}Kubernetes cluster%{link_end} for your deployment strategy to work."
msgstr "Додайти %{base_domain_link_start}базовий домен%{link_end} у Ñвій %{kubernetes_cluster_link_start} клаÑтер Kubernetes%{link_end}, щоб ваша ÑÑ‚Ñ€Ð°Ñ‚ÐµÐ³Ñ–Ñ Ñ€Ð¾Ð·Ð³Ð¾Ñ€Ñ‚Ð°Ð½Ð½Ñ Ð¿Ñ€Ð°Ñ†ÑŽÐ²Ð°Ð»Ð°."
@@ -6668,7 +6729,7 @@ msgid "CLOSED (MOVED)"
msgstr "ЗÐКРИТО (ПЕРЕМІЩЕÐО)"
msgid "CODEOWNERS rule violation"
-msgstr ""
+msgstr "ÐŸÐ¾Ñ€ÑƒÑˆÐµÐ½Ð½Ñ Ð¿Ñ€Ð°Ð²Ð¸Ð» CODEOWNERS"
msgid "CONTRIBUTING"
msgstr "CONTRIBUTING"
@@ -6677,7 +6738,7 @@ msgid "CPU"
msgstr "ЦП"
msgid "CSV is being generated and will be emailed to you upon completion."
-msgstr ""
+msgstr "CSV ÑтворюєтьÑÑ Ñ– буде надіÑлано вам електронною поштою піÑÐ»Ñ Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð½Ñ."
msgid "CVE|As a maintainer, requesting a CVE for a vulnerability in your project will help your users stay secure and informed."
msgstr ""
@@ -6739,6 +6800,9 @@ msgstr "Може бути перевизначено в кожному проєÐ
msgid "Can create groups:"
msgstr "Може Ñтворити групи:"
+msgid "Can not delete primary training"
+msgstr ""
+
msgid "Can't apply as the source branch was deleted."
msgstr "Ðе вдаєтьÑÑ Ð·Ð°ÑтоÑувати, оÑкільки гілку джерела видалено."
@@ -6845,7 +6909,7 @@ msgid "Cannot be merged automatically"
msgstr "Ðеможливо злити автоматично"
msgid "Cannot create the abuse report. The reported user was invalid. Please try again or contact support."
-msgstr ""
+msgstr "Ðеможливо Ñтворити звіт про зловживаннÑ. Повідомлений кориÑтувач недійÑний. Будь лаÑка, Ñпробуйте знову або звернітьÑÑ Ð´Ð¾ Ñлужби підтримки."
msgid "Cannot create the abuse report. The user has been deleted."
msgstr "Ðеможливо Ñтворити звіт про зловживаннÑ. КориÑтувача було видалено."
@@ -6860,7 +6924,7 @@ msgid "Cannot have multiple Jira imports running at the same time"
msgstr "Ðеможливо мати декілька імпортів Jira одночаÑно"
msgid "Cannot have multiple unresolved alerts"
-msgstr ""
+msgstr "Ðе може бути кілька невирішених попереджень"
msgid "Cannot import because issues are not available in this project."
msgstr "Ðе вдаєтьÑÑ Ñ–Ð¼Ð¿Ð¾Ñ€Ñ‚ÑƒÐ²Ð°Ñ‚Ð¸, тому що задачі не доÑтупні в цьому проєкті."
@@ -7072,9 +7136,6 @@ msgstr "Зміни в заголовку не збережені"
msgid "Changing any setting here requires an application restart"
msgstr ""
-msgid "Changing group URL can have unintended side effects."
-msgstr "Зміна групи URL-адреÑи може мати небажані побічні ефекти."
-
msgid "Charts can't be displayed as the request for data has timed out. %{documentationLink}"
msgstr "Графіки не можуть відображатиÑÑ, оÑкільки вичерпано Ñ‡Ð°Ñ Ð·Ð°Ð¿Ð¸Ñ‚Ñƒ даних. %{documentationLink}"
@@ -7162,9 +7223,6 @@ msgstr "Перевірка ÑтатуÑу затвердженнÑ"
msgid "Checking branch availability..."
msgstr "Перевірка доÑтупноÑÑ‚Ñ– гілки..."
-msgid "Checking group URL availability..."
-msgstr "Перевірка доÑтупноÑÑ‚Ñ– URL групи..."
-
msgid "Checking group path availability..."
msgstr "Перевірка доÑтупноÑÑ‚Ñ– шлÑху Ð´Ð»Ñ Ð³Ñ€ÑƒÐ¿Ð¸..."
@@ -7175,7 +7233,7 @@ msgid "Checkout"
msgstr "ÐžÑ„Ð¾Ñ€Ð¼Ð»ÐµÐ½Ð½Ñ Ð·Ð°Ð¼Ð¾Ð²Ð»ÐµÐ½Ð½Ñ"
msgid "Checkout|$%{selectedPlanPrice} per 10 GB storage pack per year"
-msgstr ""
+msgstr "$%{selectedPlanPrice} за 10 ГБ Ñховища на рік"
msgid "Checkout|$%{selectedPlanPrice} per pack of 1,000 minutes"
msgstr "$%{selectedPlanPrice} за пакет 1000 хвилин"
@@ -7231,7 +7289,7 @@ msgid "Checkout|(x%{quantity})"
msgstr "(x%{quantity})"
msgid "Checkout|An unknown error has occurred. Please try again by refreshing this page."
-msgstr ""
+msgstr "Виникла невідома помилка. Будь лаÑка, Ñпробуйте знову, оновивши цю Ñторінку."
msgid "Checkout|Billing address"
msgstr "Платіжна адреÑа"
@@ -7411,7 +7469,7 @@ msgid "Child"
msgstr "Дочірний"
msgid "Child epic"
-msgstr ""
+msgstr "Дочірній епік"
msgid "Child epic does not exist."
msgstr "Дочірній епік не Ñ–Ñнує."
@@ -7657,11 +7715,14 @@ msgid "Clear due date"
msgstr "ОчиÑтити дату завершеннÑ"
msgid "Clear health status"
-msgstr ""
+msgstr "ОчиÑтити працездатніÑÑ‚ÑŒ"
msgid "Clear recent searches"
msgstr "ОчиÑтити недавні пошуки"
+msgid "Clear repository checks"
+msgstr ""
+
msgid "Clear search"
msgstr "ОчиÑтити пошук"
@@ -7678,13 +7739,13 @@ msgid "Clear weight"
msgstr "ОчиÑтити вагу"
msgid "Cleared health status."
-msgstr ""
+msgstr "ПрацездатніÑÑ‚ÑŒ очищена."
msgid "Cleared weight."
msgstr "Вагу очищено."
msgid "Clears health status."
-msgstr ""
+msgstr "Очищає працездатніÑÑ‚ÑŒ."
msgid "Clears weight."
msgstr "Очищає вагу."
@@ -7720,7 +7781,7 @@ msgid "Clients"
msgstr "Клієнти"
msgid "Clientside DSN"
-msgstr ""
+msgstr "КлієнтÑький DSN"
msgid "Clone"
msgstr "Клонувати"
@@ -7794,9 +7855,6 @@ msgstr "Закрито %{epicTimeagoDate}"
msgid "Closed MRs"
msgstr "Закриті запити"
-msgid "Closed epics"
-msgstr "Закриті епіки"
-
msgid "Closed issues"
msgstr "Закриті задачі"
@@ -7810,10 +7868,10 @@ msgid "Closes this %{quick_action_target}."
msgstr "Закриває %{quick_action_target}."
msgid "Cloud Run"
-msgstr ""
+msgstr "Cloud Run"
msgid "Cloud Storage"
-msgstr ""
+msgstr "Хмарне Ñховище даних"
msgid "Cluster"
msgstr "КлаÑтер"
@@ -7833,29 +7891,29 @@ msgstr ""
msgid "Cluster level"
msgstr "Рівень клаÑтера"
-msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
+msgid "Cluster type must be specified for Stages::ClusterEndpointInserter"
msgstr ""
msgid "ClusterAgents|%{name} successfully deleted"
-msgstr ""
+msgstr "%{name} уÑпішно видалено"
-msgid "ClusterAgents|%{number} of %{total} Agents"
+msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
-msgstr ""
+msgstr "%{number} з %{total} клаÑтерів, підключених через Ñертифікати клаÑтера"
msgid "ClusterAgents|%{titleIcon}Connected"
msgstr "%{titleIcon}Підключено"
msgid "ClusterAgents|%{titleIcon}Not connected"
-msgstr ""
+msgstr "%{titleIcon}Ðе підключено"
msgid "ClusterAgents|%{tokenName} created"
msgstr "%{tokenName} Ñтворено"
msgid "ClusterAgents|%{tokenName} revoked"
-msgstr ""
+msgstr "%{tokenName} відкликано"
msgid "ClusterAgents|Access tokens"
msgstr "Токени доÑтупу"
@@ -7867,37 +7925,46 @@ msgid "ClusterAgents|Advanced installation methods"
msgstr "Додаткові методи вÑтановленнÑ"
msgid "ClusterAgents|Agent"
-msgstr ""
+msgstr "Ðгент"
msgid "ClusterAgents|Agent %{strongStart}connected%{strongEnd}"
-msgstr ""
+msgstr "Ðгент %{strongStart}підключено%{strongEnd}"
msgid "ClusterAgents|Agent %{strongStart}disconnected%{strongEnd}"
-msgstr ""
+msgstr "Ðгент %{strongStart}відключений%{strongEnd}"
msgid "ClusterAgents|Agent might not be connected to GitLab"
-msgstr ""
+msgstr "Ðгент не може підключитиÑÑ Ð´Ð¾ Gitlab"
msgid "ClusterAgents|Agent never connected to GitLab"
msgstr "Agent ніколи не підключаєтьÑÑ Ð´Ð¾ GitLab"
+msgid "ClusterAgents|Agent version mismatch"
+msgstr ""
+
+msgid "ClusterAgents|Agent version mismatch and update"
+msgstr ""
+
+msgid "ClusterAgents|Agent version update required"
+msgstr ""
+
msgid "ClusterAgents|All"
msgstr "Ð’ÑÑ–"
msgid "ClusterAgents|An error occurred while loading your Agents"
-msgstr ""
+msgstr "СталаÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ° при завантаженні ваших агентів"
msgid "ClusterAgents|An error occurred while loading your agent"
msgstr "СталаÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ° при завантаженні вашого агента"
msgid "ClusterAgents|An error occurred while retrieving GitLab Agent activity. Reload the page to try again."
-msgstr ""
+msgstr "СталаÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ° під Ñ‡Ð°Ñ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ Ð°ÐºÑ‚Ð¸Ð²Ð½Ð¾ÑÑ‚Ñ– GitLab Agent. Перезавантажте Ñторінку, щоб Ñпробувати знову."
msgid "ClusterAgents|An unknown error occurred. Please try again."
msgstr "СталаÑÑ Ð½ÐµÐ²Ñ–Ð´Ð¾Ð¼Ð° помилка, Ñпробуйте ще раз."
msgid "ClusterAgents|Are you sure you want to delete this agent? You cannot undo this."
-msgstr ""
+msgstr "Ви впевнені, що хочете видалити цього агента? Ви не можете ÑкаÑовувати це."
msgid "ClusterAgents|Certificate"
msgstr "Сертифікат"
@@ -7905,22 +7972,22 @@ msgstr "Сертифікат"
msgid "ClusterAgents|Configuration"
msgstr "КонфігураціÑ"
-msgid "ClusterAgents|Connect a cluster through the Agent"
+msgid "ClusterAgents|Connect a cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connect existing cluster"
-msgstr ""
+msgstr "Підключити Ñ–Ñнуючий клаÑтер"
msgid "ClusterAgents|Connect with a certificate"
-msgstr ""
+msgstr "Підключити за допомогою Ñертифіката"
-msgid "ClusterAgents|Connect with agent"
+msgid "ClusterAgents|Connect with an agent"
msgstr ""
msgid "ClusterAgents|Connect with the GitLab Agent"
-msgstr ""
+msgstr "З'єднатиÑÑ Ð· GitLab Agent"
-msgid "ClusterAgents|Connect your cluster through the Agent"
+msgid "ClusterAgents|Connect your cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connected"
@@ -7957,30 +8024,33 @@ msgid "ClusterAgents|Description"
msgstr "ОпиÑ"
msgid "ClusterAgents|Event occurred"
-msgstr ""
+msgstr "ВідбулаÑÑ Ð¿Ð¾Ð´Ñ–Ñ"
msgid "ClusterAgents|Failed to register an agent"
-msgstr ""
+msgstr "Помилка реєÑтрації агента"
msgid "ClusterAgents|For the advanced installation method %{linkStart}see the documentation%{linkEnd}."
-msgstr ""
+msgstr "Ð”Ð»Ñ Ñ€Ð¾Ð·ÑˆÐ¸Ñ€ÐµÐ½Ð¾Ð³Ð¾ методу вÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ %{linkStart}див. документацію%{linkEnd}."
msgid "ClusterAgents|GitLab Agent"
-msgstr ""
+msgstr "Ðгент GitLab"
msgid "ClusterAgents|GitLab Agent for Kubernetes"
-msgstr ""
+msgstr "GitLab Ðгент Ð´Ð»Ñ Kubernetes"
msgid "ClusterAgents|Give feedback"
-msgstr ""
+msgstr "Ðадати відгук"
msgid "ClusterAgents|Go to the repository files"
-msgstr ""
+msgstr "Перейти до файлів репозиторію"
msgid "ClusterAgents|How to register an agent?"
+msgstr "Як зареєÑтрувати агента?"
+
+msgid "ClusterAgents|How to update an agent?"
msgstr ""
-msgid "ClusterAgents|Install new Agent"
+msgid "ClusterAgents|Install a new agent"
msgstr ""
msgid "ClusterAgents|Last connected %{timeAgo}."
@@ -7993,7 +8063,7 @@ msgid "ClusterAgents|Learn how to create an agent access token"
msgstr "ДізнайтеÑÑ, Ñк Ñтворити токен доÑтупу агентів"
msgid "ClusterAgents|Learn how to troubleshoot"
-msgstr ""
+msgstr "ДізнайтеÑÑ, Ñк уÑунути неполадки"
msgid "ClusterAgents|Make sure you are using a valid token."
msgstr "ПереконайтеÑÑ, що ви викориÑтовуєте дійÑний токен."
@@ -8007,11 +8077,11 @@ msgstr "Ðіколи"
msgid "ClusterAgents|Never connected"
msgstr "Ðіколи не підключавÑÑ"
-msgid "ClusterAgents|No Agents"
+msgid "ClusterAgents|No agents"
msgstr ""
msgid "ClusterAgents|No clusters connected through cluster certificates"
-msgstr ""
+msgstr "Ðемає клаÑтерів, підключених через Ñертифікати клаÑтера"
msgid "ClusterAgents|Not connected"
msgstr "Ðе підключений"
@@ -8035,59 +8105,62 @@ msgid "ClusterAgents|Registration token"
msgstr "РеєÑÑ‚Ñ€Ð°Ñ†Ñ–Ñ Ñ‚Ð¾ÐºÐµÐ½Ð°"
msgid "ClusterAgents|Requires a Maintainer or greater role to delete agents"
-msgstr ""
+msgstr "Ð”Ð»Ñ Ð²Ð¸Ð´Ð°Ð»ÐµÐ½Ð½Ñ Ð°Ð³ÐµÐ½Ñ‚Ñ–Ð² потрібна роль Керівника або вища"
msgid "ClusterAgents|Requires a Maintainer or greater role to install new agents"
-msgstr ""
+msgstr "Ð”Ð»Ñ Ð²ÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð½Ð¾Ð²Ð¸Ñ… агентів потрібна роль Керівника або вища"
msgid "ClusterAgents|Requires a Maintainer or greater role to perform these actions"
-msgstr ""
+msgstr "Потрібна роль Керівника або більша, Ð´Ð»Ñ Ð²Ð¸ÐºÐ¾Ð½Ð°Ð½Ð½Ñ Ñ†Ð¸Ñ… дій"
msgid "ClusterAgents|Requires a maintainer or greater role to connect existing clusters"
-msgstr ""
+msgstr "Потрібна роль Керівника або вища, Ð´Ð»Ñ Ð¿Ñ–Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð½Ñ Ñ–Ñнуючих клаÑтерів"
msgid "ClusterAgents|Security"
msgstr "Безпека"
msgid "ClusterAgents|See Agent activity updates such as tokens created or revoked and clusters connected or not connected."
-msgstr ""
+msgstr "Див. Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð°ÐºÑ‚Ð¸Ð²Ð½Ð¾ÑÑ‚Ñ– агента, наприклад Ñтворені або відкликані токени, підключені чи не підключені клаÑтери."
msgid "ClusterAgents|Select an agent"
msgstr "Вибрати агента"
msgid "ClusterAgents|Select an agent to register with GitLab"
-msgstr ""
+msgstr "Виберіть агента Ð´Ð»Ñ Ñ€ÐµÑ”Ñтрації в GitLab"
msgid "ClusterAgents|Tell us what you think"
-msgstr ""
+msgstr "Розкажіть нам, що ви думаєте"
msgid "ClusterAgents|The GitLab Agent provides an increased level of security when connecting Kubernetes clusters to GitLab. %{linkStart}Learn more about the GitLab Agent.%{linkEnd}"
-msgstr ""
+msgstr "GitLab Agent забезпечує підвищений рівень безпеки при підключенні Kubernetes-клаÑтерів до GitLab. %{linkStart}ДізнатиÑÑ Ð±Ñ–Ð»ÑŒÑˆÐµ про GitLab Agent.%{linkEnd}"
msgid "ClusterAgents|The agent has not been connected in a long time. There might be a connectivity issue. Last contact was %{timeAgo}."
+msgstr "Ðгент не був підключений протÑгом тривалого чаÑу. Можливо, виникла проблема з підключеннÑм. ОÑтанній Ñ‡Ð°Ñ Ð·'Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð±ÑƒÐ² %{timeAgo}."
+
+msgid "ClusterAgents|The agent version do not match each other across your cluster's pods. This can happen when a new agent version was just deployed and Kubernetes is shutting down the old pods."
msgstr ""
msgid "ClusterAgents|The recommended installation method includes the token. If you want to follow the advanced installation method provided in the docs, make sure you save the token value before you close this window."
-msgstr ""
+msgstr "Рекомендований метод вÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð²ÐºÐ»ÑŽÑ‡Ð°Ñ” токен. Якщо ви хочете дотримуватиÑÑ Ñ€Ð¾Ð·ÑˆÐ¸Ñ€ÐµÐ½Ð¾Ð³Ð¾ ÑпоÑобу вÑтановленнÑ, зазначеного в документації, переконайтеÑÑ, що зберегли Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ñ‚Ð¾ÐºÐµÐ½Ð° перед закриттÑм цього вікна."
msgid "ClusterAgents|The registration token will be used to connect the agent on your cluster to GitLab. %{linkStart}What are registration tokens?%{linkEnd}"
-msgstr ""
+msgstr "Токен реєÑтрації буде викориÑтовуватиÑÑ Ð´Ð»Ñ Ð¿Ñ–Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð½Ñ Ð°Ð³ÐµÐ½Ñ‚Ð° на вашому клаÑтері до GitLab. %{linkStart}Що таке реєÑтраційні токени?%{linkEnd}"
msgid "ClusterAgents|There's no activity from the past day"
msgid_plural "ClusterAgents|There's no activity from the past %d days"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-msgstr[3] ""
+msgstr[0] "Ðемає активноÑÑ‚Ñ– за минулий день"
+msgstr[1] "Ðемає активноÑтей за минулі %d дні"
+msgstr[2] "Ðемає активноÑтей за минулих %d днів"
+msgstr[3] "Ðемає активноÑтей за минулих %d днів"
msgid "ClusterAgents|This agent has no tokens"
msgstr "Цей агент не має токенів"
msgid "ClusterAgents|To delete the agent, type %{name} to confirm:"
-msgstr ""
+msgstr "Щоб видалити агента, введіть %{name} Ð´Ð»Ñ Ð¿Ñ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¶ÐµÐ½Ð½Ñ:"
msgid "ClusterAgents|To install a new agent, first add the agent's configuration file to this repository. %{linkStart}Learn more about installing GitLab Agent.%{linkEnd}"
-msgstr ""
+msgstr "Щоб вÑтановити новий агент, Ñпочатку додайте файл конфігурації агента до цього репозиторію. %{linkStart}ДізнайтеÑÑ Ð±Ñ–Ð»ÑŒÑˆÐµ про вÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ GitLab Agent.%{linkEnd}"
msgid "ClusterAgents|Token created by %{userName}"
msgstr "Токен, Ñтворений %{userName}"
@@ -8099,26 +8172,29 @@ msgid "ClusterAgents|Unknown user"
msgstr "Ðевідомий кориÑтувач"
msgid "ClusterAgents|View all %{number} agents"
-msgstr ""
+msgstr "ПереглÑнути вÑÑ– %{number} агентів"
msgid "ClusterAgents|View all %{number} clusters"
-msgstr ""
+msgstr "ПереглÑнути вÑÑ– %{number} клаÑтери"
msgid "ClusterAgents|We would love to learn more about your experience with the GitLab Agent."
-msgstr ""
+msgstr "Ми хотіли б дізнатиÑÑŒ більше про ваш доÑвід з GitLab Agent."
msgid "ClusterAgents|What is GitLab Agent activity?"
-msgstr ""
+msgstr "Що таке активніÑÑ‚ÑŒ GitLab Agent?"
msgid "ClusterAgents|You cannot see this token again after you close this window."
-msgstr ""
+msgstr "Ви більше не зможете побачити цей токен піÑÐ»Ñ Ð·Ð°ÐºÑ€Ð¸Ñ‚Ñ‚Ñ Ñ†ÑŒÐ¾Ð³Ð¾ вікна."
msgid "ClusterAgents|You will need to create a token to connect to your agent"
msgstr "Вам потрібно Ñтворити токен Ð´Ð»Ñ Ð¿Ñ–Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð½Ñ Ð´Ð¾ вашого агента"
-msgid "ClusterAgents|Your instance doesn't have the %{linkStart}GitLab Agent Server (KAS)%{linkEnd} set up. Ask a GitLab Administrator to install it."
+msgid "ClusterAgents|Your agent version is out of sync with your GitLab version (v%{version}), which might cause compatibility problems. Update the agent installed on your cluster to the most recent version."
msgstr ""
+msgid "ClusterAgents|Your instance doesn't have the %{linkStart}GitLab Agent Server (KAS)%{linkEnd} set up. Ask a GitLab Administrator to install it."
+msgstr "У вашому інÑтанÑÑ– не налаштовано %{linkStart}GitLab Agent Server (KAS)%{linkEnd} ПопроÑÑ–Ñ‚ÑŒ адмініÑтратора GitLab вÑтановити його."
+
msgid "ClusterAgent|User has insufficient permissions to create a token for this project"
msgstr "КориÑтувач не має доÑтатніх прав Ð´Ð»Ñ ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ñ‚Ð¾ÐºÐµÐ½Ð° Ð´Ð»Ñ Ñ†ÑŒÐ¾Ð³Ð¾ проєкту"
@@ -8267,10 +8343,10 @@ msgid "ClusterIntegration|Connect existing cluster"
msgstr "Підключити Ñ–Ñнуючий клаÑтер"
msgid "ClusterIntegration|Connect with a certificate"
-msgstr ""
+msgstr "Підключити за допомогою Ñертифікату"
msgid "ClusterIntegration|Connect your cluster to GitLab through %{linkStart}cluster certificates%{linkEnd}."
-msgstr ""
+msgstr "Підключити ваш клаÑтер до GitLab через %{linkStart}клаÑтерні Ñертифікати%{linkEnd}."
msgid "ClusterIntegration|Connection Error"
msgstr "Помилка підключеннÑ"
@@ -8765,7 +8841,7 @@ msgid "ClusterIntegration|The URL used to access the Kubernetes API."
msgstr "URL-адреÑа, що викориÑтовуєтьÑÑ Ð´Ð»Ñ Ð´Ð¾Ñтупу до Kubernetes API."
msgid "ClusterIntegration|The certificate-based method to connect clusters to GitLab was %{linkStart}deprecated%{linkEnd} in GitLab 14.5."
-msgstr ""
+msgstr "СпоÑіб Ð¿Ñ–Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð½Ñ ÐºÐ»Ð°Ñтерів до GitLab через Ñертифікати %{linkStart}заÑтарілий%{linkEnd} у GitLab 14.5."
msgid "ClusterIntegration|The namespace associated with your project. This will be used for deploy boards, logs, and Web terminals."
msgstr ""
@@ -8992,9 +9068,6 @@ msgstr "ComboSearch не визначено"
msgid "Comma-separated list of email addresses."
msgstr "СпиÑок Ð°Ð´Ñ€ÐµÑ ÐµÐ»ÐµÐºÑ‚Ñ€Ð¾Ð½Ð½Ð¾Ñ— пошти, відокремлених комами."
-msgid "Comma-separated list of users allowed to exceed the rate limit."
-msgstr "Відокремлений комами ÑпиÑок кориÑтувачів, Ñким дозволено перевищувати ліміт допуÑтимого."
-
msgid "Comma-separated, e.g. '1.1.1.1, 2.2.2.0/24'"
msgstr "Розділений комами, напр. '1.1.1.1, 2.2.0/24'"
@@ -9060,7 +9133,7 @@ msgid "Commit Message"
msgstr "ÐŸÐ¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ ÐºÐ¾Ð¼Ñ–Ñ‚Ñƒ"
msgid "Commit SHA"
-msgstr ""
+msgstr "Коміт SHA"
msgid "Commit changes"
msgstr "ЗафікÑувати зміни"
@@ -9303,16 +9376,16 @@ msgid "ComplianceFramework|New compliance framework"
msgstr "Ðова оболонка Ð´Ð»Ñ Ð²Ñ–Ð´Ð¿Ð¾Ð²Ñ–Ð´Ð½Ð¾ÑÑ‚Ñ–"
msgid "ComplianceReport|Approved by author"
-msgstr ""
+msgstr "Затверджено автором"
msgid "ComplianceReport|Approved by committer"
-msgstr ""
+msgstr "Затверджено комітером"
msgid "ComplianceReport|Less than 2 approvers"
-msgstr ""
+msgstr "Менше, ніж 2 затверджувачі"
msgid "ComplianceReport|No violations found"
-msgstr ""
+msgstr "ÐŸÐ¾Ñ€ÑƒÑˆÐµÐ½Ð½Ñ Ð½Ðµ виÑвлені"
msgid "Component"
msgstr "Компонент"
@@ -9323,6 +9396,12 @@ msgstr "ВпевненіÑÑ‚ÑŒ"
msgid "Confidential"
msgstr "Конфіденційний"
+msgid "Confidential issue"
+msgstr ""
+
+msgid "Confidential note"
+msgstr ""
+
msgid "Confidentiality"
msgstr "КонфіденційніÑÑ‚ÑŒ"
@@ -9348,7 +9427,7 @@ msgid "Configure Container Scanning in `.gitlab-ci.yml` using the GitLab managed
msgstr ""
msgid "Configure Container Scanning in `.gitlab-ci.yml`, creating this file if it does not already exist"
-msgstr ""
+msgstr "Ðалаштуйте ÑÐºÐ°Ð½ÑƒÐ²Ð°Ð½Ð½Ñ ÐºÐ¾Ð½Ñ‚ÐµÐ¹Ð½ÐµÑ€Ñ–Ð² в `.gitlab-ci.yml`, Ñтворивши цей файл, Ñкщо його ще не Ñ–Ñнує"
msgid "Configure Dependency Scanning in `.gitlab-ci.yml` using the GitLab managed template. You can [add variable overrides](https://docs.gitlab.com/ee/user/application_security/dependency_scanning/#customizing-the-dependency-scanning-settings) to customize Dependency Scanning settings."
msgstr "ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ ÑÐºÐ°Ð½ÑƒÐ²Ð°Ð½Ð½Ñ Ð·Ð°Ð»ÐµÐ¶Ð½Ð¾Ñтей в `.gitlab-ci.yml` викориÑтовуючи керований шаблон GitLab. Ви можете [додати змінну overrides](https://docs.gitlab.com/ee/user/application_security/dependency_scanning/#customizing-the-dependency-scanning-settings), щоб налаштувати Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ ÑÐºÐ°Ð½ÑƒÐ²Ð°Ð½Ð½Ñ Ð·Ð°Ð»ÐµÐ¶Ð½Ð¾Ñтей."
@@ -9356,6 +9435,9 @@ msgstr "ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ ÑÐºÐ°Ð½ÑƒÐ²Ð°Ð½Ð½Ñ Ð·Ð°Ð»ÐµÐ¶Ð½Ð¾Ñтей в
msgid "Configure Dependency Scanning in `.gitlab-ci.yml`, creating this file if it does not already exist"
msgstr "ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ ÑÐºÐ°Ð½ÑƒÐ²Ð°Ð½Ð½Ñ Ð·Ð°Ð»ÐµÐ¶Ð½Ð¾Ñтей в `.gitlab-ci.yml`, ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ñ†ÑŒÐ¾Ð³Ð¾ файлу, Ñкщо він ще не Ñ–Ñнує"
+msgid "Configure GitLab"
+msgstr ""
+
msgid "Configure GitLab runners to start using the Web Terminal. %{helpStart}Learn more.%{helpEnd}"
msgstr "Ðалаштувати runner'ів GitLab Ð´Ð»Ñ Ð¿Ð¾Ñ‡Ð°Ñ‚ÐºÑƒ викориÑÑ‚Ð°Ð½Ð½Ñ Ð’ÐµÐ±-терміналу. %{helpStart}Докладніше.%{helpEnd}"
@@ -9372,7 +9454,7 @@ msgid "Configure SAST IaC in `.gitlab-ci.yml` using the GitLab managed template.
msgstr ""
msgid "Configure SAST IaC in `.gitlab-ci.yml`, creating this file if it does not already exist"
-msgstr ""
+msgstr "Ðалаштуйте SAST IaC в `.gitlab-ci.yml`, Ñтворивши цей файл, Ñкщо його ще не Ñ–Ñнує"
msgid "Configure SAST in `.gitlab-ci.yml` using the GitLab managed template. You can [add variable overrides](https://docs.gitlab.com/ee/user/application_security/sast/#customizing-the-sast-settings) to customize SAST settings."
msgstr "ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ SAST в `.gitlab-ci.yml` викориÑтовуючи керований шаблон GitLab. Ви можете [налаштувати змінні](https://docs.gitlab.com/ee/user/application_security/sast/#customizing-the-sast-settings) Ð´Ð»Ñ Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ SAST."
@@ -9387,7 +9469,7 @@ msgid "Configure Secret Detection in `.gitlab-ci.yml`, creating this file if it
msgstr "Ðалаштуйте виÑÐ²Ð»ÐµÐ½Ð½Ñ Secret Detection в `.gitlab-ci.yml`, ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ñ†ÑŒÐ¾Ð³Ð¾ файлу, Ñкщо він ще не Ñ–Ñнує"
msgid "Configure Sentry integration for error tracking"
-msgstr ""
+msgstr "Ðалаштуйте інтеграцію Sentry Ð´Ð»Ñ Ð²Ñ–Ð´ÑÑ‚ÐµÐ¶ÐµÐ½Ð½Ñ Ð¿Ð¾Ð¼Ð¸Ð»Ð¾Ðº"
msgid "Configure Tracing"
msgstr "ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð’Ñ–Ð´ÑтеженнÑ"
@@ -9396,7 +9478,7 @@ msgid "Configure a %{codeStart}.gitlab-webide.yml%{codeEnd} file in the %{codeSt
msgstr "Ðалаштуйте %{codeStart}.gitlab-webide.yml%{codeEnd} файл %{codeStart}.gitlab%{codeEnd} , щоб почати викориÑтовувати Веб-термінал. %{helpStart}Докладніше%{helpEnd}"
msgid "Configure advanced permissions, Large File Storage, two-factor authentication, and customer relations settings."
-msgstr ""
+msgstr "Ðалаштуйте додаткові права, Ñховище великих файлів, двофакторну автентифікацію та Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ñ€Ð¾Ð±Ð¾Ñ‚Ð¸ з клієнтами."
msgid "Configure existing installation"
msgstr "Ðалаштувати Ñ–Ñнуючу інÑталÑцію"
@@ -9404,6 +9486,15 @@ msgstr "Ðалаштувати Ñ–Ñнуючу інÑталÑцію"
msgid "Configure pipelines to deploy web apps, backend services, APIs and static resources to Google Cloud"
msgstr ""
+msgid "Configure region"
+msgstr ""
+
+msgid "Configure region for environment"
+msgstr ""
+
+msgid "Configure regions"
+msgstr ""
+
msgid "Configure repository mirroring."
msgstr "Ðалаштувати Ð²Ñ–Ð´Ð´Ð·ÐµÑ€ÐºÐ°Ð»ÐµÐ½Ð½Ñ Ñ€ÐµÐ¿Ð¾Ð·Ð¸Ñ‚Ð¾Ñ€Ñ–Ñ—Ð²."
@@ -9432,16 +9523,19 @@ msgid "Configure the way a user creates a new account."
msgstr "Ðалаштувати ÑпоÑіб ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ ÐºÐ¾Ñ€Ð¸Ñтувачем нового облікового запиÑу."
msgid "Configure via Merge Request"
-msgstr ""
+msgstr "Ðалаштувати через запит на злиттÑ"
msgid "Configure which lists are shown for anyone who visits this board"
msgstr ""
+msgid "Configure your environments to be deployed to specific geographical regions"
+msgstr ""
+
msgid "Confirm"
msgstr "Підтвердити"
msgid "Confirm approval"
-msgstr ""
+msgstr "Підтвердити затвердженнÑ"
msgid "Confirm new password"
msgstr "Підвердіть новий пароль"
@@ -9468,7 +9562,7 @@ msgid "Confirmed:"
msgstr "Підтверджено:"
msgid "Conflict: This file was added both in the source and target branches, but with different contents."
-msgstr ""
+msgstr "Конфлікт: цей файл було додано Ñк до гілки-джерела, так Ñ– до цільової гілки, але вміÑÑ‚ відрізнÑєтьÑÑ."
msgid "Conflict: This file was modified in both the source and target branches."
msgstr "Конфлікт: цей файл було змінено Ñк у гілці-джерелі, так Ñ– у цільовій гілці."
@@ -9662,7 +9756,7 @@ msgid "ContainerRegistry|Cleanup will run soon"
msgstr "ÐžÑ‡Ð¸Ñ‰ÐµÐ½Ð½Ñ Ð½ÐµÐ·Ð°Ð±Ð°Ñ€Ð¾Ð¼ запуÑтитьÑÑ"
msgid "ContainerRegistry|Configuration digest: %{digest}"
-msgstr ""
+msgstr "ДайджеÑÑ‚ конфігурації: %{digest}"
msgid "ContainerRegistry|Container Registry"
msgstr "РеєÑÑ‚Ñ€ контейнерів"
@@ -9755,7 +9849,7 @@ msgid "ContainerRegistry|Note: Any policy update will result in a change to the
msgstr "Примітка: Будь-Ñке Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð¿Ð¾Ð»Ñ–Ñ‚Ð¸ÐºÐ¸ призведе до зміни запланованої та чаÑу"
msgid "ContainerRegistry|Please try different search criteria"
-msgstr ""
+msgstr "Спробуйте інші критерії пошуку"
msgid "ContainerRegistry|Published %{timeInfo}"
msgstr "Опубліковано %{timeInfo}"
@@ -9849,7 +9943,7 @@ msgid "ContainerRegistry|The cleanup policy timed out before it could delete all
msgstr "Ð§Ð°Ñ Ð¾Ñ‡Ñ–ÐºÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ð¾Ð»Ñ–Ñ‚Ð¸ÐºÐ¸ Ð¾Ñ‡Ð¸Ñ‰ÐµÐ½Ð½Ñ Ð·Ð°ÐºÑ–Ð½Ñ‡Ð¸Ð²ÑÑ, перш ніж вона могла видалити вÑÑ– теги. ÐдмініÑтратор може %{adminLinkStart}вручну запуÑтити Ð¾Ñ‡Ð¸Ñ‰ÐµÐ½Ð½Ñ Ð·Ð°Ñ€Ð°Ð·%{adminLinkEnd} або ви можете зачекати, поки політика Ð¾Ñ‡Ð¸Ñ‰ÐµÐ½Ð½Ñ Ð·Ð½Ð¾Ð²Ñƒ запуÑтитьÑÑ Ð°Ð²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð¸Ñ‡Ð½Ð¾. %{docLinkStart}Додаткова інформаціÑ%{docLinkEnd}"
msgid "ContainerRegistry|The filter returned no results"
-msgstr ""
+msgstr "Фільтр не дав результатів"
msgid "ContainerRegistry|The image repository could not be found."
msgstr "Репозиторій образів не знайдено."
@@ -10083,7 +10177,7 @@ msgid "Copy evidence SHA"
msgstr "Скопіювати SHA даних"
msgid "Copy failed. Please manually copy the value."
-msgstr ""
+msgstr "Помилка копіюваннÑ. Будь лаÑка, Ñкопіюйте Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð²Ñ€ÑƒÑ‡Ð½Ñƒ."
msgid "Copy file contents"
msgstr "Скопіювати вміÑÑ‚ файлу"
@@ -10092,7 +10186,7 @@ msgid "Copy file path"
msgstr "Скопіювати шлÑÑ… до файлу"
msgid "Copy issue URL to clipboard"
-msgstr ""
+msgstr "Скопіювати URL задачі в буфер обміну"
msgid "Copy key"
msgstr "Копіювати ключ"
@@ -10145,26 +10239,26 @@ msgstr ""
msgid "CorpusManagement|Actions"
msgstr "Дії"
-msgid "CorpusManagement|Corpus are used in fuzz testing as mutation source to Improve future testing."
-msgstr ""
-
msgid "CorpusManagement|Corpus file"
+msgstr "Файл корпуÑу"
+
+msgid "CorpusManagement|Corpus files are used in coverage-guided fuzz testing as seed inputs to improve testing."
msgstr ""
msgid "CorpusManagement|Corpus files must be in *.zip format. Maximum 5 GB"
-msgstr ""
+msgstr "Файли корпуÑу мають бути у форматі *.zip. МакÑимум 5 ГБ"
msgid "CorpusManagement|Corpus name"
msgstr ""
msgid "CorpusManagement|Currently, there are no uploaded or generated corpuses."
-msgstr ""
+msgstr "Зараз немає завантажених або Ñтворених корпуÑів."
msgid "CorpusManagement|File too large, Maximum 5 GB"
-msgstr ""
+msgstr "Файл занадто великий, макÑимум 5 Гб"
msgid "CorpusManagement|Filename can contain only lowercase letters (a-z), uppercase letter (A-Z), numbers (0-9), dots (.), hyphens (-), or underscores (_)."
-msgstr ""
+msgstr "Ім'Ñ Ñ„Ð°Ð¹Ð»Ñƒ може міÑтити лише малі літери (a-z), великі літери (A-Z), цифри (0-9), крапки (.), дефіÑи (-) або знаки підкреÑÐ»ÐµÐ½Ð½Ñ (_)."
msgid "CorpusManagement|Fuzz testing corpus management"
msgstr ""
@@ -10202,6 +10296,9 @@ msgstr "Ðе вдалоÑÑ Ð´Ð¾Ð´Ð°Ñ‚Ð¸ адмініÑтраторів Ñк уÑ
msgid "Could not apply %{name} command."
msgstr "Ðе вдалоÑÑ Ð·Ð°ÑтоÑувати команду %{name}"
+msgid "Could not apply %{name} command. %{message}."
+msgstr ""
+
msgid "Could not authorize chat nickname. Try again!"
msgstr "Ðе вдалоÑÑ Ð°Ð²Ñ‚Ð¾Ñ€Ð¸Ð·ÑƒÐ²Ð°Ñ‚Ð¸ пÑевдонім Ð´Ð»Ñ Ñ‡Ð°Ñ‚Ñƒ. Спробуйте ще раз!"
@@ -10251,7 +10348,7 @@ msgid "Could not fetch policy because existing policy YAML is invalid"
msgstr ""
msgid "Could not fetch training providers. Please refresh the page, or try again later."
-msgstr ""
+msgstr "Ðе вдалоÑÑ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ñ‚Ð¸ тренінг-провайдери. Будь лаÑка, оновіть Ñторінку або Ñпробуйте пізніше."
msgid "Could not find design."
msgstr "Ðе вдалоÑÑ Ð·Ð½Ð°Ð¹Ñ‚Ð¸ дизайн."
@@ -10281,7 +10378,7 @@ msgid "Could not restore the group"
msgstr "Ðе вдалоÑÑ Ð²Ñ–Ð´Ð½Ð¾Ð²Ð¸Ñ‚Ð¸ групу"
msgid "Could not revoke access token %{access_token_name}."
-msgstr ""
+msgstr "Ðе вдалоÑÑ Ð²Ñ–Ð´ÐºÐ»Ð¸ÐºÐ°Ñ‚Ð¸ токен доÑтупу %{access_token_name}."
msgid "Could not revoke impersonation token %{token_name}."
msgstr "Ðеможливо відкликати токен Ñ–Ð¼Ñ–Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ %{token_name}."
@@ -10290,7 +10387,7 @@ msgid "Could not revoke personal access token %{personal_access_token_name}."
msgstr "Ðеможливо відкликати перÑональний токен доÑтупу %{personal_access_token_name}."
msgid "Could not save configuration. Please refresh the page, or try again later."
-msgstr ""
+msgstr "Ðе вдалоÑÑ Ð·Ð±ÐµÑ€ÐµÐ³Ñ‚Ð¸ конфігурацію. Будь лаÑка, оновіть Ñторінку або Ñпробуйте пізніше."
msgid "Could not save group ID"
msgstr "Ðе вдалоÑÑ Ð·Ð±ÐµÑ€ÐµÐ³Ñ‚Ð¸ ID групи."
@@ -10352,6 +10449,9 @@ msgstr "Спочатку Ñтворіть обліковий Ð·Ð°Ð¿Ð¸Ñ GitLab,
msgid "Create a Mattermost team for this group"
msgstr "Створити команду в Mattermost Ð´Ð»Ñ Ñ†Ñ–Ñ”Ñ— групи"
+msgid "Create a group"
+msgstr ""
+
msgid "Create a merge request"
msgstr "Створити запит на злиттÑ"
@@ -10376,6 +10476,9 @@ msgstr "Створити новий репозиторій"
msgid "Create a personal access token on your account to pull or push via %{protocol}."
msgstr "Створити токен доÑтупу Ð´Ð»Ñ Ð²Ð°ÑˆÐ¾Ð³Ð¾ аккаунта, щоб відправлÑти та отримувати через %{protocol}."
+msgid "Create a project"
+msgstr ""
+
msgid "Create an account using:"
msgstr "Створити обліковий Ð·Ð°Ð¿Ð¸Ñ Ð·Ð° допомогою:"
@@ -10434,7 +10537,7 @@ msgid "Create iteration"
msgstr "Створити ітерацію"
msgid "Create label"
-msgstr ""
+msgstr "Створити мітку"
msgid "Create list"
msgstr "Створити ÑпиÑок"
@@ -10461,7 +10564,7 @@ msgid "Create new CI/CD pipeline"
msgstr "Створити новий CI/CD конвеєр"
msgid "Create new Value Stream"
-msgstr ""
+msgstr "Створити нове Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð¿Ð¾Ñ‚Ð¾ÐºÑƒ"
msgid "Create new branch"
msgstr "Створити нову гілку"
@@ -10515,7 +10618,7 @@ msgid "Create user"
msgstr "Створити кориÑтувача"
msgid "Create via merge request"
-msgstr ""
+msgstr "Створити через запит на злиттÑ"
msgid "Create wildcard: %{searchTerm}"
msgstr "Створити шаблон: %{searchTerm}"
@@ -10569,7 +10672,7 @@ msgid "CreateValueStreamForm|Create new Value Stream"
msgstr ""
msgid "CreateValueStreamForm|Create value stream"
-msgstr ""
+msgstr "Створити потік значень"
msgid "CreateValueStreamForm|Default stages"
msgstr ""
@@ -10578,7 +10681,7 @@ msgid "CreateValueStreamForm|Default stages can only be hidden or re-ordered"
msgstr ""
msgid "CreateValueStreamForm|Edit value stream"
-msgstr ""
+msgstr "Редагувати потік значень"
msgid "CreateValueStreamForm|Editing stage"
msgstr ""
@@ -10695,7 +10798,7 @@ msgid "Created by:"
msgstr "Ðвтор:"
msgid "Created compliance violations if any were found"
-msgstr ""
+msgstr "Створено Ð¿Ð¾Ñ€ÑƒÑˆÐµÐ½Ð½Ñ Ð²Ñ–Ð´Ð¿Ð¾Ð²Ñ–Ð´Ð½Ð¾ÑÑ‚Ñ–, Ñкщо вони були виÑвлені"
msgid "Created date"
msgstr "Дата ÑтвореннÑ"
@@ -10739,6 +10842,9 @@ msgstr "Ð¡Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð³Ñ€Ð°Ñ„Ñ–ÐºÑ–Ð² викориÑтовує дані з
msgid "Creation date"
msgstr "Дата ÑтвореннÑ"
+msgid "Creator"
+msgstr ""
+
msgid "Credentials"
msgstr "Облікові дані"
@@ -10751,9 +10857,15 @@ msgstr "Облікові дані не знайдено"
msgid "CredentialsInventory|Personal Access Tokens"
msgstr "ОÑобиÑÑ‚Ñ– токени доÑтупу"
+msgid "CredentialsInventory|Project Access Tokens"
+msgstr ""
+
msgid "CredentialsInventory|SSH Keys"
msgstr "Ключі SSH"
+msgid "Credit card required to be on file in order to create a pipeline"
+msgstr ""
+
msgid "Credit card:"
msgstr "Кредитна картка:"
@@ -10761,31 +10873,31 @@ msgid "Critical vulnerabilities present"
msgstr "ПриÑутні критичні вразливоÑÑ‚Ñ–"
msgid "Crm|Contact has been added"
-msgstr ""
+msgstr "Контакт додано"
msgid "Crm|Contact has been updated"
-msgstr ""
+msgstr "Контакт оновлено"
msgid "Crm|Create new contact"
msgstr ""
msgid "Crm|Create organization"
-msgstr ""
+msgstr "Створити організацію"
msgid "Crm|Customer Relations Contacts"
-msgstr ""
+msgstr "Контакти по роботі з клієнтами"
msgid "Crm|Customer Relations Organizations"
-msgstr ""
+msgstr "Організації по роботі з клієнтами"
msgid "Crm|Default rate (optional)"
-msgstr ""
+msgstr "Рівень за замовчуваннÑм (необов'Ñзково)"
msgid "Crm|Description (optional)"
-msgstr ""
+msgstr "ÐžÐ¿Ð¸Ñ (необов'Ñзково)"
msgid "Crm|Edit contact"
-msgstr ""
+msgstr "Редагувати контакт"
msgid "Crm|Email"
msgstr "Електронна пошта"
@@ -10797,25 +10909,25 @@ msgid "Crm|Last name"
msgstr "Прізвище"
msgid "Crm|New Organization"
-msgstr ""
+msgstr "Ðова організаціÑ"
msgid "Crm|New contact"
msgstr "Ðовий контакт"
msgid "Crm|New organization"
-msgstr ""
+msgstr "Ðова організаціÑ"
msgid "Crm|No contacts found"
-msgstr ""
+msgstr "Контактів не знайдено"
msgid "Crm|No organizations found"
-msgstr ""
+msgstr "Організацій не знайдено"
msgid "Crm|Organization has been added"
-msgstr ""
+msgstr "Організацію було додано"
msgid "Crm|Phone number (optional)"
-msgstr ""
+msgstr "Ðомер телефону (необов'Ñзково)"
msgid "Cron Timezone"
msgstr "ЧаÑовий поÑÑ Cron"
@@ -10884,7 +10996,7 @@ msgid "CurrentUser|One of your groups is running out"
msgstr ""
msgid "CurrentUser|Preferences"
-msgstr "ÐалаштуваннÑ"
+msgstr "Параметри"
msgid "CurrentUser|Start an Ultimate trial"
msgstr ""
@@ -10905,7 +11017,7 @@ msgid "Custom hostname (for private commit emails)"
msgstr "ВлаÑне ім'Ñ Ñ…Ð¾Ñта (Ð´Ð»Ñ Ð¿Ñ€Ð¸Ð²Ð°Ñ‚Ð½Ð¸Ñ… повідомлень електронної пошти)"
msgid "Custom metrics"
-msgstr ""
+msgstr "КориÑтувацькі метрики"
msgid "Custom notification events"
msgstr "КориÑтувацькі Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½ÑŒ про події"
@@ -10932,14 +11044,11 @@ msgid "Customer Relations Organizations"
msgstr ""
msgid "Customer experience improvement and third-party offers"
-msgstr ""
+msgstr "ÐŸÐ¾ÐºÑ€Ð°Ñ‰ÐµÐ½Ð½Ñ ÐºÐ»Ñ–Ñ”Ð½Ñ‚Ñького доÑвіду та Ñторонні пропозиції"
msgid "Customer relations"
msgstr ""
-msgid "Customizable by an administrator."
-msgstr ""
-
msgid "Customizable by owners."
msgstr ""
@@ -10947,7 +11056,7 @@ msgid "Customize CI/CD settings, including Auto DevOps, shared runners, and job
msgstr ""
msgid "Customize colors"
-msgstr "ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ ÐºÐ¾Ð»ÑŒÐ¾Ñ€Ñ–Ð²"
+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 "Ðалаштуйте, Ñк адреÑи електронної пошти та імена кориÑтувачів FogBugz імпортуютьÑÑ Ð² GitLab. Ðа наÑтупному кроці ви зможете вибрати проєкти, Ñкі потрібно імпортувати."
@@ -11069,30 +11178,18 @@ msgstr "має бути в групі"
msgid "CycleAnalytics|%{selectedLabelsCount} selected (%{maxLabels} max)"
msgstr "%{selectedLabelsCount} вибрано (%{maxLabels} max)"
-msgid "CycleAnalytics|%{stageCount} stages selected"
-msgstr "Вибрано %{stageCount} Ñтадій"
-
-msgid "CycleAnalytics|All stages"
-msgstr "Ð’ÑÑ– Ñтадії"
-
-msgid "CycleAnalytics|Average days to completion"
-msgstr "Ð¡ÐµÑ€ÐµÐ´Ð½Ñ ÐºÑ–Ð»ÑŒÐºÑ–ÑÑ‚ÑŒ днів до завершеннÑ"
+msgid "CycleAnalytics|Average time to completion"
+msgstr ""
msgid "CycleAnalytics|Date"
msgstr "Дата"
-msgid "CycleAnalytics|Days to completion"
-msgstr "Днів до завершеннÑ"
-
msgid "CycleAnalytics|Display chart filters"
msgstr "Ð’Ñ–Ð´Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Ñ„Ñ–Ð»ÑŒÑ‚Ñ€Ñ–Ð² графіків"
msgid "CycleAnalytics|Lead Time for Changes"
msgstr ""
-msgid "CycleAnalytics|No stages selected"
-msgstr "Жодної Ñтадії не вибрано"
-
msgid "CycleAnalytics|Number of tasks"
msgstr "КількіÑÑ‚ÑŒ задач"
@@ -11125,18 +11222,30 @@ msgstr "Ð’Ñ–Ð´Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Ð´Ð°Ð½Ð¸Ñ… Ð´Ð»Ñ Ð³Ñ€ÑƒÐ¿Ð¸ \"%{groupName}\" Ñ
msgid "CycleAnalytics|Showing data for group '%{groupName}' from %{createdAfter} to %{createdBefore}"
msgstr "Ð’Ñ–Ð´Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Ð´Ð°Ð½Ð¸Ñ… Ð´Ð»Ñ Ð³Ñ€ÑƒÐ¿Ð¸ \"%{groupName}\" від %{createdAfter} до %{createdBefore}"
-msgid "CycleAnalytics|Stages"
-msgstr "Стадії"
+msgid "CycleAnalytics|Stage time: %{title}"
+msgstr ""
msgid "CycleAnalytics|Tasks by type"
msgstr "Ð—Ð°Ð²Ð´Ð°Ð½Ð½Ñ Ð·Ð° типом"
-msgid "CycleAnalytics|The average time spent in the selected stage for the items that were completed on each date. Data limited to the last 500 items."
-msgstr "Середній чаÑ, витрачений на обраному етапі Ð´Ð»Ñ ÐµÐ»ÐµÐ¼ÐµÐ½Ñ‚Ñ–Ð², Ñкі були виконані у кожну дату. Дані обмежуютьÑÑ Ð¾Ñтанніми 500 елементами."
+msgid "CycleAnalytics|The average time items spent in this stage. Data limited to items completed within this date range."
+msgstr ""
msgid "CycleAnalytics|The given date range is larger than 180 days"
msgstr "Даний діапазон чаÑу перевищує 180 днів"
+msgid "CycleAnalytics|The total time items spent across each value stream stage. Data limited to items completed within this date range."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Stage time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Total time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|Total time"
+msgstr ""
+
msgid "CycleAnalytics|Type of work"
msgstr "Тип роботи"
@@ -11149,9 +11258,6 @@ msgstr "не дозволена Ð´Ð»Ñ Ð´Ð°Ð½Ð¾Ñ— початкової подіÑ
msgid "CycleAnalytics|project dropdown filter"
msgstr "випадаючий ÑпиÑок проєктів"
-msgid "CycleAnalytics|stage dropdown"
-msgstr "Випадаючий ÑпиÑок Ñтадій"
-
msgid "DAG visualization requires at least 3 dependent jobs."
msgstr "Ð”Ð»Ñ Ð²Ñ–Ð·ÑƒÐ°Ð»Ñ–Ð·Ð°Ñ†Ñ–Ñ— DAG потрібно щонайменше 3 залежних завданнÑ."
@@ -11171,7 +11277,7 @@ msgid "DORA4Metrics|%{startDate} - %{endDate}"
msgstr "%{startDate} - %{endDate}"
msgid "DORA4Metrics|Average (last %{days}d)"
-msgstr ""
+msgstr "Ð’ Ñередньому (оÑтанні %{days}d)"
msgid "DORA4Metrics|Date"
msgstr "Дата"
@@ -11183,10 +11289,10 @@ msgid "DORA4Metrics|Deployment frequency"
msgstr "ЧаÑтота розгортаннÑ"
msgid "DORA4Metrics|Lead time for changes"
-msgstr ""
+msgstr "Ð§Ð°Ñ Ð²Ð¸ÐºÐ¾Ð½Ð°Ð½Ð½Ñ Ð·Ð¼Ñ–Ð½"
msgid "DORA4Metrics|Median (last %{days}d)"
-msgstr ""
+msgstr "Ð’ Ñередньому (оÑтанні %{days}d)"
msgid "DORA4Metrics|No merge requests were deployed during this period"
msgstr "За цей період не було розгорнуто жодних запитів на злиттÑ"
@@ -11207,7 +11313,7 @@ msgid "DORA4Metrics|The chart displays the median time between a merge request b
msgstr "Графік відображає Ñередній Ñ‡Ð°Ñ Ð¼Ñ–Ð¶ об’єднаннÑм запиту на Ð·Ð»Ð¸Ñ‚Ñ‚Ñ Ñ‚Ð° його розгортаннÑм у production Ñередовищі, що базуютьÑÑ Ð½Ð° значенні %{linkStart}deployment_tier%{linkEnd}."
msgid "DSN"
-msgstr ""
+msgstr "DSN"
msgid "Dashboard"
msgstr "Панель керуваннÑ"
@@ -11237,7 +11343,7 @@ msgid "DastConfig|Customize DAST settings to suit your requirements. Configurati
msgstr "Ðалаштуйте параметри DAST відповідно до ваших вимог. Зміни конфігурації, зроблені тут, перевизначать налаштуваннÑ, надані GitLab, Ñ– не будуть оновлюватиÑÑ. Ð”Ð»Ñ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ Ð±Ñ–Ð»ÑŒÑˆ детальної інформації про додаткові Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð¿ÐµÑ€ÐµÐ³Ð»Ñньте %{docsLinkStart}документацію GitLab DAST%{docsLinkEnd}."
msgid "DastConfig|DAST Settings"
-msgstr "ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ DAST"
+msgstr "Параметри DAST"
msgid "DastConfig|Generate code snippet"
msgstr ""
@@ -11251,11 +11357,17 @@ msgstr "ПаÑивне ÑÐºÐ°Ð½ÑƒÐ²Ð°Ð½Ð½Ñ Ð²Ñ–Ð´Ñтежує вÑÑ– HTTP-поÐ
msgid "DastProfiles|AJAX spider"
msgstr "AJAX spider"
+msgid "DastProfiles|API"
+msgstr ""
+
+msgid "DastProfiles|API endpoint URL"
+msgstr ""
+
msgid "DastProfiles|Active"
msgstr "Ðктивний"
-msgid "DastProfiles|Additional request headers (Optional)"
-msgstr "Додаткові заголовки запиту (необов'Ñзково)"
+msgid "DastProfiles|Additional request headers (optional)"
+msgstr ""
msgid "DastProfiles|Are you sure you want to delete this profile?"
msgstr "Ви впевнені, що хочете видалити цей профіль?"
@@ -11269,6 +11381,9 @@ msgstr "URL-адреÑа автентифікації"
msgid "DastProfiles|Branch missing"
msgstr "ВідÑÑƒÑ‚Ð½Ñ Ð³Ñ–Ð»ÐºÐ°"
+msgid "DastProfiles|Choose a scan method"
+msgstr ""
+
msgid "DastProfiles|Could not create the scanner profile. Please try again."
msgstr "Ðе вдалоÑÑ Ñтворити профіль Ñканера. Будь лаÑка, Ñпробуйте ще раз."
@@ -11306,10 +11421,10 @@ msgid "DastProfiles|Delete profile"
msgstr "Видалити профіль"
msgid "DastProfiles|Do you want to discard this scanner profile?"
-msgstr ""
+msgstr "Ви хочете відхилити цей профіль Ñканера?"
msgid "DastProfiles|Do you want to discard this site profile?"
-msgstr ""
+msgstr "Ви хочете відхилити цей профіль Ñайту?"
msgid "DastProfiles|Do you want to discard your changes?"
msgstr "Ви хочете ÑкаÑувати ваші зміни?"
@@ -11338,7 +11453,13 @@ msgstr "Помилка деталі"
msgid "DastProfiles|Excluded URLs"
msgstr ""
-msgid "DastProfiles|Excluded URLs (Optional)"
+msgid "DastProfiles|Excluded URLs (optional)"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths (optional)"
msgstr ""
msgid "DastProfiles|Hide debug messages"
@@ -11351,7 +11472,7 @@ msgid "DastProfiles|Manage DAST scans"
msgstr ""
msgid "DastProfiles|Manage profiles"
-msgstr ""
+msgstr "Керувати профілÑми"
msgid "DastProfiles|Manage site profiles"
msgstr ""
@@ -11395,9 +11516,6 @@ msgstr ""
msgid "DastProfiles|Request headers"
msgstr ""
-msgid "DastProfiles|Rest API"
-msgstr ""
-
msgid "DastProfiles|Run the AJAX spider, in addition to the traditional spider, to crawl the target site."
msgstr ""
@@ -11407,6 +11525,9 @@ msgstr ""
msgid "DastProfiles|Save profile"
msgstr "Зберегти профіль"
+msgid "DastProfiles|Scan method"
+msgstr ""
+
msgid "DastProfiles|Scan mode"
msgstr "Режим ÑкануваннÑ"
@@ -11429,7 +11550,7 @@ msgid "DastProfiles|Site Profile"
msgstr "Профіль Ñайту"
msgid "DastProfiles|Site Profiles"
-msgstr ""
+msgstr "Профілі Ñайту"
msgid "DastProfiles|Site name"
msgstr "Ім'Ñ Ñайту"
@@ -11485,12 +11606,24 @@ msgstr "Ð¡Ñ‚Ð°Ñ‚ÑƒÑ Ð¿ÐµÑ€ÐµÐ²Ñ–Ñ€ÐºÐ¸"
msgid "DastProfiles|Website"
msgstr "Веб-Ñайт"
+msgid "DastProfiles|What does each method do?"
+msgstr ""
+
msgid "DastProfiles|You can either choose a passive scan or validate the target site from the site profile management page. %{docsLinkStart}Learn more about site validation.%{docsLinkEnd}"
msgstr ""
msgid "DastProfiles|You cannot run an active scan against an unvalidated site."
msgstr ""
+msgid "DastProfiles|folder/dast_example.har or https://example.com/dast_example.har"
+msgstr ""
+
+msgid "DastProfiles|folder/example.postman_collection.json or https://example.com/"
+msgstr ""
+
+msgid "DastProfiles|folder/openapi.json or https://example.com/openapi.json"
+msgstr ""
+
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
@@ -11522,7 +11655,7 @@ msgid "DastSiteValidation|Step 1 - Choose site validation method"
msgstr "Крок 1 - Виберіть метод перевірки Ñайту"
msgid "DastSiteValidation|Step 2 - Add following HTTP header to your site"
-msgstr ""
+msgstr "Крок 2 - додати заголовок HTTP на вашому Ñайті"
msgid "DastSiteValidation|Step 2 - Add following meta tag to your site"
msgstr ""
@@ -11600,6 +11733,9 @@ msgstr ""
msgid "DatadogIntegration|API URL"
msgstr ""
+msgid "DatadogIntegration|Custom tags in Datadog. Enter one tag per line in the %{codeOpen}key:value%{codeClose} format. %{linkOpen}How do I use tags?%{linkClose}"
+msgstr ""
+
msgid "DatadogIntegration|Environment"
msgstr "Середовище"
@@ -11618,12 +11754,18 @@ msgstr "СервіÑ"
msgid "DatadogIntegration|Tag all data from this GitLab instance in Datadog. Useful when managing several self-managed deployments."
msgstr ""
+msgid "DatadogIntegration|Tags"
+msgstr ""
+
msgid "DatadogIntegration|The Datadog site to send data to. To send data to the EU site, use %{codeOpen}datadoghq.eu%{codeClose}."
msgstr ""
msgid "DatadogIntegration|Trace your GitLab pipelines with Datadog."
msgstr "ВідÑтежуйте конвеєри GitLab за допомогою Datadog."
+msgid "DatadogIntegration|have an invalid format"
+msgstr ""
+
msgid "Datasource name not found"
msgstr "Ім'Ñ Ð´Ð¶ÐµÑ€ÐµÐ»Ð° даних не знайдено"
@@ -11631,10 +11773,7 @@ msgid "Date"
msgstr "Дата"
msgid "Date merged"
-msgstr ""
-
-msgid "Date picker"
-msgstr "Вибір дати"
+msgstr "Дата ЗлиттÑ"
msgid "Date range"
msgstr ""
@@ -11789,9 +11928,6 @@ msgstr ""
msgid "Definition"
msgstr "ВизначеннÑ"
-msgid "Delayed Project Deletion (%{adjourned_deletion})"
-msgstr ""
-
msgid "DelayedJobs|Are you sure you want to run %{jobName} immediately? Otherwise this job will run automatically after its timer finishes."
msgstr "Ви впевнені, що ви хочете запуÑтити %{jobName} відразу? Ð’ іншому випадку це Ð·Ð°Ð²Ð´Ð°Ð½Ð½Ñ Ð±ÑƒÐ´Ðµ виконано автоматично по завершенню таймера."
@@ -11853,7 +11989,7 @@ msgid "Delete corpus"
msgstr ""
msgid "Delete deploy key"
-msgstr ""
+msgstr "Видалити ключ Ð´Ð»Ñ Ñ€Ð¾Ð·Ð³Ð¾Ñ€Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ"
msgid "Delete file"
msgstr "Видалити файл"
@@ -11870,12 +12006,12 @@ msgstr "Видалити мітку: %{labelName}"
msgid "Delete pipeline"
msgstr "Видалити конвеєр"
+msgid "Delete pipeline schedule"
+msgstr ""
+
msgid "Delete project"
msgstr "Видалити проєкт"
-msgid "Delete project. Are you ABSOLUTELY SURE?"
-msgstr "Видалити проєкт. Ви ÐБСОЛЮТÐО ВПЕВÐЕÐІ?"
-
msgid "Delete row"
msgstr "Видалити Ñ€Ñдок"
@@ -11903,6 +12039,9 @@ msgstr "Видалити це вкладеннÑ"
msgid "Delete this epic and all descendants?"
msgstr ""
+msgid "Delete this project"
+msgstr ""
+
msgid "Delete user list"
msgstr "Видалити ÑпиÑок кориÑтувачів"
@@ -11910,7 +12049,7 @@ msgid "Delete variable"
msgstr "Видалити змінну"
msgid "DeleteProject|Failed to remove events. Please try again or contact administrator."
-msgstr ""
+msgstr "Помилка при видаленні подій. Будь лаÑка, Ñпробуйте знову, або зв'ÑжітьÑÑ Ð· адмініÑтратором."
msgid "DeleteProject|Failed to remove project repository. Please try again or contact administrator."
msgstr "Помилка при видаленні репозиторію проєкту. Будь лаÑка, Ñпробуйте знову, або зв'ÑжітьÑÑ Ñ–Ð· адмініÑтратором."
@@ -12087,7 +12226,7 @@ msgid "DependencyProxy|Cached %{time}"
msgstr "Кешовано %{time}"
msgid "DependencyProxy|Clear the Dependency Proxy cache automatically"
-msgstr ""
+msgstr "ОчиÑтити кеш прокÑÑ– залежноÑтей автоматично"
msgid "DependencyProxy|Contains %{count} blobs of images (%{size})"
msgstr ""
@@ -12108,22 +12247,22 @@ msgid "DependencyProxy|Dependency Proxy image prefix"
msgstr ""
msgid "DependencyProxy|Enable Dependency Proxy"
-msgstr ""
+msgstr "Увімкнути прокÑÑ– залежноÑтей"
msgid "DependencyProxy|Image list"
-msgstr ""
+msgstr "СпиÑок образів"
msgid "DependencyProxy|Storage settings"
-msgstr ""
+msgstr "ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ñховища"
msgid "DependencyProxy|There are no images in the cache"
-msgstr ""
+msgstr "Ðемає образів у кеші"
msgid "DependencyProxy|To see the image prefix and what is in the cache, visit the %{linkStart}Dependency Proxy%{linkEnd}"
-msgstr ""
+msgstr "Щоб переглÑнути Ð¿Ñ€ÐµÑ„Ñ–ÐºÑ Ð¾Ð±Ñ€Ð°Ð·Ñ–Ð² та вміÑÑ‚ кешу, перейдіть на %{linkStart}прокÑÑ–-залежніÑÑ‚ÑŒ%{linkEnd}"
msgid "DependencyProxy|When enabled, images older than 90 days will be removed from the cache."
-msgstr ""
+msgstr "Якщо увімкнено, образ, що зберігаютьÑÑ Ð±Ñ–Ð»ÑŒÑˆÐµ ніж 90 днів, будуть видалені з кешу."
msgid "Depends on %d merge request being merged"
msgid_plural "Depends on %d merge requests being merged"
@@ -12168,11 +12307,17 @@ msgid "Deploy progress not found. To see pods, ensure your environment matches %
msgstr "Хід Ñ€Ð¾Ð·Ð³Ð¾Ñ€Ñ‚Ð°Ð½Ð½Ñ Ð½Ðµ знайдено. Щоб побачити pod'и, переконайтеÑÑŒ, що ваше Ñередовище відповідає %{linkStart}критеріÑм дошки розгортань%{linkEnd}."
msgid "Deploy static assets and resources to Google managed CDN"
-msgstr ""
+msgstr "Розгорніть Ñтатичні активи та реÑурÑи в CDN, що керуєтьÑÑ Google"
msgid "Deploy to..."
msgstr "Розгорнути на..."
+msgid "DeployBoards|To see deployment progress for your environments, make sure you are deploying to %{codeStart}$KUBE_NAMESPACE%{codeEnd} and annotating with %{codeStart}app.gitlab.com/app=$CI_PROJECT_PATH_SLUG%{codeEnd} and %{codeStart}app.gitlab.com/env=$CI_ENVIRONMENT_SLUG%{codeEnd}."
+msgstr ""
+
+msgid "DeployBoard|Kubernetes Pods"
+msgstr ""
+
msgid "DeployFreeze|Add a freeze period to prevent unintended releases during a period of time for a given environment. You must update the deployment jobs in %{filename} according to the deploy freezes added here. %{freeze_period_link_start}Learn more.%{freeze_period_link_end}"
msgstr ""
@@ -12257,9 +12402,6 @@ msgstr "ДоÑтуп тільки Ð´Ð»Ñ Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ"
msgid "DeployTokens|Active Deploy Tokens (%{active_tokens})"
msgstr "Ðктивні токени Ñ€Ð¾Ð·Ð³Ð¾Ñ€Ñ‚Ð°Ð½Ð½Ñ (%{active_tokens})"
-msgid "DeployTokens|Allows read and write access to registry images."
-msgstr "ДозволÑÑ” читати та запиÑувати образи реєÑтру."
-
msgid "DeployTokens|Allows read and write access to the package registry."
msgstr "ДозволÑÑ” доÑтуп Ð´Ð»Ñ Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ Ñ‚Ð° запиÑу до реєÑтру пакетів."
@@ -12272,6 +12414,9 @@ msgstr "ДозволÑÑ” доÑтуп лише Ð´Ð»Ñ Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ Ð´Ð¾ реє
msgid "DeployTokens|Allows read-only access to the repository."
msgstr ""
+msgid "DeployTokens|Allows write access to registry images."
+msgstr ""
+
msgid "DeployTokens|Copy deploy token"
msgstr "Скопіювати токен розгортаннÑ"
@@ -12365,12 +12510,57 @@ msgstr "Ð Ð¾Ð·Ð³Ð¾Ñ€Ñ‚Ð°Ð½Ð½Ñ Ð´Ð¾"
msgid "Deploying to AWS is easy with GitLab"
msgstr ""
+msgid "Deployment"
+msgstr ""
+
msgid "Deployment Frequency"
msgstr "ЧаÑтота РозгортаннÑ"
+msgid "Deployment Target|Project deployment target (optional)"
+msgstr ""
+
+msgid "Deployment Target|Select the deployment target"
+msgstr ""
+
msgid "Deployment frequency"
msgstr ""
+msgid "DeploymentTarget|GitLab Pages"
+msgstr ""
+
+msgid "DeploymentTarget|Heroku"
+msgstr ""
+
+msgid "DeploymentTarget|Infrastructure provider (Terraform, Cloudformation, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Kubernetes (GKE, EKS, OpenShift, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Managed container runtime (Fargate, Cloud Run, DigitalOcean App)"
+msgstr ""
+
+msgid "DeploymentTarget|Mobile app store"
+msgstr ""
+
+msgid "DeploymentTarget|No deployment planned"
+msgstr ""
+
+msgid "DeploymentTarget|Other hosting service"
+msgstr ""
+
+msgid "DeploymentTarget|Registry (package or container)"
+msgstr ""
+
+msgid "DeploymentTarget|Self-managed container runtime (Podman, Docker Swarm, Docker Compose)"
+msgstr ""
+
+msgid "DeploymentTarget|Serverless backend (Lambda, Cloud functions)"
+msgstr ""
+
+msgid "DeploymentTarget|Virtual machine (for example, EC2)"
+msgstr ""
+
msgid "Deployments"
msgstr "РозгортаннÑ"
@@ -12385,37 +12575,40 @@ msgid "Deployment|API"
msgstr "API"
msgid "Deployment|Cancelled"
-msgstr ""
+msgstr "СкаÑовано"
msgid "Deployment|Created"
-msgstr ""
+msgstr "Створено"
msgid "Deployment|Deployment ID"
-msgstr ""
+msgstr "ID розгортаннÑ"
msgid "Deployment|Failed"
-msgstr ""
+msgstr "Ðевдало"
msgid "Deployment|Latest Deployed"
-msgstr ""
+msgstr "ОÑтанній розгорнутий"
msgid "Deployment|Running"
-msgstr ""
+msgstr "ВиконуєтьÑÑ"
msgid "Deployment|Skipped"
-msgstr ""
+msgstr "Пропущено"
msgid "Deployment|Success"
-msgstr ""
+msgstr "УÑпішно"
msgid "Deployment|This deployment was created using the API"
msgstr "Це Ñ€Ð¾Ð·Ð³Ð¾Ñ€Ñ‚Ð°Ð½Ð½Ñ Ð±ÑƒÐ»Ð¾ Ñтворено через API"
-msgid "Deployment|Waiting"
+msgid "Deployment|Triggerer"
msgstr ""
+msgid "Deployment|Waiting"
+msgstr "ОчікуваннÑ"
+
msgid "Deployment|blocked"
-msgstr ""
+msgstr "заблоковано"
msgid "Deployment|canceled"
msgstr "відмінено"
@@ -12438,6 +12631,18 @@ msgstr "уÑпішно"
msgid "Deprecated API rate limits"
msgstr ""
+msgid "Deprecations|Feature deprecation and removal"
+msgstr ""
+
+msgid "Deprecations|For information on a possible replacement %{epicStart} learn more about Opstrace %{epicEnd}."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7 and are %{epicStart} scheduled for removal %{epicEnd} in GitLab 15.0."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7, and are %{removal_link_start} scheduled for removal %{link_end} in GitLab 15.0. For information on a possible replacement, %{opstrace_link_start} learn more about Opstrace %{link_end}."
+msgstr ""
+
msgid "Deprioritize label"
msgstr "Зменшити пріоритет мітки"
@@ -12572,7 +12777,7 @@ msgid "DesignManagement|Keep comment"
msgstr "Залишити коментар"
msgid "DesignManagement|Learn more about resolving comments"
-msgstr ""
+msgstr "ДізнатиÑÑ Ð±Ñ–Ð»ÑŒÑˆÐµ про Ð²Ð¸Ñ€Ñ–ÑˆÐµÐ½Ð½Ñ ÐºÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ñ–Ð²"
msgid "DesignManagement|Requested design version does not exist. Showing latest version instead"
msgstr "Бажана верÑÑ–Ñ Ð´Ð¸Ð·Ð°Ð¹Ð½Ñƒ не Ñ–Ñнує. ЗаміÑÑ‚ÑŒ неї відображаєтьÑÑ Ð¾ÑтаннÑ"
@@ -12635,16 +12840,16 @@ msgid "Detect host keys"
msgstr "ВиÑÐ²Ð»ÐµÐ½Ð½Ñ ÐºÐ»ÑŽÑ‡Ñ–Ð² хоÑта"
msgid "DevOps Adoption"
-msgstr ""
+msgstr "ÐŸÑ€Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ DevOps"
msgid "DevOps Reports"
-msgstr ""
+msgstr "Звіти DevOps"
msgid "DevOps adoption"
-msgstr ""
+msgstr "ÐŸÑ€Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ DevOps"
msgid "Devices (optional)"
-msgstr ""
+msgstr "ПриÑтрої (необов’Ñзково)"
msgid "DevopsAdoption|%{adoptedCount}/%{featuresCount} %{title} features adopted"
msgstr ""
@@ -12685,10 +12890,10 @@ msgstr ""
msgid "DevopsAdoption|At least one deploy"
msgstr ""
-msgid "DevopsAdoption|At least one issue opened"
+msgid "DevopsAdoption|At least one issue created"
msgstr ""
-msgid "DevopsAdoption|At least one merge request opened"
+msgid "DevopsAdoption|At least one merge request created"
msgstr ""
msgid "DevopsAdoption|At least one pipeline successfully run"
@@ -12740,13 +12945,13 @@ msgid "DevopsAdoption|Fuzz Testing enabled for at least one project"
msgstr ""
msgid "DevopsAdoption|Issues"
-msgstr ""
+msgstr "Задачі"
msgid "DevopsAdoption|MRs"
-msgstr ""
+msgstr "Запит на злиттÑ"
msgid "DevopsAdoption|No results…"
-msgstr ""
+msgstr "Ðемає результатів…"
msgid "DevopsAdoption|No tracked features"
msgstr ""
@@ -12851,7 +13056,7 @@ msgid "Difference between start date and now"
msgstr "Ð Ñ–Ð·Ð½Ð¸Ñ†Ñ Ð¼Ñ–Ð¶ датою початку та теперішньою"
msgid "DiffsCompareBaseBranch|(HEAD)"
-msgstr ""
+msgstr "(HEAD)"
msgid "DiffsCompareBaseBranch|(base)"
msgstr "(базова)"
@@ -12895,6 +13100,9 @@ msgstr ""
msgid "Direct member"
msgstr ""
+msgid "Direct members"
+msgstr ""
+
msgid "Direct non-authenticated users to this page."
msgstr ""
@@ -13013,6 +13221,9 @@ msgstr[1] "Відхилити %d виділені вразливоÑÑ‚Ñ– Ñк"
msgstr[2] "Відхилити %d виділених вразливоÑтей Ñк"
msgstr[3] "Відхилити %d виділених вразливоÑтей Ñк"
+msgid "Dismiss Alert"
+msgstr ""
+
msgid "Dismiss merge request promotion"
msgstr ""
@@ -13040,9 +13251,15 @@ msgstr "Відхилено в конвеєрі %{pipelineLink} в %{projectLink}
msgid "Display alerts from all configured monitoring tools."
msgstr ""
+msgid "Display milestones"
+msgstr ""
+
msgid "Display name"
msgstr "Ð†Ð¼â€™Ñ Ð´Ð»Ñ Ð²Ñ–Ð´Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ"
+msgid "Display progress of child issues"
+msgstr ""
+
msgid "Display rendered file"
msgstr "Показувати перетворений файл"
@@ -13053,7 +13270,7 @@ msgid "Display time tracking in issues in total hours only."
msgstr ""
msgid "Do not display content for customer experience improvement and offers from third parties"
-msgstr ""
+msgstr "Ðе показувати вміÑÑ‚ Ð´Ð»Ñ Ð¿Ð¾ÐºÑ€Ð°Ñ‰ÐµÐ½Ð½Ñ ÐºÐ»Ñ–Ñ”Ð½Ñ‚Ñького доÑвіду та Ñторонніх пропозицій"
msgid "Do not force push over diverged refs. After the mirror is created, this setting can only be modified using the API. %{mirroring_docs_link_start}Learn more about this option%{link_closing_tag} and %{mirroring_api_docs_link_start}the API.%{link_closing_tag}"
msgstr ""
@@ -13122,13 +13339,13 @@ msgid "Download (%{fileSizeReadable})"
msgstr "Завантажити (%{fileSizeReadable})"
msgid "Download (%{size})"
-msgstr ""
+msgstr "Завантажити (%{size})"
msgid "Download CSV"
msgstr "Завантажити CSV"
msgid "Download PDF"
-msgstr ""
+msgstr "Завантажити PDF"
msgid "Download artifacts"
msgstr "Завантажити артефакти"
@@ -13148,6 +13365,9 @@ msgstr "Завантажити екÑпор"
msgid "Download image"
msgstr "Завантажити зображеннÑ"
+msgid "Download payload"
+msgstr ""
+
msgid "Download raw data (.csv)"
msgstr "Завантажити необроблені дані (.csv)"
@@ -13194,7 +13414,7 @@ msgid "DropdownWidget|An error occurred while fetching the assigned %{issuableAt
msgstr ""
msgid "DropdownWidget|Assign %{issuableAttribute}"
-msgstr ""
+msgstr "Призначити %{issuableAttribute}"
msgid "DropdownWidget|Failed to fetch the %{issuableAttribute} for this %{issuableType}. Please try again."
msgstr ""
@@ -13248,7 +13468,7 @@ msgid "Edit Deploy Key"
msgstr "Редагувати ключ Ð´Ð»Ñ Ñ€Ð¾Ð·Ð³Ð¾Ñ€Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ"
msgid "Edit Geo Site"
-msgstr ""
+msgstr "Редагувати Ñайт Geo"
msgid "Edit Group Hook"
msgstr "Редагувати хук групи"
@@ -13266,7 +13486,7 @@ msgid "Edit Password"
msgstr "Редагувати пароль"
msgid "Edit Pipeline Schedule"
-msgstr ""
+msgstr "Редагувати розклад Конвеєра"
msgid "Edit Release"
msgstr "Редагувати Реліз"
@@ -13305,7 +13525,7 @@ msgid "Edit environment"
msgstr "Редагувати Ñередовище"
msgid "Edit epics"
-msgstr ""
+msgstr "Редагувати епіки"
msgid "Edit files in the editor and commit changes here"
msgstr "Редагуйте файли в редакторі і закомітьте зміни тут"
@@ -13325,6 +13545,9 @@ msgstr "Редагувати ідентифікацію Ð´Ð»Ñ %{user_name}"
msgid "Edit in Web IDE"
msgstr "Редагувати у веб-IDE"
+msgid "Edit in pipeline editor"
+msgstr ""
+
msgid "Edit in single-file editor"
msgstr ""
@@ -13367,6 +13590,9 @@ msgstr "Редагувати wiki-Ñторінку"
msgid "Edit your most recent comment in a thread (from an empty textarea)"
msgstr "Редагувати ваш оÑтанній коментар в обговоренні (в порожньому текÑтовому полі)"
+msgid "Edit, lint, and visualize your pipeline."
+msgstr ""
+
msgid "Edited"
msgstr "Відредаговано"
@@ -13590,7 +13816,7 @@ msgid "Enable Registration Features"
msgstr ""
msgid "Enable SSL verification"
-msgstr ""
+msgstr "Увімкнути перевірку SSL"
msgid "Enable Sentry error tracking"
msgstr ""
@@ -13647,7 +13873,7 @@ msgid "Enable delayed project deletion by default for newly-created groups."
msgstr ""
msgid "Enable email notification"
-msgstr ""
+msgstr "Увімкнути ÑÐ¿Ð¾Ð²Ñ–Ñ‰ÐµÐ½Ð½Ñ ÐµÐ»ÐµÐºÑ‚Ñ€Ð¾Ð½Ð½Ð¾ÑŽ поштою"
msgid "Enable error tracking"
msgstr "Увімкнути відÑÑ‚ÐµÐ¶ÐµÐ½Ð½Ñ Ð¿Ð¾Ð¼Ð¸Ð»Ð¾Ðº"
@@ -13683,7 +13909,7 @@ msgid "Enable kuromoji custom analyzer: Search"
msgstr ""
msgid "Enable logs collection"
-msgstr ""
+msgstr "Увімкнути збір логів"
msgid "Enable maintenance mode"
msgstr "Увімкнути режим обÑлуговуваннÑ"
@@ -13713,10 +13939,10 @@ msgid "Enable repository checks"
msgstr ""
msgid "Enable security training"
-msgstr ""
+msgstr "Увімкнути Ñ‚Ñ€ÐµÐ½ÑƒÐ²Ð°Ð½Ð½Ñ Ð±ÐµÐ·Ð¿ÐµÐºÐ¸"
msgid "Enable security training to help your developers learn how to fix vulnerabilities. Developers can view security training from selected educational providers, relevant to the detected vulnerability."
-msgstr ""
+msgstr "Увімкніть Ñ‚Ñ€ÐµÐ½ÑƒÐ²Ð°Ð½Ð½Ñ Ð±ÐµÐ·Ð¿ÐµÐºÐ¸, щоб допомогти вашим розробникам навчитиÑÑ Ð²Ð¸Ð¿Ñ€Ð°Ð²Ð»Ñти вразливоÑÑ‚Ñ–. Розробники можуть переглÑдати Ñ‚Ñ€ÐµÐ½ÑƒÐ²Ð°Ð½Ð½Ñ Ð±ÐµÐ·Ð¿ÐµÐºÐ¸ вибраних оÑвітніх провайдерів, що ÑтоÑуютьÑÑ Ð²Ð¸Ñвленої вразливоÑÑ‚Ñ–."
msgid "Enable shared runners for all projects and subgroups in this group."
msgstr ""
@@ -13749,7 +13975,7 @@ msgid "Enable version check"
msgstr ""
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 ""
@@ -13808,6 +14034,9 @@ msgstr ""
msgid "Enforce two-factor authentication for all user sign-ins."
msgstr ""
+msgid "Enhance security by storing service account keys in secret managers - learn more about %{docLinkStart}secret management with GitLab%{docLinkEnd}"
+msgstr ""
+
msgid "Ensure connectivity is available from the GitLab server to the Prometheus server"
msgstr "ПереконайтеÑÑ, що між Ñерверами GitLab та Prometheus Ñ–Ñнує з’єднаннÑ"
@@ -13818,7 +14047,7 @@ msgid "Enter %{weights_link_start}weights%{weights_link_end} for storages for ne
msgstr ""
msgid "Enter 2FA for Admin Mode"
-msgstr ""
+msgstr "Введіть 2FA Ð´Ð»Ñ Ñ€ÐµÐ¶Ð¸Ð¼Ñƒ адмініÑтратора"
msgid "Enter Admin Mode"
msgstr "Увійти в Режим ÐдмініÑтратора"
@@ -13827,10 +14056,10 @@ msgid "Enter a number"
msgstr "Введіть номер"
msgid "Enter an integer number between 0 and 100"
-msgstr ""
+msgstr "Введіть ціле чиÑло від 0 до 100"
msgid "Enter any color or choose one of the suggested colors below."
-msgstr ""
+msgstr "Введіть будь-Ñкий колір або виберіть один із запропонованих нижче кольорів."
msgid "Enter any color."
msgstr "Введіть будь-Ñкий колір."
@@ -13845,7 +14074,7 @@ msgid "Enter in your Phabricator Server URL and personal access token below"
msgstr "Введіть URL-адреÑу вашого Ñервера Phabricator Ñ– перÑональний ключ доÑтупу"
msgid "Enter license key"
-msgstr ""
+msgstr "Введіть ліцензійний ключ"
msgid "Enter merge request URLs"
msgstr "Введіть URL-адреÑи запиту на злиттÑ"
@@ -13868,6 +14097,9 @@ msgstr "Введіть %{name} заголовок"
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 following to confirm:"
+msgstr ""
+
msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
@@ -14125,7 +14357,7 @@ msgid "Environments|Stopping %{environmentName}"
msgstr "Зупинка %{environmentName}"
msgid "Environments|There are no deployments for this environment yet. %{linkStart}Learn more about setting up deployments.%{linkEnd}"
-msgstr ""
+msgstr "Ще немає розгортань Ð´Ð»Ñ Ñ†ÑŒÐ¾Ð³Ð¾ Ñередовища. %{linkStart}ДізнатиÑÑ Ð±Ñ–Ð»ÑŒÑˆÐµ про Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ñ€Ð¾Ð·Ð³Ð¾Ñ€Ñ‚Ð°Ð½ÑŒ.%{linkEnd}"
msgid "Environments|There was an error fetching the logs. Please try again."
msgstr "СталаÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ° під Ñ‡Ð°Ñ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ Ð»Ð¾Ð³Ñ–Ð². Будь лаÑка, Ñпробуйте ще раз."
@@ -14155,7 +14387,7 @@ msgid "Environments|protected"
msgstr "захищені"
msgid "Environment|Auto stop %{time}"
-msgstr ""
+msgstr "Ðвтозупинка %{time}"
msgid "Epic"
msgstr "Епік"
@@ -14266,7 +14498,7 @@ msgid "Epics|Something went wrong while removing issue from epic."
msgstr "Помилка при видаленні задачі із епіка."
msgid "Epics|Something went wrong while updating epics."
-msgstr ""
+msgstr "ЩоÑÑŒ пішло не так під Ñ‡Ð°Ñ Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ ÐµÐ¿Ñ–ÐºÑ–Ð²."
msgid "Epics|This epic and any containing child epics are confidential and should only be visible to team members with at least Reporter access."
msgstr ""
@@ -14400,9 +14632,6 @@ 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 "СталаÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ°. Заблокований кориÑтувач не може бути деактивований"
@@ -14538,6 +14767,9 @@ msgstr ""
msgid "Errors:"
msgstr "Помилки:"
+msgid "Escalate this incident"
+msgstr ""
+
msgid "Escalation Policies"
msgstr ""
@@ -14550,9 +14782,12 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
-msgid "Escalation policy:"
+msgid "Escalation policy"
msgstr ""
+msgid "Escalation policy:"
+msgstr "Політика еÑкалації:"
+
msgid "EscalationPolicies|%{clockIcon} IF alert is not %{alertStatus} in %{minutes}"
msgstr ""
@@ -14596,7 +14831,7 @@ msgid "EscalationPolicies|Email on-call user in schedule"
msgstr ""
msgid "EscalationPolicies|Email user"
-msgstr ""
+msgstr "КориÑтувач електронної пошти"
msgid "EscalationPolicies|Escalation policies"
msgstr ""
@@ -14780,7 +15015,7 @@ msgid "Except policy:"
msgstr "Політика виключеннÑ:"
msgid "Exceptions"
-msgstr ""
+msgstr "ВинÑтки"
msgid "Excluding merge commits. Limited to %{limit} commits."
msgstr ""
@@ -14803,6 +15038,9 @@ msgstr "ІÑнуючі проєкти зможуть викориÑтовуваÑ
msgid "Existing sign in methods may be removed"
msgstr "ІÑнуючі методи входу можуть бути видалені."
+msgid "Exit."
+msgstr ""
+
msgid "Expand"
msgstr "Розгорнути"
@@ -14899,6 +15137,9 @@ msgstr "ОглÑд проєктів"
msgid "Explore public groups"
msgstr "ПереглÑнути публічні групи"
+msgid "Explore public projects"
+msgstr ""
+
msgid "Explore snippets"
msgstr "ОглÑд Ñніпетів"
@@ -14933,7 +15174,7 @@ msgid "Export requirements"
msgstr ""
msgid "Export this group with all related data."
-msgstr ""
+msgstr "ЕкÑпортуйте цю групу з уÑіма пов'Ñзаними даними."
msgid "Export this project with all its related data in order to move it to a new GitLab instance. When the exported file is ready, you can download it from this page or from the download link in the email notification you will receive. You can then import it when creating a new project. %{link_start}Learn more.%{link_end}"
msgstr ""
@@ -14972,10 +15213,10 @@ msgid "ExternalAuthorizationService|When no classification label is set the defa
msgstr "Якщо клаÑифікаційну мітку не вÑтановлено, викориÑтовуватиметьÑÑ Ñтандартна мітка `%{default_label}`."
msgid "ExternalAuthorization|Access to projects is validated on an external service using their classification label."
-msgstr ""
+msgstr "ДоÑтуп до проєктів перевірÑєтьÑÑ Ð·Ð¾Ð²Ð½Ñ–ÑˆÐ½ÑŒÐ¾ÑŽ Ñлужбою з викориÑтаннÑм їхньої мітки клаÑифікації."
msgid "ExternalAuthorization|Certificate used to authenticate with the external authorization service. If blank, the server certificate is validated when accessing over HTTPS."
-msgstr ""
+msgstr "Сертифікат Ð´Ð»Ñ Ð°Ð²Ñ‚ÐµÐ½Ñ‚Ð¸Ñ„Ñ–ÐºÐ°Ñ†Ñ–Ñ— із зовнішньою Ñлужбою авторизації. Якщо він пуÑтий, Ñертифікат Ñервера перевірÑєтьÑÑ Ð¿Ñ–Ð´ Ñ‡Ð°Ñ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ Ð´Ð¾Ñтупу через HTTPS."
msgid "ExternalAuthorization|Classification label to use when requesting authorization if no specific label is defined on the project."
msgstr ""
@@ -14996,13 +15237,13 @@ msgid "ExternalAuthorization|Enable classification control using an external ser
msgstr ""
msgid "ExternalAuthorization|External authorization"
-msgstr ""
+msgstr "Ð—Ð¾Ð²Ð½Ñ–ÑˆÐ½Ñ Ð°Ð²Ñ‚Ð¾Ñ€Ð¸Ð·Ð°Ñ†Ñ–Ñ"
msgid "ExternalAuthorization|External authorization request timeout (seconds)"
-msgstr ""
+msgstr "Ð§Ð°Ñ Ð¾Ñ‡Ñ–ÐºÑƒÐ²Ð°Ð½Ð½Ñ Ð·Ð°Ð¿Ð¸Ñ‚Ñƒ на зовнішню авторизацію (Ñекунди)"
msgid "ExternalAuthorization|External classification policy authorization."
-msgstr ""
+msgstr "ÐÐ²Ñ‚Ð¾Ñ€Ð¸Ð·Ð°Ñ†Ñ–Ñ Ð¿Ð¾Ð»Ñ–Ñ‚Ð¸ÐºÐ¸ зовнішньої клаÑифікації."
msgid "ExternalAuthorization|Passphrase required to decrypt the private key. Encrypted when stored."
msgstr ""
@@ -15014,7 +15255,7 @@ msgid "ExternalAuthorization|Private key of client authentication certificate. E
msgstr ""
msgid "ExternalAuthorization|Service URL"
-msgstr ""
+msgstr "URL-адреÑа Ñлужби"
msgid "ExternalAuthorization|URL to which the projects make authorization requests. If the URL is blank, cross-project features are available and can still specify classification labels for projects."
msgstr ""
@@ -15035,7 +15276,7 @@ msgid "ExternalWikiService|Link to an external wiki from the sidebar."
msgstr ""
msgid "ExternalWikiService|https://example.com/xxx/wiki/..."
-msgstr ""
+msgstr "https://example.com/xxx/wiki/..."
msgid "Facebook"
msgstr "Facebook"
@@ -15062,7 +15303,7 @@ msgstr[1] ""
msgstr[2] ""
msgstr[3] ""
-msgid "Failed to assign a reviewer because no user was found."
+msgid "Failed to assign a reviewer because no user was specified."
msgstr ""
msgid "Failed to assign a user because no user was found."
@@ -15102,7 +15343,7 @@ msgid "Failed to create import label for jira import."
msgstr ""
msgid "Failed to create new access token: %{token_response_message}"
-msgstr ""
+msgstr "Ðе вдалоÑÑ Ñтворити новий токен доÑтупу: %{token_response_message}"
msgid "Failed to create repository"
msgstr "Ðе вдалоÑÑ Ñтворити репозиторій"
@@ -15128,10 +15369,10 @@ msgstr ""
msgid "Failed to find import label for Jira import."
msgstr "Ðе вдалоÑÑ Ð·Ð½Ð°Ð¹Ñ‚Ð¸ мітку Ð´Ð»Ñ Ñ–Ð¼Ð¿Ð¾Ñ€Ñ‚Ñƒ ÑиÑтеми Jira."
-msgid "Failed to generate export, please try again later."
+msgid "Failed to find users for %{missing}"
msgstr ""
-msgid "Failed to generate report, please try again after sometime"
+msgid "Failed to generate export, please try again later."
msgstr ""
msgid "Failed to get ref."
@@ -15230,6 +15471,9 @@ msgstr "Ðе вдалоÑÑ Ð²Ð¸Ð´Ð°Ð»Ð¸Ñ‚Ð¸ Zoom-зуÑтріч"
msgid "Failed to remove a to-do item for the design."
msgstr ""
+msgid "Failed to remove attention because no user was found."
+msgstr ""
+
msgid "Failed to remove mirror."
msgstr "Ðе вдалоÑÑ Ð²Ð¸Ð´Ð°Ð»Ð¸Ñ‚Ð¸ дзеркало."
@@ -15242,6 +15486,9 @@ msgstr "Ðе вдалоÑÑ Ð²Ð¸Ð´Ð°Ð»Ð¸Ñ‚Ð¸ ідентифікацію кори
msgid "Failed to remove user key."
msgstr "Ðе вдалоÑÑ Ð²Ð¸Ð´Ð°Ð»Ð¸Ñ‚Ð¸ ключ кориÑтувача."
+msgid "Failed to request attention because no user was found."
+msgstr ""
+
msgid "Failed to reset key. Please try again."
msgstr "Ðе вдалоÑÑ Ñкинути ключ. Будь лаÑка, Ñпробуйте знову."
@@ -15323,6 +15570,9 @@ msgstr ""
msgid "Feature Flags"
msgstr "Перемикачі функцій"
+msgid "Feature deprecation and removal"
+msgstr ""
+
msgid "Feature flag status"
msgstr ""
@@ -15334,10 +15584,10 @@ msgstr "Перемикач функції уÑпішно видалено."
msgid "FeatureFlags|%d user"
msgid_plural "FeatureFlags|%d users"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-msgstr[3] ""
+msgstr[0] "%d кориÑтувач"
+msgstr[1] "%d кориÑтувачі"
+msgstr[2] "%d кориÑтувачів"
+msgstr[3] "%d кориÑтувачів"
msgid "FeatureFlags|%{percent} by available ID"
msgstr ""
@@ -15373,7 +15623,7 @@ msgid "FeatureFlags|All users"
msgstr "Ð’ÑÑ– кориÑтувачі"
msgid "FeatureFlags|Configure"
-msgstr "ÐалаштуваннÑ"
+msgstr "Параметри"
msgid "FeatureFlags|Configure feature flags"
msgstr "Ðалаштувати перемикачі функцій"
@@ -15822,7 +16072,7 @@ msgstr ""
msgid "For each job, re-use the project workspace. If the workspace doesn't exist, use %{code_open}git clone%{code_close}."
msgstr ""
-msgid "For example, the application using the token or the purpose of the token."
+msgid "For example, the application using the token or the purpose of the token. Do not give sensitive information for the name of the token, as it will be visible to all %{resource_type} members."
msgstr ""
msgid "For files larger than this limit, only index the file name. The file content is neither indexed nor searchable."
@@ -15906,14 +16156,11 @@ msgstr "Публічний"
msgid "ForkProject|Select a namespace"
msgstr "Виберіть проÑÑ‚Ñ–Ñ€ імен"
-msgid "ForkProject|Select a namespace to fork the project"
-msgstr ""
-
msgid "ForkProject|The project can be accessed by any logged in user."
-msgstr ""
+msgstr "Проєкт може бути доÑтупний будь-Ñким зареєÑтрованим кориÑтувачем."
msgid "ForkProject|The project can be accessed without any authentication."
-msgstr ""
+msgstr "Проєкт може бути доÑтупний без будь-Ñкої автентифікації."
msgid "ForkProject|Visibility level"
msgstr "Рівень видимоÑÑ‚Ñ–"
@@ -16005,6 +16252,9 @@ msgstr ""
msgid "Full name"
msgstr "Повне ім'Ñ"
+msgid "GCP region configured"
+msgstr ""
+
msgid "GPG Key ID:"
msgstr "Ідентифікатор ключа GPG:"
@@ -16114,7 +16364,7 @@ msgid "Geo|%{title} checksum progress"
msgstr ""
msgid "Geo|(%{timeAgo})"
-msgstr ""
+msgstr "(%{timeAgo})"
msgid "Geo|Add site"
msgstr "Додати Ñайт"
@@ -16123,7 +16373,7 @@ msgid "Geo|Adjust your filters/search criteria above. If you believe this may be
msgstr ""
msgid "Geo|All"
-msgstr ""
+msgstr "Ð’ÑÑ–"
msgid "Geo|All %{replicable_name}"
msgstr "Ð’ÑÑ– %{replicable_name}"
@@ -16185,6 +16435,9 @@ msgstr ""
msgid "Geo|Failed"
msgstr "Ðевдало"
+msgid "Geo|Filter Geo sites"
+msgstr ""
+
msgid "Geo|Filter by name"
msgstr ""
@@ -16330,7 +16583,7 @@ msgid "Geo|Replicated data is verified with the secondary site(s) using checksum
msgstr ""
msgid "Geo|Replication Details"
-msgstr ""
+msgstr "Деталі реплікації"
msgid "Geo|Replication slot WAL"
msgstr ""
@@ -16450,10 +16703,10 @@ msgid "Geo|URL must be a valid url (ex: https://gitlab.com)"
msgstr ""
msgid "Geo|Undefined"
-msgstr ""
+msgstr "Ðевизначено"
msgid "Geo|Unhealthy"
-msgstr ""
+msgstr "Ðездоровий"
msgid "Geo|Unknown"
msgstr "Ðевідомий"
@@ -16462,22 +16715,22 @@ msgid "Geo|Unknown state"
msgstr "Ðевідомий Ñтан"
msgid "Geo|Updated %{timeAgo}"
-msgstr ""
+msgstr "Оновлено %{timeAgo}"
msgid "Geo|Verification"
-msgstr ""
+msgstr "Перевірка"
msgid "Geo|Verification failed - %{error}"
msgstr "Перевірка невдала: %{error}"
msgid "Geo|Verification information"
-msgstr ""
+msgstr "Ð†Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ Ð¿Ñ€Ð¾ перевірку"
msgid "Geo|Verification status"
-msgstr ""
+msgstr "Стан перевірки"
msgid "Geo|Verified"
-msgstr ""
+msgstr "Перевірено"
msgid "Geo|Waiting for scheduler"
msgstr "ÐžÑ‡Ñ–ÐºÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ð»Ð°Ð½ÑƒÐ²Ð°Ð»ÑŒÐ½Ð¸ÐºÐ°"
@@ -16489,7 +16742,7 @@ msgid "Geo|You are on a secondary, %{b_open}read-only%{b_close} Geo site."
msgstr ""
msgid "Geo|You may be able to make a limited amount of changes or perform a limited amount of actions on this page."
-msgstr ""
+msgstr "Ви зможете вноÑити лише обмежену кількіÑÑ‚ÑŒ змін та виконувати обмежений набір операцій з цієї Ñторінки."
msgid "Geo|misconfigured"
msgstr "неправильно налаштований"
@@ -16504,7 +16757,7 @@ msgid "Get a free instance review"
msgstr "Отримайте безкоштовну оцінку інÑтанÑа"
msgid "Get a free trial"
-msgstr ""
+msgstr "Спробувати безкоштовну пробну верÑÑ–ÑŽ"
msgid "Get a support subscription"
msgstr ""
@@ -16513,7 +16766,7 @@ msgid "Get started"
msgstr "Почати"
msgid "Get started with GitLab"
-msgstr ""
+msgstr "Розпочати роботу з GitLab"
msgid "Get started with error tracking"
msgstr "Розпочати роботу з відÑтеженнÑм помилок"
@@ -16531,7 +16784,7 @@ msgid "Git"
msgstr "Git"
msgid "Git GC period"
-msgstr ""
+msgstr "Період Ð·Ð±Ð¸Ñ€Ð°Ð½Ð½Ñ ÑÐ¼Ñ–Ñ‚Ñ‚Ñ Git"
msgid "Git LFS Rate Limits"
msgstr ""
@@ -16540,7 +16793,7 @@ msgid "Git LFS is not enabled on this GitLab server, contact your admin."
msgstr "Git LFS не увімкнено на цьому Ñервері GitLab, звернітьÑÑ Ð´Ð¾ адмініÑтратора."
msgid "Git LFS objects will be synced if LFS is %{docs_link_start}enabled for the project%{docs_link_end}. Push mirrors will %{strong_open}not%{strong_close} sync LFS objects over SSH."
-msgstr ""
+msgstr "Об'єкти Git LFS будуть Ñинхронізовані, Ñкщо LFS %{docs_link_start} увімкнено Ð´Ð»Ñ Ð¿Ñ€Ð¾Ñ”ÐºÑ‚Ñƒ%{docs_link_end}. Вихідні дзеркала %{strong_open}не будуть%{strong_close} Ñинхронізувати об'єкти LFS через SSH."
msgid "Git LFS status:"
msgstr "Ð¡Ñ‚Ð°Ñ‚ÑƒÑ Git LFS:"
@@ -16567,7 +16820,7 @@ 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-імпорт"
@@ -16596,11 +16849,17 @@ msgstr "Імпорт з GitLab"
msgid "GitLab Issue"
msgstr "Задача GitLab"
+msgid "GitLab KAS"
+msgstr ""
+
+msgid "GitLab Memberships CSV Export"
+msgstr ""
+
msgid "GitLab Pages"
msgstr "Gitlab Pages"
msgid "GitLab Shell"
-msgstr ""
+msgstr "GitLab Shell"
msgid "GitLab Support Bot"
msgstr "Бот Підтримки GitLab"
@@ -16618,7 +16877,7 @@ msgid "GitLab account request rejected"
msgstr ""
msgid "GitLab and Google Cloud configuration seems to be incomplete. This probably can be fixed by your GitLab administration team. You may share these logs with them:"
-msgstr ""
+msgstr "ÐšÐ¾Ð½Ñ„Ñ–Ð³ÑƒÑ€Ð°Ñ†Ñ–Ñ GitLab та Google Cloud незавершена. Можливо, ваша команда ÑƒÐ¿Ñ€Ð°Ð²Ð»Ñ–Ð½Ð½Ñ GitLab зможе це владнати. Ви можете надіÑлати їм ці логи:"
msgid "GitLab commit"
msgstr "GitLab коміт"
@@ -16644,6 +16903,9 @@ 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 "GitLab Ñ” окремою програмою Ð´Ð»Ñ Ð²Ñього життєвого циклу розробки програмного забезпеченнÑ. Від Ð¿Ð»Ð°Ð½ÑƒÐ²Ð°Ð½Ð½Ñ Ñ‚Ð° ÑƒÐ¿Ñ€Ð°Ð²Ð»Ñ–Ð½Ð½Ñ Ð²Ð¸Ñ…Ñ–Ð´Ð½Ð¸Ð¼Ð¸ кодами до CI/CD, моніторингу та безпеки."
+msgid "GitLab is free to use. Many features for larger teams are part of our %{link_start}paid products%{link_end}. You can try Ultimate for free without any obligation or payment details."
+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 "GitLab отримує SSL-Ñертифікат Ð´Ð»Ñ Ñ†ÑŒÐ¾Ð³Ð¾ домену від Let's Encrypt. Це може зайнÑти деÑкий чаÑ. Будь лаÑка, Ñпробуйте знову пізніше."
@@ -16654,7 +16916,7 @@ msgid "GitLab is undergoing maintenance and is operating in read-only mode."
msgstr ""
msgid "GitLab logo"
-msgstr ""
+msgstr "Логотип GitLab"
msgid "GitLab member or Email address"
msgstr "УчаÑник GitLab або адреÑа електронної пошти"
@@ -16684,7 +16946,7 @@ msgid "GitLab version"
msgstr "ВерÑÑ–Ñ GitLab"
msgid "GitLab will create a branch in your fork and start a merge request."
-msgstr ""
+msgstr "GitLab Ñтворить гілку у вашому форку та розпочне запит на злиттÑ."
msgid "GitLab.com"
msgstr "GitLab.com"
@@ -16711,7 +16973,7 @@ msgid "GitLabPages|Certificate: %{subject}"
msgstr "Сертифікат: %{subject}"
msgid "GitLabPages|Configure pages"
-msgstr "ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ñторінок"
+msgstr "Параметри Ñторінок"
msgid "GitLabPages|Domains"
msgstr "Домени"
@@ -16770,7 +17032,7 @@ msgstr "Підтверджено"
msgid "GitLabPages|When enabled, all attempts to visit your website through HTTP are automatically redirected to HTTPS using a response with status code 301. Requires a valid certificate for all domains. %{docs_link_start}Learn more.%{link_end}"
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. %{docs_link_start}Learn more.%{link_end}"
+msgid "GitLabPages|When using Pages under the general domain of a GitLab instance (%{pages_host}), you cannot use HTTPS with subdomains of subdomains. If your namespace or groupname contains a dot, it does not work. This is a limitation of the HTTP Over TLS protocol. HTTP pages work if you don't redirect HTTP to HTTPS. %{docs_link_start}Learn more.%{link_end}"
msgstr ""
msgid "GitLabPages|With GitLab Pages you can host your static website directly from your GitLab repository. %{docs_link_start}Learn more.%{link_end}"
@@ -16837,7 +17099,7 @@ msgid "Gitpod|The URL to your Gitpod instance configured to read your GitLab pro
msgstr ""
msgid "Gitpod|To use Gitpod you must first enable the feature in the integrations section of your %{linkStart}user preferences%{linkEnd}."
-msgstr ""
+msgstr "Ð”Ð»Ñ Ð²Ð¸ÐºÐ¾Ñ€Ð¸ÑÑ‚Ð°Ð½Ð½Ñ Gitpod, Ñпочатку ви повинні увімкнути у розділі інтеграцій функцію ваших %{linkStart}налаштувань кориÑтувача%{linkEnd}."
msgid "Gitpod|To use the integration, each user must also enable Gitpod on their GitLab account. %{link_start}How do I enable it?%{link_end} "
msgstr ""
@@ -16861,22 +17123,22 @@ msgid "Global notification settings"
msgstr "Загальні Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ñповіщень"
msgid "GlobalSearch|%{count} default results provided. Use the up and down arrow keys to navigate search results list."
-msgstr ""
+msgstr "%{count} надано результати за замовчуваннÑм. ВикориÑтовуйте верхні та нижні клавіші зі Ñтрілками, щоб перейти до ÑпиÑку результатів пошуку."
msgid "GlobalSearch|Issues I've created"
-msgstr ""
+msgstr "Створені мною задачі"
msgid "GlobalSearch|Issues assigned to me"
-msgstr ""
+msgstr "Задачі призначені Ð´Ð»Ñ Ð¼ÐµÐ½Ðµ"
msgid "GlobalSearch|Merge requests I've created"
-msgstr ""
+msgstr "Створені мною запити на злиттÑ"
msgid "GlobalSearch|Merge requests assigned to me"
-msgstr ""
+msgstr "Запити на Ð·Ð»Ð¸Ñ‚Ñ‚Ñ Ð¿Ñ€Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ñ– Ð´Ð»Ñ Ð¼ÐµÐ½Ðµ"
msgid "GlobalSearch|Merge requests that I'm a reviewer"
-msgstr ""
+msgstr "Запити на злиттÑ, Ñкі Ñ Ð¾Ð³Ð»Ñдаю"
msgid "GlobalSearch|Results updated. %{count} results available. Use the up and down arrow keys to navigate search results list, or ENTER to submit."
msgstr ""
@@ -16888,16 +17150,16 @@ msgid "GlobalSearch|Search results are loading"
msgstr ""
msgid "GlobalSearch|Type and press the enter key to submit search."
-msgstr ""
+msgstr "Введіть та натиÑніть клавішу Enter Ð´Ð»Ñ Ð¿Ñ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¶ÐµÐ½Ð½Ñ Ð¿Ð¾ÑˆÑƒÐºÑƒ."
msgid "GlobalSearch|Type for new suggestions to appear below."
-msgstr ""
+msgstr "Введіть, щоб нижче з'ÑвилиÑÑ Ð½Ð¾Ð²Ñ– пропозиції."
msgid "GlobalSearch|in all GitLab"
msgstr "У вÑьому GitLab"
msgid "GlobalSearch|in group"
-msgstr ""
+msgstr "у групі"
msgid "GlobalSearch|in project"
msgstr "В проєкті"
@@ -16947,9 +17209,6 @@ msgstr "Перейти до файлів"
msgid "Go to find file"
msgstr "Перейти до пошуку файлів"
-msgid "Go to fork"
-msgstr "Перейти до форку"
-
msgid "Go to issue boards"
msgstr "Перейти до дошок задач"
@@ -16969,22 +17228,22 @@ msgid "Go to metrics"
msgstr "Перейти до метрик"
msgid "Go to next page"
-msgstr ""
+msgstr "Перейти на наÑтупну Ñторінку"
msgid "Go to page %{page}"
-msgstr ""
+msgstr "Перейдіть на Ñторінку %{page}"
msgid "Go to parent"
msgstr "Перейти на рівень вище"
msgid "Go to parent directory"
-msgstr ""
+msgstr "Перейти до батьківÑького каталогу"
msgid "Go to previous page"
-msgstr ""
+msgstr "Перейти до попередньої Ñторінки"
msgid "Go to primary site"
-msgstr ""
+msgstr "Перейдіть на оÑновний Ñайт"
msgid "Go to project"
msgstr "Перейти до проєкту"
@@ -17056,19 +17315,19 @@ msgid "Google Cloud"
msgstr "Google Cloud"
msgid "Google Cloud Project"
-msgstr ""
+msgstr "Проєкт Google Cloud"
msgid "Google Cloud authorizations required"
-msgstr ""
+msgstr "Потрібно авторизуватиÑÑ Ð² Google Cloud"
msgid "Google Cloud project"
-msgstr ""
+msgstr "Проєкт Google Cloud"
msgid "Google Cloud project misconfigured"
-msgstr ""
+msgstr "Ðеправильно налаштовано проєкт Google Cloud"
msgid "Google Cloud project required"
-msgstr ""
+msgstr "Потрібен проєкт Google Cloud"
msgid "Google authentication is not %{link_start}properly configured%{link_end}. Ask your GitLab administrator if you want to use this service."
msgstr "ÐÐ²Ñ‚ÐµÐ½Ñ‚Ð¸Ñ„Ñ–ÐºÐ°Ñ†Ñ–Ñ Google не %{link_start}налаштована належним чином%{link_end}. ЗвернітьÑÑ Ð´Ð¾ вашого адмініÑтратора GitLab Ñкщо хочете викориÑтовувати цю Ñлужбу."
@@ -17083,10 +17342,10 @@ msgid "Grafana URL"
msgstr "URL-адреÑа Grafana"
msgid "Grafana response contains invalid json"
-msgstr ""
+msgstr "Відповідь Grafana міÑтить недійÑний json"
msgid "GrafanaIntegration|API token"
-msgstr ""
+msgstr "Токен API"
msgid "GrafanaIntegration|Active"
msgstr "Увімкнено"
@@ -17101,7 +17360,7 @@ msgid "GrafanaIntegration|Grafana URL"
msgstr "Grafana URL"
msgid "GrafanaIntegration|Grafana authentication"
-msgstr ""
+msgstr "ÐÐ²Ñ‚ÐµÐ½Ñ‚Ð¸Ñ„Ñ–ÐºÐ°Ñ†Ñ–Ñ Grafana"
msgid "GrafanaIntegration|Set up Grafana authentication to embed Grafana panels in GitLab Flavored Markdown."
msgstr ""
@@ -17110,19 +17369,19 @@ msgid "Grant access"
msgstr "Ðадати доÑтуп"
msgid "Grant write permissions to this key"
-msgstr ""
+msgstr "Ðадайте дозволи на Ð·Ð°Ð¿Ð¸Ñ Ð´Ð»Ñ Ñ†ÑŒÐ¾Ð³Ð¾ ключа"
msgid "Graph"
msgstr "Граф"
msgid "GraphViewType|Job dependencies"
-msgstr ""
+msgstr "ЗалежноÑÑ‚Ñ– завдань"
msgid "GraphViewType|Show dependencies"
-msgstr ""
+msgstr "Показати залежноÑÑ‚Ñ–"
msgid "GraphViewType|Stage"
-msgstr ""
+msgstr "СтадіÑ"
msgid "Graphs"
msgstr ""
@@ -17149,7 +17408,7 @@ msgid "Group %{group_name} was successfully created."
msgstr "Групу %{group_name} уÑпішно Ñтворено."
msgid "Group Access Tokens"
-msgstr ""
+msgstr "Токени доÑтупу групи"
msgid "Group Git LFS status:"
msgstr "Ð¡Ñ‚Ð°Ñ‚ÑƒÑ Ð³Ñ€ÑƒÐ¿Ð¸ Git LFS:"
@@ -17157,9 +17416,6 @@ msgstr "Ð¡Ñ‚Ð°Ñ‚ÑƒÑ Ð³Ñ€ÑƒÐ¿Ð¸ Git LFS:"
msgid "Group Hooks"
msgstr "Хуки Групи"
-msgid "Group ID"
-msgstr "Ідентифікатор групи"
-
msgid "Group Owner must have signed in with SAML before enabling Group Managed Accounts"
msgstr ""
@@ -17179,7 +17435,7 @@ msgid "Group applications"
msgstr ""
msgid "Group audit events"
-msgstr ""
+msgstr "Групові події аудиту"
msgid "Group avatar"
msgstr "Ðватар групи"
@@ -17187,9 +17443,6 @@ msgstr "Ðватар групи"
msgid "Group by"
msgstr "Групувати за"
-msgid "Group description"
-msgstr ""
-
msgid "Group description (optional)"
msgstr "ÐžÐ¿Ð¸Ñ Ð³Ñ€ÑƒÐ¿Ð¸ (необов'Ñзково)"
@@ -17230,7 +17483,7 @@ msgid "Group information"
msgstr "Ð†Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ Ð¿Ñ€Ð¾ групу"
msgid "Group is required when cluster_type is :group"
-msgstr ""
+msgstr "Група Ñ” обов'Ñзковою, Ñкщо cluster_type Ñ” :group"
msgid "Group jobs by"
msgstr "Групувати Ð·Ð°Ð²Ð´Ð°Ð½Ð½Ñ Ð·Ð°"
@@ -17290,13 +17543,13 @@ msgid "Group variables (inherited)"
msgstr "Змінні групи (уÑпадковані)"
msgid "Group was exported"
-msgstr ""
+msgstr "Група була екÑпортована"
msgid "Group was successfully updated."
msgstr "Групу уÑпішно оновлено."
msgid "Group wikis"
-msgstr ""
+msgstr "Wiki-Ñторінки групи"
msgid "Group: %{group_name}"
msgstr "Група: %{group_name}"
@@ -17304,26 +17557,26 @@ msgstr "Група: %{group_name}"
msgid "Group: %{name}"
msgstr "Група: %{name}"
-msgid "GroupActivityMetrics|Issues opened"
+msgid "GroupActivityMetrics|Issues created"
msgstr ""
msgid "GroupActivityMetrics|Last 90 days"
msgstr "ОÑтанні 90 днів"
msgid "GroupActivityMetrics|Members added"
-msgstr ""
+msgstr "УчаÑники додані"
-msgid "GroupActivityMetrics|Merge Requests opened"
+msgid "GroupActivityMetrics|Merge Requests created"
msgstr ""
msgid "GroupActivityMetrics|Recent activity"
-msgstr ""
+msgstr "ÐÐµÑ‰Ð¾Ð´Ð°Ð²Ð½Ñ Ð°ÐºÑ‚Ð¸Ð²Ð½Ñ–ÑÑ‚ÑŒ"
msgid "GroupImport|Failed to import group."
-msgstr ""
+msgstr "Ðе вдалоÑÑ Ñ–Ð¼Ð¿Ð¾Ñ€Ñ‚ÑƒÐ²Ð°Ñ‚Ð¸ групу."
msgid "GroupImport|Group '%{group_name}' is being imported."
-msgstr ""
+msgstr "Група '%{group_name}' імпортуєтьÑÑ."
msgid "GroupImport|Group could not be imported: %{errors}"
msgstr ""
@@ -17341,10 +17594,10 @@ msgid "GroupPage|Copy group ID"
msgstr "Копіювати ID групи"
msgid "GroupPage|Group ID: %{group_id}"
-msgstr ""
+msgstr "Ідентифікатор групи: %{group_id}"
msgid "GroupRoadmap|%{dateWord} – No end date"
-msgstr ""
+msgstr "%{dateWord} – дати Ð·Ð°ÐºÑ–Ð½Ñ‡ÐµÐ½Ð½Ñ Ð½ÐµÐ¼Ð°Ñ”"
msgid "GroupRoadmap|%{startDateInWords} – %{endDateInWords}"
msgstr "%{startDateInWords} – %{endDateInWords}"
@@ -17353,10 +17606,10 @@ msgid "GroupRoadmap|Loading epics"
msgstr "Ð—Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ ÐµÐ¿Ñ–ÐºÑ–Ð²"
msgid "GroupRoadmap|No start and end date"
-msgstr ""
+msgstr "Дати початку та Ð·Ð°ÐºÑ–Ð½Ñ‡ÐµÐ½Ð½Ñ Ð½ÐµÐ¼Ð°Ñ”"
msgid "GroupRoadmap|No start date – %{dateWord}"
-msgstr ""
+msgstr "Дати початку немає – %{dateWord}"
msgid "GroupRoadmap|Something went wrong while fetching epics"
msgstr "Проблема при завантаженні епіків"
@@ -17410,7 +17663,7 @@ msgid "GroupSAML|Are you sure you want to remove the SAML group link?"
msgstr ""
msgid "GroupSAML|Are you sure you want to reset the SCIM token? SCIM provisioning will stop working until the new token is updated."
-msgstr ""
+msgstr "Ви впевнені, що хочете Ñкинути токен SCIM? Ð’Ð¸ÐºÐ¾Ð½Ð°Ð½Ð½Ñ SCIM переÑтане працювати доти, поки новий токен не буде оновлено."
msgid "GroupSAML|Before enforcing SSO, enable SAML authentication."
msgstr ""
@@ -17422,7 +17675,7 @@ msgid "GroupSAML|Certificate fingerprint"
msgstr "Відбиток Ñертифікату"
msgid "GroupSAML|Configuration"
-msgstr "ÐалаштуваннÑ"
+msgstr "Параметри"
msgid "GroupSAML|Copy SAML Response XML"
msgstr ""
@@ -17509,7 +17762,7 @@ msgid "GroupSAML|SAML Single Sign On"
msgstr "Єдиний вхід через SAML"
msgid "GroupSAML|SAML Single Sign On Settings"
-msgstr "ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ñ”Ð´Ð¸Ð½Ð¾Ð³Ð¾ входу через SAML"
+msgstr "Параметри єдиного входу через SAML"
msgid "GroupSAML|SAML group link was successfully removed."
msgstr ""
@@ -17545,7 +17798,7 @@ msgid "GroupSAML|With prohibit outer forks flag enabled group members will be ab
msgstr ""
msgid "GroupSAML|as %{access_level}"
-msgstr ""
+msgstr "Ñк %{access_level}"
msgid "GroupSAML|must match stored NameID of \"%{extern_uid}\" to identify user and allow sign in"
msgstr ""
@@ -17557,13 +17810,13 @@ msgid "GroupSaml|Copy SCIM API endpoint URL"
msgstr ""
msgid "GroupSaml|Copy SCIM token"
-msgstr ""
+msgstr "Скопіювати токен SCIM"
msgid "GroupSaml|SCIM API endpoint URL"
msgstr ""
msgid "GroupSaml|Your SCIM token"
-msgstr ""
+msgstr "Ваш токен SCIM"
msgid "GroupSelect|No matching results"
msgstr ""
@@ -17575,7 +17828,7 @@ msgid "GroupSelect|Select a group"
msgstr "Вибрати групу"
msgid "GroupSettings|Allow project and group access token creation"
-msgstr ""
+msgstr "Дозволити ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ñ‚Ð¾ÐºÐµÐ½Ñƒ доÑтупу до проєкту та групи"
msgid "GroupSettings|Allows creating organizations and contacts and associating them with issues."
msgstr ""
@@ -17604,6 +17857,9 @@ msgstr "Змінити URL-адреÑу групи"
msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
+msgid "GroupSettings|Choose a group path that does not start with a dash or end with a period. It can also contain alphanumeric characters and underscores."
+msgstr ""
+
msgid "GroupSettings|Compliance frameworks"
msgstr ""
@@ -17632,13 +17888,13 @@ msgid "GroupSettings|Enable delayed project deletion"
msgstr ""
msgid "GroupSettings|Export group"
-msgstr ""
+msgstr "ЕкÑпортувати групу"
msgid "GroupSettings|If not specified at the group or instance level, the default is %{default_initial_branch_name}. Does not affect existing repositories."
msgstr ""
-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|If the parent group's visibility is lower than the group's current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility."
+msgstr ""
msgid "GroupSettings|New runners registration token has been generated!"
msgstr "Згенеровано новий токен Ð´Ð»Ñ Ñ€ÐµÑ”Ñтрації runner'ів!"
@@ -17650,7 +17906,7 @@ msgid "GroupSettings|Pipeline settings was updated for the group"
msgstr "ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ ÐºÐ¾Ð½Ð²ÐµÑ”Ñ€Ñ–Ð² були оновлені Ð´Ð»Ñ Ñ†Ñ–Ñ”Ñ— групи"
msgid "GroupSettings|Please choose a group URL with no special characters or spaces."
-msgstr ""
+msgstr "Будь лаÑка, оберіть URL-адреÑу групи без Ñпеціальних Ñимволів або пробілів."
msgid "GroupSettings|Prevent forking outside of the group"
msgstr ""
@@ -17719,7 +17975,7 @@ msgid "GroupSettings|Users can create %{link_start_project}project access tokens
msgstr ""
msgid "GroupSettings|What are badges?"
-msgstr ""
+msgstr "Що таке значки?"
msgid "GroupSettings|When the number of active users exceeds this number, additional users must be %{user_cap_docs_link_start}approved by an owner%{user_cap_docs_link_end}. Leave empty if you don't want to enforce approvals."
msgstr ""
@@ -17734,7 +17990,7 @@ msgid "GroupSettings|You will need to update your local repositories to point to
msgstr "Вам необхідно обновити Ñвої локальні репозиторії з тим, щоб вони вказували на нове розміщеннÑ."
msgid "GroupSettings|cannot be changed by you"
-msgstr ""
+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 "не може бути ÑкаÑовано поки \"Ð‘Ð»Ð¾ÐºÑƒÐ²Ð°Ð½Ð½Ñ Ñпільного доÑтупу з іншими групами\" активне на батьківÑькій групі, за винÑтком влаÑника батьківÑької групи"
@@ -17754,8 +18010,11 @@ msgstr "Групи (%{count})"
msgid "Groups and projects"
msgstr "Групи та проєкти"
-msgid "Groups and subgroups"
-msgstr "Групи і підгрупи"
+msgid "Groups are a great way to organize projects and people."
+msgstr ""
+
+msgid "Groups are the best way to manage projects and members."
+msgstr ""
msgid "Groups to synchronize"
msgstr "Групи Ð´Ð»Ñ Ñинхронізації"
@@ -17800,7 +18059,7 @@ msgid "GroupsNew|Assemble related projects together and grant members access to
msgstr ""
msgid "GroupsNew|Connect instance"
-msgstr ""
+msgstr "Підключити інÑтанÑ"
msgid "GroupsNew|Contact an administrator to enable options for importing your group."
msgstr ""
@@ -17815,7 +18074,7 @@ msgid "GroupsNew|Export groups with all their related data and move to a new Git
msgstr ""
msgid "GroupsNew|GitLab source URL"
-msgstr ""
+msgstr "Вихідна URL-адреÑа GitLab"
msgid "GroupsNew|Groups can also be nested by creating %{linkStart}subgroups%{linkEnd}."
msgstr ""
@@ -17833,25 +18092,25 @@ msgid "GroupsNew|Navigate to user settings to find your %{link_start}personal ac
msgstr ""
msgid "GroupsNew|No import options available"
-msgstr ""
+msgstr "Ðемає доÑтупних параметрів імпорту"
msgid "GroupsNew|Not all related objects are migrated. %{docs_link_start}More info%{docs_link_end}."
msgstr ""
msgid "GroupsNew|Personal access token"
-msgstr ""
+msgstr "ОÑобиÑтий токен доÑтупу"
msgid "GroupsNew|Please fill in GitLab source URL."
-msgstr ""
+msgstr "Будь лаÑка, заповніть вихідну URL-адреÑу GitLab."
msgid "GroupsNew|Please fill in your personal access token."
-msgstr ""
+msgstr "Будь лаÑка, заповніть ваш оÑобиÑтий токен доÑтупу."
msgid "GroupsNew|Provide credentials for another instance of GitLab to import your groups directly."
msgstr ""
msgid "GroupsNew|This feature is deprecated and replaced by %{docs_link_start}group migration%{docs_link_end}."
-msgstr ""
+msgstr "Ð¦Ñ Ñ„ÑƒÐ½ÐºÑ†Ñ–Ñ Ð·Ð°Ñтаріла Ñ– замінена на %{docs_link_start}груповою міграцією%{docs_link_end}."
msgid "GroupsNew|To import a group, navigate to the group settings for the GitLab source instance, %{link_start}generate an export file%{link_end}, and upload it here."
msgstr ""
@@ -17860,19 +18119,22 @@ msgid "GroupsNew|Upload file"
msgstr "Завантажити файл"
msgid "GroupsNew|e.g. h8d3f016698e..."
-msgstr ""
+msgstr "напр. h8d3f016698e..."
msgid "GroupsTree|Are you sure you want to leave the \"%{fullName}\" group?"
msgstr "Ви впевнені, що хочете залишити групу \"%{fullName}\"?"
-msgid "GroupsTree|Edit group"
-msgstr "Редагувати групу"
+msgid "GroupsTree|Delete"
+msgstr ""
+
+msgid "GroupsTree|Edit"
+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|Leave group"
+msgstr ""
msgid "GroupsTree|Loading groups"
msgstr "Ð—Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ð³Ñ€ÑƒÐ¿"
@@ -17883,16 +18145,67 @@ msgstr "Жодна группа не задовольнÑÑ” параметрам
msgid "GroupsTree|No groups or projects matched your search"
msgstr "Жодна группа чи проєкт не задовольнÑÑ” параметрам вашого запиту"
+msgid "GroupsTree|Options"
+msgstr ""
+
msgid "GroupsTree|Search by name"
msgstr "Пошук за іменем"
+msgid "Groups|Avatar will be removed. Are you sure?"
+msgstr ""
+
+msgid "Groups|Changing group URL can have unintended side effects."
+msgstr ""
+
+msgid "Groups|Checking group URL availability..."
+msgstr ""
+
+msgid "Groups|Enter a descriptive name for your group."
+msgstr ""
+
+msgid "Groups|Group ID"
+msgstr ""
+
+msgid "Groups|Group URL"
+msgstr ""
+
+msgid "Groups|Group avatar"
+msgstr ""
+
+msgid "Groups|Group description (optional)"
+msgstr ""
+
+msgid "Groups|Group name"
+msgstr ""
+
+msgid "Groups|Group path is available."
+msgstr ""
+
+msgid "Groups|Group path is unavailable. Path has been replaced with a suggested available path."
+msgstr ""
+
+msgid "Groups|Learn more"
+msgstr ""
+
+msgid "Groups|Must start with letter, digit, emoji, or underscore. Can also contain periods, dashes, spaces, and parentheses."
+msgstr ""
+
+msgid "Groups|Remove avatar"
+msgstr ""
+
+msgid "Groups|Save changes"
+msgstr ""
+
msgid "Guideline"
msgstr "Керівництво"
msgid "HAR (HTTP Archive)"
-msgstr ""
+msgstr "HAR (архів HTTP)"
msgid "HAR file path or URL"
+msgstr "ШлÑÑ… до файлу HAR або URL-адреÑа"
+
+msgid "HTTP Archive (HAR)"
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}"
@@ -17914,7 +18227,7 @@ msgid "Have more to say about GitLab?"
msgstr ""
msgid "Header logo"
-msgstr ""
+msgstr "Логотип заголовка"
msgid "Header logo was successfully removed."
msgstr "Логотип в заголовку уÑпішно видалено."
@@ -17926,10 +18239,10 @@ msgid "Header message"
msgstr "ÐŸÐ¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð·Ð°Ð³Ð¾Ð»Ð¾Ð²ÐºÐ°"
msgid "HeaderAction|incident"
-msgstr ""
+msgstr "інцидент"
msgid "HeaderAction|issue"
-msgstr ""
+msgstr "задача"
msgid "Headers"
msgstr "Заголовки"
@@ -18084,7 +18397,7 @@ msgid "Hide values"
msgstr "Сховати значеннÑ"
msgid "Hierarchy|Current structure"
-msgstr ""
+msgstr "Поточна Ñтруктура"
msgid "Hierarchy|Deliver value more efficiently by breaking down necessary work into a hierarchical structure. This structure helps teams understand scope, priorities, and how work cascades up toward larger goals."
msgstr ""
@@ -18096,19 +18409,19 @@ msgid "Hierarchy|Is there a framework or type of work item you wish you had acce
msgstr ""
msgid "Hierarchy|Planning hierarchy"
-msgstr ""
+msgstr "Ð†Ñ”Ñ€Ð°Ñ€Ñ…Ñ–Ñ Ð¿Ð»Ð°Ð½ÑƒÐ²Ð°Ð½Ð½Ñ"
msgid "Hierarchy|Take the work items survey"
msgstr ""
msgid "Hierarchy|These items are unavailable in the current structure."
-msgstr ""
+msgstr "Ці елементи недоÑтупні в поточній Ñтруктурі."
msgid "Hierarchy|Unavailable structure"
-msgstr ""
+msgstr "ÐедоÑтупна Ñтруктура"
msgid "Hierarchy|You can start using these items now."
-msgstr ""
+msgstr "Ви можете почати викориÑтовувати ці елементи зараз."
msgid "High or unknown vulnerabilities present"
msgstr "ПриÑутні вразливоÑÑ‚Ñ– виÑокого або невідомого рівнÑ"
@@ -18198,7 +18511,7 @@ msgid "How do I set up a Google Chat webhook?"
msgstr ""
msgid "How do I set up this service?"
-msgstr ""
+msgstr "Як налаштувати цей ÑервіÑ?"
msgid "How do I use a web terminal?"
msgstr ""
@@ -18228,7 +18541,7 @@ msgid "I want to explore GitLab to see if it’s worth switching to"
msgstr ""
msgid "I want to learn the basics of Git"
-msgstr ""
+msgstr "Я хочу вивчити оÑнови Git"
msgid "I want to move my repository to GitLab from somewhere else"
msgstr ""
@@ -18299,6 +18612,9 @@ msgstr ""
msgid "INFO: Your SSH key is expiring soon. Please generate a new key."
msgstr ""
+msgid "IP"
+msgstr ""
+
msgid "IP Address"
msgstr "IP-адреÑа"
@@ -18324,15 +18640,18 @@ msgid "Identities"
msgstr "ІдентифікаціÑ"
msgid "IdentityVerification|Before you create your first project, we need you to verify your identity with a valid payment method. You will not be charged during this step. If we ever need to charge you, we will let you know."
-msgstr ""
+msgstr "Перш ніж Ñтворити Ñвій перший проєкт, вам потрібно підтвердити Ñвою оÑобу за допомогою дійÑного ÑпоÑобу оплати. З Ð²Ð°Ñ Ð½Ðµ ÑÑ‚ÑгуватиметьÑÑ Ð¿Ð»Ð°Ñ‚Ð° під Ñ‡Ð°Ñ Ñ†Ñ–Ñ”Ñ— операції. Якщо нам колиÑÑŒ буде потрібно ÑÑ‚Ñгнути з Ð²Ð°Ñ Ð¿Ð»Ð°Ñ‚Ñƒ, ми вам повідомимо."
msgid "IdentityVerification|Before you create your group, we need you to verify your identity with a valid payment method. You will not be charged during this step. If we ever need to charge you, we will let you know."
-msgstr ""
+msgstr "Перш ніж Ñтворити Ñвою групу, вам потрібно підтвердити Ñвою оÑобу за допомогою дійÑного ÑпоÑобу оплати. З Ð²Ð°Ñ Ð½Ðµ ÑÑ‚ÑгуватиметьÑÑ Ð¿Ð»Ð°Ñ‚Ð° під Ñ‡Ð°Ñ Ñ†Ñ–Ñ”Ñ— операції. Якщо нам колиÑÑŒ буде потрібно ÑÑ‚Ñгнути з Ð²Ð°Ñ Ð¿Ð»Ð°Ñ‚Ñƒ, ми вам повідомимо."
msgid "IdentityVerification|Create a project"
-msgstr ""
+msgstr "Створити проєкт"
msgid "IdentityVerification|Verify your identity"
+msgstr "Підтвердити Ñвою оÑобу"
+
+msgid "IdentityVerification|You can always verify your account at a later time to create a group."
msgstr ""
msgid "If any indexed field exceeds this limit, it is truncated to this number of characters. The rest of the content is neither indexed nor searchable. This does not apply to repository and wiki indexing. For unlimited characters, set this to 0."
@@ -18392,6 +18711,9 @@ msgstr "При викориÑтанні GitHub, ви побачите Ñтату
msgid "If you add %{codeStart}needs%{codeEnd} to jobs in your pipeline you'll be able to view the %{codeStart}needs%{codeEnd} relationships between jobs in this tab as a %{linkStart}Directed Acyclic Graph (DAG)%{linkEnd}."
msgstr ""
+msgid "If you are added to a project, it will be displayed here."
+msgstr ""
+
msgid "If you did not initiate these sign-in attempts, please reach out to your administrator or enable two-factor authentication (2FA) on your account."
msgstr ""
@@ -18417,13 +18739,13 @@ msgid "If you recently signed in and recognize the IP address, you may disregard
msgstr ""
msgid "If you want to re-enable two-factor authentication, visit %{two_factor_link}"
-msgstr ""
+msgstr "Якщо ви хочете знову увімкнути двофакторну автентифікацію, перейдіть на Ñторінку %{two_factor_link}"
msgid "If you want to re-enable two-factor authentication, visit the %{settings_link_to} page."
-msgstr ""
+msgstr "Якщо ви хочете знову увімкнути двофакторну автентифікацію, перейдіть на Ñторінку %{settings_link_to}."
msgid "If you've purchased or renewed your subscription and have an activation code, please enter it below to start the activation process."
-msgstr ""
+msgstr "Якщо ви придбали або поновили Ñвою підпиÑку Ñ– маєте код активації, введіть його нижче, щоб почати Ð¿Ñ€Ð¾Ñ†ÐµÑ Ð°ÐºÑ‚Ð¸Ð²Ð°Ñ†Ñ–Ñ—."
msgid "If your HTTP repository is not publicly accessible, add your credentials."
msgstr "Якщо ваш HTTP-репозиторій не Ñ” загальнодоÑтупним, додайте Ñвої облікові дані."
@@ -18462,7 +18784,7 @@ msgid "Impersonate"
msgstr ""
msgid "Impersonation Tokens"
-msgstr ""
+msgstr "Токени імітуваннÑ"
msgid "Impersonation has been disabled"
msgstr "Ð†Ð¼Ñ–Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð±ÑƒÐ»Ð¾ вимкнено"
@@ -18494,7 +18816,7 @@ msgid "Import an exported GitLab project"
msgstr "Імпортувати екÑпортований проєкт GitLab"
msgid "Import and export rate limits"
-msgstr ""
+msgstr "ÐžÐ±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ Ñ‡Ð°Ñтоти імпорту та екÑпорту"
msgid "Import failed due to a GitHub error: %{original}"
msgstr ""
@@ -18581,19 +18903,19 @@ msgid "Import timed out. Import took longer than %{import_jobs_expiration} secon
msgstr "Ð§Ð°Ñ Ñ–Ð¼Ð¿Ð¾Ñ€Ñ‚Ñƒ вичерпано. Імпорт зайнÑв більше %{import_jobs_expiration} Ñекунд"
msgid "ImportAProjectModal|Import from a project"
-msgstr ""
+msgstr "Імпортувати з проєкту"
msgid "ImportAProjectModal|Import members from another project"
msgstr ""
msgid "ImportAProjectModal|Import project members"
-msgstr ""
+msgstr "Імпортувати учаÑників проєкту"
msgid "ImportAProjectModal|Only project members (not group members) are imported, and they get the same permissions as the project you import from."
msgstr ""
msgid "ImportAProjectModal|Successfully imported"
-msgstr ""
+msgstr "УÑпішно імпортовано"
msgid "ImportAProjectModal|Unable to import project members"
msgstr ""
@@ -18620,7 +18942,7 @@ msgid "ImportProjects|Importing the project failed"
msgstr "Ð†Ð¼Ð¿Ð¾Ñ€Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ñ€Ð¾Ñ”ÐºÑ‚Ñƒ невдале"
msgid "ImportProjects|Importing the project failed: %{reason}"
-msgstr ""
+msgstr "Ðе вдалоÑÑ Ñ–Ð¼Ð¿Ð¾Ñ€Ñ‚ÑƒÐ²Ð°Ñ‚Ð¸ проєкт: %{reason}"
msgid "ImportProjects|Requesting namespaces failed"
msgstr ""
@@ -18675,7 +18997,7 @@ msgid "In this page you will find information about the settings that are used i
msgstr ""
msgid "InProductMarketing|%{organization_name} logo"
-msgstr ""
+msgstr "%{organization_name} логотип"
msgid "InProductMarketing|%{strong_start}Advanced application security%{strong_end} — including SAST, DAST scanning, FUZZ testing, dependency scanning, license compliance, secrete detection"
msgstr ""
@@ -18704,12 +19026,24 @@ msgstr ""
msgid "InProductMarketing|3 ways to dive into GitLab CI/CD"
msgstr ""
+msgid "InProductMarketing|A single application eliminates complex integrations, data chokepoints, and toolchain maintenance, resulting in greater productivity and lower cost."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features, build more efficiently, strengthen security and compliance."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features."
+msgstr ""
+
msgid "InProductMarketing|Actually, GitLab makes the team work (better)"
msgstr ""
msgid "InProductMarketing|And finally %{deploy_link} a Python application."
msgstr ""
+msgid "InProductMarketing|And many more..."
+msgstr ""
+
msgid "InProductMarketing|Are your runners ready?"
msgstr ""
@@ -18726,6 +19060,12 @@ msgid "InProductMarketing|Better code in less time"
msgstr ""
msgid "InProductMarketing|Blog"
+msgstr "Блог"
+
+msgid "InProductMarketing|Break down silos to coordinate seamlessly across development, operations, and security with a consistent experience across the development lifecycle."
+msgstr ""
+
+msgid "InProductMarketing|Burn up/down charts"
msgstr ""
msgid "InProductMarketing|By enabling code owners and required merge approvals the right person will review the right MR. This is a win-win: cleaner code and a more efficient review process."
@@ -18734,9 +19074,21 @@ msgstr ""
msgid "InProductMarketing|Click on the number below that corresponds with your answer — 1 being very difficult, 5 being very easy."
msgstr ""
+msgid "InProductMarketing|Code owners"
+msgstr ""
+
msgid "InProductMarketing|Code owners and required merge approvals are part of the paid tiers of GitLab. You can start a free 30-day trial of GitLab Ultimate and enable these features in less than 5 minutes with no credit card required."
msgstr ""
+msgid "InProductMarketing|Code review analytics"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration across stages in GitLab"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration made easy"
+msgstr ""
+
msgid "InProductMarketing|Create a custom CI runner with just a few clicks"
msgstr ""
@@ -18746,12 +19098,21 @@ msgstr "Створити влаÑного runner"
msgid "InProductMarketing|Create a project in GitLab in 5 minutes"
msgstr ""
+msgid "InProductMarketing|Create well-defined workflows by using scoped labels on issues, merge requests, and epics. Labels with the same scope cannot be used together, which prevents conflicts."
+msgstr ""
+
msgid "InProductMarketing|Create your first project!"
msgstr ""
+msgid "InProductMarketing|Define who owns specific files or directories, so the right reviewers are suggested when a merge request introduces changes to those files."
+msgstr ""
+
msgid "InProductMarketing|Deliver Better Products Faster"
msgstr ""
+msgid "InProductMarketing|Dependency scanning"
+msgstr ""
+
msgid "InProductMarketing|Did you know teams that use GitLab are far more efficient?"
msgstr ""
@@ -18761,15 +19122,27 @@ msgstr ""
msgid "InProductMarketing|Dig in and create a project and a repo"
msgstr ""
+msgid "InProductMarketing|Discover Premium & Ultimate"
+msgstr ""
+
+msgid "InProductMarketing|Discover Premium & Ultimate."
+msgstr ""
+
msgid "InProductMarketing|Do you have a minute?"
msgstr ""
msgid "InProductMarketing|Do you have a teammate who would be perfect for this task?"
msgstr ""
+msgid "InProductMarketing|Dynamic application security testing"
+msgstr ""
+
msgid "InProductMarketing|Easy"
msgstr "Легко"
+msgid "InProductMarketing|Epics"
+msgstr ""
+
msgid "InProductMarketing|Expand your DevOps journey with a free GitLab trial"
msgstr ""
@@ -18791,9 +19164,15 @@ msgstr ""
msgid "InProductMarketing|Feel the need for speed?"
msgstr ""
+msgid "InProductMarketing|Find and fix bottlenecks in your code review process by understanding how long open merge requests have been in review."
+msgstr ""
+
msgid "InProductMarketing|Find out how your teams are really doing"
msgstr ""
+msgid "InProductMarketing|Find out if your external libraries are safe. Run dependency scanning jobs that check for known vulnerabilities in your external libraries."
+msgstr ""
+
msgid "InProductMarketing|Follow our steps"
msgstr ""
@@ -18830,38 +19209,41 @@ msgstr "GitHub Enterprise Ð´Ð»Ñ GitLab"
msgid "InProductMarketing|GitLab is better with teammates to help out!"
msgstr ""
+msgid "InProductMarketing|GitLab is infrastructure agnostic (supporting GCP, AWS, Azure, OpenShift, VMWare, On Prem, Bare Metal, and more), offering a consistent workflow experience – irrespective of the environment."
+msgstr ""
+
msgid "InProductMarketing|GitLab provides static application security testing (SAST), dynamic application security testing (DAST), container scanning, and dependency scanning to help you deliver secure applications along with license compliance."
msgstr ""
msgid "InProductMarketing|GitLab's CI/CD makes software development easier. Don't believe us? Here are three ways you can take it for a fast (and satisfying) test drive:"
-msgstr ""
+msgstr "GitLab's CI/CD Ñпрощує розробку програмного забезпеченнÑ. Ðе вірите нам? ОÑÑŒ вам три ÑпоÑоби Ð´Ð»Ñ ÑˆÐ²Ð¸Ð´ÐºÐ¾Ð³Ð¾ (Ñ– приємного) теÑÑ‚-драйву:"
msgid "InProductMarketing|GitLab's premium tiers are designed to make you, your team and your application more efficient and more secure with features including but not limited to:"
msgstr ""
msgid "InProductMarketing|Give us one minute..."
-msgstr ""
+msgstr "Дайте нам одну хвилину..."
msgid "InProductMarketing|Go farther with GitLab"
-msgstr ""
+msgstr "Працюйте далі з GitLab"
msgid "InProductMarketing|Goldman Sachs went from 1 build every two weeks to thousands of builds a day"
-msgstr ""
+msgstr "Goldman Sachs почав з однієї збірки кожні два тижні Ñ– дійшов до тиÑÑч збірок на день"
msgid "InProductMarketing|Have a different instance you'd like to import? Here's our %{import_link}."
msgstr ""
msgid "InProductMarketing|Here's what you need to know"
-msgstr ""
+msgstr "ОÑÑŒ, що вам потрібно знати"
msgid "InProductMarketing|How (and why) mirroring makes sense"
-msgstr ""
+msgstr "Як (Ñ– чому) Ð²Ñ–Ð´Ð´Ð·ÐµÑ€ÐºÐ°Ð»ÐµÐ½Ð½Ñ Ð¼Ð°Ñ” значеннÑ"
msgid "InProductMarketing|How long does it take us to close issues/MRs by types like feature requests, bugs, tech debt, security?"
-msgstr ""
+msgstr "Скільки чаÑу нам потрібно, щоб закрити задачі/запити на Ð·Ð»Ð¸Ñ‚Ñ‚Ñ Ð·Ð° такими типами, Ñк запити функцій, помилки, технічний борг, безпека?"
msgid "InProductMarketing|How many days does it take our team to complete various tasks?"
-msgstr ""
+msgstr "Скільки днів необхідно нашій команді Ð´Ð»Ñ Ð²Ð¸ÐºÐ¾Ð½Ð°Ð½Ð½Ñ Ñ€Ñ–Ð·Ð½Ð¾Ð¼Ð°Ð½Ñ–Ñ‚Ð½Ð¸Ñ… завдань?"
msgid "InProductMarketing|How to build and test faster"
msgstr ""
@@ -18879,22 +19261,22 @@ msgid "InProductMarketing|Improve app security with a 30-day trial"
msgstr ""
msgid "InProductMarketing|Improve code quality and streamline reviews"
-msgstr ""
+msgstr "Покращте ÑкіÑÑ‚ÑŒ коду та ÑпроÑÑ‚Ñ–Ñ‚ÑŒ перевірки"
msgid "InProductMarketing|Increase Operational Efficiencies"
-msgstr ""
+msgstr "Підвищуйте операційну ефективніÑÑ‚ÑŒ"
msgid "InProductMarketing|Invite them to help out."
-msgstr ""
+msgstr "ЗапроÑÑ–Ñ‚ÑŒ Ñ—Ñ… допомогти."
msgid "InProductMarketing|Invite your colleagues and start shipping code faster."
-msgstr ""
+msgstr "ЗапроÑÑ–Ñ‚ÑŒ Ñвоїх колег та почніть надÑилати код швидше."
msgid "InProductMarketing|Invite your colleagues to join in less than one minute"
-msgstr ""
+msgstr "ЗапроÑÑ–Ñ‚ÑŒ Ñвоїх колег приєднатиÑÑ Ð¼ÐµÐ½Ñˆ ніж за одну хвилину"
msgid "InProductMarketing|Invite your colleagues today"
-msgstr ""
+msgstr "ЗапроÑÑ–Ñ‚ÑŒ Ñвоїх колег Ñьогодні"
msgid "InProductMarketing|Invite your team in less than 60 seconds"
msgstr "ЗапроÑÑ–Ñ‚ÑŒ Ñвою команду менш ніж за 60 Ñекунд"
@@ -18906,7 +19288,7 @@ msgid "InProductMarketing|Invite your team today to build better code (and proce
msgstr ""
msgid "InProductMarketing|Invite your teammates to GitLab"
-msgstr ""
+msgstr "ЗапроÑÑ–Ñ‚ÑŒ Ñвоїх товаришів по команді в GitLab"
msgid "InProductMarketing|Invite your teammates to help"
msgstr ""
@@ -18915,50 +19297,80 @@ msgid "InProductMarketing|Invite your teammates today and build better code toge
msgstr ""
msgid "InProductMarketing|It's all in the stats"
-msgstr ""
+msgstr "Ð’Ñе це Ñ” в ÑтатиÑтиці"
msgid "InProductMarketing|It's also possible to simply %{external_repo_link} in order to take advantage of GitLab's CI/CD."
+msgstr "Також можливо проÑто %{external_repo_link}, щоб ÑкориÑтатиÑÑ GitLab CI/CD."
+
+msgid "InProductMarketing|Keep your code quality high by defining who should approve merge requests and how many approvals are required."
msgstr ""
msgid "InProductMarketing|Launch GitLab CI/CD in 20 minutes or less"
msgstr ""
+msgid "InProductMarketing|Lower cost of development"
+msgstr ""
+
+msgid "InProductMarketing|Make it easier to collaborate on high-level ideas by grouping related issues in an epic."
+msgstr ""
+
msgid "InProductMarketing|Making the switch? It's easier than you think to import your projects into GitLab. Move %{github_link}, or import something %{bitbucket_link}."
msgstr ""
msgid "InProductMarketing|Master the art of importing!"
msgstr ""
+msgid "InProductMarketing|Merge request approval rule"
+msgstr ""
+
msgid "InProductMarketing|Move on to easily creating a Pages website %{ci_template_link}"
msgstr ""
msgid "InProductMarketing|Multiple owners, confusing workstreams? We've got you covered"
msgstr ""
+msgid "InProductMarketing|Multiple required approvers"
+msgstr ""
+
msgid "InProductMarketing|Need an alternative to importing?"
msgstr ""
msgid "InProductMarketing|Neutral"
-msgstr ""
+msgstr "Ðейтральний"
msgid "InProductMarketing|No credit card required."
-msgstr ""
+msgstr "Кредитна картка непотрібна."
msgid "InProductMarketing|Our tool brings all the things together"
msgstr ""
+msgid "InProductMarketing|Protect your web application by using DAST to examine for vulnerabilities in deployed environments."
+msgstr ""
+
msgid "InProductMarketing|Rapid development, simplified"
msgstr ""
msgid "InProductMarketing|Reduce Security & Compliance Risk"
msgstr ""
+msgid "InProductMarketing|Require multiple approvers on a merge request, so you know it's in good shape before it's merged."
+msgstr ""
+
+msgid "InProductMarketing|Roadmaps"
+msgstr ""
+
+msgid "InProductMarketing|Scoped labels"
+msgstr ""
+
msgid "InProductMarketing|Security that's integrated into your development lifecycle"
msgstr ""
msgid "InProductMarketing|Sometimes you're not ready to make a full transition to a new tool. If you're not ready to fully commit, %{mirroring_link} gives you a safe way to try out GitLab in parallel with your current tool."
msgstr ""
+msgid "InProductMarketing|Speed. Efficiency. Trust."
+msgstr ""
+
msgid "InProductMarketing|Spin up an autoscaling runner in GitLab"
msgstr ""
@@ -18968,6 +19380,9 @@ msgstr ""
msgid "InProductMarketing|Start a Self-Managed trial"
msgstr ""
+msgid "InProductMarketing|Start a free trial"
+msgstr ""
+
msgid "InProductMarketing|Start a free trial of GitLab Ultimate – no credit card required"
msgstr ""
@@ -18975,13 +19390,13 @@ msgid "InProductMarketing|Start a trial"
msgstr "Розпочати пробну верÑÑ–ÑŽ"
msgid "InProductMarketing|Start by %{performance_link}"
-msgstr ""
+msgstr "Розпочніть з %{performance_link}"
msgid "InProductMarketing|Start by importing your projects"
msgstr ""
msgid "InProductMarketing|Start with a GitLab Ultimate free trial"
-msgstr ""
+msgstr "Розпочніть з безкоштовної пробної верÑÑ–Ñ— GitLab Ultimate"
msgid "InProductMarketing|Start your trial now!"
msgstr ""
@@ -18996,10 +19411,10 @@ msgid "InProductMarketing|Streamline code review, know at a glance who's unavail
msgstr ""
msgid "InProductMarketing|Take this 1-question survey!"
-msgstr ""
+msgstr "Візьміть учаÑÑ‚ÑŒ у цьому опитуванні з 1 запитаннÑ!"
msgid "InProductMarketing|Take your first steps with GitLab"
-msgstr ""
+msgstr "Зробіть перші кроки з GitLab"
msgid "InProductMarketing|Take your source code management to the next level"
msgstr ""
@@ -19034,20 +19449,23 @@ msgstr ""
msgid "InProductMarketing|To understand and get the most out of GitLab, start at the beginning and %{project_link}. In GitLab, repositories are part of a project, so after you've created your project you can go ahead and %{repo_link}."
msgstr ""
-msgid "InProductMarketing|Try GitLab Ultimate for free"
+msgid "InProductMarketing|Track completed issues in a chart, so you can see how a milestone is progressing at a glance."
msgstr ""
+msgid "InProductMarketing|Try GitLab Ultimate for free"
+msgstr "Спробувати верÑÑ–ÑŽ GitLab Ultimate безкоштовно"
+
msgid "InProductMarketing|Try it out"
-msgstr ""
+msgstr "Спробуйте!"
msgid "InProductMarketing|Try it yourself"
-msgstr ""
+msgstr "Спробуйте Ñамі!"
msgid "InProductMarketing|Turn coworkers into collaborators"
msgstr ""
msgid "InProductMarketing|Twitter"
-msgstr ""
+msgstr "Twitter"
msgid "InProductMarketing|Understand repository mirroring"
msgstr ""
@@ -19056,58 +19474,64 @@ msgid "InProductMarketing|Understand your project options"
msgstr ""
msgid "InProductMarketing|Use GitLab CI/CD"
-msgstr ""
+msgstr "ВикориÑтовувати GitLab CI/CD"
msgid "InProductMarketing|Use our AWS cloudformation template to spin up your runners in just a few clicks!"
msgstr ""
msgid "InProductMarketing|Used by more than 100,000 organizations from around the globe:"
-msgstr ""
+msgstr "ВикориÑтовуєтьÑÑ Ð¿Ð¾Ð½Ð°Ð´ 100 000 організаціÑми з уÑього Ñвіту:"
msgid "InProductMarketing|Very difficult"
-msgstr ""
+msgstr "Дуже Ñкладний"
msgid "InProductMarketing|Very easy"
+msgstr "Дуже проÑтий"
+
+msgid "InProductMarketing|Visualize your epics and milestones in a timeline."
msgstr ""
msgid "InProductMarketing|Want to host GitLab on your servers?"
-msgstr ""
+msgstr "Бажаєте розміÑтити GitLab на Ñвоїх Ñерверах?"
msgid "InProductMarketing|We know a thing or two about efficiency and we don't want to keep that to ourselves. Sign up for a free trial of GitLab Ultimate and your teams will be on it from day one."
-msgstr ""
+msgstr "Ми дещо знаємо про ефективніÑÑ‚ÑŒ Ñ– хочемо цим поділитиÑÑ. ПідпишітьÑÑ Ð½Ð° безкоштовну пробну верÑÑ–ÑŽ GitLab Ultimate, Ñ– ваші команди кориÑтуватимутьÑÑ Ð½ÐµÑŽ з першого днÑ."
msgid "InProductMarketing|We want your GitLab experience to be great"
-msgstr ""
+msgstr "Ми хочемо, щоб ви отримали гарний доÑвід від роботи з GitLab"
msgid "InProductMarketing|What does our value stream timeline look like from product to development to review and production?"
-msgstr ""
+msgstr "Як виглÑдає чаÑова шкала нашого потоку значень від розробки продукту до його Ð·Ð°Ñ‚Ð²ÐµÑ€Ð´Ð¶ÐµÐ½Ð½Ñ Ñ‚Ð° ÑтвореннÑ?"
msgid "InProductMarketing|When your team is on GitLab these answers are a click away."
-msgstr ""
+msgstr "Коли ваша команда перебуває в GitLab, ці відповіді можна знайти одним кліком."
msgid "InProductMarketing|Working in GitLab = more efficient"
-msgstr ""
+msgstr "Робота в GitLab = більша ефективніÑÑ‚ÑŒ"
msgid "InProductMarketing|YouTube"
msgstr "YouTube"
-msgid "InProductMarketing|Your teams can be more efficient"
+msgid "InProductMarketing|Your software, deployed your way"
msgstr ""
+msgid "InProductMarketing|Your teams can be more efficient"
+msgstr "Ваші команди можуть працювати ефективніше"
+
msgid "InProductMarketing|comprehensive guide"
-msgstr ""
+msgstr "детальне поÑÑненнÑ"
msgid "InProductMarketing|connect an external repository"
-msgstr ""
+msgstr "підключіть зовнішній репозиторій"
msgid "InProductMarketing|create a project"
msgstr "Створити проєкт"
msgid "InProductMarketing|from Bitbucket"
-msgstr ""
+msgstr "від Bitbucket"
msgid "InProductMarketing|go to about.gitlab.com"
-msgstr ""
+msgstr "перейдіть на about.gitlab.com"
msgid "InProductMarketing|how easy it is to get started"
msgstr ""
@@ -19128,16 +19552,16 @@ msgid "InProductMarketing|testing browser performance"
msgstr ""
msgid "InProductMarketing|unsubscribe"
-msgstr ""
+msgstr "відпиÑатиÑÑ"
msgid "InProductMarketing|update your preferences"
-msgstr ""
+msgstr "оновіть Ñвої налаштуваннÑ"
msgid "InProductMarketing|using a CI/CD template"
-msgstr ""
+msgstr "викориÑтовуючи шаблон CI/CD"
msgid "InProductMarketing|you may %{unsubscribe_link} at any time."
-msgstr ""
+msgstr "ви можете %{unsubscribe_link} у будь-Ñкий чаÑ."
msgid "Inactive"
msgstr "Ðеактивний"
@@ -19149,19 +19573,19 @@ msgid "Incident Management Limits"
msgstr "Ліміти, пов’Ñзані із УправліннÑм Інцидентами"
msgid "Incident details"
-msgstr ""
+msgstr "Деталі інциденту"
msgid "Incident template (optional)."
msgstr ""
msgid "IncidentManagement|%{hours} hours, %{minutes} minutes remaining"
-msgstr ""
+msgstr "%{hours} годин, %{minutes} хвилин залишилоÑÑ"
msgid "IncidentManagement|%{minutes} minutes remaining"
msgstr "ЗалишилоÑÑŒ%{minutes} хвилин"
msgid "IncidentManagement|Achieved SLA"
-msgstr ""
+msgstr "Укладена угода про рівень поÑлуг (SLA)"
msgid "IncidentManagement|All"
msgstr "Ð’ÑÑ–"
@@ -19170,25 +19594,25 @@ msgid "IncidentManagement|All alerts promoted to incidents are automatically dis
msgstr ""
msgid "IncidentManagement|All alerts promoted to incidents are automatically displayed within the list. You can also create a new incident using the button below."
-msgstr ""
+msgstr "УÑÑ– попередженнÑ, переведені до розрÑду інцидентів, автоматично відображаютьÑÑ Ñƒ ÑпиÑку. Ви також можете Ñтворити новий інцидент за допомогою кнопки нижче."
msgid "IncidentManagement|Assignees"
-msgstr ""
+msgstr "Виконавці"
msgid "IncidentManagement|Closed"
msgstr "Закрито"
msgid "IncidentManagement|Create incident"
-msgstr ""
+msgstr "Створити інцидент"
msgid "IncidentManagement|Critical - S1"
msgstr "Критичні - S1"
msgid "IncidentManagement|Date created"
-msgstr ""
+msgstr "Дата ÑтвореннÑ"
msgid "IncidentManagement|Display your incidents in a dedicated view"
-msgstr ""
+msgstr "Відображайте Ñвої інциденти у виділеному вікні"
msgid "IncidentManagement|High - S2"
msgstr "ВиÑокі - S2"
@@ -19206,39 +19630,54 @@ msgid "IncidentManagement|Medium - S3"
msgstr "Середні - S3"
msgid "IncidentManagement|Missed SLA"
-msgstr ""
+msgstr "ВідÑÑƒÑ‚Ð½Ñ ÑƒÐ³Ð¾Ð´Ð° про рівень поÑлуг (SLA)"
msgid "IncidentManagement|No incidents to display."
+msgstr "Ðемає інцидентів Ð´Ð»Ñ Ð²Ñ–Ð´Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ."
+
+msgid "IncidentManagement|None"
msgstr ""
msgid "IncidentManagement|Open"
msgstr "Відкрити"
-msgid "IncidentManagement|Published"
+msgid "IncidentManagement|Page your team with escalation policies"
msgstr ""
-msgid "IncidentManagement|Published to status page"
+msgid "IncidentManagement|Paged"
msgstr ""
+msgid "IncidentManagement|Published"
+msgstr "Опубліковано"
+
+msgid "IncidentManagement|Published to status page"
+msgstr "Опубліковано на Ñторінці ÑтатуÑу"
+
msgid "IncidentManagement|Severity"
msgstr "Рівень"
-msgid "IncidentManagement|There are no closed incidents"
+msgid "IncidentManagement|Status"
msgstr ""
+msgid "IncidentManagement|There are no closed incidents"
+msgstr "Ðемає закритих інцидентів"
+
msgid "IncidentManagement|There was an error displaying the incidents."
-msgstr ""
+msgstr "Виникла помилка під Ñ‡Ð°Ñ Ð²Ñ–Ð´Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Ñ–Ð½Ñ†Ð¸Ð´ÐµÐ½Ñ‚Ñ–Ð²."
msgid "IncidentManagement|Time to SLA"
-msgstr ""
+msgstr "Ð§Ð°Ñ Ð½Ð° угоду про рівень поÑлуг (SLA)"
msgid "IncidentManagement|Unassigned"
-msgstr ""
+msgstr "Ðепризначено"
msgid "IncidentManagement|Unknown"
-msgstr ""
+msgstr "Ðевідомо"
msgid "IncidentManagement|Unpublished"
+msgstr "Ðеопубліковано"
+
+msgid "IncidentManagement|Use escalation policies to automatically page your team when incidents are created."
msgstr ""
msgid "IncidentSettings|Activate \"time to SLA\" countdown timer"
@@ -19248,7 +19687,7 @@ msgid "IncidentSettings|Fine-tune incident settings and set up integrations with
msgstr ""
msgid "IncidentSettings|Grafana integration"
-msgstr ""
+msgstr "Ð†Ð½Ñ‚ÐµÐ³Ñ€Ð°Ñ†Ñ–Ñ Grafana"
msgid "IncidentSettings|Incident settings"
msgstr ""
@@ -19286,7 +19725,10 @@ msgstr "хвилини"
msgid "Incidents"
msgstr "Інциденти"
-msgid "Incidents|Add a URL"
+msgid "Incidents|Add image details"
+msgstr ""
+
+msgid "Incidents|Add text or a link to display with your image. If you don't add either, the file name displays instead."
msgstr ""
msgid "Incidents|Drop or %{linkStart}upload%{linkEnd} a metric screenshot to attach it to the incident"
@@ -19301,10 +19743,10 @@ msgstr ""
msgid "Incidents|There was an issue loading metric images."
msgstr ""
-msgid "Incidents|There was an issue uploading your image."
+msgid "Incidents|There was an issue updating your image."
msgstr ""
-msgid "Incidents|You can optionally add a URL to link users to the original graph."
+msgid "Incidents|There was an issue uploading your image."
msgstr ""
msgid "Incident|Alert details"
@@ -19313,9 +19755,18 @@ msgstr ""
msgid "Incident|Are you sure you wish to delete this image?"
msgstr ""
+msgid "Incident|Delete image"
+msgstr ""
+
msgid "Incident|Deleting %{filename}"
msgstr ""
+msgid "Incident|Edit image text or link"
+msgstr ""
+
+msgid "Incident|Editing %{filename}"
+msgstr ""
+
msgid "Incident|Metrics"
msgstr "Метрики"
@@ -19398,7 +19849,7 @@ msgid "Infrastructure Registry"
msgstr "РеєÑÑ‚Ñ€ інфраÑтруктури"
msgid "Infrastructure as Code (IaC) Scanning"
-msgstr ""
+msgstr "Ð¡ÐºÐ°Ð½ÑƒÐ²Ð°Ð½Ð½Ñ Ñ–Ð½Ñ„Ñ€Ð°Ñтруктури Ñк коду (IaC)"
msgid "InfrastructureRegistry|Copy Terraform Command"
msgstr "Копіювати команду Terraform"
@@ -19522,7 +19973,7 @@ msgstr[2] "ІнÑтанÑів"
msgstr[3] "ІнÑтанÑів"
msgid "Instance Configuration"
-msgstr "ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ñ–Ð½Ñтанції"
+msgstr "Параметри інÑтанÑу"
msgid "Instance access request"
msgstr ""
@@ -19537,10 +19988,10 @@ msgid "Instance administrators group already exists"
msgstr "Група Ð´Ð»Ñ Ð°Ð´Ð¼Ñ–Ð½Ñ–Ñтраторів інÑтанÑу вже Ñ–Ñнує"
msgid "Instance audit events"
-msgstr ""
+msgstr "Події аудиту інÑтанÑа"
msgid "Instance overview"
-msgstr ""
+msgstr "ОглÑд інÑтанÑу"
msgid "Insufficient permissions"
msgstr ""
@@ -19552,7 +20003,7 @@ msgid "Integration"
msgstr "ІнтеграціÑ"
msgid "Integration Settings"
-msgstr "ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð†Ð½Ñ‚ÐµÐ³Ñ€Ð°Ñ†Ñ–Ñ—"
+msgstr "Параметри Інтеграції"
msgid "Integrations"
msgstr "Інтеграції"
@@ -19587,11 +20038,17 @@ msgstr ""
msgid "Integrations|Branches for which notifications are to be sent"
msgstr ""
+msgid "Integrations|Clear if using a self-signed certificate."
+msgstr ""
+
msgid "Integrations|Comment detail:"
msgstr "Деталі коментарÑ:"
msgid "Integrations|Comment settings:"
-msgstr "ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ ÐºÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ñ–Ð²:"
+msgstr "Параметри коментарів:"
+
+msgid "Integrations|Connection details"
+msgstr ""
msgid "Integrations|Connection failed. Please check your settings."
msgstr ""
@@ -19617,6 +20074,9 @@ msgstr ""
msgid "Integrations|Enable GitLab.com slash commands in a Slack workspace."
msgstr ""
+msgid "Integrations|Enable SSL verification"
+msgstr ""
+
msgid "Integrations|Enable comments"
msgstr "Увімкнути коментарі"
@@ -19695,6 +20155,9 @@ msgstr ""
msgid "Integrations|Return to GitLab for Jira"
msgstr ""
+msgid "Integrations|SSL verification"
+msgstr ""
+
msgid "Integrations|Save settings?"
msgstr "Зберегти налаштуваннÑ?"
@@ -19740,9 +20203,6 @@ msgstr ""
msgid "Integrations|Use default settings"
msgstr "ВикориÑтовувати Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð·Ð° замовчуваннÑм"
-msgid "Integrations|When you mention a Jira issue in a commit or merge request, GitLab creates a remote link and comment (if enabled)."
-msgstr ""
-
msgid "Integrations|You can now close this window and return to the GitLab for Jira application."
msgstr ""
@@ -19767,9 +20227,6 @@ msgstr ""
msgid "Integrations|can't exceed %{recipients_limit}"
msgstr ""
-msgid "Interactive developer security education."
-msgstr ""
-
msgid "Interactive mode"
msgstr "Інтерактивний режим"
@@ -19816,7 +20273,7 @@ msgid "Invalid URL"
msgstr "ÐедійÑна URL адреÑа"
msgid "Invalid URL: %{url}"
-msgstr ""
+msgstr "ÐедійÑна URL-адреÑа: %{url}"
msgid "Invalid container_name"
msgstr "ÐеприпуÑтиме ім'Ñ ÐºÐ¾Ð½Ñ‚ÐµÐ¹Ð½ÐµÑ€Ð°"
@@ -19939,13 +20396,13 @@ msgid "Invite members"
msgstr "ЗапроÑити учаÑників"
msgid "InviteEmail|%{inviter} invited you to join the %{project_or_group_name} %{project_or_group} as a %{role}"
-msgstr ""
+msgstr "%{inviter} запроÑив Ð²Ð°Ñ Ð¿Ñ€Ð¸Ñ”Ð´Ð½Ð°Ñ‚Ð¸ÑÑ Ð´Ð¾ %{project_or_group_name}%{project_or_group} у ролі %{role}"
msgid "InviteEmail|%{inviter} invited you to join the %{strong_start}%{project_or_group_name}%{strong_end}%{br_tag}%{project_or_group} as a %{role}"
msgstr ""
msgid "InviteEmail|%{project_or_group} details"
-msgstr ""
+msgstr "деталі %{project_or_group}"
msgid "InviteEmail|Groups assemble related projects together and grant members access to several projects at once."
msgstr ""
@@ -19963,19 +20420,19 @@ msgid "InviteEmail|Projects are used to host and collaborate on code, track issu
msgstr ""
msgid "InviteEmail|What's it about?"
-msgstr ""
+msgstr "Про що це?"
msgid "InviteEmail|You are invited to join the %{strong_start}%{project_or_group_name}%{strong_end}%{br_tag}%{project_or_group} as a %{role}"
-msgstr ""
+msgstr "Ð’Ð°Ñ Ð·Ð°Ð¿Ñ€Ð¾ÑˆÑƒÑŽÑ‚ÑŒ приєднатиÑÑ Ð´Ð¾ %{strong_start}%{project_or_group_name}%{strong_end}%{br_tag}%{project_or_group} у ÑкоÑÑ‚Ñ– %{role}"
msgid "InviteEmail|You have been invited to join the %{project_or_group_name} %{project_or_group} as a %{role}"
-msgstr ""
+msgstr "Ð’Ð°Ñ Ð·Ð°Ð¿Ñ€Ð¾Ñили приєднатиÑÑ Ð´Ð¾ %{project_or_group_name}%{project_or_group} у ÑкоÑÑ‚Ñ– %{role}"
msgid "InviteEmail|You were assigned the following tasks:"
-msgstr ""
+msgstr "Вам призначено такі завданнÑ:"
msgid "InviteEmail|and has assigned you the following tasks:"
-msgstr ""
+msgstr "та призначив вам такі завданнÑ:"
msgid "InviteMembersBanner|Collaborate with your team"
msgstr ""
@@ -19984,37 +20441,37 @@ msgid "InviteMembersBanner|Invite your colleagues"
msgstr ""
msgid "InviteMembersBanner|We noticed that you haven't invited anyone to this group. Invite your colleagues so you can discuss issues, collaborate on merge requests, and share your knowledge."
-msgstr ""
+msgstr "Ми помітили, що ви нікого не запроÑили до цієї групи. ЗапроÑÑ–Ñ‚ÑŒ Ñвоїх колег, щоб ви могли обговорювати задачі, Ñпівпрацювати над запитами на Ð·Ð»Ð¸Ñ‚Ñ‚Ñ Ñ‚Ð° ділитиÑÑ Ñвоїми знаннÑми."
msgid "InviteMembersModal|%{linkStart}Read more%{linkEnd} about role permissions"
-msgstr ""
+msgstr "%{linkStart}Читати більше%{linkEnd} про дозволи ролей"
msgid "InviteMembersModal|Access expiration date (optional)"
-msgstr ""
+msgstr "Дата Ð·Ð°ÐºÑ–Ð½Ñ‡ÐµÐ½Ð½Ñ Ð´Ð¾Ñтупу (необов'Ñзково)"
msgid "InviteMembersModal|Cancel"
msgstr "СкаÑувати"
msgid "InviteMembersModal|Choose a project for the issues"
-msgstr ""
+msgstr "Виберіть проєкт Ð´Ð»Ñ Ð·Ð°Ð´Ð°Ñ‡"
msgid "InviteMembersModal|Close invite team members"
-msgstr ""
+msgstr "Закрити Ð·Ð°Ð¿Ñ€Ð¾ÑˆÐµÐ½Ð½Ñ ÑƒÑ‡Ð°Ñників команди"
msgid "InviteMembersModal|Congratulations on creating your project, you're almost there!"
-msgstr ""
+msgstr "Вітаємо із ÑтвореннÑм влаÑного проєкту, ви майже тут!"
msgid "InviteMembersModal|Create issues for your new team member to work on (optional)"
-msgstr ""
+msgstr "Створіть задачі Ð´Ð»Ñ Ð²Ð°ÑˆÐ¾Ð³Ð¾ нового учаÑника команди (необов'Ñзково)"
msgid "InviteMembersModal|GitLab is better with colleagues!"
-msgstr ""
+msgstr "Працювати в GitLab з колегами краще!"
msgid "InviteMembersModal|GitLab member or email address"
-msgstr ""
+msgstr "УчаÑник GitLab або адреÑа електронної пошти"
msgid "InviteMembersModal|How about inviting a colleague or two to join you?"
-msgstr ""
+msgstr "Як щодо того, щоб запроÑити одного чи двох колег приєднатиÑÑ Ð´Ð¾ ваÑ?"
msgid "InviteMembersModal|Invite"
msgstr "ЗапроÑити"
@@ -20023,13 +20480,13 @@ msgid "InviteMembersModal|Invite a group"
msgstr "ЗапроÑити групу"
msgid "InviteMembersModal|Invite members"
-msgstr ""
+msgstr "ЗапроÑити учаÑників"
msgid "InviteMembersModal|Members were successfully added"
-msgstr ""
+msgstr "УчаÑники були уÑпішно додані"
msgid "InviteMembersModal|Search for a group to invite"
-msgstr ""
+msgstr "Шукайте групу, щоб запроÑити"
msgid "InviteMembersModal|Select a group to invite"
msgstr "Вибрати групу Ð´Ð»Ñ Ð·Ð°Ð¿Ñ€Ð¾ÑˆÐµÐ½Ð½Ñ"
@@ -20038,7 +20495,7 @@ msgid "InviteMembersModal|Select a role"
msgstr "Вибрати роль"
msgid "InviteMembersModal|Select members or type email addresses"
-msgstr ""
+msgstr "Виберіть учаÑників або введіть адреÑи електронної пошти"
msgid "InviteMembersModal|Something went wrong"
msgstr "ЩоÑÑŒ пішло не так"
@@ -20062,16 +20519,16 @@ msgid "InviteMembers|Invite a group"
msgstr "ЗапроÑити групу"
msgid "InviteMembers|Invite team members"
-msgstr ""
+msgstr "ЗапроÑити учаÑників команди"
msgid "InviteMember|Add members to this project and start collaborating with your team."
msgstr ""
msgid "InviteMember|Invite Members (optional)"
-msgstr ""
+msgstr "ЗапроÑити учаÑників (необов'Ñзково)"
msgid "InviteMember|Invite another member"
-msgstr ""
+msgstr "ЗапроÑити іншого учаÑника"
msgid "InviteMember|Invite members"
msgstr "ЗапроÑити учаÑників"
@@ -20092,37 +20549,37 @@ msgid "InviteReminderEmail|%{inviter} is waiting for you to join the %{strong_st
msgstr ""
msgid "InviteReminderEmail|%{inviter}'s invitation to GitLab is pending"
-msgstr ""
+msgstr "Ð·Ð°Ð¿Ñ€Ð¾ÑˆÐµÐ½Ð½Ñ %{inviter} до GitLab очікує"
msgid "InviteReminderEmail|Accept invitation"
-msgstr ""
+msgstr "ПрийнÑти запрошеннÑ"
msgid "InviteReminderEmail|Accept invitation: %{invite_url}"
-msgstr ""
+msgstr "ПрийнÑти запрошеннÑ: %{invite_url}"
msgid "InviteReminderEmail|Decline invitation"
-msgstr ""
+msgstr "Відхилити запрошеннÑ"
msgid "InviteReminderEmail|Decline invitation: %{decline_url}"
-msgstr ""
+msgstr "Відхилити запрошеннÑ: %{decline_url}"
msgid "InviteReminderEmail|Hey there %{wave_emoji}"
-msgstr ""
+msgstr "Привіт %{wave_emoji}"
msgid "InviteReminderEmail|Hey there!"
msgstr "Привіт!"
msgid "InviteReminderEmail|In case you missed it..."
-msgstr ""
+msgstr "Якщо ви пропуÑтили це..."
msgid "InviteReminderEmail|Invitation pending"
-msgstr ""
+msgstr "ÐžÑ‡Ñ–ÐºÑƒÐ²Ð°Ð½Ð½Ñ Ð·Ð°Ð¿Ñ€Ð¾ÑˆÐµÐ½Ð½Ñ"
msgid "InviteReminderEmail|It's been %{invitation_age} days since %{inviter} invited you to join the %{strong_start}%{project_or_group_name}%{strong_end} %{project_or_group} as a %{role}. What would you like to do?"
-msgstr ""
+msgstr "Минуло %{invitation_age} днів відтоді, Ñк %{inviter} запроÑив Ð²Ð°Ñ Ð¿Ñ€Ð¸Ñ”Ð´Ð½Ð°Ñ‚Ð¸ÑÑ Ð´Ð¾ %{strong_start}%{project_or_group_name}%{strong_end}%{project_or_group} у ÑкоÑÑ‚Ñ– %{role}. Що б ви хотіли робити?"
msgid "InviteReminderEmail|This is a friendly reminder that %{inviter} invited you to join the %{strong_start}%{project_or_group_name}%{strong_end} %{project_or_group} as a %{role}."
-msgstr ""
+msgstr "Це дружнє Ð½Ð°Ð³Ð°Ð´ÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ñ€Ð¾ те, що %{inviter} запроÑив Ð²Ð°Ñ Ð¿Ñ€Ð¸Ñ”Ð´Ð½Ð°Ñ‚Ð¸ÑÑ Ð´Ð¾ %{strong_start}%{project_or_group_name}%{strong_end}%{project_or_group} у ÑкоÑÑ‚Ñ– %{role}."
msgid "Invited"
msgstr "Запрошені"
@@ -20131,7 +20588,7 @@ msgid "Invocations"
msgstr "Виклики"
msgid "IrkerService|Channels and users separated by whitespaces. %{recipients_docs_link}"
-msgstr ""
+msgstr "Канали та кориÑтувачі розділені пробілами. %{recipients_docs_link}"
msgid "IrkerService|Default IRC URI (optional)"
msgstr ""
@@ -20140,7 +20597,7 @@ msgid "IrkerService|How to enter channels or users?"
msgstr ""
msgid "IrkerService|Recipients"
-msgstr ""
+msgstr "Одержувачі"
msgid "IrkerService|Send update messages to an irker server."
msgstr ""
@@ -20152,7 +20609,7 @@ msgid "IrkerService|Server host (optional)"
msgstr ""
msgid "IrkerService|Server port (optional)"
-msgstr ""
+msgstr "Порт Ñервера (необов'Ñзково)"
msgid "IrkerService|URI to add before each recipient."
msgstr ""
@@ -20188,7 +20645,7 @@ msgid "IssuableStatus|moved"
msgstr "переміщено"
msgid "IssuableStatus|promoted"
-msgstr ""
+msgstr "перенеÑено"
msgid "Issue"
msgstr "Задача"
@@ -20218,7 +20675,7 @@ msgid "Issue creation requests"
msgstr ""
msgid "Issue details"
-msgstr ""
+msgstr "Деталі задачі"
msgid "Issue events"
msgstr "Задачі"
@@ -20259,11 +20716,14 @@ msgstr "Вік"
msgid "IssueAnalytics|Assignees"
msgstr "Виконавці"
-msgid "IssueAnalytics|Due date"
+msgid "IssueAnalytics|Created by"
msgstr ""
+msgid "IssueAnalytics|Due date"
+msgstr "Запланована дата завершеннÑ"
+
msgid "IssueAnalytics|Failed to load issues. Please try again."
-msgstr ""
+msgstr "Помилка при завантаженні задач. Будь лаÑка, Ñпробуйте ще."
msgid "IssueAnalytics|Issue"
msgstr "Задача"
@@ -20271,9 +20731,6 @@ msgstr "Задача"
msgid "IssueAnalytics|Milestone"
msgstr "Етап"
-msgid "IssueAnalytics|Opened by"
-msgstr ""
-
msgid "IssueAnalytics|Status"
msgstr "СтатуÑ"
@@ -20302,13 +20759,13 @@ msgid "IssueBoards|Switch board"
msgstr "Перемкнути дошку"
msgid "IssueList|created %{timeAgoString} by %{user}"
-msgstr ""
+msgstr "Ñтворено %{timeAgoString} %{user}"
msgid "IssueTracker|Custom issue tracker"
msgstr "ВлаÑний реєÑÑ‚Ñ€ задач"
msgid "IssueTracker|Issue URL"
-msgstr ""
+msgstr "URL-адреÑа задачі"
msgid "IssueTracker|New issue URL"
msgstr ""
@@ -20397,10 +20854,10 @@ msgstr "ПіÑÐ»Ñ ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð·Ð°Ð´Ð°Ñ‡ Ð´Ð»Ñ Ð²Ð°ÑˆÐ¸Ñ… проєктÑ
msgid "IssuesAnalytics|Avg/Month:"
msgstr "Ð’ Ñередньому за міÑÑць:"
-msgid "IssuesAnalytics|Issues opened"
-msgstr "Відкриті задачі"
+msgid "IssuesAnalytics|Issues created"
+msgstr ""
-msgid "IssuesAnalytics|Issues opened per month"
+msgid "IssuesAnalytics|Issues created per month"
msgstr ""
msgid "IssuesAnalytics|Last 12 months"
@@ -20427,6 +20884,9 @@ msgstr ""
msgid "It looks like you have some draft commits in this branch."
msgstr ""
+msgid "It looks like you're attempting to activate your subscription. Use %{a_start}the Subscription page%{a_end} instead."
+msgstr ""
+
msgid "It may be several days before you see feature usage data."
msgstr ""
@@ -20497,7 +20957,7 @@ msgid "Iterations|Delete iteration?"
msgstr ""
msgid "Iterations|Duration"
-msgstr ""
+msgstr "ТриваліÑÑ‚ÑŒ"
msgid "Iterations|Edit cadence"
msgstr ""
@@ -20557,16 +21017,16 @@ msgid "Iterations|Select number"
msgstr ""
msgid "Iterations|Select start date"
-msgstr ""
+msgstr "Обрати дату початку"
msgid "Iterations|Start date"
-msgstr ""
+msgstr "Дата початку"
msgid "Iterations|The duration for each iteration (in weeks)"
-msgstr ""
+msgstr "ТриваліÑÑ‚ÑŒ кожної ітерації (у тижнÑÑ…)"
msgid "Iterations|The iteration has been deleted."
-msgstr ""
+msgstr "Ð†Ñ‚ÐµÑ€Ð°Ñ†Ñ–Ñ Ð±ÑƒÐ»Ð° видалена."
msgid "Iterations|The start date of your first iteration"
msgstr ""
@@ -20611,19 +21071,19 @@ msgid "January"
msgstr "Ñічень"
msgid "Japanese language support using"
-msgstr ""
+msgstr "ВикориÑÑ‚Ð°Ð½Ð½Ñ Ð¿Ñ–Ð´Ñ‚Ñ€Ð¸Ð¼ÐºÐ¸ ÑпонÑької мови"
msgid "Jira display name"
msgstr "Показати Ñ–Ð¼Ê¼Ñ Jira"
msgid "Jira import is already running."
-msgstr ""
+msgstr "Імпорт Jira вже виконуєтьÑÑ."
msgid "Jira integration not configured."
-msgstr ""
+msgstr "Ð†Ð½Ñ‚ÐµÐ³Ñ€Ð°Ñ†Ñ–Ñ Ð· Jira не налаштована."
msgid "Jira project key is not configured."
-msgstr ""
+msgstr "Ключ проєкту Jira не налаштований."
msgid "Jira project: %{importProject}"
msgstr "Проєкт Jira: %{importProject}"
@@ -20638,13 +21098,13 @@ msgid "Jira users have been imported from the configured Jira instance. They can
msgstr ""
msgid "Jira-GitLab user mapping template"
-msgstr ""
+msgstr "Шаблон зіÑÑ‚Ð°Ð²Ð»ÐµÐ½Ð½Ñ ÐºÐ¾Ñ€Ð¸Ñтувачів Jira-GitLab"
msgid "JiraConnect|Create branch for Jira issue %{jiraIssue}"
msgstr ""
msgid "JiraConnect|Failed to create branch."
-msgstr ""
+msgstr "Ðе вдалоÑÑ Ñтворити гілку."
msgid "JiraConnect|Failed to create branch. Please try again."
msgstr ""
@@ -20653,22 +21113,25 @@ msgid "JiraConnect|New branch was successfully created."
msgstr ""
msgid "JiraConnect|You can now close this window and return to Jira."
+msgstr "Зараз ви можете закрити це вікно та повернутиÑÑ Ð´Ð¾ Jira."
+
+msgid "JiraConnect|You don't have permission to create branches for this project. Select a different project or contact the project owner for access. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "JiraRequest|A connection error occurred while connecting to Jira. Try your request again."
msgstr ""
msgid "JiraRequest|A timeout error occurred while connecting to Jira. Try your request again."
-msgstr ""
+msgstr "Виникла помилка Ð¿ÐµÑ€ÐµÐ²Ð¸Ñ‰ÐµÐ½Ð½Ñ Ð»Ñ–Ð¼Ñ–Ñ‚Ñƒ чаÑу під Ñ‡Ð°Ñ Ð¿Ñ–Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð½Ñ Ð´Ð¾ Jira. Повторіть Ñвій запит знову."
msgid "JiraRequest|An SSL error occurred while connecting to Jira: %{message}. Try your request again."
-msgstr ""
+msgstr "Виникла помилка SSL під Ñ‡Ð°Ñ Ð¿Ñ–Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð½Ñ Ð´Ð¾ Jira: %{message}. Повторіть Ñвій запит знову."
msgid "JiraRequest|An error occurred while requesting data from Jira. Check your %{docs_link_start}Jira integration configuration%{docs_link_end} and try again."
msgstr ""
msgid "JiraRequest|An error occurred while requesting data from Jira: %{messages}. Check your %{docs_link_start}Jira integration configuration%{docs_link_end} and try again."
-msgstr ""
+msgstr "Виникла помилка під Ñ‡Ð°Ñ Ð·Ð°Ð¿Ð¸Ñ‚Ñƒ даних з Jira: %{messages}. Перевірте Ñвою %{docs_link_start}конфігурацію інтеграції Jira%{docs_link_end} та Ñпробуйте знову."
msgid "JiraRequest|The Jira API URL for connecting to Jira is not valid. Check your Jira integration API URL and try again."
msgstr ""
@@ -20686,16 +21149,16 @@ msgid "JiraService|%{jiraDocsLinkStart}Enable the Jira integration%{jiraDocsLink
msgstr ""
msgid "JiraService|%{jira_docs_link_start}Enable the Jira integration%{jira_docs_link_end} to view your Jira issues in GitLab."
-msgstr ""
+msgstr "%{jira_docs_link_start}Увімкніть інтеграцію Jira%{jira_docs_link_end}, щоб переглÑнути ваші задачі Jira в GitLab."
msgid "JiraService|%{user_link} mentioned this issue in %{entity_link} of %{project_link}%{branch}:{quote}%{entity_message}{quote}"
msgstr "%{user_link} вказав цю задачу в %{entity_link} з %{project_link}%{branch}:{quote}%{entity_message}{quote}"
msgid "JiraService|An error occurred while fetching issue list"
-msgstr ""
+msgstr "Виникла помилка під Ñ‡Ð°Ñ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ ÑпиÑку задач"
msgid "JiraService|Automatically transitions Jira issues to the \"Done\" category. %{linkStart}Learn more%{linkEnd}"
-msgstr ""
+msgstr "Ðвтоматично переноÑить задачі Jira до категорії \"Виконано\". %{linkStart}ДізнатиÑÑ Ð±Ñ–Ð»ÑŒÑˆÐµ%{linkEnd}"
msgid "JiraService|Base URL of the Jira instance."
msgstr ""
@@ -20703,62 +21166,62 @@ msgstr ""
msgid "JiraService|Define the type of Jira issue to create from a vulnerability."
msgstr ""
-msgid "JiraService|Displaying Jira issues while leaving the GitLab issue functionality enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
-msgstr "Ð’Ñ–Ð´Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Ð·Ð°Ð´Ð°Ñ‡ Jira при увімкненій функціональноÑÑ‚Ñ– задач Gitlab може заплутати. Подумайте про %{linkStart}Ð²Ð¸Ð¼ÐºÐ½ÐµÐ½Ð½Ñ Ð·Ð°Ð´Ð°Ñ‡ GitLab%{linkEnd}, Ñкщо вони не викориÑтовуютьÑÑ."
+msgid "JiraService|Displaying Jira issues while leaving GitLab issues also enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
+msgstr ""
+
+msgid "JiraService|Enable Jira issue creation from vulnerabilities"
+msgstr ""
msgid "JiraService|Enable Jira issues"
msgstr "Увімкнути задачі Jira"
-msgid "JiraService|Enable Jira issues creation from vulnerabilities"
-msgstr ""
-
msgid "JiraService|Enable Jira transitions"
-msgstr ""
+msgstr "Увімкнути переходи Jira"
msgid "JiraService|Enter new password or API token"
-msgstr ""
+msgstr "Введіть новий пароль або токен API"
msgid "JiraService|Events for %{noteable_model_name} are disabled."
msgstr "Події Ð´Ð»Ñ %{noteable_model_name} вимкнені."
msgid "JiraService|Failed to load Jira issue. View the issue in Jira, or reload the page."
-msgstr ""
+msgstr "Ðе вдалоÑÑ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶Ð¸Ñ‚Ð¸ задачу Jira. ПереглÑньте задачу в Jira або перезавантажте Ñторінку."
msgid "JiraService|Fetch issue types for this Jira project"
-msgstr ""
+msgstr "Отримати типи задач Ð´Ð»Ñ Ñ†ÑŒÐ¾Ð³Ð¾ проєкту Jira"
msgid "JiraService|For example, 12, 24"
-msgstr ""
+msgstr "Ðаприклад, 12, 24"
msgid "JiraService|For example, AB"
-msgstr ""
+msgstr "Ðаприклад, AB"
msgid "JiraService|GitLab for Jira Configuration"
-msgstr ""
+msgstr "GitLab Ð´Ð»Ñ ÐºÐ¾Ð½Ñ„Ñ–Ð³ÑƒÑ€Ð°Ñ†Ñ–Ñ— Jira"
msgid "JiraService|IDs must be a list of numbers that can be split with , or ;"
-msgstr ""
+msgstr "Ідентифікатори повинні мати виглÑд ÑпиÑку чиÑел, Ñкі можна розділити , або ;"
msgid "JiraService|If different from Web URL."
msgstr ""
msgid "JiraService|Issues created from vulnerabilities in this project will be Jira issues, even if GitLab issues are enabled."
-msgstr ""
+msgstr "Задачі, Ñтворені із вразливоÑтей у цьому проєкті, будуть задачами Jira, навіть Ñкщо задачі GitLab будуть увімкнені."
msgid "JiraService|Jira API URL"
msgstr "URL-адреÑа Jira API"
msgid "JiraService|Jira comments are created when an issue is referenced in a commit."
-msgstr ""
+msgstr "Коментарі Jira ÑтворюютьÑÑ, коли в коміті Ñ” поÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð½Ð° задачу."
msgid "JiraService|Jira comments are created when an issue is referenced in a merge request."
-msgstr ""
+msgstr "Коментарі Jira ÑтворюютьÑÑ, коли в запиті на Ð·Ð»Ð¸Ñ‚Ñ‚Ñ Ñ” поÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð½Ð° задачу."
msgid "JiraService|Jira issue type"
-msgstr ""
+msgstr "Тип задач Jira"
msgid "JiraService|Jira issues"
-msgstr ""
+msgstr "Задачі Jira"
msgid "JiraService|Jira project key"
msgstr "Ключ проєкту Jira"
@@ -20782,7 +21245,7 @@ msgid "JiraService|Project key is required to generate issue types"
msgstr ""
msgid "JiraService|Select issue type"
-msgstr ""
+msgstr "Виберіть тип задачі"
msgid "JiraService|Set a custom final state by using transition IDs. %{linkStart}Learn about transition IDs%{linkEnd}"
msgstr ""
@@ -20826,16 +21289,19 @@ msgstr ""
msgid "JiraService|View Jira issues in GitLab"
msgstr "ПереглÑнути задачі Jira в GitLab"
-msgid "JiraService|Warning: All GitLab users that have access to this GitLab project are able to view all issues from the Jira project specified below."
+msgid "JiraService|Warning: All GitLab users with access to this GitLab project can view all issues from the Jira project you select."
msgstr ""
msgid "JiraService|Web URL"
msgstr "Веб URL"
-msgid "JiraService|Work on Jira issues without leaving GitLab. Adds a Jira menu to access your list of Jira issues and view any issue as read-only."
-msgstr "Робота із задачами Jira, не залишаючи GitLab. Додає меню Jira Ð´Ð»Ñ Ð´Ð¾Ñтупу до ÑпиÑку ваших задач Jira та Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ³Ð»Ñду кожної із задач без можливоÑÑ‚Ñ– редагуваннÑ."
+msgid "JiraService|When a Jira issue is mentioned in a commit or merge request, a remote link and comment (if enabled) will be created."
+msgstr ""
+
+msgid "JiraService|Work on Jira issues without leaving GitLab. Add a Jira menu to access a read-only list of your Jira issues."
+msgstr ""
-msgid "JiraService|You need to configure Jira before enabling this integration. For more details, read the %{jira_doc_link_start}Jira integration documentation%{link_end}."
+msgid "JiraService|You must configure Jira before enabling this integration. %{jira_doc_link_start}Learn more.%{link_end}"
msgstr ""
msgid "Job"
@@ -20847,9 +21313,6 @@ msgstr "Ð—Ð°Ð²Ð´Ð°Ð½Ð½Ñ %{jobName}"
msgid "Job Failed #%{build_id}"
msgstr "Ð—Ð°Ð²Ð´Ð°Ð½Ð½Ñ Ð½ÐµÐ²Ð´Ð°Ð»Ðµ #%{build_id}"
-msgid "Job ID"
-msgstr "Ідентифікатор завданнÑ"
-
msgid "Job artifact"
msgstr ""
@@ -20916,9 +21379,27 @@ msgstr ""
msgid "Jobs|You're about to retry a job that failed because it attempted to deploy code that is older than the latest deployment. Retrying this job could result in overwriting the environment with the older source code."
msgstr ""
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source} into %{target}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{ref}"
+msgstr ""
+
+msgid "Job|Are you sure you want to erase this job log and artifacts?"
+msgstr ""
+
msgid "Job|Browse"
msgstr "ПереглÑнути"
+msgid "Job|Cancel"
+msgstr ""
+
msgid "Job|Complete Raw"
msgstr "Повний неформатований"
@@ -20928,6 +21409,9 @@ msgstr "Завантажити"
msgid "Job|Erase job log and artifacts"
msgstr ""
+msgid "Job|Finished at"
+msgstr ""
+
msgid "Job|Job artifacts"
msgstr "Ðртефакти завдань"
@@ -20940,8 +21424,8 @@ msgstr ""
msgid "Job|Keep"
msgstr "Залишити"
-msgid "Job|Pipeline"
-msgstr "Конвеєр"
+msgid "Job|Retry"
+msgstr ""
msgid "Job|Scroll to bottom"
msgstr "Прокрутити вниз"
@@ -20952,6 +21436,9 @@ msgstr "Прокрутити вгору"
msgid "Job|Show complete raw"
msgstr "Показати повний неформатований"
+msgid "Job|Status"
+msgstr ""
+
msgid "Job|The artifacts were removed"
msgstr "Ðртефакти були видалені"
@@ -20979,21 +21466,12 @@ msgstr ""
msgid "Job|delayed"
msgstr ""
-msgid "Job|for"
-msgstr "длÑ"
-
-msgid "Job|into"
-msgstr "в"
-
msgid "Job|manual"
msgstr ""
msgid "Job|triggered"
msgstr ""
-msgid "Job|with"
-msgstr "з"
-
msgid "Join Zoom meeting"
msgstr "ПриєднатиÑÑ Ð´Ð¾ зуÑтрічі в Zoom"
@@ -21067,25 +21545,25 @@ msgid "Keyboard shortcuts"
msgstr "Комбінації клавіш"
msgid "KeyboardKey|Alt"
-msgstr ""
+msgstr "Alt"
msgid "KeyboardKey|Ctrl"
-msgstr ""
+msgstr "Ctrl"
msgid "KeyboardKey|Ctrl+"
-msgstr ""
+msgstr "Ctrl+"
msgid "KeyboardKey|Enter"
-msgstr ""
+msgstr "Enter"
msgid "KeyboardKey|Esc"
-msgstr ""
+msgstr "Esc"
msgid "KeyboardKey|Shift"
-msgstr ""
+msgstr "Shift"
msgid "KeyboardShortcuts|No shortcuts matched your search"
-msgstr ""
+msgstr "Ðемає комбінацій, що відповідають вашому пошуку"
msgid "KeyboardShortcuts|Search keyboard shortcuts"
msgstr "Пошук комбінацій клавіш"
@@ -21096,9 +21574,6 @@ msgstr "Ключі"
msgid "Ki"
msgstr "Ki"
-msgid "Kontra"
-msgstr ""
-
msgid "Kroki"
msgstr "Kroki"
@@ -21130,7 +21605,7 @@ msgid "Kubernetes cluster was successfully updated."
msgstr "Kubernetes-клаÑтер уÑпішно оновлено."
msgid "Kubernetes clusters"
-msgstr ""
+msgstr "Kubernetes-клаÑтери"
msgid "Kubernetes deployment not found"
msgstr "Ð Ð¾Ð·Ð³Ð¾Ñ€Ñ‚Ð°Ð½Ð½Ñ Kubernetes не знайдено"
@@ -21145,10 +21620,10 @@ msgid "LDAP Synchronization"
msgstr "Ð¡Ð¸Ð½Ñ…Ñ€Ð¾Ð½Ñ–Ð·Ð°Ñ†Ñ–Ñ LDAP"
msgid "LDAP group settings"
-msgstr ""
+msgstr "ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð³Ñ€ÑƒÐ¿Ð¸ LDAP"
msgid "LDAP settings"
-msgstr "ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ LDAP"
+msgstr "Параметри LDAP"
msgid "LDAP settings updated"
msgstr "Параметри LDAP оновлено"
@@ -21157,10 +21632,10 @@ msgid "LDAP sync in progress. This could take a few minutes. Refresh the page to
msgstr "ВідбуваєтьÑÑ ÑÐ¸Ð½Ñ…Ñ€Ð¾Ð½Ñ–Ð·Ð°Ñ†Ñ–Ñ LDAP. Вона може зайнÑти кілька хвилин. Оновлюйте Ñторінку, щоб бачити зміни."
msgid "LDAP synchronizations"
-msgstr ""
+msgstr "Синхронізації LDAP"
msgid "LDAP uid:"
-msgstr ""
+msgstr "uid LDAP:"
msgid "LFS"
msgstr "LFS"
@@ -21217,7 +21692,7 @@ msgid "Labels can be applied to issues and merge requests."
msgstr "Мітки можуть бути заÑтоÑовані до задач та запитів на злиттÑ."
msgid "Labels with no issues in this iteration:"
-msgstr ""
+msgstr "Мітки без задач у цій ітерації:"
msgid "Labels|%{spanStart}Promote label%{spanEnd} %{labelTitle} %{spanStart}to Group Label?%{spanEnd}"
msgstr ""
@@ -21302,7 +21777,7 @@ msgid "Last modified"
msgstr ""
msgid "Last month"
-msgstr ""
+msgstr "Минулий міÑÑць"
msgid "Last name"
msgstr "Прізвище"
@@ -21424,6 +21899,9 @@ msgstr "ДізнайтеÑÑ Ð±Ñ–Ð»ÑŒÑˆÐµ про %{username}"
msgid "Learn more about Auto DevOps"
msgstr "ДізнайтеÑÑ Ð±Ñ–Ð»ÑŒÑˆÐµ про Auto DevOps"
+msgid "Learn more about GitLab"
+msgstr ""
+
msgid "Learn more about Needs relationships"
msgstr ""
@@ -21467,7 +21945,7 @@ msgid "LearnGitLab|%{percentage}%{percentSymbol} completed"
msgstr ""
msgid "LearnGitLab|Add code owners"
-msgstr ""
+msgstr "Додати влаÑників коду"
msgid "LearnGitLab|Add merge request approval"
msgstr ""
@@ -21479,7 +21957,7 @@ msgid "LearnGitLab|Create a workflow for your new workspace, and learn how GitLa
msgstr ""
msgid "LearnGitLab|Create an issue"
-msgstr ""
+msgstr "Створити задачу"
msgid "LearnGitLab|Create or import a repository"
msgstr ""
@@ -21503,7 +21981,7 @@ msgid "LearnGitLab|Invite your colleagues"
msgstr ""
msgid "LearnGitLab|Learn GitLab"
-msgstr ""
+msgstr "ДізнайтеÑÑ Ð±Ñ–Ð»ÑŒÑˆÐµ про GitLab"
msgid "LearnGitLab|Plan and execute"
msgstr ""
@@ -21599,7 +22077,7 @@ msgid "Let's Encrypt is a free, automated, and open certificate authority (CA) t
msgstr "Let's Encrypt Ñ” безкоштовним, автоматизованим та відкритим центром Ñертифікації (CA), Ñкий видає цифрові Ñертифікати Ð´Ð»Ñ Ð°ÐºÑ‚Ð¸Ð²Ð°Ñ†Ñ–Ñ— HTTPS (SSL/TLS) на вебÑайтах. ДізнайтеÑÑ Ð±Ñ–Ð»ÑŒÑˆÐµ про Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Let's Encrypt перейшовши до %{docs_link_start}документації по GitLab Pages%{docs_link_end}."
msgid "Let's talk!"
-msgstr ""
+msgstr "Давайте поговоримо!"
msgid "License Compliance"
msgstr "ВідповідніÑÑ‚ÑŒ ліцензіÑм"
@@ -21611,25 +22089,25 @@ msgid "License file"
msgstr "Файл ліцензії"
msgid "License key"
-msgstr ""
+msgstr "Ліцензійний ключ"
msgid "License overview"
msgstr "ПереглÑд ліцензії"
msgid "LicenseCompliance|%{docLinkStart}License Approvals%{docLinkEnd} are active"
-msgstr ""
+msgstr "%{docLinkStart}Ð—Ð°Ñ‚Ð²ÐµÑ€Ð´Ð¶ÐµÐ½Ð½Ñ Ð»Ñ–Ñ†ÐµÐ½Ð·Ñ–Ñ—%{docLinkEnd} активні"
msgid "LicenseCompliance|%{docLinkStart}License Approvals%{docLinkEnd} are inactive"
-msgstr ""
+msgstr "%{docLinkStart}Ð—Ð°Ñ‚Ð²ÐµÑ€Ð´Ð¶ÐµÐ½Ð½Ñ Ð»Ñ–Ñ†ÐµÐ½Ð·Ñ–Ñ—%{docLinkEnd} неактивні"
msgid "LicenseCompliance|Acceptable license to be used in the project"
-msgstr ""
+msgstr "ПрийнÑтна Ð»Ñ–Ñ†ÐµÐ½Ð·Ñ–Ñ Ð´Ð»Ñ Ð²Ð¸ÐºÐ¾Ñ€Ð¸ÑÑ‚Ð°Ð½Ð½Ñ Ð² проєкті"
msgid "LicenseCompliance|Add license and related policy"
msgstr "Додати ліцензію та відповідну політику"
msgid "LicenseCompliance|Add license policy"
-msgstr ""
+msgstr "Додати ліцензійну політику"
msgid "LicenseCompliance|Allow"
msgstr "Дозволити"
@@ -21638,19 +22116,19 @@ msgid "LicenseCompliance|Allowed"
msgstr "Дозволено"
msgid "LicenseCompliance|Denied"
-msgstr ""
+msgstr "Відхилено"
msgid "LicenseCompliance|Deny"
-msgstr ""
+msgstr "Відхилити"
msgid "LicenseCompliance|Disallow merge request if detected and will instruct developer to remove"
-msgstr ""
+msgstr "Заборонити запит на злиттÑ, Ñкщо його буде виÑвлено та дати вказівку розробнику видалити"
msgid "LicenseCompliance|Learn more about %{linkStart}License Approvals%{linkEnd}"
-msgstr ""
+msgstr "ДізнатиÑÑ Ð±Ñ–Ð»ÑŒÑˆÐµ про %{linkStart}Ð—Ð°Ñ‚Ð²ÐµÑ€Ð´Ð¶ÐµÐ½Ð½Ñ Ð»Ñ–Ñ†ÐµÐ½Ð·Ñ–Ñ—%{linkEnd}"
msgid "LicenseCompliance|License Approvals"
-msgstr ""
+msgstr "Ð—Ð°Ñ‚Ð²ÐµÑ€Ð´Ð¶ÐµÐ½Ð½Ñ Ð»Ñ–Ñ†ÐµÐ½Ð·Ñ–Ñ—"
msgid "LicenseCompliance|License Compliance detected %d license and policy violation for the source branch only"
msgid_plural "LicenseCompliance|License Compliance detected %d licenses and policy violations for the source branch only"
@@ -21710,10 +22188,10 @@ msgid "LicenseCompliance|Remove license?"
msgstr "Видалити ліцензію?"
msgid "LicenseCompliance|There are currently no policies in this project."
-msgstr ""
+msgstr "Ðаразі в цьому проєкті немає політик."
msgid "LicenseCompliance|There are currently no policies that match in this project."
-msgstr ""
+msgstr "Ðаразі немає політик, Ñкі б відповідали цьому проєкту."
msgid "LicenseCompliance|This license already exists in this project."
msgstr "Така Ð»Ñ–Ñ†ÐµÐ½Ð·Ñ–Ñ Ð²Ð¶Ðµ Ñ–Ñнує в цьому проєкті."
@@ -21725,7 +22203,7 @@ msgid "LicenseManagement|Allowed"
msgstr "Дозволено"
msgid "LicenseManagement|Denied"
-msgstr ""
+msgstr "Відхилено"
msgid "LicenseManagement|Uncategorized"
msgstr ""
@@ -21746,7 +22224,7 @@ msgid "Licenses|%{remainingComponentsCount} more"
msgstr "Ще %{remainingComponentsCount}"
msgid "Licenses|Acceptable license to be used in the project"
-msgstr ""
+msgstr "ПрийнÑтна Ð»Ñ–Ñ†ÐµÐ½Ð·Ñ–Ñ Ð´Ð»Ñ Ð²Ð¸ÐºÐ¾Ñ€Ð¸ÑÑ‚Ð°Ð½Ð½Ñ Ñƒ цьому проєкті"
msgid "Licenses|Component"
msgstr "Компонент"
@@ -21761,11 +22239,20 @@ 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 "Відображає ліцензії, виÑвлені у цьому проєкті, на оÑнові %{linkStart}оÑтаннього уÑпішного%{linkEnd} ÑкануваннÑ"
+
+msgid "Licenses|Drag your license file here or %{linkStart}click to upload%{linkEnd}."
+msgstr ""
+
+msgid "Licenses|Drop your license file to start the upload."
msgstr ""
msgid "Licenses|Error fetching the license list. Please check your network connection and try again."
msgstr "Помилка під Ñ‡Ð°Ñ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ð½Ð½Ñ ÑпиÑку ліцензій. Будь лаÑка, перевірте Ð¿Ñ–Ð´ÐºÐ»ÑŽÑ‡ÐµÐ½Ð½Ñ Ð´Ð¾ мережі та Ñпробуйте ще раз."
+msgid "Licenses|Error: You are trying to upload something other than a file"
+msgstr ""
+
msgid "Licenses|License Compliance"
msgstr "ВідповідніÑÑ‚ÑŒ Ліцензії"
@@ -21779,16 +22266,19 @@ msgid "Licenses|Policy"
msgstr "Політика"
msgid "Licenses|Policy violation: denied"
-msgstr ""
+msgstr "ÐŸÐ¾Ñ€ÑƒÑˆÐµÐ½Ð½Ñ Ð¿Ð¾Ð»Ñ–Ñ‚Ð¸ÐºÐ¸: відхилено"
msgid "Licenses|Specified policies in this project"
+msgstr "Зазначені політики у цьому проєкті"
+
+msgid "Licenses|The file could not be uploaded."
msgstr ""
msgid "Licenses|The license list details information about the licenses used within your project."
msgstr "СпиÑок ліцензій міÑтить детальну інформацію про Ñ‚Ñ–, Ñкі викориÑтовуютьÑÑ Ñƒ вашому проєкті."
msgid "Licenses|Unacceptable license, if detected it will disallow a merge request until it's removed"
-msgstr ""
+msgstr "ÐеприйнÑтна ліцензіÑ, Ñкщо Ñ—Ñ— буде виÑвлено, запит на Ð·Ð»Ð¸Ñ‚Ñ‚Ñ Ð±ÑƒÐ´Ðµ заборонений, доки вона не буде видалена"
msgid "Licenses|View license details for your project"
msgstr "ПереглÑд деталей ліцензії Ð´Ð»Ñ Ð²Ð°ÑˆÐ¾Ð³Ð¾ проєкту"
@@ -21797,13 +22287,13 @@ msgid "Limit display of time tracking units to hours."
msgstr "Обмежити Ð²Ñ–Ð´Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Ð¾Ð´Ð¸Ð½Ð¸Ñ†ÑŒ відÑÑ‚ÐµÐ¶ÐµÐ½Ð½Ñ Ñ‡Ð°Ñу до годин."
msgid "Limit project size at a global, group, and project level. %{link_start}Learn more%{link_end}."
-msgstr ""
+msgstr "Обмежити розмір проєкту на загальному, груповому та проєктному рівнÑÑ…. %{link_start}ДізнатиÑÑ Ð±Ñ–Ð»ÑŒÑˆÐµ%{link_end}."
msgid "Limit sign in from multiple IP addresses"
-msgstr ""
+msgstr "Обмежити вхід з кількох IP-адреÑ"
msgid "Limit the number of concurrent operations this secondary site can run in the background."
-msgstr ""
+msgstr "Обмежити кількіÑÑ‚ÑŒ одночаÑних операцій, Ñкі цей вторинний Ñайт може виконувати у фоновому режимі."
msgid "Limit the number of inbound incident management alerts that can be sent to a project."
msgstr ""
@@ -21812,18 +22302,11 @@ msgid "Limit the number of issues and epics per minute a user can create through
msgstr ""
msgid "Limit the number of namespaces and projects that can be indexed."
-msgstr ""
+msgstr "Обмежити кількіÑÑ‚ÑŒ проÑторів імен та проєктів, що можуть бути індекÑовані."
msgid "Limit the size of Sidekiq jobs stored in Redis."
msgstr ""
-msgid "Limited to showing %d event at most"
-msgid_plural "Limited to showing %d events at most"
-msgstr[0] "Показ обмежено тільки %d подією"
-msgstr[1] "Показ обмежено тільки %d подіÑми"
-msgstr[2] "Показ обмежено тільки %d подіÑми"
-msgstr[3] "Показ обмежено тільки %d подіÑми"
-
msgid "Limiting mode"
msgstr "Режим обмеженнÑ"
@@ -21833,6 +22316,9 @@ msgstr "Зміни Ñ€Ñдка"
msgid "Link"
msgstr "ПоÑиланнÑ"
+msgid "Link (optional)"
+msgstr ""
+
msgid "Link Prometheus monitoring to GitLab."
msgstr ""
@@ -21869,6 +22355,9 @@ msgstr ""
msgid "Linked emails (%{email_count})"
msgstr "Пов’Ñзані адреÑи електронної пошти (%{email_count})"
+msgid "Linked epics"
+msgstr ""
+
msgid "Linked issues"
msgstr "Пов'Ñзані задачі"
@@ -21876,7 +22365,7 @@ msgid "LinkedIn"
msgstr "LinkedIn"
msgid "LinkedIn:"
-msgstr ""
+msgstr "LinkedIn:"
msgid "LinkedPipelines|%{counterLabel} more downstream pipelines"
msgstr "Ще %{counterLabel} наÑтупних конвеєрів"
@@ -21894,11 +22383,20 @@ msgid "List available repositories"
msgstr "СпиÑок доÑтупних репозиторіїв"
msgid "List of all merge commits"
+msgstr "СпиÑок уÑÑ–Ñ… комітів злиттÑ"
+
+msgid "List of environments for this project"
msgstr ""
-msgid "List options"
+msgid "List of suitable GCP locations"
+msgstr ""
+
+msgid "List of users allowed to exceed the rate limit."
msgstr ""
+msgid "List options"
+msgstr "Параметри ÑпиÑку"
+
msgid "List settings"
msgstr "СпиÑок налаштувань"
@@ -21966,7 +22464,7 @@ msgid "Lock %{issuableDisplayName}"
msgstr "Заблокувати %{issuableDisplayName}"
msgid "Lock File?"
-msgstr ""
+msgstr "Заблокувати файл?"
msgid "Lock memberships to LDAP synchronization"
msgstr "ЗафікÑувати належноÑÑ‚Ñ– (до груп) через LDAP Ñинхронізацію"
@@ -22005,7 +22503,7 @@ msgid "Locks the discussion."
msgstr "Блокує обговореннÑ."
msgid "LoggedOutMarketingHeader|About GitLab"
-msgstr ""
+msgstr "Про GitLab"
msgid "LoggedOutMarketingHeader|Explore GitLab"
msgstr ""
@@ -22014,10 +22512,10 @@ msgid "LoggedOutMarketingHeader|Get started"
msgstr ""
msgid "LoggedOutMarketingHeader|GitLab Learn"
-msgstr ""
+msgstr "ДізнайтеÑÑ Ð¿Ñ€Ð¾ GitLab"
msgid "LoggedOutMarketingHeader|GitLab docs"
-msgstr ""
+msgstr "Ð”Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð°Ñ†Ñ–Ñ GitLab"
msgid "LoggedOutMarketingHeader|GitLab: the DevOps platform"
msgstr ""
@@ -22035,7 +22533,7 @@ msgid "LoggedOutMarketingHeader|Talk to an expert"
msgstr ""
msgid "Login"
-msgstr ""
+msgstr "Увійти"
msgid "Login with smartcard"
msgstr "Вхід за допомогою Ñмарт-картки"
@@ -22065,10 +22563,10 @@ msgid "MERGED"
msgstr "ЗЛИТО"
msgid "MR widget|Back to the merge request"
-msgstr ""
+msgstr "ПовернутиÑÑ Ð´Ð¾ запиту на злиттÑ"
msgid "MR widget|See your pipeline in action"
-msgstr ""
+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 learn more."
msgstr ""
@@ -22115,6 +22613,9 @@ msgstr ""
msgid "Maintenance mode"
msgstr "Режим обÑлуговуваннÑ"
+msgid "Make adjustments to how your GitLab instance is set up."
+msgstr ""
+
msgid "Make and review changes in the browser with the Web IDE"
msgstr "ЗдійÑнити та переглÑнути зміни в браузері за допомогою веб-IDE"
@@ -22259,6 +22760,12 @@ msgstr ""
msgid "MarkdownEditor|Add italic text (%{modifier_key}I)"
msgstr ""
+msgid "MarkdownEditor|Add strikethrough text (%{modifierKey}⇧X)"
+msgstr ""
+
+msgid "MarkdownEditor|Add strikethrough text (%{modifier_key}⇧X)"
+msgstr ""
+
msgid "Marked For Deletion At - %{deletion_time}"
msgstr ""
@@ -22344,7 +22851,7 @@ msgid "Max authenticated Git LFS requests per period per user"
msgstr ""
msgid "Max file size is 200 KB."
-msgstr ""
+msgstr "МакÑимальний розмір файлу 200 KB."
msgid "Max role"
msgstr "МакÑимальна роль"
@@ -22491,7 +22998,7 @@ msgid "Maximum number of mirrors that can be synchronizing at the same time."
msgstr "МакÑимальна кількіÑÑ‚ÑŒ дзеркал, що можуть бути Ñинхронізовані одночаÑно."
msgid "Maximum number of projects."
-msgstr ""
+msgstr "МакÑимальна кількіÑÑ‚ÑŒ проєктів."
msgid "Maximum number of requests per minute for each raw path (default is 300). Set to 0 to disable throttling."
msgstr ""
@@ -22520,6 +23027,9 @@ msgstr ""
msgid "Maximum push size (MB)"
msgstr "МакÑимальний розмір Ð´Ð»Ñ Ð²Ñ–Ð´Ð¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð½Ñ (МБ)"
+msgid "Maximum requests per 10 minutes per user"
+msgstr ""
+
msgid "Maximum requests per minute"
msgstr ""
@@ -22610,6 +23120,23 @@ msgstr ""
msgid "Members of a group may only view projects they have permission to access"
msgstr ""
+msgid "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seat in use and will be billed for the overage."
+msgid_plural "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seats in use and will be billed for the overage."
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
+msgid "MembersOverage|You are about to incur additional charges"
+msgstr ""
+
+msgid "MembersOverage|Your subscription includes %d seat."
+msgid_plural "MembersOverage|Your subscription includes %d seats."
+msgstr[0] ""
+msgstr[1] ""
+msgstr[2] ""
+msgstr[3] ""
+
msgid "Membership"
msgstr ""
@@ -22623,22 +23150,22 @@ msgid "Members|2FA"
msgstr ""
msgid "Members|An error occurred while trying to enable LDAP override, please try again."
-msgstr ""
+msgstr "Виникла помилка під Ñ‡Ð°Ñ Ñпроби увімкнути Ð¿ÐµÑ€ÐµÐ²Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ LDAP, будь лаÑка, Ñпробуйте знову."
msgid "Members|An error occurred while trying to revert to LDAP group sync settings, please try again."
msgstr ""
msgid "Members|An error occurred while updating the member's expiration date, please try again."
-msgstr ""
+msgstr "Виникла помилка під Ñ‡Ð°Ñ Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð·Ð°ÐºÑ–Ð½Ñ‡ÐµÐ½Ð½Ñ Ñ‚ÐµÑ€Ð¼Ñ–Ð½Ñƒ дії учаÑника, будь лаÑка, Ñпробуйте знову."
msgid "Members|An error occurred while updating the member's role, please try again."
-msgstr ""
+msgstr "Виникла помилка під Ñ‡Ð°Ñ Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ñ€Ð¾Ð»Ñ– учаÑника. будь лаÑка, Ñпробуйте знову."
msgid "Members|Are you sure you want to deny %{usersName}'s request to join \"%{source}\""
-msgstr ""
+msgstr "Ви впевнені, що хочете відхилити запит %{usersName} на Ð¿Ñ€Ð¸Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð´Ð¾ \"%{source}\""
msgid "Members|Are you sure you want to leave \"%{source}\"?"
-msgstr ""
+msgstr "Ви впевнені, що хочете залишити \"%{source}\"?"
msgid "Members|Are you sure you want to remove \"%{groupName}\"?"
msgstr "Ви впевнені, що хочете видалити\"%{groupName}?"
@@ -22650,10 +23177,10 @@ msgid "Members|Are you sure you want to remove this orphaned member from \"%{sou
msgstr ""
msgid "Members|Are you sure you want to revoke the invitation for %{inviteEmail} to join \"%{source}\""
-msgstr ""
+msgstr "Ви впевнені, що хочете відкликати Ð·Ð°Ð¿Ñ€Ð¾ÑˆÐµÐ½Ð½Ñ Ð´Ð»Ñ %{inviteEmail} приєднатиÑÑ Ð´Ð¾ \"%{source}\""
msgid "Members|Are you sure you want to withdraw your access request for \"%{source}\""
-msgstr ""
+msgstr "Ви впевнені, що хочете відкликати Ñвій запит на доÑтуп до \"%{source}\""
msgid "Members|Direct"
msgstr ""
@@ -22668,22 +23195,22 @@ msgid "Members|Enabled"
msgstr ""
msgid "Members|Expiration date removed successfully."
-msgstr ""
+msgstr "Дата Ð·Ð°ÐºÑ–Ð½Ñ‡ÐµÐ½Ð½Ñ Ñ‚ÐµÑ€Ð¼Ñ–Ð½Ñƒ дії уÑпішно видалена."
msgid "Members|Expiration date updated successfully."
-msgstr ""
+msgstr "Дата Ð·Ð°ÐºÑ–Ð½Ñ‡ÐµÐ½Ð½Ñ Ñ‚ÐµÑ€Ð¼Ñ–Ð½Ñƒ дії уÑпішно оновлена."
msgid "Members|Filter members"
msgstr "Фільтр учаÑників"
msgid "Members|Inherited"
-msgstr ""
+msgstr "УÑпадковані"
msgid "Members|LDAP override enabled."
msgstr ""
msgid "Members|Leave \"%{source}\""
-msgstr ""
+msgstr "Залишити \"%{source}\""
msgid "Members|Membership"
msgstr ""
@@ -22701,10 +23228,10 @@ msgid "Members|Reverted to LDAP group sync settings."
msgstr ""
msgid "Members|Role updated successfully."
-msgstr ""
+msgstr "Роль уÑпішно оновлена."
msgid "Members|Search groups"
-msgstr ""
+msgstr "Пошук груп"
msgid "Members|Search invited"
msgstr ""
@@ -22734,7 +23261,7 @@ msgid "Merge Request"
msgstr "Запит на злиттÑ"
msgid "Merge Request Analytics"
-msgstr ""
+msgstr "Ðналітика запитів на злиттÑ"
msgid "Merge Requests"
msgstr "Запити на злиттÑ"
@@ -22767,7 +23294,7 @@ msgid "Merge blocked: the source branch must be rebased onto the target branch."
msgstr ""
msgid "Merge commit SHA"
-msgstr ""
+msgstr "SHA коміту злиттÑ"
msgid "Merge commit message"
msgstr "ÐŸÐ¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð´Ð»Ñ ÐºÐ¾Ð¼Ñ–Ñ‚Ñƒ-злиттÑ"
@@ -22814,9 +23341,6 @@ msgstr "Події запиту на злиттÑ"
msgid "Merge request not merged"
msgstr ""
-msgid "Merge request pipelines 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 merge request pipelines."
-msgstr ""
-
msgid "Merge request reports"
msgstr ""
@@ -22845,7 +23369,7 @@ msgid "Merge when pipeline succeeds"
msgstr "Злити, коли конвеєр уÑпішно завершитьÑÑ"
msgid "Merge..."
-msgstr ""
+msgstr "ЗлиттÑ..."
msgid "MergeConflict|Commit to source branch"
msgstr "Закомітити в гілку-джерело"
@@ -22913,13 +23437,13 @@ msgstr "Виникла помилка під Ñ‡Ð°Ñ Ð·Ð±ÐµÑ€ÐµÐ¶ÐµÐ½Ð½Ñ Ñ‡ÐµÑ€Ð
msgid "MergeRequests|Create issue to resolve thread"
msgstr ""
-msgid "MergeRequests|Failed to squash. Should be done manually."
-msgstr "ÐевдалоÑÑ Ð¾Ð±â€™Ñ”Ð´Ð½Ð°Ñ‚Ð¸ коміти. Це повинно бути виконано вручну."
-
msgid "MergeRequests|Saving the comment failed"
msgstr "Помилка при збереженні коментарÑ"
-msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
+msgid "MergeRequests|Squashing failed: Squash the commits locally, resolve any conflicts, then push the branch."
+msgstr ""
+
+msgid "MergeRequests|Squashing not allowed: This project doesn't allow you to squash commits when merging."
msgstr ""
msgid "MergeRequests|Thread stays resolved"
@@ -23070,28 +23594,28 @@ msgid "Metrics and profiling"
msgstr "Метрики та профілюваннÑ"
msgid "Metrics:"
-msgstr ""
+msgstr "Метрики:"
msgid "MetricsDashboardAnnotation|Annotation can't belong to both a cluster and an environment at the same time"
msgstr ""
msgid "MetricsDashboardAnnotation|Annotation has not been deleted"
-msgstr ""
+msgstr "ÐÐ½Ð¾Ñ‚Ð°Ñ†Ñ–Ñ Ð½Ðµ була видалена"
msgid "MetricsDashboardAnnotation|Annotation must belong to a cluster or an environment"
-msgstr ""
+msgstr "ÐÐ½Ð¾Ñ‚Ð°Ñ†Ñ–Ñ Ð¿Ð¾Ð²Ð¸Ð½Ð½Ð° належати до клаÑтера або до Ñередовища"
msgid "MetricsDashboardAnnotation|Dashboard with requested path can not be found"
-msgstr ""
+msgstr "Панель ÐºÐµÑ€ÑƒÐ²Ð°Ð½Ð½Ñ Ñ–Ð· запитаним шлÑхом не може бути знайдена"
msgid "MetricsDashboardAnnotation|You are not authorized to create annotation for selected cluster"
-msgstr ""
+msgstr "Ви не можете Ñтворити анотацію Ð´Ð»Ñ Ð²Ð¸Ð±Ñ€Ð°Ð½Ð¾Ð³Ð¾ клаÑтера"
msgid "MetricsDashboardAnnotation|You are not authorized to create annotation for selected environment"
-msgstr ""
+msgstr "Ви не можете Ñтворити анотацію Ð´Ð»Ñ Ð²Ð¸Ð±Ñ€Ð°Ð½Ð¾Ð³Ð¾ Ñередовища"
msgid "MetricsDashboardAnnotation|You are not authorized to delete this annotation"
-msgstr ""
+msgstr "Ви не можете видалити цю анотацію"
msgid "MetricsDashboardAnnotation|can't be before starting_at time"
msgstr ""
@@ -23103,16 +23627,16 @@ msgid "MetricsSettings|Choose whether to display dashboard metrics in UTC or the
msgstr ""
msgid "MetricsSettings|Dashboard timezone"
-msgstr ""
+msgstr "ЧаÑовий поÑÑ Ð¿Ð°Ð½ÐµÐ»Ñ– керуваннÑ"
msgid "MetricsSettings|External dashboard URL"
-msgstr ""
+msgstr "URL-адреÑа зовнішньої панелі керуваннÑ"
msgid "MetricsSettings|Manage metrics dashboard settings."
msgstr ""
msgid "MetricsSettings|Metrics"
-msgstr ""
+msgstr "Метрики"
msgid "MetricsSettings|UTC (Coordinated Universal Time)"
msgstr ""
@@ -23169,10 +23693,10 @@ msgid "Metrics|Create metric"
msgstr "Створити метрику"
msgid "Metrics|Create new dashboard"
-msgstr ""
+msgstr "Створити нову панель керуваннÑ"
msgid "Metrics|Create your dashboard configuration file"
-msgstr ""
+msgstr "Створити файл конфігурації панелі керуваннÑ"
msgid "Metrics|Current"
msgstr ""
@@ -23612,16 +24136,16 @@ msgid "Missing commit signatures endpoint!"
msgstr "ВідÑÑƒÑ‚Ð½Ñ ÐºÑ–Ð½Ñ†ÐµÐ²Ð° точка Ð´Ð»Ñ Ð¿Ñ–Ð´Ð¿Ð¸Ñів комітів!"
msgid "MissingSSHKeyWarningLink|Add SSH key"
-msgstr ""
+msgstr "Додати ключ SSH"
msgid "MissingSSHKeyWarningLink|Don't show again"
msgstr "Більше не показувати"
msgid "MissingSSHKeyWarningLink|You can't push or pull repositories using SSH until you add an SSH key to your profile."
-msgstr ""
+msgstr "Ви не можете відправлÑти або отримувати репозиторії за допомогою SSH, поки не додаÑте ключ SSH до Ñвого профілю."
msgid "MissingSSHKeyWarningLink|You won't be able to pull or push repositories via SSH until you add an SSH key to your profile"
-msgstr ""
+msgstr "Ви не зможете відправлÑти або отримувати репозиторії через SSH, поки не додаÑте ключ SSH до Ñвого профілю."
msgid "ModalButton|Add projects"
msgstr "Додати проєкти"
@@ -23687,7 +24211,7 @@ msgid "More information and share feedback"
msgstr "Ðадати більше інформації Ñ– поділитиÑÑ Ð²Ñ–Ð´Ð³ÑƒÐºÐ¾Ð¼"
msgid "More information is available|here"
-msgstr ""
+msgstr "тут"
msgid "More information."
msgstr "Докладніше."
@@ -23696,7 +24220,7 @@ msgid "More than %{number_commits_distance} commits different with %{default_bra
msgstr "Ð Ñ–Ð·Ð½Ð¸Ñ†Ñ Ñ–Ð· %{default_branch} Ñкладає більше %{number_commits_distance} комітів"
msgid "More topics"
-msgstr ""
+msgstr "Більше тем"
msgid "Most relevant"
msgstr ""
@@ -23764,6 +24288,18 @@ msgstr "Повторно розгорнути"
msgid "MrDeploymentActions|Stop environment"
msgstr "Зупинити Ñередовище"
+msgid "MrList|Assigned to %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from assignee %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from reviewer %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Review requested from %{name}, go to their profile."
+msgstr ""
+
msgid "Multi-project"
msgstr "Багатопроєкт"
@@ -23797,8 +24333,8 @@ msgstr ""
msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "My Awesome Group"
-msgstr "ÐœÐ¾Ñ Ð´Ð¸Ð²Ð¾Ð²Ð¸Ð¶Ð½Ð° група"
+msgid "My awesome group"
+msgstr ""
msgid "My company or team"
msgstr "ÐœÐ¾Ñ ÐºÐ¾Ð¼Ð¿Ð°Ð½Ñ–Ñ Ð°Ð±Ð¾ команда"
@@ -23816,13 +24352,13 @@ msgid "Name"
msgstr "Ім’Ñ"
msgid "Name can't be blank"
-msgstr ""
+msgstr "Ðе може бути порожнім"
msgid "Name has already been taken"
msgstr "Ð†Ð¼â€™Ñ Ð²Ð¶Ðµ викориÑтовуєтьÑÑ"
msgid "Name is already taken."
-msgstr ""
+msgstr "Ім'Ñ Ð²Ð¶Ðµ зайнÑто."
msgid "Name new label"
msgstr "Ðазвіть нову мітку"
@@ -23850,7 +24386,7 @@ msgstr[2] ""
msgstr[3] ""
msgid "NamespaceStorageSize|%{namespace_name} is now read-only. You cannot: %{base_message}"
-msgstr ""
+msgstr "%{namespace_name} зараз доÑтупний лише Ð´Ð»Ñ Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ. Ви не можете: %{base_message}"
msgid "NamespaceStorageSize|If you reach 100%% storage capacity, you will not be able to: %{base_message}"
msgstr ""
@@ -24000,19 +24536,19 @@ msgid "NetworkPolicies|Allow all outbound traffic from %{selector} to %{ruleSele
msgstr ""
msgid "NetworkPolicies|Are you sure you want to delete this policy? This action cannot be undone."
-msgstr ""
+msgstr "Ви впевнені, що хочете видалити цю політику? Цю дію не можна ÑкаÑувати."
msgid "NetworkPolicies|Create policy"
-msgstr ""
+msgstr "Створити політику"
msgid "NetworkPolicies|Define this policy's location, conditions and actions."
-msgstr ""
+msgstr "Визначте розташуваннÑ, умови та дії цієї політики."
msgid "NetworkPolicies|Delete policy"
-msgstr ""
+msgstr "Видалити політику"
msgid "NetworkPolicies|Delete policy: %{policy}"
-msgstr ""
+msgstr "Видалити політику: %{policy}"
msgid "NetworkPolicies|Deny all traffic"
msgstr ""
@@ -24051,10 +24587,10 @@ msgid "NetworkPolicies|None selected"
msgstr ""
msgid "NetworkPolicies|Policy %{policyName} was successfully changed"
-msgstr ""
+msgstr "Політика %{policyName} була уÑпішно змінена"
msgid "NetworkPolicies|Policy definition"
-msgstr ""
+msgstr "Ð’Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð¿Ð¾Ð»Ñ–Ñ‚Ð¸ÐºÐ¸"
msgid "NetworkPolicies|Rule mode"
msgstr ""
@@ -24063,10 +24599,10 @@ msgid "NetworkPolicies|Rule mode is unavailable for this policy. In some cases,
msgstr ""
msgid "NetworkPolicies|Save changes"
-msgstr ""
+msgstr "Зберегти зміни"
msgid "NetworkPolicies|Something went wrong, failed to update policy"
-msgstr ""
+msgstr "ЩоÑÑŒ пішло не так, не вдалоÑÑ Ð¾Ð½Ð¾Ð²Ð¸Ñ‚Ð¸ політику"
msgid "NetworkPolicies|Something went wrong, unable to fetch policies"
msgstr ""
@@ -24292,7 +24828,7 @@ msgid "New project"
msgstr "Ðовий проєкт"
msgid "New project page"
-msgstr ""
+msgstr "Ðова Ñторінка проєкту"
msgid "New project pages"
msgstr "Ðові Ñторінки проєкту"
@@ -24423,9 +24959,6 @@ msgstr "Методи автентифікації не налаштовано."
msgid "No available branches"
msgstr "Ðемає доÑтупних гілок"
-msgid "No available groups to fork the project."
-msgstr ""
-
msgid "No branches found"
msgstr "Гілок не знайдено"
@@ -24568,7 +25101,7 @@ msgid "No matching results for \"%{query}\""
msgstr ""
msgid "No matching results..."
-msgstr ""
+msgstr "Ðемає відповідних результатів..."
msgid "No member provided"
msgstr "Ðемає учаÑника"
@@ -24592,7 +25125,7 @@ msgid "No milestones to show"
msgstr "Ðемає етапів Ð´Ð»Ñ Ð¿Ð¾ÐºÐ°Ð·Ñƒ"
msgid "No namespace"
-msgstr ""
+msgstr "Ðемає проÑтору імен"
msgid "No other labels with such name or description"
msgstr "Ðемає інших міток з таким іменем або опиÑом"
@@ -24625,7 +25158,7 @@ msgid "No project subscribes to the pipelines in this project."
msgstr ""
msgid "No projects found"
-msgstr ""
+msgstr "Проєкти не знайдені"
msgid "No public deploy keys"
msgstr ""
@@ -24634,6 +25167,9 @@ msgid "No public groups"
msgstr "Ðемає публічних груп"
msgid "No ref selected"
+msgstr "ПоÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð½Ðµ вибрано"
+
+msgid "No regions configured"
msgstr ""
msgid "No related merge requests found."
@@ -24701,7 +25237,7 @@ msgstr[2] ""
msgstr[3] ""
msgid "No. of commits"
-msgstr ""
+msgstr "КількіÑÑ‚ÑŒ комітів"
msgid "Nobody has starred this repository yet"
msgstr "Ðіхто ще не додав цей репозиторій в обране"
@@ -24752,7 +25288,7 @@ msgid "Not confidential"
msgstr "Ðе конфіденційно"
msgid "Not found"
-msgstr ""
+msgstr "Ðе знайдено"
msgid "Not found."
msgstr "Ðе знайдено."
@@ -25248,16 +25784,16 @@ msgid "OnDemandScans|Create new site profile"
msgstr ""
msgid "OnDemandScans|Delete profile"
-msgstr ""
+msgstr "Видалити профіль"
msgid "OnDemandScans|Description (optional)"
-msgstr ""
+msgstr "ÐžÐ¿Ð¸Ñ (необов'Ñзково)"
msgid "OnDemandScans|Edit on-demand DAST scan"
msgstr ""
msgid "OnDemandScans|Edit profile"
-msgstr ""
+msgstr "Редагувати профіль"
msgid "OnDemandScans|For example: Tests the login page for SQL injections"
msgstr ""
@@ -25384,10 +25920,10 @@ msgstr[2] "Ще %d елементів"
msgstr[3] "Ще %d елементів"
msgid "One or more contacts were successfully added."
-msgstr ""
+msgstr "Один або більше контактів були уÑпішно додані."
msgid "One or more contacts were successfully removed."
-msgstr ""
+msgstr "Один або більше контактів були уÑпішно видалені."
msgid "One or more groups that you don't have access to."
msgstr "Одна або декілька груп, до Ñких ви не маєте доÑтупу."
@@ -25452,6 +25988,9 @@ msgstr ""
msgid "Only reCAPTCHA v2 is supported:"
msgstr ""
+msgid "Only required if not using role instance credentials."
+msgstr ""
+
msgid "Only use lowercase letters, numbers, and underscores."
msgstr ""
@@ -25476,9 +26015,6 @@ msgstr "Відкрити виділеннÑ"
msgid "Open a CLI and connect to the cluster you want to install the agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
-msgid "Open epics"
-msgstr ""
-
msgid "Open errors"
msgstr "Відкрити помилки"
@@ -25504,7 +26040,7 @@ msgid "Open: %{open}"
msgstr ""
msgid "OpenAPI"
-msgstr ""
+msgstr "OpenAPI"
msgid "OpenAPI Specification file path or URL"
msgstr ""
@@ -25518,8 +26054,8 @@ msgstr "Відкриті запити на злиттÑ"
msgid "Opened issues"
msgstr "Відкриті задачі"
-msgid "OpenedNDaysAgo|Opened"
-msgstr "Відкрито"
+msgid "OpenedNDaysAgo|Created"
+msgstr ""
msgid "Opens in a new window"
msgstr "ВідкриваєтьÑÑ Ñƒ новому вікні"
@@ -25528,7 +26064,7 @@ msgid "Operation failed. Check pod logs for %{pod_name} for more details."
msgstr "ÐžÐ¿ÐµÑ€Ð°Ñ†Ñ–Ñ Ð·Ð°Ð²ÐµÑ€ÑˆÐ¸Ð»Ð°ÑÑ Ð½ÐµÐ²Ð´Ð°Ð»Ð¾. Перевірте журнал pod'а %{pod_name} Ð´Ð»Ñ Ð±Ñ–Ð»ÑŒÑˆ детальної інформації."
msgid "Operation not allowed"
-msgstr ""
+msgstr "ÐžÐ¿ÐµÑ€Ð°Ñ†Ñ–Ñ Ð·Ð°Ð±Ð¾Ñ€Ð¾Ð½ÐµÐ½Ð°"
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
msgstr "ÐžÐ¿ÐµÑ€Ð°Ñ†Ñ–Ñ Ð¿ÐµÑ€ÐµÐ²Ð¸Ñ‰Ð¸Ð»Ð° ліміт очікуваннÑ. Перевірте журнал pod'а %{pod_name} Ð´Ð»Ñ Ð±Ñ–Ð»ÑŒÑˆ детальної інформації."
@@ -25563,9 +26099,6 @@ msgstr "Ðеобов'Ñзково"
msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
-msgid "Optional."
-msgstr ""
-
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
msgstr "За необхідноÑÑ‚Ñ– ви можете %{link_to_customize} Ñк адреÑи електронної почти та імена кориÑтувачів FobBugz будуть імпортовані у GitLab."
@@ -25994,7 +26527,7 @@ msgid "PackageRegistry|Recipe: %{recipe}"
msgstr ""
msgid "PackageRegistry|Registry setup"
-msgstr "ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ñ€ÐµÑ”Ñтру"
+msgstr "Параметри реєÑтру"
msgid "PackageRegistry|Remove package"
msgstr "Видалити пакет"
@@ -26078,7 +26611,7 @@ msgid "PackageRegistry|You are about to delete %{name}, this operation is irreve
msgstr ""
msgid "PackageRegistry|You are about to delete version %{version} of %{name}. Are you sure?"
-msgstr ""
+msgstr "Ви збираєтеÑÑ Ð²Ð¸Ð´Ð°Ð»Ð¸Ñ‚Ð¸ верÑÑ–ÑŽ %{version} з %{name}. Ви впевнені?"
msgid "PackageRegistry|You may also need to setup authentication using an auth token. %{linkStart}See the documentation%{linkEnd} to find out more."
msgstr ""
@@ -26096,7 +26629,7 @@ msgid "Page not found"
msgstr "Сторінку не знайдено"
msgid "Page settings"
-msgstr "ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ñторінки"
+msgstr "Параметри Ñторінки"
msgid "PagerDutySettings|Active"
msgstr ""
@@ -26356,6 +26889,9 @@ msgstr "Виклики Gitaly"
msgid "PerformanceBar|Memory"
msgstr ""
+msgid "PerformanceBar|Memory report"
+msgstr ""
+
msgid "PerformanceBar|Redis calls"
msgstr "Виклики Redis"
@@ -26389,18 +26925,12 @@ msgstr ""
msgid "PerformanceBar|wall"
msgstr ""
-msgid "Performs a rebase but skips triggering a new pipeline"
-msgstr ""
-
msgid "Period in seconds"
msgstr ""
msgid "Permalink"
msgstr ""
-msgid "Permanently delete project"
-msgstr ""
-
msgid "Permanently remove group"
msgstr ""
@@ -26671,6 +27201,51 @@ msgstr "Конвеєр: %{ciStatus}"
msgid "PipelineStatusTooltip|Pipeline: %{ci_status}"
msgstr "Конвеєр: %{ci_status}"
+msgid "PipelineWizardDefaultCommitMessage|Add %{filename}"
+msgstr ""
+
+msgid "PipelineWizardDefaultCommitMessage|Update %{filename}"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|At least one entry is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This field is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This value is not valid"
+msgstr ""
+
+msgid "PipelineWizardListWidget|add another step"
+msgstr ""
+
+msgid "PipelineWizardListWidget|remove step"
+msgstr ""
+
+msgid "PipelineWizard|Commit"
+msgstr ""
+
+msgid "PipelineWizard|Commit Message"
+msgstr ""
+
+msgid "PipelineWizard|Commit changes to your file"
+msgstr ""
+
+msgid "PipelineWizard|Commit file to Branch"
+msgstr ""
+
+msgid "PipelineWizard|Commit your new file"
+msgstr ""
+
+msgid "PipelineWizard|The file has been committed."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem committing the changes."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem while checking whether your file already exists in the specified branch."
+msgstr ""
+
msgid "Pipelines"
msgstr "Конвеєри"
@@ -26785,8 +27360,8 @@ msgstr "Редактор Конвеєрів"
msgid "Pipelines|Project cache successfully reset."
msgstr "Кеш проєкту уÑпішно очищено."
-msgid "Pipelines|Revoke"
-msgstr "Відкликати"
+msgid "Pipelines|Revoke trigger"
+msgstr ""
msgid "Pipelines|Something went wrong while cleaning runners cache."
msgstr "Помилка при очищенні кеша runner'ів."
@@ -26830,6 +27405,12 @@ msgstr ""
msgid "Pipelines|This is a child pipeline within the parent pipeline"
msgstr ""
+msgid "Pipelines|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipelines|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipelines|This pipeline will run code originating from a forked project merge request. This means that the code can potentially have security considerations like exposing CI variables."
msgstr ""
@@ -26872,9 +27453,6 @@ msgstr "ВізуалізаціÑ"
msgid "Pipelines|Your changes have been successfully committed. Now redirecting to the new merge request page."
msgstr ""
-msgid "Pipelines|detached"
-msgstr ""
-
msgid "Pipelines|error"
msgstr ""
@@ -26884,10 +27462,13 @@ msgstr ""
msgid "Pipelines|latest"
msgstr ""
-msgid "Pipelines|stuck"
+msgid "Pipelines|merge request"
+msgstr ""
+
+msgid "Pipelines|merge train"
msgstr ""
-msgid "Pipelines|train"
+msgid "Pipelines|stuck"
msgstr ""
msgid "Pipelines|yaml invalid"
@@ -27019,6 +27600,12 @@ msgstr ""
msgid "Pipeline|This change will not change the overall test coverage if merged."
msgstr ""
+msgid "Pipeline|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipeline|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipeline|Trigger author"
msgstr "Ðвтор тригера"
@@ -27043,6 +27630,12 @@ msgstr "Зараз ви зупинете конвеєр #%{pipelineId}."
msgid "Pipeline|for"
msgstr "ДлÑ"
+msgid "Pipeline|merge request"
+msgstr ""
+
+msgid "Pipeline|merge train"
+msgstr ""
+
msgid "Pipeline|on"
msgstr "в"
@@ -27074,7 +27667,7 @@ msgid "Plan:"
msgstr "План:"
msgid "Planning hierarchy"
-msgstr ""
+msgstr "Ð†Ñ”Ñ€Ð°Ñ€Ñ…Ñ–Ñ Ð¿Ð»Ð°Ð½ÑƒÐ²Ð°Ð½Ð½Ñ"
msgid "PlantUML"
msgstr "PlantUML"
@@ -27181,9 +27774,6 @@ msgstr "Будь лаÑка, введіть дійÑний номер"
msgid "Please enter a valid time interval"
msgstr ""
-msgid "Please enter or upload a valid license."
-msgstr ""
-
msgid "Please enter your current password."
msgstr ""
@@ -27292,9 +27882,6 @@ msgstr ""
msgid "Please type %{phrase_code} to proceed or close this modal to cancel."
msgstr "Будь лаÑка, введіть %{phrase_code} Ð´Ð»Ñ Ð¿Ñ€Ð¾Ð´Ð¾Ð²Ð¶ÐµÐ½Ð½Ñ Ð°Ð±Ð¾ закрийте це модальне вікно Ð´Ð»Ñ Ð²Ñ–Ð´Ð¼Ñ–Ð½Ð¸."
-msgid "Please type the following to confirm:"
-msgstr "Будь лаÑка, введіть наÑтупні дії Ð´Ð»Ñ Ð¿Ñ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¶ÐµÐ½Ð½Ñ:"
-
msgid "Please use this form to report to the admin users who create spam issues, comments or behave inappropriately."
msgstr "Будь лаÑка, викориÑтовуйте цю форму щоб повідомити адміну Ñкі кориÑтувачі Ñтворюють Ñпам (задачі або коментарі) або поводÑÑ‚ÑŒÑÑ Ð½ÐµÐ½Ð°Ð»ÐµÐ¶Ð½Ð¸Ð¼ чином."
@@ -27322,12 +27909,27 @@ msgstr ""
msgid "Policies"
msgstr "Політики"
+msgid "Policy '%{escalation_policy_name}' does not exist."
+msgstr ""
+
msgid "Policy management project does have any policies in %{policy_path}"
msgstr ""
msgid "Policy project doesn't exist"
msgstr ""
+msgid "PolicyRuleMultiSelect|%{firstLabel} +%{numberOfAdditionalLabels} more"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|All %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select all"
+msgstr ""
+
msgid "Polling interval multiplier"
msgstr ""
@@ -27350,7 +27952,7 @@ msgid "Pre-defined push rules."
msgstr ""
msgid "Preferences"
-msgstr "ÐалаштуваннÑ"
+msgstr "Параметри"
msgid "Preferences saved."
msgstr "ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð·Ð±ÐµÑ€ÐµÐ¶ÐµÐ½Ð¾."
@@ -27446,7 +28048,7 @@ msgid "Preferences|This setting allows you to customize the behavior of the syst
msgstr "Цей параметр дозволÑÑ” вам налаштувати поведінку ÑиÑтемного макету на Ñтандартних компонентів."
msgid "Preferences|Time preferences"
-msgstr "ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ñ‡Ð°Ñу"
+msgstr "Параметри чаÑу"
msgid "Preferences|Use relative times"
msgstr "ВикориÑтовувати відноÑний чаÑ"
@@ -27556,6 +28158,9 @@ msgstr ""
msgid "Private projects can be created in your personal namespace with:"
msgstr "Приватні проєкти можуть бути Ñтворені у вашому перÑональному проÑторі імен з:"
+msgid "Problem with %{name} command: %{message}."
+msgstr ""
+
msgid "Proceed"
msgstr "Продовжити"
@@ -27620,7 +28225,7 @@ msgid "Profile"
msgstr "Профіль"
msgid "Profile Settings"
-msgstr "ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ñ€Ð¾Ñ„Ñ–Ð»ÑŽ"
+msgstr "Параметри профілю"
msgid "Profile failed to delete"
msgstr ""
@@ -27923,7 +28528,7 @@ msgid "Profiles|This information will appear on your profile"
msgstr "Ð¦Ñ Ñ–Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ Ð±ÑƒÐ´Ðµ відображатиÑÑ Ñƒ вашому профілі"
msgid "Profiles|Time settings"
-msgstr "ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ñ‡Ð°Ñу"
+msgstr "Параметри чаÑу"
msgid "Profiles|Two-Factor Authentication"
msgstr "Двофакторна автентифікаціÑ"
@@ -28030,6 +28635,9 @@ msgstr "Мови програмуваннÑ, що викориÑтовуєтьÑ
msgid "Progress"
msgstr "ПрогреÑ"
+msgid "Progress tracking"
+msgstr ""
+
msgid "Project"
msgstr "Проєкт"
@@ -28261,6 +28869,9 @@ msgstr ""
msgid "ProjectQualitySummary|Failure"
msgstr ""
+msgid "ProjectQualitySummary|Get insight into the overall percentage of tests in your project that succeed, fail and are skipped."
+msgstr ""
+
msgid "ProjectQualitySummary|Latest pipeline results"
msgstr ""
@@ -28279,6 +28890,12 @@ msgstr ""
msgid "ProjectQualitySummary|See project Code Coverage Statistics"
msgstr ""
+msgid "ProjectQualitySummary|Set up test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|Set up test runs (opens in a new tab)"
+msgstr ""
+
msgid "ProjectQualitySummary|Skipped"
msgstr ""
@@ -28555,13 +29172,19 @@ msgstr "Задачі"
msgid "ProjectSettings|LFS objects from this repository are available to forks. %{linkStart}How do I remove them?%{linkEnd}"
msgstr ""
+msgid "ProjectSettings|Learn about commit history."
+msgstr ""
+
+msgid "ProjectSettings|Leave empty to use default template."
+msgstr ""
+
msgid "ProjectSettings|Manage who can see the project in the public access directory."
msgstr ""
msgid "ProjectSettings|Manages large files such as audio, video, and graphics files."
msgstr ""
-msgid "ProjectSettings|Maximum 500 characters."
+msgid "ProjectSettings|Maximum %{maxLength} characters."
msgstr ""
msgid "ProjectSettings|Merge checks"
@@ -28640,7 +29263,7 @@ msgid "ProjectSettings|Require an associated issue from Jira"
msgstr ""
msgid "ProjectSettings|Requirements"
-msgstr ""
+msgstr "Вимоги"
msgid "ProjectSettings|Requirements management system."
msgstr ""
@@ -28702,6 +29325,9 @@ msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
msgstr ""
+msgid "ProjectSettings|The default template will be applied on save."
+msgstr ""
+
msgid "ProjectSettings|These checks must pass before merge requests can be merged."
msgstr ""
@@ -28756,6 +29382,9 @@ msgstr ""
msgid "ProjectSettings|What are badges?"
msgstr ""
+msgid "ProjectSettings|What are merge trains?"
+msgstr ""
+
msgid "ProjectSettings|When merge request pipelines are enabled in the CI/CD configuration file, pipelines validate the combined results of the source and target branches. %{link_start}How to configure merge request pipelines?%{link_end}"
msgstr ""
@@ -28850,7 +29479,7 @@ msgid "ProjectTemplates|iOS (Swift)"
msgstr "iOS (Swift)"
msgid "ProjectView|Activity"
-msgstr ""
+msgstr "ÐктивніÑÑ‚ÑŒ"
msgid "ProjectView|Files and Readme (default)"
msgstr ""
@@ -28873,6 +29502,9 @@ msgstr "Проєкти оцінюютьÑÑ Ð·Ð° найвищим наÑвним
msgid "Projects are organized into groups"
msgstr ""
+msgid "Projects are where you store your code, access issues, wiki and other features of GitLab."
+msgstr ""
+
msgid "Projects contributed to"
msgstr ""
@@ -28888,12 +29520,6 @@ msgstr ""
msgid "Projects to index"
msgstr "Проєкти Ð´Ð»Ñ Ñ–Ð½Ð´ÐµÐºÑуваннÑ"
-msgid "Projects will be permanently deleted after a %{waiting_period}-day waiting period."
-msgstr ""
-
-msgid "Projects will be permanently deleted immediately."
-msgstr ""
-
msgid "Projects with critical vulnerabilities"
msgstr "Проєкти з критичними вразливоÑÑ‚Ñми"
@@ -28978,6 +29604,9 @@ msgstr "Імпорт"
msgid "ProjectsNew|Import project"
msgstr "Імпортувати проєкт"
+msgid "ProjectsNew|Include a Getting Started README"
+msgstr ""
+
msgid "ProjectsNew|Initialize repository with a README"
msgstr "Ініціалізувати репозиторій файлом інÑтрукції (README)"
@@ -28993,6 +29622,9 @@ msgstr ""
msgid "ProjectsNew|Project description %{tag_start}(optional)%{tag_end}"
msgstr "ÐžÐ¿Ð¸Ñ Ð¿Ñ€Ð¾Ñ”ÐºÑ‚Ñƒ %{tag_start}(необов’Ñзково)%{tag_end}"
+msgid "ProjectsNew|Recommended if you're new to GitLab"
+msgstr ""
+
msgid "ProjectsNew|Run CI/CD for external repository"
msgstr "ЗапуÑтити CI/CD Ð´Ð»Ñ Ð·Ð¾Ð²Ð½Ñ–ÑˆÐ½ÑŒÐ¾Ð³Ð¾ репозиторію"
@@ -29410,6 +30042,9 @@ msgstr "Увімкнути/вимкнути Ð·Ð°Ñ‚Ð²ÐµÑ€Ð´Ð¶ÐµÐ½Ð½Ñ Ð²Ð»Ð°ÑнÐ
msgid "ProtectedBranch|Unprotect"
msgstr ""
+msgid "ProtectedBranch|Unprotect branch"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
@@ -29437,6 +30072,9 @@ msgstr "ЗахиÑити Ñередовище"
msgid "ProtectedEnvironment|Protected Environment (%{protected_environments_count})"
msgstr "ЗахиÑтити Середовище (%{protected_environments_count})"
+msgid "ProtectedEnvironment|Required approvals"
+msgstr ""
+
msgid "ProtectedEnvironment|Select an environment"
msgstr "Виберіть Ñередовище"
@@ -29458,10 +30096,13 @@ msgstr "Ваше Ñередовище було захищено."
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr "ЗахиÑÑ‚ із вашого Ñередовища було знÑто"
+msgid "ProtectedTags|Unprotect tag"
+msgstr ""
+
msgid "ProtectedTags|default"
msgstr ""
-msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
+msgid "ProtectedTag|By default, protected tags restrict who can modify the tag."
msgstr ""
msgid "ProtectedTag|Learn more."
@@ -29524,6 +30165,9 @@ msgstr "Публічні конвеєри"
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Public projects are an easy way to allow everyone to have read-only access."
+msgstr ""
+
msgid "Publish to status page"
msgstr ""
@@ -29680,9 +30324,6 @@ msgstr "Загальна кількіÑÑ‚ÑŒ комітів: %{total_commits_coun
msgid "QualitySummary|Project quality"
msgstr ""
-msgid "Quarters"
-msgstr "Квартали"
-
msgid "Query"
msgstr "Запит"
@@ -29693,10 +30334,10 @@ msgid "Queued"
msgstr "У черзі"
msgid "Quick actions can be used in description and comment boxes."
-msgstr ""
+msgstr "Швидкі дії можна викориÑтовувати в опиÑах Ñ– коментарÑÑ…."
msgid "Quick help"
-msgstr ""
+msgstr "Швидка довідка"
msgid "Quick range"
msgstr "Швидкий діапазон"
@@ -29756,7 +30397,7 @@ msgid "Re-verification interval"
msgstr "Інтервал повторної перевірки"
msgid "Read documentation"
-msgstr ""
+msgstr "Прочитати документацію"
msgid "Read more"
msgstr "Докладніше"
@@ -29767,6 +30408,9 @@ msgstr ""
msgid "Read more about project permissions %{help_link_open}here%{help_link_close}"
msgstr ""
+msgid "Read more about related epics"
+msgstr ""
+
msgid "Read more about related issues"
msgstr "ДізнатиÑÑ Ð±Ñ–Ð»ÑŒÑˆÐµ про пов’Ñзані задачі"
@@ -29797,10 +30441,7 @@ msgstr ""
msgid "Rebase source branch on the target branch."
msgstr ""
-msgid "Rebase without CI"
-msgstr ""
-
-msgid "Rebases and triggers a pipeline"
+msgid "Rebase without pipeline"
msgstr ""
msgid "Recaptcha verified?"
@@ -29851,9 +30492,6 @@ msgstr ""
msgid "Reconfigure"
msgstr "Переналаштувати"
-msgid "Recovering projects"
-msgstr "Ð’Ñ–Ð´Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¾Ñ”ÐºÑ‚Ñ–Ð²"
-
msgid "Recovery Codes"
msgstr "Коди відновленнÑ"
@@ -29915,6 +30553,12 @@ msgstr "Повторна Ð³ÐµÐ½ÐµÑ€Ð°Ñ†Ñ–Ñ Ñ–Ð´ÐµÐ½Ñ‚Ð¸Ñ„Ñ–ÐºÐ°Ñ‚Ð¾Ñ€Ð° інÑÑ
msgid "Regex pattern"
msgstr "Шаблон у виглÑді регулÑрного виразу"
+msgid "Region"
+msgstr ""
+
+msgid "Regions"
+msgstr ""
+
msgid "Register"
msgstr "ЗареєÑтруватиÑÑ"
@@ -30147,9 +30791,6 @@ msgstr "Видалити уÑÑ– або певні мітки(-ку)"
msgid "Remove all or specific reviewer(s)"
msgstr ""
-msgid "Remove approver"
-msgstr ""
-
msgid "Remove approvers"
msgstr "Видалити затверджуючих оÑіб"
@@ -30165,6 +30806,9 @@ msgstr "Видалити виконавцÑ"
msgid "Remove attention request"
msgstr ""
+msgid "Remove attention request(s)"
+msgstr ""
+
msgid "Remove avatar"
msgstr "Видалити аватар"
@@ -30303,6 +30947,9 @@ msgstr "Видалено вÑÑ– мітки."
msgid "Removed an issue from an epic."
msgstr "Видалено задачу із епіка."
+msgid "Removed attention from %{users_sentence}."
+msgstr ""
+
msgid "Removed attention request from @%{username}"
msgstr ""
@@ -30354,6 +31001,9 @@ msgstr "ВидалÑÑ” вÑÑ– мітки."
msgid "Removes an issue from an epic."
msgstr "ВидалÑÑ” задачу із епіка."
+msgid "Removes attention from %{users_sentence}."
+msgstr ""
+
msgid "Removes parent epic %{epic_ref}."
msgstr "ВидалÑÑ” батьківÑький епік %{epic_ref}."
@@ -30421,10 +31071,10 @@ msgid "Replace"
msgstr "Замінити"
msgid "Replace %{blob_name}"
-msgstr ""
+msgstr "Замінити %{blob_name}"
msgid "Replace %{name}"
-msgstr ""
+msgstr "Замінити %{name}"
msgid "Replace all label(s)"
msgstr "Замінити вÑÑ– мітки(-ку)"
@@ -30465,6 +31115,9 @@ msgstr ""
msgid "Report abuse to admin"
msgstr "Повідомити адмініÑтратора про порушеннÑ"
+msgid "Report is generating and will be sent to your email address."
+msgstr ""
+
msgid "Reported %{timeAgo} by %{reportedBy}"
msgstr "Повідомлено %{timeAgo} кориÑтувачем %{reportedBy}"
@@ -30681,7 +31334,7 @@ msgid "Repository Graph"
msgstr "Граф репозиторію"
msgid "Repository Settings"
-msgstr "ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ñ€ÐµÐ¿Ð¾Ð·Ð¸Ñ‚Ð¾Ñ€Ñ–ÑŽ"
+msgstr "Параметри репозиторію"
msgid "Repository already read-only"
msgstr ""
@@ -30764,6 +31417,15 @@ msgstr ""
msgid "Request attention"
msgstr ""
+msgid "Request attention from %{users_sentence}."
+msgstr ""
+
+msgid "Request attention from assignee or reviewer"
+msgstr ""
+
+msgid "Request attention from assignee(s) or reviewer(s)"
+msgstr ""
+
msgid "Request attention to review"
msgstr ""
@@ -30788,6 +31450,9 @@ msgstr ""
msgid "Requested %{time_ago}"
msgstr "Відправлено запит %{time_ago}"
+msgid "Requested attention from %{users_sentence}."
+msgstr ""
+
msgid "Requested attention from @%{username}"
msgstr ""
@@ -30831,7 +31496,7 @@ msgid "Required only if you are not using role instance credentials."
msgstr ""
msgid "Requirement"
-msgstr ""
+msgstr "Вимога"
msgid "Requirement %{reference} has been added"
msgstr "Вимогу %{reference} було додано"
@@ -31006,6 +31671,9 @@ msgstr "Відновити групу"
msgid "Restore project"
msgstr "Відновити проєкт"
+msgid "Restoring projects"
+msgstr ""
+
msgid "Restoring the group will prevent the group, its subgroups and projects from being removed on this date."
msgstr ""
@@ -31036,6 +31704,9 @@ msgstr ""
msgid "Retry"
msgstr "Спробувати знову"
+msgid "Retry failed jobs"
+msgstr ""
+
msgid "Retry job"
msgstr "Повторити завданнÑ"
@@ -31085,9 +31756,6 @@ msgstr ""
msgid "Review changes"
msgstr "ПереглÑнути зміни"
-msgid "Review requested from %{name}"
-msgstr ""
-
msgid "Review requests for you"
msgstr "ПереглÑньте запити Ð´Ð»Ñ Ð²Ð°Ñ"
@@ -31254,6 +31922,9 @@ msgstr "Ðрхітектура"
msgid "Runners|Assigned Group"
msgstr ""
+msgid "Runners|Assigned Projects (%{projectCount})"
+msgstr ""
+
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -31273,7 +31944,7 @@ msgid "Runners|Command to register runner"
msgstr ""
msgid "Runners|Configuration"
-msgstr ""
+msgstr "КонфігураціÑ"
msgid "Runners|Copy instructions"
msgstr ""
@@ -31294,7 +31965,7 @@ msgid "Runners|Description"
msgstr "ОпиÑ"
msgid "Runners|Details"
-msgstr ""
+msgstr "Деталі"
msgid "Runners|Download and install binary"
msgstr "Завантажити та вÑтановити бінарний файл"
@@ -31323,6 +31994,9 @@ msgstr "Ð’Ñтановити runner"
msgid "Runners|Instance"
msgstr "ІнÑтанÑ"
+msgid "Runners|Jobs"
+msgstr ""
+
msgid "Runners|Last contact"
msgstr "ОÑтанній контакт"
@@ -31416,9 +32090,6 @@ msgstr ""
msgid "Runners|Runner %{name} was deleted"
msgstr ""
-msgid "Runners|Runner ID"
-msgstr ""
-
msgid "Runners|Runner assigned to project."
msgstr ""
@@ -31566,6 +32237,9 @@ msgstr ""
msgid "Runners|stale"
msgstr ""
+msgid "Runner|This runner has not run any jobs."
+msgstr ""
+
msgid "Running"
msgstr "ВиконуєтьÑÑ"
@@ -31680,6 +32354,24 @@ msgstr "ЗбереженнÑ"
msgid "Saving project."
msgstr "Ð—Ð±ÐµÑ€ÐµÐ¶ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¾Ñ”ÐºÑ‚Ñƒ."
+msgid "ScanResultPolicy|%{ifLabelStart}if%{ifLabelEnd} %{scanners} scan in an open merge request targeting the %{branches} branch(es) finds %{vulnerabilitiesAllowed} or more %{severities} vulnerabilities that are %{vulnerabilityStates}"
+msgstr ""
+
+msgid "ScanResultPolicy|%{thenLabelStart}Then%{thenLabelEnd} Require approval from %{approvalsRequired} of the following approvers: %{approvers}"
+msgstr ""
+
+msgid "ScanResultPolicy|add an approver"
+msgstr ""
+
+msgid "ScanResultPolicy|scanners"
+msgstr ""
+
+msgid "ScanResultPolicy|severity levels"
+msgstr ""
+
+msgid "ScanResultPolicy|vulnerability states"
+msgstr ""
+
msgid "Scanner"
msgstr "Сканер"
@@ -31812,6 +32504,9 @@ msgstr "Шукати групу"
msgid "Search for a user"
msgstr "Пошук кориÑтувача"
+msgid "Search for an emoji"
+msgstr ""
+
msgid "Search for projects, issues, etc."
msgstr "Пошук в проєктах, задачах і т. д."
@@ -32021,18 +32716,12 @@ msgstr "Секрет"
msgid "Secret Detection"
msgstr "ВиÑÐ²Ð»ÐµÐ½Ð½Ñ Ñекретів"
-msgid "Secret access key"
-msgstr ""
-
msgid "Secret token"
msgstr "Секретний токен"
msgid "Secure token that identifies an external storage request."
msgstr ""
-msgid "SecureCodeWarrior"
-msgstr ""
-
msgid "Security"
msgstr "Безпека"
@@ -32057,9 +32746,6 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "Security training with guide and learning pathways."
-msgstr ""
-
msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
@@ -32162,7 +32848,7 @@ msgstr ""
msgid "SecurityConfiguration|Manage corpus"
msgstr ""
-msgid "SecurityConfiguration|Manage corpus files used as mutation sources in coverage fuzzing."
+msgid "SecurityConfiguration|Manage corpus files used as seed inputs with coverage-guided fuzzing."
msgstr ""
msgid "SecurityConfiguration|Manage profiles for use by DAST scans."
@@ -32228,15 +32914,15 @@ msgstr ""
msgid "SecurityOrchestration|.yaml preview"
msgstr ""
-msgid "SecurityOrchestration|Action"
-msgstr ""
-
msgid "SecurityOrchestration|Actions"
msgstr "Дії"
msgid "SecurityOrchestration|Add rule"
msgstr "Додати правило"
+msgid "SecurityOrchestration|After dismissing the alert, the information will never be shown again."
+msgstr ""
+
msgid "SecurityOrchestration|All policies"
msgstr ""
@@ -32252,7 +32938,7 @@ msgstr ""
msgid "SecurityOrchestration|Description"
msgstr ""
-msgid "SecurityOrchestration|Disabled"
+msgid "SecurityOrchestration|Don't show the alert anymore"
msgstr ""
msgid "SecurityOrchestration|Edit policy"
@@ -32261,13 +32947,13 @@ msgstr ""
msgid "SecurityOrchestration|Edit policy project"
msgstr ""
-msgid "SecurityOrchestration|Enabled"
+msgid "SecurityOrchestration|Empty policy name"
msgstr ""
-msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Enabled"
msgstr ""
-msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
msgstr ""
msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
@@ -32276,7 +32962,7 @@ msgstr ""
msgid "SecurityOrchestration|Invalid policy type"
msgstr ""
-msgid "SecurityOrchestration|Latest scan"
+msgid "SecurityOrchestration|Latest scan run against %{agent}"
msgstr ""
msgid "SecurityOrchestration|Network"
@@ -32285,15 +32971,27 @@ msgstr "Мережа"
msgid "SecurityOrchestration|New policy"
msgstr "Ðова політика"
+msgid "SecurityOrchestration|No actions defined - policy will not run."
+msgstr ""
+
+msgid "SecurityOrchestration|No description"
+msgstr ""
+
msgid "SecurityOrchestration|No rules defined - policy will not run."
msgstr ""
+msgid "SecurityOrchestration|Not enabled"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
msgid "SecurityOrchestration|Policies"
msgstr "Політики"
+msgid "SecurityOrchestration|Policy Type"
+msgstr ""
+
msgid "SecurityOrchestration|Policy cannot be enabled for non-existing branches (%{branches})"
msgstr ""
@@ -32318,12 +33016,15 @@ msgstr ""
msgid "SecurityOrchestration|Require %{approvals} %{plural} from %{approvers} if any of the following occur:"
msgstr ""
-msgid "SecurityOrchestration|Rule"
-msgstr ""
-
msgid "SecurityOrchestration|Rules"
msgstr "Правила"
+msgid "SecurityOrchestration|Runs %{actions} and %{lastAction} scans"
+msgstr ""
+
+msgid "SecurityOrchestration|Runs a %{action} scan"
+msgstr ""
+
msgid "SecurityOrchestration|Scan Execution"
msgstr ""
@@ -32381,6 +33082,9 @@ msgstr ""
msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
+msgid "SecurityOrchestration|This view only shows scan results for the agent %{agent}. You can view scan results for all agents in the %{linkStart}Operational Vulnerabilities tab of the vulnerability report%{linkEnd}."
+msgstr ""
+
msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
@@ -32435,9 +33139,6 @@ msgstr ""
msgid "SecurityOrchestration|users with ids"
msgstr ""
-msgid "SecurityOrchestration|view results"
-msgstr ""
-
msgid "SecurityOrchestration|vulnerabilities"
msgstr ""
@@ -32499,7 +33200,7 @@ msgid "SecurityReports|Create issue"
msgstr "Створити задачу"
msgid "SecurityReports|Create policy"
-msgstr ""
+msgstr "Створити політику"
msgid "SecurityReports|Development vulnerabilities"
msgstr ""
@@ -32550,7 +33251,7 @@ msgid "SecurityReports|Issues created from a vulnerability cannot be removed."
msgstr ""
msgid "SecurityReports|Learn more about setting up your dashboard"
-msgstr ""
+msgstr "ДізнайтеÑÑ Ð±Ñ–Ð»ÑŒÑˆÐµ про Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð²Ð°ÑˆÐ¾Ñ— панелі керуваннÑ"
msgid "SecurityReports|Manage and track vulnerabilities identified in projects within your group. Vulnerabilities in projects are shown here when security testing is configured."
msgstr ""
@@ -32946,7 +33647,7 @@ msgid "Selected levels cannot be used by non-admin users for groups, projects or
msgstr "Вибрані рівні не можуть викориÑтовуватиÑÑ Ð½ÐµÐ°Ð´Ð¼Ñ–Ð½Ñ–Ñтраторами Ð´Ð»Ñ Ð³Ñ€ÑƒÐ¿, проєктів або Ñніпетів. Якщо публічний рівень обмежений, профілі кориÑтувачів відображаютьÑÑ Ð»Ð¸ÑˆÐµ Ð´Ð»Ñ Ð·Ð°Ñ€ÐµÑ”Ñтрованих кориÑтувачів."
msgid "Selected projects"
-msgstr ""
+msgstr "Вибрані проєкти"
msgid "Selecting a GitLab user will add a link to the GitLab user in the descriptions of issues and comments (e.g. \"By %{link_open}@johnsmith%{link_close}\"). It will also associate and/or assign these issues and comments with the selected user."
msgstr ""
@@ -33107,22 +33808,19 @@ msgstr "Скопіювати URL"
msgid "Serverless|Getting started with serverless"
msgstr "Початок роботи із serverless"
-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|In order to start using functions as a service, you must first install Knative on your Kubernetes cluster. %{linkStart}More information%{linkEnd}"
-msgstr ""
-
msgid "Serverless|Learn more about Serverless"
msgstr "ДізнайтеÑÑ Ð±Ñ–Ð»ÑŒÑˆÐµ про Serverless"
msgid "Serverless|No functions available"
msgstr "Ðемає доÑтупних функцій"
-msgid "Serverless|Sign up for First Look"
+msgid "Serverless|Serverless was %{linkStart}deprecated%{linkEnd} in GitLab 14.3."
+msgstr ""
+
+msgid "Serverless|Serverless was %{postLinkStart}deprecated%{postLinkEnd}. But if you opt to use it, you must install Knative in your Kubernetes cluster first. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "Serverless|The deploy job has not finished."
@@ -33134,9 +33832,6 @@ msgstr "Функції, Ñкі вказані у файлі %{startTag}serverles
msgid "Serverless|There is currently no function data available from Knative. This could be for a variety of reasons including:"
msgstr "Ðаразі немає даних про функції від Knative. Це може бути викликано різними причинами, зокрема:"
-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 "Ваш файл %{startTag}.gitlab-ci.yml%{endTag} не Ñконфігурований правильно."
@@ -33152,9 +33847,6 @@ msgstr ""
msgid "Service Account Key"
msgstr ""
-msgid "Service Accounts"
-msgstr ""
-
msgid "Service Accounts keys authorize GitLab to deploy your Google Cloud project"
msgstr ""
@@ -33164,10 +33856,10 @@ msgstr "Service Desk"
msgid "Service Desk allows people to create issues in your GitLab instance without their own user account. It provides a unique email address for end users to create issues in a project. Replies can be sent either through the GitLab interface or by email. End users only see threads through email."
msgstr ""
-msgid "Service Usage Data"
+msgid "Service account generated successfully"
msgstr ""
-msgid "Service account generated successfully"
+msgid "Service accounts"
msgstr ""
msgid "Service ping is disabled in your configuration file, and cannot be enabled through this form."
@@ -33311,6 +34003,9 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr "Ð’Ñтановити етап %{milestone_reference}."
+msgid "Set the per-user rate limit for getting a user by ID via the API."
+msgstr ""
+
msgid "Set the per-user rate limit for notes created by web or API requests."
msgstr ""
@@ -33324,7 +34019,7 @@ msgid "Set time estimate to %{time_estimate}."
msgstr "Ð’Ñтановити запланований Ñ‡Ð°Ñ %{time_estimate}."
msgid "Set up CI/CD"
-msgstr "ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ CI/CD"
+msgstr "Параметри CI/CD"
msgid "Set up Jira Integration"
msgstr ""
@@ -33442,13 +34137,13 @@ msgstr[2] ""
msgstr[3] ""
msgid "Settings"
-msgstr "ÐалаштуваннÑ"
+msgstr "Параметри"
msgid "Settings|Unable to load the merge request options settings. Try reloading the page."
msgstr ""
msgid "Setup"
-msgstr "ÐалаштуваннÑ"
+msgstr "Параметри"
msgid "Severity"
msgstr "СерйозніÑÑ‚ÑŒ"
@@ -33492,6 +34187,9 @@ msgstr ""
msgid "Shared runners details"
msgstr ""
+msgid "Shared runners enabled cannot be enabled until a valid credit card is on file"
+msgstr ""
+
msgid "Shared runners help link"
msgstr "Допомога по загальним runner'ам"
@@ -33549,6 +34247,9 @@ msgstr ""
msgid "Show all issues."
msgstr ""
+msgid "Show all milestones"
+msgstr ""
+
msgid "Show all test cases."
msgstr ""
@@ -33585,6 +34286,9 @@ msgstr "Показати файловий менеджер"
msgid "Show file contents"
msgstr "Показати вміÑÑ‚ файлу"
+msgid "Show group milestones"
+msgstr ""
+
msgid "Show labels"
msgstr ""
@@ -33600,6 +34304,12 @@ msgstr ""
msgid "Show open epics"
msgstr ""
+msgid "Show project milestones"
+msgstr ""
+
+msgid "Show sub-group milestones"
+msgstr ""
+
msgid "Show the Closed list"
msgstr ""
@@ -33609,13 +34319,6 @@ msgstr ""
msgid "Show whitespace changes"
msgstr "Показати зміни пробілів"
-msgid "Showing %d event"
-msgid_plural "Showing %d events"
-msgstr[0] "Показано %d подію"
-msgstr[1] "Показано %d події"
-msgstr[2] "Показано %d подій"
-msgstr[3] "Показано %d подій"
-
msgid "Showing %{conflict} between %{sourceBranch} and %{targetBranch}"
msgstr ""
@@ -33654,10 +34357,10 @@ msgid "Showing last %{size} of log -"
msgstr "ПоказуютьÑÑ Ð¾Ñтанні %{size} журналу -"
msgid "Showing latest version"
-msgstr ""
+msgstr "Показано оÑтанню верÑÑ–ÑŽ"
msgid "Showing version #%{versionNumber}"
-msgstr ""
+msgstr "Показана верÑÑ–Ñ #%{versionNumber}"
msgid "Side-by-side"
msgstr "Поруч"
@@ -33672,17 +34375,11 @@ msgid "Sidebar|Health status"
msgstr "Стан працездатноÑÑ‚Ñ–"
msgid "Sidebar|No status"
-msgstr ""
+msgstr "Ðемає ÑтатуÑу"
msgid "Sidebar|None"
msgstr "Ðемає"
-msgid "Sidebar|Only numeral characters allowed"
-msgstr "Дозволені лише цифри"
-
-msgid "Sidebar|Weight"
-msgstr "Вага"
-
msgid "Sidekiq job compression threshold (bytes)"
msgstr ""
@@ -33845,6 +34542,9 @@ msgstr "Slack Ñ–Ð½Ñ‚ÐµÐ³Ñ€Ð°Ñ†Ñ–Ñ Ð´Ð¾Ð·Ð²Ð¾Ð»Ð¸Ñ‚ÑŒ вам взаємодіÑÑ
msgid "Slack logo"
msgstr ""
+msgid "SlackIntegration|Are you sure you want to remove this project from the Slack application?"
+msgstr ""
+
msgid "SlackIntegration|GitLab for Slack"
msgstr ""
@@ -33854,6 +34554,9 @@ msgstr ""
msgid "SlackIntegration|Project alias"
msgstr ""
+msgid "SlackIntegration|Remove project"
+msgstr ""
+
msgid "SlackIntegration|Select a GitLab project to link with your Slack workspace."
msgstr ""
@@ -33998,9 +34701,6 @@ msgstr "ЩоÑÑŒ пішло не так, при Ñпробі зміни Ñтан
msgid "Something went wrong trying to load issue contacts."
msgstr ""
-msgid "Something went wrong when creating a work item. Please try again"
-msgstr ""
-
msgid "Something went wrong when reordering designs. Please try again"
msgstr ""
@@ -34094,9 +34794,6 @@ msgstr ""
msgid "Something went wrong while inserting your image. Please try again."
msgstr ""
-msgid "Something went wrong while merging this merge request. Please try again."
-msgstr "Помилка при заÑтоÑуванні цього запиту на злиттÑ. Будь лаÑка, Ñпробуйте знову."
-
msgid "Something went wrong while obtaining the Let's Encrypt certificate."
msgstr ""
@@ -34416,13 +35113,13 @@ msgid "SourcegraphAdmin|Enable Sourcegraph"
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 "Увімкнути аналізатор коду %{link_start}Sourcegraph%{link_end} у вікнах коду та запитах на Ð·Ð»Ð¸Ñ‚Ñ‚Ñ Ñƒ вашому екземплÑрі Gitlab."
+msgstr "Увімкнути аналізатор коду %{link_start}Sourcegraph%{link_end} у вікнах коду та запитах на Ð·Ð»Ð¸Ñ‚Ñ‚Ñ Ñƒ вашому інÑтанÑÑ– Gitlab."
-msgid "SourcegraphAdmin|If checked, only public projects will have code intelligence and communicate with Sourcegraph."
-msgstr "Якщо вибрано, то лише публічні проєкти будуть мати аналізатор коду та ÑпілкуватиÑÑ Ñ–Ð· Sourcegraph."
+msgid "SourcegraphAdmin|Learn more."
+msgstr ""
-msgid "SourcegraphAdmin|More information"
-msgstr "Детальніше"
+msgid "SourcegraphAdmin|Only public projects have code intelligence enabled and communicate with Sourcegraph."
+msgstr ""
msgid "SourcegraphAdmin|Save changes"
msgstr "Зберегти зміни"
@@ -34430,8 +35127,8 @@ msgstr "Зберегти зміни"
msgid "SourcegraphAdmin|Sourcegraph URL"
msgstr "URL-адреÑа Sourcegraph"
-msgid "SourcegraphAdmin|e.g. https://sourcegraph.example.com"
-msgstr "напр. https://sourcegraph.example.com"
+msgid "SourcegraphAdmin|https://sourcegraph.example.com"
+msgstr ""
msgid "SourcegraphPreferences|This feature is experimental and currently limited to certain projects."
msgstr "Ð¦Ñ Ñ„ÑƒÐ½Ñ†Ñ–Ñ Ñ” екÑпериментальною Ñ– наразі доÑтупна тільки Ð´Ð»Ñ Ð¿ÐµÐ²Ð½Ð¸Ñ… проєктів."
@@ -34565,6 +35262,9 @@ msgstr "Почати очищеннÑ"
msgid "Start date"
msgstr "Дата початку"
+msgid "Start free trial"
+msgstr ""
+
msgid "Start merge train"
msgstr "Створити ланцюжок змін"
@@ -34595,6 +35295,9 @@ msgstr "Запущено %{startsIn}"
msgid "Started asynchronous removal of all repository check states."
msgstr "ÐÑинхронне Ð²Ð¸Ð´Ð°Ð»ÐµÐ½Ð½Ñ ÑƒÑÑ–Ñ… Ñтанів перевірок репозиторіїв запущено."
+msgid "Started escalation for this incident."
+msgstr ""
+
msgid "Starting..."
msgstr "ЗапуÑк..."
@@ -34607,6 +35310,9 @@ msgstr "Буде запущено %{startsIn}"
msgid "Starts at (UTC)"
msgstr "ПочинаєтьÑÑ Ð¾ (за Грінвічем)"
+msgid "Starts escalations for this incident"
+msgstr ""
+
msgid "Starts on"
msgstr ""
@@ -34656,7 +35362,7 @@ msgid "StaticSiteEditor|Could not create merge request."
msgstr ""
msgid "StaticSiteEditor|Creating your merge request"
-msgstr ""
+msgstr "Ð¡Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð²Ð°ÑˆÐ¾Ð³Ð¾ запиту на злиттÑ"
msgid "StaticSiteEditor|Incompatible file content"
msgstr ""
@@ -34868,6 +35574,9 @@ msgstr "Ðевідомо"
msgid "Strikethrough"
msgstr ""
+msgid "Strikethrough text"
+msgstr ""
+
msgid "Subgroup information"
msgstr "Ð†Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ñ–Ñ Ð¿Ñ€Ð¾ підгрупу"
@@ -35102,6 +35811,21 @@ msgstr "Облік викориÑÑ‚Ð°Ð½Ð½Ñ Ð²Ð¸ÐºÐ¾Ð½ÑƒÑ”Ñ‚ÑŒÑÑ Ð¾Ð´Ð¸Ð½ ра
msgid "Subscriptions"
msgstr "ПідпиÑки"
+msgid "Subscriptions|Chat with sales"
+msgstr ""
+
+msgid "Subscriptions|Close"
+msgstr ""
+
+msgid "Subscriptions|Not ready to buy yet?"
+msgstr ""
+
+msgid "Subscriptions|Start a free trial"
+msgstr ""
+
+msgid "Subscriptions|We understand. Maybe you have some questions for our sales team, or maybe you'd like to try some of the paid features first. What would you like to do?"
+msgstr ""
+
msgid "Subscription|Your subscription for %{strong}%{namespace_name}%{strong_close} has expired and you are now on %{pricing_link_start}the GitLab Free tier%{pricing_link_end}. Don't worry, your data is safe. Get in touch with our support team (%{support_email}). They'll gladly help with your subscription renewal."
msgstr ""
@@ -35312,6 +36036,9 @@ msgstr ""
msgid "SuperSonics|Maximum users"
msgstr ""
+msgid "SuperSonics|Offline cloud"
+msgstr ""
+
msgid "SuperSonics|Paste your activation code"
msgstr ""
@@ -35378,6 +36105,12 @@ msgstr ""
msgid "SuperSonics|You do not have an active subscription"
msgstr ""
+msgid "SuperSonics|You have a future dated license"
+msgstr ""
+
+msgid "SuperSonics|You have added a license that activates on %{date}. Please see the subscription history table below for more details."
+msgstr ""
+
msgid "SuperSonics|You have successfully added a license that activates on %{date}. Please see the subscription history table below for more details."
msgstr ""
@@ -35537,6 +36270,9 @@ msgstr "Ðазва тегу"
msgid "Tag name is required"
msgstr "Ðеобхідно вказати назву тегу"
+msgid "Tag push"
+msgstr ""
+
msgid "Tag push events"
msgstr ""
@@ -35639,6 +36375,9 @@ msgstr "Створити Ð¾Ð¿Ð¸Ñ Ñ€ÐµÐ»Ñ–Ð·Ñƒ або перетÑгніть Ñ„Ð
msgid "TagsPage|protected"
msgstr "захищений"
+msgid "Take a look at the documentation to discover all of GitLab’s capabilities."
+msgstr ""
+
msgid "Target Branch"
msgstr "Цільова гілка"
@@ -35652,10 +36391,10 @@ msgid "Target-Branch"
msgstr "Цільова гілка"
msgid "Task"
-msgstr ""
+msgstr "ЗавданнÑ"
msgid "Task ID: %{elastic_task}"
-msgstr ""
+msgstr "Ідентифікатор завданнÑ: %{elastic_task}"
msgid "TasksToBeDone|Create/import code into a project (repository)"
msgstr ""
@@ -35742,7 +36481,7 @@ msgid "TerraformBanner|Using Terraform? Try the GitLab Managed Terraform State"
msgstr ""
msgid "Terraform|%{name} successfully removed"
-msgstr ""
+msgstr "%{name} уÑпішно видалено"
msgid "Terraform|%{number} Terraform report failed to generate"
msgid_plural "Terraform|%{number} Terraform reports failed to generate"
@@ -35773,7 +36512,7 @@ msgstr[2] ""
msgstr[3] ""
msgid "Terraform|%{user} updated %{timeAgo}"
-msgstr ""
+msgstr "%{user} оновлено %{timeAgo}"
msgid "Terraform|A Terraform report failed to generate."
msgstr ""
@@ -35791,7 +36530,7 @@ msgid "Terraform|Actions"
msgstr "Дії"
msgid "Terraform|An error occurred while changing the state file"
-msgstr ""
+msgstr "СталаÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ° під Ñ‡Ð°Ñ Ð·Ð¼Ñ–Ð½Ð¸ файлу Ñтану"
msgid "Terraform|An error occurred while loading your Terraform States"
msgstr ""
@@ -35803,7 +36542,7 @@ msgid "Terraform|Cancel"
msgstr "СкаÑувати"
msgid "Terraform|Copy Terraform init command"
-msgstr ""
+msgstr "Копіювати команду Terraform init"
msgid "Terraform|Details"
msgstr "Деталі"
@@ -35836,7 +36575,7 @@ msgid "Terraform|Locked"
msgstr "Заблоковано"
msgid "Terraform|Locked by %{user} %{timeAgo}"
-msgstr ""
+msgstr "Заблоковано %{user} %{timeAgo}"
msgid "Terraform|Locking state"
msgstr "Стан блокуваннÑ"
@@ -35863,7 +36602,7 @@ msgid "Terraform|States"
msgstr "Стан"
msgid "Terraform|Terraform init command"
-msgstr ""
+msgstr "Команда Terraform init"
msgid "Terraform|Terraform reports"
msgstr ""
@@ -35884,7 +36623,7 @@ msgid "Terraform|To get access to this terraform state from your local computer,
msgstr ""
msgid "Terraform|To remove the State file and its versions, type %{name} to confirm:"
-msgstr ""
+msgstr "Щоб видалити файл Ñтану та його верÑÑ–Ñ—, введіть %{name} Ð´Ð»Ñ Ð¿Ñ–Ð´Ñ‚Ð²ÐµÑ€Ð´Ð¶ÐµÐ½Ð½Ñ:"
msgid "Terraform|Unknown User"
msgstr "Ðевідомий кориÑтувач"
@@ -35899,7 +36638,7 @@ msgid "Terraform|You are about to remove the state file %{name}. This will perma
msgstr ""
msgid "Terraform|You cannot remove the State file because it's locked. Unlock the State file first before removing it."
-msgstr ""
+msgstr "Ви не можете видалити файл Ñтану, тому що він заблокований. Перш ніж видалÑти його, розблокуйте файл Ñтану."
msgid "Test"
msgstr "ТеÑÑ‚"
@@ -36053,11 +36792,14 @@ msgstr ""
msgid "Tests"
msgstr "ТеÑти"
+msgid "Text (optional)"
+msgstr ""
+
msgid "Text added to the body of all email messages. %{character_limit} character limit"
msgstr ""
msgid "Text style"
-msgstr ""
+msgstr "Стиль текÑту"
msgid "Thank you for your business."
msgstr ""
@@ -36105,6 +36847,9 @@ msgstr ""
msgid "The CSV export will be created in the background. Once finished, it will be sent to %{email} in an attachment."
msgstr ""
+msgid "The CSV export you requested of all user memberships is attached to this email."
+msgstr ""
+
msgid "The GitLab subscription service (customers.gitlab.com) is currently experiencing an outage. You can monitor the status and get updates at %{linkStart}status.gitlab.com%{linkEnd}."
msgstr ""
@@ -36180,6 +36925,9 @@ msgstr "ВміÑÑ‚ цієї Ñторінки не закодований в UTF-
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 epic"
+msgstr ""
+
msgid "The current issue"
msgstr "Поточна задача"
@@ -36343,6 +37091,9 @@ msgstr ""
msgid "The latest pipeline for this merge request has failed."
msgstr ""
+msgid "The license key is invalid."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr "Ваш ліцензійний ключ недійÑний. ПереконайтеÑÑ, що він збігаєтьÑÑ Ð· тим, що ви отримали від GitLab Inc."
@@ -36358,6 +37109,9 @@ msgstr "Ліцензію уÑпішно завантажено Ñ– вона акÑ
msgid "The license was successfully uploaded and will be active from %{starts_at}. You can see the details below."
msgstr ""
+msgid "The license you uploaded is invalid. If the issue persists, contact support at %{link}."
+msgstr ""
+
msgid "The list creation wizard is already open"
msgstr ""
@@ -36979,10 +37733,13 @@ msgstr "Ð¦Ñ Ð´Ñ–Ñ Ð¼Ð¾Ð¶Ðµ призвеÑти до втрати даних. Щ
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} and everything this project contains. %{strongOpen}There is no going back%{strongClose}"
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}on %{date}%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains."
+msgstr ""
+
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains. %{strongOpen}There is no going back.%{strongClose}"
msgstr ""
msgid "This action will %{strongOpen}permanently remove%{strongClose} %{codeOpen}%{group}%{codeClose} %{strongOpen}immediately%{strongClose}."
@@ -37061,7 +37818,7 @@ msgid "This content could not be displayed because it is stored in LFS. You can
msgstr ""
msgid "This credential has expired"
-msgstr ""
+msgstr "Термін дії цих облікових даних закінчивÑÑ"
msgid "This device has already been registered with us."
msgstr "Цей приÑтрій уже зареєÑтровано на нашій Ñтороні."
@@ -37111,9 +37868,6 @@ msgstr "Це поле Ñ” обов'Ñзковим."
msgid "This file was modified for readability, and can't accept suggestions. Edit it directly."
msgstr ""
-msgid "This forked project has the following:"
-msgstr ""
-
msgid "This form is disabled in preview"
msgstr ""
@@ -37126,7 +37880,7 @@ msgstr ""
msgid "This group can't be removed because it is linked to a subscription. To remove this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
-msgid "This group can't be transfered because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
+msgid "This group can't be transferred because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
msgid "This group cannot be invited to a project inside a group with enforced SSO"
@@ -37153,6 +37907,9 @@ 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 incident is already escalated with '%{escalation_policy_name}'."
+msgstr ""
+
msgid "This invitation was sent to %{mail_to_invite_email}, but you are signed in as %{link_to_current_user} with email %{mail_to_current_user}."
msgstr ""
@@ -37171,9 +37928,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 merge train pipeline"
-msgstr ""
-
msgid "This is a private email address %{helpIcon} generated just for you. Anyone who has it can create issues or merge requests as if they were you. If that happens, %{resetLinkStart}reset this token%{resetLinkEnd}."
msgstr ""
@@ -37195,6 +37949,12 @@ msgstr ""
msgid "This is your current session"
msgstr "Це ваш поточний ÑеанÑ"
+msgid "This issue cannot be assigned to a confidential epic because it is public."
+msgstr ""
+
+msgid "This issue cannot be made public because it belongs to a confidential epic."
+msgstr ""
+
msgid "This issue is confidential and should only be visible to team members with at least Reporter access."
msgstr ""
@@ -37312,6 +38072,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 branch is protected from force push."
+msgstr ""
+
msgid "This merge request cannot be rebased while there are conflicts."
msgstr ""
@@ -37363,9 +38126,15 @@ msgstr "Цей конвеєр викориÑтовує попередньо ви
msgid "This pipeline was triggered by a schedule."
msgstr "Цей конвеєр був ініційований розкладом."
+msgid "This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project"
msgstr "Цей проєкт"
+msgid "This project can be restored until %{date}."
+msgstr ""
+
msgid "This project cannot be %{visibilityLevel} because the visibility of %{openShowLink}%{name}%{closeShowLink} is %{visibility}. To make this project %{visibilityLevel}, you must first %{openEditLink}change the visibility%{closeEditLink} of the parent group."
msgstr ""
@@ -37384,6 +38153,9 @@ msgstr ""
msgid "This project is %{strongStart}NOT%{strongEnd} a fork, and has the following:"
msgstr ""
+msgid "This project is %{strongStart}NOT%{strongEnd} a fork. This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr "Цей проєкт заархівовано і його не можна коментувати."
@@ -37541,7 +38313,7 @@ msgid "ThreatMonitoring|Incident"
msgstr ""
msgid "ThreatMonitoring|Name"
-msgstr ""
+msgstr "Ðазва"
msgid "ThreatMonitoring|No alerts available to display. See %{linkStart}enabling threat alerts%{linkEnd} for more information on adding alerts to the list."
msgstr ""
@@ -38079,6 +38851,9 @@ msgstr "ÐÐ°Ð³Ð°Ð´ÑƒÐ²Ð°Ð½Ð½Ñ ÑƒÑпішно позначене Ñк викон
msgid "Today"
msgstr "Сьогодні"
+msgid "Todos count"
+msgstr ""
+
msgid "Todos|Are you looking for things to do? Take a look at %{strongStart}%{openIssuesLinkStart}open issues%{openIssuesLinkEnd}%{strongEnd}, contribute to %{strongStart}%{mergeRequestLinkStart}a merge request%{mergeRequestLinkEnd}%{mergeRequestLinkEnd}%{strongEnd}, or mention someone in a comment to automatically assign them a new to-do item."
msgstr ""
@@ -38352,12 +39127,8 @@ msgstr "У виглÑді дерева"
msgid "Trending"
msgstr "ПопулÑрні"
-msgid "Trials|%{planName} Trial %{enDash} %{num} day left"
-msgid_plural "Trials|%{planName} Trial %{enDash} %{num} days left"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-msgstr[3] ""
+msgid "Trials|%{planName} Trial"
+msgstr ""
msgid "Trials|Compare all plans"
msgstr "ПорівнÑти вÑÑ– плани"
@@ -38365,6 +39136,9 @@ msgstr "ПорівнÑти вÑÑ– плани"
msgid "Trials|Create a new group to start your GitLab Ultimate trial."
msgstr ""
+msgid "Trials|Day %{daysUsed}/%{duration}"
+msgstr ""
+
msgid "Trials|Go back to GitLab"
msgstr "ПовернутиÑÑ Ð´Ð¾ GitLab"
@@ -38393,7 +39167,7 @@ msgid "Trial|Allowed characters: +, 0-9, -, and spaces."
msgstr ""
msgid "Trial|Company name"
-msgstr ""
+msgstr "Ðазва компанії"
msgid "Trial|Continue"
msgstr ""
@@ -38614,7 +39388,7 @@ msgstr ""
msgid "URL is triggered when repository is updated"
msgstr ""
-msgid "URL must be percent-encoded if neccessary."
+msgid "URL must be percent-encoded if necessary."
msgstr ""
msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
@@ -38833,6 +39607,9 @@ msgstr "Розблокувати"
msgid "Unlock account"
msgstr ""
+msgid "Unlock more features with GitLab Ultimate"
+msgstr ""
+
msgid "Unlock the discussion"
msgstr "Розблокувати обговореннÑ"
@@ -38896,6 +39673,9 @@ msgstr "ВідпиÑано від %{quick_action_target}."
msgid "Unsubscribes from this %{quick_action_target}."
msgstr "ВідпиÑує від %{quick_action_target}."
+msgid "Unsupported sort value."
+msgstr ""
+
msgid "Unsupported todo type passed. Supported todo types are: %{todo_types}"
msgstr ""
@@ -39002,7 +39782,7 @@ msgid "Updated %{updated_at} by %{updated_by}"
msgstr "Оновлено %{updated_at} %{updated_by}"
msgid "Updated date"
-msgstr ""
+msgstr "Дата оновленнÑ"
msgid "Updates"
msgstr "ОновленнÑ"
@@ -39026,7 +39806,7 @@ msgid "Upload"
msgstr ""
msgid "Upload %{file_name} file"
-msgstr ""
+msgstr "Завантажити %{file_name} файл"
msgid "Upload CSV file"
msgstr "Завантажити CSV файл"
@@ -39124,6 +39904,9 @@ msgstr "ВикориÑÑ‚Ð°Ð½Ð½Ñ Ð·Ð° поточний період"
msgid "UsageQuota|File attachments and smaller design graphics."
msgstr ""
+msgid "UsageQuota|From %{storage_enforcement_date} storage limits will apply to this namespace. View and manage your usage in %{strong_start}Group Settings &gt; Usage quotas%{strong_end}."
+msgstr ""
+
msgid "UsageQuota|Git repository."
msgstr ""
@@ -39184,6 +39967,9 @@ msgstr "Сховище"
msgid "UsageQuota|Storage type"
msgstr ""
+msgid "UsageQuota|Storage used"
+msgstr ""
+
msgid "UsageQuota|This is the total amount of storage used across your projects within this namespace."
msgstr ""
@@ -39379,6 +40165,12 @@ msgstr "ВикориÑтовувати хешоване Ñховище"
msgid "Use hashed storage paths for newly created and renamed repositories. Always enabled since 13.0."
msgstr ""
+msgid "Use issue count"
+msgstr ""
+
+msgid "Use issue weight"
+msgstr ""
+
msgid "Use one line per URI"
msgstr "ВикориÑтовуйте один Ñ€Ñдок Ð´Ð»Ñ ÐºÐ¾Ð¶Ð½Ð¾Ð³Ð¾ URI"
@@ -39455,7 +40247,7 @@ msgid "User OAuth applications"
msgstr "OAuth заÑтоÑунки кориÑтувача"
msgid "User Settings"
-msgstr "ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ ÐºÐ¾Ñ€Ð¸Ñтувача"
+msgstr "Параметри кориÑтувача"
msgid "User and IP rate limits"
msgstr ""
@@ -39503,7 +40295,7 @@ msgid "User restrictions"
msgstr "ÐžÐ±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ ÐºÐ¾Ñ€Ð¸Ñтувача"
msgid "User settings"
-msgstr "ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ ÐºÐ¾Ñ€Ð¸Ñтувача"
+msgstr "Параметри кориÑтувача"
msgid "User was successfully created."
msgstr "КориÑтувача було уÑпішно Ñтворено."
@@ -39632,10 +40424,10 @@ msgid "UserProfile|Explore public groups to find projects to contribute to."
msgstr "ПереглÑдайте публічні групи та знаходьте проєкти Ð´Ð»Ñ Ñвоїх внеÑків."
msgid "UserProfile|Followers"
-msgstr ""
+msgstr "ПідпиÑники"
msgid "UserProfile|Following"
-msgstr ""
+msgstr "ПідпиÑник"
msgid "UserProfile|Groups"
msgstr "Групи"
@@ -39683,7 +40475,7 @@ msgid "UserProfile|Subscribe"
msgstr "ПідпиÑатиÑÑ"
msgid "UserProfile|This user doesn't have any followers."
-msgstr ""
+msgstr "Цей кориÑтувач не має жодного підпиÑника."
msgid "UserProfile|This user doesn't have any personal projects"
msgstr "Цей кориÑтувач не має оÑобиÑтих проєктів"
@@ -39719,7 +40511,7 @@ msgid "UserProfile|You can create a group for several dependent projects."
msgstr "Ви можете Ñтворити групу Ð´Ð»Ñ Ð´ÐµÐºÑ–Ð»ÑŒÐºÐ¾Ñ… залежних проєктів."
msgid "UserProfile|You do not have any followers."
-msgstr ""
+msgstr "У Ð²Ð°Ñ Ð½ÐµÐ¼Ð°Ñ” жодного підпиÑника."
msgid "UserProfile|You haven't created any personal projects."
msgstr "Ви ще не Ñтворили жодного оÑобиÑтого проєкту."
@@ -39760,6 +40552,9 @@ msgstr "Ім'Ñ ÐºÐ¾Ñ€Ð¸Ñтувача: %{username}"
msgid "Users"
msgstr "КориÑтувачі"
+msgid "Users API rate limit"
+msgstr ""
+
msgid "Users can launch a development environment from a GitLab browser tab when the %{linkStart}Gitpod%{linkEnd} integration is enabled."
msgstr ""
@@ -39992,22 +40787,22 @@ msgid "Version"
msgstr "ВерÑÑ–Ñ"
msgid "Version %{versionNumber}"
-msgstr ""
+msgstr "ВерÑÑ–Ñ %{versionNumber}"
msgid "Version %{versionNumber} (latest)"
-msgstr ""
+msgstr "ВерÑÑ–Ñ %{versionNumber} (оÑтаннÑ)"
msgid "VersionCheck|Up to date"
msgstr ""
msgid "VersionCheck|Update ASAP"
-msgstr ""
+msgstr "ÐžÐ½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ñкомога швидше"
msgid "VersionCheck|Update available"
-msgstr ""
+msgstr "ДоÑтупне оновленнÑ"
msgid "VersionCheck|Your GitLab Version"
-msgstr ""
+msgstr "Ваша верÑÑ–Ñ GitLab"
msgid "View Documentation"
msgstr "ПереглÑнути документацію"
@@ -40089,6 +40884,9 @@ msgstr ""
msgid "View group labels"
msgstr "ПереглÑнути мітки групи"
+msgid "View group pipeline usage quota"
+msgstr ""
+
msgid "View incident details at"
msgstr ""
@@ -40208,7 +41006,7 @@ msgid "Visibility level:"
msgstr "Рівень видимоÑÑ‚Ñ–:"
msgid "Visibility settings have been disabled by the administrator."
-msgstr "ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð²Ð¸Ð´Ð¸Ð¼Ð¾ÑÑ‚Ñ– були вимкнені адмініÑтратором."
+msgstr "Параметри видимоÑÑ‚Ñ– були вимкнені адмініÑтратором."
msgid "Visibility, project features, permissions"
msgstr "ВидиміÑÑ‚ÑŒ, оÑобливоÑÑ‚Ñ– проєкту, дозволи"
@@ -40243,6 +41041,9 @@ msgstr "ВразливоÑÑ‚Ñ–"
msgid "Vulnerabilities over time"
msgstr "ВразливоÑÑ‚Ñ– в чаÑÑ–"
+msgid "Vulnerability"
+msgstr ""
+
msgid "Vulnerability Report"
msgstr "Звіт про вразливоÑÑ‚Ñ–"
@@ -40294,6 +41095,9 @@ msgstr ""
msgid "VulnerabilityManagement|An unverified non-confirmed finding"
msgstr ""
+msgid "VulnerabilityManagement|At least one identifier is required"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr "Змінити ÑтатуÑ"
@@ -40303,12 +41107,24 @@ msgstr ""
msgid "VulnerabilityManagement|Create Jira issue"
msgstr ""
+msgid "VulnerabilityManagement|Enter a name"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE code"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE identifier URL"
+msgstr ""
+
msgid "VulnerabilityManagement|Fetching linked Jira issues"
msgstr ""
msgid "VulnerabilityManagement|Manually add a vulnerability entry into the vulnerability report."
msgstr ""
+msgid "VulnerabilityManagement|Name is a required field"
+msgstr ""
+
msgid "VulnerabilityManagement|Needs triage"
msgstr ""
@@ -40324,6 +41140,18 @@ msgstr ""
msgid "VulnerabilityManagement|Select a method"
msgstr ""
+msgid "VulnerabilityManagement|Select a severity level"
+msgstr ""
+
+msgid "VulnerabilityManagement|Select a status"
+msgstr ""
+
+msgid "VulnerabilityManagement|Severity is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Something went wrong while creating vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -40348,6 +41176,12 @@ msgstr "ЩоÑÑŒ пішло не так, не вдалоÑÑ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ñ‚Ð¸ к
msgid "VulnerabilityManagement|Something went wrong, could not update vulnerability state."
msgstr "ЩоÑÑŒ пішло не так, не вдалоÑÑ Ð¾Ð½Ð¾Ð²Ð¸Ñ‚Ð¸ Ñтан вразливоÑÑ‚Ñ–."
+msgid "VulnerabilityManagement|Status is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Submit vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Summary, detailed description, steps to reproduce, etc."
msgstr ""
@@ -40543,6 +41377,9 @@ msgstr ""
msgid "WARNING:"
msgstr ""
+msgid "WARNING: This snippet contains hidden files which might be used to mask malicious behavior. Exercise caution if cloning and executing code from this snippet."
+msgstr ""
+
msgid "Wait for the file to load to copy its contents"
msgstr "Зачекайте Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ñ„Ð°Ð¹Ð»Ñƒ Ð´Ð»Ñ ÐºÐ¾Ð¿Ñ–ÑŽÐ²Ð°Ð½Ð½Ñ Ð¹Ð¾Ð³Ð¾ вміÑту"
@@ -40762,6 +41599,15 @@ msgstr ""
msgid "Webhooks|An issue is created, updated, closed, or reopened."
msgstr ""
+msgid "Webhooks|Are you sure you want to delete this group hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this project hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this webhook?"
+msgstr ""
+
msgid "Webhooks|Comments"
msgstr ""
@@ -40771,6 +41617,9 @@ msgstr ""
msgid "Webhooks|Confidential issues events"
msgstr ""
+msgid "Webhooks|Delete webhook"
+msgstr ""
+
msgid "Webhooks|Deployment events"
msgstr ""
@@ -40883,10 +41732,10 @@ msgid "Welcome to GitLab, %{first_name}!"
msgstr "ЛаÑкаво проÑимо до GitLab, %{first_name}!"
msgid "Welcome to GitLab,%{br_tag}%{name}!"
-msgstr ""
+msgstr "ЛаÑкаво проÑимо до GitLab,%{br_tag}%{name}!"
msgid "Welcome, %{name}!"
-msgstr ""
+msgstr "ЛаÑкаво проÑимо, %{name}!"
msgid "What are CI/CD minutes?"
msgstr ""
@@ -40916,7 +41765,7 @@ msgid "What is repository mirroring?"
msgstr ""
msgid "What is squashing?"
-msgstr ""
+msgstr "Що таке об'Ñ”Ð´Ð½Ð°Ð½Ð½Ñ (squash) комітів?"
msgid "What is time tracking?"
msgstr ""
@@ -41006,6 +41855,9 @@ msgstr ""
msgid "Wiki"
msgstr "Вікі"
+msgid "Wiki page"
+msgstr ""
+
msgid "Wiki page was successfully created."
msgstr ""
@@ -41111,7 +41963,7 @@ msgstr "Видалити Ñторінку %{pageTitle}?"
msgid "WikiPageConflictMessage|Someone edited the page the same time you did. Please check out %{wikiLinkStart}the page%{wikiLinkEnd} and make sure your changes will not unintentionally remove theirs."
msgstr ""
-msgid "WikiPage|An error occured while trying to render the content editor. Please try again later."
+msgid "WikiPage|An error occurred while trying to render the content editor. Please try again later."
msgstr ""
msgid "WikiPage|Are you sure you want to switch back to the classic editor?"
@@ -41130,7 +41982,7 @@ msgid "WikiPage|Create %{pageTitle}"
msgstr ""
msgid "WikiPage|Create page"
-msgstr ""
+msgstr "Створити Ñторінку"
msgid "WikiPage|Edit rich text"
msgstr ""
@@ -41268,6 +42120,18 @@ msgid "WorkItem|Create work item"
msgstr ""
msgid "WorkItem|New Task"
+msgstr "Ðове завданнÑ"
+
+msgid "WorkItem|Something went wrong when creating a work item. Please try again"
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching the work item. Please try again."
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching work item types. Please try again"
+msgstr ""
+
+msgid "WorkItem|Type"
msgstr ""
msgid "WorkItem|Work Items"
@@ -41336,8 +42200,11 @@ msgstr ""
msgid "You are about to add %{usersTag} people to the discussion. They will all receive a notification."
msgstr ""
-msgid "You are about to permanently delete this project"
-msgstr "Ви збираєтеÑÑŒ оÑтаточно видалити цей проєкт"
+msgid "You are about to delete this forked project containing:"
+msgstr ""
+
+msgid "You are about to delete this project containing:"
+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 "Ви збираєтеÑÑŒ передати контроль над Ñвоїм обліковим запиÑом групі %{group_name}. Ð¦Ñ Ð´Ñ–Ñ ÐЕЗВОРОТÐÐ, ви не зможете отримати доÑтуп до жодної групи та проєкту за межами %{group_name}, Ñк тільки Ñ†Ñ Ð¿ÐµÑ€ÐµÐ´Ð°Ñ‡Ð° буде завершена."
@@ -41357,6 +42224,9 @@ msgstr "Ви намагаєтеÑÑ Ð²Ð¸Ð´Ð°Ð»Ð¸Ñ‚Ð¸ файл, Ñкий рані
msgid "You are attempting to update a file that has changed since you started editing it."
msgstr "Ви намагаєтеÑÑ Ð¾Ð½Ð¾Ð²Ð¸Ñ‚Ð¸ файл, Ñкий було змінено піÑÐ»Ñ Ð¿Ð¾Ñ‡Ð°Ñ‚ÐºÑƒ редагуваннÑ."
+msgid "You are billed if you exceed this number. %{qsrOverageLinkStart}How does billing work?%{qsrOverageLinkEnd}"
+msgstr ""
+
msgid "You are connected to the Prometheus server, but there is currently no data to display."
msgstr "Ви підключені до Ñервера Prometheus, але в даний Ñ‡Ð°Ñ Ð½ÐµÐ¼Ð°Ñ” даних Ð´Ð»Ñ Ð²Ñ–Ð´Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ."
@@ -41414,6 +42284,9 @@ msgstr ""
msgid "You are not authorized to update this scanner profile"
msgstr ""
+msgid "You are not authorized to upload metric images"
+msgstr ""
+
msgid "You are now impersonating %{username}"
msgstr "Зараз ви імітуєте %{username}"
@@ -41567,9 +42440,6 @@ msgstr "Ви можете переміщувати проєкт тільки в
msgid "You can only upload one design when dropping onto an existing design."
msgstr ""
-msgid "You can recover this project until %{date}"
-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 "Ви можете розв’Ñзати цей конфлікт Ð·Ð»Ð¸Ñ‚Ñ‚Ñ Ð·Ð° допомогою інтерактивного режиму (викориÑтовуючи кнопки %{use_ours} та %{use_theirs}), або безпоÑередньо редагуючи файли. Закомітити зміни у %{branch_name}"
@@ -41618,9 +42488,6 @@ msgstr "Ви не можете запиÑувати на вторинні інÑ
msgid "You cannot write to this read-only GitLab instance."
msgstr "Ви не можете запиÑувати на цей \"тільки Ð´Ð»Ñ Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ\" інÑÑ‚Ð°Ð½Ñ GitLab."
-msgid "You can’t %{tag_start}edit%{tag_end} files directly in this project. Fork this project and submit a merge request with your changes."
-msgstr ""
-
msgid "You can’t edit files directly in this project. Fork this project and submit a merge request with your changes."
msgstr ""
@@ -41775,9 +42642,6 @@ 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 set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
@@ -41808,12 +42672,6 @@ msgstr ""
msgid "You must have maintainer access to force delete a lock"
msgstr "Ви повинні мати доÑтуп керівника Ð´Ð»Ñ Ð¿Ñ€Ð¸Ð¼ÑƒÑового Ð²Ð¸Ð´Ð°Ð»ÐµÐ½Ð½Ñ Ð±Ð»Ð¾ÐºÑƒÐ²Ð°Ð½Ð½Ñ"
-msgid "You must have permission to create a project in a group before forking."
-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 "Вам потрібно вказати дійÑний поточний пароль"
@@ -42219,7 +43077,7 @@ msgstr "Ваші проєкти"
msgid "Your public email will be displayed on your public profile."
msgstr ""
-msgid "Your request for access could not be processed: %{error_meesage}"
+msgid "Your request for access could not be processed: %{error_message}"
msgstr ""
msgid "Your request for access has been queued for review."
@@ -42408,6 +43266,9 @@ msgstr "заархівовано"
msgid "archived:"
msgstr "архівовано:"
+msgid "artifacts"
+msgstr ""
+
msgid "assign yourself"
msgstr "призначити Ñамому Ñобі"
@@ -42439,6 +43300,9 @@ msgstr[3] ""
msgid "branch name"
msgstr "ім'Ñ Ð³Ñ–Ð»ÐºÐ¸"
+msgid "builds"
+msgstr ""
+
msgid "by"
msgstr "від"
@@ -42868,6 +43732,9 @@ msgstr ""
msgid "contact with same email already exists in group hierarchy"
msgstr ""
+msgid "container registry images"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -42907,6 +43774,9 @@ msgstr ""
msgid "data"
msgstr "дані"
+msgid "database"
+msgstr ""
+
msgid "date must not be after 9999-12-31"
msgstr "дата не повинна бути пізніше 9999-12-31"
@@ -42932,9 +43802,6 @@ msgstr "розгортаннÑ"
msgid "design"
msgstr "дизайн"
-msgid "detached"
-msgstr "відділена"
-
msgid "disabled"
msgstr "вимкнено"
@@ -43191,7 +44058,7 @@ msgstr "не Ñ” нащадком групи, Ñкій належить шаблÐ
msgid "is not a valid X509 certificate."
msgstr "не відповідний Ñертифікат X509."
-msgid "is not allowed for sign-up."
+msgid "is not allowed for sign-up. Please use your regular email address."
msgstr ""
msgid "is not allowed for this group."
@@ -43203,7 +44070,7 @@ msgstr ""
msgid "is not allowed since the group is not top-level group."
msgstr ""
-msgid "is not allowed."
+msgid "is not allowed. Please use your regular email address."
msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
@@ -43290,6 +44157,9 @@ msgstr "менше хвилини"
msgid "level: %{level}"
msgstr "рівень: %{level}"
+msgid "lfs objects"
+msgstr ""
+
msgid "limit of %{project_limit} reached"
msgstr "доÑÑгнуто ліміт %{project_limit}"
@@ -43352,10 +44222,10 @@ msgid "mrWidget|%{linkStart}Set up now%{linkEnd} to analyze your source code for
msgstr ""
msgid "mrWidget|%{mergeError}."
-msgstr ""
+msgstr "%{mergeError}."
msgid "mrWidget|%{mergeError}. Try again."
-msgstr ""
+msgstr "%{mergeError}. Спробуйте ще раз."
msgid "mrWidget|%{metricsLinkStart} Memory %{metricsLinkEnd} usage %{emphasisStart} decreased %{emphasisEnd} from %{memoryFrom}MB to %{memoryTo}MB"
msgstr "ВикориÑÑ‚Ð°Ð½Ð½Ñ %{metricsLinkStart} пам’ÑÑ‚Ñ– %{metricsLinkEnd} %{emphasisStart} впало %{emphasisEnd} з %{memoryFrom}Мб до %{memoryTo}Мб"
@@ -43403,10 +44273,10 @@ msgid "mrWidget|Approved by"
msgstr "Затверджено"
msgid "mrWidget|Approved by you"
-msgstr ""
+msgstr "Затверджено вами"
msgid "mrWidget|Approved by you and others"
-msgstr ""
+msgstr "Затверджено вами та іншими"
msgid "mrWidget|Cancel auto-merge"
msgstr "СкаÑувати автоматичне злиттÑ"
@@ -43431,10 +44301,10 @@ msgstr "Закритий"
msgid "mrWidget|Closes issue"
msgid_plural "mrWidget|Closes issues"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] ""
-msgstr[3] ""
+msgstr[0] "Закриває задачу"
+msgstr[1] "Закриває задачі"
+msgstr[2] "Закриває задач"
+msgstr[3] "Закриває задач"
msgid "mrWidget|Create issue to resolve all threads"
msgstr ""
@@ -43443,7 +44313,7 @@ msgid "mrWidget|Delete source branch"
msgstr "Видалити гілку-джерело"
msgid "mrWidget|Deletes the source branch"
-msgstr ""
+msgstr "ВидалÑÑ” гілку джерела"
msgid "mrWidget|Deployment statistics are not available currently"
msgstr "СтатиÑтика Ñ€Ð¾Ð·Ð³Ð¾Ñ€Ñ‚Ð°Ð½Ð½Ñ Ð½Ð°Ñ€Ð°Ð·Ñ– недоÑтупна"
@@ -43452,7 +44322,7 @@ msgid "mrWidget|Did not close"
msgstr "Ðе закрив"
msgid "mrWidget|Dismiss"
-msgstr ""
+msgstr "Відхилити"
msgid "mrWidget|Does not delete the source branch"
msgstr ""
@@ -43467,10 +44337,10 @@ msgid "mrWidget|GitLab %{linkStart}CI/CD can automatically build, test, and depl
msgstr ""
msgid "mrWidget|Hide %{widget} details"
-msgstr ""
+msgstr "Приховати деталі %{widget}"
msgid "mrWidget|If the %{type} branch exists in your local repository, you can merge this merge request manually using the command line."
-msgstr ""
+msgstr "Якщо гілка %{type} Ñ–Ñнує у вашому локальному репозиторії, то ви можете заÑтоÑувати цей запит на Ð·Ð»Ð¸Ñ‚Ñ‚Ñ Ð²Ñ€ÑƒÑ‡Ð½Ñƒ за допомогою командного Ñ€Ñдка."
msgid "mrWidget|If the last pipeline ran in the fork project, it may be inaccurate. Before merge, we advise running a pipeline in this project."
msgstr ""
@@ -43510,14 +44380,17 @@ msgid "mrWidget|Merge blocked: fast-forward merge is not possible. To merge this
msgstr ""
msgid "mrWidget|Merge blocked: merge conflicts must be resolved."
-msgstr ""
+msgstr "Заблоковано: конфлікти Ð·Ð»Ð¸Ñ‚Ñ‚Ñ Ð¿Ð¾Ð²Ð¸Ð½Ð½Ñ– бути вирішені."
msgid "mrWidget|Merge blocked: pipeline must succeed. It's waiting for a manual action to continue."
msgstr ""
-msgid "mrWidget|Merge blocked: this merge request must be approved."
+msgid "mrWidget|Merge blocked: pipeline must succeed. Push a commit that fixes the failure, or %{linkStart}learn about other solutions.%{linkEnd}"
msgstr ""
+msgid "mrWidget|Merge blocked: this merge request must be approved."
+msgstr "Заблоковано: цей запит на Ð·Ð»Ð¸Ñ‚Ñ‚Ñ Ð¼Ð°Ñ” бути затверджений."
+
msgid "mrWidget|Merge blocked: you can only merge after the above items are resolved."
msgstr ""
@@ -43528,46 +44401,46 @@ msgid "mrWidget|Merge locally"
msgstr "Злити локально"
msgid "mrWidget|Merge unavailable: merge requests are read-only on archived projects."
-msgstr ""
+msgstr "ÐедоÑтупне: запити на Ð·Ð»Ð¸Ñ‚Ñ‚Ñ Ð´Ð¾Ñтупні лише Ð´Ð»Ñ Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ Ð· архівних проєктів."
msgid "mrWidget|Merged by"
msgstr "Злито"
msgid "mrWidget|Merges changes into"
-msgstr ""
+msgstr "Об'єднує зміни в"
msgid "mrWidget|Merging! Changes are being shipped…"
-msgstr ""
+msgstr "ЗлиттÑ! Зміни відправлÑÑŽÑ‚ÑŒÑÑ…"
msgid "mrWidget|Merging! Changes will land soon…"
-msgstr ""
+msgstr "ЗлиттÑ! Зміни Ñкоро відбудутьÑÑ…"
msgid "mrWidget|Merging! Drum roll, please…"
-msgstr ""
+msgstr "ЗлиттÑ! Барабанний дріб…"
msgid "mrWidget|Merging! Everything's good…"
-msgstr ""
+msgstr "ЗлиттÑ! Ð’Ñе добре…"
msgid "mrWidget|Merging! Lift-off in 5… 4… 3…"
-msgstr ""
+msgstr "ЗлиттÑ! Зліт через 5…4…3…"
msgid "mrWidget|Merging! Take a deep breath and relax…"
-msgstr ""
+msgstr "ЗлиттÑ! Зробіть глибокий вдих Ñ– розÑлабтеÑÑ…"
msgid "mrWidget|Merging! The changes are leaving the station…"
-msgstr ""
+msgstr "ЗлиттÑ! Зміни залишають Ñтанцію…"
msgid "mrWidget|Merging! This is going to be great…"
-msgstr ""
+msgstr "ЗлиттÑ! Це буде чудовий…"
msgid "mrWidget|Merging! We're almost there…"
-msgstr ""
+msgstr "ЗлиттÑ! Ми майже на міÑці…"
msgid "mrWidget|More information"
msgstr "Детальніше"
msgid "mrWidget|Open in Gitpod"
-msgstr ""
+msgstr "Відкрити у Gitpod"
msgid "mrWidget|Open in Web IDE"
msgstr "Відкрити у Web IDE"
@@ -43621,7 +44494,7 @@ msgid "mrWidget|Set by %{merge_author} to start a merge train when the pipeline
msgstr ""
msgid "mrWidget|Show %{widget} details"
-msgstr ""
+msgstr "Показати %{widget} подробиці"
msgid "mrWidget|The %{type} branch %{codeStart}%{name}%{codeEnd} does not exist."
msgstr ""
@@ -43632,9 +44505,6 @@ msgstr "Зміни були злиті в"
msgid "mrWidget|The changes were not merged into"
msgstr "Зміни не були злиті в"
-msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr "Гілку-джерело видалено"
@@ -43747,7 +44617,7 @@ msgid "no expiration"
msgstr ""
msgid "no name set"
-msgstr ""
+msgstr "немає імені"
msgid "no one can merge"
msgstr "ніхто не може виконати злиттÑ"
@@ -43782,9 +44652,6 @@ msgstr ""
msgid "open issue"
msgstr "відкрита задачу"
-msgid "opened %{timeAgo}"
-msgstr "відкрито %{timeAgo}"
-
msgid "or"
msgstr "або"
@@ -43798,6 +44665,12 @@ msgstr[1] "із %d теÑтів"
msgstr[2] "із %d теÑтів"
msgstr[3] "із %d теÑтів"
+msgid "packages"
+msgstr ""
+
+msgid "pages"
+msgstr ""
+
msgid "parent"
msgid_plural "parents"
msgstr[0] "батьківÑький об’єкт"
@@ -43955,6 +44828,9 @@ msgstr[1] "відповіді"
msgstr[2] "відповідей"
msgstr[3] "відповідей"
+msgid "repositories"
+msgstr ""
+
msgid "repository:"
msgstr "репозиторій:"
@@ -44075,12 +44951,18 @@ msgstr ""
msgid "tag name"
msgstr "назва тегу"
+msgid "terraform states"
+msgstr ""
+
msgid "the correct format."
msgstr ""
msgid "the file"
msgstr ""
+msgid "the following epic(s)"
+msgstr ""
+
msgid "the following issue(s)"
msgstr ""
@@ -44093,21 +44975,12 @@ msgstr ""
msgid "this document"
msgstr "цей документ"
-msgid "this issue cannot be assigned to a confidential epic since it is public"
-msgstr ""
-
-msgid "this issue cannot be made public since it belongs to a confidential epic"
-msgstr ""
-
msgid "time summary"
msgstr "підÑумок чаÑу"
msgid "toggle collapse"
msgstr "згорнути/розгорнути"
-msgid "train"
-msgstr ""
-
msgid "triggered"
msgstr "запущено"
@@ -44127,7 +45000,7 @@ msgid "updated"
msgstr "оновлено"
msgid "updated %{timeAgo}"
-msgstr ""
+msgstr "оновлено %{timeAgo}"
msgid "updated %{time_ago}"
msgstr "оновлено %{time_ago}"
@@ -44238,3 +45111,6 @@ msgstr "{group}"
msgid "{project}"
msgstr "{project}"
+msgid "✔"
+msgstr ""
+
diff --git a/locale/ur_PK/gitlab.po b/locale/ur_PK/gitlab.po
index aecaf9bd0db..f3bc4fc2e28 100644
--- a/locale/ur_PK/gitlab.po
+++ b/locale/ur_PK/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: ur-PK\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2022-02-02 15:43\n"
+"PO-Revision-Date: 2022-03-01 20:36\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -146,6 +146,11 @@ msgid_plural "%d approvers (you've approved)"
msgstr[0] ""
msgstr[1] ""
+msgid "%d assigned issue"
+msgid_plural "%d assigned issues"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -421,8 +426,23 @@ msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
msgstr[1] ""
-msgid "%d vulnerability updated"
-msgid_plural "%d vulnerabilities updated"
+msgid "%d vulnerability set to confirmed"
+msgid_plural "%d vulnerabilities set to confirmed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to dismissed"
+msgid_plural "%d vulnerabilities set to dismissed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to needs triage"
+msgid_plural "%d vulnerabilities set to needs triage"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to resolved"
+msgid_plural "%d vulnerabilities set to resolved"
msgstr[0] ""
msgstr[1] ""
@@ -510,6 +530,12 @@ msgstr[1] ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{completed} of %{total} issues closed"
+msgstr ""
+
+msgid "%{completed} of %{total} weight completed"
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -858,6 +884,9 @@ msgstr ""
msgid "%{openedIssues} open, %{closedIssues} closed"
msgstr ""
+msgid "%{percentage}%% issues closed"
+msgstr ""
+
msgid "%{percentage}%% weight completed"
msgstr ""
@@ -1287,6 +1316,9 @@ msgid_plural "- Users"
msgstr[0] ""
msgstr[1] ""
+msgid "- of - issues closed"
+msgstr ""
+
msgid "- of - weight completed"
msgstr ""
@@ -1429,7 +1461,7 @@ msgstr ""
msgid "1000+"
msgstr ""
-msgid "192.168.0.0/24"
+msgid "192.168.0.0/24 or 2001:0DB8:1234::/48"
msgstr ""
msgid "1st contribution!"
@@ -1741,13 +1773,13 @@ msgstr ""
msgid "AWS Access Key"
msgstr ""
-msgid "AWS Access Key. Only required if not using role instance credentials"
+msgid "AWS Secret Access Key"
msgstr ""
-msgid "AWS Secret Access Key"
+msgid "AWS access key ID (Optional)"
msgstr ""
-msgid "AWS Secret Access Key. Only required if not using role instance credentials"
+msgid "AWS secret access key (Optional)"
msgstr ""
msgid "AWS service error: %{error}"
@@ -1807,9 +1839,6 @@ msgstr ""
msgid "Access granted"
msgstr ""
-msgid "Access key ID"
-msgstr ""
-
msgid "Access requests"
msgstr ""
@@ -1984,7 +2013,7 @@ msgstr ""
msgid "Activity"
msgstr ""
-msgid "Activity|An error occured while retrieving activity. Reload the page to try again."
+msgid "Activity|An error occurred while retrieving activity. Reload the page to try again."
msgstr ""
msgid "Add"
@@ -2023,6 +2052,9 @@ msgstr ""
msgid "Add a %{type}"
msgstr ""
+msgid "Add a GCP region"
+msgstr ""
+
msgid "Add a GPG key"
msgstr ""
@@ -2074,6 +2106,9 @@ msgstr ""
msgid "Add a numbered list"
msgstr ""
+msgid "Add a related epic"
+msgstr ""
+
msgid "Add a related issue"
msgstr ""
@@ -2188,6 +2223,9 @@ msgstr ""
msgid "Add or subtract spent time"
msgstr ""
+msgid "Add people"
+msgstr ""
+
msgid "Add previously merged commits"
msgstr ""
@@ -2254,6 +2292,9 @@ msgstr ""
msgid "Add webhook"
msgstr ""
+msgid "Add your team members and others to GitLab."
+msgstr ""
+
msgid "Add/remove"
msgstr ""
@@ -3076,12 +3117,6 @@ msgstr ""
msgid "AdvancedSearch|Reindex required"
msgstr ""
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. Permanently deleting this project will %{strongStart}immediately delete%{strongEnd} its repositories and %{strongStart}all related resources%{strongEnd}, including issues, merge requests etc."
-msgstr ""
-
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. You will lose this project's repository and %{strongStart}all related resources%{strongEnd}, including issues and merge requests."
-msgstr ""
-
msgid "After a successful password update you will be redirected to login screen."
msgstr ""
@@ -3112,6 +3147,9 @@ msgstr ""
msgid "Akismet helps prevent the creation of spam issues in public projects."
msgstr ""
+msgid "Alert"
+msgstr ""
+
msgid "AlertManagement|Acknowledged"
msgstr ""
@@ -3484,9 +3522,6 @@ msgstr ""
msgid "All environments"
msgstr ""
-msgid "All epics"
-msgstr ""
-
msgid "All groups and projects"
msgstr ""
@@ -4223,12 +4258,15 @@ msgstr ""
msgid "ApplicationSettings|Approve users in the pending approval status?"
msgstr ""
-msgid "ApplicationSettings|By making this change, you will automatically approve %d user with the pending approval status."
-msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users with the pending approval status."
+msgid "ApplicationSettings|Approve users who are pending approval?"
+msgstr ""
+
+msgid "ApplicationSettings|By making this change, you will automatically approve %d user who is pending approval."
+msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users who are pending approval."
msgstr[0] ""
msgstr[1] ""
-msgid "ApplicationSettings|By making this change, you will automatically approve all users in pending approval status."
+msgid "ApplicationSettings|By making this change, you will automatically approve all users who are pending approval."
msgstr ""
msgid "ApplicationSettings|Denied domains for sign-ups"
@@ -4634,10 +4672,10 @@ msgstr ""
msgid "Archiving the project will make it entirely read-only. It is hidden from the dashboard and doesn't show up in searches. %{strong_start}The repository cannot be committed to, and no issues, comments, or other entities can be created.%{strong_end} %{link_start}Learn more.%{link_end}"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to delete this project?"
+msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
+msgid "Are you absolutely sure?"
msgstr ""
msgid "Are you sure that you want to archive this project?"
@@ -4673,12 +4711,18 @@ msgstr ""
msgid "Are you sure you want to delete this SSH key?"
msgstr ""
+msgid "Are you sure you want to delete this comment?"
+msgstr ""
+
msgid "Are you sure you want to delete this deploy key?"
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 label?"
+msgstr ""
+
msgid "Are you sure you want to delete this pipeline schedule?"
msgstr ""
@@ -4694,9 +4738,6 @@ msgstr ""
msgid "Are you sure you want to discard your changes?"
msgstr ""
-msgid "Are you sure you want to erase this build?"
-msgstr ""
-
msgid "Are you sure you want to import %d repository?"
msgid_plural "Are you sure you want to import %d repositories?"
msgstr[0] ""
@@ -4744,6 +4785,9 @@ msgstr ""
msgid "Are you sure you want to remove this list?"
msgstr ""
+msgid "Are you sure you want to remove this nickname?"
+msgstr ""
+
msgid "Are you sure you want to reset the health check token?"
msgstr ""
@@ -4756,10 +4800,10 @@ 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?"
+msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
msgstr ""
-msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
+msgid "Are you sure you want to revoke this project access token? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to stop this environment?"
@@ -4906,9 +4950,6 @@ msgstr ""
msgid "Assigned to %{assignee_name}"
msgstr ""
-msgid "Assigned to %{name}"
-msgstr ""
-
msgid "Assigned to me"
msgstr ""
@@ -4973,6 +5014,9 @@ msgstr[1] ""
msgid "Attaching the file failed."
msgstr ""
+msgid "Attention"
+msgstr ""
+
msgid "Audit Events"
msgstr ""
@@ -5135,6 +5179,12 @@ msgstr ""
msgid "Authorized applications (%{size})"
msgstr ""
+msgid "AuthorizedApplication|Are you sure you want to revoke this application?"
+msgstr ""
+
+msgid "AuthorizedApplication|Revoke application"
+msgstr ""
+
msgid "Authors: %{authors}"
msgstr ""
@@ -6328,6 +6378,9 @@ msgstr ""
msgid "CICDAnalytics|Shared Runners Usage"
msgstr ""
+msgid "CICDAnalytics|Shared runner pipeline minute duration by month"
+msgstr ""
+
msgid "CICDAnalytics|Shared runner usage"
msgstr ""
@@ -6469,6 +6522,9 @@ msgstr ""
msgid "Can create groups:"
msgstr ""
+msgid "Can not delete primary training"
+msgstr ""
+
msgid "Can't apply as the source branch was deleted."
msgstr ""
@@ -6802,9 +6858,6 @@ msgstr ""
msgid "Changing any setting here requires an application restart"
msgstr ""
-msgid "Changing group URL can have unintended side effects."
-msgstr ""
-
msgid "Charts can't be displayed as the request for data has timed out. %{documentationLink}"
msgstr ""
@@ -6892,9 +6945,6 @@ msgstr ""
msgid "Checking branch availability..."
msgstr ""
-msgid "Checking group URL availability..."
-msgstr ""
-
msgid "Checking group path availability..."
msgstr ""
@@ -7388,6 +7438,9 @@ msgstr ""
msgid "Clear recent searches"
msgstr ""
+msgid "Clear repository checks"
+msgstr ""
+
msgid "Clear search"
msgstr ""
@@ -7520,9 +7573,6 @@ msgstr ""
msgid "Closed MRs"
msgstr ""
-msgid "Closed epics"
-msgstr ""
-
msgid "Closed issues"
msgstr ""
@@ -7559,13 +7609,13 @@ msgstr ""
msgid "Cluster level"
msgstr ""
-msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
+msgid "Cluster type must be specified for Stages::ClusterEndpointInserter"
msgstr ""
msgid "ClusterAgents|%{name} successfully deleted"
msgstr ""
-msgid "ClusterAgents|%{number} of %{total} Agents"
+msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
@@ -7607,6 +7657,15 @@ msgstr ""
msgid "ClusterAgents|Agent never connected to GitLab"
msgstr ""
+msgid "ClusterAgents|Agent version mismatch"
+msgstr ""
+
+msgid "ClusterAgents|Agent version mismatch and update"
+msgstr ""
+
+msgid "ClusterAgents|Agent version update required"
+msgstr ""
+
msgid "ClusterAgents|All"
msgstr ""
@@ -7631,7 +7690,7 @@ msgstr ""
msgid "ClusterAgents|Configuration"
msgstr ""
-msgid "ClusterAgents|Connect a cluster through the Agent"
+msgid "ClusterAgents|Connect a cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connect existing cluster"
@@ -7640,13 +7699,13 @@ msgstr ""
msgid "ClusterAgents|Connect with a certificate"
msgstr ""
-msgid "ClusterAgents|Connect with agent"
+msgid "ClusterAgents|Connect with an agent"
msgstr ""
msgid "ClusterAgents|Connect with the GitLab Agent"
msgstr ""
-msgid "ClusterAgents|Connect your cluster through the Agent"
+msgid "ClusterAgents|Connect your cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connected"
@@ -7706,7 +7765,10 @@ msgstr ""
msgid "ClusterAgents|How to register an agent?"
msgstr ""
-msgid "ClusterAgents|Install new Agent"
+msgid "ClusterAgents|How to update an agent?"
+msgstr ""
+
+msgid "ClusterAgents|Install a new agent"
msgstr ""
msgid "ClusterAgents|Last connected %{timeAgo}."
@@ -7733,7 +7795,7 @@ msgstr ""
msgid "ClusterAgents|Never connected"
msgstr ""
-msgid "ClusterAgents|No Agents"
+msgid "ClusterAgents|No agents"
msgstr ""
msgid "ClusterAgents|No clusters connected through cluster certificates"
@@ -7793,6 +7855,9 @@ msgstr ""
msgid "ClusterAgents|The agent has not been connected in a long time. There might be a connectivity issue. Last contact was %{timeAgo}."
msgstr ""
+msgid "ClusterAgents|The agent version do not match each other across your cluster's pods. This can happen when a new agent version was just deployed and Kubernetes is shutting down the old pods."
+msgstr ""
+
msgid "ClusterAgents|The recommended installation method includes the token. If you want to follow the advanced installation method provided in the docs, make sure you save the token value before you close this window."
msgstr ""
@@ -7840,6 +7905,9 @@ msgstr ""
msgid "ClusterAgents|You will need to create a token to connect to your agent"
msgstr ""
+msgid "ClusterAgents|Your agent version is out of sync with your GitLab version (v%{version}), which might cause compatibility problems. Update the agent installed on your cluster to the most recent version."
+msgstr ""
+
msgid "ClusterAgents|Your instance doesn't have the %{linkStart}GitLab Agent Server (KAS)%{linkEnd} set up. Ask a GitLab Administrator to install it."
msgstr ""
@@ -8716,9 +8784,6 @@ msgstr ""
msgid "Comma-separated list of email addresses."
msgstr ""
-msgid "Comma-separated list of users allowed to exceed the rate limit."
-msgstr ""
-
msgid "Comma-separated, e.g. '1.1.1.1, 2.2.2.0/24'"
msgstr ""
@@ -9045,6 +9110,12 @@ msgstr ""
msgid "Confidential"
msgstr ""
+msgid "Confidential issue"
+msgstr ""
+
+msgid "Confidential note"
+msgstr ""
+
msgid "Confidentiality"
msgstr ""
@@ -9078,6 +9149,9 @@ msgstr ""
msgid "Configure Dependency Scanning in `.gitlab-ci.yml`, creating this file if it does not already exist"
msgstr ""
+msgid "Configure GitLab"
+msgstr ""
+
msgid "Configure GitLab runners to start using the Web Terminal. %{helpStart}Learn more.%{helpEnd}"
msgstr ""
@@ -9126,6 +9200,15 @@ msgstr ""
msgid "Configure pipelines to deploy web apps, backend services, APIs and static resources to Google Cloud"
msgstr ""
+msgid "Configure region"
+msgstr ""
+
+msgid "Configure region for environment"
+msgstr ""
+
+msgid "Configure regions"
+msgstr ""
+
msgid "Configure repository mirroring."
msgstr ""
@@ -9159,6 +9242,9 @@ msgstr ""
msgid "Configure which lists are shown for anyone who visits this board"
msgstr ""
+msgid "Configure your environments to be deployed to specific geographical regions"
+msgstr ""
+
msgid "Confirm"
msgstr ""
@@ -9861,10 +9947,10 @@ msgstr ""
msgid "CorpusManagement|Actions"
msgstr ""
-msgid "CorpusManagement|Corpus are used in fuzz testing as mutation source to Improve future testing."
+msgid "CorpusManagement|Corpus file"
msgstr ""
-msgid "CorpusManagement|Corpus file"
+msgid "CorpusManagement|Corpus files are used in coverage-guided fuzz testing as seed inputs to improve testing."
msgstr ""
msgid "CorpusManagement|Corpus files must be in *.zip format. Maximum 5 GB"
@@ -9918,6 +10004,9 @@ msgstr ""
msgid "Could not apply %{name} command."
msgstr ""
+msgid "Could not apply %{name} command. %{message}."
+msgstr ""
+
msgid "Could not authorize chat nickname. Try again!"
msgstr ""
@@ -10068,6 +10157,9 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
+msgid "Create a group"
+msgstr ""
+
msgid "Create a merge request"
msgstr ""
@@ -10092,6 +10184,9 @@ msgstr ""
msgid "Create a personal access token on your account to pull or push via %{protocol}."
msgstr ""
+msgid "Create a project"
+msgstr ""
+
msgid "Create an account using:"
msgstr ""
@@ -10455,6 +10550,9 @@ msgstr ""
msgid "Creation date"
msgstr ""
+msgid "Creator"
+msgstr ""
+
msgid "Credentials"
msgstr ""
@@ -10467,9 +10565,15 @@ msgstr ""
msgid "CredentialsInventory|Personal Access Tokens"
msgstr ""
+msgid "CredentialsInventory|Project Access Tokens"
+msgstr ""
+
msgid "CredentialsInventory|SSH Keys"
msgstr ""
+msgid "Credit card required to be on file in order to create a pipeline"
+msgstr ""
+
msgid "Credit card:"
msgstr ""
@@ -10653,9 +10757,6 @@ msgstr ""
msgid "Customer relations"
msgstr ""
-msgid "Customizable by an administrator."
-msgstr ""
-
msgid "Customizable by owners."
msgstr ""
@@ -10785,30 +10886,18 @@ msgstr ""
msgid "CycleAnalytics|%{selectedLabelsCount} selected (%{maxLabels} max)"
msgstr ""
-msgid "CycleAnalytics|%{stageCount} stages selected"
-msgstr ""
-
-msgid "CycleAnalytics|All stages"
-msgstr ""
-
-msgid "CycleAnalytics|Average days to completion"
+msgid "CycleAnalytics|Average time to completion"
msgstr ""
msgid "CycleAnalytics|Date"
msgstr ""
-msgid "CycleAnalytics|Days to completion"
-msgstr ""
-
msgid "CycleAnalytics|Display chart filters"
msgstr ""
msgid "CycleAnalytics|Lead Time for Changes"
msgstr ""
-msgid "CycleAnalytics|No stages selected"
-msgstr ""
-
msgid "CycleAnalytics|Number of tasks"
msgstr ""
@@ -10837,18 +10926,30 @@ msgstr ""
msgid "CycleAnalytics|Showing data for group '%{groupName}' from %{createdAfter} to %{createdBefore}"
msgstr ""
-msgid "CycleAnalytics|Stages"
+msgid "CycleAnalytics|Stage time: %{title}"
msgstr ""
msgid "CycleAnalytics|Tasks by type"
msgstr ""
-msgid "CycleAnalytics|The average time spent in the selected stage for the items that were completed on each date. Data limited to the last 500 items."
+msgid "CycleAnalytics|The average time items spent in this stage. Data limited to items completed within this date range."
msgstr ""
msgid "CycleAnalytics|The given date range is larger than 180 days"
msgstr ""
+msgid "CycleAnalytics|The total time items spent across each value stream stage. Data limited to items completed within this date range."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Stage time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Total time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|Total time"
+msgstr ""
+
msgid "CycleAnalytics|Type of work"
msgstr ""
@@ -10861,9 +10962,6 @@ msgstr ""
msgid "CycleAnalytics|project dropdown filter"
msgstr ""
-msgid "CycleAnalytics|stage dropdown"
-msgstr ""
-
msgid "DAG visualization requires at least 3 dependent jobs."
msgstr ""
@@ -10963,10 +11061,16 @@ msgstr ""
msgid "DastProfiles|AJAX spider"
msgstr ""
+msgid "DastProfiles|API"
+msgstr ""
+
+msgid "DastProfiles|API endpoint URL"
+msgstr ""
+
msgid "DastProfiles|Active"
msgstr ""
-msgid "DastProfiles|Additional request headers (Optional)"
+msgid "DastProfiles|Additional request headers (optional)"
msgstr ""
msgid "DastProfiles|Are you sure you want to delete this profile?"
@@ -10981,6 +11085,9 @@ msgstr ""
msgid "DastProfiles|Branch missing"
msgstr ""
+msgid "DastProfiles|Choose a scan method"
+msgstr ""
+
msgid "DastProfiles|Could not create the scanner profile. Please try again."
msgstr ""
@@ -11050,7 +11157,13 @@ msgstr ""
msgid "DastProfiles|Excluded URLs"
msgstr ""
-msgid "DastProfiles|Excluded URLs (Optional)"
+msgid "DastProfiles|Excluded URLs (optional)"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths (optional)"
msgstr ""
msgid "DastProfiles|Hide debug messages"
@@ -11107,9 +11220,6 @@ msgstr ""
msgid "DastProfiles|Request headers"
msgstr ""
-msgid "DastProfiles|Rest API"
-msgstr ""
-
msgid "DastProfiles|Run the AJAX spider, in addition to the traditional spider, to crawl the target site."
msgstr ""
@@ -11119,6 +11229,9 @@ msgstr ""
msgid "DastProfiles|Save profile"
msgstr ""
+msgid "DastProfiles|Scan method"
+msgstr ""
+
msgid "DastProfiles|Scan mode"
msgstr ""
@@ -11197,12 +11310,24 @@ msgstr ""
msgid "DastProfiles|Website"
msgstr ""
+msgid "DastProfiles|What does each method do?"
+msgstr ""
+
msgid "DastProfiles|You can either choose a passive scan or validate the target site from the site profile management page. %{docsLinkStart}Learn more about site validation.%{docsLinkEnd}"
msgstr ""
msgid "DastProfiles|You cannot run an active scan against an unvalidated site."
msgstr ""
+msgid "DastProfiles|folder/dast_example.har or https://example.com/dast_example.har"
+msgstr ""
+
+msgid "DastProfiles|folder/example.postman_collection.json or https://example.com/"
+msgstr ""
+
+msgid "DastProfiles|folder/openapi.json or https://example.com/openapi.json"
+msgstr ""
+
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
@@ -11310,6 +11435,9 @@ msgstr ""
msgid "DatadogIntegration|API URL"
msgstr ""
+msgid "DatadogIntegration|Custom tags in Datadog. Enter one tag per line in the %{codeOpen}key:value%{codeClose} format. %{linkOpen}How do I use tags?%{linkClose}"
+msgstr ""
+
msgid "DatadogIntegration|Environment"
msgstr ""
@@ -11328,12 +11456,18 @@ msgstr ""
msgid "DatadogIntegration|Tag all data from this GitLab instance in Datadog. Useful when managing several self-managed deployments."
msgstr ""
+msgid "DatadogIntegration|Tags"
+msgstr ""
+
msgid "DatadogIntegration|The Datadog site to send data to. To send data to the EU site, use %{codeOpen}datadoghq.eu%{codeClose}."
msgstr ""
msgid "DatadogIntegration|Trace your GitLab pipelines with Datadog."
msgstr ""
+msgid "DatadogIntegration|have an invalid format"
+msgstr ""
+
msgid "Datasource name not found"
msgstr ""
@@ -11343,9 +11477,6 @@ msgstr ""
msgid "Date merged"
msgstr ""
-msgid "Date picker"
-msgstr ""
-
msgid "Date range"
msgstr ""
@@ -11499,9 +11630,6 @@ msgstr ""
msgid "Definition"
msgstr ""
-msgid "Delayed Project Deletion (%{adjourned_deletion})"
-msgstr ""
-
msgid "DelayedJobs|Are you sure you want to run %{jobName} immediately? Otherwise this job will run automatically after its timer finishes."
msgstr ""
@@ -11580,10 +11708,10 @@ msgstr ""
msgid "Delete pipeline"
msgstr ""
-msgid "Delete project"
+msgid "Delete pipeline schedule"
msgstr ""
-msgid "Delete project. Are you ABSOLUTELY SURE?"
+msgid "Delete project"
msgstr ""
msgid "Delete row"
@@ -11613,6 +11741,9 @@ msgstr ""
msgid "Delete this epic and all descendants?"
msgstr ""
+msgid "Delete this project"
+msgstr ""
+
msgid "Delete user list"
msgstr ""
@@ -11871,6 +12002,12 @@ msgstr ""
msgid "Deploy to..."
msgstr ""
+msgid "DeployBoards|To see deployment progress for your environments, make sure you are deploying to %{codeStart}$KUBE_NAMESPACE%{codeEnd} and annotating with %{codeStart}app.gitlab.com/app=$CI_PROJECT_PATH_SLUG%{codeEnd} and %{codeStart}app.gitlab.com/env=$CI_ENVIRONMENT_SLUG%{codeEnd}."
+msgstr ""
+
+msgid "DeployBoard|Kubernetes Pods"
+msgstr ""
+
msgid "DeployFreeze|Add a freeze period to prevent unintended releases during a period of time for a given environment. You must update the deployment jobs in %{filename} according to the deploy freezes added here. %{freeze_period_link_start}Learn more.%{freeze_period_link_end}"
msgstr ""
@@ -11955,9 +12092,6 @@ msgstr ""
msgid "DeployTokens|Active Deploy Tokens (%{active_tokens})"
msgstr ""
-msgid "DeployTokens|Allows read and write access to registry images."
-msgstr ""
-
msgid "DeployTokens|Allows read and write access to the package registry."
msgstr ""
@@ -11970,6 +12104,9 @@ msgstr ""
msgid "DeployTokens|Allows read-only access to the repository."
msgstr ""
+msgid "DeployTokens|Allows write access to registry images."
+msgstr ""
+
msgid "DeployTokens|Copy deploy token"
msgstr ""
@@ -12063,12 +12200,57 @@ msgstr ""
msgid "Deploying to AWS is easy with GitLab"
msgstr ""
+msgid "Deployment"
+msgstr ""
+
msgid "Deployment Frequency"
msgstr ""
+msgid "Deployment Target|Project deployment target (optional)"
+msgstr ""
+
+msgid "Deployment Target|Select the deployment target"
+msgstr ""
+
msgid "Deployment frequency"
msgstr ""
+msgid "DeploymentTarget|GitLab Pages"
+msgstr ""
+
+msgid "DeploymentTarget|Heroku"
+msgstr ""
+
+msgid "DeploymentTarget|Infrastructure provider (Terraform, Cloudformation, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Kubernetes (GKE, EKS, OpenShift, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Managed container runtime (Fargate, Cloud Run, DigitalOcean App)"
+msgstr ""
+
+msgid "DeploymentTarget|Mobile app store"
+msgstr ""
+
+msgid "DeploymentTarget|No deployment planned"
+msgstr ""
+
+msgid "DeploymentTarget|Other hosting service"
+msgstr ""
+
+msgid "DeploymentTarget|Registry (package or container)"
+msgstr ""
+
+msgid "DeploymentTarget|Self-managed container runtime (Podman, Docker Swarm, Docker Compose)"
+msgstr ""
+
+msgid "DeploymentTarget|Serverless backend (Lambda, Cloud functions)"
+msgstr ""
+
+msgid "DeploymentTarget|Virtual machine (for example, EC2)"
+msgstr ""
+
msgid "Deployments"
msgstr ""
@@ -12107,6 +12289,9 @@ msgstr ""
msgid "Deployment|This deployment was created using the API"
msgstr ""
+msgid "Deployment|Triggerer"
+msgstr ""
+
msgid "Deployment|Waiting"
msgstr ""
@@ -12134,6 +12319,18 @@ msgstr ""
msgid "Deprecated API rate limits"
msgstr ""
+msgid "Deprecations|Feature deprecation and removal"
+msgstr ""
+
+msgid "Deprecations|For information on a possible replacement %{epicStart} learn more about Opstrace %{epicEnd}."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7 and are %{epicStart} scheduled for removal %{epicEnd} in GitLab 15.0."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7, and are %{removal_link_start} scheduled for removal %{link_end} in GitLab 15.0. For information on a possible replacement, %{opstrace_link_start} learn more about Opstrace %{link_end}."
+msgstr ""
+
msgid "Deprioritize label"
msgstr ""
@@ -12379,10 +12576,10 @@ msgstr ""
msgid "DevopsAdoption|At least one deploy"
msgstr ""
-msgid "DevopsAdoption|At least one issue opened"
+msgid "DevopsAdoption|At least one issue created"
msgstr ""
-msgid "DevopsAdoption|At least one merge request opened"
+msgid "DevopsAdoption|At least one merge request created"
msgstr ""
msgid "DevopsAdoption|At least one pipeline successfully run"
@@ -12583,6 +12780,9 @@ msgstr ""
msgid "Direct member"
msgstr ""
+msgid "Direct members"
+msgstr ""
+
msgid "Direct non-authenticated users to this page."
msgstr ""
@@ -12699,6 +12899,9 @@ msgid_plural "Dismiss %d selected vulnerabilities as"
msgstr[0] ""
msgstr[1] ""
+msgid "Dismiss Alert"
+msgstr ""
+
msgid "Dismiss merge request promotion"
msgstr ""
@@ -12726,9 +12929,15 @@ msgstr ""
msgid "Display alerts from all configured monitoring tools."
msgstr ""
+msgid "Display milestones"
+msgstr ""
+
msgid "Display name"
msgstr ""
+msgid "Display progress of child issues"
+msgstr ""
+
msgid "Display rendered file"
msgstr ""
@@ -12834,6 +13043,9 @@ msgstr ""
msgid "Download image"
msgstr ""
+msgid "Download payload"
+msgstr ""
+
msgid "Download raw data (.csv)"
msgstr ""
@@ -13011,6 +13223,9 @@ msgstr ""
msgid "Edit in Web IDE"
msgstr ""
+msgid "Edit in pipeline editor"
+msgstr ""
+
msgid "Edit in single-file editor"
msgstr ""
@@ -13053,6 +13268,9 @@ msgstr ""
msgid "Edit your most recent comment in a thread (from an empty textarea)"
msgstr ""
+msgid "Edit, lint, and visualize your pipeline."
+msgstr ""
+
msgid "Edited"
msgstr ""
@@ -13494,6 +13712,9 @@ msgstr ""
msgid "Enforce two-factor authentication for all user sign-ins."
msgstr ""
+msgid "Enhance security by storing service account keys in secret managers - learn more about %{docLinkStart}secret management with GitLab%{docLinkEnd}"
+msgstr ""
+
msgid "Ensure connectivity is available from the GitLab server to the Prometheus server"
msgstr ""
@@ -13554,6 +13775,9 @@ 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 following to confirm:"
+msgstr ""
+
msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
@@ -14084,9 +14308,6 @@ 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 ""
@@ -14222,6 +14443,9 @@ msgstr ""
msgid "Errors:"
msgstr ""
+msgid "Escalate this incident"
+msgstr ""
+
msgid "Escalation Policies"
msgstr ""
@@ -14234,6 +14458,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy"
+msgstr ""
+
msgid "Escalation policy:"
msgstr ""
@@ -14485,6 +14712,9 @@ msgstr ""
msgid "Existing sign in methods may be removed"
msgstr ""
+msgid "Exit."
+msgstr ""
+
msgid "Expand"
msgstr ""
@@ -14581,6 +14811,9 @@ msgstr ""
msgid "Explore public groups"
msgstr ""
+msgid "Explore public projects"
+msgstr ""
+
msgid "Explore snippets"
msgstr ""
@@ -14742,7 +14975,7 @@ msgid_plural "Failed to archive designs. Please try again."
msgstr[0] ""
msgstr[1] ""
-msgid "Failed to assign a reviewer because no user was found."
+msgid "Failed to assign a reviewer because no user was specified."
msgstr ""
msgid "Failed to assign a user because no user was found."
@@ -14808,10 +15041,10 @@ msgstr ""
msgid "Failed to find import label for Jira import."
msgstr ""
-msgid "Failed to generate export, please try again later."
+msgid "Failed to find users for %{missing}"
msgstr ""
-msgid "Failed to generate report, please try again after sometime"
+msgid "Failed to generate export, please try again later."
msgstr ""
msgid "Failed to get ref."
@@ -14910,6 +15143,9 @@ msgstr ""
msgid "Failed to remove a to-do item for the design."
msgstr ""
+msgid "Failed to remove attention because no user was found."
+msgstr ""
+
msgid "Failed to remove mirror."
msgstr ""
@@ -14922,6 +15158,9 @@ msgstr ""
msgid "Failed to remove user key."
msgstr ""
+msgid "Failed to request attention because no user was found."
+msgstr ""
+
msgid "Failed to reset key. Please try again."
msgstr ""
@@ -15003,6 +15242,9 @@ msgstr ""
msgid "Feature Flags"
msgstr ""
+msgid "Feature deprecation and removal"
+msgstr ""
+
msgid "Feature flag status"
msgstr ""
@@ -15500,7 +15742,7 @@ msgstr ""
msgid "For each job, re-use the project workspace. If the workspace doesn't exist, use %{code_open}git clone%{code_close}."
msgstr ""
-msgid "For example, the application using the token or the purpose of the token."
+msgid "For example, the application using the token or the purpose of the token. Do not give sensitive information for the name of the token, as it will be visible to all %{resource_type} members."
msgstr ""
msgid "For files larger than this limit, only index the file name. The file content is neither indexed nor searchable."
@@ -15584,9 +15826,6 @@ msgstr ""
msgid "ForkProject|Select a namespace"
msgstr ""
-msgid "ForkProject|Select a namespace to fork the project"
-msgstr ""
-
msgid "ForkProject|The project can be accessed by any logged in user."
msgstr ""
@@ -15683,6 +15922,9 @@ msgstr ""
msgid "Full name"
msgstr ""
+msgid "GCP region configured"
+msgstr ""
+
msgid "GPG Key ID:"
msgstr ""
@@ -15863,6 +16105,9 @@ msgstr ""
msgid "Geo|Failed"
msgstr ""
+msgid "Geo|Filter Geo sites"
+msgstr ""
+
msgid "Geo|Filter by name"
msgstr ""
@@ -16274,6 +16519,12 @@ msgstr ""
msgid "GitLab Issue"
msgstr ""
+msgid "GitLab KAS"
+msgstr ""
+
+msgid "GitLab Memberships CSV Export"
+msgstr ""
+
msgid "GitLab Pages"
msgstr ""
@@ -16322,6 +16573,9 @@ 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 free to use. Many features for larger teams are part of our %{link_start}paid products%{link_end}. You can try Ultimate for free without any obligation or payment details."
+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 ""
@@ -16448,7 +16702,7 @@ msgstr ""
msgid "GitLabPages|When enabled, all attempts to visit your website through HTTP are automatically redirected to HTTPS using a response with status code 301. Requires a valid certificate for all domains. %{docs_link_start}Learn more.%{link_end}"
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. %{docs_link_start}Learn more.%{link_end}"
+msgid "GitLabPages|When using Pages under the general domain of a GitLab instance (%{pages_host}), you cannot use HTTPS with subdomains of subdomains. If your namespace or groupname contains a dot, it does not work. This is a limitation of the HTTP Over TLS protocol. HTTP pages work if you don't redirect HTTP to HTTPS. %{docs_link_start}Learn more.%{link_end}"
msgstr ""
msgid "GitLabPages|With GitLab Pages you can host your static website directly from your GitLab repository. %{docs_link_start}Learn more.%{link_end}"
@@ -16625,9 +16879,6 @@ msgstr ""
msgid "Go to find file"
msgstr ""
-msgid "Go to fork"
-msgstr ""
-
msgid "Go to issue boards"
msgstr ""
@@ -16835,9 +17086,6 @@ msgstr ""
msgid "Group Hooks"
msgstr ""
-msgid "Group ID"
-msgstr ""
-
msgid "Group Owner must have signed in with SAML before enabling Group Managed Accounts"
msgstr ""
@@ -16865,9 +17113,6 @@ msgstr ""
msgid "Group by"
msgstr ""
-msgid "Group description"
-msgstr ""
-
msgid "Group description (optional)"
msgstr ""
@@ -16982,7 +17227,7 @@ msgstr ""
msgid "Group: %{name}"
msgstr ""
-msgid "GroupActivityMetrics|Issues opened"
+msgid "GroupActivityMetrics|Issues created"
msgstr ""
msgid "GroupActivityMetrics|Last 90 days"
@@ -16991,7 +17236,7 @@ msgstr ""
msgid "GroupActivityMetrics|Members added"
msgstr ""
-msgid "GroupActivityMetrics|Merge Requests opened"
+msgid "GroupActivityMetrics|Merge Requests created"
msgstr ""
msgid "GroupActivityMetrics|Recent activity"
@@ -17282,6 +17527,9 @@ msgstr ""
msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
+msgid "GroupSettings|Choose a group path that does not start with a dash or end with a period. It can also contain alphanumeric characters and underscores."
+msgstr ""
+
msgid "GroupSettings|Compliance frameworks"
msgstr ""
@@ -17315,7 +17563,7 @@ msgstr ""
msgid "GroupSettings|If not specified at the group or instance level, the default is %{default_initial_branch_name}. Does not affect existing repositories."
msgstr ""
-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."
+msgid "GroupSettings|If the parent group's visibility is lower than the group's current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility."
msgstr ""
msgid "GroupSettings|New runners registration token has been generated!"
@@ -17432,7 +17680,10 @@ msgstr ""
msgid "Groups and projects"
msgstr ""
-msgid "Groups and subgroups"
+msgid "Groups are a great way to organize projects and people."
+msgstr ""
+
+msgid "Groups are the best way to manage projects and members."
msgstr ""
msgid "Groups to synchronize"
@@ -17543,13 +17794,16 @@ msgstr ""
msgid "GroupsTree|Are you sure you want to leave the \"%{fullName}\" group?"
msgstr ""
-msgid "GroupsTree|Edit group"
+msgid "GroupsTree|Delete"
+msgstr ""
+
+msgid "GroupsTree|Edit"
msgstr ""
msgid "GroupsTree|Failed to leave the group. Please make sure you are not the only owner."
msgstr ""
-msgid "GroupsTree|Leave this group"
+msgid "GroupsTree|Leave group"
msgstr ""
msgid "GroupsTree|Loading groups"
@@ -17561,9 +17815,57 @@ msgstr ""
msgid "GroupsTree|No groups or projects matched your search"
msgstr ""
+msgid "GroupsTree|Options"
+msgstr ""
+
msgid "GroupsTree|Search by name"
msgstr ""
+msgid "Groups|Avatar will be removed. Are you sure?"
+msgstr ""
+
+msgid "Groups|Changing group URL can have unintended side effects."
+msgstr ""
+
+msgid "Groups|Checking group URL availability..."
+msgstr ""
+
+msgid "Groups|Enter a descriptive name for your group."
+msgstr ""
+
+msgid "Groups|Group ID"
+msgstr ""
+
+msgid "Groups|Group URL"
+msgstr ""
+
+msgid "Groups|Group avatar"
+msgstr ""
+
+msgid "Groups|Group description (optional)"
+msgstr ""
+
+msgid "Groups|Group name"
+msgstr ""
+
+msgid "Groups|Group path is available."
+msgstr ""
+
+msgid "Groups|Group path is unavailable. Path has been replaced with a suggested available path."
+msgstr ""
+
+msgid "Groups|Learn more"
+msgstr ""
+
+msgid "Groups|Must start with letter, digit, emoji, or underscore. Can also contain periods, dashes, spaces, and parentheses."
+msgstr ""
+
+msgid "Groups|Remove avatar"
+msgstr ""
+
+msgid "Groups|Save changes"
+msgstr ""
+
msgid "Guideline"
msgstr ""
@@ -17573,6 +17875,9 @@ msgstr ""
msgid "HAR file path or URL"
msgstr ""
+msgid "HTTP Archive (HAR)"
+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 ""
@@ -17973,6 +18278,9 @@ msgstr ""
msgid "INFO: Your SSH key is expiring soon. Please generate a new key."
msgstr ""
+msgid "IP"
+msgstr ""
+
msgid "IP Address"
msgstr ""
@@ -18009,6 +18317,9 @@ msgstr ""
msgid "IdentityVerification|Verify your identity"
msgstr ""
+msgid "IdentityVerification|You can always verify your account at a later time to create a group."
+msgstr ""
+
msgid "If any indexed field exceeds this limit, it is truncated to this number of characters. The rest of the content is neither indexed nor searchable. This does not apply to repository and wiki indexing. For unlimited characters, set this to 0."
msgstr ""
@@ -18066,6 +18377,9 @@ msgstr ""
msgid "If you add %{codeStart}needs%{codeEnd} to jobs in your pipeline you'll be able to view the %{codeStart}needs%{codeEnd} relationships between jobs in this tab as a %{linkStart}Directed Acyclic Graph (DAG)%{linkEnd}."
msgstr ""
+msgid "If you are added to a project, it will be displayed here."
+msgstr ""
+
msgid "If you did not initiate these sign-in attempts, please reach out to your administrator or enable two-factor authentication (2FA) on your account."
msgstr ""
@@ -18372,12 +18686,24 @@ msgstr ""
msgid "InProductMarketing|3 ways to dive into GitLab CI/CD"
msgstr ""
+msgid "InProductMarketing|A single application eliminates complex integrations, data chokepoints, and toolchain maintenance, resulting in greater productivity and lower cost."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features, build more efficiently, strengthen security and compliance."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features."
+msgstr ""
+
msgid "InProductMarketing|Actually, GitLab makes the team work (better)"
msgstr ""
msgid "InProductMarketing|And finally %{deploy_link} a Python application."
msgstr ""
+msgid "InProductMarketing|And many more..."
+msgstr ""
+
msgid "InProductMarketing|Are your runners ready?"
msgstr ""
@@ -18396,15 +18722,33 @@ msgstr ""
msgid "InProductMarketing|Blog"
msgstr ""
+msgid "InProductMarketing|Break down silos to coordinate seamlessly across development, operations, and security with a consistent experience across the development lifecycle."
+msgstr ""
+
+msgid "InProductMarketing|Burn up/down charts"
+msgstr ""
+
msgid "InProductMarketing|By enabling code owners and required merge approvals the right person will review the right MR. This is a win-win: cleaner code and a more efficient review process."
msgstr ""
msgid "InProductMarketing|Click on the number below that corresponds with your answer — 1 being very difficult, 5 being very easy."
msgstr ""
+msgid "InProductMarketing|Code owners"
+msgstr ""
+
msgid "InProductMarketing|Code owners and required merge approvals are part of the paid tiers of GitLab. You can start a free 30-day trial of GitLab Ultimate and enable these features in less than 5 minutes with no credit card required."
msgstr ""
+msgid "InProductMarketing|Code review analytics"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration across stages in GitLab"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration made easy"
+msgstr ""
+
msgid "InProductMarketing|Create a custom CI runner with just a few clicks"
msgstr ""
@@ -18414,12 +18758,21 @@ msgstr ""
msgid "InProductMarketing|Create a project in GitLab in 5 minutes"
msgstr ""
+msgid "InProductMarketing|Create well-defined workflows by using scoped labels on issues, merge requests, and epics. Labels with the same scope cannot be used together, which prevents conflicts."
+msgstr ""
+
msgid "InProductMarketing|Create your first project!"
msgstr ""
+msgid "InProductMarketing|Define who owns specific files or directories, so the right reviewers are suggested when a merge request introduces changes to those files."
+msgstr ""
+
msgid "InProductMarketing|Deliver Better Products Faster"
msgstr ""
+msgid "InProductMarketing|Dependency scanning"
+msgstr ""
+
msgid "InProductMarketing|Did you know teams that use GitLab are far more efficient?"
msgstr ""
@@ -18429,15 +18782,27 @@ msgstr ""
msgid "InProductMarketing|Dig in and create a project and a repo"
msgstr ""
+msgid "InProductMarketing|Discover Premium & Ultimate"
+msgstr ""
+
+msgid "InProductMarketing|Discover Premium & Ultimate."
+msgstr ""
+
msgid "InProductMarketing|Do you have a minute?"
msgstr ""
msgid "InProductMarketing|Do you have a teammate who would be perfect for this task?"
msgstr ""
+msgid "InProductMarketing|Dynamic application security testing"
+msgstr ""
+
msgid "InProductMarketing|Easy"
msgstr ""
+msgid "InProductMarketing|Epics"
+msgstr ""
+
msgid "InProductMarketing|Expand your DevOps journey with a free GitLab trial"
msgstr ""
@@ -18459,9 +18824,15 @@ msgstr ""
msgid "InProductMarketing|Feel the need for speed?"
msgstr ""
+msgid "InProductMarketing|Find and fix bottlenecks in your code review process by understanding how long open merge requests have been in review."
+msgstr ""
+
msgid "InProductMarketing|Find out how your teams are really doing"
msgstr ""
+msgid "InProductMarketing|Find out if your external libraries are safe. Run dependency scanning jobs that check for known vulnerabilities in your external libraries."
+msgstr ""
+
msgid "InProductMarketing|Follow our steps"
msgstr ""
@@ -18498,6 +18869,9 @@ msgstr ""
msgid "InProductMarketing|GitLab is better with teammates to help out!"
msgstr ""
+msgid "InProductMarketing|GitLab is infrastructure agnostic (supporting GCP, AWS, Azure, OpenShift, VMWare, On Prem, Bare Metal, and more), offering a consistent workflow experience – irrespective of the environment."
+msgstr ""
+
msgid "InProductMarketing|GitLab provides static application security testing (SAST), dynamic application security testing (DAST), container scanning, and dependency scanning to help you deliver secure applications along with license compliance."
msgstr ""
@@ -18588,21 +18962,36 @@ msgstr ""
msgid "InProductMarketing|It's also possible to simply %{external_repo_link} in order to take advantage of GitLab's CI/CD."
msgstr ""
+msgid "InProductMarketing|Keep your code quality high by defining who should approve merge requests and how many approvals are required."
+msgstr ""
+
msgid "InProductMarketing|Launch GitLab CI/CD in 20 minutes or less"
msgstr ""
+msgid "InProductMarketing|Lower cost of development"
+msgstr ""
+
+msgid "InProductMarketing|Make it easier to collaborate on high-level ideas by grouping related issues in an epic."
+msgstr ""
+
msgid "InProductMarketing|Making the switch? It's easier than you think to import your projects into GitLab. Move %{github_link}, or import something %{bitbucket_link}."
msgstr ""
msgid "InProductMarketing|Master the art of importing!"
msgstr ""
+msgid "InProductMarketing|Merge request approval rule"
+msgstr ""
+
msgid "InProductMarketing|Move on to easily creating a Pages website %{ci_template_link}"
msgstr ""
msgid "InProductMarketing|Multiple owners, confusing workstreams? We've got you covered"
msgstr ""
+msgid "InProductMarketing|Multiple required approvers"
+msgstr ""
+
msgid "InProductMarketing|Need an alternative to importing?"
msgstr ""
@@ -18615,18 +19004,33 @@ msgstr ""
msgid "InProductMarketing|Our tool brings all the things together"
msgstr ""
+msgid "InProductMarketing|Protect your web application by using DAST to examine for vulnerabilities in deployed environments."
+msgstr ""
+
msgid "InProductMarketing|Rapid development, simplified"
msgstr ""
msgid "InProductMarketing|Reduce Security & Compliance Risk"
msgstr ""
+msgid "InProductMarketing|Require multiple approvers on a merge request, so you know it's in good shape before it's merged."
+msgstr ""
+
+msgid "InProductMarketing|Roadmaps"
+msgstr ""
+
+msgid "InProductMarketing|Scoped labels"
+msgstr ""
+
msgid "InProductMarketing|Security that's integrated into your development lifecycle"
msgstr ""
msgid "InProductMarketing|Sometimes you're not ready to make a full transition to a new tool. If you're not ready to fully commit, %{mirroring_link} gives you a safe way to try out GitLab in parallel with your current tool."
msgstr ""
+msgid "InProductMarketing|Speed. Efficiency. Trust."
+msgstr ""
+
msgid "InProductMarketing|Spin up an autoscaling runner in GitLab"
msgstr ""
@@ -18636,6 +19040,9 @@ msgstr ""
msgid "InProductMarketing|Start a Self-Managed trial"
msgstr ""
+msgid "InProductMarketing|Start a free trial"
+msgstr ""
+
msgid "InProductMarketing|Start a free trial of GitLab Ultimate – no credit card required"
msgstr ""
@@ -18702,6 +19109,9 @@ msgstr ""
msgid "InProductMarketing|To understand and get the most out of GitLab, start at the beginning and %{project_link}. In GitLab, repositories are part of a project, so after you've created your project you can go ahead and %{repo_link}."
msgstr ""
+msgid "InProductMarketing|Track completed issues in a chart, so you can see how a milestone is progressing at a glance."
+msgstr ""
+
msgid "InProductMarketing|Try GitLab Ultimate for free"
msgstr ""
@@ -18738,6 +19148,9 @@ msgstr ""
msgid "InProductMarketing|Very easy"
msgstr ""
+msgid "InProductMarketing|Visualize your epics and milestones in a timeline."
+msgstr ""
+
msgid "InProductMarketing|Want to host GitLab on your servers?"
msgstr ""
@@ -18759,6 +19172,9 @@ msgstr ""
msgid "InProductMarketing|YouTube"
msgstr ""
+msgid "InProductMarketing|Your software, deployed your way"
+msgstr ""
+
msgid "InProductMarketing|Your teams can be more efficient"
msgstr ""
@@ -18879,9 +19295,18 @@ msgstr ""
msgid "IncidentManagement|No incidents to display."
msgstr ""
+msgid "IncidentManagement|None"
+msgstr ""
+
msgid "IncidentManagement|Open"
msgstr ""
+msgid "IncidentManagement|Page your team with escalation policies"
+msgstr ""
+
+msgid "IncidentManagement|Paged"
+msgstr ""
+
msgid "IncidentManagement|Published"
msgstr ""
@@ -18891,6 +19316,9 @@ msgstr ""
msgid "IncidentManagement|Severity"
msgstr ""
+msgid "IncidentManagement|Status"
+msgstr ""
+
msgid "IncidentManagement|There are no closed incidents"
msgstr ""
@@ -18909,6 +19337,9 @@ msgstr ""
msgid "IncidentManagement|Unpublished"
msgstr ""
+msgid "IncidentManagement|Use escalation policies to automatically page your team when incidents are created."
+msgstr ""
+
msgid "IncidentSettings|Activate \"time to SLA\" countdown timer"
msgstr ""
@@ -18954,7 +19385,10 @@ msgstr ""
msgid "Incidents"
msgstr ""
-msgid "Incidents|Add a URL"
+msgid "Incidents|Add image details"
+msgstr ""
+
+msgid "Incidents|Add text or a link to display with your image. If you don't add either, the file name displays instead."
msgstr ""
msgid "Incidents|Drop or %{linkStart}upload%{linkEnd} a metric screenshot to attach it to the incident"
@@ -18969,10 +19403,10 @@ msgstr ""
msgid "Incidents|There was an issue loading metric images."
msgstr ""
-msgid "Incidents|There was an issue uploading your image."
+msgid "Incidents|There was an issue updating your image."
msgstr ""
-msgid "Incidents|You can optionally add a URL to link users to the original graph."
+msgid "Incidents|There was an issue uploading your image."
msgstr ""
msgid "Incident|Alert details"
@@ -18981,9 +19415,18 @@ msgstr ""
msgid "Incident|Are you sure you wish to delete this image?"
msgstr ""
+msgid "Incident|Delete image"
+msgstr ""
+
msgid "Incident|Deleting %{filename}"
msgstr ""
+msgid "Incident|Edit image text or link"
+msgstr ""
+
+msgid "Incident|Editing %{filename}"
+msgstr ""
+
msgid "Incident|Metrics"
msgstr ""
@@ -19253,12 +19696,18 @@ msgstr ""
msgid "Integrations|Branches for which notifications are to be sent"
msgstr ""
+msgid "Integrations|Clear if using a self-signed certificate."
+msgstr ""
+
msgid "Integrations|Comment detail:"
msgstr ""
msgid "Integrations|Comment settings:"
msgstr ""
+msgid "Integrations|Connection details"
+msgstr ""
+
msgid "Integrations|Connection failed. Please check your settings."
msgstr ""
@@ -19283,6 +19732,9 @@ msgstr ""
msgid "Integrations|Enable GitLab.com slash commands in a Slack workspace."
msgstr ""
+msgid "Integrations|Enable SSL verification"
+msgstr ""
+
msgid "Integrations|Enable comments"
msgstr ""
@@ -19361,6 +19813,9 @@ msgstr ""
msgid "Integrations|Return to GitLab for Jira"
msgstr ""
+msgid "Integrations|SSL verification"
+msgstr ""
+
msgid "Integrations|Save settings?"
msgstr ""
@@ -19406,9 +19861,6 @@ msgstr ""
msgid "Integrations|Use default settings"
msgstr ""
-msgid "Integrations|When you mention a Jira issue in a commit or merge request, GitLab creates a remote link and comment (if enabled)."
-msgstr ""
-
msgid "Integrations|You can now close this window and return to the GitLab for Jira application."
msgstr ""
@@ -19433,9 +19885,6 @@ msgstr ""
msgid "Integrations|can't exceed %{recipients_limit}"
msgstr ""
-msgid "Interactive developer security education."
-msgstr ""
-
msgid "Interactive mode"
msgstr ""
@@ -19925,6 +20374,9 @@ msgstr ""
msgid "IssueAnalytics|Assignees"
msgstr ""
+msgid "IssueAnalytics|Created by"
+msgstr ""
+
msgid "IssueAnalytics|Due date"
msgstr ""
@@ -19937,9 +20389,6 @@ msgstr ""
msgid "IssueAnalytics|Milestone"
msgstr ""
-msgid "IssueAnalytics|Opened by"
-msgstr ""
-
msgid "IssueAnalytics|Status"
msgstr ""
@@ -20063,10 +20512,10 @@ msgstr ""
msgid "IssuesAnalytics|Avg/Month:"
msgstr ""
-msgid "IssuesAnalytics|Issues opened"
+msgid "IssuesAnalytics|Issues created"
msgstr ""
-msgid "IssuesAnalytics|Issues opened per month"
+msgid "IssuesAnalytics|Issues created per month"
msgstr ""
msgid "IssuesAnalytics|Last 12 months"
@@ -20093,6 +20542,9 @@ msgstr ""
msgid "It looks like you have some draft commits in this branch."
msgstr ""
+msgid "It looks like you're attempting to activate your subscription. Use %{a_start}the Subscription page%{a_end} instead."
+msgstr ""
+
msgid "It may be several days before you see feature usage data."
msgstr ""
@@ -20321,6 +20773,9 @@ msgstr ""
msgid "JiraConnect|You can now close this window and return to Jira."
msgstr ""
+msgid "JiraConnect|You don't have permission to create branches for this project. Select a different project or contact the project owner for access. %{linkStart}Learn more.%{linkEnd}"
+msgstr ""
+
msgid "JiraRequest|A connection error occurred while connecting to Jira. Try your request again."
msgstr ""
@@ -20369,13 +20824,13 @@ msgstr ""
msgid "JiraService|Define the type of Jira issue to create from a vulnerability."
msgstr ""
-msgid "JiraService|Displaying Jira issues while leaving the GitLab issue functionality enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
+msgid "JiraService|Displaying Jira issues while leaving GitLab issues also enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
msgstr ""
-msgid "JiraService|Enable Jira issues"
+msgid "JiraService|Enable Jira issue creation from vulnerabilities"
msgstr ""
-msgid "JiraService|Enable Jira issues creation from vulnerabilities"
+msgid "JiraService|Enable Jira issues"
msgstr ""
msgid "JiraService|Enable Jira transitions"
@@ -20492,16 +20947,19 @@ msgstr ""
msgid "JiraService|View Jira issues in GitLab"
msgstr ""
-msgid "JiraService|Warning: All GitLab users that have access to this GitLab project are able to view all issues from the Jira project specified below."
+msgid "JiraService|Warning: All GitLab users with access to this GitLab project can view all issues from the Jira project you select."
msgstr ""
msgid "JiraService|Web URL"
msgstr ""
-msgid "JiraService|Work on Jira issues without leaving GitLab. Adds a Jira menu to access your list of Jira issues and view any issue as read-only."
+msgid "JiraService|When a Jira issue is mentioned in a commit or merge request, a remote link and comment (if enabled) will be created."
+msgstr ""
+
+msgid "JiraService|Work on Jira issues without leaving GitLab. Add a Jira menu to access a read-only list of your Jira issues."
msgstr ""
-msgid "JiraService|You need to configure Jira before enabling this integration. For more details, read the %{jira_doc_link_start}Jira integration documentation%{link_end}."
+msgid "JiraService|You must configure Jira before enabling this integration. %{jira_doc_link_start}Learn more.%{link_end}"
msgstr ""
msgid "Job"
@@ -20513,9 +20971,6 @@ msgstr ""
msgid "Job Failed #%{build_id}"
msgstr ""
-msgid "Job ID"
-msgstr ""
-
msgid "Job artifact"
msgstr ""
@@ -20582,9 +21037,27 @@ msgstr ""
msgid "Jobs|You're about to retry a job that failed because it attempted to deploy code that is older than the latest deployment. Retrying this job could result in overwriting the environment with the older source code."
msgstr ""
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source} into %{target}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{ref}"
+msgstr ""
+
+msgid "Job|Are you sure you want to erase this job log and artifacts?"
+msgstr ""
+
msgid "Job|Browse"
msgstr ""
+msgid "Job|Cancel"
+msgstr ""
+
msgid "Job|Complete Raw"
msgstr ""
@@ -20594,6 +21067,9 @@ msgstr ""
msgid "Job|Erase job log and artifacts"
msgstr ""
+msgid "Job|Finished at"
+msgstr ""
+
msgid "Job|Job artifacts"
msgstr ""
@@ -20606,7 +21082,7 @@ msgstr ""
msgid "Job|Keep"
msgstr ""
-msgid "Job|Pipeline"
+msgid "Job|Retry"
msgstr ""
msgid "Job|Scroll to bottom"
@@ -20618,6 +21094,9 @@ msgstr ""
msgid "Job|Show complete raw"
msgstr ""
+msgid "Job|Status"
+msgstr ""
+
msgid "Job|The artifacts were removed"
msgstr ""
@@ -20645,21 +21124,12 @@ msgstr ""
msgid "Job|delayed"
msgstr ""
-msgid "Job|for"
-msgstr ""
-
-msgid "Job|into"
-msgstr ""
-
msgid "Job|manual"
msgstr ""
msgid "Job|triggered"
msgstr ""
-msgid "Job|with"
-msgstr ""
-
msgid "Join Zoom meeting"
msgstr ""
@@ -20762,9 +21232,6 @@ msgstr ""
msgid "Ki"
msgstr ""
-msgid "Kontra"
-msgstr ""
-
msgid "Kroki"
msgstr ""
@@ -21088,6 +21555,9 @@ msgstr ""
msgid "Learn more about Auto DevOps"
msgstr ""
+msgid "Learn more about GitLab"
+msgstr ""
+
msgid "Learn more about Needs relationships"
msgstr ""
@@ -21415,9 +21885,18 @@ msgstr ""
msgid "Licenses|Displays licenses detected in the project, based on the %{linkStart}latest successful%{linkEnd} scan"
msgstr ""
+msgid "Licenses|Drag your license file here or %{linkStart}click to upload%{linkEnd}."
+msgstr ""
+
+msgid "Licenses|Drop your license file to start the upload."
+msgstr ""
+
msgid "Licenses|Error fetching the license list. Please check your network connection and try again."
msgstr ""
+msgid "Licenses|Error: You are trying to upload something other than a file"
+msgstr ""
+
msgid "Licenses|License Compliance"
msgstr ""
@@ -21436,6 +21915,9 @@ msgstr ""
msgid "Licenses|Specified policies in this project"
msgstr ""
+msgid "Licenses|The file could not be uploaded."
+msgstr ""
+
msgid "Licenses|The license list details information about the licenses used within your project."
msgstr ""
@@ -21469,11 +21951,6 @@ msgstr ""
msgid "Limit the size of Sidekiq jobs stored in Redis."
msgstr ""
-msgid "Limited to showing %d event at most"
-msgid_plural "Limited to showing %d events at most"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Limiting mode"
msgstr ""
@@ -21483,6 +21960,9 @@ msgstr ""
msgid "Link"
msgstr ""
+msgid "Link (optional)"
+msgstr ""
+
msgid "Link Prometheus monitoring to GitLab."
msgstr ""
@@ -21519,6 +21999,9 @@ msgstr ""
msgid "Linked emails (%{email_count})"
msgstr ""
+msgid "Linked epics"
+msgstr ""
+
msgid "Linked issues"
msgstr ""
@@ -21546,6 +22029,15 @@ msgstr ""
msgid "List of all merge commits"
msgstr ""
+msgid "List of environments for this project"
+msgstr ""
+
+msgid "List of suitable GCP locations"
+msgstr ""
+
+msgid "List of users allowed to exceed the rate limit."
+msgstr ""
+
msgid "List options"
msgstr ""
@@ -21765,6 +22257,9 @@ msgstr ""
msgid "Maintenance mode"
msgstr ""
+msgid "Make adjustments to how your GitLab instance is set up."
+msgstr ""
+
msgid "Make and review changes in the browser with the Web IDE"
msgstr ""
@@ -21909,6 +22404,12 @@ msgstr ""
msgid "MarkdownEditor|Add italic text (%{modifier_key}I)"
msgstr ""
+msgid "MarkdownEditor|Add strikethrough text (%{modifierKey}⇧X)"
+msgstr ""
+
+msgid "MarkdownEditor|Add strikethrough text (%{modifier_key}⇧X)"
+msgstr ""
+
msgid "Marked For Deletion At - %{deletion_time}"
msgstr ""
@@ -22170,6 +22671,9 @@ msgstr ""
msgid "Maximum push size (MB)"
msgstr ""
+msgid "Maximum requests per 10 minutes per user"
+msgstr ""
+
msgid "Maximum requests per minute"
msgstr ""
@@ -22260,6 +22764,19 @@ msgstr ""
msgid "Members of a group may only view projects they have permission to access"
msgstr ""
+msgid "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seat in use and will be billed for the overage."
+msgid_plural "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seats in use and will be billed for the overage."
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "MembersOverage|You are about to incur additional charges"
+msgstr ""
+
+msgid "MembersOverage|Your subscription includes %d seat."
+msgid_plural "MembersOverage|Your subscription includes %d seats."
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Membership"
msgstr ""
@@ -22464,9 +22981,6 @@ msgstr ""
msgid "Merge request not merged"
msgstr ""
-msgid "Merge request pipelines 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 merge request pipelines."
-msgstr ""
-
msgid "Merge request reports"
msgstr ""
@@ -22563,13 +23077,13 @@ msgstr ""
msgid "MergeRequests|Create issue to resolve thread"
msgstr ""
-msgid "MergeRequests|Failed to squash. Should be done manually."
+msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Saving the comment failed"
+msgid "MergeRequests|Squashing failed: Squash the commits locally, resolve any conflicts, then push the branch."
msgstr ""
-msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
+msgid "MergeRequests|Squashing not allowed: This project doesn't allow you to squash commits when merging."
msgstr ""
msgid "MergeRequests|Thread stays resolved"
@@ -23410,6 +23924,18 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "MrList|Assigned to %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from assignee %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from reviewer %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Review requested from %{name}, go to their profile."
+msgstr ""
+
msgid "Multi-project"
msgstr ""
@@ -23443,7 +23969,7 @@ msgstr ""
msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "My Awesome Group"
+msgid "My awesome group"
msgstr ""
msgid "My company or team"
@@ -24065,9 +24591,6 @@ msgstr ""
msgid "No available branches"
msgstr ""
-msgid "No available groups to fork the project."
-msgstr ""
-
msgid "No branches found"
msgstr ""
@@ -24278,6 +24801,9 @@ msgstr ""
msgid "No ref selected"
msgstr ""
+msgid "No regions configured"
+msgstr ""
+
msgid "No related merge requests found."
msgstr ""
@@ -25082,6 +25608,9 @@ msgstr ""
msgid "Only reCAPTCHA v2 is supported:"
msgstr ""
+msgid "Only required if not using role instance credentials."
+msgstr ""
+
msgid "Only use lowercase letters, numbers, and underscores."
msgstr ""
@@ -25106,9 +25635,6 @@ msgstr ""
msgid "Open a CLI and connect to the cluster you want to install the agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
-msgid "Open epics"
-msgstr ""
-
msgid "Open errors"
msgstr ""
@@ -25148,7 +25674,7 @@ msgstr ""
msgid "Opened issues"
msgstr ""
-msgid "OpenedNDaysAgo|Opened"
+msgid "OpenedNDaysAgo|Created"
msgstr ""
msgid "Opens in a new window"
@@ -25193,9 +25719,6 @@ msgstr ""
msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
-msgid "Optional."
-msgstr ""
-
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
msgstr ""
@@ -25984,6 +26507,9 @@ msgstr ""
msgid "PerformanceBar|Memory"
msgstr ""
+msgid "PerformanceBar|Memory report"
+msgstr ""
+
msgid "PerformanceBar|Redis calls"
msgstr ""
@@ -26017,18 +26543,12 @@ msgstr ""
msgid "PerformanceBar|wall"
msgstr ""
-msgid "Performs a rebase but skips triggering a new pipeline"
-msgstr ""
-
msgid "Period in seconds"
msgstr ""
msgid "Permalink"
msgstr ""
-msgid "Permanently delete project"
-msgstr ""
-
msgid "Permanently remove group"
msgstr ""
@@ -26299,6 +26819,51 @@ msgstr ""
msgid "PipelineStatusTooltip|Pipeline: %{ci_status}"
msgstr ""
+msgid "PipelineWizardDefaultCommitMessage|Add %{filename}"
+msgstr ""
+
+msgid "PipelineWizardDefaultCommitMessage|Update %{filename}"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|At least one entry is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This field is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This value is not valid"
+msgstr ""
+
+msgid "PipelineWizardListWidget|add another step"
+msgstr ""
+
+msgid "PipelineWizardListWidget|remove step"
+msgstr ""
+
+msgid "PipelineWizard|Commit"
+msgstr ""
+
+msgid "PipelineWizard|Commit Message"
+msgstr ""
+
+msgid "PipelineWizard|Commit changes to your file"
+msgstr ""
+
+msgid "PipelineWizard|Commit file to Branch"
+msgstr ""
+
+msgid "PipelineWizard|Commit your new file"
+msgstr ""
+
+msgid "PipelineWizard|The file has been committed."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem committing the changes."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem while checking whether your file already exists in the specified branch."
+msgstr ""
+
msgid "Pipelines"
msgstr ""
@@ -26413,7 +26978,7 @@ msgstr ""
msgid "Pipelines|Project cache successfully reset."
msgstr ""
-msgid "Pipelines|Revoke"
+msgid "Pipelines|Revoke trigger"
msgstr ""
msgid "Pipelines|Something went wrong while cleaning runners cache."
@@ -26458,6 +27023,12 @@ msgstr ""
msgid "Pipelines|This is a child pipeline within the parent pipeline"
msgstr ""
+msgid "Pipelines|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipelines|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipelines|This pipeline will run code originating from a forked project merge request. This means that the code can potentially have security considerations like exposing CI variables."
msgstr ""
@@ -26500,9 +27071,6 @@ msgstr ""
msgid "Pipelines|Your changes have been successfully committed. Now redirecting to the new merge request page."
msgstr ""
-msgid "Pipelines|detached"
-msgstr ""
-
msgid "Pipelines|error"
msgstr ""
@@ -26512,10 +27080,13 @@ msgstr ""
msgid "Pipelines|latest"
msgstr ""
-msgid "Pipelines|stuck"
+msgid "Pipelines|merge request"
msgstr ""
-msgid "Pipelines|train"
+msgid "Pipelines|merge train"
+msgstr ""
+
+msgid "Pipelines|stuck"
msgstr ""
msgid "Pipelines|yaml invalid"
@@ -26647,6 +27218,12 @@ msgstr ""
msgid "Pipeline|This change will not change the overall test coverage if merged."
msgstr ""
+msgid "Pipeline|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipeline|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipeline|Trigger author"
msgstr ""
@@ -26671,6 +27248,12 @@ msgstr ""
msgid "Pipeline|for"
msgstr ""
+msgid "Pipeline|merge request"
+msgstr ""
+
+msgid "Pipeline|merge train"
+msgstr ""
+
msgid "Pipeline|on"
msgstr ""
@@ -26809,9 +27392,6 @@ msgstr ""
msgid "Please enter a valid time interval"
msgstr ""
-msgid "Please enter or upload a valid license."
-msgstr ""
-
msgid "Please enter your current password."
msgstr ""
@@ -26920,9 +27500,6 @@ msgstr ""
msgid "Please type %{phrase_code} to proceed or close this modal to cancel."
msgstr ""
-msgid "Please type the following to confirm:"
-msgstr ""
-
msgid "Please use this form to report to the admin users who create spam issues, comments or behave inappropriately."
msgstr ""
@@ -26950,12 +27527,27 @@ msgstr ""
msgid "Policies"
msgstr ""
+msgid "Policy '%{escalation_policy_name}' does not exist."
+msgstr ""
+
msgid "Policy management project does have any policies in %{policy_path}"
msgstr ""
msgid "Policy project doesn't exist"
msgstr ""
+msgid "PolicyRuleMultiSelect|%{firstLabel} +%{numberOfAdditionalLabels} more"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|All %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select all"
+msgstr ""
+
msgid "Polling interval multiplier"
msgstr ""
@@ -27184,6 +27776,9 @@ msgstr ""
msgid "Private projects can be created in your personal namespace with:"
msgstr ""
+msgid "Problem with %{name} command: %{message}."
+msgstr ""
+
msgid "Proceed"
msgstr ""
@@ -27658,6 +28253,9 @@ msgstr ""
msgid "Progress"
msgstr ""
+msgid "Progress tracking"
+msgstr ""
+
msgid "Project"
msgstr ""
@@ -27889,6 +28487,9 @@ msgstr ""
msgid "ProjectQualitySummary|Failure"
msgstr ""
+msgid "ProjectQualitySummary|Get insight into the overall percentage of tests in your project that succeed, fail and are skipped."
+msgstr ""
+
msgid "ProjectQualitySummary|Latest pipeline results"
msgstr ""
@@ -27907,6 +28508,12 @@ msgstr ""
msgid "ProjectQualitySummary|See project Code Coverage Statistics"
msgstr ""
+msgid "ProjectQualitySummary|Set up test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|Set up test runs (opens in a new tab)"
+msgstr ""
+
msgid "ProjectQualitySummary|Skipped"
msgstr ""
@@ -28183,13 +28790,19 @@ msgstr ""
msgid "ProjectSettings|LFS objects from this repository are available to forks. %{linkStart}How do I remove them?%{linkEnd}"
msgstr ""
+msgid "ProjectSettings|Learn about commit history."
+msgstr ""
+
+msgid "ProjectSettings|Leave empty to use default template."
+msgstr ""
+
msgid "ProjectSettings|Manage who can see the project in the public access directory."
msgstr ""
msgid "ProjectSettings|Manages large files such as audio, video, and graphics files."
msgstr ""
-msgid "ProjectSettings|Maximum 500 characters."
+msgid "ProjectSettings|Maximum %{maxLength} characters."
msgstr ""
msgid "ProjectSettings|Merge checks"
@@ -28330,6 +28943,9 @@ msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
msgstr ""
+msgid "ProjectSettings|The default template will be applied on save."
+msgstr ""
+
msgid "ProjectSettings|These checks must pass before merge requests can be merged."
msgstr ""
@@ -28384,6 +29000,9 @@ msgstr ""
msgid "ProjectSettings|What are badges?"
msgstr ""
+msgid "ProjectSettings|What are merge trains?"
+msgstr ""
+
msgid "ProjectSettings|When merge request pipelines are enabled in the CI/CD configuration file, pipelines validate the combined results of the source and target branches. %{link_start}How to configure merge request pipelines?%{link_end}"
msgstr ""
@@ -28501,6 +29120,9 @@ msgstr ""
msgid "Projects are organized into groups"
msgstr ""
+msgid "Projects are where you store your code, access issues, wiki and other features of GitLab."
+msgstr ""
+
msgid "Projects contributed to"
msgstr ""
@@ -28516,12 +29138,6 @@ msgstr ""
msgid "Projects to index"
msgstr ""
-msgid "Projects will be permanently deleted after a %{waiting_period}-day waiting period."
-msgstr ""
-
-msgid "Projects will be permanently deleted immediately."
-msgstr ""
-
msgid "Projects with critical vulnerabilities"
msgstr ""
@@ -28606,6 +29222,9 @@ msgstr ""
msgid "ProjectsNew|Import project"
msgstr ""
+msgid "ProjectsNew|Include a Getting Started README"
+msgstr ""
+
msgid "ProjectsNew|Initialize repository with a README"
msgstr ""
@@ -28621,6 +29240,9 @@ msgstr ""
msgid "ProjectsNew|Project description %{tag_start}(optional)%{tag_end}"
msgstr ""
+msgid "ProjectsNew|Recommended if you're new to GitLab"
+msgstr ""
+
msgid "ProjectsNew|Run CI/CD for external repository"
msgstr ""
@@ -29038,6 +29660,9 @@ msgstr ""
msgid "ProtectedBranch|Unprotect"
msgstr ""
+msgid "ProtectedBranch|Unprotect branch"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
@@ -29065,6 +29690,9 @@ msgstr ""
msgid "ProtectedEnvironment|Protected Environment (%{protected_environments_count})"
msgstr ""
+msgid "ProtectedEnvironment|Required approvals"
+msgstr ""
+
msgid "ProtectedEnvironment|Select an environment"
msgstr ""
@@ -29086,10 +29714,13 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|Unprotect tag"
+msgstr ""
+
msgid "ProtectedTags|default"
msgstr ""
-msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
+msgid "ProtectedTag|By default, protected tags restrict who can modify the tag."
msgstr ""
msgid "ProtectedTag|Learn more."
@@ -29152,6 +29783,9 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Public projects are an easy way to allow everyone to have read-only access."
+msgstr ""
+
msgid "Publish to status page"
msgstr ""
@@ -29308,9 +29942,6 @@ msgstr ""
msgid "QualitySummary|Project quality"
msgstr ""
-msgid "Quarters"
-msgstr ""
-
msgid "Query"
msgstr ""
@@ -29395,6 +30026,9 @@ msgstr ""
msgid "Read more about project permissions %{help_link_open}here%{help_link_close}"
msgstr ""
+msgid "Read more about related epics"
+msgstr ""
+
msgid "Read more about related issues"
msgstr ""
@@ -29425,10 +30059,7 @@ msgstr ""
msgid "Rebase source branch on the target branch."
msgstr ""
-msgid "Rebase without CI"
-msgstr ""
-
-msgid "Rebases and triggers a pipeline"
+msgid "Rebase without pipeline"
msgstr ""
msgid "Recaptcha verified?"
@@ -29479,9 +30110,6 @@ msgstr ""
msgid "Reconfigure"
msgstr ""
-msgid "Recovering projects"
-msgstr ""
-
msgid "Recovery Codes"
msgstr ""
@@ -29541,6 +30169,12 @@ msgstr ""
msgid "Regex pattern"
msgstr ""
+msgid "Region"
+msgstr ""
+
+msgid "Regions"
+msgstr ""
+
msgid "Register"
msgstr ""
@@ -29771,9 +30405,6 @@ msgstr ""
msgid "Remove all or specific reviewer(s)"
msgstr ""
-msgid "Remove approver"
-msgstr ""
-
msgid "Remove approvers"
msgstr ""
@@ -29789,6 +30420,9 @@ msgstr ""
msgid "Remove attention request"
msgstr ""
+msgid "Remove attention request(s)"
+msgstr ""
+
msgid "Remove avatar"
msgstr ""
@@ -29927,6 +30561,9 @@ msgstr ""
msgid "Removed an issue from an epic."
msgstr ""
+msgid "Removed attention from %{users_sentence}."
+msgstr ""
+
msgid "Removed attention request from @%{username}"
msgstr ""
@@ -29978,6 +30615,9 @@ msgstr ""
msgid "Removes an issue from an epic."
msgstr ""
+msgid "Removes attention from %{users_sentence}."
+msgstr ""
+
msgid "Removes parent epic %{epic_ref}."
msgstr ""
@@ -30089,6 +30729,9 @@ msgstr ""
msgid "Report abuse to admin"
msgstr ""
+msgid "Report is generating and will be sent to your email address."
+msgstr ""
+
msgid "Reported %{timeAgo} by %{reportedBy}"
msgstr ""
@@ -30378,6 +31021,15 @@ msgstr ""
msgid "Request attention"
msgstr ""
+msgid "Request attention from %{users_sentence}."
+msgstr ""
+
+msgid "Request attention from assignee or reviewer"
+msgstr ""
+
+msgid "Request attention from assignee(s) or reviewer(s)"
+msgstr ""
+
msgid "Request attention to review"
msgstr ""
@@ -30402,6 +31054,9 @@ msgstr ""
msgid "Requested %{time_ago}"
msgstr ""
+msgid "Requested attention from %{users_sentence}."
+msgstr ""
+
msgid "Requested attention from @%{username}"
msgstr ""
@@ -30616,6 +31271,9 @@ msgstr ""
msgid "Restore project"
msgstr ""
+msgid "Restoring projects"
+msgstr ""
+
msgid "Restoring the group will prevent the group, its subgroups and projects from being removed on this date."
msgstr ""
@@ -30646,6 +31304,9 @@ msgstr ""
msgid "Retry"
msgstr ""
+msgid "Retry failed jobs"
+msgstr ""
+
msgid "Retry job"
msgstr ""
@@ -30693,9 +31354,6 @@ msgstr ""
msgid "Review changes"
msgstr ""
-msgid "Review requested from %{name}"
-msgstr ""
-
msgid "Review requests for you"
msgstr ""
@@ -30860,6 +31518,9 @@ msgstr ""
msgid "Runners|Assigned Group"
msgstr ""
+msgid "Runners|Assigned Projects (%{projectCount})"
+msgstr ""
+
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30929,6 +31590,9 @@ msgstr ""
msgid "Runners|Instance"
msgstr ""
+msgid "Runners|Jobs"
+msgstr ""
+
msgid "Runners|Last contact"
msgstr ""
@@ -31022,9 +31686,6 @@ msgstr ""
msgid "Runners|Runner %{name} was deleted"
msgstr ""
-msgid "Runners|Runner ID"
-msgstr ""
-
msgid "Runners|Runner assigned to project."
msgstr ""
@@ -31172,6 +31833,9 @@ msgstr ""
msgid "Runners|stale"
msgstr ""
+msgid "Runner|This runner has not run any jobs."
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -31286,6 +31950,24 @@ msgstr ""
msgid "Saving project."
msgstr ""
+msgid "ScanResultPolicy|%{ifLabelStart}if%{ifLabelEnd} %{scanners} scan in an open merge request targeting the %{branches} branch(es) finds %{vulnerabilitiesAllowed} or more %{severities} vulnerabilities that are %{vulnerabilityStates}"
+msgstr ""
+
+msgid "ScanResultPolicy|%{thenLabelStart}Then%{thenLabelEnd} Require approval from %{approvalsRequired} of the following approvers: %{approvers}"
+msgstr ""
+
+msgid "ScanResultPolicy|add an approver"
+msgstr ""
+
+msgid "ScanResultPolicy|scanners"
+msgstr ""
+
+msgid "ScanResultPolicy|severity levels"
+msgstr ""
+
+msgid "ScanResultPolicy|vulnerability states"
+msgstr ""
+
msgid "Scanner"
msgstr ""
@@ -31418,6 +32100,9 @@ msgstr ""
msgid "Search for a user"
msgstr ""
+msgid "Search for an emoji"
+msgstr ""
+
msgid "Search for projects, issues, etc."
msgstr ""
@@ -31605,18 +32290,12 @@ msgstr ""
msgid "Secret Detection"
msgstr ""
-msgid "Secret access key"
-msgstr ""
-
msgid "Secret token"
msgstr ""
msgid "Secure token that identifies an external storage request."
msgstr ""
-msgid "SecureCodeWarrior"
-msgstr ""
-
msgid "Security"
msgstr ""
@@ -31641,9 +32320,6 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "Security training with guide and learning pathways."
-msgstr ""
-
msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
@@ -31746,7 +32422,7 @@ msgstr ""
msgid "SecurityConfiguration|Manage corpus"
msgstr ""
-msgid "SecurityConfiguration|Manage corpus files used as mutation sources in coverage fuzzing."
+msgid "SecurityConfiguration|Manage corpus files used as seed inputs with coverage-guided fuzzing."
msgstr ""
msgid "SecurityConfiguration|Manage profiles for use by DAST scans."
@@ -31812,15 +32488,15 @@ msgstr ""
msgid "SecurityOrchestration|.yaml preview"
msgstr ""
-msgid "SecurityOrchestration|Action"
-msgstr ""
-
msgid "SecurityOrchestration|Actions"
msgstr ""
msgid "SecurityOrchestration|Add rule"
msgstr ""
+msgid "SecurityOrchestration|After dismissing the alert, the information will never be shown again."
+msgstr ""
+
msgid "SecurityOrchestration|All policies"
msgstr ""
@@ -31836,7 +32512,7 @@ msgstr ""
msgid "SecurityOrchestration|Description"
msgstr ""
-msgid "SecurityOrchestration|Disabled"
+msgid "SecurityOrchestration|Don't show the alert anymore"
msgstr ""
msgid "SecurityOrchestration|Edit policy"
@@ -31845,13 +32521,13 @@ msgstr ""
msgid "SecurityOrchestration|Edit policy project"
msgstr ""
-msgid "SecurityOrchestration|Enabled"
+msgid "SecurityOrchestration|Empty policy name"
msgstr ""
-msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Enabled"
msgstr ""
-msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
msgstr ""
msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
@@ -31860,7 +32536,7 @@ msgstr ""
msgid "SecurityOrchestration|Invalid policy type"
msgstr ""
-msgid "SecurityOrchestration|Latest scan"
+msgid "SecurityOrchestration|Latest scan run against %{agent}"
msgstr ""
msgid "SecurityOrchestration|Network"
@@ -31869,15 +32545,27 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No actions defined - policy will not run."
+msgstr ""
+
+msgid "SecurityOrchestration|No description"
+msgstr ""
+
msgid "SecurityOrchestration|No rules defined - policy will not run."
msgstr ""
+msgid "SecurityOrchestration|Not enabled"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
msgid "SecurityOrchestration|Policies"
msgstr ""
+msgid "SecurityOrchestration|Policy Type"
+msgstr ""
+
msgid "SecurityOrchestration|Policy cannot be enabled for non-existing branches (%{branches})"
msgstr ""
@@ -31902,10 +32590,13 @@ msgstr ""
msgid "SecurityOrchestration|Require %{approvals} %{plural} from %{approvers} if any of the following occur:"
msgstr ""
-msgid "SecurityOrchestration|Rule"
+msgid "SecurityOrchestration|Rules"
msgstr ""
-msgid "SecurityOrchestration|Rules"
+msgid "SecurityOrchestration|Runs %{actions} and %{lastAction} scans"
+msgstr ""
+
+msgid "SecurityOrchestration|Runs a %{action} scan"
msgstr ""
msgid "SecurityOrchestration|Scan Execution"
@@ -31965,6 +32656,9 @@ msgstr ""
msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
+msgid "SecurityOrchestration|This view only shows scan results for the agent %{agent}. You can view scan results for all agents in the %{linkStart}Operational Vulnerabilities tab of the vulnerability report%{linkEnd}."
+msgstr ""
+
msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
@@ -32019,9 +32713,6 @@ msgstr ""
msgid "SecurityOrchestration|users with ids"
msgstr ""
-msgid "SecurityOrchestration|view results"
-msgstr ""
-
msgid "SecurityOrchestration|vulnerabilities"
msgstr ""
@@ -32691,22 +33382,19 @@ 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|In order to start using functions as a service, you must first install Knative on your Kubernetes cluster. %{linkStart}More information%{linkEnd}"
-msgstr ""
-
msgid "Serverless|Learn more about Serverless"
msgstr ""
msgid "Serverless|No functions available"
msgstr ""
-msgid "Serverless|Sign up for First Look"
+msgid "Serverless|Serverless was %{linkStart}deprecated%{linkEnd} in GitLab 14.3."
+msgstr ""
+
+msgid "Serverless|Serverless was %{postLinkStart}deprecated%{postLinkEnd}. But if you opt to use it, you must install Knative in your Kubernetes cluster first. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "Serverless|The deploy job has not finished."
@@ -32718,9 +33406,6 @@ 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 ""
@@ -32736,9 +33421,6 @@ msgstr ""
msgid "Service Account Key"
msgstr ""
-msgid "Service Accounts"
-msgstr ""
-
msgid "Service Accounts keys authorize GitLab to deploy your Google Cloud project"
msgstr ""
@@ -32748,10 +33430,10 @@ msgstr ""
msgid "Service Desk allows people to create issues in your GitLab instance without their own user account. It provides a unique email address for end users to create issues in a project. Replies can be sent either through the GitLab interface or by email. End users only see threads through email."
msgstr ""
-msgid "Service Usage Data"
+msgid "Service account generated successfully"
msgstr ""
-msgid "Service account generated successfully"
+msgid "Service accounts"
msgstr ""
msgid "Service ping is disabled in your configuration file, and cannot be enabled through this form."
@@ -32895,6 +33577,9 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
+msgid "Set the per-user rate limit for getting a user by ID via the API."
+msgstr ""
+
msgid "Set the per-user rate limit for notes created by web or API requests."
msgstr ""
@@ -33074,6 +33759,9 @@ msgstr ""
msgid "Shared runners details"
msgstr ""
+msgid "Shared runners enabled cannot be enabled until a valid credit card is on file"
+msgstr ""
+
msgid "Shared runners help link"
msgstr ""
@@ -33131,6 +33819,9 @@ msgstr ""
msgid "Show all issues."
msgstr ""
+msgid "Show all milestones"
+msgstr ""
+
msgid "Show all test cases."
msgstr ""
@@ -33167,6 +33858,9 @@ msgstr ""
msgid "Show file contents"
msgstr ""
+msgid "Show group milestones"
+msgstr ""
+
msgid "Show labels"
msgstr ""
@@ -33182,6 +33876,12 @@ msgstr ""
msgid "Show open epics"
msgstr ""
+msgid "Show project milestones"
+msgstr ""
+
+msgid "Show sub-group milestones"
+msgstr ""
+
msgid "Show the Closed list"
msgstr ""
@@ -33191,11 +33891,6 @@ msgstr ""
msgid "Show whitespace changes"
msgstr ""
-msgid "Showing %d event"
-msgid_plural "Showing %d events"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Showing %{conflict} between %{sourceBranch} and %{targetBranch}"
msgstr ""
@@ -33255,12 +33950,6 @@ msgstr ""
msgid "Sidebar|None"
msgstr ""
-msgid "Sidebar|Only numeral characters allowed"
-msgstr ""
-
-msgid "Sidebar|Weight"
-msgstr ""
-
msgid "Sidekiq job compression threshold (bytes)"
msgstr ""
@@ -33423,6 +34112,9 @@ msgstr ""
msgid "Slack logo"
msgstr ""
+msgid "SlackIntegration|Are you sure you want to remove this project from the Slack application?"
+msgstr ""
+
msgid "SlackIntegration|GitLab for Slack"
msgstr ""
@@ -33432,6 +34124,9 @@ msgstr ""
msgid "SlackIntegration|Project alias"
msgstr ""
+msgid "SlackIntegration|Remove project"
+msgstr ""
+
msgid "SlackIntegration|Select a GitLab project to link with your Slack workspace."
msgstr ""
@@ -33576,9 +34271,6 @@ msgstr ""
msgid "Something went wrong trying to load issue contacts."
msgstr ""
-msgid "Something went wrong when creating a work item. Please try again"
-msgstr ""
-
msgid "Something went wrong when reordering designs. Please try again"
msgstr ""
@@ -33672,9 +34364,6 @@ msgstr ""
msgid "Something went wrong while inserting your image. Please try again."
msgstr ""
-msgid "Something went wrong while merging this merge request. Please try again."
-msgstr ""
-
msgid "Something went wrong while obtaining the Let's Encrypt certificate."
msgstr ""
@@ -33996,10 +34685,10 @@ 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."
+msgid "SourcegraphAdmin|Learn more."
msgstr ""
-msgid "SourcegraphAdmin|More information"
+msgid "SourcegraphAdmin|Only public projects have code intelligence enabled and communicate with Sourcegraph."
msgstr ""
msgid "SourcegraphAdmin|Save changes"
@@ -34008,7 +34697,7 @@ msgstr ""
msgid "SourcegraphAdmin|Sourcegraph URL"
msgstr ""
-msgid "SourcegraphAdmin|e.g. https://sourcegraph.example.com"
+msgid "SourcegraphAdmin|https://sourcegraph.example.com"
msgstr ""
msgid "SourcegraphPreferences|This feature is experimental and currently limited to certain projects."
@@ -34143,6 +34832,9 @@ msgstr ""
msgid "Start date"
msgstr ""
+msgid "Start free trial"
+msgstr ""
+
msgid "Start merge train"
msgstr ""
@@ -34173,6 +34865,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started escalation for this incident."
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -34185,6 +34880,9 @@ msgstr ""
msgid "Starts at (UTC)"
msgstr ""
+msgid "Starts escalations for this incident"
+msgstr ""
+
msgid "Starts on"
msgstr ""
@@ -34446,6 +35144,9 @@ msgstr ""
msgid "Strikethrough"
msgstr ""
+msgid "Strikethrough text"
+msgstr ""
+
msgid "Subgroup information"
msgstr ""
@@ -34680,6 +35381,21 @@ msgstr ""
msgid "Subscriptions"
msgstr ""
+msgid "Subscriptions|Chat with sales"
+msgstr ""
+
+msgid "Subscriptions|Close"
+msgstr ""
+
+msgid "Subscriptions|Not ready to buy yet?"
+msgstr ""
+
+msgid "Subscriptions|Start a free trial"
+msgstr ""
+
+msgid "Subscriptions|We understand. Maybe you have some questions for our sales team, or maybe you'd like to try some of the paid features first. What would you like to do?"
+msgstr ""
+
msgid "Subscription|Your subscription for %{strong}%{namespace_name}%{strong_close} has expired and you are now on %{pricing_link_start}the GitLab Free tier%{pricing_link_end}. Don't worry, your data is safe. Get in touch with our support team (%{support_email}). They'll gladly help with your subscription renewal."
msgstr ""
@@ -34890,6 +35606,9 @@ msgstr ""
msgid "SuperSonics|Maximum users"
msgstr ""
+msgid "SuperSonics|Offline cloud"
+msgstr ""
+
msgid "SuperSonics|Paste your activation code"
msgstr ""
@@ -34956,6 +35675,12 @@ msgstr ""
msgid "SuperSonics|You do not have an active subscription"
msgstr ""
+msgid "SuperSonics|You have a future dated license"
+msgstr ""
+
+msgid "SuperSonics|You have added a license that activates on %{date}. Please see the subscription history table below for more details."
+msgstr ""
+
msgid "SuperSonics|You have successfully added a license that activates on %{date}. Please see the subscription history table below for more details."
msgstr ""
@@ -35115,6 +35840,9 @@ msgstr ""
msgid "Tag name is required"
msgstr ""
+msgid "Tag push"
+msgstr ""
+
msgid "Tag push events"
msgstr ""
@@ -35217,6 +35945,9 @@ msgstr ""
msgid "TagsPage|protected"
msgstr ""
+msgid "Take a look at the documentation to discover all of GitLab’s capabilities."
+msgstr ""
+
msgid "Target Branch"
msgstr ""
@@ -35619,6 +36350,9 @@ msgstr ""
msgid "Tests"
msgstr ""
+msgid "Text (optional)"
+msgstr ""
+
msgid "Text added to the body of all email messages. %{character_limit} character limit"
msgstr ""
@@ -35669,6 +36403,9 @@ msgstr ""
msgid "The CSV export will be created in the background. Once finished, it will be sent to %{email} in an attachment."
msgstr ""
+msgid "The CSV export you requested of all user memberships is attached to this email."
+msgstr ""
+
msgid "The GitLab subscription service (customers.gitlab.com) is currently experiencing an outage. You can monitor the status and get updates at %{linkStart}status.gitlab.com%{linkEnd}."
msgstr ""
@@ -35744,6 +36481,9 @@ 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 epic"
+msgstr ""
+
msgid "The current issue"
msgstr ""
@@ -35905,6 +36645,9 @@ msgstr ""
msgid "The latest pipeline for this merge request has failed."
msgstr ""
+msgid "The license key is invalid."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -35920,6 +36663,9 @@ msgstr ""
msgid "The license was successfully uploaded and will be active from %{starts_at}. You can see the details below."
msgstr ""
+msgid "The license you uploaded is invalid. If the issue persists, contact support at %{link}."
+msgstr ""
+
msgid "The list creation wizard is already open"
msgstr ""
@@ -36541,10 +37287,13 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} and everything this project contains. %{strongOpen}There is no going back%{strongClose}"
+msgstr ""
+
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains."
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}on %{date}%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains. %{strongOpen}There is no going back.%{strongClose}"
msgstr ""
msgid "This action will %{strongOpen}permanently remove%{strongClose} %{codeOpen}%{group}%{codeClose} %{strongOpen}immediately%{strongClose}."
@@ -36673,9 +37422,6 @@ msgstr ""
msgid "This file was modified for readability, and can't accept suggestions. Edit it directly."
msgstr ""
-msgid "This forked project has the following:"
-msgstr ""
-
msgid "This form is disabled in preview"
msgstr ""
@@ -36688,7 +37434,7 @@ msgstr ""
msgid "This group can't be removed because it is linked to a subscription. To remove this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
-msgid "This group can't be transfered because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
+msgid "This group can't be transferred because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
msgid "This group cannot be invited to a project inside a group with enforced SSO"
@@ -36715,6 +37461,9 @@ 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 incident is already escalated with '%{escalation_policy_name}'."
+msgstr ""
+
msgid "This invitation was sent to %{mail_to_invite_email}, but you are signed in as %{link_to_current_user} with email %{mail_to_current_user}."
msgstr ""
@@ -36733,9 +37482,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 merge train pipeline"
-msgstr ""
-
msgid "This is a private email address %{helpIcon} generated just for you. Anyone who has it can create issues or merge requests as if they were you. If that happens, %{resetLinkStart}reset this token%{resetLinkEnd}."
msgstr ""
@@ -36757,6 +37503,12 @@ msgstr ""
msgid "This is your current session"
msgstr ""
+msgid "This issue cannot be assigned to a confidential epic because it is public."
+msgstr ""
+
+msgid "This issue cannot be made public because it belongs to a confidential epic."
+msgstr ""
+
msgid "This issue is confidential and should only be visible to team members with at least Reporter access."
msgstr ""
@@ -36874,6 +37626,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 branch is protected from force push."
+msgstr ""
+
msgid "This merge request cannot be rebased while there are conflicts."
msgstr ""
@@ -36925,9 +37680,15 @@ msgstr ""
msgid "This pipeline was triggered by a schedule."
msgstr ""
+msgid "This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project"
msgstr ""
+msgid "This project can be restored until %{date}."
+msgstr ""
+
msgid "This project cannot be %{visibilityLevel} because the visibility of %{openShowLink}%{name}%{closeShowLink} is %{visibility}. To make this project %{visibilityLevel}, you must first %{openEditLink}change the visibility%{closeEditLink} of the parent group."
msgstr ""
@@ -36946,6 +37707,9 @@ msgstr ""
msgid "This project is %{strongStart}NOT%{strongEnd} a fork, and has the following:"
msgstr ""
+msgid "This project is %{strongStart}NOT%{strongEnd} a fork. This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -37637,6 +38401,9 @@ msgstr ""
msgid "Today"
msgstr ""
+msgid "Todos count"
+msgstr ""
+
msgid "Todos|Are you looking for things to do? Take a look at %{strongStart}%{openIssuesLinkStart}open issues%{openIssuesLinkEnd}%{strongEnd}, contribute to %{strongStart}%{mergeRequestLinkStart}a merge request%{mergeRequestLinkEnd}%{mergeRequestLinkEnd}%{strongEnd}, or mention someone in a comment to automatically assign them a new to-do item."
msgstr ""
@@ -37910,10 +38677,8 @@ msgstr ""
msgid "Trending"
msgstr ""
-msgid "Trials|%{planName} Trial %{enDash} %{num} day left"
-msgid_plural "Trials|%{planName} Trial %{enDash} %{num} days left"
-msgstr[0] ""
-msgstr[1] ""
+msgid "Trials|%{planName} Trial"
+msgstr ""
msgid "Trials|Compare all plans"
msgstr ""
@@ -37921,6 +38686,9 @@ msgstr ""
msgid "Trials|Create a new group to start your GitLab Ultimate trial."
msgstr ""
+msgid "Trials|Day %{daysUsed}/%{duration}"
+msgstr ""
+
msgid "Trials|Go back to GitLab"
msgstr ""
@@ -38170,7 +38938,7 @@ msgstr ""
msgid "URL is triggered when repository is updated"
msgstr ""
-msgid "URL must be percent-encoded if neccessary."
+msgid "URL must be percent-encoded if necessary."
msgstr ""
msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
@@ -38389,6 +39157,9 @@ msgstr ""
msgid "Unlock account"
msgstr ""
+msgid "Unlock more features with GitLab Ultimate"
+msgstr ""
+
msgid "Unlock the discussion"
msgstr ""
@@ -38452,6 +39223,9 @@ msgstr ""
msgid "Unsubscribes from this %{quick_action_target}."
msgstr ""
+msgid "Unsupported sort value."
+msgstr ""
+
msgid "Unsupported todo type passed. Supported todo types are: %{todo_types}"
msgstr ""
@@ -38680,6 +39454,9 @@ msgstr ""
msgid "UsageQuota|File attachments and smaller design graphics."
msgstr ""
+msgid "UsageQuota|From %{storage_enforcement_date} storage limits will apply to this namespace. View and manage your usage in %{strong_start}Group Settings &gt; Usage quotas%{strong_end}."
+msgstr ""
+
msgid "UsageQuota|Git repository."
msgstr ""
@@ -38740,6 +39517,9 @@ msgstr ""
msgid "UsageQuota|Storage type"
msgstr ""
+msgid "UsageQuota|Storage used"
+msgstr ""
+
msgid "UsageQuota|This is the total amount of storage used across your projects within this namespace."
msgstr ""
@@ -38935,6 +39715,12 @@ msgstr ""
msgid "Use hashed storage paths for newly created and renamed repositories. Always enabled since 13.0."
msgstr ""
+msgid "Use issue count"
+msgstr ""
+
+msgid "Use issue weight"
+msgstr ""
+
msgid "Use one line per URI"
msgstr ""
@@ -39316,6 +40102,9 @@ msgstr ""
msgid "Users"
msgstr ""
+msgid "Users API rate limit"
+msgstr ""
+
msgid "Users can launch a development environment from a GitLab browser tab when the %{linkStart}Gitpod%{linkEnd} integration is enabled."
msgstr ""
@@ -39641,6 +40430,9 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View group pipeline usage quota"
+msgstr ""
+
msgid "View incident details at"
msgstr ""
@@ -39793,6 +40585,9 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
+msgid "Vulnerability"
+msgstr ""
+
msgid "Vulnerability Report"
msgstr ""
@@ -39844,6 +40639,9 @@ msgstr ""
msgid "VulnerabilityManagement|An unverified non-confirmed finding"
msgstr ""
+msgid "VulnerabilityManagement|At least one identifier is required"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -39853,12 +40651,24 @@ msgstr ""
msgid "VulnerabilityManagement|Create Jira issue"
msgstr ""
+msgid "VulnerabilityManagement|Enter a name"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE code"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE identifier URL"
+msgstr ""
+
msgid "VulnerabilityManagement|Fetching linked Jira issues"
msgstr ""
msgid "VulnerabilityManagement|Manually add a vulnerability entry into the vulnerability report."
msgstr ""
+msgid "VulnerabilityManagement|Name is a required field"
+msgstr ""
+
msgid "VulnerabilityManagement|Needs triage"
msgstr ""
@@ -39874,6 +40684,18 @@ msgstr ""
msgid "VulnerabilityManagement|Select a method"
msgstr ""
+msgid "VulnerabilityManagement|Select a severity level"
+msgstr ""
+
+msgid "VulnerabilityManagement|Select a status"
+msgstr ""
+
+msgid "VulnerabilityManagement|Severity is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Something went wrong while creating vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -39898,6 +40720,12 @@ msgstr ""
msgid "VulnerabilityManagement|Something went wrong, could not update vulnerability state."
msgstr ""
+msgid "VulnerabilityManagement|Status is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Submit vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Summary, detailed description, steps to reproduce, etc."
msgstr ""
@@ -40093,6 +40921,9 @@ msgstr ""
msgid "WARNING:"
msgstr ""
+msgid "WARNING: This snippet contains hidden files which might be used to mask malicious behavior. Exercise caution if cloning and executing code from this snippet."
+msgstr ""
+
msgid "Wait for the file to load to copy its contents"
msgstr ""
@@ -40312,6 +41143,15 @@ msgstr ""
msgid "Webhooks|An issue is created, updated, closed, or reopened."
msgstr ""
+msgid "Webhooks|Are you sure you want to delete this group hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this project hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this webhook?"
+msgstr ""
+
msgid "Webhooks|Comments"
msgstr ""
@@ -40321,6 +41161,9 @@ msgstr ""
msgid "Webhooks|Confidential issues events"
msgstr ""
+msgid "Webhooks|Delete webhook"
+msgstr ""
+
msgid "Webhooks|Deployment events"
msgstr ""
@@ -40554,6 +41397,9 @@ msgstr ""
msgid "Wiki"
msgstr ""
+msgid "Wiki page"
+msgstr ""
+
msgid "Wiki page was successfully created."
msgstr ""
@@ -40659,7 +41505,7 @@ msgstr ""
msgid "WikiPageConflictMessage|Someone edited the page the same time you did. Please check out %{wikiLinkStart}the page%{wikiLinkEnd} and make sure your changes will not unintentionally remove theirs."
msgstr ""
-msgid "WikiPage|An error occured while trying to render the content editor. Please try again later."
+msgid "WikiPage|An error occurred while trying to render the content editor. Please try again later."
msgstr ""
msgid "WikiPage|Are you sure you want to switch back to the classic editor?"
@@ -40818,6 +41664,18 @@ msgstr ""
msgid "WorkItem|New Task"
msgstr ""
+msgid "WorkItem|Something went wrong when creating a work item. Please try again"
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching the work item. Please try again."
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching work item types. Please try again"
+msgstr ""
+
+msgid "WorkItem|Type"
+msgstr ""
+
msgid "WorkItem|Work Items"
msgstr ""
@@ -40884,7 +41742,10 @@ msgstr ""
msgid "You are about to add %{usersTag} people to the discussion. They will all receive a notification."
msgstr ""
-msgid "You are about to permanently delete this project"
+msgid "You are about to delete this forked project containing:"
+msgstr ""
+
+msgid "You are about to delete this project containing:"
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."
@@ -40905,6 +41766,9 @@ msgstr ""
msgid "You are attempting to update a file that has changed since you started editing it."
msgstr ""
+msgid "You are billed if you exceed this number. %{qsrOverageLinkStart}How does billing work?%{qsrOverageLinkEnd}"
+msgstr ""
+
msgid "You are connected to the Prometheus server, but there is currently no data to display."
msgstr ""
@@ -40962,6 +41826,9 @@ msgstr ""
msgid "You are not authorized to update this scanner profile"
msgstr ""
+msgid "You are not authorized to upload metric images"
+msgstr ""
+
msgid "You are now impersonating %{username}"
msgstr ""
@@ -41115,9 +41982,6 @@ msgstr ""
msgid "You can only upload one design when dropping onto an existing design."
msgstr ""
-msgid "You can recover this project until %{date}"
-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 ""
@@ -41166,9 +42030,6 @@ msgstr ""
msgid "You cannot write to this read-only GitLab instance."
msgstr ""
-msgid "You can’t %{tag_start}edit%{tag_end} files directly in this project. Fork this project and submit a merge request with your changes."
-msgstr ""
-
msgid "You can’t edit files directly in this project. Fork this project and submit a merge request with your changes."
msgstr ""
@@ -41321,9 +42182,6 @@ 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 set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
@@ -41354,12 +42212,6 @@ msgstr ""
msgid "You must have maintainer access to force delete a lock"
msgstr ""
-msgid "You must have permission to create a project in a group before forking."
-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 ""
@@ -41765,7 +42617,7 @@ msgstr ""
msgid "Your public email will be displayed on your public profile."
msgstr ""
-msgid "Your request for access could not be processed: %{error_meesage}"
+msgid "Your request for access could not be processed: %{error_message}"
msgstr ""
msgid "Your request for access has been queued for review."
@@ -41948,6 +42800,9 @@ msgstr ""
msgid "archived:"
msgstr ""
+msgid "artifacts"
+msgstr ""
+
msgid "assign yourself"
msgstr ""
@@ -41977,6 +42832,9 @@ msgstr[1] ""
msgid "branch name"
msgstr ""
+msgid "builds"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -42400,6 +43258,9 @@ msgstr ""
msgid "contact with same email already exists in group hierarchy"
msgstr ""
+msgid "container registry images"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -42439,6 +43300,9 @@ msgstr ""
msgid "data"
msgstr ""
+msgid "database"
+msgstr ""
+
msgid "date must not be after 9999-12-31"
msgstr ""
@@ -42462,9 +43326,6 @@ msgstr ""
msgid "design"
msgstr ""
-msgid "detached"
-msgstr ""
-
msgid "disabled"
msgstr ""
@@ -42713,7 +43574,7 @@ msgstr ""
msgid "is not a valid X509 certificate."
msgstr ""
-msgid "is not allowed for sign-up."
+msgid "is not allowed for sign-up. Please use your regular email address."
msgstr ""
msgid "is not allowed for this group."
@@ -42725,7 +43586,7 @@ msgstr ""
msgid "is not allowed since the group is not top-level group."
msgstr ""
-msgid "is not allowed."
+msgid "is not allowed. Please use your regular email address."
msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
@@ -42812,6 +43673,9 @@ msgstr ""
msgid "level: %{level}"
msgstr ""
+msgid "lfs objects"
+msgstr ""
+
msgid "limit of %{project_limit} reached"
msgstr ""
@@ -43031,6 +43895,9 @@ msgstr ""
msgid "mrWidget|Merge blocked: pipeline must succeed. It's waiting for a manual action to continue."
msgstr ""
+msgid "mrWidget|Merge blocked: pipeline must succeed. Push a commit that fixes the failure, or %{linkStart}learn about other solutions.%{linkEnd}"
+msgstr ""
+
msgid "mrWidget|Merge blocked: this merge request must be approved."
msgstr ""
@@ -43148,9 +44015,6 @@ msgstr ""
msgid "mrWidget|The changes were not merged into"
msgstr ""
-msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -43298,9 +44162,6 @@ msgstr ""
msgid "open issue"
msgstr ""
-msgid "opened %{timeAgo}"
-msgstr ""
-
msgid "or"
msgstr ""
@@ -43312,6 +44173,12 @@ msgid_plural "out of %d total tests"
msgstr[0] ""
msgstr[1] ""
+msgid "packages"
+msgstr ""
+
+msgid "pages"
+msgstr ""
+
msgid "parent"
msgid_plural "parents"
msgstr[0] ""
@@ -43461,6 +44328,9 @@ msgid_plural "replies"
msgstr[0] ""
msgstr[1] ""
+msgid "repositories"
+msgstr ""
+
msgid "repository:"
msgstr ""
@@ -43581,12 +44451,18 @@ msgstr ""
msgid "tag name"
msgstr ""
+msgid "terraform states"
+msgstr ""
+
msgid "the correct format."
msgstr ""
msgid "the file"
msgstr ""
+msgid "the following epic(s)"
+msgstr ""
+
msgid "the following issue(s)"
msgstr ""
@@ -43599,21 +44475,12 @@ msgstr ""
msgid "this document"
msgstr ""
-msgid "this issue cannot be assigned to a confidential epic since it is public"
-msgstr ""
-
-msgid "this issue cannot be made public since it belongs to a confidential epic"
-msgstr ""
-
msgid "time summary"
msgstr ""
msgid "toggle collapse"
msgstr ""
-msgid "train"
-msgstr ""
-
msgid "triggered"
msgstr ""
@@ -43742,3 +44609,6 @@ msgstr ""
msgid "{project}"
msgstr ""
+msgid "✔"
+msgstr ""
+
diff --git a/locale/uz_UZ/gitlab.po b/locale/uz_UZ/gitlab.po
index 8230fa9108a..2b19d6ad5ce 100644
--- a/locale/uz_UZ/gitlab.po
+++ b/locale/uz_UZ/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: uz\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2022-02-02 15:48\n"
+"PO-Revision-Date: 2022-03-01 20:41\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -146,6 +146,11 @@ msgid_plural "%d approvers (you've approved)"
msgstr[0] ""
msgstr[1] ""
+msgid "%d assigned issue"
+msgid_plural "%d assigned issues"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -421,8 +426,23 @@ msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
msgstr[1] ""
-msgid "%d vulnerability updated"
-msgid_plural "%d vulnerabilities updated"
+msgid "%d vulnerability set to confirmed"
+msgid_plural "%d vulnerabilities set to confirmed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to dismissed"
+msgid_plural "%d vulnerabilities set to dismissed"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to needs triage"
+msgid_plural "%d vulnerabilities set to needs triage"
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "%d vulnerability set to resolved"
+msgid_plural "%d vulnerabilities set to resolved"
msgstr[0] ""
msgstr[1] ""
@@ -510,6 +530,12 @@ msgstr[1] ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{completed} of %{total} issues closed"
+msgstr ""
+
+msgid "%{completed} of %{total} weight completed"
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -858,6 +884,9 @@ msgstr ""
msgid "%{openedIssues} open, %{closedIssues} closed"
msgstr ""
+msgid "%{percentage}%% issues closed"
+msgstr ""
+
msgid "%{percentage}%% weight completed"
msgstr ""
@@ -1287,6 +1316,9 @@ msgid_plural "- Users"
msgstr[0] ""
msgstr[1] ""
+msgid "- of - issues closed"
+msgstr ""
+
msgid "- of - weight completed"
msgstr ""
@@ -1429,7 +1461,7 @@ msgstr ""
msgid "1000+"
msgstr ""
-msgid "192.168.0.0/24"
+msgid "192.168.0.0/24 or 2001:0DB8:1234::/48"
msgstr ""
msgid "1st contribution!"
@@ -1741,13 +1773,13 @@ msgstr ""
msgid "AWS Access Key"
msgstr ""
-msgid "AWS Access Key. Only required if not using role instance credentials"
+msgid "AWS Secret Access Key"
msgstr ""
-msgid "AWS Secret Access Key"
+msgid "AWS access key ID (Optional)"
msgstr ""
-msgid "AWS Secret Access Key. Only required if not using role instance credentials"
+msgid "AWS secret access key (Optional)"
msgstr ""
msgid "AWS service error: %{error}"
@@ -1807,9 +1839,6 @@ msgstr ""
msgid "Access granted"
msgstr ""
-msgid "Access key ID"
-msgstr ""
-
msgid "Access requests"
msgstr ""
@@ -1984,7 +2013,7 @@ msgstr ""
msgid "Activity"
msgstr ""
-msgid "Activity|An error occured while retrieving activity. Reload the page to try again."
+msgid "Activity|An error occurred while retrieving activity. Reload the page to try again."
msgstr ""
msgid "Add"
@@ -2023,6 +2052,9 @@ msgstr ""
msgid "Add a %{type}"
msgstr ""
+msgid "Add a GCP region"
+msgstr ""
+
msgid "Add a GPG key"
msgstr ""
@@ -2074,6 +2106,9 @@ msgstr ""
msgid "Add a numbered list"
msgstr ""
+msgid "Add a related epic"
+msgstr ""
+
msgid "Add a related issue"
msgstr ""
@@ -2188,6 +2223,9 @@ msgstr ""
msgid "Add or subtract spent time"
msgstr ""
+msgid "Add people"
+msgstr ""
+
msgid "Add previously merged commits"
msgstr ""
@@ -2254,6 +2292,9 @@ msgstr ""
msgid "Add webhook"
msgstr ""
+msgid "Add your team members and others to GitLab."
+msgstr ""
+
msgid "Add/remove"
msgstr ""
@@ -3076,12 +3117,6 @@ msgstr ""
msgid "AdvancedSearch|Reindex required"
msgstr ""
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. Permanently deleting this project will %{strongStart}immediately delete%{strongEnd} its repositories and %{strongStart}all related resources%{strongEnd}, including issues, merge requests etc."
-msgstr ""
-
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. You will lose this project's repository and %{strongStart}all related resources%{strongEnd}, including issues and merge requests."
-msgstr ""
-
msgid "After a successful password update you will be redirected to login screen."
msgstr ""
@@ -3112,6 +3147,9 @@ msgstr ""
msgid "Akismet helps prevent the creation of spam issues in public projects."
msgstr ""
+msgid "Alert"
+msgstr ""
+
msgid "AlertManagement|Acknowledged"
msgstr ""
@@ -3484,9 +3522,6 @@ msgstr ""
msgid "All environments"
msgstr ""
-msgid "All epics"
-msgstr ""
-
msgid "All groups and projects"
msgstr ""
@@ -4223,12 +4258,15 @@ msgstr ""
msgid "ApplicationSettings|Approve users in the pending approval status?"
msgstr ""
-msgid "ApplicationSettings|By making this change, you will automatically approve %d user with the pending approval status."
-msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users with the pending approval status."
+msgid "ApplicationSettings|Approve users who are pending approval?"
+msgstr ""
+
+msgid "ApplicationSettings|By making this change, you will automatically approve %d user who is pending approval."
+msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users who are pending approval."
msgstr[0] ""
msgstr[1] ""
-msgid "ApplicationSettings|By making this change, you will automatically approve all users in pending approval status."
+msgid "ApplicationSettings|By making this change, you will automatically approve all users who are pending approval."
msgstr ""
msgid "ApplicationSettings|Denied domains for sign-ups"
@@ -4634,10 +4672,10 @@ msgstr ""
msgid "Archiving the project will make it entirely read-only. It is hidden from the dashboard and doesn't show up in searches. %{strong_start}The repository cannot be committed to, and no issues, comments, or other entities can be created.%{strong_end} %{link_start}Learn more.%{link_end}"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to delete this project?"
+msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
+msgid "Are you absolutely sure?"
msgstr ""
msgid "Are you sure that you want to archive this project?"
@@ -4673,12 +4711,18 @@ msgstr ""
msgid "Are you sure you want to delete this SSH key?"
msgstr ""
+msgid "Are you sure you want to delete this comment?"
+msgstr ""
+
msgid "Are you sure you want to delete this deploy key?"
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 label?"
+msgstr ""
+
msgid "Are you sure you want to delete this pipeline schedule?"
msgstr ""
@@ -4694,9 +4738,6 @@ msgstr ""
msgid "Are you sure you want to discard your changes?"
msgstr ""
-msgid "Are you sure you want to erase this build?"
-msgstr ""
-
msgid "Are you sure you want to import %d repository?"
msgid_plural "Are you sure you want to import %d repositories?"
msgstr[0] ""
@@ -4744,6 +4785,9 @@ msgstr ""
msgid "Are you sure you want to remove this list?"
msgstr ""
+msgid "Are you sure you want to remove this nickname?"
+msgstr ""
+
msgid "Are you sure you want to reset the health check token?"
msgstr ""
@@ -4756,10 +4800,10 @@ 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?"
+msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
msgstr ""
-msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
+msgid "Are you sure you want to revoke this project access token? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to stop this environment?"
@@ -4906,9 +4950,6 @@ msgstr ""
msgid "Assigned to %{assignee_name}"
msgstr ""
-msgid "Assigned to %{name}"
-msgstr ""
-
msgid "Assigned to me"
msgstr ""
@@ -4973,6 +5014,9 @@ msgstr[1] ""
msgid "Attaching the file failed."
msgstr ""
+msgid "Attention"
+msgstr ""
+
msgid "Audit Events"
msgstr ""
@@ -5135,6 +5179,12 @@ msgstr ""
msgid "Authorized applications (%{size})"
msgstr ""
+msgid "AuthorizedApplication|Are you sure you want to revoke this application?"
+msgstr ""
+
+msgid "AuthorizedApplication|Revoke application"
+msgstr ""
+
msgid "Authors: %{authors}"
msgstr ""
@@ -6328,6 +6378,9 @@ msgstr ""
msgid "CICDAnalytics|Shared Runners Usage"
msgstr ""
+msgid "CICDAnalytics|Shared runner pipeline minute duration by month"
+msgstr ""
+
msgid "CICDAnalytics|Shared runner usage"
msgstr ""
@@ -6469,6 +6522,9 @@ msgstr ""
msgid "Can create groups:"
msgstr ""
+msgid "Can not delete primary training"
+msgstr ""
+
msgid "Can't apply as the source branch was deleted."
msgstr ""
@@ -6802,9 +6858,6 @@ msgstr ""
msgid "Changing any setting here requires an application restart"
msgstr ""
-msgid "Changing group URL can have unintended side effects."
-msgstr ""
-
msgid "Charts can't be displayed as the request for data has timed out. %{documentationLink}"
msgstr ""
@@ -6892,9 +6945,6 @@ msgstr ""
msgid "Checking branch availability..."
msgstr ""
-msgid "Checking group URL availability..."
-msgstr ""
-
msgid "Checking group path availability..."
msgstr ""
@@ -7388,6 +7438,9 @@ msgstr ""
msgid "Clear recent searches"
msgstr ""
+msgid "Clear repository checks"
+msgstr ""
+
msgid "Clear search"
msgstr ""
@@ -7520,9 +7573,6 @@ msgstr ""
msgid "Closed MRs"
msgstr ""
-msgid "Closed epics"
-msgstr ""
-
msgid "Closed issues"
msgstr ""
@@ -7559,13 +7609,13 @@ msgstr ""
msgid "Cluster level"
msgstr ""
-msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
+msgid "Cluster type must be specified for Stages::ClusterEndpointInserter"
msgstr ""
msgid "ClusterAgents|%{name} successfully deleted"
msgstr ""
-msgid "ClusterAgents|%{number} of %{total} Agents"
+msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
@@ -7607,6 +7657,15 @@ msgstr ""
msgid "ClusterAgents|Agent never connected to GitLab"
msgstr ""
+msgid "ClusterAgents|Agent version mismatch"
+msgstr ""
+
+msgid "ClusterAgents|Agent version mismatch and update"
+msgstr ""
+
+msgid "ClusterAgents|Agent version update required"
+msgstr ""
+
msgid "ClusterAgents|All"
msgstr ""
@@ -7631,7 +7690,7 @@ msgstr ""
msgid "ClusterAgents|Configuration"
msgstr ""
-msgid "ClusterAgents|Connect a cluster through the Agent"
+msgid "ClusterAgents|Connect a cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connect existing cluster"
@@ -7640,13 +7699,13 @@ msgstr ""
msgid "ClusterAgents|Connect with a certificate"
msgstr ""
-msgid "ClusterAgents|Connect with agent"
+msgid "ClusterAgents|Connect with an agent"
msgstr ""
msgid "ClusterAgents|Connect with the GitLab Agent"
msgstr ""
-msgid "ClusterAgents|Connect your cluster through the Agent"
+msgid "ClusterAgents|Connect your cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connected"
@@ -7706,7 +7765,10 @@ msgstr ""
msgid "ClusterAgents|How to register an agent?"
msgstr ""
-msgid "ClusterAgents|Install new Agent"
+msgid "ClusterAgents|How to update an agent?"
+msgstr ""
+
+msgid "ClusterAgents|Install a new agent"
msgstr ""
msgid "ClusterAgents|Last connected %{timeAgo}."
@@ -7733,7 +7795,7 @@ msgstr ""
msgid "ClusterAgents|Never connected"
msgstr ""
-msgid "ClusterAgents|No Agents"
+msgid "ClusterAgents|No agents"
msgstr ""
msgid "ClusterAgents|No clusters connected through cluster certificates"
@@ -7793,6 +7855,9 @@ msgstr ""
msgid "ClusterAgents|The agent has not been connected in a long time. There might be a connectivity issue. Last contact was %{timeAgo}."
msgstr ""
+msgid "ClusterAgents|The agent version do not match each other across your cluster's pods. This can happen when a new agent version was just deployed and Kubernetes is shutting down the old pods."
+msgstr ""
+
msgid "ClusterAgents|The recommended installation method includes the token. If you want to follow the advanced installation method provided in the docs, make sure you save the token value before you close this window."
msgstr ""
@@ -7840,6 +7905,9 @@ msgstr ""
msgid "ClusterAgents|You will need to create a token to connect to your agent"
msgstr ""
+msgid "ClusterAgents|Your agent version is out of sync with your GitLab version (v%{version}), which might cause compatibility problems. Update the agent installed on your cluster to the most recent version."
+msgstr ""
+
msgid "ClusterAgents|Your instance doesn't have the %{linkStart}GitLab Agent Server (KAS)%{linkEnd} set up. Ask a GitLab Administrator to install it."
msgstr ""
@@ -8716,9 +8784,6 @@ msgstr ""
msgid "Comma-separated list of email addresses."
msgstr ""
-msgid "Comma-separated list of users allowed to exceed the rate limit."
-msgstr ""
-
msgid "Comma-separated, e.g. '1.1.1.1, 2.2.2.0/24'"
msgstr ""
@@ -9045,6 +9110,12 @@ msgstr ""
msgid "Confidential"
msgstr ""
+msgid "Confidential issue"
+msgstr ""
+
+msgid "Confidential note"
+msgstr ""
+
msgid "Confidentiality"
msgstr ""
@@ -9078,6 +9149,9 @@ msgstr ""
msgid "Configure Dependency Scanning in `.gitlab-ci.yml`, creating this file if it does not already exist"
msgstr ""
+msgid "Configure GitLab"
+msgstr ""
+
msgid "Configure GitLab runners to start using the Web Terminal. %{helpStart}Learn more.%{helpEnd}"
msgstr ""
@@ -9126,6 +9200,15 @@ msgstr ""
msgid "Configure pipelines to deploy web apps, backend services, APIs and static resources to Google Cloud"
msgstr ""
+msgid "Configure region"
+msgstr ""
+
+msgid "Configure region for environment"
+msgstr ""
+
+msgid "Configure regions"
+msgstr ""
+
msgid "Configure repository mirroring."
msgstr ""
@@ -9159,6 +9242,9 @@ msgstr ""
msgid "Configure which lists are shown for anyone who visits this board"
msgstr ""
+msgid "Configure your environments to be deployed to specific geographical regions"
+msgstr ""
+
msgid "Confirm"
msgstr ""
@@ -9861,10 +9947,10 @@ msgstr ""
msgid "CorpusManagement|Actions"
msgstr ""
-msgid "CorpusManagement|Corpus are used in fuzz testing as mutation source to Improve future testing."
+msgid "CorpusManagement|Corpus file"
msgstr ""
-msgid "CorpusManagement|Corpus file"
+msgid "CorpusManagement|Corpus files are used in coverage-guided fuzz testing as seed inputs to improve testing."
msgstr ""
msgid "CorpusManagement|Corpus files must be in *.zip format. Maximum 5 GB"
@@ -9918,6 +10004,9 @@ msgstr ""
msgid "Could not apply %{name} command."
msgstr ""
+msgid "Could not apply %{name} command. %{message}."
+msgstr ""
+
msgid "Could not authorize chat nickname. Try again!"
msgstr ""
@@ -10068,6 +10157,9 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
+msgid "Create a group"
+msgstr ""
+
msgid "Create a merge request"
msgstr ""
@@ -10092,6 +10184,9 @@ msgstr ""
msgid "Create a personal access token on your account to pull or push via %{protocol}."
msgstr ""
+msgid "Create a project"
+msgstr ""
+
msgid "Create an account using:"
msgstr ""
@@ -10455,6 +10550,9 @@ msgstr ""
msgid "Creation date"
msgstr ""
+msgid "Creator"
+msgstr ""
+
msgid "Credentials"
msgstr ""
@@ -10467,9 +10565,15 @@ msgstr ""
msgid "CredentialsInventory|Personal Access Tokens"
msgstr ""
+msgid "CredentialsInventory|Project Access Tokens"
+msgstr ""
+
msgid "CredentialsInventory|SSH Keys"
msgstr ""
+msgid "Credit card required to be on file in order to create a pipeline"
+msgstr ""
+
msgid "Credit card:"
msgstr ""
@@ -10653,9 +10757,6 @@ msgstr ""
msgid "Customer relations"
msgstr ""
-msgid "Customizable by an administrator."
-msgstr ""
-
msgid "Customizable by owners."
msgstr ""
@@ -10785,30 +10886,18 @@ msgstr ""
msgid "CycleAnalytics|%{selectedLabelsCount} selected (%{maxLabels} max)"
msgstr ""
-msgid "CycleAnalytics|%{stageCount} stages selected"
-msgstr ""
-
-msgid "CycleAnalytics|All stages"
-msgstr ""
-
-msgid "CycleAnalytics|Average days to completion"
+msgid "CycleAnalytics|Average time to completion"
msgstr ""
msgid "CycleAnalytics|Date"
msgstr ""
-msgid "CycleAnalytics|Days to completion"
-msgstr ""
-
msgid "CycleAnalytics|Display chart filters"
msgstr ""
msgid "CycleAnalytics|Lead Time for Changes"
msgstr ""
-msgid "CycleAnalytics|No stages selected"
-msgstr ""
-
msgid "CycleAnalytics|Number of tasks"
msgstr ""
@@ -10837,18 +10926,30 @@ msgstr ""
msgid "CycleAnalytics|Showing data for group '%{groupName}' from %{createdAfter} to %{createdBefore}"
msgstr ""
-msgid "CycleAnalytics|Stages"
+msgid "CycleAnalytics|Stage time: %{title}"
msgstr ""
msgid "CycleAnalytics|Tasks by type"
msgstr ""
-msgid "CycleAnalytics|The average time spent in the selected stage for the items that were completed on each date. Data limited to the last 500 items."
+msgid "CycleAnalytics|The average time items spent in this stage. Data limited to items completed within this date range."
msgstr ""
msgid "CycleAnalytics|The given date range is larger than 180 days"
msgstr ""
+msgid "CycleAnalytics|The total time items spent across each value stream stage. Data limited to items completed within this date range."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Stage time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Total time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|Total time"
+msgstr ""
+
msgid "CycleAnalytics|Type of work"
msgstr ""
@@ -10861,9 +10962,6 @@ msgstr ""
msgid "CycleAnalytics|project dropdown filter"
msgstr ""
-msgid "CycleAnalytics|stage dropdown"
-msgstr ""
-
msgid "DAG visualization requires at least 3 dependent jobs."
msgstr ""
@@ -10963,10 +11061,16 @@ msgstr ""
msgid "DastProfiles|AJAX spider"
msgstr ""
+msgid "DastProfiles|API"
+msgstr ""
+
+msgid "DastProfiles|API endpoint URL"
+msgstr ""
+
msgid "DastProfiles|Active"
msgstr ""
-msgid "DastProfiles|Additional request headers (Optional)"
+msgid "DastProfiles|Additional request headers (optional)"
msgstr ""
msgid "DastProfiles|Are you sure you want to delete this profile?"
@@ -10981,6 +11085,9 @@ msgstr ""
msgid "DastProfiles|Branch missing"
msgstr ""
+msgid "DastProfiles|Choose a scan method"
+msgstr ""
+
msgid "DastProfiles|Could not create the scanner profile. Please try again."
msgstr ""
@@ -11050,7 +11157,13 @@ msgstr ""
msgid "DastProfiles|Excluded URLs"
msgstr ""
-msgid "DastProfiles|Excluded URLs (Optional)"
+msgid "DastProfiles|Excluded URLs (optional)"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths (optional)"
msgstr ""
msgid "DastProfiles|Hide debug messages"
@@ -11107,9 +11220,6 @@ msgstr ""
msgid "DastProfiles|Request headers"
msgstr ""
-msgid "DastProfiles|Rest API"
-msgstr ""
-
msgid "DastProfiles|Run the AJAX spider, in addition to the traditional spider, to crawl the target site."
msgstr ""
@@ -11119,6 +11229,9 @@ msgstr ""
msgid "DastProfiles|Save profile"
msgstr ""
+msgid "DastProfiles|Scan method"
+msgstr ""
+
msgid "DastProfiles|Scan mode"
msgstr ""
@@ -11197,12 +11310,24 @@ msgstr ""
msgid "DastProfiles|Website"
msgstr ""
+msgid "DastProfiles|What does each method do?"
+msgstr ""
+
msgid "DastProfiles|You can either choose a passive scan or validate the target site from the site profile management page. %{docsLinkStart}Learn more about site validation.%{docsLinkEnd}"
msgstr ""
msgid "DastProfiles|You cannot run an active scan against an unvalidated site."
msgstr ""
+msgid "DastProfiles|folder/dast_example.har or https://example.com/dast_example.har"
+msgstr ""
+
+msgid "DastProfiles|folder/example.postman_collection.json or https://example.com/"
+msgstr ""
+
+msgid "DastProfiles|folder/openapi.json or https://example.com/openapi.json"
+msgstr ""
+
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
@@ -11310,6 +11435,9 @@ msgstr ""
msgid "DatadogIntegration|API URL"
msgstr ""
+msgid "DatadogIntegration|Custom tags in Datadog. Enter one tag per line in the %{codeOpen}key:value%{codeClose} format. %{linkOpen}How do I use tags?%{linkClose}"
+msgstr ""
+
msgid "DatadogIntegration|Environment"
msgstr ""
@@ -11328,12 +11456,18 @@ msgstr ""
msgid "DatadogIntegration|Tag all data from this GitLab instance in Datadog. Useful when managing several self-managed deployments."
msgstr ""
+msgid "DatadogIntegration|Tags"
+msgstr ""
+
msgid "DatadogIntegration|The Datadog site to send data to. To send data to the EU site, use %{codeOpen}datadoghq.eu%{codeClose}."
msgstr ""
msgid "DatadogIntegration|Trace your GitLab pipelines with Datadog."
msgstr ""
+msgid "DatadogIntegration|have an invalid format"
+msgstr ""
+
msgid "Datasource name not found"
msgstr ""
@@ -11343,9 +11477,6 @@ msgstr ""
msgid "Date merged"
msgstr ""
-msgid "Date picker"
-msgstr ""
-
msgid "Date range"
msgstr ""
@@ -11499,9 +11630,6 @@ msgstr ""
msgid "Definition"
msgstr ""
-msgid "Delayed Project Deletion (%{adjourned_deletion})"
-msgstr ""
-
msgid "DelayedJobs|Are you sure you want to run %{jobName} immediately? Otherwise this job will run automatically after its timer finishes."
msgstr ""
@@ -11580,10 +11708,10 @@ msgstr ""
msgid "Delete pipeline"
msgstr ""
-msgid "Delete project"
+msgid "Delete pipeline schedule"
msgstr ""
-msgid "Delete project. Are you ABSOLUTELY SURE?"
+msgid "Delete project"
msgstr ""
msgid "Delete row"
@@ -11613,6 +11741,9 @@ msgstr ""
msgid "Delete this epic and all descendants?"
msgstr ""
+msgid "Delete this project"
+msgstr ""
+
msgid "Delete user list"
msgstr ""
@@ -11871,6 +12002,12 @@ msgstr ""
msgid "Deploy to..."
msgstr ""
+msgid "DeployBoards|To see deployment progress for your environments, make sure you are deploying to %{codeStart}$KUBE_NAMESPACE%{codeEnd} and annotating with %{codeStart}app.gitlab.com/app=$CI_PROJECT_PATH_SLUG%{codeEnd} and %{codeStart}app.gitlab.com/env=$CI_ENVIRONMENT_SLUG%{codeEnd}."
+msgstr ""
+
+msgid "DeployBoard|Kubernetes Pods"
+msgstr ""
+
msgid "DeployFreeze|Add a freeze period to prevent unintended releases during a period of time for a given environment. You must update the deployment jobs in %{filename} according to the deploy freezes added here. %{freeze_period_link_start}Learn more.%{freeze_period_link_end}"
msgstr ""
@@ -11955,9 +12092,6 @@ msgstr ""
msgid "DeployTokens|Active Deploy Tokens (%{active_tokens})"
msgstr ""
-msgid "DeployTokens|Allows read and write access to registry images."
-msgstr ""
-
msgid "DeployTokens|Allows read and write access to the package registry."
msgstr ""
@@ -11970,6 +12104,9 @@ msgstr ""
msgid "DeployTokens|Allows read-only access to the repository."
msgstr ""
+msgid "DeployTokens|Allows write access to registry images."
+msgstr ""
+
msgid "DeployTokens|Copy deploy token"
msgstr ""
@@ -12063,12 +12200,57 @@ msgstr ""
msgid "Deploying to AWS is easy with GitLab"
msgstr ""
+msgid "Deployment"
+msgstr ""
+
msgid "Deployment Frequency"
msgstr ""
+msgid "Deployment Target|Project deployment target (optional)"
+msgstr ""
+
+msgid "Deployment Target|Select the deployment target"
+msgstr ""
+
msgid "Deployment frequency"
msgstr ""
+msgid "DeploymentTarget|GitLab Pages"
+msgstr ""
+
+msgid "DeploymentTarget|Heroku"
+msgstr ""
+
+msgid "DeploymentTarget|Infrastructure provider (Terraform, Cloudformation, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Kubernetes (GKE, EKS, OpenShift, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Managed container runtime (Fargate, Cloud Run, DigitalOcean App)"
+msgstr ""
+
+msgid "DeploymentTarget|Mobile app store"
+msgstr ""
+
+msgid "DeploymentTarget|No deployment planned"
+msgstr ""
+
+msgid "DeploymentTarget|Other hosting service"
+msgstr ""
+
+msgid "DeploymentTarget|Registry (package or container)"
+msgstr ""
+
+msgid "DeploymentTarget|Self-managed container runtime (Podman, Docker Swarm, Docker Compose)"
+msgstr ""
+
+msgid "DeploymentTarget|Serverless backend (Lambda, Cloud functions)"
+msgstr ""
+
+msgid "DeploymentTarget|Virtual machine (for example, EC2)"
+msgstr ""
+
msgid "Deployments"
msgstr ""
@@ -12107,6 +12289,9 @@ msgstr ""
msgid "Deployment|This deployment was created using the API"
msgstr ""
+msgid "Deployment|Triggerer"
+msgstr ""
+
msgid "Deployment|Waiting"
msgstr ""
@@ -12134,6 +12319,18 @@ msgstr ""
msgid "Deprecated API rate limits"
msgstr ""
+msgid "Deprecations|Feature deprecation and removal"
+msgstr ""
+
+msgid "Deprecations|For information on a possible replacement %{epicStart} learn more about Opstrace %{epicEnd}."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7 and are %{epicStart} scheduled for removal %{epicEnd} in GitLab 15.0."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7, and are %{removal_link_start} scheduled for removal %{link_end} in GitLab 15.0. For information on a possible replacement, %{opstrace_link_start} learn more about Opstrace %{link_end}."
+msgstr ""
+
msgid "Deprioritize label"
msgstr ""
@@ -12379,10 +12576,10 @@ msgstr ""
msgid "DevopsAdoption|At least one deploy"
msgstr ""
-msgid "DevopsAdoption|At least one issue opened"
+msgid "DevopsAdoption|At least one issue created"
msgstr ""
-msgid "DevopsAdoption|At least one merge request opened"
+msgid "DevopsAdoption|At least one merge request created"
msgstr ""
msgid "DevopsAdoption|At least one pipeline successfully run"
@@ -12583,6 +12780,9 @@ msgstr ""
msgid "Direct member"
msgstr ""
+msgid "Direct members"
+msgstr ""
+
msgid "Direct non-authenticated users to this page."
msgstr ""
@@ -12699,6 +12899,9 @@ msgid_plural "Dismiss %d selected vulnerabilities as"
msgstr[0] ""
msgstr[1] ""
+msgid "Dismiss Alert"
+msgstr ""
+
msgid "Dismiss merge request promotion"
msgstr ""
@@ -12726,9 +12929,15 @@ msgstr ""
msgid "Display alerts from all configured monitoring tools."
msgstr ""
+msgid "Display milestones"
+msgstr ""
+
msgid "Display name"
msgstr ""
+msgid "Display progress of child issues"
+msgstr ""
+
msgid "Display rendered file"
msgstr ""
@@ -12834,6 +13043,9 @@ msgstr ""
msgid "Download image"
msgstr ""
+msgid "Download payload"
+msgstr ""
+
msgid "Download raw data (.csv)"
msgstr ""
@@ -13011,6 +13223,9 @@ msgstr ""
msgid "Edit in Web IDE"
msgstr ""
+msgid "Edit in pipeline editor"
+msgstr ""
+
msgid "Edit in single-file editor"
msgstr ""
@@ -13053,6 +13268,9 @@ msgstr ""
msgid "Edit your most recent comment in a thread (from an empty textarea)"
msgstr ""
+msgid "Edit, lint, and visualize your pipeline."
+msgstr ""
+
msgid "Edited"
msgstr ""
@@ -13494,6 +13712,9 @@ msgstr ""
msgid "Enforce two-factor authentication for all user sign-ins."
msgstr ""
+msgid "Enhance security by storing service account keys in secret managers - learn more about %{docLinkStart}secret management with GitLab%{docLinkEnd}"
+msgstr ""
+
msgid "Ensure connectivity is available from the GitLab server to the Prometheus server"
msgstr ""
@@ -13554,6 +13775,9 @@ 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 following to confirm:"
+msgstr ""
+
msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
@@ -14084,9 +14308,6 @@ 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 ""
@@ -14222,6 +14443,9 @@ msgstr ""
msgid "Errors:"
msgstr ""
+msgid "Escalate this incident"
+msgstr ""
+
msgid "Escalation Policies"
msgstr ""
@@ -14234,6 +14458,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy"
+msgstr ""
+
msgid "Escalation policy:"
msgstr ""
@@ -14485,6 +14712,9 @@ msgstr ""
msgid "Existing sign in methods may be removed"
msgstr ""
+msgid "Exit."
+msgstr ""
+
msgid "Expand"
msgstr ""
@@ -14581,6 +14811,9 @@ msgstr ""
msgid "Explore public groups"
msgstr ""
+msgid "Explore public projects"
+msgstr ""
+
msgid "Explore snippets"
msgstr ""
@@ -14742,7 +14975,7 @@ msgid_plural "Failed to archive designs. Please try again."
msgstr[0] ""
msgstr[1] ""
-msgid "Failed to assign a reviewer because no user was found."
+msgid "Failed to assign a reviewer because no user was specified."
msgstr ""
msgid "Failed to assign a user because no user was found."
@@ -14808,10 +15041,10 @@ msgstr ""
msgid "Failed to find import label for Jira import."
msgstr ""
-msgid "Failed to generate export, please try again later."
+msgid "Failed to find users for %{missing}"
msgstr ""
-msgid "Failed to generate report, please try again after sometime"
+msgid "Failed to generate export, please try again later."
msgstr ""
msgid "Failed to get ref."
@@ -14910,6 +15143,9 @@ msgstr ""
msgid "Failed to remove a to-do item for the design."
msgstr ""
+msgid "Failed to remove attention because no user was found."
+msgstr ""
+
msgid "Failed to remove mirror."
msgstr ""
@@ -14922,6 +15158,9 @@ msgstr ""
msgid "Failed to remove user key."
msgstr ""
+msgid "Failed to request attention because no user was found."
+msgstr ""
+
msgid "Failed to reset key. Please try again."
msgstr ""
@@ -15003,6 +15242,9 @@ msgstr ""
msgid "Feature Flags"
msgstr ""
+msgid "Feature deprecation and removal"
+msgstr ""
+
msgid "Feature flag status"
msgstr ""
@@ -15500,7 +15742,7 @@ msgstr ""
msgid "For each job, re-use the project workspace. If the workspace doesn't exist, use %{code_open}git clone%{code_close}."
msgstr ""
-msgid "For example, the application using the token or the purpose of the token."
+msgid "For example, the application using the token or the purpose of the token. Do not give sensitive information for the name of the token, as it will be visible to all %{resource_type} members."
msgstr ""
msgid "For files larger than this limit, only index the file name. The file content is neither indexed nor searchable."
@@ -15584,9 +15826,6 @@ msgstr ""
msgid "ForkProject|Select a namespace"
msgstr ""
-msgid "ForkProject|Select a namespace to fork the project"
-msgstr ""
-
msgid "ForkProject|The project can be accessed by any logged in user."
msgstr ""
@@ -15683,6 +15922,9 @@ msgstr ""
msgid "Full name"
msgstr ""
+msgid "GCP region configured"
+msgstr ""
+
msgid "GPG Key ID:"
msgstr ""
@@ -15863,6 +16105,9 @@ msgstr ""
msgid "Geo|Failed"
msgstr ""
+msgid "Geo|Filter Geo sites"
+msgstr ""
+
msgid "Geo|Filter by name"
msgstr ""
@@ -16274,6 +16519,12 @@ msgstr ""
msgid "GitLab Issue"
msgstr ""
+msgid "GitLab KAS"
+msgstr ""
+
+msgid "GitLab Memberships CSV Export"
+msgstr ""
+
msgid "GitLab Pages"
msgstr ""
@@ -16322,6 +16573,9 @@ 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 free to use. Many features for larger teams are part of our %{link_start}paid products%{link_end}. You can try Ultimate for free without any obligation or payment details."
+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 ""
@@ -16448,7 +16702,7 @@ msgstr ""
msgid "GitLabPages|When enabled, all attempts to visit your website through HTTP are automatically redirected to HTTPS using a response with status code 301. Requires a valid certificate for all domains. %{docs_link_start}Learn more.%{link_end}"
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. %{docs_link_start}Learn more.%{link_end}"
+msgid "GitLabPages|When using Pages under the general domain of a GitLab instance (%{pages_host}), you cannot use HTTPS with subdomains of subdomains. If your namespace or groupname contains a dot, it does not work. This is a limitation of the HTTP Over TLS protocol. HTTP pages work if you don't redirect HTTP to HTTPS. %{docs_link_start}Learn more.%{link_end}"
msgstr ""
msgid "GitLabPages|With GitLab Pages you can host your static website directly from your GitLab repository. %{docs_link_start}Learn more.%{link_end}"
@@ -16625,9 +16879,6 @@ msgstr ""
msgid "Go to find file"
msgstr ""
-msgid "Go to fork"
-msgstr ""
-
msgid "Go to issue boards"
msgstr ""
@@ -16835,9 +17086,6 @@ msgstr ""
msgid "Group Hooks"
msgstr ""
-msgid "Group ID"
-msgstr ""
-
msgid "Group Owner must have signed in with SAML before enabling Group Managed Accounts"
msgstr ""
@@ -16865,9 +17113,6 @@ msgstr ""
msgid "Group by"
msgstr ""
-msgid "Group description"
-msgstr ""
-
msgid "Group description (optional)"
msgstr ""
@@ -16982,7 +17227,7 @@ msgstr ""
msgid "Group: %{name}"
msgstr ""
-msgid "GroupActivityMetrics|Issues opened"
+msgid "GroupActivityMetrics|Issues created"
msgstr ""
msgid "GroupActivityMetrics|Last 90 days"
@@ -16991,7 +17236,7 @@ msgstr ""
msgid "GroupActivityMetrics|Members added"
msgstr ""
-msgid "GroupActivityMetrics|Merge Requests opened"
+msgid "GroupActivityMetrics|Merge Requests created"
msgstr ""
msgid "GroupActivityMetrics|Recent activity"
@@ -17282,6 +17527,9 @@ msgstr ""
msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
+msgid "GroupSettings|Choose a group path that does not start with a dash or end with a period. It can also contain alphanumeric characters and underscores."
+msgstr ""
+
msgid "GroupSettings|Compliance frameworks"
msgstr ""
@@ -17315,7 +17563,7 @@ msgstr ""
msgid "GroupSettings|If not specified at the group or instance level, the default is %{default_initial_branch_name}. Does not affect existing repositories."
msgstr ""
-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."
+msgid "GroupSettings|If the parent group's visibility is lower than the group's current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility."
msgstr ""
msgid "GroupSettings|New runners registration token has been generated!"
@@ -17432,7 +17680,10 @@ msgstr ""
msgid "Groups and projects"
msgstr ""
-msgid "Groups and subgroups"
+msgid "Groups are a great way to organize projects and people."
+msgstr ""
+
+msgid "Groups are the best way to manage projects and members."
msgstr ""
msgid "Groups to synchronize"
@@ -17543,13 +17794,16 @@ msgstr ""
msgid "GroupsTree|Are you sure you want to leave the \"%{fullName}\" group?"
msgstr ""
-msgid "GroupsTree|Edit group"
+msgid "GroupsTree|Delete"
+msgstr ""
+
+msgid "GroupsTree|Edit"
msgstr ""
msgid "GroupsTree|Failed to leave the group. Please make sure you are not the only owner."
msgstr ""
-msgid "GroupsTree|Leave this group"
+msgid "GroupsTree|Leave group"
msgstr ""
msgid "GroupsTree|Loading groups"
@@ -17561,9 +17815,57 @@ msgstr ""
msgid "GroupsTree|No groups or projects matched your search"
msgstr ""
+msgid "GroupsTree|Options"
+msgstr ""
+
msgid "GroupsTree|Search by name"
msgstr ""
+msgid "Groups|Avatar will be removed. Are you sure?"
+msgstr ""
+
+msgid "Groups|Changing group URL can have unintended side effects."
+msgstr ""
+
+msgid "Groups|Checking group URL availability..."
+msgstr ""
+
+msgid "Groups|Enter a descriptive name for your group."
+msgstr ""
+
+msgid "Groups|Group ID"
+msgstr ""
+
+msgid "Groups|Group URL"
+msgstr ""
+
+msgid "Groups|Group avatar"
+msgstr ""
+
+msgid "Groups|Group description (optional)"
+msgstr ""
+
+msgid "Groups|Group name"
+msgstr ""
+
+msgid "Groups|Group path is available."
+msgstr ""
+
+msgid "Groups|Group path is unavailable. Path has been replaced with a suggested available path."
+msgstr ""
+
+msgid "Groups|Learn more"
+msgstr ""
+
+msgid "Groups|Must start with letter, digit, emoji, or underscore. Can also contain periods, dashes, spaces, and parentheses."
+msgstr ""
+
+msgid "Groups|Remove avatar"
+msgstr ""
+
+msgid "Groups|Save changes"
+msgstr ""
+
msgid "Guideline"
msgstr ""
@@ -17573,6 +17875,9 @@ msgstr ""
msgid "HAR file path or URL"
msgstr ""
+msgid "HTTP Archive (HAR)"
+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 ""
@@ -17973,6 +18278,9 @@ msgstr ""
msgid "INFO: Your SSH key is expiring soon. Please generate a new key."
msgstr ""
+msgid "IP"
+msgstr ""
+
msgid "IP Address"
msgstr ""
@@ -18009,6 +18317,9 @@ msgstr ""
msgid "IdentityVerification|Verify your identity"
msgstr ""
+msgid "IdentityVerification|You can always verify your account at a later time to create a group."
+msgstr ""
+
msgid "If any indexed field exceeds this limit, it is truncated to this number of characters. The rest of the content is neither indexed nor searchable. This does not apply to repository and wiki indexing. For unlimited characters, set this to 0."
msgstr ""
@@ -18066,6 +18377,9 @@ msgstr ""
msgid "If you add %{codeStart}needs%{codeEnd} to jobs in your pipeline you'll be able to view the %{codeStart}needs%{codeEnd} relationships between jobs in this tab as a %{linkStart}Directed Acyclic Graph (DAG)%{linkEnd}."
msgstr ""
+msgid "If you are added to a project, it will be displayed here."
+msgstr ""
+
msgid "If you did not initiate these sign-in attempts, please reach out to your administrator or enable two-factor authentication (2FA) on your account."
msgstr ""
@@ -18372,12 +18686,24 @@ msgstr ""
msgid "InProductMarketing|3 ways to dive into GitLab CI/CD"
msgstr ""
+msgid "InProductMarketing|A single application eliminates complex integrations, data chokepoints, and toolchain maintenance, resulting in greater productivity and lower cost."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features, build more efficiently, strengthen security and compliance."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features."
+msgstr ""
+
msgid "InProductMarketing|Actually, GitLab makes the team work (better)"
msgstr ""
msgid "InProductMarketing|And finally %{deploy_link} a Python application."
msgstr ""
+msgid "InProductMarketing|And many more..."
+msgstr ""
+
msgid "InProductMarketing|Are your runners ready?"
msgstr ""
@@ -18396,15 +18722,33 @@ msgstr ""
msgid "InProductMarketing|Blog"
msgstr ""
+msgid "InProductMarketing|Break down silos to coordinate seamlessly across development, operations, and security with a consistent experience across the development lifecycle."
+msgstr ""
+
+msgid "InProductMarketing|Burn up/down charts"
+msgstr ""
+
msgid "InProductMarketing|By enabling code owners and required merge approvals the right person will review the right MR. This is a win-win: cleaner code and a more efficient review process."
msgstr ""
msgid "InProductMarketing|Click on the number below that corresponds with your answer — 1 being very difficult, 5 being very easy."
msgstr ""
+msgid "InProductMarketing|Code owners"
+msgstr ""
+
msgid "InProductMarketing|Code owners and required merge approvals are part of the paid tiers of GitLab. You can start a free 30-day trial of GitLab Ultimate and enable these features in less than 5 minutes with no credit card required."
msgstr ""
+msgid "InProductMarketing|Code review analytics"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration across stages in GitLab"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration made easy"
+msgstr ""
+
msgid "InProductMarketing|Create a custom CI runner with just a few clicks"
msgstr ""
@@ -18414,12 +18758,21 @@ msgstr ""
msgid "InProductMarketing|Create a project in GitLab in 5 minutes"
msgstr ""
+msgid "InProductMarketing|Create well-defined workflows by using scoped labels on issues, merge requests, and epics. Labels with the same scope cannot be used together, which prevents conflicts."
+msgstr ""
+
msgid "InProductMarketing|Create your first project!"
msgstr ""
+msgid "InProductMarketing|Define who owns specific files or directories, so the right reviewers are suggested when a merge request introduces changes to those files."
+msgstr ""
+
msgid "InProductMarketing|Deliver Better Products Faster"
msgstr ""
+msgid "InProductMarketing|Dependency scanning"
+msgstr ""
+
msgid "InProductMarketing|Did you know teams that use GitLab are far more efficient?"
msgstr ""
@@ -18429,15 +18782,27 @@ msgstr ""
msgid "InProductMarketing|Dig in and create a project and a repo"
msgstr ""
+msgid "InProductMarketing|Discover Premium & Ultimate"
+msgstr ""
+
+msgid "InProductMarketing|Discover Premium & Ultimate."
+msgstr ""
+
msgid "InProductMarketing|Do you have a minute?"
msgstr ""
msgid "InProductMarketing|Do you have a teammate who would be perfect for this task?"
msgstr ""
+msgid "InProductMarketing|Dynamic application security testing"
+msgstr ""
+
msgid "InProductMarketing|Easy"
msgstr ""
+msgid "InProductMarketing|Epics"
+msgstr ""
+
msgid "InProductMarketing|Expand your DevOps journey with a free GitLab trial"
msgstr ""
@@ -18459,9 +18824,15 @@ msgstr ""
msgid "InProductMarketing|Feel the need for speed?"
msgstr ""
+msgid "InProductMarketing|Find and fix bottlenecks in your code review process by understanding how long open merge requests have been in review."
+msgstr ""
+
msgid "InProductMarketing|Find out how your teams are really doing"
msgstr ""
+msgid "InProductMarketing|Find out if your external libraries are safe. Run dependency scanning jobs that check for known vulnerabilities in your external libraries."
+msgstr ""
+
msgid "InProductMarketing|Follow our steps"
msgstr ""
@@ -18498,6 +18869,9 @@ msgstr ""
msgid "InProductMarketing|GitLab is better with teammates to help out!"
msgstr ""
+msgid "InProductMarketing|GitLab is infrastructure agnostic (supporting GCP, AWS, Azure, OpenShift, VMWare, On Prem, Bare Metal, and more), offering a consistent workflow experience – irrespective of the environment."
+msgstr ""
+
msgid "InProductMarketing|GitLab provides static application security testing (SAST), dynamic application security testing (DAST), container scanning, and dependency scanning to help you deliver secure applications along with license compliance."
msgstr ""
@@ -18588,21 +18962,36 @@ msgstr ""
msgid "InProductMarketing|It's also possible to simply %{external_repo_link} in order to take advantage of GitLab's CI/CD."
msgstr ""
+msgid "InProductMarketing|Keep your code quality high by defining who should approve merge requests and how many approvals are required."
+msgstr ""
+
msgid "InProductMarketing|Launch GitLab CI/CD in 20 minutes or less"
msgstr ""
+msgid "InProductMarketing|Lower cost of development"
+msgstr ""
+
+msgid "InProductMarketing|Make it easier to collaborate on high-level ideas by grouping related issues in an epic."
+msgstr ""
+
msgid "InProductMarketing|Making the switch? It's easier than you think to import your projects into GitLab. Move %{github_link}, or import something %{bitbucket_link}."
msgstr ""
msgid "InProductMarketing|Master the art of importing!"
msgstr ""
+msgid "InProductMarketing|Merge request approval rule"
+msgstr ""
+
msgid "InProductMarketing|Move on to easily creating a Pages website %{ci_template_link}"
msgstr ""
msgid "InProductMarketing|Multiple owners, confusing workstreams? We've got you covered"
msgstr ""
+msgid "InProductMarketing|Multiple required approvers"
+msgstr ""
+
msgid "InProductMarketing|Need an alternative to importing?"
msgstr ""
@@ -18615,18 +19004,33 @@ msgstr ""
msgid "InProductMarketing|Our tool brings all the things together"
msgstr ""
+msgid "InProductMarketing|Protect your web application by using DAST to examine for vulnerabilities in deployed environments."
+msgstr ""
+
msgid "InProductMarketing|Rapid development, simplified"
msgstr ""
msgid "InProductMarketing|Reduce Security & Compliance Risk"
msgstr ""
+msgid "InProductMarketing|Require multiple approvers on a merge request, so you know it's in good shape before it's merged."
+msgstr ""
+
+msgid "InProductMarketing|Roadmaps"
+msgstr ""
+
+msgid "InProductMarketing|Scoped labels"
+msgstr ""
+
msgid "InProductMarketing|Security that's integrated into your development lifecycle"
msgstr ""
msgid "InProductMarketing|Sometimes you're not ready to make a full transition to a new tool. If you're not ready to fully commit, %{mirroring_link} gives you a safe way to try out GitLab in parallel with your current tool."
msgstr ""
+msgid "InProductMarketing|Speed. Efficiency. Trust."
+msgstr ""
+
msgid "InProductMarketing|Spin up an autoscaling runner in GitLab"
msgstr ""
@@ -18636,6 +19040,9 @@ msgstr ""
msgid "InProductMarketing|Start a Self-Managed trial"
msgstr ""
+msgid "InProductMarketing|Start a free trial"
+msgstr ""
+
msgid "InProductMarketing|Start a free trial of GitLab Ultimate – no credit card required"
msgstr ""
@@ -18702,6 +19109,9 @@ msgstr ""
msgid "InProductMarketing|To understand and get the most out of GitLab, start at the beginning and %{project_link}. In GitLab, repositories are part of a project, so after you've created your project you can go ahead and %{repo_link}."
msgstr ""
+msgid "InProductMarketing|Track completed issues in a chart, so you can see how a milestone is progressing at a glance."
+msgstr ""
+
msgid "InProductMarketing|Try GitLab Ultimate for free"
msgstr ""
@@ -18738,6 +19148,9 @@ msgstr ""
msgid "InProductMarketing|Very easy"
msgstr ""
+msgid "InProductMarketing|Visualize your epics and milestones in a timeline."
+msgstr ""
+
msgid "InProductMarketing|Want to host GitLab on your servers?"
msgstr ""
@@ -18759,6 +19172,9 @@ msgstr ""
msgid "InProductMarketing|YouTube"
msgstr ""
+msgid "InProductMarketing|Your software, deployed your way"
+msgstr ""
+
msgid "InProductMarketing|Your teams can be more efficient"
msgstr ""
@@ -18879,9 +19295,18 @@ msgstr ""
msgid "IncidentManagement|No incidents to display."
msgstr ""
+msgid "IncidentManagement|None"
+msgstr ""
+
msgid "IncidentManagement|Open"
msgstr ""
+msgid "IncidentManagement|Page your team with escalation policies"
+msgstr ""
+
+msgid "IncidentManagement|Paged"
+msgstr ""
+
msgid "IncidentManagement|Published"
msgstr ""
@@ -18891,6 +19316,9 @@ msgstr ""
msgid "IncidentManagement|Severity"
msgstr ""
+msgid "IncidentManagement|Status"
+msgstr ""
+
msgid "IncidentManagement|There are no closed incidents"
msgstr ""
@@ -18909,6 +19337,9 @@ msgstr ""
msgid "IncidentManagement|Unpublished"
msgstr ""
+msgid "IncidentManagement|Use escalation policies to automatically page your team when incidents are created."
+msgstr ""
+
msgid "IncidentSettings|Activate \"time to SLA\" countdown timer"
msgstr ""
@@ -18954,7 +19385,10 @@ msgstr ""
msgid "Incidents"
msgstr ""
-msgid "Incidents|Add a URL"
+msgid "Incidents|Add image details"
+msgstr ""
+
+msgid "Incidents|Add text or a link to display with your image. If you don't add either, the file name displays instead."
msgstr ""
msgid "Incidents|Drop or %{linkStart}upload%{linkEnd} a metric screenshot to attach it to the incident"
@@ -18969,10 +19403,10 @@ msgstr ""
msgid "Incidents|There was an issue loading metric images."
msgstr ""
-msgid "Incidents|There was an issue uploading your image."
+msgid "Incidents|There was an issue updating your image."
msgstr ""
-msgid "Incidents|You can optionally add a URL to link users to the original graph."
+msgid "Incidents|There was an issue uploading your image."
msgstr ""
msgid "Incident|Alert details"
@@ -18981,9 +19415,18 @@ msgstr ""
msgid "Incident|Are you sure you wish to delete this image?"
msgstr ""
+msgid "Incident|Delete image"
+msgstr ""
+
msgid "Incident|Deleting %{filename}"
msgstr ""
+msgid "Incident|Edit image text or link"
+msgstr ""
+
+msgid "Incident|Editing %{filename}"
+msgstr ""
+
msgid "Incident|Metrics"
msgstr ""
@@ -19253,12 +19696,18 @@ msgstr ""
msgid "Integrations|Branches for which notifications are to be sent"
msgstr ""
+msgid "Integrations|Clear if using a self-signed certificate."
+msgstr ""
+
msgid "Integrations|Comment detail:"
msgstr ""
msgid "Integrations|Comment settings:"
msgstr ""
+msgid "Integrations|Connection details"
+msgstr ""
+
msgid "Integrations|Connection failed. Please check your settings."
msgstr ""
@@ -19283,6 +19732,9 @@ msgstr ""
msgid "Integrations|Enable GitLab.com slash commands in a Slack workspace."
msgstr ""
+msgid "Integrations|Enable SSL verification"
+msgstr ""
+
msgid "Integrations|Enable comments"
msgstr ""
@@ -19361,6 +19813,9 @@ msgstr ""
msgid "Integrations|Return to GitLab for Jira"
msgstr ""
+msgid "Integrations|SSL verification"
+msgstr ""
+
msgid "Integrations|Save settings?"
msgstr ""
@@ -19406,9 +19861,6 @@ msgstr ""
msgid "Integrations|Use default settings"
msgstr ""
-msgid "Integrations|When you mention a Jira issue in a commit or merge request, GitLab creates a remote link and comment (if enabled)."
-msgstr ""
-
msgid "Integrations|You can now close this window and return to the GitLab for Jira application."
msgstr ""
@@ -19433,9 +19885,6 @@ msgstr ""
msgid "Integrations|can't exceed %{recipients_limit}"
msgstr ""
-msgid "Interactive developer security education."
-msgstr ""
-
msgid "Interactive mode"
msgstr ""
@@ -19925,6 +20374,9 @@ msgstr ""
msgid "IssueAnalytics|Assignees"
msgstr ""
+msgid "IssueAnalytics|Created by"
+msgstr ""
+
msgid "IssueAnalytics|Due date"
msgstr ""
@@ -19937,9 +20389,6 @@ msgstr ""
msgid "IssueAnalytics|Milestone"
msgstr ""
-msgid "IssueAnalytics|Opened by"
-msgstr ""
-
msgid "IssueAnalytics|Status"
msgstr ""
@@ -20063,10 +20512,10 @@ msgstr ""
msgid "IssuesAnalytics|Avg/Month:"
msgstr ""
-msgid "IssuesAnalytics|Issues opened"
+msgid "IssuesAnalytics|Issues created"
msgstr ""
-msgid "IssuesAnalytics|Issues opened per month"
+msgid "IssuesAnalytics|Issues created per month"
msgstr ""
msgid "IssuesAnalytics|Last 12 months"
@@ -20093,6 +20542,9 @@ msgstr ""
msgid "It looks like you have some draft commits in this branch."
msgstr ""
+msgid "It looks like you're attempting to activate your subscription. Use %{a_start}the Subscription page%{a_end} instead."
+msgstr ""
+
msgid "It may be several days before you see feature usage data."
msgstr ""
@@ -20321,6 +20773,9 @@ msgstr ""
msgid "JiraConnect|You can now close this window and return to Jira."
msgstr ""
+msgid "JiraConnect|You don't have permission to create branches for this project. Select a different project or contact the project owner for access. %{linkStart}Learn more.%{linkEnd}"
+msgstr ""
+
msgid "JiraRequest|A connection error occurred while connecting to Jira. Try your request again."
msgstr ""
@@ -20369,13 +20824,13 @@ msgstr ""
msgid "JiraService|Define the type of Jira issue to create from a vulnerability."
msgstr ""
-msgid "JiraService|Displaying Jira issues while leaving the GitLab issue functionality enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
+msgid "JiraService|Displaying Jira issues while leaving GitLab issues also enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
msgstr ""
-msgid "JiraService|Enable Jira issues"
+msgid "JiraService|Enable Jira issue creation from vulnerabilities"
msgstr ""
-msgid "JiraService|Enable Jira issues creation from vulnerabilities"
+msgid "JiraService|Enable Jira issues"
msgstr ""
msgid "JiraService|Enable Jira transitions"
@@ -20492,16 +20947,19 @@ msgstr ""
msgid "JiraService|View Jira issues in GitLab"
msgstr ""
-msgid "JiraService|Warning: All GitLab users that have access to this GitLab project are able to view all issues from the Jira project specified below."
+msgid "JiraService|Warning: All GitLab users with access to this GitLab project can view all issues from the Jira project you select."
msgstr ""
msgid "JiraService|Web URL"
msgstr ""
-msgid "JiraService|Work on Jira issues without leaving GitLab. Adds a Jira menu to access your list of Jira issues and view any issue as read-only."
+msgid "JiraService|When a Jira issue is mentioned in a commit or merge request, a remote link and comment (if enabled) will be created."
+msgstr ""
+
+msgid "JiraService|Work on Jira issues without leaving GitLab. Add a Jira menu to access a read-only list of your Jira issues."
msgstr ""
-msgid "JiraService|You need to configure Jira before enabling this integration. For more details, read the %{jira_doc_link_start}Jira integration documentation%{link_end}."
+msgid "JiraService|You must configure Jira before enabling this integration. %{jira_doc_link_start}Learn more.%{link_end}"
msgstr ""
msgid "Job"
@@ -20513,9 +20971,6 @@ msgstr ""
msgid "Job Failed #%{build_id}"
msgstr ""
-msgid "Job ID"
-msgstr ""
-
msgid "Job artifact"
msgstr ""
@@ -20582,9 +21037,27 @@ msgstr ""
msgid "Jobs|You're about to retry a job that failed because it attempted to deploy code that is older than the latest deployment. Retrying this job could result in overwriting the environment with the older source code."
msgstr ""
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source} into %{target}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{ref}"
+msgstr ""
+
+msgid "Job|Are you sure you want to erase this job log and artifacts?"
+msgstr ""
+
msgid "Job|Browse"
msgstr ""
+msgid "Job|Cancel"
+msgstr ""
+
msgid "Job|Complete Raw"
msgstr ""
@@ -20594,6 +21067,9 @@ msgstr ""
msgid "Job|Erase job log and artifacts"
msgstr ""
+msgid "Job|Finished at"
+msgstr ""
+
msgid "Job|Job artifacts"
msgstr ""
@@ -20606,7 +21082,7 @@ msgstr ""
msgid "Job|Keep"
msgstr ""
-msgid "Job|Pipeline"
+msgid "Job|Retry"
msgstr ""
msgid "Job|Scroll to bottom"
@@ -20618,6 +21094,9 @@ msgstr ""
msgid "Job|Show complete raw"
msgstr ""
+msgid "Job|Status"
+msgstr ""
+
msgid "Job|The artifacts were removed"
msgstr ""
@@ -20645,21 +21124,12 @@ msgstr ""
msgid "Job|delayed"
msgstr ""
-msgid "Job|for"
-msgstr ""
-
-msgid "Job|into"
-msgstr ""
-
msgid "Job|manual"
msgstr ""
msgid "Job|triggered"
msgstr ""
-msgid "Job|with"
-msgstr ""
-
msgid "Join Zoom meeting"
msgstr ""
@@ -20762,9 +21232,6 @@ msgstr ""
msgid "Ki"
msgstr ""
-msgid "Kontra"
-msgstr ""
-
msgid "Kroki"
msgstr ""
@@ -21088,6 +21555,9 @@ msgstr ""
msgid "Learn more about Auto DevOps"
msgstr ""
+msgid "Learn more about GitLab"
+msgstr ""
+
msgid "Learn more about Needs relationships"
msgstr ""
@@ -21415,9 +21885,18 @@ msgstr ""
msgid "Licenses|Displays licenses detected in the project, based on the %{linkStart}latest successful%{linkEnd} scan"
msgstr ""
+msgid "Licenses|Drag your license file here or %{linkStart}click to upload%{linkEnd}."
+msgstr ""
+
+msgid "Licenses|Drop your license file to start the upload."
+msgstr ""
+
msgid "Licenses|Error fetching the license list. Please check your network connection and try again."
msgstr ""
+msgid "Licenses|Error: You are trying to upload something other than a file"
+msgstr ""
+
msgid "Licenses|License Compliance"
msgstr ""
@@ -21436,6 +21915,9 @@ msgstr ""
msgid "Licenses|Specified policies in this project"
msgstr ""
+msgid "Licenses|The file could not be uploaded."
+msgstr ""
+
msgid "Licenses|The license list details information about the licenses used within your project."
msgstr ""
@@ -21469,11 +21951,6 @@ msgstr ""
msgid "Limit the size of Sidekiq jobs stored in Redis."
msgstr ""
-msgid "Limited to showing %d event at most"
-msgid_plural "Limited to showing %d events at most"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Limiting mode"
msgstr ""
@@ -21483,6 +21960,9 @@ msgstr ""
msgid "Link"
msgstr ""
+msgid "Link (optional)"
+msgstr ""
+
msgid "Link Prometheus monitoring to GitLab."
msgstr ""
@@ -21519,6 +21999,9 @@ msgstr ""
msgid "Linked emails (%{email_count})"
msgstr ""
+msgid "Linked epics"
+msgstr ""
+
msgid "Linked issues"
msgstr ""
@@ -21546,6 +22029,15 @@ msgstr ""
msgid "List of all merge commits"
msgstr ""
+msgid "List of environments for this project"
+msgstr ""
+
+msgid "List of suitable GCP locations"
+msgstr ""
+
+msgid "List of users allowed to exceed the rate limit."
+msgstr ""
+
msgid "List options"
msgstr ""
@@ -21765,6 +22257,9 @@ msgstr ""
msgid "Maintenance mode"
msgstr ""
+msgid "Make adjustments to how your GitLab instance is set up."
+msgstr ""
+
msgid "Make and review changes in the browser with the Web IDE"
msgstr ""
@@ -21909,6 +22404,12 @@ msgstr ""
msgid "MarkdownEditor|Add italic text (%{modifier_key}I)"
msgstr ""
+msgid "MarkdownEditor|Add strikethrough text (%{modifierKey}⇧X)"
+msgstr ""
+
+msgid "MarkdownEditor|Add strikethrough text (%{modifier_key}⇧X)"
+msgstr ""
+
msgid "Marked For Deletion At - %{deletion_time}"
msgstr ""
@@ -22170,6 +22671,9 @@ msgstr ""
msgid "Maximum push size (MB)"
msgstr ""
+msgid "Maximum requests per 10 minutes per user"
+msgstr ""
+
msgid "Maximum requests per minute"
msgstr ""
@@ -22260,6 +22764,19 @@ msgstr ""
msgid "Members of a group may only view projects they have permission to access"
msgstr ""
+msgid "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seat in use and will be billed for the overage."
+msgid_plural "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seats in use and will be billed for the overage."
+msgstr[0] ""
+msgstr[1] ""
+
+msgid "MembersOverage|You are about to incur additional charges"
+msgstr ""
+
+msgid "MembersOverage|Your subscription includes %d seat."
+msgid_plural "MembersOverage|Your subscription includes %d seats."
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Membership"
msgstr ""
@@ -22464,9 +22981,6 @@ msgstr ""
msgid "Merge request not merged"
msgstr ""
-msgid "Merge request pipelines 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 merge request pipelines."
-msgstr ""
-
msgid "Merge request reports"
msgstr ""
@@ -22563,13 +23077,13 @@ msgstr ""
msgid "MergeRequests|Create issue to resolve thread"
msgstr ""
-msgid "MergeRequests|Failed to squash. Should be done manually."
+msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Saving the comment failed"
+msgid "MergeRequests|Squashing failed: Squash the commits locally, resolve any conflicts, then push the branch."
msgstr ""
-msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
+msgid "MergeRequests|Squashing not allowed: This project doesn't allow you to squash commits when merging."
msgstr ""
msgid "MergeRequests|Thread stays resolved"
@@ -23410,6 +23924,18 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "MrList|Assigned to %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from assignee %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from reviewer %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Review requested from %{name}, go to their profile."
+msgstr ""
+
msgid "Multi-project"
msgstr ""
@@ -23443,7 +23969,7 @@ msgstr ""
msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "My Awesome Group"
+msgid "My awesome group"
msgstr ""
msgid "My company or team"
@@ -24065,9 +24591,6 @@ msgstr ""
msgid "No available branches"
msgstr ""
-msgid "No available groups to fork the project."
-msgstr ""
-
msgid "No branches found"
msgstr ""
@@ -24278,6 +24801,9 @@ msgstr ""
msgid "No ref selected"
msgstr ""
+msgid "No regions configured"
+msgstr ""
+
msgid "No related merge requests found."
msgstr ""
@@ -25082,6 +25608,9 @@ msgstr ""
msgid "Only reCAPTCHA v2 is supported:"
msgstr ""
+msgid "Only required if not using role instance credentials."
+msgstr ""
+
msgid "Only use lowercase letters, numbers, and underscores."
msgstr ""
@@ -25106,9 +25635,6 @@ msgstr ""
msgid "Open a CLI and connect to the cluster you want to install the agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
-msgid "Open epics"
-msgstr ""
-
msgid "Open errors"
msgstr ""
@@ -25148,7 +25674,7 @@ msgstr ""
msgid "Opened issues"
msgstr ""
-msgid "OpenedNDaysAgo|Opened"
+msgid "OpenedNDaysAgo|Created"
msgstr ""
msgid "Opens in a new window"
@@ -25193,9 +25719,6 @@ msgstr ""
msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
-msgid "Optional."
-msgstr ""
-
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
msgstr ""
@@ -25984,6 +26507,9 @@ msgstr ""
msgid "PerformanceBar|Memory"
msgstr ""
+msgid "PerformanceBar|Memory report"
+msgstr ""
+
msgid "PerformanceBar|Redis calls"
msgstr ""
@@ -26017,18 +26543,12 @@ msgstr ""
msgid "PerformanceBar|wall"
msgstr ""
-msgid "Performs a rebase but skips triggering a new pipeline"
-msgstr ""
-
msgid "Period in seconds"
msgstr ""
msgid "Permalink"
msgstr ""
-msgid "Permanently delete project"
-msgstr ""
-
msgid "Permanently remove group"
msgstr ""
@@ -26299,6 +26819,51 @@ msgstr ""
msgid "PipelineStatusTooltip|Pipeline: %{ci_status}"
msgstr ""
+msgid "PipelineWizardDefaultCommitMessage|Add %{filename}"
+msgstr ""
+
+msgid "PipelineWizardDefaultCommitMessage|Update %{filename}"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|At least one entry is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This field is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This value is not valid"
+msgstr ""
+
+msgid "PipelineWizardListWidget|add another step"
+msgstr ""
+
+msgid "PipelineWizardListWidget|remove step"
+msgstr ""
+
+msgid "PipelineWizard|Commit"
+msgstr ""
+
+msgid "PipelineWizard|Commit Message"
+msgstr ""
+
+msgid "PipelineWizard|Commit changes to your file"
+msgstr ""
+
+msgid "PipelineWizard|Commit file to Branch"
+msgstr ""
+
+msgid "PipelineWizard|Commit your new file"
+msgstr ""
+
+msgid "PipelineWizard|The file has been committed."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem committing the changes."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem while checking whether your file already exists in the specified branch."
+msgstr ""
+
msgid "Pipelines"
msgstr ""
@@ -26413,7 +26978,7 @@ msgstr ""
msgid "Pipelines|Project cache successfully reset."
msgstr ""
-msgid "Pipelines|Revoke"
+msgid "Pipelines|Revoke trigger"
msgstr ""
msgid "Pipelines|Something went wrong while cleaning runners cache."
@@ -26458,6 +27023,12 @@ msgstr ""
msgid "Pipelines|This is a child pipeline within the parent pipeline"
msgstr ""
+msgid "Pipelines|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipelines|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipelines|This pipeline will run code originating from a forked project merge request. This means that the code can potentially have security considerations like exposing CI variables."
msgstr ""
@@ -26500,9 +27071,6 @@ msgstr ""
msgid "Pipelines|Your changes have been successfully committed. Now redirecting to the new merge request page."
msgstr ""
-msgid "Pipelines|detached"
-msgstr ""
-
msgid "Pipelines|error"
msgstr ""
@@ -26512,10 +27080,13 @@ msgstr ""
msgid "Pipelines|latest"
msgstr ""
-msgid "Pipelines|stuck"
+msgid "Pipelines|merge request"
msgstr ""
-msgid "Pipelines|train"
+msgid "Pipelines|merge train"
+msgstr ""
+
+msgid "Pipelines|stuck"
msgstr ""
msgid "Pipelines|yaml invalid"
@@ -26647,6 +27218,12 @@ msgstr ""
msgid "Pipeline|This change will not change the overall test coverage if merged."
msgstr ""
+msgid "Pipeline|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipeline|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipeline|Trigger author"
msgstr ""
@@ -26671,6 +27248,12 @@ msgstr ""
msgid "Pipeline|for"
msgstr ""
+msgid "Pipeline|merge request"
+msgstr ""
+
+msgid "Pipeline|merge train"
+msgstr ""
+
msgid "Pipeline|on"
msgstr ""
@@ -26809,9 +27392,6 @@ msgstr ""
msgid "Please enter a valid time interval"
msgstr ""
-msgid "Please enter or upload a valid license."
-msgstr ""
-
msgid "Please enter your current password."
msgstr ""
@@ -26920,9 +27500,6 @@ msgstr ""
msgid "Please type %{phrase_code} to proceed or close this modal to cancel."
msgstr ""
-msgid "Please type the following to confirm:"
-msgstr ""
-
msgid "Please use this form to report to the admin users who create spam issues, comments or behave inappropriately."
msgstr ""
@@ -26950,12 +27527,27 @@ msgstr ""
msgid "Policies"
msgstr ""
+msgid "Policy '%{escalation_policy_name}' does not exist."
+msgstr ""
+
msgid "Policy management project does have any policies in %{policy_path}"
msgstr ""
msgid "Policy project doesn't exist"
msgstr ""
+msgid "PolicyRuleMultiSelect|%{firstLabel} +%{numberOfAdditionalLabels} more"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|All %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select all"
+msgstr ""
+
msgid "Polling interval multiplier"
msgstr ""
@@ -27184,6 +27776,9 @@ msgstr ""
msgid "Private projects can be created in your personal namespace with:"
msgstr ""
+msgid "Problem with %{name} command: %{message}."
+msgstr ""
+
msgid "Proceed"
msgstr ""
@@ -27658,6 +28253,9 @@ msgstr ""
msgid "Progress"
msgstr ""
+msgid "Progress tracking"
+msgstr ""
+
msgid "Project"
msgstr ""
@@ -27889,6 +28487,9 @@ msgstr ""
msgid "ProjectQualitySummary|Failure"
msgstr ""
+msgid "ProjectQualitySummary|Get insight into the overall percentage of tests in your project that succeed, fail and are skipped."
+msgstr ""
+
msgid "ProjectQualitySummary|Latest pipeline results"
msgstr ""
@@ -27907,6 +28508,12 @@ msgstr ""
msgid "ProjectQualitySummary|See project Code Coverage Statistics"
msgstr ""
+msgid "ProjectQualitySummary|Set up test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|Set up test runs (opens in a new tab)"
+msgstr ""
+
msgid "ProjectQualitySummary|Skipped"
msgstr ""
@@ -28183,13 +28790,19 @@ msgstr ""
msgid "ProjectSettings|LFS objects from this repository are available to forks. %{linkStart}How do I remove them?%{linkEnd}"
msgstr ""
+msgid "ProjectSettings|Learn about commit history."
+msgstr ""
+
+msgid "ProjectSettings|Leave empty to use default template."
+msgstr ""
+
msgid "ProjectSettings|Manage who can see the project in the public access directory."
msgstr ""
msgid "ProjectSettings|Manages large files such as audio, video, and graphics files."
msgstr ""
-msgid "ProjectSettings|Maximum 500 characters."
+msgid "ProjectSettings|Maximum %{maxLength} characters."
msgstr ""
msgid "ProjectSettings|Merge checks"
@@ -28330,6 +28943,9 @@ msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
msgstr ""
+msgid "ProjectSettings|The default template will be applied on save."
+msgstr ""
+
msgid "ProjectSettings|These checks must pass before merge requests can be merged."
msgstr ""
@@ -28384,6 +29000,9 @@ msgstr ""
msgid "ProjectSettings|What are badges?"
msgstr ""
+msgid "ProjectSettings|What are merge trains?"
+msgstr ""
+
msgid "ProjectSettings|When merge request pipelines are enabled in the CI/CD configuration file, pipelines validate the combined results of the source and target branches. %{link_start}How to configure merge request pipelines?%{link_end}"
msgstr ""
@@ -28501,6 +29120,9 @@ msgstr ""
msgid "Projects are organized into groups"
msgstr ""
+msgid "Projects are where you store your code, access issues, wiki and other features of GitLab."
+msgstr ""
+
msgid "Projects contributed to"
msgstr ""
@@ -28516,12 +29138,6 @@ msgstr ""
msgid "Projects to index"
msgstr ""
-msgid "Projects will be permanently deleted after a %{waiting_period}-day waiting period."
-msgstr ""
-
-msgid "Projects will be permanently deleted immediately."
-msgstr ""
-
msgid "Projects with critical vulnerabilities"
msgstr ""
@@ -28606,6 +29222,9 @@ msgstr ""
msgid "ProjectsNew|Import project"
msgstr ""
+msgid "ProjectsNew|Include a Getting Started README"
+msgstr ""
+
msgid "ProjectsNew|Initialize repository with a README"
msgstr ""
@@ -28621,6 +29240,9 @@ msgstr ""
msgid "ProjectsNew|Project description %{tag_start}(optional)%{tag_end}"
msgstr ""
+msgid "ProjectsNew|Recommended if you're new to GitLab"
+msgstr ""
+
msgid "ProjectsNew|Run CI/CD for external repository"
msgstr ""
@@ -29038,6 +29660,9 @@ msgstr ""
msgid "ProtectedBranch|Unprotect"
msgstr ""
+msgid "ProtectedBranch|Unprotect branch"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
@@ -29065,6 +29690,9 @@ msgstr ""
msgid "ProtectedEnvironment|Protected Environment (%{protected_environments_count})"
msgstr ""
+msgid "ProtectedEnvironment|Required approvals"
+msgstr ""
+
msgid "ProtectedEnvironment|Select an environment"
msgstr ""
@@ -29086,10 +29714,13 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|Unprotect tag"
+msgstr ""
+
msgid "ProtectedTags|default"
msgstr ""
-msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
+msgid "ProtectedTag|By default, protected tags restrict who can modify the tag."
msgstr ""
msgid "ProtectedTag|Learn more."
@@ -29152,6 +29783,9 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Public projects are an easy way to allow everyone to have read-only access."
+msgstr ""
+
msgid "Publish to status page"
msgstr ""
@@ -29308,9 +29942,6 @@ msgstr ""
msgid "QualitySummary|Project quality"
msgstr ""
-msgid "Quarters"
-msgstr ""
-
msgid "Query"
msgstr ""
@@ -29395,6 +30026,9 @@ msgstr ""
msgid "Read more about project permissions %{help_link_open}here%{help_link_close}"
msgstr ""
+msgid "Read more about related epics"
+msgstr ""
+
msgid "Read more about related issues"
msgstr ""
@@ -29425,10 +30059,7 @@ msgstr ""
msgid "Rebase source branch on the target branch."
msgstr ""
-msgid "Rebase without CI"
-msgstr ""
-
-msgid "Rebases and triggers a pipeline"
+msgid "Rebase without pipeline"
msgstr ""
msgid "Recaptcha verified?"
@@ -29479,9 +30110,6 @@ msgstr ""
msgid "Reconfigure"
msgstr ""
-msgid "Recovering projects"
-msgstr ""
-
msgid "Recovery Codes"
msgstr ""
@@ -29541,6 +30169,12 @@ msgstr ""
msgid "Regex pattern"
msgstr ""
+msgid "Region"
+msgstr ""
+
+msgid "Regions"
+msgstr ""
+
msgid "Register"
msgstr ""
@@ -29771,9 +30405,6 @@ msgstr ""
msgid "Remove all or specific reviewer(s)"
msgstr ""
-msgid "Remove approver"
-msgstr ""
-
msgid "Remove approvers"
msgstr ""
@@ -29789,6 +30420,9 @@ msgstr ""
msgid "Remove attention request"
msgstr ""
+msgid "Remove attention request(s)"
+msgstr ""
+
msgid "Remove avatar"
msgstr ""
@@ -29927,6 +30561,9 @@ msgstr ""
msgid "Removed an issue from an epic."
msgstr ""
+msgid "Removed attention from %{users_sentence}."
+msgstr ""
+
msgid "Removed attention request from @%{username}"
msgstr ""
@@ -29978,6 +30615,9 @@ msgstr ""
msgid "Removes an issue from an epic."
msgstr ""
+msgid "Removes attention from %{users_sentence}."
+msgstr ""
+
msgid "Removes parent epic %{epic_ref}."
msgstr ""
@@ -30089,6 +30729,9 @@ msgstr ""
msgid "Report abuse to admin"
msgstr ""
+msgid "Report is generating and will be sent to your email address."
+msgstr ""
+
msgid "Reported %{timeAgo} by %{reportedBy}"
msgstr ""
@@ -30378,6 +31021,15 @@ msgstr ""
msgid "Request attention"
msgstr ""
+msgid "Request attention from %{users_sentence}."
+msgstr ""
+
+msgid "Request attention from assignee or reviewer"
+msgstr ""
+
+msgid "Request attention from assignee(s) or reviewer(s)"
+msgstr ""
+
msgid "Request attention to review"
msgstr ""
@@ -30402,6 +31054,9 @@ msgstr ""
msgid "Requested %{time_ago}"
msgstr ""
+msgid "Requested attention from %{users_sentence}."
+msgstr ""
+
msgid "Requested attention from @%{username}"
msgstr ""
@@ -30616,6 +31271,9 @@ msgstr ""
msgid "Restore project"
msgstr ""
+msgid "Restoring projects"
+msgstr ""
+
msgid "Restoring the group will prevent the group, its subgroups and projects from being removed on this date."
msgstr ""
@@ -30646,6 +31304,9 @@ msgstr ""
msgid "Retry"
msgstr ""
+msgid "Retry failed jobs"
+msgstr ""
+
msgid "Retry job"
msgstr ""
@@ -30693,9 +31354,6 @@ msgstr ""
msgid "Review changes"
msgstr ""
-msgid "Review requested from %{name}"
-msgstr ""
-
msgid "Review requests for you"
msgstr ""
@@ -30860,6 +31518,9 @@ msgstr ""
msgid "Runners|Assigned Group"
msgstr ""
+msgid "Runners|Assigned Projects (%{projectCount})"
+msgstr ""
+
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30929,6 +31590,9 @@ msgstr ""
msgid "Runners|Instance"
msgstr ""
+msgid "Runners|Jobs"
+msgstr ""
+
msgid "Runners|Last contact"
msgstr ""
@@ -31022,9 +31686,6 @@ msgstr ""
msgid "Runners|Runner %{name} was deleted"
msgstr ""
-msgid "Runners|Runner ID"
-msgstr ""
-
msgid "Runners|Runner assigned to project."
msgstr ""
@@ -31172,6 +31833,9 @@ msgstr ""
msgid "Runners|stale"
msgstr ""
+msgid "Runner|This runner has not run any jobs."
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -31286,6 +31950,24 @@ msgstr ""
msgid "Saving project."
msgstr ""
+msgid "ScanResultPolicy|%{ifLabelStart}if%{ifLabelEnd} %{scanners} scan in an open merge request targeting the %{branches} branch(es) finds %{vulnerabilitiesAllowed} or more %{severities} vulnerabilities that are %{vulnerabilityStates}"
+msgstr ""
+
+msgid "ScanResultPolicy|%{thenLabelStart}Then%{thenLabelEnd} Require approval from %{approvalsRequired} of the following approvers: %{approvers}"
+msgstr ""
+
+msgid "ScanResultPolicy|add an approver"
+msgstr ""
+
+msgid "ScanResultPolicy|scanners"
+msgstr ""
+
+msgid "ScanResultPolicy|severity levels"
+msgstr ""
+
+msgid "ScanResultPolicy|vulnerability states"
+msgstr ""
+
msgid "Scanner"
msgstr ""
@@ -31418,6 +32100,9 @@ msgstr ""
msgid "Search for a user"
msgstr ""
+msgid "Search for an emoji"
+msgstr ""
+
msgid "Search for projects, issues, etc."
msgstr ""
@@ -31605,18 +32290,12 @@ msgstr ""
msgid "Secret Detection"
msgstr ""
-msgid "Secret access key"
-msgstr ""
-
msgid "Secret token"
msgstr ""
msgid "Secure token that identifies an external storage request."
msgstr ""
-msgid "SecureCodeWarrior"
-msgstr ""
-
msgid "Security"
msgstr ""
@@ -31641,9 +32320,6 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "Security training with guide and learning pathways."
-msgstr ""
-
msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
@@ -31746,7 +32422,7 @@ msgstr ""
msgid "SecurityConfiguration|Manage corpus"
msgstr ""
-msgid "SecurityConfiguration|Manage corpus files used as mutation sources in coverage fuzzing."
+msgid "SecurityConfiguration|Manage corpus files used as seed inputs with coverage-guided fuzzing."
msgstr ""
msgid "SecurityConfiguration|Manage profiles for use by DAST scans."
@@ -31812,15 +32488,15 @@ msgstr ""
msgid "SecurityOrchestration|.yaml preview"
msgstr ""
-msgid "SecurityOrchestration|Action"
-msgstr ""
-
msgid "SecurityOrchestration|Actions"
msgstr ""
msgid "SecurityOrchestration|Add rule"
msgstr ""
+msgid "SecurityOrchestration|After dismissing the alert, the information will never be shown again."
+msgstr ""
+
msgid "SecurityOrchestration|All policies"
msgstr ""
@@ -31836,7 +32512,7 @@ msgstr ""
msgid "SecurityOrchestration|Description"
msgstr ""
-msgid "SecurityOrchestration|Disabled"
+msgid "SecurityOrchestration|Don't show the alert anymore"
msgstr ""
msgid "SecurityOrchestration|Edit policy"
@@ -31845,13 +32521,13 @@ msgstr ""
msgid "SecurityOrchestration|Edit policy project"
msgstr ""
-msgid "SecurityOrchestration|Enabled"
+msgid "SecurityOrchestration|Empty policy name"
msgstr ""
-msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Enabled"
msgstr ""
-msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
msgstr ""
msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
@@ -31860,7 +32536,7 @@ msgstr ""
msgid "SecurityOrchestration|Invalid policy type"
msgstr ""
-msgid "SecurityOrchestration|Latest scan"
+msgid "SecurityOrchestration|Latest scan run against %{agent}"
msgstr ""
msgid "SecurityOrchestration|Network"
@@ -31869,15 +32545,27 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No actions defined - policy will not run."
+msgstr ""
+
+msgid "SecurityOrchestration|No description"
+msgstr ""
+
msgid "SecurityOrchestration|No rules defined - policy will not run."
msgstr ""
+msgid "SecurityOrchestration|Not enabled"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
msgid "SecurityOrchestration|Policies"
msgstr ""
+msgid "SecurityOrchestration|Policy Type"
+msgstr ""
+
msgid "SecurityOrchestration|Policy cannot be enabled for non-existing branches (%{branches})"
msgstr ""
@@ -31902,10 +32590,13 @@ msgstr ""
msgid "SecurityOrchestration|Require %{approvals} %{plural} from %{approvers} if any of the following occur:"
msgstr ""
-msgid "SecurityOrchestration|Rule"
+msgid "SecurityOrchestration|Rules"
msgstr ""
-msgid "SecurityOrchestration|Rules"
+msgid "SecurityOrchestration|Runs %{actions} and %{lastAction} scans"
+msgstr ""
+
+msgid "SecurityOrchestration|Runs a %{action} scan"
msgstr ""
msgid "SecurityOrchestration|Scan Execution"
@@ -31965,6 +32656,9 @@ msgstr ""
msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
+msgid "SecurityOrchestration|This view only shows scan results for the agent %{agent}. You can view scan results for all agents in the %{linkStart}Operational Vulnerabilities tab of the vulnerability report%{linkEnd}."
+msgstr ""
+
msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
@@ -32019,9 +32713,6 @@ msgstr ""
msgid "SecurityOrchestration|users with ids"
msgstr ""
-msgid "SecurityOrchestration|view results"
-msgstr ""
-
msgid "SecurityOrchestration|vulnerabilities"
msgstr ""
@@ -32691,22 +33382,19 @@ 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|In order to start using functions as a service, you must first install Knative on your Kubernetes cluster. %{linkStart}More information%{linkEnd}"
-msgstr ""
-
msgid "Serverless|Learn more about Serverless"
msgstr ""
msgid "Serverless|No functions available"
msgstr ""
-msgid "Serverless|Sign up for First Look"
+msgid "Serverless|Serverless was %{linkStart}deprecated%{linkEnd} in GitLab 14.3."
+msgstr ""
+
+msgid "Serverless|Serverless was %{postLinkStart}deprecated%{postLinkEnd}. But if you opt to use it, you must install Knative in your Kubernetes cluster first. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "Serverless|The deploy job has not finished."
@@ -32718,9 +33406,6 @@ 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 ""
@@ -32736,9 +33421,6 @@ msgstr ""
msgid "Service Account Key"
msgstr ""
-msgid "Service Accounts"
-msgstr ""
-
msgid "Service Accounts keys authorize GitLab to deploy your Google Cloud project"
msgstr ""
@@ -32748,10 +33430,10 @@ msgstr ""
msgid "Service Desk allows people to create issues in your GitLab instance without their own user account. It provides a unique email address for end users to create issues in a project. Replies can be sent either through the GitLab interface or by email. End users only see threads through email."
msgstr ""
-msgid "Service Usage Data"
+msgid "Service account generated successfully"
msgstr ""
-msgid "Service account generated successfully"
+msgid "Service accounts"
msgstr ""
msgid "Service ping is disabled in your configuration file, and cannot be enabled through this form."
@@ -32895,6 +33577,9 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
+msgid "Set the per-user rate limit for getting a user by ID via the API."
+msgstr ""
+
msgid "Set the per-user rate limit for notes created by web or API requests."
msgstr ""
@@ -33074,6 +33759,9 @@ msgstr ""
msgid "Shared runners details"
msgstr ""
+msgid "Shared runners enabled cannot be enabled until a valid credit card is on file"
+msgstr ""
+
msgid "Shared runners help link"
msgstr ""
@@ -33131,6 +33819,9 @@ msgstr ""
msgid "Show all issues."
msgstr ""
+msgid "Show all milestones"
+msgstr ""
+
msgid "Show all test cases."
msgstr ""
@@ -33167,6 +33858,9 @@ msgstr ""
msgid "Show file contents"
msgstr ""
+msgid "Show group milestones"
+msgstr ""
+
msgid "Show labels"
msgstr ""
@@ -33182,6 +33876,12 @@ msgstr ""
msgid "Show open epics"
msgstr ""
+msgid "Show project milestones"
+msgstr ""
+
+msgid "Show sub-group milestones"
+msgstr ""
+
msgid "Show the Closed list"
msgstr ""
@@ -33191,11 +33891,6 @@ msgstr ""
msgid "Show whitespace changes"
msgstr ""
-msgid "Showing %d event"
-msgid_plural "Showing %d events"
-msgstr[0] ""
-msgstr[1] ""
-
msgid "Showing %{conflict} between %{sourceBranch} and %{targetBranch}"
msgstr ""
@@ -33255,12 +33950,6 @@ msgstr ""
msgid "Sidebar|None"
msgstr ""
-msgid "Sidebar|Only numeral characters allowed"
-msgstr ""
-
-msgid "Sidebar|Weight"
-msgstr ""
-
msgid "Sidekiq job compression threshold (bytes)"
msgstr ""
@@ -33423,6 +34112,9 @@ msgstr ""
msgid "Slack logo"
msgstr ""
+msgid "SlackIntegration|Are you sure you want to remove this project from the Slack application?"
+msgstr ""
+
msgid "SlackIntegration|GitLab for Slack"
msgstr ""
@@ -33432,6 +34124,9 @@ msgstr ""
msgid "SlackIntegration|Project alias"
msgstr ""
+msgid "SlackIntegration|Remove project"
+msgstr ""
+
msgid "SlackIntegration|Select a GitLab project to link with your Slack workspace."
msgstr ""
@@ -33576,9 +34271,6 @@ msgstr ""
msgid "Something went wrong trying to load issue contacts."
msgstr ""
-msgid "Something went wrong when creating a work item. Please try again"
-msgstr ""
-
msgid "Something went wrong when reordering designs. Please try again"
msgstr ""
@@ -33672,9 +34364,6 @@ msgstr ""
msgid "Something went wrong while inserting your image. Please try again."
msgstr ""
-msgid "Something went wrong while merging this merge request. Please try again."
-msgstr ""
-
msgid "Something went wrong while obtaining the Let's Encrypt certificate."
msgstr ""
@@ -33996,10 +34685,10 @@ 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."
+msgid "SourcegraphAdmin|Learn more."
msgstr ""
-msgid "SourcegraphAdmin|More information"
+msgid "SourcegraphAdmin|Only public projects have code intelligence enabled and communicate with Sourcegraph."
msgstr ""
msgid "SourcegraphAdmin|Save changes"
@@ -34008,7 +34697,7 @@ msgstr ""
msgid "SourcegraphAdmin|Sourcegraph URL"
msgstr ""
-msgid "SourcegraphAdmin|e.g. https://sourcegraph.example.com"
+msgid "SourcegraphAdmin|https://sourcegraph.example.com"
msgstr ""
msgid "SourcegraphPreferences|This feature is experimental and currently limited to certain projects."
@@ -34143,6 +34832,9 @@ msgstr ""
msgid "Start date"
msgstr ""
+msgid "Start free trial"
+msgstr ""
+
msgid "Start merge train"
msgstr ""
@@ -34173,6 +34865,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started escalation for this incident."
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -34185,6 +34880,9 @@ msgstr ""
msgid "Starts at (UTC)"
msgstr ""
+msgid "Starts escalations for this incident"
+msgstr ""
+
msgid "Starts on"
msgstr ""
@@ -34446,6 +35144,9 @@ msgstr ""
msgid "Strikethrough"
msgstr ""
+msgid "Strikethrough text"
+msgstr ""
+
msgid "Subgroup information"
msgstr ""
@@ -34680,6 +35381,21 @@ msgstr ""
msgid "Subscriptions"
msgstr ""
+msgid "Subscriptions|Chat with sales"
+msgstr ""
+
+msgid "Subscriptions|Close"
+msgstr ""
+
+msgid "Subscriptions|Not ready to buy yet?"
+msgstr ""
+
+msgid "Subscriptions|Start a free trial"
+msgstr ""
+
+msgid "Subscriptions|We understand. Maybe you have some questions for our sales team, or maybe you'd like to try some of the paid features first. What would you like to do?"
+msgstr ""
+
msgid "Subscription|Your subscription for %{strong}%{namespace_name}%{strong_close} has expired and you are now on %{pricing_link_start}the GitLab Free tier%{pricing_link_end}. Don't worry, your data is safe. Get in touch with our support team (%{support_email}). They'll gladly help with your subscription renewal."
msgstr ""
@@ -34890,6 +35606,9 @@ msgstr ""
msgid "SuperSonics|Maximum users"
msgstr ""
+msgid "SuperSonics|Offline cloud"
+msgstr ""
+
msgid "SuperSonics|Paste your activation code"
msgstr ""
@@ -34956,6 +35675,12 @@ msgstr ""
msgid "SuperSonics|You do not have an active subscription"
msgstr ""
+msgid "SuperSonics|You have a future dated license"
+msgstr ""
+
+msgid "SuperSonics|You have added a license that activates on %{date}. Please see the subscription history table below for more details."
+msgstr ""
+
msgid "SuperSonics|You have successfully added a license that activates on %{date}. Please see the subscription history table below for more details."
msgstr ""
@@ -35115,6 +35840,9 @@ msgstr ""
msgid "Tag name is required"
msgstr ""
+msgid "Tag push"
+msgstr ""
+
msgid "Tag push events"
msgstr ""
@@ -35217,6 +35945,9 @@ msgstr ""
msgid "TagsPage|protected"
msgstr ""
+msgid "Take a look at the documentation to discover all of GitLab’s capabilities."
+msgstr ""
+
msgid "Target Branch"
msgstr ""
@@ -35619,6 +36350,9 @@ msgstr ""
msgid "Tests"
msgstr ""
+msgid "Text (optional)"
+msgstr ""
+
msgid "Text added to the body of all email messages. %{character_limit} character limit"
msgstr ""
@@ -35669,6 +36403,9 @@ msgstr ""
msgid "The CSV export will be created in the background. Once finished, it will be sent to %{email} in an attachment."
msgstr ""
+msgid "The CSV export you requested of all user memberships is attached to this email."
+msgstr ""
+
msgid "The GitLab subscription service (customers.gitlab.com) is currently experiencing an outage. You can monitor the status and get updates at %{linkStart}status.gitlab.com%{linkEnd}."
msgstr ""
@@ -35744,6 +36481,9 @@ 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 epic"
+msgstr ""
+
msgid "The current issue"
msgstr ""
@@ -35905,6 +36645,9 @@ msgstr ""
msgid "The latest pipeline for this merge request has failed."
msgstr ""
+msgid "The license key is invalid."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -35920,6 +36663,9 @@ msgstr ""
msgid "The license was successfully uploaded and will be active from %{starts_at}. You can see the details below."
msgstr ""
+msgid "The license you uploaded is invalid. If the issue persists, contact support at %{link}."
+msgstr ""
+
msgid "The list creation wizard is already open"
msgstr ""
@@ -36541,10 +37287,13 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} and everything this project contains. %{strongOpen}There is no going back%{strongClose}"
+msgstr ""
+
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains."
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}on %{date}%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains. %{strongOpen}There is no going back.%{strongClose}"
msgstr ""
msgid "This action will %{strongOpen}permanently remove%{strongClose} %{codeOpen}%{group}%{codeClose} %{strongOpen}immediately%{strongClose}."
@@ -36673,9 +37422,6 @@ msgstr ""
msgid "This file was modified for readability, and can't accept suggestions. Edit it directly."
msgstr ""
-msgid "This forked project has the following:"
-msgstr ""
-
msgid "This form is disabled in preview"
msgstr ""
@@ -36688,7 +37434,7 @@ msgstr ""
msgid "This group can't be removed because it is linked to a subscription. To remove this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
-msgid "This group can't be transfered because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
+msgid "This group can't be transferred because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
msgid "This group cannot be invited to a project inside a group with enforced SSO"
@@ -36715,6 +37461,9 @@ 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 incident is already escalated with '%{escalation_policy_name}'."
+msgstr ""
+
msgid "This invitation was sent to %{mail_to_invite_email}, but you are signed in as %{link_to_current_user} with email %{mail_to_current_user}."
msgstr ""
@@ -36733,9 +37482,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 merge train pipeline"
-msgstr ""
-
msgid "This is a private email address %{helpIcon} generated just for you. Anyone who has it can create issues or merge requests as if they were you. If that happens, %{resetLinkStart}reset this token%{resetLinkEnd}."
msgstr ""
@@ -36757,6 +37503,12 @@ msgstr ""
msgid "This is your current session"
msgstr ""
+msgid "This issue cannot be assigned to a confidential epic because it is public."
+msgstr ""
+
+msgid "This issue cannot be made public because it belongs to a confidential epic."
+msgstr ""
+
msgid "This issue is confidential and should only be visible to team members with at least Reporter access."
msgstr ""
@@ -36874,6 +37626,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 branch is protected from force push."
+msgstr ""
+
msgid "This merge request cannot be rebased while there are conflicts."
msgstr ""
@@ -36925,9 +37680,15 @@ msgstr ""
msgid "This pipeline was triggered by a schedule."
msgstr ""
+msgid "This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project"
msgstr ""
+msgid "This project can be restored until %{date}."
+msgstr ""
+
msgid "This project cannot be %{visibilityLevel} because the visibility of %{openShowLink}%{name}%{closeShowLink} is %{visibility}. To make this project %{visibilityLevel}, you must first %{openEditLink}change the visibility%{closeEditLink} of the parent group."
msgstr ""
@@ -36946,6 +37707,9 @@ msgstr ""
msgid "This project is %{strongStart}NOT%{strongEnd} a fork, and has the following:"
msgstr ""
+msgid "This project is %{strongStart}NOT%{strongEnd} a fork. This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -37637,6 +38401,9 @@ msgstr ""
msgid "Today"
msgstr ""
+msgid "Todos count"
+msgstr ""
+
msgid "Todos|Are you looking for things to do? Take a look at %{strongStart}%{openIssuesLinkStart}open issues%{openIssuesLinkEnd}%{strongEnd}, contribute to %{strongStart}%{mergeRequestLinkStart}a merge request%{mergeRequestLinkEnd}%{mergeRequestLinkEnd}%{strongEnd}, or mention someone in a comment to automatically assign them a new to-do item."
msgstr ""
@@ -37910,10 +38677,8 @@ msgstr ""
msgid "Trending"
msgstr ""
-msgid "Trials|%{planName} Trial %{enDash} %{num} day left"
-msgid_plural "Trials|%{planName} Trial %{enDash} %{num} days left"
-msgstr[0] ""
-msgstr[1] ""
+msgid "Trials|%{planName} Trial"
+msgstr ""
msgid "Trials|Compare all plans"
msgstr ""
@@ -37921,6 +38686,9 @@ msgstr ""
msgid "Trials|Create a new group to start your GitLab Ultimate trial."
msgstr ""
+msgid "Trials|Day %{daysUsed}/%{duration}"
+msgstr ""
+
msgid "Trials|Go back to GitLab"
msgstr ""
@@ -38170,7 +38938,7 @@ msgstr ""
msgid "URL is triggered when repository is updated"
msgstr ""
-msgid "URL must be percent-encoded if neccessary."
+msgid "URL must be percent-encoded if necessary."
msgstr ""
msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
@@ -38389,6 +39157,9 @@ msgstr ""
msgid "Unlock account"
msgstr ""
+msgid "Unlock more features with GitLab Ultimate"
+msgstr ""
+
msgid "Unlock the discussion"
msgstr ""
@@ -38452,6 +39223,9 @@ msgstr ""
msgid "Unsubscribes from this %{quick_action_target}."
msgstr ""
+msgid "Unsupported sort value."
+msgstr ""
+
msgid "Unsupported todo type passed. Supported todo types are: %{todo_types}"
msgstr ""
@@ -38680,6 +39454,9 @@ msgstr ""
msgid "UsageQuota|File attachments and smaller design graphics."
msgstr ""
+msgid "UsageQuota|From %{storage_enforcement_date} storage limits will apply to this namespace. View and manage your usage in %{strong_start}Group Settings &gt; Usage quotas%{strong_end}."
+msgstr ""
+
msgid "UsageQuota|Git repository."
msgstr ""
@@ -38740,6 +39517,9 @@ msgstr ""
msgid "UsageQuota|Storage type"
msgstr ""
+msgid "UsageQuota|Storage used"
+msgstr ""
+
msgid "UsageQuota|This is the total amount of storage used across your projects within this namespace."
msgstr ""
@@ -38935,6 +39715,12 @@ msgstr ""
msgid "Use hashed storage paths for newly created and renamed repositories. Always enabled since 13.0."
msgstr ""
+msgid "Use issue count"
+msgstr ""
+
+msgid "Use issue weight"
+msgstr ""
+
msgid "Use one line per URI"
msgstr ""
@@ -39316,6 +40102,9 @@ msgstr ""
msgid "Users"
msgstr ""
+msgid "Users API rate limit"
+msgstr ""
+
msgid "Users can launch a development environment from a GitLab browser tab when the %{linkStart}Gitpod%{linkEnd} integration is enabled."
msgstr ""
@@ -39641,6 +40430,9 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View group pipeline usage quota"
+msgstr ""
+
msgid "View incident details at"
msgstr ""
@@ -39793,6 +40585,9 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
+msgid "Vulnerability"
+msgstr ""
+
msgid "Vulnerability Report"
msgstr ""
@@ -39844,6 +40639,9 @@ msgstr ""
msgid "VulnerabilityManagement|An unverified non-confirmed finding"
msgstr ""
+msgid "VulnerabilityManagement|At least one identifier is required"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -39853,12 +40651,24 @@ msgstr ""
msgid "VulnerabilityManagement|Create Jira issue"
msgstr ""
+msgid "VulnerabilityManagement|Enter a name"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE code"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE identifier URL"
+msgstr ""
+
msgid "VulnerabilityManagement|Fetching linked Jira issues"
msgstr ""
msgid "VulnerabilityManagement|Manually add a vulnerability entry into the vulnerability report."
msgstr ""
+msgid "VulnerabilityManagement|Name is a required field"
+msgstr ""
+
msgid "VulnerabilityManagement|Needs triage"
msgstr ""
@@ -39874,6 +40684,18 @@ msgstr ""
msgid "VulnerabilityManagement|Select a method"
msgstr ""
+msgid "VulnerabilityManagement|Select a severity level"
+msgstr ""
+
+msgid "VulnerabilityManagement|Select a status"
+msgstr ""
+
+msgid "VulnerabilityManagement|Severity is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Something went wrong while creating vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -39898,6 +40720,12 @@ msgstr ""
msgid "VulnerabilityManagement|Something went wrong, could not update vulnerability state."
msgstr ""
+msgid "VulnerabilityManagement|Status is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Submit vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Summary, detailed description, steps to reproduce, etc."
msgstr ""
@@ -40093,6 +40921,9 @@ msgstr ""
msgid "WARNING:"
msgstr ""
+msgid "WARNING: This snippet contains hidden files which might be used to mask malicious behavior. Exercise caution if cloning and executing code from this snippet."
+msgstr ""
+
msgid "Wait for the file to load to copy its contents"
msgstr ""
@@ -40312,6 +41143,15 @@ msgstr ""
msgid "Webhooks|An issue is created, updated, closed, or reopened."
msgstr ""
+msgid "Webhooks|Are you sure you want to delete this group hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this project hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this webhook?"
+msgstr ""
+
msgid "Webhooks|Comments"
msgstr ""
@@ -40321,6 +41161,9 @@ msgstr ""
msgid "Webhooks|Confidential issues events"
msgstr ""
+msgid "Webhooks|Delete webhook"
+msgstr ""
+
msgid "Webhooks|Deployment events"
msgstr ""
@@ -40554,6 +41397,9 @@ msgstr ""
msgid "Wiki"
msgstr ""
+msgid "Wiki page"
+msgstr ""
+
msgid "Wiki page was successfully created."
msgstr ""
@@ -40659,7 +41505,7 @@ msgstr ""
msgid "WikiPageConflictMessage|Someone edited the page the same time you did. Please check out %{wikiLinkStart}the page%{wikiLinkEnd} and make sure your changes will not unintentionally remove theirs."
msgstr ""
-msgid "WikiPage|An error occured while trying to render the content editor. Please try again later."
+msgid "WikiPage|An error occurred while trying to render the content editor. Please try again later."
msgstr ""
msgid "WikiPage|Are you sure you want to switch back to the classic editor?"
@@ -40818,6 +41664,18 @@ msgstr ""
msgid "WorkItem|New Task"
msgstr ""
+msgid "WorkItem|Something went wrong when creating a work item. Please try again"
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching the work item. Please try again."
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching work item types. Please try again"
+msgstr ""
+
+msgid "WorkItem|Type"
+msgstr ""
+
msgid "WorkItem|Work Items"
msgstr ""
@@ -40884,7 +41742,10 @@ msgstr ""
msgid "You are about to add %{usersTag} people to the discussion. They will all receive a notification."
msgstr ""
-msgid "You are about to permanently delete this project"
+msgid "You are about to delete this forked project containing:"
+msgstr ""
+
+msgid "You are about to delete this project containing:"
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."
@@ -40905,6 +41766,9 @@ msgstr ""
msgid "You are attempting to update a file that has changed since you started editing it."
msgstr ""
+msgid "You are billed if you exceed this number. %{qsrOverageLinkStart}How does billing work?%{qsrOverageLinkEnd}"
+msgstr ""
+
msgid "You are connected to the Prometheus server, but there is currently no data to display."
msgstr ""
@@ -40962,6 +41826,9 @@ msgstr ""
msgid "You are not authorized to update this scanner profile"
msgstr ""
+msgid "You are not authorized to upload metric images"
+msgstr ""
+
msgid "You are now impersonating %{username}"
msgstr ""
@@ -41115,9 +41982,6 @@ msgstr ""
msgid "You can only upload one design when dropping onto an existing design."
msgstr ""
-msgid "You can recover this project until %{date}"
-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 ""
@@ -41166,9 +42030,6 @@ msgstr ""
msgid "You cannot write to this read-only GitLab instance."
msgstr ""
-msgid "You can’t %{tag_start}edit%{tag_end} files directly in this project. Fork this project and submit a merge request with your changes."
-msgstr ""
-
msgid "You can’t edit files directly in this project. Fork this project and submit a merge request with your changes."
msgstr ""
@@ -41321,9 +42182,6 @@ 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 set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
@@ -41354,12 +42212,6 @@ msgstr ""
msgid "You must have maintainer access to force delete a lock"
msgstr ""
-msgid "You must have permission to create a project in a group before forking."
-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 ""
@@ -41765,7 +42617,7 @@ msgstr ""
msgid "Your public email will be displayed on your public profile."
msgstr ""
-msgid "Your request for access could not be processed: %{error_meesage}"
+msgid "Your request for access could not be processed: %{error_message}"
msgstr ""
msgid "Your request for access has been queued for review."
@@ -41948,6 +42800,9 @@ msgstr ""
msgid "archived:"
msgstr ""
+msgid "artifacts"
+msgstr ""
+
msgid "assign yourself"
msgstr ""
@@ -41977,6 +42832,9 @@ msgstr[1] ""
msgid "branch name"
msgstr ""
+msgid "builds"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -42400,6 +43258,9 @@ msgstr ""
msgid "contact with same email already exists in group hierarchy"
msgstr ""
+msgid "container registry images"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -42439,6 +43300,9 @@ msgstr ""
msgid "data"
msgstr ""
+msgid "database"
+msgstr ""
+
msgid "date must not be after 9999-12-31"
msgstr ""
@@ -42462,9 +43326,6 @@ msgstr ""
msgid "design"
msgstr ""
-msgid "detached"
-msgstr ""
-
msgid "disabled"
msgstr ""
@@ -42713,7 +43574,7 @@ msgstr ""
msgid "is not a valid X509 certificate."
msgstr ""
-msgid "is not allowed for sign-up."
+msgid "is not allowed for sign-up. Please use your regular email address."
msgstr ""
msgid "is not allowed for this group."
@@ -42725,7 +43586,7 @@ msgstr ""
msgid "is not allowed since the group is not top-level group."
msgstr ""
-msgid "is not allowed."
+msgid "is not allowed. Please use your regular email address."
msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
@@ -42812,6 +43673,9 @@ msgstr ""
msgid "level: %{level}"
msgstr ""
+msgid "lfs objects"
+msgstr ""
+
msgid "limit of %{project_limit} reached"
msgstr ""
@@ -43031,6 +43895,9 @@ msgstr ""
msgid "mrWidget|Merge blocked: pipeline must succeed. It's waiting for a manual action to continue."
msgstr ""
+msgid "mrWidget|Merge blocked: pipeline must succeed. Push a commit that fixes the failure, or %{linkStart}learn about other solutions.%{linkEnd}"
+msgstr ""
+
msgid "mrWidget|Merge blocked: this merge request must be approved."
msgstr ""
@@ -43148,9 +44015,6 @@ msgstr ""
msgid "mrWidget|The changes were not merged into"
msgstr ""
-msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -43298,9 +44162,6 @@ msgstr ""
msgid "open issue"
msgstr ""
-msgid "opened %{timeAgo}"
-msgstr ""
-
msgid "or"
msgstr ""
@@ -43312,6 +44173,12 @@ msgid_plural "out of %d total tests"
msgstr[0] ""
msgstr[1] ""
+msgid "packages"
+msgstr ""
+
+msgid "pages"
+msgstr ""
+
msgid "parent"
msgid_plural "parents"
msgstr[0] ""
@@ -43461,6 +44328,9 @@ msgid_plural "replies"
msgstr[0] ""
msgstr[1] ""
+msgid "repositories"
+msgstr ""
+
msgid "repository:"
msgstr ""
@@ -43581,12 +44451,18 @@ msgstr ""
msgid "tag name"
msgstr ""
+msgid "terraform states"
+msgstr ""
+
msgid "the correct format."
msgstr ""
msgid "the file"
msgstr ""
+msgid "the following epic(s)"
+msgstr ""
+
msgid "the following issue(s)"
msgstr ""
@@ -43599,21 +44475,12 @@ msgstr ""
msgid "this document"
msgstr ""
-msgid "this issue cannot be assigned to a confidential epic since it is public"
-msgstr ""
-
-msgid "this issue cannot be made public since it belongs to a confidential epic"
-msgstr ""
-
msgid "time summary"
msgstr ""
msgid "toggle collapse"
msgstr ""
-msgid "train"
-msgstr ""
-
msgid "triggered"
msgstr ""
@@ -43742,3 +44609,6 @@ msgstr ""
msgid "{project}"
msgstr ""
+msgid "✔"
+msgstr ""
+
diff --git a/locale/vi_VN/gitlab.po b/locale/vi_VN/gitlab.po
index 5656fc481a5..8054a8dcc76 100644
--- a/locale/vi_VN/gitlab.po
+++ b/locale/vi_VN/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: vi\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2022-02-02 15:42\n"
+"PO-Revision-Date: 2022-03-01 20:36\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -132,6 +132,10 @@ msgid "%d approver (you've approved)"
msgid_plural "%d approvers (you've approved)"
msgstr[0] ""
+msgid "%d assigned issue"
+msgid_plural "%d assigned issues"
+msgstr[0] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -352,8 +356,20 @@ msgid "%d vulnerability dismissed"
msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
-msgid "%d vulnerability updated"
-msgid_plural "%d vulnerabilities updated"
+msgid "%d vulnerability set to confirmed"
+msgid_plural "%d vulnerabilities set to confirmed"
+msgstr[0] ""
+
+msgid "%d vulnerability set to dismissed"
+msgid_plural "%d vulnerabilities set to dismissed"
+msgstr[0] ""
+
+msgid "%d vulnerability set to needs triage"
+msgid_plural "%d vulnerabilities set to needs triage"
+msgstr[0] ""
+
+msgid "%d vulnerability set to resolved"
+msgid_plural "%d vulnerabilities set to resolved"
msgstr[0] ""
msgid "%d warning found:"
@@ -434,6 +450,12 @@ msgstr[0] ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{completed} of %{total} issues closed"
+msgstr ""
+
+msgid "%{completed} of %{total} weight completed"
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -776,6 +798,9 @@ msgstr ""
msgid "%{openedIssues} open, %{closedIssues} closed"
msgstr ""
+msgid "%{percentage}%% issues closed"
+msgstr ""
+
msgid "%{percentage}%% weight completed"
msgstr ""
@@ -1190,6 +1215,9 @@ msgid "- User"
msgid_plural "- Users"
msgstr[0] ""
+msgid "- of - issues closed"
+msgstr ""
+
msgid "- of - weight completed"
msgstr ""
@@ -1309,7 +1337,7 @@ msgstr ""
msgid "1000+"
msgstr ""
-msgid "192.168.0.0/24"
+msgid "192.168.0.0/24 or 2001:0DB8:1234::/48"
msgstr ""
msgid "1st contribution!"
@@ -1621,13 +1649,13 @@ msgstr ""
msgid "AWS Access Key"
msgstr ""
-msgid "AWS Access Key. Only required if not using role instance credentials"
+msgid "AWS Secret Access Key"
msgstr ""
-msgid "AWS Secret Access Key"
+msgid "AWS access key ID (Optional)"
msgstr ""
-msgid "AWS Secret Access Key. Only required if not using role instance credentials"
+msgid "AWS secret access key (Optional)"
msgstr ""
msgid "AWS service error: %{error}"
@@ -1687,9 +1715,6 @@ msgstr ""
msgid "Access granted"
msgstr ""
-msgid "Access key ID"
-msgstr ""
-
msgid "Access requests"
msgstr ""
@@ -1864,7 +1889,7 @@ msgstr ""
msgid "Activity"
msgstr ""
-msgid "Activity|An error occured while retrieving activity. Reload the page to try again."
+msgid "Activity|An error occurred while retrieving activity. Reload the page to try again."
msgstr ""
msgid "Add"
@@ -1903,6 +1928,9 @@ msgstr ""
msgid "Add a %{type}"
msgstr ""
+msgid "Add a GCP region"
+msgstr ""
+
msgid "Add a GPG key"
msgstr ""
@@ -1954,6 +1982,9 @@ msgstr ""
msgid "Add a numbered list"
msgstr ""
+msgid "Add a related epic"
+msgstr ""
+
msgid "Add a related issue"
msgstr ""
@@ -2068,6 +2099,9 @@ msgstr ""
msgid "Add or subtract spent time"
msgstr ""
+msgid "Add people"
+msgstr ""
+
msgid "Add previously merged commits"
msgstr ""
@@ -2134,6 +2168,9 @@ msgstr ""
msgid "Add webhook"
msgstr ""
+msgid "Add your team members and others to GitLab."
+msgstr ""
+
msgid "Add/remove"
msgstr ""
@@ -2956,12 +2993,6 @@ msgstr ""
msgid "AdvancedSearch|Reindex required"
msgstr ""
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. Permanently deleting this project will %{strongStart}immediately delete%{strongEnd} its repositories and %{strongStart}all related resources%{strongEnd}, including issues, merge requests etc."
-msgstr ""
-
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. You will lose this project's repository and %{strongStart}all related resources%{strongEnd}, including issues and merge requests."
-msgstr ""
-
msgid "After a successful password update you will be redirected to login screen."
msgstr ""
@@ -2992,6 +3023,9 @@ msgstr ""
msgid "Akismet helps prevent the creation of spam issues in public projects."
msgstr ""
+msgid "Alert"
+msgstr ""
+
msgid "AlertManagement|Acknowledged"
msgstr ""
@@ -3364,9 +3398,6 @@ msgstr ""
msgid "All environments"
msgstr ""
-msgid "All epics"
-msgstr ""
-
msgid "All groups and projects"
msgstr ""
@@ -4101,11 +4132,14 @@ msgstr ""
msgid "ApplicationSettings|Approve users in the pending approval status?"
msgstr ""
-msgid "ApplicationSettings|By making this change, you will automatically approve %d user with the pending approval status."
-msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users with the pending approval status."
+msgid "ApplicationSettings|Approve users who are pending approval?"
+msgstr ""
+
+msgid "ApplicationSettings|By making this change, you will automatically approve %d user who is pending approval."
+msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users who are pending approval."
msgstr[0] ""
-msgid "ApplicationSettings|By making this change, you will automatically approve all users in pending approval status."
+msgid "ApplicationSettings|By making this change, you will automatically approve all users who are pending approval."
msgstr ""
msgid "ApplicationSettings|Denied domains for sign-ups"
@@ -4506,10 +4540,10 @@ msgstr ""
msgid "Archiving the project will make it entirely read-only. It is hidden from the dashboard and doesn't show up in searches. %{strong_start}The repository cannot be committed to, and no issues, comments, or other entities can be created.%{strong_end} %{link_start}Learn more.%{link_end}"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to delete this project?"
+msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
+msgid "Are you absolutely sure?"
msgstr ""
msgid "Are you sure that you want to archive this project?"
@@ -4545,12 +4579,18 @@ msgstr ""
msgid "Are you sure you want to delete this SSH key?"
msgstr ""
+msgid "Are you sure you want to delete this comment?"
+msgstr ""
+
msgid "Are you sure you want to delete this deploy key?"
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 label?"
+msgstr ""
+
msgid "Are you sure you want to delete this pipeline schedule?"
msgstr ""
@@ -4566,9 +4606,6 @@ msgstr ""
msgid "Are you sure you want to discard your changes?"
msgstr ""
-msgid "Are you sure you want to erase this build?"
-msgstr ""
-
msgid "Are you sure you want to import %d repository?"
msgid_plural "Are you sure you want to import %d repositories?"
msgstr[0] ""
@@ -4615,6 +4652,9 @@ msgstr ""
msgid "Are you sure you want to remove this list?"
msgstr ""
+msgid "Are you sure you want to remove this nickname?"
+msgstr ""
+
msgid "Are you sure you want to reset the health check token?"
msgstr ""
@@ -4627,10 +4667,10 @@ 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?"
+msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
msgstr ""
-msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
+msgid "Are you sure you want to revoke this project access token? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to stop this environment?"
@@ -4777,9 +4817,6 @@ msgstr ""
msgid "Assigned to %{assignee_name}"
msgstr ""
-msgid "Assigned to %{name}"
-msgstr ""
-
msgid "Assigned to me"
msgstr ""
@@ -4842,6 +4879,9 @@ msgstr[0] ""
msgid "Attaching the file failed."
msgstr ""
+msgid "Attention"
+msgstr ""
+
msgid "Audit Events"
msgstr ""
@@ -5004,6 +5044,12 @@ msgstr ""
msgid "Authorized applications (%{size})"
msgstr ""
+msgid "AuthorizedApplication|Are you sure you want to revoke this application?"
+msgstr ""
+
+msgid "AuthorizedApplication|Revoke application"
+msgstr ""
+
msgid "Authors: %{authors}"
msgstr ""
@@ -6193,6 +6239,9 @@ msgstr ""
msgid "CICDAnalytics|Shared Runners Usage"
msgstr ""
+msgid "CICDAnalytics|Shared runner pipeline minute duration by month"
+msgstr ""
+
msgid "CICDAnalytics|Shared runner usage"
msgstr ""
@@ -6334,6 +6383,9 @@ msgstr ""
msgid "Can create groups:"
msgstr ""
+msgid "Can not delete primary training"
+msgstr ""
+
msgid "Can't apply as the source branch was deleted."
msgstr ""
@@ -6667,9 +6719,6 @@ msgstr ""
msgid "Changing any setting here requires an application restart"
msgstr ""
-msgid "Changing group URL can have unintended side effects."
-msgstr ""
-
msgid "Charts can't be displayed as the request for data has timed out. %{documentationLink}"
msgstr ""
@@ -6757,9 +6806,6 @@ msgstr ""
msgid "Checking branch availability..."
msgstr ""
-msgid "Checking group URL availability..."
-msgstr ""
-
msgid "Checking group path availability..."
msgstr ""
@@ -7251,6 +7297,9 @@ msgstr ""
msgid "Clear recent searches"
msgstr ""
+msgid "Clear repository checks"
+msgstr ""
+
msgid "Clear search"
msgstr ""
@@ -7383,9 +7432,6 @@ msgstr ""
msgid "Closed MRs"
msgstr ""
-msgid "Closed epics"
-msgstr ""
-
msgid "Closed issues"
msgstr ""
@@ -7422,13 +7468,13 @@ msgstr ""
msgid "Cluster level"
msgstr ""
-msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
+msgid "Cluster type must be specified for Stages::ClusterEndpointInserter"
msgstr ""
msgid "ClusterAgents|%{name} successfully deleted"
msgstr ""
-msgid "ClusterAgents|%{number} of %{total} Agents"
+msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
@@ -7470,6 +7516,15 @@ msgstr ""
msgid "ClusterAgents|Agent never connected to GitLab"
msgstr ""
+msgid "ClusterAgents|Agent version mismatch"
+msgstr ""
+
+msgid "ClusterAgents|Agent version mismatch and update"
+msgstr ""
+
+msgid "ClusterAgents|Agent version update required"
+msgstr ""
+
msgid "ClusterAgents|All"
msgstr ""
@@ -7494,7 +7549,7 @@ msgstr ""
msgid "ClusterAgents|Configuration"
msgstr ""
-msgid "ClusterAgents|Connect a cluster through the Agent"
+msgid "ClusterAgents|Connect a cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connect existing cluster"
@@ -7503,13 +7558,13 @@ msgstr ""
msgid "ClusterAgents|Connect with a certificate"
msgstr ""
-msgid "ClusterAgents|Connect with agent"
+msgid "ClusterAgents|Connect with an agent"
msgstr ""
msgid "ClusterAgents|Connect with the GitLab Agent"
msgstr ""
-msgid "ClusterAgents|Connect your cluster through the Agent"
+msgid "ClusterAgents|Connect your cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connected"
@@ -7569,7 +7624,10 @@ msgstr ""
msgid "ClusterAgents|How to register an agent?"
msgstr ""
-msgid "ClusterAgents|Install new Agent"
+msgid "ClusterAgents|How to update an agent?"
+msgstr ""
+
+msgid "ClusterAgents|Install a new agent"
msgstr ""
msgid "ClusterAgents|Last connected %{timeAgo}."
@@ -7596,7 +7654,7 @@ msgstr ""
msgid "ClusterAgents|Never connected"
msgstr ""
-msgid "ClusterAgents|No Agents"
+msgid "ClusterAgents|No agents"
msgstr ""
msgid "ClusterAgents|No clusters connected through cluster certificates"
@@ -7656,6 +7714,9 @@ msgstr ""
msgid "ClusterAgents|The agent has not been connected in a long time. There might be a connectivity issue. Last contact was %{timeAgo}."
msgstr ""
+msgid "ClusterAgents|The agent version do not match each other across your cluster's pods. This can happen when a new agent version was just deployed and Kubernetes is shutting down the old pods."
+msgstr ""
+
msgid "ClusterAgents|The recommended installation method includes the token. If you want to follow the advanced installation method provided in the docs, make sure you save the token value before you close this window."
msgstr ""
@@ -7702,6 +7763,9 @@ msgstr ""
msgid "ClusterAgents|You will need to create a token to connect to your agent"
msgstr ""
+msgid "ClusterAgents|Your agent version is out of sync with your GitLab version (v%{version}), which might cause compatibility problems. Update the agent installed on your cluster to the most recent version."
+msgstr ""
+
msgid "ClusterAgents|Your instance doesn't have the %{linkStart}GitLab Agent Server (KAS)%{linkEnd} set up. Ask a GitLab Administrator to install it."
msgstr ""
@@ -8578,9 +8642,6 @@ msgstr ""
msgid "Comma-separated list of email addresses."
msgstr ""
-msgid "Comma-separated list of users allowed to exceed the rate limit."
-msgstr ""
-
msgid "Comma-separated, e.g. '1.1.1.1, 2.2.2.0/24'"
msgstr ""
@@ -8906,6 +8967,12 @@ msgstr ""
msgid "Confidential"
msgstr ""
+msgid "Confidential issue"
+msgstr ""
+
+msgid "Confidential note"
+msgstr ""
+
msgid "Confidentiality"
msgstr ""
@@ -8939,6 +9006,9 @@ msgstr ""
msgid "Configure Dependency Scanning in `.gitlab-ci.yml`, creating this file if it does not already exist"
msgstr ""
+msgid "Configure GitLab"
+msgstr ""
+
msgid "Configure GitLab runners to start using the Web Terminal. %{helpStart}Learn more.%{helpEnd}"
msgstr ""
@@ -8987,6 +9057,15 @@ msgstr ""
msgid "Configure pipelines to deploy web apps, backend services, APIs and static resources to Google Cloud"
msgstr ""
+msgid "Configure region"
+msgstr ""
+
+msgid "Configure region for environment"
+msgstr ""
+
+msgid "Configure regions"
+msgstr ""
+
msgid "Configure repository mirroring."
msgstr ""
@@ -9020,6 +9099,9 @@ msgstr ""
msgid "Configure which lists are shown for anyone who visits this board"
msgstr ""
+msgid "Configure your environments to be deployed to specific geographical regions"
+msgstr ""
+
msgid "Confirm"
msgstr ""
@@ -9719,10 +9801,10 @@ msgstr ""
msgid "CorpusManagement|Actions"
msgstr ""
-msgid "CorpusManagement|Corpus are used in fuzz testing as mutation source to Improve future testing."
+msgid "CorpusManagement|Corpus file"
msgstr ""
-msgid "CorpusManagement|Corpus file"
+msgid "CorpusManagement|Corpus files are used in coverage-guided fuzz testing as seed inputs to improve testing."
msgstr ""
msgid "CorpusManagement|Corpus files must be in *.zip format. Maximum 5 GB"
@@ -9776,6 +9858,9 @@ msgstr ""
msgid "Could not apply %{name} command."
msgstr ""
+msgid "Could not apply %{name} command. %{message}."
+msgstr ""
+
msgid "Could not authorize chat nickname. Try again!"
msgstr ""
@@ -9926,6 +10011,9 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
+msgid "Create a group"
+msgstr ""
+
msgid "Create a merge request"
msgstr ""
@@ -9950,6 +10038,9 @@ msgstr ""
msgid "Create a personal access token on your account to pull or push via %{protocol}."
msgstr ""
+msgid "Create a project"
+msgstr ""
+
msgid "Create an account using:"
msgstr ""
@@ -10313,6 +10404,9 @@ msgstr ""
msgid "Creation date"
msgstr ""
+msgid "Creator"
+msgstr ""
+
msgid "Credentials"
msgstr ""
@@ -10325,9 +10419,15 @@ msgstr ""
msgid "CredentialsInventory|Personal Access Tokens"
msgstr ""
+msgid "CredentialsInventory|Project Access Tokens"
+msgstr ""
+
msgid "CredentialsInventory|SSH Keys"
msgstr ""
+msgid "Credit card required to be on file in order to create a pipeline"
+msgstr ""
+
msgid "Credit card:"
msgstr ""
@@ -10511,9 +10611,6 @@ msgstr ""
msgid "Customer relations"
msgstr ""
-msgid "Customizable by an administrator."
-msgstr ""
-
msgid "Customizable by owners."
msgstr ""
@@ -10643,30 +10740,18 @@ msgstr ""
msgid "CycleAnalytics|%{selectedLabelsCount} selected (%{maxLabels} max)"
msgstr ""
-msgid "CycleAnalytics|%{stageCount} stages selected"
-msgstr ""
-
-msgid "CycleAnalytics|All stages"
-msgstr ""
-
-msgid "CycleAnalytics|Average days to completion"
+msgid "CycleAnalytics|Average time to completion"
msgstr ""
msgid "CycleAnalytics|Date"
msgstr ""
-msgid "CycleAnalytics|Days to completion"
-msgstr ""
-
msgid "CycleAnalytics|Display chart filters"
msgstr ""
msgid "CycleAnalytics|Lead Time for Changes"
msgstr ""
-msgid "CycleAnalytics|No stages selected"
-msgstr ""
-
msgid "CycleAnalytics|Number of tasks"
msgstr ""
@@ -10693,18 +10778,30 @@ msgstr ""
msgid "CycleAnalytics|Showing data for group '%{groupName}' from %{createdAfter} to %{createdBefore}"
msgstr ""
-msgid "CycleAnalytics|Stages"
+msgid "CycleAnalytics|Stage time: %{title}"
msgstr ""
msgid "CycleAnalytics|Tasks by type"
msgstr ""
-msgid "CycleAnalytics|The average time spent in the selected stage for the items that were completed on each date. Data limited to the last 500 items."
+msgid "CycleAnalytics|The average time items spent in this stage. Data limited to items completed within this date range."
msgstr ""
msgid "CycleAnalytics|The given date range is larger than 180 days"
msgstr ""
+msgid "CycleAnalytics|The total time items spent across each value stream stage. Data limited to items completed within this date range."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Stage time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Total time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|Total time"
+msgstr ""
+
msgid "CycleAnalytics|Type of work"
msgstr ""
@@ -10717,9 +10814,6 @@ msgstr ""
msgid "CycleAnalytics|project dropdown filter"
msgstr ""
-msgid "CycleAnalytics|stage dropdown"
-msgstr ""
-
msgid "DAG visualization requires at least 3 dependent jobs."
msgstr ""
@@ -10819,10 +10913,16 @@ msgstr ""
msgid "DastProfiles|AJAX spider"
msgstr ""
+msgid "DastProfiles|API"
+msgstr ""
+
+msgid "DastProfiles|API endpoint URL"
+msgstr ""
+
msgid "DastProfiles|Active"
msgstr ""
-msgid "DastProfiles|Additional request headers (Optional)"
+msgid "DastProfiles|Additional request headers (optional)"
msgstr ""
msgid "DastProfiles|Are you sure you want to delete this profile?"
@@ -10837,6 +10937,9 @@ msgstr ""
msgid "DastProfiles|Branch missing"
msgstr ""
+msgid "DastProfiles|Choose a scan method"
+msgstr ""
+
msgid "DastProfiles|Could not create the scanner profile. Please try again."
msgstr ""
@@ -10906,7 +11009,13 @@ msgstr ""
msgid "DastProfiles|Excluded URLs"
msgstr ""
-msgid "DastProfiles|Excluded URLs (Optional)"
+msgid "DastProfiles|Excluded URLs (optional)"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths (optional)"
msgstr ""
msgid "DastProfiles|Hide debug messages"
@@ -10963,9 +11072,6 @@ msgstr ""
msgid "DastProfiles|Request headers"
msgstr ""
-msgid "DastProfiles|Rest API"
-msgstr ""
-
msgid "DastProfiles|Run the AJAX spider, in addition to the traditional spider, to crawl the target site."
msgstr ""
@@ -10975,6 +11081,9 @@ msgstr ""
msgid "DastProfiles|Save profile"
msgstr ""
+msgid "DastProfiles|Scan method"
+msgstr ""
+
msgid "DastProfiles|Scan mode"
msgstr ""
@@ -11053,12 +11162,24 @@ msgstr ""
msgid "DastProfiles|Website"
msgstr ""
+msgid "DastProfiles|What does each method do?"
+msgstr ""
+
msgid "DastProfiles|You can either choose a passive scan or validate the target site from the site profile management page. %{docsLinkStart}Learn more about site validation.%{docsLinkEnd}"
msgstr ""
msgid "DastProfiles|You cannot run an active scan against an unvalidated site."
msgstr ""
+msgid "DastProfiles|folder/dast_example.har or https://example.com/dast_example.har"
+msgstr ""
+
+msgid "DastProfiles|folder/example.postman_collection.json or https://example.com/"
+msgstr ""
+
+msgid "DastProfiles|folder/openapi.json or https://example.com/openapi.json"
+msgstr ""
+
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
@@ -11165,6 +11286,9 @@ msgstr ""
msgid "DatadogIntegration|API URL"
msgstr ""
+msgid "DatadogIntegration|Custom tags in Datadog. Enter one tag per line in the %{codeOpen}key:value%{codeClose} format. %{linkOpen}How do I use tags?%{linkClose}"
+msgstr ""
+
msgid "DatadogIntegration|Environment"
msgstr ""
@@ -11183,12 +11307,18 @@ msgstr ""
msgid "DatadogIntegration|Tag all data from this GitLab instance in Datadog. Useful when managing several self-managed deployments."
msgstr ""
+msgid "DatadogIntegration|Tags"
+msgstr ""
+
msgid "DatadogIntegration|The Datadog site to send data to. To send data to the EU site, use %{codeOpen}datadoghq.eu%{codeClose}."
msgstr ""
msgid "DatadogIntegration|Trace your GitLab pipelines with Datadog."
msgstr ""
+msgid "DatadogIntegration|have an invalid format"
+msgstr ""
+
msgid "Datasource name not found"
msgstr ""
@@ -11198,9 +11328,6 @@ msgstr ""
msgid "Date merged"
msgstr ""
-msgid "Date picker"
-msgstr ""
-
msgid "Date range"
msgstr ""
@@ -11354,9 +11481,6 @@ msgstr ""
msgid "Definition"
msgstr ""
-msgid "Delayed Project Deletion (%{adjourned_deletion})"
-msgstr ""
-
msgid "DelayedJobs|Are you sure you want to run %{jobName} immediately? Otherwise this job will run automatically after its timer finishes."
msgstr ""
@@ -11435,10 +11559,10 @@ msgstr ""
msgid "Delete pipeline"
msgstr ""
-msgid "Delete project"
+msgid "Delete pipeline schedule"
msgstr ""
-msgid "Delete project. Are you ABSOLUTELY SURE?"
+msgid "Delete project"
msgstr ""
msgid "Delete row"
@@ -11468,6 +11592,9 @@ msgstr ""
msgid "Delete this epic and all descendants?"
msgstr ""
+msgid "Delete this project"
+msgstr ""
+
msgid "Delete user list"
msgstr ""
@@ -11720,6 +11847,12 @@ msgstr ""
msgid "Deploy to..."
msgstr ""
+msgid "DeployBoards|To see deployment progress for your environments, make sure you are deploying to %{codeStart}$KUBE_NAMESPACE%{codeEnd} and annotating with %{codeStart}app.gitlab.com/app=$CI_PROJECT_PATH_SLUG%{codeEnd} and %{codeStart}app.gitlab.com/env=$CI_ENVIRONMENT_SLUG%{codeEnd}."
+msgstr ""
+
+msgid "DeployBoard|Kubernetes Pods"
+msgstr ""
+
msgid "DeployFreeze|Add a freeze period to prevent unintended releases during a period of time for a given environment. You must update the deployment jobs in %{filename} according to the deploy freezes added here. %{freeze_period_link_start}Learn more.%{freeze_period_link_end}"
msgstr ""
@@ -11804,9 +11937,6 @@ msgstr ""
msgid "DeployTokens|Active Deploy Tokens (%{active_tokens})"
msgstr ""
-msgid "DeployTokens|Allows read and write access to registry images."
-msgstr ""
-
msgid "DeployTokens|Allows read and write access to the package registry."
msgstr ""
@@ -11819,6 +11949,9 @@ msgstr ""
msgid "DeployTokens|Allows read-only access to the repository."
msgstr ""
+msgid "DeployTokens|Allows write access to registry images."
+msgstr ""
+
msgid "DeployTokens|Copy deploy token"
msgstr ""
@@ -11912,12 +12045,57 @@ msgstr ""
msgid "Deploying to AWS is easy with GitLab"
msgstr ""
+msgid "Deployment"
+msgstr ""
+
msgid "Deployment Frequency"
msgstr ""
+msgid "Deployment Target|Project deployment target (optional)"
+msgstr ""
+
+msgid "Deployment Target|Select the deployment target"
+msgstr ""
+
msgid "Deployment frequency"
msgstr ""
+msgid "DeploymentTarget|GitLab Pages"
+msgstr ""
+
+msgid "DeploymentTarget|Heroku"
+msgstr ""
+
+msgid "DeploymentTarget|Infrastructure provider (Terraform, Cloudformation, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Kubernetes (GKE, EKS, OpenShift, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Managed container runtime (Fargate, Cloud Run, DigitalOcean App)"
+msgstr ""
+
+msgid "DeploymentTarget|Mobile app store"
+msgstr ""
+
+msgid "DeploymentTarget|No deployment planned"
+msgstr ""
+
+msgid "DeploymentTarget|Other hosting service"
+msgstr ""
+
+msgid "DeploymentTarget|Registry (package or container)"
+msgstr ""
+
+msgid "DeploymentTarget|Self-managed container runtime (Podman, Docker Swarm, Docker Compose)"
+msgstr ""
+
+msgid "DeploymentTarget|Serverless backend (Lambda, Cloud functions)"
+msgstr ""
+
+msgid "DeploymentTarget|Virtual machine (for example, EC2)"
+msgstr ""
+
msgid "Deployments"
msgstr ""
@@ -11955,6 +12133,9 @@ msgstr ""
msgid "Deployment|This deployment was created using the API"
msgstr ""
+msgid "Deployment|Triggerer"
+msgstr ""
+
msgid "Deployment|Waiting"
msgstr ""
@@ -11982,6 +12163,18 @@ msgstr ""
msgid "Deprecated API rate limits"
msgstr ""
+msgid "Deprecations|Feature deprecation and removal"
+msgstr ""
+
+msgid "Deprecations|For information on a possible replacement %{epicStart} learn more about Opstrace %{epicEnd}."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7 and are %{epicStart} scheduled for removal %{epicEnd} in GitLab 15.0."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7, and are %{removal_link_start} scheduled for removal %{link_end} in GitLab 15.0. For information on a possible replacement, %{opstrace_link_start} learn more about Opstrace %{link_end}."
+msgstr ""
+
msgid "Deprioritize label"
msgstr ""
@@ -12226,10 +12419,10 @@ msgstr ""
msgid "DevopsAdoption|At least one deploy"
msgstr ""
-msgid "DevopsAdoption|At least one issue opened"
+msgid "DevopsAdoption|At least one issue created"
msgstr ""
-msgid "DevopsAdoption|At least one merge request opened"
+msgid "DevopsAdoption|At least one merge request created"
msgstr ""
msgid "DevopsAdoption|At least one pipeline successfully run"
@@ -12427,6 +12620,9 @@ msgstr ""
msgid "Direct member"
msgstr ""
+msgid "Direct members"
+msgstr ""
+
msgid "Direct non-authenticated users to this page."
msgstr ""
@@ -12542,6 +12738,9 @@ msgid "Dismiss %d selected vulnerability as"
msgid_plural "Dismiss %d selected vulnerabilities as"
msgstr[0] ""
+msgid "Dismiss Alert"
+msgstr ""
+
msgid "Dismiss merge request promotion"
msgstr ""
@@ -12569,9 +12768,15 @@ msgstr ""
msgid "Display alerts from all configured monitoring tools."
msgstr ""
+msgid "Display milestones"
+msgstr ""
+
msgid "Display name"
msgstr ""
+msgid "Display progress of child issues"
+msgstr ""
+
msgid "Display rendered file"
msgstr ""
@@ -12677,6 +12882,9 @@ msgstr ""
msgid "Download image"
msgstr ""
+msgid "Download payload"
+msgstr ""
+
msgid "Download raw data (.csv)"
msgstr ""
@@ -12854,6 +13062,9 @@ msgstr ""
msgid "Edit in Web IDE"
msgstr ""
+msgid "Edit in pipeline editor"
+msgstr ""
+
msgid "Edit in single-file editor"
msgstr ""
@@ -12896,6 +13107,9 @@ msgstr ""
msgid "Edit your most recent comment in a thread (from an empty textarea)"
msgstr ""
+msgid "Edit, lint, and visualize your pipeline."
+msgstr ""
+
msgid "Edited"
msgstr ""
@@ -13337,6 +13551,9 @@ msgstr ""
msgid "Enforce two-factor authentication for all user sign-ins."
msgstr ""
+msgid "Enhance security by storing service account keys in secret managers - learn more about %{docLinkStart}secret management with GitLab%{docLinkEnd}"
+msgstr ""
+
msgid "Ensure connectivity is available from the GitLab server to the Prometheus server"
msgstr ""
@@ -13397,6 +13614,9 @@ 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 following to confirm:"
+msgstr ""
+
msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
@@ -13926,9 +14146,6 @@ 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 ""
@@ -14064,6 +14281,9 @@ msgstr ""
msgid "Errors:"
msgstr ""
+msgid "Escalate this incident"
+msgstr ""
+
msgid "Escalation Policies"
msgstr ""
@@ -14076,6 +14296,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy"
+msgstr ""
+
msgid "Escalation policy:"
msgstr ""
@@ -14326,6 +14549,9 @@ msgstr ""
msgid "Existing sign in methods may be removed"
msgstr ""
+msgid "Exit."
+msgstr ""
+
msgid "Expand"
msgstr ""
@@ -14422,6 +14648,9 @@ msgstr ""
msgid "Explore public groups"
msgstr ""
+msgid "Explore public projects"
+msgstr ""
+
msgid "Explore snippets"
msgstr ""
@@ -14582,7 +14811,7 @@ msgid "Failed to archive a design. Please try again."
msgid_plural "Failed to archive designs. Please try again."
msgstr[0] ""
-msgid "Failed to assign a reviewer because no user was found."
+msgid "Failed to assign a reviewer because no user was specified."
msgstr ""
msgid "Failed to assign a user because no user was found."
@@ -14648,10 +14877,10 @@ msgstr ""
msgid "Failed to find import label for Jira import."
msgstr ""
-msgid "Failed to generate export, please try again later."
+msgid "Failed to find users for %{missing}"
msgstr ""
-msgid "Failed to generate report, please try again after sometime"
+msgid "Failed to generate export, please try again later."
msgstr ""
msgid "Failed to get ref."
@@ -14750,6 +14979,9 @@ msgstr ""
msgid "Failed to remove a to-do item for the design."
msgstr ""
+msgid "Failed to remove attention because no user was found."
+msgstr ""
+
msgid "Failed to remove mirror."
msgstr ""
@@ -14762,6 +14994,9 @@ msgstr ""
msgid "Failed to remove user key."
msgstr ""
+msgid "Failed to request attention because no user was found."
+msgstr ""
+
msgid "Failed to reset key. Please try again."
msgstr ""
@@ -14843,6 +15078,9 @@ msgstr ""
msgid "Feature Flags"
msgstr ""
+msgid "Feature deprecation and removal"
+msgstr ""
+
msgid "Feature flag status"
msgstr ""
@@ -15339,7 +15577,7 @@ msgstr ""
msgid "For each job, re-use the project workspace. If the workspace doesn't exist, use %{code_open}git clone%{code_close}."
msgstr ""
-msgid "For example, the application using the token or the purpose of the token."
+msgid "For example, the application using the token or the purpose of the token. Do not give sensitive information for the name of the token, as it will be visible to all %{resource_type} members."
msgstr ""
msgid "For files larger than this limit, only index the file name. The file content is neither indexed nor searchable."
@@ -15423,9 +15661,6 @@ msgstr ""
msgid "ForkProject|Select a namespace"
msgstr ""
-msgid "ForkProject|Select a namespace to fork the project"
-msgstr ""
-
msgid "ForkProject|The project can be accessed by any logged in user."
msgstr ""
@@ -15522,6 +15757,9 @@ msgstr ""
msgid "Full name"
msgstr ""
+msgid "GCP region configured"
+msgstr ""
+
msgid "GPG Key ID:"
msgstr ""
@@ -15702,6 +15940,9 @@ msgstr ""
msgid "Geo|Failed"
msgstr ""
+msgid "Geo|Filter Geo sites"
+msgstr ""
+
msgid "Geo|Filter by name"
msgstr ""
@@ -16113,6 +16354,12 @@ msgstr ""
msgid "GitLab Issue"
msgstr ""
+msgid "GitLab KAS"
+msgstr ""
+
+msgid "GitLab Memberships CSV Export"
+msgstr ""
+
msgid "GitLab Pages"
msgstr ""
@@ -16161,6 +16408,9 @@ 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 free to use. Many features for larger teams are part of our %{link_start}paid products%{link_end}. You can try Ultimate for free without any obligation or payment details."
+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 ""
@@ -16287,7 +16537,7 @@ msgstr ""
msgid "GitLabPages|When enabled, all attempts to visit your website through HTTP are automatically redirected to HTTPS using a response with status code 301. Requires a valid certificate for all domains. %{docs_link_start}Learn more.%{link_end}"
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. %{docs_link_start}Learn more.%{link_end}"
+msgid "GitLabPages|When using Pages under the general domain of a GitLab instance (%{pages_host}), you cannot use HTTPS with subdomains of subdomains. If your namespace or groupname contains a dot, it does not work. This is a limitation of the HTTP Over TLS protocol. HTTP pages work if you don't redirect HTTP to HTTPS. %{docs_link_start}Learn more.%{link_end}"
msgstr ""
msgid "GitLabPages|With GitLab Pages you can host your static website directly from your GitLab repository. %{docs_link_start}Learn more.%{link_end}"
@@ -16464,9 +16714,6 @@ msgstr ""
msgid "Go to find file"
msgstr ""
-msgid "Go to fork"
-msgstr ""
-
msgid "Go to issue boards"
msgstr ""
@@ -16674,9 +16921,6 @@ msgstr ""
msgid "Group Hooks"
msgstr ""
-msgid "Group ID"
-msgstr ""
-
msgid "Group Owner must have signed in with SAML before enabling Group Managed Accounts"
msgstr ""
@@ -16704,9 +16948,6 @@ msgstr ""
msgid "Group by"
msgstr ""
-msgid "Group description"
-msgstr ""
-
msgid "Group description (optional)"
msgstr ""
@@ -16821,7 +17062,7 @@ msgstr ""
msgid "Group: %{name}"
msgstr ""
-msgid "GroupActivityMetrics|Issues opened"
+msgid "GroupActivityMetrics|Issues created"
msgstr ""
msgid "GroupActivityMetrics|Last 90 days"
@@ -16830,7 +17071,7 @@ msgstr ""
msgid "GroupActivityMetrics|Members added"
msgstr ""
-msgid "GroupActivityMetrics|Merge Requests opened"
+msgid "GroupActivityMetrics|Merge Requests created"
msgstr ""
msgid "GroupActivityMetrics|Recent activity"
@@ -17121,6 +17362,9 @@ msgstr ""
msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
+msgid "GroupSettings|Choose a group path that does not start with a dash or end with a period. It can also contain alphanumeric characters and underscores."
+msgstr ""
+
msgid "GroupSettings|Compliance frameworks"
msgstr ""
@@ -17154,7 +17398,7 @@ msgstr ""
msgid "GroupSettings|If not specified at the group or instance level, the default is %{default_initial_branch_name}. Does not affect existing repositories."
msgstr ""
-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."
+msgid "GroupSettings|If the parent group's visibility is lower than the group's current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility."
msgstr ""
msgid "GroupSettings|New runners registration token has been generated!"
@@ -17271,7 +17515,10 @@ msgstr ""
msgid "Groups and projects"
msgstr ""
-msgid "Groups and subgroups"
+msgid "Groups are a great way to organize projects and people."
+msgstr ""
+
+msgid "Groups are the best way to manage projects and members."
msgstr ""
msgid "Groups to synchronize"
@@ -17382,13 +17629,16 @@ msgstr ""
msgid "GroupsTree|Are you sure you want to leave the \"%{fullName}\" group?"
msgstr ""
-msgid "GroupsTree|Edit group"
+msgid "GroupsTree|Delete"
+msgstr ""
+
+msgid "GroupsTree|Edit"
msgstr ""
msgid "GroupsTree|Failed to leave the group. Please make sure you are not the only owner."
msgstr ""
-msgid "GroupsTree|Leave this group"
+msgid "GroupsTree|Leave group"
msgstr ""
msgid "GroupsTree|Loading groups"
@@ -17400,9 +17650,57 @@ msgstr ""
msgid "GroupsTree|No groups or projects matched your search"
msgstr ""
+msgid "GroupsTree|Options"
+msgstr ""
+
msgid "GroupsTree|Search by name"
msgstr ""
+msgid "Groups|Avatar will be removed. Are you sure?"
+msgstr ""
+
+msgid "Groups|Changing group URL can have unintended side effects."
+msgstr ""
+
+msgid "Groups|Checking group URL availability..."
+msgstr ""
+
+msgid "Groups|Enter a descriptive name for your group."
+msgstr ""
+
+msgid "Groups|Group ID"
+msgstr ""
+
+msgid "Groups|Group URL"
+msgstr ""
+
+msgid "Groups|Group avatar"
+msgstr ""
+
+msgid "Groups|Group description (optional)"
+msgstr ""
+
+msgid "Groups|Group name"
+msgstr ""
+
+msgid "Groups|Group path is available."
+msgstr ""
+
+msgid "Groups|Group path is unavailable. Path has been replaced with a suggested available path."
+msgstr ""
+
+msgid "Groups|Learn more"
+msgstr ""
+
+msgid "Groups|Must start with letter, digit, emoji, or underscore. Can also contain periods, dashes, spaces, and parentheses."
+msgstr ""
+
+msgid "Groups|Remove avatar"
+msgstr ""
+
+msgid "Groups|Save changes"
+msgstr ""
+
msgid "Guideline"
msgstr ""
@@ -17412,6 +17710,9 @@ msgstr ""
msgid "HAR file path or URL"
msgstr ""
+msgid "HTTP Archive (HAR)"
+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 ""
@@ -17810,6 +18111,9 @@ msgstr ""
msgid "INFO: Your SSH key is expiring soon. Please generate a new key."
msgstr ""
+msgid "IP"
+msgstr ""
+
msgid "IP Address"
msgstr ""
@@ -17846,6 +18150,9 @@ msgstr ""
msgid "IdentityVerification|Verify your identity"
msgstr ""
+msgid "IdentityVerification|You can always verify your account at a later time to create a group."
+msgstr ""
+
msgid "If any indexed field exceeds this limit, it is truncated to this number of characters. The rest of the content is neither indexed nor searchable. This does not apply to repository and wiki indexing. For unlimited characters, set this to 0."
msgstr ""
@@ -17903,6 +18210,9 @@ msgstr ""
msgid "If you add %{codeStart}needs%{codeEnd} to jobs in your pipeline you'll be able to view the %{codeStart}needs%{codeEnd} relationships between jobs in this tab as a %{linkStart}Directed Acyclic Graph (DAG)%{linkEnd}."
msgstr ""
+msgid "If you are added to a project, it will be displayed here."
+msgstr ""
+
msgid "If you did not initiate these sign-in attempts, please reach out to your administrator or enable two-factor authentication (2FA) on your account."
msgstr ""
@@ -18206,12 +18516,24 @@ msgstr ""
msgid "InProductMarketing|3 ways to dive into GitLab CI/CD"
msgstr ""
+msgid "InProductMarketing|A single application eliminates complex integrations, data chokepoints, and toolchain maintenance, resulting in greater productivity and lower cost."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features, build more efficiently, strengthen security and compliance."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features."
+msgstr ""
+
msgid "InProductMarketing|Actually, GitLab makes the team work (better)"
msgstr ""
msgid "InProductMarketing|And finally %{deploy_link} a Python application."
msgstr ""
+msgid "InProductMarketing|And many more..."
+msgstr ""
+
msgid "InProductMarketing|Are your runners ready?"
msgstr ""
@@ -18230,15 +18552,33 @@ msgstr ""
msgid "InProductMarketing|Blog"
msgstr ""
+msgid "InProductMarketing|Break down silos to coordinate seamlessly across development, operations, and security with a consistent experience across the development lifecycle."
+msgstr ""
+
+msgid "InProductMarketing|Burn up/down charts"
+msgstr ""
+
msgid "InProductMarketing|By enabling code owners and required merge approvals the right person will review the right MR. This is a win-win: cleaner code and a more efficient review process."
msgstr ""
msgid "InProductMarketing|Click on the number below that corresponds with your answer — 1 being very difficult, 5 being very easy."
msgstr ""
+msgid "InProductMarketing|Code owners"
+msgstr ""
+
msgid "InProductMarketing|Code owners and required merge approvals are part of the paid tiers of GitLab. You can start a free 30-day trial of GitLab Ultimate and enable these features in less than 5 minutes with no credit card required."
msgstr ""
+msgid "InProductMarketing|Code review analytics"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration across stages in GitLab"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration made easy"
+msgstr ""
+
msgid "InProductMarketing|Create a custom CI runner with just a few clicks"
msgstr ""
@@ -18248,12 +18588,21 @@ msgstr ""
msgid "InProductMarketing|Create a project in GitLab in 5 minutes"
msgstr ""
+msgid "InProductMarketing|Create well-defined workflows by using scoped labels on issues, merge requests, and epics. Labels with the same scope cannot be used together, which prevents conflicts."
+msgstr ""
+
msgid "InProductMarketing|Create your first project!"
msgstr ""
+msgid "InProductMarketing|Define who owns specific files or directories, so the right reviewers are suggested when a merge request introduces changes to those files."
+msgstr ""
+
msgid "InProductMarketing|Deliver Better Products Faster"
msgstr ""
+msgid "InProductMarketing|Dependency scanning"
+msgstr ""
+
msgid "InProductMarketing|Did you know teams that use GitLab are far more efficient?"
msgstr ""
@@ -18263,15 +18612,27 @@ msgstr ""
msgid "InProductMarketing|Dig in and create a project and a repo"
msgstr ""
+msgid "InProductMarketing|Discover Premium & Ultimate"
+msgstr ""
+
+msgid "InProductMarketing|Discover Premium & Ultimate."
+msgstr ""
+
msgid "InProductMarketing|Do you have a minute?"
msgstr ""
msgid "InProductMarketing|Do you have a teammate who would be perfect for this task?"
msgstr ""
+msgid "InProductMarketing|Dynamic application security testing"
+msgstr ""
+
msgid "InProductMarketing|Easy"
msgstr ""
+msgid "InProductMarketing|Epics"
+msgstr ""
+
msgid "InProductMarketing|Expand your DevOps journey with a free GitLab trial"
msgstr ""
@@ -18293,9 +18654,15 @@ msgstr ""
msgid "InProductMarketing|Feel the need for speed?"
msgstr ""
+msgid "InProductMarketing|Find and fix bottlenecks in your code review process by understanding how long open merge requests have been in review."
+msgstr ""
+
msgid "InProductMarketing|Find out how your teams are really doing"
msgstr ""
+msgid "InProductMarketing|Find out if your external libraries are safe. Run dependency scanning jobs that check for known vulnerabilities in your external libraries."
+msgstr ""
+
msgid "InProductMarketing|Follow our steps"
msgstr ""
@@ -18332,6 +18699,9 @@ msgstr ""
msgid "InProductMarketing|GitLab is better with teammates to help out!"
msgstr ""
+msgid "InProductMarketing|GitLab is infrastructure agnostic (supporting GCP, AWS, Azure, OpenShift, VMWare, On Prem, Bare Metal, and more), offering a consistent workflow experience – irrespective of the environment."
+msgstr ""
+
msgid "InProductMarketing|GitLab provides static application security testing (SAST), dynamic application security testing (DAST), container scanning, and dependency scanning to help you deliver secure applications along with license compliance."
msgstr ""
@@ -18422,21 +18792,36 @@ msgstr ""
msgid "InProductMarketing|It's also possible to simply %{external_repo_link} in order to take advantage of GitLab's CI/CD."
msgstr ""
+msgid "InProductMarketing|Keep your code quality high by defining who should approve merge requests and how many approvals are required."
+msgstr ""
+
msgid "InProductMarketing|Launch GitLab CI/CD in 20 minutes or less"
msgstr ""
+msgid "InProductMarketing|Lower cost of development"
+msgstr ""
+
+msgid "InProductMarketing|Make it easier to collaborate on high-level ideas by grouping related issues in an epic."
+msgstr ""
+
msgid "InProductMarketing|Making the switch? It's easier than you think to import your projects into GitLab. Move %{github_link}, or import something %{bitbucket_link}."
msgstr ""
msgid "InProductMarketing|Master the art of importing!"
msgstr ""
+msgid "InProductMarketing|Merge request approval rule"
+msgstr ""
+
msgid "InProductMarketing|Move on to easily creating a Pages website %{ci_template_link}"
msgstr ""
msgid "InProductMarketing|Multiple owners, confusing workstreams? We've got you covered"
msgstr ""
+msgid "InProductMarketing|Multiple required approvers"
+msgstr ""
+
msgid "InProductMarketing|Need an alternative to importing?"
msgstr ""
@@ -18449,18 +18834,33 @@ msgstr ""
msgid "InProductMarketing|Our tool brings all the things together"
msgstr ""
+msgid "InProductMarketing|Protect your web application by using DAST to examine for vulnerabilities in deployed environments."
+msgstr ""
+
msgid "InProductMarketing|Rapid development, simplified"
msgstr ""
msgid "InProductMarketing|Reduce Security & Compliance Risk"
msgstr ""
+msgid "InProductMarketing|Require multiple approvers on a merge request, so you know it's in good shape before it's merged."
+msgstr ""
+
+msgid "InProductMarketing|Roadmaps"
+msgstr ""
+
+msgid "InProductMarketing|Scoped labels"
+msgstr ""
+
msgid "InProductMarketing|Security that's integrated into your development lifecycle"
msgstr ""
msgid "InProductMarketing|Sometimes you're not ready to make a full transition to a new tool. If you're not ready to fully commit, %{mirroring_link} gives you a safe way to try out GitLab in parallel with your current tool."
msgstr ""
+msgid "InProductMarketing|Speed. Efficiency. Trust."
+msgstr ""
+
msgid "InProductMarketing|Spin up an autoscaling runner in GitLab"
msgstr ""
@@ -18470,6 +18870,9 @@ msgstr ""
msgid "InProductMarketing|Start a Self-Managed trial"
msgstr ""
+msgid "InProductMarketing|Start a free trial"
+msgstr ""
+
msgid "InProductMarketing|Start a free trial of GitLab Ultimate – no credit card required"
msgstr ""
@@ -18536,6 +18939,9 @@ msgstr ""
msgid "InProductMarketing|To understand and get the most out of GitLab, start at the beginning and %{project_link}. In GitLab, repositories are part of a project, so after you've created your project you can go ahead and %{repo_link}."
msgstr ""
+msgid "InProductMarketing|Track completed issues in a chart, so you can see how a milestone is progressing at a glance."
+msgstr ""
+
msgid "InProductMarketing|Try GitLab Ultimate for free"
msgstr ""
@@ -18572,6 +18978,9 @@ msgstr ""
msgid "InProductMarketing|Very easy"
msgstr ""
+msgid "InProductMarketing|Visualize your epics and milestones in a timeline."
+msgstr ""
+
msgid "InProductMarketing|Want to host GitLab on your servers?"
msgstr ""
@@ -18593,6 +19002,9 @@ msgstr ""
msgid "InProductMarketing|YouTube"
msgstr ""
+msgid "InProductMarketing|Your software, deployed your way"
+msgstr ""
+
msgid "InProductMarketing|Your teams can be more efficient"
msgstr ""
@@ -18713,9 +19125,18 @@ msgstr ""
msgid "IncidentManagement|No incidents to display."
msgstr ""
+msgid "IncidentManagement|None"
+msgstr ""
+
msgid "IncidentManagement|Open"
msgstr ""
+msgid "IncidentManagement|Page your team with escalation policies"
+msgstr ""
+
+msgid "IncidentManagement|Paged"
+msgstr ""
+
msgid "IncidentManagement|Published"
msgstr ""
@@ -18725,6 +19146,9 @@ msgstr ""
msgid "IncidentManagement|Severity"
msgstr ""
+msgid "IncidentManagement|Status"
+msgstr ""
+
msgid "IncidentManagement|There are no closed incidents"
msgstr ""
@@ -18743,6 +19167,9 @@ msgstr ""
msgid "IncidentManagement|Unpublished"
msgstr ""
+msgid "IncidentManagement|Use escalation policies to automatically page your team when incidents are created."
+msgstr ""
+
msgid "IncidentSettings|Activate \"time to SLA\" countdown timer"
msgstr ""
@@ -18788,7 +19215,10 @@ msgstr ""
msgid "Incidents"
msgstr ""
-msgid "Incidents|Add a URL"
+msgid "Incidents|Add image details"
+msgstr ""
+
+msgid "Incidents|Add text or a link to display with your image. If you don't add either, the file name displays instead."
msgstr ""
msgid "Incidents|Drop or %{linkStart}upload%{linkEnd} a metric screenshot to attach it to the incident"
@@ -18803,10 +19233,10 @@ msgstr ""
msgid "Incidents|There was an issue loading metric images."
msgstr ""
-msgid "Incidents|There was an issue uploading your image."
+msgid "Incidents|There was an issue updating your image."
msgstr ""
-msgid "Incidents|You can optionally add a URL to link users to the original graph."
+msgid "Incidents|There was an issue uploading your image."
msgstr ""
msgid "Incident|Alert details"
@@ -18815,9 +19245,18 @@ msgstr ""
msgid "Incident|Are you sure you wish to delete this image?"
msgstr ""
+msgid "Incident|Delete image"
+msgstr ""
+
msgid "Incident|Deleting %{filename}"
msgstr ""
+msgid "Incident|Edit image text or link"
+msgstr ""
+
+msgid "Incident|Editing %{filename}"
+msgstr ""
+
msgid "Incident|Metrics"
msgstr ""
@@ -19086,12 +19525,18 @@ msgstr ""
msgid "Integrations|Branches for which notifications are to be sent"
msgstr ""
+msgid "Integrations|Clear if using a self-signed certificate."
+msgstr ""
+
msgid "Integrations|Comment detail:"
msgstr ""
msgid "Integrations|Comment settings:"
msgstr ""
+msgid "Integrations|Connection details"
+msgstr ""
+
msgid "Integrations|Connection failed. Please check your settings."
msgstr ""
@@ -19116,6 +19561,9 @@ msgstr ""
msgid "Integrations|Enable GitLab.com slash commands in a Slack workspace."
msgstr ""
+msgid "Integrations|Enable SSL verification"
+msgstr ""
+
msgid "Integrations|Enable comments"
msgstr ""
@@ -19194,6 +19642,9 @@ msgstr ""
msgid "Integrations|Return to GitLab for Jira"
msgstr ""
+msgid "Integrations|SSL verification"
+msgstr ""
+
msgid "Integrations|Save settings?"
msgstr ""
@@ -19239,9 +19690,6 @@ msgstr ""
msgid "Integrations|Use default settings"
msgstr ""
-msgid "Integrations|When you mention a Jira issue in a commit or merge request, GitLab creates a remote link and comment (if enabled)."
-msgstr ""
-
msgid "Integrations|You can now close this window and return to the GitLab for Jira application."
msgstr ""
@@ -19266,9 +19714,6 @@ msgstr ""
msgid "Integrations|can't exceed %{recipients_limit}"
msgstr ""
-msgid "Interactive developer security education."
-msgstr ""
-
msgid "Interactive mode"
msgstr ""
@@ -19758,6 +20203,9 @@ msgstr ""
msgid "IssueAnalytics|Assignees"
msgstr ""
+msgid "IssueAnalytics|Created by"
+msgstr ""
+
msgid "IssueAnalytics|Due date"
msgstr ""
@@ -19770,9 +20218,6 @@ msgstr ""
msgid "IssueAnalytics|Milestone"
msgstr ""
-msgid "IssueAnalytics|Opened by"
-msgstr ""
-
msgid "IssueAnalytics|Status"
msgstr ""
@@ -19896,10 +20341,10 @@ msgstr ""
msgid "IssuesAnalytics|Avg/Month:"
msgstr ""
-msgid "IssuesAnalytics|Issues opened"
+msgid "IssuesAnalytics|Issues created"
msgstr ""
-msgid "IssuesAnalytics|Issues opened per month"
+msgid "IssuesAnalytics|Issues created per month"
msgstr ""
msgid "IssuesAnalytics|Last 12 months"
@@ -19926,6 +20371,9 @@ msgstr ""
msgid "It looks like you have some draft commits in this branch."
msgstr ""
+msgid "It looks like you're attempting to activate your subscription. Use %{a_start}the Subscription page%{a_end} instead."
+msgstr ""
+
msgid "It may be several days before you see feature usage data."
msgstr ""
@@ -20154,6 +20602,9 @@ msgstr ""
msgid "JiraConnect|You can now close this window and return to Jira."
msgstr ""
+msgid "JiraConnect|You don't have permission to create branches for this project. Select a different project or contact the project owner for access. %{linkStart}Learn more.%{linkEnd}"
+msgstr ""
+
msgid "JiraRequest|A connection error occurred while connecting to Jira. Try your request again."
msgstr ""
@@ -20202,13 +20653,13 @@ msgstr ""
msgid "JiraService|Define the type of Jira issue to create from a vulnerability."
msgstr ""
-msgid "JiraService|Displaying Jira issues while leaving the GitLab issue functionality enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
+msgid "JiraService|Displaying Jira issues while leaving GitLab issues also enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
msgstr ""
-msgid "JiraService|Enable Jira issues"
+msgid "JiraService|Enable Jira issue creation from vulnerabilities"
msgstr ""
-msgid "JiraService|Enable Jira issues creation from vulnerabilities"
+msgid "JiraService|Enable Jira issues"
msgstr ""
msgid "JiraService|Enable Jira transitions"
@@ -20325,16 +20776,19 @@ msgstr ""
msgid "JiraService|View Jira issues in GitLab"
msgstr ""
-msgid "JiraService|Warning: All GitLab users that have access to this GitLab project are able to view all issues from the Jira project specified below."
+msgid "JiraService|Warning: All GitLab users with access to this GitLab project can view all issues from the Jira project you select."
msgstr ""
msgid "JiraService|Web URL"
msgstr ""
-msgid "JiraService|Work on Jira issues without leaving GitLab. Adds a Jira menu to access your list of Jira issues and view any issue as read-only."
+msgid "JiraService|When a Jira issue is mentioned in a commit or merge request, a remote link and comment (if enabled) will be created."
+msgstr ""
+
+msgid "JiraService|Work on Jira issues without leaving GitLab. Add a Jira menu to access a read-only list of your Jira issues."
msgstr ""
-msgid "JiraService|You need to configure Jira before enabling this integration. For more details, read the %{jira_doc_link_start}Jira integration documentation%{link_end}."
+msgid "JiraService|You must configure Jira before enabling this integration. %{jira_doc_link_start}Learn more.%{link_end}"
msgstr ""
msgid "Job"
@@ -20346,9 +20800,6 @@ msgstr ""
msgid "Job Failed #%{build_id}"
msgstr ""
-msgid "Job ID"
-msgstr ""
-
msgid "Job artifact"
msgstr ""
@@ -20415,9 +20866,27 @@ msgstr ""
msgid "Jobs|You're about to retry a job that failed because it attempted to deploy code that is older than the latest deployment. Retrying this job could result in overwriting the environment with the older source code."
msgstr ""
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source} into %{target}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{ref}"
+msgstr ""
+
+msgid "Job|Are you sure you want to erase this job log and artifacts?"
+msgstr ""
+
msgid "Job|Browse"
msgstr ""
+msgid "Job|Cancel"
+msgstr ""
+
msgid "Job|Complete Raw"
msgstr ""
@@ -20427,6 +20896,9 @@ msgstr ""
msgid "Job|Erase job log and artifacts"
msgstr ""
+msgid "Job|Finished at"
+msgstr ""
+
msgid "Job|Job artifacts"
msgstr ""
@@ -20439,7 +20911,7 @@ msgstr ""
msgid "Job|Keep"
msgstr ""
-msgid "Job|Pipeline"
+msgid "Job|Retry"
msgstr ""
msgid "Job|Scroll to bottom"
@@ -20451,6 +20923,9 @@ msgstr ""
msgid "Job|Show complete raw"
msgstr ""
+msgid "Job|Status"
+msgstr ""
+
msgid "Job|The artifacts were removed"
msgstr ""
@@ -20478,21 +20953,12 @@ msgstr ""
msgid "Job|delayed"
msgstr ""
-msgid "Job|for"
-msgstr ""
-
-msgid "Job|into"
-msgstr ""
-
msgid "Job|manual"
msgstr ""
msgid "Job|triggered"
msgstr ""
-msgid "Job|with"
-msgstr ""
-
msgid "Join Zoom meeting"
msgstr ""
@@ -20595,9 +21061,6 @@ msgstr ""
msgid "Ki"
msgstr ""
-msgid "Kontra"
-msgstr ""
-
msgid "Kroki"
msgstr ""
@@ -20920,6 +21383,9 @@ msgstr ""
msgid "Learn more about Auto DevOps"
msgstr ""
+msgid "Learn more about GitLab"
+msgstr ""
+
msgid "Learn more about Needs relationships"
msgstr ""
@@ -21241,9 +21707,18 @@ msgstr ""
msgid "Licenses|Displays licenses detected in the project, based on the %{linkStart}latest successful%{linkEnd} scan"
msgstr ""
+msgid "Licenses|Drag your license file here or %{linkStart}click to upload%{linkEnd}."
+msgstr ""
+
+msgid "Licenses|Drop your license file to start the upload."
+msgstr ""
+
msgid "Licenses|Error fetching the license list. Please check your network connection and try again."
msgstr ""
+msgid "Licenses|Error: You are trying to upload something other than a file"
+msgstr ""
+
msgid "Licenses|License Compliance"
msgstr ""
@@ -21262,6 +21737,9 @@ msgstr ""
msgid "Licenses|Specified policies in this project"
msgstr ""
+msgid "Licenses|The file could not be uploaded."
+msgstr ""
+
msgid "Licenses|The license list details information about the licenses used within your project."
msgstr ""
@@ -21295,10 +21773,6 @@ msgstr ""
msgid "Limit the size of Sidekiq jobs stored in Redis."
msgstr ""
-msgid "Limited to showing %d event at most"
-msgid_plural "Limited to showing %d events at most"
-msgstr[0] ""
-
msgid "Limiting mode"
msgstr ""
@@ -21308,6 +21782,9 @@ msgstr ""
msgid "Link"
msgstr ""
+msgid "Link (optional)"
+msgstr ""
+
msgid "Link Prometheus monitoring to GitLab."
msgstr ""
@@ -21344,6 +21821,9 @@ msgstr ""
msgid "Linked emails (%{email_count})"
msgstr ""
+msgid "Linked epics"
+msgstr ""
+
msgid "Linked issues"
msgstr ""
@@ -21371,6 +21851,15 @@ msgstr ""
msgid "List of all merge commits"
msgstr ""
+msgid "List of environments for this project"
+msgstr ""
+
+msgid "List of suitable GCP locations"
+msgstr ""
+
+msgid "List of users allowed to exceed the rate limit."
+msgstr ""
+
msgid "List options"
msgstr ""
@@ -21590,6 +22079,9 @@ msgstr ""
msgid "Maintenance mode"
msgstr ""
+msgid "Make adjustments to how your GitLab instance is set up."
+msgstr ""
+
msgid "Make and review changes in the browser with the Web IDE"
msgstr ""
@@ -21734,6 +22226,12 @@ msgstr ""
msgid "MarkdownEditor|Add italic text (%{modifier_key}I)"
msgstr ""
+msgid "MarkdownEditor|Add strikethrough text (%{modifierKey}⇧X)"
+msgstr ""
+
+msgid "MarkdownEditor|Add strikethrough text (%{modifier_key}⇧X)"
+msgstr ""
+
msgid "Marked For Deletion At - %{deletion_time}"
msgstr ""
@@ -21995,6 +22493,9 @@ msgstr ""
msgid "Maximum push size (MB)"
msgstr ""
+msgid "Maximum requests per 10 minutes per user"
+msgstr ""
+
msgid "Maximum requests per minute"
msgstr ""
@@ -22085,6 +22586,17 @@ msgstr ""
msgid "Members of a group may only view projects they have permission to access"
msgstr ""
+msgid "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seat in use and will be billed for the overage."
+msgid_plural "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seats in use and will be billed for the overage."
+msgstr[0] ""
+
+msgid "MembersOverage|You are about to incur additional charges"
+msgstr ""
+
+msgid "MembersOverage|Your subscription includes %d seat."
+msgid_plural "MembersOverage|Your subscription includes %d seats."
+msgstr[0] ""
+
msgid "Membership"
msgstr ""
@@ -22289,9 +22801,6 @@ msgstr ""
msgid "Merge request not merged"
msgstr ""
-msgid "Merge request pipelines 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 merge request pipelines."
-msgstr ""
-
msgid "Merge request reports"
msgstr ""
@@ -22388,13 +22897,13 @@ msgstr ""
msgid "MergeRequests|Create issue to resolve thread"
msgstr ""
-msgid "MergeRequests|Failed to squash. Should be done manually."
+msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Saving the comment failed"
+msgid "MergeRequests|Squashing failed: Squash the commits locally, resolve any conflicts, then push the branch."
msgstr ""
-msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
+msgid "MergeRequests|Squashing not allowed: This project doesn't allow you to squash commits when merging."
msgstr ""
msgid "MergeRequests|Thread stays resolved"
@@ -23233,6 +23742,18 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "MrList|Assigned to %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from assignee %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from reviewer %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Review requested from %{name}, go to their profile."
+msgstr ""
+
msgid "Multi-project"
msgstr ""
@@ -23266,7 +23787,7 @@ msgstr ""
msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "My Awesome Group"
+msgid "My awesome group"
msgstr ""
msgid "My company or team"
@@ -23886,9 +24407,6 @@ msgstr ""
msgid "No available branches"
msgstr ""
-msgid "No available groups to fork the project."
-msgstr ""
-
msgid "No branches found"
msgstr ""
@@ -24099,6 +24617,9 @@ msgstr ""
msgid "No ref selected"
msgstr ""
+msgid "No regions configured"
+msgstr ""
+
msgid "No related merge requests found."
msgstr ""
@@ -24897,6 +25418,9 @@ msgstr ""
msgid "Only reCAPTCHA v2 is supported:"
msgstr ""
+msgid "Only required if not using role instance credentials."
+msgstr ""
+
msgid "Only use lowercase letters, numbers, and underscores."
msgstr ""
@@ -24921,9 +25445,6 @@ msgstr ""
msgid "Open a CLI and connect to the cluster you want to install the agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
-msgid "Open epics"
-msgstr ""
-
msgid "Open errors"
msgstr ""
@@ -24963,7 +25484,7 @@ msgstr ""
msgid "Opened issues"
msgstr ""
-msgid "OpenedNDaysAgo|Opened"
+msgid "OpenedNDaysAgo|Created"
msgstr ""
msgid "Opens in a new window"
@@ -25008,9 +25529,6 @@ msgstr ""
msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
-msgid "Optional."
-msgstr ""
-
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
msgstr ""
@@ -25798,6 +26316,9 @@ msgstr ""
msgid "PerformanceBar|Memory"
msgstr ""
+msgid "PerformanceBar|Memory report"
+msgstr ""
+
msgid "PerformanceBar|Redis calls"
msgstr ""
@@ -25831,18 +26352,12 @@ msgstr ""
msgid "PerformanceBar|wall"
msgstr ""
-msgid "Performs a rebase but skips triggering a new pipeline"
-msgstr ""
-
msgid "Period in seconds"
msgstr ""
msgid "Permalink"
msgstr ""
-msgid "Permanently delete project"
-msgstr ""
-
msgid "Permanently remove group"
msgstr ""
@@ -26113,6 +26628,51 @@ msgstr ""
msgid "PipelineStatusTooltip|Pipeline: %{ci_status}"
msgstr ""
+msgid "PipelineWizardDefaultCommitMessage|Add %{filename}"
+msgstr ""
+
+msgid "PipelineWizardDefaultCommitMessage|Update %{filename}"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|At least one entry is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This field is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This value is not valid"
+msgstr ""
+
+msgid "PipelineWizardListWidget|add another step"
+msgstr ""
+
+msgid "PipelineWizardListWidget|remove step"
+msgstr ""
+
+msgid "PipelineWizard|Commit"
+msgstr ""
+
+msgid "PipelineWizard|Commit Message"
+msgstr ""
+
+msgid "PipelineWizard|Commit changes to your file"
+msgstr ""
+
+msgid "PipelineWizard|Commit file to Branch"
+msgstr ""
+
+msgid "PipelineWizard|Commit your new file"
+msgstr ""
+
+msgid "PipelineWizard|The file has been committed."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem committing the changes."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem while checking whether your file already exists in the specified branch."
+msgstr ""
+
msgid "Pipelines"
msgstr ""
@@ -26227,7 +26787,7 @@ msgstr ""
msgid "Pipelines|Project cache successfully reset."
msgstr ""
-msgid "Pipelines|Revoke"
+msgid "Pipelines|Revoke trigger"
msgstr ""
msgid "Pipelines|Something went wrong while cleaning runners cache."
@@ -26272,6 +26832,12 @@ msgstr ""
msgid "Pipelines|This is a child pipeline within the parent pipeline"
msgstr ""
+msgid "Pipelines|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipelines|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipelines|This pipeline will run code originating from a forked project merge request. This means that the code can potentially have security considerations like exposing CI variables."
msgstr ""
@@ -26314,9 +26880,6 @@ msgstr ""
msgid "Pipelines|Your changes have been successfully committed. Now redirecting to the new merge request page."
msgstr ""
-msgid "Pipelines|detached"
-msgstr ""
-
msgid "Pipelines|error"
msgstr ""
@@ -26326,10 +26889,13 @@ msgstr ""
msgid "Pipelines|latest"
msgstr ""
-msgid "Pipelines|stuck"
+msgid "Pipelines|merge request"
msgstr ""
-msgid "Pipelines|train"
+msgid "Pipelines|merge train"
+msgstr ""
+
+msgid "Pipelines|stuck"
msgstr ""
msgid "Pipelines|yaml invalid"
@@ -26461,6 +27027,12 @@ msgstr ""
msgid "Pipeline|This change will not change the overall test coverage if merged."
msgstr ""
+msgid "Pipeline|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipeline|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipeline|Trigger author"
msgstr ""
@@ -26485,6 +27057,12 @@ msgstr ""
msgid "Pipeline|for"
msgstr ""
+msgid "Pipeline|merge request"
+msgstr ""
+
+msgid "Pipeline|merge train"
+msgstr ""
+
msgid "Pipeline|on"
msgstr ""
@@ -26623,9 +27201,6 @@ msgstr ""
msgid "Please enter a valid time interval"
msgstr ""
-msgid "Please enter or upload a valid license."
-msgstr ""
-
msgid "Please enter your current password."
msgstr ""
@@ -26734,9 +27309,6 @@ msgstr ""
msgid "Please type %{phrase_code} to proceed or close this modal to cancel."
msgstr ""
-msgid "Please type the following to confirm:"
-msgstr ""
-
msgid "Please use this form to report to the admin users who create spam issues, comments or behave inappropriately."
msgstr ""
@@ -26764,12 +27336,27 @@ msgstr ""
msgid "Policies"
msgstr ""
+msgid "Policy '%{escalation_policy_name}' does not exist."
+msgstr ""
+
msgid "Policy management project does have any policies in %{policy_path}"
msgstr ""
msgid "Policy project doesn't exist"
msgstr ""
+msgid "PolicyRuleMultiSelect|%{firstLabel} +%{numberOfAdditionalLabels} more"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|All %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select all"
+msgstr ""
+
msgid "Polling interval multiplier"
msgstr ""
@@ -26998,6 +27585,9 @@ msgstr ""
msgid "Private projects can be created in your personal namespace with:"
msgstr ""
+msgid "Problem with %{name} command: %{message}."
+msgstr ""
+
msgid "Proceed"
msgstr ""
@@ -27472,6 +28062,9 @@ msgstr ""
msgid "Progress"
msgstr ""
+msgid "Progress tracking"
+msgstr ""
+
msgid "Project"
msgstr ""
@@ -27703,6 +28296,9 @@ msgstr ""
msgid "ProjectQualitySummary|Failure"
msgstr ""
+msgid "ProjectQualitySummary|Get insight into the overall percentage of tests in your project that succeed, fail and are skipped."
+msgstr ""
+
msgid "ProjectQualitySummary|Latest pipeline results"
msgstr ""
@@ -27721,6 +28317,12 @@ msgstr ""
msgid "ProjectQualitySummary|See project Code Coverage Statistics"
msgstr ""
+msgid "ProjectQualitySummary|Set up test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|Set up test runs (opens in a new tab)"
+msgstr ""
+
msgid "ProjectQualitySummary|Skipped"
msgstr ""
@@ -27997,13 +28599,19 @@ msgstr ""
msgid "ProjectSettings|LFS objects from this repository are available to forks. %{linkStart}How do I remove them?%{linkEnd}"
msgstr ""
+msgid "ProjectSettings|Learn about commit history."
+msgstr ""
+
+msgid "ProjectSettings|Leave empty to use default template."
+msgstr ""
+
msgid "ProjectSettings|Manage who can see the project in the public access directory."
msgstr ""
msgid "ProjectSettings|Manages large files such as audio, video, and graphics files."
msgstr ""
-msgid "ProjectSettings|Maximum 500 characters."
+msgid "ProjectSettings|Maximum %{maxLength} characters."
msgstr ""
msgid "ProjectSettings|Merge checks"
@@ -28144,6 +28752,9 @@ msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
msgstr ""
+msgid "ProjectSettings|The default template will be applied on save."
+msgstr ""
+
msgid "ProjectSettings|These checks must pass before merge requests can be merged."
msgstr ""
@@ -28198,6 +28809,9 @@ msgstr ""
msgid "ProjectSettings|What are badges?"
msgstr ""
+msgid "ProjectSettings|What are merge trains?"
+msgstr ""
+
msgid "ProjectSettings|When merge request pipelines are enabled in the CI/CD configuration file, pipelines validate the combined results of the source and target branches. %{link_start}How to configure merge request pipelines?%{link_end}"
msgstr ""
@@ -28315,6 +28929,9 @@ msgstr ""
msgid "Projects are organized into groups"
msgstr ""
+msgid "Projects are where you store your code, access issues, wiki and other features of GitLab."
+msgstr ""
+
msgid "Projects contributed to"
msgstr ""
@@ -28330,12 +28947,6 @@ msgstr ""
msgid "Projects to index"
msgstr ""
-msgid "Projects will be permanently deleted after a %{waiting_period}-day waiting period."
-msgstr ""
-
-msgid "Projects will be permanently deleted immediately."
-msgstr ""
-
msgid "Projects with critical vulnerabilities"
msgstr ""
@@ -28420,6 +29031,9 @@ msgstr ""
msgid "ProjectsNew|Import project"
msgstr ""
+msgid "ProjectsNew|Include a Getting Started README"
+msgstr ""
+
msgid "ProjectsNew|Initialize repository with a README"
msgstr ""
@@ -28435,6 +29049,9 @@ msgstr ""
msgid "ProjectsNew|Project description %{tag_start}(optional)%{tag_end}"
msgstr ""
+msgid "ProjectsNew|Recommended if you're new to GitLab"
+msgstr ""
+
msgid "ProjectsNew|Run CI/CD for external repository"
msgstr ""
@@ -28852,6 +29469,9 @@ msgstr ""
msgid "ProtectedBranch|Unprotect"
msgstr ""
+msgid "ProtectedBranch|Unprotect branch"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
@@ -28879,6 +29499,9 @@ msgstr ""
msgid "ProtectedEnvironment|Protected Environment (%{protected_environments_count})"
msgstr ""
+msgid "ProtectedEnvironment|Required approvals"
+msgstr ""
+
msgid "ProtectedEnvironment|Select an environment"
msgstr ""
@@ -28900,10 +29523,13 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|Unprotect tag"
+msgstr ""
+
msgid "ProtectedTags|default"
msgstr ""
-msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
+msgid "ProtectedTag|By default, protected tags restrict who can modify the tag."
msgstr ""
msgid "ProtectedTag|Learn more."
@@ -28966,6 +29592,9 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Public projects are an easy way to allow everyone to have read-only access."
+msgstr ""
+
msgid "Publish to status page"
msgstr ""
@@ -29122,9 +29751,6 @@ msgstr ""
msgid "QualitySummary|Project quality"
msgstr ""
-msgid "Quarters"
-msgstr ""
-
msgid "Query"
msgstr ""
@@ -29209,6 +29835,9 @@ msgstr ""
msgid "Read more about project permissions %{help_link_open}here%{help_link_close}"
msgstr ""
+msgid "Read more about related epics"
+msgstr ""
+
msgid "Read more about related issues"
msgstr ""
@@ -29239,10 +29868,7 @@ msgstr ""
msgid "Rebase source branch on the target branch."
msgstr ""
-msgid "Rebase without CI"
-msgstr ""
-
-msgid "Rebases and triggers a pipeline"
+msgid "Rebase without pipeline"
msgstr ""
msgid "Recaptcha verified?"
@@ -29293,9 +29919,6 @@ msgstr ""
msgid "Reconfigure"
msgstr ""
-msgid "Recovering projects"
-msgstr ""
-
msgid "Recovery Codes"
msgstr ""
@@ -29354,6 +29977,12 @@ msgstr ""
msgid "Regex pattern"
msgstr ""
+msgid "Region"
+msgstr ""
+
+msgid "Regions"
+msgstr ""
+
msgid "Register"
msgstr ""
@@ -29583,9 +30212,6 @@ msgstr ""
msgid "Remove all or specific reviewer(s)"
msgstr ""
-msgid "Remove approver"
-msgstr ""
-
msgid "Remove approvers"
msgstr ""
@@ -29601,6 +30227,9 @@ msgstr ""
msgid "Remove attention request"
msgstr ""
+msgid "Remove attention request(s)"
+msgstr ""
+
msgid "Remove avatar"
msgstr ""
@@ -29739,6 +30368,9 @@ msgstr ""
msgid "Removed an issue from an epic."
msgstr ""
+msgid "Removed attention from %{users_sentence}."
+msgstr ""
+
msgid "Removed attention request from @%{username}"
msgstr ""
@@ -29790,6 +30422,9 @@ msgstr ""
msgid "Removes an issue from an epic."
msgstr ""
+msgid "Removes attention from %{users_sentence}."
+msgstr ""
+
msgid "Removes parent epic %{epic_ref}."
msgstr ""
@@ -29901,6 +30536,9 @@ msgstr ""
msgid "Report abuse to admin"
msgstr ""
+msgid "Report is generating and will be sent to your email address."
+msgstr ""
+
msgid "Reported %{timeAgo} by %{reportedBy}"
msgstr ""
@@ -30185,6 +30823,15 @@ msgstr ""
msgid "Request attention"
msgstr ""
+msgid "Request attention from %{users_sentence}."
+msgstr ""
+
+msgid "Request attention from assignee or reviewer"
+msgstr ""
+
+msgid "Request attention from assignee(s) or reviewer(s)"
+msgstr ""
+
msgid "Request attention to review"
msgstr ""
@@ -30209,6 +30856,9 @@ msgstr ""
msgid "Requested %{time_ago}"
msgstr ""
+msgid "Requested attention from %{users_sentence}."
+msgstr ""
+
msgid "Requested attention from @%{username}"
msgstr ""
@@ -30421,6 +31071,9 @@ msgstr ""
msgid "Restore project"
msgstr ""
+msgid "Restoring projects"
+msgstr ""
+
msgid "Restoring the group will prevent the group, its subgroups and projects from being removed on this date."
msgstr ""
@@ -30451,6 +31104,9 @@ msgstr ""
msgid "Retry"
msgstr ""
+msgid "Retry failed jobs"
+msgstr ""
+
msgid "Retry job"
msgstr ""
@@ -30497,9 +31153,6 @@ msgstr ""
msgid "Review changes"
msgstr ""
-msgid "Review requested from %{name}"
-msgstr ""
-
msgid "Review requests for you"
msgstr ""
@@ -30663,6 +31316,9 @@ msgstr ""
msgid "Runners|Assigned Group"
msgstr ""
+msgid "Runners|Assigned Projects (%{projectCount})"
+msgstr ""
+
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30732,6 +31388,9 @@ msgstr ""
msgid "Runners|Instance"
msgstr ""
+msgid "Runners|Jobs"
+msgstr ""
+
msgid "Runners|Last contact"
msgstr ""
@@ -30825,9 +31484,6 @@ msgstr ""
msgid "Runners|Runner %{name} was deleted"
msgstr ""
-msgid "Runners|Runner ID"
-msgstr ""
-
msgid "Runners|Runner assigned to project."
msgstr ""
@@ -30975,6 +31631,9 @@ msgstr ""
msgid "Runners|stale"
msgstr ""
+msgid "Runner|This runner has not run any jobs."
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -31089,6 +31748,24 @@ msgstr ""
msgid "Saving project."
msgstr ""
+msgid "ScanResultPolicy|%{ifLabelStart}if%{ifLabelEnd} %{scanners} scan in an open merge request targeting the %{branches} branch(es) finds %{vulnerabilitiesAllowed} or more %{severities} vulnerabilities that are %{vulnerabilityStates}"
+msgstr ""
+
+msgid "ScanResultPolicy|%{thenLabelStart}Then%{thenLabelEnd} Require approval from %{approvalsRequired} of the following approvers: %{approvers}"
+msgstr ""
+
+msgid "ScanResultPolicy|add an approver"
+msgstr ""
+
+msgid "ScanResultPolicy|scanners"
+msgstr ""
+
+msgid "ScanResultPolicy|severity levels"
+msgstr ""
+
+msgid "ScanResultPolicy|vulnerability states"
+msgstr ""
+
msgid "Scanner"
msgstr ""
@@ -31221,6 +31898,9 @@ msgstr ""
msgid "Search for a user"
msgstr ""
+msgid "Search for an emoji"
+msgstr ""
+
msgid "Search for projects, issues, etc."
msgstr ""
@@ -31397,18 +32077,12 @@ msgstr ""
msgid "Secret Detection"
msgstr ""
-msgid "Secret access key"
-msgstr ""
-
msgid "Secret token"
msgstr ""
msgid "Secure token that identifies an external storage request."
msgstr ""
-msgid "SecureCodeWarrior"
-msgstr ""
-
msgid "Security"
msgstr ""
@@ -31433,9 +32107,6 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "Security training with guide and learning pathways."
-msgstr ""
-
msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
@@ -31538,7 +32209,7 @@ msgstr ""
msgid "SecurityConfiguration|Manage corpus"
msgstr ""
-msgid "SecurityConfiguration|Manage corpus files used as mutation sources in coverage fuzzing."
+msgid "SecurityConfiguration|Manage corpus files used as seed inputs with coverage-guided fuzzing."
msgstr ""
msgid "SecurityConfiguration|Manage profiles for use by DAST scans."
@@ -31604,15 +32275,15 @@ msgstr ""
msgid "SecurityOrchestration|.yaml preview"
msgstr ""
-msgid "SecurityOrchestration|Action"
-msgstr ""
-
msgid "SecurityOrchestration|Actions"
msgstr ""
msgid "SecurityOrchestration|Add rule"
msgstr ""
+msgid "SecurityOrchestration|After dismissing the alert, the information will never be shown again."
+msgstr ""
+
msgid "SecurityOrchestration|All policies"
msgstr ""
@@ -31628,7 +32299,7 @@ msgstr ""
msgid "SecurityOrchestration|Description"
msgstr ""
-msgid "SecurityOrchestration|Disabled"
+msgid "SecurityOrchestration|Don't show the alert anymore"
msgstr ""
msgid "SecurityOrchestration|Edit policy"
@@ -31637,13 +32308,13 @@ msgstr ""
msgid "SecurityOrchestration|Edit policy project"
msgstr ""
-msgid "SecurityOrchestration|Enabled"
+msgid "SecurityOrchestration|Empty policy name"
msgstr ""
-msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Enabled"
msgstr ""
-msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
msgstr ""
msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
@@ -31652,7 +32323,7 @@ msgstr ""
msgid "SecurityOrchestration|Invalid policy type"
msgstr ""
-msgid "SecurityOrchestration|Latest scan"
+msgid "SecurityOrchestration|Latest scan run against %{agent}"
msgstr ""
msgid "SecurityOrchestration|Network"
@@ -31661,15 +32332,27 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No actions defined - policy will not run."
+msgstr ""
+
+msgid "SecurityOrchestration|No description"
+msgstr ""
+
msgid "SecurityOrchestration|No rules defined - policy will not run."
msgstr ""
+msgid "SecurityOrchestration|Not enabled"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
msgid "SecurityOrchestration|Policies"
msgstr ""
+msgid "SecurityOrchestration|Policy Type"
+msgstr ""
+
msgid "SecurityOrchestration|Policy cannot be enabled for non-existing branches (%{branches})"
msgstr ""
@@ -31694,10 +32377,13 @@ msgstr ""
msgid "SecurityOrchestration|Require %{approvals} %{plural} from %{approvers} if any of the following occur:"
msgstr ""
-msgid "SecurityOrchestration|Rule"
+msgid "SecurityOrchestration|Rules"
msgstr ""
-msgid "SecurityOrchestration|Rules"
+msgid "SecurityOrchestration|Runs %{actions} and %{lastAction} scans"
+msgstr ""
+
+msgid "SecurityOrchestration|Runs a %{action} scan"
msgstr ""
msgid "SecurityOrchestration|Scan Execution"
@@ -31757,6 +32443,9 @@ msgstr ""
msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
+msgid "SecurityOrchestration|This view only shows scan results for the agent %{agent}. You can view scan results for all agents in the %{linkStart}Operational Vulnerabilities tab of the vulnerability report%{linkEnd}."
+msgstr ""
+
msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
@@ -31811,9 +32500,6 @@ msgstr ""
msgid "SecurityOrchestration|users with ids"
msgstr ""
-msgid "SecurityOrchestration|view results"
-msgstr ""
-
msgid "SecurityOrchestration|vulnerabilities"
msgstr ""
@@ -32483,22 +33169,19 @@ 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|In order to start using functions as a service, you must first install Knative on your Kubernetes cluster. %{linkStart}More information%{linkEnd}"
-msgstr ""
-
msgid "Serverless|Learn more about Serverless"
msgstr ""
msgid "Serverless|No functions available"
msgstr ""
-msgid "Serverless|Sign up for First Look"
+msgid "Serverless|Serverless was %{linkStart}deprecated%{linkEnd} in GitLab 14.3."
+msgstr ""
+
+msgid "Serverless|Serverless was %{postLinkStart}deprecated%{postLinkEnd}. But if you opt to use it, you must install Knative in your Kubernetes cluster first. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "Serverless|The deploy job has not finished."
@@ -32510,9 +33193,6 @@ 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 ""
@@ -32528,9 +33208,6 @@ msgstr ""
msgid "Service Account Key"
msgstr ""
-msgid "Service Accounts"
-msgstr ""
-
msgid "Service Accounts keys authorize GitLab to deploy your Google Cloud project"
msgstr ""
@@ -32540,10 +33217,10 @@ msgstr ""
msgid "Service Desk allows people to create issues in your GitLab instance without their own user account. It provides a unique email address for end users to create issues in a project. Replies can be sent either through the GitLab interface or by email. End users only see threads through email."
msgstr ""
-msgid "Service Usage Data"
+msgid "Service account generated successfully"
msgstr ""
-msgid "Service account generated successfully"
+msgid "Service accounts"
msgstr ""
msgid "Service ping is disabled in your configuration file, and cannot be enabled through this form."
@@ -32687,6 +33364,9 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
+msgid "Set the per-user rate limit for getting a user by ID via the API."
+msgstr ""
+
msgid "Set the per-user rate limit for notes created by web or API requests."
msgstr ""
@@ -32865,6 +33545,9 @@ msgstr ""
msgid "Shared runners details"
msgstr ""
+msgid "Shared runners enabled cannot be enabled until a valid credit card is on file"
+msgstr ""
+
msgid "Shared runners help link"
msgstr ""
@@ -32922,6 +33605,9 @@ msgstr ""
msgid "Show all issues."
msgstr ""
+msgid "Show all milestones"
+msgstr ""
+
msgid "Show all test cases."
msgstr ""
@@ -32958,6 +33644,9 @@ msgstr ""
msgid "Show file contents"
msgstr ""
+msgid "Show group milestones"
+msgstr ""
+
msgid "Show labels"
msgstr ""
@@ -32973,6 +33662,12 @@ msgstr ""
msgid "Show open epics"
msgstr ""
+msgid "Show project milestones"
+msgstr ""
+
+msgid "Show sub-group milestones"
+msgstr ""
+
msgid "Show the Closed list"
msgstr ""
@@ -32982,10 +33677,6 @@ msgstr ""
msgid "Show whitespace changes"
msgstr ""
-msgid "Showing %d event"
-msgid_plural "Showing %d events"
-msgstr[0] ""
-
msgid "Showing %{conflict} between %{sourceBranch} and %{targetBranch}"
msgstr ""
@@ -33044,12 +33735,6 @@ msgstr ""
msgid "Sidebar|None"
msgstr ""
-msgid "Sidebar|Only numeral characters allowed"
-msgstr ""
-
-msgid "Sidebar|Weight"
-msgstr ""
-
msgid "Sidekiq job compression threshold (bytes)"
msgstr ""
@@ -33212,6 +33897,9 @@ msgstr ""
msgid "Slack logo"
msgstr ""
+msgid "SlackIntegration|Are you sure you want to remove this project from the Slack application?"
+msgstr ""
+
msgid "SlackIntegration|GitLab for Slack"
msgstr ""
@@ -33221,6 +33909,9 @@ msgstr ""
msgid "SlackIntegration|Project alias"
msgstr ""
+msgid "SlackIntegration|Remove project"
+msgstr ""
+
msgid "SlackIntegration|Select a GitLab project to link with your Slack workspace."
msgstr ""
@@ -33365,9 +34056,6 @@ msgstr ""
msgid "Something went wrong trying to load issue contacts."
msgstr ""
-msgid "Something went wrong when creating a work item. Please try again"
-msgstr ""
-
msgid "Something went wrong when reordering designs. Please try again"
msgstr ""
@@ -33461,9 +34149,6 @@ msgstr ""
msgid "Something went wrong while inserting your image. Please try again."
msgstr ""
-msgid "Something went wrong while merging this merge request. Please try again."
-msgstr ""
-
msgid "Something went wrong while obtaining the Let's Encrypt certificate."
msgstr ""
@@ -33785,10 +34470,10 @@ 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."
+msgid "SourcegraphAdmin|Learn more."
msgstr ""
-msgid "SourcegraphAdmin|More information"
+msgid "SourcegraphAdmin|Only public projects have code intelligence enabled and communicate with Sourcegraph."
msgstr ""
msgid "SourcegraphAdmin|Save changes"
@@ -33797,7 +34482,7 @@ msgstr ""
msgid "SourcegraphAdmin|Sourcegraph URL"
msgstr ""
-msgid "SourcegraphAdmin|e.g. https://sourcegraph.example.com"
+msgid "SourcegraphAdmin|https://sourcegraph.example.com"
msgstr ""
msgid "SourcegraphPreferences|This feature is experimental and currently limited to certain projects."
@@ -33932,6 +34617,9 @@ msgstr ""
msgid "Start date"
msgstr ""
+msgid "Start free trial"
+msgstr ""
+
msgid "Start merge train"
msgstr ""
@@ -33962,6 +34650,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started escalation for this incident."
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -33974,6 +34665,9 @@ msgstr ""
msgid "Starts at (UTC)"
msgstr ""
+msgid "Starts escalations for this incident"
+msgstr ""
+
msgid "Starts on"
msgstr ""
@@ -34235,6 +34929,9 @@ msgstr ""
msgid "Strikethrough"
msgstr ""
+msgid "Strikethrough text"
+msgstr ""
+
msgid "Subgroup information"
msgstr ""
@@ -34469,6 +35166,21 @@ msgstr ""
msgid "Subscriptions"
msgstr ""
+msgid "Subscriptions|Chat with sales"
+msgstr ""
+
+msgid "Subscriptions|Close"
+msgstr ""
+
+msgid "Subscriptions|Not ready to buy yet?"
+msgstr ""
+
+msgid "Subscriptions|Start a free trial"
+msgstr ""
+
+msgid "Subscriptions|We understand. Maybe you have some questions for our sales team, or maybe you'd like to try some of the paid features first. What would you like to do?"
+msgstr ""
+
msgid "Subscription|Your subscription for %{strong}%{namespace_name}%{strong_close} has expired and you are now on %{pricing_link_start}the GitLab Free tier%{pricing_link_end}. Don't worry, your data is safe. Get in touch with our support team (%{support_email}). They'll gladly help with your subscription renewal."
msgstr ""
@@ -34679,6 +35391,9 @@ msgstr ""
msgid "SuperSonics|Maximum users"
msgstr ""
+msgid "SuperSonics|Offline cloud"
+msgstr ""
+
msgid "SuperSonics|Paste your activation code"
msgstr ""
@@ -34745,6 +35460,12 @@ msgstr ""
msgid "SuperSonics|You do not have an active subscription"
msgstr ""
+msgid "SuperSonics|You have a future dated license"
+msgstr ""
+
+msgid "SuperSonics|You have added a license that activates on %{date}. Please see the subscription history table below for more details."
+msgstr ""
+
msgid "SuperSonics|You have successfully added a license that activates on %{date}. Please see the subscription history table below for more details."
msgstr ""
@@ -34904,6 +35625,9 @@ msgstr ""
msgid "Tag name is required"
msgstr ""
+msgid "Tag push"
+msgstr ""
+
msgid "Tag push events"
msgstr ""
@@ -35006,6 +35730,9 @@ msgstr ""
msgid "TagsPage|protected"
msgstr ""
+msgid "Take a look at the documentation to discover all of GitLab’s capabilities."
+msgstr ""
+
msgid "Target Branch"
msgstr ""
@@ -35402,6 +36129,9 @@ msgstr ""
msgid "Tests"
msgstr ""
+msgid "Text (optional)"
+msgstr ""
+
msgid "Text added to the body of all email messages. %{character_limit} character limit"
msgstr ""
@@ -35451,6 +36181,9 @@ msgstr ""
msgid "The CSV export will be created in the background. Once finished, it will be sent to %{email} in an attachment."
msgstr ""
+msgid "The CSV export you requested of all user memberships is attached to this email."
+msgstr ""
+
msgid "The GitLab subscription service (customers.gitlab.com) is currently experiencing an outage. You can monitor the status and get updates at %{linkStart}status.gitlab.com%{linkEnd}."
msgstr ""
@@ -35526,6 +36259,9 @@ 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 epic"
+msgstr ""
+
msgid "The current issue"
msgstr ""
@@ -35686,6 +36422,9 @@ msgstr ""
msgid "The latest pipeline for this merge request has failed."
msgstr ""
+msgid "The license key is invalid."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -35701,6 +36440,9 @@ msgstr ""
msgid "The license was successfully uploaded and will be active from %{starts_at}. You can see the details below."
msgstr ""
+msgid "The license you uploaded is invalid. If the issue persists, contact support at %{link}."
+msgstr ""
+
msgid "The list creation wizard is already open"
msgstr ""
@@ -36322,10 +37064,13 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} and everything this project contains. %{strongOpen}There is no going back%{strongClose}"
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}on %{date}%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains."
+msgstr ""
+
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains. %{strongOpen}There is no going back.%{strongClose}"
msgstr ""
msgid "This action will %{strongOpen}permanently remove%{strongClose} %{codeOpen}%{group}%{codeClose} %{strongOpen}immediately%{strongClose}."
@@ -36454,9 +37199,6 @@ msgstr ""
msgid "This file was modified for readability, and can't accept suggestions. Edit it directly."
msgstr ""
-msgid "This forked project has the following:"
-msgstr ""
-
msgid "This form is disabled in preview"
msgstr ""
@@ -36469,7 +37211,7 @@ msgstr ""
msgid "This group can't be removed because it is linked to a subscription. To remove this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
-msgid "This group can't be transfered because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
+msgid "This group can't be transferred because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
msgid "This group cannot be invited to a project inside a group with enforced SSO"
@@ -36496,6 +37238,9 @@ 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 incident is already escalated with '%{escalation_policy_name}'."
+msgstr ""
+
msgid "This invitation was sent to %{mail_to_invite_email}, but you are signed in as %{link_to_current_user} with email %{mail_to_current_user}."
msgstr ""
@@ -36514,9 +37259,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 merge train pipeline"
-msgstr ""
-
msgid "This is a private email address %{helpIcon} generated just for you. Anyone who has it can create issues or merge requests as if they were you. If that happens, %{resetLinkStart}reset this token%{resetLinkEnd}."
msgstr ""
@@ -36538,6 +37280,12 @@ msgstr ""
msgid "This is your current session"
msgstr ""
+msgid "This issue cannot be assigned to a confidential epic because it is public."
+msgstr ""
+
+msgid "This issue cannot be made public because it belongs to a confidential epic."
+msgstr ""
+
msgid "This issue is confidential and should only be visible to team members with at least Reporter access."
msgstr ""
@@ -36655,6 +37403,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 branch is protected from force push."
+msgstr ""
+
msgid "This merge request cannot be rebased while there are conflicts."
msgstr ""
@@ -36706,9 +37457,15 @@ msgstr ""
msgid "This pipeline was triggered by a schedule."
msgstr ""
+msgid "This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project"
msgstr ""
+msgid "This project can be restored until %{date}."
+msgstr ""
+
msgid "This project cannot be %{visibilityLevel} because the visibility of %{openShowLink}%{name}%{closeShowLink} is %{visibility}. To make this project %{visibilityLevel}, you must first %{openEditLink}change the visibility%{closeEditLink} of the parent group."
msgstr ""
@@ -36727,6 +37484,9 @@ msgstr ""
msgid "This project is %{strongStart}NOT%{strongEnd} a fork, and has the following:"
msgstr ""
+msgid "This project is %{strongStart}NOT%{strongEnd} a fork. This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -37416,6 +38176,9 @@ msgstr ""
msgid "Today"
msgstr ""
+msgid "Todos count"
+msgstr ""
+
msgid "Todos|Are you looking for things to do? Take a look at %{strongStart}%{openIssuesLinkStart}open issues%{openIssuesLinkEnd}%{strongEnd}, contribute to %{strongStart}%{mergeRequestLinkStart}a merge request%{mergeRequestLinkEnd}%{mergeRequestLinkEnd}%{strongEnd}, or mention someone in a comment to automatically assign them a new to-do item."
msgstr ""
@@ -37689,9 +38452,8 @@ msgstr ""
msgid "Trending"
msgstr ""
-msgid "Trials|%{planName} Trial %{enDash} %{num} day left"
-msgid_plural "Trials|%{planName} Trial %{enDash} %{num} days left"
-msgstr[0] ""
+msgid "Trials|%{planName} Trial"
+msgstr ""
msgid "Trials|Compare all plans"
msgstr ""
@@ -37699,6 +38461,9 @@ msgstr ""
msgid "Trials|Create a new group to start your GitLab Ultimate trial."
msgstr ""
+msgid "Trials|Day %{daysUsed}/%{duration}"
+msgstr ""
+
msgid "Trials|Go back to GitLab"
msgstr ""
@@ -37948,7 +38713,7 @@ msgstr ""
msgid "URL is triggered when repository is updated"
msgstr ""
-msgid "URL must be percent-encoded if neccessary."
+msgid "URL must be percent-encoded if necessary."
msgstr ""
msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
@@ -38167,6 +38932,9 @@ msgstr ""
msgid "Unlock account"
msgstr ""
+msgid "Unlock more features with GitLab Ultimate"
+msgstr ""
+
msgid "Unlock the discussion"
msgstr ""
@@ -38230,6 +38998,9 @@ msgstr ""
msgid "Unsubscribes from this %{quick_action_target}."
msgstr ""
+msgid "Unsupported sort value."
+msgstr ""
+
msgid "Unsupported todo type passed. Supported todo types are: %{todo_types}"
msgstr ""
@@ -38458,6 +39229,9 @@ msgstr ""
msgid "UsageQuota|File attachments and smaller design graphics."
msgstr ""
+msgid "UsageQuota|From %{storage_enforcement_date} storage limits will apply to this namespace. View and manage your usage in %{strong_start}Group Settings &gt; Usage quotas%{strong_end}."
+msgstr ""
+
msgid "UsageQuota|Git repository."
msgstr ""
@@ -38518,6 +39292,9 @@ msgstr ""
msgid "UsageQuota|Storage type"
msgstr ""
+msgid "UsageQuota|Storage used"
+msgstr ""
+
msgid "UsageQuota|This is the total amount of storage used across your projects within this namespace."
msgstr ""
@@ -38713,6 +39490,12 @@ msgstr ""
msgid "Use hashed storage paths for newly created and renamed repositories. Always enabled since 13.0."
msgstr ""
+msgid "Use issue count"
+msgstr ""
+
+msgid "Use issue weight"
+msgstr ""
+
msgid "Use one line per URI"
msgstr ""
@@ -39094,6 +39877,9 @@ msgstr ""
msgid "Users"
msgstr ""
+msgid "Users API rate limit"
+msgstr ""
+
msgid "Users can launch a development environment from a GitLab browser tab when the %{linkStart}Gitpod%{linkEnd} integration is enabled."
msgstr ""
@@ -39417,6 +40203,9 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View group pipeline usage quota"
+msgstr ""
+
msgid "View incident details at"
msgstr ""
@@ -39568,6 +40357,9 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
+msgid "Vulnerability"
+msgstr ""
+
msgid "Vulnerability Report"
msgstr ""
@@ -39619,6 +40411,9 @@ msgstr ""
msgid "VulnerabilityManagement|An unverified non-confirmed finding"
msgstr ""
+msgid "VulnerabilityManagement|At least one identifier is required"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -39628,12 +40423,24 @@ msgstr ""
msgid "VulnerabilityManagement|Create Jira issue"
msgstr ""
+msgid "VulnerabilityManagement|Enter a name"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE code"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE identifier URL"
+msgstr ""
+
msgid "VulnerabilityManagement|Fetching linked Jira issues"
msgstr ""
msgid "VulnerabilityManagement|Manually add a vulnerability entry into the vulnerability report."
msgstr ""
+msgid "VulnerabilityManagement|Name is a required field"
+msgstr ""
+
msgid "VulnerabilityManagement|Needs triage"
msgstr ""
@@ -39649,6 +40456,18 @@ msgstr ""
msgid "VulnerabilityManagement|Select a method"
msgstr ""
+msgid "VulnerabilityManagement|Select a severity level"
+msgstr ""
+
+msgid "VulnerabilityManagement|Select a status"
+msgstr ""
+
+msgid "VulnerabilityManagement|Severity is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Something went wrong while creating vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -39673,6 +40492,12 @@ msgstr ""
msgid "VulnerabilityManagement|Something went wrong, could not update vulnerability state."
msgstr ""
+msgid "VulnerabilityManagement|Status is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Submit vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Summary, detailed description, steps to reproduce, etc."
msgstr ""
@@ -39868,6 +40693,9 @@ msgstr ""
msgid "WARNING:"
msgstr ""
+msgid "WARNING: This snippet contains hidden files which might be used to mask malicious behavior. Exercise caution if cloning and executing code from this snippet."
+msgstr ""
+
msgid "Wait for the file to load to copy its contents"
msgstr ""
@@ -40087,6 +40915,15 @@ msgstr ""
msgid "Webhooks|An issue is created, updated, closed, or reopened."
msgstr ""
+msgid "Webhooks|Are you sure you want to delete this group hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this project hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this webhook?"
+msgstr ""
+
msgid "Webhooks|Comments"
msgstr ""
@@ -40096,6 +40933,9 @@ msgstr ""
msgid "Webhooks|Confidential issues events"
msgstr ""
+msgid "Webhooks|Delete webhook"
+msgstr ""
+
msgid "Webhooks|Deployment events"
msgstr ""
@@ -40328,6 +41168,9 @@ msgstr ""
msgid "Wiki"
msgstr ""
+msgid "Wiki page"
+msgstr ""
+
msgid "Wiki page was successfully created."
msgstr ""
@@ -40433,7 +41276,7 @@ msgstr ""
msgid "WikiPageConflictMessage|Someone edited the page the same time you did. Please check out %{wikiLinkStart}the page%{wikiLinkEnd} and make sure your changes will not unintentionally remove theirs."
msgstr ""
-msgid "WikiPage|An error occured while trying to render the content editor. Please try again later."
+msgid "WikiPage|An error occurred while trying to render the content editor. Please try again later."
msgstr ""
msgid "WikiPage|Are you sure you want to switch back to the classic editor?"
@@ -40592,6 +41435,18 @@ msgstr ""
msgid "WorkItem|New Task"
msgstr ""
+msgid "WorkItem|Something went wrong when creating a work item. Please try again"
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching the work item. Please try again."
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching work item types. Please try again"
+msgstr ""
+
+msgid "WorkItem|Type"
+msgstr ""
+
msgid "WorkItem|Work Items"
msgstr ""
@@ -40658,7 +41513,10 @@ msgstr ""
msgid "You are about to add %{usersTag} people to the discussion. They will all receive a notification."
msgstr ""
-msgid "You are about to permanently delete this project"
+msgid "You are about to delete this forked project containing:"
+msgstr ""
+
+msgid "You are about to delete this project containing:"
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."
@@ -40679,6 +41537,9 @@ msgstr ""
msgid "You are attempting to update a file that has changed since you started editing it."
msgstr ""
+msgid "You are billed if you exceed this number. %{qsrOverageLinkStart}How does billing work?%{qsrOverageLinkEnd}"
+msgstr ""
+
msgid "You are connected to the Prometheus server, but there is currently no data to display."
msgstr ""
@@ -40736,6 +41597,9 @@ msgstr ""
msgid "You are not authorized to update this scanner profile"
msgstr ""
+msgid "You are not authorized to upload metric images"
+msgstr ""
+
msgid "You are now impersonating %{username}"
msgstr ""
@@ -40889,9 +41753,6 @@ msgstr ""
msgid "You can only upload one design when dropping onto an existing design."
msgstr ""
-msgid "You can recover this project until %{date}"
-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 ""
@@ -40940,9 +41801,6 @@ msgstr ""
msgid "You cannot write to this read-only GitLab instance."
msgstr ""
-msgid "You can’t %{tag_start}edit%{tag_end} files directly in this project. Fork this project and submit a merge request with your changes."
-msgstr ""
-
msgid "You can’t edit files directly in this project. Fork this project and submit a merge request with your changes."
msgstr ""
@@ -41094,9 +41952,6 @@ 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 set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
@@ -41127,12 +41982,6 @@ msgstr ""
msgid "You must have maintainer access to force delete a lock"
msgstr ""
-msgid "You must have permission to create a project in a group before forking."
-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 ""
@@ -41538,7 +42387,7 @@ msgstr ""
msgid "Your public email will be displayed on your public profile."
msgstr ""
-msgid "Your request for access could not be processed: %{error_meesage}"
+msgid "Your request for access could not be processed: %{error_message}"
msgstr ""
msgid "Your request for access has been queued for review."
@@ -41718,6 +42567,9 @@ msgstr ""
msgid "archived:"
msgstr ""
+msgid "artifacts"
+msgstr ""
+
msgid "assign yourself"
msgstr ""
@@ -41746,6 +42598,9 @@ msgstr[0] ""
msgid "branch name"
msgstr ""
+msgid "builds"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -42166,6 +43021,9 @@ msgstr ""
msgid "contact with same email already exists in group hierarchy"
msgstr ""
+msgid "container registry images"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -42205,6 +43063,9 @@ msgstr ""
msgid "data"
msgstr ""
+msgid "database"
+msgstr ""
+
msgid "date must not be after 9999-12-31"
msgstr ""
@@ -42227,9 +43088,6 @@ msgstr ""
msgid "design"
msgstr ""
-msgid "detached"
-msgstr ""
-
msgid "disabled"
msgstr ""
@@ -42474,7 +43332,7 @@ msgstr ""
msgid "is not a valid X509 certificate."
msgstr ""
-msgid "is not allowed for sign-up."
+msgid "is not allowed for sign-up. Please use your regular email address."
msgstr ""
msgid "is not allowed for this group."
@@ -42486,7 +43344,7 @@ msgstr ""
msgid "is not allowed since the group is not top-level group."
msgstr ""
-msgid "is not allowed."
+msgid "is not allowed. Please use your regular email address."
msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
@@ -42573,6 +43431,9 @@ msgstr ""
msgid "level: %{level}"
msgstr ""
+msgid "lfs objects"
+msgstr ""
+
msgid "limit of %{project_limit} reached"
msgstr ""
@@ -42789,6 +43650,9 @@ msgstr ""
msgid "mrWidget|Merge blocked: pipeline must succeed. It's waiting for a manual action to continue."
msgstr ""
+msgid "mrWidget|Merge blocked: pipeline must succeed. Push a commit that fixes the failure, or %{linkStart}learn about other solutions.%{linkEnd}"
+msgstr ""
+
msgid "mrWidget|Merge blocked: this merge request must be approved."
msgstr ""
@@ -42906,9 +43770,6 @@ msgstr ""
msgid "mrWidget|The changes were not merged into"
msgstr ""
-msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -43056,9 +43917,6 @@ msgstr ""
msgid "open issue"
msgstr ""
-msgid "opened %{timeAgo}"
-msgstr ""
-
msgid "or"
msgstr ""
@@ -43069,6 +43927,12 @@ msgid "out of %d total test"
msgid_plural "out of %d total tests"
msgstr[0] ""
+msgid "packages"
+msgstr ""
+
+msgid "pages"
+msgstr ""
+
msgid "parent"
msgid_plural "parents"
msgstr[0] ""
@@ -43214,6 +44078,9 @@ msgid "reply"
msgid_plural "replies"
msgstr[0] ""
+msgid "repositories"
+msgstr ""
+
msgid "repository:"
msgstr ""
@@ -43334,12 +44201,18 @@ msgstr ""
msgid "tag name"
msgstr ""
+msgid "terraform states"
+msgstr ""
+
msgid "the correct format."
msgstr ""
msgid "the file"
msgstr ""
+msgid "the following epic(s)"
+msgstr ""
+
msgid "the following issue(s)"
msgstr ""
@@ -43352,21 +44225,12 @@ msgstr ""
msgid "this document"
msgstr ""
-msgid "this issue cannot be assigned to a confidential epic since it is public"
-msgstr ""
-
-msgid "this issue cannot be made public since it belongs to a confidential epic"
-msgstr ""
-
msgid "time summary"
msgstr ""
msgid "toggle collapse"
msgstr ""
-msgid "train"
-msgstr ""
-
msgid "triggered"
msgstr ""
@@ -43494,3 +44358,6 @@ msgstr ""
msgid "{project}"
msgstr ""
+msgid "✔"
+msgstr ""
+
diff --git a/locale/zh_CN/gitlab.po b/locale/zh_CN/gitlab.po
index 1c60ebc9ab5..0d4bd6ac254 100644
--- a/locale/zh_CN/gitlab.po
+++ b/locale/zh_CN/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: zh-CN\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2022-02-02 15:42\n"
+"PO-Revision-Date: 2022-03-01 20:36\n"
msgid " %{start} to %{end}"
msgstr "从%{start}到%{end}"
@@ -110,19 +110,19 @@ msgstr[0] "%d 个网å€å·²æ‰«æ"
msgid "%d additional approver"
msgid_plural "%d additional approvers"
-msgstr[0] ""
+msgstr[0] "%d 个é¢å¤–的核准人"
msgid "%d additional assignee"
msgid_plural "%d additional assignees"
-msgstr[0] ""
+msgstr[0] "%d 个é¢å¤–的指派人"
msgid "%d additional commenter"
msgid_plural "%d additional commenters"
-msgstr[0] ""
+msgstr[0] "%d 个é¢å¤–评论者"
msgid "%d additional committer"
msgid_plural "%d additional committers"
-msgstr[0] ""
+msgstr[0] "%d 个é¢å¤–æ交者"
msgid "%d approver"
msgid_plural "%d approvers"
@@ -132,6 +132,10 @@ msgid "%d approver (you've approved)"
msgid_plural "%d approvers (you've approved)"
msgstr[0] "%dä½æ ¸å‡†äºº(您已批准)"
+msgid "%d assigned issue"
+msgid_plural "%d assigned issues"
+msgstr[0] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] "%d 个已更改的文件"
@@ -352,9 +356,21 @@ msgid "%d vulnerability dismissed"
msgid_plural "%d vulnerabilities dismissed"
msgstr[0] "%d个æ¼æ´žå·²å¿½ç•¥"
-msgid "%d vulnerability updated"
-msgid_plural "%d vulnerabilities updated"
-msgstr[0] "%d个æ¼æ´žå·²æ›´æ–°"
+msgid "%d vulnerability set to confirmed"
+msgid_plural "%d vulnerabilities set to confirmed"
+msgstr[0] ""
+
+msgid "%d vulnerability set to dismissed"
+msgid_plural "%d vulnerabilities set to dismissed"
+msgstr[0] ""
+
+msgid "%d vulnerability set to needs triage"
+msgid_plural "%d vulnerabilities set to needs triage"
+msgstr[0] ""
+
+msgid "%d vulnerability set to resolved"
+msgid_plural "%d vulnerabilities set to resolved"
+msgstr[0] ""
msgid "%d warning found:"
msgid_plural "%d warnings found:"
@@ -407,10 +423,10 @@ msgid_plural "%{bold_start}%{count}%{bold_end} opened merge requests"
msgstr[0] "%{bold_start}%{count}%{bold_end} 个开放中的åˆå¹¶è¯·æ±‚"
msgid "%{codeStart}type%{codeEnd} is deprecated and will be removed in 15.0. Use %{codeStart}stage%{codeEnd} instead. %{linkStart}Learn More %{linkEnd}"
-msgstr ""
+msgstr "%{codeStart}type%{codeEnd} 已弃用,并将在 15.0 中删除。改为使用 %{codeStart}stage%{codeEnd} 。%{linkStart}了解更多 %{linkEnd}"
msgid "%{codeStart}types%{codeEnd} is deprecated and will be removed in 15.0. Use %{codeStart}stages%{codeEnd} instead. %{linkStart}Learn More %{linkEnd}"
-msgstr ""
+msgstr "%{codeStart}types%{codeEnd} 已弃用,并将在 15.0 中删除。改为使用 %{codeStart}stages%{codeEnd} 。%{linkStart}了解更多 %{linkEnd}"
msgid "%{code_open}Masked:%{code_close} Hidden in job logs. Must match masking requirements."
msgstr "%{code_open}éšè—:%{code_close} éšè—在作业日志中。必须符åˆéšè—è¦æ±‚。"
@@ -434,6 +450,12 @@ msgstr[0] "%{completedCount}/%{count} 任务已完æˆ"
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr "总æƒé‡%{totalWeight}中的%{completedWeight}已完æˆ"
+msgid "%{completed} of %{total} issues closed"
+msgstr ""
+
+msgid "%{completed} of %{total} weight completed"
+msgstr ""
+
msgid "%{cores} cores"
msgstr "%{cores}个核心"
@@ -572,7 +594,7 @@ msgid "%{group_name} group members"
msgstr "%{group_name}群组æˆå‘˜"
msgid "%{group_name} is approaching the limit of available seats"
-msgstr ""
+msgstr "%{group_name} 正接近å¯ç”¨å¸­ä½çš„é™åˆ¶"
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}组æ¥ç®¡ç†ã€‚"
@@ -671,7 +693,7 @@ msgid "%{level_name} is not allowed since the fork source project has lower visi
msgstr "由于派生的æºé¡¹ç›®å¯è§æ€§è¾ƒä½Žï¼Œå› æ­¤ä¸å…许使用%{level_name}。"
msgid "%{linkStart}Learn more.%{linkEnd}"
-msgstr ""
+msgstr "%{linkStart}了解更多。%{linkEnd}"
msgid "%{link_start}Learn more%{link_end} about roles."
msgstr "%{link_start}查看更多%{link_end} 关于角色的信æ¯ã€‚"
@@ -683,7 +705,7 @@ msgid "%{link_start}Start the title with %{draft_snippet}%{link_end} to prevent
msgstr "使用 %{link_start} %{draft_snippet}%{link_end} 开始标题,以防止åˆå¹¶è¯·æ±‚è‰ç¨¿åœ¨å‡†å¤‡å°±ç»ªä¹‹å‰åˆå¹¶ã€‚"
msgid "%{link_start}Upload a license%{link_end} file or enter the license key you have received from GitLab Inc."
-msgstr ""
+msgstr "%{link_start}上传许å¯è¯%{link_end} 文件或输入您收到的许å¯è¯å¯†é’¥ã€‚"
msgid "%{link_start}What information does GitLab Inc. collect?%{link_end}"
msgstr "%{link_start}GitLab Inc. 收集哪些信æ¯ï¼Ÿ%{link_end}"
@@ -776,6 +798,9 @@ msgstr "%{openedEpics}个开å¯ä¸­ï¼Œ %{closedEpics}个已关闭"
msgid "%{openedIssues} open, %{closedIssues} closed"
msgstr "%{openedIssues}个开å¯ä¸­ï¼Œ %{closedIssues}个已关闭"
+msgid "%{percentage}%% issues closed"
+msgstr ""
+
msgid "%{percentage}%% weight completed"
msgstr "%{percentage}%%æƒé‡å·²å®Œæˆ"
@@ -826,7 +851,7 @@ msgid "%{rotation} has been recalculated with the remaining participants. Please
msgstr "%{rotation} 已与其余å‚与者é‡æ–°è®¡ç®—。请审查 %{rotation} 的新设置。建议您与目å‰çš„on-call人员å–å¾—è”系,以确ä¿on-call工作的连续性。"
msgid "%{runner} created %{timeago}"
-msgstr ""
+msgstr "%{runner} 已创建 %{timeago}"
msgid "%{scope} results for term '%{term}'"
msgstr "'%{term}' 的结果 %{scope} "
@@ -1190,6 +1215,9 @@ msgid "- User"
msgid_plural "- Users"
msgstr[0] "- 用户"
+msgid "- of - issues closed"
+msgstr ""
+
msgid "- of - weight completed"
msgstr "- 于总计 - æƒé‡å·²å®Œæˆ"
@@ -1309,8 +1337,8 @@ msgstr "10-19项贡献"
msgid "1000+"
msgstr "1000+"
-msgid "192.168.0.0/24"
-msgstr "192.168.0.0/24"
+msgid "192.168.0.0/24 or 2001:0DB8:1234::/48"
+msgstr ""
msgid "1st contribution!"
msgstr "最高贡献"
@@ -1621,14 +1649,14 @@ msgstr "文件夹/openapi.json"
msgid "AWS Access Key"
msgstr "AWS访问密钥"
-msgid "AWS Access Key. Only required if not using role instance credentials"
-msgstr "AWS访问密钥。仅当ä¸ä½¿ç”¨è§’色实例凭æ®æ—¶æ‰éœ€è¦"
-
msgid "AWS Secret Access Key"
msgstr "AWS秘密访问密钥"
-msgid "AWS Secret Access Key. Only required if not using role instance credentials"
-msgstr "AWS秘密访问密钥。仅当ä¸ä½¿ç”¨è§’色实例凭æ®æ—¶æ‰éœ€è¦"
+msgid "AWS access key ID (Optional)"
+msgstr ""
+
+msgid "AWS secret access key (Optional)"
+msgstr ""
msgid "AWS service error: %{error}"
msgstr "AWSæœåŠ¡é”™è¯¯ï¼š%{error}"
@@ -1687,9 +1715,6 @@ msgstr "访问被ç¦æ­¢ã€‚检查您的访问æƒé™ã€‚"
msgid "Access granted"
msgstr "已授予访问"
-msgid "Access key ID"
-msgstr "访问密钥 ID"
-
msgid "Access requests"
msgstr "访问请求"
@@ -1859,13 +1884,13 @@ msgid "Active Sessions"
msgstr "活动会è¯"
msgid "Active chat names (%{count})"
-msgstr ""
+msgstr "活跃的èŠå¤©ç”¨æˆ·å (%{count})"
msgid "Activity"
msgstr "动æ€"
-msgid "Activity|An error occured while retrieving activity. Reload the page to try again."
-msgstr "获å–动æ€æ—¶å‘生错误,é‡æ–°åŠ è½½é¡µé¢ä»¥é‡è¯•ã€‚"
+msgid "Activity|An error occurred while retrieving activity. Reload the page to try again."
+msgstr ""
msgid "Add"
msgstr "添加"
@@ -1892,7 +1917,7 @@ msgid "Add LICENSE"
msgstr "添加LICENSE"
msgid "Add New Site"
-msgstr ""
+msgstr "添加新站点"
msgid "Add README"
msgstr "添加自述文件"
@@ -1903,11 +1928,14 @@ msgstr "添加 Zoom 会议"
msgid "Add a %{type}"
msgstr "添加一个%{type}"
+msgid "Add a GCP region"
+msgstr ""
+
msgid "Add a GPG key"
msgstr "添加GPG密钥"
msgid "Add a GPG key for secure access to GitLab. %{help_link_start}Learn more.%{help_link_end}"
-msgstr ""
+msgstr "添加 GPG 密钥,安全访问 GitLab。%{help_link_start}了解更多。%{help_link_end}"
msgid "Add a Jaeger URL to replace this page with a link to your Jaeger server. You first need to %{link_start_tag}install Jaeger%{link_end_tag}."
msgstr "添加一个Jaeger URL,用指å‘您的JaegeræœåŠ¡å™¨çš„链接替æ¢æ­¤é¡µé¢ã€‚æ‚¨é¦–å…ˆéœ€è¦ %{link_start_tag}安装Jaeger%{link_end_tag}。"
@@ -1954,6 +1982,9 @@ msgstr "添加一个新议题"
msgid "Add a numbered list"
msgstr "添加编å·åˆ—表"
+msgid "Add a related epic"
+msgstr ""
+
msgid "Add a related issue"
msgstr "添加一个相关议题"
@@ -1976,7 +2007,7 @@ msgid "Add an SSH key"
msgstr "添加SSH密钥"
msgid "Add an SSH key for secure access to GitLab. %{help_link_start}Learn more.%{help_link_end}"
-msgstr ""
+msgstr "添加 SSH 密钥,安全访问 GitLab。%{help_link_start}了解更多。%{help_link_end}"
msgid "Add an existing issue"
msgstr "添加一个已有议题"
@@ -2068,6 +2099,9 @@ msgstr "添加或删除先å‰åˆå¹¶çš„æ交"
msgid "Add or subtract spent time"
msgstr "增加或å‡å°‘耗时"
+msgid "Add people"
+msgstr ""
+
msgid "Add previously merged commits"
msgstr "添加先å‰åˆå¹¶çš„æ交"
@@ -2134,6 +2168,9 @@ msgstr "添加æ¼æ´žå‘现"
msgid "Add webhook"
msgstr "添加webhook"
+msgid "Add your team members and others to GitLab."
+msgstr ""
+
msgid "Add/remove"
msgstr "添加/删除"
@@ -2393,10 +2430,10 @@ msgid "AdminDashboard|Error loading the statistics. Please try again"
msgstr "加载统计数æ®æ—¶å‡ºé”™ã€‚请å†è¯•ä¸€æ¬¡"
msgid "AdminGeo|The URL of the primary site that is used internally by the secondary sites."
-msgstr ""
+msgstr "次è¦ç«™ç‚¹å†…部使用的主站点的 URL。"
msgid "AdminGeo|The URL of the secondary site that is used internally by the primary site."
-msgstr ""
+msgstr "主站点内部使用的次è¦ç«™ç‚¹çš„ URL。"
msgid "AdminLabels|Define your default set of project labels"
msgstr "定义项目标记的默认集"
@@ -2555,7 +2592,7 @@ msgid "AdminUsers|(Internal)"
msgstr "内部"
msgid "AdminUsers|(Locked)"
-msgstr ""
+msgstr "(é”定)"
msgid "AdminUsers|(Pending approval)"
msgstr "等待批准"
@@ -2594,7 +2631,7 @@ msgid "AdminUsers|Admin"
msgstr "管ç†å‘˜"
msgid "AdminUsers|Administrator"
-msgstr ""
+msgstr "管ç†å‘˜"
msgid "AdminUsers|Admins"
msgstr "管ç†å‘˜"
@@ -2720,7 +2757,7 @@ msgid "AdminUsers|Learn more about %{link_start}banned users.%{link_end}"
msgstr "了解更多关于 %{link_start}å°ç¦ç”¨æˆ·ã€‚%{link_end}"
msgid "AdminUsers|Locked"
-msgstr ""
+msgstr "å·²é”定"
msgid "AdminUsers|Log in"
msgstr "登录"
@@ -2786,7 +2823,7 @@ msgid "AdminUsers|The user can't log in."
msgstr "用户无法登录。"
msgid "AdminUsers|The user has unlimited access to all groups, projects, users, and features."
-msgstr ""
+msgstr "用户å¯ä»¥æ— é™åˆ¶åœ°è®¿é—®æ‰€æœ‰ç¾¤ç»„ã€é¡¹ç›®ã€ç”¨æˆ·å’ŒåŠŸèƒ½ã€‚"
msgid "AdminUsers|The user will be logged out"
msgstr "此用户将被注销"
@@ -2891,7 +2928,7 @@ msgid "AdminUsers|You can unban their account in the future. Their data remains
msgstr "未æ¥ï¼Œæ‚¨å¯ä»¥è§£ç¦ä»–们的å¸æˆ·ã€‚他们的数æ®å°†ä¼šä¿æŒå®Œå¥½ã€‚"
msgid "AdminUsers|You cannot remove your own administrator access."
-msgstr ""
+msgstr "您ä¸èƒ½åˆ é™¤æ‚¨è‡ªå·±çš„管ç†å‘˜æƒé™ã€‚"
msgid "AdminUsers|You must transfer ownership or delete the groups owned by this user before you can delete their account"
msgstr "您必须转移所有æƒæˆ–删除这些群组,然åŽæ‰èƒ½åˆ é™¤æ‚¨çš„å¸æˆ·ã€‚"
@@ -2956,12 +2993,6 @@ msgstr "高级导出选项"
msgid "AdvancedSearch|Reindex required"
msgstr "需è¦é‡æ–°ç´¢å¼•"
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. Permanently deleting this project will %{strongStart}immediately delete%{strongEnd} its repositories and %{strongStart}all related resources%{strongEnd}, including issues, merge requests etc."
-msgstr "项目永久删除åŽï¼Œå°† %{strongStart}无法æ¢å¤%{strongEnd},永久删除此项目将 %{strongStart}ç«‹å³åˆ é™¤%{strongEnd} 它的仓库和 %{strongStart}所有相关资æº%{strongEnd},包括议题ã€åˆå¹¶è¯·æ±‚等。"
-
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. You will lose this project's repository and %{strongStart}all related resources%{strongEnd}, including issues and merge requests."
-msgstr "项目永久删除åŽï¼Œå°† %{strongStart}无法æ¢å¤%{strongEnd},您将丢失此项目的仓库和%{strongStart}所有相关资æº%{strongEnd},包括议题和åˆå¹¶è¯·æ±‚。"
-
msgid "After a successful password update you will be redirected to login screen."
msgstr "密ç æ›´æ–°æˆåŠŸåŽï¼Œæ‚¨å°†è¢«é‡å®šå‘到登录页é¢ã€‚"
@@ -2992,6 +3023,9 @@ msgstr "Akismet API 密钥"
msgid "Akismet helps prevent the creation of spam issues in public projects."
msgstr "Akismet有助于防止在公共项目中产生垃圾信æ¯ã€‚"
+msgid "Alert"
+msgstr ""
+
msgid "AlertManagement|Acknowledged"
msgstr "已确认"
@@ -3364,9 +3398,6 @@ msgstr "所有电å­é‚®ä»¶åœ°å€éƒ½å¯ç”¨äºŽæ ‡è¯†æ‚¨çš„æ交。"
msgid "All environments"
msgstr "所有环境"
-msgid "All epics"
-msgstr "所有å²è¯—"
-
msgid "All groups and projects"
msgstr "所有群组和项目"
@@ -3452,13 +3483,13 @@ msgid "Allow public access to pipelines and job details, including output logs a
msgstr "å…许所有人访问æµæ°´çº¿å’Œä½œä¸šè¯¦æƒ…,包括输出日志和产物。"
msgid "Allow subgroups to set up their own two-factor authentication rules"
-msgstr "å…许副组设置自己的åŒé‡èº«ä»½éªŒè¯è§„则"
+msgstr "å…许å­ç»„设置自己的åŒé‡è®¤è¯è§„则"
msgid "Allow this key to push to this repository"
msgstr "å…许此密钥推é€åˆ°è¿™ä¸ªä»“库"
msgid "Allow this secondary site to replicate content on Object Storage"
-msgstr ""
+msgstr "å…许此次è¦ç«™ç‚¹å¤åˆ¶å¯¹è±¡å­˜å‚¨ä¸­çš„内容"
msgid "Allow use of licensed EE features"
msgstr "å…许使用许å¯çš„EE功能"
@@ -3716,7 +3747,7 @@ msgid "An error occurred while fetching the latest pipeline."
msgstr "获å–最新æµæ°´çº¿æ—¶å‘生错误。"
msgid "An error occurred while fetching the pipelines jobs."
-msgstr ""
+msgstr "获å–æµæ°´çº¿ä½œä¸šæ—¶å‡ºé”™ã€‚"
msgid "An error occurred while fetching the releases. Please try again."
msgstr "获å–å‘布时å‘生错误。请é‡è¯•ã€‚"
@@ -4101,12 +4132,15 @@ msgstr "批准用户"
msgid "ApplicationSettings|Approve users in the pending approval status?"
msgstr "批准处于待批准状æ€çš„用户?"
-msgid "ApplicationSettings|By making this change, you will automatically approve %d user with the pending approval status."
-msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users with the pending approval status."
-msgstr[0] "通过进行此更改,您将自动批准 %d å处于待批准状æ€çš„用户。"
+msgid "ApplicationSettings|Approve users who are pending approval?"
+msgstr ""
-msgid "ApplicationSettings|By making this change, you will automatically approve all users in pending approval status."
-msgstr "通过åšæ­¤æ›´æ”¹ï¼Œæ‚¨å°†è‡ªåŠ¨æ‰¹å‡†æ‰€æœ‰ç­‰å¾…批准状æ€çš„用户。"
+msgid "ApplicationSettings|By making this change, you will automatically approve %d user who is pending approval."
+msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users who are pending approval."
+msgstr[0] ""
+
+msgid "ApplicationSettings|By making this change, you will automatically approve all users who are pending approval."
+msgstr ""
msgid "ApplicationSettings|Denied domains for sign-ups"
msgstr "æ‹’ç»æ³¨å†Œçš„域"
@@ -4312,10 +4346,10 @@ msgid "ApprovalRule|Improve your organization's code review with required approv
msgstr ""
msgid "ApprovalRule|Increase quality and maintain standards."
-msgstr ""
+msgstr "æ高质é‡å¹¶ä¿æŒæ ‡å‡†ã€‚"
msgid "ApprovalRule|Learn more about merge request approval rules."
-msgstr ""
+msgstr "了解有关åˆå¹¶è¯·æ±‚批准规则的更多信æ¯ã€‚"
msgid "ApprovalRule|Name"
msgstr "å称"
@@ -4342,7 +4376,7 @@ msgid "ApprovalRule|Previously detected"
msgstr "以å‰æ£€æµ‹åˆ°"
msgid "ApprovalRule|Reduce your time to merge."
-msgstr ""
+msgstr "å‡å°‘åˆå¹¶æ—¶é—´ã€‚"
msgid "ApprovalRule|Resolved"
msgstr "已解决"
@@ -4375,7 +4409,7 @@ msgid "ApprovalRule|Target branch"
msgstr "目标分支"
msgid "ApprovalRule|Try for free"
-msgstr ""
+msgstr "å…费试用"
msgid "ApprovalRule|Vulnerabilities allowed"
msgstr "å…许的æ¼æ´ž"
@@ -4387,28 +4421,28 @@ msgid "ApprovalSettings|Merge request approval settings have been updated."
msgstr "åˆå¹¶è¯·æ±‚审批设置已更新。"
msgid "ApprovalSettings|Prevent approval by author"
-msgstr ""
+msgstr "阻止作者批准"
msgid "ApprovalSettings|Prevent approval by author."
msgstr "ç¦æ­¢ä½œè€…审批。"
msgid "ApprovalSettings|Prevent approvals by users who add commits"
-msgstr ""
+msgstr "阻止添加æ交的用户批准"
msgid "ApprovalSettings|Prevent approvals by users who add commits."
msgstr "ç¦æ­¢æ·»åŠ æ交的用户审批。"
msgid "ApprovalSettings|Prevent editing approval rules in merge requests"
-msgstr ""
+msgstr "阻止在åˆå¹¶è¯·æ±‚中编辑批准规则"
msgid "ApprovalSettings|Prevent editing approval rules in projects and merge requests."
msgstr "ç¦æ­¢åœ¨é¡¹ç›®å’Œåˆå¹¶è¯·æ±‚中编辑批准规则。"
msgid "ApprovalSettings|Remove all approvals when commits are added to the source branch"
-msgstr ""
+msgstr "当æ交被添加到æºåˆ†æ”¯æ—¶ï¼Œåˆ é™¤æ‰€æœ‰æ‰¹å‡†"
msgid "ApprovalSettings|Require user password to approve"
-msgstr ""
+msgstr "需è¦ç”¨æˆ·å¯†ç æ‰èƒ½æ‰¹å‡†"
msgid "ApprovalSettings|There was an error loading merge request approval settings."
msgstr "加载åˆå¹¶è¯·æ±‚批准设置时出错。"
@@ -4506,12 +4540,12 @@ msgstr "归档项目"
msgid "Archiving the project will make it entirely read-only. It is hidden from the dashboard and doesn't show up in searches. %{strong_start}The repository cannot be committed to, and no issues, comments, or other entities can be created.%{strong_end} %{link_start}Learn more.%{link_end}"
msgstr "归档项目将使其完全åªè¯»ã€‚仪表æ¿ä¸­å’Œæœç´¢ç»“果中都ä¸ä¼šå‡ºçŽ°è¯¥é¡¹ç›®ã€‚%{strong_start}代ç å°†æ— æ³•æ交到仓库,也无法创建任何议题ã€è¯„论或其它对象。%{strong_end}%{link_start}了解详情。%{link_end}"
-msgid "Are you ABSOLUTELY SURE you wish to delete this project?"
-msgstr "您确定è¦åˆ é™¤æ­¤é¡¹ç›®å—?"
-
msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
msgstr "您ç»å¯¹ç¡®å®šè¦åˆ é™¤æ­¤ç¾¤ç»„å—?"
+msgid "Are you absolutely sure?"
+msgstr ""
+
msgid "Are you sure that you want to archive this project?"
msgstr "确定è¦å½’档此项目å—?"
@@ -4522,7 +4556,7 @@ msgid "Are you sure you want to %{action} %{name}?"
msgstr "æ‚¨ç¡®å®šè¦ %{action} %{name}å—?"
msgid "Are you sure you want to approve %{user}?"
-msgstr ""
+msgstr "您确定è¦æ‰¹å‡† %{user} å—?"
msgid "Are you sure you want to attempt to merge?"
msgstr "您确定è¦å°è¯•åˆå¹¶å—?"
@@ -4545,12 +4579,18 @@ msgstr "确实è¦åˆ é™¤æ­¤%{typeOfComment}å—?"
msgid "Are you sure you want to delete this SSH key?"
msgstr "您确定è¦åˆ é™¤æ­¤SSH密钥å—?"
+msgid "Are you sure you want to delete this comment?"
+msgstr ""
+
msgid "Are you sure you want to delete this deploy key?"
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 label?"
+msgstr ""
+
msgid "Are you sure you want to delete this pipeline schedule?"
msgstr "确定è¦åˆ é™¤æ­¤æµæ°´çº¿è®¡åˆ’å—?"
@@ -4566,9 +4606,6 @@ msgstr "确定放弃评论å—?"
msgid "Are you sure you want to discard your changes?"
msgstr "确定è¦æ”¾å¼ƒæ›´æ”¹å—?"
-msgid "Are you sure you want to erase this build?"
-msgstr "您确定è¦åˆ é™¤è¿™ä¸ªæž„建å—?"
-
msgid "Are you sure you want to import %d repository?"
msgid_plural "Are you sure you want to import %d repositories?"
msgstr[0] "您确定è¦å¯¼å…¥%d个仓库å—?"
@@ -4615,6 +4652,9 @@ msgstr "您确定è¦åˆ é™¤è¿™ä¸ªèº«ä»½æ ‡è¯†å—?"
msgid "Are you sure you want to remove this list?"
msgstr "您确定è¦åˆ é™¤æ­¤åˆ—表å—?"
+msgid "Are you sure you want to remove this nickname?"
+msgstr ""
+
msgid "Are you sure you want to reset the health check token?"
msgstr "确定è¦é‡ç½®è¿è¡ŒçŠ¶å†µæ£€æŸ¥ä»¤ç‰Œå—?"
@@ -4627,12 +4667,12 @@ msgstr "确定è¦é‡è¯•æ­¤è¿ç§»å—?"
msgid "Are you sure you want to revoke this %{type}? This action cannot be undone."
msgstr "您确定è¦æ’¤é”€æ­¤%{type}å—?此æ“作ä¸å¯é€†ã€‚"
-msgid "Are you sure you want to revoke this nickname?"
-msgstr "您确定è¦å–消此昵称?"
-
msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
msgstr "您确定è¦æ’¤æ¶ˆæ­¤ä¸ªäººè®¿é—®ä»¤ç‰Œå—?此æ“作无法撤消。"
+msgid "Are you sure you want to revoke this project access token? This action cannot be undone."
+msgstr ""
+
msgid "Are you sure you want to stop this environment?"
msgstr "是å¦ç¡®å®šç»ˆæ­¢å½“å‰çŽ¯å¢ƒï¼Ÿ"
@@ -4700,7 +4740,7 @@ msgid "Ask someone with write access to resolve it."
msgstr "请有写入æƒé™çš„人æ¥è§£å†³å®ƒã€‚"
msgid "Ask your group owner to set up a group runner."
-msgstr ""
+msgstr "询问您的群组所有者设置一个群组 runner。"
msgid "Assertion consumer service URL"
msgstr "断言消费者æœåŠ¡ URL"
@@ -4777,9 +4817,6 @@ msgstr "分é…ç»™%{assigneeName}"
msgid "Assigned to %{assignee_name}"
msgstr "分é…ç»™%{assignee_name}"
-msgid "Assigned to %{name}"
-msgstr "分é…ç»™%{name}"
-
msgid "Assigned to me"
msgstr "已分派给我"
@@ -4842,6 +4879,9 @@ msgstr[0] "添加%d个附件"
msgid "Attaching the file failed."
msgstr "添加附件失败。"
+msgid "Attention"
+msgstr ""
+
msgid "Audit Events"
msgstr "审计事件"
@@ -5004,6 +5044,12 @@ msgstr "授æƒäºŽ"
msgid "Authorized applications (%{size})"
msgstr "已授æƒåº”用 (%{size})"
+msgid "AuthorizedApplication|Are you sure you want to revoke this application?"
+msgstr ""
+
+msgid "AuthorizedApplication|Revoke application"
+msgstr ""
+
msgid "Authors: %{authors}"
msgstr "作者人数:%{authors}"
@@ -5140,7 +5186,7 @@ msgid "Average per day: %{average}"
msgstr "å¹³å‡æ¯å¤©: %{average}"
msgid "Awaiting user signup"
-msgstr ""
+msgstr "等待用户注册"
msgid "Award added"
msgstr "赞èµå·²æ·»åŠ "
@@ -5275,7 +5321,7 @@ msgid "Based on"
msgstr "基于"
msgid "Basic information"
-msgstr ""
+msgstr "基本信æ¯"
msgid "Be careful. Changing the project's namespace can have unintended side effects."
msgstr "请注æ„,更改项目的命å空间å¯èƒ½ä¼šäº§ç”Ÿéžé¢„期的副作用。"
@@ -5305,7 +5351,7 @@ msgid "Below you will find all the groups that are public."
msgstr "您将在下é¢æ‰¾åˆ°æ‰€æœ‰å…¬å¼€çš„群组。"
msgid "Beta"
-msgstr ""
+msgstr "Beta"
msgid "Bi-weekly code coverage"
msgstr "åŒå‘¨ä»£ç è¦†ç›–率"
@@ -5335,7 +5381,7 @@ msgid "BillingPlans|If you would like to downgrade your plan please contact %{su
msgstr "如果您想è¦é™çº§æ‚¨çš„订阅计划,请è”ç³»%{support_link_start}客户支æŒ%{support_link_end}。"
msgid "BillingPlans|Learn more about each plan by reading our %{faq_link}, or start a free 30-day trial of GitLab.com Ultimate."
-msgstr "å¯ä»¥é˜…读%{faq_link}了解更多付费方案细节,或者开始为期30天的试用。"
+msgstr "å¯ä»¥é˜…读%{faq_link}了解更多付费方案细节,或者开始为期30天的旗舰版试用。"
msgid "BillingPlans|Learn more about each plan by visiting our %{pricing_page_link}."
msgstr "通过阅读我们的 %{pricing_page_link} 了解有关æ¯ä¸ªè®¡åˆ’的更多信æ¯ã€‚"
@@ -5437,13 +5483,13 @@ msgid "Billings|Your account has been validated"
msgstr "您的å¸æˆ·å·²é€šè¿‡éªŒè¯"
msgid "Billing|%{user} was successfully approved"
-msgstr ""
+msgstr "%{user} æˆåŠŸèŽ·å¾—批准"
msgid "Billing|An email address is only visible for users with public emails."
msgstr "åªæœ‰ç”¨æˆ·è®¾ç½®äº†å…¬å¼€ç”µå­é‚®ä»¶ï¼Œä»–们的邮件æ‰å¯¹å¤–å¯è§ã€‚"
msgid "Billing|An error occurred while approving %{user}"
-msgstr ""
+msgstr "批准 %{user} 时出错"
msgid "Billing|An error occurred while getting a billable member details"
msgstr "获å–计费会员详细信æ¯æ—¶å‘生错误"
@@ -5524,7 +5570,7 @@ msgid "Blame"
msgstr "Blame"
msgid "BlobViewer|View on %{environmentName}"
-msgstr ""
+msgstr "在 %{environmentName} 查看"
msgid "Block user"
msgstr "å±è”½ç”¨æˆ·"
@@ -6118,13 +6164,13 @@ msgid "By default, all projects and groups will use the global notifications set
msgstr "默认情况下,所有项目和群组将使用全局通知设置。"
msgid "By month"
-msgstr ""
+msgstr "按月"
msgid "By quarter"
-msgstr ""
+msgstr "按季度"
msgid "By week"
-msgstr ""
+msgstr "按周"
msgid "ByAuthor|by"
msgstr "作者:"
@@ -6191,10 +6237,13 @@ msgid "CICDAnalytics|Releases"
msgstr "å‘布"
msgid "CICDAnalytics|Shared Runners Usage"
+msgstr "共享 Runner 的使用情况"
+
+msgid "CICDAnalytics|Shared runner pipeline minute duration by month"
msgstr ""
msgid "CICDAnalytics|Shared runner usage"
-msgstr ""
+msgstr "共享 Runner 的使用情况"
msgid "CICDAnalytics|Shared runner usage is the total runtime of all jobs that ran on shared runners"
msgstr ""
@@ -6203,7 +6252,7 @@ msgid "CICDAnalytics|Something went wrong while fetching release statistics"
msgstr "获å–å‘布统计信æ¯æ—¶å‡ºçŽ°é”™è¯¯"
msgid "CICDAnalytics|What is shared runner usage?"
-msgstr ""
+msgstr "什么是共享 Runner 的使用情况?"
msgid "CICD|Add a %{base_domain_link_start}base domain%{link_end} to your %{kubernetes_cluster_link_start}Kubernetes cluster%{link_end} for your deployment strategy to work."
msgstr "请将%{base_domain_link_start}基础域å%{link_end}添加到%{kubernetes_cluster_link_start}Kubernetes集群%{link_end},æ‰èƒ½ä½¿æ‚¨çš„部署策略正常工作。"
@@ -6334,6 +6383,9 @@ msgstr "å¯ä»¥åœ¨æ¯ä¸ªé¡¹ç›®ä¸­è¦†ç›–。"
msgid "Can create groups:"
msgstr "å¯ä»¥åˆ›å»ºç¾¤ç»„:"
+msgid "Can not delete primary training"
+msgstr ""
+
msgid "Can't apply as the source branch was deleted."
msgstr "由于æºåˆ†æ”¯å·²åˆ é™¤ï¼Œå› æ­¤æ— æ³•åº”用。"
@@ -6440,7 +6492,7 @@ msgid "Cannot be merged automatically"
msgstr "无法自动åˆå¹¶"
msgid "Cannot create the abuse report. The reported user was invalid. Please try again or contact support."
-msgstr ""
+msgstr "无法创建滥用报告。报告的用户无效。请é‡è¯•æˆ–è”系支æŒäººå‘˜ã€‚"
msgid "Cannot create the abuse report. The user has been deleted."
msgstr "无法创建滥用报告。用户已被删除。"
@@ -6667,9 +6719,6 @@ msgstr "标题更改尚未ä¿å­˜"
msgid "Changing any setting here requires an application restart"
msgstr "更改此处的任何设置都需è¦é‡æ–°å¯åŠ¨åº”用程åº"
-msgid "Changing group URL can have unintended side effects."
-msgstr "更改群组URLå¯èƒ½ä¼šæœ‰éžé¢„期的副作用。"
-
msgid "Charts can't be displayed as the request for data has timed out. %{documentationLink}"
msgstr "无法显示图表,因为数æ®è¯·æ±‚已超时。 %{documentationLink}"
@@ -6757,9 +6806,6 @@ msgstr "检查批准状æ€"
msgid "Checking branch availability..."
msgstr "正在检查分支的å¯ç”¨æ€§..."
-msgid "Checking group URL availability..."
-msgstr "正在检查群组URL是å¦å¯ç”¨..."
-
msgid "Checking group path availability..."
msgstr "正在检查群组路径是å¦å¯ç”¨..."
@@ -6820,7 +6866,7 @@ msgid "Checkout|(x%{quantity})"
msgstr "(x%{quantity})"
msgid "Checkout|An unknown error has occurred. Please try again by refreshing this page."
-msgstr ""
+msgstr "出现未知错误。请刷新此页é¢å†è¯•ã€‚"
msgid "Checkout|Billing address"
msgstr "å¸å•åœ°å€"
@@ -7000,7 +7046,7 @@ msgid "Child"
msgstr "å­çº§"
msgid "Child epic"
-msgstr ""
+msgstr "å­å²è¯—"
msgid "Child epic does not exist."
msgstr "å­å²è¯—ä¸å­˜åœ¨ã€‚"
@@ -7251,6 +7297,9 @@ msgstr "清除å¥åº·çŠ¶æ€"
msgid "Clear recent searches"
msgstr "清除最近的æœç´¢"
+msgid "Clear repository checks"
+msgstr ""
+
msgid "Clear search"
msgstr "清除æœç´¢"
@@ -7383,9 +7432,6 @@ msgstr "关闭于%{epicTimeagoDate}"
msgid "Closed MRs"
msgstr "已关闭的åˆå¹¶è¯·æ±‚"
-msgid "Closed epics"
-msgstr "已关闭å²è¯—"
-
msgid "Closed issues"
msgstr "已关闭议题"
@@ -7399,10 +7445,10 @@ msgid "Closes this %{quick_action_target}."
msgstr "关闭此%{quick_action_target}."
msgid "Cloud Run"
-msgstr ""
+msgstr "Cloud Run"
msgid "Cloud Storage"
-msgstr ""
+msgstr "云存储"
msgid "Cluster"
msgstr "集群"
@@ -7422,13 +7468,13 @@ msgstr "Stages::ClusterEndpointInserter需è¦é›†ç¾¤"
msgid "Cluster level"
msgstr "集群级别"
-msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
-msgstr "Stages::ClusterEndpointInserter需è¦é›†ç¾¤ç±»åž‹"
+msgid "Cluster type must be specified for Stages::ClusterEndpointInserter"
+msgstr ""
msgid "ClusterAgents|%{name} successfully deleted"
msgstr "%{name} å·²æˆåŠŸåˆ é™¤"
-msgid "ClusterAgents|%{number} of %{total} Agents"
+msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
@@ -7470,11 +7516,20 @@ msgstr "代ç†å¯èƒ½æ— æ³•è¿žæŽ¥åˆ° GitLab"
msgid "ClusterAgents|Agent never connected to GitLab"
msgstr "代ç†ä»Žæœªè¿žæŽ¥åˆ° GitLab"
+msgid "ClusterAgents|Agent version mismatch"
+msgstr ""
+
+msgid "ClusterAgents|Agent version mismatch and update"
+msgstr ""
+
+msgid "ClusterAgents|Agent version update required"
+msgstr ""
+
msgid "ClusterAgents|All"
msgstr "全部"
msgid "ClusterAgents|An error occurred while loading your Agents"
-msgstr ""
+msgstr "加载您的代ç†æ—¶å‡ºé”™ã€‚"
msgid "ClusterAgents|An error occurred while loading your agent"
msgstr "加载代ç†æ—¶å‡ºé”™"
@@ -7494,8 +7549,8 @@ msgstr "è¯ä¹¦"
msgid "ClusterAgents|Configuration"
msgstr "é…ç½®"
-msgid "ClusterAgents|Connect a cluster through the Agent"
-msgstr "通过代ç†è¿žæŽ¥é›†ç¾¤"
+msgid "ClusterAgents|Connect a cluster through an agent"
+msgstr ""
msgid "ClusterAgents|Connect existing cluster"
msgstr "连接现有集群"
@@ -7503,14 +7558,14 @@ msgstr "连接现有集群"
msgid "ClusterAgents|Connect with a certificate"
msgstr "使用è¯ä¹¦è¿žæŽ¥"
-msgid "ClusterAgents|Connect with agent"
+msgid "ClusterAgents|Connect with an agent"
msgstr ""
msgid "ClusterAgents|Connect with the GitLab Agent"
msgstr "与 GitLab 代ç†è¿žæŽ¥"
-msgid "ClusterAgents|Connect your cluster through the Agent"
-msgstr "通过代ç†è¿žæŽ¥æ‚¨çš„集群"
+msgid "ClusterAgents|Connect your cluster through an agent"
+msgstr ""
msgid "ClusterAgents|Connected"
msgstr "已连接"
@@ -7561,7 +7616,7 @@ msgid "ClusterAgents|GitLab Agent for Kubernetes"
msgstr "适用于 Kubernetes çš„ GitLab 代ç†"
msgid "ClusterAgents|Give feedback"
-msgstr ""
+msgstr "æä¾›å馈"
msgid "ClusterAgents|Go to the repository files"
msgstr "转到仓库文件"
@@ -7569,7 +7624,10 @@ msgstr "转到仓库文件"
msgid "ClusterAgents|How to register an agent?"
msgstr "如何注册代ç†ï¼Ÿ"
-msgid "ClusterAgents|Install new Agent"
+msgid "ClusterAgents|How to update an agent?"
+msgstr ""
+
+msgid "ClusterAgents|Install a new agent"
msgstr ""
msgid "ClusterAgents|Last connected %{timeAgo}."
@@ -7596,7 +7654,7 @@ msgstr "从ä¸"
msgid "ClusterAgents|Never connected"
msgstr "从未连接"
-msgid "ClusterAgents|No Agents"
+msgid "ClusterAgents|No agents"
msgstr ""
msgid "ClusterAgents|No clusters connected through cluster certificates"
@@ -7624,16 +7682,16 @@ msgid "ClusterAgents|Registration token"
msgstr "注册令牌"
msgid "ClusterAgents|Requires a Maintainer or greater role to delete agents"
-msgstr ""
+msgstr "需è¦æœ‰è‡³å°‘维护者级别的æƒé™ï¼Œæ‰å¯åˆ é™¤ä»£ç†ã€‚"
msgid "ClusterAgents|Requires a Maintainer or greater role to install new agents"
-msgstr ""
+msgstr "需è¦æœ‰è‡³å°‘维护者级别的æƒé™ï¼Œæ‰å¯å®‰è£…新的代ç†ã€‚"
msgid "ClusterAgents|Requires a Maintainer or greater role to perform these actions"
-msgstr ""
+msgstr "需è¦æœ‰è‡³å°‘维护者级别的æƒé™ï¼Œæ‰å¯æ‰§è¡Œè¿™äº›æ“作。"
msgid "ClusterAgents|Requires a maintainer or greater role to connect existing clusters"
-msgstr ""
+msgstr "需è¦æœ‰è‡³å°‘维护者级别的æƒé™ï¼Œæ‰å¯è¿žæŽ¥çŽ°æœ‰é›†ç¾¤ã€‚"
msgid "ClusterAgents|Security"
msgstr "安全"
@@ -7648,7 +7706,7 @@ msgid "ClusterAgents|Select an agent to register with GitLab"
msgstr "选择è¦æ³¨å†Œåˆ° GitLab 的代ç†"
msgid "ClusterAgents|Tell us what you think"
-msgstr ""
+msgstr "告诉我们您的想法"
msgid "ClusterAgents|The GitLab Agent provides an increased level of security when connecting Kubernetes clusters to GitLab. %{linkStart}Learn more about the GitLab Agent.%{linkEnd}"
msgstr "当将 Kubernetes 集群连接到 GitLab 时,GitLab 代ç†æ供更高级别的安全性。 %{linkStart}了解有关 GitLab 代ç†çš„更多信æ¯ã€‚%{linkEnd}"
@@ -7656,6 +7714,9 @@ msgstr "当将 Kubernetes 集群连接到 GitLab 时,GitLab 代ç†æ供更高
msgid "ClusterAgents|The agent has not been connected in a long time. There might be a connectivity issue. Last contact was %{timeAgo}."
msgstr "代ç†é•¿æ—¶é—´æœªè¿žæŽ¥ï¼Œå¯èƒ½æœ‰è¿žæŽ¥é—®é¢˜ï¼Œæœ€åŽè¿žæŽ¥æ—¶é—´æ˜¯ %{timeAgo}。"
+msgid "ClusterAgents|The agent version do not match each other across your cluster's pods. This can happen when a new agent version was just deployed and Kubernetes is shutting down the old pods."
+msgstr ""
+
msgid "ClusterAgents|The recommended installation method includes the token. If you want to follow the advanced installation method provided in the docs, make sure you save the token value before you close this window."
msgstr "推è的安装方法包括令牌, 如果您想éµå¾ªæ–‡æ¡£ä¸­æ供的高级安装方法,请确ä¿æ‚¨åœ¨å…³é—­æ­¤çª—å£ä¹‹å‰ä¿å­˜ä»¤ç‰Œå€¼ã€‚"
@@ -7673,7 +7734,7 @@ msgid "ClusterAgents|To delete the agent, type %{name} to confirm:"
msgstr "è¦åˆ é™¤ä»£ç†ï¼Œè¯·è¾“å…¥ %{name} 进行确认:"
msgid "ClusterAgents|To install a new agent, first add the agent's configuration file to this repository. %{linkStart}Learn more about installing GitLab Agent.%{linkEnd}"
-msgstr ""
+msgstr "如果è¦å®‰è£…新的代ç†ï¼Œé¦–先需è¦å‘此仓库添加此代ç†çš„é…置文件。%{linkStart}了解更多关于安装 GitLab Agent çš„ä¿¡æ¯ã€‚%{linkEnd}"
msgid "ClusterAgents|Token created by %{userName}"
msgstr "由 %{userName} 创建的令牌"
@@ -7691,7 +7752,7 @@ msgid "ClusterAgents|View all %{number} clusters"
msgstr "查看所有 %{number} 个集群"
msgid "ClusterAgents|We would love to learn more about your experience with the GitLab Agent."
-msgstr ""
+msgstr "我们想è¦äº†è§£ä½ å¯¹ GitLab Agent 的想法。"
msgid "ClusterAgents|What is GitLab Agent activity?"
msgstr "什么是 GitLab 代ç†åŠ¨æ€ï¼Ÿ"
@@ -7702,6 +7763,9 @@ msgstr "关闭此窗å£åŽï¼Œæ‚¨æ— æ³•å†çœ‹åˆ°æ­¤ä»¤ç‰Œã€‚"
msgid "ClusterAgents|You will need to create a token to connect to your agent"
msgstr "您需è¦åˆ›å»ºä¸€ä¸ªä»¤ç‰Œæ‰èƒ½è¿žæŽ¥åˆ°æ‚¨çš„代ç†"
+msgid "ClusterAgents|Your agent version is out of sync with your GitLab version (v%{version}), which might cause compatibility problems. Update the agent installed on your cluster to the most recent version."
+msgstr ""
+
msgid "ClusterAgents|Your instance doesn't have the %{linkStart}GitLab Agent Server (KAS)%{linkEnd} set up. Ask a GitLab Administrator to install it."
msgstr "您的实例没有设置 %{linkStart}GitLab 代ç†æœåŠ¡å™¨ (KAS)%{linkEnd} 。è¦æ±‚ GitLab 管ç†å‘˜å®‰è£…它。"
@@ -8578,9 +8642,6 @@ msgstr "ComboSearch未定义"
msgid "Comma-separated list of email addresses."
msgstr "逗å·åˆ†éš”的电å­é‚®ä»¶åœ°å€åˆ—表。"
-msgid "Comma-separated list of users allowed to exceed the rate limit."
-msgstr "å…许超过速率é™åˆ¶çš„以逗å·åˆ†éš”的用户列表。"
-
msgid "Comma-separated, e.g. '1.1.1.1, 2.2.2.0/24'"
msgstr "以逗å·åˆ†éš”,例如 '1.1.1, 2.2.2.0/24'"
@@ -8643,7 +8704,7 @@ msgid "Commit Message"
msgstr "æ交消æ¯"
msgid "Commit SHA"
-msgstr ""
+msgstr "æ交 SHA"
msgid "Commit changes"
msgstr "æ交更改"
@@ -8895,7 +8956,7 @@ msgid "ComplianceReport|Less than 2 approvers"
msgstr "少于 2 个核准人"
msgid "ComplianceReport|No violations found"
-msgstr ""
+msgstr "未å‘现è¿è§„行为"
msgid "Component"
msgstr "组件"
@@ -8906,6 +8967,12 @@ msgstr "置信度"
msgid "Confidential"
msgstr "ç§å¯†"
+msgid "Confidential issue"
+msgstr ""
+
+msgid "Confidential note"
+msgstr ""
+
msgid "Confidentiality"
msgstr "ç§å¯†æ€§"
@@ -8939,6 +9006,9 @@ msgstr "使用 GitLab 托管模æ¿åœ¨ `.gitlab-ci.yml` 中é…ç½®ä¾èµ–扫æ。æ
msgid "Configure Dependency Scanning in `.gitlab-ci.yml`, creating this file if it does not already exist"
msgstr "在`.gitlab-ci.yml`中é…ç½®ä¾èµ–扫æ,如果该文件ä¸å­˜åœ¨åˆ™åˆ›å»ºè¯¥æ–‡ä»¶"
+msgid "Configure GitLab"
+msgstr ""
+
msgid "Configure GitLab runners to start using the Web Terminal. %{helpStart}Learn more.%{helpEnd}"
msgstr "é…ç½® GitLab Runner 以开始使用Web终端。 %{helpStart}了解更多。%{helpEnd}"
@@ -8979,12 +9049,21 @@ msgid "Configure a %{codeStart}.gitlab-webide.yml%{codeEnd} file in the %{codeSt
msgstr "在%{codeStart}.gitlab%{codeEnd}目录中é…ç½®%{codeStart}gitlab-webide.yml%{codeEnd}文件以开始使用Web终端。 %{helpStart}了解更多。%{helpEnd}"
msgid "Configure advanced permissions, Large File Storage, two-factor authentication, and customer relations settings."
-msgstr ""
+msgstr "调整高级æƒé™ã€å¤§æ–‡ä»¶å­˜å‚¨ã€åŒé‡è®¤è¯å’Œå®¢æˆ·å…³ç³»è®¾ç½®ã€‚"
msgid "Configure existing installation"
msgstr "é…置现有安装"
msgid "Configure pipelines to deploy web apps, backend services, APIs and static resources to Google Cloud"
+msgstr "é…ç½®æµæ°´çº¿ï¼Œå°†ç½‘络应用ã€åŽç«¯æœåŠ¡ã€API å’Œé™æ€èµ„æºéƒ¨ç½²åˆ° Google Cloud"
+
+msgid "Configure region"
+msgstr ""
+
+msgid "Configure region for environment"
+msgstr ""
+
+msgid "Configure regions"
msgstr ""
msgid "Configure repository mirroring."
@@ -9015,16 +9094,19 @@ msgid "Configure the way a user creates a new account."
msgstr "é…置用户创建新å¸æˆ·çš„æ–¹å¼ã€‚"
msgid "Configure via Merge Request"
-msgstr ""
+msgstr "通过åˆå¹¶è¯·æ±‚é…ç½®"
msgid "Configure which lists are shown for anyone who visits this board"
msgstr "é…置显示给任何访问此看æ¿çš„人的列表"
+msgid "Configure your environments to be deployed to specific geographical regions"
+msgstr ""
+
msgid "Confirm"
msgstr "确认"
msgid "Confirm approval"
-msgstr ""
+msgstr "确认批准"
msgid "Confirm new password"
msgstr "确认新密ç "
@@ -9582,7 +9664,7 @@ msgid "Control how the GitLab Package Registry functions."
msgstr "控制 GitLab 软件包仓库是如何è¿ä½œçš„。"
msgid "Control whether to display customer experience improvement content and third-party offers in GitLab."
-msgstr ""
+msgstr "控制是å¦åœ¨ GitLab 中显示客户体验改进内容和第三方优惠。"
msgid "Control which projects can be accessed by API requests authenticated with this project's CI_JOB_TOKEN CI/CD variable. It is a security risk to disable this feature, because unauthorized projects might attempt to retrieve an active token and access the API."
msgstr "控制使用此项目的 CI_JOB_TOKEN CI/CD å˜é‡è¿›è¡Œèº«ä»½éªŒè¯çš„ API 请求å¯ä»¥è®¿é—®å“ªäº›é¡¹ç›®ã€‚ç¦ç”¨æ­¤åŠŸèƒ½å­˜åœ¨å®‰å…¨é£Žé™©ï¼Œå› ä¸ºæœªç»æŽˆæƒçš„项目å¯èƒ½ä¼šå°è¯•æ£€ç´¢æ´»åŠ¨ä»¤ç‰Œå¹¶è®¿é—® API。"
@@ -9719,26 +9801,26 @@ msgstr "确定è¦åˆ é™¤è¯­æ–™åº“å—?"
msgid "CorpusManagement|Actions"
msgstr "动作"
-msgid "CorpusManagement|Corpus are used in fuzz testing as mutation source to Improve future testing."
-msgstr "语料库在模糊测试中用作å˜å¼‚æºä»¥æ”¹è¿›æœªæ¥çš„测试。"
-
msgid "CorpusManagement|Corpus file"
+msgstr "语料库文件"
+
+msgid "CorpusManagement|Corpus files are used in coverage-guided fuzz testing as seed inputs to improve testing."
msgstr ""
msgid "CorpusManagement|Corpus files must be in *.zip format. Maximum 5 GB"
-msgstr ""
+msgstr "语料库文件必须以 *.zip æ ¼å¼ä¸Šä¼ ï¼ˆæœ€å¤§ 5 GB)"
msgid "CorpusManagement|Corpus name"
msgstr "语料库å称"
msgid "CorpusManagement|Currently, there are no uploaded or generated corpuses."
-msgstr ""
+msgstr "ç›®å‰æ²¡æœ‰å·²ä¸Šä¼ æˆ–者自动生æˆçš„语料库。"
msgid "CorpusManagement|File too large, Maximum 5 GB"
-msgstr ""
+msgstr "文件过大(最大 5GB)"
msgid "CorpusManagement|Filename can contain only lowercase letters (a-z), uppercase letter (A-Z), numbers (0-9), dots (.), hyphens (-), or underscores (_)."
-msgstr ""
+msgstr "文件ååªèƒ½åŒ…å«å¤§å†™ï¼ˆA-Z)和å°å†™ï¼ˆa-z)英文字æ¯ã€æ•°å­—(0-9)ã€ç‚¹å·ï¼ˆ.)ã€æ¨ªæ ï¼ˆ-)或下划线(_)。"
msgid "CorpusManagement|Fuzz testing corpus management"
msgstr "模糊测试语料库管ç†"
@@ -9776,6 +9858,9 @@ msgstr "无法将管ç†å‘˜æ·»åŠ ä¸ºæˆå‘˜"
msgid "Could not apply %{name} command."
msgstr "无法应用 %{name} 命令。"
+msgid "Could not apply %{name} command. %{message}."
+msgstr ""
+
msgid "Could not authorize chat nickname. Try again!"
msgstr "无法授æƒèŠå¤©æ˜µç§°ã€‚å†è¯•ä¸€æ¬¡ï¼"
@@ -9825,7 +9910,7 @@ msgid "Could not fetch policy because existing policy YAML is invalid"
msgstr "无法获å–策略,因为现有的策略 YAML 无效"
msgid "Could not fetch training providers. Please refresh the page, or try again later."
-msgstr ""
+msgstr "无法获å–培训æ供者。请刷新此页,或ç¨åŽå†è¯•ã€‚"
msgid "Could not find design."
msgstr "未找到设计."
@@ -9855,7 +9940,7 @@ msgid "Could not restore the group"
msgstr "无法还原群组"
msgid "Could not revoke access token %{access_token_name}."
-msgstr ""
+msgstr "无法撤消访问令牌 %{access_token_name}。"
msgid "Could not revoke impersonation token %{token_name}."
msgstr "无法撤消身份模拟令牌 %{token_name}。"
@@ -9864,7 +9949,7 @@ msgid "Could not revoke personal access token %{personal_access_token_name}."
msgstr "无法撤消个人访问令牌 %{personal_access_token_name}。"
msgid "Could not save configuration. Please refresh the page, or try again later."
-msgstr ""
+msgstr "无法ä¿å­˜é…置。请刷新此页,或ç¨åŽå†è¯•ã€‚"
msgid "Could not save group ID"
msgstr "无法ä¿å­˜ç¾¤ç»„ID"
@@ -9926,6 +10011,9 @@ msgstr "请先创建一个GitLabå¸æˆ·ï¼Œç„¶åŽå°†å…¶è¿žæŽ¥åˆ°æ‚¨çš„ %{label} å¸
msgid "Create a Mattermost team for this group"
msgstr "为这个群组创建一个Mattermost团队"
+msgid "Create a group"
+msgstr ""
+
msgid "Create a merge request"
msgstr "创建一个åˆå¹¶ç”³è¯·"
@@ -9950,6 +10038,9 @@ msgstr "创建一个新仓库"
msgid "Create a personal access token on your account to pull or push via %{protocol}."
msgstr "在å¸æˆ·ä¸Šåˆ›å»ºä¸ªäººè®¿é—®ä»¤ç‰Œï¼Œä»¥é€šè¿‡ %{protocol} æ¥æ‹‰å–或推é€ã€‚"
+msgid "Create a project"
+msgstr ""
+
msgid "Create an account using:"
msgstr "使用以下方å¼åˆ›å»ºå¸æˆ·ï¼š"
@@ -10008,7 +10099,7 @@ msgid "Create iteration"
msgstr "创建迭代"
msgid "Create label"
-msgstr ""
+msgstr "创建标记"
msgid "Create list"
msgstr "创建列表"
@@ -10269,7 +10360,7 @@ msgid "Created by:"
msgstr "创建人:"
msgid "Created compliance violations if any were found"
-msgstr ""
+msgstr "如果å‘现,则创建è¿è§„行为"
msgid "Created date"
msgstr "创建日期"
@@ -10313,6 +10404,9 @@ msgstr "正在使用PrometheusæœåŠ¡å™¨ä¸­çš„æ•°æ®åˆ›å»ºå›¾è¡¨ã€‚如果这需è¦
msgid "Creation date"
msgstr "创建日期"
+msgid "Creator"
+msgstr ""
+
msgid "Credentials"
msgstr "凭æ®"
@@ -10325,9 +10419,15 @@ msgstr "找ä¸åˆ°å‡­è¯"
msgid "CredentialsInventory|Personal Access Tokens"
msgstr "个人访问令牌"
+msgid "CredentialsInventory|Project Access Tokens"
+msgstr ""
+
msgid "CredentialsInventory|SSH Keys"
msgstr "SSH密钥"
+msgid "Credit card required to be on file in order to create a pipeline"
+msgstr ""
+
msgid "Credit card:"
msgstr "信用å¡ï¼š"
@@ -10506,14 +10606,11 @@ msgid "Customer Relations Organizations"
msgstr "客户关系组织"
msgid "Customer experience improvement and third-party offers"
-msgstr ""
+msgstr "客户体验改善和第三方优惠"
msgid "Customer relations"
msgstr "客户关系"
-msgid "Customizable by an administrator."
-msgstr "å¯ç”±ç®¡ç†å‘˜è‡ªå®šä¹‰ã€‚"
-
msgid "Customizable by owners."
msgstr "由所有者自定义。"
@@ -10643,30 +10740,18 @@ msgstr "应该属于一个群组"
msgid "CycleAnalytics|%{selectedLabelsCount} selected (%{maxLabels} max)"
msgstr "%{selectedLabelsCount}项已选择(最大%{maxLabels})"
-msgid "CycleAnalytics|%{stageCount} stages selected"
-msgstr "已选择%{stageCount}个阶段"
-
-msgid "CycleAnalytics|All stages"
-msgstr "所有阶段"
-
-msgid "CycleAnalytics|Average days to completion"
-msgstr "å¹³å‡å®Œæˆå¤©æ•°"
+msgid "CycleAnalytics|Average time to completion"
+msgstr ""
msgid "CycleAnalytics|Date"
msgstr "日期"
-msgid "CycleAnalytics|Days to completion"
-msgstr "完æˆæ‰€éœ€å¤©æ•°"
-
msgid "CycleAnalytics|Display chart filters"
msgstr "显示图表筛选器"
msgid "CycleAnalytics|Lead Time for Changes"
msgstr "å˜æ›´çš„交付时间"
-msgid "CycleAnalytics|No stages selected"
-msgstr "未选择阶段"
-
msgid "CycleAnalytics|Number of tasks"
msgstr "任务数"
@@ -10693,18 +10778,30 @@ msgstr "显示群组“%{groupName}â€å’Œ%{selectedProjectCount}个项目从%{cr
msgid "CycleAnalytics|Showing data for group '%{groupName}' from %{createdAfter} to %{createdBefore}"
msgstr "显示群组“%{groupName}â€ä»Ž%{createdAfter}到%{createdBefore}çš„æ•°æ®"
-msgid "CycleAnalytics|Stages"
-msgstr "阶段"
+msgid "CycleAnalytics|Stage time: %{title}"
+msgstr ""
msgid "CycleAnalytics|Tasks by type"
msgstr "按类型的任务"
-msgid "CycleAnalytics|The average time spent in the selected stage for the items that were completed on each date. Data limited to the last 500 items."
-msgstr "æ¯ä¸ªæ—¥æœŸå®Œæˆçš„项目在选定阶段花费的平å‡æ—¶é—´ã€‚æ•°æ®ä»…é™äºŽæœ€è¿‘ 500 项。"
+msgid "CycleAnalytics|The average time items spent in this stage. Data limited to items completed within this date range."
+msgstr ""
msgid "CycleAnalytics|The given date range is larger than 180 days"
msgstr "给定的日期范围大于180天"
+msgid "CycleAnalytics|The total time items spent across each value stream stage. Data limited to items completed within this date range."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Stage time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Total time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|Total time"
+msgstr ""
+
msgid "CycleAnalytics|Type of work"
msgstr "工作类型"
@@ -10717,9 +10814,6 @@ msgstr "ä¸é€‚用于给定的开始事件"
msgid "CycleAnalytics|project dropdown filter"
msgstr "项目下拉列表筛选器"
-msgid "CycleAnalytics|stage dropdown"
-msgstr "阶段下拉列表"
-
msgid "DAG visualization requires at least 3 dependent jobs."
msgstr "DAGå¯è§†åŒ–至少需è¦3个ä¾èµ–作业。"
@@ -10739,7 +10833,7 @@ msgid "DORA4Metrics|%{startDate} - %{endDate}"
msgstr "%{startDate} - %{endDate}"
msgid "DORA4Metrics|Average (last %{days}d)"
-msgstr ""
+msgstr "å¹³å‡ï¼ˆæœ€è¿‘%{days}天)"
msgid "DORA4Metrics|Date"
msgstr "日期"
@@ -10754,7 +10848,7 @@ msgid "DORA4Metrics|Lead time for changes"
msgstr ""
msgid "DORA4Metrics|Median (last %{days}d)"
-msgstr ""
+msgstr "中值(最近%{days}天)"
msgid "DORA4Metrics|No merge requests were deployed during this period"
msgstr "在此期间没有部署åˆå¹¶è¯·æ±‚"
@@ -10819,11 +10913,17 @@ msgstr "被动扫æ监控å‘é€åˆ°ç›®æ ‡çš„所有HTTP消æ¯(请求和å“应)。
msgid "DastProfiles|AJAX spider"
msgstr "AJAX爬虫"
+msgid "DastProfiles|API"
+msgstr ""
+
+msgid "DastProfiles|API endpoint URL"
+msgstr ""
+
msgid "DastProfiles|Active"
msgstr "主动"
-msgid "DastProfiles|Additional request headers (Optional)"
-msgstr "附加请求报头 (å¯é€‰)"
+msgid "DastProfiles|Additional request headers (optional)"
+msgstr ""
msgid "DastProfiles|Are you sure you want to delete this profile?"
msgstr "您确定è¦åˆ é™¤æ­¤é…ç½®å—?"
@@ -10837,6 +10937,9 @@ msgstr "身份验è¯ç½‘å€"
msgid "DastProfiles|Branch missing"
msgstr "缺少分支"
+msgid "DastProfiles|Choose a scan method"
+msgstr ""
+
msgid "DastProfiles|Could not create the scanner profile. Please try again."
msgstr "无法创建扫æ工具é…置。请é‡è¯•ã€‚"
@@ -10906,8 +11009,14 @@ msgstr "错误详细信æ¯"
msgid "DastProfiles|Excluded URLs"
msgstr "排除的URL"
-msgid "DastProfiles|Excluded URLs (Optional)"
-msgstr "排除的 URLs (å¯é€‰)"
+msgid "DastProfiles|Excluded URLs (optional)"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths (optional)"
+msgstr ""
msgid "DastProfiles|Hide debug messages"
msgstr "éšè—调试消æ¯"
@@ -10963,9 +11072,6 @@ msgstr "请求 header å称和值。Headers 会添加到 DAST å‘出的æ¯ä¸ªè¯
msgid "DastProfiles|Request headers"
msgstr "请求报头"
-msgid "DastProfiles|Rest API"
-msgstr "Rest API"
-
msgid "DastProfiles|Run the AJAX spider, in addition to the traditional spider, to crawl the target site."
msgstr "除了传统的爬虫之外,å¯ä»¥è¿è¡ŒAJAX爬虫æ¥é历目标站点。"
@@ -10975,6 +11081,9 @@ msgstr "将目标站点和扫æ设置的常用设定ä¿å­˜ä¸ºé…置。使用这
msgid "DastProfiles|Save profile"
msgstr "ä¿å­˜é…ç½®"
+msgid "DastProfiles|Scan method"
+msgstr ""
+
msgid "DastProfiles|Scan mode"
msgstr "扫æ模å¼"
@@ -11053,12 +11162,24 @@ msgstr "验è¯çŠ¶æ€"
msgid "DastProfiles|Website"
msgstr "网站"
+msgid "DastProfiles|What does each method do?"
+msgstr ""
+
msgid "DastProfiles|You can either choose a passive scan or validate the target site from the site profile management page. %{docsLinkStart}Learn more about site validation.%{docsLinkEnd}"
msgstr "您å¯ä»¥é€‰æ‹©è¢«åŠ¨æ‰«æ或从站点é…置文件管ç†é¡µé¢éªŒè¯ç›®æ ‡ç«™ç‚¹ã€‚ %{docsLinkStart}了解有关站点验è¯çš„更多信æ¯ã€‚%{docsLinkEnd}"
msgid "DastProfiles|You cannot run an active scan against an unvalidated site."
msgstr "ä¸èƒ½å¯¹æœªç»éªŒè¯çš„站点è¿è¡Œä¸»åŠ¨æ‰«æ。"
+msgid "DastProfiles|folder/dast_example.har or https://example.com/dast_example.har"
+msgstr ""
+
+msgid "DastProfiles|folder/example.postman_collection.json or https://example.com/"
+msgstr ""
+
+msgid "DastProfiles|folder/openapi.json or https://example.com/openapi.json"
+msgstr ""
+
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr "å¤åˆ¶HTTP报头到剪贴æ¿"
@@ -11165,6 +11286,9 @@ msgstr "(高级)您的Datadog站点的完整URL"
msgid "DatadogIntegration|API URL"
msgstr "API URL"
+msgid "DatadogIntegration|Custom tags in Datadog. Enter one tag per line in the %{codeOpen}key:value%{codeClose} format. %{linkOpen}How do I use tags?%{linkClose}"
+msgstr ""
+
msgid "DatadogIntegration|Environment"
msgstr "环境"
@@ -11183,12 +11307,18 @@ msgstr "Service"
msgid "DatadogIntegration|Tag all data from this GitLab instance in Datadog. Useful when managing several self-managed deployments."
msgstr "在Datadog中,为æ¥è‡ªæ­¤GitLab实例的所有数æ®æ‰“标签。当管ç†å¤šä¸ªè‡ªåŠ©ç®¡ç†éƒ¨ç½²æ—¶å¾ˆæœ‰ç”¨ã€‚"
+msgid "DatadogIntegration|Tags"
+msgstr ""
+
msgid "DatadogIntegration|The Datadog site to send data to. To send data to the EU site, use %{codeOpen}datadoghq.eu%{codeClose}."
msgstr "è¦å‘å…¶å‘é€æ•°æ®çš„Datadog站点。è¦å°†æ•°æ®å‘é€åˆ°EU站点,请使用%{codeOpen}datadoghq.eu%{codeClose}。"
msgid "DatadogIntegration|Trace your GitLab pipelines with Datadog."
msgstr "使用Datadog跟踪您的GitLabæµæ°´çº¿ã€‚"
+msgid "DatadogIntegration|have an invalid format"
+msgstr ""
+
msgid "Datasource name not found"
msgstr "找ä¸åˆ°æ•°æ®æºå称"
@@ -11198,9 +11328,6 @@ msgstr "日期"
msgid "Date merged"
msgstr "åˆå¹¶æ—¥æœŸ"
-msgid "Date picker"
-msgstr "日期选择器"
-
msgid "Date range"
msgstr "日期范围"
@@ -11354,9 +11481,6 @@ msgstr "定义审核规则如何应用于åˆå¹¶è¯·æ±‚。"
msgid "Definition"
msgstr "定义"
-msgid "Delayed Project Deletion (%{adjourned_deletion})"
-msgstr "延迟项目删除(%{adjourned_deletion})"
-
msgid "DelayedJobs|Are you sure you want to run %{jobName} immediately? Otherwise this job will run automatically after its timer finishes."
msgstr "确定è¦ç«‹å³è¿è¡Œ%{jobName}å—?å¦åˆ™è¯¥ä½œä¸šå°†åœ¨è®¡æ—¶å™¨ç»“æŸåŽè‡ªåŠ¨è¿è¡Œã€‚"
@@ -11435,12 +11559,12 @@ msgstr "删除标记:%{labelName}"
msgid "Delete pipeline"
msgstr "删除æµæ°´çº¿"
+msgid "Delete pipeline schedule"
+msgstr ""
+
msgid "Delete project"
msgstr "删除项目"
-msgid "Delete project. Are you ABSOLUTELY SURE?"
-msgstr "删除项目。您ç»å¯¹ç¡®å®šå—?"
-
msgid "Delete row"
msgstr "删除行"
@@ -11468,6 +11592,9 @@ msgstr "删除此附件"
msgid "Delete this epic and all descendants?"
msgstr "删除此å²è¯—和所有下级?"
+msgid "Delete this project"
+msgstr ""
+
msgid "Delete user list"
msgstr "删除用户列表"
@@ -11697,7 +11824,7 @@ msgid "Deploy Keys"
msgstr "部署密钥"
msgid "Deploy container based web apps on Google managed clusters"
-msgstr ""
+msgstr "在 Google 托管的集群上部署基于容器的网络应用"
msgid "Deploy freezes"
msgstr "部署冻结"
@@ -11715,11 +11842,17 @@ msgid "Deploy progress not found. To see pods, ensure your environment matches %
msgstr "未找到部署进度。è¦æŸ¥çœ‹pod,请确ä¿æ‚¨çš„环境符åˆ%{linkStart}部署看æ¿æ¡ä»¶%{linkEnd}。"
msgid "Deploy static assets and resources to Google managed CDN"
-msgstr ""
+msgstr "å°†é™æ€èµ„产和资æºéƒ¨ç½²åˆ° Google 托管的 CDN"
msgid "Deploy to..."
msgstr "部署到 ..."
+msgid "DeployBoards|To see deployment progress for your environments, make sure you are deploying to %{codeStart}$KUBE_NAMESPACE%{codeEnd} and annotating with %{codeStart}app.gitlab.com/app=$CI_PROJECT_PATH_SLUG%{codeEnd} and %{codeStart}app.gitlab.com/env=$CI_ENVIRONMENT_SLUG%{codeEnd}."
+msgstr ""
+
+msgid "DeployBoard|Kubernetes Pods"
+msgstr ""
+
msgid "DeployFreeze|Add a freeze period to prevent unintended releases during a period of time for a given environment. You must update the deployment jobs in %{filename} according to the deploy freezes added here. %{freeze_period_link_start}Learn more.%{freeze_period_link_end}"
msgstr "添加冻结期以防止在给定环境的一段时间内æ„外å‘布。您必须根æ®æ­¤å¤„添加的部署冻结更新%{filename}的部署作业。%{freeze_period_link_start}了解更多。%{freeze_period_link_end}"
@@ -11804,9 +11937,6 @@ msgstr "åªè¯»æƒé™"
msgid "DeployTokens|Active Deploy Tokens (%{active_tokens})"
msgstr "å¯ç”¨éƒ¨ç½²ä»¤ç‰Œï¼ˆ%{active_tokens})"
-msgid "DeployTokens|Allows read and write access to registry images."
-msgstr "å…许对容器仓库镜åƒè¿›è¡Œè¯»å†™è®¿é—®ã€‚"
-
msgid "DeployTokens|Allows read and write access to the package registry."
msgstr "å…许对软件包仓库进行读写访问。"
@@ -11819,6 +11949,9 @@ msgstr "å…许对软件包仓库进行åªè¯»è®¿é—®ã€‚"
msgid "DeployTokens|Allows read-only access to the repository."
msgstr "å…许以åªè¯»æƒé™è®¿é—®é•œåƒä»“库。"
+msgid "DeployTokens|Allows write access to registry images."
+msgstr ""
+
msgid "DeployTokens|Copy deploy token"
msgstr "å¤åˆ¶éƒ¨ç½²ä»¤ç‰Œ"
@@ -11912,12 +12045,57 @@ msgstr "正在部署到"
msgid "Deploying to AWS is easy with GitLab"
msgstr "使用GitLabè½»æ¾éƒ¨ç½²åˆ° AWS"
+msgid "Deployment"
+msgstr ""
+
msgid "Deployment Frequency"
msgstr "部署频率"
+msgid "Deployment Target|Project deployment target (optional)"
+msgstr ""
+
+msgid "Deployment Target|Select the deployment target"
+msgstr ""
+
msgid "Deployment frequency"
msgstr "部署频率"
+msgid "DeploymentTarget|GitLab Pages"
+msgstr ""
+
+msgid "DeploymentTarget|Heroku"
+msgstr ""
+
+msgid "DeploymentTarget|Infrastructure provider (Terraform, Cloudformation, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Kubernetes (GKE, EKS, OpenShift, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Managed container runtime (Fargate, Cloud Run, DigitalOcean App)"
+msgstr ""
+
+msgid "DeploymentTarget|Mobile app store"
+msgstr ""
+
+msgid "DeploymentTarget|No deployment planned"
+msgstr ""
+
+msgid "DeploymentTarget|Other hosting service"
+msgstr ""
+
+msgid "DeploymentTarget|Registry (package or container)"
+msgstr ""
+
+msgid "DeploymentTarget|Self-managed container runtime (Podman, Docker Swarm, Docker Compose)"
+msgstr ""
+
+msgid "DeploymentTarget|Serverless backend (Lambda, Cloud functions)"
+msgstr ""
+
+msgid "DeploymentTarget|Virtual machine (for example, EC2)"
+msgstr ""
+
msgid "Deployments"
msgstr "部署"
@@ -11929,37 +12107,40 @@ msgid "Deployment|API"
msgstr "API"
msgid "Deployment|Cancelled"
-msgstr ""
+msgstr "å·²å–消"
msgid "Deployment|Created"
-msgstr ""
+msgstr "已创建"
msgid "Deployment|Deployment ID"
-msgstr ""
+msgstr "部署 ID"
msgid "Deployment|Failed"
-msgstr ""
+msgstr "失败"
msgid "Deployment|Latest Deployed"
-msgstr ""
+msgstr "最近一次部署"
msgid "Deployment|Running"
-msgstr ""
+msgstr "è¿è¡Œä¸­"
msgid "Deployment|Skipped"
-msgstr ""
+msgstr "已跳过"
msgid "Deployment|Success"
-msgstr ""
+msgstr "æˆåŠŸ"
msgid "Deployment|This deployment was created using the API"
msgstr "此部署使用API创建"
-msgid "Deployment|Waiting"
+msgid "Deployment|Triggerer"
msgstr ""
+msgid "Deployment|Waiting"
+msgstr "等待中"
+
msgid "Deployment|blocked"
-msgstr ""
+msgstr "已阻塞"
msgid "Deployment|canceled"
msgstr "å·²å–消"
@@ -11982,6 +12163,18 @@ msgstr "æˆåŠŸ"
msgid "Deprecated API rate limits"
msgstr "已弃用的 API 速率é™åˆ¶"
+msgid "Deprecations|Feature deprecation and removal"
+msgstr ""
+
+msgid "Deprecations|For information on a possible replacement %{epicStart} learn more about Opstrace %{epicEnd}."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7 and are %{epicStart} scheduled for removal %{epicEnd} in GitLab 15.0."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7, and are %{removal_link_start} scheduled for removal %{link_end} in GitLab 15.0. For information on a possible replacement, %{opstrace_link_start} learn more about Opstrace %{link_end}."
+msgstr ""
+
msgid "Deprioritize label"
msgstr "å–消优先标记"
@@ -12226,11 +12419,11 @@ msgstr "在åˆå¹¶è¯·æ±‚上至少有一次批准"
msgid "DevopsAdoption|At least one deploy"
msgstr "至少部署一次"
-msgid "DevopsAdoption|At least one issue opened"
-msgstr "至少开放了一个议题"
+msgid "DevopsAdoption|At least one issue created"
+msgstr ""
-msgid "DevopsAdoption|At least one merge request opened"
-msgstr "至少开放一个åˆå¹¶è¯·æ±‚"
+msgid "DevopsAdoption|At least one merge request created"
+msgstr ""
msgid "DevopsAdoption|At least one pipeline successfully run"
msgstr "至少有一æ¡æµæ°´çº¿è¿è¡ŒæˆåŠŸ"
@@ -12427,6 +12620,9 @@ msgstr "有 %{additions} 和 %{deletions}"
msgid "Direct member"
msgstr "直接æˆå‘˜"
+msgid "Direct members"
+msgstr ""
+
msgid "Direct non-authenticated users to this page."
msgstr "将未ç»èº«ä»½éªŒè¯çš„用户定å‘到此页é¢ã€‚"
@@ -12542,6 +12738,9 @@ msgid "Dismiss %d selected vulnerability as"
msgid_plural "Dismiss %d selected vulnerabilities as"
msgstr[0] "忽略%d个选定的æ¼æ´žï¼Œå°†å®ƒä»¬å½’类为"
+msgid "Dismiss Alert"
+msgstr ""
+
msgid "Dismiss merge request promotion"
msgstr "关闭åˆå¹¶è¯·æ±‚推è"
@@ -12569,9 +12768,15 @@ msgstr "在%{projectLink} 中的æµæ°´çº¿ %{pipelineLink}上忽略"
msgid "Display alerts from all configured monitoring tools."
msgstr "显示æ¥è‡ªæ‰€æœ‰é…置的监控工具的警报。"
+msgid "Display milestones"
+msgstr ""
+
msgid "Display name"
msgstr "显示å称"
+msgid "Display progress of child issues"
+msgstr ""
+
msgid "Display rendered file"
msgstr "显示渲染åŽæ–‡ä»¶"
@@ -12582,7 +12787,7 @@ msgid "Display time tracking in issues in total hours only."
msgstr "仅以总å°æ—¶æ•°æ˜¾ç¤ºè®®é¢˜ä¸­çš„时间跟踪。"
msgid "Do not display content for customer experience improvement and offers from third parties"
-msgstr ""
+msgstr "ä¸è¦æ˜¾ç¤ºç”¨äºŽæ”¹å–„客户体验的内容和æ¥è‡ªç¬¬ä¸‰æ–¹çš„优惠"
msgid "Do not force push over diverged refs. After the mirror is created, this setting can only be modified using the API. %{mirroring_docs_link_start}Learn more about this option%{link_closing_tag} and %{mirroring_api_docs_link_start}the API.%{link_closing_tag}"
msgstr "ä¸è¦å¼ºè¡ŒæŽ¨åŠ¨åˆ†æ­§çš„ref。创建镜åƒåŽï¼Œåªèƒ½ä½¿ç”¨ API 修改此设置。 %{mirroring_docs_link_start}了解有关此选项%{link_closing_tag} å’Œ %{mirroring_api_docs_link_start}API 的更多信æ¯ã€‚%{link_closing_tag}"
@@ -12677,6 +12882,9 @@ msgstr "下载导出"
msgid "Download image"
msgstr "下载图片"
+msgid "Download payload"
+msgstr ""
+
msgid "Download raw data (.csv)"
msgstr "ä¸‹è½½åŽŸå§‹æ•°æ® (.csv)"
@@ -12777,7 +12985,7 @@ msgid "Edit Deploy Key"
msgstr "编辑部署密钥"
msgid "Edit Geo Site"
-msgstr ""
+msgstr "编辑 Geo 站点"
msgid "Edit Group Hook"
msgstr "编辑群组钩å­"
@@ -12854,6 +13062,9 @@ msgstr "编辑 %{user_name} 的身份信æ¯"
msgid "Edit in Web IDE"
msgstr "在Web IDE中编辑"
+msgid "Edit in pipeline editor"
+msgstr ""
+
msgid "Edit in single-file editor"
msgstr "在å•æ–‡ä»¶ç¼–辑器中编辑"
@@ -12896,6 +13107,9 @@ msgstr "编辑Wiki页é¢"
msgid "Edit your most recent comment in a thread (from an empty textarea)"
msgstr "编辑你在最近主题中的评论(从空白文本区)"
+msgid "Edit, lint, and visualize your pipeline."
+msgstr ""
+
msgid "Edited"
msgstr "已编辑"
@@ -13023,7 +13237,7 @@ msgid "EmailError|We couldn't find the project. Please check if there's any typo
msgstr "我们找ä¸åˆ°è¯¥é¡¹ç›®ã€‚请检查是å¦æœ‰æ‹¼å†™é”™è¯¯ã€‚"
msgid "EmailError|We couldn't process your email because it is too large. Please create your issue or comment through the web interface."
-msgstr ""
+msgstr "因为您的电å­é‚®ä»¶è¿‡å¤§ï¼Œæˆ‘们无法处ç†ã€‚请通过界é¢åˆ›å»ºæ‚¨çš„议题或者评论。"
msgid "EmailError|You are not allowed to perform this action. If you believe this is in error, contact a staff member."
msgstr "ä¸å…许您执行此æ“作。如果您认为这是错误的,请è”系系统管ç†å‘˜ã€‚"
@@ -13212,7 +13426,7 @@ msgid "Enable kuromoji custom analyzer: Search"
msgstr "å¯ç”¨kuromoji自定义分æžå™¨ï¼šæœç´¢"
msgid "Enable logs collection"
-msgstr ""
+msgstr "å¯ç”¨æ—¥å¿—收集"
msgid "Enable maintenance mode"
msgstr "å¯ç”¨ç»´æŠ¤æ¨¡å¼"
@@ -13242,7 +13456,7 @@ msgid "Enable repository checks"
msgstr "å¯ç”¨ä»“库检查"
msgid "Enable security training"
-msgstr ""
+msgstr "å¯ç”¨å®‰å…¨åŸ¹è®­"
msgid "Enable security training to help your developers learn how to fix vulnerabilities. Developers can view security training from selected educational providers, relevant to the detected vulnerability."
msgstr ""
@@ -13337,6 +13551,9 @@ msgstr "强制执行åŒé‡è®¤è¯"
msgid "Enforce two-factor authentication for all user sign-ins."
msgstr "对所有用户登录强制执行åŒé‡è®¤è¯ã€‚"
+msgid "Enhance security by storing service account keys in secret managers - learn more about %{docLinkStart}secret management with GitLab%{docLinkEnd}"
+msgstr ""
+
msgid "Ensure connectivity is available from the GitLab server to the Prometheus server"
msgstr "ç¡®ä¿ä»ŽGitLabæœåŠ¡å™¨åˆ°PrometheusæœåŠ¡å™¨çš„连接"
@@ -13374,7 +13591,7 @@ msgid "Enter in your Phabricator Server URL and personal access token below"
msgstr "在下é¢è¾“入您的Phabricator Server URL和个人访问令牌"
msgid "Enter license key"
-msgstr ""
+msgstr "请输入许å¯è¯å¯†é’¥"
msgid "Enter merge request URLs"
msgstr "输入åˆå¹¶è¯·æ±‚网å€"
@@ -13397,6 +13614,9 @@ msgstr "输入 %{name} 标题"
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 following to confirm:"
+msgstr ""
+
msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr "输入您的应用程åºçš„å称,我们会返回唯一的%{type}。"
@@ -13651,7 +13871,7 @@ msgid "Environments|Stopping %{environmentName}"
msgstr "终止%{environmentName}"
msgid "Environments|There are no deployments for this environment yet. %{linkStart}Learn more about setting up deployments.%{linkEnd}"
-msgstr ""
+msgstr "尚无此环境的部署。%{linkStart}了解有关设置部署的更多信æ¯ã€‚%{linkEnd}"
msgid "Environments|There was an error fetching the logs. Please try again."
msgstr "获å–日志时出错。请é‡è¯•ã€‚"
@@ -13681,7 +13901,7 @@ msgid "Environments|protected"
msgstr "å—ä¿æŠ¤çš„"
msgid "Environment|Auto stop %{time}"
-msgstr ""
+msgstr "自动åœæ­¢ %{time}"
msgid "Epic"
msgstr "å²è¯—"
@@ -13926,9 +14146,6 @@ msgstr "æ›´æ–° %{issuableType} 状æ€æ—¶å‡ºé”™"
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 "å‘生错误。无法冻结被ç¦ç”¨çš„用户"
@@ -14064,6 +14281,9 @@ msgstr "在第%{line_number}行中å‘现错误: %{error_lines}。请检查这些
msgid "Errors:"
msgstr "错误:"
+msgid "Escalate this incident"
+msgstr ""
+
msgid "Escalation Policies"
msgstr "å‡çº§ç­–ç•¥"
@@ -14076,6 +14296,9 @@ msgstr "å‡çº§ç­–ç•¥ä¸èƒ½è¶…过 %{rule_count} 个规则"
msgid "Escalation policies must have at least one rule"
msgstr "å‡çº§ç­–略必须至少有一个规则"
+msgid "Escalation policy"
+msgstr ""
+
msgid "Escalation policy:"
msgstr "å‡çº§ç­–略:"
@@ -14326,6 +14549,9 @@ msgstr "现有项目将能够使用到期策略。如果正在使用外部容器
msgid "Existing sign in methods may be removed"
msgstr "现有的登录方法å¯èƒ½ä¼šè¢«åˆ é™¤"
+msgid "Exit."
+msgstr ""
+
msgid "Expand"
msgstr "展开"
@@ -14422,6 +14648,9 @@ msgstr "æµè§ˆé¡¹ç›®"
msgid "Explore public groups"
msgstr "æµè§ˆå…¬å¼€ç¾¤ç»„"
+msgid "Explore public projects"
+msgstr ""
+
msgid "Explore snippets"
msgstr "æµè§ˆä»£ç ç‰‡æ®µ"
@@ -14504,28 +14733,28 @@ msgid "ExternalAuthorization|Classification label to use when requesting authori
msgstr ""
msgid "ExternalAuthorization|Client authorization certificate"
-msgstr ""
+msgstr "客户端授æƒè¯ä¹¦"
msgid "ExternalAuthorization|Client authorization key"
-msgstr ""
+msgstr "客户端授æƒå¯†é’¥"
msgid "ExternalAuthorization|Client authorization key password (optional)"
-msgstr ""
+msgstr "客户端授æƒå¯†é’¥å¯†ç ï¼ˆå¯é€‰ï¼‰"
msgid "ExternalAuthorization|Default classification label"
-msgstr ""
+msgstr "默认分类标签"
msgid "ExternalAuthorization|Enable classification control using an external service"
-msgstr ""
+msgstr "使用外部æœåŠ¡å¯ç”¨åˆ†ç±»æŽ§åˆ¶"
msgid "ExternalAuthorization|External authorization"
-msgstr ""
+msgstr "外部授æƒ"
msgid "ExternalAuthorization|External authorization request timeout (seconds)"
-msgstr ""
+msgstr "外部授æƒè¯·æ±‚超时(秒)"
msgid "ExternalAuthorization|External classification policy authorization."
-msgstr ""
+msgstr "外部分类策略授æƒã€‚"
msgid "ExternalAuthorization|Passphrase required to decrypt the private key. Encrypted when stored."
msgstr ""
@@ -14537,7 +14766,7 @@ msgid "ExternalAuthorization|Private key of client authentication certificate. E
msgstr ""
msgid "ExternalAuthorization|Service URL"
-msgstr ""
+msgstr "æœåŠ¡ URL"
msgid "ExternalAuthorization|URL to which the projects make authorization requests. If the URL is blank, cross-project features are available and can still specify classification labels for projects."
msgstr ""
@@ -14546,7 +14775,7 @@ msgid "ExternalIssueIntegration|Not all data may be displayed here. To view more
msgstr "此处å¯èƒ½ä¸ä¼šæ˜¾ç¤ºæ‰€æœ‰æ•°æ®ï¼Œè¦æŸ¥çœ‹æ›´å¤šè¯¦ç»†ä¿¡æ¯æˆ–对此议题进行更改,请转到 %{linkStart}%{trackerName}%{linkEnd}。"
msgid "ExternalIssueIntegration|This issue is synchronized with %{trackerName}"
-msgstr "此问题已与 %{trackerName} åŒæ­¥"
+msgstr "此议题已与 %{trackerName} åŒæ­¥"
msgid "ExternalWikiService|External wiki"
msgstr "外部Wiki"
@@ -14582,8 +14811,8 @@ msgid "Failed to archive a design. Please try again."
msgid_plural "Failed to archive designs. Please try again."
msgstr[0] "归档设计失败。请é‡è¯•ã€‚"
-msgid "Failed to assign a reviewer because no user was found."
-msgstr "由于未找到用户,因此无法指派审核者。"
+msgid "Failed to assign a reviewer because no user was specified."
+msgstr ""
msgid "Failed to assign a user because no user was found."
msgstr "由于未找到用户,因此无法指派用户。"
@@ -14622,7 +14851,7 @@ msgid "Failed to create import label for jira import."
msgstr "为jira导入创建导入标签失败。"
msgid "Failed to create new access token: %{token_response_message}"
-msgstr ""
+msgstr "创建新访问令牌失败:%{token_response_message}"
msgid "Failed to create repository"
msgstr "创建仓库失败"
@@ -14648,12 +14877,12 @@ msgstr "无法获å–此群组的迭代,请é‡è¯•ã€‚"
msgid "Failed to find import label for Jira import."
msgstr "找ä¸åˆ°ç”¨äºŽJira导入的导入标记。"
+msgid "Failed to find users for %{missing}"
+msgstr ""
+
msgid "Failed to generate export, please try again later."
msgstr "生æˆå¯¼å‡ºå¤±è´¥ï¼Œè¯·ç¨åŽå†è¯•ã€‚"
-msgid "Failed to generate report, please try again after sometime"
-msgstr "生æˆæŠ¥å‘Šå¤±è´¥ï¼Œè¯·ç¨åŽå†è¯•"
-
msgid "Failed to get ref."
msgstr "获å–ref失败。"
@@ -14750,6 +14979,9 @@ msgstr "无法删除Zoom会议"
msgid "Failed to remove a to-do item for the design."
msgstr "无法删除设计的待办事项。"
+msgid "Failed to remove attention because no user was found."
+msgstr ""
+
msgid "Failed to remove mirror."
msgstr "删除镜åƒå¤±è´¥ã€‚"
@@ -14762,6 +14994,9 @@ msgstr "无法删除用户标识。"
msgid "Failed to remove user key."
msgstr "无法删除用户密钥。"
+msgid "Failed to request attention because no user was found."
+msgstr ""
+
msgid "Failed to reset key. Please try again."
msgstr "é‡ç½®å¯†é’¥å¤±è´¥ã€‚请é‡è¯•ã€‚"
@@ -14843,6 +15078,9 @@ msgstr "图标将被删除。您确定å—?"
msgid "Feature Flags"
msgstr "功能标志"
+msgid "Feature deprecation and removal"
+msgstr ""
+
msgid "Feature flag status"
msgstr "功能标志状æ€"
@@ -15339,8 +15577,8 @@ msgstr "为æ¯ä¸ªä½œä¸šï¼Œå…‹éš†ä»“库。"
msgid "For each job, re-use the project workspace. If the workspace doesn't exist, use %{code_open}git clone%{code_close}."
msgstr "对于æ¯ä¸ªä½œä¸šï¼Œé‡æ–°ä½¿ç”¨é¡¹ç›®å·¥ä½œåŒºï¼Œå¦‚果工作区ä¸å­˜åœ¨ï¼Œè¯·ä½¿ç”¨ %{code_open}git clone%{code_close}。"
-msgid "For example, the application using the token or the purpose of the token."
-msgstr "例如,应用程åºä½¿ç”¨ä»¤ç‰Œæˆ–令牌的用途。"
+msgid "For example, the application using the token or the purpose of the token. Do not give sensitive information for the name of the token, as it will be visible to all %{resource_type} members."
+msgstr ""
msgid "For files larger than this limit, only index the file name. The file content is neither indexed nor searchable."
msgstr "对于大于此é™åˆ¶çš„文件,仅索引文件å,文件内容既ä¸ç¼–入索引也ä¸å¯æœç´¢ã€‚"
@@ -15423,9 +15661,6 @@ msgstr "公开"
msgid "ForkProject|Select a namespace"
msgstr "选择命å空间"
-msgid "ForkProject|Select a namespace to fork the project"
-msgstr "选择一个命å空间æ¥æ´¾ç”Ÿï¼ˆfork)项目"
-
msgid "ForkProject|The project can be accessed by any logged in user."
msgstr "任何登录用户都å¯ä»¥è®¿é—®è¯¥é¡¹ç›®ã€‚"
@@ -15472,7 +15707,7 @@ msgid "Found errors in your .gitlab-ci.yml:"
msgstr "在.gitlab-ci.yml中å‘现错误:"
msgid "Found warning in your .gitlab-ci.yml"
-msgstr ""
+msgstr "在您的 .gitlab-ci.yml 中å‘现警告"
msgid "Framework successfully deleted"
msgstr "框架删除æˆåŠŸ"
@@ -15522,6 +15757,9 @@ msgstr "完整日志"
msgid "Full name"
msgstr "å…¨å"
+msgid "GCP region configured"
+msgstr ""
+
msgid "GPG Key ID:"
msgstr "GPG密钥ID:"
@@ -15550,7 +15788,7 @@ msgid "Generate a default set of labels"
msgstr "生æˆä¸€ç»„默认的标记"
msgid "Generate group access tokens scoped to this group for your applications that need access to the GitLab API."
-msgstr ""
+msgstr "为需è¦è®¿é—® GitLab API 的应用程åºï¼Œç”ŸæˆèŒƒå›´åœ¨æ­¤ç¾¤ç»„内的群组访问令牌。"
msgid "Generate key"
msgstr "生æˆå¯†é’¥"
@@ -15595,7 +15833,7 @@ msgid "Geo Settings"
msgstr "Geo设置"
msgid "Geo Sites"
-msgstr ""
+msgstr "Geo 站点"
msgid "Geo sites"
msgstr "Geo站点"
@@ -15640,7 +15878,7 @@ msgid "Geo|Adjust your filters/search criteria above. If you believe this may be
msgstr "请您调整上é¢çš„筛选器/æœç´¢æ¡ä»¶ã€‚如果您认为此处有误,请å‚阅 %{linkStart}Geo Troubleshow%{linkEnd} 文档以获å–更多信æ¯ã€‚"
msgid "Geo|All"
-msgstr ""
+msgstr "所有"
msgid "Geo|All %{replicable_name}"
msgstr "所有%{replicable_name}"
@@ -15697,11 +15935,14 @@ msgid "Geo|Does not match the primary storage configuration"
msgstr "与主存储é…ç½®ä¸ä¸€è‡´"
msgid "Geo|Edit %{nodeType} site"
-msgstr ""
+msgstr "编辑 %{nodeType} 站点"
msgid "Geo|Failed"
msgstr "失败"
+msgid "Geo|Filter Geo sites"
+msgstr ""
+
msgid "Geo|Filter by name"
msgstr "按å称筛选"
@@ -15826,13 +16067,13 @@ msgid "Geo|Remove"
msgstr "删除"
msgid "Geo|Remove %{nodeType} site"
-msgstr ""
+msgstr "删除 %{nodeType} 站点"
msgid "Geo|Remove entry"
msgstr "移除æ¡ç›®"
msgid "Geo|Remove site"
-msgstr ""
+msgstr "移除站点"
msgid "Geo|Remove tracking database entry"
msgstr "移除跟踪数æ®åº“æ¡ç›®"
@@ -15898,10 +16139,10 @@ msgid "Geo|Selective (%{syncLabel})"
msgstr "选择性 (%{syncLabel})"
msgid "Geo|Site name can't be blank"
-msgstr ""
+msgstr "站点å称ä¸èƒ½ä¸ºç©º"
msgid "Geo|Site name should be between 1 and 255 characters"
-msgstr ""
+msgstr "站点å称应该介于 1 到 255 个字符之间"
msgid "Geo|Site's status was updated %{timeAgo}."
msgstr "站点状æ€æ›´æ–°äºŽ%{timeAgo}。"
@@ -15940,10 +16181,10 @@ msgid "Geo|There are no %{replicable_type} to show"
msgstr "没有%{replicable_type}å¯æ˜¾ç¤º"
msgid "Geo|There was an error deleting the Geo Site"
-msgstr ""
+msgstr "删除Geo站点时出错"
msgid "Geo|There was an error fetching the Geo Sites"
-msgstr ""
+msgstr "删除Geo站点时出错"
msgid "Geo|This will resync all %{replicableType}. It may take some time to complete. Are you sure you want to continue?"
msgstr "å°†è¦é‡æ–°åŒæ­¥æ‰€æœ‰%{replicableType}。å¯èƒ½éœ€è¦ä¸€äº›æ—¶é—´å®Œæˆã€‚确定继续å—?"
@@ -16021,7 +16262,7 @@ msgid "Get a free instance review"
msgstr "获得å…费的实例评估"
msgid "Get a free trial"
-msgstr ""
+msgstr "获得å…费试用"
msgid "Get a support subscription"
msgstr "获å–支æŒè®¢é˜…"
@@ -16113,6 +16354,12 @@ msgstr "GitLab导入"
msgid "GitLab Issue"
msgstr "GitLab议题"
+msgid "GitLab KAS"
+msgstr ""
+
+msgid "GitLab Memberships CSV Export"
+msgstr ""
+
msgid "GitLab Pages"
msgstr "GitLab Pages"
@@ -16161,6 +16408,9 @@ msgstr "GitLab是一个完整的DevOpså¹³å°ï¼Œä½œä¸ºå•ä¸ªåº”用程åºå‘ˆçŽ°ï¼Œ
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 "GitLab是æœåŠ¡äºŽæ•´ä¸ªè½¯ä»¶å¼€å‘生命周期的å•ä¸€åº”用程åºã€‚从项目规划和æºç ç®¡ç†åˆ°CI/CDã€ç›‘控和安全。"
+msgid "GitLab is free to use. Many features for larger teams are part of our %{link_start}paid products%{link_end}. You can try Ultimate for free without any obligation or payment details."
+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 "GitLab正在为该域获å–Let's Encrypt SSLè¯ä¹¦ã€‚这个过程å¯èƒ½éœ€è¦ä¸€äº›æ—¶é—´ã€‚请ç¨åŽå†è¯•ã€‚"
@@ -16171,7 +16421,7 @@ msgid "GitLab is undergoing maintenance and is operating in read-only mode."
msgstr "GitLab 正在进行维护并以åªè¯»æ¨¡å¼è¿è¡Œã€‚"
msgid "GitLab logo"
-msgstr ""
+msgstr "GitLab logo"
msgid "GitLab member or Email address"
msgstr "GitLabæˆå‘˜æˆ–电å­é‚®ä»¶åœ°å€"
@@ -16287,8 +16537,8 @@ msgstr "已验è¯"
msgid "GitLabPages|When enabled, all attempts to visit your website through HTTP are automatically redirected to HTTPS using a response with status code 301. Requires a valid certificate for all domains. %{docs_link_start}Learn more.%{link_end}"
msgstr "å¯ç”¨åŽï¼Œæ‰€æœ‰é€šè¿‡HTTP的访问å°è¯•éƒ½ä¼šè‡ªåŠ¨é‡å®šå‘到HTTPS,使用状æ€ä»£ç 301。 需è¦å¯¹æ‰€æœ‰åŸŸå有效的è¯ä¹¦ã€‚%{docs_link_start}了解更多信æ¯ã€‚%{link_end}"
-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. %{docs_link_start}Learn more.%{link_end}"
-msgstr "在 GitLab 实例的通用域å (%{pages_host}) 下使用 Pages 时,ä¸èƒ½å°† HTTPS 与å­åŸŸä¸€èµ·ä½¿ç”¨ã€‚è¿™æ„味ç€å¦‚果您的用户å/群组å包å«ä¸€ä¸ªç‚¹ï¼Œå®ƒå°†ä¸èµ·ä½œç”¨ã€‚这是 HTTP Over TLS å议的é™åˆ¶ã€‚如果您ä¸å°† HTTP é‡å®šå‘到 HTTPS,HTTP 页é¢å°†ç»§ç»­å·¥ä½œã€‚ %{docs_link_start}了解更多。%{link_end}"
+msgid "GitLabPages|When using Pages under the general domain of a GitLab instance (%{pages_host}), you cannot use HTTPS with subdomains of subdomains. If your namespace or groupname contains a dot, it does not work. This is a limitation of the HTTP Over TLS protocol. HTTP pages work if you don't redirect HTTP to HTTPS. %{docs_link_start}Learn more.%{link_end}"
+msgstr ""
msgid "GitLabPages|With GitLab Pages you can host your static website directly from your GitLab repository. %{docs_link_start}Learn more.%{link_end}"
msgstr "使用 GitLab Pages,您å¯ä»¥ç›´æŽ¥ä»Žæ‚¨çš„ GitLab 仓库托管您的é™æ€ç½‘站。%{docs_link_start}了解更多。%{link_end}"
@@ -16464,9 +16714,6 @@ msgstr "转到文件"
msgid "Go to find file"
msgstr "转到查找文件"
-msgid "Go to fork"
-msgstr "转到派生"
-
msgid "Go to issue boards"
msgstr "转到议题看æ¿"
@@ -16495,7 +16742,7 @@ msgid "Go to parent"
msgstr "转到上一级"
msgid "Go to parent directory"
-msgstr ""
+msgstr "转到父目录"
msgid "Go to previous page"
msgstr "转到上一页"
@@ -16666,7 +16913,7 @@ msgid "Group %{group_name} was successfully created."
msgstr "群组 %{group_name} å·²æˆåŠŸåˆ›å»ºã€‚"
msgid "Group Access Tokens"
-msgstr ""
+msgstr "群组访问令牌"
msgid "Group Git LFS status:"
msgstr "群组Git LFS状æ€ï¼š"
@@ -16674,9 +16921,6 @@ msgstr "群组Git LFS状æ€ï¼š"
msgid "Group Hooks"
msgstr "群组钩å­"
-msgid "Group ID"
-msgstr "群组 ID"
-
msgid "Group Owner must have signed in with SAML before enabling Group Managed Accounts"
msgstr "群组所有者必须先使用SAML登录,然åŽæ‰èƒ½å¯ç”¨ç¾¤ç»„托管å¸æˆ·"
@@ -16704,9 +16948,6 @@ msgstr "群组头åƒ"
msgid "Group by"
msgstr "分组方å¼"
-msgid "Group description"
-msgstr "群组æè¿°"
-
msgid "Group description (optional)"
msgstr "群组æ述(å¯é€‰ï¼‰"
@@ -16777,7 +17018,7 @@ msgid "Group overview content"
msgstr "群组概述内容"
msgid "Group owners can register group runners in the %{link}"
-msgstr ""
+msgstr "群组所有者å¯ä»¥åœ¨ %{link} 注册群组 Runner"
msgid "Group path is already taken. We've suggested one that is available."
msgstr "群组路径已被å ç”¨ï¼Œæˆ‘们已ç»æŽ¨è了一个å¯ç”¨çš„。"
@@ -16821,8 +17062,8 @@ msgstr "群组:%{group_name}"
msgid "Group: %{name}"
msgstr "群组: %{name}"
-msgid "GroupActivityMetrics|Issues opened"
-msgstr "å¼€å¯çš„议题数"
+msgid "GroupActivityMetrics|Issues created"
+msgstr ""
msgid "GroupActivityMetrics|Last 90 days"
msgstr "过去 90 天"
@@ -16830,8 +17071,8 @@ msgstr "过去 90 天"
msgid "GroupActivityMetrics|Members added"
msgstr "添加新æˆå‘˜æ•°"
-msgid "GroupActivityMetrics|Merge Requests opened"
-msgstr "å¼€å¯çš„åˆå¹¶è¯·æ±‚æ•°"
+msgid "GroupActivityMetrics|Merge Requests created"
+msgstr ""
msgid "GroupActivityMetrics|Recent activity"
msgstr "最近活动"
@@ -17092,7 +17333,7 @@ msgid "GroupSelect|Select a group"
msgstr "选择一个群组"
msgid "GroupSettings|Allow project and group access token creation"
-msgstr ""
+msgstr "å…许项目和群组访问令牌创建"
msgid "GroupSettings|Allows creating organizations and contacts and associating them with issues."
msgstr ""
@@ -17121,6 +17362,9 @@ msgstr "更改群组URL"
msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr "更改群组 URL å¯èƒ½ä¼šäº§ç”Ÿæ„外的副作用。"
+msgid "GroupSettings|Choose a group path that does not start with a dash or end with a period. It can also contain alphanumeric characters and underscores."
+msgstr ""
+
msgid "GroupSettings|Compliance frameworks"
msgstr "åˆè§„框架"
@@ -17143,7 +17387,7 @@ msgid "GroupSettings|Disable group mentions"
msgstr "ç¦ç”¨ç¾¤ç»„æåŠ"
msgid "GroupSettings|Enable customer relations"
-msgstr ""
+msgstr "å¯ç”¨å®¢æˆ·å…³ç³»"
msgid "GroupSettings|Enable delayed project deletion"
msgstr "å¯ç”¨å»¶è¿Ÿé¡¹ç›®åˆ é™¤"
@@ -17154,8 +17398,8 @@ msgstr "导出群组"
msgid "GroupSettings|If not specified at the group or instance level, the default is %{default_initial_branch_name}. Does not affect existing repositories."
msgstr "如果未在群组或实例级别指定,则默认为 %{default_initial_branch_name}。ä¸å½±å“现有仓库。"
-msgid "GroupSettings|If the parent group's visibility is lower than the group current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility."
-msgstr "如果新父群组的å¯è§æ€§ä½ŽäºŽå½“å‰ç¾¤ç»„çš„å¯è§æ€§ï¼Œå­ç¾¤ç»„和项目的å¯è§åº¦å°†ä¼šæ”¹å˜ï¼Œä»¥ä¾¿ä¸Žæ–°çˆ¶ç¾¤ç»„çš„å¯è§æ€§ç›¸åŒ¹é…。"
+msgid "GroupSettings|If the parent group's visibility is lower than the group's current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility."
+msgstr ""
msgid "GroupSettings|New runners registration token has been generated!"
msgstr "已生æˆæ–°çš„Runner注册令牌ï¼"
@@ -17271,8 +17515,11 @@ msgstr "群组(%{count})"
msgid "Groups and projects"
msgstr "群组和项目"
-msgid "Groups and subgroups"
-msgstr "群组和å­ç¾¤ç»„"
+msgid "Groups are a great way to organize projects and people."
+msgstr ""
+
+msgid "Groups are the best way to manage projects and members."
+msgstr ""
msgid "Groups to synchronize"
msgstr "需åŒæ­¥çš„群组"
@@ -17382,14 +17629,17 @@ msgstr "例如h8d3f016698e..."
msgid "GroupsTree|Are you sure you want to leave the \"%{fullName}\" group?"
msgstr "您确定è¦é€€å‡ºç¾¤ç»„“%{fullName}â€å—?"
-msgid "GroupsTree|Edit group"
-msgstr "编辑群组"
+msgid "GroupsTree|Delete"
+msgstr ""
+
+msgid "GroupsTree|Edit"
+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|Leave group"
+msgstr ""
msgid "GroupsTree|Loading groups"
msgstr "加载群组中"
@@ -17400,9 +17650,57 @@ msgstr "没有æœç´¢åˆ°ä»»ä½•ç¬¦åˆçš„群组"
msgid "GroupsTree|No groups or projects matched your search"
msgstr "没有任何群组或项目符åˆæ‚¨çš„æœç´¢"
+msgid "GroupsTree|Options"
+msgstr ""
+
msgid "GroupsTree|Search by name"
msgstr "按å称æœç´¢"
+msgid "Groups|Avatar will be removed. Are you sure?"
+msgstr ""
+
+msgid "Groups|Changing group URL can have unintended side effects."
+msgstr ""
+
+msgid "Groups|Checking group URL availability..."
+msgstr ""
+
+msgid "Groups|Enter a descriptive name for your group."
+msgstr ""
+
+msgid "Groups|Group ID"
+msgstr ""
+
+msgid "Groups|Group URL"
+msgstr ""
+
+msgid "Groups|Group avatar"
+msgstr ""
+
+msgid "Groups|Group description (optional)"
+msgstr ""
+
+msgid "Groups|Group name"
+msgstr ""
+
+msgid "Groups|Group path is available."
+msgstr ""
+
+msgid "Groups|Group path is unavailable. Path has been replaced with a suggested available path."
+msgstr ""
+
+msgid "Groups|Learn more"
+msgstr ""
+
+msgid "Groups|Must start with letter, digit, emoji, or underscore. Can also contain periods, dashes, spaces, and parentheses."
+msgstr ""
+
+msgid "Groups|Remove avatar"
+msgstr ""
+
+msgid "Groups|Save changes"
+msgstr ""
+
msgid "Guideline"
msgstr "å‚考"
@@ -17412,6 +17710,9 @@ msgstr "HAR(HTTP 存档)"
msgid "HAR file path or URL"
msgstr "HAR 文件路径或 URL"
+msgid "HTTP Archive (HAR)"
+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您必须使用具有'api'æƒé™çš„个人访问令牌。\\n您å¯ä»¥åœ¨ %{profile_personal_access_tokens_url}中生æˆä¸€ä¸ª"
@@ -17503,7 +17804,7 @@ msgid "Hello, %{username}!"
msgstr "%{username},您好!"
msgid "HelloMessage|%{handshake_emoji} Contribute to GitLab: %{contribute_link}"
-msgstr "%{handshake_emoji} 贡献 GitLab:%{contribute_link}"
+msgstr "%{handshake_emoji} å‘ GitLab 贡献代ç ï¼š%{contribute_link}"
msgid "HelloMessage|%{magnifier_emoji} Create a new GitLab issue: %{new_issue_link}"
msgstr "%{magnifier_emoji} 创建一个新的议题:%{new_issue_link}"
@@ -17595,31 +17896,31 @@ msgid "Hide values"
msgstr "éšè—值"
msgid "Hierarchy|Current structure"
-msgstr ""
+msgstr "当å‰ç»“æž„"
msgid "Hierarchy|Deliver value more efficiently by breaking down necessary work into a hierarchical structure. This structure helps teams understand scope, priorities, and how work cascades up toward larger goals."
msgstr ""
msgid "Hierarchy|Help us improve work items in GitLab!"
-msgstr ""
+msgstr "帮助我们改进 GitLab 中的工作项ï¼"
msgid "Hierarchy|Is there a framework or type of work item you wish you had access to in GitLab? Give us your feedback and help us build the experiences valuable to you."
msgstr ""
msgid "Hierarchy|Planning hierarchy"
-msgstr ""
+msgstr "规划结构"
msgid "Hierarchy|Take the work items survey"
-msgstr ""
+msgstr "å‚加工作事项调查"
msgid "Hierarchy|These items are unavailable in the current structure."
-msgstr ""
+msgstr "这些事项在当å‰ç»“构中ä¸å¯ç”¨ã€‚"
msgid "Hierarchy|Unavailable structure"
-msgstr ""
+msgstr "ä¸å¯ç”¨çš„结构"
msgid "Hierarchy|You can start using these items now."
-msgstr ""
+msgstr "您现在å¯ä»¥å¼€å§‹ä½¿ç”¨è¿™äº›äº‹é¡¹ã€‚"
msgid "High or unknown vulnerabilities present"
msgstr "存在高å±æˆ–未知æ¼æ´ž"
@@ -17733,7 +18034,7 @@ msgid "I forgot my password"
msgstr "我忘记了密ç "
msgid "I understand the responsibilities involved with managing service account keys"
-msgstr ""
+msgstr "我ç†è§£ç®¡ç†æœåŠ¡è´¦æˆ·å¯†é’¥æ‰€æ¶‰åŠçš„责任"
msgid "I want to explore GitLab to see if it’s worth switching to"
msgstr "我想探索 GitLab,看看是å¦å€¼å¾—切æ¢åˆ°è¿™é‡Œ"
@@ -17810,6 +18111,9 @@ msgstr "ä¿¡æ¯ï¼šæ‚¨çš„SSH密钥已过期。请生æˆä¸€ä¸ªæ–°å¯†é’¥ã€‚"
msgid "INFO: Your SSH key is expiring soon. Please generate a new key."
msgstr "ä¿¡æ¯ï¼šæ‚¨çš„SSH密钥å³å°†è¿‡æœŸã€‚请生æˆä¸€ä¸ªæ–°å¯†é’¥ã€‚"
+msgid "IP"
+msgstr ""
+
msgid "IP Address"
msgstr "IP地å€"
@@ -17841,9 +18145,12 @@ msgid "IdentityVerification|Before you create your group, we need you to verify
msgstr ""
msgid "IdentityVerification|Create a project"
-msgstr ""
+msgstr "创建项目"
msgid "IdentityVerification|Verify your identity"
+msgstr "验è¯æ‚¨çš„身份"
+
+msgid "IdentityVerification|You can always verify your account at a later time to create a group."
msgstr ""
msgid "If any indexed field exceeds this limit, it is truncated to this number of characters. The rest of the content is neither indexed nor searchable. This does not apply to repository and wiki indexing. For unlimited characters, set this to 0."
@@ -17903,6 +18210,9 @@ msgstr "如使用 GitHub,GitHubçš„æ交(commits)和拉å–请求(pull request)
msgid "If you add %{codeStart}needs%{codeEnd} to jobs in your pipeline you'll be able to view the %{codeStart}needs%{codeEnd} relationships between jobs in this tab as a %{linkStart}Directed Acyclic Graph (DAG)%{linkEnd}."
msgstr "如果将%{codeStart}needs%{codeEnd}加到æµæ°´çº¿çš„作业里é¢ï¼Œæ‚¨å°†å¯ä»¥åœ¨%{linkStart}有å‘无环图 (DAG)%{linkEnd}页é¢çœ‹åˆ°ä½œä¸šä¹‹é—´çš„%{codeStart}needs%{codeEnd}关系。"
+msgid "If you are added to a project, it will be displayed here."
+msgstr ""
+
msgid "If you did not initiate these sign-in attempts, please reach out to your administrator or enable two-factor authentication (2FA) on your account."
msgstr "如果您没有å‘起这些登录å°è¯•ï¼Œè¯·è”系您的管ç†å‘˜æˆ–在您的å¸æˆ·ä¸Šå¯ç”¨åŒé‡èº«ä»½éªŒè¯ï¼ˆ2FA)。"
@@ -18206,12 +18516,24 @@ msgstr "...您å¯ä»¥èŽ·å¾—旗舰版的å…费试用"
msgid "InProductMarketing|3 ways to dive into GitLab CI/CD"
msgstr "深入了解 GitLab CI/CD çš„ 3 ç§æ–¹æ³•"
+msgid "InProductMarketing|A single application eliminates complex integrations, data chokepoints, and toolchain maintenance, resulting in greater productivity and lower cost."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features, build more efficiently, strengthen security and compliance."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features."
+msgstr ""
+
msgid "InProductMarketing|Actually, GitLab makes the team work (better)"
msgstr "实际上,GitLab 使团队能够工作更好"
msgid "InProductMarketing|And finally %{deploy_link} a Python application."
msgstr "æœ€åŽ %{deploy_link} 一个 Python 应用程åºã€‚"
+msgid "InProductMarketing|And many more..."
+msgstr ""
+
msgid "InProductMarketing|Are your runners ready?"
msgstr "您的Runner准备好了å—?"
@@ -18230,15 +18552,33 @@ msgstr "用更少的时间编写更好的代ç "
msgid "InProductMarketing|Blog"
msgstr "åšå®¢"
+msgid "InProductMarketing|Break down silos to coordinate seamlessly across development, operations, and security with a consistent experience across the development lifecycle."
+msgstr ""
+
+msgid "InProductMarketing|Burn up/down charts"
+msgstr ""
+
msgid "InProductMarketing|By enabling code owners and required merge approvals the right person will review the right MR. This is a win-win: cleaner code and a more efficient review process."
msgstr "通过å¯ç”¨ä»£ç æ‰€æœ‰è€…和所需的åˆå¹¶æ‰¹å‡†ï¼Œåˆé€‚的人将审查åˆé€‚çš„ MR。这是åŒèµ¢çš„:更干净的代ç å’Œæ›´æœ‰æ•ˆçš„审查过程。"
msgid "InProductMarketing|Click on the number below that corresponds with your answer — 1 being very difficult, 5 being very easy."
msgstr "å•å‡»ä¸‹é¢ä¸Žæ‚¨çš„答案相对应的数字 - 1 表示éžå¸¸å›°éš¾ï¼Œ5 表示éžå¸¸å®¹æ˜“。"
+msgid "InProductMarketing|Code owners"
+msgstr ""
+
msgid "InProductMarketing|Code owners and required merge approvals are part of the paid tiers of GitLab. You can start a free 30-day trial of GitLab Ultimate and enable these features in less than 5 minutes with no credit card required."
msgstr "代ç æ‰€æœ‰è€…和所需的åˆå¹¶æ‰¹å‡†æ˜¯ GitLab 付费版的一部分。您å¯ä»¥å¼€å§‹å…费试用 GitLab 旗舰版 30 天,并在 5 分钟内å¯ç”¨è¿™äº›åŠŸèƒ½ï¼Œæ— éœ€ä¿¡ç”¨å¡ã€‚"
+msgid "InProductMarketing|Code review analytics"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration across stages in GitLab"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration made easy"
+msgstr ""
+
msgid "InProductMarketing|Create a custom CI runner with just a few clicks"
msgstr "åªéœ€å•å‡»å‡ ä¸‹å³å¯åˆ›å»ºè‡ªå®šä¹‰ CI Runner"
@@ -18248,12 +18588,21 @@ msgstr "创建自定义Runner"
msgid "InProductMarketing|Create a project in GitLab in 5 minutes"
msgstr "在5分钟内在 GitLab 中创建一个项目"
+msgid "InProductMarketing|Create well-defined workflows by using scoped labels on issues, merge requests, and epics. Labels with the same scope cannot be used together, which prevents conflicts."
+msgstr ""
+
msgid "InProductMarketing|Create your first project!"
msgstr "创建您的第一个项目ï¼"
+msgid "InProductMarketing|Define who owns specific files or directories, so the right reviewers are suggested when a merge request introduces changes to those files."
+msgstr ""
+
msgid "InProductMarketing|Deliver Better Products Faster"
msgstr "更快地交付更好的产å“"
+msgid "InProductMarketing|Dependency scanning"
+msgstr ""
+
msgid "InProductMarketing|Did you know teams that use GitLab are far more efficient?"
msgstr "您知é“使用 GitLab 的团队效率更高å—?"
@@ -18263,15 +18612,27 @@ msgstr "å›°éš¾"
msgid "InProductMarketing|Dig in and create a project and a repo"
msgstr "深入并创建一个项目和仓库"
+msgid "InProductMarketing|Discover Premium & Ultimate"
+msgstr ""
+
+msgid "InProductMarketing|Discover Premium & Ultimate."
+msgstr ""
+
msgid "InProductMarketing|Do you have a minute?"
msgstr "有空å—?"
msgid "InProductMarketing|Do you have a teammate who would be perfect for this task?"
msgstr "您有一ä½é€‚åˆæ­¤ä»»åŠ¡çš„团队æˆå‘˜å—?"
+msgid "InProductMarketing|Dynamic application security testing"
+msgstr ""
+
msgid "InProductMarketing|Easy"
msgstr "简å•"
+msgid "InProductMarketing|Epics"
+msgstr ""
+
msgid "InProductMarketing|Expand your DevOps journey with a free GitLab trial"
msgstr "通过å…费的 GitLab 试用扩展您的 DevOps 之旅"
@@ -18293,9 +18654,15 @@ msgstr "æ¥è‡ªåƒæ‚¨è¿™æ ·çš„用户的å馈真正改善了我们的产å“,感
msgid "InProductMarketing|Feel the need for speed?"
msgstr "感觉需è¦é€Ÿåº¦å—?"
+msgid "InProductMarketing|Find and fix bottlenecks in your code review process by understanding how long open merge requests have been in review."
+msgstr ""
+
msgid "InProductMarketing|Find out how your teams are really doing"
msgstr "了解您的团队的实际情况"
+msgid "InProductMarketing|Find out if your external libraries are safe. Run dependency scanning jobs that check for known vulnerabilities in your external libraries."
+msgstr ""
+
msgid "InProductMarketing|Follow our steps"
msgstr "è·Ÿéšæˆ‘们的步骤"
@@ -18332,6 +18699,9 @@ msgstr "GitHub ä¼ä¸šé¡¹ç›®åˆ° GitLab"
msgid "InProductMarketing|GitLab is better with teammates to help out!"
msgstr "GitLab 更适åˆé˜Ÿå‹å¸®å¿™ï¼"
+msgid "InProductMarketing|GitLab is infrastructure agnostic (supporting GCP, AWS, Azure, OpenShift, VMWare, On Prem, Bare Metal, and more), offering a consistent workflow experience – irrespective of the environment."
+msgstr ""
+
msgid "InProductMarketing|GitLab provides static application security testing (SAST), dynamic application security testing (DAST), container scanning, and dependency scanning to help you deliver secure applications along with license compliance."
msgstr "GitLab æä¾›é™æ€åº”用程åºå®‰å…¨æµ‹è¯•ï¼ˆSAST)ã€åŠ¨æ€åº”用程åºå®‰å…¨æµ‹è¯•ï¼ˆDAST)ã€å®¹å™¨æ‰«æå’Œä¾èµ–扫æ以帮助您æ供安全的应用程åºä»¥åŠéµå®ˆè®¸å¯å议。"
@@ -18422,21 +18792,36 @@ msgstr "一切尽在统计中"
msgid "InProductMarketing|It's also possible to simply %{external_repo_link} in order to take advantage of GitLab's CI/CD."
msgstr "为了利用 GitLab çš„ CI/CD,也å¯ä»¥ç®€å•åœ°è®¾ç½®ä¸º %{external_repo_link}"
+msgid "InProductMarketing|Keep your code quality high by defining who should approve merge requests and how many approvals are required."
+msgstr ""
+
msgid "InProductMarketing|Launch GitLab CI/CD in 20 minutes or less"
msgstr "在 20 分钟或更短的时间内å¯åŠ¨ GitLab CI/CD"
+msgid "InProductMarketing|Lower cost of development"
+msgstr ""
+
+msgid "InProductMarketing|Make it easier to collaborate on high-level ideas by grouping related issues in an epic."
+msgstr ""
+
msgid "InProductMarketing|Making the switch? It's easier than you think to import your projects into GitLab. Move %{github_link}, or import something %{bitbucket_link}."
msgstr "进行转æ¢ï¼Ÿå°†é¡¹ç›®å¯¼å…¥ GitLab 比您想象的è¦å®¹æ˜“,移动 %{github_link},或者导入一些东西 %{bitbucket_link}。"
msgid "InProductMarketing|Master the art of importing!"
msgstr "掌æ¡å¯¼å…¥çš„艺术ï¼"
+msgid "InProductMarketing|Merge request approval rule"
+msgstr ""
+
msgid "InProductMarketing|Move on to easily creating a Pages website %{ci_template_link}"
msgstr "继续轻æ¾åˆ›å»º Pages 网站 %{ci_template_link}"
msgid "InProductMarketing|Multiple owners, confusing workstreams? We've got you covered"
msgstr "多个所有者,混乱的工作æµï¼Ÿæˆ‘们已为您æä¾›ä¿éšœ"
+msgid "InProductMarketing|Multiple required approvers"
+msgstr ""
+
msgid "InProductMarketing|Need an alternative to importing?"
msgstr "需è¦æ›¿ä»£å¯¼å…¥çš„方法å—?"
@@ -18449,18 +18834,33 @@ msgstr "ä¸éœ€è¦ä¿¡ç”¨å¡ã€‚"
msgid "InProductMarketing|Our tool brings all the things together"
msgstr "我们的工具将所有东西整åˆåœ¨ä¸€èµ·"
+msgid "InProductMarketing|Protect your web application by using DAST to examine for vulnerabilities in deployed environments."
+msgstr ""
+
msgid "InProductMarketing|Rapid development, simplified"
msgstr "快速开å‘,简化"
msgid "InProductMarketing|Reduce Security & Compliance Risk"
msgstr "é™ä½Žå®‰å…¨ä¸Žåˆè§„风险"
+msgid "InProductMarketing|Require multiple approvers on a merge request, so you know it's in good shape before it's merged."
+msgstr ""
+
+msgid "InProductMarketing|Roadmaps"
+msgstr ""
+
+msgid "InProductMarketing|Scoped labels"
+msgstr ""
+
msgid "InProductMarketing|Security that's integrated into your development lifecycle"
msgstr "集æˆåˆ°æ‚¨çš„å¼€å‘生命周期中的安全性"
msgid "InProductMarketing|Sometimes you're not ready to make a full transition to a new tool. If you're not ready to fully commit, %{mirroring_link} gives you a safe way to try out GitLab in parallel with your current tool."
msgstr "有时您还没有准备好完全过渡到新工具。如果您还没有准备好完全æ交, %{mirroring_link} 为您æ供了一ç§ä¸Žå½“å‰å·¥å…·å¹¶è¡Œè¯•ç”¨ GitLab 的安全方法。"
+msgid "InProductMarketing|Speed. Efficiency. Trust."
+msgstr ""
+
msgid "InProductMarketing|Spin up an autoscaling runner in GitLab"
msgstr "在 GitLab 中å¯åŠ¨è‡ªåŠ¨ç¼©æ”¾Runner"
@@ -18468,6 +18868,9 @@ msgid "InProductMarketing|Start a GitLab Ultimate trial today in less than one m
msgstr "ç«‹å³åœ¨ä¸åˆ°ä¸€åˆ†é’Ÿçš„时间内开始 GitLab Ultimate 试用,无需信用å¡ã€‚"
msgid "InProductMarketing|Start a Self-Managed trial"
+msgstr "开始试用"
+
+msgid "InProductMarketing|Start a free trial"
msgstr ""
msgid "InProductMarketing|Start a free trial of GitLab Ultimate – no credit card required"
@@ -18536,6 +18939,9 @@ msgstr "选择退出Onboarding邮件,%{unsubscribe_link}。"
msgid "InProductMarketing|To understand and get the most out of GitLab, start at the beginning and %{project_link}. In GitLab, repositories are part of a project, so after you've created your project you can go ahead and %{repo_link}."
msgstr "è¦äº†è§£å¹¶å……分利用GitLab,请从头开始,从%{project_link}开始。在GitLab中,仓库是项目的一部分,所以在您创建了您的项目之åŽï¼Œæ‚¨å¯ä»¥ç»§ç»­æ‰§è¡Œ%{repo_link}。"
+msgid "InProductMarketing|Track completed issues in a chart, so you can see how a milestone is progressing at a glance."
+msgstr ""
+
msgid "InProductMarketing|Try GitLab Ultimate for free"
msgstr "å…费试用 GitLab 旗舰版"
@@ -18572,9 +18978,12 @@ msgstr "éžå¸¸å›°éš¾"
msgid "InProductMarketing|Very easy"
msgstr "éžå¸¸å®¹æ˜“"
-msgid "InProductMarketing|Want to host GitLab on your servers?"
+msgid "InProductMarketing|Visualize your epics and milestones in a timeline."
msgstr ""
+msgid "InProductMarketing|Want to host GitLab on your servers?"
+msgstr "想在您的æœåŠ¡å™¨ä¸Šæ‰˜ç®¡ GitLab?"
+
msgid "InProductMarketing|We know a thing or two about efficiency and we don't want to keep that to ourselves. Sign up for a free trial of GitLab Ultimate and your teams will be on it from day one."
msgstr "我们知é“一些关于效率的事情,我们想分享给大家。注册GitLab Ultimateçš„å…费试用版,您的团队将从第一天开始使用它。"
@@ -18593,6 +19002,9 @@ msgstr "在 GitLab 中工作 = 更高效"
msgid "InProductMarketing|YouTube"
msgstr "YouTube"
+msgid "InProductMarketing|Your software, deployed your way"
+msgstr ""
+
msgid "InProductMarketing|Your teams can be more efficient"
msgstr "您的团队å¯ä»¥æ›´å…·æ•ˆçŽ‡"
@@ -18651,7 +19063,7 @@ msgid "Incident Management Limits"
msgstr "事件管ç†é™åˆ¶"
msgid "Incident details"
-msgstr ""
+msgstr "事件详情"
msgid "Incident template (optional)."
msgstr "事件模æ¿ï¼ˆå¯é€‰ï¼‰ã€‚"
@@ -18713,9 +19125,18 @@ msgstr "已错过的SLA"
msgid "IncidentManagement|No incidents to display."
msgstr "没有è¦æ˜¾ç¤ºçš„事件。"
+msgid "IncidentManagement|None"
+msgstr ""
+
msgid "IncidentManagement|Open"
msgstr "打开"
+msgid "IncidentManagement|Page your team with escalation policies"
+msgstr ""
+
+msgid "IncidentManagement|Paged"
+msgstr ""
+
msgid "IncidentManagement|Published"
msgstr "å·²å‘布"
@@ -18725,6 +19146,9 @@ msgstr "å‘布到状æ€é¡µ"
msgid "IncidentManagement|Severity"
msgstr "严é‡æ€§"
+msgid "IncidentManagement|Status"
+msgstr ""
+
msgid "IncidentManagement|There are no closed incidents"
msgstr "没有已关闭的事件"
@@ -18743,6 +19167,9 @@ msgstr "未知"
msgid "IncidentManagement|Unpublished"
msgstr "未å‘布"
+msgid "IncidentManagement|Use escalation policies to automatically page your team when incidents are created."
+msgstr ""
+
msgid "IncidentSettings|Activate \"time to SLA\" countdown timer"
msgstr "å¯ç”¨â€è·SLA时间â€å€’计时器"
@@ -18788,8 +19215,11 @@ msgstr "分钟"
msgid "Incidents"
msgstr "事件"
-msgid "Incidents|Add a URL"
-msgstr "添加 URL"
+msgid "Incidents|Add image details"
+msgstr ""
+
+msgid "Incidents|Add text or a link to display with your image. If you don't add either, the file name displays instead."
+msgstr ""
msgid "Incidents|Drop or %{linkStart}upload%{linkEnd} a metric screenshot to attach it to the incident"
msgstr "放置或%{linkStart}上传%{linkEnd}指标截图,将其附加到事件中。"
@@ -18803,21 +19233,30 @@ msgstr "删除镜åƒæ—¶å‡ºçŽ°é—®é¢˜ã€‚"
msgid "Incidents|There was an issue loading metric images."
msgstr "加载指标图片时出现问题。"
+msgid "Incidents|There was an issue updating your image."
+msgstr ""
+
msgid "Incidents|There was an issue uploading your image."
msgstr "上传您的镜åƒæ—¶å‡ºçŽ°é—®é¢˜ã€‚"
-msgid "Incidents|You can optionally add a URL to link users to the original graph."
-msgstr "您å¯ä»¥é€‰æ‹©æ·»åŠ  URL 以将用户链接到原始图表。"
-
msgid "Incident|Alert details"
msgstr "警报详情"
msgid "Incident|Are you sure you wish to delete this image?"
msgstr "您确定è¦åˆ é™¤æ­¤é•œåƒå—?"
+msgid "Incident|Delete image"
+msgstr ""
+
msgid "Incident|Deleting %{filename}"
msgstr "删除%{filename}"
+msgid "Incident|Edit image text or link"
+msgstr ""
+
+msgid "Incident|Editing %{filename}"
+msgstr ""
+
msgid "Incident|Metrics"
msgstr "指标"
@@ -18870,7 +19309,7 @@ msgid "Incompatible project"
msgstr "ä¸å…¼å®¹çš„项目"
msgid "Incomplete"
-msgstr "ä¸å®Œæ•´"
+msgstr "未完æˆ"
msgid "Increase"
msgstr "增加"
@@ -19086,12 +19525,18 @@ msgstr "使用自定义设置加载项目时å‘生错误。"
msgid "Integrations|Branches for which notifications are to be sent"
msgstr "è¦å‘é€é€šçŸ¥çš„分支"
+msgid "Integrations|Clear if using a self-signed certificate."
+msgstr ""
+
msgid "Integrations|Comment detail:"
msgstr "评论细节:"
msgid "Integrations|Comment settings:"
msgstr "评论设置:"
+msgid "Integrations|Connection details"
+msgstr ""
+
msgid "Integrations|Connection failed. Please check your settings."
msgstr "连接失败。请检查您的设置。"
@@ -19116,6 +19561,9 @@ msgstr "编辑项目别å"
msgid "Integrations|Enable GitLab.com slash commands in a Slack workspace."
msgstr "在 Slack 工作区中å¯ç”¨ GitLab.com æ–œæ å‘½ä»¤ã€‚"
+msgid "Integrations|Enable SSL verification"
+msgstr ""
+
msgid "Integrations|Enable comments"
msgstr "å¯ç”¨è¯„论"
@@ -19156,7 +19604,7 @@ msgid "Integrations|Keep your PHP dependencies updated on Packagist."
msgstr "在 Packagist 上更新您的 PHP ä¾èµ–项。"
msgid "Integrations|Known limitations"
-msgstr ""
+msgstr "已知é™åˆ¶"
msgid "Integrations|Link namespaces"
msgstr "链接命å空间"
@@ -19194,6 +19642,9 @@ msgstr "é‡ç½®æ­¤é›†æˆå°†æ¸…除设置并åœç”¨æ­¤é›†æˆã€‚"
msgid "Integrations|Return to GitLab for Jira"
msgstr "返回GitLab for Jira"
+msgid "Integrations|SSL verification"
+msgstr ""
+
msgid "Integrations|Save settings?"
msgstr "ä¿å­˜è®¾ç½®å—?"
@@ -19213,7 +19664,7 @@ msgid "Integrations|Send notifications about project events to a Unify Circuit c
msgstr "将有关项目事件的通知å‘é€åˆ° Unify Circuit 对è¯ã€‚ %{docs_link}"
msgid "Integrations|Sign in to GitLab"
-msgstr ""
+msgstr "登录到 GitLab"
msgid "Integrations|Sign in to add namespaces"
msgstr "登录以添加命å空间"
@@ -19239,9 +19690,6 @@ msgstr "使用自定义设置"
msgid "Integrations|Use default settings"
msgstr "使用默认设置"
-msgid "Integrations|When you mention a Jira issue in a commit or merge request, GitLab creates a remote link and comment (if enabled)."
-msgstr "当您在æ交或åˆå¹¶è¯·æ±‚中æåŠ Jira 议题时,GitLab 会创建一个远程链接和评论(如果å¯ç”¨ï¼‰ã€‚"
-
msgid "Integrations|You can now close this window and return to the GitLab for Jira application."
msgstr "您现在å¯ä»¥å…³é—­æ­¤çª—å£å¹¶è¿”回GitLab for Jira应用。"
@@ -19266,9 +19714,6 @@ msgstr "当您在禅é“中创建项目的议题时,禅é“议题会显示在此
msgid "Integrations|can't exceed %{recipients_limit}"
msgstr "ä¸èƒ½è¶…过 %{recipients_limit}"
-msgid "Interactive developer security education."
-msgstr "互动å¼å¼€å‘者安全教育。"
-
msgid "Interactive mode"
msgstr "交互模å¼"
@@ -19288,7 +19733,7 @@ msgid "Internal URL (optional)"
msgstr "内部URL(å¯é€‰)"
msgid "Internal error occurred while delivering this webhook."
-msgstr ""
+msgstr "ä¼ é€æ­¤ webhook æ—¶å‘生内部错误。"
msgid "Internal users"
msgstr "内部用户"
@@ -19758,6 +20203,9 @@ msgstr "年龄"
msgid "IssueAnalytics|Assignees"
msgstr "指派人"
+msgid "IssueAnalytics|Created by"
+msgstr ""
+
msgid "IssueAnalytics|Due date"
msgstr "截止日期"
@@ -19770,9 +20218,6 @@ msgstr "议题"
msgid "IssueAnalytics|Milestone"
msgstr "里程碑"
-msgid "IssueAnalytics|Opened by"
-msgstr "å¼€å¯è€…"
-
msgid "IssueAnalytics|Status"
msgstr "状æ€"
@@ -19828,34 +20273,34 @@ msgid "IssueTracker|The URL to view an issue in the external issue tracker. Must
msgstr "在外部议题跟踪器中查看议题的 URLã€‚å¿…é¡»åŒ…å« %{colon_id}。"
msgid "IssueTracker|Use Bugzilla as this project's issue tracker."
-msgstr "使用 Bugzilla 作为该项目的议题追踪器。"
+msgstr "使用 Bugzilla 作为该项目的议题跟踪器。"
msgid "IssueTracker|Use Bugzilla as this project's issue tracker. %{docs_link}"
-msgstr "使用 Bugzilla 作为该项目的议题追踪器。 %{docs_link}"
+msgstr "使用 Bugzilla 作为该项目的议题跟踪器。 %{docs_link}"
msgid "IssueTracker|Use IBM Engineering Workflow Management as this project's issue tracker."
-msgstr "使用 IBM Engineering Workflow Management 作为该项目的议题追踪器。"
+msgstr "使用 IBM Engineering Workflow Management 作为该项目的议题跟踪器。"
msgid "IssueTracker|Use IBM Engineering Workflow Management as this project's issue tracker. %{docs_link}"
-msgstr "使用 IBM Engineering Workflow Management 作为该项目的议题追踪器。 %{docs_link}"
+msgstr "使用 IBM Engineering Workflow Management 作为该项目的议题跟踪器。 %{docs_link}"
msgid "IssueTracker|Use Redmine as the issue tracker. %{docs_link}"
-msgstr "使用 Redmine 作为议题追踪器。 %{docs_link}"
+msgstr "使用 Redmine 作为议题跟踪器。 %{docs_link}"
msgid "IssueTracker|Use Redmine as this project's issue tracker."
-msgstr "使用 Redmine 作为该项目的议题追踪器。"
+msgstr "使用 Redmine 作为该项目的议题跟踪器。"
msgid "IssueTracker|Use YouTrack as this project's issue tracker."
-msgstr "使用 YouTrack 作为该项目的议题追踪器。"
+msgstr "使用 YouTrack 作为该项目的议题跟踪器。"
msgid "IssueTracker|Use YouTrack as this project's issue tracker. %{docs_link}"
msgstr "使用 YouTrack 作为该项目的问题跟踪器。 %{docs_link}"
msgid "IssueTracker|Use a custom issue tracker as this project's issue tracker."
-msgstr "使用自定义议题追踪器作为该项目的议题追踪器。"
+msgstr "使用自定义议题跟踪器作为该项目的议题跟踪器。"
msgid "IssueTracker|Use a custom issue tracker that is not in the integration list. %{docs_link}"
-msgstr "使用ä¸åœ¨é›†æˆåˆ—表中的自定义议题追踪器。 %{docs_link}"
+msgstr "使用ä¸åœ¨é›†æˆåˆ—表中的自定义议题跟踪器。 %{docs_link}"
msgid "Issues"
msgstr "议题"
@@ -19896,11 +20341,11 @@ msgstr "在您为项目创建议题åŽï¼Œæˆ‘们就会开始跟踪并显示它们
msgid "IssuesAnalytics|Avg/Month:"
msgstr "月å‡ï¼š"
-msgid "IssuesAnalytics|Issues opened"
-msgstr "å¼€å¯çš„议题数"
+msgid "IssuesAnalytics|Issues created"
+msgstr ""
-msgid "IssuesAnalytics|Issues opened per month"
-msgstr "æ¯æœˆå¼€å¯çš„议题数"
+msgid "IssuesAnalytics|Issues created per month"
+msgstr ""
msgid "IssuesAnalytics|Last 12 months"
msgstr "最近12个月"
@@ -19926,6 +20371,9 @@ msgstr "无法使用 Web ç•Œé¢ %{action} 存储在 LFS 中的文件"
msgid "It looks like you have some draft commits in this branch."
msgstr "看起æ¥ä½ åœ¨è¿™ä¸ªåˆ†æ”¯ä¸Šæœ‰ä¸€äº›è‰ç¨¿æ交。"
+msgid "It looks like you're attempting to activate your subscription. Use %{a_start}the Subscription page%{a_end} instead."
+msgstr ""
+
msgid "It may be several days before you see feature usage data."
msgstr "您å¯èƒ½è¦è¿‡å‡ å¤©æ‰èƒ½çœ‹åˆ°åŠŸèƒ½ä½¿ç”¨æƒ…况数æ®ã€‚"
@@ -20154,6 +20602,9 @@ msgstr "æˆåŠŸåˆ›å»ºæ–°åˆ†æ”¯ã€‚"
msgid "JiraConnect|You can now close this window and return to Jira."
msgstr "您现在å¯ä»¥å…³é—­æ­¤çª—å£å¹¶è¿”回Jira。"
+msgid "JiraConnect|You don't have permission to create branches for this project. Select a different project or contact the project owner for access. %{linkStart}Learn more.%{linkEnd}"
+msgstr ""
+
msgid "JiraRequest|A connection error occurred while connecting to Jira. Try your request again."
msgstr "连接到 Jira æ—¶å‘生连接错误。请您å†æ¬¡å°è¯•è¯·æ±‚。"
@@ -20202,15 +20653,15 @@ msgstr "Jira 实例的基础 URL。"
msgid "JiraService|Define the type of Jira issue to create from a vulnerability."
msgstr "定义è¦ä»Žæ¼æ´žåˆ›å»ºçš„ Jira 议题的类型。"
-msgid "JiraService|Displaying Jira issues while leaving the GitLab issue functionality enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
-msgstr "显示Jira议题且ä¿æŒGitLab自带议题功能å¯ç”¨å¯èƒ½å¼•èµ·æ··æ·†ã€‚如未计划使用,请考虑%{linkStart}ç¦ç”¨GitLab议题%{linkEnd}。"
+msgid "JiraService|Displaying Jira issues while leaving GitLab issues also enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
+msgstr ""
+
+msgid "JiraService|Enable Jira issue creation from vulnerabilities"
+msgstr ""
msgid "JiraService|Enable Jira issues"
msgstr "å¯ç”¨Jira议题"
-msgid "JiraService|Enable Jira issues creation from vulnerabilities"
-msgstr "å¯ç”¨ä»Žæ¼æ´žåˆ›å»º Jira 问题"
-
msgid "JiraService|Enable Jira transitions"
msgstr "å¯ç”¨ Jira 转æ¢"
@@ -20325,17 +20776,20 @@ msgstr "使用Jira进行议题跟踪å—?"
msgid "JiraService|View Jira issues in GitLab"
msgstr "在GitLab查看Jira议题"
-msgid "JiraService|Warning: All GitLab users that have access to this GitLab project are able to view all issues from the Jira project specified below."
-msgstr "警告:有æƒè®¿é—®æ­¤ GitLab 项目的所有 GitLab 用户都能够查看æ¥è‡ªä¸‹é¢æŒ‡å®šçš„ Jira 项目的所有问题。"
+msgid "JiraService|Warning: All GitLab users with access to this GitLab project can view all issues from the Jira project you select."
+msgstr ""
msgid "JiraService|Web URL"
msgstr "Web URL"
-msgid "JiraService|Work on Jira issues without leaving GitLab. Adds a Jira menu to access your list of Jira issues and view any issue as read-only."
-msgstr "在ä¸ç¦»å¼€GitLab的情况下处ç†Jira议题。添加一个Jiraèœå•æ¥è®¿é—®æ‚¨çš„Jira议题列表,并å¯ä»¥ä»¥åªè¯»æ¨¡å¼æŸ¥çœ‹ä»»ä½•è®®é¢˜ã€‚"
+msgid "JiraService|When a Jira issue is mentioned in a commit or merge request, a remote link and comment (if enabled) will be created."
+msgstr ""
-msgid "JiraService|You need to configure Jira before enabling this integration. For more details, read the %{jira_doc_link_start}Jira integration documentation%{link_end}."
-msgstr "您需è¦åœ¨å¯ç”¨æ­¤é›†æˆä¹‹å‰é…ç½® Jira。有关更多详细信æ¯ï¼Œè¯·é˜…读 %{jira_doc_link_start}Jira 集æˆæ–‡æ¡£%{link_end}。"
+msgid "JiraService|Work on Jira issues without leaving GitLab. Add a Jira menu to access a read-only list of your Jira issues."
+msgstr ""
+
+msgid "JiraService|You must configure Jira before enabling this integration. %{jira_doc_link_start}Learn more.%{link_end}"
+msgstr ""
msgid "Job"
msgstr "作业"
@@ -20346,9 +20800,6 @@ msgstr "作业 %{jobName}"
msgid "Job Failed #%{build_id}"
msgstr "作业 #%{build_id} 已失败 "
-msgid "Job ID"
-msgstr "作业 ID"
-
msgid "Job artifact"
msgstr "作业产物"
@@ -20415,9 +20866,27 @@ msgstr "使用作业自动执行任务"
msgid "Jobs|You're about to retry a job that failed because it attempted to deploy code that is older than the latest deployment. Retrying this job could result in overwriting the environment with the older source code."
msgstr "ä½ å³å°†é‡è¯•ä¸€ä¸ªä½œä¸šï¼Œæ­¤ä½œä¸šå› è¯•å›¾éƒ¨ç½²æ—§çš„代ç è€Œå¤±è´¥ã€‚ é‡è¯•æ­¤ä»»åŠ¡å¯èƒ½å¯¼è‡´ç”¨æ—§ç‰ˆæœ¬æºä»£ç è¦†ç›–环境。"
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source} into %{target}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{ref}"
+msgstr ""
+
+msgid "Job|Are you sure you want to erase this job log and artifacts?"
+msgstr ""
+
msgid "Job|Browse"
msgstr "æµè§ˆ"
+msgid "Job|Cancel"
+msgstr ""
+
msgid "Job|Complete Raw"
msgstr "完整原始日志"
@@ -20427,6 +20896,9 @@ msgstr "下载"
msgid "Job|Erase job log and artifacts"
msgstr "擦除作业日志和产物"
+msgid "Job|Finished at"
+msgstr ""
+
msgid "Job|Job artifacts"
msgstr "作业产物"
@@ -20439,8 +20911,8 @@ msgstr "作业已被 %{userLink} 删除"
msgid "Job|Keep"
msgstr "ä¿æŒ"
-msgid "Job|Pipeline"
-msgstr "æµæ°´çº¿"
+msgid "Job|Retry"
+msgstr ""
msgid "Job|Scroll to bottom"
msgstr "滚动到底部"
@@ -20451,6 +20923,9 @@ msgstr "滚动到顶部"
msgid "Job|Show complete raw"
msgstr "显示完整æº"
+msgid "Job|Status"
+msgstr ""
+
msgid "Job|The artifacts were removed"
msgstr "作业产物已被删除"
@@ -20478,21 +20953,12 @@ msgstr "å…许失败"
msgid "Job|delayed"
msgstr "延迟"
-msgid "Job|for"
-msgstr "于"
-
-msgid "Job|into"
-msgstr "åˆå¹¶å…¥"
-
msgid "Job|manual"
msgstr "手动"
msgid "Job|triggered"
msgstr "已触å‘"
-msgid "Job|with"
-msgstr "ç”±"
-
msgid "Join Zoom meeting"
msgstr "加入Zoom会议"
@@ -20595,9 +21061,6 @@ msgstr "é”®"
msgid "Ki"
msgstr "Ki"
-msgid "Kontra"
-msgstr "Kontra"
-
msgid "Kroki"
msgstr "Kroki"
@@ -20920,6 +21383,9 @@ msgstr "进一步了解%{username}"
msgid "Learn more about Auto DevOps"
msgstr "了解更多关于Auto DevOps"
+msgid "Learn more about GitLab"
+msgstr ""
+
msgid "Learn more about Needs relationships"
msgstr "了解更多关于Needs关系的信æ¯"
@@ -21107,7 +21573,7 @@ msgid "License file"
msgstr "许å¯è¯æ–‡ä»¶"
msgid "License key"
-msgstr ""
+msgstr "许å¯è¯å¯†é’¥"
msgid "License overview"
msgstr "许å¯è¯æ¦‚览"
@@ -21241,9 +21707,18 @@ msgstr "检测到的ä¸ç¬¦åˆé¡¹ç›®æŒ‡å®šæ”¿ç­–的许å¯è¯"
msgid "Licenses|Displays licenses detected in the project, based on the %{linkStart}latest successful%{linkEnd} scan"
msgstr "显示项目中检测到的许å¯è¯ï¼ŒåŸºäºŽ%{linkStart}最新的æˆåŠŸæ‰«æ%{linkEnd}"
+msgid "Licenses|Drag your license file here or %{linkStart}click to upload%{linkEnd}."
+msgstr ""
+
+msgid "Licenses|Drop your license file to start the upload."
+msgstr ""
+
msgid "Licenses|Error fetching the license list. Please check your network connection and try again."
msgstr "获å–许å¯è¯åˆ—表时出错。请检查您的网络连接并é‡è¯•ã€‚"
+msgid "Licenses|Error: You are trying to upload something other than a file"
+msgstr ""
+
msgid "Licenses|License Compliance"
msgstr "许å¯è¯åˆè§„性"
@@ -21262,6 +21737,9 @@ msgstr "è¿å策略:拒ç»"
msgid "Licenses|Specified policies in this project"
msgstr "本项目中的指定政策"
+msgid "Licenses|The file could not be uploaded."
+msgstr ""
+
msgid "Licenses|The license list details information about the licenses used within your project."
msgstr "许å¯è¯åˆ—表详细说明您项目中使用的许å¯è¯ä¿¡æ¯ã€‚"
@@ -21295,10 +21773,6 @@ msgstr "é™åˆ¶å¯ä»¥ç´¢å¼•çš„命å空间和项目的数é‡ã€‚"
msgid "Limit the size of Sidekiq jobs stored in Redis."
msgstr "é™åˆ¶å­˜å‚¨åœ¨Redis中的Sidekiq作业的大å°ã€‚"
-msgid "Limited to showing %d event at most"
-msgid_plural "Limited to showing %d events at most"
-msgstr[0] "最多显示 %d 个事件"
-
msgid "Limiting mode"
msgstr "é™åˆ¶æ¨¡å¼"
@@ -21308,6 +21782,9 @@ msgstr "è¡Œå˜æ›´"
msgid "Link"
msgstr "链接"
+msgid "Link (optional)"
+msgstr ""
+
msgid "Link Prometheus monitoring to GitLab."
msgstr "将Prometheus监控链接到 GitLab。"
@@ -21344,6 +21821,9 @@ msgstr "链接到您的 Grafana 实例。"
msgid "Linked emails (%{email_count})"
msgstr "链接的电å­é‚®ä»¶ (%{email_count})"
+msgid "Linked epics"
+msgstr ""
+
msgid "Linked issues"
msgstr "相关议题"
@@ -21371,6 +21851,15 @@ msgstr "列出å¯ç”¨ä»“库"
msgid "List of all merge commits"
msgstr "所有åˆå¹¶æ交列表"
+msgid "List of environments for this project"
+msgstr ""
+
+msgid "List of suitable GCP locations"
+msgstr ""
+
+msgid "List of users allowed to exceed the rate limit."
+msgstr ""
+
msgid "List options"
msgstr "列表选项"
@@ -21441,7 +21930,7 @@ msgid "Lock %{issuableDisplayName}"
msgstr "é”定 %{issuableDisplayName}"
msgid "Lock File?"
-msgstr ""
+msgstr "é”定文件?"
msgid "Lock memberships to LDAP synchronization"
msgstr "é”定æˆå‘˜èº«ä»½åˆ°LDAPåŒæ­¥"
@@ -21480,37 +21969,37 @@ msgid "Locks the discussion."
msgstr "é”定讨论."
msgid "LoggedOutMarketingHeader|About GitLab"
-msgstr ""
+msgstr "关于 GitLab"
msgid "LoggedOutMarketingHeader|Explore GitLab"
-msgstr ""
+msgstr "æµè§ˆ GitLab"
msgid "LoggedOutMarketingHeader|Get started"
-msgstr ""
+msgstr "开始使用"
msgid "LoggedOutMarketingHeader|GitLab Learn"
-msgstr ""
+msgstr "GitLab 学习"
msgid "LoggedOutMarketingHeader|GitLab docs"
-msgstr ""
+msgstr "GitLab 文档"
msgid "LoggedOutMarketingHeader|GitLab: the DevOps platform"
-msgstr ""
+msgstr "GitLab:DevOps å¹³å°"
msgid "LoggedOutMarketingHeader|How GitLab compares"
-msgstr ""
+msgstr "与åŒç±»äº§å“相比"
msgid "LoggedOutMarketingHeader|Install GitLab"
-msgstr ""
+msgstr "安装 GitLab"
msgid "LoggedOutMarketingHeader|Pricing"
-msgstr ""
+msgstr "定价"
msgid "LoggedOutMarketingHeader|Talk to an expert"
-msgstr ""
+msgstr "与专家交谈"
msgid "Login"
-msgstr ""
+msgstr "登录"
msgid "Login with smartcard"
msgstr "使用智能å¡ç™»å½•"
@@ -21590,6 +22079,9 @@ msgstr "Mailgun事件"
msgid "Maintenance mode"
msgstr "维护模å¼"
+msgid "Make adjustments to how your GitLab instance is set up."
+msgstr ""
+
msgid "Make and review changes in the browser with the Web IDE"
msgstr "使用Web IDE在æµè§ˆå™¨ä¸­åˆ›å»ºå’ŒæŸ¥çœ‹æ›´æ”¹"
@@ -21734,6 +22226,12 @@ msgstr "添加斜体文本(%{modifierKey}I)"
msgid "MarkdownEditor|Add italic text (%{modifier_key}I)"
msgstr "添加斜体文本(%{modifier_key}I)"
+msgid "MarkdownEditor|Add strikethrough text (%{modifierKey}⇧X)"
+msgstr ""
+
+msgid "MarkdownEditor|Add strikethrough text (%{modifier_key}⇧X)"
+msgstr ""
+
msgid "Marked For Deletion At - %{deletion_time}"
msgstr "标记删除于 - %{deletion_time}"
@@ -21995,6 +22493,9 @@ msgstr "最大推é€å¤§å°"
msgid "Maximum push size (MB)"
msgstr "最大推é€å¤§å° (MB)"
+msgid "Maximum requests per 10 minutes per user"
+msgstr ""
+
msgid "Maximum requests per minute"
msgstr "æ¯åˆ†é’Ÿæœ€å¤§è¯·æ±‚æ•°"
@@ -22085,6 +22586,17 @@ msgstr "%{group}çš„æˆå‘˜ä¹Ÿå¯ä»¥æŽ¨é€åˆ°æ­¤åˆ†æ”¯: %{branch}"
msgid "Members of a group may only view projects they have permission to access"
msgstr "群组æˆå‘˜åªèƒ½æŸ¥çœ‹ä»–们有æƒè®¿é—®çš„项目"
+msgid "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seat in use and will be billed for the overage."
+msgid_plural "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seats in use and will be billed for the overage."
+msgstr[0] ""
+
+msgid "MembersOverage|You are about to incur additional charges"
+msgstr ""
+
+msgid "MembersOverage|Your subscription includes %d seat."
+msgid_plural "MembersOverage|Your subscription includes %d seats."
+msgstr[0] ""
+
msgid "Membership"
msgstr "æˆå‘˜èµ„æ ¼"
@@ -22287,10 +22799,7 @@ msgid "Merge request events"
msgstr "åˆå¹¶è¯·æ±‚事件"
msgid "Merge request not merged"
-msgstr ""
-
-msgid "Merge request pipelines 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 merge request pipelines."
-msgstr ""
+msgstr "åˆå¹¶è¯·æ±‚未åˆå¹¶"
msgid "Merge request reports"
msgstr "åˆå¹¶è¯·æ±‚报告"
@@ -22311,16 +22820,16 @@ msgid "Merge unavailable: merge requests are read-only in a secondary Geo node."
msgstr "åˆå¹¶ä¸å¯ç”¨ï¼šåˆå¹¶è¯·æ±‚åœ¨æ¬¡è¦ Geo 节点中是åªè¯»çš„。"
msgid "Merge unverified changes"
-msgstr ""
+msgstr "åˆå¹¶æœªç»éªŒè¯çš„更改"
msgid "Merge unverified changes?"
-msgstr ""
+msgstr "åˆå¹¶æœªç»éªŒè¯çš„更改?"
msgid "Merge when pipeline succeeds"
msgstr "当æµæ°´çº¿æˆåŠŸæ—¶åˆå¹¶"
msgid "Merge..."
-msgstr ""
+msgstr "åˆå¹¶"
msgid "MergeConflict|Commit to source branch"
msgstr "æ交到æºåˆ†æ”¯"
@@ -22388,14 +22897,14 @@ msgstr "ä¿å­˜è¯„论è‰ç¨¿æ—¶å‘生错误。"
msgid "MergeRequests|Create issue to resolve thread"
msgstr "创建议题以解决主题"
-msgid "MergeRequests|Failed to squash. Should be done manually."
-msgstr "无法压缩(Squash)。应该手动完æˆã€‚"
-
msgid "MergeRequests|Saving the comment failed"
msgstr "ä¿å­˜è¯„论失败"
-msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
-msgstr "此项目ä¸å…许在接å—åˆå¹¶è¯·æ±‚时压缩æ交。"
+msgid "MergeRequests|Squashing failed: Squash the commits locally, resolve any conflicts, then push the branch."
+msgstr ""
+
+msgid "MergeRequests|Squashing not allowed: This project doesn't allow you to squash commits when merging."
+msgstr ""
msgid "MergeRequests|Thread stays resolved"
msgstr "主题ä¿æŒå·²è§£å†³çŠ¶æ€"
@@ -23233,6 +23742,18 @@ msgstr "é‡æ–°éƒ¨ç½²"
msgid "MrDeploymentActions|Stop environment"
msgstr "终止环境"
+msgid "MrList|Assigned to %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from assignee %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from reviewer %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Review requested from %{name}, go to their profile."
+msgstr ""
+
msgid "Multi-project"
msgstr "多项目"
@@ -23266,8 +23787,8 @@ msgstr "必须匹é…%{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}中的%{codeStart
msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr "必须与 %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd} 中的 %{codeStart}geo_node_name%{codeEnd} 匹é…。%{linkStart}了解更多%{linkEnd}"
-msgid "My Awesome Group"
-msgstr "My Awesome Group"
+msgid "My awesome group"
+msgstr ""
msgid "My company or team"
msgstr "我的公å¸æˆ–团队"
@@ -23337,10 +23858,10 @@ msgid "NamespaceStorageSize|push to your repository, create pipelines, create is
msgstr "推é€åˆ°æ‚¨çš„仓库,创建æµæ°´çº¿ï¼Œåˆ›å»ºè®®é¢˜æˆ–添加评论。如需å‡å°‘存储使用,请删除未使用的仓库,产物,wiki,议题和æµæ°´çº¿ã€‚"
msgid "NamespaceUserCap|Pending users must be reviewed and approved by a group owner. Learn more about %{user_caps_link_start}user caps%{link_end} and %{users_pending_approval_link_start}users pending approval%{link_end}."
-msgstr ""
+msgstr "需è¦å®¡æ ¸çš„用户必须由群组所有者审核。了解更多关于%{user_caps_link_start}用户上é™%{link_end}å’Œ%{users_pending_approval_link_start}用户等待批准%{link_end}çš„ä¿¡æ¯ã€‚"
msgid "NamespaceUserCap|View pending approvals"
-msgstr ""
+msgstr "查看等待处ç†çš„审批"
msgid "NamespaceUserCap|Your group has reached its billable member limit"
msgstr "您的群组已达到å¯è®¡è´¹æˆå‘˜ä¸Šé™"
@@ -23886,9 +24407,6 @@ msgstr "未é…置身份验è¯æ–¹æ³•ã€‚"
msgid "No available branches"
msgstr "没有å¯ç”¨çš„分支"
-msgid "No available groups to fork the project."
-msgstr "没有å¯ç”¨çš„群组å¯ä»¥æ´¾ç”Ÿè¯¥é¡¹ç›®ã€‚"
-
msgid "No branches found"
msgstr "未å‘现分支"
@@ -24055,7 +24573,7 @@ msgid "No milestones to show"
msgstr "没有è¦æ˜¾ç¤ºçš„里程碑"
msgid "No namespace"
-msgstr ""
+msgstr "没有命å空间"
msgid "No other labels with such name or description"
msgstr "没有其他具有此类å称或æ述的标记"
@@ -24085,7 +24603,7 @@ msgid "No profiles found"
msgstr "未找到é…置文件"
msgid "No project subscribes to the pipelines in this project."
-msgstr ""
+msgstr "没有项目订阅此项目中的æµæ°´çº¿ã€‚"
msgid "No projects found"
msgstr "未找到项目"
@@ -24099,6 +24617,9 @@ msgstr "无公开群组"
msgid "No ref selected"
msgstr "未选择ref"
+msgid "No regions configured"
+msgstr ""
+
msgid "No related merge requests found."
msgstr "未找到相关的åˆå¹¶è¯·æ±‚。"
@@ -24154,7 +24675,7 @@ msgid "No webhook events"
msgstr "没有 webhook 事件"
msgid "No webhooks enabled. Select trigger events above."
-msgstr ""
+msgstr "未å¯ç”¨ webhook。选择上é¢çš„触å‘事件。"
msgid "No worries, you can still use all the %{strong}%{plan_name}%{strong_close} features for now. You have %{remaining_days} day to renew your subscription."
msgid_plural "No worries, you can still use all the %{strong}%{plan_name}%{strong_close} features for now. You have %{remaining_days} days to renew your subscription."
@@ -24897,6 +25418,9 @@ msgstr "åªæœ‰åœ¨æ——舰版许å¯ä¸‹åˆ›å»ºçš„项目æ‰èƒ½åœ¨å®‰å…¨ä»ªè¡¨æ¿ä¸­ä½¿
msgid "Only reCAPTCHA v2 is supported:"
msgstr "仅支æŒreCAPTCHA v2:"
+msgid "Only required if not using role instance credentials."
+msgstr ""
+
msgid "Only use lowercase letters, numbers, and underscores."
msgstr "仅使用å°å†™å­—æ¯ã€æ•°å­—和下划线。"
@@ -24921,9 +25445,6 @@ msgstr "打开所选项"
msgid "Open a CLI and connect to the cluster you want to install the agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr "打开 CLI 并连接到您想è¦å®‰è£…代ç†çš„集群。 使用此安装方法æ¥æœ€å°åŒ–任何手动步骤。令牌已ç»åŒ…å«åœ¨å‘½ä»¤ä¸­ã€‚"
-msgid "Open epics"
-msgstr "打开å²è¯—"
-
msgid "Open errors"
msgstr "打开错误"
@@ -24963,8 +25484,8 @@ msgstr "å¼€å¯çš„åˆå¹¶è¯·æ±‚"
msgid "Opened issues"
msgstr "å¼€å¯çš„议题"
-msgid "OpenedNDaysAgo|Opened"
-msgstr "创建于"
+msgid "OpenedNDaysAgo|Created"
+msgstr ""
msgid "Opens in a new window"
msgstr "打开一个新窗å£"
@@ -25008,9 +25529,6 @@ msgstr "å¯é€‰"
msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr "å¯é€‰å‚数“variablesâ€å¿…须是哈希。例如:variables[key1]=value1"
-msgid "Optional."
-msgstr "å¯é€‰çš„。"
-
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
msgstr "您å¯ä»¥é€‰æ‹© %{link_to_customize} FogBugz的电å­é‚®ä»¶åœ°å€å’Œç”¨æˆ·å如何被导入到GitLab。"
@@ -25057,28 +25575,28 @@ msgid "Out-of-compliance with this project's policies and should be removed"
msgstr "ä¸ç¬¦åˆè¯¥é¡¹ç›®æ”¿ç­–,应予以删除"
msgid "OutboundRequests|Allow requests to the local network from hooks and services."
-msgstr ""
+msgstr "å…许æ¥è‡ªé’©å­å’ŒæœåŠ¡çš„对本地网络的请求。"
msgid "OutboundRequests|Allow requests to the local network from system hooks"
-msgstr ""
+msgstr "å…许系统钩å­å‘本地网络å‘é€è¯·æ±‚"
msgid "OutboundRequests|Allow requests to the local network from web hooks and services"
-msgstr ""
+msgstr "å…许æ¥è‡ªweb é’©å­å’ŒæœåŠ¡å¯¹æœ¬åœ°ç½‘络的请求。"
msgid "OutboundRequests|Enforce DNS rebinding attack protection"
-msgstr ""
+msgstr "强制执行 DNS é‡æ–°ç»‘定攻击ä¿æŠ¤"
msgid "OutboundRequests|Local IP addresses and domain names that hooks and services may access"
-msgstr ""
+msgstr "é’©å­å’ŒæœåŠ¡å¯ä»¥è®¿é—®çš„本地IP地å€å’ŒåŸŸå。"
msgid "OutboundRequests|Outbound requests"
-msgstr ""
+msgstr "出站请求"
msgid "OutboundRequests|Requests to these domains and IP addresses are accessible to both system hooks and web hooks even when local requests are not allowed. IP ranges such as 1:0:0:0:0:0:0:0/124 and 127.0.0.0/28 are supported. Domain wildcards are not supported. To separate entries use commas, semicolons, or newlines. The allowlist can hold a maximum of 1000 entries. Domains must be IDNA encoded."
msgstr ""
msgid "OutboundRequests|Resolve IP addresses once and uses them to submit requests."
-msgstr ""
+msgstr "解æžIP地å€å¹¶ä½¿ç”¨å®ƒä»¬æ交请求。"
msgid "OutdatedBrowser|GitLab may not work properly, because you are using an outdated web browser."
msgstr "GitLabå¯èƒ½æ— æ³•æ­£å¸¸å·¥ä½œï¼Œå› ä¸ºæ‚¨æ­£åœ¨ä½¿ç”¨è¿‡æ—¶çš„æµè§ˆå™¨ã€‚"
@@ -25798,6 +26316,9 @@ msgstr "Gitaly调用"
msgid "PerformanceBar|Memory"
msgstr "内存"
+msgid "PerformanceBar|Memory report"
+msgstr ""
+
msgid "PerformanceBar|Redis calls"
msgstr "Redis调用"
@@ -25831,18 +26352,12 @@ msgstr "对象"
msgid "PerformanceBar|wall"
msgstr "墙"
-msgid "Performs a rebase but skips triggering a new pipeline"
-msgstr ""
-
msgid "Period in seconds"
msgstr "周期(秒)"
msgid "Permalink"
msgstr "永久链接"
-msgid "Permanently delete project"
-msgstr "永久删除项目"
-
msgid "Permanently remove group"
msgstr "永久删除群组"
@@ -25853,7 +26368,7 @@ msgid "Permissions Help"
msgstr "æƒé™å¸®åŠ©"
msgid "Permissions and group features"
-msgstr ""
+msgstr "æƒé™å’Œç¾¤ç»„功能"
msgid "Personal Access Token"
msgstr "个人访问凭è¯"
@@ -26113,6 +26628,51 @@ msgstr "æµæ°´çº¿ï¼š%{ciStatus}"
msgid "PipelineStatusTooltip|Pipeline: %{ci_status}"
msgstr "æµæ°´çº¿ï¼š%{ci_status}"
+msgid "PipelineWizardDefaultCommitMessage|Add %{filename}"
+msgstr ""
+
+msgid "PipelineWizardDefaultCommitMessage|Update %{filename}"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|At least one entry is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This field is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This value is not valid"
+msgstr ""
+
+msgid "PipelineWizardListWidget|add another step"
+msgstr ""
+
+msgid "PipelineWizardListWidget|remove step"
+msgstr ""
+
+msgid "PipelineWizard|Commit"
+msgstr ""
+
+msgid "PipelineWizard|Commit Message"
+msgstr ""
+
+msgid "PipelineWizard|Commit changes to your file"
+msgstr ""
+
+msgid "PipelineWizard|Commit file to Branch"
+msgstr ""
+
+msgid "PipelineWizard|Commit your new file"
+msgstr ""
+
+msgid "PipelineWizard|The file has been committed."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem committing the changes."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem while checking whether your file already exists in the specified branch."
+msgstr ""
+
msgid "Pipelines"
msgstr "æµæ°´çº¿"
@@ -26132,7 +26692,7 @@ msgid "Pipelines|Are you sure you want to run this pipeline?"
msgstr "您确定è¦è¿è¡Œè¿™æ¡æµæ°´çº¿å—?"
msgid "Pipelines|Auto DevOps"
-msgstr ""
+msgstr "Auto DevOps"
msgid "Pipelines|Build with confidence"
msgstr "自信地构建"
@@ -26227,8 +26787,8 @@ msgstr "æµæ°´çº¿ç¼–辑器"
msgid "Pipelines|Project cache successfully reset."
msgstr "项目缓存é‡ç½®æˆåŠŸã€‚"
-msgid "Pipelines|Revoke"
-msgstr "撤销"
+msgid "Pipelines|Revoke trigger"
+msgstr ""
msgid "Pipelines|Something went wrong while cleaning runners cache."
msgstr "清ç†runner缓存时å‘生错误。"
@@ -26272,6 +26832,12 @@ msgstr "æ­¤GitLab CIé…置有效。"
msgid "Pipelines|This is a child pipeline within the parent pipeline"
msgstr "æ­¤æµæ°´çº¿ä¸ºå…·æœ‰çˆ¶æµæ°´çº¿çš„å­æµæ°´çº¿"
+msgid "Pipelines|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipelines|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipelines|This pipeline will run code originating from a forked project merge request. This means that the code can potentially have security considerations like exposing CI variables."
msgstr "此管é“å°†è¿è¡Œæºè‡ªæ´¾ç”Ÿé¡¹ç›®åˆå¹¶è¯·æ±‚的代ç ã€‚ è¿™æ„味ç€è¯¥ä»£ç å¯èƒ½å­˜åœ¨å®‰å…¨é—®é¢˜ï¼Œå¦‚暴露CIå˜é‡ã€‚"
@@ -26312,28 +26878,28 @@ msgid "Pipelines|Visualize"
msgstr "å¯è§†åŒ–"
msgid "Pipelines|Your changes have been successfully committed. Now redirecting to the new merge request page."
-msgstr ""
-
-msgid "Pipelines|detached"
-msgstr ""
+msgstr "您的更改已æˆåŠŸæ交,现在é‡å®šå‘到新的åˆå¹¶è¯·æ±‚页é¢ã€‚"
msgid "Pipelines|error"
-msgstr ""
+msgstr "错误"
msgid "Pipelines|invalid"
msgstr "无效"
msgid "Pipelines|latest"
-msgstr ""
+msgstr "最新"
-msgid "Pipelines|stuck"
+msgid "Pipelines|merge request"
msgstr ""
-msgid "Pipelines|train"
+msgid "Pipelines|merge train"
msgstr ""
+msgid "Pipelines|stuck"
+msgstr "阻塞"
+
msgid "Pipelines|yaml invalid"
-msgstr ""
+msgstr "Yaml 无效"
msgid "Pipeline|Actions"
msgstr "æ“作"
@@ -26461,6 +27027,12 @@ msgstr "如果åˆå¹¶ï¼Œæ­¤æ›´æ”¹å°†å¢žåŠ æ•´ä½“测试覆盖率。"
msgid "Pipeline|This change will not change the overall test coverage if merged."
msgstr "如果åˆå¹¶ï¼Œæ­¤æ›´æ”¹ä¸ä¼šæ›´æ”¹æ•´ä½“测试覆盖率。"
+msgid "Pipeline|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipeline|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipeline|Trigger author"
msgstr "触å‘者"
@@ -26485,6 +27057,12 @@ msgstr "您将è¦åœæ­¢æµæ°´çº¿ #%{pipelineId}。"
msgid "Pipeline|for"
msgstr "使用æ交"
+msgid "Pipeline|merge request"
+msgstr ""
+
+msgid "Pipeline|merge train"
+msgstr ""
+
msgid "Pipeline|on"
msgstr "于"
@@ -26516,7 +27094,7 @@ msgid "Plan:"
msgstr "计划:"
msgid "Planning hierarchy"
-msgstr ""
+msgstr "规划结构"
msgid "PlantUML"
msgstr "PlantUML"
@@ -26534,10 +27112,10 @@ msgid "Please %{link_to_register} or %{link_to_sign_in} to comment"
msgstr "想è¦è¯„论请 %{link_to_register} 或 %{link_to_sign_in}"
msgid "Please %{registerLinkStart}register%{registerLinkEnd} or %{signInLinkStart}sign in%{signInLinkEnd} to reply."
-msgstr ""
+msgstr "请先%{registerLinkStart}注册%{registerLinkEnd}或%{signInLinkStart}登录%{signInLinkEnd},然åŽå†å›žå¤ã€‚"
msgid "Please %{registerLinkStart}register%{registerLinkEnd} or %{signInLinkStart}sign in%{signInLinkEnd} to start a new discussion."
-msgstr ""
+msgstr "请先%{registerLinkStart}注册%{registerLinkEnd}或%{signInLinkStart}登录%{signInLinkEnd},然åŽå¼€å§‹æ–°è®¨è®ºã€‚"
msgid "Please %{startTagRegister}register%{endRegisterTag} or %{startTagSignIn}sign in%{endSignInTag} to reply"
msgstr "请%{startTagRegister}注册%{endRegisterTag}或%{startTagSignIn}登录%{endSignInTag}å†å›žå¤"
@@ -26623,9 +27201,6 @@ msgstr "请输入有效的数字"
msgid "Please enter a valid time interval"
msgstr "请输入有效的时间间隔"
-msgid "Please enter or upload a valid license."
-msgstr "请输入或上传有效的许å¯è¯ã€‚"
-
msgid "Please enter your current password."
msgstr "请输入您的当å‰å¯†ç ã€‚"
@@ -26734,9 +27309,6 @@ msgstr "请å°è¯•åˆ·æ–°é¡µé¢ã€‚如果问题ä»ç„¶å­˜åœ¨ï¼Œè¯·è”系支æŒäººå‘˜
msgid "Please type %{phrase_code} to proceed or close this modal to cancel."
msgstr "请输入%{phrase_code}以继续或关闭此对è¯æ¡†ä»¥å–消。"
-msgid "Please type the following to confirm:"
-msgstr "请输入以下内容以确认:"
-
msgid "Please use this form to report to the admin users who create spam issues, comments or behave inappropriately."
msgstr "请使用此表å•å‘管ç†å‘˜æŠ¥å‘Šåˆ›å»ºåžƒåœ¾è®®é¢˜ã€è¯„论或行为ä¸å½“的用户。"
@@ -26764,12 +27336,27 @@ msgstr "指å‘您需è¦çš„任何链接:文档,生æˆçš„二进制文件或其
msgid "Policies"
msgstr "ç­–ç•¥"
+msgid "Policy '%{escalation_policy_name}' does not exist."
+msgstr ""
+
msgid "Policy management project does have any policies in %{policy_path}"
msgstr "策略管ç†é¡¹ç›®çš„任何策略ä½äºŽ%{policy_path}"
msgid "Policy project doesn't exist"
msgstr "策略项目ä¸å­˜åœ¨"
+msgid "PolicyRuleMultiSelect|%{firstLabel} +%{numberOfAdditionalLabels} more"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|All %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select all"
+msgstr ""
+
msgid "Polling interval multiplier"
msgstr "轮询间隔å€æ•°"
@@ -26894,7 +27481,7 @@ msgid "Preferences|Use relative times"
msgstr "使用相对时间"
msgid "Preferences|When you type in a description or comment box, selected text is surrounded by the corresponding character after typing one of the following characters: %{supported_characters}."
-msgstr ""
+msgstr "当您在æ述或评论框中键入时,在键入以下字符之一åŽï¼Œé€‰å®šçš„文本将被相应的字符包围:%{supported_characters}。"
msgid "Prev"
msgstr "上一页"
@@ -26998,6 +27585,9 @@ msgstr "ç§æœ‰é¡¹ç›®åˆ†é’Ÿæˆæœ¬ç³»æ•°"
msgid "Private projects can be created in your personal namespace with:"
msgstr "ç§æœ‰é¡¹ç›®å¯ä»¥åœ¨ä¸ªäººå称空间中创建:"
+msgid "Problem with %{name} command: %{message}."
+msgstr ""
+
msgid "Proceed"
msgstr "继续"
@@ -27122,7 +27712,7 @@ msgid "Profiles|Avatar will be removed. Are you sure?"
msgstr "å³å°†åˆ é™¤å¤´åƒã€‚确定继续å—?"
msgid "Profiles|Begins with %{ssh_key_algorithms}."
-msgstr ""
+msgstr "以 %{ssh_key_algorithms} 开头。"
msgid "Profiles|Bio"
msgstr "自我介ç»"
@@ -27326,7 +27916,7 @@ msgid "Profiles|Remove avatar"
msgstr "删除头åƒ"
msgid "Profiles|Select a service to sign in with."
-msgstr ""
+msgstr "选择è¦ç™»å½•çš„æœåŠ¡ã€‚"
msgid "Profiles|Set new profile picture"
msgstr "设置新个人资料图片"
@@ -27472,6 +28062,9 @@ msgstr "当å‰ä»£ç ä»“库中使用的编程语言"
msgid "Progress"
msgstr "进度"
+msgid "Progress tracking"
+msgstr ""
+
msgid "Project"
msgstr "项目"
@@ -27703,6 +28296,9 @@ msgstr "覆盖率"
msgid "ProjectQualitySummary|Failure"
msgstr "失败"
+msgid "ProjectQualitySummary|Get insight into the overall percentage of tests in your project that succeed, fail and are skipped."
+msgstr ""
+
msgid "ProjectQualitySummary|Latest pipeline results"
msgstr "最新æµæ°´çº¿ç»“æžœ"
@@ -27721,6 +28317,12 @@ msgstr "查看完整报告"
msgid "ProjectQualitySummary|See project Code Coverage Statistics"
msgstr "查看项目代ç è¦†ç›–率统计"
+msgid "ProjectQualitySummary|Set up test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|Set up test runs (opens in a new tab)"
+msgstr ""
+
msgid "ProjectQualitySummary|Skipped"
msgstr "跳过"
@@ -27896,13 +28498,13 @@ msgid "ProjectSettings|Checkbox is visible and unselected by default."
msgstr "默认情况下,å¤é€‰æ¡†æ˜¯å¯è§å’Œæœªé€‰ä¸­çš„。"
msgid "ProjectSettings|Choose the method, options, checks, and squash options for merge requests. You can also set up merge request templates for different actions."
-msgstr ""
+msgstr "为åˆå¹¶è¯·æ±‚选择方法ã€é€‰é¡¹ã€æ£€æŸ¥å’ŒåŽ‹ç¼©ã€‚您还å¯ä»¥ä¸ºä¸åŒçš„æ“作设置åˆå¹¶è¯·æ±‚模æ¿ã€‚"
msgid "ProjectSettings|Choose your merge method, merge options, merge checks, and merge suggestions."
msgstr "选择åˆå¹¶æ–¹æ³•ã€åˆå¹¶é€‰é¡¹ï¼Œåˆå¹¶æ£€æŸ¥ä»¥åŠåˆå¹¶å»ºè®®"
msgid "ProjectSettings|Choose your merge method, options, checks, and squash options."
-msgstr ""
+msgstr "选择您的åˆå¹¶æ–¹æ³•ã€é€‰é¡¹ã€æ£€æŸ¥å’ŒåŽ‹ç¼©é€‰é¡¹ã€‚"
msgid "ProjectSettings|Configure your project resources and monitor their health."
msgstr "é…置您的项目资æºå¹¶ç›‘控它们的è¿è¡ŒçŠ¶å†µã€‚"
@@ -27980,10 +28582,10 @@ msgid "ProjectSettings|Highlight the usage of hidden unicode characters. These h
msgstr "çªå‡ºæ˜¾ç¤ºéšè—çš„ unicode 字符的用法。这些对从å³åˆ°å·¦çš„语言无害,但也å¯ç”¨äºŽæ½œåœ¨çš„æ¼æ´žåˆ©ç”¨ã€‚"
msgid "ProjectSettings|Housekeeping, export, archive, change path, transfer, and delete."
-msgstr ""
+msgstr "例行维护ã€å¯¼å‡ºã€å½’æ¡£ã€æ›´æ”¹è·¯å¾„ã€ä¼ è¾“和删除。"
msgid "ProjectSettings|If merge trains are enabled, merging is only possible if the branch can be rebased without conflicts."
-msgstr ""
+msgstr "如果å¯ç”¨äº†åˆå¹¶é˜Ÿåˆ—,则åªæœ‰åœ¨å¯ä»¥é‡æ–°è®¾ç½®åˆ†æ”¯è€Œä¸å‘生冲çªçš„情况下æ‰èƒ½è¿›è¡Œåˆå¹¶ã€‚"
msgid "ProjectSettings|Internal"
msgstr "内部"
@@ -27997,14 +28599,20 @@ msgstr "议题"
msgid "ProjectSettings|LFS objects from this repository are available to forks. %{linkStart}How do I remove them?%{linkEnd}"
msgstr "此仓库中的 LFS 对象å¯ä¾›æ´¾ç”Ÿã€‚ %{linkStart}我如何移除它们?%{linkEnd}"
+msgid "ProjectSettings|Learn about commit history."
+msgstr ""
+
+msgid "ProjectSettings|Leave empty to use default template."
+msgstr ""
+
msgid "ProjectSettings|Manage who can see the project in the public access directory."
msgstr "管ç†è°å¯ä»¥åœ¨å…¬å…±è®¿é—®ç›®å½•ä¸­çœ‹åˆ°è¿™ä¸ªé¡¹ç›®ã€‚"
msgid "ProjectSettings|Manages large files such as audio, video, and graphics files."
msgstr "管ç†å¤§åž‹æ–‡ä»¶ï¼Œä¾‹å¦‚音频ã€è§†é¢‘和图形文件。"
-msgid "ProjectSettings|Maximum 500 characters."
-msgstr "最多500个字符。"
+msgid "ProjectSettings|Maximum %{maxLength} characters."
+msgstr ""
msgid "ProjectSettings|Merge checks"
msgstr "åˆå¹¶æ£€æŸ¥"
@@ -28031,7 +28639,7 @@ msgid "ProjectSettings|Merge requests approved for merge are queued, and pipelin
msgstr "已批准的åˆå¹¶è¯·æ±‚已排队,æµæ°´çº¿åœ¨åˆå¹¶å‰éªŒè¯æºå’Œç›®æ ‡åˆ†æ”¯çš„åˆå¹¶ç»“果。 %{link_start}什么是åˆå¹¶é˜Ÿåˆ—?%{link_end}"
msgid "ProjectSettings|Merge requests can't be merged if the latest pipeline did not succeed or is still running."
-msgstr ""
+msgstr "如果最新æµæ°´çº¿æœªæˆåŠŸæˆ–ä»åœ¨è¿è¡Œï¼Œåˆ™æ— æ³•åˆå¹¶åˆå¹¶è¯·æ±‚。"
msgid "ProjectSettings|Merge suggestions"
msgstr "åˆå¹¶å»ºè®®"
@@ -28144,6 +28752,9 @@ msgstr "压缩æ交时使用的æ交消æ¯ã€‚"
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
msgstr "在此派生项目中创建的åˆå¹¶è¯·æ±‚的默认目标项目。"
+msgid "ProjectSettings|The default template will be applied on save."
+msgstr ""
+
msgid "ProjectSettings|These checks must pass before merge requests can be merged."
msgstr "必须通过这些检查æ‰èƒ½åˆå¹¶åˆå¹¶è¯·æ±‚。"
@@ -28181,7 +28792,7 @@ msgid "ProjectSettings|View and edit files in this project."
msgstr "查看和编辑此项目中的文件。"
msgid "ProjectSettings|View and edit files in this project. Non-project members have only read access."
-msgstr ""
+msgstr "查看和编辑此项目中的文件。éžé¡¹ç›®æˆå‘˜åªæœ‰è¯»å–æƒé™ã€‚"
msgid "ProjectSettings|View project analytics."
msgstr "查看项目分æžã€‚"
@@ -28198,9 +28809,12 @@ msgstr "关于潜在的ä¸éœ€è¦çš„字符的警告"
msgid "ProjectSettings|What are badges?"
msgstr "什么是徽章?"
-msgid "ProjectSettings|When merge request pipelines are enabled in the CI/CD configuration file, pipelines validate the combined results of the source and target branches. %{link_start}How to configure merge request pipelines?%{link_end}"
+msgid "ProjectSettings|What are merge trains?"
msgstr ""
+msgid "ProjectSettings|When merge request pipelines are enabled in the CI/CD configuration file, pipelines validate the combined results of the source and target branches. %{link_start}How to configure merge request pipelines?%{link_end}"
+msgstr "在 CI/CD é…置文件中å¯ç”¨åˆå¹¶è¯·æ±‚æµæ°´çº¿æ—¶ï¼Œæµæ°´çº¿ä¼šéªŒè¯æºåˆ†æ”¯å’Œç›®æ ‡åˆ†æ”¯çš„组åˆç»“果。%{link_start}如何é…ç½®åˆå¹¶è¯·æ±‚æµæ°´çº¿ï¼Ÿ%{link_end}"
+
msgid "ProjectSettings|When there is a merge conflict, the user is given the option to rebase."
msgstr "当出现åˆå¹¶å†²çªæ—¶ï¼Œç”¨æˆ·å¯ä»¥é€‰æ‹©å˜åŸºï¼ˆrebase)。"
@@ -28315,6 +28929,9 @@ msgstr "按项目所包å«æœ€é«˜å±é™©ç¨‹åº¦å®‰å…¨æ¼æ´žåˆ†çº§"
msgid "Projects are organized into groups"
msgstr "项目被组织æˆç¾¤ç»„"
+msgid "Projects are where you store your code, access issues, wiki and other features of GitLab."
+msgstr ""
+
msgid "Projects contributed to"
msgstr "贡献的项目"
@@ -28330,12 +28947,6 @@ msgstr "å¯ä»¥è®¿é—®çš„项目"
msgid "Projects to index"
msgstr "è¦ç´¢å¼•çš„项目"
-msgid "Projects will be permanently deleted after a %{waiting_period}-day waiting period."
-msgstr "项目将在 %{waiting_period}天等待期åŽæ°¸ä¹…删除。"
-
-msgid "Projects will be permanently deleted immediately."
-msgstr "项目将立å³è¢«æ°¸ä¹…删除。"
-
msgid "Projects with critical vulnerabilities"
msgstr "具有严é‡æ¼æ´žçš„项目"
@@ -28420,6 +29031,9 @@ msgstr "导入"
msgid "ProjectsNew|Import project"
msgstr "导入项目"
+msgid "ProjectsNew|Include a Getting Started README"
+msgstr ""
+
msgid "ProjectsNew|Initialize repository with a README"
msgstr "使用自述文件åˆå§‹åŒ–仓库"
@@ -28435,6 +29049,9 @@ msgstr "项目é…ç½®"
msgid "ProjectsNew|Project description %{tag_start}(optional)%{tag_end}"
msgstr "项目æè¿°%{tag_start}(å¯é€‰)%{tag_end}"
+msgid "ProjectsNew|Recommended if you're new to GitLab"
+msgstr ""
+
msgid "ProjectsNew|Run CI/CD for external repository"
msgstr "为外部仓库è¿è¡ŒCI/CD"
@@ -28852,6 +29469,9 @@ msgstr "切æ¢ä»£ç æ‰€æœ‰è€…的批准"
msgid "ProtectedBranch|Unprotect"
msgstr "å–消ä¿æŠ¤"
+msgid "ProtectedBranch|Unprotect branch"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr "什么是å—ä¿æŠ¤çš„分支?"
@@ -28879,6 +29499,9 @@ msgstr "ä¿æŠ¤éƒ¨ç½²çŽ¯å¢ƒ"
msgid "ProtectedEnvironment|Protected Environment (%{protected_environments_count})"
msgstr "å—ä¿æŠ¤çš„环境 (%{protected_environments_count})"
+msgid "ProtectedEnvironment|Required approvals"
+msgstr ""
+
msgid "ProtectedEnvironment|Select an environment"
msgstr "选择一个环境"
@@ -28900,11 +29523,14 @@ msgstr "您的环境已å—到ä¿æŠ¤ã€‚"
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr "环境已ç»ä¸è¢«ä¿æŠ¤"
+msgid "ProtectedTags|Unprotect tag"
+msgstr ""
+
msgid "ProtectedTags|default"
msgstr "默认"
-msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
-msgstr "默认情况下,å—ä¿æŠ¤çš„分支会é™åˆ¶è°å¯ä»¥ä¿®æ”¹æ ‡ç­¾ã€‚"
+msgid "ProtectedTag|By default, protected tags restrict who can modify the tag."
+msgstr ""
msgid "ProtectedTag|Learn more."
msgstr "了解更多。"
@@ -28966,6 +29592,9 @@ msgstr "公开æµæ°´çº¿"
msgid "Public projects Minutes cost factor"
msgstr "公开项目分钟æˆæœ¬ç³»æ•°"
+msgid "Public projects are an easy way to allow everyone to have read-only access."
+msgstr ""
+
msgid "Publish to status page"
msgstr "å‘布到状æ€é¡µ"
@@ -29122,9 +29751,6 @@ msgstr "总æ交次数:%{total_commits_count}"
msgid "QualitySummary|Project quality"
msgstr "项目质é‡"
-msgid "Quarters"
-msgstr "季度"
-
msgid "Query"
msgstr "查询"
@@ -29209,6 +29835,9 @@ msgstr "在%{link_to_promo}上阅读更多关于 GitLab çš„ä¿¡æ¯ã€‚"
msgid "Read more about project permissions %{help_link_open}here%{help_link_close}"
msgstr "于%{help_link_open}此处%{help_link_close}了解有关项目æƒé™çš„更多信æ¯"
+msgid "Read more about related epics"
+msgstr ""
+
msgid "Read more about related issues"
msgstr "了解更多关于相关议题的信æ¯"
@@ -29239,10 +29868,7 @@ msgstr "Rebaseæºåˆ†æ”¯"
msgid "Rebase source branch on the target branch."
msgstr "在目标分支上Rebaseæºåˆ†æ”¯ã€‚"
-msgid "Rebase without CI"
-msgstr ""
-
-msgid "Rebases and triggers a pipeline"
+msgid "Rebase without pipeline"
msgstr ""
msgid "Recaptcha verified?"
@@ -29293,9 +29919,6 @@ msgstr "最近使用"
msgid "Reconfigure"
msgstr "é‡æ–°é…ç½®"
-msgid "Recovering projects"
-msgstr "æ¢å¤é¡¹ç›®"
-
msgid "Recovery Codes"
msgstr "æ¢å¤ç "
@@ -29315,7 +29938,7 @@ msgid "Reduce project visibility"
msgstr "é™ä½Žé¡¹ç›®å¯è§æ€§"
msgid "Reduce risk and triage fewer vulnerabilities with security training"
-msgstr ""
+msgstr "通过安全培训é™ä½Žé£Žé™©å¹¶å‡å°‘æ¼æ´žç±»åž‹"
msgid "Reduce this project’s visibility?"
msgstr "é™ä½Žæ­¤é¡¹ç›®å¯è§æ€§å—?"
@@ -29354,6 +29977,12 @@ msgstr "é‡æ–°ç”Ÿæˆå®žä¾‹ ID,å¯èƒ½ä¼šæ‚¨ä½¿ç”¨çš„部分客户端的集æˆå¤±
msgid "Regex pattern"
msgstr "正则表达å¼"
+msgid "Region"
+msgstr ""
+
+msgid "Regions"
+msgstr ""
+
msgid "Register"
msgstr "注册"
@@ -29583,9 +30212,6 @@ msgstr "删除所有或特定标记"
msgid "Remove all or specific reviewer(s)"
msgstr "删除所有或特定的审核者"
-msgid "Remove approver"
-msgstr "移除核准人"
-
msgid "Remove approvers"
msgstr "删除核准人"
@@ -29601,6 +30227,9 @@ msgstr "删除指派人"
msgid "Remove attention request"
msgstr "删除关注请求"
+msgid "Remove attention request(s)"
+msgstr ""
+
msgid "Remove avatar"
msgstr "删除头åƒ"
@@ -29739,6 +30368,9 @@ msgstr "已删除所有标签。"
msgid "Removed an issue from an epic."
msgstr "从å²è¯—中移除了一个议题。"
+msgid "Removed attention from %{users_sentence}."
+msgstr ""
+
msgid "Removed attention request from @%{username}"
msgstr "已从 @%{username} 移除关注请求"
@@ -29790,6 +30422,9 @@ msgstr "删除所有标记。"
msgid "Removes an issue from an epic."
msgstr "从å²è¯—中移除一个议题。"
+msgid "Removes attention from %{users_sentence}."
+msgstr ""
+
msgid "Removes parent epic %{epic_ref}."
msgstr "删除父å²è¯—%{epic_ref}。"
@@ -29901,6 +30536,9 @@ msgstr "报告滥用"
msgid "Report abuse to admin"
msgstr "å‘管ç†å‘˜æŠ¥å‘Šæ»¥ç”¨è¡Œä¸º"
+msgid "Report is generating and will be sent to your email address."
+msgstr ""
+
msgid "Reported %{timeAgo} by %{reportedBy}"
msgstr "由%{reportedBy}报告于%{timeAgo}"
@@ -30156,7 +30794,7 @@ msgid "Repository size is above the limit."
msgstr "仓库大å°è¶…过é™åˆ¶ã€‚"
msgid "Repository size limit (MB)"
-msgstr ""
+msgstr "仓库大å°é™åˆ¶ï¼ˆMB)"
msgid "Repository storage"
msgstr "仓库存储"
@@ -30185,6 +30823,15 @@ msgstr "请求一个新的"
msgid "Request attention"
msgstr "请求关注"
+msgid "Request attention from %{users_sentence}."
+msgstr ""
+
+msgid "Request attention from assignee or reviewer"
+msgstr ""
+
+msgid "Request attention from assignee(s) or reviewer(s)"
+msgstr ""
+
msgid "Request attention to review"
msgstr "请求关注审核"
@@ -30209,6 +30856,9 @@ msgstr "已请求"
msgid "Requested %{time_ago}"
msgstr "请求的 %{time_ago}"
+msgid "Requested attention from %{users_sentence}."
+msgstr ""
+
msgid "Requested attention from @%{username}"
msgstr "请求æ¥è‡ª @%{username} 的注æ„事项"
@@ -30252,7 +30902,7 @@ msgid "Required only if you are not using role instance credentials."
msgstr "仅当您没有使用角色实例凭æ®æ—¶æ‰éœ€è¦ã€‚"
msgid "Requirement"
-msgstr ""
+msgstr "需求"
msgid "Requirement %{reference} has been added"
msgstr "需求%{reference}已添加"
@@ -30421,6 +31071,9 @@ msgstr "æ¢å¤ç¾¤ç»„"
msgid "Restore project"
msgstr "æ¢å¤é¡¹ç›®"
+msgid "Restoring projects"
+msgstr ""
+
msgid "Restoring the group will prevent the group, its subgroups and projects from being removed on this date."
msgstr "æ¢å¤è¯¥ç¾¤ç»„将防止该群组åŠå…¶å­ç¾¤ç»„和项目在此日期被删除。"
@@ -30446,11 +31099,14 @@ msgid "Resync"
msgstr "é‡æ–°åŒæ­¥"
msgid "Retrieving the compliance report failed. Refresh the page and try again."
-msgstr ""
+msgstr "检索åˆè§„性报告失败。请刷新页é¢å¹¶é‡è¯•ã€‚"
msgid "Retry"
msgstr "é‡è¯•"
+msgid "Retry failed jobs"
+msgstr ""
+
msgid "Retry job"
msgstr "é‡è¯•ä½œä¸š"
@@ -30497,9 +31153,6 @@ msgstr "查看最新应用"
msgid "Review changes"
msgstr "审阅更改"
-msgid "Review requested from %{name}"
-msgstr "æ¥è‡ª%{name}的审核请求"
-
msgid "Review requests for you"
msgstr "您的审核请求"
@@ -30544,7 +31197,7 @@ msgid "Revoked"
msgstr "已撤销"
msgid "Revoked access token %{access_token_name}!"
-msgstr ""
+msgstr "已撤销访问令牌 %{access_token_name}ï¼"
msgid "Revoked impersonation token %{token_name}!"
msgstr "撤销身份模拟令牌 %{token_name}ï¼"
@@ -30571,7 +31224,7 @@ msgid "Roadmap"
msgstr "路线图"
msgid "Roadmap settings"
-msgstr ""
+msgstr "路线图设置"
msgid "Role"
msgstr "角色"
@@ -30661,6 +31314,9 @@ msgid "Runners|Architecture"
msgstr "架构"
msgid "Runners|Assigned Group"
+msgstr "指派群组"
+
+msgid "Runners|Assigned Projects (%{projectCount})"
msgstr ""
msgid "Runners|Associated with one or more projects"
@@ -30676,13 +31332,13 @@ msgid "Runners|Can run untagged jobs"
msgstr "å¯ä»¥è¿è¡Œæœªæ ‡è®°çš„作业"
msgid "Runners|Change to project runner"
-msgstr ""
+msgstr "更改为项目 runner"
msgid "Runners|Command to register runner"
msgstr "注册runner的命令"
msgid "Runners|Configuration"
-msgstr ""
+msgstr "é…ç½®"
msgid "Runners|Copy instructions"
msgstr "å¤åˆ¶è¯´æ˜Ž"
@@ -30703,7 +31359,7 @@ msgid "Runners|Description"
msgstr "æè¿°"
msgid "Runners|Details"
-msgstr ""
+msgstr "详情"
msgid "Runners|Download and install binary"
msgstr "下载并安装二进制文件"
@@ -30732,6 +31388,9 @@ msgstr "安装Runner"
msgid "Runners|Instance"
msgstr "实例"
+msgid "Runners|Jobs"
+msgstr ""
+
msgid "Runners|Last contact"
msgstr "最åŽè”ç³»"
@@ -30769,13 +31428,13 @@ msgid "Runners|Offline"
msgstr "离线"
msgid "Runners|Offline runners"
-msgstr ""
+msgstr "离线 Runners"
msgid "Runners|Online"
msgstr "在线"
msgid "Runners|Online runners"
-msgstr ""
+msgstr "在线 Runners"
msgid "Runners|Paused"
msgstr "已暂åœ"
@@ -30811,7 +31470,7 @@ msgid "Runners|Registration token copied!"
msgstr "注册令牌已å¤åˆ¶ï¼"
msgid "Runners|Reset token"
-msgstr ""
+msgstr "é‡ç½®ä»¤ç‰Œ"
msgid "Runners|Revision"
msgstr "版本"
@@ -30825,9 +31484,6 @@ msgstr "Runner #%{runner_id}"
msgid "Runners|Runner %{name} was deleted"
msgstr "Runner %{name} 已删除"
-msgid "Runners|Runner ID"
-msgstr "Runner ID"
-
msgid "Runners|Runner assigned to project."
msgstr "分é…给项目的runner"
@@ -30853,7 +31509,7 @@ msgid "Runners|Runners"
msgstr "Runner"
msgid "Runners|Runs untagged jobs"
-msgstr ""
+msgstr "è¿è¡Œæœªæ ‡è®°çš„作业"
msgid "Runners|Shared runners are available to every project in a GitLab instance. If you want a runner to build only specific projects, restrict the project in the table below. After you restrict a runner to a project, you cannot change it back to a shared runner."
msgstr "共享Runnerå¯ç”¨äºŽ GitLab 实例中的æ¯ä¸ªé¡¹ç›®ã€‚如果您希望Runner仅构建特定项目,请é™åˆ¶ä¸‹è¡¨ä¸­çš„项目。当é™åˆ¶Runner的特定项目åŽï¼Œæ‚¨æ— æ³•å°†å…¶æ”¹å›žå…±äº«Runner。"
@@ -30862,7 +31518,7 @@ msgid "Runners|Show runner installation and registration instructions"
msgstr "显示runner安装和注册说明"
msgid "Runners|Show runner installation instructions"
-msgstr ""
+msgstr "显示 Runner 安装说明"
msgid "Runners|Something went wrong while fetching runner data."
msgstr "获å–Runneræ•°æ®æ—¶å‡ºé”™ã€‚"
@@ -30874,7 +31530,7 @@ msgid "Runners|Stale"
msgstr "Stale"
msgid "Runners|Stale runners"
-msgstr ""
+msgstr "过期 runners"
msgid "Runners|Status"
msgstr "状æ€"
@@ -30975,6 +31631,9 @@ msgstr "特定"
msgid "Runners|stale"
msgstr "stale"
+msgid "Runner|This runner has not run any jobs."
+msgstr ""
+
msgid "Running"
msgstr "è¿è¡Œä¸­"
@@ -31089,6 +31748,24 @@ msgstr "ä¿å­˜ä¸­"
msgid "Saving project."
msgstr "正在ä¿å­˜é¡¹ç›®ã€‚"
+msgid "ScanResultPolicy|%{ifLabelStart}if%{ifLabelEnd} %{scanners} scan in an open merge request targeting the %{branches} branch(es) finds %{vulnerabilitiesAllowed} or more %{severities} vulnerabilities that are %{vulnerabilityStates}"
+msgstr ""
+
+msgid "ScanResultPolicy|%{thenLabelStart}Then%{thenLabelEnd} Require approval from %{approvalsRequired} of the following approvers: %{approvers}"
+msgstr ""
+
+msgid "ScanResultPolicy|add an approver"
+msgstr ""
+
+msgid "ScanResultPolicy|scanners"
+msgstr ""
+
+msgid "ScanResultPolicy|severity levels"
+msgstr ""
+
+msgid "ScanResultPolicy|vulnerability states"
+msgstr ""
+
msgid "Scanner"
msgstr "扫æ工具"
@@ -31221,6 +31898,9 @@ msgstr "æœç´¢ç¾¤ç»„"
msgid "Search for a user"
msgstr "æœç´¢ç”¨æˆ·"
+msgid "Search for an emoji"
+msgstr ""
+
msgid "Search for projects, issues, etc."
msgstr "æœç´¢é¡¹ç›®ã€è®®é¢˜ç­‰ç­‰â€¦"
@@ -31397,18 +32077,12 @@ msgstr "密ç "
msgid "Secret Detection"
msgstr "密ç æ£€æµ‹"
-msgid "Secret access key"
-msgstr "Secret 访问密钥"
-
msgid "Secret token"
msgstr "Secret令牌"
msgid "Secure token that identifies an external storage request."
msgstr "识别外部存储请求的安全令牌。"
-msgid "SecureCodeWarrior"
-msgstr "SecureCodeWarrior"
-
msgid "Security"
msgstr "安全"
@@ -31433,9 +32107,6 @@ msgstr "安全报告已过时。请使用目标分支(%{targetBranchName})中的
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr "安全报告已过时。请在目标分支(%{targetBranchName})上è¿è¡Œ%{newPipelineLinkStart}æ–°çš„æµæ°´çº¿%{newPipelineLinkEnd}"
-msgid "Security training with guide and learning pathways."
-msgstr "具有指导和学习途径的安全培训。"
-
msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr "当安全报告包å«æ–°æ¼æ´žæ—¶éœ€è¦åˆå¹¶è¯·æ±‚审批。"
@@ -31461,7 +32132,7 @@ msgid "SecurityApprovals|License-Check"
msgstr "许å¯è¯æ£€æŸ¥"
msgid "SecurityApprovals|Requires approval for Denied licenses. %{linkStart}Learn more.%{linkEnd}"
-msgstr ""
+msgstr "需è¦å¯¹è¢«æ‹’ç»çš„许å¯è¯è¿›è¡Œæ‰¹å‡†ã€‚%{linkStart}了解更多。%{linkEnd}"
msgid "SecurityApprovals|Requires approval for decreases in test coverage. %{linkStart}Learn more.%{linkEnd}"
msgstr "测试覆盖率é™ä½Žï¼Œéœ€æ‰¹å‡†ã€‚%{linkStart}了解更多。%{linkEnd}"
@@ -31538,8 +32209,8 @@ msgstr "使用应用程åºå®‰å…¨åŠŸèƒ½ç«‹å³å¼€å§‹é£Žé™©åˆ†æžå’Œè¡¥æ•‘。从 SA
msgid "SecurityConfiguration|Manage corpus"
msgstr "管ç†è¯­æ–™åº“"
-msgid "SecurityConfiguration|Manage corpus files used as mutation sources in coverage fuzzing."
-msgstr "管ç†åœ¨è¦†ç›–模糊测试中用作å˜å¼‚æºçš„语料库文件。"
+msgid "SecurityConfiguration|Manage corpus files used as seed inputs with coverage-guided fuzzing."
+msgstr ""
msgid "SecurityConfiguration|Manage profiles for use by DAST scans."
msgstr "管ç†ä¾› DAST 扫æ使用的é…置文件。"
@@ -31593,7 +32264,7 @@ msgid "SecurityConfiguration|Vulnerability details and statistics in the merge r
msgstr "åˆå¹¶è¯·æ±‚中的æ¼æ´žè¯¦ç»†ä¿¡æ¯å’Œç»Ÿè®¡"
msgid "SecurityOrchestration| or "
-msgstr ""
+msgstr "或 "
msgid "SecurityOrchestration|%{branches} %{plural}"
msgstr "%{branches} %{plural}"
@@ -31604,15 +32275,15 @@ msgstr "%{branches} 和 %{lastBranch} %{plural}"
msgid "SecurityOrchestration|.yaml preview"
msgstr ".yaml 预览"
-msgid "SecurityOrchestration|Action"
-msgstr "行动"
-
msgid "SecurityOrchestration|Actions"
msgstr "行动"
msgid "SecurityOrchestration|Add rule"
msgstr "添加规则"
+msgid "SecurityOrchestration|After dismissing the alert, the information will never be shown again."
+msgstr ""
+
msgid "SecurityOrchestration|All policies"
msgstr "所有策略"
@@ -31628,8 +32299,8 @@ msgstr "选择项目"
msgid "SecurityOrchestration|Description"
msgstr "æè¿°"
-msgid "SecurityOrchestration|Disabled"
-msgstr "ç¦ç”¨"
+msgid "SecurityOrchestration|Don't show the alert anymore"
+msgstr ""
msgid "SecurityOrchestration|Edit policy"
msgstr "编辑策略"
@@ -31637,23 +32308,23 @@ msgstr "编辑策略"
msgid "SecurityOrchestration|Edit policy project"
msgstr "编辑策略项目"
+msgid "SecurityOrchestration|Empty policy name"
+msgstr ""
+
msgid "SecurityOrchestration|Enabled"
msgstr "å¯ç”¨"
msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
msgstr "强制此项目的安全性。 %{linkStart}更多信æ¯ã€‚%{linkEnd}"
-msgid "SecurityOrchestration|Executes a %{scanType} scan"
-msgstr "执行 %{scanType} 扫æ"
-
msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
msgstr "如果您正在使用Auto DevOps,如果您改å˜äº†æ­¤éƒ¨åˆ†çš„策略,您的 %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} 文件将ä¸ä¼šè¢«æ›´æ–° Auto DevOps 用户应按照 %{linkStart}容器网络策略文档%{linkEnd}进行更改。"
msgid "SecurityOrchestration|Invalid policy type"
-msgstr ""
+msgstr "无效的策略类型"
-msgid "SecurityOrchestration|Latest scan"
-msgstr "最新扫æ"
+msgid "SecurityOrchestration|Latest scan run against %{agent}"
+msgstr ""
msgid "SecurityOrchestration|Network"
msgstr "网络"
@@ -31661,20 +32332,32 @@ msgstr "网络"
msgid "SecurityOrchestration|New policy"
msgstr "æ–°ç­–ç•¥"
+msgid "SecurityOrchestration|No actions defined - policy will not run."
+msgstr ""
+
+msgid "SecurityOrchestration|No description"
+msgstr ""
+
msgid "SecurityOrchestration|No rules defined - policy will not run."
msgstr "未定义规则 - 策略无法è¿è¡Œã€‚"
+msgid "SecurityOrchestration|Not enabled"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr "åªæœ‰æ‰€æœ‰è€…å¯ä»¥æ›´æ–°å®‰å…¨ç­–略项目"
msgid "SecurityOrchestration|Policies"
msgstr "ç­–ç•¥"
-msgid "SecurityOrchestration|Policy cannot be enabled for non-existing branches (%{branches})"
+msgid "SecurityOrchestration|Policy Type"
msgstr ""
+msgid "SecurityOrchestration|Policy cannot be enabled for non-existing branches (%{branches})"
+msgstr "无法为ä¸å­˜åœ¨çš„分支å¯ç”¨ç­–ç•¥ (%{branches})"
+
msgid "SecurityOrchestration|Policy cannot be enabled without branch information"
-msgstr ""
+msgstr "没有分支信æ¯å°±æ— æ³•å¯ç”¨ç­–ç•¥"
msgid "SecurityOrchestration|Policy description"
msgstr "ç­–ç•¥æè¿°"
@@ -31686,7 +32369,7 @@ msgid "SecurityOrchestration|Policy status"
msgstr "策略状æ€"
msgid "SecurityOrchestration|Policy summary"
-msgstr ""
+msgstr "策略摘è¦"
msgid "SecurityOrchestration|Policy type"
msgstr "策略类型"
@@ -31694,17 +32377,20 @@ msgstr "策略类型"
msgid "SecurityOrchestration|Require %{approvals} %{plural} from %{approvers} if any of the following occur:"
msgstr ""
-msgid "SecurityOrchestration|Rule"
-msgstr "规则"
-
msgid "SecurityOrchestration|Rules"
msgstr "规则"
+msgid "SecurityOrchestration|Runs %{actions} and %{lastAction} scans"
+msgstr ""
+
+msgid "SecurityOrchestration|Runs a %{action} scan"
+msgstr ""
+
msgid "SecurityOrchestration|Scan Execution"
msgstr "扫æ执行"
msgid "SecurityOrchestration|Scan Result"
-msgstr ""
+msgstr "扫æ结果"
msgid "SecurityOrchestration|Scan execution"
msgstr "扫æ执行"
@@ -31713,10 +32399,10 @@ msgid "SecurityOrchestration|Scan execution policies can only be created by proj
msgstr "扫æ执行策略åªèƒ½ç”±é¡¹ç›®æ‰€æœ‰è€…创建。"
msgid "SecurityOrchestration|Scan result"
-msgstr ""
+msgstr "扫æ结果"
msgid "SecurityOrchestration|Scan result policies can only be created by project owners."
-msgstr ""
+msgstr "扫æ结果策略åªèƒ½ç”±é¡¹ç›®æ‰€æœ‰è€…创建。"
msgid "SecurityOrchestration|Scan to be performed %{cadence}"
msgstr "è¦æ‰§è¡Œçš„扫æ %{cadence}"
@@ -31746,7 +32432,7 @@ msgid "SecurityOrchestration|Status"
msgstr "状æ€"
msgid "SecurityOrchestration|Summary"
-msgstr ""
+msgstr "摘è¦"
msgid "SecurityOrchestration|The %{scanners} %{severities} in an open merge request targeting %{branches}."
msgstr ""
@@ -31757,6 +32443,9 @@ msgstr "创建新的安全策略时出现问题"
msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr "此项目ä¸åŒ…å«ä»»ä½•å®‰å…¨ç­–略。"
+msgid "SecurityOrchestration|This view only shows scan results for the agent %{agent}. You can view scan results for all agents in the %{linkStart}Operational Vulnerabilities tab of the vulnerability report%{linkEnd}."
+msgstr ""
+
msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr "è¦æ‰©å¤§æ‚¨çš„æœç´¢èŒƒå›´ï¼Œè¯·åœ¨ä¸Šé¢æ›´æ”¹è¿‡æ»¤è§„则或选择ä¸åŒçš„安全策略项目。"
@@ -31767,58 +32456,55 @@ msgid "SecurityOrchestration|Unlinking a security project removes all policies s
msgstr "å–消链接安全项目会移除在链接的安全项目中存储的所有策略。ä¿å­˜ä»¥ç¡®è®¤æ­¤æ“作。"
msgid "SecurityOrchestration|Update scan policies"
-msgstr ""
+msgstr "更新扫æç­–ç•¥"
msgid "SecurityOrchestration|a"
-msgstr ""
+msgstr "一个"
msgid "SecurityOrchestration|all branches"
-msgstr ""
+msgstr "所有分支"
msgid "SecurityOrchestration|an"
-msgstr ""
+msgstr "一个"
msgid "SecurityOrchestration|branch"
-msgstr ""
+msgstr "分支"
msgid "SecurityOrchestration|branches"
-msgstr ""
+msgstr "分支"
msgid "SecurityOrchestration|members of groups"
-msgstr ""
+msgstr "群组æˆå‘˜"
msgid "SecurityOrchestration|members of groups with ids"
-msgstr ""
+msgstr "带有 ID 的群组æˆå‘˜"
msgid "SecurityOrchestration|members of the group"
-msgstr ""
+msgstr "群组æˆå‘˜"
msgid "SecurityOrchestration|members of the group with id"
-msgstr ""
+msgstr "带有 ID 的群组æˆå‘˜"
msgid "SecurityOrchestration|scanner finds"
-msgstr ""
+msgstr "扫æ器å‘现"
msgid "SecurityOrchestration|scanners find"
-msgstr ""
+msgstr "扫æ器å‘现"
msgid "SecurityOrchestration|the %{branches}"
-msgstr ""
+msgstr "%{branches}"
msgid "SecurityOrchestration|user with id"
-msgstr ""
+msgstr "带 ID 的用户"
msgid "SecurityOrchestration|users with ids"
-msgstr ""
-
-msgid "SecurityOrchestration|view results"
-msgstr "查看结果"
+msgstr "带 ID 的用户"
msgid "SecurityOrchestration|vulnerabilities"
-msgstr ""
+msgstr "æ¼æ´ž"
msgid "SecurityOrchestration|vulnerability"
-msgstr ""
+msgstr "æ¼æ´ž"
msgid "SecurityPolicies|+%{count} more"
msgstr "+%{count} 更多"
@@ -31830,7 +32516,7 @@ msgid "SecurityPolicies|Policy type"
msgstr "策略类型"
msgid "SecurityReports|%{count}+ projects"
-msgstr ""
+msgstr "%{count}+项目"
msgid "SecurityReports|%{firstProject} and %{secondProject}"
msgstr "%{firstProject}和%{secondProject}"
@@ -32483,23 +33169,20 @@ msgstr "å¤åˆ¶ç½‘å€"
msgid "Serverless|Getting started with serverless"
msgstr "开始使用Serverless"
-msgid "Serverless|Help shape the future of Serverless at GitLab"
-msgstr "å助塑造GitLabæ— æœåŠ¡å™¨åŠŸèƒ½çš„未æ¥"
-
msgid "Serverless|If you believe none of these apply, please check back later as the function data may be in the process of becoming available."
msgstr "如果您认为这些都ä¸é€‚用,请ç¨åŽå†æŸ¥çœ‹ï¼Œå› ä¸ºåŠŸèƒ½æ•°æ®å¯èƒ½æ­£åœ¨å˜ä¸ºå¯ç”¨ã€‚"
-msgid "Serverless|In order to start using functions as a service, you must first install Knative on your Kubernetes cluster. %{linkStart}More information%{linkEnd}"
-msgstr "è¦å¼€å§‹ä½¿ç”¨åŠŸèƒ½å³æœåŠ¡ï¼Œå¿…须先在Kubernetes群集上安装Knative。%{linkStart}更多信æ¯%{linkEnd}"
-
msgid "Serverless|Learn more about Serverless"
msgstr "了解更多关于 Serverless"
msgid "Serverless|No functions available"
msgstr "没有å¯ç”¨çš„功能"
-msgid "Serverless|Sign up for First Look"
-msgstr "注册First Look"
+msgid "Serverless|Serverless was %{linkStart}deprecated%{linkEnd} in GitLab 14.3."
+msgstr ""
+
+msgid "Serverless|Serverless was %{postLinkStart}deprecated%{postLinkEnd}. But if you opt to use it, you must install Knative in your Kubernetes cluster first. %{linkStart}Learn more.%{linkEnd}"
+msgstr ""
msgid "Serverless|The deploy job has not finished."
msgstr "部署作业尚未完æˆã€‚"
@@ -32510,9 +33193,6 @@ 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ç›®å‰æ²¡æœ‰å¯ç”¨çš„功能数æ®ã€‚è¿™å¯èƒ½æœ‰å¤šç§åŽŸå› ï¼ŒåŒ…括:"
-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 "我们一直在努力改善无æœåŠ¡å™¨åŠŸèƒ½ã€‚作为Knative用户,我们希望能倾å¬æˆ‘们如何为您æ供更好的体验。立å³æ³¨å†ŒGitLab First Look,我们将很快与您è”系。"
-
msgid "Serverless|Your %{startTag}.gitlab-ci.yml%{endTag} file is not properly configured."
msgstr "%{startTag}.gitab-ci.yml%{endTag}文件未正确é…置。"
@@ -32528,9 +33208,6 @@ msgstr "æœåŠ¡å¸æˆ·"
msgid "Service Account Key"
msgstr "æœåŠ¡å¸æˆ·å¯†é’¥"
-msgid "Service Accounts"
-msgstr "æœåŠ¡å¸æˆ·"
-
msgid "Service Accounts keys authorize GitLab to deploy your Google Cloud project"
msgstr "æœåŠ¡å¸æˆ·å¯†é’¥æŽˆæƒ GitLab 部署您的 Google Cloud 项目"
@@ -32540,17 +33217,17 @@ msgstr "æœåŠ¡å°"
msgid "Service Desk allows people to create issues in your GitLab instance without their own user account. It provides a unique email address for end users to create issues in a project. Replies can be sent either through the GitLab interface or by email. End users only see threads through email."
msgstr "æœåŠ¡å°å…许人们在没有自己的用户账å·çš„情况下在您的 GitLab 实例中创建议题。它为最终用户在项目中创建议题æ供了一个唯一的电å­é‚®ä»¶åœ°å€ã€‚回å¤å¯ä»¥é€šè¿‡ GitLab ç•Œé¢æˆ–通过电å­é‚®ä»¶å‘é€ã€‚最终用户åªèƒ½é€šè¿‡ç”µå­é‚®ä»¶æŸ¥çœ‹ä¸»é¢˜ã€‚"
-msgid "Service Usage Data"
-msgstr ""
-
msgid "Service account generated successfully"
msgstr "æœåŠ¡å¸æˆ·ç”ŸæˆæˆåŠŸ"
+msgid "Service accounts"
+msgstr ""
+
msgid "Service ping is disabled in your configuration file, and cannot be enabled through this form."
msgstr "æœåŠ¡ ping 在您的é…置文件中被ç¦ç”¨ï¼Œå¹¶ä¸”无法通过此表å•å¯ç”¨ã€‚"
msgid "Service usage data"
-msgstr ""
+msgstr "æœåŠ¡ä½¿ç”¨æ•°æ®"
msgid "ServiceDesk|Enable Service Desk"
msgstr "å¯ç”¨æœåŠ¡å°"
@@ -32687,6 +33364,9 @@ msgstr "设置 Web 终端的最长会è¯æ—¶é—´ã€‚"
msgid "Set the milestone to %{milestone_reference}."
msgstr "将里程碑设置为%{milestone_reference}。"
+msgid "Set the per-user rate limit for getting a user by ID via the API."
+msgstr ""
+
msgid "Set the per-user rate limit for notes created by web or API requests."
msgstr "为由 Web 或 API 请求创建的 notes 设置æ¯ä¸ªç”¨æˆ·çš„速率é™åˆ¶ã€‚"
@@ -32706,7 +33386,7 @@ msgid "Set up Jira Integration"
msgstr "设置Jira集æˆ"
msgid "Set up a %{type} runner for a project"
-msgstr ""
+msgstr "为项目设置一个 %{type} 的 Runner"
msgid "Set up a hardware device as a second factor to sign in."
msgstr "设置一个硬件设备作为登录的第二个因素。"
@@ -32865,6 +33545,9 @@ msgstr "共享Runner在群组级别已ç¦ç”¨"
msgid "Shared runners details"
msgstr "共享Runner的详细信æ¯"
+msgid "Shared runners enabled cannot be enabled until a valid credit card is on file"
+msgstr ""
+
msgid "Shared runners help link"
msgstr "共享Runner帮助链接"
@@ -32917,11 +33600,14 @@ msgid "Show all breadcrumbs"
msgstr "显示所有é¢åŒ…屑导航"
msgid "Show all epics"
-msgstr ""
+msgstr "显示所有å²è¯—"
msgid "Show all issues."
msgstr "显示所有议题。"
+msgid "Show all milestones"
+msgstr ""
+
msgid "Show all test cases."
msgstr "显示所有测试用例。"
@@ -32932,7 +33618,7 @@ msgid "Show archived projects only"
msgstr "仅显示已归档项目"
msgid "Show closed epics"
-msgstr ""
+msgstr "显示已关闭的å²è¯—"
msgid "Show command"
msgstr "显示相关命令"
@@ -32958,6 +33644,9 @@ msgstr "显示文件æµè§ˆå™¨"
msgid "Show file contents"
msgstr "显示文件内容"
+msgid "Show group milestones"
+msgstr ""
+
msgid "Show labels"
msgstr "显示标记"
@@ -32971,6 +33660,12 @@ msgid "Show one file at a time"
msgstr "一次显示一个文件"
msgid "Show open epics"
+msgstr "显示开放中的å²è¯—"
+
+msgid "Show project milestones"
+msgstr ""
+
+msgid "Show sub-group milestones"
msgstr ""
msgid "Show the Closed list"
@@ -32982,10 +33677,6 @@ msgstr "显示已打开列表"
msgid "Show whitespace changes"
msgstr "显示空白å˜æ›´å†…容"
-msgid "Showing %d event"
-msgid_plural "Showing %d events"
-msgstr[0] "显示 %d 个事件"
-
msgid "Showing %{conflict} between %{sourceBranch} and %{targetBranch}"
msgstr "在 %{sourceBranch} 和 %{targetBranch}之间显示 %{conflict}"
@@ -33044,12 +33735,6 @@ msgstr "无状æ€"
msgid "Sidebar|None"
msgstr "æ— "
-msgid "Sidebar|Only numeral characters allowed"
-msgstr "åªå…许使用数字字符"
-
-msgid "Sidebar|Weight"
-msgstr "æƒé‡"
-
msgid "Sidekiq job compression threshold (bytes)"
msgstr "Sidekiq 作业压缩阈值(字节)"
@@ -33105,7 +33790,7 @@ msgid "Sign up"
msgstr "注册"
msgid "Sign up now"
-msgstr ""
+msgstr "ç«‹å³æ³¨å†Œ"
msgid "Sign up was successful! Please confirm your email to sign in."
msgstr "注册æˆåŠŸï¼è¯·ç¡®è®¤æ‚¨çš„电å­é‚®ä»¶ä»¥ç™»å½•ã€‚"
@@ -33210,31 +33895,37 @@ msgid "Slack integration allows you to interact with GitLab via slash commands i
msgstr "Slack集æˆå…许您通过èŠå¤©çª—å£ä¸­çš„shash命令与GitLab交互。"
msgid "Slack logo"
+msgstr "Slack logo"
+
+msgid "SlackIntegration|Are you sure you want to remove this project from the Slack application?"
msgstr ""
msgid "SlackIntegration|GitLab for Slack"
-msgstr ""
+msgstr "GitLab for Slack"
msgid "SlackIntegration|GitLab for Slack was successfully installed."
-msgstr ""
+msgstr "GitLab for Slack å·²æˆåŠŸå®‰è£…。"
msgid "SlackIntegration|Project alias"
+msgstr "项目别å"
+
+msgid "SlackIntegration|Remove project"
msgstr ""
msgid "SlackIntegration|Select a GitLab project to link with your Slack workspace."
-msgstr ""
+msgstr "选择一个è¦è¿žæŽ¥åˆ°ä½ çš„ Slack 工作区的项目。"
msgid "SlackIntegration|Sends notifications about project events to Slack channels."
msgstr "å‘ Slack 频é“å‘é€æœ‰å…³é¡¹ç›®äº‹ä»¶çš„通知。"
msgid "SlackIntegration|Team name"
-msgstr ""
+msgstr "团队å称"
msgid "SlackIntegration|To set up this integration press \"Add to Slack\""
-msgstr ""
+msgstr "按下“添加到 Slackâ€æ¥è®¾ç½®è¿™ä¸ªé›†æˆ"
msgid "SlackIntegration|You can now close this window and go to your Slack workspace."
-msgstr ""
+msgstr "您现在å¯ä»¥å…³é—­æ­¤çª—å£å¹¶è½¬åˆ°æ‚¨çš„ Slack 工作区。"
msgid "SlackService|1. %{slash_command_link_start}Add a slash command%{slash_command_link_end} in your Slack team using this information:"
msgstr "1. %{slash_command_link_start}在您的Slack团队中使用此信æ¯æ·»åŠ ä¸€ä¸ªæ–œæ å‘½ä»¤%{slash_command_link_end}:"
@@ -33365,9 +34056,6 @@ msgstr "è¯•å›¾æ”¹å˜ %{issuableDisplayName} çš„é”定状æ€æ—¶å‡ºé”™äº†"
msgid "Something went wrong trying to load issue contacts."
msgstr "å°è¯•åŠ è½½è®®é¢˜è”系人时出错。"
-msgid "Something went wrong when creating a work item. Please try again"
-msgstr "创建工作项时出错,请é‡è¯•"
-
msgid "Something went wrong when reordering designs. Please try again"
msgstr "é‡æ–°æŽ’åºè®¾è®¡æ—¶å‡ºäº†ç‚¹é—®é¢˜ã€‚请å†è¯•ä¸€æ¬¡"
@@ -33461,9 +34149,6 @@ msgstr "åˆå§‹åŒ–OpenAPI查看器时出错"
msgid "Something went wrong while inserting your image. Please try again."
msgstr "æ’入图åƒæ—¶å‡ºäº†é”™ã€‚请é‡è¯•ã€‚"
-msgid "Something went wrong while merging this merge request. Please try again."
-msgstr "åˆå¹¶æ­¤åˆå¹¶è¯·æ±‚时出错。请é‡è¯•ã€‚"
-
msgid "Something went wrong while obtaining the Let's Encrypt certificate."
msgstr "获å–Let's Encryptè¯ä¹¦æ—¶å‡ºäº†é”™ã€‚"
@@ -33785,11 +34470,11 @@ 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 "在您的GitLab实例的代ç è§†å›¾å’Œåˆå¹¶è¯·æ±‚上å¯ç”¨ç”±%{link_start}Sourcegraph%{link_end}æ供的代ç æ™ºèƒ½ã€‚"
-msgid "SourcegraphAdmin|If checked, only public projects will have code intelligence and communicate with Sourcegraph."
-msgstr "如果选中,åªæœ‰å…¬å¼€é¡¹ç›®ä¼šæ‹¥æœ‰ä»£ç æ™ºèƒ½å¹¶ä¸ŽSourcegraph通信。"
+msgid "SourcegraphAdmin|Learn more."
+msgstr ""
-msgid "SourcegraphAdmin|More information"
-msgstr "更多信æ¯"
+msgid "SourcegraphAdmin|Only public projects have code intelligence enabled and communicate with Sourcegraph."
+msgstr ""
msgid "SourcegraphAdmin|Save changes"
msgstr "ä¿å­˜æ›´æ”¹"
@@ -33797,8 +34482,8 @@ msgstr "ä¿å­˜æ›´æ”¹"
msgid "SourcegraphAdmin|Sourcegraph URL"
msgstr "Sourcegraph网å€"
-msgid "SourcegraphAdmin|e.g. https://sourcegraph.example.com"
-msgstr "例如:https://sourcegraph.example.com"
+msgid "SourcegraphAdmin|https://sourcegraph.example.com"
+msgstr ""
msgid "SourcegraphPreferences|This feature is experimental and currently limited to certain projects."
msgstr "此功能是实验性的,目å‰ä»…é™äºŽæŸäº›é¡¹ç›®ã€‚"
@@ -33932,6 +34617,9 @@ msgstr "开始清ç†"
msgid "Start date"
msgstr "开始日期"
+msgid "Start free trial"
+msgstr ""
+
msgid "Start merge train"
msgstr "å¯åŠ¨åˆå¹¶é˜Ÿåˆ—"
@@ -33939,7 +34627,7 @@ msgid "Start merge train when pipeline succeeds"
msgstr "æµæ°´çº¿æˆåŠŸæ—¶å¯åŠ¨åˆå¹¶é˜Ÿåˆ—"
msgid "Start merge train..."
-msgstr ""
+msgstr "å¯åŠ¨åˆå¹¶é˜Ÿåˆ—..."
msgid "Start search"
msgstr "开始æœç´¢"
@@ -33962,6 +34650,9 @@ msgstr "已开始 %{startsIn}"
msgid "Started asynchronous removal of all repository check states."
msgstr "已开始所有仓库检查状æ€çš„异步删除。"
+msgid "Started escalation for this incident."
+msgstr ""
+
msgid "Starting..."
msgstr "正在å¯åŠ¨..."
@@ -33974,6 +34665,9 @@ msgstr "开始 %{startsIn}"
msgid "Starts at (UTC)"
msgstr "开始于(UTC)"
+msgid "Starts escalations for this incident"
+msgstr ""
+
msgid "Starts on"
msgstr "开始于"
@@ -33984,7 +34678,7 @@ msgid "State your message to activate"
msgstr "输入消æ¯ä»¥å¯ç”¨"
msgid "State/Province"
-msgstr ""
+msgstr "å·ž/çœ"
msgid "State/Province/City"
msgstr "å·ž/çœ/市"
@@ -34235,6 +34929,9 @@ msgstr "未知"
msgid "Strikethrough"
msgstr "删除线"
+msgid "Strikethrough text"
+msgstr ""
+
msgid "Subgroup information"
msgstr "å­ç¾¤ç»„ä¿¡æ¯"
@@ -34329,7 +35026,7 @@ msgid "Subscribed to this %{quick_action_target}."
msgstr "已订阅 %{quick_action_target}。"
msgid "Subscribed to this project"
-msgstr ""
+msgstr "已订阅此项目"
msgid "Subscribes to this %{quick_action_target}."
msgstr "订阅%{quick_action_target}。"
@@ -34362,22 +35059,22 @@ msgid "SubscriptionBanner|Upload new license"
msgstr "上传新许å¯è¯"
msgid "SubscriptionEmail|%{doc_link_start}Please reach out if you have questions%{doc_link_end}, and we'll be happy to assist."
-msgstr ""
+msgstr "如果您有%{doc_link_start}任何问题需è¦è§£ç­”%{doc_link_end},我们很ä¹æ„为您æ供帮助。"
msgid "SubscriptionEmail|Additional charges for your GitLab subscription"
-msgstr ""
+msgstr "您的订阅的é¢å¤–费用"
msgid "SubscriptionEmail|Dear %{customer_name},"
-msgstr ""
+msgstr "%{customer_name},"
msgid "SubscriptionEmail|GitLab Billing Team"
-msgstr ""
+msgstr "GitLab è´¦å•å›¢é˜Ÿ"
msgid "SubscriptionEmail|Thank you for your business!"
-msgstr ""
+msgstr "感谢您的光临ï¼"
msgid "SubscriptionEmail|You can find more information about the quarterly reconciliation process in %{doc_link_start}our documentation%{doc_link_end}."
-msgstr ""
+msgstr "您å¯ä»¥åœ¨%{doc_link_start}文档%{doc_link_end}中找到关于季度对账过程的更多信æ¯ã€‚"
msgid "SubscriptionEmail|You have exceeded the number of seats in your GitLab subscription %{subscription_name} by %{seat_quantity}. Even if you've exceeded the seats in your subscription, you can continue to add users, and GitLab will bill you a prorated amount for any seat overages on a quarterly basis."
msgstr ""
@@ -34469,6 +35166,21 @@ msgstr "使用次数将在æ¯å¤©ä¸­åˆ12:00进行更新。"
msgid "Subscriptions"
msgstr "订阅"
+msgid "Subscriptions|Chat with sales"
+msgstr ""
+
+msgid "Subscriptions|Close"
+msgstr ""
+
+msgid "Subscriptions|Not ready to buy yet?"
+msgstr ""
+
+msgid "Subscriptions|Start a free trial"
+msgstr ""
+
+msgid "Subscriptions|We understand. Maybe you have some questions for our sales team, or maybe you'd like to try some of the paid features first. What would you like to do?"
+msgstr ""
+
msgid "Subscription|Your subscription for %{strong}%{namespace_name}%{strong_close} has expired and you are now on %{pricing_link_start}the GitLab Free tier%{pricing_link_end}. Don't worry, your data is safe. Get in touch with our support team (%{support_email}). They'll gladly help with your subscription renewal."
msgstr "您对 %{strong}%{namespace_name}%{strong_close} 的订阅已过期,您现在在 %{pricing_link_start}标准版%{pricing_link_end}了。别担心,您的数æ®æ˜¯å®‰å…¨çš„。请è”系我们的支æŒå›¢é˜Ÿï¼ˆ%{support_email})。他们将ä¹æ„帮助您更新订阅。"
@@ -34653,7 +35365,7 @@ msgid "SuperSonics|Cloud licensing is now available. It's an easier way to activ
msgstr "Cloud 许å¯çŽ°å·²æŽ¨å‡ºã€‚这是激活实例和管ç†è®¢é˜…的更简å•æ–¹æ³•ã€‚阅读 %{blogPostLinkStart}åšå®¢æ–‡ç« %{blogPostLinkEnd}中的更多相关信æ¯ã€‚激活ç åœ¨ %{portalLinkStart}客户门户%{portalLinkEnd}中å¯ç”¨ã€‚"
msgid "SuperSonics|Enter activation code"
-msgstr ""
+msgstr "输入激活ç "
msgid "SuperSonics|Export license usage file"
msgstr "导出许å¯è¯ä½¿ç”¨æ–‡ä»¶"
@@ -34679,6 +35391,9 @@ msgstr "管ç†"
msgid "SuperSonics|Maximum users"
msgstr "最大用户数"
+msgid "SuperSonics|Offline cloud"
+msgstr ""
+
msgid "SuperSonics|Paste your activation code"
msgstr "粘贴您的激活ç "
@@ -34695,7 +35410,7 @@ msgid "SuperSonics|Subscription details"
msgstr "订阅详情"
msgid "SuperSonics|Subscription unavailable"
-msgstr ""
+msgstr "订阅ä¸å¯ç”¨"
msgid "SuperSonics|Sync subscription details"
msgstr "åŒæ­¥è®¢é˜…详情"
@@ -34745,6 +35460,12 @@ msgstr "您å¯ä»¥å¼€å§‹å…费试用 GitLab 旗舰版,无需任何承诺或付æ
msgid "SuperSonics|You do not have an active subscription"
msgstr "您没有有效订阅"
+msgid "SuperSonics|You have a future dated license"
+msgstr ""
+
+msgid "SuperSonics|You have added a license that activates on %{date}. Please see the subscription history table below for more details."
+msgstr ""
+
msgid "SuperSonics|You have successfully added a license that activates on %{date}. Please see the subscription history table below for more details."
msgstr "您已æˆåŠŸæ·»åŠ åœ¨ %{date} 激活的许å¯è¯ã€‚有关更多详细信æ¯ï¼Œè¯·å‚阅下é¢çš„订阅历å²è¡¨ã€‚"
@@ -34752,7 +35473,7 @@ msgid "SuperSonics|You'll be charged for %{trueUpLinkStart}users over license%{t
msgstr "æ ¹æ®æ‚¨çš„åè®®æ¡æ¬¾ï¼Œæ‚¨å°†æŒ‰å­£åº¦æˆ–æ¯å¹´ä¸º %{trueUpLinkStart}超过许å¯è¯çš„用户%{trueUpLinkEnd}付费。"
msgid "SuperSonics|Your %{subscriptionEntryName} cannot be displayed at the moment. Please refresh the page to try again."
-msgstr ""
+msgstr "您的 %{subscriptionEntryName} 暂时无法显示。请刷新此页é¢ã€‚"
msgid "SuperSonics|Your future dated license was successfully added"
msgstr "您的未æ¥æ—¥æœŸè®¸å¯è¯å·²æˆåŠŸæ·»åŠ "
@@ -34767,13 +35488,13 @@ msgid "SuperSonics|Your subscription was successfully activated. You can see the
msgstr "您的订阅已æˆåŠŸæ¿€æ´»ã€‚您å¯ä»¥åœ¨ä¸‹é¢æŸ¥çœ‹è¯¦ç»†ä¿¡æ¯ã€‚"
msgid "SuperSonics|current subscription"
-msgstr ""
+msgstr "当å‰è®¢é˜…"
msgid "SuperSonics|future subscriptions"
-msgstr ""
+msgstr "未æ¥çš„订阅"
msgid "SuperSonics|past subscriptions"
-msgstr ""
+msgstr "以å‰çš„订阅"
msgid "Support"
msgstr "支æŒ"
@@ -34904,6 +35625,9 @@ msgstr "标签å称"
msgid "Tag name is required"
msgstr "标签å称为必填项"
+msgid "Tag push"
+msgstr ""
+
msgid "Tag push events"
msgstr "标签推é€äº‹ä»¶"
@@ -35006,6 +35730,9 @@ msgstr "编写å‘行说明(Release Notes)或将文件拖动到此处..."
msgid "TagsPage|protected"
msgstr "å·²ä¿æŠ¤"
+msgid "Take a look at the documentation to discover all of GitLab’s capabilities."
+msgstr ""
+
msgid "Target Branch"
msgstr "目标分支"
@@ -35019,7 +35746,7 @@ msgid "Target-Branch"
msgstr "目标分支"
msgid "Task"
-msgstr ""
+msgstr "任务"
msgid "Task ID: %{elastic_task}"
msgstr "任务ID: %{elastic_task}"
@@ -35094,7 +35821,7 @@ msgid "Terms of Service and Privacy Policy"
msgstr "æœåŠ¡æ¡æ¬¾å’Œéšç§æ”¿ç­–"
msgid "Terms of service"
-msgstr ""
+msgstr "æœåŠ¡æ¡æ¬¾"
msgid "Terraform"
msgstr "Terraform"
@@ -35263,7 +35990,7 @@ msgid "Test Cases"
msgstr "测试用例"
msgid "Test case"
-msgstr ""
+msgstr "测试用例"
msgid "Test coverage parsing"
msgstr "测试覆盖率解æž"
@@ -35402,6 +36129,9 @@ msgstr "您å¯ä»¥å°†ä½œä¸šé…置为使用å•å…ƒæµ‹è¯•æŠ¥å‘Šï¼ŒGitLab 会在此å¤
msgid "Tests"
msgstr "测试"
+msgid "Text (optional)"
+msgstr ""
+
msgid "Text added to the body of all email messages. %{character_limit} character limit"
msgstr "添加到所有电å­é‚®ä»¶æ­£æ–‡çš„文本。 %{character_limit} 字符é™åˆ¶"
@@ -35451,6 +36181,9 @@ msgstr "用于访问垃圾邮件检查æœåŠ¡ç«¯ç‚¹çš„ API 密钥."
msgid "The CSV export will be created in the background. Once finished, it will be sent to %{email} in an attachment."
msgstr "CSV导出将在åŽå°åˆ›å»ºã€‚完æˆåŽï¼Œå®ƒå°†ä»¥é™„件形å¼å‘é€åˆ°%{email}。"
+msgid "The CSV export you requested of all user memberships is attached to this email."
+msgstr ""
+
msgid "The GitLab subscription service (customers.gitlab.com) is currently experiencing an outage. You can monitor the status and get updates at %{linkStart}status.gitlab.com%{linkEnd}."
msgstr "GitLab 订阅æœåŠ¡ (customers.gitlab.com) ç›®å‰æ­£åœ¨ä¸­æ–­ã€‚您å¯ä»¥é€šè¿‡ %{linkStart}status.gitlab.com%{linkEnd}监控状æ€å¹¶èŽ·å–更新。"
@@ -35515,7 +36248,7 @@ msgid "The connection will time out after %{timeout}. For repositories that take
msgstr "该连接将在 %{timeout}åŽè¶…时。如仓库导入耗时超过该时间,请使用克隆/推é€ç»„åˆã€‚"
msgid "The contact does not belong to the issue group or an ancestor"
-msgstr ""
+msgstr "è”系人ä¸å±žäºŽè®®é¢˜æ‰€åœ¨ç¾¤ç»„或上级群组"
msgid "The content editor may change the markdown formatting style of the document, which may not match your original markdown style."
msgstr "内容编辑器å¯èƒ½ä¼šæ›´æ”¹æ–‡æ¡£çš„ Markdown æ ¼å¼æ ·å¼ï¼Œè¿™å¯èƒ½ä¸Žæ‚¨åŽŸæ¥çš„ Markdown æ ·å¼ä¸åŒ¹é…。"
@@ -35526,6 +36259,9 @@ msgstr "此页é¢çš„内容未以UTF-8ç¼–ç ã€‚编辑åªèƒ½é€šè¿‡Git仓库进行ã
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 "该群组,其å­ç»„和项目的内容将于%{deletion_adjourned_period}天åŽåœ¨%{date}永久删除。在此之åŽï¼Œæ‚¨çš„æ•°æ®å°†æ— æ³•æ¢å¤ã€‚"
+msgid "The current epic"
+msgstr ""
+
msgid "The current issue"
msgstr "当å‰è®®é¢˜"
@@ -35681,11 +36417,14 @@ msgid "The latest pipeline for this merge request did not complete successfully.
msgstr "æ­¤åˆå¹¶è¯·æ±‚的最新æµæ°´çº¿æœªæˆåŠŸå®Œæˆã€‚"
msgid "The latest pipeline for this merge request did not succeed. The latest changes are unverified."
-msgstr ""
+msgstr "æ­¤åˆå¹¶è¯·æ±‚的最新æµæ°´çº¿æœªæˆåŠŸã€‚最新更改未ç»éªŒè¯ã€‚"
msgid "The latest pipeline for this merge request has failed."
msgstr "æ­¤åˆå¹¶è¯·æ±‚的最新æµæ°´çº¿å·²å¤±è´¥ã€‚"
+msgid "The license key is invalid."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr "许å¯è¯å¯†é’¥æ— æ•ˆã€‚请确ä¿å®ƒä¸Žæ‚¨ä»ŽGitLab Inc.收到的一致。"
@@ -35701,6 +36440,9 @@ msgstr "许å¯è¯å·²æˆåŠŸä¸Šä¼ ï¼Œå¹¶å·²æ¿€æ´»ã€‚详细信æ¯å¦‚下。"
msgid "The license was successfully uploaded and will be active from %{starts_at}. You can see the details below."
msgstr "许å¯è¯å·²æˆåŠŸä¸Šä¼ ï¼Œå°†äºŽ%{starts_at}激活。您å¯ä»¥åœ¨ä¸‹é¢çœ‹åˆ°è¯¦ç»†ä¿¡æ¯ã€‚"
+msgid "The license you uploaded is invalid. If the issue persists, contact support at %{link}."
+msgstr ""
+
msgid "The list creation wizard is already open"
msgstr "列表创建å‘导已打开"
@@ -36143,7 +36885,7 @@ msgid "There was an error fetching the Geo Settings"
msgstr "获å–Geo设置时出错"
msgid "There was an error fetching the Sites's Groups"
-msgstr ""
+msgstr "获å–站点的群组时出错"
msgid "There was an error fetching the deploy freezes."
msgstr "获å–部署冻结时出错。"
@@ -36194,7 +36936,7 @@ msgid "There was an error retrieving the Jira users."
msgstr "获å–Jira用户时出错。"
msgid "There was an error saving this Geo Site"
-msgstr ""
+msgstr "ä¿å­˜æ­¤ Geo 站点时出错"
msgid "There was an error saving your changes."
msgstr "ä¿å­˜å˜æ›´æ—¶å‡ºé”™ã€‚"
@@ -36322,11 +37064,14 @@ msgstr "æ­¤æ“作å¯èƒ½å¯¼è‡´æ•°æ®ä¸¢å¤±ã€‚为防止æ„外,我们会è¦æ±‚您
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr "æ­¤æ“作无法撤消,它将永久删除%{key}SSH密钥"
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
-msgstr "æ­¤æ“作将 %{strongOpen}ç«‹å³%{strongClose}%{strongOpen}永久删除%{strongClose} %{codeOpen}%{project}%{codeClose} ,包括其仓库和所有相关资æºï¼ŒåŒ…括议题和åˆå¹¶è¯·æ±‚。"
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} and everything this project contains. %{strongOpen}There is no going back%{strongClose}"
+msgstr ""
+
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains."
+msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}on %{date}%{strongClose}, including its repositories and all related resources, including issues and merge requests."
-msgstr "æ­¤æ“作将%{strongOpen}于 %{date}%{strongClose} %{strongOpen}永久删除%{strongClose} %{codeOpen}%{project}%{codeClose} ,包括其仓库和所有相关资æºï¼ŒåŒ…括议题和åˆå¹¶è¯·æ±‚。"
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains. %{strongOpen}There is no going back.%{strongClose}"
+msgstr ""
msgid "This action will %{strongOpen}permanently remove%{strongClose} %{codeOpen}%{group}%{codeClose} %{strongOpen}immediately%{strongClose}."
msgstr "æ­¤æ“作将%{strongOpen}ç«‹å³%{strongClose}%{strongOpen}永久删除%{strongClose} %{codeOpen}%{group}%{codeClose}。"
@@ -36401,7 +37146,7 @@ msgid "This content could not be displayed because %{reason}. You can %{options}
msgstr "由于%{reason},无法显示此内容。您å¯ä»¥%{options}以代替。"
msgid "This content could not be displayed because it is stored in LFS. You can %{linkStart}download it%{linkEnd} instead."
-msgstr ""
+msgstr "此内容无法显示,因为它存储在 LFS 中。您å¯ä»¥ %{linkStart}下载它%{linkEnd} 代替。"
msgid "This credential has expired"
msgstr "此凭è¯å·²è¿‡æœŸ"
@@ -36454,9 +37199,6 @@ msgstr "该字段是必填字段。"
msgid "This file was modified for readability, and can't accept suggestions. Edit it directly."
msgstr "此文件已被修改以æ高å¯è¯»æ€§ï¼Œä¸èƒ½æŽ¥å—建议,请直接编辑。"
-msgid "This forked project has the following:"
-msgstr "这个派生项目有以下几点:"
-
msgid "This form is disabled in preview"
msgstr "此表å•åœ¨é¢„览中被ç¦ç”¨"
@@ -36469,8 +37211,8 @@ msgstr "该组åŠå…¶å­ç»„和项目将在 %{deletion_adjourned_period} 天内处
msgid "This group can't be removed because it is linked to a subscription. To remove this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr "此群组ä¸èƒ½è¢«åˆ é™¤ï¼Œå› ä¸ºå®ƒå·²é“¾æŽ¥åˆ°ä¸€ä¸ªè®¢é˜…,è¦åˆ é™¤æ­¤ç¾¤ç»„, %{linkStart}将订阅%{linkEnd} 链接到å¦ä¸€ä¸ªç¾¤ç»„。"
-msgid "This group can't be transfered because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
-msgstr "无法转移此群组,因为它已链接到订阅。è¦è½¬ç§»è¿™ä¸ªç»„,与ä¸åŒçš„组%{linkStart}链接订阅%{linkEnd}。"
+msgid "This group can't be transferred because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
+msgstr ""
msgid "This group cannot be invited to a project inside a group with enforced SSO"
msgstr "此群组ä¸èƒ½è¢«é‚€è¯·åˆ°å¼ºåˆ¶SSO的群组中"
@@ -36482,13 +37224,13 @@ msgid "This group has been scheduled for permanent removal on %{date}"
msgstr "此群组已安排在%{date}永久删除"
msgid "This group has no active access tokens."
-msgstr ""
+msgstr "此群组没有有效的访问令牌。"
msgid "This group is linked to a subscription"
msgstr "此群组已链接到订阅"
msgid "This group is not permitted to create compliance violations"
-msgstr ""
+msgstr "ä¸å…许此群组创建è¿è§„行为"
msgid "This group, its subgroups and projects has been scheduled for removal on %{date}."
msgstr "此群组ã€å…¶å­ç¾¤ç»„和项目已安排在%{date}移除。"
@@ -36496,6 +37238,9 @@ msgstr "此群组ã€å…¶å­ç¾¤ç»„和项目已安排在%{date}移除。"
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 "此群组ã€å…¶å­ç¾¤ç»„åŠé¡¹ç›®å°†äºŽ%{date}被删除,因为其父群组“%{parent_group_name}â€å·²è¢«è®¡åˆ’移除。"
+msgid "This incident is already escalated with '%{escalation_policy_name}'."
+msgstr ""
+
msgid "This invitation was sent to %{mail_to_invite_email}, but you are signed in as %{link_to_current_user} with email %{mail_to_current_user}."
msgstr "此邀请已å‘é€è‡³ %{mail_to_invite_email},但您以 %{link_to_current_user} 身份使用电å­é‚®ä»¶ %{mail_to_current_user}登录。"
@@ -36514,9 +37259,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 merge train pipeline"
-msgstr "这是一个åˆå¹¶é˜Ÿåˆ—æµæ°´çº¿"
-
msgid "This is a private email address %{helpIcon} generated just for you. Anyone who has it can create issues or merge requests as if they were you. If that happens, %{resetLinkStart}reset this token%{resetLinkEnd}."
msgstr "这是专为您生æˆçš„ç§äººç”µå­é‚®ä»¶åœ°å€ %{helpIcon} 任何拥有它的人都å¯ä»¥åƒæ‚¨ä¸€æ ·åˆ›å»ºé—®é¢˜æˆ–åˆå¹¶è¯·æ±‚。如果å‘生这ç§æƒ…况, %{resetLinkStart}é‡ç½®è¿™ä¸ªä»¤ç‰Œ%{resetLinkEnd}。"
@@ -36538,6 +37280,12 @@ msgstr "此数目为您æœåŠ¡å™¨å½“å‰%{billable_users_link_start}收费用户%{
msgid "This is your current session"
msgstr "这是您当å‰çš„会è¯"
+msgid "This issue cannot be assigned to a confidential epic because it is public."
+msgstr ""
+
+msgid "This issue cannot be made public because it belongs to a confidential epic."
+msgstr ""
+
msgid "This issue is confidential and should only be visible to team members with at least Reporter access."
msgstr "此议题是ä¿å¯†çš„,åªèƒ½æ˜¾ç¤ºç»™æ‹¥æœ‰è‡³å°‘“报告人â€è®¿é—®æƒé™çš„团队æˆå‘˜ã€‚"
@@ -36655,6 +37403,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 branch is protected from force push."
+msgstr ""
+
msgid "This merge request cannot be rebased while there are conflicts."
msgstr "存在冲çªæ—¶ï¼Œæ­¤åˆå¹¶è¯·æ±‚无法 rebase。"
@@ -36706,12 +37457,18 @@ msgstr "æ­¤æµæ°´çº¿ä½¿ç”¨äº† %{strongStart}Auto DevOps 预先定义的并已å¯
msgid "This pipeline was triggered by a schedule."
msgstr "æ­¤æµæ°´çº¿æ˜¯ç”±å®šæ—¶è®¡åˆ’触å‘çš„."
+msgid "This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project"
msgstr "当å‰é¡¹ç›®"
-msgid "This project cannot be %{visibilityLevel} because the visibility of %{openShowLink}%{name}%{closeShowLink} is %{visibility}. To make this project %{visibilityLevel}, you must first %{openEditLink}change the visibility%{closeEditLink} of the parent group."
+msgid "This project can be restored until %{date}."
msgstr ""
+msgid "This project cannot be %{visibilityLevel} because the visibility of %{openShowLink}%{name}%{closeShowLink} is %{visibility}. To make this project %{visibilityLevel}, you must first %{openEditLink}change the visibility%{closeEditLink} of the parent group."
+msgstr "此项目ä¸èƒ½ä¸º%{visibilityLevel} ,因为 %{openShowLink}%{name}%{closeShowLink} çš„å¯è§æ€§ä¸º %{visibility}。è¦ä½¿è¿™ä¸ªé¡¹ç›®ä¸º%{visibilityLevel},您必须首先%{openEditLink}更改父组的å¯è§æ€§%{closeEditLink}。"
+
msgid "This project does not belong to a group and cannot make use of group runners."
msgstr "此项目ä¸å±žäºŽç¾¤ç»„,ä¸èƒ½ä½¿ç”¨ç¾¤ç»„Runner。"
@@ -36727,6 +37484,9 @@ msgstr "此项目没有有效的访问令牌。"
msgid "This project is %{strongStart}NOT%{strongEnd} a fork, and has the following:"
msgstr "这个项目 %{strongStart}ä¸æ˜¯%{strongEnd} 一个派生项目,并具有以下内容:"
+msgid "This project is %{strongStart}NOT%{strongEnd} a fork. This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr "此项目已存档,无法添加评论。"
@@ -36734,7 +37494,7 @@ msgid "This project is licensed under the %{strong_start}%{license_name}%{strong
msgstr "该项目在 %{strong_start}%{license_name}%{strong_end}下获得许å¯ã€‚"
msgid "This project is not subscribed to any project pipelines."
-msgstr ""
+msgstr "此项目未订阅任何项目æµæ°´çº¿ã€‚"
msgid "This project manages its dependencies using %{strong_start}%{manager_name}%{strong_end}"
msgstr "此项目使用%{strong_start}%{manager_name}%{strong_end}管ç†å…¶ä¾èµ–关系"
@@ -36776,7 +37536,7 @@ msgid "This setting can be overridden in each project."
msgstr "当å‰è®¾ç½®å¯åœ¨æ¯ä¸ªé¡¹ç›®ä¸­è¿›è¡Œæ›´æ”¹è¦†ç›–。"
msgid "This setting is allowed for forked projects only"
-msgstr ""
+msgstr "此设置仅适用于派生项目"
msgid "This subscription is for"
msgstr "此订阅适用于"
@@ -37416,6 +38176,9 @@ msgstr "待办事项已æˆåŠŸæ ‡è®°ä¸ºå·²å®Œæˆã€‚"
msgid "Today"
msgstr "今日"
+msgid "Todos count"
+msgstr ""
+
msgid "Todos|Are you looking for things to do? Take a look at %{strongStart}%{openIssuesLinkStart}open issues%{openIssuesLinkEnd}%{strongEnd}, contribute to %{strongStart}%{mergeRequestLinkStart}a merge request%{mergeRequestLinkEnd}%{mergeRequestLinkEnd}%{strongEnd}, or mention someone in a comment to automatically assign them a new to-do item."
msgstr "您正在寻找è¦åšçš„事情å—? 查看 %{strongStart}%{openIssuesLinkStart}打开的议题%{openIssuesLinkEnd}%{strongEnd},贡献给 %{strongStart}%{mergeRequestLinkStart}åˆå¹¶è¯·æ±‚%{mergeRequestLinkEnd}%{mergeRequestLinkEnd}%{strongEnd},或在评论中æåŠæŸäººï¼Œè‡ªåŠ¨åˆ†é…新的待办事项。"
@@ -37689,9 +38452,8 @@ msgstr "树形视图"
msgid "Trending"
msgstr "热门"
-msgid "Trials|%{planName} Trial %{enDash} %{num} day left"
-msgid_plural "Trials|%{planName} Trial %{enDash} %{num} days left"
-msgstr[0] "%{planName} 试用版 %{enDash} 剩下 %{num} 天"
+msgid "Trials|%{planName} Trial"
+msgstr ""
msgid "Trials|Compare all plans"
msgstr "比较所有方案"
@@ -37699,6 +38461,9 @@ msgstr "比较所有方案"
msgid "Trials|Create a new group to start your GitLab Ultimate trial."
msgstr "创建一个新群组以开始您的旗舰版试用。"
+msgid "Trials|Day %{daysUsed}/%{duration}"
+msgstr ""
+
msgid "Trials|Go back to GitLab"
msgstr "返回GitLab"
@@ -37724,7 +38489,7 @@ msgid "Trials|Your trial ends on %{boldStart}%{trialEndDate}%{boldEnd}. We hope
msgstr "您的试用版在 %{boldStart}%{trialEndDate}%{boldEnd}结æŸï¼Œæˆ‘们希望您能享å—GitLab %{planName}的功能,为了在试用结æŸåŽä¿ç•™è¿™äº›åŠŸèƒ½ï¼Œæ‚¨éœ€è¦è´­ä¹°è®¢é˜…。(如果您满足您的需è¦ï¼Œæ‚¨ä¹Ÿå¯ä»¥é€‰æ‹©ä¸“业版。)"
msgid "Trial|Allowed characters: +, 0-9, -, and spaces."
-msgstr ""
+msgstr "å…许的字符:+ã€0-9ã€- 和空格。"
msgid "Trial|Company name"
msgstr "å…¬å¸å称"
@@ -37811,10 +38576,10 @@ msgid "Triggerer"
msgstr "触å‘者"
msgid "Trigger|Trigger user has insufficient permissions to project"
-msgstr ""
+msgstr "触å‘用户没有足够的项目æƒé™"
msgid "Trigger|invalid"
-msgstr ""
+msgstr "无效"
msgid "Troubleshoot and monitor your application with tracing"
msgstr "使用跟踪对应用程åºè¿›è¡Œæ•…障排除与监控"
@@ -37948,8 +38713,8 @@ msgstr "将新标签推é€åˆ°ä»“åº“æ—¶ä¼šè§¦å‘ URL"
msgid "URL is triggered when repository is updated"
msgstr "æ›´æ–°ä»“åº“æ—¶è§¦å‘ URL"
-msgid "URL must be percent-encoded if neccessary."
-msgstr "如有必è¦ï¼ŒURL 必须进行百分比编ç ã€‚"
+msgid "URL must be percent-encoded if necessary."
+msgstr ""
msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
msgstr "URL必须以%{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}或%{codeStart}ftp://%{codeEnd}开始"
@@ -38167,6 +38932,9 @@ msgstr "解é”"
msgid "Unlock account"
msgstr "解é”账户"
+msgid "Unlock more features with GitLab Ultimate"
+msgstr ""
+
msgid "Unlock the discussion"
msgstr "解é”讨论"
@@ -38230,6 +38998,9 @@ msgstr "å–消订阅%{quick_action_target}."
msgid "Unsubscribes from this %{quick_action_target}."
msgstr "å–消订阅%{quick_action_target}."
+msgid "Unsupported sort value."
+msgstr ""
+
msgid "Unsupported todo type passed. Supported todo types are: %{todo_types}"
msgstr "传入了ä¸æ”¯æŒçš„待办事项类型。支æŒçš„待办事项类型为: %{todo_types}"
@@ -38336,7 +39107,7 @@ msgid "Updated %{updated_at} by %{updated_by}"
msgstr "由%{updated_by}更新于%{updated_at}"
msgid "Updated date"
-msgstr ""
+msgstr "更新日期"
msgid "Updates"
msgstr "æ›´æ–°"
@@ -38360,7 +39131,7 @@ msgid "Upload"
msgstr "上传"
msgid "Upload %{file_name} file"
-msgstr ""
+msgstr "上传 %{file_name} 文件"
msgid "Upload CSV file"
msgstr "上传CSV文件"
@@ -38458,6 +39229,9 @@ msgstr "当å‰å‘¨æœŸä½¿ç”¨é‡"
msgid "UsageQuota|File attachments and smaller design graphics."
msgstr "文件附件和较å°çš„设计图表。"
+msgid "UsageQuota|From %{storage_enforcement_date} storage limits will apply to this namespace. View and manage your usage in %{strong_start}Group Settings &gt; Usage quotas%{strong_end}."
+msgstr ""
+
msgid "UsageQuota|Git repository."
msgstr "Git仓库。"
@@ -38518,6 +39292,9 @@ msgstr "存储"
msgid "UsageQuota|Storage type"
msgstr "存储类型"
+msgid "UsageQuota|Storage used"
+msgstr ""
+
msgid "UsageQuota|This is the total amount of storage used across your projects within this namespace."
msgstr "这是此å称空间中所有项目使用的存储空间总和。"
@@ -38713,6 +39490,12 @@ msgstr "使用哈希存储"
msgid "Use hashed storage paths for newly created and renamed repositories. Always enabled since 13.0."
msgstr "对新创建和é‡å‘½å的仓库使用哈希存储路径。从 13.0 版起始终å¯ç”¨ã€‚"
+msgid "Use issue count"
+msgstr ""
+
+msgid "Use issue weight"
+msgstr ""
+
msgid "Use one line per URI"
msgstr "æ¯ä¸ªURIå ä¸€è¡Œ"
@@ -38798,7 +39581,7 @@ msgid "User cap"
msgstr "用户上é™"
msgid "User cap cannot be enabled. The group or one of its subgroups or projects is shared externally."
-msgstr ""
+msgstr "无法å¯ç”¨ç”¨æˆ·ä¸Šé™ã€‚该组或其å­ç»„或项目之一在外部共享。"
msgid "User created at"
msgstr "用户创建于"
@@ -39094,6 +39877,9 @@ msgstr "用户å: %{username}"
msgid "Users"
msgstr "用户"
+msgid "Users API rate limit"
+msgstr ""
+
msgid "Users can launch a development environment from a GitLab browser tab when the %{linkStart}Gitpod%{linkEnd} integration is enabled."
msgstr "%{linkStart}Gitpod%{linkEnd} 集æˆåŽï¼Œç”¨æˆ·å¯ä»¥ä»Ž GitLab æµè§ˆå™¨é€‰é¡¹å¡å¯åŠ¨å¼€å‘环境。"
@@ -39332,16 +40118,16 @@ msgid "Version %{versionNumber} (latest)"
msgstr "版本 %{versionNumber} (最新)"
msgid "VersionCheck|Up to date"
-msgstr ""
+msgstr "最新"
msgid "VersionCheck|Update ASAP"
-msgstr ""
+msgstr "尽快更新"
msgid "VersionCheck|Update available"
-msgstr ""
+msgstr "æ›´æ–°å¯ç”¨"
msgid "VersionCheck|Your GitLab Version"
-msgstr ""
+msgstr "您的 GitLab 版本"
msgid "View Documentation"
msgstr "查看文档"
@@ -39417,6 +40203,9 @@ msgstr "在管ç†ä¸­å¿ƒæŸ¥çœ‹ç¾¤ç»„"
msgid "View group labels"
msgstr "查看群组标记"
+msgid "View group pipeline usage quota"
+msgstr ""
+
msgid "View incident details at"
msgstr "查看事件详细信æ¯äºŽ"
@@ -39488,7 +40277,7 @@ msgid "View replaced file @ "
msgstr "查看替æ¢æ–‡ä»¶ @ "
msgid "View seat usage"
-msgstr ""
+msgstr "查看席ä½ä½¿ç”¨æƒ…况"
msgid "View setting"
msgstr "查看设置"
@@ -39568,6 +40357,9 @@ msgstr "æ¼æ´ž"
msgid "Vulnerabilities over time"
msgstr "æ¼æ´žè¶‹åŠ¿å›¾"
+msgid "Vulnerability"
+msgstr ""
+
msgid "Vulnerability Report"
msgstr "æ¼æ´žæŠ¥å‘Š"
@@ -39619,6 +40411,9 @@ msgstr "添加æ¼æ´žå‘现"
msgid "VulnerabilityManagement|An unverified non-confirmed finding"
msgstr "未è¯å®žçš„未确认å‘现"
+msgid "VulnerabilityManagement|At least one identifier is required"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr "更改状æ€"
@@ -39628,12 +40423,24 @@ msgstr "无法处ç†%{issueReference}: %{errorMessage}。"
msgid "VulnerabilityManagement|Create Jira issue"
msgstr "创建 Jira 议题"
+msgid "VulnerabilityManagement|Enter a name"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE code"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE identifier URL"
+msgstr ""
+
msgid "VulnerabilityManagement|Fetching linked Jira issues"
msgstr "获å–å…³è”çš„ Jira 议题"
msgid "VulnerabilityManagement|Manually add a vulnerability entry into the vulnerability report."
msgstr "在æ¼æ´žæŠ¥å‘Šä¸­æ‰‹åŠ¨æ·»åŠ æ¼æ´žæ¡ç›®ã€‚"
+msgid "VulnerabilityManagement|Name is a required field"
+msgstr ""
+
msgid "VulnerabilityManagement|Needs triage"
msgstr "需è¦åˆ†ç±»"
@@ -39649,6 +40456,18 @@ msgstr "需è¦è¯„ä¼°"
msgid "VulnerabilityManagement|Select a method"
msgstr "选择方法"
+msgid "VulnerabilityManagement|Select a severity level"
+msgstr ""
+
+msgid "VulnerabilityManagement|Select a status"
+msgstr ""
+
+msgid "VulnerabilityManagement|Severity is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Something went wrong while creating vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr "试图删除评论时出错。请ç¨åŽå†è¯•ã€‚"
@@ -39673,6 +40492,12 @@ msgstr "出错了,无法读å–用户。"
msgid "VulnerabilityManagement|Something went wrong, could not update vulnerability state."
msgstr "出错了,无法更新æ¼æ´žçŠ¶æ€ã€‚"
+msgid "VulnerabilityManagement|Status is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Submit vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Summary, detailed description, steps to reproduce, etc."
msgstr "总结ã€è¯¦ç»†è¯´æ˜Žã€é‡çŽ°æ­¥éª¤ç­‰"
@@ -39716,7 +40541,7 @@ msgid "Vulnerability|Actual received response is the one received when this faul
msgstr "实际收到的å“应是检测到此故障时收到的å“应"
msgid "Vulnerability|Add another identifier"
-msgstr ""
+msgstr "添加å¦ä¸€ä¸ªæ ‡è¯†ç¬¦"
msgid "Vulnerability|Additional Info"
msgstr "其它信æ¯"
@@ -39761,7 +40586,7 @@ msgid "Vulnerability|Download"
msgstr "下载"
msgid "Vulnerability|Enter the associated CVE or CWE entries for this vulnerability."
-msgstr ""
+msgstr "输入此æ¼æ´žçš„å…³è” CVE 或 CWE æ¡ç›®ã€‚"
msgid "Vulnerability|Evidence"
msgstr "è¯æ®"
@@ -39782,10 +40607,10 @@ msgid "Vulnerability|Identifier"
msgstr "标识"
msgid "Vulnerability|Identifier URL"
-msgstr ""
+msgstr "标识符 URL"
msgid "Vulnerability|Identifier code"
-msgstr ""
+msgstr "识别ç "
msgid "Vulnerability|Identifiers"
msgstr "标识"
@@ -39797,7 +40622,7 @@ msgid "Vulnerability|Information related how the vulnerability was discovered an
msgstr "关于如何å‘现æ¼æ´žåŠå…¶å¯¹ç³»ç»Ÿçš„å½±å“çš„ä¿¡æ¯ã€‚"
msgid "Vulnerability|Learn more about this vulnerability and the best way to resolve it."
-msgstr ""
+msgstr "了解有关此æ¼æ´žçš„更多信æ¯ä»¥åŠè§£å†³å®ƒçš„最佳方法。"
msgid "Vulnerability|Links"
msgstr "链接"
@@ -39812,7 +40637,7 @@ msgid "Vulnerability|Project"
msgstr "项目"
msgid "Vulnerability|Remove identifier row"
-msgstr ""
+msgstr "删除标识符行"
msgid "Vulnerability|Reproduction Assets"
msgstr "å†ç”Ÿèµ„产"
@@ -39827,7 +40652,7 @@ msgid "Vulnerability|Scanner Provider"
msgstr "扫æ工具æ供者"
msgid "Vulnerability|Secure Code Warrior"
-msgstr ""
+msgstr "Secure Code Warrior"
msgid "Vulnerability|Security Audit"
msgstr "安全审计"
@@ -39854,20 +40679,23 @@ msgid "Vulnerability|Tool"
msgstr "工具"
msgid "Vulnerability|Training"
-msgstr ""
+msgstr "培训"
msgid "Vulnerability|Training not available for this vulnerability."
-msgstr ""
+msgstr "没有针对此æ¼æ´žçš„培训。"
msgid "Vulnerability|Unmodified Response"
msgstr "未修改的å“应"
msgid "Vulnerability|View training"
-msgstr ""
+msgstr "查看培训"
msgid "WARNING:"
msgstr "警告:"
+msgid "WARNING: This snippet contains hidden files which might be used to mask malicious behavior. Exercise caution if cloning and executing code from this snippet."
+msgstr ""
+
msgid "Wait for the file to load to copy its contents"
msgstr "等待文件加载以å¤åˆ¶å…¶å†…容"
@@ -40046,45 +40874,54 @@ msgid "Webhooks Help"
msgstr "Webhooks帮助"
msgid "Webhooks|A comment is added to a confidential issue."
-msgstr ""
+msgstr "一æ¡è¯„论被添加到机密议题。"
msgid "Webhooks|A comment is added to an issue."
-msgstr ""
+msgstr "一æ¡è¯„论被添加到议题。"
msgid "Webhooks|A confidential issue is created, updated, closed, or reopened."
-msgstr ""
+msgstr "已创建ã€æ›´æ–°ã€å…³é—­æˆ–é‡æ–°æ‰“开机密议题。"
msgid "Webhooks|A deployment starts, finishes, fails, or is canceled."
-msgstr ""
+msgstr "部署开始ã€å®Œæˆã€å¤±è´¥æˆ–被å–消。"
msgid "Webhooks|A feature flag is turned on or off."
-msgstr ""
+msgstr "一个功能标志已打开或关闭。"
msgid "Webhooks|A group member is created, updated, or removed."
-msgstr ""
+msgstr "已创建ã€æ›´æ–°æˆ–删除群组æˆå‘˜ã€‚"
msgid "Webhooks|A job's status changes."
-msgstr ""
+msgstr "作业的状æ€å‘生å˜åŒ–。"
msgid "Webhooks|A merge request is created, updated, or merged."
-msgstr ""
+msgstr "创建ã€æ›´æ–°æˆ–åˆå¹¶åˆå¹¶è¯·æ±‚。"
msgid "Webhooks|A new tag is pushed to the repository."
-msgstr ""
+msgstr "新标签被推é€åˆ°ä»“库。"
msgid "Webhooks|A pipeline's status changes."
-msgstr ""
+msgstr "æµæ°´çº¿çš„状æ€å˜æ›´ã€‚"
msgid "Webhooks|A release is created or updated."
-msgstr ""
+msgstr "已创建或更新å‘布。"
msgid "Webhooks|A subgroup is created or removed."
-msgstr ""
+msgstr "已创建或删除å­ç»„。"
msgid "Webhooks|A wiki page is created or updated."
-msgstr ""
+msgstr "已创建或更新 wiki 页é¢ã€‚"
msgid "Webhooks|An issue is created, updated, closed, or reopened."
+msgstr "已创建ã€æ›´æ–°ã€å…³é—­æˆ–é‡æ–°æ‰“开议题。"
+
+msgid "Webhooks|Are you sure you want to delete this group hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this project hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this webhook?"
msgstr ""
msgid "Webhooks|Comments"
@@ -40096,6 +40933,9 @@ msgstr "ç§å¯†è¯„论"
msgid "Webhooks|Confidential issues events"
msgstr "ç§å¯†è®®é¢˜äº‹ä»¶"
+msgid "Webhooks|Delete webhook"
+msgstr ""
+
msgid "Webhooks|Deployment events"
msgstr "部署事件"
@@ -40130,7 +40970,7 @@ msgid "Webhooks|Push events"
msgstr "推é€äº‹ä»¶"
msgid "Webhooks|Push to the repository."
-msgstr ""
+msgstr "推é€åˆ°ä»“库。"
msgid "Webhooks|Releases events"
msgstr "å‘布事件"
@@ -40163,10 +41003,10 @@ msgid "Webhooks|URL"
msgstr "网å€"
msgid "Webhooks|URL must be percent-encoded if it contains one or more special characters."
-msgstr ""
+msgstr "如果 URL 包å«ä¸€ä¸ªæˆ–多个特殊字符,则必须进行百分å·ç¼–ç ã€‚"
msgid "Webhooks|Used to validate received payloads. Sent with the request in the %{code_start}X-Gitlab-Token HTTP%{code_end} header."
-msgstr ""
+msgstr "用于验è¯æŽ¥æ”¶åˆ°çš„有效载è·ã€‚与 %{code_start}X-Gitlab-Token HTTP%{code_end} 标头中的请求一起å‘é€ã€‚"
msgid "Webhooks|Webhook failed to connect"
msgstr "Webhook 连接失败"
@@ -40274,7 +41114,7 @@ msgid "When enabled, existing personal access tokens may be revoked. Leave blank
msgstr "å¯ç”¨åŽï¼ŒçŽ°æœ‰çš„个人访问令牌å¯èƒ½ä¼šè¢«æ’¤é”€ã€‚留空表示没有é™åˆ¶ã€‚"
msgid "When enabled, job logs are collected by Datadog and displayed along with pipeline execution traces."
-msgstr ""
+msgstr "å¯ç”¨åŽï¼ŒDatadog 会收集作业日志并与æµæ°´çº¿æ‰§è¡Œè·Ÿè¸ªä¸€èµ·æ˜¾ç¤ºã€‚"
msgid "When inactive, an external authentication provider must be used."
msgstr "当未激活时,必须使用外部身份验è¯æ供程åºã€‚"
@@ -40328,6 +41168,9 @@ msgstr "您为什么è¦æ³¨å†Œï¼Ÿ(å¯é€‰)"
msgid "Wiki"
msgstr "Wiki"
+msgid "Wiki page"
+msgstr ""
+
msgid "Wiki page was successfully created."
msgstr "Wiki页é¢å·²æˆåŠŸåˆ›å»ºã€‚"
@@ -40433,8 +41276,8 @@ msgstr "删除页é¢%{pageTitle}?"
msgid "WikiPageConflictMessage|Someone edited the page the same time you did. Please check out %{wikiLinkStart}the page%{wikiLinkEnd} and make sure your changes will not unintentionally remove theirs."
msgstr "有人在您编辑页é¢çš„åŒæ—¶ç¼–辑了页é¢ã€‚请查看%{wikiLinkStart}页é¢%{wikiLinkEnd}并确ä¿æ‚¨çš„更改ä¸ä¼šæ— æ„中删除它们的更改。"
-msgid "WikiPage|An error occured while trying to render the content editor. Please try again later."
-msgstr "å°è¯•æ¸²æŸ“内容编辑器时å‘生错误。请ç¨åŽå†è¯•ã€‚"
+msgid "WikiPage|An error occurred while trying to render the content editor. Please try again later."
+msgstr ""
msgid "WikiPage|Are you sure you want to switch back to the classic editor?"
msgstr "确定è¦åˆ‡æ¢å›žç»å…¸ç¼–辑器å—?"
@@ -40584,12 +41427,24 @@ msgid "Work in progress Limit"
msgstr "“进行中â€é™åˆ¶"
msgid "WorkItem|Convert to work item"
-msgstr ""
+msgstr "转æ¢ä¸ºå·¥ä½œé¡¹"
msgid "WorkItem|Create work item"
-msgstr ""
+msgstr "创建工作项"
msgid "WorkItem|New Task"
+msgstr "新建任务"
+
+msgid "WorkItem|Something went wrong when creating a work item. Please try again"
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching the work item. Please try again."
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching work item types. Please try again"
+msgstr ""
+
+msgid "WorkItem|Type"
msgstr ""
msgid "WorkItem|Work Items"
@@ -40658,8 +41513,11 @@ msgstr "您已有针对此警报的待处ç†çš„待办事项"
msgid "You are about to add %{usersTag} people to the discussion. They will all receive a notification."
msgstr "å³å°†æŠŠ%{usersTag}相关人员添加到讨论中。他们都会收到通知。"
-msgid "You are about to permanently delete this project"
-msgstr "您将永久删除此项目"
+msgid "You are about to delete this forked project containing:"
+msgstr ""
+
+msgid "You are about to delete this project containing:"
+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 "您å³å°†æŠŠå¸æˆ·æŽ§åˆ¶æƒè½¬ç§»åˆ°%{group_name}群组。此æ“作ä¸å¯æ’¤æ¶ˆï¼Œè½¬ç§»å®ŒæˆåŽï¼Œæ‚¨å°†æ— æ³•è®¿é—®%{group_name}以外的任何群组和项目。"
@@ -40679,6 +41537,9 @@ msgstr "您正在å°è¯•åˆ é™¤å…ˆå‰å·²æ›´æ–°çš„文件。"
msgid "You are attempting to update a file that has changed since you started editing it."
msgstr "您正在å°è¯•æ›´æ–°çš„文件自您开始编辑以æ¥å·²ç»å‘生更改。"
+msgid "You are billed if you exceed this number. %{qsrOverageLinkStart}How does billing work?%{qsrOverageLinkEnd}"
+msgstr ""
+
msgid "You are connected to the Prometheus server, but there is currently no data to display."
msgstr "您已连接到PrometheusæœåŠ¡å™¨ï¼Œä½†å½“å‰æ²¡æœ‰æ•°æ®å¯æ˜¾ç¤ºã€‚"
@@ -40692,7 +41553,7 @@ msgid "You are going to remove the fork relationship from %{project_full_name}.
msgstr "å³å°†åˆ é™¤ä¸Žæºé¡¹ç›®%{project_full_name}的派生关系。确定继续å—?"
msgid "You are going to transfer %{group_name} to another namespace. Are you ABSOLUTELY sure?"
-msgstr ""
+msgstr "您正在将 %{group_name} 转移到å¦ä¸€ä¸ªå‘½å空间,您确定å—?"
msgid "You are going to transfer %{project_full_name} to another namespace. Are you ABSOLUTELY sure?"
msgstr "您将è¦å°† %{project_full_name} 转移到å¦ä¸€ä¸ªå称空间。您完全确定å—?"
@@ -40728,7 +41589,7 @@ msgid "You are not authorized to perform this action"
msgstr "您无æƒæ‰§è¡Œæ­¤æ“作"
msgid "You are not authorized to run this manual job"
-msgstr ""
+msgstr "您无æƒè¿è¡Œæ­¤æ‰‹åŠ¨ä½œä¸š"
msgid "You are not authorized to update this profile"
msgstr "您无æƒæ›´æ–°æ­¤é…置文件"
@@ -40736,6 +41597,9 @@ msgstr "您无æƒæ›´æ–°æ­¤é…置文件"
msgid "You are not authorized to update this scanner profile"
msgstr "您无æƒæ›´æ–°æ­¤æ‰«æ工具é…置文件"
+msgid "You are not authorized to upload metric images"
+msgstr ""
+
msgid "You are now impersonating %{username}"
msgstr "您正在使用%{username}的身份"
@@ -40779,7 +41643,7 @@ msgid "You can also upload existing files from your computer using the instructi
msgstr "您还å¯ä»¥æŒ‰ç…§ä»¥ä¸‹è¯´æ˜Žä»Žè®¡ç®—机中上传现有文件。"
msgid "You can also use group access tokens with Git to authenticate over HTTP(S). %{link_start}Learn more.%{link_end}"
-msgstr ""
+msgstr "您还å¯ä»¥åœ¨ Git 中使用群组访问令牌通过 HTTP(S) 进行身份验è¯ã€‚%{link_start}了解更多。%{link_end}"
msgid "You can also use project access tokens with Git to authenticate over HTTP(S). %{link_start}Learn more.%{link_end}"
msgstr "您还å¯ä»¥å°†é¡¹ç›®è®¿é—®ä»¤ç‰Œä¸Ž Git 结åˆä½¿ç”¨ä»¥é€šè¿‡ HTTP(S) 进行身份验è¯ã€‚ %{link_start}了解更多。%{link_end}"
@@ -40827,7 +41691,7 @@ msgid "You can enable Registration Features because Service Ping is enabled. To
msgstr "您å¯ä»¥å¯ç”¨æ³¨å†ŒåŠŸèƒ½ï¼Œå› ä¸ºæœåŠ¡ Ping å·²å¯ç”¨ã€‚è¦åœ¨æœªæ¥ç»§ç»­ä½¿ç”¨æ³¨å†ŒåŠŸèƒ½ï¼Œæ‚¨è¿˜éœ€è¦é€šè¿‡æ–°çš„云许å¯æœåŠ¡å‘ GitLab 注册。"
msgid "You can enable group access token creation in %{link_start}group settings%{link_end}."
-msgstr ""
+msgstr "您å¯ä»¥åœ¨%{link_start}群组设置%{link_end}中å¯ç”¨ç¾¤ç»„访问令牌创建。"
msgid "You can enable project access token creation in %{link_start}group settings%{link_end}."
msgstr "您å¯ä»¥åœ¨ %{link_start}群组设置%{link_end} 中å¯ç”¨é¡¹ç›®è®¿é—®ä»¤ç‰Œåˆ›å»ºã€‚"
@@ -40889,9 +41753,6 @@ msgstr "您åªèƒ½å°†é¡¹ç›®è½¬ç§»åˆ°æ‚¨ç®¡ç†çš„命å空间。"
msgid "You can only upload one design when dropping onto an existing design."
msgstr "通过拖放到现有设计的方å¼ï¼Œæ‚¨æ¯æ¬¡åªèƒ½ä¸Šä¼ ä¸€ä¸ªè®¾è®¡ã€‚"
-msgid "You can recover this project until %{date}"
-msgstr "您å¯ä»¥åœ¨%{date}之å‰æ¢å¤æ­¤é¡¹ç›®"
-
msgid "You can resolve the merge conflict using either the Interactive mode, by choosing %{use_ours} or %{use_theirs} buttons, or by editing the files directly. Commit these changes into %{branch_name}"
msgstr "您å¯ä»¥ä½¿ç”¨äº¤äº’模å¼ï¼Œé€šè¿‡é€‰æ‹© %{use_ours} 或 %{use_theirs} 按钮æ¥è§£å†³åˆå¹¶å†²çªã€‚也å¯ä»¥é€šè¿‡ç›´æŽ¥ç¼–辑文件æ¥è§£å†³åˆå¹¶å†²çªã€‚然åŽå°†è¿™äº›æ›´æ”¹æ交到 %{branch_name}"
@@ -40940,9 +41801,6 @@ msgstr "您ä¸èƒ½å†™å…¥åªè¯»çš„æ¬¡è¦ GitLab Geo 实例。请改用%{link_to_pr
msgid "You cannot write to this read-only GitLab instance."
msgstr "您ä¸èƒ½å†™å…¥è¿™ä¸ªåªè¯»çš„ GitLab 实例。"
-msgid "You can’t %{tag_start}edit%{tag_end} files directly in this project. Fork this project and submit a merge request with your changes."
-msgstr "您ä¸èƒ½åœ¨æ­¤é¡¹ç›®ä¸­ç›´æŽ¥ %{tag_start}编辑%{tag_end},派生(fork)这个项目并æ交一个包å«æ‚¨çš„更改的åˆå¹¶è¯·æ±‚。"
-
msgid "You can’t edit files directly in this project. Fork this project and submit a merge request with your changes."
msgstr "您ä¸èƒ½åœ¨è¿™ä¸ªé¡¹ç›®ä¸­ç›´æŽ¥ç¼–辑文件,请派生(Fork)这个项目并æ交包å«æ‚¨çš„更改的åˆå¹¶è¯·æ±‚。"
@@ -40965,7 +41823,7 @@ msgid "You do not have permission to leave this %{namespaceType}."
msgstr "您没有æƒé™é€€å‡º%{namespaceType}。"
msgid "You do not have permission to run a pipeline on this branch."
-msgstr ""
+msgstr "您没有æƒé™åœ¨æ­¤åˆ†æ”¯ä¸Šè¿è¡Œæµæ°´çº¿ã€‚"
msgid "You do not have permission to run the Web Terminal. Please contact a project administrator."
msgstr "您无æƒè¿è¡ŒWeb终端。请è”系项目管ç†å‘˜ã€‚"
@@ -41059,7 +41917,7 @@ msgid "You have insufficient permissions to create an on-call schedule for this
msgstr "您没有足够的æƒé™æ¥åˆ›å»ºæ­¤é¡¹ç›®çš„待命计划"
msgid "You have insufficient permissions to manage timeline events for this incident"
-msgstr ""
+msgstr "您没有足够的æƒé™ç®¡ç†æ­¤äº‹ä»¶çš„时间线事件"
msgid "You have insufficient permissions to remove an on-call rotation from this project"
msgstr "您的æƒé™ä¸è¶³ï¼Œæ— æ³•ä»Žæ­¤é¡¹ç›®ä¸­åˆ é™¤on-callè½®æ¢"
@@ -41094,14 +41952,11 @@ 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 set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr "您已ç»ä¸ºæ‚¨çš„å¸æˆ·è®¾ç½®äº†ä¸¤æ­¥éªŒè¯ï¼ 如果您无法访问您的2FA 设备,您å¯ä»¥ä½¿ç”¨æ¢å¤ç è®¿é—®æ‚¨çš„å¸æˆ·ã€‚ 或者,如果您上传一个 SSH 密钥,您å¯ä»¥ä½¿ç”¨ %{anchorOpen}使用该密钥生æˆé¢å¤–çš„æ¢å¤ç %{anchorClose}。"
msgid "You have successfully purchased %{product}. You'll receive a receipt by email. Your purchase may take a minute to sync, so refresh the page if you don't see it yet."
-msgstr ""
+msgstr "您已æˆåŠŸè´­ä¹° %{product}。您将通过电å­é‚®ä»¶æ”¶åˆ°æ”¶æ®ã€‚您的购买å¯èƒ½éœ€è¦ä¸€åˆ†é’Ÿæ‰èƒ½åŒæ­¥ï¼Œå¦‚果您还没有看到,请刷新页é¢ã€‚"
msgid "You have successfully purchased a %{plan} plan subscription for %{seats}. You’ll receive a receipt via email."
msgstr "您已æˆåŠŸè´­ä¹°äº†%{seats}用户的%{plan}计划订阅。收æ®å°†é€šè¿‡ç”µå­é‚®ä»¶å‘é€ç»™æ‚¨ã€‚"
@@ -41116,7 +41971,7 @@ msgid "You may close the milestone now."
msgstr "你现在å¯ä»¥å…³é—­è¿™ä¸ªé‡Œç¨‹ç¢‘。"
msgid "You must be authenticated to access this path."
-msgstr ""
+msgstr "您必须ç»è¿‡è®¤è¯æ‰èƒ½è®¿é—®æ­¤è·¯å¾„。"
msgid "You must be logged in to search across all of GitLab"
msgstr "您必须登录æ‰èƒ½åœ¨æ•´ä¸ªGitLab中进行æœç´¢"
@@ -41127,12 +41982,6 @@ msgstr "å¯ç”¨è°ƒè¯•è·Ÿè¸ªæ—¶ï¼Œæ‚¨å¿…须在关è”项目中拥有开å‘人员或
msgid "You must have maintainer access to force delete a lock"
msgstr "必须拥有维护者æƒé™æ‰èƒ½å¼ºåˆ¶åˆ é™¤é”"
-msgid "You must have permission to create a project in a group before forking."
-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 "您必须æ供一个有效的当å‰å¯†ç "
@@ -41500,7 +42349,7 @@ msgid "Your new %{type}"
msgstr "您的新%{type}"
msgid "Your new access token has been created."
-msgstr ""
+msgstr "您的新访问令牌已创建。"
msgid "Your new comment"
msgstr "您的新评论"
@@ -41538,8 +42387,8 @@ msgstr "您的项目"
msgid "Your public email will be displayed on your public profile."
msgstr "您的公开电å­é‚®ä»¶å°†æ˜¾ç¤ºåœ¨æ‚¨çš„公开个人资料中。"
-msgid "Your request for access could not be processed: %{error_meesage}"
-msgstr "您的访问请求无法处ç†: %{error_meesage}"
+msgid "Your request for access could not be processed: %{error_message}"
+msgstr ""
msgid "Your request for access has been queued for review."
msgstr "您的访问请求已进入审核队列。"
@@ -41575,7 +42424,7 @@ msgid "Your subscription expired!"
msgstr "您的订阅已过期ï¼"
msgid "Your subscription has %{remaining_seats_count} out of %{total_seats_count} seats remaining. Even if you reach the number of seats in your subscription, you can continue to add users, and GitLab will bill you for the overage."
-msgstr ""
+msgstr "您的订阅剩余 %{total_seats_count} 个席ä½ä¸­çš„ %{remaining_seats_count} 个。å³ä½¿æ‚¨è¾¾åˆ°è®¢é˜…的席ä½æ•°é‡ï¼Œæ‚¨ä¹Ÿå¯ä»¥ç»§ç»­æ·»åŠ ç”¨æˆ·ï¼Œç³»ç»Ÿä¼šå‘您收å–超é¢è´¹ç”¨ã€‚"
msgid "Your subscription is now expired. To renew, export your license usage file and email it to %{renewal_service_email}. A new license will be emailed to the email address registered in the %{customers_dot}. You can upload this license to your instance. To use Free tier, remove your current license."
msgstr "您的订阅现在已过期。若è¦æ›´æ–°ï¼Œè¯·å°†æ‚¨çš„许å¯è¯ä½¿ç”¨æ–‡ä»¶å¯¼å‡ºå¹¶å‘é€ç”µå­é‚®ä»¶è‡³ %{renewal_service_email}。新的许å¯è¯å°†å‘é€ç”µå­é‚®ä»¶åˆ°åœ¨ %{customers_dot} 注册的电å­é‚®ä»¶åœ°å€ã€‚ 您å¯ä»¥ä¸Šä¼ æ­¤è®¸å¯è¯åˆ°æ‚¨çš„实例。è¦ä½¿ç”¨æ ‡å‡†ç‰ˆï¼Œè¯·åˆ é™¤æ‚¨å½“å‰çš„许å¯è¯ã€‚"
@@ -41707,7 +42556,7 @@ msgstr "项目已有任æ„核准人(any-approver)"
msgid "approval"
msgid_plural "approvals"
-msgstr[0] ""
+msgstr[0] "批准"
msgid "approved by: "
msgstr "已核准人: "
@@ -41718,6 +42567,9 @@ msgstr "已存档"
msgid "archived:"
msgstr "存档:"
+msgid "artifacts"
+msgstr ""
+
msgid "assign yourself"
msgstr "分é…给自己"
@@ -41746,6 +42598,9 @@ msgstr[0] "分支"
msgid "branch name"
msgstr "分支å称"
+msgid "builds"
+msgstr ""
+
msgid "by"
msgstr "æ¥è‡ª"
@@ -41792,7 +42647,7 @@ msgid "cannot be changed if shared runners are enabled"
msgstr "如果å¯ç”¨å…±äº«Runner,则无法更改"
msgid "cannot be enabled"
-msgstr ""
+msgstr "无法å¯ç”¨"
msgid "cannot be enabled because parent group does not allow it"
msgstr "无法å¯ç”¨ï¼Œå› ä¸ºçˆ¶ç¾¤ç»„ä¸å…许"
@@ -42164,6 +43019,9 @@ msgid "compliance violation has already been recorded"
msgstr "è¿è§„行为已被记录"
msgid "contact with same email already exists in group hierarchy"
+msgstr "群组层次结构中已存在具有相åŒç”µå­é‚®ä»¶çš„è”系人"
+
+msgid "container registry images"
msgstr ""
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
@@ -42205,6 +43063,9 @@ msgstr "创建人:"
msgid "data"
msgstr "æ•°æ®"
+msgid "database"
+msgstr ""
+
msgid "date must not be after 9999-12-31"
msgstr "日期ä¸èƒ½åœ¨9999-12-31之åŽ"
@@ -42227,9 +43088,6 @@ msgstr "部署"
msgid "design"
msgstr "设计"
-msgid "detached"
-msgstr "已游离"
-
msgid "disabled"
msgstr "å·²ç¦ç”¨"
@@ -42366,10 +43224,10 @@ msgid "group"
msgstr "群组"
msgid "group access token"
-msgstr ""
+msgstr "群组访问令牌"
msgid "group access tokens"
-msgstr ""
+msgstr "群组访问令牌"
msgid "group members"
msgstr "群组æˆå‘˜"
@@ -42474,8 +43332,8 @@ msgstr "相关群组ä¸å«æ¨¡ç‰ˆ"
msgid "is not a valid X509 certificate."
msgstr "ä¸æ˜¯æœ‰æ•ˆçš„X509è¯ä¹¦ã€‚"
-msgid "is not allowed for sign-up."
-msgstr "ä¸å…许注册。"
+msgid "is not allowed for sign-up. Please use your regular email address."
+msgstr ""
msgid "is not allowed for this group."
msgstr "在此群组中ä¸è¢«å…许。"
@@ -42486,7 +43344,7 @@ msgstr "在此项目中ä¸è¢«å…许。"
msgid "is not allowed since the group is not top-level group."
msgstr "ä¸å…许,因为该群组ä¸æ˜¯é¡¶çº§ç¾¤ç»„。"
-msgid "is not allowed."
+msgid "is not allowed. Please use your regular email address."
msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
@@ -42573,6 +43431,9 @@ msgstr "少于一分钟"
msgid "level: %{level}"
msgstr "等级: %{level}"
+msgid "lfs objects"
+msgstr ""
+
msgid "limit of %{project_limit} reached"
msgstr "已达到%{project_limit}çš„é™åˆ¶"
@@ -42747,7 +43608,7 @@ msgid "mrWidget|Hide %{widget} details"
msgstr "éšè— %{widget} 的详细信æ¯"
msgid "mrWidget|If the %{type} branch exists in your local repository, you can merge this merge request manually using the command line."
-msgstr ""
+msgstr "如果本地仓库中存在 %{type} 分支,å¯ä»¥ä½¿ç”¨å‘½ä»¤è¡Œæ‰‹åŠ¨åˆå¹¶è¿™ä¸ªåˆå¹¶è¯·æ±‚。"
msgid "mrWidget|If the last pipeline ran in the fork project, it may be inaccurate. Before merge, we advise running a pipeline in this project."
msgstr "如果最åŽä¸€ä¸ªæµæ°´çº¿è¿è¡Œåœ¨æ´¾ç”Ÿé¡¹ç›®ä¸­ï¼Œå®ƒå¯èƒ½ä¸å‡†ç¡®ã€‚åˆå¹¶å‰ï¼Œæˆ‘们建议在这个项目中è¿è¡Œä¸€æ¡æµæ°´çº¿ã€‚"
@@ -42789,11 +43650,14 @@ msgstr "åˆå¹¶è¢«é˜»æ­¢ï¼šå¿…须解决åˆå¹¶å†²çªã€‚"
msgid "mrWidget|Merge blocked: pipeline must succeed. It's waiting for a manual action to continue."
msgstr "åˆå¹¶è¢«é˜»æ­¢ï¼šæµæ°´çº¿å¿…é¡»æˆåŠŸã€‚等待手动完æˆæ“作。"
+msgid "mrWidget|Merge blocked: pipeline must succeed. Push a commit that fixes the failure, or %{linkStart}learn about other solutions.%{linkEnd}"
+msgstr ""
+
msgid "mrWidget|Merge blocked: this merge request must be approved."
msgstr "åˆå¹¶è¢«é˜»æ­¢ï¼šå¿…须批准此åˆå¹¶è¯·æ±‚。"
msgid "mrWidget|Merge blocked: you can only merge after the above items are resolved."
-msgstr ""
+msgstr "åˆå¹¶é˜»å¡žï¼šè§£å†³ä¸Šè¿°é—®é¢˜åŽæ‰èƒ½åˆå¹¶ã€‚"
msgid "mrWidget|Merge failed."
msgstr "åˆå¹¶å¤±è´¥ã€‚"
@@ -42850,7 +43714,7 @@ msgid "mrWidget|Plain diff"
msgstr "文本差异"
msgid "mrWidget|Please restore it or use a different %{type} branch."
-msgstr ""
+msgstr "请还原它或使用ä¸åŒçš„ %{type} 分支。"
msgid "mrWidget|Ready to be merged automatically. Ask someone with write access to this repository to merge this request"
msgstr "å·²å¯è‡ªåŠ¨åˆå¹¶ã€‚ 请具有仓库写入æƒé™çš„用户æ¥åˆå¹¶æ­¤è¯·æ±‚"
@@ -42898,7 +43762,7 @@ msgid "mrWidget|Show %{widget} details"
msgstr "显示 %{widget} 详情"
msgid "mrWidget|The %{type} branch %{codeStart}%{name}%{codeEnd} does not exist."
-msgstr ""
+msgstr "%{type} 分支 %{codeStart}%{name}%{codeEnd} ä¸å­˜åœ¨ã€‚"
msgid "mrWidget|The changes were merged into"
msgstr "更改已åˆå¹¶åˆ°"
@@ -42906,9 +43770,6 @@ msgstr "更改已åˆå¹¶åˆ°"
msgid "mrWidget|The changes were not merged into"
msgstr "更改未åˆå¹¶åˆ°"
-msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
-msgstr "æ­¤åˆå¹¶è¯·æ±‚çš„æµæ°´çº¿æœªå®Œæˆã€‚推é€æ–°çš„æ交以修å¤å¤±è´¥ï¼Œæˆ–检查 %{linkStart}故障排查文档%{linkEnd} 以查看其它å¯èƒ½çš„æ“作。"
-
msgid "mrWidget|The source branch has been deleted"
msgstr "æºåˆ†æ”¯å·²åˆ é™¤"
@@ -43056,9 +43917,6 @@ msgstr "åªèƒ½åœ¨æœ€é¡¶çº§ç¾¤ç»„中使用。"
msgid "open issue"
msgstr "å¼€å¯çš„议题"
-msgid "opened %{timeAgo}"
-msgstr "å¼€å¯äºŽ%{timeAgo}"
-
msgid "or"
msgstr "或"
@@ -43069,6 +43927,12 @@ msgid "out of %d total test"
msgid_plural "out of %d total tests"
msgstr[0] "于总计%d个测试中"
+msgid "packages"
+msgstr ""
+
+msgid "pages"
+msgstr ""
+
msgid "parent"
msgid_plural "parents"
msgstr[0] "上级"
@@ -43214,6 +44078,9 @@ msgid "reply"
msgid_plural "replies"
msgstr[0] "æ¡å›žå¤"
+msgid "repositories"
+msgstr ""
+
msgid "repository:"
msgstr "仓库:"
@@ -43334,12 +44201,18 @@ msgstr "我们正在添加GitLab CIé…置文件,以将æµæ°´çº¿æ·»åŠ åˆ°é¡¹ç›®
msgid "tag name"
msgstr "标签å称"
+msgid "terraform states"
+msgstr ""
+
msgid "the correct format."
msgstr "正确的格å¼ã€‚"
msgid "the file"
msgstr "文件"
+msgid "the following epic(s)"
+msgstr ""
+
msgid "the following issue(s)"
msgstr "下列议题"
@@ -43352,21 +44225,12 @@ msgstr "然åŽ"
msgid "this document"
msgstr "此文档"
-msgid "this issue cannot be assigned to a confidential epic since it is public"
-msgstr "此议题ä¸èƒ½åˆ†é…ç»™ä¿å¯†çš„å²è¯—,因为它是公开的"
-
-msgid "this issue cannot be made public since it belongs to a confidential epic"
-msgstr "此议题ä¸èƒ½å…¬å¼€ï¼Œå› ä¸ºå®ƒå±žäºŽä¿å¯†çš„å²è¯—"
-
msgid "time summary"
msgstr "时间总计"
msgid "toggle collapse"
msgstr "切æ¢æŠ˜å "
-msgid "train"
-msgstr "队列"
-
msgid "triggered"
msgstr "已触å‘"
@@ -43494,3 +44358,6 @@ msgstr "{group}"
msgid "{project}"
msgstr "{project}"
+msgid "✔"
+msgstr ""
+
diff --git a/locale/zh_HK/gitlab.po b/locale/zh_HK/gitlab.po
index 968aec37689..4356c4d81ec 100644
--- a/locale/zh_HK/gitlab.po
+++ b/locale/zh_HK/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: zh-HK\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2022-02-02 15:49\n"
+"PO-Revision-Date: 2022-03-01 20:41\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -132,6 +132,10 @@ msgid "%d approver (you've approved)"
msgid_plural "%d approvers (you've approved)"
msgstr[0] ""
+msgid "%d assigned issue"
+msgid_plural "%d assigned issues"
+msgstr[0] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -352,8 +356,20 @@ msgid "%d vulnerability dismissed"
msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
-msgid "%d vulnerability updated"
-msgid_plural "%d vulnerabilities updated"
+msgid "%d vulnerability set to confirmed"
+msgid_plural "%d vulnerabilities set to confirmed"
+msgstr[0] ""
+
+msgid "%d vulnerability set to dismissed"
+msgid_plural "%d vulnerabilities set to dismissed"
+msgstr[0] ""
+
+msgid "%d vulnerability set to needs triage"
+msgid_plural "%d vulnerabilities set to needs triage"
+msgstr[0] ""
+
+msgid "%d vulnerability set to resolved"
+msgid_plural "%d vulnerabilities set to resolved"
msgstr[0] ""
msgid "%d warning found:"
@@ -434,6 +450,12 @@ msgstr[0] ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{completed} of %{total} issues closed"
+msgstr ""
+
+msgid "%{completed} of %{total} weight completed"
+msgstr ""
+
msgid "%{cores} cores"
msgstr ""
@@ -776,6 +798,9 @@ msgstr ""
msgid "%{openedIssues} open, %{closedIssues} closed"
msgstr ""
+msgid "%{percentage}%% issues closed"
+msgstr ""
+
msgid "%{percentage}%% weight completed"
msgstr ""
@@ -1190,6 +1215,9 @@ msgid "- User"
msgid_plural "- Users"
msgstr[0] ""
+msgid "- of - issues closed"
+msgstr ""
+
msgid "- of - weight completed"
msgstr ""
@@ -1309,7 +1337,7 @@ msgstr ""
msgid "1000+"
msgstr ""
-msgid "192.168.0.0/24"
+msgid "192.168.0.0/24 or 2001:0DB8:1234::/48"
msgstr ""
msgid "1st contribution!"
@@ -1621,13 +1649,13 @@ msgstr ""
msgid "AWS Access Key"
msgstr ""
-msgid "AWS Access Key. Only required if not using role instance credentials"
+msgid "AWS Secret Access Key"
msgstr ""
-msgid "AWS Secret Access Key"
+msgid "AWS access key ID (Optional)"
msgstr ""
-msgid "AWS Secret Access Key. Only required if not using role instance credentials"
+msgid "AWS secret access key (Optional)"
msgstr ""
msgid "AWS service error: %{error}"
@@ -1687,9 +1715,6 @@ msgstr ""
msgid "Access granted"
msgstr ""
-msgid "Access key ID"
-msgstr ""
-
msgid "Access requests"
msgstr ""
@@ -1864,7 +1889,7 @@ msgstr ""
msgid "Activity"
msgstr "活動"
-msgid "Activity|An error occured while retrieving activity. Reload the page to try again."
+msgid "Activity|An error occurred while retrieving activity. Reload the page to try again."
msgstr ""
msgid "Add"
@@ -1903,6 +1928,9 @@ msgstr ""
msgid "Add a %{type}"
msgstr ""
+msgid "Add a GCP region"
+msgstr ""
+
msgid "Add a GPG key"
msgstr ""
@@ -1954,6 +1982,9 @@ msgstr ""
msgid "Add a numbered list"
msgstr ""
+msgid "Add a related epic"
+msgstr ""
+
msgid "Add a related issue"
msgstr ""
@@ -2068,6 +2099,9 @@ msgstr ""
msgid "Add or subtract spent time"
msgstr "增加或減少所花時間"
+msgid "Add people"
+msgstr ""
+
msgid "Add previously merged commits"
msgstr ""
@@ -2134,6 +2168,9 @@ msgstr ""
msgid "Add webhook"
msgstr ""
+msgid "Add your team members and others to GitLab."
+msgstr ""
+
msgid "Add/remove"
msgstr ""
@@ -2956,12 +2993,6 @@ msgstr ""
msgid "AdvancedSearch|Reindex required"
msgstr ""
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. Permanently deleting this project will %{strongStart}immediately delete%{strongEnd} its repositories and %{strongStart}all related resources%{strongEnd}, including issues, merge requests etc."
-msgstr ""
-
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. You will lose this project's repository and %{strongStart}all related resources%{strongEnd}, including issues and merge requests."
-msgstr ""
-
msgid "After a successful password update you will be redirected to login screen."
msgstr ""
@@ -2992,6 +3023,9 @@ msgstr ""
msgid "Akismet helps prevent the creation of spam issues in public projects."
msgstr ""
+msgid "Alert"
+msgstr ""
+
msgid "AlertManagement|Acknowledged"
msgstr ""
@@ -3364,9 +3398,6 @@ msgstr ""
msgid "All environments"
msgstr ""
-msgid "All epics"
-msgstr ""
-
msgid "All groups and projects"
msgstr ""
@@ -4101,11 +4132,14 @@ msgstr ""
msgid "ApplicationSettings|Approve users in the pending approval status?"
msgstr ""
-msgid "ApplicationSettings|By making this change, you will automatically approve %d user with the pending approval status."
-msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users with the pending approval status."
+msgid "ApplicationSettings|Approve users who are pending approval?"
+msgstr ""
+
+msgid "ApplicationSettings|By making this change, you will automatically approve %d user who is pending approval."
+msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users who are pending approval."
msgstr[0] ""
-msgid "ApplicationSettings|By making this change, you will automatically approve all users in pending approval status."
+msgid "ApplicationSettings|By making this change, you will automatically approve all users who are pending approval."
msgstr ""
msgid "ApplicationSettings|Denied domains for sign-ups"
@@ -4506,10 +4540,10 @@ msgstr ""
msgid "Archiving the project will make it entirely read-only. It is hidden from the dashboard and doesn't show up in searches. %{strong_start}The repository cannot be committed to, and no issues, comments, or other entities can be created.%{strong_end} %{link_start}Learn more.%{link_end}"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to delete this project?"
+msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
+msgid "Are you absolutely sure?"
msgstr ""
msgid "Are you sure that you want to archive this project?"
@@ -4545,12 +4579,18 @@ msgstr ""
msgid "Are you sure you want to delete this SSH key?"
msgstr ""
+msgid "Are you sure you want to delete this comment?"
+msgstr ""
+
msgid "Are you sure you want to delete this deploy key?"
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 label?"
+msgstr ""
+
msgid "Are you sure you want to delete this pipeline schedule?"
msgstr "確定è¦åˆªé™¤æ­¤æµæ°´ç·šè¨ˆåŠƒå—Žï¼Ÿ"
@@ -4566,9 +4606,6 @@ msgstr ""
msgid "Are you sure you want to discard your changes?"
msgstr ""
-msgid "Are you sure you want to erase this build?"
-msgstr ""
-
msgid "Are you sure you want to import %d repository?"
msgid_plural "Are you sure you want to import %d repositories?"
msgstr[0] ""
@@ -4615,6 +4652,9 @@ msgstr ""
msgid "Are you sure you want to remove this list?"
msgstr ""
+msgid "Are you sure you want to remove this nickname?"
+msgstr ""
+
msgid "Are you sure you want to reset the health check token?"
msgstr "確定è¦é‡ç½®å¥åº·æª¢æŸ¥ä»¤ç‰Œå—Žï¼Ÿ"
@@ -4627,10 +4667,10 @@ 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?"
+msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
msgstr ""
-msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
+msgid "Are you sure you want to revoke this project access token? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to stop this environment?"
@@ -4777,9 +4817,6 @@ msgstr ""
msgid "Assigned to %{assignee_name}"
msgstr ""
-msgid "Assigned to %{name}"
-msgstr ""
-
msgid "Assigned to me"
msgstr ""
@@ -4842,6 +4879,9 @@ msgstr[0] ""
msgid "Attaching the file failed."
msgstr ""
+msgid "Attention"
+msgstr ""
+
msgid "Audit Events"
msgstr ""
@@ -5004,6 +5044,12 @@ msgstr ""
msgid "Authorized applications (%{size})"
msgstr ""
+msgid "AuthorizedApplication|Are you sure you want to revoke this application?"
+msgstr ""
+
+msgid "AuthorizedApplication|Revoke application"
+msgstr ""
+
msgid "Authors: %{authors}"
msgstr ""
@@ -6193,6 +6239,9 @@ msgstr ""
msgid "CICDAnalytics|Shared Runners Usage"
msgstr ""
+msgid "CICDAnalytics|Shared runner pipeline minute duration by month"
+msgstr ""
+
msgid "CICDAnalytics|Shared runner usage"
msgstr ""
@@ -6334,6 +6383,9 @@ msgstr ""
msgid "Can create groups:"
msgstr ""
+msgid "Can not delete primary training"
+msgstr ""
+
msgid "Can't apply as the source branch was deleted."
msgstr ""
@@ -6667,9 +6719,6 @@ msgstr ""
msgid "Changing any setting here requires an application restart"
msgstr ""
-msgid "Changing group URL can have unintended side effects."
-msgstr ""
-
msgid "Charts can't be displayed as the request for data has timed out. %{documentationLink}"
msgstr ""
@@ -6757,9 +6806,6 @@ msgstr ""
msgid "Checking branch availability..."
msgstr ""
-msgid "Checking group URL availability..."
-msgstr ""
-
msgid "Checking group path availability..."
msgstr ""
@@ -7251,6 +7297,9 @@ msgstr ""
msgid "Clear recent searches"
msgstr ""
+msgid "Clear repository checks"
+msgstr ""
+
msgid "Clear search"
msgstr ""
@@ -7383,9 +7432,6 @@ msgstr ""
msgid "Closed MRs"
msgstr ""
-msgid "Closed epics"
-msgstr ""
-
msgid "Closed issues"
msgstr "已關閉議題"
@@ -7422,13 +7468,13 @@ msgstr ""
msgid "Cluster level"
msgstr ""
-msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
+msgid "Cluster type must be specified for Stages::ClusterEndpointInserter"
msgstr ""
msgid "ClusterAgents|%{name} successfully deleted"
msgstr ""
-msgid "ClusterAgents|%{number} of %{total} Agents"
+msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
@@ -7470,6 +7516,15 @@ msgstr ""
msgid "ClusterAgents|Agent never connected to GitLab"
msgstr ""
+msgid "ClusterAgents|Agent version mismatch"
+msgstr ""
+
+msgid "ClusterAgents|Agent version mismatch and update"
+msgstr ""
+
+msgid "ClusterAgents|Agent version update required"
+msgstr ""
+
msgid "ClusterAgents|All"
msgstr ""
@@ -7494,7 +7549,7 @@ msgstr ""
msgid "ClusterAgents|Configuration"
msgstr ""
-msgid "ClusterAgents|Connect a cluster through the Agent"
+msgid "ClusterAgents|Connect a cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connect existing cluster"
@@ -7503,13 +7558,13 @@ msgstr ""
msgid "ClusterAgents|Connect with a certificate"
msgstr ""
-msgid "ClusterAgents|Connect with agent"
+msgid "ClusterAgents|Connect with an agent"
msgstr ""
msgid "ClusterAgents|Connect with the GitLab Agent"
msgstr ""
-msgid "ClusterAgents|Connect your cluster through the Agent"
+msgid "ClusterAgents|Connect your cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connected"
@@ -7569,7 +7624,10 @@ msgstr ""
msgid "ClusterAgents|How to register an agent?"
msgstr ""
-msgid "ClusterAgents|Install new Agent"
+msgid "ClusterAgents|How to update an agent?"
+msgstr ""
+
+msgid "ClusterAgents|Install a new agent"
msgstr ""
msgid "ClusterAgents|Last connected %{timeAgo}."
@@ -7596,7 +7654,7 @@ msgstr ""
msgid "ClusterAgents|Never connected"
msgstr ""
-msgid "ClusterAgents|No Agents"
+msgid "ClusterAgents|No agents"
msgstr ""
msgid "ClusterAgents|No clusters connected through cluster certificates"
@@ -7656,6 +7714,9 @@ msgstr ""
msgid "ClusterAgents|The agent has not been connected in a long time. There might be a connectivity issue. Last contact was %{timeAgo}."
msgstr ""
+msgid "ClusterAgents|The agent version do not match each other across your cluster's pods. This can happen when a new agent version was just deployed and Kubernetes is shutting down the old pods."
+msgstr ""
+
msgid "ClusterAgents|The recommended installation method includes the token. If you want to follow the advanced installation method provided in the docs, make sure you save the token value before you close this window."
msgstr ""
@@ -7702,6 +7763,9 @@ msgstr ""
msgid "ClusterAgents|You will need to create a token to connect to your agent"
msgstr ""
+msgid "ClusterAgents|Your agent version is out of sync with your GitLab version (v%{version}), which might cause compatibility problems. Update the agent installed on your cluster to the most recent version."
+msgstr ""
+
msgid "ClusterAgents|Your instance doesn't have the %{linkStart}GitLab Agent Server (KAS)%{linkEnd} set up. Ask a GitLab Administrator to install it."
msgstr ""
@@ -8578,9 +8642,6 @@ msgstr ""
msgid "Comma-separated list of email addresses."
msgstr ""
-msgid "Comma-separated list of users allowed to exceed the rate limit."
-msgstr ""
-
msgid "Comma-separated, e.g. '1.1.1.1, 2.2.2.0/24'"
msgstr ""
@@ -8906,6 +8967,12 @@ msgstr ""
msgid "Confidential"
msgstr "隱密"
+msgid "Confidential issue"
+msgstr ""
+
+msgid "Confidential note"
+msgstr ""
+
msgid "Confidentiality"
msgstr "隱密的"
@@ -8939,6 +9006,9 @@ msgstr ""
msgid "Configure Dependency Scanning in `.gitlab-ci.yml`, creating this file if it does not already exist"
msgstr ""
+msgid "Configure GitLab"
+msgstr ""
+
msgid "Configure GitLab runners to start using the Web Terminal. %{helpStart}Learn more.%{helpEnd}"
msgstr ""
@@ -8987,6 +9057,15 @@ msgstr ""
msgid "Configure pipelines to deploy web apps, backend services, APIs and static resources to Google Cloud"
msgstr ""
+msgid "Configure region"
+msgstr ""
+
+msgid "Configure region for environment"
+msgstr ""
+
+msgid "Configure regions"
+msgstr ""
+
msgid "Configure repository mirroring."
msgstr ""
@@ -9020,6 +9099,9 @@ msgstr ""
msgid "Configure which lists are shown for anyone who visits this board"
msgstr ""
+msgid "Configure your environments to be deployed to specific geographical regions"
+msgstr ""
+
msgid "Confirm"
msgstr ""
@@ -9719,10 +9801,10 @@ msgstr ""
msgid "CorpusManagement|Actions"
msgstr ""
-msgid "CorpusManagement|Corpus are used in fuzz testing as mutation source to Improve future testing."
+msgid "CorpusManagement|Corpus file"
msgstr ""
-msgid "CorpusManagement|Corpus file"
+msgid "CorpusManagement|Corpus files are used in coverage-guided fuzz testing as seed inputs to improve testing."
msgstr ""
msgid "CorpusManagement|Corpus files must be in *.zip format. Maximum 5 GB"
@@ -9776,6 +9858,9 @@ msgstr ""
msgid "Could not apply %{name} command."
msgstr ""
+msgid "Could not apply %{name} command. %{message}."
+msgstr ""
+
msgid "Could not authorize chat nickname. Try again!"
msgstr ""
@@ -9926,6 +10011,9 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
+msgid "Create a group"
+msgstr ""
+
msgid "Create a merge request"
msgstr ""
@@ -9950,6 +10038,9 @@ msgstr ""
msgid "Create a personal access token on your account to pull or push via %{protocol}."
msgstr "在帳戶上創建個人訪å•ä»¤ç‰Œï¼Œä»¥é€šéŽ %{protocol} 來拉å–或推é€ã€‚"
+msgid "Create a project"
+msgstr ""
+
msgid "Create an account using:"
msgstr ""
@@ -10313,6 +10404,9 @@ msgstr ""
msgid "Creation date"
msgstr ""
+msgid "Creator"
+msgstr ""
+
msgid "Credentials"
msgstr ""
@@ -10325,9 +10419,15 @@ msgstr ""
msgid "CredentialsInventory|Personal Access Tokens"
msgstr ""
+msgid "CredentialsInventory|Project Access Tokens"
+msgstr ""
+
msgid "CredentialsInventory|SSH Keys"
msgstr ""
+msgid "Credit card required to be on file in order to create a pipeline"
+msgstr ""
+
msgid "Credit card:"
msgstr ""
@@ -10511,9 +10611,6 @@ msgstr ""
msgid "Customer relations"
msgstr ""
-msgid "Customizable by an administrator."
-msgstr ""
-
msgid "Customizable by owners."
msgstr ""
@@ -10643,30 +10740,18 @@ msgstr ""
msgid "CycleAnalytics|%{selectedLabelsCount} selected (%{maxLabels} max)"
msgstr ""
-msgid "CycleAnalytics|%{stageCount} stages selected"
-msgstr ""
-
-msgid "CycleAnalytics|All stages"
-msgstr ""
-
-msgid "CycleAnalytics|Average days to completion"
+msgid "CycleAnalytics|Average time to completion"
msgstr ""
msgid "CycleAnalytics|Date"
msgstr ""
-msgid "CycleAnalytics|Days to completion"
-msgstr ""
-
msgid "CycleAnalytics|Display chart filters"
msgstr ""
msgid "CycleAnalytics|Lead Time for Changes"
msgstr ""
-msgid "CycleAnalytics|No stages selected"
-msgstr ""
-
msgid "CycleAnalytics|Number of tasks"
msgstr ""
@@ -10693,18 +10778,30 @@ msgstr ""
msgid "CycleAnalytics|Showing data for group '%{groupName}' from %{createdAfter} to %{createdBefore}"
msgstr ""
-msgid "CycleAnalytics|Stages"
+msgid "CycleAnalytics|Stage time: %{title}"
msgstr ""
msgid "CycleAnalytics|Tasks by type"
msgstr ""
-msgid "CycleAnalytics|The average time spent in the selected stage for the items that were completed on each date. Data limited to the last 500 items."
+msgid "CycleAnalytics|The average time items spent in this stage. Data limited to items completed within this date range."
msgstr ""
msgid "CycleAnalytics|The given date range is larger than 180 days"
msgstr ""
+msgid "CycleAnalytics|The total time items spent across each value stream stage. Data limited to items completed within this date range."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Stage time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Total time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|Total time"
+msgstr ""
+
msgid "CycleAnalytics|Type of work"
msgstr ""
@@ -10717,9 +10814,6 @@ msgstr ""
msgid "CycleAnalytics|project dropdown filter"
msgstr ""
-msgid "CycleAnalytics|stage dropdown"
-msgstr ""
-
msgid "DAG visualization requires at least 3 dependent jobs."
msgstr ""
@@ -10819,10 +10913,16 @@ msgstr ""
msgid "DastProfiles|AJAX spider"
msgstr ""
+msgid "DastProfiles|API"
+msgstr ""
+
+msgid "DastProfiles|API endpoint URL"
+msgstr ""
+
msgid "DastProfiles|Active"
msgstr ""
-msgid "DastProfiles|Additional request headers (Optional)"
+msgid "DastProfiles|Additional request headers (optional)"
msgstr ""
msgid "DastProfiles|Are you sure you want to delete this profile?"
@@ -10837,6 +10937,9 @@ msgstr ""
msgid "DastProfiles|Branch missing"
msgstr ""
+msgid "DastProfiles|Choose a scan method"
+msgstr ""
+
msgid "DastProfiles|Could not create the scanner profile. Please try again."
msgstr ""
@@ -10906,7 +11009,13 @@ msgstr ""
msgid "DastProfiles|Excluded URLs"
msgstr ""
-msgid "DastProfiles|Excluded URLs (Optional)"
+msgid "DastProfiles|Excluded URLs (optional)"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths (optional)"
msgstr ""
msgid "DastProfiles|Hide debug messages"
@@ -10963,9 +11072,6 @@ msgstr ""
msgid "DastProfiles|Request headers"
msgstr ""
-msgid "DastProfiles|Rest API"
-msgstr ""
-
msgid "DastProfiles|Run the AJAX spider, in addition to the traditional spider, to crawl the target site."
msgstr ""
@@ -10975,6 +11081,9 @@ msgstr ""
msgid "DastProfiles|Save profile"
msgstr ""
+msgid "DastProfiles|Scan method"
+msgstr ""
+
msgid "DastProfiles|Scan mode"
msgstr ""
@@ -11053,12 +11162,24 @@ msgstr ""
msgid "DastProfiles|Website"
msgstr ""
+msgid "DastProfiles|What does each method do?"
+msgstr ""
+
msgid "DastProfiles|You can either choose a passive scan or validate the target site from the site profile management page. %{docsLinkStart}Learn more about site validation.%{docsLinkEnd}"
msgstr ""
msgid "DastProfiles|You cannot run an active scan against an unvalidated site."
msgstr ""
+msgid "DastProfiles|folder/dast_example.har or https://example.com/dast_example.har"
+msgstr ""
+
+msgid "DastProfiles|folder/example.postman_collection.json or https://example.com/"
+msgstr ""
+
+msgid "DastProfiles|folder/openapi.json or https://example.com/openapi.json"
+msgstr ""
+
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
@@ -11165,6 +11286,9 @@ msgstr ""
msgid "DatadogIntegration|API URL"
msgstr ""
+msgid "DatadogIntegration|Custom tags in Datadog. Enter one tag per line in the %{codeOpen}key:value%{codeClose} format. %{linkOpen}How do I use tags?%{linkClose}"
+msgstr ""
+
msgid "DatadogIntegration|Environment"
msgstr ""
@@ -11183,12 +11307,18 @@ msgstr ""
msgid "DatadogIntegration|Tag all data from this GitLab instance in Datadog. Useful when managing several self-managed deployments."
msgstr ""
+msgid "DatadogIntegration|Tags"
+msgstr ""
+
msgid "DatadogIntegration|The Datadog site to send data to. To send data to the EU site, use %{codeOpen}datadoghq.eu%{codeClose}."
msgstr ""
msgid "DatadogIntegration|Trace your GitLab pipelines with Datadog."
msgstr ""
+msgid "DatadogIntegration|have an invalid format"
+msgstr ""
+
msgid "Datasource name not found"
msgstr ""
@@ -11198,9 +11328,6 @@ msgstr ""
msgid "Date merged"
msgstr ""
-msgid "Date picker"
-msgstr ""
-
msgid "Date range"
msgstr ""
@@ -11354,9 +11481,6 @@ msgstr ""
msgid "Definition"
msgstr ""
-msgid "Delayed Project Deletion (%{adjourned_deletion})"
-msgstr ""
-
msgid "DelayedJobs|Are you sure you want to run %{jobName} immediately? Otherwise this job will run automatically after its timer finishes."
msgstr ""
@@ -11435,10 +11559,10 @@ msgstr ""
msgid "Delete pipeline"
msgstr ""
-msgid "Delete project"
+msgid "Delete pipeline schedule"
msgstr ""
-msgid "Delete project. Are you ABSOLUTELY SURE?"
+msgid "Delete project"
msgstr ""
msgid "Delete row"
@@ -11468,6 +11592,9 @@ msgstr ""
msgid "Delete this epic and all descendants?"
msgstr ""
+msgid "Delete this project"
+msgstr ""
+
msgid "Delete user list"
msgstr ""
@@ -11720,6 +11847,12 @@ msgstr ""
msgid "Deploy to..."
msgstr ""
+msgid "DeployBoards|To see deployment progress for your environments, make sure you are deploying to %{codeStart}$KUBE_NAMESPACE%{codeEnd} and annotating with %{codeStart}app.gitlab.com/app=$CI_PROJECT_PATH_SLUG%{codeEnd} and %{codeStart}app.gitlab.com/env=$CI_ENVIRONMENT_SLUG%{codeEnd}."
+msgstr ""
+
+msgid "DeployBoard|Kubernetes Pods"
+msgstr ""
+
msgid "DeployFreeze|Add a freeze period to prevent unintended releases during a period of time for a given environment. You must update the deployment jobs in %{filename} according to the deploy freezes added here. %{freeze_period_link_start}Learn more.%{freeze_period_link_end}"
msgstr ""
@@ -11804,9 +11937,6 @@ msgstr ""
msgid "DeployTokens|Active Deploy Tokens (%{active_tokens})"
msgstr ""
-msgid "DeployTokens|Allows read and write access to registry images."
-msgstr ""
-
msgid "DeployTokens|Allows read and write access to the package registry."
msgstr ""
@@ -11819,6 +11949,9 @@ msgstr ""
msgid "DeployTokens|Allows read-only access to the repository."
msgstr ""
+msgid "DeployTokens|Allows write access to registry images."
+msgstr ""
+
msgid "DeployTokens|Copy deploy token"
msgstr ""
@@ -11912,12 +12045,57 @@ msgstr ""
msgid "Deploying to AWS is easy with GitLab"
msgstr ""
+msgid "Deployment"
+msgstr ""
+
msgid "Deployment Frequency"
msgstr ""
+msgid "Deployment Target|Project deployment target (optional)"
+msgstr ""
+
+msgid "Deployment Target|Select the deployment target"
+msgstr ""
+
msgid "Deployment frequency"
msgstr ""
+msgid "DeploymentTarget|GitLab Pages"
+msgstr ""
+
+msgid "DeploymentTarget|Heroku"
+msgstr ""
+
+msgid "DeploymentTarget|Infrastructure provider (Terraform, Cloudformation, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Kubernetes (GKE, EKS, OpenShift, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Managed container runtime (Fargate, Cloud Run, DigitalOcean App)"
+msgstr ""
+
+msgid "DeploymentTarget|Mobile app store"
+msgstr ""
+
+msgid "DeploymentTarget|No deployment planned"
+msgstr ""
+
+msgid "DeploymentTarget|Other hosting service"
+msgstr ""
+
+msgid "DeploymentTarget|Registry (package or container)"
+msgstr ""
+
+msgid "DeploymentTarget|Self-managed container runtime (Podman, Docker Swarm, Docker Compose)"
+msgstr ""
+
+msgid "DeploymentTarget|Serverless backend (Lambda, Cloud functions)"
+msgstr ""
+
+msgid "DeploymentTarget|Virtual machine (for example, EC2)"
+msgstr ""
+
msgid "Deployments"
msgstr ""
@@ -11955,6 +12133,9 @@ msgstr ""
msgid "Deployment|This deployment was created using the API"
msgstr ""
+msgid "Deployment|Triggerer"
+msgstr ""
+
msgid "Deployment|Waiting"
msgstr ""
@@ -11982,6 +12163,18 @@ msgstr ""
msgid "Deprecated API rate limits"
msgstr ""
+msgid "Deprecations|Feature deprecation and removal"
+msgstr ""
+
+msgid "Deprecations|For information on a possible replacement %{epicStart} learn more about Opstrace %{epicEnd}."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7 and are %{epicStart} scheduled for removal %{epicEnd} in GitLab 15.0."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7, and are %{removal_link_start} scheduled for removal %{link_end} in GitLab 15.0. For information on a possible replacement, %{opstrace_link_start} learn more about Opstrace %{link_end}."
+msgstr ""
+
msgid "Deprioritize label"
msgstr ""
@@ -12226,10 +12419,10 @@ msgstr ""
msgid "DevopsAdoption|At least one deploy"
msgstr ""
-msgid "DevopsAdoption|At least one issue opened"
+msgid "DevopsAdoption|At least one issue created"
msgstr ""
-msgid "DevopsAdoption|At least one merge request opened"
+msgid "DevopsAdoption|At least one merge request created"
msgstr ""
msgid "DevopsAdoption|At least one pipeline successfully run"
@@ -12427,6 +12620,9 @@ msgstr ""
msgid "Direct member"
msgstr ""
+msgid "Direct members"
+msgstr ""
+
msgid "Direct non-authenticated users to this page."
msgstr ""
@@ -12542,6 +12738,9 @@ msgid "Dismiss %d selected vulnerability as"
msgid_plural "Dismiss %d selected vulnerabilities as"
msgstr[0] ""
+msgid "Dismiss Alert"
+msgstr ""
+
msgid "Dismiss merge request promotion"
msgstr ""
@@ -12569,9 +12768,15 @@ msgstr ""
msgid "Display alerts from all configured monitoring tools."
msgstr ""
+msgid "Display milestones"
+msgstr ""
+
msgid "Display name"
msgstr ""
+msgid "Display progress of child issues"
+msgstr ""
+
msgid "Display rendered file"
msgstr ""
@@ -12677,6 +12882,9 @@ msgstr ""
msgid "Download image"
msgstr ""
+msgid "Download payload"
+msgstr ""
+
msgid "Download raw data (.csv)"
msgstr ""
@@ -12854,6 +13062,9 @@ msgstr ""
msgid "Edit in Web IDE"
msgstr ""
+msgid "Edit in pipeline editor"
+msgstr ""
+
msgid "Edit in single-file editor"
msgstr ""
@@ -12896,6 +13107,9 @@ msgstr ""
msgid "Edit your most recent comment in a thread (from an empty textarea)"
msgstr ""
+msgid "Edit, lint, and visualize your pipeline."
+msgstr ""
+
msgid "Edited"
msgstr ""
@@ -13337,6 +13551,9 @@ msgstr ""
msgid "Enforce two-factor authentication for all user sign-ins."
msgstr ""
+msgid "Enhance security by storing service account keys in secret managers - learn more about %{docLinkStart}secret management with GitLab%{docLinkEnd}"
+msgstr ""
+
msgid "Ensure connectivity is available from the GitLab server to the Prometheus server"
msgstr ""
@@ -13397,6 +13614,9 @@ 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 following to confirm:"
+msgstr ""
+
msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
@@ -13926,9 +14146,6 @@ 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 ""
@@ -14064,6 +14281,9 @@ msgstr ""
msgid "Errors:"
msgstr ""
+msgid "Escalate this incident"
+msgstr ""
+
msgid "Escalation Policies"
msgstr ""
@@ -14076,6 +14296,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy"
+msgstr ""
+
msgid "Escalation policy:"
msgstr ""
@@ -14326,6 +14549,9 @@ msgstr ""
msgid "Existing sign in methods may be removed"
msgstr ""
+msgid "Exit."
+msgstr ""
+
msgid "Expand"
msgstr ""
@@ -14422,6 +14648,9 @@ msgstr ""
msgid "Explore public groups"
msgstr ""
+msgid "Explore public projects"
+msgstr ""
+
msgid "Explore snippets"
msgstr ""
@@ -14582,7 +14811,7 @@ msgid "Failed to archive a design. Please try again."
msgid_plural "Failed to archive designs. Please try again."
msgstr[0] ""
-msgid "Failed to assign a reviewer because no user was found."
+msgid "Failed to assign a reviewer because no user was specified."
msgstr ""
msgid "Failed to assign a user because no user was found."
@@ -14648,10 +14877,10 @@ msgstr ""
msgid "Failed to find import label for Jira import."
msgstr ""
-msgid "Failed to generate export, please try again later."
+msgid "Failed to find users for %{missing}"
msgstr ""
-msgid "Failed to generate report, please try again after sometime"
+msgid "Failed to generate export, please try again later."
msgstr ""
msgid "Failed to get ref."
@@ -14750,6 +14979,9 @@ msgstr ""
msgid "Failed to remove a to-do item for the design."
msgstr ""
+msgid "Failed to remove attention because no user was found."
+msgstr ""
+
msgid "Failed to remove mirror."
msgstr ""
@@ -14762,6 +14994,9 @@ msgstr ""
msgid "Failed to remove user key."
msgstr ""
+msgid "Failed to request attention because no user was found."
+msgstr ""
+
msgid "Failed to reset key. Please try again."
msgstr ""
@@ -14843,6 +15078,9 @@ msgstr ""
msgid "Feature Flags"
msgstr ""
+msgid "Feature deprecation and removal"
+msgstr ""
+
msgid "Feature flag status"
msgstr ""
@@ -15339,7 +15577,7 @@ msgstr ""
msgid "For each job, re-use the project workspace. If the workspace doesn't exist, use %{code_open}git clone%{code_close}."
msgstr ""
-msgid "For example, the application using the token or the purpose of the token."
+msgid "For example, the application using the token or the purpose of the token. Do not give sensitive information for the name of the token, as it will be visible to all %{resource_type} members."
msgstr ""
msgid "For files larger than this limit, only index the file name. The file content is neither indexed nor searchable."
@@ -15423,9 +15661,6 @@ msgstr ""
msgid "ForkProject|Select a namespace"
msgstr ""
-msgid "ForkProject|Select a namespace to fork the project"
-msgstr ""
-
msgid "ForkProject|The project can be accessed by any logged in user."
msgstr ""
@@ -15522,6 +15757,9 @@ msgstr ""
msgid "Full name"
msgstr ""
+msgid "GCP region configured"
+msgstr ""
+
msgid "GPG Key ID:"
msgstr ""
@@ -15702,6 +15940,9 @@ msgstr ""
msgid "Geo|Failed"
msgstr ""
+msgid "Geo|Filter Geo sites"
+msgstr ""
+
msgid "Geo|Filter by name"
msgstr ""
@@ -16113,6 +16354,12 @@ msgstr ""
msgid "GitLab Issue"
msgstr ""
+msgid "GitLab KAS"
+msgstr ""
+
+msgid "GitLab Memberships CSV Export"
+msgstr ""
+
msgid "GitLab Pages"
msgstr ""
@@ -16161,6 +16408,9 @@ 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 free to use. Many features for larger teams are part of our %{link_start}paid products%{link_end}. You can try Ultimate for free without any obligation or payment details."
+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 ""
@@ -16287,7 +16537,7 @@ msgstr ""
msgid "GitLabPages|When enabled, all attempts to visit your website through HTTP are automatically redirected to HTTPS using a response with status code 301. Requires a valid certificate for all domains. %{docs_link_start}Learn more.%{link_end}"
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. %{docs_link_start}Learn more.%{link_end}"
+msgid "GitLabPages|When using Pages under the general domain of a GitLab instance (%{pages_host}), you cannot use HTTPS with subdomains of subdomains. If your namespace or groupname contains a dot, it does not work. This is a limitation of the HTTP Over TLS protocol. HTTP pages work if you don't redirect HTTP to HTTPS. %{docs_link_start}Learn more.%{link_end}"
msgstr ""
msgid "GitLabPages|With GitLab Pages you can host your static website directly from your GitLab repository. %{docs_link_start}Learn more.%{link_end}"
@@ -16464,9 +16714,6 @@ msgstr ""
msgid "Go to find file"
msgstr ""
-msgid "Go to fork"
-msgstr ""
-
msgid "Go to issue boards"
msgstr ""
@@ -16674,9 +16921,6 @@ msgstr ""
msgid "Group Hooks"
msgstr ""
-msgid "Group ID"
-msgstr ""
-
msgid "Group Owner must have signed in with SAML before enabling Group Managed Accounts"
msgstr ""
@@ -16704,9 +16948,6 @@ msgstr ""
msgid "Group by"
msgstr ""
-msgid "Group description"
-msgstr ""
-
msgid "Group description (optional)"
msgstr ""
@@ -16821,7 +17062,7 @@ msgstr ""
msgid "Group: %{name}"
msgstr ""
-msgid "GroupActivityMetrics|Issues opened"
+msgid "GroupActivityMetrics|Issues created"
msgstr ""
msgid "GroupActivityMetrics|Last 90 days"
@@ -16830,7 +17071,7 @@ msgstr ""
msgid "GroupActivityMetrics|Members added"
msgstr ""
-msgid "GroupActivityMetrics|Merge Requests opened"
+msgid "GroupActivityMetrics|Merge Requests created"
msgstr ""
msgid "GroupActivityMetrics|Recent activity"
@@ -17121,6 +17362,9 @@ msgstr ""
msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
+msgid "GroupSettings|Choose a group path that does not start with a dash or end with a period. It can also contain alphanumeric characters and underscores."
+msgstr ""
+
msgid "GroupSettings|Compliance frameworks"
msgstr ""
@@ -17154,7 +17398,7 @@ msgstr ""
msgid "GroupSettings|If not specified at the group or instance level, the default is %{default_initial_branch_name}. Does not affect existing repositories."
msgstr ""
-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."
+msgid "GroupSettings|If the parent group's visibility is lower than the group's current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility."
msgstr ""
msgid "GroupSettings|New runners registration token has been generated!"
@@ -17271,7 +17515,10 @@ msgstr ""
msgid "Groups and projects"
msgstr ""
-msgid "Groups and subgroups"
+msgid "Groups are a great way to organize projects and people."
+msgstr ""
+
+msgid "Groups are the best way to manage projects and members."
msgstr ""
msgid "Groups to synchronize"
@@ -17382,13 +17629,16 @@ msgstr ""
msgid "GroupsTree|Are you sure you want to leave the \"%{fullName}\" group?"
msgstr ""
-msgid "GroupsTree|Edit group"
+msgid "GroupsTree|Delete"
+msgstr ""
+
+msgid "GroupsTree|Edit"
msgstr ""
msgid "GroupsTree|Failed to leave the group. Please make sure you are not the only owner."
msgstr ""
-msgid "GroupsTree|Leave this group"
+msgid "GroupsTree|Leave group"
msgstr ""
msgid "GroupsTree|Loading groups"
@@ -17400,9 +17650,57 @@ msgstr ""
msgid "GroupsTree|No groups or projects matched your search"
msgstr ""
+msgid "GroupsTree|Options"
+msgstr ""
+
msgid "GroupsTree|Search by name"
msgstr ""
+msgid "Groups|Avatar will be removed. Are you sure?"
+msgstr ""
+
+msgid "Groups|Changing group URL can have unintended side effects."
+msgstr ""
+
+msgid "Groups|Checking group URL availability..."
+msgstr ""
+
+msgid "Groups|Enter a descriptive name for your group."
+msgstr ""
+
+msgid "Groups|Group ID"
+msgstr ""
+
+msgid "Groups|Group URL"
+msgstr ""
+
+msgid "Groups|Group avatar"
+msgstr ""
+
+msgid "Groups|Group description (optional)"
+msgstr ""
+
+msgid "Groups|Group name"
+msgstr ""
+
+msgid "Groups|Group path is available."
+msgstr ""
+
+msgid "Groups|Group path is unavailable. Path has been replaced with a suggested available path."
+msgstr ""
+
+msgid "Groups|Learn more"
+msgstr ""
+
+msgid "Groups|Must start with letter, digit, emoji, or underscore. Can also contain periods, dashes, spaces, and parentheses."
+msgstr ""
+
+msgid "Groups|Remove avatar"
+msgstr ""
+
+msgid "Groups|Save changes"
+msgstr ""
+
msgid "Guideline"
msgstr ""
@@ -17412,6 +17710,9 @@ msgstr ""
msgid "HAR file path or URL"
msgstr ""
+msgid "HTTP Archive (HAR)"
+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 ""
@@ -17810,6 +18111,9 @@ msgstr ""
msgid "INFO: Your SSH key is expiring soon. Please generate a new key."
msgstr ""
+msgid "IP"
+msgstr ""
+
msgid "IP Address"
msgstr ""
@@ -17846,6 +18150,9 @@ msgstr ""
msgid "IdentityVerification|Verify your identity"
msgstr ""
+msgid "IdentityVerification|You can always verify your account at a later time to create a group."
+msgstr ""
+
msgid "If any indexed field exceeds this limit, it is truncated to this number of characters. The rest of the content is neither indexed nor searchable. This does not apply to repository and wiki indexing. For unlimited characters, set this to 0."
msgstr ""
@@ -17903,6 +18210,9 @@ msgstr ""
msgid "If you add %{codeStart}needs%{codeEnd} to jobs in your pipeline you'll be able to view the %{codeStart}needs%{codeEnd} relationships between jobs in this tab as a %{linkStart}Directed Acyclic Graph (DAG)%{linkEnd}."
msgstr ""
+msgid "If you are added to a project, it will be displayed here."
+msgstr ""
+
msgid "If you did not initiate these sign-in attempts, please reach out to your administrator or enable two-factor authentication (2FA) on your account."
msgstr ""
@@ -18206,12 +18516,24 @@ msgstr ""
msgid "InProductMarketing|3 ways to dive into GitLab CI/CD"
msgstr ""
+msgid "InProductMarketing|A single application eliminates complex integrations, data chokepoints, and toolchain maintenance, resulting in greater productivity and lower cost."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features, build more efficiently, strengthen security and compliance."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features."
+msgstr ""
+
msgid "InProductMarketing|Actually, GitLab makes the team work (better)"
msgstr ""
msgid "InProductMarketing|And finally %{deploy_link} a Python application."
msgstr ""
+msgid "InProductMarketing|And many more..."
+msgstr ""
+
msgid "InProductMarketing|Are your runners ready?"
msgstr ""
@@ -18230,15 +18552,33 @@ msgstr ""
msgid "InProductMarketing|Blog"
msgstr ""
+msgid "InProductMarketing|Break down silos to coordinate seamlessly across development, operations, and security with a consistent experience across the development lifecycle."
+msgstr ""
+
+msgid "InProductMarketing|Burn up/down charts"
+msgstr ""
+
msgid "InProductMarketing|By enabling code owners and required merge approvals the right person will review the right MR. This is a win-win: cleaner code and a more efficient review process."
msgstr ""
msgid "InProductMarketing|Click on the number below that corresponds with your answer — 1 being very difficult, 5 being very easy."
msgstr ""
+msgid "InProductMarketing|Code owners"
+msgstr ""
+
msgid "InProductMarketing|Code owners and required merge approvals are part of the paid tiers of GitLab. You can start a free 30-day trial of GitLab Ultimate and enable these features in less than 5 minutes with no credit card required."
msgstr ""
+msgid "InProductMarketing|Code review analytics"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration across stages in GitLab"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration made easy"
+msgstr ""
+
msgid "InProductMarketing|Create a custom CI runner with just a few clicks"
msgstr ""
@@ -18248,12 +18588,21 @@ msgstr ""
msgid "InProductMarketing|Create a project in GitLab in 5 minutes"
msgstr ""
+msgid "InProductMarketing|Create well-defined workflows by using scoped labels on issues, merge requests, and epics. Labels with the same scope cannot be used together, which prevents conflicts."
+msgstr ""
+
msgid "InProductMarketing|Create your first project!"
msgstr ""
+msgid "InProductMarketing|Define who owns specific files or directories, so the right reviewers are suggested when a merge request introduces changes to those files."
+msgstr ""
+
msgid "InProductMarketing|Deliver Better Products Faster"
msgstr ""
+msgid "InProductMarketing|Dependency scanning"
+msgstr ""
+
msgid "InProductMarketing|Did you know teams that use GitLab are far more efficient?"
msgstr ""
@@ -18263,15 +18612,27 @@ msgstr ""
msgid "InProductMarketing|Dig in and create a project and a repo"
msgstr ""
+msgid "InProductMarketing|Discover Premium & Ultimate"
+msgstr ""
+
+msgid "InProductMarketing|Discover Premium & Ultimate."
+msgstr ""
+
msgid "InProductMarketing|Do you have a minute?"
msgstr ""
msgid "InProductMarketing|Do you have a teammate who would be perfect for this task?"
msgstr ""
+msgid "InProductMarketing|Dynamic application security testing"
+msgstr ""
+
msgid "InProductMarketing|Easy"
msgstr ""
+msgid "InProductMarketing|Epics"
+msgstr ""
+
msgid "InProductMarketing|Expand your DevOps journey with a free GitLab trial"
msgstr ""
@@ -18293,9 +18654,15 @@ msgstr ""
msgid "InProductMarketing|Feel the need for speed?"
msgstr ""
+msgid "InProductMarketing|Find and fix bottlenecks in your code review process by understanding how long open merge requests have been in review."
+msgstr ""
+
msgid "InProductMarketing|Find out how your teams are really doing"
msgstr ""
+msgid "InProductMarketing|Find out if your external libraries are safe. Run dependency scanning jobs that check for known vulnerabilities in your external libraries."
+msgstr ""
+
msgid "InProductMarketing|Follow our steps"
msgstr ""
@@ -18332,6 +18699,9 @@ msgstr ""
msgid "InProductMarketing|GitLab is better with teammates to help out!"
msgstr ""
+msgid "InProductMarketing|GitLab is infrastructure agnostic (supporting GCP, AWS, Azure, OpenShift, VMWare, On Prem, Bare Metal, and more), offering a consistent workflow experience – irrespective of the environment."
+msgstr ""
+
msgid "InProductMarketing|GitLab provides static application security testing (SAST), dynamic application security testing (DAST), container scanning, and dependency scanning to help you deliver secure applications along with license compliance."
msgstr ""
@@ -18422,21 +18792,36 @@ msgstr ""
msgid "InProductMarketing|It's also possible to simply %{external_repo_link} in order to take advantage of GitLab's CI/CD."
msgstr ""
+msgid "InProductMarketing|Keep your code quality high by defining who should approve merge requests and how many approvals are required."
+msgstr ""
+
msgid "InProductMarketing|Launch GitLab CI/CD in 20 minutes or less"
msgstr ""
+msgid "InProductMarketing|Lower cost of development"
+msgstr ""
+
+msgid "InProductMarketing|Make it easier to collaborate on high-level ideas by grouping related issues in an epic."
+msgstr ""
+
msgid "InProductMarketing|Making the switch? It's easier than you think to import your projects into GitLab. Move %{github_link}, or import something %{bitbucket_link}."
msgstr ""
msgid "InProductMarketing|Master the art of importing!"
msgstr ""
+msgid "InProductMarketing|Merge request approval rule"
+msgstr ""
+
msgid "InProductMarketing|Move on to easily creating a Pages website %{ci_template_link}"
msgstr ""
msgid "InProductMarketing|Multiple owners, confusing workstreams? We've got you covered"
msgstr ""
+msgid "InProductMarketing|Multiple required approvers"
+msgstr ""
+
msgid "InProductMarketing|Need an alternative to importing?"
msgstr ""
@@ -18449,18 +18834,33 @@ msgstr ""
msgid "InProductMarketing|Our tool brings all the things together"
msgstr ""
+msgid "InProductMarketing|Protect your web application by using DAST to examine for vulnerabilities in deployed environments."
+msgstr ""
+
msgid "InProductMarketing|Rapid development, simplified"
msgstr ""
msgid "InProductMarketing|Reduce Security & Compliance Risk"
msgstr ""
+msgid "InProductMarketing|Require multiple approvers on a merge request, so you know it's in good shape before it's merged."
+msgstr ""
+
+msgid "InProductMarketing|Roadmaps"
+msgstr ""
+
+msgid "InProductMarketing|Scoped labels"
+msgstr ""
+
msgid "InProductMarketing|Security that's integrated into your development lifecycle"
msgstr ""
msgid "InProductMarketing|Sometimes you're not ready to make a full transition to a new tool. If you're not ready to fully commit, %{mirroring_link} gives you a safe way to try out GitLab in parallel with your current tool."
msgstr ""
+msgid "InProductMarketing|Speed. Efficiency. Trust."
+msgstr ""
+
msgid "InProductMarketing|Spin up an autoscaling runner in GitLab"
msgstr ""
@@ -18470,6 +18870,9 @@ msgstr ""
msgid "InProductMarketing|Start a Self-Managed trial"
msgstr ""
+msgid "InProductMarketing|Start a free trial"
+msgstr ""
+
msgid "InProductMarketing|Start a free trial of GitLab Ultimate – no credit card required"
msgstr ""
@@ -18536,6 +18939,9 @@ msgstr ""
msgid "InProductMarketing|To understand and get the most out of GitLab, start at the beginning and %{project_link}. In GitLab, repositories are part of a project, so after you've created your project you can go ahead and %{repo_link}."
msgstr ""
+msgid "InProductMarketing|Track completed issues in a chart, so you can see how a milestone is progressing at a glance."
+msgstr ""
+
msgid "InProductMarketing|Try GitLab Ultimate for free"
msgstr ""
@@ -18572,6 +18978,9 @@ msgstr ""
msgid "InProductMarketing|Very easy"
msgstr ""
+msgid "InProductMarketing|Visualize your epics and milestones in a timeline."
+msgstr ""
+
msgid "InProductMarketing|Want to host GitLab on your servers?"
msgstr ""
@@ -18593,6 +19002,9 @@ msgstr ""
msgid "InProductMarketing|YouTube"
msgstr ""
+msgid "InProductMarketing|Your software, deployed your way"
+msgstr ""
+
msgid "InProductMarketing|Your teams can be more efficient"
msgstr ""
@@ -18713,9 +19125,18 @@ msgstr ""
msgid "IncidentManagement|No incidents to display."
msgstr ""
+msgid "IncidentManagement|None"
+msgstr ""
+
msgid "IncidentManagement|Open"
msgstr ""
+msgid "IncidentManagement|Page your team with escalation policies"
+msgstr ""
+
+msgid "IncidentManagement|Paged"
+msgstr ""
+
msgid "IncidentManagement|Published"
msgstr ""
@@ -18725,6 +19146,9 @@ msgstr ""
msgid "IncidentManagement|Severity"
msgstr ""
+msgid "IncidentManagement|Status"
+msgstr ""
+
msgid "IncidentManagement|There are no closed incidents"
msgstr ""
@@ -18743,6 +19167,9 @@ msgstr ""
msgid "IncidentManagement|Unpublished"
msgstr ""
+msgid "IncidentManagement|Use escalation policies to automatically page your team when incidents are created."
+msgstr ""
+
msgid "IncidentSettings|Activate \"time to SLA\" countdown timer"
msgstr ""
@@ -18788,7 +19215,10 @@ msgstr ""
msgid "Incidents"
msgstr ""
-msgid "Incidents|Add a URL"
+msgid "Incidents|Add image details"
+msgstr ""
+
+msgid "Incidents|Add text or a link to display with your image. If you don't add either, the file name displays instead."
msgstr ""
msgid "Incidents|Drop or %{linkStart}upload%{linkEnd} a metric screenshot to attach it to the incident"
@@ -18803,10 +19233,10 @@ msgstr ""
msgid "Incidents|There was an issue loading metric images."
msgstr ""
-msgid "Incidents|There was an issue uploading your image."
+msgid "Incidents|There was an issue updating your image."
msgstr ""
-msgid "Incidents|You can optionally add a URL to link users to the original graph."
+msgid "Incidents|There was an issue uploading your image."
msgstr ""
msgid "Incident|Alert details"
@@ -18815,9 +19245,18 @@ msgstr ""
msgid "Incident|Are you sure you wish to delete this image?"
msgstr ""
+msgid "Incident|Delete image"
+msgstr ""
+
msgid "Incident|Deleting %{filename}"
msgstr ""
+msgid "Incident|Edit image text or link"
+msgstr ""
+
+msgid "Incident|Editing %{filename}"
+msgstr ""
+
msgid "Incident|Metrics"
msgstr ""
@@ -19086,12 +19525,18 @@ msgstr ""
msgid "Integrations|Branches for which notifications are to be sent"
msgstr ""
+msgid "Integrations|Clear if using a self-signed certificate."
+msgstr ""
+
msgid "Integrations|Comment detail:"
msgstr ""
msgid "Integrations|Comment settings:"
msgstr ""
+msgid "Integrations|Connection details"
+msgstr ""
+
msgid "Integrations|Connection failed. Please check your settings."
msgstr ""
@@ -19116,6 +19561,9 @@ msgstr ""
msgid "Integrations|Enable GitLab.com slash commands in a Slack workspace."
msgstr ""
+msgid "Integrations|Enable SSL verification"
+msgstr ""
+
msgid "Integrations|Enable comments"
msgstr ""
@@ -19194,6 +19642,9 @@ msgstr ""
msgid "Integrations|Return to GitLab for Jira"
msgstr ""
+msgid "Integrations|SSL verification"
+msgstr ""
+
msgid "Integrations|Save settings?"
msgstr ""
@@ -19239,9 +19690,6 @@ msgstr ""
msgid "Integrations|Use default settings"
msgstr ""
-msgid "Integrations|When you mention a Jira issue in a commit or merge request, GitLab creates a remote link and comment (if enabled)."
-msgstr ""
-
msgid "Integrations|You can now close this window and return to the GitLab for Jira application."
msgstr ""
@@ -19266,9 +19714,6 @@ msgstr ""
msgid "Integrations|can't exceed %{recipients_limit}"
msgstr ""
-msgid "Interactive developer security education."
-msgstr ""
-
msgid "Interactive mode"
msgstr ""
@@ -19758,6 +20203,9 @@ msgstr ""
msgid "IssueAnalytics|Assignees"
msgstr ""
+msgid "IssueAnalytics|Created by"
+msgstr ""
+
msgid "IssueAnalytics|Due date"
msgstr ""
@@ -19770,9 +20218,6 @@ msgstr ""
msgid "IssueAnalytics|Milestone"
msgstr ""
-msgid "IssueAnalytics|Opened by"
-msgstr ""
-
msgid "IssueAnalytics|Status"
msgstr ""
@@ -19896,10 +20341,10 @@ msgstr ""
msgid "IssuesAnalytics|Avg/Month:"
msgstr ""
-msgid "IssuesAnalytics|Issues opened"
+msgid "IssuesAnalytics|Issues created"
msgstr ""
-msgid "IssuesAnalytics|Issues opened per month"
+msgid "IssuesAnalytics|Issues created per month"
msgstr ""
msgid "IssuesAnalytics|Last 12 months"
@@ -19926,6 +20371,9 @@ msgstr ""
msgid "It looks like you have some draft commits in this branch."
msgstr ""
+msgid "It looks like you're attempting to activate your subscription. Use %{a_start}the Subscription page%{a_end} instead."
+msgstr ""
+
msgid "It may be several days before you see feature usage data."
msgstr ""
@@ -20154,6 +20602,9 @@ msgstr ""
msgid "JiraConnect|You can now close this window and return to Jira."
msgstr ""
+msgid "JiraConnect|You don't have permission to create branches for this project. Select a different project or contact the project owner for access. %{linkStart}Learn more.%{linkEnd}"
+msgstr ""
+
msgid "JiraRequest|A connection error occurred while connecting to Jira. Try your request again."
msgstr ""
@@ -20202,13 +20653,13 @@ msgstr ""
msgid "JiraService|Define the type of Jira issue to create from a vulnerability."
msgstr ""
-msgid "JiraService|Displaying Jira issues while leaving the GitLab issue functionality enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
+msgid "JiraService|Displaying Jira issues while leaving GitLab issues also enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
msgstr ""
-msgid "JiraService|Enable Jira issues"
+msgid "JiraService|Enable Jira issue creation from vulnerabilities"
msgstr ""
-msgid "JiraService|Enable Jira issues creation from vulnerabilities"
+msgid "JiraService|Enable Jira issues"
msgstr ""
msgid "JiraService|Enable Jira transitions"
@@ -20325,16 +20776,19 @@ msgstr ""
msgid "JiraService|View Jira issues in GitLab"
msgstr ""
-msgid "JiraService|Warning: All GitLab users that have access to this GitLab project are able to view all issues from the Jira project specified below."
+msgid "JiraService|Warning: All GitLab users with access to this GitLab project can view all issues from the Jira project you select."
msgstr ""
msgid "JiraService|Web URL"
msgstr ""
-msgid "JiraService|Work on Jira issues without leaving GitLab. Adds a Jira menu to access your list of Jira issues and view any issue as read-only."
+msgid "JiraService|When a Jira issue is mentioned in a commit or merge request, a remote link and comment (if enabled) will be created."
msgstr ""
-msgid "JiraService|You need to configure Jira before enabling this integration. For more details, read the %{jira_doc_link_start}Jira integration documentation%{link_end}."
+msgid "JiraService|Work on Jira issues without leaving GitLab. Add a Jira menu to access a read-only list of your Jira issues."
+msgstr ""
+
+msgid "JiraService|You must configure Jira before enabling this integration. %{jira_doc_link_start}Learn more.%{link_end}"
msgstr ""
msgid "Job"
@@ -20346,9 +20800,6 @@ msgstr ""
msgid "Job Failed #%{build_id}"
msgstr ""
-msgid "Job ID"
-msgstr ""
-
msgid "Job artifact"
msgstr ""
@@ -20415,9 +20866,27 @@ msgstr ""
msgid "Jobs|You're about to retry a job that failed because it attempted to deploy code that is older than the latest deployment. Retrying this job could result in overwriting the environment with the older source code."
msgstr ""
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source} into %{target}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{ref}"
+msgstr ""
+
+msgid "Job|Are you sure you want to erase this job log and artifacts?"
+msgstr ""
+
msgid "Job|Browse"
msgstr ""
+msgid "Job|Cancel"
+msgstr ""
+
msgid "Job|Complete Raw"
msgstr ""
@@ -20427,6 +20896,9 @@ msgstr ""
msgid "Job|Erase job log and artifacts"
msgstr ""
+msgid "Job|Finished at"
+msgstr ""
+
msgid "Job|Job artifacts"
msgstr ""
@@ -20439,7 +20911,7 @@ msgstr ""
msgid "Job|Keep"
msgstr ""
-msgid "Job|Pipeline"
+msgid "Job|Retry"
msgstr ""
msgid "Job|Scroll to bottom"
@@ -20451,6 +20923,9 @@ msgstr ""
msgid "Job|Show complete raw"
msgstr ""
+msgid "Job|Status"
+msgstr ""
+
msgid "Job|The artifacts were removed"
msgstr ""
@@ -20478,21 +20953,12 @@ msgstr ""
msgid "Job|delayed"
msgstr ""
-msgid "Job|for"
-msgstr ""
-
-msgid "Job|into"
-msgstr ""
-
msgid "Job|manual"
msgstr ""
msgid "Job|triggered"
msgstr ""
-msgid "Job|with"
-msgstr ""
-
msgid "Join Zoom meeting"
msgstr ""
@@ -20595,9 +21061,6 @@ msgstr ""
msgid "Ki"
msgstr ""
-msgid "Kontra"
-msgstr ""
-
msgid "Kroki"
msgstr ""
@@ -20920,6 +21383,9 @@ msgstr ""
msgid "Learn more about Auto DevOps"
msgstr ""
+msgid "Learn more about GitLab"
+msgstr ""
+
msgid "Learn more about Needs relationships"
msgstr ""
@@ -21241,9 +21707,18 @@ msgstr ""
msgid "Licenses|Displays licenses detected in the project, based on the %{linkStart}latest successful%{linkEnd} scan"
msgstr ""
+msgid "Licenses|Drag your license file here or %{linkStart}click to upload%{linkEnd}."
+msgstr ""
+
+msgid "Licenses|Drop your license file to start the upload."
+msgstr ""
+
msgid "Licenses|Error fetching the license list. Please check your network connection and try again."
msgstr ""
+msgid "Licenses|Error: You are trying to upload something other than a file"
+msgstr ""
+
msgid "Licenses|License Compliance"
msgstr ""
@@ -21262,6 +21737,9 @@ msgstr ""
msgid "Licenses|Specified policies in this project"
msgstr ""
+msgid "Licenses|The file could not be uploaded."
+msgstr ""
+
msgid "Licenses|The license list details information about the licenses used within your project."
msgstr ""
@@ -21295,10 +21773,6 @@ msgstr ""
msgid "Limit the size of Sidekiq jobs stored in Redis."
msgstr ""
-msgid "Limited to showing %d event at most"
-msgid_plural "Limited to showing %d events at most"
-msgstr[0] ""
-
msgid "Limiting mode"
msgstr ""
@@ -21308,6 +21782,9 @@ msgstr ""
msgid "Link"
msgstr ""
+msgid "Link (optional)"
+msgstr ""
+
msgid "Link Prometheus monitoring to GitLab."
msgstr ""
@@ -21344,6 +21821,9 @@ msgstr ""
msgid "Linked emails (%{email_count})"
msgstr ""
+msgid "Linked epics"
+msgstr ""
+
msgid "Linked issues"
msgstr ""
@@ -21371,6 +21851,15 @@ msgstr ""
msgid "List of all merge commits"
msgstr ""
+msgid "List of environments for this project"
+msgstr ""
+
+msgid "List of suitable GCP locations"
+msgstr ""
+
+msgid "List of users allowed to exceed the rate limit."
+msgstr ""
+
msgid "List options"
msgstr ""
@@ -21590,6 +22079,9 @@ msgstr ""
msgid "Maintenance mode"
msgstr ""
+msgid "Make adjustments to how your GitLab instance is set up."
+msgstr ""
+
msgid "Make and review changes in the browser with the Web IDE"
msgstr ""
@@ -21734,6 +22226,12 @@ msgstr ""
msgid "MarkdownEditor|Add italic text (%{modifier_key}I)"
msgstr ""
+msgid "MarkdownEditor|Add strikethrough text (%{modifierKey}⇧X)"
+msgstr ""
+
+msgid "MarkdownEditor|Add strikethrough text (%{modifier_key}⇧X)"
+msgstr ""
+
msgid "Marked For Deletion At - %{deletion_time}"
msgstr ""
@@ -21995,6 +22493,9 @@ msgstr ""
msgid "Maximum push size (MB)"
msgstr ""
+msgid "Maximum requests per 10 minutes per user"
+msgstr ""
+
msgid "Maximum requests per minute"
msgstr ""
@@ -22085,6 +22586,17 @@ msgstr ""
msgid "Members of a group may only view projects they have permission to access"
msgstr ""
+msgid "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seat in use and will be billed for the overage."
+msgid_plural "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seats in use and will be billed for the overage."
+msgstr[0] ""
+
+msgid "MembersOverage|You are about to incur additional charges"
+msgstr ""
+
+msgid "MembersOverage|Your subscription includes %d seat."
+msgid_plural "MembersOverage|Your subscription includes %d seats."
+msgstr[0] ""
+
msgid "Membership"
msgstr ""
@@ -22289,9 +22801,6 @@ msgstr ""
msgid "Merge request not merged"
msgstr ""
-msgid "Merge request pipelines 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 merge request pipelines."
-msgstr ""
-
msgid "Merge request reports"
msgstr ""
@@ -22388,13 +22897,13 @@ msgstr ""
msgid "MergeRequests|Create issue to resolve thread"
msgstr ""
-msgid "MergeRequests|Failed to squash. Should be done manually."
+msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Saving the comment failed"
+msgid "MergeRequests|Squashing failed: Squash the commits locally, resolve any conflicts, then push the branch."
msgstr ""
-msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
+msgid "MergeRequests|Squashing not allowed: This project doesn't allow you to squash commits when merging."
msgstr ""
msgid "MergeRequests|Thread stays resolved"
@@ -23233,6 +23742,18 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "MrList|Assigned to %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from assignee %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from reviewer %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Review requested from %{name}, go to their profile."
+msgstr ""
+
msgid "Multi-project"
msgstr ""
@@ -23266,7 +23787,7 @@ msgstr ""
msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "My Awesome Group"
+msgid "My awesome group"
msgstr ""
msgid "My company or team"
@@ -23886,9 +24407,6 @@ msgstr ""
msgid "No available branches"
msgstr ""
-msgid "No available groups to fork the project."
-msgstr ""
-
msgid "No branches found"
msgstr ""
@@ -24099,6 +24617,9 @@ msgstr ""
msgid "No ref selected"
msgstr ""
+msgid "No regions configured"
+msgstr ""
+
msgid "No related merge requests found."
msgstr ""
@@ -24897,6 +25418,9 @@ msgstr ""
msgid "Only reCAPTCHA v2 is supported:"
msgstr ""
+msgid "Only required if not using role instance credentials."
+msgstr ""
+
msgid "Only use lowercase letters, numbers, and underscores."
msgstr ""
@@ -24921,9 +25445,6 @@ msgstr ""
msgid "Open a CLI and connect to the cluster you want to install the agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
-msgid "Open epics"
-msgstr ""
-
msgid "Open errors"
msgstr ""
@@ -24963,8 +25484,8 @@ msgstr ""
msgid "Opened issues"
msgstr ""
-msgid "OpenedNDaysAgo|Opened"
-msgstr "開始於"
+msgid "OpenedNDaysAgo|Created"
+msgstr ""
msgid "Opens in a new window"
msgstr ""
@@ -25008,9 +25529,6 @@ msgstr ""
msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
-msgid "Optional."
-msgstr ""
-
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
msgstr ""
@@ -25798,6 +26316,9 @@ msgstr ""
msgid "PerformanceBar|Memory"
msgstr ""
+msgid "PerformanceBar|Memory report"
+msgstr ""
+
msgid "PerformanceBar|Redis calls"
msgstr ""
@@ -25831,18 +26352,12 @@ msgstr ""
msgid "PerformanceBar|wall"
msgstr ""
-msgid "Performs a rebase but skips triggering a new pipeline"
-msgstr ""
-
msgid "Period in seconds"
msgstr ""
msgid "Permalink"
msgstr ""
-msgid "Permanently delete project"
-msgstr ""
-
msgid "Permanently remove group"
msgstr ""
@@ -26113,6 +26628,51 @@ msgstr ""
msgid "PipelineStatusTooltip|Pipeline: %{ci_status}"
msgstr ""
+msgid "PipelineWizardDefaultCommitMessage|Add %{filename}"
+msgstr ""
+
+msgid "PipelineWizardDefaultCommitMessage|Update %{filename}"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|At least one entry is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This field is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This value is not valid"
+msgstr ""
+
+msgid "PipelineWizardListWidget|add another step"
+msgstr ""
+
+msgid "PipelineWizardListWidget|remove step"
+msgstr ""
+
+msgid "PipelineWizard|Commit"
+msgstr ""
+
+msgid "PipelineWizard|Commit Message"
+msgstr ""
+
+msgid "PipelineWizard|Commit changes to your file"
+msgstr ""
+
+msgid "PipelineWizard|Commit file to Branch"
+msgstr ""
+
+msgid "PipelineWizard|Commit your new file"
+msgstr ""
+
+msgid "PipelineWizard|The file has been committed."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem committing the changes."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem while checking whether your file already exists in the specified branch."
+msgstr ""
+
msgid "Pipelines"
msgstr "æµæ°´ç·š"
@@ -26227,7 +26787,7 @@ msgstr ""
msgid "Pipelines|Project cache successfully reset."
msgstr ""
-msgid "Pipelines|Revoke"
+msgid "Pipelines|Revoke trigger"
msgstr ""
msgid "Pipelines|Something went wrong while cleaning runners cache."
@@ -26272,6 +26832,12 @@ msgstr ""
msgid "Pipelines|This is a child pipeline within the parent pipeline"
msgstr ""
+msgid "Pipelines|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipelines|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipelines|This pipeline will run code originating from a forked project merge request. This means that the code can potentially have security considerations like exposing CI variables."
msgstr ""
@@ -26314,9 +26880,6 @@ msgstr ""
msgid "Pipelines|Your changes have been successfully committed. Now redirecting to the new merge request page."
msgstr ""
-msgid "Pipelines|detached"
-msgstr ""
-
msgid "Pipelines|error"
msgstr ""
@@ -26326,10 +26889,13 @@ msgstr ""
msgid "Pipelines|latest"
msgstr ""
-msgid "Pipelines|stuck"
+msgid "Pipelines|merge request"
msgstr ""
-msgid "Pipelines|train"
+msgid "Pipelines|merge train"
+msgstr ""
+
+msgid "Pipelines|stuck"
msgstr ""
msgid "Pipelines|yaml invalid"
@@ -26461,6 +27027,12 @@ msgstr ""
msgid "Pipeline|This change will not change the overall test coverage if merged."
msgstr ""
+msgid "Pipeline|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipeline|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipeline|Trigger author"
msgstr ""
@@ -26485,6 +27057,12 @@ msgstr ""
msgid "Pipeline|for"
msgstr ""
+msgid "Pipeline|merge request"
+msgstr ""
+
+msgid "Pipeline|merge train"
+msgstr ""
+
msgid "Pipeline|on"
msgstr ""
@@ -26623,9 +27201,6 @@ msgstr ""
msgid "Please enter a valid time interval"
msgstr ""
-msgid "Please enter or upload a valid license."
-msgstr ""
-
msgid "Please enter your current password."
msgstr ""
@@ -26734,9 +27309,6 @@ msgstr ""
msgid "Please type %{phrase_code} to proceed or close this modal to cancel."
msgstr ""
-msgid "Please type the following to confirm:"
-msgstr ""
-
msgid "Please use this form to report to the admin users who create spam issues, comments or behave inappropriately."
msgstr ""
@@ -26764,12 +27336,27 @@ msgstr ""
msgid "Policies"
msgstr ""
+msgid "Policy '%{escalation_policy_name}' does not exist."
+msgstr ""
+
msgid "Policy management project does have any policies in %{policy_path}"
msgstr ""
msgid "Policy project doesn't exist"
msgstr ""
+msgid "PolicyRuleMultiSelect|%{firstLabel} +%{numberOfAdditionalLabels} more"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|All %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select all"
+msgstr ""
+
msgid "Polling interval multiplier"
msgstr ""
@@ -26998,6 +27585,9 @@ msgstr ""
msgid "Private projects can be created in your personal namespace with:"
msgstr ""
+msgid "Problem with %{name} command: %{message}."
+msgstr ""
+
msgid "Proceed"
msgstr ""
@@ -27472,6 +28062,9 @@ msgstr ""
msgid "Progress"
msgstr ""
+msgid "Progress tracking"
+msgstr ""
+
msgid "Project"
msgstr ""
@@ -27703,6 +28296,9 @@ msgstr ""
msgid "ProjectQualitySummary|Failure"
msgstr ""
+msgid "ProjectQualitySummary|Get insight into the overall percentage of tests in your project that succeed, fail and are skipped."
+msgstr ""
+
msgid "ProjectQualitySummary|Latest pipeline results"
msgstr ""
@@ -27721,6 +28317,12 @@ msgstr ""
msgid "ProjectQualitySummary|See project Code Coverage Statistics"
msgstr ""
+msgid "ProjectQualitySummary|Set up test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|Set up test runs (opens in a new tab)"
+msgstr ""
+
msgid "ProjectQualitySummary|Skipped"
msgstr ""
@@ -27997,13 +28599,19 @@ msgstr ""
msgid "ProjectSettings|LFS objects from this repository are available to forks. %{linkStart}How do I remove them?%{linkEnd}"
msgstr ""
+msgid "ProjectSettings|Learn about commit history."
+msgstr ""
+
+msgid "ProjectSettings|Leave empty to use default template."
+msgstr ""
+
msgid "ProjectSettings|Manage who can see the project in the public access directory."
msgstr ""
msgid "ProjectSettings|Manages large files such as audio, video, and graphics files."
msgstr ""
-msgid "ProjectSettings|Maximum 500 characters."
+msgid "ProjectSettings|Maximum %{maxLength} characters."
msgstr ""
msgid "ProjectSettings|Merge checks"
@@ -28144,6 +28752,9 @@ msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
msgstr ""
+msgid "ProjectSettings|The default template will be applied on save."
+msgstr ""
+
msgid "ProjectSettings|These checks must pass before merge requests can be merged."
msgstr ""
@@ -28198,6 +28809,9 @@ msgstr ""
msgid "ProjectSettings|What are badges?"
msgstr ""
+msgid "ProjectSettings|What are merge trains?"
+msgstr ""
+
msgid "ProjectSettings|When merge request pipelines are enabled in the CI/CD configuration file, pipelines validate the combined results of the source and target branches. %{link_start}How to configure merge request pipelines?%{link_end}"
msgstr ""
@@ -28315,6 +28929,9 @@ msgstr ""
msgid "Projects are organized into groups"
msgstr ""
+msgid "Projects are where you store your code, access issues, wiki and other features of GitLab."
+msgstr ""
+
msgid "Projects contributed to"
msgstr ""
@@ -28330,12 +28947,6 @@ msgstr ""
msgid "Projects to index"
msgstr ""
-msgid "Projects will be permanently deleted after a %{waiting_period}-day waiting period."
-msgstr ""
-
-msgid "Projects will be permanently deleted immediately."
-msgstr ""
-
msgid "Projects with critical vulnerabilities"
msgstr ""
@@ -28420,6 +29031,9 @@ msgstr ""
msgid "ProjectsNew|Import project"
msgstr ""
+msgid "ProjectsNew|Include a Getting Started README"
+msgstr ""
+
msgid "ProjectsNew|Initialize repository with a README"
msgstr ""
@@ -28435,6 +29049,9 @@ msgstr ""
msgid "ProjectsNew|Project description %{tag_start}(optional)%{tag_end}"
msgstr ""
+msgid "ProjectsNew|Recommended if you're new to GitLab"
+msgstr ""
+
msgid "ProjectsNew|Run CI/CD for external repository"
msgstr ""
@@ -28852,6 +29469,9 @@ msgstr ""
msgid "ProtectedBranch|Unprotect"
msgstr ""
+msgid "ProtectedBranch|Unprotect branch"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
@@ -28879,6 +29499,9 @@ msgstr ""
msgid "ProtectedEnvironment|Protected Environment (%{protected_environments_count})"
msgstr ""
+msgid "ProtectedEnvironment|Required approvals"
+msgstr ""
+
msgid "ProtectedEnvironment|Select an environment"
msgstr ""
@@ -28900,10 +29523,13 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|Unprotect tag"
+msgstr ""
+
msgid "ProtectedTags|default"
msgstr ""
-msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
+msgid "ProtectedTag|By default, protected tags restrict who can modify the tag."
msgstr ""
msgid "ProtectedTag|Learn more."
@@ -28966,6 +29592,9 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Public projects are an easy way to allow everyone to have read-only access."
+msgstr ""
+
msgid "Publish to status page"
msgstr ""
@@ -29122,9 +29751,6 @@ msgstr ""
msgid "QualitySummary|Project quality"
msgstr ""
-msgid "Quarters"
-msgstr "季度"
-
msgid "Query"
msgstr ""
@@ -29209,6 +29835,9 @@ msgstr ""
msgid "Read more about project permissions %{help_link_open}here%{help_link_close}"
msgstr ""
+msgid "Read more about related epics"
+msgstr ""
+
msgid "Read more about related issues"
msgstr ""
@@ -29239,10 +29868,7 @@ msgstr ""
msgid "Rebase source branch on the target branch."
msgstr ""
-msgid "Rebase without CI"
-msgstr ""
-
-msgid "Rebases and triggers a pipeline"
+msgid "Rebase without pipeline"
msgstr ""
msgid "Recaptcha verified?"
@@ -29293,9 +29919,6 @@ msgstr ""
msgid "Reconfigure"
msgstr ""
-msgid "Recovering projects"
-msgstr ""
-
msgid "Recovery Codes"
msgstr ""
@@ -29354,6 +29977,12 @@ msgstr ""
msgid "Regex pattern"
msgstr ""
+msgid "Region"
+msgstr ""
+
+msgid "Regions"
+msgstr ""
+
msgid "Register"
msgstr ""
@@ -29583,9 +30212,6 @@ msgstr ""
msgid "Remove all or specific reviewer(s)"
msgstr ""
-msgid "Remove approver"
-msgstr ""
-
msgid "Remove approvers"
msgstr ""
@@ -29601,6 +30227,9 @@ msgstr "移除指派人"
msgid "Remove attention request"
msgstr ""
+msgid "Remove attention request(s)"
+msgstr ""
+
msgid "Remove avatar"
msgstr ""
@@ -29739,6 +30368,9 @@ msgstr ""
msgid "Removed an issue from an epic."
msgstr ""
+msgid "Removed attention from %{users_sentence}."
+msgstr ""
+
msgid "Removed attention request from @%{username}"
msgstr ""
@@ -29790,6 +30422,9 @@ msgstr ""
msgid "Removes an issue from an epic."
msgstr ""
+msgid "Removes attention from %{users_sentence}."
+msgstr ""
+
msgid "Removes parent epic %{epic_ref}."
msgstr ""
@@ -29901,6 +30536,9 @@ msgstr ""
msgid "Report abuse to admin"
msgstr ""
+msgid "Report is generating and will be sent to your email address."
+msgstr ""
+
msgid "Reported %{timeAgo} by %{reportedBy}"
msgstr ""
@@ -30185,6 +30823,15 @@ msgstr ""
msgid "Request attention"
msgstr ""
+msgid "Request attention from %{users_sentence}."
+msgstr ""
+
+msgid "Request attention from assignee or reviewer"
+msgstr ""
+
+msgid "Request attention from assignee(s) or reviewer(s)"
+msgstr ""
+
msgid "Request attention to review"
msgstr ""
@@ -30209,6 +30856,9 @@ msgstr ""
msgid "Requested %{time_ago}"
msgstr ""
+msgid "Requested attention from %{users_sentence}."
+msgstr ""
+
msgid "Requested attention from @%{username}"
msgstr ""
@@ -30421,6 +31071,9 @@ msgstr ""
msgid "Restore project"
msgstr ""
+msgid "Restoring projects"
+msgstr ""
+
msgid "Restoring the group will prevent the group, its subgroups and projects from being removed on this date."
msgstr ""
@@ -30451,6 +31104,9 @@ msgstr ""
msgid "Retry"
msgstr ""
+msgid "Retry failed jobs"
+msgstr ""
+
msgid "Retry job"
msgstr ""
@@ -30497,9 +31153,6 @@ msgstr ""
msgid "Review changes"
msgstr ""
-msgid "Review requested from %{name}"
-msgstr ""
-
msgid "Review requests for you"
msgstr ""
@@ -30663,6 +31316,9 @@ msgstr ""
msgid "Runners|Assigned Group"
msgstr ""
+msgid "Runners|Assigned Projects (%{projectCount})"
+msgstr ""
+
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30732,6 +31388,9 @@ msgstr ""
msgid "Runners|Instance"
msgstr ""
+msgid "Runners|Jobs"
+msgstr ""
+
msgid "Runners|Last contact"
msgstr ""
@@ -30825,9 +31484,6 @@ msgstr ""
msgid "Runners|Runner %{name} was deleted"
msgstr ""
-msgid "Runners|Runner ID"
-msgstr ""
-
msgid "Runners|Runner assigned to project."
msgstr ""
@@ -30975,6 +31631,9 @@ msgstr ""
msgid "Runners|stale"
msgstr ""
+msgid "Runner|This runner has not run any jobs."
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -31089,6 +31748,24 @@ msgstr ""
msgid "Saving project."
msgstr ""
+msgid "ScanResultPolicy|%{ifLabelStart}if%{ifLabelEnd} %{scanners} scan in an open merge request targeting the %{branches} branch(es) finds %{vulnerabilitiesAllowed} or more %{severities} vulnerabilities that are %{vulnerabilityStates}"
+msgstr ""
+
+msgid "ScanResultPolicy|%{thenLabelStart}Then%{thenLabelEnd} Require approval from %{approvalsRequired} of the following approvers: %{approvers}"
+msgstr ""
+
+msgid "ScanResultPolicy|add an approver"
+msgstr ""
+
+msgid "ScanResultPolicy|scanners"
+msgstr ""
+
+msgid "ScanResultPolicy|severity levels"
+msgstr ""
+
+msgid "ScanResultPolicy|vulnerability states"
+msgstr ""
+
msgid "Scanner"
msgstr ""
@@ -31221,6 +31898,9 @@ msgstr ""
msgid "Search for a user"
msgstr ""
+msgid "Search for an emoji"
+msgstr ""
+
msgid "Search for projects, issues, etc."
msgstr ""
@@ -31397,18 +32077,12 @@ msgstr ""
msgid "Secret Detection"
msgstr ""
-msgid "Secret access key"
-msgstr ""
-
msgid "Secret token"
msgstr ""
msgid "Secure token that identifies an external storage request."
msgstr ""
-msgid "SecureCodeWarrior"
-msgstr ""
-
msgid "Security"
msgstr ""
@@ -31433,9 +32107,6 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "Security training with guide and learning pathways."
-msgstr ""
-
msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
@@ -31538,7 +32209,7 @@ msgstr ""
msgid "SecurityConfiguration|Manage corpus"
msgstr ""
-msgid "SecurityConfiguration|Manage corpus files used as mutation sources in coverage fuzzing."
+msgid "SecurityConfiguration|Manage corpus files used as seed inputs with coverage-guided fuzzing."
msgstr ""
msgid "SecurityConfiguration|Manage profiles for use by DAST scans."
@@ -31604,15 +32275,15 @@ msgstr ""
msgid "SecurityOrchestration|.yaml preview"
msgstr ""
-msgid "SecurityOrchestration|Action"
-msgstr ""
-
msgid "SecurityOrchestration|Actions"
msgstr ""
msgid "SecurityOrchestration|Add rule"
msgstr ""
+msgid "SecurityOrchestration|After dismissing the alert, the information will never be shown again."
+msgstr ""
+
msgid "SecurityOrchestration|All policies"
msgstr ""
@@ -31628,7 +32299,7 @@ msgstr ""
msgid "SecurityOrchestration|Description"
msgstr ""
-msgid "SecurityOrchestration|Disabled"
+msgid "SecurityOrchestration|Don't show the alert anymore"
msgstr ""
msgid "SecurityOrchestration|Edit policy"
@@ -31637,13 +32308,13 @@ msgstr ""
msgid "SecurityOrchestration|Edit policy project"
msgstr ""
-msgid "SecurityOrchestration|Enabled"
+msgid "SecurityOrchestration|Empty policy name"
msgstr ""
-msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Enabled"
msgstr ""
-msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
msgstr ""
msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
@@ -31652,7 +32323,7 @@ msgstr ""
msgid "SecurityOrchestration|Invalid policy type"
msgstr ""
-msgid "SecurityOrchestration|Latest scan"
+msgid "SecurityOrchestration|Latest scan run against %{agent}"
msgstr ""
msgid "SecurityOrchestration|Network"
@@ -31661,15 +32332,27 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No actions defined - policy will not run."
+msgstr ""
+
+msgid "SecurityOrchestration|No description"
+msgstr ""
+
msgid "SecurityOrchestration|No rules defined - policy will not run."
msgstr ""
+msgid "SecurityOrchestration|Not enabled"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
msgid "SecurityOrchestration|Policies"
msgstr ""
+msgid "SecurityOrchestration|Policy Type"
+msgstr ""
+
msgid "SecurityOrchestration|Policy cannot be enabled for non-existing branches (%{branches})"
msgstr ""
@@ -31694,10 +32377,13 @@ msgstr ""
msgid "SecurityOrchestration|Require %{approvals} %{plural} from %{approvers} if any of the following occur:"
msgstr ""
-msgid "SecurityOrchestration|Rule"
+msgid "SecurityOrchestration|Rules"
msgstr ""
-msgid "SecurityOrchestration|Rules"
+msgid "SecurityOrchestration|Runs %{actions} and %{lastAction} scans"
+msgstr ""
+
+msgid "SecurityOrchestration|Runs a %{action} scan"
msgstr ""
msgid "SecurityOrchestration|Scan Execution"
@@ -31757,6 +32443,9 @@ msgstr ""
msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
+msgid "SecurityOrchestration|This view only shows scan results for the agent %{agent}. You can view scan results for all agents in the %{linkStart}Operational Vulnerabilities tab of the vulnerability report%{linkEnd}."
+msgstr ""
+
msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
@@ -31811,9 +32500,6 @@ msgstr ""
msgid "SecurityOrchestration|users with ids"
msgstr ""
-msgid "SecurityOrchestration|view results"
-msgstr ""
-
msgid "SecurityOrchestration|vulnerabilities"
msgstr ""
@@ -32483,22 +33169,19 @@ 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|In order to start using functions as a service, you must first install Knative on your Kubernetes cluster. %{linkStart}More information%{linkEnd}"
-msgstr ""
-
msgid "Serverless|Learn more about Serverless"
msgstr ""
msgid "Serverless|No functions available"
msgstr ""
-msgid "Serverless|Sign up for First Look"
+msgid "Serverless|Serverless was %{linkStart}deprecated%{linkEnd} in GitLab 14.3."
+msgstr ""
+
+msgid "Serverless|Serverless was %{postLinkStart}deprecated%{postLinkEnd}. But if you opt to use it, you must install Knative in your Kubernetes cluster first. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "Serverless|The deploy job has not finished."
@@ -32510,9 +33193,6 @@ 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 ""
@@ -32528,9 +33208,6 @@ msgstr ""
msgid "Service Account Key"
msgstr ""
-msgid "Service Accounts"
-msgstr ""
-
msgid "Service Accounts keys authorize GitLab to deploy your Google Cloud project"
msgstr ""
@@ -32540,10 +33217,10 @@ msgstr ""
msgid "Service Desk allows people to create issues in your GitLab instance without their own user account. It provides a unique email address for end users to create issues in a project. Replies can be sent either through the GitLab interface or by email. End users only see threads through email."
msgstr ""
-msgid "Service Usage Data"
+msgid "Service account generated successfully"
msgstr ""
-msgid "Service account generated successfully"
+msgid "Service accounts"
msgstr ""
msgid "Service ping is disabled in your configuration file, and cannot be enabled through this form."
@@ -32687,6 +33364,9 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
+msgid "Set the per-user rate limit for getting a user by ID via the API."
+msgstr ""
+
msgid "Set the per-user rate limit for notes created by web or API requests."
msgstr ""
@@ -32865,6 +33545,9 @@ msgstr ""
msgid "Shared runners details"
msgstr ""
+msgid "Shared runners enabled cannot be enabled until a valid credit card is on file"
+msgstr ""
+
msgid "Shared runners help link"
msgstr ""
@@ -32922,6 +33605,9 @@ msgstr ""
msgid "Show all issues."
msgstr ""
+msgid "Show all milestones"
+msgstr ""
+
msgid "Show all test cases."
msgstr ""
@@ -32958,6 +33644,9 @@ msgstr ""
msgid "Show file contents"
msgstr ""
+msgid "Show group milestones"
+msgstr ""
+
msgid "Show labels"
msgstr ""
@@ -32973,6 +33662,12 @@ msgstr ""
msgid "Show open epics"
msgstr ""
+msgid "Show project milestones"
+msgstr ""
+
+msgid "Show sub-group milestones"
+msgstr ""
+
msgid "Show the Closed list"
msgstr ""
@@ -32982,10 +33677,6 @@ msgstr ""
msgid "Show whitespace changes"
msgstr ""
-msgid "Showing %d event"
-msgid_plural "Showing %d events"
-msgstr[0] "顯示 %d 個事件"
-
msgid "Showing %{conflict} between %{sourceBranch} and %{targetBranch}"
msgstr ""
@@ -33044,12 +33735,6 @@ msgstr ""
msgid "Sidebar|None"
msgstr "ç„¡"
-msgid "Sidebar|Only numeral characters allowed"
-msgstr ""
-
-msgid "Sidebar|Weight"
-msgstr "權é‡"
-
msgid "Sidekiq job compression threshold (bytes)"
msgstr ""
@@ -33212,6 +33897,9 @@ msgstr ""
msgid "Slack logo"
msgstr ""
+msgid "SlackIntegration|Are you sure you want to remove this project from the Slack application?"
+msgstr ""
+
msgid "SlackIntegration|GitLab for Slack"
msgstr ""
@@ -33221,6 +33909,9 @@ msgstr ""
msgid "SlackIntegration|Project alias"
msgstr ""
+msgid "SlackIntegration|Remove project"
+msgstr ""
+
msgid "SlackIntegration|Select a GitLab project to link with your Slack workspace."
msgstr ""
@@ -33365,9 +34056,6 @@ msgstr ""
msgid "Something went wrong trying to load issue contacts."
msgstr ""
-msgid "Something went wrong when creating a work item. Please try again"
-msgstr ""
-
msgid "Something went wrong when reordering designs. Please try again"
msgstr ""
@@ -33461,9 +34149,6 @@ msgstr ""
msgid "Something went wrong while inserting your image. Please try again."
msgstr ""
-msgid "Something went wrong while merging this merge request. Please try again."
-msgstr ""
-
msgid "Something went wrong while obtaining the Let's Encrypt certificate."
msgstr ""
@@ -33785,10 +34470,10 @@ 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."
+msgid "SourcegraphAdmin|Learn more."
msgstr ""
-msgid "SourcegraphAdmin|More information"
+msgid "SourcegraphAdmin|Only public projects have code intelligence enabled and communicate with Sourcegraph."
msgstr ""
msgid "SourcegraphAdmin|Save changes"
@@ -33797,7 +34482,7 @@ msgstr ""
msgid "SourcegraphAdmin|Sourcegraph URL"
msgstr ""
-msgid "SourcegraphAdmin|e.g. https://sourcegraph.example.com"
+msgid "SourcegraphAdmin|https://sourcegraph.example.com"
msgstr ""
msgid "SourcegraphPreferences|This feature is experimental and currently limited to certain projects."
@@ -33932,6 +34617,9 @@ msgstr ""
msgid "Start date"
msgstr ""
+msgid "Start free trial"
+msgstr ""
+
msgid "Start merge train"
msgstr ""
@@ -33962,6 +34650,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started escalation for this incident."
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -33974,6 +34665,9 @@ msgstr ""
msgid "Starts at (UTC)"
msgstr ""
+msgid "Starts escalations for this incident"
+msgstr ""
+
msgid "Starts on"
msgstr ""
@@ -34235,6 +34929,9 @@ msgstr ""
msgid "Strikethrough"
msgstr ""
+msgid "Strikethrough text"
+msgstr ""
+
msgid "Subgroup information"
msgstr ""
@@ -34469,6 +35166,21 @@ msgstr ""
msgid "Subscriptions"
msgstr ""
+msgid "Subscriptions|Chat with sales"
+msgstr ""
+
+msgid "Subscriptions|Close"
+msgstr ""
+
+msgid "Subscriptions|Not ready to buy yet?"
+msgstr ""
+
+msgid "Subscriptions|Start a free trial"
+msgstr ""
+
+msgid "Subscriptions|We understand. Maybe you have some questions for our sales team, or maybe you'd like to try some of the paid features first. What would you like to do?"
+msgstr ""
+
msgid "Subscription|Your subscription for %{strong}%{namespace_name}%{strong_close} has expired and you are now on %{pricing_link_start}the GitLab Free tier%{pricing_link_end}. Don't worry, your data is safe. Get in touch with our support team (%{support_email}). They'll gladly help with your subscription renewal."
msgstr ""
@@ -34679,6 +35391,9 @@ msgstr ""
msgid "SuperSonics|Maximum users"
msgstr ""
+msgid "SuperSonics|Offline cloud"
+msgstr ""
+
msgid "SuperSonics|Paste your activation code"
msgstr ""
@@ -34745,6 +35460,12 @@ msgstr ""
msgid "SuperSonics|You do not have an active subscription"
msgstr ""
+msgid "SuperSonics|You have a future dated license"
+msgstr ""
+
+msgid "SuperSonics|You have added a license that activates on %{date}. Please see the subscription history table below for more details."
+msgstr ""
+
msgid "SuperSonics|You have successfully added a license that activates on %{date}. Please see the subscription history table below for more details."
msgstr ""
@@ -34904,6 +35625,9 @@ msgstr ""
msgid "Tag name is required"
msgstr ""
+msgid "Tag push"
+msgstr ""
+
msgid "Tag push events"
msgstr ""
@@ -35006,6 +35730,9 @@ msgstr ""
msgid "TagsPage|protected"
msgstr ""
+msgid "Take a look at the documentation to discover all of GitLab’s capabilities."
+msgstr ""
+
msgid "Target Branch"
msgstr "目標分支"
@@ -35402,6 +36129,9 @@ msgstr ""
msgid "Tests"
msgstr ""
+msgid "Text (optional)"
+msgstr ""
+
msgid "Text added to the body of all email messages. %{character_limit} character limit"
msgstr ""
@@ -35451,6 +36181,9 @@ msgstr ""
msgid "The CSV export will be created in the background. Once finished, it will be sent to %{email} in an attachment."
msgstr ""
+msgid "The CSV export you requested of all user memberships is attached to this email."
+msgstr ""
+
msgid "The GitLab subscription service (customers.gitlab.com) is currently experiencing an outage. You can monitor the status and get updates at %{linkStart}status.gitlab.com%{linkEnd}."
msgstr ""
@@ -35526,6 +36259,9 @@ 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 epic"
+msgstr ""
+
msgid "The current issue"
msgstr ""
@@ -35686,6 +36422,9 @@ msgstr ""
msgid "The latest pipeline for this merge request has failed."
msgstr ""
+msgid "The license key is invalid."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -35701,6 +36440,9 @@ msgstr ""
msgid "The license was successfully uploaded and will be active from %{starts_at}. You can see the details below."
msgstr ""
+msgid "The license you uploaded is invalid. If the issue persists, contact support at %{link}."
+msgstr ""
+
msgid "The list creation wizard is already open"
msgstr ""
@@ -36322,10 +37064,13 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} and everything this project contains. %{strongOpen}There is no going back%{strongClose}"
+msgstr ""
+
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains."
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}on %{date}%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains. %{strongOpen}There is no going back.%{strongClose}"
msgstr ""
msgid "This action will %{strongOpen}permanently remove%{strongClose} %{codeOpen}%{group}%{codeClose} %{strongOpen}immediately%{strongClose}."
@@ -36454,9 +37199,6 @@ msgstr ""
msgid "This file was modified for readability, and can't accept suggestions. Edit it directly."
msgstr ""
-msgid "This forked project has the following:"
-msgstr ""
-
msgid "This form is disabled in preview"
msgstr ""
@@ -36469,7 +37211,7 @@ msgstr ""
msgid "This group can't be removed because it is linked to a subscription. To remove this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
-msgid "This group can't be transfered because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
+msgid "This group can't be transferred because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
msgid "This group cannot be invited to a project inside a group with enforced SSO"
@@ -36496,6 +37238,9 @@ 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 incident is already escalated with '%{escalation_policy_name}'."
+msgstr ""
+
msgid "This invitation was sent to %{mail_to_invite_email}, but you are signed in as %{link_to_current_user} with email %{mail_to_current_user}."
msgstr ""
@@ -36514,9 +37259,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 merge train pipeline"
-msgstr ""
-
msgid "This is a private email address %{helpIcon} generated just for you. Anyone who has it can create issues or merge requests as if they were you. If that happens, %{resetLinkStart}reset this token%{resetLinkEnd}."
msgstr ""
@@ -36538,6 +37280,12 @@ msgstr ""
msgid "This is your current session"
msgstr ""
+msgid "This issue cannot be assigned to a confidential epic because it is public."
+msgstr ""
+
+msgid "This issue cannot be made public because it belongs to a confidential epic."
+msgstr ""
+
msgid "This issue is confidential and should only be visible to team members with at least Reporter access."
msgstr ""
@@ -36655,6 +37403,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 branch is protected from force push."
+msgstr ""
+
msgid "This merge request cannot be rebased while there are conflicts."
msgstr ""
@@ -36706,9 +37457,15 @@ msgstr ""
msgid "This pipeline was triggered by a schedule."
msgstr ""
+msgid "This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project"
msgstr "這個專案"
+msgid "This project can be restored until %{date}."
+msgstr ""
+
msgid "This project cannot be %{visibilityLevel} because the visibility of %{openShowLink}%{name}%{closeShowLink} is %{visibility}. To make this project %{visibilityLevel}, you must first %{openEditLink}change the visibility%{closeEditLink} of the parent group."
msgstr ""
@@ -36727,6 +37484,9 @@ msgstr ""
msgid "This project is %{strongStart}NOT%{strongEnd} a fork, and has the following:"
msgstr ""
+msgid "This project is %{strongStart}NOT%{strongEnd} a fork. This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -37416,6 +38176,9 @@ msgstr ""
msgid "Today"
msgstr "今天"
+msgid "Todos count"
+msgstr ""
+
msgid "Todos|Are you looking for things to do? Take a look at %{strongStart}%{openIssuesLinkStart}open issues%{openIssuesLinkEnd}%{strongEnd}, contribute to %{strongStart}%{mergeRequestLinkStart}a merge request%{mergeRequestLinkEnd}%{mergeRequestLinkEnd}%{strongEnd}, or mention someone in a comment to automatically assign them a new to-do item."
msgstr ""
@@ -37689,9 +38452,8 @@ msgstr "樹狀顯示"
msgid "Trending"
msgstr ""
-msgid "Trials|%{planName} Trial %{enDash} %{num} day left"
-msgid_plural "Trials|%{planName} Trial %{enDash} %{num} days left"
-msgstr[0] ""
+msgid "Trials|%{planName} Trial"
+msgstr ""
msgid "Trials|Compare all plans"
msgstr ""
@@ -37699,6 +38461,9 @@ msgstr ""
msgid "Trials|Create a new group to start your GitLab Ultimate trial."
msgstr ""
+msgid "Trials|Day %{daysUsed}/%{duration}"
+msgstr ""
+
msgid "Trials|Go back to GitLab"
msgstr ""
@@ -37948,7 +38713,7 @@ msgstr ""
msgid "URL is triggered when repository is updated"
msgstr ""
-msgid "URL must be percent-encoded if neccessary."
+msgid "URL must be percent-encoded if necessary."
msgstr ""
msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
@@ -38167,6 +38932,9 @@ msgstr ""
msgid "Unlock account"
msgstr ""
+msgid "Unlock more features with GitLab Ultimate"
+msgstr ""
+
msgid "Unlock the discussion"
msgstr ""
@@ -38230,6 +38998,9 @@ msgstr ""
msgid "Unsubscribes from this %{quick_action_target}."
msgstr ""
+msgid "Unsupported sort value."
+msgstr ""
+
msgid "Unsupported todo type passed. Supported todo types are: %{todo_types}"
msgstr ""
@@ -38458,6 +39229,9 @@ msgstr ""
msgid "UsageQuota|File attachments and smaller design graphics."
msgstr ""
+msgid "UsageQuota|From %{storage_enforcement_date} storage limits will apply to this namespace. View and manage your usage in %{strong_start}Group Settings &gt; Usage quotas%{strong_end}."
+msgstr ""
+
msgid "UsageQuota|Git repository."
msgstr ""
@@ -38518,6 +39292,9 @@ msgstr ""
msgid "UsageQuota|Storage type"
msgstr ""
+msgid "UsageQuota|Storage used"
+msgstr ""
+
msgid "UsageQuota|This is the total amount of storage used across your projects within this namespace."
msgstr ""
@@ -38713,6 +39490,12 @@ msgstr ""
msgid "Use hashed storage paths for newly created and renamed repositories. Always enabled since 13.0."
msgstr ""
+msgid "Use issue count"
+msgstr ""
+
+msgid "Use issue weight"
+msgstr ""
+
msgid "Use one line per URI"
msgstr ""
@@ -39094,6 +39877,9 @@ msgstr ""
msgid "Users"
msgstr ""
+msgid "Users API rate limit"
+msgstr ""
+
msgid "Users can launch a development environment from a GitLab browser tab when the %{linkStart}Gitpod%{linkEnd} integration is enabled."
msgstr ""
@@ -39417,6 +40203,9 @@ msgstr ""
msgid "View group labels"
msgstr "查看群組標籤"
+msgid "View group pipeline usage quota"
+msgstr ""
+
msgid "View incident details at"
msgstr ""
@@ -39568,6 +40357,9 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
+msgid "Vulnerability"
+msgstr ""
+
msgid "Vulnerability Report"
msgstr ""
@@ -39619,6 +40411,9 @@ msgstr ""
msgid "VulnerabilityManagement|An unverified non-confirmed finding"
msgstr ""
+msgid "VulnerabilityManagement|At least one identifier is required"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -39628,12 +40423,24 @@ msgstr ""
msgid "VulnerabilityManagement|Create Jira issue"
msgstr ""
+msgid "VulnerabilityManagement|Enter a name"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE code"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE identifier URL"
+msgstr ""
+
msgid "VulnerabilityManagement|Fetching linked Jira issues"
msgstr ""
msgid "VulnerabilityManagement|Manually add a vulnerability entry into the vulnerability report."
msgstr ""
+msgid "VulnerabilityManagement|Name is a required field"
+msgstr ""
+
msgid "VulnerabilityManagement|Needs triage"
msgstr ""
@@ -39649,6 +40456,18 @@ msgstr ""
msgid "VulnerabilityManagement|Select a method"
msgstr ""
+msgid "VulnerabilityManagement|Select a severity level"
+msgstr ""
+
+msgid "VulnerabilityManagement|Select a status"
+msgstr ""
+
+msgid "VulnerabilityManagement|Severity is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Something went wrong while creating vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -39673,6 +40492,12 @@ msgstr ""
msgid "VulnerabilityManagement|Something went wrong, could not update vulnerability state."
msgstr ""
+msgid "VulnerabilityManagement|Status is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Submit vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Summary, detailed description, steps to reproduce, etc."
msgstr ""
@@ -39868,6 +40693,9 @@ msgstr ""
msgid "WARNING:"
msgstr ""
+msgid "WARNING: This snippet contains hidden files which might be used to mask malicious behavior. Exercise caution if cloning and executing code from this snippet."
+msgstr ""
+
msgid "Wait for the file to load to copy its contents"
msgstr ""
@@ -40087,6 +40915,15 @@ msgstr ""
msgid "Webhooks|An issue is created, updated, closed, or reopened."
msgstr ""
+msgid "Webhooks|Are you sure you want to delete this group hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this project hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this webhook?"
+msgstr ""
+
msgid "Webhooks|Comments"
msgstr ""
@@ -40096,6 +40933,9 @@ msgstr ""
msgid "Webhooks|Confidential issues events"
msgstr ""
+msgid "Webhooks|Delete webhook"
+msgstr ""
+
msgid "Webhooks|Deployment events"
msgstr ""
@@ -40328,6 +41168,9 @@ msgstr ""
msgid "Wiki"
msgstr ""
+msgid "Wiki page"
+msgstr ""
+
msgid "Wiki page was successfully created."
msgstr ""
@@ -40433,7 +41276,7 @@ msgstr ""
msgid "WikiPageConflictMessage|Someone edited the page the same time you did. Please check out %{wikiLinkStart}the page%{wikiLinkEnd} and make sure your changes will not unintentionally remove theirs."
msgstr ""
-msgid "WikiPage|An error occured while trying to render the content editor. Please try again later."
+msgid "WikiPage|An error occurred while trying to render the content editor. Please try again later."
msgstr ""
msgid "WikiPage|Are you sure you want to switch back to the classic editor?"
@@ -40592,6 +41435,18 @@ msgstr ""
msgid "WorkItem|New Task"
msgstr ""
+msgid "WorkItem|Something went wrong when creating a work item. Please try again"
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching the work item. Please try again."
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching work item types. Please try again"
+msgstr ""
+
+msgid "WorkItem|Type"
+msgstr ""
+
msgid "WorkItem|Work Items"
msgstr ""
@@ -40658,7 +41513,10 @@ msgstr ""
msgid "You are about to add %{usersTag} people to the discussion. They will all receive a notification."
msgstr ""
-msgid "You are about to permanently delete this project"
+msgid "You are about to delete this forked project containing:"
+msgstr ""
+
+msgid "You are about to delete this project containing:"
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."
@@ -40679,6 +41537,9 @@ msgstr ""
msgid "You are attempting to update a file that has changed since you started editing it."
msgstr ""
+msgid "You are billed if you exceed this number. %{qsrOverageLinkStart}How does billing work?%{qsrOverageLinkEnd}"
+msgstr ""
+
msgid "You are connected to the Prometheus server, but there is currently no data to display."
msgstr ""
@@ -40736,6 +41597,9 @@ msgstr ""
msgid "You are not authorized to update this scanner profile"
msgstr ""
+msgid "You are not authorized to upload metric images"
+msgstr ""
+
msgid "You are now impersonating %{username}"
msgstr ""
@@ -40889,9 +41753,6 @@ msgstr ""
msgid "You can only upload one design when dropping onto an existing design."
msgstr ""
-msgid "You can recover this project until %{date}"
-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 ""
@@ -40940,9 +41801,6 @@ msgstr ""
msgid "You cannot write to this read-only GitLab instance."
msgstr ""
-msgid "You can’t %{tag_start}edit%{tag_end} files directly in this project. Fork this project and submit a merge request with your changes."
-msgstr ""
-
msgid "You can’t edit files directly in this project. Fork this project and submit a merge request with your changes."
msgstr ""
@@ -41094,9 +41952,6 @@ 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 set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
@@ -41127,12 +41982,6 @@ msgstr ""
msgid "You must have maintainer access to force delete a lock"
msgstr ""
-msgid "You must have permission to create a project in a group before forking."
-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 ""
@@ -41538,7 +42387,7 @@ msgstr ""
msgid "Your public email will be displayed on your public profile."
msgstr ""
-msgid "Your request for access could not be processed: %{error_meesage}"
+msgid "Your request for access could not be processed: %{error_message}"
msgstr ""
msgid "Your request for access has been queued for review."
@@ -41718,6 +42567,9 @@ msgstr ""
msgid "archived:"
msgstr ""
+msgid "artifacts"
+msgstr ""
+
msgid "assign yourself"
msgstr ""
@@ -41746,6 +42598,9 @@ msgstr[0] ""
msgid "branch name"
msgstr "分支å稱"
+msgid "builds"
+msgstr ""
+
msgid "by"
msgstr ""
@@ -42166,6 +43021,9 @@ msgstr ""
msgid "contact with same email already exists in group hierarchy"
msgstr ""
+msgid "container registry images"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -42205,6 +43063,9 @@ msgstr ""
msgid "data"
msgstr ""
+msgid "database"
+msgstr ""
+
msgid "date must not be after 9999-12-31"
msgstr ""
@@ -42227,9 +43088,6 @@ msgstr ""
msgid "design"
msgstr ""
-msgid "detached"
-msgstr ""
-
msgid "disabled"
msgstr ""
@@ -42474,7 +43332,7 @@ msgstr ""
msgid "is not a valid X509 certificate."
msgstr ""
-msgid "is not allowed for sign-up."
+msgid "is not allowed for sign-up. Please use your regular email address."
msgstr ""
msgid "is not allowed for this group."
@@ -42486,7 +43344,7 @@ msgstr ""
msgid "is not allowed since the group is not top-level group."
msgstr ""
-msgid "is not allowed."
+msgid "is not allowed. Please use your regular email address."
msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
@@ -42573,6 +43431,9 @@ msgstr ""
msgid "level: %{level}"
msgstr ""
+msgid "lfs objects"
+msgstr ""
+
msgid "limit of %{project_limit} reached"
msgstr ""
@@ -42789,6 +43650,9 @@ msgstr ""
msgid "mrWidget|Merge blocked: pipeline must succeed. It's waiting for a manual action to continue."
msgstr ""
+msgid "mrWidget|Merge blocked: pipeline must succeed. Push a commit that fixes the failure, or %{linkStart}learn about other solutions.%{linkEnd}"
+msgstr ""
+
msgid "mrWidget|Merge blocked: this merge request must be approved."
msgstr ""
@@ -42906,9 +43770,6 @@ msgstr ""
msgid "mrWidget|The changes were not merged into"
msgstr ""
-msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -43056,9 +43917,6 @@ msgstr ""
msgid "open issue"
msgstr ""
-msgid "opened %{timeAgo}"
-msgstr ""
-
msgid "or"
msgstr ""
@@ -43069,6 +43927,12 @@ msgid "out of %d total test"
msgid_plural "out of %d total tests"
msgstr[0] ""
+msgid "packages"
+msgstr ""
+
+msgid "pages"
+msgstr ""
+
msgid "parent"
msgid_plural "parents"
msgstr[0] "父級"
@@ -43214,6 +44078,9 @@ msgid "reply"
msgid_plural "replies"
msgstr[0] ""
+msgid "repositories"
+msgstr ""
+
msgid "repository:"
msgstr ""
@@ -43334,12 +44201,18 @@ msgstr ""
msgid "tag name"
msgstr ""
+msgid "terraform states"
+msgstr ""
+
msgid "the correct format."
msgstr ""
msgid "the file"
msgstr ""
+msgid "the following epic(s)"
+msgstr ""
+
msgid "the following issue(s)"
msgstr ""
@@ -43352,21 +44225,12 @@ msgstr ""
msgid "this document"
msgstr ""
-msgid "this issue cannot be assigned to a confidential epic since it is public"
-msgstr ""
-
-msgid "this issue cannot be made public since it belongs to a confidential epic"
-msgstr ""
-
msgid "time summary"
msgstr ""
msgid "toggle collapse"
msgstr ""
-msgid "train"
-msgstr ""
-
msgid "triggered"
msgstr ""
@@ -43494,3 +44358,6 @@ msgstr ""
msgid "{project}"
msgstr ""
+msgid "✔"
+msgstr ""
+
diff --git a/locale/zh_TW/gitlab.po b/locale/zh_TW/gitlab.po
index 0a9cbc35a42..a55faa75002 100644
--- a/locale/zh_TW/gitlab.po
+++ b/locale/zh_TW/gitlab.po
@@ -14,7 +14,7 @@ msgstr ""
"X-Crowdin-Language: zh-TW\n"
"X-Crowdin-File: /master/locale/gitlab.pot\n"
"X-Crowdin-File-ID: 6\n"
-"PO-Revision-Date: 2022-02-02 15:42\n"
+"PO-Revision-Date: 2022-03-01 20:36\n"
msgid " %{start} to %{end}"
msgstr ""
@@ -132,6 +132,10 @@ msgid "%d approver (you've approved)"
msgid_plural "%d approvers (you've approved)"
msgstr[0] ""
+msgid "%d assigned issue"
+msgid_plural "%d assigned issues"
+msgstr[0] ""
+
msgid "%d changed file"
msgid_plural "%d changed files"
msgstr[0] ""
@@ -352,8 +356,20 @@ msgid "%d vulnerability dismissed"
msgid_plural "%d vulnerabilities dismissed"
msgstr[0] ""
-msgid "%d vulnerability updated"
-msgid_plural "%d vulnerabilities updated"
+msgid "%d vulnerability set to confirmed"
+msgid_plural "%d vulnerabilities set to confirmed"
+msgstr[0] ""
+
+msgid "%d vulnerability set to dismissed"
+msgid_plural "%d vulnerabilities set to dismissed"
+msgstr[0] ""
+
+msgid "%d vulnerability set to needs triage"
+msgid_plural "%d vulnerabilities set to needs triage"
+msgstr[0] ""
+
+msgid "%d vulnerability set to resolved"
+msgid_plural "%d vulnerabilities set to resolved"
msgstr[0] ""
msgid "%d warning found:"
@@ -434,6 +450,12 @@ msgstr[0] ""
msgid "%{completedWeight} of %{totalWeight} weight completed"
msgstr ""
+msgid "%{completed} of %{total} issues closed"
+msgstr ""
+
+msgid "%{completed} of %{total} weight completed"
+msgstr ""
+
msgid "%{cores} cores"
msgstr "%{cores} 核心"
@@ -776,6 +798,9 @@ msgstr "%{openedEpics} 個開放,%{closedEpics} 個關閉"
msgid "%{openedIssues} open, %{closedIssues} closed"
msgstr "%{openedIssues} 個開放,%{closedIssues} 個關閉"
+msgid "%{percentage}%% issues closed"
+msgstr ""
+
msgid "%{percentage}%% weight completed"
msgstr ""
@@ -1190,6 +1215,9 @@ msgid "- User"
msgid_plural "- Users"
msgstr[0] "- 使用者"
+msgid "- of - issues closed"
+msgstr ""
+
msgid "- of - weight completed"
msgstr ""
@@ -1309,7 +1337,7 @@ msgstr "10-19 é …è²¢ç»"
msgid "1000+"
msgstr ""
-msgid "192.168.0.0/24"
+msgid "192.168.0.0/24 or 2001:0DB8:1234::/48"
msgstr ""
msgid "1st contribution!"
@@ -1621,13 +1649,13 @@ msgstr ""
msgid "AWS Access Key"
msgstr "AWS å­˜å–金鑰"
-msgid "AWS Access Key. Only required if not using role instance credentials"
-msgstr ""
-
msgid "AWS Secret Access Key"
msgstr "AWS 密碼存å–金鑰"
-msgid "AWS Secret Access Key. Only required if not using role instance credentials"
+msgid "AWS access key ID (Optional)"
+msgstr ""
+
+msgid "AWS secret access key (Optional)"
msgstr ""
msgid "AWS service error: %{error}"
@@ -1670,7 +1698,7 @@ msgid "Access Tokens"
msgstr "å­˜å–憑證"
msgid "Access denied for your LDAP account."
-msgstr "å­˜å–您的 LDAP 帳號時被拒絕。"
+msgstr ""
msgid "Access denied: %{error}"
msgstr ""
@@ -1687,9 +1715,6 @@ msgstr "ç¦æ­¢å­˜å–。請檢查您的存å–權é™ã€‚"
msgid "Access granted"
msgstr ""
-msgid "Access key ID"
-msgstr ""
-
msgid "Access requests"
msgstr ""
@@ -1864,7 +1889,7 @@ msgstr ""
msgid "Activity"
msgstr "å‹•æ…‹"
-msgid "Activity|An error occured while retrieving activity. Reload the page to try again."
+msgid "Activity|An error occurred while retrieving activity. Reload the page to try again."
msgstr ""
msgid "Add"
@@ -1903,6 +1928,9 @@ msgstr "加入 Zoom 會議"
msgid "Add a %{type}"
msgstr ""
+msgid "Add a GCP region"
+msgstr ""
+
msgid "Add a GPG key"
msgstr "加入 GPG 金鑰"
@@ -1954,6 +1982,9 @@ msgstr ""
msgid "Add a numbered list"
msgstr "加入編號列表"
+msgid "Add a related epic"
+msgstr ""
+
msgid "Add a related issue"
msgstr ""
@@ -2068,6 +2099,9 @@ msgstr ""
msgid "Add or subtract spent time"
msgstr "增加或減少耗時"
+msgid "Add people"
+msgstr ""
+
msgid "Add previously merged commits"
msgstr ""
@@ -2134,6 +2168,9 @@ msgstr ""
msgid "Add webhook"
msgstr "加入 Webhook"
+msgid "Add your team members and others to GitLab."
+msgstr ""
+
msgid "Add/remove"
msgstr ""
@@ -2956,12 +2993,6 @@ msgstr ""
msgid "AdvancedSearch|Reindex required"
msgstr ""
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. Permanently deleting this project will %{strongStart}immediately delete%{strongEnd} its repositories and %{strongStart}all related resources%{strongEnd}, including issues, merge requests etc."
-msgstr ""
-
-msgid "After a project is permanently deleted, it %{strongStart}cannot be recovered%{strongEnd}. You will lose this project's repository and %{strongStart}all related resources%{strongEnd}, including issues and merge requests."
-msgstr ""
-
msgid "After a successful password update you will be redirected to login screen."
msgstr "密碼更新æˆåŠŸå¾Œï¼Œæ‚¨å°‡è¢«é‡æ–°å°Žå‘至登入é é¢ã€‚"
@@ -2992,6 +3023,9 @@ msgstr ""
msgid "Akismet helps prevent the creation of spam issues in public projects."
msgstr ""
+msgid "Alert"
+msgstr ""
+
msgid "AlertManagement|Acknowledged"
msgstr ""
@@ -3364,9 +3398,6 @@ msgstr "所有電å­éƒµä»¶åœ°å€éƒ½å¯ç”¨æ–¼è­˜åˆ¥æ‚¨çš„æ交。"
msgid "All environments"
msgstr ""
-msgid "All epics"
-msgstr ""
-
msgid "All groups and projects"
msgstr "所有群組和專案"
@@ -4101,11 +4132,14 @@ msgstr ""
msgid "ApplicationSettings|Approve users in the pending approval status?"
msgstr ""
-msgid "ApplicationSettings|By making this change, you will automatically approve %d user with the pending approval status."
-msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users with the pending approval status."
+msgid "ApplicationSettings|Approve users who are pending approval?"
+msgstr ""
+
+msgid "ApplicationSettings|By making this change, you will automatically approve %d user who is pending approval."
+msgid_plural "ApplicationSettings|By making this change, you will automatically approve %d users who are pending approval."
msgstr[0] ""
-msgid "ApplicationSettings|By making this change, you will automatically approve all users in pending approval status."
+msgid "ApplicationSettings|By making this change, you will automatically approve all users who are pending approval."
msgstr ""
msgid "ApplicationSettings|Denied domains for sign-ups"
@@ -4506,10 +4540,10 @@ msgstr "歸檔專案"
msgid "Archiving the project will make it entirely read-only. It is hidden from the dashboard and doesn't show up in searches. %{strong_start}The repository cannot be committed to, and no issues, comments, or other entities can be created.%{strong_end} %{link_start}Learn more.%{link_end}"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to delete this project?"
+msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
msgstr ""
-msgid "Are you ABSOLUTELY SURE you wish to remove this group?"
+msgid "Are you absolutely sure?"
msgstr ""
msgid "Are you sure that you want to archive this project?"
@@ -4545,12 +4579,18 @@ msgstr "確定è¦åˆªé™¤æ­¤%{typeOfComment}嗎?"
msgid "Are you sure you want to delete this SSH key?"
msgstr ""
+msgid "Are you sure you want to delete this comment?"
+msgstr ""
+
msgid "Are you sure you want to delete this deploy key?"
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 label?"
+msgstr ""
+
msgid "Are you sure you want to delete this pipeline schedule?"
msgstr "確定è¦åˆªé™¤æ­¤æµæ°´ç·šæŽ’程嗎?"
@@ -4566,9 +4606,6 @@ msgstr ""
msgid "Are you sure you want to discard your changes?"
msgstr ""
-msgid "Are you sure you want to erase this build?"
-msgstr "你確定è¦åˆªé™¤é€™å€‹çµ„建嗎?"
-
msgid "Are you sure you want to import %d repository?"
msgid_plural "Are you sure you want to import %d repositories?"
msgstr[0] ""
@@ -4615,6 +4652,9 @@ msgstr "您確定è¦ç§»é™¤é€™å€‹èº«ä»½è­˜åˆ¥å—Žï¼Ÿ"
msgid "Are you sure you want to remove this list?"
msgstr ""
+msgid "Are you sure you want to remove this nickname?"
+msgstr ""
+
msgid "Are you sure you want to reset the health check token?"
msgstr ""
@@ -4627,10 +4667,10 @@ 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?"
+msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
msgstr ""
-msgid "Are you sure you want to revoke this personal access token? This action cannot be undone."
+msgid "Are you sure you want to revoke this project access token? This action cannot be undone."
msgstr ""
msgid "Are you sure you want to stop this environment?"
@@ -4777,9 +4817,6 @@ msgstr ""
msgid "Assigned to %{assignee_name}"
msgstr ""
-msgid "Assigned to %{name}"
-msgstr ""
-
msgid "Assigned to me"
msgstr ""
@@ -4842,6 +4879,9 @@ msgstr[0] ""
msgid "Attaching the file failed."
msgstr ""
+msgid "Attention"
+msgstr ""
+
msgid "Audit Events"
msgstr ""
@@ -5004,6 +5044,12 @@ msgstr ""
msgid "Authorized applications (%{size})"
msgstr ""
+msgid "AuthorizedApplication|Are you sure you want to revoke this application?"
+msgstr ""
+
+msgid "AuthorizedApplication|Revoke application"
+msgstr ""
+
msgid "Authors: %{authors}"
msgstr ""
@@ -6193,6 +6239,9 @@ msgstr ""
msgid "CICDAnalytics|Shared Runners Usage"
msgstr ""
+msgid "CICDAnalytics|Shared runner pipeline minute duration by month"
+msgstr ""
+
msgid "CICDAnalytics|Shared runner usage"
msgstr ""
@@ -6334,6 +6383,9 @@ msgstr ""
msgid "Can create groups:"
msgstr ""
+msgid "Can not delete primary training"
+msgstr ""
+
msgid "Can't apply as the source branch was deleted."
msgstr ""
@@ -6667,9 +6719,6 @@ msgstr ""
msgid "Changing any setting here requires an application restart"
msgstr ""
-msgid "Changing group URL can have unintended side effects."
-msgstr ""
-
msgid "Charts can't be displayed as the request for data has timed out. %{documentationLink}"
msgstr ""
@@ -6757,9 +6806,6 @@ msgstr ""
msgid "Checking branch availability..."
msgstr ""
-msgid "Checking group URL availability..."
-msgstr ""
-
msgid "Checking group path availability..."
msgstr ""
@@ -7251,6 +7297,9 @@ msgstr ""
msgid "Clear recent searches"
msgstr ""
+msgid "Clear repository checks"
+msgstr ""
+
msgid "Clear search"
msgstr ""
@@ -7383,9 +7432,6 @@ msgstr ""
msgid "Closed MRs"
msgstr ""
-msgid "Closed epics"
-msgstr ""
-
msgid "Closed issues"
msgstr ""
@@ -7422,13 +7468,13 @@ msgstr ""
msgid "Cluster level"
msgstr ""
-msgid "Cluster type must be specificed for Stages::ClusterEndpointInserter"
+msgid "Cluster type must be specified for Stages::ClusterEndpointInserter"
msgstr ""
msgid "ClusterAgents|%{name} successfully deleted"
msgstr ""
-msgid "ClusterAgents|%{number} of %{total} Agents"
+msgid "ClusterAgents|%{number} of %{total} agents"
msgstr ""
msgid "ClusterAgents|%{number} of %{total} clusters connected through cluster certificates"
@@ -7470,6 +7516,15 @@ msgstr ""
msgid "ClusterAgents|Agent never connected to GitLab"
msgstr ""
+msgid "ClusterAgents|Agent version mismatch"
+msgstr ""
+
+msgid "ClusterAgents|Agent version mismatch and update"
+msgstr ""
+
+msgid "ClusterAgents|Agent version update required"
+msgstr ""
+
msgid "ClusterAgents|All"
msgstr ""
@@ -7494,7 +7549,7 @@ msgstr ""
msgid "ClusterAgents|Configuration"
msgstr ""
-msgid "ClusterAgents|Connect a cluster through the Agent"
+msgid "ClusterAgents|Connect a cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connect existing cluster"
@@ -7503,13 +7558,13 @@ msgstr ""
msgid "ClusterAgents|Connect with a certificate"
msgstr ""
-msgid "ClusterAgents|Connect with agent"
+msgid "ClusterAgents|Connect with an agent"
msgstr ""
msgid "ClusterAgents|Connect with the GitLab Agent"
msgstr ""
-msgid "ClusterAgents|Connect your cluster through the Agent"
+msgid "ClusterAgents|Connect your cluster through an agent"
msgstr ""
msgid "ClusterAgents|Connected"
@@ -7569,7 +7624,10 @@ msgstr ""
msgid "ClusterAgents|How to register an agent?"
msgstr ""
-msgid "ClusterAgents|Install new Agent"
+msgid "ClusterAgents|How to update an agent?"
+msgstr ""
+
+msgid "ClusterAgents|Install a new agent"
msgstr ""
msgid "ClusterAgents|Last connected %{timeAgo}."
@@ -7596,7 +7654,7 @@ msgstr ""
msgid "ClusterAgents|Never connected"
msgstr ""
-msgid "ClusterAgents|No Agents"
+msgid "ClusterAgents|No agents"
msgstr ""
msgid "ClusterAgents|No clusters connected through cluster certificates"
@@ -7656,6 +7714,9 @@ msgstr ""
msgid "ClusterAgents|The agent has not been connected in a long time. There might be a connectivity issue. Last contact was %{timeAgo}."
msgstr ""
+msgid "ClusterAgents|The agent version do not match each other across your cluster's pods. This can happen when a new agent version was just deployed and Kubernetes is shutting down the old pods."
+msgstr ""
+
msgid "ClusterAgents|The recommended installation method includes the token. If you want to follow the advanced installation method provided in the docs, make sure you save the token value before you close this window."
msgstr ""
@@ -7702,6 +7763,9 @@ msgstr ""
msgid "ClusterAgents|You will need to create a token to connect to your agent"
msgstr ""
+msgid "ClusterAgents|Your agent version is out of sync with your GitLab version (v%{version}), which might cause compatibility problems. Update the agent installed on your cluster to the most recent version."
+msgstr ""
+
msgid "ClusterAgents|Your instance doesn't have the %{linkStart}GitLab Agent Server (KAS)%{linkEnd} set up. Ask a GitLab Administrator to install it."
msgstr ""
@@ -8578,9 +8642,6 @@ msgstr ""
msgid "Comma-separated list of email addresses."
msgstr ""
-msgid "Comma-separated list of users allowed to exceed the rate limit."
-msgstr ""
-
msgid "Comma-separated, e.g. '1.1.1.1, 2.2.2.0/24'"
msgstr ""
@@ -8906,6 +8967,12 @@ msgstr ""
msgid "Confidential"
msgstr ""
+msgid "Confidential issue"
+msgstr ""
+
+msgid "Confidential note"
+msgstr ""
+
msgid "Confidentiality"
msgstr ""
@@ -8939,6 +9006,9 @@ msgstr ""
msgid "Configure Dependency Scanning in `.gitlab-ci.yml`, creating this file if it does not already exist"
msgstr ""
+msgid "Configure GitLab"
+msgstr ""
+
msgid "Configure GitLab runners to start using the Web Terminal. %{helpStart}Learn more.%{helpEnd}"
msgstr ""
@@ -8987,6 +9057,15 @@ msgstr ""
msgid "Configure pipelines to deploy web apps, backend services, APIs and static resources to Google Cloud"
msgstr ""
+msgid "Configure region"
+msgstr ""
+
+msgid "Configure region for environment"
+msgstr ""
+
+msgid "Configure regions"
+msgstr ""
+
msgid "Configure repository mirroring."
msgstr ""
@@ -9020,6 +9099,9 @@ msgstr ""
msgid "Configure which lists are shown for anyone who visits this board"
msgstr ""
+msgid "Configure your environments to be deployed to specific geographical regions"
+msgstr ""
+
msgid "Confirm"
msgstr ""
@@ -9719,10 +9801,10 @@ msgstr ""
msgid "CorpusManagement|Actions"
msgstr ""
-msgid "CorpusManagement|Corpus are used in fuzz testing as mutation source to Improve future testing."
+msgid "CorpusManagement|Corpus file"
msgstr ""
-msgid "CorpusManagement|Corpus file"
+msgid "CorpusManagement|Corpus files are used in coverage-guided fuzz testing as seed inputs to improve testing."
msgstr ""
msgid "CorpusManagement|Corpus files must be in *.zip format. Maximum 5 GB"
@@ -9776,6 +9858,9 @@ msgstr ""
msgid "Could not apply %{name} command."
msgstr ""
+msgid "Could not apply %{name} command. %{message}."
+msgstr ""
+
msgid "Could not authorize chat nickname. Try again!"
msgstr ""
@@ -9926,6 +10011,9 @@ msgstr ""
msgid "Create a Mattermost team for this group"
msgstr ""
+msgid "Create a group"
+msgstr ""
+
msgid "Create a merge request"
msgstr ""
@@ -9950,6 +10038,9 @@ msgstr ""
msgid "Create a personal access token on your account to pull or push via %{protocol}."
msgstr ""
+msgid "Create a project"
+msgstr ""
+
msgid "Create an account using:"
msgstr ""
@@ -10313,6 +10404,9 @@ msgstr ""
msgid "Creation date"
msgstr ""
+msgid "Creator"
+msgstr ""
+
msgid "Credentials"
msgstr ""
@@ -10325,9 +10419,15 @@ msgstr ""
msgid "CredentialsInventory|Personal Access Tokens"
msgstr ""
+msgid "CredentialsInventory|Project Access Tokens"
+msgstr ""
+
msgid "CredentialsInventory|SSH Keys"
msgstr ""
+msgid "Credit card required to be on file in order to create a pipeline"
+msgstr ""
+
msgid "Credit card:"
msgstr ""
@@ -10511,9 +10611,6 @@ msgstr ""
msgid "Customer relations"
msgstr ""
-msgid "Customizable by an administrator."
-msgstr ""
-
msgid "Customizable by owners."
msgstr ""
@@ -10643,30 +10740,18 @@ msgstr ""
msgid "CycleAnalytics|%{selectedLabelsCount} selected (%{maxLabels} max)"
msgstr ""
-msgid "CycleAnalytics|%{stageCount} stages selected"
-msgstr ""
-
-msgid "CycleAnalytics|All stages"
-msgstr ""
-
-msgid "CycleAnalytics|Average days to completion"
+msgid "CycleAnalytics|Average time to completion"
msgstr ""
msgid "CycleAnalytics|Date"
msgstr ""
-msgid "CycleAnalytics|Days to completion"
-msgstr ""
-
msgid "CycleAnalytics|Display chart filters"
msgstr ""
msgid "CycleAnalytics|Lead Time for Changes"
msgstr ""
-msgid "CycleAnalytics|No stages selected"
-msgstr ""
-
msgid "CycleAnalytics|Number of tasks"
msgstr ""
@@ -10693,18 +10778,30 @@ msgstr ""
msgid "CycleAnalytics|Showing data for group '%{groupName}' from %{createdAfter} to %{createdBefore}"
msgstr ""
-msgid "CycleAnalytics|Stages"
+msgid "CycleAnalytics|Stage time: %{title}"
msgstr ""
msgid "CycleAnalytics|Tasks by type"
msgstr ""
-msgid "CycleAnalytics|The average time spent in the selected stage for the items that were completed on each date. Data limited to the last 500 items."
+msgid "CycleAnalytics|The average time items spent in this stage. Data limited to items completed within this date range."
msgstr ""
msgid "CycleAnalytics|The given date range is larger than 180 days"
msgstr ""
+msgid "CycleAnalytics|The total time items spent across each value stream stage. Data limited to items completed within this date range."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Stage time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|There is no data for 'Total time' available. Adjust the current filters."
+msgstr ""
+
+msgid "CycleAnalytics|Total time"
+msgstr ""
+
msgid "CycleAnalytics|Type of work"
msgstr ""
@@ -10717,9 +10814,6 @@ msgstr ""
msgid "CycleAnalytics|project dropdown filter"
msgstr ""
-msgid "CycleAnalytics|stage dropdown"
-msgstr ""
-
msgid "DAG visualization requires at least 3 dependent jobs."
msgstr ""
@@ -10819,10 +10913,16 @@ msgstr ""
msgid "DastProfiles|AJAX spider"
msgstr ""
+msgid "DastProfiles|API"
+msgstr ""
+
+msgid "DastProfiles|API endpoint URL"
+msgstr ""
+
msgid "DastProfiles|Active"
msgstr ""
-msgid "DastProfiles|Additional request headers (Optional)"
+msgid "DastProfiles|Additional request headers (optional)"
msgstr ""
msgid "DastProfiles|Are you sure you want to delete this profile?"
@@ -10837,6 +10937,9 @@ msgstr ""
msgid "DastProfiles|Branch missing"
msgstr ""
+msgid "DastProfiles|Choose a scan method"
+msgstr ""
+
msgid "DastProfiles|Could not create the scanner profile. Please try again."
msgstr ""
@@ -10906,7 +11009,13 @@ msgstr ""
msgid "DastProfiles|Excluded URLs"
msgstr ""
-msgid "DastProfiles|Excluded URLs (Optional)"
+msgid "DastProfiles|Excluded URLs (optional)"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths"
+msgstr ""
+
+msgid "DastProfiles|Excluded paths (optional)"
msgstr ""
msgid "DastProfiles|Hide debug messages"
@@ -10963,9 +11072,6 @@ msgstr ""
msgid "DastProfiles|Request headers"
msgstr ""
-msgid "DastProfiles|Rest API"
-msgstr ""
-
msgid "DastProfiles|Run the AJAX spider, in addition to the traditional spider, to crawl the target site."
msgstr ""
@@ -10975,6 +11081,9 @@ msgstr ""
msgid "DastProfiles|Save profile"
msgstr ""
+msgid "DastProfiles|Scan method"
+msgstr ""
+
msgid "DastProfiles|Scan mode"
msgstr ""
@@ -11053,12 +11162,24 @@ msgstr ""
msgid "DastProfiles|Website"
msgstr ""
+msgid "DastProfiles|What does each method do?"
+msgstr ""
+
msgid "DastProfiles|You can either choose a passive scan or validate the target site from the site profile management page. %{docsLinkStart}Learn more about site validation.%{docsLinkEnd}"
msgstr ""
msgid "DastProfiles|You cannot run an active scan against an unvalidated site."
msgstr ""
+msgid "DastProfiles|folder/dast_example.har or https://example.com/dast_example.har"
+msgstr ""
+
+msgid "DastProfiles|folder/example.postman_collection.json or https://example.com/"
+msgstr ""
+
+msgid "DastProfiles|folder/openapi.json or https://example.com/openapi.json"
+msgstr ""
+
msgid "DastSiteValidation|Copy HTTP header to clipboard"
msgstr ""
@@ -11165,6 +11286,9 @@ msgstr ""
msgid "DatadogIntegration|API URL"
msgstr ""
+msgid "DatadogIntegration|Custom tags in Datadog. Enter one tag per line in the %{codeOpen}key:value%{codeClose} format. %{linkOpen}How do I use tags?%{linkClose}"
+msgstr ""
+
msgid "DatadogIntegration|Environment"
msgstr ""
@@ -11183,12 +11307,18 @@ msgstr ""
msgid "DatadogIntegration|Tag all data from this GitLab instance in Datadog. Useful when managing several self-managed deployments."
msgstr ""
+msgid "DatadogIntegration|Tags"
+msgstr ""
+
msgid "DatadogIntegration|The Datadog site to send data to. To send data to the EU site, use %{codeOpen}datadoghq.eu%{codeClose}."
msgstr ""
msgid "DatadogIntegration|Trace your GitLab pipelines with Datadog."
msgstr ""
+msgid "DatadogIntegration|have an invalid format"
+msgstr ""
+
msgid "Datasource name not found"
msgstr ""
@@ -11198,9 +11328,6 @@ msgstr ""
msgid "Date merged"
msgstr ""
-msgid "Date picker"
-msgstr ""
-
msgid "Date range"
msgstr ""
@@ -11354,9 +11481,6 @@ msgstr ""
msgid "Definition"
msgstr ""
-msgid "Delayed Project Deletion (%{adjourned_deletion})"
-msgstr ""
-
msgid "DelayedJobs|Are you sure you want to run %{jobName} immediately? Otherwise this job will run automatically after its timer finishes."
msgstr ""
@@ -11435,10 +11559,10 @@ msgstr ""
msgid "Delete pipeline"
msgstr ""
-msgid "Delete project"
+msgid "Delete pipeline schedule"
msgstr ""
-msgid "Delete project. Are you ABSOLUTELY SURE?"
+msgid "Delete project"
msgstr ""
msgid "Delete row"
@@ -11468,6 +11592,9 @@ msgstr ""
msgid "Delete this epic and all descendants?"
msgstr ""
+msgid "Delete this project"
+msgstr ""
+
msgid "Delete user list"
msgstr ""
@@ -11720,6 +11847,12 @@ msgstr ""
msgid "Deploy to..."
msgstr ""
+msgid "DeployBoards|To see deployment progress for your environments, make sure you are deploying to %{codeStart}$KUBE_NAMESPACE%{codeEnd} and annotating with %{codeStart}app.gitlab.com/app=$CI_PROJECT_PATH_SLUG%{codeEnd} and %{codeStart}app.gitlab.com/env=$CI_ENVIRONMENT_SLUG%{codeEnd}."
+msgstr ""
+
+msgid "DeployBoard|Kubernetes Pods"
+msgstr ""
+
msgid "DeployFreeze|Add a freeze period to prevent unintended releases during a period of time for a given environment. You must update the deployment jobs in %{filename} according to the deploy freezes added here. %{freeze_period_link_start}Learn more.%{freeze_period_link_end}"
msgstr ""
@@ -11804,9 +11937,6 @@ msgstr ""
msgid "DeployTokens|Active Deploy Tokens (%{active_tokens})"
msgstr ""
-msgid "DeployTokens|Allows read and write access to registry images."
-msgstr ""
-
msgid "DeployTokens|Allows read and write access to the package registry."
msgstr ""
@@ -11819,6 +11949,9 @@ msgstr ""
msgid "DeployTokens|Allows read-only access to the repository."
msgstr ""
+msgid "DeployTokens|Allows write access to registry images."
+msgstr ""
+
msgid "DeployTokens|Copy deploy token"
msgstr ""
@@ -11912,12 +12045,57 @@ msgstr ""
msgid "Deploying to AWS is easy with GitLab"
msgstr ""
+msgid "Deployment"
+msgstr ""
+
msgid "Deployment Frequency"
msgstr ""
+msgid "Deployment Target|Project deployment target (optional)"
+msgstr ""
+
+msgid "Deployment Target|Select the deployment target"
+msgstr ""
+
msgid "Deployment frequency"
msgstr ""
+msgid "DeploymentTarget|GitLab Pages"
+msgstr ""
+
+msgid "DeploymentTarget|Heroku"
+msgstr ""
+
+msgid "DeploymentTarget|Infrastructure provider (Terraform, Cloudformation, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Kubernetes (GKE, EKS, OpenShift, and so on)"
+msgstr ""
+
+msgid "DeploymentTarget|Managed container runtime (Fargate, Cloud Run, DigitalOcean App)"
+msgstr ""
+
+msgid "DeploymentTarget|Mobile app store"
+msgstr ""
+
+msgid "DeploymentTarget|No deployment planned"
+msgstr ""
+
+msgid "DeploymentTarget|Other hosting service"
+msgstr ""
+
+msgid "DeploymentTarget|Registry (package or container)"
+msgstr ""
+
+msgid "DeploymentTarget|Self-managed container runtime (Podman, Docker Swarm, Docker Compose)"
+msgstr ""
+
+msgid "DeploymentTarget|Serverless backend (Lambda, Cloud functions)"
+msgstr ""
+
+msgid "DeploymentTarget|Virtual machine (for example, EC2)"
+msgstr ""
+
msgid "Deployments"
msgstr ""
@@ -11955,6 +12133,9 @@ msgstr ""
msgid "Deployment|This deployment was created using the API"
msgstr ""
+msgid "Deployment|Triggerer"
+msgstr ""
+
msgid "Deployment|Waiting"
msgstr ""
@@ -11982,6 +12163,18 @@ msgstr ""
msgid "Deprecated API rate limits"
msgstr ""
+msgid "Deprecations|Feature deprecation and removal"
+msgstr ""
+
+msgid "Deprecations|For information on a possible replacement %{epicStart} learn more about Opstrace %{epicEnd}."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7 and are %{epicStart} scheduled for removal %{epicEnd} in GitLab 15.0."
+msgstr ""
+
+msgid "Deprecations|The metrics, logs and tracing features were deprecated in GitLab 14.7, and are %{removal_link_start} scheduled for removal %{link_end} in GitLab 15.0. For information on a possible replacement, %{opstrace_link_start} learn more about Opstrace %{link_end}."
+msgstr ""
+
msgid "Deprioritize label"
msgstr ""
@@ -12226,10 +12419,10 @@ msgstr ""
msgid "DevopsAdoption|At least one deploy"
msgstr ""
-msgid "DevopsAdoption|At least one issue opened"
+msgid "DevopsAdoption|At least one issue created"
msgstr ""
-msgid "DevopsAdoption|At least one merge request opened"
+msgid "DevopsAdoption|At least one merge request created"
msgstr ""
msgid "DevopsAdoption|At least one pipeline successfully run"
@@ -12427,6 +12620,9 @@ msgstr ""
msgid "Direct member"
msgstr ""
+msgid "Direct members"
+msgstr ""
+
msgid "Direct non-authenticated users to this page."
msgstr ""
@@ -12542,6 +12738,9 @@ msgid "Dismiss %d selected vulnerability as"
msgid_plural "Dismiss %d selected vulnerabilities as"
msgstr[0] ""
+msgid "Dismiss Alert"
+msgstr ""
+
msgid "Dismiss merge request promotion"
msgstr ""
@@ -12569,9 +12768,15 @@ msgstr ""
msgid "Display alerts from all configured monitoring tools."
msgstr ""
+msgid "Display milestones"
+msgstr ""
+
msgid "Display name"
msgstr ""
+msgid "Display progress of child issues"
+msgstr ""
+
msgid "Display rendered file"
msgstr ""
@@ -12677,6 +12882,9 @@ msgstr ""
msgid "Download image"
msgstr ""
+msgid "Download payload"
+msgstr ""
+
msgid "Download raw data (.csv)"
msgstr ""
@@ -12854,6 +13062,9 @@ msgstr ""
msgid "Edit in Web IDE"
msgstr ""
+msgid "Edit in pipeline editor"
+msgstr ""
+
msgid "Edit in single-file editor"
msgstr ""
@@ -12896,6 +13107,9 @@ msgstr ""
msgid "Edit your most recent comment in a thread (from an empty textarea)"
msgstr ""
+msgid "Edit, lint, and visualize your pipeline."
+msgstr ""
+
msgid "Edited"
msgstr ""
@@ -13337,6 +13551,9 @@ msgstr ""
msgid "Enforce two-factor authentication for all user sign-ins."
msgstr ""
+msgid "Enhance security by storing service account keys in secret managers - learn more about %{docLinkStart}secret management with GitLab%{docLinkEnd}"
+msgstr ""
+
msgid "Ensure connectivity is available from the GitLab server to the Prometheus server"
msgstr ""
@@ -13397,6 +13614,9 @@ 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 following to confirm:"
+msgstr ""
+
msgid "Enter the name of your application, and we'll return a unique %{type}."
msgstr ""
@@ -13926,9 +14146,6 @@ 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 ""
@@ -14064,6 +14281,9 @@ msgstr ""
msgid "Errors:"
msgstr ""
+msgid "Escalate this incident"
+msgstr ""
+
msgid "Escalation Policies"
msgstr ""
@@ -14076,6 +14296,9 @@ msgstr ""
msgid "Escalation policies must have at least one rule"
msgstr ""
+msgid "Escalation policy"
+msgstr ""
+
msgid "Escalation policy:"
msgstr ""
@@ -14326,6 +14549,9 @@ msgstr ""
msgid "Existing sign in methods may be removed"
msgstr ""
+msgid "Exit."
+msgstr ""
+
msgid "Expand"
msgstr ""
@@ -14422,6 +14648,9 @@ msgstr ""
msgid "Explore public groups"
msgstr ""
+msgid "Explore public projects"
+msgstr ""
+
msgid "Explore snippets"
msgstr ""
@@ -14582,7 +14811,7 @@ msgid "Failed to archive a design. Please try again."
msgid_plural "Failed to archive designs. Please try again."
msgstr[0] ""
-msgid "Failed to assign a reviewer because no user was found."
+msgid "Failed to assign a reviewer because no user was specified."
msgstr ""
msgid "Failed to assign a user because no user was found."
@@ -14648,10 +14877,10 @@ msgstr ""
msgid "Failed to find import label for Jira import."
msgstr ""
-msgid "Failed to generate export, please try again later."
+msgid "Failed to find users for %{missing}"
msgstr ""
-msgid "Failed to generate report, please try again after sometime"
+msgid "Failed to generate export, please try again later."
msgstr ""
msgid "Failed to get ref."
@@ -14750,6 +14979,9 @@ msgstr ""
msgid "Failed to remove a to-do item for the design."
msgstr ""
+msgid "Failed to remove attention because no user was found."
+msgstr ""
+
msgid "Failed to remove mirror."
msgstr ""
@@ -14762,6 +14994,9 @@ msgstr ""
msgid "Failed to remove user key."
msgstr ""
+msgid "Failed to request attention because no user was found."
+msgstr ""
+
msgid "Failed to reset key. Please try again."
msgstr ""
@@ -14843,6 +15078,9 @@ msgstr ""
msgid "Feature Flags"
msgstr ""
+msgid "Feature deprecation and removal"
+msgstr ""
+
msgid "Feature flag status"
msgstr ""
@@ -15339,7 +15577,7 @@ msgstr ""
msgid "For each job, re-use the project workspace. If the workspace doesn't exist, use %{code_open}git clone%{code_close}."
msgstr ""
-msgid "For example, the application using the token or the purpose of the token."
+msgid "For example, the application using the token or the purpose of the token. Do not give sensitive information for the name of the token, as it will be visible to all %{resource_type} members."
msgstr ""
msgid "For files larger than this limit, only index the file name. The file content is neither indexed nor searchable."
@@ -15423,9 +15661,6 @@ msgstr ""
msgid "ForkProject|Select a namespace"
msgstr ""
-msgid "ForkProject|Select a namespace to fork the project"
-msgstr ""
-
msgid "ForkProject|The project can be accessed by any logged in user."
msgstr ""
@@ -15522,6 +15757,9 @@ msgstr ""
msgid "Full name"
msgstr ""
+msgid "GCP region configured"
+msgstr ""
+
msgid "GPG Key ID:"
msgstr ""
@@ -15702,6 +15940,9 @@ msgstr ""
msgid "Geo|Failed"
msgstr ""
+msgid "Geo|Filter Geo sites"
+msgstr ""
+
msgid "Geo|Filter by name"
msgstr ""
@@ -16113,6 +16354,12 @@ msgstr ""
msgid "GitLab Issue"
msgstr ""
+msgid "GitLab KAS"
+msgstr ""
+
+msgid "GitLab Memberships CSV Export"
+msgstr ""
+
msgid "GitLab Pages"
msgstr ""
@@ -16161,6 +16408,9 @@ 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 free to use. Many features for larger teams are part of our %{link_start}paid products%{link_end}. You can try Ultimate for free without any obligation or payment details."
+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 ""
@@ -16287,7 +16537,7 @@ msgstr ""
msgid "GitLabPages|When enabled, all attempts to visit your website through HTTP are automatically redirected to HTTPS using a response with status code 301. Requires a valid certificate for all domains. %{docs_link_start}Learn more.%{link_end}"
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. %{docs_link_start}Learn more.%{link_end}"
+msgid "GitLabPages|When using Pages under the general domain of a GitLab instance (%{pages_host}), you cannot use HTTPS with subdomains of subdomains. If your namespace or groupname contains a dot, it does not work. This is a limitation of the HTTP Over TLS protocol. HTTP pages work if you don't redirect HTTP to HTTPS. %{docs_link_start}Learn more.%{link_end}"
msgstr ""
msgid "GitLabPages|With GitLab Pages you can host your static website directly from your GitLab repository. %{docs_link_start}Learn more.%{link_end}"
@@ -16464,9 +16714,6 @@ msgstr ""
msgid "Go to find file"
msgstr ""
-msgid "Go to fork"
-msgstr ""
-
msgid "Go to issue boards"
msgstr ""
@@ -16674,9 +16921,6 @@ msgstr ""
msgid "Group Hooks"
msgstr ""
-msgid "Group ID"
-msgstr ""
-
msgid "Group Owner must have signed in with SAML before enabling Group Managed Accounts"
msgstr ""
@@ -16704,9 +16948,6 @@ msgstr ""
msgid "Group by"
msgstr ""
-msgid "Group description"
-msgstr ""
-
msgid "Group description (optional)"
msgstr ""
@@ -16821,7 +17062,7 @@ msgstr ""
msgid "Group: %{name}"
msgstr ""
-msgid "GroupActivityMetrics|Issues opened"
+msgid "GroupActivityMetrics|Issues created"
msgstr ""
msgid "GroupActivityMetrics|Last 90 days"
@@ -16830,7 +17071,7 @@ msgstr ""
msgid "GroupActivityMetrics|Members added"
msgstr ""
-msgid "GroupActivityMetrics|Merge Requests opened"
+msgid "GroupActivityMetrics|Merge Requests created"
msgstr ""
msgid "GroupActivityMetrics|Recent activity"
@@ -17121,6 +17362,9 @@ msgstr ""
msgid "GroupSettings|Changing a group's URL can have unintended side effects."
msgstr ""
+msgid "GroupSettings|Choose a group path that does not start with a dash or end with a period. It can also contain alphanumeric characters and underscores."
+msgstr ""
+
msgid "GroupSettings|Compliance frameworks"
msgstr ""
@@ -17154,7 +17398,7 @@ msgstr ""
msgid "GroupSettings|If not specified at the group or instance level, the default is %{default_initial_branch_name}. Does not affect existing repositories."
msgstr ""
-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."
+msgid "GroupSettings|If the parent group's visibility is lower than the group's current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility."
msgstr ""
msgid "GroupSettings|New runners registration token has been generated!"
@@ -17271,7 +17515,10 @@ msgstr ""
msgid "Groups and projects"
msgstr ""
-msgid "Groups and subgroups"
+msgid "Groups are a great way to organize projects and people."
+msgstr ""
+
+msgid "Groups are the best way to manage projects and members."
msgstr ""
msgid "Groups to synchronize"
@@ -17382,13 +17629,16 @@ msgstr ""
msgid "GroupsTree|Are you sure you want to leave the \"%{fullName}\" group?"
msgstr ""
-msgid "GroupsTree|Edit group"
+msgid "GroupsTree|Delete"
+msgstr ""
+
+msgid "GroupsTree|Edit"
msgstr ""
msgid "GroupsTree|Failed to leave the group. Please make sure you are not the only owner."
msgstr ""
-msgid "GroupsTree|Leave this group"
+msgid "GroupsTree|Leave group"
msgstr ""
msgid "GroupsTree|Loading groups"
@@ -17400,9 +17650,57 @@ msgstr ""
msgid "GroupsTree|No groups or projects matched your search"
msgstr ""
+msgid "GroupsTree|Options"
+msgstr ""
+
msgid "GroupsTree|Search by name"
msgstr ""
+msgid "Groups|Avatar will be removed. Are you sure?"
+msgstr ""
+
+msgid "Groups|Changing group URL can have unintended side effects."
+msgstr ""
+
+msgid "Groups|Checking group URL availability..."
+msgstr ""
+
+msgid "Groups|Enter a descriptive name for your group."
+msgstr ""
+
+msgid "Groups|Group ID"
+msgstr ""
+
+msgid "Groups|Group URL"
+msgstr ""
+
+msgid "Groups|Group avatar"
+msgstr ""
+
+msgid "Groups|Group description (optional)"
+msgstr ""
+
+msgid "Groups|Group name"
+msgstr ""
+
+msgid "Groups|Group path is available."
+msgstr ""
+
+msgid "Groups|Group path is unavailable. Path has been replaced with a suggested available path."
+msgstr ""
+
+msgid "Groups|Learn more"
+msgstr ""
+
+msgid "Groups|Must start with letter, digit, emoji, or underscore. Can also contain periods, dashes, spaces, and parentheses."
+msgstr ""
+
+msgid "Groups|Remove avatar"
+msgstr ""
+
+msgid "Groups|Save changes"
+msgstr ""
+
msgid "Guideline"
msgstr ""
@@ -17412,6 +17710,9 @@ msgstr ""
msgid "HAR file path or URL"
msgstr ""
+msgid "HTTP Archive (HAR)"
+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 ""
@@ -17810,6 +18111,9 @@ msgstr ""
msgid "INFO: Your SSH key is expiring soon. Please generate a new key."
msgstr ""
+msgid "IP"
+msgstr ""
+
msgid "IP Address"
msgstr ""
@@ -17846,6 +18150,9 @@ msgstr ""
msgid "IdentityVerification|Verify your identity"
msgstr ""
+msgid "IdentityVerification|You can always verify your account at a later time to create a group."
+msgstr ""
+
msgid "If any indexed field exceeds this limit, it is truncated to this number of characters. The rest of the content is neither indexed nor searchable. This does not apply to repository and wiki indexing. For unlimited characters, set this to 0."
msgstr ""
@@ -17903,6 +18210,9 @@ msgstr ""
msgid "If you add %{codeStart}needs%{codeEnd} to jobs in your pipeline you'll be able to view the %{codeStart}needs%{codeEnd} relationships between jobs in this tab as a %{linkStart}Directed Acyclic Graph (DAG)%{linkEnd}."
msgstr ""
+msgid "If you are added to a project, it will be displayed here."
+msgstr ""
+
msgid "If you did not initiate these sign-in attempts, please reach out to your administrator or enable two-factor authentication (2FA) on your account."
msgstr ""
@@ -18206,12 +18516,24 @@ msgstr ""
msgid "InProductMarketing|3 ways to dive into GitLab CI/CD"
msgstr ""
+msgid "InProductMarketing|A single application eliminates complex integrations, data chokepoints, and toolchain maintenance, resulting in greater productivity and lower cost."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features, build more efficiently, strengthen security and compliance."
+msgstr ""
+
+msgid "InProductMarketing|Access advanced features."
+msgstr ""
+
msgid "InProductMarketing|Actually, GitLab makes the team work (better)"
msgstr ""
msgid "InProductMarketing|And finally %{deploy_link} a Python application."
msgstr ""
+msgid "InProductMarketing|And many more..."
+msgstr ""
+
msgid "InProductMarketing|Are your runners ready?"
msgstr ""
@@ -18230,15 +18552,33 @@ msgstr ""
msgid "InProductMarketing|Blog"
msgstr ""
+msgid "InProductMarketing|Break down silos to coordinate seamlessly across development, operations, and security with a consistent experience across the development lifecycle."
+msgstr ""
+
+msgid "InProductMarketing|Burn up/down charts"
+msgstr ""
+
msgid "InProductMarketing|By enabling code owners and required merge approvals the right person will review the right MR. This is a win-win: cleaner code and a more efficient review process."
msgstr ""
msgid "InProductMarketing|Click on the number below that corresponds with your answer — 1 being very difficult, 5 being very easy."
msgstr ""
+msgid "InProductMarketing|Code owners"
+msgstr ""
+
msgid "InProductMarketing|Code owners and required merge approvals are part of the paid tiers of GitLab. You can start a free 30-day trial of GitLab Ultimate and enable these features in less than 5 minutes with no credit card required."
msgstr ""
+msgid "InProductMarketing|Code review analytics"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration across stages in GitLab"
+msgstr ""
+
+msgid "InProductMarketing|Collaboration made easy"
+msgstr ""
+
msgid "InProductMarketing|Create a custom CI runner with just a few clicks"
msgstr ""
@@ -18248,12 +18588,21 @@ msgstr ""
msgid "InProductMarketing|Create a project in GitLab in 5 minutes"
msgstr ""
+msgid "InProductMarketing|Create well-defined workflows by using scoped labels on issues, merge requests, and epics. Labels with the same scope cannot be used together, which prevents conflicts."
+msgstr ""
+
msgid "InProductMarketing|Create your first project!"
msgstr ""
+msgid "InProductMarketing|Define who owns specific files or directories, so the right reviewers are suggested when a merge request introduces changes to those files."
+msgstr ""
+
msgid "InProductMarketing|Deliver Better Products Faster"
msgstr ""
+msgid "InProductMarketing|Dependency scanning"
+msgstr ""
+
msgid "InProductMarketing|Did you know teams that use GitLab are far more efficient?"
msgstr ""
@@ -18263,15 +18612,27 @@ msgstr ""
msgid "InProductMarketing|Dig in and create a project and a repo"
msgstr ""
+msgid "InProductMarketing|Discover Premium & Ultimate"
+msgstr ""
+
+msgid "InProductMarketing|Discover Premium & Ultimate."
+msgstr ""
+
msgid "InProductMarketing|Do you have a minute?"
msgstr ""
msgid "InProductMarketing|Do you have a teammate who would be perfect for this task?"
msgstr ""
+msgid "InProductMarketing|Dynamic application security testing"
+msgstr ""
+
msgid "InProductMarketing|Easy"
msgstr ""
+msgid "InProductMarketing|Epics"
+msgstr ""
+
msgid "InProductMarketing|Expand your DevOps journey with a free GitLab trial"
msgstr ""
@@ -18293,9 +18654,15 @@ msgstr ""
msgid "InProductMarketing|Feel the need for speed?"
msgstr ""
+msgid "InProductMarketing|Find and fix bottlenecks in your code review process by understanding how long open merge requests have been in review."
+msgstr ""
+
msgid "InProductMarketing|Find out how your teams are really doing"
msgstr ""
+msgid "InProductMarketing|Find out if your external libraries are safe. Run dependency scanning jobs that check for known vulnerabilities in your external libraries."
+msgstr ""
+
msgid "InProductMarketing|Follow our steps"
msgstr ""
@@ -18332,6 +18699,9 @@ msgstr ""
msgid "InProductMarketing|GitLab is better with teammates to help out!"
msgstr ""
+msgid "InProductMarketing|GitLab is infrastructure agnostic (supporting GCP, AWS, Azure, OpenShift, VMWare, On Prem, Bare Metal, and more), offering a consistent workflow experience – irrespective of the environment."
+msgstr ""
+
msgid "InProductMarketing|GitLab provides static application security testing (SAST), dynamic application security testing (DAST), container scanning, and dependency scanning to help you deliver secure applications along with license compliance."
msgstr ""
@@ -18422,21 +18792,36 @@ msgstr ""
msgid "InProductMarketing|It's also possible to simply %{external_repo_link} in order to take advantage of GitLab's CI/CD."
msgstr ""
+msgid "InProductMarketing|Keep your code quality high by defining who should approve merge requests and how many approvals are required."
+msgstr ""
+
msgid "InProductMarketing|Launch GitLab CI/CD in 20 minutes or less"
msgstr ""
+msgid "InProductMarketing|Lower cost of development"
+msgstr ""
+
+msgid "InProductMarketing|Make it easier to collaborate on high-level ideas by grouping related issues in an epic."
+msgstr ""
+
msgid "InProductMarketing|Making the switch? It's easier than you think to import your projects into GitLab. Move %{github_link}, or import something %{bitbucket_link}."
msgstr ""
msgid "InProductMarketing|Master the art of importing!"
msgstr ""
+msgid "InProductMarketing|Merge request approval rule"
+msgstr ""
+
msgid "InProductMarketing|Move on to easily creating a Pages website %{ci_template_link}"
msgstr ""
msgid "InProductMarketing|Multiple owners, confusing workstreams? We've got you covered"
msgstr ""
+msgid "InProductMarketing|Multiple required approvers"
+msgstr ""
+
msgid "InProductMarketing|Need an alternative to importing?"
msgstr ""
@@ -18449,18 +18834,33 @@ msgstr ""
msgid "InProductMarketing|Our tool brings all the things together"
msgstr ""
+msgid "InProductMarketing|Protect your web application by using DAST to examine for vulnerabilities in deployed environments."
+msgstr ""
+
msgid "InProductMarketing|Rapid development, simplified"
msgstr ""
msgid "InProductMarketing|Reduce Security & Compliance Risk"
msgstr ""
+msgid "InProductMarketing|Require multiple approvers on a merge request, so you know it's in good shape before it's merged."
+msgstr ""
+
+msgid "InProductMarketing|Roadmaps"
+msgstr ""
+
+msgid "InProductMarketing|Scoped labels"
+msgstr ""
+
msgid "InProductMarketing|Security that's integrated into your development lifecycle"
msgstr ""
msgid "InProductMarketing|Sometimes you're not ready to make a full transition to a new tool. If you're not ready to fully commit, %{mirroring_link} gives you a safe way to try out GitLab in parallel with your current tool."
msgstr ""
+msgid "InProductMarketing|Speed. Efficiency. Trust."
+msgstr ""
+
msgid "InProductMarketing|Spin up an autoscaling runner in GitLab"
msgstr ""
@@ -18470,6 +18870,9 @@ msgstr ""
msgid "InProductMarketing|Start a Self-Managed trial"
msgstr ""
+msgid "InProductMarketing|Start a free trial"
+msgstr ""
+
msgid "InProductMarketing|Start a free trial of GitLab Ultimate – no credit card required"
msgstr ""
@@ -18536,6 +18939,9 @@ msgstr ""
msgid "InProductMarketing|To understand and get the most out of GitLab, start at the beginning and %{project_link}. In GitLab, repositories are part of a project, so after you've created your project you can go ahead and %{repo_link}."
msgstr ""
+msgid "InProductMarketing|Track completed issues in a chart, so you can see how a milestone is progressing at a glance."
+msgstr ""
+
msgid "InProductMarketing|Try GitLab Ultimate for free"
msgstr ""
@@ -18572,6 +18978,9 @@ msgstr ""
msgid "InProductMarketing|Very easy"
msgstr ""
+msgid "InProductMarketing|Visualize your epics and milestones in a timeline."
+msgstr ""
+
msgid "InProductMarketing|Want to host GitLab on your servers?"
msgstr ""
@@ -18593,6 +19002,9 @@ msgstr ""
msgid "InProductMarketing|YouTube"
msgstr ""
+msgid "InProductMarketing|Your software, deployed your way"
+msgstr ""
+
msgid "InProductMarketing|Your teams can be more efficient"
msgstr ""
@@ -18713,9 +19125,18 @@ msgstr ""
msgid "IncidentManagement|No incidents to display."
msgstr ""
+msgid "IncidentManagement|None"
+msgstr ""
+
msgid "IncidentManagement|Open"
msgstr ""
+msgid "IncidentManagement|Page your team with escalation policies"
+msgstr ""
+
+msgid "IncidentManagement|Paged"
+msgstr ""
+
msgid "IncidentManagement|Published"
msgstr ""
@@ -18725,6 +19146,9 @@ msgstr ""
msgid "IncidentManagement|Severity"
msgstr ""
+msgid "IncidentManagement|Status"
+msgstr ""
+
msgid "IncidentManagement|There are no closed incidents"
msgstr ""
@@ -18743,6 +19167,9 @@ msgstr ""
msgid "IncidentManagement|Unpublished"
msgstr ""
+msgid "IncidentManagement|Use escalation policies to automatically page your team when incidents are created."
+msgstr ""
+
msgid "IncidentSettings|Activate \"time to SLA\" countdown timer"
msgstr ""
@@ -18788,7 +19215,10 @@ msgstr ""
msgid "Incidents"
msgstr ""
-msgid "Incidents|Add a URL"
+msgid "Incidents|Add image details"
+msgstr ""
+
+msgid "Incidents|Add text or a link to display with your image. If you don't add either, the file name displays instead."
msgstr ""
msgid "Incidents|Drop or %{linkStart}upload%{linkEnd} a metric screenshot to attach it to the incident"
@@ -18803,10 +19233,10 @@ msgstr ""
msgid "Incidents|There was an issue loading metric images."
msgstr ""
-msgid "Incidents|There was an issue uploading your image."
+msgid "Incidents|There was an issue updating your image."
msgstr ""
-msgid "Incidents|You can optionally add a URL to link users to the original graph."
+msgid "Incidents|There was an issue uploading your image."
msgstr ""
msgid "Incident|Alert details"
@@ -18815,9 +19245,18 @@ msgstr ""
msgid "Incident|Are you sure you wish to delete this image?"
msgstr ""
+msgid "Incident|Delete image"
+msgstr ""
+
msgid "Incident|Deleting %{filename}"
msgstr ""
+msgid "Incident|Edit image text or link"
+msgstr ""
+
+msgid "Incident|Editing %{filename}"
+msgstr ""
+
msgid "Incident|Metrics"
msgstr ""
@@ -19086,12 +19525,18 @@ msgstr ""
msgid "Integrations|Branches for which notifications are to be sent"
msgstr ""
+msgid "Integrations|Clear if using a self-signed certificate."
+msgstr ""
+
msgid "Integrations|Comment detail:"
msgstr ""
msgid "Integrations|Comment settings:"
msgstr ""
+msgid "Integrations|Connection details"
+msgstr ""
+
msgid "Integrations|Connection failed. Please check your settings."
msgstr ""
@@ -19116,6 +19561,9 @@ msgstr ""
msgid "Integrations|Enable GitLab.com slash commands in a Slack workspace."
msgstr ""
+msgid "Integrations|Enable SSL verification"
+msgstr ""
+
msgid "Integrations|Enable comments"
msgstr ""
@@ -19194,6 +19642,9 @@ msgstr ""
msgid "Integrations|Return to GitLab for Jira"
msgstr ""
+msgid "Integrations|SSL verification"
+msgstr ""
+
msgid "Integrations|Save settings?"
msgstr ""
@@ -19239,9 +19690,6 @@ msgstr ""
msgid "Integrations|Use default settings"
msgstr ""
-msgid "Integrations|When you mention a Jira issue in a commit or merge request, GitLab creates a remote link and comment (if enabled)."
-msgstr ""
-
msgid "Integrations|You can now close this window and return to the GitLab for Jira application."
msgstr ""
@@ -19266,9 +19714,6 @@ msgstr ""
msgid "Integrations|can't exceed %{recipients_limit}"
msgstr ""
-msgid "Interactive developer security education."
-msgstr ""
-
msgid "Interactive mode"
msgstr ""
@@ -19758,6 +20203,9 @@ msgstr ""
msgid "IssueAnalytics|Assignees"
msgstr ""
+msgid "IssueAnalytics|Created by"
+msgstr ""
+
msgid "IssueAnalytics|Due date"
msgstr ""
@@ -19770,9 +20218,6 @@ msgstr ""
msgid "IssueAnalytics|Milestone"
msgstr ""
-msgid "IssueAnalytics|Opened by"
-msgstr ""
-
msgid "IssueAnalytics|Status"
msgstr ""
@@ -19896,10 +20341,10 @@ msgstr ""
msgid "IssuesAnalytics|Avg/Month:"
msgstr ""
-msgid "IssuesAnalytics|Issues opened"
+msgid "IssuesAnalytics|Issues created"
msgstr ""
-msgid "IssuesAnalytics|Issues opened per month"
+msgid "IssuesAnalytics|Issues created per month"
msgstr ""
msgid "IssuesAnalytics|Last 12 months"
@@ -19926,6 +20371,9 @@ msgstr ""
msgid "It looks like you have some draft commits in this branch."
msgstr ""
+msgid "It looks like you're attempting to activate your subscription. Use %{a_start}the Subscription page%{a_end} instead."
+msgstr ""
+
msgid "It may be several days before you see feature usage data."
msgstr ""
@@ -20154,6 +20602,9 @@ msgstr ""
msgid "JiraConnect|You can now close this window and return to Jira."
msgstr ""
+msgid "JiraConnect|You don't have permission to create branches for this project. Select a different project or contact the project owner for access. %{linkStart}Learn more.%{linkEnd}"
+msgstr ""
+
msgid "JiraRequest|A connection error occurred while connecting to Jira. Try your request again."
msgstr ""
@@ -20202,13 +20653,13 @@ msgstr ""
msgid "JiraService|Define the type of Jira issue to create from a vulnerability."
msgstr ""
-msgid "JiraService|Displaying Jira issues while leaving the GitLab issue functionality enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
+msgid "JiraService|Displaying Jira issues while leaving GitLab issues also enabled might be confusing. Consider %{linkStart}disabling GitLab issues%{linkEnd} if they won’t otherwise be used."
msgstr ""
-msgid "JiraService|Enable Jira issues"
+msgid "JiraService|Enable Jira issue creation from vulnerabilities"
msgstr ""
-msgid "JiraService|Enable Jira issues creation from vulnerabilities"
+msgid "JiraService|Enable Jira issues"
msgstr ""
msgid "JiraService|Enable Jira transitions"
@@ -20325,16 +20776,19 @@ msgstr ""
msgid "JiraService|View Jira issues in GitLab"
msgstr ""
-msgid "JiraService|Warning: All GitLab users that have access to this GitLab project are able to view all issues from the Jira project specified below."
+msgid "JiraService|Warning: All GitLab users with access to this GitLab project can view all issues from the Jira project you select."
msgstr ""
msgid "JiraService|Web URL"
msgstr ""
-msgid "JiraService|Work on Jira issues without leaving GitLab. Adds a Jira menu to access your list of Jira issues and view any issue as read-only."
+msgid "JiraService|When a Jira issue is mentioned in a commit or merge request, a remote link and comment (if enabled) will be created."
msgstr ""
-msgid "JiraService|You need to configure Jira before enabling this integration. For more details, read the %{jira_doc_link_start}Jira integration documentation%{link_end}."
+msgid "JiraService|Work on Jira issues without leaving GitLab. Add a Jira menu to access a read-only list of your Jira issues."
+msgstr ""
+
+msgid "JiraService|You must configure Jira before enabling this integration. %{jira_doc_link_start}Learn more.%{link_end}"
msgstr ""
msgid "Job"
@@ -20346,9 +20800,6 @@ msgstr ""
msgid "Job Failed #%{build_id}"
msgstr ""
-msgid "Job ID"
-msgstr ""
-
msgid "Job artifact"
msgstr ""
@@ -20415,9 +20866,27 @@ msgstr ""
msgid "Jobs|You're about to retry a job that failed because it attempted to deploy code that is older than the latest deployment. Retrying this job could result in overwriting the environment with the older source code."
msgstr ""
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{mrId} with %{source} into %{target}"
+msgstr ""
+
+msgid "Job|%{boldStart}Pipeline%{boldEnd} %{id} for %{ref}"
+msgstr ""
+
+msgid "Job|Are you sure you want to erase this job log and artifacts?"
+msgstr ""
+
msgid "Job|Browse"
msgstr ""
+msgid "Job|Cancel"
+msgstr ""
+
msgid "Job|Complete Raw"
msgstr ""
@@ -20427,6 +20896,9 @@ msgstr ""
msgid "Job|Erase job log and artifacts"
msgstr ""
+msgid "Job|Finished at"
+msgstr ""
+
msgid "Job|Job artifacts"
msgstr ""
@@ -20439,7 +20911,7 @@ msgstr ""
msgid "Job|Keep"
msgstr ""
-msgid "Job|Pipeline"
+msgid "Job|Retry"
msgstr ""
msgid "Job|Scroll to bottom"
@@ -20451,6 +20923,9 @@ msgstr ""
msgid "Job|Show complete raw"
msgstr ""
+msgid "Job|Status"
+msgstr ""
+
msgid "Job|The artifacts were removed"
msgstr ""
@@ -20478,21 +20953,12 @@ msgstr ""
msgid "Job|delayed"
msgstr ""
-msgid "Job|for"
-msgstr ""
-
-msgid "Job|into"
-msgstr ""
-
msgid "Job|manual"
msgstr ""
msgid "Job|triggered"
msgstr ""
-msgid "Job|with"
-msgstr ""
-
msgid "Join Zoom meeting"
msgstr ""
@@ -20595,9 +21061,6 @@ msgstr ""
msgid "Ki"
msgstr ""
-msgid "Kontra"
-msgstr ""
-
msgid "Kroki"
msgstr ""
@@ -20920,6 +21383,9 @@ msgstr ""
msgid "Learn more about Auto DevOps"
msgstr ""
+msgid "Learn more about GitLab"
+msgstr ""
+
msgid "Learn more about Needs relationships"
msgstr ""
@@ -21241,9 +21707,18 @@ msgstr ""
msgid "Licenses|Displays licenses detected in the project, based on the %{linkStart}latest successful%{linkEnd} scan"
msgstr ""
+msgid "Licenses|Drag your license file here or %{linkStart}click to upload%{linkEnd}."
+msgstr ""
+
+msgid "Licenses|Drop your license file to start the upload."
+msgstr ""
+
msgid "Licenses|Error fetching the license list. Please check your network connection and try again."
msgstr ""
+msgid "Licenses|Error: You are trying to upload something other than a file"
+msgstr ""
+
msgid "Licenses|License Compliance"
msgstr ""
@@ -21262,6 +21737,9 @@ msgstr ""
msgid "Licenses|Specified policies in this project"
msgstr ""
+msgid "Licenses|The file could not be uploaded."
+msgstr ""
+
msgid "Licenses|The license list details information about the licenses used within your project."
msgstr ""
@@ -21295,10 +21773,6 @@ msgstr ""
msgid "Limit the size of Sidekiq jobs stored in Redis."
msgstr ""
-msgid "Limited to showing %d event at most"
-msgid_plural "Limited to showing %d events at most"
-msgstr[0] ""
-
msgid "Limiting mode"
msgstr ""
@@ -21308,6 +21782,9 @@ msgstr ""
msgid "Link"
msgstr ""
+msgid "Link (optional)"
+msgstr ""
+
msgid "Link Prometheus monitoring to GitLab."
msgstr ""
@@ -21344,6 +21821,9 @@ msgstr ""
msgid "Linked emails (%{email_count})"
msgstr ""
+msgid "Linked epics"
+msgstr ""
+
msgid "Linked issues"
msgstr ""
@@ -21371,6 +21851,15 @@ msgstr ""
msgid "List of all merge commits"
msgstr ""
+msgid "List of environments for this project"
+msgstr ""
+
+msgid "List of suitable GCP locations"
+msgstr ""
+
+msgid "List of users allowed to exceed the rate limit."
+msgstr ""
+
msgid "List options"
msgstr ""
@@ -21590,6 +22079,9 @@ msgstr ""
msgid "Maintenance mode"
msgstr ""
+msgid "Make adjustments to how your GitLab instance is set up."
+msgstr ""
+
msgid "Make and review changes in the browser with the Web IDE"
msgstr ""
@@ -21734,6 +22226,12 @@ msgstr ""
msgid "MarkdownEditor|Add italic text (%{modifier_key}I)"
msgstr ""
+msgid "MarkdownEditor|Add strikethrough text (%{modifierKey}⇧X)"
+msgstr ""
+
+msgid "MarkdownEditor|Add strikethrough text (%{modifier_key}⇧X)"
+msgstr ""
+
msgid "Marked For Deletion At - %{deletion_time}"
msgstr ""
@@ -21995,6 +22493,9 @@ msgstr ""
msgid "Maximum push size (MB)"
msgstr ""
+msgid "Maximum requests per 10 minutes per user"
+msgstr ""
+
msgid "Maximum requests per minute"
msgstr ""
@@ -22085,6 +22586,17 @@ msgstr ""
msgid "Members of a group may only view projects they have permission to access"
msgstr ""
+msgid "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seat in use and will be billed for the overage."
+msgid_plural "MembersOverage|If you continue, the %{groupName} group will have %{quantity} seats in use and will be billed for the overage."
+msgstr[0] ""
+
+msgid "MembersOverage|You are about to incur additional charges"
+msgstr ""
+
+msgid "MembersOverage|Your subscription includes %d seat."
+msgid_plural "MembersOverage|Your subscription includes %d seats."
+msgstr[0] ""
+
msgid "Membership"
msgstr ""
@@ -22289,9 +22801,6 @@ msgstr ""
msgid "Merge request not merged"
msgstr ""
-msgid "Merge request pipelines 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 merge request pipelines."
-msgstr ""
-
msgid "Merge request reports"
msgstr ""
@@ -22388,13 +22897,13 @@ msgstr ""
msgid "MergeRequests|Create issue to resolve thread"
msgstr ""
-msgid "MergeRequests|Failed to squash. Should be done manually."
+msgid "MergeRequests|Saving the comment failed"
msgstr ""
-msgid "MergeRequests|Saving the comment failed"
+msgid "MergeRequests|Squashing failed: Squash the commits locally, resolve any conflicts, then push the branch."
msgstr ""
-msgid "MergeRequests|This project does not allow squashing commits when merge requests are accepted."
+msgid "MergeRequests|Squashing not allowed: This project doesn't allow you to squash commits when merging."
msgstr ""
msgid "MergeRequests|Thread stays resolved"
@@ -23233,6 +23742,18 @@ msgstr ""
msgid "MrDeploymentActions|Stop environment"
msgstr ""
+msgid "MrList|Assigned to %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from assignee %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Attention requested from reviewer %{name}, go to their profile."
+msgstr ""
+
+msgid "MrList|Review requested from %{name}, go to their profile."
+msgstr ""
+
msgid "Multi-project"
msgstr ""
@@ -23266,7 +23787,7 @@ msgstr ""
msgid "Must match with the %{codeStart}geo_node_name%{codeEnd} in %{codeStart}/etc/gitlab/gitlab.rb%{codeEnd}. %{linkStart}Learn more%{linkEnd}"
msgstr ""
-msgid "My Awesome Group"
+msgid "My awesome group"
msgstr ""
msgid "My company or team"
@@ -23886,9 +24407,6 @@ msgstr ""
msgid "No available branches"
msgstr ""
-msgid "No available groups to fork the project."
-msgstr ""
-
msgid "No branches found"
msgstr ""
@@ -24099,6 +24617,9 @@ msgstr ""
msgid "No ref selected"
msgstr ""
+msgid "No regions configured"
+msgstr ""
+
msgid "No related merge requests found."
msgstr ""
@@ -24897,6 +25418,9 @@ msgstr ""
msgid "Only reCAPTCHA v2 is supported:"
msgstr ""
+msgid "Only required if not using role instance credentials."
+msgstr ""
+
msgid "Only use lowercase letters, numbers, and underscores."
msgstr ""
@@ -24921,9 +25445,6 @@ msgstr ""
msgid "Open a CLI and connect to the cluster you want to install the agent in. Use this installation method to minimize any manual steps. The token is already included in the command."
msgstr ""
-msgid "Open epics"
-msgstr ""
-
msgid "Open errors"
msgstr ""
@@ -24963,7 +25484,7 @@ msgstr ""
msgid "Opened issues"
msgstr ""
-msgid "OpenedNDaysAgo|Opened"
+msgid "OpenedNDaysAgo|Created"
msgstr ""
msgid "Opens in a new window"
@@ -25008,9 +25529,6 @@ msgstr ""
msgid "Optional parameter \"variables\" must be a Hash. Ex: variables[key1]=value1"
msgstr ""
-msgid "Optional."
-msgstr ""
-
msgid "Optionally, you can %{link_to_customize} how FogBugz email addresses and usernames are imported into GitLab."
msgstr ""
@@ -25798,6 +26316,9 @@ msgstr ""
msgid "PerformanceBar|Memory"
msgstr ""
+msgid "PerformanceBar|Memory report"
+msgstr ""
+
msgid "PerformanceBar|Redis calls"
msgstr ""
@@ -25831,18 +26352,12 @@ msgstr ""
msgid "PerformanceBar|wall"
msgstr ""
-msgid "Performs a rebase but skips triggering a new pipeline"
-msgstr ""
-
msgid "Period in seconds"
msgstr ""
msgid "Permalink"
msgstr ""
-msgid "Permanently delete project"
-msgstr ""
-
msgid "Permanently remove group"
msgstr ""
@@ -26113,6 +26628,51 @@ msgstr ""
msgid "PipelineStatusTooltip|Pipeline: %{ci_status}"
msgstr ""
+msgid "PipelineWizardDefaultCommitMessage|Add %{filename}"
+msgstr ""
+
+msgid "PipelineWizardDefaultCommitMessage|Update %{filename}"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|At least one entry is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This field is required"
+msgstr ""
+
+msgid "PipelineWizardInputValidation|This value is not valid"
+msgstr ""
+
+msgid "PipelineWizardListWidget|add another step"
+msgstr ""
+
+msgid "PipelineWizardListWidget|remove step"
+msgstr ""
+
+msgid "PipelineWizard|Commit"
+msgstr ""
+
+msgid "PipelineWizard|Commit Message"
+msgstr ""
+
+msgid "PipelineWizard|Commit changes to your file"
+msgstr ""
+
+msgid "PipelineWizard|Commit file to Branch"
+msgstr ""
+
+msgid "PipelineWizard|Commit your new file"
+msgstr ""
+
+msgid "PipelineWizard|The file has been committed."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem committing the changes."
+msgstr ""
+
+msgid "PipelineWizard|There was a problem while checking whether your file already exists in the specified branch."
+msgstr ""
+
msgid "Pipelines"
msgstr ""
@@ -26227,7 +26787,7 @@ msgstr ""
msgid "Pipelines|Project cache successfully reset."
msgstr ""
-msgid "Pipelines|Revoke"
+msgid "Pipelines|Revoke trigger"
msgstr ""
msgid "Pipelines|Something went wrong while cleaning runners cache."
@@ -26272,6 +26832,12 @@ msgstr ""
msgid "Pipelines|This is a child pipeline within the parent pipeline"
msgstr ""
+msgid "Pipelines|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipelines|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipelines|This pipeline will run code originating from a forked project merge request. This means that the code can potentially have security considerations like exposing CI variables."
msgstr ""
@@ -26314,9 +26880,6 @@ msgstr ""
msgid "Pipelines|Your changes have been successfully committed. Now redirecting to the new merge request page."
msgstr ""
-msgid "Pipelines|detached"
-msgstr ""
-
msgid "Pipelines|error"
msgstr ""
@@ -26326,10 +26889,13 @@ msgstr ""
msgid "Pipelines|latest"
msgstr ""
-msgid "Pipelines|stuck"
+msgid "Pipelines|merge request"
msgstr ""
-msgid "Pipelines|train"
+msgid "Pipelines|merge train"
+msgstr ""
+
+msgid "Pipelines|stuck"
msgstr ""
msgid "Pipelines|yaml invalid"
@@ -26461,6 +27027,12 @@ msgstr ""
msgid "Pipeline|This change will not change the overall test coverage if merged."
msgstr ""
+msgid "Pipeline|This pipeline ran on the contents of this merge request combined with the contents of all other merge requests queued for merging into the target branch."
+msgstr ""
+
+msgid "Pipeline|This pipeline ran on the contents of this merge request's source branch, not the target branch."
+msgstr ""
+
msgid "Pipeline|Trigger author"
msgstr ""
@@ -26485,6 +27057,12 @@ msgstr ""
msgid "Pipeline|for"
msgstr ""
+msgid "Pipeline|merge request"
+msgstr ""
+
+msgid "Pipeline|merge train"
+msgstr ""
+
msgid "Pipeline|on"
msgstr ""
@@ -26623,9 +27201,6 @@ msgstr ""
msgid "Please enter a valid time interval"
msgstr ""
-msgid "Please enter or upload a valid license."
-msgstr ""
-
msgid "Please enter your current password."
msgstr ""
@@ -26734,9 +27309,6 @@ msgstr ""
msgid "Please type %{phrase_code} to proceed or close this modal to cancel."
msgstr ""
-msgid "Please type the following to confirm:"
-msgstr ""
-
msgid "Please use this form to report to the admin users who create spam issues, comments or behave inappropriately."
msgstr ""
@@ -26764,12 +27336,27 @@ msgstr ""
msgid "Policies"
msgstr ""
+msgid "Policy '%{escalation_policy_name}' does not exist."
+msgstr ""
+
msgid "Policy management project does have any policies in %{policy_path}"
msgstr ""
msgid "Policy project doesn't exist"
msgstr ""
+msgid "PolicyRuleMultiSelect|%{firstLabel} +%{numberOfAdditionalLabels} more"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|All %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select %{itemTypeName}"
+msgstr ""
+
+msgid "PolicyRuleMultiSelect|Select all"
+msgstr ""
+
msgid "Polling interval multiplier"
msgstr ""
@@ -26998,6 +27585,9 @@ msgstr ""
msgid "Private projects can be created in your personal namespace with:"
msgstr ""
+msgid "Problem with %{name} command: %{message}."
+msgstr ""
+
msgid "Proceed"
msgstr ""
@@ -27472,6 +28062,9 @@ msgstr ""
msgid "Progress"
msgstr ""
+msgid "Progress tracking"
+msgstr ""
+
msgid "Project"
msgstr ""
@@ -27703,6 +28296,9 @@ msgstr ""
msgid "ProjectQualitySummary|Failure"
msgstr ""
+msgid "ProjectQualitySummary|Get insight into the overall percentage of tests in your project that succeed, fail and are skipped."
+msgstr ""
+
msgid "ProjectQualitySummary|Latest pipeline results"
msgstr ""
@@ -27721,6 +28317,12 @@ msgstr ""
msgid "ProjectQualitySummary|See project Code Coverage Statistics"
msgstr ""
+msgid "ProjectQualitySummary|Set up test runs"
+msgstr ""
+
+msgid "ProjectQualitySummary|Set up test runs (opens in a new tab)"
+msgstr ""
+
msgid "ProjectQualitySummary|Skipped"
msgstr ""
@@ -27997,13 +28599,19 @@ msgstr ""
msgid "ProjectSettings|LFS objects from this repository are available to forks. %{linkStart}How do I remove them?%{linkEnd}"
msgstr ""
+msgid "ProjectSettings|Learn about commit history."
+msgstr ""
+
+msgid "ProjectSettings|Leave empty to use default template."
+msgstr ""
+
msgid "ProjectSettings|Manage who can see the project in the public access directory."
msgstr ""
msgid "ProjectSettings|Manages large files such as audio, video, and graphics files."
msgstr ""
-msgid "ProjectSettings|Maximum 500 characters."
+msgid "ProjectSettings|Maximum %{maxLength} characters."
msgstr ""
msgid "ProjectSettings|Merge checks"
@@ -28144,6 +28752,9 @@ msgstr ""
msgid "ProjectSettings|The default target project for merge requests created in this fork project."
msgstr ""
+msgid "ProjectSettings|The default template will be applied on save."
+msgstr ""
+
msgid "ProjectSettings|These checks must pass before merge requests can be merged."
msgstr ""
@@ -28198,6 +28809,9 @@ msgstr ""
msgid "ProjectSettings|What are badges?"
msgstr ""
+msgid "ProjectSettings|What are merge trains?"
+msgstr ""
+
msgid "ProjectSettings|When merge request pipelines are enabled in the CI/CD configuration file, pipelines validate the combined results of the source and target branches. %{link_start}How to configure merge request pipelines?%{link_end}"
msgstr ""
@@ -28315,6 +28929,9 @@ msgstr ""
msgid "Projects are organized into groups"
msgstr ""
+msgid "Projects are where you store your code, access issues, wiki and other features of GitLab."
+msgstr ""
+
msgid "Projects contributed to"
msgstr ""
@@ -28330,12 +28947,6 @@ msgstr ""
msgid "Projects to index"
msgstr ""
-msgid "Projects will be permanently deleted after a %{waiting_period}-day waiting period."
-msgstr ""
-
-msgid "Projects will be permanently deleted immediately."
-msgstr ""
-
msgid "Projects with critical vulnerabilities"
msgstr ""
@@ -28420,6 +29031,9 @@ msgstr ""
msgid "ProjectsNew|Import project"
msgstr ""
+msgid "ProjectsNew|Include a Getting Started README"
+msgstr ""
+
msgid "ProjectsNew|Initialize repository with a README"
msgstr ""
@@ -28435,6 +29049,9 @@ msgstr ""
msgid "ProjectsNew|Project description %{tag_start}(optional)%{tag_end}"
msgstr ""
+msgid "ProjectsNew|Recommended if you're new to GitLab"
+msgstr ""
+
msgid "ProjectsNew|Run CI/CD for external repository"
msgstr ""
@@ -28852,6 +29469,9 @@ msgstr ""
msgid "ProtectedBranch|Unprotect"
msgstr ""
+msgid "ProtectedBranch|Unprotect branch"
+msgstr ""
+
msgid "ProtectedBranch|What are protected branches?"
msgstr ""
@@ -28879,6 +29499,9 @@ msgstr ""
msgid "ProtectedEnvironment|Protected Environment (%{protected_environments_count})"
msgstr ""
+msgid "ProtectedEnvironment|Required approvals"
+msgstr ""
+
msgid "ProtectedEnvironment|Select an environment"
msgstr ""
@@ -28900,10 +29523,13 @@ msgstr ""
msgid "ProtectedEnvironment|Your environment has been unprotected"
msgstr ""
+msgid "ProtectedTags|Unprotect tag"
+msgstr ""
+
msgid "ProtectedTags|default"
msgstr ""
-msgid "ProtectedTag|By default, protected branches restrict who can modify the tag."
+msgid "ProtectedTag|By default, protected tags restrict who can modify the tag."
msgstr ""
msgid "ProtectedTag|Learn more."
@@ -28966,6 +29592,9 @@ msgstr ""
msgid "Public projects Minutes cost factor"
msgstr ""
+msgid "Public projects are an easy way to allow everyone to have read-only access."
+msgstr ""
+
msgid "Publish to status page"
msgstr ""
@@ -29122,9 +29751,6 @@ msgstr ""
msgid "QualitySummary|Project quality"
msgstr ""
-msgid "Quarters"
-msgstr ""
-
msgid "Query"
msgstr ""
@@ -29209,6 +29835,9 @@ msgstr ""
msgid "Read more about project permissions %{help_link_open}here%{help_link_close}"
msgstr ""
+msgid "Read more about related epics"
+msgstr ""
+
msgid "Read more about related issues"
msgstr ""
@@ -29239,10 +29868,7 @@ msgstr ""
msgid "Rebase source branch on the target branch."
msgstr ""
-msgid "Rebase without CI"
-msgstr ""
-
-msgid "Rebases and triggers a pipeline"
+msgid "Rebase without pipeline"
msgstr ""
msgid "Recaptcha verified?"
@@ -29293,9 +29919,6 @@ msgstr ""
msgid "Reconfigure"
msgstr ""
-msgid "Recovering projects"
-msgstr ""
-
msgid "Recovery Codes"
msgstr ""
@@ -29354,6 +29977,12 @@ msgstr ""
msgid "Regex pattern"
msgstr ""
+msgid "Region"
+msgstr ""
+
+msgid "Regions"
+msgstr ""
+
msgid "Register"
msgstr ""
@@ -29583,9 +30212,6 @@ msgstr ""
msgid "Remove all or specific reviewer(s)"
msgstr ""
-msgid "Remove approver"
-msgstr ""
-
msgid "Remove approvers"
msgstr ""
@@ -29601,6 +30227,9 @@ msgstr ""
msgid "Remove attention request"
msgstr ""
+msgid "Remove attention request(s)"
+msgstr ""
+
msgid "Remove avatar"
msgstr ""
@@ -29739,6 +30368,9 @@ msgstr ""
msgid "Removed an issue from an epic."
msgstr ""
+msgid "Removed attention from %{users_sentence}."
+msgstr ""
+
msgid "Removed attention request from @%{username}"
msgstr ""
@@ -29790,6 +30422,9 @@ msgstr ""
msgid "Removes an issue from an epic."
msgstr ""
+msgid "Removes attention from %{users_sentence}."
+msgstr ""
+
msgid "Removes parent epic %{epic_ref}."
msgstr ""
@@ -29901,6 +30536,9 @@ msgstr ""
msgid "Report abuse to admin"
msgstr ""
+msgid "Report is generating and will be sent to your email address."
+msgstr ""
+
msgid "Reported %{timeAgo} by %{reportedBy}"
msgstr ""
@@ -30185,6 +30823,15 @@ msgstr ""
msgid "Request attention"
msgstr ""
+msgid "Request attention from %{users_sentence}."
+msgstr ""
+
+msgid "Request attention from assignee or reviewer"
+msgstr ""
+
+msgid "Request attention from assignee(s) or reviewer(s)"
+msgstr ""
+
msgid "Request attention to review"
msgstr ""
@@ -30209,6 +30856,9 @@ msgstr ""
msgid "Requested %{time_ago}"
msgstr ""
+msgid "Requested attention from %{users_sentence}."
+msgstr ""
+
msgid "Requested attention from @%{username}"
msgstr ""
@@ -30421,6 +31071,9 @@ msgstr ""
msgid "Restore project"
msgstr ""
+msgid "Restoring projects"
+msgstr ""
+
msgid "Restoring the group will prevent the group, its subgroups and projects from being removed on this date."
msgstr ""
@@ -30451,6 +31104,9 @@ msgstr ""
msgid "Retry"
msgstr ""
+msgid "Retry failed jobs"
+msgstr ""
+
msgid "Retry job"
msgstr ""
@@ -30497,9 +31153,6 @@ msgstr ""
msgid "Review changes"
msgstr ""
-msgid "Review requested from %{name}"
-msgstr ""
-
msgid "Review requests for you"
msgstr ""
@@ -30663,6 +31316,9 @@ msgstr ""
msgid "Runners|Assigned Group"
msgstr ""
+msgid "Runners|Assigned Projects (%{projectCount})"
+msgstr ""
+
msgid "Runners|Associated with one or more projects"
msgstr ""
@@ -30732,6 +31388,9 @@ msgstr ""
msgid "Runners|Instance"
msgstr ""
+msgid "Runners|Jobs"
+msgstr ""
+
msgid "Runners|Last contact"
msgstr ""
@@ -30825,9 +31484,6 @@ msgstr ""
msgid "Runners|Runner %{name} was deleted"
msgstr ""
-msgid "Runners|Runner ID"
-msgstr ""
-
msgid "Runners|Runner assigned to project."
msgstr ""
@@ -30975,6 +31631,9 @@ msgstr ""
msgid "Runners|stale"
msgstr ""
+msgid "Runner|This runner has not run any jobs."
+msgstr ""
+
msgid "Running"
msgstr ""
@@ -31089,6 +31748,24 @@ msgstr ""
msgid "Saving project."
msgstr ""
+msgid "ScanResultPolicy|%{ifLabelStart}if%{ifLabelEnd} %{scanners} scan in an open merge request targeting the %{branches} branch(es) finds %{vulnerabilitiesAllowed} or more %{severities} vulnerabilities that are %{vulnerabilityStates}"
+msgstr ""
+
+msgid "ScanResultPolicy|%{thenLabelStart}Then%{thenLabelEnd} Require approval from %{approvalsRequired} of the following approvers: %{approvers}"
+msgstr ""
+
+msgid "ScanResultPolicy|add an approver"
+msgstr ""
+
+msgid "ScanResultPolicy|scanners"
+msgstr ""
+
+msgid "ScanResultPolicy|severity levels"
+msgstr ""
+
+msgid "ScanResultPolicy|vulnerability states"
+msgstr ""
+
msgid "Scanner"
msgstr ""
@@ -31221,6 +31898,9 @@ msgstr ""
msgid "Search for a user"
msgstr ""
+msgid "Search for an emoji"
+msgstr ""
+
msgid "Search for projects, issues, etc."
msgstr ""
@@ -31397,18 +32077,12 @@ msgstr ""
msgid "Secret Detection"
msgstr ""
-msgid "Secret access key"
-msgstr ""
-
msgid "Secret token"
msgstr ""
msgid "Secure token that identifies an external storage request."
msgstr ""
-msgid "SecureCodeWarrior"
-msgstr ""
-
msgid "Security"
msgstr ""
@@ -31433,9 +32107,6 @@ msgstr ""
msgid "Security report is out of date. Run %{newPipelineLinkStart}a new pipeline%{newPipelineLinkEnd} for the target branch (%{targetBranchName})"
msgstr ""
-msgid "Security training with guide and learning pathways."
-msgstr ""
-
msgid "SecurityApprovals|A merge request approval is required when a security report contains a new vulnerability."
msgstr ""
@@ -31538,7 +32209,7 @@ msgstr ""
msgid "SecurityConfiguration|Manage corpus"
msgstr ""
-msgid "SecurityConfiguration|Manage corpus files used as mutation sources in coverage fuzzing."
+msgid "SecurityConfiguration|Manage corpus files used as seed inputs with coverage-guided fuzzing."
msgstr ""
msgid "SecurityConfiguration|Manage profiles for use by DAST scans."
@@ -31604,15 +32275,15 @@ msgstr ""
msgid "SecurityOrchestration|.yaml preview"
msgstr ""
-msgid "SecurityOrchestration|Action"
-msgstr ""
-
msgid "SecurityOrchestration|Actions"
msgstr ""
msgid "SecurityOrchestration|Add rule"
msgstr ""
+msgid "SecurityOrchestration|After dismissing the alert, the information will never be shown again."
+msgstr ""
+
msgid "SecurityOrchestration|All policies"
msgstr ""
@@ -31628,7 +32299,7 @@ msgstr ""
msgid "SecurityOrchestration|Description"
msgstr ""
-msgid "SecurityOrchestration|Disabled"
+msgid "SecurityOrchestration|Don't show the alert anymore"
msgstr ""
msgid "SecurityOrchestration|Edit policy"
@@ -31637,13 +32308,13 @@ msgstr ""
msgid "SecurityOrchestration|Edit policy project"
msgstr ""
-msgid "SecurityOrchestration|Enabled"
+msgid "SecurityOrchestration|Empty policy name"
msgstr ""
-msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
+msgid "SecurityOrchestration|Enabled"
msgstr ""
-msgid "SecurityOrchestration|Executes a %{scanType} scan"
+msgid "SecurityOrchestration|Enforce security for this project. %{linkStart}More information.%{linkEnd}"
msgstr ""
msgid "SecurityOrchestration|If you are using Auto DevOps, your %{monospacedStart}auto-deploy-values.yaml%{monospacedEnd} file will not be updated if you change a policy in this section. Auto DevOps users should make changes by following the %{linkStart}Container Network Policy documentation%{linkEnd}."
@@ -31652,7 +32323,7 @@ msgstr ""
msgid "SecurityOrchestration|Invalid policy type"
msgstr ""
-msgid "SecurityOrchestration|Latest scan"
+msgid "SecurityOrchestration|Latest scan run against %{agent}"
msgstr ""
msgid "SecurityOrchestration|Network"
@@ -31661,15 +32332,27 @@ msgstr ""
msgid "SecurityOrchestration|New policy"
msgstr ""
+msgid "SecurityOrchestration|No actions defined - policy will not run."
+msgstr ""
+
+msgid "SecurityOrchestration|No description"
+msgstr ""
+
msgid "SecurityOrchestration|No rules defined - policy will not run."
msgstr ""
+msgid "SecurityOrchestration|Not enabled"
+msgstr ""
+
msgid "SecurityOrchestration|Only owners can update Security Policy Project"
msgstr ""
msgid "SecurityOrchestration|Policies"
msgstr ""
+msgid "SecurityOrchestration|Policy Type"
+msgstr ""
+
msgid "SecurityOrchestration|Policy cannot be enabled for non-existing branches (%{branches})"
msgstr ""
@@ -31694,10 +32377,13 @@ msgstr ""
msgid "SecurityOrchestration|Require %{approvals} %{plural} from %{approvers} if any of the following occur:"
msgstr ""
-msgid "SecurityOrchestration|Rule"
+msgid "SecurityOrchestration|Rules"
msgstr ""
-msgid "SecurityOrchestration|Rules"
+msgid "SecurityOrchestration|Runs %{actions} and %{lastAction} scans"
+msgstr ""
+
+msgid "SecurityOrchestration|Runs a %{action} scan"
msgstr ""
msgid "SecurityOrchestration|Scan Execution"
@@ -31757,6 +32443,9 @@ msgstr ""
msgid "SecurityOrchestration|This project does not contain any security policies."
msgstr ""
+msgid "SecurityOrchestration|This view only shows scan results for the agent %{agent}. You can view scan results for all agents in the %{linkStart}Operational Vulnerabilities tab of the vulnerability report%{linkEnd}."
+msgstr ""
+
msgid "SecurityOrchestration|To widen your search, change filters above or select a different security policy project."
msgstr ""
@@ -31811,9 +32500,6 @@ msgstr ""
msgid "SecurityOrchestration|users with ids"
msgstr ""
-msgid "SecurityOrchestration|view results"
-msgstr ""
-
msgid "SecurityOrchestration|vulnerabilities"
msgstr ""
@@ -32483,22 +33169,19 @@ 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|In order to start using functions as a service, you must first install Knative on your Kubernetes cluster. %{linkStart}More information%{linkEnd}"
-msgstr ""
-
msgid "Serverless|Learn more about Serverless"
msgstr ""
msgid "Serverless|No functions available"
msgstr ""
-msgid "Serverless|Sign up for First Look"
+msgid "Serverless|Serverless was %{linkStart}deprecated%{linkEnd} in GitLab 14.3."
+msgstr ""
+
+msgid "Serverless|Serverless was %{postLinkStart}deprecated%{postLinkEnd}. But if you opt to use it, you must install Knative in your Kubernetes cluster first. %{linkStart}Learn more.%{linkEnd}"
msgstr ""
msgid "Serverless|The deploy job has not finished."
@@ -32510,9 +33193,6 @@ 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 ""
@@ -32528,9 +33208,6 @@ msgstr ""
msgid "Service Account Key"
msgstr ""
-msgid "Service Accounts"
-msgstr ""
-
msgid "Service Accounts keys authorize GitLab to deploy your Google Cloud project"
msgstr ""
@@ -32540,10 +33217,10 @@ msgstr ""
msgid "Service Desk allows people to create issues in your GitLab instance without their own user account. It provides a unique email address for end users to create issues in a project. Replies can be sent either through the GitLab interface or by email. End users only see threads through email."
msgstr ""
-msgid "Service Usage Data"
+msgid "Service account generated successfully"
msgstr ""
-msgid "Service account generated successfully"
+msgid "Service accounts"
msgstr ""
msgid "Service ping is disabled in your configuration file, and cannot be enabled through this form."
@@ -32687,6 +33364,9 @@ msgstr ""
msgid "Set the milestone to %{milestone_reference}."
msgstr ""
+msgid "Set the per-user rate limit for getting a user by ID via the API."
+msgstr ""
+
msgid "Set the per-user rate limit for notes created by web or API requests."
msgstr ""
@@ -32865,6 +33545,9 @@ msgstr ""
msgid "Shared runners details"
msgstr ""
+msgid "Shared runners enabled cannot be enabled until a valid credit card is on file"
+msgstr ""
+
msgid "Shared runners help link"
msgstr ""
@@ -32922,6 +33605,9 @@ msgstr ""
msgid "Show all issues."
msgstr ""
+msgid "Show all milestones"
+msgstr ""
+
msgid "Show all test cases."
msgstr ""
@@ -32958,6 +33644,9 @@ msgstr ""
msgid "Show file contents"
msgstr ""
+msgid "Show group milestones"
+msgstr ""
+
msgid "Show labels"
msgstr ""
@@ -32973,6 +33662,12 @@ msgstr ""
msgid "Show open epics"
msgstr ""
+msgid "Show project milestones"
+msgstr ""
+
+msgid "Show sub-group milestones"
+msgstr ""
+
msgid "Show the Closed list"
msgstr ""
@@ -32982,10 +33677,6 @@ msgstr ""
msgid "Show whitespace changes"
msgstr ""
-msgid "Showing %d event"
-msgid_plural "Showing %d events"
-msgstr[0] ""
-
msgid "Showing %{conflict} between %{sourceBranch} and %{targetBranch}"
msgstr ""
@@ -33044,12 +33735,6 @@ msgstr ""
msgid "Sidebar|None"
msgstr ""
-msgid "Sidebar|Only numeral characters allowed"
-msgstr ""
-
-msgid "Sidebar|Weight"
-msgstr ""
-
msgid "Sidekiq job compression threshold (bytes)"
msgstr ""
@@ -33212,6 +33897,9 @@ msgstr ""
msgid "Slack logo"
msgstr ""
+msgid "SlackIntegration|Are you sure you want to remove this project from the Slack application?"
+msgstr ""
+
msgid "SlackIntegration|GitLab for Slack"
msgstr ""
@@ -33221,6 +33909,9 @@ msgstr ""
msgid "SlackIntegration|Project alias"
msgstr ""
+msgid "SlackIntegration|Remove project"
+msgstr ""
+
msgid "SlackIntegration|Select a GitLab project to link with your Slack workspace."
msgstr ""
@@ -33365,9 +34056,6 @@ msgstr ""
msgid "Something went wrong trying to load issue contacts."
msgstr ""
-msgid "Something went wrong when creating a work item. Please try again"
-msgstr ""
-
msgid "Something went wrong when reordering designs. Please try again"
msgstr ""
@@ -33461,9 +34149,6 @@ msgstr ""
msgid "Something went wrong while inserting your image. Please try again."
msgstr ""
-msgid "Something went wrong while merging this merge request. Please try again."
-msgstr ""
-
msgid "Something went wrong while obtaining the Let's Encrypt certificate."
msgstr ""
@@ -33785,10 +34470,10 @@ 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."
+msgid "SourcegraphAdmin|Learn more."
msgstr ""
-msgid "SourcegraphAdmin|More information"
+msgid "SourcegraphAdmin|Only public projects have code intelligence enabled and communicate with Sourcegraph."
msgstr ""
msgid "SourcegraphAdmin|Save changes"
@@ -33797,7 +34482,7 @@ msgstr ""
msgid "SourcegraphAdmin|Sourcegraph URL"
msgstr ""
-msgid "SourcegraphAdmin|e.g. https://sourcegraph.example.com"
+msgid "SourcegraphAdmin|https://sourcegraph.example.com"
msgstr ""
msgid "SourcegraphPreferences|This feature is experimental and currently limited to certain projects."
@@ -33932,6 +34617,9 @@ msgstr ""
msgid "Start date"
msgstr ""
+msgid "Start free trial"
+msgstr ""
+
msgid "Start merge train"
msgstr ""
@@ -33962,6 +34650,9 @@ msgstr ""
msgid "Started asynchronous removal of all repository check states."
msgstr ""
+msgid "Started escalation for this incident."
+msgstr ""
+
msgid "Starting..."
msgstr ""
@@ -33974,6 +34665,9 @@ msgstr ""
msgid "Starts at (UTC)"
msgstr ""
+msgid "Starts escalations for this incident"
+msgstr ""
+
msgid "Starts on"
msgstr ""
@@ -34235,6 +34929,9 @@ msgstr ""
msgid "Strikethrough"
msgstr ""
+msgid "Strikethrough text"
+msgstr ""
+
msgid "Subgroup information"
msgstr ""
@@ -34469,6 +35166,21 @@ msgstr ""
msgid "Subscriptions"
msgstr ""
+msgid "Subscriptions|Chat with sales"
+msgstr ""
+
+msgid "Subscriptions|Close"
+msgstr ""
+
+msgid "Subscriptions|Not ready to buy yet?"
+msgstr ""
+
+msgid "Subscriptions|Start a free trial"
+msgstr ""
+
+msgid "Subscriptions|We understand. Maybe you have some questions for our sales team, or maybe you'd like to try some of the paid features first. What would you like to do?"
+msgstr ""
+
msgid "Subscription|Your subscription for %{strong}%{namespace_name}%{strong_close} has expired and you are now on %{pricing_link_start}the GitLab Free tier%{pricing_link_end}. Don't worry, your data is safe. Get in touch with our support team (%{support_email}). They'll gladly help with your subscription renewal."
msgstr ""
@@ -34679,6 +35391,9 @@ msgstr ""
msgid "SuperSonics|Maximum users"
msgstr ""
+msgid "SuperSonics|Offline cloud"
+msgstr ""
+
msgid "SuperSonics|Paste your activation code"
msgstr ""
@@ -34745,6 +35460,12 @@ msgstr ""
msgid "SuperSonics|You do not have an active subscription"
msgstr ""
+msgid "SuperSonics|You have a future dated license"
+msgstr ""
+
+msgid "SuperSonics|You have added a license that activates on %{date}. Please see the subscription history table below for more details."
+msgstr ""
+
msgid "SuperSonics|You have successfully added a license that activates on %{date}. Please see the subscription history table below for more details."
msgstr ""
@@ -34904,6 +35625,9 @@ msgstr ""
msgid "Tag name is required"
msgstr ""
+msgid "Tag push"
+msgstr ""
+
msgid "Tag push events"
msgstr ""
@@ -35006,6 +35730,9 @@ msgstr ""
msgid "TagsPage|protected"
msgstr ""
+msgid "Take a look at the documentation to discover all of GitLab’s capabilities."
+msgstr ""
+
msgid "Target Branch"
msgstr ""
@@ -35402,6 +36129,9 @@ msgstr ""
msgid "Tests"
msgstr ""
+msgid "Text (optional)"
+msgstr ""
+
msgid "Text added to the body of all email messages. %{character_limit} character limit"
msgstr ""
@@ -35451,6 +36181,9 @@ msgstr ""
msgid "The CSV export will be created in the background. Once finished, it will be sent to %{email} in an attachment."
msgstr ""
+msgid "The CSV export you requested of all user memberships is attached to this email."
+msgstr ""
+
msgid "The GitLab subscription service (customers.gitlab.com) is currently experiencing an outage. You can monitor the status and get updates at %{linkStart}status.gitlab.com%{linkEnd}."
msgstr ""
@@ -35526,6 +36259,9 @@ 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 epic"
+msgstr ""
+
msgid "The current issue"
msgstr ""
@@ -35686,6 +36422,9 @@ msgstr ""
msgid "The latest pipeline for this merge request has failed."
msgstr ""
+msgid "The license key is invalid."
+msgstr ""
+
msgid "The license key is invalid. Make sure it is exactly as you received it from GitLab Inc."
msgstr ""
@@ -35701,6 +36440,9 @@ msgstr ""
msgid "The license was successfully uploaded and will be active from %{starts_at}. You can see the details below."
msgstr ""
+msgid "The license you uploaded is invalid. If the issue persists, contact support at %{link}."
+msgstr ""
+
msgid "The list creation wizard is already open"
msgstr ""
@@ -36322,10 +37064,13 @@ msgstr ""
msgid "This action cannot be undone, and will permanently delete the %{key} SSH key"
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}immediately%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} and everything this project contains. %{strongOpen}There is no going back%{strongClose}"
+msgstr ""
+
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains."
msgstr ""
-msgid "This action will %{strongOpen}permanently delete%{strongClose} %{codeOpen}%{project}%{codeClose} %{strongOpen}on %{date}%{strongClose}, including its repositories and all related resources, including issues and merge requests."
+msgid "This action deletes %{codeOpen}%{project_path_with_namespace}%{codeClose} on %{date} and everything this project contains. %{strongOpen}There is no going back.%{strongClose}"
msgstr ""
msgid "This action will %{strongOpen}permanently remove%{strongClose} %{codeOpen}%{group}%{codeClose} %{strongOpen}immediately%{strongClose}."
@@ -36454,9 +37199,6 @@ msgstr ""
msgid "This file was modified for readability, and can't accept suggestions. Edit it directly."
msgstr ""
-msgid "This forked project has the following:"
-msgstr ""
-
msgid "This form is disabled in preview"
msgstr ""
@@ -36469,7 +37211,7 @@ msgstr ""
msgid "This group can't be removed because it is linked to a subscription. To remove this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
-msgid "This group can't be transfered because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
+msgid "This group can't be transferred because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
msgid "This group cannot be invited to a project inside a group with enforced SSO"
@@ -36496,6 +37238,9 @@ 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 incident is already escalated with '%{escalation_policy_name}'."
+msgstr ""
+
msgid "This invitation was sent to %{mail_to_invite_email}, but you are signed in as %{link_to_current_user} with email %{mail_to_current_user}."
msgstr ""
@@ -36514,9 +37259,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 merge train pipeline"
-msgstr ""
-
msgid "This is a private email address %{helpIcon} generated just for you. Anyone who has it can create issues or merge requests as if they were you. If that happens, %{resetLinkStart}reset this token%{resetLinkEnd}."
msgstr ""
@@ -36538,6 +37280,12 @@ msgstr ""
msgid "This is your current session"
msgstr ""
+msgid "This issue cannot be assigned to a confidential epic because it is public."
+msgstr ""
+
+msgid "This issue cannot be made public because it belongs to a confidential epic."
+msgstr ""
+
msgid "This issue is confidential and should only be visible to team members with at least Reporter access."
msgstr ""
@@ -36655,6 +37403,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 branch is protected from force push."
+msgstr ""
+
msgid "This merge request cannot be rebased while there are conflicts."
msgstr ""
@@ -36706,9 +37457,15 @@ msgstr ""
msgid "This pipeline was triggered by a schedule."
msgstr ""
+msgid "This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project"
msgstr ""
+msgid "This project can be restored until %{date}."
+msgstr ""
+
msgid "This project cannot be %{visibilityLevel} because the visibility of %{openShowLink}%{name}%{closeShowLink} is %{visibility}. To make this project %{visibilityLevel}, you must first %{openEditLink}change the visibility%{closeEditLink} of the parent group."
msgstr ""
@@ -36727,6 +37484,9 @@ msgstr ""
msgid "This project is %{strongStart}NOT%{strongEnd} a fork, and has the following:"
msgstr ""
+msgid "This project is %{strongStart}NOT%{strongEnd} a fork. This process deletes the project repository and all related resources."
+msgstr ""
+
msgid "This project is archived and cannot be commented on."
msgstr ""
@@ -37416,6 +38176,9 @@ msgstr ""
msgid "Today"
msgstr ""
+msgid "Todos count"
+msgstr ""
+
msgid "Todos|Are you looking for things to do? Take a look at %{strongStart}%{openIssuesLinkStart}open issues%{openIssuesLinkEnd}%{strongEnd}, contribute to %{strongStart}%{mergeRequestLinkStart}a merge request%{mergeRequestLinkEnd}%{mergeRequestLinkEnd}%{strongEnd}, or mention someone in a comment to automatically assign them a new to-do item."
msgstr ""
@@ -37689,9 +38452,8 @@ msgstr ""
msgid "Trending"
msgstr ""
-msgid "Trials|%{planName} Trial %{enDash} %{num} day left"
-msgid_plural "Trials|%{planName} Trial %{enDash} %{num} days left"
-msgstr[0] ""
+msgid "Trials|%{planName} Trial"
+msgstr ""
msgid "Trials|Compare all plans"
msgstr ""
@@ -37699,6 +38461,9 @@ msgstr ""
msgid "Trials|Create a new group to start your GitLab Ultimate trial."
msgstr ""
+msgid "Trials|Day %{daysUsed}/%{duration}"
+msgstr ""
+
msgid "Trials|Go back to GitLab"
msgstr ""
@@ -37948,7 +38713,7 @@ msgstr ""
msgid "URL is triggered when repository is updated"
msgstr ""
-msgid "URL must be percent-encoded if neccessary."
+msgid "URL must be percent-encoded if necessary."
msgstr ""
msgid "URL must start with %{codeStart}http://%{codeEnd}, %{codeStart}https://%{codeEnd}, or %{codeStart}ftp://%{codeEnd}"
@@ -38167,6 +38932,9 @@ msgstr ""
msgid "Unlock account"
msgstr ""
+msgid "Unlock more features with GitLab Ultimate"
+msgstr ""
+
msgid "Unlock the discussion"
msgstr ""
@@ -38230,6 +38998,9 @@ msgstr ""
msgid "Unsubscribes from this %{quick_action_target}."
msgstr ""
+msgid "Unsupported sort value."
+msgstr ""
+
msgid "Unsupported todo type passed. Supported todo types are: %{todo_types}"
msgstr ""
@@ -38458,6 +39229,9 @@ msgstr ""
msgid "UsageQuota|File attachments and smaller design graphics."
msgstr ""
+msgid "UsageQuota|From %{storage_enforcement_date} storage limits will apply to this namespace. View and manage your usage in %{strong_start}Group Settings &gt; Usage quotas%{strong_end}."
+msgstr ""
+
msgid "UsageQuota|Git repository."
msgstr ""
@@ -38518,6 +39292,9 @@ msgstr ""
msgid "UsageQuota|Storage type"
msgstr ""
+msgid "UsageQuota|Storage used"
+msgstr ""
+
msgid "UsageQuota|This is the total amount of storage used across your projects within this namespace."
msgstr ""
@@ -38713,6 +39490,12 @@ msgstr ""
msgid "Use hashed storage paths for newly created and renamed repositories. Always enabled since 13.0."
msgstr ""
+msgid "Use issue count"
+msgstr ""
+
+msgid "Use issue weight"
+msgstr ""
+
msgid "Use one line per URI"
msgstr ""
@@ -39094,6 +39877,9 @@ msgstr ""
msgid "Users"
msgstr ""
+msgid "Users API rate limit"
+msgstr ""
+
msgid "Users can launch a development environment from a GitLab browser tab when the %{linkStart}Gitpod%{linkEnd} integration is enabled."
msgstr ""
@@ -39417,6 +40203,9 @@ msgstr ""
msgid "View group labels"
msgstr ""
+msgid "View group pipeline usage quota"
+msgstr ""
+
msgid "View incident details at"
msgstr ""
@@ -39568,6 +40357,9 @@ msgstr ""
msgid "Vulnerabilities over time"
msgstr ""
+msgid "Vulnerability"
+msgstr ""
+
msgid "Vulnerability Report"
msgstr ""
@@ -39619,6 +40411,9 @@ msgstr ""
msgid "VulnerabilityManagement|An unverified non-confirmed finding"
msgstr ""
+msgid "VulnerabilityManagement|At least one identifier is required"
+msgstr ""
+
msgid "VulnerabilityManagement|Change status"
msgstr ""
@@ -39628,12 +40423,24 @@ msgstr ""
msgid "VulnerabilityManagement|Create Jira issue"
msgstr ""
+msgid "VulnerabilityManagement|Enter a name"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE code"
+msgstr ""
+
+msgid "VulnerabilityManagement|Enter the CVE or CWE identifier URL"
+msgstr ""
+
msgid "VulnerabilityManagement|Fetching linked Jira issues"
msgstr ""
msgid "VulnerabilityManagement|Manually add a vulnerability entry into the vulnerability report."
msgstr ""
+msgid "VulnerabilityManagement|Name is a required field"
+msgstr ""
+
msgid "VulnerabilityManagement|Needs triage"
msgstr ""
@@ -39649,6 +40456,18 @@ msgstr ""
msgid "VulnerabilityManagement|Select a method"
msgstr ""
+msgid "VulnerabilityManagement|Select a severity level"
+msgstr ""
+
+msgid "VulnerabilityManagement|Select a status"
+msgstr ""
+
+msgid "VulnerabilityManagement|Severity is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Something went wrong while creating vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Something went wrong while trying to delete the comment. Please try again later."
msgstr ""
@@ -39673,6 +40492,12 @@ msgstr ""
msgid "VulnerabilityManagement|Something went wrong, could not update vulnerability state."
msgstr ""
+msgid "VulnerabilityManagement|Status is a required field"
+msgstr ""
+
+msgid "VulnerabilityManagement|Submit vulnerability"
+msgstr ""
+
msgid "VulnerabilityManagement|Summary, detailed description, steps to reproduce, etc."
msgstr ""
@@ -39868,6 +40693,9 @@ msgstr ""
msgid "WARNING:"
msgstr ""
+msgid "WARNING: This snippet contains hidden files which might be used to mask malicious behavior. Exercise caution if cloning and executing code from this snippet."
+msgstr ""
+
msgid "Wait for the file to load to copy its contents"
msgstr ""
@@ -40087,6 +40915,15 @@ msgstr ""
msgid "Webhooks|An issue is created, updated, closed, or reopened."
msgstr ""
+msgid "Webhooks|Are you sure you want to delete this group hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this project hook?"
+msgstr ""
+
+msgid "Webhooks|Are you sure you want to delete this webhook?"
+msgstr ""
+
msgid "Webhooks|Comments"
msgstr ""
@@ -40096,6 +40933,9 @@ msgstr ""
msgid "Webhooks|Confidential issues events"
msgstr ""
+msgid "Webhooks|Delete webhook"
+msgstr ""
+
msgid "Webhooks|Deployment events"
msgstr ""
@@ -40328,6 +41168,9 @@ msgstr ""
msgid "Wiki"
msgstr "Wiki"
+msgid "Wiki page"
+msgstr ""
+
msgid "Wiki page was successfully created."
msgstr ""
@@ -40433,7 +41276,7 @@ msgstr ""
msgid "WikiPageConflictMessage|Someone edited the page the same time you did. Please check out %{wikiLinkStart}the page%{wikiLinkEnd} and make sure your changes will not unintentionally remove theirs."
msgstr ""
-msgid "WikiPage|An error occured while trying to render the content editor. Please try again later."
+msgid "WikiPage|An error occurred while trying to render the content editor. Please try again later."
msgstr ""
msgid "WikiPage|Are you sure you want to switch back to the classic editor?"
@@ -40592,6 +41435,18 @@ msgstr ""
msgid "WorkItem|New Task"
msgstr ""
+msgid "WorkItem|Something went wrong when creating a work item. Please try again"
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching the work item. Please try again."
+msgstr ""
+
+msgid "WorkItem|Something went wrong when fetching work item types. Please try again"
+msgstr ""
+
+msgid "WorkItem|Type"
+msgstr ""
+
msgid "WorkItem|Work Items"
msgstr ""
@@ -40658,7 +41513,10 @@ msgstr ""
msgid "You are about to add %{usersTag} people to the discussion. They will all receive a notification."
msgstr ""
-msgid "You are about to permanently delete this project"
+msgid "You are about to delete this forked project containing:"
+msgstr ""
+
+msgid "You are about to delete this project containing:"
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."
@@ -40679,6 +41537,9 @@ msgstr ""
msgid "You are attempting to update a file that has changed since you started editing it."
msgstr ""
+msgid "You are billed if you exceed this number. %{qsrOverageLinkStart}How does billing work?%{qsrOverageLinkEnd}"
+msgstr ""
+
msgid "You are connected to the Prometheus server, but there is currently no data to display."
msgstr ""
@@ -40736,6 +41597,9 @@ msgstr ""
msgid "You are not authorized to update this scanner profile"
msgstr ""
+msgid "You are not authorized to upload metric images"
+msgstr ""
+
msgid "You are now impersonating %{username}"
msgstr ""
@@ -40889,9 +41753,6 @@ msgstr ""
msgid "You can only upload one design when dropping onto an existing design."
msgstr ""
-msgid "You can recover this project until %{date}"
-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 ""
@@ -40940,9 +41801,6 @@ msgstr ""
msgid "You cannot write to this read-only GitLab instance."
msgstr ""
-msgid "You can’t %{tag_start}edit%{tag_end} files directly in this project. Fork this project and submit a merge request with your changes."
-msgstr ""
-
msgid "You can’t edit files directly in this project. Fork this project and submit a merge request with your changes."
msgstr ""
@@ -41094,9 +41952,6 @@ 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 set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can %{anchorOpen}use that key to generate additional recovery codes%{anchorClose}."
msgstr ""
@@ -41127,12 +41982,6 @@ msgstr ""
msgid "You must have maintainer access to force delete a lock"
msgstr ""
-msgid "You must have permission to create a project in a group before forking."
-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 ""
@@ -41538,7 +42387,7 @@ msgstr ""
msgid "Your public email will be displayed on your public profile."
msgstr ""
-msgid "Your request for access could not be processed: %{error_meesage}"
+msgid "Your request for access could not be processed: %{error_message}"
msgstr ""
msgid "Your request for access has been queued for review."
@@ -41718,6 +42567,9 @@ msgstr ""
msgid "archived:"
msgstr ""
+msgid "artifacts"
+msgstr ""
+
msgid "assign yourself"
msgstr ""
@@ -41746,6 +42598,9 @@ msgstr[0] ""
msgid "branch name"
msgstr ""
+msgid "builds"
+msgstr ""
+
msgid "by"
msgstr "來自"
@@ -42166,6 +43021,9 @@ msgstr ""
msgid "contact with same email already exists in group hierarchy"
msgstr ""
+msgid "container registry images"
+msgstr ""
+
msgid "container_name can contain only lowercase letters, digits, '-', and '.' and must start and end with an alphanumeric character"
msgstr ""
@@ -42205,6 +43063,9 @@ msgstr ""
msgid "data"
msgstr ""
+msgid "database"
+msgstr ""
+
msgid "date must not be after 9999-12-31"
msgstr ""
@@ -42227,9 +43088,6 @@ msgstr ""
msgid "design"
msgstr ""
-msgid "detached"
-msgstr ""
-
msgid "disabled"
msgstr ""
@@ -42474,7 +43332,7 @@ msgstr ""
msgid "is not a valid X509 certificate."
msgstr ""
-msgid "is not allowed for sign-up."
+msgid "is not allowed for sign-up. Please use your regular email address."
msgstr ""
msgid "is not allowed for this group."
@@ -42486,7 +43344,7 @@ msgstr ""
msgid "is not allowed since the group is not top-level group."
msgstr ""
-msgid "is not allowed."
+msgid "is not allowed. Please use your regular email address."
msgstr ""
msgid "is not allowed. We do not currently support project-level iterations"
@@ -42573,6 +43431,9 @@ msgstr ""
msgid "level: %{level}"
msgstr ""
+msgid "lfs objects"
+msgstr ""
+
msgid "limit of %{project_limit} reached"
msgstr ""
@@ -42789,6 +43650,9 @@ msgstr ""
msgid "mrWidget|Merge blocked: pipeline must succeed. It's waiting for a manual action to continue."
msgstr ""
+msgid "mrWidget|Merge blocked: pipeline must succeed. Push a commit that fixes the failure, or %{linkStart}learn about other solutions.%{linkEnd}"
+msgstr ""
+
msgid "mrWidget|Merge blocked: this merge request must be approved."
msgstr ""
@@ -42906,9 +43770,6 @@ msgstr ""
msgid "mrWidget|The changes were not merged into"
msgstr ""
-msgid "mrWidget|The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
-msgstr ""
-
msgid "mrWidget|The source branch has been deleted"
msgstr ""
@@ -43056,9 +43917,6 @@ msgstr ""
msgid "open issue"
msgstr ""
-msgid "opened %{timeAgo}"
-msgstr ""
-
msgid "or"
msgstr ""
@@ -43069,6 +43927,12 @@ msgid "out of %d total test"
msgid_plural "out of %d total tests"
msgstr[0] ""
+msgid "packages"
+msgstr ""
+
+msgid "pages"
+msgstr ""
+
msgid "parent"
msgid_plural "parents"
msgstr[0] ""
@@ -43214,6 +44078,9 @@ msgid "reply"
msgid_plural "replies"
msgstr[0] ""
+msgid "repositories"
+msgstr ""
+
msgid "repository:"
msgstr ""
@@ -43334,12 +44201,18 @@ msgstr ""
msgid "tag name"
msgstr ""
+msgid "terraform states"
+msgstr ""
+
msgid "the correct format."
msgstr ""
msgid "the file"
msgstr ""
+msgid "the following epic(s)"
+msgstr ""
+
msgid "the following issue(s)"
msgstr ""
@@ -43352,21 +44225,12 @@ msgstr ""
msgid "this document"
msgstr ""
-msgid "this issue cannot be assigned to a confidential epic since it is public"
-msgstr ""
-
-msgid "this issue cannot be made public since it belongs to a confidential epic"
-msgstr ""
-
msgid "time summary"
msgstr ""
msgid "toggle collapse"
msgstr ""
-msgid "train"
-msgstr ""
-
msgid "triggered"
msgstr ""
@@ -43494,3 +44358,6 @@ msgstr ""
msgid "{project}"
msgstr ""
+msgid "✔"
+msgstr ""
+
diff --git a/metrics_server/dependencies.rb b/metrics_server/dependencies.rb
index 02cec1173e0..bfa6aae8ef8 100644
--- a/metrics_server/dependencies.rb
+++ b/metrics_server/dependencies.rb
@@ -31,5 +31,6 @@ require_relative '../lib/gitlab/metrics/exporter/gc_request_middleware'
require_relative '../lib/gitlab/health_checks/probes/collection'
require_relative '../lib/gitlab/health_checks/probes/status'
require_relative '../lib/gitlab/process_management'
+require_relative '../lib/gitlab/process_supervisor'
# rubocop:enable Naming/FileName
diff --git a/metrics_server/metrics_server.rb b/metrics_server/metrics_server.rb
index 70769459019..2aadc63d65d 100644
--- a/metrics_server/metrics_server.rb
+++ b/metrics_server/metrics_server.rb
@@ -2,10 +2,29 @@
require_relative '../config/boot'
-require_relative 'dependencies'
-
class MetricsServer # rubocop:disable Gitlab/NamespacedClass
+ # The singleton instance used to supervise the Puma metrics server.
+ PumaProcessSupervisor = Class.new(Gitlab::ProcessSupervisor)
+
class << self
+ def start_for_puma
+ metrics_dir = ::Prometheus::Client.configuration.multiprocess_files_dir
+
+ start_server = proc do
+ MetricsServer.spawn('puma', metrics_dir: metrics_dir).tap do |pid|
+ Gitlab::AppLogger.info("Starting Puma metrics server with pid #{pid}")
+ end
+ end
+
+ supervisor = PumaProcessSupervisor.instance
+ supervisor.supervise(start_server.call) do
+ next unless supervisor.alive
+
+ Gitlab::AppLogger.info('Puma metrics server terminated, restarting...')
+ start_server.call
+ end
+ end
+
def spawn(target, metrics_dir:, gitlab_config: nil, wipe_metrics_dir: false)
ensure_valid_target!(target)
diff --git a/package.json b/package.json
index ddaf4f60af7..80aeb235b6b 100644
--- a/package.json
+++ b/package.json
@@ -56,16 +56,16 @@
"@babel/preset-env": "^7.10.1",
"@gitlab/at.js": "1.5.7",
"@gitlab/favicon-overlay": "2.0.0",
- "@gitlab/svgs": "2.5.0",
- "@gitlab/ui": "36.6.0",
+ "@gitlab/svgs": "2.6.0",
+ "@gitlab/ui": "37.3.0",
"@gitlab/visual-review-tools": "1.6.1",
"@rails/actioncable": "6.1.4-6",
"@rails/ujs": "6.1.4-6",
"@sentry/browser": "5.30.0",
"@sourcegraph/code-host-integration": "0.0.60",
- "@tiptap/core": "^2.0.0-beta.171",
+ "@tiptap/core": "^2.0.0-beta.174",
"@tiptap/extension-blockquote": "^2.0.0-beta.26",
- "@tiptap/extension-bold": "^2.0.0-beta.25",
+ "@tiptap/extension-bold": "^2.0.0-beta.26",
"@tiptap/extension-bullet-list": "^2.0.0-beta.26",
"@tiptap/extension-code": "^2.0.0-beta.26",
"@tiptap/extension-code-block-lowlight": "2.0.0-beta.68",
@@ -76,8 +76,8 @@
"@tiptap/extension-heading": "^2.0.0-beta.26",
"@tiptap/extension-history": "^2.0.0-beta.21",
"@tiptap/extension-horizontal-rule": "^2.0.0-beta.31",
- "@tiptap/extension-image": "^2.0.0-beta.25",
- "@tiptap/extension-italic": "^2.0.0-beta.25",
+ "@tiptap/extension-image": "^2.0.0-beta.27",
+ "@tiptap/extension-italic": "^2.0.0-beta.26",
"@tiptap/extension-link": "^2.0.0-beta.36",
"@tiptap/extension-list-item": "^2.0.0-beta.20",
"@tiptap/extension-ordered-list": "^2.0.0-beta.27",
@@ -120,7 +120,7 @@
"dateformat": "^5.0.1",
"deckar01-task_list": "^2.3.1",
"diff": "^3.4.0",
- "dompurify": "^2.3.5",
+ "dompurify": "^2.3.6",
"dropzone": "^4.2.0",
"editorconfig": "^0.15.3",
"emoji-regex": "^10.0.0",
@@ -141,7 +141,7 @@
"jszip-utils": "^0.0.2",
"katex": "^0.13.2",
"lodash": "^4.17.20",
- "lowlight": "^1.20.0",
+ "lowlight": "^2.5.0",
"marked": "^0.3.12",
"mathjax": "3",
"mermaid": "^8.13.10",
@@ -157,11 +157,11 @@
"portal-vue": "^2.1.7",
"postcss": "8.4.5",
"prismjs": "^1.21.0",
- "prosemirror-markdown": "1.6.0",
+ "prosemirror-markdown": "1.7.1",
"prosemirror-model": "^1.16.1",
"prosemirror-state": "^1.3.4",
"prosemirror-tables": "^1.1.1",
- "prosemirror-view": "^1.23.6",
+ "prosemirror-view": "^1.23.7",
"raphael": "^2.2.7",
"raw-loader": "^4.0.2",
"scrollparent": "^2.0.1",
@@ -176,8 +176,6 @@
"three-orbit-controls": "^82.1.0",
"three-stl-loader": "^1.0.4",
"timeago.js": "^4.0.2",
- "tiptap": "^1.32.2",
- "tiptap-extensions": "^1.35.2",
"url-loader": "^4.1.1",
"uuid": "8.1.0",
"visibilityjs": "^1.2.4",
@@ -202,7 +200,7 @@
},
"devDependencies": {
"@babel/plugin-transform-modules-commonjs": "^7.10.1",
- "@gitlab/eslint-plugin": "10.0.0",
+ "@gitlab/eslint-plugin": "11.0.0",
"@gitlab/stylelint-config": "4.0.0",
"@graphql-eslint/eslint-plugin": "3.0.0",
"@testing-library/dom": "^7.16.2",
diff --git a/qa/Gemfile b/qa/Gemfile
index 1eaf9c7cec0..05acab5653f 100644
--- a/qa/Gemfile
+++ b/qa/Gemfile
@@ -4,7 +4,7 @@ source 'https://rubygems.org'
gem 'gitlab-qa', require: 'gitlab/qa'
gem 'activesupport', '~> 6.1.4.6' # This should stay in sync with the root's Gemfile
-gem 'allure-rspec', '~> 2.15.0'
+gem 'allure-rspec', '~> 2.16.0'
gem 'capybara', '~> 3.35.0'
gem 'capybara-screenshot', '~> 1.0.23'
gem 'rake', '~> 13'
@@ -35,6 +35,8 @@ gem 'confiner', '~> 0.2'
gem 'chemlab', '~> 0.9'
gem 'chemlab-library-www-gitlab-com', '~> 0.1'
+gem "pact", "~> 1.12"
+
gem 'deprecation_toolkit', '~> 1.5.1', require: false
group :development do
diff --git a/qa/Gemfile.lock b/qa/Gemfile.lock
index 6afd205a6e1..4be8adaef33 100644
--- a/qa/Gemfile.lock
+++ b/qa/Gemfile.lock
@@ -2,7 +2,7 @@ GEM
remote: https://rubygems.org/
specs:
abstract_type (0.0.7)
- activesupport (6.1.4.6)
+ activesupport (6.1.4.7)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 1.6, < 2)
minitest (>= 5.1)
@@ -19,15 +19,16 @@ GEM
rack-test (>= 1.1.0, < 2.0)
rest-client (>= 2.0.2, < 3.0)
rspec (~> 3.8)
- allure-rspec (2.15.0)
- allure-ruby-commons (= 2.15.0)
+ allure-rspec (2.16.1)
+ allure-ruby-commons (= 2.16.1)
rspec-core (>= 3.8, < 4)
- allure-ruby-commons (2.15.0)
+ allure-ruby-commons (2.16.1)
mime-types (>= 3.3, < 4)
oj (>= 3.10, < 4)
require_all (>= 2, < 4)
uuid (>= 2.3, < 3)
ast (2.4.2)
+ awesome_print (1.9.2)
binding_ninja (0.2.3)
builder (3.2.4)
byebug (9.1.0)
@@ -57,7 +58,7 @@ GEM
adamantium (~> 0.2.0)
equalizer (~> 0.0.9)
concurrent-ruby (1.1.9)
- confiner (0.2.1)
+ confiner (0.2.3)
gitlab (>= 4.17)
zeitwerk (~> 2.5.1)
declarative (0.0.20)
@@ -87,10 +88,12 @@ GEM
faraday-net_http (1.0.1)
faraday-net_http_persistent (1.2.0)
faraday-patron (1.0.0)
- ffi (1.15.4)
+ ffi (1.15.5)
ffi-compiler (1.0.1)
ffi (>= 1.0.0)
rake
+ filelock (1.1.1)
+ find_a_port (1.0.1)
fog-core (2.1.0)
builder
excon (~> 0.58)
@@ -118,11 +121,12 @@ GEM
gitlab (4.18.0)
httparty (~> 0.18)
terminal-table (>= 1.5.1)
- gitlab-qa (7.17.1)
+ gitlab-qa (7.24.4)
activesupport (~> 6.1)
gitlab (~> 4.18.0)
http (~> 5.0)
nokogiri (~> 1.10)
+ rainbow (~> 3.0.0)
table_print (= 1.5.7)
google-apis-compute_v1 (0.21.0)
google-apis-core (>= 0.4, < 2.a)
@@ -169,10 +173,11 @@ GEM
mime-types (~> 3.0)
multi_xml (>= 0.5.2)
httpclient (2.8.3)
- i18n (1.8.11)
+ i18n (1.10.0)
concurrent-ruby (~> 1.0)
ice_nine (0.11.2)
influxdb-client (1.17.0)
+ json (2.6.1)
jwt (2.3.0)
knapsack (4.0.0)
rake
@@ -191,20 +196,43 @@ GEM
mime-types-data (~> 3.2015)
mime-types-data (3.2022.0105)
mini_mime (1.1.0)
- mini_portile2 (2.6.1)
+ mini_portile2 (2.8.0)
minitest (5.15.0)
multi_json (1.15.0)
multi_xml (0.6.0)
multipart-post (2.1.1)
netrc (0.11.0)
- nokogiri (1.12.5)
- mini_portile2 (~> 2.6.1)
+ nokogiri (1.13.3)
+ mini_portile2 (~> 2.8.0)
racc (~> 1.4)
octokit (4.21.0)
faraday (>= 0.9)
sawyer (~> 0.8.0, >= 0.5.3)
- oj (3.13.8)
+ oj (3.13.11)
os (1.1.4)
+ pact (1.59.0)
+ pact-mock_service (~> 3.0, >= 3.3.1)
+ pact-support (~> 1.15)
+ rack-test (>= 0.6.3, < 2.0.0)
+ rspec (~> 3.0)
+ term-ansicolor (~> 1.0)
+ thor (>= 0.20, < 2.0)
+ webrick (~> 1.3)
+ pact-mock_service (3.6.2)
+ filelock (~> 1.1)
+ find_a_port (~> 1.0.1)
+ json
+ pact-support (~> 1.12, >= 1.12.0)
+ rack (~> 2.0)
+ rspec (>= 2.14)
+ term-ansicolor (~> 1.0)
+ thor (>= 0.19, < 2.0)
+ webrick (~> 1.3)
+ pact-support (1.15.1)
+ awesome_print (~> 1.1)
+ randexp (~> 0.1.7)
+ rspec (>= 2.14)
+ term-ansicolor (~> 1.0)
parallel (1.19.2)
parallel_tests (2.29.0)
parallel
@@ -228,6 +256,7 @@ GEM
rack (>= 1.0, < 3)
rainbow (3.0.0)
rake (13.0.6)
+ randexp (0.1.7)
regexp_parser (2.1.1)
representable (3.1.1)
declarative (< 0.1.0)
@@ -282,19 +311,25 @@ GEM
jwt (>= 1.5, < 3.0)
multi_json (~> 1.10)
slack-notifier (2.4.0)
+ sync (0.5.0)
systemu (2.6.5)
table_print (1.5.7)
+ term-ansicolor (1.7.1)
+ tins (~> 1.0)
terminal-table (3.0.2)
unicode-display_width (>= 1.1.1, < 3)
+ thor (1.2.1)
thread_safe (0.3.6)
timecop (0.9.1)
+ tins (1.31.0)
+ sync
trailblazer-option (0.1.2)
tzinfo (2.0.4)
concurrent-ruby (~> 1.0)
uber (0.1.0)
unf (0.1.4)
unf_ext
- unf_ext (0.0.8)
+ unf_ext (0.0.8.1)
unicode-display_width (2.1.0)
unparser (0.4.7)
abstract_type (~> 0.0.7)
@@ -316,7 +351,7 @@ GEM
webrick (1.7.0)
xpath (3.2.0)
nokogiri (~> 1.8)
- zeitwerk (2.5.3)
+ zeitwerk (2.5.4)
PLATFORMS
ruby
@@ -324,7 +359,7 @@ PLATFORMS
DEPENDENCIES
activesupport (~> 6.1.4.6)
airborne (~> 0.3.4)
- allure-rspec (~> 2.15.0)
+ allure-rspec (~> 2.16.0)
capybara (~> 3.35.0)
capybara-screenshot (~> 1.0.23)
chemlab (~> 0.9)
@@ -337,6 +372,7 @@ DEPENDENCIES
influxdb-client (~> 1.17)
knapsack (~> 4.0)
octokit (~> 4.21)
+ pact (~> 1.12)
parallel (~> 1.19)
parallel_tests (~> 2.29)
pry-byebug (~> 3.5.1)
diff --git a/qa/Rakefile b/qa/Rakefile
index 5d8c49a399b..0a65a58e6fc 100644
--- a/qa/Rakefile
+++ b/qa/Rakefile
@@ -60,8 +60,25 @@ task :delete_projects do
QA::Tools::DeleteProjects.new.run
end
-desc "Deletes resources created during E2E test runs"
-task :delete_test_resources, :file_pattern do |t, args|
- QA::Tools::DeleteTestResources.new(args[:file_pattern]).run
+desc "Deletes test users"
+task :delete_test_users, [:delete_before, :dry_run, :exclude_users] do |t, args|
+ QA::Tools::DeleteTestUsers.new(args).run
+end
+
+namespace :test_resources do
+ desc "Deletes resources created during E2E test runs"
+ task :delete, [:file_pattern] do |t, args|
+ QA::Tools::TestResourcesHandler.new(args[:file_pattern]).run_delete
+ end
+
+ desc "Upload test resources JSON files to GCS"
+ task :upload, [:file_pattern, :ci_project_name] do |t, args|
+ QA::Tools::TestResourcesHandler.new(args[:file_pattern]).upload(args[:ci_project_name])
+ end
+
+ desc "Download test resources JSON files from GCS"
+ task :download, [:ci_project_name] do |t, args|
+ QA::Tools::TestResourcesHandler.new.download(args[:ci_project_name])
+ end
end
# rubocop:enable Rails/RakeEnvironment
diff --git a/qa/contracts/.gitignore b/qa/contracts/.gitignore
new file mode 100644
index 00000000000..cb89d4102d3
--- /dev/null
+++ b/qa/contracts/.gitignore
@@ -0,0 +1,2 @@
+logs/
+consumer/node_modules
diff --git a/qa/contracts/consumer/.node-version b/qa/contracts/consumer/.node-version
new file mode 100644
index 00000000000..18711d290ea
--- /dev/null
+++ b/qa/contracts/consumer/.node-version
@@ -0,0 +1 @@
+14.17.5
diff --git a/qa/contracts/consumer/endpoints/merge_request.js b/qa/contracts/consumer/endpoints/merge_request.js
new file mode 100644
index 00000000000..74fd4e75bec
--- /dev/null
+++ b/qa/contracts/consumer/endpoints/merge_request.js
@@ -0,0 +1,42 @@
+'use strict';
+
+const axios = require('axios');
+
+exports.getMetadata = (endpoint) => {
+ const url = endpoint.url;
+
+ return axios
+ .request({
+ method: 'GET',
+ baseURL: url,
+ url: '/diffs_metadata.json',
+ headers: { Accept: '*/*' },
+ })
+ .then((response) => response.data);
+};
+
+exports.getDiscussions = (endpoint) => {
+ const url = endpoint.url;
+
+ return axios
+ .request({
+ method: 'GET',
+ baseURL: url,
+ url: '/discussions.json',
+ headers: { Accept: '*/*' },
+ })
+ .then((response) => response.data);
+};
+
+exports.getDiffs = (endpoint) => {
+ const url = endpoint.url;
+
+ return axios
+ .request({
+ method: 'GET',
+ baseURL: url,
+ url: '/diffs_batch.json?page=0',
+ headers: { Accept: '*/*' },
+ })
+ .then((response) => response.data);
+};
diff --git a/qa/contracts/consumer/fixtures/diffs.fixture.js b/qa/contracts/consumer/fixtures/diffs.fixture.js
new file mode 100644
index 00000000000..286d71f421c
--- /dev/null
+++ b/qa/contracts/consumer/fixtures/diffs.fixture.js
@@ -0,0 +1,89 @@
+'use strict';
+
+const { Matchers } = require('@pact-foundation/pact');
+
+const body = {
+ diff_files: Matchers.eachLike({
+ content_sha: Matchers.string('b0c94059db75b2473d616d4b1fde1a77533355a3'),
+ submodule: Matchers.boolean(false),
+ edit_path: Matchers.string('/gitlab-qa-bot/...'),
+ ide_edit_path: Matchers.string('/gitlab-qa-bot/...'),
+ old_path_html: Matchers.string('Gemfile'),
+ new_path_html: Matchers.string('Gemfile'),
+ blob: {
+ id: Matchers.string('855071bb3928d140764885964f7be1bb3e582495'),
+ path: Matchers.string('Gemfile'),
+ name: Matchers.string('Gemfile'),
+ mode: Matchers.string('1234567'),
+ readable_text: Matchers.boolean(true),
+ icon: Matchers.string('doc-text'),
+ },
+ can_modify_blob: Matchers.boolean(false),
+ file_identifier_hash: Matchers.string('67d82b8716a5b6c52c7abf0b2cd99c7594ed3587'),
+ file_hash: Matchers.string('67d82b8716a5b6c52c7abf0b2cd99c7594ed3587'),
+ file_path: Matchers.string('Gemfile'),
+ old_path: Matchers.string('Gemfile'),
+ new_path: Matchers.string('Gemfile'),
+ new_file: Matchers.boolean(false),
+ renamed_file: Matchers.boolean(false),
+ deleted_file: Matchers.boolean(false),
+ diff_refs: {
+ base_sha: Matchers.string('67d82b8716a5b6c52c7abf0b2cd99c7594ed3587'),
+ start_sha: Matchers.string('67d82b8716a5b6c52c7abf0b2cd99c7594ed3587'),
+ head_sha: Matchers.string('67d82b8716a5b6c52c7abf0b2cd99c7594ed3587'),
+ },
+ mode_changed: Matchers.boolean(false),
+ a_mode: Matchers.string('123456'),
+ b_mode: Matchers.string('123456'),
+ viewer: {
+ name: Matchers.string('text'),
+ collapsed: Matchers.boolean(false),
+ },
+ old_size: Matchers.integer(2288),
+ new_size: Matchers.integer(2288),
+ added_lines: Matchers.integer(1),
+ removed_lines: Matchers.integer(1),
+ load_collapsed_diff_url: Matchers.string('/gitlab-qa-bot/...'),
+ view_path: Matchers.string('/gitlab-qa-bot/...'),
+ context_lines_path: Matchers.string('/gitlab-qa-bot/...'),
+ highlighted_diff_lines: Matchers.eachLike({
+ // The following values can also be null which is not supported
+ //line_code: Matchers.string('de3150c01c3a946a6168173c4116741379fe3579_1_1'),
+ //old_line: Matchers.integer(1),
+ //new_line: Matchers.integer(1),
+ text: Matchers.string('source'),
+ rich_text: Matchers.string('<span></span>'),
+ can_receive_suggestion: Matchers.boolean(true),
+ }),
+ is_fully_expanded: Matchers.boolean(false),
+ }),
+ pagination: {
+ total_pages: Matchers.integer(1),
+ },
+};
+
+const Diffs = {
+ body: Matchers.extractPayload(body),
+
+ success: {
+ status: 200,
+ headers: {
+ 'Content-Type': 'application/json; charset=utf-8',
+ },
+ body: body,
+ },
+
+ request: {
+ uponReceiving: 'a request for diff lines',
+ withRequest: {
+ method: 'GET',
+ path: '/diffs_batch.json',
+ headers: {
+ Accept: '*/*',
+ },
+ query: 'page=0',
+ },
+ },
+};
+
+exports.Diffs = Diffs;
diff --git a/qa/contracts/consumer/fixtures/discussions.fixture.js b/qa/contracts/consumer/fixtures/discussions.fixture.js
new file mode 100644
index 00000000000..cfc6112561b
--- /dev/null
+++ b/qa/contracts/consumer/fixtures/discussions.fixture.js
@@ -0,0 +1,85 @@
+'use strict';
+
+const { Matchers } = require('@pact-foundation/pact');
+
+const body = Matchers.eachLike({
+ id: Matchers.string('fd73763cbcbf7b29eb8765d969a38f7d735e222a'),
+ reply_id: Matchers.string('fd73763cbcbf7b29eb8765d969a38f7d735e222a'),
+ project_id: Matchers.integer(6954442),
+ confidential: Matchers.boolean(false),
+ diff_discussion: Matchers.boolean(false),
+ expanded: Matchers.boolean(false),
+ for_commit: Matchers.boolean(false),
+ individual_note: Matchers.boolean(true),
+ resolvable: Matchers.boolean(false),
+ resolved_by_push: Matchers.boolean(false),
+ notes: Matchers.eachLike({
+ id: Matchers.string('76489845'),
+ author: {
+ id: Matchers.integer(1675733),
+ username: Matchers.string('gitlab-qa-bot'),
+ name: Matchers.string('gitlab-qa-bot'),
+ state: Matchers.string('active'),
+ avatar_url: Matchers.string(
+ 'https://secure.gravatar.com/avatar/8355ad0f2761367fae6b9c4fe80994b9?s=80&d=identicon',
+ ),
+ show_status: Matchers.boolean(false),
+ path: Matchers.string('/gitlab-qa-bot'),
+ },
+ created_at: Matchers.iso8601DateTimeWithMillis('2022-02-22T07:06:55.038Z'),
+ updated_at: Matchers.iso8601DateTimeWithMillis('2022-02-22T07:06:55.038Z'),
+ system: Matchers.boolean(false),
+ noteable_id: Matchers.integer(8333422),
+ noteable_type: Matchers.string('MergeRequest'),
+ resolvable: Matchers.boolean(false),
+ resolved: Matchers.boolean(true),
+ confidential: Matchers.boolean(false),
+ noteable_iid: Matchers.integer(1),
+ note: Matchers.string('This is a test comment'),
+ note_html: Matchers.string(
+ '<p data-sourcepos="1:1-1:22" dir="auto">This is a test comment</p>',
+ ),
+ current_user: {
+ can_edit: Matchers.boolean(true),
+ can_award_emoji: Matchers.boolean(true),
+ can_resolve: Matchers.boolean(false),
+ can_resolve_discussion: Matchers.boolean(false),
+ },
+ is_noteable_author: Matchers.boolean(true),
+ discussion_id: Matchers.string('fd73763cbcbf7b29eb8765d969a38f7d735e222a'),
+ emoji_awardable: Matchers.boolean(true),
+ report_abuse_path: Matchers.string('/gitlab-qa-bot/...'),
+ noteable_note_url: Matchers.string('https://staging.gitlab.com/gitlab-qa-bot/...'),
+ cached_markdown_version: Matchers.integer(1900552),
+ human_access: Matchers.string('Maintainer'),
+ is_contributor: Matchers.boolean(false),
+ project_name: Matchers.string('contract-testing'),
+ path: Matchers.string('/gitlab-qa-bot/...'),
+ }),
+ resolved: Matchers.boolean(true),
+});
+
+const Discussions = {
+ body: Matchers.extractPayload(body),
+
+ success: {
+ status: 200,
+ headers: {
+ 'Content-Type': 'application/json; charset=utf-8',
+ },
+ body: body,
+ },
+
+ request: {
+ uponReceiving: 'a request for discussions',
+ withRequest: {
+ method: 'GET',
+ path: '/discussions.json',
+ headers: {
+ Accept: '*/*',
+ },
+ },
+ },
+};
+
+exports.Discussions = Discussions;
diff --git a/qa/contracts/consumer/fixtures/metadata.fixture.js b/qa/contracts/consumer/fixtures/metadata.fixture.js
new file mode 100644
index 00000000000..05a4831c447
--- /dev/null
+++ b/qa/contracts/consumer/fixtures/metadata.fixture.js
@@ -0,0 +1,96 @@
+'use strict';
+
+const { Matchers } = require('@pact-foundation/pact');
+
+const body = {
+ real_size: Matchers.string('1'),
+ size: Matchers.integer(1),
+ branch_name: Matchers.string('testing-branch-1'),
+ source_branch_exists: Matchers.boolean(true),
+ target_branch_name: Matchers.string('master'),
+ merge_request_diff: {
+ created_at: Matchers.iso8601DateTimeWithMillis('2022-02-17T11:47:08.804Z'),
+ commits_count: Matchers.integer(1),
+ latest: Matchers.boolean(true),
+ short_commit_sha: Matchers.string('aee1ffec'),
+ base_version_path: Matchers.string(
+ '/gitlab-qa-bot/contract-testing/-/merge_requests/1/diffs?diff_id=10581773',
+ ),
+ head_version_path: Matchers.string(
+ '/gitlab-qa-bot/contract-testing/-/merge_requests/1/diffs?diff_head=true',
+ ),
+ version_path: Matchers.string(
+ '/gitlab-qa-bot/contract-testing/-/merge_requests/1/diffs?diff_id=10581773',
+ ),
+ compare_path: Matchers.string(
+ '/gitlab-qa-bot/contract-testing/-/merge_requests/1/diffs?diff_id=10581773&start_sha=aee1ffec2299c0cfb17c8821e931339b73a3759f',
+ ),
+ },
+ latest_diff: Matchers.boolean(true),
+ latest_version_path: Matchers.string('/gitlab-qa-bot/contract-testing/-/merge_requests/1/diffs'),
+ added_lines: Matchers.integer(1),
+ removed_lines: Matchers.integer(1),
+ render_overflow_warning: Matchers.boolean(false),
+ email_patch_path: Matchers.string('/gitlab-qa-bot/contract-testing/-/merge_requests/1.patch'),
+ plain_diff_path: Matchers.string('/gitlab-qa-bot/contract-testing/-/merge_requests/1.diff'),
+ merge_request_diffs: Matchers.eachLike({
+ commits_count: Matchers.integer(1),
+ latest: Matchers.boolean(true),
+ short_commit_sha: Matchers.string('aee1ffec'),
+ base_version_path: Matchers.string(
+ '/gitlab-qa-bot/contract-testing/-/merge_requests/1/diffs?diff_id=10581773',
+ ),
+ head_version_path: Matchers.string(
+ '/gitlab-qa-bot/contract-testing/-/merge_requests/1/diffs?diff_head=true',
+ ),
+ version_path: Matchers.string(
+ '/gitlab-qa-bot/contract-testing/-/merge_requests/1/diffs?diff_id=10581773',
+ ),
+ compare_path: Matchers.string(
+ '/gitlab-qa-bot/contract-testing/-/merge_requests/1/diffs?diff_id=10581773&start_sha=aee1ffec2299c0cfb17c8821e931339b73a3759f',
+ ),
+ }),
+ definition_path_prefix: Matchers.string(
+ '/gitlab-qa-bot/contract-testing/-/blob/aee1ffec2299c0cfb17c8821e931339b73a3759f',
+ ),
+ diff_files: Matchers.eachLike({
+ added_lines: Matchers.integer(1),
+ removed_lines: Matchers.integer(1),
+ new_path: Matchers.string('Gemfile'),
+ old_path: Matchers.string('Gemfile'),
+ new_file: Matchers.boolean(false),
+ deleted_file: Matchers.boolean(false),
+ submodule: Matchers.boolean(false),
+ file_identifier_hash: Matchers.string('67d82b8716a5b6c52c7abf0b2cd99c7594ed3587'),
+ file_hash: Matchers.string('de3150c01c3a946a6168173c4116741379fe3579'),
+ }),
+ has_conflicts: Matchers.boolean(false),
+ can_merge: Matchers.boolean(false),
+ project_path: Matchers.string('gitlab-qa-bot/contract-testing'),
+ project_name: Matchers.string('contract-testing'),
+};
+
+const Metadata = {
+ body: Matchers.extractPayload(body),
+
+ success: {
+ status: 200,
+ headers: {
+ 'Content-Type': 'application/json; charset=utf-8',
+ },
+ body: body,
+ },
+
+ request: {
+ uponReceiving: 'a request for Metadata',
+ withRequest: {
+ method: 'GET',
+ path: '/diffs_metadata.json',
+ headers: {
+ Accept: '*/*',
+ },
+ },
+ },
+};
+
+exports.Metadata = Metadata;
diff --git a/qa/contracts/consumer/package.json b/qa/contracts/consumer/package.json
new file mode 100644
index 00000000000..b4a3f59e89e
--- /dev/null
+++ b/qa/contracts/consumer/package.json
@@ -0,0 +1,17 @@
+{
+ "name": "consumer",
+ "version": "1.0.0",
+ "description": "consumer side contract testing",
+ "license": "MIT",
+ "repository": "https://gitlab.com/gitlab-org/gitlab.git",
+ "dependencies": {
+ "@pact-foundation/pact": "^9.17.2",
+ "axios": "^0.26.0",
+ "jest": "^27.5.1",
+ "jest-pact": "^0.9.1",
+ "prettier": "^2.5.1"
+ },
+ "scripts": {
+ "test": "jest specs/ --runInBand"
+ }
+}
diff --git a/qa/contracts/consumer/specs/diffs.spec.js b/qa/contracts/consumer/specs/diffs.spec.js
new file mode 100644
index 00000000000..5be2ed7ac00
--- /dev/null
+++ b/qa/contracts/consumer/specs/diffs.spec.js
@@ -0,0 +1,35 @@
+'use strict';
+
+const { pactWith } = require('jest-pact');
+
+const { Diffs } = require('../fixtures/diffs.fixture');
+const { getDiffs } = require('../endpoints/merge_request');
+
+pactWith(
+ {
+ consumer: 'Merge Request Page',
+ provider: 'Merge Request Diffs Endpoint',
+ log: '../logs/consumer.log',
+ dir: '../contracts',
+ },
+
+ (provider) => {
+ describe('Diffs Endpoint', () => {
+ beforeEach(() => {
+ const interaction = {
+ ...Diffs.request,
+ willRespondWith: Diffs.success,
+ };
+ return provider.addInteraction(interaction);
+ });
+
+ it('return a successful body', () => {
+ return getDiffs({
+ url: provider.mockService.baseUrl,
+ }).then((diffs) => {
+ expect(diffs).toEqual(Diffs.body);
+ });
+ });
+ });
+ },
+);
diff --git a/qa/contracts/consumer/specs/discussions.spec.js b/qa/contracts/consumer/specs/discussions.spec.js
new file mode 100644
index 00000000000..28ee3186a9f
--- /dev/null
+++ b/qa/contracts/consumer/specs/discussions.spec.js
@@ -0,0 +1,35 @@
+'use strict';
+
+const { pactWith } = require('jest-pact');
+
+const { Discussions } = require('../fixtures/discussions.fixture');
+const { getDiscussions } = require('../endpoints/merge_request');
+
+pactWith(
+ {
+ consumer: 'Merge Request Page',
+ provider: 'Merge Request Discussions Endpoint',
+ log: '../logs/consumer.log',
+ dir: '../contracts',
+ },
+
+ (provider) => {
+ describe('Discussions Endpoint', () => {
+ beforeEach(() => {
+ const interaction = {
+ ...Discussions.request,
+ willRespondWith: Discussions.success,
+ };
+ return provider.addInteraction(interaction);
+ });
+
+ it('return a successful body', () => {
+ return getDiscussions({
+ url: provider.mockService.baseUrl,
+ }).then((discussions) => {
+ expect(discussions).toEqual(Discussions.body);
+ });
+ });
+ });
+ },
+);
diff --git a/qa/contracts/consumer/specs/metadata.spec.js b/qa/contracts/consumer/specs/metadata.spec.js
new file mode 100644
index 00000000000..31fc398f228
--- /dev/null
+++ b/qa/contracts/consumer/specs/metadata.spec.js
@@ -0,0 +1,35 @@
+'use strict';
+
+const { pactWith } = require('jest-pact');
+
+const { Metadata } = require('../fixtures/metadata.fixture');
+const { getMetadata } = require('../endpoints/merge_request');
+
+pactWith(
+ {
+ consumer: 'Merge Request Page',
+ provider: 'Merge Request Metadata Endpoint',
+ log: '../logs/consumer.log',
+ dir: '../contracts',
+ },
+
+ (provider) => {
+ describe('Metadata Endpoint', () => {
+ beforeEach(() => {
+ const interaction = {
+ ...Metadata.request,
+ willRespondWith: Metadata.success,
+ };
+ return provider.addInteraction(interaction);
+ });
+
+ it('return a successful body', () => {
+ return getMetadata({
+ url: provider.mockService.baseUrl,
+ }).then((metadata) => {
+ expect(metadata).toEqual(Metadata.body);
+ });
+ });
+ });
+ },
+);
diff --git a/qa/contracts/contracts/merge_request_page-merge_request_diffs_endpoint.json b/qa/contracts/contracts/merge_request_page-merge_request_diffs_endpoint.json
new file mode 100644
index 00000000000..8df54c25326
--- /dev/null
+++ b/qa/contracts/contracts/merge_request_page-merge_request_diffs_endpoint.json
@@ -0,0 +1,228 @@
+{
+ "consumer": {
+ "name": "Merge Request Page"
+ },
+ "provider": {
+ "name": "Merge Request Diffs Endpoint"
+ },
+ "interactions": [
+ {
+ "description": "a request for diff lines",
+ "request": {
+ "method": "GET",
+ "path": "/diffs_batch.json",
+ "query": "page=0",
+ "headers": {
+ "Accept": "*/*"
+ }
+ },
+ "response": {
+ "status": 200,
+ "headers": {
+ "Content-Type": "application/json; charset=utf-8"
+ },
+ "body": {
+ "diff_files": [
+ {
+ "content_sha": "b0c94059db75b2473d616d4b1fde1a77533355a3",
+ "submodule": false,
+ "edit_path": "/gitlab-qa-bot/...",
+ "ide_edit_path": "/gitlab-qa-bot/...",
+ "old_path_html": "Gemfile",
+ "new_path_html": "Gemfile",
+ "blob": {
+ "id": "855071bb3928d140764885964f7be1bb3e582495",
+ "path": "Gemfile",
+ "name": "Gemfile",
+ "mode": "1234567",
+ "readable_text": true,
+ "icon": "doc-text"
+ },
+ "can_modify_blob": false,
+ "file_identifier_hash": "67d82b8716a5b6c52c7abf0b2cd99c7594ed3587",
+ "file_hash": "67d82b8716a5b6c52c7abf0b2cd99c7594ed3587",
+ "file_path": "Gemfile",
+ "old_path": "Gemfile",
+ "new_path": "Gemfile",
+ "new_file": false,
+ "renamed_file": false,
+ "deleted_file": false,
+ "diff_refs": {
+ "base_sha": "67d82b8716a5b6c52c7abf0b2cd99c7594ed3587",
+ "start_sha": "67d82b8716a5b6c52c7abf0b2cd99c7594ed3587",
+ "head_sha": "67d82b8716a5b6c52c7abf0b2cd99c7594ed3587"
+ },
+ "mode_changed": false,
+ "a_mode": "123456",
+ "b_mode": "123456",
+ "viewer": {
+ "name": "text",
+ "collapsed": false
+ },
+ "old_size": 2288,
+ "new_size": 2288,
+ "added_lines": 1,
+ "removed_lines": 1,
+ "load_collapsed_diff_url": "/gitlab-qa-bot/...",
+ "view_path": "/gitlab-qa-bot/...",
+ "context_lines_path": "/gitlab-qa-bot/...",
+ "highlighted_diff_lines": [
+ {
+ "text": "source",
+ "rich_text": "<span></span>",
+ "can_receive_suggestion": true
+ }
+ ],
+ "is_fully_expanded": false
+ }
+ ],
+ "pagination": {
+ "total_pages": 1
+ }
+ },
+ "matchingRules": {
+ "$.body.diff_files": {
+ "min": 1
+ },
+ "$.body.diff_files[*].*": {
+ "match": "type"
+ },
+ "$.body.diff_files[*].content_sha": {
+ "match": "type"
+ },
+ "$.body.diff_files[*].submodule": {
+ "match": "type"
+ },
+ "$.body.diff_files[*].edit_path": {
+ "match": "type"
+ },
+ "$.body.diff_files[*].ide_edit_path": {
+ "match": "type"
+ },
+ "$.body.diff_files[*].old_path_html": {
+ "match": "type"
+ },
+ "$.body.diff_files[*].new_path_html": {
+ "match": "type"
+ },
+ "$.body.diff_files[*].blob.id": {
+ "match": "type"
+ },
+ "$.body.diff_files[*].blob.path": {
+ "match": "type"
+ },
+ "$.body.diff_files[*].blob.name": {
+ "match": "type"
+ },
+ "$.body.diff_files[*].blob.mode": {
+ "match": "type"
+ },
+ "$.body.diff_files[*].blob.readable_text": {
+ "match": "type"
+ },
+ "$.body.diff_files[*].blob.icon": {
+ "match": "type"
+ },
+ "$.body.diff_files[*].can_modify_blob": {
+ "match": "type"
+ },
+ "$.body.diff_files[*].file_identifier_hash": {
+ "match": "type"
+ },
+ "$.body.diff_files[*].file_hash": {
+ "match": "type"
+ },
+ "$.body.diff_files[*].file_path": {
+ "match": "type"
+ },
+ "$.body.diff_files[*].old_path": {
+ "match": "type"
+ },
+ "$.body.diff_files[*].new_path": {
+ "match": "type"
+ },
+ "$.body.diff_files[*].new_file": {
+ "match": "type"
+ },
+ "$.body.diff_files[*].renamed_file": {
+ "match": "type"
+ },
+ "$.body.diff_files[*].deleted_file": {
+ "match": "type"
+ },
+ "$.body.diff_files[*].diff_refs.base_sha": {
+ "match": "type"
+ },
+ "$.body.diff_files[*].diff_refs.start_sha": {
+ "match": "type"
+ },
+ "$.body.diff_files[*].diff_refs.head_sha": {
+ "match": "type"
+ },
+ "$.body.diff_files[*].mode_changed": {
+ "match": "type"
+ },
+ "$.body.diff_files[*].a_mode": {
+ "match": "type"
+ },
+ "$.body.diff_files[*].b_mode": {
+ "match": "type"
+ },
+ "$.body.diff_files[*].viewer.name": {
+ "match": "type"
+ },
+ "$.body.diff_files[*].viewer.collapsed": {
+ "match": "type"
+ },
+ "$.body.diff_files[*].old_size": {
+ "match": "type"
+ },
+ "$.body.diff_files[*].new_size": {
+ "match": "type"
+ },
+ "$.body.diff_files[*].added_lines": {
+ "match": "type"
+ },
+ "$.body.diff_files[*].removed_lines": {
+ "match": "type"
+ },
+ "$.body.diff_files[*].load_collapsed_diff_url": {
+ "match": "type"
+ },
+ "$.body.diff_files[*].view_path": {
+ "match": "type"
+ },
+ "$.body.diff_files[*].context_lines_path": {
+ "match": "type"
+ },
+ "$.body.diff_files[*].highlighted_diff_lines": {
+ "min": 1
+ },
+ "$.body.diff_files[*].highlighted_diff_lines[*].*": {
+ "match": "type"
+ },
+ "$.body.diff_files[*].highlighted_diff_lines[*].text": {
+ "match": "type"
+ },
+ "$.body.diff_files[*].highlighted_diff_lines[*].rich_text": {
+ "match": "type"
+ },
+ "$.body.diff_files[*].highlighted_diff_lines[*].can_receive_suggestion": {
+ "match": "type"
+ },
+ "$.body.diff_files[*].is_fully_expanded": {
+ "match": "type"
+ },
+ "$.body.pagination.total_pages": {
+ "match": "type"
+ }
+ }
+ }
+ }
+ ],
+ "metadata": {
+ "pactSpecification": {
+ "version": "2.0.0"
+ }
+ }
+} \ No newline at end of file
diff --git a/qa/contracts/contracts/merge_request_page-merge_request_discussions_endpoint.json b/qa/contracts/contracts/merge_request_page-merge_request_discussions_endpoint.json
new file mode 100644
index 00000000000..14839053e57
--- /dev/null
+++ b/qa/contracts/contracts/merge_request_page-merge_request_discussions_endpoint.json
@@ -0,0 +1,235 @@
+{
+ "consumer": {
+ "name": "Merge Request Page"
+ },
+ "provider": {
+ "name": "Merge Request Discussions Endpoint"
+ },
+ "interactions": [
+ {
+ "description": "a request for discussions",
+ "request": {
+ "method": "GET",
+ "path": "/discussions.json",
+ "headers": {
+ "Accept": "*/*"
+ }
+ },
+ "response": {
+ "status": 200,
+ "headers": {
+ "Content-Type": "application/json; charset=utf-8"
+ },
+ "body": [
+ {
+ "id": "fd73763cbcbf7b29eb8765d969a38f7d735e222a",
+ "reply_id": "fd73763cbcbf7b29eb8765d969a38f7d735e222a",
+ "project_id": 6954442,
+ "confidential": false,
+ "diff_discussion": false,
+ "expanded": false,
+ "for_commit": false,
+ "individual_note": true,
+ "resolvable": false,
+ "resolved_by_push": false,
+ "notes": [
+ {
+ "id": "76489845",
+ "author": {
+ "id": 1675733,
+ "username": "gitlab-qa-bot",
+ "name": "gitlab-qa-bot",
+ "state": "active",
+ "avatar_url": "https://secure.gravatar.com/avatar/8355ad0f2761367fae6b9c4fe80994b9?s=80&d=identicon",
+ "show_status": false,
+ "path": "/gitlab-qa-bot"
+ },
+ "created_at": "2022-02-22T07:06:55.038Z",
+ "updated_at": "2022-02-22T07:06:55.038Z",
+ "system": false,
+ "noteable_id": 8333422,
+ "noteable_type": "MergeRequest",
+ "resolvable": false,
+ "resolved": true,
+ "confidential": false,
+ "noteable_iid": 1,
+ "note": "This is a test comment",
+ "note_html": "<p data-sourcepos=\"1:1-1:22\" dir=\"auto\">This is a test comment</p>",
+ "current_user": {
+ "can_edit": true,
+ "can_award_emoji": true,
+ "can_resolve": false,
+ "can_resolve_discussion": false
+ },
+ "is_noteable_author": true,
+ "discussion_id": "fd73763cbcbf7b29eb8765d969a38f7d735e222a",
+ "emoji_awardable": true,
+ "report_abuse_path": "/gitlab-qa-bot/...",
+ "noteable_note_url": "https://staging.gitlab.com/gitlab-qa-bot/...",
+ "cached_markdown_version": 1900552,
+ "human_access": "Maintainer",
+ "is_contributor": false,
+ "project_name": "contract-testing",
+ "path": "/gitlab-qa-bot/..."
+ }
+ ],
+ "resolved": true
+ }
+ ],
+ "matchingRules": {
+ "$.body": {
+ "min": 1
+ },
+ "$.body[*].*": {
+ "match": "type"
+ },
+ "$.body[*].id": {
+ "match": "type"
+ },
+ "$.body[*].reply_id": {
+ "match": "type"
+ },
+ "$.body[*].project_id": {
+ "match": "type"
+ },
+ "$.body[*].confidential": {
+ "match": "type"
+ },
+ "$.body[*].diff_discussion": {
+ "match": "type"
+ },
+ "$.body[*].expanded": {
+ "match": "type"
+ },
+ "$.body[*].for_commit": {
+ "match": "type"
+ },
+ "$.body[*].individual_note": {
+ "match": "type"
+ },
+ "$.body[*].resolvable": {
+ "match": "type"
+ },
+ "$.body[*].resolved_by_push": {
+ "match": "type"
+ },
+ "$.body[*].notes": {
+ "min": 1
+ },
+ "$.body[*].notes[*].*": {
+ "match": "type"
+ },
+ "$.body[*].notes[*].id": {
+ "match": "type"
+ },
+ "$.body[*].notes[*].author.id": {
+ "match": "type"
+ },
+ "$.body[*].notes[*].author.username": {
+ "match": "type"
+ },
+ "$.body[*].notes[*].author.name": {
+ "match": "type"
+ },
+ "$.body[*].notes[*].author.state": {
+ "match": "type"
+ },
+ "$.body[*].notes[*].author.avatar_url": {
+ "match": "type"
+ },
+ "$.body[*].notes[*].author.show_status": {
+ "match": "type"
+ },
+ "$.body[*].notes[*].author.path": {
+ "match": "type"
+ },
+ "$.body[*].notes[*].created_at": {
+ "match": "regex",
+ "regex": "^\\d{4}-[01]\\d-[0-3]\\dT[0-2]\\d:[0-5]\\d:[0-5]\\d\\.\\d+([+-][0-2]\\d(:?[0-5]\\d)?|Z)$"
+ },
+ "$.body[*].notes[*].updated_at": {
+ "match": "regex",
+ "regex": "^\\d{4}-[01]\\d-[0-3]\\dT[0-2]\\d:[0-5]\\d:[0-5]\\d\\.\\d+([+-][0-2]\\d(:?[0-5]\\d)?|Z)$"
+ },
+ "$.body[*].notes[*].system": {
+ "match": "type"
+ },
+ "$.body[*].notes[*].noteable_id": {
+ "match": "type"
+ },
+ "$.body[*].notes[*].noteable_type": {
+ "match": "type"
+ },
+ "$.body[*].notes[*].resolvable": {
+ "match": "type"
+ },
+ "$.body[*].notes[*].resolved": {
+ "match": "type"
+ },
+ "$.body[*].notes[*].confidential": {
+ "match": "type"
+ },
+ "$.body[*].notes[*].noteable_iid": {
+ "match": "type"
+ },
+ "$.body[*].notes[*].note": {
+ "match": "type"
+ },
+ "$.body[*].notes[*].note_html": {
+ "match": "type"
+ },
+ "$.body[*].notes[*].current_user.can_edit": {
+ "match": "type"
+ },
+ "$.body[*].notes[*].current_user.can_award_emoji": {
+ "match": "type"
+ },
+ "$.body[*].notes[*].current_user.can_resolve": {
+ "match": "type"
+ },
+ "$.body[*].notes[*].current_user.can_resolve_discussion": {
+ "match": "type"
+ },
+ "$.body[*].notes[*].is_noteable_author": {
+ "match": "type"
+ },
+ "$.body[*].notes[*].discussion_id": {
+ "match": "type"
+ },
+ "$.body[*].notes[*].emoji_awardable": {
+ "match": "type"
+ },
+ "$.body[*].notes[*].report_abuse_path": {
+ "match": "type"
+ },
+ "$.body[*].notes[*].noteable_note_url": {
+ "match": "type"
+ },
+ "$.body[*].notes[*].cached_markdown_version": {
+ "match": "type"
+ },
+ "$.body[*].notes[*].human_access": {
+ "match": "type"
+ },
+ "$.body[*].notes[*].is_contributor": {
+ "match": "type"
+ },
+ "$.body[*].notes[*].project_name": {
+ "match": "type"
+ },
+ "$.body[*].notes[*].path": {
+ "match": "type"
+ },
+ "$.body[*].resolved": {
+ "match": "type"
+ }
+ }
+ }
+ }
+ ],
+ "metadata": {
+ "pactSpecification": {
+ "version": "2.0.0"
+ }
+ }
+} \ No newline at end of file
diff --git a/qa/contracts/contracts/merge_request_page-merge_request_metadata_endpoint.json b/qa/contracts/contracts/merge_request_page-merge_request_metadata_endpoint.json
new file mode 100644
index 00000000000..4b6cab0fc94
--- /dev/null
+++ b/qa/contracts/contracts/merge_request_page-merge_request_metadata_endpoint.json
@@ -0,0 +1,222 @@
+{
+ "consumer": {
+ "name": "Merge Request Page"
+ },
+ "provider": {
+ "name": "Merge Request Metadata Endpoint"
+ },
+ "interactions": [
+ {
+ "description": "a request for Metadata",
+ "request": {
+ "method": "GET",
+ "path": "/diffs_metadata.json",
+ "headers": {
+ "Accept": "*/*"
+ }
+ },
+ "response": {
+ "status": 200,
+ "headers": {
+ "Content-Type": "application/json; charset=utf-8"
+ },
+ "body": {
+ "real_size": "1",
+ "size": 1,
+ "branch_name": "testing-branch-1",
+ "source_branch_exists": true,
+ "target_branch_name": "master",
+ "merge_request_diff": {
+ "created_at": "2022-02-17T11:47:08.804Z",
+ "commits_count": 1,
+ "latest": true,
+ "short_commit_sha": "aee1ffec",
+ "base_version_path": "/gitlab-qa-bot/contract-testing/-/merge_requests/1/diffs?diff_id=10581773",
+ "head_version_path": "/gitlab-qa-bot/contract-testing/-/merge_requests/1/diffs?diff_head=true",
+ "version_path": "/gitlab-qa-bot/contract-testing/-/merge_requests/1/diffs?diff_id=10581773",
+ "compare_path": "/gitlab-qa-bot/contract-testing/-/merge_requests/1/diffs?diff_id=10581773&start_sha=aee1ffec2299c0cfb17c8821e931339b73a3759f"
+ },
+ "latest_diff": true,
+ "latest_version_path": "/gitlab-qa-bot/contract-testing/-/merge_requests/1/diffs",
+ "added_lines": 1,
+ "removed_lines": 1,
+ "render_overflow_warning": false,
+ "email_patch_path": "/gitlab-qa-bot/contract-testing/-/merge_requests/1.patch",
+ "plain_diff_path": "/gitlab-qa-bot/contract-testing/-/merge_requests/1.diff",
+ "merge_request_diffs": [
+ {
+ "commits_count": 1,
+ "latest": true,
+ "short_commit_sha": "aee1ffec",
+ "base_version_path": "/gitlab-qa-bot/contract-testing/-/merge_requests/1/diffs?diff_id=10581773",
+ "head_version_path": "/gitlab-qa-bot/contract-testing/-/merge_requests/1/diffs?diff_head=true",
+ "version_path": "/gitlab-qa-bot/contract-testing/-/merge_requests/1/diffs?diff_id=10581773",
+ "compare_path": "/gitlab-qa-bot/contract-testing/-/merge_requests/1/diffs?diff_id=10581773&start_sha=aee1ffec2299c0cfb17c8821e931339b73a3759f"
+ }
+ ],
+ "definition_path_prefix": "/gitlab-qa-bot/contract-testing/-/blob/aee1ffec2299c0cfb17c8821e931339b73a3759f",
+ "diff_files": [
+ {
+ "added_lines": 1,
+ "removed_lines": 1,
+ "new_path": "Gemfile",
+ "old_path": "Gemfile",
+ "new_file": false,
+ "deleted_file": false,
+ "submodule": false,
+ "file_identifier_hash": "67d82b8716a5b6c52c7abf0b2cd99c7594ed3587",
+ "file_hash": "de3150c01c3a946a6168173c4116741379fe3579"
+ }
+ ],
+ "has_conflicts": false,
+ "can_merge": false,
+ "project_path": "gitlab-qa-bot/contract-testing",
+ "project_name": "contract-testing"
+ },
+ "matchingRules": {
+ "$.body.real_size": {
+ "match": "type"
+ },
+ "$.body.size": {
+ "match": "type"
+ },
+ "$.body.branch_name": {
+ "match": "type"
+ },
+ "$.body.source_branch_exists": {
+ "match": "type"
+ },
+ "$.body.target_branch_name": {
+ "match": "type"
+ },
+ "$.body.merge_request_diff.created_at": {
+ "match": "regex",
+ "regex": "^\\d{4}-[01]\\d-[0-3]\\dT[0-2]\\d:[0-5]\\d:[0-5]\\d\\.\\d+([+-][0-2]\\d(:?[0-5]\\d)?|Z)$"
+ },
+ "$.body.merge_request_diff.commits_count": {
+ "match": "type"
+ },
+ "$.body.merge_request_diff.latest": {
+ "match": "type"
+ },
+ "$.body.merge_request_diff.short_commit_sha": {
+ "match": "type"
+ },
+ "$.body.merge_request_diff.base_version_path": {
+ "match": "type"
+ },
+ "$.body.merge_request_diff.head_version_path": {
+ "match": "type"
+ },
+ "$.body.merge_request_diff.version_path": {
+ "match": "type"
+ },
+ "$.body.merge_request_diff.compare_path": {
+ "match": "type"
+ },
+ "$.body.latest_diff": {
+ "match": "type"
+ },
+ "$.body.latest_version_path": {
+ "match": "type"
+ },
+ "$.body.added_lines": {
+ "match": "type"
+ },
+ "$.body.removed_lines": {
+ "match": "type"
+ },
+ "$.body.render_overflow_warning": {
+ "match": "type"
+ },
+ "$.body.email_patch_path": {
+ "match": "type"
+ },
+ "$.body.plain_diff_path": {
+ "match": "type"
+ },
+ "$.body.merge_request_diffs": {
+ "min": 1
+ },
+ "$.body.merge_request_diffs[*].*": {
+ "match": "type"
+ },
+ "$.body.merge_request_diffs[*].commits_count": {
+ "match": "type"
+ },
+ "$.body.merge_request_diffs[*].latest": {
+ "match": "type"
+ },
+ "$.body.merge_request_diffs[*].short_commit_sha": {
+ "match": "type"
+ },
+ "$.body.merge_request_diffs[*].base_version_path": {
+ "match": "type"
+ },
+ "$.body.merge_request_diffs[*].head_version_path": {
+ "match": "type"
+ },
+ "$.body.merge_request_diffs[*].version_path": {
+ "match": "type"
+ },
+ "$.body.merge_request_diffs[*].compare_path": {
+ "match": "type"
+ },
+ "$.body.definition_path_prefix": {
+ "match": "type"
+ },
+ "$.body.diff_files": {
+ "min": 1
+ },
+ "$.body.diff_files[*].*": {
+ "match": "type"
+ },
+ "$.body.diff_files[*].added_lines": {
+ "match": "type"
+ },
+ "$.body.diff_files[*].removed_lines": {
+ "match": "type"
+ },
+ "$.body.diff_files[*].new_path": {
+ "match": "type"
+ },
+ "$.body.diff_files[*].old_path": {
+ "match": "type"
+ },
+ "$.body.diff_files[*].new_file": {
+ "match": "type"
+ },
+ "$.body.diff_files[*].deleted_file": {
+ "match": "type"
+ },
+ "$.body.diff_files[*].submodule": {
+ "match": "type"
+ },
+ "$.body.diff_files[*].file_identifier_hash": {
+ "match": "type"
+ },
+ "$.body.diff_files[*].file_hash": {
+ "match": "type"
+ },
+ "$.body.has_conflicts": {
+ "match": "type"
+ },
+ "$.body.can_merge": {
+ "match": "type"
+ },
+ "$.body.project_path": {
+ "match": "type"
+ },
+ "$.body.project_name": {
+ "match": "type"
+ }
+ }
+ }
+ }
+ ],
+ "metadata": {
+ "pactSpecification": {
+ "version": "2.0.0"
+ }
+ }
+} \ No newline at end of file
diff --git a/qa/contracts/provider/environments/base.rb b/qa/contracts/provider/environments/base.rb
new file mode 100644
index 00000000000..695ee6b867d
--- /dev/null
+++ b/qa/contracts/provider/environments/base.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+module Provider
+ module Environments
+ class Base
+ attr_writer :base_url, :merge_request
+
+ def call(env)
+ @payload
+ end
+
+ def http(endpoint)
+ Faraday.default_adapter = :net_http
+ response = Faraday.get(@base_url + endpoint)
+ @payload = [response.status, response.headers, [response.body]]
+ self
+ end
+
+ def merge_request(endpoint)
+ http(@merge_request + endpoint) if endpoint.include? '.json'
+ end
+ end
+ end
+end
diff --git a/qa/contracts/provider/environments/local.rb b/qa/contracts/provider/environments/local.rb
new file mode 100644
index 00000000000..0d472bc25e9
--- /dev/null
+++ b/qa/contracts/provider/environments/local.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+module Provider
+ module Environments
+ class Local < Base
+ def initialize
+ @base_url = ENV['CONTRACT_HOST']
+ @merge_request = ENV['CONTRACT_MR']
+ end
+ end
+ end
+end
diff --git a/qa/contracts/provider/spec/diffs_helper.rb b/qa/contracts/provider/spec/diffs_helper.rb
new file mode 100644
index 00000000000..95dbc4254e6
--- /dev/null
+++ b/qa/contracts/provider/spec/diffs_helper.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+require_relative '../spec_helper'
+
+module Provider
+ module DiffsHelper
+ local = Environments::Local.new
+
+ Pact.service_provider "Merge Request Diffs Endpoint" do
+ app { local.merge_request('/diffs_batch.json?page=0') }
+
+ honours_pact_with 'Merge Request Page' do
+ pact_uri '../contracts/merge_request_page-merge_request_diffs_endpoint.json'
+ end
+ end
+ end
+end
diff --git a/qa/contracts/provider/spec/discussions_helper.rb b/qa/contracts/provider/spec/discussions_helper.rb
new file mode 100644
index 00000000000..642dde79e1d
--- /dev/null
+++ b/qa/contracts/provider/spec/discussions_helper.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+require_relative '../spec_helper'
+
+module Provider
+ module DiscussionsHelper
+ local = Environments::Local.new
+
+ Pact.service_provider "Merge Request Discussions Endpoint" do
+ app { local.merge_request('/discussions.json') }
+
+ honours_pact_with 'Merge Request Page' do
+ pact_uri '../contracts/merge_request_page-merge_request_discussions_endpoint.json'
+ end
+ end
+ end
+end
diff --git a/qa/contracts/provider/spec/metadata_helper.rb b/qa/contracts/provider/spec/metadata_helper.rb
new file mode 100644
index 00000000000..a3eb4978641
--- /dev/null
+++ b/qa/contracts/provider/spec/metadata_helper.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+require_relative '../spec_helper'
+
+module Provider
+ module MetadataHelper
+ local = Environments::Local.new
+
+ Pact.service_provider "Merge Request Metadata Endpoint" do
+ app { local.merge_request('/diffs_metadata.json') }
+
+ honours_pact_with 'Merge Request Page' do
+ pact_uri '../contracts/merge_request_page-merge_request_metadata_endpoint.json'
+ end
+ end
+ end
+end
diff --git a/qa/contracts/provider/spec_helper.rb b/qa/contracts/provider/spec_helper.rb
new file mode 100644
index 00000000000..1869c039910
--- /dev/null
+++ b/qa/contracts/provider/spec_helper.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+module SpecHelper
+ unless ENV['CONTRACT_HOST']
+ raise(ArgumentError, 'Contract tests require CONTRACT_HOST environment variable to be set!')
+ end
+
+ require_relative '../../../config/bundler_setup'
+ Bundler.require(:default)
+
+ root = File.expand_path('../', __dir__)
+
+ loader = Zeitwerk::Loader.new
+ loader.push_dir(root)
+
+ loader.ignore("#{root}/consumer")
+ loader.ignore("#{root}/contracts")
+
+ loader.collapse("#{root}/provider/spec")
+
+ loader.setup
+end
diff --git a/qa/knapsack/master_report.json b/qa/knapsack/master_report.json
index 0e9f67fa967..3880346a1b9 100644
--- a/qa/knapsack/master_report.json
+++ b/qa/knapsack/master_report.json
@@ -32,7 +32,6 @@
"qa/specs/features/ee/browser_ui/10_protect/policy_alerts_list_spec.rb": 14.055217947000074,
"qa/specs/features/browser_ui/3_create/snippet/create_personal_snippet_with_multiple_files_spec.rb": 14.212461153999811,
"qa/specs/features/ee/api/2_plan/epics_milestone_dates_spec.rb": 14.218627059000028,
- "qa/specs/features/browser_ui/1_manage/group/transfer_group_spec.rb": 14.295524570999987,
"qa/specs/features/api/1_manage/project_access_token_spec.rb": 14.394589879999785,
"qa/specs/features/ee/browser_ui/2_plan/multiple_assignees_for_issues/four_assignees_spec.rb": 14.505683429000328,
"qa/specs/features/browser_ui/2_plan/related_issues/related_issues_spec.rb": 14.804579386000114,
diff --git a/qa/qa.rb b/qa/qa.rb
index 442f6c578cf..73bcb6de637 100644
--- a/qa/qa.rb
+++ b/qa/qa.rb
@@ -11,6 +11,12 @@ require_relative 'lib/gitlab'
require_relative '../config/bundler_setup'
Bundler.require(:default)
+require 'securerandom'
+require 'pathname'
+require 'active_support/core_ext/hash'
+require 'active_support/core_ext/object/blank'
+require 'rainbow/refinement'
+
module QA
root = "#{__dir__}/qa"
@@ -53,7 +59,8 @@ module QA
"jira_api" => "JiraAPI",
"registry_tls" => "RegistryTLS",
"jetbrains" => "JetBrains",
- "vscode" => "VSCode"
+ "vscode" => "VSCode",
+ "registry_with_cdn" => "RegistryWithCDN"
)
loader.setup
diff --git a/qa/qa/git/location.rb b/qa/qa/git/location.rb
index 032c6837db1..c3733572e70 100644
--- a/qa/qa/git/location.rb
+++ b/qa/qa/git/location.rb
@@ -9,6 +9,7 @@ module QA
extend Forwardable
attr_reader :git_uri, :uri
+
def_delegators :@uri, :user, :host, :path
# See: config/initializers/1_settings.rb
diff --git a/qa/qa/page/component/new_snippet.rb b/qa/qa/page/component/new_snippet.rb
index 673bc7ba44c..6ccf8a4043e 100644
--- a/qa/qa/page/component/new_snippet.rb
+++ b/qa/qa/page/component/new_snippet.rb
@@ -77,7 +77,10 @@ module QA
def click_create_snippet_button
wait_until(reload: false) { !find_element(:submit_button).disabled? }
- click_element(:submit_button, Page::Dashboard::Snippet::Show)
+ click_element(:submit_button)
+ wait_until(reload: false) do
+ has_no_element?(:snippet_title_field)
+ end
end
private
diff --git a/qa/qa/page/component/snippet.rb b/qa/qa/page/component/snippet.rb
index 34e884f2a08..a8ae706858e 100644
--- a/qa/qa/page/component/snippet.rb
+++ b/qa/qa/page/component/snippet.rb
@@ -10,7 +10,7 @@ module QA
super
base.view 'app/assets/javascripts/snippets/components/snippet_title.vue' do
- element :snippet_title_content, required: true
+ element :snippet_title_content
end
base.view 'app/assets/javascripts/snippets/components/snippet_description_view.vue' do
@@ -87,7 +87,7 @@ module QA
end
def has_snippet_title?(snippet_title)
- has_element? :snippet_title_content, text: snippet_title
+ has_element?(:snippet_title_content, text: snippet_title, wait: 10)
end
def has_snippet_description?(snippet_description)
diff --git a/qa/qa/page/dashboard/projects.rb b/qa/qa/page/dashboard/projects.rb
index c0108d85365..a0b42598962 100644
--- a/qa/qa/page/dashboard/projects.rb
+++ b/qa/qa/page/dashboard/projects.rb
@@ -23,6 +23,12 @@ module QA
end
end
+ def filter_by_name(name)
+ within_element(:project_filter_form) do
+ fill_in :name, with: name
+ end
+ end
+
def go_to_project(name)
filter_by_name(name)
@@ -40,14 +46,6 @@ module QA
def clear_project_filter
fill_element(:project_filter_form, "")
end
-
- private
-
- def filter_by_name(name)
- within_element(:project_filter_form) do
- fill_in :name, with: name
- end
- end
end
end
end
diff --git a/qa/qa/page/dashboard/snippet/edit.rb b/qa/qa/page/dashboard/snippet/edit.rb
index 939413f6d76..d84a053591c 100644
--- a/qa/qa/page/dashboard/snippet/edit.rb
+++ b/qa/qa/page/dashboard/snippet/edit.rb
@@ -64,7 +64,10 @@ module QA
def save_changes
wait_until(reload: false) { !find_element(:submit_button).disabled? }
- click_element(:submit_button, Page::Dashboard::Snippet::Show)
+ click_element(:submit_button)
+ wait_until(reload: false) do
+ has_no_element?(:file_name_field)
+ end
end
private
diff --git a/qa/qa/page/dashboard/snippet/show.rb b/qa/qa/page/dashboard/snippet/show.rb
index a314f523108..f395bd4f8cb 100644
--- a/qa/qa/page/dashboard/snippet/show.rb
+++ b/qa/qa/page/dashboard/snippet/show.rb
@@ -9,7 +9,7 @@ module QA
include Page::Component::BlobContent
view 'app/assets/javascripts/snippets/components/snippet_title.vue' do
- element :snippet_title_content, required: true
+ element :snippet_title_content
end
end
end
diff --git a/qa/qa/page/file/show.rb b/qa/qa/page/file/show.rb
index e54c3e0cd07..7d6d81cf869 100644
--- a/qa/qa/page/file/show.rb
+++ b/qa/qa/page/file/show.rb
@@ -33,15 +33,10 @@ module QA
end
def click_edit
- # TODO: remove this condition and else part once ff :consolidated_edit_button is enabled by default
- if has_element?(:action_dropdown)
- within_element(:action_dropdown) do
- click_button(class: 'dropdown-toggle-split')
- click_element(:edit_menu_item)
- click_element(:edit_button)
- end
- else
- click_on 'Edit'
+ within_element(:action_dropdown) do
+ click_button(class: 'dropdown-toggle-split')
+ click_element(:edit_menu_item)
+ click_element(:edit_button)
end
end
diff --git a/qa/qa/page/group/settings/general.rb b/qa/qa/page/group/settings/general.rb
index 1877065f478..86585eee121 100644
--- a/qa/qa/page/group/settings/general.rb
+++ b/qa/qa/page/group/settings/general.rb
@@ -102,16 +102,6 @@ module QA
click_element(:save_permissions_changes_button)
end
-
- def transfer_group(target_group, source_group)
- expand_content :advanced_settings_content
-
- select_namespace(target_group)
- click_element(:transfer_button)
-
- fill_confirmation_text(source_group)
- confirm_transfer
- end
end
end
end
diff --git a/qa/qa/page/main/login.rb b/qa/qa/page/main/login.rb
index a5bd37be287..c34b8f33a5d 100644
--- a/qa/qa/page/main/login.rb
+++ b/qa/qa/page/main/login.rb
@@ -4,6 +4,8 @@ module QA
module Page
module Main
class Login < Page::Base
+ include Layout::Flash
+
view 'app/views/devise/passwords/edit.html.haml' do
element :password_field
element :password_confirmation_field
@@ -176,6 +178,9 @@ module QA
Support::WaitForRequests.wait_for_requests
+ # For debugging invalid login attempts
+ has_notice?('Invalid login or password')
+
Page::Main::Terms.perform do |terms|
terms.accept_terms if terms.visible?
end
diff --git a/qa/qa/page/merge_request/show.rb b/qa/qa/page/merge_request/show.rb
index d76dfb295a0..689b3dba286 100644
--- a/qa/qa/page/merge_request/show.rb
+++ b/qa/qa/page/merge_request/show.rb
@@ -116,7 +116,7 @@ module QA
end
view 'app/views/projects/merge_requests/_mr_box.html.haml' do
- element :title_content
+ element :title_content, required: true
end
view 'app/views/projects/merge_requests/_mr_title.html.haml' do
@@ -124,9 +124,9 @@ module QA
end
view 'app/views/projects/merge_requests/show.html.haml' do
- element :notes_tab
- element :commits_tab
- element :diffs_tab
+ element :notes_tab, required: true
+ element :commits_tab, required: true
+ element :diffs_tab, required: true
end
view 'app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_auto_merge_enabled.vue' do
diff --git a/qa/qa/page/modal/delete_issue.rb b/qa/qa/page/modal/delete_issue.rb
new file mode 100644
index 00000000000..9b51e969b48
--- /dev/null
+++ b/qa/qa/page/modal/delete_issue.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+module QA
+ module Page
+ module Modal
+ class DeleteIssue < Base
+ view 'app/assets/javascripts/issues/show/components/delete_issue_modal.vue' do
+ element :confirm_delete_issue_button, required: true
+ end
+
+ def confirm_delete_issue
+ click_element :confirm_delete_issue_button
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/page/project/fork/new.rb b/qa/qa/page/project/fork/new.rb
index cd743b648d8..e1b5e47dd0b 100644
--- a/qa/qa/page/project/fork/new.rb
+++ b/qa/qa/page/project/fork/new.rb
@@ -5,10 +5,6 @@ module QA
module Project
module Fork
class New < Page::Base
- view 'app/views/projects/forks/_fork_button.html.haml' do
- element :fork_namespace_button
- end
-
view 'app/assets/javascripts/pages/projects/forks/new/components/fork_form.vue' do
element :fork_namespace_dropdown
element :fork_project_button
@@ -16,13 +12,9 @@ module QA
end
def fork_project(namespace = Runtime::Namespace.path)
- if has_element?(:fork_namespace_button, wait: 0)
- click_element(:fork_namespace_button, name: namespace)
- else
- select_element(:fork_namespace_dropdown, namespace)
- click_element(:fork_privacy_button, privacy_level: 'public')
- click_element(:fork_project_button)
- end
+ select_element(:fork_namespace_dropdown, namespace)
+ click_element(:fork_privacy_button, privacy_level: 'public')
+ click_element(:fork_project_button)
end
def fork_namespace_dropdown_values
diff --git a/qa/qa/page/project/infrastructure/kubernetes/add.rb b/qa/qa/page/project/infrastructure/kubernetes/add.rb
deleted file mode 100644
index ed9ecb51a46..00000000000
--- a/qa/qa/page/project/infrastructure/kubernetes/add.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-# frozen_string_literal: true
-
-module QA
- module Page
- module Project
- module Infrastructure
- module Kubernetes
- class Add < Page::Base
- view 'app/views/clusters/clusters/new.html.haml' do
- element :add_existing_cluster_tab
- end
-
- def add_existing_cluster
- page.find('.gl-tab-nav-item', text: 'Connect existing cluster').click
- end
- end
- end
- end
- end
- end
-end
diff --git a/qa/qa/page/project/issue/show.rb b/qa/qa/page/project/issue/show.rb
index b37210f4d3f..fe468de60cd 100644
--- a/qa/qa/page/project/issue/show.rb
+++ b/qa/qa/page/project/issue/show.rb
@@ -18,6 +18,8 @@ module QA
view 'app/assets/javascripts/issues/show/components/header_actions.vue' do
element :close_issue_button
element :reopen_issue_button
+ element :issue_actions_ellipsis_dropdown
+ element :delete_issue_button
end
view 'app/assets/javascripts/related_issues/components/add_issuable_form.vue' do
@@ -69,6 +71,20 @@ module QA
def has_reopen_issue_button?
has_element?(:reopen_issue_button)
end
+
+ def has_delete_issue_button?
+ click_element(:issue_actions_ellipsis_dropdown)
+ has_element?(:delete_issue_button)
+ end
+
+ def delete_issue
+ click_element(:issue_actions_ellipsis_dropdown)
+ click_element(:delete_issue_button, Page::Modal::DeleteIssue)
+
+ Page::Modal::DeleteIssue.perform(&:confirm_delete_issue)
+
+ wait_for_requests
+ end
end
end
end
diff --git a/qa/qa/page/project/new.rb b/qa/qa/page/project/new.rb
index e061bc52abc..340e40127c9 100644
--- a/qa/qa/page/project/new.rb
+++ b/qa/qa/page/project/new.rb
@@ -13,11 +13,11 @@ module QA
view 'app/views/projects/_new_project_fields.html.haml' do
element :initialize_with_readme_checkbox
- element :project_name, 'text_field :name' # rubocop:disable QA/ElementWithPattern
- element :project_path, 'text_field :path' # rubocop:disable QA/ElementWithPattern
- element :project_description, 'text_area :description' # rubocop:disable QA/ElementWithPattern
- element :project_create_button, "submit _('Create project')" # rubocop:disable QA/ElementWithPattern
- element :visibility_radios, 'visibility_level:' # rubocop:disable QA/ElementWithPattern
+ element :project_name
+ element :project_path
+ element :project_description
+ element :project_create_button
+ element :visibility_radios
end
view 'app/views/projects/_new_project_initialize_with_sast.html.haml' do
diff --git a/qa/qa/page/project/pipeline_editor/new.rb b/qa/qa/page/project/pipeline_editor/new.rb
new file mode 100644
index 00000000000..5d79dd86f2a
--- /dev/null
+++ b/qa/qa/page/project/pipeline_editor/new.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+module QA
+ module Page
+ module Project
+ module PipelineEditor
+ class New < QA::Page::Base
+ view 'app/assets/javascripts/pipeline_editor/components/ui/pipeline_editor_empty_state.vue' do
+ element :create_new_ci_button, required: true
+ end
+
+ def create_new_ci
+ click_element(:create_new_ci_button, Page::Project::PipelineEditor::Show)
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/page/project/pipeline_editor/show.rb b/qa/qa/page/project/pipeline_editor/show.rb
index 8289039d4c5..caf54a10025 100644
--- a/qa/qa/page/project/pipeline_editor/show.rb
+++ b/qa/qa/page/project/pipeline_editor/show.rb
@@ -6,13 +6,13 @@ module QA
module PipelineEditor
class Show < QA::Page::Base
view 'app/assets/javascripts/pipeline_editor/components/file_nav/branch_switcher.vue' do
- element :branch_selector_button, require: true
+ element :branch_selector_button, required: true
element :branch_menu_item_button
element :branch_menu_container
end
view 'app/assets/javascripts/pipeline_editor/components/commit/commit_form.vue' do
- element :target_branch_field, require: true
+ element :target_branch_field, required: true
end
view 'app/assets/javascripts/pipeline_editor/components/drawer/pipeline_editor_drawer.vue' do
@@ -21,7 +21,7 @@ module QA
end
view 'app/assets/javascripts/vue_shared/components/source_editor.vue' do
- element :source_editor_container, require: true
+ element :source_editor_container, required: true
end
view 'app/assets/javascripts/pipeline_editor/components/header/pipeline_status.vue' do
@@ -30,6 +30,7 @@ module QA
view 'app/assets/javascripts/pipeline_editor/components/commit/commit_form.vue' do
element :commit_changes_button
+ element :new_mr_checkbox
end
view 'app/assets/javascripts/pipeline_editor/components/header/validation_segment.vue' do
@@ -76,6 +77,7 @@ module QA
end
def submit_changes
+ Support::Waiter.wait_until { !find_element(:commit_changes_button).disabled? }
click_element(:commit_changes_button)
wait_for_requests
@@ -127,6 +129,18 @@ module QA
end
end
+ def has_new_mr_checkbox?
+ has_element?(:new_mr_checkbox, visible: true)
+ end
+
+ def has_no_new_mr_checkbox?
+ has_no_element?(:new_mr_checkbox, visible: true)
+ end
+
+ def select_new_mr_checkbox
+ check_element(:new_mr_checkbox, true)
+ end
+
private
def go_to_tab(name)
diff --git a/qa/qa/page/project/settings/mirroring_repositories.rb b/qa/qa/page/project/settings/mirroring_repositories.rb
index 582079157f2..501b31f8a95 100644
--- a/qa/qa/page/project/settings/mirroring_repositories.rb
+++ b/qa/qa/page/project/settings/mirroring_repositories.rb
@@ -87,20 +87,21 @@ module QA
end
def update(url)
- row_index = find_repository_row_index url
+ row_index = find_repository_row_index(url)
within_element_by_index(:mirrored_repository_row, row_index) do
# When a repository is first mirrored, the update process might
# already be started, so the button is already "clicked"
click_element :update_now_button unless has_element? :updating_button
end
+ end
- # Wait a few seconds for the sync to occur and then refresh the page
- # so that 'last update' shows 'just now' or a period in seconds
- sleep 5
+ def verify_update(url)
refresh
- wait_until(max_duration: 180, sleep_interval: 1) do
+ row_index = find_repository_row_index(url)
+
+ wait_until(sleep_interval: 1) do
within_element_by_index(:mirrored_repository_row, row_index) do
last_update = find_element(:mirror_last_update_at_cell, wait: 0)
last_update.has_text?('just now') || last_update.has_text?('seconds')
diff --git a/qa/qa/page/project/show.rb b/qa/qa/page/project/show.rb
index 4c9df2716e2..b234a9ba986 100644
--- a/qa/qa/page/project/show.rb
+++ b/qa/qa/page/project/show.rb
@@ -121,6 +121,8 @@ module QA
end
def has_file?(name)
+ return false unless has_element?(:file_tree_table)
+
within_element(:file_tree_table) do
has_element?(:file_name_link, text: name)
end
diff --git a/qa/qa/page/project/web_ide/edit.rb b/qa/qa/page/project/web_ide/edit.rb
index 403c919c6e5..435cc4a717e 100644
--- a/qa/qa/page/project/web_ide/edit.rb
+++ b/qa/qa/page/project/web_ide/edit.rb
@@ -32,7 +32,7 @@ module QA
element :file_template_dropdown
end
- view 'app/assets/javascripts/ide/components/file_templates/dropdown.vue' do
+ view 'app/assets/javascripts/ide/components/file_templates/bar.vue' do
element :dropdown_filter_input
end
diff --git a/qa/qa/page/trials/new.rb b/qa/qa/page/trials/new.rb
index cd3b145a89e..40f593a7aa7 100644
--- a/qa/qa/page/trials/new.rb
+++ b/qa/qa/page/trials/new.rb
@@ -12,7 +12,7 @@ module QA
select :number_of_employees
text_field :telephone_number
select :country
- select :state, id: 'state'
+ select :state
button :continue
end
end
diff --git a/qa/qa/page/trials/select.rb b/qa/qa/page/trials/select.rb
index 3da0fb46322..39ef604a781 100644
--- a/qa/qa/page/trials/select.rb
+++ b/qa/qa/page/trials/select.rb
@@ -6,12 +6,11 @@ module QA
class Select < Chemlab::Page
path '/-/trials/select'
- # TODO: Supplant with data-qa-selectors
- select :subscription_for, id: 'namespace_id'
- text_field :new_group_name, id: 'new_group_name'
- button :start_your_free_trial, value: 'Start your free trial'
- radio :trial_company, id: 'trial_entity_company'
- radio :trial_individual, id: 'trial_entity_individual'
+ select :subscription_for
+ text_field :new_group_name
+ button :start_your_free_trial
+ radio :trial_company
+ radio :trial_individual
end
end
end
diff --git a/qa/qa/resource/api_fabricator.rb b/qa/qa/resource/api_fabricator.rb
index 1958884916c..79cb1ebebc9 100644
--- a/qa/qa/resource/api_fabricator.rb
+++ b/qa/qa/resource/api_fabricator.rb
@@ -54,7 +54,7 @@ module QA
body)
unless response.code == HTTP_STATUS_OK
- raise ResourceFabricationFailedError, "Updating #{self.class.name} using the API failed (#{response.code}) with `#{response}`."
+ raise ResourceFabricationFailedError, "Updating #{self.class.name} using the API failed (#{response.code}) with `#{response}`.\n#{QA::Support::Loglinking.failure_metadata(response.headers[:x_request_id])}"
end
process_api_response(parse_body(response))
@@ -91,9 +91,9 @@ module QA
response = get(request.url)
if response.code == HTTP_STATUS_SERVER_ERROR
- raise InternalServerError, "Failed to GET #{request.mask_url} - (#{response.code}): `#{response}`."
+ raise InternalServerError, "Failed to GET #{request.mask_url} - (#{response.code}): `#{response}`.\n#{QA::Support::Loglinking.failure_metadata(response.headers[:x_request_id])}"
elsif response.code != HTTP_STATUS_OK
- raise ResourceNotFoundError, "Resource at #{request.mask_url} could not be found (#{response.code}): `#{response}`."
+ raise ResourceNotFoundError, "Resource at #{request.mask_url} could not be found (#{response.code}): `#{response}`.\n#{QA::Support::Loglinking.failure_metadata(response.headers[:x_request_id])}"
end
@api_fabrication_http_method = :get # rubocop:disable Gitlab/ModuleWithInstanceVariables
@@ -114,6 +114,7 @@ module QA
unless graphql_response.code == HTTP_STATUS_OK && (body[:errors].nil? || body[:errors].empty?)
raise(ResourceFabricationFailedError, <<~MSG)
Fabrication of #{self.class.name} using the API failed (#{graphql_response.code}) with `#{graphql_response}`.
+ #{QA::Support::Loglinking.failure_metadata(graphql_response.headers[:x_request_id])}
MSG
end
@@ -126,7 +127,7 @@ module QA
unless response.code == HTTP_STATUS_CREATED
raise(
ResourceFabricationFailedError,
- "Fabrication of #{self.class.name} using the API failed (#{response.code}) with `#{response}`."
+ "Fabrication of #{self.class.name} using the API failed (#{response.code}) with `#{response}`.\n#{QA::Support::Loglinking.failure_metadata(response.headers[:x_request_id])}"
)
end
@@ -145,7 +146,7 @@ module QA
response = delete(request.url)
unless [HTTP_STATUS_NO_CONTENT, HTTP_STATUS_ACCEPTED].include? response.code
- raise ResourceNotDeletedError, "Resource at #{request.mask_url} could not be deleted (#{response.code}): `#{response}`."
+ raise ResourceNotDeletedError, "Resource at #{request.mask_url} could not be deleted (#{response.code}): `#{response}`.\n#{QA::Support::Loglinking.failure_metadata(response.headers[:x_request_id])}"
end
response
@@ -165,6 +166,14 @@ module QA
def transform_api_resource(api_resource)
api_resource
end
+
+ # Get api request url
+ #
+ # @param [String] path
+ # @return [String]
+ def request_url(path, **opts)
+ Runtime::API::Request.new(api_client, path, **opts).url
+ end
end
end
end
diff --git a/qa/qa/resource/deploy_key.rb b/qa/qa/resource/deploy_key.rb
index 26355729dab..c06671be77d 100644
--- a/qa/qa/resource/deploy_key.rb
+++ b/qa/qa/resource/deploy_key.rb
@@ -5,6 +5,8 @@ module QA
class DeployKey < Base
attr_accessor :title, :key
+ attribute :id
+
attribute :md5_fingerprint do
Page::Project::Settings::Repository.perform do |setting|
setting.expand_deploy_keys do |key|
@@ -34,6 +36,46 @@ module QA
end
end
end
+
+ def fabricate_via_api!
+ resource_web_url(api_get)
+ rescue ResourceNotFoundError
+ super
+ end
+
+ def resource_web_url(resource)
+ super
+ rescue ResourceURLMissingError
+ # this particular resource does not expose a web_url property
+ end
+
+ def api_get_path
+ "/projects/#{project.id}/deploy_keys/#{find_id}"
+ end
+
+ def api_post_path
+ "/projects/#{project.id}/deploy_keys"
+ end
+
+ def api_post_body
+ {
+ key: key,
+ title: title
+ }
+ end
+
+ private
+
+ def find_id
+ id
+ rescue NoValueError
+ found_key = auto_paginated_response(request_url("/projects/#{project.id}/deploy_keys", per_page: '100'))
+ .find { |keys| keys[:key].strip == @key.strip }
+
+ return found_key.fetch(:id) if found_key
+
+ raise ResourceNotFoundError
+ end
end
end
end
diff --git a/qa/qa/resource/fork.rb b/qa/qa/resource/fork.rb
index d60b90b534f..0e6dd626312 100644
--- a/qa/qa/resource/fork.rb
+++ b/qa/qa/resource/fork.rb
@@ -95,7 +95,7 @@ module QA
def wait_until_forked
Runtime::Logger.debug("Waiting for the fork process to complete...")
forked = wait_until do
- project.import_status == "finished"
+ project.reload!.import_status == "finished"
end
raise "Timed out while waiting for the fork process to complete." unless forked
diff --git a/qa/qa/resource/group.rb b/qa/qa/resource/group.rb
index dee63f9699c..c3da9d47de5 100644
--- a/qa/qa/resource/group.rb
+++ b/qa/qa/resource/group.rb
@@ -10,7 +10,11 @@ module QA
end
attribute :name do
- @name || path
+ @name || @path || Runtime::Namespace.name
+ end
+
+ attribute :path do
+ @path || @name || Runtime::Namespace.name
end
attribute :sandbox do
@@ -20,7 +24,6 @@ module QA
end
def initialize
- @path = Runtime::Namespace.name
@description = "QA test run at #{Runtime::Namespace.time}"
@require_two_factor_authentication = false
end
@@ -64,7 +67,7 @@ module QA
{
parent_id: sandbox.id,
path: path,
- name: name || path,
+ name: name,
visibility: 'public',
require_two_factor_authentication: @require_two_factor_authentication,
avatar: avatar
diff --git a/qa/qa/resource/group_base.rb b/qa/qa/resource/group_base.rb
index 05b41a4b4f6..889197a0373 100644
--- a/qa/qa/resource/group_base.rb
+++ b/qa/qa/resource/group_base.rb
@@ -64,6 +64,10 @@ module QA
end
end
+ def marked_for_deletion?
+ reload!.api_response[:marked_for_deletion_on].present?
+ end
+
# Get group badges
#
# @return [Array<QA::Resource::GroupBadge>]
@@ -80,22 +84,6 @@ module QA
end
end
- # Get group members
- #
- # @return [Array<QA::Resource::User>]
- def members
- parse_body(api_get_from("#{api_get_path}/members")).map do |member|
- User.init do |resource|
- resource.api_client = api_client
- resource.id = member[:id]
- resource.name = member[:name]
- resource.username = member[:username]
- resource.email = member[:email]
- resource.access_level = member[:access_level]
- end
- end
- end
-
# API get path
#
# @return [String]
diff --git a/qa/qa/resource/kubernetes_cluster/project_cluster.rb b/qa/qa/resource/kubernetes_cluster/project_cluster.rb
index 0a63ff47694..0443b26064e 100644
--- a/qa/qa/resource/kubernetes_cluster/project_cluster.rb
+++ b/qa/qa/resource/kubernetes_cluster/project_cluster.rb
@@ -26,9 +26,6 @@ module QA
Page::Project::Infrastructure::Kubernetes::Index.perform(
&:connect_existing_cluster)
- Page::Project::Infrastructure::Kubernetes::Add.perform(
- &:add_existing_cluster)
-
Page::Project::Infrastructure::Kubernetes::AddExisting.perform do |cluster_page|
cluster_page.set_cluster_name(@cluster.cluster_name)
cluster_page.set_api_url(@cluster.api_url)
diff --git a/qa/qa/resource/project.rb b/qa/qa/resource/project.rb
index c5b72eebe03..740a8920cf2 100644
--- a/qa/qa/resource/project.rb
+++ b/qa/qa/resource/project.rb
@@ -262,7 +262,7 @@ module QA
reload!.api_response[:default_branch] || Runtime::Env.default_branch
end
- def import_status
+ def project_import_status
response = get(request_url("/projects/#{id}/import"))
unless response.code == HTTP_STATUS_OK
@@ -276,7 +276,7 @@ module QA
Runtime::Logger.error("Failed relations: #{result[:failed_relations]}")
end
- result[:import_status]
+ result
end
def commits(auto_paginate: false, attempts: 0)
@@ -373,6 +373,30 @@ module QA
api_post_to(api_wikis_path, title: title, content: content)
end
+ # Uses the API to wait until a pull mirroring update is successful (pull mirroring is treated as an import)
+ def wait_for_pull_mirroring
+ mirror_succeeded = Support::Retrier.retry_until(max_duration: 180, raise_on_failure: false, sleep_interval: 1) do
+ reload!
+ api_resource[:import_status] == "finished"
+ end
+
+ unless mirror_succeeded
+ raise "Mirroring failed with error: #{api_resource[:import_error]}"
+ end
+ end
+
+ def remove_via_api!
+ super
+
+ Support::Retrier.retry_until(max_duration: 60, sleep_interval: 1, message: "Waiting for #{self.class.name} to be removed") do
+ !exists?
+ rescue InternalServerError
+ # Retry on transient errors that are likely to be due to race conditions between concurrent delete operations
+ # when parts of a resource are stored in multiple tables
+ false
+ end
+ end
+
protected
# Return subset of fields for comparing projects
@@ -407,14 +431,6 @@ module QA
Git::Location.new(api_resource[:http_url_to_repo])
api_resource
end
-
- # Get api request url
- #
- # @param [String] path
- # @return [String]
- def request_url(path, **opts)
- Runtime::API::Request.new(api_client, path, **opts).url
- end
end
end
end
diff --git a/qa/qa/resource/protected_branch.rb b/qa/qa/resource/protected_branch.rb
index 062d4e9f3d8..55ad6edb3c1 100644
--- a/qa/qa/resource/protected_branch.rb
+++ b/qa/qa/resource/protected_branch.rb
@@ -72,6 +72,16 @@ module QA
self.remove_via_api!(&block)
end
+ # Remove the branch protection after confirming that it exists
+ def remove_via_api!
+ Support::Retrier.retry_until(max_duration: 60, sleep_interval: 1, message: "Waiting for branch #{branch_name} to be protected") do
+ # We confirm it exists before removal because there's no creation event when the default branch is automatically protected by GitLab itself, and there's a slight delay between creating the repo and protecting the default branch
+ exists?
+ end
+
+ super
+ end
+
def api_get_path
"/projects/#{project.id}/protected_branches/#{branch_name}"
end
diff --git a/qa/qa/resource/reusable_collection.rb b/qa/qa/resource/reusable_collection.rb
index 1168b0091fc..99a55800d1c 100644
--- a/qa/qa/resource/reusable_collection.rb
+++ b/qa/qa/resource/reusable_collection.rb
@@ -35,6 +35,10 @@ module QA
instance.each_resource do |reuse_as, resource|
next QA::Runtime::Logger.debug("#{resource.class.name} reused as :#{reuse_as} has already been removed.") unless resource.exists?
+ if resource.respond_to?(:marked_for_deletion?) && resource.marked_for_deletion?
+ next QA::Runtime::Logger.debug("#{resource.class.name} reused as :#{reuse_as} is already scheduled to be removed.")
+ end
+
resource.method(:remove_via_api!).super_method.call
end
end
diff --git a/qa/qa/resource/reusable_group.rb b/qa/qa/resource/reusable_group.rb
index b75cb0517bf..05ff38249f6 100644
--- a/qa/qa/resource/reusable_group.rb
+++ b/qa/qa/resource/reusable_group.rb
@@ -8,7 +8,7 @@ module QA
def initialize
super
- @name = @path = 'reusable_group'
+ @name = @path = QA::Runtime::Env.reusable_group_path
@description = "QA reusable group"
@reuse_as = :default_group
end
diff --git a/qa/qa/resource/reusable_project.rb b/qa/qa/resource/reusable_project.rb
index b9fca314122..8a12c25b6f0 100644
--- a/qa/qa/resource/reusable_project.rb
+++ b/qa/qa/resource/reusable_project.rb
@@ -15,7 +15,7 @@ module QA
super
@add_name_uuid = false
- @name = @path = 'reusable_project'
+ @name = @path = QA::Runtime::Env.reusable_project_path
@reuse_as = :default_project
@initialize_with_readme = true
end
diff --git a/qa/qa/resource/runner.rb b/qa/qa/resource/runner.rb
index e69702a8ffa..9c5c9992442 100644
--- a/qa/qa/resource/runner.rb
+++ b/qa/qa/resource/runner.rb
@@ -47,9 +47,8 @@ module QA
def remove_via_api!
runners = project.runners(tag_list: @tags)
- unless runners && !runners.empty?
- raise "Project #{project.path_with_namespace} has no runners#{" with tags #{@tags}." if @tags&.any?}"
- end
+
+ return if runners.blank?
this_runner = runners.find { |runner| runner[:description] == name }
unless this_runner
diff --git a/qa/qa/runtime/allure_report.rb b/qa/qa/runtime/allure_report.rb
index 9ae04dbe111..10f47ca56ba 100644
--- a/qa/qa/runtime/allure_report.rb
+++ b/qa/qa/runtime/allure_report.rb
@@ -74,8 +74,8 @@ module QA
# @return [void]
def configure_rspec
RSpec.configure do |config|
- config.add_formatter(AllureRspecFormatter)
config.add_formatter(QA::Support::Formatters::AllureMetadataFormatter)
+ config.add_formatter(AllureRspecFormatter)
config.append_after do |example|
Allure.add_attachment(
diff --git a/qa/qa/runtime/api/client.rb b/qa/qa/runtime/api/client.rb
index b5b572890c1..5ca3b0c51f8 100644
--- a/qa/qa/runtime/api/client.rb
+++ b/qa/qa/runtime/api/client.rb
@@ -8,12 +8,11 @@ module QA
AuthorizationError = Class.new(RuntimeError)
- def initialize(address = :gitlab, personal_access_token: nil, is_new_session: true, user: nil, ip_limits: false)
+ def initialize(address = :gitlab, personal_access_token: nil, is_new_session: true, user: nil)
@address = address
@personal_access_token = personal_access_token
@is_new_session = is_new_session
@user = user
- enable_ip_limits if ip_limits
end
# Personal access token
@@ -68,24 +67,6 @@ module QA
private
- def enable_ip_limits
- Page::Main::Menu.perform(&:sign_out) if Page::Main::Menu.perform { |p| p.has_personal_area?(wait: 0) }
-
- Runtime::Browser.visit(@address, Page::Main::Login)
- Page::Main::Login.perform(&:sign_in_using_admin_credentials)
- Page::Main::Menu.perform(&:go_to_admin_area)
- Page::Admin::Menu.perform(&:go_to_network_settings)
-
- Page::Admin::Settings::Network.perform do |setting|
- setting.expand_ip_limits do |page|
- page.enable_throttles
- page.save_settings
- end
- end
-
- Page::Main::Menu.perform(&:sign_out)
- end
-
# Create PAT
#
# Use api if admin personal access token is present and skip any UI actions otherwise perform creation via UI
diff --git a/qa/qa/runtime/env.rb b/qa/qa/runtime/env.rb
index 088822cc2ca..63207751c78 100644
--- a/qa/qa/runtime/env.rb
+++ b/qa/qa/runtime/env.rb
@@ -404,6 +404,14 @@ module QA
ENV.fetch('GITLAB_QA_LOOP_RUNNER_MINUTES', 1).to_i
end
+ def reusable_project_path
+ ENV.fetch('QA_REUSABLE_PROJECT_PATH', 'reusable_project')
+ end
+
+ def reusable_group_path
+ ENV.fetch('QA_REUSABLE_GROUP_PATH', 'reusable_group')
+ end
+
def mailhog_hostname
ENV['MAILHOG_HOSTNAME']
end
@@ -441,11 +449,6 @@ module QA
running_in_ci? && enabled?(ENV['QA_EXPORT_TEST_METRICS'], default: true)
end
- def test_resources_created_filepath
- file_name = running_in_ci? ? "test-resources-#{SecureRandom.hex(3)}.json" : 'test-resources.json'
- ENV.fetch('QA_TEST_RESOURCES_CREATED_FILEPATH', File.join(Path.qa_root, 'tmp', file_name))
- end
-
def ee_activation_code
ENV['QA_EE_ACTIVATION_CODE']
end
@@ -458,6 +461,10 @@ module QA
enabled?(ENV['QA_VALIDATE_RESOURCE_REUSE'], default: false)
end
+ def skip_smoke_reliable?
+ enabled?(ENV['QA_SKIP_SMOKE_RELIABLE'], default: false)
+ end
+
private
def remote_grid_credentials
diff --git a/qa/qa/runtime/logger.rb b/qa/qa/runtime/logger.rb
index 81c41000033..1f17146303a 100644
--- a/qa/qa/runtime/logger.rb
+++ b/qa/qa/runtime/logger.rb
@@ -1,33 +1,19 @@
# frozen_string_literal: true
-require 'logger'
require 'forwardable'
-require 'rainbow/refinement'
module QA
module Runtime
- module Logger
+ class Logger
extend SingleForwardable
- using Rainbow
def_delegators :logger, :debug, :info, :warn, :error, :fatal, :unknown
- singleton_class.module_eval do
- attr_writer :logger
-
- def logger
- Rainbow.enabled = Runtime::Env.colorized_logs?
-
- @logger ||= ::Logger.new(Runtime::Env.log_destination).tap do |logger|
- logger.level = Runtime::Env.debug? ? ::Logger::DEBUG : ::Logger::ERROR
-
- logger.formatter = proc do |severity, datetime, progname, msg|
- date_format = datetime.strftime("%Y-%m-%d %H:%M:%S")
-
- "[date=#{date_format} from=QA Tests] #{severity.ljust(5)} -- ".yellow + "#{msg}\n"
- end
- end
- end
+ def self.logger
+ @logger ||= Gitlab::QA::TestLogger.logger(
+ level: Runtime::Env.debug? ? ::Logger::DEBUG : ::Logger::INFO,
+ source: 'QA Tests'
+ )
end
end
end
diff --git a/qa/qa/scenario/test/integration/object_storage_gcs.rb b/qa/qa/scenario/test/integration/object_storage_gcs.rb
new file mode 100644
index 00000000000..81e56c9316f
--- /dev/null
+++ b/qa/qa/scenario/test/integration/object_storage_gcs.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+module QA
+ module Scenario
+ module Test
+ module Integration
+ class ObjectStorageGcs < Test::Instance::All
+ tags :object_storage
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/scenario/test/integration/registry_with_cdn.rb b/qa/qa/scenario/test/integration/registry_with_cdn.rb
new file mode 100644
index 00000000000..87114d3c203
--- /dev/null
+++ b/qa/qa/scenario/test/integration/registry_with_cdn.rb
@@ -0,0 +1,14 @@
+# rubocop:todo Naming/FileName
+# frozen_string_literal: true
+
+module QA
+ module Scenario
+ module Test
+ module Integration
+ class RegistryWithCDN < Test::Instance::All
+ tags :registry
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/service/praefect_manager.rb b/qa/qa/service/praefect_manager.rb
index 8ffb7c47652..c364b00629c 100644
--- a/qa/qa/service/praefect_manager.rb
+++ b/qa/qa/service/praefect_manager.rb
@@ -327,6 +327,22 @@ module QA
end
end
+ def accept_dataloss_for_project(project_id, authoritative_storage)
+ repository_hash = "#{Digest::SHA256.hexdigest(project_id.to_s)}"
+ repository = "@hashed/#{repository_hash[0, 2]}/#{repository_hash[2, 2]}/#{repository_hash}.git"
+
+ cmd = %{
+ docker exec #{@praefect} \
+ praefect \
+ -config /var/opt/gitlab/praefect/config.toml \
+ accept-dataloss \
+ --virtual-storage=default \
+ --repository=#{repository} \
+ --authoritative-storage=#{authoritative_storage}
+ }
+ shell(cmd)
+ end
+
def wait_for_health_check_all_nodes
wait_for_gitaly_health_check(@primary_node)
wait_for_gitaly_health_check(@secondary_node)
@@ -415,6 +431,27 @@ module QA
Support::Waiter.wait_until(sleep_interval: 1) { replication_queue_incomplete_count == 0 && replicated?(project_id) }
end
+ def wait_for_replication_to_node(project_id, node)
+ Support::Waiter.wait_until(sleep_interval: 1) do
+ result = []
+ shell sql_to_docker_exec_cmd(%{
+ select * from replication_queue
+ where state = 'ready'
+ and job ->> 'change' = 'update'
+ and job ->> 'target_node_storage' = '#{node}'
+ and job ->> 'relative_path' = '#{Digest::SHA256.hexdigest(project_id.to_s)}.git';
+ }) do |line|
+ result << line.strip
+ QA::Runtime::Logger.debug(line.strip)
+ end
+ # The result should look like this when all items are replicated
+ # id | state | created_at | updated_at | attempt | lock_id | job | meta
+ # ----+-------+------------+------------+---------+---------+-----+------
+ # (0 rows)
+ result[2] == '(0 rows)'
+ end
+ end
+
def replication_pending?
result = []
shell sql_to_docker_exec_cmd(
diff --git a/qa/qa/specs/features/api/1_manage/import_github_repo_spec.rb b/qa/qa/specs/features/api/1_manage/import_github_repo_spec.rb
index a51d733d484..c39db63f64d 100644
--- a/qa/qa/specs/features/api/1_manage/import_github_repo_spec.rb
+++ b/qa/qa/specs/features/api/1_manage/import_github_repo_spec.rb
@@ -2,7 +2,7 @@
module QA
RSpec.describe 'Manage', :github, :requires_admin, :reliable do
- describe 'Project import' do
+ describe 'Project import', issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/353583' do
let!(:api_client) { Runtime::API::Client.as_admin }
let!(:group) { Resource::Group.fabricate_via_api! { |resource| resource.api_client = api_client } }
let!(:user) do
@@ -17,7 +17,7 @@ module QA
project.name = 'imported-project'
project.group = group
project.github_personal_access_token = Runtime::Env.github_access_token
- project.github_repository_path = 'gitlab-qa-github/test-project'
+ project.github_repository_path = 'gitlab-qa-github/import-test'
project.api_client = api_client
end
end
@@ -31,11 +31,13 @@ module QA
end
it 'imports Github repo via api', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347670' do
- imported_project # import the project
+ imported_project.reload! # import the project
- expect { imported_project.reload!.import_status }.to eventually_eq('finished').within(max_duration: 90)
+ expect { imported_project.project_import_status[:import_status] }.to eventually_eq('finished')
+ .within(max_duration: 90, sleep_interval: 1)
aggregate_failures do
+ verify_status_data
verify_repository_import
verify_commits_import
verify_labels_import
@@ -46,15 +48,29 @@ module QA
end
end
+ def verify_status_data
+ stats = imported_project.project_import_status.dig(:stats, :imported)
+ expect(stats).to include(
+ # issue: 2,
+ label: 9,
+ milestone: 1,
+ note: 3,
+ pull_request: 1,
+ pull_request_review: 1,
+ diff_note: 1,
+ release: 1
+ )
+ end
+
def verify_repository_import
expect(imported_project.api_response).to include(
- description: 'A new repo for test',
+ description: 'Project for github import test',
import_error: nil
)
end
def verify_commits_import
- expect(imported_project.commits.length).to eq(20)
+ expect(imported_project.commits.length).to eq(2)
end
def verify_labels_import
@@ -62,7 +78,6 @@ module QA
expect(labels).to include(
{ name: 'bug', color: '#d73a4a' },
- { name: 'custom new label', color: '#fc8f91' },
{ name: 'documentation', color: '#0075ca' },
{ name: 'duplicate', color: '#cfd3d7' },
{ name: 'enhancement', color: '#a2eeef' },
@@ -79,10 +94,10 @@ module QA
expect(issues.length).to eq(1)
expect(issues.first).to include(
- title: 'This is a sample issue',
- description: "*Created by: gitlab-qa-github*\n\nThis is a sample first comment",
- labels: ['custom new label', 'good first issue', 'help wanted'],
- user_notes_count: 1
+ title: 'Test issue',
+ description: "*Created by: gitlab-qa-github*\n\nTest issue description",
+ labels: ['good first issue', 'help wanted', 'question'],
+ user_notes_count: 2
)
end
@@ -90,7 +105,7 @@ module QA
milestones = imported_project.milestones
expect(milestones.length).to eq(1)
- expect(milestones.first).to include(title: 'v1.0', description: nil, state: 'active')
+ expect(milestones.first).to include(title: '0.0.1', description: nil, state: 'active')
end
def verify_wikis_import
@@ -111,20 +126,20 @@ module QA
expect(merge_requests.length).to eq(1)
expect(merge_request.api_resource).to include(
- title: 'Improve readme',
+ title: 'Test pull request',
state: 'opened',
target_branch: 'main',
- source_branch: 'improve-readme',
- labels: %w[bug documentation],
+ source_branch: 'gitlab-qa-github-patch-1',
+ labels: %w[documentation],
description: <<~DSC.strip
- *Created by: gitlab-qa-github*\n\nThis improves the README file a bit.\r\n\r\nTODO:\r\n\r\n \r\n\r\n- [ ] Do foo\r\n- [ ] Make bar\r\n - [ ] Think about baz
+ *Created by: gitlab-qa-github*\n\nTest pull request body
DSC
)
- expect(mr_comments).to eq(
+ expect(mr_comments).to match_array(
[
- "*Created by: gitlab-qa-github*\n\n[PR comment by @sliaquat] Nice work! ",
- "*Created by: gitlab-qa-github*\n\n[Single diff comment] Nice addition",
- "*Created by: gitlab-qa-github*\n\n[Single diff comment] Good riddance"
+ "*Created by: gitlab-qa-github*\n\n**Review:** Commented\n\nGood but needs some improvement",
+ "*Created by: gitlab-qa-github*\n\n```suggestion:-0+0\nProject for GitHub import test to GitLab\r\n```",
+ "*Created by: gitlab-qa-github*\n\nSome test PR comment"
]
)
end
diff --git a/qa/qa/specs/features/api/1_manage/import_large_github_repo_spec.rb b/qa/qa/specs/features/api/1_manage/import_large_github_repo_spec.rb
index c46de0ac514..84eda023576 100644
--- a/qa/qa/specs/features/api/1_manage/import_large_github_repo_spec.rb
+++ b/qa/qa/specs/features/api/1_manage/import_large_github_repo_spec.rb
@@ -3,11 +3,16 @@
# rubocop:disable Rails/Pluck
module QA
# Only executes in custom job/pipeline
+ # https://gitlab.com/gitlab-org/manage/import/import-github-performance
+ #
RSpec.describe 'Manage', :github, :requires_admin, only: { job: 'large-github-import' } do
describe 'Project import' do
let(:logger) { Runtime::Logger.logger }
let(:differ) { RSpec::Support::Differ.new(color: true) }
+ let(:created_by_pattern) { /\*Created by: \S+\*\n\n/ }
+ let(:suggestion_pattern) { /suggestion:-\d+\+\d+/ }
+
let(:api_client) { Runtime::API::Client.as_admin }
let(:user) do
@@ -19,46 +24,57 @@ module QA
let(:github_repo) { ENV['QA_LARGE_GH_IMPORT_REPO'] || 'rspec/rspec-core' }
let(:import_max_duration) { ENV['QA_LARGE_GH_IMPORT_DURATION'] ? ENV['QA_LARGE_GH_IMPORT_DURATION'].to_i : 7200 }
let(:github_client) do
- Octokit.middleware = Faraday::RackBuilder.new do |builder|
- builder.response(:logger, logger, headers: false, bodies: false)
- end
-
Octokit::Client.new(
access_token: ENV['QA_LARGE_GH_IMPORT_GH_TOKEN'] || Runtime::Env.github_access_token,
auto_paginate: true
)
end
- let(:gh_branches) { github_client.branches(github_repo).map(&:name) }
- let(:gh_commits) { github_client.commits(github_repo).map(&:sha) }
let(:gh_repo) { github_client.repository(github_repo) }
+ let(:gh_branches) do
+ logger.debug("= Fetching branches =")
+ github_client.branches(github_repo).map(&:name)
+ end
+
+ let(:gh_commits) do
+ logger.debug("= Fetching commits =")
+ github_client.commits(github_repo).map(&:sha)
+ end
+
let(:gh_labels) do
+ logger.debug("= Fetching labels =")
github_client.labels(github_repo).map { |label| { name: label.name, color: "##{label.color}" } }
end
let(:gh_milestones) do
+ logger.debug("= Fetching milestones =")
github_client
.list_milestones(github_repo, state: 'all')
.map { |ms| { title: ms.title, description: ms.description } }
end
let(:gh_all_issues) do
+ logger.debug("= Fetching issues and prs =")
github_client.list_issues(github_repo, state: 'all')
end
let(:gh_prs) do
gh_all_issues.select(&:pull_request).each_with_object({}) do |pr, hash|
- hash[pr.title] = {
+ hash[pr.number] = {
+ url: pr.html_url,
+ title: pr.title,
body: pr.body || '',
- comments: [*gh_pr_comments[pr.html_url], *gh_issue_comments[pr.html_url]].compact.sort
+ comments: [*gh_pr_comments[pr.html_url], *gh_issue_comments[pr.html_url]].compact
}
end
end
let(:gh_issues) do
gh_all_issues.reject(&:pull_request).each_with_object({}) do |issue, hash|
- hash[issue.title] = {
+ hash[issue.number] = {
+ url: issue.html_url,
+ title: issue.title,
body: issue.body || '',
comments: gh_issue_comments[issue.html_url]
}
@@ -66,12 +82,14 @@ module QA
end
let(:gh_issue_comments) do
+ logger.debug("= Fetching issue comments =")
github_client.issues_comments(github_repo).each_with_object(Hash.new { |h, k| h[k] = [] }) do |c, hash|
hash[c.html_url.gsub(/\#\S+/, "")] << c.body # use base html url as key
end
end
let(:gh_pr_comments) do
+ logger.debug("= Fetching pr comments =")
github_client.pull_requests_comments(github_repo).each_with_object(Hash.new { |h, k| h[k] = [] }) do |c, hash|
hash[c.html_url.gsub(/\#\S+/, "")] << c.body # use base html url as key
end
@@ -97,25 +115,34 @@ module QA
"data",
{
import_time: @import_time,
+ reported_stats: @stats,
github: {
project_name: github_repo,
- branches: gh_branches,
- commits: gh_commits,
- labels: gh_labels,
- milestones: gh_milestones,
- prs: gh_prs,
- issues: gh_issues
+ branches: gh_branches.length,
+ commits: gh_commits.length,
+ labels: gh_labels.length,
+ milestones: gh_milestones.length,
+ prs: gh_prs.length,
+ pr_comments: gh_prs.sum { |_k, v| v[:comments].length },
+ issues: gh_issues.length,
+ issue_comments: gh_issues.sum { |_k, v| v[:comments].length }
},
gitlab: {
project_name: imported_project.path_with_namespace,
- branches: gl_branches,
- commits: gl_commits,
- labels: gl_labels,
- milestones: gl_milestones,
- mrs: mrs,
- issues: gl_issues
+ branches: gl_branches.length,
+ commits: gl_commits.length,
+ labels: gl_labels.length,
+ milestones: gl_milestones.length,
+ mrs: mrs.length,
+ mr_comments: mrs.sum { |_k, v| v[:comments].length },
+ issues: gl_issues.length,
+ issue_comments: gl_issues.sum { |_k, v| v[:comments].length }
+ },
+ not_imported: {
+ mrs: @mr_diff,
+ issues: @issue_diff
}
- }.to_json
+ }
)
end
@@ -125,15 +152,25 @@ module QA
) do
start = Time.now
- Runtime::Logger.info("Importing project '#{imported_project.full_path}'") # import the project and log path
- fetch_github_objects # fetch all objects right after import has started
+ # import the project and log gitlab path
+ Runtime::Logger.info("== Importing project '#{github_repo}' in to '#{imported_project.reload!.full_path}' ==")
+ # fetch all objects right after import has started
+ fetch_github_objects
import_status = lambda do
- imported_project.reload!.import_status.tap do |status|
- raise "Import of '#{imported_project.name}' failed!" if status == 'failed'
+ imported_project.project_import_status.yield_self do |status|
+ @stats = status.dig(:stats, :imported)
+
+ # fail fast if import explicitly failed
+ raise "Import of '#{imported_project.name}' failed!" if status[:import_status] == 'failed'
+
+ status[:import_status]
end
end
+
+ logger.info("== Waiting for import to be finished ==")
expect(import_status).to eventually_eq('finished').within(max_duration: import_max_duration, sleep_interval: 30)
+
@import_time = Time.now - start
aggregate_failures do
@@ -149,22 +186,22 @@ module QA
#
# @return [void]
def fetch_github_objects
- logger.debug("== Fetching objects for github repo: '#{github_repo}' ==")
+ logger.info("== Fetching github repo objects ==")
gh_repo
gh_branches
gh_commits
- gh_prs
- gh_issues
gh_labels
gh_milestones
+ gh_prs
+ gh_issues
end
# Verify repository imported correctly
#
# @return [void]
def verify_repository_import
- logger.debug("== Verifying repository import ==")
+ logger.info("== Verifying repository import ==")
expect(imported_project.description).to eq(gh_repo.description)
# check via include, importer creates more branches
# https://gitlab.com/gitlab-org/gitlab/-/issues/332711
@@ -172,82 +209,109 @@ module QA
expect(gl_commits).to match_array(gh_commits)
end
- # Verify imported merge requests and mr issues
+ # Verify imported labels
#
# @return [void]
- def verify_merge_requests_import
- logger.debug("== Verifying merge request import ==")
- verify_mrs_or_issues('mr')
+ def verify_labels_import
+ logger.info("== Verifying label import ==")
+ # check via include, additional labels can be inherited from parent group
+ expect(gl_labels).to include(*gh_labels)
end
- # Verify imported issues and issue comments
+ # Verify milestones import
#
# @return [void]
- def verify_issues_import
- logger.debug("== Verifying issue import ==")
- verify_mrs_or_issues('issue')
+ def verify_milestones_import
+ logger.info("== Verifying milestones import ==")
+ expect(gl_milestones).to match_array(gh_milestones)
end
- # Verify imported labels
+ # Verify imported merge requests and mr issues
#
# @return [void]
- def verify_labels_import
- logger.debug("== Verifying label import ==")
- # check via include, additional labels can be inherited from parent group
- expect(gl_labels).to include(*gh_labels)
+ def verify_merge_requests_import
+ logger.info("== Verifying merge request import ==")
+ @mr_diff = verify_mrs_or_issues('mr')
end
- # Verify milestones import
+ # Verify imported issues and issue comments
#
# @return [void]
- def verify_milestones_import
- logger.debug("== Verifying milestones import ==")
- expect(gl_milestones).to match_array(gh_milestones)
+ def verify_issues_import
+ logger.info("== Verifying issue import ==")
+ @issue_diff = verify_mrs_or_issues('issue')
end
private
- # Verify imported mrs or issues
+ # Verify imported mrs or issues and return missing items
#
# @param [String] type verification object, 'mrs' or 'issues'
- # @return [void]
+ # @return [Hash]
def verify_mrs_or_issues(type)
- msg = ->(title) { "expected #{type} with title '#{title}' to have" }
-
# Compare length to have easy to read overview how many objects are missing
+ #
expected = type == 'mr' ? mrs : gl_issues
actual = type == 'mr' ? gh_prs : gh_issues
count_msg = "Expected to contain same amount of #{type}s. Gitlab: #{expected.length}, Github: #{actual.length}"
expect(expected.length).to eq(actual.length), count_msg
- logger.debug("= Comparing #{type}s =")
- actual.each do |title, actual_item|
- print "." # indicate that it is still going but don't spam the output with newlines
+ missing_comments = verify_comments(type, actual, expected)
- expected_item = expected[title]
+ {
+ "#{type}s": (actual.keys - expected.keys).map { |it| actual[it].slice(:title, :url) },
+ "#{type}_comments": missing_comments
+ }
+ end
+
+ # Verify imported comments
+ #
+ # @param [String] type verification object, 'mrs' or 'issues'
+ # @param [Hash] actual
+ # @param [Hash] expected
+ # @return [Hash]
+ def verify_comments(type, actual, expected)
+ actual.each_with_object([]) do |(key, actual_item), missing_comments|
+ expected_item = expected[key]
+ title = actual_item[:title]
+ msg = "expected #{type} with title '#{title}' to have"
# Print title in the error message to see which object is missing
- expect(expected_item).to be_truthy, "#{msg.call(title)} been imported"
+ #
+ expect(expected_item).to be_truthy, "#{msg} been imported"
next unless expected_item
# Print difference in the description
+ #
expected_body = expected_item[:body]
actual_body = actual_item[:body]
body_msg = <<~MSG
- #{msg.call(title)} same description. diff:\n#{differ.diff(expected_item[:body], actual_item[:body])}
+ #{msg} same description. diff:\n#{differ.diff(expected_body, actual_body)}
MSG
- expect(expected_body).to include(actual_body), body_msg
+ expect(expected_body).to eq(actual_body), body_msg
# Print amount difference first
+ #
expected_comments = expected_item[:comments]
actual_comments = actual_item[:comments]
comment_count_msg = <<~MSG
- #{msg.call(title)} same amount of comments. Gitlab: #{expected_comments.length}, Github: #{actual_comments.length}
+ #{msg} same amount of comments. Gitlab: #{expected_comments.length}, Github: #{actual_comments.length}
MSG
expect(expected_comments.length).to eq(actual_comments.length), comment_count_msg
expect(expected_comments).to match_array(actual_comments)
+
+ # Save missing comments
+ #
+ comment_diff = actual_comments - expected_comments
+ next if comment_diff.empty?
+
+ missing_comments << {
+ title: title,
+ github_url: actual_item[:url],
+ gitlab_url: expected_item[:url],
+ missing_comments: comment_diff
+ }
end
- puts # print newline after last print to make output pretty
end
# Imported project branches
@@ -297,22 +361,27 @@ module QA
@mrs ||= begin
logger.debug("= Fetching merge requests =")
imported_mrs = imported_project.merge_requests(auto_paginate: true, attempts: 2)
- logger.debug("= Transforming merge request objects for comparison =")
- imported_mrs.each_with_object({}) do |mr, hash|
+
+ logger.debug("= Fetching merge request comments =")
+ Parallel.map(imported_mrs, in_threads: 4) do |mr|
resource = Resource::MergeRequest.init do |resource|
resource.project = imported_project
resource.iid = mr[:iid]
resource.api_client = api_client
end
- hash[mr[:title]] = {
- body: mr[:description],
- comments: resource.comments(auto_paginate: true, attempts: 2)
+ logger.debug("Fetching comments for mr '#{mr[:title]}'")
+ [mr[:iid], {
+ url: mr[:web_url],
+ title: mr[:title],
+ body: sanitize_description(mr[:description]) || '',
+ comments: resource
+ .comments(auto_paginate: true, attempts: 2)
# remove system notes
.reject { |c| c[:system] || c[:body].match?(/^(\*\*Review:\*\*)|(\*Merged by:).*/) }
- .map { |c| sanitize(c[:body]) }
- }
- end
+ .map { |c| sanitize_comment(c[:body]) }
+ }]
+ end.to_h
end
end
@@ -323,37 +392,51 @@ module QA
@gl_issues ||= begin
logger.debug("= Fetching issues =")
imported_issues = imported_project.issues(auto_paginate: true, attempts: 2)
- logger.debug("= Transforming issue objects for comparison =")
- imported_issues.each_with_object({}) do |issue, hash|
+
+ logger.debug("= Fetching issue comments =")
+ Parallel.map(imported_issues, in_threads: 4) do |issue|
resource = Resource::Issue.init do |issue_resource|
issue_resource.project = imported_project
issue_resource.iid = issue[:iid]
issue_resource.api_client = api_client
end
- hash[issue[:title]] = {
- body: issue[:description],
- comments: resource.comments(auto_paginate: true, attempts: 2).map { |c| sanitize(c[:body]) }
- }
- end
+ logger.debug("Fetching comments for issue '#{issue[:title]}'")
+ [issue[:iid], {
+ url: issue[:web_url],
+ title: issue[:title],
+ body: sanitize_description(issue[:description]) || '',
+ comments: resource
+ .comments(auto_paginate: true, attempts: 2)
+ .map { |c| sanitize_comment(c[:body]) }
+ }]
+ end.to_h
end
end
- # Remove added prefixes by importer
+ # Remove added prefixes and legacy diff format from comments
+ #
+ # @param [String] body
+ # @return [String]
+ def sanitize_comment(body)
+ body.gsub(created_by_pattern, "").gsub(suggestion_pattern, "suggestion\r")
+ end
+
+ # Remove created by prefix from descripion
#
# @param [String] body
# @return [String]
- def sanitize(body)
- body.gsub(/\*Created by: \S+\*\n\n/, "")
+ def sanitize_description(body)
+ body&.gsub(created_by_pattern, "")
end
# Save json as file
#
# @param [String] name
- # @param [String] json
+ # @param [Hash] json
# @return [void]
def save_json(name, json)
- File.open("tmp/#{name}.json", "w") { |file| file.write(json) }
+ File.open("tmp/#{name}.json", "w") { |file| file.write(JSON.pretty_generate(json)) }
end
end
end
diff --git a/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_group_spec.rb b/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_group_spec.rb
index a6655471591..f721b3326a0 100644
--- a/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_group_spec.rb
+++ b/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_group_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Manage', :requires_admin do
+ RSpec.describe 'Manage', :reliable, :requires_admin do
describe 'Gitlab migration' do
let(:import_wait_duration) { { max_duration: 300, sleep_interval: 2 } }
let(:admin_api_client) { Runtime::API::Client.as_admin }
@@ -55,9 +55,9 @@ module QA
after do |example|
# Checking for failures in the test currently makes test very flaky due to catching unrelated failures
- # Just log in case of failure until cause of network errors is found
- # See: https://gitlab.com/gitlab-org/gitlab/-/issues/346500
- Runtime::Logger.warn(import_failures) if example.exception && !import_failures.empty?
+ # Log failures for easier debugging
+ Runtime::Logger.warn("Import failures: #{import_failures}") if example.exception && !import_failures.empty?
+ ensure
user.remove_via_api!
end
@@ -147,39 +147,6 @@ module QA
end
end
end
-
- context 'with group members' do
- let(:member) do
- Resource::User.fabricate_via_api! do |usr|
- usr.api_client = admin_api_client
- usr.hard_delete_on_api_removal = true
- end
- end
-
- before do
- member.set_public_email
- source_group.add_member(member, Resource::Members::AccessLevel::DEVELOPER)
-
- imported_group # trigger import
- end
-
- after do
- member.remove_via_api!
- end
-
- it(
- 'adds members for imported group',
- testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347609'
- ) do
- expect { imported_group.import_status }.to eventually_eq('finished').within(import_wait_duration)
-
- imported_member = imported_group.reload!.members.find { |usr| usr.username == member.username }
- aggregate_failures do
- expect(imported_member).not_to be_nil
- expect(imported_member.access_level).to eq(Resource::Members::AccessLevel::DEVELOPER)
- end
- end
- end
end
end
end
diff --git a/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_members_spec.rb b/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_members_spec.rb
new file mode 100644
index 00000000000..704325d9235
--- /dev/null
+++ b/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_members_spec.rb
@@ -0,0 +1,74 @@
+# frozen_string_literal: true
+
+require_relative 'gitlab_project_migration_common'
+
+module QA
+ RSpec.describe 'Manage' do
+ describe 'Gitlab migration' do
+ include_context 'with gitlab project migration'
+
+ let(:member) do
+ Resource::User.fabricate_via_api! do |usr|
+ usr.api_client = admin_api_client
+ usr.hard_delete_on_api_removal = true
+ end
+ end
+
+ let(:imported_group_member) do
+ imported_group.reload!.list_members.find { |usr| usr['username'] == member.username }
+ end
+
+ let(:imported_project_member) do
+ imported_project.reload!.list_members.find { |usr| usr['username'] == member.username }
+ end
+
+ before do
+ member.set_public_email
+ end
+
+ after do
+ member.remove_via_api!
+ end
+
+ context 'with group member' do
+ before do
+ source_group.add_member(member, Resource::Members::AccessLevel::DEVELOPER)
+ end
+
+ it(
+ 'member retains indirect membership in imported project',
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/354416'
+ ) do
+ expect_import_finished
+
+ aggregate_failures do
+ expect(imported_project_member).to be_nil
+ expect(imported_group_member&.fetch('access_level')).to eq(
+ Resource::Members::AccessLevel::DEVELOPER
+ )
+ end
+ end
+ end
+
+ context 'with project member' do
+ before do
+ source_project.add_member(member, Resource::Members::AccessLevel::DEVELOPER)
+ end
+
+ it(
+ 'member retains direct membership in imported project',
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/354417'
+ ) do
+ expect_import_finished
+
+ aggregate_failures do
+ expect(imported_group_member).to be_nil
+ expect(imported_project_member&.fetch('access_level')).to eq(
+ Resource::Members::AccessLevel::DEVELOPER
+ )
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_pipeline_spec.rb b/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_pipeline_spec.rb
new file mode 100644
index 00000000000..484c32956e3
--- /dev/null
+++ b/qa/qa/specs/features/api/1_manage/migration/gitlab_migration_pipeline_spec.rb
@@ -0,0 +1,59 @@
+# frozen_string_literal: true
+
+require_relative 'gitlab_project_migration_common'
+
+module QA
+ RSpec.describe 'Manage' do
+ describe 'Gitlab migration' do
+ include_context 'with gitlab project migration'
+
+ context 'with ci pipeline' do
+ let!(:source_project_with_readme) { true }
+
+ let(:source_pipelines) do
+ source_project.pipelines.map do |pipeline|
+ pipeline.except(:id, :web_url, :project_id)
+ end
+ end
+
+ let(:imported_pipelines) do
+ imported_project.pipelines.map do |pipeline|
+ pipeline.except(:id, :web_url, :project_id)
+ end
+ end
+
+ before do
+ Resource::Repository::Commit.fabricate_via_api! do |commit|
+ commit.api_client = api_client
+ commit.project = source_project
+ commit.commit_message = 'Add .gitlab-ci.yml'
+ commit.add_files(
+ [
+ {
+ file_path: '.gitlab-ci.yml',
+ content: <<~YML
+ test-success:
+ script: echo 'OK'
+ YML
+ }
+ ]
+ )
+ end
+
+ Support::Waiter.wait_until(max_duration: 10, sleep_interval: 1) do
+ !source_project.pipelines.empty?
+ end
+ end
+
+ it(
+ 'successfully imports ci pipeline',
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/354650'
+ ) do
+ expect_import_finished
+
+ expect(imported_pipelines).to eq(source_pipelines)
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/specs/features/api/1_manage/migration/gitlab_project_migration_common.rb b/qa/qa/specs/features/api/1_manage/migration/gitlab_project_migration_common.rb
index b7f0a10c525..70f19e9f3d7 100644
--- a/qa/qa/specs/features/api/1_manage/migration/gitlab_project_migration_common.rb
+++ b/qa/qa/specs/features/api/1_manage/migration/gitlab_project_migration_common.rb
@@ -1,13 +1,9 @@
# frozen_string_literal: true
module QA
- # Disable on staging until bulk_import_projects toggle is on by default
+ # Disable on live envs until bulk_import_projects toggle is on by default
# Otherwise tests running in parallel can disable feature in the middle of other test
- RSpec.shared_context 'with gitlab project migration', :requires_admin, except: { subdomain: :staging }, quarantine: {
- only: { job: 'praefect' },
- type: :investigating,
- issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/348999'
- } do
+ RSpec.shared_context 'with gitlab project migration', :requires_admin, :skip_live_env do
let(:source_project_with_readme) { false }
let(:import_wait_duration) { { max_duration: 300, sleep_interval: 2 } }
let(:admin_api_client) { Runtime::API::Client.as_admin }
@@ -79,13 +75,11 @@ module QA
end
after do |example|
- # Checking for failures in the test currently makes test very flaky
- # Just log in case of failure until cause of network errors is found
+ # Checking for failures in the test currently makes test very flaky due to catching unrelated failures
+ # Log failures for easier debugging
Runtime::Logger.warn("Import failures: #{import_failures}") if example.exception && !import_failures.empty?
-
- user.remove_via_api!
ensure
- Runtime::Feature.disable(:bulk_import_projects)
+ user.remove_via_api!
end
end
end
diff --git a/qa/qa/specs/features/api/1_manage/rate_limits_spec.rb b/qa/qa/specs/features/api/1_manage/rate_limits_spec.rb
index 17ffb901e5a..fc221c963b1 100644
--- a/qa/qa/specs/features/api/1_manage/rate_limits_spec.rb
+++ b/qa/qa/specs/features/api/1_manage/rate_limits_spec.rb
@@ -1,19 +1,41 @@
# frozen_string_literal: true
-require 'airborne'
-
module QA
- RSpec.describe 'Manage with IP rate limits', :requires_admin, :skip_live_env do
- describe 'Users API' do
- let(:api_client) { Runtime::API::Client.new(:gitlab, ip_limits: true) }
- let(:request) { Runtime::API::Request.new(api_client, '/users') }
+ RSpec.describe 'Manage', :requires_admin, :skip_live_env, except: { job: 'review-qa-*' } do
+ describe 'rate limits' do
+ let(:rate_limited_user) { Resource::User.fabricate_via_api! }
+ let(:api_client) { Runtime::API::Client.new(:gitlab, user: rate_limited_user) }
+ let!(:request) { Runtime::API::Request.new(api_client, '/users') }
+
+ after do
+ rate_limited_user.remove_via_api!
+ end
+
+ it 'throttles authenticated api requests by user', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347881' do
+ with_application_settings(
+ throttle_authenticated_api_requests_per_period: 5,
+ throttle_authenticated_api_period_in_seconds: 60,
+ throttle_authenticated_api_enabled: true
+ ) do
+ 5.times do
+ res = RestClient.get request.url
+ expect(res.code).to be(200)
+ end
- it 'GET /users', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347881' do
- 5.times do
- get request.url
- expect_status(200)
+ expect { RestClient.get request.url }.to raise_error do |e|
+ expect(e.class).to be(RestClient::TooManyRequests)
+ end
end
end
end
+
+ private
+
+ def with_application_settings(**hargs)
+ QA::Runtime::ApplicationSettings.set_application_settings(**hargs)
+ yield
+ ensure
+ QA::Runtime::ApplicationSettings.restore_application_settings(*hargs.keys)
+ end
end
end
diff --git a/qa/qa/specs/features/api/1_manage/users_spec.rb b/qa/qa/specs/features/api/1_manage/users_spec.rb
index 53587209bfb..531419e8d0f 100644
--- a/qa/qa/specs/features/api/1_manage/users_spec.rb
+++ b/qa/qa/specs/features/api/1_manage/users_spec.rb
@@ -4,7 +4,7 @@ require 'airborne'
module QA
RSpec.describe 'Manage' do
- describe 'Users API' do
+ describe 'Users API', :reliable do
let(:api_client) { Runtime::API::Client.new(:gitlab) }
let(:request) { Runtime::API::Request.new(api_client, '/users') }
diff --git a/qa/qa/specs/features/api/3_create/gitaly/praefect_dataloss_spec.rb b/qa/qa/specs/features/api/3_create/gitaly/praefect_dataloss_spec.rb
index 6e2a34afb3e..5b02cc4646c 100644
--- a/qa/qa/specs/features/api/3_create/gitaly/praefect_dataloss_spec.rb
+++ b/qa/qa/specs/features/api/3_create/gitaly/praefect_dataloss_spec.rb
@@ -52,6 +52,53 @@ module QA
expect(project_data_loss).to include('gitaly3, assigned host, unhealthy')
end
end
+
+ it 'allows admin resolve scenario where data cannot be recovered', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/352708' do
+ # Ensure everything is in sync before begining test
+ praefect_manager.wait_for_project_synced_across_all_storages(project.id)
+
+ Resource::Repository::Commit.fabricate_via_api! do |commit|
+ commit.project = project
+ commit.commit_message = 'accept-dataloss-1'
+ commit.add_files([
+ { file_path: "new_file-#{SecureRandom.hex(8)}.txt", content: 'Add a commit to gitaly1,gitaly2,gitaly3' }
+ ])
+ end
+
+ praefect_manager.wait_for_replication_to_node(project.id, praefect_manager.primary_node)
+ praefect_manager.stop_primary_node
+ Resource::Repository::Commit.fabricate_via_api! do |commit|
+ commit.project = project
+ commit.commit_message = 'accept-dataloss-2'
+ commit.add_files([
+ { file_path: "new_file-#{SecureRandom.hex(8)}.txt", content: 'Add a commit to gitaly2,gitaly3' }
+ ])
+ end
+
+ praefect_manager.wait_for_replication_to_node(project.id, praefect_manager.secondary_node)
+ praefect_manager.stop_secondary_node
+ Resource::Repository::Commit.fabricate_via_api! do |commit|
+ commit.project = project
+ commit.commit_message = 'accept-dataloss-3'
+ commit.add_files([
+ { file_path: "new_file-#{SecureRandom.hex(8)}.txt", content: 'Add a commit to gitaly3' }
+ ])
+ end
+
+ # Confirms that they want to accept dataloss, using gitaly2 as authoritative storage to use as a base
+ praefect_manager.accept_dataloss_for_project(project.id, praefect_manager.secondary_node)
+
+ # Restart nodes, and allow replication to apply dataloss changes
+ praefect_manager.start_all_nodes
+ praefect_manager.wait_for_project_synced_across_all_storages(project.id)
+
+ # Validate that gitaly2 was accepted as the authorative storage
+ aggregate_failures "validate correct set of commits available" do
+ expect(project.commits.map { |commit| commit[:message].chomp }).to include('accept-dataloss-1')
+ expect(project.commits.map { |commit| commit[:message].chomp }).to include('accept-dataloss-2')
+ expect(project.commits.map { |commit| commit[:message].chomp }).not_to include('accept-dataloss-3')
+ end
+ end
end
end
end
diff --git a/qa/qa/specs/features/api/3_create/repository/files_spec.rb b/qa/qa/specs/features/api/3_create/repository/files_spec.rb
index 48608094f5e..4d28937fbf8 100644
--- a/qa/qa/specs/features/api/3_create/repository/files_spec.rb
+++ b/qa/qa/specs/features/api/3_create/repository/files_spec.rb
@@ -104,6 +104,14 @@ module QA
expect(response.headers[:content_disposition]).not_to include("inline")
expect(response.headers[:content_type]).to include("image/svg+xml")
end
+
+ delete_project_request = Runtime::API::Request.new(@api_client, "/projects/#{sanitized_project_path}")
+ delete delete_project_request.url
+
+ expect_status(202)
+ expect(json_body).to match(
+ a_hash_including(message: '202 Accepted')
+ )
end
end
end
diff --git a/qa/qa/specs/features/api/4_verify/remove_runner_spec.rb b/qa/qa/specs/features/api/4_verify/remove_runner_spec.rb
new file mode 100644
index 00000000000..0d10783735b
--- /dev/null
+++ b/qa/qa/specs/features/api/4_verify/remove_runner_spec.rb
@@ -0,0 +1,36 @@
+# frozen_string_literal: true
+
+module QA
+ RSpec.describe 'Verify', :runner do
+ describe 'Runner removal' do
+ include Support::API
+
+ let(:api_client) { Runtime::API::Client.new(:gitlab) }
+ let(:executor) { "qa-runner-#{Time.now.to_i}" }
+ let(:runner_tags) { ['runner-registration-e2e-test'] }
+ let!(:runner) do
+ Resource::Runner.fabricate! do |runner|
+ runner.name = executor
+ runner.tags = runner_tags
+ end
+ end
+
+ before do
+ sleep 5 # Runner should register within 5 seconds
+ end
+
+ # Removing a runner via the UI is covered by `spec/features/runners_spec.rb``
+ it 'removes the runner', quarantine: { issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/355302', type: :investigating } do
+ expect(runner.project.runners.size).to eq(1)
+ expect(runner.project.runners.first[:description]).to eq(executor)
+
+ request = Runtime::API::Request.new(api_client, "runners/#{runner.project.runners.first[:id]}")
+ response = delete(request.url)
+ expect(response.code).to eq(Support::API::HTTP_STATUS_NO_CONTENT)
+ expect(response.body).to be_empty
+
+ expect(runner.project.runners).to be_empty
+ end
+ end
+ end
+end
diff --git a/qa/qa/specs/features/browser_ui/1_manage/group/transfer_group_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/group/transfer_group_spec.rb
deleted file mode 100644
index 2db93ac60ea..00000000000
--- a/qa/qa/specs/features/browser_ui/1_manage/group/transfer_group_spec.rb
+++ /dev/null
@@ -1,51 +0,0 @@
-# frozen_string_literal: true
-
-module QA
- RSpec.describe 'Manage' do
- describe 'Subgroup transfer' do
- let(:source_group) do
- Resource::Group.fabricate_via_api! do |group|
- group.path = "source-group-for-transfer_#{SecureRandom.hex(8)}"
- end
- end
-
- let!(:target_group) do
- Resource::Group.fabricate_via_api! do |group|
- group.path = "target-group-for-transfer_#{SecureRandom.hex(8)}"
- end
- end
-
- let(:sub_group_for_transfer) do
- Resource::Group.fabricate_via_api! do |group|
- group.path = "subgroup-for-transfer_#{SecureRandom.hex(8)}"
- group.sandbox = source_group
- end
- end
-
- before do
- Flow::Login.sign_in
- sub_group_for_transfer.visit!
- end
-
- it 'transfers a subgroup to another group',
- testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347692' do
- Page::Group::Menu.perform(&:click_group_general_settings_item)
- Page::Group::Settings::General.perform do |general|
- general.transfer_group(target_group.path, sub_group_for_transfer.path)
-
- sub_group_for_transfer.sandbox = target_group
- sub_group_for_transfer.reload!
- end
-
- expect(page).to have_text("Group '#{sub_group_for_transfer.path}' was successfully transferred.")
- expect(page.driver.current_url).to include(sub_group_for_transfer.full_path)
- end
-
- after do
- source_group&.remove_via_api!
- target_group&.remove_via_api!
- sub_group_for_transfer&.remove_via_api!
- end
- end
- end
-end
diff --git a/qa/qa/specs/features/browser_ui/1_manage/group/transfer_project_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/group/transfer_project_spec.rb
index ffd7a7dfb6c..7b60adae836 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/group/transfer_project_spec.rb
+++ b/qa/qa/specs/features/browser_ui/1_manage/group/transfer_project_spec.rb
@@ -2,7 +2,7 @@
module QA
RSpec.describe 'Manage' do
- describe 'Project transfer between groups' do
+ describe 'Project transfer between groups', :reliable do
let(:source_group) do
Resource::Group.fabricate_via_api! do |group|
group.path = 'source-group'
diff --git a/qa/qa/specs/features/browser_ui/1_manage/login/2fa_recovery_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/login/2fa_recovery_spec.rb
index 5ba80489652..c86a649f179 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/login/2fa_recovery_spec.rb
+++ b/qa/qa/specs/features/browser_ui/1_manage/login/2fa_recovery_spec.rb
@@ -29,7 +29,6 @@ module QA
end
before do
- Runtime::Feature.enable(:invite_members_group_modal, group: group)
group.add_member(developer_user, Resource::Members::AccessLevel::DEVELOPER)
end
diff --git a/qa/qa/specs/features/browser_ui/1_manage/login/log_in_with_2fa_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/login/log_in_with_2fa_spec.rb
index ca0ce0d5775..64614ed654f 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/login/log_in_with_2fa_spec.rb
+++ b/qa/qa/specs/features/browser_ui/1_manage/login/log_in_with_2fa_spec.rb
@@ -31,7 +31,6 @@ module QA
let(:two_fa_expected_text) { /The group settings for.*require you to enable Two-Factor Authentication for your account.*You need to do this before/ }
before do
- Runtime::Feature.enable(:invite_members_group_modal, group: group)
group.add_member(developer_user, Resource::Members::AccessLevel::DEVELOPER)
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 bfb810b5c2b..90fbff3261e 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
@@ -1,12 +1,8 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Manage', :requires_admin do
+ RSpec.describe 'Manage', :reliable do
describe 'Add project member' do
- before do
- Runtime::Feature.enable(:invite_members_group_modal)
- end
-
it 'user adds project member', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347887' do
Flow::Login.sign_in
diff --git a/qa/qa/specs/features/browser_ui/1_manage/project/import_github_repo_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/project/import_github_repo_spec.rb
index 72867333d16..d803f5e473c 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/project/import_github_repo_spec.rb
+++ b/qa/qa/specs/features/browser_ui/1_manage/project/import_github_repo_spec.rb
@@ -1,9 +1,9 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Manage', :github, :requires_admin do
+ RSpec.describe 'Manage', :reliable, :github, :requires_admin do
describe 'Project import' do
- let(:github_repo) { 'gitlab-qa-github/test-project' }
+ let(:github_repo) { 'gitlab-qa-github/import-test' }
let(:api_client) { Runtime::API::Client.as_admin }
let(:group) { Resource::Group.fabricate_via_api! { |resource| resource.api_client = api_client } }
let(:user) do
@@ -55,7 +55,7 @@ module QA
Page::Project::Show.perform do |project|
aggregate_failures do
expect(project).to have_content(imported_project.name)
- expect(project).to have_content('This test project is used for automated GitHub import by GitLab QA.')
+ expect(project).to have_content('Project for github import test')
end
end
end
diff --git a/qa/qa/specs/features/browser_ui/1_manage/project/invite_group_to_project_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/project/invite_group_to_project_spec.rb
index 6997447411a..dd27e85af3c 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/project/invite_group_to_project_spec.rb
+++ b/qa/qa/specs/features/browser_ui/1_manage/project/invite_group_to_project_spec.rb
@@ -2,7 +2,7 @@
module QA
# Tagging with issue for a transient invite group modal search bug, but does not require quarantine at this time
- RSpec.describe 'Manage', :requires_admin, :transient, issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/349379' do
+ RSpec.describe 'Manage', :transient, issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/349379' do
describe 'Invite group' do
shared_examples 'invites group to project' do
it 'verifies group is added and members can access project with correct access level' do
@@ -16,6 +16,8 @@ module QA
Flow::Login.sign_in(as: @user)
Page::Dashboard::Projects.perform do |projects|
+ projects.filter_by_name(project.name)
+
expect(projects).to have_project_with_access_role(project.name, 'Developer')
end
@@ -28,7 +30,6 @@ module QA
end
before(:context) do
- Runtime::Feature.enable(:invite_members_group_modal)
@user = Resource::User.fabricate_or_use(Runtime::Env.gitlab_qa_username_1, Runtime::Env.gitlab_qa_password_1)
end
@@ -79,10 +80,6 @@ module QA
project&.remove_via_api!
group&.remove_via_api!
end
-
- after(:context) do
- Runtime::Feature.disable(:invite_members_group_modal)
- end
end
end
end
diff --git a/qa/qa/specs/features/browser_ui/1_manage/project/personal_project_permissions_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/project/personal_project_permissions_spec.rb
new file mode 100644
index 00000000000..2aefa1c39ed
--- /dev/null
+++ b/qa/qa/specs/features/browser_ui/1_manage/project/personal_project_permissions_spec.rb
@@ -0,0 +1,98 @@
+# frozen_string_literal: true
+
+module QA
+ RSpec.describe 'Manage' do
+ describe 'Personal project permissions' do
+ let!(:owner) { Resource::User.fabricate_or_use(Runtime::Env.gitlab_qa_username_1, Runtime::Env.gitlab_qa_password_1) }
+
+ let!(:owner_api_client) { Runtime::API::Client.new(:gitlab, user: owner) }
+
+ let!(:project) do
+ Resource::Project.fabricate_via_api! do |project|
+ project.api_client = owner_api_client
+ project.name = 'qa-owner-personal-project'
+ project.personal_namespace = owner.username
+ end
+ end
+
+ after do
+ project&.remove_via_api!
+ end
+
+ context 'when user is added as Owner' do
+ let(:issue) do
+ Resource::Issue.fabricate_via_api! do |issue|
+ issue.api_client = owner_api_client
+ issue.project = project
+ issue.title = 'Test Owner deletes issue'
+ end
+ end
+
+ before do
+ Flow::Login.sign_in(as: owner)
+ end
+
+ it "has Owner role with Owner permissions", testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/352542' do
+ Page::Dashboard::Projects.perform do |projects|
+ projects.filter_by_name(project.name)
+
+ expect(projects).to have_project_with_access_role(project.name, 'Owner')
+ end
+
+ expect_owner_permissions_allow_delete_issue
+ end
+ end
+
+ context 'when user is added as Maintainer' do
+ let(:maintainer) { Resource::User.fabricate_or_use(Runtime::Env.gitlab_qa_username_2, Runtime::Env.gitlab_qa_password_2) }
+
+ let(:issue) do
+ Resource::Issue.fabricate_via_api! do |issue|
+ issue.api_client = owner_api_client
+ issue.project = project
+ issue.title = 'Test Maintainer deletes issue'
+ end
+ end
+
+ before do
+ project.add_member(maintainer, Resource::Members::AccessLevel::MAINTAINER)
+ Flow::Login.sign_in(as: maintainer)
+ end
+
+ it "has Maintainer role without Owner permissions", testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/352607' do
+ Page::Dashboard::Projects.perform do |projects|
+ projects.filter_by_name(project.name)
+
+ expect(projects).to have_project_with_access_role(project.name, 'Maintainer')
+ end
+
+ expect_maintainer_permissions_do_not_allow_delete_issue
+ end
+ end
+
+ private
+
+ def expect_owner_permissions_allow_delete_issue
+ expect do
+ issue.visit!
+
+ Page::Project::Issue::Show.perform(&:delete_issue)
+
+ Page::Project::Issue::Index.perform do |index|
+ expect(index).not_to have_issue(issue)
+ end
+ end.not_to raise_error
+ end
+
+ def expect_maintainer_permissions_do_not_allow_delete_issue
+ expect do
+ issue.visit!
+
+ Page::Project::Issue::Show.perform do |issue|
+ expect(issue).not_to have_delete_issue_button
+ end
+ end.not_to raise_error
+ end
+ end
+ end
+end
diff --git a/qa/qa/specs/features/browser_ui/1_manage/project/protected_tags_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/project/protected_tags_spec.rb
index 4f9ba579730..f6448fea2d4 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/project/protected_tags_spec.rb
+++ b/qa/qa/specs/features/browser_ui/1_manage/project/protected_tags_spec.rb
@@ -2,8 +2,7 @@
module QA
RSpec.describe 'Manage' do
- # TODO: Remove :requires_admin meta when the `Runtime::Feature.enable` method call is removed
- describe 'Repository tags', :requires_admin do
+ describe 'Repository tags', :reliable do
let(:project) do
Resource::Project.fabricate_via_api! do |project|
project.name = 'project-for-tags'
@@ -11,12 +10,14 @@ module QA
end
end
- before do
- Runtime::Feature.enable(:invite_members_group_modal, project: project)
+ let(:developer_user) do
+ Resource::User.fabricate_or_use(Runtime::Env.gitlab_qa_username_1, Runtime::Env.gitlab_qa_password_1)
+ end
+
+ let(:maintainer_user) do
+ Resource::User.fabricate_or_use(Runtime::Env.gitlab_qa_username_2, Runtime::Env.gitlab_qa_password_2)
end
- let(:developer_user) { Resource::User.fabricate_or_use(Runtime::Env.gitlab_qa_username_1, Runtime::Env.gitlab_qa_password_1) }
- let(:maintainer_user) { Resource::User.fabricate_or_use(Runtime::Env.gitlab_qa_username_2, Runtime::Env.gitlab_qa_password_2) }
let(:tag_name) { 'v0.0.1' }
let(:tag_message) { 'Version 0.0.1' }
let(:tag_release_notes) { 'Release It!' }
diff --git a/qa/qa/specs/features/browser_ui/1_manage/project/view_project_activity_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/project/view_project_activity_spec.rb
index 1be73d92a8c..88f4996ff03 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/project/view_project_activity_spec.rb
+++ b/qa/qa/specs/features/browser_ui/1_manage/project/view_project_activity_spec.rb
@@ -2,8 +2,9 @@
module QA
RSpec.describe 'Manage' do
- describe 'Project activity' do
- it 'user creates an event in the activity page upon Git push', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347879' do
+ describe 'Project activity', :reliable do
+ it 'user creates an event in the activity page upon Git push',
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347879' do
Flow::Login.sign_in
project = Resource::Repository::ProjectPush.fabricate! do |push|
diff --git a/qa/qa/specs/features/browser_ui/1_manage/user/user_access_termination_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/user/user_access_termination_spec.rb
index 58dcd922255..8462f5db30b 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/user/user_access_termination_spec.rb
+++ b/qa/qa/specs/features/browser_ui/1_manage/user/user_access_termination_spec.rb
@@ -2,7 +2,7 @@
module QA
RSpec.describe 'Manage' do
- describe 'User', :requires_admin do
+ describe 'User', :requires_admin, :reliable do
let(:admin_api_client) { Runtime::API::Client.as_admin }
let!(:user) do
diff --git a/qa/qa/specs/features/browser_ui/2_plan/email/trigger_email_notification_spec.rb b/qa/qa/specs/features/browser_ui/2_plan/email/trigger_email_notification_spec.rb
index 4350b8f0d3e..0d706aef6ab 100644
--- a/qa/qa/specs/features/browser_ui/2_plan/email/trigger_email_notification_spec.rb
+++ b/qa/qa/specs/features/browser_ui/2_plan/email/trigger_email_notification_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Plan', :orchestrated, :smtp, :requires_admin do
+ RSpec.describe 'Plan', :orchestrated, :smtp do
describe 'Email Notification' do
include Support::API
@@ -16,7 +16,6 @@ module QA
end
before do
- Runtime::Feature.enable(:invite_members_group_modal)
Flow::Login.sign_in
end
diff --git a/qa/qa/specs/features/browser_ui/2_plan/issue/check_mentions_for_xss_spec.rb b/qa/qa/specs/features/browser_ui/2_plan/issue/check_mentions_for_xss_spec.rb
index c2b42de6701..1ba110a9602 100644
--- a/qa/qa/specs/features/browser_ui/2_plan/issue/check_mentions_for_xss_spec.rb
+++ b/qa/qa/specs/features/browser_ui/2_plan/issue/check_mentions_for_xss_spec.rb
@@ -4,7 +4,7 @@ module QA
RSpec.describe 'Plan', :reliable do
let!(:user) do
Resource::User.fabricate_via_api! do |user|
- user.name = "eve <img src=x onerror=alert(2)&lt;img src=x onerror=alert(1)&gt;"
+ user.name = "QA User <img src=x onerror=alert(2)&lt;img src=x onerror=alert(1)&gt;"
user.password = "test1234"
user.api_client = Runtime::API::Client.as_admin
end
@@ -18,8 +18,6 @@ module QA
describe 'check xss occurence in @mentions in issues', :requires_admin do
before do
- Runtime::Feature.enable(:invite_members_group_modal)
-
Flow::Login.sign_in
project.add_member(user)
diff --git a/qa/qa/specs/features/browser_ui/2_plan/issue/mentions_spec.rb b/qa/qa/specs/features/browser_ui/2_plan/issue/mentions_spec.rb
index 7d6718073f9..e7025920def 100644
--- a/qa/qa/specs/features/browser_ui/2_plan/issue/mentions_spec.rb
+++ b/qa/qa/specs/features/browser_ui/2_plan/issue/mentions_spec.rb
@@ -1,8 +1,7 @@
# frozen_string_literal: true
module QA
- # TODO: Remove :requires_admin meta when the `Runtime::Feature.enable` method call is removed
- RSpec.describe 'Plan', :smoke, :reliable, :requires_admin do
+ RSpec.describe 'Plan', :smoke, :reliable do
describe 'mention' do
let(:user) { Resource::User.fabricate_or_use(Runtime::Env.gitlab_qa_username_1, Runtime::Env.gitlab_qa_password_1) }
let(:project) do
@@ -14,7 +13,6 @@ module QA
before do
Flow::Login.sign_in
- Runtime::Feature.enable(:invite_members_group_modal, project: project)
project.add_member(user)
diff --git a/qa/qa/specs/features/browser_ui/2_plan/issue/real_time_assignee_spec.rb b/qa/qa/specs/features/browser_ui/2_plan/issue/real_time_assignee_spec.rb
index 45d466903de..ac0f16b50cc 100644
--- a/qa/qa/specs/features/browser_ui/2_plan/issue/real_time_assignee_spec.rb
+++ b/qa/qa/specs/features/browser_ui/2_plan/issue/real_time_assignee_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Plan', :requires_admin, :actioncable, :orchestrated do
+ RSpec.describe 'Plan', :requires_admin, :actioncable, :orchestrated, quarantine: { issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/293699', type: :bug } do
describe 'Assignees' do
let(:user1) { Resource::User.fabricate_or_use(Runtime::Env.gitlab_qa_username_1, Runtime::Env.gitlab_qa_password_1) }
let(:user2) { Resource::User.fabricate_or_use(Runtime::Env.gitlab_qa_username_2, Runtime::Env.gitlab_qa_password_2) }
@@ -12,22 +12,12 @@ module QA
end
before do
- Runtime::Feature.enable('real_time_issue_sidebar', project: project)
- Runtime::Feature.enable('broadcast_issue_updates', project: project)
- Runtime::Feature.enable(:invite_members_group_modal, project: project)
-
Flow::Login.sign_in
project.add_member(user1)
project.add_member(user2)
end
- after do
- Runtime::Feature.disable('real_time_issue_sidebar', project: project)
- Runtime::Feature.disable('broadcast_issue_updates', project: project)
- Runtime::Feature.disable(:invite_members_group_modal, project: project)
- end
-
it 'update without refresh', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347941' do
issue = Resource::Issue.fabricate_via_api! do |issue|
issue.project = project
diff --git a/qa/qa/specs/features/browser_ui/2_plan/milestone/assign_milestone_spec.rb b/qa/qa/specs/features/browser_ui/2_plan/milestone/assign_milestone_spec.rb
index d3662884952..d6eab3c8dd0 100644
--- a/qa/qa/specs/features/browser_ui/2_plan/milestone/assign_milestone_spec.rb
+++ b/qa/qa/specs/features/browser_ui/2_plan/milestone/assign_milestone_spec.rb
@@ -10,13 +10,13 @@ module QA
let(:group) do
Resource::Group.fabricate_via_api! do |group|
- group.name = 'group-to-test-milestones'
+ group.name = "group-to-test-milestones-#{SecureRandom.hex(4)}"
end
end
let(:project) do
Resource::Project.fabricate_via_api! do |project|
- project.name = 'project-to-test-milestones'
+ project.name = "project-to-test-milestones-#{SecureRandom.hex(4)}"
project.group = group
end
end
diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/move_project_create_fork_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/move_project_create_fork_spec.rb
index bec95e41202..153bfd292aa 100644
--- a/qa/qa/specs/features/browser_ui/3_create/repository/move_project_create_fork_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/repository/move_project_create_fork_spec.rb
@@ -19,7 +19,6 @@ module QA
end
before do
- Runtime::Feature.enable(:invite_members_group_modal, project: parent_project)
parent_project.add_member(user)
end
diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/push_mirroring_lfs_over_http_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/push_mirroring_lfs_over_http_spec.rb
index b8e425ae3b8..4228c3ed352 100644
--- a/qa/qa/specs/features/browser_ui/3_create/repository/push_mirroring_lfs_over_http_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/repository/push_mirroring_lfs_over_http_spec.rb
@@ -3,7 +3,7 @@
module QA
RSpec.describe 'Create' do
describe 'Push mirror a repository over HTTP' do
- it 'configures and syncs LFS objects for a (push) mirrored repository', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347847' do
+ it 'configures and syncs LFS objects for a (push) mirrored repository', :aggregate_failures, testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347847' do
Runtime::Browser.visit(:gitlab, Page::Main::Login)
Page::Main::Login.perform(&:sign_in_using_credentials)
@@ -30,14 +30,15 @@ module QA
mirror_settings.authentication_method = 'Password'
mirror_settings.password = Runtime::User.password
mirror_settings.mirror_repository
- mirror_settings.update target_project_uri # rubocop:disable Rails/SaveBang
+ mirror_settings.update(target_project_uri) # rubocop:disable Rails/SaveBang
+ mirror_settings.verify_update(target_project_uri)
end
end
# Check that the target project has the commit from the source
target_project.visit!
Page::Project::Show.perform do |project_page|
- expect(project_page).to have_file('README.md')
+ expect { project_page.has_file?('README.md') }.to eventually_be_truthy.within(max_duration: 60, reload_page: page), "Expected a file named README.md but it did not appear."
expect(project_page).to have_readme_content('The rendered file could not be displayed because it is stored in LFS')
end
end
diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/push_mirroring_over_http_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/push_mirroring_over_http_spec.rb
index 6d3d86d0663..d644a7ead1e 100644
--- a/qa/qa/specs/features/browser_ui/3_create/repository/push_mirroring_over_http_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/repository/push_mirroring_over_http_spec.rb
@@ -29,7 +29,8 @@ module QA
mirror_settings.authentication_method = 'Password'
mirror_settings.password = Runtime::User.password
mirror_settings.mirror_repository
- mirror_settings.update target_project_uri # rubocop:disable Rails/SaveBang
+ mirror_settings.update(target_project_uri) # rubocop:disable Rails/SaveBang
+ mirror_settings.verify_update(target_project_uri)
end
end
@@ -37,7 +38,7 @@ module QA
target_project.visit!
Page::Project::Show.perform do |project|
- expect(project).to have_content('README.md')
+ expect { project.has_file?('README.md') }.to eventually_be_truthy.within(max_duration: 60, reload_page: page), "Expected a file named README.md but it did not appear."
expect(project).to have_content('This is a test project')
end
end
diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/push_over_ssh_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/push_over_ssh_spec.rb
index 0323448878b..18a77bd5ae3 100644
--- a/qa/qa/specs/features/browser_ui/3_create/repository/push_over_ssh_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/repository/push_over_ssh_spec.rb
@@ -2,7 +2,7 @@
module QA
RSpec.describe 'Create' do
- describe 'SSH key support' do
+ describe 'SSH key support', :skip_fips_env do
# Note: If you run these tests against GDK make sure you've enabled sshd
# See: https://gitlab.com/gitlab-org/gitlab-qa/blob/master/docs/run_qa_against_gdk.md
diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/ssh_key_support_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/ssh_key_support_spec.rb
index 2e8c43d6981..b0eb3ac7b37 100644
--- a/qa/qa/specs/features/browser_ui/3_create/repository/ssh_key_support_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/repository/ssh_key_support_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'SSH keys support', :smoke do
+ RSpec.describe 'SSH keys support', :smoke, :skip_fips_env do
key_title = "key for ssh tests #{Time.now.to_f}"
key = nil
diff --git a/qa/qa/specs/features/browser_ui/3_create/snippet/clone_push_pull_personal_snippet_spec.rb b/qa/qa/specs/features/browser_ui/3_create/snippet/clone_push_pull_personal_snippet_spec.rb
index 8f22a28628f..7a0b4674581 100644
--- a/qa/qa/specs/features/browser_ui/3_create/snippet/clone_push_pull_personal_snippet_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/snippet/clone_push_pull_personal_snippet_spec.rb
@@ -2,7 +2,7 @@
module QA
RSpec.describe 'Create' do
- describe 'Version control for personal snippets' do
+ describe 'Version control for personal snippets', :skip_fips_env do
let(:new_file) { 'new_snippet_file' }
let(:changed_content) { 'changes' }
let(:commit_message) { 'Changes to snippets' }
diff --git a/qa/qa/specs/features/browser_ui/3_create/snippet/clone_push_pull_project_snippet_spec.rb b/qa/qa/specs/features/browser_ui/3_create/snippet/clone_push_pull_project_snippet_spec.rb
index 9a5fe44c927..d269e02e26d 100644
--- a/qa/qa/specs/features/browser_ui/3_create/snippet/clone_push_pull_project_snippet_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/snippet/clone_push_pull_project_snippet_spec.rb
@@ -2,7 +2,7 @@
module QA
RSpec.describe 'Create' do
- describe 'Version control for project snippets' do
+ describe 'Version control for project snippets', :skip_fips_env do
let(:new_file) { 'new_snippet_file' }
let(:changed_content) { 'changes' }
let(:commit_message) { 'Changes to snippets' }
diff --git a/qa/qa/specs/features/browser_ui/3_create/snippet/create_personal_snippet_spec.rb b/qa/qa/specs/features/browser_ui/3_create/snippet/create_personal_snippet_spec.rb
index e04f580dc15..b4519327a62 100644
--- a/qa/qa/specs/features/browser_ui/3_create/snippet/create_personal_snippet_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/snippet/create_personal_snippet_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Create', :smoke do
+ RSpec.describe 'Create', :smoke, quarantine: { issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/326624', type: :investigating } do
describe 'Personal snippet creation' do
let(:snippet) do
Resource::Snippet.fabricate_via_browser_ui! do |snippet|
@@ -22,7 +22,7 @@ module QA
end
it 'user creates a personal snippet', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347799' do
- snippet.visit!
+ snippet
Page::Dashboard::Snippet::Show.perform do |snippet|
expect(snippet).to have_snippet_title('Snippet title')
diff --git a/qa/qa/specs/features/browser_ui/3_create/snippet/create_personal_snippet_with_multiple_files_spec.rb b/qa/qa/specs/features/browser_ui/3_create/snippet/create_personal_snippet_with_multiple_files_spec.rb
index 28bea89e3bd..ce99822b572 100644
--- a/qa/qa/specs/features/browser_ui/3_create/snippet/create_personal_snippet_with_multiple_files_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/snippet/create_personal_snippet_with_multiple_files_spec.rb
@@ -27,7 +27,7 @@ module QA
end
it 'creates a personal snippet with multiple files', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347723' do
- snippet.visit!
+ snippet
Page::Dashboard::Snippet::Show.perform do |snippet|
expect(snippet).to have_snippet_title('Personal snippet with multiple files')
diff --git a/qa/qa/specs/features/browser_ui/3_create/snippet/create_project_snippet_spec.rb b/qa/qa/specs/features/browser_ui/3_create/snippet/create_project_snippet_spec.rb
index 56cbe7d6bfa..b93bc1545d1 100644
--- a/qa/qa/specs/features/browser_ui/3_create/snippet/create_project_snippet_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/snippet/create_project_snippet_spec.rb
@@ -22,7 +22,7 @@ module QA
end
it 'user creates a project snippet', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347798' do
- snippet.visit!
+ snippet
Page::Dashboard::Snippet::Show.perform do |snippet|
expect(snippet).to have_snippet_title('Project snippet')
diff --git a/qa/qa/specs/features/browser_ui/3_create/snippet/create_project_snippet_with_multiple_files_spec.rb b/qa/qa/specs/features/browser_ui/3_create/snippet/create_project_snippet_with_multiple_files_spec.rb
index 3d69ef5dde6..70891ec72c7 100644
--- a/qa/qa/specs/features/browser_ui/3_create/snippet/create_project_snippet_with_multiple_files_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/snippet/create_project_snippet_with_multiple_files_spec.rb
@@ -29,7 +29,7 @@ module QA
end
it 'creates a project snippet with multiple files', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347725' do
- snippet.visit!
+ snippet
Page::Dashboard::Snippet::Show.perform do |snippet|
aggregate_failures 'file content verification' do
diff --git a/qa/qa/specs/features/browser_ui/3_create/web_ide/open_fork_in_web_ide_spec.rb b/qa/qa/specs/features/browser_ui/3_create/web_ide/open_fork_in_web_ide_spec.rb
index 96e85139e78..653c0657c81 100644
--- a/qa/qa/specs/features/browser_ui/3_create/web_ide/open_fork_in_web_ide_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/web_ide/open_fork_in_web_ide_spec.rb
@@ -2,7 +2,10 @@
module QA
RSpec.describe 'Create' do
- describe 'Open a fork in Web IDE' do
+ describe 'Open a fork in Web IDE', quarantine: {
+ issue: "https://gitlab.com/gitlab-org/gitlab/-/issues/351696",
+ type: :flaky
+ } do
let(:parent_project) do
Resource::Project.fabricate_via_api! do |project|
project.name = 'parent-project'
diff --git a/qa/qa/specs/features/browser_ui/3_create/web_ide/web_terminal_spec.rb b/qa/qa/specs/features/browser_ui/3_create/web_ide/web_terminal_spec.rb
index 022731faade..09459057992 100644
--- a/qa/qa/specs/features/browser_ui/3_create/web_ide/web_terminal_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/web_ide/web_terminal_spec.rb
@@ -4,6 +4,8 @@ module QA
RSpec.describe(
'Create',
:runner,
+ # TODO: remove limitation to only run on main when the bug is fixed
+ only: { pipeline: :main },
quarantine: {
issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/338179',
type: :bug
diff --git a/qa/qa/specs/features/browser_ui/4_verify/pipeline/include_local_config_file_paths_with_wildcard_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/pipeline/include_local_config_file_paths_with_wildcard_spec.rb
index f2ebc191a8a..b9b87ed29bb 100644
--- a/qa/qa/specs/features/browser_ui/4_verify/pipeline/include_local_config_file_paths_with_wildcard_spec.rb
+++ b/qa/qa/specs/features/browser_ui/4_verify/pipeline/include_local_config_file_paths_with_wildcard_spec.rb
@@ -2,7 +2,7 @@
module QA
RSpec.describe 'Verify' do
- describe 'Include local config file paths with wildcard' do
+ describe 'Include local config file paths with wildcard', :reliable do
let(:project) do
Resource::Project.fabricate_via_api! do |project|
project.name = 'project-with-pipeline'
diff --git a/qa/qa/specs/features/browser_ui/4_verify/pipeline/pipeline_editor_can_create_merge_request_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/pipeline/pipeline_editor_can_create_merge_request_spec.rb
new file mode 100644
index 00000000000..0e7a38626aa
--- /dev/null
+++ b/qa/qa/specs/features/browser_ui/4_verify/pipeline/pipeline_editor_can_create_merge_request_spec.rb
@@ -0,0 +1,53 @@
+# frozen_string_literal: true
+
+module QA
+ RSpec.describe 'Verify' do
+ describe 'Pipeline editor' do
+ let(:project) do
+ Resource::Project.fabricate_via_api! do |project|
+ project.name = 'pipeline-editor-project'
+ project.initialize_with_readme = true
+ end
+ end
+
+ before do
+ Flow::Login.sign_in
+ project.visit!
+ Page::Project::Menu.perform(&:go_to_pipeline_editor)
+ end
+
+ after do
+ project&.remove_via_api!
+ end
+
+ it(
+ 'can create merge request',
+ test_case: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/349130'
+ ) do
+ Page::Project::PipelineEditor::New.perform(&:create_new_ci)
+
+ Page::Project::PipelineEditor::Show.perform do |show|
+ # Editor should display default content when project does not have CI file yet
+ # New MR checkbox should not be rendered when a new target branch is yet to be provided
+ aggregate_failures 'check editor default conditions' do
+ expect(show.editing_content).not_to be_empty
+ expect(show).to have_no_new_mr_checkbox
+ end
+
+ # The new MR checkbox is visible after a new target branch name is set
+ show.set_target_branch(SecureRandom.hex(10))
+ expect(show).to have_new_mr_checkbox
+
+ show.select_new_mr_checkbox
+ show.submit_changes
+ end
+
+ Page::MergeRequest::New.perform(&:create_merge_request)
+
+ Page::MergeRequest::Show.perform do |show|
+ expect(show).to have_title('Update .gitlab-ci.yml file')
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/specs/features/browser_ui/4_verify/pipeline/pipeline_editor_lint_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/pipeline/pipeline_editor_lint_spec.rb
index 8f3284662d7..23f212e110b 100644
--- a/qa/qa/specs/features/browser_ui/4_verify/pipeline/pipeline_editor_lint_spec.rb
+++ b/qa/qa/specs/features/browser_ui/4_verify/pipeline/pipeline_editor_lint_spec.rb
@@ -2,7 +2,7 @@
module QA
RSpec.describe 'Verify' do
- describe 'Pipeline editor' do
+ describe 'Pipeline editor', :reliable do
let(:project) do
Resource::Project.fabricate_via_api! do |project|
project.name = 'pipeline-editor-project'
diff --git a/qa/qa/specs/features/browser_ui/4_verify/pipeline/run_pipeline_via_web_only_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/pipeline/run_pipeline_via_web_only_spec.rb
index 7656aea885e..d1e9981ae74 100644
--- a/qa/qa/specs/features/browser_ui/4_verify/pipeline/run_pipeline_via_web_only_spec.rb
+++ b/qa/qa/specs/features/browser_ui/4_verify/pipeline/run_pipeline_via_web_only_spec.rb
@@ -2,7 +2,7 @@
module QA
RSpec.describe 'Verify' do
- describe 'Run pipeline' do
+ describe 'Run pipeline', :reliable do
context 'with web only rule' do
let(:job_name) { 'test_job' }
let(:project) do
diff --git a/qa/qa/specs/features/browser_ui/5_package/container_registry/container_registry_omnibus_spec.rb b/qa/qa/specs/features/browser_ui/5_package/container_registry/container_registry_omnibus_spec.rb
index e3c06242a9b..c833aa1a5b8 100644
--- a/qa/qa/specs/features/browser_ui/5_package/container_registry/container_registry_omnibus_spec.rb
+++ b/qa/qa/specs/features/browser_ui/5_package/container_registry/container_registry_omnibus_spec.rb
@@ -1,10 +1,8 @@
# frozen_string_literal: true
module QA
- RSpec.describe 'Package', :orchestrated, only: { pipeline: :main } do
+ RSpec.describe 'Package', :orchestrated, :skip_live_env do
describe 'Self-managed Container Registry' do
- using RSpec::Parameterized::TableSyntax
-
let(:project) do
Resource::Project.fabricate_via_api! do |project|
project.name = 'project-with-registry'
@@ -49,10 +47,63 @@ module QA
end
context "when tls is disabled" do
- where(:authentication_token_type, :token_name) do
- :personal_access_token | 'Personal Access Token'
- :project_deploy_token | 'Deploy Token'
- :ci_job_token | 'Job Token'
+ where do
+ {
+ 'using docker:18.09.9 and a personal access token' => {
+ docker_client_version: 'docker:18.09.9',
+ authentication_token_type: :personal_access_token,
+ token_name: 'Personal Access Token',
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/348499'
+ },
+ 'using docker:18.09.9 and a project deploy token' => {
+ docker_client_version: 'docker:18.09.9',
+ authentication_token_type: :project_deploy_token,
+ token_name: 'Deploy Token',
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/348852'
+ },
+ 'using docker:18.09.9 and a ci job token' => {
+ docker_client_version: 'docker:18.09.9',
+ authentication_token_type: :ci_job_token,
+ token_name: 'Job Token',
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/348765'
+ },
+ 'using docker:19.03.12 and a personal access token' => {
+ docker_client_version: 'docker:19.03.12',
+ authentication_token_type: :personal_access_token,
+ token_name: 'Personal Access Token',
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/348507'
+ },
+ 'using docker:19.03.12 and a project deploy token' => {
+ docker_client_version: 'docker:19.03.12',
+ authentication_token_type: :project_deploy_token,
+ token_name: 'Deploy Token',
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/348859'
+ },
+ 'using docker:19.03.12 and a ci job token' => {
+ docker_client_version: 'docker:19.03.12',
+ authentication_token_type: :ci_job_token,
+ token_name: 'Job Token',
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/348654'
+ },
+ 'using docker:20.10 and a personal access token' => {
+ docker_client_version: 'docker:20.10',
+ authentication_token_type: :personal_access_token,
+ token_name: 'Personal Access Token',
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/348754'
+ },
+ 'using docker:20.10 and a project deploy token' => {
+ docker_client_version: 'docker:20.10',
+ authentication_token_type: :project_deploy_token,
+ token_name: 'Deploy Token',
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/348856'
+ },
+ 'using docker:20.10 and a ci job token' => {
+ docker_client_version: 'docker:20.10',
+ authentication_token_type: :ci_job_token,
+ token_name: 'Job Token',
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/348766'
+ }
+ }
end
with_them do
@@ -78,57 +129,51 @@ module QA
end
end
- where(:docker_client_version) do
- %w[docker:18.09.9 docker:19.03.12 docker:20.10]
- end
-
- with_them do
- it "pushes image and deletes tag", :registry do
- Support::Retrier.retry_on_exception(max_attempts: 3, sleep_interval: 2) do
- Resource::Repository::Commit.fabricate_via_api! do |commit|
- commit.project = project
- commit.commit_message = 'Add .gitlab-ci.yml'
- commit.add_files([{
- file_path: '.gitlab-ci.yml',
- content:
- <<~YAML
- build:
- image: "#{docker_client_version}"
- stage: build
- services:
- - name: "#{docker_client_version}-dind"
- command: ["--insecure-registry=gitlab.test:5050"]
- variables:
- IMAGE_TAG: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG
- script:
- - docker login -u #{auth_user} -p #{auth_token} gitlab.test:5050
- - docker build -t $IMAGE_TAG .
- - docker push $IMAGE_TAG
- tags:
- - "runner-for-#{project.name}"
- YAML
- }])
- end
+ it "pushes image and deletes tag", :registry, testcase: params[:testcase] do
+ Support::Retrier.retry_on_exception(max_attempts: 3, sleep_interval: 2) do
+ Resource::Repository::Commit.fabricate_via_api! do |commit|
+ commit.project = project
+ commit.commit_message = 'Add .gitlab-ci.yml'
+ commit.add_files([{
+ file_path: '.gitlab-ci.yml',
+ content:
+ <<~YAML
+ build:
+ image: "#{docker_client_version}"
+ stage: build
+ services:
+ - name: "#{docker_client_version}-dind"
+ command: ["--insecure-registry=gitlab.test:5050"]
+ variables:
+ IMAGE_TAG: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG
+ script:
+ - docker login -u #{auth_user} -p #{auth_token} gitlab.test:5050
+ - docker build -t $IMAGE_TAG .
+ - docker push $IMAGE_TAG
+ tags:
+ - "runner-for-#{project.name}"
+ YAML
+ }])
end
+ end
- Flow::Pipeline.visit_latest_pipeline
+ Flow::Pipeline.visit_latest_pipeline
- Page::Project::Pipeline::Show.perform do |pipeline|
- pipeline.click_job('build')
- end
+ 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: 800)
- end
+ Page::Project::Job::Show.perform do |job|
+ expect(job).to be_successful(timeout: 800)
+ end
- Page::Project::Menu.perform(&:go_to_container_registry)
+ Page::Project::Menu.perform(&:go_to_container_registry)
- Page::Project::Registry::Show.perform do |registry|
- expect(registry).to have_registry_repository(project.path_with_namespace)
+ Page::Project::Registry::Show.perform do |registry|
+ expect(registry).to have_registry_repository(project.path_with_namespace)
- registry.click_on_image(project.path_with_namespace)
- expect(registry).to have_tag('master')
- end
+ registry.click_on_image(project.path_with_namespace)
+ expect(registry).to have_tag('master')
end
end
end
@@ -156,7 +201,7 @@ module QA
apk add --no-cache openssl
true | openssl s_client -showcerts -connect gitlab.test:5050 > /usr/local/share/ca-certificates/gitlab.test.crt
update-ca-certificates
- dockerd-entrypoint.sh || exit
+ dockerd-entrypoint.sh || exit
variables:
IMAGE_TAG: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG
script:
diff --git a/qa/qa/specs/features/browser_ui/5_package/package_registry/maven/maven_group_level_spec.rb b/qa/qa/specs/features/browser_ui/5_package/package_registry/maven/maven_group_level_spec.rb
new file mode 100644
index 00000000000..9ef5b8c84fa
--- /dev/null
+++ b/qa/qa/specs/features/browser_ui/5_package/package_registry/maven/maven_group_level_spec.rb
@@ -0,0 +1,314 @@
+# frozen_string_literal: true
+
+module QA
+ RSpec.describe 'Package', :orchestrated, :packages, :object_storage do
+ describe 'Maven group level endpoint' do
+ include Runtime::Fixtures
+ include_context 'packages registry qa scenario'
+
+ let(:group_id) { 'com.gitlab.qa' }
+ let(:artifact_id) { "maven-#{SecureRandom.hex(8)}" }
+ let(:package_name) { "#{group_id}/#{artifact_id}".tr('.', '/') }
+ let(:package_version) { '1.3.7' }
+ let(:package_type) { 'maven' }
+
+ context 'via maven' do
+ where do
+ {
+ 'using a personal access token' => {
+ authentication_token_type: :personal_access_token,
+ maven_header_name: 'Private-Token',
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347582'
+ },
+ 'using a project deploy token' => {
+ authentication_token_type: :project_deploy_token,
+ maven_header_name: 'Deploy-Token',
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347585'
+ },
+ 'using a ci job token' => {
+ authentication_token_type: :ci_job_token,
+ maven_header_name: 'Job-Token',
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347579'
+ }
+ }
+ end
+
+ with_them do
+ let(:token) do
+ case authentication_token_type
+ when :personal_access_token
+ personal_access_token
+ when :ci_job_token
+ '${env.CI_JOB_TOKEN}'
+ when :project_deploy_token
+ project_deploy_token.token
+ end
+ end
+
+ it 'pushes and pulls a maven package', testcase: params[:testcase] do
+ Support::Retrier.retry_on_exception(max_attempts: 3, sleep_interval: 2) do
+ Resource::Repository::Commit.fabricate_via_api! do |commit|
+ maven_upload_package_yaml = ERB.new(read_fixture('package_managers/maven', 'maven_upload_package.yaml.erb')).result(binding)
+ package_pom_xml = ERB.new(read_fixture('package_managers/maven', 'package_pom.xml.erb')).result(binding)
+ settings_xml = ERB.new(read_fixture('package_managers/maven', 'settings.xml.erb')).result(binding)
+
+ commit.project = package_project
+ commit.commit_message = 'Add files'
+ commit.add_files([
+ {
+ file_path: '.gitlab-ci.yml',
+ content: maven_upload_package_yaml
+ },
+ {
+ file_path: 'pom.xml',
+ content: package_pom_xml
+ },
+ {
+ file_path: 'settings.xml',
+ content: settings_xml
+ }
+ ])
+ end
+ end
+
+ package_project.visit!
+
+ Flow::Pipeline.visit_latest_pipeline
+
+ Page::Project::Pipeline::Show.perform do |pipeline|
+ pipeline.click_job('deploy')
+ end
+
+ Page::Project::Job::Show.perform do |job|
+ expect(job).to be_successful(timeout: 800)
+ end
+
+ Page::Project::Menu.perform(&:click_packages_link)
+
+ Page::Project::Packages::Index.perform do |index|
+ expect(index).to have_package(package_name)
+
+ index.click_package(package_name)
+ end
+
+ Page::Project::Packages::Show.perform do |show|
+ expect(show).to have_package_info(package_name, package_version)
+ end
+
+ Support::Retrier.retry_on_exception(max_attempts: 3, sleep_interval: 2) do
+ Resource::Repository::Commit.fabricate_via_api! do |commit|
+ maven_install_package_yaml = ERB.new(read_fixture('package_managers/maven', 'maven_install_package.yaml.erb')).result(binding)
+ client_pom_xml = ERB.new(read_fixture('package_managers/maven', 'client_pom.xml.erb')).result(binding)
+ settings_xml = ERB.new(read_fixture('package_managers/maven', 'settings.xml.erb')).result(binding)
+
+ commit.project = client_project
+ commit.commit_message = 'Add files'
+ commit.add_files([
+ {
+ file_path: '.gitlab-ci.yml',
+ content: maven_install_package_yaml
+ },
+ {
+ file_path: 'pom.xml',
+ content: client_pom_xml
+ },
+ {
+ file_path: 'settings.xml',
+ content: settings_xml
+ }
+ ])
+ end
+ end
+
+ client_project.visit!
+
+ Flow::Pipeline.visit_latest_pipeline
+
+ Page::Project::Pipeline::Show.perform do |pipeline|
+ pipeline.click_job('install')
+ end
+
+ Page::Project::Job::Show.perform do |job|
+ expect(job).to be_successful(timeout: 800)
+ end
+ end
+ end
+ end
+
+ context 'duplication setting' do
+ before do
+ package_project.group.visit!
+
+ Page::Group::Menu.perform(&:go_to_package_settings)
+ end
+
+ context 'when disabled' do
+ where do
+ {
+ 'using a personal access token' => {
+ authentication_token_type: :personal_access_token,
+ maven_header_name: 'Private-Token',
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347581'
+ },
+ 'using a project deploy token' => {
+ authentication_token_type: :project_deploy_token,
+ maven_header_name: 'Deploy-Token',
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347584'
+ },
+ 'using a ci job token' => {
+ authentication_token_type: :ci_job_token,
+ maven_header_name: 'Job-Token',
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347578'
+ }
+ }
+ end
+
+ with_them do
+ let(:token) do
+ case authentication_token_type
+ when :personal_access_token
+ personal_access_token
+ when :ci_job_token
+ '${env.CI_JOB_TOKEN}'
+ when :project_deploy_token
+ project_deploy_token.token
+ end
+ end
+
+ before do
+ Page::Group::Settings::PackageRegistries.perform(&:set_allow_duplicates_disabled)
+ end
+
+ it 'prevents users from publishing group level Maven packages duplicates', testcase: params[:testcase] do
+ create_duplicated_package
+
+ push_duplicated_package
+
+ client_project.visit!
+
+ show_latest_deploy_job
+
+ Page::Project::Job::Show.perform do |job|
+ expect(job).not_to be_successful(timeout: 800)
+ end
+ end
+ end
+ end
+
+ context 'when enabled' do
+ where do
+ {
+ 'using a personal access token' => {
+ authentication_token_type: :personal_access_token,
+ maven_header_name: 'Private-Token',
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347580'
+ },
+ 'using a project deploy token' => {
+ authentication_token_type: :project_deploy_token,
+ maven_header_name: 'Deploy-Token',
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347583'
+ },
+ 'using a ci job token' => {
+ authentication_token_type: :ci_job_token,
+ maven_header_name: 'Job-Token',
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347577'
+ }
+ }
+ end
+
+ with_them do
+ let(:token) do
+ case authentication_token_type
+ when :personal_access_token
+ personal_access_token
+ when :ci_job_token
+ '${env.CI_JOB_TOKEN}'
+ when :project_deploy_token
+ project_deploy_token.token
+ end
+ end
+
+ before do
+ Page::Group::Settings::PackageRegistries.perform(&:set_allow_duplicates_enabled)
+ end
+
+ it 'allows users to publish group level Maven packages duplicates', testcase: params[:testcase] do
+ create_duplicated_package
+
+ push_duplicated_package
+
+ show_latest_deploy_job
+
+ Page::Project::Job::Show.perform do |job|
+ expect(job).to be_successful(timeout: 800)
+ end
+ end
+ end
+ end
+
+ def create_duplicated_package
+ settings_xml_with_pat = ERB.new(read_fixture('package_managers/maven', 'settings_with_pat.xml.erb')).result(binding)
+ package_pom_xml = ERB.new(read_fixture('package_managers/maven', 'package_pom.xml.erb')).result(binding)
+
+ with_fixtures([
+ {
+ file_path: 'pom.xml',
+ content: package_pom_xml
+ },
+ {
+ file_path: 'settings.xml',
+ content: settings_xml_with_pat
+ }
+ ]) do |dir|
+ Service::DockerRun::Maven.new(dir).publish!
+ end
+
+ package_project.visit!
+
+ Page::Project::Menu.perform(&:click_packages_link)
+
+ Page::Project::Packages::Index.perform do |index|
+ expect(index).to have_package(package_name)
+ end
+ end
+
+ def push_duplicated_package
+ Support::Retrier.retry_on_exception(max_attempts: 3, sleep_interval: 2) do
+ Resource::Repository::Commit.fabricate_via_api! do |commit|
+ maven_upload_package_yaml = ERB.new(read_fixture('package_managers/maven', 'maven_upload_package.yaml.erb')).result(binding)
+ package_pom_xml = ERB.new(read_fixture('package_managers/maven', 'package_pom.xml.erb')).result(binding)
+ settings_xml = ERB.new(read_fixture('package_managers/maven', 'settings.xml.erb')).result(binding)
+
+ commit.project = client_project
+ commit.commit_message = 'Add .gitlab-ci.yml'
+ commit.add_files([
+ {
+ file_path: '.gitlab-ci.yml',
+ content: maven_upload_package_yaml
+ },
+ {
+ file_path: 'pom.xml',
+ content: package_pom_xml
+ },
+ {
+ file_path: 'settings.xml',
+ content: settings_xml
+ }
+ ])
+ end
+ end
+ end
+
+ def show_latest_deploy_job
+ client_project.visit!
+
+ Flow::Pipeline.visit_latest_pipeline
+
+ Page::Project::Pipeline::Show.perform do |pipeline|
+ pipeline.click_job('deploy')
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/specs/features/browser_ui/5_package/package_registry/maven/maven_project_level_spec.rb b/qa/qa/specs/features/browser_ui/5_package/package_registry/maven/maven_project_level_spec.rb
new file mode 100644
index 00000000000..d79f65764d4
--- /dev/null
+++ b/qa/qa/specs/features/browser_ui/5_package/package_registry/maven/maven_project_level_spec.rb
@@ -0,0 +1,219 @@
+# frozen_string_literal: true
+
+module QA
+ RSpec.describe 'Package', :orchestrated, :packages, :object_storage do
+ describe 'Maven project level endpoint' do
+ let(:group_id) { 'com.gitlab.qa' }
+ let(:artifact_id) { "maven-#{SecureRandom.hex(8)}" }
+ let(:package_name) { "#{group_id}/#{artifact_id}".tr('.', '/') }
+ let(:package_version) { '1.3.7' }
+ let(:package_type) { 'maven' }
+ let(:personal_access_token) { Runtime::Env.personal_access_token }
+
+ let(:package_project) do
+ Resource::Project.fabricate_via_api! do |project|
+ project.name = "#{package_type}_package_project"
+ project.initialize_with_readme = true
+ project.visibility = :private
+ end
+ end
+
+ let(:package) do
+ Resource::Package.init do |package|
+ package.name = package_name
+ package.project = package_project
+ end
+ end
+
+ let(:runner) do
+ Resource::Runner.fabricate! do |runner|
+ runner.name = "qa-runner-#{Time.now.to_i}"
+ runner.tags = ["runner-for-#{package_project.name}"]
+ runner.executor = :docker
+ runner.project = package_project
+ end
+ end
+
+ let(:gitlab_address_with_port) do
+ uri = URI.parse(Runtime::Scenario.gitlab_address)
+ "#{uri.scheme}://#{uri.host}:#{uri.port}"
+ end
+
+ let(:project_deploy_token) do
+ Resource::ProjectDeployToken.fabricate_via_api! do |deploy_token|
+ deploy_token.name = 'package-deploy-token'
+ deploy_token.project = package_project
+ deploy_token.scopes = %w[
+ read_repository
+ read_package_registry
+ write_package_registry
+ ]
+ end
+ end
+
+ let(:gitlab_ci_file) do
+ {
+ file_path: '.gitlab-ci.yml',
+ content:
+ <<~YAML
+ deploy-and-install:
+ image: maven:3.6-jdk-11
+ script:
+ - 'mvn deploy -s settings.xml'
+ - 'mvn install -s settings.xml'
+ only:
+ - "#{package_project.default_branch}"
+ tags:
+ - "runner-for-#{package_project.name}"
+ YAML
+ }
+ end
+
+ let(:pom_file) do
+ {
+ file_path: 'pom.xml',
+ content: <<~XML
+ <project>
+ <groupId>#{group_id}</groupId>
+ <artifactId>#{artifact_id}</artifactId>
+ <version>#{package_version}</version>
+ <modelVersion>4.0.0</modelVersion>
+ <repositories>
+ <repository>
+ <id>#{package_project.name}</id>
+ <url>#{gitlab_address_with_port}/api/v4/projects/#{package_project.id}/-/packages/maven</url>
+ </repository>
+ </repositories>
+ <distributionManagement>
+ <repository>
+ <id>#{package_project.name}</id>
+ <url>#{gitlab_address_with_port}/api/v4/projects/#{package_project.id}/packages/maven</url>
+ </repository>
+ <snapshotRepository>
+ <id>#{package_project.name}</id>
+ <url>#{gitlab_address_with_port}/api/v4/projects/#{package_project.id}/packages/maven</url>
+ </snapshotRepository>
+ </distributionManagement>
+ </project>
+ XML
+ }
+ end
+
+ before do
+ Flow::Login.sign_in_unless_signed_in
+ runner
+ end
+
+ after do
+ runner.remove_via_api!
+ package.remove_via_api!
+ package_project.remove_via_api!
+ end
+
+ where do
+ {
+ 'using a personal access token' => {
+ authentication_token_type: :personal_access_token,
+ maven_header_name: 'Private-Token',
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/354347'
+ },
+ 'using a project deploy token' => {
+ authentication_token_type: :project_deploy_token,
+ maven_header_name: 'Deploy-Token',
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/354348'
+ },
+ 'using a ci job token' => {
+ authentication_token_type: :ci_job_token,
+ maven_header_name: 'Job-Token',
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/354349'
+ }
+ }
+ end
+
+ with_them do
+ let(:token) do
+ case authentication_token_type
+ when :personal_access_token
+ personal_access_token
+ when :ci_job_token
+ '${env.CI_JOB_TOKEN}'
+ when :project_deploy_token
+ project_deploy_token.token
+ end
+ end
+
+ let(:settings_xml) do
+ {
+ file_path: 'settings.xml',
+ content: <<~XML
+ <settings xmlns="http://maven.apache.org/SETTINGS/1.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.1.0 http://maven.apache.org/xsd/settings-1.1.0.xsd">
+ <servers>
+ <server>
+ <id>#{package_project.name}</id>
+ <configuration>
+ <httpHeaders>
+ <property>
+ <name>#{maven_header_name}</name>
+ <value>#{token}</value>
+ </property>
+ </httpHeaders>
+ </configuration>
+ </server>
+ </servers>
+ </settings>
+ XML
+ }
+ end
+
+ it 'pushes and pulls a maven package via maven', testcase: params[:testcase] do
+ Support::Retrier.retry_on_exception(max_attempts: 3, sleep_interval: 2) do
+ Resource::Repository::Commit.fabricate_via_api! do |commit|
+ commit.project = package_project
+ commit.commit_message = 'Add .gitlab-ci.yml'
+ commit.add_files([
+ gitlab_ci_file,
+ pom_file,
+ settings_xml
+ ])
+ end
+ end
+
+ package_project.visit!
+
+ Flow::Pipeline.visit_latest_pipeline
+
+ Page::Project::Pipeline::Show.perform do |pipeline|
+ pipeline.click_job('deploy')
+ end
+
+ Page::Project::Job::Show.perform do |job|
+ expect(job).to be_successful(timeout: 800)
+
+ job.click_element(:pipeline_path)
+ end
+
+ Page::Project::Pipeline::Show.perform do |pipeline|
+ pipeline.click_job('install')
+ end
+
+ Page::Project::Job::Show.perform do |job|
+ expect(job).to be_successful(timeout: 800)
+ end
+
+ Page::Project::Menu.perform(&:click_packages_link)
+
+ Page::Project::Packages::Index.perform do |index|
+ expect(index).to have_package(package_name)
+
+ index.click_package(package_name)
+ end
+
+ Page::Project::Packages::Show.perform do |show|
+ expect(show).to have_package_info(package_name, package_version)
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/specs/features/browser_ui/5_package/package_registry/maven_repository_spec.rb b/qa/qa/specs/features/browser_ui/5_package/package_registry/maven_repository_spec.rb
deleted file mode 100644
index b4ebb9dd475..00000000000
--- a/qa/qa/specs/features/browser_ui/5_package/package_registry/maven_repository_spec.rb
+++ /dev/null
@@ -1,233 +0,0 @@
-# frozen_string_literal: true
-
-module QA
- RSpec.describe 'Package', :orchestrated, :packages, :object_storage do
- describe 'Maven Repository' do
- using RSpec::Parameterized::TableSyntax
- include Runtime::Fixtures
- include_context 'packages registry qa scenario'
-
- let(:group_id) { 'com.gitlab.qa' }
- let(:artifact_id) { "maven-#{SecureRandom.hex(8)}" }
- let(:package_name) { "#{group_id}/#{artifact_id}".tr('.', '/') }
- let(:package_version) { '1.3.7' }
- let(:package_type) { 'maven' }
-
- where(:authentication_token_type, :maven_header_name) do
- :personal_access_token | 'Private-Token'
- :ci_job_token | 'Job-Token'
- :project_deploy_token | 'Deploy-Token'
- end
-
- with_them do
- let(:token) do
- case authentication_token_type
- when :personal_access_token
- personal_access_token
- when :ci_job_token
- '${env.CI_JOB_TOKEN}'
- when :project_deploy_token
- project_deploy_token.token
- end
- end
-
- it "pushes and pulls a maven package via maven using #{params[:authentication_token_type]}" do
- Support::Retrier.retry_on_exception(max_attempts: 3, sleep_interval: 2) do
- Resource::Repository::Commit.fabricate_via_api! do |commit|
- maven_upload_package_yaml = ERB.new(read_fixture('package_managers/maven', 'maven_upload_package.yaml.erb')).result(binding)
- package_pom_xml = ERB.new(read_fixture('package_managers/maven', 'package_pom.xml.erb')).result(binding)
- settings_xml = ERB.new(read_fixture('package_managers/maven', 'settings.xml.erb')).result(binding)
-
- commit.project = package_project
- commit.commit_message = 'Add files'
- commit.add_files([
- {
- file_path: '.gitlab-ci.yml',
- content: maven_upload_package_yaml
- },
- {
- file_path: 'pom.xml',
- content: package_pom_xml
- },
- {
- file_path: 'settings.xml',
- content: settings_xml
- }
- ])
- end
- end
-
- package_project.visit!
-
- Flow::Pipeline.visit_latest_pipeline
-
- Page::Project::Pipeline::Show.perform do |pipeline|
- pipeline.click_job('deploy')
- end
-
- Page::Project::Job::Show.perform do |job|
- expect(job).to be_successful(timeout: 800)
- end
-
- Page::Project::Menu.perform(&:click_packages_link)
-
- Page::Project::Packages::Index.perform do |index|
- expect(index).to have_package(package_name)
-
- index.click_package(package_name)
- end
-
- Page::Project::Packages::Show.perform do |show|
- expect(show).to have_package_info(package_name, package_version)
- end
-
- Support::Retrier.retry_on_exception(max_attempts: 3, sleep_interval: 2) do
- Resource::Repository::Commit.fabricate_via_api! do |commit|
- maven_install_package_yaml = ERB.new(read_fixture('package_managers/maven', 'maven_install_package.yaml.erb')).result(binding)
- client_pom_xml = ERB.new(read_fixture('package_managers/maven', 'client_pom.xml.erb')).result(binding)
- settings_xml = ERB.new(read_fixture('package_managers/maven', 'settings.xml.erb')).result(binding)
-
- commit.project = client_project
- commit.commit_message = 'Add files'
- commit.add_files([
- {
- file_path: '.gitlab-ci.yml',
- content: maven_install_package_yaml
- },
- {
- file_path: 'pom.xml',
- content: client_pom_xml
- },
- {
- file_path: 'settings.xml',
- content: settings_xml
- }
- ])
- end
- end
-
- client_project.visit!
-
- Flow::Pipeline.visit_latest_pipeline
-
- Page::Project::Pipeline::Show.perform do |pipeline|
- pipeline.click_job('install')
- end
-
- Page::Project::Job::Show.perform do |job|
- expect(job).to be_successful(timeout: 800)
- end
- end
-
- context 'duplication setting' do
- before do
- package_project.group.visit!
-
- Page::Group::Menu.perform(&:go_to_package_settings)
- end
-
- context 'when disabled' do
- before do
- Page::Group::Settings::PackageRegistries.perform(&:set_allow_duplicates_disabled)
- end
-
- it "prevents users from publishing group level Maven packages duplicates using #{params[:authentication_token_type]}" do
- create_duplicated_package
-
- push_duplicated_package
-
- client_project.visit!
-
- show_latest_deploy_job
-
- Page::Project::Job::Show.perform do |job|
- expect(job).not_to be_successful(timeout: 800)
- end
- end
- end
-
- context 'when enabled' do
- before do
- Page::Group::Settings::PackageRegistries.perform(&:set_allow_duplicates_enabled)
- end
-
- it "allows users to publish group level Maven packages duplicates using #{params[:authentication_token_type]}" do
- create_duplicated_package
-
- push_duplicated_package
-
- show_latest_deploy_job
-
- Page::Project::Job::Show.perform do |job|
- expect(job).to be_successful(timeout: 800)
- end
- end
- end
-
- def create_duplicated_package
- settings_xml_with_pat = ERB.new(read_fixture('package_managers/maven', 'settings_with_pat.xml.erb')).result(binding)
- package_pom_xml = ERB.new(read_fixture('package_managers/maven', 'package_pom.xml.erb')).result(binding)
-
- with_fixtures([
- {
- file_path: 'pom.xml',
- content: package_pom_xml
- },
- {
- file_path: 'settings.xml',
- content: settings_xml_with_pat
- }
- ]) do |dir|
- Service::DockerRun::Maven.new(dir).publish!
- end
-
- package_project.visit!
-
- Page::Project::Menu.perform(&:click_packages_link)
-
- Page::Project::Packages::Index.perform do |index|
- expect(index).to have_package(package_name)
- end
- end
-
- def push_duplicated_package
- Support::Retrier.retry_on_exception(max_attempts: 3, sleep_interval: 2) do
- Resource::Repository::Commit.fabricate_via_api! do |commit|
- maven_upload_package_yaml = ERB.new(read_fixture('package_managers/maven', 'maven_upload_package.yaml.erb')).result(binding)
- package_pom_xml = ERB.new(read_fixture('package_managers/maven', 'package_pom.xml.erb')).result(binding)
- settings_xml = ERB.new(read_fixture('package_managers/maven', 'settings.xml.erb')).result(binding)
-
- commit.project = client_project
- commit.commit_message = 'Add .gitlab-ci.yml'
- commit.add_files([
- {
- file_path: '.gitlab-ci.yml',
- content: maven_upload_package_yaml
- },
- {
- file_path: 'pom.xml',
- content: package_pom_xml
- },
- {
- file_path: 'settings.xml',
- content: settings_xml
- }
- ])
- end
- end
- end
-
- def show_latest_deploy_job
- client_project.visit!
-
- Flow::Pipeline.visit_latest_pipeline
-
- Page::Project::Pipeline::Show.perform do |pipeline|
- pipeline.click_job('deploy')
- end
- end
- end
- end
- end
- end
-end
diff --git a/qa/qa/specs/features/browser_ui/5_package/package_registry/nuget/nuget_group_level_spec.rb b/qa/qa/specs/features/browser_ui/5_package/package_registry/nuget/nuget_group_level_spec.rb
new file mode 100644
index 00000000000..b0a6555a16b
--- /dev/null
+++ b/qa/qa/specs/features/browser_ui/5_package/package_registry/nuget/nuget_group_level_spec.rb
@@ -0,0 +1,182 @@
+# frozen_string_literal: true
+
+module QA
+ RSpec.describe 'Package', :orchestrated, :packages, :object_storage do
+ describe 'NuGet group level endpoint' do
+ using RSpec::Parameterized::TableSyntax
+ include Runtime::Fixtures
+
+ let(:project) do
+ Resource::Project.fabricate_via_api! do |project|
+ project.name = 'nuget-package-project'
+ project.template_name = 'dotnetcore'
+ project.visibility = :private
+ end
+ end
+
+ let(:personal_access_token) do
+ unless Page::Main::Menu.perform(&:signed_in?)
+ Flow::Login.sign_in
+ end
+
+ Resource::PersonalAccessToken.fabricate!
+ end
+
+ let(:group_deploy_token) do
+ Resource::GroupDeployToken.fabricate_via_api! do |deploy_token|
+ deploy_token.name = 'nuget-group-deploy-token'
+ deploy_token.group = project.group
+ deploy_token.scopes = %w[
+ read_repository
+ read_package_registry
+ write_package_registry
+ ]
+ end
+ end
+
+ let(:package) do
+ Resource::Package.init do |package|
+ package.name = "dotnetcore-#{SecureRandom.hex(8)}"
+ package.project = project
+ end
+ end
+
+ let(:another_project) do
+ Resource::Project.fabricate_via_api! do |another_project|
+ another_project.name = 'nuget-package-install-project'
+ another_project.template_name = 'dotnetcore'
+ another_project.group = project.group
+ end
+ end
+
+ let!(:runner) do
+ Resource::Runner.fabricate! do |runner|
+ runner.name = "qa-runner-#{Time.now.to_i}"
+ runner.tags = ["runner-for-#{project.group.name}"]
+ runner.executor = :docker
+ runner.token = project.group.reload!.runners_token
+ end
+ end
+
+ after do
+ runner.remove_via_api!
+ package.remove_via_api!
+ end
+
+ where(:case_name, :authentication_token_type, :token_name, :testcase) do
+ 'using personal access token' | :personal_access_token | 'Personal Access Token' | 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347597'
+ 'using ci job token' | :ci_job_token | 'CI Job Token' | 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347595'
+ 'using group deploy token' | :group_deploy_token | 'Deploy Token' | 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347596'
+ end
+
+ with_them do
+ let(:auth_token_password) do
+ case authentication_token_type
+ when :personal_access_token
+ "\"#{personal_access_token.token}\""
+ when :ci_job_token
+ '${CI_JOB_TOKEN}'
+ when :group_deploy_token
+ "\"#{group_deploy_token.token}\""
+ end
+ end
+
+ let(:auth_token_username) do
+ case authentication_token_type
+ when :personal_access_token
+ "\"#{personal_access_token.user.username}\""
+ when :ci_job_token
+ 'gitlab-ci-token'
+ when :group_deploy_token
+ "\"#{group_deploy_token.username}\""
+ end
+ end
+
+ it 'publishes a nuget package at the project endpoint and installs it from the group endpoint', testcase: params[:testcase] do
+ Flow::Login.sign_in
+
+ Support::Retrier.retry_on_exception(max_attempts: 3, sleep_interval: 2) do
+ Resource::Repository::Commit.fabricate_via_api! do |commit|
+ nuget_upload_yaml = ERB.new(read_fixture('package_managers/nuget', 'nuget_upload_package.yaml.erb')).result(binding)
+ commit.project = project
+ commit.commit_message = 'Add .gitlab-ci.yml'
+ commit.update_files(
+ [
+ {
+ file_path: '.gitlab-ci.yml',
+ content: nuget_upload_yaml
+ }
+ ]
+ )
+ end
+ end
+
+ project.visit!
+ Flow::Pipeline.visit_latest_pipeline
+
+ Page::Project::Pipeline::Show.perform do |pipeline|
+ pipeline.click_job('deploy')
+ end
+
+ Page::Project::Job::Show.perform do |job|
+ expect(job).to be_successful(timeout: 800)
+ end
+
+ another_project.visit!
+
+ Support::Retrier.retry_on_exception(max_attempts: 3, sleep_interval: 2) do
+ Resource::Repository::Commit.fabricate_via_api! do |commit|
+ nuget_install_yaml = ERB.new(read_fixture('package_managers/nuget', 'nuget_install_package.yaml.erb')).result(binding)
+
+ commit.project = another_project
+ commit.commit_message = 'Add new csproj file'
+ commit.add_files(
+ [
+ {
+ file_path: 'otherdotnet.csproj',
+ content: <<~EOF
+ <Project Sdk="Microsoft.NET.Sdk">
+
+ <PropertyGroup>
+ <OutputType>Exe</OutputType>
+ <TargetFramework>net5.0</TargetFramework>
+ </PropertyGroup>
+
+ </Project>
+ EOF
+ }
+ ]
+ )
+ commit.update_files(
+ [
+ {
+ file_path: '.gitlab-ci.yml',
+ content: nuget_install_yaml
+ }
+ ]
+ )
+ end
+ end
+
+ Flow::Pipeline.visit_latest_pipeline
+
+ Page::Project::Pipeline::Show.perform do |pipeline|
+ pipeline.click_job('install')
+ end
+
+ Page::Project::Job::Show.perform do |job|
+ expect(job).to be_successful(timeout: 800)
+ end
+
+ project.group.visit!
+
+ Page::Group::Menu.perform(&:go_to_group_packages)
+
+ Page::Project::Packages::Index.perform do |index|
+ expect(index).to have_package(package.name)
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/specs/features/browser_ui/5_package/package_registry/nuget/nuget_project_level_spec.rb b/qa/qa/specs/features/browser_ui/5_package/package_registry/nuget/nuget_project_level_spec.rb
new file mode 100644
index 00000000000..4cac055634e
--- /dev/null
+++ b/qa/qa/specs/features/browser_ui/5_package/package_registry/nuget/nuget_project_level_spec.rb
@@ -0,0 +1,164 @@
+# frozen_string_literal: true
+
+module QA
+ RSpec.describe 'Package', :orchestrated, :packages, :object_storage do
+ describe 'NuGet project level endpoint' do
+ let(:project) do
+ Resource::Project.fabricate_via_api! do |project|
+ project.name = 'nuget-package-project'
+ project.template_name = 'dotnetcore'
+ project.visibility = :private
+ end
+ end
+
+ let(:personal_access_token) do
+ unless Page::Main::Menu.perform(&:signed_in?)
+ Flow::Login.sign_in
+ end
+
+ Resource::PersonalAccessToken.fabricate!
+ end
+
+ let(:project_deploy_token) do
+ Resource::ProjectDeployToken.fabricate_via_api! do |deploy_token|
+ deploy_token.name = 'package-deploy-token'
+ deploy_token.project = project
+ deploy_token.scopes = %w[
+ read_repository
+ read_package_registry
+ write_package_registry
+ ]
+ end
+ end
+
+ let(:package) do
+ Resource::Package.init do |package|
+ package.name = "dotnetcore-#{SecureRandom.hex(8)}"
+ package.project = project
+ end
+ end
+
+ let!(:runner) do
+ Resource::Runner.fabricate! do |runner|
+ runner.name = "qa-runner-#{Time.now.to_i}"
+ runner.tags = ["runner-for-#{project.name}"]
+ runner.executor = :docker
+ runner.project = project
+ end
+ end
+
+ after do
+ runner.remove_via_api!
+ package.remove_via_api!
+ project.remove_via_api!
+ end
+
+ where do
+ {
+ 'using a personal access token' => {
+ authentication_token_type: :personal_access_token,
+ maven_header_name: 'Private-Token',
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/354351'
+ },
+ 'using a project deploy token' => {
+ authentication_token_type: :project_deploy_token,
+ maven_header_name: 'Deploy-Token',
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/354352'
+ },
+ 'using a ci job token' => {
+ authentication_token_type: :ci_job_token,
+ maven_header_name: 'Job-Token',
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/354353'
+ }
+ }
+ end
+
+ with_them do
+ let(:auth_token_password) do
+ case authentication_token_type
+ when :personal_access_token
+ "\"#{personal_access_token.token}\""
+ when :ci_job_token
+ '${CI_JOB_TOKEN}'
+ when :project_deploy_token
+ "\"#{project_deploy_token.token}\""
+ end
+ end
+
+ let(:auth_token_username) do
+ case authentication_token_type
+ when :personal_access_token
+ "\"#{personal_access_token.user.username}\""
+ when :ci_job_token
+ 'gitlab-ci-token'
+ when :project_deploy_token
+ "\"#{project_deploy_token.username}\""
+ end
+ end
+
+ it 'publishes a nuget package and installs', testcase: params[:testcase] do
+ Flow::Login.sign_in
+
+ Support::Retrier.retry_on_exception(max_attempts: 3, sleep_interval: 2) do
+ Resource::Repository::Commit.fabricate_via_api! do |commit|
+ commit.project = project
+ commit.commit_message = 'Add files'
+ commit.update_files(
+ [
+ {
+ file_path: '.gitlab-ci.yml',
+ content: <<~YAML
+ deploy-and-install:
+ image: mcr.microsoft.com/dotnet/sdk:5.0
+ script:
+ - dotnet restore -p:Configuration=Release
+ - dotnet build -c Release
+ - dotnet pack -c Release -p:PackageID=#{package.name}
+ - dotnet nuget add source "$CI_SERVER_URL/api/v4/projects/$CI_PROJECT_ID/packages/nuget/index.json" --name gitlab --username #{auth_token_username} --password #{auth_token_password} --store-password-in-clear-text
+ - dotnet nuget push "bin/Release/*.nupkg" --source gitlab
+ - "dotnet add dotnetcore.csproj package #{package.name} --version 1.0.0"
+ rules:
+ - if: '$CI_COMMIT_BRANCH == "#{project.default_branch}"'
+ tags:
+ - "runner-for-#{project.name}"
+ YAML
+ },
+ {
+ file_path: 'dotnetcore.csproj',
+ content: <<~EOF
+ <Project Sdk="Microsoft.NET.Sdk">
+
+ <PropertyGroup>
+ <OutputType>Exe</OutputType>
+ <TargetFramework>net5.0</TargetFramework>
+ </PropertyGroup>
+
+ </Project>
+ EOF
+ }
+ ]
+ )
+ end
+ end
+
+ project.visit!
+ Flow::Pipeline.visit_latest_pipeline
+
+ Page::Project::Pipeline::Show.perform do |pipeline|
+ pipeline.click_job('deploy-and-install')
+ end
+
+ Page::Project::Job::Show.perform do |job|
+ expect(job).to be_successful(timeout: 800)
+ end
+
+ Page::Project::Menu.perform(&:click_packages_link)
+
+ Page::Project::Packages::Index.perform do |index|
+ expect(index).to have_package(package.name)
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/qa/qa/specs/features/browser_ui/5_package/package_registry/nuget_repository_spec.rb b/qa/qa/specs/features/browser_ui/5_package/package_registry/nuget_repository_spec.rb
deleted file mode 100644
index 24f83bc19fb..00000000000
--- a/qa/qa/specs/features/browser_ui/5_package/package_registry/nuget_repository_spec.rb
+++ /dev/null
@@ -1,182 +0,0 @@
-# frozen_string_literal: true
-
-module QA
- RSpec.describe 'Package', :orchestrated, :packages, :object_storage do
- describe 'NuGet Repository' do
- using RSpec::Parameterized::TableSyntax
- include Runtime::Fixtures
-
- let(:project) do
- Resource::Project.fabricate_via_api! do |project|
- project.name = 'nuget-package-project'
- project.template_name = 'dotnetcore'
- project.visibility = :private
- end
- end
-
- let(:personal_access_token) do
- unless Page::Main::Menu.perform(&:signed_in?)
- Flow::Login.sign_in
- end
-
- Resource::PersonalAccessToken.fabricate!
- end
-
- let(:group_deploy_token) do
- Resource::GroupDeployToken.fabricate_via_api! do |deploy_token|
- deploy_token.name = 'nuget-group-deploy-token'
- deploy_token.group = project.group
- deploy_token.scopes = %w[
- read_repository
- read_package_registry
- write_package_registry
- ]
- end
- end
-
- let(:package) do
- Resource::Package.init do |package|
- package.name = "dotnetcore-#{SecureRandom.hex(8)}"
- package.project = project
- end
- end
-
- let(:another_project) do
- Resource::Project.fabricate_via_api! do |another_project|
- another_project.name = 'nuget-package-install-project'
- another_project.template_name = 'dotnetcore'
- another_project.group = project.group
- end
- end
-
- let!(:runner) do
- Resource::Runner.fabricate! do |runner|
- runner.name = "qa-runner-#{Time.now.to_i}"
- runner.tags = ["runner-for-#{project.group.name}"]
- runner.executor = :docker
- runner.token = project.group.reload!.runners_token
- end
- end
-
- after do
- runner.remove_via_api!
- package.remove_via_api!
- end
-
- where(:case_name, :authentication_token_type, :token_name, :testcase) do
- 'using personal access token' | :personal_access_token | 'Personal Access Token' | 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347597'
- 'using ci job token' | :ci_job_token | 'CI Job Token' | 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347595'
- 'using group deploy token' | :group_deploy_token | 'Deploy Token' | 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347596'
- end
-
- with_them do
- let(:auth_token_password) do
- case authentication_token_type
- when :personal_access_token
- "\"#{personal_access_token.token}\""
- when :ci_job_token
- '${CI_JOB_TOKEN}'
- when :group_deploy_token
- "\"#{group_deploy_token.token}\""
- end
- end
-
- let(:auth_token_username) do
- case authentication_token_type
- when :personal_access_token
- "\"#{personal_access_token.user.username}\""
- when :ci_job_token
- 'gitlab-ci-token'
- when :group_deploy_token
- "\"#{group_deploy_token.username}\""
- end
- end
-
- it 'publishes a nuget package at the project endpoint and installs it from the group endpoint', testcase: params[:testcase] do
- Flow::Login.sign_in
-
- Support::Retrier.retry_on_exception(max_attempts: 3, sleep_interval: 2) do
- Resource::Repository::Commit.fabricate_via_api! do |commit|
- nuget_upload_yaml = ERB.new(read_fixture('package_managers/nuget', 'nuget_upload_package.yaml.erb')).result(binding)
- commit.project = project
- commit.commit_message = 'Add .gitlab-ci.yml'
- commit.update_files(
- [
- {
- file_path: '.gitlab-ci.yml',
- content: nuget_upload_yaml
- }
- ]
- )
- end
- end
-
- project.visit!
- Flow::Pipeline.visit_latest_pipeline
-
- Page::Project::Pipeline::Show.perform do |pipeline|
- pipeline.click_job('deploy')
- end
-
- Page::Project::Job::Show.perform do |job|
- expect(job).to be_successful(timeout: 800)
- end
-
- another_project.visit!
-
- Support::Retrier.retry_on_exception(max_attempts: 3, sleep_interval: 2) do
- Resource::Repository::Commit.fabricate_via_api! do |commit|
- nuget_install_yaml = ERB.new(read_fixture('package_managers/nuget', 'nuget_install_package.yaml.erb')).result(binding)
-
- commit.project = another_project
- commit.commit_message = 'Add new csproj file'
- commit.add_files(
- [
- {
- file_path: 'otherdotnet.csproj',
- content: <<~EOF
- <Project Sdk="Microsoft.NET.Sdk">
-
- <PropertyGroup>
- <OutputType>Exe</OutputType>
- <TargetFramework>net5.0</TargetFramework>
- </PropertyGroup>
-
- </Project>
- EOF
- }
- ]
- )
- commit.update_files(
- [
- {
- file_path: '.gitlab-ci.yml',
- content: nuget_install_yaml
- }
- ]
- )
- end
- end
-
- Flow::Pipeline.visit_latest_pipeline
-
- Page::Project::Pipeline::Show.perform do |pipeline|
- pipeline.click_job('install')
- end
-
- Page::Project::Job::Show.perform do |job|
- expect(job).to be_successful(timeout: 800)
- end
-
- project.group.visit!
-
- Page::Group::Menu.perform(&:go_to_group_packages)
-
- Page::Project::Packages::Index.perform do |index|
- expect(index).to have_package(package.name)
- end
- end
- end
- end
- end
-end
diff --git a/qa/qa/specs/features/browser_ui/6_release/deploy_key/add_deploy_key_spec.rb b/qa/qa/specs/features/browser_ui/6_release/deploy_key/add_deploy_key_spec.rb
index 260c812420c..1661fec03be 100644
--- a/qa/qa/specs/features/browser_ui/6_release/deploy_key/add_deploy_key_spec.rb
+++ b/qa/qa/specs/features/browser_ui/6_release/deploy_key/add_deploy_key_spec.rb
@@ -2,7 +2,7 @@
module QA
RSpec.describe 'Release' do
- describe 'Deploy key creation' do
+ describe 'Deploy key creation', :skip_fips_env do
it 'user adds a deploy key', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/348023' do
Flow::Login.sign_in
@@ -10,7 +10,7 @@ module QA
deploy_key_title = 'deploy key title'
deploy_key_value = key.public_key
- deploy_key = Resource::DeployKey.fabricate! do |resource|
+ deploy_key = Resource::DeployKey.fabricate_via_browser_ui! do |resource|
resource.title = deploy_key_title
resource.key = deploy_key_value
end
diff --git a/qa/qa/specs/features/browser_ui/6_release/deploy_key/clone_using_deploy_key_spec.rb b/qa/qa/specs/features/browser_ui/6_release/deploy_key/clone_using_deploy_key_spec.rb
index c86f75e0b16..ff8dc686991 100644
--- a/qa/qa/specs/features/browser_ui/6_release/deploy_key/clone_using_deploy_key_spec.rb
+++ b/qa/qa/specs/features/browser_ui/6_release/deploy_key/clone_using_deploy_key_spec.rb
@@ -4,7 +4,7 @@ require 'digest/sha1'
module QA
RSpec.describe 'Release', :runner do
- describe 'Git clone using a deploy key' do
+ describe 'Git clone using a deploy key', :skip_fips_env do
let(:runner_name) { "qa-runner-#{SecureRandom.hex(4)}" }
let(:repository_location) { project.repository_ssh_location }
diff --git a/qa/qa/specs/features/browser_ui/7_configure/auto_devops/auto_devops_templates_spec.rb b/qa/qa/specs/features/browser_ui/7_configure/auto_devops/auto_devops_templates_spec.rb
index 718dc9860fb..980c6da2576 100644
--- a/qa/qa/specs/features/browser_ui/7_configure/auto_devops/auto_devops_templates_spec.rb
+++ b/qa/qa/specs/features/browser_ui/7_configure/auto_devops/auto_devops_templates_spec.rb
@@ -56,7 +56,7 @@ module QA
end
Page::Project::Job::Show.perform do |show|
- expect(show).to have_passed(timeout: 360)
+ expect(show).to have_passed(timeout: 800)
end
end
end
diff --git a/qa/qa/specs/features/browser_ui/7_configure/auto_devops/create_project_with_auto_devops_spec.rb b/qa/qa/specs/features/browser_ui/7_configure/auto_devops/create_project_with_auto_devops_spec.rb
index 70321dcafe4..e0cd5a52bfb 100644
--- a/qa/qa/specs/features/browser_ui/7_configure/auto_devops/create_project_with_auto_devops_spec.rb
+++ b/qa/qa/specs/features/browser_ui/7_configure/auto_devops/create_project_with_auto_devops_spec.rb
@@ -10,6 +10,7 @@ module QA
end
before do
+ set_kube_ingress_base_domain(project)
disable_optional_jobs(project)
end
@@ -73,6 +74,15 @@ module QA
private
+ def set_kube_ingress_base_domain(project)
+ Resource::CiVariable.fabricate_via_api! do |resource|
+ resource.project = project
+ resource.key = 'KUBE_INGRESS_BASE_DOMAIN'
+ resource.value = 'example.com'
+ resource.masked = false
+ end
+ end
+
def disable_optional_jobs(project)
%w[
CODE_QUALITY_DISABLED LICENSE_MANAGEMENT_DISABLED
diff --git a/qa/qa/specs/runner.rb b/qa/qa/specs/runner.rb
index a861c13a44c..2b9adf0e870 100644
--- a/qa/qa/specs/runner.rb
+++ b/qa/qa/specs/runner.rb
@@ -7,6 +7,7 @@ module QA
module Specs
class Runner < Scenario::Template
attr_accessor :tty, :tags, :options
+
RegexMismatchError = Class.new(StandardError)
DEFAULT_TEST_PATH_ARGS = ['--', File.expand_path('./features', __dir__)].freeze
@@ -40,9 +41,8 @@ module QA
end
tags_for_rspec.push(%w[--tag ~geo]) unless QA::Runtime::Env.geo_environment?
-
tags_for_rspec.push(%w[--tag ~skip_signup_disabled]) if QA::Runtime::Env.signup_disabled?
-
+ tags_for_rspec.push(%w[--tag ~smoke --tag ~reliable]) if QA::Runtime::Env.skip_smoke_reliable?
tags_for_rspec.push(%w[--tag ~skip_live_env]) if QA::Specs::Helpers::ContextSelector.dot_com?
QA::Runtime::Env.supported_features.each_key do |key|
diff --git a/qa/qa/support/dates.rb b/qa/qa/support/dates.rb
index 3d1f146730b..9e791bc11c5 100644
--- a/qa/qa/support/dates.rb
+++ b/qa/qa/support/dates.rb
@@ -11,6 +11,10 @@ module QA
current_date.next_month.strftime("%Y/%m/%d")
end
+ def thirteen_days_from_now_yyyy_mm_dd
+ (current_date + 13).strftime("%Y/%m/%d")
+ end
+
def format_date(date)
new_date = DateTime.strptime(date, "%Y/%m/%d")
new_date.strftime("%b %-d, %Y")
diff --git a/qa/qa/support/formatters/allure_metadata_formatter.rb b/qa/qa/support/formatters/allure_metadata_formatter.rb
index da35ffde1ae..2ed4ee2066a 100644
--- a/qa/qa/support/formatters/allure_metadata_formatter.rb
+++ b/qa/qa/support/formatters/allure_metadata_formatter.rb
@@ -4,20 +4,41 @@ module QA
module Support
module Formatters
class AllureMetadataFormatter < ::RSpec::Core::Formatters::BaseFormatter
+ include Support::InfluxdbTools
+
::RSpec::Core::Formatters.register(
self,
- :example_started
+ :start,
+ :example_finished
)
- # Starts example
+ # Starts test run
+ # Fetch flakiness data in mr pipelines to help identify unrelated flaky failures
+ #
+ # @param [RSpec::Core::Notifications::StartNotification] _start_notification
+ # @return [void]
+ def start(_start_notification)
+ return unless merge_request_iid # on main runs allure native history has pass rate already
+
+ save_failures
+ log(:debug, "Fetched #{failures.length} flaky testcases!")
+ rescue StandardError => e
+ log(:error, "Failed to fetch flaky spec data for report: #{e}")
+ @failures = {}
+ end
+
+ # Finished example
+ # Add additional metadata to report
+ #
# @param [RSpec::Core::Notifications::ExampleNotification] example_notification
# @return [void]
- def example_started(example_notification)
+ def example_finished(example_notification)
example = example_notification.example
add_quarantine_issue_link(example)
add_failure_issues_link(example)
add_ci_job_link(example)
+ set_flaky_status(example)
end
private
@@ -55,6 +76,66 @@ module QA
example.add_link(name: "Job(#{Runtime::Env.ci_job_name})", url: Runtime::Env.ci_job_url)
end
+
+ # Mark test as flaky
+ #
+ # @param [RSpec::Core::Example] example
+ # @return [void]
+ def set_flaky_status(example)
+ return unless merge_request_iid
+ return unless example.execution_result.status == :failed && failures.key?(example.metadata[:testcase])
+
+ example.set_flaky
+ example.parameter("pass_rate", "#{failures[example.metadata[:testcase]].round(1)}%")
+ log(:debug, "Setting spec as flaky due to present failures in last 14 days!")
+ end
+
+ # Failed spec testcases
+ #
+ # @return [Array]
+ def failures
+ @failures ||= influx_data.lazy.each_with_object({}) do |data, result|
+ # TODO: replace with mr_iid once stats are populated
+ records = data.records.reject { |r| r.values["_value"] == env("CI_PIPELINE_ID") }
+
+ runs = records.count
+ failed = records.count { |r| r.values["status"] == "failed" }
+ pass_rate = 100 - ((failed.to_f / runs.to_f) * 100)
+
+ # Consider spec with a pass rate less than 98% as flaky
+ result[records.last.values["testcase"]] = pass_rate if pass_rate < 98
+ end.compact
+ end
+
+ alias_method :save_failures, :failures
+
+ # Records of previous failures for runs of same type
+ #
+ # @return [Array]
+ def influx_data
+ return [] unless run_type
+
+ query_api.query(query: <<~QUERY).values
+ from(bucket: "#{Support::InfluxdbTools::INFLUX_TEST_METRICS_BUCKET}")
+ |> range(start: -14d)
+ |> filter(fn: (r) => r._measurement == "test-stats")
+ |> filter(fn: (r) => r.run_type == "#{run_type}" and
+ r.status != "pending" and
+ r.quarantined == "false" and
+ r._field == "pipeline_id"
+ )
+ |> group(columns: ["testcase"])
+ QUERY
+ end
+
+ # Print log message
+ #
+ # @param [Symbol] level
+ # @param [String] message
+ # @return [void]
+ def log(level, message)
+ QA::Runtime::Logger.public_send(level, "[Allure]: #{message}")
+ end
end
end
end
diff --git a/qa/qa/support/formatters/test_stats_formatter.rb b/qa/qa/support/formatters/test_stats_formatter.rb
index 430294b0bb6..16fc0a50b1b 100644
--- a/qa/qa/support/formatters/test_stats_formatter.rb
+++ b/qa/qa/support/formatters/test_stats_formatter.rb
@@ -4,6 +4,8 @@ module QA
module Support
module Formatters
class TestStatsFormatter < RSpec::Core::Formatters::BaseFormatter
+ include Support::InfluxdbTools
+
RSpec::Core::Formatters.register(self, :stop)
# Finish test execution
@@ -11,9 +13,6 @@ module QA
# @param [RSpec::Core::Notifications::ExamplesNotification] notification
# @return [void]
def stop(notification)
- return log(:warn, 'Missing QA_INFLUXDB_URL, skipping metrics export!') unless influxdb_url
- return log(:warn, 'Missing QA_INFLUXDB_TOKEN, skipping metrics export!') unless influxdb_token
-
push_test_stats(notification.examples)
push_fabrication_stats
end
@@ -27,7 +26,7 @@ module QA
def push_test_stats(examples)
data = examples.map { |example| test_stats(example) }.compact
- influx_client.write(data: data)
+ write_api.write(data: data)
log(:debug, "Pushed #{data.length} test execution entries to influxdb")
rescue StandardError => e
log(:error, "Failed to push test execution stats to influxdb, error: #{e}")
@@ -42,7 +41,7 @@ module QA
end
return if data.empty?
- influx_client.write(data: data)
+ write_api.write(data: data)
log(:debug, "Pushed #{data.length} resource fabrication entries to influxdb")
rescue StandardError => e
log(:error, "Failed to push fabrication stats to influxdb, error: #{e}")
@@ -66,11 +65,11 @@ module QA
file_path: file_path,
status: example.execution_result.status,
reliable: example.metadata.key?(:reliable).to_s,
- quarantined: example.metadata.key?(:quarantine).to_s,
+ quarantined: quarantined(example.metadata),
retried: ((example.metadata[:retry_attempts] || 0) > 0).to_s,
job_name: job_name,
merge_request: merge_request,
- run_type: env('QA_RUN_TYPE') || run_type,
+ run_type: run_type,
stage: devops_stage(file_path),
testcase: example.metadata[:testcase]
},
@@ -83,7 +82,8 @@ module QA
retry_attempts: example.metadata[:retry_attempts] || 0,
job_url: QA::Runtime::Env.ci_job_url,
pipeline_url: env('CI_PIPELINE_URL'),
- pipeline_id: env('CI_PIPELINE_ID')
+ pipeline_id: env('CI_PIPELINE_ID'),
+ merge_request_iid: merge_request_iid
}
}
rescue StandardError => e
@@ -119,13 +119,6 @@ module QA
}
end
- # Project name
- #
- # @return [String]
- def project_name
- @project_name ||= QA::Runtime::Env.ci_project_name
- end
-
# Base ci job name
#
# @return [String]
@@ -148,26 +141,18 @@ module QA
#
# @return [String]
def merge_request
- @merge_request ||= (!!env('CI_MERGE_REQUEST_IID') || !!env('TOP_UPSTREAM_MERGE_REQUEST_IID')).to_s
+ (!!merge_request_iid).to_s
end
- # Test run type from staging (`gstg`, `gstg-cny`, `gstg-ref`), canary, preprod or production env
+ # Is spec quarantined
#
- # @return [String, nil]
- def run_type
- return unless %w[staging staging-canary staging-ref canary preprod production].include?(project_name)
-
- @run_type ||= begin
- test_subset = if env('NO_ADMIN') == 'true'
- 'sanity-no-admin'
- elsif env('SMOKE_ONLY') == 'true'
- 'sanity'
- else
- 'full'
- end
-
- "#{project_name}-#{test_subset}"
- end
+ # @param [Hash] metadata
+ # @return [String]
+ def quarantined(metadata)
+ return "false" unless metadata.key?(:quarantine)
+ return "true" unless metadata[:quarantine].is_a?(Hash)
+
+ (!Specs::Helpers::Quarantine.quarantined_different_context?(metadata[:quarantine])).to_s
end
# Print log message
@@ -179,16 +164,6 @@ module QA
QA::Runtime::Logger.public_send(level, "[influxdb exporter]: #{message}")
end
- # Return non empty environment variable value
- #
- # @param [String] name
- # @return [String, nil]
- def env(name)
- return unless ENV[name] && !ENV[name].empty?
-
- ENV[name]
- end
-
# Get spec devops stage
#
# @param [String] location
@@ -196,33 +171,6 @@ module QA
def devops_stage(file_path)
file_path.match(%r{\d{1,2}_(\w+)/})&.captures&.first
end
-
- # InfluxDb client
- #
- # @return [InfluxDB2::WriteApi]
- def influx_client
- @influx_client ||= InfluxDB2::Client.new(
- influxdb_url,
- influxdb_token,
- bucket: 'e2e-test-stats',
- org: 'gitlab-qa',
- precision: InfluxDB2::WritePrecision::NANOSECOND
- ).create_write_api
- end
-
- # InfluxDb instance url
- #
- # @return [String]
- def influxdb_url
- @influxdb_url ||= env('QA_INFLUXDB_URL')
- end
-
- # Influxdb token
- #
- # @return [String]
- def influxdb_token
- @influxdb_token ||= env('QA_INFLUXDB_TOKEN')
- end
end
end
end
diff --git a/qa/qa/support/influxdb_tools.rb b/qa/qa/support/influxdb_tools.rb
new file mode 100644
index 00000000000..e53b843ca87
--- /dev/null
+++ b/qa/qa/support/influxdb_tools.rb
@@ -0,0 +1,83 @@
+# frozen_string_literal: true
+
+require "active_support/core_ext/module/delegation"
+
+module QA
+ module Support
+ # Common tools for use with influxdb metrics setup
+ #
+ module InfluxdbTools
+ INFLUX_TEST_METRICS_BUCKET = "e2e-test-stats"
+ LIVE_ENVS = %w[staging staging-canary staging-ref canary preprod production].freeze
+
+ private
+
+ delegate :ci_project_name, to: "QA::Runtime::Env"
+
+ # Query client
+ #
+ # @return [QueryApi]
+ def query_api
+ @query_api ||= influx_client.create_query_api
+ end
+
+ # Write client
+ #
+ # @return [WriteApi]
+ def write_api
+ @write_api ||= influx_client.create_write_api
+ end
+
+ # InfluxDb client
+ #
+ # @return [InfluxDB2::Client]
+ def influx_client
+ @influx_client ||= InfluxDB2::Client.new(
+ ENV["QA_INFLUXDB_URL"] || raise("Missing QA_INFLUXDB_URL env variable"),
+ ENV["QA_INFLUXDB_TOKEN"] || raise("Missing QA_INFLUXDB_TOKEN env variable"),
+ bucket: INFLUX_TEST_METRICS_BUCKET,
+ org: "gitlab-qa",
+ precision: InfluxDB2::WritePrecision::NANOSECOND
+ )
+ end
+
+ # Test run type
+ # Automatically infer for staging (`gstg`, `gstg-cny`, `gstg-ref`), canary, preprod or production env
+ #
+ # @return [String, nil]
+ def run_type
+ @run_type ||= begin
+ return env('QA_RUN_TYPE') if env('QA_RUN_TYPE')
+ return unless LIVE_ENVS.include?(ci_project_name)
+
+ test_subset = if env('NO_ADMIN') == 'true'
+ 'sanity-no-admin'
+ elsif env('SMOKE_ONLY') == 'true'
+ 'sanity'
+ else
+ 'full'
+ end
+
+ "#{ci_project_name}-#{test_subset}"
+ end
+ end
+
+ # Merge request iid
+ #
+ # @return [String]
+ def merge_request_iid
+ env('CI_MERGE_REQUEST_IID') || env('TOP_UPSTREAM_MERGE_REQUEST_IID')
+ end
+
+ # Return non empty environment variable value
+ #
+ # @param [String] name
+ # @return [String, nil]
+ def env(name)
+ return unless ENV[name] && !ENV[name].empty?
+
+ ENV[name]
+ end
+ end
+ end
+end
diff --git a/qa/qa/support/loglinking.rb b/qa/qa/support/loglinking.rb
new file mode 100644
index 00000000000..89519e9537c
--- /dev/null
+++ b/qa/qa/support/loglinking.rb
@@ -0,0 +1,86 @@
+# frozen_string_literal: true
+module QA
+ module Support
+ module Loglinking
+ # Static address variables declared for mapping environment to logging URLs
+ STAGING_ADDRESS = 'https://staging.gitlab.com'
+ STAGING_REF_ADDRESS = 'https://staging-ref.gitlab.com'
+ PRODUCTION_ADDRESS = 'https://www.gitlab.com'
+ PRE_PROD_ADDRESS = 'https://pre.gitlab.com'
+ SENTRY_ENVIRONMENTS = {
+ staging: 'https://sentry.gitlab.net/gitlab/staginggitlabcom/?environment=gstg',
+ staging_canary: 'https://sentry.gitlab.net/gitlab/staginggitlabcom/?environment=gstg-cny',
+ staging_ref: 'https://sentry.gitlab.net/gitlab/staging-ref/?environment=gstg-ref',
+ pre: 'https://sentry.gitlab.net/gitlab/pregitlabcom/?environment=pre',
+ canary: 'https://sentry.gitlab.net/gitlab/gitlabcom/?environment=gprd',
+ production: 'https://sentry.gitlab.net/gitlab/gitlabcom/?environment=gprd-cny'
+ }.freeze
+ KIBANA_ENVIRONMENTS = {
+ staging: 'https://nonprod-log.gitlab.net/',
+ staging_canary: 'https://nonprod-log.gitlab.net/',
+ canary: 'https://log.gprd.gitlab.net/',
+ production: 'https://log.gprd.gitlab.net/'
+ }.freeze
+
+ def self.failure_metadata(correlation_id)
+ return if correlation_id.blank?
+
+ sentry_uri = sentry_url
+ kibana_uri = kibana_url
+
+ errors = ["Correlation Id: #{correlation_id}"]
+ errors << "Sentry Url: #{sentry_uri}&query=correlation_id%3A%22#{correlation_id}%22" if sentry_uri
+ errors << "Kibana Url: #{kibana_uri}app/discover#/?_a=(query:(language:kuery,query:'json.correlation_id%20:%20#{correlation_id}'))" if kibana_uri
+
+ errors.join("\n")
+ end
+
+ def self.sentry_url
+ return unless logging_environment?
+
+ SENTRY_ENVIRONMENTS[logging_environment]
+ end
+
+ def self.kibana_url
+ return unless logging_environment?
+
+ KIBANA_ENVIRONMENTS[logging_environment]
+ end
+
+ def self.logging_environment
+ address = QA::Runtime::Scenario.attributes[:gitlab_address]
+ return if address.nil?
+
+ case address
+ when STAGING_ADDRESS
+ canary? ? :staging_canary : :staging
+ when STAGING_REF_ADDRESS
+ :staging_ref
+ when PRODUCTION_ADDRESS
+ canary? ? :canary : :production
+ when PRE_PROD_ADDRESS
+ :pre
+ else
+ nil
+ end
+ end
+
+ def self.logging_environment?
+ !logging_environment.nil?
+ end
+
+ def self.cookies
+ browser_cookies = Capybara.current_session.driver.browser.manage.all_cookies
+ # rubocop:disable Rails/IndexBy
+ browser_cookies.each_with_object({}) do |cookie, memo|
+ memo[cookie[:name]] = cookie
+ end
+ # rubocop:enable Rails/IndexBy
+ end
+
+ def self.canary?
+ cookies.dig('gitlab_canary', :value) == 'true'
+ end
+ end
+ end
+end
diff --git a/qa/qa/support/page_error_checker.rb b/qa/qa/support/page_error_checker.rb
index 5d16245b4cd..ede9b49bda6 100644
--- a/qa/qa/support/page_error_checker.rb
+++ b/qa/qa/support/page_error_checker.rb
@@ -5,14 +5,28 @@ module QA
class PageErrorChecker
class << self
def report!(page, error_code)
+ request_id_string = ''
+ if error_code == 500
+ request_id = parse_five_c_page_request_id(page)
+ if request_id
+ request_id_string = "\n\n" + Loglinking.failure_metadata(request_id)
+ end
+ end
+
report = if QA::Runtime::Env.browser == :chrome
return_chrome_errors(page, error_code)
else
status_code_report(error_code)
end
- raise "#{report}\n\n"\
- "Path: #{page.current_path}"
+ raise "Error Code #{error_code}\n\n"\
+ "#{report}\n\n"\
+ "Path: #{page.current_path}"\
+ "#{request_id_string}"
+ end
+
+ def parse_five_c_page_request_id(page)
+ Nokogiri::HTML.parse(page.html).xpath("/html/body/div/p[1]/code").children.first
end
def return_chrome_errors(page, error_code)
diff --git a/qa/qa/support/repeater.rb b/qa/qa/support/repeater.rb
index 1b9aa809051..6956987de05 100644
--- a/qa/qa/support/repeater.rb
+++ b/qa/qa/support/repeater.rb
@@ -1,6 +1,5 @@
# frozen_string_literal: true
require 'active_support/inflector'
-require 'rainbow/refinement'
module QA
module Support
@@ -40,7 +39,9 @@ module QA
QA::Runtime::Logger.debug(msg.join(' '))
end
- QA::Runtime::Logger.debug("Attempt number #{attempts + 1}".bg(:yellow).black) if log && max_attempts && attempts > 0
+ if log && max_attempts && attempts > 0
+ QA::Runtime::Logger.debug("Attempt number #{attempts + 1}".bg(:yellow).black)
+ end
result = yield
if result
diff --git a/qa/qa/tools/delete_test_resources.rb b/qa/qa/tools/delete_test_resources.rb
deleted file mode 100644
index 6f63c56f736..00000000000
--- a/qa/qa/tools/delete_test_resources.rb
+++ /dev/null
@@ -1,100 +0,0 @@
-# frozen_string_literal: true
-
-# This script reads from test-resources JSON file to collect data about resources to delete
-# Filter out resources that cannot be deleted
-# Then deletes all deletable resources that E2E tests created
-#
-# Required environment variables: GITLAB_QA_ACCESS_TOKEN and GITLAB_ADDRESS
-# When in CI also requires: QA_TEST_RESOURCES_FILE_PATTERN
-# Run `rake delete_test_resources[<file_pattern>]`
-
-module QA
- module Tools
- class DeleteTestResources
- include Support::API
-
- IGNORED_RESOURCES = [
- 'QA::Resource::PersonalAccessToken',
- 'QA::Resource::CiVariable',
- 'QA::Resource::Repository::Commit',
- 'QA::EE::Resource::GroupIteration',
- 'QA::EE::Resource::Settings::Elasticsearch'
- ].freeze
-
- def initialize(file_pattern = Runtime::Env.test_resources_created_filepath)
- raise ArgumentError, "Please provide GITLAB_ADDRESS" unless ENV['GITLAB_ADDRESS']
- raise ArgumentError, "Please provide GITLAB_QA_ACCESS_TOKEN" unless ENV['GITLAB_QA_ACCESS_TOKEN']
-
- @api_client = Runtime::API::Client.new(ENV['GITLAB_ADDRESS'], personal_access_token: ENV['GITLAB_QA_ACCESS_TOKEN'])
- @file_pattern = file_pattern
- end
-
- def run
- failures = files.flat_map do |file|
- resources = read_file(file)
- filtered_resources = filter_resources(resources)
- delete_resources(filtered_resources)
- end
-
- return puts "\nDone" if failures.empty?
-
- puts "\nFailed to delete #{failures.size} resources:\n"
- puts failures
- end
-
- private
-
- def files
- puts "Gathering JSON files...\n"
- files = Dir.glob(@file_pattern)
- abort("There is no file with this pattern #{@file_pattern}") if files.empty?
-
- files.reject { |file| File.zero?(file) }
-
- files
- end
-
- def read_file(file)
- JSON.parse(File.read(file))
- end
-
- def filter_resources(resources)
- puts "Filtering resources - Only keep deletable resources...\n"
-
- transformed_values = resources.transform_values! do |v|
- v.reject do |attributes|
- attributes['info'] == "with full_path 'gitlab-qa-sandbox-group'" ||
- attributes['http_method'] == 'get' && !attributes['info']&.include?("with username 'qa-") ||
- attributes['api_path'] == 'Cannot find resource API path'
- end
- end
-
- transformed_values.reject! { |k, v| v.empty? || IGNORED_RESOURCES.include?(k) }
- end
-
- def delete_resources(resources)
- resources.each_with_object([]) do |(key, value), failures|
- value.each do |resource|
- next if resource_not_found?(resource['api_path'])
-
- msg = resource['info'] ? "#{key} - #{resource['info']}" : "#{key} at #{resource['api_path']}"
- puts "\nDeleting #{msg}..."
- delete_response = delete(Runtime::API::Request.new(@api_client, resource['api_path']).url)
-
- if delete_response.code == 202 || delete_response.code == 204
- print "\e[32m.\e[0m"
- else
- print "\e[31mF\e[0m"
- failures << msg
- end
- end
- end
- end
-
- def resource_not_found?(api_path)
- # if api path contains param "?hard_delete=<boolean>", remove it
- get(Runtime::API::Request.new(@api_client, api_path.split('?').first).url).code.eql? 404
- end
- end
- end
-end
diff --git a/qa/qa/tools/delete_test_users.rb b/qa/qa/tools/delete_test_users.rb
new file mode 100644
index 00000000000..30d3a82fb1b
--- /dev/null
+++ b/qa/qa/tools/delete_test_users.rb
@@ -0,0 +1,87 @@
+# frozen_string_literal: true
+
+# This script deletes users with a username starting with "qa-user-"
+# - Specify `delete_before` to delete only keys that were created before the given date (default: yesterday)
+# - If `dry_run` is true the script will list the users to be deleted by username, but it won't delete them
+# - Specify `exclude_users` as a comma-separated list of usernames to not delete.
+#
+# Required environment variables: GITLAB_QA_ADMIN_ACCESS_TOKEN and GITLAB_ADDRESS
+# - GITLAB_QA_ADMIN_ACCESS_TOKEN must have admin API access
+
+module QA
+ module Tools
+ class DeleteTestUsers
+ include Support::API
+
+ ITEMS_PER_PAGE = '100'
+ EXCLUDE_USERS = %w[qa-user-abc123].freeze
+ FALSY_VALUES = %w[false no 0].freeze
+
+ def initialize(delete_before: (Date.today - 1).to_s, dry_run: 'false', exclude_users: nil)
+ raise ArgumentError, "Please provide GITLAB_ADDRESS" unless ENV['GITLAB_ADDRESS']
+ raise ArgumentError, "Please provide GITLAB_QA_ADMIN_ACCESS_TOKEN" unless ENV['GITLAB_QA_ADMIN_ACCESS_TOKEN']
+
+ @api_client = Runtime::API::Client.new(ENV['GITLAB_ADDRESS'], personal_access_token: ENV['GITLAB_QA_ADMIN_ACCESS_TOKEN'])
+ @dry_run = !FALSY_VALUES.include?(dry_run.to_s.downcase)
+ @delete_before = Date.parse(delete_before)
+ @page_no = '1'
+ @exclude_users = Array(exclude_users.to_s.split(',')) + EXCLUDE_USERS
+ end
+
+ def run
+ puts "Deleting users with a username starting with 'qa-user-' or 'test-user-' created before #{@delete_before}..."
+
+ while page_no.present?
+ users = fetch_test_users
+
+ delete_test_users(users) if users.present?
+ end
+
+ puts "\nDone"
+ end
+
+ private
+
+ attr_reader :dry_run, :page_no
+ alias_method :dry_run?, :dry_run
+
+ def fetch_test_users
+ puts "Fetching QA test users from page #{page_no}..."
+
+ response = get Runtime::API::Request.new(@api_client, "/users", page: page_no, per_page: ITEMS_PER_PAGE).url
+
+ # When we reach the last page, the x-next-page header is a blank string
+ @page_no = response.headers[:x_next_page].to_s
+
+ if @page_no.to_i > 1000
+ puts "Finishing early to avoid timing out the CI job"
+ exit
+ end
+
+ JSON.parse(response.body).select do |user|
+ user['username'].start_with?('qa-user-', 'test-user-') \
+ && (user['name'] == 'QA Tests' || user['name'].start_with?('QA User')) \
+ && !@exclude_users.include?(user['username']) \
+ && Date.parse(user.fetch('created_at', Date.today.to_s)) < @delete_before
+ end
+ end
+
+ def delete_test_users(users)
+ usernames = users.map { |user| user['username'] }.join(', ')
+ if dry_run?
+ puts "Dry run: found users with usernames #{usernames}"
+
+ return
+ end
+
+ puts "Deleting #{users.length} users with usernames #{usernames}..."
+ users.each do |user|
+ delete_response = delete Runtime::API::Request.new(@api_client, "/users/#{user['id']}", hard_delete: 'true').url
+ dot_or_f = delete_response.code == 204 ? "\e[32m.\e[0m" : "\e[31mF\e[0m"
+ print dot_or_f
+ end
+ print "\n"
+ end
+ end
+ end
+end
diff --git a/qa/qa/tools/reliable_report.rb b/qa/qa/tools/reliable_report.rb
index 27e54c2d8bf..96e5690ce30 100644
--- a/qa/qa/tools/reliable_report.rb
+++ b/qa/qa/tools/reliable_report.rb
@@ -8,6 +8,7 @@ require "colorize"
module QA
module Tools
class ReliableReport
+ include Support::InfluxdbTools
include Support::API
# Project for report creation: https://gitlab.com/gitlab-org/gitlab
@@ -15,10 +16,7 @@ module QA
def initialize(range)
@range = range.to_i
- @influxdb_bucket = "e2e-test-stats"
@slack_channel = "#quality-reports"
- @influxdb_url = ENV["QA_INFLUXDB_URL"] || raise("Missing QA_INFLUXDB_URL env variable")
- @influxdb_token = ENV["QA_INFLUXDB_TOKEN"] || raise("Missing QA_INFLUXDB_TOKEN env variable")
end
# Run reliable reporter
@@ -58,7 +56,7 @@ module QA
{
title: "Reliable e2e test report",
description: report_issue_body,
- labels: "Quality,test,type::maintenance,reliable test report,automation:devops-mapping-disable"
+ labels: "Quality,test,type::maintenance,reliable test report,automation:ml"
},
headers: { "PRIVATE-TOKEN" => gitlab_access_token }
)
@@ -91,7 +89,7 @@ module QA
private
- attr_reader :range, :influxdb_bucket, :slack_channel, :influxdb_url, :influxdb_token
+ attr_reader :range, :slack_channel
# Markdown formatted report issue body
#
@@ -304,7 +302,7 @@ module QA
# @return [String]
def query(reliable)
<<~QUERY
- from(bucket: "#{influxdb_bucket}")
+ from(bucket: "#{Support::InfluxdbTools::INFLUX_TEST_METRICS_BUCKET}")
|> range(start: -#{range}d)
|> filter(fn: (r) => r._measurement == "test-stats")
|> filter(fn: (r) => r.run_type == "staging-full" or
@@ -325,26 +323,6 @@ module QA
QUERY
end
- # Query client
- #
- # @return [QueryApi]
- def query_api
- @query_api ||= influx_client.create_query_api
- end
-
- # InfluxDb client
- #
- # @return [InfluxDB2::Client]
- def influx_client
- @influx_client ||= InfluxDB2::Client.new(
- influxdb_url,
- influxdb_token,
- bucket: influxdb_bucket,
- org: "gitlab-qa",
- precision: InfluxDB2::WritePrecision::NANOSECOND
- )
- end
-
# Slack notifier
#
# @return [Slack::Notifier]
diff --git a/qa/qa/tools/test_resource_data_processor.rb b/qa/qa/tools/test_resource_data_processor.rb
index 965919dc516..a86c94b4914 100644
--- a/qa/qa/tools/test_resource_data_processor.rb
+++ b/qa/qa/tools/test_resource_data_processor.rb
@@ -49,10 +49,12 @@ module QA
# Otherwise create file and write data hash to file for the first time
#
# @return [void]
- def write_to_file
+ def write_to_file(suite_failed)
return if resources.empty?
- file = Pathname.new(Runtime::Env.test_resources_created_filepath)
+ start_str = suite_failed ? 'failed-test-resources' : 'test-resources'
+ file_name = Runtime::Env.running_in_ci? ? "#{start_str}-#{SecureRandom.hex(3)}.json" : "#{start_str}.json"
+ file = Pathname.new(File.join(Runtime::Path.qa_root, 'tmp', file_name))
FileUtils.mkdir_p(file.dirname)
data = resources.deep_dup
@@ -79,7 +81,7 @@ module QA
else
default
end
- rescue QA::Resource::Base::NoValueError
+ rescue QA::Resource::Base::NoValueError, QA::Resource::Errors::ResourceNotFoundError
default
end
end
diff --git a/qa/qa/tools/test_resources_handler.rb b/qa/qa/tools/test_resources_handler.rb
new file mode 100644
index 00000000000..476f87fff6b
--- /dev/null
+++ b/qa/qa/tools/test_resources_handler.rb
@@ -0,0 +1,180 @@
+# frozen_string_literal: true
+
+require "fog/google"
+
+# This script handles resources created during E2E test runs
+#
+# Delete: find all matching file pattern, read file and delete resources
+# rake test_resources:delete[<file_pattern>]
+#
+# Upload: find all matching file pattern for failed test resources
+# upload these files to GCS bucket `failed-test-resources` under specific environment name
+# rake test_resources:upload[<file_pattern>,<ci_project_name>]
+#
+# Download: download JSON files under a given environment name (bucket directory)
+# save to local under `tmp/`
+# rake test_resources:download[<ci_project_name>]
+#
+# Required environment variables:
+# GITLAB_ADDRESS, required for delete task
+# GITLAB_QA_ACCESS_TOKEN, required for delete task
+# QA_TEST_RESOURCES_FILE_PATTERN, optional for delete task, required for upload task
+# QA_FAILED_TEST_RESOURCES_GCS_CREDENTIALS, required for upload task or download task
+
+module QA
+ module Tools
+ class TestResourcesHandler
+ include Support::API
+
+ IGNORED_RESOURCES = [
+ 'QA::Resource::PersonalAccessToken',
+ 'QA::Resource::CiVariable',
+ 'QA::Resource::Repository::Commit',
+ 'QA::EE::Resource::GroupIteration',
+ 'QA::EE::Resource::Settings::Elasticsearch'
+ ].freeze
+
+ PROJECT = 'gitlab-qa-resources'
+ BUCKET = 'failed-test-resources'
+
+ def initialize(file_pattern = nil)
+ @file_pattern = file_pattern
+ end
+
+ def run_delete
+ failures = files.flat_map do |file|
+ resources = read_file(file)
+ next if resources.nil?
+
+ filtered_resources = filter_resources(resources)
+ delete_resources(filtered_resources)
+ end
+
+ return puts "\nDone" if failures.empty?
+
+ puts "\nFailed to delete #{failures.size} resources:\n"
+ puts failures
+ end
+
+ # Upload resources from failed test suites to GCS bucket
+ # Files are organized by environment in which tests were executed
+ #
+ # E.g: staging/failed-test-resources-<randomhex>.json
+ def upload(ci_project_name)
+ return puts "\nNothing to upload!" if files.empty?
+
+ files.each do |file|
+ file_name = "#{ci_project_name}/#{file.split('/').last}"
+ Runtime::Logger.info("Uploading #{file_name}...")
+ gcs_storage.put_object(BUCKET, file_name, File.read(file))
+ end
+
+ puts "\nDone"
+ end
+
+ # Download files from GCS bucket by environment name
+ # Delete the files afterward
+ def download(ci_project_name)
+ files_list = gcs_storage.list_objects(BUCKET, prefix: ci_project_name).items.each_with_object([]) do |obj, arr|
+ arr << obj.name
+ end
+
+ return puts "\nNothing to download!" if files_list.empty?
+
+ files_list.each do |file_name|
+ local_path = "tmp/#{file_name.split('/').last}"
+ Runtime::Logger.info("Downloading #{file_name} to #{local_path}")
+ file = gcs_storage.get_object(BUCKET, file_name)
+ File.write(local_path, file[:body])
+
+ Runtime::Logger.info("Deleting #{file_name} from bucket")
+ gcs_storage.delete_object(BUCKET, file_name)
+ end
+
+ puts "\nDone"
+ end
+
+ private
+
+ def files
+ Runtime::Logger.info('Gathering JSON files...')
+ files = Dir.glob(@file_pattern)
+ abort("There is no file with this pattern #{@file_pattern}") if files.empty?
+
+ files.reject! { |file| File.zero?(file) }
+
+ files
+ end
+
+ def read_file(file)
+ JSON.parse(File.read(file))
+ rescue JSON::ParserError
+ Runtime::Logger.error("Failed to read #{file} - Invalid format")
+ nil
+ end
+
+ def filter_resources(resources)
+ Runtime::Logger.info('Filtering resources - Only keep deletable resources...')
+
+ transformed_values = resources.transform_values! do |v|
+ v.reject do |attributes|
+ attributes['info'] == "with full_path 'gitlab-qa-sandbox-group'" ||
+ attributes['http_method'] == 'get' && !attributes['info']&.include?("with username 'qa-") ||
+ attributes['api_path'] == 'Cannot find resource API path'
+ end
+ end
+
+ transformed_values.reject! { |k, v| v.empty? || IGNORED_RESOURCES.include?(k) }
+ end
+
+ def delete_resources(resources)
+ Runtime::Logger.info('Nothing to delete.') && return if resources.nil?
+
+ resources.each_with_object([]) do |(key, value), failures|
+ value.each do |resource|
+ next if resource_not_found?(resource['api_path'])
+
+ resource_info = resource['info'] ? "#{key} - #{resource['info']}" : "#{key} at #{resource['api_path']}"
+ delete_response = delete(Runtime::API::Request.new(api_client, resource['api_path']).url)
+
+ if delete_response.code == 202 || delete_response.code == 204
+ Runtime::Logger.info("Deleting #{resource_info}... SUCCESS")
+ else
+ Runtime::Logger.info("Deleting #{resource_info}... FAILED")
+ failures << resource_info
+ end
+ end
+ end
+ end
+
+ def resource_not_found?(api_path)
+ # if api path contains param "?hard_delete=<boolean>", remove it
+ get(Runtime::API::Request.new(api_client, api_path.split('?').first).url).code.eql? 404
+ end
+
+ def api_client
+ abort("\nPlease provide GITLAB_ADDRESS") unless ENV['GITLAB_ADDRESS']
+ abort("\nPlease provide GITLAB_QA_ACCESS_TOKEN") unless ENV['GITLAB_QA_ACCESS_TOKEN']
+
+ @api_client ||= Runtime::API::Client.new(ENV['GITLAB_ADDRESS'], personal_access_token: ENV['GITLAB_QA_ACCESS_TOKEN'])
+ end
+
+ def gcs_storage
+ @gcs_storage ||= Fog::Storage::Google.new(
+ google_project: PROJECT,
+ **(File.exist?(json_key) ? { google_json_key_location: json_key } : { google_json_key_string: json_key })
+ )
+ rescue StandardError => e
+ abort("\nThere might be something wrong with the JSON key file - [ERROR] #{e}")
+ end
+
+ # Path to GCS service account json key file
+ # Or the content of the key file as a hash
+ def json_key
+ abort("\nPlease provide QA_FAILED_TEST_RESOURCES_GCS_CREDENTIALS") unless ENV['QA_FAILED_TEST_RESOURCES_GCS_CREDENTIALS']
+
+ @json_key ||= ENV["QA_FAILED_TEST_RESOURCES_GCS_CREDENTIALS"]
+ end
+ end
+ end
+end
diff --git a/qa/spec/page/logging_spec.rb b/qa/spec/page/logging_spec.rb
index 98326ecd343..054332eea29 100644
--- a/qa/spec/page/logging_spec.rb
+++ b/qa/spec/page/logging_spec.rb
@@ -4,11 +4,10 @@ require 'capybara/dsl'
RSpec.describe QA::Support::Page::Logging do
let(:page) { double.as_null_object }
+ let(:logger) { Gitlab::QA::TestLogger.logger(level: ::Logger::DEBUG, source: 'QA Tests') }
before do
- logger = ::Logger.new $stdout
- logger.level = ::Logger::DEBUG
- QA::Runtime::Logger.logger = logger
+ allow(QA::Runtime::Logger).to receive(:logger).and_return(logger)
allow(Capybara).to receive(:current_session).and_return(page)
allow(page).to receive(:find).and_return(page)
@@ -59,7 +58,7 @@ RSpec.describe QA::Support::Page::Logging do
it 'logs find_element with class' do
expect { subject.find_element(:element, class: 'active') }
- .to output(/finding :element with args {:class=>\"active\"}/).to_stdout_from_any_process
+ .to output(/finding :element with args {:class=>"active"}/).to_stdout_from_any_process
end
it 'logs click_element' do
@@ -74,40 +73,40 @@ RSpec.describe QA::Support::Page::Logging do
it 'logs has_element?' do
expect { subject.has_element?(:element) }
- .to output(/has_element\? :element \(wait: #{QA::Runtime::Browser::CAPYBARA_MAX_WAIT_TIME}\) returned: true/).to_stdout_from_any_process
+ .to output(/has_element\? :element \(wait: #{QA::Runtime::Browser::CAPYBARA_MAX_WAIT_TIME}\) returned: true/o).to_stdout_from_any_process
end
it 'logs has_element? with text' do
expect { subject.has_element?(:element, text: "some text") }
- .to output(/has_element\? :element with text \"some text\" \(wait: #{QA::Runtime::Browser::CAPYBARA_MAX_WAIT_TIME}\) returned: true/).to_stdout_from_any_process
+ .to output(/has_element\? :element with text "some text" \(wait: #{QA::Runtime::Browser::CAPYBARA_MAX_WAIT_TIME}\) returned: true/o).to_stdout_from_any_process
end
it 'logs has_no_element?' do
allow(page).to receive(:has_no_css?).and_return(true)
expect { subject.has_no_element?(:element) }
- .to output(/has_no_element\? :element \(wait: #{QA::Runtime::Browser::CAPYBARA_MAX_WAIT_TIME}\) returned: true/).to_stdout_from_any_process
+ .to output(/has_no_element\? :element \(wait: #{QA::Runtime::Browser::CAPYBARA_MAX_WAIT_TIME}\) returned: true/o).to_stdout_from_any_process
end
it 'logs has_no_element? with text' do
allow(page).to receive(:has_no_css?).and_return(true)
expect { subject.has_no_element?(:element, text: "more text") }
- .to output(/has_no_element\? :element with text \"more text\" \(wait: #{QA::Runtime::Browser::CAPYBARA_MAX_WAIT_TIME}\) returned: true/).to_stdout_from_any_process
+ .to output(/has_no_element\? :element with text "more text" \(wait: #{QA::Runtime::Browser::CAPYBARA_MAX_WAIT_TIME}\) returned: true/o).to_stdout_from_any_process
end
it 'logs has_text?' do
allow(page).to receive(:has_text?).and_return(true)
expect { subject.has_text? 'foo' }
- .to output(/has_text\?\('foo', wait: #{QA::Runtime::Browser::CAPYBARA_MAX_WAIT_TIME}\) returned true/).to_stdout_from_any_process
+ .to output(/has_text\?\('foo', wait: #{QA::Runtime::Browser::CAPYBARA_MAX_WAIT_TIME}\) returned true/o).to_stdout_from_any_process
end
it 'logs has_no_text?' do
allow(page).to receive(:has_no_text?).with('foo', any_args).and_return(true)
expect { subject.has_no_text? 'foo' }
- .to output(/has_no_text\?\('foo', wait: #{QA::Runtime::Browser::CAPYBARA_MAX_WAIT_TIME}\) returned true/).to_stdout_from_any_process
+ .to output(/has_no_text\?\('foo', wait: #{QA::Runtime::Browser::CAPYBARA_MAX_WAIT_TIME}\) returned true/o).to_stdout_from_any_process
end
it 'logs finished_loading?' do
diff --git a/qa/spec/resource/api_fabricator_spec.rb b/qa/spec/resource/api_fabricator_spec.rb
index 69a95c92332..ec9907916eb 100644
--- a/qa/spec/resource/api_fabricator_spec.rb
+++ b/qa/spec/resource/api_fabricator_spec.rb
@@ -108,15 +108,58 @@ RSpec.describe QA::Resource::ApiFabricator do
context 'when the POST fails' do
let(:post_response) { { error: "Name already taken." } }
- let(:raw_post) { double('Raw POST response', code: 400, body: post_response.to_json) }
+ let(:raw_post) { double('Raw POST response', code: 400, body: post_response.to_json, headers: {}) }
it 'raises a ResourceFabricationFailedError exception' do
expect(api_request).to receive(:new).with(api_client_instance, subject.api_post_path).and_return(double(url: resource_web_url))
expect(subject).to receive(:post).with(resource_web_url, subject.api_post_body).and_return(raw_post)
+ allow(QA::Support::Loglinking).to receive(:logging_environment).and_return(nil)
- expect { subject.fabricate_via_api! }.to raise_error(described_class::ResourceFabricationFailedError, "Fabrication of FooBarResource using the API failed (400) with `#{raw_post}`.")
+ expect { subject.fabricate_via_api! }.to raise_error do |error|
+ expect(error.class).to eql(described_class::ResourceFabricationFailedError)
+ expect(error.to_s).to eql(<<~ERROR.chomp)
+ Fabrication of FooBarResource using the API failed (400) with `#{raw_post}`.\n
+ ERROR
+ end
expect(subject.api_resource).to be_nil
end
+
+ it 'logs a correlation id' do
+ response = double('Raw POST response', code: 400, body: post_response.to_json, headers: { x_request_id: 'foobar' })
+ allow(QA::Support::Loglinking).to receive(:logging_environment).and_return(nil)
+
+ expect(api_request).to receive(:new).with(api_client_instance, subject.api_post_path).and_return(double(url: resource_web_url))
+ expect(subject).to receive(:post).with(resource_web_url, subject.api_post_body).and_return(response)
+
+ expect { subject.fabricate_via_api! }.to raise_error do |error|
+ expect(error.class).to eql(described_class::ResourceFabricationFailedError)
+ expect(error.to_s).to eql(<<~ERROR.chomp)
+ Fabrication of FooBarResource using the API failed (400) with `#{raw_post}`.
+ Correlation Id: foobar
+ ERROR
+ end
+ end
+
+ it 'logs a sentry url from staging' do
+ response = double('Raw POST response', code: 400, body: post_response.to_json, headers: { x_request_id: 'foobar' })
+ cookies = [{ name: 'Foo', value: 'Bar' }, { name: 'gitlab_canary', value: 'true' }]
+
+ allow(Capybara.current_session).to receive_message_chain(:driver, :browser, :manage, :all_cookies).and_return(cookies)
+ allow(QA::Runtime::Scenario).to receive(:attributes).and_return({ gitlab_address: 'https://staging.gitlab.com' })
+
+ expect(api_request).to receive(:new).with(api_client_instance, subject.api_post_path).and_return(double(url: resource_web_url))
+ expect(subject).to receive(:post).with(resource_web_url, subject.api_post_body).and_return(response)
+
+ expect { subject.fabricate_via_api! }.to raise_error do |error|
+ expect(error.class).to eql(described_class::ResourceFabricationFailedError)
+ expect(error.to_s).to eql(<<~ERROR.chomp)
+ Fabrication of FooBarResource using the API failed (400) with `#{raw_post}`.
+ Correlation Id: foobar
+ Sentry Url: https://sentry.gitlab.net/gitlab/staginggitlabcom/?environment=gstg-cny&query=correlation_id%3A%22foobar%22
+ Kibana Url: https://nonprod-log.gitlab.net/app/discover#/?_a=(query:(language:kuery,query:'json.correlation_id%20:%20foobar'))
+ ERROR
+ end
+ end
end
end
diff --git a/qa/spec/resource/reusable_collection_spec.rb b/qa/spec/resource/reusable_collection_spec.rb
index 9116462b396..cb2df6931d0 100644
--- a/qa/spec/resource/reusable_collection_spec.rb
+++ b/qa/spec/resource/reusable_collection_spec.rb
@@ -20,6 +20,10 @@ RSpec.describe QA::Resource::ReusableCollection do
end
def exists?() end
+
+ def reload!
+ Struct.new(:api_resource).new({ marked_for_deletion_on: false })
+ end
end
end
@@ -88,8 +92,22 @@ RSpec.describe QA::Resource::ReusableCollection do
it 'removes each instance of each resource class' do
described_class.remove_all_via_api!
- expect(a_resource_instance.removed).to be true
- expect(another_resource_instance.removed).to be true
+ expect(a_resource_instance.removed).to be_truthy
+ expect(another_resource_instance.removed).to be_truthy
+ end
+
+ context 'when a resource is marked for deletion' do
+ before do
+ marked_for_deletion = Struct.new(:api_resource).new({ marked_for_deletion_on: true })
+
+ allow(a_resource_instance).to receive(:reload!).and_return(marked_for_deletion)
+ allow(another_resource_instance).to receive(:reload!).and_return(marked_for_deletion)
+ end
+
+ it 'does not remove the resource' do
+ expect(a_resource_instance.removed).to be_falsey
+ expect(another_resource_instance.removed).to be_falsy
+ end
end
end
diff --git a/qa/spec/runtime/env_spec.rb b/qa/spec/runtime/env_spec.rb
index 0f752ad96b7..22603497019 100644
--- a/qa/spec/runtime/env_spec.rb
+++ b/qa/spec/runtime/env_spec.rb
@@ -360,36 +360,4 @@ RSpec.describe QA::Runtime::Env do
end
end
end
-
- describe '.test_resources_created_filepath' do
- context 'when not in CI' do
- before do
- allow(described_class).to receive(:running_in_ci?).and_return(false)
- end
-
- it 'returns default path if QA_TEST_RESOURCES_CREATED_FILEPATH is not defined' do
- stub_env('QA_TEST_RESOURCES_CREATED_FILEPATH', nil)
-
- expect(described_class.test_resources_created_filepath).to include('tmp/test-resources.json')
- end
-
- it 'returns path if QA_TEST_RESOURCES_CREATED_FILEPATH is defined' do
- stub_env('QA_TEST_RESOURCES_CREATED_FILEPATH', 'path/to_file')
-
- expect(described_class.test_resources_created_filepath).to eq('path/to_file')
- end
- end
-
- context 'when in CI' do
- before do
- allow(described_class).to receive(:running_in_ci?).and_return(true)
- allow(SecureRandom).to receive(:hex).with(3).and_return('abc123')
- stub_env('QA_TEST_RESOURCES_CREATED_FILEPATH', nil)
- end
-
- it 'returns path with random hex in file name' do
- expect(described_class.test_resources_created_filepath).to include('tmp/test-resources-abc123.json')
- end
- end
- end
end
diff --git a/qa/spec/runtime/logger_spec.rb b/qa/spec/runtime/logger_spec.rb
index a888bf1452b..f0fcfa0564e 100644
--- a/qa/spec/runtime/logger_spec.rb
+++ b/qa/spec/runtime/logger_spec.rb
@@ -1,33 +1,7 @@
# frozen_string_literal: true
RSpec.describe QA::Runtime::Logger do
- before do
- logger = Logger.new $stdout
- logger.level = ::Logger::DEBUG
- described_class.logger = logger
- end
-
- it 'logs debug' do
- expect { described_class.debug('test') }.to output(/DEBUG -- : test/).to_stdout_from_any_process
- end
-
- it 'logs info' do
- expect { described_class.info('test') }.to output(/INFO -- : test/).to_stdout_from_any_process
- end
-
- it 'logs warn' do
- expect { described_class.warn('test') }.to output(/WARN -- : test/).to_stdout_from_any_process
- end
-
- it 'logs error' do
- expect { described_class.error('test') }.to output(/ERROR -- : test/).to_stdout_from_any_process
- end
-
- it 'logs fatal' do
- expect { described_class.fatal('test') }.to output(/FATAL -- : test/).to_stdout_from_any_process
- end
-
- it 'logs unknown' do
- expect { described_class.unknown('test') }.to output(/ANY -- : test/).to_stdout_from_any_process
+ it 'returns logger instance' do
+ expect(described_class.logger).to be_an_instance_of(::Logger)
end
end
diff --git a/qa/spec/spec_helper.rb b/qa/spec/spec_helper.rb
index 2a6acd6d014..655b0088feb 100644
--- a/qa/spec/spec_helper.rb
+++ b/qa/spec/spec_helper.rb
@@ -2,12 +2,6 @@
require_relative '../qa'
-require 'securerandom'
-require 'pathname'
-require 'active_support/core_ext/hash'
-require 'active_support/core_ext/object/blank'
-require 'rainbow/refinement'
-
require_relative 'qa_deprecation_toolkit_env'
QaDeprecationToolkitEnv.configure!
@@ -36,7 +30,7 @@ RSpec.configure do |config|
end
config.prepend_before do |example|
- QA::Runtime::Logger.debug("\nStarting test: #{example.full_description}\n")
+ QA::Runtime::Logger.info("Starting test: #{Rainbow(example.full_description).bright}")
QA::Runtime::Example.current = example
# Reset fabrication counters tracked in resource base
@@ -75,14 +69,15 @@ RSpec.configure do |config|
config.after(:suite) do |suite|
# Write all test created resources to JSON file
- QA::Tools::TestResourceDataProcessor.write_to_file
+ QA::Tools::TestResourceDataProcessor.write_to_file(suite.reporter.failed_examples.any?)
# If requested, confirm that resources were used appropriately (e.g., not left with changes that interfere with
# further reuse)
QA::Resource::ReusableCollection.validate_resource_reuse if QA::Runtime::Env.validate_resource_reuse?
# If any tests failed, leave the resources behind to help troubleshoot, otherwise remove them.
- QA::Resource::ReusableCollection.remove_all_via_api! unless suite.reporter.failed_examples.present?
+ # Do not remove the shared resource on live environments
+ QA::Resource::ReusableCollection.remove_all_via_api! if !suite.reporter.failed_examples.present? && !QA::Runtime::Env.running_on_dot_com?
end
config.append_after(:suite) do
diff --git a/qa/spec/specs/allure_report_spec.rb b/qa/spec/specs/allure_report_spec.rb
index 06b09106140..86ceaf51cbb 100644
--- a/qa/spec/specs/allure_report_spec.rb
+++ b/qa/spec/specs/allure_report_spec.rb
@@ -76,9 +76,10 @@ describe QA::Runtime::AllureReport do
end
it 'adds rspec and metadata formatter' do
+ expect(rspec_config).to have_received(:add_formatter).with(
+ QA::Support::Formatters::AllureMetadataFormatter
+ ).ordered
expect(rspec_config).to have_received(:add_formatter).with(AllureRspecFormatter).ordered
- expect(rspec_config).to have_received(:add_formatter)
- .with(QA::Support::Formatters::AllureMetadataFormatter).ordered
end
it 'configures attachments saving' do
diff --git a/qa/spec/support/formatters/allure_metadata_formatter_spec.rb b/qa/spec/support/formatters/allure_metadata_formatter_spec.rb
index 631d2eda54f..d84e190fd56 100644
--- a/qa/spec/support/formatters/allure_metadata_formatter_spec.rb
+++ b/qa/spec/support/formatters/allure_metadata_formatter_spec.rb
@@ -14,6 +14,7 @@ describe QA::Support::Formatters::AllureMetadataFormatter do
add_link: nil,
attempts: 0,
file_path: 'file/path/spec.rb',
+ execution_result: instance_double("RSpec::Core::Example::ExecutionResult", status: :passed),
metadata: {
testcase: 'testcase',
quarantine: { issue: 'issue' }
@@ -31,7 +32,7 @@ describe QA::Support::Formatters::AllureMetadataFormatter do
end
it "adds additional data to report" do
- formatter.example_started(rspec_example_notification)
+ formatter.example_finished(rspec_example_notification)
aggregate_failures do
expect(rspec_example).to have_received(:issue).with('Quarantine issue', 'issue')
diff --git a/qa/spec/support/formatters/test_stats_formatter_spec.rb b/qa/spec/support/formatters/test_stats_formatter_spec.rb
index 84fc3b83185..518c7407ba6 100644
--- a/qa/spec/support/formatters/test_stats_formatter_spec.rb
+++ b/qa/spec/support/formatters/test_stats_formatter_spec.rb
@@ -60,7 +60,8 @@ describe QA::Support::Formatters::TestStatsFormatter do
retry_attempts: 0,
job_url: ci_job_url,
pipeline_url: ci_pipeline_url,
- pipeline_id: ci_pipeline_id
+ pipeline_id: ci_pipeline_id,
+ merge_request_iid: nil
}
}
end
@@ -157,6 +158,23 @@ describe QA::Support::Formatters::TestStatsFormatter do
end
end
+ context 'with context quarantined spec' do
+ let(:quarantined) { 'false' }
+
+ it 'exports data to influxdb with correct qurantine tag' do
+ run_spec do
+ it(
+ 'spec',
+ quarantine: { only: { job: 'praefect' } },
+ testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/1234'
+ ) {}
+ end
+
+ expect(influx_write_api).to have_received(:write).once
+ expect(influx_write_api).to have_received(:write).with(data: [data])
+ end
+ end
+
context 'with staging full run' do
let(:run_type) { 'staging-full' }
diff --git a/qa/spec/support/loglinking_spec.rb b/qa/spec/support/loglinking_spec.rb
new file mode 100644
index 00000000000..cba8a139767
--- /dev/null
+++ b/qa/spec/support/loglinking_spec.rb
@@ -0,0 +1,185 @@
+# frozen_string_literal: true
+
+RSpec.describe QA::Support::Loglinking do
+ describe '.failure_metadata' do
+ context 'return nil string' do
+ it 'if correlation_id is empty' do
+ expect(QA::Support::Loglinking.failure_metadata('')).to eq(nil)
+ end
+ it 'if correlation_id is nil' do
+ expect(QA::Support::Loglinking.failure_metadata(nil)).to eq(nil)
+ end
+ end
+
+ context 'return error string' do
+ it 'with sentry URL' do
+ allow(QA::Support::Loglinking).to receive(:sentry_url).and_return('https://sentry.address/?environment=bar')
+ allow(QA::Support::Loglinking).to receive(:kibana_url).and_return(nil)
+
+ expect(QA::Support::Loglinking.failure_metadata('foo123')).to eql(<<~ERROR.chomp)
+ Correlation Id: foo123
+ Sentry Url: https://sentry.address/?environment=bar&query=correlation_id%3A%22foo123%22
+ ERROR
+ end
+
+ it 'with kibana URL' do
+ allow(QA::Support::Loglinking).to receive(:sentry_url).and_return(nil)
+ allow(QA::Support::Loglinking).to receive(:kibana_url).and_return('https://kibana.address/')
+
+ expect(QA::Support::Loglinking.failure_metadata('foo123')).to eql(<<~ERROR.chomp)
+ Correlation Id: foo123
+ Kibana Url: https://kibana.address/app/discover#/?_a=(query:(language:kuery,query:'json.correlation_id%20:%20foo123'))
+ ERROR
+ end
+ end
+ end
+
+ describe '.sentry_url' do
+ let(:url_hash) do
+ {
+ :staging => 'https://sentry.gitlab.net/gitlab/staginggitlabcom/?environment=gstg',
+ :staging_canary => 'https://sentry.gitlab.net/gitlab/staginggitlabcom/?environment=gstg-cny',
+ :staging_ref => 'https://sentry.gitlab.net/gitlab/staging-ref/?environment=gstg-ref',
+ :pre => 'https://sentry.gitlab.net/gitlab/pregitlabcom/?environment=pre',
+ :canary => 'https://sentry.gitlab.net/gitlab/gitlabcom/?environment=gprd',
+ :production => 'https://sentry.gitlab.net/gitlab/gitlabcom/?environment=gprd-cny',
+ :foo => nil,
+ nil => nil
+ }
+ end
+
+ it 'returns sentry URL if environment found' do
+ url_hash.each do |environment, url|
+ allow(QA::Support::Loglinking).to receive(:logging_environment).and_return(environment)
+
+ expect(QA::Support::Loglinking.sentry_url).to eq(url)
+ end
+ end
+ end
+
+ describe '.kibana_url' do
+ let(:url_hash) do
+ {
+ :staging => 'https://nonprod-log.gitlab.net/',
+ :staging_canary => 'https://nonprod-log.gitlab.net/',
+ :staging_ref => nil,
+ :pre => nil,
+ :canary => 'https://log.gprd.gitlab.net/',
+ :production => 'https://log.gprd.gitlab.net/',
+ :foo => nil,
+ nil => nil
+ }
+ end
+
+ it 'returns kibana URL if environment found' do
+ url_hash.each do |environment, url|
+ allow(QA::Support::Loglinking).to receive(:logging_environment).and_return(environment)
+
+ expect(QA::Support::Loglinking.kibana_url).to eq(url)
+ end
+ end
+ end
+
+ describe '.logging_environment' do
+ let(:staging_address) { 'https://staging.gitlab.com' }
+ let(:staging_ref_address) { 'https://staging-ref.gitlab.com' }
+ let(:production_address) { 'https://www.gitlab.com' }
+ let(:pre_prod_address) { 'https://pre.gitlab.com' }
+ let(:logging_env_array) do
+ [
+ {
+ address: staging_address,
+ canary: false,
+ expected_env: :staging
+ },
+ {
+ address: staging_address,
+ canary: true,
+ expected_env: :staging_canary
+ },
+ {
+ address: staging_ref_address,
+ canary: true,
+ expected_env: :staging_ref
+ },
+ {
+ address: production_address,
+ canary: false,
+ expected_env: :production
+ },
+ {
+ address: production_address,
+ canary: true,
+ expected_env: :canary
+ },
+ {
+ address: pre_prod_address,
+ canary: true,
+ expected_env: :pre
+ },
+ {
+ address: 'https://foo.com',
+ canary: true,
+ expected_env: nil
+ }
+ ]
+ end
+
+ it 'returns logging environment if environment found' do
+ logging_env_array.each do |logging_env_hash|
+ allow(QA::Runtime::Scenario).to receive(:attributes).and_return({ gitlab_address: logging_env_hash[:address] })
+ allow(QA::Support::Loglinking).to receive(:canary?).and_return(logging_env_hash[:canary])
+
+ expect(QA::Support::Loglinking.logging_environment).to eq(logging_env_hash[:expected_env])
+ end
+ end
+ end
+
+ describe '.logging_environment?' do
+ context 'returns boolean' do
+ it 'returns true if logging_environment is not nil' do
+ allow(QA::Support::Loglinking).to receive(:logging_environment).and_return(:staging)
+
+ expect(QA::Support::Loglinking.logging_environment?).to eq(true)
+ end
+
+ it 'returns false if logging_environment is nil' do
+ allow(QA::Support::Loglinking).to receive(:logging_environment).and_return(nil)
+
+ expect(QA::Support::Loglinking.logging_environment?).to eq(false)
+ end
+ end
+ end
+
+ describe '.cookies' do
+ let(:cookies) { [{ name: 'Foo', value: 'Bar' }, { name: 'gitlab_canary', value: 'true' }] }
+
+ it 'returns browser cookies' do
+ allow(Capybara.current_session).to receive_message_chain(:driver, :browser, :manage, :all_cookies).and_return(cookies)
+
+ expect(QA::Support::Loglinking.cookies).to eq({ "Foo" => { name: "Foo", value: "Bar" }, "gitlab_canary" => { name: "gitlab_canary", value: "true" } })
+ end
+ end
+
+ describe '.canary?' do
+ context 'gitlab_canary cookie is present' do
+ it 'and true returns true' do
+ allow(QA::Support::Loglinking).to receive(:cookies).and_return({ 'gitlab_canary' => { name: 'gitlab_canary', value: 'true' } })
+
+ expect(QA::Support::Loglinking.canary?).to eq(true)
+ end
+ it 'and not true returns false' do
+ allow(QA::Support::Loglinking).to receive(:cookies).and_return({ 'gitlab_canary' => { name: 'gitlab_canary', value: 'false' } })
+
+ expect(QA::Support::Loglinking.canary?).to eq(false)
+ end
+ end
+ context 'gitlab_canary cookie is not present' do
+ it 'returns false' do
+ allow(QA::Support::Loglinking).to receive(:cookies).and_return({ 'foo' => { name: 'foo', path: '/pathname' } })
+
+ expect(QA::Support::Loglinking.canary?).to eq(false)
+ end
+ end
+ end
+end
diff --git a/qa/spec/support/page_error_checker_spec.rb b/qa/spec/support/page_error_checker_spec.rb
index 764b6110e08..b9b085fa7b9 100644
--- a/qa/spec/support/page_error_checker_spec.rb
+++ b/qa/spec/support/page_error_checker_spec.rb
@@ -8,16 +8,28 @@ RSpec.describe QA::Support::PageErrorChecker do
describe '.report!' do
context 'reports errors' do
let(:expected_chrome_error) do
+ "Error Code 500\n\n"\
"chrome errors\n\n"\
- "Path: #{test_path}"
+ "Path: #{test_path}\n\n"\
+ "Logging: foo123"
end
let(:expected_basic_error) do
+ "Error Code 500\n\n"\
+ "foo status\n\n"\
+ "Path: #{test_path}\n\n"\
+ "Logging: foo123"
+ end
+
+ let(:expected_basic_404) do
+ "Error Code 404\n\n"\
"foo status\n\n"\
"Path: #{test_path}"
end
it 'reports error message on chrome browser' do
+ allow(QA::Support::PageErrorChecker).to receive(:parse_five_c_page_request_id).and_return('foo123')
+ allow(QA::Support::Loglinking).to receive(:failure_metadata).with('foo123').and_return('Logging: foo123')
allow(QA::Support::PageErrorChecker).to receive(:return_chrome_errors).and_return('chrome errors')
allow(page).to receive(:current_path).and_return(test_path)
allow(QA::Runtime::Env).to receive(:browser).and_return(:chrome)
@@ -26,12 +38,64 @@ RSpec.describe QA::Support::PageErrorChecker do
end
it 'reports basic message on non-chrome browser' do
+ allow(QA::Support::PageErrorChecker).to receive(:parse_five_c_page_request_id).and_return('foo123')
+ allow(QA::Support::Loglinking).to receive(:failure_metadata).with('foo123').and_return('Logging: foo123')
allow(QA::Support::PageErrorChecker).to receive(:status_code_report).and_return('foo status')
allow(page).to receive(:current_path).and_return(test_path)
allow(QA::Runtime::Env).to receive(:browser).and_return(:firefox)
expect { QA::Support::PageErrorChecker.report!(page, 500) }.to raise_error(RuntimeError, expected_basic_error)
end
+
+ it 'does not report failure metadata on non 500 error' do
+ allow(QA::Support::PageErrorChecker).to receive(:parse_five_c_page_request_id).and_return('foo123')
+
+ expect(QA::Support::Loglinking).not_to receive(:failure_metadata)
+
+ allow(QA::Support::PageErrorChecker).to receive(:status_code_report).and_return('foo status')
+ allow(page).to receive(:current_path).and_return(test_path)
+ allow(QA::Runtime::Env).to receive(:browser).and_return(:firefox)
+
+ expect { QA::Support::PageErrorChecker.report!(page, 404) }.to raise_error(RuntimeError, expected_basic_404)
+ end
+ end
+ end
+
+ describe '.parse_five_c_page_request_id' do
+ context 'parse correlation ID' do
+ require 'nokogiri'
+ before do
+ nokogiri_parse = Class.new do
+ def self.parse(str)
+ Nokogiri::HTML.parse(str)
+ end
+ end
+ stub_const('NokogiriParse', nokogiri_parse)
+ end
+ let(:error_500_str) do
+ "<html><body><div><p><code>"\
+ "req678"\
+ "</code></p></div></body></html>"
+ end
+
+ let(:error_500_no_code_str) do
+ "<html><body>"\
+ "The code you are looking for is not here"\
+ "</body></html>"
+ end
+
+ it 'returns code is present' do
+ allow(page).to receive(:html).and_return(error_500_str)
+ allow(Nokogiri::HTML).to receive(:parse).with(error_500_str).and_return(NokogiriParse.parse(error_500_str))
+
+ expect(QA::Support::PageErrorChecker.parse_five_c_page_request_id(page).to_str).to eq('req678')
+ end
+ it 'returns nil if not present' do
+ allow(page).to receive(:html).and_return(error_500_no_code_str)
+ allow(Nokogiri::HTML).to receive(:parse).with(error_500_no_code_str).and_return(NokogiriParse.parse(error_500_no_code_str))
+
+ expect(QA::Support::PageErrorChecker.parse_five_c_page_request_id(page)).to be_nil
+ end
end
end
diff --git a/qa/spec/support/repeater_spec.rb b/qa/spec/support/repeater_spec.rb
index 4fa3bcde5e7..96e780fc9bd 100644
--- a/qa/spec/support/repeater_spec.rb
+++ b/qa/spec/support/repeater_spec.rb
@@ -3,12 +3,6 @@
require 'active_support/core_ext/integer/time'
RSpec.describe QA::Support::Repeater do
- before do
- logger = ::Logger.new $stdout
- logger.level = ::Logger::DEBUG
- QA::Runtime::Logger.logger = logger
- end
-
subject do
Module.new do
extend QA::Support::Repeater
diff --git a/qa/spec/tools/reliable_report_spec.rb b/qa/spec/tools/reliable_report_spec.rb
index 85b2590d3aa..318b0833f62 100644
--- a/qa/spec/tools/reliable_report_spec.rb
+++ b/qa/spec/tools/reliable_report_spec.rb
@@ -167,7 +167,7 @@ describe QA::Tools::ReliableReport do
payload: {
title: "Reliable e2e test report",
description: issue_body,
- labels: "Quality,test,type::maintenance,reliable test report,automation:devops-mapping-disable"
+ labels: "Quality,test,type::maintenance,reliable test report,automation:ml"
}
)
expect(slack_notifier).to have_received(:post).with(
diff --git a/qa/spec/tools/test_resources_data_processor_spec.rb b/qa/spec/tools/test_resources_data_processor_spec.rb
index 5117d1d367f..2ae43974a0c 100644
--- a/qa/spec/tools/test_resources_data_processor_spec.rb
+++ b/qa/spec/tools/test_resources_data_processor_spec.rb
@@ -43,18 +43,30 @@ RSpec.describe QA::Tools::TestResourceDataProcessor do
end
describe '.write_to_file' do
- let(:resources_file) { Pathname.new(Faker::File.file_name(dir: 'tmp', ext: 'json')) }
+ using RSpec::Parameterized::TableSyntax
- before do
- stub_env('QA_TEST_RESOURCES_CREATED_FILEPATH', resources_file)
-
- allow(File).to receive(:write)
+ where(:ci, :suite_failed, :file_path) do
+ true | true | 'root/tmp/failed-test-resources-random.json'
+ true | false | 'root/tmp/test-resources-random.json'
+ false | true | 'root/tmp/failed-test-resources.json'
+ false | false | 'root/tmp/test-resources.json'
end
- it 'writes applicable resources to file' do
- processor.write_to_file
+ with_them do
+ let(:resources_file) { Pathname.new(file_path) }
+
+ before do
+ allow(QA::Runtime::Env).to receive(:running_in_ci?).and_return(ci)
+ allow(File).to receive(:write)
+ allow(QA::Runtime::Path).to receive(:qa_root).and_return('root')
+ allow(SecureRandom).to receive(:hex).with(any_args).and_return('random')
+ end
+
+ it 'writes applicable resources to file' do
+ processor.write_to_file(suite_failed)
- expect(File).to have_received(:write).with(resources_file, JSON.pretty_generate(result))
+ expect(File).to have_received(:write).with(resources_file, JSON.pretty_generate(result))
+ end
end
end
end
diff --git a/qa/tasks/contracts.rake b/qa/tasks/contracts.rake
new file mode 100644
index 00000000000..682ec0e2e21
--- /dev/null
+++ b/qa/tasks/contracts.rake
@@ -0,0 +1,47 @@
+# frozen_string_literal: true
+
+require 'pact/tasks/verification_task'
+
+contracts = File.expand_path('../contracts', __dir__)
+provider = File.expand_path('provider', contracts)
+
+# rubocop:disable Rails/RakeEnvironment
+namespace :contracts do
+ namespace :mr do
+ Pact::VerificationTask.new(:metadata) do |pact|
+ pact.uri(
+ "#{contracts}/contracts/merge_request_page-merge_request_metadata_endpoint.json",
+ pact_helper: "#{provider}/spec/metadata_helper.rb"
+ )
+ end
+
+ Pact::VerificationTask.new(:discussions) do |pact|
+ pact.uri(
+ "#{contracts}/contracts/merge_request_page-merge_request_discussions_endpoint.json",
+ pact_helper: "#{provider}/spec/discussions_helper.rb"
+ )
+ end
+
+ Pact::VerificationTask.new(:diffs) do |pact|
+ pact.uri(
+ "#{contracts}/contracts/merge_request_page-merge_request_diffs_endpoint.json",
+ pact_helper: "#{provider}/spec/diffs_helper.rb"
+ )
+ end
+
+ desc 'Run all merge request contract tests'
+ task 'test:merge_request', :contract_mr do |_t, arg|
+ raise(ArgumentError, 'Merge request contract tests require contract_mr to be set') unless arg[:contract_mr]
+
+ ENV['CONTRACT_MR'] = arg[:contract_mr]
+ errors = %w[metadata discussions diffs].each_with_object([]) do |task, err|
+ Rake::Task["contracts:mr:pact:verify:#{task}"].execute
+ rescue StandardError, SystemExit
+ err << "contracts:mr:pact:verify:#{task}"
+ end
+
+ raise StandardError, "Errors in tasks #{errors.join(', ')}" unless errors.empty?
+ end
+ end
+end
+# rubocop:enable Rails/RakeEnvironment
diff --git a/rubocop/cop/database/multiple_databases.rb b/rubocop/cop/database/multiple_databases.rb
index fb6e81f9845..f20348d9d1f 100644
--- a/rubocop/cop/database/multiple_databases.rb
+++ b/rubocop/cop/database/multiple_databases.rb
@@ -17,6 +17,10 @@ module RuboCop
https://docs.gitlab.com/ee/development/database/transaction_guidelines.html
EOF
+ ALLOWED_METHODS = %i[
+ no_touching
+ ].freeze
+
def_node_matcher :active_record_base_method_is_used?, <<~PATTERN
(send (const (const nil? :ActiveRecord) :Base) $_)
PATTERN
@@ -24,8 +28,17 @@ module RuboCop
def on_send(node)
return unless active_record_base_method_is_used?(node)
+ active_record_base_method = node.children[1]
+ return if method_is_allowed?(active_record_base_method)
+
add_offense(node, location: :expression, message: AR_BASE_MESSAGE)
end
+
+ private
+
+ def method_is_allowed?(method_name)
+ ALLOWED_METHODS.include?(method_name.to_sym)
+ end
end
end
end
diff --git a/rubocop/cop/gitlab/avoid_uploaded_file_from_params.rb b/rubocop/cop/gitlab/avoid_uploaded_file_from_params.rb
index 599371aa5a1..0795f96732d 100644
--- a/rubocop/cop/gitlab/avoid_uploaded_file_from_params.rb
+++ b/rubocop/cop/gitlab/avoid_uploaded_file_from_params.rb
@@ -4,7 +4,7 @@ module RuboCop
module Cop
module Gitlab
# This cop checks for `UploadedFile.from_params` usage.
- # See https://docs.gitlab.com/ee/development/uploads.html#how-to-add-a-new-upload-route
+ # See https://docs.gitlab.com/ee/development/uploads/working_with_uploads.html
#
# @example
#
@@ -34,7 +34,7 @@ module RuboCop
# end
# end
class AvoidUploadedFileFromParams < RuboCop::Cop::Cop
- MSG = 'Use the `UploadedFile` set by `multipart.rb` instead of calling `UploadedFile.from_params` directly. See https://docs.gitlab.com/ee/development/uploads.html#how-to-add-a-new-upload-route'
+ MSG = 'Use the `UploadedFile` set by `multipart.rb` instead of calling `UploadedFile.from_params` directly. See https://docs.gitlab.com/ee/development/uploads/working_with_uploads.html'
def_node_matcher :calling_uploaded_file_from_params?, <<~PATTERN
(send (const nil? :UploadedFile) :from_params ...)
diff --git a/rubocop/cop/graphql/graphql_name_position.rb b/rubocop/cop/graphql/graphql_name_position.rb
new file mode 100644
index 00000000000..f18d65588cc
--- /dev/null
+++ b/rubocop/cop/graphql/graphql_name_position.rb
@@ -0,0 +1,40 @@
+# frozen_string_literal: true
+
+# This cop ensures that if a class uses `graphql_name`, then
+# it's the first line of the class
+#
+# @example
+#
+# # bad
+# class AwfulClass
+# field :some_field, GraphQL::Types::JSON
+# graphql_name 'AwfulClass'
+# end
+#
+# # good
+# class GreatClass
+# graphql_name 'AwfulClass'
+# field :some_field, GraphQL::Types::String
+# end
+
+module RuboCop
+ module Cop
+ module Graphql
+ class GraphqlNamePosition < RuboCop::Cop::Cop
+ MSG = '`graphql_name` should be the first line of the class: '\
+ 'https://docs.gitlab.com/ee/development/api_graphql_styleguide.html#naming-conventions'
+
+ def_node_search :graphql_name?, <<~PATTERN
+ (send nil? :graphql_name ...)
+ PATTERN
+
+ def on_class(node)
+ return unless graphql_name?(node)
+ return if node.body.single_line?
+
+ add_offense(node, location: :expression) unless graphql_name?(node.body.children.first)
+ end
+ end
+ end
+ end
+end
diff --git a/rubocop/formatter/todo_formatter.rb b/rubocop/formatter/todo_formatter.rb
new file mode 100644
index 00000000000..14b4242063e
--- /dev/null
+++ b/rubocop/formatter/todo_formatter.rb
@@ -0,0 +1,141 @@
+# frozen_string_literal: true
+
+require 'set'
+require 'rubocop'
+require 'yaml'
+
+require_relative '../todo_dir'
+
+module RuboCop
+ module Formatter
+ # This formatter dumps a YAML configuration file per cop rule
+ # into `.rubocop_todo/**/*.yml` which contains detected offenses.
+ #
+ # For example, this formatter stores offenses for `RSpec/VariableName`
+ # in `.rubocop_todo/rspec/variable_name.yml`.
+ class TodoFormatter < BaseFormatter
+ # Disable a cop which exceeds this limit. This way we ensure that we
+ # don't enable a cop by accident when moving it from
+ # .rubocop_todo.yml to .rubocop_todo/.
+ # We keep the cop disabled if it has been disabled previously explicitly
+ # via `Enabled: false` in .rubocop_todo.yml or .rubocop_todo/.
+ MAX_OFFENSE_COUNT = 15
+
+ class Todo
+ attr_reader :cop_name, :files, :offense_count
+
+ def initialize(cop_name)
+ @cop_name = cop_name
+ @files = Set.new
+ @offense_count = 0
+ @cop_class = RuboCop::Cop::Registry.global.find_by_cop_name(cop_name)
+ end
+
+ def record(file, offense_count)
+ @files << file
+ @offense_count += offense_count
+ end
+
+ def autocorrectable?
+ @cop_class&.support_autocorrect?
+ end
+ end
+
+ def initialize(output, options = {})
+ directory = options.delete(:rubocop_todo_dir) || TodoDir::DEFAULT_TODO_DIR
+ @todos = Hash.new { |hash, cop_name| hash[cop_name] = Todo.new(cop_name) }
+ @todo_dir = TodoDir.new(directory)
+ @config_inspect_todo_dir = load_config_inspect_todo_dir(directory)
+ @config_old_todo_yml = load_config_old_todo_yml(directory)
+ check_multiple_configurations!
+
+ super
+ end
+
+ def file_finished(file, offenses)
+ return if offenses.empty?
+
+ file = relative_path(file)
+
+ offenses.map(&:cop_name).tally.each do |cop_name, offense_count|
+ @todos[cop_name].record(file, offense_count)
+ end
+ end
+
+ def finished(_inspected_files)
+ @todos.values.sort_by(&:cop_name).each do |todo|
+ yaml = to_yaml(todo)
+ path = @todo_dir.write(todo.cop_name, yaml)
+
+ output.puts "Written to #{relative_path(path)}\n"
+ end
+ end
+
+ private
+
+ def relative_path(path)
+ parent = File.expand_path('..', @todo_dir.directory)
+ path.delete_prefix("#{parent}/")
+ end
+
+ def to_yaml(todo)
+ yaml = []
+ yaml << '---'
+ yaml << '# Cop supports --auto-correct.' if todo.autocorrectable?
+ yaml << "#{todo.cop_name}:"
+
+ if previously_disabled?(todo) && offense_count_exceeded?(todo)
+ yaml << " # Offense count: #{todo.offense_count}"
+ yaml << ' # Temporarily disabled due to too many offenses'
+ yaml << ' Enabled: false'
+ end
+
+ yaml << ' Exclude:'
+
+ files = todo.files.sort.map { |file| " - '#{file}'" }
+ yaml.concat files
+ yaml << ''
+
+ yaml.join("\n")
+ end
+
+ def offense_count_exceeded?(todo)
+ todo.offense_count > MAX_OFFENSE_COUNT
+ end
+
+ def check_multiple_configurations!
+ cop_names = @config_inspect_todo_dir.keys & @config_old_todo_yml.keys
+ return if cop_names.empty?
+
+ list = cop_names.sort.map { |cop_name| "- #{cop_name}" }.join("\n")
+ raise "Multiple configurations found for cops:\n#{list}\n"
+ end
+
+ def previously_disabled?(todo)
+ cop_name = todo.cop_name
+
+ config = @config_old_todo_yml[cop_name] ||
+ @config_inspect_todo_dir[cop_name] || {}
+ return false if config.empty?
+
+ config['Enabled'] == false
+ end
+
+ def load_config_inspect_todo_dir(directory)
+ @todo_dir.list_inspect.each_with_object({}) do |path, combined|
+ config = YAML.load_file(path)
+ combined.update(config) if Hash === config
+ end
+ end
+
+ # Load YAML configuration from `.rubocop_todo.yml`.
+ # We consider this file already old, obsolete, and to be removed soon.
+ def load_config_old_todo_yml(directory)
+ path = File.expand_path(File.join(directory, '../.rubocop_todo.yml'))
+ config = YAML.load_file(path) if File.exist?(path)
+
+ config || {}
+ end
+ end
+ end
+end
diff --git a/rubocop/todo_dir.rb b/rubocop/todo_dir.rb
new file mode 100644
index 00000000000..4aca4454a06
--- /dev/null
+++ b/rubocop/todo_dir.rb
@@ -0,0 +1,81 @@
+# frozen_string_literal: true
+
+require 'fileutils'
+require 'active_support/inflector/inflections'
+
+module RuboCop
+ # Helper class to manage file access to RuboCop TODOs in .rubocop_todo directory.
+ class TodoDir
+ DEFAULT_TODO_DIR = File.expand_path('../.rubocop_todo', __dir__)
+
+ # Suffix to indicate TODOs being inspected right now.
+ SUFFIX_INSPECT = '.inspect'
+
+ attr_reader :directory
+
+ def initialize(directory, inflector: ActiveSupport::Inflector)
+ @directory = directory
+ @inflector = inflector
+ end
+
+ def read(cop_name, suffix = nil)
+ read_suffixed(cop_name)
+ end
+
+ def write(cop_name, content)
+ path = path_for(cop_name)
+
+ FileUtils.mkdir_p(File.dirname(path))
+ File.write(path, content)
+
+ path
+ end
+
+ def inspect(cop_name)
+ path = path_for(cop_name)
+
+ if File.exist?(path)
+ FileUtils.mv(path, "#{path}#{SUFFIX_INSPECT}")
+ true
+ else
+ false
+ end
+ end
+
+ def inspect_all
+ pattern = File.join(@directory, '**/*.yml')
+
+ Dir.glob(pattern).count do |path|
+ FileUtils.mv(path, "#{path}#{SUFFIX_INSPECT}")
+ end
+ end
+
+ def list_inspect
+ pattern = File.join(@directory, "**/*.yml.inspect")
+
+ Dir.glob(pattern)
+ end
+
+ def delete_inspected
+ pattern = File.join(@directory, '**/*.yml.inspect')
+
+ Dir.glob(pattern).count do |path|
+ File.delete(path)
+ end
+ end
+
+ private
+
+ def read_suffixed(cop_name, suffix = nil)
+ path = path_for(cop_name, suffix)
+
+ File.read(path) if File.exist?(path)
+ end
+
+ def path_for(cop_name, suffix = nil)
+ todo_path = "#{@inflector.underscore(cop_name)}.yml#{suffix}"
+
+ File.join(@directory, todo_path)
+ end
+ end
+end
diff --git a/scripts/generate-memory-metrics-on-boot b/scripts/generate-memory-metrics-on-boot
index 945661aa057..539446f7c0c 100755
--- a/scripts/generate-memory-metrics-on-boot
+++ b/scripts/generate-memory-metrics-on-boot
@@ -1,12 +1,29 @@
#!/usr/bin/env ruby
# frozen_string_literal: true
-abort "usage: #{__FILE__} <memory_bundle_mem_file_name>" unless ARGV.length == 1
-memory_bundle_mem_file_name = ARGV.first
+abort "usage: #{__FILE__} <memory_bundle_mem_file_name_prefix> <test_count>" unless ARGV.length == 2
+memory_bundle_mem_file_name_prefix = ARGV.first
+test_count = ARGV.last.to_i
-full_report = File.open(memory_bundle_mem_file_name).read
+results = []
+(1..test_count).each do |i|
+ report_filename = "#{memory_bundle_mem_file_name_prefix}#{i}.txt"
-stats = /TOP: (?<total_mibs_str>.*) MiB/.match(full_report)
-abort 'failed to process the benchmark output' unless stats
+ stats = nil
+ File.foreach(report_filename).detect do |line|
+ stats = /TOP: (?<total_mibs_str>.*) MiB/.match(line)
+ end
+ abort 'failed to process the benchmark output' unless stats
-puts "total_memory_used_by_dependencies_on_boot_prod_env_mb #{stats[:total_mibs_str].to_f.round(1)}"
+ total_mibs = stats[:total_mibs_str].to_f
+ results << total_mibs
+end
+
+res = results.sort
+median = (res[(test_count - 1) / 2] + res[test_count / 2]) / 2.0
+
+METRIC_NAME = "total_memory_used_by_dependencies_on_boot_prod_env_mb"
+
+puts "# TYPE #{METRIC_NAME} gauge"
+puts "# UNIT #{METRIC_NAME} mebibytes"
+puts "#{METRIC_NAME} #{median.round(1)}"
diff --git a/scripts/gitlab_workhorse_component_helpers.sh b/scripts/gitlab_workhorse_component_helpers.sh
new file mode 100644
index 00000000000..06fe7b2ea51
--- /dev/null
+++ b/scripts/gitlab_workhorse_component_helpers.sh
@@ -0,0 +1,73 @@
+#!/usr/bin/env bash
+
+set -euo pipefail
+
+export CURL_TOKEN_HEADER="${CURL_TOKEN_HEADER:-"JOB-TOKEN"}"
+export GITLAB_WORKHORSE_BINARIES_LIST="gitlab-resize-image gitlab-zip-cat gitlab-zip-metadata gitlab-workhorse"
+export GITLAB_WORKHORSE_PACKAGE_FILES_LIST="${GITLAB_WORKHORSE_BINARIES_LIST} WORKHORSE_TREE"
+export GITLAB_WORKHORSE_TREE=${GITLAB_WORKHORSE_TREE:-$(git rev-parse HEAD:workhorse)}
+export GITLAB_WORKHORSE_PACKAGE="workhorse-${GITLAB_WORKHORSE_TREE}.tar.gz"
+export GITLAB_WORKHORSE_PACKAGE_URL="${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/${GITLAB_WORKHORSE_FOLDER}/${GITLAB_WORKHORSE_TREE}/${GITLAB_WORKHORSE_PACKAGE}"
+
+function gitlab_workhorse_archive_doesnt_exist() {
+ local package_url="${GITLAB_WORKHORSE_PACKAGE_URL}"
+
+ status=$(curl -I --silent --retry 3 --output /dev/null -w "%{http_code}" "${package_url}")
+
+ [[ "${status}" != "200" ]]
+}
+
+function create_gitlab_workhorse_package() {
+ local archive_filename="${GITLAB_WORKHORSE_PACKAGE}"
+ local folder_to_archive="${GITLAB_WORKHORSE_FOLDER}"
+ local workhorse_folder_path="${TMP_TEST_GITLAB_WORKHORSE_PATH}"
+ local tar_working_folder="${TMP_TEST_FOLDER}"
+
+ echoinfo "Running 'tar -czvf ${archive_filename} -C ${tar_working_folder} ${folder_to_archive}'"
+ tar -czvf ${archive_filename} -C ${tar_working_folder} ${folder_to_archive}
+ du -h ${archive_filename}
+}
+
+function extract_gitlab_workhorse_package() {
+ local tar_working_folder="${TMP_TEST_FOLDER}"
+
+ echoinfo "Extracting archive to ${tar_working_folder}"
+
+ tar -xzv -C ${tar_working_folder} < /dev/stdin
+}
+
+function upload_gitlab_workhorse_package() {
+ local archive_filename="${GITLAB_WORKHORSE_PACKAGE}"
+ local package_url="${GITLAB_WORKHORSE_PACKAGE_URL}"
+ local token_header="${CURL_TOKEN_HEADER}"
+ local token="${CI_JOB_TOKEN}"
+
+ echoinfo "Uploading ${archive_filename} to ${package_url} ..."
+ curl --fail --silent --retry 3 --header "${token_header}: ${token}" --upload-file "${archive_filename}" "${package_url}"
+}
+
+function read_curl_gitlab_workhorse_package() {
+ local package_url="${GITLAB_WORKHORSE_PACKAGE_URL}"
+ local token_header="${CURL_TOKEN_HEADER}"
+ local token="${CI_JOB_TOKEN}"
+
+ echoinfo "Downloading from ${package_url} ..."
+
+ curl --fail --silent --retry 3 --header "${token_header}: ${token}" "${package_url}"
+}
+
+function download_and_extract_gitlab_workhorse_package() {
+ read_curl_gitlab_workhorse_package | extract_gitlab_workhorse_package
+}
+
+function select_gitlab_workhorse_essentials() {
+ local tmp_path="${CI_PROJECT_DIR}/tmp/${GITLAB_WORKHORSE_FOLDER}"
+ local original_gitlab_workhorse_path="${TMP_TEST_GITLAB_WORKHORSE_PATH}"
+
+ mkdir -p ${tmp_path}
+ cd ${original_gitlab_workhorse_path} && mv ${GITLAB_WORKHORSE_PACKAGE_FILES_LIST} ${tmp_path} && cd -
+ rm -rf ${original_gitlab_workhorse_path}
+
+ # Move the temp folder to its final destination
+ mv ${tmp_path} ${TMP_TEST_FOLDER}
+}
diff --git a/scripts/ingest-reports-to-siem b/scripts/ingest-reports-to-siem
new file mode 100755
index 00000000000..86c72e1d7eb
--- /dev/null
+++ b/scripts/ingest-reports-to-siem
@@ -0,0 +1,45 @@
+#!/usr/bin/env node
+
+const { S3Client, PutObjectCommand } = require('@aws-sdk/client-s3')
+const { fromIni } = require('@aws-sdk/credential-provider-ini')
+const path = require('path')
+const fs = require('fs')
+const crypto = require('crypto')
+
+function getMD5HashFromFile(data) {
+ const hash = crypto.createHash('md5').update(data).digest('base64')
+ return hash
+}
+
+(async function () {
+ const s3Client = new S3Client({
+ region: 'us-east-2',
+ credentials: fromIni({ profile: 'gl-logs-for-panther' }),
+ })
+ try {
+ const file = 'gl-dependency-scanning-report.json'
+ const data = fs.readFileSync(file)
+
+ const [filename, fileext] = path.basename(file).split('.')
+ const uniqueId = process.env['CI_PIPELINE_ID'] && process.env['CI_JOB_ID'] ?
+ process.env['CI_PIPELINE_ID'] + '-' + process.env['CI_JOB_ID'] :
+ Date.now()
+ const key = path.join('package_hunter_test', filename + '-' + uniqueId + '.' + fileext)
+
+ const responseData = await s3Client.send(
+ new PutObjectCommand({
+ Bucket: 'gl-logs-for-panther-test',
+ Key: key,
+ Body: data,
+ ContentMD5: getMD5HashFromFile(data),
+ }),
+ )
+ console.log('Successfully uploaded %s to %s', file, key)
+ } catch (err) {
+ if (err.name === 'CredentialsProviderError' || err.name === 'AuthorizationHeaderMalformed')
+ console.log('Could not upload the report. Are AWS credentials configured in ~/.aws/credentials?')
+ else
+ console.log('Unexpected error during upload: ', err.message)
+ process.exit(1)
+ }
+})()
diff --git a/scripts/lint_templates_bash.rb b/scripts/lint_templates_bash.rb
new file mode 100755
index 00000000000..8db9469ecdf
--- /dev/null
+++ b/scripts/lint_templates_bash.rb
@@ -0,0 +1,76 @@
+#!/usr/bin/env ruby
+# frozen_string_literal: true
+
+require_relative '../config/environment'
+require 'open3'
+
+module LintTemplatesBash
+ module_function
+
+ EXCLUDED_RULES = [
+ "SC2046", "SC2086", # will be fixed later: https://gitlab.com/gitlab-org/gitlab/-/issues/352973
+ "SC1090", "SC1091", # we do not have access to sourced files for analysis.
+ "SC2154", # Referencing undefined variables is common and adding per-line exceptions for them is unintuitive for end-users
+ "SC2164" # CI/CD automatically fails if attempting to change to a directory which does not exist.
+ ].join(",").freeze
+
+ EXCLUDED_TEMPLATES = [
+ "dotNET.gitlab-ci.yml" # Powershell
+ ].freeze
+
+ def run
+ failed_templates = Gitlab::Template::GitlabCiYmlTemplate.all.filter_map do |template|
+ next if EXCLUDED_TEMPLATES.include?(template.full_name)
+
+ success = check_template(template)
+
+ template.full_name unless success
+ end
+
+ if failed_templates.any?
+ puts "The following templates have shellcheck violations:"
+ puts failed_templates.join("\n")
+ exit 1
+ end
+ end
+
+ def process_content(content)
+ Gitlab::Ci::YamlProcessor.new(content).execute
+ end
+
+ def job_script(job)
+ parts = [:before_script, :script, :after_script].map do |key|
+ job[key]&.join("\n")
+ end.compact
+
+ parts.prepend("#!/bin/bash\n").join("\n")
+ end
+
+ def shellcheck(script_content)
+ combined_streams, status = Open3.capture2e("shellcheck --exclude='#{EXCLUDED_RULES}' -", stdin_data: script_content)
+
+ [combined_streams, status.success?]
+ end
+
+ def check_job(job)
+ shellcheck(job_script(job))
+ end
+
+ def check_template(template)
+ parsed = process_content(template.content)
+ results = parsed.jobs.map do |name, job|
+ out, success = check_job(job)
+
+ unless success
+ puts "The '#{name}' job in #{template.full_name} has shellcheck failures:"
+ puts out
+ end
+
+ success
+ end
+
+ results.all?
+ end
+end
+
+LintTemplatesBash.run
diff --git a/scripts/merge-simplecov b/scripts/merge-simplecov
index b74a416a6e0..32a0cd86f82 100755
--- a/scripts/merge-simplecov
+++ b/scripts/merge-simplecov
@@ -5,26 +5,4 @@ require_relative '../spec/simplecov_env'
SimpleCovEnv.configure_profile
SimpleCovEnv.configure_formatter
-module SimpleCov
- module ResultMerger
- class << self
- def resultset_files
- Dir.glob(File.join(SimpleCov.coverage_path, '*', '.resultset.json'))
- end
-
- def resultset_hashes
- resultset_files.map do |path|
- JSON.parse(File.read(path))
- rescue StandardError
- {}
- end
- end
-
- def resultset
- resultset_hashes.reduce({}, :merge)
- end
- end
- end
-end
-
-SimpleCov::ResultMerger.merged_result.format!
+SimpleCov.collate Dir.glob(File.join(SimpleCov.coverage_path, '*', '.resultset.json'))
diff --git a/scripts/setup/find-jh-branch.rb b/scripts/setup/find-jh-branch.rb
index 89aa1492939..a7c1cafd74c 100755
--- a/scripts/setup/find-jh-branch.rb
+++ b/scripts/setup/find-jh-branch.rb
@@ -8,7 +8,7 @@ require_relative '../api/default_options'
class FindJhBranch
JH_DEFAULT_BRANCH = 'main-jh'
- JH_PROJECT_PATH = 'gitlab-org/gitlab-jh/gitlab'
+ JH_PROJECT_PATH = 'gitlab-org/gitlab-jh-mirrors/gitlab'
BranchNotFound = Class.new(RuntimeError)
def run
diff --git a/scripts/trigger-build.rb b/scripts/trigger-build.rb
index 17cbd91a8ee..a3356c664d1 100755
--- a/scripts/trigger-build.rb
+++ b/scripts/trigger-build.rb
@@ -324,8 +324,8 @@ module Trigger
def invoke!(post_comment: false, downstream_job_name: nil)
pipeline = super
gitlab = gitlab_client(:upstream)
- project_path = base_variables['TOP_UPSTREAM_SOURCE_PROJECT']
- merge_request_id = base_variables['TOP_UPSTREAM_MERGE_REQUEST_IID']
+ project_path = variables['TOP_UPSTREAM_SOURCE_PROJECT']
+ merge_request_id = variables['TOP_UPSTREAM_MERGE_REQUEST_IID']
comment = "<!-- #{IDENTIFIABLE_NOTE_TAG} --> \nStarted database testing [pipeline](https://ops.gitlab.net/#{downstream_project_path}/-/pipelines/#{pipeline.id}) " \
"(limited access). This comment will be updated once the pipeline has finished running."
diff --git a/scripts/utils.sh b/scripts/utils.sh
index c20508617b8..e896fe40e06 100644
--- a/scripts/utils.sh
+++ b/scripts/utils.sh
@@ -83,7 +83,7 @@ function install_junit_merge_gem() {
function run_timed_command() {
local cmd="${1}"
- local metric_name="${2}"
+ local metric_name="${2:-no}"
local timed_metric_file
local start=$(date +%s)
@@ -97,7 +97,7 @@ function run_timed_command() {
if [[ $ret -eq 0 ]]; then
echosuccess "==> '${cmd}' succeeded in ${runtime} seconds."
- if [[ -n "${metric_name}" ]]; then
+ if [[ "${metric_name}" != "no" ]]; then
timed_metric_file=$(timed_metric_file $metric_name)
echo "# TYPE ${metric_name} gauge" > "${timed_metric_file}"
echo "# UNIT ${metric_name} seconds" >> "${timed_metric_file}"
@@ -132,9 +132,9 @@ function timed_metric_file() {
}
function echoerr() {
- local header="${2}"
+ local header="${2:-no}"
- if [ -n "${header}" ]; then
+ if [ "${header}" != "no" ]; then
printf "\n\033[0;31m** %s **\n\033[0m" "${1}" >&2;
else
printf "\033[0;31m%s\n\033[0m" "${1}" >&2;
@@ -142,9 +142,9 @@ function echoerr() {
}
function echoinfo() {
- local header="${2}"
+ local header="${2:-no}"
- if [ -n "${header}" ]; then
+ if [ "${header}" != "no" ]; then
printf "\n\033[0;33m** %s **\n\033[0m" "${1}" >&2;
else
printf "\033[0;33m%s\n\033[0m" "${1}" >&2;
@@ -152,9 +152,9 @@ function echoinfo() {
}
function echosuccess() {
- local header="${2}"
+ local header="${2:-no}"
- if [ -n "${header}" ]; then
+ if [ "${header}" != "no" ]; then
printf "\n\033[0;32m** %s **\n\033[0m" "${1}" >&2;
else
printf "\033[0;32m%s\n\033[0m" "${1}" >&2;
diff --git a/sidekiq_cluster/cli.rb b/sidekiq_cluster/cli.rb
index 2feb77601b8..e04f5ab1d42 100644
--- a/sidekiq_cluster/cli.rb
+++ b/sidekiq_cluster/cli.rb
@@ -13,7 +13,7 @@ require_relative '../lib/gitlab/utils'
require_relative '../lib/gitlab/sidekiq_config/cli_methods'
require_relative '../lib/gitlab/sidekiq_config/worker_matcher'
require_relative '../lib/gitlab/sidekiq_logging/json_formatter'
-require_relative '../lib/gitlab/process_management'
+require_relative '../metrics_server/dependencies'
require_relative '../metrics_server/metrics_server'
require_relative 'sidekiq_cluster'
@@ -38,8 +38,7 @@ module Gitlab
@metrics_dir = ENV["prometheus_multiproc_dir"] || File.absolute_path("tmp/prometheus_multiproc_dir/sidekiq")
@pid = nil
@interval = 5
- @alive = true
- @processes = []
+ @soft_timeout_seconds = DEFAULT_SOFT_TIMEOUT_SECONDS
@logger = Logger.new(log_output)
@logger.formatter = ::Gitlab::SidekiqLogging::JSONFormatter.new
@rails_path = Dir.pwd
@@ -103,95 +102,64 @@ module Gitlab
@logger.info("Starting cluster with #{queue_groups.length} processes")
end
- start_metrics_server(wipe_metrics_dir: true)
+ start_and_supervise_workers(queue_groups)
+ end
- @processes = SidekiqCluster.start(
+ def start_and_supervise_workers(queue_groups)
+ worker_pids = SidekiqCluster.start(
queue_groups,
env: @environment,
directory: @rails_path,
max_concurrency: @max_concurrency,
min_concurrency: @min_concurrency,
dryrun: @dryrun,
- timeout: soft_timeout_seconds
+ timeout: @soft_timeout_seconds
)
return if @dryrun
- write_pid
- trap_signals
- start_loop
- end
-
- def write_pid
ProcessManagement.write_pid(@pid) if @pid
- end
-
- def soft_timeout_seconds
- @soft_timeout_seconds || DEFAULT_SOFT_TIMEOUT_SECONDS
- end
-
- # The amount of time it'll wait for killing the alive Sidekiq processes.
- def hard_timeout_seconds
- soft_timeout_seconds + DEFAULT_HARD_TIMEOUT_SECONDS
- end
-
- def monotonic_time
- Process.clock_gettime(Process::CLOCK_MONOTONIC, :float_second)
- end
-
- def continue_waiting?(deadline)
- ProcessManagement.any_alive?(@processes) && monotonic_time < deadline
- end
-
- def hard_stop_stuck_pids
- ProcessManagement.signal_processes(ProcessManagement.pids_alive(@processes), "-KILL")
- end
-
- def wait_for_termination
- deadline = monotonic_time + hard_timeout_seconds
- sleep(CHECK_TERMINATE_INTERVAL_SECONDS) while continue_waiting?(deadline)
- hard_stop_stuck_pids
- end
-
- def trap_signals
- ProcessManagement.trap_signals(TERMINATE_SIGNALS) do |signal|
- @alive = false
- ProcessManagement.signal_processes(@processes, signal)
- wait_for_termination
- end
-
- ProcessManagement.trap_signals(FORWARD_SIGNALS) do |signal|
- ProcessManagement.signal_processes(@processes, signal)
- end
- end
+ supervisor = SidekiqProcessSupervisor.instance(
+ health_check_interval_seconds: @interval,
+ terminate_timeout_seconds: @soft_timeout_seconds + TIMEOUT_GRACE_PERIOD_SECONDS,
+ term_signals: TERMINATE_SIGNALS,
+ forwarded_signals: FORWARD_SIGNALS,
+ synchronous: true
+ )
- def start_loop
- while @alive
- sleep(@interval)
+ metrics_server_pid = start_metrics_server
- if metrics_server_enabled? && ProcessManagement.process_died?(@metrics_server_pid)
- @logger.warn('Metrics server went away')
- start_metrics_server(wipe_metrics_dir: false)
- end
+ all_pids = worker_pids + Array(metrics_server_pid)
- unless ProcessManagement.all_alive?(@processes)
- # If a child process died we'll just terminate the whole cluster. It's up to
- # runit and such to then restart the cluster.
+ supervisor.supervise(all_pids) do |dead_pids|
+ # If we're not in the process of shutting down the cluster,
+ # and the metrics server died, restart it.
+ if supervisor.alive && dead_pids.include?(metrics_server_pid)
+ @logger.info('Sidekiq metrics server terminated, restarting...')
+ metrics_server_pid = restart_metrics_server(wipe_metrics_dir: false)
+ all_pids = worker_pids + Array(metrics_server_pid)
+ else
+ # If a worker process died we'll just terminate the whole cluster.
+ # We let an external system (runit, kubernetes) handle the restart.
@logger.info('A worker terminated, shutting down the cluster')
- stop_metrics_server
- ProcessManagement.signal_processes(@processes, :TERM)
- break
+ ProcessManagement.signal_processes(all_pids - dead_pids, :TERM)
+ # Signal supervisor not to respawn workers and shut down.
+ []
end
end
end
- def start_metrics_server(wipe_metrics_dir: false)
+ def start_metrics_server
return unless metrics_server_enabled?
+ restart_metrics_server(wipe_metrics_dir: true)
+ end
+
+ def restart_metrics_server(wipe_metrics_dir: false)
@logger.info("Starting metrics server on port #{sidekiq_exporter_port}")
- @metrics_server_pid = MetricsServer.fork(
+ MetricsServer.fork(
'sidekiq',
metrics_dir: @metrics_dir,
wipe_metrics_dir: wipe_metrics_dir,
@@ -225,13 +193,6 @@ module Gitlab
!@dryrun && sidekiq_exporter_enabled? && exporter_has_a_unique_port?
end
- def stop_metrics_server
- return unless @metrics_server_pid
-
- @logger.info("Stopping metrics server (PID #{@metrics_server_pid})")
- ProcessManagement.signal(@metrics_server_pid, :TERM)
- end
-
def option_parser
OptionParser.new do |opt|
opt.banner = "#{File.basename(__FILE__)} [QUEUE,QUEUE] [QUEUE] ... [OPTIONS]"
diff --git a/sidekiq_cluster/sidekiq_cluster.rb b/sidekiq_cluster/sidekiq_cluster.rb
index c5139ab8874..c68cbe7c163 100644
--- a/sidekiq_cluster/sidekiq_cluster.rb
+++ b/sidekiq_cluster/sidekiq_cluster.rb
@@ -4,8 +4,6 @@ require_relative '../lib/gitlab/process_management'
module Gitlab
module SidekiqCluster
- CHECK_TERMINATE_INTERVAL_SECONDS = 1
-
# How long to wait when asking for a clean termination.
# It maps the Sidekiq default timeout:
# https://github.com/mperham/sidekiq/wiki/Signals#term
@@ -14,8 +12,12 @@ module Gitlab
# is given through arguments.
DEFAULT_SOFT_TIMEOUT_SECONDS = 25
- # After surpassing the soft timeout.
- DEFAULT_HARD_TIMEOUT_SECONDS = 5
+ # Additional time granted after surpassing the soft timeout
+ # before we kill the process.
+ TIMEOUT_GRACE_PERIOD_SECONDS = 5
+
+ # The singleton instance used to supervise cluster processes.
+ SidekiqProcessSupervisor = Class.new(Gitlab::ProcessSupervisor)
# Starts Sidekiq workers for the pairs of processes.
#
diff --git a/spec/commands/sidekiq_cluster/cli_spec.rb b/spec/commands/sidekiq_cluster/cli_spec.rb
index 15b738cacd1..2cb3f67b03d 100644
--- a/spec/commands/sidekiq_cluster/cli_spec.rb
+++ b/spec/commands/sidekiq_cluster/cli_spec.rb
@@ -5,8 +5,11 @@ require 'rspec-parameterized'
require_relative '../../support/stub_settings_source'
require_relative '../../../sidekiq_cluster/cli'
+require_relative '../../support/helpers/next_instance_of'
RSpec.describe Gitlab::SidekiqCluster::CLI, stub_settings_source: true do # rubocop:disable RSpec/FilePath
+ include NextInstanceOf
+
let(:cli) { described_class.new('/dev/null') }
let(:timeout) { Gitlab::SidekiqCluster::DEFAULT_SOFT_TIMEOUT_SECONDS }
let(:default_options) do
@@ -37,6 +40,8 @@ RSpec.describe Gitlab::SidekiqCluster::CLI, stub_settings_source: true do # rubo
}
end
+ let(:supervisor) { instance_double(Gitlab::SidekiqCluster::SidekiqProcessSupervisor) }
+
before do
stub_env('RAILS_ENV', 'test')
@@ -44,8 +49,11 @@ RSpec.describe Gitlab::SidekiqCluster::CLI, stub_settings_source: true do # rubo
config_file.close
allow(::Settings).to receive(:source).and_return(config_file.path)
-
::Settings.reload!
+
+ allow(Gitlab::ProcessManagement).to receive(:write_pid)
+ allow(Gitlab::SidekiqCluster::SidekiqProcessSupervisor).to receive(:instance).and_return(supervisor)
+ allow(supervisor).to receive(:supervise)
end
after do
@@ -60,12 +68,6 @@ RSpec.describe Gitlab::SidekiqCluster::CLI, stub_settings_source: true do # rubo
end
context 'with arguments' do
- before do
- allow(cli).to receive(:write_pid)
- allow(cli).to receive(:trap_signals)
- allow(cli).to receive(:start_loop)
- end
-
it 'starts the Sidekiq workers' do
expect(Gitlab::SidekiqCluster).to receive(:start)
.with([['foo']], default_options)
@@ -81,7 +83,7 @@ RSpec.describe Gitlab::SidekiqCluster::CLI, stub_settings_source: true do # rubo
.to receive(:worker_queues).and_return(worker_queues)
expect(Gitlab::SidekiqCluster)
- .to receive(:start).with([worker_queues], default_options)
+ .to receive(:start).with([worker_queues], default_options).and_return([])
cli.run(%w(*))
end
@@ -135,6 +137,7 @@ RSpec.describe Gitlab::SidekiqCluster::CLI, stub_settings_source: true do # rubo
it 'when given', 'starts Sidekiq workers with given timeout' do
expect(Gitlab::SidekiqCluster).to receive(:start)
.with([['foo']], default_options.merge(timeout: 10))
+ .and_return([])
cli.run(%w(foo --timeout 10))
end
@@ -142,6 +145,7 @@ RSpec.describe Gitlab::SidekiqCluster::CLI, stub_settings_source: true do # rubo
it 'when not given', 'starts Sidekiq workers with default timeout' do
expect(Gitlab::SidekiqCluster).to receive(:start)
.with([['foo']], default_options.merge(timeout: Gitlab::SidekiqCluster::DEFAULT_SOFT_TIMEOUT_SECONDS))
+ .and_return([])
cli.run(%w(foo))
end
@@ -257,7 +261,7 @@ RSpec.describe Gitlab::SidekiqCluster::CLI, stub_settings_source: true do # rubo
.to receive(:worker_queues).and_return(worker_queues)
expect(Gitlab::SidekiqCluster)
- .to receive(:start).with([worker_queues], default_options)
+ .to receive(:start).with([worker_queues], default_options).and_return([])
cli.run(%w(--queue-selector *))
end
@@ -292,16 +296,13 @@ RSpec.describe Gitlab::SidekiqCluster::CLI, stub_settings_source: true do # rubo
context 'starting the server' do
context 'without --dryrun' do
+ before do
+ allow(Gitlab::SidekiqCluster).to receive(:start).and_return([])
+ end
+
context 'when there are no sidekiq_health_checks settings set' do
let(:sidekiq_exporter_enabled) { true }
- before do
- allow(Gitlab::SidekiqCluster).to receive(:start)
- allow(cli).to receive(:write_pid)
- allow(cli).to receive(:trap_signals)
- allow(cli).to receive(:start_loop)
- end
-
it 'does not start a sidekiq metrics server' do
expect(MetricsServer).not_to receive(:fork)
@@ -312,13 +313,6 @@ RSpec.describe Gitlab::SidekiqCluster::CLI, stub_settings_source: true do # rubo
context 'when the sidekiq_exporter.port setting is not set' do
let(:sidekiq_exporter_enabled) { true }
- before do
- allow(Gitlab::SidekiqCluster).to receive(:start)
- allow(cli).to receive(:write_pid)
- allow(cli).to receive(:trap_signals)
- allow(cli).to receive(:start_loop)
- end
-
it 'does not start a sidekiq metrics server' do
expect(MetricsServer).not_to receive(:fork)
@@ -342,13 +336,6 @@ RSpec.describe Gitlab::SidekiqCluster::CLI, stub_settings_source: true do # rubo
}
end
- before do
- allow(Gitlab::SidekiqCluster).to receive(:start)
- allow(cli).to receive(:write_pid)
- allow(cli).to receive(:trap_signals)
- allow(cli).to receive(:start_loop)
- end
-
it 'does not start a sidekiq metrics server' do
expect(MetricsServer).not_to receive(:fork)
@@ -368,13 +355,6 @@ RSpec.describe Gitlab::SidekiqCluster::CLI, stub_settings_source: true do # rubo
}
end
- before do
- allow(Gitlab::SidekiqCluster).to receive(:start)
- allow(cli).to receive(:write_pid)
- allow(cli).to receive(:trap_signals)
- allow(cli).to receive(:start_loop)
- end
-
it 'does not start a sidekiq metrics server' do
expect(MetricsServer).not_to receive(:fork)
@@ -397,13 +377,6 @@ RSpec.describe Gitlab::SidekiqCluster::CLI, stub_settings_source: true do # rubo
end
with_them do
- before do
- allow(Gitlab::SidekiqCluster).to receive(:start)
- allow(cli).to receive(:write_pid)
- allow(cli).to receive(:trap_signals)
- allow(cli).to receive(:start_loop)
- end
-
specify do
if start_metrics_server
expect(MetricsServer).to receive(:fork).with('sidekiq', metrics_dir: metrics_dir, wipe_metrics_dir: true, reset_signals: trapped_signals)
@@ -415,6 +388,23 @@ RSpec.describe Gitlab::SidekiqCluster::CLI, stub_settings_source: true do # rubo
end
end
end
+
+ context 'when a PID is specified' do
+ it 'writes the PID to a file' do
+ expect(Gitlab::ProcessManagement).to receive(:write_pid).with('/dev/null')
+
+ cli.option_parser.parse!(%w(-P /dev/null))
+ cli.run(%w(foo))
+ end
+ end
+
+ context 'when no PID is specified' do
+ it 'does not write a PID' do
+ expect(Gitlab::ProcessManagement).not_to receive(:write_pid)
+
+ cli.run(%w(foo))
+ end
+ end
end
context 'with --dryrun set' do
@@ -427,130 +417,46 @@ RSpec.describe Gitlab::SidekiqCluster::CLI, stub_settings_source: true do # rubo
end
end
end
-
- context 'supervising the server' do
- let(:sidekiq_exporter_enabled) { true }
- let(:sidekiq_health_checks_port) { '3907' }
-
- before do
- allow(cli).to receive(:sleep).with(a_kind_of(Numeric))
- allow(MetricsServer).to receive(:fork).and_return(99)
- cli.start_metrics_server
- end
-
- it 'stops the metrics server when one of the processes has been terminated' do
- allow(Gitlab::ProcessManagement).to receive(:process_died?).and_return(false)
- allow(Gitlab::ProcessManagement).to receive(:all_alive?).with(an_instance_of(Array)).and_return(false)
- allow(Gitlab::ProcessManagement).to receive(:signal_processes).with(an_instance_of(Array), :TERM)
-
- expect(Process).to receive(:kill).with(:TERM, 99)
-
- cli.start_loop
- end
-
- it 'starts the metrics server when it is down' do
- allow(Gitlab::ProcessManagement).to receive(:process_died?).and_return(true)
- allow(Gitlab::ProcessManagement).to receive(:all_alive?).with(an_instance_of(Array)).and_return(false)
- allow(cli).to receive(:stop_metrics_server)
-
- expect(MetricsServer).to receive(:fork).with(
- 'sidekiq', metrics_dir: metrics_dir, wipe_metrics_dir: false, reset_signals: trapped_signals
- )
-
- cli.start_loop
- end
- end
- end
- end
-
- describe '#write_pid' do
- context 'when a PID is specified' do
- it 'writes the PID to a file' do
- expect(Gitlab::ProcessManagement).to receive(:write_pid).with('/dev/null')
-
- cli.option_parser.parse!(%w(-P /dev/null))
- cli.write_pid
- end
end
- context 'when no PID is specified' do
- it 'does not write a PID' do
- expect(Gitlab::ProcessManagement).not_to receive(:write_pid)
+ context 'supervising the cluster' do
+ let(:sidekiq_exporter_enabled) { true }
+ let(:sidekiq_health_checks_port) { '3907' }
+ let(:metrics_server_pid) { 99 }
+ let(:sidekiq_worker_pids) { [2, 42] }
- cli.write_pid
- end
- end
- end
-
- describe '#wait_for_termination' do
- it 'waits for termination of all sub-processes and succeeds after 3 checks' do
- expect(Gitlab::ProcessManagement).to receive(:any_alive?)
- .with(an_instance_of(Array)).and_return(true, true, true, false)
-
- expect(Gitlab::ProcessManagement).to receive(:pids_alive)
- .with([]).and_return([])
-
- expect(Gitlab::ProcessManagement).to receive(:signal_processes)
- .with([], "-KILL")
-
- stub_const("Gitlab::SidekiqCluster::CHECK_TERMINATE_INTERVAL_SECONDS", 0.1)
- allow(cli).to receive(:terminate_timeout_seconds) { 1 }
-
- cli.wait_for_termination
- end
-
- context 'with hanging workers' do
before do
- expect(cli).to receive(:write_pid)
- expect(cli).to receive(:trap_signals)
- expect(cli).to receive(:start_loop)
+ allow(Gitlab::SidekiqCluster).to receive(:start).and_return(sidekiq_worker_pids)
end
- it 'hard kills workers after timeout expires' do
- worker_pids = [101, 102, 103]
- expect(Gitlab::SidekiqCluster).to receive(:start)
- .with([['foo']], default_options)
- .and_return(worker_pids)
-
- expect(Gitlab::ProcessManagement).to receive(:any_alive?)
- .with(worker_pids).and_return(true).at_least(10).times
-
- expect(Gitlab::ProcessManagement).to receive(:pids_alive)
- .with(worker_pids).and_return([102])
-
- expect(Gitlab::ProcessManagement).to receive(:signal_processes)
- .with([102], "-KILL")
+ it 'stops the entire process cluster if one of the workers has been terminated' do
+ expect(supervisor).to receive(:alive).and_return(true)
+ expect(supervisor).to receive(:supervise).and_yield([2])
+ expect(MetricsServer).to receive(:fork).once.and_return(metrics_server_pid)
+ expect(Gitlab::ProcessManagement).to receive(:signal_processes).with([42, 99], :TERM)
cli.run(%w(foo))
-
- stub_const("Gitlab::SidekiqCluster::CHECK_TERMINATE_INTERVAL_SECONDS", 0.1)
- allow(cli).to receive(:terminate_timeout_seconds) { 1 }
-
- cli.wait_for_termination
end
- end
- end
-
- describe '#trap_signals' do
- it 'traps termination and sidekiq specific signals' do
- expect(Gitlab::ProcessManagement).to receive(:trap_signals).with(%i[INT TERM])
- expect(Gitlab::ProcessManagement).to receive(:trap_signals).with(%i[TTIN USR1 USR2 HUP])
- cli.trap_signals
- end
- end
-
- describe '#start_loop' do
- it 'runs until one of the processes has been terminated' do
- allow(cli).to receive(:sleep).with(a_kind_of(Numeric))
+ context 'when the supervisor is alive' do
+ it 'restarts the metrics server when it is down' do
+ expect(supervisor).to receive(:alive).and_return(true)
+ expect(supervisor).to receive(:supervise).and_yield([metrics_server_pid])
+ expect(MetricsServer).to receive(:fork).twice.and_return(metrics_server_pid)
- expect(Gitlab::ProcessManagement).to receive(:all_alive?)
- .with(an_instance_of(Array)).and_return(false)
+ cli.run(%w(foo))
+ end
+ end
- expect(Gitlab::ProcessManagement).to receive(:signal_processes)
- .with(an_instance_of(Array), :TERM)
+ context 'when the supervisor is shutting down' do
+ it 'does not restart the metrics server' do
+ expect(supervisor).to receive(:alive).and_return(false)
+ expect(supervisor).to receive(:supervise).and_yield([metrics_server_pid])
+ expect(MetricsServer).to receive(:fork).once.and_return(metrics_server_pid)
- cli.start_loop
+ cli.run(%w(foo))
+ end
+ end
end
end
end
diff --git a/spec/components/pajamas/component_spec.rb b/spec/components/pajamas/component_spec.rb
new file mode 100644
index 00000000000..96f6b43bac1
--- /dev/null
+++ b/spec/components/pajamas/component_spec.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+require 'spec_helper'
+
+RSpec.describe Pajamas::Component do
+ describe '#filter_attribute' do
+ let(:allowed) { %w[default something] }
+
+ it 'returns default value when no value is given' do
+ value = subject.send(:filter_attribute, nil, allowed, default: 'default')
+
+ expect(value).to eq('default')
+ end
+
+ it 'returns default value when invalid value is given' do
+ value = subject.send(:filter_attribute, 'invalid', allowed, default: 'default')
+
+ expect(value).to eq('default')
+ end
+
+ it 'returns given value when it is part of allowed list' do
+ value = subject.send(:filter_attribute, 'something', allowed, default: 'default')
+
+ expect(value).to eq('something')
+ end
+ end
+end
diff --git a/spec/components/pajamas/toggle_component_spec.rb b/spec/components/pajamas/toggle_component_spec.rb
new file mode 100644
index 00000000000..b2727dec318
--- /dev/null
+++ b/spec/components/pajamas/toggle_component_spec.rb
@@ -0,0 +1,107 @@
+# frozen_string_literal: true
+require "spec_helper"
+
+RSpec.describe Pajamas::ToggleComponent, type: :component do
+ context 'with defaults' do
+ before do
+ render_inline described_class.new(classes: 'js-feature-toggle')
+ end
+
+ it 'renders a toggle container with provided class' do
+ expect(rendered_component).to have_selector "[class='js-feature-toggle']"
+ end
+
+ it 'does not set a name' do
+ expect(rendered_component).not_to have_selector('[data-name]')
+ end
+
+ it 'sets default is-checked attributes' do
+ expect(rendered_component).to have_selector('[data-is-checked="false"]')
+ end
+
+ it 'sets default disabled attributes' do
+ expect(rendered_component).to have_selector('[data-disabled="false"]')
+ end
+
+ it 'sets default is-loading attributes' do
+ expect(rendered_component).to have_selector('[data-is-loading="false"]')
+ end
+
+ it 'does not set a label' do
+ expect(rendered_component).not_to have_selector('[data-label]')
+ end
+
+ it 'does not set a label position' do
+ expect(rendered_component).not_to have_selector('[data-label-position]')
+ end
+ end
+
+ context 'with custom options' do
+ before do
+ render_inline described_class.new(
+ classes: 'js-custom-gl-toggle',
+ name: 'toggle-name',
+ is_checked: true,
+ is_disabled: true,
+ is_loading: true,
+ label: 'Custom label',
+ label_position: :top,
+ data: {
+ foo: 'bar'
+ })
+ end
+
+ it 'sets the custom class' do
+ expect(rendered_component).to have_selector('.js-custom-gl-toggle')
+ end
+
+ it 'sets the custom name' do
+ expect(rendered_component).to have_selector('[data-name="toggle-name"]')
+ end
+
+ it 'sets the custom is-checked attributes' do
+ expect(rendered_component).to have_selector('[data-is-checked="true"]')
+ end
+
+ it 'sets the custom disabled attributes' do
+ expect(rendered_component).to have_selector('[data-disabled="true"]')
+ end
+
+ it 'sets the custom is-loading attributes' do
+ expect(rendered_component).to have_selector('[data-is-loading="true"]')
+ end
+
+ it 'sets the custom label' do
+ expect(rendered_component).to have_selector('[data-label="Custom label"]')
+ end
+
+ it 'sets the custom label position' do
+ expect(rendered_component).to have_selector('[data-label-position="top"]')
+ end
+
+ it 'sets custom data attributes' do
+ expect(rendered_component).to have_selector('[data-foo="bar"]')
+ end
+ end
+
+ context 'with setting label_position' do
+ using RSpec::Parameterized::TableSyntax
+
+ where(:position, :count) do
+ :top | 1
+ :left | 1
+ :hidden | 1
+ :bogus | 0
+ 'bogus' | 0
+ nil | 0
+ end
+
+ before do
+ render_inline described_class.new(classes: '_class_', label_position: position)
+ end
+
+ with_them do
+ it { expect(rendered_component).to have_selector("[data-label-position='#{position}']", count: count) }
+ end
+ end
+end
diff --git a/spec/controllers/admin/application_settings_controller_spec.rb b/spec/controllers/admin/application_settings_controller_spec.rb
index fb4c0970653..f7b2bab3615 100644
--- a/spec/controllers/admin/application_settings_controller_spec.rb
+++ b/spec/controllers/admin/application_settings_controller_spec.rb
@@ -81,6 +81,18 @@ RSpec.describe Admin::ApplicationSettingsController, :do_not_mock_admin_mode_set
expect(body).to include('counts')
expect(response).to have_gitlab_http_status(:ok)
end
+
+ describe 'usage data counter' do
+ let(:counter) { Gitlab::UsageDataCounters::ServiceUsageDataCounter }
+
+ it 'incremented when json generated' do
+ expect { get :usage_data, format: :json }.to change { counter.read(:download_payload_click) }.by(1)
+ end
+
+ it 'not incremented when html format requested' do
+ expect { get :usage_data }.not_to change { counter.read(:download_payload_click) }
+ end
+ end
end
describe 'PUT #update' do
diff --git a/spec/controllers/admin/clusters_controller_spec.rb b/spec/controllers/admin/clusters_controller_spec.rb
index 25c4830a79a..fed9d2e8588 100644
--- a/spec/controllers/admin/clusters_controller_spec.rb
+++ b/spec/controllers/admin/clusters_controller_spec.rb
@@ -27,6 +27,10 @@ RSpec.describe Admin::ClustersController do
create(:cluster, :disabled, :provided_by_gcp, :production_environment, :instance)
end
+ include_examples ':certificate_based_clusters feature flag controller responses' do
+ let(:subject) { get_index }
+ end
+
it 'lists available clusters and displays html' do
get_index
@@ -105,6 +109,10 @@ RSpec.describe Admin::ClustersController do
get :new, params: { provider: provider }
end
+ include_examples ':certificate_based_clusters feature flag controller responses' do
+ let(:subject) { go }
+ end
+
describe 'functionality for new cluster' do
context 'when omniauth has been configured' do
let(:key) { 'secret-key' }
@@ -226,6 +234,10 @@ RSpec.describe Admin::ClustersController do
post :create_gcp, params: params
end
+ include_examples ':certificate_based_clusters feature flag controller responses' do
+ let(:subject) { post_create_gcp }
+ end
+
describe 'functionality' do
context 'when access token is valid' do
before do
@@ -318,6 +330,10 @@ RSpec.describe Admin::ClustersController do
post :create_aws, params: params
end
+ include_examples ':certificate_based_clusters feature flag controller responses' do
+ let(:subject) { post_create_aws }
+ end
+
it 'creates a new cluster' do
expect(ClusterProvisionWorker).to receive(:perform_async)
expect { post_create_aws }.to change { Clusters::Cluster.count }
@@ -375,6 +391,10 @@ RSpec.describe Admin::ClustersController do
post :create_user, params: params
end
+ include_examples ':certificate_based_clusters feature flag controller responses' do
+ let(:subject) { post_create_user }
+ end
+
describe 'functionality' do
context 'when creates a cluster' do
it 'creates a new cluster' do
@@ -445,6 +465,10 @@ RSpec.describe Admin::ClustersController do
post :authorize_aws_role, params: params
end
+ include_examples ':certificate_based_clusters feature flag controller responses' do
+ let(:subject) { go }
+ end
+
before do
allow(Clusters::Aws::FetchCredentialsService).to receive(:new)
.and_return(double(execute: double))
@@ -495,6 +519,10 @@ RSpec.describe Admin::ClustersController do
delete :clear_cache, params: { id: cluster }
end
+ include_examples ':certificate_based_clusters feature flag controller responses' do
+ let(:subject) { go }
+ end
+
it 'deletes the namespaces associated with the cluster' do
expect { go }.to change { Clusters::KubernetesNamespace.count }
@@ -520,6 +548,10 @@ RSpec.describe Admin::ClustersController do
format: :json
end
+ include_examples ':certificate_based_clusters feature flag controller responses' do
+ let(:subject) { get_cluster_status }
+ end
+
describe 'functionality' do
it 'responds with matching schema' do
get_cluster_status
@@ -555,6 +587,10 @@ RSpec.describe Admin::ClustersController do
}
end
+ include_examples ':certificate_based_clusters feature flag controller responses' do
+ let(:subject) { get_show }
+ end
+
describe 'functionality' do
render_views
@@ -603,6 +639,10 @@ RSpec.describe Admin::ClustersController do
}
end
+ include_examples ':certificate_based_clusters feature flag controller responses' do
+ let(:subject) { put_update }
+ end
+
it 'updates and redirects back to show page' do
put_update
@@ -694,6 +734,10 @@ RSpec.describe Admin::ClustersController do
}
end
+ include_examples ':certificate_based_clusters feature flag controller responses' do
+ let(:subject) { delete_destroy }
+ end
+
describe 'functionality' do
context 'when cluster is provided by GCP' do
context 'when cluster is created' do
diff --git a/spec/controllers/admin/runner_projects_controller_spec.rb b/spec/controllers/admin/runner_projects_controller_spec.rb
index e5f63025cf7..98f961f66bb 100644
--- a/spec/controllers/admin/runner_projects_controller_spec.rb
+++ b/spec/controllers/admin/runner_projects_controller_spec.rb
@@ -13,7 +13,7 @@ RSpec.describe Admin::RunnerProjectsController do
describe '#create' do
let(:project_id) { project.path }
- subject do
+ subject(:send_create) do
post :create, params: {
namespace_id: group.path,
project_id: project_id,
@@ -25,7 +25,7 @@ RSpec.describe Admin::RunnerProjectsController do
let(:project_runner) { create(:ci_runner, :project, projects: [project]) }
it 'redirects to the admin runner edit page' do
- subject
+ send_create
expect(response).to have_gitlab_http_status(:redirect)
expect(response).to redirect_to edit_admin_runner_url(project_runner)
@@ -37,7 +37,7 @@ RSpec.describe Admin::RunnerProjectsController do
let(:source_project) { create(:project) }
it 'redirects to the admin runner edit page' do
- subject
+ send_create
expect(response).to have_gitlab_http_status(:redirect)
expect(response).to redirect_to edit_admin_runner_url(project_runner)
@@ -50,7 +50,42 @@ RSpec.describe Admin::RunnerProjectsController do
let(:project_id) { 0 }
it 'shows 404 for unknown project' do
- subject
+ send_create
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+ end
+
+ describe '#destroy' do
+ let_it_be(:project_runner) { create(:ci_runner, :project, projects: [project]) }
+
+ let(:project_id) { project.path }
+
+ subject(:send_destroy) do
+ delete :destroy, params: {
+ namespace_id: group.path,
+ project_id: project_id,
+ id: runner_project_id
+ }
+ end
+
+ context 'unassigning runner from project' do
+ let(:runner_project_id) { project_runner.runner_projects.last.id }
+
+ it 'redirects to the admin runner edit page' do
+ send_destroy
+
+ expect(response).to have_gitlab_http_status(:redirect)
+ expect(response).to redirect_to edit_admin_runner_url(project_runner)
+ end
+ end
+
+ context 'for unknown project runner relationship' do
+ let(:runner_project_id) { 0 }
+
+ it 'shows 404 for unknown project runner relationship' do
+ send_destroy
expect(response).to have_gitlab_http_status(:not_found)
end
diff --git a/spec/controllers/admin/runners_controller_spec.rb b/spec/controllers/admin/runners_controller_spec.rb
index 74f352e8ec2..8f70cb32d3e 100644
--- a/spec/controllers/admin/runners_controller_spec.rb
+++ b/spec/controllers/admin/runners_controller_spec.rb
@@ -105,7 +105,7 @@ RSpec.describe Admin::RunnersController do
describe '#destroy' do
it 'destroys the runner' do
- expect_next_instance_of(Ci::UnregisterRunnerService, runner) do |service|
+ expect_next_instance_of(Ci::Runners::UnregisterRunnerService, runner, user) do |service|
expect(service).to receive(:execute).once.and_call_original
end
diff --git a/spec/controllers/admin/topics_controller_spec.rb b/spec/controllers/admin/topics_controller_spec.rb
index 6d66cb43338..ea510f916da 100644
--- a/spec/controllers/admin/topics_controller_spec.rb
+++ b/spec/controllers/admin/topics_controller_spec.rb
@@ -88,6 +88,13 @@ RSpec.describe Admin::TopicsController do
expect(errors).to contain_exactly(errors.full_message(:name, I18n.t('errors.messages.blank')))
end
+ it 'shows error message if topic not unique (case insensitive)' do
+ post :create, params: { projects_topic: { name: topic.name.upcase } }
+
+ errors = assigns[:topic].errors
+ expect(errors).to contain_exactly(errors.full_message(:name, I18n.t('errors.messages.taken')))
+ end
+
context 'as a normal user' do
before do
sign_in(user)
@@ -116,6 +123,15 @@ RSpec.describe Admin::TopicsController do
expect(errors).to contain_exactly(errors.full_message(:name, I18n.t('errors.messages.blank')))
end
+ it 'shows error message if topic not unique (case insensitive)' do
+ other_topic = create(:topic, name: 'other-topic')
+
+ put :update, params: { id: topic.id, projects_topic: { name: other_topic.name.upcase } }
+
+ errors = assigns[:topic].errors
+ expect(errors).to contain_exactly(errors.full_message(:name, I18n.t('errors.messages.taken')))
+ end
+
context 'as a normal user' do
before do
sign_in(user)
diff --git a/spec/controllers/application_controller_spec.rb b/spec/controllers/application_controller_spec.rb
index 004bea02580..ddd80b67639 100644
--- a/spec/controllers/application_controller_spec.rb
+++ b/spec/controllers/application_controller_spec.rb
@@ -501,6 +501,7 @@ RSpec.describe ApplicationController do
describe '#append_info_to_payload' do
controller(described_class) do
attr_reader :last_payload
+
urgency :high, [:foo]
def index
@@ -1058,15 +1059,25 @@ RSpec.describe ApplicationController do
describe 'setting permissions-policy header' do
controller do
skip_before_action :authenticate_user!
+ before_action :redirect_to_example, only: [:redirect]
def index
render html: 'It is a flock of sheep, not a floc of sheep.'
end
+
+ def redirect
+ raise 'Should not be reached'
+ end
+
+ def redirect_to_example
+ redirect_to('https://example.com')
+ end
end
before do
routes.draw do
get 'index' => 'anonymous#index'
+ get 'redirect' => 'anonymous#redirect'
end
end
@@ -1092,6 +1103,13 @@ RSpec.describe ApplicationController do
expect(response.headers['Permissions-Policy']).to eq('interest-cohort=()')
end
+
+ it 'sets the Permissions-Policy header even when redirected before_action' do
+ get :redirect
+
+ expect(response).to have_gitlab_http_status(:redirect)
+ expect(response.headers['Permissions-Policy']).to eq('interest-cohort=()')
+ end
end
end
end
diff --git a/spec/controllers/autocomplete_controller_spec.rb b/spec/controllers/autocomplete_controller_spec.rb
index 533d3896ee6..0a809e80fcd 100644
--- a/spec/controllers/autocomplete_controller_spec.rb
+++ b/spec/controllers/autocomplete_controller_spec.rb
@@ -235,7 +235,7 @@ RSpec.describe AutocompleteController do
end
end
- it_behaves_like 'rate limited endpoint', rate_limit_key: :user_email_lookup do
+ it_behaves_like 'rate limited endpoint', rate_limit_key: :search_rate_limit do
let(:current_user) { user }
def request
diff --git a/spec/controllers/boards/lists_controller_spec.rb b/spec/controllers/boards/lists_controller_spec.rb
index 29141582c6f..95334974e66 100644
--- a/spec/controllers/boards/lists_controller_spec.rb
+++ b/spec/controllers/boards/lists_controller_spec.rb
@@ -208,7 +208,7 @@ RSpec.describe Boards::ListsController do
sign_in(user)
params = { namespace_id: project.namespace.to_param,
- project_id: project,
+ project_id: project.id,
board_id: board.to_param,
id: list.to_param,
list: { position: position },
@@ -221,7 +221,7 @@ RSpec.describe Boards::ListsController do
sign_in(user)
params = { namespace_id: project.namespace.to_param,
- project_id: project,
+ project_id: project.id,
board_id: board.to_param,
id: list.to_param,
list: setting,
diff --git a/spec/controllers/concerns/product_analytics_tracking_spec.rb b/spec/controllers/concerns/product_analytics_tracking_spec.rb
new file mode 100644
index 00000000000..250cc3cf2cf
--- /dev/null
+++ b/spec/controllers/concerns/product_analytics_tracking_spec.rb
@@ -0,0 +1,171 @@
+# frozen_string_literal: true
+
+require "spec_helper"
+
+RSpec.describe ProductAnalyticsTracking, :snowplow do
+ include TrackingHelpers
+ include SnowplowHelpers
+
+ let(:user) { create(:user) }
+ let!(:group) { create(:group) }
+
+ before do
+ allow(Gitlab::UsageDataCounters::HLLRedisCounter).to receive(:track_event)
+ end
+
+ controller(ApplicationController) do
+ include ProductAnalyticsTracking
+
+ skip_before_action :authenticate_user!, only: :show
+ track_event(:index, :show, name: 'g_analytics_valuestream', destinations: [:redis_hll, :snowplow],
+ conditions: [:custom_condition_one?, :custom_condition_two?]) { |controller| controller.get_custom_id }
+
+ def index
+ render html: 'index'
+ end
+
+ def new
+ render html: 'new'
+ end
+
+ def show
+ render html: 'show'
+ end
+
+ def get_custom_id
+ 'some_custom_id'
+ end
+
+ private
+
+ def tracking_namespace_source
+ Group.first
+ end
+
+ def custom_condition_one?
+ true
+ end
+
+ def custom_condition_two?
+ true
+ end
+ end
+
+ def expect_tracking(user: self.user)
+ expect(Gitlab::UsageDataCounters::HLLRedisCounter).to have_received(:track_event)
+ .with('g_analytics_valuestream', values: instance_of(String))
+
+ expect_snowplow_event(
+ category: anything,
+ action: 'g_analytics_valuestream',
+ namespace: group,
+ user: user
+ )
+ end
+
+ def expect_no_tracking
+ expect(Gitlab::UsageDataCounters::HLLRedisCounter).not_to receive(:track_event)
+
+ expect_no_snowplow_event
+ end
+
+ context 'when user is logged in' do
+ before do
+ sign_in(user)
+ end
+
+ it 'tracks the event' do
+ get :index
+
+ expect_tracking
+ end
+
+ context 'when FF is disabled' do
+ before do
+ stub_feature_flags(route_hll_to_snowplow: false)
+ end
+
+ it 'doesnt track snowplow event' do
+ get :index
+
+ expect_no_snowplow_event
+ end
+ end
+
+ it 'tracks the event if DNT is not enabled' do
+ stub_do_not_track('0')
+
+ get :index
+
+ expect_tracking
+ end
+
+ it 'does not track the event if DNT is enabled' do
+ stub_do_not_track('1')
+
+ get :index
+
+ expect_no_tracking
+ end
+
+ it 'does not track the event if the format is not HTML' do
+ get :index, format: :json
+
+ expect_no_tracking
+ end
+
+ it 'does not track the event if a custom condition returns false' do
+ allow(controller).to receive(:custom_condition_two?).and_return(false)
+
+ get :index
+
+ expect_no_tracking
+ end
+
+ it 'does not track the event for untracked actions' do
+ get :new
+
+ expect_no_tracking
+ end
+ end
+
+ context 'when user is not logged in' do
+ let(:visitor_id) { SecureRandom.uuid }
+
+ it 'tracks the event when there is a visitor id' do
+ cookies[:visitor_id] = { value: visitor_id, expires: 24.months }
+
+ get :show, params: { id: 1 }
+
+ expect_tracking(user: nil)
+ end
+ end
+
+ context 'when user is not logged in and there is no visitor_id' do
+ it 'does not track the event' do
+ get :index
+
+ expect_no_tracking
+ end
+
+ it 'tracks the event when there is custom id' do
+ get :show, params: { id: 1 }
+
+ expect_tracking(user: nil)
+ end
+
+ it 'does not track the HLL event when there is no custom id' do
+ allow(controller).to receive(:get_custom_id).and_return(nil)
+
+ get :show, params: { id: 2 }
+
+ expect(Gitlab::UsageDataCounters::HLLRedisCounter).not_to receive(:track_event)
+ expect_snowplow_event(
+ category: anything,
+ action: 'g_analytics_valuestream',
+ namespace: group,
+ user: nil
+ )
+ end
+ end
+end
diff --git a/spec/controllers/concerns/spammable_actions/akismet_mark_as_spam_action_spec.rb b/spec/controllers/concerns/spammable_actions/akismet_mark_as_spam_action_spec.rb
index 7c10dccdcb9..caa0fa2d437 100644
--- a/spec/controllers/concerns/spammable_actions/akismet_mark_as_spam_action_spec.rb
+++ b/spec/controllers/concerns/spammable_actions/akismet_mark_as_spam_action_spec.rb
@@ -7,12 +7,6 @@ RSpec.describe SpammableActions::AkismetMarkAsSpamAction do
controller(ActionController::Base) do
include SpammableActions::AkismetMarkAsSpamAction
-
- private
-
- def spammable_path
- '/fake_spammable_path'
- end
end
let(:spammable_type) { 'SpammableType' }
@@ -22,7 +16,6 @@ RSpec.describe SpammableActions::AkismetMarkAsSpamAction do
before do
allow(Gitlab::Recaptcha).to receive(:load_configurations!) { true }
routes.draw { get 'mark_as_spam' => 'anonymous#mark_as_spam' }
- allow(controller).to receive(:spammable) { spammable }
allow(controller).to receive(:current_user) { double(:current_user, admin?: admin) }
allow(controller).to receive(:current_user).and_return(current_user)
end
@@ -31,6 +24,9 @@ RSpec.describe SpammableActions::AkismetMarkAsSpamAction do
subject { post :mark_as_spam }
before do
+ allow(controller).to receive(:spammable) { spammable }
+ allow(controller).to receive(:spammable_path) { '/fake_spammable_path' }
+
expect_next(Spam::AkismetMarkAsSpamService, target: spammable)
.to receive(:execute).and_return(execute_result)
end
@@ -68,4 +64,16 @@ RSpec.describe SpammableActions::AkismetMarkAsSpamAction do
end
end
end
+
+ describe '#spammable' do
+ it 'raises when unimplemented' do
+ expect { controller.send(:spammable) }.to raise_error(NotImplementedError)
+ end
+ end
+
+ describe '#spammable_path' do
+ it 'raises when unimplemented' do
+ expect { controller.send(:spammable_path) }.to raise_error(NotImplementedError)
+ end
+ end
end
diff --git a/spec/controllers/concerns/spammable_actions/captcha_check/html_format_actions_support_spec.rb b/spec/controllers/concerns/spammable_actions/captcha_check/html_format_actions_support_spec.rb
index 53a78326397..c5d17e0232c 100644
--- a/spec/controllers/concerns/spammable_actions/captcha_check/html_format_actions_support_spec.rb
+++ b/spec/controllers/concerns/spammable_actions/captcha_check/html_format_actions_support_spec.rb
@@ -7,7 +7,7 @@ RSpec.describe SpammableActions::CaptchaCheck::HtmlFormatActionsSupport do
include SpammableActions::CaptchaCheck::HtmlFormatActionsSupport
def create
- with_captcha_check_html_format { render :some_rendered_view }
+ with_captcha_check_html_format(spammable: spammable) { render :some_rendered_view }
end
end
diff --git a/spec/controllers/concerns/spammable_actions/captcha_check/json_format_actions_support_spec.rb b/spec/controllers/concerns/spammable_actions/captcha_check/json_format_actions_support_spec.rb
index d7a44351ad8..7796d9d1273 100644
--- a/spec/controllers/concerns/spammable_actions/captcha_check/json_format_actions_support_spec.rb
+++ b/spec/controllers/concerns/spammable_actions/captcha_check/json_format_actions_support_spec.rb
@@ -7,7 +7,7 @@ RSpec.describe SpammableActions::CaptchaCheck::JsonFormatActionsSupport do
include SpammableActions::CaptchaCheck::JsonFormatActionsSupport
def some_action
- with_captcha_check_json_format { render :some_rendered_view }
+ with_captcha_check_json_format(spammable: spammable) { render :some_rendered_view }
end
end
diff --git a/spec/controllers/concerns/spammable_actions/captcha_check/rest_api_actions_support_spec.rb b/spec/controllers/concerns/spammable_actions/captcha_check/rest_api_actions_support_spec.rb
new file mode 100644
index 00000000000..07c564b555e
--- /dev/null
+++ b/spec/controllers/concerns/spammable_actions/captcha_check/rest_api_actions_support_spec.rb
@@ -0,0 +1,86 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe SpammableActions::CaptchaCheck::RestApiActionsSupport do
+ include Rack::Test::Methods
+
+ subject do
+ Class.new(Grape::API) do
+ helpers API::Helpers
+ helpers SpammableActions::CaptchaCheck::RestApiActionsSupport
+
+ get ':id' do
+ # NOTE: This was the only way that seemed to work to inject the mock spammable into the
+ # Grape rack app instance. If there's a better way, improvements are welcome.
+ spammable = Object.fake_spammable_factory
+ with_captcha_check_rest_api(spammable: spammable) do
+ render_api_error!(spammable.errors, 400)
+ end
+ end
+ end
+ end
+
+ def app
+ subject
+ end
+
+ before do
+ allow(Gitlab::Recaptcha).to receive(:load_configurations!) { true }
+ end
+
+ describe '#with_captcha_check_json_format' do
+ let(:spammable) { instance_double(Snippet) }
+
+ before do
+ expect(spammable).to receive(:render_recaptcha?).at_least(:once) { render_recaptcha }
+ allow(Object).to receive(:fake_spammable_factory) { spammable }
+ end
+
+ context 'when spammable.render_recaptcha? is true' do
+ let(:render_recaptcha) { true }
+ let(:spam_log) { instance_double(SpamLog, id: 1) }
+ let(:spammable) { instance_double(Snippet, spam?: true, render_recaptcha?: render_recaptcha, spam_log: spam_log) }
+ let(:recaptcha_site_key) { 'abc123' }
+ let(:err_msg) { 'You gotta solve the CAPTCHA' }
+ let(:spam_action_response_fields) do
+ {
+ spam: true,
+ needs_captcha_response: render_recaptcha,
+ spam_log_id: 1,
+ captcha_site_key: recaptcha_site_key
+ }
+ end
+
+ it 'renders json containing spam_action_response_fields' do
+ allow(spammable).to receive_message_chain('errors.full_messages.to_sentence') { err_msg }
+ allow(Gitlab::CurrentSettings).to receive(:recaptcha_site_key) { recaptcha_site_key }
+ response = get '/test'
+ expected_response = {
+ 'needs_captcha_response' => render_recaptcha,
+ 'spam_log_id' => 1,
+ 'captcha_site_key' => recaptcha_site_key,
+ 'message' => { 'error' => err_msg }
+ }
+ expect(Gitlab::Json.parse(response.body)).to eq(expected_response)
+ expect(response.status).to eq(409)
+ end
+ end
+
+ context 'when spammable.render_recaptcha? is false' do
+ let(:render_recaptcha) { false }
+ let(:errors) { { 'base' => "It's definitely spam" } }
+
+ it 'yields to block' do
+ allow(spammable).to receive(:errors) { errors }
+
+ response = get 'test'
+ expected_response = {
+ 'message' => errors
+ }
+ expect(Gitlab::Json.parse(response.body)).to eq(expected_response)
+ expect(response.status).to eq(400)
+ end
+ end
+ end
+end
diff --git a/spec/controllers/confirmations_controller_spec.rb b/spec/controllers/confirmations_controller_spec.rb
index 1c7f8de32bb..3b5afbcebca 100644
--- a/spec/controllers/confirmations_controller_spec.rb
+++ b/spec/controllers/confirmations_controller_spec.rb
@@ -152,7 +152,7 @@ RSpec.describe ConfirmationsController do
perform_request
expect(response).to render_template(:new)
- expect(flash[:alert]).to include 'There was an error with the reCAPTCHA. Please solve the reCAPTCHA again.'
+ expect(flash[:alert]).to include _('There was an error with the reCAPTCHA. Please solve the reCAPTCHA again.')
end
it 'successfully sends password reset when reCAPTCHA is solved' do
diff --git a/spec/controllers/dashboard_controller_spec.rb b/spec/controllers/dashboard_controller_spec.rb
index 8fae617ea65..aed310531e6 100644
--- a/spec/controllers/dashboard_controller_spec.rb
+++ b/spec/controllers/dashboard_controller_spec.rb
@@ -13,7 +13,22 @@ RSpec.describe DashboardController do
end
describe 'GET issues' do
- it_behaves_like 'issuables list meta-data', :issue, :issues
+ context 'when issues_full_text_search is disabled' do
+ before do
+ stub_feature_flags(issues_full_text_search: false)
+ end
+
+ it_behaves_like 'issuables list meta-data', :issue, :issues
+ end
+
+ context 'when issues_full_text_search is enabled' do
+ before do
+ stub_feature_flags(issues_full_text_search: true)
+ end
+
+ it_behaves_like 'issuables list meta-data', :issue, :issues
+ end
+
it_behaves_like 'issuables requiring filter', :issues
end
@@ -83,25 +98,49 @@ RSpec.describe DashboardController do
context "no filters" do
let(:params) { {} }
+ shared_examples_for 'no filters are set' do
+ it 'sets @no_filters_set to true' do
+ expect(assigns[:no_filters_set]).to eq(true)
+ end
+ end
+
+ it_behaves_like 'no filters are set'
+
+ context 'when key is present but value is not' do
+ let(:params) { { author_username: nil } }
+
+ it_behaves_like 'no filters are set'
+ end
+
+ context 'when in param is set but no search' do
+ let(:params) { { in: 'title' } }
+
+ it_behaves_like 'no filters are set'
+ end
+ end
+
+ shared_examples_for 'filters are set' do
it 'sets @no_filters_set to false' do
- expect(assigns[:no_filters_set]).to eq(true)
+ expect(assigns[:no_filters_set]).to eq(false)
end
end
context "scalar filters" do
let(:params) { { author_id: user.id } }
- it 'sets @no_filters_set to false' do
- expect(assigns[:no_filters_set]).to eq(false)
- end
+ it_behaves_like 'filters are set'
end
context "array filters" do
let(:params) { { label_name: ['bug'] } }
- it 'sets @no_filters_set to false' do
- expect(assigns[:no_filters_set]).to eq(false)
- end
+ it_behaves_like 'filters are set'
+ end
+
+ context 'search' do
+ let(:params) { { search: 'test' } }
+
+ it_behaves_like 'filters are set'
end
end
end
diff --git a/spec/controllers/graphql_controller_spec.rb b/spec/controllers/graphql_controller_spec.rb
index 95f60156c40..dbaed8aaa19 100644
--- a/spec/controllers/graphql_controller_spec.rb
+++ b/spec/controllers/graphql_controller_spec.rb
@@ -139,8 +139,45 @@ RSpec.describe GraphqlController do
context 'when user uses an API token' do
let(:user) { create(:user, last_activity_on: Date.yesterday) }
let(:token) { create(:personal_access_token, user: user, scopes: [:api]) }
+ let(:query) { '{ __typename }' }
- subject { post :execute, params: { access_token: token.token } }
+ subject { post :execute, params: { query: query, access_token: token.token } }
+
+ context 'when the user is a project bot' do
+ let(:user) { create(:user, :project_bot, last_activity_on: Date.yesterday) }
+
+ it 'updates the users last_activity_on field' do
+ expect { subject }.to change { user.reload.last_activity_on }
+ end
+
+ it "sets context's sessionless value as true" do
+ subject
+
+ expect(assigns(:context)[:is_sessionless_user]).to be true
+ end
+
+ it 'executes a simple query with no errors' do
+ subject
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response).to eq({ 'data' => { '__typename' => 'Query' } })
+ end
+
+ it 'can access resources the project_bot has access to' do
+ project_a, project_b = create_list(:project, 2, :private)
+ project_a.add_developer(user)
+
+ post :execute, params: { query: <<~GQL, access_token: token.token }
+ query {
+ a: project(fullPath: "#{project_a.full_path}") { name }
+ b: project(fullPath: "#{project_b.full_path}") { name }
+ }
+ GQL
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response).to eq({ 'data' => { 'a' => { 'name' => project_a.name }, 'b' => nil } })
+ end
+ end
it 'updates the users last_activity_on field' do
expect { subject }.to change { user.reload.last_activity_on }
diff --git a/spec/controllers/groups/clusters_controller_spec.rb b/spec/controllers/groups/clusters_controller_spec.rb
index 710e983dfbd..4eeae64b760 100644
--- a/spec/controllers/groups/clusters_controller_spec.rb
+++ b/spec/controllers/groups/clusters_controller_spec.rb
@@ -32,6 +32,10 @@ RSpec.describe Groups::ClustersController do
create(:cluster, :disabled, :provided_by_gcp, :production_environment, cluster_type: :group_type, groups: [group])
end
+ include_examples ':certificate_based_clusters feature flag controller responses' do
+ let(:subject) { go }
+ end
+
it 'lists available clusters and renders html' do
go
@@ -116,6 +120,10 @@ RSpec.describe Groups::ClustersController do
get :new, params: { group_id: group, provider: provider }
end
+ include_examples ':certificate_based_clusters feature flag controller responses' do
+ let(:subject) { go }
+ end
+
describe 'functionality for new cluster' do
context 'when omniauth has been configured' do
let(:key) { 'secret-key' }
@@ -255,6 +263,10 @@ RSpec.describe Groups::ClustersController do
post :create_gcp, params: params.merge(group_id: group)
end
+ include_examples ':certificate_based_clusters feature flag controller responses' do
+ let(:subject) { go }
+ end
+
describe 'functionality' do
context 'when access token is valid' do
before do
@@ -349,6 +361,10 @@ RSpec.describe Groups::ClustersController do
post :create_user, params: params.merge(group_id: group)
end
+ include_examples ':certificate_based_clusters feature flag controller responses' do
+ let(:subject) { go }
+ end
+
describe 'functionality' do
context 'when creates a cluster' do
it 'creates a new cluster' do
@@ -457,6 +473,10 @@ RSpec.describe Groups::ClustersController do
post :create_aws, params: params.merge(group_id: group)
end
+ include_examples ':certificate_based_clusters feature flag controller responses' do
+ let(:subject) { post_create_aws }
+ end
+
it 'creates a new cluster' do
expect(ClusterProvisionWorker).to receive(:perform_async)
expect { post_create_aws }.to change { Clusters::Cluster.count }
@@ -519,6 +539,10 @@ RSpec.describe Groups::ClustersController do
post :authorize_aws_role, params: params.merge(group_id: group)
end
+ include_examples ':certificate_based_clusters feature flag controller responses' do
+ let(:subject) { go }
+ end
+
before do
allow(Clusters::Aws::FetchCredentialsService).to receive(:new)
.and_return(double(execute: double))
@@ -579,6 +603,10 @@ RSpec.describe Groups::ClustersController do
}
end
+ include_examples ':certificate_based_clusters feature flag controller responses' do
+ let(:subject) { go }
+ end
+
it 'deletes the namespaces associated with the cluster' do
expect { go }.to change { Clusters::KubernetesNamespace.count }
@@ -611,6 +639,10 @@ RSpec.describe Groups::ClustersController do
format: :json
end
+ include_examples ':certificate_based_clusters feature flag controller responses' do
+ let(:subject) { go }
+ end
+
describe 'functionality' do
it 'responds with matching schema' do
go
@@ -651,6 +683,10 @@ RSpec.describe Groups::ClustersController do
}
end
+ include_examples ':certificate_based_clusters feature flag controller responses' do
+ let(:subject) { go }
+ end
+
describe 'functionality' do
render_views
@@ -705,6 +741,10 @@ RSpec.describe Groups::ClustersController do
}
end
+ include_examples ':certificate_based_clusters feature flag controller responses' do
+ let(:subject) { go }
+ end
+
it 'updates and redirects back to show page' do
go
@@ -802,6 +842,10 @@ RSpec.describe Groups::ClustersController do
}
end
+ include_examples ':certificate_based_clusters feature flag controller responses' do
+ let(:subject) { go }
+ end
+
describe 'functionality' do
context 'when cluster is provided by GCP' do
context 'when cluster is created' do
diff --git a/spec/controllers/groups/dependency_proxy_for_containers_controller_spec.rb b/spec/controllers/groups/dependency_proxy_for_containers_controller_spec.rb
index 57a83da3425..61445603a2d 100644
--- a/spec/controllers/groups/dependency_proxy_for_containers_controller_spec.rb
+++ b/spec/controllers/groups/dependency_proxy_for_containers_controller_spec.rb
@@ -170,6 +170,14 @@ RSpec.describe Groups::DependencyProxyForContainersController do
end
end
+ shared_examples 'namespace statistics refresh' do
+ it 'updates namespace statistics' do
+ expect(Groups::UpdateStatisticsWorker).to receive(:perform_async)
+
+ subject
+ end
+ end
+
before do
allow(Gitlab.config.dependency_proxy)
.to receive(:enabled).and_return(true)
@@ -403,13 +411,15 @@ RSpec.describe Groups::DependencyProxyForContainersController do
context 'with a valid user' do
before do
group.add_guest(user)
-
- expect_next_found_instance_of(Group) do |instance|
- expect(instance).to receive_message_chain(:dependency_proxy_blobs, :create!)
- end
end
it_behaves_like 'a package tracking event', described_class.name, 'pull_blob'
+
+ it 'creates a blob' do
+ expect { subject }.to change { group.dependency_proxy_blobs.count }.by(1)
+ end
+
+ it_behaves_like 'namespace statistics refresh'
end
end
@@ -473,6 +483,8 @@ RSpec.describe Groups::DependencyProxyForContainersController do
expect(manifest.digest).to eq(digest)
expect(manifest.file_name).to eq(file_name)
end
+
+ it_behaves_like 'namespace statistics refresh'
end
context 'with existing stale manifest' do
@@ -483,6 +495,8 @@ RSpec.describe Groups::DependencyProxyForContainersController do
expect { subject }.to change { group.dependency_proxy_manifests.count }.by(0)
.and change { manifest.reload.digest }.from(old_digest).to(digest)
end
+
+ it_behaves_like 'namespace statistics refresh'
end
end
end
diff --git a/spec/controllers/groups/group_members_controller_spec.rb b/spec/controllers/groups/group_members_controller_spec.rb
index 04a9b9f5250..25d32436d58 100644
--- a/spec/controllers/groups/group_members_controller_spec.rb
+++ b/spec/controllers/groups/group_members_controller_spec.rb
@@ -38,12 +38,6 @@ RSpec.describe Groups::GroupMembersController do
expect(assigns(:invited_members).map(&:invite_email)).to match_array(invited.map(&:invite_email))
end
- it 'assigns skip groups' do
- get :index, params: { group_id: group }
-
- expect(assigns(:skip_groups)).to match_array(group.related_group_ids)
- end
-
it 'restricts search to one email' do
get :index, params: { group_id: group, search_invited: invited.first.invite_email }
@@ -68,11 +62,10 @@ RSpec.describe Groups::GroupMembersController do
sign_in(user)
end
- it 'does not assign invited members or skip_groups', :aggregate_failures do
+ it 'does not assign invited members' do
get :index, params: { group_id: group }
expect(assigns(:invited_members)).to be_nil
- expect(assigns(:skip_groups)).to be_nil
end
end
@@ -106,107 +99,6 @@ RSpec.describe Groups::GroupMembersController do
end
end
- describe 'POST create' do
- let_it_be(:group_user) { create(:user) }
-
- before do
- sign_in(user)
- end
-
- context 'when user does not have enough rights' do
- before do
- group.add_developer(user)
- end
-
- it 'returns 403', :aggregate_failures do
- post :create, params: {
- group_id: group,
- user_ids: group_user.id,
- access_level: Gitlab::Access::GUEST
- }
-
- expect(response).to have_gitlab_http_status(:forbidden)
- expect(group.users).not_to include group_user
- end
- end
-
- context 'when user has enough rights' do
- before do
- group.add_owner(user)
- end
-
- it 'adds user to members', :aggregate_failures, :snowplow do
- post :create, params: {
- group_id: group,
- user_ids: group_user.id,
- access_level: Gitlab::Access::GUEST
- }
-
- expect(controller).to set_flash.to 'Users were successfully added.'
- expect(response).to redirect_to(group_group_members_path(group))
- expect(group.users).to include group_user
- expect_snowplow_event(
- category: 'Members::CreateService',
- action: 'create_member',
- label: 'group-members-page',
- property: 'existing_user',
- user: user
- )
- end
-
- it 'adds no user to members', :aggregate_failures do
- post :create, params: {
- group_id: group,
- user_ids: '',
- access_level: Gitlab::Access::GUEST
- }
-
- expect(controller).to set_flash.to 'No users specified.'
- expect(response).to redirect_to(group_group_members_path(group))
- expect(group.users).not_to include group_user
- end
- end
-
- context 'access expiry date' do
- before do
- group.add_owner(user)
- end
-
- subject do
- post :create, params: {
- group_id: group,
- user_ids: group_user.id,
- access_level: Gitlab::Access::GUEST,
- expires_at: expires_at
- }
- end
-
- context 'when set to a date in the past' do
- let(:expires_at) { 2.days.ago }
-
- it 'does not add user to members', :aggregate_failures do
- subject
-
- expect(flash[:alert]).to include('Expires at cannot be a date in the past')
- expect(response).to redirect_to(group_group_members_path(group))
- expect(group.users).not_to include group_user
- end
- end
-
- context 'when set to a date in the future' do
- let(:expires_at) { 5.days.from_now }
-
- it 'adds user to members', :aggregate_failures do
- subject
-
- expect(controller).to set_flash.to 'Users were successfully added.'
- expect(response).to redirect_to(group_group_members_path(group))
- expect(group.users).to include group_user
- end
- end
- end
- end
-
describe 'PUT update' do
let_it_be(:requester) { create(:group_member, :access_request, group: group) }
@@ -515,14 +407,6 @@ RSpec.describe Groups::GroupMembersController do
end
end
- describe 'POST #create' do
- it 'is successful' do
- post :create, params: { group_id: group, users: user, access_level: Gitlab::Access::GUEST }
-
- expect(response).to have_gitlab_http_status(:found)
- end
- end
-
describe 'PUT #update' do
it 'is successful' do
put :update,
diff --git a/spec/controllers/groups/releases_controller_spec.rb b/spec/controllers/groups/releases_controller_spec.rb
index 582a77b1c50..8b08f913e10 100644
--- a/spec/controllers/groups/releases_controller_spec.rb
+++ b/spec/controllers/groups/releases_controller_spec.rb
@@ -20,11 +20,11 @@ RSpec.describe Groups::ReleasesController do
context 'as json' do
let(:format) { :json }
- subject { get :index, params: { group_id: group }, format: format }
+ subject(:index) { get :index, params: { group_id: group }, format: format }
context 'json_response' do
before do
- subject
+ index
end
it 'returns an application/json content_type' do
@@ -38,7 +38,7 @@ RSpec.describe Groups::ReleasesController do
context 'the user is not authorized' do
before do
- subject
+ index
end
it 'does not return any releases' do
@@ -54,12 +54,38 @@ RSpec.describe Groups::ReleasesController do
it "returns all group's public and private project's releases as JSON, ordered by released_at" do
sign_in(guest)
- subject
+ index
expect(json_response.map {|r| r['tag'] } ).to match_array(%w(p2 p1 v2 v1))
end
end
+ context 'group_releases_finder_inoperator feature flag' do
+ before do
+ sign_in(guest)
+ end
+
+ it 'calls old code when disabled' do
+ stub_feature_flags(group_releases_finder_inoperator: false)
+
+ allow(ReleasesFinder).to receive(:new).and_call_original
+
+ index
+
+ expect(ReleasesFinder).to have_received(:new)
+ end
+
+ it 'calls new code when enabled' do
+ stub_feature_flags(group_releases_finder_inoperator: true)
+
+ allow(Releases::GroupReleasesFinder).to receive(:new).and_call_original
+
+ index
+
+ expect(Releases::GroupReleasesFinder).to have_received(:new)
+ end
+ end
+
context 'N+1 queries' do
it 'avoids N+1 database queries' do
control_count = ActiveRecord::QueryRecorder.new { subject }.count
diff --git a/spec/controllers/groups/runners_controller_spec.rb b/spec/controllers/groups/runners_controller_spec.rb
index 9f0615a96ae..b4950b93a3f 100644
--- a/spec/controllers/groups/runners_controller_spec.rb
+++ b/spec/controllers/groups/runners_controller_spec.rb
@@ -190,7 +190,7 @@ RSpec.describe Groups::RunnersController do
end
it 'destroys the runner and redirects' do
- expect_next_instance_of(Ci::UnregisterRunnerService, runner) do |service|
+ expect_next_instance_of(Ci::Runners::UnregisterRunnerService, runner, user) do |service|
expect(service).to receive(:execute).once.and_call_original
end
@@ -208,21 +208,39 @@ RSpec.describe Groups::RunnersController do
end
end
- context 'when user is an owner and runner in multiple projects' do
- let(:project_2) { create(:project, group: group) }
+ context 'with runner associated with multiple projects' do
+ let_it_be(:project_2) { create(:project, group: group) }
+
let(:runner_project_2) { create(:ci_runner, :project, projects: [project, project_2]) }
let(:params_runner_project_2) { { group_id: group, id: runner_project_2 } }
- before do
- group.add_owner(user)
+ context 'when user is an admin', :enable_admin_mode do
+ let(:user) { create(:user, :admin) }
+
+ before do
+ sign_in(user)
+ end
+
+ it 'destroys the project runner and redirects' do
+ delete :destroy, params: params_runner_project_2
+
+ expect(response).to have_gitlab_http_status(:found)
+ expect(Ci::Runner.find_by(id: runner_project_2.id)).to be_nil
+ end
end
- it 'does not destroy the project runner' do
- delete :destroy, params: params_runner_project_2
+ context 'when user is an owner' do
+ before do
+ group.add_owner(user)
+ end
+
+ it 'does not destroy the project runner' do
+ delete :destroy, params: params_runner_project_2
- expect(response).to have_gitlab_http_status(:found)
- expect(flash[:alert]).to eq('Runner was not deleted because it is assigned to multiple projects.')
- expect(Ci::Runner.find_by(id: runner_project_2.id)).to be_present
+ expect(response).to have_gitlab_http_status(:found)
+ expect(flash[:alert]).to eq('Runner cannot be deleted, please contact your administrator.')
+ expect(Ci::Runner.find_by(id: runner_project_2.id)).to be_present
+ end
end
end
diff --git a/spec/controllers/jira_connect/events_controller_spec.rb b/spec/controllers/jira_connect/events_controller_spec.rb
index 2a70a2ea683..2129b24b2fb 100644
--- a/spec/controllers/jira_connect/events_controller_spec.rb
+++ b/spec/controllers/jira_connect/events_controller_spec.rb
@@ -43,14 +43,15 @@ RSpec.describe JiraConnect::EventsController do
end
describe '#installed' do
- let(:client_key) { '1234' }
- let(:shared_secret) { 'secret' }
+ let_it_be(:client_key) { '1234' }
+ let_it_be(:shared_secret) { 'secret' }
+ let_it_be(:base_url) { 'https://test.atlassian.net' }
let(:params) do
{
clientKey: client_key,
sharedSecret: shared_secret,
- baseUrl: 'https://test.atlassian.net'
+ baseUrl: base_url
}
end
@@ -77,11 +78,11 @@ RSpec.describe JiraConnect::EventsController do
expect(installation.base_url).to eq('https://test.atlassian.net')
end
- context 'when it is a version update and shared_secret is not sent' do
+ context 'when the shared_secret param is missing' do
let(:params) do
{
clientKey: client_key,
- baseUrl: 'https://test.atlassian.net'
+ baseUrl: base_url
}
end
@@ -90,13 +91,48 @@ RSpec.describe JiraConnect::EventsController do
expect(response).to have_gitlab_http_status(:unprocessable_entity)
end
+ end
+
+ context 'when an installation already exists' do
+ let_it_be(:installation) { create(:jira_connect_installation, base_url: base_url, client_key: client_key, shared_secret: shared_secret) }
+
+ it 'validates the JWT token in authorization header and returns 200 without creating a new installation', :aggregate_failures do
+ expect { subject }.not_to change { JiraConnectInstallation.count }
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+
+ context 'when parameters include a new shared secret and base_url' do
+ let(:shared_secret) { 'new_secret' }
+ let(:base_url) { 'https://new_test.atlassian.net' }
- context 'and an installation exists' do
- let!(:installation) { create(:jira_connect_installation, client_key: client_key, shared_secret: shared_secret) }
+ it 'updates the installation', :aggregate_failures do
+ subject
- it 'validates the JWT token in authorization header and returns 200 without creating a new installation' do
- expect { subject }.not_to change { JiraConnectInstallation.count }
expect(response).to have_gitlab_http_status(:ok)
+ expect(installation.reload).to have_attributes(
+ shared_secret: shared_secret,
+ base_url: base_url
+ )
+ end
+
+ context 'when the `jira_connect_installation_update` feature flag is disabled' do
+ before do
+ stub_feature_flags(jira_connect_installation_update: false)
+ end
+
+ it 'does not update the installation', :aggregate_failures do
+ expect { subject }.not_to change { installation.reload.attributes }
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+ end
+ end
+
+ context 'when the new base_url is invalid' do
+ let(:base_url) { 'invalid' }
+
+ it 'renders 422', :aggregate_failures do
+ expect { subject }.not_to change { installation.reload.base_url }
+ expect(response).to have_gitlab_http_status(:unprocessable_entity)
end
end
end
diff --git a/spec/controllers/passwords_controller_spec.rb b/spec/controllers/passwords_controller_spec.rb
index 01c032d9e3b..82014282c6e 100644
--- a/spec/controllers/passwords_controller_spec.rb
+++ b/spec/controllers/passwords_controller_spec.rb
@@ -121,7 +121,7 @@ RSpec.describe PasswordsController do
perform_request
expect(response).to render_template(:new)
- expect(flash[:alert]).to include 'There was an error with the reCAPTCHA. Please solve the reCAPTCHA again.'
+ expect(flash[:alert]).to include _('There was an error with the reCAPTCHA. Please solve the reCAPTCHA again.')
end
it 'successfully sends password reset when reCAPTCHA is solved' do
diff --git a/spec/controllers/projects/blob_controller_spec.rb b/spec/controllers/projects/blob_controller_spec.rb
index 53efcc65066..cc807098498 100644
--- a/spec/controllers/projects/blob_controller_spec.rb
+++ b/spec/controllers/projects/blob_controller_spec.rb
@@ -366,8 +366,8 @@ RSpec.describe Projects::BlobController do
it_behaves_like 'tracking unique hll events' do
subject(:request) { put :update, params: default_params }
- let(:target_id) { 'g_edit_by_sfe' }
- let(:expected_type) { instance_of(Integer) }
+ let(:target_event) { 'g_edit_by_sfe' }
+ let(:expected_value) { instance_of(Integer) }
end
end
@@ -516,8 +516,8 @@ RSpec.describe Projects::BlobController do
subject(:request) { post :create, params: default_params }
it_behaves_like 'tracking unique hll events' do
- let(:target_id) { 'g_edit_by_sfe' }
- let(:expected_type) { instance_of(Integer) }
+ let(:target_event) { 'g_edit_by_sfe' }
+ let(:expected_value) { instance_of(Integer) }
end
it 'redirects to blob' do
@@ -525,24 +525,5 @@ RSpec.describe Projects::BlobController do
expect(response).to redirect_to(project_blob_path(project, 'master/docs/EXAMPLE_FILE'))
end
-
- context 'when code_quality_walkthrough param is present' do
- let(:default_params) { super().merge(code_quality_walkthrough: true) }
-
- it 'redirects to the pipelines page' do
- request
-
- expect(response).to redirect_to(project_pipelines_path(project, code_quality_walkthrough: true))
- end
-
- it 'creates an "commit_created" experiment tracking event' do
- experiment = double(track: true)
- expect(controller).to receive(:experiment).with(:code_quality_walkthrough, namespace: project.root_ancestor).and_return(experiment)
-
- request
-
- expect(experiment).to have_received(:track).with(:commit_created)
- end
- end
end
end
diff --git a/spec/controllers/projects/ci/pipeline_editor_controller_spec.rb b/spec/controllers/projects/ci/pipeline_editor_controller_spec.rb
index d55aad20689..37406d704f1 100644
--- a/spec/controllers/projects/ci/pipeline_editor_controller_spec.rb
+++ b/spec/controllers/projects/ci/pipeline_editor_controller_spec.rb
@@ -36,17 +36,5 @@ RSpec.describe Projects::Ci::PipelineEditorController do
expect(response).to have_gitlab_http_status(:not_found)
end
end
-
- describe 'pipeline_editor_walkthrough experiment' do
- before do
- project.add_developer(user)
- end
-
- subject(:action) { show_request }
-
- it_behaves_like 'tracks assignment and records the subject', :pipeline_editor_walkthrough, :namespace do
- subject { project.namespace }
- end
- end
end
end
diff --git a/spec/controllers/projects/ci/secure_files_controller_spec.rb b/spec/controllers/projects/ci/secure_files_controller_spec.rb
new file mode 100644
index 00000000000..1138897bcc6
--- /dev/null
+++ b/spec/controllers/projects/ci/secure_files_controller_spec.rb
@@ -0,0 +1,49 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Projects::Ci::SecureFilesController do
+ let_it_be(:project) { create(:project) }
+ let_it_be(:user) { create(:user) }
+
+ subject(:show_request) { get :show, params: { namespace_id: project.namespace, project_id: project } }
+
+ describe 'GET #show' do
+ context 'with enough privileges' do
+ before do
+ sign_in(user)
+ project.add_developer(user)
+ show_request
+ end
+
+ it { expect(response).to have_gitlab_http_status(:ok) }
+
+ it 'renders show page' do
+ expect(response).to render_template :show
+ end
+ end
+
+ context 'without enough privileges' do
+ before do
+ sign_in(user)
+ project.add_reporter(user)
+ show_request
+ end
+
+ it 'responds with 404' do
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+
+ context 'an unauthenticated user' do
+ before do
+ show_request
+ end
+
+ it 'redirects to sign in' do
+ expect(response).to have_gitlab_http_status(:found)
+ expect(response).to redirect_to('/users/sign_in')
+ end
+ end
+ end
+end
diff --git a/spec/controllers/projects/clusters_controller_spec.rb b/spec/controllers/projects/clusters_controller_spec.rb
index d0bef810ec8..44bdc958805 100644
--- a/spec/controllers/projects/clusters_controller_spec.rb
+++ b/spec/controllers/projects/clusters_controller_spec.rb
@@ -26,6 +26,10 @@ RSpec.describe Projects::ClustersController do
let!(:enabled_cluster) { create(:cluster, :provided_by_gcp, projects: [project]) }
let!(:disabled_cluster) { create(:cluster, :disabled, :provided_by_gcp, :production_environment, projects: [project]) }
+ include_examples ':certificate_based_clusters feature flag index responses' do
+ let(:subject) { go }
+ end
+
it 'lists available clusters and renders html' do
go
@@ -118,6 +122,10 @@ RSpec.describe Projects::ClustersController do
}
end
+ include_examples ':certificate_based_clusters feature flag controller responses' do
+ let(:subject) { go }
+ end
+
describe 'functionality for new cluster' do
context 'when omniauth has been configured' do
let(:key) { 'secret-key' }
@@ -264,6 +272,10 @@ RSpec.describe Projects::ClustersController do
post :create_gcp, params: params.merge(namespace_id: project.namespace, project_id: project)
end
+ include_examples ':certificate_based_clusters feature flag controller responses' do
+ let(:subject) { go }
+ end
+
describe 'functionality' do
context 'when access token is valid' do
before do
@@ -360,6 +372,10 @@ RSpec.describe Projects::ClustersController do
post :create_user, params: params.merge(namespace_id: project.namespace, project_id: project)
end
+ include_examples ':certificate_based_clusters feature flag controller responses' do
+ let(:subject) { go }
+ end
+
describe 'functionality' do
context 'when creates a cluster' do
it 'creates a new cluster' do
@@ -477,6 +493,10 @@ RSpec.describe Projects::ClustersController do
post :create_aws, params: params.merge(namespace_id: project.namespace, project_id: project)
end
+ include_examples ':certificate_based_clusters feature flag controller responses' do
+ let(:subject) { post_create_aws }
+ end
+
it 'creates a new cluster' do
expect(ClusterProvisionWorker).to receive(:perform_async)
expect { post_create_aws }.to change { Clusters::Cluster.count }
@@ -548,6 +568,10 @@ RSpec.describe Projects::ClustersController do
.and_return(double(execute: double))
end
+ include_examples ':certificate_based_clusters feature flag controller responses' do
+ let(:subject) { go }
+ end
+
it 'updates the associated role with the supplied ARN' do
go
@@ -603,6 +627,10 @@ RSpec.describe Projects::ClustersController do
}
end
+ include_examples ':certificate_based_clusters feature flag controller responses' do
+ let(:subject) { go }
+ end
+
it 'deletes the namespaces associated with the cluster' do
expect { go }.to change { Clusters::KubernetesNamespace.count }
@@ -640,6 +668,10 @@ RSpec.describe Projects::ClustersController do
format: :json
end
+ include_examples ':certificate_based_clusters feature flag controller responses' do
+ let(:subject) { go }
+ end
+
describe 'functionality' do
it "responds with matching schema" do
go
@@ -685,6 +717,10 @@ RSpec.describe Projects::ClustersController do
}
end
+ include_examples ':certificate_based_clusters feature flag controller responses' do
+ let(:subject) { go }
+ end
+
describe 'functionality' do
render_views
@@ -749,6 +785,10 @@ RSpec.describe Projects::ClustersController do
}
end
+ include_examples ':certificate_based_clusters feature flag controller responses' do
+ let(:subject) { go }
+ end
+
it "updates and redirects back to show page" do
go
@@ -842,6 +882,10 @@ RSpec.describe Projects::ClustersController do
}
end
+ include_examples ':certificate_based_clusters feature flag controller responses' do
+ let(:subject) { go }
+ end
+
describe 'functionality' do
context 'when cluster is provided by GCP' do
context 'when cluster is created' do
diff --git a/spec/controllers/projects/environments_controller_spec.rb b/spec/controllers/projects/environments_controller_spec.rb
index 0fcdeb2edde..fdfc21887a6 100644
--- a/spec/controllers/projects/environments_controller_spec.rb
+++ b/spec/controllers/projects/environments_controller_spec.rb
@@ -6,7 +6,7 @@ RSpec.describe Projects::EnvironmentsController do
include MetricsDashboardHelpers
include KubernetesHelpers
- let_it_be(:project) { create(:project) }
+ let_it_be(:project) { create(:project, :repository) }
let_it_be(:maintainer) { create(:user, name: 'main-dos').tap { |u| project.add_maintainer(u) } }
let_it_be(:reporter) { create(:user, name: 'repo-dos').tap { |u| project.add_reporter(u) } }
@@ -55,11 +55,11 @@ RSpec.describe Projects::EnvironmentsController do
let(:environments) { json_response['environments'] }
context 'with default parameters' do
- before do
- get :index, params: environment_params(format: :json)
- end
+ subject { get :index, params: environment_params(format: :json) }
it 'responds with a flat payload describing available environments' do
+ subject
+
expect(environments.count).to eq 3
expect(environments.first).to include('name' => 'production', 'name_without_type' => 'production')
expect(environments.second).to include('name' => 'staging/review-1', 'name_without_type' => 'review-1')
@@ -69,9 +69,28 @@ RSpec.describe Projects::EnvironmentsController do
end
it 'sets the polling interval header' do
+ subject
+
expect(response).to have_gitlab_http_status(:ok)
expect(response.headers['Poll-Interval']).to eq("3000")
end
+
+ context 'validates latest deployment' do
+ let_it_be(:test_environment) do
+ create(:environment, project: project, name: 'staging/review-4', state: :available)
+ end
+
+ before do
+ create_list(:deployment, 2, :success, environment: test_environment, project: project)
+ end
+
+ it 'responds with the latest deployment for the environment' do
+ subject
+
+ environment = environments.find { |env| env['id'] == test_environment.id }
+ expect(environment['last_deployment']['id']).to eq(test_environment.deployments.last.id)
+ end
+ end
end
context 'when a folder-based nested structure is requested' do
diff --git a/spec/controllers/projects/error_tracking_controller_spec.rb b/spec/controllers/projects/error_tracking_controller_spec.rb
index 822778779eb..b4f21e070c6 100644
--- a/spec/controllers/projects/error_tracking_controller_spec.rb
+++ b/spec/controllers/projects/error_tracking_controller_spec.rb
@@ -50,9 +50,7 @@ RSpec.describe Projects::ErrorTrackingController do
let(:external_url) { 'http://example.com' }
context 'no data' do
- let(:permitted_params) do
- ActionController::Parameters.new({}).permit!
- end
+ let(:permitted_params) { permit_index_parameters!({}) }
before do
expect(ErrorTracking::ListIssuesService)
@@ -75,9 +73,7 @@ RSpec.describe Projects::ErrorTrackingController do
let(:search_term) { 'something' }
let(:sort) { 'last_seen' }
let(:params) { project_params(format: :json, search_term: search_term, sort: sort, cursor: cursor) }
- let(:permitted_params) do
- ActionController::Parameters.new(search_term: search_term, sort: sort, cursor: cursor).permit!
- end
+ let(:permitted_params) { permit_index_parameters!(search_term: search_term, sort: sort, cursor: cursor) }
before do
expect(ErrorTracking::ListIssuesService)
@@ -114,7 +110,7 @@ RSpec.describe Projects::ErrorTrackingController do
context 'without extra params' do
before do
expect(ErrorTracking::ListIssuesService)
- .to receive(:new).with(project, user, {})
+ .to receive(:new).with(project, user, permit_index_parameters!({}))
.and_return(list_issues_service)
end
@@ -179,6 +175,15 @@ RSpec.describe Projects::ErrorTrackingController do
end
end
end
+
+ private
+
+ def permit_index_parameters!(params)
+ ActionController::Parameters.new(
+ **params,
+ tracking_event: :error_tracking_view_list
+ ).permit!
+ end
end
describe 'GET #issue_details' do
@@ -188,7 +193,8 @@ RSpec.describe Projects::ErrorTrackingController do
let(:permitted_params) do
ActionController::Parameters.new(
- { issue_id: issue_id.to_s }
+ issue_id: issue_id.to_s,
+ tracking_event: :error_tracking_view_details
).permit!
end
diff --git a/spec/controllers/projects/forks_controller_spec.rb b/spec/controllers/projects/forks_controller_spec.rb
index 0f8f3b49e02..962ef93dc72 100644
--- a/spec/controllers/projects/forks_controller_spec.rb
+++ b/spec/controllers/projects/forks_controller_spec.rb
@@ -199,15 +199,6 @@ RSpec.describe Projects::ForksController do
expect(json_response['namespaces'][1]['id']).to eq(group.id)
end
- it 'responds with group only when fork_project_form feature flag is disabled' do
- stub_feature_flags(fork_project_form: false)
- do_request
-
- expect(response).to have_gitlab_http_status(:ok)
- expect(json_response['namespaces'].length).to eq(1)
- expect(json_response['namespaces'][0]['id']).to eq(group.id)
- end
-
context 'N+1 queries' do
before do
create(:fork_network, root_project: project)
diff --git a/spec/controllers/projects/incidents_controller_spec.rb b/spec/controllers/projects/incidents_controller_spec.rb
index 460821634b0..20cf0dcfd3a 100644
--- a/spec/controllers/projects/incidents_controller_spec.rb
+++ b/spec/controllers/projects/incidents_controller_spec.rb
@@ -43,6 +43,7 @@ RSpec.describe Projects::IncidentsController do
expect(response).to have_gitlab_http_status(:ok)
expect(response).to render_template(:index)
+ expect(Gon.features).to include('incidentEscalations' => true)
end
context 'when user is unauthorized' do
diff --git a/spec/controllers/projects/issues_controller_spec.rb b/spec/controllers/projects/issues_controller_spec.rb
index bf0b833b311..9d3711d8a96 100644
--- a/spec/controllers/projects/issues_controller_spec.rb
+++ b/spec/controllers/projects/issues_controller_spec.rb
@@ -72,7 +72,21 @@ RSpec.describe Projects::IssuesController do
project.add_developer(user)
end
- it_behaves_like "issuables list meta-data", :issue
+ context 'when issues_full_text_search is disabled' do
+ before do
+ stub_feature_flags(issues_full_text_search: false)
+ end
+
+ it_behaves_like 'issuables list meta-data', :issue
+ end
+
+ context 'when issues_full_text_search is enabled' do
+ before do
+ stub_feature_flags(issues_full_text_search: true)
+ end
+
+ it_behaves_like 'issuables list meta-data', :issue
+ end
it_behaves_like 'set sort order from user preference' do
let(:sorting_param) { 'updated_asc' }
@@ -605,11 +619,11 @@ RSpec.describe Projects::IssuesController do
end
end
- context 'when the SpamVerdictService disallows' do
+ context 'when an issue is identified as spam' 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(CONDITIONAL_ALLOW)
+ allow_next_instance_of(Spam::AkismetService) do |akismet_service|
+ allow(akismet_service).to receive(:spam?).and_return(true)
end
end
@@ -926,8 +940,8 @@ RSpec.describe Projects::IssuesController do
context 'when an issue is identified as spam' 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(CONDITIONAL_ALLOW)
+ allow_next_instance_of(Spam::AkismetService) do |akismet_service|
+ allow(akismet_service).to receive(:spam?).and_return(true)
end
end
@@ -1004,6 +1018,7 @@ RSpec.describe Projects::IssuesController do
end
it 'returns 200 status' do
+ update_verified_issue
expect(response).to have_gitlab_http_status(:ok)
end
@@ -1051,35 +1066,6 @@ RSpec.describe Projects::IssuesController do
.not_to exceed_query_limit(control_count + 2 * labels.count)
end
- context 'real-time sidebar feature flag' do
- let_it_be(:project) { create(:project, :public) }
- let_it_be(:issue) { create(:issue, project: project) }
-
- context 'when enabled' do
- before do
- stub_feature_flags(real_time_issue_sidebar: true)
- end
-
- it 'pushes the correct value to the frontend' do
- go(id: issue.to_param)
-
- expect(Gon.features).to include('realTimeIssueSidebar' => true)
- end
- end
-
- context 'when disabled' do
- before do
- stub_feature_flags(real_time_issue_sidebar: false)
- end
-
- it 'pushes the correct value to the frontend' do
- go(id: issue.to_param)
-
- expect(Gon.features).to include('realTimeIssueSidebar' => false)
- end
- end
- end
-
it 'logs the view with Gitlab::Search::RecentIssues' do
sign_in(user)
recent_issues_double = instance_double(::Gitlab::Search::RecentIssues, log_view: nil)
@@ -1260,11 +1246,11 @@ RSpec.describe Projects::IssuesController do
end
end
- context 'when SpamVerdictService requires recaptcha' do
+ context 'when an issue is identified as spam and requires recaptcha' 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(CONDITIONAL_ALLOW)
+ allow_next_instance_of(Spam::AkismetService) do |akismet_service|
+ allow(akismet_service).to receive(:spam?).and_return(true)
end
end
diff --git a/spec/controllers/projects/merge_requests/diffs_controller_spec.rb b/spec/controllers/projects/merge_requests/diffs_controller_spec.rb
index a5c59b7e22d..367781c0e76 100644
--- a/spec/controllers/projects/merge_requests/diffs_controller_spec.rb
+++ b/spec/controllers/projects/merge_requests/diffs_controller_spec.rb
@@ -220,29 +220,6 @@ RSpec.describe Projects::MergeRequests::DiffsController do
end
end
- context "with the :default_merge_ref_for_diffs flag on" do
- let(:diffable_merge_ref) { true }
-
- subject do
- go(diff_head: true,
- diff_id: merge_request.merge_request_diff.id,
- start_sha: merge_request.merge_request_diff.start_commit_sha)
- end
-
- it "correctly generates the right diff between versions" do
- MergeRequests::MergeToRefService.new(project: project, current_user: merge_request.author).execute(merge_request)
-
- expect_next_instance_of(CompareService) do |service|
- expect(service).to receive(:execute).with(
- project,
- merge_request.merge_request_diff.head_commit_sha,
- straight: true)
- end
-
- subject
- end
- end
-
context 'with diff_head param passed' do
before do
allow(merge_request).to receive(:diffable_merge_ref?)
@@ -259,6 +236,23 @@ RSpec.describe Projects::MergeRequests::DiffsController do
expect(response).to have_gitlab_http_status(:ok)
end
+
+ context 'when diff_id and start_sha are set' do
+ it 'correctly generates the right diff between versions' do
+ MergeRequests::MergeToRefService.new(project: project, current_user: merge_request.author).execute(merge_request)
+
+ expect_next_instance_of(CompareService) do |service|
+ expect(service).to receive(:execute).with(
+ project,
+ merge_request.merge_request_diff.head_commit_sha,
+ straight: true)
+ end
+
+ go(diff_head: true,
+ diff_id: merge_request.merge_request_diff.id,
+ start_sha: merge_request.merge_request_diff.start_commit_sha)
+ end
+ end
end
context 'the merge request cannot be compared with head' do
diff --git a/spec/controllers/projects/merge_requests_controller_spec.rb b/spec/controllers/projects/merge_requests_controller_spec.rb
index 2390687c3ea..f6db809c2e3 100644
--- a/spec/controllers/projects/merge_requests_controller_spec.rb
+++ b/spec/controllers/projects/merge_requests_controller_spec.rb
@@ -68,6 +68,18 @@ RSpec.describe Projects::MergeRequestsController do
end
describe 'as html' do
+ it 'sets the endpoint_metadata_url' do
+ go
+
+ expect(assigns["endpoint_metadata_url"]).to eq(
+ diffs_metadata_project_json_merge_request_path(
+ project,
+ merge_request,
+ 'json',
+ diff_head: true,
+ view: 'inline'))
+ end
+
context 'when diff files were cleaned' do
render_views
@@ -85,23 +97,6 @@ RSpec.describe Projects::MergeRequestsController do
end
end
- context 'with `default_merge_ref_for_diffs` feature flag enabled' do
- before do
- stub_feature_flags(default_merge_ref_for_diffs: true)
- go
- end
-
- it 'adds the diff_head parameter' do
- expect(assigns["endpoint_metadata_url"]).to eq(
- diffs_metadata_project_json_merge_request_path(
- project,
- merge_request,
- 'json',
- diff_head: true,
- view: 'inline'))
- end
- end
-
context 'when diff is missing' do
render_views
diff --git a/spec/controllers/projects/pipelines_controller_spec.rb b/spec/controllers/projects/pipelines_controller_spec.rb
index 4a51e2ed5a0..8fae82d54a2 100644
--- a/spec/controllers/projects/pipelines_controller_spec.rb
+++ b/spec/controllers/projects/pipelines_controller_spec.rb
@@ -292,12 +292,8 @@ RSpec.describe Projects::PipelinesController do
subject { project.namespace }
- context 'code_quality_walkthrough experiment' do
- it_behaves_like 'tracks assignment and records the subject', :code_quality_walkthrough, :namespace
- end
-
- context 'ci_runner_templates experiment' do
- it_behaves_like 'tracks assignment and records the subject', :ci_runner_templates, :namespace
+ context 'runners_availability_section experiment' do
+ it_behaves_like 'tracks assignment and records the subject', :runners_availability_section, :namespace
end
end
@@ -936,6 +932,33 @@ RSpec.describe Projects::PipelinesController do
expect(response).to have_gitlab_http_status(:not_found)
end
end
+
+ context 'when access denied' do
+ it 'returns an error' do
+ sign_in(create(:user))
+
+ post_retry
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+
+ context 'when service returns an error' do
+ before do
+ service_response = ServiceResponse.error(message: 'some error', http_status: 404)
+ allow_next_instance_of(::Ci::RetryPipelineService) do |service|
+ allow(service).to receive(:check_access).and_return(service_response)
+ end
+ end
+
+ it 'does not retry' do
+ post_retry
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ expect(response.body).to include('some error')
+ expect(::Ci::RetryPipelineWorker).not_to have_received(:perform_async).with(pipeline.id, user.id)
+ end
+ end
end
describe 'POST cancel.json' do
diff --git a/spec/controllers/projects/project_members_controller_spec.rb b/spec/controllers/projects/project_members_controller_spec.rb
index d8ef95cf11a..20a114bbe8c 100644
--- a/spec/controllers/projects/project_members_controller_spec.rb
+++ b/spec/controllers/projects/project_members_controller_spec.rb
@@ -147,137 +147,6 @@ RSpec.describe Projects::ProjectMembersController do
end
end
- describe 'POST create' do
- let_it_be(:project_user) { create(:user) }
-
- before do
- sign_in(user)
- end
-
- context 'when user does not have enough rights' do
- before do
- project.add_developer(user)
- end
-
- it 'returns 404', :aggregate_failures do
- post :create, params: {
- namespace_id: project.namespace,
- project_id: project,
- user_ids: project_user.id,
- access_level: Gitlab::Access::GUEST
- }
-
- expect(response).to have_gitlab_http_status(:not_found)
- expect(project.users).not_to include project_user
- end
- end
-
- context 'when user has enough rights' do
- before do
- project.add_maintainer(user)
- end
-
- it 'adds user to members', :aggregate_failures, :snowplow do
- post :create, params: {
- namespace_id: project.namespace,
- project_id: project,
- user_ids: project_user.id,
- access_level: Gitlab::Access::GUEST
- }
-
- expect(controller).to set_flash.to 'Users were successfully added.'
- expect(response).to redirect_to(project_project_members_path(project))
- expect(project.users).to include project_user
- expect_snowplow_event(
- category: 'Members::CreateService',
- action: 'create_member',
- label: 'project-members-page',
- property: 'existing_user',
- user: user
- )
- end
-
- it 'adds no user to members', :aggregate_failures do
- expect_next_instance_of(Members::CreateService) do |instance|
- expect(instance).to receive(:execute).and_return(status: :failure, message: 'Message')
- end
-
- post :create, params: {
- namespace_id: project.namespace,
- project_id: project,
- user_ids: '',
- access_level: Gitlab::Access::GUEST
- }
-
- expect(controller).to set_flash.to 'Message'
- expect(response).to redirect_to(project_project_members_path(project))
- end
- end
-
- context 'adding project bot' do
- let_it_be(:project_bot) { create(:user, :project_bot) }
-
- before do
- project.add_maintainer(user)
-
- unrelated_project = create(:project)
- unrelated_project.add_maintainer(project_bot)
- end
-
- it 'returns error', :aggregate_failures do
- post :create, params: {
- namespace_id: project.namespace,
- project_id: project,
- user_ids: project_bot.id,
- access_level: Gitlab::Access::GUEST
- }
-
- expect(flash[:alert]).to include('project bots cannot be added to other groups / projects')
- expect(response).to redirect_to(project_project_members_path(project))
- end
- end
-
- context 'access expiry date' do
- before do
- project.add_maintainer(user)
- end
-
- subject do
- post :create, params: {
- namespace_id: project.namespace,
- project_id: project,
- user_ids: project_user.id,
- access_level: Gitlab::Access::GUEST,
- expires_at: expires_at
- }
- end
-
- context 'when set to a date in the past' do
- let(:expires_at) { 2.days.ago }
-
- it 'does not add user to members', :aggregate_failures do
- subject
-
- expect(flash[:alert]).to include('Expires at cannot be a date in the past')
- expect(response).to redirect_to(project_project_members_path(project))
- expect(project.users).not_to include project_user
- end
- end
-
- context 'when set to a date in the future' do
- let(:expires_at) { 5.days.from_now }
-
- it 'adds user to members', :aggregate_failures do
- subject
-
- expect(controller).to set_flash.to 'Users were successfully added.'
- expect(response).to redirect_to(project_project_members_path(project))
- expect(project.users).to include project_user
- end
- end
- end
- end
-
describe 'PUT update' do
let_it_be(:requester) { create(:project_member, :access_request, project: project) }
@@ -603,99 +472,6 @@ RSpec.describe Projects::ProjectMembersController do
end
end
- describe 'POST apply_import' do
- let_it_be(:another_project) { create(:project, :private) }
- let_it_be(:member) { create(:user) }
-
- before do
- project.add_maintainer(user)
- another_project.add_guest(member)
- sign_in(user)
- end
-
- shared_context 'import applied' do
- before do
- post(:apply_import, params: {
- namespace_id: project.namespace,
- project_id: project,
- source_project_id: another_project.id
- })
- end
- end
-
- context 'when user can admin source project members' do
- before do
- another_project.add_maintainer(user)
- end
-
- include_context 'import applied'
-
- it 'imports source project members', :aggregate_failures do
- expect(project.team_members).to include member
- expect(controller).to set_flash.to 'Successfully imported'
- expect(response).to redirect_to(
- project_project_members_path(project)
- )
- end
- end
-
- context "when user can't admin source project members" do
- before do
- another_project.add_developer(user)
- end
-
- include_context 'import applied'
-
- it 'does not import team members' do
- expect(project.team_members).not_to include member
- end
-
- it 'responds with not found' do
- expect(response).to have_gitlab_http_status(:not_found)
- end
- end
- end
-
- describe 'POST create' do
- let_it_be(:stranger) { create(:user) }
-
- context 'when creating owner' do
- before do
- project.add_maintainer(user)
- sign_in(user)
- end
-
- it 'does not create a member' do
- expect do
- post :create, params: {
- user_ids: stranger.id,
- namespace_id: project.namespace,
- access_level: Member::OWNER,
- project_id: project
- }
- end.to change { project.members.count }.by(0)
- end
- end
-
- context 'when create maintainer' do
- before do
- project.add_maintainer(user)
- sign_in(user)
- end
-
- it 'creates a member' do
- expect do
- post :create, params: {
- user_ids: stranger.id,
- namespace_id: project.namespace,
- access_level: Member::MAINTAINER,
- project_id: project
- }
- end.to change { project.members.count }.by(1)
- end
- end
- end
-
describe 'POST resend_invite' do
let_it_be(:member) { create(:project_member, project: project) }
diff --git a/spec/controllers/projects/releases_controller_spec.rb b/spec/controllers/projects/releases_controller_spec.rb
index 120020273f9..9dd18e58109 100644
--- a/spec/controllers/projects/releases_controller_spec.rb
+++ b/spec/controllers/projects/releases_controller_spec.rb
@@ -222,6 +222,168 @@ RSpec.describe Projects::ReleasesController do
end
end
+ describe 'GET #latest_permalink' do
+ # Uses default order_by=released_at parameter.
+ subject do
+ get :latest_permalink, params: { namespace_id: project.namespace, project_id: project }
+ end
+
+ before do
+ sign_in(user)
+ end
+
+ let(:release) { create(:release, project: project) }
+ let(:tag) { CGI.escape(release.tag) }
+
+ context 'when user is a guest' do
+ let(:project) { private_project }
+ let(:user) { guest }
+
+ it 'proceeds with the redirect' do
+ subject
+
+ expect(response).to have_gitlab_http_status(:redirect)
+ end
+ end
+
+ context 'when user is an external user for the project' do
+ let(:project) { private_project }
+ let(:user) { create(:user) }
+
+ it 'behaves like not found' do
+ subject
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+
+ context 'when there are no releases for the project' do
+ let(:project) { create(:project, :repository, :public) }
+ let(:user) { developer }
+
+ before do
+ project.releases.destroy_all # rubocop: disable Cop/DestroyAll
+ end
+
+ it 'behaves like not found' do
+ subject
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+
+ context 'multiple releases' do
+ let(:user) { developer }
+
+ it 'redirects to the latest release' do
+ create(:release, project: project, released_at: 1.day.ago)
+ latest_release = create(:release, project: project, released_at: Time.current)
+
+ subject
+
+ expect(response).to redirect_to("#{project_releases_path(project)}/#{latest_release.tag}")
+ end
+ end
+
+ context 'suffix path redirection' do
+ let(:user) { developer }
+ let(:suffix_path) { 'downloads/zips/helm-hello-world.zip' }
+ let!(:latest_release) { create(:release, project: project, released_at: Time.current) }
+
+ subject do
+ get :latest_permalink, params: {
+ namespace_id: project.namespace,
+ project_id: project,
+ suffix_path: suffix_path
+ }
+ end
+
+ it 'redirects to the latest release with suffix path and format' do
+ subject
+
+ expect(response).to redirect_to(
+ "#{project_releases_path(project)}/#{latest_release.tag}/#{suffix_path}")
+ end
+
+ context 'suffix path abuse' do
+ let(:suffix_path) { 'downloads/zips/../../../../../../../robots.txt'}
+
+ it 'raises attack error' do
+ expect do
+ subject
+ end.to raise_error(Gitlab::Utils::PathTraversalAttackError)
+ end
+ end
+
+ context 'url parameters' do
+ let(:suffix_path) { 'downloads/zips/helm-hello-world.zip' }
+
+ subject do
+ get :latest_permalink, params: {
+ namespace_id: project.namespace,
+ project_id: project,
+ suffix_path: suffix_path,
+ order_by: 'released_at',
+ param_1: 1,
+ param_2: 2
+ }
+ end
+
+ it 'carries over query parameters without order_by parameter in the redirect' do
+ subject
+
+ expect(response).to redirect_to(
+ "#{project_releases_path(project)}/#{latest_release.tag}/#{suffix_path}?param_1=1&param_2=2")
+ end
+ end
+ end
+
+ context 'order_by parameter' do
+ let!(:latest_release) { create(:release, project: project, released_at: Time.current, tag: 'latest') }
+
+ shared_examples_for 'redirects to latest release ordered by using released_at' do
+ it do
+ expect(Release).to receive(:order_released_desc).and_call_original
+
+ subject
+
+ expect(response).to redirect_to("#{project_releases_path(project)}/#{latest_release.tag}")
+ end
+ end
+
+ before do
+ create(:release, project: project, released_at: 1.day.ago, tag: 'alpha')
+ create(:release, project: project, released_at: 2.days.ago, tag: 'beta')
+ end
+
+ context 'invalid parameter' do
+ let(:user) { developer }
+
+ subject do
+ get :latest_permalink, params: {
+ namespace_id: project.namespace,
+ project_id: project,
+ order_by: 'unsupported'
+ }
+ end
+
+ it_behaves_like 'redirects to latest release ordered by using released_at'
+ end
+
+ context 'valid parameter' do
+ subject do
+ get :latest_permalink, params: {
+ namespace_id: project.namespace,
+ project_id: project,
+ order_by: 'released_at'
+ }
+ end
+
+ it_behaves_like 'redirects to latest release ordered by using released_at'
+ end
+ end
+ end
+
# `GET #downloads` is addressed in spec/requests/projects/releases_controller_spec.rb
private
diff --git a/spec/controllers/projects/runners_controller_spec.rb b/spec/controllers/projects/runners_controller_spec.rb
index 246a37129d7..57d1695b842 100644
--- a/spec/controllers/projects/runners_controller_spec.rb
+++ b/spec/controllers/projects/runners_controller_spec.rb
@@ -37,7 +37,7 @@ RSpec.describe Projects::RunnersController do
describe '#destroy' do
it 'destroys the runner' do
- expect_next_instance_of(Ci::UnregisterRunnerService, runner) do |service|
+ expect_next_instance_of(Ci::Runners::UnregisterRunnerService, runner, user) do |service|
expect(service).to receive(:execute).once.and_call_original
end
diff --git a/spec/controllers/projects/serverless/functions_controller_spec.rb b/spec/controllers/projects/serverless/functions_controller_spec.rb
index 860bbc1c5cc..f8cee09006c 100644
--- a/spec/controllers/projects/serverless/functions_controller_spec.rb
+++ b/spec/controllers/projects/serverless/functions_controller_spec.rb
@@ -39,9 +39,24 @@ RSpec.describe Projects::Serverless::FunctionsController do
project_id: project.to_param)
end
+ shared_examples_for 'behind :deprecated_serverless feature flag' do
+ before do
+ stub_feature_flags(deprecated_serverless: false)
+ end
+
+ it 'returns 404' do
+ action
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+
describe 'GET #index' do
let(:expected_json) { { 'knative_installed' => knative_state, 'functions' => functions } }
+ it_behaves_like 'behind :deprecated_serverless feature flag' do
+ let(:action) { get :index, params: params({ format: :json }) }
+ end
+
context 'when cache is being read' do
let(:knative_state) { 'checking' }
let(:functions) { [] }
@@ -147,6 +162,10 @@ RSpec.describe Projects::Serverless::FunctionsController do
end
describe 'GET #show' do
+ it_behaves_like 'behind :deprecated_serverless feature flag' do
+ let(:action) { get :show, params: params({ format: :json, environment_id: "*", id: "foo" }) }
+ end
+
context 'with function that does not exist' do
it 'returns 404' do
get :show, params: params({ format: :json, environment_id: "*", id: "foo" })
@@ -239,6 +258,10 @@ RSpec.describe Projects::Serverless::FunctionsController do
end
describe 'GET #metrics' do
+ it_behaves_like 'behind :deprecated_serverless feature flag' do
+ let(:action) { get :metrics, params: params({ format: :json, environment_id: "*", id: "foo" }) }
+ end
+
context 'invalid data' do
it 'has a bad function name' do
get :metrics, params: params({ format: :json, environment_id: "*", id: "foo" })
diff --git a/spec/controllers/projects/services_controller_spec.rb b/spec/controllers/projects/services_controller_spec.rb
index f3c7b501faa..35e5422d072 100644
--- a/spec/controllers/projects/services_controller_spec.rb
+++ b/spec/controllers/projects/services_controller_spec.rb
@@ -353,7 +353,16 @@ RSpec.describe Projects::ServicesController do
it 'does not modify integration' do
expect { put :update, params: project_params.merge(service: integration_params) }
- .not_to change { project.prometheus_integration.reload.attributes }
+ .not_to change { prometheus_integration_as_data }
+ end
+
+ def prometheus_integration_as_data
+ pi = project.prometheus_integration.reload
+ attrs = pi.attributes.except('encrypted_properties',
+ 'encrypted_properties_iv',
+ 'encrypted_properties_tmp')
+
+ [attrs, pi.encrypted_properties_tmp]
end
end
diff --git a/spec/controllers/projects/tags/releases_controller_spec.rb b/spec/controllers/projects/tags/releases_controller_spec.rb
index b3d4d944440..1d2385f54f9 100644
--- a/spec/controllers/projects/tags/releases_controller_spec.rb
+++ b/spec/controllers/projects/tags/releases_controller_spec.rb
@@ -5,7 +5,7 @@ require 'spec_helper'
RSpec.describe Projects::Tags::ReleasesController do
let!(:project) { create(:project, :repository) }
let!(:user) { create(:user) }
- let!(:release) { create(:release, project: project) }
+ let!(:release) { create(:release, project: project, tag: "v1.1.0") }
let!(:tag) { release.tag }
before do
@@ -27,7 +27,7 @@ RSpec.describe Projects::Tags::ReleasesController do
end
it 'retrieves an existing release' do
- response = get :edit, params: { namespace_id: project.namespace, project_id: project, tag_id: release.tag }
+ response = get :edit, params: { namespace_id: project.namespace, project_id: project, tag_id: tag }
release = assigns(:release)
expect(release).not_to be_nil
diff --git a/spec/controllers/projects/tags_controller_spec.rb b/spec/controllers/projects/tags_controller_spec.rb
index f955f9d0248..d0971e96910 100644
--- a/spec/controllers/projects/tags_controller_spec.rb
+++ b/spec/controllers/projects/tags_controller_spec.rb
@@ -4,7 +4,7 @@ require 'spec_helper'
RSpec.describe Projects::TagsController do
let(:project) { create(:project, :public, :repository) }
- let!(:release) { create(:release, project: project) }
+ let!(:release) { create(:release, project: project, tag: "v1.1.0") }
let!(:invalid_release) { create(:release, project: project, tag: 'does-not-exist') }
let(:user) { create(:user) }
diff --git a/spec/controllers/projects_controller_spec.rb b/spec/controllers/projects_controller_spec.rb
index 08d1d88fcda..c098ea71f7a 100644
--- a/spec/controllers/projects_controller_spec.rb
+++ b/spec/controllers/projects_controller_spec.rb
@@ -1211,16 +1211,6 @@ RSpec.describe ProjectsController do
expect(response).to have_gitlab_http_status(:success)
end
-
- context 'when "strong_parameters_for_project_controller" FF is disabled' do
- before do
- stub_feature_flags(strong_parameters_for_project_controller: false)
- end
-
- it 'raises an exception' do
- expect { request }.to raise_error(TypeError)
- end
- end
end
end
@@ -1600,71 +1590,22 @@ RSpec.describe ProjectsController do
get :show, format: :atom, params: { id: public_project, namespace_id: public_project.namespace }
- expect(response).to render_template('xml.atom')
+ expect(response).to have_gitlab_http_status(:success)
+ expect(response).to render_template(:show)
+ expect(response).to render_template(layout: :xml)
expect(assigns(:events)).to eq([event])
end
it 'filters by calling event.visible_to_user?' do
get :show, format: :atom, params: { id: public_project, namespace_id: public_project.namespace }
- expect(response).to render_template('xml.atom')
+ expect(response).to have_gitlab_http_status(:success)
+ expect(response).to render_template(:show)
+ expect(response).to render_template(layout: :xml)
expect(assigns(:events)).to eq([event])
end
end
- describe 'GET resolve' do
- shared_examples 'resolvable endpoint' do
- it 'redirects to the project page' do
- get :resolve, params: { id: project.id }
-
- expect(response).to have_gitlab_http_status(:found)
- expect(response).to redirect_to(project_path(project))
- end
- end
-
- context 'with an authenticated user' do
- before do
- sign_in(user)
- end
-
- context 'when user has access to the project' do
- before do
- project.add_developer(user)
- end
-
- it_behaves_like 'resolvable endpoint'
- end
-
- context 'when user has no access to the project' do
- it 'gives 404 for existing project' do
- get :resolve, params: { id: project.id }
-
- expect(response).to have_gitlab_http_status(:not_found)
- end
- end
-
- it 'gives 404 for non-existing project' do
- get :resolve, params: { id: '0' }
-
- expect(response).to have_gitlab_http_status(:not_found)
- end
- end
-
- context 'non authenticated user' do
- context 'with a public project' do
- let(:project) { public_project }
-
- it_behaves_like 'resolvable endpoint'
- end
-
- it 'gives 404 for private project' do
- get :resolve, params: { id: project.id }
-
- expect(response).to have_gitlab_http_status(:not_found)
- end
- end
- end
-
it 'updates Service Desk attributes' do
project.add_maintainer(user)
sign_in(user)
diff --git a/spec/controllers/search_controller_spec.rb b/spec/controllers/search_controller_spec.rb
index 0f1501d4c3c..9482448fc03 100644
--- a/spec/controllers/search_controller_spec.rb
+++ b/spec/controllers/search_controller_spec.rb
@@ -251,8 +251,8 @@ RSpec.describe SearchController do
it_behaves_like 'tracking unique hll events' do
subject(:request) { get :show, params: { scope: 'projects', search: 'term' } }
- let(:target_id) { 'i_search_total' }
- let(:expected_type) { instance_of(String) }
+ let(:target_event) { 'i_search_total' }
+ let(:expected_value) { instance_of(String) }
end
end
@@ -291,7 +291,7 @@ RSpec.describe SearchController do
end
end
- it_behaves_like 'rate limited endpoint', rate_limit_key: :user_email_lookup do
+ it_behaves_like 'rate limited endpoint', rate_limit_key: :search_rate_limit do
let(:current_user) { user }
def request
@@ -355,7 +355,7 @@ RSpec.describe SearchController do
expect(json_response).to eq({ 'count' => '0' })
end
- it_behaves_like 'rate limited endpoint', rate_limit_key: :user_email_lookup do
+ it_behaves_like 'rate limited endpoint', rate_limit_key: :search_rate_limit do
let(:current_user) { user }
def request
@@ -375,7 +375,7 @@ RSpec.describe SearchController do
expect(json_response).to match_array([])
end
- it_behaves_like 'rate limited endpoint', rate_limit_key: :user_email_lookup do
+ it_behaves_like 'rate limited endpoint', rate_limit_key: :search_rate_limit do
let(:current_user) { user }
def request
@@ -445,6 +445,26 @@ RSpec.describe SearchController do
end
context 'unauthorized user' do
+ describe 'search rate limits' do
+ using RSpec::Parameterized::TableSyntax
+
+ let(:project) { create(:project, :public) }
+
+ where(:endpoint, :params) do
+ :show | { search: 'hello', scope: 'projects' }
+ :count | { search: 'hello', scope: 'projects' }
+ :autocomplete | { term: 'hello', scope: 'projects' }
+ end
+
+ with_them do
+ it_behaves_like 'rate limited endpoint', rate_limit_key: :search_rate_limit_unauthenticated do
+ def request
+ get endpoint, params: params.merge(project_id: project.id)
+ end
+ end
+ end
+ end
+
describe 'GET #opensearch' do
render_views
diff --git a/spec/controllers/sessions_controller_spec.rb b/spec/controllers/sessions_controller_spec.rb
index 31de00dd8bd..03d053e6f97 100644
--- a/spec/controllers/sessions_controller_spec.rb
+++ b/spec/controllers/sessions_controller_spec.rb
@@ -235,7 +235,7 @@ RSpec.describe SessionsController do
unsuccesful_login(user_params)
expect(response).to render_template(:new)
- expect(flash[:alert]).to include 'There was an error with the reCAPTCHA. Please solve the reCAPTCHA again.'
+ expect(flash[:alert]).to include _('There was an error with the reCAPTCHA. Please solve the reCAPTCHA again.')
expect(subject.current_user).to be_nil
end
@@ -259,7 +259,7 @@ RSpec.describe SessionsController do
unsuccesful_login(user_params, sesion_params: { failed_login_attempts: 6 })
expect(response).to render_template(:new)
- expect(flash[:alert]).to include 'There was an error with the reCAPTCHA. Please solve the reCAPTCHA again.'
+ expect(flash[:alert]).to include _('There was an error with the reCAPTCHA. Please solve the reCAPTCHA again.')
expect(subject.current_user).to be_nil
end
@@ -279,7 +279,7 @@ RSpec.describe SessionsController do
unsuccesful_login(user_params)
expect(response).to render_template(:new)
- expect(flash[:alert]).to include 'There was an error with the reCAPTCHA. Please solve the reCAPTCHA again.'
+ expect(flash[:alert]).to include _('There was an error with the reCAPTCHA. Please solve the reCAPTCHA again.')
expect(subject.current_user).to be_nil
end
diff --git a/spec/controllers/snippets_controller_spec.rb b/spec/controllers/snippets_controller_spec.rb
index a82c44fcc44..18b2d3b14ec 100644
--- a/spec/controllers/snippets_controller_spec.rb
+++ b/spec/controllers/snippets_controller_spec.rb
@@ -176,8 +176,8 @@ RSpec.describe SnippetsController do
it_behaves_like 'tracking unique hll events' do
subject(:request) { get :show, params: { id: public_snippet.to_param } }
- let(:target_id) { 'i_snippets_show' }
- let(:expected_type) { instance_of(String) }
+ let(:target_event) { 'i_snippets_show' }
+ let(:expected_value) { instance_of(String) }
end
end
diff --git a/spec/db/schema_spec.rb b/spec/db/schema_spec.rb
index 2608a13a399..177a565bbc0 100644
--- a/spec/db/schema_spec.rb
+++ b/spec/db/schema_spec.rb
@@ -18,6 +18,7 @@ RSpec.describe 'Database schema' do
approvals: %w[user_id],
approver_groups: %w[target_id],
approvers: %w[target_id user_id],
+ analytics_cycle_analytics_aggregations: %w[last_full_run_issues_id last_full_run_merge_requests_id last_incremental_issues_id last_incremental_merge_requests_id],
analytics_cycle_analytics_merge_request_stage_events: %w[author_id group_id merge_request_id milestone_id project_id stage_event_hash_id state_id],
analytics_cycle_analytics_issue_stage_events: %w[author_id group_id issue_id milestone_id project_id stage_event_hash_id state_id],
audit_events: %w[author_id entity_id target_id],
@@ -66,6 +67,7 @@ RSpec.describe 'Database schema' do
oauth_access_tokens: %w[resource_owner_id application_id],
oauth_applications: %w[owner_id],
product_analytics_events_experimental: %w[event_id txn_id user_id],
+ project_build_artifacts_size_refreshes: %w[last_job_artifact_id],
project_group_links: %w[group_id],
project_statistics: %w[namespace_id],
projects: %w[creator_id ci_id mirror_user_id],
diff --git a/spec/experiments/application_experiment_spec.rb b/spec/experiments/application_experiment_spec.rb
index 70ee4bd3c5a..15b45099a06 100644
--- a/spec/experiments/application_experiment_spec.rb
+++ b/spec/experiments/application_experiment_spec.rb
@@ -18,68 +18,33 @@ RSpec.describe ApplicationExperiment, :experiment do
allow(application_experiment).to receive(:enabled?).and_return(true)
end
- it "doesn't raise an exception without a defined control" do
- # because we have a default behavior defined
+ it "registers a default control behavior for anonymous experiments" do
+ # This default control behavior is not inherited, intentionally, but it
+ # does provide anonymous experiments with a base control behavior to keep
+ # them optional there.
- expect { experiment('namespaced/stub') { } }.not_to raise_error
+ expect(experiment(:example)).to register_behavior(:control).with(nil)
+ expect { experiment(:example) { } }.not_to raise_error
end
describe "#publish" do
- let(:should_track) { true }
-
- before do
- allow(application_experiment).to receive(:should_track?).and_return(should_track)
- end
-
it "tracks the assignment", :snowplow do
- application_experiment.publish
-
- expect_snowplow_event(
- category: 'namespaced/stub',
- action: 'assignment',
- context: [{ schema: anything, data: anything }]
- )
- end
-
- it "publishes to the client" do
- expect(application_experiment).to receive(:publish_to_client)
+ expect(application_experiment).to receive(:track).with(:assignment)
application_experiment.publish
end
- context 'when we should not track' do
- let(:should_track) { false }
-
- it 'does not track an event to Snowplow', :snowplow do
- application_experiment.publish
-
- expect_no_snowplow_event
- end
- end
-
- describe "#publish_to_client" do
- it "adds the data into Gon" do
- signature = { key: '86208ac54ca798e11f127e8b23ec396a', variant: 'control' }
- expect(Gon).to receive(:push).with({ experiment: { 'namespaced/stub' => hash_including(signature) } }, true)
-
- application_experiment.publish_to_client
- end
-
- it "handles when Gon raises exceptions (like when it can't be pushed into)" do
- expect(Gon).to receive(:push).and_raise(NoMethodError)
-
- expect { application_experiment.publish_to_client }.not_to raise_error
- end
-
- context 'when we should not track' do
- let(:should_track) { false }
-
- it 'returns early' do
- expect(Gon).not_to receive(:push)
+ it "adds to the published experiments" do
+ # These are surfaced in the client layer by rendering them in the
+ # _published_experiments.html.haml partial.
+ application_experiment.publish
- application_experiment.publish_to_client
- end
- end
+ expect(ApplicationExperiment.published_experiments['namespaced/stub']).to include(
+ experiment: 'namespaced/stub',
+ excluded: false,
+ key: anything,
+ variant: 'control'
+ )
end
describe '#publish_to_database' do
@@ -278,12 +243,12 @@ RSpec.describe ApplicationExperiment, :experiment do
with_them do
it "returns the url or nil if invalid" do
- allow(Gitlab).to receive(:dev_env_or_com?).and_return(true)
+ allow(Gitlab).to receive(:com?).and_return(true)
expect(application_experiment.process_redirect_url(url)).to eq(processed_url)
end
it "considers all urls invalid when not on dev or com" do
- allow(Gitlab).to receive(:dev_env_or_com?).and_return(false)
+ allow(Gitlab).to receive(:com?).and_return(false)
expect(application_experiment.process_redirect_url(url)).to be_nil
end
end
@@ -340,7 +305,7 @@ RSpec.describe ApplicationExperiment, :experiment do
end
it "caches the variant determined by the variant resolver" do
- expect(application_experiment.variant.name).to eq('candidate') # we should be in the experiment
+ expect(application_experiment.assigned.name).to eq('candidate') # we should be in the experiment
application_experiment.run
@@ -355,7 +320,7 @@ RSpec.describe ApplicationExperiment, :experiment do
# the control.
stub_feature_flags(namespaced_stub: false) # simulate being not rolled out
- expect(application_experiment.variant.name).to eq('control') # if we ask, it should be control
+ expect(application_experiment.assigned.name).to eq('control') # if we ask, it should be control
application_experiment.run
diff --git a/spec/factories/analytics/cycle_analytics/aggregations.rb b/spec/factories/analytics/cycle_analytics/aggregations.rb
new file mode 100644
index 00000000000..78e82f166d0
--- /dev/null
+++ b/spec/factories/analytics/cycle_analytics/aggregations.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+FactoryBot.define do
+ factory :cycle_analytics_aggregation, class: 'Analytics::CycleAnalytics::Aggregation' do
+ group
+
+ enabled { true }
+
+ trait :disabled do
+ enabled { false }
+ end
+
+ trait :enabled do
+ enabled { true }
+ end
+ end
+end
diff --git a/spec/factories/ci/reports/security/evidence.rb b/spec/factories/ci/reports/security/evidence.rb
new file mode 100644
index 00000000000..ed744644447
--- /dev/null
+++ b/spec/factories/ci/reports/security/evidence.rb
@@ -0,0 +1,60 @@
+# frozen_string_literal: true
+
+FactoryBot.define do
+ factory :ci_reports_security_evidence, class: '::Gitlab::Ci::Reports::Security::Evidence' do
+ data do
+ {
+ summary: 'Credit card detected',
+ request: {
+ headers: [{ name: 'Accept', value: '*/*' }],
+ method: 'GET',
+ url: 'http://goat:8080/WebGoat/logout',
+ body: nil
+ },
+ response: {
+ headers: [{ name: 'Content-Length', value: '0' }],
+ reason_phrase: 'OK',
+ status_code: 200,
+ body: nil
+ },
+ source: {
+ id: 'assert:Response Body Analysis',
+ name: 'Response Body Analysis',
+ url: 'htpp://hostname/documentation'
+ },
+ supporting_messages: [
+ {
+ name: 'Origional',
+ request: {
+ headers: [{ name: 'Accept', value: '*/*' }],
+ method: 'GET',
+ url: 'http://goat:8080/WebGoat/logout',
+ body: ''
+ }
+ },
+ {
+ name: 'Recorded',
+ request: {
+ headers: [{ name: 'Accept', value: '*/*' }],
+ method: 'GET',
+ url: 'http://goat:8080/WebGoat/logout',
+ body: ''
+ },
+ response: {
+ headers: [{ name: 'Content-Length', value: '0' }],
+ reason_phrase: 'OK',
+ status_code: 200,
+ body: ''
+ }
+ }
+ ]
+ }
+ end
+
+ skip_create
+
+ initialize_with do
+ ::Gitlab::Ci::Reports::Security::Evidence.new(**attributes)
+ end
+ end
+end
diff --git a/spec/factories/ci/reports/security/findings.rb b/spec/factories/ci/reports/security/findings.rb
index 8a39fce971f..78c11210f97 100644
--- a/spec/factories/ci/reports/security/findings.rb
+++ b/spec/factories/ci/reports/security/findings.rb
@@ -6,6 +6,7 @@ FactoryBot.define do
confidence { :medium }
identifiers { Array.new(1) { association(:ci_reports_security_identifier) } }
location factory: :ci_reports_security_locations_sast
+ evidence factory: :ci_reports_security_evidence
metadata_version { 'sast:1.0' }
name { 'Cipher with no integrity' }
report_type { :sast }
@@ -25,7 +26,53 @@ FactoryBot.define do
name: "Cipher does not check for integrity first?",
url: "https://crypto.stackexchange.com/questions/31428/pbewithmd5anddes-cipher-does-not-check-for-integrity-first"
}
- ]
+ ],
+ evidence: {
+ summary: 'Credit card detected',
+ request: {
+ headers: [{ name: 'Accept', value: '*/*' }],
+ method: 'GET',
+ url: 'http://goat:8080/WebGoat/logout',
+ body: nil
+ },
+ response: {
+ headers: [{ name: 'Content-Length', value: '0' }],
+ reason_phrase: 'OK',
+ status_code: 200,
+ body: nil
+ },
+ source: {
+ id: 'assert:Response Body Analysis',
+ name: 'Response Body Analysis',
+ url: 'htpp://hostname/documentation'
+ },
+ supporting_messages: [
+ {
+ name: 'Origional',
+ request: {
+ headers: [{ name: 'Accept', value: '*/*' }],
+ method: 'GET',
+ url: 'http://goat:8080/WebGoat/logout',
+ body: ''
+ }
+ },
+ {
+ name: 'Recorded',
+ request: {
+ headers: [{ name: 'Accept', value: '*/*' }],
+ method: 'GET',
+ url: 'http://goat:8080/WebGoat/logout',
+ body: ''
+ },
+ response: {
+ headers: [{ name: 'Content-Length', value: '0' }],
+ reason_phrase: 'OK',
+ status_code: 200,
+ body: ''
+ }
+ }
+ ]
+ }
}.deep_stringify_keys
end
scanner factory: :ci_reports_security_scanner
diff --git a/spec/factories/customer_relations/issue_customer_relations_contacts.rb b/spec/factories/customer_relations/issue_customer_relations_contacts.rb
index 6a4fecfb3cf..8ea1a521a33 100644
--- a/spec/factories/customer_relations/issue_customer_relations_contacts.rb
+++ b/spec/factories/customer_relations/issue_customer_relations_contacts.rb
@@ -21,7 +21,7 @@ FactoryBot.define do
trait :for_issue do
issue { raise ArgumentError, '`issue` is manadatory' }
- contact { association(:contact, group: issue.project.group) }
+ contact { association(:contact, group: issue.project.root_ancestor) }
end
end
end
diff --git a/spec/factories/groups.rb b/spec/factories/groups.rb
index 152ae061605..aa264ad3377 100644
--- a/spec/factories/groups.rb
+++ b/spec/factories/groups.rb
@@ -118,5 +118,14 @@ FactoryBot.define do
create(:crm_settings, group: group, enabled: true)
end
end
+
+ trait :test_group do
+ path { "test-group-fulfillment#{SecureRandom.hex(4)}" }
+ created_at { 4.days.ago }
+
+ after(:create) do |group|
+ group.add_owner(create(:user, email: "test-user-#{SecureRandom.hex(4)}@test.com"))
+ end
+ end
end
end
diff --git a/spec/factories/integrations.rb b/spec/factories/integrations.rb
index f3a00ac083a..0ffa15ad403 100644
--- a/spec/factories/integrations.rb
+++ b/spec/factories/integrations.rb
@@ -12,6 +12,16 @@ FactoryBot.define do
issue_tracker
end
+ factory :jenkins_integration, class: 'Integrations::Jenkins' do
+ project
+ active { true }
+ type { 'Integrations::Jenkins' }
+ jenkins_url { 'http://jenkins.example.com/' }
+ project_name { 'my-project' }
+ username { 'jenkings-user' }
+ password { 'passw0rd' }
+ end
+
factory :datadog_integration, class: 'Integrations::Datadog' do
project
active { true }
@@ -20,7 +30,7 @@ FactoryBot.define do
factory :emails_on_push_integration, class: 'Integrations::EmailsOnPush' do
project
- type { 'EmailsOnPushService' }
+ type { 'Integrations::EmailsOnPush' }
active { true }
push_events { true }
tag_push_events { true }
@@ -54,7 +64,7 @@ FactoryBot.define do
factory :jira_integration, class: 'Integrations::Jira' do
project
active { true }
- type { 'JiraService' }
+ type { 'Integrations::Jira' }
transient do
create_data { true }
@@ -88,7 +98,7 @@ FactoryBot.define do
factory :zentao_integration, class: 'Integrations::Zentao' do
project
active { true }
- type { 'ZentaoService' }
+ type { 'Integrations::Zentao' }
transient do
create_data { true }
@@ -167,7 +177,7 @@ FactoryBot.define do
factory :external_wiki_integration, class: 'Integrations::ExternalWiki' do
project
- type { 'ExternalWikiService' }
+ type { 'Integrations::ExternalWiki' }
active { true }
external_wiki_url { 'http://external-wiki-url.com' }
end
@@ -178,27 +188,59 @@ FactoryBot.define do
password { 'my-secret-password' }
end
+ trait :chat_notification do
+ webhook { 'https://example.com/webhook' }
+ end
+
+ trait :inactive do
+ active { false }
+ end
+
+ factory :mattermost_integration, class: 'Integrations::Mattermost' do
+ chat_notification
+ project
+ type { 'Integrations::Mattermost' }
+ active { true }
+ end
+
# avoids conflict with slack_integration factory
factory :integrations_slack, class: 'Integrations::Slack' do
+ chat_notification
project
active { true }
- webhook { 'https://slack.service.url' }
- type { 'SlackService' }
+ type { 'Integrations::Slack' }
end
factory :slack_slash_commands_integration, class: 'Integrations::SlackSlashCommands' do
project
active { true }
- type { 'SlackSlashCommandsService' }
+ type { 'Integrations::SlackSlashCommands' }
end
factory :pipelines_email_integration, class: 'Integrations::PipelinesEmail' do
project
active { true }
- type { 'PipelinesEmailService' }
+ type { 'Integrations::PipelinesEmail' }
recipients { 'test@example.com' }
end
+ factory :pivotaltracker_integration, class: 'Integrations::Pivotaltracker' do
+ project
+ active { true }
+ token { 'test' }
+ end
+
+ factory :harbor_integration, class: 'Integrations::Harbor' do
+ project
+ active { true }
+ type { 'HarborService' }
+
+ url { 'https://demo.goharbor.io' }
+ project_name { 'testproject' }
+ username { 'harborusername' }
+ password { 'harborpassword' }
+ 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
@@ -217,11 +259,6 @@ FactoryBot.define do
end
end
- trait :template do
- project { nil }
- template { true }
- end
-
trait :group do
group
project { nil }
diff --git a/spec/factories/merge_requests.rb b/spec/factories/merge_requests.rb
index 6f706546402..26804b38db8 100644
--- a/spec/factories/merge_requests.rb
+++ b/spec/factories/merge_requests.rb
@@ -33,6 +33,10 @@ FactoryBot.define do
title { generate(:jira_title) }
end
+ trait :jira_description do
+ description { generate(:jira_description) }
+ end
+
trait :jira_branch do
source_branch { generate(:jira_branch) }
end
diff --git a/spec/factories/project_hooks.rb b/spec/factories/project_hooks.rb
index 88c06b3857a..e0b61526ba0 100644
--- a/spec/factories/project_hooks.rb
+++ b/spec/factories/project_hooks.rb
@@ -25,5 +25,9 @@ FactoryBot.define do
feature_flag_events { true }
releases_events { true }
end
+
+ trait :with_push_branch_filter do
+ push_events_branch_filter { 'my-branch-*' }
+ end
end
end
diff --git a/spec/factories/projects.rb b/spec/factories/projects.rb
index 8a406f95f58..ef1313541f8 100644
--- a/spec/factories/projects.rb
+++ b/spec/factories/projects.rb
@@ -35,6 +35,7 @@ FactoryBot.define do
metrics_dashboard_access_level { ProjectFeature::PRIVATE }
operations_access_level { ProjectFeature::ENABLED }
container_registry_access_level { ProjectFeature::ENABLED }
+ security_and_compliance_access_level { ProjectFeature::PRIVATE }
# we can't assign the delegated `#ci_cd_settings` attributes directly, as the
# `#ci_cd_settings` relation needs to be created first
@@ -70,7 +71,8 @@ FactoryBot.define do
metrics_dashboard_access_level: evaluator.metrics_dashboard_access_level,
operations_access_level: evaluator.operations_access_level,
analytics_access_level: evaluator.analytics_access_level,
- container_registry_access_level: evaluator.container_registry_access_level
+ container_registry_access_level: evaluator.container_registry_access_level,
+ security_and_compliance_access_level: evaluator.security_and_compliance_access_level
}
project.build_project_feature(hash)
@@ -82,7 +84,7 @@ FactoryBot.define do
# user have access to the project. Our specs don't use said service class,
# thus we must manually refresh things here.
unless project.group || project.pending_delete
- project.add_maintainer(project.first_owner)
+ project.add_owner(project.first_owner)
end
project.group&.refresh_members_authorized_projects
@@ -154,6 +156,10 @@ FactoryBot.define do
archived { true }
end
+ trait :hidden do
+ hidden { true }
+ end
+
trait :last_repository_check_failed do
last_repository_check_failed { true }
end
@@ -355,6 +361,9 @@ FactoryBot.define do
trait(:container_registry_enabled) { container_registry_access_level { ProjectFeature::ENABLED } }
trait(:container_registry_disabled) { container_registry_access_level { ProjectFeature::DISABLED } }
trait(:container_registry_private) { container_registry_access_level { ProjectFeature::PRIVATE } }
+ trait(:security_and_compliance_enabled) { security_and_compliance_access_level { ProjectFeature::ENABLED } }
+ trait(:security_and_compliance_disabled) { security_and_compliance_access_level { ProjectFeature::DISABLED } }
+ trait(:security_and_compliance_private) { security_and_compliance_access_level { ProjectFeature::PRIVATE } }
trait :auto_devops do
association :auto_devops, factory: :project_auto_devops
@@ -379,6 +388,10 @@ FactoryBot.define do
service_desk_enabled { true }
end
+ trait :with_error_tracking_setting do
+ error_tracking_setting { association :project_error_tracking_setting }
+ end
+
# Project with empty repository
#
# This is a case when you just created a project
diff --git a/spec/factories/projects/build_artifacts_size_refreshes.rb b/spec/factories/projects/build_artifacts_size_refreshes.rb
new file mode 100644
index 00000000000..b05f5dfab1c
--- /dev/null
+++ b/spec/factories/projects/build_artifacts_size_refreshes.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+FactoryBot.define do
+ factory :project_build_artifacts_size_refresh, class: 'Projects::BuildArtifactsSizeRefresh' do
+ project factory: :project
+
+ trait :created do
+ state { Projects::BuildArtifactsSizeRefresh::STATES[:created] }
+ end
+
+ trait :pending do
+ state { Projects::BuildArtifactsSizeRefresh::STATES[:pending] }
+ refresh_started_at { Time.zone.now }
+ end
+
+ trait :running do
+ state { Projects::BuildArtifactsSizeRefresh::STATES[:running] }
+ refresh_started_at { Time.zone.now }
+ end
+
+ trait :stale do
+ running
+ refresh_started_at { 30.days.ago }
+ updated_at { 30.days.ago }
+ end
+ end
+end
diff --git a/spec/factories/releases.rb b/spec/factories/releases.rb
index 0e79f2e6d3a..52a9341b955 100644
--- a/spec/factories/releases.rb
+++ b/spec/factories/releases.rb
@@ -2,7 +2,9 @@
FactoryBot.define do
factory :release do
- tag { "v1.1.0" }
+ sequence :tag do |n|
+ "v1.#{n}.0"
+ end
sha { 'b83d6e391c22777fca1ed3012fce84f633d7fed0' }
name { tag }
description { "Awesome release" }
diff --git a/spec/factories/sequences.rb b/spec/factories/sequences.rb
index 893865962d8..6b86154aa91 100644
--- a/spec/factories/sequences.rb
+++ b/spec/factories/sequences.rb
@@ -18,6 +18,7 @@ FactoryBot.define do
sequence(:draft_title) { |n| "Draft: #{n}" }
sequence(:wip_title) { |n| "WIP: #{n}" }
sequence(:jira_title) { |n| "[PROJ-#{n}]: fix bug" }
+ sequence(:jira_description) { |n| "This is a description\n here is the description\n Related to: PROJ-#{n}" }
sequence(:jira_branch) { |n| "feature/PROJ-#{n}" }
sequence(:job_name) { |n| "job #{n}" }
sequence(:work_item_type_name) { |n| "bug#{n}" }
diff --git a/spec/factories/usage_data.rb b/spec/factories/usage_data.rb
index 86799af1719..316e0c2b8d6 100644
--- a/spec/factories/usage_data.rb
+++ b/spec/factories/usage_data.rb
@@ -5,8 +5,7 @@ FactoryBot.define do
skip_create # non-model factories (i.e. without #save)
initialize_with do
- projects = create_list(:project, 3)
- projects << create(:project, :repository)
+ projects = create_list(:project, 4, :repository)
group = create(:group)
create(:board, project: projects[0])
create(:jira_integration, project: projects[0])
@@ -19,16 +18,21 @@ FactoryBot.define do
create(:jira_import_state, :finished, project: projects[1], label: jira_label, imported_issues_count: 3)
create(:jira_import_state, :scheduled, project: projects[1], label: jira_label)
create(:prometheus_integration, project: projects[1])
- create(:integration, project: projects[1], type: 'JenkinsService', active: true)
- create(:integration, project: projects[0], type: 'SlackSlashCommandsService', active: true)
- create(:integration, project: projects[1], type: 'SlackService', active: true)
- create(:integration, project: projects[2], type: 'SlackService', active: true)
- create(:integration, project: projects[2], type: 'MattermostService', active: false)
- create(:integration, group: group, project: nil, type: 'MattermostService', active: true)
- mattermost_instance = create(:integration, :instance, type: 'MattermostService', active: true)
- create(:integration, project: projects[1], type: 'MattermostService', active: true, inherit_from_id: mattermost_instance.id)
- create(:integration, group: group, project: nil, type: 'SlackService', active: true, inherit_from_id: mattermost_instance.id)
- create(:integration, project: projects[2], type: 'CustomIssueTrackerService', active: true)
+ create(:jenkins_integration, project: projects[1])
+
+ # slack
+ create(:slack_slash_commands_integration, project: projects[0])
+ create(:integrations_slack, project: projects[1])
+ create(:integrations_slack, project: projects[2])
+
+ # mattermost
+ create(:mattermost_integration, project: projects[2], active: false)
+ create(:mattermost_integration, group: group, project: nil)
+ mattermost_instance = create(:mattermost_integration, :instance)
+ create(:mattermost_integration, project: projects[1], inherit_from_id: mattermost_instance.id)
+ create(:integrations_slack, group: group, project: nil, active: true, inherit_from_id: mattermost_instance.id)
+
+ create(:custom_issue_tracker_integration, project: projects[2], active: true)
create(:project_error_tracking_setting, project: projects[0])
create(:project_error_tracking_setting, project: projects[1], enabled: false)
alert_bot_issues = create_list(:incident, 2, project: projects[0], author: User.alert_bot)
diff --git a/spec/factories/users.rb b/spec/factories/users.rb
index 8764ac90af8..eb89cb0a40a 100644
--- a/spec/factories/users.rb
+++ b/spec/factories/users.rb
@@ -151,7 +151,7 @@ FactoryBot.define do
transient do
extern_uid { '123456' }
- provider { 'ldapmain' }
+ provider { 'twitter' }
end
after(:create) do |user, evaluator|
@@ -166,6 +166,12 @@ FactoryBot.define do
user.identities << create(:identity, identity_attrs)
end
+
+ trait :ldap do
+ transient do
+ provider { 'ldapmain' }
+ end
+ end
end
factory :atlassian_user do
diff --git a/spec/factories/users/saved_replies.rb b/spec/factories/users/saved_replies.rb
new file mode 100644
index 00000000000..a3c450fb1f1
--- /dev/null
+++ b/spec/factories/users/saved_replies.rb
@@ -0,0 +1,10 @@
+# frozen_string_literal: true
+
+FactoryBot.define do
+ factory :saved_reply, class: 'Users::SavedReply' do
+ sequence(:name) { |n| "saved_reply_#{n}" }
+ content { 'Saved Reply Content' }
+
+ user
+ end
+end
diff --git a/spec/fast_spec_helper.rb b/spec/fast_spec_helper.rb
index 1485edcd97d..ce3c9af22f1 100644
--- a/spec/fast_spec_helper.rb
+++ b/spec/fast_spec_helper.rb
@@ -18,6 +18,9 @@ require_relative '../config/settings'
require_relative 'support/rspec'
require 'active_support/all'
+require_relative 'simplecov_env'
+SimpleCovEnv.start!
+
unless ActiveSupport::Dependencies.autoload_paths.frozen?
ActiveSupport::Dependencies.autoload_paths << 'lib'
ActiveSupport::Dependencies.autoload_paths << 'ee/lib'
diff --git a/spec/features/admin/admin_appearance_spec.rb b/spec/features/admin/admin_appearance_spec.rb
index 0785c736cfb..8bf8ef56353 100644
--- a/spec/features/admin/admin_appearance_spec.rb
+++ b/spec/features/admin/admin_appearance_spec.rb
@@ -17,7 +17,7 @@ RSpec.describe 'Admin Appearance' do
fill_in 'appearance_profile_image_guidelines', with: 'Custom profile image guidelines'
click_button 'Update appearance settings'
- expect(current_path).to eq admin_application_settings_appearances_path
+ expect(page).to have_current_path admin_application_settings_appearances_path, ignore_query: true
expect(page).to have_content 'Appearance'
expect(page).to have_field('appearance_title', with: 'MyCompany')
diff --git a/spec/features/admin/admin_broadcast_messages_spec.rb b/spec/features/admin/admin_broadcast_messages_spec.rb
index 476dd4469bc..e40f4c4678c 100644
--- a/spec/features/admin/admin_broadcast_messages_spec.rb
+++ b/spec/features/admin/admin_broadcast_messages_spec.rb
@@ -7,7 +7,12 @@ RSpec.describe 'Admin Broadcast Messages' do
admin = create(:admin)
sign_in(admin)
gitlab_enable_admin_mode_sign_in(admin)
- create(:broadcast_message, :expired, message: 'Migration to new server')
+ create(
+ :broadcast_message,
+ :expired,
+ message: 'Migration to new server',
+ target_access_levels: [Gitlab::Access::DEVELOPER]
+ )
visit admin_broadcast_messages_path
end
@@ -21,10 +26,13 @@ RSpec.describe 'Admin Broadcast Messages' do
fill_in 'broadcast_message_target_path', with: '*/user_onboarded'
fill_in 'broadcast_message_font', with: '#b94a48'
select Date.today.next_year.year, from: 'broadcast_message_ends_at_1i'
+ check 'Guest'
+ check 'Owner'
click_button 'Add broadcast message'
- expect(current_path).to eq admin_broadcast_messages_path
+ expect(page).to have_current_path admin_broadcast_messages_path, ignore_query: true
expect(page).to have_content 'Application update from 4:00 CST to 5:00 CST'
+ expect(page).to have_content 'Guest, Owner'
expect(page).to have_content '*/user_onboarded'
expect(page).to have_selector 'strong', text: '4:00 CST to 5:00 CST'
expect(page).to have_selector %(div[style="background-color: #f2dede; color: #b94a48"])
@@ -35,10 +43,14 @@ RSpec.describe 'Admin Broadcast Messages' do
fill_in 'broadcast_message_target_path', with: '*/user_onboarded'
select 'Notification', from: 'broadcast_message_broadcast_type'
select Date.today.next_year.year, from: 'broadcast_message_ends_at_1i'
+ check 'Reporter'
+ check 'Developer'
+ check 'Maintainer'
click_button 'Add broadcast message'
- expect(current_path).to eq admin_broadcast_messages_path
+ expect(page).to have_current_path admin_broadcast_messages_path, ignore_query: true
expect(page).to have_content 'Application update from 4:00 CST to 5:00 CST'
+ expect(page).to have_content 'Reporter, Developer, Maintainer'
expect(page).to have_content '*/user_onboarded'
expect(page).to have_content 'Notification'
expect(page).to have_selector 'strong', text: '4:00 CST to 5:00 CST'
@@ -47,16 +59,21 @@ RSpec.describe 'Admin Broadcast Messages' do
it 'edit an existing broadcast message' do
click_link 'Edit'
fill_in 'broadcast_message_message', with: 'Application update RIGHT NOW'
+ check 'Reporter'
click_button 'Update broadcast message'
- expect(current_path).to eq admin_broadcast_messages_path
+ expect(page).to have_current_path admin_broadcast_messages_path, ignore_query: true
expect(page).to have_content 'Application update RIGHT NOW'
+
+ page.within('.table-responsive') do
+ expect(page).to have_content 'Reporter, Developer'
+ end
end
it 'remove an existing broadcast message' do
click_link 'Remove'
- expect(current_path).to eq admin_broadcast_messages_path
+ expect(page).to have_current_path admin_broadcast_messages_path, ignore_query: true
expect(page).not_to have_content 'Migration to new server'
end
diff --git a/spec/features/admin/admin_deploy_keys_spec.rb b/spec/features/admin/admin_deploy_keys_spec.rb
index 88b8fcd8d5e..56b8c7fce14 100644
--- a/spec/features/admin/admin_deploy_keys_spec.rb
+++ b/spec/features/admin/admin_deploy_keys_spec.rb
@@ -47,7 +47,7 @@ RSpec.describe 'admin deploy keys', :js do
fill_in 'deploy_key_key', with: new_ssh_key
click_button 'Create'
- expect(current_path).to eq admin_deploy_keys_path
+ expect(page).to have_current_path admin_deploy_keys_path, ignore_query: true
page.within(find('[data-testid="deploy-keys-list"]', match: :first)) do
expect(page).to have_content('laptop')
@@ -67,7 +67,7 @@ RSpec.describe 'admin deploy keys', :js do
fill_in 'deploy_key_title', with: 'new-title'
click_button 'Save changes'
- expect(current_path).to eq admin_deploy_keys_path
+ expect(page).to have_current_path admin_deploy_keys_path, ignore_query: true
page.within(find('[data-testid="deploy-keys-list"]', match: :first)) do
expect(page).to have_content('new-title')
@@ -87,7 +87,7 @@ RSpec.describe 'admin deploy keys', :js do
end
end
- expect(current_path).to eq admin_deploy_keys_path
+ expect(page).to have_current_path admin_deploy_keys_path, ignore_query: true
page.within(find('[data-testid="deploy-keys-list"]', match: :first)) do
expect(page).not_to have_content(deploy_key.title)
end
diff --git a/spec/features/admin/admin_groups_spec.rb b/spec/features/admin/admin_groups_spec.rb
index a0a41061d64..3b3289a8487 100644
--- a/spec/features/admin/admin_groups_spec.rb
+++ b/spec/features/admin/admin_groups_spec.rb
@@ -58,7 +58,7 @@ RSpec.describe 'Admin Groups' do
fill_in 'group_admin_note_attributes_note', with: group_admin_note
click_button "Create group"
- expect(current_path).to eq admin_group_path(Group.find_by(path: path_component))
+ expect(page).to have_current_path admin_group_path(Group.find_by(path: path_component)), ignore_query: true
content = page.find('#content-body')
h3_texts = content.all('h3').collect(&:text).join("\n")
expect(h3_texts).to match group_name
diff --git a/spec/features/admin/admin_hook_logs_spec.rb b/spec/features/admin/admin_hook_logs_spec.rb
index 837cab49bd4..fd51fd71fea 100644
--- a/spec/features/admin/admin_hook_logs_spec.rb
+++ b/spec/features/admin/admin_hook_logs_spec.rb
@@ -39,6 +39,6 @@ RSpec.describe 'Admin::HookLogs' do
click_link 'View details'
click_link 'Resend Request'
- expect(current_path).to eq(edit_admin_hook_path(system_hook))
+ expect(page).to have_current_path(edit_admin_hook_path(system_hook), ignore_query: true)
end
end
diff --git a/spec/features/admin/admin_hooks_spec.rb b/spec/features/admin/admin_hooks_spec.rb
index 32e4d18227e..388ab02d8e8 100644
--- a/spec/features/admin/admin_hooks_spec.rb
+++ b/spec/features/admin/admin_hooks_spec.rb
@@ -18,7 +18,7 @@ RSpec.describe 'Admin::Hooks' do
click_on 'System Hooks', match: :first
end
- expect(current_path).to eq(admin_hooks_path)
+ expect(page).to have_current_path(admin_hooks_path, ignore_query: true)
end
it 'has hooks list' do
@@ -49,7 +49,7 @@ RSpec.describe 'Admin::Hooks' do
expect { click_button 'Add system hook' }.to change(SystemHook, :count).by(1)
expect(page).to have_content 'SSL Verification: enabled'
- expect(current_path).to eq(admin_hooks_path)
+ expect(page).to have_current_path(admin_hooks_path, ignore_query: true)
expect(page).to have_content(url)
end
end
@@ -70,7 +70,7 @@ RSpec.describe 'Admin::Hooks' do
click_button 'Save changes'
expect(page).to have_content 'SSL Verification: enabled'
- expect(current_path).to eq(admin_hooks_path)
+ expect(page).to have_current_path(admin_hooks_path, ignore_query: true)
expect(page).to have_content(new_url)
end
end
@@ -111,7 +111,7 @@ RSpec.describe 'Admin::Hooks' do
click_link 'Push events'
end
- it { expect(current_path).to eq(admin_hooks_path) }
+ it { expect(page).to have_current_path(admin_hooks_path, ignore_query: true) }
end
context 'Merge request hook' do
@@ -126,7 +126,7 @@ RSpec.describe 'Admin::Hooks' do
check 'Merge request events'
expect { click_button 'Add system hook' }.to change(SystemHook, :count).by(1)
- expect(current_path).to eq(admin_hooks_path)
+ expect(page).to have_current_path(admin_hooks_path, ignore_query: true)
expect(page).to have_content(url)
end
end
diff --git a/spec/features/admin/admin_mode/login_spec.rb b/spec/features/admin/admin_mode/login_spec.rb
index c8ee6c14499..659f66a67d2 100644
--- a/spec/features/admin/admin_mode/login_spec.rb
+++ b/spec/features/admin/admin_mode/login_spec.rb
@@ -30,7 +30,7 @@ RSpec.describe 'Admin Mode Login' do
enter_code(repeated_otp)
- expect(current_path).to eq admin_session_path
+ expect(page).to have_current_path admin_session_path, ignore_query: true
expect(page).to have_content('Invalid two-factor code')
end
@@ -51,7 +51,7 @@ RSpec.describe 'Admin Mode Login' do
travel_to(30.seconds.from_now) do
enter_code(user.current_otp)
- expect(current_path).to eq admin_root_path
+ expect(page).to have_current_path admin_root_path, ignore_query: true
expect(page).to have_content('Admin mode enabled')
end
end
@@ -74,7 +74,7 @@ RSpec.describe 'Admin Mode Login' do
enter_code(user.current_otp)
- expect(current_path).to eq admin_root_path
+ expect(page).to have_current_path admin_root_path, ignore_query: true
expect(page).to have_content('Admin mode enabled')
end
end
@@ -93,7 +93,7 @@ RSpec.describe 'Admin Mode Login' do
it 'allows login' do
enter_code(codes.sample)
- expect(current_path).to eq admin_root_path
+ expect(page).to have_current_path admin_root_path, ignore_query: true
expect(page).to have_content('Admin mode enabled')
end
@@ -146,7 +146,7 @@ RSpec.describe 'Admin Mode Login' do
enable_admin_mode_using_saml!
expect(page).not_to have_content('Two-Factor Authentication')
- expect(current_path).to eq admin_root_path
+ expect(page).to have_current_path admin_root_path, ignore_query: true
expect(page).to have_content('Admin mode enabled')
end
end
@@ -166,7 +166,7 @@ RSpec.describe 'Admin Mode Login' do
travel_to(30.seconds.from_now) do
enter_code(user.current_otp)
- expect(current_path).to eq admin_root_path
+ expect(page).to have_current_path admin_root_path, ignore_query: true
expect(page).to have_content('Admin mode enabled')
end
end
@@ -218,7 +218,7 @@ RSpec.describe 'Admin Mode Login' do
travel_to(30.seconds.from_now) do
enter_code(user.current_otp)
- expect(current_path).to eq admin_root_path
+ expect(page).to have_current_path admin_root_path, ignore_query: true
expect(page).to have_content('Admin mode enabled')
end
end
diff --git a/spec/features/admin/admin_mode/logout_spec.rb b/spec/features/admin/admin_mode/logout_spec.rb
index f2f6e26fbee..3ca66ef0d6a 100644
--- a/spec/features/admin/admin_mode/logout_spec.rb
+++ b/spec/features/admin/admin_mode/logout_spec.rb
@@ -20,7 +20,7 @@ RSpec.describe 'Admin Mode Logout', :js do
it 'disable removes admin mode and redirects to root page' do
gitlab_disable_admin_mode
- expect(current_path).to eq root_path
+ expect(page).to have_current_path root_path, ignore_query: true
open_top_nav
@@ -43,7 +43,7 @@ RSpec.describe 'Admin Mode Logout', :js do
it 'disable removes admin mode and redirects to root page' do
gitlab_disable_admin_mode
- expect(current_path).to eq root_path
+ expect(page).to have_current_path root_path, ignore_query: true
open_top_nav
diff --git a/spec/features/admin/admin_projects_spec.rb b/spec/features/admin/admin_projects_spec.rb
index 8938bab60d7..b0737377de0 100644
--- a/spec/features/admin/admin_projects_spec.rb
+++ b/spec/features/admin/admin_projects_spec.rb
@@ -5,7 +5,6 @@ require 'spec_helper'
RSpec.describe "Admin::Projects" do
include Spec::Support::Helpers::Features::MembersHelpers
include Spec::Support::Helpers::Features::InviteMembersModalHelper
- include Select2Helper
include Spec::Support::Helpers::ModalHelpers
let(:user) { create :user }
@@ -26,7 +25,7 @@ RSpec.describe "Admin::Projects" do
end
it "is ok" do
- expect(current_path).to eq(admin_projects_path)
+ expect(page).to have_current_path(admin_projects_path, ignore_query: true)
end
it 'renders projects list without archived project' do
@@ -63,7 +62,7 @@ RSpec.describe "Admin::Projects" do
end
it "has project info" do
- expect(current_path).to eq admin_project_path(project)
+ expect(page).to have_current_path admin_project_path(project), ignore_query: true
expect(page).to have_content(project.path)
expect(page).to have_content(project.name)
expect(page).to have_content(project.full_name)
@@ -117,18 +116,6 @@ RSpec.describe "Admin::Projects" do
expect(find_member_row(current_user)).to have_content('Developer')
end
-
- context 'with the invite_members_group_modal feature flag disabled' do
- it 'adds admin to the project as developer' do
- stub_feature_flags(invite_members_group_modal: false)
-
- visit project_project_members_path(project)
-
- add_member_using_form(current_user.id, role: 'Developer')
-
- expect(find_member_row(current_user)).to have_content('Developer')
- end
- end
end
describe 'admin removes themselves from the project', :js do
@@ -150,22 +137,7 @@ RSpec.describe "Admin::Projects" do
click_button('Leave')
end
- expect(current_path).to match dashboard_projects_path
- end
- end
-
- # temporary method for the form until the :invite_members_group_modal feature flag is
- # enabled: https://gitlab.com/gitlab-org/gitlab/-/issues/247208
- def add_member_using_form(id, role: 'Developer')
- page.within '.invite-users-form' do
- select2(id, from: '#user_ids', multiple: true)
-
- fill_in 'expires_at', with: 5.days.from_now.to_date
- find_field('expires_at').native.send_keys :enter
-
- select(role, from: "access_level")
-
- click_on 'Invite'
+ expect(page).to have_current_path(dashboard_projects_path, ignore_query: true, url: false)
end
end
end
diff --git a/spec/features/admin/admin_runners_spec.rb b/spec/features/admin/admin_runners_spec.rb
index 25ff4022454..3f0c7e64a1f 100644
--- a/spec/features/admin/admin_runners_spec.rb
+++ b/spec/features/admin/admin_runners_spec.rb
@@ -11,6 +11,8 @@ RSpec.describe "Admin Runners" do
admin = create(:admin)
sign_in(admin)
gitlab_enable_admin_mode_sign_in(admin)
+
+ wait_for_requests
end
describe "Runners page", :js do
@@ -21,7 +23,7 @@ RSpec.describe "Admin Runners" do
context "when there are runners" do
it 'has all necessary texts' do
- create(:ci_runner, :instance, created_at: 1.year.ago, contacted_at: Time.now)
+ create(:ci_runner, :instance, created_at: 1.year.ago, contacted_at: Time.zone.now)
create(:ci_runner, :instance, created_at: 1.year.ago, contacted_at: 1.week.ago)
create(:ci_runner, :instance, created_at: 1.year.ago, contacted_at: 1.year.ago)
@@ -156,9 +158,9 @@ RSpec.describe "Admin Runners" do
let!(:never_contacted) { create(:ci_runner, :instance, description: 'runner-never-contacted', contacted_at: nil) }
before do
- create(:ci_runner, :instance, description: 'runner-1', contacted_at: Time.now)
- create(:ci_runner, :instance, description: 'runner-2', contacted_at: Time.now)
- create(:ci_runner, :instance, description: 'runner-paused', active: false, contacted_at: Time.now)
+ create(:ci_runner, :instance, description: 'runner-1', contacted_at: Time.zone.now)
+ create(:ci_runner, :instance, description: 'runner-2', contacted_at: Time.zone.now)
+ create(:ci_runner, :instance, description: 'runner-paused', active: false, contacted_at: Time.zone.now)
visit admin_runners_path
end
diff --git a/spec/features/admin/admin_sees_background_migrations_spec.rb b/spec/features/admin/admin_sees_background_migrations_spec.rb
index a3d0c7bdd4d..d05a09a79ef 100644
--- a/spec/features/admin/admin_sees_background_migrations_spec.rb
+++ b/spec/features/admin/admin_sees_background_migrations_spec.rb
@@ -56,7 +56,13 @@ RSpec.describe "Admin > Admin sees background migrations" do
context 'when there are failed migrations' do
before do
allow_next_instance_of(Gitlab::BackgroundMigration::BatchingStrategies::PrimaryKeyBatchingStrategy) do |batch_class|
- allow(batch_class).to receive(:next_batch).with(anything, anything, batch_min_value: 6, batch_size: 5).and_return([6, 10])
+ allow(batch_class).to receive(:next_batch).with(
+ anything,
+ anything,
+ batch_min_value: 6,
+ batch_size: 5,
+ job_arguments: failed_migration.job_arguments
+ ).and_return([6, 10])
end
end
diff --git a/spec/features/admin/admin_settings_spec.rb b/spec/features/admin/admin_settings_spec.rb
index ca452264c02..df93bd773a6 100644
--- a/spec/features/admin/admin_settings_spec.rb
+++ b/spec/features/admin/admin_settings_spec.rb
@@ -373,7 +373,8 @@ RSpec.describe 'Admin updates settings' do
{
container_registry_delete_tags_service_timeout: 'Container Registry delete tags service execution timeout',
container_registry_expiration_policies_worker_capacity: 'Cleanup policy maximum workers running concurrently',
- container_registry_cleanup_tags_service_max_list_size: 'Cleanup policy maximum number of tags to be deleted'
+ container_registry_cleanup_tags_service_max_list_size: 'Cleanup policy maximum number of tags to be deleted',
+ container_registry_expiration_policies_caching: 'Enable container expiration caching'
}
end
@@ -393,26 +394,16 @@ RSpec.describe 'Admin updates settings' do
%i[container_registry_delete_tags_service_timeout container_registry_expiration_policies_worker_capacity container_registry_cleanup_tags_service_max_list_size].each do |setting|
context "for container registry setting #{setting}" do
- context 'with feature flag enabled' do
- context 'with client supporting tag delete' do
- it 'changes the setting' do
- visit ci_cd_admin_application_settings_path
-
- page.within('.as-registry') do
- fill_in "application_setting_#{setting}", with: 400
- click_button 'Save changes'
- end
-
- expect(current_settings.public_send(setting)).to eq(400)
- expect(page).to have_content "Application settings saved successfully"
- end
- end
-
- context 'with client not supporting tag delete' do
- let(:client_support) { false }
+ it 'changes the setting' do
+ visit ci_cd_admin_application_settings_path
- it_behaves_like 'not having container registry setting', setting
+ page.within('.as-registry') do
+ fill_in "application_setting_#{setting}", with: 400
+ click_button 'Save changes'
end
+
+ expect(current_settings.public_send(setting)).to eq(400)
+ expect(page).to have_content "Application settings saved successfully"
end
context 'with feature flag disabled' do
@@ -422,6 +413,28 @@ RSpec.describe 'Admin updates settings' do
end
end
end
+
+ context 'for container registry setting container_registry_expiration_policies_caching' do
+ it 'updates container_registry_expiration_policies_caching' do
+ old_value = current_settings.container_registry_expiration_policies_caching
+
+ visit ci_cd_admin_application_settings_path
+
+ page.within('.as-registry') do
+ find('#application_setting_container_registry_expiration_policies_caching.form-check-input').click
+ click_button 'Save changes'
+ end
+
+ expect(current_settings.container_registry_expiration_policies_caching).to eq(!old_value)
+ expect(page).to have_content "Application settings saved successfully"
+ end
+
+ context 'with feature flag disabled' do
+ let(:feature_flag_enabled) { false }
+
+ it_behaves_like 'not having container registry setting', :container_registry_expiration_policies_caching
+ end
+ end
end
end
@@ -694,6 +707,20 @@ RSpec.describe 'Admin updates settings' do
include_examples 'regular throttle rate limit settings'
end
+
+ it 'changes search rate limits' do
+ visit network_admin_application_settings_path
+
+ page.within('.as-search-limits') do
+ fill_in 'Maximum number of requests per minute for an authenticated user', with: 98
+ fill_in 'Maximum number of requests per minute for an unauthenticated IP address', with: 76
+ click_button 'Save changes'
+ end
+
+ expect(page).to have_content "Application settings saved successfully"
+ expect(current_settings.search_rate_limit).to eq(98)
+ expect(current_settings.search_rate_limit_unauthenticated).to eq(76)
+ end
end
context 'Preferences page' do
@@ -838,7 +865,7 @@ RSpec.describe 'Admin updates settings' do
end
it 'loads admin settings page without redirect for reauthentication' do
- expect(current_path).to eq general_admin_application_settings_path
+ expect(page).to have_current_path general_admin_application_settings_path, ignore_query: true
end
end
diff --git a/spec/features/admin/admin_users_spec.rb b/spec/features/admin/admin_users_spec.rb
index 95e3f5c70e5..f4b7fa45e4f 100644
--- a/spec/features/admin/admin_users_spec.rb
+++ b/spec/features/admin/admin_users_spec.rb
@@ -54,7 +54,7 @@ RSpec.describe "Admin::Users" do
visit admin_users_path(tab: 'cohorts')
- expect(page).to have_content("#{Time.now.strftime('%b %Y')} 3 0")
+ expect(page).to have_content("#{Time.zone.now.strftime('%b %Y')} 3 0")
end
end
diff --git a/spec/features/admin/admin_uses_repository_checks_spec.rb b/spec/features/admin/admin_uses_repository_checks_spec.rb
index c13313609b5..4e6aae7c46f 100644
--- a/spec/features/admin/admin_uses_repository_checks_spec.rb
+++ b/spec/features/admin/admin_uses_repository_checks_spec.rb
@@ -43,7 +43,7 @@ RSpec.describe 'Admin uses repository checks', :request_store do
project = create(:project)
project.update_columns(
last_repository_check_failed: true,
- last_repository_check_at: Time.now
+ last_repository_check_at: Time.zone.now
)
visit_admin_project_page(project)
diff --git a/spec/features/admin/clusters/eks_spec.rb b/spec/features/admin/clusters/eks_spec.rb
index bb2678de2ae..71d2bba73b1 100644
--- a/spec/features/admin/clusters/eks_spec.rb
+++ b/spec/features/admin/clusters/eks_spec.rb
@@ -8,13 +8,15 @@ RSpec.describe 'Instance-level AWS EKS Cluster', :js do
before do
sign_in(user)
gitlab_enable_admin_mode_sign_in(user)
+ stub_application_setting(eks_integration_enabled: true)
end
context 'when user does not have a cluster and visits group clusters page' do
before do
visit admin_clusters_path
- click_link 'Connect with a certificate'
+ click_button 'Actions'
+ click_link 'Create a new cluster'
end
context 'when user creates a cluster on AWS EKS' do
@@ -23,7 +25,7 @@ RSpec.describe 'Instance-level AWS EKS Cluster', :js do
end
it 'user sees a form to create an EKS cluster' do
- expect(page).to have_content('Create new cluster on EKS')
+ expect(page).to have_content('Authenticate with Amazon Web Services')
end
end
end
diff --git a/spec/features/admin/users/user_spec.rb b/spec/features/admin/users/user_spec.rb
index 0d053329627..7e8dee9cc0b 100644
--- a/spec/features/admin/users/user_spec.rb
+++ b/spec/features/admin/users/user_spec.rb
@@ -220,13 +220,13 @@ RSpec.describe 'Admin::Users::User' do
context 'a user with an expired password' do
before do
- another_user.update!(password_expires_at: Time.now - 5.minutes)
+ another_user.update!(password_expires_at: Time.zone.now - 5.minutes)
end
it 'does not redirect to password change page' do
subject
- expect(current_path).to eq('/')
+ expect(page).to have_current_path('/')
end
end
end
@@ -250,18 +250,18 @@ RSpec.describe 'Admin::Users::User' do
it 'is redirected back to the impersonated users page in the admin after stopping' do
subject
- expect(current_path).to eq("/admin/users/#{another_user.username}")
+ expect(page).to have_current_path("/admin/users/#{another_user.username}", ignore_query: true)
end
context 'a user with an expired password' do
before do
- another_user.update!(password_expires_at: Time.now - 5.minutes)
+ another_user.update!(password_expires_at: Time.zone.now - 5.minutes)
end
it 'is redirected back to the impersonated users page in the admin after stopping' do
subject
- expect(current_path).to eq("/admin/users/#{another_user.username}")
+ expect(page).to have_current_path("/admin/users/#{another_user.username}", ignore_query: true)
end
end
end
diff --git a/spec/features/admin/users/users_spec.rb b/spec/features/admin/users/users_spec.rb
index 5b0b6e085c9..4d9a7f31911 100644
--- a/spec/features/admin/users/users_spec.rb
+++ b/spec/features/admin/users/users_spec.rb
@@ -21,7 +21,7 @@ RSpec.describe 'Admin::Users' do
end
it "is ok" do
- expect(current_path).to eq(admin_users_path)
+ expect(page).to have_current_path(admin_users_path, ignore_query: true)
end
it "has users list" do
@@ -132,7 +132,7 @@ RSpec.describe 'Admin::Users' do
end
it 'searches with respect of sorting' do
- visit admin_users_path(sort: 'Name')
+ visit admin_users_path(sort: 'name_asc')
fill_in :search_query, with: 'Foo'
click_button('Search users')
@@ -338,6 +338,8 @@ RSpec.describe 'Admin::Users' do
end
it 'displays count of the users authorized groups' do
+ visit admin_users_path
+
wait_for_requests
expect(page.find("[data-testid='user-group-count-#{current_user.id}']").text).to eq("2")
@@ -574,7 +576,7 @@ RSpec.describe 'Admin::Users' do
user.reload
expect(user.name).to eq('Big Bang')
expect(user.admin?).to be_truthy
- expect(user.password_expires_at).to be <= Time.now
+ expect(user.password_expires_at).to be <= Time.zone.now
end
end
@@ -602,8 +604,8 @@ RSpec.describe 'Admin::Users' do
def sort_by(option)
page.within('.filtered-search-block') do
- find('.dropdown-menu-toggle').click
- click_link option
+ find('.gl-new-dropdown').click
+ find('.gl-new-dropdown-item', text: option).click
end
end
end
diff --git a/spec/features/boards/board_filters_spec.rb b/spec/features/boards/board_filters_spec.rb
index e37bf515088..537b677cbd0 100644
--- a/spec/features/boards/board_filters_spec.rb
+++ b/spec/features/boards/board_filters_spec.rb
@@ -22,8 +22,6 @@ RSpec.describe 'Issue board filters', :js do
let(:filter_submit) { find('.gl-search-box-by-click-search-button') }
before do
- stub_feature_flags(issue_boards_filtered_search: true)
-
project.add_maintainer(user)
sign_in(user)
diff --git a/spec/features/boards/boards_spec.rb b/spec/features/boards/boards_spec.rb
index 2ca4ff94911..5dd627f3b76 100644
--- a/spec/features/boards/boards_spec.rb
+++ b/spec/features/boards/boards_spec.rb
@@ -13,12 +13,17 @@ RSpec.describe 'Project issue boards', :js do
let_it_be(:user) { create(:user) }
let_it_be(:user2) { create(:user) }
+ let(:filtered_search) { find('[data-testid="issue-board-filtered-search"]') }
+ let(:filter_input) { find('.gl-filtered-search-term-input') }
+ let(:filter_submit) { find('.gl-search-box-by-click-search-button') }
+
context 'signed in user' do
before do
project.add_maintainer(user)
project.add_maintainer(user2)
sign_in(user)
+ stub_feature_flags(gl_avatar_for_all_user_avatars: false)
set_cookie('sidebar_collapsed', 'true')
end
@@ -90,8 +95,7 @@ RSpec.describe 'Project issue boards', :js do
end
it 'search closed list' do
- find('.filtered-search').set(issue8.title)
- find('.filtered-search').native.send_keys(:enter)
+ set_filter_and_search_by_token_value(issue8.title)
wait_for_requests
@@ -101,8 +105,7 @@ RSpec.describe 'Project issue boards', :js do
end
it 'search list' do
- find('.filtered-search').set(issue5.title)
- find('.filtered-search').native.send_keys(:enter)
+ set_filter_and_search_by_token_value(issue5.title)
wait_for_requests
@@ -111,26 +114,6 @@ RSpec.describe 'Project issue boards', :js do
expect(find('.board:nth-child(4)')).to have_selector('.board-card', count: 0)
end
- context 'search list negation queries' do
- before do
- visit_project_board_path_without_query_limit(project, board)
- end
-
- it 'does not have the != option' do
- find('.filtered-search').set('label:')
-
- wait_for_requests
- within('#js-dropdown-operator') do
- tokens = all(:css, 'li.filter-dropdown-item')
- expect(tokens.count).to eq(2)
- button = tokens[0].find('button')
- expect(button).to have_content('=')
- button = tokens[1].find('button')
- expect(button).to have_content('!=')
- end
- end
- end
-
it 'allows user to delete board' do
remove_list
@@ -309,8 +292,8 @@ RSpec.describe 'Project issue boards', :js do
context 'filtering' do
it 'filters by author' do
set_filter("author", user2.username)
- click_filter_link(user2.username)
- submit_filter
+ click_on user2.username
+ filter_submit.click
wait_for_requests
wait_for_board_cards(2, 1)
@@ -319,8 +302,8 @@ RSpec.describe 'Project issue boards', :js do
it 'filters by assignee' do
set_filter("assignee", user.username)
- click_filter_link(user.username)
- submit_filter
+ click_on user.username
+ filter_submit.click
wait_for_requests
@@ -330,8 +313,8 @@ RSpec.describe 'Project issue boards', :js do
it 'filters by milestone' do
set_filter("milestone", "\"#{milestone.title}")
- click_filter_link(milestone.title)
- submit_filter
+ click_on milestone.title
+ filter_submit.click
wait_for_requests
wait_for_board_cards(2, 1)
@@ -341,8 +324,8 @@ RSpec.describe 'Project issue boards', :js do
it 'filters by label' do
set_filter("label", testing.title)
- click_filter_link(testing.title)
- submit_filter
+ click_on testing.title
+ filter_submit.click
wait_for_requests
wait_for_board_cards(2, 1)
@@ -351,8 +334,10 @@ RSpec.describe 'Project issue boards', :js do
it 'filters by label with encoded character' do
set_filter("label", a_plus.title)
- click_filter_link(a_plus.title)
- submit_filter
+ # This one is a char encoding issue like the & issue
+ click_on a_plus.title
+ filter_submit.click
+ wait_for_requests
wait_for_board_cards(1, 1)
wait_for_empty_boards((2..4))
@@ -360,8 +345,8 @@ RSpec.describe 'Project issue boards', :js do
it 'filters by label with space after reload', :quarantine do
set_filter("label", "\"#{accepting.title}")
- click_filter_link(accepting.title)
- submit_filter
+ click_on accepting.title
+ filter_submit.click
# Test after reload
page.evaluate_script 'window.location.reload()'
@@ -384,13 +369,13 @@ RSpec.describe 'Project issue boards', :js do
it 'removes filtered labels' do
inspect_requests(inject_headers: { 'X-GITLAB-DISABLE-SQL-QUERY-LIMIT' => 'https://gitlab.com/gitlab-org/gitlab/-/issues/323426' }) do
set_filter("label", testing.title)
- click_filter_link(testing.title)
- submit_filter
+ click_on testing.title
+ filter_submit.click
wait_for_board_cards(2, 1)
- find('.clear-search').click
- submit_filter
+ find('[data-testid="filtered-search-clear-button"]').click
+ filter_submit.click
end
wait_for_board_cards(2, 8)
@@ -400,9 +385,9 @@ RSpec.describe 'Project issue boards', :js do
create_list(:labeled_issue, 30, project: project, labels: [planning, testing])
set_filter("label", testing.title)
- click_filter_link(testing.title)
+ click_on testing.title
inspect_requests(inject_headers: { 'X-GITLAB-DISABLE-SQL-QUERY-LIMIT' => 'https://gitlab.com/gitlab-org/gitlab/-/issues/323426' }) do
- submit_filter
+ filter_submit.click
end
wait_for_requests
@@ -442,10 +427,10 @@ RSpec.describe 'Project issue boards', :js do
it 'filters by multiple labels', :quarantine do
set_filter("label", testing.title)
- click_filter_link(testing.title)
+ click_on testing.title
set_filter("label", bug.title)
- click_filter_link(bug.title)
+ click_on bug.title
submit_filter
@@ -463,7 +448,7 @@ RSpec.describe 'Project issue boards', :js do
wait_for_requests
end
- page.within('.tokens-container') do
+ page.within('.gl-filtered-search-token') do
expect(page).to have_content(bug.title)
end
@@ -561,19 +546,26 @@ RSpec.describe 'Project issue boards', :js do
end
end
+ def set_filter_and_search_by_token_value(value)
+ filter_input.click
+ filter_input.set(value)
+ filter_submit.click
+ end
+
def set_filter(type, text)
- find('.filtered-search').native.send_keys("#{type}:=#{text}")
+ filter_input.click
+ filter_input.native.send_keys("#{type}:=#{text}")
end
def submit_filter
- find('.filtered-search').native.send_keys(:enter)
+ filter_input.native.send_keys(:enter)
end
def click_filter_link(link_text)
- page.within('.filtered-search-box') do
+ page.within(filtered_search) do
expect(page).to have_button(link_text)
- click_button(link_text)
+ click_on link_text
end
end
diff --git a/spec/features/callouts/registration_enabled_spec.rb b/spec/features/callouts/registration_enabled_spec.rb
index 4055965273f..79e99712183 100644
--- a/spec/features/callouts/registration_enabled_spec.rb
+++ b/spec/features/callouts/registration_enabled_spec.rb
@@ -5,6 +5,8 @@ require 'spec_helper'
RSpec.describe 'Registration enabled callout' do
let_it_be(:admin) { create(:admin) }
let_it_be(:non_admin) { create(:user) }
+ let_it_be(:project) { create(:project) }
+ let_it_be(:callout_title) { _('Anyone can register for an account.') }
context 'when "Sign-up enabled" setting is `true`' do
before do
@@ -14,23 +16,42 @@ RSpec.describe 'Registration enabled callout' do
context 'when an admin is logged in' do
before do
sign_in(admin)
+ end
+
+ it 'displays callout on admin and dashboard pages and root page' do
+ visit root_path
+
+ expect(page).to have_content callout_title
+ expect(page).to have_link _('Turn off'), href: general_admin_application_settings_path(anchor: 'js-signup-settings')
+
visit root_dashboard_path
+
+ expect(page).to have_content callout_title
+
+ visit admin_root_path
+
+ expect(page).to have_content callout_title
end
- it 'displays callout' do
- expect(page).to have_content 'Open registration is enabled on your instance.'
- expect(page).to have_link 'View setting', href: general_admin_application_settings_path(anchor: 'js-signup-settings')
+ it 'does not display callout on pages other than root, admin, or dashboard' do
+ visit project_issues_path(project)
+
+ expect(page).not_to have_content callout_title
end
context 'when callout is dismissed', :js do
before do
+ visit admin_root_path
+
find('[data-testid="close-registration-enabled-callout"]').click
+ wait_for_requests
+
visit root_dashboard_path
end
it 'does not display callout' do
- expect(page).not_to have_content 'Open registration is enabled on your instance.'
+ expect(page).not_to have_content callout_title
end
end
end
@@ -42,7 +63,7 @@ RSpec.describe 'Registration enabled callout' do
end
it 'does not display callout' do
- expect(page).not_to have_content 'Open registration is enabled on your instance.'
+ expect(page).not_to have_content callout_title
end
end
end
diff --git a/spec/features/clusters/cluster_detail_page_spec.rb b/spec/features/clusters/cluster_detail_page_spec.rb
index 06e3e00db7d..09e042b00cc 100644
--- a/spec/features/clusters/cluster_detail_page_spec.rb
+++ b/spec/features/clusters/cluster_detail_page_spec.rb
@@ -36,6 +36,20 @@ RSpec.describe 'Clusterable > Show page' do
expect(page).not_to have_selector('[data-testid="cluster-environments-tab"]')
end
+
+ context 'content-security policy' do
+ it 'has AWS domains in the CSP' do
+ visit cluster_path
+
+ expect(response_headers['Content-Security-Policy']).to include(::Clusters::ClustersController::AWS_CSP_DOMAINS.join(' '))
+ end
+
+ it 'keeps existing connect-src in the CSP' do
+ visit cluster_path
+
+ expect(response_headers['Content-Security-Policy']).to include("connect-src #{Gitlab::ContentSecurityPolicy::Directives.connect_src}")
+ end
+ end
end
shared_examples 'editing a GCP cluster' do
diff --git a/spec/features/commits_spec.rb b/spec/features/commits_spec.rb
index e600a99e3b6..db841ffc627 100644
--- a/spec/features/commits_spec.rb
+++ b/spec/features/commits_spec.rb
@@ -30,23 +30,7 @@ RSpec.describe 'Commits' do
project.add_reporter(user)
end
- describe 'Commit builds with jobs_tab_vue feature flag off' do
- before do
- stub_feature_flags(jobs_tab_vue: false)
- visit builds_project_pipeline_path(project, pipeline)
- end
-
- it { expect(page).to have_content pipeline.sha[0..7] }
-
- it 'contains generic commit status build' do
- page.within('.table-holder') do
- expect(page).to have_content "##{status.id}" # build id
- expect(page).to have_content 'generic' # build name
- end
- end
- end
-
- describe 'Commit builds with jobs_tab_vue feature flag on', :js do
+ describe 'Commit builds', :js do
before do
visit builds_project_pipeline_path(project, pipeline)
@@ -107,20 +91,7 @@ RSpec.describe 'Commits' do
end
end
- context 'Download artifacts with jobs_tab_vue feature flag off' do
- before do
- stub_feature_flags(jobs_tab_vue: false)
- create(:ci_job_artifact, :archive, file: artifacts_file, job: build)
- end
-
- it do
- visit pipeline_path(pipeline)
- click_on 'Download artifacts'
- expect(page.response_headers['Content-Type']).to eq(artifacts_file.content_type)
- end
- end
-
- context 'Download artifacts with jobs_tab_vue feature flag on', :js do
+ context 'Download artifacts', :js do
before do
create(:ci_job_artifact, :archive, file: artifacts_file, job: build)
end
@@ -149,28 +120,7 @@ RSpec.describe 'Commits' do
end
end
- context "when logged as reporter and with jobs_tab_vue feature flag off" do
- before do
- stub_feature_flags(jobs_tab_vue: false)
- project.add_reporter(user)
- create(:ci_job_artifact, :archive, file: artifacts_file, job: build)
- visit pipeline_path(pipeline)
- end
-
- it 'renders header', :js do
- expect(page).to have_content pipeline.sha[0..7]
- expect(page).to have_content pipeline.git_commit_message.gsub!(/\s+/, ' ')
- expect(page).to have_content pipeline.user.name
- expect(page).not_to have_link('Cancel running')
- expect(page).not_to have_link('Retry')
- end
-
- it do
- expect(page).to have_link('Download artifacts')
- end
- end
-
- context "when logged as reporter and with jobs_tab_vue feature flag on", :js do
+ context "when logged as reporter", :js do
before do
project.add_reporter(user)
create(:ci_job_artifact, :archive, file: artifacts_file, job: build)
diff --git a/spec/features/dashboard/group_spec.rb b/spec/features/dashboard/group_spec.rb
index 02cbdc7c777..f1283d29f4c 100644
--- a/spec/features/dashboard/group_spec.rb
+++ b/spec/features/dashboard/group_spec.rb
@@ -23,7 +23,7 @@ RSpec.describe 'Dashboard Group' do
fill_in 'group_name', with: new_name
click_button 'Create group'
- expect(current_path).to eq group_path(Group.find_by(name: new_name))
+ expect(page).to have_current_path group_path(Group.find_by(name: new_name)), ignore_query: true
expect(page).to have_content(new_name)
end
end
diff --git a/spec/features/dashboard/issuables_counter_spec.rb b/spec/features/dashboard/issuables_counter_spec.rb
index 6700ec07765..aa445265eec 100644
--- a/spec/features/dashboard/issuables_counter_spec.rb
+++ b/spec/features/dashboard/issuables_counter_spec.rb
@@ -8,41 +8,68 @@ RSpec.describe 'Navigation bar counter', :use_clean_rails_memory_store_caching d
let(:issue) { create(:issue, project: project) }
let(:merge_request) { create(:merge_request, source_project: project) }
- before do
- issue.assignees = [user]
- merge_request.update!(assignees: [user])
- sign_in(user)
- end
+ describe 'feature flag mr_attention_requests is disabled' do
+ before do
+ stub_feature_flags(mr_attention_requests: false)
- it 'reflects dashboard issues count' do
- visit issues_path
+ issue.assignees = [user]
+ merge_request.update!(assignees: [user])
+ sign_in(user)
+ end
- expect_counters('issues', '1', n_("%d assigned issue", "%d assigned issues", 1) % 1)
+ it 'reflects dashboard issues count' do
+ visit issues_path
- issue.assignees = []
+ expect_counters('issues', '1', n_("%d assigned issue", "%d assigned issues", 1) % 1)
- user.invalidate_cache_counts
+ issue.assignees = []
- travel_to(3.minutes.from_now) do
- visit issues_path
+ user.invalidate_cache_counts
+
+ travel_to(3.minutes.from_now) do
+ visit issues_path
- expect_counters('issues', '0', n_("%d assigned issue", "%d assigned issues", 0) % 0)
+ expect_counters('issues', '0', n_("%d assigned issue", "%d assigned issues", 0) % 0)
+ end
+ end
+
+ it 'reflects dashboard merge requests count', :js do
+ visit merge_requests_path
+
+ expect_counters('merge_requests', '1', n_("%d merge request", "%d merge requests", 1) % 1)
+
+ merge_request.update!(assignees: [])
+
+ user.invalidate_cache_counts
+
+ travel_to(3.minutes.from_now) do
+ visit merge_requests_path
+
+ expect_counters('merge_requests', '0', n_("%d merge request", "%d merge requests", 0) % 0)
+ end
end
end
- it 'reflects dashboard merge requests count' do
- visit merge_requests_path
+ describe 'feature flag mr_attention_requests is enabled' do
+ before do
+ merge_request.update!(assignees: [user])
+ sign_in(user)
+ end
- expect_counters('merge_requests', '1', n_("%d merge request", "%d merge requests", 1) % 1)
+ it 'reflects dashboard merge requests count', :js do
+ visit merge_requests_attention_path
- merge_request.update!(assignees: [])
+ expect_counters('merge_requests', '1', n_("%d merge request", "%d merge requests", 1) % 1)
- user.invalidate_cache_counts
+ merge_request.find_assignee(user).update!(state: :reviewed)
- travel_to(3.minutes.from_now) do
- visit merge_requests_path
+ user.invalidate_attention_requested_count
- expect_counters('merge_requests', '0', n_("%d merge request", "%d merge requests", 0) % 0)
+ travel_to(3.minutes.from_now) do
+ visit merge_requests_attention_path
+
+ expect_counters('merge_requests', '0', n_("%d merge request", "%d merge requests", 0) % 0)
+ end
end
end
@@ -54,14 +81,15 @@ RSpec.describe 'Navigation bar counter', :use_clean_rails_memory_store_caching d
merge_requests_dashboard_path(assignee_username: user.username)
end
+ def merge_requests_attention_path
+ merge_requests_dashboard_path(attention: user.username)
+ end
+
def expect_counters(issuable_type, count, badge_label)
dashboard_count = find('.gl-tabs-nav li a.active')
- nav_count = find(".dashboard-shortcuts-#{issuable_type}")
expect(dashboard_count).to have_content(count)
- expect(nav_count).to have_content(count)
- within("span[aria-label='#{badge_label}']") do
- expect(page).to have_content(count)
- end
+ expect(page).to have_css(".dashboard-shortcuts-#{issuable_type}", visible: :all, text: count)
+ expect(page).to have_css("span[aria-label='#{badge_label}']", visible: :all, text: count)
end
end
diff --git a/spec/features/dashboard/milestones_spec.rb b/spec/features/dashboard/milestones_spec.rb
index 9758454ab61..3f89955b12b 100644
--- a/spec/features/dashboard/milestones_spec.rb
+++ b/spec/features/dashboard/milestones_spec.rb
@@ -9,7 +9,7 @@ RSpec.describe 'Dashboard > Milestones' do
end
it 'is redirected to sign-in page' do
- expect(current_path).to eq new_user_session_path
+ expect(page).to have_current_path new_user_session_path, ignore_query: true
end
end
@@ -27,7 +27,7 @@ RSpec.describe 'Dashboard > Milestones' do
end
it 'sees milestones' do
- expect(current_path).to eq dashboard_milestones_path
+ expect(page).to have_current_path dashboard_milestones_path, ignore_query: true
expect(page).to have_content(milestone.title)
expect(page).to have_content(group.name)
expect(first('.milestone')).to have_content('Merge requests')
@@ -43,7 +43,7 @@ RSpec.describe 'Dashboard > Milestones' do
find('.js-new-project-item-link').click
- expect(current_path).to eq(new_group_milestone_path(group))
+ expect(page).to have_current_path(new_group_milestone_path(group), ignore_query: true)
end
end
end
@@ -61,7 +61,7 @@ RSpec.describe 'Dashboard > Milestones' do
end
it 'does not see milestones' do
- expect(current_path).to eq dashboard_milestones_path
+ expect(page).to have_current_path dashboard_milestones_path, ignore_query: true
expect(page).to have_content(milestone.title)
expect(first('.milestone')).to have_no_content('Merge Requests')
end
diff --git a/spec/features/dashboard/projects_spec.rb b/spec/features/dashboard/projects_spec.rb
index 82288a6c1a6..847d0faf60d 100644
--- a/spec/features/dashboard/projects_spec.rb
+++ b/spec/features/dashboard/projects_spec.rb
@@ -48,7 +48,7 @@ RSpec.describe 'Dashboard Projects' do
context 'when last_repository_updated_at, last_activity_at and update_at are present' do
it 'shows the last_repository_updated_at attribute as the update date' do
- project.update!(last_repository_updated_at: Time.now, last_activity_at: 1.hour.ago)
+ project.update!(last_repository_updated_at: Time.zone.now, last_activity_at: 1.hour.ago)
visit dashboard_projects_path
@@ -56,7 +56,7 @@ RSpec.describe 'Dashboard Projects' do
end
it 'shows the last_activity_at attribute as the update date' do
- project.update!(last_repository_updated_at: 1.hour.ago, last_activity_at: Time.now)
+ project.update!(last_repository_updated_at: 1.hour.ago, last_activity_at: Time.zone.now)
visit dashboard_projects_path
@@ -236,7 +236,7 @@ RSpec.describe 'Dashboard Projects' do
end
expect(page).to have_selector('.merge-request-form')
- expect(current_path).to eq project_new_merge_request_path(project)
+ expect(page).to have_current_path project_new_merge_request_path(project), ignore_query: true
expect(find('#merge_request_target_project_id', visible: false).value).to eq project.id.to_s
expect(page).to have_content "From feature into master"
end
diff --git a/spec/features/dashboard/todos/todos_filtering_spec.rb b/spec/features/dashboard/todos/todos_filtering_spec.rb
index 53209db3107..938e42623f6 100644
--- a/spec/features/dashboard/todos/todos_filtering_spec.rb
+++ b/spec/features/dashboard/todos/todos_filtering_spec.rb
@@ -178,7 +178,7 @@ RSpec.describe 'Dashboard > User filters todos', :js do
review_requested: ' requested a review of ',
mentioned: ' mentioned ',
marked: ' added a todo for ',
- build_failed: ' build failed for '
+ build_failed: ' pipeline failed in '
}
action_name_text = action_names.delete(action_name)
diff --git a/spec/features/dashboard/todos/todos_spec.rb b/spec/features/dashboard/todos/todos_spec.rb
index b00bdeac3b9..68d979bb1cf 100644
--- a/spec/features/dashboard/todos/todos_spec.rb
+++ b/spec/features/dashboard/todos/todos_spec.rb
@@ -400,7 +400,7 @@ RSpec.describe 'Dashboard Todos' do
end
it 'shows the todo' do
- expect(page).to have_content 'The build failed for merge request'
+ expect(page).to have_content 'The pipeline failed in merge request'
end
it 'links to the pipelines for the merge request' do
@@ -441,7 +441,7 @@ RSpec.describe 'Dashboard Todos' do
target.project, target.issue, target.filename
)
- expect(current_path).to eq(expectation)
+ expect(page).to have_current_path(expectation, ignore_query: true)
end
end
end
diff --git a/spec/features/dashboard/user_filters_projects_spec.rb b/spec/features/dashboard/user_filters_projects_spec.rb
index f6821ae66e8..2cf56f93cf9 100644
--- a/spec/features/dashboard/user_filters_projects_spec.rb
+++ b/spec/features/dashboard/user_filters_projects_spec.rb
@@ -79,11 +79,11 @@ RSpec.describe 'Dashboard > User filters projects' do
page.find('.filtered-search-block #filtered-search-sorting-dropdown .reverse-sort-btn').click
end
- def select_dropdown_option(selector, label)
+ def select_dropdown_option(selector, label, option_selector = '.dropdown-menu a')
dropdown = page.find(selector)
dropdown.click
- dropdown.find('.dropdown-menu a', text: label, match: :first).click
+ dropdown.find(option_selector, text: label, match: :first).click
end
def expect_to_see_projects(sorted_projects)
@@ -125,7 +125,7 @@ RSpec.describe 'Dashboard > User filters projects' do
end
it 'filters private projects only' do
- select_dropdown_option '#filtered-search-visibility-dropdown', 'Private'
+ select_dropdown_option '#filtered-search-visibility-dropdown > .dropdown', 'Private', '.dropdown-item'
expect(current_url).to match(/visibility_level=0/)
@@ -135,7 +135,7 @@ RSpec.describe 'Dashboard > User filters projects' do
end
it 'filters internal projects only' do
- select_dropdown_option '#filtered-search-visibility-dropdown', 'Internal'
+ select_dropdown_option '#filtered-search-visibility-dropdown > .dropdown', 'Internal', '.dropdown-item'
expect(current_url).to match(/visibility_level=10/)
@@ -145,7 +145,7 @@ RSpec.describe 'Dashboard > User filters projects' do
end
it 'filters any project' do
- select_dropdown_option '#filtered-search-visibility-dropdown', 'Any'
+ select_dropdown_option '#filtered-search-visibility-dropdown > .dropdown', 'Any', '.dropdown-item'
list = page.all('.projects-list .project-name').map(&:text)
expect(list).to contain_exactly("Internal project", "Private project", "Treasure", "Victorialand")
diff --git a/spec/features/expand_collapse_diffs_spec.rb b/spec/features/expand_collapse_diffs_spec.rb
index 63e16946a0b..98282e47488 100644
--- a/spec/features/expand_collapse_diffs_spec.rb
+++ b/spec/features/expand_collapse_diffs_spec.rb
@@ -13,6 +13,8 @@ RSpec.describe 'Expand and collapse diffs', :js do
sign_in(admin)
gitlab_enable_admin_mode_sign_in(admin)
+ wait_for_requests
+
# Ensure that undiffable.md is in .gitattributes
project.repository.copy_gitattributes(branch)
visit project_commit_path(project, project.commit(branch))
diff --git a/spec/features/explore/topics_spec.rb b/spec/features/explore/topics_spec.rb
index 9d2e76bc3a1..d6f3d6a123d 100644
--- a/spec/features/explore/topics_spec.rb
+++ b/spec/features/explore/topics_spec.rb
@@ -7,7 +7,7 @@ RSpec.describe 'Explore Topics' do
it 'renders empty message', :aggregate_failures do
visit topics_explore_projects_path
- expect(current_path).to eq topics_explore_projects_path
+ expect(page).to have_current_path topics_explore_projects_path, ignore_query: true
expect(page).to have_content('There are no topics to show.')
end
end
@@ -18,7 +18,7 @@ RSpec.describe 'Explore Topics' do
it 'renders topic list' do
visit topics_explore_projects_path
- expect(current_path).to eq topics_explore_projects_path
+ expect(page).to have_current_path topics_explore_projects_path, ignore_query: true
expect(page).to have_content('topic1')
end
end
diff --git a/spec/features/file_uploads/user_avatar_spec.rb b/spec/features/file_uploads/user_avatar_spec.rb
index c30e3452201..34cfb4a4128 100644
--- a/spec/features/file_uploads/user_avatar_spec.rb
+++ b/spec/features/file_uploads/user_avatar_spec.rb
@@ -26,7 +26,7 @@ RSpec.describe 'Upload a user avatar', :js do
expect(page).to have_content 'Profile was successfully updated'
expect(user.reload.avatar.file).to be_present
expect(user.avatar).to be_instance_of AvatarUploader
- expect(current_path).to eq(profile_path)
+ expect(page).to have_current_path(profile_path, ignore_query: true)
end
end
diff --git a/spec/features/global_search_spec.rb b/spec/features/global_search_spec.rb
index 0397e72502a..baa691d244e 100644
--- a/spec/features/global_search_spec.rb
+++ b/spec/features/global_search_spec.rb
@@ -72,6 +72,10 @@ RSpec.describe 'Global search' do
# TODO: Remove this along with feature flag #339348
stub_feature_flags(new_header_search: true)
visit dashboard_projects_path
+
+ # intialize javascript loaded input search input field
+ find('#search').click
+ find('body').click
end
it 'renders updated search bar' do
diff --git a/spec/features/groups/clusters/eks_spec.rb b/spec/features/groups/clusters/eks_spec.rb
index fe62efbd3bf..3cca2d0919c 100644
--- a/spec/features/groups/clusters/eks_spec.rb
+++ b/spec/features/groups/clusters/eks_spec.rb
@@ -13,13 +13,15 @@ RSpec.describe 'Group AWS EKS Cluster', :js do
allow(Groups::ClustersController).to receive(:STATUS_POLLING_INTERVAL) { 100 }
allow_any_instance_of(Clusters::Kubernetes::CreateOrUpdateNamespaceService).to receive(:execute)
allow_any_instance_of(Clusters::Cluster).to receive(:retrieve_connection_status).and_return(:connected)
+ stub_application_setting(eks_integration_enabled: true)
end
context 'when user does not have a cluster and visits group clusters page' do
before do
visit group_clusters_path(group)
- click_link 'Connect with a certificate'
+ click_button 'Actions'
+ click_link 'Create a new cluster'
end
context 'when user creates a cluster on AWS EKS' do
@@ -28,7 +30,7 @@ RSpec.describe 'Group AWS EKS Cluster', :js do
end
it 'user sees a form to create an EKS cluster' do
- expect(page).to have_content('Create new cluster on EKS')
+ expect(page).to have_content('Authenticate with Amazon Web Services')
end
end
end
diff --git a/spec/features/groups/clusters/user_spec.rb b/spec/features/groups/clusters/user_spec.rb
index 1788167c94c..2ed6ddc09ab 100644
--- a/spec/features/groups/clusters/user_spec.rb
+++ b/spec/features/groups/clusters/user_spec.rb
@@ -26,7 +26,6 @@ RSpec.describe 'User Cluster', :js do
visit group_clusters_path(group)
click_link 'Connect with a certificate'
- click_link 'Connect existing cluster'
end
context 'when user filled form with valid parameters' do
@@ -94,16 +93,7 @@ RSpec.describe 'User Cluster', :js do
expect(page).to have_button('Save changes')
end
- context 'when user disables the cluster' do
- before do
- page.find(:css, '.js-cluster-enable-toggle-area .js-project-feature-toggle').click
- page.within('.js-cluster-details-form') { click_button 'Save changes' }
- end
-
- it 'user sees the successful message' do
- expect(page).to have_content('Kubernetes cluster was successfully updated.')
- end
- end
+ include_examples "user disables a cluster"
context 'when user changes cluster parameters' do
before do
diff --git a/spec/features/groups/container_registry_spec.rb b/spec/features/groups/container_registry_spec.rb
index f5af9ba8b7b..7bef2dc9416 100644
--- a/spec/features/groups/container_registry_spec.rb
+++ b/spec/features/groups/container_registry_spec.rb
@@ -97,6 +97,8 @@ RSpec.describe 'Container Registry', :js do
expect(find('.modal .modal-title')).to have_content _('Remove tag')
find('.modal .modal-footer .btn-danger').click
end
+
+ it_behaves_like 'rejecting tags destruction for an importing repository on', tags: ['latest']
end
end
diff --git a/spec/features/groups/group_settings_spec.rb b/spec/features/groups/group_settings_spec.rb
index 30a81333547..50982cb1452 100644
--- a/spec/features/groups/group_settings_spec.rb
+++ b/spec/features/groups/group_settings_spec.rb
@@ -20,7 +20,7 @@ RSpec.describe 'Edit group settings' do
update_path(new_group_path)
visit new_group_full_path
- expect(current_path).to eq(new_group_full_path)
+ expect(page).to have_current_path(new_group_full_path, ignore_query: true)
expect(find('h1.home-panel-title')).to have_content(group.name)
end
@@ -28,7 +28,7 @@ RSpec.describe 'Edit group settings' do
update_path(new_group_path)
visit old_group_full_path
- expect(current_path).to eq(new_group_full_path)
+ expect(page).to have_current_path(new_group_full_path, ignore_query: true)
expect(find('h1.home-panel-title')).to have_content(group.name)
end
@@ -41,7 +41,7 @@ RSpec.describe 'Edit group settings' do
update_path(new_group_path)
visit new_subgroup_full_path
- expect(current_path).to eq(new_subgroup_full_path)
+ expect(page).to have_current_path(new_subgroup_full_path, ignore_query: true)
expect(find('h1.home-panel-title')).to have_content(subgroup.name)
end
@@ -49,7 +49,7 @@ RSpec.describe 'Edit group settings' do
update_path(new_group_path)
visit old_subgroup_full_path
- expect(current_path).to eq(new_subgroup_full_path)
+ expect(page).to have_current_path(new_subgroup_full_path, ignore_query: true)
expect(find('h1.home-panel-title')).to have_content(subgroup.name)
end
end
@@ -71,7 +71,7 @@ RSpec.describe 'Edit group settings' do
update_path(new_group_path)
visit new_project_full_path
- expect(current_path).to eq(new_project_full_path)
+ expect(page).to have_current_path(new_project_full_path, ignore_query: true)
expect(find('.breadcrumbs')).to have_content(project.path)
end
@@ -79,7 +79,7 @@ RSpec.describe 'Edit group settings' do
update_path(new_group_path)
visit old_project_full_path
- expect(current_path).to eq(new_project_full_path)
+ expect(page).to have_current_path(new_project_full_path, ignore_query: true)
expect(find('.breadcrumbs')).to have_content(project.path)
end
end
@@ -154,32 +154,50 @@ RSpec.describe 'Edit group settings' do
namespace_select.find('button').click
namespace_select.find('.dropdown-menu p', text: target_group_name, match: :first).click
- click_button "Transfer group"
+ click_button 'Transfer group'
end
page.within(confirm_modal) do
- expect(page).to have_text "You are going to transfer #{selected_group.name} to another namespace. Are you ABSOLUTELY sure? "
+ expect(page).to have_text "You are going to transfer #{selected_group.name} to another namespace. Are you ABSOLUTELY sure?"
- fill_in "confirm_name_input", with: selected_group.name
- click_button "Confirm"
+ fill_in 'confirm_name_input', with: selected_group.name
+ click_button 'Confirm'
end
expect(page).to have_text "Group '#{selected_group.name}' was successfully transferred."
+ expect(current_url).to include(selected_group.reload.full_path)
end
end
- context 'with a sub group' do
+ context 'from a subgroup' do
let(:selected_group) { create(:group, path: 'foo-subgroup', parent: group) }
- let(:target_group_name) { "No parent group" }
- it_behaves_like 'can transfer the group'
+ context 'to no parent group' do
+ let(:target_group_name) { 'No parent group' }
+
+ it_behaves_like 'can transfer the group'
+ end
+
+ context 'to a different parent group' do
+ let(:target_group) { create(:group, path: 'foo-parentgroup') }
+ let(:target_group_name) { target_group.name }
+
+ before do
+ target_group.add_owner(user)
+ end
+
+ it_behaves_like 'can transfer the group'
+ end
end
- context 'with a root group' do
+ context 'from a root group' do
let(:selected_group) { create(:group, path: 'foo-rootgroup') }
- let(:target_group_name) { group.name }
- it_behaves_like 'can transfer the group'
+ context 'to a parent group' do
+ let(:target_group_name) { group.name }
+
+ it_behaves_like 'can transfer the group'
+ end
end
end
diff --git a/spec/features/groups/issues_spec.rb b/spec/features/groups/issues_spec.rb
index 3fc1484826c..6b663445124 100644
--- a/spec/features/groups/issues_spec.rb
+++ b/spec/features/groups/issues_spec.rb
@@ -108,6 +108,22 @@ RSpec.describe 'Group issues page' do
end
end
+ context 'group with no issues', :js do
+ let!(:group_with_no_issues) { create(:group) }
+ let!(:subgroup_with_issues) { create(:group, parent: group_with_no_issues) }
+ let!(:subgroup_project) { create(:project, :public, group: subgroup_with_issues) }
+ let!(:subgroup_issue) { create(:issue, project: subgroup_project) }
+
+ before do
+ stub_feature_flags(vue_issues_list: true)
+ visit issues_group_path(group_with_no_issues)
+ end
+
+ it 'shows issues from subgroups on issues list' do
+ expect(page).to have_text subgroup_issue.title
+ end
+ end
+
context 'projects with issues disabled' do
describe 'issue dropdown' do
let(:user_in_group) { create(:group_member, :maintainer, user: create(:user), group: group ).user }
diff --git a/spec/features/groups/labels/create_spec.rb b/spec/features/groups/labels/create_spec.rb
index 9c1a3672ebd..19433e612ff 100644
--- a/spec/features/groups/labels/create_spec.rb
+++ b/spec/features/groups/labels/create_spec.rb
@@ -18,6 +18,6 @@ RSpec.describe 'Create a group label' do
click_button 'Create label'
expect(page).to have_content 'test-label'
- expect(current_path).to eq(group_labels_path(group))
+ expect(page).to have_current_path(group_labels_path(group), ignore_query: true)
end
end
diff --git a/spec/features/groups/labels/edit_spec.rb b/spec/features/groups/labels/edit_spec.rb
index 8e6560af352..cf1729af97d 100644
--- a/spec/features/groups/labels/edit_spec.rb
+++ b/spec/features/groups/labels/edit_spec.rb
@@ -19,7 +19,7 @@ RSpec.describe 'Edit group label' do
fill_in 'label_title', with: 'new label name'
click_button 'Save changes'
- expect(current_path).to eq(root_path)
+ expect(page).to have_current_path(root_path, ignore_query: true)
expect(label.reload.title).to eq('new label name')
end
diff --git a/spec/features/groups/labels/sort_labels_spec.rb b/spec/features/groups/labels/sort_labels_spec.rb
index df75ff7c3cb..fba166449f8 100644
--- a/spec/features/groups/labels/sort_labels_spec.rb
+++ b/spec/features/groups/labels/sort_labels_spec.rb
@@ -28,7 +28,7 @@ RSpec.describe 'Sort labels', :js do
it 'sorts by date' do
click_button 'Name'
- sort_options = find('ul.dropdown-menu-sort li').all('a').collect(&:text)
+ sort_options = find('ul.dropdown-menu').all('li').collect(&:text)
expect(sort_options[0]).to eq('Name')
expect(sort_options[1]).to eq('Name, descending')
@@ -37,7 +37,7 @@ RSpec.describe 'Sort labels', :js do
expect(sort_options[4]).to eq('Updated date')
expect(sort_options[5]).to eq('Oldest updated')
- click_link 'Name, descending'
+ click_button 'Name, descending'
# assert default sorting
within '.other-labels' do
diff --git a/spec/features/groups/members/leave_group_spec.rb b/spec/features/groups/members/leave_group_spec.rb
index 9612c6625f6..50d5db46cee 100644
--- a/spec/features/groups/members/leave_group_spec.rb
+++ b/spec/features/groups/members/leave_group_spec.rb
@@ -21,7 +21,7 @@ RSpec.describe 'Groups > Members > Leave group' do
visit group_path(group)
click_link 'Leave group'
- expect(current_path).to eq(dashboard_groups_path)
+ expect(page).to have_current_path(dashboard_groups_path, ignore_query: true)
expect(page).to have_content left_group_message(group)
expect(group.users).not_to include(user)
end
@@ -35,7 +35,7 @@ RSpec.describe 'Groups > Members > Leave group' do
page.accept_confirm
wait_for_all_requests
- expect(current_path).to eq(dashboard_groups_path)
+ expect(page).to have_current_path(dashboard_groups_path, ignore_query: true)
expect(group.users).not_to include(user)
end
@@ -45,7 +45,7 @@ RSpec.describe 'Groups > Members > Leave group' do
visit group_path(group)
click_link 'Leave group'
- expect(current_path).to eq(dashboard_groups_path)
+ expect(page).to have_current_path(dashboard_groups_path, ignore_query: true)
expect(page).to have_content left_group_message(group)
expect(group.users).not_to include(user)
end
@@ -57,7 +57,7 @@ RSpec.describe 'Groups > Members > Leave group' do
visit group_path(group)
click_link 'Leave group'
- expect(current_path).to eq(dashboard_groups_path)
+ expect(page).to have_current_path(dashboard_groups_path, ignore_query: true)
expect(page).to have_content left_group_message(group)
expect(group.users).not_to include(user)
end
diff --git a/spec/features/groups/members/manage_groups_spec.rb b/spec/features/groups/members/manage_groups_spec.rb
index 61c6709f9cc..5ab5a7ea716 100644
--- a/spec/features/groups/members/manage_groups_spec.rb
+++ b/spec/features/groups/members/manage_groups_spec.rb
@@ -14,34 +14,6 @@ RSpec.describe 'Groups > Members > Manage groups', :js do
sign_in(user)
end
- context 'with invite_members_group_modal disabled' do
- before do
- stub_feature_flags(invite_members_group_modal: false)
- end
-
- context 'when group link does not exist' do
- let_it_be(:group) { create(:group) }
- let_it_be(:group_to_add) { create(:group) }
-
- before do
- group.add_owner(user)
- group_to_add.add_owner(user)
- visit group_group_members_path(group)
- end
-
- it 'can share group with group' do
- add_group(group_to_add.id, 'Reporter')
-
- click_groups_tab
-
- page.within(first_row) do
- expect(page).to have_content(group_to_add.name)
- expect(page).to have_content('Reporter')
- end
- end
- end
- end
-
context 'when group link does not exist' do
it 'can share a group with group' do
group = create(:group)
@@ -177,32 +149,14 @@ RSpec.describe 'Groups > Members > Manage groups', :js do
end
context 'when sharing with groups outside the hierarchy is enabled' do
- context 'when the invite members group modal is disabled' do
- before do
- stub_feature_flags(invite_members_group_modal: false)
- end
-
- it 'shows groups within and outside the hierarchy in search results' do
- visit group_group_members_path(group)
-
- click_on 'Invite group'
- click_on 'Search for a group'
-
- expect(page).to have_text group_within_hierarchy.name
- expect(page).to have_text group_outside_hierarchy.name
- end
- end
-
- context 'when the invite members group modal is enabled' do
- it 'shows groups within and outside the hierarchy in search results' do
- visit group_group_members_path(group)
+ it 'shows groups within and outside the hierarchy in search results' do
+ visit group_group_members_path(group)
- click_on 'Invite a group'
- click_on 'Select a group'
+ click_on 'Invite a group'
+ click_on 'Select a group'
- expect(page).to have_text group_within_hierarchy.name
- expect(page).to have_text group_outside_hierarchy.name
- end
+ expect(page).to have_text group_within_hierarchy.name
+ expect(page).to have_text group_outside_hierarchy.name
end
end
@@ -211,45 +165,18 @@ RSpec.describe 'Groups > Members > Manage groups', :js do
group.namespace_settings.update!(prevent_sharing_groups_outside_hierarchy: true)
end
- context 'when the invite members group modal is disabled' do
- before do
- stub_feature_flags(invite_members_group_modal: false)
- end
-
- it 'shows only groups within the hierarchy in search results' do
- visit group_group_members_path(group)
-
- click_on 'Invite group'
- click_on 'Search for a group'
-
- expect(page).to have_text group_within_hierarchy.name
- expect(page).not_to have_text group_outside_hierarchy.name
- end
- end
-
- context 'when the invite members group modal is enabled' do
- it 'shows only groups within the hierarchy in search results' do
- visit group_group_members_path(group)
+ it 'shows only groups within the hierarchy in search results' do
+ visit group_group_members_path(group)
- click_on 'Invite a group'
- click_on 'Select a group'
+ click_on 'Invite a group'
+ click_on 'Select a group'
- expect(page).to have_text group_within_hierarchy.name
- expect(page).not_to have_text group_outside_hierarchy.name
- end
+ expect(page).to have_text group_within_hierarchy.name
+ expect(page).not_to have_text group_outside_hierarchy.name
end
end
end
- def add_group(id, role)
- page.click_link 'Invite group'
- page.within ".invite-group-form" do
- select2(id, from: "#shared_with_group_id")
- select(role, from: "shared_group_access")
- click_button "Invite"
- end
- end
-
def click_groups_tab
expect(page).to have_link 'Groups'
click_link "Groups"
diff --git a/spec/features/groups/members/manage_members_spec.rb b/spec/features/groups/members/manage_members_spec.rb
index e5dad5ee4be..533d2118b30 100644
--- a/spec/features/groups/members/manage_members_spec.rb
+++ b/spec/features/groups/members/manage_members_spec.rb
@@ -15,42 +15,18 @@ RSpec.describe 'Groups > Members > Manage members' do
sign_in(user1)
end
- shared_examples 'includes the correct Invite link' do |should_include, should_not_include|
- it 'includes either the form or the modal trigger', :aggregate_failures do
+ shared_examples 'includes the correct Invite link' do |should_include|
+ it 'includes the modal trigger', :aggregate_failures do
group.add_owner(user1)
visit group_group_members_path(group)
expect(page).to have_selector(should_include)
- expect(page).not_to have_selector(should_not_include)
end
end
- shared_examples 'does not include either invite modal or either invite form' do
- it 'does not include either of the invite members or invite group modal buttons', :aggregate_failures do
- expect(page).not_to have_selector '.js-invite-members-modal'
- expect(page).not_to have_selector '.js-invite-group-modal'
- end
-
- it 'does not include either of the invite users or invite group forms', :aggregate_failures do
- expect(page).not_to have_selector '.invite-users-form'
- expect(page).not_to have_selector '.invite-group-form'
- end
- end
-
- context 'when Invite Members modal is enabled' do
- it_behaves_like 'includes the correct Invite link', '.js-invite-members-trigger', '.invite-users-form'
- it_behaves_like 'includes the correct Invite link', '.js-invite-group-trigger', '.invite-group-form'
- end
-
- context 'when Invite Members modal is disabled' do
- before do
- stub_feature_flags(invite_members_group_modal: false)
- end
-
- it_behaves_like 'includes the correct Invite link', '.invite-users-form', '.js-invite-members-trigger'
- it_behaves_like 'includes the correct Invite link', '.invite-group-form', '.js-invite-group-trigger'
- end
+ it_behaves_like 'includes the correct Invite link', '.js-invite-members-trigger'
+ it_behaves_like 'includes the correct Invite link', '.js-invite-group-trigger'
it 'update user to owner level', :js do
group.add_owner(user1)
@@ -106,33 +82,6 @@ RSpec.describe 'Groups > Members > Manage members' do
expect(page).to have_content('Invite "undisclosed_email@gitlab.com" by email')
end
- context 'when Invite Members modal is disabled' do
- before do
- stub_feature_flags(invite_members_group_modal: false)
- end
-
- it 'do not disclose email addresses', :js do
- group.add_owner(user1)
- create(:user, email: 'undisclosed_email@gitlab.com', name: "Jane 'invisible' Doe")
-
- visit group_group_members_path(group)
-
- find('.select2-container').click
- select_input = find('.select2-input')
-
- select_input.send_keys('@gitlab.com')
- wait_for_requests
-
- expect(page).to have_content('No matches found')
-
- select_input.native.clear
- select_input.send_keys('undisclosed_email@gitlab.com')
- wait_for_requests
-
- expect(page).to have_content('Invite "undisclosed_email@gitlab.com" by email')
- end
- end
-
it 'remove user from group', :js do
group.add_owner(user1)
group.add_developer(user2)
@@ -205,30 +154,11 @@ RSpec.describe 'Groups > Members > Manage members' do
visit group_group_members_path(group)
end
- it_behaves_like 'does not include either invite modal or either invite form'
-
- it 'does not include a button on the members page list to manage or remove the existing member', :js, :aggregate_failures do
- page.within(second_row) do
- # Can not modify user2 role
- expect(page).not_to have_button 'Developer'
-
- # Can not remove user2
- expect(page).not_to have_selector 'button[title="Remove member"]'
- end
- end
- end
-
- context 'when user is a guest and the :invite_members_group_modal feature flag is disabled' do
- before do
- stub_feature_flags(invite_members_group_modal: false)
- group.add_guest(user1)
- group.add_developer(user2)
-
- visit group_group_members_path(group)
+ it 'does not include either of the invite members or invite group modal buttons', :aggregate_failures do
+ expect(page).not_to have_selector '.js-invite-members-modal'
+ expect(page).not_to have_selector '.js-invite-group-modal'
end
- it_behaves_like 'does not include either invite modal or either invite form'
-
it 'does not include a button on the members page list to manage or remove the existing member', :js, :aggregate_failures do
page.within(second_row) do
# Can not modify user2 role
diff --git a/spec/features/groups/navbar_spec.rb b/spec/features/groups/navbar_spec.rb
index c5d2f5e6733..e4b44d65438 100644
--- a/spec/features/groups/navbar_spec.rb
+++ b/spec/features/groups/navbar_spec.rb
@@ -18,6 +18,7 @@ RSpec.describe 'Group navbar' do
stub_feature_flags(customer_relations: false)
stub_config(dependency_proxy: { enabled: false })
stub_config(registry: { enabled: false })
+ stub_feature_flags(harbor_registry_integration: false)
stub_group_wikis(false)
group.add_maintainer(user)
sign_in(user)
@@ -59,6 +60,18 @@ RSpec.describe 'Group navbar' do
it_behaves_like 'verified navigation bar'
end
+ context 'when customer_relations feature and flag is enabled but subgroup' do
+ let(:group) { create(:group, :crm_enabled, parent: create(:group)) }
+
+ before do
+ stub_feature_flags(customer_relations: true)
+
+ visit group_path(group)
+ end
+
+ it_behaves_like 'verified navigation bar'
+ end
+
context 'when dependency proxy is available' do
before do
stub_config(dependency_proxy: { enabled: true })
@@ -70,4 +83,16 @@ RSpec.describe 'Group navbar' do
it_behaves_like 'verified navigation bar'
end
+
+ context 'when harbor registry is available' do
+ before do
+ stub_feature_flags(harbor_registry_integration: true)
+
+ insert_harbor_registry_nav(_('Package Registry'))
+
+ visit group_path(group)
+ end
+
+ it_behaves_like 'verified navigation bar'
+ end
end
diff --git a/spec/features/groups/settings/ci_cd_spec.rb b/spec/features/groups/settings/ci_cd_spec.rb
index b059cd8da29..8851aeb6381 100644
--- a/spec/features/groups/settings/ci_cd_spec.rb
+++ b/spec/features/groups/settings/ci_cd_spec.rb
@@ -13,6 +13,24 @@ RSpec.describe 'Group CI/CD settings' do
sign_in(user)
end
+ describe 'new group runners view banner' do
+ it 'displays banner' do
+ visit group_settings_ci_cd_path(group)
+
+ expect(page).to have_content(s_('Runners|New group runners view'))
+ expect(page).to have_link(href: group_runners_path(group))
+ end
+
+ it 'does not display banner' do
+ stub_feature_flags(runner_list_group_view_vue_ui: false)
+
+ visit group_settings_ci_cd_path(group)
+
+ expect(page).not_to have_content(s_('Runners|New group runners view'))
+ expect(page).not_to have_link(href: group_runners_path(group))
+ end
+ end
+
describe 'runners registration token' do
let!(:token) { group.runners_token }
diff --git a/spec/features/groups/settings/repository_spec.rb b/spec/features/groups/settings/repository_spec.rb
index d95eaf3c92c..159deb2a4e3 100644
--- a/spec/features/groups/settings/repository_spec.rb
+++ b/spec/features/groups/settings/repository_spec.rb
@@ -26,7 +26,7 @@ RSpec.describe 'Group Repository settings' do
end
end
- context 'Default initial branch name' do
+ context 'Default branch' do
before do
visit group_settings_repository_path(group)
end
@@ -37,8 +37,8 @@ RSpec.describe 'Group Repository settings' do
it 'renders the correct setting section content' do
within("#js-default-branch-name") do
- expect(page).to have_content("Default initial branch name")
- expect(page).to have_content("The default name for the initial branch of new repositories created in the group.")
+ expect(page).to have_content("Default branch")
+ expect(page).to have_content("Set the initial name and protections for the default branch of new repositories created in the group.")
end
end
end
diff --git a/spec/features/groups/settings/user_searches_in_settings_spec.rb b/spec/features/groups/settings/user_searches_in_settings_spec.rb
index abf56232aff..c7b7b25caa7 100644
--- a/spec/features/groups/settings/user_searches_in_settings_spec.rb
+++ b/spec/features/groups/settings/user_searches_in_settings_spec.rb
@@ -32,7 +32,7 @@ RSpec.describe 'User searches group settings', :js do
visit group_settings_repository_path(group)
end
- it_behaves_like 'can search settings', 'Deploy tokens', 'Default initial branch name'
+ it_behaves_like 'can search settings', 'Deploy tokens', 'Default branch'
end
context 'in CI/CD page' do
diff --git a/spec/features/groups_spec.rb b/spec/features/groups_spec.rb
index 925bbc47cf6..08183badda1 100644
--- a/spec/features/groups_spec.rb
+++ b/spec/features/groups_spec.rb
@@ -32,7 +32,7 @@ RSpec.describe 'Group' do
group = Group.find_by(name: 'test-group')
expect(group.visibility_level).to eq(Gitlab::VisibilityLevel::PUBLIC)
- expect(current_path).to eq(group_path(group))
+ expect(page).to have_current_path(group_path(group), ignore_query: true)
expect(page).to have_selector '.visibility-icon [data-testid="earth-icon"]'
end
end
@@ -51,7 +51,7 @@ RSpec.describe 'Group' do
fill_in 'Group URL', with: 'space group'
click_button 'Create group'
- expect(current_path).to eq(new_group_path)
+ expect(page).to have_current_path(new_group_path, ignore_query: true)
expect(page).to have_text('Choose a group path that does not start with a dash or end with a period. It can also contain alphanumeric characters and underscores.')
end
end
@@ -62,7 +62,7 @@ RSpec.describe 'Group' do
fill_in 'Group URL', with: 'atom_group.atom'
click_button 'Create group'
- expect(current_path).to eq(groups_path)
+ expect(page).to have_current_path(groups_path, ignore_query: true)
expect(page).to have_namespace_error_message
end
end
@@ -73,7 +73,7 @@ RSpec.describe 'Group' do
fill_in 'Group URL', with: 'git_group.git'
click_button 'Create group'
- expect(current_path).to eq(groups_path)
+ expect(page).to have_current_path(groups_path, ignore_query: true)
expect(page).to have_namespace_error_message
end
end
@@ -211,7 +211,7 @@ RSpec.describe 'Group' do
fill_in 'Group name', with: 'bar'
click_button 'Create group'
- expect(current_path).to eq(group_path('foo/bar'))
+ expect(page).to have_current_path(group_path('foo/bar'), ignore_query: true)
expect(page).to have_selector 'h1', text: 'bar'
end
end
@@ -237,7 +237,7 @@ RSpec.describe 'Group' do
fill_in 'Group name', with: 'bar'
click_button 'Create group'
- expect(current_path).to eq(group_path('foo/bar'))
+ expect(page).to have_current_path(group_path('foo/bar'), ignore_query: true)
expect(page).to have_selector 'h1', text: 'bar'
end
end
@@ -474,4 +474,69 @@ RSpec.describe 'Group' do
fill_in 'confirm_name_input', with: confirm_with
click_button 'Confirm'
end
+
+ describe 'storage_enforcement_banner', :js do
+ let_it_be(:group) { create(:group) }
+ let_it_be_with_refind(:user) { create(:user) }
+
+ before_all do
+ group.add_owner(user)
+ sign_in(user)
+ end
+
+ context 'with storage_enforcement_date set' do
+ let_it_be(:storage_enforcement_date) { Date.today + 30 }
+
+ before do
+ allow_next_found_instance_of(Group) do |g|
+ allow(g).to receive(:storage_enforcement_date).and_return(storage_enforcement_date)
+ end
+ end
+
+ it 'displays the banner in the group page' do
+ visit group_path(group)
+ expect_page_to_have_storage_enforcement_banner(storage_enforcement_date)
+ end
+
+ it 'does not display the banner in a paid group page' do
+ allow_next_found_instance_of(Group) do |g|
+ allow(g).to receive(:paid?).and_return(true)
+ end
+ visit group_path(group)
+ expect_page_not_to_have_storage_enforcement_banner
+ end
+
+ it 'does not display the banner if user has previously closed unless threshold has changed' do
+ visit group_path(group)
+ expect_page_to_have_storage_enforcement_banner(storage_enforcement_date)
+ find('.js-storage-enforcement-banner [data-testid="close-icon"]').click
+ page.refresh
+ expect_page_not_to_have_storage_enforcement_banner
+
+ storage_enforcement_date = Date.today + 13
+ allow_next_found_instance_of(Group) do |g|
+ allow(g).to receive(:storage_enforcement_date).and_return(storage_enforcement_date)
+ end
+ page.refresh
+ expect_page_to_have_storage_enforcement_banner(storage_enforcement_date)
+ end
+ end
+
+ context 'with storage_enforcement_date not set' do
+ # This test should break and be rewritten after the implementation of the storage_enforcement_date
+ # TBD: https://gitlab.com/gitlab-org/gitlab/-/issues/350632
+ it 'does not display the banner in the group page' do
+ visit group_path(group)
+ expect_page_not_to_have_storage_enforcement_banner
+ end
+ end
+ end
+
+ def expect_page_to_have_storage_enforcement_banner(storage_enforcement_date)
+ expect(page).to have_text "From #{storage_enforcement_date} storage limits will apply to this namespace"
+ end
+
+ def expect_page_not_to_have_storage_enforcement_banner
+ expect(page).not_to have_text "storage limits will apply to this namespace"
+ end
end
diff --git a/spec/features/incidents/incident_details_spec.rb b/spec/features/incidents/incident_details_spec.rb
index b704a0515c8..dad3dfd3440 100644
--- a/spec/features/incidents/incident_details_spec.rb
+++ b/spec/features/incidents/incident_details_spec.rb
@@ -6,6 +6,7 @@ RSpec.describe 'Incident details', :js do
let_it_be(:project) { create(:project) }
let_it_be(:developer) { create(:user) }
let_it_be(:incident) { create(:incident, project: project, author: developer, description: 'description') }
+ let_it_be(:escalation_status) { create(:incident_management_issuable_escalation_status, issue: incident) }
before_all do
project.add_developer(developer)
@@ -21,7 +22,7 @@ RSpec.describe 'Incident details', :js do
context 'when a developer+ displays the incident' do
it 'shows the incident' do
page.within('.issuable-details') do
- expect(find('h2')).to have_content(incident.title)
+ expect(find('h1')).to have_content(incident.title)
end
end
@@ -33,7 +34,7 @@ RSpec.describe 'Incident details', :js do
page.within('.issuable-details') do
incident_tabs = find('[data-testid="incident-tabs"]')
- expect(find('h2')).to have_content(incident.title)
+ expect(find('h1')).to have_content(incident.title)
expect(incident_tabs).to have_content('Summary')
expect(incident_tabs).to have_content(incident.description)
end
@@ -46,6 +47,42 @@ RSpec.describe 'Incident details', :js do
expect(page).to have_selector('.right-sidebar[data-issuable-type="issue"]')
expect(sidebar).to have_selector('.incident-severity')
expect(sidebar).to have_selector('.milestone')
+ expect(sidebar).to have_selector('[data-testid="escalation_status_container"]')
+ end
+ end
+
+ context 'escalation status' do
+ let(:sidebar) { page.find('.right-sidebar') }
+ let(:widget) { sidebar.find('[data-testid="escalation_status_container"]') }
+ let(:expected_dropdown_options) { escalation_status.class::STATUSES.keys.take(3).map { |key| key.to_s.titleize } }
+
+ it 'has an interactable escalation status widget' do
+ expect(current_status).to have_text(escalation_status.status_name.to_s.titleize)
+
+ # list the available statuses
+ widget.find('[data-testid="edit-button"]').click
+ expect(dropdown_options.map(&:text)).to eq(expected_dropdown_options)
+ expect(widget).not_to have_selector('#escalation-status-help')
+
+ # update the status
+ select_resolved(dropdown_options)
+ expect(current_status).to have_text('Resolved')
+ expect(escalation_status.reload).to be_resolved
+ end
+
+ private
+
+ def dropdown_options
+ widget.all('[data-testid="status-dropdown-item"]', count: 3)
+ end
+
+ def select_resolved(options)
+ options.last.click
+ wait_for_requests
+ end
+
+ def current_status
+ widget.find('[data-testid="collapsed-content"]')
end
end
end
diff --git a/spec/features/incidents/incidents_list_spec.rb b/spec/features/incidents/incidents_list_spec.rb
index c65c83b2804..789cc89e083 100644
--- a/spec/features/incidents/incidents_list_spec.rb
+++ b/spec/features/incidents/incidents_list_spec.rb
@@ -34,5 +34,28 @@ RSpec.describe 'Incident Management index', :js do
it 'alert page title' do
expect(page).to have_content('Incidents')
end
+
+ it 'has expected columns' do
+ table = page.find('.gl-table')
+
+ expect(table).to have_content('Severity')
+ expect(table).to have_content('Incident')
+ expect(table).to have_content('Status')
+ expect(table).to have_content('Date created')
+ expect(table).to have_content('Assignees')
+ end
+
+ context 'when :incident_escalations feature is disabled' do
+ before do
+ stub_feature_flags(incident_escalations: false)
+ end
+
+ it 'does not include the Status columns' do
+ visit project_incidents_path(project)
+ wait_for_requests
+
+ expect(page.find('.gl-table')).not_to have_content('Status')
+ end
+ end
end
end
diff --git a/spec/features/incidents/user_views_incident_spec.rb b/spec/features/incidents/user_views_incident_spec.rb
index fe54f7708c9..a669966502e 100644
--- a/spec/features/incidents/user_views_incident_spec.rb
+++ b/spec/features/incidents/user_views_incident_spec.rb
@@ -26,7 +26,7 @@ RSpec.describe "User views incident" do
it 'shows the merge request and incident actions', :js, :aggregate_failures do
click_button 'Incident actions'
- expect(page).to have_link('New incident', href: new_project_issue_path(project, { issuable_template: 'incident', issue: { issue_type: 'incident', description: "Related to \##{incident.iid}.\n\n" } }))
+ expect(page).to have_link('New related incident', href: new_project_issue_path(project, { issuable_template: 'incident', issue: { issue_type: 'incident' }, add_related_issue: incident.iid }))
expect(page).to have_button('Create merge request')
expect(page).to have_button('Close incident')
end
@@ -40,10 +40,8 @@ RSpec.describe "User views incident" do
visit(project_issues_incident_path(project, incident))
end
- it 'does not show the incident action', :js, :aggregate_failures do
- click_button 'Incident actions'
-
- expect(page).not_to have_link('New incident')
+ it 'does not show the incident actions', :js, :aggregate_failures do
+ expect(page).not_to have_button('Incident actions')
end
end
end
diff --git a/spec/features/invites_spec.rb b/spec/features/invites_spec.rb
index 9cb9416e7a0..965e97baadd 100644
--- a/spec/features/invites_spec.rb
+++ b/spec/features/invites_spec.rb
@@ -57,7 +57,7 @@ RSpec.describe 'Group or Project invitations', :aggregate_failures do
end
it 'renders sign up page with sign up notice' do
- expect(current_path).to eq(new_user_registration_path)
+ expect(page).to have_current_path(new_user_registration_path, ignore_query: true)
expect(page).to have_content('To accept this invitation, create an account or sign in')
end
@@ -85,7 +85,7 @@ RSpec.describe 'Group or Project invitations', :aggregate_failures do
fill_in_sign_in_form(user)
- expect(current_path).to eq(activity_group_path(group))
+ expect(page).to have_current_path(activity_group_path(group), ignore_query: true)
end
end
@@ -98,7 +98,7 @@ RSpec.describe 'Group or Project invitations', :aggregate_failures do
end
it 'shows message user already a member' do
- expect(current_path).to eq(invite_path(group_invite.raw_invite_token))
+ expect(page).to have_current_path(invite_path(group_invite.raw_invite_token), ignore_query: true)
expect(page).to have_link(user.name, href: user_path(user))
expect(page).to have_content('You are already a member of this group.')
end
@@ -127,7 +127,7 @@ RSpec.describe 'Group or Project invitations', :aggregate_failures do
end
it 'declines application and redirects to dashboard' do
- expect(current_path).to eq(dashboard_projects_path)
+ expect(page).to have_current_path(dashboard_projects_path, ignore_query: true)
expect(page).to have_content('You have declined the invitation to join group Owned.')
expect { group_invite.reload }.to raise_error ActiveRecord::RecordNotFound
end
@@ -139,7 +139,7 @@ RSpec.describe 'Group or Project invitations', :aggregate_failures do
end
it 'declines application and redirects to sign in page' do
- expect(current_path).to eq(decline_invite_path(group_invite.raw_invite_token))
+ expect(page).to have_current_path(decline_invite_path(group_invite.raw_invite_token), ignore_query: true)
expect(page).not_to have_content('You have declined the invitation to join')
expect(page).to have_content('You successfully declined the invitation')
expect { group_invite.reload }.to raise_error ActiveRecord::RecordNotFound
@@ -174,7 +174,7 @@ RSpec.describe 'Group or Project invitations', :aggregate_failures do
it 'does not sign the user in' do
fill_in_sign_up_form(new_user)
- expect(current_path).to eq(new_user_session_path)
+ expect(page).to have_current_path(new_user_session_path, ignore_query: true)
expect(page).to have_content('You have signed up successfully. However, we could not sign you in because your account is awaiting approval from your GitLab administrator')
end
end
@@ -186,7 +186,7 @@ RSpec.describe 'Group or Project invitations', :aggregate_failures do
fill_in_sign_up_form(new_user)
fill_in_welcome_form
- expect(current_path).to eq(activity_group_path(group))
+ expect(page).to have_current_path(activity_group_path(group), ignore_query: true)
expect(page).to have_content('You have been granted Owner access to group Owned.')
end
@@ -197,7 +197,7 @@ RSpec.describe 'Group or Project invitations', :aggregate_failures do
fill_in_sign_up_form(new_user)
fill_in_welcome_form
- expect(current_path).to eq(activity_group_path(group))
+ expect(page).to have_current_path(activity_group_path(group), ignore_query: true)
end
end
end
@@ -209,7 +209,7 @@ RSpec.describe 'Group or Project invitations', :aggregate_failures do
it 'fails sign up and redirects back to sign up', :aggregate_failures do
expect { fill_in_sign_up_form(new_user) }.not_to change { User.count }
expect(page).to have_content('prohibited this user from being saved')
- expect(current_path).to eq(user_registration_path)
+ expect(page).to have_current_path(user_registration_path, ignore_query: true)
end
end
@@ -230,7 +230,7 @@ RSpec.describe 'Group or Project invitations', :aggregate_failures do
fill_in_sign_up_form(new_user)
fill_in_welcome_form
- expect(current_path).to eq(activity_group_path(group))
+ expect(page).to have_current_path(activity_group_path(group), ignore_query: true)
end
context 'the user sign-up using a different email address' do
@@ -248,7 +248,7 @@ RSpec.describe 'Group or Project invitations', :aggregate_failures do
fill_in_sign_in_form(new_user)
fill_in_welcome_form
- expect(current_path).to eq(activity_group_path(group))
+ expect(page).to have_current_path(activity_group_path(group), ignore_query: true)
end
end
@@ -262,7 +262,7 @@ RSpec.describe 'Group or Project invitations', :aggregate_failures do
fill_in_sign_up_form(new_user)
fill_in_welcome_form
- expect(current_path).to eq(activity_group_path(group))
+ expect(page).to have_current_path(activity_group_path(group), ignore_query: true)
end
end
end
@@ -273,11 +273,11 @@ RSpec.describe 'Group or Project invitations', :aggregate_failures do
it 'lands on sign up page and then registers' do
visit invite_path(group_invite.raw_invite_token)
- expect(current_path).to eq(new_user_registration_path)
+ expect(page).to have_current_path(new_user_registration_path, ignore_query: true)
fill_in_sign_up_form(new_user, 'Register')
- expect(current_path).to eq(users_sign_up_welcome_path)
+ expect(page).to have_current_path(users_sign_up_welcome_path, ignore_query: true)
end
end
@@ -285,7 +285,7 @@ RSpec.describe 'Group or Project invitations', :aggregate_failures do
it 'declines application and shows a decline page' do
visit decline_invite_path(group_invite.raw_invite_token)
- expect(current_path).to eq(decline_invite_path(group_invite.raw_invite_token))
+ expect(page).to have_current_path(decline_invite_path(group_invite.raw_invite_token), ignore_query: true)
expect(page).to have_content('You successfully declined the invitation')
expect { group_invite.reload }.to raise_error ActiveRecord::RecordNotFound
end
diff --git a/spec/features/issues/filtered_search/dropdown_assignee_spec.rb b/spec/features/issues/filtered_search/dropdown_assignee_spec.rb
index e873ebb21c4..3ba2f7e788d 100644
--- a/spec/features/issues/filtered_search/dropdown_assignee_spec.rb
+++ b/spec/features/issues/filtered_search/dropdown_assignee_spec.rb
@@ -12,14 +12,14 @@ RSpec.describe 'Dropdown assignee', :js do
let(:js_dropdown_assignee) { '#js-dropdown-assignee' }
let(:filter_dropdown) { find("#{js_dropdown_assignee} .filter-dropdown") }
- before do
- project.add_maintainer(user)
- sign_in(user)
+ describe 'behavior' do
+ before do
+ project.add_maintainer(user)
+ sign_in(user)
- visit project_issues_path(project)
- end
+ visit project_issues_path(project)
+ end
- describe 'behavior' do
it 'loads all the assignees when opened' do
input_filtered_search('assignee:=', submit: false, extra_space: false)
@@ -35,6 +35,11 @@ RSpec.describe 'Dropdown assignee', :js do
describe 'selecting from dropdown without Ajax call' do
before do
+ project.add_maintainer(user)
+ sign_in(user)
+
+ visit project_issues_path(project)
+
Gitlab::Testing::RequestBlockerMiddleware.block_requests!
input_filtered_search('assignee:=', submit: false, extra_space: false)
end
@@ -51,4 +56,60 @@ RSpec.describe 'Dropdown assignee', :js do
expect_filtered_search_input_empty
end
end
+
+ context 'assignee suggestions' do
+ let!(:group) { create(:group) }
+ let!(:group_project) { create(:project, namespace: group) }
+ let!(:group_user) { create(:user) }
+
+ let!(:subgroup) { create(:group, parent: group) }
+ let!(:subgroup_project) { create(:project, namespace: subgroup) }
+ let!(:subgroup_project_issue) { create(:issue, project: subgroup_project) }
+ let!(:subgroup_user) { create(:user) }
+
+ let!(:subsubgroup) { create(:group, parent: subgroup) }
+ let!(:subsubgroup_project) { create(:project, namespace: subsubgroup) }
+ let!(:subsubgroup_user) { create(:user) }
+
+ let!(:invited_to_group_group) { create(:group) }
+ let!(:invited_to_group_group_user) { create(:user) }
+
+ let!(:invited_to_project_group) { create(:group) }
+ let!(:invited_to_project_group_user) { create(:user) }
+
+ before do
+ group.add_developer(group_user)
+ subgroup.add_developer(subgroup_user)
+ subsubgroup.add_developer(subsubgroup_user)
+ invited_to_group_group.add_developer(invited_to_group_group_user)
+ invited_to_project_group.add_developer(invited_to_project_group_user)
+
+ create(:group_group_link, shared_group: subgroup, shared_with_group: invited_to_group_group)
+ create(:project_group_link, project: subgroup_project, group: invited_to_project_group)
+
+ sign_in(subgroup_user)
+ end
+
+ it 'shows inherited, direct, and invited group members but not descendent members', :aggregate_failures do
+ visit issues_group_path(subgroup)
+
+ input_filtered_search('assignee:=', submit: false, extra_space: false)
+
+ expect(page).to have_text group_user.name
+ expect(page).to have_text subgroup_user.name
+ expect(page).to have_text invited_to_group_group_user.name
+ expect(page).not_to have_text subsubgroup_user.name
+ expect(page).not_to have_text invited_to_project_group_user.name
+
+ visit project_issues_path(subgroup_project)
+
+ input_filtered_search('assignee:=', submit: false, extra_space: false)
+
+ expect(page).to have_text group_user.name
+ expect(page).to have_text subgroup_user.name
+ expect(page).to have_text invited_to_project_group_user.name
+ expect(page).not_to have_text subsubgroup_user.name
+ expect(page).not_to have_text invited_to_group_group_user.name
+ end
+ end
end
diff --git a/spec/features/issues/filtered_search/filter_issues_spec.rb b/spec/features/issues/filtered_search/filter_issues_spec.rb
index edf3df7c16e..1375384d1aa 100644
--- a/spec/features/issues/filtered_search/filter_issues_spec.rb
+++ b/spec/features/issues/filtered_search/filter_issues_spec.rb
@@ -497,6 +497,8 @@ RSpec.describe 'Filter issues', :js do
end
it 'filters issues by searched text containing special characters' do
+ stub_feature_flags(issues_full_text_search: false)
+
issue = create(:issue, project: project, author: user, title: "issue with !@\#{$%^&*()-+")
search = '!@#{$%^&*()-+'
@@ -514,6 +516,14 @@ RSpec.describe 'Filter issues', :js do
expect_no_issues_list
expect_filtered_search_input(search)
end
+
+ it 'filters issues by issue reference' do
+ search = '#1'
+ input_filtered_search(search)
+
+ expect_issues_list_count(1)
+ expect_filtered_search_input(search)
+ end
end
context 'searched text with other filters' do
diff --git a/spec/features/issues/form_spec.rb b/spec/features/issues/form_spec.rb
index b26f65316c5..0700423983f 100644
--- a/spec/features/issues/form_spec.rb
+++ b/spec/features/issues/form_spec.rb
@@ -5,19 +5,22 @@ require 'spec_helper'
RSpec.describe 'New/edit issue', :js do
include ActionView::Helpers::JavaScriptHelper
- let_it_be(:project) { create(:project) }
+ let_it_be(:project) { create(:project, :repository) }
let_it_be(:user) { create(:user) }
let_it_be(:user2) { create(:user) }
+ let_it_be(:guest) { create(:user) }
let_it_be(:milestone) { create(:milestone, project: project) }
let_it_be(:label) { create(:label, project: project) }
let_it_be(:label2) { create(:label, project: project) }
let_it_be(:issue) { create(:issue, project: project, assignees: [user], milestone: milestone) }
+ let_it_be(:confidential_issue) { create(:issue, project: project, assignees: [user], milestone: milestone, confidential: true) }
let(:current_user) { user }
before_all do
project.add_maintainer(user)
project.add_maintainer(user2)
+ project.add_guest(guest)
end
before do
@@ -184,6 +187,14 @@ RSpec.describe 'New/edit issue', :js do
end
end
+ it 'displays an error message when submitting an invalid form' do
+ click_button 'Create issue'
+
+ page.within('[data-testid="issue-title-input-field"]') do
+ expect(page).to have_text(_('This field is required.'))
+ end
+ end
+
it 'correctly updates the dropdown toggle when removing a label' do
click_button 'Labels'
@@ -310,6 +321,108 @@ RSpec.describe 'New/edit issue', :js do
end
end
+ describe 'new issue with query parameters' do
+ before do
+ project.repository.create_file(
+ current_user,
+ '.gitlab/issue_templates/test_template.md',
+ 'description from template',
+ message: 'Add test_template.md',
+ branch_name: project.default_branch_or_main
+ )
+ end
+
+ after do
+ project.repository.delete_file(
+ current_user,
+ '.gitlab/issue_templates/test_template.md',
+ message: 'Remove test_template.md',
+ branch_name: project.default_branch_or_main
+ )
+ end
+
+ it 'leaves the description blank if no query parameters are specified' do
+ visit new_project_issue_path(project)
+
+ expect(find('#issue_description').value).to be_empty
+ end
+
+ it 'fills the description from the issue[description] query parameter' do
+ visit new_project_issue_path(project, issue: { description: 'description from query parameter' })
+
+ expect(find('#issue_description').value).to match('description from query parameter')
+ end
+
+ it 'fills the description from the issuable_template query parameter' do
+ visit new_project_issue_path(project, issuable_template: 'test_template')
+ wait_for_requests
+
+ expect(find('#issue_description').value).to match('description from template')
+ end
+
+ it 'fills the description from the issuable_template and issue[description] query parameters' do
+ visit new_project_issue_path(project, issuable_template: 'test_template', issue: { description: 'description from query parameter' })
+ wait_for_requests
+
+ expect(find('#issue_description').value).to match('description from template\ndescription from query parameter')
+ end
+ end
+
+ describe 'new issue from related issue' do
+ it 'does not offer to link the new issue to any other issues if the URL parameter is absent' do
+ visit new_project_issue_path(project)
+ expect(page).not_to have_selector '#add_related_issue'
+ expect(page).not_to have_text "Relate to"
+ end
+
+ context 'guest' do
+ let(:current_user) { guest }
+
+ it 'does not offer to link the new issue to an issue that the user does not have access to' do
+ visit new_project_issue_path(project, { add_related_issue: confidential_issue.iid })
+ expect(page).not_to have_selector '#add_related_issue'
+ expect(page).not_to have_text "Relate to"
+ end
+ end
+
+ it 'links the new issue and the issue of origin' do
+ visit new_project_issue_path(project, { add_related_issue: issue.iid })
+ expect(page).to have_selector '#add_related_issue'
+ expect(page).to have_text "Relate to issue \##{issue.iid}"
+ expect(page).to have_text 'Adds this issue as related to the issue it was created from'
+ fill_in 'issue_title', with: 'title'
+ click_button 'Create issue'
+ page.within '#related-issues' do
+ expect(page).to have_text "\##{issue.iid}"
+ end
+ end
+
+ it 'links the new incident and the incident of origin' do
+ incident = create(:incident, project: project)
+ visit new_project_issue_path(project, { add_related_issue: incident.iid })
+ expect(page).to have_selector '#add_related_issue'
+ expect(page).to have_text "Relate to incident \##{incident.iid}"
+ expect(page).to have_text 'Adds this incident as related to the incident it was created from'
+ fill_in 'issue_title', with: 'title'
+ click_button 'Create issue'
+ page.within '#related-issues' do
+ expect(page).to have_text "\##{incident.iid}"
+ end
+ end
+
+ it 'does not link the new issue to any other issues if the checkbox is not checked' do
+ visit new_project_issue_path(project, { add_related_issue: issue.iid })
+ expect(page).to have_selector '#add_related_issue'
+ expect(page).to have_text "Relate to issue \##{issue.iid}"
+ uncheck "Relate to issue \##{issue.iid}"
+ fill_in 'issue_title', with: 'title'
+ click_button 'Create issue'
+ page.within '#related-issues' do
+ expect(page).not_to have_text "\##{issue.iid}"
+ end
+ end
+ end
+
describe 'edit issue' do
before do
visit edit_project_issue_path(project, issue)
diff --git a/spec/features/issues/gfm_autocomplete_spec.rb b/spec/features/issues/gfm_autocomplete_spec.rb
index b4d1b0aeab9..6f4a13c5fad 100644
--- a/spec/features/issues/gfm_autocomplete_spec.rb
+++ b/spec/features/issues/gfm_autocomplete_spec.rb
@@ -111,6 +111,20 @@ RSpec.describe 'GFM autocomplete', :js do
fill_in 'Comment', with: "test\n\n@"
expect(find_autocomplete_menu).to be_visible
end
+
+ it 'does not open label autocomplete menu after strikethrough', :aggregate_failures do
+ fill_in 'Comment', with: "~~"
+ expect(page).not_to have_css('.atwho-view')
+
+ fill_in 'Comment', with: "~~gone~~"
+ expect(page).not_to have_css('.atwho-view')
+
+ fill_in 'Comment', with: "~"
+ expect(find_autocomplete_menu).to be_visible
+
+ fill_in 'Comment', with: "test\n\n~"
+ expect(find_autocomplete_menu).to be_visible
+ end
end
context 'xss checks' do
@@ -406,6 +420,14 @@ RSpec.describe 'GFM autocomplete', :js do
end
end
end
+
+ context 'when typing enter for autocomplete in a markdown list' do
+ it 'does not create a new list item' do
+ fill_in 'Comment', with: "- @#{user.username}\n"
+
+ expect(find_field('Comment').value).to eq "- @#{user.username}\n"
+ end
+ end
end
private
diff --git a/spec/features/issues/incident_issue_spec.rb b/spec/features/issues/incident_issue_spec.rb
index 3033a138551..2956ddede2e 100644
--- a/spec/features/issues/incident_issue_spec.rb
+++ b/spec/features/issues/incident_issue_spec.rb
@@ -38,7 +38,7 @@ RSpec.describe 'Incident Detail', :js do
incident_tabs = find('[data-testid="incident-tabs"]')
aggregate_failures 'shows title and Summary tab' do
- expect(find('h2')).to have_content(incident.title)
+ expect(find('h1')).to have_content(incident.title)
expect(incident_tabs).to have_content('Summary')
expect(incident_tabs).to have_content(incident.description)
end
diff --git a/spec/features/issues/issue_detail_spec.rb b/spec/features/issues/issue_detail_spec.rb
index b37c8e9d1cf..88709d66887 100644
--- a/spec/features/issues/issue_detail_spec.rb
+++ b/spec/features/issues/issue_detail_spec.rb
@@ -17,7 +17,7 @@ RSpec.describe 'Issue Detail', :js do
it 'shows the issue' do
page.within('.issuable-details') do
- expect(find('h2')).to have_content(issue.title)
+ expect(find('h1')).to have_content(issue.title)
end
end
end
@@ -85,7 +85,7 @@ RSpec.describe 'Issue Detail', :js do
it 'shows the issue' do
page.within('.issuable-details') do
- expect(find('h2')).to have_content(issue.reload.title)
+ expect(find('h1')).to have_content(issue.reload.title)
end
end
end
diff --git a/spec/features/issues/issue_header_spec.rb b/spec/features/issues/issue_header_spec.rb
index 3e27ce81860..165015013dd 100644
--- a/spec/features/issues/issue_header_spec.rb
+++ b/spec/features/issues/issue_header_spec.rb
@@ -25,8 +25,8 @@ RSpec.describe 'issue header', :js do
click_button 'Issue actions'
end
- it 'shows the "New issue", "Report abuse", and "Delete issue" items', :aggregate_failures do
- expect(page).to have_link 'New issue'
+ it 'shows the "New related issue", "Report abuse", and "Delete issue" items', :aggregate_failures do
+ expect(page).to have_link 'New related issue'
expect(page).to have_link 'Report abuse'
expect(page).to have_button 'Delete issue'
expect(page).not_to have_link 'Submit as spam'
@@ -114,8 +114,8 @@ RSpec.describe 'issue header', :js do
click_button 'Issue actions'
end
- it 'only shows the "New issue" and "Report abuse" items', :aggregate_failures do
- expect(page).to have_link 'New issue'
+ it 'only shows the "New related issue" and "Report abuse" items', :aggregate_failures do
+ expect(page).to have_link 'New related issue'
expect(page).to have_link 'Report abuse'
expect(page).not_to have_link 'Submit as spam'
expect(page).not_to have_button 'Delete issue'
diff --git a/spec/features/issues/issue_sidebar_spec.rb b/spec/features/issues/issue_sidebar_spec.rb
index 868946814c3..aaa478378a9 100644
--- a/spec/features/issues/issue_sidebar_spec.rb
+++ b/spec/features/issues/issue_sidebar_spec.rb
@@ -106,6 +106,7 @@ RSpec.describe 'Issue Sidebar' do
end
context 'when GraphQL assignees widget feature flag is enabled' do
+ # TODO: Move to shared examples when feature flag is removed: https://gitlab.com/gitlab-org/gitlab/-/issues/328185
context 'when a privileged user can invite' do
it 'shows a link for inviting members and launches invite modal' do
project.add_maintainer(user)
@@ -236,6 +237,12 @@ RSpec.describe 'Issue Sidebar' do
it_behaves_like 'labels sidebar widget'
end
+ context 'escalation status', :js do
+ it 'is not available for default issue type' do
+ expect(page).not_to have_selector('.block.escalation-status')
+ end
+ end
+
context 'interacting with collapsed sidebar', :js do
collapsed_sidebar_selector = 'aside.right-sidebar.right-sidebar-collapsed'
expanded_sidebar_selector = 'aside.right-sidebar.right-sidebar-expanded'
diff --git a/spec/features/issues/move_spec.rb b/spec/features/issues/move_spec.rb
index ee2fbf0865e..054b7b3855b 100644
--- a/spec/features/issues/move_spec.rb
+++ b/spec/features/issues/move_spec.rb
@@ -50,7 +50,7 @@ RSpec.describe 'issue move to another project' do
expect(page).to have_content("Text with #{cross_reference}#{mr.to_reference}")
expect(page).to have_content("moved from #{cross_reference}#{issue.to_reference}")
expect(page).to have_content(issue.title)
- expect(page.current_path).to include project_path(new_project)
+ expect(page).to have_current_path(%r(#{project_path(new_project)}))
end
it 'searching project dropdown', :js do
diff --git a/spec/features/issues/spam_akismet_issue_creation_spec.rb b/spec/features/issues/spam_akismet_issue_creation_spec.rb
new file mode 100644
index 00000000000..4cc4c4cf607
--- /dev/null
+++ b/spec/features/issues/spam_akismet_issue_creation_spec.rb
@@ -0,0 +1,178 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Spam detection on issue creation', :js do
+ include StubENV
+
+ let(:project) { create(:project, :public) }
+ let(:user) { create(:user) }
+
+ include_context 'includes Spam constants'
+
+ before do
+ stub_env('IN_MEMORY_APPLICATION_SETTINGS', 'false')
+
+ Gitlab::CurrentSettings.update!(
+ akismet_enabled: true,
+ akismet_api_key: 'testkey',
+ spam_check_api_key: 'testkey',
+ recaptcha_enabled: true,
+ recaptcha_site_key: 'test site key',
+ recaptcha_private_key: 'test private key'
+ )
+
+ project.add_maintainer(user)
+ sign_in(user)
+ visit new_project_issue_path(project)
+
+ fill_in 'issue_title', with: 'issue title'
+ fill_in 'issue_description', with: 'issue description'
+ end
+
+ shared_examples 'disallows issue creation' do
+ it 'disallows issue creation' do
+ click_button 'Create issue'
+
+ expect(page).to have_content('discarded')
+ expect(page).not_to have_css('.recaptcha')
+ expect(page).not_to have_content('issue title')
+ end
+ end
+
+ shared_examples 'allows issue creation with CAPTCHA' do
+ it 'allows issue creation' do
+ click_button 'Create issue'
+
+ # it is impossible to test reCAPTCHA automatically and there is no possibility to fill in recaptcha
+ # reCAPTCHA verification is skipped in test environment and it always returns true
+ expect(page).not_to have_content('issue title')
+ expect(page).to have_css('.recaptcha')
+
+ click_button 'Create issue'
+
+ expect(page.find('.issue-details h1.title')).to have_content('issue title')
+ expect(page.find('.issue-details .description')).to have_content('issue description')
+ end
+ end
+
+ shared_examples 'allows issue creation without CAPTCHA' do
+ it 'allows issue creation without need to solve CAPTCHA' do
+ click_button 'Create issue'
+
+ expect(page).not_to have_css('.recaptcha')
+ expect(page.find('.issue-details h1.title')).to have_content('issue title')
+ expect(page.find('.issue-details .description')).to have_content('issue description')
+ end
+ end
+
+ shared_examples 'creates a spam_log record' do
+ it 'creates a spam_log record' do
+ expect { click_button 'Create issue' }
+ .to log_spam(title: 'issue title', description: 'issue description', user_id: user.id, noteable_type: 'Issue')
+ end
+ end
+
+ shared_examples 'does not create a spam_log record' do
+ it 'does not creates a spam_log record' do
+ expect { click_button 'Create issue' }
+ .not_to log_spam(title: 'issue title', description: 'issue description', user_id: user.id, noteable_type: 'Issue')
+ end
+ end
+
+ shared_context 'when spammable is identified as possible spam' do
+ before do
+ allow_next_instance_of(Spam::AkismetService) do |akismet_service|
+ allow(akismet_service).to receive(:spam?).and_return(true)
+ end
+ end
+ end
+
+ shared_context 'when spammable is not identified as possible spam' do
+ before do
+ allow_next_instance_of(Spam::AkismetService) do |akismet_service|
+ allow(akismet_service).to receive(:spam?).and_return(false)
+ end
+ end
+ end
+
+ shared_context 'when CAPTCHA is enabled' do
+ before do
+ stub_application_setting(recaptcha_enabled: true)
+ end
+ end
+
+ shared_context 'when CAPTCHA is not enabled' do
+ before do
+ stub_application_setting(recaptcha_enabled: false)
+ end
+ end
+
+ shared_context 'when allow_possible_spam feature flag is true' do
+ before do
+ stub_feature_flags(allow_possible_spam: true)
+ end
+ end
+
+ shared_context 'when allow_possible_spam feature flag is false' do
+ before do
+ stub_feature_flags(allow_possible_spam: false)
+ end
+ end
+
+ describe 'spam handling' do
+ # verdict, spam_flagged, captcha_enabled, allow_possible_spam_flag, creates_spam_log
+ # TODO: Add example for BLOCK_USER verdict when we add support for testing SpamCheck - see https://gitlab.com/groups/gitlab-org/-/epics/5527#lacking-coverage-for-spamcheck-vs-akismet
+ # DISALLOW, true, false, false, true
+ # CONDITIONAL_ALLOW, true, true, false, true
+ # OVERRIDE_VIA_ALLOW_POSSIBLE_SPAM, true, true, true, true
+ # OVERRIDE_VIA_ALLOW_POSSIBLE_SPAM, true, false, true, true
+ # ALLOW, false, true, false, false
+ # TODO: Add example for NOOP verdict when we add support for testing SpamCheck - see https://gitlab.com/groups/gitlab-org/-/epics/5527#lacking-coverage-for-spamcheck-vs-akismet
+
+ context 'DISALLOW: spam_flagged=true, captcha_enabled=true, allow_possible_spam=true' do
+ include_context 'when spammable is identified as possible spam'
+ include_context 'when CAPTCHA is enabled'
+ include_context 'when allow_possible_spam feature flag is true'
+
+ it_behaves_like 'allows issue creation without CAPTCHA'
+ it_behaves_like 'creates a spam_log record'
+ end
+
+ context 'CONDITIONAL_ALLOW: spam_flagged=true, captcha_enabled=true, allow_possible_spam=false' do
+ include_context 'when spammable is identified as possible spam'
+ include_context 'when CAPTCHA is enabled'
+ include_context 'when allow_possible_spam feature flag is false'
+
+ it_behaves_like 'allows issue creation with CAPTCHA'
+ it_behaves_like 'creates a spam_log record'
+ end
+
+ context 'OVERRIDE_VIA_ALLOW_POSSIBLE_SPAM: spam_flagged=true, captcha_enabled=true, allow_possible_spam=true' do
+ include_context 'when spammable is identified as possible spam'
+ include_context 'when CAPTCHA is enabled'
+ include_context 'when allow_possible_spam feature flag is true'
+
+ it_behaves_like 'allows issue creation without CAPTCHA'
+ it_behaves_like 'creates a spam_log record'
+ end
+
+ context 'OVERRIDE_VIA_ALLOW_POSSIBLE_SPAM: spam_flagged=true, captcha_enabled=false, allow_possible_spam=true' do
+ include_context 'when spammable is identified as possible spam'
+ include_context 'when CAPTCHA is not enabled'
+ include_context 'when allow_possible_spam feature flag is true'
+
+ it_behaves_like 'allows issue creation without CAPTCHA'
+ it_behaves_like 'creates a spam_log record'
+ end
+
+ context 'ALLOW: spam_flagged=false, captcha_enabled=true, allow_possible_spam=false' do
+ include_context 'when spammable is not identified as possible spam'
+ include_context 'when CAPTCHA is not enabled'
+ include_context 'when allow_possible_spam feature flag is false'
+
+ it_behaves_like 'allows issue creation without CAPTCHA'
+ it_behaves_like 'does not create a spam_log record'
+ end
+ end
+end
diff --git a/spec/features/issues/spam_issues_spec.rb b/spec/features/issues/spam_issues_spec.rb
deleted file mode 100644
index 70d7deadec3..00000000000
--- a/spec/features/issues/spam_issues_spec.rb
+++ /dev/null
@@ -1,188 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe 'New issue', :js do
- include StubENV
-
- let(:project) { create(:project, :public) }
- let(:user) { create(:user)}
-
- before do
- stub_env('IN_MEMORY_APPLICATION_SETTINGS', 'false')
-
- Gitlab::CurrentSettings.update!(
- akismet_enabled: true,
- akismet_api_key: 'testkey',
- spam_check_api_key: 'testkey',
- recaptcha_enabled: true,
- recaptcha_site_key: 'test site key',
- recaptcha_private_key: 'test private key'
- )
-
- project.add_maintainer(user)
- sign_in(user)
- end
-
- context 'when SpamVerdictService disallows' 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(DISALLOW)
- end
-
- visit new_project_issue_path(project)
- end
-
- context 'when allow_possible_spam feature flag is false' do
- before do
- stub_feature_flags(allow_possible_spam: false)
-
- fill_in 'issue_title', with: 'issue title'
- fill_in 'issue_description', with: 'issue description'
- end
-
- it 'rejects issue creation' do
- click_button 'Create issue'
-
- expect(page).to have_content('discarded')
- expect(page).not_to have_content('potential spam')
- expect(page).not_to have_content('issue title')
- end
-
- it 'creates a spam log record' do
- expect { click_button 'Create issue' }
- .to log_spam(title: 'issue title', description: 'issue description', user_id: user.id, noteable_type: 'Issue')
- end
- end
-
- context 'when allow_possible_spam feature flag is true' do
- before do
- fill_in 'issue_title', with: 'issue title'
- fill_in 'issue_description', with: 'issue description'
- end
-
- it 'allows issue creation' do
- click_button 'Create issue'
-
- expect(page.find('.issue-details h2.title')).to have_content('issue title')
- expect(page.find('.issue-details .description')).to have_content('issue description')
- end
-
- it 'creates a spam log record' do
- expect { click_button 'Create issue' }
- .to log_spam(title: 'issue title', description: 'issue description', user_id: user.id, noteable_type: 'Issue')
- end
- end
- end
-
- context 'when SpamVerdictService requires recaptcha' 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(CONDITIONAL_ALLOW)
- end
-
- visit new_project_issue_path(project)
- end
-
- context 'when recaptcha is enabled' do
- before do
- stub_application_setting(recaptcha_enabled: true)
- end
-
- context 'when allow_possible_spam feature flag is false' do
- before do
- stub_feature_flags(allow_possible_spam: false)
- end
-
- it 'creates an issue after solving reCaptcha' do
- fill_in 'issue_title', with: 'issue title'
- fill_in 'issue_description', with: 'issue description'
-
- click_button 'Create issue'
-
- # it is impossible to test reCAPTCHA automatically and there is no possibility to fill in recaptcha
- # reCAPTCHA verification is skipped in test environment and it always returns true
- expect(page).not_to have_content('issue title')
- expect(page).to have_css('.recaptcha')
-
- click_button 'Create issue'
-
- expect(page.find('.issue-details h2.title')).to have_content('issue title')
- expect(page.find('.issue-details .description')).to have_content('issue description')
- end
- end
-
- context 'when allow_possible_spam feature flag is true' do
- before do
- fill_in 'issue_title', with: 'issue title'
- fill_in 'issue_description', with: 'issue description'
- end
-
- it 'creates an issue without a need to solve reCAPTCHA' do
- click_button 'Create issue'
-
- expect(page).not_to have_css('.recaptcha')
- expect(page.find('.issue-details h2.title')).to have_content('issue title')
- expect(page.find('.issue-details .description')).to have_content('issue description')
- end
-
- it 'creates a spam log record' do
- expect { click_button 'Create issue' }
- .to log_spam(title: 'issue title', description: 'issue description', user_id: user.id, noteable_type: 'Issue')
- end
- end
- end
-
- context 'when reCAPTCHA is not enabled' do
- before do
- stub_application_setting(recaptcha_enabled: false)
- end
-
- context 'when allow_possible_spam feature flag is true' do
- before do
- fill_in 'issue_title', with: 'issue title'
- fill_in 'issue_description', with: 'issue description'
- end
-
- it 'creates an issue without a need to solve reCaptcha' do
- click_button 'Create issue'
-
- expect(page).not_to have_css('.recaptcha')
- expect(page.find('.issue-details h2.title')).to have_content('issue title')
- expect(page.find('.issue-details .description')).to have_content('issue description')
- end
-
- it 'creates a spam log record' do
- expect { click_button 'Create issue' }
- .to log_spam(title: 'issue title', description: 'issue description', user_id: user.id, noteable_type: 'Issue')
- end
- end
- end
- 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)
- end
-
- visit new_project_issue_path(project)
- end
-
- it 'creates an issue' do
- fill_in 'issue_title', with: 'issue title'
- fill_in 'issue_description', with: 'issue description'
-
- click_button 'Create issue'
-
- expect(page.find('.issue-details h2.title')).to have_content('issue title')
- expect(page.find('.issue-details .description')).to have_content('issue description')
- end
- end
-end
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 8c80e19810e..ae1bce7ea4c 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
@@ -85,7 +85,7 @@ RSpec.describe 'User creates branch and merge request on issue page', :js do
wait_for_requests
expect(page).to have_selector('.dropdown-toggle-text ', text: '1-cherry-coloured-funk')
- expect(current_path).to eq project_tree_path(project, '1-cherry-coloured-funk')
+ expect(page).to have_current_path project_tree_path(project, '1-cherry-coloured-funk'), ignore_query: true
end
end
@@ -110,7 +110,7 @@ RSpec.describe 'User creates branch and merge request on issue page', :js do
wait_for_requests
expect(page).to have_selector('.dropdown-toggle-text ', text: branch_name)
- expect(current_path).to eq project_tree_path(project, branch_name)
+ expect(page).to have_current_path project_tree_path(project, branch_name), ignore_query: true
end
end
end
diff --git a/spec/features/issues/user_creates_issue_spec.rb b/spec/features/issues/user_creates_issue_spec.rb
index 37e324e6ded..446f13dc4d0 100644
--- a/spec/features/issues/user_creates_issue_spec.rb
+++ b/spec/features/issues/user_creates_issue_spec.rb
@@ -22,11 +22,11 @@ RSpec.describe "User creates issue" do
click_link "New issue"
end
- expect(current_path).to eq new_user_session_path
+ expect(page).to have_current_path new_user_session_path, ignore_query: true
gitlab_sign_in(create(:user))
- expect(current_path).to eq new_project_issue_path(project)
+ expect(page).to have_current_path new_project_issue_path(project), ignore_query: true
end
end
diff --git a/spec/features/issues/user_sorts_issues_spec.rb b/spec/features/issues/user_sorts_issues_spec.rb
index f3eaff379a1..86bdaf5d706 100644
--- a/spec/features/issues/user_sorts_issues_spec.rb
+++ b/spec/features/issues/user_sorts_issues_spec.rb
@@ -9,9 +9,9 @@ RSpec.describe "User sorts issues" do
let_it_be(:user) { create(:user) }
let_it_be(:group) { create(:group) }
let_it_be(:project) { create(:project_empty_repo, :public, group: group) }
- let_it_be(:issue1, reload: true) { create(:issue, title: 'foo', created_at: Time.now, project: project) }
- let_it_be(:issue2, reload: true) { create(:issue, title: 'bar', created_at: Time.now - 60, project: project) }
- let_it_be(:issue3, reload: true) { create(:issue, title: 'baz', created_at: Time.now - 120, project: project) }
+ let_it_be(:issue1, reload: true) { create(:issue, title: 'foo', created_at: Time.zone.now, project: project) }
+ let_it_be(:issue2, reload: true) { create(:issue, title: 'bar', created_at: Time.zone.now - 60, project: project) }
+ let_it_be(:issue3, reload: true) { create(:issue, title: 'baz', created_at: Time.zone.now - 120, project: project) }
let_it_be(:newer_due_milestone) { create(:milestone, project: project, due_date: '2013-12-11') }
let_it_be(:later_due_milestone) { create(:milestone, project: project, due_date: '2013-12-12') }
@@ -75,7 +75,7 @@ RSpec.describe "User sorts issues" do
end
it 'sorts by most recently updated', :js do
- issue3.updated_at = Time.now + 100
+ issue3.updated_at = Time.zone.now + 100
issue3.save!
visit project_issues_path(project, sort: sort_value_recently_updated)
diff --git a/spec/features/issues/user_views_issue_spec.rb b/spec/features/issues/user_views_issue_spec.rb
index 31bf7649470..eca698bb2f4 100644
--- a/spec/features/issues/user_views_issue_spec.rb
+++ b/spec/features/issues/user_views_issue_spec.rb
@@ -25,7 +25,7 @@ RSpec.describe "User views issue" do
it 'shows the merge request and issue actions', :js, :aggregate_failures do
click_button 'Issue actions'
- expect(page).to have_link('New issue', href: new_project_issue_path(project, { issue: { description: "Related to \##{issue.iid}.\n\n" } }))
+ expect(page).to have_link('New related issue', href: new_project_issue_path(project, { add_related_issue: issue.iid }))
expect(page).to have_button('Create merge request')
expect(page).to have_button('Close issue')
end
diff --git a/spec/features/jira_connect/subscriptions_spec.rb b/spec/features/jira_connect/subscriptions_spec.rb
index e1589ba997e..0b7321bf271 100644
--- a/spec/features/jira_connect/subscriptions_spec.rb
+++ b/spec/features/jira_connect/subscriptions_spec.rb
@@ -3,6 +3,8 @@
require 'spec_helper'
RSpec.describe 'Subscriptions Content Security Policy' do
+ include ContentSecurityPolicyHelpers
+
let(:installation) { create(:jira_connect_installation) }
let(:qsh) { Atlassian::Jwt.create_query_string_hash('https://gitlab.test/subscriptions', 'GET', 'https://gitlab.test') }
let(:jwt) { Atlassian::Jwt.encode({ iss: installation.client_key, qsh: qsh }, installation.shared_secret) }
@@ -11,10 +13,7 @@ RSpec.describe 'Subscriptions Content Security Policy' do
context 'when there is no global config' do
before do
- expect_next_instance_of(JiraConnect::SubscriptionsController) do |controller|
- expect(controller).to receive(:current_content_security_policy)
- .and_return(ActionDispatch::ContentSecurityPolicy.new)
- end
+ setup_csp_for_controller(JiraConnect::SubscriptionsController)
end
it 'does not add CSP directives' do
@@ -31,9 +30,7 @@ RSpec.describe 'Subscriptions Content Security Policy' do
p.style_src :self, 'https://some-cdn.test'
end
- expect_next_instance_of(JiraConnect::SubscriptionsController) do |controller|
- expect(controller).to receive(:current_content_security_policy).and_return(csp)
- end
+ setup_existing_csp_for_controller(JiraConnect::SubscriptionsController, csp)
end
it 'appends to CSP directives' do
diff --git a/spec/features/labels_hierarchy_spec.rb b/spec/features/labels_hierarchy_spec.rb
index 6c8d41fd96f..479199b72b7 100644
--- a/spec/features/labels_hierarchy_spec.rb
+++ b/spec/features/labels_hierarchy_spec.rb
@@ -160,7 +160,7 @@ RSpec.describe 'Labels Hierarchy', :js do
find('.btn-confirm').click
- expect(page.find('.issue-details h2.title')).to have_content('new created issue')
+ expect(page.find('.issue-details h1.title')).to have_content('new created issue')
expect(page).to have_selector('span.gl-label-text', text: grandparent_group_label.title)
expect(page).to have_selector('span.gl-label-text', text: parent_group_label.title)
expect(page).to have_selector('span.gl-label-text', text: project_label_1.title)
@@ -179,38 +179,6 @@ RSpec.describe 'Labels Hierarchy', :js do
it_behaves_like 'assigning labels from sidebar'
end
-
- context 'on project board issue sidebar' do
- let(:board) { create(:board, project: project_1) }
-
- before do
- project_1.add_developer(user)
-
- visit project_board_path(project_1, board)
-
- wait_for_requests
-
- find('.board-card').click
- end
-
- it_behaves_like 'assigning labels from sidebar'
- end
-
- context 'on group board issue sidebar' do
- let(:board) { create(:board, group: parent) }
-
- before do
- parent.add_developer(user)
-
- visit group_board_path(parent, board)
-
- wait_for_requests
-
- find('.board-card').click
- end
-
- it_behaves_like 'assigning labels from sidebar'
- end
end
context 'issuable filtering' do
@@ -242,29 +210,5 @@ RSpec.describe 'Labels Hierarchy', :js do
it_behaves_like 'filtering by ancestor labels for groups'
end
-
- context 'on project boards filter' do
- let(:board) { create(:board, project: project_1) }
-
- before do
- project_1.add_developer(user)
-
- visit project_board_path(project_1, board)
- end
-
- it_behaves_like 'filtering by ancestor labels for projects', true
- end
-
- context 'on group boards filter' do
- let(:board) { create(:board, group: parent) }
-
- before do
- parent.add_developer(user)
-
- visit group_board_path(parent, board)
- end
-
- it_behaves_like 'filtering by ancestor labels for groups', true
- end
end
end
diff --git a/spec/features/markdown/copy_as_gfm_spec.rb b/spec/features/markdown/copy_as_gfm_spec.rb
index 6951d8298e5..d472134a2c7 100644
--- a/spec/features/markdown/copy_as_gfm_spec.rb
+++ b/spec/features/markdown/copy_as_gfm_spec.rb
@@ -7,10 +7,6 @@ RSpec.describe 'Copy as GFM', :js do
include RepoHelpers
include ActionView::Helpers::JavaScriptHelper
- before do
- stub_feature_flags(refactor_blob_viewer: false) # This stub will be removed in https://gitlab.com/gitlab-org/gitlab/-/issues/350454
- end
-
describe 'Copying rendered GFM' do
before do
@feat = MarkdownFeature.new
@@ -764,8 +760,8 @@ RSpec.describe 'Copy as GFM', :js do
context 'selecting one word of text' do
it 'copies as inline code' do
verify(
- '.line[id="LC9"] .no',
- '`RuntimeError`'
+ '.line[id="LC10"]',
+ '`end`'
)
end
end
@@ -834,6 +830,7 @@ RSpec.describe 'Copy as GFM', :js do
end
def verify(selector, gfm, target: nil)
+ expect(page).to have_selector('.js-syntax-highlight')
html = html_for_selector(selector)
output_gfm = html_to_gfm(html, 'transformCodeSelection', target: target)
wait_for_requests
diff --git a/spec/features/markdown/keyboard_shortcuts_spec.rb b/spec/features/markdown/keyboard_shortcuts_spec.rb
index 81b1928658c..82288af1f9f 100644
--- a/spec/features/markdown/keyboard_shortcuts_spec.rb
+++ b/spec/features/markdown/keyboard_shortcuts_spec.rb
@@ -37,6 +37,14 @@ RSpec.describe 'Markdown keyboard shortcuts', :js do
expect(markdown_field.value).to eq('_italic_')
end
+ it 'strikes text when <modifier>+<shift>+x is pressed' do
+ type_and_select('strikethrough')
+
+ markdown_field.send_keys([modifier_key, :shift, 'x'])
+
+ expect(markdown_field.value).to eq('~~strikethrough~~')
+ end
+
it 'links text when <modifier>+K is pressed' do
type_and_select('link')
diff --git a/spec/features/markdown/sandboxed_mermaid_spec.rb b/spec/features/markdown/sandboxed_mermaid_spec.rb
index f118fb3db66..05fe83b3107 100644
--- a/spec/features/markdown/sandboxed_mermaid_spec.rb
+++ b/spec/features/markdown/sandboxed_mermaid_spec.rb
@@ -26,7 +26,7 @@ RSpec.describe 'Sandboxed Mermaid rendering', :js do
wait_for_requests
- expected = %(<iframe src="/-/sandbox/mermaid" sandbox="allow-scripts" frameborder="0" scrolling="no")
+ expected = %(<iframe src="/-/sandbox/mermaid" sandbox="allow-scripts allow-popups" frameborder="0" scrolling="no")
expect(page.html).to include(expected)
end
end
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 5894ec923c2..92b9b785148 100644
--- a/spec/features/merge_request/user_edits_assignees_sidebar_spec.rb
+++ b/spec/features/merge_request/user_edits_assignees_sidebar_spec.rb
@@ -17,66 +17,172 @@ RSpec.describe 'Merge request > User edits assignees sidebar', :js do
let(:sidebar_assignee_block) { page.find('.js-issuable-sidebar .assignee') }
let(:sidebar_assignee_avatar_link) { sidebar_assignee_block.find_all('a').find { |a| a['href'].include? assignee.username } }
let(:sidebar_assignee_tooltip) { sidebar_assignee_avatar_link['title'] || '' }
- 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'] || '' }
- context 'when user is an owner' do
+ context 'when GraphQL assignees widget feature flag is disabled' 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)
+ stub_feature_flags(issue_assignees_widget: false)
+ end
- sign_in(project.first_owner)
+ context 'when user is an owner' do
+ before do
+ stub_const('Autocomplete::UsersFinder::LIMIT', users_find_limit)
- merge_request.assignees << assignee
+ sign_in(project.first_owner)
- visit project_merge_request_path(project, merge_request)
+ merge_request.assignees << assignee
- wait_for_requests
+ visit project_merge_request_path(project, merge_request)
+
+ 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
+ end
+ end
+
+ context 'when assigned to maintainer' do
+ let(:assignee) { project_maintainers.last }
+
+ it_behaves_like 'when assigned', expected_tooltip: ''
+ end
+
+ context 'when assigned to developer' do
+ let(:assignee) { project_developers.last }
+
+ it_behaves_like 'when assigned', expected_tooltip: 'Cannot merge'
+ end
end
- shared_examples 'when assigned' do |expected_tooltip: ''|
- it 'shows assignee name' do
- expect(sidebar_assignee_block).to have_text(assignee.name)
+ context 'with invite members considerations' do
+ let_it_be(:user) { create(:user) }
+
+ before do
+ sign_in(user)
end
- it "shows assignee tooltip '#{expected_tooltip}'" do
- expect(sidebar_assignee_tooltip).to eql(expected_tooltip)
+ include_examples 'issuable invite members' do
+ let(:issuable_path) { project_merge_request_path(project, merge_request) }
end
+ end
+ end
+
+ context 'when GraphQL assignees widget feature flag is enabled' do
+ let(:sidebar_assignee_dropdown_item) { sidebar_assignee_block.find(".dropdown-item", text: assignee.username ) }
+ let(:sidebar_assignee_dropdown_tooltip) { sidebar_assignee_dropdown_item['title']}
+
+ context 'when user is an owner' do
+ before do
+ stub_const('Autocomplete::UsersFinder::LIMIT', users_find_limit)
+
+ sign_in(project.first_owner)
+
+ merge_request.assignees << assignee
- context 'when edit is clicked' do
- before do
- sidebar_assignee_block.click_link('Edit')
+ visit project_merge_request_path(project, merge_request)
- wait_for_requests
+ 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_dropdown_tooltip).to eql(expected_tooltip)
+ it "shows assignee tooltip '#{expected_tooltip}'" do
+ expect(sidebar_assignee_tooltip).to eql(expected_tooltip)
+ end
+
+ context 'when edit is clicked' do
+ before do
+ open_assignees_dropdown
+ end
+
+ it "shows assignee tooltip '#{expected_tooltip}" do
+ expect(sidebar_assignee_dropdown_tooltip).to eql(expected_tooltip)
+ end
end
end
- end
- context 'when assigned to maintainer' do
- let(:assignee) { project_maintainers.last }
+ context 'when assigned to maintainer' do
+ let(:assignee) { project_maintainers.last }
- it_behaves_like 'when assigned', expected_tooltip: ''
- end
+ it_behaves_like 'when assigned', expected_tooltip: ''
+ end
- context 'when assigned to developer' do
- let(:assignee) { project_developers.last }
+ context 'when assigned to developer' do
+ let(:assignee) { project_developers.last }
- it_behaves_like 'when assigned', expected_tooltip: 'Cannot merge'
+ it_behaves_like 'when assigned', expected_tooltip: 'Cannot merge'
+ end
end
- end
- context 'with invite members considerations' do
- let_it_be(:user) { create(:user) }
+ context 'with invite members considerations' do
+ let_it_be(:user) { create(:user) }
- before do
- sign_in(user)
+ before do
+ sign_in(user)
+ end
+
+ # TODO: Move to shared examples when feature flag is removed: https://gitlab.com/gitlab-org/gitlab/-/issues/328185
+ context 'when a privileged user can invite' do
+ it 'shows a link for inviting members and launches invite modal' do
+ project.add_maintainer(user)
+ visit project_merge_request_path(project, merge_request)
+
+ open_assignees_dropdown
+
+ page.within '.dropdown-menu-user' do
+ expect(page).to have_link('Invite members')
+ expect(page).to have_selector('[data-track-action="click_invite_members"]')
+ expect(page).to have_selector('[data-track-label="edit_assignee"]')
+ end
+
+ click_link 'Invite members'
+
+ expect(page).to have_content("You're inviting members to the")
+ end
+ end
+
+ context 'when user cannot invite members in assignee dropdown' do
+ it 'shows author in assignee dropdown and no invite link' do
+ project.add_developer(user)
+ visit project_merge_request_path(project, merge_request)
+
+ open_assignees_dropdown
+
+ page.within '.dropdown-menu-user' do
+ expect(page).not_to have_link('Invite members')
+ end
+ end
+ end
end
+ end
- include_examples 'issuable invite members' do
- let(:issuable_path) { project_merge_request_path(project, merge_request) }
+ def open_assignees_dropdown
+ page.within('.assignee') do
+ click_button('Edit')
+ wait_for_requests
end
end
end
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 8343e04aef1..231722c166d 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
@@ -140,7 +140,7 @@ RSpec.describe 'Merge request > User resolves diff notes and threads', :js do
describe 'reply form' do
before do
- click_button 'Toggle thread'
+ click_button _('Show thread')
end
it 'allows user to comment' do
@@ -362,7 +362,7 @@ RSpec.describe 'Merge request > User resolves diff notes and threads', :js do
it 'displays next thread even if hidden' do
page.all('.note-discussion', count: 2).each do |discussion|
page.within discussion do
- click_button 'Toggle thread'
+ click_button _('Hide thread')
end
end
@@ -549,13 +549,13 @@ RSpec.describe 'Merge request > User resolves diff notes and threads', :js do
it 'shows resolved icon' do
expect(page).to have_content 'All threads resolved'
- click_button 'Toggle thread'
+ click_button _('Show thread')
expect(page).to have_selector('.line-resolve-btn.is-active')
end
it 'does not allow user to click resolve button' do
expect(page).to have_selector('.line-resolve-btn.is-active')
- click_button 'Toggle thread'
+ click_button _('Show thread')
expect(page).to have_selector('.line-resolve-btn.is-active')
end
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 33c5a936b8d..fca40dc7edc 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
@@ -25,6 +25,7 @@ RSpec.describe 'Merge request > User sees avatars on diff notes', :js do
before do
project.add_maintainer(user)
sign_in user
+ stub_feature_flags(gl_avatar_for_all_user_avatars: false)
set_cookie('sidebar_collapsed', 'true')
end
diff --git a/spec/features/merge_request/user_sees_diff_spec.rb b/spec/features/merge_request/user_sees_diff_spec.rb
index 7cd9ef80874..50f4cce5c23 100644
--- a/spec/features/merge_request/user_sees_diff_spec.rb
+++ b/spec/features/merge_request/user_sees_diff_spec.rb
@@ -45,8 +45,8 @@ RSpec.describe 'Merge request > User sees diff', :js do
visit diffs_project_merge_request_path(project, merge_request)
- page.within('.alert') do
- expect(page).to have_text("Too many changes to show. Plain diff Email patch To preserve performance only 3 of 3+ files are displayed.")
+ page.within('.gl-alert') do
+ expect(page).to have_text("Too many changes to show. To preserve performance only 3 of 3+ files are displayed. Plain diff Email patch")
end
end
end
@@ -69,7 +69,7 @@ RSpec.describe 'Merge request > User sees diff', :js do
end
context 'as user who needs to fork' do
- it 'shows fork/cancel confirmation', :sidekiq_might_not_need_inline do
+ it 'shows fork/cancel confirmation', :sidekiq_might_not_need_inline, quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/337477' do
sign_in(user)
visit diffs_project_merge_request_path(project, merge_request)
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 2a49109d360..09c6b6bce3b 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
@@ -25,6 +25,8 @@ RSpec.describe 'Merge request > User sees pipelines triggered by merge request',
}
end
+ let(:expected_detached_mr_tag) {'merge request'}
+
before do
stub_application_setting(auto_devops_enabled: false)
stub_ci_pipeline_yaml_file(YAML.dump(config))
@@ -118,16 +120,16 @@ RSpec.describe 'Merge request > User sees pipelines triggered by merge request',
it 'sees detached tag for detached merge request pipelines' do
page.within('.ci-table') do
expect(all('.pipeline-tags')[0])
- .to have_content("detached")
+ .to have_content(expected_detached_mr_tag)
expect(all('.pipeline-tags')[1])
- .to have_content("detached")
+ .to have_content(expected_detached_mr_tag)
expect(all('.pipeline-tags')[2])
- .not_to have_content("detached")
+ .not_to have_content(expected_detached_mr_tag)
expect(all('.pipeline-tags')[3])
- .not_to have_content("detached")
+ .not_to have_content(expected_detached_mr_tag)
end
end
@@ -312,16 +314,16 @@ RSpec.describe 'Merge request > User sees pipelines triggered by merge request',
it 'sees detached tag for detached merge request pipelines' do
page.within('.ci-table') do
expect(all('.pipeline-tags')[0])
- .to have_content("detached")
+ .to have_content(expected_detached_mr_tag)
expect(all('.pipeline-tags')[1])
- .to have_content("detached")
+ .to have_content(expected_detached_mr_tag)
expect(all('.pipeline-tags')[2])
- .not_to have_content("detached")
+ .not_to have_content(expected_detached_mr_tag)
expect(all('.pipeline-tags')[3])
- .not_to have_content("detached")
+ .not_to have_content(expected_detached_mr_tag)
end
end
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 872507c3b7a..27f7c699c50 100644
--- a/spec/features/merge_request/user_sees_merge_widget_spec.rb
+++ b/spec/features/merge_request/user_sees_merge_widget_spec.rb
@@ -96,10 +96,7 @@ RSpec.describe 'Merge request > User sees merge widget', :js do
context 'view merge request with external CI service' do
before do
- create(:integration, project: project,
- active: true,
- type: 'DroneCiService',
- category: 'ci')
+ create(:drone_ci_integration, project: project)
visit project_merge_request_path(project, merge_request)
end
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 e5592ae9535..23b03e33f5d 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
@@ -137,7 +137,7 @@ RSpec.describe 'Merge request < User sees mini pipeline graph', :js do
build_item.click
find('.build-page')
- expect(current_path).to eql(project_job_path(project, build))
+ expect(page).to have_current_path(project_job_path(project, build), ignore_query: true)
end
it 'shows tooltip when hovered' do
diff --git a/spec/features/merge_request/user_sees_pipelines_spec.rb b/spec/features/merge_request/user_sees_pipelines_spec.rb
index 266ae0d8c37..9696b1ff551 100644
--- a/spec/features/merge_request/user_sees_pipelines_spec.rb
+++ b/spec/features/merge_request/user_sees_pipelines_spec.rb
@@ -125,7 +125,6 @@ RSpec.describe 'Merge request > User sees pipelines', :js do
before do
stub_feature_flags(ci_disallow_to_create_merge_request_pipelines_in_target_project: false)
- stub_feature_flags(rearrange_pipelines_table: false)
end
it 'creates a pipeline in the parent project when user proceeds with the warning' do
@@ -186,7 +185,7 @@ RSpec.describe 'Merge request > User sees pipelines', :js do
page.within(first('.commit')) do
page.within('.pipeline-tags') do
expect(page.find('[data-testid="pipeline-url-link"]')[:href]).to include(expected_project.full_path)
- expect(page).to have_content('detached')
+ expect(page).to have_content('merge request')
end
page.within('.pipeline-triggerer') do
expect(page).to have_link(href: user_path(actor))
@@ -232,7 +231,7 @@ RSpec.describe 'Merge request > User sees pipelines', :js do
sign_in user
end
- context 'when pipeline and merge request were created simultaneously' do
+ context 'when pipeline and merge request were created simultaneously', :delete do
before do
stub_ci_pipeline_to_return_yaml_file
diff --git a/spec/features/merge_request/user_sees_suggest_pipeline_spec.rb b/spec/features/merge_request/user_sees_suggest_pipeline_spec.rb
index 2191849edd9..448ef750508 100644
--- a/spec/features/merge_request/user_sees_suggest_pipeline_spec.rb
+++ b/spec/features/merge_request/user_sees_suggest_pipeline_spec.rb
@@ -42,9 +42,6 @@ RSpec.describe 'Merge request > User sees suggest pipeline', :js do
wait_for_requests
- # Drawer is open
- expect(page).to have_content('This template creates a simple test pipeline. To use it:')
-
# Editor shows template
expect(page).to have_content('This file is a template, and might need editing before it works on your project.')
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 f96717970bf..8c1d9dd38b0 100644
--- a/spec/features/merge_requests/user_lists_merge_requests_spec.rb
+++ b/spec/features/merge_requests/user_lists_merge_requests_spec.rb
@@ -77,7 +77,7 @@ RSpec.describe 'Merge requests > User lists merge requests' do
it 'filters on no assignee' do
visit_merge_requests(project, assignee_id: IssuableFinder::Params::FILTER_NONE)
- expect(current_path).to eq(project_merge_requests_path(project))
+ expect(page).to have_current_path(project_merge_requests_path(project), ignore_query: true)
expect(page).to have_content 'merge-test'
expect(page).to have_content 'feature'
expect(page).not_to have_content 'fix'
diff --git a/spec/features/milestones/user_views_milestones_spec.rb b/spec/features/milestones/user_views_milestones_spec.rb
index 58439df92ba..752cc63486f 100644
--- a/spec/features/milestones/user_views_milestones_spec.rb
+++ b/spec/features/milestones/user_views_milestones_spec.rb
@@ -28,7 +28,7 @@ RSpec.describe "User views milestones" do
it "opens milestone" do
click_link(milestone.title)
- expect(current_path).to eq(project_milestone_path(project, milestone))
+ expect(page).to have_current_path(project_milestone_path(project, milestone), ignore_query: true)
expect(page).to have_content(milestone.title)
.and have_selector("#tab-issues li.issuable-row", count: 2)
.and have_content(issue.title)
@@ -85,7 +85,7 @@ RSpec.describe "User views milestones with no MR" do
it "opens milestone" do
click_link(milestone.title)
- expect(current_path).to eq(project_milestone_path(project, milestone))
+ expect(page).to have_current_path(project_milestone_path(project, milestone), ignore_query: true)
expect(page).to have_content(milestone.title)
.and have_selector("#tab-issues")
.and have_no_selector("#tab-merge-requests")
diff --git a/spec/features/oauth_login_spec.rb b/spec/features/oauth_login_spec.rb
index 0ea14bc00a5..93674057fed 100644
--- a/spec/features/oauth_login_spec.rb
+++ b/spec/features/oauth_login_spec.rb
@@ -45,7 +45,7 @@ RSpec.describe 'OAuth Login', :js, :allow_forgery_protection do
it 'logs the user in' do
login_with_provider(provider, additional_info: additional_info)
- expect(current_path).to eq root_path
+ expect(page).to have_current_path root_path, ignore_query: true
end
end
@@ -55,19 +55,19 @@ RSpec.describe 'OAuth Login', :js, :allow_forgery_protection do
it 'logs the user in' do
login_with_provider(provider, additional_info: additional_info, enter_two_factor: true)
- expect(current_path).to eq root_path
+ expect(page).to have_current_path root_path, ignore_query: true
end
it 'when bypass-two-factor is enabled' do
allow(Gitlab.config.omniauth).to receive_messages(allow_bypass_two_factor: true)
login_via(provider.to_s, user, uid, remember_me: false, additional_info: additional_info)
- expect(current_path).to eq root_path
+ expect(page).to have_current_path root_path, ignore_query: true
end
it 'when bypass-two-factor is disabled' do
allow(Gitlab.config.omniauth).to receive_messages(allow_bypass_two_factor: false)
login_with_provider(provider, enter_two_factor: true, additional_info: additional_info)
- expect(current_path).to eq root_path
+ expect(page).to have_current_path root_path, ignore_query: true
end
end
@@ -81,7 +81,7 @@ RSpec.describe 'OAuth Login', :js, :allow_forgery_protection do
clear_browser_session
visit(root_path)
- expect(current_path).to eq root_path
+ expect(page).to have_current_path root_path, ignore_query: true
end
end
@@ -94,7 +94,7 @@ RSpec.describe 'OAuth Login', :js, :allow_forgery_protection do
clear_browser_session
visit(root_path)
- expect(current_path).to eq root_path
+ expect(page).to have_current_path root_path, ignore_query: true
end
end
end
@@ -107,7 +107,7 @@ RSpec.describe 'OAuth Login', :js, :allow_forgery_protection do
clear_browser_session
visit(root_path)
- expect(current_path).to eq new_user_session_path
+ expect(page).to have_current_path new_user_session_path, ignore_query: true
end
end
@@ -120,7 +120,7 @@ RSpec.describe 'OAuth Login', :js, :allow_forgery_protection do
clear_browser_session
visit(root_path)
- expect(current_path).to eq new_user_session_path
+ expect(page).to have_current_path new_user_session_path, ignore_query: true
end
end
end
diff --git a/spec/features/password_reset_spec.rb b/spec/features/password_reset_spec.rb
index 322ccc6a0c0..a4e167a3e75 100644
--- a/spec/features/password_reset_spec.rb
+++ b/spec/features/password_reset_spec.rb
@@ -9,7 +9,7 @@ RSpec.describe 'Password reset' do
forgot_password(user)
expect(page).to have_content(I18n.t('devise.passwords.send_paranoid_instructions'))
- expect(current_path).to eq new_user_session_path
+ expect(page).to have_current_path new_user_session_path, ignore_query: true
expect(user.recently_sent_password_reset?).to be_truthy
end
@@ -20,7 +20,7 @@ RSpec.describe 'Password reset' do
expect { forgot_password(user) }.to change { user.reset_password_sent_at }
expect(page).to have_content(I18n.t('devise.passwords.send_paranoid_instructions'))
- expect(current_path).to eq new_user_session_path
+ expect(page).to have_current_path new_user_session_path, ignore_query: true
end
it 'throttles multiple resets in a short timespan' do
@@ -31,7 +31,7 @@ RSpec.describe 'Password reset' do
expect { forgot_password(user) }.not_to change { user.reset_password_sent_at }
expect(page).to have_content(I18n.t('devise.passwords.send_paranoid_instructions'))
- expect(current_path).to eq new_user_session_path
+ expect(page).to have_current_path new_user_session_path, ignore_query: true
end
end
@@ -50,7 +50,7 @@ RSpec.describe 'Password reset' do
click_button 'Change your password'
expect(page).to have_content(I18n.t('devise.passwords.updated_not_active'))
- expect(current_path).to eq new_user_session_path
+ expect(page).to have_current_path new_user_session_path, ignore_query: true
end
end
diff --git a/spec/features/profiles/account_spec.rb b/spec/features/profiles/account_spec.rb
index 2e8d9ef80cd..6a4a1fca008 100644
--- a/spec/features/profiles/account_spec.rb
+++ b/spec/features/profiles/account_spec.rb
@@ -50,14 +50,14 @@ RSpec.describe 'Profile > Account', :js do
it 'the user is accessible via the new path' do
update_username(new_username)
visit new_user_path
- expect(current_path).to eq(new_user_path)
+ expect(page).to have_current_path(new_user_path, ignore_query: true)
expect(find('.user-info')).to have_content(new_username)
end
it 'the old user path redirects to the new path' do
update_username(new_username)
visit old_user_path
- expect(current_path).to eq(new_user_path)
+ expect(page).to have_current_path(new_user_path, ignore_query: true)
expect(find('.user-info')).to have_content(new_username)
end
@@ -77,14 +77,14 @@ RSpec.describe 'Profile > Account', :js do
it 'the project is accessible via the new path' do
update_username(new_username)
visit new_project_path
- expect(current_path).to eq(new_project_path)
+ expect(page).to have_current_path(new_project_path, ignore_query: true)
expect(find('.breadcrumbs')).to have_content(user.name)
end
it 'the old project path redirects to the new path' do
update_username(new_username)
visit old_project_path
- expect(current_path).to eq(new_project_path)
+ expect(page).to have_current_path(new_project_path, ignore_query: true)
expect(find('.breadcrumbs')).to have_content(user.name)
end
end
diff --git a/spec/features/profiles/chat_names_spec.rb b/spec/features/profiles/chat_names_spec.rb
index b392d8dfa8e..82134de582a 100644
--- a/spec/features/profiles/chat_names_spec.rb
+++ b/spec/features/profiles/chat_names_spec.rb
@@ -28,7 +28,7 @@ RSpec.describe 'Profile > Chat' do
end
it 'goes to list of chat names and see chat account' do
- expect(page.current_path).to eq(profile_chat_names_path)
+ expect(page).to have_current_path(profile_chat_names_path, ignore_query: true)
expect(page).to have_content('my_chat_team')
expect(page).to have_content('my_chat_user')
end
@@ -46,7 +46,7 @@ RSpec.describe 'Profile > Chat' do
end
it 'goes to list of chat names and do not see chat account' do
- expect(page.current_path).to eq(profile_chat_names_path)
+ expect(page).to have_current_path(profile_chat_names_path, ignore_query: true)
expect(page).not_to have_content('my_chat_team')
expect(page).not_to have_content('my_chat_user')
end
diff --git a/spec/features/profiles/password_spec.rb b/spec/features/profiles/password_spec.rb
index 898e2c2aa59..2181285f771 100644
--- a/spec/features/profiles/password_spec.rb
+++ b/spec/features/profiles/password_spec.rb
@@ -104,7 +104,7 @@ RSpec.describe 'Profile > Password' do
expect(user.failed_attempts).to eq(1)
expect(user.valid_password?(new_password)).to eq(false)
- expect(current_path).to eq(edit_profile_password_path)
+ expect(page).to have_current_path(edit_profile_password_path, ignore_query: true)
page.within '.flash-container' do
expect(page).to have_content('You must provide a valid current password')
@@ -116,7 +116,7 @@ RSpec.describe 'Profile > Password' do
subject
- expect(current_path).to eq(new_user_session_path)
+ expect(page).to have_current_path(new_user_session_path, ignore_query: true)
page.within '.flash-container' do
expect(page).to have_content('Your account is locked.')
@@ -146,7 +146,7 @@ RSpec.describe 'Profile > Password' do
it 'changes the password, logs the user out and prompts them to sign in again', :aggregate_failures do
expect { subject }.to change { user.reload.valid_password?(new_password) }.to(true)
- expect(current_path).to eq new_user_session_path
+ expect(page).to have_current_path new_user_session_path, ignore_query: true
page.within '.flash-container' do
expect(page).to have_content('Password was successfully updated. Please sign in again.')
@@ -167,14 +167,14 @@ RSpec.describe 'Profile > Password' do
it 'needs change user password' do
visit edit_profile_password_path
- expect(current_path).to eq new_profile_password_path
+ expect(page).to have_current_path new_profile_password_path, ignore_query: true
fill_in :user_password, with: user.password
fill_in :user_new_password, with: Gitlab::Password.test_default
fill_in :user_password_confirmation, with: Gitlab::Password.test_default
click_button 'Set new password'
- expect(current_path).to eq new_user_session_path
+ expect(page).to have_current_path new_user_session_path, ignore_query: true
end
context 'when global require_two_factor_authentication is enabled' do
@@ -183,7 +183,7 @@ RSpec.describe 'Profile > Password' do
visit profile_path
- expect(current_path).to eq new_profile_password_path
+ expect(page).to have_current_path new_profile_password_path, ignore_query: true
end
end
end
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 da63f7c0f41..e19e29bf63a 100644
--- a/spec/features/profiles/user_visits_profile_preferences_page_spec.rb
+++ b/spec/features/profiles/user_visits_profile_preferences_page_spec.rb
@@ -55,12 +55,12 @@ RSpec.describe 'User visits the profile preferences page', :js do
find('#logo').click
expect(page).to have_content("You don't have starred projects yet")
- expect(page.current_path).to eq starred_dashboard_projects_path
+ expect(page).to have_current_path starred_dashboard_projects_path, ignore_query: true
find('.shortcuts-activity').click
expect(page).not_to have_content("You don't have starred projects yet")
- expect(page.current_path).to eq dashboard_projects_path
+ expect(page).to have_current_path dashboard_projects_path, ignore_query: true
end
end
diff --git a/spec/features/profiles/user_visits_profile_spec.rb b/spec/features/profiles/user_visits_profile_spec.rb
index d90ac439eee..7d545711997 100644
--- a/spec/features/profiles/user_visits_profile_spec.rb
+++ b/spec/features/profiles/user_visits_profile_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
RSpec.describe 'User visits their profile' do
- let(:user) { create(:user) }
+ let_it_be_with_refind(:user) { create(:user) }
before do
sign_in(user)
@@ -87,4 +87,53 @@ RSpec.describe 'User visits their profile' do
end
end
end
+
+ describe 'storage_enforcement_banner', :js do
+ context 'with storage_enforcement_date set' do
+ let_it_be(:storage_enforcement_date) { Date.today + 30 }
+
+ before do
+ allow_next_found_instance_of(Namespaces::UserNamespace) do |g|
+ allow(g).to receive(:storage_enforcement_date).and_return(storage_enforcement_date)
+ end
+ end
+
+ it 'displays the banner in the profile page' do
+ visit(profile_path)
+ expect_page_to_have_storage_enforcement_banner(storage_enforcement_date)
+ end
+
+ it 'does not display the banner if user has previously closed unless threshold has changed' do
+ visit(profile_path)
+ expect_page_to_have_storage_enforcement_banner(storage_enforcement_date)
+ find('.js-storage-enforcement-banner [data-testid="close-icon"]').click
+ page.refresh
+ expect_page_not_to_have_storage_enforcement_banner
+
+ storage_enforcement_date = Date.today + 13
+ allow_next_found_instance_of(Namespaces::UserNamespace) do |g|
+ allow(g).to receive(:storage_enforcement_date).and_return(storage_enforcement_date)
+ end
+ page.refresh
+ expect_page_to_have_storage_enforcement_banner(storage_enforcement_date)
+ end
+ end
+
+ context 'with storage_enforcement_date not set' do
+ # This test should break and be rewritten after the implementation of the storage_enforcement_date
+ # TBD: https://gitlab.com/gitlab-org/gitlab/-/issues/350632
+ it 'does not display the banner in the group page' do
+ visit(profile_path)
+ expect_page_not_to_have_storage_enforcement_banner
+ end
+ end
+ end
+
+ def expect_page_to_have_storage_enforcement_banner(storage_enforcement_date)
+ expect(page).to have_text "From #{storage_enforcement_date} storage limits will apply to this namespace"
+ end
+
+ def expect_page_not_to_have_storage_enforcement_banner
+ expect(page).not_to have_text "storage limits will apply to this namespace"
+ end
end
diff --git a/spec/features/projects/artifacts/file_spec.rb b/spec/features/projects/artifacts/file_spec.rb
index b61ee623fec..f97c1b0e543 100644
--- a/spec/features/projects/artifacts/file_spec.rb
+++ b/spec/features/projects/artifacts/file_spec.rb
@@ -73,7 +73,7 @@ RSpec.describe 'Artifact file', :js do
end
it "redirects to new URL" do
- expect(page.current_path).to eq(file_url)
+ expect(page).to have_current_path(file_url, ignore_query: true)
end
end
end
diff --git a/spec/features/projects/artifacts/raw_spec.rb b/spec/features/projects/artifacts/raw_spec.rb
index d580262d48b..c10cb56a44b 100644
--- a/spec/features/projects/artifacts/raw_spec.rb
+++ b/spec/features/projects/artifacts/raw_spec.rb
@@ -21,7 +21,7 @@ RSpec.describe 'Raw artifact' do
end
it "redirects to new URL" do
- expect(page.current_path).to eq(raw_url)
+ expect(page).to have_current_path(raw_url, ignore_query: true)
end
end
end
diff --git a/spec/features/projects/artifacts/user_browses_artifacts_spec.rb b/spec/features/projects/artifacts/user_browses_artifacts_spec.rb
index 77e3c7f972d..2d09f5a4263 100644
--- a/spec/features/projects/artifacts/user_browses_artifacts_spec.rb
+++ b/spec/features/projects/artifacts/user_browses_artifacts_spec.rb
@@ -12,7 +12,7 @@ RSpec.describe "User browses artifacts" do
it "redirects to new URL" do
visit(browse_url.sub("/-/jobs", "/builds"))
- expect(page.current_path).to eq(browse_url)
+ expect(page).to have_current_path(browse_url, ignore_query: true)
end
end
diff --git a/spec/features/projects/blobs/blob_show_spec.rb b/spec/features/projects/blobs/blob_show_spec.rb
index 77194fd6ca1..05fd72a8932 100644
--- a/spec/features/projects/blobs/blob_show_spec.rb
+++ b/spec/features/projects/blobs/blob_show_spec.rb
@@ -1009,6 +1009,29 @@ RSpec.describe 'File blob', :js do
stub_application_setting(static_objects_external_storage_url: 'https://cdn.gitlab.com')
end
+ context 'private project' do
+ let_it_be(:project) { create(:project, :repository, :private) }
+ let_it_be(:user) { create(:user, static_object_token: 'ABCD1234') }
+
+ before do
+ project.add_developer(user)
+
+ sign_in(user)
+ visit_blob('README.md')
+ end
+
+ it 'shows open raw and download buttons with external storage URL prepended and user token appended to their href' do
+ path = project_raw_path(project, 'master/README.md')
+ raw_uri = "https://cdn.gitlab.com#{path}?token=#{user.static_object_token}"
+ download_uri = "https://cdn.gitlab.com#{path}?token=#{user.static_object_token}&inline=false"
+
+ aggregate_failures do
+ expect(page).to have_link 'Open raw', href: raw_uri
+ expect(page).to have_link 'Download', href: download_uri
+ end
+ end
+ end
+
context 'public project' do
before do
visit_blob('README.md')
@@ -1033,71 +1056,6 @@ RSpec.describe 'File blob', :js do
stub_feature_flags(refactor_blob_viewer: false)
end
- context 'when ref switch' do
- # We need to unsre that this test runs with the refactor_blob_viewer feature flag enabled
- # This will be addressed in https://gitlab.com/gitlab-org/gitlab/-/issues/351558
-
- def switch_ref_to(ref_name)
- first('.qa-branches-select').click # rubocop:disable QA/SelectorUsage
-
- page.within '.project-refs-form' do
- click_link ref_name
- wait_for_requests
- end
- end
-
- context 'when highlighting lines' do
- it 'displays single highlighted line number of different ref' do
- visit_blob('files/js/application.js', anchor: 'L1')
-
- switch_ref_to('feature')
-
- page.within '.blob-content' do
- expect(find_by_id('LC1')[:class]).to include("hll")
- end
- end
-
- it 'displays multiple highlighted line numbers of different ref' do
- visit_blob('files/js/application.js', anchor: 'L1-3')
-
- switch_ref_to('feature')
-
- page.within '.blob-content' do
- expect(find_by_id('LC1')[:class]).to include("hll")
- expect(find_by_id('LC2')[:class]).to include("hll")
- expect(find_by_id('LC3')[:class]).to include("hll")
- end
- end
- end
- end
-
- context 'visiting with a line number anchor' do
- # We need to unsre that this test runs with the refactor_blob_viewer feature flag enabled
- # This will be addressed in https://gitlab.com/gitlab-org/gitlab/-/issues/351558
-
- before do
- visit_blob('files/markdown/ruby-style-guide.md', anchor: 'L1')
- end
-
- it 'displays the blob using the simple viewer' do
- aggregate_failures do
- # hides the rich viewer
- expect(page).to have_selector('.blob-viewer[data-type="simple"]')
- expect(page).not_to have_selector('.blob-viewer[data-type="rich"]')
-
- # highlights the line in question
- expect(page).to have_selector('#LC1.hll')
-
- # shows highlighted Markdown code
- expect(page).to have_css(".js-syntax-highlight")
- expect(page).to have_content("[PEP-8](http://www.python.org/dev/peps/pep-0008/)")
-
- # shows an enabled copy button
- expect(page).to have_selector('.js-copy-blob-source-btn:not(.disabled)')
- end
- end
- end
-
context 'binary file that appears to be text in the first 1024 bytes' do
# We need to unsre that this test runs with the refactor_blob_viewer feature flag enabled
# This will be addressed in https://gitlab.com/gitlab-org/gitlab/-/issues/351559
@@ -1126,535 +1084,5 @@ RSpec.describe 'File blob', :js do
end
end
end
-
- context 'when static objects external storage is enabled' do
- # We need to unsre that this test runs with the refactor_blob_viewer feature flag enabled
- # This will be addressed in https://gitlab.com/gitlab-org/gitlab/-/issues/351555
-
- before do
- stub_application_setting(static_objects_external_storage_url: 'https://cdn.gitlab.com')
- end
-
- context 'private project' do
- let_it_be(:project) { create(:project, :repository, :private) }
- let_it_be(:user) { create(:user) }
-
- before do
- project.add_developer(user)
-
- sign_in(user)
- visit_blob('README.md')
- end
-
- it 'shows open raw and download buttons with external storage URL prepended and user token appended to their href' do
- path = project_raw_path(project, 'master/README.md')
- raw_uri = "https://cdn.gitlab.com#{path}?token=#{user.static_object_token}"
- download_uri = "https://cdn.gitlab.com#{path}?inline=false&token=#{user.static_object_token}"
-
- aggregate_failures do
- expect(page).to have_link 'Open raw', href: raw_uri
- expect(page).to have_link 'Download', href: download_uri
- end
- end
- end
- end
-
- context 'files with auxiliary viewers' do
- # This context is the same as the other 'files with auxiliary viewers' in this file, we just ensure that the auxiliary viewers still work this the refactor_blob_viewer disabled
- # It should be safe to remove once we rollout the refactored blob viewer
-
- describe '.gitlab-ci.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-ci.yml",
- file_path: '.gitlab-ci.yml',
- file_content: File.read(Rails.root.join('spec/support/gitlab_stubs/gitlab_ci.yml'))
- ).execute
-
- visit_blob('.gitlab-ci.yml')
- end
-
- it 'displays an auxiliary viewer' do
- aggregate_failures do
- # shows that configuration is valid
- expect(page).to have_content('This GitLab CI configuration is valid.')
-
- # shows a learn more link
- expect(page).to have_link('Learn more')
- end
- end
- end
-
- describe '.gitlab/route-map.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/route-map.yml",
- file_path: '.gitlab/route-map.yml',
- file_content: <<-MAP.strip_heredoc
- # Team data
- - source: 'data/team.yml'
- public: 'team/'
- MAP
- ).execute
-
- visit_blob('.gitlab/route-map.yml')
- end
-
- it 'displays an auxiliary viewer' do
- aggregate_failures do
- # shows that map is valid
- expect(page).to have_content('This Route Map is valid.')
-
- # shows a learn more link
- expect(page).to have_link('Learn more')
- end
- 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
- end
-
- context 'with metrics_dashboard_exhaustive_validations feature flag off' do
- before do
- stub_feature_flags(metrics_dashboard_exhaustive_validations: false)
- 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: should be an array of panel_groups objects")
-
- # shows a learn more link
- expect(page).to have_link('Learn more')
- end
- end
- end
- end
-
- context 'with metrics_dashboard_exhaustive_validations feature flag on' do
- before do
- stub_feature_flags(metrics_dashboard_exhaustive_validations: true)
- 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("root is missing required keys: panel_groups")
-
- # shows a learn more link
- expect(page).to have_link('Learn more')
- end
- end
- end
- end
- end
-
- context 'LICENSE' do
- before do
- visit_blob('LICENSE')
- end
-
- it 'displays an auxiliary viewer' do
- aggregate_failures do
- # shows license
- expect(page).to have_content('This project is licensed under the MIT License.')
-
- # shows a learn more link
- expect(page).to have_link('Learn more', href: 'http://choosealicense.com/licenses/mit/')
- end
- end
- end
-
- context '*.gemspec' do
- before do
- project.add_maintainer(project.creator)
-
- Files::CreateService.new(
- project,
- project.creator,
- start_branch: 'master',
- branch_name: 'master',
- commit_message: "Add activerecord.gemspec",
- file_path: 'activerecord.gemspec',
- file_content: <<-SPEC.strip_heredoc
- Gem::Specification.new do |s|
- s.platform = Gem::Platform::RUBY
- s.name = "activerecord"
- end
- SPEC
- ).execute
-
- visit_blob('activerecord.gemspec')
- end
-
- it 'displays an auxiliary viewer' do
- aggregate_failures do
- # shows names of dependency manager and package
- expect(page).to have_content('This project manages its dependencies using RubyGems.')
-
- # shows a learn more link
- expect(page).to have_link('Learn more', href: 'https://rubygems.org/')
- end
- end
- end
-
- context 'CONTRIBUTING.md' do
- before do
- file_name = 'CONTRIBUTING.md'
-
- create_file(file_name, '## Contribution guidelines')
- visit_blob(file_name)
- end
-
- it 'displays an auxiliary viewer' do
- aggregate_failures do
- expect(page).to have_content("After you've reviewed these contribution guidelines, you'll be all set to contribute to this project.")
- end
- end
- end
-
- context 'CHANGELOG.md' do
- before do
- file_name = 'CHANGELOG.md'
-
- create_file(file_name, '## Changelog for v1.0.0')
- visit_blob(file_name)
- end
-
- it 'displays an auxiliary viewer' do
- aggregate_failures do
- expect(page).to have_content("To find the state of this project's repository at the time of any of these versions, check out the tags.")
- end
- end
- end
-
- context 'Cargo.toml' do
- before do
- file_name = 'Cargo.toml'
-
- create_file(file_name, '
- [package]
- name = "hello_world" # the name of the package
- version = "0.1.0" # the current version, obeying semver
- authors = ["Alice <a@example.com>", "Bob <b@example.com>"]
- ')
- visit_blob(file_name)
- end
-
- it 'displays an auxiliary viewer' do
- aggregate_failures do
- expect(page).to have_content("This project manages its dependencies using Cargo.")
- end
- end
- end
-
- context 'Cartfile' do
- before do
- file_name = 'Cartfile'
-
- create_file(file_name, '
- gitlab "Alamofire/Alamofire" == 4.9.0
- gitlab "Alamofire/AlamofireImage" ~> 3.4
- ')
- visit_blob(file_name)
- end
-
- it 'displays an auxiliary viewer' do
- aggregate_failures do
- expect(page).to have_content("This project manages its dependencies using Carthage.")
- end
- end
- end
-
- context 'composer.json' do
- before do
- file_name = 'composer.json'
-
- create_file(file_name, '
- {
- "license": "MIT"
- }
- ')
- visit_blob(file_name)
- end
-
- it 'displays an auxiliary viewer' do
- aggregate_failures do
- expect(page).to have_content("This project manages its dependencies using Composer.")
- end
- end
- end
-
- context 'Gemfile' do
- before do
- file_name = 'Gemfile'
-
- create_file(file_name, '
- source "https://rubygems.org"
-
- # Gems here
- ')
- visit_blob(file_name)
- end
-
- it 'displays an auxiliary viewer' do
- aggregate_failures do
- expect(page).to have_content("This project manages its dependencies using Bundler.")
- end
- end
- end
-
- context 'Godeps.json' do
- before do
- file_name = 'Godeps.json'
-
- create_file(file_name, '
- {
- "GoVersion": "go1.6"
- }
- ')
- visit_blob(file_name)
- end
-
- it 'displays an auxiliary viewer' do
- aggregate_failures do
- expect(page).to have_content("This project manages its dependencies using godep.")
- end
- end
- end
-
- context 'go.mod' do
- before do
- file_name = 'go.mod'
-
- create_file(file_name, '
- module example.com/mymodule
-
- go 1.14
- ')
- visit_blob(file_name)
- end
-
- it 'displays an auxiliary viewer' do
- aggregate_failures do
- expect(page).to have_content("This project manages its dependencies using Go Modules.")
- end
- end
- end
-
- context 'package.json' do
- before do
- file_name = 'package.json'
-
- create_file(file_name, '
- {
- "name": "my-awesome-package",
- "version": "1.0.0"
- }
- ')
- visit_blob(file_name)
- end
-
- it 'displays an auxiliary viewer' do
- aggregate_failures do
- expect(page).to have_content("This project manages its dependencies using npm.")
- end
- end
- end
-
- context 'podfile' do
- before do
- file_name = 'podfile'
-
- create_file(file_name, 'platform :ios, "8.0"')
- visit_blob(file_name)
- end
-
- it 'displays an auxiliary viewer' do
- aggregate_failures do
- expect(page).to have_content("This project manages its dependencies using CocoaPods.")
- end
- end
- end
-
- context 'test.podspec' do
- before do
- file_name = 'test.podspec'
-
- create_file(file_name, '
- Pod::Spec.new do |s|
- s.name = "TensorFlowLiteC"
- ')
- visit_blob(file_name)
- end
-
- it 'displays an auxiliary viewer' do
- aggregate_failures do
- expect(page).to have_content("This project manages its dependencies using CocoaPods.")
- end
- end
- end
-
- context 'JSON.podspec.json' do
- before do
- file_name = 'JSON.podspec.json'
-
- create_file(file_name, '
- {
- "name": "JSON"
- }
- ')
- visit_blob(file_name)
- end
-
- it 'displays an auxiliary viewer' do
- aggregate_failures do
- expect(page).to have_content("This project manages its dependencies using CocoaPods.")
- end
- end
- end
-
- context 'requirements.txt' do
- before do
- file_name = 'requirements.txt'
-
- create_file(file_name, 'Project requirements')
- visit_blob(file_name)
- end
-
- it 'displays an auxiliary viewer' do
- aggregate_failures do
- expect(page).to have_content("This project manages its dependencies using pip.")
- end
- end
- end
-
- context 'yarn.lock' do
- before do
- file_name = 'yarn.lock'
-
- create_file(file_name, '
- # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
- # yarn lockfile v1
- ')
- visit_blob(file_name)
- end
-
- it 'displays an auxiliary viewer' do
- aggregate_failures do
- expect(page).to have_content("This project manages its dependencies using Yarn.")
- end
- end
- end
-
- context 'openapi.yml' do
- before do
- file_name = 'openapi.yml'
-
- create_file(file_name, '
- swagger: \'2.0\'
- info:
- title: Classic API Resource Documentation
- description: |
- <div class="foo-bar" style="background-color: red;" data-foo-bar="baz">
- <h1>Swagger API documentation</h1>
- </div>
- version: production
- basePath: /JSSResource/
- produces:
- - application/xml
- - application/json
- consumes:
- - application/xml
- - application/json
- security:
- - basicAuth: []
- paths:
- /accounts:
- get:
- responses:
- \'200\':
- description: No response was specified
- tags:
- - accounts
- operationId: findAccounts
- summary: Finds all accounts
- ')
- visit_blob(file_name, useUnsafeMarkdown: '1')
- click_button('Display rendered file')
-
- wait_for_requests
- end
-
- it 'removes `style`, `class`, and `data-*`` attributes from HTML' do
- expect(page).to have_css('h1', text: 'Swagger API documentation')
- expect(page).not_to have_css('.foo-bar')
- expect(page).not_to have_css('[style="background-color: red;"]')
- expect(page).not_to have_css('[data-foo-bar="baz"]')
- end
- end
- end
end
end
diff --git a/spec/features/projects/blobs/edit_spec.rb b/spec/features/projects/blobs/edit_spec.rb
index 3f1c10b3688..54176378de8 100644
--- a/spec/features/projects/blobs/edit_spec.rb
+++ b/spec/features/projects/blobs/edit_spec.rb
@@ -183,7 +183,7 @@ RSpec.describe 'Editing file blob', :js do
freeze_time do
visit project_edit_blob_path(project, tree_join(protected_branch, file_path))
- epoch = Time.now.strftime('%s%L').last(5)
+ epoch = Time.zone.now.strftime('%s%L').last(5)
expect(find('.js-branch-name').value).to eq "#{user.username}-protected-branch-patch-#{epoch}"
end
diff --git a/spec/features/projects/blobs/user_views_pipeline_editor_button_spec.rb b/spec/features/projects/blobs/user_views_pipeline_editor_button_spec.rb
index b872fa701c8..15e7a495e60 100644
--- a/spec/features/projects/blobs/user_views_pipeline_editor_button_spec.rb
+++ b/spec/features/projects/blobs/user_views_pipeline_editor_button_spec.rb
@@ -19,14 +19,14 @@ RSpec.describe 'User views pipeline editor button on root ci config file', :js d
project.repository.create_file(user, project.ci_config_path_or_default, 'test', message: 'testing', branch_name: 'master')
visit project_blob_path(project, File.join('master', '.my-config.yml'))
- expect(page).to have_content('Pipeline Editor')
+ expect(page).to have_content('Edit in pipeline editor')
end
it 'does not shows the Pipeline Editor button' do
project.repository.create_file(user, '.my-sub-config.yml', 'test', message: 'testing', branch_name: 'master')
visit project_blob_path(project, File.join('master', '.my-sub-config.yml'))
- expect(page).not_to have_content('Pipeline Editor')
+ expect(page).not_to have_content('Edit in pipeline editor')
end
end
@@ -36,7 +36,7 @@ RSpec.describe 'User views pipeline editor button on root ci config file', :js d
end
it 'does not shows the Pipeline Editor button' do
visit project_blob_path(project, File.join('master', '.my-config.yml'))
- expect(page).not_to have_content('Pipeline Editor')
+ expect(page).not_to have_content('Edit in pipeline editor')
end
end
end
diff --git a/spec/features/projects/ci/editor_spec.rb b/spec/features/projects/ci/editor_spec.rb
index daf5ac61d73..ad4381a526a 100644
--- a/spec/features/projects/ci/editor_spec.rb
+++ b/spec/features/projects/ci/editor_spec.rb
@@ -55,6 +55,10 @@ RSpec.describe 'Pipeline Editor', :js do
it 'displays new branch as selected after commiting on a new branch' do
find('#target-branch-field').set('new_branch', clear: :backspace)
+ page.within('#source-editor-') do
+ find('textarea').send_keys '123'
+ end
+
click_button 'Commit changes'
page.within('[data-testid="branch-selector"]') do
@@ -77,8 +81,6 @@ RSpec.describe 'Pipeline Editor', :js do
context 'when a change is made' do
before do
- click_button 'Collapse'
-
page.within('#source-editor-') do
find('textarea').send_keys '123'
# It takes some time after sending keys for the vue
@@ -123,8 +125,6 @@ RSpec.describe 'Pipeline Editor', :js do
describe 'Editor content' do
it 'user can reset their CI configuration' do
- click_button 'Collapse'
-
page.within('#source-editor-') do
find('textarea').send_keys '123'
end
@@ -147,8 +147,6 @@ RSpec.describe 'Pipeline Editor', :js do
end
it 'user can cancel reseting their CI configuration' do
- click_button 'Collapse'
-
page.within('#source-editor-') do
find('textarea').send_keys '123'
end
diff --git a/spec/features/projects/ci/secure_files_spec.rb b/spec/features/projects/ci/secure_files_spec.rb
new file mode 100644
index 00000000000..65c41eaf2ac
--- /dev/null
+++ b/spec/features/projects/ci/secure_files_spec.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Secure Files', :js do
+ let(:project) { create(:project) }
+ let(:user) { create(:user) }
+
+ before do
+ project.add_maintainer(user)
+ sign_in(user)
+
+ visit project_ci_secure_files_path(project)
+ end
+
+ it 'user sees the Secure Files list component' do
+ expect(page).to have_content('There are no records to show')
+ end
+end
diff --git a/spec/features/projects/cluster_agents_spec.rb b/spec/features/projects/cluster_agents_spec.rb
index d2b07bbc1de..e9162359940 100644
--- a/spec/features/projects/cluster_agents_spec.rb
+++ b/spec/features/projects/cluster_agents_spec.rb
@@ -27,7 +27,7 @@ RSpec.describe 'ClusterAgents', :js do
end
it 'displays empty state', :aggregate_failures do
- expect(page).to have_content('Install new Agent')
+ expect(page).to have_content('Install a new agent')
expect(page).to have_selector('.empty-state')
end
end
diff --git a/spec/features/projects/clusters/eks_spec.rb b/spec/features/projects/clusters/eks_spec.rb
index a925e3a72f8..0dd6effe551 100644
--- a/spec/features/projects/clusters/eks_spec.rb
+++ b/spec/features/projects/clusters/eks_spec.rb
@@ -19,8 +19,8 @@ RSpec.describe 'AWS EKS Cluster', :js do
before do
visit project_clusters_path(project)
- click_link 'Certificate'
- click_link 'Connect with a certificate'
+ click_button(class: 'dropdown-toggle-split')
+ click_link 'Create a new cluster'
end
context 'when user creates a cluster on AWS EKS' do
@@ -28,10 +28,6 @@ RSpec.describe 'AWS EKS Cluster', :js do
click_link 'Amazon EKS'
end
- it 'user sees a form to create an EKS cluster' do
- expect(page).to have_content('Create new cluster on EKS')
- end
-
it 'highlights Amazon EKS logo' do
expect(page).to have_css('.js-create-aws-cluster-button.active')
end
diff --git a/spec/features/projects/clusters/gcp_spec.rb b/spec/features/projects/clusters/gcp_spec.rb
index 0c9db24f1d8..90d7e2d02e9 100644
--- a/spec/features/projects/clusters/gcp_spec.rb
+++ b/spec/features/projects/clusters/gcp_spec.rb
@@ -33,9 +33,7 @@ RSpec.describe 'Gcp Cluster', :js do
before do
visit project_clusters_path(project)
- click_link 'Certificate'
- click_link 'Connect with a certificate'
- click_link 'Create new cluster'
+ visit_create_cluster_page
click_link 'Google GKE'
end
@@ -118,16 +116,7 @@ RSpec.describe 'Gcp Cluster', :js do
expect(page.find(:css, '.cluster-name').value).to eq(cluster.name)
end
- context 'when user disables the cluster' do
- before do
- page.find(:css, '.js-cluster-enable-toggle-area .js-project-feature-toggle').click
- page.within('.js-cluster-details-form') { click_button 'Save changes' }
- end
-
- it 'user sees the successful message' do
- expect(page).to have_content('Kubernetes cluster was successfully updated.')
- end
- end
+ include_examples "user disables a cluster"
context 'when user changes cluster parameters' do
before do
@@ -145,7 +134,6 @@ RSpec.describe 'Gcp Cluster', :js do
before do
visit project_clusters_path(project)
- click_link 'Certificate'
click_button(class: 'dropdown-toggle-split')
click_link 'Connect with a certificate'
end
@@ -175,7 +163,6 @@ RSpec.describe 'Gcp Cluster', :js do
context 'when user has not dismissed GCP signup offer' do
before do
visit project_clusters_path(project)
- click_link 'Certificate'
end
it 'user sees offer on cluster index page' do
@@ -183,7 +170,7 @@ RSpec.describe 'Gcp Cluster', :js do
end
it 'user sees offer on cluster create page' do
- click_link 'Connect with a certificate'
+ visit_create_cluster_page
expect(page).to have_css('.gcp-signup-offer')
end
@@ -201,7 +188,7 @@ RSpec.describe 'Gcp Cluster', :js do
find('.gcp-signup-offer .js-close').click
wait_for_requests
- click_link 'Connect with a certificate'
+ visit_create_cluster_page
expect(page).not_to have_css('.gcp-signup-offer')
end
@@ -230,4 +217,9 @@ RSpec.describe 'Gcp Cluster', :js do
expect(page).not_to have_css('.gcp-signup-offer')
end
end
+
+ def visit_create_cluster_page
+ click_button(class: 'dropdown-toggle-split')
+ click_link 'Create a new cluster'
+ end
end
diff --git a/spec/features/projects/clusters/user_spec.rb b/spec/features/projects/clusters/user_spec.rb
index d9887ea4fe0..3fd78d338da 100644
--- a/spec/features/projects/clusters/user_spec.rb
+++ b/spec/features/projects/clusters/user_spec.rb
@@ -27,7 +27,6 @@ RSpec.describe 'User Cluster', :js do
click_link 'Certificate'
click_link 'Connect with a certificate'
- click_link 'Connect existing cluster'
end
context 'when user filled form with valid parameters' do
@@ -82,16 +81,7 @@ RSpec.describe 'User Cluster', :js do
expect(page).to have_button('Save changes')
end
- context 'when user disables the cluster' do
- before do
- page.find(:css, '.js-cluster-enable-toggle-area .js-project-feature-toggle').click
- page.within('.js-cluster-details-form') { click_button 'Save changes' }
- end
-
- it 'user sees the successful message' do
- expect(page).to have_content('Kubernetes cluster was successfully updated.')
- end
- end
+ include_examples "user disables a cluster"
context 'when user changes cluster parameters' do
before do
diff --git a/spec/features/projects/clusters_spec.rb b/spec/features/projects/clusters_spec.rb
index b0406e1f3c4..b9a544144c3 100644
--- a/spec/features/projects/clusters_spec.rb
+++ b/spec/features/projects/clusters_spec.rb
@@ -34,17 +34,12 @@ RSpec.describe 'Clusters', :js do
before do
create(:cluster, :provided_by_user, name: 'default-cluster', environment_scope: '*', projects: [project])
visit project_clusters_path(project)
- click_link 'Certificate'
- click_button(class: 'dropdown-toggle-split')
- end
-
- it 'user sees an add cluster button' do
- expect(page).to have_content('Connect with a certificate')
end
context 'when user filled form with environment scope' do
before do
- click_link 'Connect with a certificate'
+ visit_connect_cluster_page
+
fill_in 'cluster_name', with: 'staging-cluster'
fill_in 'cluster_environment_scope', with: 'staging/*'
click_button 'Add Kubernetes cluster'
@@ -72,7 +67,8 @@ RSpec.describe 'Clusters', :js do
context 'when user updates duplicated environment scope' do
before do
- click_link 'Connect with a certificate'
+ visit_connect_cluster_page
+
fill_in 'cluster_name', with: 'staging-cluster'
fill_in 'cluster_environment_scope', with: '*'
fill_in 'cluster_platform_kubernetes_attributes_api_url', with: 'https://0.0.0.0'
@@ -115,8 +111,7 @@ RSpec.describe 'Clusters', :js do
context 'when user filled form with environment scope' do
before do
- click_button(class: 'dropdown-toggle-split')
- click_link 'Create a new cluster'
+ visit_create_cluster_page
click_link 'Google GKE'
sleep 2 # wait for ajax
@@ -160,8 +155,7 @@ RSpec.describe 'Clusters', :js do
context 'when user updates duplicated environment scope' do
before do
- click_button(class: 'dropdown-toggle-split')
- click_link 'Create a new cluster'
+ visit_create_cluster_page
click_link 'Google GKE'
sleep 2 # wait for ajax
@@ -212,11 +206,7 @@ RSpec.describe 'Clusters', :js do
context 'user visits create cluster page' do
before do
- visit project_clusters_path(project)
-
- click_link 'Certificate'
- click_link 'Connect with a certificate'
- click_link 'Create new cluster'
+ visit_create_cluster_page
end
it 'user sees a link to create a GKE cluster' do
@@ -227,4 +217,16 @@ RSpec.describe 'Clusters', :js do
expect(page).to have_link('Amazon EKS')
end
end
+
+ def visit_create_cluster_page
+ visit project_clusters_path(project)
+
+ click_button(class: 'dropdown-toggle-split')
+ click_link 'Create a new cluster'
+ end
+
+ def visit_connect_cluster_page
+ click_button(class: 'dropdown-toggle-split')
+ click_link 'Connect with a certificate'
+ end
end
diff --git a/spec/features/projects/commits/multi_view_diff_spec.rb b/spec/features/projects/commits/multi_view_diff_spec.rb
new file mode 100644
index 00000000000..ecdd398c739
--- /dev/null
+++ b/spec/features/projects/commits/multi_view_diff_spec.rb
@@ -0,0 +1,85 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.shared_examples "no multiple viewers" do |commit_ref|
+ let(:ref) { commit_ref }
+
+ it "does not display multiple diff viewers" do
+ expect(page).not_to have_selector '[data-diff-toggle-entity]'
+ end
+end
+
+RSpec.describe 'Multiple view Diffs', :js do
+ let(:user) { create(:user) }
+ let(:project) { create(:project, :repository, visibility_level: Gitlab::VisibilityLevel::PUBLIC) }
+ let(:ref) { '5d6ed1503801ca9dc28e95eeb85a7cf863527aee' }
+ let(:path) { project_commit_path(project, ref) }
+ let(:feature_flag_on) { false }
+
+ before do
+ stub_feature_flags(rendered_diffs_viewer: feature_flag_on ? project : false)
+
+ visit path
+
+ wait_for_all_requests
+ end
+
+ context 'when :rendered_diffs_viewer is off' do
+ context 'and diff does not have ipynb' do
+ include_examples "no multiple viewers", 'ddd0f15ae83993f5cb66a927a28673882e99100b'
+ end
+
+ context 'and diff has ipynb' do
+ include_examples "no multiple viewers", '5d6ed1503801ca9dc28e95eeb85a7cf863527aee'
+
+ it 'shows the transformed diff' do
+ diff = page.find('.diff-file, .file-holder', match: :first)
+
+ expect(diff['innerHTML']).to include('%% Cell type:markdown id:0aac5da7-745c-4eda-847a-3d0d07a1bb9b tags:')
+ end
+ end
+ end
+
+ context 'when :rendered_diffs_viewer is on' do
+ let(:feature_flag_on) { true }
+
+ context 'and diff does not include ipynb' do
+ include_examples "no multiple viewers", 'ddd0f15ae83993f5cb66a927a28673882e99100b'
+ end
+
+ context 'and opening a diff with ipynb' do
+ context 'but the changes are not renderable' do
+ include_examples "no multiple viewers", 'a867a602d2220e5891b310c07d174fbe12122830'
+ end
+
+ it 'loads the rendered diff as hidden' do
+ diff = page.find('.diff-file, .file-holder', match: :first)
+
+ expect(diff).not_to have_selector '[data-diff-toggle-entity="toHide"]'
+ expect(diff).to have_selector '[data-diff-toggle-entity="toShow"]'
+
+ expect(classes_for_element(diff, 'toHide', visible: false)).to include('hidden')
+ expect(classes_for_element(diff, 'toShow')).not_to include('hidden')
+
+ expect(classes_for_element(diff, 'toShowBtn')).to include('selected')
+ expect(classes_for_element(diff, 'toHideBtn')).not_to include('selected')
+ end
+
+ it 'displays the rendered diff and hides after selection changes' do
+ diff = page.find('.diff-file, .file-holder', match: :first)
+ diff.find('[data-diff-toggle-entity="toShowBtn"]').click
+
+ expect(diff).to have_selector '[data-diff-toggle-entity="toShow"]'
+ expect(diff).not_to have_selector '[data-diff-toggle-entity="toHide"]'
+
+ expect(classes_for_element(diff, 'toHideBtn')).not_to include('selected')
+ expect(classes_for_element(diff, 'toShowBtn')).to include('selected')
+ end
+ end
+ end
+
+ def classes_for_element(node, data_diff_entity, visible: true)
+ node.find("[data-diff-toggle-entity=\"#{data_diff_entity}\"]", visible: visible)[:class]
+ end
+end
diff --git a/spec/features/projects/container_registry_spec.rb b/spec/features/projects/container_registry_spec.rb
index 4ebcb69592b..17eb421191f 100644
--- a/spec/features/projects/container_registry_spec.rb
+++ b/spec/features/projects/container_registry_spec.rb
@@ -103,6 +103,8 @@ RSpec.describe 'Container Registry', :js do
find('.modal .modal-footer .btn-danger').click
end
+ it_behaves_like 'rejecting tags destruction for an importing repository on', tags: ['1']
+
it('pagination navigate to the second page') do
visit_next_page
diff --git a/spec/features/projects/environments/environment_metrics_spec.rb b/spec/features/projects/environments/environment_metrics_spec.rb
index 0f858c627bc..f5f4d13dd58 100644
--- a/spec/features/projects/environments/environment_metrics_spec.rb
+++ b/spec/features/projects/environments/environment_metrics_spec.rb
@@ -18,7 +18,6 @@ RSpec.describe 'Environment > Metrics' do
stub_any_prometheus_request
sign_in(user)
- visit_environment(environment)
end
around do |example|
@@ -27,6 +26,7 @@ RSpec.describe 'Environment > Metrics' do
shared_examples 'has environment selector' do
it 'has a working environment selector', :js do
+ visit_environment(environment)
click_link 'Monitoring'
expect(page).to have_current_path(project_metrics_dashboard_path(project, environment: environment.id))
@@ -56,6 +56,7 @@ RSpec.describe 'Environment > Metrics' do
end
it 'shows metrics', :js do
+ visit_environment(environment)
click_link 'Monitoring'
expect(page).to have_css('[data-qa-selector="prometheus_graphs"]') # rubocop:disable QA/SelectorUsage
diff --git a/spec/features/projects/environments/environments_spec.rb b/spec/features/projects/environments/environments_spec.rb
index 3b83c25b629..99137018d6b 100644
--- a/spec/features/projects/environments/environments_spec.rb
+++ b/spec/features/projects/environments/environments_spec.rb
@@ -3,12 +3,13 @@
require 'spec_helper'
RSpec.describe 'Environments page', :js do
+ include Spec::Support::Helpers::ModalHelpers
+
let(:project) { create(:project) }
let(:user) { create(:user) }
let(:role) { :developer }
before do
- stub_feature_flags(new_environments_table: false)
project.add_role(user, role)
sign_in(user)
end
@@ -33,24 +34,18 @@ RSpec.describe 'Environments page', :js do
it 'shows "Available" and "Stopped" tab with links' do
visit_environments(project)
- expect(page).to have_selector('.js-environments-tab-available')
- expect(page).to have_content('Available')
- expect(page).to have_selector('.js-environments-tab-stopped')
- expect(page).to have_content('Stopped')
+ expect(page).to have_link(_('Available'))
+ expect(page).to have_link(_('Stopped'))
end
describe 'with one available environment' do
- before do
- create(:environment, project: project, state: :available)
- end
+ let!(:environment) { create(:environment, project: project, state: :available) }
describe 'in available tab page' do
it 'shows one environment' do
visit_environments(project, scope: 'available')
- expect(page).to have_css('.environments-container')
- expect(page.all('.environment-name').length).to eq(1)
- expect(page.all('[data-testid="stop-icon"]').length).to eq(1)
+ expect(page).to have_link(environment.name, href: project_environment_path(project, environment))
end
end
@@ -75,7 +70,6 @@ RSpec.describe 'Environments page', :js do
it 'shows no environments' do
visit_environments(project, scope: 'stopped')
- expect(page).to have_css('.environments-container')
expect(page).to have_content('You don\'t have any environments right now')
end
end
@@ -93,22 +87,18 @@ RSpec.describe 'Environments page', :js do
it 'shows one environment without error' do
visit_environments(project, scope: 'available')
- expect(page).to have_css('.environments-container')
- expect(page.all('.environment-name').length).to eq(1)
+ expect(page).to have_link(environment.name, href: project_environment_path(project, environment))
end
end
end
describe 'with one stopped environment' do
- before do
- create(:environment, project: project, state: :stopped)
- end
+ let!(:environment) { create(:environment, project: project, state: :stopped) }
describe 'in available tab page' do
it 'shows no environments' do
visit_environments(project, scope: 'available')
- expect(page).to have_css('.environments-container')
expect(page).to have_content('You don\'t have any environments right now')
end
end
@@ -117,8 +107,7 @@ RSpec.describe 'Environments page', :js do
it 'shows one environment' do
visit_environments(project, scope: 'stopped')
- expect(page).to have_css('.environments-container')
- expect(page.all('.environment-name').length).to eq(1)
+ expect(page).to have_link(environment.name, href: project_environment_path(project, environment))
expect(page.all('[data-testid="stop-icon"]').length).to eq(0)
end
end
@@ -133,8 +122,8 @@ RSpec.describe 'Environments page', :js do
it 'does not show environments and counters are set to zero' do
expect(page).to have_content('You don\'t have any environments right now')
- expect(page.find('.js-environments-tab-available .badge').text).to eq('0')
- expect(page.find('.js-environments-tab-stopped .badge').text).to eq('0')
+ expect(page).to have_link("#{_('Available')} 0")
+ expect(page).to have_link("#{_('Stopped')} 0")
end
end
@@ -148,21 +137,23 @@ RSpec.describe 'Environments page', :js do
context 'when there are no deployments' do
before do
visit_environments(project)
+
+ page.click_button _('Expand')
end
it 'shows environments names and counters' do
- expect(page).to have_link(environment.name)
+ expect(page).to have_link(environment.name, href: project_environment_path(project, environment))
- expect(page.find('.js-environments-tab-available .badge').text).to eq('1')
- expect(page.find('.js-environments-tab-stopped .badge').text).to eq('0')
+ expect(page).to have_link("#{_('Available')} 1")
+ expect(page).to have_link("#{_('Stopped')} 0")
end
it 'does not show deployments' do
- expect(page).to have_content('No deployments yet')
+ expect(page).to have_content(s_('Environments|There are no deployments for this environment yet. Learn more about setting up deployments.'))
end
it 'shows stop button when environment is not stoppable' do
- expect(page).to have_selector(stop_button_selector)
+ expect(page).to have_button('Stop')
end
end
@@ -177,8 +168,10 @@ RSpec.describe 'Environments page', :js do
it 'shows deployment SHA and internal ID' do
visit_environments(project)
+ page.click_button _('Expand')
- expect(page).to have_link(deployment.short_sha)
+ expect(page).to have_text(deployment.short_sha)
+ expect(page).to have_link(deployment.commit.full_title)
expect(page).to have_content(deployment.iid)
end
@@ -216,10 +209,6 @@ RSpec.describe 'Environments page', :js do
.not_to change { Ci::Pipeline.count }
end
- it 'shows build name and id' do
- expect(page).to have_link("#{build.name} ##{build.id}")
- end
-
it 'shows a stop button' do
expect(page).to have_selector(stop_button_selector)
end
@@ -346,7 +335,9 @@ RSpec.describe 'Environments page', :js do
context 'when user played a delayed job immediately' do
before do
find(actions_button_selector).click
- accept_confirm { find(action_link_selector).click }
+ accept_gl_confirm do
+ find(action_link_selector).click
+ end
wait_for_requests
end
@@ -369,7 +360,8 @@ RSpec.describe 'Environments page', :js do
it 'does not show deployments' do
visit_environments(project)
- expect(page).to have_content('No deployments yet')
+ page.click_button _('Expand')
+ expect(page).to have_content(s_('Environments|There are no deployments for this environment yet. Learn more about setting up deployments.'))
end
end
@@ -385,9 +377,10 @@ RSpec.describe 'Environments page', :js do
it "renders the upcoming deployment", :aggregate_failures do
visit_environments(project)
+ page.click_button _('Expand')
+
within(upcoming_deployment_content_selector) do
expect(page).to have_content("##{deployment.iid}")
- expect(page).to have_selector("a[href=\"#{project_job_path(project, deployment.deployable)}\"]")
expect(page).to have_link(href: /#{deployment.user.username}/)
end
end
@@ -409,15 +402,15 @@ RSpec.describe 'Environments page', :js do
let(:role) { :developer }
it 'developer creates a new environment with a valid name' do
- within(".environments-section") { click_link 'New environment' }
+ click_link 'New environment'
fill_in('Name', with: 'production')
click_on 'Save'
expect(page).to have_content('production')
end
- it 'developer creates a new environmetn with invalid name' do
- within(".environments-section") { click_link 'New environment' }
+ it 'developer creates a new environment with invalid name' do
+ click_link 'New environment'
fill_in('Name', with: 'name,with,commas')
click_on 'Save'
@@ -454,20 +447,11 @@ RSpec.describe 'Environments page', :js do
expect(page).not_to have_content 'review-2'
expect(page).to have_content 'staging 2'
- within('.folder-row') do
- find('.folder-name', text: 'staging').click
- end
+ page.click_button _('Expand')
expect(page).to have_content 'review-1'
expect(page).to have_content 'review-2'
- within('.ci-table') do
- within('[data-qa-selector="environment_item"]', text: 'review-1') do # rubocop:disable QA/SelectorUsage
- expect(find('.js-auto-stop').text).not_to be_empty
- end
- within('[data-qa-selector="environment_item"]', text: 'review-2') do # rubocop:disable QA/SelectorUsage
- expect(find('.js-auto-stop').text).not_to be_empty
- end
- end
+ expect(page).to have_content 'Auto stop in'
end
end
@@ -490,9 +474,7 @@ RSpec.describe 'Environments page', :js do
expect(page).not_to have_content 'review-2'
expect(page).to have_content 'staging 2'
- within('.folder-row') do
- find('.folder-name', text: 'staging').click
- end
+ page.click_button _('Expand')
expect(page).to have_content 'review-1'
expect(page).to have_content 'review-2'
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 4a0b1f4c548..c9ba8cbd2bb 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
@@ -26,23 +26,23 @@ RSpec.describe 'Projects > Files > Project owner creates a license file', :js do
file_content = first('.file-editor')
expect(file_content).to have_content('MIT License')
- expect(file_content).to have_content("Copyright (c) #{Time.now.year} #{project.namespace.human_name}")
+ expect(file_content).to have_content("Copyright (c) #{Time.zone.now.year} #{project.namespace.human_name}")
fill_in :commit_message, with: 'Add a LICENSE file', visible: true
click_button 'Commit changes'
- expect(current_path).to eq(
- project_blob_path(project, 'master/LICENSE'))
+ expect(page).to have_current_path(
+ project_blob_path(project, 'master/LICENSE'), ignore_query: true)
expect(page).to have_content('MIT License')
- expect(page).to have_content("Copyright (c) #{Time.now.year} #{project.namespace.human_name}")
+ expect(page).to have_content("Copyright (c) #{Time.zone.now.year} #{project.namespace.human_name}")
end
it 'project maintainer creates a license file from the "Add license" link' do
click_link 'Add LICENSE'
expect(page).to have_content('New file')
- expect(current_path).to eq(
- project_new_blob_path(project, 'master'))
+ expect(page).to have_current_path(
+ project_new_blob_path(project, 'master'), ignore_query: true)
expect(find('#file_name').value).to eq('LICENSE')
expect(page).to have_selector('.license-selector')
@@ -50,15 +50,15 @@ RSpec.describe 'Projects > Files > Project owner creates a license file', :js do
file_content = first('.file-editor')
expect(file_content).to have_content('MIT License')
- expect(file_content).to have_content("Copyright (c) #{Time.now.year} #{project.namespace.human_name}")
+ expect(file_content).to have_content("Copyright (c) #{Time.zone.now.year} #{project.namespace.human_name}")
fill_in :commit_message, with: 'Add a LICENSE file', visible: true
click_button 'Commit changes'
- expect(current_path).to eq(
- project_blob_path(project, 'master/LICENSE'))
+ expect(page).to have_current_path(
+ project_blob_path(project, 'master/LICENSE'), ignore_query: true)
expect(page).to have_content('MIT License')
- expect(page).to have_content("Copyright (c) #{Time.now.year} #{project.namespace.human_name}")
+ expect(page).to have_content("Copyright (c) #{Time.zone.now.year} #{project.namespace.human_name}")
end
def select_template(template)
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 ca384291c12..0e87622d3c2 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
@@ -16,24 +16,24 @@ RSpec.describe 'Projects > Files > Project owner sees a link to create a license
visit project_path(project)
click_on 'Add LICENSE'
- expect(current_path).to eq("/-/ide/project/#{project.full_path}/edit/master/-/LICENSE")
+ expect(page).to have_current_path("/-/ide/project/#{project.full_path}/edit/master/-/LICENSE", ignore_query: true)
expect(page).to have_selector('.qa-file-templates-bar') # rubocop:disable QA/SelectorUsage
select_template('MIT License')
expect(ide_editor_value).to have_content('MIT License')
- expect(ide_editor_value).to have_content("Copyright (c) #{Time.now.year} #{project.namespace.human_name}")
+ expect(ide_editor_value).to have_content("Copyright (c) #{Time.zone.now.year} #{project.namespace.human_name}")
ide_commit
- expect(current_path).to eq("/-/ide/project/#{project.full_path}/tree/master/-/LICENSE/")
+ expect(page).to have_current_path("/-/ide/project/#{project.full_path}/tree/master/-/LICENSE/", ignore_query: true)
expect(page).to have_content('All changes are committed')
license_file = project.repository.blob_at('master', 'LICENSE').data
expect(license_file).to have_content('MIT License')
- expect(license_file).to have_content("Copyright (c) #{Time.now.year} #{project.namespace.human_name}")
+ expect(license_file).to have_content("Copyright (c) #{Time.zone.now.year} #{project.namespace.human_name}")
end
def select_template(template)
diff --git a/spec/features/projects/files/user_browses_files_spec.rb b/spec/features/projects/files/user_browses_files_spec.rb
index 9b4d1502bc8..53fdd5a15dd 100644
--- a/spec/features/projects/files/user_browses_files_spec.rb
+++ b/spec/features/projects/files/user_browses_files_spec.rb
@@ -76,7 +76,7 @@ RSpec.describe "User browses files", :js do
permalink_path = project_blob_path(project, "#{project.repository.commit.sha}/.gitignore")
- expect(current_path).to eq(permalink_path)
+ expect(page).to have_current_path(permalink_path, ignore_query: true)
end
end
@@ -87,7 +87,7 @@ RSpec.describe "User browses files", :js do
end
it "shows correct files and links" do
- expect(current_path).to eq(project_tree_path(project, "markdown"))
+ expect(page).to have_current_path(project_tree_path(project, "markdown"), ignore_query: true)
expect(page).to have_content("README.md")
.and have_content("CHANGELOG")
.and have_content("Welcome to GitLab GitLab is a free project and repository management application")
@@ -108,7 +108,7 @@ RSpec.describe "User browses files", :js do
it "shows correct content of file" do
click_link("GitLab API doc")
- expect(current_path).to eq(project_blob_path(project, "markdown/doc/api/README.md"))
+ expect(page).to have_current_path(project_blob_path(project, "markdown/doc/api/README.md"), ignore_query: true)
expect(page).to have_content("All API requests require authentication")
.and have_content("Contents")
.and have_link("Users")
@@ -117,19 +117,19 @@ RSpec.describe "User browses files", :js do
click_link("Users")
- expect(current_path).to eq(project_blob_path(project, "markdown/doc/api/users.md"))
+ expect(page).to have_current_path(project_blob_path(project, "markdown/doc/api/users.md"), ignore_query: true)
expect(page).to have_content("Get a list of users.")
page.go_back
click_link("Rake tasks")
- expect(current_path).to eq(project_tree_path(project, "markdown/doc/raketasks"))
+ expect(page).to have_current_path(project_tree_path(project, "markdown/doc/raketasks"), ignore_query: true)
expect(page).to have_content("backup_restore.md").and have_content("maintenance.md")
click_link("maintenance.md")
- expect(current_path).to eq(project_blob_path(project, "markdown/doc/raketasks/maintenance.md"))
+ expect(page).to have_current_path(project_blob_path(project, "markdown/doc/raketasks/maintenance.md"), ignore_query: true)
expect(page).to have_content("bundle exec rake gitlab:env:info RAILS_ENV=production")
click_link("shop")
@@ -156,12 +156,12 @@ RSpec.describe "User browses files", :js do
it "shows correct content of directory" do
click_link("GitLab API doc directory")
- expect(current_path).to eq(project_tree_path(project, "markdown/doc/api"))
+ expect(page).to have_current_path(project_tree_path(project, "markdown/doc/api"), ignore_query: true)
expect(page).to have_content("README.md").and have_content("users.md")
click_link("Users")
- expect(current_path).to eq(project_blob_path(project, "markdown/doc/api/users.md"))
+ expect(page).to have_current_path(project_blob_path(project, "markdown/doc/api/users.md"), ignore_query: true)
expect(page).to have_content("List users").and have_content("Get a list of users.")
end
end
@@ -267,7 +267,7 @@ RSpec.describe "User browses files", :js do
end
it "shows files from a repository for `6d39438`" do
- expect(current_path).to eq(ref)
+ expect(page).to have_current_path(ref, ignore_query: true)
expect(page).to have_content(".gitignore").and have_content("LICENSE")
end
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 3976df849fa..56e18871810 100644
--- a/spec/features/projects/files/user_browses_lfs_files_spec.rb
+++ b/spec/features/projects/files/user_browses_lfs_files_spec.rb
@@ -72,24 +72,7 @@ RSpec.describe 'Projects > Files > User browses LFS files' do
expect(page).not_to have_content('Blame')
expect(page).not_to have_selector(:link_or_button, text: /^Edit$/)
- expect(page).to have_selector(:link_or_button, 'Edit in Web IDE')
- end
- end
-
- context 'when feature flag :consolidated_edit_button is off' do
- before do
- stub_feature_flags(consolidated_edit_button: false)
-
- click_link('files')
- click_link('lfs')
- click_link('lfs_object.iso')
- end
-
- it 'does not show single file edit link' do
- page.within('.content') do
- expect(page).to have_selector(:link_or_button, 'Web IDE')
- expect(page).not_to have_css('button[data-testid="edit"')
- end
+ expect(page).to have_selector(:link_or_button, 'Open in Web IDE')
end
end
end
diff --git a/spec/features/projects/files/user_creates_directory_spec.rb b/spec/features/projects/files/user_creates_directory_spec.rb
index 5ad7641a5be..9e0168d7ef3 100644
--- a/spec/features/projects/files/user_creates_directory_spec.rb
+++ b/spec/features/projects/files/user_creates_directory_spec.rb
@@ -42,7 +42,7 @@ RSpec.describe 'Projects > Files > User creates a directory', :js do
click_button('Create directory')
expect(page).to have_content('A directory with this name already exists')
- expect(current_path).to eq(project_tree_path(project, 'master'))
+ expect(page).to have_current_path(project_tree_path(project, 'master'), ignore_query: true)
end
end
@@ -81,7 +81,7 @@ RSpec.describe 'Projects > Files > User creates a directory', :js do
expect(page).to have_content('From new-feature into master')
expect(page).to have_content('Add new directory')
- expect(current_path).to eq(project_new_merge_request_path(project))
+ expect(page).to have_current_path(project_new_merge_request_path(project), ignore_query: true)
end
end
@@ -107,7 +107,7 @@ RSpec.describe 'Projects > Files > User creates a directory', :js do
fork = user.fork_of(project2.reload)
wait_for_requests
- expect(current_path).to eq(project_new_merge_request_path(fork))
+ expect(page).to have_current_path(project_new_merge_request_path(fork), ignore_query: true)
end
end
end
diff --git a/spec/features/projects/files/user_creates_files_spec.rb b/spec/features/projects/files/user_creates_files_spec.rb
index 7159418deda..7344c91b6dc 100644
--- a/spec/features/projects/files/user_creates_files_spec.rb
+++ b/spec/features/projects/files/user_creates_files_spec.rb
@@ -97,7 +97,7 @@ RSpec.describe 'Projects > Files > User creates files', :js do
new_file_path = project_blob_path(project, 'master/not_a_file.md')
- expect(current_path).to eq(new_file_path)
+ expect(page).to have_current_path(new_file_path, ignore_query: true)
wait_for_requests
@@ -115,7 +115,7 @@ RSpec.describe 'Projects > Files > User creates files', :js do
new_file_path = project_blob_path(project, 'master/not_a_file.md')
- expect(current_path).to eq(new_file_path)
+ expect(page).to have_current_path(new_file_path, ignore_query: true)
click_link('Edit')
@@ -133,7 +133,7 @@ RSpec.describe 'Projects > Files > User creates files', :js do
fill_in(:commit_message, with: 'New commit message', visible: true)
click_button('Commit changes')
- expect(current_path).to eq(project_blob_path(project, 'master/foo/bar/baz.txt'))
+ expect(page).to have_current_path(project_blob_path(project, 'master/foo/bar/baz.txt'), ignore_query: true)
wait_for_requests
@@ -150,7 +150,7 @@ RSpec.describe 'Projects > Files > User creates files', :js do
fill_in(:branch_name, with: 'new_branch_name', visible: true)
click_button('Commit changes')
- expect(current_path).to eq(project_new_merge_request_path(project))
+ expect(page).to have_current_path(project_new_merge_request_path(project), ignore_query: true)
click_link('Changes')
@@ -187,7 +187,7 @@ RSpec.describe 'Projects > Files > User creates files', :js do
fork = user.fork_of(project2.reload)
- expect(current_path).to eq(project_new_merge_request_path(fork))
+ expect(page).to have_current_path(project_new_merge_request_path(fork), ignore_query: true)
expect(page).to have_content('New commit message')
end
end
diff --git a/spec/features/projects/files/user_deletes_files_spec.rb b/spec/features/projects/files/user_deletes_files_spec.rb
index c508b2ddba9..806f1e8e9ed 100644
--- a/spec/features/projects/files/user_deletes_files_spec.rb
+++ b/spec/features/projects/files/user_deletes_files_spec.rb
@@ -15,7 +15,6 @@ RSpec.describe 'Projects > Files > User deletes files', :js do
let(:user) { create(:user) }
before do
- stub_feature_flags(refactor_blob_viewer: false) # This stub will be removed in https://gitlab.com/gitlab-org/gitlab/-/issues/349953
sign_in(user)
end
@@ -35,7 +34,7 @@ RSpec.describe 'Projects > Files > User deletes files', :js do
fill_in(:commit_message, with: 'New commit message', visible: true)
click_button('Delete file')
- expect(current_path).to eq(project_tree_path(project, 'master/'))
+ expect(page).to have_current_path(project_tree_path(project, 'master/'), ignore_query: true)
expect(page).not_to have_content('.gitignore')
end
end
@@ -67,7 +66,7 @@ RSpec.describe 'Projects > Files > User deletes files', :js do
fork = user.fork_of(project2.reload)
- expect(current_path).to eq(project_new_merge_request_path(fork))
+ expect(page).to have_current_path(project_new_merge_request_path(fork), ignore_query: true)
expect(page).to have_content('New commit message')
end
end
diff --git a/spec/features/projects/files/user_edits_files_spec.rb b/spec/features/projects/files/user_edits_files_spec.rb
index 2b4ac3dc1d8..1ac45970828 100644
--- a/spec/features/projects/files/user_edits_files_spec.rb
+++ b/spec/features/projects/files/user_edits_files_spec.rb
@@ -77,7 +77,7 @@ RSpec.describe 'Projects > Files > User edits files', :js do
fill_in(:commit_message, with: 'New commit message', visible: true)
click_button('Commit changes')
- expect(current_path).to eq(project_blob_path(project, 'master/.gitignore'))
+ expect(page).to have_current_path(project_blob_path(project, 'master/.gitignore'), ignore_query: true)
wait_for_requests
@@ -97,7 +97,7 @@ RSpec.describe 'Projects > Files > User edits files', :js do
fill_in(:branch_name, with: 'new_branch_name', visible: true)
click_button('Commit changes')
- expect(current_path).to eq(project_new_merge_request_path(project))
+ expect(page).to have_current_path(project_new_merge_request_path(project), ignore_query: true)
click_link('Changes')
@@ -194,7 +194,7 @@ RSpec.describe 'Projects > Files > User edits files', :js do
fork = user.fork_of(project2.reload)
- expect(current_path).to eq(project_new_merge_request_path(fork))
+ expect(page).to have_current_path(project_new_merge_request_path(fork), ignore_query: true)
wait_for_requests
@@ -223,7 +223,7 @@ RSpec.describe 'Projects > Files > User edits files', :js do
fork = user.fork_of(project2)
- expect(current_path).to eq(project_new_merge_request_path(fork))
+ expect(page).to have_current_path(project_new_merge_request_path(fork), ignore_query: true)
wait_for_requests
@@ -236,116 +236,5 @@ RSpec.describe 'Projects > Files > User edits files', :js do
let(:project) { project2 }
end
end
-
- context 'when feature flag :consolidated_edit_button is off' do
- before do
- stub_feature_flags(consolidated_edit_button: false)
- end
-
- context 'when an user does not have write access', :js do
- before do
- project2.add_reporter(user)
- visit(project2_tree_path_root_ref)
- wait_for_requests
- end
-
- it 'inserts a content of a file in a forked project', :sidekiq_might_not_need_inline do
- set_default_button('edit')
- click_link('.gitignore')
- click_link_or_button('Edit')
-
- expect_fork_prompt
-
- click_link_or_button('Fork')
-
- expect_fork_status
-
- find('.file-editor', match: :first)
-
- find('#editor')
- set_editor_value('*.rbca')
-
- expect(editor_value).to eq('*.rbca')
- end
-
- it 'opens the Web IDE in a forked project', :sidekiq_might_not_need_inline do
- set_default_button('webide')
- click_link('.gitignore')
- click_link_or_button('Web IDE')
-
- expect_fork_prompt
-
- click_link_or_button('Fork')
-
- expect_fork_status
-
- expect(page).to have_css('.ide-sidebar-project-title', text: "#{project2.name} #{user.namespace.full_path}/#{project2.path}")
- expect(page).to have_css('.ide .multi-file-tab', text: '.gitignore')
- end
-
- it 'commits an edited file in a forked project', :sidekiq_might_not_need_inline do
- set_default_button('edit')
- click_link('.gitignore')
- click_link_or_button('Edit')
-
- expect_fork_prompt
-
- click_link_or_button('Fork')
-
- expect_fork_status
-
- find('.file-editor', match: :first)
-
- find('#editor')
- set_editor_value('*.rbca')
- fill_in(:commit_message, with: 'New commit message', visible: true)
- click_button('Commit changes')
-
- fork = user.fork_of(project2.reload)
-
- expect(current_path).to eq(project_new_merge_request_path(fork))
-
- wait_for_requests
-
- expect(page).to have_content('New commit message')
- end
-
- context 'when the user already had a fork of the project', :js do
- let!(:forked_project) { fork_project(project2, user, namespace: user.namespace, repository: true) }
-
- before do
- visit(project2_tree_path_root_ref)
- wait_for_requests
- end
-
- it 'links to the forked project for editing', :sidekiq_might_not_need_inline do
- set_default_button('edit')
- click_link('.gitignore')
- click_link_or_button('Edit')
-
- expect(page).not_to have_link('Fork')
-
- find('#editor')
- set_editor_value('*.rbca')
- fill_in(:commit_message, with: 'Another commit', visible: true)
- click_button('Commit changes')
-
- fork = user.fork_of(project2)
-
- expect(current_path).to eq(project_new_merge_request_path(fork))
-
- wait_for_requests
-
- expect(page).to have_content('Another commit')
- expect(page).to have_content("From #{forked_project.full_path}")
- expect(page).to have_content("into #{project2.full_path}")
- end
-
- it_behaves_like 'unavailable for an archived project' do
- let(:project) { project2 }
- end
- end
- end
- end
end
end
diff --git a/spec/features/projects/files/user_replaces_files_spec.rb b/spec/features/projects/files/user_replaces_files_spec.rb
index fe9520fffc8..1ecd50b6463 100644
--- a/spec/features/projects/files/user_replaces_files_spec.rb
+++ b/spec/features/projects/files/user_replaces_files_spec.rb
@@ -17,7 +17,6 @@ RSpec.describe 'Projects > Files > User replaces files', :js do
let(:user) { create(:user) }
before do
- stub_feature_flags(refactor_blob_viewer: false) # This stub will be removed in https://gitlab.com/gitlab-org/gitlab/-/issues/349953
sign_in(user)
end
@@ -34,9 +33,9 @@ RSpec.describe 'Projects > Files > User replaces files', :js do
expect(page).to have_content('.gitignore')
click_on('Replace')
- drop_in_dropzone(File.join(Rails.root, 'spec', 'fixtures', 'doc_sample.txt'))
+ find(".upload-dropzone-card").drop(File.join(Rails.root, 'spec', 'fixtures', 'doc_sample.txt'))
- page.within('#modal-upload-blob') do
+ page.within('#modal-replace-blob') do
fill_in(:commit_message, with: 'Replacement file commit message')
end
@@ -70,9 +69,9 @@ RSpec.describe 'Projects > Files > User replaces files', :js do
expect(page).to have_content(fork_message)
click_on('Replace')
- drop_in_dropzone(File.join(Rails.root, 'spec', 'fixtures', 'doc_sample.txt'))
+ find(".upload-dropzone-card").drop(File.join(Rails.root, 'spec', 'fixtures', 'doc_sample.txt'))
- page.within('#modal-upload-blob') do
+ page.within('#modal-replace-blob') do
fill_in(:commit_message, with: 'Replacement file commit message')
end
@@ -82,7 +81,7 @@ RSpec.describe 'Projects > Files > User replaces files', :js do
fork = user.fork_of(project2.reload)
- expect(current_path).to eq(project_new_merge_request_path(fork))
+ expect(page).to have_current_path(project_new_merge_request_path(fork), ignore_query: true)
click_link('Changes')
diff --git a/spec/features/projects/fork_spec.rb b/spec/features/projects/fork_spec.rb
index f9a6b67e469..fb27f0961b6 100644
--- a/spec/features/projects/fork_spec.rb
+++ b/spec/features/projects/fork_spec.rb
@@ -164,199 +164,4 @@ RSpec.describe 'Project fork' do
end
end
end
-
- context 'with fork_project_form feature flag disabled' do
- before do
- stub_feature_flags(fork_project_form: false)
- sign_in(user)
- end
-
- it_behaves_like 'fork button on project page'
-
- context 'user has exceeded personal project limit' do
- before do
- user.update!(projects_limit: 0)
- end
-
- context 'with a group to fork to' do
- let!(:group) { create(:group).tap { |group| group.add_owner(user) } }
-
- it 'allows user to fork only to the group on fork page', :js do
- visit new_project_fork_path(project)
-
- to_personal_namespace = find('[data-qa-selector=fork_namespace_button].disabled') # rubocop:disable QA/SelectorUsage
- to_group = find(".fork-groups button[data-qa-name=#{group.name}]") # rubocop:disable QA/SelectorUsage
-
- expect(to_personal_namespace).not_to be_nil
- expect(to_group).not_to be_disabled
- end
- end
- end
-
- it_behaves_like 'create fork page', ' Select a namespace to fork the project '
-
- it 'forks the project', :sidekiq_might_not_need_inline do
- visit project_path(project)
-
- click_link 'Fork'
-
- page.within '.fork-thumbnail-container' do
- click_link 'Select'
- end
-
- expect(page).to have_content 'Forked from'
-
- visit project_path(project)
-
- expect(page).to have_content(/new merge request/i)
-
- page.within '.nav-sidebar' do
- first(:link, 'Merge requests').click
- end
-
- expect(page).to have_content(/new merge request/i)
-
- page.within '#content-body' do
- click_link('New merge request')
- end
-
- expect(current_path).to have_content(/#{user.namespace.path}/i)
- end
-
- it 'shows avatars when Gravatar is disabled' do
- stub_application_setting(gravatar_enabled: false)
-
- visit project_path(project)
-
- click_link 'Fork'
-
- page.within('.fork-thumbnail-container') do
- expect(page).to have_css('span.identicon')
- end
- end
-
- it 'shows the forked project on the list' do
- visit project_path(project)
-
- click_link 'Fork'
-
- page.within '.fork-thumbnail-container' do
- click_link 'Select'
- end
-
- visit project_forks_path(project)
-
- forked_project = user.fork_of(project.reload)
-
- page.within('.js-projects-list-holder') do
- expect(page).to have_content("#{forked_project.namespace.human_name} / #{forked_project.name}")
- end
-
- forked_project.update!(path: 'test-crappy-path')
-
- visit project_forks_path(project)
-
- page.within('.js-projects-list-holder') do
- expect(page).to have_content("#{forked_project.namespace.human_name} / #{forked_project.name}")
- end
- end
-
- context 'when the project is private' do
- let(:project) { create(:project, :repository) }
- let(:another_user) { create(:user, name: 'Mike') }
-
- before do
- project.add_reporter(user)
- project.add_reporter(another_user)
- end
-
- it 'renders private forks of the project' do
- visit project_path(project)
-
- another_project_fork = Projects::ForkService.new(project, another_user).execute
-
- click_link 'Fork'
-
- page.within '.fork-thumbnail-container' do
- click_link 'Select'
- end
-
- visit project_forks_path(project)
-
- page.within('.js-projects-list-holder') do
- user_project_fork = user.fork_of(project.reload)
- expect(page).to have_content("#{user_project_fork.namespace.human_name} / #{user_project_fork.name}")
- end
-
- expect(page).not_to have_content("#{another_project_fork.namespace.human_name} / #{another_project_fork.name}")
- end
- end
-
- context 'when the user already forked the project' do
- before do
- create(:project, :repository, name: project.name, namespace: user.namespace)
- end
-
- it 'renders error' do
- visit project_path(project)
-
- click_link 'Fork'
-
- page.within '.fork-thumbnail-container' do
- click_link 'Select'
- end
-
- expect(page).to have_content "Name has already been taken"
- end
- end
-
- context 'maintainer in group' do
- let(:group) { create(:group) }
-
- before do
- group.add_maintainer(user)
- end
-
- it 'allows user to fork project to group or to user namespace', :js do
- visit project_path(project)
- wait_for_requests
-
- expect(page).not_to have_css('a.disabled', text: 'Fork')
-
- click_link 'Fork'
-
- expect(page).to have_css('.fork-thumbnail')
- expect(page).to have_css('.group-row')
- expect(page).not_to have_css('.fork-thumbnail.disabled')
- end
-
- it 'allows user to fork project to group and not user when exceeded project limit', :js do
- user.projects_limit = 0
- user.save!
-
- visit project_path(project)
- wait_for_requests
-
- expect(page).not_to have_css('a.disabled', text: 'Fork')
-
- click_link 'Fork'
-
- expect(page).to have_css('.fork-thumbnail.disabled')
- expect(page).to have_css('.group-row')
- end
-
- it 'links to the fork if the project was already forked within that namespace', :sidekiq_might_not_need_inline, :js do
- forked_project = fork_project(project, user, namespace: group, repository: true)
-
- visit new_project_fork_path(project)
- wait_for_requests
-
- expect(page).to have_css('.group-row a.btn', text: 'Go to fork')
-
- click_link 'Go to fork'
-
- expect(current_path).to eq(project_path(forked_project))
- end
- end
- end
end
diff --git a/spec/features/projects/integrations/user_activates_issue_tracker_spec.rb b/spec/features/projects/integrations/user_activates_issue_tracker_spec.rb
index b9c2c539899..2821f35f6a6 100644
--- a/spec/features/projects/integrations/user_activates_issue_tracker_spec.rb
+++ b/spec/features/projects/integrations/user_activates_issue_tracker_spec.rb
@@ -34,7 +34,7 @@ RSpec.describe 'User activates issue tracker', :js do
it 'activates the integration' do
expect(page).to have_content("#{tracker} settings saved and active.")
- expect(current_path).to eq(edit_project_integration_path(project, tracker.parameterize(separator: '_')))
+ expect(page).to have_current_path(edit_project_integration_path(project, tracker.parameterize(separator: '_')), ignore_query: true)
end
it 'shows the link in the menu' do
@@ -58,7 +58,7 @@ RSpec.describe 'User activates issue tracker', :js do
end
expect(page).to have_content("#{tracker} settings saved and active.")
- expect(current_path).to eq(edit_project_integration_path(project, tracker.parameterize(separator: '_')))
+ expect(page).to have_current_path(edit_project_integration_path(project, tracker.parameterize(separator: '_')), ignore_query: true)
end
end
end
@@ -73,7 +73,7 @@ RSpec.describe 'User activates issue tracker', :js do
it 'saves but does not activate the integration' do
expect(page).to have_content("#{tracker} settings saved, but not active.")
- expect(current_path).to eq(edit_project_integration_path(project, tracker.parameterize(separator: '_')))
+ expect(page).to have_current_path(edit_project_integration_path(project, tracker.parameterize(separator: '_')), ignore_query: true)
end
it 'does not show the external tracker link in the menu' do
diff --git a/spec/features/projects/integrations/user_activates_jetbrains_teamcity_ci_spec.rb b/spec/features/projects/integrations/user_activates_jetbrains_teamcity_ci_spec.rb
index e6f2e462b8c..f86a1b8a0a4 100644
--- a/spec/features/projects/integrations/user_activates_jetbrains_teamcity_ci_spec.rb
+++ b/spec/features/projects/integrations/user_activates_jetbrains_teamcity_ci_spec.rb
@@ -12,7 +12,7 @@ RSpec.describe 'User activates JetBrains TeamCity CI' do
it 'activates integration', :js do
visit_project_integration('JetBrains TeamCity')
check('Push')
- check('Merge Request')
+ check('Merge request')
fill_in('TeamCity server URL', with: 'http://teamcity.example.com')
fill_in('Build type', with: 'GitlabTest_Build')
fill_in('Username', with: 'user')
diff --git a/spec/features/projects/integrations/user_activates_jira_spec.rb b/spec/features/projects/integrations/user_activates_jira_spec.rb
index 7562dc00092..f855d6befe7 100644
--- a/spec/features/projects/integrations/user_activates_jira_spec.rb
+++ b/spec/features/projects/integrations/user_activates_jira_spec.rb
@@ -20,7 +20,7 @@ RSpec.describe 'User activates Jira', :js do
it 'activates the Jira integration' do
expect(page).to have_content('Jira settings saved and active.')
- expect(current_path).to eq(edit_project_integration_path(project, :jira))
+ expect(page).to have_current_path(edit_project_integration_path(project, :jira), ignore_query: true)
end
unless Gitlab.ee?
@@ -55,7 +55,7 @@ RSpec.describe 'User activates Jira', :js do
click_test_then_save_integration
expect(page).to have_content('Jira settings saved and active.')
- expect(current_path).to eq(edit_project_integration_path(project, :jira))
+ expect(page).to have_current_path(edit_project_integration_path(project, :jira), ignore_query: true)
end
end
end
@@ -72,7 +72,7 @@ RSpec.describe 'User activates Jira', :js do
it 'saves but does not activate the Jira integration' do
expect(page).to have_content('Jira settings saved, but not active.')
- expect(current_path).to eq(edit_project_integration_path(project, :jira))
+ expect(page).to have_current_path(edit_project_integration_path(project, :jira), ignore_query: true)
end
it 'does not show the Jira link in the menu' do
diff --git a/spec/features/projects/integrations/user_activates_slack_slash_command_spec.rb b/spec/features/projects/integrations/user_activates_slack_slash_command_spec.rb
index 7ec469070ea..0b4c9620bdf 100644
--- a/spec/features/projects/integrations/user_activates_slack_slash_command_spec.rb
+++ b/spec/features/projects/integrations/user_activates_slack_slash_command_spec.rb
@@ -24,7 +24,7 @@ RSpec.describe 'Slack slash commands', :js do
click_active_checkbox
click_on 'Save'
- expect(current_path).to eq(edit_project_integration_path(project, :slack_slash_commands))
+ expect(page).to have_current_path(edit_project_integration_path(project, :slack_slash_commands), ignore_query: true)
expect(page).to have_content('Slack slash commands settings saved, but not active.')
end
@@ -32,7 +32,7 @@ RSpec.describe 'Slack slash commands', :js do
fill_in 'Token', with: 'token'
click_on 'Save'
- expect(current_path).to eq(edit_project_integration_path(project, :slack_slash_commands))
+ expect(page).to have_current_path(edit_project_integration_path(project, :slack_slash_commands), ignore_query: true)
expect(page).to have_content('Slack slash commands settings saved and active.')
end
diff --git a/spec/features/projects/jobs/user_browses_job_spec.rb b/spec/features/projects/jobs/user_browses_job_spec.rb
index 12e88bbf6a5..e2dc760beda 100644
--- a/spec/features/projects/jobs/user_browses_job_spec.rb
+++ b/spec/features/projects/jobs/user_browses_job_spec.rb
@@ -15,11 +15,10 @@ RSpec.describe 'User browses a job', :js do
stub_feature_flags(bootstrap_confirmation_modals: false)
sign_in(user)
-
- visit(project_job_path(project, build))
end
it 'erases the job log', :js do
+ visit(project_job_path(project, build))
wait_for_requests
expect(page).to have_content("Job #{build.name}")
@@ -41,6 +40,7 @@ RSpec.describe 'User browses a job', :js do
let!(:build) { create(:ci_build, :success, :unarchived_trace_artifact, :coverage, pipeline: pipeline) }
it 'shows no trace message', :js do
+ visit(project_job_path(project, build))
wait_for_requests
expect(page).to have_content('This job does not have a trace.')
@@ -51,6 +51,7 @@ RSpec.describe 'User browses a job', :js do
let!(:build) { create(:ci_build, :failed, :trace_live, pipeline: pipeline) }
it 'displays the failure reason' do
+ visit(project_job_path(project, build))
wait_for_all_requests
within('.builds-container') do
expect(page).to have_selector(
@@ -62,6 +63,7 @@ RSpec.describe 'User browses a job', :js do
let!(:artifact) { create(:ci_job_artifact, :unarchived_trace_artifact, job: build) }
it 'displays the failure reason from the live trace' do
+ visit(project_job_path(project, build))
wait_for_all_requests
within('.builds-container') do
expect(page).to have_selector(
@@ -75,6 +77,7 @@ RSpec.describe 'User browses a job', :js do
let!(:build_retried) { create(:ci_build, :failed, :retried, :trace_artifact, pipeline: pipeline) }
it 'displays the failure reason and retried label' do
+ visit(project_job_path(project, build))
wait_for_all_requests
within('.builds-container') do
expect(page).to have_selector(
diff --git a/spec/features/projects/jobs/user_browses_jobs_spec.rb b/spec/features/projects/jobs/user_browses_jobs_spec.rb
index a47aab1ec70..fde6240d373 100644
--- a/spec/features/projects/jobs/user_browses_jobs_spec.rb
+++ b/spec/features/projects/jobs/user_browses_jobs_spec.rb
@@ -270,7 +270,7 @@ RSpec.describe 'User browses jobs' do
wait_for_requests
expect(page).to have_content 'You need to sign in'
- expect(page.current_path).to eq("/users/sign_in")
+ expect(page).to have_current_path("/users/sign_in")
end
end
end
diff --git a/spec/features/projects/jobs/user_triggers_manual_job_with_variables_spec.rb b/spec/features/projects/jobs/user_triggers_manual_job_with_variables_spec.rb
index e8a14694d88..eea7e070a35 100644
--- a/spec/features/projects/jobs/user_triggers_manual_job_with_variables_spec.rb
+++ b/spec/features/projects/jobs/user_triggers_manual_job_with_variables_spec.rb
@@ -28,7 +28,7 @@ RSpec.describe 'User triggers manual job with variables', :js do
wait_for_requests
- expect(build.job_variables.as_json).to contain_exactly(
+ expect(build.job_variables.as_json(only: [:key, :value])).to contain_exactly(
hash_including('key' => 'key_name', 'value' => 'key_value'))
end
end
diff --git a/spec/features/projects/jobs_spec.rb b/spec/features/projects/jobs_spec.rb
index a65d2d15c12..b34a615e651 100644
--- a/spec/features/projects/jobs_spec.rb
+++ b/spec/features/projects/jobs_spec.rb
@@ -103,7 +103,7 @@ RSpec.describe 'Jobs', :clean_gitlab_redis_shared_state do
end
it "redirects to new URL" do
- expect(page.current_path).to eq(jobs_url)
+ expect(page).to have_current_path(jobs_url, ignore_query: true)
end
end
end
@@ -313,9 +313,9 @@ RSpec.describe 'Jobs', :clean_gitlab_redis_shared_state do
context 'job is cancelable' do
it 'shows cancel button' do
- click_link 'Cancel'
+ find('[data-testid="cancel-button"]').click
- expect(page.current_path).to eq(job_url)
+ expect(page).to have_current_path(job_url, ignore_query: true)
end
end
end
@@ -384,7 +384,7 @@ RSpec.describe 'Jobs', :clean_gitlab_redis_shared_state do
end
context 'when expire date is defined' do
- let(:expire_at) { Time.now + 7.days }
+ let(:expire_at) { Time.zone.now + 7.days }
context 'when user has ability to update job' do
context 'when artifacts are unlocked' do
@@ -423,7 +423,7 @@ RSpec.describe 'Jobs', :clean_gitlab_redis_shared_state do
end
context 'when artifacts expired' do
- let(:expire_at) { Time.now - 7.days }
+ let(:expire_at) { Time.zone.now - 7.days }
context 'when artifacts are unlocked' do
before do
@@ -459,7 +459,7 @@ RSpec.describe 'Jobs', :clean_gitlab_redis_shared_state do
end
it "redirects to new URL" do
- expect(page.current_path).to eq(job_url)
+ expect(page).to have_current_path(job_url, ignore_query: true)
end
end
@@ -1031,7 +1031,7 @@ RSpec.describe 'Jobs', :clean_gitlab_redis_shared_state do
end
it 'loads the page and shows all needed controls' do
- expect(page).to have_content 'Retry'
+ expect(page).to have_selector('[data-testid="retry-button"')
end
end
end
@@ -1049,7 +1049,7 @@ RSpec.describe 'Jobs', :clean_gitlab_redis_shared_state do
it 'shows the right status and buttons' do
page.within('aside.right-sidebar') do
- expect(page).to have_content 'Cancel'
+ expect(page).to have_selector('[data-testid="cancel-button"')
end
end
end
@@ -1179,7 +1179,7 @@ RSpec.describe 'Jobs', :clean_gitlab_redis_shared_state do
end
it "redirects to new URL" do
- expect(page.current_path).to eq(raw_job_url)
+ expect(page).to have_current_path(raw_job_url, ignore_query: true)
end
end
end
diff --git a/spec/features/projects/labels/sort_labels_spec.rb b/spec/features/projects/labels/sort_labels_spec.rb
index 26b3d08253c..ecbc4b524dc 100644
--- a/spec/features/projects/labels/sort_labels_spec.rb
+++ b/spec/features/projects/labels/sort_labels_spec.rb
@@ -28,7 +28,7 @@ RSpec.describe 'Sort labels', :js do
it 'sorts by date' do
click_button 'Name'
- sort_options = find('ul.dropdown-menu-sort li').all('a').collect(&:text)
+ sort_options = find('ul.dropdown-menu').all('li').collect(&:text)
expect(sort_options[0]).to eq('Name')
expect(sort_options[1]).to eq('Name, descending')
@@ -37,7 +37,7 @@ RSpec.describe 'Sort labels', :js do
expect(sort_options[4]).to eq('Updated date')
expect(sort_options[5]).to eq('Oldest updated')
- click_link 'Name, descending'
+ click_button 'Name, descending'
# assert default sorting
within '.other-labels' do
diff --git a/spec/features/projects/members/group_members_spec.rb b/spec/features/projects/members/group_members_spec.rb
index 94ce18fef93..6aa6acbdae4 100644
--- a/spec/features/projects/members/group_members_spec.rb
+++ b/spec/features/projects/members/group_members_spec.rb
@@ -92,7 +92,6 @@ RSpec.describe 'Projects members', :js do
context 'with a group requester' do
before do
- stub_feature_flags(invite_members_group_modal: false)
group.request_access(group_requester)
visit project_project_members_path(project)
end
diff --git a/spec/features/projects/members/invite_group_spec.rb b/spec/features/projects/members/invite_group_spec.rb
index 066e0b0d20f..9c256504934 100644
--- a/spec/features/projects/members/invite_group_spec.rb
+++ b/spec/features/projects/members/invite_group_spec.rb
@@ -3,47 +3,33 @@
require 'spec_helper'
RSpec.describe 'Project > Members > Invite group', :js do
- include Select2Helper
include ActionView::Helpers::DateHelper
include Spec::Support::Helpers::Features::MembersHelpers
include Spec::Support::Helpers::Features::InviteMembersModalHelper
let_it_be(:maintainer) { create(:user) }
- using RSpec::Parameterized::TableSyntax
+ it 'displays the invite group button' do
+ project = create(:project, namespace: create(:group))
- where(:invite_members_group_modal_enabled, :expected_invite_group_selector) do
- true | 'button[data-qa-selector="invite_a_group_button"]' # rubocop:disable QA/SelectorUsage
- false | '#invite-group-tab'
- end
-
- with_them do
- before do
- stub_feature_flags(invite_members_group_modal: invite_members_group_modal_enabled)
- end
+ project.add_maintainer(maintainer)
+ sign_in(maintainer)
- it 'displays either the invite group button or the form with tabs based on the feature flag' do
- project = create(:project, namespace: create(:group))
+ visit project_project_members_path(project)
- project.add_maintainer(maintainer)
- sign_in(maintainer)
+ expect(page).to have_selector('button[data-test-id="invite-group-button"]')
+ end
- visit project_project_members_path(project)
+ it 'does not display the button when visiting the page not signed in' do
+ project = create(:project, namespace: create(:group))
- expect(page).to have_selector(expected_invite_group_selector)
- end
+ visit project_project_members_path(project)
- it 'does not display either the form or the button when visiting the page not signed in' do
- project = create(:project, namespace: create(:group))
-
- visit project_project_members_path(project)
-
- expect(page).not_to have_selector(expected_invite_group_selector)
- end
+ expect(page).not_to have_selector('button[data-test-id="invite-group-button"]')
end
describe 'Share with group lock' do
- let(:invite_group_selector) { 'button[data-qa-selector="invite_a_group_button"]' } # rubocop:disable QA/SelectorUsage
+ let(:invite_group_selector) { 'button[data-test-id="invite-group-button"]' }
shared_examples 'the project can be shared with groups' do
it 'the "Invite a group" button exists' do
@@ -72,27 +58,7 @@ RSpec.describe 'Project > Members > Invite group', :js do
context 'when the group has "Share with group lock" disabled' do
it_behaves_like 'the project can be shared with groups'
- it 'the project can be shared with another group when the feature flag invite_members_group_modal is disabled' do
- stub_feature_flags(invite_members_group_modal: false)
-
- visit project_project_members_path(project)
-
- expect(page).not_to have_link 'Groups'
-
- click_on 'invite-group-tab'
-
- select2 group_to_share_with.id, from: '#link_group_id'
- page.find('body').click
- find('.btn-confirm').click
-
- click_link 'Groups'
-
- expect(members_table).to have_content(group_to_share_with.name)
- end
-
- it 'the project can be shared with another group when the feature flag invite_members_group_modal is enabled' do
- stub_feature_flags(invite_members_group_modal: true)
-
+ it 'the project can be shared with another group' do
visit project_project_members_path(project)
expect(page).not_to have_link 'Groups'
@@ -250,51 +216,6 @@ RSpec.describe 'Project > Members > Invite group', :js do
end
end
- context 'when invite_members_group_modal feature disabled' do
- let(:group_invite_dropdown) { find('#select2-results-2') }
-
- before do
- stub_feature_flags(invite_members_group_modal: false)
- end
-
- it 'does not show the groups inherited from projects', :aggregate_failures do
- project.add_maintainer(maintainer)
- public_sibbling_group.add_maintainer(maintainer)
-
- visit project_project_members_path(project)
-
- click_on 'Invite group'
- click_on 'Search for a group'
- wait_for_requests
-
- expect(group_invite_dropdown).to have_text(public_membership_group.full_path)
- expect(group_invite_dropdown).to have_text(public_sibbling_group.full_path)
- expect(group_invite_dropdown).to have_text(private_membership_group.full_path)
- expect(group_invite_dropdown).not_to have_text(public_sub_subgroup.full_path)
- expect(group_invite_dropdown).not_to have_text(private_sibbling_group.full_path)
- expect(group_invite_dropdown).not_to have_text(parent_group.full_path, exact: true)
- expect(group_invite_dropdown).not_to have_text(project_group.full_path, exact: true)
- end
-
- it 'does not show the ancestors or project group', :aggregate_failures do
- parent_group.add_maintainer(maintainer)
-
- visit project_project_members_path(project)
-
- click_on 'Invite group'
- click_on 'Search for a group'
- wait_for_requests
-
- expect(group_invite_dropdown).to have_text(public_membership_group.full_path)
- expect(group_invite_dropdown).to have_text(public_sub_subgroup.full_path)
- expect(group_invite_dropdown).to have_text(public_sibbling_group.full_path)
- expect(group_invite_dropdown).to have_text(private_sibbling_group.full_path)
- expect(group_invite_dropdown).to have_text(private_membership_group.full_path)
- expect(group_invite_dropdown).not_to have_text(parent_group.full_path, exact: true)
- expect(group_invite_dropdown).not_to have_text(project_group.full_path, exact: true)
- end
- end
-
def expect_to_have_group(group)
expect(page).to have_selector("[entity-id='#{group.id}']")
end
diff --git a/spec/features/projects/members/member_leaves_project_spec.rb b/spec/features/projects/members/member_leaves_project_spec.rb
index c38292f81bf..78a0a384d2c 100644
--- a/spec/features/projects/members/member_leaves_project_spec.rb
+++ b/spec/features/projects/members/member_leaves_project_spec.rb
@@ -19,7 +19,7 @@ RSpec.describe 'Projects > Members > Member leaves project' do
click_link 'Leave project'
- expect(current_path).to eq(dashboard_projects_path)
+ expect(page).to have_current_path(dashboard_projects_path, ignore_query: true)
expect(project.users.exists?(user.id)).to be_falsey
end
@@ -29,7 +29,7 @@ RSpec.describe 'Projects > Members > Member leaves project' do
page.accept_confirm
wait_for_all_requests
- expect(current_path).to eq(dashboard_projects_path)
+ expect(page).to have_current_path(dashboard_projects_path, ignore_query: true)
sign_in(project.first_owner)
diff --git a/spec/features/projects/members/user_requests_access_spec.rb b/spec/features/projects/members/user_requests_access_spec.rb
index 0b00656f87b..370d7b49832 100644
--- a/spec/features/projects/members/user_requests_access_spec.rb
+++ b/spec/features/projects/members/user_requests_access_spec.rb
@@ -4,12 +4,14 @@ require 'spec_helper'
RSpec.describe 'Projects > Members > User requests access', :js do
let_it_be(:user) { create(:user) }
+ let_it_be(:maintainer) { create(:user) }
let_it_be(:project) { create(:project, :public, :repository) }
- let(:maintainer) { project.first_owner }
+ let(:owner) { project.first_owner }
before do
sign_in(user)
+ project.add_maintainer(maintainer)
visit project_path(project)
stub_feature_flags(bootstrap_confirmation_modals: false)
end
@@ -24,7 +26,7 @@ RSpec.describe 'Projects > Members > User requests access', :js do
it 'user can request access to a project' do
perform_enqueued_jobs { click_link 'Request Access' }
- expect(ActionMailer::Base.deliveries.last.to).to eq [maintainer.notification_email_or_default]
+ expect(ActionMailer::Base.deliveries.map(&:to)).to match_array([[owner.notification_email_or_default], [maintainer.notification_email_or_default]])
expect(ActionMailer::Base.deliveries.last.subject).to eq "Request to join the #{project.full_name} project"
expect(project.requesters.exists?(user_id: user)).to be_truthy
diff --git a/spec/features/projects/navbar_spec.rb b/spec/features/projects/navbar_spec.rb
index 91e643ff258..5098908857a 100644
--- a/spec/features/projects/navbar_spec.rb
+++ b/spec/features/projects/navbar_spec.rb
@@ -16,6 +16,7 @@ RSpec.describe 'Project navbar' do
sign_in(user)
stub_config(registry: { enabled: false })
+ stub_feature_flags(harbor_registry_integration: false)
insert_package_nav(_('Infrastructure'))
insert_infrastructure_registry_nav
insert_infrastructure_google_cloud_nav
@@ -76,4 +77,16 @@ RSpec.describe 'Project navbar' do
it_behaves_like 'verified navigation bar'
end
+
+ context 'when harbor registry is available' do
+ before do
+ stub_feature_flags(harbor_registry_integration: true)
+
+ insert_harbor_registry_nav(_('Infrastructure Registry'))
+
+ visit project_path(project)
+ end
+
+ it_behaves_like 'verified navigation bar'
+ end
end
diff --git a/spec/features/projects/new_project_spec.rb b/spec/features/projects/new_project_spec.rb
index b3fbf5d356e..c57e39b6508 100644
--- a/spec/features/projects/new_project_spec.rb
+++ b/spec/features/projects/new_project_spec.rb
@@ -372,7 +372,7 @@ RSpec.describe 'New project', :js do
it 'shows import instructions' do
expect(page).to have_content('Authenticate with GitHub')
- expect(current_path).to eq new_import_github_path
+ expect(page).to have_current_path new_import_github_path, ignore_query: true
end
end
@@ -383,7 +383,7 @@ RSpec.describe 'New project', :js do
it 'shows import instructions' do
expect(page).to have_content('Manifest file import')
- expect(current_path).to eq new_import_manifest_path
+ expect(page).to have_current_path new_import_manifest_path, ignore_query: true
end
end
end
@@ -405,46 +405,62 @@ RSpec.describe 'New project', :js do
end
end
- context 'from Bitbucket', :js do
- shared_examples 'has a link to bitbucket cloud' do
- context 'when bitbucket is not configured' do
- before do
- allow(Gitlab::Auth::OAuth::Provider).to receive(:enabled?).and_call_original
- allow(Gitlab::Auth::OAuth::Provider)
- .to receive(:enabled?).with(:bitbucket)
- .and_return(false)
+ shared_examples 'has instructions to enable OAuth' do
+ context 'when OAuth is not configured' do
+ before do
+ sign_in(user)
- visit new_project_path
- click_link 'Import project'
- click_link 'Bitbucket Cloud'
- end
+ allow(Gitlab::Auth::OAuth::Provider).to receive(:enabled?).and_call_original
+ allow(Gitlab::Auth::OAuth::Provider)
+ .to receive(:enabled?).with(provider)
+ .and_return(false)
- it 'shows import instructions' do
- expect(find('.modal-body')).to have_content(bitbucket_link_content)
- end
+ visit new_project_path
+ click_link 'Import project'
+ click_link target_link
+ end
+
+ it 'shows import instructions' do
+ expect(find('.modal-body')).to have_content(oauth_config_instructions)
end
end
+ end
+
+ context 'from Bitbucket', :js do
+ let(:target_link) { 'Bitbucket Cloud' }
+ let(:provider) { :bitbucket }
context 'as a user' do
let(:user) { create(:user) }
- let(:bitbucket_link_content) { 'To enable importing projects from Bitbucket, ask your GitLab administrator to configure OAuth integration' }
+ let(:oauth_config_instructions) { 'To enable importing projects from Bitbucket, ask your GitLab administrator to configure OAuth integration' }
- before do
- sign_in(user)
- end
-
- it_behaves_like 'has a link to bitbucket cloud'
+ it_behaves_like 'has instructions to enable OAuth'
end
context 'as an admin' do
let(:user) { create(:admin) }
- let(:bitbucket_link_content) { 'To enable importing projects from Bitbucket, as administrator you need to configure OAuth integration' }
+ let(:oauth_config_instructions) { 'To enable importing projects from Bitbucket, as administrator you need to configure OAuth integration' }
- before do
- sign_in(user)
- end
+ it_behaves_like 'has instructions to enable OAuth'
+ end
+ end
+
+ context 'from GitLab.com', :js do
+ let(:target_link) { 'GitLab.com' }
+ let(:provider) { :gitlab }
+
+ context 'as a user' do
+ let(:user) { create(:user) }
+ let(:oauth_config_instructions) { 'To enable importing projects from GitLab.com, ask your GitLab administrator to configure OAuth integration' }
+
+ it_behaves_like 'has instructions to enable OAuth'
+ end
+
+ context 'as an admin' do
+ let(:user) { create(:admin) }
+ let(:oauth_config_instructions) { 'To enable importing projects from GitLab.com, as administrator you need to configure OAuth integration' }
- it_behaves_like 'has a link to bitbucket cloud'
+ it_behaves_like 'has instructions to enable OAuth'
end
end
end
diff --git a/spec/features/projects/pages/user_adds_domain_spec.rb b/spec/features/projects/pages/user_adds_domain_spec.rb
index bd4cb1aa39b..71bf1c24655 100644
--- a/spec/features/projects/pages/user_adds_domain_spec.rb
+++ b/spec/features/projects/pages/user_adds_domain_spec.rb
@@ -95,7 +95,7 @@ RSpec.describe 'User adds pages domain', :js do
fill_in 'Domain', with: 'my.test.domain.com'
- find('.js-auto-ssl-toggle-container .project-feature-toggle').click
+ find('.js-auto-ssl-toggle-container .js-project-feature-toggle').click
fill_in 'Certificate (PEM)', with: certificate_pem
fill_in 'Key (PEM)', with: certificate_key
diff --git a/spec/features/projects/pages/user_edits_lets_encrypt_settings_spec.rb b/spec/features/projects/pages/user_edits_lets_encrypt_settings_spec.rb
index a3fc5804e13..bdf280f4fe4 100644
--- a/spec/features/projects/pages/user_edits_lets_encrypt_settings_spec.rb
+++ b/spec/features/projects/pages/user_edits_lets_encrypt_settings_spec.rb
@@ -50,7 +50,7 @@ RSpec.describe "Pages with Let's Encrypt", :https_pages_enabled do
expect(page).to have_selector '.card-header', text: 'Certificate'
expect(page).to have_text domain.subject
- find('.js-auto-ssl-toggle-container .project-feature-toggle').click
+ find('.js-auto-ssl-toggle-container .js-project-feature-toggle').click
expect(find("#pages_domain_auto_ssl_enabled", visible: false).value).to eq 'true'
expect(page).not_to have_selector '.card-header', text: 'Certificate'
@@ -74,7 +74,7 @@ RSpec.describe "Pages with Let's Encrypt", :https_pages_enabled do
expect(page).not_to have_field 'Certificate (PEM)', type: 'textarea'
expect(page).not_to have_field 'Key (PEM)', type: 'textarea'
- find('.js-auto-ssl-toggle-container .project-feature-toggle').click
+ find('.js-auto-ssl-toggle-container .js-project-feature-toggle').click
expect(find("#pages_domain_auto_ssl_enabled", visible: false).value).to eq 'false'
expect(page).to have_field 'Certificate (PEM)', type: 'textarea'
diff --git a/spec/features/projects/pipeline_schedules_spec.rb b/spec/features/projects/pipeline_schedules_spec.rb
index aae5ab58b5d..63867a7e900 100644
--- a/spec/features/projects/pipeline_schedules_spec.rb
+++ b/spec/features/projects/pipeline_schedules_spec.rb
@@ -135,8 +135,8 @@ RSpec.describe 'Pipeline Schedules', :js do
end
it 'shows the pipeline schedule with default ref' do
- page.within('.js-target-branch-dropdown') do
- expect(first('.dropdown-toggle-text').text).to eq('master')
+ page.within('[data-testid="schedule-target-ref"]') do
+ expect(first('.gl-new-dropdown-button-text').text).to eq('master')
end
end
end
@@ -148,8 +148,8 @@ RSpec.describe 'Pipeline Schedules', :js do
end
it 'shows the pipeline schedule with default ref' do
- page.within('.js-target-branch-dropdown') do
- expect(first('.dropdown-toggle-text').text).to eq('master')
+ page.within('[data-testid="schedule-target-ref"]') do
+ expect(first('.gl-new-dropdown-button-text').text).to eq('master')
end
end
end
@@ -293,8 +293,8 @@ RSpec.describe 'Pipeline Schedules', :js do
end
def select_target_branch
- find('.js-target-branch-dropdown').click
- click_link 'master'
+ find('[data-testid="schedule-target-ref"] .dropdown-toggle').click
+ click_button 'master'
end
def save_pipeline_schedule
diff --git a/spec/features/projects/pipelines/pipeline_spec.rb b/spec/features/projects/pipelines/pipeline_spec.rb
index 01c942aec4c..6b9dfdf3a7b 100644
--- a/spec/features/projects/pipelines/pipeline_spec.rb
+++ b/spec/features/projects/pipelines/pipeline_spec.rb
@@ -477,7 +477,7 @@ RSpec.describe 'Pipeline', :js do
it 'redirects to pipeline overview page', :sidekiq_inline do
expect(page).to have_content('The pipeline has been deleted')
- expect(current_path).to eq(project_pipelines_path(project))
+ expect(page).to have_current_path(project_pipelines_path(project), ignore_query: true)
end
end
@@ -916,111 +916,7 @@ RSpec.describe 'Pipeline', :js do
end
end
- describe 'GET /:project/-/pipelines/:id/builds with jobs_tab_vue feature flag turned off' do
- include_context 'pipeline builds'
-
- let_it_be(:project) { create(:project, :repository) }
-
- let(:pipeline) { create(:ci_pipeline, project: project, ref: 'master', sha: project.commit.id) }
-
- before do
- stub_feature_flags(jobs_tab_vue: false)
- visit builds_project_pipeline_path(project, pipeline)
- end
-
- it 'shows a list of jobs' do
- expect(page).to have_content('Test')
- expect(page).to have_content(build_passed.id)
- expect(page).to have_content('Deploy')
- expect(page).to have_content(build_failed.id)
- expect(page).to have_content(build_running.id)
- expect(page).to have_content(build_external.id)
- expect(page).to have_content('Retry')
- expect(page).to have_content('Cancel running')
- expect(page).to have_link('Play')
- end
-
- it 'shows jobs tab pane as active' do
- expect(page).to have_css('#js-tab-builds.active')
- end
-
- context 'page tabs' do
- it 'shows Pipeline, Jobs and DAG tabs with link' do
- expect(page).to have_link('Pipeline')
- expect(page).to have_link('Jobs')
- expect(page).to have_link('Needs')
- end
-
- it 'shows counter in Jobs tab' do
- expect(page.find('.js-builds-counter').text).to eq(pipeline.total_size.to_s)
- end
-
- it 'shows Jobs tab as active' do
- expect(page).to have_css('li.js-builds-tab-link .active')
- end
- end
-
- context 'retrying jobs' do
- it { expect(page).not_to have_content('retried') }
-
- context 'when retrying' do
- before do
- find('[data-testid="retryPipeline"]').click
- end
-
- it 'does not show a "Retry" button', :sidekiq_might_not_need_inline do
- expect(page).not_to have_content('Retry')
- end
- end
- end
-
- context 'canceling jobs' do
- it { expect(page).not_to have_selector('.ci-canceled') }
-
- context 'when canceling' do
- before do
- click_on 'Cancel running'
- end
-
- it 'does not show a "Cancel running" button', :sidekiq_might_not_need_inline do
- expect(page).not_to have_content('Cancel running')
- end
- end
- end
-
- context 'playing manual job' do
- before do
- within '.pipeline-holder' do
- click_link('Play')
- end
- end
-
- it { expect(build_manual.reload).to be_pending }
- end
-
- context 'when user unschedules a delayed job' do
- before do
- within '.pipeline-holder' do
- click_link('Unschedule')
- end
- end
-
- it 'unschedules the delayed job and shows play button as a manual job' do
- expect(page).to have_content('Trigger this manual action')
- end
- end
-
- context 'failed jobs' do
- it 'displays a tooltip with the failure reason' do
- page.within('.ci-table') do
- failed_job_link = page.find('.ci-failed')
- expect(failed_job_link[:title]).to eq('Failed - (unknown failure)')
- end
- end
- end
- end
-
- describe 'GET /:project/-/pipelines/:id/builds with jobs_tab_vue feature flag turned on' do
+ describe 'GET /:project/-/pipelines/:id/builds' do
include_context 'pipeline builds'
let_it_be(:project) { create(:project, :repository) }
@@ -1228,7 +1124,7 @@ RSpec.describe 'Pipeline', :js do
it 'displays the pipeline graph' do
subject
- expect(current_path).to eq(pipeline_path(pipeline))
+ expect(page).to have_current_path(pipeline_path(pipeline), ignore_query: true)
expect(page).not_to have_content('Failed Jobs')
expect(page).to have_selector('.js-pipeline-graph')
end
@@ -1413,7 +1309,7 @@ RSpec.describe 'Pipeline', :js do
it 'contains badge that indicates detached merge request pipeline' do
page.within(all('.well-segment')[1]) do
- expect(page).to have_content 'detached'
+ expect(page).to have_content 'merge request'
end
end
end
diff --git a/spec/features/projects/pipelines/pipelines_spec.rb b/spec/features/projects/pipelines/pipelines_spec.rb
index 37ac5a9d5a2..0e1728858ec 100644
--- a/spec/features/projects/pipelines/pipelines_spec.rb
+++ b/spec/features/projects/pipelines/pipelines_spec.rb
@@ -7,6 +7,7 @@ RSpec.describe 'Pipelines', :js do
include Spec::Support::Helpers::ModalHelpers
let(:project) { create(:project) }
+ let(:expected_detached_mr_tag) {'merge request'}
context 'when user is logged in' do
let(:user) { create(:user) }
@@ -160,51 +161,7 @@ RSpec.describe 'Pipelines', :js do
end
end
- context 'when pipeline is detached merge request pipeline, with rearrange_pipelines_table feature flag turned off' do
- let(:merge_request) do
- create(:merge_request,
- :with_detached_merge_request_pipeline,
- source_project: source_project,
- target_project: target_project)
- end
-
- let!(:pipeline) { merge_request.all_pipelines.first }
- let(:source_project) { project }
- let(:target_project) { project }
-
- before do
- stub_feature_flags(rearrange_pipelines_table: false)
-
- visit project_pipelines_path(source_project)
- end
-
- shared_examples_for 'detached merge request pipeline' do
- it 'shows pipeline information without pipeline ref', :sidekiq_might_not_need_inline do
- within '.pipeline-tags' do
- expect(page).to have_content('detached')
- end
-
- within '.branch-commit' do
- expect(page).to have_link(merge_request.iid,
- href: project_merge_request_path(project, merge_request))
- end
-
- within '.branch-commit' do
- expect(page).not_to have_link(pipeline.ref)
- end
- end
- end
-
- it_behaves_like 'detached merge request pipeline'
-
- context 'when source project is a forked project' do
- let(:source_project) { fork_project(project, user, repository: true) }
-
- it_behaves_like 'detached merge request pipeline'
- end
- end
-
- context 'when pipeline is detached merge request pipeline, with rearrange_pipelines_table feature flag turned on' do
+ context 'when pipeline is detached merge request pipeline' do
let(:merge_request) do
create(:merge_request,
:with_detached_merge_request_pipeline,
@@ -217,15 +174,13 @@ RSpec.describe 'Pipelines', :js do
let(:target_project) { project }
before do
- stub_feature_flags(rearrange_pipelines_table: true)
-
visit project_pipelines_path(source_project)
end
shared_examples_for 'detached merge request pipeline' do
it 'shows pipeline information without pipeline ref', :sidekiq_might_not_need_inline do
within '.pipeline-tags' do
- expect(page).to have_content('detached')
+ expect(page).to have_content(expected_detached_mr_tag)
expect(page).to have_link(merge_request.iid,
href: project_merge_request_path(project, merge_request))
@@ -244,52 +199,7 @@ RSpec.describe 'Pipelines', :js do
end
end
- context 'when pipeline is merge request pipeline, with rearrange_pipelines_table feature flag turned off' do
- let(:merge_request) do
- create(:merge_request,
- :with_merge_request_pipeline,
- source_project: source_project,
- target_project: target_project,
- merge_sha: target_project.commit.sha)
- end
-
- let!(:pipeline) { merge_request.all_pipelines.first }
- let(:source_project) { project }
- let(:target_project) { project }
-
- before do
- stub_feature_flags(rearrange_pipelines_table: false)
-
- visit project_pipelines_path(source_project)
- end
-
- shared_examples_for 'Correct merge request pipeline information' do
- it 'does not show detached tag for the pipeline, and shows the link of the merge request, and does not show the ref of the pipeline', :sidekiq_might_not_need_inline do
- within '.pipeline-tags' do
- expect(page).not_to have_content('detached')
- end
-
- within '.branch-commit' do
- expect(page).to have_link(merge_request.iid,
- href: project_merge_request_path(project, merge_request))
- end
-
- within '.branch-commit' do
- expect(page).not_to have_link(pipeline.ref)
- end
- end
- end
-
- it_behaves_like 'Correct merge request pipeline information'
-
- context 'when source project is a forked project' do
- let(:source_project) { fork_project(project, user, repository: true) }
-
- it_behaves_like 'Correct merge request pipeline information'
- end
- end
-
- context 'when pipeline is merge request pipeline, with rearrange_pipelines_table feature flag turned on' do
+ context 'when pipeline is merge request pipeline' do
let(:merge_request) do
create(:merge_request,
:with_merge_request_pipeline,
@@ -303,15 +213,13 @@ RSpec.describe 'Pipelines', :js do
let(:target_project) { project }
before do
- stub_feature_flags(rearrange_pipelines_table: true)
-
visit project_pipelines_path(source_project)
end
shared_examples_for 'Correct merge request pipeline information' do
it 'does not show detached tag for the pipeline, and shows the link of the merge request, and does not show the ref of the pipeline', :sidekiq_might_not_need_inline do
within '.pipeline-tags' do
- expect(page).not_to have_content('detached')
+ expect(page).not_to have_content(expected_detached_mr_tag)
expect(page).to have_link(merge_request.iid,
href: project_merge_request_path(project, merge_request))
@@ -414,7 +322,7 @@ RSpec.describe 'Pipelines', :js do
it "has link to the delayed job's action" do
find('[data-testid="pipelines-manual-actions-dropdown"]').click
- time_diff = [0, delayed_job.scheduled_at - Time.now].max
+ time_diff = [0, delayed_job.scheduled_at - Time.zone.now].max
expect(page).to have_button('delayed job 1')
expect(page).to have_content(Time.at(time_diff).utc.strftime("%H:%M:%S"))
end
@@ -675,28 +583,6 @@ RSpec.describe 'Pipelines', :js do
context 'with pipeline key selection' do
before do
- stub_feature_flags(rearrange_pipelines_table: false)
- visit project_pipelines_path(project)
- wait_for_requests
- end
-
- it 'changes the Pipeline ID column for Pipeline IID' do
- page.find('[data-testid="pipeline-key-dropdown"]').click
-
- within '.gl-new-dropdown-contents' do
- dropdown_options = page.find_all '.gl-new-dropdown-item'
-
- dropdown_options[1].click
- end
-
- expect(page.find('[data-testid="pipeline-th"]')).to have_content 'Pipeline IID'
- expect(page.find('[data-testid="pipeline-url-link"]')).to have_content "##{pipeline.iid}"
- end
- end
-
- context 'with pipeline key selection and rearrange_pipelines_table ff on' do
- before do
- stub_feature_flags(rearrange_pipelines_table: true)
visit project_pipelines_path(project)
wait_for_requests
end
@@ -912,7 +798,7 @@ RSpec.describe 'Pipelines', :js do
end
it 'renders empty state' do
- expect(page).to have_content 'Use a sample CI/CD template'
+ expect(page).to have_content 'Try test template'
end
end
end
@@ -936,7 +822,7 @@ RSpec.describe 'Pipelines', :js do
it 'redirects the user to sign_in and displays the flash alert' do
expect(page).to have_content 'You need to sign in'
- expect(page.current_path).to eq("/users/sign_in")
+ expect(page).to have_current_path("/users/sign_in")
end
end
end
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 561b283ee15..f08f5529472 100644
--- a/spec/features/projects/releases/user_views_edit_release_spec.rb
+++ b/spec/features/projects/releases/user_views_edit_release_spec.rb
@@ -6,7 +6,7 @@ RSpec.describe 'User edits Release', :js do
let_it_be(:project) { create(:project, :repository) }
let_it_be(:user) { create(:user) }
- let(:release) { create(:release, :with_milestones, milestones_count: 1, project: project, name: 'The first release' ) }
+ let(:release) { create(:release, :with_milestones, milestones_count: 1, project: project, name: 'The first release', tag: "v1.1.0" ) }
let(:release_link) { create(:release_link, release: release) }
before do
diff --git a/spec/features/projects/remote_mirror_spec.rb b/spec/features/projects/remote_mirror_spec.rb
index 7bbffe627f6..2c8e895d43d 100644
--- a/spec/features/projects/remote_mirror_spec.rb
+++ b/spec/features/projects/remote_mirror_spec.rb
@@ -25,7 +25,7 @@ RSpec.describe 'Project remote mirror', :feature do
context 'when last_error and last_update_at are present' do
it 'renders error message with timestamp' do
- remote_mirror.update!(last_error: 'Some new error', last_update_at: Time.now - 5.minutes)
+ remote_mirror.update!(last_error: 'Some new error', last_update_at: Time.zone.now - 5.minutes)
visit project_mirror_path(project)
diff --git a/spec/features/projects/settings/registry_settings_spec.rb b/spec/features/projects/settings/registry_settings_spec.rb
index 509729d526d..ff28d59ed08 100644
--- a/spec/features/projects/settings/registry_settings_spec.rb
+++ b/spec/features/projects/settings/registry_settings_spec.rb
@@ -3,8 +3,6 @@
require 'spec_helper'
RSpec.describe 'Project > Settings > CI/CD > Container registry tag expiration policy', :js do
- using RSpec::Parameterized::TableSyntax
-
let_it_be(:user) { create(:user) }
let_it_be(:project, reload: true) { create(:project, namespace: user.namespace) }
@@ -63,31 +61,34 @@ RSpec.describe 'Project > Settings > CI/CD > Container registry tag expiration p
end
context 'with a project without expiration policy' do
- where(:application_setting, :feature_flag, :result) do
- true | true | :available_section
- true | false | :available_section
- false | true | :available_section
- false | false | :disabled_message
+ before do
+ project.container_expiration_policy.destroy!
+ end
+
+ context 'with container_expiration_policies_enable_historic_entries enabled' do
+ before do
+ stub_application_setting(container_expiration_policies_enable_historic_entries: true)
+ end
+
+ it 'displays the related section' do
+ subject
+
+ within '[data-testid="registry-settings-app"]' do
+ expect(find('[data-testid="enable-toggle"]')).to have_content('Disabled - Tags will not be automatically deleted.')
+ end
+ end
end
- with_them do
+ context 'with container_expiration_policies_enable_historic_entries disabled' do
before do
- project.container_expiration_policy.destroy!
- stub_feature_flags(container_expiration_policies_historic_entry: false)
- stub_application_setting(container_expiration_policies_enable_historic_entries: application_setting)
- stub_feature_flags(container_expiration_policies_historic_entry: project) if feature_flag
+ stub_application_setting(container_expiration_policies_enable_historic_entries: false)
end
- it 'displays the expected result' do
+ it 'does not display the related section' do
subject
within '[data-testid="registry-settings-app"]' do
- case result
- when :available_section
- expect(find('[data-testid="enable-toggle"]')).to have_content('Disabled - Tags will not be automatically deleted.')
- when :disabled_message
- expect(find('.gl-alert-title')).to have_content('Cleanup policy for tags is disabled')
- end
+ expect(find('.gl-alert-title')).to have_content('Cleanup policy for tags is disabled')
end
end
end
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 d16295aedbe..0fc12f93850 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
@@ -20,7 +20,7 @@ RSpec.describe "User interacts with deploy keys", :js do
click_button("Enable")
expect(page).not_to have_selector(".gl-spinner")
- expect(current_path).to eq(project_settings_repository_path(project))
+ expect(page).to have_current_path(project_settings_repository_path(project), ignore_query: true)
find(".js-deployKeys-tab-enabled_keys").click
@@ -96,7 +96,7 @@ RSpec.describe "User interacts with deploy keys", :js do
click_button("Add key")
- expect(current_path).to eq(project_settings_repository_path(project))
+ expect(page).to have_current_path(project_settings_repository_path(project), ignore_query: true)
page.within(".deploy-keys") do
expect(page).to have_content(deploy_key_title)
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 31dc939e6b8..2fe06414b32 100644
--- a/spec/features/projects/settings/user_manages_project_members_spec.rb
+++ b/spec/features/projects/settings/user_manages_project_members_spec.rb
@@ -4,7 +4,6 @@ require 'spec_helper'
RSpec.describe 'Projects > Settings > User manages project members' do
include Spec::Support::Helpers::Features::MembersHelpers
- include Select2Helper
include Spec::Support::Helpers::ModalHelpers
let(:group) { create(:group, name: 'OpenSource') }
@@ -57,28 +56,6 @@ RSpec.describe 'Projects > Settings > User manages project members' do
expect(find_member_row(user_mike)).to have_content('Reporter')
end
- describe 'when the :invite_members_group_modal is disabled' do
- before do
- stub_feature_flags(invite_members_group_modal: false)
- end
-
- it 'imports a team from another project', :js do
- project2.add_maintainer(user)
- project2.add_reporter(user_mike)
-
- visit(project_project_members_path(project))
-
- page.within('.invite-users-form') do
- click_link('Import')
- end
-
- select2(project2.id, from: '#source_project_id')
- click_button('Import project members')
-
- expect(find_member_row(user_mike)).to have_content('Reporter')
- end
- end
-
it 'shows all members of project shared group', :js do
group.add_owner(user)
group.add_developer(user_dmitriy)
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 1ff976eb800..2e2d7119e2e 100644
--- a/spec/features/projects/settings/user_renames_a_project_spec.rb
+++ b/spec/features/projects/settings/user_renames_a_project_spec.rb
@@ -82,7 +82,7 @@ RSpec.describe 'Projects > Settings > User renames a project' do
new_path = namespace_project_path(project.namespace, 'bar')
visit new_path
- expect(current_path).to eq(new_path)
+ expect(page).to have_current_path(new_path, ignore_query: true)
expect(find('.breadcrumbs')).to have_content(project.name)
end
@@ -92,7 +92,7 @@ RSpec.describe 'Projects > Settings > User renames a project' do
new_path = namespace_project_path(project.namespace, 'bar')
visit old_path
- expect(current_path).to eq(new_path)
+ expect(page).to have_current_path(new_path, ignore_query: true)
expect(find('.breadcrumbs')).to have_content(project.name)
end
@@ -103,7 +103,7 @@ RSpec.describe 'Projects > Settings > User renames a project' do
new_project = create(:project, namespace: user.namespace, path: 'gitlabhq', name: 'quz')
visit old_path
- expect(current_path).to eq(old_path)
+ expect(page).to have_current_path(old_path, ignore_query: true)
expect(find('.breadcrumbs')).to have_content(new_project.name)
end
end
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 a88b9101869..6041dca305b 100644
--- a/spec/features/projects/settings/user_transfers_a_project_spec.rb
+++ b/spec/features/projects/settings/user_transfers_a_project_spec.rb
@@ -51,13 +51,13 @@ RSpec.describe 'Projects > Settings > User transfers a project', :js do
visit new_path
wait_for_requests
- expect(current_path).to eq(new_path)
+ expect(page).to have_current_path(new_path, ignore_query: true)
expect(find('.breadcrumbs')).to have_content(project.name)
visit old_path
wait_for_requests
- expect(current_path).to eq(new_path)
+ expect(page).to have_current_path(new_path, ignore_query: true)
expect(find('.breadcrumbs')).to have_content(project.name)
end
@@ -69,7 +69,7 @@ RSpec.describe 'Projects > Settings > User transfers a project', :js do
new_project = create(:project, namespace: user.namespace, path: project_path)
visit old_path
- expect(current_path).to eq(old_path)
+ expect(page).to have_current_path(old_path, ignore_query: true)
expect(find('.breadcrumbs')).to have_content(new_project.name)
end
end
diff --git a/spec/features/projects/settings/webhooks_settings_spec.rb b/spec/features/projects/settings/webhooks_settings_spec.rb
index 8d73ffecd46..c84de7fc03f 100644
--- a/spec/features/projects/settings/webhooks_settings_spec.rb
+++ b/spec/features/projects/settings/webhooks_settings_spec.rb
@@ -86,7 +86,7 @@ RSpec.describe 'Projects > Settings > Webhook Settings' do
find('.hook-test-button.dropdown').click
click_link 'Push events'
- expect(current_path).to eq(webhooks_path)
+ expect(page).to have_current_path(webhooks_path, ignore_query: true)
end
context 'delete existing webhook' do
@@ -137,7 +137,7 @@ RSpec.describe 'Projects > Settings > Webhook Settings' do
click_link 'View details'
click_link 'Resend Request'
- expect(current_path).to eq(edit_project_hook_path(project, hook))
+ expect(page).to have_current_path(edit_project_hook_path(project, hook), ignore_query: true)
end
end
end
diff --git a/spec/features/projects/show/redirects_spec.rb b/spec/features/projects/show/redirects_spec.rb
index 3ac82244ded..55069cdd6c5 100644
--- a/spec/features/projects/show/redirects_spec.rb
+++ b/spec/features/projects/show/redirects_spec.rb
@@ -22,13 +22,13 @@ RSpec.describe 'Projects > Show > Redirects' do
it 'redirects to sign in page when project is private' do
visit project_path(private_project)
- expect(current_path).to eq(new_user_session_path)
+ expect(page).to have_current_path(new_user_session_path, ignore_query: true)
end
it 'redirects to sign in page when project does not exist' do
visit project_path(build(:project, :public))
- expect(current_path).to eq(new_user_session_path)
+ expect(page).to have_current_path(new_user_session_path, ignore_query: true)
end
it 'redirects to public project page after signing in' do
@@ -41,7 +41,7 @@ RSpec.describe 'Projects > Show > Redirects' do
click_button 'Sign in'
expect(status_code).to eq(200)
- expect(current_path).to eq("/#{public_project.full_path}")
+ expect(page).to have_current_path("/#{public_project.full_path}", ignore_query: true)
end
it 'redirects to private project page after sign in' do
@@ -53,7 +53,7 @@ RSpec.describe 'Projects > Show > Redirects' do
click_button 'Sign in'
expect(status_code).to eq(200)
- expect(current_path).to eq("/#{private_project.full_path}")
+ expect(page).to have_current_path("/#{private_project.full_path}", ignore_query: true)
end
context 'when signed in' do
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 99f84c19bf3..aa61b629d92 100644
--- a/spec/features/projects/show/user_interacts_with_stars_spec.rb
+++ b/spec/features/projects/show/user_interacts_with_stars_spec.rb
@@ -34,7 +34,7 @@ RSpec.describe 'Projects > Show > User interacts with project stars' do
find('.star-btn').click
- expect(current_path).to eq(new_user_session_path)
+ expect(page).to have_current_path(new_user_session_path, ignore_query: true)
end
end
end
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 5270939f681..608bb4c5997 100644
--- a/spec/features/projects/show/user_sees_git_instructions_spec.rb
+++ b/spec/features/projects/show/user_sees_git_instructions_spec.rb
@@ -14,7 +14,7 @@ RSpec.describe 'Projects > Show > User sees Git instructions' do
shared_examples_for 'redirects to the sign in page' do
it 'redirects to the sign in page' do
- expect(current_path).to eq(new_user_session_path)
+ expect(page).to have_current_path(new_user_session_path, ignore_query: true)
end
end
diff --git a/spec/features/projects/tags/user_views_tags_spec.rb b/spec/features/projects/tags/user_views_tags_spec.rb
index ef363ab6158..e1962ad3df5 100644
--- a/spec/features/projects/tags/user_views_tags_spec.rb
+++ b/spec/features/projects/tags/user_views_tags_spec.rb
@@ -15,7 +15,7 @@ RSpec.describe 'User views tags', :feature do
it do
visit project_tags_path(project, format: :atom)
- expect(page.current_path).to eq("/users/sign_in")
+ expect(page).to have_current_path("/users/sign_in")
end
end
diff --git a/spec/features/projects/tracings_spec.rb b/spec/features/projects/tracings_spec.rb
index c4a4f1382ed..b79a0427ef6 100644
--- a/spec/features/projects/tracings_spec.rb
+++ b/spec/features/projects/tracings_spec.rb
@@ -3,6 +3,8 @@
require 'spec_helper'
RSpec.describe 'Tracings Content Security Policy' do
+ include ContentSecurityPolicyHelpers
+
let_it_be(:project) { create(:project) }
let_it_be(:user) { create(:user) }
@@ -18,10 +20,7 @@ RSpec.describe 'Tracings Content Security Policy' do
context 'when there is no global config' do
before do
- expect_next_instance_of(Projects::TracingsController) do |controller|
- expect(controller).to receive(:current_content_security_policy)
- .and_return(ActionDispatch::ContentSecurityPolicy.new)
- end
+ setup_csp_for_controller(Projects::TracingsController)
end
it 'does not add CSP directives' do
@@ -37,9 +36,7 @@ RSpec.describe 'Tracings Content Security Policy' do
p.frame_src 'https://global-policy.com'
end
- expect_next_instance_of(Projects::TracingsController) do |controller|
- expect(controller).to receive(:current_content_security_policy).and_return(csp)
- end
+ setup_existing_csp_for_controller(Projects::TracingsController, csp)
end
context 'when external_url is set' do
diff --git a/spec/features/projects/user_creates_project_spec.rb b/spec/features/projects/user_creates_project_spec.rb
index c4e2e3353a4..6491a7425f7 100644
--- a/spec/features/projects/user_creates_project_spec.rb
+++ b/spec/features/projects/user_creates_project_spec.rb
@@ -25,7 +25,7 @@ RSpec.describe 'User creates a project', :js do
project = Project.last
- expect(current_path).to eq(project_path(project))
+ expect(page).to have_current_path(project_path(project), ignore_query: true)
expect(page).to have_content('Empty')
expect(page).to have_content('git init')
expect(page).to have_content('git remote')
@@ -47,7 +47,7 @@ RSpec.describe 'User creates a project', :js do
project = Project.last
- expect(current_path).to eq(project_path(project))
+ expect(page).to have_current_path(project_path(project), ignore_query: true)
expect(page).to have_content('With initial commits')
expect(page).to have_content('Configure SAST in `.gitlab-ci.yml`, creating this file if it does not already exist')
expect(page).to have_content('README.md Initial commit')
@@ -72,7 +72,7 @@ RSpec.describe 'User creates a project', :js do
project = Project.last
- expect(current_path).to eq(project_path(project))
+ expect(page).to have_current_path(project_path(project), ignore_query: true)
expect(page).to have_content('With initial commits')
expect(page).to have_content('Configure SAST in `.gitlab-ci.yml`, creating this file if it does not already exist')
expect(page).to have_content('README.md Initial commit')
diff --git a/spec/features/projects/wikis_spec.rb b/spec/features/projects/wikis_spec.rb
index 621f8c71b20..879ffd2932b 100644
--- a/spec/features/projects/wikis_spec.rb
+++ b/spec/features/projects/wikis_spec.rb
@@ -2,7 +2,7 @@
require "spec_helper"
-RSpec.describe 'Project wikis' do
+RSpec.describe 'Project wikis', :js do
let_it_be(:user) { create(:user) }
let(:wiki) { create(:project_wiki, user: user, project: project) }
diff --git a/spec/features/refactor_blob_viewer_disabled/projects/blobs/balsamiq_spec.rb b/spec/features/refactor_blob_viewer_disabled/projects/blobs/balsamiq_spec.rb
new file mode 100644
index 00000000000..3638e98a08a
--- /dev/null
+++ b/spec/features/refactor_blob_viewer_disabled/projects/blobs/balsamiq_spec.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Balsamiq file blob', :js do
+ let(:project) { create(:project, :public, :repository) }
+
+ before do
+ stub_feature_flags(refactor_blob_viewer: false)
+ visit project_blob_path(project, 'add-balsamiq-file/files/images/balsamiq.bmpr')
+
+ wait_for_requests
+ end
+
+ it 'displays Balsamiq file content' do
+ expect(page).to have_content("Mobile examples")
+ end
+end
diff --git a/spec/features/refactor_blob_viewer_disabled/projects/blobs/blob_line_permalink_updater_spec.rb b/spec/features/refactor_blob_viewer_disabled/projects/blobs/blob_line_permalink_updater_spec.rb
new file mode 100644
index 00000000000..e8c026a254e
--- /dev/null
+++ b/spec/features/refactor_blob_viewer_disabled/projects/blobs/blob_line_permalink_updater_spec.rb
@@ -0,0 +1,103 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Blob button line permalinks (BlobLinePermalinkUpdater)', :js do
+ include TreeHelper
+
+ let(:project) { create(:project, :public, :repository) }
+ let(:path) { 'CHANGELOG' }
+ let(:sha) { project.repository.commit.sha }
+
+ before do
+ stub_feature_flags(refactor_blob_viewer: false)
+ end
+
+ describe 'On a file(blob)' do
+ def get_absolute_url(path = "")
+ "http://#{page.server.host}:#{page.server.port}#{path}"
+ end
+
+ def visit_blob(fragment = nil)
+ visit project_blob_path(project, tree_join('master', path), anchor: fragment)
+ end
+
+ describe 'Click "Permalink" button' do
+ it 'works with no initial line number fragment hash' do
+ visit_blob
+
+ expect(find('.js-data-file-blob-permalink-url')['href']).to eq(get_absolute_url(project_blob_path(project, tree_join(sha, path))))
+ end
+
+ it 'maintains intitial fragment hash' do
+ fragment = "L3"
+
+ visit_blob(fragment)
+
+ expect(find('.js-data-file-blob-permalink-url')['href']).to eq(get_absolute_url(project_blob_path(project, tree_join(sha, path), anchor: fragment)))
+ end
+
+ it 'changes fragment hash if line number clicked' do
+ ending_fragment = "L5"
+
+ visit_blob
+
+ find('#L3').click
+ find("##{ending_fragment}").click
+
+ expect(find('.js-data-file-blob-permalink-url')['href']).to eq(get_absolute_url(project_blob_path(project, tree_join(sha, path), anchor: ending_fragment)))
+ end
+
+ it 'with initial fragment hash, changes fragment hash if line number clicked' do
+ fragment = "L1"
+ ending_fragment = "L5"
+
+ visit_blob(fragment)
+
+ find('#L3').click
+ find("##{ending_fragment}").click
+
+ expect(find('.js-data-file-blob-permalink-url')['href']).to eq(get_absolute_url(project_blob_path(project, tree_join(sha, path), anchor: ending_fragment)))
+ end
+ end
+
+ describe 'Click "Blame" button' do
+ it 'works with no initial line number fragment hash' do
+ visit_blob
+
+ expect(find('.js-blob-blame-link')['href']).to eq(get_absolute_url(project_blame_path(project, tree_join('master', path))))
+ end
+
+ it 'maintains intitial fragment hash' do
+ fragment = "L3"
+
+ visit_blob(fragment)
+
+ expect(find('.js-blob-blame-link')['href']).to eq(get_absolute_url(project_blame_path(project, tree_join('master', path), anchor: fragment)))
+ end
+
+ it 'changes fragment hash if line number clicked' do
+ ending_fragment = "L5"
+
+ visit_blob
+
+ find('#L3').click
+ find("##{ending_fragment}").click
+
+ expect(find('.js-blob-blame-link')['href']).to eq(get_absolute_url(project_blame_path(project, tree_join('master', path), anchor: ending_fragment)))
+ end
+
+ it 'with initial fragment hash, changes fragment hash if line number clicked' do
+ fragment = "L1"
+ ending_fragment = "L5"
+
+ visit_blob(fragment)
+
+ find('#L3').click
+ find("##{ending_fragment}").click
+
+ expect(find('.js-blob-blame-link')['href']).to eq(get_absolute_url(project_blame_path(project, tree_join('master', path), anchor: ending_fragment)))
+ end
+ end
+ end
+end
diff --git a/spec/features/refactor_blob_viewer_disabled/projects/blobs/blob_show_spec.rb b/spec/features/refactor_blob_viewer_disabled/projects/blobs/blob_show_spec.rb
new file mode 100644
index 00000000000..659014c922b
--- /dev/null
+++ b/spec/features/refactor_blob_viewer_disabled/projects/blobs/blob_show_spec.rb
@@ -0,0 +1,1154 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'File blob', :js do
+ include MobileHelpers
+
+ let(:project) { create(:project, :public, :repository) }
+
+ before do
+ stub_feature_flags(refactor_blob_viewer: false)
+ end
+
+ def visit_blob(path, anchor: nil, ref: 'master', **additional_args)
+ visit project_blob_path(project, File.join(ref, path), anchor: anchor, **additional_args)
+
+ wait_for_requests
+ end
+
+ def create_file(file_name, content)
+ project.add_maintainer(project.creator)
+
+ Files::CreateService.new(
+ project,
+ project.creator,
+ start_branch: 'master',
+ branch_name: 'master',
+ commit_message: "Add #{file_name}",
+ file_path: file_name,
+ file_content: <<-SPEC.strip_heredoc
+ #{content}
+ SPEC
+ ).execute
+ end
+
+ context 'Ruby file' do
+ before do
+ visit_blob('files/ruby/popen.rb')
+
+ wait_for_requests
+ end
+
+ it 'displays the blob' do
+ aggregate_failures do
+ # shows highlighted Ruby code
+ expect(page).to have_css(".js-syntax-highlight")
+ expect(page).to have_content("require 'fileutils'")
+
+ # does not show a viewer switcher
+ expect(page).not_to have_selector('.js-blob-viewer-switcher')
+
+ # shows an enabled copy button
+ expect(page).to have_selector('.js-copy-blob-source-btn:not(.disabled)')
+
+ # shows a raw button
+ expect(page).to have_link('Open raw')
+ end
+ end
+
+ it 'displays file actions on all screen sizes' do
+ file_actions_selector = '.file-actions'
+
+ resize_screen_sm
+ expect(page).to have_selector(file_actions_selector, visible: true)
+
+ resize_screen_xs
+ expect(page).to have_selector(file_actions_selector, visible: true)
+ end
+ end
+
+ context 'Markdown file' do
+ context 'visiting directly' do
+ before do
+ visit_blob('files/markdown/ruby-style-guide.md')
+
+ wait_for_requests
+ end
+
+ it 'displays the blob using the rich viewer' do
+ aggregate_failures do
+ # hides the simple viewer
+ expect(page).to have_selector('.blob-viewer[data-type="simple"]', visible: false)
+ expect(page).to have_selector('.blob-viewer[data-type="rich"]')
+
+ # shows rendered Markdown
+ expect(page).to have_link("PEP-8")
+
+ # shows a viewer switcher
+ expect(page).to have_selector('.js-blob-viewer-switcher')
+
+ # shows a disabled copy button
+ expect(page).to have_selector('.js-copy-blob-source-btn.disabled')
+
+ # shows a raw button
+ expect(page).to have_link('Open raw')
+ end
+ end
+
+ context 'switching to the simple viewer' do
+ before do
+ find('.js-blob-viewer-switch-btn[data-viewer=simple]').click
+
+ wait_for_requests
+ end
+
+ it 'displays the blob using the simple viewer' do
+ aggregate_failures do
+ # hides the rich viewer
+ expect(page).to have_selector('.blob-viewer[data-type="simple"]')
+ expect(page).to have_selector('.blob-viewer[data-type="rich"]', visible: false)
+
+ # shows highlighted Markdown code
+ expect(page).to have_css(".js-syntax-highlight")
+ expect(page).to have_content("[PEP-8](http://www.python.org/dev/peps/pep-0008/)")
+
+ # shows an enabled copy button
+ expect(page).to have_selector('.js-copy-blob-source-btn:not(.disabled)')
+ end
+ end
+
+ context 'switching to the rich viewer again' do
+ before do
+ find('.js-blob-viewer-switch-btn[data-viewer=rich]').click
+
+ wait_for_requests
+ end
+
+ it 'displays the blob using the rich viewer' do
+ aggregate_failures do
+ # hides the simple viewer
+ expect(page).to have_selector('.blob-viewer[data-type="simple"]', visible: false)
+ expect(page).to have_selector('.blob-viewer[data-type="rich"]')
+
+ # shows an enabled copy button
+ expect(page).to have_selector('.js-copy-blob-source-btn:not(.disabled)')
+ end
+ end
+ end
+ end
+ end
+
+ context 'when ref switch' do
+ def switch_ref_to(ref_name)
+ first('.qa-branches-select').click # rubocop:disable QA/SelectorUsage
+
+ page.within '.project-refs-form' do
+ click_link ref_name
+ wait_for_requests
+ end
+ end
+
+ it 'displays single highlighted line number of different ref' do
+ visit_blob('files/js/application.js', anchor: 'L1')
+
+ switch_ref_to('feature')
+
+ page.within '.blob-content' do
+ expect(find_by_id('LC1')[:class]).to include("hll")
+ end
+ end
+
+ it 'displays multiple highlighted line numbers of different ref' do
+ visit_blob('files/js/application.js', anchor: 'L1-3')
+
+ switch_ref_to('feature')
+
+ page.within '.blob-content' do
+ expect(find_by_id('LC1')[:class]).to include("hll")
+ expect(find_by_id('LC2')[:class]).to include("hll")
+ expect(find_by_id('LC3')[:class]).to include("hll")
+ end
+ end
+
+ it 'displays no highlighted number of different ref' do
+ Files::UpdateService.new(
+ project,
+ project.first_owner,
+ commit_message: 'Update',
+ start_branch: 'feature',
+ branch_name: 'feature',
+ file_path: 'files/js/application.js',
+ file_content: 'new content'
+ ).execute
+
+ project.commit('feature').diffs.diff_files.first
+
+ visit_blob('files/js/application.js', anchor: 'L3')
+ switch_ref_to('feature')
+
+ page.within '.blob-content' do
+ expect(page).not_to have_css('.hll')
+ end
+ end
+
+ context 'successfully change ref of similar name' do
+ before do
+ project.repository.create_branch('dev')
+ project.repository.create_branch('development')
+ end
+
+ it 'switch ref from longer to shorter ref name' do
+ visit_blob('files/js/application.js', ref: 'development')
+ switch_ref_to('dev')
+
+ aggregate_failures do
+ expect(page.find('.file-title-name').text).to eq('application.js')
+ expect(page).not_to have_css('flash-container')
+ end
+ end
+
+ it 'switch ref from shorter to longer ref name' do
+ visit_blob('files/js/application.js', ref: 'dev')
+ switch_ref_to('development')
+
+ aggregate_failures do
+ expect(page.find('.file-title-name').text).to eq('application.js')
+ expect(page).not_to have_css('flash-container')
+ end
+ end
+ end
+
+ it 'successfully changes ref when the ref name matches the project name' do
+ project.repository.create_branch(project.name)
+
+ visit_blob('files/js/application.js', ref: project.name)
+ switch_ref_to('master')
+
+ aggregate_failures do
+ expect(page.find('.file-title-name').text).to eq('application.js')
+ expect(page).not_to have_css('flash-container')
+ end
+ end
+ end
+
+ context 'visiting with a line number anchor' do
+ before do
+ visit_blob('files/markdown/ruby-style-guide.md', anchor: 'L1')
+ end
+
+ it 'displays the blob using the simple viewer' do
+ aggregate_failures do
+ # hides the rich viewer
+ expect(page).to have_selector('.blob-viewer[data-type="simple"]')
+ expect(page).to have_selector('.blob-viewer[data-type="rich"]', visible: false)
+
+ # highlights the line in question
+ expect(page).to have_selector('#LC1.hll')
+
+ # shows highlighted Markdown code
+ expect(page).to have_css(".js-syntax-highlight")
+ expect(page).to have_content("[PEP-8](http://www.python.org/dev/peps/pep-0008/)")
+
+ # shows an enabled copy button
+ expect(page).to have_selector('.js-copy-blob-source-btn:not(.disabled)')
+ end
+ end
+ end
+ end
+
+ context 'Markdown rendering' do
+ before do
+ project.add_maintainer(project.creator)
+
+ Files::CreateService.new(
+ project,
+ project.creator,
+ start_branch: 'master',
+ branch_name: 'master',
+ commit_message: "Add RedCarpet and CommonMark Markdown ",
+ file_path: 'files/commonmark/file.md',
+ file_content: "1. one\n - sublist\n"
+ ).execute
+ end
+
+ context 'when rendering default markdown' do
+ before do
+ visit_blob('files/commonmark/file.md')
+
+ wait_for_requests
+ end
+
+ it 'renders using CommonMark' do
+ aggregate_failures do
+ expect(page).to have_content("sublist")
+ expect(page).not_to have_xpath("//ol//li//ul")
+ end
+ end
+ end
+ end
+
+ context 'Markdown file (stored in LFS)' do
+ before do
+ project.add_maintainer(project.creator)
+
+ Files::CreateService.new(
+ project,
+ project.creator,
+ start_branch: 'master',
+ branch_name: 'master',
+ commit_message: "Add Markdown in LFS",
+ file_path: 'files/lfs/file.md',
+ file_content: project.repository.blob_at('master', 'files/lfs/lfs_object.iso').data
+ ).execute
+ end
+
+ context 'when LFS is enabled on the project' do
+ before do
+ allow(Gitlab.config.lfs).to receive(:enabled).and_return(true)
+ project.update_attribute(:lfs_enabled, true)
+
+ visit_blob('files/lfs/file.md')
+
+ wait_for_requests
+ end
+
+ it 'displays an error' do
+ aggregate_failures do
+ # hides the simple viewer
+ expect(page).to have_selector('.blob-viewer[data-type="simple"]', visible: false)
+ expect(page).to have_selector('.blob-viewer[data-type="rich"]')
+
+ # shows an error message
+ expect(page).to have_content('The rendered file could not be displayed because it is stored in LFS. You can download it instead.')
+
+ # shows a viewer switcher
+ expect(page).to have_selector('.js-blob-viewer-switcher')
+
+ # does not show a copy button
+ expect(page).not_to have_selector('.js-copy-blob-source-btn')
+
+ # shows a download button
+ expect(page).to have_link('Download')
+ end
+ end
+
+ context 'switching to the simple viewer' do
+ before do
+ find('.js-blob-viewer-switcher .js-blob-viewer-switch-btn[data-viewer=simple]').click
+
+ wait_for_requests
+ end
+
+ it 'displays an error' do
+ aggregate_failures do
+ # hides the rich viewer
+ expect(page).to have_selector('.blob-viewer[data-type="simple"]')
+ expect(page).to have_selector('.blob-viewer[data-type="rich"]', visible: false)
+
+ # shows an error message
+ expect(page).to have_content('The source could not be displayed because it is stored in LFS. You can download it instead.')
+
+ # does not show a copy button
+ expect(page).not_to have_selector('.js-copy-blob-source-btn')
+ end
+ end
+ end
+ end
+
+ context 'when LFS is disabled on the project' do
+ before do
+ visit_blob('files/lfs/file.md')
+
+ wait_for_requests
+ end
+
+ it 'displays the blob' do
+ aggregate_failures do
+ # shows text
+ expect(page).to have_content('size 1575078')
+
+ # does not show a viewer switcher
+ expect(page).not_to have_selector('.js-blob-viewer-switcher')
+
+ # shows an enabled copy button
+ expect(page).to have_selector('.js-copy-blob-source-btn:not(.disabled)')
+
+ # shows a raw button
+ expect(page).to have_link('Open raw')
+ end
+ end
+ end
+ end
+
+ context 'PDF file' do
+ before do
+ project.add_maintainer(project.creator)
+
+ Files::CreateService.new(
+ project,
+ project.creator,
+ start_branch: 'master',
+ branch_name: 'master',
+ commit_message: "Add PDF",
+ file_path: 'files/test.pdf',
+ file_content: project.repository.blob_at('add-pdf-file', 'files/pdf/test.pdf').data
+ ).execute
+
+ visit_blob('files/test.pdf')
+
+ wait_for_requests
+ end
+
+ it 'displays the blob' do
+ aggregate_failures do
+ # shows rendered PDF
+ expect(page).to have_selector('.js-pdf-viewer')
+
+ # does not show a viewer switcher
+ expect(page).not_to have_selector('.js-blob-viewer-switcher')
+
+ # does not show a copy button
+ expect(page).not_to have_selector('.js-copy-blob-source-btn')
+
+ # shows a download button
+ expect(page).to have_link('Download')
+ end
+ end
+ end
+
+ context 'Jupiter Notebook file' do
+ before do
+ project.add_maintainer(project.creator)
+
+ Files::CreateService.new(
+ project,
+ project.creator,
+ start_branch: 'master',
+ branch_name: 'master',
+ commit_message: "Add Jupiter Notebook",
+ file_path: 'files/basic.ipynb',
+ file_content: project.repository.blob_at('add-ipython-files', 'files/ipython/basic.ipynb').data
+ ).execute
+
+ visit_blob('files/basic.ipynb')
+
+ wait_for_requests
+ end
+
+ it 'displays the blob' do
+ aggregate_failures do
+ # shows rendered notebook
+ expect(page).to have_selector('.js-notebook-viewer-mounted')
+
+ # does show a viewer switcher
+ expect(page).to have_selector('.js-blob-viewer-switcher')
+
+ # show a disabled copy button
+ expect(page).to have_selector('.js-copy-blob-source-btn.disabled')
+
+ # shows a raw button
+ expect(page).to have_link('Open raw')
+
+ # shows a download button
+ expect(page).to have_link('Download')
+
+ # shows the rendered notebook
+ expect(page).to have_content('test')
+ end
+ end
+ end
+
+ context 'ISO file (stored in LFS)' do
+ context 'when LFS is enabled on the project' do
+ before do
+ allow(Gitlab.config.lfs).to receive(:enabled).and_return(true)
+ project.update_attribute(:lfs_enabled, true)
+
+ visit_blob('files/lfs/lfs_object.iso')
+
+ wait_for_requests
+ end
+
+ it 'displays the blob' do
+ aggregate_failures do
+ # shows a download link
+ expect(page).to have_link('Download (1.5 MB)')
+
+ # does not show a viewer switcher
+ expect(page).not_to have_selector('.js-blob-viewer-switcher')
+
+ # does not show a copy button
+ expect(page).not_to have_selector('.js-copy-blob-source-btn')
+
+ # shows a download button
+ expect(page).to have_link('Download')
+ end
+ end
+ end
+
+ context 'when LFS is disabled on the project' do
+ before do
+ visit_blob('files/lfs/lfs_object.iso')
+
+ wait_for_requests
+ end
+
+ it 'displays the blob' do
+ aggregate_failures do
+ # shows text
+ expect(page).to have_content('size 1575078')
+
+ # does not show a viewer switcher
+ expect(page).not_to have_selector('.js-blob-viewer-switcher')
+
+ # shows an enabled copy button
+ expect(page).to have_selector('.js-copy-blob-source-btn:not(.disabled)')
+
+ # shows a raw button
+ expect(page).to have_link('Open raw')
+ end
+ end
+ end
+ end
+
+ context 'ZIP file' do
+ before do
+ visit_blob('Gemfile.zip')
+
+ wait_for_requests
+ end
+
+ it 'displays the blob' do
+ aggregate_failures do
+ # shows a download link
+ expect(page).to have_link('Download (2.11 KB)')
+
+ # does not show a viewer switcher
+ expect(page).not_to have_selector('.js-blob-viewer-switcher')
+
+ # does not show a copy button
+ expect(page).not_to have_selector('.js-copy-blob-source-btn')
+
+ # shows a download button
+ expect(page).to have_link('Download')
+ end
+ end
+ end
+
+ context 'empty file' do
+ before do
+ project.add_maintainer(project.creator)
+
+ Files::CreateService.new(
+ project,
+ project.creator,
+ start_branch: 'master',
+ branch_name: 'master',
+ commit_message: "Add empty file",
+ file_path: 'files/empty.md',
+ file_content: ''
+ ).execute
+
+ visit_blob('files/empty.md')
+
+ wait_for_requests
+ end
+
+ it 'displays an error' do
+ aggregate_failures do
+ # shows an error message
+ expect(page).to have_content('Empty file')
+
+ # does not show a viewer switcher
+ expect(page).not_to have_selector('.js-blob-viewer-switcher')
+
+ # does not show a copy button
+ expect(page).not_to have_selector('.js-copy-blob-source-btn')
+
+ # does not show a download or raw button
+ expect(page).not_to have_link('Download')
+ expect(page).not_to have_link('Open raw')
+ end
+ end
+ end
+
+ context 'binary file that appears to be text in the first 1024 bytes' do
+ before do
+ visit_blob('encoding/binary-1.bin', ref: 'binary-encoding')
+ end
+
+ it 'displays the blob' do
+ aggregate_failures do
+ # shows a download link
+ expect(page).to have_link('Download (23.8 KB)')
+
+ # does not show a viewer switcher
+ expect(page).not_to have_selector('.js-blob-viewer-switcher')
+
+ # The specs below verify an arguably incorrect result, but since we only
+ # learn that the file is not actually text once the text viewer content
+ # is loaded asynchronously, there is no straightforward way to get these
+ # synchronously loaded elements to display correctly.
+ #
+ # Clicking the copy button will result in nothing being copied.
+ # Clicking the raw button will result in the binary file being downloaded,
+ # as expected.
+
+ # shows an enabled copy button, incorrectly
+ expect(page).to have_selector('.js-copy-blob-source-btn:not(.disabled)')
+
+ # shows a raw button, incorrectly
+ expect(page).to have_link('Open raw')
+ end
+ end
+ end
+
+ context 'files with auxiliary viewers' do
+ describe '.gitlab-ci.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-ci.yml",
+ file_path: '.gitlab-ci.yml',
+ file_content: File.read(Rails.root.join('spec/support/gitlab_stubs/gitlab_ci.yml'))
+ ).execute
+
+ visit_blob('.gitlab-ci.yml')
+ end
+
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ # shows that configuration is valid
+ expect(page).to have_content('This GitLab CI configuration is valid.')
+
+ # shows a learn more link
+ expect(page).to have_link('Learn more')
+ end
+ end
+ end
+
+ describe '.gitlab/route-map.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/route-map.yml",
+ file_path: '.gitlab/route-map.yml',
+ file_content: <<-MAP.strip_heredoc
+ # Team data
+ - source: 'data/team.yml'
+ public: 'team/'
+ MAP
+ ).execute
+
+ visit_blob('.gitlab/route-map.yml')
+ end
+
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ # shows that map is valid
+ expect(page).to have_content('This Route Map is valid.')
+
+ # shows a learn more link
+ expect(page).to have_link('Learn more')
+ end
+ 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
+ end
+
+ context 'with metrics_dashboard_exhaustive_validations feature flag off' do
+ before do
+ stub_feature_flags(metrics_dashboard_exhaustive_validations: false)
+ 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: should be an array of panel_groups objects")
+
+ # shows a learn more link
+ expect(page).to have_link('Learn more')
+ end
+ end
+ end
+ end
+
+ context 'with metrics_dashboard_exhaustive_validations feature flag on' do
+ before do
+ stub_feature_flags(metrics_dashboard_exhaustive_validations: true)
+ 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("root is missing required keys: panel_groups")
+
+ # shows a learn more link
+ expect(page).to have_link('Learn more')
+ end
+ end
+ end
+ end
+ end
+
+ context 'LICENSE' do
+ before do
+ visit_blob('LICENSE')
+ end
+
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ # shows license
+ expect(page).to have_content('This project is licensed under the MIT License.')
+
+ # shows a learn more link
+ expect(page).to have_link('Learn more', href: 'http://choosealicense.com/licenses/mit/')
+ end
+ end
+ end
+
+ context '*.gemspec' do
+ before do
+ project.add_maintainer(project.creator)
+
+ Files::CreateService.new(
+ project,
+ project.creator,
+ start_branch: 'master',
+ branch_name: 'master',
+ commit_message: "Add activerecord.gemspec",
+ file_path: 'activerecord.gemspec',
+ file_content: <<-SPEC.strip_heredoc
+ Gem::Specification.new do |s|
+ s.platform = Gem::Platform::RUBY
+ s.name = "activerecord"
+ end
+ SPEC
+ ).execute
+
+ visit_blob('activerecord.gemspec')
+ end
+
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ # shows names of dependency manager and package
+ expect(page).to have_content('This project manages its dependencies using RubyGems.')
+
+ # shows a learn more link
+ expect(page).to have_link('Learn more', href: 'https://rubygems.org/')
+ end
+ end
+ end
+
+ context 'CONTRIBUTING.md' do
+ before do
+ file_name = 'CONTRIBUTING.md'
+
+ create_file(file_name, '## Contribution guidelines')
+ visit_blob(file_name)
+ end
+
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ expect(page).to have_content("After you've reviewed these contribution guidelines, you'll be all set to contribute to this project.")
+ end
+ end
+ end
+
+ context 'CHANGELOG.md' do
+ before do
+ file_name = 'CHANGELOG.md'
+
+ create_file(file_name, '## Changelog for v1.0.0')
+ visit_blob(file_name)
+ end
+
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ expect(page).to have_content("To find the state of this project's repository at the time of any of these versions, check out the tags.")
+ end
+ end
+ end
+
+ context 'Cargo.toml' do
+ before do
+ file_name = 'Cargo.toml'
+
+ create_file(file_name, '
+ [package]
+ name = "hello_world" # the name of the package
+ version = "0.1.0" # the current version, obeying semver
+ authors = ["Alice <a@example.com>", "Bob <b@example.com>"]
+ ')
+ visit_blob(file_name)
+ end
+
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ expect(page).to have_content("This project manages its dependencies using Cargo.")
+ end
+ end
+ end
+
+ context 'Cartfile' do
+ before do
+ file_name = 'Cartfile'
+
+ create_file(file_name, '
+ gitlab "Alamofire/Alamofire" == 4.9.0
+ gitlab "Alamofire/AlamofireImage" ~> 3.4
+ ')
+ visit_blob(file_name)
+ end
+
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ expect(page).to have_content("This project manages its dependencies using Carthage.")
+ end
+ end
+ end
+
+ context 'composer.json' do
+ before do
+ file_name = 'composer.json'
+
+ create_file(file_name, '
+ {
+ "license": "MIT"
+ }
+ ')
+ visit_blob(file_name)
+ end
+
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ expect(page).to have_content("This project manages its dependencies using Composer.")
+ end
+ end
+ end
+
+ context 'Gemfile' do
+ before do
+ file_name = 'Gemfile'
+
+ create_file(file_name, '
+ source "https://rubygems.org"
+
+ # Gems here
+ ')
+ visit_blob(file_name)
+ end
+
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ expect(page).to have_content("This project manages its dependencies using Bundler.")
+ end
+ end
+ end
+
+ context 'Godeps.json' do
+ before do
+ file_name = 'Godeps.json'
+
+ create_file(file_name, '
+ {
+ "GoVersion": "go1.6"
+ }
+ ')
+ visit_blob(file_name)
+ end
+
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ expect(page).to have_content("This project manages its dependencies using godep.")
+ end
+ end
+ end
+
+ context 'go.mod' do
+ before do
+ file_name = 'go.mod'
+
+ create_file(file_name, '
+ module example.com/mymodule
+
+ go 1.14
+ ')
+ visit_blob(file_name)
+ end
+
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ expect(page).to have_content("This project manages its dependencies using Go Modules.")
+ end
+ end
+ end
+
+ context 'package.json' do
+ before do
+ file_name = 'package.json'
+
+ create_file(file_name, '
+ {
+ "name": "my-awesome-package",
+ "version": "1.0.0"
+ }
+ ')
+ visit_blob(file_name)
+ end
+
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ expect(page).to have_content("This project manages its dependencies using npm.")
+ end
+ end
+ end
+
+ context 'podfile' do
+ before do
+ file_name = 'podfile'
+
+ create_file(file_name, 'platform :ios, "8.0"')
+ visit_blob(file_name)
+ end
+
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ expect(page).to have_content("This project manages its dependencies using CocoaPods.")
+ end
+ end
+ end
+
+ context 'test.podspec' do
+ before do
+ file_name = 'test.podspec'
+
+ create_file(file_name, '
+ Pod::Spec.new do |s|
+ s.name = "TensorFlowLiteC"
+ ')
+ visit_blob(file_name)
+ end
+
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ expect(page).to have_content("This project manages its dependencies using CocoaPods.")
+ end
+ end
+ end
+
+ context 'JSON.podspec.json' do
+ before do
+ file_name = 'JSON.podspec.json'
+
+ create_file(file_name, '
+ {
+ "name": "JSON"
+ }
+ ')
+ visit_blob(file_name)
+ end
+
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ expect(page).to have_content("This project manages its dependencies using CocoaPods.")
+ end
+ end
+ end
+
+ context 'requirements.txt' do
+ before do
+ file_name = 'requirements.txt'
+
+ create_file(file_name, 'Project requirements')
+ visit_blob(file_name)
+ end
+
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ expect(page).to have_content("This project manages its dependencies using pip.")
+ end
+ end
+ end
+
+ context 'yarn.lock' do
+ before do
+ file_name = 'yarn.lock'
+
+ create_file(file_name, '
+ # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
+ # yarn lockfile v1
+ ')
+ visit_blob(file_name)
+ end
+
+ it 'displays an auxiliary viewer' do
+ aggregate_failures do
+ expect(page).to have_content("This project manages its dependencies using Yarn.")
+ end
+ end
+ end
+ end
+
+ context 'realtime pipelines' do
+ before do
+ Files::CreateService.new(
+ project,
+ project.creator,
+ start_branch: 'feature',
+ branch_name: 'feature',
+ commit_message: "Add ruby file",
+ file_path: 'files/ruby/test.rb',
+ file_content: "# Awesome content"
+ ).execute
+
+ create(:ci_pipeline, status: 'running', project: project, ref: 'feature', sha: project.commit('feature').sha)
+ visit_blob('files/ruby/test.rb', ref: 'feature')
+ end
+
+ it 'shows the realtime pipeline status' do
+ page.within('.commit-actions') do
+ expect(page).to have_css('.ci-status-icon')
+ expect(page).to have_css('.ci-status-icon-running')
+ expect(page).to have_css('.js-ci-status-icon-running')
+ end
+ end
+ end
+
+ context 'for subgroups' do
+ let(:group) { create(:group) }
+ let(:subgroup) { create(:group, parent: group) }
+ let(:project) { create(:project, :public, :repository, group: subgroup) }
+
+ it 'renders tree table without errors' do
+ visit_blob('README.md')
+
+ expect(page).to have_selector('.file-content')
+ expect(page).not_to have_selector('[data-testid="alert-danger"]')
+ end
+
+ it 'displays a GPG badge' do
+ visit_blob('CONTRIBUTING.md', ref: '33f3729a45c02fc67d00adb1b8bca394b0e761d9')
+
+ expect(page).not_to have_selector '.gpg-status-box.js-loading-gpg-badge'
+ expect(page).to have_selector '.gpg-status-box.invalid'
+ end
+ end
+
+ context 'on signed merge commit' do
+ it 'displays a GPG badge' do
+ visit_blob('conflicting-file.md', ref: '6101e87e575de14b38b4e1ce180519a813671e10')
+
+ expect(page).not_to have_selector '.gpg-status-box.js-loading-gpg-badge'
+ expect(page).to have_selector '.gpg-status-box.invalid'
+ end
+ end
+
+ context 'when static objects external storage is enabled' do
+ before do
+ stub_application_setting(static_objects_external_storage_url: 'https://cdn.gitlab.com')
+ end
+
+ context 'private project' do
+ let_it_be(:project) { create(:project, :repository, :private) }
+ let_it_be(:user) { create(:user) }
+
+ before do
+ project.add_developer(user)
+
+ sign_in(user)
+ visit_blob('README.md')
+ end
+
+ it 'shows open raw and download buttons with external storage URL prepended and user token appended to their href' do
+ path = project_raw_path(project, 'master/README.md')
+ raw_uri = "https://cdn.gitlab.com#{path}?token=#{user.static_object_token}"
+ download_uri = "https://cdn.gitlab.com#{path}?inline=false&token=#{user.static_object_token}"
+
+ aggregate_failures do
+ expect(page).to have_link 'Open raw', href: raw_uri
+ expect(page).to have_link 'Download', href: download_uri
+ end
+ end
+ end
+
+ context 'public project' do
+ before do
+ visit_blob('README.md')
+ end
+
+ it 'shows open raw and download buttons with external storage URL prepended to their href' do
+ path = project_raw_path(project, 'master/README.md')
+ raw_uri = "https://cdn.gitlab.com#{path}"
+ download_uri = "https://cdn.gitlab.com#{path}?inline=false"
+
+ aggregate_failures do
+ expect(page).to have_link 'Open raw', href: raw_uri
+ expect(page).to have_link 'Download', href: download_uri
+ end
+ end
+ end
+ end
+end
diff --git a/spec/features/refactor_blob_viewer_disabled/projects/blobs/edit_spec.rb b/spec/features/refactor_blob_viewer_disabled/projects/blobs/edit_spec.rb
new file mode 100644
index 00000000000..f5b9947b29e
--- /dev/null
+++ b/spec/features/refactor_blob_viewer_disabled/projects/blobs/edit_spec.rb
@@ -0,0 +1,213 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Editing file blob', :js do
+ include TreeHelper
+ include BlobSpecHelpers
+
+ let(:project) { create(:project, :public, :repository) }
+ let(:merge_request) { create(:merge_request, source_project: project, source_branch: 'feature', target_branch: 'master') }
+ let(:branch) { 'master' }
+ let(:file_path) { project.repository.ls_files(project.repository.root_ref)[1] }
+ let(:readme_file_path) { 'README.md' }
+
+ before do
+ stub_feature_flags(refactor_blob_viewer: false)
+ end
+
+ context 'as a developer' do
+ let(:user) { create(:user) }
+ let(:role) { :developer }
+
+ before do
+ project.add_role(user, role)
+ sign_in(user)
+ end
+
+ def edit_and_commit(commit_changes: true, is_diff: false)
+ set_default_button('edit')
+ refresh
+ wait_for_requests
+
+ if is_diff
+ first('.js-diff-more-actions').click
+ click_link('Edit in single-file editor')
+ else
+ click_link('Edit')
+ end
+
+ fill_editor(content: 'class NextFeature\\nend\\n')
+
+ if commit_changes
+ click_button 'Commit changes'
+ end
+ end
+
+ def fill_editor(content: 'class NextFeature\\nend\\n')
+ wait_for_requests
+ execute_script("monaco.editor.getModels()[0].setValue('#{content}')")
+ end
+
+ context 'from MR diff' do
+ before do
+ visit diffs_project_merge_request_path(project, merge_request)
+ edit_and_commit(is_diff: true)
+ end
+
+ it 'returns me to the mr' do
+ expect(page).to have_content(merge_request.title)
+ end
+ end
+
+ it 'updates the content of file with a number as file path' do
+ project.repository.create_file(user, '1', 'test', message: 'testing', branch_name: branch)
+ visit project_blob_path(project, tree_join(branch, '1'))
+
+ edit_and_commit
+
+ expect(page).to have_content 'NextFeature'
+ end
+
+ it 'editing a template file in a sub directory does not change path' do
+ project.repository.create_file(user, 'ci/.gitlab-ci.yml', 'test', message: 'testing', branch_name: branch)
+ visit project_edit_blob_path(project, tree_join(branch, 'ci/.gitlab-ci.yml'))
+
+ expect(find_by_id('file_path').value).to eq('ci/.gitlab-ci.yml')
+ end
+
+ it 'updating file path updates syntax highlighting' do
+ visit project_edit_blob_path(project, tree_join(branch, readme_file_path))
+ expect(find('#editor')['data-mode-id']).to eq('markdown')
+
+ find('#file_path').send_keys('foo.txt') do
+ expect(find('#editor')['data-mode-id']).to eq('plaintext')
+ end
+ end
+
+ context 'from blob file path' do
+ before do
+ visit project_blob_path(project, tree_join(branch, file_path))
+ end
+
+ it 'updates content' do
+ edit_and_commit
+
+ expect(page).to have_content 'successfully committed'
+ expect(page).to have_content 'NextFeature'
+ end
+
+ it 'previews content' do
+ edit_and_commit(commit_changes: false)
+ click_link 'Preview changes'
+ wait_for_requests
+
+ old_line_count = page.all('.line_holder.old').size
+ new_line_count = page.all('.line_holder.new').size
+
+ expect(old_line_count).to be > 0
+ expect(new_line_count).to be > 0
+ end
+ end
+
+ context 'when rendering the preview' do
+ it 'renders content with CommonMark' do
+ visit project_edit_blob_path(project, tree_join(branch, readme_file_path))
+ fill_editor(content: '1. one\\n - sublist\\n')
+ click_link 'Preview'
+ wait_for_requests
+
+ # the above generates two separate lists (not embedded) in CommonMark
+ expect(page).to have_content('sublist')
+ expect(page).not_to have_xpath('//ol//li//ul')
+ end
+ end
+ end
+
+ context 'visit blob edit' do
+ context 'redirects to sign in and returns' do
+ context 'as developer' do
+ let(:user) { create(:user) }
+
+ before do
+ project.add_developer(user)
+ visit project_edit_blob_path(project, tree_join(branch, file_path))
+ end
+
+ it 'redirects to sign in and returns' do
+ expect(page).to have_current_path(new_user_session_path)
+
+ gitlab_sign_in(user)
+
+ expect(page).to have_current_path(project_edit_blob_path(project, tree_join(branch, file_path)))
+ end
+ end
+
+ context 'as guest' do
+ let(:user) { create(:user) }
+
+ before do
+ visit project_edit_blob_path(project, tree_join(branch, file_path))
+ end
+
+ it 'redirects to sign in and returns' do
+ expect(page).to have_current_path(new_user_session_path)
+
+ gitlab_sign_in(user)
+
+ expect(page).to have_current_path(project_blob_path(project, tree_join(branch, file_path)))
+ end
+ end
+ end
+
+ context 'as developer' do
+ let(:user) { create(:user) }
+ let(:protected_branch) { 'protected-branch' }
+
+ before do
+ project.add_developer(user)
+ project.repository.add_branch(user, protected_branch, 'master')
+ create(:protected_branch, project: project, name: protected_branch)
+ sign_in(user)
+ end
+
+ context 'on some branch' do
+ before do
+ visit project_edit_blob_path(project, tree_join(branch, file_path))
+ end
+
+ it 'shows blob editor with same branch' do
+ expect(page).to have_current_path(project_edit_blob_path(project, tree_join(branch, file_path)))
+ expect(find('.js-branch-name').value).to eq(branch)
+ end
+ end
+
+ context 'with protected branch' do
+ it 'shows blob editor with patch branch' do
+ freeze_time do
+ visit project_edit_blob_path(project, tree_join(protected_branch, file_path))
+
+ epoch = Time.zone.now.strftime('%s%L').last(5)
+
+ expect(find('.js-branch-name').value).to eq "#{user.username}-protected-branch-patch-#{epoch}"
+ end
+ end
+ end
+ end
+
+ context 'as maintainer' do
+ let(:user) { create(:user) }
+
+ before do
+ project.add_maintainer(user)
+ sign_in(user)
+ visit project_edit_blob_path(project, tree_join(branch, file_path))
+ end
+
+ it 'shows blob editor with same branch' do
+ expect(page).to have_current_path(project_edit_blob_path(project, tree_join(branch, file_path)))
+ expect(find('.js-branch-name').value).to eq(branch)
+ end
+ end
+ end
+end
diff --git a/spec/features/refactor_blob_viewer_disabled/projects/blobs/shortcuts_blob_spec.rb b/spec/features/refactor_blob_viewer_disabled/projects/blobs/shortcuts_blob_spec.rb
new file mode 100644
index 00000000000..fe0b217992e
--- /dev/null
+++ b/spec/features/refactor_blob_viewer_disabled/projects/blobs/shortcuts_blob_spec.rb
@@ -0,0 +1,45 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+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] }
+ let(:sha) { project.repository.commit.sha }
+
+ before do
+ stub_feature_flags(refactor_blob_viewer: false)
+ end
+
+ describe 'On a file(blob)', :js do
+ def get_absolute_url(path = "")
+ "http://#{page.server.host}:#{page.server.port}#{path}"
+ end
+
+ def visit_blob(fragment = nil)
+ visit project_blob_path(project, tree_join('master', path), anchor: fragment)
+ end
+
+ describe 'pressing "y"' do
+ it 'redirects to permalink with commit sha' do
+ visit_blob
+ wait_for_requests
+
+ find('body').native.send_key('y')
+
+ expect(page).to have_current_path(get_absolute_url(project_blob_path(project, tree_join(sha, path))), url: true)
+ end
+
+ it 'maintains fragment hash when redirecting' do
+ fragment = "L1"
+ visit_blob(fragment)
+ wait_for_requests
+
+ find('body').native.send_key('y')
+
+ expect(page).to have_current_path(get_absolute_url(project_blob_path(project, tree_join(sha, path), anchor: fragment)), url: true)
+ end
+ end
+ end
+end
diff --git a/spec/features/refactor_blob_viewer_disabled/projects/blobs/user_creates_new_blob_in_new_project_spec.rb b/spec/features/refactor_blob_viewer_disabled/projects/blobs/user_creates_new_blob_in_new_project_spec.rb
new file mode 100644
index 00000000000..fe38659f60b
--- /dev/null
+++ b/spec/features/refactor_blob_viewer_disabled/projects/blobs/user_creates_new_blob_in_new_project_spec.rb
@@ -0,0 +1,63 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'User creates new blob', :js do
+ include WebIdeSpecHelpers
+
+ let(:user) { create(:user) }
+ let(:project) { create(:project, :empty_repo) }
+
+ before do
+ stub_feature_flags(refactor_blob_viewer: false)
+ end
+
+ shared_examples 'creating a file' do
+ it 'allows the user to add a new file in Web IDE' do
+ visit project_path(project)
+
+ click_link 'New file'
+
+ wait_for_requests
+
+ ide_create_new_file('dummy-file', content: "Hello world\n")
+
+ ide_commit
+
+ expect(page).to have_content('All changes are committed')
+ expect(project.repository.blob_at('master', 'dummy-file').data).to eql("Hello world\n")
+ end
+ end
+
+ describe 'as a maintainer' do
+ before do
+ project.add_maintainer(user)
+ sign_in(user)
+ end
+
+ it_behaves_like 'creating a file'
+ end
+
+ describe 'as an admin' do
+ let(:user) { create(:user, :admin) }
+
+ before do
+ sign_in(user)
+ gitlab_enable_admin_mode_sign_in(user)
+ end
+
+ it_behaves_like 'creating a file'
+ end
+
+ describe 'as a developer' do
+ before do
+ project.add_developer(user)
+ sign_in(user)
+ visit project_path(project)
+ end
+
+ it 'does not allow pushing to the default branch' do
+ expect(page).not_to have_content('New file')
+ end
+ end
+end
diff --git a/spec/features/refactor_blob_viewer_disabled/projects/blobs/user_follows_pipeline_suggest_nudge_spec.rb b/spec/features/refactor_blob_viewer_disabled/projects/blobs/user_follows_pipeline_suggest_nudge_spec.rb
new file mode 100644
index 00000000000..4290df08e66
--- /dev/null
+++ b/spec/features/refactor_blob_viewer_disabled/projects/blobs/user_follows_pipeline_suggest_nudge_spec.rb
@@ -0,0 +1,80 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'User follows pipeline suggest nudge spec when feature is enabled', :js do
+ include CookieHelper
+
+ let(:project) { create(:project, :empty_repo) }
+ let(:user) { project.first_owner }
+
+ before do
+ stub_feature_flags(refactor_blob_viewer: false)
+ end
+
+ describe 'viewing the new blob page' do
+ before do
+ sign_in(user)
+ end
+
+ context 'when the page is loaded from the link using the suggest_gitlab_ci_yml param' do
+ before do
+ visit namespace_project_new_blob_path(namespace_id: project.namespace, project_id: project, id: 'master', suggest_gitlab_ci_yml: 'true')
+ end
+
+ it 'pre-fills .gitlab-ci.yml for file name' do
+ file_name = page.find_by_id('file_name')
+
+ expect(file_name.value).to have_content('.gitlab-ci.yml')
+ end
+
+ it 'chooses the .gitlab-ci.yml Template Type' do
+ template_type = page.find(:css, '.template-type-selector .dropdown-toggle-text')
+
+ expect(template_type.text).to have_content('.gitlab-ci.yml')
+ end
+
+ it 'displays suggest_gitlab_ci_yml popover' do
+ page.find(:css, '.gitlab-ci-yml-selector').click
+
+ popover_selector = '.suggest-gitlab-ci-yml'
+
+ expect(page).to have_css(popover_selector, visible: true)
+
+ page.within(popover_selector) do
+ expect(page).to have_content('1/2: Choose a template')
+ end
+ end
+
+ it 'sets the commit cookie when the Commit button is clicked' do
+ click_button 'Commit changes'
+
+ expect(get_cookie("suggest_gitlab_ci_yml_commit_#{project.id}")).to be_present
+ end
+ end
+
+ context 'when the page is visited without the param' do
+ before do
+ visit namespace_project_new_blob_path(namespace_id: project.namespace, project_id: project, id: 'master')
+ end
+
+ it 'does not pre-fill .gitlab-ci.yml for file name' do
+ file_name = page.find_by_id('file_name')
+
+ expect(file_name.value).not_to have_content('.gitlab-ci.yml')
+ end
+
+ it 'does not choose the .gitlab-ci.yml Template Type' do
+ template_type = page.find(:css, '.template-type-selector .dropdown-toggle-text')
+
+ expect(template_type.text).to have_content('Select a template type')
+ end
+
+ it 'does not display suggest_gitlab_ci_yml popover' do
+ popover_selector = '.b-popover.suggest-gitlab-ci-yml'
+
+ expect(page).not_to have_css(popover_selector, visible: true)
+ end
+ end
+ end
+end
diff --git a/spec/features/refactor_blob_viewer_disabled/projects/blobs/user_views_pipeline_editor_button_spec.rb b/spec/features/refactor_blob_viewer_disabled/projects/blobs/user_views_pipeline_editor_button_spec.rb
new file mode 100644
index 00000000000..a00e1eaa551
--- /dev/null
+++ b/spec/features/refactor_blob_viewer_disabled/projects/blobs/user_views_pipeline_editor_button_spec.rb
@@ -0,0 +1,46 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'User views pipeline editor button on root ci config file', :js do
+ include BlobSpecHelpers
+
+ let_it_be(:user) { create(:user) }
+ let_it_be(:project) { create(:project, :public, :repository) }
+
+ before do
+ stub_feature_flags(refactor_blob_viewer: false)
+ end
+
+ context "when the ci config is the root file" do
+ before do
+ project.add_developer(user)
+ sign_in(user)
+ end
+
+ it 'shows the button to the Pipeline Editor' do
+ project.update!(ci_config_path: '.my-config.yml')
+ project.repository.create_file(user, project.ci_config_path_or_default, 'test', message: 'testing', branch_name: 'master')
+ visit project_blob_path(project, File.join('master', '.my-config.yml'))
+
+ expect(page).to have_content('Edit in pipeline editor')
+ end
+
+ it 'does not shows the Pipeline Editor button' do
+ project.repository.create_file(user, '.my-sub-config.yml', 'test', message: 'testing', branch_name: 'master')
+ visit project_blob_path(project, File.join('master', '.my-sub-config.yml'))
+
+ expect(page).not_to have_content('Edit in pipeline editor')
+ end
+ end
+
+ context "when user cannot collaborate" do
+ before do
+ sign_in(user)
+ end
+ it 'does not shows the Pipeline Editor button' do
+ visit project_blob_path(project, File.join('master', '.my-config.yml'))
+ expect(page).not_to have_content('Edit in pipeline editor')
+ end
+ end
+end
diff --git a/spec/features/refactor_blob_viewer_disabled/projects/files/editing_a_file_spec.rb b/spec/features/refactor_blob_viewer_disabled/projects/files/editing_a_file_spec.rb
new file mode 100644
index 00000000000..c32fb1aa4d3
--- /dev/null
+++ b/spec/features/refactor_blob_viewer_disabled/projects/files/editing_a_file_spec.rb
@@ -0,0 +1,34 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Projects > Files > User wants to edit a file' do
+ let(:project) { create(:project, :repository) }
+ let(:user) { project.first_owner }
+ let(:commit_params) do
+ {
+ start_branch: project.default_branch,
+ branch_name: project.default_branch,
+ commit_message: "Committing First Update",
+ file_path: ".gitignore",
+ file_content: "First Update",
+ last_commit_sha: Gitlab::Git::Commit.last_for_path(project.repository, project.default_branch,
+ ".gitignore").sha
+ }
+ end
+
+ before do
+ stub_feature_flags(refactor_blob_viewer: false)
+ sign_in user
+ visit project_edit_blob_path(project,
+ File.join(project.default_branch, '.gitignore'))
+ end
+
+ it 'file has been updated since the user opened the edit page' do
+ Files::UpdateService.new(project, user, commit_params).execute
+
+ click_button 'Commit changes'
+
+ expect(page).to have_content 'Someone edited the file the same time you did.'
+ end
+end
diff --git a/spec/features/refactor_blob_viewer_disabled/projects/files/find_file_keyboard_spec.rb b/spec/features/refactor_blob_viewer_disabled/projects/files/find_file_keyboard_spec.rb
new file mode 100644
index 00000000000..9ba5f5a9b57
--- /dev/null
+++ b/spec/features/refactor_blob_viewer_disabled/projects/files/find_file_keyboard_spec.rb
@@ -0,0 +1,42 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Projects > Files > Find file keyboard shortcuts', :js do
+ let(:project) { create(:project, :repository) }
+ let(:user) { project.first_owner }
+
+ before do
+ stub_feature_flags(refactor_blob_viewer: false)
+ sign_in user
+
+ visit project_find_file_path(project, project.repository.root_ref)
+
+ wait_for_requests
+ end
+
+ it 'opens file when pressing enter key' do
+ fill_in 'file_find', with: 'CHANGELOG'
+
+ find('#file_find').native.send_keys(:enter)
+
+ expect(page).to have_selector('.blob-content-holder')
+
+ page.within('.js-file-title') do
+ expect(page).to have_content('CHANGELOG')
+ end
+ end
+
+ it 'navigates files with arrow keys' do
+ fill_in 'file_find', with: 'application.'
+
+ find('#file_find').native.send_keys(:down)
+ find('#file_find').native.send_keys(:enter)
+
+ expect(page).to have_selector('.blob-content-holder')
+
+ page.within('.js-file-title') do
+ expect(page).to have_content('application.js')
+ end
+ end
+end
diff --git a/spec/features/refactor_blob_viewer_disabled/projects/files/project_owner_creates_license_file_spec.rb b/spec/features/refactor_blob_viewer_disabled/projects/files/project_owner_creates_license_file_spec.rb
new file mode 100644
index 00000000000..ab920504100
--- /dev/null
+++ b/spec/features/refactor_blob_viewer_disabled/projects/files/project_owner_creates_license_file_spec.rb
@@ -0,0 +1,72 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Projects > Files > Project owner creates a license file', :js do
+ let(:project) { create(:project, :repository) }
+ let(:project_maintainer) { project.first_owner }
+
+ before do
+ stub_feature_flags(refactor_blob_viewer: false)
+ project.repository.delete_file(project_maintainer, 'LICENSE',
+ message: 'Remove LICENSE', branch_name: 'master')
+ sign_in(project_maintainer)
+ visit project_path(project)
+ end
+
+ it 'project maintainer creates a license file manually from a template' do
+ visit project_tree_path(project, project.repository.root_ref)
+ find('.add-to-tree').click
+ click_link 'New file'
+
+ fill_in :file_name, with: 'LICENSE'
+
+ expect(page).to have_selector('.license-selector')
+
+ select_template('MIT License')
+
+ file_content = first('.file-editor')
+ expect(file_content).to have_content('MIT License')
+ expect(file_content).to have_content("Copyright (c) #{Time.zone.now.year} #{project.namespace.human_name}")
+
+ fill_in :commit_message, with: 'Add a LICENSE file', visible: true
+ click_button 'Commit changes'
+
+ expect(page).to have_current_path(
+ project_blob_path(project, 'master/LICENSE'), ignore_query: true)
+ expect(page).to have_content('MIT License')
+ expect(page).to have_content("Copyright (c) #{Time.zone.now.year} #{project.namespace.human_name}")
+ end
+
+ it 'project maintainer creates a license file from the "Add license" link' do
+ click_link 'Add LICENSE'
+
+ expect(page).to have_content('New file')
+ expect(page).to have_current_path(
+ project_new_blob_path(project, 'master'), ignore_query: true)
+ expect(find('#file_name').value).to eq('LICENSE')
+ expect(page).to have_selector('.license-selector')
+
+ select_template('MIT License')
+
+ file_content = first('.file-editor')
+ expect(file_content).to have_content('MIT License')
+ expect(file_content).to have_content("Copyright (c) #{Time.zone.now.year} #{project.namespace.human_name}")
+
+ fill_in :commit_message, with: 'Add a LICENSE file', visible: true
+ click_button 'Commit changes'
+
+ expect(page).to have_current_path(
+ project_blob_path(project, 'master/LICENSE'), ignore_query: true)
+ expect(page).to have_content('MIT License')
+ expect(page).to have_content("Copyright (c) #{Time.zone.now.year} #{project.namespace.human_name}")
+ end
+
+ def select_template(template)
+ page.within('.js-license-selector-wrap') do
+ click_button 'Apply a template'
+ click_link template
+ wait_for_requests
+ end
+ end
+end
diff --git a/spec/features/refactor_blob_viewer_disabled/projects/files/user_browses_files_spec.rb b/spec/features/refactor_blob_viewer_disabled/projects/files/user_browses_files_spec.rb
new file mode 100644
index 00000000000..5abdad905fd
--- /dev/null
+++ b/spec/features/refactor_blob_viewer_disabled/projects/files/user_browses_files_spec.rb
@@ -0,0 +1,377 @@
+# frozen_string_literal: true
+
+require "spec_helper"
+
+RSpec.describe "User browses files", :js do
+ include RepoHelpers
+
+ 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."
+ end
+
+ let(:project) { create(:project, :repository, name: "Shop") }
+ let(:project2) { create(:project, :repository, name: "Another Project", path: "another-project") }
+ let(:tree_path_root_ref) { project_tree_path(project, project.repository.root_ref) }
+ let(:user) { project.first_owner }
+
+ before do
+ stub_feature_flags(refactor_blob_viewer: false)
+ sign_in(user)
+ end
+
+ it "shows last commit for current directory", :js do
+ visit(tree_path_root_ref)
+
+ click_link("files")
+
+ last_commit = project.repository.last_commit_for_path(project.default_branch, "files")
+
+ page.within(".commit-detail") do
+ expect(page).to have_content(last_commit.short_id).and have_content(last_commit.author_name)
+ end
+ end
+
+ context "when browsing the master branch", :js do
+ before do
+ visit(tree_path_root_ref)
+ end
+
+ it "shows files from a repository" do
+ expect(page).to have_content("VERSION")
+ .and have_content(".gitignore")
+ .and have_content("LICENSE")
+ end
+
+ it "shows the `Browse Directory` link" do
+ click_link("files")
+
+ page.within('.repo-breadcrumb') do
+ expect(page).to have_link('files')
+ end
+
+ click_link("History")
+
+ expect(page).to have_link("Browse Directory").and have_no_link("Browse Code")
+ end
+
+ it "shows the `Browse File` link" do
+ page.within(".tree-table") do
+ click_link("README.md")
+ end
+
+ click_link("History")
+
+ expect(page).to have_link("Browse File").and have_no_link("Browse Files")
+ end
+
+ it "shows the `Browse Files` link" do
+ click_link("History")
+
+ expect(page).to have_link("Browse Files").and have_no_link("Browse Directory")
+ end
+
+ it "redirects to the permalink URL" do
+ click_link(".gitignore")
+ click_link("Permalink")
+
+ permalink_path = project_blob_path(project, "#{project.repository.commit.sha}/.gitignore")
+
+ expect(page).to have_current_path(permalink_path, ignore_query: true)
+ end
+ end
+
+ context "when browsing the `markdown` branch", :js do
+ context "when browsing the root" do
+ before do
+ visit(project_tree_path(project, "markdown"))
+ end
+
+ it "shows correct files and links" do
+ expect(page).to have_current_path(project_tree_path(project, "markdown"), ignore_query: true)
+ expect(page).to have_content("README.md")
+ .and have_content("CHANGELOG")
+ .and have_content("Welcome to GitLab GitLab is a free project and repository management application")
+ .and have_link("GitLab API doc")
+ .and have_link("GitLab API website")
+ .and have_link("Rake tasks")
+ .and have_link("backup and restore procedure")
+ .and have_link("GitLab API doc directory")
+ .and have_link("Maintenance")
+ .and have_header_with_correct_id_and_link(2, "Application details", "application-details")
+ .and have_link("empty", href: "")
+ .and have_link("#id", href: "#id")
+ .and have_link("/#id", href: project_blob_path(project, "markdown/README.md", anchor: "id"))
+ .and have_link("README.md#id", href: project_blob_path(project, "markdown/README.md", anchor: "id"))
+ .and have_link("d/README.md#id", href: project_blob_path(project, "markdown/db/README.md", anchor: "id"))
+ end
+
+ it "shows correct content of file" do
+ click_link("GitLab API doc")
+
+ expect(page).to have_current_path(project_blob_path(project, "markdown/doc/api/README.md"), ignore_query: true)
+ expect(page).to have_content("All API requests require authentication")
+ .and have_content("Contents")
+ .and have_link("Users")
+ .and have_link("Rake tasks")
+ .and have_header_with_correct_id_and_link(1, "GitLab API", "gitlab-api")
+
+ click_link("Users")
+
+ expect(page).to have_current_path(project_blob_path(project, "markdown/doc/api/users.md"), ignore_query: true)
+ expect(page).to have_content("Get a list of users.")
+
+ page.go_back
+
+ click_link("Rake tasks")
+
+ expect(page).to have_current_path(project_tree_path(project, "markdown/doc/raketasks"), ignore_query: true)
+ expect(page).to have_content("backup_restore.md").and have_content("maintenance.md")
+
+ click_link("maintenance.md")
+
+ expect(page).to have_current_path(project_blob_path(project, "markdown/doc/raketasks/maintenance.md"), ignore_query: true)
+ expect(page).to have_content("bundle exec rake gitlab:env:info RAILS_ENV=production")
+
+ click_link("shop")
+
+ page.within(".tree-table") do
+ click_link("README.md")
+ end
+
+ page.go_back
+
+ page.within(".tree-table") do
+ click_link("d")
+ end
+
+ expect(page).to have_link("..", href: project_tree_path(project, "markdown/"))
+
+ page.within(".tree-table") do
+ click_link("README.md")
+ end
+
+ expect(page).to have_link("empty", href: "")
+ end
+
+ it "shows correct content of directory" do
+ click_link("GitLab API doc directory")
+
+ expect(page).to have_current_path(project_tree_path(project, "markdown/doc/api"), ignore_query: true)
+ expect(page).to have_content("README.md").and have_content("users.md")
+
+ click_link("Users")
+
+ expect(page).to have_current_path(project_blob_path(project, "markdown/doc/api/users.md"), ignore_query: true)
+ expect(page).to have_content("List users").and have_content("Get a list of users.")
+ end
+ end
+ end
+
+ context 'when commit message has markdown', :js do
+ before do
+ project.repository.create_file(user, 'index', 'test', message: ':star: testing', branch_name: 'master')
+
+ visit(project_tree_path(project, "master"))
+ end
+
+ it 'renders emojis' do
+ expect(page).to have_selector('gl-emoji', count: 2)
+ end
+ end
+
+ context "when browsing a `improve/awesome` branch", :js do
+ before do
+ visit(project_tree_path(project, "improve/awesome"))
+ end
+
+ it "shows files from a repository" do
+ expect(page).to have_content("VERSION")
+ .and have_content(".gitignore")
+ .and have_content("LICENSE")
+
+ click_link("files")
+
+ page.within('.repo-breadcrumb') do
+ expect(page).to have_link('files')
+ end
+
+ click_link("html")
+
+ page.within('.repo-breadcrumb') do
+ expect(page).to have_link('html')
+ end
+
+ expect(page).to have_link('500.html')
+ end
+ end
+
+ context "when browsing a `Ääh-test-utf-8` branch", :js do
+ before do
+ project.repository.create_branch('Ääh-test-utf-8', project.repository.root_ref)
+ visit(project_tree_path(project, "Ääh-test-utf-8"))
+ end
+
+ it "shows files from a repository" do
+ expect(page).to have_content("VERSION")
+ .and have_content(".gitignore")
+ .and have_content("LICENSE")
+
+ click_link("files")
+
+ page.within('.repo-breadcrumb') do
+ expect(page).to have_link('files')
+ end
+
+ click_link("html")
+
+ page.within('.repo-breadcrumb') do
+ expect(page).to have_link('html')
+ end
+
+ expect(page).to have_link('500.html')
+ end
+ end
+
+ context "when browsing a `test-#` branch", :js do
+ before do
+ project.repository.create_branch('test-#', project.repository.root_ref)
+ visit(project_tree_path(project, "test-#"))
+ end
+
+ it "shows files from a repository" do
+ expect(page).to have_content("VERSION")
+ .and have_content(".gitignore")
+ .and have_content("LICENSE")
+
+ click_link("files")
+
+ page.within('.repo-breadcrumb') do
+ expect(page).to have_link('files')
+ end
+
+ click_link("html")
+
+ page.within('.repo-breadcrumb') do
+ expect(page).to have_link('html')
+ end
+
+ expect(page).to have_link('500.html')
+ end
+ end
+
+ context "when browsing a specific ref", :js do
+ let(:ref) { project_tree_path(project, "6d39438") }
+
+ before do
+ visit(ref)
+ end
+
+ it "shows files from a repository for `6d39438`" do
+ expect(page).to have_current_path(ref, ignore_query: true)
+ expect(page).to have_content(".gitignore").and have_content("LICENSE")
+ end
+
+ it "shows files from a repository with apostroph in its name" do
+ first(".js-project-refs-dropdown").click
+
+ page.within(".project-refs-form") do
+ click_link("'test'")
+ end
+
+ expect(page).to have_selector(".dropdown-toggle-text", text: "'test'")
+
+ visit(project_tree_path(project, "'test'"))
+
+ expect(page).not_to have_selector(".tree-commit .animation-container")
+ end
+
+ it "shows the code with a leading dot in the directory" do
+ first(".js-project-refs-dropdown").click
+
+ page.within(".project-refs-form") do
+ click_link("fix")
+ end
+
+ visit(project_tree_path(project, "fix/.testdir"))
+
+ expect(page).not_to have_selector(".tree-commit .animation-container")
+ end
+
+ it "does not show the permalink link" do
+ click_link(".gitignore")
+
+ expect(page).not_to have_link("permalink")
+ end
+ end
+
+ context "when browsing a file content", :js do
+ before do
+ visit(tree_path_root_ref)
+ wait_for_requests
+
+ click_link(".gitignore")
+ end
+
+ it "shows a file content" do
+ expect(page).to have_content("*.rbc")
+ end
+
+ it "is possible to blame" do
+ click_link("Blame")
+
+ expect(page).to have_content("*.rb")
+ .and have_content("Dmitriy Zaporozhets")
+ .and have_content("Initial commit")
+ .and have_content("Ignore DS files")
+
+ previous_commit_anchor = "//a[@title='Ignore DS files']/parent::span/following-sibling::span/a"
+ find(:xpath, previous_commit_anchor).click
+
+ expect(page).to have_content("*.rb")
+ .and have_content("Dmitriy Zaporozhets")
+ .and have_content("Initial commit")
+
+ expect(page).not_to have_content("Ignore DS files")
+ end
+ end
+
+ context "when browsing a file with pathspec characters" do
+ let(:filename) { ':wq' }
+ let(:newrev) { project.repository.commit('master').sha }
+
+ before do
+ create_file_in_repo(project, 'master', 'master', filename, 'Test file')
+ path = File.join('master', filename)
+
+ visit(project_blob_path(project, path))
+ wait_for_requests
+ end
+
+ it "shows raw file content in a new tab" do
+ new_tab = window_opened_by {click_link 'Open raw'}
+
+ within_window new_tab do
+ expect(page).to have_content("Test file")
+ end
+ end
+ end
+
+ context "when browsing a raw file" do
+ before do
+ visit(tree_path_root_ref)
+ wait_for_requests
+
+ click_link(".gitignore")
+ wait_for_requests
+ end
+
+ it "shows raw file content in a new tab" do
+ new_tab = window_opened_by {click_link 'Open raw'}
+
+ within_window new_tab do
+ expect(page).to have_content("*.rbc")
+ end
+ end
+ end
+end
diff --git a/spec/features/refactor_blob_viewer_disabled/projects/files/user_browses_lfs_files_spec.rb b/spec/features/refactor_blob_viewer_disabled/projects/files/user_browses_lfs_files_spec.rb
new file mode 100644
index 00000000000..2d9b6b3a903
--- /dev/null
+++ b/spec/features/refactor_blob_viewer_disabled/projects/files/user_browses_lfs_files_spec.rb
@@ -0,0 +1,86 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Projects > Files > User browses LFS files' do
+ let(:project) { create(:project, :repository) }
+ let(:user) { project.first_owner }
+
+ before do
+ stub_feature_flags(refactor_blob_viewer: false)
+ sign_in(user)
+ end
+
+ context 'when LFS is disabled', :js do
+ before do
+ allow_next_found_instance_of(Project) do |project|
+ allow(project).to receive(:lfs_enabled?).and_return(false)
+ end
+
+ visit project_tree_path(project, 'lfs')
+ wait_for_requests
+ end
+
+ it 'is possible to see raw content of LFS pointer' do
+ click_link 'files'
+
+ page.within('.repo-breadcrumb') do
+ expect(page).to have_link('files')
+ end
+
+ click_link 'lfs'
+
+ page.within('.repo-breadcrumb') do
+ expect(page).to have_link('lfs')
+ end
+
+ click_link 'lfs_object.iso'
+
+ expect(page).to have_content 'version https://git-lfs.github.com/spec/v1'
+ expect(page).to have_content 'oid sha256:91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897'
+ expect(page).to have_content 'size 1575078'
+ expect(page).not_to have_content 'Download (1.5 MB)'
+ end
+ end
+
+ context 'when LFS is enabled', :js do
+ before do
+ allow_next_found_instance_of(Project) do |project|
+ allow(project).to receive(:lfs_enabled?).and_return(true)
+ end
+
+ visit project_tree_path(project, 'lfs')
+ wait_for_requests
+ end
+
+ it 'shows an LFS object' do
+ click_link('files')
+
+ page.within('.repo-breadcrumb') do
+ expect(page).to have_link('files')
+ end
+
+ click_link('lfs')
+ click_link('lfs_object.iso')
+
+ expect(page).to have_content('Download (1.5 MB)')
+ expect(page).not_to have_content('version https://git-lfs.github.com/spec/v1')
+ expect(page).not_to have_content('oid sha256:91eff75a492a3ed0dfcb544d7f31326bc4014c8551849c192fd1e48d4dd2c897')
+ expect(page).not_to have_content('size 1575078')
+
+ page.within('.content') do
+ expect(page).to have_content('Delete')
+ expect(page).to have_content('History')
+ expect(page).to have_content('Permalink')
+ expect(page).to have_content('Replace')
+ expect(page).to have_link('Download')
+
+ expect(page).not_to have_content('Annotate')
+ expect(page).not_to have_content('Blame')
+
+ expect(page).not_to have_selector(:link_or_button, text: /^Edit$/)
+ expect(page).to have_selector(:link_or_button, 'Open in Web IDE')
+ end
+ end
+ end
+end
diff --git a/spec/features/refactor_blob_viewer_disabled/projects/files/user_deletes_files_spec.rb b/spec/features/refactor_blob_viewer_disabled/projects/files/user_deletes_files_spec.rb
new file mode 100644
index 00000000000..d503c9b1192
--- /dev/null
+++ b/spec/features/refactor_blob_viewer_disabled/projects/files/user_deletes_files_spec.rb
@@ -0,0 +1,74 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+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."
+ end
+
+ let(:project) { create(:project, :repository, name: 'Shop') }
+ let(:project2) { create(:project, :repository, name: 'Another Project', path: 'another-project') }
+ let(:project_tree_path_root_ref) { project_tree_path(project, project.repository.root_ref) }
+ let(:project2_tree_path_root_ref) { project_tree_path(project2, project2.repository.root_ref) }
+ let(:user) { create(:user) }
+
+ before do
+ stub_feature_flags(refactor_blob_viewer: false)
+ sign_in(user)
+ end
+
+ context 'when an user has write access' do
+ before do
+ project.add_maintainer(user)
+ visit(project_tree_path_root_ref)
+ wait_for_requests
+ end
+
+ it 'deletes the file', :js do
+ click_link('.gitignore')
+
+ expect(page).to have_content('.gitignore')
+
+ click_on('Delete')
+ fill_in(:commit_message, with: 'New commit message', visible: true)
+ click_button('Delete file')
+
+ expect(page).to have_current_path(project_tree_path(project, 'master/'), ignore_query: true)
+ expect(page).not_to have_content('.gitignore')
+ end
+ end
+
+ context 'when an user does not have write access', :js do
+ before do
+ project2.add_reporter(user)
+ visit(project2_tree_path_root_ref)
+ wait_for_requests
+ end
+
+ it 'deletes the file in a forked project', :js, :sidekiq_might_not_need_inline do
+ click_link('.gitignore')
+
+ expect(page).to have_content('.gitignore')
+
+ click_on('Delete')
+
+ expect(page).to have_link('Fork')
+ expect(page).to have_button('Cancel')
+
+ click_link('Fork')
+
+ expect(page).to have_content(fork_message)
+
+ click_on('Delete')
+ fill_in(:commit_message, with: 'New commit message', visible: true)
+ click_button('Delete file')
+
+ fork = user.fork_of(project2.reload)
+
+ expect(page).to have_current_path(project_new_merge_request_path(fork), ignore_query: true)
+ expect(page).to have_content('New commit message')
+ end
+ end
+end
diff --git a/spec/features/refactor_blob_viewer_disabled/projects/files/user_edits_files_spec.rb b/spec/features/refactor_blob_viewer_disabled/projects/files/user_edits_files_spec.rb
new file mode 100644
index 00000000000..7a70d67d8ca
--- /dev/null
+++ b/spec/features/refactor_blob_viewer_disabled/projects/files/user_edits_files_spec.rb
@@ -0,0 +1,226 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Projects > Files > User edits files', :js do
+ include ProjectForksHelper
+ include BlobSpecHelpers
+
+ let(:project) { create(:project, :repository, name: 'Shop') }
+ let(:project2) { create(:project, :repository, name: 'Another Project', path: 'another-project') }
+ let(:project_tree_path_root_ref) { project_tree_path(project, project.repository.root_ref) }
+ let(:project2_tree_path_root_ref) { project_tree_path(project2, project2.repository.root_ref) }
+ let(:user) { create(:user) }
+
+ before do
+ stub_feature_flags(refactor_blob_viewer: false)
+ sign_in(user)
+ end
+
+ after do
+ unset_default_button
+ end
+
+ shared_examples 'unavailable for an archived project' do
+ it 'does not show the edit link for an archived project', :js do
+ project.update!(archived: true)
+ visit project_tree_path(project, project.repository.root_ref)
+
+ click_link('.gitignore')
+
+ aggregate_failures 'available edit buttons' do
+ expect(page).not_to have_text('Edit')
+ expect(page).not_to have_text('Web IDE')
+
+ expect(page).not_to have_text('Replace')
+ expect(page).not_to have_text('Delete')
+ end
+ end
+ end
+
+ context 'when an user has write access', :js do
+ before do
+ project.add_maintainer(user)
+ visit(project_tree_path_root_ref)
+ wait_for_requests
+ end
+
+ it 'inserts a content of a file' do
+ set_default_button('edit')
+ click_link('.gitignore')
+ click_link_or_button('Edit')
+ find('.file-editor', match: :first)
+
+ find('#editor')
+ set_editor_value('*.rbca')
+
+ expect(editor_value).to eq('*.rbca')
+ end
+
+ it 'does not show the edit link if a file is binary' do
+ binary_file = File.join(project.repository.root_ref, 'files/images/logo-black.png')
+ visit(project_blob_path(project, binary_file))
+ wait_for_requests
+
+ page.within '.content' do
+ expect(page).not_to have_link('edit')
+ end
+ end
+
+ it 'commits an edited file' do
+ set_default_button('edit')
+ click_link('.gitignore')
+ click_link_or_button('Edit')
+ find('.file-editor', match: :first)
+
+ find('#editor')
+ set_editor_value('*.rbca')
+ fill_in(:commit_message, with: 'New commit message', visible: true)
+ click_button('Commit changes')
+
+ expect(page).to have_current_path(project_blob_path(project, 'master/.gitignore'), ignore_query: true)
+
+ wait_for_requests
+
+ expect(page).to have_content('*.rbca')
+ end
+
+ it 'commits an edited file to a new branch' do
+ set_default_button('edit')
+ click_link('.gitignore')
+ click_link_or_button('Edit')
+
+ find('.file-editor', match: :first)
+
+ find('#editor')
+ set_editor_value('*.rbca')
+ fill_in(:commit_message, with: 'New commit message', visible: true)
+ fill_in(:branch_name, with: 'new_branch_name', visible: true)
+ click_button('Commit changes')
+
+ expect(page).to have_current_path(project_new_merge_request_path(project), ignore_query: true)
+
+ click_link('Changes')
+
+ expect(page).to have_content('*.rbca')
+ end
+
+ it 'shows the diff of an edited file' do
+ set_default_button('edit')
+ click_link('.gitignore')
+ click_link_or_button('Edit')
+ find('.file-editor', match: :first)
+
+ find('#editor')
+ set_editor_value('*.rbca')
+ click_link('Preview changes')
+
+ expect(page).to have_css('.line_holder.new')
+ end
+
+ it_behaves_like 'unavailable for an archived project'
+ end
+
+ context 'when an user does not have write access', :js do
+ before do
+ project2.add_reporter(user)
+ visit(project2_tree_path_root_ref)
+ wait_for_requests
+ end
+
+ def expect_fork_prompt
+ expect(page).to have_selector(:link_or_button, 'Fork')
+ expect(page).to have_selector(:link_or_button, 'Cancel')
+ expect(page).to have_content(
+ "You can’t edit files directly in this project. "\
+ "Fork this project and submit a merge request with your changes."
+ )
+ end
+
+ def expect_fork_status
+ expect(page).to have_content(
+ "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."
+ )
+ end
+
+ it 'inserts a content of a file in a forked project', :sidekiq_might_not_need_inline do
+ set_default_button('edit')
+ click_link('.gitignore')
+ click_link_or_button('Edit')
+
+ expect_fork_prompt
+
+ click_link_or_button('Fork project')
+
+ expect_fork_status
+
+ find('.file-editor', match: :first)
+
+ find('#editor')
+ set_editor_value('*.rbca')
+
+ expect(editor_value).to eq('*.rbca')
+ end
+
+ it 'commits an edited file in a forked project', :sidekiq_might_not_need_inline do
+ set_default_button('edit')
+ click_link('.gitignore')
+ click_link_or_button('Edit')
+
+ expect_fork_prompt
+ click_link_or_button('Fork project')
+
+ find('.file-editor', match: :first)
+
+ find('#editor')
+ set_editor_value('*.rbca')
+ fill_in(:commit_message, with: 'New commit message', visible: true)
+ click_button('Commit changes')
+
+ fork = user.fork_of(project2.reload)
+
+ expect(page).to have_current_path(project_new_merge_request_path(fork), ignore_query: true)
+
+ wait_for_requests
+
+ expect(page).to have_content('New commit message')
+ end
+
+ context 'when the user already had a fork of the project', :js do
+ let!(:forked_project) { fork_project(project2, user, namespace: user.namespace, repository: true) }
+
+ before do
+ visit(project2_tree_path_root_ref)
+ wait_for_requests
+ end
+
+ it 'links to the forked project for editing', :sidekiq_might_not_need_inline do
+ set_default_button('edit')
+ click_link('.gitignore')
+ click_link_or_button('Edit')
+
+ expect(page).not_to have_link('Fork project')
+
+ find('#editor')
+ set_editor_value('*.rbca')
+ fill_in(:commit_message, with: 'Another commit', visible: true)
+ click_button('Commit changes')
+
+ fork = user.fork_of(project2)
+
+ expect(page).to have_current_path(project_new_merge_request_path(fork), ignore_query: true)
+
+ wait_for_requests
+
+ expect(page).to have_content('Another commit')
+ expect(page).to have_content("From #{forked_project.full_path}")
+ expect(page).to have_content("into #{project2.full_path}")
+ end
+
+ it_behaves_like 'unavailable for an archived project' do
+ let(:project) { project2 }
+ end
+ end
+ end
+end
diff --git a/spec/features/refactor_blob_viewer_disabled/projects/files/user_replaces_files_spec.rb b/spec/features/refactor_blob_viewer_disabled/projects/files/user_replaces_files_spec.rb
new file mode 100644
index 00000000000..5561cf15a66
--- /dev/null
+++ b/spec/features/refactor_blob_viewer_disabled/projects/files/user_replaces_files_spec.rb
@@ -0,0 +1,93 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Projects > Files > User replaces files', :js do
+ include DropzoneHelper
+
+ 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."
+ end
+
+ let(:project) { create(:project, :repository, name: 'Shop') }
+ let(:project2) { create(:project, :repository, name: 'Another Project', path: 'another-project') }
+ let(:project_tree_path_root_ref) { project_tree_path(project, project.repository.root_ref) }
+ let(:project2_tree_path_root_ref) { project_tree_path(project2, project2.repository.root_ref) }
+ let(:user) { create(:user) }
+
+ before do
+ stub_feature_flags(refactor_blob_viewer: false)
+ sign_in(user)
+ end
+
+ context 'when an user has write access' do
+ before do
+ project.add_maintainer(user)
+ visit(project_tree_path_root_ref)
+ wait_for_requests
+ end
+
+ it 'replaces an existed file with a new one' do
+ click_link('.gitignore')
+
+ expect(page).to have_content('.gitignore')
+
+ click_on('Replace')
+ drop_in_dropzone(File.join(Rails.root, 'spec', 'fixtures', 'doc_sample.txt'))
+
+ page.within('#modal-upload-blob') do
+ fill_in(:commit_message, with: 'Replacement file commit message')
+ end
+
+ click_button('Replace file')
+
+ expect(page).to have_content('Lorem ipsum dolor sit amet')
+ expect(page).to have_content('Sed ut perspiciatis unde omnis')
+ expect(page).to have_content('Replacement file commit message')
+ end
+ end
+
+ context 'when an user does not have write access' do
+ before do
+ project2.add_reporter(user)
+ visit(project2_tree_path_root_ref)
+ wait_for_requests
+ end
+
+ it 'replaces an existed file with a new one in a forked project', :sidekiq_might_not_need_inline do
+ click_link('.gitignore')
+
+ expect(page).to have_content('.gitignore')
+
+ click_on('Replace')
+
+ expect(page).to have_link('Fork')
+ expect(page).to have_button('Cancel')
+
+ click_link('Fork')
+
+ expect(page).to have_content(fork_message)
+
+ click_on('Replace')
+ drop_in_dropzone(File.join(Rails.root, 'spec', 'fixtures', 'doc_sample.txt'))
+
+ page.within('#modal-upload-blob') do
+ fill_in(:commit_message, with: 'Replacement file commit message')
+ end
+
+ click_button('Replace file')
+
+ expect(page).to have_content('Replacement file commit message')
+
+ fork = user.fork_of(project2.reload)
+
+ expect(page).to have_current_path(project_new_merge_request_path(fork), ignore_query: true)
+
+ click_link('Changes')
+
+ expect(page).to have_content('Lorem ipsum dolor sit amet')
+ expect(page).to have_content('Sed ut perspiciatis unde omnis')
+ end
+ end
+end
diff --git a/spec/features/search/user_searches_for_code_spec.rb b/spec/features/search/user_searches_for_code_spec.rb
index c04a4493a9b..53c95b4a446 100644
--- a/spec/features/search/user_searches_for_code_spec.rb
+++ b/spec/features/search/user_searches_for_code_spec.rb
@@ -42,7 +42,7 @@ RSpec.describe 'User searches for code' do
it 'finds code and links to blob' do
fill_in('dashboard_search', with: 'rspec')
- find('.btn-search').click
+ find('.gl-search-box-by-click-search-button').click
expect(page).to have_selector('.results', text: 'Update capybara, rspec-rails, poltergeist to recent versions')
@@ -52,7 +52,7 @@ RSpec.describe 'User searches for code' do
it 'finds code and links to blame' do
fill_in('dashboard_search', with: 'rspec')
- find('.btn-search').click
+ find('.gl-search-box-by-click-search-button').click
expect(page).to have_selector('.results', text: 'Update capybara, rspec-rails, poltergeist to recent versions')
@@ -65,7 +65,7 @@ RSpec.describe 'User searches for code' do
search = 'for naming files'
fill_in('dashboard_search', with: search)
- find('.btn-search').click
+ find('.gl-search-box-by-click-search-button').click
expect(page).to have_selector('.results', text: expected_result)
@@ -80,46 +80,103 @@ RSpec.describe 'User searches for code' do
end
end
- context 'search code within refs', :js do
- let(:ref_name) { 'v1.0.0' }
+ context 'when :new_header_search is true' do
+ context 'search code within refs', :js do
+ let(:ref_name) { 'v1.0.0' }
- before do
- visit(project_tree_path(project, ref_name))
+ before do
+ # This feature is diabled by default in spec_helper.rb.
+ # We missed a feature breaking bug, so to prevent this regression, testing both scenarios for this spec.
+ # This can be removed as part of closing https://gitlab.com/gitlab-org/gitlab/-/issues/339348.
+ stub_feature_flags(new_header_search: true)
+ visit(project_tree_path(project, ref_name))
- submit_search('gitlab-grack')
- select_search_scope('Code')
- end
+ submit_search('gitlab-grack')
+ select_search_scope('Code')
+ end
- it 'shows ref switcher in code result summary' do
- expect(find('.js-project-refs-dropdown')).to have_text(ref_name)
- end
- it 'persists branch name across search' do
- find('.btn-search').click
- expect(find('.js-project-refs-dropdown')).to have_text(ref_name)
- end
+ it 'shows ref switcher in code result summary' do
+ expect(find('.js-project-refs-dropdown')).to have_text(ref_name)
+ end
- # this example is use to test the desgine that the refs is not
- # only repersent the branch as well as the tags.
- it 'ref swither list all the branchs and tags' do
- find('.js-project-refs-dropdown').click
- expect(find('.dropdown-page-one .dropdown-content')).to have_link('sha-starting-with-large-number')
- expect(find('.dropdown-page-one .dropdown-content')).to have_link('v1.0.0')
- end
+ it 'persists branch name across search' do
+ find('.gl-search-box-by-click-search-button').click
+ expect(find('.js-project-refs-dropdown')).to have_text(ref_name)
+ end
+
+ # this example is use to test the desgine that the refs is not
+ # only repersent the branch as well as the tags.
+ it 'ref swither list all the branchs and tags' do
+ find('.js-project-refs-dropdown').click
+ expect(find('.dropdown-page-one .dropdown-content')).to have_link('sha-starting-with-large-number')
+ expect(find('.dropdown-page-one .dropdown-content')).to have_link('v1.0.0')
+ end
- it 'search result changes when refs switched' do
- expect(find('.results')).not_to have_content('path = gitlab-grack')
+ it 'search result changes when refs switched' do
+ expect(find('.results')).not_to have_content('path = gitlab-grack')
- find('.js-project-refs-dropdown').click
- find('.dropdown-page-one .dropdown-content').click_link('master')
+ find('.js-project-refs-dropdown').click
+ find('.dropdown-page-one .dropdown-content').click_link('master')
- expect(page).to have_selector('.results', text: 'path = gitlab-grack')
+ expect(page).to have_selector('.results', text: 'path = gitlab-grack')
+ end
+
+ it 'persist refs over browser tabs' do
+ ref = 'feature'
+ find('.js-project-refs-dropdown').click
+ link = find_link(ref)[:href]
+ expect(link.include?("repository_ref=" + ref)).to be(true)
+ end
end
+ end
- it 'persist refs over browser tabs' do
- ref = 'feature'
- find('.js-project-refs-dropdown').click
- link = find_link(ref)[:href]
- expect(link.include?("repository_ref=" + ref)).to be(true)
+ context 'when :new_header_search is false' do
+ context 'search code within refs', :js do
+ let(:ref_name) { 'v1.0.0' }
+
+ before do
+ # This feature is diabled by default in spec_helper.rb.
+ # We missed a feature breaking bug, so to prevent this regression, testing both scenarios for this spec.
+ # This can be removed as part of closing https://gitlab.com/gitlab-org/gitlab/-/issues/339348.
+ stub_feature_flags(new_header_search: false)
+ visit(project_tree_path(project, ref_name))
+
+ submit_search('gitlab-grack')
+ select_search_scope('Code')
+ end
+
+ it 'shows ref switcher in code result summary' do
+ expect(find('.js-project-refs-dropdown')).to have_text(ref_name)
+ end
+
+ it 'persists branch name across search' do
+ find('.gl-search-box-by-click-search-button').click
+ expect(find('.js-project-refs-dropdown')).to have_text(ref_name)
+ end
+
+ # this example is use to test the desgine that the refs is not
+ # only repersent the branch as well as the tags.
+ it 'ref swither list all the branchs and tags' do
+ find('.js-project-refs-dropdown').click
+ expect(find('.dropdown-page-one .dropdown-content')).to have_link('sha-starting-with-large-number')
+ expect(find('.dropdown-page-one .dropdown-content')).to have_link('v1.0.0')
+ end
+
+ it 'search result changes when refs switched' do
+ expect(find('.results')).not_to have_content('path = gitlab-grack')
+
+ find('.js-project-refs-dropdown').click
+ find('.dropdown-page-one .dropdown-content').click_link('master')
+
+ expect(page).to have_selector('.results', text: 'path = gitlab-grack')
+ end
+
+ it 'persist refs over browser tabs' do
+ ref = 'feature'
+ find('.js-project-refs-dropdown').click
+ link = find_link(ref)[:href]
+ expect(link.include?("repository_ref=" + ref)).to be(true)
+ end
end
end
diff --git a/spec/features/search/user_searches_for_issues_spec.rb b/spec/features/search/user_searches_for_issues_spec.rb
index b0902096770..c23a54594d4 100644
--- a/spec/features/search/user_searches_for_issues_spec.rb
+++ b/spec/features/search/user_searches_for_issues_spec.rb
@@ -10,7 +10,7 @@ RSpec.describe 'User searches for issues', :js do
def search_for_issue(search)
fill_in('dashboard_search', with: search)
- find('.btn-search').click
+ find('.gl-search-box-by-click-search-button').click
select_search_scope('Issues')
end
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 d7f490ba9bc..61c61d793db 100644
--- a/spec/features/search/user_searches_for_merge_requests_spec.rb
+++ b/spec/features/search/user_searches_for_merge_requests_spec.rb
@@ -10,7 +10,7 @@ RSpec.describe 'User searches for merge requests', :js do
def search_for_mr(search)
fill_in('dashboard_search', with: search)
- find('.btn-search').click
+ find('.gl-search-box-by-click-search-button').click
select_search_scope('Merge requests')
end
diff --git a/spec/features/search/user_searches_for_milestones_spec.rb b/spec/features/search/user_searches_for_milestones_spec.rb
index 7a1ec16385c..61f2e8e0c8f 100644
--- a/spec/features/search/user_searches_for_milestones_spec.rb
+++ b/spec/features/search/user_searches_for_milestones_spec.rb
@@ -20,7 +20,7 @@ RSpec.describe 'User searches for milestones', :js do
it 'finds a milestone' do
fill_in('dashboard_search', with: milestone1.title)
- find('.btn-search').click
+ find('.gl-search-box-by-click-search-button').click
select_search_scope('Milestones')
page.within('.results') do
@@ -40,7 +40,7 @@ RSpec.describe 'User searches for milestones', :js do
end
fill_in('dashboard_search', with: milestone1.title)
- find('.btn-search').click
+ find('.gl-search-box-by-click-search-button').click
select_search_scope('Milestones')
page.within('.results') do
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 06545d8640f..9808383adb7 100644
--- a/spec/features/search/user_searches_for_wiki_pages_spec.rb
+++ b/spec/features/search/user_searches_for_wiki_pages_spec.rb
@@ -28,7 +28,7 @@ RSpec.describe 'User searches for wiki pages', :js do
end
fill_in('dashboard_search', with: search_term)
- find('.btn-search').click
+ find('.gl-search-box-by-click-search-button').click
select_search_scope('Wiki')
page.within('.results') do
diff --git a/spec/features/static_site_editor_spec.rb b/spec/features/static_site_editor_spec.rb
index a47579582e2..98313905a33 100644
--- a/spec/features/static_site_editor_spec.rb
+++ b/spec/features/static_site_editor_spec.rb
@@ -3,6 +3,8 @@
require 'spec_helper'
RSpec.describe 'Static Site Editor' do
+ include ContentSecurityPolicyHelpers
+
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project, :public, :repository) }
@@ -79,10 +81,7 @@ RSpec.describe 'Static Site Editor' do
context 'when no global CSP config exists' do
before do
- expect_next_instance_of(Projects::StaticSiteEditorController) do |controller|
- expect(controller).to receive(:current_content_security_policy)
- .and_return(ActionDispatch::ContentSecurityPolicy.new)
- end
+ setup_csp_for_controller(Projects::StaticSiteEditorController)
end
it 'does not add CSP directives' do
@@ -101,9 +100,7 @@ RSpec.describe 'Static Site Editor' do
p.frame_src :self, cdn_url
end
- expect_next_instance_of(Projects::StaticSiteEditorController) do |controller|
- expect(controller).to receive(:current_content_security_policy).and_return(csp)
- end
+ setup_existing_csp_for_controller(Projects::StaticSiteEditorController, csp)
end
it 'appends youtube to the CSP frame-src policy' do
diff --git a/spec/features/tags/developer_creates_tag_spec.rb b/spec/features/tags/developer_creates_tag_spec.rb
index f982d403ce1..b0219cb546d 100644
--- a/spec/features/tags/developer_creates_tag_spec.rb
+++ b/spec/features/tags/developer_creates_tag_spec.rb
@@ -38,8 +38,8 @@ RSpec.describe 'Developer creates tag' do
it 'with multiline message displays the message in a <pre> block' do
create_tag_in_form(tag: 'v3.0', ref: 'master', message: "Awesome tag message\n\n- hello\n- world")
- expect(current_path).to eq(
- project_tag_path(project, 'v3.0'))
+ expect(page).to have_current_path(
+ project_tag_path(project, 'v3.0'), ignore_query: true)
expect(page).to have_content 'v3.0'
page.within 'pre.wrap' do
expect(page).to have_content "Awesome tag message - hello - world"
@@ -49,8 +49,8 @@ RSpec.describe 'Developer creates tag' do
it 'with multiline release notes parses the release note as Markdown' do
create_tag_in_form(tag: 'v4.0', ref: 'master', desc: "Awesome release notes\n\n- hello\n- world")
- expect(current_path).to eq(
- project_tag_path(project, 'v4.0'))
+ expect(page).to have_current_path(
+ project_tag_path(project, 'v4.0'), ignore_query: true)
expect(page).to have_content 'v4.0'
page.within '.description' do
expect(page).to have_content 'Awesome release notes'
diff --git a/spec/features/tags/developer_deletes_tag_spec.rb b/spec/features/tags/developer_deletes_tag_spec.rb
index 7c4c6f54685..6b669695f7b 100644
--- a/spec/features/tags/developer_deletes_tag_spec.rb
+++ b/spec/features/tags/developer_deletes_tag_spec.rb
@@ -27,13 +27,13 @@ RSpec.describe 'Developer deletes tag', :js do
context 'from a specific tag page' do
it 'deletes the tag' do
click_on 'v1.0.0'
- expect(current_path).to eq(
- project_tag_path(project, 'v1.0.0'))
+ expect(page).to have_current_path(
+ project_tag_path(project, 'v1.0.0'), ignore_query: true)
container = page.find('.nav-controls')
delete_tag container
- expect(current_path).to eq("#{project_tags_path(project)}/")
+ expect(page).to have_current_path("#{project_tags_path(project)}/", ignore_query: true)
expect(page).not_to have_content 'v1.0.0'
end
end
diff --git a/spec/features/tags/developer_updates_tag_spec.rb b/spec/features/tags/developer_updates_tag_spec.rb
index 93a275131bd..b2fc28b8493 100644
--- a/spec/features/tags/developer_updates_tag_spec.rb
+++ b/spec/features/tags/developer_updates_tag_spec.rb
@@ -20,8 +20,8 @@ RSpec.describe 'Developer updates tag' do
fill_in 'release_description', with: 'Awesome release notes'
click_button 'Save changes'
- expect(current_path).to eq(
- project_tag_path(project, 'v1.1.0'))
+ expect(page).to have_current_path(
+ project_tag_path(project, 'v1.1.0'), ignore_query: true)
expect(page).to have_content 'v1.1.0'
expect(page).to have_content 'Awesome release notes'
end
@@ -45,8 +45,8 @@ RSpec.describe 'Developer updates tag' do
fill_in 'release_description', with: 'Awesome release notes'
click_button 'Save changes'
- expect(current_path).to eq(
- project_tag_path(project, 'v1.1.0'))
+ expect(page).to have_current_path(
+ project_tag_path(project, 'v1.1.0'), ignore_query: true)
expect(page).to have_content 'v1.1.0'
expect(page).to have_content 'Awesome release notes'
end
diff --git a/spec/features/tags/developer_views_tags_spec.rb b/spec/features/tags/developer_views_tags_spec.rb
index 6bae53afe6f..57e1f7da04e 100644
--- a/spec/features/tags/developer_views_tags_spec.rb
+++ b/spec/features/tags/developer_views_tags_spec.rb
@@ -55,8 +55,8 @@ RSpec.describe 'Developer views tags' do
it 'views a specific tag page' do
click_on 'v1.0.0'
- expect(current_path).to eq(
- project_tag_path(project, 'v1.0.0'))
+ expect(page).to have_current_path(
+ project_tag_path(project, 'v1.0.0'), ignore_query: true)
expect(page).to have_content 'v1.0.0'
expect(page).to have_content 'This tag has no release notes.'
end
@@ -65,25 +65,25 @@ RSpec.describe 'Developer views tags' do
it 'has a button to browse files' do
click_on 'v1.0.0'
- expect(current_path).to eq(
- project_tag_path(project, 'v1.0.0'))
+ expect(page).to have_current_path(
+ project_tag_path(project, 'v1.0.0'), ignore_query: true)
click_on 'Browse files'
- expect(current_path).to eq(
- project_tree_path(project, 'v1.0.0'))
+ expect(page).to have_current_path(
+ project_tree_path(project, 'v1.0.0'), ignore_query: true)
end
it 'has a button to browse commits' do
click_on 'v1.0.0'
- expect(current_path).to eq(
- project_tag_path(project, 'v1.0.0'))
+ expect(page).to have_current_path(
+ project_tag_path(project, 'v1.0.0'), ignore_query: true)
click_on 'Browse commits'
- expect(current_path).to eq(
- project_commits_path(project, 'v1.0.0'))
+ expect(page).to have_current_path(
+ project_commits_path(project, 'v1.0.0'), ignore_query: true)
end
end
end
diff --git a/spec/features/triggers_spec.rb b/spec/features/triggers_spec.rb
index 1f1824c897e..7f5cf2359a3 100644
--- a/spec/features/triggers_spec.rb
+++ b/spec/features/triggers_spec.rb
@@ -17,6 +17,8 @@ RSpec.describe 'Triggers', :js do
@project.add_guest(guest_user)
visit project_settings_ci_cd_path(@project)
+
+ wait_for_requests
end
shared_examples 'triggers page' do
diff --git a/spec/features/unsubscribe_links_spec.rb b/spec/features/unsubscribe_links_spec.rb
index b7471720008..3fe276ce162 100644
--- a/spec/features/unsubscribe_links_spec.rb
+++ b/spec/features/unsubscribe_links_spec.rb
@@ -25,7 +25,7 @@ RSpec.describe 'Unsubscribe links', :sidekiq_might_not_need_inline do
it 'shows the unsubscribe confirmation page and redirects to root path when confirming' do
visit body_link
- expect(current_path).to eq unsubscribe_sent_notification_path(SentNotification.last)
+ expect(page).to have_current_path unsubscribe_sent_notification_path(SentNotification.last), ignore_query: true
expect(page).to have_text(%(Unsubscribe from issue))
expect(page).to have_text(%(Are you sure you want to unsubscribe from the issue: #{issue.title} (#{issue.to_reference})?))
expect(issue.subscribed?(recipient, project)).to be_truthy
@@ -33,19 +33,19 @@ RSpec.describe 'Unsubscribe links', :sidekiq_might_not_need_inline do
click_link 'Unsubscribe'
expect(issue.subscribed?(recipient, project)).to be_falsey
- expect(current_path).to eq new_user_session_path
+ expect(page).to have_current_path new_user_session_path, ignore_query: true
end
it 'shows the unsubscribe confirmation page and redirects to root path when canceling' do
visit body_link
- expect(current_path).to eq unsubscribe_sent_notification_path(SentNotification.last)
+ expect(page).to have_current_path unsubscribe_sent_notification_path(SentNotification.last), ignore_query: true
expect(issue.subscribed?(recipient, project)).to be_truthy
click_link 'Cancel'
expect(issue.subscribed?(recipient, project)).to be_truthy
- expect(current_path).to eq new_user_session_path
+ expect(page).to have_current_path new_user_session_path, ignore_query: true
end
end
diff --git a/spec/features/users/active_sessions_spec.rb b/spec/features/users/active_sessions_spec.rb
index 6dc93fe017f..c722a4ec05c 100644
--- a/spec/features/users/active_sessions_spec.rb
+++ b/spec/features/users/active_sessions_spec.rb
@@ -8,7 +8,7 @@ RSpec.describe 'Active user sessions', :clean_gitlab_redis_sessions do
Timecop.freeze(now) do
user = create(:user)
gitlab_sign_in(user)
- expect(current_path).to eq root_path
+ expect(page).to have_current_path root_path, ignore_query: true
sessions = ActiveSession.list(user)
expect(sessions.count).to eq 1
@@ -59,12 +59,12 @@ RSpec.describe 'Active user sessions', :clean_gitlab_redis_sessions do
it 'logout deletes the active user login' do
user = create(:user)
gitlab_sign_in(user)
- expect(current_path).to eq root_path
+ expect(page).to have_current_path root_path, ignore_query: true
expect(ActiveSession.list(user).count).to eq 1
gitlab_sign_out
- expect(current_path).to eq new_user_session_path
+ expect(page).to have_current_path new_user_session_path, ignore_query: true
expect(ActiveSession.list(user)).to be_empty
end
diff --git a/spec/features/users/login_spec.rb b/spec/features/users/login_spec.rb
index 2780549eea1..4d06415e203 100644
--- a/spec/features/users/login_spec.rb
+++ b/spec/features/users/login_spec.rb
@@ -28,7 +28,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
expect(user.reset_password_token).not_to be_nil
gitlab_sign_in(user)
- expect(current_path).to eq root_path
+ expect(page).to have_current_path root_path, ignore_query: true
user.reload
expect(user.reset_password_token).to be_nil
@@ -46,14 +46,14 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
user = create(:admin, password_automatically_set: true)
visit root_path
- expect(current_path).to eq edit_user_password_path
+ expect(page).to have_current_path edit_user_password_path, ignore_query: true
expect(page).to have_content('Please create a password for your new account.')
fill_in 'user_password', with: Gitlab::Password.test_default
fill_in 'user_password_confirmation', with: Gitlab::Password.test_default
click_button 'Change your password'
- expect(current_path).to eq new_user_session_path
+ expect(page).to have_current_path new_user_session_path, ignore_query: true
expect(page).to have_content(I18n.t('devise.passwords.updated_not_active'))
fill_in 'user_login', with: user.username
@@ -61,7 +61,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
click_button 'Sign in'
expect_single_session_with_authenticated_ttl
- expect(current_path).to eq root_path
+ expect(page).to have_current_path root_path, ignore_query: true
end
it 'does not show flash messages when login page' do
@@ -145,7 +145,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
fill_in 'user_email', with: user.email
click_button 'Resend'
- expect(current_path).to eq users_almost_there_path
+ expect(page).to have_current_path users_almost_there_path, ignore_query: true
end
end
end
@@ -226,7 +226,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
enter_code(user.current_otp)
expect_single_session_with_authenticated_ttl
- expect(current_path).to eq root_path
+ expect(page).to have_current_path root_path, ignore_query: true
end
it 'persists remember_me value via hidden field' do
@@ -255,7 +255,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
enter_code(user.current_otp)
expect_single_session_with_authenticated_ttl
- expect(current_path).to eq root_path
+ expect(page).to have_current_path root_path, ignore_query: true
end
it 'triggers ActiveSession.cleanup for the user' do
@@ -286,7 +286,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
enter_code(codes.sample)
- expect(current_path).to eq root_path
+ expect(page).to have_current_path root_path, ignore_query: true
end
it 'invalidates the used code' do
@@ -373,7 +373,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
expect_single_session_with_authenticated_ttl
expect(page).not_to have_content('Two-Factor Authentication')
- expect(current_path).to eq root_path
+ expect(page).to have_current_path root_path, ignore_query: true
end
end
@@ -391,7 +391,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
enter_code(user.current_otp)
expect_single_session_with_authenticated_ttl
- expect(current_path).to eq root_path
+ expect(page).to have_current_path root_path, ignore_query: true
end
end
@@ -412,7 +412,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
gitlab_sign_in(user)
expect_single_session_with_authenticated_ttl
- expect(current_path).to eq root_path
+ expect(page).to have_current_path root_path, ignore_query: true
expect(page).not_to have_content(I18n.t('devise.failure.already_authenticated'))
end
@@ -437,7 +437,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
context 'when the users password is expired' do
before do
- user.update!(password_expires_at: Time.parse('2018-05-08 11:29:46 UTC'))
+ user.update!(password_expires_at: Time.zone.parse('2018-05-08 11:29:46 UTC'))
end
it 'asks for a new password' do
@@ -450,7 +450,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
fill_in 'user_password', with: Gitlab::Password.test_default
click_button 'Sign in'
- expect(current_path).to eq(new_profile_password_path)
+ expect(page).to have_current_path(new_profile_password_path, ignore_query: true)
end
end
end
@@ -493,7 +493,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
gitlab_sign_in(user)
- expect(current_path).to eq profile_two_factor_auth_path
+ expect(page).to have_current_path profile_two_factor_auth_path, ignore_query: true
expect(page).to have_content('The global settings require you to enable Two-Factor Authentication for your account. You need to do this before ')
end
@@ -503,9 +503,9 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
gitlab_sign_in(user)
- expect(current_path).to eq profile_two_factor_auth_path
+ expect(page).to have_current_path profile_two_factor_auth_path, ignore_query: true
click_link 'Configure it later'
- expect(current_path).to eq root_path
+ expect(page).to have_current_path root_path, ignore_query: true
end
end
@@ -518,7 +518,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
gitlab_sign_in(user)
- expect(current_path).to eq profile_two_factor_auth_path
+ expect(page).to have_current_path profile_two_factor_auth_path, ignore_query: true
expect(page).to have_content(
'The global settings require you to enable Two-Factor Authentication for your account.'
)
@@ -530,7 +530,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
gitlab_sign_in(user)
- expect(current_path).to eq profile_two_factor_auth_path
+ expect(page).to have_current_path profile_two_factor_auth_path, ignore_query: true
expect(page).not_to have_link('Configure it later')
end
end
@@ -547,7 +547,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
gitlab_sign_in(user)
- expect(current_path).to eq profile_two_factor_auth_path
+ expect(page).to have_current_path profile_two_factor_auth_path, ignore_query: true
expect(page).to have_content(
'The global settings require you to enable Two-Factor Authentication for your account.'
)
@@ -576,7 +576,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
gitlab_sign_in(user)
- expect(current_path).to eq profile_two_factor_auth_path
+ expect(page).to have_current_path profile_two_factor_auth_path, ignore_query: true
expect(page).to have_content(
'The group settings for Group 1 and Group 2 require you to enable '\
'Two-Factor Authentication for your account. '\
@@ -594,9 +594,9 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
gitlab_sign_in(user)
- expect(current_path).to eq profile_two_factor_auth_path
+ expect(page).to have_current_path profile_two_factor_auth_path, ignore_query: true
click_link 'Configure it later'
- expect(current_path).to eq root_path
+ expect(page).to have_current_path root_path, ignore_query: true
end
end
@@ -609,7 +609,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
gitlab_sign_in(user)
- expect(current_path).to eq profile_two_factor_auth_path
+ expect(page).to have_current_path profile_two_factor_auth_path, ignore_query: true
expect(page).to have_content(
'The group settings for Group 1 and Group 2 require you to enable ' \
'Two-Factor Authentication for your account.'
@@ -622,7 +622,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
gitlab_sign_in(user)
- expect(current_path).to eq profile_two_factor_auth_path
+ expect(page).to have_current_path profile_two_factor_auth_path, ignore_query: true
expect(page).not_to have_link('Configure it later')
end
end
@@ -639,7 +639,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
gitlab_sign_in(user)
- expect(current_path).to eq profile_two_factor_auth_path
+ expect(page).to have_current_path profile_two_factor_auth_path, ignore_query: true
expect(page).to have_content(
'The group settings for Group 1 and Group 2 require you to enable ' \
'Two-Factor Authentication for your account. '\
@@ -775,7 +775,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
click_button 'Accept terms'
- expect(current_path).to eq(root_path)
+ expect(page).to have_current_path(root_path, ignore_query: true)
expect(page).not_to have_content(I18n.t('devise.failure.already_authenticated'))
end
@@ -792,11 +792,12 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
click_button 'Sign in'
- expect(current_path).to eq(root_path)
+ expect(page).to have_current_path(root_path, ignore_query: true)
end
context 'when 2FA is required for the user' do
before do
+ stub_feature_flags(mr_attention_requests: false)
group = create(:group, require_two_factor_authentication: true)
group.add_developer(user)
end
@@ -816,7 +817,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
expect_to_be_on_terms_page
click_button 'Accept terms'
- expect(current_path).to eq(profile_two_factor_auth_path)
+ expect(page).to have_current_path(profile_two_factor_auth_path, ignore_query: true)
fill_in 'pin_code', with: user.reload.current_otp
fill_in 'current_password', with: user.password
@@ -825,7 +826,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
click_button 'Copy codes'
click_link 'Proceed'
- expect(current_path).to eq(profile_account_path)
+ expect(page).to have_current_path(profile_account_path, ignore_query: true)
expect(page).to have_content('You have set up 2FA for your account! If you lose access to your 2FA device, you can use your recovery codes to access your account. Alternatively, if you upload an SSH key, you can use that key to generate additional recovery codes.')
end
end
@@ -853,14 +854,14 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
expect_to_be_on_terms_page
click_button 'Accept terms'
- expect(current_path).to eq(root_path)
+ expect(page).to have_current_path(root_path, ignore_query: true)
end
end
end
context 'when the users password is expired' do
before do
- user.update!(password_expires_at: Time.parse('2018-05-08 11:29:46 UTC'))
+ user.update!(password_expires_at: Time.zone.parse('2018-05-08 11:29:46 UTC'))
end
it 'asks the user to accept the terms before setting a new password' do
@@ -876,7 +877,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
expect_to_be_on_terms_page
click_button 'Accept terms'
- expect(current_path).to eq(new_profile_password_path)
+ expect(page).to have_current_path(new_profile_password_path, ignore_query: true)
fill_in 'user_password', with: Gitlab::Password.test_default
fill_in 'user_new_password', with: 'new password'
@@ -903,7 +904,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
expect_to_be_on_terms_page
click_button 'Accept terms'
- expect(current_path).to eq(profile_path)
+ expect(page).to have_current_path(profile_path, ignore_query: true)
fill_in 'Email', with: 'hello@world.com'
@@ -931,7 +932,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
gitlab_sign_in(user)
- expect(current_path).to eq root_path
+ expect(page).to have_current_path root_path, ignore_query: true
expect(page).to have_content("Please check your email (#{user.email}) to verify that you own this address and unlock the power of CI/CD.")
end
@@ -944,7 +945,7 @@ RSpec.describe 'Login', :clean_gitlab_redis_sessions do
gitlab_sign_in(user)
- expect(current_path).to eq new_user_session_path
+ expect(page).to have_current_path new_user_session_path, ignore_query: true
expect(page).to have_content(alert_title)
expect(page).to have_content(alert_message)
expect(page).to have_link('Resend confirmation email', href: new_user_confirmation_path)
diff --git a/spec/features/users/logout_spec.rb b/spec/features/users/logout_spec.rb
index 3129eb5e6f3..596f0dd5a94 100644
--- a/spec/features/users/logout_spec.rb
+++ b/spec/features/users/logout_spec.rb
@@ -13,7 +13,7 @@ RSpec.describe 'Logout/Sign out', :js do
it 'sign out redirects to sign in page' do
gitlab_sign_out
- expect(current_path).to eq new_user_session_path
+ expect(page).to have_current_path new_user_session_path, ignore_query: true
end
it 'sign out does not show signed out flash notice' do
@@ -30,7 +30,7 @@ RSpec.describe 'Logout/Sign out', :js do
it 'sign out redirects to sign in page' do
gitlab_sign_out
- expect(current_path).to eq new_user_session_path
+ expect(page).to have_current_path new_user_session_path, ignore_query: true
end
end
end
diff --git a/spec/features/users/show_spec.rb b/spec/features/users/show_spec.rb
index 8edbf639c81..cb395846b96 100644
--- a/spec/features/users/show_spec.rb
+++ b/spec/features/users/show_spec.rb
@@ -426,7 +426,7 @@ RSpec.describe 'User page' do
end
context 'structured markup' do
- let_it_be(:user) { create(:user, website_url: 'https://gitlab.com', organization: 'GitLab', job_title: 'Frontend Engineer', email: 'public@example.com', public_email: 'public@example.com', location: 'Country', created_at: Time.now, updated_at: Time.now) }
+ let_it_be(:user) { create(:user, website_url: 'https://gitlab.com', organization: 'GitLab', job_title: 'Frontend Engineer', email: 'public@example.com', public_email: 'public@example.com', location: 'Country', created_at: Time.zone.now, updated_at: Time.zone.now) }
it 'shows Person structured markup' do
subject
diff --git a/spec/features/users/signup_spec.rb b/spec/features/users/signup_spec.rb
index a651a6c09c6..3eae4955167 100644
--- a/spec/features/users/signup_spec.rb
+++ b/spec/features/users/signup_spec.rb
@@ -203,7 +203,7 @@ RSpec.describe 'Signup' do
fill_in_signup_form
expect { click_button 'Register' }.to change { User.count }.by(1)
- expect(current_path).to eq users_almost_there_path
+ expect(page).to have_current_path users_almost_there_path, ignore_query: true
expect(page).to have_content("Please check your email (#{new_user.email}) to confirm your account")
confirm_email
@@ -223,7 +223,7 @@ RSpec.describe 'Signup' do
fill_in_signup_form
expect { click_button 'Register' }.to change { User.count }.by(1)
- expect(current_path).to eq users_sign_up_welcome_path
+ expect(page).to have_current_path users_sign_up_welcome_path, ignore_query: true
end
end
end
@@ -239,7 +239,7 @@ RSpec.describe 'Signup' do
fill_in_signup_form
click_button "Register"
- expect(current_path).to eq users_sign_up_welcome_path
+ expect(page).to have_current_path users_sign_up_welcome_path, ignore_query: true
end
end
@@ -254,7 +254,7 @@ RSpec.describe 'Signup' do
fill_in_signup_form
expect { click_button 'Register' }.to change { User.count }.by(1)
- expect(current_path).to eq new_user_session_path
+ expect(page).to have_current_path new_user_session_path, ignore_query: true
expect(page).to have_content("You have signed up successfully. However, we could not sign you in because your account is awaiting approval from your GitLab administrator")
end
end
@@ -268,7 +268,7 @@ RSpec.describe 'Signup' do
fill_in_signup_form
click_button "Register"
- expect(current_path).to eq user_registration_path
+ expect(page).to have_current_path user_registration_path, ignore_query: true
expect(page).to have_content("error prohibited this user from being saved")
expect(page).to have_content("Email has already been taken")
end
@@ -280,7 +280,7 @@ RSpec.describe 'Signup' do
fill_in_signup_form
click_button "Register"
- expect(current_path).to eq user_registration_path
+ expect(page).to have_current_path user_registration_path, ignore_query: true
expect(page.body).not_to match(/#{new_user.password}/)
end
end
@@ -298,7 +298,7 @@ RSpec.describe 'Signup' do
fill_in_signup_form
click_button 'Register'
- expect(current_path).to eq users_sign_up_welcome_path
+ expect(page).to have_current_path users_sign_up_welcome_path, ignore_query: true
end
end
@@ -324,7 +324,7 @@ RSpec.describe 'Signup' do
fill_in_signup_form
expect { click_button 'Register' }.not_to change { User.count }
- expect(page).to have_content('There was an error with the reCAPTCHA. Please solve the reCAPTCHA again.')
+ expect(page).to have_content(_('There was an error with the reCAPTCHA. Please solve the reCAPTCHA again.'))
end
end
diff --git a/spec/features/users/terms_spec.rb b/spec/features/users/terms_spec.rb
index 7cfe74f8aa9..7a662d24d60 100644
--- a/spec/features/users/terms_spec.rb
+++ b/spec/features/users/terms_spec.rb
@@ -82,7 +82,7 @@ RSpec.describe 'Users > Terms', :js do
click_link 'Continue'
- expect(current_path).to eq(root_path)
+ expect(page).to have_current_path(root_path, ignore_query: true)
end
end
@@ -99,7 +99,7 @@ RSpec.describe 'Users > Terms', :js do
enforce_terms
# Application settings are cached for a minute
- Timecop.travel 2.minutes do
+ travel_to 2.minutes.from_now do
within('.nav-sidebar') do
click_link 'Issues'
end
@@ -108,7 +108,7 @@ RSpec.describe 'Users > Terms', :js do
click_button('Accept terms')
- expect(current_path).to eq(project_issues_path(project))
+ expect(page).to have_current_path(project_issues_path(project), ignore_query: true)
end
end
@@ -123,11 +123,11 @@ RSpec.describe 'Users > Terms', :js do
click_button 'Create issue'
- expect(current_path).to eq(terms_path)
+ expect(page).to have_current_path(terms_path, ignore_query: true)
click_button('Accept terms')
- expect(current_path).to eq(new_project_issue_path(project))
+ expect(page).to have_current_path(new_project_issue_path(project), ignore_query: true)
expect(find_field('issue_title').value).to eq('Hello world, a new issue')
expect(find_field('issue_description').value).to eq("We don't want to lose what the user typed")
end
diff --git a/spec/finders/issues_finder_spec.rb b/spec/finders/issues_finder_spec.rb
index c22e56c3b9e..aa9357a686a 100644
--- a/spec/finders/issues_finder_spec.rb
+++ b/spec/finders/issues_finder_spec.rb
@@ -588,10 +588,37 @@ RSpec.describe IssuesFinder do
end
context 'filtering by issue term' do
- let(:params) { { search: 'git' } }
+ let(:params) { { search: search_term } }
- it 'returns issues with title and description match for search term' do
- expect(issues).to contain_exactly(issue1, issue2)
+ let_it_be(:english) { create(:issue, project: project1, title: 'title', description: 'something english') }
+ let_it_be(:japanese) { create(:issue, project: project1, title: '日本語 title', description: 'another english description') }
+
+ context 'with latin search term' do
+ let(:search_term) { 'title english' }
+
+ it 'returns matching issues' do
+ expect(issues).to contain_exactly(english, japanese)
+ end
+ end
+
+ context 'with non-latin search term' do
+ let(:search_term) { '日本語' }
+
+ it 'returns matching issues' do
+ expect(issues).to contain_exactly(japanese)
+ end
+ end
+
+ context 'when full-text search is disabled' do
+ let(:search_term) { 'somet' }
+
+ before do
+ stub_feature_flags(issues_full_text_search: false)
+ end
+
+ it 'allows partial word matches' do
+ expect(issues).to contain_exactly(english)
+ end
end
context 'with anonymous user' do
@@ -1257,7 +1284,7 @@ RSpec.describe IssuesFinder do
end
context 'when the force_cte param is falsey' do
- let(:params) { { search: 'foo' } }
+ let(:params) { { search: '日本語' } }
it 'returns false' do
expect(finder.use_cte_for_search?).to be_falsey
@@ -1265,7 +1292,7 @@ RSpec.describe IssuesFinder do
end
context 'when a non-simple sort is given' do
- let(:params) { { search: 'foo', attempt_project_search_optimizations: true, sort: 'popularity' } }
+ let(:params) { { search: '日本語', attempt_project_search_optimizations: true, sort: 'popularity' } }
it 'returns false' do
expect(finder.use_cte_for_search?).to be_falsey
@@ -1274,7 +1301,7 @@ RSpec.describe IssuesFinder do
context 'when all conditions are met' do
context "uses group search optimization" do
- let(:params) { { search: 'foo', attempt_group_search_optimizations: true } }
+ let(:params) { { search: '日本語', attempt_group_search_optimizations: true } }
it 'returns true' do
expect(finder.use_cte_for_search?).to be_truthy
@@ -1283,7 +1310,7 @@ RSpec.describe IssuesFinder do
end
context "uses project search optimization" do
- let(:params) { { search: 'foo', attempt_project_search_optimizations: true } }
+ let(:params) { { search: '日本語', attempt_project_search_optimizations: true } }
it 'returns true' do
expect(finder.use_cte_for_search?).to be_truthy
@@ -1292,7 +1319,7 @@ RSpec.describe IssuesFinder do
end
context 'with simple sort' do
- let(:params) { { search: 'foo', attempt_project_search_optimizations: true, sort: 'updated_desc' } }
+ let(:params) { { search: '日本語', attempt_project_search_optimizations: true, sort: 'updated_desc' } }
it 'returns true' do
expect(finder.use_cte_for_search?).to be_truthy
@@ -1301,7 +1328,7 @@ RSpec.describe IssuesFinder do
end
context 'with simple sort as a symbol' do
- let(:params) { { search: 'foo', attempt_project_search_optimizations: true, sort: :updated_desc } }
+ let(:params) { { search: '日本語', attempt_project_search_optimizations: true, sort: :updated_desc } }
it 'returns true' do
expect(finder.use_cte_for_search?).to be_truthy
diff --git a/spec/finders/pending_todos_finder_spec.rb b/spec/finders/pending_todos_finder_spec.rb
index f317d8b1633..4f4862852f4 100644
--- a/spec/finders/pending_todos_finder_spec.rb
+++ b/spec/finders/pending_todos_finder_spec.rb
@@ -75,5 +75,15 @@ RSpec.describe PendingTodosFinder do
expect(todos).to contain_exactly(todo1, todo2)
end
+
+ it 'supports retrieving of todos for a specific action' do
+ todo = create(:todo, :pending, user: user, target: issue, action: Todo::MENTIONED)
+
+ create(:todo, :pending, user: user, target: issue, action: Todo::ASSIGNED)
+
+ todos = described_class.new(users, action: Todo::MENTIONED).execute
+
+ expect(todos).to contain_exactly(todo)
+ end
end
end
diff --git a/spec/finders/personal_access_tokens_finder_spec.rb b/spec/finders/personal_access_tokens_finder_spec.rb
index cece80047e1..7607d08dc64 100644
--- a/spec/finders/personal_access_tokens_finder_spec.rb
+++ b/spec/finders/personal_access_tokens_finder_spec.rb
@@ -17,6 +17,9 @@ RSpec.describe PersonalAccessTokensFinder do
let!(:active_impersonation_token) { create(:personal_access_token, :impersonation, user: user) }
let!(:expired_impersonation_token) { create(:personal_access_token, :expired, :impersonation, user: user) }
let!(:revoked_impersonation_token) { create(:personal_access_token, :revoked, :impersonation, user: user) }
+ let!(:project_bot) { create(:user, :project_bot) }
+ let!(:project_member) { create(:project_member, user: project_bot) }
+ let!(:project_access_token) { create(:personal_access_token, user: project_bot) }
subject { finder(params, current_user).execute }
@@ -44,7 +47,7 @@ RSpec.describe PersonalAccessTokensFinder do
it do
is_expected.to contain_exactly(active_personal_access_token, active_impersonation_token,
revoked_personal_access_token, expired_personal_access_token,
- revoked_impersonation_token, expired_impersonation_token)
+ revoked_impersonation_token, expired_impersonation_token, project_access_token)
end
context 'when current_user is not an administrator' do
@@ -59,7 +62,7 @@ RSpec.describe PersonalAccessTokensFinder do
it do
is_expected.to contain_exactly(active_personal_access_token, active_impersonation_token,
revoked_personal_access_token, expired_personal_access_token,
- revoked_impersonation_token, expired_impersonation_token)
+ revoked_impersonation_token, expired_impersonation_token, project_access_token)
end
describe 'with users' do
@@ -98,14 +101,14 @@ RSpec.describe PersonalAccessTokensFinder do
params[:impersonation] = false
end
- it { is_expected.to contain_exactly(active_personal_access_token, revoked_personal_access_token, expired_personal_access_token) }
+ it { is_expected.to contain_exactly(active_personal_access_token, revoked_personal_access_token, expired_personal_access_token, project_access_token) }
describe 'with active state' do
before do
params[:state] = 'active'
end
- it { is_expected.to contain_exactly(active_personal_access_token) }
+ it { is_expected.to contain_exactly(active_personal_access_token, project_access_token) }
end
describe 'with inactive state' do
@@ -146,7 +149,7 @@ RSpec.describe PersonalAccessTokensFinder do
params[:state] = 'active'
end
- it { is_expected.to contain_exactly(active_personal_access_token, active_impersonation_token) }
+ it { is_expected.to contain_exactly(active_personal_access_token, active_impersonation_token, project_access_token) }
end
describe 'with inactive state' do
@@ -208,6 +211,14 @@ RSpec.describe PersonalAccessTokensFinder do
revoked_impersonation_token, expired_impersonation_token)
end
+ describe 'filtering human tokens' do
+ before do
+ params[:owner_type] = 'human'
+ end
+
+ it { is_expected.not_to include(project_access_token) }
+ end
+
describe 'without impersonation' do
before do
params[:impersonation] = false
diff --git a/spec/finders/projects/members/effective_access_level_finder_spec.rb b/spec/finders/projects/members/effective_access_level_finder_spec.rb
index 33fbb5aca30..bec327835f6 100644
--- a/spec/finders/projects/members/effective_access_level_finder_spec.rb
+++ b/spec/finders/projects/members/effective_access_level_finder_spec.rb
@@ -11,13 +11,13 @@ RSpec.describe Projects::Members::EffectiveAccessLevelFinder, '#execute' do
context 'for a personal project' do
let_it_be(:project) { create(:project) }
- shared_examples_for 'includes access level of the owner of the project as Maintainer' do
- it 'includes access level of the owner of the project as Maintainer' do
+ shared_examples_for 'includes access level of the owner of the project' do
+ it 'includes access level of the owner of the project as Owner' do
expect(subject).to(
contain_exactly(
hash_including(
'user_id' => project.namespace.owner.id,
- 'access_level' => Gitlab::Access::MAINTAINER
+ 'access_level' => Gitlab::Access::OWNER
)
)
)
@@ -25,7 +25,7 @@ RSpec.describe Projects::Members::EffectiveAccessLevelFinder, '#execute' do
end
context 'when the project owner is a member of the project' do
- it_behaves_like 'includes access level of the owner of the project as Maintainer'
+ it_behaves_like 'includes access level of the owner of the project'
end
context 'when the project owner is not explicitly a member of the project' do
@@ -33,7 +33,7 @@ RSpec.describe Projects::Members::EffectiveAccessLevelFinder, '#execute' do
project.members.find_by(user_id: project.namespace.owner.id).destroy!
end
- it_behaves_like 'includes access level of the owner of the project as Maintainer'
+ it_behaves_like 'includes access level of the owner of the project'
end
end
@@ -84,17 +84,32 @@ RSpec.describe Projects::Members::EffectiveAccessLevelFinder, '#execute' do
context 'for a project within a group' do
context 'project in a root group' do
- it 'includes access levels of users who are direct members of the parent group' do
- group_member = create(:group_member, :developer, source: group)
+ context 'includes access levels of users who are direct members of the parent group' do
+ it 'when access level is developer' do
+ group_member = create(:group_member, :developer, source: group)
- expect(subject).to(
- include(
- hash_including(
- 'user_id' => group_member.user.id,
- 'access_level' => Gitlab::Access::DEVELOPER
+ expect(subject).to(
+ include(
+ hash_including(
+ 'user_id' => group_member.user.id,
+ 'access_level' => Gitlab::Access::DEVELOPER
+ )
)
)
- )
+ end
+
+ it 'when access level is owner' do
+ group_member = create(:group_member, :owner, source: group)
+
+ expect(subject).to(
+ include(
+ hash_including(
+ 'user_id' => group_member.user.id,
+ 'access_level' => Gitlab::Access::OWNER
+ )
+ )
+ )
+ end
end
end
diff --git a/spec/finders/projects/topics_finder_spec.rb b/spec/finders/projects/topics_finder_spec.rb
index 28802c5d49e..3812f0757bc 100644
--- a/spec/finders/projects/topics_finder_spec.rb
+++ b/spec/finders/projects/topics_finder_spec.rb
@@ -9,9 +9,9 @@ RSpec.describe Projects::TopicsFinder do
let!(:topic2) { create(:topic, name: 'topicC') }
let!(:topic3) { create(:topic, name: 'topicA') }
- let!(:project1) { create(:project, namespace: user.namespace, topic_list: 'topicC, topicA, topicB') }
- let!(:project2) { create(:project, namespace: user.namespace, topic_list: 'topicC, topicA') }
- let!(:project3) { create(:project, namespace: user.namespace, topic_list: 'topicC') }
+ let!(:project1) { create(:project, :public, namespace: user.namespace, topic_list: 'topicC, topicA, topicB') }
+ let!(:project2) { create(:project, :public, namespace: user.namespace, topic_list: 'topicC, topicA') }
+ let!(:project3) { create(:project, :public, namespace: user.namespace, topic_list: 'topicC') }
describe '#execute' do
it 'returns topics' do
diff --git a/spec/finders/releases/group_releases_finder_spec.rb b/spec/finders/releases/group_releases_finder_spec.rb
new file mode 100644
index 00000000000..b8899a8ee40
--- /dev/null
+++ b/spec/finders/releases/group_releases_finder_spec.rb
@@ -0,0 +1,204 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Releases::GroupReleasesFinder do
+ let(:user) { create(:user) }
+ let(:group) { create(:group) }
+ let(:project) { create(:project, :repository, group: group) }
+ let(:params) { {} }
+ let(:args) { {} }
+ let(:repository) { project.repository }
+ let(:v1_0_0) { create(:release, project: project, tag: 'v1.0.0') }
+ let(:v1_1_0) { create(:release, project: project, tag: 'v1.1.0') }
+ let(:v1_1_1) { create(:release, project: project, tag: 'v1.1.1') }
+
+ before do
+ v1_0_0.update_attribute(:released_at, 2.days.ago)
+ v1_1_0.update_attribute(:released_at, 1.day.ago)
+ v1_1_1.update_attribute(:released_at, 0.5.days.ago)
+ end
+
+ shared_examples_for 'when the user is not part of the project' do
+ it 'returns no releases' do
+ is_expected.to be_empty
+ end
+ end
+
+ shared_examples_for 'when the user is not part of the group' do
+ before do
+ allow(Ability).to receive(:allowed?).with(user, :read_release, group).and_return(false)
+ end
+
+ it 'returns no releases' do
+ is_expected.to be_empty
+ end
+ end
+
+ shared_examples_for 'preload' do
+ before do
+ allow(Ability).to receive(:allowed?).with(user, :read_release, group).and_return(true)
+ end
+
+ it 'preloads associations' do
+ expect(Release).to receive(:preloaded).once.and_call_original
+
+ releases
+ end
+
+ context 'when preload is false' do
+ let(:args) { { preload: false } }
+
+ it 'does not preload associations' do
+ expect(Release).not_to receive(:preloaded)
+
+ releases
+ end
+ end
+ end
+
+ describe 'when parent is a group' do
+ context 'without subgroups' do
+ let(:project2) { create(:project, :repository, namespace: group) }
+ let!(:v6) { create(:release, project: project2, tag: 'v6') }
+
+ subject(:releases) { described_class.new(group, user, params).execute(**args) }
+
+ it_behaves_like 'preload'
+ it_behaves_like 'when the user is not part of the group'
+
+ context 'when the user is a project guest on one sibling project' do
+ before do
+ project.add_guest(user)
+ end
+
+ it 'does not return any releases' do
+ expect(releases.size).to eq(0)
+ expect(releases).to eq([])
+ end
+ end
+
+ context 'when the user is a guest on the group' do
+ before do
+ group.add_guest(user)
+ v1_0_0.update_attribute(:released_at, 3.days.ago)
+ v6.update_attribute(:released_at, 2.days.ago)
+ v1_1_0.update_attribute(:released_at, 1.day.ago)
+ v1_1_1.update_attribute(:released_at, v1_1_0.released_at)
+ end
+
+ it 'sorts by release date and id' do
+ expect(releases.size).to eq(4)
+ expect(releases).to eq([v1_1_1, v1_1_0, v6, v1_0_0])
+ end
+ end
+ end
+
+ describe 'with subgroups' do
+ let(:params) { { include_subgroups: true } }
+
+ subject(:releases) { described_class.new(group, user, params).execute(**args) }
+
+ context 'with a single-level subgroup' do
+ let(:subgroup) { create(:group, parent: group) }
+ let(:project2) { create(:project, :repository, namespace: subgroup) }
+ let!(:v6) { create(:release, project: project2, tag: 'v6') }
+
+ it_behaves_like 'when the user is not part of the group'
+
+ context 'when the user a project guest in the subgroup project' do
+ before do
+ project2.add_guest(user)
+ end
+
+ it 'does not return any releases' do
+ expect(releases).to match_array([])
+ end
+ end
+
+ context 'when the user is a guest on the group' do
+ before do
+ group.add_guest(user)
+ v6.update_attribute(:released_at, 2.days.ago)
+ end
+
+ it 'returns all releases' do
+ expect(releases).to match_array([v1_1_1, v1_1_0, v1_0_0, v6])
+ end
+ end
+ end
+
+ context 'with a multi-level subgroup' do
+ let(:subgroup) { create(:group, parent: group) }
+ let(:subsubgroup) { create(:group, parent: subgroup) }
+ let(:project2) { create(:project, :repository, namespace: subgroup) }
+ let(:project3) { create(:project, :repository, namespace: subsubgroup) }
+ let!(:v6) { create(:release, project: project2, tag: 'v6') }
+ let!(:p3) { create(:release, project: project3, tag: 'p3') }
+
+ before do
+ v6.update_attribute(:released_at, 2.days.ago)
+ p3.update_attribute(:released_at, 3.days.ago)
+ end
+
+ it_behaves_like 'when the user is not part of the group'
+
+ context 'when the user a project guest in the subgroup and subsubgroup project' do
+ before do
+ project2.add_guest(user)
+ project3.add_guest(user)
+ end
+
+ it 'does not return any releases' do
+ expect(releases).to match_array([])
+ end
+ end
+
+ context 'when the user a project guest in the subsubgroup project' do
+ before do
+ project3.add_guest(user)
+ end
+
+ it 'does not return any releases' do
+ expect(releases).to match_array([])
+ end
+ end
+
+ context 'when the user a guest on the group' do
+ before do
+ group.add_guest(user)
+ end
+
+ it 'returns all releases' do
+ expect(releases).to match_array([v1_1_1, v1_1_0, v6, v1_0_0, p3])
+ end
+ end
+
+ context 'performance testing' do
+ shared_examples 'avoids N+1 queries' do |query_params = {}|
+ context 'with subgroups' do
+ let(:params) { query_params }
+
+ it 'include_subgroups avoids N+1 queries' do
+ control_count = ActiveRecord::QueryRecorder.new(skip_cached: false) do
+ releases
+ end.count
+
+ subgroups = create_list(:group, 10, parent: group)
+ projects = create_list(:project, 10, namespace: subgroups[0])
+ create_list(:release, 10, project: projects[0], author: user)
+
+ expect do
+ releases
+ end.not_to exceed_all_query_limit(control_count)
+ end
+ end
+ end
+
+ it_behaves_like 'avoids N+1 queries'
+ it_behaves_like 'avoids N+1 queries', { simple: true }
+ end
+ end
+ end
+ end
+end
diff --git a/spec/finders/releases_finder_spec.rb b/spec/finders/releases_finder_spec.rb
index 5ddb5c33fad..b0fa1177245 100644
--- a/spec/finders/releases_finder_spec.rb
+++ b/spec/finders/releases_finder_spec.rb
@@ -33,18 +33,6 @@ RSpec.describe ReleasesFinder do
end
end
- # See https://gitlab.com/gitlab-org/gitlab/-/merge_requests/27716
- shared_examples_for 'when tag is nil' do
- before do
- v1_0_0.update_column(:tag, nil)
- end
-
- it 'ignores rows with a nil tag' do
- expect(subject.size).to eq(1)
- expect(subject).to eq([v1_1_0])
- end
- end
-
shared_examples_for 'when a tag parameter is passed' do
let(:params) { { tag: 'v1.0.0' } }
@@ -116,7 +104,6 @@ RSpec.describe ReleasesFinder do
end
it_behaves_like 'preload'
- it_behaves_like 'when tag is nil'
it_behaves_like 'when a tag parameter is passed'
end
end
diff --git a/spec/fixtures/api/schemas/deployment.json b/spec/fixtures/api/schemas/deployment.json
index fa34a61c7d3..7d96147314c 100644
--- a/spec/fixtures/api/schemas/deployment.json
+++ b/spec/fixtures/api/schemas/deployment.json
@@ -64,6 +64,5 @@
"items": { "$ref": "job/job.json" }
},
"status": { "type": "string" }
- },
- "additionalProperties": false
+ }
}
diff --git a/spec/fixtures/api/schemas/environment.json b/spec/fixtures/api/schemas/environment.json
index 4f54a77e6b2..87b6e5da370 100644
--- a/spec/fixtures/api/schemas/environment.json
+++ b/spec/fixtures/api/schemas/environment.json
@@ -35,6 +35,8 @@
"auto_stop_at": { "type": "string", "format": "date-time" },
"can_stop": { "type": "boolean" },
"has_opened_alert": { "type": "boolean" },
+ "tier": { "type": "string" },
+ "required_approval_count": { "type": "integer" },
"cluster_type": { "type": "types/nullable_string.json" },
"terminal_path": { "type": "types/nullable_string.json" },
"rollout_status": {
diff --git a/spec/fixtures/api/schemas/list.json b/spec/fixtures/api/schemas/list.json
index 65e140f9e28..0985874a500 100644
--- a/spec/fixtures/api/schemas/list.json
+++ b/spec/fixtures/api/schemas/list.json
@@ -34,7 +34,7 @@
"priority": { "type": ["integer", "null"] }
}
},
- "title": { "type": "string" },
+ "title": { "type": ["string", "null"] },
"position": { "type": ["integer", "null"] },
"max_issue_count": { "type": "integer" },
"max_issue_weight": { "type": "integer" },
diff --git a/spec/fixtures/api/schemas/public_api/v4/deploy_token.json b/spec/fixtures/api/schemas/public_api/v4/deploy_token.json
index c4d3f944aea..102ab95a4ee 100644
--- a/spec/fixtures/api/schemas/public_api/v4/deploy_token.json
+++ b/spec/fixtures/api/schemas/public_api/v4/deploy_token.json
@@ -5,7 +5,9 @@
"name",
"username",
"expires_at",
- "scopes"
+ "scopes",
+ "revoked",
+ "expired"
],
"properties": {
"id": {
@@ -26,6 +28,12 @@
},
"token": {
"type": "string"
+ },
+ "revoked": {
+ "type": "boolean"
+ },
+ "expired": {
+ "type": "boolean"
}
}
} \ No newline at end of file
diff --git a/spec/fixtures/api/schemas/public_api/v4/system_hook.json b/spec/fixtures/api/schemas/public_api/v4/system_hook.json
new file mode 100644
index 00000000000..f992bc8b809
--- /dev/null
+++ b/spec/fixtures/api/schemas/public_api/v4/system_hook.json
@@ -0,0 +1,24 @@
+{
+ "type": "object",
+ "required": [
+ "id",
+ "url",
+ "created_at",
+ "push_events",
+ "tag_push_events",
+ "merge_requests_events",
+ "repository_update_events",
+ "enable_ssl_verification"
+ ],
+ "properties": {
+ "id": { "type": "integer" },
+ "url": { "type": "string" },
+ "created_at": { "type": "string" },
+ "push_events": { "type": "boolean" },
+ "tag_push_events": { "type": "boolean" },
+ "merge_requests_events": { "type": "boolean" },
+ "repository_update_events": { "type": "boolean" },
+ "enable_ssl_verification": { "type": "boolean" }
+ },
+ "additionalProperties": false
+}
diff --git a/spec/fixtures/api/schemas/public_api/v4/system_hooks.json b/spec/fixtures/api/schemas/public_api/v4/system_hooks.json
new file mode 100644
index 00000000000..a56542a8b99
--- /dev/null
+++ b/spec/fixtures/api/schemas/public_api/v4/system_hooks.json
@@ -0,0 +1,9 @@
+{
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties" : {
+ "$ref": "./system_hook.json"
+ }
+ }
+}
diff --git a/spec/fixtures/emails/missing_delivered_to_header.eml b/spec/fixtures/emails/missing_delivered_to_header.eml
new file mode 100644
index 00000000000..511f60ab719
--- /dev/null
+++ b/spec/fixtures/emails/missing_delivered_to_header.eml
@@ -0,0 +1,35 @@
+Return-Path: <jake@example.com>
+Received: from myserver.example.com ([unix socket]) by myserver (Cyrus v2.2.13-Debian-2.2.13-19+squeeze3) with LMTPA; Thu, 13 Jun 2013 17:03:50 -0400
+Received: by 10.0.0.1 with HTTP; Thu, 13 Jun 2013 14:03:48 -0700
+Received: from blabla.google.com (blabla.google.com. [1.1.1.1])
+ by bla.google.com with SMTPS id something.1.1.1.1.1.1.1
+ for <incoming+gitlabhq/gitlabhq+auth_token@appmail.example.com>
+ (Google Transport Security);
+ Mon, 21 Feb 2022 14:41:58 -0800 (PST)
+Received: from mail.example.com (mail.example.com [IPv6:2607:f8b0:4001:c03::234]) by myserver.example.com (8.14.3/8.14.3/Debian-9.4) with ESMTP id r5DL3nFJ016967 (version=TLSv1/SSLv3 cipher=RC4-SHA bits=128 verify=NOT) for <incoming+gitlabhq/gitlabhq@example.com>; Thu, 13 Jun 2013 17:03:50 -0400
+From: "jake@example.com" <jake@example.com>
+To: "support@example.com" <support@example.com>
+Subject: Insert hilarious subject line here
+Date: Tue, 26 Nov 2019 14:22:41 +0000
+Message-ID: <7e2296f83dbf4de388cbf5f56f52c11f@EXDAG29-1.EXCHANGE.INT>
+Accept-Language: de-DE, en-US
+Content-Language: de-DE
+X-MS-Has-Attach:
+X-MS-TNEF-Correlator:
+x-ms-exchange-transport-fromentityheader: Hosted
+x-originating-ip: [62.96.54.178]
+Content-Type: multipart/alternative;
+ boundary="_000_7e2296f83dbf4de388cbf5f56f52c11fEXDAG291EXCHANGEINT_"
+MIME-Version: 1.0
+
+--_000_7e2296f83dbf4de388cbf5f56f52c11fEXDAG291EXCHANGEINT_
+Content-Type: text/plain; charset="iso-8859-1"
+Content-Transfer-Encoding: quoted-printable
+
+
+
+--_000_7e2296f83dbf4de388cbf5f56f52c11fEXDAG291EXCHANGEINT_
+Content-Type: text/html; charset="iso-8859-1"
+Content-Transfer-Encoding: quoted-printable
+
+Look, a message with no Delivered-To header! Let's fallback to Received: in case it's there.
diff --git a/spec/fixtures/emails/service_desk_reply_to_and_from.eml b/spec/fixtures/emails/service_desk_reply_to_and_from.eml
new file mode 100644
index 00000000000..2545e0d30f8
--- /dev/null
+++ b/spec/fixtures/emails/service_desk_reply_to_and_from.eml
@@ -0,0 +1,28 @@
+Delivered-To: incoming+email-test-project_id-issue-@appmail.adventuretime.ooo
+Return-Path: <jake@adventuretime.ooo>
+Received: from iceking.adventuretime.ooo ([unix socket]) by iceking (Cyrus v2.2.13-Debian-2.2.13-19+squeeze3) with LMTPA; Thu, 13 Jun 2013 17:03:50 -0400
+Received: from mail-ie0-x234.google.com (mail-ie0-x234.google.com [IPv6:2607:f8b0:4001:c03::234]) by iceking.adventuretime.ooo (8.14.3/8.14.3/Debian-9.4) with ESMTP id r5DL3nFJ016967 (version=TLSv1/SSLv3 cipher=RC4-SHA bits=128 verify=NOT) for <incoming+gitlabhq/gitlabhq@appmail.adventuretime.ooo>; Thu, 13 Jun 2013 17:03:50 -0400
+Received: by mail-ie0-f180.google.com with SMTP id f4so21977375iea.25 for <incoming+email-test-project_id-issue-@appmail.adventuretime.ooo>; Thu, 13 Jun 2013 14:03:48 -0700
+Received: by 10.0.0.1 with HTTP; Thu, 13 Jun 2013 14:03:48 -0700
+Date: Thu, 13 Jun 2013 17:03:48 -0400
+Reply-To: Marceline <marceline@adventuretime.ooo>
+From: Finn the Human <finn@adventuretime.ooo>
+Sender: Jake the Dog <jake@adventuretime.ooo>
+To: support@adventuretime.ooo
+Delivered-To: support@adventuretime.ooo
+Message-ID: <CADkmRc+rNGAGGbV2iE5p918UVy4UyJqVcXRO2=otppgzduJSg@mail.gmail.com>
+Subject: The message subject! @all
+Mime-Version: 1.0
+Content-Type: text/plain;
+ charset=ISO-8859-1
+Content-Transfer-Encoding: 7bit
+X-Sieve: CMU Sieve 2.2
+X-Received: by 10.0.0.1 with SMTP id n7mr11234144ipb.85.1371157428600; Thu,
+ 13 Jun 2013 14:03:48 -0700 (PDT)
+X-Scanned-By: MIMEDefang 2.69 on IPv6:2001:470:1d:165::1
+
+Service desk stuff!
+
+```
+a = b
+```
diff --git a/spec/fixtures/emails/valid_note_on_issuable.eml b/spec/fixtures/emails/valid_note_on_issuable.eml
index 29308c9d969..38b733b6a32 100644
--- a/spec/fixtures/emails/valid_note_on_issuable.eml
+++ b/spec/fixtures/emails/valid_note_on_issuable.eml
@@ -1,6 +1,6 @@
Return-Path: <jake@adventuretime.ooo>
Received: from iceking.adventuretime.ooo ([unix socket]) by iceking (Cyrus v2.2.13-Debian-2.2.13-19+squeeze3) with LMTPA; Thu, 13 Jun 2013 17:03:50 -0400
-Received: from mail-ie0-x234.google.com (mail-ie0-x234.google.com [IPv6:2607:f8b0:4001:c03::234]) by iceking.adventuretime.ooo (8.14.3/8.14.3/Debian-9.4) with ESMTP id r5DL3nFJ016967 (version=TLSv1/SSLv3 cipher=RC4-SHA bits=128 verify=NOT) for <incoming+gitlabhq/gitlabhq@appmail.adventuretime.ooo>; Thu, 13 Jun 2013 17:03:50 -0400
+Received: from mail-ie0-x234.google.com (mail-ie0-x234.google.com [IPv6:2607:f8b0:4001:c03::234]) by iceking.adventuretime.ooo (8.14.3/8.14.3/Debian-9.4) with ESMTP id r5DL3nFJ016967 (version=TLSv1/SSLv3 cipher=RC4-SHA bits=128 verify=NOT) for <incoming+gitlabhq-gitlabhq-project_id-auth_token-issue-issue_iid@appmail.adventuretime.ooo>; Thu, 13 Jun 2013 17:03:50 -0400
Received: by mail-ie0-f180.google.com with SMTP id f4so21977375iea.25 for <incoming+gitlabhq-gitlabhq-project_id-auth_token-issue-issue_iid@appmail.adventuretime.ooo>; Thu, 13 Jun 2013 14:03:48 -0700
Received: by 10.0.0.1 with HTTP; Thu, 13 Jun 2013 14:03:48 -0700
Date: Thu, 13 Jun 2013 17:03:48 -0400
diff --git a/spec/fixtures/error_tracking/php_empty_transaction.json b/spec/fixtures/error_tracking/php_empty_transaction.json
new file mode 100644
index 00000000000..fc51894145d
--- /dev/null
+++ b/spec/fixtures/error_tracking/php_empty_transaction.json
@@ -0,0 +1,45 @@
+{
+ "event_id": "dquJXuPF9sP1fMy5RpKo979xUALjNDQB",
+ "timestamp": 1645191605.123456,
+ "platform": "php",
+ "sdk": {
+ "name": "sentry.php",
+ "version": "3.3.7"
+ },
+ "logger": "php",
+ "transaction": "",
+ "server_name": "oAjA5zTgIjqP",
+ "release": "C0FFEE",
+ "environment": "Development/Berlin",
+ "exception": {
+ "values": [
+ {
+ "type": "TestException",
+ "value": "Sentry test exception",
+ "stacktrace": {
+ "frames": [
+ {
+ "filename": "/src/Path/To/Class.php",
+ "lineno": 3,
+ "in_app": true,
+ "abs_path": "/var/www/html/src/Path/To/Class.php",
+ "function": "Path\\To\\Class::method",
+ "raw_function": "Path\\To\\Class::method",
+ "pre_context": [
+ "// Pre-context"
+ ],
+ "context_line": "throw new TestException('Sentry test exception');",
+ "post_context": [
+ "// Post-context"
+ ]
+ }
+ ]
+ },
+ "mechanism": {
+ "type": "generic",
+ "handled": true
+ }
+ }
+ ]
+ }
+}
diff --git a/spec/fixtures/markdown/markdown_golden_master_examples.yml b/spec/fixtures/markdown/markdown_golden_master_examples.yml
index b024064dc21..8556811974d 100644
--- a/spec/fixtures/markdown/markdown_golden_master_examples.yml
+++ b/spec/fixtures/markdown/markdown_golden_master_examples.yml
@@ -218,13 +218,13 @@
</ol>
<ul data-sourcepos="7:1-9:47" class="task-list" dir="auto">
<li data-sourcepos="7:1-7:47" class="task-list-item">
- <input type="checkbox" class="task-list-item-checkbox" checked disabled> <span class="media-container audio-container"><audio src="https://gitlab.com/1.mp3" controls="true" data-setup="{}" data-title="Sample Audio"></audio><a href="https://gitlab.com/1.mp3" target="_blank" rel="nofollow noreferrer noopener" title="Download 'Sample Audio'">Sample Audio</a></span>
+ <task-button></task-button><input type="checkbox" class="task-list-item-checkbox" checked disabled> <span class="media-container audio-container"><audio src="https://gitlab.com/1.mp3" controls="true" data-setup="{}" data-title="Sample Audio"></audio><a href="https://gitlab.com/1.mp3" target="_blank" rel="nofollow noreferrer noopener" title="Download 'Sample Audio'">Sample Audio</a></span>
</li>
<li data-sourcepos="8:1-8:47" class="task-list-item">
- <input type="checkbox" class="task-list-item-checkbox" checked disabled> <span class="media-container audio-container"><audio src="https://gitlab.com/2.mp3" controls="true" data-setup="{}" data-title="Sample Audio"></audio><a href="https://gitlab.com/2.mp3" target="_blank" rel="nofollow noreferrer noopener" title="Download 'Sample Audio'">Sample Audio</a></span>
+ <task-button></task-button><input type="checkbox" class="task-list-item-checkbox" checked disabled> <span class="media-container audio-container"><audio src="https://gitlab.com/2.mp3" controls="true" data-setup="{}" data-title="Sample Audio"></audio><a href="https://gitlab.com/2.mp3" target="_blank" rel="nofollow noreferrer noopener" title="Download 'Sample Audio'">Sample Audio</a></span>
</li>
<li data-sourcepos="9:1-9:47" class="task-list-item">
- <input type="checkbox" class="task-list-item-checkbox" checked disabled> <span class="media-container video-container"><video src="https://gitlab.com/3.mp4" controls="true" data-setup="{}" data-title="Sample Video" width="400" preload="metadata"></video><a href="https://gitlab.com/3.mp4" target="_blank" rel="nofollow noreferrer noopener" title="Download 'Sample Video'">Sample Video</a></span>
+ <task-button></task-button><input type="checkbox" class="task-list-item-checkbox" checked disabled> <span class="media-container video-container"><video src="https://gitlab.com/3.mp4" controls="true" data-setup="{}" data-title="Sample Video" width="400" preload="metadata"></video><a href="https://gitlab.com/3.mp4" target="_blank" rel="nofollow noreferrer noopener" title="Download 'Sample Video'">Sample Video</a></span>
</li>
</ul>
@@ -553,7 +553,7 @@
* The concert starts at <time datetime="20:00">20:00</time> and you'll be able to enjoy the band for at least <time datetime="PT2H30M">2h 30m</time>.
* Press <kbd>Ctrl</kbd> + <kbd>C</kbd> to copy text (Windows).
* WWF's goal is to: <q>Build a future where people live in harmony with nature.</q> We hope they succeed.
- * The error occured was: <samp>Keyboard not found. Press F1 to continue.</samp>
+ * The error occurred was: <samp>Keyboard not found. Press F1 to continue.</samp>
* The area of a triangle is: 1/2 x <var>b</var> x <var>h</var>, where <var>b</var> is the base, and <var>h</var> is the vertical height.
* <ruby>æ¼¢<rt>ã„ㄢˋ</rt></ruby>
* C<sub>7</sub>H<sub>16</sub> + O<sub>2</sub> → CO<sub>2</sub> + H<sub>2</sub>O
@@ -572,7 +572,7 @@
<li data-sourcepos="8:1-8:149">The concert starts at <time datetime="20:00">20:00</time> and you'll be able to enjoy the band for at least <time datetime="PT2H30M">2h 30m</time>.</li>
<li data-sourcepos="9:1-9:62">Press <kbd>Ctrl</kbd> + <kbd>C</kbd> to copy text (Windows).</li>
<li data-sourcepos="10:1-10:105">WWF's goal is to: <q>Build a future where people live in harmony with nature.</q> We hope they succeed.</li>
- <li data-sourcepos="11:1-11:79">The error occured was: <samp>Keyboard not found. Press F1 to continue.</samp>
+ <li data-sourcepos="11:1-11:80">The error occurred was: <samp>Keyboard not found. Press F1 to continue.</samp>
</li>
<li data-sourcepos="12:1-12:136">The area of a triangle is: 1/2 x <var>b</var> x <var>h</var>, where <var>b</var> is the base, and <var>h</var> is the vertical height.</li>
<li data-sourcepos="13:1-13:35"><ruby>æ¼¢<rt>ã„ㄢˋ</rt></ruby></li>
@@ -670,19 +670,19 @@
html: |-
<ol data-sourcepos="1:1-6:18" class="task-list" dir="auto">
<li data-sourcepos="1:1-1:12" class="task-list-item">
- <input type="checkbox" class="task-list-item-checkbox" checked disabled> hello</li>
+ <task-button></task-button><input type="checkbox" class="task-list-item-checkbox" checked disabled> hello</li>
<li data-sourcepos="2:1-2:12" class="task-list-item">
- <input type="checkbox" class="task-list-item-checkbox" checked disabled> world</li>
+ <task-button></task-button><input type="checkbox" class="task-list-item-checkbox" checked disabled> world</li>
<li data-sourcepos="3:1-6:18" class="task-list-item">
- <input type="checkbox" class="task-list-item-checkbox" disabled> example
+ <task-button></task-button><input type="checkbox" class="task-list-item-checkbox" disabled> example
<ol data-sourcepos="4:4-6:18" class="task-list">
<li data-sourcepos="4:4-6:18" class="task-list-item">
- <input type="checkbox" class="task-list-item-checkbox" disabled> of nested
+ <task-button></task-button><input type="checkbox" class="task-list-item-checkbox" disabled> of nested
<ol data-sourcepos="5:7-6:18" class="task-list">
<li data-sourcepos="5:7-5:22" class="task-list-item">
- <input type="checkbox" class="task-list-item-checkbox" checked disabled> task list</li>
+ <task-button></task-button><input type="checkbox" class="task-list-item-checkbox" checked disabled> task list</li>
<li data-sourcepos="6:7-6:18" class="task-list-item">
- <input type="checkbox" class="task-list-item-checkbox" disabled> items</li>
+ <task-button></task-button><input type="checkbox" class="task-list-item-checkbox" disabled> items</li>
</ol>
</li>
</ol>
@@ -697,11 +697,11 @@
html: |-
<ol start="4893" data-sourcepos="1:1-3:17" class="task-list" dir="auto">
<li data-sourcepos="1:1-1:15" class="task-list-item">
- <input type="checkbox" class="task-list-item-checkbox" checked disabled> hello</li>
+ <task-button></task-button><input type="checkbox" class="task-list-item-checkbox" checked disabled> hello</li>
<li data-sourcepos="2:1-2:15" class="task-list-item">
- <input type="checkbox" class="task-list-item-checkbox" checked disabled> world</li>
+ <task-button></task-button><input type="checkbox" class="task-list-item-checkbox" checked disabled> world</li>
<li data-sourcepos="3:1-3:17" class="task-list-item">
- <input type="checkbox" class="task-list-item-checkbox" disabled> example</li>
+ <task-button></task-button><input type="checkbox" class="task-list-item-checkbox" disabled> example</li>
</ol>
- name: reference_for_project_wiki
@@ -810,19 +810,19 @@
html: |-
<ul data-sourcepos="1:1-6:15" class="task-list" dir="auto">
<li data-sourcepos="1:1-1:11" class="task-list-item">
- <input type="checkbox" class="task-list-item-checkbox" checked disabled> hello</li>
+ <task-button></task-button><input type="checkbox" class="task-list-item-checkbox" checked disabled> hello</li>
<li data-sourcepos="2:1-2:11" class="task-list-item">
- <input type="checkbox" class="task-list-item-checkbox" checked disabled> world</li>
+ <task-button></task-button><input type="checkbox" class="task-list-item-checkbox" checked disabled> world</li>
<li data-sourcepos="3:1-6:15" class="task-list-item">
- <input type="checkbox" class="task-list-item-checkbox" disabled> example
+ <task-button></task-button><input type="checkbox" class="task-list-item-checkbox" disabled> example
<ul data-sourcepos="4:3-6:15" class="task-list">
<li data-sourcepos="4:3-6:15" class="task-list-item">
- <input type="checkbox" class="task-list-item-checkbox" disabled> of nested
+ <task-button></task-button><input type="checkbox" class="task-list-item-checkbox" disabled> of nested
<ul data-sourcepos="5:5-6:15" class="task-list">
<li data-sourcepos="5:5-5:19" class="task-list-item">
- <input type="checkbox" class="task-list-item-checkbox" checked disabled> task list</li>
+ <task-button></task-button><input type="checkbox" class="task-list-item-checkbox" checked disabled> task list</li>
<li data-sourcepos="6:5-6:15" class="task-list-item">
- <input type="checkbox" class="task-list-item-checkbox" disabled> items</li>
+ <task-button></task-button><input type="checkbox" class="task-list-item-checkbox" disabled> items</li>
</ul>
</li>
</ul>
diff --git a/spec/fixtures/security_reports/master/gl-common-scanning-report.json b/spec/fixtures/security_reports/master/gl-common-scanning-report.json
index cf4c5239b57..1fb00b2ff3a 100644
--- a/spec/fixtures/security_reports/master/gl-common-scanning-report.json
+++ b/spec/fixtures/security_reports/master/gl-common-scanning-report.json
@@ -12,6 +12,76 @@
"id": "gemnasium",
"name": "Gemnasium"
},
+ "evidence": {
+ "source": {
+ "id": "assert:CORS - Bad 'Origin' value",
+ "name": "CORS - Bad 'Origin' value"
+ },
+ "summary": "The Origin header was changed to an invalid value of http://peachapisecurity.com and the response contained an Access-Control-Allow-Origin header which included this invalid Origin, indicating that the CORS configuration on the server is overly permissive.\n\n\n",
+ "request": {
+ "headers": [
+ {
+ "name": "Host",
+ "value": "127.0.0.1:7777"
+ }
+ ],
+ "method": "GET",
+ "url": "http://127.0.0.1:7777/api/users",
+ "body": ""
+ },
+ "response": {
+ "headers": [
+ {
+ "name": "Server",
+ "value": "TwistedWeb/20.3.0"
+ }
+ ],
+ "reason_phrase": "OK",
+ "status_code": 200,
+ "body": "[{\"user_id\":1,\"user\":\"admin\",\"first\":\"Joe\",\"last\":\"Smith\",\"password\":\"Password!\"}]"
+ },
+ "supporting_messages": [
+ {
+ "name": "Origional",
+ "request": {
+ "headers": [
+ {
+ "name": "Host",
+ "value": "127.0.0.1:7777"
+ }
+ ],
+ "method": "GET",
+ "url": "http://127.0.0.1:7777/api/users",
+ "body": ""
+ }
+ },
+ {
+ "name": "Recorded",
+ "request": {
+ "headers": [
+ {
+ "name": "Host",
+ "value": "127.0.0.1:7777"
+ }
+ ],
+ "method": "GET",
+ "url": "http://127.0.0.1:7777/api/users",
+ "body": ""
+ },
+ "response": {
+ "headers": [
+ {
+ "name": "Server",
+ "value": "TwistedWeb/20.3.0"
+ }
+ ],
+ "reason_phrase": "OK",
+ "status_code": 200,
+ "body": "[{\"user_id\":1,\"user\":\"admin\",\"first\":\"Joe\",\"last\":\"Smith\",\"password\":\"Password!\"}]"
+ }
+ }
+ ]
+ },
"location": {},
"identifiers": [
{
@@ -57,6 +127,76 @@
"id": "gemnasium",
"name": "Gemnasium"
},
+ "evidence": {
+ "source": {
+ "id": "assert:CORS - Bad 'Origin' value",
+ "name": "CORS - Bad 'Origin' value"
+ },
+ "summary": "The Origin header was changed to an invalid value of http://peachapisecurity.com and the response contained an Access-Control-Allow-Origin header which included this invalid Origin, indicating that the CORS configuration on the server is overly permissive.\n\n\n",
+ "request": {
+ "headers": [
+ {
+ "name": "Host",
+ "value": "127.0.0.1:7777"
+ }
+ ],
+ "method": "GET",
+ "url": "http://127.0.0.1:7777/api/users",
+ "body": ""
+ },
+ "response": {
+ "headers": [
+ {
+ "name": "Server",
+ "value": "TwistedWeb/20.3.0"
+ }
+ ],
+ "reason_phrase": "OK",
+ "status_code": 200,
+ "body": "[{\"user_id\":1,\"user\":\"admin\",\"first\":\"Joe\",\"last\":\"Smith\",\"password\":\"Password!\"}]"
+ },
+ "supporting_messages": [
+ {
+ "name": "Origional",
+ "request": {
+ "headers": [
+ {
+ "name": "Host",
+ "value": "127.0.0.1:7777"
+ }
+ ],
+ "method": "GET",
+ "url": "http://127.0.0.1:7777/api/users",
+ "body": ""
+ }
+ },
+ {
+ "name": "Recorded",
+ "request": {
+ "headers": [
+ {
+ "name": "Host",
+ "value": "127.0.0.1:7777"
+ }
+ ],
+ "method": "GET",
+ "url": "http://127.0.0.1:7777/api/users",
+ "body": ""
+ },
+ "response": {
+ "headers": [
+ {
+ "name": "Server",
+ "value": "TwistedWeb/20.3.0"
+ }
+ ],
+ "reason_phrase": "OK",
+ "status_code": 200,
+ "body": "[{\"user_id\":1,\"user\":\"admin\",\"first\":\"Joe\",\"last\":\"Smith\",\"password\":\"Password!\"}]"
+ }
+ }
+ ]
+ },
"location": {},
"identifiers": [
{
diff --git a/spec/frontend/__helpers__/flush_promises.js b/spec/frontend/__helpers__/flush_promises.js
index 5287a060753..eefc2ed7c17 100644
--- a/spec/frontend/__helpers__/flush_promises.js
+++ b/spec/frontend/__helpers__/flush_promises.js
@@ -1,3 +1,4 @@
export default function flushPromises() {
+ // eslint-disable-next-line no-restricted-syntax
return new Promise(setImmediate);
}
diff --git a/spec/frontend/__helpers__/mocks/axios_utils.js b/spec/frontend/__helpers__/mocks/axios_utils.js
index 674563b9f28..b1efd29dc8d 100644
--- a/spec/frontend/__helpers__/mocks/axios_utils.js
+++ b/spec/frontend/__helpers__/mocks/axios_utils.js
@@ -25,6 +25,7 @@ const onRequest = () => {
// Use setImmediate to alloow the response interceptor to finish
const onResponse = (config) => {
activeRequests -= 1;
+ // eslint-disable-next-line no-restricted-syntax
setImmediate(() => {
events.emit('response', config);
});
@@ -43,6 +44,7 @@ const subscribeToResponse = (predicate = () => true) =>
// If a request has been made synchronously, setImmediate waits for it to be
// processed and the counter incremented.
+ // eslint-disable-next-line no-restricted-syntax
setImmediate(listener);
});
diff --git a/spec/frontend/__helpers__/vuex_action_helper.js b/spec/frontend/__helpers__/vuex_action_helper.js
index e482a8fbc71..68203b544ef 100644
--- a/spec/frontend/__helpers__/vuex_action_helper.js
+++ b/spec/frontend/__helpers__/vuex_action_helper.js
@@ -116,6 +116,7 @@ export default (
payload,
);
+ // eslint-disable-next-line no-restricted-syntax
return (result || new Promise((resolve) => setImmediate(resolve)))
.catch((error) => {
validateResults();
diff --git a/spec/frontend/access_tokens/components/__snapshots__/expires_at_field_spec.js.snap b/spec/frontend/access_tokens/components/__snapshots__/expires_at_field_spec.js.snap
index 0b86c10ea46..dd742419d32 100644
--- a/spec/frontend/access_tokens/components/__snapshots__/expires_at_field_spec.js.snap
+++ b/spec/frontend/access_tokens/components/__snapshots__/expires_at_field_spec.js.snap
@@ -1,25 +1,32 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`~/access_tokens/components/expires_at_field should render datepicker with input info 1`] = `
-<gl-datepicker-stub
- ariallabel=""
- autocomplete=""
- container=""
- displayfield="true"
- firstday="0"
- inputlabel="Enter date"
- mindate="Mon Jul 06 2020 00:00:00 GMT+0000 (Greenwich Mean Time)"
- placeholder="YYYY-MM-DD"
- theme=""
+<gl-form-group-stub
+ label="Expiration date"
+ label-for="personal_access_token_expires_at"
+ labeldescription=""
+ optionaltext="(optional)"
>
- <gl-form-input-stub
- autocomplete="off"
- class="datepicker gl-datepicker-input"
- data-qa-selector="expiry_date_field"
- id="personal_access_token_expires_at"
- inputmode="none"
- name="personal_access_token[expires_at]"
+ <gl-datepicker-stub
+ ariallabel=""
+ autocomplete=""
+ container=""
+ displayfield="true"
+ firstday="0"
+ inputlabel="Enter date"
+ mindate="Mon Jul 06 2020 00:00:00 GMT+0000 (Greenwich Mean Time)"
placeholder="YYYY-MM-DD"
- />
-</gl-datepicker-stub>
+ theme=""
+ >
+ <gl-form-input-stub
+ autocomplete="off"
+ class="datepicker gl-datepicker-input"
+ data-qa-selector="expiry_date_field"
+ id="personal_access_token_expires_at"
+ inputmode="none"
+ name="personal_access_token[expires_at]"
+ placeholder="YYYY-MM-DD"
+ />
+ </gl-datepicker-stub>
+</gl-form-group-stub>
`;
diff --git a/spec/frontend/access_tokens/components/expires_at_field_spec.js b/spec/frontend/access_tokens/components/expires_at_field_spec.js
index 4a2815e6931..fc8edcb573f 100644
--- a/spec/frontend/access_tokens/components/expires_at_field_spec.js
+++ b/spec/frontend/access_tokens/components/expires_at_field_spec.js
@@ -4,15 +4,17 @@ import ExpiresAtField from '~/access_tokens/components/expires_at_field.vue';
describe('~/access_tokens/components/expires_at_field', () => {
let wrapper;
- const createComponent = () => {
+ const defaultPropsData = {
+ inputAttrs: {
+ id: 'personal_access_token_expires_at',
+ name: 'personal_access_token[expires_at]',
+ placeholder: 'YYYY-MM-DD',
+ },
+ };
+
+ const createComponent = (propsData = defaultPropsData) => {
wrapper = shallowMount(ExpiresAtField, {
- propsData: {
- inputAttrs: {
- id: 'personal_access_token_expires_at',
- name: 'personal_access_token[expires_at]',
- placeholder: 'YYYY-MM-DD',
- },
- },
+ propsData,
});
};
diff --git a/spec/frontend/admin/applications/components/__snapshots__/delete_application_spec.js.snap b/spec/frontend/admin/applications/components/__snapshots__/delete_application_spec.js.snap
new file mode 100644
index 00000000000..459a113b6d1
--- /dev/null
+++ b/spec/frontend/admin/applications/components/__snapshots__/delete_application_spec.js.snap
@@ -0,0 +1,20 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`DeleteApplication the modal component form matches the snapshot 1`] = `
+<form
+ action="application/path/1"
+ method="post"
+>
+ <input
+ name="_method"
+ type="hidden"
+ value="delete"
+ />
+
+ <input
+ name="authenticity_token"
+ type="hidden"
+ value="mock-csrf-token"
+ />
+</form>
+`;
diff --git a/spec/frontend/admin/applications/components/delete_application_spec.js b/spec/frontend/admin/applications/components/delete_application_spec.js
new file mode 100644
index 00000000000..20119b64952
--- /dev/null
+++ b/spec/frontend/admin/applications/components/delete_application_spec.js
@@ -0,0 +1,69 @@
+import { GlModal, GlSprintf } from '@gitlab/ui';
+import { shallowMount } from '@vue/test-utils';
+import DeleteApplication from '~/admin/applications/components/delete_application.vue';
+
+const path = 'application/path/1';
+const name = 'Application name';
+
+jest.mock('~/lib/utils/csrf', () => ({ token: 'mock-csrf-token' }));
+
+describe('DeleteApplication', () => {
+ let wrapper;
+
+ const createComponent = () => {
+ wrapper = shallowMount(DeleteApplication, {
+ stubs: {
+ GlSprintf,
+ },
+ });
+ };
+
+ const findModal = () => wrapper.findComponent(GlModal);
+ const findForm = () => wrapper.find('form');
+
+ beforeEach(() => {
+ setFixtures(`
+ <button class="js-application-delete-button" data-path="${path}" data-name="${name}">Destroy</button>
+ `);
+
+ createComponent();
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ describe('the modal component', () => {
+ beforeEach(() => {
+ wrapper.vm.$refs.deleteModal.show = jest.fn();
+ document.querySelector('.js-application-delete-button').click();
+ });
+
+ it('displays the modal component', () => {
+ const modal = findModal();
+
+ expect(modal.exists()).toBe(true);
+ expect(modal.props('title')).toBe('Confirm destroy application');
+ expect(modal.text()).toBe(`Are you sure that you want to destroy ${name}`);
+ });
+
+ describe('form', () => {
+ it('matches the snapshot', () => {
+ expect(findForm().element).toMatchSnapshot();
+ });
+
+ describe('form submission', () => {
+ let formSubmitSpy;
+
+ beforeEach(() => {
+ formSubmitSpy = jest.spyOn(wrapper.vm.$refs.deleteForm, 'submit');
+ findModal().vm.$emit('primary');
+ });
+
+ it('submits the form on the modal primary action', () => {
+ expect(formSubmitSpy).toHaveBeenCalled();
+ });
+ });
+ });
+ });
+});
diff --git a/spec/frontend/admin/topics/components/__snapshots__/remove_avatar_spec.js.snap b/spec/frontend/admin/topics/components/__snapshots__/remove_avatar_spec.js.snap
new file mode 100644
index 00000000000..00f742c3614
--- /dev/null
+++ b/spec/frontend/admin/topics/components/__snapshots__/remove_avatar_spec.js.snap
@@ -0,0 +1,20 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`RemoveAvatar the modal component form matches the snapshot 1`] = `
+<form
+ action="topic/path/1"
+ method="post"
+>
+ <input
+ name="_method"
+ type="hidden"
+ value="delete"
+ />
+
+ <input
+ name="authenticity_token"
+ type="hidden"
+ value="mock-csrf-token"
+ />
+</form>
+`;
diff --git a/spec/frontend/admin/topics/components/remove_avatar_spec.js b/spec/frontend/admin/topics/components/remove_avatar_spec.js
new file mode 100644
index 00000000000..d4656f0a199
--- /dev/null
+++ b/spec/frontend/admin/topics/components/remove_avatar_spec.js
@@ -0,0 +1,85 @@
+import { GlButton, GlModal } from '@gitlab/ui';
+import { shallowMount } from '@vue/test-utils';
+import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
+import RemoveAvatar from '~/admin/topics/components/remove_avatar.vue';
+
+const modalID = 'fake-id';
+const path = 'topic/path/1';
+
+jest.mock('lodash/uniqueId', () => () => 'fake-id');
+jest.mock('~/lib/utils/csrf', () => ({ token: 'mock-csrf-token' }));
+
+describe('RemoveAvatar', () => {
+ let wrapper;
+
+ const createComponent = () => {
+ wrapper = shallowMount(RemoveAvatar, {
+ provide: {
+ path,
+ },
+ directives: {
+ GlModal: createMockDirective(),
+ },
+ });
+ };
+
+ const findButton = () => wrapper.findComponent(GlButton);
+ const findModal = () => wrapper.findComponent(GlModal);
+ const findForm = () => wrapper.find('form');
+
+ beforeEach(() => {
+ createComponent();
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ describe('the button component', () => {
+ it('displays the remove button', () => {
+ const button = findButton();
+
+ expect(button.exists()).toBe(true);
+ expect(button.text()).toBe('Remove avatar');
+ });
+
+ it('contains the correct modal ID', () => {
+ const buttonModalId = getBinding(findButton().element, 'gl-modal').value;
+
+ expect(buttonModalId).toBe(modalID);
+ });
+ });
+
+ describe('the modal component', () => {
+ it('displays the modal component', () => {
+ const modal = findModal();
+
+ expect(modal.exists()).toBe(true);
+ expect(modal.props('title')).toBe('Confirm remove avatar');
+ expect(modal.text()).toBe('Avatar will be removed. Are you sure?');
+ });
+
+ it('contains the correct modal ID', () => {
+ expect(findModal().props('modalId')).toBe(modalID);
+ });
+
+ describe('form', () => {
+ it('matches the snapshot', () => {
+ expect(findForm().element).toMatchSnapshot();
+ });
+
+ describe('form submission', () => {
+ let formSubmitSpy;
+
+ beforeEach(() => {
+ formSubmitSpy = jest.spyOn(wrapper.vm.$refs.deleteForm, 'submit');
+ findModal().vm.$emit('primary');
+ });
+
+ it('submits the form on the modal primary action', () => {
+ expect(formSubmitSpy).toHaveBeenCalled();
+ });
+ });
+ });
+ });
+});
diff --git a/spec/frontend/admin/users/components/user_actions_spec.js b/spec/frontend/admin/users/components/user_actions_spec.js
index 43313424553..b90a30b5b89 100644
--- a/spec/frontend/admin/users/components/user_actions_spec.js
+++ b/spec/frontend/admin/users/components/user_actions_spec.js
@@ -77,6 +77,12 @@ describe('AdminUserActions component', () => {
expect(findActionsDropdown().exists()).toBe(true);
});
+ it('renders the tooltip', () => {
+ const tooltip = getBinding(findActionsDropdown().element, 'gl-tooltip');
+
+ expect(tooltip.value).toBe(I18N_USER_ACTIONS.userAdministration);
+ });
+
describe('when there are actions that require confirmation', () => {
beforeEach(() => {
initComponent({ actions: CONFIRMATION_ACTIONS });
@@ -152,7 +158,7 @@ describe('AdminUserActions component', () => {
describe('when `showButtonLabels` prop is `false`', () => {
beforeEach(() => {
- initComponent({ actions: [EDIT, ...CONFIRMATION_ACTIONS] });
+ initComponent({ actions: [EDIT] });
});
it('does not render "Edit" button label', () => {
@@ -163,16 +169,11 @@ describe('AdminUserActions component', () => {
expect(tooltip).toBeDefined();
expect(tooltip.value).toBe(I18N_USER_ACTIONS.edit);
});
-
- it('does not render "User administration" dropdown button label', () => {
- expect(findActionsDropdown().props('text')).toBe(I18N_USER_ACTIONS.userAdministration);
- expect(findActionsDropdown().props('textSrOnly')).toBe(true);
- });
});
describe('when `showButtonLabels` prop is `true`', () => {
beforeEach(() => {
- initComponent({ actions: [EDIT, ...CONFIRMATION_ACTIONS], showButtonLabels: true });
+ initComponent({ actions: [EDIT], showButtonLabels: true });
});
it('renders "Edit" button label', () => {
@@ -181,10 +182,5 @@ describe('AdminUserActions component', () => {
expect(findEditButton().text()).toBe(I18N_USER_ACTIONS.edit);
expect(tooltip).not.toBeDefined();
});
-
- it('renders "User administration" dropdown button label', () => {
- expect(findActionsDropdown().props('text')).toBe(I18N_USER_ACTIONS.userAdministration);
- expect(findActionsDropdown().props('textSrOnly')).toBe(false);
- });
});
});
diff --git a/spec/frontend/api_spec.js b/spec/frontend/api_spec.js
index 75faf6d66fa..bc3e12d3fc4 100644
--- a/spec/frontend/api_spec.js
+++ b/spec/frontend/api_spec.js
@@ -1619,6 +1619,28 @@ describe('Api', () => {
});
});
+ describe('projectSecureFiles', () => {
+ it('fetches secure files for a project', async () => {
+ const projectId = 1;
+ const secureFiles = [
+ {
+ id: projectId,
+ title: 'File Name',
+ permissions: 'read_only',
+ checksum: '12345',
+ checksum_algorithm: 'sha256',
+ created_at: '2022-02-21T15:27:18',
+ },
+ ];
+
+ const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/projects/${projectId}/secure_files`;
+ mock.onGet(expectedUrl).reply(httpStatus.OK, secureFiles);
+ const { data } = await Api.projectSecureFiles(projectId, {});
+
+ expect(data).toEqual(secureFiles);
+ });
+ });
+
describe('Feature Flag User List', () => {
let expectedUrl;
let projectId;
diff --git a/spec/frontend/attention_requests/components/navigation_popover_spec.js b/spec/frontend/attention_requests/components/navigation_popover_spec.js
new file mode 100644
index 00000000000..d0231afbdc4
--- /dev/null
+++ b/spec/frontend/attention_requests/components/navigation_popover_spec.js
@@ -0,0 +1,86 @@
+import { shallowMount } from '@vue/test-utils';
+import { GlPopover, GlButton, GlSprintf, GlIcon } from '@gitlab/ui';
+import { GlBreakpointInstance as bp } from '@gitlab/ui/dist/utils';
+import NavigationPopover from '~/attention_requests/components/navigation_popover.vue';
+import { makeMockUserCalloutDismisser } from 'helpers/mock_user_callout_dismisser';
+
+let wrapper;
+let dismiss;
+
+function createComponent(provideData = {}, shouldShowCallout = true) {
+ wrapper = shallowMount(NavigationPopover, {
+ provide: {
+ message: ['Test'],
+ observerElSelector: '.js-test',
+ observerElToggledClass: 'show',
+ featureName: 'attention_requests',
+ popoverTarget: '.js-test-popover',
+ ...provideData,
+ },
+ stubs: {
+ UserCalloutDismisser: makeMockUserCalloutDismisser({
+ dismiss,
+ shouldShowCallout,
+ }),
+ GlSprintf,
+ },
+ });
+}
+
+describe('Attention requests navigation popover', () => {
+ beforeEach(() => {
+ setFixtures('<div><div class="js-test-popover"></div><div class="js-test"></div></div>');
+ dismiss = jest.fn();
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ wrapper = null;
+ });
+
+ it('hides popover if callout is disabled', () => {
+ createComponent({}, false);
+
+ expect(wrapper.findComponent(GlPopover).exists()).toBe(false);
+ });
+
+ it('shows popover if callout is enabled', () => {
+ createComponent();
+
+ expect(wrapper.findComponent(GlPopover).exists()).toBe(true);
+ });
+
+ it.each`
+ isDesktop | device | expectedPlacement
+ ${true} | ${'desktop'} | ${'left'}
+ ${false} | ${'mobile'} | ${'bottom'}
+ `(
+ 'sets popover position to $expectedPlacement on $device',
+ ({ isDesktop, expectedPlacement }) => {
+ jest.spyOn(bp, 'isDesktop').mockReturnValue(isDesktop);
+
+ createComponent();
+
+ expect(wrapper.findComponent(GlPopover).props('placement')).toBe(expectedPlacement);
+ },
+ );
+
+ it('calls dismiss when clicking action button', () => {
+ createComponent();
+
+ wrapper
+ .findComponent(GlButton)
+ .vm.$emit('click', { preventDefault() {}, stopPropagation() {} });
+
+ expect(dismiss).toHaveBeenCalled();
+ });
+
+ it('shows icon in text', () => {
+ createComponent({ showAttentionIcon: true, message: ['%{strongStart}Test%{strongEnd}'] });
+
+ const icon = wrapper.findComponent(GlIcon);
+
+ expect(icon.exists()).toBe(true);
+ expect(icon.props('name')).toBe('attention');
+ });
+});
diff --git a/spec/frontend/authentication/webauthn/util_spec.js b/spec/frontend/authentication/webauthn/util_spec.js
index c9b8bfd8679..bc44b47d0ba 100644
--- a/spec/frontend/authentication/webauthn/util_spec.js
+++ b/spec/frontend/authentication/webauthn/util_spec.js
@@ -1,4 +1,4 @@
-import { base64ToBuffer, bufferToBase64 } from '~/authentication/webauthn/util';
+import { base64ToBuffer, bufferToBase64, base64ToBase64Url } from '~/authentication/webauthn/util';
const encodedString = 'SGVsbG8gd29ybGQh';
const stringBytes = [72, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 33];
@@ -16,4 +16,19 @@ describe('Webauthn utils', () => {
const buffer = base64ToBuffer(encodedString);
expect(bufferToBase64(buffer)).toBe(encodedString);
});
+
+ describe('base64ToBase64Url', () => {
+ it.each`
+ argument | expectedResult
+ ${'asd+'} | ${'asd-'}
+ ${'asd/'} | ${'asd_'}
+ ${'asd='} | ${'asd'}
+ ${'+asd'} | ${'-asd'}
+ ${'/asd'} | ${'_asd'}
+ ${'=asd'} | ${'=asd'}
+ ${'a+bc/def=ghigjk=='} | ${'a-bc_def=ghigjk'}
+ `('returns $expectedResult when argument is $argument', ({ argument, expectedResult }) => {
+ expect(base64ToBase64Url(argument)).toBe(expectedResult);
+ });
+ });
});
diff --git a/spec/frontend/blob/components/__snapshots__/blob_header_spec.js.snap b/spec/frontend/blob/components/__snapshots__/blob_header_spec.js.snap
index b3d93906445..5926836d9c1 100644
--- a/spec/frontend/blob/components/__snapshots__/blob_header_spec.js.snap
+++ b/spec/frontend/blob/components/__snapshots__/blob_header_spec.js.snap
@@ -21,12 +21,13 @@ exports[`Blob Header Default Actions rendering matches the snapshot 1`] = `
class="gl-sm-display-flex file-actions"
>
<viewer-switcher-stub
+ docicon="document"
value="simple"
/>
<default-actions-stub
activeviewer="simple"
- rawpath="/flightjs/flight/snippets/51/raw"
+ rawpath="https://testing.com/flightjs/flight/snippets/51/raw"
/>
</div>
</div>
diff --git a/spec/frontend/blob/components/blob_header_spec.js b/spec/frontend/blob/components/blob_header_spec.js
index 8e1b03c6126..ee42c2387ae 100644
--- a/spec/frontend/blob/components/blob_header_spec.js
+++ b/spec/frontend/blob/components/blob_header_spec.js
@@ -159,5 +159,20 @@ describe('Blob Header Default Actions', () => {
await nextTick();
expect(wrapper.vm.$emit).not.toHaveBeenCalled();
});
+
+ it('sets different icons depending on the blob file type', async () => {
+ factory();
+ expect(wrapper.vm.blobSwitcherDocIcon).toBe('document');
+ await wrapper.setProps({
+ blob: {
+ ...Blob,
+ richViewer: {
+ ...Blob.richViewer,
+ fileType: 'csv',
+ },
+ },
+ });
+ expect(wrapper.vm.blobSwitcherDocIcon).toBe('table');
+ });
});
});
diff --git a/spec/frontend/blob/components/mock_data.js b/spec/frontend/blob/components/mock_data.js
index 9a345921f16..b5803bf0cbc 100644
--- a/spec/frontend/blob/components/mock_data.js
+++ b/spec/frontend/blob/components/mock_data.js
@@ -22,7 +22,7 @@ export const Blob = {
binary: false,
name: 'dummy.md',
path: 'foo/bar/dummy.md',
- rawPath: '/flightjs/flight/snippets/51/raw',
+ rawPath: 'https://testing.com/flightjs/flight/snippets/51/raw',
size: 75,
simpleViewer: {
...SimpleViewerMock,
diff --git a/spec/frontend/blob/csv/csv_viewer_spec.js b/spec/frontend/blob/csv/csv_viewer_spec.js
index 17973c709c1..ff96193a20c 100644
--- a/spec/frontend/blob/csv/csv_viewer_spec.js
+++ b/spec/frontend/blob/csv/csv_viewer_spec.js
@@ -2,6 +2,7 @@ import { GlLoadingIcon, GlTable } from '@gitlab/ui';
import { getAllByRole } from '@testing-library/dom';
import { shallowMount, mount } from '@vue/test-utils';
import { nextTick } from 'vue';
+import Papa from 'papaparse';
import CsvViewer from '~/blob/csv/csv_viewer.vue';
import PapaParseAlert from '~/vue_shared/components/papa_parse_alert.vue';
@@ -11,10 +12,15 @@ const brokenCsv = '{\n "json": 1,\n "key": [1, 2, 3]\n}';
describe('app/assets/javascripts/blob/csv/csv_viewer.vue', () => {
let wrapper;
- const createComponent = ({ csv = validCsv, mountFunction = shallowMount } = {}) => {
+ const createComponent = ({
+ csv = validCsv,
+ remoteFile = false,
+ mountFunction = shallowMount,
+ } = {}) => {
wrapper = mountFunction(CsvViewer, {
propsData: {
csv,
+ remoteFile,
},
});
};
@@ -73,4 +79,22 @@ describe('app/assets/javascripts/blob/csv/csv_viewer.vue', () => {
expect(getAllByRole(wrapper.element, 'row', { name: /Three/i })).toHaveLength(1);
});
});
+
+ describe('when csv prop is path and indicates a remote file', () => {
+ it('should render call parse with download flag true', async () => {
+ const path = 'path/to/remote/file.csv';
+ jest.spyOn(Papa, 'parse').mockImplementation((_, { complete }) => {
+ complete({ data: validCsv.split(','), errors: [] });
+ });
+
+ createComponent({ csv: path, remoteFile: true });
+ expect(Papa.parse).toHaveBeenCalledWith(path, {
+ download: true,
+ skipEmptyLines: true,
+ complete: expect.any(Function),
+ });
+ await nextTick;
+ expect(wrapper.vm.items).toEqual(validCsv.split(','));
+ });
+ });
});
diff --git a/spec/frontend/blob_edit/blob_bundle_spec.js b/spec/frontend/blob_edit/blob_bundle_spec.js
index 8986dfbfa9c..2c9ddfaf867 100644
--- a/spec/frontend/blob_edit/blob_bundle_spec.js
+++ b/spec/frontend/blob_edit/blob_bundle_spec.js
@@ -25,7 +25,7 @@ describe('BlobBundle', () => {
setFixtures(`
<div class="js-edit-blob-form" data-blob-filename="blah">
<button class="js-commit-button"></button>
- <a class="btn btn-cancel" href="#"></a>
+ <button id='cancel-changes'></button>
</div>`);
blobBundle();
@@ -42,7 +42,7 @@ describe('BlobBundle', () => {
});
it('removes beforeunload listener when cancel link is clicked', () => {
- $('.btn.btn-cancel').click();
+ $('#cancel-changes').click();
expect(window.onbeforeunload).toBeNull();
});
@@ -61,7 +61,7 @@ describe('BlobBundle', () => {
data-human-access="owner"
data-merge-request-path="path/to/mr">
<button id='commit-changes' class="js-commit-button"></button>
- <a class="btn btn-cancel" href="#"></a>
+ <button id='cancel-changes'></button>
</div>
</div>`);
diff --git a/spec/frontend/boards/components/board_form_spec.js b/spec/frontend/boards/components/board_form_spec.js
index 5678da2a246..c976ba7525b 100644
--- a/spec/frontend/boards/components/board_form_spec.js
+++ b/spec/frontend/boards/components/board_form_spec.js
@@ -1,6 +1,6 @@
import { GlModal } from '@gitlab/ui';
-import { shallowMount } from '@vue/test-utils';
import setWindowLocation from 'helpers/set_window_location_helper';
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import waitForPromises from 'helpers/wait_for_promises';
import BoardForm from '~/boards/components/board_form.vue';
@@ -22,6 +22,8 @@ const currentBoard = {
labels: [],
milestone: {},
assignee: {},
+ iteration: {},
+ iterationCadence: {},
weight: null,
hideBacklogList: false,
hideClosedList: false,
@@ -37,11 +39,11 @@ describe('BoardForm', () => {
let wrapper;
let mutate;
- const findModal = () => wrapper.find(GlModal);
+ const findModal = () => wrapper.findComponent(GlModal);
const findModalActionPrimary = () => findModal().props('actionPrimary');
- const findForm = () => wrapper.find('[data-testid="board-form"]');
- const findFormWrapper = () => wrapper.find('[data-testid="board-form-wrapper"]');
- const findDeleteConfirmation = () => wrapper.find('[data-testid="delete-confirmation-message"]');
+ const findForm = () => wrapper.findByTestId('board-form');
+ const findFormWrapper = () => wrapper.findByTestId('board-form-wrapper');
+ const findDeleteConfirmation = () => wrapper.findByTestId('delete-confirmation-message');
const findInput = () => wrapper.find('#board-new-name');
const store = createStore({
@@ -52,7 +54,7 @@ describe('BoardForm', () => {
});
const createComponent = (props, data) => {
- wrapper = shallowMount(BoardForm, {
+ wrapper = shallowMountExtended(BoardForm, {
propsData: { ...defaultProps, ...props },
data() {
return {
diff --git a/spec/frontend/boards/components/boards_selector_spec.js b/spec/frontend/boards/components/boards_selector_spec.js
index 26a5bf34595..0c044deb78c 100644
--- a/spec/frontend/boards/components/boards_selector_spec.js
+++ b/spec/frontend/boards/components/boards_selector_spec.js
@@ -41,6 +41,7 @@ describe('BoardsSelector', () => {
...defaultStore,
actions: {
setError: jest.fn(),
+ setBoardConfig: jest.fn(),
},
getters: {
isGroupBoard: () => isGroupBoard,
diff --git a/spec/frontend/boards/mock_data.js b/spec/frontend/boards/mock_data.js
index 24096fddea6..ec9342cffc2 100644
--- a/spec/frontend/boards/mock_data.js
+++ b/spec/frontend/boards/mock_data.js
@@ -8,6 +8,37 @@ import LabelToken from '~/vue_shared/components/filtered_search_bar/tokens/label
import MilestoneToken from '~/vue_shared/components/filtered_search_bar/tokens/milestone_token.vue';
import ReleaseToken from '~/vue_shared/components/filtered_search_bar/tokens/release_token.vue';
+export const mockBoard = {
+ milestone: {
+ id: 'gid://gitlab/Milestone/114',
+ title: '14.9',
+ },
+ iteration: {
+ id: 'gid://gitlab/Iteration/124',
+ title: 'Iteration 9',
+ },
+ assignee: {
+ id: 'gid://gitlab/User/1',
+ username: 'admin',
+ },
+ labels: {
+ nodes: [{ id: 'gid://gitlab/Label/32', title: 'Deliverable' }],
+ },
+ weight: 2,
+};
+
+export const mockBoardConfig = {
+ milestoneId: 'gid://gitlab/Milestone/114',
+ milestoneTitle: '14.9',
+ iterationId: 'gid://gitlab/Iteration/124',
+ iterationTitle: 'Iteration 9',
+ assigneeId: 'gid://gitlab/User/1',
+ assigneeUsername: 'admin',
+ labels: [{ id: 'gid://gitlab/Label/32', title: 'Deliverable' }],
+ labelIds: ['gid://gitlab/Label/32'],
+ weight: 2,
+};
+
export const boardObj = {
id: 1,
name: 'test',
diff --git a/spec/frontend/boards/stores/actions_spec.js b/spec/frontend/boards/stores/actions_spec.js
index 0eca0cb3ee5..ad661a31556 100644
--- a/spec/frontend/boards/stores/actions_spec.js
+++ b/spec/frontend/boards/stores/actions_spec.js
@@ -32,6 +32,8 @@ import { getIdFromGraphQLId } from '~/graphql_shared/utils';
import projectBoardMilestones from '~/boards/graphql/project_board_milestones.query.graphql';
import groupBoardMilestones from '~/boards/graphql/group_board_milestones.query.graphql';
import {
+ mockBoard,
+ mockBoardConfig,
mockLists,
mockListsById,
mockIssue,
@@ -60,6 +62,52 @@ beforeEach(() => {
window.gon = { features: {} };
});
+describe('fetchBoard', () => {
+ const payload = {
+ fullPath: 'gitlab-org',
+ fullBoardId: 'gid://gitlab/Board/1',
+ boardType: 'project',
+ };
+
+ const queryResponse = {
+ data: {
+ workspace: {
+ board: mockBoard,
+ },
+ },
+ };
+
+ it('should commit mutation RECEIVE_BOARD_SUCCESS and dispatch setBoardConfig on success', async () => {
+ jest.spyOn(gqlClient, 'query').mockResolvedValue(queryResponse);
+
+ await testAction({
+ action: actions.fetchBoard,
+ payload,
+ expectedMutations: [
+ {
+ type: types.RECEIVE_BOARD_SUCCESS,
+ payload: mockBoard,
+ },
+ ],
+ expectedActions: [{ type: 'setBoardConfig', payload: mockBoard }],
+ });
+ });
+
+ it('should commit mutation RECEIVE_BOARD_FAILURE on failure', async () => {
+ jest.spyOn(gqlClient, 'query').mockResolvedValue(Promise.reject());
+
+ await testAction({
+ action: actions.fetchBoard,
+ payload,
+ expectedMutations: [
+ {
+ type: types.RECEIVE_BOARD_FAILURE,
+ },
+ ],
+ });
+ });
+});
+
describe('setInitialBoardData', () => {
it('sets data object', () => {
const mockData = {
@@ -67,13 +115,21 @@ describe('setInitialBoardData', () => {
bar: 'baz',
};
- return testAction(
- actions.setInitialBoardData,
- mockData,
- {},
- [{ type: types.SET_INITIAL_BOARD_DATA, payload: mockData }],
- [],
- );
+ return testAction({
+ action: actions.setInitialBoardData,
+ payload: mockData,
+ expectedMutations: [{ type: types.SET_INITIAL_BOARD_DATA, payload: mockData }],
+ });
+ });
+});
+
+describe('setBoardConfig', () => {
+ it('sets board config object from board object', () => {
+ return testAction({
+ action: actions.setBoardConfig,
+ payload: mockBoard,
+ expectedMutations: [{ type: types.SET_BOARD_CONFIG, payload: mockBoardConfig }],
+ });
});
});
@@ -87,7 +143,7 @@ describe('setFilters', () => {
},
],
[
- "and use 'assigneeWildcardId' as filter variable for 'assigneId' param",
+ "and use 'assigneeWildcardId' as filter variable for 'assigneeId' param",
{
filters: { assigneeId: 'None' },
filterVariables: { assigneeWildcardId: 'NONE', not: {} },
diff --git a/spec/frontend/boards/stores/mutations_spec.js b/spec/frontend/boards/stores/mutations_spec.js
index 0e830258327..738737bf4b6 100644
--- a/spec/frontend/boards/stores/mutations_spec.js
+++ b/spec/frontend/boards/stores/mutations_spec.js
@@ -4,6 +4,7 @@ import * as types from '~/boards/stores/mutation_types';
import mutations from '~/boards/stores/mutations';
import defaultState from '~/boards/stores/state';
import {
+ mockBoard,
mockLists,
rawIssue,
mockIssue,
@@ -33,6 +34,27 @@ describe('Board Store Mutations', () => {
state = defaultState();
});
+ describe('RECEIVE_BOARD_SUCCESS', () => {
+ it('Should set board to state', () => {
+ mutations[types.RECEIVE_BOARD_SUCCESS](state, mockBoard);
+
+ expect(state.board).toEqual({
+ ...mockBoard,
+ labels: mockBoard.labels.nodes,
+ });
+ });
+ });
+
+ describe('RECEIVE_BOARD_FAILURE', () => {
+ it('Should set error in state', () => {
+ mutations[types.RECEIVE_BOARD_FAILURE](state);
+
+ expect(state.error).toEqual(
+ 'An error occurred while fetching the board. Please reload the page.',
+ );
+ });
+ });
+
describe('SET_INITIAL_BOARD_DATA', () => {
it('Should set initial Boards data to state', () => {
const allowSubEpics = true;
@@ -40,9 +62,6 @@ describe('Board Store Mutations', () => {
const fullPath = 'gitlab-org';
const boardType = 'group';
const disabled = false;
- const boardConfig = {
- milestoneTitle: 'Milestone 1',
- };
const issuableType = issuableTypes.issue;
mutations[types.SET_INITIAL_BOARD_DATA](state, {
@@ -51,7 +70,6 @@ describe('Board Store Mutations', () => {
fullPath,
boardType,
disabled,
- boardConfig,
issuableType,
});
@@ -60,11 +78,23 @@ describe('Board Store Mutations', () => {
expect(state.fullPath).toEqual(fullPath);
expect(state.boardType).toEqual(boardType);
expect(state.disabled).toEqual(disabled);
- expect(state.boardConfig).toEqual(boardConfig);
expect(state.issuableType).toEqual(issuableType);
});
});
+ describe('SET_BOARD_CONFIG', () => {
+ it('Should set board config data o state', () => {
+ const boardConfig = {
+ milestoneId: 1,
+ milestoneTitle: 'Milestone 1',
+ };
+
+ mutations[types.SET_BOARD_CONFIG](state, boardConfig);
+
+ expect(state.boardConfig).toEqual(boardConfig);
+ });
+ });
+
describe('RECEIVE_BOARD_LISTS_SUCCESS', () => {
it('Should set boardLists to state', () => {
mutations[types.RECEIVE_BOARD_LISTS_SUCCESS](state, initialBoardListsState);
diff --git a/spec/frontend/branches/ajax_loading_spinner_spec.js b/spec/frontend/branches/ajax_loading_spinner_spec.js
deleted file mode 100644
index 31cc7b99e42..00000000000
--- a/spec/frontend/branches/ajax_loading_spinner_spec.js
+++ /dev/null
@@ -1,32 +0,0 @@
-import AjaxLoadingSpinner from '~/branches/ajax_loading_spinner';
-
-describe('Ajax Loading Spinner', () => {
- let ajaxLoadingSpinnerElement;
- let fauxEvent;
- beforeEach(() => {
- document.body.innerHTML = `
- <div>
- <a class="js-ajax-loading-spinner"
- data-remote
- href="http://goesnowhere.nothing/whereami">
- Remove me
- </a></div>`;
- AjaxLoadingSpinner.init();
- ajaxLoadingSpinnerElement = document.querySelector('.js-ajax-loading-spinner');
- fauxEvent = { target: ajaxLoadingSpinnerElement };
- });
-
- afterEach(() => {
- document.body.innerHTML = '';
- });
-
- it('`ajaxBeforeSend` event handler sets current icon to spinner and disables link', () => {
- expect(ajaxLoadingSpinnerElement.parentNode.querySelector('.gl-spinner')).toBeNull();
- expect(ajaxLoadingSpinnerElement.classList.contains('hidden')).toBe(false);
-
- AjaxLoadingSpinner.ajaxBeforeSend(fauxEvent);
-
- expect(ajaxLoadingSpinnerElement.parentNode.querySelector('.gl-spinner')).not.toBeNull();
- expect(ajaxLoadingSpinnerElement.classList.contains('hidden')).toBe(true);
- });
-});
diff --git a/spec/frontend/ci_secure_files/components/secure_files_list_spec.js b/spec/frontend/ci_secure_files/components/secure_files_list_spec.js
new file mode 100644
index 00000000000..042376c71e8
--- /dev/null
+++ b/spec/frontend/ci_secure_files/components/secure_files_list_spec.js
@@ -0,0 +1,139 @@
+import { GlLoadingIcon } from '@gitlab/ui';
+import MockAdapter from 'axios-mock-adapter';
+import { mount } from '@vue/test-utils';
+import axios from '~/lib/utils/axios_utils';
+import SecureFilesList from '~/ci_secure_files/components/secure_files_list.vue';
+import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
+import waitForPromises from 'helpers/wait_for_promises';
+
+import { secureFiles } from '../mock_data';
+
+const dummyApiVersion = 'v3000';
+const dummyProjectId = 1;
+const dummyUrlRoot = '/gitlab';
+const dummyGon = {
+ api_version: dummyApiVersion,
+ relative_url_root: dummyUrlRoot,
+};
+let originalGon;
+const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/projects/${dummyProjectId}/secure_files`;
+
+describe('SecureFilesList', () => {
+ let wrapper;
+ let mock;
+
+ beforeEach(() => {
+ originalGon = window.gon;
+ window.gon = { ...dummyGon };
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ mock.restore();
+ window.gon = originalGon;
+ });
+
+ const createWrapper = (props = {}) => {
+ wrapper = mount(SecureFilesList, {
+ provide: { projectId: dummyProjectId },
+ ...props,
+ });
+ };
+
+ const findRows = () => wrapper.findAll('tbody tr');
+ const findRowAt = (i) => findRows().at(i);
+ const findCell = (i, col) => findRowAt(i).findAll('td').at(col);
+ const findHeaderAt = (i) => wrapper.findAll('thead th').at(i);
+ const findPagination = () => wrapper.findAll('ul.pagination');
+ const findLoadingIcon = () => wrapper.findComponent(GlLoadingIcon);
+
+ describe('when secure files exist in a project', () => {
+ beforeEach(async () => {
+ mock = new MockAdapter(axios);
+ mock.onGet(expectedUrl).reply(200, secureFiles);
+
+ createWrapper();
+ await waitForPromises();
+ });
+
+ it('displays a table with expected headers', () => {
+ const headers = ['Filename', 'Permissions', 'Uploaded'];
+ headers.forEach((header, i) => {
+ expect(findHeaderAt(i).text()).toBe(header);
+ });
+ });
+
+ it('displays a table with rows', () => {
+ expect(findRows()).toHaveLength(secureFiles.length);
+
+ const [secureFile] = secureFiles;
+
+ expect(findCell(0, 0).text()).toBe(secureFile.name);
+ expect(findCell(0, 1).text()).toBe(secureFile.permissions);
+ expect(findCell(0, 2).find(TimeAgoTooltip).props('time')).toBe(secureFile.created_at);
+ });
+ });
+
+ describe('when no secure files exist in a project', () => {
+ beforeEach(async () => {
+ mock = new MockAdapter(axios);
+ mock.onGet(expectedUrl).reply(200, []);
+
+ createWrapper();
+ await waitForPromises();
+ });
+
+ it('displays a table with expected headers', () => {
+ const headers = ['Filename', 'Permissions', 'Uploaded'];
+ headers.forEach((header, i) => {
+ expect(findHeaderAt(i).text()).toBe(header);
+ });
+ });
+
+ it('displays a table with a no records message', () => {
+ expect(findCell(0, 0).text()).toBe('There are no records to show');
+ });
+ });
+
+ describe('pagination', () => {
+ it('displays the pagination component with there are more than 20 items', async () => {
+ mock = new MockAdapter(axios);
+ mock.onGet(expectedUrl).reply(200, secureFiles, { 'x-total': 30 });
+
+ createWrapper();
+ await waitForPromises();
+
+ expect(findPagination().exists()).toBe(true);
+ });
+
+ it('does not display the pagination component with there are 20 items', async () => {
+ mock = new MockAdapter(axios);
+ mock.onGet(expectedUrl).reply(200, secureFiles, { 'x-total': 20 });
+
+ createWrapper();
+ await waitForPromises();
+
+ expect(findPagination().exists()).toBe(false);
+ });
+ });
+
+ describe('loading state', () => {
+ it('displays the loading icon while waiting for the backend request', () => {
+ mock = new MockAdapter(axios);
+ mock.onGet(expectedUrl).reply(200, secureFiles);
+ createWrapper();
+
+ expect(findLoadingIcon().exists()).toBe(true);
+ });
+
+ it('does not display the loading icon after the backend request has completed', async () => {
+ mock = new MockAdapter(axios);
+ mock.onGet(expectedUrl).reply(200, secureFiles);
+
+ createWrapper();
+ await waitForPromises();
+
+ expect(findLoadingIcon().exists()).toBe(false);
+ });
+ });
+});
diff --git a/spec/frontend/ci_secure_files/mock_data.js b/spec/frontend/ci_secure_files/mock_data.js
new file mode 100644
index 00000000000..5a9e16d1ad6
--- /dev/null
+++ b/spec/frontend/ci_secure_files/mock_data.js
@@ -0,0 +1,18 @@
+export const secureFiles = [
+ {
+ id: 1,
+ name: 'myfile.jks',
+ checksum: '16630b189ab34b2e3504f4758e1054d2e478deda510b2b08cc0ef38d12e80aac',
+ checksum_algorithm: 'sha256',
+ permissions: 'read_only',
+ created_at: '2022-02-22T22:22:22.222Z',
+ },
+ {
+ id: 2,
+ name: 'myotherfile.jks',
+ checksum: '16630b189ab34b2e3504f4758e1054d2e478deda510b2b08cc0ef38d12e80aa2',
+ checksum_algorithm: 'sha256',
+ permissions: 'execute',
+ created_at: '2022-02-22T22:22:22.222Z',
+ },
+];
diff --git a/spec/frontend/clusters/agents/components/create_token_button_spec.js b/spec/frontend/clusters/agents/components/create_token_button_spec.js
new file mode 100644
index 00000000000..b9a3a851e57
--- /dev/null
+++ b/spec/frontend/clusters/agents/components/create_token_button_spec.js
@@ -0,0 +1,257 @@
+import { GlButton, GlTooltip, GlModal, GlFormInput, GlFormTextarea, GlAlert } from '@gitlab/ui';
+import Vue from 'vue';
+import VueApollo from 'vue-apollo';
+import createMockApollo from 'helpers/mock_apollo_helper';
+import waitForPromises from 'helpers/wait_for_promises';
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
+import { mockTracking } from 'helpers/tracking_helper';
+import {
+ EVENT_LABEL_MODAL,
+ EVENT_ACTIONS_OPEN,
+ TOKEN_NAME_LIMIT,
+ TOKEN_STATUS_ACTIVE,
+ MAX_LIST_COUNT,
+} from '~/clusters/agents/constants';
+import createNewAgentToken from '~/clusters/agents/graphql/mutations/create_new_agent_token.mutation.graphql';
+import getClusterAgentQuery from '~/clusters/agents/graphql/queries/get_cluster_agent.query.graphql';
+import AgentToken from '~/clusters_list/components/agent_token.vue';
+import CreateTokenButton from '~/clusters/agents/components/create_token_button.vue';
+import {
+ clusterAgentToken,
+ getTokenResponse,
+ createAgentTokenErrorResponse,
+} from '../../mock_data';
+
+Vue.use(VueApollo);
+
+describe('CreateTokenButton', () => {
+ let wrapper;
+ let apolloProvider;
+ let trackingSpy;
+ let createResponse;
+
+ const clusterAgentId = 'cluster-agent-id';
+ const cursor = {
+ first: MAX_LIST_COUNT,
+ last: null,
+ };
+ const agentName = 'cluster-agent';
+ const projectPath = 'path/to/project';
+
+ const defaultProvide = {
+ agentName,
+ projectPath,
+ canAdminCluster: true,
+ };
+ const propsData = {
+ clusterAgentId,
+ cursor,
+ };
+
+ const findModal = () => wrapper.findComponent(GlModal);
+ const findBtn = () => wrapper.findComponent(GlButton);
+ const findInput = () => wrapper.findComponent(GlFormInput);
+ const findTextarea = () => wrapper.findComponent(GlFormTextarea);
+ const findAlert = () => wrapper.findComponent(GlAlert);
+ const findTooltip = () => wrapper.findComponent(GlTooltip);
+ const findAgentInstructions = () => findModal().findComponent(AgentToken);
+ const findButtonByVariant = (variant) =>
+ findModal()
+ .findAll(GlButton)
+ .wrappers.find((button) => button.props('variant') === variant);
+ const findActionButton = () => findButtonByVariant('confirm');
+ const findCancelButton = () => wrapper.findByTestId('agent-token-close-button');
+
+ const expectDisabledAttribute = (element, disabled) => {
+ if (disabled) {
+ expect(element.attributes('disabled')).toBe('true');
+ } else {
+ expect(element.attributes('disabled')).toBeUndefined();
+ }
+ };
+
+ const createMockApolloProvider = ({ mutationResponse }) => {
+ createResponse = jest.fn().mockResolvedValue(mutationResponse);
+
+ return createMockApollo([[createNewAgentToken, createResponse]]);
+ };
+
+ const writeQuery = () => {
+ apolloProvider.clients.defaultClient.cache.writeQuery({
+ query: getClusterAgentQuery,
+ data: getTokenResponse.data,
+ variables: {
+ agentName,
+ projectPath,
+ tokenStatus: TOKEN_STATUS_ACTIVE,
+ ...cursor,
+ },
+ });
+ };
+
+ const createWrapper = async ({ provideData = {} } = {}) => {
+ wrapper = shallowMountExtended(CreateTokenButton, {
+ apolloProvider,
+ provide: {
+ ...defaultProvide,
+ ...provideData,
+ },
+ propsData,
+ stubs: {
+ GlModal,
+ GlTooltip,
+ },
+ });
+ wrapper.vm.$refs.modal.hide = jest.fn();
+
+ trackingSpy = mockTracking(undefined, wrapper.element, jest.spyOn);
+ };
+
+ const mockCreatedResponse = (mutationResponse) => {
+ apolloProvider = createMockApolloProvider({ mutationResponse });
+ writeQuery();
+
+ createWrapper();
+
+ findInput().vm.$emit('input', 'new-token');
+ findTextarea().vm.$emit('input', 'new-token-description');
+ findActionButton().vm.$emit('click');
+
+ return waitForPromises();
+ };
+
+ beforeEach(() => {
+ createWrapper();
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ apolloProvider = null;
+ createResponse = null;
+ });
+
+ describe('create agent token action', () => {
+ it('displays create agent token button', () => {
+ expect(findBtn().text()).toBe('Create token');
+ });
+
+ describe('when user cannot create token', () => {
+ beforeEach(() => {
+ createWrapper({ provideData: { canAdminCluster: false } });
+ });
+
+ it('disabled the button', () => {
+ expect(findBtn().attributes('disabled')).toBe('true');
+ });
+
+ it('shows a disabled tooltip', () => {
+ expect(findTooltip().attributes('title')).toBe(
+ 'Requires a Maintainer or greater role to perform these actions',
+ );
+ });
+ });
+
+ describe('when user can create a token and clicks the button', () => {
+ beforeEach(() => {
+ findBtn().vm.$emit('click');
+ });
+
+ it('displays a token creation modal', () => {
+ expect(findModal().isVisible()).toBe(true);
+ });
+
+ describe('initial state', () => {
+ it('renders an input for the token name', () => {
+ expect(findInput().exists()).toBe(true);
+ expectDisabledAttribute(findInput(), false);
+ expect(findInput().attributes('max-length')).toBe(TOKEN_NAME_LIMIT.toString());
+ });
+
+ it('renders a textarea for the token description', () => {
+ expect(findTextarea().exists()).toBe(true);
+ expectDisabledAttribute(findTextarea(), false);
+ });
+
+ it('renders a cancel button', () => {
+ expect(findCancelButton().isVisible()).toBe(true);
+ expectDisabledAttribute(findCancelButton(), false);
+ });
+
+ it('renders a disabled next button', () => {
+ expect(findActionButton().text()).toBe('Create token');
+ expectDisabledAttribute(findActionButton(), true);
+ });
+
+ it('sends tracking event for modal shown', () => {
+ findModal().vm.$emit('show');
+ expect(trackingSpy).toHaveBeenCalledWith(undefined, EVENT_ACTIONS_OPEN, {
+ label: EVENT_LABEL_MODAL,
+ });
+ });
+ });
+
+ describe('when user inputs the token name', () => {
+ beforeEach(() => {
+ expectDisabledAttribute(findActionButton(), true);
+ findInput().vm.$emit('input', 'new-token');
+ });
+
+ it('enables the next button', () => {
+ expectDisabledAttribute(findActionButton(), false);
+ });
+ });
+
+ describe('when user clicks the create-token button', () => {
+ beforeEach(async () => {
+ const loadingResponse = new Promise(() => {});
+ await mockCreatedResponse(loadingResponse);
+
+ findInput().vm.$emit('input', 'new-token');
+ findActionButton().vm.$emit('click');
+ });
+
+ it('disables the create-token button', () => {
+ expectDisabledAttribute(findActionButton(), true);
+ });
+
+ it('hides the cancel button', () => {
+ expect(findCancelButton().exists()).toBe(false);
+ });
+ });
+
+ describe('creating a new token', () => {
+ beforeEach(async () => {
+ await mockCreatedResponse(clusterAgentToken);
+ });
+
+ it('creates a token', () => {
+ expect(createResponse).toHaveBeenCalledWith({
+ input: { clusterAgentId, name: 'new-token', description: 'new-token-description' },
+ });
+ });
+
+ it('shows agent instructions', () => {
+ expect(findAgentInstructions().exists()).toBe(true);
+ });
+
+ it('renders a close button', () => {
+ expect(findActionButton().isVisible()).toBe(true);
+ expect(findActionButton().text()).toBe('Close');
+ expectDisabledAttribute(findActionButton(), false);
+ });
+ });
+
+ describe('error creating a new token', () => {
+ beforeEach(async () => {
+ await mockCreatedResponse(createAgentTokenErrorResponse);
+ });
+
+ it('displays the error message', async () => {
+ expect(findAlert().text()).toBe(
+ createAgentTokenErrorResponse.data.clusterAgentTokenCreate.errors[0],
+ );
+ });
+ });
+ });
+ });
+});
diff --git a/spec/frontend/clusters/agents/components/token_table_spec.js b/spec/frontend/clusters/agents/components/token_table_spec.js
index 47ff944dd84..f6baaf87fa4 100644
--- a/spec/frontend/clusters/agents/components/token_table_spec.js
+++ b/spec/frontend/clusters/agents/components/token_table_spec.js
@@ -1,8 +1,10 @@
-import { GlEmptyState, GlLink, GlTooltip, GlTruncate } from '@gitlab/ui';
+import { GlEmptyState, GlTooltip, GlTruncate } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
import TokenTable from '~/clusters/agents/components/token_table.vue';
+import CreateTokenButton from '~/clusters/agents/components/create_token_button.vue';
import { useFakeDate } from 'helpers/fake_date';
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
+import { MAX_LIST_COUNT } from '~/clusters/agents/constants';
describe('ClusterAgentTokenTable', () => {
let wrapper;
@@ -28,13 +30,26 @@ describe('ClusterAgentTokenTable', () => {
name: 'token-2',
},
];
+ const clusterAgentId = 'cluster-agent-id';
+ const cursor = {
+ first: MAX_LIST_COUNT,
+ last: null,
+ };
+
+ const provide = {
+ agentName: 'cluster-agent',
+ projectPath: 'path/to/project',
+ canAdminCluster: true,
+ };
const createComponent = (tokens) => {
- wrapper = extendedWrapper(mount(TokenTable, { propsData: { tokens } }));
+ wrapper = extendedWrapper(
+ mount(TokenTable, { propsData: { tokens, clusterAgentId, cursor }, provide }),
+ );
};
- const findEmptyState = () => wrapper.find(GlEmptyState);
- const findLink = () => wrapper.find(GlLink);
+ const findEmptyState = () => wrapper.findComponent(GlEmptyState);
+ const findCreateTokenBtn = () => wrapper.findComponent(CreateTokenButton);
beforeEach(() => {
return createComponent(defaultTokens);
@@ -44,11 +59,15 @@ describe('ClusterAgentTokenTable', () => {
wrapper.destroy();
});
- it('displays a learn more link', () => {
- const learnMoreLink = findLink();
+ it('displays the create token button', () => {
+ expect(findCreateTokenBtn().exists()).toBe(true);
+ });
- expect(learnMoreLink.exists()).toBe(true);
- expect(learnMoreLink.text()).toBe(TokenTable.i18n.learnMore);
+ it('passes the correct params to the create token component', () => {
+ expect(findCreateTokenBtn().props()).toMatchObject({
+ clusterAgentId,
+ cursor,
+ });
});
it.each`
@@ -56,7 +75,7 @@ describe('ClusterAgentTokenTable', () => {
${'token-1'} | ${0}
${'token-2'} | ${1}
`('displays token name "$name" for line "$lineNumber"', ({ name, lineNumber }) => {
- const tokens = wrapper.findAll('[data-testid="agent-token-name"]');
+ const tokens = wrapper.findAllByTestId('agent-token-name');
const token = tokens.at(lineNumber);
expect(token.text()).toBe(name);
@@ -83,7 +102,7 @@ describe('ClusterAgentTokenTable', () => {
`(
'displays created information "$createdText" for line "$lineNumber"',
({ createdText, lineNumber }) => {
- const tokens = wrapper.findAll('[data-testid="agent-token-created-time"]');
+ const tokens = wrapper.findAllByTestId('agent-token-created-time');
const token = tokens.at(lineNumber);
expect(token.text()).toBe(createdText);
@@ -97,7 +116,7 @@ describe('ClusterAgentTokenTable', () => {
`(
'displays creator information "$createdBy" for line "$lineNumber"',
({ createdBy, lineNumber }) => {
- const tokens = wrapper.findAll('[data-testid="agent-token-created-user"]');
+ const tokens = wrapper.findAllByTestId('agent-token-created-user');
const token = tokens.at(lineNumber);
expect(token.text()).toBe(createdBy);
@@ -111,7 +130,7 @@ describe('ClusterAgentTokenTable', () => {
`(
'displays description information "$description" for line "$lineNumber"',
({ description, truncatesText, hasTooltip, lineNumber }) => {
- const tokens = wrapper.findAll('[data-testid="agent-token-description"]');
+ const tokens = wrapper.findAllByTestId('agent-token-description');
const token = tokens.at(lineNumber);
expect(token.text()).toContain(description);
diff --git a/spec/frontend/clusters/components/__snapshots__/new_cluster_spec.js.snap b/spec/frontend/clusters/components/__snapshots__/new_cluster_spec.js.snap
index 5577176bcc5..0bec2a5934e 100644
--- a/spec/frontend/clusters/components/__snapshots__/new_cluster_spec.js.snap
+++ b/spec/frontend/clusters/components/__snapshots__/new_cluster_spec.js.snap
@@ -1,8 +1,9 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`NewCluster renders the cluster component correctly 1`] = `
-"<div>
- <h4>Enter the details for your Kubernetes cluster</h4>
- <p>Please enter access information for your Kubernetes cluster. If you need help, you can read our <b-link-stub href=\\"/some/help/path\\" target=\\"_blank\\" event=\\"click\\" routertag=\\"a\\" class=\\"gl-link\\">documentation</b-link-stub> on Kubernetes</p>
+"<div class=\\"gl-pt-4\\">
+ <h4>Enter your Kubernetes cluster certificate details</h4>
+ <p>Enter details about your cluster. <b-link-stub href=\\"/some/help/path\\" target=\\"_blank\\" event=\\"click\\" routertag=\\"a\\" class=\\"gl-link\\">How do I use a certificate to connect to my cluster?</b-link-stub>
+ </p>
</div>"
`;
diff --git a/spec/frontend/clusters/components/new_cluster_spec.js b/spec/frontend/clusters/components/new_cluster_spec.js
index b73442f6ec3..b62e678154c 100644
--- a/spec/frontend/clusters/components/new_cluster_spec.js
+++ b/spec/frontend/clusters/components/new_cluster_spec.js
@@ -31,9 +31,7 @@ describe('NewCluster', () => {
});
it('renders the correct information text', () => {
- expect(findDescription().text()).toContain(
- 'Please enter access information for your Kubernetes cluster.',
- );
+ expect(findDescription().text()).toContain('Enter details about your cluster.');
});
it('renders a valid help link set by the backend', () => {
diff --git a/spec/frontend/clusters/mock_data.js b/spec/frontend/clusters/mock_data.js
index 75306ca0295..63840486d0d 100644
--- a/spec/frontend/clusters/mock_data.js
+++ b/spec/frontend/clusters/mock_data.js
@@ -163,3 +163,60 @@ export const mockAgentHistoryActivityItems = [
body: 'Event occurred',
},
];
+
+export const clusterAgentToken = {
+ data: {
+ clusterAgentTokenCreate: {
+ errors: [],
+ secret: 'token-secret',
+ token: {
+ createdAt: '2022-03-13T18:42:44Z',
+ createdByUser: {
+ ...user,
+ },
+ description: 'token-description',
+ id: 'token-id',
+ lastUsedAt: null,
+ name: 'token-name',
+ __typename: 'ClusterAgentToken',
+ },
+ __typename: 'ClusterAgentTokenCreatePayload',
+ },
+ },
+};
+
+export const createAgentTokenErrorResponse = {
+ data: {
+ clusterAgentTokenCreate: {
+ token: null,
+ secret: null,
+ errors: ['could not create agent token'],
+ },
+ },
+};
+
+export const getTokenResponse = {
+ data: {
+ project: {
+ id: 'project-1',
+ clusterAgent: {
+ id: 'cluster-agent-id',
+ createdAt: '2022-03-13T18:42:44Z',
+ createdByUser: {
+ ...user,
+ },
+ tokens: {
+ count: 1,
+ nodes: [{ ...clusterAgentToken.token }],
+ pageInfo: {
+ endCursor: '',
+ hasNextPage: false,
+ hasPreviousPage: false,
+ startCursor: '',
+ },
+ },
+ },
+ __typename: 'Project',
+ },
+ },
+};
diff --git a/spec/frontend/clusters_list/components/agent_table_spec.js b/spec/frontend/clusters_list/components/agent_table_spec.js
index dc7f0ebae74..db723622a51 100644
--- a/spec/frontend/clusters_list/components/agent_table_spec.js
+++ b/spec/frontend/clusters_list/components/agent_table_spec.js
@@ -8,6 +8,9 @@ import { stubComponent } from 'helpers/stub_component';
import timeagoMixin from '~/vue_shared/mixins/timeago';
import { clusterAgents, connectedTimeNow, connectedTimeInactive } from './mock_data';
+const defaultConfigHelpUrl =
+ '/help/user/clusters/agent/install/index#create-an-agent-without-configuration-file';
+
const provideData = {
gitlabVersion: '14.8',
};
@@ -31,8 +34,8 @@ describe('AgentTable', () => {
let wrapper;
const findAgentLink = (at) => wrapper.findAllByTestId('cluster-agent-name-link').at(at);
- const findStatusIcon = (at) => wrapper.findAllComponents(GlIcon).at(at);
const findStatusText = (at) => wrapper.findAllByTestId('cluster-agent-connection-status').at(at);
+ const findStatusIcon = (at) => findStatusText(at).find(GlIcon);
const findLastContactText = (at) => wrapper.findAllByTestId('cluster-agent-last-contact').at(at);
const findVersionText = (at) => wrapper.findAllByTestId('cluster-agent-version').at(at);
const findConfiguration = (at) =>
@@ -141,16 +144,16 @@ describe('AgentTable', () => {
);
it.each`
- agentPath | hasLink | lineNumber
- ${'.gitlab/agents/agent-1'} | ${true} | ${0}
- ${'.gitlab/agents/agent-2'} | ${false} | ${1}
+ agentConfig | link | lineNumber
+ ${'.gitlab/agents/agent-1'} | ${'/agent/full/path'} | ${0}
+ ${'Default configuration'} | ${defaultConfigHelpUrl} | ${1}
`(
'displays config file path as "$agentPath" at line $lineNumber',
- ({ agentPath, hasLink, lineNumber }) => {
+ ({ agentConfig, link, lineNumber }) => {
const findLink = findConfiguration(lineNumber).find(GlLink);
- expect(findLink.exists()).toBe(hasLink);
- expect(findConfiguration(lineNumber).text()).toBe(agentPath);
+ expect(findLink.attributes('href')).toBe(link);
+ expect(findConfiguration(lineNumber).text()).toBe(agentConfig);
},
);
diff --git a/spec/frontend/clusters_list/components/agent_token_spec.js b/spec/frontend/clusters_list/components/agent_token_spec.js
new file mode 100644
index 00000000000..a80c8ffaad4
--- /dev/null
+++ b/spec/frontend/clusters_list/components/agent_token_spec.js
@@ -0,0 +1,76 @@
+import { GlAlert, GlFormInputGroup } from '@gitlab/ui';
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
+import AgentToken from '~/clusters_list/components/agent_token.vue';
+import { I18N_AGENT_TOKEN, INSTALL_AGENT_MODAL_ID } from '~/clusters_list/constants';
+import { generateAgentRegistrationCommand } from '~/clusters_list/clusters_util';
+import CodeBlock from '~/vue_shared/components/code_block.vue';
+import ModalCopyButton from '~/vue_shared/components/modal_copy_button.vue';
+
+const kasAddress = 'kas.example.com';
+const agentToken = 'agent-token';
+const modalId = INSTALL_AGENT_MODAL_ID;
+
+describe('InstallAgentModal', () => {
+ let wrapper;
+
+ const findAlert = () => wrapper.findComponent(GlAlert);
+ const findCodeBlock = () => wrapper.findComponent(CodeBlock);
+ const findCopyButton = () => wrapper.findComponent(ModalCopyButton);
+ const findInput = () => wrapper.findComponent(GlFormInputGroup);
+
+ const createWrapper = () => {
+ const provide = {
+ kasAddress,
+ };
+
+ const propsData = {
+ agentToken,
+ modalId,
+ };
+
+ wrapper = shallowMountExtended(AgentToken, {
+ provide,
+ propsData,
+ });
+ };
+
+ beforeEach(() => {
+ createWrapper();
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ describe('initial state', () => {
+ it('shows basic agent installation instructions', () => {
+ expect(wrapper.text()).toContain(I18N_AGENT_TOKEN.basicInstallTitle);
+ expect(wrapper.text()).toContain(I18N_AGENT_TOKEN.basicInstallBody);
+ });
+
+ it('shows advanced agent installation instructions', () => {
+ expect(wrapper.text()).toContain(I18N_AGENT_TOKEN.advancedInstallTitle);
+ });
+
+ it('shows agent token as an input value', () => {
+ expect(findInput().props('value')).toBe('agent-token');
+ });
+
+ it('renders a copy button', () => {
+ expect(findCopyButton().props()).toMatchObject({
+ title: 'Copy command',
+ text: generateAgentRegistrationCommand(agentToken, kasAddress),
+ modalId,
+ });
+ });
+
+ it('shows warning alert', () => {
+ expect(findAlert().props('title')).toBe(I18N_AGENT_TOKEN.tokenSingleUseWarningTitle);
+ });
+
+ it('shows code block with agent installation command', () => {
+ expect(findCodeBlock().props('code')).toContain('--agent-token=agent-token');
+ expect(findCodeBlock().props('code')).toContain('--kas-address=kas.example.com');
+ });
+ });
+});
diff --git a/spec/frontend/clusters_list/components/available_agents_dropwdown_spec.js b/spec/frontend/clusters_list/components/available_agents_dropwdown_spec.js
index bcc1d4e8b9e..eca2b1f5cb1 100644
--- a/spec/frontend/clusters_list/components/available_agents_dropwdown_spec.js
+++ b/spec/frontend/clusters_list/components/available_agents_dropwdown_spec.js
@@ -1,5 +1,5 @@
-import { GlDropdown, GlDropdownItem } from '@gitlab/ui';
-import { shallowMount } from '@vue/test-utils';
+import { GlDropdown, GlDropdownItem, GlSearchBoxByType } from '@gitlab/ui';
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import AvailableAgentsDropdown from '~/clusters_list/components/available_agents_dropdown.vue';
import { I18N_AVAILABLE_AGENTS_DROPDOWN } from '~/clusters_list/constants';
@@ -9,11 +9,14 @@ describe('AvailableAgentsDropdown', () => {
const i18n = I18N_AVAILABLE_AGENTS_DROPDOWN;
const findDropdown = () => wrapper.findComponent(GlDropdown);
const findDropdownItems = () => wrapper.findAllComponents(GlDropdownItem);
- const findConfiguredAgentItem = () => findDropdownItems().at(0);
+ const findFirstAgentItem = () => findDropdownItems().at(0);
+ const findSearchInput = () => wrapper.findComponent(GlSearchBoxByType);
+ const findCreateButton = () => wrapper.findByTestId('create-config-button');
const createWrapper = ({ propsData }) => {
- wrapper = shallowMount(AvailableAgentsDropdown, {
+ wrapper = shallowMountExtended(AvailableAgentsDropdown, {
propsData,
+ stubs: { GlDropdown },
});
};
@@ -23,7 +26,7 @@ describe('AvailableAgentsDropdown', () => {
describe('there are agents available', () => {
const propsData = {
- availableAgents: ['configured-agent'],
+ availableAgents: ['configured-agent', 'search-agent', 'test-agent'],
isRegistering: false,
};
@@ -35,9 +38,38 @@ describe('AvailableAgentsDropdown', () => {
expect(findDropdown().props('text')).toBe(i18n.selectAgent);
});
- describe('click events', () => {
+ describe('search agent', () => {
+ it('renders search button', () => {
+ expect(findSearchInput().exists()).toBe(true);
+ });
+
+ it('renders all agents when search term is empty', () => {
+ expect(findDropdownItems()).toHaveLength(3);
+ });
+
+ it('renders only the agent searched for when the search item exists', async () => {
+ await findSearchInput().vm.$emit('input', 'search-agent');
+
+ expect(findDropdownItems()).toHaveLength(1);
+ expect(findFirstAgentItem().text()).toBe('search-agent');
+ });
+
+ it('renders create button when search started', async () => {
+ await findSearchInput().vm.$emit('input', 'new-agent');
+
+ expect(findCreateButton().exists()).toBe(true);
+ });
+
+ it("doesn't render create button when search item is found", async () => {
+ await findSearchInput().vm.$emit('input', 'search-agent');
+
+ expect(findCreateButton().exists()).toBe(false);
+ });
+ });
+
+ describe('select existing agent configuration', () => {
beforeEach(() => {
- findConfiguredAgentItem().vm.$emit('click');
+ findFirstAgentItem().vm.$emit('click');
});
it('emits agentSelected with the name of the clicked agent', () => {
@@ -46,7 +78,22 @@ describe('AvailableAgentsDropdown', () => {
it('marks the clicked item as selected', () => {
expect(findDropdown().props('text')).toBe('configured-agent');
- expect(findConfiguredAgentItem().props('isChecked')).toBe(true);
+ expect(findFirstAgentItem().props('isChecked')).toBe(true);
+ });
+ });
+
+ describe('create new agent configuration', () => {
+ beforeEach(async () => {
+ await findSearchInput().vm.$emit('input', 'new-agent');
+ findCreateButton().vm.$emit('click');
+ });
+
+ it('emits agentSelected with the name of the clicked agent', () => {
+ expect(wrapper.emitted('agentSelected')).toEqual([['new-agent']]);
+ });
+
+ it('marks the clicked item as selected', () => {
+ expect(findDropdown().props('text')).toBe('new-agent');
});
});
});
diff --git a/spec/frontend/clusters_list/components/clusters_actions_spec.js b/spec/frontend/clusters_list/components/clusters_actions_spec.js
index 331690fc642..312df12ab5f 100644
--- a/spec/frontend/clusters_list/components/clusters_actions_spec.js
+++ b/spec/frontend/clusters_list/components/clusters_actions_spec.js
@@ -1,4 +1,4 @@
-import { GlDropdown, GlDropdownItem } from '@gitlab/ui';
+import { GlDropdown, GlDropdownItem, GlButton } from '@gitlab/ui';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import ClustersActions from '~/clusters_list/components/clusters_actions.vue';
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
@@ -14,13 +14,18 @@ describe('ClustersActionsComponent', () => {
newClusterPath,
addClusterPath,
canAddCluster: true,
+ displayClusterAgents: true,
+ certificateBasedClustersEnabled: true,
};
const findDropdown = () => wrapper.findComponent(GlDropdown);
const findDropdownItems = () => wrapper.findAllComponents(GlDropdownItem);
+ const findDropdownItemIds = () =>
+ findDropdownItems().wrappers.map((x) => x.attributes('data-testid'));
const findNewClusterLink = () => wrapper.findByTestId('new-cluster-link');
const findConnectClusterLink = () => wrapper.findByTestId('connect-cluster-link');
const findConnectNewAgentLink = () => wrapper.findByTestId('connect-new-agent-link');
+ const findConnectWithAgentButton = () => wrapper.findComponent(GlButton);
const createWrapper = (provideData = {}) => {
wrapper = shallowMountExtended(ClustersActions, {
@@ -42,43 +47,110 @@ describe('ClustersActionsComponent', () => {
afterEach(() => {
wrapper.destroy();
});
+ describe('when the certificate based clusters are enabled', () => {
+ it('renders actions menu', () => {
+ expect(findDropdown().props('text')).toBe(CLUSTERS_ACTIONS.actionsButton);
+ });
- it('renders actions menu', () => {
- expect(findDropdown().props('text')).toBe(CLUSTERS_ACTIONS.actionsButton);
- });
+ it('renders correct href attributes for the links', () => {
+ expect(findNewClusterLink().attributes('href')).toBe(newClusterPath);
+ expect(findConnectClusterLink().attributes('href')).toBe(addClusterPath);
+ });
- it('renders a dropdown with 3 actions items', () => {
- expect(findDropdownItems()).toHaveLength(3);
- });
+ describe('when user cannot add clusters', () => {
+ beforeEach(() => {
+ createWrapper({ canAddCluster: false });
+ });
- it('renders correct href attributes for the links', () => {
- expect(findNewClusterLink().attributes('href')).toBe(newClusterPath);
- expect(findConnectClusterLink().attributes('href')).toBe(addClusterPath);
- });
+ it('disables dropdown', () => {
+ expect(findDropdown().props('disabled')).toBe(true);
+ });
- it('renders correct modal id for the agent link', () => {
- const binding = getBinding(findConnectNewAgentLink().element, 'gl-modal-directive');
+ it('shows tooltip explaining why dropdown is disabled', () => {
+ const tooltip = getBinding(findDropdown().element, 'gl-tooltip');
+ expect(tooltip.value).toBe(CLUSTERS_ACTIONS.dropdownDisabledHint);
+ });
- expect(binding.value).toBe(INSTALL_AGENT_MODAL_ID);
- });
+ it('does not bind split dropdown button', () => {
+ const binding = getBinding(findDropdown().element, 'gl-modal-directive');
+
+ expect(binding.value).toBe(false);
+ });
+ });
+
+ describe('when on project level', () => {
+ it('renders a dropdown with 3 actions items', () => {
+ expect(findDropdownItemIds()).toEqual([
+ 'connect-new-agent-link',
+ 'new-cluster-link',
+ 'connect-cluster-link',
+ ]);
+ });
+
+ it('renders correct modal id for the agent link', () => {
+ const binding = getBinding(findConnectNewAgentLink().element, 'gl-modal-directive');
+
+ expect(binding.value).toBe(INSTALL_AGENT_MODAL_ID);
+ });
- it('shows tooltip', () => {
- const tooltip = getBinding(findDropdown().element, 'gl-tooltip');
- expect(tooltip.value).toBe(CLUSTERS_ACTIONS.connectWithAgent);
+ it('shows tooltip', () => {
+ const tooltip = getBinding(findDropdown().element, 'gl-tooltip');
+ expect(tooltip.value).toBe(CLUSTERS_ACTIONS.connectWithAgent);
+ });
+
+ it('shows split button in dropdown', () => {
+ expect(findDropdown().props('split')).toBe(true);
+ });
+
+ it('binds split button with modal id', () => {
+ const binding = getBinding(findDropdown().element, 'gl-modal-directive');
+
+ expect(binding.value).toBe(INSTALL_AGENT_MODAL_ID);
+ });
+ });
+
+ describe('when on group or admin level', () => {
+ beforeEach(() => {
+ createWrapper({ displayClusterAgents: false });
+ });
+
+ it('renders a dropdown with 2 actions items', () => {
+ expect(findDropdownItemIds()).toEqual(['new-cluster-link', 'connect-cluster-link']);
+ });
+
+ it('shows tooltip', () => {
+ const tooltip = getBinding(findDropdown().element, 'gl-tooltip');
+ expect(tooltip.value).toBe(CLUSTERS_ACTIONS.connectExistingCluster);
+ });
+
+ it('does not show split button in dropdown', () => {
+ expect(findDropdown().props('split')).toBe(false);
+ });
+
+ it('does not bind dropdown button to modal', () => {
+ const binding = getBinding(findDropdown().element, 'gl-modal-directive');
+
+ expect(binding.value).toBe(false);
+ });
+ });
});
- describe('when user cannot add clusters', () => {
+ describe('when the certificate based clusters not enabled', () => {
beforeEach(() => {
- createWrapper({ canAddCluster: false });
+ createWrapper({ certificateBasedClustersEnabled: false });
});
- it('disables dropdown', () => {
- expect(findDropdown().props('disabled')).toBe(true);
+ it('it does not show the the dropdown', () => {
+ expect(findDropdown().exists()).toBe(false);
});
- it('shows tooltip explaining why dropdown is disabled', () => {
- const tooltip = getBinding(findDropdown().element, 'gl-tooltip');
- expect(tooltip.value).toBe(CLUSTERS_ACTIONS.dropdownDisabledHint);
+ it('shows the connect with agent button', () => {
+ expect(findConnectWithAgentButton().props()).toMatchObject({
+ disabled: !defaultProvide.canAddCluster,
+ category: 'primary',
+ variant: 'confirm',
+ });
+ expect(findConnectWithAgentButton().text()).toBe(CLUSTERS_ACTIONS.connectWithAgent);
});
});
});
diff --git a/spec/frontend/clusters_list/components/clusters_empty_state_spec.js b/spec/frontend/clusters_list/components/clusters_empty_state_spec.js
index cf0f6881960..fe2189296a6 100644
--- a/spec/frontend/clusters_list/components/clusters_empty_state_spec.js
+++ b/spec/frontend/clusters_list/components/clusters_empty_state_spec.js
@@ -4,7 +4,7 @@ import ClustersEmptyState from '~/clusters_list/components/clusters_empty_state.
import ClusterStore from '~/clusters_list/store';
const clustersEmptyStateImage = 'path/to/svg';
-const newClusterPath = '/path/to/connect/cluster';
+const addClusterPath = '/path/to/connect/cluster';
const emptyStateHelpText = 'empty state text';
describe('ClustersEmptyStateComponent', () => {
@@ -12,7 +12,7 @@ describe('ClustersEmptyStateComponent', () => {
const defaultProvideData = {
clustersEmptyStateImage,
- newClusterPath,
+ addClusterPath,
};
const findButton = () => wrapper.findComponent(GlButton);
diff --git a/spec/frontend/clusters_list/components/clusters_main_view_spec.js b/spec/frontend/clusters_list/components/clusters_main_view_spec.js
index 37665bf7abd..218463b9adf 100644
--- a/spec/frontend/clusters_list/components/clusters_main_view_spec.js
+++ b/spec/frontend/clusters_list/components/clusters_main_view_spec.js
@@ -6,7 +6,9 @@ import InstallAgentModal from '~/clusters_list/components/install_agent_modal.vu
import {
AGENT,
CERTIFICATE_BASED,
+ AGENT_TAB,
CLUSTERS_TABS,
+ CERTIFICATE_TAB,
MAX_CLUSTERS_LIST,
MAX_LIST_COUNT,
EVENT_LABEL_TABS,
@@ -23,12 +25,20 @@ describe('ClustersMainViewComponent', () => {
defaultBranchName,
};
- beforeEach(() => {
+ const defaultProvide = {
+ certificateBasedClustersEnabled: true,
+ displayClusterAgents: true,
+ };
+
+ const createWrapper = (extendedProvide = {}) => {
wrapper = shallowMountExtended(ClustersMainView, {
propsData,
+ provide: {
+ ...defaultProvide,
+ ...extendedProvide,
+ },
});
- trackingSpy = mockTracking(undefined, wrapper.element, jest.spyOn);
- });
+ };
afterEach(() => {
wrapper.destroy();
@@ -39,57 +49,110 @@ describe('ClustersMainViewComponent', () => {
const findGlTabAtIndex = (index) => findAllTabs().at(index);
const findComponent = () => wrapper.findByTestId('clusters-tab-component');
const findModal = () => wrapper.findComponent(InstallAgentModal);
+ describe('when the certificate based clusters are enabled', () => {
+ describe('when on project level', () => {
+ beforeEach(() => {
+ createWrapper({ displayClusterAgents: true });
+ trackingSpy = mockTracking(undefined, wrapper.element, jest.spyOn);
+ });
- it('renders `GlTabs` with `syncActiveTabWithQueryParams` and `queryParamName` props set', () => {
- expect(findTabs().exists()).toBe(true);
- expect(findTabs().props('syncActiveTabWithQueryParams')).toBe(true);
- });
+ it('renders `GlTabs` with `syncActiveTabWithQueryParams` and `queryParamName` props set', () => {
+ expect(findTabs().exists()).toBe(true);
+ expect(findTabs().props('syncActiveTabWithQueryParams')).toBe(true);
+ });
- it('renders correct number of tabs', () => {
- expect(findAllTabs()).toHaveLength(CLUSTERS_TABS.length);
- });
+ it('renders correct number of tabs', () => {
+ expect(findAllTabs()).toHaveLength(CLUSTERS_TABS.length);
+ });
- it('passes child-component param to the component', () => {
- expect(findComponent().props('defaultBranchName')).toBe(defaultBranchName);
- });
+ describe('tabs', () => {
+ it.each`
+ tabTitle | queryParamValue | lineNumber
+ ${'All'} | ${'all'} | ${0}
+ ${'Agent'} | ${AGENT} | ${1}
+ ${'Certificate'} | ${CERTIFICATE_BASED} | ${2}
+ `(
+ 'renders correct tab title and query param value',
+ ({ tabTitle, queryParamValue, lineNumber }) => {
+ expect(findGlTabAtIndex(lineNumber).attributes('title')).toBe(tabTitle);
+ expect(findGlTabAtIndex(lineNumber).props('queryParamValue')).toBe(queryParamValue);
+ },
+ );
+ });
- it('passes correct max-agents param to the modal', () => {
- expect(findModal().props('maxAgents')).toBe(MAX_CLUSTERS_LIST);
- });
+ describe.each`
+ tab | tabName
+ ${'1'} | ${AGENT}
+ ${'2'} | ${CERTIFICATE_BASED}
+ `(
+ 'when the child component emits the tab change event for $tabName tab',
+ ({ tab, tabName }) => {
+ beforeEach(() => {
+ findComponent().vm.$emit('changeTab', tabName);
+ });
- describe('tabs', () => {
- it.each`
- tabTitle | queryParamValue | lineNumber
- ${'All'} | ${'all'} | ${0}
- ${'Agent'} | ${AGENT} | ${1}
- ${'Certificate'} | ${CERTIFICATE_BASED} | ${2}
- `(
- 'renders correct tab title and query param value',
- ({ tabTitle, queryParamValue, lineNumber }) => {
- expect(findGlTabAtIndex(lineNumber).attributes('title')).toBe(tabTitle);
- expect(findGlTabAtIndex(lineNumber).props('queryParamValue')).toBe(queryParamValue);
- },
- );
- });
+ it(`changes the tab value to ${tab}`, () => {
+ expect(findTabs().attributes('value')).toBe(tab);
+ });
+ },
+ );
- describe('when the child component emits the tab change event', () => {
- beforeEach(() => {
- findComponent().vm.$emit('changeTab', AGENT);
- });
+ describe.each`
+ tab | tabName | maxAgents
+ ${1} | ${AGENT} | ${MAX_LIST_COUNT}
+ ${2} | ${CERTIFICATE_BASED} | ${MAX_CLUSTERS_LIST}
+ `('when the active tab is $tabName', ({ tab, tabName, maxAgents }) => {
+ beforeEach(() => {
+ findTabs().vm.$emit('input', tab);
+ });
+
+ it('passes child-component param to the component', () => {
+ expect(findComponent().props('defaultBranchName')).toBe(defaultBranchName);
+ });
+
+ it(`sets max-agents param to ${maxAgents} and passes it to the modal`, () => {
+ expect(findModal().props('maxAgents')).toBe(maxAgents);
+ });
- it('changes the tab', () => {
- expect(findTabs().attributes('value')).toBe('1');
+ it(`sends the correct tracking event with the property '${tabName}'`, () => {
+ expect(trackingSpy).toHaveBeenCalledWith(undefined, EVENT_ACTIONS_CHANGE, {
+ label: EVENT_LABEL_TABS,
+ property: tabName,
+ });
+ });
+ });
});
- it('passes correct max-agents param to the modal', () => {
- expect(findModal().props('maxAgents')).toBe(MAX_LIST_COUNT);
+ describe('when on group or admin level', () => {
+ beforeEach(() => {
+ createWrapper({ displayClusterAgents: false });
+ });
+
+ it('renders correct number of tabs', () => {
+ expect(findAllTabs()).toHaveLength(1);
+ });
+
+ it('renders correct tab title', () => {
+ expect(findGlTabAtIndex(0).attributes('title')).toBe(CERTIFICATE_TAB.title);
+ });
});
- it('sends the correct tracking event', () => {
- findTabs().vm.$emit('input', 1);
- expect(trackingSpy).toHaveBeenCalledWith(undefined, EVENT_ACTIONS_CHANGE, {
- label: EVENT_LABEL_TABS,
- property: AGENT,
+ describe('when the certificate based clusters not enabled', () => {
+ beforeEach(() => {
+ createWrapper({ certificateBasedClustersEnabled: false });
+ });
+
+ it('it displays only the Agent tab', () => {
+ expect(findAllTabs()).toHaveLength(1);
+ const agentTab = findGlTabAtIndex(0);
+
+ expect(agentTab.props()).toMatchObject({
+ queryParamValue: AGENT_TAB.queryParamValue,
+ titleLinkClass: '',
+ });
+ expect(agentTab.attributes()).toMatchObject({
+ title: AGENT_TAB.title,
+ });
});
});
});
diff --git a/spec/frontend/clusters_list/components/clusters_spec.js b/spec/frontend/clusters_list/components/clusters_spec.js
index 82e667093aa..3f3f5e0daf6 100644
--- a/spec/frontend/clusters_list/components/clusters_spec.js
+++ b/spec/frontend/clusters_list/components/clusters_spec.js
@@ -2,7 +2,7 @@ import {
GlLoadingIcon,
GlPagination,
GlDeprecatedSkeletonLoading as GlSkeletonLoading,
- GlTable,
+ GlTableLite,
} from '@gitlab/ui';
import * as Sentry from '@sentry/browser';
import { mount } from '@vue/test-utils';
@@ -23,7 +23,7 @@ describe('Clusters', () => {
const totalClustersNumber = 6;
const clustersEmptyStateImage = 'path/to/svg';
const emptyStateHelpText = null;
- const newClusterPath = '/path/to/new/cluster';
+ const addClusterPath = '/path/to/new/cluster';
const entryData = {
endpoint,
@@ -36,12 +36,12 @@ describe('Clusters', () => {
const provideData = {
clustersEmptyStateImage,
emptyStateHelpText,
- newClusterPath,
+ addClusterPath,
};
const findLoader = () => wrapper.findComponent(GlLoadingIcon);
const findPaginatedButtons = () => wrapper.findComponent(GlPagination);
- const findTable = () => wrapper.findComponent(GlTable);
+ const findTable = () => wrapper.findComponent(GlTableLite);
const findStatuses = () => findTable().findAll('.js-status');
const findEmptyState = () => wrapper.findComponent(ClustersEmptyState);
@@ -51,7 +51,7 @@ describe('Clusters', () => {
const createWrapper = ({ propsData = {} }) => {
store = ClusterStore(entryData);
- wrapper = mount(Clusters, { propsData, provide: provideData, store, stubs: { GlTable } });
+ wrapper = mount(Clusters, { propsData, provide: provideData, store, stubs: { GlTableLite } });
return axios.waitForAll();
};
diff --git a/spec/frontend/clusters_list/components/install_agent_modal_spec.js b/spec/frontend/clusters_list/components/install_agent_modal_spec.js
index 37432ed0193..38f653509a8 100644
--- a/spec/frontend/clusters_list/components/install_agent_modal_spec.js
+++ b/spec/frontend/clusters_list/components/install_agent_modal_spec.js
@@ -6,6 +6,7 @@ import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import { mockTracking } from 'helpers/tracking_helper';
import AvailableAgentsDropdown from '~/clusters_list/components/available_agents_dropdown.vue';
import InstallAgentModal from '~/clusters_list/components/install_agent_modal.vue';
+import AgentToken from '~/clusters_list/components/agent_token.vue';
import {
I18N_AGENT_MODAL,
MAX_LIST_COUNT,
@@ -21,7 +22,6 @@ import createAgentMutation from '~/clusters_list/graphql/mutations/create_agent.
import createAgentTokenMutation from '~/clusters_list/graphql/mutations/create_agent_token.mutation.graphql';
import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises';
-import CodeBlock from '~/vue_shared/components/code_block.vue';
import {
createAgentResponse,
createAgentErrorResponse,
@@ -39,6 +39,7 @@ const kasAddress = 'kas.example.com';
const emptyStateImage = 'path/to/image';
const defaultBranchName = 'default';
const maxAgents = MAX_LIST_COUNT;
+const i18n = I18N_AGENT_MODAL;
describe('InstallAgentModal', () => {
let wrapper;
@@ -60,6 +61,7 @@ describe('InstallAgentModal', () => {
const findModal = () => wrapper.findComponent(ModalStub);
const findAgentDropdown = () => findModal().findComponent(AvailableAgentsDropdown);
const findAlert = () => findModal().findComponent(GlAlert);
+ const findAgentInstructions = () => findModal().findComponent(AgentToken);
const findButtonByVariant = (variant) =>
findModal()
.findAll(GlButton)
@@ -67,7 +69,7 @@ describe('InstallAgentModal', () => {
const findActionButton = () => findButtonByVariant('confirm');
const findCancelButton = () => findButtonByVariant('default');
const findPrimaryButton = () => wrapper.findByTestId('agent-primary-button');
- const findImage = () => wrapper.findByRole('img', { alt: I18N_AGENT_MODAL.empty_state.altText });
+ const findImage = () => wrapper.findByRole('img', { alt: i18n.altText });
const expectDisabledAttribute = (element, disabled) => {
if (disabled) {
@@ -140,16 +142,16 @@ describe('InstallAgentModal', () => {
apolloProvider = null;
});
- describe('when agent configurations are present', () => {
- const i18n = I18N_AGENT_MODAL.agent_registration;
-
+ describe('when KAS is enabled', () => {
describe('initial state', () => {
it('renders the dropdown for available agents', () => {
expect(findAgentDropdown().isVisible()).toBe(true);
+ });
+
+ it("doesn't render agent installation instructions", () => {
expect(findModal().text()).not.toContain(i18n.basicInstallTitle);
expect(findModal().findComponent(GlFormInputGroup).exists()).toBe(false);
expect(findModal().findComponent(GlAlert).exists()).toBe(false);
- expect(findModal().findComponent(CodeBlock).exists()).toBe(false);
});
it('renders a cancel button', () => {
@@ -220,19 +222,7 @@ describe('InstallAgentModal', () => {
});
it('shows agent instructions', () => {
- const modalText = findModal().text();
- expect(modalText).toContain(i18n.basicInstallTitle);
- expect(modalText).toContain(i18n.basicInstallBody);
-
- const token = findModal().findComponent(GlFormInputGroup);
- expect(token.props('value')).toBe('mock-agent-token');
-
- const alert = findModal().findComponent(GlAlert);
- expect(alert.props('title')).toBe(i18n.tokenSingleUseWarningTitle);
-
- const code = findModal().findComponent(CodeBlock).props('code');
- expect(code).toContain('--agent-token=mock-agent-token');
- expect(code).toContain('--kas-address=kas.example.com');
+ expect(findAgentInstructions().exists()).toBe(true);
});
describe('error creating agent', () => {
@@ -272,44 +262,7 @@ describe('InstallAgentModal', () => {
});
});
- describe('when there are no agent configurations present', () => {
- const i18n = I18N_AGENT_MODAL.empty_state;
- const apolloQueryEmptyResponse = {
- data: {
- project: {
- clusterAgents: { nodes: [] },
- agentConfigurations: { nodes: [] },
- },
- },
- };
-
- beforeEach(() => {
- apolloProvider = createMockApollo([
- [getAgentConfigurations, jest.fn().mockResolvedValue(apolloQueryEmptyResponse)],
- ]);
- createWrapper();
- });
-
- it('renders empty state image', () => {
- expect(findImage().attributes('src')).toBe(emptyStateImage);
- });
-
- it('renders a primary button', () => {
- expect(findPrimaryButton().isVisible()).toBe(true);
- expect(findPrimaryButton().text()).toBe(i18n.primaryButton);
- });
-
- it('sends the event with the modalType', () => {
- findModal().vm.$emit('show');
- expect(trackingSpy).toHaveBeenCalledWith(undefined, EVENT_ACTIONS_OPEN, {
- label: EVENT_LABEL_MODAL,
- property: MODAL_TYPE_EMPTY,
- });
- });
- });
-
describe('when KAS is disabled', () => {
- const i18n = I18N_AGENT_MODAL.empty_state;
beforeEach(async () => {
apolloProvider = createMockApollo([
[getAgentConfigurations, jest.fn().mockResolvedValue(kasDisabledErrorResponse)],
@@ -331,11 +284,19 @@ describe('InstallAgentModal', () => {
it('renders a cancel button', () => {
expect(findCancelButton().isVisible()).toBe(true);
- expect(findCancelButton().text()).toBe(i18n.done);
+ expect(findCancelButton().text()).toBe(i18n.close);
});
it("doesn't render a secondary button", () => {
expect(findPrimaryButton().exists()).toBe(false);
});
+
+ it('sends the event with the modalType', () => {
+ findModal().vm.$emit('show');
+ expect(trackingSpy).toHaveBeenCalledWith(undefined, EVENT_ACTIONS_OPEN, {
+ label: EVENT_LABEL_MODAL,
+ property: MODAL_TYPE_EMPTY,
+ });
+ });
});
});
diff --git a/spec/frontend/code_navigation/components/app_spec.js b/spec/frontend/code_navigation/components/app_spec.js
index 9306c15e676..0d7c0360e9b 100644
--- a/spec/frontend/code_navigation/components/app_spec.js
+++ b/spec/frontend/code_navigation/components/app_spec.js
@@ -5,13 +5,14 @@ import App from '~/code_navigation/components/app.vue';
import Popover from '~/code_navigation/components/popover.vue';
import createState from '~/code_navigation/store/state';
+const setInitialData = jest.fn();
const fetchData = jest.fn();
const showDefinition = jest.fn();
let wrapper;
Vue.use(Vuex);
-function factory(initialState = {}) {
+function factory(initialState = {}, props = {}) {
const store = new Vuex.Store({
state: {
...createState(),
@@ -19,12 +20,13 @@ function factory(initialState = {}) {
definitionPathPrefix: 'https://test.com/blob/main',
},
actions: {
+ setInitialData,
fetchData,
showDefinition,
},
});
- wrapper = shallowMount(App, { store });
+ wrapper = shallowMount(App, { store, propsData: { ...props } });
}
describe('Code navigation app component', () => {
@@ -32,6 +34,19 @@ describe('Code navigation app component', () => {
wrapper.destroy();
});
+ it('sets initial data on mount if the correct props are passed', () => {
+ const codeNavigationPath = 'code/nav/path.js';
+ const path = 'blob/path.js';
+ const definitionPathPrefix = 'path/prefix';
+
+ factory({}, { codeNavigationPath, blobPath: path, pathPrefix: definitionPathPrefix });
+
+ expect(setInitialData).toHaveBeenCalledWith(expect.anything(), {
+ blobs: [{ codeNavigationPath, path }],
+ definitionPathPrefix,
+ });
+ });
+
it('fetches data on mount', () => {
factory();
diff --git a/spec/frontend/code_quality_walkthrough/components/__snapshots__/step_spec.js.snap b/spec/frontend/code_quality_walkthrough/components/__snapshots__/step_spec.js.snap
deleted file mode 100644
index f17d99ad257..00000000000
--- a/spec/frontend/code_quality_walkthrough/components/__snapshots__/step_spec.js.snap
+++ /dev/null
@@ -1,174 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`When the code_quality_walkthrough URL parameter is present Code Quality Walkthrough Step component commit_ci_file step renders a popover 1`] = `
-<div>
- <gl-popover-stub
- container="viewport"
- cssclasses=""
- offset="90"
- placement="right"
- show=""
- target="#js-code-quality-walkthrough"
- triggers="manual"
- >
-
- <gl-sprintf-stub
- message="To begin with code quality, we first need to create a new CI file using our code editor. We added a code quality template in the code editor to help you get started %{emojiStart}wink%{emojiEnd} .%{lineBreak}Take some time to review the template, when you are ready, use the %{strongStart}commit changes%{strongEnd} button at the bottom of the page."
- />
-
- <div
- class="gl-mt-2 gl-text-right"
- >
- <gl-button-stub
- buttontextclasses=""
- category="tertiary"
- href=""
- icon=""
- size="medium"
- variant="link"
- >
-
- Got it
-
- </gl-button-stub>
- </div>
- </gl-popover-stub>
-
- <!---->
-</div>
-`;
-
-exports[`When the code_quality_walkthrough URL parameter is present Code Quality Walkthrough Step component failed_pipeline step renders a popover 1`] = `
-<div>
- <gl-popover-stub
- container="viewport"
- cssclasses=""
- offset="98"
- placement="bottom"
- show=""
- target="#js-code-quality-walkthrough"
- triggers="manual"
- >
-
- <gl-sprintf-stub
- message="Your job failed. No worries - this happens. Let's view the logs, and see how we can fix it."
- />
-
- <div
- class="gl-mt-2 gl-text-right"
- >
- <gl-button-stub
- buttontextclasses=""
- category="tertiary"
- href="/group/project/-/jobs/:id?code_quality_walkthrough=true"
- icon=""
- size="medium"
- variant="link"
- >
-
- View the logs
-
- </gl-button-stub>
- </div>
- </gl-popover-stub>
-
- <!---->
-</div>
-`;
-
-exports[`When the code_quality_walkthrough URL parameter is present Code Quality Walkthrough Step component running_pipeline step renders a popover 1`] = `
-<div>
- <gl-popover-stub
- container="viewport"
- cssclasses=""
- offset="97"
- placement="bottom"
- show=""
- target="#js-code-quality-walkthrough"
- triggers="manual"
- >
-
- <gl-sprintf-stub
- message="Your pipeline can take a few minutes to run. If you enabled email notifications, you'll receive an email with your pipeline status. In the meantime, why don't you get some coffee? You earned it!"
- />
-
- <div
- class="gl-mt-2 gl-text-right"
- >
- <gl-button-stub
- buttontextclasses=""
- category="tertiary"
- href=""
- icon=""
- size="medium"
- variant="link"
- >
-
- Got it
-
- </gl-button-stub>
- </div>
- </gl-popover-stub>
-
- <!---->
-</div>
-`;
-
-exports[`When the code_quality_walkthrough URL parameter is present Code Quality Walkthrough Step component success_pipeline step renders a popover 1`] = `
-<div>
- <gl-popover-stub
- container="viewport"
- cssclasses=""
- offset="98"
- placement="bottom"
- show=""
- target="#js-code-quality-walkthrough"
- triggers="manual"
- >
-
- <gl-sprintf-stub
- message="A code quality job will now run every time you or your team members commit changes to your project. You can view the results of the code quality job in the job logs."
- />
-
- <div
- class="gl-mt-2 gl-text-right"
- >
- <gl-button-stub
- buttontextclasses=""
- category="tertiary"
- href="/group/project/-/jobs/:id?code_quality_walkthrough=true"
- icon=""
- size="medium"
- variant="link"
- >
-
- View the logs
-
- </gl-button-stub>
- </div>
- </gl-popover-stub>
-
- <!---->
-</div>
-`;
-
-exports[`When the code_quality_walkthrough URL parameter is present Code Quality Walkthrough Step component troubleshoot_job step renders an alert 1`] = `
-<div>
- <!---->
-
- <gl-alert-stub
- class="gl-my-5"
- dismissible="true"
- dismisslabel="Dismiss"
- primarybuttontext="Read the documentation"
- secondarybuttonlink=""
- secondarybuttontext=""
- title="Troubleshoot your code quality job"
- variant="tip"
- >
-
- Not sure how to fix your failed job? We have compiled some tips on how to troubleshoot code quality jobs in the documentation.
-
- </gl-alert-stub>
-</div>
-`;
diff --git a/spec/frontend/code_quality_walkthrough/components/step_spec.js b/spec/frontend/code_quality_walkthrough/components/step_spec.js
deleted file mode 100644
index b43629c2f96..00000000000
--- a/spec/frontend/code_quality_walkthrough/components/step_spec.js
+++ /dev/null
@@ -1,156 +0,0 @@
-import { GlButton, GlPopover } from '@gitlab/ui';
-import { shallowMount } from '@vue/test-utils';
-import Cookies from 'js-cookie';
-import Step from '~/code_quality_walkthrough/components/step.vue';
-import { EXPERIMENT_NAME, STEPS } from '~/code_quality_walkthrough/constants';
-import { TRACKING_CONTEXT_SCHEMA } from '~/experimentation/constants';
-import { getParameterByName } from '~/lib/utils/url_utility';
-import Tracking from '~/tracking';
-
-jest.mock('~/lib/utils/url_utility', () => ({
- ...jest.requireActual('~/lib/utils/url_utility'),
- getParameterByName: jest.fn(),
-}));
-
-let wrapper;
-
-function factory({ step, link }) {
- wrapper = shallowMount(Step, {
- propsData: { step, link },
- });
-}
-
-afterEach(() => {
- wrapper.destroy();
-});
-
-const dummyLink = '/group/project/-/jobs/:id?code_quality_walkthrough=true';
-const dummyContext = 'experiment_context';
-
-const findButton = () => wrapper.findComponent(GlButton);
-const findPopover = () => wrapper.findComponent(GlPopover);
-
-describe('When the code_quality_walkthrough URL parameter is missing', () => {
- beforeEach(() => {
- getParameterByName.mockReturnValue(false);
- });
-
- it('does not render the component', () => {
- factory({
- step: STEPS.commitCiFile,
- });
-
- expect(findPopover().exists()).toBe(false);
- });
-});
-
-describe('When the code_quality_walkthrough URL parameter is present', () => {
- beforeEach(() => {
- getParameterByName.mockReturnValue(true);
- Cookies.set(EXPERIMENT_NAME, { data: dummyContext });
- });
-
- afterEach(() => {
- Cookies.remove(EXPERIMENT_NAME);
- });
-
- describe('When mounting the component', () => {
- beforeEach(() => {
- jest.spyOn(Tracking, 'event');
-
- factory({
- step: STEPS.commitCiFile,
- });
- });
-
- it('tracks an event', () => {
- expect(Tracking.event).toHaveBeenCalledWith(
- EXPERIMENT_NAME,
- `${STEPS.commitCiFile}_displayed`,
- {
- context: {
- schema: TRACKING_CONTEXT_SCHEMA,
- data: dummyContext,
- },
- },
- );
- });
- });
-
- describe('When updating the component', () => {
- beforeEach(() => {
- factory({
- step: STEPS.runningPipeline,
- });
-
- jest.spyOn(Tracking, 'event');
-
- wrapper.setProps({ step: STEPS.successPipeline });
- });
-
- it('tracks an event', () => {
- expect(Tracking.event).toHaveBeenCalledWith(
- EXPERIMENT_NAME,
- `${STEPS.successPipeline}_displayed`,
- {
- context: {
- schema: TRACKING_CONTEXT_SCHEMA,
- data: dummyContext,
- },
- },
- );
- });
- });
-
- describe('When dismissing a popover', () => {
- beforeEach(() => {
- factory({
- step: STEPS.commitCiFile,
- });
-
- jest.spyOn(Cookies, 'set');
- jest.spyOn(Tracking, 'event');
-
- findButton().vm.$emit('click');
- });
-
- it('sets a cookie', () => {
- expect(Cookies.set).toHaveBeenCalledWith(
- EXPERIMENT_NAME,
- { commit_ci_file: true, data: dummyContext },
- { expires: 365, secure: false },
- );
- });
-
- it('removes the popover', () => {
- expect(findPopover().exists()).toBe(false);
- });
-
- it('tracks an event', () => {
- expect(Tracking.event).toHaveBeenCalledWith(
- EXPERIMENT_NAME,
- `${STEPS.commitCiFile}_dismissed`,
- {
- context: {
- schema: TRACKING_CONTEXT_SCHEMA,
- data: dummyContext,
- },
- },
- );
- });
- });
-
- describe('Code Quality Walkthrough Step component', () => {
- describe.each(Object.values(STEPS))('%s step', (step) => {
- it(`renders ${step === STEPS.troubleshootJob ? 'an alert' : 'a popover'}`, () => {
- const options = { step };
- if ([STEPS.successPipeline, STEPS.failedPipeline].includes(step)) {
- options.link = dummyLink;
- }
- factory(options);
-
- expect(wrapper.element).toMatchSnapshot();
- });
- });
- });
-});
diff --git a/spec/frontend/content_editor/components/content_editor_alert_spec.js b/spec/frontend/content_editor/components/content_editor_alert_spec.js
index 2ddcd8f024e..12484cb13c6 100644
--- a/spec/frontend/content_editor/components/content_editor_alert_spec.js
+++ b/spec/frontend/content_editor/components/content_editor_alert_spec.js
@@ -3,20 +3,25 @@ import { nextTick } from 'vue';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import ContentEditorAlert from '~/content_editor/components/content_editor_alert.vue';
import EditorStateObserver from '~/content_editor/components/editor_state_observer.vue';
-import { createTestEditor, emitEditorEvent } from '../test_utils';
+import eventHubFactory from '~/helpers/event_hub_factory';
+import { ALERT_EVENT } from '~/content_editor/constants';
+import { createTestEditor } from '../test_utils';
describe('content_editor/components/content_editor_alert', () => {
let wrapper;
let tiptapEditor;
+ let eventHub;
const findErrorAlert = () => wrapper.findComponent(GlAlert);
const createWrapper = async () => {
tiptapEditor = createTestEditor();
+ eventHub = eventHubFactory();
wrapper = shallowMountExtended(ContentEditorAlert, {
provide: {
tiptapEditor,
+ eventHub,
},
stubs: {
EditorStateObserver,
@@ -37,7 +42,9 @@ describe('content_editor/components/content_editor_alert', () => {
async ({ message, variant }) => {
createWrapper();
- await emitEditorEvent({ tiptapEditor, event: 'alert', params: { message, variant } });
+ eventHub.$emit(ALERT_EVENT, { message, variant });
+
+ await nextTick();
expect(findErrorAlert().text()).toBe(message);
expect(findErrorAlert().attributes().variant).toBe(variant);
@@ -48,11 +55,9 @@ describe('content_editor/components/content_editor_alert', () => {
const message = 'error message';
createWrapper();
-
- await emitEditorEvent({ tiptapEditor, event: 'alert', params: { message } });
-
+ eventHub.$emit(ALERT_EVENT, { message });
+ await nextTick();
findErrorAlert().vm.$emit('dismiss');
-
await nextTick();
expect(findErrorAlert().exists()).toBe(false);
diff --git a/spec/frontend/content_editor/components/content_editor_spec.js b/spec/frontend/content_editor/components/content_editor_spec.js
index 9a772c41e52..73fcfeab8bc 100644
--- a/spec/frontend/content_editor/components/content_editor_spec.js
+++ b/spec/frontend/content_editor/components/content_editor_spec.js
@@ -1,6 +1,4 @@
-import { GlLoadingIcon } from '@gitlab/ui';
import { EditorContent } from '@tiptap/vue-2';
-import { nextTick } from 'vue';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import ContentEditor from '~/content_editor/components/content_editor.vue';
import ContentEditorAlert from '~/content_editor/components/content_editor_alert.vue';
@@ -8,11 +6,7 @@ import ContentEditorProvider from '~/content_editor/components/content_editor_pr
import EditorStateObserver from '~/content_editor/components/editor_state_observer.vue';
import FormattingBubbleMenu from '~/content_editor/components/formatting_bubble_menu.vue';
import TopToolbar from '~/content_editor/components/top_toolbar.vue';
-import {
- LOADING_CONTENT_EVENT,
- LOADING_SUCCESS_EVENT,
- LOADING_ERROR_EVENT,
-} from '~/content_editor/constants';
+import LoadingIndicator from '~/content_editor/components/loading_indicator.vue';
import { emitEditorEvent } from '../test_utils';
jest.mock('~/emoji');
@@ -25,9 +19,6 @@ describe('ContentEditor', () => {
const findEditorElement = () => wrapper.findByTestId('content-editor');
const findEditorContent = () => wrapper.findComponent(EditorContent);
- const findLoadingIcon = () => wrapper.findComponent(GlLoadingIcon);
- const findBubbleMenu = () => wrapper.findComponent(FormattingBubbleMenu);
-
const createWrapper = (propsData = {}) => {
renderMarkdown = jest.fn();
@@ -117,69 +108,15 @@ describe('ContentEditor', () => {
expect(wrapper.findComponent(ContentEditorAlert).exists()).toBe(true);
});
- describe('when loading content', () => {
- beforeEach(async () => {
- createWrapper();
-
- contentEditor.emit(LOADING_CONTENT_EVENT);
-
- await nextTick();
- });
-
- it('displays loading indicator', () => {
- expect(findLoadingIcon().exists()).toBe(true);
- });
-
- it('hides EditorContent component', () => {
- expect(findEditorContent().exists()).toBe(false);
- });
-
- it('hides formatting bubble menu', () => {
- expect(findBubbleMenu().exists()).toBe(false);
- });
- });
-
- describe('when loading content succeeds', () => {
- beforeEach(async () => {
- createWrapper();
-
- contentEditor.emit(LOADING_CONTENT_EVENT);
- await nextTick();
- contentEditor.emit(LOADING_SUCCESS_EVENT);
- await nextTick();
- });
-
- it('hides loading indicator', () => {
- expect(findLoadingIcon().exists()).toBe(false);
- });
+ it('renders loading indicator component', () => {
+ createWrapper();
- it('displays EditorContent component', () => {
- expect(findEditorContent().exists()).toBe(true);
- });
+ expect(wrapper.findComponent(LoadingIndicator).exists()).toBe(true);
});
- describe('when loading content fails', () => {
- const error = 'error';
-
- beforeEach(async () => {
- createWrapper();
-
- contentEditor.emit(LOADING_CONTENT_EVENT);
- await nextTick();
- contentEditor.emit(LOADING_ERROR_EVENT, error);
- await nextTick();
- });
-
- it('hides loading indicator', () => {
- expect(findLoadingIcon().exists()).toBe(false);
- });
-
- it('displays EditorContent component', () => {
- expect(findEditorContent().exists()).toBe(true);
- });
+ it('renders formatting bubble menu', () => {
+ createWrapper();
- it('displays formatting bubble menu', () => {
- expect(findBubbleMenu().exists()).toBe(true);
- });
+ expect(wrapper.findComponent(FormattingBubbleMenu).exists()).toBe(true);
});
});
diff --git a/spec/frontend/content_editor/components/editor_state_observer_spec.js b/spec/frontend/content_editor/components/editor_state_observer_spec.js
index 5e4bb348e1f..51a594a606b 100644
--- a/spec/frontend/content_editor/components/editor_state_observer_spec.js
+++ b/spec/frontend/content_editor/components/editor_state_observer_spec.js
@@ -3,6 +3,13 @@ import { each } from 'lodash';
import EditorStateObserver, {
tiptapToComponentMap,
} from '~/content_editor/components/editor_state_observer.vue';
+import eventHubFactory from '~/helpers/event_hub_factory';
+import {
+ LOADING_CONTENT_EVENT,
+ LOADING_SUCCESS_EVENT,
+ LOADING_ERROR_EVENT,
+ ALERT_EVENT,
+} from '~/content_editor/constants';
import { createTestEditor } from '../test_utils';
describe('content_editor/components/editor_state_observer', () => {
@@ -11,19 +18,29 @@ describe('content_editor/components/editor_state_observer', () => {
let onDocUpdateListener;
let onSelectionUpdateListener;
let onTransactionListener;
+ let onLoadingContentListener;
+ let onLoadingSuccessListener;
+ let onLoadingErrorListener;
+ let onAlertListener;
+ let eventHub;
const buildEditor = () => {
tiptapEditor = createTestEditor();
+ eventHub = eventHubFactory();
jest.spyOn(tiptapEditor, 'on');
};
const buildWrapper = () => {
wrapper = shallowMount(EditorStateObserver, {
- provide: { tiptapEditor },
+ provide: { tiptapEditor, eventHub },
listeners: {
docUpdate: onDocUpdateListener,
selectionUpdate: onSelectionUpdateListener,
transaction: onTransactionListener,
+ [ALERT_EVENT]: onAlertListener,
+ [LOADING_CONTENT_EVENT]: onLoadingContentListener,
+ [LOADING_SUCCESS_EVENT]: onLoadingSuccessListener,
+ [LOADING_ERROR_EVENT]: onLoadingErrorListener,
},
});
};
@@ -32,8 +49,11 @@ describe('content_editor/components/editor_state_observer', () => {
onDocUpdateListener = jest.fn();
onSelectionUpdateListener = jest.fn();
onTransactionListener = jest.fn();
+ onAlertListener = jest.fn();
+ onLoadingSuccessListener = jest.fn();
+ onLoadingContentListener = jest.fn();
+ onLoadingErrorListener = jest.fn();
buildEditor();
- buildWrapper();
});
afterEach(() => {
@@ -44,6 +64,8 @@ describe('content_editor/components/editor_state_observer', () => {
it('emits update, selectionUpdate, and transaction events', () => {
const content = '<p>My paragraph</p>';
+ buildWrapper();
+
tiptapEditor.commands.insertContent(content);
expect(onDocUpdateListener).toHaveBeenCalledWith(
@@ -58,10 +80,27 @@ describe('content_editor/components/editor_state_observer', () => {
});
});
+ it.each`
+ event | listener
+ ${ALERT_EVENT} | ${() => onAlertListener}
+ ${LOADING_CONTENT_EVENT} | ${() => onLoadingContentListener}
+ ${LOADING_SUCCESS_EVENT} | ${() => onLoadingSuccessListener}
+ ${LOADING_ERROR_EVENT} | ${() => onLoadingErrorListener}
+ `('listens to $event event in the eventBus object', ({ event, listener }) => {
+ const args = {};
+
+ buildWrapper();
+
+ eventHub.$emit(event, args);
+ expect(listener()).toHaveBeenCalledWith(args);
+ });
+
describe('when component is destroyed', () => {
it('removes onTiptapDocUpdate and onTiptapSelectionUpdate hooks', () => {
jest.spyOn(tiptapEditor, 'off');
+ buildWrapper();
+
wrapper.destroy();
each(tiptapToComponentMap, (_, tiptapEvent) => {
@@ -71,5 +110,25 @@ describe('content_editor/components/editor_state_observer', () => {
);
});
});
+
+ it.each`
+ event
+ ${ALERT_EVENT}
+ ${LOADING_CONTENT_EVENT}
+ ${LOADING_SUCCESS_EVENT}
+ ${LOADING_ERROR_EVENT}
+ `('removes $event event hook from eventHub', ({ event }) => {
+ jest.spyOn(eventHub, '$off');
+ jest.spyOn(eventHub, '$on');
+
+ buildWrapper();
+
+ wrapper.destroy();
+
+ expect(eventHub.$off).toHaveBeenCalledWith(
+ event,
+ eventHub.$on.mock.calls.find(([eventName]) => eventName === event)[1],
+ );
+ });
});
});
diff --git a/spec/frontend/content_editor/components/loading_indicator_spec.js b/spec/frontend/content_editor/components/loading_indicator_spec.js
new file mode 100644
index 00000000000..e4fb09b70a4
--- /dev/null
+++ b/spec/frontend/content_editor/components/loading_indicator_spec.js
@@ -0,0 +1,71 @@
+import { GlLoadingIcon } from '@gitlab/ui';
+import { nextTick } from 'vue';
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
+import LoadingIndicator from '~/content_editor/components/loading_indicator.vue';
+import EditorStateObserver from '~/content_editor/components/editor_state_observer.vue';
+import {
+ LOADING_CONTENT_EVENT,
+ LOADING_SUCCESS_EVENT,
+ LOADING_ERROR_EVENT,
+} from '~/content_editor/constants';
+
+describe('content_editor/components/loading_indicator', () => {
+ let wrapper;
+
+ const findEditorStateObserver = () => wrapper.findComponent(EditorStateObserver);
+ const findLoadingIcon = () => wrapper.findComponent(GlLoadingIcon);
+
+ const createWrapper = () => {
+ wrapper = shallowMountExtended(LoadingIndicator);
+ };
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ describe('when loading content', () => {
+ beforeEach(async () => {
+ createWrapper();
+
+ findEditorStateObserver().vm.$emit(LOADING_CONTENT_EVENT);
+
+ await nextTick();
+ });
+
+ it('displays loading indicator', () => {
+ expect(findLoadingIcon().exists()).toBe(true);
+ });
+ });
+
+ describe('when loading content succeeds', () => {
+ beforeEach(async () => {
+ createWrapper();
+
+ findEditorStateObserver().vm.$emit(LOADING_CONTENT_EVENT);
+ await nextTick();
+ findEditorStateObserver().vm.$emit(LOADING_SUCCESS_EVENT);
+ await nextTick();
+ });
+
+ it('hides loading indicator', () => {
+ expect(findLoadingIcon().exists()).toBe(false);
+ });
+ });
+
+ describe('when loading content fails', () => {
+ const error = 'error';
+
+ beforeEach(async () => {
+ createWrapper();
+
+ findEditorStateObserver().vm.$emit(LOADING_CONTENT_EVENT);
+ await nextTick();
+ findEditorStateObserver().vm.$emit(LOADING_ERROR_EVENT, error);
+ await nextTick();
+ });
+
+ it('hides loading indicator', () => {
+ expect(findLoadingIcon().exists()).toBe(false);
+ });
+ });
+});
diff --git a/spec/frontend/content_editor/components/toolbar_button_spec.js b/spec/frontend/content_editor/components/toolbar_button_spec.js
index 60263c46bdd..ce50482302d 100644
--- a/spec/frontend/content_editor/components/toolbar_button_spec.js
+++ b/spec/frontend/content_editor/components/toolbar_button_spec.js
@@ -2,6 +2,7 @@ import { GlButton } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import EditorStateObserver from '~/content_editor/components/editor_state_observer.vue';
import ToolbarButton from '~/content_editor/components/toolbar_button.vue';
+import eventHubFactory from '~/helpers/event_hub_factory';
import { createTestEditor, mockChainedCommands, emitEditorEvent } from '../test_utils';
describe('content_editor/components/toolbar_button', () => {
@@ -25,6 +26,7 @@ describe('content_editor/components/toolbar_button', () => {
},
provide: {
tiptapEditor,
+ eventHub: eventHubFactory(),
},
propsData: {
contentType: CONTENT_TYPE,
diff --git a/spec/frontend/content_editor/components/toolbar_link_button_spec.js b/spec/frontend/content_editor/components/toolbar_link_button_spec.js
index 0cf488260bd..fc26a9da471 100644
--- a/spec/frontend/content_editor/components/toolbar_link_button_spec.js
+++ b/spec/frontend/content_editor/components/toolbar_link_button_spec.js
@@ -1,6 +1,7 @@
import { GlDropdown, GlButton, GlFormInputGroup } from '@gitlab/ui';
import { mountExtended } from 'helpers/vue_test_utils_helper';
import ToolbarLinkButton from '~/content_editor/components/toolbar_link_button.vue';
+import eventHubFactory from '~/helpers/event_hub_factory';
import Link from '~/content_editor/extensions/link';
import { hasSelection } from '~/content_editor/services/utils';
import { createTestEditor, mockChainedCommands, emitEditorEvent } from '../test_utils';
@@ -15,6 +16,7 @@ describe('content_editor/components/toolbar_link_button', () => {
wrapper = mountExtended(ToolbarLinkButton, {
provide: {
tiptapEditor: editor,
+ eventHub: eventHubFactory(),
},
});
};
diff --git a/spec/frontend/content_editor/components/toolbar_text_style_dropdown_spec.js b/spec/frontend/content_editor/components/toolbar_text_style_dropdown_spec.js
index 65c1c8c8310..608be1bd693 100644
--- a/spec/frontend/content_editor/components/toolbar_text_style_dropdown_spec.js
+++ b/spec/frontend/content_editor/components/toolbar_text_style_dropdown_spec.js
@@ -4,6 +4,7 @@ import EditorStateObserver from '~/content_editor/components/editor_state_observ
import ToolbarTextStyleDropdown from '~/content_editor/components/toolbar_text_style_dropdown.vue';
import { TEXT_STYLE_DROPDOWN_ITEMS } from '~/content_editor/constants';
import Heading from '~/content_editor/extensions/heading';
+import eventHubFactory from '~/helpers/event_hub_factory';
import { createTestEditor, mockChainedCommands, emitEditorEvent } from '../test_utils';
describe('content_editor/components/toolbar_text_style_dropdown', () => {
@@ -27,6 +28,7 @@ describe('content_editor/components/toolbar_text_style_dropdown', () => {
},
provide: {
tiptapEditor,
+ eventHub: eventHubFactory(),
},
propsData: {
...propsData,
diff --git a/spec/frontend/content_editor/extensions/attachment_spec.js b/spec/frontend/content_editor/extensions/attachment_spec.js
index d2d2cd98a78..ec67545cf17 100644
--- a/spec/frontend/content_editor/extensions/attachment_spec.js
+++ b/spec/frontend/content_editor/extensions/attachment_spec.js
@@ -4,7 +4,9 @@ import Attachment from '~/content_editor/extensions/attachment';
import Image from '~/content_editor/extensions/image';
import Link from '~/content_editor/extensions/link';
import Loading from '~/content_editor/extensions/loading';
+import { VARIANT_DANGER } from '~/flash';
import httpStatus from '~/lib/utils/http_status';
+import eventHubFactory from '~/helpers/event_hub_factory';
import { createTestEditor, createDocBuilder } from '../test_utils';
const PROJECT_WIKI_ATTACHMENT_IMAGE_HTML = `<p data-sourcepos="1:1-1:27" dir="auto">
@@ -25,6 +27,7 @@ describe('content_editor/extensions/attachment', () => {
let link;
let renderMarkdown;
let mock;
+ let eventHub;
const uploadsPath = '/uploads/';
const imageFile = new File(['foo'], 'test-file.png', { type: 'image/png' });
@@ -50,9 +53,15 @@ describe('content_editor/extensions/attachment', () => {
beforeEach(() => {
renderMarkdown = jest.fn();
+ eventHub = eventHubFactory();
tiptapEditor = createTestEditor({
- extensions: [Loading, Link, Image, Attachment.configure({ renderMarkdown, uploadsPath })],
+ extensions: [
+ Loading,
+ Link,
+ Image,
+ Attachment.configure({ renderMarkdown, uploadsPath, eventHub }),
+ ],
});
({
@@ -160,7 +169,8 @@ describe('content_editor/extensions/attachment', () => {
it('emits an alert event that includes an error message', (done) => {
tiptapEditor.commands.uploadAttachment({ file: imageFile });
- tiptapEditor.on('alert', ({ message }) => {
+ eventHub.$on('alert', ({ message, variant }) => {
+ expect(variant).toBe(VARIANT_DANGER);
expect(message).toBe('An error occurred while uploading the image. Please try again.');
done();
});
@@ -236,7 +246,8 @@ describe('content_editor/extensions/attachment', () => {
it('emits an alert event that includes an error message', (done) => {
tiptapEditor.commands.uploadAttachment({ file: attachmentFile });
- tiptapEditor.on('alert', ({ message }) => {
+ eventHub.$on('alert', ({ message, variant }) => {
+ expect(variant).toBe(VARIANT_DANGER);
expect(message).toBe('An error occurred while uploading the file. Please try again.');
done();
});
diff --git a/spec/frontend/content_editor/extensions/paste_markdown_spec.js b/spec/frontend/content_editor/extensions/paste_markdown_spec.js
new file mode 100644
index 00000000000..8f734c7dabc
--- /dev/null
+++ b/spec/frontend/content_editor/extensions/paste_markdown_spec.js
@@ -0,0 +1,127 @@
+import PasteMarkdown from '~/content_editor/extensions/paste_markdown';
+import Bold from '~/content_editor/extensions/bold';
+import { VARIANT_DANGER } from '~/flash';
+import eventHubFactory from '~/helpers/event_hub_factory';
+import {
+ ALERT_EVENT,
+ LOADING_CONTENT_EVENT,
+ LOADING_SUCCESS_EVENT,
+ LOADING_ERROR_EVENT,
+} from '~/content_editor/constants';
+import waitForPromises from 'helpers/wait_for_promises';
+import { createTestEditor, createDocBuilder, waitUntilNextDocTransaction } from '../test_utils';
+
+describe('content_editor/extensions/paste_markdown', () => {
+ let tiptapEditor;
+ let doc;
+ let p;
+ let bold;
+ let renderMarkdown;
+ let eventHub;
+ const defaultData = { 'text/plain': '**bold text**' };
+
+ beforeEach(() => {
+ renderMarkdown = jest.fn();
+ eventHub = eventHubFactory();
+
+ jest.spyOn(eventHub, '$emit');
+
+ tiptapEditor = createTestEditor({
+ extensions: [PasteMarkdown.configure({ renderMarkdown, eventHub }), Bold],
+ });
+
+ ({
+ builders: { doc, p, bold },
+ } = createDocBuilder({
+ tiptapEditor,
+ names: {
+ Bold: { markType: Bold.name },
+ },
+ }));
+ });
+
+ const buildClipboardEvent = ({ data = {}, types = ['text/plain'] } = {}) => {
+ return Object.assign(new Event('paste'), {
+ clipboardData: { types, getData: jest.fn((type) => data[type] || defaultData[type]) },
+ });
+ };
+
+ const triggerPasteEventHandler = (event) => {
+ let handled = false;
+
+ tiptapEditor.view.someProp('handlePaste', (eventHandler) => {
+ handled = eventHandler(tiptapEditor.view, event);
+ });
+
+ return handled;
+ };
+
+ const triggerPasteEventHandlerAndWaitForTransaction = (event) => {
+ return waitUntilNextDocTransaction({
+ tiptapEditor,
+ action: () => {
+ tiptapEditor.view.someProp('handlePaste', (eventHandler) => {
+ return eventHandler(tiptapEditor.view, event);
+ });
+ },
+ });
+ };
+
+ it.each`
+ types | data | handled | desc
+ ${['text/plain']} | ${{}} | ${true} | ${'handles plain text'}
+ ${['text/plain', 'text/html']} | ${{}} | ${false} | ${'doesn’t handle html format'}
+ ${['text/plain', 'text/html', 'vscode-editor-data']} | ${{ 'vscode-editor-data': '{ "mode": "markdown" }' }} | ${true} | ${'handles vscode markdown'}
+ ${['text/plain', 'text/html', 'vscode-editor-data']} | ${{ 'vscode-editor-data': '{ "mode": "ruby" }' }} | ${false} | ${'doesn’t vscode code snippet'}
+ `('$desc', ({ types, handled, data }) => {
+ expect(triggerPasteEventHandler(buildClipboardEvent({ types, data }))).toBe(handled);
+ });
+
+ describe('when pasting raw markdown source', () => {
+ describe('when rendering markdown succeeds', () => {
+ beforeEach(() => {
+ renderMarkdown.mockResolvedValueOnce('<strong>bold text</strong>');
+ });
+
+ it('transforms pasted text into a prosemirror node', async () => {
+ const expectedDoc = doc(p(bold('bold text')));
+
+ await triggerPasteEventHandlerAndWaitForTransaction(buildClipboardEvent());
+
+ expect(tiptapEditor.state.doc.toJSON()).toEqual(expectedDoc.toJSON());
+ });
+
+ it(`triggers ${LOADING_SUCCESS_EVENT}`, async () => {
+ await triggerPasteEventHandlerAndWaitForTransaction(buildClipboardEvent());
+
+ expect(eventHub.$emit).toHaveBeenCalledWith(LOADING_CONTENT_EVENT);
+ expect(eventHub.$emit).toHaveBeenCalledWith(LOADING_SUCCESS_EVENT);
+ });
+ });
+
+ describe('when rendering markdown fails', () => {
+ beforeEach(() => {
+ renderMarkdown.mockRejectedValueOnce();
+ });
+
+ it(`triggers ${LOADING_ERROR_EVENT} event`, async () => {
+ triggerPasteEventHandler(buildClipboardEvent());
+
+ await waitForPromises();
+
+ expect(eventHub.$emit).toHaveBeenCalledWith(LOADING_ERROR_EVENT);
+ });
+
+ it(`triggers ${ALERT_EVENT} event`, async () => {
+ triggerPasteEventHandler(buildClipboardEvent());
+
+ await waitForPromises();
+
+ expect(eventHub.$emit).toHaveBeenCalledWith(ALERT_EVENT, {
+ message: expect.any(String),
+ variant: VARIANT_DANGER,
+ });
+ });
+ });
+ });
+});
diff --git a/spec/frontend/content_editor/markdown_processing_spec_helper.js b/spec/frontend/content_editor/markdown_processing_spec_helper.js
index bb7ec0030a2..41442dd8388 100644
--- a/spec/frontend/content_editor/markdown_processing_spec_helper.js
+++ b/spec/frontend/content_editor/markdown_processing_spec_helper.js
@@ -55,7 +55,7 @@ const testSerializesHtmlToMarkdownForElement = async ({ markdown, html }) => {
// Assert that the markdown we ended up with after sending it through all the ContentEditor
// plumbing matches the original markdown from the YAML.
- expect(serializedContent).toBe(markdown);
+ expect(serializedContent.trim()).toBe(markdown.trim());
};
// describeMarkdownProcesssing
diff --git a/spec/frontend/content_editor/services/content_editor_spec.js b/spec/frontend/content_editor/services/content_editor_spec.js
index e48687f1548..3bc72b13302 100644
--- a/spec/frontend/content_editor/services/content_editor_spec.js
+++ b/spec/frontend/content_editor/services/content_editor_spec.js
@@ -4,19 +4,31 @@ import {
LOADING_ERROR_EVENT,
} from '~/content_editor/constants';
import { ContentEditor } from '~/content_editor/services/content_editor';
-
-import { createTestEditor } from '../test_utils';
+import eventHubFactory from '~/helpers/event_hub_factory';
+import { createTestEditor, createDocBuilder } from '../test_utils';
describe('content_editor/services/content_editor', () => {
let contentEditor;
let serializer;
+ let deserializer;
+ let eventHub;
+ let doc;
+ let p;
beforeEach(() => {
const tiptapEditor = createTestEditor();
jest.spyOn(tiptapEditor, 'destroy');
+ ({
+ builders: { doc, p },
+ } = createDocBuilder({
+ tiptapEditor,
+ }));
+
serializer = { deserialize: jest.fn() };
- contentEditor = new ContentEditor({ tiptapEditor, serializer });
+ deserializer = { deserialize: jest.fn() };
+ eventHub = eventHubFactory();
+ contentEditor = new ContentEditor({ tiptapEditor, serializer, deserializer, eventHub });
});
describe('.dispose', () => {
@@ -30,33 +42,42 @@ describe('content_editor/services/content_editor', () => {
});
describe('when setSerializedContent succeeds', () => {
+ let document;
+
beforeEach(() => {
- serializer.deserialize.mockResolvedValueOnce('');
+ document = doc(p('document'));
+ deserializer.deserialize.mockResolvedValueOnce({ document });
});
- it('emits loadingContent and loadingSuccess event', () => {
+ it('emits loadingContent and loadingSuccess event in the eventHub', () => {
let loadingContentEmitted = false;
- contentEditor.on(LOADING_CONTENT_EVENT, () => {
+ eventHub.$on(LOADING_CONTENT_EVENT, () => {
loadingContentEmitted = true;
});
- contentEditor.on(LOADING_SUCCESS_EVENT, () => {
+ eventHub.$on(LOADING_SUCCESS_EVENT, () => {
expect(loadingContentEmitted).toBe(true);
});
contentEditor.setSerializedContent('**bold text**');
});
+
+ it('sets the deserialized document in the tiptap editor object', async () => {
+ await contentEditor.setSerializedContent('**bold text**');
+
+ expect(contentEditor.tiptapEditor.state.doc.toJSON()).toEqual(document.toJSON());
+ });
});
describe('when setSerializedContent fails', () => {
const error = 'error';
beforeEach(() => {
- serializer.deserialize.mockRejectedValueOnce(error);
+ deserializer.deserialize.mockRejectedValueOnce(error);
});
it('emits loadingError event', async () => {
- contentEditor.on(LOADING_ERROR_EVENT, (e) => {
+ eventHub.$on(LOADING_ERROR_EVENT, (e) => {
expect(e).toBe('error');
});
diff --git a/spec/frontend/content_editor/services/markdown_deserializer_spec.js b/spec/frontend/content_editor/services/markdown_deserializer_spec.js
new file mode 100644
index 00000000000..bea43a0effc
--- /dev/null
+++ b/spec/frontend/content_editor/services/markdown_deserializer_spec.js
@@ -0,0 +1,62 @@
+import createMarkdownDeserializer from '~/content_editor/services/markdown_deserializer';
+import Bold from '~/content_editor/extensions/bold';
+import { createTestEditor, createDocBuilder } from '../test_utils';
+
+describe('content_editor/services/markdown_deserializer', () => {
+ let renderMarkdown;
+ let doc;
+ let p;
+ let bold;
+ let tiptapEditor;
+
+ beforeEach(() => {
+ tiptapEditor = createTestEditor({
+ extensions: [Bold],
+ });
+
+ ({
+ builders: { doc, p, bold },
+ } = createDocBuilder({
+ tiptapEditor,
+ names: {
+ bold: { markType: Bold.name },
+ },
+ }));
+ renderMarkdown = jest.fn();
+ });
+
+ describe('when deserializing', () => {
+ let result;
+ const text = 'Bold text';
+
+ beforeEach(async () => {
+ const deserializer = createMarkdownDeserializer({ render: renderMarkdown });
+
+ renderMarkdown.mockResolvedValueOnce(`<p><strong>${text}</strong></p>`);
+
+ result = await deserializer.deserialize({
+ content: 'content',
+ schema: tiptapEditor.schema,
+ });
+ });
+ it('transforms HTML returned by render function to a ProseMirror document', async () => {
+ const expectedDoc = doc(p(bold(text)));
+
+ expect(result.document.toJSON()).toEqual(expectedDoc.toJSON());
+ });
+
+ it('returns parsed HTML as a DOM object', () => {
+ expect(result.dom.innerHTML).toEqual(`<p><strong>${text}</strong></p><!--content-->`);
+ });
+ });
+
+ describe('when the render function returns an empty value', () => {
+ it('returns an empty object', async () => {
+ const deserializer = createMarkdownDeserializer({ render: renderMarkdown });
+
+ renderMarkdown.mockResolvedValueOnce(null);
+
+ expect(await deserializer.deserialize({ content: 'content' })).toEqual({});
+ });
+ });
+});
diff --git a/spec/frontend/content_editor/services/markdown_serializer_spec.js b/spec/frontend/content_editor/services/markdown_serializer_spec.js
index 01d4c994e88..2b76dc6c984 100644
--- a/spec/frontend/content_editor/services/markdown_serializer_spec.js
+++ b/spec/frontend/content_editor/services/markdown_serializer_spec.js
@@ -597,6 +597,7 @@ this is not really json but just trying out whether this case works or not
paragraph('A giant ', italic('owl-like'), ' creature.'),
),
),
+ heading('this is a heading'),
),
).toBe(
`
@@ -612,6 +613,8 @@ A giant _owl-like_ creature.
</dd>
</dl>
+
+# this is a heading
`.trim(),
);
});
@@ -623,6 +626,7 @@ A giant _owl-like_ creature.
detailsContent(paragraph('this is the summary')),
detailsContent(paragraph('this content will be hidden')),
),
+ heading('this is a heading'),
),
).toBe(
`
@@ -630,6 +634,8 @@ A giant _owl-like_ creature.
<summary>this is the summary</summary>
this content will be hidden
</details>
+
+# this is a heading
`.trim(),
);
});
@@ -648,7 +654,7 @@ this content will be hidden
detailsContent(paragraph('this content will be ', italic('hidden'))),
),
details(detailsContent(paragraph('summary 2')), detailsContent(paragraph('content 2'))),
- ),
+ ).trim(),
).toBe(
`
<details>
@@ -669,6 +675,7 @@ console.log(c);
this content will be _hidden_
</details>
+
<details>
<summary>summary 2</summary>
content 2
@@ -694,7 +701,7 @@ content 2
),
),
),
- ),
+ ).trim(),
).toBe(
`
<details>
@@ -709,7 +716,9 @@ content 2
_inception_
</details>
+
</details>
+
</details>
`.trim(),
);
diff --git a/spec/frontend/content_editor/services/markdown_sourcemap_spec.js b/spec/frontend/content_editor/services/markdown_sourcemap_spec.js
index 6f908f468f6..abd9588daff 100644
--- a/spec/frontend/content_editor/services/markdown_sourcemap_spec.js
+++ b/spec/frontend/content_editor/services/markdown_sourcemap_spec.js
@@ -2,8 +2,8 @@ import { Extension } from '@tiptap/core';
import BulletList from '~/content_editor/extensions/bullet_list';
import ListItem from '~/content_editor/extensions/list_item';
import Paragraph from '~/content_editor/extensions/paragraph';
-import markdownSerializer from '~/content_editor/services/markdown_serializer';
-import { getMarkdownSource } from '~/content_editor/services/markdown_sourcemap';
+import markdownDeserializer from '~/content_editor/services/markdown_deserializer';
+import { getMarkdownSource, getFullSource } from '~/content_editor/services/markdown_sourcemap';
import { createTestEditor, createDocBuilder } from '../test_utils';
const BULLET_LIST_MARKDOWN = `+ list item 1
@@ -52,10 +52,29 @@ const {
});
describe('content_editor/services/markdown_sourcemap', () => {
+ describe('getFullSource', () => {
+ it.each`
+ lastChild | expected
+ ${null} | ${[]}
+ ${{ nodeName: 'paragraph' }} | ${[]}
+ ${{ nodeName: '#comment', textContent: null }} | ${[]}
+ ${{ nodeName: '#comment', textContent: '+ list item 1\n+ list item 2' }} | ${['+ list item 1', '+ list item 2']}
+ `('with lastChild=$lastChild, returns $expected', ({ lastChild, expected }) => {
+ const element = {
+ ownerDocument: {
+ body: {
+ lastChild,
+ },
+ },
+ };
+
+ expect(getFullSource(element)).toEqual(expected);
+ });
+ });
+
it('gets markdown source for a rendered HTML element', async () => {
- const deserialized = await markdownSerializer({
+ const { document } = await markdownDeserializer({
render: () => BULLET_LIST_HTML,
- serializerConfig: {},
}).deserialize({
schema: tiptapEditor.schema,
content: BULLET_LIST_MARKDOWN,
@@ -76,6 +95,6 @@ describe('content_editor/services/markdown_sourcemap', () => {
),
);
- expect(deserialized).toEqual(expected.toJSON());
+ expect(document.toJSON()).toEqual(expected.toJSON());
});
});
diff --git a/spec/frontend/content_editor/test_utils.js b/spec/frontend/content_editor/test_utils.js
index 84eaa3c5f44..dde9d738235 100644
--- a/spec/frontend/content_editor/test_utils.js
+++ b/spec/frontend/content_editor/test_utils.js
@@ -142,3 +142,23 @@ export const triggerMarkInputRule = ({ tiptapEditor, inputRuleText }) => {
f(view, selection.from, inputRuleText.length + 1, inputRuleText),
);
};
+
+/**
+ * Executes an action that triggers a transaction in the
+ * tiptap Editor. Returns a promise that resolves
+ * after the transaction completes
+ * @param {*} params.tiptapEditor Tiptap editor
+ * @param {*} params.action A function that triggers a transaction in the tiptap Editor
+ * @returns A promise that resolves when the transaction completes
+ */
+export const waitUntilNextDocTransaction = ({ tiptapEditor, action }) => {
+ return new Promise((resolve) => {
+ const handleTransaction = () => {
+ tiptapEditor.off('update', handleTransaction);
+ resolve();
+ };
+
+ tiptapEditor.on('update', handleTransaction);
+ action();
+ });
+};
diff --git a/spec/frontend/contributors/store/getters_spec.js b/spec/frontend/contributors/store/getters_spec.js
index a4202e0ef4b..48218ff60e4 100644
--- a/spec/frontend/contributors/store/getters_spec.js
+++ b/spec/frontend/contributors/store/getters_spec.js
@@ -35,7 +35,7 @@ describe('Contributors Store Getters', () => {
{ author_name: 'Carlson', author_email: 'carlson123@gmail.com', date: '2019-05-05' },
{ author_name: 'John', author_email: 'jawnnypoo@gmail.com', date: '2019-04-04' },
{ author_name: 'Johan', author_email: 'jawnnypoo@gmail.com', date: '2019-04-04' },
- { author_name: 'John', author_email: 'jawnnypoo@gmail.com', date: '2019-03-03' },
+ { author_name: 'John', author_email: 'JAWNNYPOO@gmail.com', date: '2019-03-03' },
];
parsed = getters.parsedData(state);
});
diff --git a/spec/frontend/cycle_analytics/__snapshots__/total_time_component_spec.js.snap b/spec/frontend/cycle_analytics/__snapshots__/total_time_component_spec.js.snap
deleted file mode 100644
index e688df8f281..00000000000
--- a/spec/frontend/cycle_analytics/__snapshots__/total_time_component_spec.js.snap
+++ /dev/null
@@ -1,28 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`TotalTimeComponent with a blank object should render -- 1`] = `"<span class=\\"total-time\\"> -- </span>"`;
-
-exports[`TotalTimeComponent with a valid time object with {"days": 3, "mins": 47, "seconds": 3} 1`] = `
-"<span class=\\"total-time\\">
- 3 <span>days</span></span>"
-`;
-
-exports[`TotalTimeComponent with a valid time object with {"hours": 7, "mins": 20, "seconds": 10} 1`] = `
-"<span class=\\"total-time\\">
- 7 <span>hrs</span></span>"
-`;
-
-exports[`TotalTimeComponent with a valid time object with {"hours": 23, "mins": 10} 1`] = `
-"<span class=\\"total-time\\">
- 23 <span>hrs</span></span>"
-`;
-
-exports[`TotalTimeComponent with a valid time object with {"mins": 47, "seconds": 3} 1`] = `
-"<span class=\\"total-time\\">
- 47 <span>mins</span></span>"
-`;
-
-exports[`TotalTimeComponent with a valid time object with {"seconds": 35} 1`] = `
-"<span class=\\"total-time\\">
- 35 <span>s</span></span>"
-`;
diff --git a/spec/frontend/cycle_analytics/__snapshots__/total_time_spec.js.snap b/spec/frontend/cycle_analytics/__snapshots__/total_time_spec.js.snap
new file mode 100644
index 00000000000..7f211c1028e
--- /dev/null
+++ b/spec/frontend/cycle_analytics/__snapshots__/total_time_spec.js.snap
@@ -0,0 +1,28 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`TotalTime with a blank object should render -- 1`] = `"<span class=\\"total-time\\"> -- </span>"`;
+
+exports[`TotalTime with a valid time object with {"days": 3, "mins": 47, "seconds": 3} 1`] = `
+"<span class=\\"total-time\\">
+ 3 <span>days</span></span>"
+`;
+
+exports[`TotalTime with a valid time object with {"hours": 7, "mins": 20, "seconds": 10} 1`] = `
+"<span class=\\"total-time\\">
+ 7 <span>hrs</span></span>"
+`;
+
+exports[`TotalTime with a valid time object with {"hours": 23, "mins": 10} 1`] = `
+"<span class=\\"total-time\\">
+ 23 <span>hrs</span></span>"
+`;
+
+exports[`TotalTime with a valid time object with {"mins": 47, "seconds": 3} 1`] = `
+"<span class=\\"total-time\\">
+ 47 <span>mins</span></span>"
+`;
+
+exports[`TotalTime with a valid time object with {"seconds": 35} 1`] = `
+"<span class=\\"total-time\\">
+ 35 <span>s</span></span>"
+`;
diff --git a/spec/frontend/cycle_analytics/base_spec.js b/spec/frontend/cycle_analytics/base_spec.js
index 7b1ef71da63..bdf35f904ed 100644
--- a/spec/frontend/cycle_analytics/base_spec.js
+++ b/spec/frontend/cycle_analytics/base_spec.js
@@ -143,9 +143,12 @@ describe('Value stream analytics component', () => {
expect(findFilters().props()).toEqual({
groupId,
groupPath,
+ canToggleAggregation: false,
endDate: createdBefore,
hasDateRangeFilter: true,
hasProjectFilter: false,
+ isAggregationEnabled: false,
+ isUpdatingAggregationData: false,
selectedProjects: [],
startDate: createdAfter,
});
diff --git a/spec/frontend/cycle_analytics/limit_warning_component_spec.js b/spec/frontend/cycle_analytics/limit_warning_component_spec.js
deleted file mode 100644
index 3dac7438909..00000000000
--- a/spec/frontend/cycle_analytics/limit_warning_component_spec.js
+++ /dev/null
@@ -1,41 +0,0 @@
-import { shallowMount } from '@vue/test-utils';
-import Vue from 'vue';
-import LimitWarningComponent from '~/cycle_analytics/components/limit_warning_component.vue';
-import Translate from '~/vue_shared/translate';
-
-Vue.use(Translate);
-
-const createComponent = (props) =>
- shallowMount(LimitWarningComponent, {
- propsData: {
- ...props,
- },
- });
-
-describe('Limit warning component', () => {
- let component;
-
- beforeEach(() => {
- component = null;
- });
-
- afterEach(() => {
- component.destroy();
- });
-
- it('should not render if count is not exactly than 50', () => {
- component = createComponent({ count: 5 });
-
- expect(component.text().trim()).toBe('');
-
- component = createComponent({ count: 55 });
-
- expect(component.text().trim()).toBe('');
- });
-
- it('should render if count is exactly 50', () => {
- component = createComponent({ count: 50 });
-
- expect(component.text().trim()).toBe('Showing 50 events');
- });
-});
diff --git a/spec/frontend/cycle_analytics/total_time_component_spec.js b/spec/frontend/cycle_analytics/total_time_component_spec.js
deleted file mode 100644
index 9003c0330c0..00000000000
--- a/spec/frontend/cycle_analytics/total_time_component_spec.js
+++ /dev/null
@@ -1,45 +0,0 @@
-import { mount } from '@vue/test-utils';
-import TotalTimeComponent from '~/cycle_analytics/components/total_time_component.vue';
-
-describe('TotalTimeComponent', () => {
- let wrapper = null;
-
- const createComponent = (propsData) => {
- return mount(TotalTimeComponent, {
- propsData,
- });
- };
-
- afterEach(() => {
- wrapper.destroy();
- });
-
- describe('with a valid time object', () => {
- it.each`
- time
- ${{ seconds: 35 }}
- ${{ mins: 47, seconds: 3 }}
- ${{ days: 3, mins: 47, seconds: 3 }}
- ${{ hours: 23, mins: 10 }}
- ${{ hours: 7, mins: 20, seconds: 10 }}
- `('with $time', ({ time }) => {
- wrapper = createComponent({
- time,
- });
-
- expect(wrapper.html()).toMatchSnapshot();
- });
- });
-
- describe('with a blank object', () => {
- beforeEach(() => {
- wrapper = createComponent({
- time: {},
- });
- });
-
- it('should render --', () => {
- expect(wrapper.html()).toMatchSnapshot();
- });
- });
-});
diff --git a/spec/frontend/cycle_analytics/total_time_spec.js b/spec/frontend/cycle_analytics/total_time_spec.js
new file mode 100644
index 00000000000..8cf9feab6e9
--- /dev/null
+++ b/spec/frontend/cycle_analytics/total_time_spec.js
@@ -0,0 +1,45 @@
+import { mount } from '@vue/test-utils';
+import TotalTime from '~/cycle_analytics/components/total_time.vue';
+
+describe('TotalTime', () => {
+ let wrapper = null;
+
+ const createComponent = (propsData) => {
+ return mount(TotalTime, {
+ propsData,
+ });
+ };
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ describe('with a valid time object', () => {
+ it.each`
+ time
+ ${{ seconds: 35 }}
+ ${{ mins: 47, seconds: 3 }}
+ ${{ days: 3, mins: 47, seconds: 3 }}
+ ${{ hours: 23, mins: 10 }}
+ ${{ hours: 7, mins: 20, seconds: 10 }}
+ `('with $time', ({ time }) => {
+ wrapper = createComponent({
+ time,
+ });
+
+ expect(wrapper.html()).toMatchSnapshot();
+ });
+ });
+
+ describe('with a blank object', () => {
+ beforeEach(() => {
+ wrapper = createComponent({
+ time: {},
+ });
+ });
+
+ it('should render --', () => {
+ expect(wrapper.html()).toMatchSnapshot();
+ });
+ });
+});
diff --git a/spec/frontend/cycle_analytics/value_stream_filters_spec.js b/spec/frontend/cycle_analytics/value_stream_filters_spec.js
index 6e96a6d756a..5a0b046393a 100644
--- a/spec/frontend/cycle_analytics/value_stream_filters_spec.js
+++ b/spec/frontend/cycle_analytics/value_stream_filters_spec.js
@@ -1,4 +1,5 @@
import { shallowMount } from '@vue/test-utils';
+import { GlToggle } from '@gitlab/ui';
import Daterange from '~/analytics/shared/components/daterange.vue';
import ProjectsDropdownFilter from '~/analytics/shared/components/projects_dropdown_filter.vue';
import FilterBar from '~/cycle_analytics/components/filter_bar.vue';
@@ -29,6 +30,7 @@ describe('ValueStreamFilters', () => {
const findProjectsDropdown = () => wrapper.findComponent(ProjectsDropdownFilter);
const findDateRangePicker = () => wrapper.findComponent(Daterange);
const findFilterBar = () => wrapper.findComponent(FilterBar);
+ const findAggregationToggle = () => wrapper.findComponent(GlToggle);
beforeEach(() => {
wrapper = createComponent();
@@ -57,6 +59,10 @@ describe('ValueStreamFilters', () => {
expect(findDateRangePicker().exists()).toBe(true);
});
+ it('will not render the aggregation toggle', () => {
+ expect(findAggregationToggle().exists()).toBe(false);
+ });
+
it('will emit `selectProject` when a project is selected', () => {
findProjectsDropdown().vm.$emit('selected');
@@ -88,4 +94,52 @@ describe('ValueStreamFilters', () => {
expect(findProjectsDropdown().exists()).toBe(false);
});
});
+
+ describe('canToggleAggregation = true', () => {
+ beforeEach(() => {
+ wrapper = createComponent({ isAggregationEnabled: false, canToggleAggregation: true });
+ });
+
+ it('will render the aggregation toggle', () => {
+ expect(findAggregationToggle().exists()).toBe(true);
+ });
+
+ it('will set the aggregation toggle to the `isAggregationEnabled` value', () => {
+ expect(findAggregationToggle().props('value')).toBe(false);
+
+ wrapper = createComponent({
+ isAggregationEnabled: true,
+ canToggleAggregation: true,
+ });
+
+ expect(findAggregationToggle().props('value')).toBe(true);
+ });
+
+ it('will emit `toggleAggregation` when the toggle is changed', async () => {
+ expect(wrapper.emitted('toggleAggregation')).toBeUndefined();
+
+ await findAggregationToggle().vm.$emit('change', true);
+
+ expect(wrapper.emitted('toggleAggregation')).toHaveLength(1);
+ expect(wrapper.emitted('toggleAggregation')).toEqual([[true]]);
+ });
+ });
+
+ describe('isUpdatingAggregationData = true', () => {
+ beforeEach(() => {
+ wrapper = createComponent({ canToggleAggregation: true, isUpdatingAggregationData: true });
+ });
+
+ it('will disable the aggregation toggle', () => {
+ expect(findAggregationToggle().props('disabled')).toBe(true);
+ });
+
+ it('will not emit `toggleAggregation` when the toggle is changed', async () => {
+ expect(wrapper.emitted('toggleAggregation')).toBeUndefined();
+
+ await findAggregationToggle().vm.$emit('change', true);
+
+ expect(wrapper.emitted('toggleAggregation')).toBeUndefined();
+ });
+ });
});
diff --git a/spec/frontend/cycle_analytics/value_stream_metrics_spec.js b/spec/frontend/cycle_analytics/value_stream_metrics_spec.js
index 7a539b262fc..6199e61df0c 100644
--- a/spec/frontend/cycle_analytics/value_stream_metrics_spec.js
+++ b/spec/frontend/cycle_analytics/value_stream_metrics_spec.js
@@ -109,7 +109,7 @@ describe('ValueStreamMetrics', () => {
});
describe('filterFn', () => {
- const transferedMetricsData = prepareTimeMetricsData(metricsData, METRICS_POPOVER_CONTENT);
+ const transferredMetricsData = prepareTimeMetricsData(metricsData, METRICS_POPOVER_CONTENT);
it('with a filter function, will call the function with the metrics data', async () => {
const filteredData = [
@@ -123,7 +123,7 @@ describe('ValueStreamMetrics', () => {
await waitForPromises();
- expect(mockFilterFn).toHaveBeenCalledWith(transferedMetricsData);
+ expect(mockFilterFn).toHaveBeenCalledWith(transferredMetricsData);
expect(wrapper.vm.metrics).toEqual(filteredData);
});
@@ -133,7 +133,7 @@ describe('ValueStreamMetrics', () => {
await waitForPromises();
expect(mockFilterFn).not.toHaveBeenCalled();
- expect(wrapper.vm.metrics).toEqual(transferedMetricsData);
+ expect(wrapper.vm.metrics).toEqual(transferredMetricsData);
});
});
diff --git a/spec/frontend/deploy_tokens/components/revoke_button_spec.js b/spec/frontend/deploy_tokens/components/revoke_button_spec.js
index e70dfe4d2e6..fa2a7d9b155 100644
--- a/spec/frontend/deploy_tokens/components/revoke_button_spec.js
+++ b/spec/frontend/deploy_tokens/components/revoke_button_spec.js
@@ -70,11 +70,6 @@ describe('RevokeButton', () => {
expect(findRevokeButton().exists()).toBe(true);
});
- it('passes the buttonClass to the button', () => {
- wrapper = createComponent({ buttonClass: 'my-revoke-button' });
- expect(findRevokeButton().classes()).toContain('my-revoke-button');
- });
-
it('opens the modal', () => {
findRevokeButton().trigger('click');
expect(glModalDirective).toHaveBeenCalledWith(wrapper.vm.modalId);
diff --git a/spec/frontend/diffs/components/diff_view_spec.js b/spec/frontend/diffs/components/diff_view_spec.js
index 9b8f0421b7c..f982749d1de 100644
--- a/spec/frontend/diffs/components/diff_view_spec.js
+++ b/spec/frontend/diffs/components/diff_view_spec.js
@@ -51,10 +51,18 @@ describe('DiffView', () => {
it('renders a match line', () => {
const wrapper = createWrapper({
- diffLines: [{ isMatchLineLeft: true, left: { rich_text: 'matched text', lineDraft: {} } }],
+ diffLines: [
+ {
+ isMatchLineLeft: true,
+ left: {
+ rich_text: '@@ -4,12 +4,12 @@ import createFlash from &#39;~/flash&#39;;',
+ lineDraft: {},
+ },
+ },
+ ],
});
expect(wrapper.find(DiffExpansionCell).exists()).toBe(true);
- expect(wrapper.text()).toContain('matched text');
+ expect(wrapper.text()).toContain("@@ -4,12 +4,12 @@ import createFlash from '~/flash';");
});
it.each`
diff --git a/spec/frontend/diffs/components/hidden_files_warning_spec.js b/spec/frontend/diffs/components/hidden_files_warning_spec.js
index 3f1f23a40f5..bbd4f5faeec 100644
--- a/spec/frontend/diffs/components/hidden_files_warning_spec.js
+++ b/spec/frontend/diffs/components/hidden_files_warning_spec.js
@@ -1,4 +1,6 @@
-import { shallowMount } from '@vue/test-utils';
+import { mount } from '@vue/test-utils';
+import { GlButton } from '@gitlab/ui';
+import { __ } from '~/locale';
import HiddenFilesWarning from '~/diffs/components/hidden_files_warning.vue';
const propsData = {
@@ -12,7 +14,7 @@ describe('HiddenFilesWarning', () => {
let wrapper;
const createComponent = () => {
- wrapper = shallowMount(HiddenFilesWarning, {
+ wrapper = mount(HiddenFilesWarning, {
propsData,
});
};
@@ -26,22 +28,20 @@ describe('HiddenFilesWarning', () => {
});
it('has a correct plain diff URL', () => {
- const plainDiffLink = wrapper.findAll('a').wrappers.filter((x) => x.text() === 'Plain diff')[0];
+ const plainDiffLink = wrapper.findAllComponents(GlButton).at(0);
expect(plainDiffLink.attributes('href')).toBe(propsData.plainDiffPath);
});
it('has a correct email patch URL', () => {
- const emailPatchLink = wrapper
- .findAll('a')
- .wrappers.filter((x) => x.text() === 'Email patch')[0];
+ const emailPatchLink = wrapper.findAllComponents(GlButton).at(1);
expect(emailPatchLink.attributes('href')).toBe(propsData.emailPatchPath);
});
it('has a correct visible/total files text', () => {
- const filesText = wrapper.find('strong');
-
- expect(filesText.text()).toBe('5 of 10');
+ expect(wrapper.text()).toContain(
+ __('To preserve performance only 5 of 10 files are displayed.'),
+ );
});
});
diff --git a/spec/frontend/diffs/store/getters_versions_dropdowns_spec.js b/spec/frontend/diffs/store/getters_versions_dropdowns_spec.js
index 6ea8f691c3c..49f8e22e01c 100644
--- a/spec/frontend/diffs/store/getters_versions_dropdowns_spec.js
+++ b/spec/frontend/diffs/store/getters_versions_dropdowns_spec.js
@@ -79,27 +79,21 @@ describe('Compare diff version dropdowns', () => {
};
};
- const assertVersions = (targetVersions) => {
- // base and head should be the last two versions in that order
- const targetBaseVersion = targetVersions[targetVersions.length - 2];
- const targetHeadVersion = targetVersions[targetVersions.length - 1];
+ const assertVersions = (targetVersions, checkBaseVersion) => {
+ const targetLatestVersion = targetVersions[targetVersions.length - 1];
expect(targetVersions[0]).toEqual(expectedFirstVersion);
- expect(targetBaseVersion).toEqual(expectedBaseVersion);
- expect(targetHeadVersion).toEqual(expectedHeadVersion);
+
+ if (checkBaseVersion) {
+ expect(targetLatestVersion).toEqual(expectedBaseVersion);
+ } else {
+ expect(targetLatestVersion).toEqual(expectedHeadVersion);
+ }
};
afterEach(() => {
setWindowLocation(originalLocation);
});
- it('base version selected', () => {
- setupTest();
- expectedBaseVersion.selected = true;
-
- const targetVersions = getters.diffCompareDropdownTargetVersions(localState, getters);
- assertVersions(targetVersions);
- });
-
it('head version selected', () => {
setupTest(true);
@@ -126,6 +120,21 @@ describe('Compare diff version dropdowns', () => {
});
assertVersions(targetVersions);
});
+
+ describe('when state.mergeRequestDiff.head_version_path is null', () => {
+ beforeEach(() => {
+ localState.mergeRequestDiff.head_version_path = null;
+ });
+
+ it('base version selected', () => {
+ setupTest(true);
+
+ expectedBaseVersion.selected = true;
+
+ const targetVersions = getters.diffCompareDropdownTargetVersions(localState, getters);
+ assertVersions(targetVersions, true);
+ });
+ });
});
it('diffCompareDropdownSourceVersions', () => {
diff --git a/spec/frontend/dirty_submit/dirty_submit_form_spec.js b/spec/frontend/dirty_submit/dirty_submit_form_spec.js
index cfcf1be609e..bcbe824bd9f 100644
--- a/spec/frontend/dirty_submit/dirty_submit_form_spec.js
+++ b/spec/frontend/dirty_submit/dirty_submit_form_spec.js
@@ -93,5 +93,38 @@ describe('DirtySubmitForm', () => {
expect(updateDirtyInputSpy).toHaveBeenCalledTimes(range.length);
});
+
+ describe('when inputs listener is added', () => {
+ it('calls listener when changes are made to an input', () => {
+ const { form, input } = createForm();
+ const inputsListener = jest.fn();
+
+ const dirtySubmitForm = new DirtySubmitForm(form);
+ dirtySubmitForm.addInputsListener(inputsListener);
+
+ setInputValue(input, 'new value');
+
+ jest.runOnlyPendingTimers();
+
+ expect(inputsListener).toHaveBeenCalledTimes(1);
+ });
+
+ describe('when inputs listener is removed', () => {
+ it('does not call listener when changes are made to an input', () => {
+ const { form, input } = createForm();
+ const inputsListener = jest.fn();
+
+ const dirtySubmitForm = new DirtySubmitForm(form);
+ dirtySubmitForm.addInputsListener(inputsListener);
+ dirtySubmitForm.removeInputsListener(inputsListener);
+
+ setInputValue(input, 'new value');
+
+ jest.runOnlyPendingTimers();
+
+ expect(inputsListener).not.toHaveBeenCalled();
+ });
+ });
+ });
});
});
diff --git a/spec/frontend/editor/source_editor_ci_schema_ext_spec.js b/spec/frontend/editor/source_editor_ci_schema_ext_spec.js
index 5eaac9e9ef9..2f6d277ca75 100644
--- a/spec/frontend/editor/source_editor_ci_schema_ext_spec.js
+++ b/spec/frontend/editor/source_editor_ci_schema_ext_spec.js
@@ -4,10 +4,14 @@ import { CiSchemaExtension } from '~/editor/extensions/source_editor_ci_schema_e
import ciSchemaPath from '~/editor/schema/ci.json';
import SourceEditor from '~/editor/source_editor';
+// Webpack is configured to use file-loader for the CI schema; mimic that here
+jest.mock('~/editor/schema/ci.json', () => '/assets/ci.json');
+
const mockRef = 'AABBCCDD';
describe('~/editor/editor_ci_config_ext', () => {
const defaultBlobPath = '.gitlab-ci.yml';
+ const expectedSchemaUri = `${TEST_HOST}${ciSchemaPath}`;
let editor;
let instance;
@@ -84,14 +88,13 @@ describe('~/editor/editor_ci_config_ext', () => {
});
expect(getConfiguredYmlSchema()).toEqual({
- uri: `${TEST_HOST}${ciSchemaPath}`,
+ uri: expectedSchemaUri,
fileMatch: [defaultBlobPath],
});
});
it('with an alternative file name match', () => {
createMockEditor({ blobPath: 'dir1/dir2/another-ci-filename.yml' });
-
instance.registerCiSchema({
projectNamespace: mockProjectNamespace,
projectPath: mockProjectPath,
@@ -99,7 +102,7 @@ describe('~/editor/editor_ci_config_ext', () => {
});
expect(getConfiguredYmlSchema()).toEqual({
- uri: `${TEST_HOST}${ciSchemaPath}`,
+ uri: expectedSchemaUri,
fileMatch: ['another-ci-filename.yml'],
});
});
diff --git a/spec/frontend/environment.js b/spec/frontend/environment.js
index d7acf75fc95..8465b57c660 100644
--- a/spec/frontend/environment.js
+++ b/spec/frontend/environment.js
@@ -123,6 +123,7 @@ class CustomEnvironment extends JSDOMEnvironment {
// Reset `Date` so that Jest can report timing accurately *roll eyes*...
setGlobalDateToRealDate();
+ // eslint-disable-next-line no-restricted-syntax
await new Promise(setImmediate);
if (this.rejectedPromises.length > 0) {
diff --git a/spec/frontend/environments/delete_environment_modal_spec.js b/spec/frontend/environments/delete_environment_modal_spec.js
index 50c4ca00009..48e4f661c1d 100644
--- a/spec/frontend/environments/delete_environment_modal_spec.js
+++ b/spec/frontend/environments/delete_environment_modal_spec.js
@@ -5,8 +5,11 @@ import VueApollo from 'vue-apollo';
import { s__, sprintf } from '~/locale';
import DeleteEnvironmentModal from '~/environments/components/delete_environment_modal.vue';
import createMockApollo from 'helpers/mock_apollo_helper';
+import waitForPromises from 'helpers/wait_for_promises';
+import createFlash from '~/flash';
import { resolvedEnvironment } from './graphql/mock_data';
+jest.mock('~/flash');
Vue.use(VueApollo);
describe('~/environments/components/delete_environment_modal.vue', () => {
@@ -54,6 +57,34 @@ describe('~/environments/components/delete_environment_modal.vue', () => {
await nextTick();
+ expect(createFlash).not.toHaveBeenCalled();
+
+ expect(deleteResolver).toHaveBeenCalledWith(
+ expect.anything(),
+ { environment: resolvedEnvironment },
+ expect.anything(),
+ expect.anything(),
+ );
+ });
+
+ it('should flash a message on error', async () => {
+ createComponent({ apolloProvider: mockApollo });
+
+ deleteResolver.mockRejectedValue();
+
+ wrapper.findComponent(GlModal).vm.$emit('primary');
+
+ await waitForPromises();
+
+ expect(createFlash).toHaveBeenCalledWith(
+ expect.objectContaining({
+ message: s__(
+ 'Environments|An error occurred while deleting the environment. Check if the environment stopped; if not, stop it and try again.',
+ ),
+ captureError: true,
+ }),
+ );
+
expect(deleteResolver).toHaveBeenCalledWith(
expect.anything(),
{ environment: resolvedEnvironment },
diff --git a/spec/frontend/environments/enable_review_app_modal_spec.js b/spec/frontend/environments/enable_review_app_modal_spec.js
index 17ae10a2884..b6dac811ea6 100644
--- a/spec/frontend/environments/enable_review_app_modal_spec.js
+++ b/spec/frontend/environments/enable_review_app_modal_spec.js
@@ -4,10 +4,17 @@ import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import EnableReviewAppButton from '~/environments/components/enable_review_app_modal.vue';
import ModalCopyButton from '~/vue_shared/components/modal_copy_button.vue';
+// hardcode uniqueId for determinism
+jest.mock('lodash/uniqueId', () => (x) => `${x}77`);
+
+const EXPECTED_COPY_PRE_ID = 'enable-review-app-copy-string-77';
+
describe('Enable Review App Button', () => {
let wrapper;
let modal;
+ const findCopyString = () => wrapper.find(`#${EXPECTED_COPY_PRE_ID}`);
+
afterEach(() => {
wrapper.destroy();
});
@@ -30,12 +37,15 @@ describe('Enable Review App Button', () => {
});
it('renders the defaultBranchName copy', () => {
- const findCopyString = () => wrapper.findByTestId('enable-review-app-copy-string');
expect(findCopyString().text()).toContain('- main');
});
it('renders the copyToClipboard button', () => {
- expect(wrapper.findComponent(ModalCopyButton).exists()).toBe(true);
+ expect(wrapper.findComponent(ModalCopyButton).props()).toMatchObject({
+ modalId: 'fake-id',
+ target: `#${EXPECTED_COPY_PRE_ID}`,
+ title: 'Copy snippet text',
+ });
});
it('emits change events from the modal up', () => {
diff --git a/spec/frontend/environments/environment_actions_spec.js b/spec/frontend/environments/environment_actions_spec.js
index 336c207428e..ada79e2d415 100644
--- a/spec/frontend/environments/environment_actions_spec.js
+++ b/spec/frontend/environments/environment_actions_spec.js
@@ -7,8 +7,15 @@ import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
import EnvironmentActions from '~/environments/components/environment_actions.vue';
import eventHub from '~/environments/event_hub';
import actionMutation from '~/environments/graphql/mutations/action.mutation.graphql';
+import { confirmAction } from '~/lib/utils/confirm_via_gl_modal/confirm_via_gl_modal';
import createMockApollo from 'helpers/mock_apollo_helper';
+jest.mock('~/lib/utils/confirm_via_gl_modal/confirm_via_gl_modal', () => {
+ return {
+ confirmAction: jest.fn(),
+ };
+});
+
const scheduledJobAction = {
name: 'scheduled action',
playPath: `${TEST_HOST}/scheduled/job/action`,
@@ -50,7 +57,7 @@ describe('EnvironmentActions Component', () => {
afterEach(() => {
wrapper.destroy();
- wrapper = null;
+ confirmAction.mockReset();
});
it('should render a dropdown button with 2 icons', () => {
@@ -105,7 +112,7 @@ describe('EnvironmentActions Component', () => {
let emitSpy;
const clickAndConfirm = async ({ confirm = true } = {}) => {
- jest.spyOn(window, 'confirm').mockImplementation(() => confirm);
+ confirmAction.mockResolvedValueOnce(confirm);
findDropdownItem(scheduledJobAction).vm.$emit('click');
await nextTick();
@@ -124,7 +131,7 @@ describe('EnvironmentActions Component', () => {
});
it('emits postAction event', () => {
- expect(window.confirm).toHaveBeenCalled();
+ expect(confirmAction).toHaveBeenCalled();
expect(emitSpy).toHaveBeenCalledWith({ endpoint: scheduledJobAction.playPath });
});
@@ -134,13 +141,13 @@ describe('EnvironmentActions Component', () => {
});
describe('when postAction event is denied', () => {
- beforeEach(() => {
+ beforeEach(async () => {
createComponentWithScheduledJobs({ mountFn: mount });
clickAndConfirm({ confirm: false });
});
it('does not emit postAction event if confirmation is cancelled', () => {
- expect(window.confirm).toHaveBeenCalled();
+ expect(confirmAction).toHaveBeenCalled();
expect(emitSpy).not.toHaveBeenCalled();
});
});
diff --git a/spec/frontend/environments/environment_folder_spec.js b/spec/frontend/environments/environment_folder_spec.js
new file mode 100644
index 00000000000..f2027252f05
--- /dev/null
+++ b/spec/frontend/environments/environment_folder_spec.js
@@ -0,0 +1,132 @@
+import VueApollo from 'vue-apollo';
+import Vue, { nextTick } from 'vue';
+import { GlCollapse, GlIcon } from '@gitlab/ui';
+import waitForPromises from 'helpers/wait_for_promises';
+import createMockApollo from 'helpers/mock_apollo_helper';
+import { mountExtended } from 'helpers/vue_test_utils_helper';
+import { stubTransition } from 'helpers/stub_transition';
+import { __, s__ } from '~/locale';
+import EnvironmentsFolder from '~/environments/components/environment_folder.vue';
+import EnvironmentItem from '~/environments/components/new_environment_item.vue';
+import { resolvedEnvironmentsApp, resolvedFolder } from './graphql/mock_data';
+
+Vue.use(VueApollo);
+
+describe('~/environments/components/environments_folder.vue', () => {
+ let wrapper;
+ let environmentFolderMock;
+ let nestedEnvironment;
+
+ const findLink = () => wrapper.findByRole('link', { name: s__('Environments|Show all') });
+
+ const createApolloProvider = () => {
+ const mockResolvers = { Query: { folder: environmentFolderMock } };
+
+ return createMockApollo([], mockResolvers);
+ };
+
+ const createWrapper = (propsData, apolloProvider) =>
+ mountExtended(EnvironmentsFolder, {
+ apolloProvider,
+ propsData: {
+ scope: 'available',
+ ...propsData,
+ },
+ stubs: { transition: stubTransition() },
+ provide: { helpPagePath: '/help' },
+ });
+
+ beforeEach(async () => {
+ environmentFolderMock = jest.fn();
+ [nestedEnvironment] = resolvedEnvironmentsApp.environments;
+ environmentFolderMock.mockReturnValue(resolvedFolder);
+ });
+
+ afterEach(() => {
+ wrapper?.destroy();
+ });
+
+ describe('default', () => {
+ let folderName;
+ let button;
+
+ beforeEach(async () => {
+ wrapper = createWrapper({ nestedEnvironment }, createApolloProvider());
+
+ await nextTick();
+ await waitForPromises();
+ folderName = wrapper.findByText(nestedEnvironment.name);
+ button = wrapper.findByRole('button', { name: __('Expand') });
+ });
+
+ it('displays the name of the folder', () => {
+ expect(folderName.text()).toBe(nestedEnvironment.name);
+ });
+
+ describe('collapse', () => {
+ let icons;
+ let collapse;
+
+ beforeEach(() => {
+ collapse = wrapper.findComponent(GlCollapse);
+ icons = wrapper.findAllComponents(GlIcon);
+ });
+
+ it('is collapsed by default', () => {
+ const link = findLink();
+
+ expect(collapse.attributes('visible')).toBeUndefined();
+ const iconNames = icons.wrappers.map((i) => i.props('name')).slice(0, 2);
+ expect(iconNames).toEqual(['angle-right', 'folder-o']);
+ expect(folderName.classes('gl-font-weight-bold')).toBe(false);
+ expect(link.exists()).toBe(false);
+ });
+
+ it('opens on click', async () => {
+ await button.trigger('click');
+
+ const link = findLink();
+
+ expect(button.attributes('aria-label')).toBe(__('Collapse'));
+ expect(collapse.attributes('visible')).toBe('visible');
+ const iconNames = icons.wrappers.map((i) => i.props('name')).slice(0, 2);
+ expect(iconNames).toEqual(['angle-down', 'folder-open']);
+ expect(folderName.classes('gl-font-weight-bold')).toBe(true);
+ expect(link.attributes('href')).toBe(nestedEnvironment.latest.folderPath);
+ });
+
+ it('displays all environments when opened', async () => {
+ await button.trigger('click');
+
+ const names = resolvedFolder.environments.map((e) =>
+ expect.stringMatching(e.nameWithoutType),
+ );
+ const environments = wrapper
+ .findAllComponents(EnvironmentItem)
+ .wrappers.map((w) => w.text());
+ expect(environments).toEqual(expect.arrayContaining(names));
+ });
+ });
+ });
+
+ it.each(['available', 'stopped'])(
+ 'with scope=%s, fetches environments with scope',
+ async (scope) => {
+ wrapper = createWrapper({ nestedEnvironment, scope }, createApolloProvider());
+
+ await nextTick();
+ await waitForPromises();
+
+ expect(environmentFolderMock).toHaveBeenCalledTimes(1);
+ expect(environmentFolderMock).toHaveBeenCalledWith(
+ {},
+ {
+ environment: nestedEnvironment.latest,
+ scope,
+ },
+ expect.anything(),
+ expect.anything(),
+ );
+ },
+ );
+});
diff --git a/spec/frontend/environments/environment_item_spec.js b/spec/frontend/environments/environment_item_spec.js
index b930259149f..0b36d2a940d 100644
--- a/spec/frontend/environments/environment_item_spec.js
+++ b/spec/frontend/environments/environment_item_spec.js
@@ -79,7 +79,7 @@ describe('Environment item', () => {
describe('With user information', () => {
it('should render user avatar with link to profile', () => {
- expect(wrapper.find('.js-deploy-user-container').attributes('href')).toEqual(
+ expect(wrapper.find('.js-deploy-user-container').props('linkHref')).toEqual(
environment.last_deployment.user.web_url,
);
});
diff --git a/spec/frontend/environments/environments_app_spec.js b/spec/frontend/environments/environments_app_spec.js
index 92d1820681c..91b75c850bd 100644
--- a/spec/frontend/environments/environments_app_spec.js
+++ b/spec/frontend/environments/environments_app_spec.js
@@ -1,282 +1,355 @@
-import { GlTabs } from '@gitlab/ui';
-import { mount, shallowMount } from '@vue/test-utils';
-import MockAdapter from 'axios-mock-adapter';
-import { nextTick } from 'vue';
-import { extendedWrapper } from 'helpers/vue_test_utils_helper';
-import Container from '~/environments/components/container.vue';
-import DeployBoard from '~/environments/components/deploy_board.vue';
-import EmptyState from '~/environments/components/empty_state.vue';
-import EnableReviewAppModal from '~/environments/components/enable_review_app_modal.vue';
+import Vue, { nextTick } from 'vue';
+import VueApollo from 'vue-apollo';
+import { GlPagination } from '@gitlab/ui';
+import { mountExtended } from 'helpers/vue_test_utils_helper';
+import createMockApollo from 'helpers/mock_apollo_helper';
+import waitForPromises from 'helpers/wait_for_promises';
+import setWindowLocation from 'helpers/set_window_location_helper';
+import { sprintf, __, s__ } from '~/locale';
import EnvironmentsApp from '~/environments/components/environments_app.vue';
-import axios from '~/lib/utils/axios_utils';
-import * as urlUtils from '~/lib/utils/url_utility';
-import { environment, folder } from './mock_data';
+import EnvironmentsFolder from '~/environments/components/environment_folder.vue';
+import EnvironmentsItem from '~/environments/components/new_environment_item.vue';
+import EmptyState from '~/environments/components/empty_state.vue';
+import StopEnvironmentModal from '~/environments/components/stop_environment_modal.vue';
+import CanaryUpdateModal from '~/environments/components/canary_update_modal.vue';
+import { resolvedEnvironmentsApp, resolvedFolder, resolvedEnvironment } from './graphql/mock_data';
-describe('Environment', () => {
- let mock;
- let wrapper;
+Vue.use(VueApollo);
- const mockData = {
- endpoint: 'environments.json',
- canCreateEnvironment: true,
- newEnvironmentPath: 'environments/new',
- helpPagePath: 'help',
- userCalloutsPath: '/callouts',
- lockPromotionSvgPath: '/assets/illustrations/lock-promotion.svg',
- helpCanaryDeploymentsPath: 'help/canary-deployments',
+describe('~/environments/components/environments_app.vue', () => {
+ let wrapper;
+ let environmentAppMock;
+ let environmentFolderMock;
+ let paginationMock;
+ let environmentToStopMock;
+ let environmentToChangeCanaryMock;
+ let weightMock;
+
+ const createApolloProvider = () => {
+ const mockResolvers = {
+ Query: {
+ environmentApp: environmentAppMock,
+ folder: environmentFolderMock,
+ pageInfo: paginationMock,
+ environmentToStop: environmentToStopMock,
+ environmentToDelete: jest.fn().mockResolvedValue(resolvedEnvironment),
+ environmentToRollback: jest.fn().mockResolvedValue(resolvedEnvironment),
+ environmentToChangeCanary: environmentToChangeCanaryMock,
+ weight: weightMock,
+ },
+ };
+
+ return createMockApollo([], mockResolvers);
};
- const mockRequest = (response, body) => {
- mock.onGet(mockData.endpoint).reply(response, body, {
- 'X-nExt-pAge': '2',
- 'x-page': '1',
- 'X-Per-Page': '1',
- 'X-Prev-Page': '',
- 'X-TOTAL': '37',
- 'X-Total-Pages': '2',
+ const createWrapper = ({ provide = {}, apolloProvider } = {}) =>
+ mountExtended(EnvironmentsApp, {
+ provide: {
+ newEnvironmentPath: '/environments/new',
+ canCreateEnvironment: true,
+ defaultBranchName: 'main',
+ helpPagePath: '/help',
+ projectId: '1',
+ ...provide,
+ },
+ apolloProvider,
});
- };
- const createWrapper = (shallow = false, props = {}) => {
- const fn = shallow ? shallowMount : mount;
- wrapper = extendedWrapper(fn(EnvironmentsApp, { propsData: { ...mockData, ...props } }));
- return axios.waitForAll();
+ const createWrapperWithMocked = async ({
+ provide = {},
+ environmentsApp,
+ folder,
+ environmentToStop = {},
+ environmentToChangeCanary = {},
+ weight = 0,
+ pageInfo = {
+ total: 20,
+ perPage: 5,
+ nextPage: 3,
+ page: 2,
+ previousPage: 1,
+ __typename: 'LocalPageInfo',
+ },
+ location = '?scope=available&page=2',
+ }) => {
+ setWindowLocation(location);
+ environmentAppMock.mockReturnValue(environmentsApp);
+ environmentFolderMock.mockReturnValue(folder);
+ paginationMock.mockReturnValue(pageInfo);
+ environmentToStopMock.mockReturnValue(environmentToStop);
+ environmentToChangeCanaryMock.mockReturnValue(environmentToChangeCanary);
+ weightMock.mockReturnValue(weight);
+ const apolloProvider = createApolloProvider();
+ wrapper = createWrapper({ apolloProvider, provide });
+
+ await waitForPromises();
+ await nextTick();
};
- const findEnableReviewAppButton = () => wrapper.findByTestId('enable-review-app');
- const findEnableReviewAppModal = () => wrapper.findAll(EnableReviewAppModal);
- const findNewEnvironmentButton = () => wrapper.findByTestId('new-environment');
- const findEnvironmentsTabAvailable = () => wrapper.find('.js-environments-tab-available > a');
- const findEnvironmentsTabStopped = () => wrapper.find('.js-environments-tab-stopped > a');
-
beforeEach(() => {
- mock = new MockAdapter(axios);
+ environmentAppMock = jest.fn();
+ environmentFolderMock = jest.fn();
+ environmentToStopMock = jest.fn();
+ environmentToChangeCanaryMock = jest.fn();
+ weightMock = jest.fn();
+ paginationMock = jest.fn();
});
afterEach(() => {
wrapper.destroy();
- mock.restore();
});
- describe('successful request', () => {
- describe('without environments', () => {
- beforeEach(() => {
- mockRequest(200, { environments: [] });
- return createWrapper();
- });
+ it('should request available environments if the scope is invalid', async () => {
+ await createWrapperWithMocked({
+ environmentsApp: resolvedEnvironmentsApp,
+ folder: resolvedFolder,
+ location: '?scope=bad&page=2',
+ });
- it('should render the empty state', () => {
- expect(wrapper.find(EmptyState).exists()).toBe(true);
- });
+ expect(environmentAppMock).toHaveBeenCalledWith(
+ expect.anything(),
+ expect.objectContaining({ scope: 'available', page: 2 }),
+ expect.anything(),
+ expect.anything(),
+ );
+ });
+
+ it('should show all the folders that are fetched', async () => {
+ await createWrapperWithMocked({
+ environmentsApp: resolvedEnvironmentsApp,
+ folder: resolvedFolder,
});
- describe('with paginated environments', () => {
- const environmentList = [environment];
+ const text = wrapper.findAllComponents(EnvironmentsFolder).wrappers.map((w) => w.text());
- beforeEach(() => {
- mockRequest(200, {
- environments: environmentList,
- stopped_count: 1,
- available_count: 0,
- });
- return createWrapper();
- });
+ expect(text).toContainEqual(expect.stringMatching('review'));
+ expect(text).not.toContainEqual(expect.stringMatching('production'));
+ });
- it('should render a container table with environments', () => {
- const containerTable = wrapper.find(Container);
+ it('should show all the environments that are fetched', async () => {
+ await createWrapperWithMocked({
+ environmentsApp: resolvedEnvironmentsApp,
+ folder: resolvedFolder,
+ });
- expect(containerTable.exists()).toBe(true);
- expect(containerTable.props('environments').length).toEqual(environmentList.length);
- expect(containerTable.find('.environment-name').text()).toEqual(environmentList[0].name);
- });
+ const text = wrapper.findAllComponents(EnvironmentsItem).wrappers.map((w) => w.text());
- describe('pagination', () => {
- it('should render pagination', () => {
- expect(wrapper.findAll('.gl-pagination li').length).toEqual(9);
- });
-
- it('should make an API request when page is clicked', () => {
- jest.spyOn(wrapper.vm, 'updateContent').mockImplementation(() => {});
-
- wrapper.find('.gl-pagination li:nth-child(3) .page-link').trigger('click');
- expect(wrapper.vm.updateContent).toHaveBeenCalledWith({
- scope: 'available',
- page: '2',
- nested: true,
- });
- });
-
- it('should make an API request when using tabs', () => {
- jest.spyOn(wrapper.vm, 'updateContent').mockImplementation(() => {});
- findEnvironmentsTabStopped().trigger('click');
- expect(wrapper.vm.updateContent).toHaveBeenCalledWith({
- scope: 'stopped',
- page: '1',
- nested: true,
- });
- });
-
- it('should not make the same API request when clicking on the current scope tab', () => {
- // component starts at available
- jest.spyOn(wrapper.vm, 'updateContent').mockImplementation(() => {});
- findEnvironmentsTabAvailable().trigger('click');
- expect(wrapper.vm.updateContent).toHaveBeenCalledTimes(0);
- });
- });
+ expect(text).not.toContainEqual(expect.stringMatching('review'));
+ expect(text).toContainEqual(expect.stringMatching('production'));
+ });
- describe('deploy boards', () => {
- beforeEach(() => {
- const deployEnvironment = {
- ...environment,
- rollout_status: {
- status: 'found',
- },
- };
-
- mockRequest(200, {
- environments: [deployEnvironment],
- stopped_count: 1,
- available_count: 0,
- });
-
- return createWrapper();
- });
-
- it('should render deploy boards', () => {
- expect(wrapper.find(DeployBoard).exists()).toBe(true);
- });
-
- it('should render arrow to open deploy boards', () => {
- expect(
- wrapper.find('.deploy-board-icon [data-testid="chevron-down-icon"]').exists(),
- ).toBe(true);
- });
- });
+ it('should show an empty state with no environments', async () => {
+ await createWrapperWithMocked({
+ environmentsApp: { ...resolvedEnvironmentsApp, environments: [] },
});
+
+ expect(wrapper.findComponent(EmptyState).exists()).toBe(true);
});
- describe('unsuccessful request', () => {
- beforeEach(() => {
- mockRequest(500, {});
- return createWrapper();
+ it('should show a button to create a new environment', async () => {
+ await createWrapperWithMocked({
+ environmentsApp: resolvedEnvironmentsApp,
+ folder: resolvedFolder,
});
- it('should render empty state', () => {
- expect(wrapper.find(EmptyState).exists()).toBe(true);
- });
+ const button = wrapper.findByRole('link', { name: s__('Environments|New environment') });
+ expect(button.attributes('href')).toBe('/environments/new');
});
- describe('expandable folders', () => {
- beforeEach(() => {
- mockRequest(200, {
- environments: [folder],
- stopped_count: 1,
- available_count: 0,
- });
+ it('should not show a button to create a new environment if the user has no permissions', async () => {
+ await createWrapperWithMocked({
+ environmentsApp: resolvedEnvironmentsApp,
+ folder: resolvedFolder,
+ provide: { canCreateEnvironment: false, newEnvironmentPath: '' },
+ });
- mock.onGet(environment.folder_path).reply(200, { environments: [environment] });
+ const button = wrapper.findByRole('link', { name: s__('Environments|New environment') });
+ expect(button.exists()).toBe(false);
+ });
- return createWrapper().then(() => {
- // open folder
- wrapper.find('.folder-name').trigger('click');
- return axios.waitForAll();
- });
+ it('should show a button to open the review app modal', async () => {
+ await createWrapperWithMocked({
+ environmentsApp: resolvedEnvironmentsApp,
+ folder: resolvedFolder,
});
- it('should open a closed folder', () => {
- expect(wrapper.find('.folder-icon[data-testid="chevron-right-icon"]').exists()).toBe(false);
- });
+ const button = wrapper.findByRole('button', { name: s__('Environments|Enable review app') });
+ button.trigger('click');
- it('should close an opened folder', async () => {
- expect(wrapper.find('.folder-icon[data-testid="chevron-down-icon"]').exists()).toBe(true);
+ await nextTick();
- // close folder
- wrapper.find('.folder-name').trigger('click');
- await nextTick();
- expect(wrapper.find('.folder-icon[data-testid="chevron-down-icon"]').exists()).toBe(false);
- });
+ expect(wrapper.findByText(s__('ReviewApp|Enable Review App')).exists()).toBe(true);
+ });
- it('should show children environments', () => {
- expect(wrapper.findAll('.js-child-row').length).toEqual(1);
+ it('should not show a button to open the review app modal if review apps are configured', async () => {
+ await createWrapperWithMocked({
+ environmentsApp: {
+ ...resolvedEnvironmentsApp,
+ reviewApp: { canSetupReviewApp: false },
+ },
+ folder: resolvedFolder,
});
- it('should show a button to show all environments', () => {
- expect(wrapper.find('.text-center > a.btn').text()).toContain('Show all');
- });
+ const button = wrapper.findByRole('button', { name: s__('Environments|Enable review app') });
+ expect(button.exists()).toBe(false);
});
- describe('environment button', () => {
- describe('when user can create environment', () => {
- beforeEach(() => {
- mockRequest(200, { environments: [] });
- return createWrapper(true);
+ describe('tabs', () => {
+ it('should show tabs for available and stopped environmets', async () => {
+ await createWrapperWithMocked({
+ environmentsApp: resolvedEnvironmentsApp,
+ folder: resolvedFolder,
});
- it('should render', () => {
- expect(findNewEnvironmentButton().exists()).toBe(true);
+ const [available, stopped] = wrapper.findAllByRole('tab').wrappers;
+
+ expect(available.text()).toContain(__('Available'));
+ expect(available.text()).toContain(resolvedEnvironmentsApp.availableCount);
+ expect(stopped.text()).toContain(__('Stopped'));
+ expect(stopped.text()).toContain(resolvedEnvironmentsApp.stoppedCount);
+ });
+
+ it('should change the requested scope on tab change', async () => {
+ await createWrapperWithMocked({
+ environmentsApp: resolvedEnvironmentsApp,
+ folder: resolvedFolder,
+ });
+ const stopped = wrapper.findByRole('tab', {
+ name: `${__('Stopped')} ${resolvedEnvironmentsApp.stoppedCount}`,
});
+
+ stopped.trigger('click');
+
+ await nextTick();
+ await waitForPromises();
+
+ expect(environmentAppMock).toHaveBeenCalledWith(
+ expect.anything(),
+ expect.objectContaining({ scope: 'stopped', page: 1 }),
+ expect.anything(),
+ expect.anything(),
+ );
});
+ });
- describe('when user can not create environment', () => {
- beforeEach(() => {
- mockRequest(200, { environments: [] });
- return createWrapper(true, { ...mockData, canCreateEnvironment: false });
+ describe('modals', () => {
+ it('should pass the environment to stop to the stop environment modal', async () => {
+ await createWrapperWithMocked({
+ environmentsApp: resolvedEnvironmentsApp,
+ folder: resolvedFolder,
+ environmentToStop: resolvedEnvironment,
});
- it('should not render', () => {
- expect(findNewEnvironmentButton().exists()).toBe(false);
+ const modal = wrapper.findComponent(StopEnvironmentModal);
+
+ expect(modal.props('environment')).toMatchObject(resolvedEnvironment);
+ });
+
+ it('should pass the environment to change canary to the canary update modal', async () => {
+ await createWrapperWithMocked({
+ environmentsApp: resolvedEnvironmentsApp,
+ folder: resolvedFolder,
+ environmentToChangeCanary: resolvedEnvironment,
+ weight: 10,
});
+
+ const modal = wrapper.findComponent(CanaryUpdateModal);
+
+ expect(modal.props('environment')).toMatchObject(resolvedEnvironment);
});
});
- describe('review app modal', () => {
- describe('when it is not possible to enable a review app', () => {
- beforeEach(() => {
- mockRequest(200, { environments: [] });
- return createWrapper(true);
+ describe('pagination', () => {
+ it('should sync page from query params on load', async () => {
+ await createWrapperWithMocked({
+ environmentsApp: resolvedEnvironmentsApp,
+ folder: resolvedFolder,
});
- it('should not render the enable review app button', () => {
- expect(findEnableReviewAppButton().exists()).toBe(false);
- });
+ expect(wrapper.findComponent(GlPagination).props('value')).toBe(2);
+ });
- it('should not render a review app modal', () => {
- const modal = findEnableReviewAppModal();
- expect(modal).toHaveLength(0);
- expect(modal.exists()).toBe(false);
+ it('should change the requested page on next page click', async () => {
+ await createWrapperWithMocked({
+ environmentsApp: resolvedEnvironmentsApp,
+ folder: resolvedFolder,
+ });
+ const next = wrapper.findByRole('link', {
+ name: __('Go to next page'),
});
+
+ next.trigger('click');
+
+ await nextTick();
+ await waitForPromises();
+
+ expect(environmentAppMock).toHaveBeenCalledWith(
+ expect.anything(),
+ expect.objectContaining({ page: 3 }),
+ expect.anything(),
+ expect.anything(),
+ );
});
- describe('when it is possible to enable a review app', () => {
- beforeEach(() => {
- mockRequest(200, { environments: [], review_app: { can_setup_review_app: true } });
- return createWrapper(true);
+ it('should change the requested page on previous page click', async () => {
+ await createWrapperWithMocked({
+ environmentsApp: resolvedEnvironmentsApp,
+ folder: resolvedFolder,
+ });
+ const prev = wrapper.findByRole('link', {
+ name: __('Go to previous page'),
});
- it('should render the enable review app button', () => {
- expect(findEnableReviewAppButton().exists()).toBe(true);
- expect(findEnableReviewAppButton().text()).toContain('Enable review app');
+ prev.trigger('click');
+
+ await nextTick();
+ await waitForPromises();
+
+ expect(environmentAppMock).toHaveBeenCalledWith(
+ expect.anything(),
+ expect.objectContaining({ page: 1 }),
+ expect.anything(),
+ expect.anything(),
+ );
+ });
+
+ it('should change the requested page on specific page click', async () => {
+ await createWrapperWithMocked({
+ environmentsApp: resolvedEnvironmentsApp,
+ folder: resolvedFolder,
});
- it('should render only one review app modal', () => {
- const modal = findEnableReviewAppModal();
- expect(modal).toHaveLength(1);
- expect(modal.at(0).exists()).toBe(true);
+ const page = 1;
+ const pageButton = wrapper.findByRole('link', {
+ name: sprintf(__('Go to page %{page}'), { page }),
});
- });
- });
- describe('tabs', () => {
- beforeEach(() => {
- mockRequest(200, { environments: [] });
- jest
- .spyOn(urlUtils, 'getParameterByName')
- .mockImplementation((param) => (param === 'scope' ? 'stopped' : null));
- return createWrapper(true);
+ pageButton.trigger('click');
+
+ await nextTick();
+ await waitForPromises();
+
+ expect(environmentAppMock).toHaveBeenCalledWith(
+ expect.anything(),
+ expect.objectContaining({ page }),
+ expect.anything(),
+ expect.anything(),
+ );
});
- it('selects the tab for the parameter', () => {
- expect(wrapper.findComponent(GlTabs).attributes('value')).toBe('1');
+ it('should sync the query params to the new page', async () => {
+ await createWrapperWithMocked({
+ environmentsApp: resolvedEnvironmentsApp,
+ folder: resolvedFolder,
+ });
+ const next = wrapper.findByRole('link', {
+ name: __('Go to next page'),
+ });
+
+ next.trigger('click');
+
+ await nextTick();
+ expect(window.location.search).toBe('?scope=available&page=3');
});
});
});
diff --git a/spec/frontend/environments/graphql/resolvers_spec.js b/spec/frontend/environments/graphql/resolvers_spec.js
index 21d7e09bad5..26f0659204a 100644
--- a/spec/frontend/environments/graphql/resolvers_spec.js
+++ b/spec/frontend/environments/graphql/resolvers_spec.js
@@ -7,6 +7,7 @@ import environmentToDelete from '~/environments/graphql/queries/environment_to_d
import environmentToStopQuery from '~/environments/graphql/queries/environment_to_stop.query.graphql';
import createMockApollo from 'helpers/mock_apollo_helper';
import pollIntervalQuery from '~/environments/graphql/queries/poll_interval.query.graphql';
+import isEnvironmentStoppingQuery from '~/environments/graphql/queries/is_environment_stopping.query.graphql';
import pageInfoQuery from '~/environments/graphql/queries/page_info.query.graphql';
import { TEST_HOST } from 'helpers/test_constants';
import {
@@ -123,10 +124,11 @@ describe('~/frontend/environments/graphql/resolvers', () => {
});
describe('folder', () => {
it('should fetch the folder url passed to it', async () => {
- mock.onGet(ENDPOINT, { params: { per_page: 3 } }).reply(200, folder);
+ mock.onGet(ENDPOINT, { params: { per_page: 3, scope: 'available' } }).reply(200, folder);
const environmentFolder = await mockResolvers.Query.folder(null, {
environment: { folderPath: ENDPOINT },
+ scope: 'available',
});
expect(environmentFolder).toEqual(resolvedFolder);
@@ -136,11 +138,36 @@ describe('~/frontend/environments/graphql/resolvers', () => {
it('should post to the stop environment path', async () => {
mock.onPost(ENDPOINT).reply(200);
- await mockResolvers.Mutation.stopEnvironment(null, { environment: { stopPath: ENDPOINT } });
+ const client = { writeQuery: jest.fn() };
+ const environment = { stopPath: ENDPOINT };
+ await mockResolvers.Mutation.stopEnvironment(null, { environment }, { client });
expect(mock.history.post).toContainEqual(
expect.objectContaining({ url: ENDPOINT, method: 'post' }),
);
+
+ expect(client.writeQuery).toHaveBeenCalledWith({
+ query: isEnvironmentStoppingQuery,
+ variables: { environment },
+ data: { isEnvironmentStopping: true },
+ });
+ });
+ it('should set is stopping to false if stop fails', async () => {
+ mock.onPost(ENDPOINT).reply(500);
+
+ const client = { writeQuery: jest.fn() };
+ const environment = { stopPath: ENDPOINT };
+ await mockResolvers.Mutation.stopEnvironment(null, { environment }, { client });
+
+ expect(mock.history.post).toContainEqual(
+ expect.objectContaining({ url: ENDPOINT, method: 'post' }),
+ );
+
+ expect(client.writeQuery).toHaveBeenCalledWith({
+ query: isEnvironmentStoppingQuery,
+ variables: { environment },
+ data: { isEnvironmentStopping: false },
+ });
});
});
describe('rollbackEnvironment', () => {
diff --git a/spec/frontend/environments/new_environment_folder_spec.js b/spec/frontend/environments/new_environment_folder_spec.js
deleted file mode 100644
index 460263587be..00000000000
--- a/spec/frontend/environments/new_environment_folder_spec.js
+++ /dev/null
@@ -1,100 +0,0 @@
-import VueApollo from 'vue-apollo';
-import Vue, { nextTick } from 'vue';
-import { GlCollapse, GlIcon } from '@gitlab/ui';
-import waitForPromises from 'helpers/wait_for_promises';
-import createMockApollo from 'helpers/mock_apollo_helper';
-import { mountExtended } from 'helpers/vue_test_utils_helper';
-import { stubTransition } from 'helpers/stub_transition';
-import { __, s__ } from '~/locale';
-import EnvironmentsFolder from '~/environments/components/new_environment_folder.vue';
-import EnvironmentItem from '~/environments/components/new_environment_item.vue';
-import { resolvedEnvironmentsApp, resolvedFolder } from './graphql/mock_data';
-
-Vue.use(VueApollo);
-
-describe('~/environments/components/new_environments_folder.vue', () => {
- let wrapper;
- let environmentFolderMock;
- let nestedEnvironment;
- let folderName;
- let button;
-
- const findLink = () => wrapper.findByRole('link', { name: s__('Environments|Show all') });
-
- const createApolloProvider = () => {
- const mockResolvers = { Query: { folder: environmentFolderMock } };
-
- return createMockApollo([], mockResolvers);
- };
-
- const createWrapper = (propsData, apolloProvider) =>
- mountExtended(EnvironmentsFolder, {
- apolloProvider,
- propsData,
- stubs: { transition: stubTransition() },
- provide: { helpPagePath: '/help' },
- });
-
- beforeEach(async () => {
- environmentFolderMock = jest.fn();
- [nestedEnvironment] = resolvedEnvironmentsApp.environments;
- environmentFolderMock.mockReturnValue(resolvedFolder);
- wrapper = createWrapper({ nestedEnvironment }, createApolloProvider());
-
- await nextTick();
- await waitForPromises();
- folderName = wrapper.findByText(nestedEnvironment.name);
- button = wrapper.findByRole('button', { name: __('Expand') });
- });
-
- afterEach(() => {
- wrapper?.destroy();
- });
-
- it('displays the name of the folder', () => {
- expect(folderName.text()).toBe(nestedEnvironment.name);
- });
-
- describe('collapse', () => {
- let icons;
- let collapse;
-
- beforeEach(() => {
- collapse = wrapper.findComponent(GlCollapse);
- icons = wrapper.findAllComponents(GlIcon);
- });
-
- it('is collapsed by default', () => {
- const link = findLink();
-
- expect(collapse.attributes('visible')).toBeUndefined();
- const iconNames = icons.wrappers.map((i) => i.props('name')).slice(0, 2);
- expect(iconNames).toEqual(['angle-right', 'folder-o']);
- expect(folderName.classes('gl-font-weight-bold')).toBe(false);
- expect(link.exists()).toBe(false);
- });
-
- it('opens on click', async () => {
- await button.trigger('click');
-
- const link = findLink();
-
- expect(button.attributes('aria-label')).toBe(__('Collapse'));
- expect(collapse.attributes('visible')).toBe('visible');
- const iconNames = icons.wrappers.map((i) => i.props('name')).slice(0, 2);
- expect(iconNames).toEqual(['angle-down', 'folder-open']);
- expect(folderName.classes('gl-font-weight-bold')).toBe(true);
- expect(link.attributes('href')).toBe(nestedEnvironment.latest.folderPath);
- });
-
- it('displays all environments when opened', async () => {
- await button.trigger('click');
-
- const names = resolvedFolder.environments.map((e) =>
- expect.stringMatching(e.nameWithoutType),
- );
- const environments = wrapper.findAllComponents(EnvironmentItem).wrappers.map((w) => w.text());
- expect(environments).toEqual(expect.arrayContaining(names));
- });
- });
-});
diff --git a/spec/frontend/environments/new_environment_item_spec.js b/spec/frontend/environments/new_environment_item_spec.js
index db596688dad..1d7a33fb95b 100644
--- a/spec/frontend/environments/new_environment_item_spec.js
+++ b/spec/frontend/environments/new_environment_item_spec.js
@@ -24,7 +24,7 @@ describe('~/environments/components/new_environment_item.vue', () => {
mountExtended(EnvironmentItem, {
apolloProvider,
propsData: { environment: resolvedEnvironment, ...propsData },
- provide: { helpPagePath: '/help' },
+ provide: { helpPagePath: '/help', projectId: '1' },
stubs: { transition: stubTransition() },
});
diff --git a/spec/frontend/environments/new_environments_app_spec.js b/spec/frontend/environments/new_environments_app_spec.js
deleted file mode 100644
index 42e3608109b..00000000000
--- a/spec/frontend/environments/new_environments_app_spec.js
+++ /dev/null
@@ -1,329 +0,0 @@
-import Vue, { nextTick } from 'vue';
-import VueApollo from 'vue-apollo';
-import { GlPagination } from '@gitlab/ui';
-import { mountExtended } from 'helpers/vue_test_utils_helper';
-import createMockApollo from 'helpers/mock_apollo_helper';
-import waitForPromises from 'helpers/wait_for_promises';
-import setWindowLocation from 'helpers/set_window_location_helper';
-import { sprintf, __, s__ } from '~/locale';
-import EnvironmentsApp from '~/environments/components/new_environments_app.vue';
-import EnvironmentsFolder from '~/environments/components/new_environment_folder.vue';
-import EnvironmentsItem from '~/environments/components/new_environment_item.vue';
-import StopEnvironmentModal from '~/environments/components/stop_environment_modal.vue';
-import CanaryUpdateModal from '~/environments/components/canary_update_modal.vue';
-import { resolvedEnvironmentsApp, resolvedFolder, resolvedEnvironment } from './graphql/mock_data';
-
-Vue.use(VueApollo);
-
-describe('~/environments/components/new_environments_app.vue', () => {
- let wrapper;
- let environmentAppMock;
- let environmentFolderMock;
- let paginationMock;
- let environmentToStopMock;
- let environmentToChangeCanaryMock;
- let weightMock;
-
- const createApolloProvider = () => {
- const mockResolvers = {
- Query: {
- environmentApp: environmentAppMock,
- folder: environmentFolderMock,
- pageInfo: paginationMock,
- environmentToStop: environmentToStopMock,
- environmentToDelete: jest.fn().mockResolvedValue(resolvedEnvironment),
- environmentToRollback: jest.fn().mockResolvedValue(resolvedEnvironment),
- environmentToChangeCanary: environmentToChangeCanaryMock,
- weight: weightMock,
- },
- };
-
- return createMockApollo([], mockResolvers);
- };
-
- const createWrapper = ({ provide = {}, apolloProvider } = {}) =>
- mountExtended(EnvironmentsApp, {
- provide: {
- newEnvironmentPath: '/environments/new',
- canCreateEnvironment: true,
- defaultBranchName: 'main',
- helpPagePath: '/help',
- ...provide,
- },
- apolloProvider,
- });
-
- const createWrapperWithMocked = async ({
- provide = {},
- environmentsApp,
- folder,
- environmentToStop = {},
- environmentToChangeCanary = {},
- weight = 0,
- pageInfo = {
- total: 20,
- perPage: 5,
- nextPage: 3,
- page: 2,
- previousPage: 1,
- __typename: 'LocalPageInfo',
- },
- }) => {
- setWindowLocation('?scope=available&page=2');
- environmentAppMock.mockReturnValue(environmentsApp);
- environmentFolderMock.mockReturnValue(folder);
- paginationMock.mockReturnValue(pageInfo);
- environmentToStopMock.mockReturnValue(environmentToStop);
- environmentToChangeCanaryMock.mockReturnValue(environmentToChangeCanary);
- weightMock.mockReturnValue(weight);
- const apolloProvider = createApolloProvider();
- wrapper = createWrapper({ apolloProvider, provide });
-
- await waitForPromises();
- await nextTick();
- };
-
- beforeEach(() => {
- environmentAppMock = jest.fn();
- environmentFolderMock = jest.fn();
- environmentToStopMock = jest.fn();
- environmentToChangeCanaryMock = jest.fn();
- weightMock = jest.fn();
- paginationMock = jest.fn();
- });
-
- afterEach(() => {
- wrapper.destroy();
- });
-
- it('should show all the folders that are fetched', async () => {
- await createWrapperWithMocked({
- environmentsApp: resolvedEnvironmentsApp,
- folder: resolvedFolder,
- });
-
- const text = wrapper.findAllComponents(EnvironmentsFolder).wrappers.map((w) => w.text());
-
- expect(text).toContainEqual(expect.stringMatching('review'));
- expect(text).not.toContainEqual(expect.stringMatching('production'));
- });
-
- it('should show all the environments that are fetched', async () => {
- await createWrapperWithMocked({
- environmentsApp: resolvedEnvironmentsApp,
- folder: resolvedFolder,
- });
-
- const text = wrapper.findAllComponents(EnvironmentsItem).wrappers.map((w) => w.text());
-
- expect(text).not.toContainEqual(expect.stringMatching('review'));
- expect(text).toContainEqual(expect.stringMatching('production'));
- });
-
- it('should show a button to create a new environment', async () => {
- await createWrapperWithMocked({
- environmentsApp: resolvedEnvironmentsApp,
- folder: resolvedFolder,
- });
-
- const button = wrapper.findByRole('link', { name: s__('Environments|New environment') });
- expect(button.attributes('href')).toBe('/environments/new');
- });
-
- it('should not show a button to create a new environment if the user has no permissions', async () => {
- await createWrapperWithMocked({
- environmentsApp: resolvedEnvironmentsApp,
- folder: resolvedFolder,
- provide: { canCreateEnvironment: false, newEnvironmentPath: '' },
- });
-
- const button = wrapper.findByRole('link', { name: s__('Environments|New environment') });
- expect(button.exists()).toBe(false);
- });
-
- it('should show a button to open the review app modal', async () => {
- await createWrapperWithMocked({
- environmentsApp: resolvedEnvironmentsApp,
- folder: resolvedFolder,
- });
-
- const button = wrapper.findByRole('button', { name: s__('Environments|Enable review app') });
- button.trigger('click');
-
- await nextTick();
-
- expect(wrapper.findByText(s__('ReviewApp|Enable Review App')).exists()).toBe(true);
- });
-
- it('should not show a button to open the review app modal if review apps are configured', async () => {
- await createWrapperWithMocked({
- environmentsApp: {
- ...resolvedEnvironmentsApp,
- reviewApp: { canSetupReviewApp: false },
- },
- folder: resolvedFolder,
- });
-
- const button = wrapper.findByRole('button', { name: s__('Environments|Enable review app') });
- expect(button.exists()).toBe(false);
- });
-
- describe('tabs', () => {
- it('should show tabs for available and stopped environmets', async () => {
- await createWrapperWithMocked({
- environmentsApp: resolvedEnvironmentsApp,
- folder: resolvedFolder,
- });
-
- const [available, stopped] = wrapper.findAllByRole('tab').wrappers;
-
- expect(available.text()).toContain(__('Available'));
- expect(available.text()).toContain(resolvedEnvironmentsApp.availableCount);
- expect(stopped.text()).toContain(__('Stopped'));
- expect(stopped.text()).toContain(resolvedEnvironmentsApp.stoppedCount);
- });
-
- it('should change the requested scope on tab change', async () => {
- await createWrapperWithMocked({
- environmentsApp: resolvedEnvironmentsApp,
- folder: resolvedFolder,
- });
- const stopped = wrapper.findByRole('tab', {
- name: `${__('Stopped')} ${resolvedEnvironmentsApp.stoppedCount}`,
- });
-
- stopped.trigger('click');
-
- await nextTick();
- await waitForPromises();
-
- expect(environmentAppMock).toHaveBeenCalledWith(
- expect.anything(),
- expect.objectContaining({ scope: 'stopped', page: 1 }),
- expect.anything(),
- expect.anything(),
- );
- });
- });
-
- describe('modals', () => {
- it('should pass the environment to stop to the stop environment modal', async () => {
- await createWrapperWithMocked({
- environmentsApp: resolvedEnvironmentsApp,
- folder: resolvedFolder,
- environmentToStop: resolvedEnvironment,
- });
-
- const modal = wrapper.findComponent(StopEnvironmentModal);
-
- expect(modal.props('environment')).toMatchObject(resolvedEnvironment);
- });
-
- it('should pass the environment to change canary to the canary update modal', async () => {
- await createWrapperWithMocked({
- environmentsApp: resolvedEnvironmentsApp,
- folder: resolvedFolder,
- environmentToChangeCanary: resolvedEnvironment,
- weight: 10,
- });
-
- const modal = wrapper.findComponent(CanaryUpdateModal);
-
- expect(modal.props('environment')).toMatchObject(resolvedEnvironment);
- });
- });
-
- describe('pagination', () => {
- it('should sync page from query params on load', async () => {
- await createWrapperWithMocked({
- environmentsApp: resolvedEnvironmentsApp,
- folder: resolvedFolder,
- });
-
- expect(wrapper.findComponent(GlPagination).props('value')).toBe(2);
- });
-
- it('should change the requested page on next page click', async () => {
- await createWrapperWithMocked({
- environmentsApp: resolvedEnvironmentsApp,
- folder: resolvedFolder,
- });
- const next = wrapper.findByRole('link', {
- name: __('Go to next page'),
- });
-
- next.trigger('click');
-
- await nextTick();
- await waitForPromises();
-
- expect(environmentAppMock).toHaveBeenCalledWith(
- expect.anything(),
- expect.objectContaining({ page: 3 }),
- expect.anything(),
- expect.anything(),
- );
- });
-
- it('should change the requested page on previous page click', async () => {
- await createWrapperWithMocked({
- environmentsApp: resolvedEnvironmentsApp,
- folder: resolvedFolder,
- });
- const prev = wrapper.findByRole('link', {
- name: __('Go to previous page'),
- });
-
- prev.trigger('click');
-
- await nextTick();
- await waitForPromises();
-
- expect(environmentAppMock).toHaveBeenCalledWith(
- expect.anything(),
- expect.objectContaining({ page: 1 }),
- expect.anything(),
- expect.anything(),
- );
- });
-
- it('should change the requested page on specific page click', async () => {
- await createWrapperWithMocked({
- environmentsApp: resolvedEnvironmentsApp,
- folder: resolvedFolder,
- });
-
- const page = 1;
- const pageButton = wrapper.findByRole('link', {
- name: sprintf(__('Go to page %{page}'), { page }),
- });
-
- pageButton.trigger('click');
-
- await nextTick();
- await waitForPromises();
-
- expect(environmentAppMock).toHaveBeenCalledWith(
- expect.anything(),
- expect.objectContaining({ page }),
- expect.anything(),
- expect.anything(),
- );
- });
-
- it('should sync the query params to the new page', async () => {
- await createWrapperWithMocked({
- environmentsApp: resolvedEnvironmentsApp,
- folder: resolvedFolder,
- });
- const next = wrapper.findByRole('link', {
- name: __('Go to next page'),
- });
-
- next.trigger('click');
-
- await nextTick();
- expect(window.location.search).toBe('?scope=available&page=3');
- });
- });
-});
diff --git a/spec/frontend/error_tracking/components/error_details_spec.js b/spec/frontend/error_tracking/components/error_details_spec.js
index 03ae437a89e..4273da6c735 100644
--- a/spec/frontend/error_tracking/components/error_details_spec.js
+++ b/spec/frontend/error_tracking/components/error_details_spec.js
@@ -10,11 +10,7 @@ import {
import { shallowMount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
import Vuex from 'vuex';
-import {
- severityLevel,
- severityLevelVariant,
- errorStatus,
-} from '~/error_tracking/components/constants';
+import { severityLevel, severityLevelVariant, errorStatus } from '~/error_tracking/constants';
import ErrorDetails from '~/error_tracking/components/error_details.vue';
import Stacktrace from '~/error_tracking/components/stacktrace.vue';
import {
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 59671c175e7..5e0f0ca9bef 100644
--- a/spec/frontend/error_tracking/components/error_tracking_list_spec.js
+++ b/spec/frontend/error_tracking/components/error_tracking_list_spec.js
@@ -7,6 +7,7 @@ import ErrorTrackingActions from '~/error_tracking/components/error_tracking_act
import ErrorTrackingList from '~/error_tracking/components/error_tracking_list.vue';
import { trackErrorListViewsOptions, trackErrorStatusUpdateOptions } from '~/error_tracking/utils';
import Tracking from '~/tracking';
+import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import errorsList from './list_mock.json';
Vue.use(Vuex);
@@ -25,28 +26,33 @@ describe('ErrorTrackingList', () => {
const findLoadingIcon = () => wrapper.find(GlLoadingIcon);
const findPagination = () => wrapper.find(GlPagination);
const findErrorActions = () => wrapper.find(ErrorTrackingActions);
+ const findIntegratedDisabledAlert = () => wrapper.findByTestId('integrated-disabled-alert');
function mountComponent({
errorTrackingEnabled = true,
userCanEnableErrorTracking = true,
+ showIntegratedTrackingDisabledAlert = false,
stubs = {},
} = {}) {
- wrapper = mount(ErrorTrackingList, {
- store,
- propsData: {
- indexPath: '/path',
- listPath: '/error_tracking',
- projectPath: 'project/test',
- enableErrorTrackingLink: '/link',
- userCanEnableErrorTracking,
- errorTrackingEnabled,
- illustrationPath: 'illustration/path',
- },
- stubs: {
- ...stubChildren(ErrorTrackingList),
- ...stubs,
- },
- });
+ wrapper = extendedWrapper(
+ mount(ErrorTrackingList, {
+ store,
+ propsData: {
+ indexPath: '/path',
+ listPath: '/error_tracking',
+ projectPath: 'project/test',
+ enableErrorTrackingLink: '/link',
+ userCanEnableErrorTracking,
+ errorTrackingEnabled,
+ showIntegratedTrackingDisabledAlert,
+ illustrationPath: 'illustration/path',
+ },
+ stubs: {
+ ...stubChildren(ErrorTrackingList),
+ ...stubs,
+ },
+ }),
+ );
}
beforeEach(() => {
@@ -223,6 +229,31 @@ describe('ErrorTrackingList', () => {
});
});
+ describe('When the integrated tracking diabled alert should be shown', () => {
+ beforeEach(() => {
+ mountComponent({
+ showIntegratedTrackingDisabledAlert: true,
+ stubs: {
+ GlAlert: false,
+ },
+ });
+ });
+
+ it('shows the alert box', () => {
+ expect(findIntegratedDisabledAlert().exists()).toBe(true);
+ });
+
+ describe('when alert is dismissed', () => {
+ it('hides the alert box', async () => {
+ findIntegratedDisabledAlert().vm.$emit('dismiss');
+
+ await nextTick();
+
+ expect(findIntegratedDisabledAlert().exists()).toBe(false);
+ });
+ });
+ });
+
describe('When the ignore button on an error is clicked', () => {
beforeEach(() => {
store.state.list.loading = false;
@@ -367,21 +398,6 @@ describe('ErrorTrackingList', () => {
});
describe('When pagination is required', () => {
- describe('and the user is on the first page', () => {
- beforeEach(() => {
- store.state.list.loading = false;
- mountComponent({
- stubs: {
- GlPagination: false,
- },
- });
- });
-
- it('shows a disabled Prev button', () => {
- expect(wrapper.find('.prev-page-item').attributes('aria-disabled')).toBe('true');
- });
- });
-
describe('and the user is not on the first page', () => {
describe('and the previous button is clicked', () => {
beforeEach(async () => {
diff --git a/spec/frontend/error_tracking_settings/components/app_spec.js b/spec/frontend/error_tracking_settings/components/app_spec.js
index 4d19ec047ef..4a0bbb1acbe 100644
--- a/spec/frontend/error_tracking_settings/components/app_spec.js
+++ b/spec/frontend/error_tracking_settings/components/app_spec.js
@@ -18,19 +18,27 @@ describe('error tracking settings app', () => {
let store;
let wrapper;
- function mountComponent() {
+ const defaultProps = {
+ initialEnabled: 'true',
+ initialIntegrated: 'false',
+ initialApiHost: TEST_HOST,
+ initialToken: 'someToken',
+ initialProject: null,
+ listProjectsEndpoint: TEST_HOST,
+ operationsSettingsEndpoint: TEST_HOST,
+ gitlabDsn: TEST_GITLAB_DSN,
+ };
+
+ function mountComponent({
+ glFeatures = { integratedErrorTracking: false },
+ props = defaultProps,
+ } = {}) {
wrapper = extendedWrapper(
shallowMount(ErrorTrackingSettings, {
store, // Override the imported store
- propsData: {
- initialEnabled: 'true',
- initialIntegrated: 'false',
- initialApiHost: TEST_HOST,
- initialToken: 'someToken',
- initialProject: null,
- listProjectsEndpoint: TEST_HOST,
- operationsSettingsEndpoint: TEST_HOST,
- gitlabDsn: TEST_GITLAB_DSN,
+ propsData: { ...props },
+ provide: {
+ glFeatures,
},
stubs: {
GlFormInputGroup, // we need this non-shallow to query for a component within a slot
@@ -47,6 +55,7 @@ describe('error tracking settings app', () => {
const findElementWithText = (wrappers, text) => wrappers.filter((item) => item.text() === text);
const findSentrySettings = () => wrapper.findByTestId('sentry-setting-form');
const findDsnSettings = () => wrapper.findByTestId('gitlab-dsn-setting-form');
+ const findEnabledCheckbox = () => wrapper.findByTestId('error-tracking-enabled');
const enableGitLabErrorTracking = async () => {
findBackendSettingsRadioGroup().vm.$emit('change', true);
@@ -88,62 +97,104 @@ describe('error tracking settings app', () => {
});
describe('tracking-backend settings', () => {
- it('contains a form-group with the correct label', () => {
- expect(findBackendSettingsSection().attributes('label')).toBe('Error tracking backend');
+ it('does not contain backend settings section', () => {
+ expect(findBackendSettingsSection().exists()).toBe(false);
});
- it('contains a radio group', () => {
- expect(findBackendSettingsRadioGroup().exists()).toBe(true);
+ it('shows the sentry form', () => {
+ expect(findSentrySettings().exists()).toBe(true);
});
- it('contains the correct radio buttons', () => {
- expect(findBackendSettingsRadioButtons()).toHaveLength(2);
+ describe('enabled setting is true', () => {
+ describe('integrated setting is true', () => {
+ beforeEach(() => {
+ mountComponent({
+ props: { ...defaultProps, initialEnabled: 'true', initialIntegrated: 'true' },
+ });
+ });
+
+ it('displays enabled as false', () => {
+ expect(findEnabledCheckbox().attributes('checked')).toBeUndefined();
+ });
+ });
+
+ describe('integrated setting is false', () => {
+ beforeEach(() => {
+ mountComponent({
+ props: { ...defaultProps, initialEnabled: 'true', initialIntegrated: 'false' },
+ });
+ });
- expect(findElementWithText(findBackendSettingsRadioButtons(), 'Sentry')).toHaveLength(1);
- expect(findElementWithText(findBackendSettingsRadioButtons(), 'GitLab')).toHaveLength(1);
+ it('displays enabled as true', () => {
+ expect(findEnabledCheckbox().attributes('checked')).toBe('true');
+ });
+ });
});
- it('hides the Sentry settings when GitLab is selected as a tracking-backend', async () => {
- expect(findSentrySettings().exists()).toBe(true);
+ describe('integrated_error_tracking feature flag enabled', () => {
+ beforeEach(() => {
+ mountComponent({
+ glFeatures: { integratedErrorTracking: true },
+ });
+ });
- await enableGitLabErrorTracking();
+ it('contains a form-group with the correct label', () => {
+ expect(findBackendSettingsSection().attributes('label')).toBe('Error tracking backend');
+ });
- expect(findSentrySettings().exists()).toBe(false);
- });
+ it('contains a radio group', () => {
+ expect(findBackendSettingsRadioGroup().exists()).toBe(true);
+ });
- describe('GitLab DSN section', () => {
- it('is visible when GitLab is selected as a tracking-backend and DSN is present', async () => {
- expect(findDsnSettings().exists()).toBe(false);
+ it('contains the correct radio buttons', () => {
+ expect(findBackendSettingsRadioButtons()).toHaveLength(2);
+
+ expect(findElementWithText(findBackendSettingsRadioButtons(), 'Sentry')).toHaveLength(1);
+ expect(findElementWithText(findBackendSettingsRadioButtons(), 'GitLab')).toHaveLength(1);
+ });
+
+ it('hides the Sentry settings when GitLab is selected as a tracking-backend', async () => {
+ expect(findSentrySettings().exists()).toBe(true);
await enableGitLabErrorTracking();
- expect(findDsnSettings().exists()).toBe(true);
+ expect(findSentrySettings().exists()).toBe(false);
});
- it('contains copy-to-clipboard functionality for the GitLab DSN string', async () => {
- await enableGitLabErrorTracking();
+ describe('GitLab DSN section', () => {
+ it('is visible when GitLab is selected as a tracking-backend and DSN is present', async () => {
+ expect(findDsnSettings().exists()).toBe(false);
+
+ await enableGitLabErrorTracking();
+
+ expect(findDsnSettings().exists()).toBe(true);
+ });
- const clipBoardInput = findDsnSettings().findComponent(GlFormInputGroup);
- const clipBoardButton = findDsnSettings().findComponent(ClipboardButton);
+ it('contains copy-to-clipboard functionality for the GitLab DSN string', async () => {
+ await enableGitLabErrorTracking();
- expect(clipBoardInput.props('value')).toBe(TEST_GITLAB_DSN);
- expect(clipBoardInput.attributes('readonly')).toBeTruthy();
- expect(clipBoardButton.props('text')).toBe(TEST_GITLAB_DSN);
+ const clipBoardInput = findDsnSettings().findComponent(GlFormInputGroup);
+ const clipBoardButton = findDsnSettings().findComponent(ClipboardButton);
+
+ expect(clipBoardInput.props('value')).toBe(TEST_GITLAB_DSN);
+ expect(clipBoardInput.attributes('readonly')).toBeTruthy();
+ expect(clipBoardButton.props('text')).toBe(TEST_GITLAB_DSN);
+ });
});
- });
- it.each([true, false])(
- 'calls the `updateIntegrated` action when the setting changes to `%s`',
- (integrated) => {
- jest.spyOn(store, 'dispatch').mockImplementation();
+ it.each([true, false])(
+ 'calls the `updateIntegrated` action when the setting changes to `%s`',
+ (integrated) => {
+ jest.spyOn(store, 'dispatch').mockImplementation();
- expect(store.dispatch).toHaveBeenCalledTimes(0);
+ expect(store.dispatch).toHaveBeenCalledTimes(0);
- findBackendSettingsRadioGroup().vm.$emit('change', integrated);
+ findBackendSettingsRadioGroup().vm.$emit('change', integrated);
- expect(store.dispatch).toHaveBeenCalledTimes(1);
- expect(store.dispatch).toHaveBeenCalledWith('updateIntegrated', integrated);
- },
- );
+ expect(store.dispatch).toHaveBeenCalledTimes(1);
+ expect(store.dispatch).toHaveBeenCalledWith('updateIntegrated', integrated);
+ },
+ );
+ });
});
});
diff --git a/spec/frontend/fixtures/merge_requests.rb b/spec/frontend/fixtures/merge_requests.rb
index 1eb48c0ce2c..cb4eb43b88d 100644
--- a/spec/frontend/fixtures/merge_requests.rb
+++ b/spec/frontend/fixtures/merge_requests.rb
@@ -130,6 +130,25 @@ RSpec.describe Projects::MergeRequestsController, '(JavaScript fixtures)', type:
expect(response).to be_successful
end
+ describe GraphQL::Query, type: :request do
+ include ApiHelpers
+ include GraphqlHelpers
+
+ context 'merge request in state readyToMerge query' do
+ base_input_path = 'vue_merge_request_widget/queries/states/'
+ base_output_path = 'graphql/merge_requests/states/'
+ query_name = 'ready_to_merge.query.graphql'
+
+ it "#{base_output_path}#{query_name}.json" do
+ query = get_graphql_query_as_string("#{base_input_path}#{query_name}", ee: Gitlab.ee?)
+
+ post_graphql(query, current_user: user, variables: { projectPath: project.full_path, iid: merge_request.iid.to_s })
+
+ expect_graphql_errors_to_be_empty
+ end
+ end
+ end
+
private
def render_discussions_json(merge_request)
diff --git a/spec/frontend/fixtures/runner.rb b/spec/frontend/fixtures/runner.rb
index cdb4c3fd8ba..25049ee4722 100644
--- a/spec/frontend/fixtures/runner.rb
+++ b/spec/frontend/fixtures/runner.rb
@@ -33,19 +33,19 @@ RSpec.describe 'Runner (JavaScript fixtures)' do
end
describe GraphQL::Query, type: :request do
- get_runners_query_name = 'get_runners.query.graphql'
+ admin_runners_query = 'list/admin_runners.query.graphql'
let_it_be(:query) do
- get_graphql_query_as_string("#{query_path}#{get_runners_query_name}")
+ get_graphql_query_as_string("#{query_path}#{admin_runners_query}")
end
- it "#{fixtures_path}#{get_runners_query_name}.json" do
+ it "#{fixtures_path}#{admin_runners_query}.json" do
post_graphql(query, current_user: admin, variables: {})
expect_graphql_errors_to_be_empty
end
- it "#{fixtures_path}#{get_runners_query_name}.paginated.json" do
+ it "#{fixtures_path}#{admin_runners_query}.paginated.json" do
post_graphql(query, current_user: admin, variables: { first: 2 })
expect_graphql_errors_to_be_empty
@@ -53,13 +53,13 @@ RSpec.describe 'Runner (JavaScript fixtures)' do
end
describe GraphQL::Query, type: :request do
- get_runners_count_query_name = 'get_runners_count.query.graphql'
+ admin_runners_count_query = 'list/admin_runners_count.query.graphql'
let_it_be(:query) do
- get_graphql_query_as_string("#{query_path}#{get_runners_count_query_name}")
+ get_graphql_query_as_string("#{query_path}#{admin_runners_count_query}")
end
- it "#{fixtures_path}#{get_runners_count_query_name}.json" do
+ it "#{fixtures_path}#{admin_runners_count_query}.json" do
post_graphql(query, current_user: admin, variables: {})
expect_graphql_errors_to_be_empty
@@ -67,13 +67,13 @@ RSpec.describe 'Runner (JavaScript fixtures)' do
end
describe GraphQL::Query, type: :request do
- get_runner_query_name = 'get_runner.query.graphql'
+ runner_query = 'details/runner.query.graphql'
let_it_be(:query) do
- get_graphql_query_as_string("#{query_path}#{get_runner_query_name}")
+ get_graphql_query_as_string("#{query_path}#{runner_query}")
end
- it "#{fixtures_path}#{get_runner_query_name}.json" do
+ it "#{fixtures_path}#{runner_query}.json" do
post_graphql(query, current_user: admin, variables: {
id: instance_runner.to_global_id.to_s
})
@@ -81,7 +81,7 @@ RSpec.describe 'Runner (JavaScript fixtures)' do
expect_graphql_errors_to_be_empty
end
- it "#{fixtures_path}#{get_runner_query_name}.with_group.json" do
+ it "#{fixtures_path}#{runner_query}.with_group.json" do
post_graphql(query, current_user: admin, variables: {
id: group_runner.to_global_id.to_s
})
@@ -91,13 +91,13 @@ RSpec.describe 'Runner (JavaScript fixtures)' do
end
describe GraphQL::Query, type: :request do
- get_runner_projects_query_name = 'get_runner_projects.query.graphql'
+ runner_projects_query = 'details/runner_projects.query.graphql'
let_it_be(:query) do
- get_graphql_query_as_string("#{query_path}#{get_runner_projects_query_name}")
+ get_graphql_query_as_string("#{query_path}#{runner_projects_query}")
end
- it "#{fixtures_path}#{get_runner_projects_query_name}.json" do
+ it "#{fixtures_path}#{runner_projects_query}.json" do
post_graphql(query, current_user: admin, variables: {
id: project_runner.to_global_id.to_s
})
@@ -107,13 +107,13 @@ RSpec.describe 'Runner (JavaScript fixtures)' do
end
describe GraphQL::Query, type: :request do
- get_runner_jobs_query_name = 'get_runner_jobs.query.graphql'
+ runner_jobs_query = 'details/runner_jobs.query.graphql'
let_it_be(:query) do
- get_graphql_query_as_string("#{query_path}#{get_runner_jobs_query_name}")
+ get_graphql_query_as_string("#{query_path}#{runner_jobs_query}")
end
- it "#{fixtures_path}#{get_runner_jobs_query_name}.json" do
+ it "#{fixtures_path}#{runner_jobs_query}.json" do
post_graphql(query, current_user: admin, variables: {
id: instance_runner.to_global_id.to_s
})
@@ -131,13 +131,13 @@ RSpec.describe 'Runner (JavaScript fixtures)' do
end
describe GraphQL::Query, type: :request do
- get_group_runners_query_name = 'get_group_runners.query.graphql'
+ group_runners_query = 'list/group_runners.query.graphql'
let_it_be(:query) do
- get_graphql_query_as_string("#{query_path}#{get_group_runners_query_name}")
+ get_graphql_query_as_string("#{query_path}#{group_runners_query}")
end
- it "#{fixtures_path}#{get_group_runners_query_name}.json" do
+ it "#{fixtures_path}#{group_runners_query}.json" do
post_graphql(query, current_user: group_owner, variables: {
groupFullPath: group.full_path
})
@@ -145,7 +145,7 @@ RSpec.describe 'Runner (JavaScript fixtures)' do
expect_graphql_errors_to_be_empty
end
- it "#{fixtures_path}#{get_group_runners_query_name}.paginated.json" do
+ it "#{fixtures_path}#{group_runners_query}.paginated.json" do
post_graphql(query, current_user: group_owner, variables: {
groupFullPath: group.full_path,
first: 1
@@ -156,13 +156,13 @@ RSpec.describe 'Runner (JavaScript fixtures)' do
end
describe GraphQL::Query, type: :request do
- get_group_runners_count_query_name = 'get_group_runners_count.query.graphql'
+ group_runners_count_query = 'list/group_runners_count.query.graphql'
let_it_be(:query) do
- get_graphql_query_as_string("#{query_path}#{get_group_runners_count_query_name}")
+ get_graphql_query_as_string("#{query_path}#{group_runners_count_query}")
end
- it "#{fixtures_path}#{get_group_runners_count_query_name}.json" do
+ it "#{fixtures_path}#{group_runners_count_query}.json" do
post_graphql(query, current_user: group_owner, variables: {
groupFullPath: group.full_path
})
diff --git a/spec/frontend/google_cloud/components/app_spec.js b/spec/frontend/google_cloud/components/app_spec.js
index 5ddc0ffa50f..50b05fb30e0 100644
--- a/spec/frontend/google_cloud/components/app_spec.js
+++ b/spec/frontend/google_cloud/components/app_spec.js
@@ -17,15 +17,18 @@ const SCREEN_COMPONENTS = {
};
const SERVICE_ACCOUNTS_FORM_PROPS = {
gcpProjects: [1, 2, 3],
- environments: [4, 5, 6],
+ refs: [4, 5, 6],
cancelPath: '',
};
const HOME_PROPS = {
serviceAccounts: [{}, {}],
+ gcpRegions: [{}, {}],
createServiceAccountUrl: '#url-create-service-account',
+ configureGcpRegionsUrl: '#url-configure-gcp-regions',
emptyIllustrationUrl: '#url-empty-illustration',
enableCloudRunUrl: '#url-enable-cloud-run',
enableCloudStorageUrl: '#enableCloudStorageUrl',
+ revokeOauthUrl: '#revokeOauthUrl',
};
describe('google_cloud App component', () => {
diff --git a/spec/frontend/google_cloud/components/gcp_regions_form_spec.js b/spec/frontend/google_cloud/components/gcp_regions_form_spec.js
new file mode 100644
index 00000000000..a8b7593e7c8
--- /dev/null
+++ b/spec/frontend/google_cloud/components/gcp_regions_form_spec.js
@@ -0,0 +1,59 @@
+import { shallowMount } from '@vue/test-utils';
+import { GlButton, GlFormGroup, GlFormSelect } from '@gitlab/ui';
+import GcpRegionsForm from '~/google_cloud/components/gcp_regions_form.vue';
+
+describe('GcpRegionsForm component', () => {
+ let wrapper;
+
+ const findHeader = () => wrapper.find('header');
+ const findAllFormGroups = () => wrapper.findAllComponents(GlFormGroup);
+ const findAllFormSelects = () => wrapper.findAllComponents(GlFormSelect);
+ const findAllButtons = () => wrapper.findAllComponents(GlButton);
+
+ const propsData = { availableRegions: [], refs: [], cancelPath: '#cancel-url' };
+
+ beforeEach(() => {
+ wrapper = shallowMount(GcpRegionsForm, { propsData });
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ it('contains header', () => {
+ expect(findHeader().exists()).toBe(true);
+ });
+
+ it('contains Regions form group', () => {
+ const formGroup = findAllFormGroups().at(0);
+ expect(formGroup.exists()).toBe(true);
+ });
+
+ it('contains Regions dropdown', () => {
+ const select = findAllFormSelects().at(0);
+ expect(select.exists()).toBe(true);
+ });
+
+ it('contains Refs form group', () => {
+ const formGroup = findAllFormGroups().at(1);
+ expect(formGroup.exists()).toBe(true);
+ });
+
+ it('contains Refs dropdown', () => {
+ const select = findAllFormSelects().at(1);
+ expect(select.exists()).toBe(true);
+ });
+
+ it('contains Submit button', () => {
+ const button = findAllButtons().at(0);
+ expect(button.exists()).toBe(true);
+ expect(button.text()).toBe(GcpRegionsForm.i18n.submitLabel);
+ });
+
+ it('contains Cancel button', () => {
+ const button = findAllButtons().at(1);
+ expect(button.exists()).toBe(true);
+ expect(button.text()).toBe(GcpRegionsForm.i18n.cancelLabel);
+ expect(button.attributes('href')).toBe('#cancel-url');
+ });
+});
diff --git a/spec/frontend/google_cloud/components/gcp_regions_list_spec.js b/spec/frontend/google_cloud/components/gcp_regions_list_spec.js
new file mode 100644
index 00000000000..ab0c17451e8
--- /dev/null
+++ b/spec/frontend/google_cloud/components/gcp_regions_list_spec.js
@@ -0,0 +1,79 @@
+import { mount } from '@vue/test-utils';
+import { GlButton, GlEmptyState, GlTable } from '@gitlab/ui';
+import GcpRegionsList from '~/google_cloud/components/gcp_regions_list.vue';
+
+describe('GcpRegions component', () => {
+ describe('when the project does not have any configured regions', () => {
+ let wrapper;
+
+ const findEmptyState = () => wrapper.findComponent(GlEmptyState);
+ const findButtonInEmptyState = () => findEmptyState().findComponent(GlButton);
+
+ beforeEach(() => {
+ const propsData = {
+ list: [],
+ createUrl: '#create-url',
+ emptyIllustrationUrl: '#empty-illustration-url',
+ };
+ wrapper = mount(GcpRegionsList, { propsData });
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ it('shows the empty state component', () => {
+ expect(findEmptyState().exists()).toBe(true);
+ });
+ it('shows the link to create new service accounts', () => {
+ const button = findButtonInEmptyState();
+ expect(button.exists()).toBe(true);
+ expect(button.text()).toBe('Configure regions');
+ expect(button.attributes('href')).toBe('#create-url');
+ });
+ });
+
+ describe('when three gcp regions are passed via props', () => {
+ let wrapper;
+
+ const findTitle = () => wrapper.find('h2');
+ const findDescription = () => wrapper.find('p');
+ const findTable = () => wrapper.findComponent(GlTable);
+ const findRows = () => findTable().findAll('tr');
+ const findButton = () => wrapper.findComponent(GlButton);
+
+ beforeEach(() => {
+ const propsData = {
+ list: [{}, {}, {}],
+ createUrl: '#create-url',
+ emptyIllustrationUrl: '#empty-illustration-url',
+ };
+ wrapper = mount(GcpRegionsList, { propsData });
+ });
+
+ it('shows the title', () => {
+ expect(findTitle().text()).toBe('Regions');
+ });
+
+ it('shows the description', () => {
+ expect(findDescription().text()).toBe(
+ 'Configure your environments to be deployed to specific geographical regions',
+ );
+ });
+
+ it('shows the table', () => {
+ expect(findTable().exists()).toBe(true);
+ });
+
+ it('table must have three rows + header row', () => {
+ expect(findRows()).toHaveLength(4);
+ });
+
+ it('shows the link to create new service accounts', () => {
+ const button = findButton();
+ expect(button.exists()).toBe(true);
+ expect(button.text()).toBe('Configure regions');
+ expect(button.attributes('href')).toBe('#create-url');
+ });
+ });
+});
diff --git a/spec/frontend/google_cloud/components/home_spec.js b/spec/frontend/google_cloud/components/home_spec.js
index 57cf831b19b..42e3d72577d 100644
--- a/spec/frontend/google_cloud/components/home_spec.js
+++ b/spec/frontend/google_cloud/components/home_spec.js
@@ -18,10 +18,13 @@ describe('google_cloud Home component', () => {
const TEST_HOME_PROPS = {
serviceAccounts: [{}, {}],
+ gcpRegions: [{}, {}],
createServiceAccountUrl: '#url-create-service-account',
+ configureGcpRegionsUrl: '#url-configure-gcp-regions',
emptyIllustrationUrl: '#url-empty-illustration',
enableCloudRunUrl: '#url-enable-cloud-run',
enableCloudStorageUrl: '#enableCloudStorageUrl',
+ revokeOauthUrl: '#revokeOauthUrl',
};
beforeEach(() => {
diff --git a/spec/frontend/google_cloud/components/revoke_oauth_spec.js b/spec/frontend/google_cloud/components/revoke_oauth_spec.js
new file mode 100644
index 00000000000..87580dbf6de
--- /dev/null
+++ b/spec/frontend/google_cloud/components/revoke_oauth_spec.js
@@ -0,0 +1,47 @@
+import { shallowMount } from '@vue/test-utils';
+import { GlButton, GlForm } from '@gitlab/ui';
+import RevokeOauth, {
+ GOOGLE_CLOUD_REVOKE_TITLE,
+ GOOGLE_CLOUD_REVOKE_DESCRIPTION,
+} from '~/google_cloud/components/revoke_oauth.vue';
+
+describe('RevokeOauth component', () => {
+ let wrapper;
+
+ const findTitle = () => wrapper.find('h2');
+ const findDescription = () => wrapper.find('p');
+ const findForm = () => wrapper.findComponent(GlForm);
+ const findButton = () => wrapper.findComponent(GlButton);
+ const propsData = {
+ url: 'url_general_feedback',
+ };
+
+ beforeEach(() => {
+ wrapper = shallowMount(RevokeOauth, { propsData });
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ it('contains title', () => {
+ const title = findTitle();
+ expect(title.text()).toContain('Revoke authorizations');
+ });
+
+ it('contains description', () => {
+ const description = findDescription();
+ expect(description.text()).toContain(GOOGLE_CLOUD_REVOKE_DESCRIPTION);
+ });
+
+ it('contains form', () => {
+ const form = findForm();
+ expect(form.attributes('action')).toBe(propsData.url);
+ expect(form.attributes('method')).toBe('post');
+ });
+
+ it('contains button', () => {
+ const button = findButton();
+ expect(button.text()).toContain(GOOGLE_CLOUD_REVOKE_TITLE);
+ });
+});
diff --git a/spec/frontend/google_cloud/components/service_accounts_form_spec.js b/spec/frontend/google_cloud/components/service_accounts_form_spec.js
index 7262e12c84d..38602d4e8cc 100644
--- a/spec/frontend/google_cloud/components/service_accounts_form_spec.js
+++ b/spec/frontend/google_cloud/components/service_accounts_form_spec.js
@@ -11,7 +11,7 @@ describe('ServiceAccountsForm component', () => {
const findAllButtons = () => wrapper.findAllComponents(GlButton);
const findCheckbox = () => wrapper.findComponent(GlFormCheckbox);
- const propsData = { gcpProjects: [], environments: [], cancelPath: '#cancel-url' };
+ const propsData = { gcpProjects: [], refs: [], cancelPath: '#cancel-url' };
beforeEach(() => {
wrapper = shallowMount(ServiceAccountsForm, { propsData, stubs: { GlFormCheckbox } });
diff --git a/spec/frontend/google_tag_manager/index_spec.js b/spec/frontend/google_tag_manager/index_spec.js
index 9112b0e17e7..de4a57a7319 100644
--- a/spec/frontend/google_tag_manager/index_spec.js
+++ b/spec/frontend/google_tag_manager/index_spec.js
@@ -1,16 +1,18 @@
import { merge } from 'lodash';
import { v4 as uuidv4 } from 'uuid';
import {
+ trackCombinedGroupProjectForm,
trackFreeTrialAccountSubmissions,
+ trackProjectImport,
trackNewRegistrations,
trackSaasTrialSubmit,
trackSaasTrialSkip,
trackSaasTrialGroup,
trackSaasTrialProject,
- trackSaasTrialProjectImport,
trackSaasTrialGetStarted,
trackCheckout,
trackTransaction,
+ trackAddToCartUsageTab,
} from '~/google_tag_manager';
import { setHTMLFixture } from 'helpers/fixtures';
import { logError } from '~/lib/logger';
@@ -148,20 +150,20 @@ describe('~/google_tag_manager/index', () => {
createTestCase(trackSaasTrialProject, {
forms: [{ id: 'new_project', expectation: { event: 'saasTrialProject' } }],
}),
- createTestCase(trackSaasTrialProjectImport, {
+ createTestCase(trackProjectImport, {
links: [
{
id: 'js-test-btn-0',
cls: 'js-import-project-btn',
attributes: { 'data-platform': 'bitbucket' },
- expectation: { event: 'saasTrialProjectImport', saasProjectImport: 'bitbucket' },
+ expectation: { event: 'projectImport', platform: 'bitbucket' },
},
{
// id is neeeded so we trigger the right element in the test
id: 'js-test-btn-1',
cls: 'js-import-project-btn',
attributes: { 'data-platform': 'github' },
- expectation: { event: 'saasTrialProjectImport', saasProjectImport: 'github' },
+ expectation: { event: 'projectImport', platform: 'github' },
},
],
}),
@@ -173,6 +175,40 @@ describe('~/google_tag_manager/index', () => {
},
],
}),
+ createTestCase(trackAddToCartUsageTab, {
+ links: [
+ {
+ cls: 'js-buy-additional-minutes',
+ expectation: {
+ event: 'EECproductAddToCart',
+ ecommerce: {
+ currencyCode: 'USD',
+ add: {
+ products: [
+ {
+ name: 'CI/CD Minutes',
+ id: '0003',
+ price: '10',
+ brand: 'GitLab',
+ category: 'DevOps',
+ variant: 'add-on',
+ quantity: 1,
+ },
+ ],
+ },
+ },
+ },
+ },
+ ],
+ }),
+ createTestCase(trackCombinedGroupProjectForm, {
+ forms: [
+ {
+ cls: 'js-groups-projects-form',
+ expectation: { event: 'combinedGroupProjectFormSubmit' },
+ },
+ ],
+ }),
])('%p', (subject, { links = [], forms = [], expectedEvents }) => {
beforeEach(() => {
setHTMLFixture(createHTML({ links, forms }));
diff --git a/spec/frontend/graphql_shared/utils_spec.js b/spec/frontend/graphql_shared/utils_spec.js
index 9f478eedbfb..bf899e47d1c 100644
--- a/spec/frontend/graphql_shared/utils_spec.js
+++ b/spec/frontend/graphql_shared/utils_spec.js
@@ -95,7 +95,7 @@ describe('convertToGraphQLIds', () => {
it.each`
type | ids | message
- ${mockType} | ${null} | ${"Cannot read property 'map' of null"}
+ ${mockType} | ${null} | ${"Cannot read properties of null (reading 'map')"}
${mockType} | ${[mockId, null]} | ${'id must be a number or string; got object'}
${null} | ${[mockId]} | ${'type must be a string; got object'}
`('throws TypeError with "$message" if a param is missing', ({ type, ids, message }) => {
diff --git a/spec/frontend/header_search/components/header_search_autocomplete_items_spec.js b/spec/frontend/header_search/components/header_search_autocomplete_items_spec.js
index 502f10ff771..f427482be46 100644
--- a/spec/frontend/header_search/components/header_search_autocomplete_items_spec.js
+++ b/spec/frontend/header_search/components/header_search_autocomplete_items_spec.js
@@ -1,4 +1,4 @@
-import { GlDropdownItem, GlLoadingIcon, GlAvatar } from '@gitlab/ui';
+import { GlDropdownItem, GlLoadingIcon, GlAvatar, GlAlert } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
import Vuex from 'vuex';
@@ -46,6 +46,7 @@ describe('HeaderSearchAutocompleteItems', () => {
const findDropdownItemLinks = () => findDropdownItems().wrappers.map((w) => w.attributes('href'));
const findGlLoadingIcon = () => wrapper.findComponent(GlLoadingIcon);
const findGlAvatar = () => wrapper.findComponent(GlAvatar);
+ const findGlAlert = () => wrapper.findComponent(GlAlert);
describe('template', () => {
describe('when loading is true', () => {
@@ -62,6 +63,15 @@ describe('HeaderSearchAutocompleteItems', () => {
});
});
+ describe('when api returns error', () => {
+ beforeEach(() => {
+ createComponent({ autocompleteError: true });
+ });
+
+ it('renders Alert', () => {
+ expect(findGlAlert().exists()).toBe(true);
+ });
+ });
describe('when loading is false', () => {
beforeEach(() => {
createComponent({ loading: false });
@@ -86,6 +96,7 @@ describe('HeaderSearchAutocompleteItems', () => {
expect(findDropdownItemLinks()).toStrictEqual(expectedLinks);
});
});
+
describe.each`
item | showAvatar | avatarSize
${{ data: [{ category: PROJECTS_CATEGORY, avatar_url: null }] }} | ${true} | ${String(LARGE_AVATAR_PX)}
diff --git a/spec/frontend/header_search/store/actions_spec.js b/spec/frontend/header_search/store/actions_spec.js
index 6599115f017..1748d89a6d3 100644
--- a/spec/frontend/header_search/store/actions_spec.js
+++ b/spec/frontend/header_search/store/actions_spec.js
@@ -1,6 +1,5 @@
import MockAdapter from 'axios-mock-adapter';
import testAction from 'helpers/vuex_action_helper';
-import createFlash from '~/flash';
import * as actions from '~/header_search/store/actions';
import * as types from '~/header_search/store/mutation_types';
import createState from '~/header_search/store/state';
@@ -13,11 +12,6 @@ describe('Header Search Store Actions', () => {
let state;
let mock;
- const flashCallback = (callCount) => {
- expect(createFlash).toHaveBeenCalledTimes(callCount);
- createFlash.mockClear();
- };
-
beforeEach(() => {
state = createState({});
mock = new MockAdapter(axios);
@@ -29,10 +23,10 @@ describe('Header Search Store Actions', () => {
});
describe.each`
- axiosMock | type | expectedMutations | flashCallCount
- ${{ method: 'onGet', code: 200, res: MOCK_AUTOCOMPLETE_OPTIONS_RES }} | ${'success'} | ${[{ type: types.REQUEST_AUTOCOMPLETE }, { type: types.RECEIVE_AUTOCOMPLETE_SUCCESS, payload: MOCK_AUTOCOMPLETE_OPTIONS_RES }]} | ${0}
- ${{ method: 'onGet', code: 500, res: null }} | ${'error'} | ${[{ type: types.REQUEST_AUTOCOMPLETE }, { type: types.RECEIVE_AUTOCOMPLETE_ERROR }]} | ${1}
- `('fetchAutocompleteOptions', ({ axiosMock, type, expectedMutations, flashCallCount }) => {
+ axiosMock | type | expectedMutations
+ ${{ method: 'onGet', code: 200, res: MOCK_AUTOCOMPLETE_OPTIONS_RES }} | ${'success'} | ${[{ type: types.REQUEST_AUTOCOMPLETE }, { type: types.RECEIVE_AUTOCOMPLETE_SUCCESS, payload: MOCK_AUTOCOMPLETE_OPTIONS_RES }]}
+ ${{ method: 'onGet', code: 500, res: null }} | ${'error'} | ${[{ type: types.REQUEST_AUTOCOMPLETE }, { type: types.RECEIVE_AUTOCOMPLETE_ERROR }]}
+ `('fetchAutocompleteOptions', ({ axiosMock, type, expectedMutations }) => {
describe(`on ${type}`, () => {
beforeEach(() => {
mock[axiosMock.method]().replyOnce(axiosMock.code, axiosMock.res);
@@ -42,7 +36,7 @@ describe('Header Search Store Actions', () => {
action: actions.fetchAutocompleteOptions,
state,
expectedMutations,
- }).then(() => flashCallback(flashCallCount));
+ });
});
});
});
diff --git a/spec/frontend/header_search/store/getters_spec.js b/spec/frontend/header_search/store/getters_spec.js
index 35d1bf350d7..d3510de1439 100644
--- a/spec/frontend/header_search/store/getters_spec.js
+++ b/spec/frontend/header_search/store/getters_spec.js
@@ -37,20 +37,29 @@ describe('Header Search Store Getters', () => {
});
describe.each`
- group | project | scope | expectedPath
- ${null} | ${null} | ${null} | ${`${MOCK_SEARCH_PATH}?search=${MOCK_SEARCH}&nav_source=navbar`}
- ${MOCK_GROUP} | ${null} | ${null} | ${`${MOCK_SEARCH_PATH}?search=${MOCK_SEARCH}&nav_source=navbar&group_id=${MOCK_GROUP.id}`}
- ${null} | ${MOCK_PROJECT} | ${null} | ${`${MOCK_SEARCH_PATH}?search=${MOCK_SEARCH}&nav_source=navbar&project_id=${MOCK_PROJECT.id}`}
- ${MOCK_GROUP} | ${MOCK_PROJECT} | ${null} | ${`${MOCK_SEARCH_PATH}?search=${MOCK_SEARCH}&nav_source=navbar&project_id=${MOCK_PROJECT.id}&group_id=${MOCK_GROUP.id}`}
- ${MOCK_GROUP} | ${MOCK_PROJECT} | ${'issues'} | ${`${MOCK_SEARCH_PATH}?search=${MOCK_SEARCH}&nav_source=navbar&project_id=${MOCK_PROJECT.id}&group_id=${MOCK_GROUP.id}&scope=issues`}
- `('searchQuery', ({ group, project, scope, expectedPath }) => {
- describe(`when group is ${group?.name}, project is ${project?.name}, and scope is ${scope}`, () => {
+ group | project | scope | forSnippets | codeSearch | ref | expectedPath
+ ${null} | ${null} | ${null} | ${false} | ${false} | ${null} | ${`${MOCK_SEARCH_PATH}?search=${MOCK_SEARCH}&nav_source=navbar`}
+ ${null} | ${null} | ${null} | ${true} | ${false} | ${null} | ${`${MOCK_SEARCH_PATH}?search=${MOCK_SEARCH}&nav_source=navbar&snippets=true`}
+ ${null} | ${null} | ${null} | ${false} | ${true} | ${null} | ${`${MOCK_SEARCH_PATH}?search=${MOCK_SEARCH}&nav_source=navbar&search_code=true`}
+ ${null} | ${null} | ${null} | ${false} | ${false} | ${'test-branch'} | ${`${MOCK_SEARCH_PATH}?search=${MOCK_SEARCH}&nav_source=navbar&repository_ref=test-branch`}
+ ${MOCK_GROUP} | ${null} | ${null} | ${false} | ${false} | ${null} | ${`${MOCK_SEARCH_PATH}?search=${MOCK_SEARCH}&nav_source=navbar&group_id=${MOCK_GROUP.id}`}
+ ${null} | ${MOCK_PROJECT} | ${null} | ${false} | ${false} | ${null} | ${`${MOCK_SEARCH_PATH}?search=${MOCK_SEARCH}&nav_source=navbar&project_id=${MOCK_PROJECT.id}`}
+ ${MOCK_GROUP} | ${MOCK_PROJECT} | ${null} | ${false} | ${false} | ${null} | ${`${MOCK_SEARCH_PATH}?search=${MOCK_SEARCH}&nav_source=navbar&project_id=${MOCK_PROJECT.id}&group_id=${MOCK_GROUP.id}`}
+ ${MOCK_GROUP} | ${MOCK_PROJECT} | ${'issues'} | ${false} | ${false} | ${null} | ${`${MOCK_SEARCH_PATH}?search=${MOCK_SEARCH}&nav_source=navbar&project_id=${MOCK_PROJECT.id}&group_id=${MOCK_GROUP.id}&scope=issues`}
+ ${MOCK_GROUP} | ${MOCK_PROJECT} | ${'issues'} | ${true} | ${false} | ${null} | ${`${MOCK_SEARCH_PATH}?search=${MOCK_SEARCH}&nav_source=navbar&project_id=${MOCK_PROJECT.id}&group_id=${MOCK_GROUP.id}&scope=issues&snippets=true`}
+ ${MOCK_GROUP} | ${MOCK_PROJECT} | ${'issues'} | ${true} | ${true} | ${null} | ${`${MOCK_SEARCH_PATH}?search=${MOCK_SEARCH}&nav_source=navbar&project_id=${MOCK_PROJECT.id}&group_id=${MOCK_GROUP.id}&scope=issues&snippets=true&search_code=true`}
+ ${MOCK_GROUP} | ${MOCK_PROJECT} | ${'issues'} | ${true} | ${true} | ${'test-branch'} | ${`${MOCK_SEARCH_PATH}?search=${MOCK_SEARCH}&nav_source=navbar&project_id=${MOCK_PROJECT.id}&group_id=${MOCK_GROUP.id}&scope=issues&snippets=true&search_code=true&repository_ref=test-branch`}
+ `('searchQuery', ({ group, project, scope, forSnippets, codeSearch, ref, expectedPath }) => {
+ describe(`when group is ${group?.name}, project is ${project?.name}, scope is ${scope}, for_snippets is ${forSnippets}, code_search is ${codeSearch}, and ref is ${ref}`, () => {
beforeEach(() => {
createState({
searchContext: {
group,
project,
scope,
+ for_snippets: forSnippets,
+ code_search: codeSearch,
+ ref,
},
});
state.search = MOCK_SEARCH;
@@ -135,20 +144,29 @@ describe('Header Search Store Getters', () => {
});
describe.each`
- group | project | scope | expectedPath
- ${null} | ${null} | ${null} | ${`${MOCK_SEARCH_PATH}?search=${MOCK_SEARCH}&nav_source=navbar`}
- ${MOCK_GROUP} | ${null} | ${null} | ${`${MOCK_SEARCH_PATH}?search=${MOCK_SEARCH}&nav_source=navbar&group_id=${MOCK_GROUP.id}`}
- ${null} | ${MOCK_PROJECT} | ${null} | ${`${MOCK_SEARCH_PATH}?search=${MOCK_SEARCH}&nav_source=navbar&project_id=${MOCK_PROJECT.id}`}
- ${MOCK_GROUP} | ${MOCK_PROJECT} | ${null} | ${`${MOCK_SEARCH_PATH}?search=${MOCK_SEARCH}&nav_source=navbar&project_id=${MOCK_PROJECT.id}&group_id=${MOCK_GROUP.id}`}
- ${MOCK_GROUP} | ${MOCK_PROJECT} | ${'issues'} | ${`${MOCK_SEARCH_PATH}?search=${MOCK_SEARCH}&nav_source=navbar&project_id=${MOCK_PROJECT.id}&group_id=${MOCK_GROUP.id}&scope=issues`}
- `('projectUrl', ({ group, project, scope, expectedPath }) => {
- describe(`when group is ${group?.name}, project is ${project?.name}, and scope is ${scope}`, () => {
+ group | project | scope | forSnippets | codeSearch | ref | expectedPath
+ ${null} | ${null} | ${null} | ${false} | ${false} | ${null} | ${`${MOCK_SEARCH_PATH}?search=${MOCK_SEARCH}&nav_source=navbar`}
+ ${null} | ${null} | ${null} | ${true} | ${false} | ${null} | ${`${MOCK_SEARCH_PATH}?search=${MOCK_SEARCH}&nav_source=navbar&snippets=true`}
+ ${null} | ${null} | ${null} | ${false} | ${true} | ${null} | ${`${MOCK_SEARCH_PATH}?search=${MOCK_SEARCH}&nav_source=navbar&search_code=true`}
+ ${null} | ${null} | ${null} | ${false} | ${false} | ${'test-branch'} | ${`${MOCK_SEARCH_PATH}?search=${MOCK_SEARCH}&nav_source=navbar&repository_ref=test-branch`}
+ ${MOCK_GROUP} | ${null} | ${null} | ${false} | ${false} | ${null} | ${`${MOCK_SEARCH_PATH}?search=${MOCK_SEARCH}&nav_source=navbar&group_id=${MOCK_GROUP.id}`}
+ ${null} | ${MOCK_PROJECT} | ${null} | ${false} | ${false} | ${null} | ${`${MOCK_SEARCH_PATH}?search=${MOCK_SEARCH}&nav_source=navbar&project_id=${MOCK_PROJECT.id}`}
+ ${MOCK_GROUP} | ${MOCK_PROJECT} | ${null} | ${false} | ${false} | ${null} | ${`${MOCK_SEARCH_PATH}?search=${MOCK_SEARCH}&nav_source=navbar&project_id=${MOCK_PROJECT.id}&group_id=${MOCK_GROUP.id}`}
+ ${MOCK_GROUP} | ${MOCK_PROJECT} | ${'issues'} | ${false} | ${false} | ${null} | ${`${MOCK_SEARCH_PATH}?search=${MOCK_SEARCH}&nav_source=navbar&project_id=${MOCK_PROJECT.id}&group_id=${MOCK_GROUP.id}&scope=issues`}
+ ${MOCK_GROUP} | ${MOCK_PROJECT} | ${'issues'} | ${true} | ${false} | ${null} | ${`${MOCK_SEARCH_PATH}?search=${MOCK_SEARCH}&nav_source=navbar&project_id=${MOCK_PROJECT.id}&group_id=${MOCK_GROUP.id}&scope=issues&snippets=true`}
+ ${MOCK_GROUP} | ${MOCK_PROJECT} | ${'issues'} | ${true} | ${true} | ${null} | ${`${MOCK_SEARCH_PATH}?search=${MOCK_SEARCH}&nav_source=navbar&project_id=${MOCK_PROJECT.id}&group_id=${MOCK_GROUP.id}&scope=issues&snippets=true&search_code=true`}
+ ${MOCK_GROUP} | ${MOCK_PROJECT} | ${'issues'} | ${true} | ${true} | ${'test-branch'} | ${`${MOCK_SEARCH_PATH}?search=${MOCK_SEARCH}&nav_source=navbar&project_id=${MOCK_PROJECT.id}&group_id=${MOCK_GROUP.id}&scope=issues&snippets=true&search_code=true&repository_ref=test-branch`}
+ `('projectUrl', ({ group, project, scope, forSnippets, codeSearch, ref, expectedPath }) => {
+ describe(`when group is ${group?.name}, project is ${project?.name}, scope is ${scope}, for_snippets is ${forSnippets}, code_search is ${codeSearch}, and ref is ${ref}`, () => {
beforeEach(() => {
createState({
searchContext: {
group,
project,
scope,
+ for_snippets: forSnippets,
+ code_search: codeSearch,
+ ref,
},
});
state.search = MOCK_SEARCH;
@@ -161,20 +179,29 @@ describe('Header Search Store Getters', () => {
});
describe.each`
- group | project | scope | expectedPath
- ${null} | ${null} | ${null} | ${`${MOCK_SEARCH_PATH}?search=${MOCK_SEARCH}&nav_source=navbar`}
- ${MOCK_GROUP} | ${null} | ${null} | ${`${MOCK_SEARCH_PATH}?search=${MOCK_SEARCH}&nav_source=navbar&group_id=${MOCK_GROUP.id}`}
- ${null} | ${MOCK_PROJECT} | ${null} | ${`${MOCK_SEARCH_PATH}?search=${MOCK_SEARCH}&nav_source=navbar`}
- ${MOCK_GROUP} | ${MOCK_PROJECT} | ${null} | ${`${MOCK_SEARCH_PATH}?search=${MOCK_SEARCH}&nav_source=navbar&group_id=${MOCK_GROUP.id}`}
- ${MOCK_GROUP} | ${MOCK_PROJECT} | ${'issues'} | ${`${MOCK_SEARCH_PATH}?search=${MOCK_SEARCH}&nav_source=navbar&group_id=${MOCK_GROUP.id}&scope=issues`}
- `('groupUrl', ({ group, project, scope, expectedPath }) => {
- describe(`when group is ${group?.name}, project is ${project?.name}, and scope is ${scope}`, () => {
+ group | project | scope | forSnippets | codeSearch | ref | expectedPath
+ ${null} | ${null} | ${null} | ${false} | ${false} | ${null} | ${`${MOCK_SEARCH_PATH}?search=${MOCK_SEARCH}&nav_source=navbar`}
+ ${null} | ${null} | ${null} | ${true} | ${false} | ${null} | ${`${MOCK_SEARCH_PATH}?search=${MOCK_SEARCH}&nav_source=navbar&snippets=true`}
+ ${null} | ${null} | ${null} | ${false} | ${true} | ${null} | ${`${MOCK_SEARCH_PATH}?search=${MOCK_SEARCH}&nav_source=navbar&search_code=true`}
+ ${null} | ${null} | ${null} | ${false} | ${false} | ${'test-branch'} | ${`${MOCK_SEARCH_PATH}?search=${MOCK_SEARCH}&nav_source=navbar&repository_ref=test-branch`}
+ ${MOCK_GROUP} | ${null} | ${null} | ${false} | ${false} | ${null} | ${`${MOCK_SEARCH_PATH}?search=${MOCK_SEARCH}&nav_source=navbar&group_id=${MOCK_GROUP.id}`}
+ ${null} | ${MOCK_PROJECT} | ${null} | ${false} | ${false} | ${null} | ${`${MOCK_SEARCH_PATH}?search=${MOCK_SEARCH}&nav_source=navbar`}
+ ${MOCK_GROUP} | ${MOCK_PROJECT} | ${null} | ${false} | ${false} | ${null} | ${`${MOCK_SEARCH_PATH}?search=${MOCK_SEARCH}&nav_source=navbar&group_id=${MOCK_GROUP.id}`}
+ ${MOCK_GROUP} | ${MOCK_PROJECT} | ${'issues'} | ${false} | ${false} | ${null} | ${`${MOCK_SEARCH_PATH}?search=${MOCK_SEARCH}&nav_source=navbar&group_id=${MOCK_GROUP.id}&scope=issues`}
+ ${MOCK_GROUP} | ${MOCK_PROJECT} | ${'issues'} | ${true} | ${false} | ${null} | ${`${MOCK_SEARCH_PATH}?search=${MOCK_SEARCH}&nav_source=navbar&group_id=${MOCK_GROUP.id}&scope=issues&snippets=true`}
+ ${MOCK_GROUP} | ${MOCK_PROJECT} | ${'issues'} | ${true} | ${true} | ${null} | ${`${MOCK_SEARCH_PATH}?search=${MOCK_SEARCH}&nav_source=navbar&group_id=${MOCK_GROUP.id}&scope=issues&snippets=true&search_code=true`}
+ ${MOCK_GROUP} | ${MOCK_PROJECT} | ${'issues'} | ${true} | ${true} | ${'test-branch'} | ${`${MOCK_SEARCH_PATH}?search=${MOCK_SEARCH}&nav_source=navbar&group_id=${MOCK_GROUP.id}&scope=issues&snippets=true&search_code=true&repository_ref=test-branch`}
+ `('groupUrl', ({ group, project, scope, forSnippets, codeSearch, ref, expectedPath }) => {
+ describe(`when group is ${group?.name}, project is ${project?.name}, scope is ${scope}, for_snippets is ${forSnippets}, code_search is ${codeSearch}, and ref is ${ref}`, () => {
beforeEach(() => {
createState({
searchContext: {
group,
project,
scope,
+ for_snippets: forSnippets,
+ code_search: codeSearch,
+ ref,
},
});
state.search = MOCK_SEARCH;
@@ -187,20 +214,29 @@ describe('Header Search Store Getters', () => {
});
describe.each`
- group | project | scope | expectedPath
- ${null} | ${null} | ${null} | ${`${MOCK_SEARCH_PATH}?search=${MOCK_SEARCH}&nav_source=navbar`}
- ${MOCK_GROUP} | ${null} | ${null} | ${`${MOCK_SEARCH_PATH}?search=${MOCK_SEARCH}&nav_source=navbar`}
- ${null} | ${MOCK_PROJECT} | ${null} | ${`${MOCK_SEARCH_PATH}?search=${MOCK_SEARCH}&nav_source=navbar`}
- ${MOCK_GROUP} | ${MOCK_PROJECT} | ${null} | ${`${MOCK_SEARCH_PATH}?search=${MOCK_SEARCH}&nav_source=navbar`}
- ${MOCK_GROUP} | ${MOCK_PROJECT} | ${'issues'} | ${`${MOCK_SEARCH_PATH}?search=${MOCK_SEARCH}&nav_source=navbar&scope=issues`}
- `('allUrl', ({ group, project, scope, expectedPath }) => {
- describe(`when group is ${group?.name}, project is ${project?.name}, and scope is ${scope}`, () => {
+ group | project | scope | forSnippets | codeSearch | ref | expectedPath
+ ${null} | ${null} | ${null} | ${false} | ${false} | ${null} | ${`${MOCK_SEARCH_PATH}?search=${MOCK_SEARCH}&nav_source=navbar`}
+ ${null} | ${null} | ${null} | ${true} | ${false} | ${null} | ${`${MOCK_SEARCH_PATH}?search=${MOCK_SEARCH}&nav_source=navbar&snippets=true`}
+ ${null} | ${null} | ${null} | ${false} | ${true} | ${null} | ${`${MOCK_SEARCH_PATH}?search=${MOCK_SEARCH}&nav_source=navbar&search_code=true`}
+ ${null} | ${null} | ${null} | ${false} | ${false} | ${'test-branch'} | ${`${MOCK_SEARCH_PATH}?search=${MOCK_SEARCH}&nav_source=navbar&repository_ref=test-branch`}
+ ${MOCK_GROUP} | ${null} | ${null} | ${false} | ${false} | ${null} | ${`${MOCK_SEARCH_PATH}?search=${MOCK_SEARCH}&nav_source=navbar`}
+ ${null} | ${MOCK_PROJECT} | ${null} | ${false} | ${false} | ${null} | ${`${MOCK_SEARCH_PATH}?search=${MOCK_SEARCH}&nav_source=navbar`}
+ ${MOCK_GROUP} | ${MOCK_PROJECT} | ${null} | ${false} | ${false} | ${null} | ${`${MOCK_SEARCH_PATH}?search=${MOCK_SEARCH}&nav_source=navbar`}
+ ${MOCK_GROUP} | ${MOCK_PROJECT} | ${'issues'} | ${false} | ${false} | ${null} | ${`${MOCK_SEARCH_PATH}?search=${MOCK_SEARCH}&nav_source=navbar&scope=issues`}
+ ${MOCK_GROUP} | ${MOCK_PROJECT} | ${'issues'} | ${true} | ${false} | ${null} | ${`${MOCK_SEARCH_PATH}?search=${MOCK_SEARCH}&nav_source=navbar&scope=issues&snippets=true`}
+ ${MOCK_GROUP} | ${MOCK_PROJECT} | ${'issues'} | ${true} | ${true} | ${null} | ${`${MOCK_SEARCH_PATH}?search=${MOCK_SEARCH}&nav_source=navbar&scope=issues&snippets=true&search_code=true`}
+ ${MOCK_GROUP} | ${MOCK_PROJECT} | ${'issues'} | ${true} | ${true} | ${'test-branch'} | ${`${MOCK_SEARCH_PATH}?search=${MOCK_SEARCH}&nav_source=navbar&scope=issues&snippets=true&search_code=true&repository_ref=test-branch`}
+ `('allUrl', ({ group, project, scope, forSnippets, codeSearch, ref, expectedPath }) => {
+ describe(`when group is ${group?.name}, project is ${project?.name}, scope is ${scope}, for_snippets is ${forSnippets}, code_search is ${codeSearch}, and ref is ${ref}`, () => {
beforeEach(() => {
createState({
searchContext: {
group,
project,
scope,
+ for_snippets: forSnippets,
+ code_search: codeSearch,
+ ref,
},
});
state.search = MOCK_SEARCH;
diff --git a/spec/frontend/header_search/store/mutations_spec.js b/spec/frontend/header_search/store/mutations_spec.js
index 7bcf8e49118..e3c15ded948 100644
--- a/spec/frontend/header_search/store/mutations_spec.js
+++ b/spec/frontend/header_search/store/mutations_spec.js
@@ -20,6 +20,7 @@ describe('Header Search Store Mutations', () => {
expect(state.loading).toBe(true);
expect(state.autocompleteOptions).toStrictEqual([]);
+ expect(state.autocompleteError).toBe(false);
});
});
@@ -29,6 +30,7 @@ describe('Header Search Store Mutations', () => {
expect(state.loading).toBe(false);
expect(state.autocompleteOptions).toStrictEqual(MOCK_AUTOCOMPLETE_OPTIONS);
+ expect(state.autocompleteError).toBe(false);
});
});
@@ -38,6 +40,7 @@ describe('Header Search Store Mutations', () => {
expect(state.loading).toBe(false);
expect(state.autocompleteOptions).toStrictEqual([]);
+ expect(state.autocompleteError).toBe(true);
});
});
@@ -46,6 +49,7 @@ describe('Header Search Store Mutations', () => {
mutations[types.CLEAR_AUTOCOMPLETE](state);
expect(state.autocompleteOptions).toStrictEqual([]);
+ expect(state.autocompleteError).toBe(false);
});
});
diff --git a/spec/frontend/ide/components/file_templates/bar_spec.js b/spec/frontend/ide/components/file_templates/bar_spec.js
index e8ebfa78fe9..aaf9c17ccbf 100644
--- a/spec/frontend/ide/components/file_templates/bar_spec.js
+++ b/spec/frontend/ide/components/file_templates/bar_spec.js
@@ -36,7 +36,7 @@ describe('IDE file templates bar component', () => {
it('calls setSelectedTemplateType when clicking item', () => {
jest.spyOn(vm, 'setSelectedTemplateType').mockImplementation();
- vm.$el.querySelector('.dropdown-content button').click();
+ vm.$el.querySelector('.dropdown-menu button').click();
expect(vm.setSelectedTemplateType).toHaveBeenCalledWith({
name: '.gitlab-ci.yml',
@@ -64,10 +64,10 @@ describe('IDE file templates bar component', () => {
expect(vm.$el.querySelectorAll('.dropdown')[1].textContent).toContain('Choose a template');
});
- it('calls fetchTemplate on click', () => {
+ it('calls fetchTemplate on dropdown open', () => {
jest.spyOn(vm, 'fetchTemplate').mockImplementation();
- vm.$el.querySelectorAll('.dropdown-content')[1].querySelector('button').click();
+ vm.$el.querySelectorAll('.dropdown-menu')[1].querySelector('button').click();
expect(vm.fetchTemplate).toHaveBeenCalledWith({
name: 'test',
@@ -85,7 +85,7 @@ describe('IDE file templates bar component', () => {
it('calls undoFileTemplate when clicking undo button', () => {
jest.spyOn(vm, 'undoFileTemplate').mockImplementation();
- vm.$el.querySelector('.btn-default').click();
+ vm.$el.querySelector('.btn-default-secondary').click();
expect(vm.undoFileTemplate).toHaveBeenCalled();
});
diff --git a/spec/frontend/ide/components/new_dropdown/modal_spec.js b/spec/frontend/ide/components/new_dropdown/modal_spec.js
index 8134248bbf4..e8635444801 100644
--- a/spec/frontend/ide/components/new_dropdown/modal_spec.js
+++ b/spec/frontend/ide/components/new_dropdown/modal_spec.js
@@ -38,7 +38,7 @@ describe('new file modal component', () => {
});
it(`sets button label as ${entryType}`, () => {
- expect(document.querySelector('.btn-success').textContent.trim()).toBe(btnTitle);
+ expect(document.querySelector('.btn-confirm').textContent.trim()).toBe(btnTitle);
});
it(`sets form label as ${entryType}`, () => {
@@ -77,7 +77,7 @@ describe('new file modal component', () => {
await nextTick();
expect(document.querySelector('.modal-title').textContent.trim()).toBe(modalTitle);
- expect(document.querySelector('.btn-success').textContent.trim()).toBe(btnTitle);
+ expect(document.querySelector('.btn-confirm').textContent.trim()).toBe(btnTitle);
},
);
diff --git a/spec/frontend/ide/components/repo_editor_spec.js b/spec/frontend/ide/components/repo_editor_spec.js
index 96c9baeb328..9a30fd5f5c3 100644
--- a/spec/frontend/ide/components/repo_editor_spec.js
+++ b/spec/frontend/ide/components/repo_editor_spec.js
@@ -169,12 +169,11 @@ describe('RepoEditor', () => {
expect(findEditor().isVisible()).toBe(true);
});
- it('renders only an edit tab', async () => {
+ it('renders no tabs', async () => {
await createComponent();
const tabs = findTabs();
- expect(tabs).toHaveLength(1);
- expect(tabs.at(0).text()).toBe('Edit');
+ expect(tabs).toHaveLength(0);
});
});
@@ -196,25 +195,48 @@ describe('RepoEditor', () => {
mock.restore();
});
- it('renders an Edit and a Preview Tab', async () => {
- await createComponent({ activeFile });
- const tabs = findTabs();
+ describe('when files is markdown', () => {
+ let layoutSpy;
- expect(tabs).toHaveLength(2);
- expect(tabs.at(0).text()).toBe('Edit');
- expect(tabs.at(1).text()).toBe('Preview Markdown');
- });
+ beforeEach(async () => {
+ await createComponent({ activeFile });
+ layoutSpy = jest.spyOn(wrapper.vm.editor, 'layout');
+ });
- it('renders markdown for tempFile', async () => {
- // by default files created in the spec are temp: no need for explicitly sending the param
- await createComponent({ activeFile });
+ it('renders an Edit and a Preview Tab', () => {
+ const tabs = findTabs();
- findPreviewTab().trigger('click');
- await waitForPromises();
- expect(wrapper.find(ContentViewer).html()).toContain(defaultFileProps.content);
+ expect(tabs).toHaveLength(2);
+ expect(tabs.at(0).text()).toBe('Edit');
+ expect(tabs.at(1).text()).toBe('Preview Markdown');
+ });
+
+ it('renders markdown for tempFile', async () => {
+ findPreviewTab().trigger('click');
+ await waitForPromises();
+ expect(wrapper.find(ContentViewer).html()).toContain(defaultFileProps.content);
+ });
+
+ it('should not trigger layout', async () => {
+ expect(layoutSpy).not.toHaveBeenCalled();
+ });
+
+ describe('when file changes to non-markdown file', () => {
+ beforeEach(async () => {
+ wrapper.setProps({ file: dummyFile.empty });
+ });
+
+ it('should hide tabs', () => {
+ expect(findTabs()).toHaveLength(0);
+ });
+
+ it('should trigger refresh dimensions', async () => {
+ expect(layoutSpy).toHaveBeenCalledTimes(1);
+ });
+ });
});
- it('shows no tabs when not in Edit mode', async () => {
+ it('when not in edit mode, shows no tabs', async () => {
await createComponent({
state: {
currentActivityView: leftSidebarViews.review.name,
@@ -405,7 +427,7 @@ describe('RepoEditor', () => {
it.each`
mode | isVisible
- ${'edit'} | ${true}
+ ${'edit'} | ${false}
${'review'} | ${false}
${'commit'} | ${false}
`('tabs in $mode are $isVisible', async ({ mode, isVisible } = {}) => {
diff --git a/spec/frontend/import_entities/import_projects/components/import_projects_table_spec.js b/spec/frontend/import_entities/import_projects/components/import_projects_table_spec.js
index 0b12df83cd1..16adf88700f 100644
--- a/spec/frontend/import_entities/import_projects/components/import_projects_table_spec.js
+++ b/spec/frontend/import_entities/import_projects/components/import_projects_table_spec.js
@@ -16,7 +16,7 @@ describe('ImportProjectsTable', () => {
const findFilterField = () =>
wrapper
.findAllComponents(GlFormInput)
- .wrappers.find((w) => w.attributes('placeholder') === 'Filter your repositories by name');
+ .wrappers.find((w) => w.attributes('placeholder') === 'Filter by name');
const providerTitle = 'THE PROVIDER';
const providerRepo = {
diff --git a/spec/frontend/incidents/components/incidents_list_spec.js b/spec/frontend/incidents/components/incidents_list_spec.js
index 1be6007d844..9ed0294e876 100644
--- a/spec/frontend/incidents/components/incidents_list_spec.js
+++ b/spec/frontend/incidents/components/incidents_list_spec.js
@@ -1,6 +1,7 @@
import { GlAlert, GlLoadingIcon, GlTable, GlAvatar, GlEmptyState } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
import { nextTick } from 'vue';
+import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import IncidentsList from '~/incidents/components/incidents_list.vue';
import {
I18N,
@@ -19,7 +20,7 @@ import mockIncidents from '../mocks/incidents.json';
jest.mock('~/lib/utils/url_utility', () => ({
visitUrl: jest.fn().mockName('visitUrlMock'),
- joinPaths: jest.fn(),
+ joinPaths: jest.requireActual('~/lib/utils/url_utility').joinPaths,
mergeUrlParams: jest.fn(),
setUrlParams: jest.fn(),
updateHistory: jest.fn(),
@@ -48,47 +49,52 @@ describe('Incidents List', () => {
const findClosedIcon = () => wrapper.findAll("[data-testid='incident-closed']");
const findEmptyState = () => wrapper.find(GlEmptyState);
const findSeverity = () => wrapper.findAll(SeverityToken);
+ const findEscalationStatus = () => wrapper.findAll('[data-testid="incident-escalation-status"]');
+ const findIncidentLink = () => wrapper.findByTestId('incident-link');
function mountComponent({ data = {}, loading = false, provide = {} } = {}) {
- wrapper = mount(IncidentsList, {
- data() {
- return {
- incidents: [],
- incidentsCount: {},
- ...data,
- };
- },
- mocks: {
- $apollo: {
- queries: {
- incidents: {
- loading,
+ wrapper = extendedWrapper(
+ mount(IncidentsList, {
+ data() {
+ return {
+ incidents: [],
+ incidentsCount: {},
+ ...data,
+ };
+ },
+ mocks: {
+ $apollo: {
+ queries: {
+ incidents: {
+ loading,
+ },
},
},
},
- },
- provide: {
- projectPath: '/project/path',
- newIssuePath,
- incidentTemplateName,
- incidentType,
- issuePath: '/project/issues',
- publishedAvailable: true,
- emptyListSvgPath,
- textQuery: '',
- authorUsernameQuery: '',
- assigneeUsernameQuery: '',
- slaFeatureAvailable: true,
- canCreateIncident: true,
- ...provide,
- },
- stubs: {
- GlButton: true,
- GlAvatar: true,
- GlEmptyState: true,
- ServiceLevelAgreementCell: true,
- },
- });
+ provide: {
+ projectPath: '/project/path',
+ newIssuePath,
+ incidentTemplateName,
+ incidentType,
+ issuePath: '/project/issues',
+ publishedAvailable: true,
+ emptyListSvgPath,
+ textQuery: '',
+ authorUsernameQuery: '',
+ assigneeUsernameQuery: '',
+ slaFeatureAvailable: true,
+ canCreateIncident: true,
+ incidentEscalationsAvailable: true,
+ ...provide,
+ },
+ stubs: {
+ GlButton: true,
+ GlAvatar: true,
+ GlEmptyState: true,
+ ServiceLevelAgreementCell: true,
+ },
+ }),
+ );
}
afterEach(() => {
@@ -158,6 +164,14 @@ describe('Incidents List', () => {
expect(findTimeAgo().length).toBe(mockIncidents.length);
});
+ it('renders a link to the incident as the incident title', () => {
+ const { title, iid } = mockIncidents[0];
+ const link = findIncidentLink();
+
+ expect(link.text()).toBe(title);
+ expect(link.attributes('href')).toContain(`issues/incident/${iid}`);
+ });
+
describe('Assignees', () => {
it('shows Unassigned when there are no assignees', () => {
expect(findAssignees().at(0).text()).toBe(I18N.unassigned);
@@ -184,6 +198,34 @@ describe('Incidents List', () => {
expect(findSeverity().length).toBe(mockIncidents.length);
});
+ describe('Escalation status', () => {
+ it('renders escalation status per row', () => {
+ expect(findEscalationStatus().length).toBe(mockIncidents.length);
+
+ const actualStatuses = findEscalationStatus().wrappers.map((status) => status.text());
+ expect(actualStatuses).toEqual([
+ 'Triggered',
+ 'Acknowledged',
+ 'Resolved',
+ I18N.noEscalationStatus,
+ ]);
+ });
+
+ describe('when feature is disabled', () => {
+ beforeEach(() => {
+ mountComponent({
+ data: { incidents: { list: mockIncidents }, incidentsCount },
+ provide: { incidentEscalationsAvailable: false },
+ loading: false,
+ });
+ });
+
+ it('is absent if feature flag is disabled', () => {
+ expect(findEscalationStatus().length).toBe(0);
+ });
+ });
+ });
+
it('contains a link to the incident details page', async () => {
findTableRows().at(0).trigger('click');
expect(visitUrl).toHaveBeenCalledWith(
diff --git a/spec/frontend/incidents/mocks/incidents.json b/spec/frontend/incidents/mocks/incidents.json
index 357b94e5b6c..479b0809de3 100644
--- a/spec/frontend/incidents/mocks/incidents.json
+++ b/spec/frontend/incidents/mocks/incidents.json
@@ -7,6 +7,7 @@
"assignees": {},
"state": "opened",
"severity": "CRITICAL",
+ "escalationStatus": "TRIGGERED",
"slaDueAt": "2020-06-04T12:46:08Z"
},
{
@@ -26,6 +27,7 @@
},
"state": "opened",
"severity": "HIGH",
+ "escalationStatus": "ACKNOWLEDGED",
"slaDueAt": null
},
{
@@ -35,7 +37,8 @@
"createdAt": "2020-05-19T08:53:55Z",
"assignees": {},
"state": "closed",
- "severity": "LOW"
+ "severity": "LOW",
+ "escalationStatus": "RESOLVED"
},
{
"id": 4,
@@ -44,6 +47,7 @@
"createdAt": "2020-05-18T17:13:35Z",
"assignees": {},
"state": "closed",
- "severity": "MEDIUM"
+ "severity": "MEDIUM",
+ "escalationStatus": null
}
]
diff --git a/spec/frontend/integrations/edit/components/active_checkbox_spec.js b/spec/frontend/integrations/edit/components/active_checkbox_spec.js
index c335b593f7d..633389578a0 100644
--- a/spec/frontend/integrations/edit/components/active_checkbox_spec.js
+++ b/spec/frontend/integrations/edit/components/active_checkbox_spec.js
@@ -35,6 +35,15 @@ describe('ActiveCheckbox', () => {
});
});
+ describe('when activateDisabled is true', () => {
+ it('renders GlFormCheckbox as disabled', () => {
+ createComponent({ activateDisabled: true });
+
+ expect(findGlFormCheckbox().exists()).toBe(true);
+ expect(findInputInCheckbox().attributes('disabled')).toBe('disabled');
+ });
+ });
+
describe('initialActivated is `false`', () => {
beforeEach(() => {
createComponent({
diff --git a/spec/frontend/integrations/edit/components/integration_form_spec.js b/spec/frontend/integrations/edit/components/integration_form_spec.js
index 7e01b79383a..c4569070d09 100644
--- a/spec/frontend/integrations/edit/components/integration_form_spec.js
+++ b/spec/frontend/integrations/edit/components/integration_form_spec.js
@@ -14,6 +14,8 @@ import JiraTriggerFields from '~/integrations/edit/components/jira_trigger_field
import OverrideDropdown from '~/integrations/edit/components/override_dropdown.vue';
import ResetConfirmationModal from '~/integrations/edit/components/reset_confirmation_modal.vue';
import TriggerFields from '~/integrations/edit/components/trigger_fields.vue';
+import IntegrationSectionConnection from '~/integrations/edit/components/sections/connection.vue';
+
import {
integrationLevels,
I18N_SUCCESSFUL_CONNECTION_MESSAGE,
@@ -22,7 +24,7 @@ import {
import { createStore } from '~/integrations/edit/store';
import httpStatus from '~/lib/utils/http_status';
import { refreshCurrentPage } from '~/lib/utils/url_utility';
-import { mockIntegrationProps, mockField } from '../mock_data';
+import { mockIntegrationProps, mockField, mockSectionConnection } from '../mock_data';
jest.mock('@sentry/browser');
jest.mock('~/lib/utils/url_utility');
@@ -37,7 +39,7 @@ describe('IntegrationForm', () => {
const createComponent = ({
customStateProps = {},
initialState = {},
- props = {},
+ provide = {},
mountFn = shallowMountExtended,
} = {}) => {
const store = createStore({
@@ -47,7 +49,7 @@ describe('IntegrationForm', () => {
dispatch = jest.spyOn(store, 'dispatch').mockImplementation();
wrapper = mountFn(IntegrationForm, {
- propsData: { ...props },
+ provide,
store,
stubs: {
OverrideDropdown,
@@ -78,6 +80,11 @@ describe('IntegrationForm', () => {
const findGlForm = () => wrapper.findComponent(GlForm);
const findRedirectToField = () => wrapper.findByTestId('redirect-to-field');
const findDynamicField = () => wrapper.findComponent(DynamicField);
+ const findAllDynamicFields = () => wrapper.findAllComponents(DynamicField);
+ const findAllSections = () => wrapper.findAllByTestId('integration-section');
+ const findConnectionSection = () => findAllSections().at(0);
+ const findConnectionSectionComponent = () =>
+ findConnectionSection().findComponent(IntegrationSectionConnection);
beforeEach(() => {
mockAxios = new MockAdapter(axios);
@@ -253,23 +260,32 @@ describe('IntegrationForm', () => {
});
describe('fields is present', () => {
- it('renders DynamicField for each field', () => {
- const fields = [
- { name: 'username', type: 'text' },
- { name: 'API token', type: 'password' },
+ it('renders DynamicField for each field without a section', () => {
+ const sectionFields = [
+ { name: 'username', type: 'text', section: mockSectionConnection.type },
+ { name: 'API token', type: 'password', section: mockSectionConnection.type },
+ ];
+
+ const nonSectionFields = [
+ { name: 'branch', type: 'text' },
+ { name: 'labels', type: 'select' },
];
createComponent({
+ provide: {
+ glFeatures: { integrationFormSections: true },
+ },
customStateProps: {
- fields,
+ sections: [mockSectionConnection],
+ fields: [...sectionFields, ...nonSectionFields],
},
});
- const dynamicFields = wrapper.findAll(DynamicField);
+ const dynamicFields = findAllDynamicFields();
expect(dynamicFields).toHaveLength(2);
dynamicFields.wrappers.forEach((field, index) => {
- expect(field.props()).toMatchObject(fields[index]);
+ expect(field.props()).toMatchObject(nonSectionFields[index]);
});
});
});
@@ -300,7 +316,7 @@ describe('IntegrationForm', () => {
});
});
- describe('with `helpHtml` prop', () => {
+ describe('with `helpHtml` provided', () => {
const mockTestId = 'jest-help-html-test';
setHTMLFixture(`
@@ -316,7 +332,7 @@ describe('IntegrationForm', () => {
const mockHelpHtml = document.querySelector(`[data-testid="${mockTestId}"]`);
createComponent({
- props: {
+ provide: {
helpHtml: mockHelpHtml.outerHTML,
},
});
@@ -344,6 +360,106 @@ describe('IntegrationForm', () => {
});
});
+ describe('when integration has sections', () => {
+ beforeEach(() => {
+ createComponent({
+ provide: {
+ glFeatures: { integrationFormSections: true },
+ },
+ customStateProps: {
+ sections: [mockSectionConnection],
+ },
+ });
+ });
+
+ it('renders the expected number of sections', () => {
+ expect(findAllSections().length).toBe(1);
+ });
+
+ it('renders title, description and the correct dynamic component', () => {
+ const connectionSection = findConnectionSection();
+
+ expect(connectionSection.find('h4').text()).toBe(mockSectionConnection.title);
+ expect(connectionSection.find('p').text()).toBe(mockSectionConnection.description);
+ expect(findConnectionSectionComponent().exists()).toBe(true);
+ });
+
+ it('passes only fields with section type', () => {
+ const sectionFields = [
+ { name: 'username', type: 'text', section: mockSectionConnection.type },
+ { name: 'API token', type: 'password', section: mockSectionConnection.type },
+ ];
+
+ const nonSectionFields = [
+ { name: 'branch', type: 'text' },
+ { name: 'labels', type: 'select' },
+ ];
+
+ createComponent({
+ provide: {
+ glFeatures: { integrationFormSections: true },
+ },
+ customStateProps: {
+ sections: [mockSectionConnection],
+ fields: [...sectionFields, ...nonSectionFields],
+ },
+ });
+
+ expect(findConnectionSectionComponent().props('fields')).toEqual(sectionFields);
+ });
+
+ describe.each`
+ formActive | novalidate
+ ${true} | ${undefined}
+ ${false} | ${'true'}
+ `(
+ 'when `toggle-integration-active` is emitted with $formActive',
+ ({ formActive, novalidate }) => {
+ beforeEach(() => {
+ createComponent({
+ provide: {
+ glFeatures: { integrationFormSections: true },
+ },
+ customStateProps: {
+ sections: [mockSectionConnection],
+ showActive: true,
+ initialActivated: false,
+ },
+ });
+
+ findConnectionSectionComponent().vm.$emit('toggle-integration-active', formActive);
+ });
+
+ it(`sets noValidate to ${novalidate}`, () => {
+ expect(findGlForm().attributes('novalidate')).toBe(novalidate);
+ });
+ },
+ );
+
+ describe('when IntegrationSectionConnection emits `request-jira-issue-types` event', () => {
+ beforeEach(() => {
+ jest.spyOn(document, 'querySelector').mockReturnValue(document.createElement('form'));
+
+ createComponent({
+ provide: {
+ glFeatures: { integrationFormSections: true },
+ },
+ customStateProps: {
+ sections: [mockSectionConnection],
+ testPath: '/test',
+ },
+ mountFn: mountExtended,
+ });
+
+ findConnectionSectionComponent().vm.$emit('request-jira-issue-types');
+ });
+
+ it('dispatches `requestJiraIssueTypes` action', () => {
+ expect(dispatch).toHaveBeenCalledWith('requestJiraIssueTypes', expect.any(FormData));
+ });
+ });
+ });
+
describe('ActiveCheckbox', () => {
describe.each`
showActive
@@ -368,7 +484,7 @@ describe('IntegrationForm', () => {
`(
'when `toggle-integration-active` is emitted with $formActive',
({ formActive, novalidate }) => {
- beforeEach(async () => {
+ beforeEach(() => {
createComponent({
customStateProps: {
showActive: true,
@@ -376,7 +492,7 @@ describe('IntegrationForm', () => {
},
});
- await findActiveCheckbox().vm.$emit('toggle-integration-active', formActive);
+ findActiveCheckbox().vm.$emit('toggle-integration-active', formActive);
});
it(`sets noValidate to ${novalidate}`, () => {
diff --git a/spec/frontend/integrations/edit/components/sections/connection_spec.js b/spec/frontend/integrations/edit/components/sections/connection_spec.js
new file mode 100644
index 00000000000..1eb92e80723
--- /dev/null
+++ b/spec/frontend/integrations/edit/components/sections/connection_spec.js
@@ -0,0 +1,77 @@
+import { shallowMount } from '@vue/test-utils';
+
+import IntegrationSectionConnection from '~/integrations/edit/components/sections/connection.vue';
+import ActiveCheckbox from '~/integrations/edit/components/active_checkbox.vue';
+import DynamicField from '~/integrations/edit/components/dynamic_field.vue';
+import { createStore } from '~/integrations/edit/store';
+
+import { mockIntegrationProps } from '../../mock_data';
+
+describe('IntegrationSectionConnection', () => {
+ let wrapper;
+
+ const createComponent = ({ customStateProps = {}, props = {} } = {}) => {
+ const store = createStore({
+ customState: { ...mockIntegrationProps, ...customStateProps },
+ });
+ wrapper = shallowMount(IntegrationSectionConnection, {
+ propsData: { ...props },
+ store,
+ });
+ };
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ const findActiveCheckbox = () => wrapper.findComponent(ActiveCheckbox);
+ const findAllDynamicFields = () => wrapper.findAllComponents(DynamicField);
+
+ describe('template', () => {
+ describe('ActiveCheckbox', () => {
+ describe.each`
+ showActive
+ ${true}
+ ${false}
+ `('when `showActive` is $showActive', ({ showActive }) => {
+ it(`${showActive ? 'renders' : 'does not render'} ActiveCheckbox`, () => {
+ createComponent({
+ customStateProps: {
+ showActive,
+ },
+ });
+
+ expect(findActiveCheckbox().exists()).toBe(showActive);
+ });
+ });
+ });
+
+ describe('DynamicField', () => {
+ it('renders DynamicField for each field', () => {
+ const fields = [
+ { name: 'username', type: 'text' },
+ { name: 'API token', type: 'password' },
+ ];
+
+ createComponent({
+ props: {
+ fields,
+ },
+ });
+
+ const dynamicFields = findAllDynamicFields();
+
+ expect(dynamicFields).toHaveLength(2);
+ dynamicFields.wrappers.forEach((field, index) => {
+ expect(field.props()).toMatchObject(fields[index]);
+ });
+ });
+
+ it('does not render DynamicField when field is empty', () => {
+ createComponent();
+
+ expect(findAllDynamicFields()).toHaveLength(0);
+ });
+ });
+ });
+});
diff --git a/spec/frontend/integrations/edit/components/sections/jira_issues_spec.js b/spec/frontend/integrations/edit/components/sections/jira_issues_spec.js
new file mode 100644
index 00000000000..a7c1cc2a03f
--- /dev/null
+++ b/spec/frontend/integrations/edit/components/sections/jira_issues_spec.js
@@ -0,0 +1,34 @@
+import { shallowMount } from '@vue/test-utils';
+
+import IntegrationSectionJiraIssue from '~/integrations/edit/components/sections/jira_issues.vue';
+import JiraIssuesFields from '~/integrations/edit/components/jira_issues_fields.vue';
+import { createStore } from '~/integrations/edit/store';
+
+import { mockIntegrationProps } from '../../mock_data';
+
+describe('IntegrationSectionJiraIssue', () => {
+ let wrapper;
+
+ const createComponent = () => {
+ const store = createStore({
+ customState: { ...mockIntegrationProps },
+ });
+ wrapper = shallowMount(IntegrationSectionJiraIssue, {
+ store,
+ });
+ };
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ const findJiraIssuesFields = () => wrapper.findComponent(JiraIssuesFields);
+
+ describe('template', () => {
+ it('renders JiraIssuesFields', () => {
+ createComponent();
+
+ expect(findJiraIssuesFields().exists()).toBe(true);
+ });
+ });
+});
diff --git a/spec/frontend/integrations/edit/components/sections/jira_trigger_spec.js b/spec/frontend/integrations/edit/components/sections/jira_trigger_spec.js
new file mode 100644
index 00000000000..d4ab9864fab
--- /dev/null
+++ b/spec/frontend/integrations/edit/components/sections/jira_trigger_spec.js
@@ -0,0 +1,34 @@
+import { shallowMount } from '@vue/test-utils';
+
+import IntegrationSectionJiraTrigger from '~/integrations/edit/components/sections/jira_trigger.vue';
+import JiraTriggerFields from '~/integrations/edit/components/jira_trigger_fields.vue';
+import { createStore } from '~/integrations/edit/store';
+
+import { mockIntegrationProps } from '../../mock_data';
+
+describe('IntegrationSectionJiraTrigger', () => {
+ let wrapper;
+
+ const createComponent = () => {
+ const store = createStore({
+ customState: { ...mockIntegrationProps },
+ });
+ wrapper = shallowMount(IntegrationSectionJiraTrigger, {
+ store,
+ });
+ };
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ const findJiraTriggerFields = () => wrapper.findComponent(JiraTriggerFields);
+
+ describe('template', () => {
+ it('renders JiraTriggerFields', () => {
+ createComponent();
+
+ expect(findJiraTriggerFields().exists()).toBe(true);
+ });
+ });
+});
diff --git a/spec/frontend/integrations/edit/components/trigger_fields_spec.js b/spec/frontend/integrations/edit/components/trigger_fields_spec.js
index a0816682741..8ee55928926 100644
--- a/spec/frontend/integrations/edit/components/trigger_fields_spec.js
+++ b/spec/frontend/integrations/edit/components/trigger_fields_spec.js
@@ -40,13 +40,13 @@ describe('TriggerFields', () => {
describe('events without field property', () => {
const events = [
{
- title: 'push',
+ title: 'Push',
name: 'push_event',
description: 'Event on push',
value: true,
},
{
- title: 'merge_request',
+ title: 'Merge request',
name: 'merge_requests_event',
description: 'Event on merge_request',
value: false,
@@ -81,7 +81,7 @@ describe('TriggerFields', () => {
const checkboxes = findAllGlFormGroups();
const expectedResults = [
{ labelText: 'Push', inputName: 'service[push_event]' },
- { labelText: 'Merge Request', inputName: 'service[merge_requests_event]' },
+ { labelText: 'Merge request', inputName: 'service[merge_requests_event]' },
];
expect(checkboxes).toHaveLength(2);
diff --git a/spec/frontend/integrations/edit/mock_data.js b/spec/frontend/integrations/edit/mock_data.js
index 39e5f8521e8..36850a0a33a 100644
--- a/spec/frontend/integrations/edit/mock_data.js
+++ b/spec/frontend/integrations/edit/mock_data.js
@@ -10,9 +10,11 @@ export const mockIntegrationProps = {
},
jiraIssuesProps: {},
triggerEvents: [],
+ sections: [],
fields: [],
type: '',
inheritFromId: 25,
+ integrationLevel: 'project',
};
export const mockJiraIssueTypes = [
@@ -29,3 +31,9 @@ export const mockField = {
type: 'text',
value: '1',
};
+
+export const mockSectionConnection = {
+ type: 'connection',
+ title: 'Connection details',
+ description: 'Learn more on how to configure this integration.',
+};
diff --git a/spec/frontend/integrations/edit/store/getters_spec.js b/spec/frontend/integrations/edit/store/getters_spec.js
index 3353e0c84cc..4680c4b24cc 100644
--- a/spec/frontend/integrations/edit/store/getters_spec.js
+++ b/spec/frontend/integrations/edit/store/getters_spec.js
@@ -1,5 +1,12 @@
-import { currentKey, isInheriting, propsSource } from '~/integrations/edit/store/getters';
+import {
+ currentKey,
+ isInheriting,
+ isProjectLevel,
+ propsSource,
+} from '~/integrations/edit/store/getters';
+
import createState from '~/integrations/edit/store/state';
+import { integrationLevels } from '~/integrations/constants';
import { mockIntegrationProps } from '../mock_data';
describe('Integration form store getters', () => {
@@ -45,6 +52,18 @@ describe('Integration form store getters', () => {
});
});
+ describe('isProjectLevel', () => {
+ it.each`
+ integrationLevel | expected
+ ${integrationLevels.PROJECT} | ${true}
+ ${integrationLevels.GROUP} | ${false}
+ ${integrationLevels.INSTANCE} | ${false}
+ `('when integrationLevel is `$integrationLevel`', ({ integrationLevel, expected }) => {
+ state.customState.integrationLevel = integrationLevel;
+ expect(isProjectLevel(state)).toBe(expected);
+ });
+ });
+
describe('propsSource', () => {
beforeEach(() => {
state.defaultState = defaultState;
diff --git a/spec/frontend/invite_members/components/invite_groups_modal_spec.js b/spec/frontend/invite_members/components/invite_groups_modal_spec.js
index 49c55d56080..8085f48f6e2 100644
--- a/spec/frontend/invite_members/components/invite_groups_modal_spec.js
+++ b/spec/frontend/invite_members/components/invite_groups_modal_spec.js
@@ -4,6 +4,7 @@ import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import Api from '~/api';
import InviteGroupsModal from '~/invite_members/components/invite_groups_modal.vue';
import InviteModalBase from '~/invite_members/components/invite_modal_base.vue';
+import ContentTransition from '~/vue_shared/components/content_transition.vue';
import GroupSelect from '~/invite_members/components/group_select.vue';
import { stubComponent } from 'helpers/stub_component';
import { propsData, sharedGroup } from '../mock_data/group_modal';
@@ -19,6 +20,7 @@ describe('InviteGroupsModal', () => {
},
stubs: {
InviteModalBase,
+ ContentTransition,
GlSprintf,
GlModal: stubComponent(GlModal, {
template: '<div><slot></slot><slot name="modal-footer"></slot></div>',
@@ -50,6 +52,8 @@ describe('InviteGroupsModal', () => {
const clickInviteButton = () => findInviteButton().vm.$emit('click');
const clickCancelButton = () => findCancelButton().vm.$emit('click');
const triggerGroupSelect = (val) => findGroupSelect().vm.$emit('input', val);
+ const findBase = () => wrapper.findComponent(InviteModalBase);
+ const hideModal = () => wrapper.findComponent(GlModal).vm.$emit('hide');
describe('displaying the correct introText and form group description', () => {
describe('when inviting to a project', () => {
@@ -70,26 +74,50 @@ describe('InviteGroupsModal', () => {
});
describe('submitting the invite form', () => {
- describe('when sharing the group is successful', () => {
- const groupPostData = {
- group_id: sharedGroup.id,
- group_access: propsData.defaultAccessLevel,
- expires_at: undefined,
- format: 'json',
- };
+ let apiResolve;
+ let apiReject;
+ const groupPostData = {
+ group_id: sharedGroup.id,
+ group_access: propsData.defaultAccessLevel,
+ expires_at: undefined,
+ format: 'json',
+ };
+
+ beforeEach(() => {
+ createComponent();
+ triggerGroupSelect(sharedGroup);
+
+ wrapper.vm.$toast = { show: jest.fn() };
+ jest.spyOn(Api, 'groupShareWithGroup').mockImplementation(
+ () =>
+ new Promise((resolve, reject) => {
+ apiResolve = resolve;
+ apiReject = reject;
+ }),
+ );
+
+ clickInviteButton();
+ });
- beforeEach(() => {
- createComponent();
- triggerGroupSelect(sharedGroup);
+ it('shows loading', () => {
+ expect(findBase().props('isLoading')).toBe(true);
+ });
+
+ it('calls Api groupShareWithGroup with the correct params', () => {
+ expect(Api.groupShareWithGroup).toHaveBeenCalledWith(propsData.id, groupPostData);
+ });
- wrapper.vm.$toast = { show: jest.fn() };
- jest.spyOn(Api, 'groupShareWithGroup').mockResolvedValue({ data: groupPostData });
+ describe('when succeeds', () => {
+ beforeEach(() => {
+ apiResolve({ data: groupPostData });
+ });
- clickInviteButton();
+ it('hides loading', () => {
+ expect(findBase().props('isLoading')).toBe(false);
});
- it('calls Api groupShareWithGroup with the correct params', () => {
- expect(Api.groupShareWithGroup).toHaveBeenCalledWith(propsData.id, groupPostData);
+ it('has no error message', () => {
+ expect(findBase().props('invalidFeedbackMessage')).toBe('');
});
it('displays the successful toastMessage', () => {
@@ -99,18 +127,9 @@ describe('InviteGroupsModal', () => {
});
});
- describe('when sharing the group fails', () => {
+ describe('when fails', () => {
beforeEach(() => {
- createInviteGroupToGroupWrapper();
- triggerGroupSelect(sharedGroup);
-
- wrapper.vm.$toast = { show: jest.fn() };
-
- jest
- .spyOn(Api, 'groupShareWithGroup')
- .mockRejectedValue({ response: { data: { success: false } } });
-
- clickInviteButton();
+ apiReject({ response: { data: { success: false } } });
});
it('does not show the toast message on failure', () => {
@@ -121,22 +140,18 @@ describe('InviteGroupsModal', () => {
expect(membersFormGroupInvalidFeedback()).toBe('Something went wrong');
});
- describe('clearing the invalid state and message', () => {
- it('clears the error when the cancel button is clicked', async () => {
- clickCancelButton();
-
- await nextTick();
+ it.each`
+ desc | act
+ ${'when the cancel button is clicked'} | ${clickCancelButton}
+ ${'when the modal is hidden'} | ${hideModal}
+ ${'when invite button is clicked'} | ${clickInviteButton}
+ ${'when group input changes'} | ${() => triggerGroupSelect(sharedGroup)}
+ `('clears the error, $desc', async ({ act }) => {
+ act();
- expect(membersFormGroupInvalidFeedback()).toBe('');
- });
-
- it('clears the error when the modal is hidden', async () => {
- wrapper.findComponent(GlModal).vm.$emit('hide');
+ await nextTick();
- await nextTick();
-
- expect(membersFormGroupInvalidFeedback()).toBe('');
- });
+ expect(membersFormGroupInvalidFeedback()).toBe('');
});
});
});
diff --git a/spec/frontend/invite_members/components/invite_members_modal_spec.js b/spec/frontend/invite_members/components/invite_members_modal_spec.js
index 15a366474e4..dd16bb48cb8 100644
--- a/spec/frontend/invite_members/components/invite_members_modal_spec.js
+++ b/spec/frontend/invite_members/components/invite_members_modal_spec.js
@@ -19,6 +19,7 @@ import {
LEARN_GITLAB,
} from '~/invite_members/constants';
import eventHub from '~/invite_members/event_hub';
+import ContentTransition from '~/vue_shared/components/content_transition.vue';
import axios from '~/lib/utils/axios_utils';
import httpStatus from '~/lib/utils/http_status';
import { getParameterValues } from '~/lib/utils/url_utility';
@@ -55,6 +56,7 @@ describe('InviteMembersModal', () => {
},
stubs: {
InviteModalBase,
+ ContentTransition,
GlSprintf,
GlModal: stubComponent(GlModal, {
template: '<div><slot></slot><slot name="modal-footer"></slot></div>',
diff --git a/spec/frontend/invite_members/components/invite_modal_base_spec.js b/spec/frontend/invite_members/components/invite_modal_base_spec.js
index 4b183bfd670..9e17112fb15 100644
--- a/spec/frontend/invite_members/components/invite_modal_base_spec.js
+++ b/spec/frontend/invite_members/components/invite_modal_base_spec.js
@@ -10,22 +10,21 @@ import {
import { stubComponent } from 'helpers/stub_component';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import InviteModalBase from '~/invite_members/components/invite_modal_base.vue';
+import ContentTransition from '~/vue_shared/components/content_transition.vue';
import { CANCEL_BUTTON_TEXT, INVITE_BUTTON_TEXT } from '~/invite_members/constants';
import { propsData } from '../mock_data/modal_base';
describe('InviteModalBase', () => {
let wrapper;
- const createComponent = (data = {}, props = {}) => {
+ const createComponent = (props = {}) => {
wrapper = shallowMountExtended(InviteModalBase, {
propsData: {
...propsData,
...props,
},
- data() {
- return data;
- },
stubs: {
+ ContentTransition,
GlModal: stubComponent(GlModal, {
template:
'<div><slot name="modal-title"></slot><slot></slot><slot name="modal-footer"></slot></div>',
@@ -52,6 +51,7 @@ describe('InviteModalBase', () => {
const findIntroText = () => wrapper.findByTestId('modal-base-intro-text').text();
const findCancelButton = () => wrapper.findByTestId('cancel-button');
const findInviteButton = () => wrapper.findByTestId('invite-button');
+ const findMembersFormGroup = () => wrapper.findByTestId('members-form-group');
describe('rendering the modal', () => {
beforeEach(() => {
@@ -99,5 +99,33 @@ describe('InviteModalBase', () => {
expect(findDatepicker().exists()).toBe(true);
});
});
+
+ it('renders the members form group', () => {
+ expect(findMembersFormGroup().props()).toEqual({
+ description: propsData.formGroupDescription,
+ invalidFeedback: '',
+ state: null,
+ });
+ });
+ });
+
+ it('with isLoading, shows loading for invite button', () => {
+ createComponent({
+ isLoading: true,
+ });
+
+ expect(findInviteButton().props('loading')).toBe(true);
+ });
+
+ it('with invalidFeedbackMessage, set members form group validation state', () => {
+ createComponent({
+ invalidFeedbackMessage: 'invalid message!',
+ });
+
+ expect(findMembersFormGroup().props()).toEqual({
+ description: propsData.formGroupDescription,
+ invalidFeedback: 'invalid message!',
+ state: false,
+ });
});
});
diff --git a/spec/frontend/issuable/related_issues/components/related_issues_block_spec.js b/spec/frontend/issuable/related_issues/components/related_issues_block_spec.js
index c7925034eb0..7a350df0ba6 100644
--- a/spec/frontend/issuable/related_issues/components/related_issues_block_spec.js
+++ b/spec/frontend/issuable/related_issues/components/related_issues_block_spec.js
@@ -6,6 +6,7 @@ import {
issuable3,
} from 'jest/issuable/components/related_issuable_mock_data';
import RelatedIssuesBlock from '~/related_issues/components/related_issues_block.vue';
+import AddIssuableForm from '~/related_issues/components/add_issuable_form.vue';
import {
issuableTypesMap,
linkedIssueTypesMap,
@@ -139,6 +140,7 @@ describe('RelatedIssuesBlock', () => {
pathIdSeparator: PathIdSeparator.Issue,
isFormVisible: true,
issuableType: 'issue',
+ autoCompleteEpics: false,
},
});
});
@@ -146,6 +148,10 @@ describe('RelatedIssuesBlock', () => {
it('shows add related issues form', () => {
expect(wrapper.find('.js-add-related-issues-form-area').exists()).toBe(true);
});
+
+ it('sets `autoCompleteEpics` to false for add-issuable-form', () => {
+ expect(wrapper.find(AddIssuableForm).props('autoCompleteEpics')).toBe(false);
+ });
});
describe('showCategorizedIssues prop', () => {
diff --git a/spec/frontend/issuable/related_issues/components/related_issues_list_spec.js b/spec/frontend/issuable/related_issues/components/related_issues_list_spec.js
index c7df3755e88..fd623ad9a5f 100644
--- a/spec/frontend/issuable/related_issues/components/related_issues_list_spec.js
+++ b/spec/frontend/issuable/related_issues/components/related_issues_list_spec.js
@@ -28,11 +28,16 @@ describe('RelatedIssuesList', () => {
propsData: {
pathIdSeparator: PathIdSeparator.Issue,
issuableType: 'issue',
+ listLinkType: 'relates_to',
heading,
},
});
});
+ it('assigns value of listLinkType prop to data attribute', () => {
+ expect(wrapper.attributes('data-link-type')).toBe('relates_to');
+ });
+
it('shows a heading', () => {
expect(wrapper.find('h4').text()).toContain(heading);
});
diff --git a/spec/frontend/issues/list/components/issues_list_app_spec.js b/spec/frontend/issues/list/components/issues_list_app_spec.js
index 88652ddc3cc..33c7ccac180 100644
--- a/spec/frontend/issues/list/components/issues_list_app_spec.js
+++ b/spec/frontend/issues/list/components/issues_list_app_spec.js
@@ -294,6 +294,28 @@ describe('CE IssuesListApp component', () => {
});
describe('initial url params', () => {
+ describe('page', () => {
+ it('page_after is set from the url params', () => {
+ setWindowLocation('?page_after=randomCursorString');
+
+ wrapper = mountComponent();
+
+ expect(findIssuableList().props('urlParams')).toMatchObject({
+ page_after: 'randomCursorString',
+ });
+ });
+
+ it('page_before is set from the url params', () => {
+ setWindowLocation('?page_before=anotherRandomCursorString');
+
+ wrapper = mountComponent();
+
+ expect(findIssuableList().props('urlParams')).toMatchObject({
+ page_before: 'anotherRandomCursorString',
+ });
+ });
+ });
+
describe('search', () => {
it('is set from the url params', () => {
setWindowLocation(locationSearch);
@@ -881,7 +903,12 @@ describe('CE IssuesListApp component', () => {
});
it('does not update IssuableList with url params ', async () => {
- const defaultParams = { sort: 'created_date', state: 'opened' };
+ const defaultParams = {
+ page_after: null,
+ page_before: null,
+ sort: 'created_date',
+ state: 'opened',
+ };
expect(findIssuableList().props('urlParams')).toEqual(defaultParams);
});
diff --git a/spec/frontend/issues/list/utils_spec.js b/spec/frontend/issues/list/utils_spec.js
index 1d3e94df897..a60350d91c5 100644
--- a/spec/frontend/issues/list/utils_spec.js
+++ b/spec/frontend/issues/list/utils_spec.js
@@ -9,8 +9,8 @@ import {
urlParamsWithSpecialValues,
} from 'jest/issues/list/mock_data';
import {
- defaultPageSizeParams,
- largePageSizeParams,
+ PAGE_SIZE,
+ PAGE_SIZE_MANUAL,
RELATIVE_POSITION_ASC,
urlSortParams,
} from '~/issues/list/constants';
@@ -29,10 +29,37 @@ describe('getInitialPageParams', () => {
it.each(Object.keys(urlSortParams))(
'returns the correct page params for sort key %s',
(sortKey) => {
- const expectedPageParams =
- sortKey === RELATIVE_POSITION_ASC ? largePageSizeParams : defaultPageSizeParams;
+ const firstPageSize = sortKey === RELATIVE_POSITION_ASC ? PAGE_SIZE_MANUAL : PAGE_SIZE;
- expect(getInitialPageParams(sortKey)).toBe(expectedPageParams);
+ expect(getInitialPageParams(sortKey)).toEqual({ firstPageSize });
+ },
+ );
+
+ it.each(Object.keys(urlSortParams))(
+ 'returns the correct page params for sort key %s with afterCursor',
+ (sortKey) => {
+ const firstPageSize = sortKey === RELATIVE_POSITION_ASC ? PAGE_SIZE_MANUAL : PAGE_SIZE;
+ const afterCursor = 'randomCursorString';
+ const beforeCursor = undefined;
+
+ expect(getInitialPageParams(sortKey, afterCursor, beforeCursor)).toEqual({
+ firstPageSize,
+ afterCursor,
+ });
+ },
+ );
+
+ it.each(Object.keys(urlSortParams))(
+ 'returns the correct page params for sort key %s with beforeCursor',
+ (sortKey) => {
+ const firstPageSize = sortKey === RELATIVE_POSITION_ASC ? PAGE_SIZE_MANUAL : PAGE_SIZE;
+ const afterCursor = undefined;
+ const beforeCursor = 'anotherRandomCursorString';
+
+ expect(getInitialPageParams(sortKey, afterCursor, beforeCursor)).toEqual({
+ firstPageSize,
+ beforeCursor,
+ });
},
);
});
diff --git a/spec/frontend/issues/show/components/description_spec.js b/spec/frontend/issues/show/components/description_spec.js
index 3890fc7a353..08f8996de6f 100644
--- a/spec/frontend/issues/show/components/description_spec.js
+++ b/spec/frontend/issues/show/components/description_spec.js
@@ -2,17 +2,21 @@ import $ from 'jquery';
import { nextTick } from 'vue';
import '~/behaviors/markdown/render_gfm';
import { GlPopover, GlModal } from '@gitlab/ui';
-import { shallowMount } from '@vue/test-utils';
import { stubComponent } from 'helpers/stub_component';
import { TEST_HOST } from 'helpers/test_constants';
+import { mockTracking } from 'helpers/tracking_helper';
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
+import createFlash from '~/flash';
import Description from '~/issues/show/components/description.vue';
import TaskList from '~/task_list';
+import WorkItemDetailModal from '~/work_items/components/work_item_detail_modal.vue';
import CreateWorkItem from '~/work_items/pages/create_work_item.vue';
import {
descriptionProps as initialProps,
descriptionHtmlWithCheckboxes,
} from '../mock_data/mock_data';
+jest.mock('~/flash');
jest.mock('~/task_list');
const showModal = jest.fn();
@@ -30,9 +34,10 @@ describe('Description component', () => {
const findPopovers = () => wrapper.findAllComponents(GlPopover);
const findModal = () => wrapper.findComponent(GlModal);
const findCreateWorkItem = () => wrapper.findComponent(CreateWorkItem);
+ const findWorkItemDetailModal = () => wrapper.findComponent(WorkItemDetailModal);
function createComponent({ props = {}, provide = {} } = {}) {
- wrapper = shallowMount(Description, {
+ wrapper = shallowMountExtended(Description, {
propsData: {
...initialProps,
...props,
@@ -210,7 +215,7 @@ describe('Description component', () => {
describe('with work items feature flag is enabled', () => {
describe('empty description', () => {
- beforeEach(async () => {
+ beforeEach(() => {
createComponent({
props: {
descriptionHtml: '',
@@ -221,7 +226,7 @@ describe('Description component', () => {
},
},
});
- await nextTick();
+ return nextTick();
});
it('renders without error', () => {
@@ -230,7 +235,7 @@ describe('Description component', () => {
});
describe('description with checkboxes', () => {
- beforeEach(async () => {
+ beforeEach(() => {
createComponent({
props: {
descriptionHtml: descriptionHtmlWithCheckboxes,
@@ -241,7 +246,7 @@ describe('Description component', () => {
},
},
});
- await nextTick();
+ return nextTick();
});
it('renders a list of hidden buttons corresponding to checkboxes in description HTML', () => {
@@ -275,7 +280,7 @@ describe('Description component', () => {
it('updates description HTML on `onCreate` event', async () => {
const newTitle = 'New title';
findConvertToTaskButton().vm.$emit('click');
- findCreateWorkItem().vm.$emit('onCreate', newTitle);
+ findCreateWorkItem().vm.$emit('onCreate', { title: newTitle });
expect(hideModal).toHaveBeenCalled();
await nextTick();
@@ -283,5 +288,69 @@ describe('Description component', () => {
expect(wrapper.text()).toContain(newTitle);
});
});
+
+ describe('work items detail', () => {
+ const id = '1';
+ const title = 'my first task';
+ const type = 'task';
+
+ const createThenClickOnTask = () => {
+ findConvertToTaskButton().vm.$emit('click');
+ findCreateWorkItem().vm.$emit('onCreate', { id, title, type });
+ return wrapper.findByRole('button', { name: title }).trigger('click');
+ };
+
+ beforeEach(() => {
+ createComponent({
+ props: {
+ descriptionHtml: descriptionHtmlWithCheckboxes,
+ },
+ provide: {
+ glFeatures: { workItems: true },
+ },
+ });
+ return nextTick();
+ });
+
+ it('opens when task button is clicked', async () => {
+ expect(findWorkItemDetailModal().props('visible')).toBe(false);
+
+ await createThenClickOnTask();
+
+ expect(findWorkItemDetailModal().props('visible')).toBe(true);
+ });
+
+ it('closes from an open state', async () => {
+ await createThenClickOnTask();
+
+ expect(findWorkItemDetailModal().props('visible')).toBe(true);
+
+ findWorkItemDetailModal().vm.$emit('close');
+ await nextTick();
+
+ expect(findWorkItemDetailModal().props('visible')).toBe(false);
+ });
+
+ it('shows error on error', async () => {
+ const message = 'I am error';
+
+ await createThenClickOnTask();
+ findWorkItemDetailModal().vm.$emit('error', message);
+
+ expect(createFlash).toHaveBeenCalledWith({ message });
+ });
+
+ it('tracks when opened', async () => {
+ const trackingSpy = mockTracking(undefined, wrapper.element, jest.spyOn);
+
+ await createThenClickOnTask();
+
+ expect(trackingSpy).toHaveBeenCalledWith('workItems:show', 'viewed_work_item_from_modal', {
+ category: 'workItems:show',
+ label: 'work_item_view',
+ property: 'type_task',
+ });
+ });
+ });
});
});
diff --git a/spec/frontend/issues/show/components/header_actions_spec.js b/spec/frontend/issues/show/components/header_actions_spec.js
index 4a557a60b94..329c4234f30 100644
--- a/spec/frontend/issues/show/components/header_actions_spec.js
+++ b/spec/frontend/issues/show/components/header_actions_spec.js
@@ -1,5 +1,5 @@
-import { GlButton, GlDropdown, GlDropdownItem, GlLink, GlModal } from '@gitlab/ui';
import Vue, { nextTick } from 'vue';
+import { GlButton, GlDropdownItem, GlLink, GlModal } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vuex from 'vuex';
import { mockTracking } from 'helpers/tracking_helper';
@@ -65,12 +65,17 @@ describe('HeaderActions component', () => {
},
};
- const findToggleIssueStateButton = () => wrapper.findComponent(GlButton);
- const findDropdownAt = (index) => wrapper.findAllComponents(GlDropdown).at(index);
- const findMobileDropdownItems = () => findDropdownAt(0).findAllComponents(GlDropdownItem);
- const findDesktopDropdownItems = () => findDropdownAt(1).findAllComponents(GlDropdownItem);
- const findModal = () => wrapper.findComponent(GlModal);
- const findModalLinkAt = (index) => findModal().findAllComponents(GlLink).at(index);
+ const findToggleIssueStateButton = () => wrapper.find(GlButton);
+
+ const findDropdownBy = (dataTestId) => wrapper.find(`[data-testid="${dataTestId}"]`);
+ const findMobileDropdown = () => findDropdownBy('mobile-dropdown');
+ const findDesktopDropdown = () => findDropdownBy('desktop-dropdown');
+ const findMobileDropdownItems = () => findMobileDropdown().findAll(GlDropdownItem);
+ const findDesktopDropdownItems = () => findDesktopDropdown().findAll(GlDropdownItem);
+
+ const findModal = () => wrapper.find(GlModal);
+
+ const findModalLinkAt = (index) => findModal().findAll(GlLink).at(index);
const mountComponent = ({
props = {},
@@ -161,24 +166,24 @@ describe('HeaderActions component', () => {
});
describe.each`
- description | isCloseIssueItemVisible | findDropdownItems
- ${'mobile dropdown'} | ${true} | ${findMobileDropdownItems}
- ${'desktop dropdown'} | ${false} | ${findDesktopDropdownItems}
- `('$description', ({ isCloseIssueItemVisible, findDropdownItems }) => {
+ description | isCloseIssueItemVisible | findDropdownItems | findDropdown
+ ${'mobile dropdown'} | ${true} | ${findMobileDropdownItems} | ${findMobileDropdown}
+ ${'desktop dropdown'} | ${false} | ${findDesktopDropdownItems} | ${findDesktopDropdown}
+ `('$description', ({ isCloseIssueItemVisible, findDropdownItems, findDropdown }) => {
describe.each`
- description | itemText | isItemVisible | canUpdateIssue | canCreateIssue | isIssueAuthor | canReportSpam | canPromoteToEpic | canDestroyIssue
- ${`when user can update ${issueType}`} | ${`Close ${issueType}`} | ${isCloseIssueItemVisible} | ${true} | ${true} | ${true} | ${true} | ${true} | ${true}
- ${`when user cannot update ${issueType}`} | ${`Close ${issueType}`} | ${false} | ${false} | ${true} | ${true} | ${true} | ${true} | ${true}
- ${`when user can create ${issueType}`} | ${`New ${issueType}`} | ${true} | ${true} | ${true} | ${true} | ${true} | ${true} | ${true}
- ${`when user cannot create ${issueType}`} | ${`New ${issueType}`} | ${false} | ${true} | ${false} | ${true} | ${true} | ${true} | ${true}
- ${'when user can promote to epic'} | ${'Promote to epic'} | ${true} | ${true} | ${true} | ${true} | ${true} | ${true} | ${true}
- ${'when user cannot promote to epic'} | ${'Promote to epic'} | ${false} | ${true} | ${true} | ${true} | ${true} | ${false} | ${true}
- ${'when user can report abuse'} | ${'Report abuse'} | ${true} | ${true} | ${true} | ${false} | ${true} | ${true} | ${true}
- ${'when user cannot report abuse'} | ${'Report abuse'} | ${false} | ${true} | ${true} | ${true} | ${true} | ${true} | ${true}
- ${'when user can submit as spam'} | ${'Submit as spam'} | ${true} | ${true} | ${true} | ${true} | ${true} | ${true} | ${true}
- ${'when user cannot submit as spam'} | ${'Submit as spam'} | ${false} | ${true} | ${true} | ${true} | ${false} | ${true} | ${true}
- ${`when user can delete ${issueType}`} | ${`Delete ${issueType}`} | ${true} | ${true} | ${true} | ${true} | ${true} | ${true} | ${true}
- ${`when user cannot delete ${issueType}`} | ${`Delete ${issueType}`} | ${false} | ${true} | ${true} | ${true} | ${true} | ${true} | ${false}
+ description | itemText | isItemVisible | canUpdateIssue | canCreateIssue | isIssueAuthor | canReportSpam | canPromoteToEpic | canDestroyIssue
+ ${`when user can update ${issueType}`} | ${`Close ${issueType}`} | ${isCloseIssueItemVisible} | ${true} | ${true} | ${true} | ${true} | ${true} | ${true}
+ ${`when user cannot update ${issueType}`} | ${`Close ${issueType}`} | ${false} | ${false} | ${true} | ${true} | ${true} | ${true} | ${true}
+ ${`when user can create ${issueType}`} | ${`New related ${issueType}`} | ${true} | ${true} | ${true} | ${true} | ${true} | ${true} | ${true}
+ ${`when user cannot create ${issueType}`} | ${`New related ${issueType}`} | ${false} | ${true} | ${false} | ${true} | ${true} | ${true} | ${true}
+ ${'when user can promote to epic'} | ${'Promote to epic'} | ${true} | ${true} | ${true} | ${true} | ${true} | ${true} | ${true}
+ ${'when user cannot promote to epic'} | ${'Promote to epic'} | ${false} | ${true} | ${true} | ${true} | ${true} | ${false} | ${true}
+ ${'when user can report abuse'} | ${'Report abuse'} | ${true} | ${true} | ${true} | ${false} | ${true} | ${true} | ${true}
+ ${'when user cannot report abuse'} | ${'Report abuse'} | ${false} | ${true} | ${true} | ${true} | ${true} | ${true} | ${true}
+ ${'when user can submit as spam'} | ${'Submit as spam'} | ${true} | ${true} | ${true} | ${true} | ${true} | ${true} | ${true}
+ ${'when user cannot submit as spam'} | ${'Submit as spam'} | ${false} | ${true} | ${true} | ${true} | ${false} | ${true} | ${true}
+ ${`when user can delete ${issueType}`} | ${`Delete ${issueType}`} | ${true} | ${true} | ${true} | ${true} | ${true} | ${true} | ${true}
+ ${`when user cannot delete ${issueType}`} | ${`Delete ${issueType}`} | ${false} | ${true} | ${true} | ${true} | ${true} | ${true} | ${false}
`(
'$description',
({
@@ -214,6 +219,24 @@ describe('HeaderActions component', () => {
});
},
);
+
+ describe(`when user can update but not create ${issueType}`, () => {
+ beforeEach(() => {
+ wrapper = mountComponent({
+ props: {
+ canUpdateIssue: true,
+ canCreateIssue: false,
+ isIssueAuthor: true,
+ issueType,
+ canReportSpam: false,
+ canPromoteToEpic: false,
+ },
+ });
+ });
+ it(`${isCloseIssueItemVisible ? 'shows' : 'hides'} the dropdown button`, () => {
+ expect(findDropdown().exists()).toBe(isCloseIssueItemVisible);
+ });
+ });
});
});
diff --git a/spec/frontend/issues/show/components/incidents/incident_tabs_spec.js b/spec/frontend/issues/show/components/incidents/incident_tabs_spec.js
index 9bf0e106194..20c6cda33d4 100644
--- a/spec/frontend/issues/show/components/incidents/incident_tabs_spec.js
+++ b/spec/frontend/issues/show/components/incidents/incident_tabs_spec.js
@@ -1,7 +1,6 @@
import { GlTab } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import merge from 'lodash/merge';
-import waitForPromises from 'helpers/wait_for_promises';
import { trackIncidentDetailsViewsOptions } from '~/incidents/constants';
import DescriptionComponent from '~/issues/show/components/description.vue';
import HighlightBar from '~/issues/show/components/incidents/highlight_bar.vue';
@@ -36,6 +35,7 @@ describe('Incident Tabs component', () => {
fullPath: '',
iid: '',
uploadMetricsFeatureAvailable: true,
+ glFeatures: { incidentTimelineEventTab: true, incidentTimelineEvents: true },
},
data() {
return { alert: mockAlert, ...data };
@@ -112,19 +112,15 @@ describe('Incident Tabs component', () => {
});
describe('upload metrics feature available', () => {
- it('shows the metric tab when metrics are available', async () => {
+ it('shows the metric tab when metrics are available', () => {
mountComponent({}, { provide: { uploadMetricsFeatureAvailable: true } });
- await waitForPromises();
-
expect(findMetricsTab().exists()).toBe(true);
});
- it('hides the tab when metrics are not available', async () => {
+ it('hides the tab when metrics are not available', () => {
mountComponent({}, { provide: { uploadMetricsFeatureAvailable: false } });
- await waitForPromises();
-
expect(findMetricsTab().exists()).toBe(false);
});
});
diff --git a/spec/frontend/jira_connect/subscriptions/components/app_spec.js b/spec/frontend/jira_connect/subscriptions/components/app_spec.js
index aa0f1440b20..6b3ca7ffd65 100644
--- a/spec/frontend/jira_connect/subscriptions/components/app_spec.js
+++ b/spec/frontend/jira_connect/subscriptions/components/app_spec.js
@@ -8,6 +8,7 @@ import SubscriptionsPage from '~/jira_connect/subscriptions/pages/subscriptions.
import UserLink from '~/jira_connect/subscriptions/components/user_link.vue';
import createStore from '~/jira_connect/subscriptions/store';
import { SET_ALERT } from '~/jira_connect/subscriptions/store/mutation_types';
+import { I18N_DEFAULT_SIGN_IN_ERROR_MESSAGE } from '~/jira_connect/subscriptions/constants';
import { __ } from '~/locale';
import { mockSubscription } from '../mock_data';
@@ -24,6 +25,7 @@ describe('JiraConnectApp', () => {
const findAlertLink = () => findAlert().findComponent(GlLink);
const findSignInPage = () => wrapper.findComponent(SignInPage);
const findSubscriptionsPage = () => wrapper.findComponent(SubscriptionsPage);
+ const findUserLink = () => wrapper.findComponent(UserLink);
const createComponent = ({ provide, mountFn = shallowMountExtended } = {}) => {
store = createStore();
@@ -78,10 +80,11 @@ describe('JiraConnectApp', () => {
},
});
- const userLink = wrapper.findComponent(UserLink);
+ const userLink = findUserLink();
expect(userLink.exists()).toBe(true);
expect(userLink.props()).toEqual({
hasSubscriptions: false,
+ user: null,
userSignedIn: false,
});
});
@@ -153,4 +156,55 @@ describe('JiraConnectApp', () => {
});
});
});
+
+ describe('when user signed out', () => {
+ describe('when sign in page emits `sign-in-oauth` event', () => {
+ const mockUser = { name: 'test' };
+ beforeEach(async () => {
+ createComponent({
+ provide: {
+ usersPath: '/mock',
+ subscriptions: [],
+ },
+ });
+ findSignInPage().vm.$emit('sign-in-oauth', mockUser);
+
+ await nextTick();
+ });
+
+ it('hides sign in page and renders subscriptions page', () => {
+ expect(findSignInPage().exists()).toBe(false);
+ expect(findSubscriptionsPage().exists()).toBe(true);
+ });
+
+ it('sets correct UserLink props', () => {
+ expect(findUserLink().props()).toMatchObject({
+ user: mockUser,
+ userSignedIn: true,
+ });
+ });
+ });
+
+ describe('when sign in page emits `error` event', () => {
+ beforeEach(async () => {
+ createComponent({
+ provide: {
+ usersPath: '/mock',
+ subscriptions: [],
+ },
+ });
+ findSignInPage().vm.$emit('error');
+
+ await nextTick();
+ });
+
+ it('displays alert', () => {
+ const alert = findAlert();
+
+ expect(alert.exists()).toBe(true);
+ expect(alert.html()).toContain(I18N_DEFAULT_SIGN_IN_ERROR_MESSAGE);
+ expect(alert.props('variant')).toBe('danger');
+ });
+ });
+ });
});
diff --git a/spec/frontend/jira_connect/subscriptions/components/sign_in_button_spec.js b/spec/frontend/jira_connect/subscriptions/components/sign_in_button_spec.js
deleted file mode 100644
index 94dcf9decec..00000000000
--- a/spec/frontend/jira_connect/subscriptions/components/sign_in_button_spec.js
+++ /dev/null
@@ -1,58 +0,0 @@
-import { GlButton } from '@gitlab/ui';
-import { shallowMount } from '@vue/test-utils';
-import { getGitlabSignInURL } from '~/jira_connect/subscriptions/utils';
-import SignInButton from '~/jira_connect/subscriptions/components/sign_in_button.vue';
-import waitForPromises from 'helpers/wait_for_promises';
-
-const MOCK_USERS_PATH = '/user';
-
-jest.mock('~/jira_connect/subscriptions/utils');
-
-describe('SignInButton', () => {
- let wrapper;
-
- const createComponent = ({ slots } = {}) => {
- wrapper = shallowMount(SignInButton, {
- propsData: {
- usersPath: MOCK_USERS_PATH,
- },
- slots,
- });
- };
-
- const findButton = () => wrapper.findComponent(GlButton);
-
- afterEach(() => {
- wrapper.destroy();
- });
-
- it('displays a button', () => {
- createComponent();
-
- expect(findButton().exists()).toBe(true);
- expect(findButton().text()).toBe(SignInButton.i18n.defaultButtonText);
- });
-
- describe.each`
- expectedHref
- ${MOCK_USERS_PATH}
- ${`${MOCK_USERS_PATH}?return_to=${encodeURIComponent('https://test.jira.com')}`}
- `('when getGitlabSignInURL resolves with `$expectedHref`', ({ expectedHref }) => {
- it(`sets button href to ${expectedHref}`, async () => {
- getGitlabSignInURL.mockResolvedValue(expectedHref);
- createComponent();
-
- await waitForPromises();
-
- expect(findButton().attributes('href')).toBe(expectedHref);
- });
- });
-
- describe('with slot', () => {
- const mockSlotContent = 'custom button content!';
- it('renders slot content in button', () => {
- createComponent({ slots: { default: mockSlotContent } });
- expect(wrapper.text()).toMatchInterpolatedText(mockSlotContent);
- });
- });
-});
diff --git a/spec/frontend/jira_connect/subscriptions/components/sign_in_legacy_button_spec.js b/spec/frontend/jira_connect/subscriptions/components/sign_in_legacy_button_spec.js
new file mode 100644
index 00000000000..4ebfaed261e
--- /dev/null
+++ b/spec/frontend/jira_connect/subscriptions/components/sign_in_legacy_button_spec.js
@@ -0,0 +1,58 @@
+import { GlButton } from '@gitlab/ui';
+import { shallowMount } from '@vue/test-utils';
+import { getGitlabSignInURL } from '~/jira_connect/subscriptions/utils';
+import SignInLegacyButton from '~/jira_connect/subscriptions/components/sign_in_legacy_button.vue';
+import waitForPromises from 'helpers/wait_for_promises';
+
+const MOCK_USERS_PATH = '/user';
+
+jest.mock('~/jira_connect/subscriptions/utils');
+
+describe('SignInLegacyButton', () => {
+ let wrapper;
+
+ const createComponent = ({ slots } = {}) => {
+ wrapper = shallowMount(SignInLegacyButton, {
+ propsData: {
+ usersPath: MOCK_USERS_PATH,
+ },
+ slots,
+ });
+ };
+
+ const findButton = () => wrapper.findComponent(GlButton);
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ it('displays a button', () => {
+ createComponent();
+
+ expect(findButton().exists()).toBe(true);
+ expect(findButton().text()).toBe(SignInLegacyButton.i18n.defaultButtonText);
+ });
+
+ describe.each`
+ expectedHref
+ ${MOCK_USERS_PATH}
+ ${`${MOCK_USERS_PATH}?return_to=${encodeURIComponent('https://test.jira.com')}`}
+ `('when getGitlabSignInURL resolves with `$expectedHref`', ({ expectedHref }) => {
+ it(`sets button href to ${expectedHref}`, async () => {
+ getGitlabSignInURL.mockResolvedValue(expectedHref);
+ createComponent();
+
+ await waitForPromises();
+
+ expect(findButton().attributes('href')).toBe(expectedHref);
+ });
+ });
+
+ describe('with slot', () => {
+ const mockSlotContent = 'custom button content!';
+ it('renders slot content in button', () => {
+ createComponent({ slots: { default: mockSlotContent } });
+ expect(wrapper.text()).toMatchInterpolatedText(mockSlotContent);
+ });
+ });
+});
diff --git a/spec/frontend/jira_connect/subscriptions/components/sign_in_oauth_button_spec.js b/spec/frontend/jira_connect/subscriptions/components/sign_in_oauth_button_spec.js
new file mode 100644
index 00000000000..18274cd4362
--- /dev/null
+++ b/spec/frontend/jira_connect/subscriptions/components/sign_in_oauth_button_spec.js
@@ -0,0 +1,204 @@
+import { GlButton } from '@gitlab/ui';
+import { shallowMount } from '@vue/test-utils';
+import MockAdapter from 'axios-mock-adapter';
+import { nextTick } from 'vue';
+import SignInOauthButton from '~/jira_connect/subscriptions/components/sign_in_oauth_button.vue';
+import {
+ I18N_DEFAULT_SIGN_IN_BUTTON_TEXT,
+ OAUTH_WINDOW_OPTIONS,
+} from '~/jira_connect/subscriptions/constants';
+import axios from '~/lib/utils/axios_utils';
+import waitForPromises from 'helpers/wait_for_promises';
+import httpStatus from '~/lib/utils/http_status';
+import AccessorUtilities from '~/lib/utils/accessor';
+
+jest.mock('~/lib/utils/accessor');
+jest.mock('~/jira_connect/subscriptions/utils');
+jest.mock('~/jira_connect/subscriptions/pkce', () => ({
+ createCodeVerifier: jest.fn().mockReturnValue('mock-verifier'),
+ createCodeChallenge: jest.fn().mockResolvedValue('mock-challenge'),
+}));
+
+const mockOauthMetadata = {
+ oauth_authorize_url: 'https://gitlab.com/mockOauth',
+ oauth_token_url: 'https://gitlab.com/mockOauthToken',
+ state: 'good-state',
+};
+
+describe('SignInOauthButton', () => {
+ let wrapper;
+ let mockAxios;
+
+ const createComponent = ({ slots } = {}) => {
+ wrapper = shallowMount(SignInOauthButton, {
+ slots,
+ provide: {
+ oauthMetadata: mockOauthMetadata,
+ },
+ });
+ };
+
+ beforeEach(() => {
+ mockAxios = new MockAdapter(axios);
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ mockAxios.restore();
+ });
+
+ const findButton = () => wrapper.findComponent(GlButton);
+
+ it('displays a button', () => {
+ createComponent();
+
+ expect(findButton().exists()).toBe(true);
+ expect(findButton().text()).toBe(I18N_DEFAULT_SIGN_IN_BUTTON_TEXT);
+ });
+
+ it.each`
+ scenario | cryptoAvailable
+ ${'when crypto API is available'} | ${true}
+ ${'when crypto API is unavailable'} | ${false}
+ `('$scenario when canUseCrypto returns $cryptoAvailable', ({ cryptoAvailable }) => {
+ AccessorUtilities.canUseCrypto = jest.fn().mockReturnValue(cryptoAvailable);
+ createComponent();
+
+ expect(findButton().props('disabled')).toBe(!cryptoAvailable);
+ });
+
+ describe('on click', () => {
+ beforeEach(async () => {
+ jest.spyOn(window, 'open').mockReturnValue();
+ createComponent();
+
+ findButton().vm.$emit('click');
+
+ await nextTick();
+ });
+
+ it('sets `loading` prop of button to `true`', () => {
+ expect(findButton().props('loading')).toBe(true);
+ });
+
+ it('calls `window.open` with correct arguments', () => {
+ expect(window.open).toHaveBeenCalledWith(
+ `${mockOauthMetadata.oauth_authorize_url}?code_challenge=mock-challenge&code_challenge_method=S256`,
+ I18N_DEFAULT_SIGN_IN_BUTTON_TEXT,
+ OAUTH_WINDOW_OPTIONS,
+ );
+ });
+
+ it('sets the `codeVerifier` internal state', () => {
+ expect(wrapper.vm.codeVerifier).toBe('mock-verifier');
+ });
+
+ describe('on window message event', () => {
+ describe('when window message properties are corrupted', () => {
+ describe.each`
+ origin | state | messageOrigin | messageState
+ ${window.origin} | ${mockOauthMetadata.state} | ${'bad-origin'} | ${mockOauthMetadata.state}
+ ${window.origin} | ${mockOauthMetadata.state} | ${window.origin} | ${'bad-state'}
+ `(
+ 'when message is [state=$messageState, origin=$messageOrigin]',
+ ({ messageOrigin, messageState }) => {
+ beforeEach(async () => {
+ const mockEvent = {
+ origin: messageOrigin,
+ data: {
+ state: messageState,
+ code: '1234',
+ },
+ };
+ window.dispatchEvent(new MessageEvent('message', mockEvent));
+ await waitForPromises();
+ });
+
+ it('emits `error` event', () => {
+ expect(wrapper.emitted('error')).toBeTruthy();
+ });
+
+ it('does not emit `sign-in` event', () => {
+ expect(wrapper.emitted('sign-in')).toBeFalsy();
+ });
+
+ it('sets `loading` prop of button to `false`', () => {
+ expect(findButton().props('loading')).toBe(false);
+ });
+ },
+ );
+ });
+
+ describe('when window message properties are valid', () => {
+ const mockAccessToken = '5678';
+ const mockUser = { name: 'test user' };
+ const mockEvent = {
+ origin: window.origin,
+ data: {
+ state: mockOauthMetadata.state,
+ code: '1234',
+ },
+ };
+
+ describe('when API requests succeed', () => {
+ beforeEach(async () => {
+ jest.spyOn(axios, 'post');
+ jest.spyOn(axios, 'get');
+ mockAxios
+ .onPost(mockOauthMetadata.oauth_token_url)
+ .replyOnce(httpStatus.OK, { access_token: mockAccessToken });
+ mockAxios.onGet('/api/v4/user').replyOnce(httpStatus.OK, mockUser);
+
+ window.dispatchEvent(new MessageEvent('message', mockEvent));
+
+ await waitForPromises();
+ });
+
+ it('executes POST request to Oauth token endpoint', () => {
+ expect(axios.post).toHaveBeenCalledWith(mockOauthMetadata.oauth_token_url, {
+ code: '1234',
+ code_verifier: 'mock-verifier',
+ });
+ });
+
+ it('executes GET request to fetch user data', () => {
+ expect(axios.get).toHaveBeenCalledWith('/api/v4/user', {
+ headers: { Authorization: `Bearer ${mockAccessToken}` },
+ });
+ });
+
+ it('emits `sign-in` event with user data', () => {
+ expect(wrapper.emitted('sign-in')[0]).toEqual([mockUser]);
+ });
+ });
+
+ describe('when API requests fail', () => {
+ beforeEach(async () => {
+ jest.spyOn(axios, 'post');
+ jest.spyOn(axios, 'get');
+ mockAxios
+ .onPost(mockOauthMetadata.oauth_token_url)
+ .replyOnce(httpStatus.INTERNAL_SERVER_ERROR, { access_token: mockAccessToken });
+ mockAxios.onGet('/api/v4/user').replyOnce(httpStatus.INTERNAL_SERVER_ERROR, mockUser);
+
+ window.dispatchEvent(new MessageEvent('message', mockEvent));
+
+ await waitForPromises();
+ });
+
+ it('emits `error` event', () => {
+ expect(wrapper.emitted('error')).toBeTruthy();
+ });
+
+ it('does not emit `sign-in` event', () => {
+ expect(wrapper.emitted('sign-in')).toBeFalsy();
+ });
+
+ it('sets `loading` prop of button to `false`', () => {
+ expect(findButton().props('loading')).toBe(false);
+ });
+ });
+ });
+ });
+ });
+});
diff --git a/spec/frontend/jira_connect/subscriptions/components/user_link_spec.js b/spec/frontend/jira_connect/subscriptions/components/user_link_spec.js
index b98a36269a3..2f5e47d1ae4 100644
--- a/spec/frontend/jira_connect/subscriptions/components/user_link_spec.js
+++ b/spec/frontend/jira_connect/subscriptions/components/user_link_spec.js
@@ -7,7 +7,7 @@ jest.mock('~/jira_connect/subscriptions/utils', () => ({
getGitlabSignInURL: jest.fn().mockImplementation((path) => Promise.resolve(path)),
}));
-describe('SubscriptionsList', () => {
+describe('UserLink', () => {
let wrapper;
const createComponent = (propsData = {}, { provide } = {}) => {
@@ -68,24 +68,35 @@ describe('SubscriptionsList', () => {
});
describe('gitlab user link', () => {
- window.gon = { current_username: 'root' };
+ describe.each`
+ current_username | gitlabUserPath | user | expectedUserHandle | expectedUserLink
+ ${'root'} | ${'/root'} | ${{ username: 'test-user' }} | ${'@root'} | ${'/root'}
+ ${'root'} | ${'/root'} | ${undefined} | ${'@root'} | ${'/root'}
+ ${undefined} | ${undefined} | ${{ username: 'test-user' }} | ${'@test-user'} | ${'/test-user'}
+ `(
+ 'when current_username=$current_username, gitlabUserPath=$gitlabUserPath and user=$user',
+ ({ current_username, gitlabUserPath, user, expectedUserHandle, expectedUserLink }) => {
+ beforeEach(() => {
+ window.gon = { current_username, relative_root_url: '' };
- beforeEach(() => {
- createComponent(
- {
- userSignedIn: true,
- hasSubscriptions: true,
- },
- { provide: { gitlabUserPath: '/root' } },
- );
- });
+ createComponent(
+ {
+ userSignedIn: true,
+ hasSubscriptions: true,
+ user,
+ },
+ { provide: { gitlabUserPath } },
+ );
+ });
- it('renders with correct href', () => {
- expect(findGitlabUserLink().attributes('href')).toBe('/root');
- });
+ it(`sets href to ${expectedUserLink}`, () => {
+ expect(findGitlabUserLink().attributes('href')).toBe(expectedUserLink);
+ });
- it('contains GitLab user handle', () => {
- expect(findGitlabUserLink().text()).toBe('@root');
- });
+ it(`renders ${expectedUserHandle} as text`, () => {
+ expect(findGitlabUserLink().text()).toBe(expectedUserHandle);
+ });
+ },
+ );
});
});
diff --git a/spec/frontend/jira_connect/subscriptions/pages/sign_in_spec.js b/spec/frontend/jira_connect/subscriptions/pages/sign_in_spec.js
index 4e3297506f1..175896c4ab0 100644
--- a/spec/frontend/jira_connect/subscriptions/pages/sign_in_spec.js
+++ b/spec/frontend/jira_connect/subscriptions/pages/sign_in_spec.js
@@ -1,26 +1,44 @@
-import { mount } from '@vue/test-utils';
+import { shallowMount } from '@vue/test-utils';
import SignInPage from '~/jira_connect/subscriptions/pages/sign_in.vue';
-import SignInButton from '~/jira_connect/subscriptions/components/sign_in_button.vue';
+import SignInLegacyButton from '~/jira_connect/subscriptions/components/sign_in_legacy_button.vue';
+import SignInOauthButton from '~/jira_connect/subscriptions/components/sign_in_oauth_button.vue';
import SubscriptionsList from '~/jira_connect/subscriptions/components/subscriptions_list.vue';
import createStore from '~/jira_connect/subscriptions/store';
+import { I18N_DEFAULT_SIGN_IN_BUTTON_TEXT } from '../../../../../app/assets/javascripts/jira_connect/subscriptions/constants';
jest.mock('~/jira_connect/subscriptions/utils');
+const mockUsersPath = '/test';
+const defaultProvide = {
+ oauthMetadata: {},
+ usersPath: mockUsersPath,
+};
+
describe('SignInPage', () => {
let wrapper;
let store;
- const findSignInButton = () => wrapper.findComponent(SignInButton);
+ const findSignInLegacyButton = () => wrapper.findComponent(SignInLegacyButton);
+ const findSignInOauthButton = () => wrapper.findComponent(SignInOauthButton);
const findSubscriptionsList = () => wrapper.findComponent(SubscriptionsList);
- const createComponent = ({ provide, props } = {}) => {
+ const createComponent = ({ props, jiraConnectOauthEnabled } = {}) => {
store = createStore();
- wrapper = mount(SignInPage, {
+ wrapper = shallowMount(SignInPage, {
store,
- provide,
+ provide: {
+ ...defaultProvide,
+ glFeatures: {
+ jiraConnectOauth: jiraConnectOauthEnabled,
+ },
+ },
propsData: props,
+ stubs: {
+ SignInLegacyButton,
+ SignInOauthButton,
+ },
});
};
@@ -29,33 +47,74 @@ describe('SignInPage', () => {
});
describe('template', () => {
- const mockUsersPath = '/test';
describe.each`
- scenario | expectSubscriptionsList | signInButtonText
- ${'with subscriptions'} | ${true} | ${SignInPage.i18n.signinButtonTextWithSubscriptions}
- ${'without subscriptions'} | ${false} | ${SignInButton.i18n.defaultButtonText}
- `('$scenario', ({ expectSubscriptionsList, signInButtonText }) => {
- beforeEach(() => {
- createComponent({
- provide: {
- usersPath: mockUsersPath,
- },
- props: {
- hasSubscriptions: expectSubscriptionsList,
- },
+ scenario | hasSubscriptions | signInButtonText
+ ${'with subscriptions'} | ${true} | ${SignInPage.i18n.signInButtonTextWithSubscriptions}
+ ${'without subscriptions'} | ${false} | ${I18N_DEFAULT_SIGN_IN_BUTTON_TEXT}
+ `('$scenario', ({ hasSubscriptions, signInButtonText }) => {
+ describe('when `jiraConnectOauthEnabled` feature flag is disabled', () => {
+ beforeEach(() => {
+ createComponent({
+ jiraConnectOauthEnabled: false,
+ props: {
+ hasSubscriptions,
+ },
+ });
});
- });
- it(`renders sign in button with text ${signInButtonText}`, () => {
- expect(findSignInButton().text()).toMatchInterpolatedText(signInButtonText);
+ it('renders legacy sign in button', () => {
+ const button = findSignInLegacyButton();
+ expect(button.props('usersPath')).toBe(mockUsersPath);
+ expect(button.text()).toMatchInterpolatedText(signInButtonText);
+ });
});
- it('renders sign in button with `usersPath` prop', () => {
- expect(findSignInButton().props('usersPath')).toBe(mockUsersPath);
+ describe('when `jiraConnectOauthEnabled` feature flag is enabled', () => {
+ beforeEach(() => {
+ createComponent({
+ jiraConnectOauthEnabled: true,
+ props: {
+ hasSubscriptions,
+ },
+ });
+ });
+
+ describe('oauth sign in button', () => {
+ it('renders oauth sign in button', () => {
+ const button = findSignInOauthButton();
+ expect(button.text()).toMatchInterpolatedText(signInButtonText);
+ });
+
+ describe('when button emits `sign-in` event', () => {
+ it('emits `sign-in-oauth` event', () => {
+ const button = findSignInOauthButton();
+
+ const mockUser = { name: 'test' };
+ button.vm.$emit('sign-in', mockUser);
+
+ expect(wrapper.emitted('sign-in-oauth')[0]).toEqual([mockUser]);
+ });
+ });
+
+ describe('when button emits `error` event', () => {
+ it('emits `error` event', () => {
+ const button = findSignInOauthButton();
+ button.vm.$emit('error');
+
+ expect(wrapper.emitted('error')).toBeTruthy();
+ });
+ });
+ });
});
- it(`${expectSubscriptionsList ? 'renders' : 'does not render'} subscriptions list`, () => {
- expect(findSubscriptionsList().exists()).toBe(expectSubscriptionsList);
+ it(`${hasSubscriptions ? 'renders' : 'does not render'} subscriptions list`, () => {
+ createComponent({
+ props: {
+ hasSubscriptions,
+ },
+ });
+
+ expect(findSubscriptionsList().exists()).toBe(hasSubscriptions);
});
});
});
diff --git a/spec/frontend/jira_connect/subscriptions/pkce_spec.js b/spec/frontend/jira_connect/subscriptions/pkce_spec.js
new file mode 100644
index 00000000000..4ee88059b7a
--- /dev/null
+++ b/spec/frontend/jira_connect/subscriptions/pkce_spec.js
@@ -0,0 +1,48 @@
+import crypto from 'crypto';
+import { TextEncoder, TextDecoder } from 'util';
+
+import { createCodeVerifier, createCodeChallenge } from '~/jira_connect/subscriptions/pkce';
+
+global.TextEncoder = TextEncoder;
+global.TextDecoder = TextDecoder;
+
+describe('pkce', () => {
+ beforeAll(() => {
+ Object.defineProperty(global.self, 'crypto', {
+ value: {
+ getRandomValues: (arr) => crypto.randomBytes(arr.length),
+ subtle: {
+ digest: jest.fn().mockResolvedValue(new ArrayBuffer(1)),
+ },
+ },
+ });
+ });
+
+ describe('createCodeVerifier', () => {
+ it('calls `window.crypto.getRandomValues`', () => {
+ window.crypto.getRandomValues = jest.fn();
+ createCodeVerifier();
+
+ expect(window.crypto.getRandomValues).toHaveBeenCalled();
+ });
+
+ it(`returns a string with 128 characters`, () => {
+ const codeVerifier = createCodeVerifier();
+ expect(codeVerifier).toHaveLength(128);
+ });
+ });
+
+ describe('createCodeChallenge', () => {
+ it('calls `window.crypto.subtle.digest` with correct arguments', async () => {
+ await createCodeChallenge('1234');
+
+ expect(window.crypto.subtle.digest).toHaveBeenCalledWith('SHA-256', expect.anything());
+ });
+
+ it('returns base64 URL-encoded string', async () => {
+ const codeChallenge = await createCodeChallenge('1234');
+
+ expect(codeChallenge).toBe('AA');
+ });
+ });
+});
diff --git a/spec/frontend/jobs/components/job_app_spec.js b/spec/frontend/jobs/components/job_app_spec.js
index d4e1e711777..06ebcd7f134 100644
--- a/spec/frontend/jobs/components/job_app_spec.js
+++ b/spec/frontend/jobs/components/job_app_spec.js
@@ -34,7 +34,6 @@ describe('Job App', () => {
const props = {
artifactHelpUrl: 'help/artifact',
deploymentHelpUrl: 'help/deployment',
- codeQualityHelpPath: '/help/code_quality',
runnerSettingsUrl: 'settings/ci-cd/runners',
terminalPath: 'jobs/123/terminal',
projectPath: 'user-name/project-name',
diff --git a/spec/frontend/jobs/components/job_log_controllers_spec.js b/spec/frontend/jobs/components/job_log_controllers_spec.js
index 226322a2951..cd3ee734466 100644
--- a/spec/frontend/jobs/components/job_log_controllers_spec.js
+++ b/spec/frontend/jobs/components/job_log_controllers_spec.js
@@ -8,7 +8,6 @@ describe('Job log controllers', () => {
afterEach(() => {
if (wrapper?.destroy) {
wrapper.destroy();
- wrapper = null;
}
});
@@ -34,7 +33,6 @@ describe('Job log controllers', () => {
const findTruncatedInfo = () => wrapper.find('[data-testid="log-truncated-info"]');
const findRawLink = () => wrapper.find('[data-testid="raw-link"]');
const findRawLinkController = () => wrapper.find('[data-testid="job-raw-link-controller"]');
- const findEraseLink = () => wrapper.find('[data-testid="job-log-erase-link"]');
const findScrollTop = () => wrapper.find('[data-testid="job-controller-scroll-top"]');
const findScrollBottom = () => wrapper.find('[data-testid="job-controller-scroll-bottom"]');
@@ -76,28 +74,6 @@ describe('Job log controllers', () => {
expect(findRawLinkController().exists()).toBe(false);
});
});
-
- describe('when is erasable', () => {
- beforeEach(() => {
- createWrapper();
- });
-
- it('renders erase job link', () => {
- expect(findEraseLink().exists()).toBe(true);
- });
- });
-
- describe('when it is not erasable', () => {
- beforeEach(() => {
- createWrapper({
- erasePath: null,
- });
- });
-
- it('does not render erase button', () => {
- expect(findEraseLink().exists()).toBe(false);
- });
- });
});
describe('scroll buttons', () => {
diff --git a/spec/frontend/jobs/components/job_sidebar_retry_button_spec.js b/spec/frontend/jobs/components/job_sidebar_retry_button_spec.js
index 6914b8d4fa1..ad72b9be261 100644
--- a/spec/frontend/jobs/components/job_sidebar_retry_button_spec.js
+++ b/spec/frontend/jobs/components/job_sidebar_retry_button_spec.js
@@ -1,5 +1,4 @@
-import { GlButton, GlLink } from '@gitlab/ui';
-import { shallowMount } from '@vue/test-utils';
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import JobsSidebarRetryButton from '~/jobs/components/job_sidebar_retry_button.vue';
import createStore from '~/jobs/store';
import job from '../mock_data';
@@ -9,12 +8,12 @@ describe('Job Sidebar Retry Button', () => {
let wrapper;
const forwardDeploymentFailure = 'forward_deployment_failure';
- const findRetryButton = () => wrapper.find(GlButton);
- const findRetryLink = () => wrapper.find(GlLink);
+ const findRetryButton = () => wrapper.findByTestId('retry-job-button');
+ const findRetryLink = () => wrapper.findByTestId('retry-job-link');
const createWrapper = ({ props = {} } = {}) => {
store = createStore();
- wrapper = shallowMount(JobsSidebarRetryButton, {
+ wrapper = shallowMountExtended(JobsSidebarRetryButton, {
propsData: {
href: job.retry_path,
modalId: 'modal-id',
@@ -27,7 +26,6 @@ describe('Job Sidebar Retry Button', () => {
afterEach(() => {
if (wrapper) {
wrapper.destroy();
- wrapper = null;
}
});
@@ -44,7 +42,6 @@ describe('Job Sidebar Retry Button', () => {
expect(findRetryButton().exists()).toBe(buttonExists);
expect(findRetryLink().exists()).toBe(linkExists);
- expect(wrapper.text()).toMatch('Retry');
},
);
@@ -55,6 +52,7 @@ describe('Job Sidebar Retry Button', () => {
expect(findRetryButton().attributes()).toMatchObject({
category: 'primary',
variant: 'confirm',
+ icon: 'retry',
});
});
});
@@ -64,6 +62,7 @@ describe('Job Sidebar Retry Button', () => {
expect(findRetryLink().attributes()).toMatchObject({
'data-method': 'post',
href: job.retry_path,
+ icon: 'retry',
});
});
});
diff --git a/spec/frontend/jobs/components/sidebar_spec.js b/spec/frontend/jobs/components/sidebar_spec.js
index 6e327725627..39c71986ce4 100644
--- a/spec/frontend/jobs/components/sidebar_spec.js
+++ b/spec/frontend/jobs/components/sidebar_spec.js
@@ -21,25 +21,54 @@ describe('Sidebar details block', () => {
const findNewIssueButton = () => wrapper.findByTestId('job-new-issue');
const findRetryButton = () => wrapper.find(JobRetryButton);
const findTerminalLink = () => wrapper.findByTestId('terminal-link');
+ const findEraseLink = () => wrapper.findByTestId('job-log-erase-link');
- const createWrapper = ({ props = {} } = {}) => {
+ const createWrapper = (props) => {
store = createStore();
store.state.job = job;
wrapper = extendedWrapper(
shallowMount(Sidebar, {
- ...props,
+ propsData: {
+ ...props,
+ },
+
store,
}),
);
};
afterEach(() => {
- if (wrapper) {
- wrapper.destroy();
- wrapper = null;
- }
+ wrapper.destroy();
+ });
+
+ describe('when job log is erasable', () => {
+ const path = '/root/ci-project/-/jobs/1447/erase';
+
+ beforeEach(() => {
+ createWrapper({
+ erasePath: path,
+ });
+ });
+
+ it('renders erase job link', () => {
+ expect(findEraseLink().exists()).toBe(true);
+ });
+
+ it('erase job link has correct path', () => {
+ expect(findEraseLink().attributes('href')).toBe(path);
+ });
+ });
+
+ describe('when job log is not erasable', () => {
+ beforeEach(() => {
+ createWrapper();
+ });
+
+ it('does not render erase button', () => {
+ expect(findEraseLink().exists()).toBe(false);
+ });
});
describe('when there is no retry path retry', () => {
@@ -86,7 +115,7 @@ describe('Sidebar details block', () => {
});
it('should render link to cancel job', () => {
- expect(findCancelButton().text()).toMatch('Cancel');
+ expect(findCancelButton().props('icon')).toBe('cancel');
expect(findCancelButton().attributes('href')).toBe(job.cancel_path);
});
});
diff --git a/spec/frontend/jobs/components/stages_dropdown_spec.js b/spec/frontend/jobs/components/stages_dropdown_spec.js
index b0e95a2d5b6..f638213ef0c 100644
--- a/spec/frontend/jobs/components/stages_dropdown_spec.js
+++ b/spec/frontend/jobs/components/stages_dropdown_spec.js
@@ -1,10 +1,12 @@
-import { GlDropdown, GlDropdownItem } from '@gitlab/ui';
+import { GlDropdown, GlDropdownItem, GlLink, GlSprintf } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
-import { trimText } from 'helpers/text_helper';
+import Mousetrap from 'mousetrap';
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import StagesDropdown from '~/jobs/components/stages_dropdown.vue';
import CiIcon from '~/vue_shared/components/ci_icon.vue';
+import * as copyToClipboard from '~/behaviors/copy_to_clipboard';
import {
+ mockPipelineWithoutRef,
mockPipelineWithoutMR,
mockPipelineWithAttachedMR,
mockPipelineDetached,
@@ -18,20 +20,19 @@ describe('Stages Dropdown', () => {
const findStageItem = (index) => wrapper.findAllComponents(GlDropdownItem).at(index);
const findPipelineInfoText = () => wrapper.findByTestId('pipeline-info').text();
- const findPipelinePath = () => wrapper.findByTestId('pipeline-path').attributes('href');
- const findMRLinkPath = () => wrapper.findByTestId('mr-link').attributes('href');
- const findCopySourceBranchBtn = () => wrapper.findByTestId('copy-source-ref-link');
- const findSourceBranchLinkPath = () =>
- wrapper.findByTestId('source-branch-link').attributes('href');
- const findTargetBranchLinkPath = () =>
- wrapper.findByTestId('target-branch-link').attributes('href');
const createComponent = (props) => {
wrapper = extendedWrapper(
shallowMount(StagesDropdown, {
propsData: {
+ stages: [],
+ selectedStage: 'deploy',
...props,
},
+ stubs: {
+ GlSprintf,
+ GlLink,
+ },
}),
);
};
@@ -45,7 +46,6 @@ describe('Stages Dropdown', () => {
createComponent({
pipeline: mockPipelineWithoutMR,
stages: [{ name: 'build' }, { name: 'test' }],
- selectedStage: 'deploy',
});
});
@@ -53,10 +53,6 @@ describe('Stages Dropdown', () => {
expect(findStatus().exists()).toBe(true);
});
- it('renders pipeline link', () => {
- expect(findPipelinePath()).toBe('pipeline/28029444');
- });
-
it('renders dropdown with stages', () => {
expect(findStageItem(0).text()).toBe('build');
});
@@ -64,84 +60,133 @@ describe('Stages Dropdown', () => {
it('rendes selected stage', () => {
expect(findSelectedStageText()).toBe('deploy');
});
-
- it(`renders the pipeline info text like "Pipeline #123 for source_branch"`, () => {
- const expected = `Pipeline #${mockPipelineWithoutMR.id} for ${mockPipelineWithoutMR.ref.name}`;
- const actual = trimText(findPipelineInfoText());
-
- expect(actual).toBe(expected);
- });
-
- it(`renders the source ref copy button`, () => {
- expect(findCopySourceBranchBtn().exists()).toBe(true);
- });
});
- describe('with an "attached" merge request pipeline', () => {
- beforeEach(() => {
- createComponent({
- pipeline: mockPipelineWithAttachedMR,
- stages: [],
- selectedStage: 'deploy',
+ describe('pipelineInfo', () => {
+ const allElements = [
+ 'pipeline-path',
+ 'mr-link',
+ 'source-ref-link',
+ 'copy-source-ref-link',
+ 'source-branch-link',
+ 'copy-source-branch-link',
+ 'target-branch-link',
+ 'copy-target-branch-link',
+ ];
+ describe.each([
+ [
+ 'does not have a ref',
+ {
+ pipeline: mockPipelineWithoutRef,
+ text: `Pipeline #${mockPipelineWithoutRef.id}`,
+ foundElements: [
+ { testId: 'pipeline-path', props: [{ href: mockPipelineWithoutRef.path }] },
+ ],
+ },
+ ],
+ [
+ 'hasRef but not triggered by MR',
+ {
+ pipeline: mockPipelineWithoutMR,
+ text: `Pipeline #${mockPipelineWithoutMR.id} for ${mockPipelineWithoutMR.ref.name}`,
+ foundElements: [
+ { testId: 'pipeline-path', props: [{ href: mockPipelineWithoutMR.path }] },
+ { testId: 'source-ref-link', props: [{ href: mockPipelineWithoutMR.ref.path }] },
+ { testId: 'copy-source-ref-link', props: [{ text: mockPipelineWithoutMR.ref.name }] },
+ ],
+ },
+ ],
+ [
+ 'hasRef and MR but not MR pipeline',
+ {
+ pipeline: mockPipelineDetached,
+ text: `Pipeline #${mockPipelineDetached.id} for !${mockPipelineDetached.merge_request.iid} with ${mockPipelineDetached.merge_request.source_branch}`,
+ foundElements: [
+ { testId: 'pipeline-path', props: [{ href: mockPipelineDetached.path }] },
+ { testId: 'mr-link', props: [{ href: mockPipelineDetached.merge_request.path }] },
+ {
+ testId: 'source-branch-link',
+ props: [{ href: mockPipelineDetached.merge_request.source_branch_path }],
+ },
+ {
+ testId: 'copy-source-branch-link',
+ props: [{ text: mockPipelineDetached.merge_request.source_branch }],
+ },
+ ],
+ },
+ ],
+ [
+ 'hasRef and MR and MR pipeline',
+ {
+ pipeline: mockPipelineWithAttachedMR,
+ text: `Pipeline #${mockPipelineWithAttachedMR.id} for !${mockPipelineWithAttachedMR.merge_request.iid} with ${mockPipelineWithAttachedMR.merge_request.source_branch} into ${mockPipelineWithAttachedMR.merge_request.target_branch}`,
+ foundElements: [
+ { testId: 'pipeline-path', props: [{ href: mockPipelineWithAttachedMR.path }] },
+ { testId: 'mr-link', props: [{ href: mockPipelineWithAttachedMR.merge_request.path }] },
+ {
+ testId: 'source-branch-link',
+ props: [{ href: mockPipelineWithAttachedMR.merge_request.source_branch_path }],
+ },
+ {
+ testId: 'copy-source-branch-link',
+ props: [{ text: mockPipelineWithAttachedMR.merge_request.source_branch }],
+ },
+ {
+ testId: 'target-branch-link',
+ props: [{ href: mockPipelineWithAttachedMR.merge_request.target_branch_path }],
+ },
+ {
+ testId: 'copy-target-branch-link',
+ props: [{ text: mockPipelineWithAttachedMR.merge_request.target_branch }],
+ },
+ ],
+ },
+ ],
+ ])('%s', (_, { pipeline, text, foundElements }) => {
+ beforeEach(() => {
+ createComponent({
+ pipeline,
+ });
});
- });
- it(`renders the pipeline info text like "Pipeline #123 for !456 with source_branch into target_branch"`, () => {
- const expected = `Pipeline #${mockPipelineWithAttachedMR.id} for !${mockPipelineWithAttachedMR.merge_request.iid} with ${mockPipelineWithAttachedMR.merge_request.source_branch} into ${mockPipelineWithAttachedMR.merge_request.target_branch}`;
- const actual = trimText(findPipelineInfoText());
-
- expect(actual).toBe(expected);
- });
-
- it(`renders the correct merge request link`, () => {
- expect(findMRLinkPath()).toBe(mockPipelineWithAttachedMR.merge_request.path);
- });
-
- it(`renders the correct source branch link`, () => {
- expect(findSourceBranchLinkPath()).toBe(
- mockPipelineWithAttachedMR.merge_request.source_branch_path,
- );
- });
-
- it(`renders the correct target branch link`, () => {
- expect(findTargetBranchLinkPath()).toBe(
- mockPipelineWithAttachedMR.merge_request.target_branch_path,
- );
- });
-
- it(`renders the source ref copy button`, () => {
- expect(findCopySourceBranchBtn().exists()).toBe(true);
- });
- });
-
- describe('with a detached merge request pipeline', () => {
- beforeEach(() => {
- createComponent({
- pipeline: mockPipelineDetached,
- stages: [],
- selectedStage: 'deploy',
+ it('should render the text', () => {
+ expect(findPipelineInfoText()).toMatchInterpolatedText(text);
});
- });
- it(`renders the pipeline info like "Pipeline #123 for !456 with source_branch"`, () => {
- const expected = `Pipeline #${mockPipelineDetached.id} for !${mockPipelineDetached.merge_request.iid} with ${mockPipelineDetached.merge_request.source_branch}`;
- const actual = trimText(findPipelineInfoText());
+ it('should find components with props', () => {
+ foundElements.forEach((element) => {
+ element.props.forEach((prop) => {
+ const key = Object.keys(prop)[0];
+ expect(wrapper.findByTestId(element.testId).attributes(key)).toBe(prop[key]);
+ });
+ });
+ });
- expect(actual).toBe(expected);
+ it('should not find components', () => {
+ const foundTestIds = foundElements.map((element) => element.testId);
+ allElements
+ .filter((testId) => !foundTestIds.includes(testId))
+ .forEach((testId) => {
+ expect(wrapper.findByTestId(testId).exists()).toBe(false);
+ });
+ });
});
+ });
- it(`renders the correct merge request link`, () => {
- expect(findMRLinkPath()).toBe(mockPipelineDetached.merge_request.path);
- });
+ describe('mousetrap', () => {
+ it.each([
+ ['copy-source-ref-link', mockPipelineWithoutMR],
+ ['copy-source-branch-link', mockPipelineWithAttachedMR],
+ ])(
+ 'calls clickCopyToClipboardButton with `%s` button when `b` is pressed',
+ (button, pipeline) => {
+ const copyToClipboardMock = jest.spyOn(copyToClipboard, 'clickCopyToClipboardButton');
+ createComponent({ pipeline });
- it(`renders the correct source branch link`, () => {
- expect(findSourceBranchLinkPath()).toBe(
- mockPipelineDetached.merge_request.source_branch_path,
- );
- });
+ Mousetrap.trigger('b');
- it(`renders the source ref copy button`, () => {
- expect(findCopySourceBranchBtn().exists()).toBe(true);
- });
+ expect(copyToClipboardMock).toHaveBeenCalledWith(wrapper.findByTestId(button).element);
+ },
+ );
});
});
diff --git a/spec/frontend/jobs/components/table/graphql/cache_config_spec.js b/spec/frontend/jobs/components/table/graphql/cache_config_spec.js
new file mode 100644
index 00000000000..ac79186cb46
--- /dev/null
+++ b/spec/frontend/jobs/components/table/graphql/cache_config_spec.js
@@ -0,0 +1,67 @@
+import cacheConfig from '~/jobs/components/table/graphql/cache_config';
+import {
+ CIJobConnectionExistingCache,
+ CIJobConnectionIncomingCache,
+ CIJobConnectionIncomingCacheRunningStatus,
+} from '../../../mock_data';
+
+const firstLoadArgs = { first: 3, statuses: 'PENDING' };
+const runningArgs = { first: 3, statuses: 'RUNNING' };
+
+describe('jobs/components/table/graphql/cache_config', () => {
+ describe('when fetching data with the same statuses', () => {
+ it('should contain cache nodes and a status when merging caches on first load', () => {
+ const res = cacheConfig.typePolicies.CiJobConnection.merge({}, CIJobConnectionIncomingCache, {
+ args: firstLoadArgs,
+ });
+
+ expect(res.nodes).toHaveLength(CIJobConnectionIncomingCache.nodes.length);
+ expect(res.statuses).toBe('PENDING');
+ });
+
+ it('should add to existing caches when merging caches after first load', () => {
+ const res = cacheConfig.typePolicies.CiJobConnection.merge(
+ CIJobConnectionExistingCache,
+ CIJobConnectionIncomingCache,
+ {
+ args: firstLoadArgs,
+ },
+ );
+
+ expect(res.nodes).toHaveLength(
+ CIJobConnectionIncomingCache.nodes.length + CIJobConnectionExistingCache.nodes.length,
+ );
+ });
+
+ it('should contain the pageInfo key as part of the result', () => {
+ const res = cacheConfig.typePolicies.CiJobConnection.merge({}, CIJobConnectionIncomingCache, {
+ args: firstLoadArgs,
+ });
+
+ expect(res.pageInfo).toEqual(
+ expect.objectContaining({
+ __typename: 'PageInfo',
+ endCursor: 'eyJpZCI6IjIwNTEifQ',
+ hasNextPage: true,
+ hasPreviousPage: false,
+ startCursor: 'eyJpZCI6IjIxNzMifQ',
+ }),
+ );
+ });
+ });
+
+ describe('when fetching data with different statuses', () => {
+ it('should reset cache when a cache already exists', () => {
+ const res = cacheConfig.typePolicies.CiJobConnection.merge(
+ CIJobConnectionExistingCache,
+ CIJobConnectionIncomingCacheRunningStatus,
+ {
+ args: runningArgs,
+ },
+ );
+
+ expect(res.nodes).not.toEqual(CIJobConnectionExistingCache.nodes);
+ expect(res.nodes).toHaveLength(CIJobConnectionIncomingCacheRunningStatus.nodes.length);
+ });
+ });
+});
diff --git a/spec/frontend/jobs/components/table/job_table_app_spec.js b/spec/frontend/jobs/components/table/job_table_app_spec.js
index 5ccd38af735..4d51624dfff 100644
--- a/spec/frontend/jobs/components/table/job_table_app_spec.js
+++ b/spec/frontend/jobs/components/table/job_table_app_spec.js
@@ -1,4 +1,4 @@
-import { GlSkeletonLoader, GlAlert, GlEmptyState, GlPagination } from '@gitlab/ui';
+import { GlSkeletonLoader, GlAlert, GlEmptyState, GlIntersectionObserver } from '@gitlab/ui';
import { mount, shallowMount } from '@vue/test-utils';
import Vue from 'vue';
import VueApollo from 'vue-apollo';
@@ -8,12 +8,7 @@ import getJobsQuery from '~/jobs/components/table/graphql/queries/get_jobs.query
import JobsTable from '~/jobs/components/table/jobs_table.vue';
import JobsTableApp from '~/jobs/components/table/jobs_table_app.vue';
import JobsTableTabs from '~/jobs/components/table/jobs_table_tabs.vue';
-import {
- mockJobsQueryResponse,
- mockJobsQueryEmptyResponse,
- mockJobsQueryResponseLastPage,
- mockJobsQueryResponseFirstPage,
-} from '../../mock_data';
+import { mockJobsQueryResponse, mockJobsQueryEmptyResponse } from '../../mock_data';
const projectPath = 'gitlab-org/gitlab';
Vue.use(VueApollo);
@@ -30,10 +25,9 @@ describe('Job table app', () => {
const findTabs = () => wrapper.findComponent(JobsTableTabs);
const findAlert = () => wrapper.findComponent(GlAlert);
const findEmptyState = () => wrapper.findComponent(GlEmptyState);
- const findPagination = () => wrapper.findComponent(GlPagination);
- const findPrevious = () => findPagination().findAll('.page-item').at(0);
- const findNext = () => findPagination().findAll('.page-item').at(1);
+ const triggerInfiniteScroll = () =>
+ wrapper.findComponent(GlIntersectionObserver).vm.$emit('appear');
const createMockApolloProvider = (handler) => {
const requestHandlers = [[getJobsQuery, handler]];
@@ -53,7 +47,7 @@ describe('Job table app', () => {
};
},
provide: {
- projectPath,
+ fullPath: projectPath,
},
apolloProvider: createMockApolloProvider(handler),
});
@@ -69,7 +63,6 @@ describe('Job table app', () => {
expect(findSkeletonLoader().exists()).toBe(true);
expect(findTable().exists()).toBe(false);
- expect(findPagination().exists()).toBe(false);
});
});
@@ -83,7 +76,6 @@ describe('Job table app', () => {
it('should display the jobs table with data', () => {
expect(findTable().exists()).toBe(true);
expect(findSkeletonLoader().exists()).toBe(false);
- expect(findPagination().exists()).toBe(true);
});
it('should refetch jobs query on fetchJobsByStatus event', async () => {
@@ -95,41 +87,24 @@ describe('Job table app', () => {
expect(wrapper.vm.$apollo.queries.jobs.refetch).toHaveBeenCalledTimes(1);
});
- });
- describe('pagination', () => {
- it('should disable the next page button on the last page', async () => {
- createComponent({
- handler: jest.fn().mockResolvedValue(mockJobsQueryResponseLastPage),
- mountFn: mount,
- data: {
- pagination: { currentPage: 3 },
- },
+ describe('when infinite scrolling is triggered', () => {
+ beforeEach(() => {
+ triggerInfiniteScroll();
});
- await waitForPromises();
-
- expect(findPrevious().exists()).toBe(true);
- expect(findNext().exists()).toBe(true);
- expect(findNext().classes('disabled')).toBe(true);
- });
-
- it('should disable the previous page button on the first page', async () => {
- createComponent({
- handler: jest.fn().mockResolvedValue(mockJobsQueryResponseFirstPage),
- mountFn: mount,
- data: {
- pagination: {
- currentPage: 1,
- },
- },
+ it('does not display a skeleton loader', () => {
+ expect(findSkeletonLoader().exists()).toBe(false);
});
- await waitForPromises();
+ it('handles infinite scrolling by calling fetch more', async () => {
+ await waitForPromises();
- expect(findPrevious().exists()).toBe(true);
- expect(findPrevious().classes('disabled')).toBe(true);
- expect(findNext().exists()).toBe(true);
+ expect(successHandler).toHaveBeenCalledWith({
+ after: 'eyJpZCI6IjIzMTcifQ',
+ fullPath: 'gitlab-org/gitlab',
+ });
+ });
});
});
diff --git a/spec/frontend/jobs/mock_data.js b/spec/frontend/jobs/mock_data.js
index 2be78bac8a9..73b9df1853d 100644
--- a/spec/frontend/jobs/mock_data.js
+++ b/spec/frontend/jobs/mock_data.js
@@ -1214,6 +1214,11 @@ export const mockPipelineWithoutMR = {
},
};
+export const mockPipelineWithoutRef = {
+ ...mockPipelineWithoutMR,
+ ref: null,
+};
+
export const mockPipelineWithAttachedMR = {
id: 28029444,
details: {
@@ -1579,44 +1584,6 @@ export const mockJobsQueryResponse = {
},
};
-export const mockJobsQueryResponseLastPage = {
- data: {
- project: {
- id: '1',
- jobs: {
- ...mockJobsQueryResponse.data.project.jobs,
- pageInfo: {
- endCursor: 'eyJpZCI6IjIzMTcifQ',
- hasNextPage: false,
- hasPreviousPage: true,
- startCursor: 'eyJpZCI6IjIzMzYifQ',
- __typename: 'PageInfo',
- },
- },
- __typename: 'Project',
- },
- },
-};
-
-export const mockJobsQueryResponseFirstPage = {
- data: {
- project: {
- id: '1',
- jobs: {
- ...mockJobsQueryResponse.data.project.jobs,
- pageInfo: {
- endCursor: 'eyJpZCI6IjIzMTcifQ',
- hasNextPage: true,
- hasPreviousPage: false,
- startCursor: 'eyJpZCI6IjIzMzYifQ',
- __typename: 'PageInfo',
- },
- },
- __typename: 'Project',
- },
- },
-};
-
export const mockJobsQueryEmptyResponse = {
data: {
project: {
@@ -1910,3 +1877,44 @@ export const cannotPlayScheduledJob = {
__typename: 'JobPermissions',
},
};
+
+export const CIJobConnectionIncomingCache = {
+ __typename: 'CiJobConnection',
+ pageInfo: {
+ __typename: 'PageInfo',
+ endCursor: 'eyJpZCI6IjIwNTEifQ',
+ hasNextPage: true,
+ hasPreviousPage: false,
+ startCursor: 'eyJpZCI6IjIxNzMifQ',
+ },
+ nodes: [
+ { __ref: 'CiJob:gid://gitlab/Ci::Build/2057' },
+ { __ref: 'CiJob:gid://gitlab/Ci::Build/2056' },
+ { __ref: 'CiJob:gid://gitlab/Ci::Build/2051' },
+ ],
+};
+
+export const CIJobConnectionIncomingCacheRunningStatus = {
+ __typename: 'CiJobConnection',
+ pageInfo: {
+ __typename: 'PageInfo',
+ endCursor: 'eyJpZCI6IjIwNTEifQ',
+ hasNextPage: true,
+ hasPreviousPage: false,
+ startCursor: 'eyJpZCI6IjIxNzMifQ',
+ },
+ nodes: [
+ { __ref: 'CiJob:gid://gitlab/Ci::Build/2000' },
+ { __ref: 'CiJob:gid://gitlab/Ci::Build/2001' },
+ { __ref: 'CiJob:gid://gitlab/Ci::Build/2002' },
+ ],
+};
+
+export const CIJobConnectionExistingCache = {
+ nodes: [
+ { __ref: 'CiJob:gid://gitlab/Ci::Build/2057' },
+ { __ref: 'CiJob:gid://gitlab/Ci::Build/2056' },
+ { __ref: 'CiJob:gid://gitlab/Ci::Build/2051' },
+ ],
+ statuses: 'PENDING',
+};
diff --git a/spec/frontend/lib/utils/array_utility_spec.js b/spec/frontend/lib/utils/array_utility_spec.js
index b95286ff254..64ddd400114 100644
--- a/spec/frontend/lib/utils/array_utility_spec.js
+++ b/spec/frontend/lib/utils/array_utility_spec.js
@@ -29,4 +29,17 @@ describe('array_utility', () => {
},
);
});
+
+ describe('getDuplicateItemsFromArray', () => {
+ it.each`
+ array | result
+ ${[]} | ${[]}
+ ${[1, 2, 2, 3, 3, 4]} | ${[2, 3]}
+ ${[1, 2, 3, 2, 3, 4]} | ${[2, 3]}
+ ${['foo', 'bar', 'bar', 'foo', 'baz']} | ${['bar', 'foo']}
+ ${['foo', 'foo', 'bar', 'foo', 'bar']} | ${['foo', 'bar']}
+ `('given $array will return $result', ({ array, result }) => {
+ expect(arrayUtils.getDuplicateItemsFromArray(array)).toEqual(result);
+ });
+ });
});
diff --git a/spec/frontend/lib/utils/common_utils_spec.js b/spec/frontend/lib/utils/common_utils_spec.js
index 3fea08d5512..0be0bf89210 100644
--- a/spec/frontend/lib/utils/common_utils_spec.js
+++ b/spec/frontend/lib/utils/common_utils_spec.js
@@ -51,31 +51,6 @@ describe('common_utils', () => {
});
});
- describe('parseUrl', () => {
- it('returns an anchor tag with url', () => {
- expect(commonUtils.parseUrl('/some/absolute/url').pathname).toContain('some/absolute/url');
- });
-
- it('url is escaped', () => {
- // IE11 will return a relative pathname while other browsers will return a full pathname.
- // parseUrl uses an anchor element for parsing an url. With relative urls, the anchor
- // element will create an absolute url relative to the current execution context.
- // The JavaScript test suite is executed at '/' which will lead to an absolute url
- // starting with '/'.
- expect(commonUtils.parseUrl('" test="asf"').pathname).toContain('/%22%20test=%22asf%22');
- });
- });
-
- describe('parseUrlPathname', () => {
- it('returns an absolute url when given an absolute url', () => {
- expect(commonUtils.parseUrlPathname('/some/absolute/url')).toEqual('/some/absolute/url');
- });
-
- it('returns an absolute url when given a relative url', () => {
- expect(commonUtils.parseUrlPathname('some/relative/url')).toEqual('/some/relative/url');
- });
- });
-
describe('handleLocationHash', () => {
beforeEach(() => {
jest.spyOn(window.document, 'getElementById');
diff --git a/spec/frontend/lib/utils/ignore_while_pending_spec.js b/spec/frontend/lib/utils/ignore_while_pending_spec.js
new file mode 100644
index 00000000000..b68ba936dde
--- /dev/null
+++ b/spec/frontend/lib/utils/ignore_while_pending_spec.js
@@ -0,0 +1,136 @@
+import waitForPromises from 'helpers/wait_for_promises';
+import { ignoreWhilePending } from '~/lib/utils/ignore_while_pending';
+
+const TEST_ARGS = [123, { foo: 'bar' }];
+
+describe('~/lib/utils/ignore_while_pending', () => {
+ let spyResolve;
+ let spyReject;
+ let spy;
+ let subject;
+
+ beforeEach(() => {
+ spy = jest.fn().mockImplementation(
+ // NOTE: We can't pass an arrow function here...
+ function foo() {
+ return new Promise((resolve, reject) => {
+ spyResolve = resolve;
+ spyReject = reject;
+ });
+ },
+ );
+ });
+
+ describe('with non-instance method', () => {
+ beforeEach(() => {
+ subject = ignoreWhilePending(spy);
+ });
+
+ it('while pending, will ignore subsequent calls', () => {
+ subject(...TEST_ARGS);
+ subject();
+ subject();
+ subject();
+
+ expect(spy).toHaveBeenCalledTimes(1);
+ expect(spy).toHaveBeenCalledWith(...TEST_ARGS);
+ });
+
+ it.each`
+ desc | act
+ ${'when resolved'} | ${() => spyResolve()}
+ ${'when rejected'} | ${() => spyReject(new Error('foo'))}
+ `('$desc, can be triggered again', async ({ act }) => {
+ // We need the empty catch(), since we are testing rejecting the promise,
+ // which would otherwise cause the test to fail.
+ subject(...TEST_ARGS).catch(() => {});
+ subject();
+ subject();
+ subject();
+
+ act();
+ // We need waitForPromises, so that the underlying finally() runs.
+ await waitForPromises();
+
+ subject({ again: 'foo' });
+
+ expect(spy).toHaveBeenCalledTimes(2);
+ expect(spy).toHaveBeenCalledWith(...TEST_ARGS);
+ expect(spy).toHaveBeenCalledWith({ again: 'foo' });
+ });
+
+ it('while pending, returns empty resolutions for ignored calls', async () => {
+ subject(...TEST_ARGS);
+
+ await expect(subject(...TEST_ARGS)).resolves.toBeUndefined();
+ await expect(subject(...TEST_ARGS)).resolves.toBeUndefined();
+ });
+
+ it('when resolved, returns resolution for origin call', async () => {
+ const resolveValue = { original: 1 };
+ const result = subject(...TEST_ARGS);
+
+ spyResolve(resolveValue);
+
+ await expect(result).resolves.toEqual(resolveValue);
+ });
+
+ it('when rejected, returns rejection for original call', async () => {
+ const rejectedErr = new Error('original');
+ const result = subject(...TEST_ARGS);
+
+ spyReject(rejectedErr);
+
+ await expect(result).rejects.toEqual(rejectedErr);
+ });
+ });
+
+ describe('with instance method', () => {
+ let instance1;
+ let instance2;
+
+ beforeEach(() => {
+ // Let's capture the "this" for tests
+ subject = ignoreWhilePending(function instanceMethod(...args) {
+ return spy(this, ...args);
+ });
+
+ instance1 = {};
+ instance2 = {};
+ });
+
+ it('will not ignore calls across instances', () => {
+ subject.call(instance1, { context: 1 });
+ subject.call(instance1, {});
+ subject.call(instance1, {});
+ subject.call(instance2, { context: 2 });
+ subject.call(instance2, {});
+
+ expect(spy.mock.calls).toEqual([
+ [instance1, { context: 1 }],
+ [instance2, { context: 2 }],
+ ]);
+ });
+
+ it('resolving one instance does not resolve other instances', async () => {
+ subject.call(instance1, { context: 1 });
+
+ // We need to save off spyResolve so it's not overwritten by next call
+ const instance1Resolve = spyResolve;
+
+ subject.call(instance2, { context: 2 });
+
+ instance1Resolve();
+ await waitForPromises();
+
+ subject.call(instance1, { context: 1 });
+ subject.call(instance2, { context: 2 });
+
+ expect(spy.mock.calls).toEqual([
+ [instance1, { context: 1 }],
+ [instance2, { context: 2 }],
+ [instance1, { context: 1 }],
+ ]);
+ });
+ });
+});
diff --git a/spec/frontend/lib/utils/resize_observer_spec.js b/spec/frontend/lib/utils/resize_observer_spec.js
index 419aff28935..6560562f204 100644
--- a/spec/frontend/lib/utils/resize_observer_spec.js
+++ b/spec/frontend/lib/utils/resize_observer_spec.js
@@ -19,16 +19,11 @@ describe('ResizeObserver Utility', () => {
jest.spyOn(document.documentElement, 'scrollTo');
- setFixtures(`<div id="content-body"><div class="target">element to scroll to</div></div>`);
+ setFixtures(`<div id="content-body"><div id="note_1234">note to scroll to</div></div>`);
- const target = document.querySelector('.target');
+ const target = document.querySelector('#note_1234');
jest.spyOn(target, 'getBoundingClientRect').mockReturnValue({ top: 200 });
-
- observer = scrollToTargetOnResize({
- target: '.target',
- container: '#content-body',
- });
});
afterEach(() => {
@@ -38,21 +33,22 @@ describe('ResizeObserver Utility', () => {
describe('Observer behavior', () => {
it('returns null for empty target', () => {
observer = scrollToTargetOnResize({
- target: '',
+ targetId: '',
container: '#content-body',
});
expect(observer).toBe(null);
});
- it('returns ResizeObserver instance', () => {
- expect(observer).toBeInstanceOf(ResizeObserver);
- });
+ it('does not scroll if target does not exist', () => {
+ observer = scrollToTargetOnResize({
+ targetId: 'some_imaginary_id',
+ container: '#content-body',
+ });
- it('scrolls body so anchor is just below sticky header (contentTop)', () => {
triggerResize();
- expect(document.documentElement.scrollTo).toHaveBeenCalledWith({ top: 110 });
+ expect(document.documentElement.scrollTo).not.toHaveBeenCalled();
});
const interactionEvents = ['mousedown', 'touchstart', 'keydown', 'wheel'];
@@ -64,5 +60,24 @@ describe('ResizeObserver Utility', () => {
expect(document.documentElement.scrollTo).not.toHaveBeenCalledWith();
});
+
+ describe('with existing target', () => {
+ beforeEach(() => {
+ observer = scrollToTargetOnResize({
+ targetId: 'note_1234',
+ container: '#content-body',
+ });
+ });
+
+ it('returns ResizeObserver instance', () => {
+ expect(observer).toBeInstanceOf(ResizeObserver);
+ });
+
+ it('scrolls body so anchor is just below sticky header (contentTop)', () => {
+ triggerResize();
+
+ expect(document.documentElement.scrollTo).toHaveBeenCalledWith({ top: 110 });
+ });
+ });
});
});
diff --git a/spec/frontend/lib/utils/text_markdown_spec.js b/spec/frontend/lib/utils/text_markdown_spec.js
index dded32cc890..a5877aa6e3e 100644
--- a/spec/frontend/lib/utils/text_markdown_spec.js
+++ b/spec/frontend/lib/utils/text_markdown_spec.js
@@ -1,4 +1,6 @@
+import $ from 'jquery';
import { insertMarkdownText, keypressNoteText } from '~/lib/utils/text_markdown';
+import '~/lib/utils/jquery_at_who';
describe('init markdown', () => {
let textArea;
@@ -179,12 +181,13 @@ describe('init markdown', () => {
${'- [ ] item'} | ${'- [ ] item\n- [ ] '}
${'- [x] item'} | ${'- [x] item\n- [x] '}
${'- item\n - second'} | ${'- item\n - second\n - '}
- ${'1. item'} | ${'1. item\n1. '}
- ${'1. [ ] item'} | ${'1. [ ] item\n1. [ ] '}
- ${'1. [x] item'} | ${'1. [x] item\n1. [x] '}
- ${'108. item'} | ${'108. item\n108. '}
+ ${'1. item'} | ${'1. item\n2. '}
+ ${'1. [ ] item'} | ${'1. [ ] item\n2. [ ] '}
+ ${'1. [x] item'} | ${'1. [x] item\n2. [x] '}
+ ${'108. item'} | ${'108. item\n109. '}
${'108. item\n - second'} | ${'108. item\n - second\n - '}
- ${'108. item\n 1. second'} | ${'108. item\n 1. second\n 1. '}
+ ${'108. item\n 1. second'} | ${'108. item\n 1. second\n 2. '}
+ ${'non-item, will not change'} | ${'non-item, will not change'}
`('adds correct list continuation characters', ({ text, expected }) => {
textArea.value = text;
textArea.setSelectionRange(text.length, text.length);
@@ -205,10 +208,10 @@ describe('init markdown', () => {
${'- [ ] item\n- [ ] '} | ${'- [ ] item\n'}
${'- [x] item\n- [x] '} | ${'- [x] item\n'}
${'- item\n - second\n - '} | ${'- item\n - second\n'}
- ${'1. item\n1. '} | ${'1. item\n'}
- ${'1. [ ] item\n1. [ ] '} | ${'1. [ ] item\n'}
- ${'1. [x] item\n1. [x] '} | ${'1. [x] item\n'}
- ${'108. item\n108. '} | ${'108. item\n'}
+ ${'1. item\n2. '} | ${'1. item\n'}
+ ${'1. [ ] item\n2. [ ] '} | ${'1. [ ] item\n'}
+ ${'1. [x] item\n2. [x] '} | ${'1. [x] item\n'}
+ ${'108. item\n109. '} | ${'108. item\n'}
${'108. item\n - second\n - '} | ${'108. item\n - second\n'}
${'108. item\n 1. second\n 1. '} | ${'108. item\n 1. second\n'}
`('adds correct list continuation characters', ({ text, expected }) => {
@@ -223,6 +226,41 @@ describe('init markdown', () => {
expect(textArea.selectionEnd).toBe(text.length);
});
+ // test that when we're in the middle of autocomplete, we don't
+ // add a new list item
+ it.each`
+ text | expected | atwho_selecting
+ ${'- item @'} | ${'- item @'} | ${true}
+ ${'- item @'} | ${'- item @\n- '} | ${false}
+ `('behaves correctly during autocomplete', ({ text, expected, atwho_selecting }) => {
+ jest.spyOn($.fn, 'atwho').mockReturnValue(atwho_selecting);
+
+ textArea.value = text;
+ textArea.setSelectionRange(text.length, text.length);
+
+ textArea.addEventListener('keydown', keypressNoteText);
+ textArea.dispatchEvent(enterEvent);
+
+ expect(textArea.value).toEqual(expected);
+ });
+
+ it.each`
+ text | add_at | expected
+ ${'1. one\n2. two\n3. three'} | ${13} | ${'1. one\n2. two\n2. \n3. three'}
+ ${'108. item\n 5. second\n 6. six\n 7. seven'} | ${36} | ${'108. item\n 5. second\n 6. six\n 6. \n 7. seven'}
+ `(
+ 'adds correct numbered continuation characters when in middle of list',
+ ({ text, add_at, expected }) => {
+ textArea.value = text;
+ textArea.setSelectionRange(add_at, add_at);
+
+ textArea.addEventListener('keydown', keypressNoteText);
+ textArea.dispatchEvent(enterEvent);
+
+ expect(textArea.value).toEqual(expected);
+ },
+ );
+
it('does nothing if feature flag disabled', () => {
gon.features = { markdownContinueLists: false };
@@ -242,8 +280,8 @@ describe('init markdown', () => {
});
describe('with selection', () => {
- const text = 'initial selected value';
- const selected = 'selected';
+ let text = 'initial selected value';
+ let selected = 'selected';
let selectedIndex;
beforeEach(() => {
@@ -389,6 +427,46 @@ describe('init markdown', () => {
expectedText.indexOf(expectedSelectionText, 1) + expectedSelectionText.length,
);
});
+
+ it('adds block tags on line above and below selection', () => {
+ selected = 'this text\nis multiple\nlines';
+ text = `before \n${selected}\nafter `;
+
+ textArea.value = text;
+ selectedIndex = text.indexOf(selected);
+ textArea.setSelectionRange(selectedIndex, selectedIndex + selected.length);
+
+ insertMarkdownText({
+ textArea,
+ text,
+ tag: '',
+ blockTag: '***',
+ selected,
+ wrap: true,
+ });
+
+ expect(textArea.value).toEqual(`before \n***\n${selected}\n***\nafter `);
+ });
+
+ it('removes block tags on line above and below selection', () => {
+ selected = 'this text\nis multiple\nlines';
+ text = `before \n***\n${selected}\n***\nafter `;
+
+ textArea.value = text;
+ selectedIndex = text.indexOf(selected);
+ textArea.setSelectionRange(selectedIndex, selectedIndex + selected.length);
+
+ insertMarkdownText({
+ textArea,
+ text,
+ tag: '',
+ blockTag: '***',
+ selected,
+ wrap: true,
+ });
+
+ expect(textArea.value).toEqual(`before \n${selected}\nafter `);
+ });
});
});
});
@@ -440,7 +518,31 @@ describe('init markdown', () => {
expect(editor.replaceSelectedText).toHaveBeenCalledWith(`***\n${selected}\n***\n`, undefined);
});
- it('uses ace editor to navigate back tag length when nothing is selected', () => {
+ it('removes block tags on line above and below selection', () => {
+ const selected = 'this text\nis multiple\nlines';
+ const text = `before\n***\n${selected}\n***\nafter`;
+
+ editor.getSelection = jest.fn().mockReturnValue({
+ startLineNumber: 2,
+ startColumn: 1,
+ endLineNumber: 4,
+ endColumn: 2,
+ setSelectionRange: jest.fn(),
+ });
+
+ insertMarkdownText({
+ text,
+ tag: '',
+ blockTag: '***',
+ selected,
+ wrap: true,
+ editor,
+ });
+
+ expect(editor.replaceSelectedText).toHaveBeenCalledWith(`${selected}\n`, undefined);
+ });
+
+ it('uses editor to navigate back tag length when nothing is selected', () => {
editor.getSelection = jest.fn().mockReturnValue({
startLineNumber: 1,
startColumn: 1,
@@ -460,7 +562,7 @@ describe('init markdown', () => {
expect(editor.moveCursor).toHaveBeenCalledWith(-1);
});
- it('ace editor does not navigate back when there is selected text', () => {
+ it('editor does not navigate back when there is selected text', () => {
insertMarkdownText({
text: editor.getValue,
tag: '*',
diff --git a/spec/frontend/lib/utils/url_utility_spec.js b/spec/frontend/lib/utils/url_utility_spec.js
index c6edba19c56..7608cff4c9e 100644
--- a/spec/frontend/lib/utils/url_utility_spec.js
+++ b/spec/frontend/lib/utils/url_utility_spec.js
@@ -22,6 +22,27 @@ beforeEach(() => {
});
describe('URL utility', () => {
+ describe('parseUrlPathname', () => {
+ it('returns an absolute url when given an absolute url', () => {
+ expect(urlUtils.parseUrlPathname('/some/absolute/url')).toBe('/some/absolute/url');
+ });
+
+ it('returns an absolute url when given a relative url', () => {
+ expect(urlUtils.parseUrlPathname('some/relative/url')).toBe('/some/relative/url');
+ });
+
+ it('returns an absolute url that includes the document.location path when given a relative url', () => {
+ // Change the location to see the `/mypath/` included in the result
+ setWindowLocation(`${TEST_HOST}/mypath/`);
+
+ expect(urlUtils.parseUrlPathname('some/relative/url')).toBe('/mypath/some/relative/url');
+ });
+
+ it('encodes certain character in the url', () => {
+ expect(urlUtils.parseUrlPathname('test="a b"')).toBe('/test=%22a%20b%22');
+ });
+ });
+
describe('webIDEUrl', () => {
afterEach(() => {
gon.relative_url_root = '';
@@ -636,7 +657,7 @@ describe('URL utility', () => {
`('returns "$expectation" with "$protocol" protocol', ({ protocol, expectation }) => {
setWindowLocation(`${protocol}//example.com`);
- expect(urlUtils.getWebSocketProtocol()).toEqual(expectation);
+ expect(urlUtils.getWebSocketProtocol()).toBe(expectation);
});
});
@@ -646,7 +667,7 @@ describe('URL utility', () => {
const path = '/lorem/ipsum?a=bc';
- expect(urlUtils.getWebSocketUrl(path)).toEqual('ws://example.com/lorem/ipsum?a=bc');
+ expect(urlUtils.getWebSocketUrl(path)).toBe('ws://example.com/lorem/ipsum?a=bc');
});
});
@@ -696,7 +717,7 @@ describe('URL utility', () => {
it('should return valid parameter', () => {
setWindowLocation('?scope=all&p=2');
- expect(getParameterByName('p')).toEqual('2');
+ expect(getParameterByName('p')).toBe('2');
expect(getParameterByName('scope')).toBe('all');
});
@@ -737,7 +758,7 @@ describe('URL utility', () => {
it('converts search query object back into a search query', () => {
const searchQueryObject = { one: '1', two: '2' };
- expect(urlUtils.objectToQuery(searchQueryObject)).toEqual('one=1&two=2');
+ expect(urlUtils.objectToQuery(searchQueryObject)).toBe('one=1&two=2');
});
it('returns empty string when `params` is undefined, null or empty string', () => {
@@ -833,15 +854,15 @@ describe('URL utility', () => {
it('adds new params as query string', () => {
const url = 'https://gitlab.com/test';
- expect(
- urlUtils.setUrlParams({ group_id: 'gitlab-org', project_id: 'my-project' }, url),
- ).toEqual('https://gitlab.com/test?group_id=gitlab-org&project_id=my-project');
+ expect(urlUtils.setUrlParams({ group_id: 'gitlab-org', project_id: 'my-project' }, url)).toBe(
+ 'https://gitlab.com/test?group_id=gitlab-org&project_id=my-project',
+ );
});
it('updates an existing parameter', () => {
const url = 'https://gitlab.com/test?group_id=gitlab-org&project_id=my-project';
- expect(urlUtils.setUrlParams({ project_id: 'gitlab-test' }, url)).toEqual(
+ expect(urlUtils.setUrlParams({ project_id: 'gitlab-test' }, url)).toBe(
'https://gitlab.com/test?group_id=gitlab-org&project_id=gitlab-test',
);
});
@@ -849,7 +870,7 @@ describe('URL utility', () => {
it("removes the project_id param when it's value is null", () => {
const url = 'https://gitlab.com/test?group_id=gitlab-org&project_id=my-project';
- expect(urlUtils.setUrlParams({ project_id: null }, url)).toEqual(
+ expect(urlUtils.setUrlParams({ project_id: null }, url)).toBe(
'https://gitlab.com/test?group_id=gitlab-org',
);
});
@@ -857,7 +878,7 @@ describe('URL utility', () => {
it('adds parameters from arrays', () => {
const url = 'https://gitlab.com/test';
- expect(urlUtils.setUrlParams({ labels: ['foo', 'bar'] }, url)).toEqual(
+ expect(urlUtils.setUrlParams({ labels: ['foo', 'bar'] }, url)).toBe(
'https://gitlab.com/test?labels=foo&labels=bar',
);
});
@@ -865,13 +886,13 @@ describe('URL utility', () => {
it('removes parameters from empty arrays', () => {
const url = 'https://gitlab.com/test?labels=foo&labels=bar';
- expect(urlUtils.setUrlParams({ labels: [] }, url)).toEqual('https://gitlab.com/test');
+ expect(urlUtils.setUrlParams({ labels: [] }, url)).toBe('https://gitlab.com/test');
});
it('removes parameters from empty arrays while keeping other parameters', () => {
const url = 'https://gitlab.com/test?labels=foo&labels=bar&unrelated=unrelated';
- expect(urlUtils.setUrlParams({ labels: [] }, url)).toEqual(
+ expect(urlUtils.setUrlParams({ labels: [] }, url)).toBe(
'https://gitlab.com/test?unrelated=unrelated',
);
});
@@ -879,7 +900,7 @@ describe('URL utility', () => {
it('adds parameters from arrays when railsArraySyntax=true', () => {
const url = 'https://gitlab.com/test';
- expect(urlUtils.setUrlParams({ labels: ['foo', 'bar'] }, url, false, true)).toEqual(
+ expect(urlUtils.setUrlParams({ labels: ['foo', 'bar'] }, url, false, true)).toBe(
'https://gitlab.com/test?labels%5B%5D=foo&labels%5B%5D=bar',
);
});
@@ -887,7 +908,7 @@ describe('URL utility', () => {
it('removes parameters from empty arrays when railsArraySyntax=true', () => {
const url = 'https://gitlab.com/test?labels%5B%5D=foo&labels%5B%5D=bar';
- expect(urlUtils.setUrlParams({ labels: [] }, url, false, true)).toEqual(
+ expect(urlUtils.setUrlParams({ labels: [] }, url, false, true)).toBe(
'https://gitlab.com/test',
);
});
@@ -895,7 +916,7 @@ describe('URL utility', () => {
it('decodes URI when decodeURI=true', () => {
const url = 'https://gitlab.com/test';
- expect(urlUtils.setUrlParams({ labels: ['foo', 'bar'] }, url, false, true, true)).toEqual(
+ expect(urlUtils.setUrlParams({ labels: ['foo', 'bar'] }, url, false, true, true)).toBe(
'https://gitlab.com/test?labels[]=foo&labels[]=bar',
);
});
@@ -903,7 +924,7 @@ describe('URL utility', () => {
it('removes all existing URL params and sets a new param when cleanParams=true', () => {
const url = 'https://gitlab.com/test?group_id=gitlab-org&project_id=my-project';
- expect(urlUtils.setUrlParams({ foo: 'bar' }, url, true)).toEqual(
+ expect(urlUtils.setUrlParams({ foo: 'bar' }, url, true)).toBe(
'https://gitlab.com/test?foo=bar',
);
});
diff --git a/spec/frontend/loading_icon_for_legacy_js_spec.js b/spec/frontend/loading_icon_for_legacy_js_spec.js
new file mode 100644
index 00000000000..46deee555ba
--- /dev/null
+++ b/spec/frontend/loading_icon_for_legacy_js_spec.js
@@ -0,0 +1,43 @@
+import { loadingIconForLegacyJS } from '~/loading_icon_for_legacy_js';
+
+describe('loadingIconForLegacyJS', () => {
+ it('sets the correct defaults', () => {
+ const el = loadingIconForLegacyJS();
+
+ expect(el.tagName).toBe('DIV');
+ expect(el.className).toBe('gl-spinner-container');
+ expect(el.querySelector('.gl-spinner-sm')).toEqual(expect.any(HTMLElement));
+ expect(el.querySelector('.gl-spinner-dark')).toEqual(expect.any(HTMLElement));
+ expect(el.querySelector('[aria-label="Loading"]')).toEqual(expect.any(HTMLElement));
+ expect(el.getAttribute('role')).toBe('status');
+ });
+
+ it('renders a span if inline = true', () => {
+ expect(loadingIconForLegacyJS({ inline: true }).tagName).toBe('SPAN');
+ });
+
+ it('can render a different size', () => {
+ const el = loadingIconForLegacyJS({ size: 'lg' });
+
+ expect(el.querySelector('.gl-spinner-lg')).toEqual(expect.any(HTMLElement));
+ });
+
+ it('can render a different color', () => {
+ const el = loadingIconForLegacyJS({ color: 'light' });
+
+ expect(el.querySelector('.gl-spinner-light')).toEqual(expect.any(HTMLElement));
+ });
+
+ it('can render a different aria-label', () => {
+ const el = loadingIconForLegacyJS({ label: 'Foo' });
+
+ expect(el.querySelector('[aria-label="Foo"]')).toEqual(expect.any(HTMLElement));
+ });
+
+ it('can render additional classes', () => {
+ const classes = ['foo', 'bar'];
+ const el = loadingIconForLegacyJS({ classes });
+
+ expect(el.classList).toContain(...classes);
+ });
+});
diff --git a/spec/frontend/members/components/action_buttons/user_action_buttons_spec.js b/spec/frontend/members/components/action_buttons/user_action_buttons_spec.js
index 356df7e7b11..3e4ffb6e61b 100644
--- a/spec/frontend/members/components/action_buttons/user_action_buttons_spec.js
+++ b/spec/frontend/members/components/action_buttons/user_action_buttons_spec.js
@@ -43,12 +43,12 @@ describe('UserActionButtons', () => {
memberId: member.id,
memberType: 'GroupMember',
message: `Are you sure you want to remove ${member.user.name} from "${member.source.fullName}"?`,
- title: 'Remove member',
+ title: null,
isAccessRequest: false,
isInvite: false,
icon: '',
buttonCategory: 'secondary',
- buttonText: 'Remove user',
+ buttonText: 'Remove member',
userDeletionObstacles: {
name: member.user.name,
obstacles: parseUserDeletionObstacles(member.user),
@@ -135,9 +135,9 @@ describe('UserActionButtons', () => {
describe('isInvitedUser', () => {
it.each`
- isInvitedUser | icon | buttonText | buttonCategory
- ${true} | ${'remove'} | ${null} | ${'primary'}
- ${false} | ${''} | ${'Remove user'} | ${'secondary'}
+ isInvitedUser | icon | buttonText | buttonCategory
+ ${true} | ${'remove'} | ${null} | ${'primary'}
+ ${false} | ${''} | ${'Remove member'} | ${'secondary'}
`(
'passes the correct props to remove-member-button when isInvitedUser is $isInvitedUser',
({ isInvitedUser, icon, buttonText, buttonCategory }) => {
diff --git a/spec/frontend/members/components/filter_sort/members_filtered_search_bar_spec.js b/spec/frontend/members/components/filter_sort/members_filtered_search_bar_spec.js
index ee2fbbe57b9..b692eea4aa5 100644
--- a/spec/frontend/members/components/filter_sort/members_filtered_search_bar_spec.js
+++ b/spec/frontend/members/components/filter_sort/members_filtered_search_bar_spec.js
@@ -1,12 +1,14 @@
-import { GlFilteredSearchToken } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
import Vuex from 'vuex';
import setWindowLocation from 'helpers/set_window_location_helper';
import { redirectTo } from '~/lib/utils/url_utility';
import MembersFilteredSearchBar from '~/members/components/filter_sort/members_filtered_search_bar.vue';
-import { MEMBER_TYPES } from '~/members/constants';
-import { OPERATOR_IS_ONLY } from '~/vue_shared/components/filtered_search_bar/constants';
+import {
+ MEMBER_TYPES,
+ FILTERED_SEARCH_TOKEN_TWO_FACTOR,
+ FILTERED_SEARCH_TOKEN_WITH_INHERITED_PERMISSIONS,
+} from '~/members/constants';
import FilteredSearchBar from '~/vue_shared/components/filtered_search_bar/filtered_search_bar_root.vue';
jest.mock('~/lib/utils/url_utility', () => {
@@ -32,7 +34,7 @@ describe('MembersFilteredSearchBar', () => {
state: {
filteredSearchBar: {
show: true,
- tokens: ['two_factor'],
+ tokens: [FILTERED_SEARCH_TOKEN_TWO_FACTOR.type],
searchParam: 'search',
placeholder: 'Filter members',
recentSearchesStorageKey: 'group_members',
@@ -70,21 +72,7 @@ describe('MembersFilteredSearchBar', () => {
it('includes tokens set in `filteredSearchBar.tokens`', () => {
createComponent();
- expect(findFilteredSearchBar().props('tokens')).toEqual([
- {
- type: 'two_factor',
- icon: 'lock',
- title: '2FA',
- token: GlFilteredSearchToken,
- unique: true,
- operators: OPERATOR_IS_ONLY,
- options: [
- { value: 'enabled', title: 'Enabled' },
- { value: 'disabled', title: 'Disabled' },
- ],
- requiredPermissions: 'canManageMembers',
- },
- ]);
+ expect(findFilteredSearchBar().props('tokens')).toEqual([FILTERED_SEARCH_TOKEN_TWO_FACTOR]);
});
describe('when `canManageMembers` is false', () => {
@@ -93,7 +81,10 @@ describe('MembersFilteredSearchBar', () => {
state: {
filteredSearchBar: {
show: true,
- tokens: ['two_factor', 'with_inherited_permissions'],
+ tokens: [
+ FILTERED_SEARCH_TOKEN_TWO_FACTOR.type,
+ FILTERED_SEARCH_TOKEN_WITH_INHERITED_PERMISSIONS.type,
+ ],
searchParam: 'search',
placeholder: 'Filter members',
recentSearchesStorageKey: 'group_members',
@@ -105,18 +96,7 @@ describe('MembersFilteredSearchBar', () => {
});
expect(findFilteredSearchBar().props('tokens')).toEqual([
- {
- type: 'with_inherited_permissions',
- icon: 'group',
- title: 'Membership',
- token: GlFilteredSearchToken,
- unique: true,
- operators: OPERATOR_IS_ONLY,
- options: [
- { value: 'exclude', title: 'Direct' },
- { value: 'only', title: 'Inherited' },
- ],
- },
+ FILTERED_SEARCH_TOKEN_WITH_INHERITED_PERMISSIONS,
]);
});
});
@@ -134,7 +114,7 @@ describe('MembersFilteredSearchBar', () => {
expect(findFilteredSearchBar().props('initialFilterValue')).toEqual([
{
- type: 'two_factor',
+ type: FILTERED_SEARCH_TOKEN_TWO_FACTOR.type,
value: {
data: 'enabled',
operator: '=',
@@ -183,7 +163,7 @@ describe('MembersFilteredSearchBar', () => {
createComponent();
findFilteredSearchBar().vm.$emit('onFilter', [
- { type: 'two_factor', value: { data: 'enabled', operator: '=' } },
+ { type: FILTERED_SEARCH_TOKEN_TWO_FACTOR.type, value: { data: 'enabled', operator: '=' } },
]);
expect(redirectTo).toHaveBeenCalledWith('https://localhost/?two_factor=enabled');
@@ -193,7 +173,7 @@ describe('MembersFilteredSearchBar', () => {
createComponent();
findFilteredSearchBar().vm.$emit('onFilter', [
- { type: 'two_factor', value: { data: 'enabled', operator: '=' } },
+ { type: FILTERED_SEARCH_TOKEN_TWO_FACTOR.type, value: { data: 'enabled', operator: '=' } },
{ type: 'filtered-search-term', value: { data: 'foobar' } },
]);
@@ -206,7 +186,7 @@ describe('MembersFilteredSearchBar', () => {
createComponent();
findFilteredSearchBar().vm.$emit('onFilter', [
- { type: 'two_factor', value: { data: 'enabled', operator: '=' } },
+ { type: FILTERED_SEARCH_TOKEN_TWO_FACTOR.type, value: { data: 'enabled', operator: '=' } },
{ type: 'filtered-search-term', value: { data: 'foo bar baz' } },
]);
@@ -221,7 +201,7 @@ describe('MembersFilteredSearchBar', () => {
createComponent();
findFilteredSearchBar().vm.$emit('onFilter', [
- { type: 'two_factor', value: { data: 'enabled', operator: '=' } },
+ { type: FILTERED_SEARCH_TOKEN_TWO_FACTOR.type, value: { data: 'enabled', operator: '=' } },
{ type: 'filtered-search-term', value: { data: 'foobar' } },
]);
diff --git a/spec/frontend/merge_conflicts/components/merge_conflict_resolver_app_spec.js b/spec/frontend/merge_conflicts/components/merge_conflict_resolver_app_spec.js
index 750fff9b0aa..55e666609bd 100644
--- a/spec/frontend/merge_conflicts/components/merge_conflict_resolver_app_spec.js
+++ b/spec/frontend/merge_conflicts/components/merge_conflict_resolver_app_spec.js
@@ -1,7 +1,7 @@
import { GlSprintf } from '@gitlab/ui';
-import { shallowMount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
import Vuex from 'vuex';
+import { shallowMountExtended, extendedWrapper } from 'helpers/vue_test_utils_helper';
import InlineConflictLines from '~/merge_conflicts/components/inline_conflict_lines.vue';
import ParallelConflictLines from '~/merge_conflicts/components/parallel_conflict_lines.vue';
import component from '~/merge_conflicts/merge_conflict_resolver_app.vue';
@@ -18,7 +18,7 @@ describe('Merge Conflict Resolver App', () => {
const decoratedMockFiles = decorateFiles(conflictsMock.files);
const mountComponent = () => {
- wrapper = shallowMount(component, {
+ wrapper = shallowMountExtended(component, {
store,
stubs: { GlSprintf },
provide() {
@@ -41,15 +41,17 @@ describe('Merge Conflict Resolver App', () => {
wrapper.destroy();
});
- const findConflictsCount = () => wrapper.find('[data-testid="conflicts-count"]');
- const findFiles = () => wrapper.findAll('[data-testid="files"]');
- const findFileHeader = (w = wrapper) => w.find('[data-testid="file-name"]');
- const findFileInteractiveButton = (w = wrapper) => w.find('[data-testid="interactive-button"]');
- const findFileInlineButton = (w = wrapper) => w.find('[data-testid="inline-button"]');
- const findSideBySideButton = () => wrapper.find('[data-testid="side-by-side"]');
+ const findLoadingSpinner = () => wrapper.findByTestId('loading-spinner');
+ const findConflictsCount = () => wrapper.findByTestId('conflicts-count');
+ const findFiles = () => wrapper.findAllByTestId('files');
+ const findFileHeader = (w = wrapper) => extendedWrapper(w).findByTestId('file-name');
+ const findFileInteractiveButton = (w = wrapper) =>
+ extendedWrapper(w).findByTestId('interactive-button');
+ const findFileInlineButton = (w = wrapper) => extendedWrapper(w).findByTestId('inline-button');
+ const findSideBySideButton = () => wrapper.findByTestId('side-by-side');
const findInlineConflictLines = (w = wrapper) => w.find(InlineConflictLines);
const findParallelConflictLines = (w = wrapper) => w.find(ParallelConflictLines);
- const findCommitMessageTextarea = () => wrapper.find('[data-testid="commit-message"]');
+ const findCommitMessageTextarea = () => wrapper.findByTestId('commit-message');
it('shows the amount of conflicts', () => {
mountComponent();
@@ -60,6 +62,19 @@ describe('Merge Conflict Resolver App', () => {
expect(title.text().trim()).toBe('Showing 3 conflicts between test-conflicts and main');
});
+ it('shows a loading spinner while loading', () => {
+ store.commit('SET_LOADING_STATE', true);
+ mountComponent();
+
+ expect(findLoadingSpinner().exists()).toBe(true);
+ });
+
+ it('does not show a loading spinner once loaded', () => {
+ mountComponent();
+
+ expect(findLoadingSpinner().exists()).toBe(false);
+ });
+
describe('files', () => {
it('shows one file area for each file', () => {
mountComponent();
diff --git a/spec/frontend/merge_request_tabs_spec.js b/spec/frontend/merge_request_tabs_spec.js
index ced9b71125b..5c24a070342 100644
--- a/spec/frontend/merge_request_tabs_spec.js
+++ b/spec/frontend/merge_request_tabs_spec.js
@@ -4,6 +4,7 @@ import initMrPage from 'helpers/init_vue_mr_page_helper';
import axios from '~/lib/utils/axios_utils';
import MergeRequestTabs from '~/merge_request_tabs';
import '~/lib/utils/common_utils';
+import '~/lib/utils/url_utility';
jest.mock('~/lib/utils/webpack', () => ({
resetServiceWorkersPublicPath: jest.fn(),
diff --git a/spec/frontend/monitoring/components/charts/time_series_spec.js b/spec/frontend/monitoring/components/charts/time_series_spec.js
index 73abd81d889..f4bca26f659 100644
--- a/spec/frontend/monitoring/components/charts/time_series_spec.js
+++ b/spec/frontend/monitoring/components/charts/time_series_spec.js
@@ -335,21 +335,6 @@ describe('Time series component', () => {
expect(formattedTooltipData.content).toBe(annotationsMetadata.tooltipData.content);
});
});
-
- describe('onResize', () => {
- const mockWidth = 233;
-
- beforeEach(() => {
- jest.spyOn(Element.prototype, 'getBoundingClientRect').mockImplementation(() => ({
- width: mockWidth,
- }));
- wrapper.vm.onResize();
- });
-
- it('sets area chart width', () => {
- expect(wrapper.vm.width).toBe(mockWidth);
- });
- });
});
describe('computed', () => {
diff --git a/spec/frontend/notes/components/note_header_spec.js b/spec/frontend/notes/components/note_header_spec.js
index 8d82cf3d2c7..4671d33219d 100644
--- a/spec/frontend/notes/components/note_header_spec.js
+++ b/spec/frontend/notes/components/note_header_spec.js
@@ -1,7 +1,7 @@
import { GlSprintf } from '@gitlab/ui';
-import { shallowMount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
import Vuex from 'vuex';
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import NoteHeader from '~/notes/components/note_header.vue';
import { AVAILABILITY_STATUS } from '~/set_status_modal/utils';
import UserNameWithStatus from '~/sidebar/components/assignees/user_name_with_status.vue';
@@ -16,11 +16,12 @@ describe('NoteHeader component', () => {
let wrapper;
const findActionsWrapper = () => wrapper.find({ ref: 'discussionActions' });
+ const findToggleThreadButton = () => wrapper.findByTestId('thread-toggle');
const findChevronIcon = () => wrapper.find({ ref: 'chevronIcon' });
const findActionText = () => wrapper.find({ ref: 'actionText' });
const findTimestampLink = () => wrapper.find({ ref: 'noteTimestampLink' });
const findTimestamp = () => wrapper.find({ ref: 'noteTimestamp' });
- const findConfidentialIndicator = () => wrapper.find('[data-testid="confidentialIndicator"]');
+ const findConfidentialIndicator = () => wrapper.findByTestId('confidentialIndicator');
const findSpinner = () => wrapper.find({ ref: 'spinner' });
const findAuthorStatus = () => wrapper.find({ ref: 'authorStatus' });
@@ -40,7 +41,7 @@ describe('NoteHeader component', () => {
};
const createComponent = (props) => {
- wrapper = shallowMount(NoteHeader, {
+ wrapper = shallowMountExtended(NoteHeader, {
store: new Vuex.Store({
actions,
}),
@@ -98,6 +99,19 @@ describe('NoteHeader component', () => {
expect(findChevronIcon().props('name')).toBe('chevron-down');
});
+
+ it.each`
+ text | expanded
+ ${NoteHeader.i18n.showThread} | ${false}
+ ${NoteHeader.i18n.hideThread} | ${true}
+ `('toggle button has text $text is expanded is $expanded', ({ text, expanded }) => {
+ createComponent({
+ includeToggle: true,
+ expanded,
+ });
+
+ expect(findToggleThreadButton().text()).toBe(text);
+ });
});
it('renders an author link if author is passed to props', () => {
diff --git a/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/delete_alert_spec.js b/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/delete_alert_spec.js
index e25162f4da5..9680e273add 100644
--- a/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/delete_alert_spec.js
+++ b/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/delete_alert_spec.js
@@ -6,6 +6,7 @@ import {
DELETE_TAG_ERROR_MESSAGE,
DELETE_TAGS_SUCCESS_MESSAGE,
DELETE_TAGS_ERROR_MESSAGE,
+ DETAILS_IMPORTING_ERROR_MESSAGE,
ADMIN_GARBAGE_COLLECTION_TIP,
} from '~/packages_and_registries/container_registry/explorer/constants';
@@ -76,6 +77,7 @@ describe('Delete alert', () => {
});
});
});
+
describe('error states', () => {
describe.each`
deleteAlertType | message
@@ -105,6 +107,25 @@ describe('Delete alert', () => {
});
});
+ describe('importing repository error state', () => {
+ beforeEach(() => {
+ mountComponent({
+ deleteAlertType: 'danger_importing',
+ containerRegistryImportingHelpPagePath: 'https://foobar',
+ });
+ });
+
+ it('alert exist and text is appropriate', () => {
+ expect(findAlert().text()).toMatchInterpolatedText(DETAILS_IMPORTING_ERROR_MESSAGE);
+ });
+
+ it('alert body contains link', () => {
+ const alertLink = findLink();
+ expect(alertLink.exists()).toBe(true);
+ expect(alertLink.attributes('href')).toBe('https://foobar');
+ });
+ });
+
describe('dismissing alert', () => {
it('GlAlert dismiss event triggers a change event', () => {
mountComponent({ deleteAlertType: 'success_tags' });
diff --git a/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/details_header_spec.js b/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/details_header_spec.js
index f4c22d9bfa7..a8d0d15007c 100644
--- a/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/details_header_spec.js
+++ b/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/details_header_spec.js
@@ -2,6 +2,7 @@ import { GlDropdownItem, GlIcon, GlDropdown } from '@gitlab/ui';
import { shallowMount, createLocalVue } from '@vue/test-utils';
import VueApollo from 'vue-apollo';
import { nextTick } from 'vue';
+import { numberToHumanSize } from '~/lib/utils/number_utils';
import { useFakeDate } from 'helpers/fake_date';
import createMockApollo from 'helpers/mock_apollo_helper';
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
@@ -20,7 +21,7 @@ import {
ROOT_IMAGE_TEXT,
ROOT_IMAGE_TOOLTIP,
} from '~/packages_and_registries/container_registry/explorer/constants';
-import getContainerRepositoryTagCountQuery from '~/packages_and_registries/container_registry/explorer/graphql/queries/get_container_repository_tags_count.query.graphql';
+import getContainerRepositoryMetadata from '~/packages_and_registries/container_registry/explorer/graphql/queries/get_container_repository_metadata.query.graphql';
import TitleArea from '~/vue_shared/components/registry/title_area.vue';
import { imageTagsCountMock } from '../../mock_data';
@@ -52,6 +53,7 @@ describe('Details Header', () => {
const findDeleteButton = () => wrapper.findComponent(GlDropdownItem);
const findInfoIcon = () => wrapper.findComponent(GlIcon);
const findMenu = () => wrapper.findComponent(GlDropdown);
+ const findSize = () => findByTestId('image-size');
const waitForMetadataItems = async () => {
// Metadata items are printed by a loop in the title-area and it takes two ticks for them to be available
@@ -72,7 +74,7 @@ describe('Details Header', () => {
localVue = createLocalVue();
localVue.use(VueApollo);
- const requestHandlers = [[getContainerRepositoryTagCountQuery, resolver]];
+ const requestHandlers = [[getContainerRepositoryMetadata, resolver]];
apolloProvider = createMockApollo(requestHandlers);
}
@@ -230,6 +232,30 @@ describe('Details Header', () => {
});
});
+ describe('size metadata item', () => {
+ it('when size is not returned, it hides the item', async () => {
+ mountComponent();
+ await waitForMetadataItems();
+
+ expect(findSize().exists()).toBe(false);
+ });
+
+ it('when size is returned shows the item', async () => {
+ const size = 1000;
+ mountComponent({
+ resolver: jest.fn().mockResolvedValue(imageTagsCountMock({ size })),
+ });
+
+ await waitForPromises();
+ await waitForMetadataItems();
+
+ expect(findSize().props()).toMatchObject({
+ icon: 'disk',
+ text: numberToHumanSize(size),
+ });
+ });
+ });
+
describe('cleanup metadata item', () => {
it('has the correct icon', async () => {
mountComponent();
diff --git a/spec/frontend/packages_and_registries/container_registry/explorer/mock_data.js b/spec/frontend/packages_and_registries/container_registry/explorer/mock_data.js
index 16625d913a5..fda1db4b7e1 100644
--- a/spec/frontend/packages_and_registries/container_registry/explorer/mock_data.js
+++ b/spec/frontend/packages_and_registries/container_registry/explorer/mock_data.js
@@ -187,6 +187,7 @@ export const imageTagsCountMock = (override) => ({
containerRepository: {
id: containerRepositoryMock.id,
tagsCount: 13,
+ size: null,
...override,
},
},
@@ -238,6 +239,15 @@ export const graphQLDeleteImageRepositoryTagsMock = {
},
};
+export const graphQLDeleteImageRepositoryTagImportingErrorMock = {
+ data: {
+ destroyContainerRepositoryTags: {
+ errors: ['repository importing'],
+ __typename: 'DestroyContainerRepositoryTagsPayload',
+ },
+ },
+};
+
export const dockerCommands = {
dockerBuildCommand: 'foofoo',
dockerPushCommand: 'barbar',
diff --git a/spec/frontend/packages_and_registries/container_registry/explorer/pages/details_spec.js b/spec/frontend/packages_and_registries/container_registry/explorer/pages/details_spec.js
index c602b37c3b5..59ca47bee50 100644
--- a/spec/frontend/packages_and_registries/container_registry/explorer/pages/details_spec.js
+++ b/spec/frontend/packages_and_registries/container_registry/explorer/pages/details_spec.js
@@ -18,6 +18,7 @@ import {
UNFINISHED_STATUS,
DELETE_SCHEDULED,
ALERT_DANGER_IMAGE,
+ ALERT_DANGER_IMPORTING,
MISSING_OR_DELETED_IMAGE_BREADCRUMB,
ROOT_IMAGE_TEXT,
MISSING_OR_DELETED_IMAGE_TITLE,
@@ -33,6 +34,7 @@ import Tracking from '~/tracking';
import {
graphQLImageDetailsMock,
graphQLDeleteImageRepositoryTagsMock,
+ graphQLDeleteImageRepositoryTagImportingErrorMock,
containerRepositoryMock,
graphQLEmptyImageDetailsMock,
tagsMock,
@@ -329,6 +331,7 @@ describe('Details Page', () => {
const config = {
isAdmin: true,
garbageCollectionHelpPagePath: 'baz',
+ containerRegistryImportingHelpPagePath: 'https://foobar',
};
const deleteAlertType = 'success_tag';
@@ -353,6 +356,35 @@ describe('Details Page', () => {
expect(findDeleteAlert().props()).toEqual({ ...config, deleteAlertType });
});
+
+ describe('importing repository error', () => {
+ let mutationResolver;
+ let tagsResolver;
+
+ beforeEach(async () => {
+ mutationResolver = jest
+ .fn()
+ .mockResolvedValue(graphQLDeleteImageRepositoryTagImportingErrorMock);
+ tagsResolver = jest.fn().mockResolvedValue(graphQLImageDetailsMock(imageTagsMock));
+
+ mountComponent({ mutationResolver, tagsResolver });
+ await waitForApolloRequestRender();
+ });
+
+ it('displays the proper alert', async () => {
+ findTagsList().vm.$emit('delete', [cleanTags[0]]);
+ await nextTick();
+
+ findDeleteModal().vm.$emit('confirmDelete');
+ await waitForPromises();
+
+ expect(tagsResolver).toHaveBeenCalled();
+
+ const deleteAlert = findDeleteAlert();
+ expect(deleteAlert.exists()).toBe(true);
+ expect(deleteAlert.props('deleteAlertType')).toBe(ALERT_DANGER_IMPORTING);
+ });
+ });
});
describe('Partial Cleanup Alert', () => {
diff --git a/spec/frontend/packages_and_registries/container_registry/explorer/pages/list_spec.js b/spec/frontend/packages_and_registries/container_registry/explorer/pages/list_spec.js
index bd126fe532d..da4bfcde217 100644
--- a/spec/frontend/packages_and_registries/container_registry/explorer/pages/list_spec.js
+++ b/spec/frontend/packages_and_registries/container_registry/explorer/pages/list_spec.js
@@ -23,7 +23,7 @@ import deleteContainerRepositoryMutation from '~/packages_and_registries/contain
import getContainerRepositoriesDetails from '~/packages_and_registries/container_registry/explorer/graphql/queries/get_container_repositories_details.query.graphql';
import component from '~/packages_and_registries/container_registry/explorer/pages/list.vue';
import Tracking from '~/tracking';
-import RegistrySearch from '~/vue_shared/components/registry/registry_search.vue';
+import PersistedSearch from '~/packages_and_registries/shared/components/persisted_search.vue';
import TitleArea from '~/vue_shared/components/registry/title_area.vue';
import { $toast } from 'jest/packages_and_registries/shared/mocks';
@@ -55,11 +55,15 @@ describe('List Page', () => {
const findDeleteAlert = () => wrapper.findComponent(GlAlert);
const findImageList = () => wrapper.findComponent(ImageList);
- const findRegistrySearch = () => wrapper.findComponent(RegistrySearch);
+ const findPersistedSearch = () => wrapper.findComponent(PersistedSearch);
const findEmptySearchMessage = () => wrapper.find('[data-testid="emptySearch"]');
const findDeleteImage = () => wrapper.findComponent(DeleteImage);
const findCleanupAlert = () => wrapper.findComponent(CleanupPolicyEnabledAlert);
+ const fireFirstSortUpdate = () => {
+ findPersistedSearch().vm.$emit('update', { sort: 'UPDATED_DESC', filters: [] });
+ };
+
const waitForApolloRequestRender = async () => {
jest.runOnlyPendingTimers();
await waitForPromises();
@@ -117,7 +121,7 @@ describe('List Page', () => {
it('contains registry header', async () => {
mountComponent();
-
+ fireFirstSortUpdate();
await waitForApolloRequestRender();
expect(findRegistryHeader().exists()).toBe(true);
@@ -167,7 +171,7 @@ describe('List Page', () => {
describe('isLoading is true', () => {
it('shows the skeleton loader', async () => {
mountComponent();
-
+ fireFirstSortUpdate();
await nextTick();
expect(findSkeletonLoader().exists()).toBe(true);
@@ -187,7 +191,7 @@ describe('List Page', () => {
it('title has the metadataLoading props set to true', async () => {
mountComponent();
-
+ fireFirstSortUpdate();
await nextTick();
expect(findRegistryHeader().props('metadataLoading')).toBe(true);
@@ -244,6 +248,7 @@ describe('List Page', () => {
describe('unfiltered state', () => {
it('quick start is visible', async () => {
mountComponent();
+ fireFirstSortUpdate();
await waitForApolloRequestRender();
@@ -252,6 +257,7 @@ describe('List Page', () => {
it('list component is visible', async () => {
mountComponent();
+ fireFirstSortUpdate();
await waitForApolloRequestRender();
@@ -264,7 +270,7 @@ describe('List Page', () => {
.fn()
.mockResolvedValue(graphQLProjectImageRepositoriesDetailsMock);
mountComponent({ detailsResolver });
-
+ fireFirstSortUpdate();
jest.runOnlyPendingTimers();
await waitForPromises();
@@ -274,7 +280,7 @@ describe('List Page', () => {
it('does not block the list ui to show', async () => {
const detailsResolver = jest.fn().mockRejectedValue();
mountComponent({ detailsResolver });
-
+ fireFirstSortUpdate();
await waitForApolloRequestRender();
expect(findImageList().exists()).toBe(true);
@@ -285,6 +291,7 @@ describe('List Page', () => {
const detailsResolver = jest.fn().mockImplementation(() => new Promise(() => {}));
mountComponent({ detailsResolver });
+ fireFirstSortUpdate();
await waitForApolloRequestRender();
expect(findImageList().props('metadataLoading')).toBe(true);
@@ -293,6 +300,7 @@ describe('List Page', () => {
describe('delete image', () => {
const selectImageForDeletion = async () => {
+ fireFirstSortUpdate();
await waitForApolloRequestRender();
findImageList().vm.$emit('delete', deletedContainerRepository);
@@ -346,27 +354,27 @@ describe('List Page', () => {
describe('search and sorting', () => {
const doSearch = async () => {
await waitForApolloRequestRender();
- findRegistrySearch().vm.$emit('filter:changed', [
- { type: FILTERED_SEARCH_TERM, value: { data: 'centos6' } },
- ]);
+ findPersistedSearch().vm.$emit('update', {
+ sort: 'UPDATED_DESC',
+ filters: [{ type: FILTERED_SEARCH_TERM, value: { data: 'centos6' } }],
+ });
- findRegistrySearch().vm.$emit('filter:submit');
+ findPersistedSearch().vm.$emit('filter:submit');
await waitForPromises();
};
- it('has a search box element', async () => {
+ it('has a persisted search box element', async () => {
mountComponent();
-
+ fireFirstSortUpdate();
await waitForApolloRequestRender();
- const registrySearch = findRegistrySearch();
+ const registrySearch = findPersistedSearch();
expect(registrySearch.exists()).toBe(true);
expect(registrySearch.props()).toMatchObject({
- filter: [],
- sorting: { orderBy: 'UPDATED', sort: 'desc' },
+ defaultOrder: 'UPDATED',
+ defaultSort: 'desc',
sortableFields: SORT_FIELDS,
- tokens: [],
});
});
@@ -376,7 +384,7 @@ describe('List Page', () => {
await waitForApolloRequestRender();
- findRegistrySearch().vm.$emit('sorting:changed', { sort: 'asc' });
+ findPersistedSearch().vm.$emit('update', { sort: 'UPDATED_DESC', filters: [] });
await nextTick();
expect(resolver).toHaveBeenCalledWith(expect.objectContaining({ sort: 'UPDATED_DESC' }));
@@ -416,7 +424,7 @@ describe('List Page', () => {
.fn()
.mockResolvedValue(graphQLProjectImageRepositoriesDetailsMock);
mountComponent({ resolver, detailsResolver });
-
+ fireFirstSortUpdate();
await waitForApolloRequestRender();
findImageList().vm.$emit('prev-page');
@@ -436,7 +444,7 @@ describe('List Page', () => {
.fn()
.mockResolvedValue(graphQLProjectImageRepositoriesDetailsMock);
mountComponent({ resolver, detailsResolver });
-
+ fireFirstSortUpdate();
await waitForApolloRequestRender();
findImageList().vm.$emit('next-page');
@@ -455,6 +463,7 @@ describe('List Page', () => {
describe('modal', () => {
beforeEach(() => {
mountComponent();
+ fireFirstSortUpdate();
});
it('exists', () => {
@@ -472,6 +481,7 @@ describe('List Page', () => {
describe('tracking', () => {
beforeEach(() => {
mountComponent();
+ fireFirstSortUpdate();
});
const testTrackingCall = (action) => {
@@ -502,62 +512,6 @@ describe('List Page', () => {
});
});
- describe('url query string handling', () => {
- const defaultQueryParams = {
- search: [1, 2],
- sort: 'asc',
- orderBy: 'CREATED',
- };
- const queryChangePayload = 'foo';
-
- it('query:updated event pushes the new query to the router', async () => {
- const push = jest.fn();
- mountComponent({ mocks: { $router: { push } } });
-
- await nextTick();
-
- findRegistrySearch().vm.$emit('query:changed', queryChangePayload);
-
- expect(push).toHaveBeenCalledWith({ query: queryChangePayload });
- });
-
- it('graphql API call has the variables set from the URL', async () => {
- const resolver = jest.fn().mockResolvedValue(graphQLImageListMock);
- mountComponent({ query: defaultQueryParams, resolver });
-
- await nextTick();
-
- expect(resolver).toHaveBeenCalledWith(
- expect.objectContaining({
- name: 1,
- sort: 'CREATED_ASC',
- }),
- );
- });
-
- it.each`
- sort | orderBy | search | payload
- ${'ASC'} | ${undefined} | ${undefined} | ${{ sort: 'UPDATED_ASC' }}
- ${undefined} | ${'bar'} | ${undefined} | ${{ sort: 'BAR_DESC' }}
- ${'ASC'} | ${'bar'} | ${undefined} | ${{ sort: 'BAR_ASC' }}
- ${undefined} | ${undefined} | ${undefined} | ${{}}
- ${undefined} | ${undefined} | ${['one']} | ${{ name: 'one' }}
- ${undefined} | ${undefined} | ${['one', 'two']} | ${{ name: 'one' }}
- ${undefined} | ${'UPDATED'} | ${['one', 'two']} | ${{ name: 'one', sort: 'UPDATED_DESC' }}
- ${'ASC'} | ${'UPDATED'} | ${['one', 'two']} | ${{ name: 'one', sort: 'UPDATED_ASC' }}
- `(
- 'with sort equal to $sort, orderBy equal to $orderBy, search set to $search API call has the variables set as $payload',
- async ({ sort, orderBy, search, payload }) => {
- const resolver = jest.fn().mockResolvedValue({ sort, orderBy });
- mountComponent({ query: { sort, orderBy, search }, resolver });
-
- await nextTick();
-
- expect(resolver).toHaveBeenCalledWith(expect.objectContaining(payload));
- },
- );
- });
-
describe('cleanup is on alert', () => {
it('exist when showCleanupPolicyOnAlert is true and has the correct props', async () => {
mountComponent({
diff --git a/spec/frontend/packages_and_registries/settings/project/settings/components/__snapshots__/settings_form_spec.js.snap b/spec/frontend/packages_and_registries/settings/project/settings/components/__snapshots__/settings_form_spec.js.snap
index 9938357ed24..841a9bf8290 100644
--- a/spec/frontend/packages_and_registries/settings/project/settings/components/__snapshots__/settings_form_spec.js.snap
+++ b/spec/frontend/packages_and_registries/settings/project/settings/components/__snapshots__/settings_form_spec.js.snap
@@ -58,7 +58,7 @@ exports[`Settings Form Remove regex matches snapshot 1`] = `
error=""
label="Remove tags matching:"
name="remove-regex"
- placeholder=".*"
+ placeholder=""
value="asdasdssssdfdf"
/>
`;
diff --git a/spec/frontend/packages_and_registries/settings/project/settings/components/settings_form_spec.js b/spec/frontend/packages_and_registries/settings/project/settings/components/settings_form_spec.js
index 625aa37fc0f..266f953c3e0 100644
--- a/spec/frontend/packages_and_registries/settings/project/settings/components/settings_form_spec.js
+++ b/spec/frontend/packages_and_registries/settings/project/settings/components/settings_form_spec.js
@@ -49,6 +49,11 @@ describe('Settings Form', () => {
const findOlderThanDropdown = () => wrapper.find('[data-testid="older-than-dropdown"]');
const findRemoveRegexInput = () => wrapper.find('[data-testid="remove-regex-input"]');
+ const submitForm = async () => {
+ findForm().trigger('submit');
+ return waitForPromises();
+ };
+
const mountComponent = ({
props = defaultProps,
data,
@@ -318,27 +323,24 @@ describe('Settings Form', () => {
mutationResolver: jest.fn().mockResolvedValue(expirationPolicyMutationPayload()),
});
- findForm().trigger('submit');
- await waitForPromises();
- await nextTick();
+ await submitForm();
expect(wrapper.vm.$toast.show).toHaveBeenCalledWith(UPDATE_SETTINGS_SUCCESS_MESSAGE);
});
describe('when submit fails', () => {
describe('user recoverable errors', () => {
- it('when there is an error is shown in a toast', async () => {
+ it('when there is an error is shown in the nameRegex field t', async () => {
mountComponentWithApollo({
mutationResolver: jest
.fn()
.mockResolvedValue(expirationPolicyMutationPayload({ errors: ['foo'] })),
});
- findForm().trigger('submit');
- await waitForPromises();
- await nextTick();
+ await submitForm();
- expect(wrapper.vm.$toast.show).toHaveBeenCalledWith('foo');
+ expect(wrapper.vm.$toast.show).toHaveBeenCalledWith(UPDATE_SETTINGS_ERROR_MESSAGE);
+ expect(findRemoveRegexInput().props('error')).toBe('foo');
});
});
@@ -348,9 +350,7 @@ describe('Settings Form', () => {
mutationResolver: jest.fn().mockRejectedValue(expirationPolicyMutationPayload()),
});
- findForm().trigger('submit');
- await waitForPromises();
- await nextTick();
+ await submitForm();
expect(wrapper.vm.$toast.show).toHaveBeenCalledWith(UPDATE_SETTINGS_ERROR_MESSAGE);
});
@@ -367,9 +367,7 @@ describe('Settings Form', () => {
});
mountComponent({ mocks: { $apollo: { mutate } } });
- findForm().trigger('submit');
- await waitForPromises();
- await nextTick();
+ await submitForm();
expect(findKeepRegexInput().props('error')).toEqual('baz');
});
diff --git a/spec/frontend/packages_and_registries/settings/project/settings/graphql/cache_updated_spec.js b/spec/frontend/packages_and_registries/settings/project/settings/graphql/cache_updated_spec.js
index 4d6bd65bd93..76d5f8a6659 100644
--- a/spec/frontend/packages_and_registries/settings/project/settings/graphql/cache_updated_spec.js
+++ b/spec/frontend/packages_and_registries/settings/project/settings/graphql/cache_updated_spec.js
@@ -4,15 +4,15 @@ import { updateContainerExpirationPolicy } from '~/packages_and_registries/setti
describe('Registry settings cache update', () => {
let client;
- const payload = {
+ const payload = (value) => ({
data: {
updateContainerExpirationPolicy: {
containerExpirationPolicy: {
- enabled: true,
+ ...value,
},
},
},
- };
+ });
const cacheMock = {
project: {
@@ -35,12 +35,12 @@ describe('Registry settings cache update', () => {
});
describe('Registry settings cache update', () => {
it('calls readQuery', () => {
- updateContainerExpirationPolicy('foo')(client, payload);
+ updateContainerExpirationPolicy('foo')(client, payload({ enabled: true }));
expect(client.readQuery).toHaveBeenCalledWith(queryAndVariables);
});
it('writes the correct result in the cache', () => {
- updateContainerExpirationPolicy('foo')(client, payload);
+ updateContainerExpirationPolicy('foo')(client, payload({ enabled: true }));
expect(client.writeQuery).toHaveBeenCalledWith({
...queryAndVariables,
data: {
@@ -52,5 +52,20 @@ describe('Registry settings cache update', () => {
},
});
});
+
+ it('with an empty update preserves the state', () => {
+ updateContainerExpirationPolicy('foo')(client, payload());
+
+ expect(client.writeQuery).toHaveBeenCalledWith({
+ ...queryAndVariables,
+ data: {
+ project: {
+ containerExpirationPolicy: {
+ enabled: false,
+ },
+ },
+ },
+ });
+ });
});
});
diff --git a/spec/frontend/pages/projects/forks/new/components/app_spec.js b/spec/frontend/pages/projects/forks/new/components/app_spec.js
index a7b4b9c42bd..0342b94a44d 100644
--- a/spec/frontend/pages/projects/forks/new/components/app_spec.js
+++ b/spec/frontend/pages/projects/forks/new/components/app_spec.js
@@ -1,19 +1,12 @@
import { shallowMount } from '@vue/test-utils';
import App from '~/pages/projects/forks/new/components/app.vue';
+import ForkForm from '~/pages/projects/forks/new/components/fork_form.vue';
describe('App component', () => {
let wrapper;
const DEFAULT_PROPS = {
forkIllustration: 'illustrations/project-create-new-sm.svg',
- endpoint: '/some/project-full-path/-/forks/new.json',
- projectFullPath: '/some/project-full-path',
- projectId: '10',
- projectName: 'Project Name',
- projectPath: 'project-name',
- projectDescription: 'some project description',
- projectVisibility: 'private',
- restrictedVisibilityLevels: [],
};
const createComponent = (props = {}) => {
@@ -37,7 +30,7 @@ describe('App component', () => {
expect(wrapper.find('img').attributes('src')).toBe('illustrations/project-create-new-sm.svg');
});
- it('renders ForkForm component with prop', () => {
- expect(wrapper.props()).toEqual(expect.objectContaining(DEFAULT_PROPS));
+ it('renders ForkForm component', () => {
+ expect(wrapper.findComponent(ForkForm).exists()).toBe(true);
});
});
diff --git a/spec/frontend/pages/projects/forks/new/components/fork_form_spec.js b/spec/frontend/pages/projects/forks/new/components/fork_form_spec.js
index dc5f1cb9e61..efbfd83a071 100644
--- a/spec/frontend/pages/projects/forks/new/components/fork_form_spec.js
+++ b/spec/frontend/pages/projects/forks/new/components/fork_form_spec.js
@@ -40,7 +40,9 @@ describe('ForkForm component', () => {
},
];
- const DEFAULT_PROPS = {
+ const DEFAULT_PROVIDE = {
+ newGroupPath: 'some/groups/path',
+ visibilityHelpPath: 'some/visibility/help/path',
endpoint: '/some/project-full-path/-/forks/new.json',
projectFullPath: '/some/project-full-path',
projectId: '10',
@@ -52,18 +54,14 @@ describe('ForkForm component', () => {
};
const mockGetRequest = (data = {}, statusCode = httpStatus.OK) => {
- axiosMock.onGet(DEFAULT_PROPS.endpoint).replyOnce(statusCode, data);
+ axiosMock.onGet(DEFAULT_PROVIDE.endpoint).replyOnce(statusCode, data);
};
- const createComponentFactory = (mountFn) => (props = {}, data = {}) => {
+ const createComponentFactory = (mountFn) => (provide = {}, data = {}) => {
wrapper = mountFn(ForkForm, {
provide: {
- newGroupPath: 'some/groups/path',
- visibilityHelpPath: 'some/visibility/help/path',
- },
- propsData: {
- ...DEFAULT_PROPS,
- ...props,
+ ...DEFAULT_PROVIDE,
+ ...provide,
},
data() {
return {
@@ -111,7 +109,7 @@ describe('ForkForm component', () => {
mockGetRequest();
createComponent();
- const { projectFullPath } = DEFAULT_PROPS;
+ const { projectFullPath } = DEFAULT_PROVIDE;
const cancelButton = wrapper.find('[data-testid="cancel-button"]');
expect(cancelButton.attributes('href')).toBe(projectFullPath);
@@ -130,10 +128,10 @@ describe('ForkForm component', () => {
mockGetRequest();
createComponent();
- expect(findForkNameInput().attributes('value')).toBe(DEFAULT_PROPS.projectName);
- expect(findForkSlugInput().attributes('value')).toBe(DEFAULT_PROPS.projectPath);
+ expect(findForkNameInput().attributes('value')).toBe(DEFAULT_PROVIDE.projectName);
+ expect(findForkSlugInput().attributes('value')).toBe(DEFAULT_PROVIDE.projectPath);
expect(findForkDescriptionTextarea().attributes('value')).toBe(
- DEFAULT_PROPS.projectDescription,
+ DEFAULT_PROVIDE.projectDescription,
);
});
@@ -164,7 +162,7 @@ describe('ForkForm component', () => {
it('make GET request from endpoint', async () => {
await axios.waitForAll();
- expect(axiosMock.history.get[0].url).toBe(DEFAULT_PROPS.endpoint);
+ expect(axiosMock.history.get[0].url).toBe(DEFAULT_PROVIDE.endpoint);
});
it('generate default option', async () => {
@@ -469,7 +467,7 @@ describe('ForkForm component', () => {
projectName,
projectPath,
projectVisibility,
- } = DEFAULT_PROPS;
+ } = DEFAULT_PROVIDE;
const url = `/api/${GON_API_VERSION}/projects/${projectId}/fork`;
const project = {
diff --git a/spec/frontend/pages/projects/forks/new/components/fork_groups_list_item_spec.js b/spec/frontend/pages/projects/forks/new/components/fork_groups_list_item_spec.js
deleted file mode 100644
index 490dafed4ae..00000000000
--- a/spec/frontend/pages/projects/forks/new/components/fork_groups_list_item_spec.js
+++ /dev/null
@@ -1,73 +0,0 @@
-import { GlBadge, GlButton, GlLink } from '@gitlab/ui';
-import { shallowMount } from '@vue/test-utils';
-import ForkGroupsListItem from '~/pages/projects/forks/new/components/fork_groups_list_item.vue';
-
-describe('Fork groups list item component', () => {
- let wrapper;
-
- const DEFAULT_GROUP_DATA = {
- id: 22,
- name: 'Gitlab Org',
- description: 'Ad et ipsam earum id aut nobis.',
- visibility: 'public',
- full_name: 'Gitlab Org',
- created_at: '2020-06-22T03:32:05.664Z',
- updated_at: '2020-06-22T03:32:05.664Z',
- avatar_url: null,
- fork_path: '/twitter/typeahead-js/-/forks?namespace_key=22',
- forked_project_path: null,
- permission: 'Owner',
- relative_path: '/gitlab-org',
- markdown_description:
- '<p data-sourcepos="1:1-1:31" dir="auto">Ad et ipsam earum id aut nobis.</p>',
- can_create_project: true,
- marked_for_deletion: false,
- };
-
- const DUMMY_PATH = '/dummy/path';
-
- const createWrapper = (propsData) => {
- wrapper = shallowMount(ForkGroupsListItem, {
- propsData: {
- ...propsData,
- },
- });
- };
-
- it('renders pending deletion badge if applicable', () => {
- createWrapper({ group: { ...DEFAULT_GROUP_DATA, marked_for_deletion: true } });
-
- expect(wrapper.find(GlBadge).text()).toBe('pending deletion');
- });
-
- it('renders go to fork button if has forked project', () => {
- createWrapper({ group: { ...DEFAULT_GROUP_DATA, forked_project_path: DUMMY_PATH } });
-
- expect(wrapper.find(GlButton).text()).toBe('Go to fork');
- expect(wrapper.find(GlButton).attributes().href).toBe(DUMMY_PATH);
- });
-
- it('renders select button if has no forked project', () => {
- createWrapper({
- group: { ...DEFAULT_GROUP_DATA, forked_project_path: null, fork_path: DUMMY_PATH },
- });
-
- expect(wrapper.find(GlButton).text()).toBe('Select');
- expect(wrapper.find('form').attributes().action).toBe(DUMMY_PATH);
- });
-
- it('renders link to current group', () => {
- const DUMMY_FULL_NAME = 'dummy';
- createWrapper({
- group: { ...DEFAULT_GROUP_DATA, relative_path: DUMMY_PATH, full_name: DUMMY_FULL_NAME },
- });
-
- expect(
- wrapper
- .findAll(GlLink)
- .filter((w) => w.text() === DUMMY_FULL_NAME)
- .at(0)
- .attributes().href,
- ).toBe(DUMMY_PATH);
- });
-});
diff --git a/spec/frontend/pages/projects/forks/new/components/fork_groups_list_spec.js b/spec/frontend/pages/projects/forks/new/components/fork_groups_list_spec.js
deleted file mode 100644
index 9f8dbf3d542..00000000000
--- a/spec/frontend/pages/projects/forks/new/components/fork_groups_list_spec.js
+++ /dev/null
@@ -1,123 +0,0 @@
-import { GlLoadingIcon, GlSearchBoxByType } from '@gitlab/ui';
-import { shallowMount } from '@vue/test-utils';
-import AxiosMockAdapter from 'axios-mock-adapter';
-import { nextTick } from 'vue';
-import waitForPromises from 'helpers/wait_for_promises';
-import createFlash from '~/flash';
-import axios from '~/lib/utils/axios_utils';
-import ForkGroupsList from '~/pages/projects/forks/new/components/fork_groups_list.vue';
-import ForkGroupsListItem from '~/pages/projects/forks/new/components/fork_groups_list_item.vue';
-
-jest.mock('~/flash');
-
-describe('Fork groups list component', () => {
- let wrapper;
- let axiosMock;
-
- const DEFAULT_PROPS = {
- endpoint: '/dummy',
- };
-
- const replyWith = (...args) => axiosMock.onGet(DEFAULT_PROPS.endpoint).reply(...args);
-
- const createWrapper = (propsData) => {
- wrapper = shallowMount(ForkGroupsList, {
- propsData: {
- ...DEFAULT_PROPS,
- ...propsData,
- },
- stubs: {
- GlTabs: {
- template: '<div><slot></slot><slot name="tabs-end"></slot></div>',
- },
- },
- });
- };
-
- beforeEach(() => {
- axiosMock = new AxiosMockAdapter(axios);
- });
-
- afterEach(() => {
- axiosMock.reset();
-
- if (wrapper) {
- wrapper.destroy();
- wrapper = null;
- }
- });
-
- it('fires load groups request on mount', async () => {
- replyWith(200, { namespaces: [] });
- createWrapper();
-
- await waitForPromises();
-
- expect(axiosMock.history.get[0].url).toBe(DEFAULT_PROPS.endpoint);
- });
-
- it('displays flash if loading groups fails', async () => {
- replyWith(500);
- createWrapper();
-
- await waitForPromises();
-
- expect(createFlash).toHaveBeenCalled();
- });
-
- it('displays loading indicator while loading groups', () => {
- replyWith(() => new Promise(() => {}));
- createWrapper();
-
- expect(wrapper.find(GlLoadingIcon).exists()).toBe(true);
- });
-
- it('displays empty text if no groups are available', async () => {
- const EMPTY_TEXT = 'No available groups to fork the project.';
- replyWith(200, { namespaces: [] });
- createWrapper();
-
- await waitForPromises();
-
- expect(wrapper.text()).toContain(EMPTY_TEXT);
- });
-
- it('displays filter field when groups are available', async () => {
- replyWith(200, { namespaces: [{ name: 'dummy1' }, { name: 'dummy2' }] });
- createWrapper();
-
- await waitForPromises();
-
- expect(wrapper.find(GlSearchBoxByType).exists()).toBe(true);
- });
-
- it('renders list items for each available group', async () => {
- const namespaces = [{ name: 'dummy1' }, { name: 'dummy2' }, { name: 'otherdummy' }];
-
- replyWith(200, { namespaces });
- createWrapper();
-
- await waitForPromises();
-
- expect(wrapper.findAll(ForkGroupsListItem)).toHaveLength(namespaces.length);
-
- namespaces.forEach((namespace, idx) => {
- expect(wrapper.findAll(ForkGroupsListItem).at(idx).props()).toStrictEqual({
- group: namespace,
- });
- });
- });
-
- it('filters repositories on the fly', async () => {
- replyWith(200, {
- namespaces: [{ name: 'dummy1' }, { name: 'dummy2' }, { name: 'otherdummy' }],
- });
- createWrapper();
- await waitForPromises();
- wrapper.find(GlSearchBoxByType).vm.$emit('input', 'other');
- await nextTick();
-
- expect(wrapper.findAll(ForkGroupsListItem)).toHaveLength(1);
- expect(wrapper.findAll(ForkGroupsListItem).at(0).props().group.name).toBe('otherdummy');
- });
-});
diff --git a/spec/frontend/pages/projects/learn_gitlab/components/__snapshots__/learn_gitlab_spec.js.snap b/spec/frontend/pages/projects/learn_gitlab/components/__snapshots__/learn_gitlab_spec.js.snap
index 86ccaa43786..62cf769cffd 100644
--- a/spec/frontend/pages/projects/learn_gitlab/components/__snapshots__/learn_gitlab_spec.js.snap
+++ b/spec/frontend/pages/projects/learn_gitlab/components/__snapshots__/learn_gitlab_spec.js.snap
@@ -137,9 +137,7 @@ exports[`Learn GitLab renders correctly 1`] = `
class="gl-link"
data-testid="uncompleted-learn-gitlab-link"
data-track-action="click_link"
- data-track-experiment="change_continuous_onboarding_link_urls"
data-track-label="Set up CI/CD"
- data-track-property="Growth::Conversion::Experiment::LearnGitLab"
href="http://example.com/"
target="_self"
>
@@ -157,9 +155,7 @@ exports[`Learn GitLab renders correctly 1`] = `
class="gl-link"
data-testid="uncompleted-learn-gitlab-link"
data-track-action="click_link"
- data-track-experiment="change_continuous_onboarding_link_urls"
data-track-label="Start a free Ultimate trial"
- data-track-property="Growth::Conversion::Experiment::LearnGitLab"
href="http://example.com/"
target="_self"
>
@@ -177,9 +173,7 @@ exports[`Learn GitLab renders correctly 1`] = `
class="gl-link"
data-testid="uncompleted-learn-gitlab-link"
data-track-action="click_link"
- data-track-experiment="change_continuous_onboarding_link_urls"
data-track-label="Add code owners"
- data-track-property="Growth::Conversion::Experiment::LearnGitLab"
href="http://example.com/"
target="_self"
>
@@ -204,9 +198,7 @@ exports[`Learn GitLab renders correctly 1`] = `
class="gl-link"
data-testid="uncompleted-learn-gitlab-link"
data-track-action="click_link"
- data-track-experiment="change_continuous_onboarding_link_urls"
data-track-label="Add merge request approval"
- data-track-property="Growth::Conversion::Experiment::LearnGitLab"
href="http://example.com/"
target="_self"
>
@@ -267,9 +259,7 @@ exports[`Learn GitLab renders correctly 1`] = `
class="gl-link"
data-testid="uncompleted-learn-gitlab-link"
data-track-action="click_link"
- data-track-experiment="change_continuous_onboarding_link_urls"
data-track-label="Create an issue"
- data-track-property="Growth::Conversion::Experiment::LearnGitLab"
href="http://example.com/"
target="_self"
>
@@ -287,9 +277,7 @@ exports[`Learn GitLab renders correctly 1`] = `
class="gl-link"
data-testid="uncompleted-learn-gitlab-link"
data-track-action="click_link"
- data-track-experiment="change_continuous_onboarding_link_urls"
data-track-label="Submit a merge request"
- data-track-property="Growth::Conversion::Experiment::LearnGitLab"
href="http://example.com/"
target="_self"
>
@@ -343,9 +331,7 @@ exports[`Learn GitLab renders correctly 1`] = `
class="gl-link"
data-testid="uncompleted-learn-gitlab-link"
data-track-action="click_link"
- data-track-experiment="change_continuous_onboarding_link_urls"
data-track-label="Run a Security scan using CI/CD"
- data-track-property="Growth::Conversion::Experiment::LearnGitLab"
href="https://docs.gitlab.com/ee/foobar/"
rel="noopener noreferrer"
target="_blank"
diff --git a/spec/frontend/pages/projects/learn_gitlab/components/learn_gitlab_section_link_spec.js b/spec/frontend/pages/projects/learn_gitlab/components/learn_gitlab_section_link_spec.js
index 3b113f4dcd7..e21371123e8 100644
--- a/spec/frontend/pages/projects/learn_gitlab/components/learn_gitlab_section_link_spec.js
+++ b/spec/frontend/pages/projects/learn_gitlab/components/learn_gitlab_section_link_spec.js
@@ -12,8 +12,9 @@ const defaultProps = {
completed: false,
};
-const docLinkProps = {
+const openInNewTabProps = {
url: 'https://docs.gitlab.com/ee/user/application_security/security_dashboard/',
+ openInNewTab: true,
};
describe('Learn GitLab Section Link', () => {
@@ -59,9 +60,9 @@ describe('Learn GitLab Section Link', () => {
expect(wrapper.find('[data-testid="trial-only"]').exists()).toBe(true);
});
- describe('doc links', () => {
+ describe('links marked with openInNewTab', () => {
beforeEach(() => {
- createWrapper('securityScanEnabled', docLinkProps);
+ createWrapper('securityScanEnabled', openInNewTabProps);
});
it('renders links with blank target', () => {
@@ -78,7 +79,6 @@ describe('Learn GitLab Section Link', () => {
expect(trackingSpy).toHaveBeenCalledWith('_category_', 'click_link', {
label: 'Run a Security scan using CI/CD',
- property: 'Growth::Conversion::Experiment::LearnGitLab',
});
unmockTracking();
diff --git a/spec/frontend/pages/projects/learn_gitlab/components/learn_gitlab_spec.js b/spec/frontend/pages/projects/learn_gitlab/components/learn_gitlab_spec.js
index ee682b18af3..5f1aff99578 100644
--- a/spec/frontend/pages/projects/learn_gitlab/components/learn_gitlab_spec.js
+++ b/spec/frontend/pages/projects/learn_gitlab/components/learn_gitlab_spec.js
@@ -9,7 +9,6 @@ import { testActions, testSections, testProject } from './mock_data';
describe('Learn GitLab', () => {
let wrapper;
let sidebar;
- let inviteMembers = false;
const createWrapper = () => {
wrapper = mount(LearnGitlab, {
@@ -17,7 +16,6 @@ describe('Learn GitLab', () => {
actions: testActions,
sections: testSections,
project: testProject,
- inviteMembers,
},
});
};
@@ -38,7 +36,6 @@ describe('Learn GitLab', () => {
afterEach(() => {
wrapper.destroy();
wrapper = null;
- inviteMembers = false;
sidebar.remove();
});
@@ -73,7 +70,6 @@ describe('Learn GitLab', () => {
});
it('emits openModal', () => {
- inviteMembers = true;
Cookies.set(INVITE_MODAL_OPEN_COOKIE, true);
createWrapper();
@@ -86,19 +82,11 @@ describe('Learn GitLab', () => {
});
it('does not emit openModal when cookie is not set', () => {
- inviteMembers = true;
-
createWrapper();
expect(spy).not.toHaveBeenCalled();
expect(cookieSpy).toHaveBeenCalledWith(INVITE_MODAL_OPEN_COOKIE);
});
-
- it('does not emit openModal when inviteMembers is false', () => {
- createWrapper();
-
- expect(spy).not.toHaveBeenCalled();
- });
});
describe('when the showSuccessfulInvitationsAlert event is fired', () => {
diff --git a/spec/frontend/pages/projects/learn_gitlab/components/mock_data.js b/spec/frontend/pages/projects/learn_gitlab/components/mock_data.js
index b21965e8f48..5dc64097d81 100644
--- a/spec/frontend/pages/projects/learn_gitlab/components/mock_data.js
+++ b/spec/frontend/pages/projects/learn_gitlab/components/mock_data.js
@@ -38,6 +38,7 @@ export const testActions = {
url: 'https://docs.gitlab.com/ee/foobar/',
completed: false,
svg: 'http://example.com/images/illustration.svg',
+ openInNewTab: true,
},
issueCreated: {
url: 'http://example.com/',
diff --git a/spec/frontend/pages/projects/pages_domains/form_spec.js b/spec/frontend/pages/projects/pages_domains/form_spec.js
new file mode 100644
index 00000000000..55336596f30
--- /dev/null
+++ b/spec/frontend/pages/projects/pages_domains/form_spec.js
@@ -0,0 +1,82 @@
+import initForm from '~/pages/projects/pages_domains/form';
+
+const ENABLED_UNLESS_AUTO_SSL_CLASS = 'js-enabled-unless-auto-ssl';
+const SSL_TOGGLE_CLASS = 'js-enable-ssl-gl-toggle';
+const SSL_TOGGLE_INPUT_CLASS = 'js-project-feature-toggle-input';
+const SHOW_IF_AUTO_SSL_CLASS = 'js-shown-if-auto-ssl';
+const SHOW_UNLESS_AUTO_SSL_CLASS = 'js-shown-unless-auto-ssl';
+const D_NONE_CLASS = 'd-none';
+
+describe('Page domains form', () => {
+ let toggle;
+
+ const findEnabledUnless = () => document.querySelector(`.${ENABLED_UNLESS_AUTO_SSL_CLASS}`);
+ const findSslToggle = () => document.querySelector(`.${SSL_TOGGLE_CLASS} button`);
+ const findSslToggleInput = () => document.querySelector(`.${SSL_TOGGLE_INPUT_CLASS}`);
+ const findIfAutoSsl = () => document.querySelector(`.${SHOW_IF_AUTO_SSL_CLASS}`);
+ const findUnlessAutoSsl = () => document.querySelector(`.${SHOW_UNLESS_AUTO_SSL_CLASS}`);
+
+ const create = () => {
+ setFixtures(`
+ <form>
+ <span
+ class="${SSL_TOGGLE_CLASS}"
+ data-label="SSL toggle"
+ ></span>
+ <input class="${SSL_TOGGLE_INPUT_CLASS}" type="hidden" />
+ <span class="${SHOW_UNLESS_AUTO_SSL_CLASS}"></span>
+ <span class="${SHOW_IF_AUTO_SSL_CLASS}"></span>
+ <button class="${ENABLED_UNLESS_AUTO_SSL_CLASS}"></button>
+ </form>
+ `);
+ };
+
+ it('instantiates the toggle', () => {
+ create();
+ initForm();
+
+ expect(findSslToggle()).not.toBe(null);
+ });
+
+ describe('when auto SSL is enabled', () => {
+ beforeEach(() => {
+ create();
+ toggle = initForm();
+ toggle.$emit('change', true);
+ });
+
+ it('sets the correct classes', () => {
+ expect(Array.from(findIfAutoSsl().classList)).not.toContain(D_NONE_CLASS);
+ expect(Array.from(findUnlessAutoSsl().classList)).toContain(D_NONE_CLASS);
+ });
+
+ it('sets the correct disabled value', () => {
+ expect(findEnabledUnless().getAttribute('disabled')).toBe('disabled');
+ });
+
+ it('sets the correct value for the input', () => {
+ expect(findSslToggleInput().getAttribute('value')).toBe('true');
+ });
+ });
+
+ describe('when auto SSL is not enabled', () => {
+ beforeEach(() => {
+ create();
+ toggle = initForm();
+ toggle.$emit('change', false);
+ });
+
+ it('sets the correct classes', () => {
+ expect(Array.from(findIfAutoSsl().classList)).toContain(D_NONE_CLASS);
+ expect(Array.from(findUnlessAutoSsl().classList)).not.toContain(D_NONE_CLASS);
+ });
+
+ it('sets the correct disabled value', () => {
+ expect(findUnlessAutoSsl().getAttribute('disabled')).toBe(null);
+ });
+
+ it('sets the correct value for the input', () => {
+ expect(findSslToggleInput().getAttribute('value')).toBe('false');
+ });
+ });
+});
diff --git a/spec/frontend/pages/shared/wikis/components/wiki_form_spec.js b/spec/frontend/pages/shared/wikis/components/wiki_form_spec.js
index 1f964e8bae2..e118a35804f 100644
--- a/spec/frontend/pages/shared/wikis/components/wiki_form_spec.js
+++ b/spec/frontend/pages/shared/wikis/components/wiki_form_spec.js
@@ -155,6 +155,20 @@ describe('WikiForm', () => {
});
it.each`
+ format | enabled | action
+ ${'markdown'} | ${true} | ${'displays'}
+ ${'rdoc'} | ${false} | ${'hides'}
+ ${'asciidoc'} | ${false} | ${'hides'}
+ ${'org'} | ${false} | ${'hides'}
+ `('$action preview in the markdown field when format is $format', async ({ format, enabled }) => {
+ createWrapper();
+
+ await setFormat(format);
+
+ expect(findClassicEditor().props('enablePreview')).toBe(enabled);
+ });
+
+ it.each`
value | text
${'markdown'} | ${'[Link Title](page-slug)'}
${'rdoc'} | ${'{Link title}[link:page-slug]'}
diff --git a/spec/frontend/performance_bar/components/detailed_metric_spec.js b/spec/frontend/performance_bar/components/detailed_metric_spec.js
index c35bd772c86..2ae36740dfb 100644
--- a/spec/frontend/performance_bar/components/detailed_metric_spec.js
+++ b/spec/frontend/performance_bar/components/detailed_metric_spec.js
@@ -1,10 +1,11 @@
import { shallowMount } from '@vue/test-utils';
+import { GlDropdownItem } from '@gitlab/ui';
import { nextTick } from 'vue';
import { trimText } from 'helpers/text_helper';
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import DetailedMetric from '~/performance_bar/components/detailed_metric.vue';
import RequestWarning from '~/performance_bar/components/request_warning.vue';
-import { sortOrders } from '~/performance_bar/constants';
+import { sortOrders, sortOrderOptions } from '~/performance_bar/constants';
describe('detailedMetric', () => {
let wrapper;
@@ -29,7 +30,13 @@ describe('detailedMetric', () => {
const findExpandBacktraceBtns = () => wrapper.findAllByTestId('backtrace-expand-btn');
const findExpandedBacktraceBtnAtIndex = (index) => findExpandBacktraceBtns().at(index);
const findDetailsLabel = () => wrapper.findByTestId('performance-bar-details-label');
- const findSortOrderSwitcher = () => wrapper.findByTestId('performance-bar-sort-order');
+ const findSortOrderDropdown = () => wrapper.findByTestId('performance-bar-sort-order');
+ const clickSortOrderDropdownItem = (sortOrder) =>
+ findSortOrderDropdown()
+ .findAllComponents(GlDropdownItem)
+ .filter((item) => item.text() === sortOrderOptions[sortOrder])
+ .at(0)
+ .vm.$emit('click');
const findEmptyDetailNotice = () => wrapper.findByTestId('performance-bar-empty-detail-notice');
const findAllDetailDurations = () =>
wrapper.findAllByTestId('performance-item-duration').wrappers.map((w) => w.text());
@@ -86,7 +93,7 @@ describe('detailedMetric', () => {
});
it('does not display sort by switcher', () => {
- expect(findSortOrderSwitcher().exists()).toBe(false);
+ expect(findSortOrderDropdown().exists()).toBe(false);
});
});
@@ -216,7 +223,7 @@ describe('detailedMetric', () => {
});
it('does not display sort by switcher', () => {
- expect(findSortOrderSwitcher().exists()).toBe(false);
+ expect(findSortOrderDropdown().exists()).toBe(false);
});
it('adds a modal with a table of the details', () => {
@@ -323,14 +330,15 @@ describe('detailedMetric', () => {
});
it('displays sort by switcher', () => {
- expect(findSortOrderSwitcher().exists()).toBe(true);
+ expect(findSortOrderDropdown().exists()).toBe(true);
});
- it('allows switch sorting orders', async () => {
- findSortOrderSwitcher().vm.$emit('input', sortOrders.CHRONOLOGICAL);
+ it('changes sortOrder on select', async () => {
+ clickSortOrderDropdownItem(sortOrders.CHRONOLOGICAL);
await nextTick();
expect(findAllDetailDurations()).toEqual(['23ms', '100ms', '75ms']);
- findSortOrderSwitcher().vm.$emit('input', sortOrders.DURATION);
+
+ clickSortOrderDropdownItem(sortOrders.DURATION);
await nextTick();
expect(findAllDetailDurations()).toEqual(['100ms', '75ms', '23ms']);
});
diff --git a/spec/frontend/performance_bar/components/performance_bar_app_spec.js b/spec/frontend/performance_bar/components/performance_bar_app_spec.js
index 67a4259a8e3..2c9ab4bf78d 100644
--- a/spec/frontend/performance_bar/components/performance_bar_app_spec.js
+++ b/spec/frontend/performance_bar/components/performance_bar_app_spec.js
@@ -18,4 +18,15 @@ describe('performance bar app', () => {
it('sets the class to match the environment', () => {
expect(wrapper.element.getAttribute('class')).toContain('development');
});
+
+ describe('changeCurrentRequest', () => {
+ it('emits a change-request event', () => {
+ expect(wrapper.emitted('change-request')).toBeUndefined();
+
+ wrapper.vm.changeCurrentRequest('123');
+
+ expect(wrapper.emitted('change-request')).toBeDefined();
+ expect(wrapper.emitted('change-request')[0]).toEqual(['123']);
+ });
+ });
});
diff --git a/spec/frontend/performance_bar/components/request_selector_spec.js b/spec/frontend/performance_bar/components/request_selector_spec.js
deleted file mode 100644
index 9cc8c5e73f4..00000000000
--- a/spec/frontend/performance_bar/components/request_selector_spec.js
+++ /dev/null
@@ -1,31 +0,0 @@
-import { shallowMount } from '@vue/test-utils';
-import RequestSelector from '~/performance_bar/components/request_selector.vue';
-
-describe('request selector', () => {
- const requests = [
- {
- id: 'warningReq',
- url: 'https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/1/discussions.json',
- truncatedUrl: 'discussions.json',
- hasWarnings: true,
- },
- ];
-
- const wrapper = shallowMount(RequestSelector, {
- propsData: {
- requests,
- currentRequest: requests[0],
- },
- });
-
- it('has a warning icon if any requests have warnings', () => {
- expect(wrapper.find('span > gl-emoji').element.dataset.name).toEqual('warning');
- });
-
- it('adds a warning glyph to requests with warnings', () => {
- const requestValue = wrapper.find('[value="warningReq"]').text();
-
- expect(requestValue).toContain('discussions.json');
- expect(requestValue).toContain('(!)');
- });
-});
diff --git a/spec/frontend/performance_bar/index_spec.js b/spec/frontend/performance_bar/index_spec.js
index 819b2bcbacf..91cb46002be 100644
--- a/spec/frontend/performance_bar/index_spec.js
+++ b/spec/frontend/performance_bar/index_spec.js
@@ -51,7 +51,7 @@ describe('performance bar wrapper', () => {
mock.restore();
});
- describe('loadRequestDetails', () => {
+ describe('addRequest', () => {
beforeEach(() => {
jest.spyOn(vm.store, 'addRequest');
});
@@ -59,26 +59,46 @@ describe('performance bar wrapper', () => {
it('does nothing if the request cannot be tracked', () => {
jest.spyOn(vm.store, 'canTrackRequest').mockImplementation(() => false);
- vm.loadRequestDetails('123', 'https://gitlab.com/');
+ vm.addRequest('123', 'https://gitlab.com/');
expect(vm.store.addRequest).not.toHaveBeenCalled();
});
it('adds the request immediately', () => {
- vm.loadRequestDetails('123', 'https://gitlab.com/');
+ vm.addRequest('123', 'https://gitlab.com/');
expect(vm.store.addRequest).toHaveBeenCalledWith('123', 'https://gitlab.com/');
});
+ });
- it('makes an HTTP request for the request details', () => {
+ describe('loadRequestDetails', () => {
+ beforeEach(() => {
jest.spyOn(PerformanceBarService, 'fetchRequestDetails');
+ });
- vm.loadRequestDetails('456', 'https://gitlab.com/');
+ it('makes an HTTP request for the request details', () => {
+ vm.addRequest('456', 'https://gitlab.com/');
+ vm.loadRequestDetails('456');
expect(PerformanceBarService.fetchRequestDetails).toHaveBeenCalledWith(
'/-/peek/results',
'456',
);
});
+
+ it('does not make a request if request was not added', () => {
+ vm.loadRequestDetails('456');
+
+ expect(PerformanceBarService.fetchRequestDetails).not.toHaveBeenCalled();
+ });
+
+ it('makes an HTTP request only once for the same request', async () => {
+ vm.addRequest('456', 'https://gitlab.com/');
+ await vm.loadRequestDetails('456');
+
+ vm.loadRequestDetails('456');
+
+ expect(PerformanceBarService.fetchRequestDetails).toHaveBeenCalledTimes(1);
+ });
});
});
diff --git a/spec/frontend/persistent_user_callout_spec.js b/spec/frontend/persistent_user_callout_spec.js
index 4633602de26..bff8fcda9b9 100644
--- a/spec/frontend/persistent_user_callout_spec.js
+++ b/spec/frontend/persistent_user_callout_spec.js
@@ -21,7 +21,8 @@ describe('PersistentUserCallout', () => {
data-feature-id="${featureName}"
data-group-id="${groupId}"
>
- <button type="button" class="js-close"></button>
+ <button type="button" class="js-close js-close-primary"></button>
+ <button type="button" class="js-close js-close-secondary"></button>
</div>
`;
@@ -64,14 +65,15 @@ describe('PersistentUserCallout', () => {
}
describe('dismiss', () => {
- let button;
+ const buttons = {};
let mockAxios;
let persistentUserCallout;
beforeEach(() => {
const fixture = createFixture();
const container = fixture.querySelector('.container');
- button = fixture.querySelector('.js-close');
+ buttons.primary = fixture.querySelector('.js-close-primary');
+ buttons.secondary = fixture.querySelector('.js-close-secondary');
mockAxios = new MockAdapter(axios);
persistentUserCallout = new PersistentUserCallout(container);
jest.spyOn(persistentUserCallout.container, 'remove').mockImplementation(() => {});
@@ -81,29 +83,33 @@ describe('PersistentUserCallout', () => {
mockAxios.restore();
});
- it('POSTs endpoint and removes container when clicking close', () => {
+ it.each`
+ button
+ ${'primary'}
+ ${'secondary'}
+ `('POSTs endpoint and removes container when clicking $button close', async ({ button }) => {
mockAxios.onPost(dismissEndpoint).replyOnce(200);
- button.click();
+ buttons[button].click();
- return waitForPromises().then(() => {
- expect(persistentUserCallout.container.remove).toHaveBeenCalled();
- expect(mockAxios.history.post[0].data).toBe(
- JSON.stringify({ feature_name: featureName, group_id: groupId }),
- );
- });
+ await waitForPromises();
+
+ expect(persistentUserCallout.container.remove).toHaveBeenCalled();
+ expect(mockAxios.history.post[0].data).toBe(
+ JSON.stringify({ feature_name: featureName, group_id: groupId }),
+ );
});
- it('invokes Flash when the dismiss request fails', () => {
+ it('invokes Flash when the dismiss request fails', async () => {
mockAxios.onPost(dismissEndpoint).replyOnce(500);
- button.click();
+ buttons.primary.click();
- return waitForPromises().then(() => {
- expect(persistentUserCallout.container.remove).not.toHaveBeenCalled();
- expect(createFlash).toHaveBeenCalledWith({
- message: 'An error occurred while dismissing the alert. Refresh the page and try again.',
- });
+ await waitForPromises();
+
+ expect(persistentUserCallout.container.remove).not.toHaveBeenCalled();
+ expect(createFlash).toHaveBeenCalledWith({
+ message: 'An error occurred while dismissing the alert. Refresh the page and try again.',
});
});
});
@@ -132,37 +138,37 @@ describe('PersistentUserCallout', () => {
mockAxios.restore();
});
- it('defers loading of a link until callout is dismissed', () => {
+ it('defers loading of a link until callout is dismissed', async () => {
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 }));
- });
+ await waitForPromises();
+
+ 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', () => {
+ it('does not dismiss callout on non-deferred links', async () => {
normalLink.click();
- return waitForPromises().then(() => {
- expect(windowSpy).not.toHaveBeenCalled();
- expect(persistentUserCallout.container.remove).not.toHaveBeenCalled();
- });
+ await waitForPromises();
+
+ expect(windowSpy).not.toHaveBeenCalled();
+ expect(persistentUserCallout.container.remove).not.toHaveBeenCalled();
});
- it('does not follow link when notification is closed', () => {
+ it('does not follow link when notification is closed', async () => {
mockAxios.onPost(dismissEndpoint).replyOnce(200);
button.click();
- return waitForPromises().then(() => {
- expect(windowSpy).not.toHaveBeenCalled();
- expect(persistentUserCallout.container.remove).toHaveBeenCalled();
- });
+ await waitForPromises();
+
+ expect(windowSpy).not.toHaveBeenCalled();
+ expect(persistentUserCallout.container.remove).toHaveBeenCalled();
});
});
@@ -187,30 +193,30 @@ describe('PersistentUserCallout', () => {
mockAxios.restore();
});
- it('uses a link to trigger callout and defers following until callout is finished', () => {
+ it('uses a link to trigger callout and defers following until callout is finished', async () => {
const { href } = link;
mockAxios.onPost(dismissEndpoint).replyOnce(200);
link.click();
- return waitForPromises().then(() => {
- expect(window.location.assign).toBeCalledWith(href);
- expect(persistentUserCallout.container.remove).not.toHaveBeenCalled();
- expect(mockAxios.history.post[0].data).toBe(JSON.stringify({ feature_name: featureName }));
- });
+ await waitForPromises();
+
+ expect(window.location.assign).toBeCalledWith(href);
+ expect(persistentUserCallout.container.remove).not.toHaveBeenCalled();
+ expect(mockAxios.history.post[0].data).toBe(JSON.stringify({ feature_name: featureName }));
});
- it('invokes Flash when the dismiss request fails', () => {
+ it('invokes Flash when the dismiss request fails', async () => {
mockAxios.onPost(dismissEndpoint).replyOnce(500);
link.click();
- return waitForPromises().then(() => {
- expect(window.location.assign).not.toHaveBeenCalled();
- expect(createFlash).toHaveBeenCalledWith({
- message:
- 'An error occurred while acknowledging the notification. Refresh the page and try again.',
- });
+ await waitForPromises();
+
+ expect(window.location.assign).not.toHaveBeenCalled();
+ expect(createFlash).toHaveBeenCalledWith({
+ message:
+ 'An error occurred while acknowledging the notification. Refresh the page and try again.',
});
});
});
diff --git a/spec/frontend/pipeline_editor/components/commit/commit_form_spec.js b/spec/frontend/pipeline_editor/components/commit/commit_form_spec.js
index 7244a179820..59bd71b0e60 100644
--- a/spec/frontend/pipeline_editor/components/commit/commit_form_spec.js
+++ b/spec/frontend/pipeline_editor/components/commit/commit_form_spec.js
@@ -17,6 +17,8 @@ describe('Pipeline Editor | Commit Form', () => {
propsData: {
defaultMessage: mockCommitMessage,
currentBranch: mockDefaultBranch,
+ hasUnsavedChanges: true,
+ isNewCiConfigFile: false,
...props,
},
@@ -82,6 +84,27 @@ describe('Pipeline Editor | Commit Form', () => {
});
});
+ describe('submit button', () => {
+ it.each`
+ hasUnsavedChanges | isNewCiConfigFile | isDisabled | btnState
+ ${false} | ${false} | ${true} | ${'disabled'}
+ ${true} | ${false} | ${false} | ${'enabled'}
+ ${true} | ${true} | ${false} | ${'enabled'}
+ ${false} | ${true} | ${false} | ${'enabled'}
+ `(
+ 'is $btnState when hasUnsavedChanges:$hasUnsavedChanges and isNewCiConfigfile:$isNewCiConfigFile',
+ ({ hasUnsavedChanges, isNewCiConfigFile, isDisabled }) => {
+ createComponent({ props: { hasUnsavedChanges, isNewCiConfigFile } });
+
+ if (isDisabled) {
+ expect(findSubmitBtn().attributes('disabled')).toBe('true');
+ } else {
+ expect(findSubmitBtn().attributes('disabled')).toBeUndefined();
+ }
+ },
+ );
+ });
+
describe('when user inputs values', () => {
const anotherMessage = 'Another commit message';
const anotherBranch = 'my-branch';
diff --git a/spec/frontend/pipeline_editor/components/commit/commit_section_spec.js b/spec/frontend/pipeline_editor/components/commit/commit_section_spec.js
index b54feea6ff7..33c76309951 100644
--- a/spec/frontend/pipeline_editor/components/commit/commit_section_spec.js
+++ b/spec/frontend/pipeline_editor/components/commit/commit_section_spec.js
@@ -51,6 +51,7 @@ describe('Pipeline Editor | Commit section', () => {
const defaultProps = {
ciFileContent: mockCiYml,
commitSha: mockCommitSha,
+ hasUnsavedChanges: true,
isNewCiConfigFile: false,
};
diff --git a/spec/frontend/pipeline_editor/components/drawer/pipeline_editor_drawer_spec.js b/spec/frontend/pipeline_editor/components/drawer/pipeline_editor_drawer_spec.js
index 4df7768b035..ba06f113120 100644
--- a/spec/frontend/pipeline_editor/components/drawer/pipeline_editor_drawer_spec.js
+++ b/spec/frontend/pipeline_editor/components/drawer/pipeline_editor_drawer_spec.js
@@ -1,7 +1,6 @@
import { GlButton } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue';
-import { stubExperiments } from 'helpers/experimentation_helper';
import { useLocalStorageSpy } from 'helpers/local_storage_helper';
import FirstPipelineCard from '~/pipeline_editor/components/drawer/cards/first_pipeline_card.vue';
import GettingStartedCard from '~/pipeline_editor/components/drawer/cards/getting_started_card.vue';
@@ -38,7 +37,6 @@ describe('Pipeline editor drawer', () => {
beforeEach(() => {
originalObjects.push(window.gon, window.gl);
- stubExperiments({ pipeline_editor_walkthrough: 'control' });
});
afterEach(() => {
@@ -48,33 +46,15 @@ describe('Pipeline editor drawer', () => {
});
describe('default expanded state', () => {
- describe('when experiment control', () => {
- it('sets the drawer to be opened by default', async () => {
- createComponent();
- expect(findDrawerContent().exists()).toBe(false);
- await nextTick();
- expect(findDrawerContent().exists()).toBe(true);
- });
- });
-
- describe('when experiment candidate', () => {
- beforeEach(() => {
- stubExperiments({ pipeline_editor_walkthrough: 'candidate' });
- });
-
- it('sets the drawer to be closed by default', async () => {
- createComponent();
- expect(findDrawerContent().exists()).toBe(false);
- await nextTick();
- expect(findDrawerContent().exists()).toBe(false);
- });
+ it('sets the drawer to be closed by default', async () => {
+ createComponent();
+ expect(findDrawerContent().exists()).toBe(false);
});
});
describe('when the drawer is collapsed', () => {
beforeEach(async () => {
createComponent();
- await clickToggleBtn();
});
it('shows the left facing arrow icon', () => {
@@ -101,6 +81,7 @@ describe('Pipeline editor drawer', () => {
describe('when the drawer is expanded', () => {
beforeEach(async () => {
createComponent();
+ await clickToggleBtn();
});
it('shows the right facing arrow icon', () => {
diff --git a/spec/frontend/pipeline_editor/components/editor/text_editor_spec.js b/spec/frontend/pipeline_editor/components/editor/text_editor_spec.js
index f15d5f334d6..6cdf9a93d55 100644
--- a/spec/frontend/pipeline_editor/components/editor/text_editor_spec.js
+++ b/spec/frontend/pipeline_editor/components/editor/text_editor_spec.js
@@ -1,6 +1,7 @@
import { shallowMount } from '@vue/test-utils';
import { EDITOR_READY_EVENT } from '~/editor/constants';
+import { SOURCE_EDITOR_DEBOUNCE } from '~/pipeline_editor/constants';
import TextEditor from '~/pipeline_editor/components/editor/text_editor.vue';
import {
mockCiConfigPath,
@@ -22,7 +23,7 @@ describe('Pipeline Editor | Text editor component', () => {
const MockSourceEditor = {
template: '<div/>',
- props: ['value', 'fileName'],
+ props: ['value', 'fileName', 'editorOptions', 'debounceValue'],
};
const createComponent = (glFeatures = {}, mountFn = shallowMount) => {
@@ -90,6 +91,14 @@ describe('Pipeline Editor | Text editor component', () => {
expect(findEditor().props('fileName')).toBe(mockCiConfigPath);
});
+ it('passes down editor configs options', () => {
+ expect(findEditor().props('editorOptions')).toEqual({ quickSuggestions: true });
+ });
+
+ it('passes down editor debounce value', () => {
+ expect(findEditor().props('debounceValue')).toBe(SOURCE_EDITOR_DEBOUNCE);
+ });
+
it('bubbles up events', () => {
findEditor().vm.$emit(EDITOR_READY_EVENT, editorInstanceDetail);
diff --git a/spec/frontend/pipeline_editor/components/pipeline_editor_tabs_spec.js b/spec/frontend/pipeline_editor/components/pipeline_editor_tabs_spec.js
index f6154f50bc0..fee52db9b64 100644
--- a/spec/frontend/pipeline_editor/components/pipeline_editor_tabs_spec.js
+++ b/spec/frontend/pipeline_editor/components/pipeline_editor_tabs_spec.js
@@ -7,7 +7,6 @@ import WalkthroughPopover from '~/pipeline_editor/components/walkthrough_popover
import CiLint from '~/pipeline_editor/components/lint/ci_lint.vue';
import PipelineEditorTabs from '~/pipeline_editor/components/pipeline_editor_tabs.vue';
import EditorTab from '~/pipeline_editor/components/ui/editor_tab.vue';
-import { stubExperiments } from 'helpers/experimentation_helper';
import {
CREATE_TAB,
EDITOR_APP_STATUS_EMPTY,
@@ -245,50 +244,30 @@ describe('Pipeline editor tabs component', () => {
});
});
- describe('pipeline_editor_walkthrough experiment', () => {
- describe('when in control path', () => {
- beforeEach(() => {
- stubExperiments({ pipeline_editor_walkthrough: 'control' });
- });
-
- it('does not show walkthrough popover', async () => {
- createComponent({ mountFn: mount });
+ describe('pipeline editor walkthrough', () => {
+ describe('when isNewCiConfigFile prop is true (default)', () => {
+ beforeEach(async () => {
+ createComponent({
+ mountFn: mount,
+ });
await nextTick();
- expect(findWalkthroughPopover().exists()).toBe(false);
});
- });
- describe('when in candidate path', () => {
- beforeEach(() => {
- stubExperiments({ pipeline_editor_walkthrough: 'candidate' });
- });
-
- describe('when isNewCiConfigFile prop is true (default)', () => {
- beforeEach(async () => {
- createComponent({
- mountFn: mount,
- });
- await nextTick();
- });
-
- it('shows walkthrough popover', async () => {
- expect(findWalkthroughPopover().exists()).toBe(true);
- });
+ it('shows walkthrough popover', async () => {
+ expect(findWalkthroughPopover().exists()).toBe(true);
});
+ });
- describe('when isNewCiConfigFile prop is false', () => {
- it('does not show walkthrough popover', async () => {
- createComponent({ props: { isNewCiConfigFile: false }, mountFn: mount });
- await nextTick();
- expect(findWalkthroughPopover().exists()).toBe(false);
- });
+ describe('when isNewCiConfigFile prop is false', () => {
+ it('does not show walkthrough popover', async () => {
+ createComponent({ props: { isNewCiConfigFile: false }, mountFn: mount });
+ await nextTick();
+ expect(findWalkthroughPopover().exists()).toBe(false);
});
});
});
it('sets listeners on walkthrough popover', async () => {
- stubExperiments({ pipeline_editor_walkthrough: 'candidate' });
-
const handler = jest.fn();
createComponent({
diff --git a/spec/frontend/pipeline_editor/pipeline_editor_app_spec.js b/spec/frontend/pipeline_editor/pipeline_editor_app_spec.js
index 0a2c03b7850..0ce6cc3f2d4 100644
--- a/spec/frontend/pipeline_editor/pipeline_editor_app_spec.js
+++ b/spec/frontend/pipeline_editor/pipeline_editor_app_spec.js
@@ -18,12 +18,15 @@ import {
COMMIT_SUCCESS,
COMMIT_SUCCESS_WITH_REDIRECT,
COMMIT_FAILURE,
+ EDITOR_APP_STATUS_LOADING,
} from '~/pipeline_editor/constants';
import getBlobContent from '~/pipeline_editor/graphql/queries/blob_content.query.graphql';
import getCiConfigData from '~/pipeline_editor/graphql/queries/ci_config.query.graphql';
import getTemplate from '~/pipeline_editor/graphql/queries/get_starter_template.query.graphql';
import getLatestCommitShaQuery from '~/pipeline_editor/graphql/queries/latest_commit_sha.query.graphql';
import getPipelineQuery from '~/pipeline_editor/graphql/queries/pipeline.query.graphql';
+import getCurrentBranch from '~/pipeline_editor/graphql/queries/client/current_branch.query.graphql';
+import getAppStatus from '~/pipeline_editor/graphql/queries/client/app_status.query.graphql';
import PipelineEditorApp from '~/pipeline_editor/pipeline_editor_app.vue';
import PipelineEditorHome from '~/pipeline_editor/pipeline_editor_home.vue';
@@ -84,9 +87,6 @@ describe('Pipeline editor app component', () => {
initialCiFileContent: {
loading: blobLoading,
},
- ciConfigData: {
- loading: false,
- },
},
},
},
@@ -94,7 +94,11 @@ describe('Pipeline editor app component', () => {
});
};
- const createComponentWithApollo = async ({ provide = {}, stubs = {} } = {}) => {
+ const createComponentWithApollo = async ({
+ provide = {},
+ stubs = {},
+ withUndefinedBranch = false,
+ } = {}) => {
const handlers = [
[getBlobContent, mockBlobContentData],
[getCiConfigData, mockCiConfigData],
@@ -105,6 +109,31 @@ describe('Pipeline editor app component', () => {
mockApollo = createMockApollo(handlers, resolvers);
+ if (!withUndefinedBranch) {
+ mockApollo.clients.defaultClient.cache.writeQuery({
+ query: getCurrentBranch,
+ data: {
+ workBranches: {
+ __typename: 'BranchList',
+ current: {
+ __typename: 'WorkBranch',
+ name: mockDefaultBranch,
+ },
+ },
+ },
+ });
+ }
+
+ mockApollo.clients.defaultClient.cache.writeQuery({
+ query: getAppStatus,
+ data: {
+ app: {
+ __typename: 'AppData',
+ status: EDITOR_APP_STATUS_LOADING,
+ },
+ },
+ });
+
const options = {
localVue,
mocks: {},
@@ -145,6 +174,55 @@ describe('Pipeline editor app component', () => {
});
});
+ describe('skipping queries', () => {
+ describe('when branchName is undefined', () => {
+ beforeEach(async () => {
+ await createComponentWithApollo({ withUndefinedBranch: true });
+ });
+
+ it('does not calls getBlobContent', () => {
+ expect(mockBlobContentData).not.toHaveBeenCalled();
+ });
+ });
+
+ describe('when branchName is defined', () => {
+ beforeEach(async () => {
+ await createComponentWithApollo();
+ });
+
+ it('calls getBlobContent', () => {
+ expect(mockBlobContentData).toHaveBeenCalled();
+ });
+ });
+
+ describe('when commit sha is undefined', () => {
+ beforeEach(async () => {
+ mockLatestCommitShaQuery.mockResolvedValue(undefined);
+ await createComponentWithApollo();
+ });
+
+ it('calls getBlobContent', () => {
+ expect(mockBlobContentData).toHaveBeenCalled();
+ });
+
+ it('does not call ciConfigData', () => {
+ expect(mockCiConfigData).not.toHaveBeenCalled();
+ });
+ });
+
+ describe('when commit sha is defined', () => {
+ beforeEach(async () => {
+ mockBlobContentData.mockResolvedValue(mockBlobContentQueryResponse);
+ mockLatestCommitShaQuery.mockResolvedValue(mockCommitShaResults);
+ await createComponentWithApollo();
+ });
+
+ it('calls ciConfigData', () => {
+ expect(mockCiConfigData).toHaveBeenCalled();
+ });
+ });
+ });
+
describe('when queries are called', () => {
beforeEach(() => {
mockBlobContentData.mockResolvedValue(mockBlobContentQueryResponse);
diff --git a/spec/frontend/pipeline_wizard/components/input_spec.js b/spec/frontend/pipeline_wizard/components/input_spec.js
new file mode 100644
index 00000000000..ee1f3fe70ff
--- /dev/null
+++ b/spec/frontend/pipeline_wizard/components/input_spec.js
@@ -0,0 +1,79 @@
+import { mount, shallowMount } from '@vue/test-utils';
+import { Document } from 'yaml';
+import InputWrapper from '~/pipeline_wizard/components/input.vue';
+import TextWidget from '~/pipeline_wizard/components/widgets/text.vue';
+
+describe('Pipeline Wizard -- Input Wrapper', () => {
+ let wrapper;
+
+ const createComponent = (props = {}, mountFunc = mount) => {
+ wrapper = mountFunc(InputWrapper, {
+ propsData: {
+ template: new Document({
+ template: {
+ bar: 'baz',
+ foo: { some: '$TARGET' },
+ },
+ }).get('template'),
+ compiled: new Document({ bar: 'baz', foo: { some: '$TARGET' } }),
+ target: '$TARGET',
+ widget: 'text',
+ label: 'some label (required by the text widget)',
+ ...props,
+ },
+ });
+ };
+
+ describe('API', () => {
+ const inputValue = 'dslkfjsdlkfjlskdjfn';
+ let inputChild;
+
+ beforeEach(() => {
+ createComponent({});
+ inputChild = wrapper.find(TextWidget);
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ it('will replace its value in compiled', async () => {
+ await inputChild.vm.$emit('input', inputValue);
+ const expected = new Document({
+ bar: 'baz',
+ foo: { some: inputValue },
+ });
+ expect(wrapper.emitted()['update:compiled']).toEqual([[expected]]);
+ });
+
+ it('will emit a highlight event with the correct path if child emits an input event', async () => {
+ await inputChild.vm.$emit('input', inputValue);
+ const expected = ['foo', 'some'];
+ expect(wrapper.emitted().highlight).toEqual([[expected]]);
+ });
+ });
+
+ describe('Target Path Discovery', () => {
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ it.each`
+ scenario | template | target | expected
+ ${'simple nested object'} | ${{ foo: { bar: { baz: '$BOO' } } }} | ${'$BOO'} | ${['foo', 'bar', 'baz']}
+ ${'list, first pos.'} | ${{ foo: ['$BOO'] }} | ${'$BOO'} | ${['foo', 0]}
+ ${'list, second pos.'} | ${{ foo: ['bar', '$BOO'] }} | ${'$BOO'} | ${['foo', 1]}
+ ${'lowercase target'} | ${{ foo: { bar: '$jupp' } }} | ${'$jupp'} | ${['foo', 'bar']}
+ ${'root list'} | ${['$BOO']} | ${'$BOO'} | ${[0]}
+ `('$scenario', ({ template, target, expected }) => {
+ createComponent(
+ {
+ template: new Document({ template }).get('template'),
+ target,
+ },
+ shallowMount,
+ );
+ expect(wrapper.vm.path).toEqual(expected);
+ });
+ });
+});
diff --git a/spec/frontend/pipeline_wizard/components/step_spec.js b/spec/frontend/pipeline_wizard/components/step_spec.js
new file mode 100644
index 00000000000..2289a349318
--- /dev/null
+++ b/spec/frontend/pipeline_wizard/components/step_spec.js
@@ -0,0 +1,227 @@
+import { parseDocument, Document } from 'yaml';
+import { omit } from 'lodash';
+import { nextTick } from 'vue';
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
+import PipelineWizardStep from '~/pipeline_wizard/components/step.vue';
+import InputWrapper from '~/pipeline_wizard/components/input.vue';
+import StepNav from '~/pipeline_wizard/components/step_nav.vue';
+import {
+ stepInputs,
+ stepTemplate,
+ compiledYamlBeforeSetup,
+ compiledYamlAfterInitialLoad,
+ compiledYaml,
+} from '../mock/yaml';
+
+describe('Pipeline Wizard - Step Page', () => {
+ const inputs = parseDocument(stepInputs).toJS();
+ let wrapper;
+ let input1;
+ let input2;
+
+ const getInputWrappers = () => wrapper.findAllComponents(InputWrapper);
+ const forEachInputWrapper = (cb) => {
+ getInputWrappers().wrappers.forEach(cb);
+ };
+ const getStepNav = () => {
+ return wrapper.findComponent(StepNav);
+ };
+ const mockNextClick = () => {
+ getStepNav().vm.$emit('next');
+ };
+ const mockPrevClick = () => {
+ getStepNav().vm.$emit('back');
+ };
+ const expectFalsyAttributeValue = (testedWrapper, attributeName) => {
+ expect([false, null, undefined]).toContain(testedWrapper.attributes(attributeName));
+ };
+ const findInputWrappers = () => {
+ const inputWrappers = wrapper.findAllComponents(InputWrapper);
+ input1 = inputWrappers.at(0);
+ input2 = inputWrappers.at(1);
+ };
+
+ const createComponent = (props = {}) => {
+ const template = parseDocument(stepTemplate).get('template');
+ const defaultProps = {
+ inputs,
+ template,
+ };
+ wrapper = shallowMountExtended(PipelineWizardStep, {
+ propsData: {
+ ...defaultProps,
+ compiled: parseDocument(compiledYamlBeforeSetup),
+ ...props,
+ },
+ });
+ };
+
+ afterEach(async () => {
+ await wrapper.destroy();
+ });
+
+ describe('input children', () => {
+ beforeEach(() => {
+ createComponent();
+ });
+
+ it('mounts an inputWrapper for each input type', () => {
+ forEachInputWrapper((inputWrapper, i) =>
+ expect(inputWrapper.attributes('widget')).toBe(inputs[i].widget),
+ );
+ });
+
+ it('passes all unused props to the inputWrapper', () => {
+ const pickChildProperties = (from) => {
+ return omit(from, ['target', 'widget']);
+ };
+ forEachInputWrapper((inputWrapper, i) => {
+ const expectedProps = pickChildProperties(inputs[i]);
+ Object.entries(expectedProps).forEach(([key, value]) => {
+ expect(inputWrapper.attributes(key.toLowerCase())).toEqual(value.toString());
+ });
+ });
+ });
+ });
+
+ const yamlDocument = new Document({ foo: { bar: 'baz' } });
+ const yamlNode = yamlDocument.get('foo');
+
+ describe('prop validation', () => {
+ describe.each`
+ componentProp | required | valid | invalid
+ ${'inputs'} | ${true} | ${[inputs, []]} | ${[['invalid'], [null], [{}, {}]]}
+ ${'template'} | ${true} | ${[yamlNode]} | ${['invalid', null, { foo: 1 }, yamlDocument]}
+ ${'compiled'} | ${true} | ${[yamlDocument]} | ${['invalid', null, { foo: 1 }, yamlNode]}
+ `('testing `$componentProp` prop', ({ componentProp, required, valid, invalid }) => {
+ it('expects prop to be required', () => {
+ expect(PipelineWizardStep.props[componentProp].required).toEqual(required);
+ });
+
+ it('prop validators return false for invalid types', () => {
+ const validatorFunc = PipelineWizardStep.props[componentProp].validator;
+ invalid.forEach((invalidType) => {
+ expect(validatorFunc(invalidType)).toBe(false);
+ });
+ });
+
+ it('prop validators return true for valid types', () => {
+ const validatorFunc = PipelineWizardStep.props[componentProp].validator;
+ valid.forEach((validType) => {
+ expect(validatorFunc(validType)).toBe(true);
+ });
+ });
+ });
+ });
+
+ describe('navigation', () => {
+ it('shows the next button', () => {
+ createComponent();
+
+ expect(getStepNav().attributes('nextbuttonenabled')).toEqual('true');
+ });
+
+ it('does not show a back button if hasPreviousStep is false', () => {
+ createComponent({ hasPreviousStep: false });
+
+ expectFalsyAttributeValue(getStepNav(), 'showbackbutton');
+ });
+
+ it('shows a back button if hasPreviousStep is true', () => {
+ createComponent({ hasPreviousStep: true });
+
+ expect(getStepNav().attributes('showbackbutton')).toBe('true');
+ });
+
+ it('lets "back" event bubble upwards', async () => {
+ createComponent();
+
+ await mockPrevClick();
+ await nextTick();
+
+ expect(wrapper.emitted().back).toBeTruthy();
+ });
+
+ it('lets "next" event bubble upwards', async () => {
+ createComponent();
+
+ await mockNextClick();
+ await nextTick();
+
+ expect(wrapper.emitted().next).toBeTruthy();
+ });
+ });
+
+ describe('validation', () => {
+ beforeEach(() => {
+ createComponent({ hasNextPage: true });
+ findInputWrappers();
+ });
+
+ it('sets invalid once one input field has an invalid value', async () => {
+ input1.vm.$emit('update:valid', true);
+ input2.vm.$emit('update:valid', false);
+
+ await mockNextClick();
+
+ expectFalsyAttributeValue(getStepNav(), 'nextbuttonenabled');
+ });
+
+ it('returns to valid state once the invalid input is valid again', async () => {
+ input1.vm.$emit('update:valid', true);
+ input2.vm.$emit('update:valid', false);
+
+ await mockNextClick();
+
+ expectFalsyAttributeValue(getStepNav(), 'nextbuttonenabled');
+
+ input2.vm.$emit('update:valid', true);
+ await nextTick();
+
+ expect(getStepNav().attributes('nextbuttonenabled')).toBe('true');
+ });
+
+ it('passes validate state to all input wrapper children when next is clicked', async () => {
+ forEachInputWrapper((inputWrapper) => {
+ expectFalsyAttributeValue(inputWrapper, 'validate');
+ });
+
+ await mockNextClick();
+
+ expect(input1.attributes('validate')).toBe('true');
+ });
+
+ it('not emitting a valid state is considered valid', async () => {
+ // input1 does not emit a update:valid event
+ input2.vm.$emit('update:valid', true);
+
+ await mockNextClick();
+
+ expect(getStepNav().attributes('nextbuttonenabled')).toBe('true');
+ });
+ });
+
+ describe('template compilation', () => {
+ beforeEach(() => {
+ createComponent();
+ findInputWrappers();
+ });
+
+ it('injects the template when an input wrapper emits a beforeUpdate:compiled event', async () => {
+ input1.vm.$emit('beforeUpdate:compiled');
+
+ expect(wrapper.vm.compiled.toString()).toBe(compiledYamlAfterInitialLoad);
+ });
+
+ it('lets the "update:compiled" event bubble upwards', async () => {
+ const compiled = parseDocument(compiledYaml);
+
+ await input1.vm.$emit('update:compiled', compiled);
+
+ const updateEvents = wrapper.emitted()['update:compiled'];
+ const latestUpdateEvent = updateEvents[updateEvents.length - 1];
+
+ expect(latestUpdateEvent[0].toString()).toBe(compiled.toString());
+ });
+ });
+});
diff --git a/spec/frontend/pipeline_wizard/components/widgets/list_spec.js b/spec/frontend/pipeline_wizard/components/widgets/list_spec.js
new file mode 100644
index 00000000000..796356634bc
--- /dev/null
+++ b/spec/frontend/pipeline_wizard/components/widgets/list_spec.js
@@ -0,0 +1,212 @@
+import { GlFormGroup, GlFormInputGroup } from '@gitlab/ui';
+import { nextTick } from 'vue';
+import ListWidget from '~/pipeline_wizard/components/widgets/list.vue';
+import { mountExtended, shallowMountExtended } from 'helpers/vue_test_utils_helper';
+
+describe('Pipeline Wizard - List Widget', () => {
+ const defaultProps = {
+ label: 'This label',
+ description: 'some description',
+ placeholder: 'some placeholder',
+ pattern: '^[a-z]+$',
+ invalidFeedback: 'some feedback',
+ };
+ let wrapper;
+ let addStepBtn;
+
+ const findGlFormGroup = () => wrapper.findComponent(GlFormGroup);
+ const findGlFormGroupInvalidFeedback = () => findGlFormGroup().find('.invalid-feedback').text();
+ const findFirstGlFormInputGroup = () => wrapper.findComponent(GlFormInputGroup);
+ const findAllGlFormInputGroups = () => wrapper.findAllComponents(GlFormInputGroup);
+ const findGlFormInputGroupByIndex = (index) => findAllGlFormInputGroups().at(index);
+ const setValueOnInputField = (value, atIndex = 0) => {
+ return findGlFormInputGroupByIndex(atIndex).vm.$emit('input', value);
+ };
+ const findAddStepButton = () => wrapper.findByTestId('add-step-button');
+ const addStep = () => findAddStepButton().vm.$emit('click');
+
+ const createComponent = (props = {}, mountFn = shallowMountExtended) => {
+ wrapper = mountFn(ListWidget, {
+ propsData: {
+ ...defaultProps,
+ ...props,
+ },
+ });
+ addStepBtn = findAddStepButton();
+ };
+
+ describe('component setup and interface', () => {
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ it('prints the label inside the legend', () => {
+ createComponent();
+
+ expect(findGlFormGroup().attributes('label')).toBe(defaultProps.label);
+ });
+
+ it('prints the description inside the legend', () => {
+ createComponent();
+
+ expect(findGlFormGroup().attributes('labeldescription')).toBe(defaultProps.description);
+ });
+
+ it('sets the input field type attribute to "text"', async () => {
+ createComponent();
+
+ expect(findFirstGlFormInputGroup().attributes('type')).toBe('text');
+ });
+
+ it('passes the placeholder to the first input field', () => {
+ createComponent();
+
+ expect(findFirstGlFormInputGroup().attributes('placeholder')).toBe(defaultProps.placeholder);
+ });
+
+ it('shows a delete button on all fields if there are more than one', async () => {
+ createComponent({}, mountExtended);
+
+ await addStep();
+ await addStep();
+ const inputGroups = findAllGlFormInputGroups().wrappers;
+
+ expect(inputGroups.length).toBe(3);
+ inputGroups.forEach((inputGroup) => {
+ const button = inputGroup.find('[data-testid="remove-step-button"]');
+ expect(button.find('[data-testid="remove-icon"]').exists()).toBe(true);
+ expect(button.attributes('aria-label')).toBe('remove step');
+ });
+ });
+
+ it('null values do not cause an input event', async () => {
+ createComponent();
+
+ await addStep();
+
+ expect(wrapper.emitted('input')).toBe(undefined);
+ });
+
+ it('hides the delete button if there is only one', () => {
+ createComponent({}, mountExtended);
+
+ const inputGroups = findAllGlFormInputGroups().wrappers;
+
+ expect(inputGroups.length).toBe(1);
+ expect(wrapper.findByTestId('remove-step-button').exists()).toBe(false);
+ });
+
+ it('shows an "add step" button', () => {
+ createComponent();
+
+ expect(addStepBtn.attributes('icon')).toBe('plus');
+ expect(addStepBtn.text()).toBe('add another step');
+ });
+
+ it('the "add step" button increases the number of input fields', async () => {
+ createComponent();
+
+ expect(findAllGlFormInputGroups().wrappers.length).toBe(1);
+ await addStep();
+ expect(findAllGlFormInputGroups().wrappers.length).toBe(2);
+ });
+
+ it('does not pass the placeholder on subsequent input fields', async () => {
+ createComponent();
+
+ await addStep();
+ await addStep();
+ const nullOrUndefined = [null, undefined];
+ expect(nullOrUndefined).toContain(findAllGlFormInputGroups().at(1).attributes('placeholder'));
+ expect(nullOrUndefined).toContain(findAllGlFormInputGroups().at(2).attributes('placeholder'));
+ });
+
+ it('emits an update event on input', async () => {
+ createComponent();
+
+ const localValue = 'somevalue';
+ await setValueOnInputField(localValue);
+ await nextTick();
+
+ expect(wrapper.emitted('input')).toEqual([[[localValue]]]);
+ });
+
+ it('only emits non-null values', async () => {
+ createComponent();
+
+ await addStep();
+ await addStep();
+ await setValueOnInputField('abc', 1);
+ await nextTick();
+
+ const events = wrapper.emitted('input');
+
+ expect(events.length).toBe(1);
+ expect(events[0]).toEqual([['abc']]);
+ });
+ });
+
+ describe('form validation', () => {
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ it('does not show validation state when untouched', async () => {
+ createComponent({}, mountExtended);
+ expect(findGlFormGroup().classes()).not.toContain('is-valid');
+ expect(findGlFormGroup().classes()).not.toContain('is-invalid');
+ });
+
+ it('shows invalid state on blur', async () => {
+ createComponent({}, mountExtended);
+ expect(findGlFormGroup().classes()).not.toContain('is-invalid');
+ const input = findFirstGlFormInputGroup().find('input');
+ await input.setValue('invalid99');
+ await input.trigger('blur');
+ expect(input.classes()).toContain('is-invalid');
+ expect(findGlFormGroup().classes()).toContain('is-invalid');
+ });
+
+ it('shows invalid state when toggling `validate` prop', async () => {
+ createComponent({ required: true, validate: false }, mountExtended);
+ await setValueOnInputField(null);
+ expect(findGlFormGroup().classes()).not.toContain('is-invalid');
+ await wrapper.setProps({ validate: true });
+ expect(findGlFormGroup().classes()).toContain('is-invalid');
+ });
+
+ it.each`
+ scenario | required | values | inputFieldClasses | inputGroupClass | feedback
+ ${'shows invalid if all inputs are empty'} | ${true} | ${[null, null]} | ${['is-invalid', null]} | ${'is-invalid'} | ${'At least one entry is required'}
+ ${'is valid if at least one field has a valid entry'} | ${true} | ${[null, 'abc']} | ${[null, 'is-valid']} | ${'is-valid'} | ${expect.anything()}
+ ${'is invalid if one field has an invalid entry'} | ${true} | ${['abc', '99']} | ${['is-valid', 'is-invalid']} | ${'is-invalid'} | ${defaultProps.invalidFeedback}
+ ${'is not invalid if its not required but all values are null'} | ${false} | ${[null, null]} | ${[null, null]} | ${'is-valid'} | ${expect.anything()}
+ ${'is invalid if pattern does not match even if its not required'} | ${false} | ${['99', null]} | ${['is-invalid', null]} | ${'is-invalid'} | ${defaultProps.invalidFeedback}
+ `('$scenario', async ({ required, values, inputFieldClasses, inputGroupClass, feedback }) => {
+ createComponent({ required, validate: true }, mountExtended);
+
+ await Promise.all(
+ values.map(async (value, i) => {
+ if (i > 0) {
+ await addStep();
+ }
+ await setValueOnInputField(value, i);
+ }),
+ );
+ await nextTick();
+
+ inputFieldClasses.forEach((expected, i) => {
+ const inputWrapper = findGlFormInputGroupByIndex(i).find('input');
+ if (expected === null) {
+ expect(inputWrapper.classes()).not.toContain('is-valid');
+ expect(inputWrapper.classes()).not.toContain('is-invalid');
+ } else {
+ expect(inputWrapper.classes()).toContain(expected);
+ }
+ });
+
+ expect(findGlFormGroup().classes()).toContain(inputGroupClass);
+ expect(findGlFormGroupInvalidFeedback()).toEqual(feedback);
+ });
+ });
+});
diff --git a/spec/frontend/pipeline_wizard/components/widgets_spec.js b/spec/frontend/pipeline_wizard/components/widgets_spec.js
new file mode 100644
index 00000000000..5944c76c5d0
--- /dev/null
+++ b/spec/frontend/pipeline_wizard/components/widgets_spec.js
@@ -0,0 +1,49 @@
+import fs from 'fs';
+import { mount } from '@vue/test-utils';
+import { Document } from 'yaml';
+import InputWrapper from '~/pipeline_wizard/components/input.vue';
+
+describe('Test all widgets in ./widgets/* whether they provide a minimal api', () => {
+ const createComponent = (props = {}, mountFunc = mount) => {
+ mountFunc(InputWrapper, {
+ propsData: {
+ template: new Document({
+ template: {
+ bar: 'baz',
+ foo: { some: '$TARGET' },
+ },
+ }).get('template'),
+ compiled: new Document({ bar: 'baz', foo: { some: '$TARGET' } }),
+ target: '$TARGET',
+ widget: 'text',
+ label: 'some label (required by the text widget)',
+ ...props,
+ },
+ });
+ };
+
+ const widgets = fs
+ .readdirSync('./app/assets/javascripts/pipeline_wizard/components/widgets')
+ .map((filename) => [filename.match(/^(.*).vue$/)[1]]);
+ let consoleErrorSpy;
+
+ beforeAll(() => {
+ consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
+ });
+
+ afterAll(() => {
+ consoleErrorSpy.mockRestore();
+ });
+
+ describe.each(widgets)('`%s` Widget', (name) => {
+ it('passes the input validator', () => {
+ const validatorFunc = InputWrapper.props.widget.validator;
+ expect(validatorFunc(name)).toBe(true);
+ });
+
+ it('mounts without error', () => {
+ createComponent({ widget: name });
+ expect(consoleErrorSpy).not.toHaveBeenCalled();
+ });
+ });
+});
diff --git a/spec/frontend/pipeline_wizard/components/wrapper_spec.js b/spec/frontend/pipeline_wizard/components/wrapper_spec.js
new file mode 100644
index 00000000000..bd1679baf48
--- /dev/null
+++ b/spec/frontend/pipeline_wizard/components/wrapper_spec.js
@@ -0,0 +1,250 @@
+import { Document, parseDocument } from 'yaml';
+import { GlProgressBar } from '@gitlab/ui';
+import { nextTick } from 'vue';
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
+import PipelineWizardWrapper, { i18n } from '~/pipeline_wizard/components/wrapper.vue';
+import WizardStep from '~/pipeline_wizard/components/step.vue';
+import CommitStep from '~/pipeline_wizard/components/commit.vue';
+import YamlEditor from '~/pipeline_wizard/components/editor.vue';
+import { sprintf } from '~/locale';
+import { steps as stepsYaml } from '../mock/yaml';
+
+describe('Pipeline Wizard - wrapper.vue', () => {
+ let wrapper;
+ const steps = parseDocument(stepsYaml).toJS();
+
+ const getAsYamlNode = (value) => new Document(value).contents;
+ const createComponent = (props = {}) => {
+ wrapper = shallowMountExtended(PipelineWizardWrapper, {
+ propsData: {
+ projectPath: '/user/repo',
+ defaultBranch: 'main',
+ filename: '.gitlab-ci.yml',
+ steps: getAsYamlNode(steps),
+ ...props,
+ },
+ });
+ };
+ const getEditorContent = () => {
+ return wrapper.getComponent(YamlEditor).attributes().doc.toString();
+ };
+ const getStepWrapper = () => wrapper.getComponent(WizardStep);
+ const getGlProgressBarWrapper = () => wrapper.getComponent(GlProgressBar);
+
+ describe('display', () => {
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ it('shows the steps', () => {
+ createComponent();
+
+ expect(getStepWrapper().exists()).toBe(true);
+ });
+
+ it('shows the progress bar', () => {
+ createComponent();
+
+ const expectedMessage = sprintf(i18n.stepNofN, {
+ currentStep: 1,
+ stepCount: 3,
+ });
+
+ expect(wrapper.findByTestId('step-count').text()).toBe(expectedMessage);
+ expect(getGlProgressBarWrapper().exists()).toBe(true);
+ });
+
+ it('shows the editor', () => {
+ createComponent();
+
+ expect(wrapper.findComponent(YamlEditor).exists()).toBe(true);
+ });
+
+ it('shows the editor header with the default filename', () => {
+ createComponent();
+
+ const expectedMessage = sprintf(i18n.draft, {
+ filename: '.gitlab-ci.yml',
+ });
+
+ expect(wrapper.findByTestId('editor-header').text()).toBe(expectedMessage);
+ });
+
+ it('shows the editor header with a custom filename', async () => {
+ const filename = 'my-file.yml';
+ createComponent({
+ filename,
+ });
+
+ const expectedMessage = sprintf(i18n.draft, {
+ filename,
+ });
+
+ expect(wrapper.findByTestId('editor-header').text()).toBe(expectedMessage);
+ });
+ });
+
+ describe('steps', () => {
+ const totalSteps = steps.length + 1;
+
+ // **Note** on `expectProgressBarValue`
+ // Why are we expecting 50% here and not 66% or even 100%?
+ // The reason is mostly a UX thing.
+ // First, we count the commit step as an extra step, so that would
+ // be 66% by now (2 of 3).
+ // But then we add yet another one to the calc, because when we
+ // arrived on the second step's page, it's not *completed* (which is
+ // what the progress bar indicates). So in that case we're at 33%.
+ // Lastly, we want to start out with the progress bar not at zero,
+ // because UX research indicates that makes a process like this less
+ // intimidating, so we're always adding one step to the value bar
+ // (but not to the step counter. Now we're back at 50%.
+ describe.each`
+ step | navigationEventChain | expectStepNumber | expectCommitStepShown | expectStepDef | expectProgressBarValue
+ ${'initial step'} | ${[]} | ${1} | ${false} | ${steps[0]} | ${25}
+ ${'second step'} | ${['next']} | ${2} | ${false} | ${steps[1]} | ${50}
+ ${'commit step'} | ${['next', 'next']} | ${3} | ${true} | ${null} | ${75}
+ ${'stepping back'} | ${['next', 'back']} | ${1} | ${false} | ${steps[0]} | ${25}
+ ${'clicking next>next>back'} | ${['next', 'next', 'back']} | ${2} | ${false} | ${steps[1]} | ${50}
+ ${'clicking all the way through and back'} | ${['next', 'next', 'back', 'back']} | ${1} | ${false} | ${steps[0]} | ${25}
+ `(
+ '$step',
+ ({
+ navigationEventChain,
+ expectStepNumber,
+ expectCommitStepShown,
+ expectStepDef,
+ expectProgressBarValue,
+ }) => {
+ beforeAll(async () => {
+ createComponent();
+ for (const emittedValue of navigationEventChain) {
+ wrapper.findComponent({ ref: 'step' }).vm.$emit(emittedValue);
+ // We have to wait for the next step to be mounted
+ // before we can emit the next event, so we have to await
+ // inside the loop.
+ // eslint-disable-next-line no-await-in-loop
+ await nextTick();
+ }
+ });
+
+ afterAll(() => {
+ wrapper.destroy();
+ });
+
+ if (expectCommitStepShown) {
+ it('does not show the step wrapper', async () => {
+ expect(wrapper.findComponent(WizardStep).exists()).toBe(false);
+ });
+
+ it('shows the commit step page', () => {
+ expect(wrapper.findComponent(CommitStep).exists()).toBe(true);
+ });
+ } else {
+ it('passes the correct step config to the step component', async () => {
+ expect(getStepWrapper().props('inputs')).toMatchObject(expectStepDef.inputs);
+ });
+
+ it('does not show the commit step page', () => {
+ expect(wrapper.findComponent(CommitStep).exists()).toBe(false);
+ });
+ }
+
+ it('updates the progress bar', () => {
+ expect(getGlProgressBarWrapper().attributes('value')).toBe(`${expectProgressBarValue}`);
+ });
+
+ it('updates the step number', () => {
+ const expectedMessage = sprintf(i18n.stepNofN, {
+ currentStep: expectStepNumber,
+ stepCount: totalSteps,
+ });
+
+ expect(wrapper.findByTestId('step-count').text()).toBe(expectedMessage);
+ });
+ },
+ );
+ });
+
+ describe('editor overlay', () => {
+ beforeAll(() => {
+ createComponent();
+ });
+
+ afterAll(() => {
+ wrapper.destroy();
+ });
+
+ it('initially shows a placeholder', async () => {
+ const editorContent = getEditorContent();
+
+ await nextTick();
+
+ expect(editorContent).toBe('foo: $FOO\nbar: $BAR\n');
+ });
+
+ it('shows an overlay with help text after setup', () => {
+ expect(wrapper.findByTestId('placeholder-overlay').exists()).toBe(true);
+ expect(wrapper.findByTestId('filename').text()).toBe('.gitlab-ci.yml');
+ expect(wrapper.findByTestId('description').text()).toBe(i18n.overlayMessage);
+ });
+
+ it('does not show overlay when content has changed', async () => {
+ const newCompiledDoc = new Document({ faa: 'bur' });
+
+ await getStepWrapper().vm.$emit('update:compiled', newCompiledDoc);
+ await nextTick();
+
+ const overlay = wrapper.findByTestId('placeholder-overlay');
+
+ expect(overlay.exists()).toBe(false);
+ });
+ });
+
+ describe('editor updates', () => {
+ beforeAll(() => {
+ createComponent();
+ });
+
+ afterAll(() => {
+ wrapper.destroy();
+ });
+
+ it('editor reflects changes', async () => {
+ const newCompiledDoc = new Document({ faa: 'bur' });
+ await getStepWrapper().vm.$emit('update:compiled', newCompiledDoc);
+
+ expect(getEditorContent()).toBe(newCompiledDoc.toString());
+ });
+ });
+
+ describe('line highlights', () => {
+ beforeAll(() => {
+ createComponent();
+ });
+
+ afterAll(() => {
+ wrapper.destroy();
+ });
+
+ it('highlight requests by the step get passed on to the editor', async () => {
+ const highlight = 'foo';
+
+ await getStepWrapper().vm.$emit('update:highlight', highlight);
+
+ expect(wrapper.getComponent(YamlEditor).props('highlight')).toBe(highlight);
+ });
+
+ it('removes the highlight when clicking through to the commit step', async () => {
+ // Simulate clicking through all steps until the last one
+ await Promise.all(
+ steps.map(async () => {
+ await getStepWrapper().vm.$emit('next');
+ await nextTick();
+ }),
+ );
+
+ expect(wrapper.getComponent(YamlEditor).props('highlight')).toBe(null);
+ });
+ });
+});
diff --git a/spec/frontend/pipeline_wizard/mock/yaml.js b/spec/frontend/pipeline_wizard/mock/yaml.js
new file mode 100644
index 00000000000..5eaeaa32a8c
--- /dev/null
+++ b/spec/frontend/pipeline_wizard/mock/yaml.js
@@ -0,0 +1,85 @@
+export const stepInputs = `
+- label: "Build Steps"
+ description: "Enter the steps necessary for your application."
+ widget: text
+ target: $BUILD_STEPS
+- label: "Select a deployment branch"
+ description: "Select the branch we should use to generate your site from."
+ widget: text
+ target: $BRANCH
+ pattern: "^[a-z]+$"
+ invalidFeedback: "This field may only contain lowercase letters"
+ required: true
+`;
+
+export const stepTemplate = `template:
+ pages:
+ script: $BUILD_STEPS
+ artifacts:
+ paths:
+ - public
+ only:
+ - $BRANCH
+`;
+
+export const compiledYamlBeforeSetup = `abc: def`;
+
+export const compiledYamlAfterInitialLoad = `abc: def
+pages:
+ script: $BUILD_STEPS
+ artifacts:
+ paths:
+ - public
+ only:
+ - $BRANCH
+`;
+
+export const compiledYaml = `abc: def
+pages:
+ script: foo
+ artifacts:
+ paths:
+ - public
+ only:
+ - bar
+`;
+
+export const steps = `
+- inputs:
+ - label: foo
+ target: $FOO
+ widget: text
+ template:
+ foo: $FOO
+- inputs:
+ - label: bar
+ target: $BAR
+ widget: text
+ template:
+ bar: $BAR
+`;
+
+export const fullTemplate = `
+title: some title
+description: some description
+filename: foo.yml
+steps:
+ - inputs:
+ - widget: text
+ label: foo
+ target: $BAR
+ template:
+ foo: $BAR
+`;
+
+export const fullTemplateWithoutFilename = `
+title: some title
+description: some description
+steps:
+ - inputs:
+ - widget: text
+ label: foo
+ target: $BAR
+ template:
+ foo: $BAR
+`;
diff --git a/spec/frontend/pipeline_wizard/pipeline_wizard_spec.js b/spec/frontend/pipeline_wizard/pipeline_wizard_spec.js
new file mode 100644
index 00000000000..dd0304518a3
--- /dev/null
+++ b/spec/frontend/pipeline_wizard/pipeline_wizard_spec.js
@@ -0,0 +1,102 @@
+import { parseDocument } from 'yaml';
+import PipelineWizard from '~/pipeline_wizard/pipeline_wizard.vue';
+import PipelineWizardWrapper from '~/pipeline_wizard/components/wrapper.vue';
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
+import {
+ fullTemplate as template,
+ fullTemplateWithoutFilename as templateWithoutFilename,
+} from './mock/yaml';
+
+const projectPath = 'foo/bar';
+const defaultBranch = 'main';
+
+describe('PipelineWizard', () => {
+ let wrapper;
+
+ const createComponent = (props = {}) => {
+ wrapper = shallowMountExtended(PipelineWizard, {
+ propsData: {
+ projectPath,
+ defaultBranch,
+ template,
+ ...props,
+ },
+ });
+ };
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ it('mounts without error', () => {
+ const consoleSpy = jest.spyOn(console, 'error');
+
+ createComponent();
+
+ expect(consoleSpy).not.toHaveBeenCalled();
+ expect(wrapper.exists()).toBe(true);
+ });
+
+ it('mounts the wizard wrapper', () => {
+ createComponent();
+
+ expect(wrapper.findComponent(PipelineWizardWrapper).exists()).toBe(true);
+ });
+
+ it('passes the correct steps prop to the wizard wrapper', () => {
+ createComponent();
+
+ expect(wrapper.findComponent(PipelineWizardWrapper).props('steps')).toEqual(
+ parseDocument(template).get('steps'),
+ );
+ });
+
+ it('passes all other expected props to the wizard wrapper', () => {
+ createComponent();
+
+ expect(wrapper.findComponent(PipelineWizardWrapper).props()).toEqual(
+ expect.objectContaining({
+ defaultBranch,
+ projectPath,
+ filename: parseDocument(template).get('filename'),
+ }),
+ );
+ });
+
+ it('passes ".gitlab-ci.yml" as default filename to the wizard wrapper', () => {
+ createComponent({ template: templateWithoutFilename });
+
+ expect(wrapper.findComponent(PipelineWizardWrapper).attributes('filename')).toBe(
+ '.gitlab-ci.yml',
+ );
+ });
+
+ it('allows overriding the defaultFilename with `defaultFilename` prop', () => {
+ const defaultFilename = 'foobar.yml';
+
+ createComponent({
+ template: templateWithoutFilename,
+ defaultFilename,
+ });
+
+ expect(wrapper.findComponent(PipelineWizardWrapper).attributes('filename')).toBe(
+ defaultFilename,
+ );
+ });
+
+ it('displays the title', () => {
+ createComponent();
+
+ expect(wrapper.findByTestId('title').text()).toBe(
+ parseDocument(template).get('title').toString(),
+ );
+ });
+
+ it('displays the description', () => {
+ createComponent();
+
+ expect(wrapper.findByTestId('description').text()).toBe(
+ parseDocument(template).get('description').toString(),
+ );
+ });
+});
diff --git a/spec/frontend/pipeline_wizard/validators_spec.js b/spec/frontend/pipeline_wizard/validators_spec.js
new file mode 100644
index 00000000000..1276c642f30
--- /dev/null
+++ b/spec/frontend/pipeline_wizard/validators_spec.js
@@ -0,0 +1,22 @@
+import { Document, parseDocument } from 'yaml';
+import { isValidStepSeq } from '~/pipeline_wizard/validators';
+import { steps as stepsYaml } from './mock/yaml';
+
+describe('prop validation', () => {
+ const steps = parseDocument(stepsYaml).toJS();
+ const getAsYamlNode = (value) => new Document(value).contents;
+
+ it('allows passing yaml nodes to the steps prop', () => {
+ const validSteps = getAsYamlNode(steps);
+ expect(isValidStepSeq(validSteps)).toBe(true);
+ });
+
+ it.each`
+ scenario | stepsValue
+ ${'not a seq'} | ${{ foo: 'bar' }}
+ ${'a step missing an input'} | ${[{ template: 'baz: boo' }]}
+ ${'an empty seq'} | ${[]}
+ `('throws an error when passing $scenario to the steps prop', ({ stepsValue }) => {
+ expect(isValidStepSeq(stepsValue)).toBe(false);
+ });
+});
diff --git a/spec/frontend/pipelines/components/jobs/jobs_app_spec.js b/spec/frontend/pipelines/components/jobs/jobs_app_spec.js
index 65814ad9a7f..81e19a6c221 100644
--- a/spec/frontend/pipelines/components/jobs/jobs_app_spec.js
+++ b/spec/frontend/pipelines/components/jobs/jobs_app_spec.js
@@ -1,4 +1,4 @@
-import { GlIntersectionObserver, GlSkeletonLoader } from '@gitlab/ui';
+import { GlIntersectionObserver, GlSkeletonLoader, GlLoadingIcon } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
import VueApollo from 'vue-apollo';
@@ -19,6 +19,7 @@ describe('Jobs app', () => {
let resolverSpy;
const findSkeletonLoader = () => wrapper.findComponent(GlSkeletonLoader);
+ const findLoadingSpinner = () => wrapper.findComponent(GlLoadingIcon);
const findJobsTable = () => wrapper.findComponent(JobsTable);
const triggerInfiniteScroll = () =>
@@ -48,7 +49,29 @@ describe('Jobs app', () => {
wrapper.destroy();
});
- it('displays the loading state', () => {
+ describe('loading spinner', () => {
+ beforeEach(async () => {
+ createComponent(resolverSpy);
+
+ await waitForPromises();
+
+ triggerInfiniteScroll();
+ });
+
+ it('displays loading spinner when fetching more jobs', () => {
+ expect(findLoadingSpinner().exists()).toBe(true);
+ expect(findSkeletonLoader().exists()).toBe(false);
+ });
+
+ it('hides loading spinner after jobs have been fetched', async () => {
+ await waitForPromises();
+
+ expect(findLoadingSpinner().exists()).toBe(false);
+ expect(findSkeletonLoader().exists()).toBe(false);
+ });
+ });
+
+ it('displays the skeleton loader', () => {
createComponent(resolverSpy);
expect(findSkeletonLoader().exists()).toBe(true);
@@ -91,7 +114,7 @@ describe('Jobs app', () => {
});
});
- it('does not display main loading state again after fetchMore', async () => {
+ it('does not display skeleton loader again after fetchMore', async () => {
createComponent(resolverSpy);
expect(findSkeletonLoader().exists()).toBe(true);
diff --git a/spec/frontend/pipelines/components/pipelines_filtered_search_spec.js b/spec/frontend/pipelines/components/pipelines_filtered_search_spec.js
index 97b59a09518..0822b293f75 100644
--- a/spec/frontend/pipelines/components/pipelines_filtered_search_spec.js
+++ b/spec/frontend/pipelines/components/pipelines_filtered_search_spec.js
@@ -27,6 +27,7 @@ describe('Pipelines filtered search', () => {
wrapper = mount(PipelinesFilteredSearch, {
propsData: {
projectId: '21',
+ defaultBranchName: 'main',
params,
},
attachTo: document.body,
@@ -69,6 +70,7 @@ describe('Pipelines filtered search', () => {
title: 'Branch name',
unique: true,
projectId: '21',
+ defaultBranchName: 'main',
operators: OPERATOR_IS_ONLY,
});
diff --git a/spec/frontend/pipelines/header_component_spec.js b/spec/frontend/pipelines/header_component_spec.js
index 1d89f949564..c4639bd8e16 100644
--- a/spec/frontend/pipelines/header_component_spec.js
+++ b/spec/frontend/pipelines/header_component_spec.js
@@ -1,5 +1,7 @@
import { GlModal, GlLoadingIcon } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
+import { nextTick } from 'vue';
+import waitForPromises from 'helpers/wait_for_promises';
import HeaderComponent from '~/pipelines/components/header_component.vue';
import cancelPipelineMutation from '~/pipelines/graphql/mutations/cancel_pipeline.mutation.graphql';
import deletePipelineMutation from '~/pipelines/graphql/mutations/delete_pipeline.mutation.graphql';
@@ -17,6 +19,7 @@ import {
describe('Pipeline details header', () => {
let wrapper;
let glModalDirective;
+ let mutate = jest.fn();
const findDeleteModal = () => wrapper.find(GlModal);
const findRetryButton = () => wrapper.find('[data-testid="retryPipeline"]');
@@ -44,7 +47,7 @@ describe('Pipeline details header', () => {
startPolling: jest.fn(),
},
},
- mutate: jest.fn(),
+ mutate,
};
return shallowMount(HeaderComponent, {
@@ -120,6 +123,26 @@ describe('Pipeline details header', () => {
});
});
+ describe('Retry action failed', () => {
+ beforeEach(() => {
+ mutate = jest.fn().mockRejectedValue('error');
+
+ wrapper = createComponent(mockCancelledPipelineHeader);
+ });
+
+ it('retry button loading state should reset on error', async () => {
+ findRetryButton().vm.$emit('click');
+
+ await nextTick();
+
+ expect(findRetryButton().props('loading')).toBe(true);
+
+ await waitForPromises();
+
+ expect(findRetryButton().props('loading')).toBe(false);
+ });
+ });
+
describe('Cancel action', () => {
beforeEach(() => {
wrapper = createComponent(mockRunningPipelineHeader);
diff --git a/spec/frontend/pipelines/pipeline_labels_spec.js b/spec/frontend/pipelines/pipeline_labels_spec.js
new file mode 100644
index 00000000000..ca0229b1cbe
--- /dev/null
+++ b/spec/frontend/pipelines/pipeline_labels_spec.js
@@ -0,0 +1,168 @@
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
+import { trimText } from 'helpers/text_helper';
+import PipelineLabelsComponent from '~/pipelines/components/pipelines_list/pipeline_labels.vue';
+import { mockPipeline } from './mock_data';
+
+const projectPath = 'test/test';
+
+describe('Pipeline label component', () => {
+ let wrapper;
+
+ const findScheduledTag = () => wrapper.findByTestId('pipeline-url-scheduled');
+ const findLatestTag = () => wrapper.findByTestId('pipeline-url-latest');
+ const findYamlTag = () => wrapper.findByTestId('pipeline-url-yaml');
+ const findStuckTag = () => wrapper.findByTestId('pipeline-url-stuck');
+ const findAutoDevopsTag = () => wrapper.findByTestId('pipeline-url-autodevops');
+ const findAutoDevopsTagLink = () => wrapper.findByTestId('pipeline-url-autodevops-link');
+ const findDetachedTag = () => wrapper.findByTestId('pipeline-url-detached');
+ const findFailureTag = () => wrapper.findByTestId('pipeline-url-failure');
+ const findForkTag = () => wrapper.findByTestId('pipeline-url-fork');
+ const findTrainTag = () => wrapper.findByTestId('pipeline-url-train');
+
+ const defaultProps = mockPipeline(projectPath);
+
+ const createComponent = (props) => {
+ wrapper = shallowMountExtended(PipelineLabelsComponent, {
+ propsData: { ...defaultProps, ...props },
+ provide: {
+ targetProjectFullPath: projectPath,
+ },
+ });
+ };
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ it('should not render tags when flags are not set', () => {
+ createComponent();
+
+ expect(findStuckTag().exists()).toBe(false);
+ expect(findLatestTag().exists()).toBe(false);
+ expect(findYamlTag().exists()).toBe(false);
+ expect(findAutoDevopsTag().exists()).toBe(false);
+ expect(findFailureTag().exists()).toBe(false);
+ expect(findScheduledTag().exists()).toBe(false);
+ expect(findForkTag().exists()).toBe(false);
+ expect(findTrainTag().exists()).toBe(false);
+ });
+
+ it('should render the stuck tag when flag is provided', () => {
+ const stuckPipeline = defaultProps.pipeline;
+ stuckPipeline.flags.stuck = true;
+
+ createComponent({
+ ...stuckPipeline.pipeline,
+ });
+
+ expect(findStuckTag().text()).toContain('stuck');
+ });
+
+ it('should render latest tag when flag is provided', () => {
+ const latestPipeline = defaultProps.pipeline;
+ latestPipeline.flags.latest = true;
+
+ createComponent({
+ ...latestPipeline,
+ });
+
+ expect(findLatestTag().text()).toContain('latest');
+ });
+
+ it('should render a yaml badge when it is invalid', () => {
+ const yamlPipeline = defaultProps.pipeline;
+ yamlPipeline.flags.yaml_errors = true;
+
+ createComponent({
+ ...yamlPipeline,
+ });
+
+ expect(findYamlTag().text()).toContain('yaml invalid');
+ });
+
+ it('should render an autodevops badge when flag is provided', () => {
+ const autoDevopsPipeline = defaultProps.pipeline;
+ autoDevopsPipeline.flags.auto_devops = true;
+
+ createComponent({
+ ...autoDevopsPipeline,
+ });
+
+ expect(trimText(findAutoDevopsTag().text())).toBe('Auto DevOps');
+
+ expect(findAutoDevopsTagLink().attributes()).toMatchObject({
+ href: '/help/topics/autodevops/index.md',
+ target: '_blank',
+ });
+ });
+
+ it('should render a detached badge when flag is provided', () => {
+ const detachedMRPipeline = defaultProps.pipeline;
+ detachedMRPipeline.flags.detached_merge_request_pipeline = true;
+
+ createComponent({
+ ...detachedMRPipeline,
+ });
+
+ expect(findDetachedTag().text()).toBe('merge request');
+ });
+
+ it('should render error badge when pipeline has a failure reason set', () => {
+ const failedPipeline = defaultProps.pipeline;
+ failedPipeline.flags.failure_reason = true;
+ failedPipeline.failure_reason = 'some reason';
+
+ createComponent({
+ ...failedPipeline,
+ });
+
+ expect(findFailureTag().text()).toContain('error');
+ expect(findFailureTag().attributes('title')).toContain('some reason');
+ });
+
+ it('should render scheduled badge when pipeline was triggered by a schedule', () => {
+ const scheduledPipeline = defaultProps.pipeline;
+ scheduledPipeline.source = 'schedule';
+
+ createComponent({
+ ...scheduledPipeline,
+ });
+
+ expect(findScheduledTag().exists()).toBe(true);
+ expect(findScheduledTag().text()).toContain('Scheduled');
+ });
+
+ it('should render the fork badge when the pipeline was run in a fork', () => {
+ const forkedPipeline = defaultProps.pipeline;
+ forkedPipeline.project.full_path = '/test/forked';
+
+ createComponent({
+ ...forkedPipeline,
+ });
+
+ expect(findForkTag().exists()).toBe(true);
+ expect(findForkTag().text()).toBe('fork');
+ });
+
+ it('should render the train badge when the pipeline is a merge train pipeline', () => {
+ const mergeTrainPipeline = defaultProps.pipeline;
+ mergeTrainPipeline.flags.merge_train_pipeline = true;
+
+ createComponent({
+ ...mergeTrainPipeline,
+ });
+
+ expect(findTrainTag().text()).toBe('merge train');
+ });
+
+ it('should not render the train badge when the pipeline is not a merge train pipeline', () => {
+ const mergeTrainPipeline = defaultProps.pipeline;
+ mergeTrainPipeline.flags.merge_train_pipeline = false;
+
+ createComponent({
+ ...mergeTrainPipeline,
+ });
+
+ expect(findTrainTag().exists()).toBe(false);
+ });
+});
diff --git a/spec/frontend/pipelines/pipeline_url_spec.js b/spec/frontend/pipelines/pipeline_url_spec.js
index 2f083faaaa6..2a0aeed917c 100644
--- a/spec/frontend/pipelines/pipeline_url_spec.js
+++ b/spec/frontend/pipelines/pipeline_url_spec.js
@@ -1,5 +1,4 @@
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
-import { trimText } from 'helpers/text_helper';
import PipelineUrlComponent from '~/pipelines/components/pipelines_list/pipeline_url.vue';
import { mockPipeline, mockPipelineBranch, mockPipelineTag } from './mock_data';
@@ -10,16 +9,6 @@ describe('Pipeline Url Component', () => {
const findTableCell = () => wrapper.findByTestId('pipeline-url-table-cell');
const findPipelineUrlLink = () => wrapper.findByTestId('pipeline-url-link');
- const findScheduledTag = () => wrapper.findByTestId('pipeline-url-scheduled');
- const findLatestTag = () => wrapper.findByTestId('pipeline-url-latest');
- const findYamlTag = () => wrapper.findByTestId('pipeline-url-yaml');
- const findFailureTag = () => wrapper.findByTestId('pipeline-url-failure');
- const findAutoDevopsTag = () => wrapper.findByTestId('pipeline-url-autodevops');
- const findAutoDevopsTagLink = () => wrapper.findByTestId('pipeline-url-autodevops-link');
- const findStuckTag = () => wrapper.findByTestId('pipeline-url-stuck');
- const findDetachedTag = () => wrapper.findByTestId('pipeline-url-detached');
- const findForkTag = () => wrapper.findByTestId('pipeline-url-fork');
- const findTrainTag = () => wrapper.findByTestId('pipeline-url-train');
const findRefName = () => wrapper.findByTestId('merge-request-ref');
const findCommitShortSha = () => wrapper.findByTestId('commit-short-sha');
const findCommitIcon = () => wrapper.findByTestId('commit-icon');
@@ -30,14 +19,11 @@ describe('Pipeline Url Component', () => {
const defaultProps = mockPipeline(projectPath);
- const createComponent = (props, rearrangePipelinesTable = false) => {
+ const createComponent = (props) => {
wrapper = shallowMountExtended(PipelineUrlComponent, {
propsData: { ...defaultProps, ...props },
provide: {
targetProjectFullPath: projectPath,
- glFeatures: {
- rearrangePipelinesTable,
- },
},
});
};
@@ -47,190 +33,44 @@ describe('Pipeline Url Component', () => {
wrapper = null;
});
- describe('with the rearrangePipelinesTable feature flag turned off', () => {
- it('should render pipeline url table cell', () => {
- createComponent();
+ it('should render pipeline url table cell', () => {
+ createComponent();
- expect(findTableCell().exists()).toBe(true);
- });
-
- it('should render a link the provided path and id', () => {
- createComponent();
-
- expect(findPipelineUrlLink().attributes('href')).toBe('foo');
-
- expect(findPipelineUrlLink().text()).toBe('#1');
- });
-
- it('should not render tags when flags are not set', () => {
- createComponent();
-
- expect(findStuckTag().exists()).toBe(false);
- expect(findLatestTag().exists()).toBe(false);
- expect(findYamlTag().exists()).toBe(false);
- expect(findAutoDevopsTag().exists()).toBe(false);
- expect(findFailureTag().exists()).toBe(false);
- expect(findScheduledTag().exists()).toBe(false);
- expect(findForkTag().exists()).toBe(false);
- expect(findTrainTag().exists()).toBe(false);
- });
-
- it('should render the stuck tag when flag is provided', () => {
- const stuckPipeline = defaultProps.pipeline;
- stuckPipeline.flags.stuck = true;
-
- createComponent({
- ...stuckPipeline.pipeline,
- });
-
- expect(findStuckTag().text()).toContain('stuck');
- });
-
- it('should render latest tag when flag is provided', () => {
- const latestPipeline = defaultProps.pipeline;
- latestPipeline.flags.latest = true;
-
- createComponent({
- ...latestPipeline,
- });
-
- expect(findLatestTag().text()).toContain('latest');
- });
-
- it('should render a yaml badge when it is invalid', () => {
- const yamlPipeline = defaultProps.pipeline;
- yamlPipeline.flags.yaml_errors = true;
-
- createComponent({
- ...yamlPipeline,
- });
-
- expect(findYamlTag().text()).toContain('yaml invalid');
- });
-
- it('should render an autodevops badge when flag is provided', () => {
- const autoDevopsPipeline = defaultProps.pipeline;
- autoDevopsPipeline.flags.auto_devops = true;
-
- createComponent({
- ...autoDevopsPipeline,
- });
-
- expect(trimText(findAutoDevopsTag().text())).toBe('Auto DevOps');
-
- expect(findAutoDevopsTagLink().attributes()).toMatchObject({
- href: '/help/topics/autodevops/index.md',
- target: '_blank',
- });
- });
-
- it('should render a detached badge when flag is provided', () => {
- const detachedMRPipeline = defaultProps.pipeline;
- detachedMRPipeline.flags.detached_merge_request_pipeline = true;
-
- createComponent({
- ...detachedMRPipeline,
- });
-
- expect(findDetachedTag().text()).toContain('detached');
- });
-
- it('should render error badge when pipeline has a failure reason set', () => {
- const failedPipeline = defaultProps.pipeline;
- failedPipeline.flags.failure_reason = true;
- failedPipeline.failure_reason = 'some reason';
-
- createComponent({
- ...failedPipeline,
- });
-
- expect(findFailureTag().text()).toContain('error');
- expect(findFailureTag().attributes('title')).toContain('some reason');
- });
-
- it('should render scheduled badge when pipeline was triggered by a schedule', () => {
- const scheduledPipeline = defaultProps.pipeline;
- scheduledPipeline.source = 'schedule';
-
- createComponent({
- ...scheduledPipeline,
- });
-
- expect(findScheduledTag().exists()).toBe(true);
- expect(findScheduledTag().text()).toContain('Scheduled');
- });
-
- it('should render the fork badge when the pipeline was run in a fork', () => {
- const forkedPipeline = defaultProps.pipeline;
- forkedPipeline.project.full_path = '/test/forked';
-
- createComponent({
- ...forkedPipeline,
- });
-
- expect(findForkTag().exists()).toBe(true);
- expect(findForkTag().text()).toBe('fork');
- });
-
- it('should render the train badge when the pipeline is a merge train pipeline', () => {
- const mergeTrainPipeline = defaultProps.pipeline;
- mergeTrainPipeline.flags.merge_train_pipeline = true;
-
- createComponent({
- ...mergeTrainPipeline,
- });
+ expect(findTableCell().exists()).toBe(true);
+ });
- expect(findTrainTag().text()).toContain('train');
- });
+ it('should render a link the provided path and id', () => {
+ createComponent();
- it('should not render the train badge when the pipeline is not a merge train pipeline', () => {
- const mergeTrainPipeline = defaultProps.pipeline;
- mergeTrainPipeline.flags.merge_train_pipeline = false;
+ expect(findPipelineUrlLink().attributes('href')).toBe('foo');
- createComponent({
- ...mergeTrainPipeline,
- });
+ expect(findPipelineUrlLink().text()).toBe('#1');
+ });
- expect(findTrainTag().exists()).toBe(false);
- });
+ it('should render the commit title, commit reference and commit-short-sha', () => {
+ createComponent({}, true);
- it('should not render the commit wrapper and commit-short-sha', () => {
- createComponent();
+ const commitWrapper = findCommitTitleContainer();
- expect(findCommitTitleContainer().exists()).toBe(false);
- expect(findCommitShortSha().exists()).toBe(false);
- });
+ expect(findCommitTitle(commitWrapper).exists()).toBe(true);
+ expect(findRefName().exists()).toBe(true);
+ expect(findCommitShortSha().exists()).toBe(true);
});
- describe('with the rearrangePipelinesTable feature flag turned on', () => {
- it('should render the commit title, commit reference and commit-short-sha', () => {
- createComponent({}, true);
+ it('should render commit icon tooltip', () => {
+ createComponent({}, true);
- const commitWrapper = findCommitTitleContainer();
-
- expect(findCommitTitle(commitWrapper).exists()).toBe(true);
- expect(findRefName().exists()).toBe(true);
- expect(findCommitShortSha().exists()).toBe(true);
- });
-
- it('should render commit icon tooltip', () => {
- createComponent({}, true);
+ expect(findCommitIcon().attributes('title')).toBe('Commit');
+ });
- expect(findCommitIcon().attributes('title')).toBe('Commit');
- });
+ it.each`
+ pipeline | expectedTitle
+ ${mockPipelineTag()} | ${'Tag'}
+ ${mockPipelineBranch()} | ${'Branch'}
+ ${mockPipeline()} | ${'Merge Request'}
+ `('should render tooltip $expectedTitle for commit icon type', ({ pipeline, expectedTitle }) => {
+ createComponent(pipeline, true);
- it.each`
- pipeline | expectedTitle
- ${mockPipelineTag()} | ${'Tag'}
- ${mockPipelineBranch()} | ${'Branch'}
- ${mockPipeline()} | ${'Merge Request'}
- `(
- 'should render tooltip $expectedTitle for commit icon type',
- ({ pipeline, expectedTitle }) => {
- createComponent(pipeline, true);
-
- expect(findCommitIconType().attributes('title')).toBe(expectedTitle);
- },
- );
+ expect(findCommitIconType().attributes('title')).toBe(expectedTitle);
});
});
diff --git a/spec/frontend/pipelines/pipelines_ci_templates_spec.js b/spec/frontend/pipelines/pipelines_ci_templates_spec.js
index db66b675fb9..7064f7448ec 100644
--- a/spec/frontend/pipelines/pipelines_ci_templates_spec.js
+++ b/spec/frontend/pipelines/pipelines_ci_templates_spec.js
@@ -1,7 +1,19 @@
import '~/commons';
-import { shallowMount } from '@vue/test-utils';
+import { GlButton, GlSprintf } from '@gitlab/ui';
+import { sprintf } from '~/locale';
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import { mockTracking } from 'helpers/tracking_helper';
+import { stubExperiments } from 'helpers/experimentation_helper';
+import GitlabExperiment from '~/experimentation/components/gitlab_experiment.vue';
+import ExperimentTracking from '~/experimentation/experiment_tracking';
import PipelinesCiTemplate from '~/pipelines/components/pipelines_list/pipelines_ci_templates.vue';
+import {
+ RUNNERS_AVAILABILITY_SECTION_EXPERIMENT_NAME,
+ RUNNERS_SETTINGS_LINK_CLICKED_EVENT,
+ RUNNERS_DOCUMENTATION_LINK_CLICKED_EVENT,
+ RUNNERS_SETTINGS_BUTTON_CLICKED_EVENT,
+ I18N,
+} from '~/pipeline_editor/constants';
const pipelineEditorPath = '/-/ci/editor';
const suggestedCiTemplates = [
@@ -10,16 +22,20 @@ const suggestedCiTemplates = [
{ name: 'C++', logo: '/assets/illustrations/logos/c_plus_plus.svg' },
];
+jest.mock('~/experimentation/experiment_tracking');
+
describe('Pipelines CI Templates', () => {
let wrapper;
let trackingSpy;
- const createWrapper = () => {
- return shallowMount(PipelinesCiTemplate, {
+ const createWrapper = (propsData = {}, stubs = {}) => {
+ return shallowMountExtended(PipelinesCiTemplate, {
provide: {
pipelineEditorPath,
suggestedCiTemplates,
},
+ propsData,
+ stubs,
});
};
@@ -28,6 +44,9 @@ describe('Pipelines CI Templates', () => {
const findTemplateLinks = () => wrapper.findAll('[data-testid="template-link"]');
const findTemplateNames = () => wrapper.findAll('[data-testid="template-name"]');
const findTemplateLogos = () => wrapper.findAll('[data-testid="template-logo"]');
+ const findSettingsLink = () => wrapper.findByTestId('settings-link');
+ const findDocumentationLink = () => wrapper.findByTestId('documentation-link');
+ const findSettingsButton = () => wrapper.findByTestId('settings-button');
afterEach(() => {
wrapper.destroy();
@@ -69,7 +88,7 @@ describe('Pipelines CI Templates', () => {
it('has the description of the template', () => {
expect(findTemplateDescriptions().at(0).text()).toBe(
- 'CI/CD template to test and deploy your Android project.',
+ sprintf(I18N.templates.description, { name: 'Android' }),
);
});
@@ -104,4 +123,84 @@ describe('Pipelines CI Templates', () => {
});
});
});
+
+ describe('when the runners_availability_section experiment is active', () => {
+ beforeEach(() => {
+ stubExperiments({ runners_availability_section: 'candidate' });
+ });
+
+ describe('when runners are available', () => {
+ beforeEach(() => {
+ wrapper = createWrapper({ anyRunnersAvailable: true }, { GitlabExperiment, GlSprintf });
+ });
+
+ it('show the runners available section', () => {
+ expect(wrapper.text()).toContain(I18N.runners.title);
+ });
+
+ it('tracks an event when clicking the settings link', () => {
+ findSettingsLink().vm.$emit('click');
+
+ expect(ExperimentTracking).toHaveBeenCalledWith(
+ RUNNERS_AVAILABILITY_SECTION_EXPERIMENT_NAME,
+ );
+ expect(ExperimentTracking.prototype.event).toHaveBeenCalledWith(
+ RUNNERS_SETTINGS_LINK_CLICKED_EVENT,
+ );
+ });
+
+ it('tracks an event when clicking the documentation link', () => {
+ findDocumentationLink().vm.$emit('click');
+
+ expect(ExperimentTracking).toHaveBeenCalledWith(
+ RUNNERS_AVAILABILITY_SECTION_EXPERIMENT_NAME,
+ );
+ expect(ExperimentTracking.prototype.event).toHaveBeenCalledWith(
+ RUNNERS_DOCUMENTATION_LINK_CLICKED_EVENT,
+ );
+ });
+ });
+
+ describe('when runners are not available', () => {
+ beforeEach(() => {
+ wrapper = createWrapper({ anyRunnersAvailable: false }, { GitlabExperiment, GlButton });
+ });
+
+ it('show the no runners available section', () => {
+ expect(wrapper.text()).toContain(I18N.noRunners.title);
+ });
+
+ it('tracks an event when clicking the settings button', () => {
+ findSettingsButton().trigger('click');
+
+ expect(ExperimentTracking).toHaveBeenCalledWith(
+ RUNNERS_AVAILABILITY_SECTION_EXPERIMENT_NAME,
+ );
+ expect(ExperimentTracking.prototype.event).toHaveBeenCalledWith(
+ RUNNERS_SETTINGS_BUTTON_CLICKED_EVENT,
+ );
+ });
+ });
+ });
+
+ describe.each`
+ experimentVariant | anyRunnersAvailable | templatesRendered
+ ${'control'} | ${true} | ${true}
+ ${'control'} | ${false} | ${true}
+ ${'candidate'} | ${true} | ${true}
+ ${'candidate'} | ${false} | ${false}
+ `(
+ 'when the runners_availability_section experiment variant is $experimentVariant and runners are available: $anyRunnersAvailable',
+ ({ experimentVariant, anyRunnersAvailable, templatesRendered }) => {
+ beforeEach(() => {
+ stubExperiments({ runners_availability_section: experimentVariant });
+ wrapper = createWrapper({ anyRunnersAvailable });
+ });
+
+ it(`renders the templates: ${templatesRendered}`, () => {
+ expect(findTestTemplateLinks().exists()).toBe(templatesRendered);
+ expect(findTemplateLinks().exists()).toBe(templatesRendered);
+ });
+ },
+ );
});
diff --git a/spec/frontend/pipelines/pipelines_spec.js b/spec/frontend/pipelines/pipelines_spec.js
index c024730570c..20ed12cd1f5 100644
--- a/spec/frontend/pipelines/pipelines_spec.js
+++ b/spec/frontend/pipelines/pipelines_spec.js
@@ -10,7 +10,6 @@ import { TEST_HOST } from 'helpers/test_constants';
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import waitForPromises from 'helpers/wait_for_promises';
import Api from '~/api';
-import { getExperimentData, getExperimentVariant } from '~/experimentation/utils';
import createFlash from '~/flash';
import axios from '~/lib/utils/axios_utils';
import NavigationControls from '~/pipelines/components/pipelines_list/nav_controls.vue';
@@ -25,14 +24,10 @@ import TablePagination from '~/vue_shared/components/pagination/table_pagination
import { stageReply, users, mockSearch, branches } from './mock_data';
jest.mock('~/flash');
-jest.mock('~/experimentation/utils', () => ({
- ...jest.requireActual('~/experimentation/utils'),
- getExperimentData: jest.fn().mockReturnValue(false),
- getExperimentVariant: jest.fn().mockReturnValue('control'),
-}));
const mockProjectPath = 'twitter/flight';
const mockProjectId = '21';
+const mockDefaultBranchName = 'main';
const mockPipelinesEndpoint = `/${mockProjectPath}/pipelines.json`;
const mockPipelinesIds = mockPipelinesResponse.pipelines.map(({ id }) => id);
const mockPipelineWithStages = mockPipelinesResponse.pipelines.find(
@@ -50,7 +45,6 @@ describe('Pipelines', () => {
ciLintPath: '/ci/lint',
resetCachePath: `${mockProjectPath}/settings/ci_cd/reset_cache`,
newPipelinePath: `${mockProjectPath}/pipelines/new`,
- codeQualityPagePath: `${mockProjectPath}/-/new/master?commit_message=Add+.gitlab-ci.yml+and+create+a+code+quality+job&file_name=.gitlab-ci.yml&template=Code-Quality`,
ciRunnerSettingsPath: `${mockProjectPath}/-/settings/ci_cd#js-runners-settings`,
};
@@ -92,6 +86,7 @@ describe('Pipelines', () => {
propsData: {
store: new Store(),
projectId: mockProjectId,
+ defaultBranchName: mockDefaultBranchName,
endpoint: mockPipelinesEndpoint,
params: {},
...props,
@@ -557,73 +552,6 @@ describe('Pipelines', () => {
expect(wrapper.findComponent(PipelinesCiTemplates).exists()).toBe(true);
});
- describe('when the code_quality_walkthrough experiment is active', () => {
- beforeAll(() => {
- getExperimentData.mockImplementation((name) => name === 'code_quality_walkthrough');
- });
-
- describe('the control state', () => {
- beforeAll(() => {
- getExperimentVariant.mockReturnValue('control');
- });
-
- it('renders the CI/CD templates', () => {
- expect(wrapper.findComponent(PipelinesCiTemplates).exists()).toBe(true);
- });
- });
-
- describe('the candidate state', () => {
- beforeAll(() => {
- getExperimentVariant.mockReturnValue('candidate');
- });
-
- it('renders another CTA button', () => {
- expect(findEmptyState().findComponent(GlButton).text()).toBe('Add a code quality job');
- expect(findEmptyState().findComponent(GlButton).attributes('href')).toBe(
- paths.codeQualityPagePath,
- );
- });
- });
- });
-
- describe('when the ci_runner_templates experiment is active', () => {
- beforeAll(() => {
- getExperimentData.mockImplementation((name) => name === 'ci_runner_templates');
- });
-
- describe('the control state', () => {
- beforeAll(() => {
- getExperimentVariant.mockReturnValue('control');
- });
-
- it('renders the CI/CD templates', () => {
- expect(wrapper.findComponent(PipelinesCiTemplates).exists()).toBe(true);
- });
- });
-
- describe('the candidate state', () => {
- beforeAll(() => {
- getExperimentVariant.mockReturnValue('candidate');
- });
-
- it('renders two buttons', () => {
- expect(findEmptyState().findAllComponents(GlButton).length).toBe(2);
- expect(findEmptyState().findAllComponents(GlButton).at(0).text()).toBe(
- 'Install GitLab Runners',
- );
- expect(findEmptyState().findAllComponents(GlButton).at(0).attributes('href')).toBe(
- paths.ciRunnerSettingsPath,
- );
- expect(findEmptyState().findAllComponents(GlButton).at(1).text()).toBe(
- 'Learn about Runners',
- );
- expect(findEmptyState().findAllComponents(GlButton).at(1).attributes('href')).toBe(
- '/help/ci/quick_start/index.md',
- );
- });
- });
- });
-
it('does not render filtered search', () => {
expect(findFilteredSearch().exists()).toBe(false);
});
diff --git a/spec/frontend/pipelines/pipelines_table_spec.js b/spec/frontend/pipelines/pipelines_table_spec.js
index f200d683a7a..7b49baa5a20 100644
--- a/spec/frontend/pipelines/pipelines_table_spec.js
+++ b/spec/frontend/pipelines/pipelines_table_spec.js
@@ -17,7 +17,6 @@ import {
import eventHub from '~/pipelines/event_hub';
import CiBadge from '~/vue_shared/components/ci_badge_link.vue';
-import CommitComponent from '~/vue_shared/components/commit.vue';
jest.mock('~/pipelines/event_hub');
@@ -37,18 +36,13 @@ describe('Pipelines Table', () => {
return pipelines.find((p) => p.user !== null && p.commit !== null);
};
- const createComponent = (props = {}, rearrangePipelinesTable = false) => {
+ const createComponent = (props = {}) => {
wrapper = extendedWrapper(
mount(PipelinesTable, {
propsData: {
...defaultProps,
...props,
},
- provide: {
- glFeatures: {
- rearrangePipelinesTable,
- },
- },
}),
);
};
@@ -57,7 +51,6 @@ describe('Pipelines Table', () => {
const findStatusBadge = () => wrapper.findComponent(CiBadge);
const findPipelineInfo = () => wrapper.findComponent(PipelineUrl);
const findTriggerer = () => wrapper.findComponent(PipelineTriggerer);
- const findCommit = () => wrapper.findComponent(CommitComponent);
const findPipelineMiniGraph = () => wrapper.findComponent(PipelineMiniGraph);
const findTimeAgo = () => wrapper.findComponent(PipelinesTimeago);
const findActions = () => wrapper.findComponent(PipelineOperations);
@@ -65,10 +58,7 @@ describe('Pipelines Table', () => {
const findTableRows = () => wrapper.findAllByTestId('pipeline-table-row');
const findStatusTh = () => wrapper.findByTestId('status-th');
const findPipelineTh = () => wrapper.findByTestId('pipeline-th');
- const findTriggererTh = () => wrapper.findByTestId('triggerer-th');
- const findCommitTh = () => wrapper.findByTestId('commit-th');
const findStagesTh = () => wrapper.findByTestId('stages-th');
- const findTimeAgoTh = () => wrapper.findByTestId('timeago-th');
const findActionsTh = () => wrapper.findByTestId('actions-th');
const findRetryBtn = () => wrapper.findByTestId('pipelines-retry-button');
const findCancelBtn = () => wrapper.findByTestId('pipelines-cancel-button');
@@ -82,7 +72,7 @@ describe('Pipelines Table', () => {
wrapper = null;
});
- describe('Pipelines Table with rearrangePipelinesTable feature flag turned off', () => {
+ describe('Pipelines Table', () => {
beforeEach(() => {
createComponent({ pipelines: [pipeline], viewType: 'root' });
});
@@ -93,11 +83,8 @@ describe('Pipelines Table', () => {
it('should render table head with correct columns', () => {
expect(findStatusTh().text()).toBe('Status');
- expect(findPipelineTh().text()).toBe('Pipeline ID');
- expect(findTriggererTh().text()).toBe('Triggerer');
- expect(findCommitTh().text()).toBe('Commit');
+ expect(findPipelineTh().text()).toBe('Pipeline');
expect(findStagesTh().text()).toBe('Stages');
- expect(findTimeAgoTh().text()).toBe('Duration');
expect(findActionsTh().text()).toBe('Actions');
});
@@ -125,27 +112,6 @@ describe('Pipelines Table', () => {
});
});
- describe('triggerer cell', () => {
- it('should render the pipeline triggerer', () => {
- expect(findTriggerer().exists()).toBe(true);
- });
- });
-
- describe('commit cell', () => {
- it('should render commit information', () => {
- expect(findCommit().exists()).toBe(true);
- });
-
- it('should display and link to commit', () => {
- expect(findCommit().text()).toContain(pipeline.commit.short_id);
- expect(findCommit().props('commitUrl')).toBe(pipeline.commit.commit_path);
- });
-
- it('should display the commit author', () => {
- expect(findCommit().props('author')).toEqual(pipeline.commit.author);
- });
- });
-
describe('stages cell', () => {
it('should render a pipeline mini graph', () => {
expect(findPipelineMiniGraph().exists()).toBe(true);
@@ -163,7 +129,7 @@ describe('Pipelines Table', () => {
pipeline = createMockPipeline();
pipeline.details.stages = null;
- createComponent({ pipelines: [pipeline] }, true);
+ createComponent({ pipelines: [pipeline] });
});
it('stages are not rendered', () => {
@@ -176,7 +142,7 @@ describe('Pipelines Table', () => {
});
it('when update graph dropdown is set, should update graph dropdown', () => {
- createComponent({ pipelines: [pipeline], updateGraphDropdown: true }, true);
+ createComponent({ pipelines: [pipeline], updateGraphDropdown: true });
expect(findPipelineMiniGraph().props('updateDropdown')).toBe(true);
});
@@ -207,30 +173,11 @@ describe('Pipelines Table', () => {
expect(findCancelBtn().attributes('title')).toBe(BUTTON_TOOLTIP_CANCEL);
});
});
- });
-
- describe('Pipelines Table with rearrangePipelinesTable feature flag turned on', () => {
- beforeEach(() => {
- createComponent({ pipelines: [pipeline], viewType: 'root' }, true);
- });
-
- it('should render table head with correct columns', () => {
- expect(findStatusTh().text()).toBe('Status');
- expect(findPipelineTh().text()).toBe('Pipeline');
- expect(findStagesTh().text()).toBe('Stages');
- expect(findActionsTh().text()).toBe('Actions');
- });
describe('triggerer cell', () => {
it('should render the pipeline triggerer', () => {
expect(findTriggerer().exists()).toBe(true);
});
});
-
- describe('commit cell', () => {
- it('should not render commit information', () => {
- expect(findCommit().exists()).toBe(false);
- });
- });
});
});
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 2e44f40eda4..42ae154fb5e 100644
--- a/spec/frontend/pipelines/tokens/pipeline_branch_name_token_spec.js
+++ b/spec/frontend/pipelines/tokens/pipeline_branch_name_token_spec.js
@@ -1,5 +1,7 @@
import { GlFilteredSearchToken, GlFilteredSearchSuggestion, GlLoadingIcon } from '@gitlab/ui';
+import { nextTick } from 'vue';
import { shallowMount } from '@vue/test-utils';
+import waitForPromises from 'helpers/wait_for_promises';
import Api from '~/api';
import PipelineBranchNameToken from '~/pipelines/components/pipelines_list/tokens/pipeline_branch_name_token.vue';
import { branches, mockBranchesAfterMap } from '../mock_data';
@@ -10,6 +12,8 @@ describe('Pipeline Branch Name Token', () => {
const findFilteredSearchToken = () => wrapper.find(GlFilteredSearchToken);
const findAllFilteredSearchSuggestions = () => wrapper.findAll(GlFilteredSearchSuggestion);
const findLoadingIcon = () => wrapper.find(GlLoadingIcon);
+ const getBranchSuggestions = () =>
+ findAllFilteredSearchSuggestions().wrappers.map((w) => w.text());
const stubs = {
GlFilteredSearchToken: {
@@ -24,6 +28,7 @@ describe('Pipeline Branch Name Token', () => {
title: 'Branch name',
unique: true,
projectId: '21',
+ defaultBranchName: null,
disabled: false,
},
value: {
@@ -31,6 +36,19 @@ describe('Pipeline Branch Name Token', () => {
},
};
+ const optionsWithDefaultBranchName = (options) => {
+ return {
+ propsData: {
+ ...defaultProps,
+ config: {
+ ...defaultProps.config,
+ defaultBranchName: 'main',
+ },
+ },
+ ...options,
+ };
+ };
+
const createComponent = (options, data) => {
wrapper = shallowMount(PipelineBranchNameToken, {
propsData: {
@@ -94,5 +112,34 @@ describe('Pipeline Branch Name Token', () => {
expect(findAllFilteredSearchSuggestions()).toHaveLength(mockBranches.length);
});
+
+ it('shows the default branch first if no branch was searched for', async () => {
+ const mockBranches = [{ name: 'branch-1' }];
+ jest.spyOn(Api, 'branches').mockResolvedValue({ data: mockBranches });
+
+ createComponent(optionsWithDefaultBranchName({ stubs }), { loading: false });
+ await nextTick();
+ expect(getBranchSuggestions()).toEqual(['main', 'branch-1']);
+ });
+
+ it('does not show the default branch if a search term was provided', async () => {
+ const mockBranches = [{ name: 'branch-1' }];
+ jest.spyOn(Api, 'branches').mockResolvedValue({ data: mockBranches });
+
+ createComponent(optionsWithDefaultBranchName(), { loading: false });
+
+ findFilteredSearchToken().vm.$emit('input', { data: 'branch-1' });
+ await waitForPromises();
+ expect(getBranchSuggestions()).toEqual(['branch-1']);
+ });
+
+ it('shows the default branch only once if it appears in the results', async () => {
+ const mockBranches = [{ name: 'main' }];
+ jest.spyOn(Api, 'branches').mockResolvedValue({ data: mockBranches });
+
+ createComponent(optionsWithDefaultBranchName({ stubs }), { loading: false });
+ await nextTick();
+ expect(getBranchSuggestions()).toEqual(['main']);
+ });
});
});
diff --git a/spec/frontend/protected_branches/protected_branch_create_spec.js b/spec/frontend/protected_branches/protected_branch_create_spec.js
new file mode 100644
index 00000000000..b3de2d5e031
--- /dev/null
+++ b/spec/frontend/protected_branches/protected_branch_create_spec.js
@@ -0,0 +1,114 @@
+import ProtectedBranchCreate from '~/protected_branches/protected_branch_create';
+
+const FORCE_PUSH_TOGGLE_TESTID = 'force-push-toggle';
+const CODE_OWNER_TOGGLE_TESTID = 'code-owner-toggle';
+const IS_CHECKED_CLASS = 'is-checked';
+const IS_DISABLED_CLASS = 'is-disabled';
+const IS_LOADING_CLASS = 'toggle-loading';
+
+describe('ProtectedBranchCreate', () => {
+ beforeEach(() => {
+ jest.spyOn(ProtectedBranchCreate.prototype, 'buildDropdowns').mockImplementation();
+ });
+
+ const findForcePushToggle = () =>
+ document.querySelector(`div[data-testid="${FORCE_PUSH_TOGGLE_TESTID}"] button`);
+ const findCodeOwnerToggle = () =>
+ document.querySelector(`div[data-testid="${CODE_OWNER_TOGGLE_TESTID}"] button`);
+
+ const create = ({
+ forcePushToggleChecked = false,
+ codeOwnerToggleChecked = false,
+ hasLicense = true,
+ } = {}) => {
+ setFixtures(`
+ <form class="js-new-protected-branch">
+ <span
+ class="js-force-push-toggle"
+ data-label="Toggle allowed to force push"
+ data-is-checked="${forcePushToggleChecked}"
+ data-testid="${FORCE_PUSH_TOGGLE_TESTID}"></span>
+ <span
+ class="js-code-owner-toggle"
+ data-label="Toggle code owner approval"
+ data-is-checked="${codeOwnerToggleChecked}"
+ data-testid="${CODE_OWNER_TOGGLE_TESTID}"></span>
+ <input type="submit" />
+ </form>
+ `);
+
+ return new ProtectedBranchCreate({ hasLicense });
+ };
+
+ describe('when license supports code owner approvals', () => {
+ it('instantiates the code owner toggle', () => {
+ create();
+
+ expect(findCodeOwnerToggle()).not.toBe(null);
+ });
+ });
+
+ describe('when license does not support code owner approvals', () => {
+ it('does not instantiate the code owner toggle', () => {
+ create({ hasLicense: false });
+
+ expect(findCodeOwnerToggle()).toBe(null);
+ });
+ });
+
+ describe.each`
+ description | checkedOption | finder
+ ${'force push'} | ${'forcePushToggleChecked'} | ${findForcePushToggle}
+ ${'code owner'} | ${'codeOwnerToggleChecked'} | ${findCodeOwnerToggle}
+ `('when unchecked $description toggle button', ({ checkedOption, finder }) => {
+ it('is not changed', () => {
+ create({ [checkedOption]: false });
+
+ const toggle = finder();
+
+ expect(toggle).not.toHaveClass(IS_CHECKED_CLASS);
+ expect(toggle.querySelector(`.${IS_LOADING_CLASS}`)).toBe(null);
+ expect(toggle).not.toHaveClass(IS_DISABLED_CLASS);
+ });
+ });
+
+ describe('form data', () => {
+ let protectedBranchCreate;
+
+ beforeEach(() => {
+ protectedBranchCreate = create({
+ forcePushToggleChecked: false,
+ codeOwnerToggleChecked: true,
+ });
+
+ // Mock access levels. This should probably be improved in future iterations.
+ protectedBranchCreate.merge_access_levels_dropdown = {
+ getSelectedItems: () => [],
+ };
+ protectedBranchCreate.push_access_levels_dropdown = {
+ getSelectedItems: () => [],
+ };
+ });
+
+ afterEach(() => {
+ protectedBranchCreate = null;
+ });
+
+ it('returns the default form data if toggles are untouched', () => {
+ expect(protectedBranchCreate.getFormData().protected_branch).toMatchObject({
+ allow_force_push: false,
+ code_owner_approval_required: true,
+ });
+ });
+
+ it('reflects toggles changes if any', () => {
+ findForcePushToggle().click();
+ findCodeOwnerToggle().click();
+
+ expect(protectedBranchCreate.getFormData().protected_branch).toMatchObject({
+ allow_force_push: true,
+ code_owner_approval_required: false,
+ });
+ });
+ });
+});
diff --git a/spec/frontend/protected_branches/protected_branch_edit_spec.js b/spec/frontend/protected_branches/protected_branch_edit_spec.js
index b41b5028736..959ca6ecde2 100644
--- a/spec/frontend/protected_branches/protected_branch_edit_spec.js
+++ b/spec/frontend/protected_branches/protected_branch_edit_spec.js
@@ -8,59 +8,116 @@ import ProtectedBranchEdit from '~/protected_branches/protected_branch_edit';
jest.mock('~/flash');
const TEST_URL = `${TEST_HOST}/url`;
+const FORCE_PUSH_TOGGLE_TESTID = 'force-push-toggle';
+const CODE_OWNER_TOGGLE_TESTID = 'code-owner-toggle';
const IS_CHECKED_CLASS = 'is-checked';
+const IS_DISABLED_CLASS = 'is-disabled';
+const IS_LOADING_SELECTOR = '.toggle-loading';
describe('ProtectedBranchEdit', () => {
let mock;
beforeEach(() => {
- setFixtures(`<div id="wrap" data-url="${TEST_URL}">
- <button class="js-force-push-toggle">Toggle</button>
- </div>`);
-
jest.spyOn(ProtectedBranchEdit.prototype, 'buildDropdowns').mockImplementation();
mock = new MockAdapter(axios);
});
- const findForcePushesToggle = () => document.querySelector('.js-force-push-toggle');
+ const findForcePushToggle = () =>
+ document.querySelector(`div[data-testid="${FORCE_PUSH_TOGGLE_TESTID}"] button`);
+ const findCodeOwnerToggle = () =>
+ document.querySelector(`div[data-testid="${CODE_OWNER_TOGGLE_TESTID}"] button`);
- const create = ({ isChecked = false }) => {
- if (isChecked) {
- findForcePushesToggle().classList.add(IS_CHECKED_CLASS);
- }
+ const create = ({
+ forcePushToggleChecked = false,
+ codeOwnerToggleChecked = false,
+ hasLicense = true,
+ } = {}) => {
+ setFixtures(`<div id="wrap" data-url="${TEST_URL}">
+ <span
+ class="js-force-push-toggle"
+ data-label="Toggle allowed to force push"
+ data-is-checked="${forcePushToggleChecked}"
+ data-testid="${FORCE_PUSH_TOGGLE_TESTID}"></span>
+ <span
+ class="js-code-owner-toggle"
+ data-label="Toggle code owner approval"
+ data-is-checked="${codeOwnerToggleChecked}"
+ data-testid="${CODE_OWNER_TOGGLE_TESTID}"></span>
+ </div>`);
- return new ProtectedBranchEdit({ $wrap: $('#wrap'), hasLicense: false });
+ return new ProtectedBranchEdit({ $wrap: $('#wrap'), hasLicense });
};
afterEach(() => {
mock.restore();
});
- describe('when unchecked toggle button', () => {
+ describe('when license supports code owner approvals', () => {
+ beforeEach(() => {
+ create();
+ });
+
+ it('instantiates the code owner toggle', () => {
+ expect(findCodeOwnerToggle()).not.toBe(null);
+ });
+ });
+
+ describe('when license does not support code owner approvals', () => {
+ beforeEach(() => {
+ create({ hasLicense: false });
+ });
+
+ it('does not instantiate the code owner toggle', () => {
+ expect(findCodeOwnerToggle()).toBe(null);
+ });
+ });
+
+ describe('when toggles are not available in the DOM on page load', () => {
+ beforeEach(() => {
+ create({ hasLicense: true });
+ setFixtures('');
+ });
+
+ it('does not instantiate the force push toggle', () => {
+ expect(findForcePushToggle()).toBe(null);
+ });
+
+ it('does not instantiate the code owner toggle', () => {
+ expect(findCodeOwnerToggle()).toBe(null);
+ });
+ });
+
+ describe.each`
+ description | checkedOption | patchParam | finder
+ ${'force push'} | ${'forcePushToggleChecked'} | ${'allow_force_push'} | ${findForcePushToggle}
+ ${'code owner'} | ${'codeOwnerToggleChecked'} | ${'code_owner_approval_required'} | ${findCodeOwnerToggle}
+ `('when unchecked $description toggle button', ({ checkedOption, patchParam, finder }) => {
let toggle;
beforeEach(() => {
- create({ isChecked: false });
+ create({ [checkedOption]: false });
- toggle = findForcePushesToggle();
+ toggle = finder();
});
it('is not changed', () => {
expect(toggle).not.toHaveClass(IS_CHECKED_CLASS);
- expect(toggle).not.toBeDisabled();
+ expect(toggle.querySelector(IS_LOADING_SELECTOR)).toBe(null);
+ expect(toggle).not.toHaveClass(IS_DISABLED_CLASS);
});
describe('when clicked', () => {
beforeEach(() => {
- mock.onPatch(TEST_URL, { protected_branch: { allow_force_push: true } }).replyOnce(200, {});
+ mock.onPatch(TEST_URL, { protected_branch: { [patchParam]: true } }).replyOnce(200, {});
toggle.click();
});
it('checks and disables button', () => {
expect(toggle).toHaveClass(IS_CHECKED_CLASS);
- expect(toggle).toBeDisabled();
+ expect(toggle.querySelector(IS_LOADING_SELECTOR)).not.toBe(null);
+ expect(toggle).toHaveClass(IS_DISABLED_CLASS);
});
it('sends update to BE', () =>
@@ -68,7 +125,8 @@ describe('ProtectedBranchEdit', () => {
// Args are asserted in the `.onPatch` call
expect(mock.history.patch).toHaveLength(1);
- expect(toggle).not.toBeDisabled();
+ expect(toggle).not.toHaveClass(IS_DISABLED_CLASS);
+ expect(toggle.querySelector(IS_LOADING_SELECTOR)).toBe(null);
expect(createFlash).not.toHaveBeenCalled();
}));
});
diff --git a/spec/frontend/ref/components/__snapshots__/ref_selector_spec.js.snap b/spec/frontend/ref/components/__snapshots__/ref_selector_spec.js.snap
index 5f05b7fc68b..5053778369e 100644
--- a/spec/frontend/ref/components/__snapshots__/ref_selector_spec.js.snap
+++ b/spec/frontend/ref/components/__snapshots__/ref_selector_spec.js.snap
@@ -10,30 +10,37 @@ Object {
Object {
"default": false,
"name": "add_images_and_changes",
+ "value": undefined,
},
Object {
"default": false,
"name": "conflict-contains-conflict-markers",
+ "value": undefined,
},
Object {
"default": false,
"name": "deleted-image-test",
+ "value": undefined,
},
Object {
"default": false,
"name": "diff-files-image-to-symlink",
+ "value": undefined,
},
Object {
"default": false,
"name": "diff-files-symlink-to-image",
+ "value": undefined,
},
Object {
"default": false,
"name": "markdown",
+ "value": undefined,
},
Object {
"default": true,
"name": "master",
+ "value": undefined,
},
],
"totalCount": 123,
@@ -54,12 +61,15 @@ Object {
"list": Array [
Object {
"name": "v1.1.1",
+ "value": undefined,
},
Object {
"name": "v1.1.0",
+ "value": undefined,
},
Object {
"name": "v1.0.0",
+ "value": undefined,
},
],
"totalCount": 456,
diff --git a/spec/frontend/ref/stores/mutations_spec.js b/spec/frontend/ref/stores/mutations_spec.js
index de1d5c557ce..37eee18dc10 100644
--- a/spec/frontend/ref/stores/mutations_spec.js
+++ b/spec/frontend/ref/stores/mutations_spec.js
@@ -48,6 +48,14 @@ describe('Ref selector Vuex store mutations', () => {
});
});
+ describe(`${types.SET_USE_SYMBOLIC_REF_NAMES}`, () => {
+ it('sets useSymbolicRefNames on the state', () => {
+ mutations[types.SET_USE_SYMBOLIC_REF_NAMES](state, true);
+
+ expect(state.useSymbolicRefNames).toBe(true);
+ });
+ });
+
describe(`${types.SET_PROJECT_ID}`, () => {
it('updates the project ID', () => {
const newProjectId = '4';
diff --git a/spec/frontend/releases/components/asset_links_form_spec.js b/spec/frontend/releases/components/asset_links_form_spec.js
index c0f7738bec5..17f079ba5a6 100644
--- a/spec/frontend/releases/components/asset_links_form_spec.js
+++ b/spec/frontend/releases/components/asset_links_form_spec.js
@@ -256,9 +256,7 @@ describe('Release edit component', () => {
},
});
- expect(findUrlValidationMessage().text()).toBe(
- 'This URL is already used for another link; duplicate URLs are not allowed',
- );
+ expect(findUrlValidationMessage().text()).toBe('This URL already exists.');
});
it('shows a validation error message when a URL has a bad format', () => {
diff --git a/spec/frontend/releases/stores/modules/detail/getters_spec.js b/spec/frontend/releases/stores/modules/detail/getters_spec.js
index 66f24ac9559..c32969c131e 100644
--- a/spec/frontend/releases/stores/modules/detail/getters_spec.js
+++ b/spec/frontend/releases/stores/modules/detail/getters_spec.js
@@ -134,6 +134,14 @@ describe('Release edit/new getters', () => {
// Missing title
{ id: 7, url: 'https://example.com/valid/1', name: '' },
{ id: 8, url: 'https://example.com/valid/2', name: ' ' },
+
+ // Duplicate title
+ { id: 9, url: 'https://example.com/1', name: 'Link 7' },
+ { id: 10, url: 'https://example.com/2', name: 'Link 7' },
+
+ // title validation ignores leading/trailing whitespace
+ { id: 11, url: 'https://example.com/3', name: ' Link 7\t ' },
+ { id: 12, url: 'https://example.com/4', name: ' Link 7\n\r\n ' },
],
},
},
@@ -201,6 +209,21 @@ describe('Release edit/new getters', () => {
expect(actualErrors).toMatchObject(expectedErrors);
});
+
+ it('returns a validation error if links share a title', () => {
+ const expectedErrors = {
+ assets: {
+ links: {
+ 9: { isTitleDuplicate: true },
+ 10: { isTitleDuplicate: true },
+ 11: { isTitleDuplicate: true },
+ 12: { isTitleDuplicate: true },
+ },
+ },
+ };
+
+ expect(actualErrors).toMatchObject(expectedErrors);
+ });
});
});
diff --git a/spec/frontend/repository/components/blob_content_viewer_spec.js b/spec/frontend/repository/components/blob_content_viewer_spec.js
index 109e5cef49b..96c03419dd6 100644
--- a/spec/frontend/repository/components/blob_content_viewer_spec.js
+++ b/spec/frontend/repository/components/blob_content_viewer_spec.js
@@ -1,5 +1,6 @@
import { GlLoadingIcon } from '@gitlab/ui';
import { mount, shallowMount } from '@vue/test-utils';
+import Vuex from 'vuex';
import Vue, { nextTick } from 'vue';
import axios from 'axios';
import MockAdapter from 'axios-mock-adapter';
@@ -10,20 +11,26 @@ import BlobContent from '~/blob/components/blob_content.vue';
import BlobHeader from '~/blob/components/blob_header.vue';
import BlobButtonGroup from '~/repository/components/blob_button_group.vue';
import BlobContentViewer from '~/repository/components/blob_content_viewer.vue';
-import BlobEdit from '~/repository/components/blob_edit.vue';
+import WebIdeLink from '~/vue_shared/components/web_ide_link.vue';
import ForkSuggestion from '~/repository/components/fork_suggestion.vue';
import { loadViewer } from '~/repository/components/blob_viewers';
import DownloadViewer from '~/repository/components/blob_viewers/download_viewer.vue';
import EmptyViewer from '~/repository/components/blob_viewers/empty_viewer.vue';
import SourceViewer from '~/vue_shared/components/source_viewer/source_viewer.vue';
import blobInfoQuery from '~/repository/queries/blob_info.query.graphql';
+import userInfoQuery from '~/repository/queries/user_info.query.graphql';
+import applicationInfoQuery from '~/repository/queries/application_info.query.graphql';
+import CodeIntelligence from '~/code_navigation/components/app.vue';
import { redirectTo } from '~/lib/utils/url_utility';
import { isLoggedIn } from '~/lib/utils/common_utils';
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
+import httpStatusCodes from '~/lib/utils/http_status';
import {
simpleViewerMock,
richViewerMock,
projectMock,
+ userInfoMock,
+ applicationInfoMock,
userPermissionsMock,
propsMock,
refMock,
@@ -35,9 +42,14 @@ jest.mock('~/lib/utils/common_utils');
let wrapper;
let mockResolver;
+let userInfoMockResolver;
+let applicationInfoMockResolver;
const mockAxios = new MockAdapter(axios);
+const createMockStore = () =>
+ new Vuex.Store({ actions: { fetchData: jest.fn, setInitialData: jest.fn() } });
+
const createComponent = async (mockData = {}, mountFn = shallowMount) => {
Vue.use(VueApollo);
@@ -71,10 +83,23 @@ const createComponent = async (mockData = {}, mountFn = shallowMount) => {
data: { isBinary, project },
});
- const fakeApollo = createMockApollo([[blobInfoQuery, mockResolver]]);
+ userInfoMockResolver = jest.fn().mockResolvedValue({
+ data: { ...userInfoMock },
+ });
+
+ applicationInfoMockResolver = jest.fn().mockResolvedValue({
+ data: { ...applicationInfoMock },
+ });
+
+ const fakeApollo = createMockApollo([
+ [blobInfoQuery, mockResolver],
+ [userInfoQuery, userInfoMockResolver],
+ [applicationInfoQuery, applicationInfoMockResolver],
+ ]);
wrapper = extendedWrapper(
mountFn(BlobContentViewer, {
+ store: createMockStore(),
apolloProvider: fakeApollo,
propsData: propsMock,
mixins: [{ data: () => ({ ref: refMock }) }],
@@ -96,16 +121,21 @@ const createComponent = async (mockData = {}, mountFn = shallowMount) => {
await waitForPromises();
};
+const execImmediately = (callback) => {
+ callback();
+};
+
describe('Blob content viewer component', () => {
const findLoadingIcon = () => wrapper.findComponent(GlLoadingIcon);
const findBlobHeader = () => wrapper.findComponent(BlobHeader);
- const findBlobEdit = () => wrapper.findComponent(BlobEdit);
- const findPipelineEditor = () => wrapper.findByTestId('pipeline-editor');
+ const findWebIdeLink = () => wrapper.findComponent(WebIdeLink);
const findBlobContent = () => wrapper.findComponent(BlobContent);
const findBlobButtonGroup = () => wrapper.findComponent(BlobButtonGroup);
const findForkSuggestion = () => wrapper.findComponent(ForkSuggestion);
+ const findCodeIntelligence = () => wrapper.findComponent(CodeIntelligence);
beforeEach(() => {
+ jest.spyOn(window, 'requestIdleCallback').mockImplementation(execImmediately);
isLoggedIn.mockReturnValue(true);
});
@@ -219,6 +249,26 @@ describe('Blob content viewer component', () => {
loadViewer.mockRestore();
});
+ it('renders a CodeIntelligence component with the correct props', async () => {
+ loadViewer.mockReturnValue(SourceViewer);
+
+ await createComponent();
+
+ expect(findCodeIntelligence().props()).toMatchObject({
+ codeNavigationPath: simpleViewerMock.codeNavigationPath,
+ blobPath: simpleViewerMock.path,
+ pathPrefix: simpleViewerMock.projectBlobPathRoot,
+ });
+ });
+
+ it('does not load a CodeIntelligence component when no viewers are loaded', async () => {
+ const url = 'some_file.js?format=json&viewer=rich';
+ mockAxios.onGet(url).replyOnce(httpStatusCodes.INTERNAL_SERVER_ERROR);
+ await createComponent({ blob: { ...richViewerMock, fileType: 'unknown' } });
+
+ expect(findCodeIntelligence().exists()).toBe(false);
+ });
+
it('does not render a BlobContent component if a Blob viewer is available', async () => {
loadViewer.mockReturnValue(() => true);
await createComponent({ blob: richViewerMock });
@@ -255,45 +305,43 @@ describe('Blob content viewer component', () => {
describe('BlobHeader action slot', () => {
const { ideEditPath, editBlobPath } = simpleViewerMock;
- it('renders BlobHeaderEdit buttons in simple viewer', async () => {
+ it('renders WebIdeLink button in simple viewer', async () => {
await createComponent({ inject: { BlobContent: true, BlobReplace: true } }, mount);
- expect(findBlobEdit().props()).toMatchObject({
- editPath: editBlobPath,
- webIdePath: ideEditPath,
+ expect(findWebIdeLink().props()).toMatchObject({
+ editUrl: editBlobPath,
+ webIdeUrl: ideEditPath,
showEditButton: true,
+ showGitpodButton: applicationInfoMock.gitpodEnabled,
+ gitpodEnabled: userInfoMock.currentUser.gitpodEnabled,
+ showPipelineEditorButton: true,
+ gitpodUrl: simpleViewerMock.gitpodBlobUrl,
+ pipelineEditorUrl: simpleViewerMock.pipelineEditorPath,
+ userPreferencesGitpodPath: userInfoMock.currentUser.preferencesGitpodPath,
+ userProfileEnableGitpodPath: userInfoMock.currentUser.profileEnableGitpodPath,
});
});
- it('renders BlobHeaderEdit button in rich viewer', async () => {
+ it('renders WebIdeLink button in rich viewer', async () => {
await createComponent({ blob: richViewerMock }, mount);
- expect(findBlobEdit().props()).toMatchObject({
- editPath: editBlobPath,
- webIdePath: ideEditPath,
+ expect(findWebIdeLink().props()).toMatchObject({
+ editUrl: editBlobPath,
+ webIdeUrl: ideEditPath,
showEditButton: true,
});
});
- it('renders BlobHeaderEdit button for binary files', async () => {
+ it('renders WebIdeLink button for binary files', async () => {
await createComponent({ blob: richViewerMock, isBinary: true }, mount);
- expect(findBlobEdit().props()).toMatchObject({
- editPath: editBlobPath,
- webIdePath: ideEditPath,
+ expect(findWebIdeLink().props()).toMatchObject({
+ editUrl: editBlobPath,
+ webIdeUrl: ideEditPath,
showEditButton: false,
});
});
- it('renders Pipeline Editor button for .gitlab-ci files', async () => {
- const pipelineEditorPath = 'some/path/.gitlab-ce';
- const blob = { ...simpleViewerMock, pipelineEditorPath };
- await createComponent({ blob, inject: { BlobContent: true, BlobReplace: true } }, mount);
-
- expect(findPipelineEditor().exists()).toBe(true);
- expect(findPipelineEditor().attributes('href')).toBe(pipelineEditorPath);
- });
-
describe('blob header binary file', () => {
it('passes the correct isBinary value when viewing a binary file', async () => {
await createComponent({ blob: richViewerMock, isBinary: true });
@@ -318,7 +366,7 @@ describe('Blob content viewer component', () => {
expect(findBlobHeader().props('hideViewerSwitcher')).toBe(true);
expect(findBlobHeader().props('isBinary')).toBe(true);
- expect(findBlobEdit().props('showEditButton')).toBe(false);
+ expect(findWebIdeLink().props('showEditButton')).toBe(false);
});
});
@@ -401,12 +449,12 @@ describe('Blob content viewer component', () => {
beforeEach(() => createComponent({}, mount));
it('simple edit redirects to the simple editor', () => {
- findBlobEdit().vm.$emit('edit', 'simple');
+ findWebIdeLink().vm.$emit('edit', 'simple');
expect(redirectTo).toHaveBeenCalledWith(simpleViewerMock.editBlobPath);
});
it('IDE edit redirects to the IDE editor', () => {
- findBlobEdit().vm.$emit('edit', 'ide');
+ findWebIdeLink().vm.$emit('edit', 'ide');
expect(redirectTo).toHaveBeenCalledWith(simpleViewerMock.ideEditPath);
});
@@ -435,7 +483,7 @@ describe('Blob content viewer component', () => {
mount,
);
- findBlobEdit().vm.$emit('edit', 'simple');
+ findWebIdeLink().vm.$emit('edit', 'simple');
await nextTick();
expect(findForkSuggestion().exists()).toBe(showForkSuggestion);
diff --git a/spec/frontend/repository/components/blob_edit_spec.js b/spec/frontend/repository/components/blob_edit_spec.js
deleted file mode 100644
index e2de7bc2957..00000000000
--- a/spec/frontend/repository/components/blob_edit_spec.js
+++ /dev/null
@@ -1,100 +0,0 @@
-import { GlButton } from '@gitlab/ui';
-import { shallowMount } from '@vue/test-utils';
-import BlobEdit from '~/repository/components/blob_edit.vue';
-import WebIdeLink from '~/vue_shared/components/web_ide_link.vue';
-
-const DEFAULT_PROPS = {
- editPath: 'some_file.js/edit',
- webIdePath: 'some_file.js/ide/edit',
- showEditButton: true,
- needsToFork: false,
-};
-
-describe('BlobEdit component', () => {
- let wrapper;
-
- const createComponent = (consolidatedEditButton = false, props = {}) => {
- wrapper = shallowMount(BlobEdit, {
- propsData: {
- ...DEFAULT_PROPS,
- ...props,
- },
- provide: {
- glFeatures: {
- consolidatedEditButton,
- },
- },
- });
- };
-
- afterEach(() => {
- wrapper.destroy();
- wrapper = null;
- });
-
- const findButtons = () => wrapper.findAll(GlButton);
- const findEditButton = () => wrapper.find('[data-testid="edit"]');
- const findWebIdeButton = () => wrapper.find('[data-testid="web-ide"]');
- const findWebIdeLink = () => wrapper.find(WebIdeLink);
-
- it('renders component', () => {
- createComponent();
-
- const { editPath, webIdePath } = DEFAULT_PROPS;
-
- expect(wrapper.props()).toMatchObject({
- editPath,
- webIdePath,
- });
- });
-
- it('renders both buttons', () => {
- createComponent();
-
- expect(findButtons()).toHaveLength(2);
- });
-
- it('renders the Edit button', () => {
- createComponent();
-
- expect(findEditButton().text()).toBe('Edit');
- expect(findEditButton()).not.toBeDisabled();
- });
-
- it('renders the Web IDE button', () => {
- createComponent();
-
- expect(findWebIdeButton().text()).toBe('Web IDE');
- expect(findWebIdeButton()).not.toBeDisabled();
- });
-
- it('renders WebIdeLink component', () => {
- createComponent(true);
-
- const { editPath: editUrl, webIdePath: webIdeUrl, needsToFork } = DEFAULT_PROPS;
-
- expect(findWebIdeLink().props()).toMatchObject({
- editUrl,
- webIdeUrl,
- isBlob: true,
- showEditButton: true,
- needsToFork,
- });
- });
-
- describe('Without Edit button', () => {
- const showEditButton = false;
-
- it('renders WebIdeLink component without an edit button', () => {
- createComponent(true, { showEditButton });
-
- expect(findWebIdeLink().props()).toMatchObject({ showEditButton });
- });
-
- it('does not render an Edit button', () => {
- createComponent(false, { showEditButton });
-
- expect(findEditButton().exists()).toBe(false);
- });
- });
-});
diff --git a/spec/frontend/repository/components/blob_viewers/audio_viewer_spec.js b/spec/frontend/repository/components/blob_viewers/audio_viewer_spec.js
new file mode 100644
index 00000000000..baf16b57d7d
--- /dev/null
+++ b/spec/frontend/repository/components/blob_viewers/audio_viewer_spec.js
@@ -0,0 +1,23 @@
+import { shallowMount } from '@vue/test-utils';
+import AudioViewer from '~/repository/components/blob_viewers/audio_viewer.vue';
+
+describe('Audio Viewer', () => {
+ let wrapper;
+
+ const DEFAULT_BLOB_DATA = {
+ rawPath: 'some/audio.mid',
+ };
+
+ const createComponent = () => {
+ wrapper = shallowMount(AudioViewer, { propsData: { blob: DEFAULT_BLOB_DATA } });
+ };
+
+ const findContent = () => wrapper.find('[data-testid="audio"]');
+
+ it('renders an audio source component', () => {
+ createComponent();
+
+ expect(findContent().exists()).toBe(true);
+ expect(findContent().attributes('src')).toBe(DEFAULT_BLOB_DATA.rawPath);
+ });
+});
diff --git a/spec/frontend/repository/components/blob_viewers/csv_viewer_spec.js b/spec/frontend/repository/components/blob_viewers/csv_viewer_spec.js
new file mode 100644
index 00000000000..7d43e4e660b
--- /dev/null
+++ b/spec/frontend/repository/components/blob_viewers/csv_viewer_spec.js
@@ -0,0 +1,27 @@
+import { shallowMount } from '@vue/test-utils';
+import CsvViewer from '~/repository/components/blob_viewers/csv_viewer.vue';
+
+describe('CSV Viewer', () => {
+ let wrapper;
+
+ const DEFAULT_BLOB_DATA = {
+ rawPath: 'some/file.csv',
+ name: 'file.csv',
+ };
+
+ const createComponent = () => {
+ wrapper = shallowMount(CsvViewer, {
+ propsData: { blob: DEFAULT_BLOB_DATA },
+ stubs: ['CsvViewer'],
+ });
+ };
+
+ const findCsvViewerComp = () => wrapper.find('[data-testid="csv"]');
+
+ it('renders a Source Editor component', () => {
+ createComponent();
+ expect(findCsvViewerComp().exists()).toBe(true);
+ expect(findCsvViewerComp().props('remoteFile')).toBeTruthy();
+ expect(findCsvViewerComp().props('csv')).toBe(DEFAULT_BLOB_DATA.rawPath);
+ });
+});
diff --git a/spec/frontend/repository/components/blob_viewers/download_viewer_spec.js b/spec/frontend/repository/components/blob_viewers/download_viewer_spec.js
index 5fe25ced302..0a91e5ce890 100644
--- a/spec/frontend/repository/components/blob_viewers/download_viewer_spec.js
+++ b/spec/frontend/repository/components/blob_viewers/download_viewer_spec.js
@@ -23,6 +23,8 @@ describe('Text Viewer', () => {
});
};
+ const findLink = () => wrapper.findComponent(GlLink);
+
it('renders download human readable file size text', () => {
createComponent();
@@ -42,7 +44,7 @@ describe('Text Viewer', () => {
createComponent();
const { rawPath, name } = DEFAULT_BLOB_DATA;
- expect(wrapper.findComponent(GlLink).attributes()).toMatchObject({
+ expect(findLink().attributes()).toMatchObject({
rel: 'nofollow',
target: '_blank',
href: rawPath,
@@ -50,6 +52,13 @@ describe('Text Viewer', () => {
});
});
+ it('renders the correct link href when stored externally', () => {
+ const externalStorageUrl = 'https://cdn.test.com/project/some/file.js?token=1234';
+ createComponent({ externalStorageUrl });
+
+ expect(findLink().attributes('href')).toBe(externalStorageUrl);
+ });
+
it('renders download icon', () => {
createComponent();
diff --git a/spec/frontend/repository/components/blob_viewers/lfs_viewer_spec.js b/spec/frontend/repository/components/blob_viewers/lfs_viewer_spec.js
index 5caeb85834d..599443bf862 100644
--- a/spec/frontend/repository/components/blob_viewers/lfs_viewer_spec.js
+++ b/spec/frontend/repository/components/blob_viewers/lfs_viewer_spec.js
@@ -10,9 +10,9 @@ describe('LFS Viewer', () => {
rawPath: '/some/file/path',
};
- const createComponent = () => {
+ const createComponent = (blobData = {}) => {
wrapper = shallowMount(LfsViewer, {
- propsData: { blob: { ...DEFAULT_BLOB_DATA } },
+ propsData: { blob: { ...DEFAULT_BLOB_DATA, ...blobData } },
stubs: { GlSprintf },
});
};
@@ -38,4 +38,11 @@ describe('LFS Viewer', () => {
download: name,
});
});
+
+ it('renders the correct link href when stored externally', () => {
+ const externalStorageUrl = 'https://cdn.test.com/project/some/file.js?token=1234';
+ createComponent({ externalStorageUrl });
+
+ expect(findLink().attributes('href')).toBe(externalStorageUrl);
+ });
});
diff --git a/spec/frontend/repository/components/blob_viewers/pdf_viewer_spec.js b/spec/frontend/repository/components/blob_viewers/pdf_viewer_spec.js
index 10eea691335..b61500ea0ad 100644
--- a/spec/frontend/repository/components/blob_viewers/pdf_viewer_spec.js
+++ b/spec/frontend/repository/components/blob_viewers/pdf_viewer_spec.js
@@ -1,4 +1,5 @@
import { GlButton } from '@gitlab/ui';
+import { nextTick } from 'vue';
import Component from '~/repository/components/blob_viewers/pdf_viewer.vue';
import PdfViewer from '~/blob/pdf/pdf_viewer.vue';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
@@ -8,9 +9,9 @@ describe('PDF Viewer', () => {
const DEFAULT_BLOB_DATA = { rawPath: 'some/pdf_blob.pdf' };
- const createComponent = (rawSize = 999) => {
+ const createComponent = (rawSize = 999, externalStorageUrl) => {
wrapper = shallowMountExtended(Component, {
- propsData: { blob: { ...DEFAULT_BLOB_DATA, rawSize } },
+ propsData: { blob: { ...DEFAULT_BLOB_DATA, rawSize, externalStorageUrl } },
});
};
@@ -45,10 +46,14 @@ describe('PDF Viewer', () => {
});
describe('Too many pages', () => {
- beforeEach(() => {
- createComponent();
- findPDFViewer().vm.$emit('pdflabload', 100);
- });
+ const loadComponent = (externalStorageUrl) => {
+ const rawSize = 999;
+ const totalPages = 100;
+ createComponent(rawSize, externalStorageUrl);
+ findPDFViewer().vm.$emit('pdflabload', totalPages);
+ };
+
+ beforeEach(() => loadComponent());
it('does not a PDF Viewer component', () => {
expect(findPDFViewer().exists()).toBe(false);
@@ -56,6 +61,15 @@ describe('PDF Viewer', () => {
it('renders a download button', () => {
expect(findDownLoadButton().exists()).toBe(true);
+ expect(findDownLoadButton().attributes('href')).toBe(DEFAULT_BLOB_DATA.rawPath);
+ });
+
+ it('renders the correct href when stored externally', async () => {
+ const externalStorageUrl = 'https://cdn.test.com/project/some/file.js?token=1234';
+ loadComponent(externalStorageUrl);
+ await nextTick();
+
+ expect(findDownLoadButton().attributes('href')).toBe(externalStorageUrl);
});
});
});
diff --git a/spec/frontend/repository/components/breadcrumbs_spec.js b/spec/frontend/repository/components/breadcrumbs_spec.js
index 0e300291d05..0e3e7075e99 100644
--- a/spec/frontend/repository/components/breadcrumbs_spec.js
+++ b/spec/frontend/repository/components/breadcrumbs_spec.js
@@ -59,6 +59,20 @@ describe('Repository breadcrumbs component', () => {
expect(wrapper.findAll(RouterLinkStub).length).toEqual(linkCount);
});
+ it.each`
+ routeName | path | linkTo
+ ${'treePath'} | ${'app/assets/javascripts'} | ${'/-/tree/app/assets/javascripts'}
+ ${'treePathDecoded'} | ${'app/assets/javascripts'} | ${'/-/tree/app/assets/javascripts'}
+ ${'blobPath'} | ${'app/assets/index.js'} | ${'/-/blob/app/assets/index.js'}
+ ${'blobPathDecoded'} | ${'app/assets/index.js'} | ${'/-/blob/app/assets/index.js'}
+ `(
+ 'links to the correct router path when routeName is $routeName',
+ ({ routeName, path, linkTo }) => {
+ factory(path, {}, { name: routeName });
+ expect(wrapper.findAll(RouterLinkStub).at(3).props('to')).toEqual(linkTo);
+ },
+ );
+
it('escapes hash in directory path', () => {
factory('app/assets/javascripts#');
diff --git a/spec/frontend/repository/mock_data.js b/spec/frontend/repository/mock_data.js
index 5a6551cb94a..0a5766a25f9 100644
--- a/spec/frontend/repository/mock_data.js
+++ b/spec/frontend/repository/mock_data.js
@@ -9,9 +9,13 @@ export const simpleViewerMock = {
path: 'some_file.js',
webPath: 'some_file.js',
editBlobPath: 'some_file.js/edit',
+ gitpodBlobUrl: 'https://gitpod.io#path/to/blob.js',
ideEditPath: 'some_file.js/ide/edit',
forkAndEditPath: 'some_file.js/fork/edit',
ideForkAndEditPath: 'some_file.js/fork/ide',
+ forkAndViewPath: 'some_file.js/fork/view',
+ codeNavigationPath: '',
+ projectBlobPathRoot: '',
environmentFormattedExternalUrl: '',
environmentExternalUrlForRouteMap: '',
canModifyBlob: true,
@@ -22,7 +26,7 @@ export const simpleViewerMock = {
externalStorage: 'lfs',
rawPath: 'some_file.js',
replacePath: 'some_file.js/replace',
- pipelineEditorPath: '',
+ pipelineEditorPath: 'path/to/pipeline/editor',
simpleViewer: {
fileType: 'text',
tooLarge: false,
@@ -67,6 +71,17 @@ export const projectMock = {
},
};
+export const userInfoMock = {
+ currentUser: {
+ id: '123',
+ gitpodEnabled: true,
+ preferencesGitpodPath: '/-/profile/preferences#user_gitpod_enabled',
+ profileEnableGitpodPath: '/-/profile?user%5Bgitpod_enabled%5D=true',
+ },
+};
+
+export const applicationInfoMock = { gitpodEnabled: true };
+
export const propsMock = { path: 'some_file.js', projectPath: 'some/path' };
export const refMock = 'default-ref';
diff --git a/spec/frontend/runner/admin_runner_edit/admin_runner_edit_app_spec.js b/spec/frontend/runner/admin_runner_edit/admin_runner_edit_app_spec.js
index ff6a632a4f8..d121c6be218 100644
--- a/spec/frontend/runner/admin_runner_edit/admin_runner_edit_app_spec.js
+++ b/spec/frontend/runner/admin_runner_edit/admin_runner_edit_app_spec.js
@@ -7,7 +7,7 @@ import { createAlert } from '~/flash';
import { getIdFromGraphQLId } from '~/graphql_shared/utils';
import RunnerHeader from '~/runner/components/runner_header.vue';
-import getRunnerQuery from '~/runner/graphql/get_runner.query.graphql';
+import runnerQuery from '~/runner/graphql/details/runner.query.graphql';
import AdminRunnerEditApp from '~//runner/admin_runner_edit/admin_runner_edit_app.vue';
import { captureException } from '~/runner/sentry_utils';
@@ -29,7 +29,7 @@ describe('AdminRunnerEditApp', () => {
const createComponentWithApollo = ({ props = {}, mountFn = shallowMount } = {}) => {
wrapper = mountFn(AdminRunnerEditApp, {
- apolloProvider: createMockApollo([[getRunnerQuery, mockRunnerQuery]]),
+ apolloProvider: createMockApollo([[runnerQuery, mockRunnerQuery]]),
propsData: {
runnerId: mockRunnerId,
...props,
diff --git a/spec/frontend/runner/admin_runner_show/admin_runner_show_app_spec.js b/spec/frontend/runner/admin_runner_show/admin_runner_show_app_spec.js
index 4b651961112..f994ff24c21 100644
--- a/spec/frontend/runner/admin_runner_show/admin_runner_show_app_spec.js
+++ b/spec/frontend/runner/admin_runner_show/admin_runner_show_app_spec.js
@@ -9,7 +9,7 @@ import { getIdFromGraphQLId } from '~/graphql_shared/utils';
import RunnerHeader from '~/runner/components/runner_header.vue';
import RunnerPauseButton from '~/runner/components/runner_pause_button.vue';
import RunnerEditButton from '~/runner/components/runner_edit_button.vue';
-import getRunnerQuery from '~/runner/graphql/get_runner.query.graphql';
+import runnerQuery from '~/runner/graphql/details/runner.query.graphql';
import AdminRunnerShowApp from '~/runner/admin_runner_show/admin_runner_show_app.vue';
import { captureException } from '~/runner/sentry_utils';
@@ -42,7 +42,7 @@ describe('AdminRunnerShowApp', () => {
const createComponent = ({ props = {}, mountFn = shallowMount } = {}) => {
wrapper = mountFn(AdminRunnerShowApp, {
- apolloProvider: createMockApollo([[getRunnerQuery, mockRunnerQuery]]),
+ apolloProvider: createMockApollo([[runnerQuery, mockRunnerQuery]]),
propsData: {
runnerId: mockRunnerId,
...props,
diff --git a/spec/frontend/runner/admin_runners/admin_runners_app_spec.js b/spec/frontend/runner/admin_runners/admin_runners_app_spec.js
index 995f0cf7ba1..cdaec0a3a8b 100644
--- a/spec/frontend/runner/admin_runners/admin_runners_app_spec.js
+++ b/spec/frontend/runner/admin_runners/admin_runners_app_spec.js
@@ -1,5 +1,5 @@
import Vue from 'vue';
-import { GlLink } from '@gitlab/ui';
+import { GlToast, GlLink } from '@gitlab/ui';
import VueApollo from 'vue-apollo';
import createMockApollo from 'helpers/mock_apollo_helper';
import setWindowLocation from 'helpers/set_window_location_helper';
@@ -18,6 +18,7 @@ import RunnerTypeTabs from '~/runner/components/runner_type_tabs.vue';
import RunnerFilteredSearchBar from '~/runner/components/runner_filtered_search_bar.vue';
import RunnerList from '~/runner/components/runner_list.vue';
import RunnerStats from '~/runner/components/stat/runner_stats.vue';
+import RunnerActionsCell from '~/runner/components/cells/runner_actions_cell.vue';
import RegistrationDropdown from '~/runner/components/registration/registration_dropdown.vue';
import RunnerPagination from '~/runner/components/runner_pagination.vue';
@@ -34,8 +35,8 @@ import {
STATUS_ACTIVE,
RUNNER_PAGE_SIZE,
} from '~/runner/constants';
-import getRunnersQuery from '~/runner/graphql/get_runners.query.graphql';
-import getRunnersCountQuery from '~/runner/graphql/get_runners_count.query.graphql';
+import adminRunnersQuery from '~/runner/graphql/list/admin_runners.query.graphql';
+import adminRunnersCountQuery from '~/runner/graphql/list/admin_runners_count.query.graphql';
import { captureException } from '~/runner/sentry_utils';
import FilteredSearch from '~/vue_shared/components/filtered_search_bar/filtered_search_bar_root.vue';
@@ -51,6 +52,7 @@ jest.mock('~/lib/utils/url_utility', () => ({
}));
Vue.use(VueApollo);
+Vue.use(GlToast);
describe('AdminRunnersApp', () => {
let wrapper;
@@ -58,20 +60,19 @@ describe('AdminRunnersApp', () => {
let mockRunnersCountQuery;
const findRunnerStats = () => wrapper.findComponent(RunnerStats);
+ const findRunnerActionsCell = () => wrapper.findComponent(RunnerActionsCell);
const findRegistrationDropdown = () => wrapper.findComponent(RegistrationDropdown);
const findRunnerTypeTabs = () => wrapper.findComponent(RunnerTypeTabs);
const findRunnerList = () => wrapper.findComponent(RunnerList);
const findRunnerPagination = () => extendedWrapper(wrapper.findComponent(RunnerPagination));
- const findRunnerPaginationPrev = () =>
- findRunnerPagination().findByLabelText('Go to previous page');
const findRunnerPaginationNext = () => findRunnerPagination().findByLabelText('Go to next page');
const findRunnerFilteredSearchBar = () => wrapper.findComponent(RunnerFilteredSearchBar);
const findFilteredSearch = () => wrapper.findComponent(FilteredSearch);
const createComponent = ({ props = {}, mountFn = shallowMountExtended } = {}) => {
const handlers = [
- [getRunnersQuery, mockRunnersQuery],
- [getRunnersCountQuery, mockRunnersCountQuery],
+ [adminRunnersQuery, mockRunnersQuery],
+ [adminRunnersCountQuery, mockRunnersCountQuery],
];
wrapper = mountFn(AdminRunnersApp, {
@@ -94,6 +95,7 @@ describe('AdminRunnersApp', () => {
afterEach(() => {
mockRunnersQuery.mockReset();
+ mockRunnersCountQuery.mockReset();
wrapper.destroy();
});
@@ -188,6 +190,21 @@ describe('AdminRunnersApp', () => {
expect(runnerLink.attributes('href')).toBe(`http://localhost/admin/runners/${numericId}`);
});
+ it('renders runner actions for each runner', async () => {
+ createComponent({ mountFn: mountExtended });
+
+ await waitForPromises();
+
+ const runnerActions = wrapper.find('tr [data-testid="td-actions"]').find(RunnerActionsCell);
+
+ const runner = runnersData.data.runners.nodes[0];
+
+ expect(runnerActions.props()).toEqual({
+ runner,
+ editUrl: runner.editAdminUrl,
+ });
+ });
+
it('requests the runners with no filters', () => {
expect(mockRunnersQuery).toHaveBeenLastCalledWith({
status: undefined,
@@ -212,6 +229,41 @@ describe('AdminRunnersApp', () => {
]);
});
+ describe('Single runner row', () => {
+ let showToast;
+
+ const mockRunner = runnersData.data.runners.nodes[0];
+ const { id: graphqlId, shortSha } = mockRunner;
+ const id = getIdFromGraphQLId(graphqlId);
+
+ beforeEach(async () => {
+ mockRunnersQuery.mockClear();
+
+ createComponent({ mountFn: mountExtended });
+ showToast = jest.spyOn(wrapper.vm.$root.$toast, 'show');
+
+ await waitForPromises();
+ });
+
+ it('Links to the runner page', async () => {
+ const runnerLink = wrapper.find('tr [data-testid="td-summary"]').find(GlLink);
+
+ expect(runnerLink.text()).toBe(`#${id} (${shortSha})`);
+ expect(runnerLink.attributes('href')).toBe(`http://localhost/admin/runners/${id}`);
+ });
+
+ it('When runner is deleted, data is refetched and a toast message is shown', async () => {
+ expect(mockRunnersQuery).toHaveBeenCalledTimes(1);
+
+ findRunnerActionsCell().vm.$emit('deleted', { message: 'Runner deleted' });
+
+ expect(mockRunnersQuery).toHaveBeenCalledTimes(2);
+
+ expect(showToast).toHaveBeenCalledTimes(1);
+ expect(showToast).toHaveBeenCalledWith('Runner deleted');
+ });
+ });
+
describe('when a filter is preselected', () => {
beforeEach(async () => {
setWindowLocation(`?status[]=${STATUS_ACTIVE}&runner_type[]=${INSTANCE_TYPE}&tag[]=tag1`);
@@ -316,14 +368,6 @@ describe('AdminRunnersApp', () => {
await waitForPromises();
});
- it('more pages can be selected', () => {
- expect(findRunnerPagination().text()).toMatchInterpolatedText('Prev Next');
- });
-
- it('cannot navigate to the previous page', () => {
- expect(findRunnerPaginationPrev().attributes('aria-disabled')).toBe('true');
- });
-
it('navigates to the next page', async () => {
await findRunnerPaginationNext().trigger('click');
diff --git a/spec/frontend/runner/components/cells/runner_actions_cell_spec.js b/spec/frontend/runner/components/cells/runner_actions_cell_spec.js
index dcb0af67784..0d579106860 100644
--- a/spec/frontend/runner/components/cells/runner_actions_cell_spec.js
+++ b/spec/frontend/runner/components/cells/runner_actions_cell_spec.js
@@ -1,84 +1,37 @@
-import Vue from 'vue';
-import VueApollo from 'vue-apollo';
-import createMockApollo from 'helpers/mock_apollo_helper';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
-import waitForPromises from 'helpers/wait_for_promises';
-import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
-import { createAlert } from '~/flash';
-import { getIdFromGraphQLId } from '~/graphql_shared/utils';
-import { captureException } from '~/runner/sentry_utils';
-import RunnerActionCell from '~/runner/components/cells/runner_actions_cell.vue';
+import RunnerActionsCell from '~/runner/components/cells/runner_actions_cell.vue';
import RunnerPauseButton from '~/runner/components/runner_pause_button.vue';
import RunnerEditButton from '~/runner/components/runner_edit_button.vue';
-import RunnerDeleteModal from '~/runner/components/runner_delete_modal.vue';
-import getGroupRunnersQuery from '~/runner/graphql/get_group_runners.query.graphql';
-import getRunnersQuery from '~/runner/graphql/get_runners.query.graphql';
-import runnerDeleteMutation from '~/runner/graphql/runner_delete.mutation.graphql';
+import RunnerDeleteButton from '~/runner/components/runner_delete_button.vue';
import { runnersData } from '../../mock_data';
const mockRunner = runnersData.data.runners.nodes[0];
-const getRunnersQueryName = getRunnersQuery.definitions[0].name.value;
-const getGroupRunnersQueryName = getGroupRunnersQuery.definitions[0].name.value;
-
-Vue.use(VueApollo);
-
-jest.mock('~/flash');
-jest.mock('~/runner/sentry_utils');
-
-describe('RunnerTypeCell', () => {
+describe('RunnerActionsCell', () => {
let wrapper;
- const mockToastShow = jest.fn();
- const runnerDeleteMutationHandler = jest.fn();
-
const findEditBtn = () => wrapper.findComponent(RunnerEditButton);
const findRunnerPauseBtn = () => wrapper.findComponent(RunnerPauseButton);
- const findRunnerDeleteModal = () => wrapper.findComponent(RunnerDeleteModal);
- const findDeleteBtn = () => wrapper.findByTestId('delete-runner');
- const getTooltip = (w) => getBinding(w.element, 'gl-tooltip')?.value;
+ const findDeleteBtn = () => wrapper.findComponent(RunnerDeleteButton);
- const createComponent = (runner = {}, options) => {
- wrapper = shallowMountExtended(RunnerActionCell, {
+ const createComponent = ({ runner = {}, ...props } = {}) => {
+ wrapper = shallowMountExtended(RunnerActionsCell, {
propsData: {
+ editUrl: mockRunner.editAdminUrl,
runner: {
id: mockRunner.id,
shortSha: mockRunner.shortSha,
editAdminUrl: mockRunner.editAdminUrl,
userPermissions: mockRunner.userPermissions,
- active: mockRunner.active,
...runner,
},
+ ...props,
},
- apolloProvider: createMockApollo([[runnerDeleteMutation, runnerDeleteMutationHandler]]),
- directives: {
- GlTooltip: createMockDirective(),
- GlModal: createMockDirective(),
- },
- mocks: {
- $toast: {
- show: mockToastShow,
- },
- },
- ...options,
});
};
- beforeEach(() => {
- runnerDeleteMutationHandler.mockResolvedValue({
- data: {
- runnerDelete: {
- errors: [],
- },
- },
- });
- });
-
afterEach(() => {
- mockToastShow.mockReset();
- runnerDeleteMutationHandler.mockReset();
-
wrapper.destroy();
});
@@ -91,18 +44,20 @@ describe('RunnerTypeCell', () => {
it('Does not render the runner edit link when user cannot update', () => {
createComponent({
- userPermissions: {
- ...mockRunner.userPermissions,
- updateRunner: false,
+ runner: {
+ userPermissions: {
+ ...mockRunner.userPermissions,
+ updateRunner: false,
+ },
},
});
expect(findEditBtn().exists()).toBe(false);
});
- it('Does not render the runner edit link when editAdminUrl is not provided', () => {
+ it('Does not render the runner edit link when editUrl is not provided', () => {
createComponent({
- editAdminUrl: null,
+ editUrl: null,
});
expect(findEditBtn().exists()).toBe(false);
@@ -118,9 +73,11 @@ describe('RunnerTypeCell', () => {
it('Does not render the runner pause button when user cannot update', () => {
createComponent({
- userPermissions: {
- ...mockRunner.userPermissions,
- updateRunner: false,
+ runner: {
+ userPermissions: {
+ ...mockRunner.userPermissions,
+ updateRunner: false,
+ },
},
});
@@ -129,147 +86,35 @@ describe('RunnerTypeCell', () => {
});
describe('Delete action', () => {
- beforeEach(() => {
- createComponent(
- {},
- {
- stubs: { RunnerDeleteModal },
- },
- );
- });
+ it('Renders a compact delete button', () => {
+ createComponent();
- it('Renders delete button', () => {
- expect(findDeleteBtn().exists()).toBe(true);
+ expect(findDeleteBtn().props('compact')).toBe(true);
});
- it('Delete button opens delete modal', () => {
- const modalId = getBinding(findDeleteBtn().element, 'gl-modal').value;
+ it('Emits delete events', () => {
+ const value = { name: 'Runner' };
- expect(findRunnerDeleteModal().attributes('modal-id')).toBeDefined();
- expect(findRunnerDeleteModal().attributes('modal-id')).toBe(modalId);
- });
-
- it('Delete modal shows the runner name', () => {
- expect(findRunnerDeleteModal().props('runnerName')).toBe(
- `#${getIdFromGraphQLId(mockRunner.id)} (${mockRunner.shortSha})`,
- );
- });
- it('The delete button does not have a loading icon', () => {
- expect(findDeleteBtn().props('loading')).toBe(false);
- expect(getTooltip(findDeleteBtn())).toBe('Delete runner');
- });
+ createComponent();
- it('When delete mutation is called, current runners are refetched', () => {
- jest.spyOn(wrapper.vm.$apollo, 'mutate');
+ expect(wrapper.emitted('deleted')).toBe(undefined);
- findRunnerDeleteModal().vm.$emit('primary');
+ findDeleteBtn().vm.$emit('deleted', value);
- expect(wrapper.vm.$apollo.mutate).toHaveBeenCalledWith({
- mutation: runnerDeleteMutation,
- variables: {
- input: {
- id: mockRunner.id,
- },
- },
- awaitRefetchQueries: true,
- refetchQueries: [getRunnersQueryName, getGroupRunnersQueryName],
- });
+ expect(wrapper.emitted('deleted')).toEqual([[value]]);
});
it('Does not render the runner delete button when user cannot delete', () => {
createComponent({
- userPermissions: {
- ...mockRunner.userPermissions,
- deleteRunner: false,
+ runner: {
+ userPermissions: {
+ ...mockRunner.userPermissions,
+ deleteRunner: false,
+ },
},
});
expect(findDeleteBtn().exists()).toBe(false);
- expect(findRunnerDeleteModal().exists()).toBe(false);
- });
-
- describe('When delete is clicked', () => {
- beforeEach(async () => {
- findRunnerDeleteModal().vm.$emit('primary');
- await waitForPromises();
- });
-
- it('The delete mutation is called correctly', () => {
- expect(runnerDeleteMutationHandler).toHaveBeenCalledTimes(1);
- expect(runnerDeleteMutationHandler).toHaveBeenCalledWith({
- input: { id: mockRunner.id },
- });
- });
-
- it('The delete button has a loading icon', () => {
- expect(findDeleteBtn().props('loading')).toBe(true);
- expect(getTooltip(findDeleteBtn())).toBe('');
- });
-
- it('The toast notification is shown', async () => {
- await waitForPromises();
- expect(mockToastShow).toHaveBeenCalledTimes(1);
- expect(mockToastShow).toHaveBeenCalledWith(
- expect.stringContaining(`#${getIdFromGraphQLId(mockRunner.id)} (${mockRunner.shortSha})`),
- );
- });
- });
-
- describe('When delete fails', () => {
- describe('On a network error', () => {
- const mockErrorMsg = 'Delete error!';
-
- beforeEach(async () => {
- runnerDeleteMutationHandler.mockRejectedValueOnce(new Error(mockErrorMsg));
-
- findRunnerDeleteModal().vm.$emit('primary');
- await waitForPromises();
- });
-
- it('error is reported to sentry', () => {
- expect(captureException).toHaveBeenCalledWith({
- error: new Error(mockErrorMsg),
- component: 'RunnerActionsCell',
- });
- });
-
- it('error is shown to the user', () => {
- expect(createAlert).toHaveBeenCalledTimes(1);
- });
-
- it('toast notification is not shown', () => {
- expect(mockToastShow).not.toHaveBeenCalled();
- });
- });
-
- describe('On a validation error', () => {
- const mockErrorMsg = 'Runner not found!';
- const mockErrorMsg2 = 'User not allowed!';
-
- beforeEach(async () => {
- runnerDeleteMutationHandler.mockResolvedValue({
- data: {
- runnerDelete: {
- errors: [mockErrorMsg, mockErrorMsg2],
- },
- },
- });
-
- findRunnerDeleteModal().vm.$emit('primary');
- await waitForPromises();
- });
-
- it('error is reported to sentry', () => {
- expect(captureException).toHaveBeenCalledWith({
- error: new Error(`${mockErrorMsg} ${mockErrorMsg2}`),
- component: 'RunnerActionsCell',
- });
- });
-
- it('error is shown to the user', () => {
- expect(createAlert).toHaveBeenCalledTimes(1);
- });
- });
});
});
});
diff --git a/spec/frontend/runner/components/registration/registration_token_reset_dropdown_item_spec.js b/spec/frontend/runner/components/registration/registration_token_reset_dropdown_item_spec.js
index d2deb49a5f7..2510aaf0334 100644
--- a/spec/frontend/runner/components/registration/registration_token_reset_dropdown_item_spec.js
+++ b/spec/frontend/runner/components/registration/registration_token_reset_dropdown_item_spec.js
@@ -8,7 +8,7 @@ import waitForPromises from 'helpers/wait_for_promises';
import { createAlert } from '~/flash';
import RegistrationTokenResetDropdownItem from '~/runner/components/registration/registration_token_reset_dropdown_item.vue';
import { INSTANCE_TYPE, GROUP_TYPE, PROJECT_TYPE } from '~/runner/constants';
-import runnersRegistrationTokenResetMutation from '~/runner/graphql/runners_registration_token_reset.mutation.graphql';
+import runnersRegistrationTokenResetMutation from '~/runner/graphql/list/runners_registration_token_reset.mutation.graphql';
import { captureException } from '~/runner/sentry_utils';
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
diff --git a/spec/frontend/runner/components/runner_delete_button_spec.js b/spec/frontend/runner/components/runner_delete_button_spec.js
new file mode 100644
index 00000000000..81c870f23cf
--- /dev/null
+++ b/spec/frontend/runner/components/runner_delete_button_spec.js
@@ -0,0 +1,233 @@
+import Vue from 'vue';
+import { GlButton } from '@gitlab/ui';
+import VueApollo from 'vue-apollo';
+import createMockApollo from 'helpers/mock_apollo_helper';
+import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
+import { shallowMountExtended, mountExtended } from 'helpers/vue_test_utils_helper';
+import runnerDeleteMutation from '~/runner/graphql/shared/runner_delete.mutation.graphql';
+import waitForPromises from 'helpers/wait_for_promises';
+import { captureException } from '~/runner/sentry_utils';
+import { getIdFromGraphQLId } from '~/graphql_shared/utils';
+import { createAlert } from '~/flash';
+import { I18N_DELETE_RUNNER } from '~/runner/constants';
+
+import RunnerDeleteButton from '~/runner/components/runner_delete_button.vue';
+import RunnerDeleteModal from '~/runner/components/runner_delete_modal.vue';
+import { runnersData } from '../mock_data';
+
+const mockRunner = runnersData.data.runners.nodes[0];
+const mockRunnerId = getIdFromGraphQLId(mockRunner.id);
+
+Vue.use(VueApollo);
+
+jest.mock('~/flash');
+jest.mock('~/runner/sentry_utils');
+
+describe('RunnerDeleteButton', () => {
+ let wrapper;
+ let runnerDeleteHandler;
+
+ const getTooltip = () => getBinding(wrapper.element, 'gl-tooltip').value;
+ const getModal = () => getBinding(wrapper.element, 'gl-modal').value;
+ const findBtn = () => wrapper.findComponent(GlButton);
+ const findModal = () => wrapper.findComponent(RunnerDeleteModal);
+
+ const createComponent = ({ props = {}, mountFn = shallowMountExtended } = {}) => {
+ const { runner, ...propsData } = props;
+
+ wrapper = mountFn(RunnerDeleteButton, {
+ propsData: {
+ runner: {
+ id: mockRunner.id,
+ shortSha: mockRunner.shortSha,
+ ...runner,
+ },
+ ...propsData,
+ },
+ apolloProvider: createMockApollo([[runnerDeleteMutation, runnerDeleteHandler]]),
+ directives: {
+ GlTooltip: createMockDirective(),
+ GlModal: createMockDirective(),
+ },
+ });
+ };
+
+ const clickOkAndWait = async () => {
+ findModal().vm.$emit('primary');
+ await waitForPromises();
+ };
+
+ beforeEach(() => {
+ runnerDeleteHandler = jest.fn().mockImplementation(() => {
+ return Promise.resolve({
+ data: {
+ runnerDelete: {
+ errors: [],
+ },
+ },
+ });
+ });
+
+ createComponent();
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ it('Displays a delete button without an icon', () => {
+ expect(findBtn().props()).toMatchObject({
+ loading: false,
+ icon: '',
+ });
+ expect(findBtn().classes('btn-icon')).toBe(false);
+ expect(findBtn().text()).toBe(I18N_DELETE_RUNNER);
+ });
+
+ it('Displays a modal with the runner name', () => {
+ expect(findModal().props('runnerName')).toBe(`#${mockRunnerId} (${mockRunner.shortSha})`);
+ });
+
+ it('Displays a modal when clicked', () => {
+ const modalId = `delete-runner-modal-${mockRunnerId}`;
+
+ expect(getModal()).toBe(modalId);
+ expect(findModal().attributes('modal-id')).toBe(modalId);
+ });
+
+ it('Does not display redundant text for screen readers', () => {
+ expect(findBtn().attributes('aria-label')).toBe(undefined);
+ });
+
+ describe(`Before the delete button is clicked`, () => {
+ it('The mutation has not been called', () => {
+ expect(runnerDeleteHandler).toHaveBeenCalledTimes(0);
+ });
+ });
+
+ describe('Immediately after the delete button is clicked', () => {
+ beforeEach(async () => {
+ findModal().vm.$emit('primary');
+ });
+
+ it('The button has a loading state', async () => {
+ expect(findBtn().props('loading')).toBe(true);
+ });
+
+ it('The stale tooltip is removed', async () => {
+ expect(getTooltip()).toBe('');
+ });
+ });
+
+ describe('After clicking on the delete button', () => {
+ beforeEach(async () => {
+ await clickOkAndWait();
+ });
+
+ it('The mutation to delete is called', () => {
+ expect(runnerDeleteHandler).toHaveBeenCalledTimes(1);
+ expect(runnerDeleteHandler).toHaveBeenCalledWith({
+ input: {
+ id: mockRunner.id,
+ },
+ });
+ });
+
+ it('The user can be notified with an event', () => {
+ const deleted = wrapper.emitted('deleted');
+
+ expect(deleted).toHaveLength(1);
+ expect(deleted[0][0].message).toMatch(`#${mockRunnerId}`);
+ expect(deleted[0][0].message).toMatch(`${mockRunner.shortSha}`);
+ });
+ });
+
+ describe('When update fails', () => {
+ describe('On a network error', () => {
+ const mockErrorMsg = 'Update error!';
+
+ beforeEach(async () => {
+ runnerDeleteHandler.mockRejectedValueOnce(new Error(mockErrorMsg));
+
+ await clickOkAndWait();
+ });
+
+ it('error is reported to sentry', () => {
+ expect(captureException).toHaveBeenCalledWith({
+ error: new Error(mockErrorMsg),
+ component: 'RunnerDeleteButton',
+ });
+ });
+
+ it('error is shown to the user', () => {
+ expect(createAlert).toHaveBeenCalledTimes(1);
+ });
+ });
+
+ describe('On a validation error', () => {
+ const mockErrorMsg = 'Runner not found!';
+ const mockErrorMsg2 = 'User not allowed!';
+
+ beforeEach(async () => {
+ runnerDeleteHandler.mockResolvedValueOnce({
+ data: {
+ runnerDelete: {
+ errors: [mockErrorMsg, mockErrorMsg2],
+ },
+ },
+ });
+
+ await clickOkAndWait();
+ });
+
+ it('error is reported to sentry', () => {
+ expect(captureException).toHaveBeenCalledWith({
+ error: new Error(`${mockErrorMsg} ${mockErrorMsg2}`),
+ component: 'RunnerDeleteButton',
+ });
+ });
+
+ it('error is shown to the user', () => {
+ expect(createAlert).toHaveBeenCalledTimes(1);
+ });
+ });
+ });
+
+ describe('When displaying a compact button for an active runner', () => {
+ beforeEach(() => {
+ createComponent({
+ props: {
+ runner: {
+ active: true,
+ },
+ compact: true,
+ },
+ mountFn: mountExtended,
+ });
+ });
+
+ it('Displays no text', () => {
+ expect(findBtn().text()).toBe('');
+ expect(findBtn().classes('btn-icon')).toBe(true);
+ });
+
+ it('Display correctly for screen readers', () => {
+ expect(findBtn().attributes('aria-label')).toBe(I18N_DELETE_RUNNER);
+ expect(getTooltip()).toBe(I18N_DELETE_RUNNER);
+ });
+
+ describe('Immediately after the button is clicked', () => {
+ beforeEach(async () => {
+ findModal().vm.$emit('primary');
+ });
+
+ it('The button has a loading state', async () => {
+ expect(findBtn().props('loading')).toBe(true);
+ });
+
+ it('The stale tooltip is removed', async () => {
+ expect(getTooltip()).toBe('');
+ });
+ });
+ });
+});
diff --git a/spec/frontend/runner/components/runner_jobs_spec.js b/spec/frontend/runner/components/runner_jobs_spec.js
index 97339056370..9abb2861005 100644
--- a/spec/frontend/runner/components/runner_jobs_spec.js
+++ b/spec/frontend/runner/components/runner_jobs_spec.js
@@ -11,7 +11,7 @@ import RunnerPagination from '~/runner/components/runner_pagination.vue';
import { captureException } from '~/runner/sentry_utils';
import { I18N_NO_JOBS_FOUND, RUNNER_DETAILS_JOBS_PAGE_SIZE } from '~/runner/constants';
-import getRunnerJobsQuery from '~/runner/graphql/get_runner_jobs.query.graphql';
+import runnerJobsQuery from '~/runner/graphql/details/runner_jobs.query.graphql';
import { runnerData, runnerJobsData } from '../mock_data';
@@ -34,7 +34,7 @@ describe('RunnerJobs', () => {
const createComponent = ({ mountFn = shallowMountExtended } = {}) => {
wrapper = mountFn(RunnerJobs, {
- apolloProvider: createMockApollo([[getRunnerJobsQuery, mockRunnerJobsQuery]]),
+ apolloProvider: createMockApollo([[runnerJobsQuery, mockRunnerJobsQuery]]),
propsData: {
runner: mockRunner,
},
diff --git a/spec/frontend/runner/components/runner_list_spec.js b/spec/frontend/runner/components/runner_list_spec.js
index 42d6ecca09e..a0f42738d2c 100644
--- a/spec/frontend/runner/components/runner_list_spec.js
+++ b/spec/frontend/runner/components/runner_list_spec.js
@@ -1,4 +1,4 @@
-import { GlTable, GlSkeletonLoader } from '@gitlab/ui';
+import { GlTableLite, GlSkeletonLoader } from '@gitlab/ui';
import {
extendedWrapper,
shallowMountExtended,
@@ -6,8 +6,6 @@ import {
} from 'helpers/vue_test_utils_helper';
import { getIdFromGraphQLId } from '~/graphql_shared/utils';
import RunnerList from '~/runner/components/runner_list.vue';
-import RunnerEditButton from '~/runner/components/runner_edit_button.vue';
-import RunnerPauseButton from '~/runner/components/runner_pause_button.vue';
import { runnersData } from '../mock_data';
const mockRunners = runnersData.data.runners.nodes;
@@ -17,19 +15,20 @@ describe('RunnerList', () => {
let wrapper;
const findSkeletonLoader = () => wrapper.findComponent(GlSkeletonLoader);
- const findTable = () => wrapper.findComponent(GlTable);
+ const findTable = () => wrapper.findComponent(GlTableLite);
const findHeaders = () => wrapper.findAll('th');
const findRows = () => wrapper.findAll('[data-testid^="runner-row-"]');
const findCell = ({ row = 0, fieldKey }) =>
extendedWrapper(findRows().at(row).find(`[data-testid="td-${fieldKey}"]`));
- const createComponent = ({ props = {} } = {}, mountFn = shallowMountExtended) => {
+ const createComponent = ({ props = {}, ...options } = {}, mountFn = shallowMountExtended) => {
wrapper = mountFn(RunnerList, {
propsData: {
runners: mockRunners,
activeRunnersCount: mockActiveRunnersCount,
...props,
},
+ ...options,
});
};
@@ -90,11 +89,31 @@ describe('RunnerList', () => {
expect(findCell({ fieldKey: 'contactedAt' }).text()).toEqual(expect.any(String));
// Actions
- const actions = findCell({ fieldKey: 'actions' });
+ expect(findCell({ fieldKey: 'actions' }).exists()).toBe(true);
+ });
+
+ describe('Scoped cell slots', () => {
+ it('Render #runner-name slot in "summary" cell', () => {
+ createComponent(
+ {
+ scopedSlots: { 'runner-name': ({ runner }) => `Summary: ${runner.id}` },
+ },
+ mountExtended,
+ );
+
+ expect(findCell({ fieldKey: 'summary' }).text()).toContain(`Summary: ${mockRunners[0].id}`);
+ });
- expect(actions.findComponent(RunnerEditButton).exists()).toBe(true);
- expect(actions.findComponent(RunnerPauseButton).exists()).toBe(true);
- expect(actions.findByTestId('delete-runner').exists()).toBe(true);
+ it('Render #runner-actions-cell slot in "actions" cell', () => {
+ createComponent(
+ {
+ scopedSlots: { 'runner-actions-cell': ({ runner }) => `Actions: ${runner.id}` },
+ },
+ mountExtended,
+ );
+
+ expect(findCell({ fieldKey: 'actions' }).text()).toBe(`Actions: ${mockRunners[0].id}`);
+ });
});
describe('Table data formatting', () => {
@@ -143,7 +162,8 @@ describe('RunnerList', () => {
describe('When data is loading', () => {
it('shows a busy state', () => {
createComponent({ props: { runners: [], loading: true } });
- expect(findTable().attributes('busy')).toBeTruthy();
+
+ expect(findTable().classes('gl-opacity-6')).toBe(true);
});
it('when there are no runners, shows an skeleton loader', () => {
diff --git a/spec/frontend/runner/components/runner_pagination_spec.js b/spec/frontend/runner/components/runner_pagination_spec.js
index ecd6e6bd7f9..e144b52ceb3 100644
--- a/spec/frontend/runner/components/runner_pagination_spec.js
+++ b/spec/frontend/runner/components/runner_pagination_spec.js
@@ -45,14 +45,6 @@ describe('RunnerPagination', () => {
expect(findPagination().props('nextPage')).toBe(2);
});
- it('Shows prev page disabled', () => {
- expect(findPagination().find('[aria-disabled]').text()).toBe('Prev');
- });
-
- it('Shows next page link', () => {
- expect(findPagination().find('a').text()).toBe('Next');
- });
-
it('Goes to the second page', () => {
findPagination().vm.$emit('input', 2);
@@ -84,7 +76,7 @@ describe('RunnerPagination', () => {
const links = findPagination().findAll('a');
expect(links).toHaveLength(2);
- expect(links.at(0).text()).toBe('Prev');
+ expect(links.at(0).text()).toBe('Previous');
expect(links.at(1).text()).toBe('Next');
});
@@ -124,14 +116,6 @@ describe('RunnerPagination', () => {
expect(findPagination().props('prevPage')).toBe(2);
expect(findPagination().props('nextPage')).toBe(null);
});
-
- it('Shows next page link', () => {
- expect(findPagination().find('a').text()).toBe('Prev');
- });
-
- it('Shows next page disabled', () => {
- expect(findPagination().find('[aria-disabled]').text()).toBe('Next');
- });
});
describe('When only one page', () => {
diff --git a/spec/frontend/runner/components/runner_pause_button_spec.js b/spec/frontend/runner/components/runner_pause_button_spec.js
index 278f3dec2ee..3d9df03977e 100644
--- a/spec/frontend/runner/components/runner_pause_button_spec.js
+++ b/spec/frontend/runner/components/runner_pause_button_spec.js
@@ -4,10 +4,16 @@ import VueApollo from 'vue-apollo';
import createMockApollo from 'helpers/mock_apollo_helper';
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
import { shallowMountExtended, mountExtended } from 'helpers/vue_test_utils_helper';
-import runnerToggleActiveMutation from '~/runner/graphql/runner_toggle_active.mutation.graphql';
+import runnerToggleActiveMutation from '~/runner/graphql/shared/runner_toggle_active.mutation.graphql';
import waitForPromises from 'helpers/wait_for_promises';
import { captureException } from '~/runner/sentry_utils';
import { createAlert } from '~/flash';
+import {
+ I18N_PAUSE,
+ I18N_PAUSE_TOOLTIP,
+ I18N_RESUME,
+ I18N_RESUME_TOOLTIP,
+} from '~/runner/constants';
import RunnerPauseButton from '~/runner/components/runner_pause_button.vue';
import { runnersData } from '../mock_data';
@@ -74,10 +80,10 @@ describe('RunnerPauseButton', () => {
describe('Pause/Resume action', () => {
describe.each`
- runnerState | icon | content | isActive | newActiveValue
- ${'paused'} | ${'play'} | ${'Resume'} | ${false} | ${true}
- ${'active'} | ${'pause'} | ${'Pause'} | ${true} | ${false}
- `('When the runner is $runnerState', ({ icon, content, isActive, newActiveValue }) => {
+ runnerState | icon | content | tooltip | isActive | newActiveValue
+ ${'paused'} | ${'play'} | ${I18N_RESUME} | ${I18N_RESUME_TOOLTIP} | ${false} | ${true}
+ ${'active'} | ${'pause'} | ${I18N_PAUSE} | ${I18N_PAUSE_TOOLTIP} | ${true} | ${false}
+ `('When the runner is $runnerState', ({ icon, content, tooltip, isActive, newActiveValue }) => {
beforeEach(() => {
createComponent({
props: {
@@ -91,7 +97,11 @@ describe('RunnerPauseButton', () => {
it(`Displays a ${icon} button`, () => {
expect(findBtn().props('loading')).toBe(false);
expect(findBtn().props('icon')).toBe(icon);
+ });
+
+ it('Displays button content', () => {
expect(findBtn().text()).toBe(content);
+ expect(getTooltip()).toBe(tooltip);
});
it('Does not display redundant text for screen readers', () => {
@@ -218,8 +228,8 @@ describe('RunnerPauseButton', () => {
});
it('Display correctly for screen readers', () => {
- expect(findBtn().attributes('aria-label')).toBe('Pause');
- expect(getTooltip()).toBe('Pause');
+ expect(findBtn().attributes('aria-label')).toBe(I18N_PAUSE);
+ expect(getTooltip()).toBe(I18N_PAUSE_TOOLTIP);
});
describe('Immediately after the button is clicked', () => {
diff --git a/spec/frontend/runner/components/runner_projects_spec.js b/spec/frontend/runner/components/runner_projects_spec.js
index 68a2130d6d9..96de8d11bca 100644
--- a/spec/frontend/runner/components/runner_projects_spec.js
+++ b/spec/frontend/runner/components/runner_projects_spec.js
@@ -16,7 +16,7 @@ import RunnerAssignedItem from '~/runner/components/runner_assigned_item.vue';
import RunnerPagination from '~/runner/components/runner_pagination.vue';
import { captureException } from '~/runner/sentry_utils';
-import getRunnerProjectsQuery from '~/runner/graphql/get_runner_projects.query.graphql';
+import runnerProjectsQuery from '~/runner/graphql/details/runner_projects.query.graphql';
import { runnerData, runnerProjectsData } from '../mock_data';
@@ -40,7 +40,7 @@ describe('RunnerProjects', () => {
const createComponent = ({ mountFn = shallowMountExtended } = {}) => {
wrapper = mountFn(RunnerProjects, {
- apolloProvider: createMockApollo([[getRunnerProjectsQuery, mockRunnerProjectsQuery]]),
+ apolloProvider: createMockApollo([[runnerProjectsQuery, mockRunnerProjectsQuery]]),
propsData: {
runner: mockRunner,
},
diff --git a/spec/frontend/runner/components/runner_update_form_spec.js b/spec/frontend/runner/components/runner_update_form_spec.js
index 8b76be396ef..b071791e39f 100644
--- a/spec/frontend/runner/components/runner_update_form_spec.js
+++ b/spec/frontend/runner/components/runner_update_form_spec.js
@@ -13,7 +13,7 @@ import {
ACCESS_LEVEL_REF_PROTECTED,
ACCESS_LEVEL_NOT_PROTECTED,
} from '~/runner/constants';
-import runnerUpdateMutation from '~/runner/graphql/runner_update.mutation.graphql';
+import runnerUpdateMutation from '~/runner/graphql/details/runner_update.mutation.graphql';
import { captureException } from '~/runner/sentry_utils';
import { runnerData } from '../mock_data';
diff --git a/spec/frontend/runner/group_runners/group_runners_app_spec.js b/spec/frontend/runner/group_runners/group_runners_app_spec.js
index 7cb1f49d4f7..70e303e8626 100644
--- a/spec/frontend/runner/group_runners/group_runners_app_spec.js
+++ b/spec/frontend/runner/group_runners/group_runners_app_spec.js
@@ -1,5 +1,5 @@
import Vue, { nextTick } from 'vue';
-import { GlLink } from '@gitlab/ui';
+import { GlButton, GlLink, GlToast } from '@gitlab/ui';
import VueApollo from 'vue-apollo';
import createMockApollo from 'helpers/mock_apollo_helper';
import setWindowLocation from 'helpers/set_window_location_helper';
@@ -17,6 +17,7 @@ import RunnerTypeTabs from '~/runner/components/runner_type_tabs.vue';
import RunnerFilteredSearchBar from '~/runner/components/runner_filtered_search_bar.vue';
import RunnerList from '~/runner/components/runner_list.vue';
import RunnerStats from '~/runner/components/stat/runner_stats.vue';
+import RunnerActionsCell from '~/runner/components/cells/runner_actions_cell.vue';
import RegistrationDropdown from '~/runner/components/registration/registration_dropdown.vue';
import RunnerPagination from '~/runner/components/runner_pagination.vue';
@@ -30,19 +31,22 @@ import {
PARAM_KEY_STATUS,
STATUS_ACTIVE,
RUNNER_PAGE_SIZE,
+ I18N_EDIT,
} from '~/runner/constants';
-import getGroupRunnersQuery from '~/runner/graphql/get_group_runners.query.graphql';
-import getGroupRunnersCountQuery from '~/runner/graphql/get_group_runners_count.query.graphql';
+import getGroupRunnersQuery from '~/runner/graphql/list/group_runners.query.graphql';
+import getGroupRunnersCountQuery from '~/runner/graphql/list/group_runners_count.query.graphql';
import GroupRunnersApp from '~/runner/group_runners/group_runners_app.vue';
import { captureException } from '~/runner/sentry_utils';
import FilteredSearch from '~/vue_shared/components/filtered_search_bar/filtered_search_bar_root.vue';
import { groupRunnersData, groupRunnersDataPaginated, groupRunnersCountData } from '../mock_data';
Vue.use(VueApollo);
+Vue.use(GlToast);
const mockGroupFullPath = 'group1';
const mockRegistrationToken = 'AABBCC';
-const mockGroupRunnersLimitedCount = groupRunnersData.data.group.runners.edges.length;
+const mockGroupRunnersEdges = groupRunnersData.data.group.runners.edges;
+const mockGroupRunnersLimitedCount = mockGroupRunnersEdges.length;
jest.mock('~/flash');
jest.mock('~/runner/sentry_utils');
@@ -57,12 +61,12 @@ describe('GroupRunnersApp', () => {
let mockGroupRunnersCountQuery;
const findRunnerStats = () => wrapper.findComponent(RunnerStats);
+ const findRunnerActionsCell = () => wrapper.findComponent(RunnerActionsCell);
const findRegistrationDropdown = () => wrapper.findComponent(RegistrationDropdown);
const findRunnerTypeTabs = () => wrapper.findComponent(RunnerTypeTabs);
const findRunnerList = () => wrapper.findComponent(RunnerList);
+ const findRunnerRow = (id) => extendedWrapper(wrapper.findByTestId(`runner-row-${id}`));
const findRunnerPagination = () => extendedWrapper(wrapper.findComponent(RunnerPagination));
- const findRunnerPaginationPrev = () =>
- findRunnerPagination().findByLabelText('Go to previous page');
const findRunnerPaginationNext = () => findRunnerPagination().findByLabelText('Go to next page');
const findRunnerFilteredSearchBar = () => wrapper.findComponent(RunnerFilteredSearchBar);
const findFilteredSearch = () => wrapper.findComponent(FilteredSearch);
@@ -156,20 +160,7 @@ describe('GroupRunnersApp', () => {
it('shows the runners list', () => {
const runners = findRunnerList().props('runners');
- expect(runners).toEqual(groupRunnersData.data.group.runners.edges.map(({ node }) => node));
- });
-
- it('runner item links to the runner group page', async () => {
- const { webUrl, node } = groupRunnersData.data.group.runners.edges[0];
- const { id, shortSha } = node;
-
- createComponent({ mountFn: mountExtended });
-
- await waitForPromises();
-
- const runnerLink = wrapper.find('tr [data-testid="td-summary"]').find(GlLink);
- expect(runnerLink.text()).toBe(`#${getIdFromGraphQLId(id)} (${shortSha})`);
- expect(runnerLink.attributes('href')).toBe(webUrl);
+ expect(runners).toEqual(mockGroupRunnersEdges.map(({ node }) => node));
});
it('requests the runners with group path and no other filters', () => {
@@ -196,6 +187,50 @@ describe('GroupRunnersApp', () => {
);
});
+ describe('Single runner row', () => {
+ let showToast;
+
+ const { webUrl, editUrl, node } = mockGroupRunnersEdges[0];
+ const { id: graphqlId, shortSha } = node;
+ const id = getIdFromGraphQLId(graphqlId);
+
+ beforeEach(async () => {
+ mockGroupRunnersQuery.mockClear();
+
+ createComponent({ mountFn: mountExtended });
+ showToast = jest.spyOn(wrapper.vm.$root.$toast, 'show');
+
+ await waitForPromises();
+ });
+
+ it('view link is displayed correctly', () => {
+ const viewLink = findRunnerRow(id).findByTestId('td-summary').findComponent(GlLink);
+
+ expect(viewLink.text()).toBe(`#${id} (${shortSha})`);
+ expect(viewLink.attributes('href')).toBe(webUrl);
+ });
+
+ it('edit link is displayed correctly', () => {
+ const editLink = findRunnerRow(id).findByTestId('td-actions').findComponent(GlButton);
+
+ expect(editLink.attributes()).toMatchObject({
+ 'aria-label': I18N_EDIT,
+ href: editUrl,
+ });
+ });
+
+ it('When runner is deleted, data is refetched and a toast is shown', async () => {
+ expect(mockGroupRunnersQuery).toHaveBeenCalledTimes(1);
+
+ findRunnerActionsCell().vm.$emit('deleted', { message: 'Runner deleted' });
+
+ expect(mockGroupRunnersQuery).toHaveBeenCalledTimes(2);
+
+ expect(showToast).toHaveBeenCalledTimes(1);
+ expect(showToast).toHaveBeenCalledWith('Runner deleted');
+ });
+ });
+
describe('when a filter is preselected', () => {
beforeEach(async () => {
setWindowLocation(`?status[]=${STATUS_ACTIVE}&runner_type[]=${INSTANCE_TYPE}`);
@@ -303,14 +338,6 @@ describe('GroupRunnersApp', () => {
await waitForPromises();
});
- it('more pages can be selected', () => {
- expect(findRunnerPagination().text()).toMatchInterpolatedText('Prev Next');
- });
-
- it('cannot navigate to the previous page', () => {
- expect(findRunnerPaginationPrev().attributes('aria-disabled')).toBe('true');
- });
-
it('navigates to the next page', async () => {
await findRunnerPaginationNext().trigger('click');
diff --git a/spec/frontend/runner/mock_data.js b/spec/frontend/runner/mock_data.js
index d80caa47752..49c25039719 100644
--- a/spec/frontend/runner/mock_data.js
+++ b/spec/frontend/runner/mock_data.js
@@ -1,18 +1,18 @@
// Fixtures generated by: spec/frontend/fixtures/runner.rb
-// Admin queries
-import runnersData from 'test_fixtures/graphql/runner/get_runners.query.graphql.json';
-import runnersCountData from 'test_fixtures/graphql/runner/get_runners_count.query.graphql.json';
-import runnersDataPaginated from 'test_fixtures/graphql/runner/get_runners.query.graphql.paginated.json';
-import runnerData from 'test_fixtures/graphql/runner/get_runner.query.graphql.json';
-import runnerWithGroupData from 'test_fixtures/graphql/runner/get_runner.query.graphql.with_group.json';
-import runnerProjectsData from 'test_fixtures/graphql/runner/get_runner_projects.query.graphql.json';
-import runnerJobsData from 'test_fixtures/graphql/runner/get_runner_jobs.query.graphql.json';
+// List queries
+import runnersData from 'test_fixtures/graphql/runner/list/admin_runners.query.graphql.json';
+import runnersDataPaginated from 'test_fixtures/graphql/runner/list/admin_runners.query.graphql.paginated.json';
+import runnersCountData from 'test_fixtures/graphql/runner/list/admin_runners_count.query.graphql.json';
+import groupRunnersData from 'test_fixtures/graphql/runner/list/group_runners.query.graphql.json';
+import groupRunnersDataPaginated from 'test_fixtures/graphql/runner/list/group_runners.query.graphql.paginated.json';
+import groupRunnersCountData from 'test_fixtures/graphql/runner/list/group_runners_count.query.graphql.json';
-// Group queries
-import groupRunnersData from 'test_fixtures/graphql/runner/get_group_runners.query.graphql.json';
-import groupRunnersCountData from 'test_fixtures/graphql/runner/get_group_runners_count.query.graphql.json';
-import groupRunnersDataPaginated from 'test_fixtures/graphql/runner/get_group_runners.query.graphql.paginated.json';
+// Details queries
+import runnerData from 'test_fixtures/graphql/runner/details/runner.query.graphql.json';
+import runnerWithGroupData from 'test_fixtures/graphql/runner/details/runner.query.graphql.with_group.json';
+import runnerProjectsData from 'test_fixtures/graphql/runner/details/runner_projects.query.graphql.json';
+import runnerJobsData from 'test_fixtures/graphql/runner/details/runner_jobs.query.graphql.json';
export {
runnersData,
diff --git a/spec/frontend/search/topbar/components/app_spec.js b/spec/frontend/search/topbar/components/app_spec.js
index 7ce5efb3c52..0a44688bfe0 100644
--- a/spec/frontend/search/topbar/components/app_spec.js
+++ b/spec/frontend/search/topbar/components/app_spec.js
@@ -1,4 +1,4 @@
-import { GlForm, GlSearchBoxByType, GlButton } from '@gitlab/ui';
+import { GlSearchBoxByClick } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
import Vuex from 'vuex';
@@ -36,40 +36,19 @@ describe('GlobalSearchTopbar', () => {
wrapper.destroy();
});
- const findTopbarForm = () => wrapper.find(GlForm);
- const findGlSearchBox = () => wrapper.find(GlSearchBoxByType);
+ const findGlSearchBox = () => wrapper.find(GlSearchBoxByClick);
const findGroupFilter = () => wrapper.find(GroupFilter);
const findProjectFilter = () => wrapper.find(ProjectFilter);
- const findSearchButton = () => wrapper.find(GlButton);
describe('template', () => {
beforeEach(() => {
createComponent();
});
- it('renders Topbar Form always', () => {
- expect(findTopbarForm().exists()).toBe(true);
- });
-
describe('Search box', () => {
it('renders always', () => {
expect(findGlSearchBox().exists()).toBe(true);
});
-
- describe('onSearch', () => {
- const testSearch = 'test search';
-
- beforeEach(() => {
- findGlSearchBox().vm.$emit('input', testSearch);
- });
-
- it('calls setQuery when input event is fired from GlSearchBoxByType', () => {
- expect(actionSpies.setQuery).toHaveBeenCalledWith(expect.any(Object), {
- key: 'search',
- value: testSearch,
- });
- });
- });
});
describe.each`
@@ -92,10 +71,6 @@ describe('GlobalSearchTopbar', () => {
expect(findProjectFilter().exists()).toBe(showFilters);
});
});
-
- it('renders SearchButton always', () => {
- expect(findSearchButton().exists()).toBe(true);
- });
});
describe('actions', () => {
@@ -103,8 +78,8 @@ describe('GlobalSearchTopbar', () => {
createComponent();
});
- it('clicking SearchButton calls applyQuery', () => {
- findTopbarForm().vm.$emit('submit', { preventDefault: () => {} });
+ it('clicking search button inside search box calls applyQuery', () => {
+ findGlSearchBox().vm.$emit('submit', { preventDefault: () => {} });
expect(actionSpies.applyQuery).toHaveBeenCalled();
});
diff --git a/spec/frontend/security_configuration/components/feature_card_spec.js b/spec/frontend/security_configuration/components/feature_card_spec.js
index 2b74be19480..f0d902bf9fe 100644
--- a/spec/frontend/security_configuration/components/feature_card_spec.js
+++ b/spec/frontend/security_configuration/components/feature_card_spec.js
@@ -50,7 +50,7 @@ describe('FeatureCard component', () => {
expect(enableLinks.exists()).toBe(expectEnableAction);
if (expectEnableAction) {
expect(enableLinks).toHaveLength(1);
- expect(enableLinks.at(0).props('category')).toBe('primary');
+ expect(enableLinks.at(0).props('category')).toBe('secondary');
}
const configureLinks = findConfigureLinks();
diff --git a/spec/frontend/security_configuration/components/training_provider_list_spec.js b/spec/frontend/security_configuration/components/training_provider_list_spec.js
index 18c9ada6bde..b8c1bef0ddd 100644
--- a/spec/frontend/security_configuration/components/training_provider_list_spec.js
+++ b/spec/frontend/security_configuration/components/training_provider_list_spec.js
@@ -1,15 +1,20 @@
import * as Sentry from '@sentry/browser';
-import { GlAlert, GlLink, GlToggle, GlCard, GlSkeletonLoader } from '@gitlab/ui';
-import { shallowMount } from '@vue/test-utils';
+import { GlAlert, GlLink, GlToggle, GlCard, GlSkeletonLoader, GlIcon } from '@gitlab/ui';
import Vue from 'vue';
import VueApollo from 'vue-apollo';
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import createMockApollo from 'helpers/mock_apollo_helper';
import { mockTracking, unmockTracking } from 'helpers/tracking_helper';
+import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
import {
TRACK_TOGGLE_TRAINING_PROVIDER_ACTION,
TRACK_TOGGLE_TRAINING_PROVIDER_LABEL,
+ TRACK_PROVIDER_LEARN_MORE_CLICK_ACTION,
+ TRACK_PROVIDER_LEARN_MORE_CLICK_LABEL,
} from '~/security_configuration/constants';
+import { TEMP_PROVIDER_URLS } from '~/security_configuration/components/constants';
import TrainingProviderList from '~/security_configuration/components/training_provider_list.vue';
+import { updateSecurityTrainingOptimisticResponse } from '~/security_configuration/graphql/cache_utils';
import securityTrainingProvidersQuery from '~/security_configuration/graphql/security_training_providers.query.graphql';
import configureSecurityTrainingProvidersMutation from '~/security_configuration/graphql/configure_security_training_providers.mutation.graphql';
import dismissUserCalloutMutation from '~/graphql_shared/mutations/dismiss_user_callout.mutation.graphql';
@@ -17,16 +22,30 @@ import waitForPromises from 'helpers/wait_for_promises';
import {
dismissUserCalloutResponse,
dismissUserCalloutErrorResponse,
- securityTrainingProviders,
- securityTrainingProvidersResponse,
+ getSecurityTrainingProvidersData,
updateSecurityTrainingProvidersResponse,
updateSecurityTrainingProvidersErrorResponse,
testProjectPath,
- textProviderIds,
+ testProviderIds,
+ testProviderName,
+ tempProviderLogos,
} from '../mock_data';
Vue.use(VueApollo);
+const TEST_TRAINING_PROVIDERS_ALL_DISABLED = getSecurityTrainingProvidersData();
+const TEST_TRAINING_PROVIDERS_FIRST_ENABLED = getSecurityTrainingProvidersData({
+ providerOverrides: { first: { isEnabled: true, isPrimary: true } },
+});
+const TEST_TRAINING_PROVIDERS_ALL_ENABLED = getSecurityTrainingProvidersData({
+ providerOverrides: {
+ first: { isEnabled: true, isPrimary: true },
+ second: { isEnabled: true, isPrimary: false },
+ third: { isEnabled: true, isPrimary: false },
+ },
+});
+const TEST_TRAINING_PROVIDERS_DEFAULT = TEST_TRAINING_PROVIDERS_ALL_DISABLED;
+
describe('TrainingProviderList component', () => {
let wrapper;
let apolloProvider;
@@ -35,7 +54,7 @@ describe('TrainingProviderList component', () => {
const defaultHandlers = [
[
securityTrainingProvidersQuery,
- jest.fn().mockResolvedValue(securityTrainingProvidersResponse),
+ jest.fn().mockResolvedValue(TEST_TRAINING_PROVIDERS_DEFAULT.response),
],
[
configureSecurityTrainingProvidersMutation,
@@ -50,10 +69,13 @@ describe('TrainingProviderList component', () => {
};
const createComponent = () => {
- wrapper = shallowMount(TrainingProviderList, {
+ wrapper = shallowMountExtended(TrainingProviderList, {
provide: {
projectFullPath: testProjectPath,
},
+ directives: {
+ GlTooltip: createMockDirective(),
+ },
apolloProvider,
});
};
@@ -65,10 +87,12 @@ describe('TrainingProviderList component', () => {
const findLinks = () => wrapper.findAllComponents(GlLink);
const findToggles = () => wrapper.findAllComponents(GlToggle);
const findFirstToggle = () => findToggles().at(0);
+ const findPrimaryProviderRadios = () => wrapper.findAllByTestId('primary-provider-radio');
const findLoader = () => wrapper.findComponent(GlSkeletonLoader);
const findErrorAlert = () => wrapper.findComponent(GlAlert);
+ const findLogos = () => wrapper.findAllByTestId('provider-logo');
- const toggleFirstProvider = () => findFirstToggle().vm.$emit('change', textProviderIds[0]);
+ const toggleFirstProvider = () => findFirstToggle().vm.$emit('change', testProviderIds[0]);
afterEach(() => {
wrapper.destroy();
@@ -104,7 +128,7 @@ describe('TrainingProviderList component', () => {
Mutation: {
configureSecurityTrainingProviders: () => ({
errors: [],
- securityTrainingProviders: [],
+ TEST_TRAINING_PROVIDERS_DEFAULT: [],
}),
},
},
@@ -119,10 +143,10 @@ describe('TrainingProviderList component', () => {
});
it('renders correct amount of cards', () => {
- expect(findCards()).toHaveLength(securityTrainingProviders.length);
+ expect(findCards()).toHaveLength(TEST_TRAINING_PROVIDERS_DEFAULT.data.length);
});
- securityTrainingProviders.forEach(({ name, description, url, isEnabled }, index) => {
+ TEST_TRAINING_PROVIDERS_DEFAULT.data.forEach(({ name, description, isEnabled }, index) => {
it(`shows the name for card ${index}`, () => {
expect(findCards().at(index).text()).toContain(name);
});
@@ -131,23 +155,76 @@ describe('TrainingProviderList component', () => {
expect(findCards().at(index).text()).toContain(description);
});
- it(`shows the learn more link for card ${index}`, () => {
- expect(findLinks().at(index).attributes()).toEqual({
- target: '_blank',
- href: url,
- });
+ it(`shows the learn more link for enabled card ${index}`, () => {
+ const learnMoreLink = findCards().at(index).find(GlLink);
+ const tempLogo = TEMP_PROVIDER_URLS[name];
+
+ if (tempLogo) {
+ expect(learnMoreLink.attributes()).toEqual({
+ target: '_blank',
+ href: TEMP_PROVIDER_URLS[name],
+ });
+ } else {
+ expect(learnMoreLink.exists()).toBe(false);
+ }
});
it(`shows the toggle with the correct value for card ${index}`, () => {
expect(findToggles().at(index).props('value')).toEqual(isEnabled);
});
+ it(`shows a radio button to select the provider as primary within card ${index}`, () => {
+ const primaryProviderRadioForCurrentCard = findPrimaryProviderRadios().at(index);
+
+ // if the given provider is not enabled it should not be possible select it as primary
+ expect(primaryProviderRadioForCurrentCard.find('input').attributes('disabled')).toBe(
+ isEnabled ? undefined : 'disabled',
+ );
+
+ expect(primaryProviderRadioForCurrentCard.text()).toBe(
+ TrainingProviderList.i18n.primaryTraining,
+ );
+ });
+
+ it('shows a info-tooltip that describes the purpose of a primary provider', () => {
+ const infoIcon = findPrimaryProviderRadios().at(index).find(GlIcon);
+ const tooltip = getBinding(infoIcon.element, 'gl-tooltip');
+
+ expect(infoIcon.props()).toMatchObject({
+ name: 'information-o',
+ });
+ expect(tooltip.value).toBe(TrainingProviderList.i18n.primaryTrainingDescription);
+ });
+
it('does not show loader when query is populated', () => {
expect(findLoader().exists()).toBe(false);
});
});
});
+ describe('provider logo', () => {
+ beforeEach(async () => {
+ wrapper.vm.$options.TEMP_PROVIDER_LOGOS = tempProviderLogos;
+ await waitForQueryToBeLoaded();
+ });
+
+ const providerIndexArray = [0, 1];
+
+ it.each(providerIndexArray)('displays the correct width for provider %s', (provider) => {
+ expect(findLogos().at(provider).attributes('style')).toBe('width: 18px;');
+ });
+
+ it.each(providerIndexArray)('has a11y decorative attribute for provider %s', (provider) => {
+ expect(findLogos().at(provider).attributes('role')).toBe('presentation');
+ });
+
+ it.each(providerIndexArray)('renders the svg content for provider %s', (provider) => {
+ expect(findLogos().at(provider).html()).toContain(
+ tempProviderLogos[testProviderName[provider]].svg,
+ );
+ });
+ });
+
describe('storing training provider settings', () => {
beforeEach(async () => {
jest.spyOn(apolloProvider.defaultClient, 'mutate');
@@ -157,26 +234,15 @@ describe('TrainingProviderList component', () => {
await toggleFirstProvider();
});
- it.each`
- loading | wait | desc
- ${true} | ${false} | ${'enables loading of GlToggle when mutation is called'}
- ${false} | ${true} | ${'disables loading of GlToggle when mutation is complete'}
- `('$desc', async ({ loading, wait }) => {
- if (wait) {
- await waitForMutationToBeLoaded();
- }
- expect(findFirstToggle().props('isLoading')).toBe(loading);
- });
-
it('calls mutation when toggle is changed', () => {
expect(apolloProvider.defaultClient.mutate).toHaveBeenCalledWith(
expect.objectContaining({
mutation: configureSecurityTrainingProvidersMutation,
variables: {
input: {
- providerId: textProviderIds[0],
+ providerId: testProviderIds[0],
isEnabled: true,
- isPrimary: false,
+ isPrimary: true,
projectPath: testProjectPath,
},
},
@@ -184,6 +250,20 @@ describe('TrainingProviderList component', () => {
);
});
+ it('returns an optimistic response when calling the mutation', () => {
+ const optimisticResponse = updateSecurityTrainingOptimisticResponse({
+ id: TEST_TRAINING_PROVIDERS_DEFAULT.data[0].id,
+ isEnabled: true,
+ isPrimary: true,
+ });
+
+ expect(apolloProvider.defaultClient.mutate).toHaveBeenCalledWith(
+ expect.objectContaining({
+ optimisticResponse,
+ }),
+ );
+ });
+
it('dismisses the callout when the feature gets first enabled', async () => {
// wait for configuration update mutation to complete
await waitForMutationToBeLoaded();
@@ -237,13 +317,62 @@ describe('TrainingProviderList component', () => {
// Once https://gitlab.com/gitlab-org/gitlab/-/issues/348985 and https://gitlab.com/gitlab-org/gitlab/-/merge_requests/79492
// are merged this will be much easer to do and should be tackled then.
expect(trackingSpy).toHaveBeenCalledWith(undefined, TRACK_TOGGLE_TRAINING_PROVIDER_ACTION, {
- property: securityTrainingProviders[0].id,
+ property: TEST_TRAINING_PROVIDERS_DEFAULT.data[0].id,
label: TRACK_TOGGLE_TRAINING_PROVIDER_LABEL,
extra: {
providerIsEnabled: true,
},
});
});
+
+ it(`tracks when a provider's "Learn more" link is clicked`, () => {
+ const firstProviderLink = findLinks().at(0);
+ const [{ id: firstProviderId }] = TEST_TRAINING_PROVIDERS_DEFAULT.data;
+
+ expect(trackingSpy).not.toHaveBeenCalled();
+
+ firstProviderLink.vm.$emit('click');
+
+ expect(trackingSpy).toHaveBeenCalledWith(
+ undefined,
+ TRACK_PROVIDER_LEARN_MORE_CLICK_ACTION,
+ {
+ label: TRACK_PROVIDER_LEARN_MORE_CLICK_LABEL,
+ property: firstProviderId,
+ },
+ );
+ });
+ });
+ });
+
+ describe('primary provider settings', () => {
+ it.each`
+ description | initialProviderData | expectedMutationInput
+ ${'sets the provider to be non-primary when it gets disabled'} | ${TEST_TRAINING_PROVIDERS_FIRST_ENABLED.response} | ${{ providerId: TEST_TRAINING_PROVIDERS_FIRST_ENABLED.data[0].id, isEnabled: false, isPrimary: false }}
+ ${'sets a provider to be primary when it is the only one enabled'} | ${TEST_TRAINING_PROVIDERS_ALL_DISABLED.response} | ${{ providerId: TEST_TRAINING_PROVIDERS_ALL_DISABLED.data[0].id, isEnabled: true, isPrimary: true }}
+ ${'sets the first other enabled provider to be primary when the primary one gets disabled'} | ${TEST_TRAINING_PROVIDERS_ALL_ENABLED.response} | ${{ providerId: TEST_TRAINING_PROVIDERS_ALL_ENABLED.data[1].id, isEnabled: true, isPrimary: true }}
+ `('$description', async ({ initialProviderData, expectedMutationInput }) => {
+ createApolloProvider({
+ handlers: [
+ [securityTrainingProvidersQuery, jest.fn().mockResolvedValue(initialProviderData)],
+ ],
+ });
+ jest.spyOn(apolloProvider.defaultClient, 'mutate');
+ createComponent();
+
+ await waitForQueryToBeLoaded();
+ await toggleFirstProvider();
+
+ expect(apolloProvider.defaultClient.mutate).toHaveBeenNthCalledWith(
+ 1,
+ expect.objectContaining({
+ variables: {
+ input: expect.objectContaining({
+ ...expectedMutationInput,
+ }),
+ },
+ }),
+ );
});
});
diff --git a/spec/frontend/security_configuration/graphql/cache_utils_spec.js b/spec/frontend/security_configuration/graphql/cache_utils_spec.js
new file mode 100644
index 00000000000..a40611cc022
--- /dev/null
+++ b/spec/frontend/security_configuration/graphql/cache_utils_spec.js
@@ -0,0 +1,108 @@
+import {
+ updateSecurityTrainingCache,
+ updateSecurityTrainingOptimisticResponse,
+} from '~/security_configuration/graphql/cache_utils';
+
+describe('EE - Security configuration graphQL cache utils', () => {
+ describe('updateSecurityTrainingOptimisticResponse', () => {
+ it('returns an optimistic response in the correct shape', () => {
+ const changes = { isEnabled: true, isPrimary: true };
+ const mutationResponse = updateSecurityTrainingOptimisticResponse(changes);
+
+ expect(mutationResponse).toEqual({
+ __typename: 'Mutation',
+ securityTrainingUpdate: {
+ __typename: 'SecurityTrainingUpdatePayload',
+ training: {
+ __typename: 'ProjectSecurityTraining',
+ ...changes,
+ },
+ errors: [],
+ },
+ });
+ });
+ });
+
+ describe('updateSecurityTrainingCache', () => {
+ let mockCache;
+
+ beforeEach(() => {
+ // freezing the data makes sure that we don't mutate the original project
+ const mockCacheData = Object.freeze({
+ project: {
+ securityTrainingProviders: [
+ { id: 1, isEnabled: true, isPrimary: true },
+ { id: 2, isEnabled: true, isPrimary: false },
+ { id: 3, isEnabled: false, isPrimary: false },
+ ],
+ },
+ });
+
+ mockCache = {
+ readQuery: () => mockCacheData,
+ writeQuery: jest.fn(),
+ };
+ });
+
+ it('does not update the cache when the primary provider is not getting disabled', () => {
+ const providerAfterUpdate = {
+ id: 2,
+ isEnabled: true,
+ isPrimary: false,
+ };
+
+ updateSecurityTrainingCache({
+ query: 'GraphQL query',
+ variables: { fullPath: 'gitlab/project' },
+ })(mockCache, {
+ data: {
+ securityTrainingUpdate: {
+ training: {
+ ...providerAfterUpdate,
+ },
+ },
+ },
+ });
+
+ expect(mockCache.writeQuery).not.toHaveBeenCalled();
+ });
+
+ it('sets the previous primary provider to be non-primary when another provider gets set as primary', () => {
+ const providerAfterUpdate = {
+ id: 2,
+ isEnabled: true,
+ isPrimary: true,
+ };
+
+ const expectedTrainingProvidersWrittenToCache = [
+ // this was the previous primary primary provider and it should not be primary any longer
+ { id: 1, isEnabled: true, isPrimary: false },
+ { id: 2, isEnabled: true, isPrimary: true },
+ { id: 3, isEnabled: false, isPrimary: false },
+ ];
+
+ updateSecurityTrainingCache({
+ query: 'GraphQL query',
+ variables: { fullPath: 'gitlab/project' },
+ })(mockCache, {
+ data: {
+ securityTrainingUpdate: {
+ training: {
+ ...providerAfterUpdate,
+ },
+ },
+ },
+ });
+
+ expect(mockCache.writeQuery).toHaveBeenCalledWith(
+ expect.objectContaining({
+ data: {
+ project: {
+ securityTrainingProviders: expectedTrainingProvidersWrittenToCache,
+ },
+ },
+ }),
+ );
+ });
+ });
+});
diff --git a/spec/frontend/security_configuration/mock_data.js b/spec/frontend/security_configuration/mock_data.js
index b042e870467..18a480bf082 100644
--- a/spec/frontend/security_configuration/mock_data.js
+++ b/spec/frontend/security_configuration/mock_data.js
@@ -1,33 +1,57 @@
export const testProjectPath = 'foo/bar';
+export const testProviderIds = [101, 102, 103];
+export const testProviderName = ['Kontra', 'Secure Code Warrior', 'Other Vendor'];
+export const testTrainingUrls = [
+ 'https://www.vendornameone.com/url',
+ 'https://www.vendornametwo.com/url',
+];
-export const textProviderIds = [101, 102];
-
-export const securityTrainingProviders = [
+const createSecurityTrainingProviders = ({ providerOverrides = {} }) => [
{
- id: textProviderIds[0],
- name: 'Vendor Name 1',
+ id: testProviderIds[0],
+ name: testProviderName[0],
description: 'Interactive developer security education',
url: 'https://www.example.org/security/training',
isEnabled: false,
isPrimary: false,
+ ...providerOverrides.first,
},
{
- id: textProviderIds[1],
- name: 'Vendor Name 2',
+ id: testProviderIds[1],
+ name: testProviderName[1],
description: 'Security training with guide and learning pathways.',
url: 'https://www.vendornametwo.com/',
- isEnabled: true,
+ isEnabled: false,
+ isPrimary: false,
+ ...providerOverrides.second,
+ },
+ {
+ id: testProviderIds[2],
+ name: testProviderName[2],
+ description: 'Security training for the everyday developer.',
+ url: 'https://www.vendornamethree.com/',
+ isEnabled: false,
isPrimary: false,
+ ...providerOverrides.third,
},
];
-export const securityTrainingProvidersResponse = {
- data: {
- project: {
- id: 1,
- securityTrainingProviders,
+export const getSecurityTrainingProvidersData = (providerOverrides = {}) => {
+ const securityTrainingProviders = createSecurityTrainingProviders(providerOverrides);
+ const response = {
+ data: {
+ project: {
+ id: 'gid://gitlab/Project/1',
+ __typename: 'Project',
+ securityTrainingProviders,
+ },
},
- },
+ };
+
+ return {
+ response,
+ data: securityTrainingProviders,
+ };
};
export const dismissUserCalloutResponse = {
@@ -76,3 +100,14 @@ export const updateSecurityTrainingProvidersErrorResponse = {
},
},
};
+
+// Will remove once this issue is resolved where the svg path will be available in the GraphQL query
+// https://gitlab.com/gitlab-org/gitlab/-/issues/346899
+export const tempProviderLogos = {
+ [testProviderName[0]]: {
+ svg: `<svg>${[testProviderName[0]]}</svg>`,
+ },
+ [testProviderName[1]]: {
+ svg: `<svg>${[testProviderName[1]]}</svg>`,
+ },
+};
diff --git a/spec/frontend/sidebar/components/assignees/sidebar_assignees_widget_spec.js b/spec/frontend/sidebar/components/assignees/sidebar_assignees_widget_spec.js
index def46255994..5fd364afbe4 100644
--- a/spec/frontend/sidebar/components/assignees/sidebar_assignees_widget_spec.js
+++ b/spec/frontend/sidebar/components/assignees/sidebar_assignees_widget_spec.js
@@ -1,4 +1,4 @@
-import { GlSearchBoxByType, GlDropdown } from '@gitlab/ui';
+import { GlSearchBoxByType } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
@@ -76,7 +76,16 @@ describe('Sidebar assignees widget', () => {
SidebarEditableItem,
UserSelect,
GlSearchBoxByType,
- GlDropdown,
+ GlDropdown: {
+ template: `
+ <div>
+ <slot name="footer"></slot>
+ </div>
+ `,
+ methods: {
+ show: jest.fn(),
+ },
+ },
},
});
};
@@ -340,21 +349,9 @@ describe('Sidebar assignees widget', () => {
});
});
- it('when realtime feature flag is disabled', async () => {
+ it('includes the real-time assignees component', async () => {
createComponent();
await waitForPromises();
- expect(findRealtimeAssignees().exists()).toBe(false);
- });
-
- it('when realtime feature flag is enabled', async () => {
- createComponent({
- provide: {
- glFeatures: {
- realTimeIssueSidebar: true,
- },
- },
- });
- await waitForPromises();
expect(findRealtimeAssignees().exists()).toBe(true);
});
diff --git a/spec/frontend/sidebar/components/assignees/sidebar_participant_spec.js b/spec/frontend/sidebar/components/assignees/sidebar_participant_spec.js
index 88a5f4ea8b7..71424aaead3 100644
--- a/spec/frontend/sidebar/components/assignees/sidebar_participant_spec.js
+++ b/spec/frontend/sidebar/components/assignees/sidebar_participant_spec.js
@@ -1,5 +1,6 @@
-import { GlAvatarLabeled } from '@gitlab/ui';
+import { GlAvatarLabeled, GlIcon } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
+import { IssuableType } from '~/issues/constants';
import SidebarParticipant from '~/sidebar/components/assignees/sidebar_participant.vue';
const user = {
@@ -13,14 +14,24 @@ describe('Sidebar participant component', () => {
let wrapper;
const findAvatar = () => wrapper.findComponent(GlAvatarLabeled);
+ const findIcon = () => wrapper.findComponent(GlIcon);
- const createComponent = (status = null) => {
+ const createComponent = ({
+ status = null,
+ issuableType = IssuableType.Issue,
+ canMerge = false,
+ } = {}) => {
wrapper = shallowMount(SidebarParticipant, {
propsData: {
user: {
...user,
+ canMerge,
status,
},
+ issuableType,
+ },
+ stubs: {
+ GlAvatarLabeled,
},
});
};
@@ -29,15 +40,35 @@ describe('Sidebar participant component', () => {
wrapper.destroy();
});
- it('when user is not busy', () => {
+ it('does not show `Busy` status when user is not busy', () => {
createComponent();
expect(findAvatar().props('label')).toBe(user.name);
});
- it('when user is busy', () => {
- createComponent({ availability: 'BUSY' });
+ it('shows `Busy` status when user is busy', () => {
+ createComponent({ status: { availability: 'BUSY' } });
expect(findAvatar().props('label')).toBe(`${user.name} (Busy)`);
});
+
+ it('does not render a warning icon', () => {
+ createComponent();
+
+ expect(findIcon().exists()).toBe(false);
+ });
+
+ describe('when on merge request sidebar', () => {
+ it('when project member cannot merge', () => {
+ createComponent({ issuableType: IssuableType.MergeRequest });
+
+ expect(findIcon().exists()).toBe(true);
+ });
+
+ it('when project member can merge', () => {
+ createComponent({ issuableType: IssuableType.MergeRequest, canMerge: true });
+
+ expect(findIcon().exists()).toBe(false);
+ });
+ });
});
diff --git a/spec/frontend/sidebar/components/attention_requested_toggle_spec.js b/spec/frontend/sidebar/components/attention_requested_toggle_spec.js
index 0939297a754..a9ae23c1624 100644
--- a/spec/frontend/sidebar/components/attention_requested_toggle_spec.js
+++ b/spec/frontend/sidebar/components/attention_requested_toggle_spec.js
@@ -16,7 +16,10 @@ describe('Attention require toggle', () => {
});
it('renders button', () => {
- factory({ type: 'reviewer', user: { attention_requested: false } });
+ factory({
+ type: 'reviewer',
+ user: { attention_requested: false, can_update_merge_request: true },
+ });
expect(findToggle().exists()).toBe(true);
});
@@ -28,7 +31,10 @@ describe('Attention require toggle', () => {
`(
'renders $icon icon when attention_requested is $attentionRequested',
({ attentionRequested, icon }) => {
- factory({ type: 'reviewer', user: { attention_requested: attentionRequested } });
+ factory({
+ type: 'reviewer',
+ user: { attention_requested: attentionRequested, can_update_merge_request: true },
+ });
expect(findToggle().props('icon')).toBe(icon);
},
@@ -41,27 +47,47 @@ describe('Attention require toggle', () => {
`(
'renders button with variant $variant when attention_requested is $attentionRequested',
({ attentionRequested, variant }) => {
- factory({ type: 'reviewer', user: { attention_requested: attentionRequested } });
+ factory({
+ type: 'reviewer',
+ user: { attention_requested: attentionRequested, can_update_merge_request: true },
+ });
expect(findToggle().props('variant')).toBe(variant);
},
);
it('emits toggle-attention-requested on click', async () => {
- factory({ type: 'reviewer', user: { attention_requested: true } });
+ factory({
+ type: 'reviewer',
+ user: { attention_requested: true, can_update_merge_request: true },
+ });
await findToggle().trigger('click');
expect(wrapper.emitted('toggle-attention-requested')[0]).toEqual([
{
- user: { attention_requested: true },
+ user: { attention_requested: true, can_update_merge_request: true },
callback: expect.anything(),
},
]);
});
+ it('does not emit toggle-attention-requested on click if can_update_merge_request is false', async () => {
+ factory({
+ type: 'reviewer',
+ user: { attention_requested: true, can_update_merge_request: false },
+ });
+
+ await findToggle().trigger('click');
+
+ expect(wrapper.emitted('toggle-attention-requested')).toBe(undefined);
+ });
+
it('sets loading on click', async () => {
- factory({ type: 'reviewer', user: { attention_requested: true } });
+ factory({
+ type: 'reviewer',
+ user: { attention_requested: true, can_update_merge_request: true },
+ });
await findToggle().trigger('click');
@@ -69,14 +95,24 @@ describe('Attention require toggle', () => {
});
it.each`
- type | attentionRequested | tooltip
- ${'reviewer'} | ${true} | ${AttentionRequestedToggle.i18n.removeAttentionRequested}
- ${'reviewer'} | ${false} | ${AttentionRequestedToggle.i18n.attentionRequestedReviewer}
- ${'assignee'} | ${false} | ${AttentionRequestedToggle.i18n.attentionRequestedAssignee}
+ type | attentionRequested | tooltip | canUpdateMergeRequest
+ ${'reviewer'} | ${true} | ${AttentionRequestedToggle.i18n.removeAttentionRequested} | ${true}
+ ${'reviewer'} | ${false} | ${AttentionRequestedToggle.i18n.attentionRequestedReviewer} | ${true}
+ ${'assignee'} | ${false} | ${AttentionRequestedToggle.i18n.attentionRequestedAssignee} | ${true}
+ ${'reviewer'} | ${true} | ${AttentionRequestedToggle.i18n.attentionRequestedNoPermission} | ${false}
+ ${'reviewer'} | ${false} | ${AttentionRequestedToggle.i18n.noAttentionRequestedNoPermission} | ${false}
+ ${'assignee'} | ${true} | ${AttentionRequestedToggle.i18n.attentionRequestedNoPermission} | ${false}
+ ${'assignee'} | ${false} | ${AttentionRequestedToggle.i18n.noAttentionRequestedNoPermission} | ${false}
`(
- 'sets tooltip as $tooltip when attention_requested is $attentionRequested and type is $type',
- ({ type, attentionRequested, tooltip }) => {
- factory({ type, user: { attention_requested: attentionRequested } });
+ 'sets tooltip as $tooltip when attention_requested is $attentionRequested, type is $type and, can_update_merge_request is $canUpdateMergeRequest',
+ ({ type, attentionRequested, tooltip, canUpdateMergeRequest }) => {
+ factory({
+ type,
+ user: {
+ attention_requested: attentionRequested,
+ can_update_merge_request: canUpdateMergeRequest,
+ },
+ });
expect(findToggle().attributes('aria-label')).toBe(tooltip);
},
diff --git a/spec/frontend/sidebar/components/incidents/escalation_status_spec.js b/spec/frontend/sidebar/components/incidents/escalation_status_spec.js
new file mode 100644
index 00000000000..7a736624fc0
--- /dev/null
+++ b/spec/frontend/sidebar/components/incidents/escalation_status_spec.js
@@ -0,0 +1,52 @@
+import { GlDropdown, GlDropdownItem } from '@gitlab/ui';
+import { mountExtended } from 'helpers/vue_test_utils_helper';
+import EscalationStatus from '~/sidebar/components/incidents/escalation_status.vue';
+import {
+ STATUS_LABELS,
+ STATUS_TRIGGERED,
+ STATUS_ACKNOWLEDGED,
+} from '~/sidebar/components/incidents/constants';
+
+describe('EscalationStatus', () => {
+ let wrapper;
+
+ function createComponent(props) {
+ wrapper = mountExtended(EscalationStatus, {
+ propsData: {
+ value: STATUS_TRIGGERED,
+ ...props,
+ },
+ });
+ }
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ const findDropdownComponent = () => wrapper.findComponent(GlDropdown);
+ const findDropdownItems = () => wrapper.findAllComponents(GlDropdownItem);
+
+ describe('status', () => {
+ it('shows the current status', () => {
+ createComponent({ value: STATUS_ACKNOWLEDGED });
+
+ expect(findDropdownComponent().props('text')).toBe(STATUS_LABELS[STATUS_ACKNOWLEDGED]);
+ });
+
+ it('shows the None option when status is null', () => {
+ createComponent({ value: null });
+
+ expect(findDropdownComponent().props('text')).toBe('None');
+ });
+ });
+
+ describe('events', () => {
+ it('selects an item', async () => {
+ createComponent();
+
+ await findDropdownItems().at(1).vm.$emit('click');
+
+ expect(wrapper.emitted().input[0][0]).toBe(STATUS_ACKNOWLEDGED);
+ });
+ });
+});
diff --git a/spec/frontend/sidebar/components/incidents/escalation_utils_spec.js b/spec/frontend/sidebar/components/incidents/escalation_utils_spec.js
new file mode 100644
index 00000000000..edd65db0325
--- /dev/null
+++ b/spec/frontend/sidebar/components/incidents/escalation_utils_spec.js
@@ -0,0 +1,18 @@
+import { STATUS_ACKNOWLEDGED } from '~/sidebar/components/incidents/constants';
+import { getStatusLabel } from '~/sidebar/components/incidents/utils';
+
+describe('EscalationUtils', () => {
+ describe('getStatusLabel', () => {
+ it('returns a label when provided with a valid status', () => {
+ const label = getStatusLabel(STATUS_ACKNOWLEDGED);
+
+ expect(label).toEqual('Acknowledged');
+ });
+
+ it("returns 'None' when status is null", () => {
+ const label = getStatusLabel(null);
+
+ expect(label).toEqual('None');
+ });
+ });
+});
diff --git a/spec/frontend/sidebar/components/incidents/mock_data.js b/spec/frontend/sidebar/components/incidents/mock_data.js
new file mode 100644
index 00000000000..bbb6c61b162
--- /dev/null
+++ b/spec/frontend/sidebar/components/incidents/mock_data.js
@@ -0,0 +1,39 @@
+import { STATUS_TRIGGERED, STATUS_ACKNOWLEDGED } from '~/sidebar/components/incidents/constants';
+
+export const fetchData = {
+ workspace: {
+ __typename: 'Project',
+ id: 'gid://gitlab/Project/2',
+ issuable: {
+ __typename: 'Issue',
+ id: 'gid://gitlab/Issue/4',
+ escalationStatus: STATUS_TRIGGERED,
+ },
+ },
+};
+
+export const mutationData = {
+ issueSetEscalationStatus: {
+ __typename: 'IssueSetEscalationStatusPayload',
+ errors: [],
+ clientMutationId: null,
+ issue: {
+ __typename: 'Issue',
+ id: 'gid://gitlab/Issue/4',
+ escalationStatus: STATUS_ACKNOWLEDGED,
+ },
+ },
+};
+
+export const fetchError = {
+ workspace: {
+ __typename: 'Project',
+ },
+};
+
+export const mutationError = {
+ issueSetEscalationStatus: {
+ __typename: 'IssueSetEscalationStatusPayload',
+ errors: ['hello'],
+ },
+};
diff --git a/spec/frontend/sidebar/components/incidents/sidebar_escalation_status_spec.js b/spec/frontend/sidebar/components/incidents/sidebar_escalation_status_spec.js
new file mode 100644
index 00000000000..a8dc610672c
--- /dev/null
+++ b/spec/frontend/sidebar/components/incidents/sidebar_escalation_status_spec.js
@@ -0,0 +1,207 @@
+import { createLocalVue } from '@vue/test-utils';
+import { nextTick } from 'vue';
+import VueApollo from 'vue-apollo';
+import createMockApollo from 'helpers/mock_apollo_helper';
+import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
+import { mountExtended } from 'helpers/vue_test_utils_helper';
+import SidebarEscalationStatus from '~/sidebar/components/incidents/sidebar_escalation_status.vue';
+import SidebarEditableItem from '~/sidebar/components/sidebar_editable_item.vue';
+import { escalationStatusQuery, escalationStatusMutation } from '~/sidebar/constants';
+import waitForPromises from 'helpers/wait_for_promises';
+import EscalationStatus from 'ee_else_ce/sidebar/components/incidents/escalation_status.vue';
+import { STATUS_ACKNOWLEDGED } from '~/sidebar/components/incidents/constants';
+import { createAlert } from '~/flash';
+import { logError } from '~/lib/logger';
+import { fetchData, fetchError, mutationData, mutationError } from './mock_data';
+
+jest.mock('~/lib/logger');
+jest.mock('~/flash');
+
+const localVue = createLocalVue();
+
+describe('SidebarEscalationStatus', () => {
+ let wrapper;
+ const queryResolverMock = jest.fn();
+ const mutationResolverMock = jest.fn();
+
+ function createMockApolloProvider({ hasFetchError = false, hasMutationError = false } = {}) {
+ localVue.use(VueApollo);
+
+ queryResolverMock.mockResolvedValue({ data: hasFetchError ? fetchError : fetchData });
+ mutationResolverMock.mockResolvedValue({
+ data: hasMutationError ? mutationError : mutationData,
+ });
+
+ const requestHandlers = [
+ [escalationStatusQuery, queryResolverMock],
+ [escalationStatusMutation, mutationResolverMock],
+ ];
+
+ return createMockApollo(requestHandlers);
+ }
+
+ function createComponent({ mockApollo } = {}) {
+ let config;
+
+ if (mockApollo) {
+ config = { apolloProvider: mockApollo };
+ } else {
+ config = { mocks: { $apollo: { queries: { status: { loading: false } } } } };
+ }
+
+ wrapper = mountExtended(SidebarEscalationStatus, {
+ propsData: {
+ iid: '1',
+ projectPath: 'gitlab-org/gitlab',
+ issuableType: 'issue',
+ },
+ provide: {
+ canUpdate: true,
+ },
+ directives: {
+ GlTooltip: createMockDirective(),
+ },
+ localVue,
+ ...config,
+ });
+ }
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ const findSidebarComponent = () => wrapper.findComponent(SidebarEditableItem);
+ const findStatusComponent = () => wrapper.findComponent(EscalationStatus);
+ const findEditButton = () => wrapper.findByTestId('edit-button');
+ const findIcon = () => wrapper.findByTestId('status-icon');
+
+ const clickEditButton = async () => {
+ findEditButton().vm.$emit('click');
+ await nextTick();
+ };
+ const selectAcknowledgedStatus = async () => {
+ findStatusComponent().vm.$emit('input', STATUS_ACKNOWLEDGED);
+ // wait for apollo requests
+ await waitForPromises();
+ };
+
+ describe('sidebar', () => {
+ it('renders the sidebar component', () => {
+ createComponent();
+ expect(findSidebarComponent().exists()).toBe(true);
+ });
+
+ describe('status icon', () => {
+ it('is visible', () => {
+ createComponent();
+
+ expect(findIcon().exists()).toBe(true);
+ expect(findIcon().isVisible()).toBe(true);
+ });
+
+ it('has correct tooltip', async () => {
+ const mockApollo = createMockApolloProvider();
+ createComponent({ mockApollo });
+
+ // wait for apollo requests
+ await waitForPromises();
+
+ const tooltip = getBinding(findIcon().element, 'gl-tooltip');
+
+ expect(tooltip).toBeDefined();
+ expect(tooltip.value).toBe('Status: Triggered');
+ });
+ });
+
+ describe('status dropdown', () => {
+ beforeEach(async () => {
+ const mockApollo = createMockApolloProvider();
+ createComponent({ mockApollo });
+
+ // wait for apollo requests
+ await waitForPromises();
+ });
+
+ it('is closed by default', () => {
+ expect(findStatusComponent().exists()).toBe(true);
+ expect(findStatusComponent().isVisible()).toBe(false);
+ });
+
+ it('is shown after clicking the edit button', async () => {
+ await clickEditButton();
+
+ expect(findStatusComponent().isVisible()).toBe(true);
+ });
+
+ it('is hidden after clicking the edit button, when open already', async () => {
+ await clickEditButton();
+ await clickEditButton();
+
+ expect(findStatusComponent().isVisible()).toBe(false);
+ });
+ });
+
+ describe('update Status event', () => {
+ beforeEach(async () => {
+ const mockApollo = createMockApolloProvider();
+ createComponent({ mockApollo });
+
+ // wait for apollo requests
+ await waitForPromises();
+
+ await clickEditButton();
+ await selectAcknowledgedStatus();
+ });
+
+ it('calls the mutation', () => {
+ const mutationVariables = {
+ iid: '1',
+ projectPath: 'gitlab-org/gitlab',
+ status: STATUS_ACKNOWLEDGED,
+ };
+
+ expect(mutationResolverMock).toHaveBeenCalledWith(mutationVariables);
+ });
+
+ it('closes the dropdown', () => {
+ expect(findStatusComponent().isVisible()).toBe(false);
+ });
+
+ it('updates the status', () => {
+ // Sometimes status has a intermediate wrapping component. A quirk of vue-test-utils
+ // means that in that case 'value' is exposed as a prop. If no wrapping component
+ // exists it is exposed as an attribute.
+ const statusValue =
+ findStatusComponent().props('value') || findStatusComponent().attributes('value');
+ expect(statusValue).toBe(STATUS_ACKNOWLEDGED);
+ });
+ });
+
+ describe('mutation errors', () => {
+ it('should error upon fetch', async () => {
+ const mockApollo = createMockApolloProvider({ hasFetchError: true });
+ createComponent({ mockApollo });
+
+ // wait for apollo requests
+ await waitForPromises();
+
+ expect(createAlert).toHaveBeenCalled();
+ expect(logError).toHaveBeenCalled();
+ });
+
+ it('should error upon mutation', async () => {
+ const mockApollo = createMockApolloProvider({ hasMutationError: true });
+ createComponent({ mockApollo });
+
+ // wait for apollo requests
+ await waitForPromises();
+
+ await clickEditButton();
+ await selectAcknowledgedStatus();
+
+ expect(createAlert).toHaveBeenCalled();
+ expect(logError).toHaveBeenCalled();
+ });
+ });
+ });
+});
diff --git a/spec/frontend/sidebar/mock_data.js b/spec/frontend/sidebar/mock_data.js
index 30972484a08..fbca00636b6 100644
--- a/spec/frontend/sidebar/mock_data.js
+++ b/spec/frontend/sidebar/mock_data.js
@@ -428,7 +428,7 @@ const mockUser1 = {
export const mockUser2 = {
__typename: 'UserCore',
- id: 'gid://gitlab/User/4',
+ id: 'gid://gitlab/User/5',
avatarUrl: '/avatar2',
name: 'rookie',
username: 'rookie',
@@ -457,6 +457,33 @@ export const searchResponse = {
},
};
+export const searchResponseOnMR = {
+ data: {
+ workspace: {
+ __typename: 'Project',
+ id: '1',
+ users: {
+ nodes: [
+ {
+ id: 'gid://gitlab/User/1',
+ user: mockUser1,
+ mergeRequestInteraction: {
+ canMerge: true,
+ },
+ },
+ {
+ id: 'gid://gitlab/User/4',
+ user: mockUser2,
+ mergeRequestInteraction: {
+ canMerge: false,
+ },
+ },
+ ],
+ },
+ },
+ },
+};
+
export const projectMembersResponse = {
data: {
workspace: {
diff --git a/spec/frontend/sidebar/sidebar_assignees_spec.js b/spec/frontend/sidebar/sidebar_assignees_spec.js
index 5f77e21c1f8..68d20060c37 100644
--- a/spec/frontend/sidebar/sidebar_assignees_spec.js
+++ b/spec/frontend/sidebar/sidebar_assignees_spec.js
@@ -14,7 +14,7 @@ describe('sidebar assignees', () => {
let wrapper;
let mediator;
let axiosMock;
- const createComponent = (realTimeIssueSidebar = false, props) => {
+ const createComponent = (props) => {
wrapper = shallowMount(SidebarAssignees, {
propsData: {
issuableIid: '1',
@@ -25,11 +25,6 @@ describe('sidebar assignees', () => {
changing: false,
...props,
},
- provide: {
- glFeatures: {
- realTimeIssueSidebar,
- },
- },
// Attaching to document is required because this component emits something from the parent element :/
attachTo: document.body,
});
@@ -86,27 +81,17 @@ describe('sidebar assignees', () => {
expect(wrapper.find(Assigness).exists()).toBe(true);
});
- describe('when realTimeIssueSidebar is turned on', () => {
- describe('when issuableType is issue', () => {
- it('finds AssigneesRealtime componeont', () => {
- createComponent(true);
-
- expect(wrapper.find(AssigneesRealtime).exists()).toBe(true);
- });
- });
-
- describe('when issuableType is MR', () => {
- it('does not find AssigneesRealtime componeont', () => {
- createComponent(true, { issuableType: 'MR' });
+ describe('when issuableType is issue', () => {
+ it('finds AssigneesRealtime component', () => {
+ createComponent();
- expect(wrapper.find(AssigneesRealtime).exists()).toBe(false);
- });
+ expect(wrapper.find(AssigneesRealtime).exists()).toBe(true);
});
});
- describe('when realTimeIssueSidebar is turned off', () => {
- it('does not find AssigneesRealtime', () => {
- createComponent(false, { issuableType: 'issue' });
+ describe('when issuableType is MR', () => {
+ it('does not find AssigneesRealtime component', () => {
+ createComponent({ issuableType: 'MR' });
expect(wrapper.find(AssigneesRealtime).exists()).toBe(false);
});
diff --git a/spec/frontend/sidebar/sidebar_mediator_spec.js b/spec/frontend/sidebar/sidebar_mediator_spec.js
index 3d7baaff10a..c472a98bf0b 100644
--- a/spec/frontend/sidebar/sidebar_mediator_spec.js
+++ b/spec/frontend/sidebar/sidebar_mediator_spec.js
@@ -5,9 +5,11 @@ import SidebarService, { gqClient } from '~/sidebar/services/sidebar_service';
import SidebarMediator from '~/sidebar/sidebar_mediator';
import SidebarStore from '~/sidebar/stores/sidebar_store';
import toast from '~/vue_shared/plugins/global_toast';
+import { refreshUserMergeRequestCounts } from '~/commons/nav/user_merge_requests';
import Mock from './mock_data';
jest.mock('~/vue_shared/plugins/global_toast');
+jest.mock('~/commons/nav/user_merge_requests');
describe('Sidebar mediator', () => {
const { mediator: mediatorMockData } = Mock;
@@ -137,6 +139,7 @@ describe('Sidebar mediator', () => {
});
expect(attentionRequiredService).toHaveBeenCalledWith(1);
+ expect(refreshUserMergeRequestCounts).toHaveBeenCalled();
});
it.each`
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 e12255fe825..6fc358a6a15 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
@@ -14,6 +14,7 @@ exports[`Snippet Blob Edit component with loaded blob matches snapshot 1`] = `
/>
<source-editor-stub
+ debouncevalue="250"
editoroptions="[object Object]"
fileglobalid="blob_local_7"
filename="foo/bar/test.md"
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 c193bb08543..2b26c306c68 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
@@ -29,6 +29,7 @@ exports[`Snippet Description Edit component rendering matches the snapshot 1`] =
>
<markdown-header-stub
data-testid="markdownHeader"
+ enablepreview="true"
linecontent=""
suggestionstartindex="0"
/>
diff --git a/spec/frontend/terraform/components/empty_state_spec.js b/spec/frontend/terraform/components/empty_state_spec.js
index 1637ac2039c..b1303cf2b5e 100644
--- a/spec/frontend/terraform/components/empty_state_spec.js
+++ b/spec/frontend/terraform/components/empty_state_spec.js
@@ -8,7 +8,7 @@ describe('EmptyStateComponent', () => {
const propsData = {
image: '/image/path',
};
- const docsUrl = '/help/user/infrastructure/terraform_state';
+ const docsUrl = '/help/user/infrastructure/iac/terraform_state';
const findEmptyState = () => wrapper.findComponent(GlEmptyState);
const findLink = () => wrapper.findComponent(GlLink);
diff --git a/spec/frontend/test_setup.js b/spec/frontend/test_setup.js
index 4fe51db8412..6c336152e9a 100644
--- a/spec/frontend/test_setup.js
+++ b/spec/frontend/test_setup.js
@@ -8,6 +8,7 @@ initializeTestTimeout(process.env.CI ? 6000 : 500);
afterEach(() =>
// give Promises a bit more time so they fail the right test
+ // eslint-disable-next-line no-restricted-syntax
new Promise(setImmediate).then(() => {
// wait for pending setTimeout()s
jest.runOnlyPendingTimers();
diff --git a/spec/frontend/toggle_buttons_spec.js b/spec/frontend/toggle_buttons_spec.js
deleted file mode 100644
index 435fd35744f..00000000000
--- a/spec/frontend/toggle_buttons_spec.js
+++ /dev/null
@@ -1,115 +0,0 @@
-import $ from 'jquery';
-import waitForPromises from 'helpers/wait_for_promises';
-import setupToggleButtons from '~/toggle_buttons';
-
-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/toggles/index_spec.js b/spec/frontend/toggles/index_spec.js
index 575b1b6080c..19c4d6f1f1d 100644
--- a/spec/frontend/toggles/index_spec.js
+++ b/spec/frontend/toggles/index_spec.js
@@ -99,10 +99,12 @@ describe('toggles/index.js', () => {
const name = 'toggle-name';
const help = 'Help text';
const foo = 'bar';
+ const id = 'an-id';
beforeEach(() => {
initToggleWithOptions({
name,
+ id,
isChecked: true,
disabled: true,
isLoading: true,
@@ -144,6 +146,10 @@ describe('toggles/index.js', () => {
it('passes custom dataset to the wrapper', () => {
expect(toggleWrapper.dataset.foo).toBe('bar');
});
+
+ it('passes an id to the wrapper', () => {
+ expect(toggleWrapper.id).toBe(id);
+ });
});
});
});
diff --git a/spec/frontend/tracking/tracking_spec.js b/spec/frontend/tracking/tracking_spec.js
index b7a2e4f4f51..d85299cdfc3 100644
--- a/spec/frontend/tracking/tracking_spec.js
+++ b/spec/frontend/tracking/tracking_spec.js
@@ -255,6 +255,23 @@ describe('Tracking', () => {
expect(snowplowSpy).toHaveBeenCalledWith('setCustomUrl', TEST_HOST);
});
+ describe('allowed hashes/fragments', () => {
+ it.each`
+ hash | appends | description
+ ${'note_abc_123'} | ${true} | ${'appends'}
+ ${'diff-content-819'} | ${true} | ${'appends'}
+ ${'first_heading'} | ${false} | ${'does not append'}
+ `('$description `$hash` hash', ({ hash, appends }) => {
+ window.gl.snowplowPseudonymizedPageUrl = TEST_HOST;
+ window.location.hash = hash;
+
+ Tracking.setAnonymousUrls();
+
+ const url = appends ? `${TEST_HOST}#${hash}` : TEST_HOST;
+ expect(snowplowSpy).toHaveBeenCalledWith('setCustomUrl', url);
+ });
+ });
+
it('does not set the referrer URL by default', () => {
window.gl.snowplowPseudonymizedPageUrl = TEST_HOST;
@@ -361,6 +378,16 @@ describe('Tracking', () => {
expect(eventSpy).toHaveBeenCalledWith(TEST_CATEGORY, 'click_input2', {
value: '0',
});
+
+ expect(snowplowSpy).toHaveBeenCalledWith(
+ 'trackStructEvent',
+ TEST_CATEGORY,
+ 'click_input2',
+ undefined,
+ undefined,
+ 0,
+ [standardContext],
+ );
});
it('handles checkbox values correctly', () => {
diff --git a/spec/frontend/users_select/index_spec.js b/spec/frontend/users_select/index_spec.js
index 0d2aae78944..3757e63c4f9 100644
--- a/spec/frontend/users_select/index_spec.js
+++ b/spec/frontend/users_select/index_spec.js
@@ -108,4 +108,39 @@ describe('~/users_select/index', () => {
});
});
});
+
+ describe('XSS', () => {
+ const escaped = '&gt;&lt;script&gt;alert(1)&lt;/script&gt;';
+ const issuableType = 'merge_request';
+ const user = {
+ availability: 'not_set',
+ can_merge: true,
+ name: 'name',
+ };
+ const selected = true;
+ const username = 'username';
+ const img = '<img user-avatar />';
+ const elsClassName = 'elsclass';
+
+ it.each`
+ prop | val | element
+ ${'username'} | ${'><script>alert(1)</script>'} | ${'.dropdown-menu-user-username'}
+ ${'name'} | ${'><script>alert(1)</script>'} | ${'.dropdown-menu-user-full-name'}
+ `('properly escapes the $prop $val', ({ prop, val, element }) => {
+ const u = prop === 'username' ? val : username;
+ const n = prop === 'name' ? val : user.name;
+ const row = UsersSelect.prototype.renderRow(
+ issuableType,
+ { ...user, name: n },
+ selected,
+ u,
+ img,
+ elsClassName,
+ );
+ const fragment = document.createRange().createContextualFragment(row);
+ const output = fragment.querySelector(element).innerHTML.trim();
+
+ expect(output).toBe(escaped);
+ });
+ });
});
diff --git a/spec/frontend/vue_mr_widget/components/extensions/child_content_spec.js b/spec/frontend/vue_mr_widget/components/extensions/child_content_spec.js
new file mode 100644
index 00000000000..198a4c2823a
--- /dev/null
+++ b/spec/frontend/vue_mr_widget/components/extensions/child_content_spec.js
@@ -0,0 +1,40 @@
+import { shallowMount } from '@vue/test-utils';
+import ChildContent from '~/vue_merge_request_widget/components/extensions/child_content.vue';
+
+let wrapper;
+const mockData = () => ({
+ header: 'Test header',
+ text: 'Test content',
+ icon: {
+ name: 'error',
+ },
+});
+
+function factory(propsData) {
+ wrapper = shallowMount(ChildContent, {
+ propsData: {
+ ...propsData,
+ widgetLabel: 'Test',
+ },
+ });
+}
+
+describe('MR widget extension child content', () => {
+ afterEach(() => {
+ wrapper.destroy();
+ wrapper = null;
+ });
+
+ it('renders child components', () => {
+ factory({
+ data: {
+ ...mockData(),
+ children: [mockData()],
+ },
+ level: 2,
+ });
+
+ expect(wrapper.find('[data-testid="child-content"]').exists()).toBe(true);
+ expect(wrapper.find('[data-testid="child-content"]').props('level')).toBe(3);
+ });
+});
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
index 27604868b3e..6386746aee4 100644
--- a/spec/frontend/vue_mr_widget/components/mr_widget_rebase_spec.js
+++ b/spec/frontend/vue_mr_widget/components/mr_widget_rebase_spec.js
@@ -2,11 +2,6 @@ import { shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue';
import WidgetRebase from '~/vue_merge_request_widget/components/states/mr_widget_rebase.vue';
import eventHub from '~/vue_merge_request_widget/event_hub';
-import ActionsButton from '~/vue_shared/components/actions_button.vue';
-import {
- REBASE_BUTTON_KEY,
- REBASE_WITHOUT_CI_BUTTON_KEY,
-} from '~/vue_merge_request_widget/constants';
let wrapper;
@@ -38,8 +33,8 @@ function createWrapper(propsData, mergeRequestWidgetGraphql, rebaseWithoutCiUi)
describe('Merge request widget rebase component', () => {
const findRebaseMessage = () => wrapper.find('[data-testid="rebase-message"]');
const findRebaseMessageText = () => findRebaseMessage().text();
- const findRebaseButtonActions = () => wrapper.find(ActionsButton);
const findStandardRebaseButton = () => wrapper.find('[data-testid="standard-rebase-button"]');
+ const findRebaseWithoutCiButton = () => wrapper.find('[data-testid="rebase-without-ci-button"]');
afterEach(() => {
wrapper.destroy();
@@ -112,7 +107,7 @@ describe('Merge request widget rebase component', () => {
expect(findRebaseMessageText()).toContain('Something went wrong!');
});
- describe('Rebase button with flag rebaseWithoutCiUi', () => {
+ describe('Rebase buttons with flag rebaseWithoutCiUi', () => {
beforeEach(() => {
createWrapper(
{
@@ -130,30 +125,13 @@ describe('Merge request widget rebase component', () => {
);
});
- it('rebase button with actions is rendered', () => {
- expect(findRebaseButtonActions().exists()).toBe(true);
- expect(findStandardRebaseButton().exists()).toBe(false);
- });
-
- it('has rebase and rebase without CI actions', () => {
- const actionNames = findRebaseButtonActions()
- .props('actions')
- .map((action) => action.key);
-
- expect(actionNames).toStrictEqual([REBASE_BUTTON_KEY, REBASE_WITHOUT_CI_BUTTON_KEY]);
- });
-
- it('defaults to rebase action', () => {
- expect(findRebaseButtonActions().props('selectedKey')).toStrictEqual(REBASE_BUTTON_KEY);
+ it('renders both buttons', () => {
+ expect(findRebaseWithoutCiButton().exists()).toBe(true);
+ expect(findStandardRebaseButton().exists()).toBe(true);
});
it('starts the rebase when clicking', async () => {
- // ActionButtons use the actions props instead of emitting
- // a click event, therefore simulating the behavior here:
- findRebaseButtonActions()
- .props('actions')
- .find((x) => x.key === REBASE_BUTTON_KEY)
- .handle();
+ findStandardRebaseButton().vm.$emit('click');
await nextTick();
@@ -161,12 +139,7 @@ describe('Merge request widget rebase component', () => {
});
it('starts the CI-skipping rebase when clicking on "Rebase without CI"', async () => {
- // ActionButtons use the actions props instead of emitting
- // a click event, therefore simulating the behavior here:
- findRebaseButtonActions()
- .props('actions')
- .find((x) => x.key === REBASE_WITHOUT_CI_BUTTON_KEY)
- .handle();
+ findRebaseWithoutCiButton().vm.$emit('click');
await nextTick();
@@ -193,7 +166,7 @@ describe('Merge request widget rebase component', () => {
it('standard rebase button is rendered', () => {
expect(findStandardRebaseButton().exists()).toBe(true);
- expect(findRebaseButtonActions().exists()).toBe(false);
+ expect(findRebaseWithoutCiButton().exists()).toBe(false);
});
it('calls rebase method with skip_ci false', () => {
@@ -240,7 +213,7 @@ describe('Merge request widget rebase component', () => {
});
});
- it('does not render the rebase actions button with rebaseWithoutCiUI flag enabled', () => {
+ it('does not render the "Rebase without pipeline" button with rebaseWithoutCiUI flag enabled', () => {
createWrapper(
{
mr: {
@@ -254,7 +227,7 @@ describe('Merge request widget rebase component', () => {
{ rebaseWithoutCiUi: true },
);
- expect(findRebaseButtonActions().exists()).toBe(false);
+ expect(findRebaseWithoutCiButton().exists()).toBe(false);
});
it('does not render the standard rebase button with rebaseWithoutCiUI flag disabled', () => {
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
index 6ea8ca10c02..15522f7ac1d 100644
--- 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
@@ -1,3 +1,4 @@
+import { GlLink } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import RelatedLinks from '~/vue_merge_request_widget/components/mr_widget_related_links.vue';
@@ -85,13 +86,29 @@ describe('MRWidgetRelatedLinks', () => {
expect(content).toContain('Mentions issues #23 and #42');
});
- it('should have assing issues link', () => {
- createComponent({
- relatedLinks: {
- assignToMe: '<a href="#">Assign yourself to these issues</a>',
- },
+ describe('should have correct assign issues link', () => {
+ it.each([
+ [1, 'Assign yourself to this issue'],
+ [2, 'Assign yourself to these issues'],
+ ])('when issue count is %s, link displays correct text', (unassignedCount, text) => {
+ const assignToMe = '/assign';
+
+ createComponent({
+ relatedLinks: { assignToMe, unassignedCount },
+ });
+
+ const glLinkWrapper = wrapper.findComponent(GlLink);
+
+ expect(glLinkWrapper.attributes('href')).toBe(assignToMe);
+ expect(glLinkWrapper.text()).toBe(text);
});
- expect(wrapper.text().trim()).toContain('Assign yourself to these issues');
+ it('when no link is present', () => {
+ createComponent({
+ relatedLinks: { assignToMe: '#', unassignedCount: 0 },
+ });
+
+ expect(wrapper.findComponent(GlLink).exists()).toBe(false);
+ });
});
});
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
index 9dcde3e4f33..7a92484695c 100644
--- 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
@@ -19,7 +19,7 @@ describe('MRWidgetConflicts', () => {
const userCannotMergeText =
'Users who can write to the source or target branches can resolve the conflicts.';
const resolveConflictsBtnText = 'Resolve conflicts';
- const mergeLocallyBtnText = 'Merge locally';
+ const mergeLocallyBtnText = 'Resolve locally';
async function createComponent(propsData = {}) {
wrapper = extendedWrapper(
@@ -224,8 +224,8 @@ describe('MRWidgetConflicts', () => {
});
});
- it('should not allow you to resolve the conflicts', () => {
- expect(findResolveButton().exists()).toBe(false);
+ it('should allow you to resolve the conflicts', () => {
+ expect(findResolveButton().exists()).toBe(true);
});
});
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
index 78585ed75bc..0e364eb6800 100644
--- 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
@@ -1,7 +1,12 @@
-import { shallowMount } from '@vue/test-utils';
+import { createLocalVue, shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue';
import { GlSprintf } from '@gitlab/ui';
+import VueApollo from 'vue-apollo';
+import produce from 'immer';
+import readyToMergeResponse from 'test_fixtures/graphql/merge_requests/states/ready_to_merge.query.graphql.json';
import waitForPromises from 'helpers/wait_for_promises';
+import createMockApollo from 'helpers/mock_apollo_helper';
+import readyToMergeQuery from 'ee_else_ce/vue_merge_request_widget/queries/states/ready_to_merge.query.graphql';
import simplePoll from '~/lib/utils/simple_poll';
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';
@@ -19,9 +24,11 @@ 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 commitMessage = readyToMergeResponse.data.project.mergeRequest.defaultMergeCommitMessage;
+const squashCommitMessage =
+ readyToMergeResponse.data.project.mergeRequest.defaultSquashCommitMessage;
+const commitMessageWithDescription =
+ readyToMergeResponse.data.project.mergeRequest.defaultMergeCommitMessageWithDescription;
const createTestMr = (customConfig) => {
const mr = {
isPipelineActive: false,
@@ -42,6 +49,8 @@ const createTestMr = (customConfig) => {
commitMessage,
squashCommitMessage,
commitMessageWithDescription,
+ defaultMergeCommitMessage: commitMessage,
+ defaultSquashCommitMessage: squashCommitMessage,
shouldRemoveSourceBranch: true,
canRemoveSourceBranch: false,
targetBranch: 'main',
@@ -61,15 +70,25 @@ const createTestService = () => ({
merge: jest.fn(),
poll: jest.fn().mockResolvedValue(),
});
+const localVue = createLocalVue();
+localVue.use(VueApollo);
let wrapper;
+let readyToMergeResponseSpy;
const findMergeButton = () => wrapper.find('[data-testid="merge-button"]');
const findPipelineFailedConfirmModal = () =>
wrapper.findComponent(MergeFailedPipelineConfirmationDialog);
+const createReadyToMergeResponse = (customMr) => {
+ return produce(readyToMergeResponse, (draft) => {
+ Object.assign(draft.data.project.mergeRequest, customMr);
+ });
+};
+
const createComponent = (customConfig = {}, mergeRequestWidgetGraphql = false) => {
wrapper = shallowMount(ReadyToMerge, {
+ localVue,
propsData: {
mr: createTestMr(customConfig),
service: createTestService(),
@@ -82,10 +101,29 @@ const createComponent = (customConfig = {}, mergeRequestWidgetGraphql = false) =
stubs: {
CommitEdit,
},
+ apolloProvider: createMockApollo([[readyToMergeQuery, readyToMergeResponseSpy]]),
});
};
+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');
+const findTipLink = () => wrapper.find(GlSprintf);
+const findCommitEditWithInputId = (inputId) =>
+ findCommitEditElements().wrappers.find((x) => x.props('inputId') === inputId);
+const findMergeCommitMessage = () => findCommitEditWithInputId('merge-message-edit').props('value');
+const findSquashCommitMessage = () =>
+ findCommitEditWithInputId('squash-message-edit').props('value');
+
+const triggerApprovalUpdated = () => eventHub.$emit('ApprovalUpdated');
+
describe('ReadyToMerge', () => {
+ beforeEach(() => {
+ readyToMergeResponseSpy = jest.fn().mockResolvedValueOnce(readyToMergeResponse);
+ });
+
afterEach(() => {
wrapper.destroy();
});
@@ -447,13 +485,6 @@ describe('ReadyToMerge', () => {
});
describe('render children components', () => {
- 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');
- const findTipLink = () => wrapper.find(GlSprintf);
-
describe('squash checkbox', () => {
it('should be rendered when squash before merge is enabled and there is more than 1 commit', () => {
createComponent({
@@ -772,4 +803,65 @@ describe('ReadyToMerge', () => {
expect(findPipelineFailedConfirmModal().props()).toEqual({ visible: true });
});
});
+
+ describe('updating graphql data triggers commit message update when default changed', () => {
+ const UPDATED_MERGE_COMMIT_MESSAGE = 'New merge message from BE';
+ const UPDATED_SQUASH_COMMIT_MESSAGE = 'New squash message from BE';
+ const USER_COMMIT_MESSAGE = 'Merge message provided manually by user';
+
+ const createDefaultGqlComponent = () =>
+ createComponent({ mr: { commitsCount: 2, enableSquashBeforeMerge: true } }, true);
+
+ beforeEach(() => {
+ readyToMergeResponseSpy = jest
+ .fn()
+ .mockResolvedValueOnce(createReadyToMergeResponse({ squash: true, squashOnMerge: true }))
+ .mockResolvedValue(
+ createReadyToMergeResponse({
+ squash: true,
+ squashOnMerge: true,
+ defaultMergeCommitMessage: UPDATED_MERGE_COMMIT_MESSAGE,
+ defaultSquashCommitMessage: UPDATED_SQUASH_COMMIT_MESSAGE,
+ }),
+ );
+ });
+
+ describe.each`
+ desc | finderFn | initialValue | updatedValue | inputId
+ ${'merge commit message'} | ${findMergeCommitMessage} | ${commitMessage} | ${UPDATED_MERGE_COMMIT_MESSAGE} | ${'#merge-message-edit'}
+ ${'squash commit message'} | ${findSquashCommitMessage} | ${squashCommitMessage} | ${UPDATED_SQUASH_COMMIT_MESSAGE} | ${'#squash-message-edit'}
+ `('with $desc', ({ finderFn, initialValue, updatedValue, inputId }) => {
+ it('should have initial value', async () => {
+ createDefaultGqlComponent();
+
+ await waitForPromises();
+
+ expect(finderFn()).toBe(initialValue);
+ });
+
+ it('should have updated value after graphql refetch', async () => {
+ createDefaultGqlComponent();
+ await waitForPromises();
+
+ triggerApprovalUpdated();
+ await waitForPromises();
+
+ expect(finderFn()).toBe(updatedValue);
+ });
+
+ it('should not update if user has touched', async () => {
+ createDefaultGqlComponent();
+ await waitForPromises();
+
+ const input = wrapper.find(inputId);
+ input.element.value = USER_COMMIT_MESSAGE;
+ input.trigger('input');
+
+ triggerApprovalUpdated();
+ await waitForPromises();
+
+ expect(finderFn()).toBe(USER_COMMIT_MESSAGE);
+ });
+ });
+ });
});
diff --git a/spec/frontend/vue_mr_widget/extentions/accessibility/index_spec.js b/spec/frontend/vue_mr_widget/extentions/accessibility/index_spec.js
index a9fe29a484a..ea422a57956 100644
--- a/spec/frontend/vue_mr_widget/extentions/accessibility/index_spec.js
+++ b/spec/frontend/vue_mr_widget/extentions/accessibility/index_spec.js
@@ -100,15 +100,15 @@ describe('Accessibility extension', () => {
await waitForPromises();
});
- it('displays all report list items', async () => {
- expect(findAllExtensionListItems()).toHaveLength(10);
+ it('displays all report list items in viewport', async () => {
+ expect(findAllExtensionListItems()).toHaveLength(7);
});
it('displays report list item formatted', () => {
const text = {
newError: trimText(findAllExtensionListItems().at(0).text()),
resolvedError: findAllExtensionListItems().at(3).text(),
- existingError: trimText(findAllExtensionListItems().at(8).text()),
+ existingError: trimText(findAllExtensionListItems().at(6).text()),
};
expect(text.newError).toBe(
@@ -118,7 +118,7 @@ describe('Accessibility extension', () => {
'The accessibility scanning found an error of the following type: WCAG2AA.Principle1.Guideline1_1.1_1_1.H30.2 Learn more Message: Img element is the only content of the link, but is missing alt text. The alt text should describe the purpose of the link.',
);
expect(text.existingError).toBe(
- 'The accessibility scanning found an error of the following type: WCAG2AA.Principle2.Guideline2_4.2_4_1.H64.1 Learn more Message: Iframe element requires a non-empty title attribute that identifies the frame.',
+ 'The accessibility scanning found an error of the following type: WCAG2AA.Principle1.Guideline1_1.1_1_1.H37 Learn more Message: Img element missing an alt attribute. Use the alt attribute to specify a short text alternative.',
);
});
});
diff --git a/spec/frontend/vue_mr_widget/extentions/code_quality/index_spec.js b/spec/frontend/vue_mr_widget/extentions/code_quality/index_spec.js
new file mode 100644
index 00000000000..9a72e4a086b
--- /dev/null
+++ b/spec/frontend/vue_mr_widget/extentions/code_quality/index_spec.js
@@ -0,0 +1,145 @@
+import MockAdapter from 'axios-mock-adapter';
+import { mountExtended } from 'helpers/vue_test_utils_helper';
+import { trimText } from 'helpers/text_helper';
+import waitForPromises from 'helpers/wait_for_promises';
+import axios from '~/lib/utils/axios_utils';
+import extensionsContainer from '~/vue_merge_request_widget/components/extensions/container';
+import { registerExtension } from '~/vue_merge_request_widget/components/extensions';
+import codeQualityExtension from '~/vue_merge_request_widget/extensions/code_quality';
+import httpStatusCodes from '~/lib/utils/http_status';
+import {
+ codeQualityResponseNewErrors,
+ codeQualityResponseResolvedErrors,
+ codeQualityResponseResolvedAndNewErrors,
+ codeQualityResponseNoErrors,
+} from './mock_data';
+
+describe('Code Quality extension', () => {
+ let wrapper;
+ let mock;
+
+ registerExtension(codeQualityExtension);
+
+ const endpoint = '/root/repo/-/merge_requests/4/accessibility_reports.json';
+
+ const mockApi = (statusCode, data) => {
+ mock.onGet(endpoint).reply(statusCode, data);
+ };
+
+ const findToggleCollapsedButton = () => wrapper.findByTestId('toggle-button');
+ const findAllExtensionListItems = () => wrapper.findAllByTestId('extension-list-item');
+
+ const createComponent = () => {
+ wrapper = mountExtended(extensionsContainer, {
+ propsData: {
+ mr: {
+ codeQuality: endpoint,
+ blobPath: {
+ head_path: 'example/path',
+ base_path: 'example/path',
+ },
+ },
+ },
+ });
+ };
+
+ beforeEach(() => {
+ mock = new MockAdapter(axios);
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ mock.restore();
+ });
+
+ describe('summary', () => {
+ it('displays loading text', () => {
+ mockApi(httpStatusCodes.OK, codeQualityResponseNewErrors);
+
+ createComponent();
+
+ expect(wrapper.text()).toBe('Code Quality test metrics results are being parsed');
+ });
+
+ it('displays failed loading text', async () => {
+ mockApi(httpStatusCodes.INTERNAL_SERVER_ERROR);
+
+ createComponent();
+
+ await waitForPromises();
+ expect(wrapper.text()).toBe('Code Quality failed loading results');
+ });
+
+ it('displays quality degradation', async () => {
+ mockApi(httpStatusCodes.OK, codeQualityResponseNewErrors);
+
+ createComponent();
+
+ await waitForPromises();
+
+ expect(wrapper.text()).toBe('Code Quality degraded on 2 points.');
+ });
+
+ it('displays quality improvement', async () => {
+ mockApi(httpStatusCodes.OK, codeQualityResponseResolvedErrors);
+
+ createComponent();
+
+ await waitForPromises();
+
+ expect(wrapper.text()).toBe('Code Quality improved on 2 points.');
+ });
+
+ it('displays quality improvement and degradation', async () => {
+ mockApi(httpStatusCodes.OK, codeQualityResponseResolvedAndNewErrors);
+
+ createComponent();
+
+ await waitForPromises();
+
+ expect(wrapper.text()).toBe('Code Quality improved on 1 point and degraded on 1 point.');
+ });
+
+ it('displays no detected errors', async () => {
+ mockApi(httpStatusCodes.OK, codeQualityResponseNoErrors);
+
+ createComponent();
+
+ await waitForPromises();
+
+ expect(wrapper.text()).toBe('No changes to Code Quality.');
+ });
+ });
+
+ describe('expanded data', () => {
+ beforeEach(async () => {
+ mockApi(httpStatusCodes.OK, codeQualityResponseResolvedAndNewErrors);
+
+ createComponent();
+
+ await waitForPromises();
+
+ findToggleCollapsedButton().trigger('click');
+
+ await waitForPromises();
+ });
+
+ it('displays all report list items in viewport', async () => {
+ expect(findAllExtensionListItems()).toHaveLength(2);
+ });
+
+ it('displays report list item formatted', () => {
+ const text = {
+ newError: trimText(findAllExtensionListItems().at(0).text().replace(/\s+/g, ' ').trim()),
+ resolvedError: findAllExtensionListItems().at(1).text().replace(/\s+/g, ' ').trim(),
+ };
+
+ expect(text.newError).toContain(
+ "Minor - Parsing error: 'return' outside of function in index.js:12",
+ );
+ expect(text.resolvedError).toContain(
+ "Minor - Parsing error: 'return' outside of function in index.js:12",
+ );
+ });
+ });
+});
diff --git a/spec/frontend/vue_mr_widget/extentions/code_quality/mock_data.js b/spec/frontend/vue_mr_widget/extentions/code_quality/mock_data.js
new file mode 100644
index 00000000000..f5ad0ce7377
--- /dev/null
+++ b/spec/frontend/vue_mr_widget/extentions/code_quality/mock_data.js
@@ -0,0 +1,87 @@
+export const codeQualityResponseNewErrors = {
+ status: 'failed',
+ new_errors: [
+ {
+ description: "Parsing error: 'return' outside of function",
+ severity: 'minor',
+ file_path: 'index.js',
+ line: 12,
+ },
+ {
+ description: 'TODO found',
+ severity: 'minor',
+ file_path: '.gitlab-ci.yml',
+ line: 73,
+ },
+ ],
+ resolved_errors: [],
+ existing_errors: [],
+ summary: {
+ total: 2,
+ resolved: 0,
+ errored: 2,
+ },
+};
+
+export const codeQualityResponseResolvedErrors = {
+ status: 'failed',
+ new_errors: [],
+ resolved_errors: [
+ {
+ description: "Parsing error: 'return' outside of function",
+ severity: 'minor',
+ file_path: 'index.js',
+ line: 12,
+ },
+ {
+ description: 'TODO found',
+ severity: 'minor',
+ file_path: '.gitlab-ci.yml',
+ line: 73,
+ },
+ ],
+ existing_errors: [],
+ summary: {
+ total: 2,
+ resolved: 2,
+ errored: 0,
+ },
+};
+
+export const codeQualityResponseResolvedAndNewErrors = {
+ status: 'failed',
+ new_errors: [
+ {
+ description: "Parsing error: 'return' outside of function",
+ severity: 'minor',
+ file_path: 'index.js',
+ line: 12,
+ },
+ ],
+ resolved_errors: [
+ {
+ description: "Parsing error: 'return' outside of function",
+ severity: 'minor',
+ file_path: 'index.js',
+ line: 12,
+ },
+ ],
+ existing_errors: [],
+ summary: {
+ total: 2,
+ resolved: 1,
+ errored: 1,
+ },
+};
+
+export const codeQualityResponseNoErrors = {
+ status: 'failed',
+ new_errors: [],
+ resolved_errors: [],
+ existing_errors: [],
+ summary: {
+ total: 0,
+ resolved: 0,
+ errored: 0,
+ },
+};
diff --git a/spec/frontend/vue_mr_widget/mr_widget_how_to_merge_modal_spec.js b/spec/frontend/vue_mr_widget/mr_widget_how_to_merge_modal_spec.js
index 913d5860b48..295b9df30b9 100644
--- a/spec/frontend/vue_mr_widget/mr_widget_how_to_merge_modal_spec.js
+++ b/spec/frontend/vue_mr_widget/mr_widget_how_to_merge_modal_spec.js
@@ -1,4 +1,4 @@
-import { GlModal, GlSprintf } from '@gitlab/ui';
+import { GlModal } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import MrWidgetHowToMergeModal from '~/vue_merge_request_widget/components/mr_widget_how_to_merge_modal.vue';
@@ -27,7 +27,7 @@ describe('MRWidgetHowToMerge', () => {
const findModal = () => wrapper.find(GlModal);
const findInstructionsFields = () =>
wrapper.findAll('[ data-testid="how-to-merge-instructions"]');
- const findTipLink = () => wrapper.find(GlSprintf);
+ const findTipLink = () => wrapper.find("[data-testid='docs-tip']");
it('renders a modal', () => {
expect(findModal().exists()).toBe(true);
diff --git a/spec/frontend/vue_mr_widget/mr_widget_options_spec.js b/spec/frontend/vue_mr_widget/mr_widget_options_spec.js
index 56c9bae0b76..0540107ea5f 100644
--- a/spec/frontend/vue_mr_widget/mr_widget_options_spec.js
+++ b/spec/frontend/vue_mr_widget/mr_widget_options_spec.js
@@ -947,6 +947,8 @@ describe('MrWidgetOptions', () => {
wrapper.find('[data-testid="widget-extension-top-level"]').find(GlDropdown).exists(),
).toBe(false);
+ await nextTick();
+
const collapsedSection = wrapper.find('[data-testid="widget-extension-collapsed-section"]');
expect(collapsedSection.exists()).toBe(true);
expect(collapsedSection.text()).toContain('Hello world');
diff --git a/spec/frontend/vue_shared/components/__snapshots__/content_transition_spec.js.snap b/spec/frontend/vue_shared/components/__snapshots__/content_transition_spec.js.snap
new file mode 100644
index 00000000000..fd804990b5e
--- /dev/null
+++ b/spec/frontend/vue_shared/components/__snapshots__/content_transition_spec.js.snap
@@ -0,0 +1,41 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`~/vue_shared/components/content_transition.vue default shows all transitions and only default is visible 1`] = `
+<div>
+ <transition-stub
+ name="test_transition_name"
+ >
+ <div
+ data-testval="default"
+ >
+ <p>
+ Default
+ </p>
+ </div>
+ </transition-stub>
+ <transition-stub
+ name="test_transition_name"
+ >
+ <div
+ data-testval="foo"
+ style="display: none;"
+ >
+ <p>
+ Foo
+ </p>
+ </div>
+ </transition-stub>
+ <transition-stub
+ name="test_transition_name"
+ >
+ <div
+ data-testval="bar"
+ style="display: none;"
+ >
+ <p>
+ Bar
+ </p>
+ </div>
+ </transition-stub>
+</div>
+`;
diff --git a/spec/frontend/vue_shared/components/color_picker/color_picker_spec.js b/spec/frontend/vue_shared/components/color_picker/color_picker_spec.js
index fef50bdaccc..28b3bf5287a 100644
--- a/spec/frontend/vue_shared/components/color_picker/color_picker_spec.js
+++ b/spec/frontend/vue_shared/components/color_picker/color_picker_spec.js
@@ -127,5 +127,18 @@ describe('ColorPicker', () => {
expect(wrapper.emitted().input[0]).toStrictEqual([setColor]);
});
+
+ it('shows the suggested colors passed using props', () => {
+ const customColors = {
+ '#ff0000': 'Red',
+ '#808080': 'Gray',
+ };
+
+ createComponent(shallowMount, { suggestedColors: customColors });
+ expect(description()).toBe('Enter any color or choose one of the suggested colors below.');
+ expect(presetColors()).toHaveLength(2);
+ expect(presetColors().at(0).attributes('title')).toBe('Red');
+ expect(presetColors().at(1).attributes('title')).toBe('Gray');
+ });
});
});
diff --git a/spec/frontend/vue_shared/components/content_transition_spec.js b/spec/frontend/vue_shared/components/content_transition_spec.js
new file mode 100644
index 00000000000..8bb6d31cce7
--- /dev/null
+++ b/spec/frontend/vue_shared/components/content_transition_spec.js
@@ -0,0 +1,109 @@
+import { groupBy, mapValues } from 'lodash';
+import { shallowMount } from '@vue/test-utils';
+import ContentTransition from '~/vue_shared/components/content_transition.vue';
+
+const TEST_CURRENT_SLOT = 'default';
+const TEST_TRANSITION_NAME = 'test_transition_name';
+const TEST_SLOTS = [
+ { key: 'default', attributes: { 'data-testval': 'default' } },
+ { key: 'foo', attributes: { 'data-testval': 'foo' } },
+ { key: 'bar', attributes: { 'data-testval': 'bar' } },
+];
+
+describe('~/vue_shared/components/content_transition.vue', () => {
+ let wrapper;
+
+ afterEach(() => {
+ wrapper.destroy();
+ wrapper = null;
+ });
+
+ const createComponent = (props = {}, slots = {}) => {
+ wrapper = shallowMount(ContentTransition, {
+ propsData: {
+ transitionName: TEST_TRANSITION_NAME,
+ currentSlot: TEST_CURRENT_SLOT,
+ slots: TEST_SLOTS,
+ ...props,
+ },
+ slots: {
+ default: '<p>Default</p>',
+ foo: '<p>Foo</p>',
+ bar: '<p>Bar</p>',
+ dne: '<p>DOES NOT EXIST</p>',
+ ...slots,
+ },
+ });
+ };
+
+ const findTransitionsData = () =>
+ wrapper.findAll('transition-stub').wrappers.map((transition) => {
+ const child = transition.find('[data-testval]');
+ const { style, ...attributes } = child.attributes();
+
+ return {
+ transitionName: transition.attributes('name'),
+ isVisible: child.isVisible(),
+ attributes,
+ text: transition.text(),
+ };
+ });
+ const findVisibleData = () => {
+ const group = groupBy(findTransitionsData(), (x) => x.attributes['data-testval']);
+
+ return mapValues(group, (x) => x[0].isVisible);
+ };
+
+ describe('default', () => {
+ beforeEach(() => {
+ createComponent();
+ });
+
+ it('shows all transitions and only default is visible', () => {
+ expect(wrapper.element).toMatchSnapshot();
+ });
+
+ it('render transitions for each slot', () => {
+ expect(findTransitionsData()).toEqual([
+ {
+ attributes: {
+ 'data-testval': 'default',
+ },
+ isVisible: true,
+ text: 'Default',
+ transitionName: 'test_transition_name',
+ },
+ {
+ attributes: {
+ 'data-testval': 'foo',
+ },
+ isVisible: false,
+ text: 'Foo',
+ transitionName: 'test_transition_name',
+ },
+ {
+ attributes: {
+ 'data-testval': 'bar',
+ },
+ isVisible: false,
+ text: 'Bar',
+ transitionName: 'test_transition_name',
+ },
+ ]);
+ });
+ });
+
+ describe('with currentSlot=foo', () => {
+ beforeEach(() => {
+ createComponent({ currentSlot: 'foo' });
+ });
+
+ it('should only show the foo slot', () => {
+ expect(findVisibleData()).toEqual({
+ default: false,
+ foo: true,
+ bar: false,
+ });
+ });
+ });
+});
diff --git a/spec/frontend/vue_shared/components/filtered_search_bar/tokens/base_token_spec.js b/spec/frontend/vue_shared/components/filtered_search_bar/tokens/base_token_spec.js
index dd9bf2ff598..af8a2a496ea 100644
--- a/spec/frontend/vue_shared/components/filtered_search_bar/tokens/base_token_spec.js
+++ b/spec/frontend/vue_shared/components/filtered_search_bar/tokens/base_token_spec.js
@@ -1,12 +1,24 @@
-import { GlFilteredSearchToken, GlLoadingIcon } from '@gitlab/ui';
+import {
+ GlFilteredSearchToken,
+ GlLoadingIcon,
+ GlFilteredSearchSuggestion,
+ GlDropdownSectionHeader,
+ GlDropdownDivider,
+ GlDropdownText,
+} from '@gitlab/ui';
import { mount } from '@vue/test-utils';
import { nextTick } from 'vue';
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import {
mockRegularLabel,
mockLabels,
} from 'jest/vue_shared/components/sidebar/labels_select_vue/mock_data';
-import { DEFAULT_NONE_ANY } from '~/vue_shared/components/filtered_search_bar/constants';
+import {
+ DEFAULT_NONE_ANY,
+ OPERATOR_IS,
+ OPERATOR_IS_NOT,
+} from '~/vue_shared/components/filtered_search_bar/constants';
import {
getRecentlyUsedSuggestions,
setTokenValueToRecentlyUsed,
@@ -32,6 +44,7 @@ const defaultStubs = {
<div>
<slot name="view-token"></slot>
<slot name="view"></slot>
+ <slot name="suggestions"></slot>
</div>
`,
},
@@ -43,6 +56,7 @@ const defaultStubs = {
},
};
+const mockSuggestionListTestId = 'suggestion-list';
const defaultSlots = {
'view-token': `
<div class="js-view-token">${mockRegularLabel.title}</div>
@@ -52,6 +66,10 @@ const defaultSlots = {
`,
};
+const defaultScopedSlots = {
+ 'suggestions-list': `<div data-testid="${mockSuggestionListTestId}" :data-suggestions="JSON.stringify(props.suggestions)"></div>`,
+};
+
const mockProps = {
config: { ...mockLabelToken, recentSuggestionsStorageKey: mockStorageKey },
value: { data: '' },
@@ -62,8 +80,15 @@ const mockProps = {
getActiveTokenValue: (labels, data) => labels.find((label) => label.title === data),
};
-function createComponent({ props = {}, stubs = defaultStubs, slots = defaultSlots } = {}) {
- return mount(BaseToken, {
+function createComponent({
+ props = {},
+ data = {},
+ stubs = defaultStubs,
+ slots = defaultSlots,
+ scopedSlots = defaultScopedSlots,
+ mountFn = mount,
+} = {}) {
+ return mountFn(BaseToken, {
propsData: {
...mockProps,
...props,
@@ -72,9 +97,17 @@ function createComponent({ props = {}, stubs = defaultStubs, slots = defaultSlot
portalName: 'fake target',
alignSuggestions: jest.fn(),
suggestionsListClass: () => 'custom-class',
+ filteredSearchSuggestionListInstance: {
+ register: jest.fn(),
+ unregister: jest.fn(),
+ },
+ },
+ data() {
+ return data;
},
stubs,
slots,
+ scopedSlots,
});
}
@@ -82,6 +115,9 @@ describe('BaseToken', () => {
let wrapper;
const findGlFilteredSearchToken = () => wrapper.findComponent(GlFilteredSearchToken);
+ const findMockSuggestionList = () => wrapper.findByTestId(mockSuggestionListTestId);
+ const getMockSuggestionListSuggestions = () =>
+ JSON.parse(findMockSuggestionList().attributes('data-suggestions'));
afterEach(() => {
wrapper.destroy();
@@ -136,6 +172,187 @@ describe('BaseToken', () => {
});
});
+ describe('suggestions', () => {
+ describe('with suggestions disabled', () => {
+ beforeEach(() => {
+ wrapper = createComponent({
+ props: {
+ config: {
+ suggestionsDisabled: true,
+ },
+ suggestions: [{ id: 'Foo' }],
+ },
+ mountFn: shallowMountExtended,
+ });
+ });
+
+ it('does not render suggestions', () => {
+ expect(findMockSuggestionList().exists()).toBe(false);
+ });
+ });
+
+ describe('with available suggestions', () => {
+ let mockSuggestions;
+
+ describe.each`
+ hasSuggestions | searchKey | shouldRenderSuggestions
+ ${true} | ${null} | ${true}
+ ${true} | ${'foo'} | ${true}
+ ${false} | ${null} | ${false}
+ `(
+ `when hasSuggestions is $hasSuggestions`,
+ ({ hasSuggestions, searchKey, shouldRenderSuggestions }) => {
+ beforeEach(async () => {
+ mockSuggestions = hasSuggestions ? [{ id: 'Foo' }] : [];
+ const props = { defaultSuggestions: [], suggestions: mockSuggestions };
+
+ getRecentlyUsedSuggestions.mockReturnValue([]);
+ wrapper = createComponent({ props, mountFn: shallowMountExtended, stubs: {} });
+ findGlFilteredSearchToken().vm.$emit('input', { data: searchKey });
+
+ await nextTick();
+ });
+
+ it(`${shouldRenderSuggestions ? 'should' : 'should not'} render suggestions`, () => {
+ expect(findMockSuggestionList().exists()).toBe(shouldRenderSuggestions);
+
+ if (shouldRenderSuggestions) {
+ expect(getMockSuggestionListSuggestions()).toEqual(mockSuggestions);
+ }
+ });
+ },
+ );
+ });
+
+ describe('with preloaded suggestions', () => {
+ const mockPreloadedSuggestions = [{ id: 'Foo' }, { id: 'Bar' }];
+
+ describe.each`
+ searchKey | shouldRenderPreloadedSuggestions
+ ${null} | ${true}
+ ${'foo'} | ${false}
+ `('when searchKey is $searchKey', ({ shouldRenderPreloadedSuggestions, searchKey }) => {
+ beforeEach(async () => {
+ const props = { preloadedSuggestions: mockPreloadedSuggestions };
+ wrapper = createComponent({ props, mountFn: shallowMountExtended, stubs: {} });
+ findGlFilteredSearchToken().vm.$emit('input', { data: searchKey });
+
+ await nextTick();
+ });
+
+ it(`${
+ shouldRenderPreloadedSuggestions ? 'should' : 'should not'
+ } render preloaded suggestions`, () => {
+ expect(findMockSuggestionList().exists()).toBe(shouldRenderPreloadedSuggestions);
+
+ if (shouldRenderPreloadedSuggestions) {
+ expect(getMockSuggestionListSuggestions()).toEqual(mockPreloadedSuggestions);
+ }
+ });
+ });
+ });
+
+ describe('with recent suggestions', () => {
+ let mockSuggestions;
+
+ describe.each`
+ searchKey | recentEnabled | shouldRenderRecentSuggestions
+ ${null} | ${true} | ${true}
+ ${'foo'} | ${true} | ${false}
+ ${null} | ${false} | ${false}
+ `(
+ 'when searchKey is $searchKey and recentEnabled is $recentEnabled',
+ ({ shouldRenderRecentSuggestions, recentEnabled, searchKey }) => {
+ beforeEach(async () => {
+ const props = { value: { data: '', operator: '=' }, defaultSuggestions: [] };
+
+ if (recentEnabled) {
+ mockSuggestions = [{ id: 'Foo' }, { id: 'Bar' }];
+ getRecentlyUsedSuggestions.mockReturnValue(mockSuggestions);
+ }
+
+ props.config = { recentSuggestionsStorageKey: recentEnabled ? mockStorageKey : null };
+
+ wrapper = createComponent({ props, mountFn: shallowMountExtended, stubs: {} });
+ findGlFilteredSearchToken().vm.$emit('input', { data: searchKey });
+
+ await nextTick();
+ });
+
+ it(`${
+ shouldRenderRecentSuggestions ? 'should' : 'should not'
+ } render recent suggestions`, () => {
+ expect(findMockSuggestionList().exists()).toBe(shouldRenderRecentSuggestions);
+ expect(wrapper.findComponent(GlDropdownSectionHeader).exists()).toBe(
+ shouldRenderRecentSuggestions,
+ );
+ expect(wrapper.findComponent(GlDropdownDivider).exists()).toBe(
+ shouldRenderRecentSuggestions,
+ );
+
+ if (shouldRenderRecentSuggestions) {
+ expect(getMockSuggestionListSuggestions()).toEqual(mockSuggestions);
+ }
+ });
+ },
+ );
+ });
+
+ describe('with default suggestions', () => {
+ describe.each`
+ operator | shouldRenderFilteredSearchSuggestion
+ ${OPERATOR_IS} | ${true}
+ ${OPERATOR_IS_NOT} | ${false}
+ `('when operator is $operator', ({ shouldRenderFilteredSearchSuggestion, operator }) => {
+ beforeEach(() => {
+ const props = {
+ defaultSuggestions: DEFAULT_NONE_ANY,
+ value: { data: '', operator },
+ };
+
+ wrapper = createComponent({ props, mountFn: shallowMountExtended });
+ });
+
+ it(`${
+ shouldRenderFilteredSearchSuggestion ? 'should' : 'should not'
+ } render GlFilteredSearchSuggestion`, () => {
+ const filteredSearchSuggestions = wrapper.findAllComponents(GlFilteredSearchSuggestion)
+ .wrappers;
+
+ if (shouldRenderFilteredSearchSuggestion) {
+ expect(filteredSearchSuggestions.map((c) => c.props())).toMatchObject(
+ DEFAULT_NONE_ANY.map((opt) => ({ value: opt.value })),
+ );
+ } else {
+ expect(filteredSearchSuggestions).toHaveLength(0);
+ }
+ });
+ });
+ });
+
+ describe('with no suggestions', () => {
+ it.each`
+ data | expected
+ ${{ searchKey: 'search' }} | ${'No matches found'}
+ ${{ hasFetched: true }} | ${'No suggestions found'}
+ `('shows $expected text', ({ data, expected }) => {
+ wrapper = createComponent({
+ props: {
+ config: { recentSuggestionsStorageKey: null },
+ defaultSuggestions: [],
+ preloadedSuggestions: [],
+ suggestions: [],
+ suggestionsLoading: false,
+ },
+ data,
+ mountFn: shallowMountExtended,
+ });
+
+ expect(wrapper.findComponent(GlDropdownText).text()).toBe(expected);
+ });
+ });
+ });
+
describe('methods', () => {
describe('handleTokenValueSelected', () => {
const mockTokenValue = mockLabels[0];
diff --git a/spec/frontend/vue_shared/components/markdown/field_spec.js b/spec/frontend/vue_shared/components/markdown/field_spec.js
index c7ad47b6ef7..b5daa389fc6 100644
--- a/spec/frontend/vue_shared/components/markdown/field_spec.js
+++ b/spec/frontend/vue_shared/components/markdown/field_spec.js
@@ -4,6 +4,7 @@ import $ from 'jquery';
import { TEST_HOST, FIXTURES_PATH } from 'spec/test_constants';
import axios from '~/lib/utils/axios_utils';
import MarkdownField from '~/vue_shared/components/markdown/field.vue';
+import MarkdownFieldHeader from '~/vue_shared/components/markdown/header.vue';
import { mountExtended } from 'helpers/vue_test_utils_helper';
const markdownPreviewPath = `${TEST_HOST}/preview`;
@@ -32,7 +33,7 @@ describe('Markdown field component', () => {
axiosMock.restore();
});
- function createSubject(lines = []) {
+ function createSubject({ lines = [], enablePreview = true } = {}) {
// We actually mount a wrapper component so that we can force Vue to rerender classes in order to test a regression
// caused by mixing Vanilla JS and Vue.
subject = mountExtended(
@@ -61,6 +62,7 @@ describe('Markdown field component', () => {
isSubmitting: false,
textareaValue,
lines,
+ enablePreview,
},
provide: {
glFeatures: {
@@ -74,7 +76,7 @@ describe('Markdown field component', () => {
const getPreviewLink = () => subject.findByTestId('preview-tab');
const getWriteLink = () => subject.findByTestId('write-tab');
const getMarkdownButton = () => subject.find('.js-md');
- const getAllMarkdownButtons = () => subject.findAll('.js-md');
+ const getListBulletedButton = () => subject.findAll('.js-md[title="Add a bullet list"]');
const getVideo = () => subject.find('video');
const getAttachButton = () => subject.find('.button-attach-file');
const clickAttachButton = () => getAttachButton().trigger('click');
@@ -183,7 +185,7 @@ describe('Markdown field component', () => {
it('converts a line', async () => {
const textarea = subject.find('textarea').element;
textarea.setSelectionRange(0, 0);
- const markdownButton = getAllMarkdownButtons().wrappers[5];
+ const markdownButton = getListBulletedButton();
markdownButton.trigger('click');
await nextTick();
@@ -193,7 +195,7 @@ describe('Markdown field component', () => {
it('converts multiple lines', async () => {
const textarea = subject.find('textarea').element;
textarea.setSelectionRange(0, 50);
- const markdownButton = getAllMarkdownButtons().wrappers[5];
+ const markdownButton = getListBulletedButton();
markdownButton.trigger('click');
await nextTick();
@@ -266,17 +268,46 @@ describe('Markdown field component', () => {
'You are about to add 11 people to the discussion. They will all receive a notification.',
);
});
+
+ it('removes warning when all mention is removed while endpoint is loading', async () => {
+ axiosMock.onPost(markdownPreviewPath).reply(200, { references: { users } });
+ jest.spyOn(axios, 'post');
+
+ subject.setProps({ textareaValue: 'hello @all' });
+
+ await nextTick();
+
+ subject.setProps({ textareaValue: 'hello @allan' });
+
+ await axios.waitFor(markdownPreviewPath);
+
+ expect(axios.post).toHaveBeenCalled();
+ expect(subject.text()).not.toContain(
+ 'You are about to add 11 people to the discussion. They will all receive a notification.',
+ );
+ });
});
});
});
describe('suggestions', () => {
it('escapes new line characters', () => {
- createSubject([{ rich_text: 'hello world\\n' }]);
+ createSubject({ lines: [{ rich_text: 'hello world\\n' }] });
expect(subject.find('[data-testid="markdownHeader"]').props('lineContent')).toBe(
'hello world%br',
);
});
});
+
+ it('allows enabling and disabling Markdown Preview', () => {
+ createSubject({ enablePreview: false });
+
+ expect(subject.findComponent(MarkdownFieldHeader).props('enablePreview')).toBe(false);
+
+ subject.destroy();
+ createSubject({ enablePreview: true });
+
+ expect(subject.findComponent(MarkdownFieldHeader).props('enablePreview')).toBe(true);
+ });
});
diff --git a/spec/frontend/vue_shared/components/markdown/header_spec.js b/spec/frontend/vue_shared/components/markdown/header_spec.js
index 700ec75fcee..9ffb9c6a541 100644
--- a/spec/frontend/vue_shared/components/markdown/header_spec.js
+++ b/spec/frontend/vue_shared/components/markdown/header_spec.js
@@ -46,6 +46,7 @@ describe('Markdown field header component', () => {
const buttons = [
'Add bold text (⌘B)',
'Add italic text (⌘I)',
+ 'Add strikethrough text (⌘⇧X)',
'Insert a quote',
'Insert suggestion',
'Insert code',
@@ -157,4 +158,12 @@ describe('Markdown field header component', () => {
expect(wrapper.find('.js-suggestion-btn').exists()).toBe(false);
});
+
+ it('hides preview tab when previewMarkdown property is false', () => {
+ createWrapper({
+ enablePreview: false,
+ });
+
+ expect(wrapper.findByTestId('preview-tab').exists()).toBe(false);
+ });
});
diff --git a/spec/frontend/vue_shared/components/notes/__snapshots__/noteable_warning_spec.js.snap b/spec/frontend/vue_shared/components/notes/__snapshots__/noteable_warning_spec.js.snap
index 573bc9abe4d..f878d685b6d 100644
--- a/spec/frontend/vue_shared/components/notes/__snapshots__/noteable_warning_spec.js.snap
+++ b/spec/frontend/vue_shared/components/notes/__snapshots__/noteable_warning_spec.js.snap
@@ -34,21 +34,19 @@ exports[`Issue Warning Component when noteable is locked and confidential render
<span>
<span>
This issue is
- <a
+ <gl-link-stub
href=""
- rel="noopener noreferrer"
target="_blank"
>
confidential
- </a>
+ </gl-link-stub>
and
- <a
+ <gl-link-stub
href=""
- rel="noopener noreferrer"
target="_blank"
>
locked
- </a>
+ </gl-link-stub>
.
</span>
diff --git a/spec/frontend/vue_shared/components/notes/noteable_warning_spec.js b/spec/frontend/vue_shared/components/notes/noteable_warning_spec.js
index accbf14572d..99b65ca6937 100644
--- a/spec/frontend/vue_shared/components/notes/noteable_warning_spec.js
+++ b/spec/frontend/vue_shared/components/notes/noteable_warning_spec.js
@@ -1,4 +1,4 @@
-import { GlIcon } from '@gitlab/ui';
+import { GlIcon, GlSprintf } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue';
import NoteableWarning from '~/vue_shared/components/notes/noteable_warning.vue';
@@ -16,6 +16,9 @@ describe('Issue Warning Component', () => {
propsData: {
...props,
},
+ stubs: {
+ GlSprintf,
+ },
});
afterEach(() => {
diff --git a/spec/frontend/vue_shared/components/paginated_table_with_search_and_tabs/paginated_table_with_search_and_tabs_spec.js b/spec/frontend/vue_shared/components/paginated_table_with_search_and_tabs/paginated_table_with_search_and_tabs_spec.js
index 36050a42da7..8270ff31574 100644
--- a/spec/frontend/vue_shared/components/paginated_table_with_search_and_tabs/paginated_table_with_search_and_tabs_spec.js
+++ b/spec/frontend/vue_shared/components/paginated_table_with_search_and_tabs/paginated_table_with_search_and_tabs_spec.js
@@ -221,7 +221,7 @@ describe('AlertManagementEmptyState', () => {
findPagination().vm.$emit('input', 3);
await nextTick();
- expect(findPagination().findAll('.page-item').at(0).text()).toBe('Prev');
+ expect(findPagination().findAll('.page-item').at(0).text()).toBe('Previous');
});
it('returns prevPage number', async () => {
diff --git a/spec/frontend/vue_shared/components/runner_aws_deployments/__snapshots__/runner_aws_deployments_modal_spec.js.snap b/spec/frontend/vue_shared/components/runner_aws_deployments/__snapshots__/runner_aws_deployments_modal_spec.js.snap
index b2906973dbd..6954bd5ccff 100644
--- a/spec/frontend/vue_shared/components/runner_aws_deployments/__snapshots__/runner_aws_deployments_modal_spec.js.snap
+++ b/spec/frontend/vue_shared/components/runner_aws_deployments/__snapshots__/runner_aws_deployments_modal_spec.js.snap
@@ -2,6 +2,7 @@
exports[`RunnerAwsDeploymentsModal renders the modal 1`] = `
<gl-modal-stub
+ actionprimary="[object Object]"
actionsecondary="[object Object]"
dismisslabel="Close"
modalclass=""
@@ -11,100 +12,161 @@ exports[`RunnerAwsDeploymentsModal renders the modal 1`] = `
titletag="h4"
>
<p>
- For each solution, you will choose a capacity. 1 enables warm HA through Auto Scaling group re-spawn. 2 enables hot HA because the service is available even when a node is lost. 3 or more enables hot HA and manual scaling of runner fleet.
+ Select your preferred option here. In the next step, you can choose the capacity for your runner in the AWS CloudFormation console.
</p>
- <ul
- class="gl-list-style-none gl-p-0 gl-mb-0"
+ <gl-form-radio-group-stub
+ checked="[object Object]"
+ disabledfield="disabled"
+ htmlfield="html"
+ label="Choose your preferred GitLab Runner"
+ label-sr-only=""
+ options=""
+ textfield="text"
+ valuefield="value"
>
- <li>
- <gl-link-stub
- class="gl-display-flex gl-font-weight-bold"
- href="https://us-west-2.console.aws.amazon.com/cloudformation/home?region=us-west-2#/stacks/create/review?templateURL=https%3A%2F%2Fgl-public-templates.s3.amazonaws.com%2Fcfn%2Fexperimental%2Feasybutton-amazon-linux-2-docker-manual-scaling-with-schedule-ondemandonly.cf.yml&stackName=linux-docker-nonspot&param_3GITLABRunnerInstanceURL=http%3A%2F%2Ftest.host"
- target="_blank"
+ <gl-form-radio-stub
+ class="gl-py-5 gl-pl-8 gl-border-b"
+ value="[object Object]"
+ >
+ <div
+ class="gl-mt-n1 gl-pl-4 gl-pb-2 gl-font-weight-bold"
>
- <img
- alt="linux-docker-nonspot"
- class="gl-mt-2 gl-mr-5 gl-mb-6"
- height="46"
- src="/assets/aws-cloud-formation.png"
- title="linux-docker-nonspot"
- width="46"
- />
- Amazon Linux 2 Docker HA with manual scaling and optional scheduling. Non-spot. Default choice for Linux Docker executor.
-
- </gl-link-stub>
- </li>
- <li>
- <gl-link-stub
- class="gl-display-flex gl-font-weight-bold"
- href="https://us-west-2.console.aws.amazon.com/cloudformation/home?region=us-west-2#/stacks/create/review?templateURL=https%3A%2F%2Fgl-public-templates.s3.amazonaws.com%2Fcfn%2Fexperimental%2Feasybutton-amazon-linux-2-docker-manual-scaling-with-schedule-spotonly.cf.yml&stackName=linux-docker-spotonly&param_3GITLABRunnerInstanceURL=http%3A%2F%2Ftest.host"
- target="_blank"
+ Amazon Linux 2 Docker HA with manual scaling and optional scheduling. Non-spot.
+
+ <gl-accordion-stub
+ class="gl-pt-3"
+ headerlevel="3"
+ >
+ <gl-accordion-item-stub
+ class="gl-font-weight-normal"
+ title="More Details"
+ title-visible="Less Details"
+ >
+ <p
+ class="gl-pt-2"
+ >
+ No spot. This is the default choice for Linux Docker executor.
+ </p>
+
+ <p
+ class="gl-m-0"
+ >
+ A capacity of 1 enables warm HA through Auto Scaling group re-spawn. A capacity of 2 enables hot HA because the service is available even when a node is lost. A capacity of 3 or more enables hot HA and manual scaling of runner fleet.
+ </p>
+ </gl-accordion-item-stub>
+ </gl-accordion-stub>
+ </div>
+ </gl-form-radio-stub>
+ <gl-form-radio-stub
+ class="gl-py-5 gl-pl-8 gl-border-b"
+ value="[object Object]"
+ >
+ <div
+ class="gl-mt-n1 gl-pl-4 gl-pb-2 gl-font-weight-bold"
>
- <img
- alt="linux-docker-spotonly"
- class="gl-mt-2 gl-mr-5 gl-mb-6"
- height="46"
- src="/assets/aws-cloud-formation.png"
- title="linux-docker-spotonly"
- width="46"
- />
Amazon Linux 2 Docker HA with manual scaling and optional scheduling. 100% spot.
-
- </gl-link-stub>
- </li>
- <li>
- <gl-link-stub
- class="gl-display-flex gl-font-weight-bold"
- href="https://us-west-2.console.aws.amazon.com/cloudformation/home?region=us-west-2#/stacks/create/review?templateURL=https%3A%2F%2Fgl-public-templates.s3.amazonaws.com%2Fcfn%2Fexperimental%2Feasybutton-windows2019-shell-manual-scaling-with-scheduling-ondemandonly.cf.yml&stackName=win2019-shell-non-spot&param_3GITLABRunnerInstanceURL=http%3A%2F%2Ftest.host"
- target="_blank"
+
+ <gl-accordion-stub
+ class="gl-pt-3"
+ headerlevel="3"
+ >
+ <gl-accordion-item-stub
+ class="gl-font-weight-normal"
+ title="More Details"
+ title-visible="Less Details"
+ >
+ <p
+ class="gl-pt-2"
+ >
+ 100% spot.
+ </p>
+
+ <p
+ class="gl-m-0"
+ >
+ Capacity of 1 enables warm HA through Auto Scaling group re-spawn. Capacity of 2 enables hot HA because the service is available even when a node is lost. Capacity of 3 or more enables hot HA and manual scaling of runner fleet.
+ </p>
+ </gl-accordion-item-stub>
+ </gl-accordion-stub>
+ </div>
+ </gl-form-radio-stub>
+ <gl-form-radio-stub
+ class="gl-py-5 gl-pl-8 gl-border-b"
+ value="[object Object]"
+ >
+ <div
+ class="gl-mt-n1 gl-pl-4 gl-pb-2 gl-font-weight-bold"
>
- <img
- alt="win2019-shell-non-spot"
- class="gl-mt-2 gl-mr-5 gl-mb-6"
- height="46"
- src="/assets/aws-cloud-formation.png"
- title="win2019-shell-non-spot"
- width="46"
- />
- Windows 2019 Shell with manual scaling and optional scheduling. Non-spot. Default choice for Windows Shell executor.
-
- </gl-link-stub>
- </li>
- <li>
- <gl-link-stub
- class="gl-display-flex gl-font-weight-bold"
- href="https://us-west-2.console.aws.amazon.com/cloudformation/home?region=us-west-2#/stacks/create/review?templateURL=https%3A%2F%2Fgl-public-templates.s3.amazonaws.com%2Fcfn%2Fexperimental%2Feasybutton-windows2019-shell-manual-scaling-with-scheduling-spotonly.cf.yml&stackName=win2019-shell-spot&param_3GITLABRunnerInstanceURL=http%3A%2F%2Ftest.host"
- target="_blank"
+ Windows 2019 Shell with manual scaling and optional scheduling. Non-spot.
+
+ <gl-accordion-stub
+ class="gl-pt-3"
+ headerlevel="3"
+ >
+ <gl-accordion-item-stub
+ class="gl-font-weight-normal"
+ title="More Details"
+ title-visible="Less Details"
+ >
+ <p
+ class="gl-pt-2"
+ >
+ No spot. Default choice for Windows Shell executor.
+ </p>
+
+ <p
+ class="gl-m-0"
+ >
+ Capacity of 1 enables warm HA through Auto Scaling group re-spawn. Capacity of 2 enables hot HA because the service is available even when a node is lost. Capacity of 3 or more enables hot HA and manual scaling of runner fleet.
+ </p>
+ </gl-accordion-item-stub>
+ </gl-accordion-stub>
+ </div>
+ </gl-form-radio-stub>
+ <gl-form-radio-stub
+ class="gl-py-5 gl-pl-8"
+ value="[object Object]"
+ >
+ <div
+ class="gl-mt-n1 gl-pl-4 gl-pb-2 gl-font-weight-bold"
>
- <img
- alt="win2019-shell-spot"
- class="gl-mt-2 gl-mr-5 gl-mb-6"
- height="46"
- src="/assets/aws-cloud-formation.png"
- title="win2019-shell-spot"
- width="46"
- />
Windows 2019 Shell with manual scaling and optional scheduling. 100% spot.
-
- </gl-link-stub>
- </li>
- </ul>
+
+ <gl-accordion-stub
+ class="gl-pt-3"
+ headerlevel="3"
+ >
+ <gl-accordion-item-stub
+ class="gl-font-weight-normal"
+ title="More Details"
+ title-visible="Less Details"
+ >
+ <p
+ class="gl-pt-2"
+ >
+ 100% spot.
+ </p>
+
+ <p
+ class="gl-m-0"
+ >
+ Capacity of 1 enables warm HA through Auto Scaling group re-spawn. Capacity of 2 enables hot HA because the service is available even when a node is lost. Capacity of 3 or more enables hot HA and manual scaling of runner fleet.
+ </p>
+ </gl-accordion-item-stub>
+ </gl-accordion-stub>
+ </div>
+ </gl-form-radio-stub>
+ </gl-form-radio-group-stub>
<p>
<gl-sprintf-stub
- message="Don't see what you are looking for? See the full list of options, including a fully customizable option, %{linkStart}here%{linkEnd}."
+ message="Don't see what you are looking for? See the full list of options, including a fully customizable option %{linkStart}here%{linkEnd}."
/>
</p>
-
- <p
- class="gl-font-sm gl-mb-0"
- >
- If you do not select an AWS VPC, the runner will deploy to the Default VPC in the AWS Region you select. Please consult with your AWS administrator to understand if there are any security risks to deploying into the Default VPC in any given region in your AWS account.
- </p>
</gl-modal-stub>
`;
diff --git a/spec/frontend/vue_shared/components/runner_aws_deployments/runner_aws_deployments_modal_spec.js b/spec/frontend/vue_shared/components/runner_aws_deployments/runner_aws_deployments_modal_spec.js
index ad692a38e65..a9ba4946358 100644
--- a/spec/frontend/vue_shared/components/runner_aws_deployments/runner_aws_deployments_modal_spec.js
+++ b/spec/frontend/vue_shared/components/runner_aws_deployments/runner_aws_deployments_modal_spec.js
@@ -1,27 +1,29 @@
-import { GlLink } from '@gitlab/ui';
+import { GlModal, GlFormRadio } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
-import ExperimentTracking from '~/experimentation/experiment_tracking';
-import { getBaseURL } from '~/lib/utils/url_utility';
+import { getBaseURL, visitUrl } from '~/lib/utils/url_utility';
+import { mockTracking } from 'helpers/tracking_helper';
import {
- EXPERIMENT_NAME,
CF_BASE_URL,
TEMPLATES_BASE_URL,
EASY_BUTTONS,
} from '~/vue_shared/components/runner_aws_deployments/constants';
import RunnerAwsDeploymentsModal from '~/vue_shared/components/runner_aws_deployments/runner_aws_deployments_modal.vue';
-jest.mock('~/experimentation/experiment_tracking');
+jest.mock('~/lib/utils/url_utility', () => ({
+ ...jest.requireActual('~/lib/utils/url_utility'),
+ visitUrl: jest.fn(),
+}));
describe('RunnerAwsDeploymentsModal', () => {
let wrapper;
- const findEasyButtons = () => wrapper.findAllComponents(GlLink);
+ const findModal = () => wrapper.findComponent(GlModal);
+ const findEasyButtons = () => wrapper.findAllComponents(GlFormRadio);
const createComponent = () => {
wrapper = shallowMount(RunnerAwsDeploymentsModal, {
propsData: {
modalId: 'runner-aws-deployments-modal',
- imgSrc: '/assets/aws-cloud-formation.png',
},
});
};
@@ -43,34 +45,30 @@ describe('RunnerAwsDeploymentsModal', () => {
});
describe('first easy button', () => {
- const findFirstButton = () => findEasyButtons().at(0);
-
it('should contain the correct description', () => {
- expect(findFirstButton().text()).toBe(EASY_BUTTONS[0].description);
+ expect(findEasyButtons().at(0).text()).toContain(EASY_BUTTONS[0].description);
});
it('should contain the correct link', () => {
- const link = findFirstButton().attributes('href');
+ const templateUrl = encodeURIComponent(TEMPLATES_BASE_URL + EASY_BUTTONS[0].templateName);
+ const { stackName } = EASY_BUTTONS[0];
+ const instanceUrl = encodeURIComponent(getBaseURL());
+ const url = `${CF_BASE_URL}templateURL=${templateUrl}&stackName=${stackName}&param_3GITLABRunnerInstanceURL=${instanceUrl}`;
+
+ findModal().vm.$emit('primary');
- expect(link.startsWith(CF_BASE_URL)).toBe(true);
- expect(
- link.includes(
- `templateURL=${encodeURIComponent(TEMPLATES_BASE_URL + EASY_BUTTONS[0].templateName)}`,
- ),
- ).toBe(true);
- expect(link.includes(`stackName=${EASY_BUTTONS[0].stackName}`)).toBe(true);
- expect(
- link.includes(`param_3GITLABRunnerInstanceURL=${encodeURIComponent(getBaseURL())}`),
- ).toBe(true);
+ expect(visitUrl).toHaveBeenCalledWith(url, true);
});
it('should track an event when clicked', () => {
- findFirstButton().vm.$emit('click');
+ const trackingSpy = mockTracking(undefined, wrapper.element, jest.spyOn);
+
+ findModal().vm.$emit('primary');
- expect(ExperimentTracking).toHaveBeenCalledWith(EXPERIMENT_NAME);
- expect(ExperimentTracking.prototype.event).toHaveBeenCalledWith(
- `template_clicked_${EASY_BUTTONS[0].stackName}`,
- );
+ expect(trackingSpy).toHaveBeenCalledTimes(1);
+ expect(trackingSpy).toHaveBeenCalledWith(undefined, 'template_clicked', {
+ label: EASY_BUTTONS[0].stackName,
+ });
});
});
});
diff --git a/spec/frontend/vue_shared/components/source_viewer/source_viewer_spec.js b/spec/frontend/vue_shared/components/source_viewer/source_viewer_spec.js
index 2010bac7060..ab579945e22 100644
--- a/spec/frontend/vue_shared/components/source_viewer/source_viewer_spec.js
+++ b/spec/frontend/vue_shared/components/source_viewer/source_viewer_spec.js
@@ -7,6 +7,7 @@ import SourceViewer from '~/vue_shared/components/source_viewer/source_viewer.vu
import { ROUGE_TO_HLJS_LANGUAGE_MAP } from '~/vue_shared/components/source_viewer/constants';
import LineNumbers from '~/vue_shared/components/line_numbers.vue';
import waitForPromises from 'helpers/wait_for_promises';
+import * as sourceViewerUtils from '~/vue_shared/components/source_viewer/utils';
jest.mock('highlight.js/lib/core');
Vue.use(VueRouter);
@@ -36,6 +37,7 @@ describe('Source Viewer component', () => {
beforeEach(() => {
hljs.highlight.mockImplementation(() => ({ value: highlightedContent }));
hljs.highlightAuto.mockImplementation(() => ({ value: highlightedContent }));
+ jest.spyOn(sourceViewerUtils, 'wrapLines');
return createComponent();
});
@@ -73,6 +75,10 @@ describe('Source Viewer component', () => {
expect(findLoadingIcon().exists()).toBe(true);
});
+ it('calls the wrapLines helper method with highlightedContent and mappedLanguage', () => {
+ expect(sourceViewerUtils.wrapLines).toHaveBeenCalledWith(highlightedContent, mappedLanguage);
+ });
+
it('renders Line Numbers', () => {
expect(findLineNumbers().props('lines')).toBe(1);
});
diff --git a/spec/frontend/vue_shared/components/source_viewer/utils_spec.js b/spec/frontend/vue_shared/components/source_viewer/utils_spec.js
index 937c3b26c67..0631e7efd54 100644
--- a/spec/frontend/vue_shared/components/source_viewer/utils_spec.js
+++ b/spec/frontend/vue_shared/components/source_viewer/utils_spec.js
@@ -2,12 +2,25 @@ import { wrapLines } from '~/vue_shared/components/source_viewer/utils';
describe('Wrap lines', () => {
it.each`
- input | output
- ${'line 1'} | ${'<span id="LC1" class="line">line 1</span>'}
- ${'line 1\nline 2'} | ${`<span id="LC1" class="line">line 1</span>\n<span id="LC2" class="line">line 2</span>`}
- ${'<span class="hljs-code">line 1\nline 2</span>'} | ${`<span id="LC1" class="hljs-code">line 1\n<span id="LC2" class="line">line 2</span></span>`}
- ${'<span class="hljs-code">```bash'} | ${'<span id="LC1" class="hljs-code">```bash'}
- `('returns lines wrapped in spans containing line numbers', ({ input, output }) => {
- expect(wrapLines(input)).toBe(output);
+ content | language | output
+ ${'line 1'} | ${'javascript'} | ${'<span id="LC1" lang="javascript" class="line">line 1</span>'}
+ ${'line 1\nline 2'} | ${'html'} | ${`<span id="LC1" lang="html" class="line">line 1</span>\n<span id="LC2" lang="html" class="line">line 2</span>`}
+ ${'<span class="hljs-code">line 1\nline 2</span>'} | ${'html'} | ${`<span id="LC1" lang="html" class="hljs-code">line 1\n<span id="LC2" lang="html" class="line">line 2</span></span>`}
+ ${'<span class="hljs-code">```bash'} | ${'bash'} | ${'<span id="LC1" lang="bash" class="hljs-code">```bash'}
+ ${'<span class="hljs-code">```bash'} | ${'valid-language1'} | ${'<span id="LC1" lang="valid-language1" class="hljs-code">```bash'}
+ ${'<span class="hljs-code">```bash'} | ${'valid_language2'} | ${'<span id="LC1" lang="valid_language2" class="hljs-code">```bash'}
+ `('returns lines wrapped in spans containing line numbers', ({ content, language, output }) => {
+ expect(wrapLines(content, language)).toBe(output);
+ });
+
+ it.each`
+ language
+ ${'invalidLanguage>'}
+ ${'"invalidLanguage"'}
+ ${'<invalidLanguage'}
+ `('returns lines safely without XSS language is not valid', ({ language }) => {
+ expect(wrapLines('<span class="hljs-code">```bash', language)).toBe(
+ '<span id="LC1" lang="" class="hljs-code">```bash',
+ );
});
});
diff --git a/spec/frontend/vue_shared/components/user_avatar/user_avatar_image_new_spec.js b/spec/frontend/vue_shared/components/user_avatar/user_avatar_image_new_spec.js
new file mode 100644
index 00000000000..f624f84eabd
--- /dev/null
+++ b/spec/frontend/vue_shared/components/user_avatar/user_avatar_image_new_spec.js
@@ -0,0 +1,127 @@
+import { shallowMount } from '@vue/test-utils';
+import { GlAvatar, GlTooltip } from '@gitlab/ui';
+import defaultAvatarUrl from 'images/no_avatar.png';
+import { placeholderImage } from '~/lazy_loader';
+import UserAvatarImage from '~/vue_shared/components/user_avatar/user_avatar_image_new.vue';
+
+jest.mock('images/no_avatar.png', () => 'default-avatar-url');
+
+const PROVIDED_PROPS = {
+ size: 32,
+ imgSrc: 'myavatarurl.com',
+ imgAlt: 'mydisplayname',
+ cssClasses: 'myextraavatarclass',
+ tooltipText: 'tooltip text',
+ tooltipPlacement: 'bottom',
+};
+
+describe('User Avatar Image Component', () => {
+ let wrapper;
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ describe('Initialization', () => {
+ beforeEach(() => {
+ wrapper = shallowMount(UserAvatarImage, {
+ propsData: {
+ ...PROVIDED_PROPS,
+ },
+ provide: {
+ glFeatures: {
+ glAvatarForAllUserAvatars: true,
+ },
+ },
+ });
+ });
+
+ it('should render `GlAvatar` and provide correct properties to it', () => {
+ const avatar = wrapper.findComponent(GlAvatar);
+
+ expect(avatar.attributes('data-src')).toBe(
+ `${PROVIDED_PROPS.imgSrc}?width=${PROVIDED_PROPS.size}`,
+ );
+ expect(avatar.props()).toMatchObject({
+ src: `${PROVIDED_PROPS.imgSrc}?width=${PROVIDED_PROPS.size}`,
+ alt: PROVIDED_PROPS.imgAlt,
+ size: PROVIDED_PROPS.size,
+ });
+ });
+
+ it('should add correct CSS classes', () => {
+ const classes = wrapper.findComponent(GlAvatar).classes();
+ expect(classes).toContain(PROVIDED_PROPS.cssClasses);
+ expect(classes).not.toContain('lazy');
+ });
+ });
+
+ describe('Initialization when lazy', () => {
+ beforeEach(() => {
+ wrapper = shallowMount(UserAvatarImage, {
+ propsData: {
+ ...PROVIDED_PROPS,
+ lazy: true,
+ },
+ provide: {
+ glFeatures: {
+ glAvatarForAllUserAvatars: true,
+ },
+ },
+ });
+ });
+
+ it('should add lazy attributes', () => {
+ const avatar = wrapper.findComponent(GlAvatar);
+
+ expect(avatar.classes()).toContain('lazy');
+ expect(avatar.attributes()).toMatchObject({
+ src: placeholderImage,
+ 'data-src': `${PROVIDED_PROPS.imgSrc}?width=${PROVIDED_PROPS.size}`,
+ });
+ });
+ });
+
+ describe('Initialization without src', () => {
+ beforeEach(() => {
+ wrapper = shallowMount(UserAvatarImage, {
+ propsData: {
+ ...PROVIDED_PROPS,
+ imgSrc: null,
+ },
+ provide: {
+ glFeatures: {
+ glAvatarForAllUserAvatars: true,
+ },
+ },
+ });
+ });
+
+ it('should have default avatar image', () => {
+ const avatar = wrapper.findComponent(GlAvatar);
+
+ expect(avatar.props('src')).toBe(`${defaultAvatarUrl}?width=${PROVIDED_PROPS.size}`);
+ });
+ });
+
+ describe('Dynamic tooltip content', () => {
+ const slots = {
+ default: ['Action!'],
+ };
+
+ beforeEach(() => {
+ wrapper = shallowMount(UserAvatarImage, {
+ propsData: PROVIDED_PROPS,
+ slots,
+ });
+ });
+
+ it('renders the tooltip slot', () => {
+ expect(wrapper.findComponent(GlTooltip).exists()).toBe(true);
+ });
+
+ it('renders the tooltip content', () => {
+ expect(wrapper.findComponent(GlTooltip).text()).toContain(slots.default[0]);
+ });
+ });
+});
diff --git a/spec/frontend/vue_shared/components/user_avatar/user_avatar_image_old_spec.js b/spec/frontend/vue_shared/components/user_avatar/user_avatar_image_old_spec.js
new file mode 100644
index 00000000000..5051b2b9cae
--- /dev/null
+++ b/spec/frontend/vue_shared/components/user_avatar/user_avatar_image_old_spec.js
@@ -0,0 +1,122 @@
+import { shallowMount } from '@vue/test-utils';
+import { GlTooltip } from '@gitlab/ui';
+import defaultAvatarUrl from 'images/no_avatar.png';
+import { placeholderImage } from '~/lazy_loader';
+import UserAvatarImage from '~/vue_shared/components/user_avatar/user_avatar_image_old.vue';
+
+jest.mock('images/no_avatar.png', () => 'default-avatar-url');
+
+const PROVIDED_PROPS = {
+ size: 32,
+ imgSrc: 'myavatarurl.com',
+ imgAlt: 'mydisplayname',
+ cssClasses: 'myextraavatarclass',
+ tooltipText: 'tooltip text',
+ tooltipPlacement: 'bottom',
+};
+
+const DEFAULT_PROPS = {
+ size: 20,
+};
+
+describe('User Avatar Image Component', () => {
+ let wrapper;
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ describe('Initialization', () => {
+ beforeEach(() => {
+ wrapper = shallowMount(UserAvatarImage, {
+ propsData: {
+ ...PROVIDED_PROPS,
+ },
+ });
+ });
+
+ it('should have <img> as a child element', () => {
+ const imageElement = wrapper.find('img');
+
+ expect(imageElement.exists()).toBe(true);
+ expect(imageElement.attributes('src')).toBe(
+ `${PROVIDED_PROPS.imgSrc}?width=${PROVIDED_PROPS.size}`,
+ );
+ expect(imageElement.attributes('data-src')).toBe(
+ `${PROVIDED_PROPS.imgSrc}?width=${PROVIDED_PROPS.size}`,
+ );
+ expect(imageElement.attributes('alt')).toBe(PROVIDED_PROPS.imgAlt);
+ });
+
+ it('should properly render img css', () => {
+ const classes = wrapper.find('img').classes();
+ expect(classes).toEqual(['avatar', 's32', PROVIDED_PROPS.cssClasses]);
+ expect(classes).not.toContain('lazy');
+ });
+ });
+
+ describe('Initialization when lazy', () => {
+ beforeEach(() => {
+ wrapper = shallowMount(UserAvatarImage, {
+ propsData: {
+ ...PROVIDED_PROPS,
+ lazy: true,
+ },
+ });
+ });
+
+ it('should add lazy attributes', () => {
+ const imageElement = wrapper.find('img');
+
+ expect(imageElement.classes()).toContain('lazy');
+ expect(imageElement.attributes('src')).toBe(placeholderImage);
+ expect(imageElement.attributes('data-src')).toBe(
+ `${PROVIDED_PROPS.imgSrc}?width=${PROVIDED_PROPS.size}`,
+ );
+ });
+ });
+
+ describe('Initialization without src', () => {
+ beforeEach(() => {
+ wrapper = shallowMount(UserAvatarImage);
+ });
+
+ it('should have default avatar image', () => {
+ const imageElement = wrapper.find('img');
+
+ expect(imageElement.attributes('src')).toBe(
+ `${defaultAvatarUrl}?width=${DEFAULT_PROPS.size}`,
+ );
+ });
+ });
+
+ describe('dynamic tooltip content', () => {
+ const props = PROVIDED_PROPS;
+ const slots = {
+ default: ['Action!'],
+ };
+
+ beforeEach(() => {
+ wrapper = shallowMount(UserAvatarImage, {
+ propsData: { props },
+ slots,
+ });
+ });
+
+ it('renders the tooltip slot', () => {
+ expect(wrapper.findComponent(GlTooltip).exists()).toBe(true);
+ });
+
+ it('renders the tooltip content', () => {
+ expect(wrapper.findComponent(GlTooltip).text()).toContain(slots.default[0]);
+ });
+
+ it('does not render tooltip data attributes on avatar image', () => {
+ const avatarImg = wrapper.find('img');
+
+ expect(avatarImg.attributes('title')).toBeFalsy();
+ expect(avatarImg.attributes('data-placement')).not.toBeDefined();
+ expect(avatarImg.attributes('data-container')).not.toBeDefined();
+ });
+ });
+});
diff --git a/spec/frontend/vue_shared/components/user_avatar/user_avatar_image_spec.js b/spec/frontend/vue_shared/components/user_avatar/user_avatar_image_spec.js
index 2c3fc70e116..75d2a936b34 100644
--- a/spec/frontend/vue_shared/components/user_avatar/user_avatar_image_spec.js
+++ b/spec/frontend/vue_shared/components/user_avatar/user_avatar_image_spec.js
@@ -1,12 +1,10 @@
import { shallowMount } from '@vue/test-utils';
-import defaultAvatarUrl from 'images/no_avatar.png';
-import { placeholderImage } from '~/lazy_loader';
import UserAvatarImage from '~/vue_shared/components/user_avatar/user_avatar_image.vue';
+import UserAvatarImageNew from '~/vue_shared/components/user_avatar/user_avatar_image_new.vue';
+import UserAvatarImageOld from '~/vue_shared/components/user_avatar/user_avatar_image_old.vue';
-jest.mock('images/no_avatar.png', () => 'default-avatar-url');
-
-const DEFAULT_PROPS = {
- size: 99,
+const PROVIDED_PROPS = {
+ size: 32,
imgSrc: 'myavatarurl.com',
imgAlt: 'mydisplayname',
cssClasses: 'myextraavatarclass',
@@ -21,89 +19,43 @@ describe('User Avatar Image Component', () => {
wrapper.destroy();
});
- describe('Initialization', () => {
+ describe('when `glAvatarForAllUserAvatars` feature flag enabled', () => {
beforeEach(() => {
wrapper = shallowMount(UserAvatarImage, {
propsData: {
- ...DEFAULT_PROPS,
+ ...PROVIDED_PROPS,
+ },
+ provide: {
+ glFeatures: {
+ glAvatarForAllUserAvatars: true,
+ },
},
});
});
- it('should have <img> as a child element', () => {
- const imageElement = wrapper.find('img');
-
- expect(imageElement.exists()).toBe(true);
- expect(imageElement.attributes('src')).toBe(`${DEFAULT_PROPS.imgSrc}?width=99`);
- expect(imageElement.attributes('data-src')).toBe(`${DEFAULT_PROPS.imgSrc}?width=99`);
- expect(imageElement.attributes('alt')).toBe(DEFAULT_PROPS.imgAlt);
- });
-
- it('should properly render img css', () => {
- const classes = wrapper.find('img').classes();
- expect(classes).toEqual(expect.arrayContaining(['avatar', 's99', DEFAULT_PROPS.cssClasses]));
- expect(classes).not.toContain('lazy');
+ it('should render `UserAvatarImageNew` component', () => {
+ expect(wrapper.findComponent(UserAvatarImageNew).exists()).toBe(true);
+ expect(wrapper.findComponent(UserAvatarImageOld).exists()).toBe(false);
});
});
- describe('Initialization when lazy', () => {
+ describe('when `glAvatarForAllUserAvatars` feature flag disabled', () => {
beforeEach(() => {
wrapper = shallowMount(UserAvatarImage, {
propsData: {
- ...DEFAULT_PROPS,
- lazy: true,
+ ...PROVIDED_PROPS,
+ },
+ provide: {
+ glFeatures: {
+ glAvatarForAllUserAvatars: false,
+ },
},
});
});
- it('should add lazy attributes', () => {
- const imageElement = wrapper.find('img');
-
- expect(imageElement.classes()).toContain('lazy');
- expect(imageElement.attributes('src')).toBe(placeholderImage);
- expect(imageElement.attributes('data-src')).toBe(`${DEFAULT_PROPS.imgSrc}?width=99`);
- });
- });
-
- describe('Initialization without src', () => {
- beforeEach(() => {
- wrapper = shallowMount(UserAvatarImage);
- });
-
- it('should have default avatar image', () => {
- const imageElement = wrapper.find('img');
-
- expect(imageElement.attributes('src')).toBe(`${defaultAvatarUrl}?width=20`);
- });
- });
-
- describe('dynamic tooltip content', () => {
- const props = DEFAULT_PROPS;
- const slots = {
- default: ['Action!'],
- };
-
- beforeEach(() => {
- wrapper = shallowMount(UserAvatarImage, {
- propsData: { props },
- slots,
- });
- });
-
- it('renders the tooltip slot', () => {
- expect(wrapper.find('.js-user-avatar-image-tooltip').exists()).toBe(true);
- });
-
- it('renders the tooltip content', () => {
- expect(wrapper.find('.js-user-avatar-image-tooltip').text()).toContain(slots.default[0]);
- });
-
- it('does not render tooltip data attributes for on avatar image', () => {
- const avatarImg = wrapper.find('img');
-
- expect(avatarImg.attributes('title')).toBeFalsy();
- expect(avatarImg.attributes('data-placement')).not.toBeDefined();
- expect(avatarImg.attributes('data-container')).not.toBeDefined();
+ it('should render `UserAvatarImageOld` component', () => {
+ expect(wrapper.findComponent(UserAvatarImageNew).exists()).toBe(false);
+ expect(wrapper.findComponent(UserAvatarImageOld).exists()).toBe(true);
});
});
});
diff --git a/spec/frontend/vue_shared/components/user_avatar/user_avatar_link_new_spec.js b/spec/frontend/vue_shared/components/user_avatar/user_avatar_link_new_spec.js
new file mode 100644
index 00000000000..5ba80b31b99
--- /dev/null
+++ b/spec/frontend/vue_shared/components/user_avatar/user_avatar_link_new_spec.js
@@ -0,0 +1,102 @@
+import { GlAvatarLink } from '@gitlab/ui';
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
+import { TEST_HOST } from 'spec/test_constants';
+import UserAvatarImage from '~/vue_shared/components/user_avatar/user_avatar_image.vue';
+import UserAvatarLink from '~/vue_shared/components/user_avatar/user_avatar_link_new.vue';
+
+describe('User Avatar Link Component', () => {
+ let wrapper;
+
+ const findUserName = () => wrapper.findByTestId('user-avatar-link-username');
+
+ const defaultProps = {
+ linkHref: `${TEST_HOST}/myavatarurl.com`,
+ imgSize: 32,
+ imgSrc: `${TEST_HOST}/myavatarurl.com`,
+ imgAlt: 'mydisplayname',
+ imgCssClasses: 'myextraavatarclass',
+ tooltipText: 'tooltip text',
+ tooltipPlacement: 'bottom',
+ username: 'username',
+ };
+
+ const createWrapper = (props, slots) => {
+ wrapper = shallowMountExtended(UserAvatarLink, {
+ propsData: {
+ ...defaultProps,
+ ...props,
+ ...slots,
+ },
+ });
+ };
+
+ beforeEach(() => {
+ createWrapper();
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ it('should render GlLink with correct props', () => {
+ const link = wrapper.findComponent(GlAvatarLink);
+ expect(link.exists()).toBe(true);
+ expect(link.attributes('href')).toBe(defaultProps.linkHref);
+ });
+
+ it('should render UserAvatarImage and provide correct props to it', () => {
+ expect(wrapper.findComponent(UserAvatarImage).exists()).toBe(true);
+ expect(wrapper.findComponent(UserAvatarImage).props()).toEqual({
+ cssClasses: defaultProps.imgCssClasses,
+ imgAlt: defaultProps.imgAlt,
+ imgSrc: defaultProps.imgSrc,
+ lazy: false,
+ size: defaultProps.imgSize,
+ tooltipPlacement: defaultProps.tooltipPlacement,
+ tooltipText: '',
+ });
+ });
+
+ describe('when username provided', () => {
+ beforeEach(() => {
+ createWrapper({ username: defaultProps.username });
+ });
+
+ it('should render provided username', () => {
+ expect(findUserName().text()).toBe(defaultProps.username);
+ });
+
+ it('should provide the tooltip data for the username', () => {
+ expect(findUserName().attributes()).toEqual(
+ expect.objectContaining({
+ title: defaultProps.tooltipText,
+ 'tooltip-placement': defaultProps.tooltipPlacement,
+ }),
+ );
+ });
+ });
+
+ describe('when username is NOT provided', () => {
+ beforeEach(() => {
+ createWrapper({ username: '' });
+ });
+
+ it('should NOT render username', () => {
+ expect(findUserName().exists()).toBe(false);
+ });
+ });
+
+ describe('avatar-badge slot', () => {
+ const badge = '<span>User badge</span>';
+
+ beforeEach(() => {
+ createWrapper(defaultProps, {
+ 'avatar-badge': badge,
+ });
+ });
+
+ it('should render provided `avatar-badge` slot content', () => {
+ expect(wrapper.html()).toContain(badge);
+ });
+ });
+});
diff --git a/spec/frontend/vue_shared/components/user_avatar/user_avatar_link_old_spec.js b/spec/frontend/vue_shared/components/user_avatar/user_avatar_link_old_spec.js
new file mode 100644
index 00000000000..2d513c46e77
--- /dev/null
+++ b/spec/frontend/vue_shared/components/user_avatar/user_avatar_link_old_spec.js
@@ -0,0 +1,102 @@
+import { GlLink } from '@gitlab/ui';
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
+import { TEST_HOST } from 'spec/test_constants';
+import UserAvatarImage from '~/vue_shared/components/user_avatar/user_avatar_image.vue';
+import UserAvatarLink from '~/vue_shared/components/user_avatar/user_avatar_link_old.vue';
+
+describe('User Avatar Link Component', () => {
+ let wrapper;
+
+ const findUserName = () => wrapper.find('[data-testid="user-avatar-link-username"]');
+
+ const defaultProps = {
+ linkHref: `${TEST_HOST}/myavatarurl.com`,
+ imgSize: 32,
+ imgSrc: `${TEST_HOST}/myavatarurl.com`,
+ imgAlt: 'mydisplayname',
+ imgCssClasses: 'myextraavatarclass',
+ tooltipText: 'tooltip text',
+ tooltipPlacement: 'bottom',
+ username: 'username',
+ };
+
+ const createWrapper = (props, slots) => {
+ wrapper = shallowMountExtended(UserAvatarLink, {
+ propsData: {
+ ...defaultProps,
+ ...props,
+ ...slots,
+ },
+ });
+ };
+
+ beforeEach(() => {
+ createWrapper();
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ it('should render GlLink with correct props', () => {
+ const link = wrapper.findComponent(GlLink);
+ expect(link.exists()).toBe(true);
+ expect(link.attributes('href')).toBe(defaultProps.linkHref);
+ });
+
+ it('should render UserAvatarImage and povide correct props to it', () => {
+ expect(wrapper.findComponent(UserAvatarImage).exists()).toBe(true);
+ expect(wrapper.findComponent(UserAvatarImage).props()).toEqual({
+ cssClasses: defaultProps.imgCssClasses,
+ imgAlt: defaultProps.imgAlt,
+ imgSrc: defaultProps.imgSrc,
+ lazy: false,
+ size: defaultProps.imgSize,
+ tooltipPlacement: defaultProps.tooltipPlacement,
+ tooltipText: '',
+ });
+ });
+
+ describe('when username provided', () => {
+ beforeEach(() => {
+ createWrapper({ username: defaultProps.username });
+ });
+
+ it('should render provided username', () => {
+ expect(findUserName().text()).toBe(defaultProps.username);
+ });
+
+ it('should provide the tooltip data for the username', () => {
+ expect(findUserName().attributes()).toEqual(
+ expect.objectContaining({
+ title: defaultProps.tooltipText,
+ 'tooltip-placement': defaultProps.tooltipPlacement,
+ }),
+ );
+ });
+ });
+
+ describe('when username is NOT provided', () => {
+ beforeEach(() => {
+ createWrapper({ username: '' });
+ });
+
+ it('should NOT render username', () => {
+ expect(findUserName().exists()).toBe(false);
+ });
+ });
+
+ describe('avatar-badge slot', () => {
+ const badge = '<span>User badge</span>';
+
+ beforeEach(() => {
+ createWrapper(defaultProps, {
+ 'avatar-badge': badge,
+ });
+ });
+
+ it('should render provided `avatar-badge` slot content', () => {
+ expect(wrapper.html()).toContain(badge);
+ });
+ });
+});
diff --git a/spec/frontend/vue_shared/components/user_avatar/user_avatar_link_spec.js b/spec/frontend/vue_shared/components/user_avatar/user_avatar_link_spec.js
index d3fec680b54..b36b83d1fea 100644
--- a/spec/frontend/vue_shared/components/user_avatar/user_avatar_link_spec.js
+++ b/spec/frontend/vue_shared/components/user_avatar/user_avatar_link_spec.js
@@ -1,118 +1,61 @@
-import { GlLink } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
-import { each } from 'lodash';
-import { trimText } from 'helpers/text_helper';
-import { TEST_HOST } from 'spec/test_constants';
-import UserAvatarImage from '~/vue_shared/components/user_avatar/user_avatar_image.vue';
import UserAvatarLink from '~/vue_shared/components/user_avatar/user_avatar_link.vue';
+import UserAvatarLinkNew from '~/vue_shared/components/user_avatar/user_avatar_link_new.vue';
+import UserAvatarLinkOld from '~/vue_shared/components/user_avatar/user_avatar_link_old.vue';
+
+const PROVIDED_PROPS = {
+ size: 32,
+ imgSrc: 'myavatarurl.com',
+ imgAlt: 'mydisplayname',
+ cssClasses: 'myextraavatarclass',
+ tooltipText: 'tooltip text',
+ tooltipPlacement: 'bottom',
+};
describe('User Avatar Link Component', () => {
let wrapper;
- const defaultProps = {
- linkHref: `${TEST_HOST}/myavatarurl.com`,
- imgSize: 99,
- imgSrc: `${TEST_HOST}/myavatarurl.com`,
- imgAlt: 'mydisplayname',
- imgCssClasses: 'myextraavatarclass',
- tooltipText: 'tooltip text',
- tooltipPlacement: 'bottom',
- username: 'username',
- };
-
- const createWrapper = (props) => {
- wrapper = shallowMount(UserAvatarLink, {
- propsData: {
- ...defaultProps,
- ...props,
- },
- });
- };
-
- beforeEach(() => {
- createWrapper();
- });
-
afterEach(() => {
wrapper.destroy();
- wrapper = null;
- });
-
- it('should have user-avatar-image registered as child component', () => {
- expect(wrapper.vm.$options.components.userAvatarImage).toBeDefined();
- });
-
- it('user-avatar-link should have user-avatar-image as child component', () => {
- expect(wrapper.find(UserAvatarImage).exists()).toBe(true);
- });
-
- it('should render GlLink as a child element', () => {
- const link = wrapper.find(GlLink);
-
- expect(link.exists()).toBe(true);
- expect(link.attributes('href')).toBe(defaultProps.linkHref);
- });
-
- it('should return necessary props as defined', () => {
- each(defaultProps, (val, key) => {
- expect(wrapper.vm[key]).toBeDefined();
- });
});
- describe('no username', () => {
+ describe('when `glAvatarForAllUserAvatars` feature flag enabled', () => {
beforeEach(() => {
- createWrapper({
- username: '',
+ wrapper = shallowMount(UserAvatarLink, {
+ propsData: {
+ ...PROVIDED_PROPS,
+ },
+ provide: {
+ glFeatures: {
+ glAvatarForAllUserAvatars: true,
+ },
+ },
});
});
- it('should only render image tag in link', () => {
- const childElements = wrapper.vm.$el.childNodes;
-
- expect(wrapper.find('img')).not.toBe('null');
-
- // Vue will render the hidden component as <!---->
- expect(childElements[1].tagName).toBeUndefined();
- });
-
- it('should render avatar image tooltip', () => {
- expect(wrapper.vm.shouldShowUsername).toBe(false);
- expect(wrapper.vm.avatarTooltipText).toEqual(defaultProps.tooltipText);
+ it('should render `UserAvatarLinkNew` component', () => {
+ expect(wrapper.findComponent(UserAvatarLinkNew).exists()).toBe(true);
+ expect(wrapper.findComponent(UserAvatarLinkOld).exists()).toBe(false);
});
});
- describe('username', () => {
- it('should not render avatar image tooltip', () => {
- expect(wrapper.find('.js-user-avatar-image-tooltip').exists()).toBe(false);
- });
-
- it('should render username prop in <span>', () => {
- expect(trimText(wrapper.find('.js-user-avatar-link-username').text())).toEqual(
- defaultProps.username,
- );
- });
-
- it('should render text tooltip for <span>', () => {
- expect(wrapper.find('.js-user-avatar-link-username').attributes('title')).toEqual(
- defaultProps.tooltipText,
- );
- });
-
- it('should render text tooltip placement for <span>', () => {
- expect(wrapper.find('.js-user-avatar-link-username').attributes('tooltip-placement')).toBe(
- defaultProps.tooltipPlacement,
- );
- });
- });
-
- describe('lazy', () => {
- it('passes lazy prop to avatar image', () => {
- createWrapper({
- username: '',
- lazy: true,
+ describe('when `glAvatarForAllUserAvatars` feature flag disabled', () => {
+ beforeEach(() => {
+ wrapper = shallowMount(UserAvatarLink, {
+ propsData: {
+ ...PROVIDED_PROPS,
+ },
+ provide: {
+ glFeatures: {
+ glAvatarForAllUserAvatars: false,
+ },
+ },
});
+ });
- expect(wrapper.find(UserAvatarImage).props('lazy')).toBe(true);
+ it('should render `UserAvatarLinkOld` component', () => {
+ expect(wrapper.findComponent(UserAvatarLinkNew).exists()).toBe(false);
+ expect(wrapper.findComponent(UserAvatarLinkOld).exists()).toBe(true);
});
});
});
diff --git a/spec/frontend/vue_shared/components/user_popover/user_popover_spec.js b/spec/frontend/vue_shared/components/user_popover/user_popover_spec.js
index 09633daf587..3329199a46b 100644
--- a/spec/frontend/vue_shared/components/user_popover/user_popover_spec.js
+++ b/spec/frontend/vue_shared/components/user_popover/user_popover_spec.js
@@ -271,6 +271,12 @@ describe('User Popover Component', () => {
expect(securityBotDocsLink.text()).toBe('Learn more about GitLab Security Bot');
});
+ it("does not show a link to the bot's documentation if there is no website_url", () => {
+ createWrapper({ user: { ...SECURITY_BOT_USER, websiteUrl: null } });
+ const securityBotDocsLink = findSecurityBotDocsLink();
+ expect(securityBotDocsLink.exists()).toBe(false);
+ });
+
it("doesn't escape user's name", () => {
createWrapper({ user: { ...SECURITY_BOT_USER, name: '%<>\';"' } });
const securityBotDocsLink = findSecurityBotDocsLink();
diff --git a/spec/frontend/vue_shared/components/user_select_spec.js b/spec/frontend/vue_shared/components/user_select_spec.js
index 411a15e1c74..cb476910944 100644
--- a/spec/frontend/vue_shared/components/user_select_spec.js
+++ b/spec/frontend/vue_shared/components/user_select_spec.js
@@ -1,4 +1,4 @@
-import { GlSearchBoxByType, GlDropdown } from '@gitlab/ui';
+import { GlSearchBoxByType } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import { cloneDeep } from 'lodash';
import Vue, { nextTick } from 'vue';
@@ -6,11 +6,14 @@ import VueApollo from 'vue-apollo';
import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises';
import searchUsersQuery from '~/graphql_shared/queries/users_search.query.graphql';
-import { ASSIGNEES_DEBOUNCE_DELAY } from '~/sidebar/constants';
+import searchUsersQueryOnMR from '~/graphql_shared/queries/users_search_with_mr_permissions.graphql';
+import { IssuableType } from '~/issues/constants';
+import { DEFAULT_DEBOUNCE_AND_THROTTLE_MS } from '~/lib/utils/constants';
import getIssueParticipantsQuery from '~/vue_shared/components/sidebar/queries/get_issue_participants.query.graphql';
import UserSelect from '~/vue_shared/components/user_select/user_select.vue';
import {
searchResponse,
+ searchResponseOnMR,
projectMembersResponse,
participantsQueryResponse,
} from '../../sidebar/mock_data';
@@ -28,7 +31,7 @@ const assignee = {
const mockError = jest.fn().mockRejectedValue('Error!');
const waitForSearch = async () => {
- jest.advanceTimersByTime(ASSIGNEES_DEBOUNCE_DELAY);
+ jest.advanceTimersByTime(DEFAULT_DEBOUNCE_AND_THROTTLE_MS);
await nextTick();
await waitForPromises();
};
@@ -58,6 +61,7 @@ describe('User select dropdown', () => {
} = {}) => {
fakeApollo = createMockApollo([
[searchUsersQuery, searchQueryHandler],
+ [searchUsersQueryOnMR, jest.fn().mockResolvedValue(searchResponseOnMR)],
[getIssueParticipantsQuery, participantsQueryHandler],
]);
wrapper = shallowMount(UserSelect, {
@@ -76,7 +80,18 @@ describe('User select dropdown', () => {
...props,
},
stubs: {
- GlDropdown,
+ GlDropdown: {
+ template: `
+ <div>
+ <slot name="header"></slot>
+ <slot></slot>
+ <slot name="footer"></slot>
+ </div>
+ `,
+ methods: {
+ hide: jest.fn(),
+ },
+ },
},
});
};
@@ -132,11 +147,19 @@ describe('User select dropdown', () => {
expect(findSelectedParticipants()).toHaveLength(1);
});
+ it('does not render a `Cannot merge` tooltip', async () => {
+ createComponent();
+ await waitForPromises();
+
+ expect(findUnselectedParticipants().at(0).attributes('title')).toBe('');
+ });
+
describe('when search is empty', () => {
it('renders a merged list of participants and project members', async () => {
createComponent();
await waitForPromises();
- expect(findUnselectedParticipants()).toHaveLength(3);
+
+ expect(findUnselectedParticipants()).toHaveLength(4);
});
it('renders `Unassigned` link with the checkmark when there are no selected users', async () => {
@@ -162,7 +185,7 @@ describe('User select dropdown', () => {
},
});
await waitForPromises();
- findUnassignLink().vm.$emit('click');
+ findUnassignLink().trigger('click');
expect(wrapper.emitted('input')).toEqual([[[]]]);
});
@@ -175,7 +198,7 @@ describe('User select dropdown', () => {
});
await waitForPromises();
- findSelectedParticipants().at(0).vm.$emit('click', new Event('click'));
+ findSelectedParticipants().at(0).trigger('click');
expect(wrapper.emitted('input')).toEqual([[[]]]);
});
@@ -187,8 +210,9 @@ describe('User select dropdown', () => {
});
await waitForPromises();
- findUnselectedParticipants().at(0).vm.$emit('click');
- expect(wrapper.emitted('input')).toEqual([
+ findUnselectedParticipants().at(0).trigger('click');
+
+ expect(wrapper.emitted('input')).toMatchObject([
[
[
{
@@ -214,7 +238,7 @@ describe('User select dropdown', () => {
});
await waitForPromises();
- findUnselectedParticipants().at(0).vm.$emit('click');
+ findUnselectedParticipants().at(0).trigger('click');
expect(wrapper.emitted('input')[0][0]).toHaveLength(2);
});
});
@@ -232,7 +256,7 @@ describe('User select dropdown', () => {
createComponent();
await waitForPromises();
findSearchField().vm.$emit('input', 'roo');
- jest.advanceTimersByTime(ASSIGNEES_DEBOUNCE_DELAY);
+ jest.advanceTimersByTime(DEFAULT_DEBOUNCE_AND_THROTTLE_MS);
await nextTick();
expect(findParticipantsLoading().exists()).toBe(true);
@@ -273,4 +297,19 @@ describe('User select dropdown', () => {
expect(findEmptySearchResults().exists()).toBe(true);
});
});
+
+ describe('when on merge request sidebar', () => {
+ beforeEach(() => {
+ createComponent({ props: { issuableType: IssuableType.MergeRequest, issuableId: 1 } });
+ return waitForPromises();
+ });
+
+ it('does not render a `Cannot merge` tooltip for a user that has merge permission', () => {
+ expect(findUnselectedParticipants().at(0).attributes('title')).toBe('');
+ });
+
+ it('renders a `Cannot merge` tooltip for a user that does not have merge permission', () => {
+ expect(findUnselectedParticipants().at(1).attributes('title')).toBe('Cannot merge');
+ });
+ });
});
diff --git a/spec/frontend/vue_shared/components/web_ide_link_spec.js b/spec/frontend/vue_shared/components/web_ide_link_spec.js
index 5589cbfd08f..e79935f8fa6 100644
--- a/spec/frontend/vue_shared/components/web_ide_link_spec.js
+++ b/spec/frontend/vue_shared/components/web_ide_link_spec.js
@@ -12,6 +12,7 @@ import { shallowMountExtended, mountExtended } from 'helpers/vue_test_utils_help
const TEST_EDIT_URL = '/gitlab-test/test/-/edit/main/';
const TEST_WEB_IDE_URL = '/-/ide/project/gitlab-test/test/edit/main/-/';
const TEST_GITPOD_URL = 'https://gitpod.test/';
+const TEST_PIPELINE_EDITOR_URL = '/-/ci/editor?branch_name="main"';
const TEST_USER_PREFERENCES_GITPOD_PATH = '/-/profile/preferences#user_gitpod_enabled';
const TEST_USER_PROFILE_ENABLE_GITPOD_PATH = '/-/profile?user%5Bgitpod_enabled%5D=true';
const forkPath = '/some/fork/path';
@@ -66,6 +67,16 @@ const ACTION_GITPOD_ENABLE = {
href: undefined,
handle: expect.any(Function),
};
+const ACTION_PIPELINE_EDITOR = {
+ href: TEST_PIPELINE_EDITOR_URL,
+ key: 'pipeline_editor',
+ secondaryText: 'Edit, lint, and visualize your pipeline.',
+ tooltip: 'Edit, lint, and visualize your pipeline.',
+ text: 'Edit in pipeline editor',
+ attrs: {
+ 'data-qa-selector': 'pipeline_editor_button',
+ },
+};
describe('Web IDE link component', () => {
let wrapper;
@@ -76,6 +87,7 @@ describe('Web IDE link component', () => {
editUrl: TEST_EDIT_URL,
webIdeUrl: TEST_WEB_IDE_URL,
gitpodUrl: TEST_GITPOD_URL,
+ pipelineEditorUrl: TEST_PIPELINE_EDITOR_URL,
forkPath,
...props,
},
@@ -107,6 +119,10 @@ describe('Web IDE link component', () => {
expectedActions: [ACTION_WEB_IDE, ACTION_EDIT],
},
{
+ props: { showPipelineEditorButton: true },
+ expectedActions: [ACTION_PIPELINE_EDITOR, ACTION_WEB_IDE, ACTION_EDIT],
+ },
+ {
props: { webIdeText: 'Test Web IDE' },
expectedActions: [{ ...ACTION_WEB_IDE_EDIT_FORK, text: 'Test Web IDE' }, ACTION_EDIT],
},
@@ -193,12 +209,34 @@ describe('Web IDE link component', () => {
expect(findActionsButton().props('actions')).toEqual(expectedActions);
});
+ describe('when pipeline editor action is available', () => {
+ beforeEach(() => {
+ createComponent({
+ showEditButton: false,
+ showWebIdeButton: true,
+ showGitpodButton: true,
+ showPipelineEditorButton: true,
+ userPreferencesGitpodPath: TEST_USER_PREFERENCES_GITPOD_PATH,
+ userProfileEnableGitpodPath: TEST_USER_PROFILE_ENABLE_GITPOD_PATH,
+ gitpodEnabled: true,
+ });
+ });
+
+ it('selected Pipeline Editor by default', () => {
+ expect(findActionsButton().props()).toMatchObject({
+ actions: [ACTION_PIPELINE_EDITOR, ACTION_WEB_IDE, ACTION_GITPOD],
+ selectedKey: ACTION_PIPELINE_EDITOR.key,
+ });
+ });
+ });
+
describe('with multiple actions', () => {
beforeEach(() => {
createComponent({
showEditButton: false,
showWebIdeButton: true,
showGitpodButton: true,
+ showPipelineEditorButton: false,
userPreferencesGitpodPath: TEST_USER_PREFERENCES_GITPOD_PATH,
userProfileEnableGitpodPath: TEST_USER_PROFILE_ENABLE_GITPOD_PATH,
gitpodEnabled: true,
@@ -240,6 +278,7 @@ describe('Web IDE link component', () => {
props: {
showWebIdeButton: true,
showEditButton: false,
+ showPipelineEditorButton: false,
forkPath,
forkModalId: 'edit-modal',
},
@@ -249,6 +288,7 @@ describe('Web IDE link component', () => {
props: {
showWebIdeButton: false,
showEditButton: true,
+ showPipelineEditorButton: false,
forkPath,
forkModalId: 'webide-modal',
},
diff --git a/spec/frontend/vue_shared/issuable/show/components/issuable_title_spec.js b/spec/frontend/vue_shared/issuable/show/components/issuable_title_spec.js
index 93de6dbe306..11e3302d409 100644
--- a/spec/frontend/vue_shared/issuable/show/components/issuable_title_spec.js
+++ b/spec/frontend/vue_shared/issuable/show/components/issuable_title_spec.js
@@ -66,10 +66,12 @@ describe('IssuableTitle', () => {
});
await nextTick();
- const titleEl = wrapperWithTitle.find('h2');
+ const titleEl = wrapperWithTitle.find('[data-testid="title"]');
expect(titleEl.exists()).toBe(true);
- expect(titleEl.html()).toBe('<h2 dir="auto" class="title qa-title"><b>Sample</b> title</h2>');
+ expect(titleEl.html()).toBe(
+ '<h1 dir="auto" data-testid="title" class="title qa-title"><b>Sample</b> title</h1>',
+ );
wrapperWithTitle.destroy();
});
diff --git a/spec/frontend/work_items/components/work_item_detail_spec.js b/spec/frontend/work_items/components/work_item_detail_spec.js
new file mode 100644
index 00000000000..305f43ad8ba
--- /dev/null
+++ b/spec/frontend/work_items/components/work_item_detail_spec.js
@@ -0,0 +1,40 @@
+import { GlModal } from '@gitlab/ui';
+import { shallowMount } from '@vue/test-utils';
+import Vue from 'vue';
+import VueApollo from 'vue-apollo';
+import createMockApollo from 'helpers/mock_apollo_helper';
+import WorkItemTitle from '~/work_items/components/item_title.vue';
+import WorkItemDetailModal from '~/work_items/components/work_item_detail_modal.vue';
+import { resolvers } from '~/work_items/graphql/resolvers';
+
+describe('WorkItemDetailModal component', () => {
+ let wrapper;
+
+ Vue.use(VueApollo);
+
+ const findModal = () => wrapper.findComponent(GlModal);
+ const findWorkItemTitle = () => wrapper.findComponent(WorkItemTitle);
+
+ const createComponent = () => {
+ wrapper = shallowMount(WorkItemDetailModal, {
+ apolloProvider: createMockApollo([], resolvers),
+ propsData: { visible: true },
+ });
+ };
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ it('renders modal', () => {
+ createComponent();
+
+ expect(findModal().props()).toMatchObject({ visible: true });
+ });
+
+ it('renders work item title', () => {
+ createComponent();
+
+ expect(findWorkItemTitle().exists()).toBe(true);
+ });
+});
diff --git a/spec/frontend/work_items/mock_data.js b/spec/frontend/work_items/mock_data.js
index a98722bc465..832795fc4ac 100644
--- a/spec/frontend/work_items/mock_data.js
+++ b/spec/frontend/work_items/mock_data.js
@@ -1,8 +1,12 @@
export const workItemQueryResponse = {
workItem: {
- __typename: 'LocalWorkItem',
+ __typename: 'WorkItem',
id: '1',
- type: 'FEATURE',
+ title: 'Test',
+ workItemType: {
+ __typename: 'WorkItemType',
+ id: 'work-item-type-1',
+ },
widgets: {
__typename: 'LocalWorkItemWidgetConnection',
nodes: [
@@ -17,20 +21,29 @@ export const workItemQueryResponse = {
};
export const updateWorkItemMutationResponse = {
- __typename: 'LocalUpdateWorkItemPayload',
- workItem: {
- __typename: 'LocalWorkItem',
- id: '1',
- widgets: {
- __typename: 'LocalWorkItemWidgetConnection',
- nodes: [
- {
- __typename: 'LocalTitleWidget',
- type: 'TITLE',
- enabled: true,
- contentText: 'Updated title',
+ data: {
+ workItemUpdate: {
+ __typename: 'LocalUpdateWorkItemPayload',
+ workItem: {
+ __typename: 'LocalWorkItem',
+ id: '1',
+ title: 'Updated title',
+ workItemType: {
+ __typename: 'WorkItemType',
+ id: 'work-item-type-1',
},
- ],
+ widgets: {
+ __typename: 'LocalWorkItemWidgetConnection',
+ nodes: [
+ {
+ __typename: 'LocalTitleWidget',
+ type: 'TITLE',
+ enabled: true,
+ contentText: 'Updated title',
+ },
+ ],
+ },
+ },
},
},
};
@@ -48,3 +61,20 @@ export const projectWorkItemTypesQueryResponse = {
},
},
};
+
+export const createWorkItemMutationResponse = {
+ data: {
+ workItemCreate: {
+ __typename: 'WorkItemCreatePayload',
+ workItem: {
+ __typename: 'WorkItem',
+ id: '1',
+ title: 'Updated title',
+ workItemType: {
+ __typename: 'WorkItemType',
+ id: 'work-item-type-1',
+ },
+ },
+ },
+ },
+};
diff --git a/spec/frontend/work_items/pages/create_work_item_spec.js b/spec/frontend/work_items/pages/create_work_item_spec.js
index b9fef0eaa6a..185b05c5191 100644
--- a/spec/frontend/work_items/pages/create_work_item_spec.js
+++ b/spec/frontend/work_items/pages/create_work_item_spec.js
@@ -8,7 +8,10 @@ import CreateWorkItem from '~/work_items/pages/create_work_item.vue';
import ItemTitle from '~/work_items/components/item_title.vue';
import { resolvers } from '~/work_items/graphql/resolvers';
import projectWorkItemTypesQuery from '~/work_items/graphql/project_work_item_types.query.graphql';
-import { projectWorkItemTypesQueryResponse } from '../mock_data';
+import createWorkItemMutation from '~/work_items/graphql/create_work_item.mutation.graphql';
+import { projectWorkItemTypesQueryResponse, createWorkItemMutationResponse } from '../mock_data';
+
+jest.mock('~/lib/utils/uuids', () => ({ uuids: () => ['testuuid'] }));
Vue.use(VueApollo);
@@ -17,6 +20,7 @@ describe('Create work item component', () => {
let fakeApollo;
const querySuccessHandler = jest.fn().mockResolvedValue(projectWorkItemTypesQueryResponse);
+ const mutationSuccessHandler = jest.fn().mockResolvedValue(createWorkItemMutationResponse);
const findAlert = () => wrapper.findComponent(GlAlert);
const findTitleInput = () => wrapper.findComponent(ItemTitle);
@@ -28,8 +32,19 @@ describe('Create work item component', () => {
const findContent = () => wrapper.find('[data-testid="content"]');
const findLoadingTypesIcon = () => wrapper.find('[data-testid="loading-types"]');
- const createComponent = ({ data = {}, props = {}, queryHandler = querySuccessHandler } = {}) => {
- fakeApollo = createMockApollo([[projectWorkItemTypesQuery, queryHandler]], resolvers);
+ const createComponent = ({
+ data = {},
+ props = {},
+ queryHandler = querySuccessHandler,
+ mutationHandler = mutationSuccessHandler,
+ } = {}) => {
+ fakeApollo = createMockApollo(
+ [
+ [projectWorkItemTypesQuery, queryHandler],
+ [createWorkItemMutation, mutationHandler],
+ ],
+ resolvers,
+ );
wrapper = shallowMount(CreateWorkItem, {
apolloProvider: fakeApollo,
data() {
@@ -124,7 +139,8 @@ describe('Create work item component', () => {
wrapper.find('form').trigger('submit');
await waitForPromises();
- expect(wrapper.emitted('onCreate')).toEqual([[mockTitle]]);
+ const expected = { id: '1', title: mockTitle };
+ expect(wrapper.emitted('onCreate')).toEqual([[expected]]);
});
it('does not right margin for create button', () => {
diff --git a/spec/frontend/work_items/pages/work_item_root_spec.js b/spec/frontend/work_items/pages/work_item_root_spec.js
index d0e40680b55..728495e0e23 100644
--- a/spec/frontend/work_items/pages/work_item_root_spec.js
+++ b/spec/frontend/work_items/pages/work_item_root_spec.js
@@ -9,11 +9,12 @@ import updateWorkItemMutation from '~/work_items/graphql/update_work_item.mutati
import WorkItemsRoot from '~/work_items/pages/work_item_root.vue';
import ItemTitle from '~/work_items/components/item_title.vue';
import { resolvers } from '~/work_items/graphql/resolvers';
-import { workItemQueryResponse } from '../mock_data';
+import { workItemQueryResponse, updateWorkItemMutationResponse } from '../mock_data';
Vue.use(VueApollo);
const WORK_ITEM_ID = '1';
+const WORK_ITEM_GID = `gid://gitlab/WorkItem/${WORK_ITEM_ID}`;
describe('Work items root component', () => {
const mockUpdatedTitle = 'Updated title';
@@ -23,15 +24,19 @@ describe('Work items root component', () => {
const findTitle = () => wrapper.findComponent(ItemTitle);
const createComponent = ({ queryResponse = workItemQueryResponse } = {}) => {
- fakeApollo = createMockApollo([], resolvers, {
- possibleTypes: {
- LocalWorkItemWidget: ['LocalTitleWidget'],
+ fakeApollo = createMockApollo(
+ [[updateWorkItemMutation, jest.fn().mockResolvedValue(updateWorkItemMutationResponse)]],
+ resolvers,
+ {
+ possibleTypes: {
+ LocalWorkItemWidget: ['LocalTitleWidget'],
+ },
},
- });
+ );
fakeApollo.clients.defaultClient.cache.writeQuery({
query: workItemQuery,
variables: {
- id: WORK_ITEM_ID,
+ id: WORK_ITEM_GID,
},
data: queryResponse,
});
@@ -49,7 +54,7 @@ describe('Work items root component', () => {
fakeApollo = null;
});
- it('renders the title if title is in the widgets list', () => {
+ it('renders the title', () => {
createComponent();
expect(findTitle().exists()).toBe(true);
@@ -66,35 +71,11 @@ describe('Work items root component', () => {
mutation: updateWorkItemMutation,
variables: {
input: {
- id: WORK_ITEM_ID,
+ id: WORK_ITEM_GID,
title: mockUpdatedTitle,
},
},
});
-
- await waitForPromises();
- expect(findTitle().props('initialTitle')).toBe(mockUpdatedTitle);
- });
-
- it('does not render the title if title is not in the widgets list', () => {
- const queryResponse = {
- workItem: {
- ...workItemQueryResponse.workItem,
- widgets: {
- __typename: 'WorkItemWidgetConnection',
- nodes: [
- {
- __typename: 'SomeOtherWidget',
- type: 'OTHER',
- contentText: 'Test',
- },
- ],
- },
- },
- };
- createComponent({ queryResponse });
-
- expect(findTitle().exists()).toBe(false);
});
describe('tracking', () => {
diff --git a/spec/frontend/work_items/router_spec.js b/spec/frontend/work_items/router_spec.js
index c583b5a5d4f..8c9054920a8 100644
--- a/spec/frontend/work_items/router_spec.js
+++ b/spec/frontend/work_items/router_spec.js
@@ -21,6 +21,7 @@ describe('Work items router', () => {
mocks: {
$apollo: {
queries: {
+ workItem: {},
workItemTypes: {},
},
},
diff --git a/spec/frontend_integration/ide/helpers/ide_helper.js b/spec/frontend_integration/ide/helpers/ide_helper.js
index 54a522324f5..00ce39a5598 100644
--- a/spec/frontend_integration/ide/helpers/ide_helper.js
+++ b/spec/frontend_integration/ide/helpers/ide_helper.js
@@ -106,7 +106,7 @@ const fillFileNameModal = async (value, submitText = 'Create file') => {
const nameField = await findByTestId(modal, 'file-name-field');
fireEvent.input(nameField, { target: { value } });
- const createButton = getByText(modal, submitText, { selector: 'button' });
+ const createButton = getByText(modal, submitText, { selector: 'button > span' });
createButton.click();
};
diff --git a/spec/graphql/mutations/boards/issues/issue_move_list_spec.rb b/spec/graphql/mutations/boards/issues/issue_move_list_spec.rb
index dd9305d2197..11c0fa44110 100644
--- a/spec/graphql/mutations/boards/issues/issue_move_list_spec.rb
+++ b/spec/graphql/mutations/boards/issues/issue_move_list_spec.rb
@@ -43,11 +43,10 @@ RSpec.describe Mutations::Boards::Issues::IssueMoveList do
context "when we only pass #{arg_name}" do
let(:move_params) { { arg_name => list1.id } }
- it 'raises an error' do
- expect { subject }.to raise_error(
- Gitlab::Graphql::Errors::ArgumentError,
- 'Both fromListId and toListId must be present'
- )
+ it 'generates an error' do
+ expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ArgumentError, 'Both fromListId and toListId must be present') do
+ subject
+ end
end
end
end
@@ -55,11 +54,10 @@ RSpec.describe Mutations::Boards::Issues::IssueMoveList do
context 'when required arguments are missing' do
let(:move_params) { {} }
- it 'raises an error' do
- expect { subject }.to raise_error(
- Gitlab::Graphql::Errors::ArgumentError,
- "At least one of the arguments fromListId, toListId, afterId or beforeId is required"
- )
+ it 'generates an error' do
+ expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ArgumentError, 'At least one of the arguments fromListId, toListId, afterId or beforeId is required') do
+ subject
+ end
end
end
diff --git a/spec/graphql/mutations/ci/runner/delete_spec.rb b/spec/graphql/mutations/ci/runner/delete_spec.rb
index b53ee30f826..c0f979e43cc 100644
--- a/spec/graphql/mutations/ci/runner/delete_spec.rb
+++ b/spec/graphql/mutations/ci/runner/delete_spec.rb
@@ -6,8 +6,9 @@ RSpec.describe Mutations::Ci::Runner::Delete do
include GraphqlHelpers
let_it_be(:runner) { create(:ci_runner) }
+ let_it_be(:admin_user) { create(:user, :admin) }
+ let_it_be(:user) { create(:user) }
- let(:user) { create(:user) }
let(:current_ctx) { { current_user: user } }
let(:mutation_params) do
@@ -22,15 +23,29 @@ RSpec.describe Mutations::Ci::Runner::Delete do
end
context 'when the user cannot admin the runner' do
- it 'raises an error' do
- expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
+ it 'generates an error' do
+ expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ResourceNotAvailable) do
+ subject
+ end
+ end
+
+ context 'with more than one associated project' do
+ let!(:project) { create(:project, creator_id: user.id) }
+ let!(:project2) { create(:project, creator_id: user.id) }
+ let!(:two_projects_runner) { create(:ci_runner, :project, description: 'Two projects runner', projects: [project, project2]) }
+
+ it 'raises an error' do
+ mutation_params[:id] = two_projects_runner.to_global_id
+
+ expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
+ end
end
end
context 'with invalid params' do
- it 'raises an error' do
- mutation_params[:id] = "invalid-id"
+ let(:mutation_params) { { id: "invalid-id" } }
+ it 'raises an error' do
expect { subject }.to raise_error(::GraphQL::CoercionError)
end
end
@@ -44,6 +59,8 @@ RSpec.describe Mutations::Ci::Runner::Delete do
end
context 'when user can delete owned runner' do
+ let_it_be(:user) { create(:user) }
+
let!(:project) { create(:project, creator_id: user.id) }
let!(:project_runner) { create(:ci_runner, :project, description: 'Project runner', projects: [project]) }
@@ -52,10 +69,12 @@ RSpec.describe Mutations::Ci::Runner::Delete do
end
context 'with one associated project' do
- it 'deletes runner' do
- mutation_params[:id] = project_runner.to_global_id
+ let(:mutation_params) do
+ { id: project_runner.to_global_id }
+ end
- expect_next_instance_of(::Ci::UnregisterRunnerService, project_runner) do |service|
+ it 'deletes runner' do
+ expect_next_instance_of(::Ci::Runners::UnregisterRunnerService, project_runner, current_ctx[:current_user]) do |service|
expect(service).to receive(:execute).once.and_call_original
end
@@ -68,28 +87,45 @@ RSpec.describe Mutations::Ci::Runner::Delete do
let!(:project2) { create(:project, creator_id: user.id) }
let!(:two_projects_runner) { create(:ci_runner, :project, description: 'Two projects runner', projects: [project, project2]) }
- before do
- project2.add_maintainer(user)
+ let(:mutation_params) do
+ { id: two_projects_runner.to_global_id }
end
- it 'does not delete project runner' do
- mutation_params[:id] = two_projects_runner.to_global_id
+ context 'with user as admin', :enable_admin_mode do
+ let(:current_ctx) { { current_user: admin_user } }
+
+ it 'deletes runner' do
+ expect_next_instance_of(::Ci::Runners::UnregisterRunnerService, two_projects_runner, current_ctx[:current_user]) do |service|
+ expect(service).to receive(:execute).once.and_call_original
+ end
+
+ expect { subject }.to change { Ci::Runner.count }.by(-1)
+ expect(subject[:errors]).to be_empty
+ end
+ end
+
+ context 'with user as project maintainer' do
+ let_it_be(:user) { create(:user) }
+
+ before do
+ project2.add_maintainer(user)
+ end
- allow_next_instance_of(::Ci::UnregisterRunnerService) do |service|
- expect(service).not_to receive(:execute).once
+ it 'raises error' do
+ allow_next_instance_of(::Ci::Runners::UnregisterRunnerService) do |service|
+ expect(service).not_to receive(:execute)
+ end
+ expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
end
- expect { subject }.not_to change { Ci::Runner.count }
- expect(subject[:errors]).to contain_exactly("Runner #{two_projects_runner.to_global_id} associated with more than one project")
end
end
end
context 'when admin can delete runner', :enable_admin_mode do
- let(:admin_user) { create(:user, :admin) }
let(:current_ctx) { { current_user: admin_user } }
it 'deletes runner' do
- expect_next_instance_of(::Ci::UnregisterRunnerService, runner) do |service|
+ expect_next_instance_of(::Ci::Runners::UnregisterRunnerService, runner, current_ctx[:current_user]) do |service|
expect(service).to receive(:execute).once.and_call_original
end
diff --git a/spec/graphql/mutations/ci/runner/update_spec.rb b/spec/graphql/mutations/ci/runner/update_spec.rb
index 83150c3d7f6..0b3489d37dc 100644
--- a/spec/graphql/mutations/ci/runner/update_spec.rb
+++ b/spec/graphql/mutations/ci/runner/update_spec.rb
@@ -26,8 +26,10 @@ RSpec.describe Mutations::Ci::Runner::Update do
end
context 'when the user cannot admin the runner' do
- it 'raises an error' do
- expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
+ it 'generates an error' do
+ expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ResourceNotAvailable) do
+ subject
+ end
end
end
diff --git a/spec/graphql/mutations/release_asset_links/create_spec.rb b/spec/graphql/mutations/release_asset_links/create_spec.rb
index eb7cbb4b789..86a6c77fa3f 100644
--- a/spec/graphql/mutations/release_asset_links/create_spec.rb
+++ b/spec/graphql/mutations/release_asset_links/create_spec.rb
@@ -63,7 +63,9 @@ RSpec.describe Mutations::ReleaseAssetLinks::Create do
let!(:protected_tag) { create(:protected_tag, :maintainers_can_create, name: '*', project: project) }
it 'has an access error' do
- expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
+ expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ResourceNotAvailable) do
+ subject
+ end
end
end
end
@@ -71,16 +73,20 @@ RSpec.describe Mutations::ReleaseAssetLinks::Create do
context "when the user doesn't have access to the project" do
let(:current_user) { reporter }
- it 'raises an error' do
- expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
+ it 'generates an error' do
+ expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ResourceNotAvailable) do
+ subject
+ end
end
end
context "when the project doesn't exist" do
let(:project_path) { 'project/that/does/not/exist' }
- it 'raises an error' do
- expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
+ it 'generates an error' do
+ expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ResourceNotAvailable) do
+ subject
+ end
end
end
diff --git a/spec/graphql/mutations/saved_replies/create_spec.rb b/spec/graphql/mutations/saved_replies/create_spec.rb
new file mode 100644
index 00000000000..5141c537b06
--- /dev/null
+++ b/spec/graphql/mutations/saved_replies/create_spec.rb
@@ -0,0 +1,46 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Mutations::SavedReplies::Create do
+ let_it_be(:current_user) { create(:user) }
+
+ let(:mutation) { described_class.new(object: nil, context: { current_user: current_user }, field: nil) }
+
+ let(:mutation_arguments) { { name: 'save_reply_name', content: 'Save Reply Content' } }
+
+ describe '#resolve' do
+ subject(:resolve) do
+ mutation.resolve(**mutation_arguments)
+ end
+
+ context 'when feature is disabled' do
+ before do
+ stub_feature_flags(saved_replies: false)
+ end
+
+ it 'raises Gitlab::Graphql::Errors::ResourceNotAvailable' do
+ expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable, 'Feature disabled')
+ end
+ end
+
+ context 'when feature is enabled for current user' do
+ before do
+ stub_feature_flags(saved_replies: current_user)
+ end
+
+ context 'when service fails to create a new saved reply' do
+ let(:mutation_arguments) { { name: '', content: '' } }
+
+ it { expect(subject[:saved_reply]).to be_nil }
+ it { expect(subject[:errors]).to match_array(["Content can't be blank", "Name can't be blank", "Name can contain only lowercase letters, digits, '_' and '-'. Must start with a letter, and cannot end with '-' or '_'"]) }
+ end
+
+ context 'when service successfully creates a new saved reply' do
+ it { expect(subject[:saved_reply].name).to eq(mutation_arguments[:name]) }
+ it { expect(subject[:saved_reply].content).to eq(mutation_arguments[:content]) }
+ it { expect(subject[:errors]).to be_empty }
+ end
+ end
+ end
+end
diff --git a/spec/graphql/mutations/saved_replies/update_spec.rb b/spec/graphql/mutations/saved_replies/update_spec.rb
new file mode 100644
index 00000000000..67c2d1348f7
--- /dev/null
+++ b/spec/graphql/mutations/saved_replies/update_spec.rb
@@ -0,0 +1,47 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Mutations::SavedReplies::Update do
+ let_it_be(:current_user) { create(:user) }
+ let_it_be(:saved_reply) { create(:saved_reply, user: current_user) }
+
+ let(:mutation) { described_class.new(object: nil, context: { current_user: current_user }, field: nil) }
+
+ let(:mutation_arguments) { { name: 'save_reply_name', content: 'Save Reply Content' } }
+
+ describe '#resolve' do
+ subject(:resolve) do
+ mutation.resolve(id: saved_reply.to_global_id, **mutation_arguments)
+ end
+
+ context 'when feature is disabled' do
+ before do
+ stub_feature_flags(saved_replies: false)
+ end
+
+ it 'raises Gitlab::Graphql::Errors::ResourceNotAvailable' do
+ expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable, 'Feature disabled')
+ end
+ end
+
+ context 'when feature is enabled for current user' do
+ before do
+ stub_feature_flags(saved_replies: current_user)
+ end
+
+ context 'when service fails to update a new saved reply' do
+ let(:mutation_arguments) { { name: '', content: '' } }
+
+ it { expect(subject[:saved_reply]).to be_nil }
+ it { expect(subject[:errors]).to match_array(["Content can't be blank", "Name can't be blank", "Name can contain only lowercase letters, digits, '_' and '-'. Must start with a letter, and cannot end with '-' or '_'"]) }
+ end
+
+ context 'when service successfully updates the saved reply' do
+ it { expect(subject[:saved_reply].name).to eq(mutation_arguments[:name]) }
+ it { expect(subject[:saved_reply].content).to eq(mutation_arguments[:content]) }
+ it { expect(subject[:errors]).to be_empty }
+ end
+ end
+ end
+end
diff --git a/spec/graphql/resolvers/admin/analytics/usage_trends/measurements_resolver_spec.rb b/spec/graphql/resolvers/admin/analytics/usage_trends/measurements_resolver_spec.rb
index b63eca4359d..6b5e351a610 100644
--- a/spec/graphql/resolvers/admin/analytics/usage_trends/measurements_resolver_spec.rb
+++ b/spec/graphql/resolvers/admin/analytics/usage_trends/measurements_resolver_spec.rb
@@ -31,16 +31,20 @@ RSpec.describe Resolvers::Admin::Analytics::UsageTrends::MeasurementsResolver do
context 'as a non-admin user' do
let(:current_user) { user }
- it 'raises ResourceNotAvailable error' do
- expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
+ it 'generates a ResourceNotAvailable error' do
+ expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ResourceNotAvailable) do
+ subject
+ end
end
end
context 'as an unauthenticated user' do
let(:current_user) { nil }
- it 'raises ResourceNotAvailable error' do
- expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
+ it 'generates a ResourceNotAvailable error' do
+ expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ResourceNotAvailable) do
+ subject
+ end
end
end
diff --git a/spec/graphql/resolvers/base_resolver_spec.rb b/spec/graphql/resolvers/base_resolver_spec.rb
index d77a0b6242e..39b00c14161 100644
--- a/spec/graphql/resolvers/base_resolver_spec.rb
+++ b/spec/graphql/resolvers/base_resolver_spec.rb
@@ -239,16 +239,16 @@ RSpec.describe Resolvers::BaseResolver do
it 'increases complexity based on arguments' do
field = Types::BaseField.new(name: 'test', type: GraphQL::Types::String.connection_type, resolver_class: described_class, null: false, max_page_size: 1)
- expect(field.to_graphql.complexity.call({}, { sort: 'foo' }, 1)).to eq 3
- expect(field.to_graphql.complexity.call({}, { search: 'foo' }, 1)).to eq 7
+ expect(field.complexity.call({}, { sort: 'foo' }, 1)).to eq 3
+ expect(field.complexity.call({}, { search: 'foo' }, 1)).to eq 7
end
it 'does not increase complexity when filtering by iids' do
field = Types::BaseField.new(name: 'test', type: GraphQL::Types::String.connection_type, resolver_class: described_class, null: false, max_page_size: 100)
- expect(field.to_graphql.complexity.call({}, { sort: 'foo' }, 1)).to eq 6
- expect(field.to_graphql.complexity.call({}, { sort: 'foo', iid: 1 }, 1)).to eq 3
- expect(field.to_graphql.complexity.call({}, { sort: 'foo', iids: [1, 2, 3] }, 1)).to eq 3
+ expect(field.complexity.call({}, { sort: 'foo' }, 1)).to eq 6
+ expect(field.complexity.call({}, { sort: 'foo', iid: 1 }, 1)).to eq 3
+ expect(field.complexity.call({}, { sort: 'foo', iids: [1, 2, 3] }, 1)).to eq 3
end
end
diff --git a/spec/graphql/resolvers/blobs_resolver_spec.rb b/spec/graphql/resolvers/blobs_resolver_spec.rb
index bc0344796ee..4b75351147c 100644
--- a/spec/graphql/resolvers/blobs_resolver_spec.rb
+++ b/spec/graphql/resolvers/blobs_resolver_spec.rb
@@ -26,8 +26,10 @@ RSpec.describe Resolvers::BlobsResolver do
subject(:resolve_blobs) { resolve(described_class, obj: repository, args: args, ctx: { current_user: user }) }
context 'when unauthorized' do
- it 'raises an exception' do
- expect { resolve_blobs }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
+ it 'generates an error' do
+ expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ResourceNotAvailable) do
+ resolve_blobs
+ end
end
end
@@ -68,6 +70,28 @@ RSpec.describe Resolvers::BlobsResolver do
)
end
end
+
+ context 'when specifying an invalid ref' do
+ let(:ref) { 'ma:in' }
+
+ it 'raises an ArgumentError' do
+ expect { resolve_blobs }.to raise_error(
+ Gitlab::Graphql::Errors::ArgumentError,
+ 'Ref is not valid'
+ )
+ end
+ end
+
+ context 'when passing an empty ref' do
+ let(:ref) { '' }
+
+ it 'raises an ArgumentError' do
+ expect { resolve_blobs }.to raise_error(
+ Gitlab::Graphql::Errors::ArgumentError,
+ 'Ref is not valid'
+ )
+ end
+ end
end
end
end
diff --git a/spec/graphql/resolvers/board_list_issues_resolver_spec.rb b/spec/graphql/resolvers/board_list_issues_resolver_spec.rb
index 6907c55bd48..392385d2a30 100644
--- a/spec/graphql/resolvers/board_list_issues_resolver_spec.rb
+++ b/spec/graphql/resolvers/board_list_issues_resolver_spec.rb
@@ -25,10 +25,10 @@ RSpec.describe Resolvers::BoardListIssuesResolver do
let(:wildcard_started) { 'STARTED' }
let(:filters) { { milestone_title: ["started"], milestone_wildcard_id: wildcard_started } }
- it 'raises a mutually exclusive filter error when milestone wildcard and title are provided' do
- expect do
+ it 'generates a mutually exclusive filter error when milestone wildcard and title are provided' do
+ expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ArgumentError) do
resolve_board_list_issues(args: { filters: filters })
- end.to raise_error(Gitlab::Graphql::Errors::ArgumentError)
+ end
end
it 'returns the issues in the correct order' do
@@ -63,10 +63,10 @@ RSpec.describe Resolvers::BoardListIssuesResolver do
expect(result).to contain_exactly(incident)
end
- it 'raises an exception if both assignee_username and assignee_wildcard_id are present' do
- expect do
+ it 'generates an error if both assignee_username and assignee_wildcard_id are present' do
+ expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ArgumentError) do
resolve_board_list_issues(args: { filters: { assignee_username: ['username'], assignee_wildcard_id: 'NONE' } })
- end.to raise_error(Gitlab::Graphql::Errors::ArgumentError)
+ end
end
it 'accepts assignee wildcard id NONE' do
diff --git a/spec/graphql/resolvers/board_lists_resolver_spec.rb b/spec/graphql/resolvers/board_lists_resolver_spec.rb
index fdcebd30bb3..7a1d8590546 100644
--- a/spec/graphql/resolvers/board_lists_resolver_spec.rb
+++ b/spec/graphql/resolvers/board_lists_resolver_spec.rb
@@ -74,9 +74,10 @@ RSpec.describe Resolvers::BoardListsResolver do
expect(list).to eq List.none
end
- it 'raises an argument error if list ID is not valid' do
- expect { resolve_board_lists(args: { id: 'test' }) }
- .to raise_error(Gitlab::Graphql::Errors::ArgumentError)
+ it 'generates an error if list ID is not valid' do
+ expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ArgumentError) do
+ resolve_board_lists(args: { id: 'test' })
+ end
end
end
end
diff --git a/spec/graphql/resolvers/board_resolver_spec.rb b/spec/graphql/resolvers/board_resolver_spec.rb
index e9c51a536ee..51a13850366 100644
--- a/spec/graphql/resolvers/board_resolver_spec.rb
+++ b/spec/graphql/resolvers/board_resolver_spec.rb
@@ -23,9 +23,9 @@ RSpec.describe Resolvers::BoardResolver do
end
it 'requires an ID' do
- expect do
+ expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ArgumentError) do
resolve(described_class, obj: board_parent, args: {}, ctx: { current_user: user })
- end.to raise_error(Gitlab::Graphql::Errors::ArgumentError)
+ end
end
context 'when querying for a single board' do
diff --git a/spec/graphql/resolvers/ci/config_resolver_spec.rb b/spec/graphql/resolvers/ci/config_resolver_spec.rb
index 97eee749290..3ff6d8f4347 100644
--- a/spec/graphql/resolvers/ci/config_resolver_spec.rb
+++ b/spec/graphql/resolvers/ci/config_resolver_spec.rb
@@ -6,16 +6,24 @@ RSpec.describe Resolvers::Ci::ConfigResolver do
include GraphqlHelpers
describe '#resolve' do
- before do
+ let_it_be(:user) { create(:user) }
+ let_it_be(:project) { create(:project, :repository, creator: user, namespace: user.namespace) }
+ let_it_be(:sha) { nil }
+
+ let_it_be(:content) do
+ File.read(Rails.root.join('spec/support/gitlab_stubs/gitlab_ci_includes.yml'))
+ end
+
+ let(:ci_lint) do
ci_lint_double = instance_double(::Gitlab::Ci::Lint)
allow(ci_lint_double).to receive(:validate).and_return(fake_result)
- allow(::Gitlab::Ci::Lint).to receive(:new).and_return(ci_lint_double)
+ ci_lint_double
end
- let_it_be(:user) { create(:user) }
- let_it_be(:project) { create(:project, :repository, creator: user, namespace: user.namespace) }
- let_it_be(:sha) { nil }
+ before do
+ allow(::Gitlab::Ci::Lint).to receive(:new).and_return(ci_lint)
+ end
subject(:response) do
resolve(described_class,
@@ -33,10 +41,6 @@ RSpec.describe Resolvers::Ci::ConfigResolver do
)
end
- let_it_be(:content) do
- File.read(Rails.root.join('spec/support/gitlab_stubs/gitlab_ci_includes.yml'))
- end
-
it 'lints the ci config file and returns the merged yaml file' do
expect(response[:status]).to eq(:valid)
expect(response[:merged_yaml]).to eq(content)
@@ -74,5 +78,23 @@ RSpec.describe Resolvers::Ci::ConfigResolver do
expect(response[:errors]).to eq(['Invalid configuration format'])
end
end
+
+ context 'with an invalid SHA' do
+ let_it_be(:sha) { ':' }
+
+ let(:ci_lint) do
+ ci_lint_double = instance_double(::Gitlab::Ci::Lint)
+ allow(ci_lint_double).to receive(:validate).and_raise(GRPC::InvalidArgument)
+
+ ci_lint_double
+ end
+
+ it 'logs the invalid SHA to Sentry' do
+ expect(Gitlab::ErrorTracking).to receive(:track_and_raise_exception)
+ .with(GRPC::InvalidArgument, sha: ':')
+
+ response
+ end
+ end
end
end
diff --git a/spec/graphql/resolvers/ci/job_token_scope_resolver_spec.rb b/spec/graphql/resolvers/ci/job_token_scope_resolver_spec.rb
index 8522542498d..59616815de0 100644
--- a/spec/graphql/resolvers/ci/job_token_scope_resolver_spec.rb
+++ b/spec/graphql/resolvers/ci/job_token_scope_resolver_spec.rb
@@ -54,10 +54,8 @@ RSpec.describe Resolvers::Ci::JobTokenScopeResolver do
project.add_user(current_user, :developer)
end
- it 'raises error' do
- expect do
- resolve_scope
- end.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
+ it 'generates an error' do
+ expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ResourceNotAvailable) { resolve_scope }
end
end
end
diff --git a/spec/graphql/resolvers/concerns/resolves_pipelines_spec.rb b/spec/graphql/resolvers/concerns/resolves_pipelines_spec.rb
index 9fe4c78f551..4c4aa4f53e1 100644
--- a/spec/graphql/resolvers/concerns/resolves_pipelines_spec.rb
+++ b/spec/graphql/resolvers/concerns/resolves_pipelines_spec.rb
@@ -15,7 +15,7 @@ RSpec.describe ResolvesPipelines do
end
end
- let(:current_user) { create(:user) }
+ let_it_be(:current_user) { create(:user) }
let_it_be(:project) { create(:project, :private) }
let_it_be(:pipeline) { create(:ci_pipeline, project: project) }
@@ -23,13 +23,15 @@ RSpec.describe ResolvesPipelines do
let_it_be(:success_pipeline) { create(:ci_pipeline, :success, project: project) }
let_it_be(:ref_pipeline) { create(:ci_pipeline, project: project, ref: 'awesome-feature') }
let_it_be(:sha_pipeline) { create(:ci_pipeline, project: project, sha: 'deadbeef') }
+ let_it_be(:username_pipeline) { create(:ci_pipeline, project: project, user: current_user) }
let_it_be(:all_pipelines) do
[
pipeline,
failed_pipeline,
success_pipeline,
ref_pipeline,
- sha_pipeline
+ sha_pipeline,
+ username_pipeline
]
end
@@ -37,7 +39,7 @@ RSpec.describe ResolvesPipelines do
project.add_developer(current_user)
end
- it { is_expected.to have_graphql_arguments(:status, :scope, :ref, :sha, :source) }
+ it { is_expected.to have_graphql_arguments(:status, :scope, :ref, :sha, :source, :updated_after, :updated_before, :username) }
it 'finds all pipelines' do
expect(resolve_pipelines).to contain_exactly(*all_pipelines)
@@ -71,6 +73,32 @@ RSpec.describe ResolvesPipelines do
end
end
+ it 'allows filtering by username' do
+ expect(resolve_pipelines(username: current_user.username)).to contain_exactly(username_pipeline)
+ end
+
+ context 'filtering by updated_at' do
+ let_it_be(:old_pipeline) { create(:ci_pipeline, project: project, updated_at: 2.days.ago) }
+ let_it_be(:older_pipeline) { create(:ci_pipeline, project: project, updated_at: 5.days.ago) }
+
+ it 'filters by updated_after' do
+ expect(resolve_pipelines(updated_after: 3.days.ago)).to contain_exactly(old_pipeline, *all_pipelines)
+ end
+
+ it 'filters by updated_before' do
+ expect(resolve_pipelines(updated_before: 3.days.ago)).to contain_exactly(older_pipeline)
+ end
+
+ it 'filters by both updated_after and updated_before with valid date range' do
+ expect(resolve_pipelines(updated_after: 10.days.ago, updated_before: 3.days.ago)).to contain_exactly(older_pipeline)
+ end
+
+ it 'filters by both updated_after and updated_before with invalid date range' do
+ # updated_after is before updated_before so result set is empty - impossible
+ expect(resolve_pipelines(updated_after: 3.days.ago, updated_before: 10.days.ago)).to be_empty
+ end
+ end
+
it 'does not return any pipelines if the user does not have access' do
expect(resolve_pipelines({}, {})).to be_empty
end
@@ -78,9 +106,9 @@ RSpec.describe ResolvesPipelines do
it 'increases field complexity based on arguments' do
field = Types::BaseField.new(name: 'test', type: GraphQL::Types::String, resolver_class: resolver, null: false, max_page_size: 1)
- expect(field.to_graphql.complexity.call({}, {}, 1)).to eq 2
- expect(field.to_graphql.complexity.call({}, { sha: 'foo' }, 1)).to eq 4
- expect(field.to_graphql.complexity.call({}, { sha: 'ref' }, 1)).to eq 4
+ expect(field.complexity.call({}, {}, 1)).to eq 2
+ expect(field.complexity.call({}, { sha: 'foo' }, 1)).to eq 4
+ expect(field.complexity.call({}, { sha: 'ref' }, 1)).to eq 4
end
def resolve_pipelines(args = {}, context = { current_user: current_user })
diff --git a/spec/graphql/resolvers/design_management/design_at_version_resolver_spec.rb b/spec/graphql/resolvers/design_management/design_at_version_resolver_spec.rb
index 4bdef49499c..a16e8821cb5 100644
--- a/spec/graphql/resolvers/design_management/design_at_version_resolver_spec.rb
+++ b/spec/graphql/resolvers/design_management/design_at_version_resolver_spec.rb
@@ -29,8 +29,10 @@ RSpec.describe Resolvers::DesignManagement::DesignAtVersionResolver do
context 'when the user cannot see designs' do
let(:current_user) { create(:user) }
- it 'raises ResourceNotAvailable' do
- expect { resolve_design }.to raise_error(resource_not_available)
+ it 'generates ResourceNotAvailable' do
+ expect_graphql_error_to_be_created(resource_not_available) do
+ resolve_design
+ end
end
end
@@ -45,8 +47,10 @@ RSpec.describe Resolvers::DesignManagement::DesignAtVersionResolver do
let(:global_id) { global_id_of(other_dav) }
- it 'raises ResourceNotAvailable' do
- expect { resolve_design }.to raise_error(resource_not_available)
+ it 'generates ResourceNotAvailable' do
+ expect_graphql_error_to_be_created(resource_not_available) do
+ resolve_design
+ end
end
context 'the current object does not constrain the issue' do
diff --git a/spec/graphql/resolvers/design_management/design_resolver_spec.rb b/spec/graphql/resolvers/design_management/design_resolver_spec.rb
index e33eaedf167..4c8b3116875 100644
--- a/spec/graphql/resolvers/design_management/design_resolver_spec.rb
+++ b/spec/graphql/resolvers/design_management/design_resolver_spec.rb
@@ -42,16 +42,20 @@ RSpec.describe Resolvers::DesignManagement::DesignResolver do
context 'when no argument has been passed' do
let(:args) { {} }
- it 'raises an error' do
- expect { resolve_design }.to raise_error(::Gitlab::Graphql::Errors::ArgumentError, /must/)
+ it 'generates an error' do
+ expect_graphql_error_to_be_created(::Gitlab::Graphql::Errors::ArgumentError, /must/) do
+ resolve_design
+ end
end
end
context 'when both arguments have been passed' do
let(:args) { { filename: first_design.filename, id: GitlabSchema.id_from_object(first_design).to_s } }
- it 'raises an error' do
- expect { resolve_design }.to raise_error(::Gitlab::Graphql::Errors::ArgumentError, /may/)
+ it 'generates an error' do
+ expect_graphql_error_to_be_created(::Gitlab::Graphql::Errors::ArgumentError, /may/) do
+ resolve_design
+ end
end
end
diff --git a/spec/graphql/resolvers/design_management/version/design_at_version_resolver_spec.rb b/spec/graphql/resolvers/design_management/version/design_at_version_resolver_spec.rb
index cc7e2f6814a..829227185c2 100644
--- a/spec/graphql/resolvers/design_management/version/design_at_version_resolver_spec.rb
+++ b/spec/graphql/resolvers/design_management/version/design_at_version_resolver_spec.rb
@@ -24,8 +24,10 @@ RSpec.describe Resolvers::DesignManagement::Version::DesignAtVersionResolver do
shared_examples 'a bad argument' do
let(:err_class) { ::Gitlab::Graphql::Errors::ArgumentError }
- it 'raises an appropriate error' do
- expect { resolve_objects }.to raise_error(err_class)
+ it 'generates an error' do
+ expect_graphql_error_to_be_created(err_class) do
+ resolve_objects
+ end
end
end
diff --git a/spec/graphql/resolvers/design_management/version_in_collection_resolver_spec.rb b/spec/graphql/resolvers/design_management/version_in_collection_resolver_spec.rb
index b0fc78af2af..8b9874c3580 100644
--- a/spec/graphql/resolvers/design_management/version_in_collection_resolver_spec.rb
+++ b/spec/graphql/resolvers/design_management/version_in_collection_resolver_spec.rb
@@ -26,8 +26,10 @@ RSpec.describe Resolvers::DesignManagement::VersionInCollectionResolver do
subject(:result) { resolve_version(issue.design_collection) }
context 'Neither id nor sha is passed as parameters' do
- it 'raises an appropriate error' do
- expect { result }.to raise_error(appropriate_error)
+ it 'generates an appropriate error' do
+ expect_graphql_error_to_be_created(appropriate_error) do
+ result
+ end
end
end
diff --git a/spec/graphql/resolvers/design_management/version_resolver_spec.rb b/spec/graphql/resolvers/design_management/version_resolver_spec.rb
index af1e6a73d09..ab1d7d4d9c5 100644
--- a/spec/graphql/resolvers/design_management/version_resolver_spec.rb
+++ b/spec/graphql/resolvers/design_management/version_resolver_spec.rb
@@ -22,8 +22,10 @@ RSpec.describe Resolvers::DesignManagement::VersionResolver do
context 'the current user is not authorized' do
let(:current_user) { create(:user) }
- it 'raises an error on resolution' do
- expect { resolve_version }.to raise_error(::Gitlab::Graphql::Errors::ResourceNotAvailable)
+ it 'generates an error on resolution' do
+ expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ResourceNotAvailable) do
+ resolve_version
+ end
end
end
diff --git a/spec/graphql/resolvers/design_management/versions_resolver_spec.rb b/spec/graphql/resolvers/design_management/versions_resolver_spec.rb
index 2c9c3a47650..d98138f6385 100644
--- a/spec/graphql/resolvers/design_management/versions_resolver_spec.rb
+++ b/spec/graphql/resolvers/design_management/versions_resolver_spec.rb
@@ -98,8 +98,10 @@ RSpec.describe Resolvers::DesignManagement::VersionsResolver do
}
end
- it 'raises a suitable error' do
- expect { result }.to raise_error(GraphQL::ExecutionError)
+ it 'generates a suitable error' do
+ expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ResourceNotAvailable) do
+ result
+ end
end
end
end
diff --git a/spec/graphql/resolvers/environments_resolver_spec.rb b/spec/graphql/resolvers/environments_resolver_spec.rb
index 6c999e5d0e7..9f4c4716de0 100644
--- a/spec/graphql/resolvers/environments_resolver_spec.rb
+++ b/spec/graphql/resolvers/environments_resolver_spec.rb
@@ -46,10 +46,10 @@ RSpec.describe Resolvers::EnvironmentsResolver do
expect(resolve_environments(states: ['available'])).to contain_exactly(environment1, environment3)
end
- it 'returns error if requested state is invalid' do
- expect { resolve_environments(states: ['invalid']) }.to(
- raise_error(Gitlab::Graphql::Errors::ArgumentError)
- )
+ it 'generates an error if requested state is invalid' do
+ expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ArgumentError) do
+ resolve_environments(states: ['invalid'])
+ end
end
end
diff --git a/spec/graphql/resolvers/group_issues_resolver_spec.rb b/spec/graphql/resolvers/group_issues_resolver_spec.rb
index e17429560ac..f5f6086cc09 100644
--- a/spec/graphql/resolvers/group_issues_resolver_spec.rb
+++ b/spec/graphql/resolvers/group_issues_resolver_spec.rb
@@ -86,10 +86,10 @@ RSpec.describe Resolvers::GroupIssuesResolver do
end
context 'release_tag filter' do
- it 'returns an error when trying to filter by negated release_tag' do
- expect do
+ it 'generates an error when trying to filter by negated release_tag' do
+ expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ArgumentError, 'releaseTag filter is not allowed when parent is a group.') do
resolve_issues(not: { release_tag: ['v1.0'] })
- end.to raise_error(Gitlab::Graphql::Errors::ArgumentError, 'releaseTag filter is not allowed when parent is a group.')
+ end
end
end
end
diff --git a/spec/graphql/resolvers/group_labels_resolver_spec.rb b/spec/graphql/resolvers/group_labels_resolver_spec.rb
index 3f4ad8760c0..2031e534703 100644
--- a/spec/graphql/resolvers/group_labels_resolver_spec.rb
+++ b/spec/graphql/resolvers/group_labels_resolver_spec.rb
@@ -27,8 +27,10 @@ RSpec.describe Resolvers::GroupLabelsResolver do
describe '#resolve' do
context 'with unauthorized user' do
- it 'raises error' do
- expect { resolve_labels(subgroup) }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
+ it 'generates an error' do
+ expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ResourceNotAvailable) do
+ resolve_labels(subgroup)
+ end
end
end
diff --git a/spec/graphql/resolvers/group_members/notification_email_resolver_spec.rb b/spec/graphql/resolvers/group_members/notification_email_resolver_spec.rb
new file mode 100644
index 00000000000..fcf67120b0e
--- /dev/null
+++ b/spec/graphql/resolvers/group_members/notification_email_resolver_spec.rb
@@ -0,0 +1,46 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Resolvers::GroupMembers::NotificationEmailResolver do
+ include GraphqlHelpers
+
+ describe '#resolve' do
+ let_it_be(:group) { create(:group) }
+ let_it_be(:developer) { create(:user) }
+
+ before do
+ group.add_developer(developer)
+ end
+
+ specify do
+ expect(described_class).to have_nullable_graphql_type(GraphQL::Types::String)
+ end
+
+ subject { batch_sync { resolve_notification_email(developer.group_members.first, current_user) }}
+
+ context 'when current_user is admin' do
+ let(:current_user) { create(:user, :admin) }
+
+ before do
+ allow(current_user).to receive(:can_admin_all_resources?).and_return(true)
+ end
+
+ it 'returns email' do
+ expect(subject).to eq(developer.email)
+ end
+ end
+
+ context 'when current_user is not admin' do
+ let(:current_user) { create(:user) }
+
+ it 'raises ResourceNotAvailable error' do
+ expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
+ end
+ end
+ end
+
+ def resolve_notification_email(obj, user)
+ resolve(described_class, obj: obj, ctx: { current_user: user })
+ end
+end
diff --git a/spec/graphql/resolvers/group_milestones_resolver_spec.rb b/spec/graphql/resolvers/group_milestones_resolver_spec.rb
index acfc8313407..7abc779a63c 100644
--- a/spec/graphql/resolvers/group_milestones_resolver_spec.rb
+++ b/spec/graphql/resolvers/group_milestones_resolver_spec.rb
@@ -101,38 +101,38 @@ RSpec.describe Resolvers::GroupMilestonesResolver do
context 'by timeframe' do
context 'when start_date and end_date are present' do
context 'when start date is after end_date' do
- it 'raises error' do
- expect do
+ it 'generates an error' do
+ expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ArgumentError, "startDate is after endDate") do
resolve_group_milestones(start_date: now, end_date: now - 2.days)
- end.to raise_error(Gitlab::Graphql::Errors::ArgumentError, "startDate is after endDate")
+ end
end
end
end
context 'when only start_date is present' do
- it 'raises error' do
- expect do
+ it 'generates an error' do
+ expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ArgumentError, /Both startDate and endDate/) do
resolve_group_milestones(start_date: now)
- end.to raise_error(Gitlab::Graphql::Errors::ArgumentError, /Both startDate and endDate/)
+ end
end
end
context 'when only end_date is present' do
- it 'raises error' do
- expect do
+ it 'generates an error' do
+ expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ArgumentError, /Both startDate and endDate/) do
resolve_group_milestones(end_date: now)
- end.to raise_error(Gitlab::Graphql::Errors::ArgumentError, /Both startDate and endDate/)
+ end
end
end
end
context 'when user cannot read milestones' do
- it 'raises error' do
+ it 'generates an error' do
unauthorized_user = create(:user)
- expect do
+ expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ResourceNotAvailable) do
resolve_group_milestones({}, { current_user: unauthorized_user })
- end.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
+ end
end
end
diff --git a/spec/graphql/resolvers/issue_status_counts_resolver_spec.rb b/spec/graphql/resolvers/issue_status_counts_resolver_spec.rb
index 3fbd9bd2368..77f4ce4cac5 100644
--- a/spec/graphql/resolvers/issue_status_counts_resolver_spec.rb
+++ b/spec/graphql/resolvers/issue_status_counts_resolver_spec.rb
@@ -70,10 +70,10 @@ RSpec.describe Resolvers::IssueStatusCountsResolver do
end
context 'when both assignee_username and assignee_usernames are provided' do
- it 'raises a mutually exclusive filter error' do
- expect do
+ it 'generates a mutually exclusive filter error' do
+ expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ArgumentError, 'only one of [assigneeUsernames, assigneeUsername] arguments is allowed at the same time.') do
resolve_issue_status_counts(assignee_usernames: [current_user.username], assignee_username: current_user.username)
- end.to raise_error(Gitlab::Graphql::Errors::ArgumentError, 'only one of [assigneeUsernames, assigneeUsername] arguments is allowed at the same time.')
+ end
end
end
diff --git a/spec/graphql/resolvers/issues_resolver_spec.rb b/spec/graphql/resolvers/issues_resolver_spec.rb
index dc717b113c1..5e9a3d0a68b 100644
--- a/spec/graphql/resolvers/issues_resolver_spec.rb
+++ b/spec/graphql/resolvers/issues_resolver_spec.rb
@@ -78,10 +78,10 @@ RSpec.describe Resolvers::IssuesResolver do
expect(resolve_issues(milestone_wildcard_id: wildcard_none)).to contain_exactly(issue2)
end
- it 'raises a mutually exclusive filter error when wildcard and title are provided' do
- expect do
+ it 'generates a mutually exclusive filter error when wildcard and title are provided' do
+ expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ArgumentError, 'only one of [milestoneTitle, milestoneWildcardId] arguments is allowed at the same time.') do
resolve_issues(milestone_title: ["started milestone"], milestone_wildcard_id: wildcard_started)
- end.to raise_error(Gitlab::Graphql::Errors::ArgumentError, 'only one of [milestoneTitle, milestoneWildcardId] arguments is allowed at the same time.')
+ end
end
context 'negated filtering' do
@@ -97,10 +97,10 @@ RSpec.describe Resolvers::IssuesResolver do
expect(resolve_issues(not: { milestone_wildcard_id: wildcard_upcoming })).to contain_exactly(issue6)
end
- it 'raises a mutually exclusive filter error when wildcard and title are provided as negated filters' do
- expect do
+ it 'generates a mutually exclusive filter error when wildcard and title are provided as negated filters' do
+ expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ArgumentError, 'only one of [milestoneTitle, milestoneWildcardId] arguments is allowed at the same time.') do
resolve_issues(not: { milestone_title: ["started milestone"], milestone_wildcard_id: wildcard_started })
- end.to raise_error(Gitlab::Graphql::Errors::ArgumentError, 'only one of [milestoneTitle, milestoneWildcardId] arguments is allowed at the same time.')
+ end
end
end
end
@@ -122,10 +122,10 @@ RSpec.describe Resolvers::IssuesResolver do
end
context 'when release_tag_wildcard_id is also provided' do
- it 'raises a mutually eclusive argument error' do
- expect do
+ it 'generates a mutually eclusive argument error' do
+ expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ArgumentError, 'only one of [releaseTag, releaseTagWildcardId] arguments is allowed at the same time.') do
resolve_issues(release_tag: [release1.tag], release_tag_wildcard_id: 'ANY')
- end.to raise_error(Gitlab::Graphql::Errors::ArgumentError, 'only one of [releaseTag, releaseTagWildcardId] arguments is allowed at the same time.')
+ end
end
end
end
@@ -191,10 +191,10 @@ RSpec.describe Resolvers::IssuesResolver do
end
context 'when both assignee_username and assignee_usernames are provided' do
- it 'raises a mutually exclusive filter error' do
- expect do
+ it 'generates a mutually exclusive filter error' do
+ expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ArgumentError, 'only one of [assigneeUsernames, assigneeUsername] arguments is allowed at the same time.') do
resolve_issues(assignee_usernames: [assignee.username], assignee_username: assignee.username)
- end.to raise_error(Gitlab::Graphql::Errors::ArgumentError, 'only one of [assigneeUsernames, assigneeUsername] arguments is allowed at the same time.')
+ end
end
end
end
@@ -331,11 +331,12 @@ RSpec.describe Resolvers::IssuesResolver do
stub_feature_flags(disable_anonymous_search: true)
end
- it 'returns an error' do
+ it 'generates an error' do
error_message = "User must be authenticated to include the `search` argument."
- expect { resolve(described_class, obj: public_project, args: { search: 'test' }, ctx: { current_user: nil }) }
- .to raise_error(Gitlab::Graphql::Errors::ArgumentError, error_message)
+ expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ArgumentError, error_message) do
+ resolve(described_class, obj: public_project, args: { search: 'test' }, ctx: { current_user: nil })
+ end
end
end
@@ -618,8 +619,8 @@ RSpec.describe Resolvers::IssuesResolver do
it 'increases field complexity based on arguments' do
field = Types::BaseField.new(name: 'test', type: GraphQL::Types::String.connection_type, resolver_class: described_class, null: false, max_page_size: 100)
- expect(field.to_graphql.complexity.call({}, {}, 1)).to eq 4
- expect(field.to_graphql.complexity.call({}, { labelName: 'foo' }, 1)).to eq 8
+ expect(field.complexity.call({}, {}, 1)).to eq 4
+ expect(field.complexity.call({}, { labelName: 'foo' }, 1)).to eq 8
end
def create_issue_with_severity(project, severity:)
diff --git a/spec/graphql/resolvers/kas/agent_configurations_resolver_spec.rb b/spec/graphql/resolvers/kas/agent_configurations_resolver_spec.rb
index bdb1ced46ae..e4cf62b0361 100644
--- a/spec/graphql/resolvers/kas/agent_configurations_resolver_spec.rb
+++ b/spec/graphql/resolvers/kas/agent_configurations_resolver_spec.rb
@@ -34,8 +34,10 @@ RSpec.describe Resolvers::Kas::AgentConfigurationsResolver do
allow(kas_client).to receive(:list_agent_config_files).and_raise(GRPC::DeadlineExceeded)
end
- it 'raises a graphql error' do
- expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable, 'GRPC::DeadlineExceeded')
+ it 'generates a graphql error' do
+ expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ResourceNotAvailable, 'GRPC::DeadlineExceeded') do
+ subject
+ end
end
end
diff --git a/spec/graphql/resolvers/labels_resolver_spec.rb b/spec/graphql/resolvers/labels_resolver_spec.rb
index be6229553d7..efd2596b9eb 100644
--- a/spec/graphql/resolvers/labels_resolver_spec.rb
+++ b/spec/graphql/resolvers/labels_resolver_spec.rb
@@ -28,7 +28,9 @@ RSpec.describe Resolvers::LabelsResolver do
describe '#resolve' do
context 'with unauthorized user' do
it 'returns no labels' do
- expect { resolve_labels(project) }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
+ expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ResourceNotAvailable) do
+ resolve_labels(project)
+ end
end
end
diff --git a/spec/graphql/resolvers/namespace_projects_resolver_spec.rb b/spec/graphql/resolvers/namespace_projects_resolver_spec.rb
index b1f50a4a4a5..eb4d0ab6f37 100644
--- a/spec/graphql/resolvers/namespace_projects_resolver_spec.rb
+++ b/spec/graphql/resolvers/namespace_projects_resolver_spec.rb
@@ -147,8 +147,8 @@ RSpec.describe Resolvers::NamespaceProjectsResolver do
it 'has an high complexity regardless of arguments' do
field = Types::BaseField.new(name: 'test', type: GraphQL::Types::String.connection_type, resolver_class: described_class, null: false, max_page_size: 100)
- expect(field.to_graphql.complexity.call({}, {}, 1)).to eq 24
- expect(field.to_graphql.complexity.call({}, { include_subgroups: true }, 1)).to eq 24
+ expect(field.complexity.call({}, {}, 1)).to eq 24
+ expect(field.complexity.call({}, { include_subgroups: true }, 1)).to eq 24
end
def resolve_projects(args = { include_subgroups: false, sort: nil, search: nil, ids: nil }, context = { current_user: current_user })
diff --git a/spec/graphql/resolvers/package_pipelines_resolver_spec.rb b/spec/graphql/resolvers/package_pipelines_resolver_spec.rb
index 892dc641201..c757c876616 100644
--- a/spec/graphql/resolvers/package_pipelines_resolver_spec.rb
+++ b/spec/graphql/resolvers/package_pipelines_resolver_spec.rb
@@ -25,32 +25,40 @@ RSpec.describe Resolvers::PackagePipelinesResolver do
context 'with invalid after' do
let(:args) { { first: 1, after: 'not_json_string' } }
- it 'raises argument error' do
- expect { subject }.to raise_error(Gitlab::Graphql::Errors::ArgumentError)
+ it 'generates an argument error' do
+ expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ArgumentError) do
+ subject
+ end
end
end
context 'with invalid after key' do
let(:args) { { first: 1, after: encode_cursor(foo: 3) } }
- it 'raises argument error' do
- expect { subject }.to raise_error(Gitlab::Graphql::Errors::ArgumentError)
+ it 'generates an argument error' do
+ expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ArgumentError) do
+ subject
+ end
end
end
context 'with invalid before' do
let(:args) { { last: 1, before: 'not_json_string' } }
- it 'raises argument error' do
- expect { subject }.to raise_error(Gitlab::Graphql::Errors::ArgumentError)
+ it 'generates an argument error' do
+ expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ArgumentError) do
+ subject
+ end
end
end
context 'with invalid before key' do
let(:args) { { last: 1, before: encode_cursor(foo: 3) } }
- it 'raises argument error' do
- expect { subject }.to raise_error(Gitlab::Graphql::Errors::ArgumentError)
+ it 'generates an argument error' do
+ expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ArgumentError) do
+ subject
+ end
end
end
diff --git a/spec/graphql/resolvers/paginated_tree_resolver_spec.rb b/spec/graphql/resolvers/paginated_tree_resolver_spec.rb
index 82b05937aa3..4b05e9076d7 100644
--- a/spec/graphql/resolvers/paginated_tree_resolver_spec.rb
+++ b/spec/graphql/resolvers/paginated_tree_resolver_spec.rb
@@ -65,7 +65,11 @@ RSpec.describe Resolvers::PaginatedTreeResolver do
context 'when cursor is invalid' do
let(:args) { super().merge(after: 'invalid') }
- it { expect { subject }.to raise_error(Gitlab::Graphql::Errors::ArgumentError) }
+ it 'generates an error' do
+ expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ArgumentError) do
+ subject
+ end
+ end
end
it 'returns all tree entries during cursor pagination' do
diff --git a/spec/graphql/resolvers/project_milestones_resolver_spec.rb b/spec/graphql/resolvers/project_milestones_resolver_spec.rb
index e168291c804..2cf490c2b6a 100644
--- a/spec/graphql/resolvers/project_milestones_resolver_spec.rb
+++ b/spec/graphql/resolvers/project_milestones_resolver_spec.rb
@@ -103,27 +103,27 @@ RSpec.describe Resolvers::ProjectMilestonesResolver do
end
context 'when start date is after end_date' do
- it 'raises error' do
- expect do
+ it 'generates an error' do
+ expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ArgumentError, 'startDate is after endDate') do
resolve_project_milestones(start_date: Time.now, end_date: Time.now - 2.days)
- end.to raise_error(Gitlab::Graphql::Errors::ArgumentError, "startDate is after endDate")
+ end
end
end
end
context 'when only start_date is present' do
- it 'raises error' do
- expect do
+ it 'generates an error' do
+ expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ArgumentError, /Both startDate and endDate/) do
resolve_project_milestones(start_date: Time.now)
- end.to raise_error(Gitlab::Graphql::Errors::ArgumentError, /Both startDate and endDate/)
+ end
end
end
context 'when only end_date is present' do
- it 'raises error' do
- expect do
+ it 'generates an error' do
+ expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ArgumentError, /Both startDate and endDate/) do
resolve_project_milestones(end_date: Time.now)
- end.to raise_error(Gitlab::Graphql::Errors::ArgumentError, /Both startDate and endDate/)
+ end
end
end
@@ -174,12 +174,12 @@ RSpec.describe Resolvers::ProjectMilestonesResolver do
end
context 'when user cannot read milestones' do
- it 'raises error' do
+ it 'generates an error' do
unauthorized_user = create(:user)
- expect do
+ expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ResourceNotAvailable) do
resolve_project_milestones({}, { current_user: unauthorized_user })
- end.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
+ end
end
end
end
diff --git a/spec/graphql/resolvers/project_pipeline_resolver_spec.rb b/spec/graphql/resolvers/project_pipeline_resolver_spec.rb
index 6a8aa39f3b2..398f8f52269 100644
--- a/spec/graphql/resolvers/project_pipeline_resolver_spec.rb
+++ b/spec/graphql/resolvers/project_pipeline_resolver_spec.rb
@@ -85,13 +85,15 @@ RSpec.describe Resolvers::ProjectPipelineResolver do
end
it 'errors when no iid or sha is passed' do
- expect { resolve_pipeline(project, {}) }
- .to raise_error(Gitlab::Graphql::Errors::ArgumentError)
+ expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ArgumentError) do
+ resolve_pipeline(project, {})
+ end
end
it 'errors when both iid and sha are passed' do
- expect { resolve_pipeline(project, { iid: '1234', sha: 'sha' }) }
- .to raise_error(Gitlab::Graphql::Errors::ArgumentError)
+ expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ArgumentError) do
+ resolve_pipeline(project, { iid: '1234', sha: 'sha' })
+ end
end
context 'when the pipeline is a dangling pipeline' do
diff --git a/spec/graphql/resolvers/project_resolver_spec.rb b/spec/graphql/resolvers/project_resolver_spec.rb
index cd3fdc788e6..dec9d4701e1 100644
--- a/spec/graphql/resolvers/project_resolver_spec.rb
+++ b/spec/graphql/resolvers/project_resolver_spec.rb
@@ -36,8 +36,8 @@ RSpec.describe Resolvers::ProjectResolver do
field1 = Types::BaseField.new(name: 'test', type: GraphQL::Types::String, resolver_class: described_class, null: false, max_page_size: 100)
field2 = Types::BaseField.new(name: 'test', type: GraphQL::Types::String, resolver_class: described_class, null: false, max_page_size: 1)
- expect(field1.to_graphql.complexity.call({}, {}, 1)).to eq 2
- expect(field2.to_graphql.complexity.call({}, {}, 1)).to eq 2
+ expect(field1.complexity.call({}, {}, 1)).to eq 2
+ expect(field2.complexity.call({}, {}, 1)).to eq 2
end
def resolve_project(full_path)
diff --git a/spec/graphql/resolvers/projects/jira_projects_resolver_spec.rb b/spec/graphql/resolvers/projects/jira_projects_resolver_spec.rb
index c6d8c518fb7..b95bab41e3e 100644
--- a/spec/graphql/resolvers/projects/jira_projects_resolver_spec.rb
+++ b/spec/graphql/resolvers/projects/jira_projects_resolver_spec.rb
@@ -14,10 +14,10 @@ RSpec.describe Resolvers::Projects::JiraProjectsResolver do
let_it_be(:project) { create(:project) }
shared_examples 'no project service access' do
- it 'raises error' do
- expect do
+ it 'generates an error' do
+ expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ResourceNotAvailable) do
resolve_jira_projects
- end.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
+ end
end
end
@@ -89,11 +89,14 @@ RSpec.describe Resolvers::Projects::JiraProjectsResolver do
.to_raise(JIRA::HTTPError.new(double(message: '{"errorMessages":["Some failure"]}')))
end
- it 'raises failure error' do
+ it 'generates a failure error' do
config_docs_link_url = Rails.application.routes.url_helpers.help_page_path('integration/jira/configure')
docs_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: config_docs_link_url }
error_message = 'An error occurred while requesting data from Jira: Some failure. Check your %{docs_link_start}Jira integration configuration</a> and try again.' % { docs_link_start: docs_link_start }
- expect { resolve_jira_projects }.to raise_error(error_message)
+
+ expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::BaseError, error_message) do
+ resolve_jira_projects
+ end
end
end
end
diff --git a/spec/graphql/resolvers/projects/snippets_resolver_spec.rb b/spec/graphql/resolvers/projects/snippets_resolver_spec.rb
index 2d8929c0e8f..b963f2509db 100644
--- a/spec/graphql/resolvers/projects/snippets_resolver_spec.rb
+++ b/spec/graphql/resolvers/projects/snippets_resolver_spec.rb
@@ -81,12 +81,14 @@ RSpec.describe Resolvers::Projects::SnippetsResolver do
end
context 'when project snippets are disabled' do
- it 'raises an error' do
+ it 'generates an error' do
disabled_snippet_project = create(:project, :snippets_disabled)
disabled_snippet_project.add_developer(current_user)
expect(SnippetsFinder).not_to receive(:new)
- expect { resolve_snippets(obj: disabled_snippet_project) }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
+ expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ResourceNotAvailable) do
+ resolve_snippets(obj: disabled_snippet_project)
+ end
end
end
end
diff --git a/spec/graphql/resolvers/snippets_resolver_spec.rb b/spec/graphql/resolvers/snippets_resolver_spec.rb
index 11cb1c0ec4b..f9feb8901cd 100644
--- a/spec/graphql/resolvers/snippets_resolver_spec.rb
+++ b/spec/graphql/resolvers/snippets_resolver_spec.rb
@@ -108,15 +108,15 @@ RSpec.describe Resolvers::SnippetsResolver do
end.to raise_error(GraphQL::CoercionError, '"foo" is not a valid Global ID')
end
- it 'returns an error if both project and author are provided' do
- expect do
+ it 'generates an error if both project and author are provided' do
+ expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ArgumentError) do
args = {
author_id: current_user.to_global_id,
project_id: project.to_global_id
}
resolve_snippets(args: args)
- end.to raise_error(Gitlab::Graphql::Errors::ArgumentError)
+ end
end
end
end
diff --git a/spec/graphql/resolvers/timelog_resolver_spec.rb b/spec/graphql/resolvers/timelog_resolver_spec.rb
index 9b3f555071e..84fa2932829 100644
--- a/spec/graphql/resolvers/timelog_resolver_spec.rb
+++ b/spec/graphql/resolvers/timelog_resolver_spec.rb
@@ -85,27 +85,30 @@ RSpec.describe Resolvers::TimelogResolver do
context 'when start_time and start_date are present' do
let(:args) { { start_time: 6.days.ago, start_date: 6.days.ago } }
- it 'returns correct error' do
- expect { timelogs }
- .to raise_error(error_class, /Provide either a start date or time, but not both/)
+ it 'generates an error' do
+ expect_graphql_error_to_be_created(error_class, /Provide either a start date or time, but not both/) do
+ timelogs
+ end
end
end
context 'when end_time and end_date are present' do
let(:args) { { end_time: 2.days.ago, end_date: 2.days.ago } }
- it 'returns correct error' do
- expect { timelogs }
- .to raise_error(error_class, /Provide either an end date or time, but not both/)
+ it 'generates an error' do
+ expect_graphql_error_to_be_created(error_class, /Provide either an end date or time, but not both/) do
+ timelogs
+ end
end
end
context 'when start argument is after end argument' do
let(:args) { { start_time: 2.days.ago, end_time: 6.days.ago } }
- it 'returns correct error' do
- expect { timelogs }
- .to raise_error(error_class, /Start argument must be before End argument/)
+ it 'generates an error' do
+ expect_graphql_error_to_be_created(error_class, /Start argument must be before End argument/) do
+ timelogs
+ end
end
end
end
@@ -170,27 +173,30 @@ RSpec.describe Resolvers::TimelogResolver do
context 'when start_time and start_date are present' do
let(:args) { { start_time: short_time_ago, start_date: short_time_ago } }
- it 'returns correct error' do
- expect { timelogs }
- .to raise_error(error_class, /Provide either a start date or time, but not both/)
+ it 'generates an error' do
+ expect_graphql_error_to_be_created(error_class, /Provide either a start date or time, but not both/) do
+ timelogs
+ end
end
end
context 'when end_time and end_date are present' do
let(:args) { { end_time: short_time_ago, end_date: short_time_ago } }
- it 'returns correct error' do
- expect { timelogs }
- .to raise_error(error_class, /Provide either an end date or time, but not both/)
+ it 'generates an error' do
+ expect_graphql_error_to_be_created(error_class, /Provide either an end date or time, but not both/) do
+ timelogs
+ end
end
end
context 'when start argument is after end argument' do
let(:args) { { start_time: short_time_ago, end_time: medium_time_ago } }
- it 'returns correct error' do
- expect { timelogs }
- .to raise_error(error_class, /Start argument must be before End argument/)
+ it 'generates an error' do
+ expect_graphql_error_to_be_created(error_class, /Start argument must be before End argument/) do
+ timelogs
+ end
end
end
end
@@ -273,9 +279,10 @@ RSpec.describe Resolvers::TimelogResolver do
let(:args) { {} }
let(:extra_args) { {} }
- it 'returns correct error' do
- expect { timelogs }
- .to raise_error(error_class, /Provide at least one argument/)
+ it 'generates an error' do
+ expect_graphql_error_to_be_created(error_class, /Provide at least one argument/) do
+ timelogs
+ end
end
end
diff --git a/spec/graphql/resolvers/topics_resolver_spec.rb b/spec/graphql/resolvers/topics_resolver_spec.rb
index 3ff1dabc927..89f4583bce8 100644
--- a/spec/graphql/resolvers/topics_resolver_spec.rb
+++ b/spec/graphql/resolvers/topics_resolver_spec.rb
@@ -6,9 +6,9 @@ RSpec.describe Resolvers::TopicsResolver do
include GraphqlHelpers
describe '#resolve' do
- let!(:topic1) { create(:topic, name: 'GitLab', total_projects_count: 1) }
- let!(:topic2) { create(:topic, name: 'git', total_projects_count: 2) }
- let!(:topic3) { create(:topic, name: 'topic3', total_projects_count: 3) }
+ let!(:topic1) { create(:topic, name: 'GitLab', non_private_projects_count: 1) }
+ let!(:topic2) { create(:topic, name: 'git', non_private_projects_count: 2) }
+ let!(:topic3) { create(:topic, name: 'topic3', non_private_projects_count: 3) }
it 'finds all topics' do
expect(resolve_topics).to eq([topic3, topic2, topic1])
diff --git a/spec/graphql/resolvers/user_discussions_count_resolver_spec.rb b/spec/graphql/resolvers/user_discussions_count_resolver_spec.rb
index 70f06b58a65..ef70418ab4b 100644
--- a/spec/graphql/resolvers/user_discussions_count_resolver_spec.rb
+++ b/spec/graphql/resolvers/user_discussions_count_resolver_spec.rb
@@ -43,7 +43,9 @@ RSpec.describe Resolvers::UserDiscussionsCountResolver do
subject { batch_sync { resolve_user_discussions_count(private_issue) } }
it 'returns no discussions' do
- expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
+ expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ResourceNotAvailable) do
+ subject
+ end
end
end
end
diff --git a/spec/graphql/resolvers/user_notes_count_resolver_spec.rb b/spec/graphql/resolvers/user_notes_count_resolver_spec.rb
index bc173b2a166..b3368d532b2 100644
--- a/spec/graphql/resolvers/user_notes_count_resolver_spec.rb
+++ b/spec/graphql/resolvers/user_notes_count_resolver_spec.rb
@@ -44,8 +44,10 @@ RSpec.describe Resolvers::UserNotesCountResolver do
context 'when a user does not have permission to view notes' do
subject { batch_sync { resolve_user_notes_count(private_issue) } }
- it 'raises an error' do
- expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
+ it 'generates an error' do
+ expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ResourceNotAvailable) do
+ subject
+ end
end
end
end
@@ -80,8 +82,10 @@ RSpec.describe Resolvers::UserNotesCountResolver do
context 'when a user does not have permission to view notes' do
subject { batch_sync { resolve_user_notes_count(private_merge_request) } }
- it 'raises an error' do
- expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
+ it 'generates an error' do
+ expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ResourceNotAvailable) do
+ subject
+ end
end
end
end
diff --git a/spec/graphql/resolvers/user_resolver_spec.rb b/spec/graphql/resolvers/user_resolver_spec.rb
index 3ee9f63d832..446d765d3ee 100644
--- a/spec/graphql/resolvers/user_resolver_spec.rb
+++ b/spec/graphql/resolvers/user_resolver_spec.rb
@@ -9,15 +9,17 @@ RSpec.describe Resolvers::UserResolver 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)
+ it 'generates an ArgumentError' do
+ expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ArgumentError) do
+ resolve_user
+ end
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)
+ it 'generates an ArgumentError when both an ID and username are provided' do
+ expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ArgumentError) do
+ resolve_user(id: user.to_global_id, username: user.username)
+ end
end
context 'by username' do
diff --git a/spec/graphql/resolvers/users_resolver_spec.rb b/spec/graphql/resolvers/users_resolver_spec.rb
index 29947c33430..b01cc0d43e3 100644
--- a/spec/graphql/resolvers/users_resolver_spec.rb
+++ b/spec/graphql/resolvers/users_resolver_spec.rb
@@ -14,10 +14,12 @@ RSpec.describe Resolvers::UsersResolver do
end
describe '#resolve' do
- it 'raises an error when read_users_list is not authorized' do
+ it 'generates an error when read_users_list is not authorized' do
expect(Ability).to receive(:allowed?).with(current_user, :read_users_list).and_return(false)
- expect { resolve_users }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
+ expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ResourceNotAvailable) do
+ resolve_users
+ end
end
context 'when no arguments are passed' do
@@ -27,9 +29,10 @@ RSpec.describe Resolvers::UsersResolver do
end
context 'when both ids and usernames are passed ' do
- it 'raises an error' do
- expect { resolve_users( args: { ids: [user1.to_global_id.to_s], usernames: [user1.username] } ) }
- .to raise_error(Gitlab::Graphql::Errors::ArgumentError)
+ it 'generates an error' do
+ expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ArgumentError) do
+ resolve_users( args: { ids: [user1.to_global_id.to_s], usernames: [user1.username] } )
+ end
end
end
diff --git a/spec/graphql/resolvers/work_item_resolver_spec.rb b/spec/graphql/resolvers/work_item_resolver_spec.rb
new file mode 100644
index 00000000000..c7e2beecb51
--- /dev/null
+++ b/spec/graphql/resolvers/work_item_resolver_spec.rb
@@ -0,0 +1,43 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Resolvers::WorkItemResolver do
+ include GraphqlHelpers
+
+ describe '#resolve' do
+ let_it_be(:developer) { create(:user) }
+ let_it_be(:project) { create(:project, :private).tap { |project| project.add_developer(developer) } }
+ let_it_be(:work_item) { create(:work_item, project: project) }
+
+ let(:current_user) { developer }
+
+ subject(:resolved_work_item) { resolve_work_item('id' => work_item.to_gid.to_s) }
+
+ context 'when the user can read the work item' do
+ it { is_expected.to eq(work_item) }
+ end
+
+ context 'when the user can not read the work item' do
+ let(:current_user) { create(:user) }
+
+ it 'raises a resource not available error' do
+ expect { resolved_work_item }.to raise_error(::Gitlab::Graphql::Errors::ResourceNotAvailable)
+ end
+ end
+
+ context 'when the work_items feature flag is disabled' do
+ before do
+ stub_feature_flags(work_items: false)
+ end
+
+ it { is_expected.to be_nil }
+ end
+ end
+
+ private
+
+ def resolve_work_item(args = {})
+ resolve(described_class, args: args, ctx: { current_user: current_user })
+ end
+end
diff --git a/spec/graphql/resolvers/work_items/types_resolver_spec.rb b/spec/graphql/resolvers/work_items/types_resolver_spec.rb
index b85989256b5..f7aeed30fd3 100644
--- a/spec/graphql/resolvers/work_items/types_resolver_spec.rb
+++ b/spec/graphql/resolvers/work_items/types_resolver_spec.rb
@@ -7,16 +7,51 @@ RSpec.describe Resolvers::WorkItems::TypesResolver do
let_it_be(:current_user) { create(:user) }
let_it_be(:group) { create(:group) }
+ let_it_be(:project) { create(:project, group: group) }
before_all do
group.add_developer(current_user)
end
- describe '#resolve' do
- it 'returns all default work item types' do
- result = resolve(described_class, obj: group)
+ shared_examples 'a work item type resolver' do
+ let(:args) { {} }
+
+ subject(:result) { resolve(described_class, obj: object, args: args) }
+ it 'returns all default work item types' do
expect(result.to_a).to match(WorkItems::Type.default.order_by_name_asc)
end
+
+ context 'when requesting taskable types' do
+ let(:args) { { taskable: true } }
+
+ it 'returns only taskable types' do
+ expect(result.to_a).to contain_exactly(WorkItems::Type.default_by_type(:task))
+ end
+ end
+
+ context 'when work_items feature flag is disabled' do
+ before do
+ stub_feature_flags(work_items: false)
+ end
+
+ it 'returns nil' do
+ expect(result).to be_nil
+ end
+ end
+ end
+
+ describe '#resolve' do
+ context 'when parent is a group' do
+ let(:object) { group }
+
+ it_behaves_like 'a work item type resolver'
+ end
+
+ context 'when parent is a project' do
+ let(:object) { project }
+
+ it_behaves_like 'a work item type resolver'
+ end
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 9ff01418c9a..69cbdb998eb 100644
--- a/spec/graphql/types/alert_management/alert_type_spec.rb
+++ b/spec/graphql/types/alert_management/alert_type_spec.rb
@@ -7,6 +7,8 @@ RSpec.describe GitlabSchema.types['AlertManagementAlert'] do
specify { expect(described_class).to require_graphql_authorizations(:read_alert_management_alert) }
+ specify { expect(described_class.interfaces).to include(Types::TodoableInterface) }
+
it 'exposes the expected fields' do
expected_fields = %i[
iid
@@ -34,6 +36,7 @@ RSpec.describe GitlabSchema.types['AlertManagementAlert'] do
details_url
prometheus_alert
environment
+ web_url
]
expect(described_class).to have_graphql_fields(*expected_fields)
diff --git a/spec/graphql/types/base_enum_spec.rb b/spec/graphql/types/base_enum_spec.rb
index bab0278ee25..65a345052c7 100644
--- a/spec/graphql/types/base_enum_spec.rb
+++ b/spec/graphql/types/base_enum_spec.rb
@@ -102,9 +102,9 @@ RSpec.describe Types::BaseEnum do
it 'sets the values defined by the declarative enum' do
set_declarative_enum
- expect(enum_type.values.keys).to eq(['FOO'])
- expect(enum_type.values.values.map(&:description)).to eq(['description of foo'])
- expect(enum_type.values.values.map(&:value)).to eq([0])
+ expect(enum_type.values.keys).to contain_exactly('FOO')
+ expect(enum_type.values.values.map(&:description)).to contain_exactly('description of foo')
+ expect(enum_type.values.values.map(&:value)).to contain_exactly('foo')
end
end
end
@@ -136,7 +136,7 @@ RSpec.describe Types::BaseEnum do
value 'TEST_VALUE', **args
end
- enum.to_graphql.values['TEST_VALUE']
+ enum.values['TEST_VALUE']
end
end
end
diff --git a/spec/graphql/types/base_field_spec.rb b/spec/graphql/types/base_field_spec.rb
index 31d07f701e8..9d02f061435 100644
--- a/spec/graphql/types/base_field_spec.rb
+++ b/spec/graphql/types/base_field_spec.rb
@@ -19,7 +19,7 @@ RSpec.describe Types::BaseField do
it 'defaults to 1' do
field = described_class.new(name: 'test', type: GraphQL::Types::String, null: true)
- expect(field.to_graphql.complexity).to eq 1
+ expect(field.complexity).to eq 1
end
describe '#base_complexity' do
@@ -43,7 +43,7 @@ RSpec.describe Types::BaseField do
it 'has specified value' do
field = described_class.new(name: 'test', type: GraphQL::Types::String, null: true, complexity: 12)
- expect(field.to_graphql.complexity).to eq 12
+ expect(field.complexity).to eq 12
end
context 'when field has a resolver' do
@@ -51,7 +51,7 @@ RSpec.describe Types::BaseField do
let(:field) { described_class.new(name: 'test', type: GraphQL::Types::String.connection_type, resolver_class: resolver, complexity: 2, max_page_size: 100, null: true) }
it 'uses this complexity' do
- expect(field.to_graphql.complexity).to eq 2
+ expect(field.complexity).to eq 2
end
end
@@ -59,13 +59,13 @@ RSpec.describe Types::BaseField do
let(:field) { described_class.new(name: 'test', type: GraphQL::Types::String.connection_type, resolver_class: resolver, max_page_size: 100, null: true) }
it 'sets complexity depending on arguments for resolvers' do
- expect(field.to_graphql.complexity.call({}, {}, 2)).to eq 4
- expect(field.to_graphql.complexity.call({}, { first: 50 }, 2)).to eq 3
+ expect(field.complexity.call({}, {}, 2)).to eq 4
+ expect(field.complexity.call({}, { first: 50 }, 2)).to eq 3
end
it 'sets complexity depending on number load limits for resolvers' do
- expect(field.to_graphql.complexity.call({}, { first: 1 }, 2)).to eq 2
- expect(field.to_graphql.complexity.call({}, { first: 1, foo: true }, 2)).to eq 4
+ expect(field.complexity.call({}, { first: 1 }, 2)).to eq 2
+ expect(field.complexity.call({}, { first: 1, foo: true }, 2)).to eq 4
end
end
@@ -73,8 +73,8 @@ RSpec.describe Types::BaseField do
it 'sets complexity as normal' do
field = described_class.new(name: 'test', type: GraphQL::Types::String, resolver_class: resolver, max_page_size: 100, null: true)
- expect(field.to_graphql.complexity.call({}, {}, 2)).to eq 2
- expect(field.to_graphql.complexity.call({}, { first: 50 }, 2)).to eq 2
+ expect(field.complexity.call({}, {}, 2)).to eq 2
+ expect(field.complexity.call({}, { first: 50 }, 2)).to eq 2
end
end
end
@@ -84,9 +84,9 @@ RSpec.describe Types::BaseField do
it 'adds 1 if true' do
with_gitaly_field = described_class.new(name: 'test', type: GraphQL::Types::String, resolver_class: resolver, null: true, calls_gitaly: true)
without_gitaly_field = described_class.new(name: 'test', type: GraphQL::Types::String, resolver_class: resolver, null: true)
- base_result = without_gitaly_field.to_graphql.complexity.call({}, {}, 2)
+ base_result = without_gitaly_field.complexity.call({}, {}, 2)
- expect(with_gitaly_field.to_graphql.complexity.call({}, {}, 2)).to eq base_result + 1
+ expect(with_gitaly_field.complexity.call({}, {}, 2)).to eq base_result + 1
end
end
@@ -94,7 +94,7 @@ RSpec.describe Types::BaseField do
it 'adds 1 if true' do
field = described_class.new(name: 'test', type: GraphQL::Types::String, null: true, calls_gitaly: true)
- expect(field.to_graphql.complexity).to eq 2
+ expect(field.complexity).to eq 2
end
end
@@ -108,14 +108,14 @@ RSpec.describe Types::BaseField do
it 'has complexity set to that constant' do
field = described_class.new(name: 'test', type: GraphQL::Types::String, null: true, complexity: 12)
- expect(field.to_graphql.complexity).to eq 12
+ expect(field.complexity).to eq 12
end
it 'does not raise an error even with Gitaly calls' do
allow(Gitlab::GitalyClient).to receive(:get_request_count).and_return([0, 1])
field = described_class.new(name: 'test', type: GraphQL::Types::String, null: true, complexity: 12)
- expect(field.to_graphql.complexity).to eq 12
+ expect(field.complexity).to eq 12
end
end
end
diff --git a/spec/graphql/types/ci/runner_web_url_edge_spec.rb b/spec/graphql/types/ci/runner_web_url_edge_spec.rb
new file mode 100644
index 00000000000..08718df0a5b
--- /dev/null
+++ b/spec/graphql/types/ci/runner_web_url_edge_spec.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Types::Ci::RunnerWebUrlEdge do
+ specify { expect(described_class.graphql_name).to eq('RunnerWebUrlEdge') }
+
+ it 'contains URL attributes' do
+ expected_fields = %w[edit_url web_url]
+
+ expect(described_class).to include_graphql_fields(*expected_fields)
+ end
+end
diff --git a/spec/graphql/types/commit_type_spec.rb b/spec/graphql/types/commit_type_spec.rb
index c1d838c3117..fe8df15028d 100644
--- a/spec/graphql/types/commit_type_spec.rb
+++ b/spec/graphql/types/commit_type_spec.rb
@@ -7,6 +7,8 @@ RSpec.describe GitlabSchema.types['Commit'] do
specify { expect(described_class).to require_graphql_authorizations(:download_code) }
+ specify { expect(described_class).to include(Types::TodoableInterface) }
+
it 'contains attributes related to commit' do
expect(described_class).to have_graphql_fields(
:id, :sha, :short_id, :title, :full_title, :full_title_html, :description, :description_html, :message, :title_html, :authored_date,
diff --git a/spec/graphql/types/container_repository_details_type_spec.rb b/spec/graphql/types/container_repository_details_type_spec.rb
index 45f6449d8c8..aa770284f89 100644
--- a/spec/graphql/types/container_repository_details_type_spec.rb
+++ b/spec/graphql/types/container_repository_details_type_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
RSpec.describe GitlabSchema.types['ContainerRepositoryDetails'] do
- fields = %i[id name path location created_at updated_at expiration_policy_started_at status tags_count can_delete expiration_policy_cleanup_status tags project]
+ fields = %i[id name path location created_at updated_at expiration_policy_started_at status tags_count can_delete expiration_policy_cleanup_status tags size project]
it { expect(described_class.graphql_name).to eq('ContainerRepositoryDetails') }
diff --git a/spec/graphql/types/design_management/design_type_spec.rb b/spec/graphql/types/design_management/design_type_spec.rb
index cae98a013e1..9c460e9058a 100644
--- a/spec/graphql/types/design_management/design_type_spec.rb
+++ b/spec/graphql/types/design_management/design_type_spec.rb
@@ -5,8 +5,10 @@ require 'spec_helper'
RSpec.describe GitlabSchema.types['Design'] do
specify { expect(described_class.interfaces).to include(Types::CurrentUserTodos) }
+ specify { expect(described_class.interfaces).to include(Types::TodoableInterface) }
+
it_behaves_like 'a GraphQL type with design fields' do
- let(:extra_design_fields) { %i[notes current_user_todos discussions versions] }
+ let(:extra_design_fields) { %i[notes current_user_todos discussions versions web_url] }
let_it_be(:design) { create(:design, :with_versions) }
let(:object_id) { GitlabSchema.id_from_object(design) }
let_it_be(:object_id_b) { GitlabSchema.id_from_object(create(:design, :with_versions)) }
diff --git a/spec/graphql/types/global_id_type_spec.rb b/spec/graphql/types/global_id_type_spec.rb
index e7e69cfad9e..8df92c818fc 100644
--- a/spec/graphql/types/global_id_type_spec.rb
+++ b/spec/graphql/types/global_id_type_spec.rb
@@ -11,7 +11,7 @@ RSpec.describe Types::GlobalIDType do
let(:gid) { project.to_global_id }
it 'is has the correct name' do
- expect(described_class.to_graphql.name).to eq('GlobalID')
+ expect(described_class.graphql_name).to eq('GlobalID')
end
describe '.coerce_result' do
@@ -63,7 +63,7 @@ RSpec.describe Types::GlobalIDType do
let(:type) { ::Types::GlobalIDType[::Project] }
it 'is has the correct name' do
- expect(type.to_graphql.name).to eq('ProjectID')
+ expect(type.graphql_name).to eq('ProjectID')
end
context 'the GID is appropriate' do
@@ -126,7 +126,7 @@ RSpec.describe Types::GlobalIDType do
let(:deprecating_gid) { Gitlab::GlobalId.build(model_name: 'Issue', id: issue.id) }
it 'appends the description with a deprecation notice for the old Global ID' do
- expect(type.to_graphql.description).to include('The older format `"gid://gitlab/OldIssue/1"` was deprecated in 10.0')
+ expect(type.description).to include('The older format `"gid://gitlab/OldIssue/1"` was deprecated in 10.0')
end
describe 'coercing input against the type (parsing the Global ID string when supplied as an argument)' do
@@ -242,7 +242,7 @@ RSpec.describe Types::GlobalIDType do
let(:type) { ::Types::GlobalIDType[::Ci::Build] }
it 'is has a valid GraphQL identifier for a name' do
- expect(type.to_graphql.name).to eq('CiBuildID')
+ expect(type.graphql_name).to eq('CiBuildID')
end
end
@@ -376,4 +376,10 @@ RSpec.describe Types::GlobalIDType do
expect(described_class.model_name_to_graphql_name('DesignManagement::Design')).to eq('DesignManagementDesignID')
end
end
+
+ describe '.[]' do
+ it 'returns a custom class for work items' do
+ expect(described_class[::WorkItem]).to eq(::Types::WorkItemIdType)
+ end
+ end
end
diff --git a/spec/graphql/types/group_member_type_spec.rb b/spec/graphql/types/group_member_type_spec.rb
index b1cb8e572ad..389295f3a39 100644
--- a/spec/graphql/types/group_member_type_spec.rb
+++ b/spec/graphql/types/group_member_type_spec.rb
@@ -11,7 +11,7 @@ RSpec.describe Types::GroupMemberType do
it 'has the expected fields' do
expected_fields = %w[
- access_level created_by created_at updated_at expires_at group
+ access_level created_by created_at updated_at expires_at group notification_email
]
expect(described_class).to include_graphql_fields(*expected_fields)
diff --git a/spec/graphql/types/merge_request_type_spec.rb b/spec/graphql/types/merge_request_type_spec.rb
index 5ab8845246a..e9e92bbdc85 100644
--- a/spec/graphql/types/merge_request_type_spec.rb
+++ b/spec/graphql/types/merge_request_type_spec.rb
@@ -13,6 +13,8 @@ RSpec.describe GitlabSchema.types['MergeRequest'] do
specify { expect(described_class.interfaces).to include(Types::CurrentUserTodos) }
+ specify { expect(described_class.interfaces).to include(Types::TodoableInterface) }
+
it 'has the expected fields' do
expected_fields = %w[
notes discussions user_permissions id iid title title_html description
@@ -33,7 +35,7 @@ RSpec.describe GitlabSchema.types['MergeRequest'] do
total_time_spent human_time_estimate human_total_time_spent reference author merged_at
commit_count current_user_todos conflicts auto_merge_enabled approved_by source_branch_protected
default_merge_commit_message_with_description squash_on_merge available_auto_merge_strategies
- has_ci mergeable commits commits_without_merge_commits squash security_auto_fix default_squash_commit_message
+ has_ci mergeable commits committers commits_without_merge_commits squash security_auto_fix default_squash_commit_message
auto_merge_strategy merge_user
]
diff --git a/spec/graphql/types/merge_requests/assignee_type_spec.rb b/spec/graphql/types/merge_requests/assignee_type_spec.rb
new file mode 100644
index 00000000000..d67d20860b2
--- /dev/null
+++ b/spec/graphql/types/merge_requests/assignee_type_spec.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe GitlabSchema.types['MergeRequestAssignee'] do
+ it_behaves_like "a user type with merge request interaction type"
+end
diff --git a/spec/graphql/types/merge_requests/author_type_spec.rb b/spec/graphql/types/merge_requests/author_type_spec.rb
new file mode 100644
index 00000000000..2a5a31f210c
--- /dev/null
+++ b/spec/graphql/types/merge_requests/author_type_spec.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe GitlabSchema.types['MergeRequestAuthor'] do
+ it_behaves_like "a user type with merge request interaction type"
+end
diff --git a/spec/graphql/types/merge_requests/participant_type_spec.rb b/spec/graphql/types/merge_requests/participant_type_spec.rb
new file mode 100644
index 00000000000..083762c7064
--- /dev/null
+++ b/spec/graphql/types/merge_requests/participant_type_spec.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe GitlabSchema.types['MergeRequestParticipant'] do
+ it_behaves_like "a user type with merge request interaction type"
+end
diff --git a/spec/graphql/types/merge_requests/reviewer_type_spec.rb b/spec/graphql/types/merge_requests/reviewer_type_spec.rb
index 4d357a922f8..92cb51df27a 100644
--- a/spec/graphql/types/merge_requests/reviewer_type_spec.rb
+++ b/spec/graphql/types/merge_requests/reviewer_type_spec.rb
@@ -3,51 +3,5 @@
require 'spec_helper'
RSpec.describe GitlabSchema.types['MergeRequestReviewer'] do
- specify { expect(described_class).to require_graphql_authorizations(:read_user) }
-
- it 'has the expected fields' do
- expected_fields = %w[
- id
- bot
- user_permissions
- snippets
- name
- username
- email
- publicEmail
- avatarUrl
- webUrl
- webPath
- todos
- state
- status
- location
- authoredMergeRequests
- assignedMergeRequests
- reviewRequestedMergeRequests
- groupMemberships
- groupCount
- projectMemberships
- starredProjects
- callouts
- merge_request_interaction
- namespace
- timelogs
- groups
- ]
-
- expect(described_class).to have_graphql_fields(*expected_fields)
- end
-
- describe '#merge_request_interaction' do
- subject { described_class.fields['mergeRequestInteraction'] }
-
- it 'returns the correct type' do
- is_expected.to have_graphql_type(Types::UserMergeRequestInteractionType)
- end
-
- it 'has the correct arguments' do
- is_expected.to have_attributes(arguments: be_empty)
- end
- end
+ it_behaves_like "a user type with merge request interaction type"
end
diff --git a/spec/graphql/types/projects/base_service_type_spec.rb b/spec/graphql/types/projects/base_service_type_spec.rb
index 423cea860d7..43a680bc9c2 100644
--- a/spec/graphql/types/projects/base_service_type_spec.rb
+++ b/spec/graphql/types/projects/base_service_type_spec.rb
@@ -6,7 +6,7 @@ RSpec.describe GitlabSchema.types['BaseService'] do
specify { expect(described_class.graphql_name).to eq('BaseService') }
it 'has basic expected fields' do
- expect(described_class).to have_graphql_fields(:type, :active)
+ expect(described_class).to have_graphql_fields(:type, :active, :service_type)
end
specify { expect(described_class).to require_graphql_authorizations(:admin_project) }
diff --git a/spec/graphql/types/projects/jira_service_type_spec.rb b/spec/graphql/types/projects/jira_service_type_spec.rb
index 9db580ac963..69cdcb0f46f 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 @@ RSpec.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, :projects)
+ expect(described_class).to have_graphql_fields(:type, :active, :projects, :service_type)
end
specify { expect(described_class).to require_graphql_authorizations(:admin_project) }
diff --git a/spec/graphql/types/projects/service_type_enum_spec.rb b/spec/graphql/types/projects/service_type_enum_spec.rb
new file mode 100644
index 00000000000..ead69e60f6c
--- /dev/null
+++ b/spec/graphql/types/projects/service_type_enum_spec.rb
@@ -0,0 +1,55 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe GitlabSchema.types['ServiceType'] do
+ it 'exposes all the existing project services' do
+ expect(described_class.values.keys).to include(*core_service_enums)
+ end
+
+ def core_service_enums
+ %w[
+ ASANA_SERVICE
+ ASSEMBLA_SERVICE
+ BAMBOO_SERVICE
+ BUGZILLA_SERVICE
+ BUILDKITE_SERVICE
+ CAMPFIRE_SERVICE
+ CONFLUENCE_SERVICE
+ CUSTOM_ISSUE_TRACKER_SERVICE
+ DATADOG_SERVICE
+ DISCORD_SERVICE
+ DRONE_CI_SERVICE
+ EMAILS_ON_PUSH_SERVICE
+ EWM_SERVICE
+ EXTERNAL_WIKI_SERVICE
+ FLOWDOCK_SERVICE
+ HANGOUTS_CHAT_SERVICE
+ IRKER_SERVICE
+ JENKINS_SERVICE
+ JIRA_SERVICE
+ MATTERMOST_SERVICE
+ MATTERMOST_SLASH_COMMANDS_SERVICE
+ MICROSOFT_TEAMS_SERVICE
+ PACKAGIST_SERVICE
+ PIPELINES_EMAIL_SERVICE
+ PIVOTALTRACKER_SERVICE
+ PROMETHEUS_SERVICE
+ PUSHOVER_SERVICE
+ REDMINE_SERVICE
+ SHIMO_SERVICE
+ SLACK_SERVICE
+ SLACK_SLASH_COMMANDS_SERVICE
+ TEAMCITY_SERVICE
+ UNIFY_CIRCUIT_SERVICE
+ WEBEX_TEAMS_SERVICE
+ YOUTRACK_SERVICE
+ ZENTAO_SERVICE
+ ]
+ end
+
+ it 'coerces values correctly' do
+ integration = build(:jenkins_integration)
+ expect(described_class.coerce_isolated_result(integration.type)).to eq 'JENKINS_SERVICE'
+ end
+end
diff --git a/spec/graphql/types/projects/service_type_spec.rb b/spec/graphql/types/projects/service_type_spec.rb
index 0bffdfd629d..1a6a128544e 100644
--- a/spec/graphql/types/projects/service_type_spec.rb
+++ b/spec/graphql/types/projects/service_type_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
RSpec.describe Types::Projects::ServiceType do
- specify { expect(described_class).to have_graphql_fields(:type, :active) }
+ specify { expect(described_class).to have_graphql_fields(:type, :service_type, :active) }
describe ".resolve_type" do
it 'resolves the corresponding type for objects' do
diff --git a/spec/graphql/types/projects/services_enum_spec.rb b/spec/graphql/types/projects/services_enum_spec.rb
deleted file mode 100644
index 00427e1d580..00000000000
--- a/spec/graphql/types/projects/services_enum_spec.rb
+++ /dev/null
@@ -1,13 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe GitlabSchema.types['ServiceType'] do
- it 'exposes all the existing project services' do
- expect(described_class.values.keys).to match_array(available_services_enum)
- end
-
- def available_services_enum
- ::Integration.available_integration_types(include_dev: false).map(&:underscore).map(&:upcase)
- end
-end
diff --git a/spec/graphql/types/query_type_spec.rb b/spec/graphql/types/query_type_spec.rb
index 49f0980bd08..8b8c44c10f6 100644
--- a/spec/graphql/types/query_type_spec.rb
+++ b/spec/graphql/types/query_type_spec.rb
@@ -29,6 +29,7 @@ RSpec.describe GitlabSchema.types['Query'] do
timelogs
board_list
topics
+ gitpod_enabled
]
expect(described_class).to have_graphql_fields(*expected_fields).at_least
diff --git a/spec/graphql/types/repository/blob_type_spec.rb b/spec/graphql/types/repository/blob_type_spec.rb
index 565341d15b9..a813ef85e6e 100644
--- a/spec/graphql/types/repository/blob_type_spec.rb
+++ b/spec/graphql/types/repository/blob_type_spec.rb
@@ -25,12 +25,15 @@ RSpec.describe Types::Repository::BlobType do
:raw_path,
:replace_path,
:pipeline_editor_path,
+ :gitpod_blob_url,
:find_file_path,
:blame_path,
:history_path,
:permalink_path,
:environment_formatted_external_url,
:environment_external_url_for_route_map,
+ :code_navigation_path,
+ :project_blob_path_root,
:code_owners,
:simple_viewer,
:rich_viewer,
@@ -42,6 +45,7 @@ RSpec.describe Types::Repository::BlobType do
:external_storage_url,
:fork_and_edit_path,
:ide_fork_and_edit_path,
+ :fork_and_view_path,
:language
)
end
diff --git a/spec/graphql/types/saved_reply_type_spec.rb b/spec/graphql/types/saved_reply_type_spec.rb
new file mode 100644
index 00000000000..3bf4d823588
--- /dev/null
+++ b/spec/graphql/types/saved_reply_type_spec.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe GitlabSchema.types['SavedReply'] do
+ specify { expect(described_class.graphql_name).to eq('SavedReply') }
+
+ it 'has all the required fields' do
+ expect(described_class).to have_graphql_fields(:id, :content, :name)
+ end
+
+ specify { expect(described_class).to require_graphql_authorizations(:read_saved_replies) }
+end
diff --git a/spec/graphql/types/todo_type_spec.rb b/spec/graphql/types/todo_type_spec.rb
index 15b6195ec5c..8de63ebfda5 100644
--- a/spec/graphql/types/todo_type_spec.rb
+++ b/spec/graphql/types/todo_type_spec.rb
@@ -4,7 +4,7 @@ require 'spec_helper'
RSpec.describe GitlabSchema.types['Todo'] do
it 'has the correct fields' do
- expected_fields = [:id, :project, :group, :author, :action, :target_type, :body, :state, :created_at]
+ expected_fields = [:id, :project, :group, :author, :action, :target, :target_type, :body, :state, :created_at]
expect(described_class).to have_graphql_fields(*expected_fields)
end
diff --git a/spec/graphql/types/todoable_interface_spec.rb b/spec/graphql/types/todoable_interface_spec.rb
new file mode 100644
index 00000000000..bafd89fbf59
--- /dev/null
+++ b/spec/graphql/types/todoable_interface_spec.rb
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Types::TodoableInterface do
+ it 'exposes the expected fields' do
+ expected_fields = %i[
+ web_url
+ ]
+
+ 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)
+ expect(described_class.resolve_type(build(:commit), {})).to eq(Types::CommitType)
+ end
+
+ it 'raises an error for an unknown type' do
+ project = build(:project)
+
+ expect { described_class.resolve_type(project, {}) }.to raise_error("Unknown GraphQL type for #{project}")
+ end
+ end
+end
diff --git a/spec/graphql/types/user_type_spec.rb b/spec/graphql/types/user_type_spec.rb
index a2fc8f4c954..c913a4c3662 100644
--- a/spec/graphql/types/user_type_spec.rb
+++ b/spec/graphql/types/user_type_spec.rb
@@ -39,6 +39,10 @@ RSpec.describe GitlabSchema.types['User'] do
namespace
timelogs
groups
+ gitpodEnabled
+ preferencesGitpodPath
+ profileEnableGitpodPath
+ savedReplies
]
expect(described_class).to have_graphql_fields(*expected_fields)
@@ -49,10 +53,13 @@ RSpec.describe GitlabSchema.types['User'] do
let_it_be(:user) { create(:user) }
let_it_be(:requested_user) { create(:user, name: 'John Smith') }
let_it_be(:requested_project_bot) { create(:user, :project_bot, name: 'Project bot') }
+ let_it_be(:requested_group_bot) { create(:user, :project_bot, name: 'Group bot') }
let_it_be(:project) { create(:project, :public) }
+ let_it_be(:group) { create(:group, :public) }
before do
project.add_maintainer(requested_project_bot)
+ group.add_maintainer(requested_group_bot)
end
let(:username) { requested_user.username }
@@ -120,6 +127,50 @@ RSpec.describe GitlabSchema.types['User'] do
end
end
end
+
+ context 'a group bot' do
+ let(:username) { requested_group_bot.username }
+
+ context 'when requester is nil' do
+ let(:current_user) { nil }
+
+ it 'returns `****`' do
+ expect(user_name).to eq('****')
+ end
+ end
+
+ context 'when the requester is not a group member' do
+ it 'returns `Group bot` for a non group member in a public group' do
+ expect(user_name).to eq('Group bot')
+ end
+
+ context 'in a private group' do
+ let(:group) { create(:group, :private) }
+
+ it 'returns `****` for a non group member in a private group' do
+ expect(user_name).to eq('****')
+ end
+ end
+ end
+
+ context 'with a group member' do
+ before do
+ group.add_guest(user)
+ end
+
+ it 'returns `Group bot` for a group member' do
+ expect(user_name).to eq('Group bot')
+ end
+
+ context 'in a private group' do
+ let(:group) { create(:group, :private) }
+
+ it 'returns `Group bot` for a group member in a private group' do
+ expect(user_name).to eq('Group bot')
+ end
+ end
+ end
+ end
end
end
@@ -139,6 +190,14 @@ RSpec.describe GitlabSchema.types['User'] do
expect(subject).to eq('Project bot')
end
end
+
+ context 'a group bot' do
+ let(:username) { requested_group_bot.username }
+
+ it 'returns name' do
+ expect(subject).to eq('Group bot')
+ end
+ end
end
end
diff --git a/spec/graphql/types/work_item_id_type_spec.rb b/spec/graphql/types/work_item_id_type_spec.rb
new file mode 100644
index 00000000000..dc02401a3d0
--- /dev/null
+++ b/spec/graphql/types/work_item_id_type_spec.rb
@@ -0,0 +1,51 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Types::WorkItemIdType do
+ let_it_be(:project) { create(:project) }
+ let_it_be(:work_item) { create(:work_item, project: project) }
+ let_it_be(:issue) { create(:issue, project: project) }
+
+ let(:work_item_gid) { work_item.to_gid }
+ let(:issue_gid) { issue.to_gid }
+ let(:ctx) { {} }
+
+ describe '.coerce_input' do
+ it 'can coerce valid issue input' do
+ coerced = described_class.coerce_input(issue_gid.to_s, ctx)
+
+ expect(coerced).to eq(WorkItem.find(issue.id).to_gid)
+ end
+
+ it 'can coerce valid work item input' do
+ coerced = described_class.coerce_input(work_item_gid.to_s, ctx)
+
+ expect(coerced).to eq(work_item_gid)
+ end
+
+ it 'fails for other input types' do
+ project_gid = project.to_gid
+
+ expect { described_class.coerce_input(project_gid.to_s, ctx) }
+ .to raise_error(GraphQL::CoercionError, "#{project_gid.to_s.inspect} does not represent an instance of WorkItem")
+ end
+ end
+
+ describe '.coerce_result' do
+ it 'can coerce issue results and return a WorkItem global ID' do
+ expect(described_class.coerce_result(issue_gid, ctx)).to eq(WorkItem.find(issue.id).to_gid.to_s)
+ end
+
+ it 'can coerce work item results' do
+ expect(described_class.coerce_result(work_item_gid, ctx)).to eq(work_item_gid.to_s)
+ end
+
+ it 'fails for other input types' do
+ project_gid = project.to_gid
+
+ expect { described_class.coerce_result(project_gid, ctx) }
+ .to raise_error(GraphQL::CoercionError, "Expected a WorkItem ID, got #{project_gid}")
+ end
+ end
+end
diff --git a/spec/graphql/types/work_item_type_spec.rb b/spec/graphql/types/work_item_type_spec.rb
new file mode 100644
index 00000000000..6a5b4a0882e
--- /dev/null
+++ b/spec/graphql/types/work_item_type_spec.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe GitlabSchema.types['WorkItem'] do
+ specify { expect(described_class.graphql_name).to eq('WorkItem') }
+
+ specify { expect(described_class).to require_graphql_authorizations(:read_work_item) }
+
+ it 'has specific fields' do
+ fields = %i[description description_html id iid lock_version state title title_html work_item_type]
+
+ fields.each do |field_name|
+ expect(described_class).to have_graphql_fields(*fields)
+ end
+ end
+end
diff --git a/spec/helpers/application_helper_spec.rb b/spec/helpers/application_helper_spec.rb
index e6a2e3f8211..47c31546629 100644
--- a/spec/helpers/application_helper_spec.rb
+++ b/spec/helpers/application_helper_spec.rb
@@ -517,4 +517,112 @@ RSpec.describe ApplicationHelper do
end
end
end
+
+ describe '#dispensable_render' do
+ context 'when an error occurs in the template to be rendered' do
+ before do
+ allow(helper).to receive(:render).and_raise
+ end
+
+ it 'calls `track_and_raise_for_dev_exception`' do
+ expect(Gitlab::ErrorTracking).to receive(:track_and_raise_for_dev_exception)
+ helper.dispensable_render
+ end
+
+ context 'for development environment' do
+ before do
+ stub_rails_env('development')
+ end
+
+ it 'raises an error' do
+ expect { helper.dispensable_render }.to raise_error(StandardError)
+ end
+ end
+
+ context 'for production environments' do
+ before do
+ stub_rails_env('production')
+ end
+
+ it 'returns nil' do
+ expect(helper.dispensable_render).to be_nil
+ end
+
+ context 'when the feature flag is disabled' do
+ before do
+ stub_feature_flags(dispensable_render: false)
+ end
+
+ it 'raises an error' do
+ expect { helper.dispensable_render }.to raise_error(StandardError)
+ end
+ end
+ end
+ end
+
+ context 'when no error occurs in the template to be rendered' do
+ before do
+ allow(helper).to receive(:render).and_return('foo')
+ end
+
+ it 'does not track or raise and returns the rendered content' do
+ expect(Gitlab::ErrorTracking).not_to receive(:track_and_raise_for_dev_exception)
+ expect(helper.dispensable_render).to eq('foo')
+ end
+ end
+ end
+
+ describe '#dispensable_render_if_exists' do
+ context 'when an error occurs in the template to be rendered' do
+ before do
+ allow(helper).to receive(:render_if_exists).and_raise
+ end
+
+ it 'calls `track_and_raise_for_dev_exception`' do
+ expect(Gitlab::ErrorTracking).to receive(:track_and_raise_for_dev_exception)
+ helper.dispensable_render_if_exists
+ end
+
+ context 'for development environment' do
+ before do
+ stub_rails_env('development')
+ end
+
+ it 'raises an error' do
+ expect { helper.dispensable_render_if_exists }.to raise_error(StandardError)
+ end
+ end
+
+ context 'for production environments' do
+ before do
+ stub_rails_env('production')
+ end
+
+ it 'returns nil' do
+ expect(helper.dispensable_render_if_exists).to be_nil
+ end
+
+ context 'when the feature flag is disabled' do
+ before do
+ stub_feature_flags(dispensable_render: false)
+ end
+
+ it 'raises an error' do
+ expect { helper.dispensable_render_if_exists }.to raise_error(StandardError)
+ end
+ end
+ end
+ end
+
+ context 'when no error occurs in the template to be rendered' do
+ before do
+ allow(helper).to receive(:render_if_exists).and_return('foo')
+ end
+
+ it 'does not track or raise' do
+ expect(Gitlab::ErrorTracking).not_to receive(:track_and_raise_for_dev_exception)
+ expect(helper.dispensable_render_if_exists).to eq('foo')
+ end
+ end
+ end
end
diff --git a/spec/helpers/application_settings_helper_spec.rb b/spec/helpers/application_settings_helper_spec.rb
index 169b1c75995..26d48bef24e 100644
--- a/spec/helpers/application_settings_helper_spec.rb
+++ b/spec/helpers/application_settings_helper_spec.rb
@@ -51,7 +51,7 @@ RSpec.describe ApplicationSettingsHelper do
issues_create_limit notes_create_limit project_export_limit
project_download_export_limit project_export_limit project_import_limit
raw_blob_request_limit group_export_limit group_download_export_limit
- group_import_limit users_get_by_id_limit user_email_lookup_limit
+ group_import_limit users_get_by_id_limit search_rate_limit search_rate_limit_unauthenticated
))
end
@@ -293,4 +293,25 @@ RSpec.describe ApplicationSettingsHelper do
it { is_expected.to eq([%w(Track track), %w(Compress compress)]) }
end
+
+ describe '#instance_clusters_enabled?' do
+ let_it_be(:user) { create(:user) }
+
+ subject { helper.instance_clusters_enabled? }
+
+ before do
+ allow(helper).to receive(:current_user).and_return(user)
+ allow(helper).to receive(:can?).with(user, :read_cluster, instance_of(Clusters::Instance)).and_return(true)
+ end
+
+ it { is_expected.to be_truthy}
+
+ context ':certificate_based_clusters feature flag is disabled' do
+ before do
+ stub_feature_flags(certificate_based_clusters: false)
+ end
+
+ it { is_expected.to be_falsey }
+ end
+ end
end
diff --git a/spec/helpers/blob_helper_spec.rb b/spec/helpers/blob_helper_spec.rb
index efcb8125f68..65e46b61882 100644
--- a/spec/helpers/blob_helper_spec.rb
+++ b/spec/helpers/blob_helper_spec.rb
@@ -54,42 +54,6 @@ RSpec.describe BlobHelper do
expect(Capybara.string(link_with_mr).find_link('Edit')[:href]).to eq("/#{project.full_path}/-/edit/master/README.md?mr_id=10")
end
-
- context 'when edit is the primary button' do
- before do
- stub_feature_flags(web_ide_primary_edit: false)
- end
-
- it 'is rendered as primary' do
- expect(link).not_to match(/btn-inverted/)
- end
-
- it 'passes on primary tracking attributes' do
- parsed_link = Capybara.string(link).find_link('Edit')
-
- expect(parsed_link[:'data-track-action']).to eq("click_edit")
- expect(parsed_link[:'data-track-label']).to eq("edit")
- expect(parsed_link[:'data-track-property']).to eq(nil)
- end
- end
-
- context 'when Web IDE is the primary button' do
- before do
- stub_feature_flags(web_ide_primary_edit: true)
- end
-
- it 'is rendered as inverted' do
- expect(link).to match(/btn-inverted/)
- end
-
- it 'passes on secondary tracking attributes' do
- parsed_link = Capybara.string(link).find_link('Edit')
-
- expect(parsed_link[:'data-track-action']).to eq("click_edit")
- expect(parsed_link[:'data-track-label']).to eq("edit")
- expect(parsed_link[:'data-track-property']).to eq("secondary")
- end
- end
end
describe "#relative_raw_path" do
@@ -324,63 +288,6 @@ RSpec.describe BlobHelper do
end
end
- describe `#ide_edit_button` do
- let_it_be(:namespace) { create(:namespace, name: 'gitlab') }
- let_it_be(:project) { create(:project, :repository, namespace: namespace) }
- let_it_be(:current_user) { create(:user) }
-
- let(:can_push_code) { true }
- let(:blob) { project.repository.blob_at('refs/heads/master', 'README.md') }
-
- subject(:link) { helper.ide_edit_button(project, 'master', 'README.md', blob: blob) }
-
- before do
- allow(helper).to receive(:current_user).and_return(current_user)
- allow(helper).to receive(:can?).with(current_user, :push_code, project).and_return(can_push_code)
- allow(helper).to receive(:can_collaborate_with_project?).and_return(true)
- end
-
- it 'returns a link with a Web IDE route' do
- expect(Capybara.string(link).find_link('Web IDE')[:href]).to eq("/-/ide/project/#{project.full_path}/edit/master/-/README.md")
- end
-
- context 'when edit is the primary button' do
- before do
- stub_feature_flags(web_ide_primary_edit: false)
- end
-
- it 'is rendered as inverted' do
- expect(link).to match(/btn-inverted/)
- end
-
- it 'passes on secondary tracking attributes' do
- parsed_link = Capybara.string(link).find_link('Web IDE')
-
- expect(parsed_link[:'data-track-action']).to eq("click_edit_ide")
- expect(parsed_link[:'data-track-label']).to eq("web_ide")
- expect(parsed_link[:'data-track-property']).to eq("secondary")
- end
- end
-
- context 'when Web IDE is the primary button' do
- before do
- stub_feature_flags(web_ide_primary_edit: true)
- end
-
- it 'is rendered as primary' do
- expect(link).not_to match(/btn-inverted/)
- end
-
- it 'passes on primary tracking attributes' do
- parsed_link = Capybara.string(link).find_link('Web IDE')
-
- expect(parsed_link[:'data-track-action']).to eq("click_edit_ide")
- expect(parsed_link[:'data-track-label']).to eq("web_ide")
- expect(parsed_link[:'data-track-property']).to eq(nil)
- end
- end
- end
-
describe '#ide_edit_path' do
let(:project) { create(:project) }
let(:current_user) { create(:user) }
diff --git a/spec/helpers/broadcast_messages_helper_spec.rb b/spec/helpers/broadcast_messages_helper_spec.rb
index 3e8cbdf89a0..e721a3fdc95 100644
--- a/spec/helpers/broadcast_messages_helper_spec.rb
+++ b/spec/helpers/broadcast_messages_helper_spec.rb
@@ -3,6 +3,71 @@
require 'spec_helper'
RSpec.describe BroadcastMessagesHelper do
+ include Gitlab::Routing.url_helpers
+
+ let_it_be(:user) { create(:user) }
+
+ before do
+ allow(helper).to receive(:current_user).and_return(user)
+ end
+
+ shared_examples 'returns role-targeted broadcast message when in project, group, or sub-group URL' do
+ let(:feature_flag_state) { true }
+
+ before do
+ stub_feature_flags(role_targeted_broadcast_messages: feature_flag_state)
+ allow(helper).to receive(:cookies) { {} }
+ end
+
+ context 'when in a project page' do
+ let_it_be(:project) { create(:project) }
+
+ before do
+ project.add_developer(user)
+
+ assign(:project, project)
+ allow(helper).to receive(:controller) { ProjectsController.new }
+ end
+
+ it { is_expected.to eq message }
+
+ context 'when feature flag is disabled' do
+ let(:feature_flag_state) { false }
+
+ it { is_expected.to be_nil }
+ end
+ end
+
+ context 'when in a group page' do
+ let_it_be(:group) { create(:group) }
+
+ before do
+ group.add_developer(user)
+
+ assign(:group, group)
+ allow(helper).to receive(:controller) { GroupsController.new }
+ end
+
+ it { is_expected.to eq message }
+
+ context 'when feature flag is disabled' do
+ let(:feature_flag_state) { false }
+
+ it { is_expected.to be_nil }
+ end
+ end
+
+ context 'when not in a project, group, or sub-group page' do
+ it { is_expected.to be_nil }
+
+ context 'when feature flag is disabled' do
+ let(:feature_flag_state) { false }
+
+ it { is_expected.to be_nil }
+ end
+ end
+ end
+
describe 'current_broadcast_notification_message' do
subject { helper.current_broadcast_notification_message }
@@ -24,16 +89,26 @@ RSpec.describe BroadcastMessagesHelper do
context 'without broadcast notification messages' do
it { is_expected.to be_nil }
end
+
+ describe 'user access level targeted messages' do
+ let_it_be(:message) { create(:broadcast_message, broadcast_type: 'notification', starts_at: Time.now, target_access_levels: [Gitlab::Access::DEVELOPER]) }
+
+ include_examples 'returns role-targeted broadcast message when in project, group, or sub-group URL'
+ end
end
- describe 'broadcast_message' do
- let_it_be(:user) { create(:user) }
+ describe 'current_broadcast_banner_messages' do
+ describe 'user access level targeted messages' do
+ let_it_be(:message) { create(:broadcast_message, broadcast_type: 'banner', starts_at: Time.now, target_access_levels: [Gitlab::Access::DEVELOPER]) }
- let(:current_broadcast_message) { BroadcastMessage.new(message: 'Current Message') }
+ subject { helper.current_broadcast_banner_messages.first }
- before do
- allow(helper).to receive(:current_user).and_return(user)
+ include_examples 'returns role-targeted broadcast message when in project, group, or sub-group URL'
end
+ end
+
+ describe 'broadcast_message' do
+ let(:current_broadcast_message) { BroadcastMessage.new(message: 'Current Message') }
it 'returns nil when no current message' do
expect(helper.broadcast_message(nil)).to be_nil
diff --git a/spec/helpers/ci/pipelines_helper_spec.rb b/spec/helpers/ci/pipelines_helper_spec.rb
index 751bcc97582..2b76eaa87bc 100644
--- a/spec/helpers/ci/pipelines_helper_spec.rb
+++ b/spec/helpers/ci/pipelines_helper_spec.rb
@@ -93,4 +93,63 @@ RSpec.describe Ci::PipelinesHelper do
end
end
end
+
+ describe '#pipelines_list_data' do
+ let_it_be(:project) { create(:project) }
+
+ subject(:data) { helper.pipelines_list_data(project, 'list_url') }
+
+ before do
+ allow(helper).to receive(:can?).and_return(true)
+ end
+
+ it 'has the expected keys' do
+ expect(subject.keys).to match_array([:endpoint,
+ :project_id,
+ :default_branch_name,
+ :params,
+ :artifacts_endpoint,
+ :artifacts_endpoint_placeholder,
+ :pipeline_schedule_url,
+ :empty_state_svg_path,
+ :error_state_svg_path,
+ :no_pipelines_svg_path,
+ :can_create_pipeline,
+ :new_pipeline_path,
+ :ci_lint_path,
+ :reset_cache_path,
+ :has_gitlab_ci,
+ :pipeline_editor_path,
+ :suggested_ci_templates,
+ :ci_runner_settings_path])
+ end
+
+ describe 'the `any_runners_available` attribute' do
+ subject { data[:any_runners_available] }
+
+ context 'when the `runners_availability_section` experiment variant is control' do
+ before do
+ stub_experiments(runners_availability_section: :control)
+ end
+
+ it { is_expected.to be_nil }
+ end
+
+ context 'when the `runners_availability_section` experiment variant is candidate' do
+ before do
+ stub_experiments(runners_availability_section: :candidate)
+ end
+
+ context 'when there are no runners' do
+ it { is_expected.to eq('false') }
+ end
+
+ context 'when there are runners' do
+ let!(:runner) { create(:ci_runner, :project, projects: [project]) }
+
+ it { is_expected.to eq('true') }
+ end
+ end
+ end
+ end
end
diff --git a/spec/helpers/clusters_helper_spec.rb b/spec/helpers/clusters_helper_spec.rb
index 18d233fcd63..53d33f2875f 100644
--- a/spec/helpers/clusters_helper_spec.rb
+++ b/spec/helpers/clusters_helper_spec.rb
@@ -31,34 +31,6 @@ RSpec.describe ClustersHelper do
end
end
- describe '#create_new_cluster_label' do
- subject { helper.create_new_cluster_label(provider: provider) }
-
- context 'GCP provider' do
- let(:provider) { 'gcp' }
-
- it { is_expected.to eq('Create new cluster on GKE') }
- end
-
- context 'AWS provider' do
- let(:provider) { 'aws' }
-
- it { is_expected.to eq('Create new cluster on EKS') }
- end
-
- context 'other provider' do
- let(:provider) { 'other' }
-
- it { is_expected.to eq('Create new cluster') }
- end
-
- context 'no provider' do
- let(:provider) { nil }
-
- it { is_expected.to eq('Create new cluster') }
- end
- end
-
describe '#js_clusters_list_data' do
let_it_be(:current_user) { create(:user) }
let_it_be(:project) { build(:project) }
@@ -66,6 +38,11 @@ RSpec.describe ClustersHelper do
subject { helper.js_clusters_list_data(clusterable) }
+ before do
+ helper.send(:default_branch_name, clusterable)
+ helper.send(:clusterable_project_path, clusterable)
+ end
+
it 'displays endpoint path' do
expect(subject[:endpoint]).to eq("#{project_path(project)}/-/clusters.json")
end
@@ -86,10 +63,31 @@ RSpec.describe ClustersHelper do
it 'displays empty image path' do
expect(subject[:clusters_empty_state_image]).to match(%r(/illustrations/empty-state/empty-state-clusters|svg))
+ expect(subject[:empty_state_image]).to match(%r(/illustrations/empty-state/empty-state-agents|svg))
end
it 'displays create cluster using certificate path' do
- expect(subject[:new_cluster_path]).to eq("#{project_path(project)}/-/clusters/new?tab=create")
+ expect(subject[:new_cluster_path]).to eq("#{project_path(project)}/-/clusters/new")
+ end
+
+ it 'displays add cluster using certificate path' do
+ expect(subject[:add_cluster_path]).to eq("#{project_path(project)}/-/clusters/connect")
+ end
+
+ it 'displays project default branch' do
+ expect(subject[:default_branch_name]).to eq(project.default_branch)
+ end
+
+ it 'displays project path' do
+ expect(subject[:project_path]).to eq(project.full_path)
+ end
+
+ it 'displays kas address' do
+ expect(subject[:kas_address]).to eq(Gitlab::Kas.external_url)
+ end
+
+ it 'displays GitLab version' do
+ expect(subject[:gitlab_version]).to eq(Gitlab.version_info)
end
context 'user has no permissions to create a cluster' do
@@ -114,6 +112,10 @@ RSpec.describe ClustersHelper do
it 'doesn\'t display empty state help text' do
expect(subject[:empty_state_help_text]).to be_nil
end
+
+ it 'displays display_cluster_agents as true' do
+ expect(subject[:display_cluster_agents]).to eq("true")
+ end
end
context 'group cluster' do
@@ -123,38 +125,40 @@ RSpec.describe ClustersHelper do
it 'displays empty state help text' do
expect(subject[:empty_state_help_text]).to eq(s_('ClusterIntegration|Adding an integration to your group will share the cluster across all your projects.'))
end
- end
- end
- describe '#js_clusters_data' do
- let_it_be(:current_user) { create(:user) }
- let_it_be(:project) { build(:project) }
- let_it_be(:clusterable) { ClusterablePresenter.fabricate(project, current_user: current_user) }
+ it 'displays display_cluster_agents as false' do
+ expect(subject[:display_cluster_agents]).to eq("false")
+ end
- subject { helper.js_clusters_data(clusterable) }
+ it 'does not include a default branch' do
+ expect(subject[:default_branch_name]).to be_nil
+ end
- it 'displays project default branch' do
- expect(subject[:default_branch_name]).to eq(project.default_branch)
+ it 'does not include a project path' do
+ expect(subject[:project_path]).to be_nil
+ end
end
- it 'displays image path' do
- expect(subject[:empty_state_image]).to match(%r(/illustrations/empty-state/empty-state-agents|svg))
- end
+ describe 'certificate based clusters enabled' do
+ before do
+ stub_feature_flags(certificate_based_clusters: flag_enabled)
+ end
- it 'displays project path' do
- expect(subject[:project_path]).to eq(project.full_path)
- end
+ context 'feature flag is enabled' do
+ let(:flag_enabled) { true }
- it 'displays add cluster using certificate path' do
- expect(subject[:add_cluster_path]).to eq("#{project_path(project)}/-/clusters/new?tab=add")
- end
+ it do
+ expect(subject[:certificate_based_clusters_enabled]).to eq('true')
+ end
+ end
- it 'displays kas address' do
- expect(subject[:kas_address]).to eq(Gitlab::Kas.external_url)
- end
+ context 'feature flag is disabled' do
+ let(:flag_enabled) { false }
- it 'displays GitLab version' do
- expect(subject[:gitlab_version]).to eq(Gitlab.version_info)
+ it do
+ expect(subject[:certificate_based_clusters_enabled]).to eq('false')
+ end
+ end
end
end
@@ -220,4 +224,33 @@ RSpec.describe ClustersHelper do
end
end
end
+
+ describe '#default_branch_name' do
+ subject { default_branch_name(clusterable) }
+
+ context 'when clusterable is a project without a repository' do
+ let(:clusterable) { build(:project) }
+
+ it 'allows default branch name to display default name from settings' do
+ expect(subject).to eq(Gitlab::CurrentSettings.default_branch_name)
+ end
+ end
+
+ context 'when clusterable is a project with a repository' do
+ let(:clusterable) { build(:project, :repository) }
+ let(:repository) { clusterable.repository }
+
+ it 'allows default branch name to display repository root branch' do
+ expect(subject).to eq(repository.root_ref)
+ end
+ end
+
+ context 'when clusterable is a group' do
+ let(:clusterable) { build(:group) }
+
+ it 'does not allow default branch name to display' do
+ expect(subject).to be_nil
+ end
+ end
+ end
end
diff --git a/spec/helpers/commits_helper_spec.rb b/spec/helpers/commits_helper_spec.rb
index 34445d26258..98db185c180 100644
--- a/spec/helpers/commits_helper_spec.rb
+++ b/spec/helpers/commits_helper_spec.rb
@@ -86,6 +86,31 @@ RSpec.describe CommitsHelper do
end
end
+ describe '#diff_mode_swap_button' do
+ let(:keyword) { 'rendered' }
+ let(:node) { Nokogiri::HTML.parse(helper.diff_mode_swap_button(keyword, 'abc')).at_css('a') }
+
+ context 'for rendered' do
+ it 'renders the correct select-rendered button' do
+ expect(node[:title]).to eq('Display rendered diff')
+ expect(node['data-file-hash']).to eq('abc')
+ expect(node['data-diff-toggle-entity']).to eq('toShowBtn')
+ expect(node.xpath("//a/svg")[0]["data-testid"]).to eq('doc-text-icon')
+ end
+ end
+
+ context 'for raw' do
+ let(:keyword) { 'raw' }
+
+ it 'renders the correct select-raw button' do
+ expect(node[:title]).to eq('Display raw diff')
+ expect(node['data-file-hash']).to eq('abc')
+ expect(node['data-diff-toggle-entity']).to eq('toHideBtn')
+ expect(node.xpath("//a/svg")[0]["data-testid"]).to eq('doc-code-icon')
+ end
+ end
+ end
+
describe '#commit_to_html' do
let(:project) { create(:project, :repository) }
let(:ref) { 'master' }
diff --git a/spec/helpers/container_expiration_policies_helper_spec.rb b/spec/helpers/container_expiration_policies_helper_spec.rb
index acb6b017d2c..704e63730c8 100644
--- a/spec/helpers/container_expiration_policies_helper_spec.rb
+++ b/spec/helpers/container_expiration_policies_helper_spec.rb
@@ -3,8 +3,6 @@
require 'spec_helper'
RSpec.describe ContainerExpirationPoliciesHelper do
- using RSpec::Parameterized::TableSyntax
-
describe '#keep_n_options' do
it 'returns keep_n options formatted for dropdown usage' do
expected_result = [
@@ -51,23 +49,22 @@ RSpec.describe ContainerExpirationPoliciesHelper do
describe '#container_expiration_policies_historic_entry_enabled?' do
let_it_be(:project) { build_stubbed(:project) }
- subject { helper.container_expiration_policies_historic_entry_enabled?(project) }
+ subject { helper.container_expiration_policies_historic_entry_enabled? }
+
+ context 'when the application setting is enabled' do
+ before do
+ stub_application_setting(container_expiration_policies_enable_historic_entries: true)
+ end
- where(:application_setting, :feature_flag, :expected_result) do
- true | true | true
- true | false | true
- false | true | true
- false | false | false
+ it { is_expected.to be_truthy }
end
- with_them do
+ context 'when the application setting is disabled' do
before do
- stub_feature_flags(container_expiration_policies_historic_entry: false)
- stub_application_setting(container_expiration_policies_enable_historic_entries: application_setting)
- stub_feature_flags(container_expiration_policies_historic_entry: project) if feature_flag
+ stub_application_setting(container_expiration_policies_enable_historic_entries: false)
end
- it { is_expected.to eq(expected_result) }
+ it { is_expected.to be_falsey }
end
end
end
diff --git a/spec/helpers/container_registry_helper_spec.rb b/spec/helpers/container_registry_helper_spec.rb
index 49e56113dd8..57641d4b5df 100644
--- a/spec/helpers/container_registry_helper_spec.rb
+++ b/spec/helpers/container_registry_helper_spec.rb
@@ -3,25 +3,17 @@
require 'spec_helper'
RSpec.describe ContainerRegistryHelper do
- using RSpec::Parameterized::TableSyntax
-
describe '#container_registry_expiration_policies_throttling?' do
subject { helper.container_registry_expiration_policies_throttling? }
- where(:feature_flag_enabled, :client_support, :expected_result) do
- true | true | true
- true | false | false
- false | true | false
- false | false | false
- end
+ it { is_expected.to eq(true) }
- with_them do
+ context 'with container_registry_expiration_policies_throttling disabled' do
before do
- stub_feature_flags(container_registry_expiration_policies_throttling: feature_flag_enabled)
- allow(ContainerRegistry::Client).to receive(:supports_tag_delete?).and_return(client_support)
+ stub_feature_flags(container_registry_expiration_policies_throttling: false)
end
- it { is_expected.to eq(expected_result) }
+ it { is_expected.to eq(false) }
end
end
end
diff --git a/spec/helpers/deploy_tokens_helper_spec.rb b/spec/helpers/deploy_tokens_helper_spec.rb
new file mode 100644
index 00000000000..e5dd5ff79a2
--- /dev/null
+++ b/spec/helpers/deploy_tokens_helper_spec.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe DeployTokensHelper do
+ describe '#deploy_token_revoke_button_data' do
+ let_it_be(:token) { build(:deploy_token) }
+ let_it_be(:project) { build(:project) }
+ let_it_be(:revoke_deploy_token_path) { '/foobar/baz/-/deploy_tokens/1/revoke' }
+
+ it 'returns expected hash' do
+ expect(helper).to receive(:revoke_deploy_token_path).with(project, token).and_return(revoke_deploy_token_path)
+
+ expect(helper.deploy_token_revoke_button_data(token: token, group_or_project: project)).to match({
+ token: token.to_json(only: [:id, :name]),
+ revoke_path: revoke_deploy_token_path
+ })
+ end
+ end
+end
diff --git a/spec/helpers/explore_helper_spec.rb b/spec/helpers/explore_helper_spec.rb
index d843a9d3ce5..4ae1b738858 100644
--- a/spec/helpers/explore_helper_spec.rb
+++ b/spec/helpers/explore_helper_spec.rb
@@ -25,4 +25,33 @@ RSpec.describe ExploreHelper do
helper.public_visibility_restricted?
end
end
+
+ describe '#projects_filter_items' do
+ let(:projects_filter_items) do
+ [
+ { href: '?', text: 'Any', value: 'Any' },
+ { href: '?visibility_level=0', text: 'Private', value: 'Private' },
+ { href: '?visibility_level=10', text: 'Internal', value: 'Internal' },
+ { href: '?visibility_level=20', text: 'Public', value: 'Public' }
+ ]
+ end
+
+ it 'returns correct dropdown items' do
+ expect(helper.projects_filter_items).to eq(projects_filter_items)
+ end
+ end
+
+ describe '#projects_filter_selected' do
+ context 'when visibility_level is present' do
+ it 'returns corresponding item' do
+ expect(helper.projects_filter_selected('0')).to eq('Private')
+ end
+ end
+
+ context 'when visibility_level is empty' do
+ it 'returns corresponding item' do
+ expect(helper.projects_filter_selected(nil)).to eq('Any')
+ end
+ end
+ end
end
diff --git a/spec/helpers/groups/crm_settings_helper_spec.rb b/spec/helpers/groups/crm_settings_helper_spec.rb
index 6376cabda3a..87690e7debc 100644
--- a/spec/helpers/groups/crm_settings_helper_spec.rb
+++ b/spec/helpers/groups/crm_settings_helper_spec.rb
@@ -3,23 +3,45 @@
require 'spec_helper'
RSpec.describe Groups::CrmSettingsHelper do
- let_it_be(:group) { create(:group) }
+ let_it_be(:root_group) { create(:group) }
- describe '#crm_feature_flag_enabled?' do
+ describe '#crm_feature_available?' do
subject do
- helper.crm_feature_flag_enabled?(group)
+ helper.crm_feature_available?(group)
end
- context 'when feature flag is enabled' do
- it { is_expected.to be_truthy }
+ context 'in root group' do
+ let(:group) { root_group }
+
+ context 'when feature flag is enabled' do
+ it { is_expected.to be_truthy }
+ end
+
+ context 'when feature flag is disabled' do
+ before do
+ stub_feature_flags(customer_relations: false)
+ end
+
+ it { is_expected.to be_falsy }
+ end
end
- context 'when feature flag is disabled' do
- before do
- stub_feature_flags(customer_relations: false)
+ context 'in subgroup' do
+ let_it_be(:subgroup) { create(:group, parent: root_group) }
+
+ let(:group) { subgroup }
+
+ context 'when feature flag is enabled' do
+ it { is_expected.to be_truthy }
end
- it { is_expected.to be_falsy }
+ context 'when feature flag is disabled' do
+ before do
+ stub_feature_flags(customer_relations: false)
+ end
+
+ it { is_expected.to be_falsy }
+ end
end
end
end
diff --git a/spec/helpers/icons_helper_spec.rb b/spec/helpers/icons_helper_spec.rb
index af2957d72c7..139e8be33d5 100644
--- a/spec/helpers/icons_helper_spec.rb
+++ b/spec/helpers/icons_helper_spec.rb
@@ -231,23 +231,33 @@ RSpec.describe IconsHelper do
end
end
- describe 'loading_icon' do
- it 'returns span with gl-spinner class and default configuration' do
- expect(loading_icon.to_s)
- .to eq '<span class="gl-spinner gl-spinner-orange gl-spinner-sm" aria-label="Loading"></span>'
+ describe 'gl_loading_icon' do
+ it 'returns the default spinner markup' do
+ expect(gl_loading_icon.to_s)
+ .to eq '<div class="gl-spinner-container" role="status"><span class="gl-spinner gl-spinner-dark gl-spinner-sm gl-vertical-align-text-bottom!" aria-label="Loading"></span></div>'
end
context 'when css_class is provided' do
- it 'appends css_class to gl-spinner element' do
- expect(loading_icon(css_class: 'gl-mr-2').to_s)
- .to eq '<span class="gl-spinner gl-spinner-orange gl-spinner-sm gl-mr-2" aria-label="Loading"></span>'
+ it 'appends css_class to container element' do
+ expect(gl_loading_icon(css_class: 'gl-mr-2').to_s).to match 'gl-spinner-container gl-mr-2'
end
end
- context 'when container is true' do
- it 'creates a container that has the gl-spinner-container class selector' do
- expect(loading_icon(container: true).to_s)
- .to eq '<div class="gl-spinner-container"><span class="gl-spinner gl-spinner-orange gl-spinner-sm" aria-label="Loading"></span></div>'
+ context 'when size is provided' do
+ it 'sets the size class' do
+ expect(gl_loading_icon(size: 'xl').to_s).to match 'gl-spinner-xl'
+ end
+ end
+
+ context 'when color is provided' do
+ it 'sets the color class' do
+ expect(gl_loading_icon(color: 'light').to_s).to match 'gl-spinner-light'
+ end
+ end
+
+ context 'when inline is true' do
+ it 'creates an inline container' do
+ expect(gl_loading_icon(inline: true).to_s).to start_with '<span class="gl-spinner-container"'
end
end
end
diff --git a/spec/helpers/integrations_helper_spec.rb b/spec/helpers/integrations_helper_spec.rb
index 38ce17e34ba..3bedc1d8aec 100644
--- a/spec/helpers/integrations_helper_spec.rb
+++ b/spec/helpers/integrations_helper_spec.rb
@@ -3,17 +3,41 @@
require 'spec_helper'
RSpec.describe IntegrationsHelper do
+ shared_examples 'is defined for each integration event' do
+ Integration.available_integration_names.each do |integration|
+ events = Integration.integration_name_to_model(integration).new.configurable_events
+ events.each do |event|
+ context "when integration is #{integration}, event is #{event}" do
+ let(:integration) { integration }
+ let(:event) { event }
+
+ it { is_expected.not_to be_nil }
+ end
+ end
+ end
+ end
+
+ describe '#integration_event_title' do
+ subject { helper.integration_event_title(event) }
+
+ it_behaves_like 'is defined for each integration event'
+ end
+
describe '#integration_event_description' do
- subject(:description) { helper.integration_event_description(integration, 'merge_request_events') }
+ subject { helper.integration_event_description(integration, event) }
+
+ it_behaves_like 'is defined for each integration event'
context 'when integration is Jira' do
let(:integration) { Integrations::Jira.new }
+ let(:event) { 'merge_request_events' }
it { is_expected.to include('Jira') }
end
context 'when integration is Team City' do
let(:integration) { Integrations::Teamcity.new }
+ let(:event) { 'merge_request_events' }
it { is_expected.to include('TeamCity') }
end
@@ -31,6 +55,7 @@ RSpec.describe IntegrationsHelper do
:id,
:show_active,
:activated,
+ :activate_disabled,
:type,
:merge_request_events,
:commit_events,
diff --git a/spec/helpers/invite_members_helper_spec.rb b/spec/helpers/invite_members_helper_spec.rb
index 6a854a65920..796d68e290e 100644
--- a/spec/helpers/invite_members_helper_spec.rb
+++ b/spec/helpers/invite_members_helper_spec.rb
@@ -147,17 +147,6 @@ RSpec.describe InviteMembersHelper do
expect(helper.can_invite_members_for_project?(project)).to eq true
expect(helper).to have_received(:can?).with(owner, :admin_project_member, project)
end
-
- context 'when feature flag is disabled' do
- before do
- stub_feature_flags(invite_members_group_modal: false)
- end
-
- it 'returns false', :aggregate_failures do
- expect(helper.can_invite_members_for_project?(project)).to eq false
- expect(helper).not_to have_received(:can?).with(owner, :admin_project_member, project)
- end
- end
end
context 'when the user can not manage project members' do
diff --git a/spec/helpers/issues_helper_spec.rb b/spec/helpers/issues_helper_spec.rb
index 2f57657736d..a85b1bd0a48 100644
--- a/spec/helpers/issues_helper_spec.rb
+++ b/spec/helpers/issues_helper_spec.rb
@@ -265,7 +265,7 @@ RSpec.describe IssuesHelper do
is_issue_author: 'false',
issue_path: issue_path(issue),
issue_type: 'issue',
- new_issue_path: new_project_issue_path(project, { issue: { description: "Related to \##{issue.iid}.\n\n" } }),
+ new_issue_path: new_project_issue_path(project, { add_related_issue: issue.iid }),
project_path: project.full_path,
report_abuse_path: new_abuse_report_path(user_id: issue.author.id, ref_url: issue_url(issue)),
submit_as_spam_path: mark_as_spam_project_issue_path(project, issue)
@@ -277,9 +277,7 @@ RSpec.describe IssuesHelper do
shared_examples 'issues list data' do
it 'returns expected result' do
- finder = double.as_null_object
allow(helper).to receive(:current_user).and_return(current_user)
- allow(helper).to receive(:finder).and_return(finder)
allow(helper).to receive(:can?).and_return(true)
allow(helper).to receive(:image_path).and_return('#')
allow(helper).to receive(:import_csv_namespace_project_issues_path).and_return('#')
@@ -308,7 +306,7 @@ RSpec.describe IssuesHelper do
jira_integration_path: help_page_url('integration/jira/issues', anchor: 'view-jira-issues'),
markdown_help_path: help_page_path('user/markdown'),
max_attachment_size: number_to_human_size(Gitlab::CurrentSettings.max_attachment_size.megabytes),
- new_issue_path: new_project_issue_path(project, issue: { milestone_id: finder.milestones.first.id }),
+ new_issue_path: new_project_issue_path(project),
project_import_jira_path: project_import_jira_path(project),
quick_actions_help_path: help_page_path('user/project/quick_actions'),
releases_path: project_releases_path(project, format: :json),
@@ -318,7 +316,7 @@ RSpec.describe IssuesHelper do
sign_in_path: new_user_session_path
}
- expect(helper.project_issues_list_data(project, current_user, finder)).to include(expected)
+ expect(helper.project_issues_list_data(project, current_user)).to include(expected)
end
end
diff --git a/spec/helpers/jira_connect_helper_spec.rb b/spec/helpers/jira_connect_helper_spec.rb
index 0f78185dc7d..1c1b2a22b7c 100644
--- a/spec/helpers/jira_connect_helper_spec.rb
+++ b/spec/helpers/jira_connect_helper_spec.rb
@@ -7,6 +7,11 @@ RSpec.describe JiraConnectHelper do
let_it_be(:subscription) { create(:jira_connect_subscription) }
let(:user) { create(:user) }
+ let(:client_id) { '123' }
+
+ before do
+ stub_env('JIRA_CONNECT_OAUTH_CLIENT_ID', client_id)
+ end
subject { helper.jira_connect_app_data([subscription]) }
@@ -29,6 +34,47 @@ RSpec.describe JiraConnectHelper do
expect(subject[:users_path]).to eq(jira_connect_users_path)
end
+ context 'with oauth_metadata' do
+ let(:oauth_metadata) { helper.jira_connect_app_data([subscription])[:oauth_metadata] }
+
+ subject(:parsed_oauth_metadata) { Gitlab::Json.parse(oauth_metadata).deep_symbolize_keys }
+
+ it 'assigns oauth_metadata' do
+ expect(parsed_oauth_metadata).to include(
+ oauth_authorize_url: start_with('http://test.host/oauth/authorize?'),
+ oauth_token_url: 'http://test.host/oauth/token',
+ state: %r/[a-z0-9.]{32}/,
+ oauth_token_payload: hash_including(
+ grant_type: 'authorization_code',
+ client_id: client_id,
+ redirect_uri: 'http://test.host/-/jira_connect/oauth_callbacks'
+ )
+ )
+ end
+
+ it 'includes oauth_authorize_url with all params' do
+ params = Rack::Utils.parse_nested_query(URI.parse(parsed_oauth_metadata[:oauth_authorize_url]).query)
+
+ expect(params).to include(
+ 'client_id' => client_id,
+ 'response_type' => 'code',
+ 'scope' => 'api',
+ 'redirect_uri' => 'http://test.host/-/jira_connect/oauth_callbacks',
+ 'state' => parsed_oauth_metadata[:state]
+ )
+ end
+
+ context 'jira_connect_oauth feature is disabled' do
+ before do
+ stub_feature_flags(jira_connect_oauth: false)
+ end
+
+ it 'does not assign oauth_metadata' do
+ expect(oauth_metadata).to be_nil
+ end
+ end
+ end
+
it 'passes group as "skip_groups" param' do
skip_groups_param = CGI.escape('skip_groups[]')
diff --git a/spec/helpers/labels_helper_spec.rb b/spec/helpers/labels_helper_spec.rb
index 526983a0d5f..5efa88a2a7d 100644
--- a/spec/helpers/labels_helper_spec.rb
+++ b/spec/helpers/labels_helper_spec.rb
@@ -114,16 +114,16 @@ RSpec.describe LabelsHelper do
describe 'text_color_for_bg' do
it 'uses light text on dark backgrounds' do
- expect(text_color_for_bg('#222E2E')).to eq('#FFFFFF')
+ expect(text_color_for_bg('#222E2E')).to be_color('#FFFFFF')
end
it 'uses dark text on light backgrounds' do
- expect(text_color_for_bg('#EEEEEE')).to eq('#333333')
+ expect(text_color_for_bg('#EEEEEE')).to be_color('#333333')
end
it 'supports RGB triplets' do
- expect(text_color_for_bg('#FFF')).to eq '#333333'
- expect(text_color_for_bg('#000')).to eq '#FFFFFF'
+ expect(text_color_for_bg('#FFF')).to be_color '#333333'
+ expect(text_color_for_bg('#000')).to be_color '#FFFFFF'
end
end
diff --git a/spec/helpers/learn_gitlab_helper_spec.rb b/spec/helpers/learn_gitlab_helper_spec.rb
index ffc2bb31b8f..9fce7495b5a 100644
--- a/spec/helpers/learn_gitlab_helper_spec.rb
+++ b/spec/helpers/learn_gitlab_helper_spec.rb
@@ -97,29 +97,29 @@ RSpec.describe LearnGitlabHelper do
trial_started: a_hash_including(
url: a_string_matching(%r{/learn_gitlab/-/issues/2\z})
),
- issue_created: a_hash_including(
- url: a_string_matching(%r{/learn_gitlab/-/issues/4\z})
- ),
- git_write: a_hash_including(
- url: a_string_matching(%r{/learn_gitlab/-/issues/6\z})
- ),
pipeline_created: a_hash_including(
url: a_string_matching(%r{/learn_gitlab/-/issues/7\z})
),
- user_added: a_hash_including(
- url: a_string_matching(%r{/learn_gitlab/-/issues/8\z})
- ),
- merge_request_created: a_hash_including(
- url: a_string_matching(%r{/learn_gitlab/-/issues/9\z})
- ),
code_owners_enabled: a_hash_including(
url: a_string_matching(%r{/learn_gitlab/-/issues/10\z})
),
required_mr_approvals_enabled: a_hash_including(
url: a_string_matching(%r{/learn_gitlab/-/issues/11\z})
),
+ issue_created: a_hash_including(
+ url: a_string_matching(%r{/learn_gitlab/-/issues\z})
+ ),
+ git_write: a_hash_including(
+ url: a_string_matching(%r{/learn_gitlab\z})
+ ),
+ user_added: a_hash_including(
+ url: a_string_matching(%r{/learn_gitlab/-/project_members\z})
+ ),
+ merge_request_created: a_hash_including(
+ url: a_string_matching(%r{/learn_gitlab/-/merge_requests\z})
+ ),
security_scan_enabled: a_hash_including(
- url: a_string_matching(%r{docs\.gitlab\.com/ee/user/application_security/security_dashboard/#gitlab-security-dashboard-security-center-and-vulnerability-reports\z})
+ url: a_string_matching(%r{/learn_gitlab/-/security/configuration\z})
)
})
end
@@ -137,58 +137,5 @@ RSpec.describe LearnGitlabHelper do
security_scan_enabled: a_hash_including(completed: false)
})
end
-
- context 'when in the new action URLs experiment' do
- before do
- stub_experiments(change_continuous_onboarding_link_urls: :candidate)
- end
-
- it_behaves_like 'has all data'
-
- it 'sets mostly new paths' do
- expect(onboarding_actions_data).to match({
- trial_started: a_hash_including(
- url: a_string_matching(%r{/learn_gitlab/-/issues/2\z})
- ),
- issue_created: a_hash_including(
- url: a_string_matching(%r{/learn_gitlab/-/issues\z})
- ),
- git_write: a_hash_including(
- url: a_string_matching(%r{/learn_gitlab\z})
- ),
- pipeline_created: a_hash_including(
- url: a_string_matching(%r{/learn_gitlab/-/pipelines\z})
- ),
- user_added: a_hash_including(
- url: a_string_matching(%r{/learn_gitlab/-/project_members\z})
- ),
- merge_request_created: a_hash_including(
- url: a_string_matching(%r{/learn_gitlab/-/merge_requests\z})
- ),
- code_owners_enabled: a_hash_including(
- url: a_string_matching(%r{/learn_gitlab/-/issues/10\z})
- ),
- required_mr_approvals_enabled: a_hash_including(
- url: a_string_matching(%r{/learn_gitlab/-/issues/11\z})
- ),
- security_scan_enabled: a_hash_including(
- url: a_string_matching(%r{/learn_gitlab/-/security/configuration\z})
- )
- })
- end
-
- it 'calls experiment with expected context & options' do
- allow(helper).to receive(:current_user).and_return(user)
-
- expect(helper).to receive(:experiment).with(
- :change_continuous_onboarding_link_urls,
- namespace: namespace,
- actor: user,
- sticky_to: namespace
- )
-
- learn_gitlab_data
- end
- end
end
end
diff --git a/spec/helpers/listbox_helper_spec.rb b/spec/helpers/listbox_helper_spec.rb
index 8935d69d4f7..0a27aa04b37 100644
--- a/spec/helpers/listbox_helper_spec.rb
+++ b/spec/helpers/listbox_helper_spec.rb
@@ -65,10 +65,13 @@ RSpec.describe ListboxHelper do
end
context 'when selected does not match any item' do
- let(:selected) { 'qux' }
+ where(selected: [nil, 'qux'])
- it 'raises an error' do
- expect { subject }.to raise_error(ArgumentError, /cannot find qux/)
+ with_them do
+ it 'selects first item' do
+ expect(subject.at_css('button').content).to eq('Foo')
+ expect(subject.attributes['data-selected'].value).to eq('foo')
+ end
end
end
end
diff --git a/spec/helpers/markup_helper_spec.rb b/spec/helpers/markup_helper_spec.rb
index ab2f6fa5b7e..a7e657f2636 100644
--- a/spec/helpers/markup_helper_spec.rb
+++ b/spec/helpers/markup_helper_spec.rb
@@ -315,33 +315,27 @@ RSpec.describe MarkupHelper do
end
describe '#render_wiki_content' do
- let(:wiki) { double('WikiPage', path: "file.#{extension}") }
- let(:wiki_repository) { double('Repository') }
+ let(:wiki) { build(:wiki, container: project) }
let(:content) { 'wiki content' }
+ let(:slug) { 'nested/page' }
+ let(:path) { "file.#{extension}" }
+ let(:wiki_page) { double('WikiPage', path: path, content: content, slug: slug, wiki: wiki) }
+
let(:context) do
{
pipeline: :wiki, project: project, wiki: wiki,
- page_slug: 'nested/page', issuable_reference_expansion_enabled: true,
- repository: wiki_repository
+ page_slug: slug, issuable_reference_expansion_enabled: true,
+ repository: wiki.repository, requested_path: path
}
end
- before do
- expect(wiki).to receive(:content).and_return(content)
- expect(wiki).to receive(:slug).and_return('nested/page')
- expect(wiki).to receive(:repository).and_return(wiki_repository)
- allow(wiki).to receive(:container).and_return(project)
-
- helper.instance_variable_set(:@wiki, wiki)
- end
-
context 'when file is Markdown' do
let(:extension) { 'md' }
it 'renders using #markdown_unsafe helper method' do
expect(helper).to receive(:markdown_unsafe).with('wiki content', context)
- helper.render_wiki_content(wiki)
+ helper.render_wiki_content(wiki_page)
end
context 'when context has labels' do
@@ -350,7 +344,7 @@ RSpec.describe MarkupHelper do
let(:content) { '~Bug' }
it 'renders label' do
- result = helper.render_wiki_content(wiki)
+ result = helper.render_wiki_content(wiki_page)
doc = Nokogiri::HTML.parse(result)
expect(doc.css('.gl-label-link')).not_to be_empty
@@ -366,7 +360,7 @@ RSpec.describe MarkupHelper do
end
it 'renders uploads relative to project' do
- result = helper.render_wiki_content(wiki)
+ result = helper.render_wiki_content(wiki_page)
expect(result).to include("#{project.full_path}#{upload_link}")
end
@@ -379,7 +373,7 @@ RSpec.describe MarkupHelper do
it 'renders using Gitlab::Asciidoc' do
expect(Gitlab::Asciidoc).to receive(:render)
- helper.render_wiki_content(wiki)
+ helper.render_wiki_content(wiki_page)
end
end
@@ -398,7 +392,7 @@ FooBar
it 'renders using #markdown_unsafe helper method' do
expect(helper).to receive(:markdown_unsafe).with(content, context)
- result = helper.render_wiki_content(wiki)
+ result = helper.render_wiki_content(wiki_page)
expect(result).to be_empty
end
@@ -410,7 +404,7 @@ FooBar
it 'renders all other formats using Gitlab::OtherMarkup' do
expect(Gitlab::OtherMarkup).to receive(:render)
- helper.render_wiki_content(wiki)
+ helper.render_wiki_content(wiki_page)
end
end
end
diff --git a/spec/helpers/merge_requests_helper_spec.rb b/spec/helpers/merge_requests_helper_spec.rb
index 3cf855229bb..38f2efd75a8 100644
--- a/spec/helpers/merge_requests_helper_spec.rb
+++ b/spec/helpers/merge_requests_helper_spec.rb
@@ -3,7 +3,6 @@
require 'spec_helper'
RSpec.describe MergeRequestsHelper do
- include ActionView::Helpers::UrlHelper
include ProjectForksHelper
describe '#state_name_with_icon' do
@@ -72,7 +71,8 @@ RSpec.describe MergeRequestsHelper do
let(:user) do
double(
assigned_open_merge_requests_count: 1,
- review_requested_open_merge_requests_count: 2
+ review_requested_open_merge_requests_count: 2,
+ attention_requested_open_merge_requests_count: 3
)
end
@@ -82,12 +82,29 @@ RSpec.describe MergeRequestsHelper do
allow(helper).to receive(:current_user).and_return(user)
end
- it "returns assigned, review requested and total merge request counts" do
- expect(subject).to eq(
- assigned: user.assigned_open_merge_requests_count,
- review_requested: user.review_requested_open_merge_requests_count,
- total: user.assigned_open_merge_requests_count + user.review_requested_open_merge_requests_count
- )
+ describe 'mr_attention_requests disabled' do
+ before do
+ stub_feature_flags(mr_attention_requests: false)
+ end
+
+ it "returns assigned, review requested and total merge request counts" do
+ expect(subject).to eq(
+ assigned: user.assigned_open_merge_requests_count,
+ review_requested: user.review_requested_open_merge_requests_count,
+ total: user.assigned_open_merge_requests_count + user.review_requested_open_merge_requests_count
+ )
+ end
+ end
+
+ describe 'mr_attention_requests enabled' do
+ it "returns assigned, review requested, attention requests and total merge request counts" do
+ expect(subject).to eq(
+ assigned: user.assigned_open_merge_requests_count,
+ review_requested: user.review_requested_open_merge_requests_count,
+ attention_requested_count: user.attention_requested_open_merge_requests_count,
+ total: user.attention_requested_open_merge_requests_count
+ )
+ end
end
end
diff --git a/spec/helpers/nav/top_nav_helper_spec.rb b/spec/helpers/nav/top_nav_helper_spec.rb
index ef6a6827826..e4422dde407 100644
--- a/spec/helpers/nav/top_nav_helper_spec.rb
+++ b/spec/helpers/nav/top_nav_helper_spec.rb
@@ -3,8 +3,6 @@
require 'spec_helper'
RSpec.describe Nav::TopNavHelper do
- include ActionView::Helpers::UrlHelper
-
let_it_be(:user) { build_stubbed(:user) }
let_it_be(:admin) { build_stubbed(:user, :admin) }
let_it_be(:external_user) { build_stubbed(:user, :external, can_create_group: false) }
diff --git a/spec/helpers/notify_helper_spec.rb b/spec/helpers/notify_helper_spec.rb
index e2a7a212b1b..654fb9bb3f8 100644
--- a/spec/helpers/notify_helper_spec.rb
+++ b/spec/helpers/notify_helper_spec.rb
@@ -3,7 +3,6 @@
require 'spec_helper'
RSpec.describe NotifyHelper do
- include ActionView::Helpers::UrlHelper
using RSpec::Parameterized::TableSyntax
describe 'merge_request_reference_link' do
diff --git a/spec/helpers/packages_helper_spec.rb b/spec/helpers/packages_helper_spec.rb
index 8b3c8411fbd..d7be4194e67 100644
--- a/spec/helpers/packages_helper_spec.rb
+++ b/spec/helpers/packages_helper_spec.rb
@@ -71,135 +71,39 @@ RSpec.describe PackagesHelper do
subject { helper.show_cleanup_policy_on_alert(project.reload) }
- where(:com, :config_registry, :project_registry, :historic_entries, :historic_entry, :nil_policy, :container_repositories_exist, :expected_result) do
- false | false | false | false | false | false | false | false
- false | false | false | false | false | false | true | false
- false | false | false | false | false | true | false | false
- false | false | false | false | false | true | true | false
- false | false | false | false | true | false | false | false
- false | false | false | false | true | false | true | false
- false | false | false | false | true | true | false | false
- false | false | false | false | true | true | true | false
- false | false | false | true | false | false | false | false
- false | false | false | true | false | false | true | false
- false | false | false | true | false | true | false | false
- false | false | false | true | false | true | true | false
- false | false | false | true | true | false | false | false
- false | false | false | true | true | false | true | false
- false | false | false | true | true | true | false | false
- false | false | false | true | true | true | true | false
- false | false | true | false | false | false | false | false
- false | false | true | false | false | false | true | false
- false | false | true | false | false | true | false | false
- false | false | true | false | false | true | true | false
- false | false | true | false | true | false | false | false
- false | false | true | false | true | false | true | false
- false | false | true | false | true | true | false | false
- false | false | true | false | true | true | true | false
- false | false | true | true | false | false | false | false
- false | false | true | true | false | false | true | false
- false | false | true | true | false | true | false | false
- false | false | true | true | false | true | true | false
- false | false | true | true | true | false | false | false
- false | false | true | true | true | false | true | false
- false | false | true | true | true | true | false | false
- false | false | true | true | true | true | true | false
- false | true | false | false | false | false | false | false
- false | true | false | false | false | false | true | false
- false | true | false | false | false | true | false | false
- false | true | false | false | false | true | true | false
- false | true | false | false | true | false | false | false
- false | true | false | false | true | false | true | false
- false | true | false | false | true | true | false | false
- false | true | false | false | true | true | true | false
- false | true | false | true | false | false | false | false
- false | true | false | true | false | false | true | false
- false | true | false | true | false | true | false | false
- false | true | false | true | false | true | true | false
- false | true | false | true | true | false | false | false
- false | true | false | true | true | false | true | false
- false | true | false | true | true | true | false | false
- false | true | false | true | true | true | true | false
- false | true | true | false | false | false | false | false
- false | true | true | false | false | false | true | false
- false | true | true | false | false | true | false | false
- false | true | true | false | false | true | true | false
- false | true | true | false | true | false | false | false
- false | true | true | false | true | false | true | false
- false | true | true | false | true | true | false | false
- false | true | true | false | true | true | true | false
- false | true | true | true | false | false | false | false
- false | true | true | true | false | false | true | false
- false | true | true | true | false | true | false | false
- false | true | true | true | false | true | true | false
- false | true | true | true | true | false | false | false
- false | true | true | true | true | false | true | false
- false | true | true | true | true | true | false | false
- false | true | true | true | true | true | true | false
- true | false | false | false | false | false | false | false
- true | false | false | false | false | false | true | false
- true | false | false | false | false | true | false | false
- true | false | false | false | false | true | true | false
- true | false | false | false | true | false | false | false
- true | false | false | false | true | false | true | false
- true | false | false | false | true | true | false | false
- true | false | false | false | true | true | true | false
- true | false | false | true | false | false | false | false
- true | false | false | true | false | false | true | false
- true | false | false | true | false | true | false | false
- true | false | false | true | false | true | true | false
- true | false | false | true | true | false | false | false
- true | false | false | true | true | false | true | false
- true | false | false | true | true | true | false | false
- true | false | false | true | true | true | true | false
- true | false | true | false | false | false | false | false
- true | false | true | false | false | false | true | false
- true | false | true | false | false | true | false | false
- true | false | true | false | false | true | true | false
- true | false | true | false | true | false | false | false
- true | false | true | false | true | false | true | false
- true | false | true | false | true | true | false | false
- true | false | true | false | true | true | true | false
- true | false | true | true | false | false | false | false
- true | false | true | true | false | false | true | false
- true | false | true | true | false | true | false | false
- true | false | true | true | false | true | true | false
- true | false | true | true | true | false | false | false
- true | false | true | true | true | false | true | false
- true | false | true | true | true | true | false | false
- true | false | true | true | true | true | true | false
- true | true | false | false | false | false | false | false
- true | true | false | false | false | false | true | false
- true | true | false | false | false | true | false | false
- true | true | false | false | false | true | true | false
- true | true | false | false | true | false | false | false
- true | true | false | false | true | false | true | false
- true | true | false | false | true | true | false | false
- true | true | false | false | true | true | true | false
- true | true | false | true | false | false | false | false
- true | true | false | true | false | false | true | false
- true | true | false | true | false | true | false | false
- true | true | false | true | false | true | true | false
- true | true | false | true | true | false | false | false
- true | true | false | true | true | false | true | false
- true | true | false | true | true | true | false | false
- true | true | false | true | true | true | true | false
- true | true | true | false | false | false | false | false
- true | true | true | false | false | false | true | false
- true | true | true | false | false | true | false | false
- true | true | true | false | false | true | true | false
- true | true | true | false | true | false | false | false
- true | true | true | false | true | false | true | false
- true | true | true | false | true | true | false | false
- true | true | true | false | true | true | true | true
- true | true | true | true | false | false | false | false
- true | true | true | true | false | false | true | false
- true | true | true | true | false | true | false | false
- true | true | true | true | false | true | true | false
- true | true | true | true | true | false | false | false
- true | true | true | true | true | false | true | false
- true | true | true | true | true | true | false | false
- true | true | true | true | true | true | true | false
+ where(:com, :config_registry, :project_registry, :nil_policy, :container_repositories_exist, :expected_result) do
+ false | false | false | false | false | false
+ false | false | false | false | true | false
+ false | false | false | true | false | false
+ false | false | false | true | true | false
+ false | false | true | false | false | false
+ false | false | true | false | true | false
+ false | false | true | true | false | false
+ false | false | true | true | true | false
+ false | true | false | false | false | false
+ false | true | false | false | true | false
+ false | true | false | true | false | false
+ false | true | false | true | true | false
+ false | true | true | false | false | false
+ false | true | true | false | true | false
+ false | true | true | true | false | false
+ false | true | true | true | true | false
+ true | false | false | false | false | false
+ true | false | false | false | true | false
+ true | false | false | true | false | false
+ true | false | false | true | true | false
+ true | false | true | false | false | false
+ true | false | true | false | true | false
+ true | false | true | true | false | false
+ true | false | true | true | true | false
+ true | true | false | false | false | false
+ true | true | false | false | true | false
+ true | true | false | true | false | false
+ true | true | false | true | true | false
+ true | true | true | false | false | false
+ true | true | true | false | true | false
+ true | true | true | true | false | false
+ true | true | true | true | true | true
end
with_them do
@@ -208,9 +112,6 @@ RSpec.describe PackagesHelper do
allow(Gitlab).to receive(:com?).and_return(com)
stub_config(registry: { enabled: config_registry })
allow(project).to receive(:feature_available?).with(:container_registry, user).and_return(project_registry)
- stub_application_setting(container_expiration_policies_enable_historic_entries: historic_entries)
- stub_feature_flags(container_expiration_policies_historic_entry: false)
- stub_feature_flags(container_expiration_policies_historic_entry: project) if historic_entry
project.container_expiration_policy.destroy! if nil_policy
container_repository.update!(project_id: project.id) if container_repositories_exist
diff --git a/spec/helpers/preferences_helper_spec.rb b/spec/helpers/preferences_helper_spec.rb
index ad2f142e3ff..8c13afc2b45 100644
--- a/spec/helpers/preferences_helper_spec.rb
+++ b/spec/helpers/preferences_helper_spec.rb
@@ -96,6 +96,30 @@ RSpec.describe PreferencesHelper do
end
end
+ describe '#user_application_dark_mode?' do
+ context 'with a user' do
+ it "returns true if user's selected dark theme" do
+ stub_user(theme_id: 11)
+
+ expect(helper.user_application_dark_mode?).to eq true
+ end
+
+ it "returns false if user's selected any light theme" do
+ stub_user(theme_id: 1)
+
+ expect(helper.user_application_dark_mode?).to eq false
+ end
+ end
+
+ context 'without a user' do
+ it 'returns false' do
+ stub_user
+
+ expect(helper.user_application_dark_mode?).to eq false
+ end
+ end
+ end
+
describe '#user_color_scheme' do
context 'with a user' do
it "returns user's scheme's css_class" do
diff --git a/spec/helpers/projects/cluster_agents_helper_spec.rb b/spec/helpers/projects/cluster_agents_helper_spec.rb
index d94a5fa9f8a..6849ec8b5ea 100644
--- a/spec/helpers/projects/cluster_agents_helper_spec.rb
+++ b/spec/helpers/projects/cluster_agents_helper_spec.rb
@@ -8,6 +8,7 @@ RSpec.describe Projects::ClusterAgentsHelper do
let_it_be(:current_user) { create(:user) }
let(:user_can_admin_vulerability) { true }
+ let(:user_can_admin_cluster) { false }
let(:agent_name) { 'agent-name' }
before do
@@ -16,6 +17,10 @@ RSpec.describe Projects::ClusterAgentsHelper do
.to receive(:can?)
.with(current_user, :admin_vulnerability, project)
.and_return(user_can_admin_vulerability)
+ allow(helper)
+ .to receive(:can?)
+ .with(current_user, :admin_cluster, project)
+ .and_return(user_can_admin_cluster)
end
subject { helper.js_cluster_agent_details_data(agent_name, project) }
@@ -26,8 +31,18 @@ RSpec.describe Projects::ClusterAgentsHelper do
project_path: project.full_path,
activity_empty_state_image: kind_of(String),
empty_state_svg_path: kind_of(String),
- can_admin_vulnerability: "true"
+ can_admin_vulnerability: "true",
+ kas_address: Gitlab::Kas.external_url,
+ can_admin_cluster: "false"
})
}
+
+ context 'user has admin cluster permissions' do
+ let(:user_can_admin_cluster) { true }
+
+ it 'displays that the user can admin cluster' do
+ expect(subject[:can_admin_cluster]).to eq("true")
+ end
+ end
end
end
diff --git a/spec/helpers/projects/error_tracking_helper_spec.rb b/spec/helpers/projects/error_tracking_helper_spec.rb
index 882031a9c86..f49458be40d 100644
--- a/spec/helpers/projects/error_tracking_helper_spec.rb
+++ b/spec/helpers/projects/error_tracking_helper_spec.rb
@@ -5,8 +5,8 @@ require 'spec_helper'
RSpec.describe Projects::ErrorTrackingHelper do
include Gitlab::Routing.url_helpers
- let_it_be(:project, reload: true) { create(:project) }
- let_it_be(:current_user) { create(:user) }
+ let(:project) { build_stubbed(:project) }
+ let(:current_user) { build_stubbed(:user) }
describe '#error_tracking_data' do
let(:can_enable_error_tracking) { true }
@@ -34,20 +34,21 @@ RSpec.describe Projects::ErrorTrackingHelper do
'error-tracking-enabled' => 'false',
'list-path' => list_path,
'project-path' => project_path,
- 'illustration-path' => match_asset_path('/assets/illustrations/cluster_popover.svg')
+ 'illustration-path' => match_asset_path('/assets/illustrations/cluster_popover.svg'),
+ 'show-integrated-tracking-disabled-alert' => 'false'
)
end
end
context 'with error_tracking_setting' do
- let(:error_tracking_setting) do
- create(:project_error_tracking_setting, project: project)
+ let(:project) { build_stubbed(:project, :with_error_tracking_setting) }
+
+ before do
+ project.error_tracking_setting.enabled = enabled
end
context 'when enabled' do
- before do
- error_tracking_setting.update!(enabled: true)
- end
+ let(:enabled) { true }
it 'show error tracking enabled' do
expect(helper.error_tracking_data(current_user, project)).to include(
@@ -57,9 +58,7 @@ RSpec.describe Projects::ErrorTrackingHelper do
end
context 'when disabled' do
- before do
- error_tracking_setting.update!(enabled: false)
- end
+ let(:enabled) { false }
it 'show error tracking not enabled' do
expect(helper.error_tracking_data(current_user, project)).to include(
@@ -67,6 +66,38 @@ RSpec.describe Projects::ErrorTrackingHelper do
)
end
end
+
+ context 'with integrated error tracking feature' do
+ using RSpec::Parameterized::TableSyntax
+
+ where(:feature_flag, :enabled, :integrated, :show_alert) do
+ false | true | true | true
+ false | true | false | false
+ false | false | true | false
+ false | false | false | false
+ true | true | true | false
+ true | true | false | false
+ true | false | true | false
+ true | false | false | false
+ end
+
+ with_them do
+ before do
+ stub_feature_flags(integrated_error_tracking: feature_flag)
+
+ project.error_tracking_setting.attributes = {
+ enabled: enabled,
+ integrated: integrated
+ }
+ end
+
+ specify do
+ expect(helper.error_tracking_data(current_user, project)).to include(
+ 'show-integrated-tracking-disabled-alert' => show_alert.to_s
+ )
+ end
+ end
+ end
end
context 'when user is not maintainer' do
diff --git a/spec/helpers/projects_helper_spec.rb b/spec/helpers/projects_helper_spec.rb
index 604ce0fe0c1..24d908a5dd3 100644
--- a/spec/helpers/projects_helper_spec.rb
+++ b/spec/helpers/projects_helper_spec.rb
@@ -1027,7 +1027,7 @@ RSpec.describe ProjectsHelper do
end
end
- describe '#import_from_bitbucket_message' do
+ shared_examples 'configure import method modal' do
before do
allow(helper).to receive(:current_user).and_return(user)
end
@@ -1036,7 +1036,7 @@ RSpec.describe ProjectsHelper do
it 'returns a link to contact an administrator' do
allow(user).to receive(:admin?).and_return(false)
- expect(helper.import_from_bitbucket_message).to have_text('To enable importing projects from Bitbucket, ask your GitLab administrator to configure OAuth integration')
+ expect(subject).to have_text("To enable importing projects from #{import_method}, ask your GitLab administrator to configure OAuth integration")
end
end
@@ -1044,8 +1044,24 @@ RSpec.describe ProjectsHelper do
it 'returns a link to configure bitbucket' do
allow(user).to receive(:admin?).and_return(true)
- expect(helper.import_from_bitbucket_message).to have_text('To enable importing projects from Bitbucket, as administrator you need to configure OAuth integration')
+ expect(subject).to have_text("To enable importing projects from #{import_method}, as administrator you need to configure OAuth integration")
end
end
end
+
+ describe '#import_from_bitbucket_message' do
+ let(:import_method) { 'Bitbucket' }
+
+ subject { helper.import_from_bitbucket_message }
+
+ it_behaves_like 'configure import method modal'
+ end
+
+ describe '#import_from_gitlab_message' do
+ let(:import_method) { 'GitLab.com' }
+
+ subject { helper.import_from_gitlab_message }
+
+ it_behaves_like 'configure import method modal'
+ end
end
diff --git a/spec/helpers/routing/pseudonymization_helper_spec.rb b/spec/helpers/routing/pseudonymization_helper_spec.rb
index d7905edb098..1221917e6b7 100644
--- a/spec/helpers/routing/pseudonymization_helper_spec.rb
+++ b/spec/helpers/routing/pseudonymization_helper_spec.rb
@@ -222,16 +222,26 @@ RSpec.describe ::Routing::PseudonymizationHelper do
end
describe 'when url has no params to mask' do
- let(:root_url) { 'http://localhost/some/path' }
+ let(:original_url) { 'http://localhost/-/security/vulnerabilities' }
+ let(:request) do
+ double(:Request,
+ path_parameters: {
+ controller: 'security/vulnerabilities',
+ action: 'index'
+ },
+ protocol: 'http',
+ host: 'localhost',
+ query_string: '',
+ original_fullpath: '/-/security/vulnerabilities',
+ original_url: original_url)
+ end
- context 'returns root url' do
- before do
- controller.request.path = 'some/path'
- end
+ before do
+ allow(helper).to receive(:request).and_return(request)
+ end
- it 'masked_page_url' do
- expect(subject).to eq(root_url)
- end
+ it 'returns unchanged url' do
+ expect(subject).to eq(original_url)
end
end
diff --git a/spec/helpers/sessions_helper_spec.rb b/spec/helpers/sessions_helper_spec.rb
index 816e43669bd..fd3d7100ba1 100644
--- a/spec/helpers/sessions_helper_spec.rb
+++ b/spec/helpers/sessions_helper_spec.rb
@@ -8,7 +8,7 @@ RSpec.describe SessionsHelper do
context 'when on .com' do
before do
- allow(Gitlab).to receive(:dev_env_or_com?).and_return(true)
+ allow(Gitlab).to receive(:com?).and_return(true)
end
it 'when flash notice is empty it is false' do
@@ -29,7 +29,7 @@ RSpec.describe SessionsHelper do
context 'when not on .com' do
before do
- allow(Gitlab).to receive(:dev_env_or_com?).and_return(false)
+ allow(Gitlab).to receive(:com?).and_return(false)
end
it 'when flash notice is devise confirmed message it is false' do
diff --git a/spec/helpers/sorting_helper_spec.rb b/spec/helpers/sorting_helper_spec.rb
index b49b4ad6e7e..e20fb77ad75 100644
--- a/spec/helpers/sorting_helper_spec.rb
+++ b/spec/helpers/sorting_helper_spec.rb
@@ -10,6 +10,18 @@ RSpec.describe SortingHelper do
allow(self).to receive(:request).and_return(double(path: 'http://test.com', query_parameters: { label_name: option }))
end
+ describe '#admin_users_sort_options' do
+ it 'returns correct link attributes in array' do
+ options = admin_users_sort_options(filter: 'filter', search_query: 'search')
+
+ expect(options[0][:href]).to include('filter')
+ expect(options[0][:href]).to include('search')
+ options.each do |option|
+ expect(option[:href]).to include(option[:value])
+ end
+ end
+ end
+
describe '#issuable_sort_option_title' do
it 'returns correct title for issuable_sort_option_overrides key' do
expect(issuable_sort_option_title('created_asc')).to eq('Created date')
diff --git a/spec/helpers/storage_helper_spec.rb b/spec/helpers/storage_helper_spec.rb
index 82b78ed831c..6b743422b04 100644
--- a/spec/helpers/storage_helper_spec.rb
+++ b/spec/helpers/storage_helper_spec.rb
@@ -57,6 +57,8 @@ RSpec.describe StorageHelper do
let_it_be(:paid_group) { create(:group) }
before do
+ allow(helper).to receive(:can?).with(current_user, :admin_namespace, free_group).and_return(true)
+ allow(helper).to receive(:can?).with(current_user, :admin_namespace, paid_group).and_return(true)
allow(helper).to receive(:current_user) { current_user }
allow(Gitlab).to receive(:com?).and_return(true)
allow(paid_group).to receive(:paid?).and_return(true)
@@ -64,26 +66,37 @@ RSpec.describe StorageHelper do
describe "#storage_enforcement_banner_info" do
it 'returns nil when namespace is not free' do
- expect(storage_enforcement_banner_info(paid_group)).to be(nil)
+ expect(helper.storage_enforcement_banner_info(paid_group)).to be(nil)
end
it 'returns nil when storage_enforcement_date is not set' do
allow(free_group).to receive(:storage_enforcement_date).and_return(nil)
- expect(storage_enforcement_banner_info(free_group)).to be(nil)
+ expect(helper.storage_enforcement_banner_info(free_group)).to be(nil)
end
- it 'returns a hash when storage_enforcement_date is set' do
- storage_enforcement_date = Date.today + 30
- allow(free_group).to receive(:storage_enforcement_date).and_return(storage_enforcement_date)
-
- expect(storage_enforcement_banner_info(free_group)).to eql({
- text: "From #{storage_enforcement_date} storage limits will apply to this namespace. View and manage your usage in <strong>Group Settings &gt; Usage quotas</strong>.",
- variant: 'warning',
- callouts_feature_name: 'storage_enforcement_banner_second_enforcement_threshold',
- callouts_path: '/-/users/group_callouts',
- learn_more_link: '<a rel="noopener noreferrer" target="_blank" href="/help//">Learn more.</a>'
- })
+ describe 'when storage_enforcement_date is set' do
+ let_it_be(:storage_enforcement_date) { Date.today + 30 }
+
+ before do
+ allow(free_group).to receive(:storage_enforcement_date).and_return(storage_enforcement_date)
+ end
+
+ it 'returns nil when current_user do not have access usage quotas page' do
+ allow(helper).to receive(:can?).with(current_user, :admin_namespace, free_group).and_return(false)
+
+ expect(helper.storage_enforcement_banner_info(free_group)).to be(nil)
+ end
+
+ it 'returns a hash when current_user can access usage quotas page' do
+ expect(helper.storage_enforcement_banner_info(free_group)).to eql({
+ text: "From #{storage_enforcement_date} storage limits will apply to this namespace. View and manage your usage in <strong>Group settings &gt; Usage quotas</strong>.",
+ variant: 'warning',
+ callouts_feature_name: 'storage_enforcement_banner_second_enforcement_threshold',
+ callouts_path: '/-/users/group_callouts',
+ learn_more_link: '<a rel="noopener noreferrer" target="_blank" href="/help//">Learn more.</a>'
+ })
+ end
end
context 'when storage_enforcement_date is set and dismissed callout exists' do
@@ -96,7 +109,7 @@ RSpec.describe StorageHelper do
allow(free_group).to receive(:storage_enforcement_date).and_return(storage_enforcement_date)
end
- it { expect(storage_enforcement_banner_info(free_group)).to be(nil) }
+ it { expect(helper.storage_enforcement_banner_info(free_group)).to be(nil) }
end
context 'callouts_feature_name' do
@@ -106,7 +119,7 @@ RSpec.describe StorageHelper do
storage_enforcement_date = Date.today + days_from_now
allow(free_group).to receive(:storage_enforcement_date).and_return(storage_enforcement_date)
- storage_enforcement_banner_info(free_group)[:callouts_feature_name]
+ helper.storage_enforcement_banner_info(free_group)[:callouts_feature_name]
end
it 'returns first callouts_feature_name' do
diff --git a/spec/helpers/tree_helper_spec.rb b/spec/helpers/tree_helper_spec.rb
index 1a0ecd5d903..026432adf99 100644
--- a/spec/helpers/tree_helper_spec.rb
+++ b/spec/helpers/tree_helper_spec.rb
@@ -116,9 +116,11 @@ RSpec.describe TreeHelper do
show_edit_button: false,
show_web_ide_button: true,
show_gitpod_button: false,
+ show_pipeline_editor_button: false,
edit_url: '',
web_ide_url: "/-/ide/project/#{project.full_path}/edit/#{sha}",
+ pipeline_editor_url: "/#{project.full_path}/-/ci/editor?branch_name=#{@ref}",
gitpod_url: '',
user_preferences_gitpod_path: user_preferences_gitpod_path,
diff --git a/spec/helpers/users/callouts_helper_spec.rb b/spec/helpers/users/callouts_helper_spec.rb
index 85e11c2ed3b..71a8d340b30 100644
--- a/spec/helpers/users/callouts_helper_spec.rb
+++ b/spec/helpers/users/callouts_helper_spec.rb
@@ -103,6 +103,7 @@ RSpec.describe Users::CalloutsHelper do
allow(helper).to receive(:current_user).and_return(admin)
stub_application_setting(signup_enabled: true)
allow(helper).to receive(:user_dismissed?).with(described_class::REGISTRATION_ENABLED_CALLOUT) { false }
+ allow(helper.controller).to receive(:controller_path).and_return("admin/users")
end
it { is_expected.to be false }
@@ -114,6 +115,7 @@ RSpec.describe Users::CalloutsHelper do
allow(helper).to receive(:current_user).and_return(user)
stub_application_setting(signup_enabled: true)
allow(helper).to receive(:user_dismissed?).with(described_class::REGISTRATION_ENABLED_CALLOUT) { false }
+ allow(helper.controller).to receive(:controller_path).and_return("admin/users")
end
it { is_expected.to be false }
@@ -125,6 +127,7 @@ RSpec.describe Users::CalloutsHelper do
allow(helper).to receive(:current_user).and_return(admin)
stub_application_setting(signup_enabled: false)
allow(helper).to receive(:user_dismissed?).with(described_class::REGISTRATION_ENABLED_CALLOUT) { false }
+ allow(helper.controller).to receive(:controller_path).and_return("admin/users")
end
it { is_expected.to be false }
@@ -136,17 +139,31 @@ RSpec.describe Users::CalloutsHelper do
allow(helper).to receive(:current_user).and_return(admin)
stub_application_setting(signup_enabled: true)
allow(helper).to receive(:user_dismissed?).with(described_class::REGISTRATION_ENABLED_CALLOUT) { true }
+ allow(helper.controller).to receive(:controller_path).and_return("admin/users")
end
it { is_expected.to be false }
end
- context 'when not gitlab.com, `current_user` is an admin, signup is enabled, and user has not dismissed callout' do
+ context 'when controller path is not allowed' do
before do
allow(::Gitlab).to receive(:com?).and_return(false)
allow(helper).to receive(:current_user).and_return(admin)
stub_application_setting(signup_enabled: true)
allow(helper).to receive(:user_dismissed?).with(described_class::REGISTRATION_ENABLED_CALLOUT) { false }
+ allow(helper.controller).to receive(:controller_path).and_return("projects/issues")
+ end
+
+ it { is_expected.to be false }
+ end
+
+ context 'when not gitlab.com, `current_user` is an admin, signup is enabled, user has not dismissed callout, and controller path is allowed' do
+ before do
+ allow(::Gitlab).to receive(:com?).and_return(false)
+ allow(helper).to receive(:current_user).and_return(admin)
+ stub_application_setting(signup_enabled: true)
+ allow(helper).to receive(:user_dismissed?).with(described_class::REGISTRATION_ENABLED_CALLOUT) { false }
+ allow(helper.controller).to receive(:controller_path).and_return("admin/users")
end
it { is_expected.to be true }
diff --git a/spec/helpers/web_ide_button_helper_spec.rb b/spec/helpers/web_ide_button_helper_spec.rb
new file mode 100644
index 00000000000..3dd46021c11
--- /dev/null
+++ b/spec/helpers/web_ide_button_helper_spec.rb
@@ -0,0 +1,45 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe WebIdeButtonHelper do
+ describe '#show_pipeline_editor_button?' do
+ subject(:result) { helper.show_pipeline_editor_button?(project, path) }
+
+ let_it_be(:project) { build(:project) }
+
+ context 'when can view pipeline editor' do
+ before do
+ allow(helper).to receive(:can_view_pipeline_editor?).and_return(true)
+ end
+
+ context 'when path is ci config path' do
+ let(:path) { project.ci_config_path_or_default }
+
+ it 'returns true' do
+ expect(result).to eq(true)
+ end
+ end
+
+ context 'when path is not config path' do
+ let(:path) { '/' }
+
+ it 'returns false' do
+ expect(result).to eq(false)
+ end
+ end
+ end
+
+ context 'when can not view pipeline editor' do
+ before do
+ allow(helper).to receive(:can_view_pipeline_editor?).and_return(false)
+ end
+
+ let(:path) { project.ci_config_path_or_default }
+
+ it 'returns false' do
+ expect(result).to eq(false)
+ end
+ end
+ end
+end
diff --git a/spec/helpers/whats_new_helper_spec.rb b/spec/helpers/whats_new_helper_spec.rb
index 9ae7ef38736..011152b2d6a 100644
--- a/spec/helpers/whats_new_helper_spec.rb
+++ b/spec/helpers/whats_new_helper_spec.rb
@@ -39,14 +39,14 @@ RSpec.describe WhatsNewHelper do
subject { helper.display_whats_new? }
it 'returns true when gitlab.com' do
- allow(Gitlab).to receive(:dev_env_org_or_com?).and_return(true)
+ allow(Gitlab).to receive(:org_or_com?).and_return(true)
expect(subject).to be true
end
context 'when self-managed' do
before do
- allow(Gitlab).to receive(:dev_env_org_or_com?).and_return(false)
+ allow(Gitlab).to receive(:org_or_com?).and_return(false)
end
it 'returns true if user is signed in' do
@@ -71,7 +71,7 @@ RSpec.describe WhatsNewHelper do
with_them do
it 'returns correct result depending on variant' do
- allow(Gitlab).to receive(:dev_env_org_or_com?).and_return(true)
+ allow(Gitlab).to receive(:org_or_com?).and_return(true)
Gitlab::CurrentSettings.update!(whats_new_variant: ApplicationSetting.whats_new_variants[variant])
expect(subject).to eq(result)
diff --git a/spec/lib/api/entities/ci/job_artifact_file_spec.rb b/spec/lib/api/entities/ci/job_artifact_file_spec.rb
new file mode 100644
index 00000000000..9e4ec272518
--- /dev/null
+++ b/spec/lib/api/entities/ci/job_artifact_file_spec.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe API::Entities::Ci::JobArtifactFile do
+ let(:artifact_file) { instance_double(JobArtifactUploader, filename: 'ci_build_artifacts.zip', cached_size: 42) }
+ let(:entity) { described_class.new(artifact_file) }
+
+ subject { entity.as_json }
+
+ it 'returns the filename' do
+ expect(subject[:filename]).to eq('ci_build_artifacts.zip')
+ end
+
+ it 'returns the size' do
+ expect(subject[:size]).to eq(42)
+ end
+end
diff --git a/spec/lib/api/entities/ci/job_request/dependency_spec.rb b/spec/lib/api/entities/ci/job_request/dependency_spec.rb
new file mode 100644
index 00000000000..fa5f3da554c
--- /dev/null
+++ b/spec/lib/api/entities/ci/job_request/dependency_spec.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe API::Entities::Ci::JobRequest::Dependency do
+ let(:job) { create(:ci_build, :artifacts) }
+ let(:entity) { described_class.new(job) }
+
+ subject { entity.as_json }
+
+ it 'returns the dependency id' do
+ expect(subject[:id]).to eq(job.id)
+ end
+
+ it 'returns the dependency name' do
+ expect(subject[:name]).to eq(job.name)
+ end
+
+ it 'returns the dependency token' do
+ expect(subject[:token]).to eq(job.token)
+ end
+
+ it 'returns the dependency artifacts_file', :aggregate_failures do
+ expect(subject[:artifacts_file][:filename]).to eq('ci_build_artifacts.zip')
+ expect(subject[:artifacts_file][:size]).to eq(job.artifacts_size)
+ end
+end
diff --git a/spec/lib/api/entities/user_spec.rb b/spec/lib/api/entities/user_spec.rb
index 14dc60e1a5f..be5e8e8e8c2 100644
--- a/spec/lib/api/entities/user_spec.rb
+++ b/spec/lib/api/entities/user_spec.rb
@@ -78,6 +78,63 @@ RSpec.describe API::Entities::User do
end
end
+ context 'with group bot user' do
+ let(:group) { create(:group) }
+ let(:user) { create(:user, :project_bot, name: 'group bot') }
+
+ before do
+ group.add_maintainer(user)
+ end
+
+ it 'exposes user as a bot' do
+ expect(subject[:bot]).to eq(true)
+ end
+
+ context 'when the requester is not a group member' do
+ context 'with a public group' do
+ it 'exposes group bot user name' do
+ expect(subject[:name]).to eq('group bot')
+ end
+ end
+
+ context 'with a private group' do
+ let(:group) { create(:group, :private) }
+
+ it 'does not expose group bot user name' do
+ expect(subject[:name]).to eq('****')
+ end
+ end
+ end
+
+ context 'when the requester is nil' do
+ let(:current_user) { nil }
+
+ it 'does not expose group bot user name' do
+ expect(subject[:name]).to eq('****')
+ end
+ end
+
+ context 'when the requester is a group maintainer' do
+ let(:current_user) { create(:user) }
+
+ before do
+ group.add_maintainer(current_user)
+ end
+
+ it 'exposes group bot user name' do
+ expect(subject[:name]).to eq('group bot')
+ end
+ end
+
+ context 'when the requester is an admin' do
+ let(:current_user) { create(:user, :admin) }
+
+ it 'exposes group bot user name', :enable_admin_mode do
+ expect(subject[:name]).to eq('group bot')
+ end
+ end
+ end
+
it 'exposes local_time' do
local_time = '2:30 PM'
expect(entity).to receive(:local_time).with(timezone).and_return(local_time)
diff --git a/spec/lib/api/entities/wiki_page_spec.rb b/spec/lib/api/entities/wiki_page_spec.rb
new file mode 100644
index 00000000000..238c8233a14
--- /dev/null
+++ b/spec/lib/api/entities/wiki_page_spec.rb
@@ -0,0 +1,56 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe API::Entities::WikiPage do
+ let_it_be_with_reload(:wiki_page) { create(:wiki_page) }
+
+ let(:params) { {} }
+ let(:entity) { described_class.new(wiki_page, params) }
+
+ subject { entity.as_json }
+
+ it 'returns the proper encoding for the wiki page content' do
+ expect(entity.as_json[:encoding]).to eq 'UTF-8'
+
+ wiki_page.update_attributes(content: 'new_content'.encode('ISO-8859-1')) # rubocop:disable Rails/ActiveRecordAliases, Rails/SaveBang
+
+ expect(entity.as_json[:encoding]).to eq 'ISO-8859-1'
+ end
+
+ it 'returns the raw wiki page content' do
+ expect(subject[:content]).to eq wiki_page.content
+ end
+
+ context 'when render_html param is passed' do
+ context 'when it is true' do
+ let(:params) { { render_html: true } }
+
+ it 'returns the wiki page content rendered' do
+ expect(subject[:content]).to eq "<p data-sourcepos=\"1:1-1:#{wiki_page.content.size}\" dir=\"auto\">#{wiki_page.content}</p>"
+ end
+
+ it 'includes the wiki page version in the render context' do
+ expect(entity).to receive(:render_wiki_content).with(anything, hash_including(ref: wiki_page.version.id)).and_call_original
+
+ subject[:content]
+ end
+
+ context 'when page is an Ascii document' do
+ let(:wiki_page) { create(:wiki_page, content: "*Test* _content_", format: :asciidoc) }
+
+ it 'renders the page without errors' do
+ expect(subject[:content]).to eq("<div>&#x000A;<p><strong>Test</strong> <em>content</em></p>&#x000A;</div>")
+ end
+ end
+ end
+
+ context 'when it is false' do
+ let(:params) { { render_html: false } }
+
+ it 'returns the raw wiki page content' do
+ expect(subject[:content]).to eq wiki_page.content
+ end
+ end
+ end
+end
diff --git a/spec/lib/api/helpers_spec.rb b/spec/lib/api/helpers_spec.rb
index b2d4a3094af..2afe5a1a9d7 100644
--- a/spec/lib/api/helpers_spec.rb
+++ b/spec/lib/api/helpers_spec.rb
@@ -109,6 +109,26 @@ RSpec.describe API::Helpers do
end
end
end
+
+ context 'when project is pending delete' do
+ let(:project_pending_delete) { create(:project, pending_delete: true) }
+
+ it 'does not return the project pending delete' do
+ expect(Project).not_to receive(:find_by_full_path)
+
+ expect(subject.find_project(project_pending_delete.id)).to be_nil
+ end
+ end
+
+ context 'when project is hidden' do
+ let(:hidden_project) { create(:project, :hidden) }
+
+ it 'does not return the hidden project' do
+ expect(Project).not_to receive(:find_by_full_path)
+
+ expect(subject.find_project(hidden_project.id)).to be_nil
+ end
+ end
end
describe '#find_project!' do
diff --git a/spec/lib/atlassian/jira_connect/client_spec.rb b/spec/lib/atlassian/jira_connect/client_spec.rb
index 9201d1c5dcb..dd3130c78bf 100644
--- a/spec/lib/atlassian/jira_connect/client_spec.rb
+++ b/spec/lib/atlassian/jira_connect/client_spec.rb
@@ -127,11 +127,19 @@ RSpec.describe Atlassian::JiraConnect::Client do
end
end
+ context 'the response is 202 accepted' do
+ let(:response) { double(code: 202, parsed_response: :foo) }
+
+ it 'yields to the block' do
+ expect(processed).to eq [:data, :foo]
+ end
+ end
+
context 'the response is 400 bad request' do
let(:response) { double(code: 400, parsed_response: errors) }
it 'extracts the errors messages' do
- expect(processed).to eq('errorMessages' => %w(X Y))
+ expect(processed).to eq('errorMessages' => %w(X Y), 'responseCode' => 400)
end
end
@@ -139,7 +147,7 @@ RSpec.describe Atlassian::JiraConnect::Client do
let(:response) { double(code: 401, parsed_response: nil) }
it 'reports that our JWT is wrong' do
- expect(processed).to eq('errorMessages' => ['Invalid JWT'])
+ expect(processed).to eq('errorMessages' => ['Invalid JWT'], 'responseCode' => 401)
end
end
@@ -147,7 +155,7 @@ RSpec.describe Atlassian::JiraConnect::Client do
let(:response) { double(code: 403, parsed_response: nil) }
it 'reports that the App is misconfigured' do
- expect(processed).to eq('errorMessages' => ['App does not support foo'])
+ expect(processed).to eq('errorMessages' => ['App does not support foo'], 'responseCode' => 403)
end
end
@@ -155,7 +163,7 @@ RSpec.describe Atlassian::JiraConnect::Client do
let(:response) { double(code: 413, parsed_response: errors) }
it 'extracts the errors messages' do
- expect(processed).to eq('errorMessages' => ['Data too large', 'X', 'Y'])
+ expect(processed).to eq('errorMessages' => ['Data too large', 'X', 'Y'], 'responseCode' => 413)
end
end
@@ -163,7 +171,7 @@ RSpec.describe Atlassian::JiraConnect::Client do
let(:response) { double(code: 429, parsed_response: nil) }
it 'reports that we exceeded the rate limit' do
- expect(processed).to eq('errorMessages' => ['Rate limit exceeded'])
+ expect(processed).to eq('errorMessages' => ['Rate limit exceeded'], 'responseCode' => 429)
end
end
@@ -171,7 +179,7 @@ RSpec.describe Atlassian::JiraConnect::Client do
let(:response) { double(code: 503, parsed_response: nil) }
it 'reports that the service is unavailable' do
- expect(processed).to eq('errorMessages' => ['Service unavailable'])
+ expect(processed).to eq('errorMessages' => ['Service unavailable'], 'responseCode' => 503)
end
end
@@ -179,7 +187,7 @@ RSpec.describe Atlassian::JiraConnect::Client do
let(:response) { double(code: 1000, parsed_response: :something) }
it 'reports that this was unanticipated' do
- expect(processed).to eq('errorMessages' => ['Unknown error'], 'response' => :something)
+ expect(processed).to eq('errorMessages' => ['Unknown error'], 'responseCode' => 1000, 'response' => :something)
end
end
end
diff --git a/spec/lib/atlassian/jira_connect/serializers/build_entity_spec.rb b/spec/lib/atlassian/jira_connect/serializers/build_entity_spec.rb
index 4bbd654655d..a29f32d35b8 100644
--- a/spec/lib/atlassian/jira_connect/serializers/build_entity_spec.rb
+++ b/spec/lib/atlassian/jira_connect/serializers/build_entity_spec.rb
@@ -31,7 +31,7 @@ RSpec.describe Atlassian::JiraConnect::Serializers::BuildEntity do
context 'when the pipeline does belong to a Jira issue' do
let(:pipeline) { create(:ci_pipeline, merge_request: merge_request) }
- %i[jira_branch jira_title].each do |trait|
+ %i[jira_branch jira_title jira_description].each do |trait|
context "because it belongs to an MR with a #{trait}" do
let(:merge_request) { create(:merge_request, trait) }
diff --git a/spec/lib/atlassian/jira_connect/serializers/deployment_entity_spec.rb b/spec/lib/atlassian/jira_connect/serializers/deployment_entity_spec.rb
index 8ccc3253a46..40b9e83719b 100644
--- a/spec/lib/atlassian/jira_connect/serializers/deployment_entity_spec.rb
+++ b/spec/lib/atlassian/jira_connect/serializers/deployment_entity_spec.rb
@@ -45,33 +45,18 @@ RSpec.describe Atlassian::JiraConnect::Serializers::DeploymentEntity do
describe 'environment type' do
using RSpec::Parameterized::TableSyntax
- where(:env_name, :env_type) do
- 'PRODUCTION' | 'production'
- 'prod' | 'production'
- 'prod-east-2' | 'production'
- 'us-prod-east' | 'production'
- 'fe-production' | 'production'
- 'test' | 'testing'
- 'qa-env-2' | 'testing'
- 'staging' | 'staging'
- 'pre-prod' | 'staging'
- 'blue-kit-stage' | 'staging'
- 'pre-prod' | 'staging'
- 'dev' | 'development'
- 'review/app' | 'development'
- 'something-else' | 'unmapped'
- 'store-produce' | 'unmapped'
- 'unproductive' | 'unmapped'
+ where(:tier, :env_type) do
+ 'other' | 'unmapped'
end
with_them do
before do
- environment.update!(name: env_name)
+ subject.environment.update!(tier: tier)
end
let(:exposed_type) { subject.send(:environment_entity).send(:type) }
- it 'has the correct environment type' do
+ it 'has the same type as the environment tier' do
expect(exposed_type).to eq(env_type)
end
end
diff --git a/spec/lib/atlassian/jira_connect_spec.rb b/spec/lib/atlassian/jira_connect_spec.rb
new file mode 100644
index 00000000000..d9c34e938b4
--- /dev/null
+++ b/spec/lib/atlassian/jira_connect_spec.rb
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+require 'fast_spec_helper'
+
+RSpec.describe Atlassian::JiraConnect do
+ describe '.app_name' do
+ subject { described_class.app_name }
+
+ it { is_expected.to eq('GitLab for Jira (localhost)') }
+ end
+
+ describe '.app_key' do
+ subject(:app_key) { described_class.app_key }
+
+ it { is_expected.to eq('gitlab-jira-connect-localhost') }
+
+ context 'host name is too long' do
+ before do
+ hostname = 'x' * 100
+
+ stub_config(gitlab: { host: hostname })
+ end
+
+ it 'truncates the key to be no longer than 64 characters', :aggregate_failures do
+ expect(app_key).to eq('gitlab-jira-connect-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx')
+ end
+ end
+ end
+end
diff --git a/spec/lib/backup/artifacts_spec.rb b/spec/lib/backup/artifacts_spec.rb
index e65dc79b65b..d830692d96b 100644
--- a/spec/lib/backup/artifacts_spec.rb
+++ b/spec/lib/backup/artifacts_spec.rb
@@ -18,7 +18,7 @@ RSpec.describe Backup::Artifacts do
expect(backup).to receive(:tar).and_return('blabla-tar')
expect(backup).to receive(:run_pipeline!).with([%w(blabla-tar --exclude=lost+found --exclude=./tmp -C /var/gitlab-artifacts -cf - .), 'gzip -c -1'], any_args).and_return([[true, true], ''])
expect(backup).to receive(:pipeline_succeeded?).and_return(true)
- backup.dump
+ backup.dump('artifacts.tar.gz')
end
end
end
diff --git a/spec/lib/backup/database_spec.rb b/spec/lib/backup/database_spec.rb
index 4345778ba92..53db7f0f149 100644
--- a/spec/lib/backup/database_spec.rb
+++ b/spec/lib/backup/database_spec.rb
@@ -6,25 +6,49 @@ RSpec.describe Backup::Database do
let(:progress) { StringIO.new }
let(:output) { progress.string }
- before do
- allow(Gitlab::TaskHelpers).to receive(:ask_to_continue)
+ before(:all) do
+ Rake.application.rake_require 'active_record/railties/databases'
+ Rake.application.rake_require 'tasks/gitlab/backup'
+ Rake.application.rake_require 'tasks/gitlab/shell'
+ Rake.application.rake_require 'tasks/gitlab/db'
+ Rake.application.rake_require 'tasks/cache'
end
describe '#restore' do
let(:cmd) { %W[#{Gem.ruby} -e $stdout.puts(1)] }
let(:data) { Rails.root.join("spec/fixtures/pages_empty.tar.gz").to_s }
+ let(:force) { true }
- subject { described_class.new(progress, filename: data) }
+ subject { described_class.new(progress, force: force) }
before do
allow(subject).to receive(:pg_restore_cmd).and_return(cmd)
end
+ context 'when not forced' do
+ let(:force) { false }
+
+ it 'warns the user and waits' do
+ expect(subject).to receive(:sleep)
+ expect(Rake::Task['gitlab:db:drop_tables']).to receive(:invoke)
+
+ subject.restore(data)
+
+ expect(output).to include('Removing all tables. Press `Ctrl-C` within 5 seconds to abort')
+ end
+
+ it 'has a pre restore warning' do
+ expect(subject.pre_restore_warning).not_to be_nil
+ end
+ end
+
context 'with an empty .gz file' do
let(:data) { Rails.root.join("spec/fixtures/pages_empty.tar.gz").to_s }
it 'returns successfully' do
- subject.restore
+ expect(Rake::Task['gitlab:db:drop_tables']).to receive(:invoke)
+
+ subject.restore(data)
expect(output).to include("Restoring PostgreSQL database")
expect(output).to include("[DONE]")
@@ -36,7 +60,9 @@ RSpec.describe Backup::Database do
let(:data) { Rails.root.join("spec/fixtures/big-image.png").to_s }
it 'raises a backup error' do
- expect { subject.restore }.to raise_error(Backup::Error)
+ expect(Rake::Task['gitlab:db:drop_tables']).to receive(:invoke)
+
+ expect { subject.restore(data) }.to raise_error(Backup::Error)
end
end
@@ -45,12 +71,15 @@ RSpec.describe Backup::Database do
let(:noise) { "Table projects does not exist\nmust be owner of extension pg_trgm\nWARNING: no privileges could be revoked for public\n" }
let(:cmd) { %W[#{Gem.ruby} -e $stderr.write("#{noise}#{visible_error}")] }
- it 'filters out noise from errors' do
- subject.restore
+ it 'filters out noise from errors and has a post restore warning' do
+ expect(Rake::Task['gitlab:db:drop_tables']).to receive(:invoke)
+
+ subject.restore(data)
expect(output).to include("ERRORS")
expect(output).not_to include(noise)
expect(output).to include(visible_error)
+ expect(subject.post_restore_warning).not_to be_nil
end
end
@@ -66,7 +95,9 @@ RSpec.describe Backup::Database do
end
it 'overrides default config values' do
- subject.restore
+ expect(Rake::Task['gitlab:db:drop_tables']).to receive(:invoke)
+
+ subject.restore(data)
expect(output).to include(%("PGHOST"=>"test.example.com"))
expect(output).to include(%("PGPASSWORD"=>"donotchange"))
diff --git a/spec/lib/backup/files_spec.rb b/spec/lib/backup/files_spec.rb
index 6bff0919293..bbc465a26c9 100644
--- a/spec/lib/backup/files_spec.rb
+++ b/spec/lib/backup/files_spec.rb
@@ -39,7 +39,7 @@ RSpec.describe Backup::Files do
end
describe '#restore' do
- subject { described_class.new('registry', '/var/gitlab-registry') }
+ subject { described_class.new(progress, 'registry', '/var/gitlab-registry') }
let(:timestamp) { Time.utc(2017, 3, 22) }
@@ -58,11 +58,11 @@ RSpec.describe Backup::Files do
it 'moves all necessary files' do
allow(subject).to receive(:backup_existing_files).and_call_original
expect(FileUtils).to receive(:mv).with(["/var/gitlab-registry/sample1"], File.join(Gitlab.config.backup.path, "tmp", "registry.#{Time.now.to_i}"))
- subject.restore
+ subject.restore('registry.tar.gz')
end
it 'raises no errors' do
- expect { subject.restore }.not_to raise_error
+ expect { subject.restore('registry.tar.gz') }.not_to raise_error
end
it 'calls tar command with unlink' do
@@ -70,13 +70,13 @@ RSpec.describe Backup::Files do
expect(subject).to receive(:run_pipeline!).with([%w(gzip -cd), %w(blabla-tar --unlink-first --recursive-unlink -C /var/gitlab-registry -xf -)], any_args)
expect(subject).to receive(:pipeline_succeeded?).and_return(true)
- subject.restore
+ subject.restore('registry.tar.gz')
end
it 'raises an error on failure' do
expect(subject).to receive(:pipeline_succeeded?).and_return(false)
- expect { subject.restore }.to raise_error(/Restore operation failed:/)
+ expect { subject.restore('registry.tar.gz') }.to raise_error(/Restore operation failed:/)
end
end
@@ -89,7 +89,7 @@ RSpec.describe Backup::Files do
it 'shows error message' do
expect(subject).to receive(:access_denied_error).with("/var/gitlab-registry")
- subject.restore
+ subject.restore('registry.tar.gz')
end
end
@@ -104,13 +104,13 @@ RSpec.describe Backup::Files do
expect(subject).to receive(:resource_busy_error).with("/var/gitlab-registry")
.and_call_original
- expect { subject.restore }.to raise_error(/is a mountpoint/)
+ expect { subject.restore('registry.tar.gz') }.to raise_error(/is a mountpoint/)
end
end
end
describe '#dump' do
- subject { described_class.new('pages', '/var/gitlab-pages', excludes: ['@pages.tmp']) }
+ subject { described_class.new(progress, 'pages', '/var/gitlab-pages', excludes: ['@pages.tmp']) }
before do
allow(subject).to receive(:run_pipeline!).and_return([[true, true], ''])
@@ -118,14 +118,14 @@ RSpec.describe Backup::Files do
end
it 'raises no errors' do
- expect { subject.dump }.not_to raise_error
+ expect { subject.dump('registry.tar.gz') }.not_to raise_error
end
it 'excludes tmp dirs from archive' do
expect(subject).to receive(:tar).and_return('blabla-tar')
expect(subject).to receive(:run_pipeline!).with([%w(blabla-tar --exclude=lost+found --exclude=./@pages.tmp -C /var/gitlab-pages -cf - .), 'gzip -c -1'], any_args)
- subject.dump
+ subject.dump('registry.tar.gz')
end
it 'raises an error on failure' do
@@ -133,7 +133,7 @@ RSpec.describe Backup::Files do
expect(subject).to receive(:pipeline_succeeded?).and_return(false)
expect do
- subject.dump
+ subject.dump('registry.tar.gz')
end.to raise_error(/Failed to create compressed file/)
end
@@ -149,7 +149,7 @@ RSpec.describe Backup::Files do
.with(%w(rsync -a --delete --exclude=lost+found --exclude=/gitlab-pages/@pages.tmp /var/gitlab-pages /var/gitlab-backup))
.and_return(['', 0])
- subject.dump
+ subject.dump('registry.tar.gz')
end
it 'retries if rsync fails due to vanishing files' do
@@ -158,7 +158,7 @@ RSpec.describe Backup::Files do
.and_return(['rsync failed', 24], ['', 0])
expect do
- subject.dump
+ subject.dump('registry.tar.gz')
end.to output(/files vanished during rsync, retrying/).to_stdout
end
@@ -168,7 +168,7 @@ RSpec.describe Backup::Files do
.and_return(['rsync failed', 1])
expect do
- subject.dump
+ subject.dump('registry.tar.gz')
end.to output(/rsync failed/).to_stdout
.and raise_error(/Failed to create compressed file/)
end
@@ -176,7 +176,7 @@ RSpec.describe Backup::Files do
end
describe '#exclude_dirs' do
- subject { described_class.new('pages', '/var/gitlab-pages', excludes: ['@pages.tmp']) }
+ subject { described_class.new(progress, 'pages', '/var/gitlab-pages', excludes: ['@pages.tmp']) }
it 'prepends a leading dot slash to tar excludes' do
expect(subject.exclude_dirs(:tar)).to eq(['--exclude=lost+found', '--exclude=./@pages.tmp'])
@@ -188,7 +188,7 @@ RSpec.describe Backup::Files do
end
describe '#run_pipeline!' do
- subject { described_class.new('registry', '/var/gitlab-registry') }
+ subject { described_class.new(progress, 'registry', '/var/gitlab-registry') }
it 'executes an Open3.pipeline for cmd_list' do
expect(Open3).to receive(:pipeline).with(%w[whew command], %w[another cmd], any_args)
@@ -222,7 +222,7 @@ RSpec.describe Backup::Files do
end
describe '#pipeline_succeeded?' do
- subject { described_class.new('registry', '/var/gitlab-registry') }
+ subject { described_class.new(progress, 'registry', '/var/gitlab-registry') }
it 'returns true if both tar and gzip succeeeded' do
expect(
@@ -262,7 +262,7 @@ RSpec.describe Backup::Files do
end
describe '#tar_ignore_non_success?' do
- subject { described_class.new('registry', '/var/gitlab-registry') }
+ subject { described_class.new(progress, 'registry', '/var/gitlab-registry') }
context 'if `tar` command exits with 1 exitstatus' do
it 'returns true' do
@@ -310,7 +310,7 @@ RSpec.describe Backup::Files do
end
describe '#noncritical_warning?' do
- subject { described_class.new('registry', '/var/gitlab-registry') }
+ subject { described_class.new(progress, 'registry', '/var/gitlab-registry') }
it 'returns true if given text matches noncritical warnings list' do
expect(
diff --git a/spec/lib/backup/gitaly_backup_spec.rb b/spec/lib/backup/gitaly_backup_spec.rb
index 6bf4f833c1f..f5295c2b04c 100644
--- a/spec/lib/backup/gitaly_backup_spec.rb
+++ b/spec/lib/backup/gitaly_backup_spec.rb
@@ -5,6 +5,8 @@ require 'spec_helper'
RSpec.describe Backup::GitalyBackup do
let(:max_parallelism) { nil }
let(:storage_parallelism) { nil }
+ let(:destination) { File.join(Gitlab.config.backup.path, 'repositories') }
+ let(:backup_id) { '20220101' }
let(:progress) do
Tempfile.new('progress').tap do |progress|
@@ -23,11 +25,11 @@ RSpec.describe Backup::GitalyBackup do
progress.close
end
- subject { described_class.new(progress, max_parallelism: max_parallelism, storage_parallelism: storage_parallelism) }
+ subject { described_class.new(progress, max_parallelism: max_parallelism, storage_parallelism: storage_parallelism, backup_id: backup_id) }
context 'unknown' do
it 'fails to start unknown' do
- expect { subject.start(:unknown) }.to raise_error(::Backup::Error, 'unknown backup type: unknown')
+ expect { subject.start(:unknown, destination) }.to raise_error(::Backup::Error, 'unknown backup type: unknown')
end
end
@@ -40,9 +42,9 @@ RSpec.describe Backup::GitalyBackup do
project_snippet = create(:project_snippet, :repository, project: project)
personal_snippet = create(:personal_snippet, :repository, author: project.first_owner)
- expect(Open3).to receive(:popen2).with(expected_env, anything, 'create', '-path', anything).and_call_original
+ expect(Open3).to receive(:popen2).with(expected_env, anything, 'create', '-path', anything, '-layout', 'pointer', '-id', backup_id).and_call_original
- subject.start(:create)
+ subject.start(:create, destination)
subject.enqueue(project, Gitlab::GlRepository::PROJECT)
subject.enqueue(project, Gitlab::GlRepository::WIKI)
subject.enqueue(project, Gitlab::GlRepository::DESIGN)
@@ -50,20 +52,20 @@ RSpec.describe Backup::GitalyBackup do
subject.enqueue(project_snippet, Gitlab::GlRepository::SNIPPET)
subject.finish!
- expect(File).to exist(File.join(Gitlab.config.backup.path, 'repositories', project.disk_path + '.bundle'))
- expect(File).to exist(File.join(Gitlab.config.backup.path, 'repositories', project.disk_path + '.wiki.bundle'))
- expect(File).to exist(File.join(Gitlab.config.backup.path, 'repositories', project.disk_path + '.design.bundle'))
- expect(File).to exist(File.join(Gitlab.config.backup.path, 'repositories', personal_snippet.disk_path + '.bundle'))
- expect(File).to exist(File.join(Gitlab.config.backup.path, 'repositories', project_snippet.disk_path + '.bundle'))
+ expect(File).to exist(File.join(destination, project.disk_path, backup_id, '001.bundle'))
+ expect(File).to exist(File.join(destination, project.disk_path + '.wiki', backup_id, '001.bundle'))
+ expect(File).to exist(File.join(destination, project.disk_path + '.design', backup_id, '001.bundle'))
+ expect(File).to exist(File.join(destination, personal_snippet.disk_path, backup_id, '001.bundle'))
+ expect(File).to exist(File.join(destination, project_snippet.disk_path, backup_id, '001.bundle'))
end
context 'parallel option set' do
let(:max_parallelism) { 3 }
it 'passes parallel option through' do
- expect(Open3).to receive(:popen2).with(expected_env, anything, 'create', '-path', anything, '-parallel', '3').and_call_original
+ expect(Open3).to receive(:popen2).with(expected_env, anything, 'create', '-path', anything, '-parallel', '3', '-layout', 'pointer', '-id', backup_id).and_call_original
- subject.start(:create)
+ subject.start(:create, destination)
subject.finish!
end
end
@@ -72,9 +74,9 @@ RSpec.describe Backup::GitalyBackup do
let(:storage_parallelism) { 3 }
it 'passes parallel option through' do
- expect(Open3).to receive(:popen2).with(expected_env, anything, 'create', '-path', anything, '-parallel-storage', '3').and_call_original
+ expect(Open3).to receive(:popen2).with(expected_env, anything, 'create', '-path', anything, '-parallel-storage', '3', '-layout', 'pointer', '-id', backup_id).and_call_original
- subject.start(:create)
+ subject.start(:create, destination)
subject.finish!
end
end
@@ -82,9 +84,39 @@ RSpec.describe Backup::GitalyBackup do
it 'raises when the exit code not zero' do
expect(subject).to receive(:bin_path).and_return(Gitlab::Utils.which('false'))
- subject.start(:create)
+ subject.start(:create, destination)
expect { subject.finish! }.to raise_error(::Backup::Error, 'gitaly-backup exit status 1')
end
+
+ context 'feature flag incremental_repository_backup disabled' do
+ before do
+ stub_feature_flags(incremental_repository_backup: false)
+ end
+
+ it 'creates repository bundles', :aggregate_failures do
+ # Add data to the wiki, design repositories, and snippets, so they will be included in the dump.
+ create(:wiki_page, container: project)
+ create(:design, :with_file, issue: create(:issue, project: project))
+ project_snippet = create(:project_snippet, :repository, project: project)
+ personal_snippet = create(:personal_snippet, :repository, author: project.first_owner)
+
+ expect(Open3).to receive(:popen2).with(expected_env, anything, 'create', '-path', anything).and_call_original
+
+ subject.start(:create, destination)
+ subject.enqueue(project, Gitlab::GlRepository::PROJECT)
+ subject.enqueue(project, Gitlab::GlRepository::WIKI)
+ subject.enqueue(project, Gitlab::GlRepository::DESIGN)
+ subject.enqueue(personal_snippet, Gitlab::GlRepository::SNIPPET)
+ subject.enqueue(project_snippet, Gitlab::GlRepository::SNIPPET)
+ subject.finish!
+
+ expect(File).to exist(File.join(destination, project.disk_path + '.bundle'))
+ expect(File).to exist(File.join(destination, project.disk_path + '.wiki.bundle'))
+ expect(File).to exist(File.join(destination, project.disk_path + '.design.bundle'))
+ expect(File).to exist(File.join(destination, personal_snippet.disk_path + '.bundle'))
+ expect(File).to exist(File.join(destination, project_snippet.disk_path + '.bundle'))
+ end
+ end
end
context 'hashed storage' do
@@ -112,9 +144,9 @@ RSpec.describe Backup::GitalyBackup do
end
it 'passes through SSL envs' do
- expect(Open3).to receive(:popen2).with(ssl_env, anything, 'create', '-path', anything).and_call_original
+ expect(Open3).to receive(:popen2).with(ssl_env, anything, 'create', '-path', anything, '-layout', 'pointer', '-id', backup_id).and_call_original
- subject.start(:create)
+ subject.start(:create, destination)
subject.finish!
end
end
@@ -137,9 +169,9 @@ RSpec.describe Backup::GitalyBackup do
copy_bundle_to_backup_path('personal_snippet_repo.bundle', personal_snippet.disk_path + '.bundle')
copy_bundle_to_backup_path('project_snippet_repo.bundle', project_snippet.disk_path + '.bundle')
- expect(Open3).to receive(:popen2).with(expected_env, anything, 'restore', '-path', anything).and_call_original
+ expect(Open3).to receive(:popen2).with(expected_env, anything, 'restore', '-path', anything, '-layout', 'pointer').and_call_original
- subject.start(:restore)
+ subject.start(:restore, destination)
subject.enqueue(project, Gitlab::GlRepository::PROJECT)
subject.enqueue(project, Gitlab::GlRepository::WIKI)
subject.enqueue(project, Gitlab::GlRepository::DESIGN)
@@ -149,20 +181,20 @@ RSpec.describe Backup::GitalyBackup do
collect_commit_shas = -> (repo) { repo.commits('master', limit: 10).map(&:sha) }
- expect(collect_commit_shas.call(project.repository)).to eq(['393a7d860a5a4c3cc736d7eb00604e3472bb95ec'])
- expect(collect_commit_shas.call(project.wiki.repository)).to eq(['c74b9948d0088d703ee1fafeddd9ed9add2901ea'])
- expect(collect_commit_shas.call(project.design_repository)).to eq(['c3cd4d7bd73a51a0f22045c3a4c871c435dc959d'])
- expect(collect_commit_shas.call(personal_snippet.repository)).to eq(['3b3c067a3bc1d1b695b51e2be30c0f8cf698a06e'])
- expect(collect_commit_shas.call(project_snippet.repository)).to eq(['6e44ba56a4748be361a841e759c20e421a1651a1'])
+ expect(collect_commit_shas.call(project.repository)).to match_array(['393a7d860a5a4c3cc736d7eb00604e3472bb95ec'])
+ expect(collect_commit_shas.call(project.wiki.repository)).to match_array(['c74b9948d0088d703ee1fafeddd9ed9add2901ea'])
+ expect(collect_commit_shas.call(project.design_repository)).to match_array(['c3cd4d7bd73a51a0f22045c3a4c871c435dc959d'])
+ expect(collect_commit_shas.call(personal_snippet.repository)).to match_array(['3b3c067a3bc1d1b695b51e2be30c0f8cf698a06e'])
+ expect(collect_commit_shas.call(project_snippet.repository)).to match_array(['6e44ba56a4748be361a841e759c20e421a1651a1'])
end
context 'parallel option set' do
let(:max_parallelism) { 3 }
it 'passes parallel option through' do
- expect(Open3).to receive(:popen2).with(expected_env, anything, 'restore', '-path', anything, '-parallel', '3').and_call_original
+ expect(Open3).to receive(:popen2).with(expected_env, anything, 'restore', '-path', anything, '-parallel', '3', '-layout', 'pointer').and_call_original
- subject.start(:restore)
+ subject.start(:restore, destination)
subject.finish!
end
end
@@ -171,17 +203,49 @@ RSpec.describe Backup::GitalyBackup do
let(:storage_parallelism) { 3 }
it 'passes parallel option through' do
- expect(Open3).to receive(:popen2).with(expected_env, anything, 'restore', '-path', anything, '-parallel-storage', '3').and_call_original
+ expect(Open3).to receive(:popen2).with(expected_env, anything, 'restore', '-path', anything, '-parallel-storage', '3', '-layout', 'pointer').and_call_original
- subject.start(:restore)
+ subject.start(:restore, destination)
subject.finish!
end
end
+ context 'feature flag incremental_repository_backup disabled' do
+ before do
+ stub_feature_flags(incremental_repository_backup: false)
+ end
+
+ it 'restores from repository bundles', :aggregate_failures do
+ copy_bundle_to_backup_path('project_repo.bundle', project.disk_path + '.bundle')
+ copy_bundle_to_backup_path('wiki_repo.bundle', project.disk_path + '.wiki.bundle')
+ copy_bundle_to_backup_path('design_repo.bundle', project.disk_path + '.design.bundle')
+ copy_bundle_to_backup_path('personal_snippet_repo.bundle', personal_snippet.disk_path + '.bundle')
+ copy_bundle_to_backup_path('project_snippet_repo.bundle', project_snippet.disk_path + '.bundle')
+
+ expect(Open3).to receive(:popen2).with(expected_env, anything, 'restore', '-path', anything).and_call_original
+
+ subject.start(:restore, destination)
+ subject.enqueue(project, Gitlab::GlRepository::PROJECT)
+ subject.enqueue(project, Gitlab::GlRepository::WIKI)
+ subject.enqueue(project, Gitlab::GlRepository::DESIGN)
+ subject.enqueue(personal_snippet, Gitlab::GlRepository::SNIPPET)
+ subject.enqueue(project_snippet, Gitlab::GlRepository::SNIPPET)
+ subject.finish!
+
+ collect_commit_shas = -> (repo) { repo.commits('master', limit: 10).map(&:sha) }
+
+ expect(collect_commit_shas.call(project.repository)).to match_array(['393a7d860a5a4c3cc736d7eb00604e3472bb95ec'])
+ expect(collect_commit_shas.call(project.wiki.repository)).to match_array(['c74b9948d0088d703ee1fafeddd9ed9add2901ea'])
+ expect(collect_commit_shas.call(project.design_repository)).to match_array(['c3cd4d7bd73a51a0f22045c3a4c871c435dc959d'])
+ expect(collect_commit_shas.call(personal_snippet.repository)).to match_array(['3b3c067a3bc1d1b695b51e2be30c0f8cf698a06e'])
+ expect(collect_commit_shas.call(project_snippet.repository)).to match_array(['6e44ba56a4748be361a841e759c20e421a1651a1'])
+ end
+ end
+
it 'raises when the exit code not zero' do
expect(subject).to receive(:bin_path).and_return(Gitlab::Utils.which('false'))
- subject.start(:restore)
+ subject.start(:restore, destination)
expect { subject.finish! }.to raise_error(::Backup::Error, 'gitaly-backup exit status 1')
end
end
diff --git a/spec/lib/backup/gitaly_rpc_backup_spec.rb b/spec/lib/backup/gitaly_rpc_backup_spec.rb
index 4829d51ac9d..6cba8c5c9b1 100644
--- a/spec/lib/backup/gitaly_rpc_backup_spec.rb
+++ b/spec/lib/backup/gitaly_rpc_backup_spec.rb
@@ -4,6 +4,7 @@ require 'spec_helper'
RSpec.describe Backup::GitalyRpcBackup do
let(:progress) { spy(:stdout) }
+ let(:destination) { File.join(Gitlab.config.backup.path, 'repositories') }
subject { described_class.new(progress) }
@@ -14,7 +15,7 @@ RSpec.describe Backup::GitalyRpcBackup do
context 'unknown' do
it 'fails to start unknown' do
- expect { subject.start(:unknown) }.to raise_error(::Backup::Error, 'unknown backup type: unknown')
+ expect { subject.start(:unknown, destination) }.to raise_error(::Backup::Error, 'unknown backup type: unknown')
end
end
@@ -27,7 +28,7 @@ RSpec.describe Backup::GitalyRpcBackup do
project_snippet = create(:project_snippet, :repository, project: project)
personal_snippet = create(:personal_snippet, :repository, author: project.first_owner)
- subject.start(:create)
+ subject.start(:create, destination)
subject.enqueue(project, Gitlab::GlRepository::PROJECT)
subject.enqueue(project, Gitlab::GlRepository::WIKI)
subject.enqueue(project, Gitlab::GlRepository::DESIGN)
@@ -35,11 +36,11 @@ RSpec.describe Backup::GitalyRpcBackup do
subject.enqueue(project_snippet, Gitlab::GlRepository::SNIPPET)
subject.finish!
- expect(File).to exist(File.join(Gitlab.config.backup.path, 'repositories', project.disk_path + '.bundle'))
- expect(File).to exist(File.join(Gitlab.config.backup.path, 'repositories', project.disk_path + '.wiki.bundle'))
- expect(File).to exist(File.join(Gitlab.config.backup.path, 'repositories', project.disk_path + '.design.bundle'))
- expect(File).to exist(File.join(Gitlab.config.backup.path, 'repositories', personal_snippet.disk_path + '.bundle'))
- expect(File).to exist(File.join(Gitlab.config.backup.path, 'repositories', project_snippet.disk_path + '.bundle'))
+ expect(File).to exist(File.join(destination, project.disk_path + '.bundle'))
+ expect(File).to exist(File.join(destination, project.disk_path + '.wiki.bundle'))
+ expect(File).to exist(File.join(destination, project.disk_path + '.design.bundle'))
+ expect(File).to exist(File.join(destination, personal_snippet.disk_path + '.bundle'))
+ expect(File).to exist(File.join(destination, project_snippet.disk_path + '.bundle'))
end
context 'failure' do
@@ -50,7 +51,7 @@ RSpec.describe Backup::GitalyRpcBackup do
end
it 'logs an appropriate message', :aggregate_failures do
- subject.start(:create)
+ subject.start(:create, destination)
subject.enqueue(project, Gitlab::GlRepository::PROJECT)
subject.finish!
@@ -90,7 +91,7 @@ RSpec.describe Backup::GitalyRpcBackup do
copy_bundle_to_backup_path('personal_snippet_repo.bundle', personal_snippet.disk_path + '.bundle')
copy_bundle_to_backup_path('project_snippet_repo.bundle', project_snippet.disk_path + '.bundle')
- subject.start(:restore)
+ subject.start(:restore, destination)
subject.enqueue(project, Gitlab::GlRepository::PROJECT)
subject.enqueue(project, Gitlab::GlRepository::WIKI)
subject.enqueue(project, Gitlab::GlRepository::DESIGN)
@@ -123,7 +124,7 @@ RSpec.describe Backup::GitalyRpcBackup do
repository
end
- subject.start(:restore)
+ subject.start(:restore, destination)
subject.enqueue(project, Gitlab::GlRepository::PROJECT)
subject.enqueue(project, Gitlab::GlRepository::WIKI)
subject.enqueue(project, Gitlab::GlRepository::DESIGN)
@@ -141,7 +142,7 @@ RSpec.describe Backup::GitalyRpcBackup do
end
it 'logs an appropriate message', :aggregate_failures do
- subject.start(:restore)
+ subject.start(:restore, destination)
subject.enqueue(project, Gitlab::GlRepository::PROJECT)
subject.finish!
diff --git a/spec/lib/backup/lfs_spec.rb b/spec/lib/backup/lfs_spec.rb
index 6525019d9ac..a27f60f20d0 100644
--- a/spec/lib/backup/lfs_spec.rb
+++ b/spec/lib/backup/lfs_spec.rb
@@ -20,7 +20,7 @@ RSpec.describe Backup::Lfs do
expect(backup).to receive(:run_pipeline!).with([%w(blabla-tar --exclude=lost+found -C /var/lfs-objects -cf - .), 'gzip -c -1'], any_args).and_return([[true, true], ''])
expect(backup).to receive(:pipeline_succeeded?).and_return(true)
- backup.dump
+ backup.dump('lfs.tar.gz')
end
end
end
diff --git a/spec/lib/backup/manager_spec.rb b/spec/lib/backup/manager_spec.rb
index 9c186205067..9cf78a11bc7 100644
--- a/spec/lib/backup/manager_spec.rb
+++ b/spec/lib/backup/manager_spec.rb
@@ -6,16 +6,149 @@ RSpec.describe Backup::Manager do
include StubENV
let(:progress) { StringIO.new }
+ let(:definitions) { nil }
- subject { described_class.new(progress) }
+ subject { described_class.new(progress, definitions: definitions) }
before do
+ # Rspec fails with `uninitialized constant RSpec::Support::Differ` when it
+ # is trying to display a diff and `File.exist?` is stubbed. Adding a
+ # default stub fixes this.
+ allow(File).to receive(:exist?).and_call_original
+
allow(progress).to receive(:puts)
allow(progress).to receive(:print)
end
- describe '#pack' do
- let(:expected_backup_contents) { %w(repositories db uploads.tar.gz builds.tar.gz artifacts.tar.gz pages.tar.gz lfs.tar.gz terraform_state.tar.gz packages.tar.gz backup_information.yml) }
+ describe '#run_create_task' do
+ let(:enabled) { true }
+ let(:task) { instance_double(Backup::Task, human_name: 'my task', enabled: enabled) }
+ let(:definitions) { { 'my_task' => Backup::Manager::TaskDefinition.new(task: task, destination_path: 'my_task.tar.gz') } }
+
+ it 'calls the named task' do
+ expect(task).to receive(:dump)
+ expect(Gitlab::BackupLogger).to receive(:info).with(message: 'Dumping my task ... ')
+ expect(Gitlab::BackupLogger).to receive(:info).with(message: 'done')
+
+ subject.run_create_task('my_task')
+ end
+
+ describe 'disabled' do
+ let(:enabled) { false }
+
+ it 'informs the user' do
+ expect(Gitlab::BackupLogger).to receive(:info).with(message: 'Dumping my task ... ')
+ expect(Gitlab::BackupLogger).to receive(:info).with(message: '[DISABLED]')
+
+ subject.run_create_task('my_task')
+ end
+ end
+
+ describe 'skipped' do
+ it 'informs the user' do
+ stub_env('SKIP', 'my_task')
+
+ expect(Gitlab::BackupLogger).to receive(:info).with(message: 'Dumping my task ... ')
+ expect(Gitlab::BackupLogger).to receive(:info).with(message: '[SKIPPED]')
+
+ subject.run_create_task('my_task')
+ end
+ end
+ end
+
+ describe '#run_restore_task' do
+ let(:enabled) { true }
+ let(:pre_restore_warning) { nil }
+ let(:post_restore_warning) { nil }
+ let(:definitions) { { 'my_task' => Backup::Manager::TaskDefinition.new(task: task, destination_path: 'my_task.tar.gz') } }
+ let(:backup_information) { {} }
+ let(:task) do
+ instance_double(Backup::Task,
+ human_name: 'my task',
+ enabled: enabled,
+ pre_restore_warning: pre_restore_warning,
+ post_restore_warning: post_restore_warning)
+ end
+
+ before do
+ allow(YAML).to receive(:load_file).with(File.join(Gitlab.config.backup.path, 'backup_information.yml'))
+ .and_return(backup_information)
+ end
+
+ it 'calls the named task' do
+ expect(task).to receive(:restore)
+ expect(Gitlab::BackupLogger).to receive(:info).with(message: 'Restoring my task ... ').ordered
+ expect(Gitlab::BackupLogger).to receive(:info).with(message: 'done').ordered
+
+ subject.run_restore_task('my_task')
+ end
+
+ describe 'disabled' do
+ let(:enabled) { false }
+
+ it 'informs the user' do
+ expect(Gitlab::BackupLogger).to receive(:info).with(message: 'Restoring my task ... ').ordered
+ expect(Gitlab::BackupLogger).to receive(:info).with(message: '[DISABLED]').ordered
+
+ subject.run_restore_task('my_task')
+ end
+ end
+
+ describe 'pre_restore_warning' do
+ let(:pre_restore_warning) { 'Watch out!' }
+
+ it 'displays and waits for the user' do
+ expect(Gitlab::BackupLogger).to receive(:info).with(message: 'Restoring my task ... ').ordered
+ expect(Gitlab::BackupLogger).to receive(:info).with(message: 'Watch out!').ordered
+ expect(Gitlab::BackupLogger).to receive(:info).with(message: 'done').ordered
+ expect(Gitlab::TaskHelpers).to receive(:ask_to_continue)
+ expect(task).to receive(:restore)
+
+ subject.run_restore_task('my_task')
+ end
+
+ it 'does not continue when the user quits' do
+ expect(Gitlab::BackupLogger).to receive(:info).with(message: 'Restoring my task ... ').ordered
+ expect(Gitlab::BackupLogger).to receive(:info).with(message: 'Watch out!').ordered
+ expect(Gitlab::BackupLogger).to receive(:info).with(message: 'Quitting...').ordered
+ expect(Gitlab::TaskHelpers).to receive(:ask_to_continue).and_raise(Gitlab::TaskAbortedByUserError)
+
+ expect do
+ subject.run_restore_task('my_task')
+ end.to raise_error(SystemExit)
+ end
+ end
+
+ describe 'post_restore_warning' do
+ let(:post_restore_warning) { 'Watch out!' }
+
+ it 'displays and waits for the user' do
+ expect(Gitlab::BackupLogger).to receive(:info).with(message: 'Restoring my task ... ').ordered
+ expect(Gitlab::BackupLogger).to receive(:info).with(message: 'done').ordered
+ expect(Gitlab::BackupLogger).to receive(:info).with(message: 'Watch out!').ordered
+ expect(Gitlab::TaskHelpers).to receive(:ask_to_continue)
+ expect(task).to receive(:restore)
+
+ subject.run_restore_task('my_task')
+ end
+
+ it 'does not continue when the user quits' do
+ expect(Gitlab::BackupLogger).to receive(:info).with(message: 'Restoring my task ... ').ordered
+ expect(Gitlab::BackupLogger).to receive(:info).with(message: 'done').ordered
+ expect(Gitlab::BackupLogger).to receive(:info).with(message: 'Watch out!').ordered
+ expect(Gitlab::BackupLogger).to receive(:info).with(message: 'Quitting...').ordered
+ expect(task).to receive(:restore)
+ expect(Gitlab::TaskHelpers).to receive(:ask_to_continue).and_raise(Gitlab::TaskAbortedByUserError)
+
+ expect do
+ subject.run_restore_task('my_task')
+ end.to raise_error(SystemExit)
+ end
+ end
+ end
+
+ describe '#create' do
+ let(:expected_backup_contents) { %w{backup_information.yml task1.tar.gz task2.tar.gz} }
let(:tar_file) { '1546300800_2019_01_01_12.3_gitlab_backup.tar' }
let(:tar_system_options) { { out: [tar_file, 'w', Gitlab.config.backup.archive_permissions] } }
let(:tar_cmdline) { ['tar', '-cf', '-', *expected_backup_contents, tar_system_options] }
@@ -26,21 +159,28 @@ RSpec.describe Backup::Manager do
}
end
+ let(:task1) { instance_double(Backup::Task, human_name: 'task 1', enabled: true) }
+ let(:task2) { instance_double(Backup::Task, human_name: 'task 2', enabled: true) }
+ let(:definitions) do
+ {
+ 'task1' => Backup::Manager::TaskDefinition.new(task: task1, destination_path: 'task1.tar.gz'),
+ 'task2' => Backup::Manager::TaskDefinition.new(task: task2, destination_path: 'task2.tar.gz')
+ }
+ end
+
before do
allow(ActiveRecord::Base.connection).to receive(:reconnect!)
allow(Kernel).to receive(:system).and_return(true)
- allow(YAML).to receive(:load_file).and_return(backup_information)
-
- ::Backup::Manager::FOLDERS_TO_BACKUP.each do |folder|
- allow(Dir).to receive(:exist?).with(File.join(Gitlab.config.backup.path, folder)).and_return(true)
- end
+ allow(YAML).to receive(:load_file).with(File.join(Gitlab.config.backup.path, 'backup_information.yml'))
+ .and_return(backup_information)
allow(subject).to receive(:backup_information).and_return(backup_information)
- allow(subject).to receive(:upload)
+ allow(task1).to receive(:dump).with(File.join(Gitlab.config.backup.path, 'task1.tar.gz'))
+ allow(task2).to receive(:dump).with(File.join(Gitlab.config.backup.path, 'task2.tar.gz'))
end
it 'executes tar' do
- subject.pack
+ subject.create # rubocop:disable Rails/SaveBang
expect(Kernel).to have_received(:system).with(*tar_cmdline)
end
@@ -50,247 +190,401 @@ RSpec.describe Backup::Manager do
it 'uses the given value as tar file name' do
stub_env('BACKUP', '/ignored/path/custom')
- subject.pack
+ subject.create # rubocop:disable Rails/SaveBang
expect(Kernel).to have_received(:system).with(*tar_cmdline)
end
end
context 'when skipped is set in backup_information.yml' do
- let(:expected_backup_contents) { %w{db uploads.tar.gz builds.tar.gz artifacts.tar.gz pages.tar.gz lfs.tar.gz terraform_state.tar.gz packages.tar.gz backup_information.yml} }
+ let(:expected_backup_contents) { %w{backup_information.yml task1.tar.gz} }
let(:backup_information) do
{
backup_created_at: Time.zone.parse('2019-01-01'),
gitlab_version: '12.3',
- skipped: ['repositories']
+ skipped: ['task2']
}
end
it 'executes tar' do
- subject.pack
+ subject.create # rubocop:disable Rails/SaveBang
expect(Kernel).to have_received(:system).with(*tar_cmdline)
end
end
- context 'when a directory does not exist' do
- let(:expected_backup_contents) { %w{db uploads.tar.gz builds.tar.gz artifacts.tar.gz pages.tar.gz lfs.tar.gz terraform_state.tar.gz packages.tar.gz backup_information.yml} }
-
- before do
- expect(Dir).to receive(:exist?).with(File.join(Gitlab.config.backup.path, 'repositories')).and_return(false)
+ context 'when the destination is optional' do
+ let(:expected_backup_contents) { %w{backup_information.yml task1.tar.gz} }
+ let(:definitions) do
+ {
+ 'task1' => Backup::Manager::TaskDefinition.new(task: task1, destination_path: 'task1.tar.gz'),
+ 'task2' => Backup::Manager::TaskDefinition.new(task: task2, destination_path: 'task2.tar.gz', destination_optional: true)
+ }
end
it 'executes tar' do
- subject.pack
+ expect(File).to receive(:exist?).with(File.join(Gitlab.config.backup.path, 'task2.tar.gz')).and_return(false)
+
+ subject.create # rubocop:disable Rails/SaveBang
expect(Kernel).to have_received(:system).with(*tar_cmdline)
end
end
- end
- describe '#remove_tmp' do
- let(:path) { File.join(Gitlab.config.backup.path, 'tmp') }
+ context 'many backup files' do
+ let(:files) do
+ [
+ '1451606400_2016_01_01_1.2.3_gitlab_backup.tar',
+ '1451520000_2015_12_31_4.5.6_gitlab_backup.tar',
+ '1451520000_2015_12_31_4.5.6-pre_gitlab_backup.tar',
+ '1451520000_2015_12_31_4.5.6-rc1_gitlab_backup.tar',
+ '1451520000_2015_12_31_4.5.6-pre-ee_gitlab_backup.tar',
+ '1451510000_2015_12_30_gitlab_backup.tar',
+ '1450742400_2015_12_22_gitlab_backup.tar',
+ '1449878400_gitlab_backup.tar',
+ '1449014400_gitlab_backup.tar',
+ 'manual_gitlab_backup.tar'
+ ]
+ end
- before do
- allow(FileUtils).to receive(:rm_rf).and_return(true)
- end
+ before do
+ allow(Dir).to receive(:chdir).and_yield
+ allow(Dir).to receive(:glob).and_return(files)
+ allow(FileUtils).to receive(:rm)
+ allow(Time).to receive(:now).and_return(Time.utc(2016))
+ end
- it 'removes backups/tmp dir' do
- subject.remove_tmp
+ context 'when keep_time is zero' do
+ before do
+ allow(Gitlab.config.backup).to receive(:keep_time).and_return(0)
- expect(FileUtils).to have_received(:rm_rf).with(path)
- end
+ subject.create # rubocop:disable Rails/SaveBang
+ end
- it 'prints running task with a done confirmation' do
- subject.remove_tmp
+ it 'removes no files' do
+ expect(FileUtils).not_to have_received(:rm)
+ end
- expect(progress).to have_received(:print).with('Deleting backups/tmp ... ')
- expect(progress).to have_received(:puts).with('done')
- end
- end
+ it 'prints a skipped message' do
+ expect(progress).to have_received(:puts).with('skipping')
+ end
+ end
- describe '#remove_old' do
- let(:files) do
- [
- '1451606400_2016_01_01_1.2.3_gitlab_backup.tar',
- '1451520000_2015_12_31_4.5.6_gitlab_backup.tar',
- '1451520000_2015_12_31_4.5.6-pre_gitlab_backup.tar',
- '1451520000_2015_12_31_4.5.6-rc1_gitlab_backup.tar',
- '1451520000_2015_12_31_4.5.6-pre-ee_gitlab_backup.tar',
- '1451510000_2015_12_30_gitlab_backup.tar',
- '1450742400_2015_12_22_gitlab_backup.tar',
- '1449878400_gitlab_backup.tar',
- '1449014400_gitlab_backup.tar',
- 'manual_gitlab_backup.tar'
- ]
- end
+ context 'when no valid file is found' do
+ let(:files) do
+ [
+ '14516064000_2016_01_01_1.2.3_gitlab_backup.tar',
+ 'foo_1451520000_2015_12_31_4.5.6_gitlab_backup.tar',
+ '1451520000_2015_12_31_4.5.6-foo_gitlab_backup.tar'
+ ]
+ end
- before do
- allow(Dir).to receive(:chdir).and_yield
- allow(Dir).to receive(:glob).and_return(files)
- allow(FileUtils).to receive(:rm)
- allow(Time).to receive(:now).and_return(Time.utc(2016))
- end
+ before do
+ allow(Gitlab.config.backup).to receive(:keep_time).and_return(1)
- context 'when keep_time is zero' do
- before do
- allow(Gitlab.config.backup).to receive(:keep_time).and_return(0)
+ subject.create # rubocop:disable Rails/SaveBang
+ end
- subject.remove_old
- end
+ it 'removes no files' do
+ expect(FileUtils).not_to have_received(:rm)
+ end
- it 'removes no files' do
- expect(FileUtils).not_to have_received(:rm)
+ it 'prints a done message' do
+ expect(progress).to have_received(:puts).with('done. (0 removed)')
+ end
end
- it 'prints a skipped message' do
- expect(progress).to have_received(:puts).with('skipping')
- end
- end
+ context 'when there are no files older than keep_time' do
+ before do
+ # Set to 30 days
+ allow(Gitlab.config.backup).to receive(:keep_time).and_return(2592000)
- context 'when no valid file is found' do
- let(:files) do
- [
- '14516064000_2016_01_01_1.2.3_gitlab_backup.tar',
- 'foo_1451520000_2015_12_31_4.5.6_gitlab_backup.tar',
- '1451520000_2015_12_31_4.5.6-foo_gitlab_backup.tar'
- ]
- end
+ subject.create # rubocop:disable Rails/SaveBang
+ end
- before do
- allow(Gitlab.config.backup).to receive(:keep_time).and_return(1)
+ it 'removes no files' do
+ expect(FileUtils).not_to have_received(:rm)
+ end
- subject.remove_old
+ it 'prints a done message' do
+ expect(progress).to have_received(:puts).with('done. (0 removed)')
+ end
end
- it 'removes no files' do
- expect(FileUtils).not_to have_received(:rm)
- end
+ context 'when keep_time is set to remove files' do
+ before do
+ # Set to 1 second
+ allow(Gitlab.config.backup).to receive(:keep_time).and_return(1)
- it 'prints a done message' do
- expect(progress).to have_received(:puts).with('done. (0 removed)')
- end
- end
+ subject.create # rubocop:disable Rails/SaveBang
+ end
- context 'when there are no files older than keep_time' do
- before do
- # Set to 30 days
- allow(Gitlab.config.backup).to receive(:keep_time).and_return(2592000)
+ it 'removes matching files with a human-readable versioned timestamp' do
+ expect(FileUtils).to have_received(:rm).with(files[1])
+ expect(FileUtils).to have_received(:rm).with(files[2])
+ expect(FileUtils).to have_received(:rm).with(files[3])
+ end
- subject.remove_old
- end
+ it 'removes matching files with a human-readable versioned timestamp with tagged EE' do
+ expect(FileUtils).to have_received(:rm).with(files[4])
+ end
- it 'removes no files' do
- expect(FileUtils).not_to have_received(:rm)
- end
+ it 'removes matching files with a human-readable non-versioned timestamp' do
+ expect(FileUtils).to have_received(:rm).with(files[5])
+ expect(FileUtils).to have_received(:rm).with(files[6])
+ end
- it 'prints a done message' do
- expect(progress).to have_received(:puts).with('done. (0 removed)')
- end
- end
+ it 'removes matching files without a human-readable timestamp' do
+ expect(FileUtils).to have_received(:rm).with(files[7])
+ expect(FileUtils).to have_received(:rm).with(files[8])
+ end
- context 'when keep_time is set to remove files' do
- before do
- # Set to 1 second
- allow(Gitlab.config.backup).to receive(:keep_time).and_return(1)
+ it 'does not remove files that are not old enough' do
+ expect(FileUtils).not_to have_received(:rm).with(files[0])
+ end
- subject.remove_old
- end
+ it 'does not remove non-matching files' do
+ expect(FileUtils).not_to have_received(:rm).with(files[9])
+ end
- it 'removes matching files with a human-readable versioned timestamp' do
- expect(FileUtils).to have_received(:rm).with(files[1])
- expect(FileUtils).to have_received(:rm).with(files[2])
- expect(FileUtils).to have_received(:rm).with(files[3])
+ it 'prints a done message' do
+ expect(progress).to have_received(:puts).with('done. (8 removed)')
+ end
end
- it 'removes matching files with a human-readable versioned timestamp with tagged EE' do
- expect(FileUtils).to have_received(:rm).with(files[4])
- end
+ context 'when removing a file fails' do
+ let(:file) { files[1] }
+ let(:message) { "Permission denied @ unlink_internal - #{file}" }
- it 'removes matching files with a human-readable non-versioned timestamp' do
- expect(FileUtils).to have_received(:rm).with(files[5])
- expect(FileUtils).to have_received(:rm).with(files[6])
- end
+ before do
+ allow(Gitlab.config.backup).to receive(:keep_time).and_return(1)
+ allow(FileUtils).to receive(:rm).with(file).and_raise(Errno::EACCES, message)
- it 'removes matching files without a human-readable timestamp' do
- expect(FileUtils).to have_received(:rm).with(files[7])
- expect(FileUtils).to have_received(:rm).with(files[8])
- end
+ subject.create # rubocop:disable Rails/SaveBang
+ end
- it 'does not remove files that are not old enough' do
- expect(FileUtils).not_to have_received(:rm).with(files[0])
- end
+ it 'removes the remaining expected files' do
+ expect(FileUtils).to have_received(:rm).with(files[4])
+ expect(FileUtils).to have_received(:rm).with(files[5])
+ expect(FileUtils).to have_received(:rm).with(files[6])
+ expect(FileUtils).to have_received(:rm).with(files[7])
+ expect(FileUtils).to have_received(:rm).with(files[8])
+ end
- it 'does not remove non-matching files' do
- expect(FileUtils).not_to have_received(:rm).with(files[9])
- end
+ it 'sets the correct removed count' do
+ expect(progress).to have_received(:puts).with('done. (7 removed)')
+ end
- it 'prints a done message' do
- expect(progress).to have_received(:puts).with('done. (8 removed)')
+ it 'prints the error from file that could not be removed' do
+ expect(progress).to have_received(:puts).with(a_string_matching(message))
+ end
end
end
- context 'when removing a file fails' do
- let(:file) { files[1] }
- let(:message) { "Permission denied @ unlink_internal - #{file}" }
+ describe 'cloud storage' do
+ let(:backup_file) { Tempfile.new('backup', Gitlab.config.backup.path) }
+ let(:backup_filename) { File.basename(backup_file.path) }
before do
- allow(Gitlab.config.backup).to receive(:keep_time).and_return(1)
- allow(FileUtils).to receive(:rm).with(file).and_raise(Errno::EACCES, message)
+ allow(subject).to receive(:tar_file).and_return(backup_filename)
- subject.remove_old
- end
+ stub_backup_setting(
+ upload: {
+ connection: {
+ provider: 'AWS',
+ aws_access_key_id: 'id',
+ aws_secret_access_key: 'secret'
+ },
+ remote_directory: 'directory',
+ multipart_chunk_size: 104857600,
+ encryption: nil,
+ encryption_key: nil,
+ storage_class: nil
+ }
+ )
- it 'removes the remaining expected files' do
- expect(FileUtils).to have_received(:rm).with(files[4])
- expect(FileUtils).to have_received(:rm).with(files[5])
- expect(FileUtils).to have_received(:rm).with(files[6])
- expect(FileUtils).to have_received(:rm).with(files[7])
- expect(FileUtils).to have_received(:rm).with(files[8])
- end
+ Fog.mock!
- it 'sets the correct removed count' do
- expect(progress).to have_received(:puts).with('done. (7 removed)')
+ # the Fog mock only knows about directories we create explicitly
+ connection = ::Fog::Storage.new(Gitlab.config.backup.upload.connection.symbolize_keys)
+ connection.directories.create(key: Gitlab.config.backup.upload.remote_directory) # rubocop:disable Rails/SaveBang
end
- it 'prints the error from file that could not be removed' do
- expect(progress).to have_received(:puts).with(a_string_matching(message))
+ context 'target path' do
+ it 'uses the tar filename by default' do
+ expect_any_instance_of(Fog::Collection).to receive(:create)
+ .with(hash_including(key: backup_filename, public: false))
+ .and_call_original
+
+ subject.create # rubocop:disable Rails/SaveBang
+ end
+
+ it 'adds the DIRECTORY environment variable if present' do
+ stub_env('DIRECTORY', 'daily')
+
+ expect_any_instance_of(Fog::Collection).to receive(:create)
+ .with(hash_including(key: "daily/#{backup_filename}", public: false))
+ .and_call_original
+
+ subject.create # rubocop:disable Rails/SaveBang
+ end
end
- end
- end
- describe 'verify_backup_version' do
- context 'on version mismatch' do
- let(:gitlab_version) { Gitlab::VERSION }
+ context 'with AWS with server side encryption' do
+ let(:connection) { ::Fog::Storage.new(Gitlab.config.backup.upload.connection.symbolize_keys) }
+ let(:encryption_key) { nil }
+ let(:encryption) { nil }
+ let(:storage_options) { nil }
+
+ before do
+ stub_backup_setting(
+ upload: {
+ connection: {
+ provider: 'AWS',
+ aws_access_key_id: 'AWS_ACCESS_KEY_ID',
+ aws_secret_access_key: 'AWS_SECRET_ACCESS_KEY'
+ },
+ remote_directory: 'directory',
+ multipart_chunk_size: Gitlab.config.backup.upload.multipart_chunk_size,
+ encryption: encryption,
+ encryption_key: encryption_key,
+ storage_options: storage_options,
+ storage_class: nil
+ }
+ )
+
+ connection.directories.create(key: Gitlab.config.backup.upload.remote_directory) # rubocop:disable Rails/SaveBang
+ end
+
+ context 'with SSE-S3 without using storage_options' do
+ let(:encryption) { 'AES256' }
+
+ it 'sets encryption attributes' do
+ subject.create # rubocop:disable Rails/SaveBang
+
+ expect(progress).to have_received(:puts).with("done (encrypted with AES256)")
+ end
+ end
+
+ context 'with SSE-C (customer-provided keys) options' do
+ let(:encryption) { 'AES256' }
+ let(:encryption_key) { SecureRandom.hex }
- it 'stops the process' do
- allow(YAML).to receive(:load_file)
- .and_return({ gitlab_version: "not #{gitlab_version}" })
+ it 'sets encryption attributes' do
+ subject.create # rubocop:disable Rails/SaveBang
- expect { subject.verify_backup_version }.to raise_error SystemExit
+ expect(progress).to have_received(:puts).with("done (encrypted with AES256)")
+ end
+ end
+
+ context 'with SSE-KMS options' do
+ let(:storage_options) do
+ {
+ server_side_encryption: 'aws:kms',
+ server_side_encryption_kms_key_id: 'arn:aws:kms:12345'
+ }
+ end
+
+ it 'sets encryption attributes' do
+ subject.create # rubocop:disable Rails/SaveBang
+
+ expect(progress).to have_received(:puts).with("done (encrypted with aws:kms)")
+ end
+ end
end
- end
- context 'on version match' do
- let(:gitlab_version) { Gitlab::VERSION }
+ context 'with Google provider' do
+ before do
+ stub_backup_setting(
+ upload: {
+ connection: {
+ provider: 'Google',
+ google_storage_access_key_id: 'test-access-id',
+ google_storage_secret_access_key: 'secret'
+ },
+ remote_directory: 'directory',
+ multipart_chunk_size: Gitlab.config.backup.upload.multipart_chunk_size,
+ encryption: nil,
+ encryption_key: nil,
+ storage_class: nil
+ }
+ )
+
+ connection = ::Fog::Storage.new(Gitlab.config.backup.upload.connection.symbolize_keys)
+ connection.directories.create(key: Gitlab.config.backup.upload.remote_directory) # rubocop:disable Rails/SaveBang
+ end
- it 'does nothing' do
- allow(YAML).to receive(:load_file)
- .and_return({ gitlab_version: "#{gitlab_version}" })
+ it 'does not attempt to set ACL' do
+ expect_any_instance_of(Fog::Collection).to receive(:create)
+ .with(hash_excluding(public: false))
+ .and_call_original
- expect { subject.verify_backup_version }.not_to raise_error
+ subject.create # rubocop:disable Rails/SaveBang
+ end
+ end
+
+ context 'with AzureRM provider' do
+ before do
+ stub_backup_setting(
+ upload: {
+ connection: {
+ provider: 'AzureRM',
+ azure_storage_account_name: 'test-access-id',
+ azure_storage_access_key: 'secret'
+ },
+ remote_directory: 'directory',
+ multipart_chunk_size: nil,
+ encryption: nil,
+ encryption_key: nil,
+ storage_class: nil
+ }
+ )
+ end
+
+ it 'loads the provider' do
+ expect { subject.create }.not_to raise_error # rubocop:disable Rails/SaveBang
+ end
end
end
end
- describe '#unpack' do
+ describe '#restore' do
+ let(:task1) { instance_double(Backup::Task, human_name: 'task 1', enabled: true, pre_restore_warning: nil, post_restore_warning: nil) }
+ let(:task2) { instance_double(Backup::Task, human_name: 'task 2', enabled: true, pre_restore_warning: nil, post_restore_warning: nil) }
+ let(:definitions) do
+ {
+ 'task1' => Backup::Manager::TaskDefinition.new(task: task1, destination_path: 'task1.tar.gz'),
+ 'task2' => Backup::Manager::TaskDefinition.new(task: task2, destination_path: 'task2.tar.gz')
+ }
+ end
+
+ let(:gitlab_version) { Gitlab::VERSION }
+ let(:backup_information) do
+ {
+ backup_created_at: Time.zone.parse('2019-01-01'),
+ gitlab_version: gitlab_version
+ }
+ end
+
+ before do
+ Rake.application.rake_require 'tasks/gitlab/shell'
+ Rake.application.rake_require 'tasks/cache'
+
+ allow(task1).to receive(:restore).with(File.join(Gitlab.config.backup.path, 'task1.tar.gz'))
+ allow(task2).to receive(:restore).with(File.join(Gitlab.config.backup.path, 'task2.tar.gz'))
+ allow(YAML).to receive(:load_file).with(File.join(Gitlab.config.backup.path, 'backup_information.yml'))
+ .and_return(backup_information)
+ allow(Rake::Task['gitlab:shell:setup']).to receive(:invoke)
+ allow(Rake::Task['cache:clear']).to receive(:invoke)
+ end
+
context 'when there are no backup files in the directory' do
before do
allow(Dir).to receive(:glob).and_return([])
end
it 'fails the operation and prints an error' do
- expect { subject.unpack }.to raise_error SystemExit
+ expect { subject.restore }.to raise_error SystemExit
expect(progress).to have_received(:puts)
.with(a_string_matching('No backups found'))
end
@@ -307,13 +601,13 @@ RSpec.describe Backup::Manager do
end
it 'prints the list of available backups' do
- expect { subject.unpack }.to raise_error SystemExit
+ expect { subject.restore }.to raise_error SystemExit
expect(progress).to have_received(:puts)
.with(a_string_matching('1451606400_2016_01_01_1.2.3\n 1451520000_2015_12_31'))
end
it 'fails the operation and prints an error' do
- expect { subject.unpack }.to raise_error SystemExit
+ expect { subject.restore }.to raise_error SystemExit
expect(progress).to have_received(:puts)
.with(a_string_matching('Found more than one backup'))
end
@@ -332,7 +626,7 @@ RSpec.describe Backup::Manager do
end
it 'fails the operation and prints an error' do
- expect { subject.unpack }.to raise_error SystemExit
+ expect { subject.restore }.to raise_error SystemExit
expect(File).to have_received(:exist?).with('wrong_gitlab_backup.tar')
expect(progress).to have_received(:puts)
.with(a_string_matching('The backup file wrong_gitlab_backup.tar does not exist'))
@@ -348,17 +642,46 @@ RSpec.describe Backup::Manager do
)
allow(File).to receive(:exist?).and_return(true)
allow(Kernel).to receive(:system).and_return(true)
- allow(YAML).to receive(:load_file).and_return(gitlab_version: Gitlab::VERSION)
stub_env('BACKUP', '/ignored/path/1451606400_2016_01_01_1.2.3')
end
it 'unpacks the file' do
- subject.unpack
+ subject.restore
expect(Kernel).to have_received(:system)
.with("tar", "-xf", "1451606400_2016_01_01_1.2.3_gitlab_backup.tar")
- expect(progress).to have_received(:puts).with(a_string_matching('done'))
+ end
+
+ context 'on version mismatch' do
+ let(:backup_information) do
+ {
+ backup_created_at: Time.zone.parse('2019-01-01'),
+ gitlab_version: "not #{gitlab_version}"
+ }
+ end
+
+ it 'stops the process' do
+ expect { subject.restore }.to raise_error SystemExit
+ expect(progress).to have_received(:puts)
+ .with(a_string_matching('GitLab version mismatch'))
+ end
+ end
+
+ describe 'tmp files' do
+ let(:path) { File.join(Gitlab.config.backup.path, 'tmp') }
+
+ before do
+ allow(FileUtils).to receive(:rm_rf).and_call_original
+ end
+
+ it 'removes backups/tmp dir' do
+ expect(FileUtils).to receive(:rm_rf).with(path).and_call_original
+
+ subject.restore
+
+ expect(progress).to have_received(:print).with('Deleting backups/tmp ... ')
+ end
end
end
@@ -375,184 +698,41 @@ RSpec.describe Backup::Manager do
it 'selects the non-tarred backup to restore from' do
expect(Kernel).not_to receive(:system)
- subject.unpack
+ subject.restore
expect(progress).to have_received(:puts)
.with(a_string_matching('Non tarred backup found '))
end
- end
- end
-
- describe '#upload' do
- let(:backup_file) { Tempfile.new('backup', Gitlab.config.backup.path) }
- let(:backup_filename) { File.basename(backup_file.path) }
-
- before do
- allow(subject).to receive(:tar_file).and_return(backup_filename)
-
- stub_backup_setting(
- upload: {
- connection: {
- provider: 'AWS',
- aws_access_key_id: 'id',
- aws_secret_access_key: 'secret'
- },
- remote_directory: 'directory',
- multipart_chunk_size: 104857600,
- encryption: nil,
- encryption_key: nil,
- storage_class: nil
- }
- )
-
- Fog.mock!
-
- # the Fog mock only knows about directories we create explicitly
- connection = ::Fog::Storage.new(Gitlab.config.backup.upload.connection.symbolize_keys)
- connection.directories.create(key: Gitlab.config.backup.upload.remote_directory) # rubocop:disable Rails/SaveBang
- end
- context 'target path' do
- it 'uses the tar filename by default' do
- expect_any_instance_of(Fog::Collection).to receive(:create)
- .with(hash_including(key: backup_filename, public: false))
- .and_return(true)
-
- subject.upload
- end
-
- it 'adds the DIRECTORY environment variable if present' do
- stub_env('DIRECTORY', 'daily')
-
- expect_any_instance_of(Fog::Collection).to receive(:create)
- .with(hash_including(key: "daily/#{backup_filename}", public: false))
- .and_return(true)
-
- subject.upload
- end
- end
-
- context 'with AWS with server side encryption' do
- let(:connection) { ::Fog::Storage.new(Gitlab.config.backup.upload.connection.symbolize_keys) }
- let(:encryption_key) { nil }
- let(:encryption) { nil }
- let(:storage_options) { nil }
-
- before do
- stub_backup_setting(
- upload: {
- connection: {
- provider: 'AWS',
- aws_access_key_id: 'AWS_ACCESS_KEY_ID',
- aws_secret_access_key: 'AWS_SECRET_ACCESS_KEY'
- },
- remote_directory: 'directory',
- multipart_chunk_size: Gitlab.config.backup.upload.multipart_chunk_size,
- encryption: encryption,
- encryption_key: encryption_key,
- storage_options: storage_options,
- storage_class: nil
- }
- )
-
- connection.directories.create(key: Gitlab.config.backup.upload.remote_directory) # rubocop:disable Rails/SaveBang
- end
-
- context 'with SSE-S3 without using storage_options' do
- let(:encryption) { 'AES256' }
-
- it 'sets encryption attributes' do
- result = subject.upload
-
- expect(result.key).to be_present
- expect(result.encryption).to eq('AES256')
- expect(result.encryption_key).to be_nil
- expect(result.kms_key_id).to be_nil
- end
- end
-
- context 'with SSE-C (customer-provided keys) options' do
- let(:encryption) { 'AES256' }
- let(:encryption_key) { SecureRandom.hex }
-
- it 'sets encryption attributes' do
- result = subject.upload
-
- expect(result.key).to be_present
- expect(result.encryption).to eq(encryption)
- expect(result.encryption_key).to eq(encryption_key)
- expect(result.kms_key_id).to be_nil
- end
- end
-
- context 'with SSE-KMS options' do
- let(:storage_options) do
+ context 'on version mismatch' do
+ let(:backup_information) do
{
- server_side_encryption: 'aws:kms',
- server_side_encryption_kms_key_id: 'arn:aws:kms:12345'
+ backup_created_at: Time.zone.parse('2019-01-01'),
+ gitlab_version: "not #{gitlab_version}"
}
end
- it 'sets encryption attributes' do
- result = subject.upload
-
- expect(result.key).to be_present
- expect(result.encryption).to eq('aws:kms')
- expect(result.kms_key_id).to eq('arn:aws:kms:12345')
+ it 'stops the process' do
+ expect { subject.restore }.to raise_error SystemExit
+ expect(progress).to have_received(:puts)
+ .with(a_string_matching('GitLab version mismatch'))
end
end
- end
- context 'with Google provider' do
- before do
- stub_backup_setting(
- upload: {
- connection: {
- provider: 'Google',
- google_storage_access_key_id: 'test-access-id',
- google_storage_secret_access_key: 'secret'
- },
- remote_directory: 'directory',
- multipart_chunk_size: Gitlab.config.backup.upload.multipart_chunk_size,
- encryption: nil,
- encryption_key: nil,
- storage_class: nil
- }
- )
-
- connection = ::Fog::Storage.new(Gitlab.config.backup.upload.connection.symbolize_keys)
- connection.directories.create(key: Gitlab.config.backup.upload.remote_directory) # rubocop:disable Rails/SaveBang
- end
+ describe 'tmp files' do
+ let(:path) { File.join(Gitlab.config.backup.path, 'tmp') }
- it 'does not attempt to set ACL' do
- expect_any_instance_of(Fog::Collection).to receive(:create)
- .with(hash_excluding(public: false))
- .and_return(true)
+ before do
+ allow(FileUtils).to receive(:rm_rf).and_call_original
+ end
- subject.upload
- end
- end
+ it 'removes backups/tmp dir' do
+ expect(FileUtils).to receive(:rm_rf).with(path).and_call_original
- context 'with AzureRM provider' do
- before do
- stub_backup_setting(
- upload: {
- connection: {
- provider: 'AzureRM',
- azure_storage_account_name: 'test-access-id',
- azure_storage_access_key: 'secret'
- },
- remote_directory: 'directory',
- multipart_chunk_size: nil,
- encryption: nil,
- encryption_key: nil,
- storage_class: nil
- }
- )
- end
+ subject.restore
- it 'loads the provider' do
- expect { subject.upload }.not_to raise_error
+ expect(progress).to have_received(:print).with('Deleting backups/tmp ... ')
+ end
end
end
end
diff --git a/spec/lib/backup/object_backup_spec.rb b/spec/lib/backup/object_backup_spec.rb
index 4d34dc0ade7..85658173b0e 100644
--- a/spec/lib/backup/object_backup_spec.rb
+++ b/spec/lib/backup/object_backup_spec.rb
@@ -21,7 +21,7 @@ RSpec.shared_examples 'backup object' do |setting|
expect(backup).to receive(:run_pipeline!).with([%W(blabla-tar --exclude=lost+found --exclude=./tmp -C #{backup_path} -cf - .), 'gzip -c -1'], any_args).and_return([[true, true], ''])
expect(backup).to receive(:pipeline_succeeded?).and_return(true)
- backup.dump
+ backup.dump('backup_object.tar.gz')
end
end
end
diff --git a/spec/lib/backup/pages_spec.rb b/spec/lib/backup/pages_spec.rb
index f9ee4bbdc41..095dda61cf4 100644
--- a/spec/lib/backup/pages_spec.rb
+++ b/spec/lib/backup/pages_spec.rb
@@ -19,7 +19,7 @@ RSpec.describe Backup::Pages do
expect(subject).to receive(:tar).and_return('blabla-tar')
expect(subject).to receive(:run_pipeline!).with([%w(blabla-tar --exclude=lost+found --exclude=./@pages.tmp -C /var/gitlab-pages -cf - .), 'gzip -c -1'], any_args).and_return([[true, true], ''])
expect(subject).to receive(:pipeline_succeeded?).and_return(true)
- subject.dump
+ subject.dump('pages.tar.gz')
end
end
end
diff --git a/spec/lib/backup/repositories_spec.rb b/spec/lib/backup/repositories_spec.rb
index 0b29a25360d..db3e507596f 100644
--- a/spec/lib/backup/repositories_spec.rb
+++ b/spec/lib/backup/repositories_spec.rb
@@ -8,6 +8,7 @@ RSpec.describe Backup::Repositories do
let(:strategy) { spy(:strategy, parallel_enqueue?: parallel_enqueue) }
let(:max_concurrency) { 1 }
let(:max_storage_concurrency) { 1 }
+ let(:destination) { 'repositories' }
subject do
described_class.new(
@@ -26,9 +27,9 @@ RSpec.describe Backup::Repositories do
project_snippet = create(:project_snippet, :repository, project: project)
personal_snippet = create(:personal_snippet, :repository, author: project.first_owner)
- subject.dump
+ subject.dump(destination)
- expect(strategy).to have_received(:start).with(:create)
+ expect(strategy).to have_received(:start).with(:create, destination)
expect(strategy).to have_received(:enqueue).with(project, Gitlab::GlRepository::PROJECT)
expect(strategy).to have_received(:enqueue).with(project, Gitlab::GlRepository::WIKI)
expect(strategy).to have_received(:enqueue).with(project, Gitlab::GlRepository::DESIGN)
@@ -54,38 +55,38 @@ RSpec.describe Backup::Repositories do
it 'creates the expected number of threads' do
expect(Thread).not_to receive(:new)
- expect(strategy).to receive(:start).with(:create)
+ expect(strategy).to receive(:start).with(:create, destination)
projects.each do |project|
expect(strategy).to receive(:enqueue).with(project, Gitlab::GlRepository::PROJECT)
end
expect(strategy).to receive(:finish!)
- subject.dump
+ subject.dump(destination)
end
describe 'command failure' do
it 'enqueue_project raises an error' do
allow(strategy).to receive(:enqueue).with(anything, Gitlab::GlRepository::PROJECT).and_raise(IOError)
- expect { subject.dump }.to raise_error(IOError)
+ expect { subject.dump(destination) }.to raise_error(IOError)
end
it 'project query raises an error' do
allow(Project).to receive_message_chain(:includes, :find_each).and_raise(ActiveRecord::StatementTimeout)
- expect { subject.dump }.to raise_error(ActiveRecord::StatementTimeout)
+ expect { subject.dump(destination) }.to raise_error(ActiveRecord::StatementTimeout)
end
end
it 'avoids N+1 database queries' do
control_count = ActiveRecord::QueryRecorder.new do
- subject.dump
+ subject.dump(destination)
end.count
create_list(:project, 2, :repository)
expect do
- subject.dump
+ subject.dump(destination)
end.not_to exceed_query_limit(control_count)
end
end
@@ -98,13 +99,13 @@ RSpec.describe Backup::Repositories do
it 'enqueues all projects sequentially' do
expect(Thread).not_to receive(:new)
- expect(strategy).to receive(:start).with(:create)
+ expect(strategy).to receive(:start).with(:create, destination)
projects.each do |project|
expect(strategy).to receive(:enqueue).with(project, Gitlab::GlRepository::PROJECT)
end
expect(strategy).to receive(:finish!)
- subject.dump
+ subject.dump(destination)
end
end
@@ -122,13 +123,13 @@ RSpec.describe Backup::Repositories do
.exactly(storage_keys.length * (max_storage_concurrency + 1)).times
.and_call_original
- expect(strategy).to receive(:start).with(:create)
+ expect(strategy).to receive(:start).with(:create, destination)
projects.each do |project|
expect(strategy).to receive(:enqueue).with(project, Gitlab::GlRepository::PROJECT)
end
expect(strategy).to receive(:finish!)
- subject.dump
+ subject.dump(destination)
end
context 'with extra max concurrency' do
@@ -139,13 +140,13 @@ RSpec.describe Backup::Repositories do
.exactly(storage_keys.length * (max_storage_concurrency + 1)).times
.and_call_original
- expect(strategy).to receive(:start).with(:create)
+ expect(strategy).to receive(:start).with(:create, destination)
projects.each do |project|
expect(strategy).to receive(:enqueue).with(project, Gitlab::GlRepository::PROJECT)
end
expect(strategy).to receive(:finish!)
- subject.dump
+ subject.dump(destination)
end
end
@@ -153,33 +154,33 @@ RSpec.describe Backup::Repositories do
it 'enqueue_project raises an error' do
allow(strategy).to receive(:enqueue).and_raise(IOError)
- expect { subject.dump }.to raise_error(IOError)
+ expect { subject.dump(destination) }.to raise_error(IOError)
end
it 'project query raises an error' do
allow(Project).to receive_message_chain(:for_repository_storage, :includes, :find_each).and_raise(ActiveRecord::StatementTimeout)
- expect { subject.dump }.to raise_error(ActiveRecord::StatementTimeout)
+ expect { subject.dump(destination) }.to raise_error(ActiveRecord::StatementTimeout)
end
context 'misconfigured storages' do
let(:storage_keys) { %w[test_second_storage] }
it 'raises an error' do
- expect { subject.dump }.to raise_error(Backup::Error, 'repositories.storages in gitlab.yml is misconfigured')
+ expect { subject.dump(destination) }.to raise_error(Backup::Error, 'repositories.storages in gitlab.yml is misconfigured')
end
end
end
it 'avoids N+1 database queries' do
control_count = ActiveRecord::QueryRecorder.new do
- subject.dump
+ subject.dump(destination)
end.count
create_list(:project, 2, :repository)
expect do
- subject.dump
+ subject.dump(destination)
end.not_to exceed_query_limit(control_count)
end
end
@@ -192,9 +193,9 @@ RSpec.describe Backup::Repositories do
let_it_be(:project_snippet) { create(:project_snippet, project: project, author: project.first_owner) }
it 'calls enqueue for each repository type', :aggregate_failures do
- subject.restore
+ subject.restore(destination)
- expect(strategy).to have_received(:start).with(:restore)
+ expect(strategy).to have_received(:start).with(:restore, destination)
expect(strategy).to have_received(:enqueue).with(project, Gitlab::GlRepository::PROJECT)
expect(strategy).to have_received(:enqueue).with(project, Gitlab::GlRepository::WIKI)
expect(strategy).to have_received(:enqueue).with(project, Gitlab::GlRepository::DESIGN)
@@ -208,7 +209,7 @@ RSpec.describe Backup::Repositories do
pool_repository = create(:pool_repository, :failed)
pool_repository.delete_object_pool
- subject.restore
+ subject.restore(destination)
pool_repository.reload
expect(pool_repository).not_to be_failed
@@ -219,7 +220,7 @@ RSpec.describe Backup::Repositories do
pool_repository = create(:pool_repository, state: :obsolete)
pool_repository.update_column(:source_project_id, nil)
- subject.restore
+ subject.restore(destination)
pool_repository.reload
expect(pool_repository).to be_obsolete
@@ -236,14 +237,14 @@ RSpec.describe Backup::Repositories do
end
it 'shows the appropriate error' do
- subject.restore
+ subject.restore(destination)
expect(progress).to have_received(:puts).with("Snippet #{personal_snippet.full_path} can't be restored: Repository has more than one branch")
expect(progress).to have_received(:puts).with("Snippet #{project_snippet.full_path} can't be restored: Repository has more than one branch")
end
it 'removes the snippets from the DB' do
- expect { subject.restore }.to change(PersonalSnippet, :count).by(-1)
+ expect { subject.restore(destination) }.to change(PersonalSnippet, :count).by(-1)
.and change(ProjectSnippet, :count).by(-1)
.and change(SnippetRepository, :count).by(-2)
end
@@ -253,7 +254,7 @@ RSpec.describe Backup::Repositories do
shard_name = personal_snippet.repository.shard
path = personal_snippet.disk_path + '.git'
- subject.restore
+ subject.restore(destination)
expect(gitlab_shell.repository_exists?(shard_name, path)).to eq false
end
diff --git a/spec/lib/backup/task_spec.rb b/spec/lib/backup/task_spec.rb
new file mode 100644
index 00000000000..b0eb885d3f4
--- /dev/null
+++ b/spec/lib/backup/task_spec.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Backup::Task do
+ let(:progress) { StringIO.new }
+
+ subject { described_class.new(progress) }
+
+ describe '#human_name' do
+ it 'must be implemented by the subclass' do
+ expect { subject.human_name }.to raise_error(NotImplementedError)
+ end
+ end
+
+ describe '#dump' do
+ it 'must be implemented by the subclass' do
+ expect { subject.dump('some/path') }.to raise_error(NotImplementedError)
+ end
+ end
+
+ describe '#restore' do
+ it 'must be implemented by the subclass' do
+ expect { subject.restore('some/path') }.to raise_error(NotImplementedError)
+ end
+ end
+end
diff --git a/spec/lib/backup/uploads_spec.rb b/spec/lib/backup/uploads_spec.rb
index 25ad0c0d3f7..0cfc80a9cb9 100644
--- a/spec/lib/backup/uploads_spec.rb
+++ b/spec/lib/backup/uploads_spec.rb
@@ -19,7 +19,7 @@ RSpec.describe Backup::Uploads do
expect(backup).to receive(:tar).and_return('blabla-tar')
expect(backup).to receive(:run_pipeline!).with([%w(blabla-tar --exclude=lost+found --exclude=./tmp -C /var/uploads -cf - .), 'gzip -c -1'], any_args).and_return([[true, true], ''])
expect(backup).to receive(:pipeline_succeeded?).and_return(true)
- backup.dump
+ backup.dump('uploads.tar.gz')
end
end
end
diff --git a/spec/lib/banzai/filter/front_matter_filter_spec.rb b/spec/lib/banzai/filter/front_matter_filter_spec.rb
index 1562c388296..f3543ab9582 100644
--- a/spec/lib/banzai/filter/front_matter_filter_spec.rb
+++ b/spec/lib/banzai/filter/front_matter_filter_spec.rb
@@ -105,6 +105,56 @@ RSpec.describe Banzai::Filter::FrontMatterFilter do
end
end
+ context 'source position mapping' do
+ it 'keeps spaces before and after' do
+ content = <<~MD
+
+
+ ---
+
+ foo: :foo_symbol
+
+ ---
+
+
+ # Header
+ MD
+
+ output = filter(content)
+
+ expect(output).to eq <<~MD
+
+
+ ```yaml:frontmatter
+
+ foo: :foo_symbol
+
+ ```
+
+
+ # Header
+ MD
+ end
+
+ it 'keeps an empty line in place of the encoding' do
+ content = <<~MD
+ # encoding: UTF-8
+ ---
+ foo: :foo_symbol
+ ---
+ MD
+
+ output = filter(content)
+
+ expect(output).to eq <<~MD
+
+ ```yaml:frontmatter
+ foo: :foo_symbol
+ ```
+ MD
+ end
+ end
+
context 'on content without front matter' do
it 'returns the content unmodified' do
content = <<~MD
@@ -119,7 +169,7 @@ RSpec.describe Banzai::Filter::FrontMatterFilter do
context 'on front matter without content' do
it 'converts YAML front matter to a fenced code block' do
- content = <<~MD
+ content = <<~MD.rstrip
---
foo: :foo_symbol
bar: :bar_symbol
@@ -134,7 +184,6 @@ RSpec.describe Banzai::Filter::FrontMatterFilter do
foo: :foo_symbol
bar: :bar_symbol
```
-
MD
end
end
diff --git a/spec/lib/banzai/filter/image_link_filter_spec.rb b/spec/lib/banzai/filter/image_link_filter_spec.rb
index 5c04f6b2b3e..238c3cdb9c1 100644
--- a/spec/lib/banzai/filter/image_link_filter_spec.rb
+++ b/spec/lib/banzai/filter/image_link_filter_spec.rb
@@ -5,34 +5,82 @@ require 'spec_helper'
RSpec.describe Banzai::Filter::ImageLinkFilter do
include FilterSpecHelper
- def image(path)
- %(<img src="#{path}" />)
+ let(:path) { '/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg' }
+ let(:context) { {} }
+
+ def image(path, alt: nil, data_src: nil)
+ alt_tag = alt ? %Q{alt="#{alt}"} : ""
+ data_src_tag = data_src ? %Q{data-src="#{data_src}"} : ""
+
+ %(<img src="#{path}" #{alt_tag} #{data_src_tag} />)
end
it 'wraps the image with a link to the image src' do
- doc = filter(image('/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg'))
+ doc = filter(image(path), context)
+
expect(doc.at_css('img')['src']).to eq doc.at_css('a')['href']
end
it 'does not wrap a duplicate link' do
- doc = filter(%Q(<a href="/whatever">#{image('/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg')}</a>))
+ doc = filter(%Q(<a href="/whatever">#{image(path)}</a>), context)
+
expect(doc.to_html).to match %r{^<a href="/whatever"><img[^>]*></a>$}
end
it 'works with external images' do
- doc = filter(image('https://i.imgur.com/DfssX9C.jpg'))
+ doc = filter(image('https://i.imgur.com/DfssX9C.jpg'), context)
+
expect(doc.at_css('img')['src']).to eq doc.at_css('a')['href']
end
it 'works with inline images' do
- doc = filter(%Q(<p>test #{image('/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg')} inline</p>))
+ doc = filter(%Q(<p>test #{image(path)} inline</p>), context)
+
expect(doc.to_html).to match %r{^<p>test <a[^>]*><img[^>]*></a> inline</p>$}
end
it 'keep the data-canonical-src' do
- doc = filter(%q(<img src="http://assets.example.com/6cd/4d7" data-canonical-src="http://example.com/test.png" />))
+ doc = filter(%q(<img src="http://assets.example.com/6cd/4d7" data-canonical-src="http://example.com/test.png" />), context)
expect(doc.at_css('img')['src']).to eq doc.at_css('a')['href']
expect(doc.at_css('img')['data-canonical-src']).to eq doc.at_css('a')['data-canonical-src']
end
+
+ it 'adds no-attachment icon class to the link' do
+ doc = filter(image(path), context)
+
+ expect(doc.at_css('a')['class']).to match(%r{no-attachment-icon})
+ end
+
+ context 'when :link_replaces_image is true' do
+ let(:context) { { link_replaces_image: true } }
+
+ it 'replaces the image with link to image src', :aggregate_failures do
+ doc = filter(image(path), context)
+
+ expect(doc.to_html).to match(%r{^<a[^>]*>#{path}</a>$})
+ expect(doc.at_css('a')['href']).to eq(path)
+ end
+
+ it 'uses image alt as a link text', :aggregate_failures do
+ doc = filter(image(path, alt: 'My image'), context)
+
+ expect(doc.to_html).to match(%r{^<a[^>]*>My image</a>$})
+ expect(doc.at_css('a')['href']).to eq(path)
+ end
+
+ it 'uses image data-src as a link text', :aggregate_failures do
+ data_src = '/uploads/data-src.png'
+ doc = filter(image(path, data_src: data_src), context)
+
+ expect(doc.to_html).to match(%r{^<a[^>]*>#{data_src}</a>$})
+ expect(doc.at_css('a')['href']).to eq(data_src)
+ end
+
+ it 'adds attachment icon class to the link' do
+ doc = filter(image(path), context)
+
+ expect(doc.at_css('a')['class']).to match(%r{with-attachment-icon})
+ end
+ end
end
diff --git a/spec/lib/banzai/filter/issuable_reference_expansion_filter_spec.rb b/spec/lib/banzai/filter/issuable_reference_expansion_filter_spec.rb
index 0840ccf19e4..ef23725c790 100644
--- a/spec/lib/banzai/filter/issuable_reference_expansion_filter_spec.rb
+++ b/spec/lib/banzai/filter/issuable_reference_expansion_filter_spec.rb
@@ -33,7 +33,7 @@ RSpec.describe Banzai::Filter::IssuableReferenceExpansionFilter do
end
it 'ignores non-issuable links' do
- link = create_link('text', project: project, reference_type: 'issue')
+ link = create_link('text', project: project.id, reference_type: 'issue')
doc = filter(link, context)
expect(doc.css('a').last.text).to eq('text')
diff --git a/spec/lib/banzai/filter/reference_redactor_filter_spec.rb b/spec/lib/banzai/filter/reference_redactor_filter_spec.rb
index d0336e9e059..a2f34d42814 100644
--- a/spec/lib/banzai/filter/reference_redactor_filter_spec.rb
+++ b/spec/lib/banzai/filter/reference_redactor_filter_spec.rb
@@ -3,7 +3,6 @@
require 'spec_helper'
RSpec.describe Banzai::Filter::ReferenceRedactorFilter do
- include ActionView::Helpers::UrlHelper
include FilterSpecHelper
it 'ignores non-GFM links' do
@@ -14,7 +13,7 @@ RSpec.describe Banzai::Filter::ReferenceRedactorFilter do
end
def reference_link(data)
- link_to('text', '', class: 'gfm', data: data)
+ ActionController::Base.helpers.link_to('text', '', class: 'gfm', data: data)
end
it 'skips when the skip_redaction flag is set' do
diff --git a/spec/lib/banzai/filter/references/external_issue_reference_filter_spec.rb b/spec/lib/banzai/filter/references/external_issue_reference_filter_spec.rb
index d7bcebbbe34..2e811d35662 100644
--- a/spec/lib/banzai/filter/references/external_issue_reference_filter_spec.rb
+++ b/spec/lib/banzai/filter/references/external_issue_reference_filter_spec.rb
@@ -256,4 +256,23 @@ RSpec.describe Banzai::Filter::References::ExternalIssueReferenceFilter do
it_behaves_like "external issue tracker"
end
end
+
+ context 'checking N+1' do
+ let_it_be(:integration) { create(:redmine_integration, project: project) }
+ let_it_be(:issue1) { ExternalIssue.new("#123", project) }
+ let_it_be(:issue2) { ExternalIssue.new("YT-123", project) }
+
+ before do
+ project.update!(issues_enabled: false)
+ end
+
+ it 'does not have N+1 per multiple references per project', :use_sql_query_cache do
+ single_reference = "External Issue #{issue1.to_reference}"
+ multiple_references = "External Issues #{issue1.to_reference} and #{issue2.to_reference}"
+
+ control_count = ActiveRecord::QueryRecorder.new { reference_filter(single_reference).to_html }.count
+
+ expect { reference_filter(multiple_references).to_html }.not_to exceed_query_limit(control_count)
+ end
+ end
end
diff --git a/spec/lib/banzai/filter/references/label_reference_filter_spec.rb b/spec/lib/banzai/filter/references/label_reference_filter_spec.rb
index b18d68c8dd4..c342a831d62 100644
--- a/spec/lib/banzai/filter/references/label_reference_filter_spec.rb
+++ b/spec/lib/banzai/filter/references/label_reference_filter_spec.rb
@@ -277,7 +277,7 @@ RSpec.describe Banzai::Filter::References::LabelReferenceFilter do
end
context 'References with html entities' do
- let!(:label) { create(:label, name: '&lt;html&gt;', project: project) }
+ let!(:label) { create(:label, title: '&lt;html&gt;', project: project) }
it 'links to a valid reference' do
doc = reference_filter('See ~"&lt;html&gt;"')
diff --git a/spec/lib/banzai/filter/task_list_filter_spec.rb b/spec/lib/banzai/filter/task_list_filter_spec.rb
new file mode 100644
index 00000000000..c89acd1a643
--- /dev/null
+++ b/spec/lib/banzai/filter/task_list_filter_spec.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Banzai::Filter::TaskListFilter do
+ include FilterSpecHelper
+
+ it 'adds `<task-button></task-button>` to every list item' do
+ doc = filter("<ul data-sourcepos=\"1:1-2:20\">\n<li data-sourcepos=\"1:1-1:20\">[ ] testing item 1</li>\n<li data-sourcepos=\"2:1-2:20\">[x] testing item 2</li>\n</ul>")
+
+ expect(doc.xpath('.//li//task-button').count).to eq(2)
+ end
+end
diff --git a/spec/lib/banzai/reference_redactor_spec.rb b/spec/lib/banzai/reference_redactor_spec.rb
index 78cceedd0e5..45e14032a98 100644
--- a/spec/lib/banzai/reference_redactor_spec.rb
+++ b/spec/lib/banzai/reference_redactor_spec.rb
@@ -106,13 +106,12 @@ RSpec.describe Banzai::ReferenceRedactor do
end
context 'when the user cannot read cross project' do
- include ActionView::Helpers::UrlHelper
let(:project) { create(:project) }
let(:other_project) { create(:project, :public) }
def create_link(issuable)
type = issuable.class.name.underscore.downcase
- link_to(issuable.to_reference, '',
+ ActionController::Base.helpers.link_to(issuable.to_reference, '',
class: 'gfm has-tooltip',
title: issuable.title,
data: {
diff --git a/spec/lib/bulk_imports/clients/http_spec.rb b/spec/lib/bulk_imports/clients/http_spec.rb
index 1bbc96af8ee..c9730e03311 100644
--- a/spec/lib/bulk_imports/clients/http_spec.rb
+++ b/spec/lib/bulk_imports/clients/http_spec.rb
@@ -38,11 +38,11 @@ RSpec.describe BulkImports::Clients::HTTP do
context 'when response is not success' do
it 'raises BulkImports::Error' do
- response_double = double(code: 503, success?: false, request: double(path: double(path: '/test')))
+ response_double = double(code: 503, success?: false, parsed_response: 'Error', request: double(path: double(path: '/test')))
allow(Gitlab::HTTP).to receive(method).and_return(response_double)
- expect { subject.public_send(method, resource) }.to raise_exception(BulkImports::NetworkError, 'Unsuccessful response 503 from /test')
+ expect { subject.public_send(method, resource) }.to raise_exception(BulkImports::NetworkError, 'Unsuccessful response 503 from /test. Body: Error')
end
end
end
diff --git a/spec/lib/bulk_imports/common/pipelines/labels_pipeline_spec.rb b/spec/lib/bulk_imports/common/pipelines/labels_pipeline_spec.rb
index 48db24def48..ac516418ce8 100644
--- a/spec/lib/bulk_imports/common/pipelines/labels_pipeline_spec.rb
+++ b/spec/lib/bulk_imports/common/pipelines/labels_pipeline_spec.rb
@@ -43,7 +43,7 @@ RSpec.describe BulkImports::Common::Pipelines::LabelsPipeline do
expect(label.title).to eq('Label 1')
expect(label.description).to eq('Label 1')
- expect(label.color).to eq('#6699cc')
+ expect(label.color).to be_color('#6699cc')
expect(File.directory?(tmpdir)).to eq(false)
end
end
diff --git a/spec/lib/container_registry/client_spec.rb b/spec/lib/container_registry/client_spec.rb
index 974c3478ddc..39a594eba5c 100644
--- a/spec/lib/container_registry/client_spec.rb
+++ b/spec/lib/container_registry/client_spec.rb
@@ -168,24 +168,100 @@ RSpec.describe ContainerRegistry::Client do
expect(subject).to eq('Blob')
end
- it 'follows 307 redirect for GET /v2/:name/blobs/:digest' do
- stub_request(method, url)
- .with(headers: blob_headers)
- .to_return(status: 307, body: '', headers: { Location: 'http://redirected' })
- # We should probably use hash_excluding here, but that requires an update to WebMock:
- # https://github.com/bblimke/webmock/blob/master/lib/webmock/matchers/hash_excluding_matcher.rb
- stub_request(:get, "http://redirected/")
- .with(headers: redirect_header) do |request|
- !request.headers.include?('Authorization')
+ context 'with a 307 redirect' do
+ let(:redirect_location) { 'http://redirected' }
+
+ before do
+ stub_request(method, url)
+ .with(headers: blob_headers)
+ .to_return(status: 307, body: '', headers: { Location: redirect_location })
+
+ # We should probably use hash_excluding here, but that requires an update to WebMock:
+ # https://github.com/bblimke/webmock/blob/master/lib/webmock/matchers/hash_excluding_matcher.rb
+ stub_request(:get, redirect_location)
+ .with(headers: redirect_header) do |request|
+ !request.headers.include?('Authorization')
+ end
+ .to_return(status: 200, body: "Successfully redirected")
+ end
+
+ shared_examples 'handling redirects' do
+ it 'follows the redirect' do
+ expect(Faraday::Utils).not_to receive(:escape).with('signature=')
+ expect_new_faraday
+ expect(subject).to eq('Successfully redirected')
+ end
+ end
+
+ it_behaves_like 'handling redirects'
+
+ context 'with a redirect location with params ending with =' do
+ let(:redirect_location) { 'http://redirect?foo=bar&test=signature=' }
+
+ it_behaves_like 'handling redirects'
+
+ context 'with container_registry_follow_redirects_middleware disabled' do
+ before do
+ stub_feature_flags(container_registry_follow_redirects_middleware: false)
+ end
+
+ it 'follows the redirect' do
+ expect(Faraday::Utils).to receive(:escape).with('foo').and_call_original
+ expect(Faraday::Utils).to receive(:escape).with('bar').and_call_original
+ expect(Faraday::Utils).to receive(:escape).with('test').and_call_original
+ expect(Faraday::Utils).to receive(:escape).with('signature=').and_call_original
+
+ expect_new_faraday(times: 2)
+ expect(subject).to eq('Successfully redirected')
+ end
end
- .to_return(status: 200, body: "Successfully redirected")
+ end
- expect_new_faraday(times: 2)
+ context 'with a redirect location with params ending with %3D' do
+ let(:redirect_location) { 'http://redirect?foo=bar&test=signature%3D' }
- expect(subject).to eq('Successfully redirected')
+ it_behaves_like 'handling redirects'
+
+ context 'with container_registry_follow_redirects_middleware disabled' do
+ before do
+ stub_feature_flags(container_registry_follow_redirects_middleware: false)
+ end
+
+ it 'follows the redirect' do
+ expect(Faraday::Utils).to receive(:escape).with('foo').and_call_original
+ expect(Faraday::Utils).to receive(:escape).with('bar').and_call_original
+ expect(Faraday::Utils).to receive(:escape).with('test').and_call_original
+ expect(Faraday::Utils).to receive(:escape).with('signature=').and_call_original
+
+ expect_new_faraday(times: 2)
+ expect(subject).to eq('Successfully redirected')
+ end
+ end
+ end
end
it_behaves_like 'handling timeouts'
+
+ # TODO Remove this context along with the
+ # container_registry_follow_redirects_middleware feature flag
+ # See https://gitlab.com/gitlab-org/gitlab/-/issues/353291
+ context 'faraday blob' do
+ subject { client.send(:faraday_blob) }
+
+ it 'has a follow redirects middleware' do
+ expect(subject.builder.handlers).to include(::FaradayMiddleware::FollowRedirects)
+ end
+
+ context 'with container_registry_follow_redirects_middleware is disabled' do
+ before do
+ stub_feature_flags(container_registry_follow_redirects_middleware: false)
+ end
+
+ it 'has not a follow redirects middleware' do
+ expect(subject.builder.handlers).not_to include(::FaradayMiddleware::FollowRedirects)
+ end
+ end
+ end
end
describe '#upload_blob' do
diff --git a/spec/lib/container_registry/gitlab_api_client_spec.rb b/spec/lib/container_registry/gitlab_api_client_spec.rb
index 292582a8d83..4fe229024e5 100644
--- a/spec/lib/container_registry/gitlab_api_client_spec.rb
+++ b/spec/lib/container_registry/gitlab_api_client_spec.rb
@@ -6,8 +6,11 @@ RSpec.describe ContainerRegistry::GitlabApiClient do
using RSpec::Parameterized::TableSyntax
include_context 'container registry client'
+ include_context 'container registry client stubs'
let(:path) { 'namespace/path/to/repository' }
+ let(:import_token) { 'import_token' }
+ let(:options) { { token: token, import_token: import_token } }
describe '#supports_gitlab_api?' do
subject { client.supports_gitlab_api? }
@@ -121,6 +124,40 @@ RSpec.describe ContainerRegistry::GitlabApiClient do
end
end
+ describe '#repository_details' do
+ let(:path) { 'namespace/path/to/repository' }
+ let(:response) { { foo: :bar, this: :is_a_test } }
+ let(:with_size) { true }
+
+ subject { client.repository_details(path, with_size: with_size) }
+
+ context 'with size' do
+ before do
+ stub_repository_details(path, with_size: with_size, respond_with: response)
+ end
+
+ it { is_expected.to eq(response.stringify_keys.deep_transform_values(&:to_s)) }
+ end
+
+ context 'without_size' do
+ let(:with_size) { false }
+
+ before do
+ stub_repository_details(path, with_size: with_size, respond_with: response)
+ end
+
+ it { is_expected.to eq(response.stringify_keys.deep_transform_values(&:to_s)) }
+ end
+
+ context 'with non successful response' do
+ before do
+ stub_repository_details(path, with_size: with_size, status_code: 404)
+ end
+
+ it { is_expected.to eq({}) }
+ end
+ end
+
describe '.supports_gitlab_api?' do
subject { described_class.supports_gitlab_api? }
@@ -180,8 +217,9 @@ RSpec.describe ContainerRegistry::GitlabApiClient do
end
def stub_pre_import(path, status_code, pre:)
- stub_request(:put, "#{registry_api_url}/gitlab/v1/import/#{path}/?pre=#{pre}")
- .with(headers: { 'Accept' => described_class::JSON_TYPE })
+ import_type = pre ? 'pre' : 'final'
+ stub_request(:put, "#{registry_api_url}/gitlab/v1/import/#{path}/?import_type=#{import_type}")
+ .with(headers: { 'Accept' => described_class::JSON_TYPE, 'Authorization' => "bearer #{import_token}" })
.to_return(status: status_code, body: '')
end
@@ -194,11 +232,19 @@ RSpec.describe ContainerRegistry::GitlabApiClient do
def stub_import_status(path, status)
stub_request(:get, "#{registry_api_url}/gitlab/v1/import/#{path}/")
- .with(headers: { 'Accept' => described_class::JSON_TYPE })
+ .with(headers: { 'Accept' => described_class::JSON_TYPE, 'Authorization' => "bearer #{import_token}" })
.to_return(
status: 200,
body: { status: status }.to_json,
headers: { content_type: 'application/json' }
)
end
+
+ def stub_repository_details(path, with_size: true, status_code: 200, respond_with: {})
+ url = "#{registry_api_url}/gitlab/v1/repositories/#{path}/"
+ url += "?size=self" if with_size
+ stub_request(:get, url)
+ .with(headers: { 'Accept' => described_class::JSON_TYPE, 'Authorization' => "bearer #{token}" })
+ .to_return(status: status_code, body: respond_with.to_json, headers: { 'Content-Type' => described_class::JSON_TYPE })
+ end
end
diff --git a/spec/lib/container_registry/registry_spec.rb b/spec/lib/container_registry/registry_spec.rb
index c690d96b4f5..86231df5fdb 100644
--- a/spec/lib/container_registry/registry_spec.rb
+++ b/spec/lib/container_registry/registry_spec.rb
@@ -4,10 +4,15 @@ require 'spec_helper'
RSpec.describe ContainerRegistry::Registry do
let(:path) { nil }
- let(:registry) { described_class.new('http://example.com', path: path) }
+ let(:registry_api_url) { 'http://example.com' }
+ let(:registry) { described_class.new(registry_api_url, path: path) }
subject { registry }
+ before do
+ stub_container_registry_config(enabled: true, api_url: registry_api_url, key: 'spec/fixtures/x509_certificate_pk.key')
+ end
+
it { is_expected.to respond_to(:client) }
it { is_expected.to respond_to(:uri) }
it { is_expected.to respond_to(:path) }
diff --git a/spec/lib/feature_spec.rb b/spec/lib/feature_spec.rb
index 5080d21d564..90c0684f8b7 100644
--- a/spec/lib/feature_spec.rb
+++ b/spec/lib/feature_spec.rb
@@ -257,7 +257,7 @@ RSpec.describe Feature, stub_feature_flags: false do
end
it 'caches the status in L2 cache after 2 minutes' do
- Timecop.travel 2.minutes do
+ travel_to 2.minutes.from_now do
expect do
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
@@ -267,7 +267,7 @@ RSpec.describe Feature, stub_feature_flags: false do
end
it 'fetches the status after an hour' do
- Timecop.travel 61.minutes do
+ travel_to 61.minutes.from_now do
expect do
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
diff --git a/spec/lib/gitlab/analytics/cycle_analytics/median_spec.rb b/spec/lib/gitlab/analytics/cycle_analytics/median_spec.rb
index 14768025932..b4aa843bcd7 100644
--- a/spec/lib/gitlab/analytics/cycle_analytics/median_spec.rb
+++ b/spec/lib/gitlab/analytics/cycle_analytics/median_spec.rb
@@ -30,11 +30,11 @@ RSpec.describe Gitlab::Analytics::CycleAnalytics::Median do
merge_request1 = create(:merge_request, source_branch: '1', target_project: project, source_project: project)
merge_request2 = create(:merge_request, source_branch: '2', target_project: project, source_project: project)
- Timecop.travel(5.minutes.from_now) do
+ travel_to(5.minutes.from_now) do
merge_request1.metrics.update!(merged_at: Time.zone.now)
end
- Timecop.travel(10.minutes.from_now) do
+ travel_to(10.minutes.from_now) do
merge_request2.metrics.update!(merged_at: Time.zone.now)
end
diff --git a/spec/lib/gitlab/auth/ldap/access_spec.rb b/spec/lib/gitlab/auth/ldap/access_spec.rb
index 9e269f84b7e..1fcdd678746 100644
--- a/spec/lib/gitlab/auth/ldap/access_spec.rb
+++ b/spec/lib/gitlab/auth/ldap/access_spec.rb
@@ -5,7 +5,7 @@ require 'spec_helper'
RSpec.describe Gitlab::Auth::Ldap::Access do
include LdapHelpers
- let(:user) { create(:omniauth_user) }
+ let(:user) { create(:omniauth_user, :ldap) }
subject(:access) { described_class.new(user) }
diff --git a/spec/lib/gitlab/auth/ldap/authentication_spec.rb b/spec/lib/gitlab/auth/ldap/authentication_spec.rb
index 42a893417d8..4b0e21da6c6 100644
--- a/spec/lib/gitlab/auth/ldap/authentication_spec.rb
+++ b/spec/lib/gitlab/auth/ldap/authentication_spec.rb
@@ -4,7 +4,7 @@ require 'spec_helper'
RSpec.describe Gitlab::Auth::Ldap::Authentication do
let(:dn) { 'uid=John Smith, ou=People, dc=example, dc=com' }
- let(:user) { create(:omniauth_user, extern_uid: Gitlab::Auth::Ldap::Person.normalize_dn(dn)) }
+ let(:user) { create(:omniauth_user, :ldap, extern_uid: Gitlab::Auth::Ldap::Person.normalize_dn(dn)) }
let(:login) { 'john' }
let(:password) { 'password' }
diff --git a/spec/lib/gitlab/auth/o_auth/provider_spec.rb b/spec/lib/gitlab/auth/o_auth/provider_spec.rb
index 57f17365190..c1b96819176 100644
--- a/spec/lib/gitlab/auth/o_auth/provider_spec.rb
+++ b/spec/lib/gitlab/auth/o_auth/provider_spec.rb
@@ -62,7 +62,7 @@ RSpec.describe Gitlab::Auth::OAuth::Provider do
context 'for an OmniAuth provider' do
before do
- provider = OpenStruct.new(
+ provider = ActiveSupport::InheritableOptions.new(
name: 'google_oauth2',
app_id: 'asd123',
app_secret: 'asd123'
@@ -74,7 +74,7 @@ RSpec.describe Gitlab::Auth::OAuth::Provider do
subject { described_class.config_for('google_oauth2') }
it 'returns the config' do
- expect(subject).to be_a(OpenStruct)
+ expect(subject).to be_a(ActiveSupport::InheritableOptions)
end
it 'merges defaults with the given configuration' do
@@ -98,7 +98,7 @@ RSpec.describe Gitlab::Auth::OAuth::Provider do
context 'when configuration specifies a custom label' do
let(:name) { 'google_oauth2' }
let(:label) { 'Custom Google Provider' }
- let(:provider) { OpenStruct.new({ 'name' => name, 'label' => label }) }
+ let(:provider) { ActiveSupport::InheritableOptions.new(name: name, label: label) }
before do
stub_omniauth_setting(providers: [provider])
@@ -110,7 +110,7 @@ RSpec.describe Gitlab::Auth::OAuth::Provider do
end
context 'when configuration does not specify a custom label' do
- let(:provider) { OpenStruct.new({ 'name' => name } ) }
+ let(:provider) { ActiveSupport::InheritableOptions.new(name: name) }
before do
stub_omniauth_setting(providers: [provider])
diff --git a/spec/lib/gitlab/auth/o_auth/user_spec.rb b/spec/lib/gitlab/auth/o_auth/user_spec.rb
index 8d36507ec7a..1a9e2f02de6 100644
--- a/spec/lib/gitlab/auth/o_auth/user_spec.rb
+++ b/spec/lib/gitlab/auth/o_auth/user_spec.rb
@@ -577,28 +577,66 @@ RSpec.describe Gitlab::Auth::OAuth::User do
stub_omniauth_config(allow_single_sign_on: ['twitter'])
end
- context 'signup with omniauth only' do
- context 'dont block on create' do
- before do
- stub_omniauth_config(block_auto_created_users: false)
+ shared_examples 'being blocked on creation' do
+ context 'when blocking on creation' do
+ it 'creates a blocked user' do
+ oauth_user.save # rubocop:disable Rails/SaveBang
+ expect(gl_user).to be_valid
+ expect(gl_user).to be_blocked
end
- it do
+ context 'when a sign up user cap has been set up but has not been reached yet' do
+ it 'still creates a blocked user' do
+ stub_application_setting(new_user_signups_cap: 999)
+
+ oauth_user.save # rubocop:disable Rails/SaveBang
+ expect(gl_user).to be_valid
+ expect(gl_user).to be_blocked
+ end
+ end
+ end
+ end
+
+ shared_examples 'not being blocked on creation' do
+ context 'when not blocking on creation' do
+ it 'creates a non-blocked user' do
oauth_user.save # rubocop:disable Rails/SaveBang
expect(gl_user).to be_valid
expect(gl_user).not_to be_blocked
end
end
+ end
+
+ context 'signup with SAML' do
+ let(:provider) { 'saml' }
+
+ before do
+ stub_omniauth_config({
+ allow_single_sign_on: ['saml'],
+ auto_link_saml_user: true,
+ block_auto_created_users: block_auto_created_users
+ })
+ end
+
+ it_behaves_like 'being blocked on creation' do
+ let(:block_auto_created_users) { true }
+ end
+
+ it_behaves_like 'not being blocked on creation' do
+ let(:block_auto_created_users) { false }
+ end
+ end
- context 'block on create' do
+ context 'signup with omniauth only' do
+ it_behaves_like 'being blocked on creation' do
before do
stub_omniauth_config(block_auto_created_users: true)
end
+ end
- it do
- oauth_user.save # rubocop:disable Rails/SaveBang
- expect(gl_user).to be_valid
- expect(gl_user).to be_blocked
+ it_behaves_like 'not being blocked on creation' do
+ before do
+ stub_omniauth_config(block_auto_created_users: false)
end
end
end
@@ -614,64 +652,40 @@ RSpec.describe Gitlab::Auth::OAuth::User do
end
context "and no account for the LDAP user" do
- context 'dont block on create (LDAP)' do
+ it_behaves_like 'being blocked on creation' do
before do
allow_next_instance_of(Gitlab::Auth::Ldap::Config) do |instance|
- allow(instance).to receive_messages(block_auto_created_users: false)
+ allow(instance).to receive_messages(block_auto_created_users: true)
end
end
-
- it do
- oauth_user.save # rubocop:disable Rails/SaveBang
- expect(gl_user).to be_valid
- expect(gl_user).not_to be_blocked
- end
end
- context 'block on create (LDAP)' do
+ it_behaves_like 'not being blocked on creation' do
before do
allow_next_instance_of(Gitlab::Auth::Ldap::Config) do |instance|
- allow(instance).to receive_messages(block_auto_created_users: true)
+ allow(instance).to receive_messages(block_auto_created_users: false)
end
end
-
- it do
- oauth_user.save # rubocop:disable Rails/SaveBang
- expect(gl_user).to be_valid
- expect(gl_user).to be_blocked
- end
end
end
context 'and LDAP user has an account already' do
let!(:existing_user) { create(:omniauth_user, email: 'john@example.com', extern_uid: dn, provider: 'ldapmain', username: 'john') }
- context 'dont block on create (LDAP)' do
+ it_behaves_like 'not being blocked on creation' do
before do
allow_next_instance_of(Gitlab::Auth::Ldap::Config) do |instance|
allow(instance).to receive_messages(block_auto_created_users: false)
end
end
-
- it do
- oauth_user.save # rubocop:disable Rails/SaveBang
- expect(gl_user).to be_valid
- expect(gl_user).not_to be_blocked
- end
end
- context 'block on create (LDAP)' do
+ it_behaves_like 'not being blocked on creation' do
before do
allow_next_instance_of(Gitlab::Auth::Ldap::Config) do |instance|
allow(instance).to receive_messages(block_auto_created_users: true)
end
end
-
- it do
- oauth_user.save # rubocop:disable Rails/SaveBang
- expect(gl_user).to be_valid
- expect(gl_user).not_to be_blocked
- end
end
end
end
@@ -682,56 +696,32 @@ RSpec.describe Gitlab::Auth::OAuth::User do
oauth_user.gl_user.activate
end
- context 'dont block on create' do
+ it_behaves_like 'not being blocked on creation' do
before do
stub_omniauth_config(block_auto_created_users: false)
end
-
- it do
- oauth_user.save # rubocop:disable Rails/SaveBang
- expect(gl_user).to be_valid
- expect(gl_user).not_to be_blocked
- end
end
- context 'block on create' do
+ it_behaves_like 'not being blocked on creation' do
before do
stub_omniauth_config(block_auto_created_users: true)
end
-
- it do
- oauth_user.save # rubocop:disable Rails/SaveBang
- expect(gl_user).to be_valid
- expect(gl_user).not_to be_blocked
- end
end
- context 'dont block on create (LDAP)' do
+ it_behaves_like 'not being blocked on creation' do
before do
allow_next_instance_of(Gitlab::Auth::Ldap::Config) do |instance|
allow(instance).to receive_messages(block_auto_created_users: false)
end
end
-
- it do
- oauth_user.save # rubocop:disable Rails/SaveBang
- expect(gl_user).to be_valid
- expect(gl_user).not_to be_blocked
- end
end
- context 'block on create (LDAP)' do
+ it_behaves_like 'not being blocked on creation' do
before do
allow_next_instance_of(Gitlab::Auth::Ldap::Config) do |instance|
allow(instance).to receive_messages(block_auto_created_users: true)
end
end
-
- it do
- oauth_user.save # rubocop:disable Rails/SaveBang
- expect(gl_user).to be_valid
- expect(gl_user).not_to be_blocked
- end
end
end
end
@@ -1057,4 +1047,10 @@ RSpec.describe Gitlab::Auth::OAuth::User do
expect(oauth_user.bypass_two_factor?).to be_falsey
end
end
+
+ describe '#protocol_name' do
+ it 'is OAuth' do
+ expect(oauth_user.protocol_name).to eq('OAuth')
+ end
+ end
end
diff --git a/spec/lib/gitlab/auth/request_authenticator_spec.rb b/spec/lib/gitlab/auth/request_authenticator_spec.rb
index 5e9d07a8bf7..2bc80edb98c 100644
--- a/spec/lib/gitlab/auth/request_authenticator_spec.rb
+++ b/spec/lib/gitlab/auth/request_authenticator_spec.rb
@@ -44,6 +44,38 @@ RSpec.describe Gitlab::Auth::RequestAuthenticator do
end
end
+ describe '#can_sign_in_bot?' do
+ context 'the user is nil' do
+ it { is_expected.not_to be_can_sign_in_bot(nil) }
+ end
+
+ context 'the user is a bot, but for a web request' do
+ let(:user) { build(:user, :project_bot) }
+
+ it { is_expected.not_to be_can_sign_in_bot(user) }
+ end
+
+ context 'the user is a regular user, for an API request' do
+ let(:user) { build(:user) }
+
+ before do
+ env['SCRIPT_NAME'] = '/api/some_resource'
+ end
+
+ it { is_expected.not_to be_can_sign_in_bot(user) }
+ end
+
+ context 'the user is a project bot, for an API request' do
+ let(:user) { build(:user, :project_bot) }
+
+ before do
+ env['SCRIPT_NAME'] = '/api/some_resource'
+ end
+
+ it { is_expected.to be_can_sign_in_bot(user) }
+ end
+ end
+
describe '#find_sessionless_user' do
let_it_be(:dependency_proxy_user) { build(:user) }
let_it_be(:access_token_user) { build(:user) }
diff --git a/spec/lib/gitlab/background_migration/backfill_issue_search_data_spec.rb b/spec/lib/gitlab/background_migration/backfill_issue_search_data_spec.rb
new file mode 100644
index 00000000000..b29d4c3583b
--- /dev/null
+++ b/spec/lib/gitlab/background_migration/backfill_issue_search_data_spec.rb
@@ -0,0 +1,57 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::BackgroundMigration::BackfillIssueSearchData do
+ let(:namespaces_table) { table(:namespaces) }
+ let(:projects_table) { table(:projects) }
+ let(:issue_search_data_table) { table(:issue_search_data) }
+
+ let!(:namespace) { namespaces_table.create!(name: 'gitlab-org', path: 'gitlab-org') }
+ let!(:project) { projects_table.create!(name: 'gitlab', path: 'gitlab-org/gitlab-ce', namespace_id: namespace.id) }
+ let!(:issues) { Array.new(10) { table(:issues).create!(project_id: project.id, title: 'test title', description: 'test description') } }
+
+ let(:migration) { described_class.new }
+
+ before do
+ allow(migration).to receive(:sleep)
+ end
+
+ it 'backfills search data for the specified records' do
+ # sleeps for every sub-batch
+ expect(migration).to receive(:sleep).with(0.05).exactly(3).times
+
+ migration.perform(issues[0].id, issues[5].id, :issues, :id, 2, 50)
+
+ expect(issue_search_data_table.count).to eq(6)
+ end
+
+ it 'skips issues that already have search data' do
+ old_time = Time.new(2019, 1, 1).in_time_zone
+ issue_search_data_table.create!(project_id: project.id, issue_id: issues[0].id, updated_at: old_time)
+
+ migration.perform(issues[0].id, issues[5].id, :issues, :id, 2, 50)
+
+ expect(issue_search_data_table.count).to eq(6)
+ expect(issue_search_data_table.find_by_issue_id(issues[0].id).updated_at).to be_like_time(old_time)
+ end
+
+ it 'rescues batch with bad data and inserts other rows' do
+ issues[1].update!(description: Array.new(30_000) { SecureRandom.hex }.join(' '))
+
+ expect_next_instance_of(Gitlab::BackgroundMigration::Logger) do |logger|
+ expect(logger).to receive(:error).with(a_hash_including(message: /string is too long for tsvector/, model_id: issues[1].id))
+ end
+
+ expect { migration.perform(issues[0].id, issues[5].id, :issues, :id, 2, 50) }.not_to raise_error
+
+ expect(issue_search_data_table.count).to eq(5)
+ expect(issue_search_data_table.find_by_issue_id(issues[1].id)).to eq(nil)
+ end
+
+ it 're-raises other errors' do
+ allow(migration).to receive(:update_search_data).and_raise(ActiveRecord::StatementTimeout)
+
+ expect { migration.perform(issues[0].id, issues[5].id, :issues, :id, 2, 50) }.to raise_error(ActiveRecord::StatementTimeout)
+ end
+end
diff --git a/spec/lib/gitlab/background_migration/backfill_member_namespace_for_group_members_spec.rb b/spec/lib/gitlab/background_migration/backfill_member_namespace_for_group_members_spec.rb
new file mode 100644
index 00000000000..e1ef12a1479
--- /dev/null
+++ b/spec/lib/gitlab/background_migration/backfill_member_namespace_for_group_members_spec.rb
@@ -0,0 +1,50 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::BackgroundMigration::BackfillMemberNamespaceForGroupMembers, :migration, schema: 20220120211832 do
+ let(:migration) { described_class.new }
+ let(:members_table) { table(:members) }
+ let(:namespaces_table) { table(:namespaces) }
+
+ let(:table_name) { 'members' }
+ let(:batch_column) { :id }
+ let(:sub_batch_size) { 100 }
+ let(:pause_ms) { 0 }
+
+ subject(:perform_migration) { migration.perform(1, 10, table_name, batch_column, sub_batch_size, pause_ms) }
+
+ before do
+ namespaces_table.create!(id: 100, name: 'test1', path: 'test1', type: 'Group')
+ namespaces_table.create!(id: 101, name: 'test2', path: 'test2', type: 'Group')
+ namespaces_table.create!(id: 102, name: 'test3', path: 'test3', type: 'Group')
+ namespaces_table.create!(id: 201, name: 'test4', path: 'test4', type: 'Project')
+
+ members_table.create!(id: 1, source_id: 100, source_type: 'Namespace', type: 'GroupMember', member_namespace_id: nil, access_level: 10, notification_level: 3)
+ members_table.create!(id: 2, source_id: 101, source_type: 'Namespace', type: 'GroupMember', member_namespace_id: nil, access_level: 10, notification_level: 3)
+ members_table.create!(id: 3, source_id: 102, source_type: 'Namespace', type: 'GroupMember', member_namespace_id: 102, access_level: 10, notification_level: 3)
+ members_table.create!(id: 4, source_id: 103, source_type: 'Project', type: 'ProjectMember', member_namespace_id: nil, access_level: 10, notification_level: 3)
+ members_table.create!(id: 5, source_id: 104, source_type: 'Project', type: 'ProjectMember', member_namespace_id: 201, access_level: 10, notification_level: 3)
+ end
+
+ it 'backfills `member_namespace_id` for the selected records', :aggregate_failures do
+ expect(members_table.where(type: 'GroupMember', member_namespace_id: nil).count).to eq 2
+ expect(members_table.where(type: 'ProjectMember', member_namespace_id: nil).count).to eq 1
+
+ queries = ActiveRecord::QueryRecorder.new do
+ perform_migration
+ end
+
+ expect(queries.count).to eq(3)
+ expect(members_table.where(type: 'GroupMember', member_namespace_id: nil).count).to eq 0
+ expect(members_table.where(type: 'GroupMember').pluck(:member_namespace_id)).to match_array([100, 101, 102])
+ expect(members_table.where(type: 'ProjectMember', member_namespace_id: nil).count).to eq 1
+ expect(members_table.where(type: 'ProjectMember').pluck(:member_namespace_id)).to match_array([nil, 201])
+ end
+
+ it 'tracks timings of queries' do
+ expect(migration.batch_metrics.timings).to be_empty
+
+ expect { perform_migration }.to change { migration.batch_metrics.timings }
+ end
+end
diff --git a/spec/lib/gitlab/background_migration/backfill_snippet_repositories_spec.rb b/spec/lib/gitlab/background_migration/backfill_snippet_repositories_spec.rb
index d22aa86dbe0..cfa03db52fe 100644
--- a/spec/lib/gitlab/background_migration/backfill_snippet_repositories_spec.rb
+++ b/spec/lib/gitlab/background_migration/backfill_snippet_repositories_spec.rb
@@ -78,6 +78,10 @@ RSpec.describe Gitlab::BackgroundMigration::BackfillSnippetRepositories, :migrat
end
shared_examples 'migration_bot user commits files' do
+ before do
+ allow(Gitlab::CurrentSettings).to receive(:default_branch_name).and_return('main')
+ end
+
it do
subject
@@ -89,6 +93,10 @@ RSpec.describe Gitlab::BackgroundMigration::BackfillSnippetRepositories, :migrat
end
shared_examples 'commits the file to the repository' do
+ before do
+ allow(Gitlab::CurrentSettings).to receive(:default_branch_name).and_return('main')
+ end
+
context 'when author can update snippet and use git' do
it 'creates the repository and commit the file' do
subject
@@ -269,6 +277,10 @@ RSpec.describe Gitlab::BackgroundMigration::BackfillSnippetRepositories, :migrat
let!(:snippet) { snippets.create!(id: 5, type: 'PersonalSnippet', author_id: other_user.id, file_name: file_name, content: content) }
let(:ids) { [4, 5] }
+ before do
+ allow(Gitlab::CurrentSettings).to receive(:default_branch_name).and_return('main')
+ end
+
after do
raw_repository(snippet).remove
raw_repository(invalid_snippet).remove
diff --git a/spec/lib/gitlab/background_migration/batching_strategies/backfill_project_namespace_per_group_batching_strategy_spec.rb b/spec/lib/gitlab/background_migration/batching_strategies/backfill_project_namespace_per_group_batching_strategy_spec.rb
index 7b8a466b37c..b01dd5b410e 100644
--- a/spec/lib/gitlab/background_migration/batching_strategies/backfill_project_namespace_per_group_batching_strategy_spec.rb
+++ b/spec/lib/gitlab/background_migration/batching_strategies/backfill_project_namespace_per_group_batching_strategy_spec.rb
@@ -15,7 +15,7 @@ RSpec.describe Gitlab::BackgroundMigration::BatchingStrategies::BackfillProjectN
let!(:project2) { projects.create!(name: 'project2', path: 'project2', namespace_id: namespace2.id, visibility_level: 20) }
let!(:project3) { projects.create!(name: 'project3', path: 'project3', namespace_id: namespace3.id, visibility_level: 20) }
let!(:project4) { projects.create!(name: 'project4', path: 'project4', namespace_id: namespace3.id, visibility_level: 20) }
- let!(:batching_strategy) { described_class.new }
+ let!(:batching_strategy) { described_class.new(connection: ActiveRecord::Base.connection) }
let(:job_arguments) { [namespace1.id, 'up'] }
diff --git a/spec/lib/gitlab/background_migration/batching_strategies/base_strategy_spec.rb b/spec/lib/gitlab/background_migration/batching_strategies/base_strategy_spec.rb
new file mode 100644
index 00000000000..56ed1f23799
--- /dev/null
+++ b/spec/lib/gitlab/background_migration/batching_strategies/base_strategy_spec.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::BackgroundMigration::BatchingStrategies::BaseStrategy, '#next_batch' do
+ let(:connection) { double(:connection) }
+ let(:base_strategy_class) { Class.new(described_class) }
+ let(:base_strategy) { base_strategy_class.new(connection: connection) }
+
+ describe '#next_batch' do
+ it 'raises an error if not overridden by a subclass' do
+ expect { base_strategy.next_batch }.to raise_error(NotImplementedError, /does not implement next_batch/)
+ end
+ end
+end
diff --git a/spec/lib/gitlab/background_migration/batching_strategies/primary_key_batching_strategy_spec.rb b/spec/lib/gitlab/background_migration/batching_strategies/primary_key_batching_strategy_spec.rb
index 39030039125..4e0ebd4b692 100644
--- a/spec/lib/gitlab/background_migration/batching_strategies/primary_key_batching_strategy_spec.rb
+++ b/spec/lib/gitlab/background_migration/batching_strategies/primary_key_batching_strategy_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
RSpec.describe Gitlab::BackgroundMigration::BatchingStrategies::PrimaryKeyBatchingStrategy, '#next_batch' do
- let(:batching_strategy) { described_class.new }
+ let(:batching_strategy) { described_class.new(connection: ActiveRecord::Base.connection) }
let(:namespaces) { table(:namespaces) }
let!(:namespace1) { namespaces.create!(name: 'batchtest1', path: 'batch-test1') }
@@ -11,6 +11,8 @@ RSpec.describe Gitlab::BackgroundMigration::BatchingStrategies::PrimaryKeyBatchi
let!(:namespace3) { namespaces.create!(name: 'batchtest3', path: 'batch-test3') }
let!(:namespace4) { namespaces.create!(name: 'batchtest4', path: 'batch-test4') }
+ it { expect(described_class).to be < Gitlab::BackgroundMigration::BatchingStrategies::BaseStrategy }
+
context 'when starting on the first batch' do
it 'returns the bounds of the next batch' do
batch_bounds = batching_strategy.next_batch(:namespaces, :id, batch_min_value: namespace1.id, batch_size: 3, job_arguments: nil)
diff --git a/spec/lib/gitlab/background_migration/encrypt_integration_properties_spec.rb b/spec/lib/gitlab/background_migration/encrypt_integration_properties_spec.rb
new file mode 100644
index 00000000000..7334867e8fb
--- /dev/null
+++ b/spec/lib/gitlab/background_migration/encrypt_integration_properties_spec.rb
@@ -0,0 +1,63 @@
+# frozen_string_literal: true
+require 'spec_helper'
+
+RSpec.describe Gitlab::BackgroundMigration::EncryptIntegrationProperties do
+ let(:integrations) do
+ table(:integrations) do |integrations|
+ integrations.send :attr_encrypted, :encrypted_properties_tmp,
+ attribute: :encrypted_properties,
+ mode: :per_attribute_iv,
+ key: ::Settings.attr_encrypted_db_key_base_32,
+ algorithm: 'aes-256-gcm',
+ marshal: true,
+ marshaler: ::Gitlab::Json,
+ encode: false,
+ encode_iv: false
+ end
+ end
+
+ let!(:no_properties) { integrations.create! }
+ let!(:with_plaintext_1) { integrations.create!(properties: json_props(1)) }
+ let!(:with_plaintext_2) { integrations.create!(properties: json_props(2)) }
+ let!(:with_encrypted) do
+ x = integrations.new
+ x.properties = nil
+ x.encrypted_properties_tmp = some_props(3)
+ x.save!
+ x
+ end
+
+ let(:start_id) { integrations.minimum(:id) }
+ let(:end_id) { integrations.maximum(:id) }
+
+ it 'ensures all properties are encrypted', :aggregate_failures do
+ described_class.new.perform(start_id, end_id)
+
+ props = integrations.all.to_h do |record|
+ [record.id, [Gitlab::Json.parse(record.properties), record.encrypted_properties_tmp]]
+ end
+
+ expect(integrations.count).to eq(4)
+
+ expect(props).to match(
+ no_properties.id => both(be_nil),
+ with_plaintext_1.id => both(eq some_props(1)),
+ with_plaintext_2.id => both(eq some_props(2)),
+ with_encrypted.id => match([be_nil, eq(some_props(3))])
+ )
+ end
+
+ private
+
+ def both(obj)
+ match [obj, obj]
+ end
+
+ def some_props(id)
+ HashWithIndifferentAccess.new({ id: id, foo: 1, bar: true, baz: %w[a string array] })
+ end
+
+ def json_props(id)
+ some_props(id).to_json
+ end
+end
diff --git a/spec/lib/gitlab/background_migration/job_coordinator_spec.rb b/spec/lib/gitlab/background_migration/job_coordinator_spec.rb
index 43d41408e66..c1351481505 100644
--- a/spec/lib/gitlab/background_migration/job_coordinator_spec.rb
+++ b/spec/lib/gitlab/background_migration/job_coordinator_spec.rb
@@ -38,13 +38,67 @@ RSpec.describe Gitlab::BackgroundMigration::JobCoordinator do
end
end
+ describe '#pending_jobs' do
+ context 'when there are enqueued jobs' do
+ let(:queue) do
+ [
+ instance_double(Sidekiq::JobRecord, args: [1, 'queue'], klass: worker_class.name),
+ instance_double(Sidekiq::JobRecord, args: [2, 'queue'], klass: worker_class.name)
+ ]
+ end
+
+ let(:queue_incorrect_job_class) do
+ [
+ instance_double(Sidekiq::JobRecord, args: [1, 'queue'], klass: 'SomeOtherClass')
+ ]
+ end
+
+ let(:scheduled_set) do
+ [instance_double(Sidekiq::JobRecord, args: [3, 'scheduled'], klass: worker_class.name)]
+ end
+
+ let(:retry_set) do
+ [instance_double(Sidekiq::JobRecord, args: [4, 'retry'], klass: worker_class.name)]
+ end
+
+ let(:dead_set) do
+ [instance_double(Sidekiq::JobRecord, args: [5, 'dead'], klass: worker_class.name)]
+ end
+
+ before do
+ allow(Sidekiq::Queue).to receive(:new)
+ .with(coordinator.queue)
+ .and_return(queue + queue_incorrect_job_class)
+ allow(Sidekiq::ScheduledSet).to receive(:new).and_return(scheduled_set)
+ allow(Sidekiq::RetrySet).to receive(:new).and_return(retry_set)
+ allow(Sidekiq::DeadSet).to receive(:new).and_return(dead_set)
+ end
+
+ it 'does not include jobs for other workers' do
+ expect(coordinator.pending_jobs).not_to include(queue_incorrect_job_class.first)
+ end
+
+ context 'when not including dead jobs' do
+ it 'includes current and future jobs' do
+ expect(coordinator.pending_jobs(include_dead_jobs: false).to_a).to match_array(queue + scheduled_set)
+ end
+ end
+
+ context 'when including dead jobs' do
+ it 'includes current and future jobs, and also dead and retry jobs' do
+ expect(coordinator.pending_jobs(include_dead_jobs: true).to_a).to match_array(queue + scheduled_set + retry_set + dead_set)
+ end
+ end
+ end
+ end
+
describe '#steal' do
context 'when there are enqueued jobs present' do
let(:queue) do
[
- double(args: ['Foo', [10, 20]], klass: worker_class.name),
- double(args: ['Bar', [20, 30]], klass: worker_class.name),
- double(args: ['Foo', [20, 30]], klass: 'MergeWorker')
+ instance_double(Sidekiq::JobRecord, args: ['Foo', [10, 20]], klass: worker_class.name),
+ instance_double(Sidekiq::JobRecord, args: ['Bar', [20, 30]], klass: worker_class.name),
+ instance_double(Sidekiq::JobRecord, args: ['Foo', [20, 30]], klass: 'MergeWorker')
]
end
diff --git a/spec/lib/gitlab/background_migration/migrate_personal_namespace_project_maintainer_to_owner_spec.rb b/spec/lib/gitlab/background_migration/migrate_personal_namespace_project_maintainer_to_owner_spec.rb
new file mode 100644
index 00000000000..07e77bdbc13
--- /dev/null
+++ b/spec/lib/gitlab/background_migration/migrate_personal_namespace_project_maintainer_to_owner_spec.rb
@@ -0,0 +1,82 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::BackgroundMigration::MigratePersonalNamespaceProjectMaintainerToOwner, :migration, schema: 20220208080921 do
+ let(:migration) { described_class.new }
+ let(:users_table) { table(:users) }
+ let(:members_table) { table(:members) }
+ let(:namespaces_table) { table(:namespaces) }
+ let(:projects_table) { table(:projects) }
+
+ let(:table_name) { 'members' }
+ let(:batch_column) { :id }
+ let(:sub_batch_size) { 10 }
+ let(:pause_ms) { 0 }
+
+ let(:owner_access) { 50 }
+ let(:maintainer_access) { 40 }
+ let(:developer_access) { 30 }
+
+ subject(:perform_migration) { migration.perform(1, 10, table_name, batch_column, sub_batch_size, pause_ms) }
+
+ before do
+ users_table.create!(id: 101, name: "user1", email: "user1@example.com", projects_limit: 5)
+ users_table.create!(id: 102, name: "user2", email: "user2@example.com", projects_limit: 5)
+
+ namespaces_table.create!(id: 201, name: 'user1s-namespace', path: 'user1s-namespace-path', type: 'User', owner_id: 101)
+ namespaces_table.create!(id: 202, name: 'user2s-namespace', path: 'user2s-namespace-path', type: 'User', owner_id: 102)
+ namespaces_table.create!(id: 203, name: 'group', path: 'group', type: 'Group')
+ namespaces_table.create!(id: 204, name: 'project-namespace', path: 'project-namespace-path', type: 'Project')
+
+ projects_table.create!(id: 301, name: 'user1-namespace-project', path: 'project-path-1', namespace_id: 201)
+ projects_table.create!(id: 302, name: 'user2-namespace-project', path: 'project-path-2', namespace_id: 202)
+ projects_table.create!(id: 303, name: 'user2s-namespace-project2', path: 'project-path-3', namespace_id: 202)
+ projects_table.create!(id: 304, name: 'group-project3', path: 'group-project-path-3', namespace_id: 203)
+
+ # user1 member of their own namespace project, maintainer access (change)
+ create_project_member(id: 1, user_id: 101, project_id: 301, level: maintainer_access)
+
+ # user2 member of their own namespace project, owner access (no change)
+ create_project_member(id: 2, user_id: 102, project_id: 302, level: owner_access)
+
+ # user1 member of user2's personal namespace project, maintainer access (no change)
+ create_project_member(id: 3, user_id: 101, project_id: 302, level: maintainer_access)
+
+ # user1 member of group project, maintainer access (no change)
+ create_project_member(id: 4, user_id: 101, project_id: 304, level: maintainer_access)
+
+ # user1 member of group, Maintainer role (no change)
+ create_group_member(id: 5, user_id: 101, group_id: 203, level: maintainer_access)
+
+ # user2 member of their own namespace project, maintainer access, but out of batch range (no change)
+ create_project_member(id: 601, user_id: 102, project_id: 303, level: maintainer_access)
+ end
+
+ it 'migrates MAINTAINER membership records for personal namespaces to OWNER', :aggregate_failures do
+ expect(members_table.where(access_level: owner_access).count).to eq 1
+ expect(members_table.where(access_level: maintainer_access).count).to eq 5
+
+ queries = ActiveRecord::QueryRecorder.new do
+ perform_migration
+ end
+
+ expect(queries.count).to eq(3)
+ expect(members_table.where(access_level: owner_access).pluck(:id)).to match_array([1, 2])
+ expect(members_table.where(access_level: maintainer_access).pluck(:id)).to match_array([3, 4, 5, 601])
+ end
+
+ it 'tracks timings of queries' do
+ expect(migration.batch_metrics.timings).to be_empty
+
+ expect { perform_migration }.to change { migration.batch_metrics.timings }
+ end
+
+ def create_group_member(id:, user_id:, group_id:, level:)
+ members_table.create!(id: id, user_id: user_id, source_id: group_id, access_level: level, source_type: "Namespace", type: "GroupMember", notification_level: 3)
+ end
+
+ def create_project_member(id:, user_id:, project_id:, level:)
+ members_table.create!(id: id, user_id: user_id, source_id: project_id, access_level: level, source_type: "Namespace", type: "ProjectMember", notification_level: 3)
+ end
+end
diff --git a/spec/lib/gitlab/background_migration/nullify_orphan_runner_id_on_ci_builds_spec.rb b/spec/lib/gitlab/background_migration/nullify_orphan_runner_id_on_ci_builds_spec.rb
new file mode 100644
index 00000000000..90dd3e14606
--- /dev/null
+++ b/spec/lib/gitlab/background_migration/nullify_orphan_runner_id_on_ci_builds_spec.rb
@@ -0,0 +1,49 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::BackgroundMigration::NullifyOrphanRunnerIdOnCiBuilds, :migration, schema: 20220223112304 do
+ let(:namespaces) { table(:namespaces) }
+ let(:projects) { table(:projects) }
+ let(:ci_runners) { table(:ci_runners) }
+ let(:ci_pipelines) { table(:ci_pipelines) }
+ let(:ci_builds) { table(:ci_builds) }
+
+ subject { described_class.new }
+
+ let(:helpers) do
+ ActiveRecord::Migration.new.extend(Gitlab::Database::MigrationHelpers)
+ end
+
+ before do
+ helpers.remove_foreign_key_if_exists(:ci_builds, column: :runner_id)
+ end
+
+ after do
+ helpers.add_concurrent_foreign_key(:ci_builds, :ci_runners, column: :runner_id, on_delete: :nullify, validate: false)
+ end
+
+ describe '#perform' do
+ let(:namespace) { namespaces.create!(name: 'test', path: 'test', type: 'Group') }
+ let(:project) { projects.create!(namespace_id: namespace.id, name: 'test') }
+ let(:pipeline) { ci_pipelines.create!(project_id: project.id, ref: 'master', sha: 'adf43c3a', status: 'success') }
+
+ it 'nullifies runner_id for orphan ci_builds in range' do
+ ci_runners.create!(id: 2, runner_type: 'project_type')
+
+ ci_builds.create!(id: 5, type: 'Ci::Build', commit_id: pipeline.id, runner_id: 2)
+ ci_builds.create!(id: 7, type: 'Ci::Build', commit_id: pipeline.id, runner_id: 4)
+ ci_builds.create!(id: 8, type: 'Ci::Build', commit_id: pipeline.id, runner_id: 5)
+ ci_builds.create!(id: 9, type: 'Ci::Build', commit_id: pipeline.id, runner_id: 6)
+
+ subject.perform(4, 8, :ci_builds, :id, 10, 0)
+
+ expect(ci_builds.all).to contain_exactly(
+ an_object_having_attributes(id: 5, runner_id: 2),
+ an_object_having_attributes(id: 7, runner_id: nil),
+ an_object_having_attributes(id: 8, runner_id: nil),
+ an_object_having_attributes(id: 9, runner_id: 6)
+ )
+ end
+ end
+end
diff --git a/spec/lib/gitlab/background_migration/remove_all_trace_expiration_dates_spec.rb b/spec/lib/gitlab/background_migration/remove_all_trace_expiration_dates_spec.rb
new file mode 100644
index 00000000000..8cdcec9621c
--- /dev/null
+++ b/spec/lib/gitlab/background_migration/remove_all_trace_expiration_dates_spec.rb
@@ -0,0 +1,53 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::BackgroundMigration::RemoveAllTraceExpirationDates, :migration, schema: 20220131000001 do
+ subject(:perform) { migration.perform(1, 99) }
+
+ let(:migration) { described_class.new }
+
+ let(:trace_in_range) { create_trace!(id: 10, created_at: Date.new(2020, 06, 20), expire_at: Date.new(2021, 01, 22)) }
+ let(:trace_outside_range) { create_trace!(id: 40, created_at: Date.new(2020, 06, 22), expire_at: Date.new(2021, 01, 22)) }
+ let(:trace_without_expiry) { create_trace!(id: 30, created_at: Date.new(2020, 06, 21), expire_at: nil) }
+ let(:archive_in_range) { create_archive!(id: 10, created_at: Date.new(2020, 06, 20), expire_at: Date.new(2021, 01, 22)) }
+ let(:trace_outside_id_range) { create_trace!(id: 100, created_at: Date.new(2020, 06, 20), expire_at: Date.new(2021, 01, 22)) }
+
+ before do
+ table(:namespaces).create!(id: 1, name: 'the-namespace', path: 'the-path')
+ table(:projects).create!(id: 1, name: 'the-project', namespace_id: 1)
+ table(:ci_builds).create!(id: 1, allow_failure: false)
+ end
+
+ context 'for self-hosted instances' do
+ it 'sets expire_at for artifacts in range to nil' do
+ expect { perform }.not_to change { trace_in_range.reload.expire_at }
+ end
+
+ it 'does not change expire_at timestamps that are not set to midnight' do
+ expect { perform }.not_to change { trace_outside_range.reload.expire_at }
+ end
+
+ it 'does not change expire_at timestamps that are set to midnight on a day other than the 22nd' do
+ expect { perform }.not_to change { trace_without_expiry.reload.expire_at }
+ end
+
+ it 'does not touch artifacts outside id range' do
+ expect { perform }.not_to change { archive_in_range.reload.expire_at }
+ end
+
+ it 'does not touch artifacts outside date range' do
+ expect { perform }.not_to change { trace_outside_id_range.reload.expire_at }
+ end
+ end
+
+ private
+
+ def create_trace!(**args)
+ table(:ci_job_artifacts).create!(**args, project_id: 1, job_id: 1, file_type: 3)
+ end
+
+ def create_archive!(**args)
+ table(:ci_job_artifacts).create!(**args, project_id: 1, job_id: 1, file_type: 1)
+ end
+end
diff --git a/spec/lib/gitlab/background_migration/reset_duplicate_ci_runners_token_encrypted_values_on_projects_spec.rb b/spec/lib/gitlab/background_migration/reset_duplicate_ci_runners_token_encrypted_values_on_projects_spec.rb
new file mode 100644
index 00000000000..6aea549b136
--- /dev/null
+++ b/spec/lib/gitlab/background_migration/reset_duplicate_ci_runners_token_encrypted_values_on_projects_spec.rb
@@ -0,0 +1,37 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::BackgroundMigration::ResetDuplicateCiRunnersTokenEncryptedValuesOnProjects do
+ let(:namespaces) { table(:namespaces) }
+ let(:projects) { table(:projects) }
+
+ let(:perform) { described_class.new.perform(1, 4) }
+
+ before do
+ namespaces.create!(id: 123, name: 'sample', path: 'sample')
+
+ projects.create!(id: 1, namespace_id: 123, runners_token_encrypted: 'duplicate')
+ projects.create!(id: 2, namespace_id: 123, runners_token_encrypted: 'a-runners-token')
+ projects.create!(id: 3, namespace_id: 123, runners_token_encrypted: 'duplicate')
+ projects.create!(id: 4, namespace_id: 123, runners_token_encrypted: nil)
+ projects.create!(id: 5, namespace_id: 123, runners_token_encrypted: 'duplicate-2')
+ projects.create!(id: 6, namespace_id: 123, runners_token_encrypted: 'duplicate-2')
+ end
+
+ describe '#up' do
+ before do
+ stub_const("#{described_class}::SUB_BATCH_SIZE", 2)
+ end
+
+ it 'nullifies duplicate tokens', :aggregate_failures do
+ perform
+
+ expect(projects.count).to eq(6)
+ expect(projects.all.pluck(:id, :runners_token_encrypted).to_h).to eq(
+ { 1 => nil, 2 => 'a-runners-token', 3 => nil, 4 => nil, 5 => 'duplicate-2', 6 => 'duplicate-2' }
+ )
+ expect(projects.pluck(:runners_token_encrypted).uniq).to match_array [nil, 'a-runners-token', 'duplicate-2']
+ end
+ end
+end
diff --git a/spec/lib/gitlab/background_migration/reset_duplicate_ci_runners_token_values_on_projects_spec.rb b/spec/lib/gitlab/background_migration/reset_duplicate_ci_runners_token_values_on_projects_spec.rb
new file mode 100644
index 00000000000..cbe762c2680
--- /dev/null
+++ b/spec/lib/gitlab/background_migration/reset_duplicate_ci_runners_token_values_on_projects_spec.rb
@@ -0,0 +1,37 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::BackgroundMigration::ResetDuplicateCiRunnersTokenValuesOnProjects do
+ let(:namespaces) { table(:namespaces) }
+ let(:projects) { table(:projects) }
+
+ let(:perform) { described_class.new.perform(1, 4) }
+
+ before do
+ namespaces.create!(id: 123, name: 'sample', path: 'sample')
+
+ projects.create!(id: 1, namespace_id: 123, runners_token: 'duplicate')
+ projects.create!(id: 2, namespace_id: 123, runners_token: 'a-runners-token')
+ projects.create!(id: 3, namespace_id: 123, runners_token: 'duplicate')
+ projects.create!(id: 4, namespace_id: 123, runners_token: nil)
+ projects.create!(id: 5, namespace_id: 123, runners_token: 'duplicate-2')
+ projects.create!(id: 6, namespace_id: 123, runners_token: 'duplicate-2')
+ end
+
+ describe '#up' do
+ before do
+ stub_const("#{described_class}::SUB_BATCH_SIZE", 2)
+ end
+
+ it 'nullifies duplicate tokens', :aggregate_failures do
+ perform
+
+ expect(projects.count).to eq(6)
+ expect(projects.all.pluck(:id, :runners_token).to_h).to eq(
+ { 1 => nil, 2 => 'a-runners-token', 3 => nil, 4 => nil, 5 => 'duplicate-2', 6 => 'duplicate-2' }
+ )
+ expect(projects.pluck(:runners_token).uniq).to match_array [nil, 'a-runners-token', 'duplicate-2']
+ end
+ end
+end
diff --git a/spec/lib/gitlab/ci/build/policy/refs_spec.rb b/spec/lib/gitlab/ci/build/policy/refs_spec.rb
index 7fd51102d71..2924b175fef 100644
--- a/spec/lib/gitlab/ci/build/policy/refs_spec.rb
+++ b/spec/lib/gitlab/ci/build/policy/refs_spec.rb
@@ -149,26 +149,9 @@ RSpec.describe Gitlab::Ci::Build::Policy::Refs do
context 'when unsafe regexp is used' do
let(:subject) { described_class.new(['/^(?!master).+/']) }
- context 'when allow_unsafe_ruby_regexp is disabled' do
- before do
- stub_feature_flags(allow_unsafe_ruby_regexp: false)
- end
-
- it 'ignores invalid regexp' do
- expect(subject)
- .not_to be_satisfied_by(pipeline)
- end
- end
-
- context 'when allow_unsafe_ruby_regexp is enabled' do
- before do
- stub_feature_flags(allow_unsafe_ruby_regexp: true)
- end
-
- it 'is satisfied by regexp' do
- expect(subject)
- .to be_satisfied_by(pipeline)
- end
+ it 'ignores invalid regexp' do
+ expect(subject)
+ .not_to be_satisfied_by(pipeline)
end
end
end
diff --git a/spec/lib/gitlab/ci/config/entry/bridge_spec.rb b/spec/lib/gitlab/ci/config/entry/bridge_spec.rb
index 62feed3dda0..c56f2d25074 100644
--- a/spec/lib/gitlab/ci/config/entry/bridge_spec.rb
+++ b/spec/lib/gitlab/ci/config/entry/bridge_spec.rb
@@ -293,6 +293,30 @@ RSpec.describe Gitlab::Ci::Config::Entry::Bridge do
end
end
end
+
+ context 'when bridge trigger contains forward' do
+ let(:config) do
+ { trigger: { project: 'some/project', forward: { pipeline_variables: true } } }
+ end
+
+ describe '#valid?' do
+ it { is_expected.to be_valid }
+ end
+
+ describe '#value' do
+ it 'returns a bridge job configuration hash' do
+ expect(subject.value).to eq(name: :my_bridge,
+ trigger: { project: 'some/project',
+ forward: { pipeline_variables: true } },
+ ignore: false,
+ stage: 'test',
+ only: { refs: %w[branches tags] },
+ job_variables: {},
+ root_variables_inheritance: true,
+ scheduling_type: :stage)
+ end
+ end
+ end
end
describe '#manual_action?' do
diff --git a/spec/lib/gitlab/ci/config/entry/include/rules/rule_spec.rb b/spec/lib/gitlab/ci/config/entry/include/rules/rule_spec.rb
index e83d4974bb7..6116fbced2b 100644
--- a/spec/lib/gitlab/ci/config/entry/include/rules/rule_spec.rb
+++ b/spec/lib/gitlab/ci/config/entry/include/rules/rule_spec.rb
@@ -59,9 +59,7 @@ RSpec.describe Gitlab::Ci::Config::Entry::Include::Rules::Rule do
context 'when using an if: clause with lookahead regex character "?"' do
let(:config) { { if: '$CI_COMMIT_REF =~ /^(?!master).+/' } }
- context 'when allow_unsafe_ruby_regexp is disabled' do
- it_behaves_like 'an invalid config', /invalid expression syntax/
- end
+ it_behaves_like 'an invalid config', /invalid expression syntax/
end
context 'when specifying unknown policy' do
diff --git a/spec/lib/gitlab/ci/config/entry/job_spec.rb b/spec/lib/gitlab/ci/config/entry/job_spec.rb
index 885f3eaff79..97691504abd 100644
--- a/spec/lib/gitlab/ci/config/entry/job_spec.rb
+++ b/spec/lib/gitlab/ci/config/entry/job_spec.rb
@@ -420,7 +420,7 @@ RSpec.describe Gitlab::Ci::Config::Entry::Job do
end
end
- context 'when has dependencies' do
+ context 'when it has dependencies' do
context 'that are not a array of strings' do
let(:config) do
{ script: 'echo', dependencies: 'build-job' }
@@ -433,8 +433,8 @@ RSpec.describe Gitlab::Ci::Config::Entry::Job do
end
end
- context 'when has needs' do
- context 'when have dependencies that are not subset of needs' do
+ context 'when the job has needs' do
+ context 'and there are dependencies that are not included in needs' do
let(:config) do
{
stage: 'test',
@@ -448,6 +448,24 @@ RSpec.describe Gitlab::Ci::Config::Entry::Job do
expect(entry).not_to be_valid
expect(entry.errors).to include 'job dependencies the another-job should be part of needs'
end
+
+ context 'and they are only cross pipeline needs' do
+ let(:config) do
+ {
+ script: 'echo',
+ dependencies: ['rspec'],
+ needs: [{
+ job: 'rspec',
+ pipeline: 'other'
+ }]
+ }
+ end
+
+ it 'adds an error for dependency keyword usage' do
+ expect(entry).not_to be_valid
+ expect(entry.errors).to include 'job needs corresponding to dependencies must be from the same pipeline'
+ end
+ end
end
end
diff --git a/spec/lib/gitlab/ci/config/entry/policy_spec.rb b/spec/lib/gitlab/ci/config/entry/policy_spec.rb
index e5de0fb38e3..378c0947e8a 100644
--- a/spec/lib/gitlab/ci/config/entry/policy_spec.rb
+++ b/spec/lib/gitlab/ci/config/entry/policy_spec.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-require 'spec_helper'
+require 'fast_spec_helper'
RSpec.describe Gitlab::Ci::Config::Entry::Policy do
let(:entry) { described_class.new(config) }
@@ -45,29 +45,10 @@ RSpec.describe Gitlab::Ci::Config::Entry::Policy do
end
context 'when using unsafe regexp' do
- # When removed we could use `require 'fast_spec_helper'` again.
- include StubFeatureFlags
-
let(:config) { ['/^(?!master).+/'] }
- context 'when allow_unsafe_ruby_regexp is disabled' do
- before do
- stub_feature_flags(allow_unsafe_ruby_regexp: false)
- end
-
- it 'is not valid' do
- expect(entry).not_to be_valid
- end
- end
-
- context 'when allow_unsafe_ruby_regexp is enabled' do
- before do
- stub_feature_flags(allow_unsafe_ruby_regexp: true)
- end
-
- it 'is valid' do
- expect(entry).to be_valid
- end
+ it 'is not valid' do
+ expect(entry).not_to be_valid
end
end
@@ -106,29 +87,10 @@ RSpec.describe Gitlab::Ci::Config::Entry::Policy do
end
context 'when using unsafe regexp' do
- # When removed we could use `require 'fast_spec_helper'` again.
- include StubFeatureFlags
-
let(:config) { { refs: ['/^(?!master).+/'] } }
- context 'when allow_unsafe_ruby_regexp is disabled' do
- before do
- stub_feature_flags(allow_unsafe_ruby_regexp: false)
- end
-
- it 'is not valid' do
- expect(entry).not_to be_valid
- end
- end
-
- context 'when allow_unsafe_ruby_regexp is enabled' do
- before do
- stub_feature_flags(allow_unsafe_ruby_regexp: true)
- end
-
- it 'is valid' do
- expect(entry).to be_valid
- end
+ it 'is not valid' do
+ expect(entry).not_to be_valid
end
end
diff --git a/spec/lib/gitlab/ci/config/entry/reports/coverage_report_spec.rb b/spec/lib/gitlab/ci/config/entry/reports/coverage_report_spec.rb
new file mode 100644
index 00000000000..588f53150ff
--- /dev/null
+++ b/spec/lib/gitlab/ci/config/entry/reports/coverage_report_spec.rb
@@ -0,0 +1,57 @@
+# frozen_string_literal: true
+
+require 'fast_spec_helper'
+
+RSpec.describe Gitlab::Ci::Config::Entry::Reports::CoverageReport do
+ let(:entry) { described_class.new(config) }
+
+ describe 'validations' do
+ context 'when it is valid' do
+ let(:config) { { coverage_format: 'cobertura', path: 'cobertura-coverage.xml' } }
+
+ it { expect(entry).to be_valid }
+
+ it { expect(entry.value).to eq(config) }
+ end
+
+ context 'with unsupported coverage format' do
+ let(:config) { { coverage_format: 'jacoco', path: 'jacoco.xml' } }
+
+ it { expect(entry).not_to be_valid }
+
+ it { expect(entry.errors).to include /format must be one of supported formats/ }
+ end
+
+ context 'without coverage format' do
+ let(:config) { { path: 'cobertura-coverage.xml' } }
+
+ it { expect(entry).not_to be_valid }
+
+ it { expect(entry.errors).to include /format can't be blank/ }
+ end
+
+ context 'without path' do
+ let(:config) { { coverage_format: 'cobertura' } }
+
+ it { expect(entry).not_to be_valid }
+
+ it { expect(entry.errors).to include /path can't be blank/ }
+ end
+
+ context 'with invalid path' do
+ let(:config) { { coverage_format: 'cobertura', path: 123 } }
+
+ it { expect(entry).not_to be_valid }
+
+ it { expect(entry.errors).to include /path should be a string/ }
+ end
+
+ context 'with unknown keys' do
+ let(:config) { { coverage_format: 'cobertura', path: 'cobertura-coverage.xml', foo: :bar } }
+
+ it { expect(entry).not_to be_valid }
+
+ it { expect(entry.errors).to include /contains unknown keys/ }
+ end
+ 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 12b8960eb32..061d8f34c8d 100644
--- a/spec/lib/gitlab/ci/config/entry/reports_spec.rb
+++ b/spec/lib/gitlab/ci/config/entry/reports_spec.rb
@@ -6,12 +6,8 @@ RSpec.describe Gitlab::Ci::Config::Entry::Reports do
let(:entry) { described_class.new(config) }
describe 'validates ALLOWED_KEYS' do
- let(:artifact_file_types) { Ci::JobArtifact.file_types }
-
- described_class::ALLOWED_KEYS.each do |keyword, _|
- it "expects #{keyword} to be an artifact file_type" do
- expect(artifact_file_types).to include(keyword)
- end
+ it "expects ALLOWED_KEYS to be an artifact file_type or coverage_report" do
+ expect(Ci::JobArtifact.file_types.keys.map(&:to_sym) + [:coverage_report]).to include(*described_class::ALLOWED_KEYS)
end
end
@@ -68,6 +64,45 @@ RSpec.describe Gitlab::Ci::Config::Entry::Reports do
it_behaves_like 'a valid entry', params[:keyword], params[:file]
end
end
+
+ context 'when coverage_report is specified' do
+ let(:coverage_format) { :cobertura }
+ let(:filename) { 'cobertura-coverage.xml' }
+ let(:coverage_report) { { path: filename, coverage_format: coverage_format } }
+ let(:config) { { coverage_report: coverage_report } }
+
+ it 'is valid' do
+ expect(entry).to be_valid
+ end
+
+ it 'returns artifacts configuration' do
+ expect(entry.value).to eq(config)
+ end
+
+ context 'and another report is specified' do
+ let(:config) { { coverage_report: coverage_report, dast: 'gl-dast-report.json' } }
+
+ it 'is valid' do
+ expect(entry).to be_valid
+ end
+
+ it 'returns artifacts configuration' do
+ expect(entry.value).to eq({ coverage_report: coverage_report, dast: ['gl-dast-report.json'] })
+ end
+ end
+
+ context 'and a direct coverage report format is specified' do
+ let(:config) { { coverage_report: coverage_report, cobertura: 'cobertura-coverage.xml' } }
+
+ it 'is not valid' do
+ expect(entry).not_to be_valid
+ end
+
+ it 'reports error' do
+ expect(entry.errors).to include /please use only one the following keys: coverage_report, cobertura/
+ end
+ end
+ end
end
context 'when entry value is not correct' do
diff --git a/spec/lib/gitlab/ci/config/entry/rules/rule_spec.rb b/spec/lib/gitlab/ci/config/entry/rules/rule_spec.rb
index d1bd22e5573..86270788431 100644
--- a/spec/lib/gitlab/ci/config/entry/rules/rule_spec.rb
+++ b/spec/lib/gitlab/ci/config/entry/rules/rule_spec.rb
@@ -92,12 +92,10 @@ RSpec.describe Gitlab::Ci::Config::Entry::Rules::Rule do
context 'when using an if: clause with lookahead regex character "?"' do
let(:config) { { if: '$CI_COMMIT_REF =~ /^(?!master).+/' } }
- context 'when allow_unsafe_ruby_regexp is disabled' do
- it { is_expected.not_to be_valid }
+ it { is_expected.not_to be_valid }
- it 'reports an error about invalid expression syntax' do
- expect(subject.errors).to include(/invalid expression syntax/)
- end
+ it 'reports an error about invalid expression syntax' do
+ expect(subject.errors).to include(/invalid expression syntax/)
end
end
@@ -174,13 +172,13 @@ RSpec.describe Gitlab::Ci::Config::Entry::Rules::Rule do
end
context 'specifying a delayed job' do
- let(:config) { { if: '$THIS || $THAT', when: 'delayed', start_in: '15 minutes' } }
+ let(:config) { { if: '$THIS || $THAT', when: 'delayed', start_in: '2 days' } }
it { is_expected.to be_valid }
it 'sets attributes for the job delay' do
expect(entry.when).to eq('delayed')
- expect(entry.start_in).to eq('15 minutes')
+ expect(entry.start_in).to eq('2 days')
end
context 'without a when: key' do
@@ -198,10 +196,20 @@ RSpec.describe Gitlab::Ci::Config::Entry::Rules::Rule do
it { is_expected.not_to be_valid }
- it 'returns an error about tstart_in being blank' do
+ it 'returns an error about start_in being blank' do
expect(entry.errors).to include(/start in can't be blank/)
end
end
+
+ context 'when start_in value is longer than a week' do
+ let(:config) { { if: '$THIS || $THAT', when: 'delayed', start_in: '2 weeks' } }
+
+ it { is_expected.not_to be_valid }
+
+ it 'returns an error about start_in exceeding the limit' do
+ expect(entry.errors).to include(/start in should not exceed the limit/)
+ end
+ end
end
context 'when specifying unknown policy' do
diff --git a/spec/lib/gitlab/ci/config/entry/trigger/forward_spec.rb b/spec/lib/gitlab/ci/config/entry/trigger/forward_spec.rb
new file mode 100644
index 00000000000..b47a27c9025
--- /dev/null
+++ b/spec/lib/gitlab/ci/config/entry/trigger/forward_spec.rb
@@ -0,0 +1,64 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Ci::Config::Entry::Trigger::Forward do
+ subject(:entry) { described_class.new(config) }
+
+ context 'when entry config is correct' do
+ let(:config) do
+ {
+ yaml_variables: false,
+ pipeline_variables: false
+ }
+ end
+
+ it 'returns set values' do
+ expect(entry.value).to eq(yaml_variables: false, pipeline_variables: false)
+ end
+
+ it { is_expected.to be_valid }
+ end
+
+ context 'when entry config value is empty' do
+ let(:config) do
+ {}
+ end
+
+ it 'returns empty' do
+ expect(entry.value).to eq({})
+ end
+
+ it { is_expected.to be_valid }
+ end
+
+ context 'when entry value is not correct' do
+ context 'invalid attribute' do
+ let(:config) do
+ {
+ xxx_variables: true
+ }
+ end
+
+ it { is_expected.not_to be_valid }
+
+ it 'reports error' do
+ expect(entry.errors).to include 'forward config contains unknown keys: xxx_variables'
+ end
+ end
+
+ context 'non-boolean value' do
+ let(:config) do
+ {
+ yaml_variables: 'okay'
+ }
+ end
+
+ it { is_expected.not_to be_valid }
+
+ it 'reports error' do
+ expect(entry.errors).to include 'forward yaml variables should be a boolean value'
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/ci/config/entry/trigger_spec.rb b/spec/lib/gitlab/ci/config/entry/trigger_spec.rb
index 5b4289741f3..d0116c961d7 100644
--- a/spec/lib/gitlab/ci/config/entry/trigger_spec.rb
+++ b/spec/lib/gitlab/ci/config/entry/trigger_spec.rb
@@ -34,7 +34,7 @@ RSpec.describe Gitlab::Ci::Config::Entry::Trigger do
end
end
- context 'when trigger is a hash' do
+ context 'when trigger is a hash - cross-project' do
context 'when branch is provided' do
let(:config) { { project: 'some/project', branch: 'feature' } }
@@ -82,52 +82,84 @@ RSpec.describe Gitlab::Ci::Config::Entry::Trigger do
end
end
- describe '#include' do
- context 'with simple include' do
- let(:config) { { include: 'path/to/config.yml' } }
+ context 'when config contains unknown keys' do
+ let(:config) { { project: 'some/project', unknown: 123 } }
- it { is_expected.to be_valid }
+ describe '#valid?' do
+ it { is_expected.not_to be_valid }
+ end
- it 'returns a trigger configuration hash' do
- expect(subject.value).to eq(include: 'path/to/config.yml' )
+ describe '#errors' do
+ it 'returns an error about unknown config key' do
+ expect(subject.errors.first)
+ .to match /config contains unknown keys: unknown/
end
end
+ end
- context 'with project' do
- let(:config) { { project: 'some/project', include: 'path/to/config.yml' } }
+ context 'with forward' do
+ let(:config) { { project: 'some/project', forward: { pipeline_variables: true } } }
- it { is_expected.not_to be_valid }
+ before do
+ subject.compose!
+ end
- it 'returns an error' do
- expect(subject.errors.first)
- .to match /config contains unknown keys: project/
- end
+ it { is_expected.to be_valid }
+
+ it 'returns a trigger configuration hash' do
+ expect(subject.value).to eq(
+ project: 'some/project', forward: { pipeline_variables: true }
+ )
end
+ end
+ end
- context 'with branch' do
- let(:config) { { branch: 'feature', include: 'path/to/config.yml' } }
+ context 'when trigger is a hash - parent-child' do
+ context 'with simple include' do
+ let(:config) { { include: 'path/to/config.yml' } }
- it { is_expected.not_to be_valid }
+ it { is_expected.to be_valid }
- it 'returns an error' do
- expect(subject.errors.first)
- .to match /config contains unknown keys: branch/
- end
+ it 'returns a trigger configuration hash' do
+ expect(subject.value).to eq(include: 'path/to/config.yml' )
end
end
- context 'when config contains unknown keys' do
- let(:config) { { project: 'some/project', unknown: 123 } }
+ context 'with project' do
+ let(:config) { { project: 'some/project', include: 'path/to/config.yml' } }
- describe '#valid?' do
- it { is_expected.not_to be_valid }
+ it { is_expected.not_to be_valid }
+
+ it 'returns an error' do
+ expect(subject.errors.first)
+ .to match /config contains unknown keys: project/
end
+ end
- describe '#errors' do
- it 'returns an error about unknown config key' do
- expect(subject.errors.first)
- .to match /config contains unknown keys: unknown/
- end
+ context 'with branch' do
+ let(:config) { { branch: 'feature', include: 'path/to/config.yml' } }
+
+ it { is_expected.not_to be_valid }
+
+ it 'returns an error' do
+ expect(subject.errors.first)
+ .to match /config contains unknown keys: branch/
+ end
+ end
+
+ context 'with forward' do
+ let(:config) { { include: 'path/to/config.yml', forward: { yaml_variables: false } } }
+
+ before do
+ subject.compose!
+ end
+
+ it { is_expected.to be_valid }
+
+ it 'returns a trigger configuration hash' do
+ expect(subject.value).to eq(
+ include: 'path/to/config.yml', forward: { yaml_variables: false }
+ )
end
end
end
diff --git a/spec/lib/gitlab/ci/config/external/file/local_spec.rb b/spec/lib/gitlab/ci/config/external/file/local_spec.rb
index 3d1fc32a62d..dec3eebe7b1 100644
--- a/spec/lib/gitlab/ci/config/external/file/local_spec.rb
+++ b/spec/lib/gitlab/ci/config/external/file/local_spec.rb
@@ -81,6 +81,16 @@ RSpec.describe Gitlab::Ci::Config::External::File::Local do
expect(local_file.valid?).to be_falsy
end
end
+
+ context 'when the given sha is not valid' do
+ let(:location) { '/lib/gitlab/ci/templates/existent-file.yml' }
+ let(:sha) { ':' }
+
+ it 'returns false and adds an error message stating that included file does not exist' do
+ expect(local_file).not_to be_valid
+ expect(local_file.errors).to include("Sha #{sha} is not valid!")
+ end
+ end
end
describe '#content' do
diff --git a/spec/lib/gitlab/ci/config/yaml/tags/reference_spec.rb b/spec/lib/gitlab/ci/config/yaml/tags/reference_spec.rb
index c68dccd3455..bf89942bf14 100644
--- a/spec/lib/gitlab/ci/config/yaml/tags/reference_spec.rb
+++ b/spec/lib/gitlab/ci/config/yaml/tags/reference_spec.rb
@@ -69,6 +69,23 @@ RSpec.describe Gitlab::Ci::Config::Yaml::Tags::Reference do
end
end
+ context 'when the references are valid but do not match the config' do
+ let(:yaml) do
+ <<~YML
+ a: [1, 2]
+ b: [3, 4]
+ c: !reference [a, b]
+ YML
+ end
+
+ it 'raises a MissingReferenceError' do
+ expect { subject }.to raise_error(
+ Gitlab::Ci::Config::Yaml::Tags::Reference::MissingReferenceError,
+ '!reference ["a", "b"] could not be found'
+ )
+ end
+ end
+
context 'with arrays' do
let(:yaml) do
<<~YML
diff --git a/spec/lib/gitlab/ci/parsers/coverage/cobertura_spec.rb b/spec/lib/gitlab/ci/parsers/coverage/cobertura_spec.rb
index 546de2bee5c..65d85c7f1c0 100644
--- a/spec/lib/gitlab/ci/parsers/coverage/cobertura_spec.rb
+++ b/spec/lib/gitlab/ci/parsers/coverage/cobertura_spec.rb
@@ -1,700 +1,24 @@
# frozen_string_literal: true
-require 'fast_spec_helper'
+require 'spec_helper'
RSpec.describe Gitlab::Ci::Parsers::Coverage::Cobertura do
- describe '#parse!' do
- subject(:parse_report) { described_class.new.parse!(cobertura, coverage_report, project_path: project_path, worktree_paths: paths) }
+ let(:xml_data) { double }
+ let(:coverage_report) { double }
+ let(:project_path) { double }
+ let(:paths) { double }
- let(:coverage_report) { Gitlab::Ci::Reports::CoverageReports.new }
- let(:project_path) { 'foo/bar' }
- let(:paths) { ['app/user.rb'] }
+ subject(:parse_report) { described_class.new.parse!(xml_data, coverage_report, project_path: project_path, worktree_paths: paths) }
- let(:cobertura) do
- <<~EOF
- <coverage>
- #{sources_xml}
- #{classes_xml}
- </coverage>
- EOF
- end
-
- context 'when data is Cobertura style XML' do
- shared_examples_for 'ignoring sources, project_path, and worktree_paths' do
- context 'when there is no <class>' do
- let(:classes_xml) { '' }
-
- it 'parses XML and returns empty coverage' do
- expect { parse_report }.not_to raise_error
-
- expect(coverage_report.files).to eq({})
- end
- end
-
- context 'when there is a single <class>' do
- context 'with no lines' do
- let(:classes_xml) do
- <<~EOF
- <packages><package name="app"><classes>
- <class filename="app.rb"></class>
- </classes></package></packages>
- EOF
- end
-
- it 'parses XML and returns empty coverage' do
- expect { parse_report }.not_to raise_error
-
- expect(coverage_report.files).to eq({})
- end
- end
-
- context 'with a single line' do
- let(:classes_xml) do
- <<~EOF
- <packages><package name="app"><classes>
- <class filename="app.rb"><lines>
- <line number="1" hits="2"/>
- </lines></class>
- </classes></package></packages>
- EOF
- end
-
- it 'parses XML and returns a single file with coverage' do
- expect { parse_report }.not_to raise_error
-
- expect(coverage_report.files).to eq({ 'app.rb' => { 1 => 2 } })
- end
- end
-
- context 'without a package parent' do
- let(:classes_xml) do
- <<~EOF
- <packages>
- <class filename="app.rb"><lines>
- <line number="1" hits="2"/>
- </lines></class>
- </packages>
- EOF
- end
-
- it 'parses XML and returns a single file with coverage' do
- expect { parse_report }.not_to raise_error
-
- expect(coverage_report.files).to eq({ 'app.rb' => { 1 => 2 } })
- end
- end
-
- context 'with multiple lines and methods info' do
- let(:classes_xml) do
- <<~EOF
- <packages><package name="app"><classes>
- <class filename="app.rb"><methods/><lines>
- <line number="1" hits="2"/>
- <line number="2" hits="0"/>
- </lines></class>
- </classes></package></packages>
- EOF
- end
-
- it 'parses XML and returns a single file with coverage' do
- expect { parse_report }.not_to raise_error
-
- expect(coverage_report.files).to eq({ 'app.rb' => { 1 => 2, 2 => 0 } })
- end
- end
- end
-
- context 'when there are multiple <class>' do
- context 'without a package parent' do
- let(:classes_xml) do
- <<~EOF
- <packages>
- <class filename="app.rb"><methods/><lines>
- <line number="1" hits="2"/>
- </lines></class>
- <class filename="foo.rb"><methods/><lines>
- <line number="6" hits="1"/>
- </lines></class>
- </packages>
- EOF
- end
-
- it 'parses XML and returns coverage information per class' do
- expect { parse_report }.not_to raise_error
-
- expect(coverage_report.files).to eq({ 'app.rb' => { 1 => 2 }, 'foo.rb' => { 6 => 1 } })
- end
- end
-
- context 'with the same filename and different lines' do
- let(:classes_xml) do
- <<~EOF
- <packages><package name="app"><classes>
- <class filename="app.rb"><methods/><lines>
- <line number="1" hits="2"/>
- <line number="2" hits="0"/>
- </lines></class>
- <class filename="app.rb"><methods/><lines>
- <line number="6" hits="1"/>
- <line number="7" hits="1"/>
- </lines></class>
- </classes></package></packages>
- EOF
- end
-
- it 'parses XML and returns a single file with merged coverage' do
- expect { parse_report }.not_to raise_error
-
- expect(coverage_report.files).to eq({ 'app.rb' => { 1 => 2, 2 => 0, 6 => 1, 7 => 1 } })
- end
- end
-
- context 'with the same filename and lines' do
- let(:classes_xml) do
- <<~EOF
- <packages><package name="app"><classes>
- <class filename="app.rb"><methods/><lines>
- <line number="1" hits="2"/>
- <line number="2" hits="0"/>
- </lines></class>
- <class filename="app.rb"><methods/><lines>
- <line number="1" hits="1"/>
- <line number="2" hits="1"/>
- </lines></class>
- </classes></package></packages>
- EOF
- end
-
- it 'parses XML and returns a single file with summed-up coverage' do
- expect { parse_report }.not_to raise_error
-
- expect(coverage_report.files).to eq({ 'app.rb' => { 1 => 3, 2 => 1 } })
- end
- end
-
- context 'with missing filename' do
- let(:classes_xml) do
- <<~EOF
- <packages><package name="app"><classes>
- <class filename="app.rb"><methods/><lines>
- <line number="1" hits="2"/>
- <line number="2" hits="0"/>
- </lines></class>
- <class><methods/><lines>
- <line number="6" hits="1"/>
- <line number="7" hits="1"/>
- </lines></class>
- </classes></package></packages>
- EOF
- end
-
- it 'parses XML and ignores class with missing name' do
- expect { parse_report }.not_to raise_error
-
- expect(coverage_report.files).to eq({ 'app.rb' => { 1 => 2, 2 => 0 } })
- end
- end
-
- context 'with invalid line information' do
- let(:classes_xml) do
- <<~EOF
- <packages><package name="app"><classes>
- <class filename="app.rb"><methods/><lines>
- <line number="1" hits="2"/>
- <line number="2" hits="0"/>
- </lines></class>
- <class filename="app.rb"><methods/><lines>
- <line null="test" hits="1"/>
- <line number="7" hits="1"/>
- </lines></class>
- </classes></package></packages>
- EOF
- end
-
- it 'raises an error' do
- expect { parse_report }.to raise_error(described_class::InvalidLineInformationError)
- end
- end
- end
- end
-
- context 'when there is no <sources>' do
- let(:sources_xml) { '' }
-
- it_behaves_like 'ignoring sources, project_path, and worktree_paths'
- end
-
- context 'when there is an empty <sources>' do
- let(:sources_xml) { '<sources />' }
-
- it_behaves_like 'ignoring sources, project_path, and worktree_paths'
- end
-
- context 'when there is a <sources>' do
- context 'and has a single source with a pattern for Go projects' do
- let(:project_path) { 'local/go' } # Make sure we're not making false positives
- let(:sources_xml) do
- <<~EOF
- <sources>
- <source>/usr/local/go/src</source>
- </sources>
- EOF
- end
-
- it_behaves_like 'ignoring sources, project_path, and worktree_paths'
- end
-
- context 'and has multiple sources with a pattern for Go projects' do
- let(:project_path) { 'local/go' } # Make sure we're not making false positives
- let(:sources_xml) do
- <<~EOF
- <sources>
- <source>/usr/local/go/src</source>
- <source>/go/src</source>
- </sources>
- EOF
- end
-
- it_behaves_like 'ignoring sources, project_path, and worktree_paths'
- end
-
- context 'and has a single source but already is at the project root path' do
- let(:sources_xml) do
- <<~EOF
- <sources>
- <source>builds/#{project_path}</source>
- </sources>
- EOF
- end
-
- it_behaves_like 'ignoring sources, project_path, and worktree_paths'
- end
-
- context 'and has multiple sources but already are at the project root path' do
- let(:sources_xml) do
- <<~EOF
- <sources>
- <source>builds/#{project_path}/</source>
- <source>builds/somewhere/#{project_path}</source>
- </sources>
- EOF
- end
-
- it_behaves_like 'ignoring sources, project_path, and worktree_paths'
- end
-
- context 'and has a single source that is not at the project root path' do
- let(:sources_xml) do
- <<~EOF
- <sources>
- <source>builds/#{project_path}/app</source>
- </sources>
- EOF
- end
-
- context 'when there is no <class>' do
- let(:classes_xml) { '' }
-
- it 'parses XML and returns empty coverage' do
- expect { parse_report }.not_to raise_error
-
- expect(coverage_report.files).to eq({})
- end
- end
-
- context 'when there is a single <class>' do
- context 'with no lines' do
- let(:classes_xml) do
- <<~EOF
- <packages><package name="app"><classes>
- <class filename="user.rb"></class>
- </classes></package></packages>
- EOF
- end
-
- it 'parses XML and returns empty coverage' do
- expect { parse_report }.not_to raise_error
-
- expect(coverage_report.files).to eq({})
- end
- end
-
- context 'with a single line but the filename cannot be determined based on extracted source and worktree paths' do
- let(:classes_xml) do
- <<~EOF
- <packages><package name="app"><classes>
- <class filename="member.rb"><lines>
- <line number="1" hits="2"/>
- </lines></class>
- </classes></package></packages>
- EOF
- end
-
- it 'parses XML and returns empty coverage' do
- expect { parse_report }.not_to raise_error
-
- expect(coverage_report.files).to eq({})
- end
- end
-
- context 'with a single line' do
- let(:classes_xml) do
- <<~EOF
- <packages><package name="app"><classes>
- <class filename="user.rb"><lines>
- <line number="1" hits="2"/>
- </lines></class>
- </classes></package></packages>
- EOF
- end
-
- it 'parses XML and returns a single file with the filename relative to project root' do
- expect { parse_report }.not_to raise_error
-
- expect(coverage_report.files).to eq({ 'app/user.rb' => { 1 => 2 } })
- end
- end
-
- context 'with multiple lines and methods info' do
- let(:classes_xml) do
- <<~EOF
- <packages><package name="app"><classes>
- <class filename="user.rb"><methods/><lines>
- <line number="1" hits="2"/>
- <line number="2" hits="0"/>
- </lines></class>
- </classes></package></packages>
- EOF
- end
-
- it 'parses XML and returns a single file with the filename relative to project root' do
- expect { parse_report }.not_to raise_error
-
- expect(coverage_report.files).to eq({ 'app/user.rb' => { 1 => 2, 2 => 0 } })
- end
- end
- end
-
- context 'when there are multiple <class>' do
- context 'with the same filename but the filename cannot be determined based on extracted source and worktree paths' do
- let(:classes_xml) do
- <<~EOF
- <packages><package name="app"><classes>
- <class filename="member.rb"><methods/><lines>
- <line number="1" hits="2"/>
- <line number="2" hits="0"/>
- </lines></class>
- <class filename="member.rb"><methods/><lines>
- <line number="6" hits="1"/>
- <line number="7" hits="1"/>
- </lines></class>
- </classes></package></packages>
- EOF
- end
-
- it 'parses XML and returns empty coverage' do
- expect { parse_report }.not_to raise_error
-
- expect(coverage_report.files).to eq({})
- end
- end
-
- context 'without a parent package' do
- let(:classes_xml) do
- <<~EOF
- <packages>
- <class filename="user.rb"><methods/><lines>
- <line number="1" hits="2"/>
- <line number="2" hits="0"/>
- </lines></class>
- <class filename="user.rb"><methods/><lines>
- <line number="6" hits="1"/>
- <line number="7" hits="1"/>
- </lines></class>
- </packages>
- EOF
- end
-
- it 'parses XML and returns coverage information with the filename relative to project root' do
- expect { parse_report }.not_to raise_error
-
- expect(coverage_report.files).to eq({ 'app/user.rb' => { 1 => 2, 2 => 0, 6 => 1, 7 => 1 } })
- end
- end
-
- context 'with the same filename and different lines' do
- let(:classes_xml) do
- <<~EOF
- <packages><package name="app"><classes>
- <class filename="user.rb"><methods/><lines>
- <line number="1" hits="2"/>
- <line number="2" hits="0"/>
- </lines></class>
- <class filename="user.rb"><methods/><lines>
- <line number="6" hits="1"/>
- <line number="7" hits="1"/>
- </lines></class>
- </classes></package></packages>
- EOF
- end
-
- it 'parses XML and returns a single file with merged coverage, and with the filename relative to project root' do
- expect { parse_report }.not_to raise_error
-
- expect(coverage_report.files).to eq({ 'app/user.rb' => { 1 => 2, 2 => 0, 6 => 1, 7 => 1 } })
- end
- end
-
- context 'with the same filename and lines' do
- let(:classes_xml) do
- <<~EOF
- <packages><package name="app"><classes>
- <class filename="user.rb"><methods/><lines>
- <line number="1" hits="2"/>
- <line number="2" hits="0"/>
- </lines></class>
- <class filename="user.rb"><methods/><lines>
- <line number="1" hits="1"/>
- <line number="2" hits="1"/>
- </lines></class>
- </classes></package></packages>
- EOF
- end
-
- it 'parses XML and returns a single file with summed-up coverage, and with the filename relative to project root' do
- expect { parse_report }.not_to raise_error
-
- expect(coverage_report.files).to eq({ 'app/user.rb' => { 1 => 3, 2 => 1 } })
- end
- end
-
- context 'with missing filename' do
- let(:classes_xml) do
- <<~EOF
- <packages><package name="app"><classes>
- <class filename="user.rb"><methods/><lines>
- <line number="1" hits="2"/>
- <line number="2" hits="0"/>
- </lines></class>
- <class><methods/><lines>
- <line number="6" hits="1"/>
- <line number="7" hits="1"/>
- </lines></class>
- </classes></package></packages>
- EOF
- end
-
- it 'parses XML and ignores class with missing name' do
- expect { parse_report }.not_to raise_error
-
- expect(coverage_report.files).to eq({ 'app/user.rb' => { 1 => 2, 2 => 0 } })
- end
- end
-
- context 'with filename that cannot be determined based on extracted source and worktree paths' do
- let(:classes_xml) do
- <<~EOF
- <packages><package name="app"><classes>
- <class filename="user.rb"><methods/><lines>
- <line number="1" hits="2"/>
- <line number="2" hits="0"/>
- </lines></class>
- <class filename="member.rb"><methods/><lines>
- <line number="6" hits="1"/>
- <line number="7" hits="1"/>
- </lines></class>
- </classes></package></packages>
- EOF
- end
-
- it 'parses XML and ignores class with undetermined filename' do
- expect { parse_report }.not_to raise_error
-
- expect(coverage_report.files).to eq({ 'app/user.rb' => { 1 => 2, 2 => 0 } })
- end
- end
-
- context 'with invalid line information' do
- let(:classes_xml) do
- <<~EOF
- <packages><package name="app"><classes>
- <class filename="user.rb"><methods/><lines>
- <line number="1" hits="2"/>
- <line number="2" hits="0"/>
- </lines></class>
- <class filename="user.rb"><methods/><lines>
- <line null="test" hits="1"/>
- <line number="7" hits="1"/>
- </lines></class>
- </classes></package></packages>
- EOF
- end
-
- it 'raises an error' do
- expect { parse_report }.to raise_error(described_class::InvalidLineInformationError)
- end
- end
- end
- end
-
- context 'and has multiple sources that are not at the project root path' do
- let(:sources_xml) do
- <<~EOF
- <sources>
- <source>builds/#{project_path}/app1/</source>
- <source>builds/#{project_path}/app2/</source>
- </sources>
- EOF
- end
-
- context 'and a class filename is available under multiple extracted sources' do
- let(:paths) { ['app1/user.rb', 'app2/user.rb'] }
-
- let(:classes_xml) do
- <<~EOF
- <package name="app1">
- <classes>
- <class filename="user.rb"><lines>
- <line number="1" hits="2"/>
- </lines></class>
- </classes>
- </package>
- <package name="app2">
- <classes>
- <class filename="user.rb"><lines>
- <line number="2" hits="3"/>
- </lines></class>
- </classes>
- </package>
- EOF
- end
-
- it 'parses XML and returns the files with the filename relative to project root' do
- expect { parse_report }.not_to raise_error
-
- expect(coverage_report.files).to eq({
- 'app1/user.rb' => { 1 => 2 },
- 'app2/user.rb' => { 2 => 3 }
- })
- end
- end
-
- context 'and a class filename is available under one of the extracted sources' do
- let(:paths) { ['app1/member.rb', 'app2/user.rb', 'app2/pet.rb'] }
-
- let(:classes_xml) do
- <<~EOF
- <packages><package name="app"><classes>
- <class filename="user.rb"><lines>
- <line number="1" hits="2"/>
- </lines></class>
- </classes></package></packages>
- EOF
- end
-
- it 'parses XML and returns a single file with the filename relative to project root using the extracted source where it is first found under' do
- expect { parse_report }.not_to raise_error
-
- expect(coverage_report.files).to eq({ 'app2/user.rb' => { 1 => 2 } })
- end
- end
-
- context 'and a class filename is not found under any of the extracted sources' do
- let(:paths) { ['app1/member.rb', 'app2/pet.rb'] }
-
- let(:classes_xml) do
- <<~EOF
- <packages><package name="app"><classes>
- <class filename="user.rb"><lines>
- <line number="1" hits="2"/>
- </lines></class>
- </classes></package></packages>
- EOF
- end
-
- it 'parses XML and returns empty coverage' do
- expect { parse_report }.not_to raise_error
-
- expect(coverage_report.files).to eq({})
- end
- end
-
- context 'and a class filename is not found under any of the extracted sources within the iteratable limit' do
- let(:paths) { ['app2/user.rb'] }
-
- let(:classes_xml) do
- <<~EOF
- <packages><package name="app"><classes>
- <class filename="record.rb"><lines>
- <line number="1" hits="2"/>
- </lines></class>
- <class filename="user.rb"><lines>
- <line number="1" hits="2"/>
- </lines></class>
- </classes></package></packages>
- EOF
- end
-
- before do
- stub_const("#{described_class}::MAX_SOURCES", 1)
- end
-
- it 'parses XML and returns empty coverage' do
- expect { parse_report }.not_to raise_error
-
- expect(coverage_report.files).to eq({})
- end
- end
- end
- end
-
- shared_examples_for 'non-smart parsing' do
- let(:sources_xml) do
- <<~EOF
- <sources>
- <source>builds/foo/bar/app</source>
- </sources>
- EOF
- end
-
- let(:classes_xml) do
- <<~EOF
- <packages><package name="app"><classes>
- <class filename="user.rb"><lines>
- <line number="1" hits="2"/>
- </lines></class>
- </classes></package></packages>
- EOF
- end
-
- it 'parses XML and returns filenames unchanged just as how they are found in the class node' do
- expect { parse_report }.not_to raise_error
-
- expect(coverage_report.files).to eq({ 'user.rb' => { 1 => 2 } })
- end
- end
-
- context 'when project_path is not present' do
- let(:project_path) { nil }
- let(:paths) { ['app/user.rb'] }
-
- it_behaves_like 'non-smart parsing'
- end
-
- context 'when worktree_paths is not present' do
- let(:project_path) { 'foo/bar' }
- let(:paths) { nil }
-
- it_behaves_like 'non-smart parsing'
- end
+ before do
+ allow_next_instance_of(Nokogiri::XML::SAX::Parser) do |document|
+ allow(document).to receive(:parse)
end
+ end
- context 'when data is not Cobertura style XML' do
- let(:cobertura) { { coverage: '12%' }.to_json }
+ it 'uses Sax parser' do
+ expect(Gitlab::Ci::Parsers::Coverage::SaxDocument).to receive(:new)
- it 'raises an error' do
- expect { parse_report }.to raise_error(described_class::InvalidXMLError)
- end
- end
+ parse_report
end
end
diff --git a/spec/lib/gitlab/ci/parsers/coverage/sax_document_spec.rb b/spec/lib/gitlab/ci/parsers/coverage/sax_document_spec.rb
new file mode 100644
index 00000000000..0580cb9922b
--- /dev/null
+++ b/spec/lib/gitlab/ci/parsers/coverage/sax_document_spec.rb
@@ -0,0 +1,725 @@
+# frozen_string_literal: true
+
+require 'fast_spec_helper'
+
+RSpec.describe Gitlab::Ci::Parsers::Coverage::SaxDocument do
+ subject(:parse_report) { Nokogiri::XML::SAX::Parser.new(described_class.new(coverage_report, project_path, paths)).parse(cobertura) }
+
+ describe '#parse!' do
+ let(:coverage_report) { Gitlab::Ci::Reports::CoverageReports.new }
+ let(:project_path) { 'foo/bar' }
+ let(:paths) { ['app/user.rb'] }
+
+ let(:cobertura) do
+ <<~EOF
+ <coverage>
+ #{sources_xml}
+ #{classes_xml}
+ </coverage>
+ EOF
+ end
+
+ context 'when data is Cobertura style XML' do
+ shared_examples_for 'ignoring sources, project_path, and worktree_paths' do
+ context 'when there is no <class>' do
+ let(:classes_xml) { '' }
+
+ it 'parses XML and returns empty coverage' do
+ expect { parse_report }.not_to raise_error
+
+ expect(coverage_report.files).to eq({})
+ end
+ end
+
+ context 'when there is a single <class>' do
+ context 'with no lines' do
+ let(:classes_xml) do
+ <<~EOF
+ <packages><package name="app"><classes>
+ <class filename="app.rb"></class>
+ </classes></package></packages>
+ EOF
+ end
+
+ it 'parses XML and returns empty coverage' do
+ expect { parse_report }.not_to raise_error
+
+ expect(coverage_report.files).to eq({})
+ end
+ end
+
+ context 'with a single line' do
+ let(:classes_xml) do
+ <<~EOF
+ <packages><package name="app"><classes>
+ <class filename="app.rb"><lines>
+ <line number="1" hits="2"/>
+ </lines></class>
+ </classes></package></packages>
+ EOF
+ end
+
+ it 'parses XML and returns a single file with coverage' do
+ expect { parse_report }.not_to raise_error
+
+ expect(coverage_report.files).to eq({ 'app.rb' => { 1 => 2 } })
+ end
+ end
+
+ context 'without a package parent' do
+ let(:classes_xml) do
+ <<~EOF
+ <packages>
+ <class filename="app.rb"><lines>
+ <line number="1" hits="2"/>
+ </lines></class>
+ </packages>
+ EOF
+ end
+
+ it 'parses XML and returns a single file with coverage' do
+ expect { parse_report }.not_to raise_error
+
+ expect(coverage_report.files).to eq({ 'app.rb' => { 1 => 2 } })
+ end
+ end
+
+ context 'with multiple lines and methods info' do
+ let(:classes_xml) do
+ <<~EOF
+ <packages><package name="app"><classes>
+ <class filename="app.rb"><methods/><lines>
+ <line number="1" hits="2"/>
+ <line number="2" hits="0"/>
+ </lines></class>
+ </classes></package></packages>
+ EOF
+ end
+
+ it 'parses XML and returns a single file with coverage' do
+ expect { parse_report }.not_to raise_error
+
+ expect(coverage_report.files).to eq({ 'app.rb' => { 1 => 2, 2 => 0 } })
+ end
+ end
+ end
+
+ context 'when there are multiple packages' do
+ let(:cobertura) do
+ <<~EOF
+ <coverage>
+ <packages><package name="app1"><classes>
+ <class filename="app1.rb"><lines>
+ <line number="1" hits="2"/>
+ </lines></class>
+ </classes></package></packages>
+ <packages><package name="app2"><classes>
+ <class filename="app2.rb"><lines>
+ <line number="11" hits="3"/>
+ </lines></class>
+ </classes></package></packages>
+ </coverage>
+ EOF
+ end
+
+ it 'parses XML and returns coverage information per class' do
+ expect { parse_report }.not_to raise_error
+
+ expect(coverage_report.files).to eq({ 'app1.rb' => { 1 => 2 }, 'app2.rb' => { 11 => 3 } })
+ end
+ end
+
+ context 'when there are multiple <class>' do
+ context 'without a package parent' do
+ let(:classes_xml) do
+ <<~EOF
+ <packages>
+ <class filename="app.rb"><methods/><lines>
+ <line number="1" hits="2"/>
+ </lines></class>
+ <class filename="foo.rb"><methods/><lines>
+ <line number="6" hits="1"/>
+ </lines></class>
+ </packages>
+ EOF
+ end
+
+ it 'parses XML and returns coverage information per class' do
+ expect { parse_report }.not_to raise_error
+
+ expect(coverage_report.files).to eq({ 'app.rb' => { 1 => 2 }, 'foo.rb' => { 6 => 1 } })
+ end
+ end
+
+ context 'with the same filename and different lines' do
+ let(:classes_xml) do
+ <<~EOF
+ <packages><package name="app"><classes>
+ <class filename="app.rb"><methods/><lines>
+ <line number="1" hits="2"/>
+ <line number="2" hits="0"/>
+ </lines></class>
+ <class filename="app.rb"><methods/><lines>
+ <line number="6" hits="1"/>
+ <line number="7" hits="1"/>
+ </lines></class>
+ </classes></package></packages>
+ EOF
+ end
+
+ it 'parses XML and returns a single file with merged coverage' do
+ expect { parse_report }.not_to raise_error
+
+ expect(coverage_report.files).to eq({ 'app.rb' => { 1 => 2, 2 => 0, 6 => 1, 7 => 1 } })
+ end
+ end
+
+ context 'with the same filename and lines' do
+ let(:classes_xml) do
+ <<~EOF
+ <packages><package name="app"><classes>
+ <class filename="app.rb"><methods/><lines>
+ <line number="1" hits="2"/>
+ <line number="2" hits="0"/>
+ </lines></class>
+ <class filename="app.rb"><methods/><lines>
+ <line number="1" hits="1"/>
+ <line number="2" hits="1"/>
+ </lines></class>
+ </classes></package></packages>
+ EOF
+ end
+
+ it 'parses XML and returns a single file with summed-up coverage' do
+ expect { parse_report }.not_to raise_error
+
+ expect(coverage_report.files).to eq({ 'app.rb' => { 1 => 3, 2 => 1 } })
+ end
+ end
+
+ context 'with missing filename' do
+ let(:classes_xml) do
+ <<~EOF
+ <packages><package name="app"><classes>
+ <class filename="app.rb"><methods/><lines>
+ <line number="1" hits="2"/>
+ <line number="2" hits="0"/>
+ </lines></class>
+ <class><methods/><lines>
+ <line number="6" hits="1"/>
+ <line number="7" hits="1"/>
+ </lines></class>
+ </classes></package></packages>
+ EOF
+ end
+
+ it 'parses XML and ignores class with missing name' do
+ expect { parse_report }.not_to raise_error
+
+ expect(coverage_report.files).to eq({ 'app.rb' => { 1 => 2, 2 => 0 } })
+ end
+ end
+
+ context 'with invalid line information' do
+ let(:classes_xml) do
+ <<~EOF
+ <packages><package name="app"><classes>
+ <class filename="app.rb"><methods/><lines>
+ <line number="1" hits="2"/>
+ <line number="2" hits="0"/>
+ </lines></class>
+ <class filename="app.rb"><methods/><lines>
+ <line null="test" hits="1"/>
+ <line number="7" hits="1"/>
+ </lines></class>
+ </classes></package></packages>
+ EOF
+ end
+
+ it 'raises an error' do
+ expect { parse_report }.to raise_error(Gitlab::Ci::Parsers::Coverage::Cobertura::InvalidLineInformationError)
+ end
+ end
+ end
+ end
+
+ context 'when there is no <sources>' do
+ let(:sources_xml) { '' }
+
+ it_behaves_like 'ignoring sources, project_path, and worktree_paths'
+ end
+
+ context 'when there is an empty <sources>' do
+ let(:sources_xml) { '<sources />' }
+
+ it_behaves_like 'ignoring sources, project_path, and worktree_paths'
+ end
+
+ context 'when there is a <sources>' do
+ context 'and has a single source with a pattern for Go projects' do
+ let(:project_path) { 'local/go' } # Make sure we're not making false positives
+ let(:sources_xml) do
+ <<~EOF
+ <sources>
+ <source>/usr/local/go/src</source>
+ </sources>
+ EOF
+ end
+
+ it_behaves_like 'ignoring sources, project_path, and worktree_paths'
+ end
+
+ context 'and has multiple sources with a pattern for Go projects' do
+ let(:project_path) { 'local/go' } # Make sure we're not making false positives
+ let(:sources_xml) do
+ <<~EOF
+ <sources>
+ <source>/usr/local/go/src</source>
+ <source>/go/src</source>
+ </sources>
+ EOF
+ end
+
+ it_behaves_like 'ignoring sources, project_path, and worktree_paths'
+ end
+
+ context 'and has a single source but already is at the project root path' do
+ let(:sources_xml) do
+ <<~EOF
+ <sources>
+ <source>builds/#{project_path}</source>
+ </sources>
+ EOF
+ end
+
+ it_behaves_like 'ignoring sources, project_path, and worktree_paths'
+ end
+
+ context 'and has multiple sources but already are at the project root path' do
+ let(:sources_xml) do
+ <<~EOF
+ <sources>
+ <source>builds/#{project_path}/</source>
+ <source>builds/somewhere/#{project_path}</source>
+ </sources>
+ EOF
+ end
+
+ it_behaves_like 'ignoring sources, project_path, and worktree_paths'
+ end
+
+ context 'and has a single source that is not at the project root path' do
+ let(:sources_xml) do
+ <<~EOF
+ <sources>
+ <source>builds/#{project_path}/app</source>
+ </sources>
+ EOF
+ end
+
+ context 'when there is no <class>' do
+ let(:classes_xml) { '' }
+
+ it 'parses XML and returns empty coverage' do
+ expect { parse_report }.not_to raise_error
+
+ expect(coverage_report.files).to eq({})
+ end
+ end
+
+ context 'when there is a single <class>' do
+ context 'with no lines' do
+ let(:classes_xml) do
+ <<~EOF
+ <packages><package name="app"><classes>
+ <class filename="user.rb"></class>
+ </classes></package></packages>
+ EOF
+ end
+
+ it 'parses XML and returns empty coverage' do
+ expect { parse_report }.not_to raise_error
+
+ expect(coverage_report.files).to eq({})
+ end
+ end
+
+ context 'with a single line but the filename cannot be determined based on extracted source and worktree paths' do
+ let(:classes_xml) do
+ <<~EOF
+ <packages><package name="app"><classes>
+ <class filename="member.rb"><lines>
+ <line number="1" hits="2"/>
+ </lines></class>
+ </classes></package></packages>
+ EOF
+ end
+
+ it 'parses XML and returns empty coverage' do
+ expect { parse_report }.not_to raise_error
+
+ expect(coverage_report.files).to eq({})
+ end
+ end
+
+ context 'with a single line' do
+ let(:classes_xml) do
+ <<~EOF
+ <packages><package name="app"><classes>
+ <class filename="user.rb"><lines>
+ <line number="1" hits="2"/>
+ </lines></class>
+ </classes></package></packages>
+ EOF
+ end
+
+ it 'parses XML and returns a single file with the filename relative to project root' do
+ expect { parse_report }.not_to raise_error
+
+ expect(coverage_report.files).to eq({ 'app/user.rb' => { 1 => 2 } })
+ end
+ end
+
+ context 'with multiple lines and methods info' do
+ let(:classes_xml) do
+ <<~EOF
+ <packages><package name="app"><classes>
+ <class filename="user.rb"><methods/><lines>
+ <line number="1" hits="2"/>
+ <line number="2" hits="0"/>
+ </lines></class>
+ </classes></package></packages>
+ EOF
+ end
+
+ it 'parses XML and returns a single file with the filename relative to project root' do
+ expect { parse_report }.not_to raise_error
+
+ expect(coverage_report.files).to eq({ 'app/user.rb' => { 1 => 2, 2 => 0 } })
+ end
+ end
+ end
+
+ context 'when there are multiple <class>' do
+ context 'with the same filename but the filename cannot be determined based on extracted source and worktree paths' do
+ let(:classes_xml) do
+ <<~EOF
+ <packages><package name="app"><classes>
+ <class filename="member.rb"><methods/><lines>
+ <line number="1" hits="2"/>
+ <line number="2" hits="0"/>
+ </lines></class>
+ <class filename="member.rb"><methods/><lines>
+ <line number="6" hits="1"/>
+ <line number="7" hits="1"/>
+ </lines></class>
+ </classes></package></packages>
+ EOF
+ end
+
+ it 'parses XML and returns empty coverage' do
+ expect { parse_report }.not_to raise_error
+
+ expect(coverage_report.files).to eq({})
+ end
+ end
+
+ context 'without a parent package' do
+ let(:classes_xml) do
+ <<~EOF
+ <packages>
+ <class filename="user.rb"><methods/><lines>
+ <line number="1" hits="2"/>
+ <line number="2" hits="0"/>
+ </lines></class>
+ <class filename="user.rb"><methods/><lines>
+ <line number="6" hits="1"/>
+ <line number="7" hits="1"/>
+ </lines></class>
+ </packages>
+ EOF
+ end
+
+ it 'parses XML and returns coverage information with the filename relative to project root' do
+ expect { parse_report }.not_to raise_error
+
+ expect(coverage_report.files).to eq({ 'app/user.rb' => { 1 => 2, 2 => 0, 6 => 1, 7 => 1 } })
+ end
+ end
+
+ context 'with the same filename and different lines' do
+ let(:classes_xml) do
+ <<~EOF
+ <packages><package name="app"><classes>
+ <class filename="user.rb"><methods/><lines>
+ <line number="1" hits="2"/>
+ <line number="2" hits="0"/>
+ </lines></class>
+ <class filename="user.rb"><methods/><lines>
+ <line number="6" hits="1"/>
+ <line number="7" hits="1"/>
+ </lines></class>
+ </classes></package></packages>
+ EOF
+ end
+
+ it 'parses XML and returns a single file with merged coverage, and with the filename relative to project root' do
+ expect { parse_report }.not_to raise_error
+
+ expect(coverage_report.files).to eq({ 'app/user.rb' => { 1 => 2, 2 => 0, 6 => 1, 7 => 1 } })
+ end
+ end
+
+ context 'with the same filename and lines' do
+ let(:classes_xml) do
+ <<~EOF
+ <packages><package name="app"><classes>
+ <class filename="user.rb"><methods/><lines>
+ <line number="1" hits="2"/>
+ <line number="2" hits="0"/>
+ </lines></class>
+ <class filename="user.rb"><methods/><lines>
+ <line number="1" hits="1"/>
+ <line number="2" hits="1"/>
+ </lines></class>
+ </classes></package></packages>
+ EOF
+ end
+
+ it 'parses XML and returns a single file with summed-up coverage, and with the filename relative to project root' do
+ expect { parse_report }.not_to raise_error
+
+ expect(coverage_report.files).to eq({ 'app/user.rb' => { 1 => 3, 2 => 1 } })
+ end
+ end
+
+ context 'with missing filename' do
+ let(:classes_xml) do
+ <<~EOF
+ <packages><package name="app"><classes>
+ <class filename="user.rb"><methods/><lines>
+ <line number="1" hits="2"/>
+ <line number="2" hits="0"/>
+ </lines></class>
+ <class><methods/><lines>
+ <line number="6" hits="1"/>
+ <line number="7" hits="1"/>
+ </lines></class>
+ </classes></package></packages>
+ EOF
+ end
+
+ it 'parses XML and ignores class with missing name' do
+ expect { parse_report }.not_to raise_error
+
+ expect(coverage_report.files).to eq({ 'app/user.rb' => { 1 => 2, 2 => 0 } })
+ end
+ end
+
+ context 'with filename that cannot be determined based on extracted source and worktree paths' do
+ let(:classes_xml) do
+ <<~EOF
+ <packages><package name="app"><classes>
+ <class filename="user.rb"><methods/><lines>
+ <line number="1" hits="2"/>
+ <line number="2" hits="0"/>
+ </lines></class>
+ <class filename="member.rb"><methods/><lines>
+ <line number="6" hits="1"/>
+ <line number="7" hits="1"/>
+ </lines></class>
+ </classes></package></packages>
+ EOF
+ end
+
+ it 'parses XML and ignores class with undetermined filename' do
+ expect { parse_report }.not_to raise_error
+
+ expect(coverage_report.files).to eq({ 'app/user.rb' => { 1 => 2, 2 => 0 } })
+ end
+ end
+
+ context 'with invalid line information' do
+ let(:classes_xml) do
+ <<~EOF
+ <packages><package name="app"><classes>
+ <class filename="user.rb"><methods/><lines>
+ <line number="1" hits="2"/>
+ <line number="2" hits="0"/>
+ </lines></class>
+ <class filename="user.rb"><methods/><lines>
+ <line null="test" hits="1"/>
+ <line number="7" hits="1"/>
+ </lines></class>
+ </classes></package></packages>
+ EOF
+ end
+
+ it 'raises an error' do
+ expect { parse_report }.to raise_error(Gitlab::Ci::Parsers::Coverage::Cobertura::InvalidLineInformationError)
+ end
+ end
+ end
+ end
+
+ context 'and has multiple sources that are not at the project root path' do
+ let(:sources_xml) do
+ <<~EOF
+ <sources>
+ <source>builds/#{project_path}/app1/</source>
+ <source>builds/#{project_path}/app2/</source>
+ </sources>
+ EOF
+ end
+
+ context 'and a class filename is available under multiple extracted sources' do
+ let(:paths) { ['app1/user.rb', 'app2/user.rb'] }
+
+ let(:classes_xml) do
+ <<~EOF
+ <package name="app1">
+ <classes>
+ <class filename="user.rb"><lines>
+ <line number="1" hits="2"/>
+ </lines></class>
+ </classes>
+ </package>
+ <package name="app2">
+ <classes>
+ <class filename="user.rb"><lines>
+ <line number="2" hits="3"/>
+ </lines></class>
+ </classes>
+ </package>
+ EOF
+ end
+
+ it 'parses XML and returns the files with the filename relative to project root' do
+ expect { parse_report }.not_to raise_error
+
+ expect(coverage_report.files).to eq({
+ 'app1/user.rb' => { 1 => 2 },
+ 'app2/user.rb' => { 2 => 3 }
+ })
+ end
+ end
+
+ context 'and a class filename is available under one of the extracted sources' do
+ let(:paths) { ['app1/member.rb', 'app2/user.rb', 'app2/pet.rb'] }
+
+ let(:classes_xml) do
+ <<~EOF
+ <packages><package name="app"><classes>
+ <class filename="user.rb"><lines>
+ <line number="1" hits="2"/>
+ </lines></class>
+ </classes></package></packages>
+ EOF
+ end
+
+ it 'parses XML and returns a single file with the filename relative to project root using the extracted source where it is first found under' do
+ expect { parse_report }.not_to raise_error
+
+ expect(coverage_report.files).to eq({ 'app2/user.rb' => { 1 => 2 } })
+ end
+ end
+
+ context 'and a class filename is not found under any of the extracted sources' do
+ let(:paths) { ['app1/member.rb', 'app2/pet.rb'] }
+
+ let(:classes_xml) do
+ <<~EOF
+ <packages><package name="app"><classes>
+ <class filename="user.rb"><lines>
+ <line number="1" hits="2"/>
+ </lines></class>
+ </classes></package></packages>
+ EOF
+ end
+
+ it 'parses XML and returns empty coverage' do
+ expect { parse_report }.not_to raise_error
+
+ expect(coverage_report.files).to eq({})
+ end
+ end
+
+ context 'and a class filename is not found under any of the extracted sources within the iteratable limit' do
+ let(:paths) { ['app2/user.rb'] }
+
+ let(:classes_xml) do
+ <<~EOF
+ <packages><package name="app"><classes>
+ <class filename="record.rb"><lines>
+ <line number="1" hits="2"/>
+ </lines></class>
+ <class filename="user.rb"><lines>
+ <line number="1" hits="2"/>
+ </lines></class>
+ </classes></package></packages>
+ EOF
+ end
+
+ before do
+ stub_const("#{described_class}::MAX_SOURCES", 1)
+ end
+
+ it 'parses XML and returns empty coverage' do
+ expect { parse_report }.not_to raise_error
+
+ expect(coverage_report.files).to eq({})
+ end
+ end
+ end
+ end
+
+ shared_examples_for 'non-smart parsing' do
+ let(:sources_xml) do
+ <<~EOF
+ <sources>
+ <source>builds/foo/bar/app</source>
+ </sources>
+ EOF
+ end
+
+ let(:classes_xml) do
+ <<~EOF
+ <packages><package name="app"><classes>
+ <class filename="user.rb"><lines>
+ <line number="1" hits="2"/>
+ </lines></class>
+ </classes></package></packages>
+ EOF
+ end
+
+ it 'parses XML and returns filenames unchanged just as how they are found in the class node' do
+ expect { parse_report }.not_to raise_error
+
+ expect(coverage_report.files).to eq({ 'user.rb' => { 1 => 2 } })
+ end
+ end
+
+ context 'when project_path is not present' do
+ let(:project_path) { nil }
+ let(:paths) { ['app/user.rb'] }
+
+ it_behaves_like 'non-smart parsing'
+ end
+
+ context 'when worktree_paths is not present' do
+ let(:project_path) { 'foo/bar' }
+ let(:paths) { nil }
+
+ it_behaves_like 'non-smart parsing'
+ end
+ end
+
+ context 'when data is not Cobertura style XML' do
+ let(:cobertura) { { coverage: '12%' }.to_json }
+
+ it 'raises an error' do
+ expect { parse_report }.to raise_error(Gitlab::Ci::Parsers::Coverage::Cobertura::InvalidXMLError)
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/ci/parsers/security/common_spec.rb b/spec/lib/gitlab/ci/parsers/security/common_spec.rb
index 7eec78ff186..1e96c717a4f 100644
--- a/spec/lib/gitlab/ci/parsers/security/common_spec.rb
+++ b/spec/lib/gitlab/ci/parsers/security/common_spec.rb
@@ -26,8 +26,6 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Common do
allow(parser).to receive(:tracking_data).and_return(tracking_data)
allow(parser).to receive(:create_flags).and_return(vulnerability_flags_data)
end
-
- artifact.each_blob { |blob| described_class.parse!(blob, report, vulnerability_finding_signatures_enabled) }
end
describe 'schema validation' do
@@ -40,40 +38,50 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Common do
allow(validator_class).to receive(:new).and_call_original
end
- context 'when enforce_security_report_validation is enabled' do
+ context 'when show_report_validation_warnings is enabled' do
before do
- stub_feature_flags(enforce_security_report_validation: true)
+ stub_feature_flags(show_report_validation_warnings: true)
end
- context 'when the validate flag is set as `true`' do
- let(:validate) { true }
+ context 'when the validate flag is set to `false`' do
+ let(:validate) { false }
+ let(:valid?) { false }
+ let(:errors) { ['foo'] }
- it 'instantiates the validator with correct params' do
- parse_report
+ before do
+ allow_next_instance_of(validator_class) do |instance|
+ allow(instance).to receive(:valid?).and_return(valid?)
+ allow(instance).to receive(:errors).and_return(errors)
+ end
- expect(validator_class).to have_received(:new).with(report.type, {})
+ allow(parser).to receive_messages(create_scanner: true, create_scan: true)
end
- context 'when the report data is valid according to the schema' do
- let(:valid?) { true }
+ it 'instantiates the validator with correct params' do
+ parse_report
- before do
- allow_next_instance_of(validator_class) do |instance|
- allow(instance).to receive(:valid?).and_return(valid?)
- allow(instance).to receive(:errors).and_return([])
- end
+ expect(validator_class).to have_received(:new).with(report.type, {}, report.version)
+ end
- allow(parser).to receive_messages(create_scanner: true, create_scan: true)
+ context 'when the report data is not valid according to the schema' do
+ it 'adds warnings to the report' do
+ expect { parse_report }.to change { report.warnings }.from([]).to([{ message: 'foo', type: 'Schema' }])
end
- it 'does not add errors to the report' do
- expect { parse_report }.not_to change { report.errors }.from([])
+ it 'keeps the execution flow as normal' do
+ parse_report
+
+ expect(parser).to have_received(:create_scanner)
+ expect(parser).to have_received(:create_scan)
end
+ end
- it 'adds the schema validation status to the report' do
- parse_report
+ context 'when the report data is valid according to the schema' do
+ let(:valid?) { true }
+ let(:errors) { [] }
- expect(report.schema_validation_status).to eq(:valid_schema)
+ it 'does not add warnings to the report' do
+ expect { parse_report }.not_to change { report.errors }
end
it 'keeps the execution flow as normal' do
@@ -83,42 +91,62 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Common do
expect(parser).to have_received(:create_scan)
end
end
+ end
- context 'when the report data is not valid according to the schema' do
- let(:valid?) { false }
-
- before do
- allow_next_instance_of(validator_class) do |instance|
- allow(instance).to receive(:valid?).and_return(valid?)
- allow(instance).to receive(:errors).and_return(['foo'])
- end
+ context 'when the validate flag is set to `true`' do
+ let(:validate) { true }
+ let(:valid?) { false }
+ let(:errors) { ['foo'] }
- allow(parser).to receive_messages(create_scanner: true, create_scan: true)
+ before do
+ allow_next_instance_of(validator_class) do |instance|
+ allow(instance).to receive(:valid?).and_return(valid?)
+ allow(instance).to receive(:errors).and_return(errors)
end
+ allow(parser).to receive_messages(create_scanner: true, create_scan: true)
+ end
+
+ it 'instantiates the validator with correct params' do
+ parse_report
+
+ expect(validator_class).to have_received(:new).with(report.type, {}, report.version)
+ end
+
+ context 'when the report data is not valid according to the schema' do
it 'adds errors to the report' do
expect { parse_report }.to change { report.errors }.from([]).to([{ message: 'foo', type: 'Schema' }])
end
- it 'adds the schema validation status to the report' do
+ it 'does not try to create report entities' do
parse_report
- expect(report.schema_validation_status).to eq(:invalid_schema)
+ expect(parser).not_to have_received(:create_scanner)
+ expect(parser).not_to have_received(:create_scan)
+ end
+ end
+
+ context 'when the report data is valid according to the schema' do
+ let(:valid?) { true }
+ let(:errors) { [] }
+
+ it 'does not add errors to the report' do
+ expect { parse_report }.not_to change { report.errors }.from([])
end
- it 'does not try to create report entities' do
+ it 'keeps the execution flow as normal' do
parse_report
- expect(parser).not_to have_received(:create_scanner)
- expect(parser).not_to have_received(:create_scan)
+ expect(parser).to have_received(:create_scanner)
+ expect(parser).to have_received(:create_scan)
end
end
end
end
- context 'when enforce_security_report_validation is disabled' do
+ context 'when show_report_validation_warnings is disabled' do
before do
- stub_feature_flags(enforce_security_report_validation: false)
+ stub_feature_flags(show_report_validation_warnings: false)
end
context 'when the validate flag is set as `false`' do
@@ -147,7 +175,7 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Common do
it 'instantiates the validator with correct params' do
parse_report
- expect(validator_class).to have_received(:new).with(report.type, {})
+ expect(validator_class).to have_received(:new).with(report.type, {}, report.version)
end
context 'when the report data is not valid according to the schema' do
@@ -181,265 +209,283 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Common do
end
end
- describe 'parsing finding.name' do
- let(:artifact) { build(:ci_job_artifact, :common_security_report_with_blank_names) }
-
- context 'when message is provided' do
- it 'sets message from the report as a finding name' do
- finding = report.findings.find { |x| x.compare_key == 'CVE-1020' }
- expected_name = Gitlab::Json.parse(finding.raw_metadata)['message']
-
- expect(finding.name).to eq(expected_name)
- end
+ context 'report parsing' do
+ before do
+ artifact.each_blob { |blob| described_class.parse!(blob, report, vulnerability_finding_signatures_enabled) }
end
- context 'when message is not provided' do
- context 'and name is provided' do
- it 'sets name from the report as a name' do
- finding = report.findings.find { |x| x.compare_key == 'CVE-1030' }
- expected_name = Gitlab::Json.parse(finding.raw_metadata)['name']
+ describe 'parsing finding.name' do
+ let(:artifact) { build(:ci_job_artifact, :common_security_report_with_blank_names) }
+
+ context 'when message is provided' do
+ it 'sets message from the report as a finding name' do
+ finding = report.findings.find { |x| x.compare_key == 'CVE-1020' }
+ expected_name = Gitlab::Json.parse(finding.raw_metadata)['message']
expect(finding.name).to eq(expected_name)
end
end
- context 'and name is not provided' do
- context 'when CVE identifier exists' do
- it 'combines identifier with location to create name' do
- finding = report.findings.find { |x| x.compare_key == 'CVE-2017-11429' }
- expect(finding.name).to eq("CVE-2017-11429 in yarn.lock")
+ context 'when message is not provided' do
+ context 'and name is provided' do
+ it 'sets name from the report as a name' do
+ finding = report.findings.find { |x| x.compare_key == 'CVE-1030' }
+ expected_name = Gitlab::Json.parse(finding.raw_metadata)['name']
+
+ expect(finding.name).to eq(expected_name)
end
end
- context 'when CWE identifier exists' do
- it 'combines identifier with location to create name' do
- finding = report.findings.find { |x| x.compare_key == 'CWE-2017-11429' }
- expect(finding.name).to eq("CWE-2017-11429 in yarn.lock")
+ context 'and name is not provided' do
+ context 'when CVE identifier exists' do
+ it 'combines identifier with location to create name' do
+ finding = report.findings.find { |x| x.compare_key == 'CVE-2017-11429' }
+ expect(finding.name).to eq("CVE-2017-11429 in yarn.lock")
+ end
end
- end
- context 'when neither CVE nor CWE identifier exist' do
- it 'combines identifier with location to create name' do
- finding = report.findings.find { |x| x.compare_key == 'OTHER-2017-11429' }
- expect(finding.name).to eq("other-2017-11429 in yarn.lock")
+ context 'when CWE identifier exists' do
+ it 'combines identifier with location to create name' do
+ finding = report.findings.find { |x| x.compare_key == 'CWE-2017-11429' }
+ expect(finding.name).to eq("CWE-2017-11429 in yarn.lock")
+ end
+ end
+
+ context 'when neither CVE nor CWE identifier exist' do
+ it 'combines identifier with location to create name' do
+ finding = report.findings.find { |x| x.compare_key == 'OTHER-2017-11429' }
+ expect(finding.name).to eq("other-2017-11429 in yarn.lock")
+ end
end
end
end
end
- end
- describe 'parsing finding.details' do
- context 'when details are provided' do
- it 'sets details from the report' do
- finding = report.findings.find { |x| x.compare_key == 'CVE-1020' }
- expected_details = Gitlab::Json.parse(finding.raw_metadata)['details']
+ describe 'parsing finding.details' do
+ context 'when details are provided' do
+ it 'sets details from the report' do
+ finding = report.findings.find { |x| x.compare_key == 'CVE-1020' }
+ expected_details = Gitlab::Json.parse(finding.raw_metadata)['details']
- expect(finding.details).to eq(expected_details)
+ expect(finding.details).to eq(expected_details)
+ end
end
- end
- context 'when details are not provided' do
- it 'sets empty hash' do
- finding = report.findings.find { |x| x.compare_key == 'CVE-1030' }
- expect(finding.details).to eq({})
+ context 'when details are not provided' do
+ it 'sets empty hash' do
+ finding = report.findings.find { |x| x.compare_key == 'CVE-1030' }
+ expect(finding.details).to eq({})
+ end
end
end
- end
- describe 'top-level scanner' do
- it 'is the primary scanner' do
- expect(report.primary_scanner.external_id).to eq('gemnasium')
- expect(report.primary_scanner.name).to eq('Gemnasium')
- expect(report.primary_scanner.vendor).to eq('GitLab')
- expect(report.primary_scanner.version).to eq('2.18.0')
- end
+ describe 'top-level scanner' do
+ it 'is the primary scanner' do
+ expect(report.primary_scanner.external_id).to eq('gemnasium')
+ expect(report.primary_scanner.name).to eq('Gemnasium')
+ expect(report.primary_scanner.vendor).to eq('GitLab')
+ expect(report.primary_scanner.version).to eq('2.18.0')
+ end
- it 'returns nil report has no scanner' do
- empty_report = Gitlab::Ci::Reports::Security::Report.new(artifact.file_type, pipeline, 2.weeks.ago)
- described_class.parse!({}.to_json, empty_report)
+ it 'returns nil report has no scanner' do
+ empty_report = Gitlab::Ci::Reports::Security::Report.new(artifact.file_type, pipeline, 2.weeks.ago)
+ described_class.parse!({}.to_json, empty_report)
- expect(empty_report.primary_scanner).to be_nil
+ expect(empty_report.primary_scanner).to be_nil
+ end
end
- end
- describe 'parsing scanners' do
- subject(:scanner) { report.findings.first.scanner }
+ describe 'parsing scanners' do
+ subject(:scanner) { report.findings.first.scanner }
- context 'when vendor is not missing in scanner' do
- it 'returns scanner with parsed vendor value' do
- expect(scanner.vendor).to eq('GitLab')
+ context 'when vendor is not missing in scanner' do
+ it 'returns scanner with parsed vendor value' do
+ expect(scanner.vendor).to eq('GitLab')
+ end
end
end
- end
- describe 'parsing scan' do
- it 'returns scan object for each finding' do
- scans = report.findings.map(&:scan)
+ describe 'parsing scan' do
+ it 'returns scan object for each finding' do
+ scans = report.findings.map(&:scan)
- expect(scans.map(&:status).all?('success')).to be(true)
- expect(scans.map(&:start_time).all?('placeholder-value')).to be(true)
- expect(scans.map(&:end_time).all?('placeholder-value')).to be(true)
- expect(scans.size).to eq(3)
- expect(scans.first).to be_a(::Gitlab::Ci::Reports::Security::Scan)
- end
+ expect(scans.map(&:status).all?('success')).to be(true)
+ expect(scans.map(&:start_time).all?('placeholder-value')).to be(true)
+ expect(scans.map(&:end_time).all?('placeholder-value')).to be(true)
+ expect(scans.size).to eq(3)
+ expect(scans.first).to be_a(::Gitlab::Ci::Reports::Security::Scan)
+ end
- it 'returns nil when scan is not a hash' do
- empty_report = Gitlab::Ci::Reports::Security::Report.new(artifact.file_type, pipeline, 2.weeks.ago)
- described_class.parse!({}.to_json, empty_report)
+ it 'returns nil when scan is not a hash' do
+ empty_report = Gitlab::Ci::Reports::Security::Report.new(artifact.file_type, pipeline, 2.weeks.ago)
+ described_class.parse!({}.to_json, empty_report)
- expect(empty_report.scan).to be(nil)
+ expect(empty_report.scan).to be(nil)
+ end
end
- end
- describe 'parsing schema version' do
- it 'parses the version' do
- expect(report.version).to eq('14.0.2')
- end
+ describe 'parsing schema version' do
+ it 'parses the version' do
+ expect(report.version).to eq('14.0.2')
+ end
- it 'returns nil when there is no version' do
- empty_report = Gitlab::Ci::Reports::Security::Report.new(artifact.file_type, pipeline, 2.weeks.ago)
- described_class.parse!({}.to_json, empty_report)
+ it 'returns nil when there is no version' do
+ empty_report = Gitlab::Ci::Reports::Security::Report.new(artifact.file_type, pipeline, 2.weeks.ago)
+ described_class.parse!({}.to_json, empty_report)
- expect(empty_report.version).to be_nil
+ expect(empty_report.version).to be_nil
+ end
end
- end
- describe 'parsing analyzer' do
- it 'associates analyzer with report' do
- expect(report.analyzer.id).to eq('common-analyzer')
- expect(report.analyzer.name).to eq('Common Analyzer')
- expect(report.analyzer.version).to eq('2.0.1')
- expect(report.analyzer.vendor).to eq('Common')
- end
+ describe 'parsing analyzer' do
+ it 'associates analyzer with report' do
+ expect(report.analyzer.id).to eq('common-analyzer')
+ expect(report.analyzer.name).to eq('Common Analyzer')
+ expect(report.analyzer.version).to eq('2.0.1')
+ expect(report.analyzer.vendor).to eq('Common')
+ end
- it 'returns nil when analyzer data is not available' do
- empty_report = Gitlab::Ci::Reports::Security::Report.new(artifact.file_type, pipeline, 2.weeks.ago)
- described_class.parse!({}.to_json, empty_report)
+ it 'returns nil when analyzer data is not available' do
+ empty_report = Gitlab::Ci::Reports::Security::Report.new(artifact.file_type, pipeline, 2.weeks.ago)
+ described_class.parse!({}.to_json, empty_report)
- expect(empty_report.analyzer).to be_nil
+ expect(empty_report.analyzer).to be_nil
+ end
end
- end
- describe 'parsing flags' do
- it 'returns flags object for each finding' do
- flags = report.findings.first.flags
+ describe 'parsing flags' do
+ it 'returns flags object for each finding' do
+ flags = report.findings.first.flags
- expect(flags).to contain_exactly(
- have_attributes(type: 'flagged-as-likely-false-positive', origin: 'post analyzer X', description: 'static string to sink'),
+ expect(flags).to contain_exactly(
+ have_attributes(type: 'flagged-as-likely-false-positive', origin: 'post analyzer X', description: 'static string to sink'),
have_attributes(type: 'flagged-as-likely-false-positive', origin: 'post analyzer Y', description: 'integer to sink')
- )
+ )
+ end
end
- end
- describe 'parsing links' do
- it 'returns links object for each finding', :aggregate_failures do
- links = report.findings.flat_map(&:links)
+ describe 'parsing links' do
+ it 'returns links object for each finding', :aggregate_failures do
+ links = report.findings.flat_map(&:links)
- expect(links.map(&:url)).to match_array(['https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-1020', 'https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-1030'])
- expect(links.map(&:name)).to match_array([nil, 'CVE-1030'])
- expect(links.size).to eq(2)
- expect(links.first).to be_a(::Gitlab::Ci::Reports::Security::Link)
+ expect(links.map(&:url)).to match_array(['https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-1020', 'https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-1030'])
+ expect(links.map(&:name)).to match_array([nil, 'CVE-1030'])
+ expect(links.size).to eq(2)
+ expect(links.first).to be_a(::Gitlab::Ci::Reports::Security::Link)
+ end
end
- end
- describe 'setting the uuid' do
- let(:finding_uuids) { report.findings.map(&:uuid) }
- let(:uuid_1) do
- Security::VulnerabilityUUID.generate(
- report_type: "sast",
- primary_identifier_fingerprint: report.findings[0].identifiers.first.fingerprint,
- location_fingerprint: location.fingerprint,
- project_id: pipeline.project_id
- )
- end
+ describe 'parsing evidence' do
+ it 'returns evidence object for each finding', :aggregate_failures do
+ evidences = report.findings.map(&:evidence)
- let(:uuid_2) do
- Security::VulnerabilityUUID.generate(
- report_type: "sast",
- primary_identifier_fingerprint: report.findings[1].identifiers.first.fingerprint,
- location_fingerprint: location.fingerprint,
- project_id: pipeline.project_id
- )
+ expect(evidences.first.data).not_to be_empty
+ expect(evidences.first.data["summary"]).to match(/The Origin header was changed/)
+ expect(evidences.size).to eq(3)
+ expect(evidences.compact.size).to eq(2)
+ expect(evidences.first).to be_a(::Gitlab::Ci::Reports::Security::Evidence)
+ end
end
- let(:expected_uuids) { [uuid_1, uuid_2, nil] }
+ describe 'setting the uuid' do
+ let(:finding_uuids) { report.findings.map(&:uuid) }
+ let(:uuid_1) do
+ Security::VulnerabilityUUID.generate(
+ report_type: "sast",
+ primary_identifier_fingerprint: report.findings[0].identifiers.first.fingerprint,
+ location_fingerprint: location.fingerprint,
+ project_id: pipeline.project_id
+ )
+ end
+
+ let(:uuid_2) do
+ Security::VulnerabilityUUID.generate(
+ report_type: "sast",
+ primary_identifier_fingerprint: report.findings[1].identifiers.first.fingerprint,
+ location_fingerprint: location.fingerprint,
+ project_id: pipeline.project_id
+ )
+ end
- it 'sets the UUIDv5 for findings', :aggregate_failures do
- allow_next_instance_of(Gitlab::Ci::Reports::Security::Report) do |report|
- allow(report).to receive(:type).and_return('sast')
+ let(:expected_uuids) { [uuid_1, uuid_2, nil] }
- expect(finding_uuids).to match_array(expected_uuids)
+ it 'sets the UUIDv5 for findings', :aggregate_failures do
+ allow_next_instance_of(Gitlab::Ci::Reports::Security::Report) do |report|
+ allow(report).to receive(:type).and_return('sast')
+
+ expect(finding_uuids).to match_array(expected_uuids)
+ end
end
end
- end
- describe 'parsing tracking' do
- let(:tracking_data) do
- {
+ describe 'parsing tracking' do
+ let(:tracking_data) do
+ {
'type' => 'source',
'items' => [
- 'signatures' => [
- { 'algorithm' => 'hash', 'value' => 'hash_value' },
- { 'algorithm' => 'location', 'value' => 'location_value' },
- { 'algorithm' => 'scope_offset', 'value' => 'scope_offset_value' }
- ]
+ 'signatures' => [
+ { 'algorithm' => 'hash', 'value' => 'hash_value' },
+ { 'algorithm' => 'location', 'value' => 'location_value' },
+ { 'algorithm' => 'scope_offset', 'value' => 'scope_offset_value' }
]
- }
- end
+ ]
+ }
+ end
- context 'with valid tracking information' do
- it 'creates signatures for each algorithm' do
- finding = report.findings.first
- expect(finding.signatures.size).to eq(3)
- expect(finding.signatures.map(&:algorithm_type).to_set).to eq(Set['hash', 'location', 'scope_offset'])
+ context 'with valid tracking information' do
+ it 'creates signatures for each algorithm' do
+ finding = report.findings.first
+ expect(finding.signatures.size).to eq(3)
+ expect(finding.signatures.map(&:algorithm_type).to_set).to eq(Set['hash', 'location', 'scope_offset'])
+ end
end
- end
- context 'with invalid tracking information' do
- let(:tracking_data) do
- {
+ context 'with invalid tracking information' do
+ let(:tracking_data) do
+ {
'type' => 'source',
'items' => [
- 'signatures' => [
- { 'algorithm' => 'hash', 'value' => 'hash_value' },
- { 'algorithm' => 'location', 'value' => 'location_value' },
- { 'algorithm' => 'INVALID', 'value' => 'scope_offset_value' }
- ]
+ 'signatures' => [
+ { 'algorithm' => 'hash', 'value' => 'hash_value' },
+ { 'algorithm' => 'location', 'value' => 'location_value' },
+ { 'algorithm' => 'INVALID', 'value' => 'scope_offset_value' }
]
- }
- end
+ ]
+ }
+ end
- it 'ignores invalid algorithm types' do
- finding = report.findings.first
- expect(finding.signatures.size).to eq(2)
- expect(finding.signatures.map(&:algorithm_type).to_set).to eq(Set['hash', 'location'])
+ it 'ignores invalid algorithm types' do
+ finding = report.findings.first
+ expect(finding.signatures.size).to eq(2)
+ expect(finding.signatures.map(&:algorithm_type).to_set).to eq(Set['hash', 'location'])
+ end
end
- end
- context 'with valid tracking information' do
- it 'creates signatures for each signature algorithm' do
- finding = report.findings.first
- expect(finding.signatures.size).to eq(3)
- expect(finding.signatures.map(&:algorithm_type)).to eq(%w[hash location scope_offset])
-
- signatures = finding.signatures.index_by(&:algorithm_type)
- expected_values = tracking_data['items'][0]['signatures'].index_by { |x| x['algorithm'] }
- expect(signatures['hash'].signature_value).to eq(expected_values['hash']['value'])
- expect(signatures['location'].signature_value).to eq(expected_values['location']['value'])
- expect(signatures['scope_offset'].signature_value).to eq(expected_values['scope_offset']['value'])
- end
+ context 'with valid tracking information' do
+ it 'creates signatures for each signature algorithm' do
+ finding = report.findings.first
+ expect(finding.signatures.size).to eq(3)
+ expect(finding.signatures.map(&:algorithm_type)).to eq(%w[hash location scope_offset])
+
+ signatures = finding.signatures.index_by(&:algorithm_type)
+ expected_values = tracking_data['items'][0]['signatures'].index_by { |x| x['algorithm'] }
+ expect(signatures['hash'].signature_value).to eq(expected_values['hash']['value'])
+ expect(signatures['location'].signature_value).to eq(expected_values['location']['value'])
+ expect(signatures['scope_offset'].signature_value).to eq(expected_values['scope_offset']['value'])
+ end
- it 'sets the uuid according to the higest priority signature' do
- finding = report.findings.first
- highest_signature = finding.signatures.max_by(&:priority)
+ it 'sets the uuid according to the higest priority signature' do
+ finding = report.findings.first
+ highest_signature = finding.signatures.max_by(&:priority)
- identifiers = if vulnerability_finding_signatures_enabled
- "#{finding.report_type}-#{finding.primary_identifier.fingerprint}-#{highest_signature.signature_hex}-#{report.project_id}"
- else
- "#{finding.report_type}-#{finding.primary_identifier.fingerprint}-#{finding.location.fingerprint}-#{report.project_id}"
- end
+ identifiers = if vulnerability_finding_signatures_enabled
+ "#{finding.report_type}-#{finding.primary_identifier.fingerprint}-#{highest_signature.signature_hex}-#{report.project_id}"
+ else
+ "#{finding.report_type}-#{finding.primary_identifier.fingerprint}-#{finding.location.fingerprint}-#{report.project_id}"
+ end
- expect(finding.uuid).to eq(Gitlab::UUID.v5(identifiers))
+ expect(finding.uuid).to eq(Gitlab::UUID.v5(identifiers))
+ end
end
end
end
diff --git a/spec/lib/gitlab/ci/parsers/security/validators/schema_validator_spec.rb b/spec/lib/gitlab/ci/parsers/security/validators/schema_validator_spec.rb
index 951e0576a58..c83427b68ef 100644
--- a/spec/lib/gitlab/ci/parsers/security/validators/schema_validator_spec.rb
+++ b/spec/lib/gitlab/ci/parsers/security/validators/schema_validator_spec.rb
@@ -3,16 +3,60 @@
require 'spec_helper'
RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do
+ describe 'SUPPORTED_VERSIONS' do
+ schema_path = Rails.root.join("lib", "gitlab", "ci", "parsers", "security", "validators", "schemas")
+
+ it 'matches DEPRECATED_VERSIONS keys' do
+ expect(described_class::SUPPORTED_VERSIONS.keys).to eq(described_class::DEPRECATED_VERSIONS.keys)
+ end
+
+ context 'files under schema path are explicitly listed' do
+ # We only care about the part that comes before report-format.json
+ # https://rubular.com/r/N8Juz7r8hYDYgD
+ filename_regex = /(?<report_type>[-\w]*)\-report-format.json/
+
+ versions = Dir.glob(File.join(schema_path, "*", File::SEPARATOR)).map { |path| path.split("/").last }
+
+ versions.each do |version|
+ files = Dir[schema_path.join(version, "*.json")]
+
+ files.each do |file|
+ matches = filename_regex.match(file)
+ report_type = matches[:report_type].tr("-", "_").to_sym
+
+ it "#{report_type} #{version}" do
+ expect(described_class::SUPPORTED_VERSIONS[report_type]).to include(version)
+ end
+ end
+ end
+ end
+
+ context 'every SUPPORTED_VERSION has a corresponding JSON file' do
+ described_class::SUPPORTED_VERSIONS.each_key do |report_type|
+ # api_fuzzing is covered by DAST schema
+ next if report_type == :api_fuzzing
+
+ described_class::SUPPORTED_VERSIONS[report_type].each do |version|
+ it "#{report_type} #{version} schema file is present" do
+ filename = "#{report_type.to_s.tr("_", "-")}-report-format.json"
+ full_path = schema_path.join(version, filename)
+ expect(File.file?(full_path)).to be true
+ end
+ end
+ end
+ end
+ end
+
using RSpec::Parameterized::TableSyntax
- where(:report_type, :expected_errors, :valid_data) do
- 'sast' | ['root is missing required keys: vulnerabilities'] | { 'version' => '10.0.0', 'vulnerabilities' => [] }
- :sast | ['root is missing required keys: vulnerabilities'] | { 'version' => '10.0.0', 'vulnerabilities' => [] }
- :secret_detection | ['root is missing required keys: vulnerabilities'] | { 'version' => '10.0.0', 'vulnerabilities' => [] }
+ where(:report_type, :report_version, :expected_errors, :valid_data) do
+ 'sast' | '10.0.0' | ['root is missing required keys: vulnerabilities'] | { 'version' => '10.0.0', 'vulnerabilities' => [] }
+ :sast | '10.0.0' | ['root is missing required keys: vulnerabilities'] | { 'version' => '10.0.0', 'vulnerabilities' => [] }
+ :secret_detection | '10.0.0' | ['root is missing required keys: vulnerabilities'] | { 'version' => '10.0.0', 'vulnerabilities' => [] }
end
with_them do
- let(:validator) { described_class.new(report_type, report_data) }
+ let(:validator) { described_class.new(report_type, report_data, report_version) }
describe '#valid?' do
subject { validator.valid? }
@@ -28,6 +72,15 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Validators::SchemaValidator do
it { is_expected.to be_truthy }
end
+
+ context 'when no report_version is provided' do
+ let(:report_version) { nil }
+ let(:report_data) { valid_data }
+
+ it 'does not fail' do
+ expect { subject }.not_to raise_error
+ end
+ end
end
describe '#errors' do
diff --git a/spec/lib/gitlab/ci/pipeline/chain/cancel_pending_pipelines_spec.rb b/spec/lib/gitlab/ci/pipeline/chain/cancel_pending_pipelines_spec.rb
index 27a5abf988c..25e81f6d538 100644
--- a/spec/lib/gitlab/ci/pipeline/chain/cancel_pending_pipelines_spec.rb
+++ b/spec/lib/gitlab/ci/pipeline/chain/cancel_pending_pipelines_spec.rb
@@ -55,31 +55,88 @@ RSpec.describe Gitlab::Ci::Pipeline::Chain::CancelPendingPipelines do
context 'when the previous pipeline has a child pipeline' do
let(:child_pipeline) { create(:ci_pipeline, child_of: prev_pipeline) }
- context 'when the child pipeline has an interruptible job' do
+ context 'when the child pipeline has interruptible running jobs' do
before do
create(:ci_build, :interruptible, :running, pipeline: child_pipeline)
+ create(:ci_build, :interruptible, :running, pipeline: child_pipeline)
end
- it 'cancels interruptible builds of child pipeline' do
- expect(build_statuses(child_pipeline)).to contain_exactly('running')
+ it 'cancels all child pipeline builds' do
+ expect(build_statuses(child_pipeline)).to contain_exactly('running', 'running')
perform
- expect(build_statuses(child_pipeline)).to contain_exactly('canceled')
+ expect(build_statuses(child_pipeline)).to contain_exactly('canceled', 'canceled')
+ end
+
+ context 'when the child pipeline includes completed interruptible jobs' do
+ before do
+ create(:ci_build, :interruptible, :failed, pipeline: child_pipeline)
+ create(:ci_build, :interruptible, :success, pipeline: child_pipeline)
+ end
+
+ it 'cancels all child pipeline builds with a cancelable_status' do
+ expect(build_statuses(child_pipeline)).to contain_exactly('running', 'running', 'failed', 'success')
+
+ perform
+
+ expect(build_statuses(child_pipeline)).to contain_exactly('canceled', 'canceled', 'failed', 'success')
+ end
end
end
- context 'when the child pipeline has not an interruptible job' do
+ context 'when the child pipeline has started non-interruptible job' do
before do
- create(:ci_build, :running, pipeline: child_pipeline)
+ create(:ci_build, :interruptible, :running, pipeline: child_pipeline)
+ # non-interruptible started
+ create(:ci_build, :success, pipeline: child_pipeline)
end
- it 'does not cancel the build of child pipeline' do
- expect(build_statuses(child_pipeline)).to contain_exactly('running')
+ it 'does not cancel any child pipeline builds' do
+ expect(build_statuses(child_pipeline)).to contain_exactly('running', 'success')
perform
- expect(build_statuses(child_pipeline)).to contain_exactly('running')
+ expect(build_statuses(child_pipeline)).to contain_exactly('running', 'success')
+ end
+ end
+
+ context 'when the child pipeline has non-interruptible non-started job' do
+ before do
+ create(:ci_build, :interruptible, :running, pipeline: child_pipeline)
+ end
+
+ not_started_statuses = Ci::HasStatus::AVAILABLE_STATUSES - Ci::HasStatus::BUILD_STARTED_RUNNING_STATUSES
+ context 'when the jobs are cancelable' do
+ cancelable_not_started_statuses = Set.new(not_started_statuses).intersection(Ci::HasStatus::CANCELABLE_STATUSES)
+ cancelable_not_started_statuses.each do |status|
+ it "cancels all child pipeline builds when build status #{status} included" do
+ # non-interruptible but non-started
+ create(:ci_build, status.to_sym, pipeline: child_pipeline)
+
+ expect(build_statuses(child_pipeline)).to contain_exactly('running', status)
+
+ perform
+
+ expect(build_statuses(child_pipeline)).to contain_exactly('canceled', 'canceled')
+ end
+ end
+ end
+
+ context 'when the jobs are not cancelable' do
+ not_cancelable_not_started_statuses = not_started_statuses - Ci::HasStatus::CANCELABLE_STATUSES
+ not_cancelable_not_started_statuses.each do |status|
+ it "does not cancel child pipeline builds when build status #{status} included" do
+ # non-interruptible but non-started
+ create(:ci_build, status.to_sym, pipeline: child_pipeline)
+
+ expect(build_statuses(child_pipeline)).to contain_exactly('running', status)
+
+ perform
+
+ expect(build_statuses(child_pipeline)).to contain_exactly('canceled', status)
+ end
+ end
end
end
end
diff --git a/spec/lib/gitlab/ci/pipeline/chain/create_spec.rb b/spec/lib/gitlab/ci/pipeline/chain/create_spec.rb
index 1d020d3ea79..9057c4e99df 100644
--- a/spec/lib/gitlab/ci/pipeline/chain/create_spec.rb
+++ b/spec/lib/gitlab/ci/pipeline/chain/create_spec.rb
@@ -106,21 +106,5 @@ RSpec.describe Gitlab::Ci::Pipeline::Chain::Create do
expect(job.reload.tag_list).to match_array(%w[tag1 tag2])
end
end
-
- context 'when the feature flag is disabled' do
- before do
- job.tag_list = %w[tag1 tag2]
- stub_feature_flags(ci_bulk_insert_tags: false)
- end
-
- it 'follows the old code path' do
- expect(CommitStatus).not_to receive(:bulk_insert_tags!)
-
- step.perform!
-
- expect(job).to be_persisted
- expect(job.reload.tag_list).to match_array(%w[tag1 tag2])
- end
- end
end
end
diff --git a/spec/lib/gitlab/ci/reports/security/report_spec.rb b/spec/lib/gitlab/ci/reports/security/report_spec.rb
index a8b962ee970..4dc1eca3859 100644
--- a/spec/lib/gitlab/ci/reports/security/report_spec.rb
+++ b/spec/lib/gitlab/ci/reports/security/report_spec.rb
@@ -158,6 +158,16 @@ RSpec.describe Gitlab::Ci::Reports::Security::Report do
end
end
+ describe '#add_warning' do
+ context 'when the message is given' do
+ it 'adds a new warning to report' do
+ expect { report.add_warning('foo', 'bar') }.to change { report.warnings }
+ .from([])
+ .to([{ type: 'foo', message: 'bar' }])
+ end
+ end
+ end
+
describe 'errored?' do
subject { report.errored? }
diff --git a/spec/lib/gitlab/ci/status/build/waiting_for_approval_spec.rb b/spec/lib/gitlab/ci/status/build/waiting_for_approval_spec.rb
index b703a8a47ac..b79b78d911b 100644
--- a/spec/lib/gitlab/ci/status/build/waiting_for_approval_spec.rb
+++ b/spec/lib/gitlab/ci/status/build/waiting_for_approval_spec.rb
@@ -5,22 +5,10 @@ require 'spec_helper'
RSpec.describe Gitlab::Ci::Status::Build::WaitingForApproval do
let_it_be(:project) { create(:project, :repository) }
let_it_be(:user) { create(:user) }
+ let_it_be(:build) { create(:ci_build, :manual, environment: 'production', project: project) }
subject { described_class.new(Gitlab::Ci::Status::Core.new(build, user)) }
- describe '#illustration' do
- let(:build) { create(:ci_build, :manual, environment: 'production', project: project) }
-
- before do
- environment = create(:environment, name: 'production', project: project)
- create(:deployment, :blocked, project: project, environment: environment, deployable: build)
- end
-
- it { expect(subject.illustration).to include(:image, :size) }
- it { expect(subject.illustration[:title]).to eq('Waiting for approval') }
- it { expect(subject.illustration[:content]).to include('This job deploys to the protected environment "production"') }
- end
-
describe '.matches?' do
subject { described_class.matches?(build, user) }
@@ -46,4 +34,39 @@ RSpec.describe Gitlab::Ci::Status::Build::WaitingForApproval do
end
end
end
+
+ describe '#illustration' do
+ before do
+ environment = create(:environment, name: 'production', project: project)
+ create(:deployment, :blocked, project: project, environment: environment, deployable: build)
+ end
+
+ it { expect(subject.illustration).to include(:image, :size) }
+ it { expect(subject.illustration[:title]).to eq('Waiting for approval') }
+ it { expect(subject.illustration[:content]).to include('This job deploys to the protected environment "production"') }
+ end
+
+ describe '#has_action?' do
+ it { expect(subject.has_action?).to be_truthy }
+ end
+
+ describe '#action_icon' do
+ it { expect(subject.action_icon).to be_nil }
+ end
+
+ describe '#action_title' do
+ it { expect(subject.action_title).to be_nil }
+ end
+
+ describe '#action_button_title' do
+ it { expect(subject.action_button_title).to eq('Go to environments page to approve or reject') }
+ end
+
+ describe '#action_path' do
+ it { expect(subject.action_path).to include('environments') }
+ end
+
+ describe '#action_method' do
+ it { expect(subject.action_method).to eq(:get) }
+ end
end
diff --git a/spec/lib/gitlab/ci/templates/auto_devops_gitlab_ci_yaml_spec.rb b/spec/lib/gitlab/ci/templates/auto_devops_gitlab_ci_yaml_spec.rb
index 6a4be1fa072..78d3982a79f 100644
--- a/spec/lib/gitlab/ci/templates/auto_devops_gitlab_ci_yaml_spec.rb
+++ b/spec/lib/gitlab/ci/templates/auto_devops_gitlab_ci_yaml_spec.rb
@@ -238,14 +238,34 @@ RSpec.describe 'Auto-DevOps.gitlab-ci.yml' do
end
it_behaves_like 'pipeline with Kubernetes jobs'
+
+ context 'when certificate_based_clusters FF is disabled' do
+ before do
+ stub_feature_flags(certificate_based_clusters: false)
+ end
+
+ it 'does not include production job' do
+ expect(build_names).not_to include('production')
+ end
+ end
end
- context 'when project has an Agent is present' do
+ context 'when project has an Agent' do
before do
create(:cluster_agent, project: project)
end
it_behaves_like 'pipeline with Kubernetes jobs'
+
+ context 'when certificate_based_clusters FF is disabled' do
+ before do
+ stub_feature_flags(certificate_based_clusters: false)
+ end
+
+ it 'includes production job' do
+ expect(build_names).to include('production')
+ end
+ end
end
end
diff --git a/spec/lib/gitlab/ci/variables/builder/group_spec.rb b/spec/lib/gitlab/ci/variables/builder/group_spec.rb
new file mode 100644
index 00000000000..72487588cde
--- /dev/null
+++ b/spec/lib/gitlab/ci/variables/builder/group_spec.rb
@@ -0,0 +1,209 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Ci::Variables::Builder::Group do
+ let_it_be(:group) { create(:group) }
+
+ let(:builder) { described_class.new(group) }
+
+ describe '#secret_variables' do
+ let(:environment) { '*' }
+ let(:protected_ref) { false }
+
+ let_it_be(:variable) do
+ create(:ci_group_variable,
+ value: 'secret',
+ group: group)
+ end
+
+ let_it_be(:protected_variable) do
+ create(:ci_group_variable, :protected,
+ value: 'protected',
+ group: group)
+ end
+
+ let(:variable_item) { item(variable) }
+ let(:protected_variable_item) { item(protected_variable) }
+
+ subject do
+ builder.secret_variables(
+ environment: environment,
+ protected_ref: protected_ref)
+ end
+
+ context 'when the ref is not protected' do
+ let(:protected_ref) { false }
+
+ it 'contains only the CI variables' do
+ is_expected.to contain_exactly(variable_item)
+ end
+ end
+
+ context 'when the ref is protected' do
+ let(:protected_ref) { true }
+
+ it 'contains all the variables' do
+ is_expected.to contain_exactly(variable_item, protected_variable_item)
+ end
+ end
+
+ context 'when environment name is specified' do
+ let(:environment) { 'review/name' }
+
+ before do
+ Ci::GroupVariable.update_all(environment_scope: environment_scope)
+ end
+
+ context 'when environment scope is exactly matched' do
+ let(:environment_scope) { 'review/name' }
+
+ it { is_expected.to contain_exactly(variable_item) }
+ end
+
+ context 'when environment scope is matched by wildcard' do
+ let(:environment_scope) { 'review/*' }
+
+ it { is_expected.to contain_exactly(variable_item) }
+ end
+
+ context 'when environment scope does not match' do
+ let(:environment_scope) { 'review/*/special' }
+
+ it { is_expected.not_to contain_exactly(variable_item) }
+ end
+
+ context 'when environment scope has _' do
+ let(:environment_scope) { '*_*' }
+
+ it 'does not treat it as wildcard' do
+ is_expected.not_to contain_exactly(variable_item)
+ end
+ end
+
+ context 'when environment name contains underscore' do
+ let(:environment) { 'foo_bar/test' }
+ let(:environment_scope) { 'foo_bar/*' }
+
+ it 'matches literally for _' do
+ is_expected.to contain_exactly(variable_item)
+ end
+ end
+
+ # The environment name and scope cannot have % at the moment,
+ # but we're considering relaxing it and we should also make sure
+ # it doesn't break in case some data sneaked in somehow as we're
+ # not checking this integrity in database level.
+ context 'when environment scope has %' do
+ let(:environment_scope) { '*%*' }
+
+ it 'does not treat it as wildcard' do
+ is_expected.not_to contain_exactly(variable_item)
+ end
+ end
+
+ context 'when environment name contains a percent' do
+ let(:environment) { 'foo%bar/test' }
+ let(:environment_scope) { 'foo%bar/*' }
+
+ it 'matches literally for _' do
+ is_expected.to contain_exactly(variable_item)
+ end
+ end
+ end
+
+ context 'when variables with the same name have different environment scopes' do
+ let(:environment) { 'review/name' }
+
+ let_it_be(:partially_matched_variable) do
+ create(:ci_group_variable,
+ key: variable.key,
+ value: 'partial',
+ environment_scope: 'review/*',
+ group: group)
+ end
+
+ let_it_be(:perfectly_matched_variable) do
+ create(:ci_group_variable,
+ key: variable.key,
+ value: 'prefect',
+ environment_scope: 'review/name',
+ group: group)
+ end
+
+ it 'orders the variables from least to most matched' do
+ variables_collection = Gitlab::Ci::Variables::Collection.new([
+ variable,
+ partially_matched_variable,
+ perfectly_matched_variable
+ ]).to_runner_variables
+
+ expect(subject.to_runner_variables).to eq(variables_collection)
+ end
+ end
+
+ context 'when group has children' do
+ let(:protected_ref) { true }
+
+ let_it_be(:group_child_1) { create(:group, parent: group) }
+ let_it_be(:group_child_2) { create(:group, parent: group_child_1) }
+
+ let_it_be_with_reload(:group_child_3) do
+ create(:group, parent: group_child_2)
+ end
+
+ let_it_be(:variable_child_1) do
+ create(:ci_group_variable, group: group_child_1)
+ end
+
+ let_it_be(:variable_child_2) do
+ create(:ci_group_variable, group: group_child_2)
+ end
+
+ let_it_be(:variable_child_3) do
+ create(:ci_group_variable, group: group_child_3)
+ end
+
+ context 'traversal queries' do
+ shared_examples 'correct ancestor order' do
+ let(:builder) { described_class.new(group_child_3) }
+
+ it 'returns all variables belonging to the group and parent groups' do
+ expected_array1 = Gitlab::Ci::Variables::Collection.new(
+ [protected_variable_item, variable_item])
+ .to_runner_variables
+
+ expected_array2 = Gitlab::Ci::Variables::Collection.new(
+ [variable_child_1, variable_child_2, variable_child_3]
+ ).to_runner_variables
+
+ got_array = subject.to_runner_variables
+
+ expect(got_array.shift(2)).to contain_exactly(*expected_array1)
+ expect(got_array).to eq(expected_array2)
+ end
+ end
+
+ context 'recursive' do
+ before do
+ stub_feature_flags(use_traversal_ids: false)
+ end
+
+ include_examples 'correct ancestor order'
+ end
+
+ context 'linear' do
+ before do
+ stub_feature_flags(use_traversal_ids: true)
+ end
+
+ include_examples 'correct ancestor order'
+ end
+ end
+ end
+ end
+
+ def item(variable)
+ Gitlab::Ci::Variables::Collection::Item.fabricate(variable)
+ end
+end
diff --git a/spec/lib/gitlab/ci/variables/builder_spec.rb b/spec/lib/gitlab/ci/variables/builder_spec.rb
index 6e144d62ac0..8552a06eab3 100644
--- a/spec/lib/gitlab/ci/variables/builder_spec.rb
+++ b/spec/lib/gitlab/ci/variables/builder_spec.rb
@@ -158,7 +158,6 @@ RSpec.describe Gitlab::Ci::Variables::Builder do
allow(pipeline).to receive(:predefined_variables) { [var('C', 3), var('D', 3)] }
allow(job).to receive(:runner) { double(predefined_variables: [var('D', 4), var('E', 4)]) }
allow(builder).to receive(:kubernetes_variables) { [var('E', 5), var('F', 5)] }
- allow(builder).to receive(:deployment_variables) { [var('F', 6), var('G', 6)] }
allow(job).to receive(:yaml_variables) { [var('G', 7), var('H', 7)] }
allow(builder).to receive(:user_variables) { [var('H', 8), var('I', 8)] }
allow(job).to receive(:dependency_variables) { [var('I', 9), var('J', 9)] }
@@ -177,7 +176,6 @@ RSpec.describe Gitlab::Ci::Variables::Builder do
var('C', 3), var('D', 3),
var('D', 4), var('E', 4),
var('E', 5), var('F', 5),
- var('F', 6), var('G', 6),
var('G', 7), var('H', 7),
var('H', 8), var('I', 8),
var('I', 9), var('J', 9),
@@ -193,7 +191,7 @@ RSpec.describe Gitlab::Ci::Variables::Builder do
expect(subject.to_hash).to match(
'A' => '1', 'B' => '2',
'C' => '3', 'D' => '4',
- 'E' => '5', 'F' => '6',
+ 'E' => '5', 'F' => '5',
'G' => '7', 'H' => '8',
'I' => '9', 'J' => '10',
'K' => '11', 'L' => '12',
@@ -231,7 +229,7 @@ RSpec.describe Gitlab::Ci::Variables::Builder do
let(:template) { double(to_yaml: 'example-kubeconfig', valid?: template_valid) }
let(:template_valid) { true }
- subject { builder.kubernetes_variables(job) }
+ subject { builder.kubernetes_variables(environment: nil, job: job) }
before do
allow(Ci::GenerateKubeconfigService).to receive(:new).with(job).and_return(service)
@@ -244,6 +242,16 @@ RSpec.describe Gitlab::Ci::Variables::Builder do
it { is_expected.not_to include(key: 'KUBECONFIG', value: 'example-kubeconfig', public: false, file: true) }
end
+
+ it 'includes #deployment_variables and merges the KUBECONFIG values', :aggregate_failures do
+ expect(builder).to receive(:deployment_variables).and_return([
+ { key: 'KUBECONFIG', value: 'deployment-kubeconfig' },
+ { key: 'OTHER', value: 'some value' }
+ ])
+ expect(template).to receive(:merge_yaml).with('deployment-kubeconfig')
+ expect(subject['KUBECONFIG'].value).to eq('example-kubeconfig')
+ expect(subject['OTHER'].value).to eq('some value')
+ end
end
describe '#deployment_variables' do
@@ -342,10 +350,88 @@ RSpec.describe Gitlab::Ci::Variables::Builder do
let_it_be(:protected_variable) { create(:ci_group_variable, protected: true, group: group) }
let_it_be(:unprotected_variable) { create(:ci_group_variable, protected: false, group: group) }
- let(:protected_variable_item) { protected_variable }
- let(:unprotected_variable_item) { unprotected_variable }
+ context 'with ci_variables_builder_memoize_secret_variables disabled' do
+ before do
+ stub_feature_flags(ci_variables_builder_memoize_secret_variables: false)
+ end
+
+ let(:protected_variable_item) { protected_variable }
+ let(:unprotected_variable_item) { unprotected_variable }
- include_examples "secret CI variables"
+ include_examples "secret CI variables"
+ end
+
+ context 'with ci_variables_builder_memoize_secret_variables enabled' do
+ before do
+ stub_feature_flags(ci_variables_builder_memoize_secret_variables: true)
+ end
+
+ let(:protected_variable_item) { Gitlab::Ci::Variables::Collection::Item.fabricate(protected_variable) }
+ let(:unprotected_variable_item) { Gitlab::Ci::Variables::Collection::Item.fabricate(unprotected_variable) }
+
+ include_examples "secret CI variables"
+
+ context 'variables memoization' do
+ let_it_be(:scoped_variable) { create(:ci_group_variable, group: group, environment_scope: 'scoped') }
+
+ let(:ref) { job.git_ref }
+ let(:environment) { job.expanded_environment_name }
+ let(:scoped_variable_item) { Gitlab::Ci::Variables::Collection::Item.fabricate(scoped_variable) }
+
+ context 'with protected environments' do
+ it 'memoizes the result by environment' do
+ expect(pipeline.project)
+ .to receive(:protected_for?)
+ .with(pipeline.jobs_git_ref)
+ .once.and_return(true)
+
+ expect_next_instance_of(described_class::Group) do |group_variables_builder|
+ expect(group_variables_builder)
+ .to receive(:secret_variables)
+ .with(environment: 'production', protected_ref: true)
+ .once
+ .and_call_original
+ end
+
+ 2.times do
+ expect(builder.secret_group_variables(ref: ref, environment: 'production'))
+ .to contain_exactly(unprotected_variable_item, protected_variable_item)
+ end
+ end
+ end
+
+ context 'with unprotected environments' do
+ it 'memoizes the result by environment' do
+ expect(pipeline.project)
+ .to receive(:protected_for?)
+ .with(pipeline.jobs_git_ref)
+ .once.and_return(false)
+
+ expect_next_instance_of(described_class::Group) do |group_variables_builder|
+ expect(group_variables_builder)
+ .to receive(:secret_variables)
+ .with(environment: nil, protected_ref: false)
+ .once
+ .and_call_original
+
+ expect(group_variables_builder)
+ .to receive(:secret_variables)
+ .with(environment: 'scoped', protected_ref: false)
+ .once
+ .and_call_original
+ end
+
+ 2.times do
+ expect(builder.secret_group_variables(ref: 'other', environment: nil))
+ .to contain_exactly(unprotected_variable_item)
+
+ expect(builder.secret_group_variables(ref: 'other', environment: 'scoped'))
+ .to contain_exactly(unprotected_variable_item, scoped_variable_item)
+ end
+ end
+ end
+ end
+ end
end
describe '#secret_project_variables' do
diff --git a/spec/lib/gitlab/ci/yaml_processor/dag_spec.rb b/spec/lib/gitlab/ci/yaml_processor/dag_spec.rb
index af1b43f6b01..f815f56543c 100644
--- a/spec/lib/gitlab/ci/yaml_processor/dag_spec.rb
+++ b/spec/lib/gitlab/ci/yaml_processor/dag_spec.rb
@@ -27,15 +27,13 @@ RSpec.describe Gitlab::Ci::YamlProcessor::Dag do
end
end
- context 'when there is a missing job' do
+ context 'when there are some missing jobs' do
let(:nodes) do
- { 'job_a' => %w(job_d), 'job_b' => %w(job_a) }
+ { 'job_a' => %w(job_d job_f), 'job_b' => %w(job_a job_c job_e) }
end
- it 'raises MissingNodeError' do
- expect { result }.to raise_error(
- Gitlab::Ci::YamlProcessor::Dag::MissingNodeError, 'node job_d is missing'
- )
+ it 'ignores the missing ones and returns in a valid order' do
+ expect(result).to eq(%w(job_d job_f job_a job_c job_e job_b))
end
end
end
diff --git a/spec/lib/gitlab/ci/yaml_processor_spec.rb b/spec/lib/gitlab/ci/yaml_processor_spec.rb
index 5f46607b042..ebb5c91ebad 100644
--- a/spec/lib/gitlab/ci/yaml_processor_spec.rb
+++ b/spec/lib/gitlab/ci/yaml_processor_spec.rb
@@ -9,10 +9,6 @@ module Gitlab
subject { described_class.new(config, user: nil).execute }
- before do
- stub_feature_flags(allow_unsafe_ruby_regexp: false)
- end
-
shared_examples 'returns errors' do |error_message|
it 'adds a message when an error is encountered' do
expect(subject.errors).to include(error_message)
@@ -329,6 +325,40 @@ module Gitlab
end
end
end
+
+ describe 'bridge job' do
+ let(:config) do
+ YAML.dump(rspec: {
+ trigger: {
+ project: 'namespace/project',
+ branch: 'main'
+ }
+ })
+ end
+
+ it 'has the attributes' do
+ expect(subject[:options]).to eq(
+ trigger: { project: 'namespace/project', branch: 'main' }
+ )
+ end
+
+ context 'with forward' do
+ let(:config) do
+ YAML.dump(rspec: {
+ trigger: {
+ project: 'namespace/project',
+ forward: { pipeline_variables: true }
+ }
+ })
+ end
+
+ it 'has the attributes' do
+ expect(subject[:options]).to eq(
+ trigger: { project: 'namespace/project', forward: { pipeline_variables: true } }
+ )
+ end
+ end
+ end
end
describe '#stages_attributes' do
diff --git a/spec/lib/gitlab/color_spec.rb b/spec/lib/gitlab/color_spec.rb
new file mode 100644
index 00000000000..8b16e13fa4d
--- /dev/null
+++ b/spec/lib/gitlab/color_spec.rb
@@ -0,0 +1,132 @@
+# frozen_string_literal: true
+
+require 'fast_spec_helper'
+
+RSpec.describe Gitlab::Color do
+ describe ".of" do
+ described_class::Constants::COLOR_NAME_TO_HEX.each do |name, value|
+ it "parses #{name} to #{value}" do
+ expect(described_class.of(name)).to eq(value)
+ end
+ end
+
+ it 'parses hex literals as colors' do
+ expect(described_class.of('#fff')).to eq(described_class.new('#fff'))
+ expect(described_class.of('#fefefe')).to eq(described_class.new('#fefefe'))
+ end
+
+ it 'raises if the input is nil' do
+ expect { described_class.of(nil) }.to raise_error(ArgumentError)
+ end
+
+ it 'returns an invalid color if the input is not valid' do
+ expect(described_class.of('unknown color')).not_to be_valid
+ end
+ end
+
+ describe '#new' do
+ it 'handles nil values' do
+ expect(described_class.new(nil)).to eq(described_class.new(nil))
+ end
+
+ it 'strips input' do
+ expect(described_class.new(' abc ')).to eq(described_class.new('abc'))
+ end
+ end
+
+ describe '#valid?' do
+ described_class::Constants::COLOR_NAME_TO_HEX.each_key do |name|
+ specify "#{name} is a valid color" do
+ expect(described_class.of(name)).to be_valid
+ end
+ end
+
+ specify '#fff is a valid color' do
+ expect(described_class.new('#fff')).to be_valid
+ end
+
+ specify '#ffffff is a valid color' do
+ expect(described_class.new('#ffffff')).to be_valid
+ end
+
+ specify '#ABCDEF is a valid color' do
+ expect(described_class.new('#ABCDEF')).to be_valid
+ end
+
+ specify '#123456 is a valid color' do
+ expect(described_class.new('#123456')).to be_valid
+ end
+
+ specify '#1234567 is not a valid color' do
+ expect(described_class.new('#1234567')).not_to be_valid
+ end
+
+ specify 'fff is not a valid color' do
+ expect(described_class.new('fff')).not_to be_valid
+ end
+
+ specify '#deadbeaf is not a valid color' do
+ expect(described_class.new('#deadbeaf')).not_to be_valid
+ end
+
+ specify '#a1b2c3 is a valid color' do
+ expect(described_class.new('#a1b2c3')).to be_valid
+ end
+
+ specify 'nil is not a valid color' do
+ expect(described_class.new(nil)).not_to be_valid
+ end
+ end
+
+ describe '#light?' do
+ specify '#fff is light' do
+ expect(described_class.new('#fff')).to be_light
+ end
+
+ specify '#a7a7a7 is light' do
+ expect(described_class.new('#a7a7a7')).to be_light
+ end
+
+ specify '#a6a7a7 is dark' do
+ expect(described_class.new('#a6a7a7')).not_to be_light
+ end
+
+ specify '#000 is dark' do
+ expect(described_class.new('#000')).not_to be_light
+ end
+
+ specify 'invalid colors are not light' do
+ expect(described_class.new('not-a-color')).not_to be_light
+ end
+ end
+
+ describe '#contrast' do
+ context 'with light colors' do
+ it 'is dark' do
+ %w[#fff #fefefe #a7a7a7].each do |hex|
+ expect(described_class.new(hex)).to have_attributes(
+ contrast: described_class::Constants::DARK,
+ luminosity: :light
+ )
+ end
+ end
+ end
+
+ context 'with dark colors' do
+ it 'is light' do
+ %w[#000 #a6a7a7].each do |hex|
+ expect(described_class.new(hex)).to have_attributes(
+ contrast: described_class::Constants::LIGHT,
+ luminosity: :dark
+ )
+ end
+ end
+ end
+ end
+
+ describe 'as_json' do
+ it 'serializes correctly' do
+ expect(described_class.new('#f0f1f2').as_json).to eq('#f0f1f2')
+ end
+ end
+end
diff --git a/spec/lib/gitlab/config/entry/validators_spec.rb b/spec/lib/gitlab/config/entry/validators_spec.rb
new file mode 100644
index 00000000000..cbc09aac586
--- /dev/null
+++ b/spec/lib/gitlab/config/entry/validators_spec.rb
@@ -0,0 +1,43 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Config::Entry::Validators do
+ let(:klass) do
+ Class.new do
+ include ActiveModel::Validations
+ include Gitlab::Config::Entry::Validators
+ end
+ end
+
+ let(:instance) { klass.new }
+
+ describe described_class::MutuallyExclusiveKeysValidator do
+ using RSpec::Parameterized::TableSyntax
+
+ before do
+ klass.instance_eval do
+ validates :config, mutually_exclusive_keys: [:foo, :bar]
+ end
+
+ allow(instance).to receive(:config).and_return(config)
+ end
+
+ where(:context, :config, :valid_result) do
+ 'with mutually exclusive keys' | { foo: 1, bar: 2 } | false
+ 'without mutually exclusive keys' | { foo: 1 } | true
+ 'without mutually exclusive keys' | { bar: 1 } | true
+ 'with other keys' | { foo: 1, baz: 2 } | true
+ end
+
+ with_them do
+ it 'validates the instance' do
+ expect(instance.valid?).to be(valid_result)
+
+ unless valid_result
+ expect(instance.errors.messages_for(:config)).to include /please use only one the following keys: foo, bar/
+ end
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/current_settings_spec.rb b/spec/lib/gitlab/current_settings_spec.rb
index 73540a9b0f3..fda3b07eb82 100644
--- a/spec/lib/gitlab/current_settings_spec.rb
+++ b/spec/lib/gitlab/current_settings_spec.rb
@@ -179,6 +179,21 @@ RSpec.describe Gitlab::CurrentSettings do
expect(settings).to have_attributes(settings_from_defaults)
end
+ context 'when we hit a recursive loop' do
+ before do
+ expect(ApplicationSetting).to receive(:create_from_defaults) do
+ raise ApplicationSetting::Recursion
+ end
+ end
+
+ it 'recovers and returns in-memory settings' do
+ settings = described_class.current_application_settings
+
+ expect(settings).to be_a(ApplicationSetting)
+ expect(settings).not_to be_persisted
+ end
+ end
+
context 'when ApplicationSettings does not have a primary key' do
before do
allow(ApplicationSetting.connection).to receive(:primary_key).with('application_settings').and_return(nil)
diff --git a/spec/lib/gitlab/database/async_indexes/migration_helpers_spec.rb b/spec/lib/gitlab/database/async_indexes/migration_helpers_spec.rb
index eb16a8ccfa5..9ba3dad72b3 100644
--- a/spec/lib/gitlab/database/async_indexes/migration_helpers_spec.rb
+++ b/spec/lib/gitlab/database/async_indexes/migration_helpers_spec.rb
@@ -16,45 +16,29 @@ RSpec.describe Gitlab::Database::AsyncIndexes::MigrationHelpers do
describe '#unprepare_async_index' do
let!(:async_index) { create(:postgres_async_index, name: index_name) }
- context 'when the flag is enabled' do
- before do
- stub_feature_flags(database_async_index_creation: true)
- end
+ it 'destroys the record' do
+ expect do
+ migration.unprepare_async_index(table_name, 'id')
+ end.to change { index_model.where(name: index_name).count }.by(-1)
+ end
+
+ context 'when an explicit name is given' do
+ let(:index_name) { 'my_test_async_index' }
it 'destroys the record' do
expect do
- migration.unprepare_async_index(table_name, 'id')
+ migration.unprepare_async_index(table_name, 'id', name: index_name)
end.to change { index_model.where(name: index_name).count }.by(-1)
end
-
- context 'when an explicit name is given' do
- let(:index_name) { 'my_test_async_index' }
-
- it 'destroys the record' do
- expect do
- migration.unprepare_async_index(table_name, 'id', name: index_name)
- end.to change { index_model.where(name: index_name).count }.by(-1)
- end
- end
-
- context 'when the async index table does not exist' do
- it 'does not raise an error' do
- connection.drop_table(:postgres_async_indexes)
-
- expect(index_model).not_to receive(:find_by)
-
- expect { migration.unprepare_async_index(table_name, 'id') }.not_to raise_error
- end
- end
end
- context 'when the feature flag is disabled' do
- it 'does not destroy the record' do
- stub_feature_flags(database_async_index_creation: false)
+ context 'when the async index table does not exist' do
+ it 'does not raise an error' do
+ connection.drop_table(:postgres_async_indexes)
- expect do
- migration.unprepare_async_index(table_name, 'id')
- end.not_to change { index_model.where(name: index_name).count }
+ expect(index_model).not_to receive(:find_by)
+
+ expect { migration.unprepare_async_index(table_name, 'id') }.not_to raise_error
end
end
end
@@ -63,35 +47,19 @@ RSpec.describe Gitlab::Database::AsyncIndexes::MigrationHelpers do
let(:index_name) { "index_#{table_name}_on_id" }
let!(:async_index) { create(:postgres_async_index, name: index_name) }
- context 'when the flag is enabled' do
- before do
- stub_feature_flags(database_async_index_creation: true)
- end
-
- it 'destroys the record' do
- expect do
- migration.unprepare_async_index_by_name(table_name, index_name)
- end.to change { index_model.where(name: index_name).count }.by(-1)
- end
-
- context 'when the async index table does not exist' do
- it 'does not raise an error' do
- connection.drop_table(:postgres_async_indexes)
-
- expect(index_model).not_to receive(:find_by)
-
- expect { migration.unprepare_async_index_by_name(table_name, index_name) }.not_to raise_error
- end
- end
+ it 'destroys the record' do
+ expect do
+ migration.unprepare_async_index_by_name(table_name, index_name)
+ end.to change { index_model.where(name: index_name).count }.by(-1)
end
- context 'when the feature flag is disabled' do
- it 'does not destroy the record' do
- stub_feature_flags(database_async_index_creation: false)
+ context 'when the async index table does not exist' do
+ it 'does not raise an error' do
+ connection.drop_table(:postgres_async_indexes)
- expect do
- migration.unprepare_async_index_by_name(table_name, index_name)
- end.not_to change { index_model.where(name: index_name).count }
+ expect(index_model).not_to receive(:find_by)
+
+ expect { migration.unprepare_async_index_by_name(table_name, index_name) }.not_to raise_error
end
end
end
@@ -101,14 +69,23 @@ RSpec.describe Gitlab::Database::AsyncIndexes::MigrationHelpers do
connection.create_table(table_name)
end
- context 'when the feature flag is enabled' do
- before do
- stub_feature_flags(database_async_index_creation: true)
- end
+ it 'creates the record for the async index' do
+ expect do
+ migration.prepare_async_index(table_name, 'id')
+ end.to change { index_model.where(name: index_name).count }.by(1)
+
+ record = index_model.find_by(name: index_name)
- it 'creates the record for the async index' do
+ expect(record.table_name).to eq(table_name)
+ expect(record.definition).to match(/CREATE INDEX CONCURRENTLY "#{index_name}"/)
+ end
+
+ context 'when an explicit name is given' do
+ let(:index_name) { 'my_async_index_name' }
+
+ it 'creates the record with the given name' do
expect do
- migration.prepare_async_index(table_name, 'id')
+ migration.prepare_async_index(table_name, 'id', name: index_name)
end.to change { index_model.where(name: index_name).count }.by(1)
record = index_model.find_by(name: index_name)
@@ -116,77 +93,52 @@ RSpec.describe Gitlab::Database::AsyncIndexes::MigrationHelpers do
expect(record.table_name).to eq(table_name)
expect(record.definition).to match(/CREATE INDEX CONCURRENTLY "#{index_name}"/)
end
+ end
- context 'when an explicit name is given' do
- let(:index_name) { 'my_async_index_name' }
-
- it 'creates the record with the given name' do
- expect do
- migration.prepare_async_index(table_name, 'id', name: index_name)
- end.to change { index_model.where(name: index_name).count }.by(1)
-
- record = index_model.find_by(name: index_name)
+ context 'when the index already exists' do
+ it 'does not create the record' do
+ connection.add_index(table_name, 'id', name: index_name)
- expect(record.table_name).to eq(table_name)
- expect(record.definition).to match(/CREATE INDEX CONCURRENTLY "#{index_name}"/)
- end
+ expect do
+ migration.prepare_async_index(table_name, 'id')
+ end.not_to change { index_model.where(name: index_name).count }
end
+ end
- context 'when the index already exists' do
- it 'does not create the record' do
- connection.add_index(table_name, 'id', name: index_name)
+ context 'when the record already exists' do
+ it 'does attempt to create the record' do
+ create(:postgres_async_index, table_name: table_name, name: index_name)
- expect do
- migration.prepare_async_index(table_name, 'id')
- end.not_to change { index_model.where(name: index_name).count }
- end
+ expect do
+ migration.prepare_async_index(table_name, 'id')
+ end.not_to change { index_model.where(name: index_name).count }
end
- context 'when the record already exists' do
- it 'does attempt to create the record' do
- create(:postgres_async_index, table_name: table_name, name: index_name)
-
- expect do
- migration.prepare_async_index(table_name, 'id')
- end.not_to change { index_model.where(name: index_name).count }
- end
-
- it 'updates definition if changed' do
- index = create(:postgres_async_index, table_name: table_name, name: index_name, definition: '...')
-
- expect do
- migration.prepare_async_index(table_name, 'id', name: index_name)
- end.to change { index.reload.definition }
- end
+ it 'updates definition if changed' do
+ index = create(:postgres_async_index, table_name: table_name, name: index_name, definition: '...')
- it 'does not update definition if not changed' do
- definition = "CREATE INDEX CONCURRENTLY \"index_#{table_name}_on_id\" ON \"#{table_name}\" (\"id\")"
- index = create(:postgres_async_index, table_name: table_name, name: index_name, definition: definition)
-
- expect do
- migration.prepare_async_index(table_name, 'id', name: index_name)
- end.not_to change { index.reload.updated_at }
- end
+ expect do
+ migration.prepare_async_index(table_name, 'id', name: index_name)
+ end.to change { index.reload.definition }
end
- context 'when the async index table does not exist' do
- it 'does not raise an error' do
- connection.drop_table(:postgres_async_indexes)
-
- expect(index_model).not_to receive(:safe_find_or_create_by!)
+ it 'does not update definition if not changed' do
+ definition = "CREATE INDEX CONCURRENTLY \"index_#{table_name}_on_id\" ON \"#{table_name}\" (\"id\")"
+ index = create(:postgres_async_index, table_name: table_name, name: index_name, definition: definition)
- expect { migration.prepare_async_index(table_name, 'id') }.not_to raise_error
- end
+ expect do
+ migration.prepare_async_index(table_name, 'id', name: index_name)
+ end.not_to change { index.reload.updated_at }
end
end
- context 'when the feature flag is disabled' do
- it 'does not create the record' do
- stub_feature_flags(database_async_index_creation: false)
+ context 'when the async index table does not exist' do
+ it 'does not raise an error' do
+ connection.drop_table(:postgres_async_indexes)
- expect do
- migration.prepare_async_index(table_name, 'id')
- end.not_to change { index_model.where(name: index_name).count }
+ expect(index_model).not_to receive(:safe_find_or_create_by!)
+
+ expect { migration.prepare_async_index(table_name, 'id') }.not_to raise_error
end
end
end
diff --git a/spec/lib/gitlab/database/background_migration/batched_job_spec.rb b/spec/lib/gitlab/database/background_migration/batched_job_spec.rb
index 7338ea657b9..8c663ff9f8a 100644
--- a/spec/lib/gitlab/database/background_migration/batched_job_spec.rb
+++ b/spec/lib/gitlab/database/background_migration/batched_job_spec.rb
@@ -5,6 +5,10 @@ require 'spec_helper'
RSpec.describe Gitlab::Database::BackgroundMigration::BatchedJob, type: :model do
it_behaves_like 'having unique enum values'
+ it { is_expected.to be_a Gitlab::Database::SharedModel }
+
+ it { expect(described_class::TIMEOUT_EXCEPTIONS).to match_array [ActiveRecord::StatementTimeout, ActiveRecord::ConnectionTimeoutError, ActiveRecord::AdapterTimeout, ActiveRecord::LockWaitTimeout] }
+
describe 'associations' do
it { is_expected.to belong_to(:batched_migration).with_foreign_key(:batched_background_migration_id) }
it { is_expected.to have_many(:batched_job_transition_logs).with_foreign_key(:batched_background_migration_job_id) }
@@ -13,6 +17,8 @@ RSpec.describe Gitlab::Database::BackgroundMigration::BatchedJob, type: :model d
describe 'state machine' do
let_it_be(:job) { create(:batched_background_migration_job, :failed) }
+ it { expect(described_class.state_machine.states.map(&:name)).to eql(%i(pending running failed succeeded)) }
+
context 'when a job is running' do
it 'logs the transition' do
expect(Gitlab::AppLogger).to receive(:info).with( { batched_job_id: job.id, message: 'BatchedJob transition', new_state: :running, previous_state: :failed } )
@@ -45,6 +51,51 @@ RSpec.describe Gitlab::Database::BackgroundMigration::BatchedJob, type: :model d
end
end
+ context 'when a job fails the number of max times' do
+ let(:max_times) { described_class::MAX_ATTEMPTS }
+ let!(:job) { create(:batched_background_migration_job, :running, batch_size: 10, min_value: 6, max_value: 15, attempts: max_times) }
+
+ context 'when job can be split' do
+ let(:exception) { ActiveRecord::StatementTimeout.new('Timeout!') }
+
+ before do
+ allow_next_instance_of(Gitlab::BackgroundMigration::BatchingStrategies::PrimaryKeyBatchingStrategy) do |batch_class|
+ allow(batch_class).to receive(:next_batch).and_return([6, 10])
+ end
+ end
+
+ it 'splits the job into two retriable jobs' do
+ expect { job.failure!(error: exception) }.to change { job.batched_migration.batched_jobs.retriable.count }.from(0).to(2)
+ end
+ end
+
+ context 'when the job cannot be split' do
+ let(:exception) { ActiveRecord::StatementTimeout.new('Timeout!') }
+ let(:max_times) { described_class::MAX_ATTEMPTS }
+ let!(:job) { create(:batched_background_migration_job, :running, batch_size: 50, sub_batch_size: 20, min_value: 6, max_value: 15, attempts: max_times) }
+ let(:error_message) { 'Job cannot be split further' }
+ let(:split_and_retry_exception) { Gitlab::Database::BackgroundMigration::SplitAndRetryError.new(error_message) }
+
+ before do
+ allow(job).to receive(:split_and_retry!).and_raise(split_and_retry_exception)
+ end
+
+ it 'does not split the job' do
+ expect { job.failure!(error: exception) }.not_to change { job.batched_migration.batched_jobs.retriable.count }
+ end
+
+ it 'keeps the same job attributes' do
+ expect { job.failure!(error: exception) }.not_to change { job }
+ end
+
+ it 'logs the error' do
+ expect(Gitlab::AppLogger).to receive(:error).with( { message: error_message, batched_job_id: job.id } )
+
+ job.failure!(error: exception)
+ end
+ end
+ end
+
context 'when a job fails' do
let(:job) { create(:batched_background_migration_job, :running) }
@@ -145,6 +196,49 @@ RSpec.describe Gitlab::Database::BackgroundMigration::BatchedJob, type: :model d
end
end
+ describe '#can_split?' do
+ subject { job.can_split?(exception) }
+
+ context 'when the number of attempts is greater than the limit and the batch_size is greater than the sub_batch_size' do
+ let(:job) { create(:batched_background_migration_job, :failed, batch_size: 4, sub_batch_size: 2, attempts: described_class::MAX_ATTEMPTS + 1) }
+
+ context 'when is a timeout exception' do
+ let(:exception) { ActiveRecord::StatementTimeout.new }
+
+ it { expect(subject).to be_truthy }
+ end
+
+ context 'when is not a timeout exception' do
+ let(:exception) { RuntimeError.new }
+
+ it { expect(subject).to be_falsey }
+ end
+ end
+
+ context 'when the number of attempts is lower than the limit and the batch_size is greater than the sub_batch_size' do
+ let(:job) { create(:batched_background_migration_job, :failed, batch_size: 4, sub_batch_size: 2, attempts: described_class::MAX_ATTEMPTS - 1) }
+
+ context 'when is a timeout exception' do
+ let(:exception) { ActiveRecord::StatementTimeout.new }
+
+ it { expect(subject).to be_falsey }
+ end
+
+ context 'when is not a timeout exception' do
+ let(:exception) { RuntimeError.new }
+
+ it { expect(subject).to be_falsey }
+ end
+ end
+
+ context 'when the batch_size is lower than the sub_batch_size' do
+ let(:job) { create(:batched_background_migration_job, :failed, batch_size: 2, sub_batch_size: 4) }
+ let(:exception) { ActiveRecord::StatementTimeout.new }
+
+ it { expect(subject).to be_falsey }
+ end
+ end
+
describe '#time_efficiency' do
subject { job.time_efficiency }
@@ -197,15 +291,17 @@ RSpec.describe Gitlab::Database::BackgroundMigration::BatchedJob, type: :model d
end
describe '#split_and_retry!' do
- let!(:job) { create(:batched_background_migration_job, :failed, batch_size: 10, min_value: 6, max_value: 15, attempts: 3) }
+ let_it_be(:migration) { create(:batched_background_migration, table_name: :events) }
+ let_it_be(:job) { create(:batched_background_migration_job, :failed, batched_migration: migration, batch_size: 10, min_value: 6, max_value: 15, attempts: 3) }
+ let_it_be(:project) { create(:project) }
- context 'when job can be split' do
- before do
- allow_next_instance_of(Gitlab::BackgroundMigration::BatchingStrategies::PrimaryKeyBatchingStrategy) do |batch_class|
- allow(batch_class).to receive(:next_batch).with(anything, anything, batch_min_value: 6, batch_size: 5).and_return([6, 10])
- end
+ before_all do
+ (6..16).each do |id|
+ create(:event, id: id, project: project)
end
+ end
+ context 'when job can be split' do
it 'sets the correct attributes' do
expect { job.split_and_retry! }.to change { described_class.count }.by(1)
@@ -261,9 +357,7 @@ RSpec.describe Gitlab::Database::BackgroundMigration::BatchedJob, type: :model d
context 'when computed midpoint is larger than the max value of the batch' do
before do
- allow_next_instance_of(Gitlab::BackgroundMigration::BatchingStrategies::PrimaryKeyBatchingStrategy) do |batch_class|
- allow(batch_class).to receive(:next_batch).with(anything, anything, batch_min_value: 6, batch_size: 5).and_return([6, 16])
- end
+ Event.where(id: 6..12).delete_all
end
it 'lowers the batch size and resets the number of attempts' do
diff --git a/spec/lib/gitlab/database/background_migration/batched_job_transition_log_spec.rb b/spec/lib/gitlab/database/background_migration/batched_job_transition_log_spec.rb
index c42a0fc5e05..59f4f40c0ef 100644
--- a/spec/lib/gitlab/database/background_migration/batched_job_transition_log_spec.rb
+++ b/spec/lib/gitlab/database/background_migration/batched_job_transition_log_spec.rb
@@ -3,6 +3,8 @@
require 'spec_helper'
RSpec.describe Gitlab::Database::BackgroundMigration::BatchedJobTransitionLog, type: :model do
+ it { is_expected.to be_a Gitlab::Database::SharedModel }
+
describe 'associations' do
it { is_expected.to belong_to(:batched_job).with_foreign_key(:batched_background_migration_job_id) }
end
diff --git a/spec/lib/gitlab/database/background_migration/batched_migration_runner_spec.rb b/spec/lib/gitlab/database/background_migration/batched_migration_runner_spec.rb
index bb2c6b9a3ae..124d204cb62 100644
--- a/spec/lib/gitlab/database/background_migration/batched_migration_runner_spec.rb
+++ b/spec/lib/gitlab/database/background_migration/batched_migration_runner_spec.rb
@@ -428,4 +428,27 @@ RSpec.describe Gitlab::Database::BackgroundMigration::BatchedMigrationRunner do
end
end
end
+
+ describe '.finalize' do
+ context 'when the connection is passed' do
+ let(:connection) { double('connection') }
+
+ let(:table_name) { :_test_batched_migrations_test_table }
+ let(:column_name) { :some_id }
+ let(:job_arguments) { [:some, :other, :arguments] }
+ let(:batched_migration) { create(:batched_background_migration, table_name: table_name, column_name: column_name) }
+
+ it 'initializes the object with the given connection' do
+ expect(described_class).to receive(:new).with(connection: connection).and_call_original
+
+ described_class.finalize(
+ batched_migration.job_class_name,
+ table_name,
+ column_name,
+ job_arguments,
+ connection: connection
+ )
+ end
+ end
+ end
end
diff --git a/spec/lib/gitlab/database/background_migration/batched_migration_spec.rb b/spec/lib/gitlab/database/background_migration/batched_migration_spec.rb
index ea4ba4dd137..803123e8e34 100644
--- a/spec/lib/gitlab/database/background_migration/batched_migration_spec.rb
+++ b/spec/lib/gitlab/database/background_migration/batched_migration_spec.rb
@@ -5,6 +5,8 @@ require 'spec_helper'
RSpec.describe Gitlab::Database::BackgroundMigration::BatchedMigration, type: :model do
it_behaves_like 'having unique enum values'
+ it { is_expected.to be_a Gitlab::Database::SharedModel }
+
describe 'associations' do
it { is_expected.to have_many(:batched_jobs).with_foreign_key(:batched_background_migration_id) }
@@ -272,7 +274,13 @@ RSpec.describe Gitlab::Database::BackgroundMigration::BatchedMigration, type: :m
before do
allow_next_instance_of(Gitlab::BackgroundMigration::BatchingStrategies::PrimaryKeyBatchingStrategy) do |batch_class|
- allow(batch_class).to receive(:next_batch).with(anything, anything, batch_min_value: 6, batch_size: 5).and_return([6, 10])
+ allow(batch_class).to receive(:next_batch).with(
+ anything,
+ anything,
+ batch_min_value: 6,
+ batch_size: 5,
+ job_arguments: batched_migration.job_arguments
+ ).and_return([6, 10])
end
end
diff --git a/spec/lib/gitlab/database/background_migration/batched_migration_wrapper_spec.rb b/spec/lib/gitlab/database/background_migration/batched_migration_wrapper_spec.rb
index 4f5536d8771..d6c984c7adb 100644
--- a/spec/lib/gitlab/database/background_migration/batched_migration_wrapper_spec.rb
+++ b/spec/lib/gitlab/database/background_migration/batched_migration_wrapper_spec.rb
@@ -193,6 +193,7 @@ RSpec.describe Gitlab::Database::BackgroundMigration::BatchedMigrationWrapper, '
it_behaves_like 'an error is raised', RuntimeError.new('Something broke!')
it_behaves_like 'an error is raised', SignalException.new('SIGTERM')
+ it_behaves_like 'an error is raised', ActiveRecord::StatementTimeout.new('Timeout!')
end
context 'when the batched background migration does not inherit from BaseJob' do
diff --git a/spec/lib/gitlab/database/each_database_spec.rb b/spec/lib/gitlab/database/each_database_spec.rb
index d526b3bc1ac..d46c1ca8681 100644
--- a/spec/lib/gitlab/database/each_database_spec.rb
+++ b/spec/lib/gitlab/database/each_database_spec.rb
@@ -3,13 +3,13 @@
require 'spec_helper'
RSpec.describe Gitlab::Database::EachDatabase do
- describe '.each_database_connection' do
+ describe '.each_database_connection', :add_ci_connection do
before do
allow(Gitlab::Database).to receive(:database_base_models)
.and_return({ main: ActiveRecord::Base, ci: Ci::ApplicationRecord }.with_indifferent_access)
end
- it 'yields each connection after connecting SharedModel', :add_ci_connection do
+ it 'yields each connection after connecting SharedModel' do
expect(Gitlab::Database::SharedModel).to receive(:using_connection)
.with(ActiveRecord::Base.connection).ordered.and_yield
@@ -22,6 +22,42 @@ RSpec.describe Gitlab::Database::EachDatabase do
[Ci::ApplicationRecord.connection, 'ci']
)
end
+
+ context 'when only certain databases are selected' do
+ it 'yields the selected connections after connecting SharedModel' do
+ expect(Gitlab::Database::SharedModel).to receive(:using_connection)
+ .with(Ci::ApplicationRecord.connection).ordered.and_yield
+
+ expect { |b| described_class.each_database_connection(only: 'ci', &b) }
+ .to yield_successive_args([Ci::ApplicationRecord.connection, 'ci'])
+ end
+
+ context 'when the selected names are passed as symbols' do
+ it 'yields the selected connections after connecting SharedModel' do
+ expect(Gitlab::Database::SharedModel).to receive(:using_connection)
+ .with(Ci::ApplicationRecord.connection).ordered.and_yield
+
+ expect { |b| described_class.each_database_connection(only: :ci, &b) }
+ .to yield_successive_args([Ci::ApplicationRecord.connection, 'ci'])
+ end
+ end
+
+ context 'when the selected names are invalid' do
+ it 'does not yield any connections' do
+ expect do |b|
+ described_class.each_database_connection(only: :notvalid, &b)
+ rescue ArgumentError => e
+ expect(e.message).to match(/notvalid is not a valid database name/)
+ end.not_to yield_control
+ end
+
+ it 'raises an error' do
+ expect do
+ described_class.each_database_connection(only: :notvalid) {}
+ end.to raise_error(ArgumentError, /notvalid is not a valid database name/)
+ end
+ end
+ end
end
describe '.each_model_connection' do
@@ -69,8 +105,8 @@ RSpec.describe Gitlab::Database::EachDatabase do
allow(main_model).to receive(:connection).and_return(main_connection)
allow(ci_model).to receive(:connection).and_return(ci_connection)
- allow(main_connection).to receive_message_chain('pool.db_config.name').and_return('main')
- allow(ci_connection).to receive_message_chain('pool.db_config.name').and_return('ci')
+ allow(main_model).to receive_message_chain('connection_db_config.name').and_return('main')
+ allow(ci_model).to receive_message_chain('connection_db_config.name').and_return('ci')
end
it 'yields each model after connecting SharedModel' do
@@ -81,10 +117,44 @@ RSpec.describe Gitlab::Database::EachDatabase do
end
end
- def expect_yielded_models(models_to_iterate, expected_values)
+ context 'when the database connections are limited by the only_on option' do
+ let(:shared_model) { Class.new(Gitlab::Database::SharedModel) }
+ let(:main_model) { Class.new(ActiveRecord::Base) }
+ let(:ci_model) { Class.new(Ci::ApplicationRecord) }
+
+ before do
+ allow(Gitlab::Database).to receive(:database_base_models)
+ .and_return({ main: ActiveRecord::Base, ci: Ci::ApplicationRecord }.with_indifferent_access)
+
+ allow(main_model).to receive_message_chain('connection_db_config.name').and_return('main')
+ allow(ci_model).to receive_message_chain('connection_db_config.name').and_return('ci')
+ end
+
+ context 'when a single name is passed in' do
+ it 'yields models only connected to the given database' do
+ expect_yielded_models([main_model, ci_model, shared_model], [
+ { model: ci_model, connection: Ci::ApplicationRecord.connection, name: 'ci' },
+ { model: shared_model, connection: Ci::ApplicationRecord.connection, name: 'ci' }
+ ], only_on: 'ci')
+ end
+ end
+
+ context 'when a list of names are passed in' do
+ it 'yields models only connected to the given databases' do
+ expect_yielded_models([main_model, ci_model, shared_model], [
+ { model: main_model, connection: ActiveRecord::Base.connection, name: 'main' },
+ { model: ci_model, connection: Ci::ApplicationRecord.connection, name: 'ci' },
+ { model: shared_model, connection: ActiveRecord::Base.connection, name: 'main' },
+ { model: shared_model, connection: Ci::ApplicationRecord.connection, name: 'ci' }
+ ], only_on: %i[main ci])
+ end
+ end
+ end
+
+ def expect_yielded_models(models_to_iterate, expected_values, only_on: nil)
times_yielded = 0
- described_class.each_model_connection(models_to_iterate) do |model, name|
+ described_class.each_model_connection(models_to_iterate, only_on: only_on) do |model, name|
expected = expected_values[times_yielded]
expect(model).to be(expected[:model])
diff --git a/spec/lib/gitlab/database/load_balancing/configuration_spec.rb b/spec/lib/gitlab/database/load_balancing/configuration_spec.rb
index e87c9c20707..77284b4d128 100644
--- a/spec/lib/gitlab/database/load_balancing/configuration_spec.rb
+++ b/spec/lib/gitlab/database/load_balancing/configuration_spec.rb
@@ -7,13 +7,6 @@ RSpec.describe Gitlab::Database::LoadBalancing::Configuration, :request_store do
let(:db_config) { ActiveRecord::DatabaseConfigurations::HashConfig.new('test', 'ci', configuration_hash) }
let(:model) { double(:model, connection_db_config: db_config) }
- before do
- # It's confusing to think about these specs with this enabled by default so
- # we make it disabled by default and just write the specific spec for when
- # it's enabled
- stub_feature_flags(force_no_sharing_primary_model: false)
- end
-
describe '.for_model' do
context 'when load balancing is not configured' do
it 'uses the default settings' do
diff --git a/spec/lib/gitlab/database/load_balancing/setup_spec.rb b/spec/lib/gitlab/database/load_balancing/setup_spec.rb
index 20519a759b2..4d565ce137a 100644
--- a/spec/lib/gitlab/database/load_balancing/setup_spec.rb
+++ b/spec/lib/gitlab/database/load_balancing/setup_spec.rb
@@ -274,6 +274,8 @@ RSpec.describe Gitlab::Database::LoadBalancing::Setup do
end
before do
+ allow(Gitlab).to receive(:dev_or_test_env?).and_return(false)
+
# Rewrite `class_attribute` to use rspec mocking and prevent modifying the objects
allow_next_instance_of(described_class) do |setup|
allow(setup).to receive(:configure_connection)
diff --git a/spec/lib/gitlab/database/load_balancing_spec.rb b/spec/lib/gitlab/database/load_balancing_spec.rb
index 45878b2e266..f320fe0276f 100644
--- a/spec/lib/gitlab/database/load_balancing_spec.rb
+++ b/spec/lib/gitlab/database/load_balancing_spec.rb
@@ -92,6 +92,18 @@ RSpec.describe Gitlab::Database::LoadBalancing do
end
end
+ context 'when an invalid connection is used' do
+ it 'returns :unknown' do
+ expect(described_class.db_role_for_connection(:invalid)).to eq(:unknown)
+ end
+ end
+
+ context 'when a null connection is used' do
+ it 'returns :unknown' do
+ expect(described_class.db_role_for_connection(nil)).to eq(:unknown)
+ end
+ end
+
context 'when a read connection is used' do
it 'returns :replica' do
load_balancer.read do |connection|
diff --git a/spec/lib/gitlab/database/migration_helpers/restrict_gitlab_schema_spec.rb b/spec/lib/gitlab/database/migration_helpers/restrict_gitlab_schema_spec.rb
new file mode 100644
index 00000000000..ad9a3a6e257
--- /dev/null
+++ b/spec/lib/gitlab/database/migration_helpers/restrict_gitlab_schema_spec.rb
@@ -0,0 +1,561 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Database::MigrationHelpers::RestrictGitlabSchema, query_analyzers: false, stub_feature_flags: false do
+ let(:schema_class) { Class.new(Gitlab::Database::Migration[1.0]).include(described_class) }
+
+ describe '#restrict_gitlab_migration' do
+ it 'invalid schema raises exception' do
+ expect { schema_class.restrict_gitlab_migration gitlab_schema: :gitlab_non_exisiting }
+ .to raise_error /Unknown 'gitlab_schema:/
+ end
+
+ it 'does configure allowed_gitlab_schema' do
+ schema_class.restrict_gitlab_migration gitlab_schema: :gitlab_main
+
+ expect(schema_class.allowed_gitlab_schemas).to eq(%i[gitlab_main])
+ end
+ end
+
+ context 'when executing migrations' do
+ using RSpec::Parameterized::TableSyntax
+
+ where do
+ {
+ "does create table in gitlab_main and gitlab_ci" => {
+ migration: ->(klass) do
+ def change
+ create_table :_test_table do |t|
+ t.references :project, foreign_key: true, null: false
+ t.timestamps_with_timezone null: false
+ end
+ end
+ end,
+ query_matcher: /CREATE TABLE "_test_table"/,
+ expected: {
+ no_gitlab_schema: {
+ main: :success,
+ ci: :success
+ },
+ gitlab_schema_gitlab_shared: {
+ main: :ddl_not_allowed,
+ ci: :ddl_not_allowed
+ },
+ gitlab_schema_gitlab_main: {
+ main: :ddl_not_allowed,
+ ci: :skipped
+ }
+ }
+ },
+ "does add column to projects in gitlab_main and gitlab_ci" => {
+ migration: ->(klass) do
+ def change
+ add_column :projects, :__test_column, :integer
+ end
+ end,
+ query_matcher: /ALTER TABLE "projects" ADD "__test_column" integer/,
+ expected: {
+ no_gitlab_schema: {
+ main: :success,
+ ci: :success
+ },
+ gitlab_schema_gitlab_shared: {
+ main: :ddl_not_allowed,
+ ci: :ddl_not_allowed
+ },
+ gitlab_schema_gitlab_main: {
+ main: :ddl_not_allowed,
+ ci: :skipped
+ }
+ }
+ },
+ "does add column to ci_builds in gitlab_main and gitlab_ci" => {
+ migration: ->(klass) do
+ def change
+ add_column :ci_builds, :__test_column, :integer
+ end
+ end,
+ query_matcher: /ALTER TABLE "ci_builds" ADD "__test_column" integer/,
+ expected: {
+ no_gitlab_schema: {
+ main: :success,
+ ci: :success
+ },
+ gitlab_schema_gitlab_shared: {
+ main: :ddl_not_allowed,
+ ci: :ddl_not_allowed
+ },
+ gitlab_schema_gitlab_main: {
+ main: :ddl_not_allowed,
+ ci: :skipped
+ }
+ }
+ },
+ "does add index to projects in gitlab_main and gitlab_ci" => {
+ migration: ->(klass) do
+ def change
+ # Due to running in transactin we cannot use `add_concurrent_index`
+ add_index :projects, :hidden
+ end
+ end,
+ query_matcher: /CREATE INDEX/,
+ expected: {
+ no_gitlab_schema: {
+ main: :success,
+ ci: :success
+ },
+ gitlab_schema_gitlab_shared: {
+ main: :ddl_not_allowed,
+ ci: :ddl_not_allowed
+ },
+ gitlab_schema_gitlab_main: {
+ main: :ddl_not_allowed,
+ ci: :skipped
+ }
+ }
+ },
+ "does add index to ci_builds in gitlab_main and gitlab_ci" => {
+ migration: ->(klass) do
+ def change
+ # Due to running in transactin we cannot use `add_concurrent_index`
+ add_index :ci_builds, :tag, where: "type = 'Ci::Build'", name: 'index_ci_builds_on_tag_and_type_eq_ci_build'
+ end
+ end,
+ query_matcher: /CREATE INDEX/,
+ expected: {
+ no_gitlab_schema: {
+ main: :success,
+ ci: :success
+ },
+ gitlab_schema_gitlab_shared: {
+ main: :ddl_not_allowed,
+ ci: :ddl_not_allowed
+ },
+ gitlab_schema_gitlab_main: {
+ main: :ddl_not_allowed,
+ ci: :skipped
+ }
+ }
+ },
+ "does create trigger in gitlab_main and gitlab_ci" => {
+ migration: ->(klass) do
+ include Gitlab::Database::SchemaHelpers
+
+ def up
+ create_trigger_function('_test_trigger_function', replace: true) do
+ <<~SQL
+ RETURN NULL;
+ SQL
+ end
+ end
+
+ def down
+ drop_function('_test_trigger_function')
+ end
+ end,
+ query_matcher: /CREATE OR REPLACE FUNCTION/,
+ expected: {
+ no_gitlab_schema: {
+ main: :success,
+ ci: :success
+ },
+ gitlab_schema_gitlab_shared: {
+ main: :ddl_not_allowed,
+ ci: :ddl_not_allowed
+ },
+ gitlab_schema_gitlab_main: {
+ main: :ddl_not_allowed,
+ ci: :skipped
+ }
+ }
+ },
+ "does create schema in gitlab_main and gitlab_ci" => {
+ migration: ->(klass) do
+ include Gitlab::Database::SchemaHelpers
+
+ def up
+ execute("create schema __test_schema")
+ end
+
+ def down
+ end
+ end,
+ query_matcher: /create schema __test_schema/,
+ expected: {
+ no_gitlab_schema: {
+ main: :success,
+ ci: :success
+ },
+ gitlab_schema_gitlab_shared: {
+ main: :success,
+ ci: :success
+ },
+ gitlab_schema_gitlab_main: {
+ # This is not properly detected today since there are no helpers
+ # available to consider this as a DDL type of change
+ main: :success,
+ ci: :skipped
+ }
+ }
+ },
+ "does attach loose foreign key trigger in gitlab_main and gitlab_ci" => {
+ migration: ->(klass) do
+ include Gitlab::Database::MigrationHelpers::LooseForeignKeyHelpers
+
+ enable_lock_retries!
+
+ def up
+ track_record_deletions(:audit_events)
+ end
+
+ def down
+ untrack_record_deletions(:audit_events)
+ end
+ end,
+ query_matcher: /CREATE TRIGGER/,
+ expected: {
+ no_gitlab_schema: {
+ main: :success,
+ ci: :success
+ },
+ gitlab_schema_gitlab_shared: {
+ main: :ddl_not_allowed,
+ ci: :ddl_not_allowed
+ },
+ gitlab_schema_gitlab_main: {
+ main: :ddl_not_allowed,
+ ci: :skipped
+ }
+ }
+ },
+ "does insert into software_licenses" => {
+ migration: ->(klass) do
+ def up
+ software_license_class.create!(name: 'aaa')
+ end
+
+ def down
+ software_license_class.where(name: 'aaa').delete_all
+ end
+
+ def software_license_class
+ Class.new(ActiveRecord::Base) do
+ self.table_name = 'software_licenses'
+ end
+ end
+ end,
+ query_matcher: /INSERT INTO "software_licenses"/,
+ expected: {
+ no_gitlab_schema: {
+ main: :dml_not_allowed,
+ ci: :dml_not_allowed
+ },
+ gitlab_schema_gitlab_shared: {
+ main: :dml_access_denied,
+ ci: :dml_access_denied
+ },
+ gitlab_schema_gitlab_main: {
+ main: :success,
+ ci: :skipped
+ }
+ }
+ },
+ "does raise exception when accessing tables outside of gitlab_main" => {
+ migration: ->(klass) do
+ def up
+ ci_instance_variables_class.create!(variable_type: 1, key: 'aaa')
+ end
+
+ def down
+ ci_instance_variables_class.delete_all
+ end
+
+ def ci_instance_variables_class
+ Class.new(ActiveRecord::Base) do
+ self.table_name = 'ci_instance_variables'
+ end
+ end
+ end,
+ query_matcher: /INSERT INTO "ci_instance_variables"/,
+ expected: {
+ no_gitlab_schema: {
+ main: :dml_not_allowed,
+ ci: :dml_not_allowed
+ },
+ gitlab_schema_gitlab_shared: {
+ main: :dml_access_denied,
+ ci: :dml_access_denied
+ },
+ gitlab_schema_gitlab_main: {
+ main: :dml_access_denied,
+ ci: :skipped
+ }
+ }
+ },
+ "does allow modifying gitlab_shared" => {
+ migration: ->(klass) do
+ def up
+ detached_partitions_class.create!(drop_after: Time.current, table_name: '_test_table')
+ end
+
+ def down
+ end
+
+ def detached_partitions_class
+ Class.new(ActiveRecord::Base) do
+ self.table_name = 'detached_partitions'
+ end
+ end
+ end,
+ query_matcher: /INSERT INTO "detached_partitions"/,
+ expected: {
+ no_gitlab_schema: {
+ main: :success,
+ ci: :success
+ },
+ gitlab_schema_gitlab_shared: {
+ main: :success,
+ ci: :success
+ },
+ gitlab_schema_gitlab_main: {
+ # TBD: This allow to selectively modify shared tables in context of a specific DB only
+ main: :success,
+ ci: :skipped
+ }
+ }
+ },
+ "does update data in batches of gitlab_main, but skips gitlab_ci" => {
+ migration: ->(klass) do
+ def up
+ update_column_in_batches(:projects, :archived, true) do |table, query|
+ query.where(table[:archived].eq(false)) # rubocop:disable CodeReuse/ActiveRecord
+ end
+ end
+
+ def down
+ # no-op
+ end
+ end,
+ query_matcher: /FROM "projects"/,
+ expected: {
+ no_gitlab_schema: {
+ main: :dml_not_allowed,
+ ci: :dml_not_allowed
+ },
+ gitlab_schema_gitlab_shared: {
+ main: :dml_access_denied,
+ ci: :dml_access_denied
+ },
+ gitlab_schema_gitlab_main: {
+ main: :success,
+ ci: :skipped
+ }
+ }
+ },
+ "does not allow executing mixed DDL and DML migrations" => {
+ migration: ->(klass) do
+ def up
+ execute('UPDATE projects SET hidden=false')
+ add_index(:projects, :hidden, name: 'test_index')
+ end
+
+ def down
+ # no-op
+ end
+ end,
+ expected: {
+ no_gitlab_schema: {
+ main: :dml_not_allowed,
+ ci: :dml_not_allowed
+ },
+ gitlab_schema_gitlab_shared: {
+ main: :dml_access_denied,
+ ci: :dml_access_denied
+ },
+ gitlab_schema_gitlab_main: {
+ main: :ddl_not_allowed,
+ ci: :skipped
+ }
+ }
+ },
+ "does schedule background migrations on gitlab_main" => {
+ migration: ->(klass) do
+ def up
+ queue_background_migration_jobs_by_range_at_intervals(
+ define_batchable_model('vulnerability_occurrences'),
+ 'RemoveDuplicateVulnerabilitiesFindings',
+ 2.minutes.to_i,
+ batch_size: 5_000
+ )
+ end
+
+ def down
+ # no-op
+ end
+ end,
+ query_matcher: /FROM "vulnerability_occurrences"/,
+ expected: {
+ no_gitlab_schema: {
+ main: :dml_not_allowed,
+ ci: :dml_not_allowed
+ },
+ gitlab_schema_gitlab_shared: {
+ main: :dml_access_denied,
+ ci: :dml_access_denied
+ },
+ gitlab_schema_gitlab_main: {
+ main: :success,
+ ci: :skipped
+ }
+ }
+ },
+ "does support prepare_async_index" => {
+ migration: ->(klass) do
+ def up
+ prepare_async_index :projects, :hidden,
+ name: :index_projects_on_hidden
+ end
+
+ def down
+ unprepare_async_index_by_name :projects, :index_projects_on_hidden
+ end
+ end,
+ query_matcher: /INSERT INTO "postgres_async_indexes"/,
+ expected: {
+ no_gitlab_schema: {
+ main: :success,
+ ci: :success
+ },
+ gitlab_schema_gitlab_shared: {
+ main: :dml_not_allowed,
+ ci: :dml_not_allowed
+ },
+ gitlab_schema_gitlab_main: {
+ main: :dml_not_allowed,
+ ci: :skipped
+ }
+ }
+ },
+ "does raise exception when accessing current settings" => {
+ migration: ->(klass) do
+ def up
+ ApplicationSetting.last
+ end
+
+ def down
+ end
+ end,
+ query_matcher: /FROM "application_settings"/,
+ expected: {
+ no_gitlab_schema: {
+ main: :dml_not_allowed,
+ ci: :dml_not_allowed
+ },
+ gitlab_schema_gitlab_shared: {
+ main: :dml_access_denied,
+ ci: :dml_access_denied
+ },
+ gitlab_schema_gitlab_main: {
+ main: :success,
+ ci: :skipped
+ }
+ }
+ },
+ "does raise exception when accessing feature flags" => {
+ migration: ->(klass) do
+ def up
+ Feature.enabled?(:redis_hll_tracking, type: :ops, default_enabled: :yaml)
+ end
+
+ def down
+ end
+ end,
+ query_matcher: /FROM "features"/,
+ expected: {
+ no_gitlab_schema: {
+ main: :dml_not_allowed,
+ ci: :dml_not_allowed
+ },
+ gitlab_schema_gitlab_shared: {
+ main: :dml_access_denied,
+ ci: :dml_access_denied
+ },
+ gitlab_schema_gitlab_main: {
+ main: :success,
+ ci: :skipped
+ }
+ }
+ }
+ }
+ end
+
+ with_them do
+ let(:migration_class) { Class.new(schema_class, &migration) }
+
+ Gitlab::Database.database_base_models.each do |db_config_name, model|
+ context "for db_config_name=#{db_config_name}" do
+ around do |example|
+ with_reestablished_active_record_base do
+ reconfigure_db_connection(model: ActiveRecord::Base, config_model: model)
+
+ example.run
+ end
+ end
+
+ before do
+ allow_next_instance_of(migration_class) do |migration|
+ allow(migration).to receive(:transaction_open?).and_return(false)
+ end
+ end
+
+ %i[no_gitlab_schema gitlab_schema_gitlab_main gitlab_schema_gitlab_shared].each do |restrict_gitlab_migration|
+ context "while restrict_gitlab_migration=#{restrict_gitlab_migration}" do
+ it "does run migrate :up and :down" do
+ expected_result = expected.fetch(restrict_gitlab_migration)[db_config_name.to_sym]
+ skip "not configured" unless expected_result
+
+ case restrict_gitlab_migration
+ when :no_gitlab_schema
+ # no-op
+ when :gitlab_schema_gitlab_main
+ migration_class.restrict_gitlab_migration gitlab_schema: :gitlab_main
+ when :gitlab_schema_gitlab_shared
+ migration_class.restrict_gitlab_migration gitlab_schema: :gitlab_shared
+ end
+
+ # In some cases (for :down) we ignore error and expect no other errors
+ case expected_result
+ when :success
+ expect { migration_class.migrate(:up) }.to make_queries_matching(query_matcher)
+ expect { migration_class.migrate(:down) }.not_to make_queries_matching(query_matcher)
+
+ when :dml_not_allowed
+ expect { migration_class.migrate(:up) }.to raise_error(Gitlab::Database::QueryAnalyzers::RestrictAllowedSchemas::DMLNotAllowedError)
+ expect { ignore_error(Gitlab::Database::QueryAnalyzers::RestrictAllowedSchemas::DMLNotAllowedError) { migration_class.migrate(:down) } }.not_to raise_error
+
+ when :dml_access_denied
+ expect { migration_class.migrate(:up) }.to raise_error(Gitlab::Database::QueryAnalyzers::RestrictAllowedSchemas::DMLAccessDeniedError)
+ expect { ignore_error(Gitlab::Database::QueryAnalyzers::RestrictAllowedSchemas::DMLAccessDeniedError) { migration_class.migrate(:down) } }.not_to raise_error
+
+ when :ddl_not_allowed
+ expect { migration_class.migrate(:up) }.to raise_error(Gitlab::Database::QueryAnalyzers::RestrictAllowedSchemas::DDLNotAllowedError)
+ expect { ignore_error(Gitlab::Database::QueryAnalyzers::RestrictAllowedSchemas::DDLNotAllowedError) { migration_class.migrate(:down) } }.not_to raise_error
+
+ when :skipped
+ expect { migration_class.migrate(:up) }.to raise_error(Gitlab::Database::MigrationHelpers::RestrictGitlabSchema::MigrationSkippedError)
+ expect { migration_class.migrate(:down) }.to raise_error(Gitlab::Database::MigrationHelpers::RestrictGitlabSchema::MigrationSkippedError)
+ end
+ end
+ end
+ end
+
+ def ignore_error(error)
+ yield
+ rescue error
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/database/migrations/background_migration_helpers_spec.rb b/spec/lib/gitlab/database/migrations/background_migration_helpers_spec.rb
index 96dc3a0fc28..e64f5807385 100644
--- a/spec/lib/gitlab/database/migrations/background_migration_helpers_spec.rb
+++ b/spec/lib/gitlab/database/migrations/background_migration_helpers_spec.rb
@@ -164,11 +164,19 @@ RSpec.describe Gitlab::Database::Migrations::BackgroundMigrationHelpers do
end
end
- context "when the primary_column_name is not an integer" do
+ context 'when the primary_column_name is a string' do
+ it 'does not raise error' do
+ expect do
+ model.queue_background_migration_jobs_by_range_at_intervals(ContainerExpirationPolicy, 'FooJob', 10.minutes, primary_column_name: :name_regex)
+ end.not_to raise_error
+ end
+ end
+
+ context "when the primary_column_name is not an integer or a string" do
it 'raises error' do
expect do
model.queue_background_migration_jobs_by_range_at_intervals(ContainerExpirationPolicy, 'FooJob', 10.minutes, primary_column_name: :enabled)
- end.to raise_error(StandardError, /is not an integer column/)
+ end.to raise_error(StandardError, /is not an integer or string column/)
end
end
diff --git a/spec/lib/gitlab/database/migrations/observers/query_details_spec.rb b/spec/lib/gitlab/database/migrations/observers/query_details_spec.rb
index a757cac0a2a..35e4cef6da5 100644
--- a/spec/lib/gitlab/database/migrations/observers/query_details_spec.rb
+++ b/spec/lib/gitlab/database/migrations/observers/query_details_spec.rb
@@ -9,7 +9,7 @@ RSpec.describe Gitlab::Database::Migrations::Observers::QueryDetails do
let(:query) { "select date_trunc('day', $1::timestamptz) + $2 * (interval '1 hour')" }
let(:query_binds) { [Time.current, 3] }
let(:directory_path) { Dir.mktmpdir }
- let(:log_file) { "#{directory_path}/#{migration_version}_#{migration_name}-query-details.json" }
+ let(:log_file) { "#{directory_path}/query-details.json" }
let(:query_details) { Gitlab::Json.parse(File.read(log_file)) }
let(:migration_version) { 20210422152437 }
let(:migration_name) { 'test' }
diff --git a/spec/lib/gitlab/database/migrations/observers/query_log_spec.rb b/spec/lib/gitlab/database/migrations/observers/query_log_spec.rb
index eb66972e5ab..34678b77a0f 100644
--- a/spec/lib/gitlab/database/migrations/observers/query_log_spec.rb
+++ b/spec/lib/gitlab/database/migrations/observers/query_log_spec.rb
@@ -18,7 +18,7 @@ RSpec.describe Gitlab::Database::Migrations::Observers::QueryLog do
it 'writes a file with the query log' do
observe
- expect(File.read("#{directory_path}/#{migration_version}_#{migration_name}.log")).to include(query)
+ expect(File.read("#{directory_path}/migration.log")).to include(query)
end
it 'does not change the default logger' do
diff --git a/spec/lib/gitlab/database/migrations/observers/transaction_duration_spec.rb b/spec/lib/gitlab/database/migrations/observers/transaction_duration_spec.rb
index f433e25b2ba..51b19e7f2da 100644
--- a/spec/lib/gitlab/database/migrations/observers/transaction_duration_spec.rb
+++ b/spec/lib/gitlab/database/migrations/observers/transaction_duration_spec.rb
@@ -7,7 +7,7 @@ RSpec.describe Gitlab::Database::Migrations::Observers::TransactionDuration do
let(:connection) { ActiveRecord::Migration.connection }
let(:observation) { Gitlab::Database::Migrations::Observation.new(version: migration_version, name: migration_name) }
let(:directory_path) { Dir.mktmpdir }
- let(:log_file) { "#{directory_path}/#{migration_version}_#{migration_name}-transaction-duration.json" }
+ let(:log_file) { "#{directory_path}/transaction-duration.json" }
let(:transaction_duration) { Gitlab::Json.parse(File.read(log_file)) }
let(:migration_version) { 20210422152437 }
let(:migration_name) { 'test' }
diff --git a/spec/lib/gitlab/database/migrations/runner_spec.rb b/spec/lib/gitlab/database/migrations/runner_spec.rb
index 7dc965c84fa..84482e6b450 100644
--- a/spec/lib/gitlab/database/migrations/runner_spec.rb
+++ b/spec/lib/gitlab/database/migrations/runner_spec.rb
@@ -79,6 +79,15 @@ RSpec.describe Gitlab::Database::Migrations::Runner do
expect(migration_runs.map(&:dir)).to match_array([:up, :up])
expect(migration_runs.map(&:version_to_migrate)).to eq(pending_migrations.map(&:version))
end
+
+ it 'writes a metadata file with the current schema version' do
+ up.run
+
+ metadata_file = result_dir.join('up', described_class::METADATA_FILENAME)
+ expect(metadata_file.exist?).to be_truthy
+ metadata = Gitlab::Json.parse(File.read(metadata_file))
+ expect(metadata).to match('version' => described_class::SCHEMA_VERSION)
+ end
end
end
@@ -105,5 +114,14 @@ RSpec.describe Gitlab::Database::Migrations::Runner do
expect(migration_runs.map(&:version_to_migrate)).to eq(applied_migrations_this_branch.reverse.map(&:version))
end
end
+
+ it 'writes a metadata file with the current schema version' do
+ down.run
+
+ metadata_file = result_dir.join('down', described_class::METADATA_FILENAME)
+ expect(metadata_file.exist?).to be_truthy
+ metadata = Gitlab::Json.parse(File.read(metadata_file))
+ expect(metadata).to match('version' => described_class::SCHEMA_VERSION)
+ end
end
end
diff --git a/spec/lib/gitlab/database/migrations/test_background_runner_spec.rb b/spec/lib/gitlab/database/migrations/test_background_runner_spec.rb
new file mode 100644
index 00000000000..c6fe88a7c2d
--- /dev/null
+++ b/spec/lib/gitlab/database/migrations/test_background_runner_spec.rb
@@ -0,0 +1,120 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Database::Migrations::TestBackgroundRunner, :redis do
+ include Gitlab::Database::Migrations::BackgroundMigrationHelpers
+
+ # In order to test the interaction between queueing sidekiq jobs and seeing those jobs in queues,
+ # we need to disable sidekiq's testing mode and actually send our jobs to redis
+ around do |ex|
+ Sidekiq::Testing.disable! { ex.run }
+ end
+
+ context 'without jobs to run' do
+ it 'returns immediately' do
+ runner = described_class.new
+ expect(runner).not_to receive(:run_job)
+ described_class.new.run_jobs(for_duration: 1.second)
+ end
+ end
+
+ context 'with jobs to run' do
+ let(:migration_name) { 'TestBackgroundMigration' }
+
+ before do
+ (1..5).each do |i|
+ migrate_in(i.minutes, migration_name, [i])
+ end
+ end
+
+ context 'finding pending background jobs' do
+ it 'finds all the migrations' do
+ expect(described_class.new.traditional_background_migrations.to_a.size).to eq(5)
+ end
+ end
+
+ context 'running migrations', :freeze_time do
+ def define_background_migration(name)
+ klass = Class.new do
+ # Can't simply def perform here as we won't have access to the block,
+ # similarly can't define_method(:perform, &block) here as it would change the block receiver
+ define_method(:perform) { |*args| yield(*args) }
+ end
+ stub_const("Gitlab::BackgroundMigration::#{name}", klass)
+ klass
+ end
+
+ def expect_migration_call_counts(migrations_to_calls)
+ migrations_to_calls.each do |migration, calls|
+ expect_next_instances_of(migration, calls) do |m|
+ expect(m).to receive(:perform).and_call_original
+ end
+ end
+ end
+
+ it 'runs the migration class correctly' do
+ calls = []
+ define_background_migration(migration_name) do |i|
+ calls << i
+ end
+ described_class.new.run_jobs(for_duration: 1.second) # Any time would work here as we do not advance time
+ expect(calls).to contain_exactly(1, 2, 3, 4, 5)
+ end
+
+ it 'runs the migration for a uniform amount of time' do
+ migration = define_background_migration(migration_name) do |i|
+ travel(1.minute)
+ end
+
+ expect_migration_call_counts(migration => 3)
+
+ described_class.new.run_jobs(for_duration: 3.minutes)
+ end
+
+ context 'with multiple migrations to run' do
+ let(:other_migration_name) { 'OtherBackgroundMigration' }
+
+ before do
+ (1..5).each do |i|
+ migrate_in(i.minutes, other_migration_name, [i])
+ end
+ end
+
+ it 'splits the time between migrations when all migrations use all their time' do
+ migration = define_background_migration(migration_name) do |i|
+ travel(1.minute)
+ end
+
+ other_migration = define_background_migration(other_migration_name) do |i|
+ travel(2.minutes)
+ end
+
+ expect_migration_call_counts(
+ migration => 2, # 1 minute jobs for 90 seconds, can finish the first and start the second
+ other_migration => 1 # 2 minute jobs for 90 seconds, past deadline after a single job
+ )
+
+ described_class.new.run_jobs(for_duration: 3.minutes)
+ end
+
+ it 'does not give leftover time to extra migrations' do
+ # This is currently implemented this way for simplicity, but it could make sense to change this behavior.
+
+ migration = define_background_migration(migration_name) do
+ travel(1.second)
+ end
+ other_migration = define_background_migration(other_migration_name) do
+ travel(1.minute)
+ end
+ expect_migration_call_counts(
+ migration => 5,
+ other_migration => 2
+ )
+
+ described_class.new.run_jobs(for_duration: 3.minutes)
+ end
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/database/partitioning_spec.rb b/spec/lib/gitlab/database/partitioning_spec.rb
index 154cc2b7972..7c69f639aab 100644
--- a/spec/lib/gitlab/database/partitioning_spec.rb
+++ b/spec/lib/gitlab/database/partitioning_spec.rb
@@ -109,6 +109,20 @@ RSpec.describe Gitlab::Database::Partitioning do
.and change { find_partitions(table_names.last).size }.from(0)
end
end
+
+ context 'when only a specific database is requested' do
+ before do
+ allow(models.first).to receive_message_chain('connection_db_config.name').and_return('main')
+ allow(models.last).to receive_message_chain('connection_db_config.name').and_return('ci')
+ end
+
+ it 'manages partitions for models for the given database', :aggregate_failures do
+ expect { described_class.sync_partitions(models, only_on: 'ci') }
+ .to change { find_partitions(table_names.last).size }.from(0)
+
+ expect(find_partitions(table_names.first).size).to eq(0)
+ end
+ end
end
describe '.report_metrics' do
diff --git a/spec/lib/gitlab/database/query_analyzer_spec.rb b/spec/lib/gitlab/database/query_analyzer_spec.rb
index 34c72893c53..3b4cbc79de2 100644
--- a/spec/lib/gitlab/database/query_analyzer_spec.rb
+++ b/spec/lib/gitlab/database/query_analyzer_spec.rb
@@ -4,6 +4,7 @@ require 'spec_helper'
RSpec.describe Gitlab::Database::QueryAnalyzer, query_analyzers: false do
let(:analyzer) { double(:query_analyzer) }
+ let(:user_analyzer) { double(:query_analyzer) }
let(:disabled_analyzer) { double(:disabled_query_analyzer) }
before do
@@ -53,6 +54,10 @@ RSpec.describe Gitlab::Database::QueryAnalyzer, query_analyzers: false do
expect { |b| described_class.instance.within(&b) }.to yield_control
end
+
+ it 'raises exception when trying to re-define analyzers' do
+ expect { |b| described_class.instance.within([user_analyzer], &b) }.to raise_error /Query analyzers are already defined, cannot re-define them/
+ end
end
context 'when initializer is enabled' do
@@ -75,6 +80,18 @@ RSpec.describe Gitlab::Database::QueryAnalyzer, query_analyzers: false do
expect { |b| described_class.instance.within(&b) }.to yield_control
end
end
+
+ context 'when user analyzers are used' do
+ it 'calls begin! and end!' do
+ expect(analyzer).not_to receive(:begin!)
+ allow(user_analyzer).to receive(:enabled?).and_return(true)
+ allow(user_analyzer).to receive(:suppressed?).and_return(false)
+ expect(user_analyzer).to receive(:begin!)
+ expect(user_analyzer).to receive(:end!)
+
+ expect { |b| described_class.instance.within([user_analyzer], &b) }.to yield_control
+ end
+ end
end
describe '#process_sql' do
diff --git a/spec/lib/gitlab/database/query_analyzers/restrict_allowed_schemas_spec.rb b/spec/lib/gitlab/database/query_analyzers/restrict_allowed_schemas_spec.rb
new file mode 100644
index 00000000000..a2c7916fa01
--- /dev/null
+++ b/spec/lib/gitlab/database/query_analyzers/restrict_allowed_schemas_spec.rb
@@ -0,0 +1,161 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Database::QueryAnalyzers::RestrictAllowedSchemas, query_analyzers: false do
+ let(:analyzer) { described_class }
+
+ context 'properly analyzes queries' do
+ using RSpec::Parameterized::TableSyntax
+
+ where do
+ examples = {
+ "for SELECT on projects" => {
+ sql: "SELECT 1 FROM projects",
+ expected_allowed_gitlab_schemas: {
+ no_schema: :dml_not_allowed,
+ gitlab_main: :success,
+ gitlab_ci: :dml_access_denied # cross-schema access
+ }
+ },
+ "for INSERT" => {
+ sql: "INSERT INTO projects VALUES (1)",
+ expected_allowed_gitlab_schemas: {
+ no_schema: :dml_not_allowed,
+ gitlab_main: :success,
+ gitlab_ci: :dml_access_denied # cross-schema access
+ }
+ },
+ "for CREATE INDEX" => {
+ sql: "CREATE INDEX index_projects_on_hidden ON projects (hidden)",
+ expected_allowed_gitlab_schemas: {
+ no_schema: :success,
+ gitlab_main: :ddl_not_allowed,
+ gitlab_ci: :ddl_not_allowed
+ }
+ },
+ "for CREATE SCHEMA" => {
+ sql: "CREATE SCHEMA __test_schema",
+ expected_allowed_gitlab_schemas: {
+ no_schema: :success,
+ # TODO: This is currently not properly detected
+ gitlab_main: :success,
+ gitlab_ci: :success
+ }
+ },
+ "for CREATE FUNCTION" => {
+ sql: "CREATE FUNCTION add(integer, integer) RETURNS integer AS 'select $1 + $2;' LANGUAGE SQL",
+ expected_allowed_gitlab_schemas: {
+ no_schema: :success,
+ gitlab_main: :ddl_not_allowed,
+ gitlab_ci: :ddl_not_allowed
+ }
+ },
+ "for CREATE TRIGGER" => {
+ sql: "CREATE TRIGGER check_projects BEFORE UPDATE ON projects FOR EACH ROW EXECUTE PROCEDURE check_projects_update()",
+ expected_allowed_gitlab_schemas: {
+ no_schema: :success,
+ gitlab_main: :ddl_not_allowed,
+ gitlab_ci: :ddl_not_allowed
+ }
+ }
+ }
+
+ # Expands all examples into individual tests
+ examples.flat_map do |name, configuration|
+ configuration[:expected_allowed_gitlab_schemas].map do |allowed_gitlab_schema, expectation|
+ [
+ "#{name} for allowed_gitlab_schema=#{allowed_gitlab_schema}",
+ {
+ sql: configuration[:sql],
+ allowed_gitlab_schema: allowed_gitlab_schema, # nil, gitlab_main
+ expectation: expectation # success, dml_access_denied, ...
+ }
+ ]
+ end
+ end.to_h
+ end
+
+ with_them do
+ subject do
+ process_sql(sql) do
+ analyzer.allowed_gitlab_schemas = [allowed_gitlab_schema] unless allowed_gitlab_schema == :no_schema
+ end
+ end
+
+ it do
+ case expectation
+ when :success
+ expect { subject }.not_to raise_error
+ when :ddl_not_allowed
+ expect { subject }.to raise_error(described_class::DDLNotAllowedError)
+ when :dml_not_allowed
+ expect { subject }.to raise_error(described_class::DMLNotAllowedError)
+ when :dml_access_denied
+ expect { subject }.to raise_error(described_class::DMLAccessDeniedError)
+ else
+ raise "invalid expectation: #{expectation}"
+ end
+ end
+ end
+ end
+
+ describe '.require_ddl_mode!' do
+ subject { described_class.require_ddl_mode! }
+
+ it "when not configured does not raise exception" do
+ expect { subject }.not_to raise_error
+ end
+
+ it "when no schemas are configured does not raise exception (DDL mode)" do
+ with_analyzer do
+ expect { subject }.not_to raise_error
+ end
+ end
+
+ it "with schemas configured does raise exception (DML mode)" do
+ with_analyzer do
+ analyzer.allowed_gitlab_schemas = %i[gitlab_main]
+
+ expect { subject }.to raise_error(described_class::DMLNotAllowedError)
+ end
+ end
+ end
+
+ describe '.require_dml_mode!' do
+ subject { described_class.require_dml_mode! }
+
+ it "when not configured does not raise exception" do
+ expect { subject }.not_to raise_error
+ end
+
+ it "when no schemas are configured does raise exception (DDL mode)" do
+ with_analyzer do
+ expect { subject }.to raise_error(described_class::DDLNotAllowedError)
+ end
+ end
+
+ it "with schemas configured does raise exception (DML mode)" do
+ with_analyzer do
+ analyzer.allowed_gitlab_schemas = %i[gitlab_main]
+
+ expect { subject }.not_to raise_error
+ end
+ end
+ end
+
+ def with_analyzer
+ Gitlab::Database::QueryAnalyzer.instance.within([analyzer]) do
+ yield
+ end
+ end
+
+ def process_sql(sql, model = ActiveRecord::Base)
+ with_analyzer do
+ yield if block_given?
+
+ # Skip load balancer and retrieve connection assigned to model
+ Gitlab::Database::QueryAnalyzer.instance.process_sql(sql, model.retrieve_connection)
+ end
+ end
+end
diff --git a/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_projects_spec.rb b/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_projects_spec.rb
index 3799fe3c316..50071e3e22b 100644
--- a/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_projects_spec.rb
+++ b/spec/lib/gitlab/database/rename_reserved_paths_migration/v1/rename_projects_spec.rb
@@ -49,7 +49,7 @@ RSpec.describe Gitlab::Database::RenameReservedPathsMigration::V1::RenameProject
it 'invalidates the markdown cache of related projects' do
expect(subject).to receive(:remove_cached_html_for_projects)
- .with(projects.map(&:id))
+ .with(a_collection_containing_exactly(*projects.map(&:id)))
subject.rename_projects
end
diff --git a/spec/lib/gitlab/database/transaction/context_spec.rb b/spec/lib/gitlab/database/transaction/context_spec.rb
index 37cfc841d48..33a47150060 100644
--- a/spec/lib/gitlab/database/transaction/context_spec.rb
+++ b/spec/lib/gitlab/database/transaction/context_spec.rb
@@ -135,4 +135,24 @@ RSpec.describe Gitlab::Database::Transaction::Context do
it_behaves_like 'logs transaction data'
end
+
+ context 'when there are too many external HTTP requests' do
+ before do
+ allow(::Gitlab::Metrics::Subscribers::ExternalHttp)
+ .to receive(:request_count)
+ .and_return(100)
+ end
+
+ it_behaves_like 'logs transaction data'
+ end
+
+ context 'when there are too many too long external HTTP requests' do
+ before do
+ allow(::Gitlab::Metrics::Subscribers::ExternalHttp)
+ .to receive(:duration)
+ .and_return(5.5)
+ end
+
+ it_behaves_like 'logs transaction data'
+ end
end
diff --git a/spec/lib/gitlab/database/transaction/observer_spec.rb b/spec/lib/gitlab/database/transaction/observer_spec.rb
index e5cc0106c9b..074c18d406e 100644
--- a/spec/lib/gitlab/database/transaction/observer_spec.rb
+++ b/spec/lib/gitlab/database/transaction/observer_spec.rb
@@ -25,7 +25,7 @@ RSpec.describe Gitlab::Database::Transaction::Observer do
User.first
expect(transaction_context).to be_a(::Gitlab::Database::Transaction::Context)
- expect(context.keys).to match_array(%i(start_time depth savepoints queries backtraces))
+ expect(context.keys).to match_array(%i(start_time depth savepoints queries backtraces external_http_count_start external_http_duration_start))
expect(context[:depth]).to eq(2)
expect(context[:savepoints]).to eq(1)
expect(context[:queries].length).to eq(1)
@@ -38,6 +38,71 @@ RSpec.describe Gitlab::Database::Transaction::Observer do
expect(context[:backtraces].length).to eq(1)
end
+ describe 'tracking external network requests', :request_store do
+ it 'tracks external requests' do
+ perform_stubbed_external_http_request(duration: 0.25)
+ perform_stubbed_external_http_request(duration: 1.25)
+
+ ActiveRecord::Base.transaction do
+ User.first
+
+ expect(context[:external_http_count_start]).to eq(2)
+ expect(context[:external_http_duration_start]).to eq(1.5)
+
+ perform_stubbed_external_http_request(duration: 1)
+ perform_stubbed_external_http_request(duration: 3)
+
+ expect(transaction_context.external_http_requests_count).to eq 2
+ expect(transaction_context.external_http_requests_duration).to eq 4
+ end
+ end
+
+ context 'when external HTTP requests duration has been exceeded' do
+ it 'logs transaction details including exceeding thresholds' do
+ expect(Gitlab::AppJsonLogger).to receive(:info).with(
+ hash_including(
+ external_http_requests_count: 2,
+ external_http_requests_duration: 12
+ )
+ )
+
+ ActiveRecord::Base.transaction do
+ User.first
+
+ perform_stubbed_external_http_request(duration: 2)
+ perform_stubbed_external_http_request(duration: 10)
+ end
+ end
+ end
+
+ context 'when external HTTP requests count has been exceeded' do
+ it 'logs transaction details including exceeding thresholds' do
+ expect(Gitlab::AppJsonLogger).to receive(:info).with(
+ hash_including(external_http_requests_count: 55)
+ )
+
+ ActiveRecord::Base.transaction do
+ User.first
+
+ 55.times { perform_stubbed_external_http_request(duration: 0.01) }
+ end
+ end
+ end
+
+ def perform_stubbed_external_http_request(duration:)
+ ::Gitlab::Metrics::Subscribers::ExternalHttp.new.request(
+ instance_double(
+ 'ActiveSupport::Notifications::Event',
+ payload: {
+ method: 'GET', code: '200', duration: duration,
+ scheme: 'http', host: 'example.gitlab.com', port: 80, path: '/'
+ },
+ time: Time.current
+ )
+ )
+ end
+ end
+
describe '.extract_sql_command' do
using RSpec::Parameterized::TableSyntax
diff --git a/spec/lib/gitlab/database/type/color_spec.rb b/spec/lib/gitlab/database/type/color_spec.rb
new file mode 100644
index 00000000000..84fd8d0bbce
--- /dev/null
+++ b/spec/lib/gitlab/database/type/color_spec.rb
@@ -0,0 +1,41 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe ::Gitlab::Database::Type::Color do
+ subject(:type) { described_class.new }
+
+ let(:color) { ::Gitlab::Color.of('red') }
+
+ it 'serializes by calling #to_s' do
+ expect(type.serialize(color)).to eq(color.to_s)
+ end
+
+ it 'serializes nil to nil' do
+ expect(type.serialize(nil)).to be_nil
+ end
+
+ it 'casts by calling Color::new' do
+ expect(type.cast('#fff')).to eq(::Gitlab::Color.new('#fff'))
+ end
+
+ it 'accepts colors as arguments to cast' do
+ expect(type.cast(color)).to eq(color)
+ end
+
+ it 'allows nil database values' do
+ expect(type.cast(nil)).to be_nil
+ end
+
+ it 'tells us what is serializable' do
+ [nil, 'foo', color].each do |value|
+ expect(type.serializable?(value)).to be true
+ end
+ end
+
+ it 'tells us what is not serializable' do
+ [0, 3.2, true, Time.current, { some: 'hash' }].each do |value|
+ expect(type.serializable?(value)).to be false
+ end
+ end
+end
diff --git a/spec/lib/gitlab/database_spec.rb b/spec/lib/gitlab/database_spec.rb
index b3b7c81e9e7..c58dba213ee 100644
--- a/spec/lib/gitlab/database_spec.rb
+++ b/spec/lib/gitlab/database_spec.rb
@@ -205,12 +205,12 @@ RSpec.describe Gitlab::Database do
end
context 'when the connection is LoadBalancing::ConnectionProxy' do
- it 'returns nil' do
+ it 'returns primary_db_config' do
lb_config = ::Gitlab::Database::LoadBalancing::Configuration.new(ActiveRecord::Base)
lb = ::Gitlab::Database::LoadBalancing::LoadBalancer.new(lb_config)
proxy = ::Gitlab::Database::LoadBalancing::ConnectionProxy.new(lb)
- expect(described_class.db_config_for_connection(proxy)).to be_nil
+ expect(described_class.db_config_for_connection(proxy)).to eq(lb_config.primary_db_config)
end
end
@@ -229,7 +229,7 @@ RSpec.describe Gitlab::Database do
# This is a ConnectionProxy
expect(described_class.db_config_name(model.connection))
- .to eq('unknown')
+ .to eq('main')
# This is an actual connection
expect(described_class.db_config_name(model.retrieve_connection))
@@ -245,6 +245,31 @@ RSpec.describe Gitlab::Database do
end
end
+ describe '.gitlab_schemas_for_connection' do
+ it 'does raise exception for invalid connection' do
+ expect { described_class.gitlab_schemas_for_connection(:invalid) }.to raise_error /key not found: "unknown"/
+ end
+
+ it 'does return a valid schema depending on a base model used', :request_store do
+ # This is currently required as otherwise the `Ci::Build.connection` == `Project.connection`
+ # ENV due to lib/gitlab/database/load_balancing/setup.rb:93
+ stub_env('GITLAB_USE_MODEL_LOAD_BALANCING', '1')
+ # FF due to lib/gitlab/database/load_balancing/configuration.rb:92
+ stub_feature_flags(force_no_sharing_primary_model: true)
+
+ expect(described_class.gitlab_schemas_for_connection(Project.connection)).to include(:gitlab_main, :gitlab_shared)
+ expect(described_class.gitlab_schemas_for_connection(Ci::Build.connection)).to include(:gitlab_ci, :gitlab_shared)
+ end
+
+ it 'does return gitlab_ci when a ActiveRecord::Base is using CI connection' do
+ with_reestablished_active_record_base do
+ reconfigure_db_connection(model: ActiveRecord::Base, config_model: Ci::Build)
+
+ expect(described_class.gitlab_schemas_for_connection(ActiveRecord::Base.connection)).to include(:gitlab_ci, :gitlab_shared)
+ end
+ end
+ end
+
describe '#true_value' do
it 'returns correct value' do
expect(described_class.true_value).to eq "'t'"
@@ -279,6 +304,46 @@ RSpec.describe Gitlab::Database do
end
end
+ describe '.all_uncached' do
+ let(:base_model) do
+ Class.new do
+ def self.uncached
+ @uncached = true
+
+ yield
+ end
+ end
+ end
+
+ let(:model1) { Class.new(base_model) }
+ let(:model2) { Class.new(base_model) }
+
+ before do
+ allow(described_class).to receive(:database_base_models)
+ .and_return({ model1: model1, model2: model2 }.with_indifferent_access)
+ end
+
+ it 'wraps the given block in uncached calls for each primary connection', :aggregate_failures do
+ expect(model1.instance_variable_get(:@uncached)).to be_nil
+ expect(model2.instance_variable_get(:@uncached)).to be_nil
+
+ expect(Gitlab::Database::LoadBalancing::Session.current).to receive(:use_primary).and_yield
+
+ expect(model2).to receive(:uncached).and_call_original
+ expect(model1).to receive(:uncached).and_call_original
+
+ yielded_to_block = false
+ described_class.all_uncached do
+ expect(model1.instance_variable_get(:@uncached)).to be(true)
+ expect(model2.instance_variable_get(:@uncached)).to be(true)
+
+ yielded_to_block = true
+ end
+
+ expect(yielded_to_block).to be(true)
+ end
+ end
+
describe '.read_only?' do
it 'returns false' do
expect(described_class.read_only?).to eq(false)
diff --git a/spec/lib/gitlab/diff/file_spec.rb b/spec/lib/gitlab/diff/file_spec.rb
index 7c1a8f4c3c8..f2212ec9b09 100644
--- a/spec/lib/gitlab/diff/file_spec.rb
+++ b/spec/lib/gitlab/diff/file_spec.rb
@@ -51,45 +51,29 @@ RSpec.describe Gitlab::Diff::File do
project.commit(branch_name).diffs.diff_files.first
end
- describe 'initialize' do
- context 'when file is ipynb with a change after transformation' do
+ describe '#has_renderable?' do
+ context 'file is ipynb' do
let(:commit) { project.commit("532c837") }
- let(:diff) { commit.raw_diffs.first }
- let(:diff_file) { described_class.new(diff, diff_refs: commit.diff_refs, repository: project.repository) }
- context 'and :jupyter_clean_diffs is enabled' do
- before do
- stub_feature_flags(jupyter_clean_diffs: true)
- end
-
- it 'recreates the diff by transforming the files' do
- expect(diff_file.diff.diff).not_to include('cell_type')
- end
+ it 'has renderable viewer' do
+ expect(diff_file.has_renderable?).to be_truthy
end
+ end
- context 'but :jupyter_clean_diffs is disabled' do
- before do
- stub_feature_flags(jupyter_clean_diffs: false)
- end
+ context 'file is not ipynb' do
+ let(:commit) { project.commit("d59c60028b053793cecfb4022de34602e1a9218e") }
- it 'does not recreate the diff' do
- expect(diff_file.diff.diff).to include('cell_type')
- end
+ it 'does not have renderable viewer' do
+ expect(diff_file.has_renderable?).to be_falsey
end
end
+ end
- context 'when file is ipynb, but there only changes that are removed' do
- let(:commit) { project.commit("2b5ef814") }
- let(:diff) { commit.raw_diffs.first }
- let(:diff_file) { described_class.new(diff, diff_refs: commit.diff_refs, repository: project.repository) }
-
- before do
- stub_feature_flags(jupyter_clean_diffs: true)
- end
+ describe '#rendered' do
+ let(:commit) { project.commit("532c837") }
- it 'does not recreate the diff' do
- expect(diff_file.diff.diff).to include('execution_count')
- end
+ it 'creates a NotebookDiffFile for rendering' do
+ expect(diff_file.rendered).to be_kind_of(Gitlab::Diff::Rendered::Notebook::DiffFile)
end
end
diff --git a/spec/lib/gitlab/diff/rendered/notebook/diff_file_spec.rb b/spec/lib/gitlab/diff/rendered/notebook/diff_file_spec.rb
new file mode 100644
index 00000000000..15edbc22460
--- /dev/null
+++ b/spec/lib/gitlab/diff/rendered/notebook/diff_file_spec.rb
@@ -0,0 +1,107 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Diff::Rendered::Notebook::DiffFile do
+ include RepoHelpers
+
+ let(:project) { create(:project, :repository) }
+ let(:commit) { project.commit("5d6ed1503801ca9dc28e95eeb85a7cf863527aee") }
+ let(:diffs) { commit.raw_diffs.to_a }
+ let(:diff) { diffs.first }
+ let(:source) { Gitlab::Diff::File.new(diff, diff_refs: commit.diff_refs, repository: project.repository) }
+ let(:nb_file) { described_class.new(source) }
+
+ describe '#old_blob and #new_blob' do
+ context 'when file is changed' do
+ it 'transforms the old blob' do
+ expect(nb_file.old_blob.data).to include('%%')
+ end
+
+ it 'transforms the new blob' do
+ expect(nb_file.new_blob.data).to include('%%')
+ end
+ end
+
+ context 'when file is added' do
+ let(:diff) { diffs[1] }
+
+ it 'old_blob is empty' do
+ expect(nb_file.old_blob).to be_nil
+ end
+
+ it 'new_blob is transformed' do
+ expect(nb_file.new_blob.data).to include('%%')
+ end
+ end
+
+ context 'when file is removed' do
+ let(:diff) { diffs[2] }
+
+ it 'old_blob is transformed' do
+ expect(nb_file.old_blob.data).to include('%%')
+ end
+
+ it 'new_blob is empty' do
+ expect(nb_file.new_blob).to be_nil
+ end
+ end
+ end
+
+ describe '#diff' do
+ context 'for valid notebooks' do
+ it 'returns the transformed diff' do
+ expect(nb_file.diff.diff).to include('%%')
+ end
+ end
+
+ context 'for invalid notebooks' do
+ let(:commit) { project.commit("6d85bb693dddaee631ec0c2f697c52c62b93f6d3") }
+ let(:diff) { diffs[1] }
+
+ it 'returns nil' do
+ expect(nb_file.diff).to be_nil
+ end
+ end
+ end
+
+ describe '#has_renderable?' do
+ context 'notebook diff is empty' do
+ let(:commit) { project.commit("a867a602d2220e5891b310c07d174fbe12122830") }
+
+ it 'is false' do
+ expect(nb_file.has_renderable?).to be_falsey
+ end
+ end
+
+ context 'notebook is valid' do
+ it 'is true' do
+ expect(nb_file.has_renderable?).to be_truthy
+ end
+ end
+ end
+
+ describe '#highlighted_diff_lines?' do
+ context 'when line transformed line is not part of the diff' do
+ it 'line is not discussable' do
+ expect(nb_file.highlighted_diff_lines[0].discussable?).to be_falsey
+ end
+ end
+
+ context 'when line transformed line part of the diff' do
+ it 'line is not discussable' do
+ expect(nb_file.highlighted_diff_lines[12].discussable?).to be_truthy
+ end
+ end
+
+ context 'assigns the correct position' do
+ it 'computes de first line where the remove would appear' do
+ expect(nb_file.highlighted_diff_lines[0].old_pos).to eq(3)
+ expect(nb_file.highlighted_diff_lines[0].new_pos).to eq(3)
+
+ expect(nb_file.highlighted_diff_lines[12].new_pos).to eq(15)
+ expect(nb_file.highlighted_diff_lines[12].old_pos).to eq(18)
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/email/attachment_uploader_spec.rb b/spec/lib/gitlab/email/attachment_uploader_spec.rb
index 4b4e671f001..40b94df6ee3 100644
--- a/spec/lib/gitlab/email/attachment_uploader_spec.rb
+++ b/spec/lib/gitlab/email/attachment_uploader_spec.rb
@@ -8,7 +8,27 @@ RSpec.describe Gitlab::Email::AttachmentUploader do
let(:message_raw) { fixture_file("emails/attachment.eml") }
let(:message) { Mail::Message.new(message_raw) }
+ before do
+ allow_next_instance_of(Gitlab::Sanitizers::Exif) do |instance|
+ allow(instance).to receive(:clean_existing_path).and_call_original
+ end
+ end
+
+ def expect_exif_sanitizer_called
+ expect_next_instance_of(Gitlab::Sanitizers::Exif) do |sanitizer|
+ expect(sanitizer).to receive(:clean_existing_path) do |path, **options|
+ expect(File.exist?(path)).to be true
+
+ file = File.open(path, "rb")
+ expect(options).to eql(content: file.read, skip_unallowed_types: true)
+ file.close
+ end
+ end
+ end
+
it "uploads all attachments and returns their links" do
+ expect_exif_sanitizer_called
+
links = described_class.new(message).execute(upload_parent: project, uploader_class: FileUploader)
link = links.first
@@ -21,6 +41,8 @@ RSpec.describe Gitlab::Email::AttachmentUploader do
let(:message_raw) { fixture_file("emails/valid_reply_signed_smime.eml") }
it 'uploads all attachments except the signature' do
+ expect_exif_sanitizer_called
+
links = described_class.new(message).execute(upload_parent: project, uploader_class: FileUploader)
expect(links).not_to include(a_hash_including(alt: 'smime.p7s'))
@@ -36,6 +58,8 @@ RSpec.describe Gitlab::Email::AttachmentUploader do
let(:message_raw) { fixture_file("emails/valid_reply_signed_smime_mixed_protocol_prefix.eml") }
it 'uploads all attachments except the signature' do
+ expect_exif_sanitizer_called
+
links = described_class.new(message).execute(upload_parent: project, uploader_class: FileUploader)
expect(links).not_to include(a_hash_including(alt: 'smime.p7s'))
diff --git a/spec/lib/gitlab/email/handler/create_issue_handler_spec.rb b/spec/lib/gitlab/email/handler/create_issue_handler_spec.rb
index 10098a66ae9..75538baf07f 100644
--- a/spec/lib/gitlab/email/handler/create_issue_handler_spec.rb
+++ b/spec/lib/gitlab/email/handler/create_issue_handler_spec.rb
@@ -148,34 +148,11 @@ RSpec.describe Gitlab::Email::Handler::CreateIssueHandler do
end
end
- context 'rate limiting' do
- let(:rate_limited_service_feature_enabled) { nil }
+ it 'raises a RateLimitedService::RateLimitedError' do
+ allow(::Gitlab::ApplicationRateLimiter).to receive(:throttled?).and_return(true)
- before do
- stub_feature_flags(rate_limited_service_issues_create: rate_limited_service_feature_enabled)
- end
-
- context 'when :rate_limited_service Feature is disabled' do
- let(:rate_limited_service_feature_enabled) { false }
-
- it 'does not attempt to throttle' do
- expect(::Gitlab::ApplicationRateLimiter).not_to receive(:throttled?)
-
- setup_attachment
- receiver.execute
- end
- end
-
- context 'when :rate_limited_service Feature is enabled' do
- let(:rate_limited_service_feature_enabled) { true }
-
- it 'raises a RateLimitedService::RateLimitedError' do
- allow(::Gitlab::ApplicationRateLimiter).to receive(:throttled?).and_return(true)
-
- setup_attachment
- expect { receiver.execute }.to raise_error(RateLimitedService::RateLimitedError, _('This endpoint has been requested too many times. Try again later.'))
- end
- end
+ setup_attachment
+ expect { receiver.execute }.to raise_error(RateLimitedService::RateLimitedError, _('This endpoint has been requested too many times. Try again later.'))
end
end
diff --git a/spec/lib/gitlab/email/handler/service_desk_handler_spec.rb b/spec/lib/gitlab/email/handler/service_desk_handler_spec.rb
index 7c34fb1a926..913e197708f 100644
--- a/spec/lib/gitlab/email/handler/service_desk_handler_spec.rb
+++ b/spec/lib/gitlab/email/handler/service_desk_handler_spec.rb
@@ -382,7 +382,6 @@ RSpec.describe Gitlab::Email::Handler::ServiceDeskHandler do
subject { 2.times { receiver.execute } }
before do
- stub_feature_flags(rate_limited_service_issues_create: true)
stub_application_setting(issues_create_limit: 1)
end
@@ -478,6 +477,20 @@ RSpec.describe Gitlab::Email::Handler::ServiceDeskHandler do
end
end
+ context 'when there is a reply-to address and a from address' do
+ let(:email_raw) { email_fixture('emails/service_desk_reply_to_and_from.eml') }
+
+ it 'shows both from and reply-to addresses in the issue header' do
+ setup_attachment
+
+ expect { receiver.execute }.to change { Issue.count }.by(1)
+
+ new_issue = Issue.last
+
+ expect(new_issue.external_author).to eq('finn@adventuretime.ooo (reply to: marceline@adventuretime.ooo)')
+ end
+ end
+
context 'when service desk is not enabled for project' do
before do
allow(Gitlab::ServiceDesk).to receive(:enabled?).and_return(false)
diff --git a/spec/lib/gitlab/email/receiver_spec.rb b/spec/lib/gitlab/email/receiver_spec.rb
index b1a04f0592a..9040731d8fd 100644
--- a/spec/lib/gitlab/email/receiver_spec.rb
+++ b/spec/lib/gitlab/email/receiver_spec.rb
@@ -32,12 +32,21 @@ RSpec.describe Gitlab::Email::Receiver do
metadata = receiver.mail_metadata
- expect(metadata.keys).to match_array(%i(mail_uid from_address to_address mail_key references delivered_to envelope_to x_envelope_to meta))
+ expect(metadata.keys).to match_array(%i(mail_uid from_address to_address mail_key references delivered_to envelope_to x_envelope_to meta received_recipients))
expect(metadata[:meta]).to include(client_id: 'email/jake@example.com', project: project.full_path)
expect(metadata[meta_key]).to eq(meta_value)
end
end
+ shared_examples 'failed receive' do
+ it 'adds metric event' do
+ expect(::Gitlab::Metrics::BackgroundTransaction).to receive(:current).and_return(metric_transaction)
+ expect(metric_transaction).to receive(:add_event).with('email_receiver_error', { error: expected_error.name })
+
+ expect { receiver.execute }.to raise_error(expected_error)
+ end
+ end
+
context 'when the email contains a valid email address in a header' do
before do
stub_incoming_email_setting(enabled: true, address: "incoming+%{key}@appmail.example.com")
@@ -74,14 +83,25 @@ RSpec.describe Gitlab::Email::Receiver do
it_behaves_like 'successful receive'
end
- end
- shared_examples 'failed receive' do
- it 'adds metric event' do
- expect(::Gitlab::Metrics::BackgroundTransaction).to receive(:current).and_return(metric_transaction)
- expect(metric_transaction).to receive(:add_event).with('email_receiver_error', { error: expected_error.name })
+ context 'when all other headers are missing' do
+ let(:email_raw) { fixture_file('emails/missing_delivered_to_header.eml') }
+ let(:meta_key) { :received_recipients }
+ let(:meta_value) { ['incoming+gitlabhq/gitlabhq+auth_token@appmail.example.com', 'incoming+gitlabhq/gitlabhq@example.com'] }
- expect { receiver.execute }.to raise_error(expected_error)
+ context 'when use_received_header_for_incoming_emails is enabled' do
+ it_behaves_like 'successful receive'
+ end
+
+ context 'when use_received_header_for_incoming_emails is disabled' do
+ let(:expected_error) { Gitlab::Email::UnknownIncomingEmail }
+
+ before do
+ stub_feature_flags(use_received_header_for_incoming_emails: false)
+ end
+
+ it_behaves_like 'failed receive'
+ end
end
end
diff --git a/spec/lib/gitlab/error_tracking/processor/grpc_error_processor_spec.rb b/spec/lib/gitlab/error_tracking/processor/grpc_error_processor_spec.rb
index 9acc7fd04be..33d322d0d44 100644
--- a/spec/lib/gitlab/error_tracking/processor/grpc_error_processor_spec.rb
+++ b/spec/lib/gitlab/error_tracking/processor/grpc_error_processor_spec.rb
@@ -2,9 +2,9 @@
require 'spec_helper'
-RSpec.describe Gitlab::ErrorTracking::Processor::GrpcErrorProcessor do
+RSpec.describe Gitlab::ErrorTracking::Processor::GrpcErrorProcessor, :sentry do
describe '.call' do
- let(:required_options) do
+ let(:raven_required_options) do
{
configuration: Raven.configuration,
context: Raven.context,
@@ -12,7 +12,15 @@ RSpec.describe Gitlab::ErrorTracking::Processor::GrpcErrorProcessor do
}
end
- let(:event) { Raven::Event.from_exception(exception, required_options.merge(data)) }
+ let(:raven_event) do
+ Raven::Event
+ .from_exception(exception, raven_required_options.merge(data))
+ end
+
+ let(:sentry_event) do
+ Sentry.get_current_client.event_from_exception(exception)
+ end
+
let(:result_hash) { described_class.call(event).to_hash }
let(:data) do
@@ -27,36 +35,43 @@ RSpec.describe Gitlab::ErrorTracking::Processor::GrpcErrorProcessor do
}
end
+ before do
+ Sentry.get_current_scope.update_from_options(**data)
+ Sentry.get_current_scope.apply_to_event(sentry_event)
+ end
+
+ after do
+ Sentry.get_current_scope.clear
+ end
+
context 'when there is no GRPC exception' do
let(:exception) { RuntimeError.new }
let(:data) { { fingerprint: ['ArgumentError', 'Missing arguments'] } }
- it 'leaves data unchanged' do
- expect(result_hash).to include(data)
+ shared_examples 'leaves data unchanged' do
+ it { expect(result_hash).to include(data) }
end
- end
- context 'when there is a GRPC exception with a debug string' do
- let(:exception) { GRPC::DeadlineExceeded.new('Deadline Exceeded', {}, '{"hello":1}') }
+ context 'with Raven event' do
+ let(:event) { raven_event }
- it 'removes the debug error string and stores it as an extra field' do
- expect(result_hash[:fingerprint])
- .to eq(['GRPC::DeadlineExceeded', '4:Deadline Exceeded.'])
+ it_behaves_like 'leaves data unchanged'
+ end
- expect(result_hash[:exception][:values].first)
- .to include(type: 'GRPC::DeadlineExceeded', value: '4:Deadline Exceeded.')
+ context 'with Sentry event' do
+ let(:event) { sentry_event }
- expect(result_hash[:extra])
- .to include(caller: 'test', grpc_debug_error_string: '{"hello":1}')
+ it_behaves_like 'leaves data unchanged'
end
+ end
- context 'with no custom fingerprint' do
- let(:data) do
- { extra: { caller: 'test' } }
- end
+ context 'when there is a GRPC exception with a debug string' do
+ let(:exception) { GRPC::DeadlineExceeded.new('Deadline Exceeded', {}, '{"hello":1}') }
+ shared_examples 'processes the exception' do
it 'removes the debug error string and stores it as an extra field' do
- expect(result_hash).not_to include(:fingerprint)
+ expect(result_hash[:fingerprint])
+ .to eq(['GRPC::DeadlineExceeded', '4:Deadline Exceeded.'])
expect(result_hash[:exception][:values].first)
.to include(type: 'GRPC::DeadlineExceeded', value: '4:Deadline Exceeded.')
@@ -64,11 +79,42 @@ RSpec.describe Gitlab::ErrorTracking::Processor::GrpcErrorProcessor do
expect(result_hash[:extra])
.to include(caller: 'test', grpc_debug_error_string: '{"hello":1}')
end
+
+ context 'with no custom fingerprint' do
+ let(:data) do
+ { extra: { caller: 'test' } }
+ end
+
+ it 'removes the debug error string and stores it as an extra field' do
+ expect(result_hash[:fingerprint]).to be_blank
+
+ expect(result_hash[:exception][:values].first)
+ .to include(type: 'GRPC::DeadlineExceeded', value: '4:Deadline Exceeded.')
+
+ expect(result_hash[:extra])
+ .to include(caller: 'test', grpc_debug_error_string: '{"hello":1}')
+ end
+ end
+ end
+
+ context 'with Raven event' do
+ let(:event) { raven_event }
+
+ it_behaves_like 'processes the exception'
+ end
+
+ context 'with Sentry event' do
+ let(:event) { sentry_event }
+
+ it_behaves_like 'processes the exception'
end
end
context 'when there is a wrapped GRPC exception with a debug string' do
- let(:inner_exception) { GRPC::DeadlineExceeded.new('Deadline Exceeded', {}, '{"hello":1}') }
+ let(:inner_exception) do
+ GRPC::DeadlineExceeded.new('Deadline Exceeded', {}, '{"hello":1}')
+ end
+
let(:exception) do
begin
raise inner_exception
@@ -79,27 +125,10 @@ RSpec.describe Gitlab::ErrorTracking::Processor::GrpcErrorProcessor do
e
end
- it 'removes the debug error string and stores it as an extra field' do
- expect(result_hash[:fingerprint])
- .to eq(['GRPC::DeadlineExceeded', '4:Deadline Exceeded.'])
-
- expect(result_hash[:exception][:values].first)
- .to include(type: 'GRPC::DeadlineExceeded', value: '4:Deadline Exceeded.')
-
- expect(result_hash[:exception][:values].second)
- .to include(type: 'StandardError', value: '4:Deadline Exceeded.')
-
- expect(result_hash[:extra])
- .to include(caller: 'test', grpc_debug_error_string: '{"hello":1}')
- end
-
- context 'with no custom fingerprint' do
- let(:data) do
- { extra: { caller: 'test' } }
- end
-
+ shared_examples 'processes the exception' do
it 'removes the debug error string and stores it as an extra field' do
- expect(result_hash).not_to include(:fingerprint)
+ expect(result_hash[:fingerprint])
+ .to eq(['GRPC::DeadlineExceeded', '4:Deadline Exceeded.'])
expect(result_hash[:exception][:values].first)
.to include(type: 'GRPC::DeadlineExceeded', value: '4:Deadline Exceeded.')
@@ -110,6 +139,37 @@ RSpec.describe Gitlab::ErrorTracking::Processor::GrpcErrorProcessor do
expect(result_hash[:extra])
.to include(caller: 'test', grpc_debug_error_string: '{"hello":1}')
end
+
+ context 'with no custom fingerprint' do
+ let(:data) do
+ { extra: { caller: 'test' } }
+ end
+
+ it 'removes the debug error string and stores it as an extra field' do
+ expect(result_hash[:fingerprint]).to be_blank
+
+ expect(result_hash[:exception][:values].first)
+ .to include(type: 'GRPC::DeadlineExceeded', value: '4:Deadline Exceeded.')
+
+ expect(result_hash[:exception][:values].second)
+ .to include(type: 'StandardError', value: '4:Deadline Exceeded.')
+
+ expect(result_hash[:extra])
+ .to include(caller: 'test', grpc_debug_error_string: '{"hello":1}')
+ end
+ end
+ end
+
+ context 'with Raven event' do
+ let(:event) { raven_event }
+
+ it_behaves_like 'processes the exception'
+ end
+
+ context 'with Sentry event' do
+ let(:event) { sentry_event }
+
+ it_behaves_like 'processes the exception'
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
index 3febc10831a..d33f8393904 100644
--- a/spec/lib/gitlab/error_tracking/processor/sidekiq_processor_spec.rb
+++ b/spec/lib/gitlab/error_tracking/processor/sidekiq_processor_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
require 'rspec-parameterized'
-RSpec.describe Gitlab::ErrorTracking::Processor::SidekiqProcessor do
+RSpec.describe Gitlab::ErrorTracking::Processor::SidekiqProcessor, :sentry do
after do
if described_class.instance_variable_defined?(:@permitted_arguments_for_worker)
described_class.remove_instance_variable(:@permitted_arguments_for_worker)
@@ -95,7 +95,9 @@ RSpec.describe Gitlab::ErrorTracking::Processor::SidekiqProcessor do
end
describe '.call' do
- let(:required_options) do
+ let(:exception) { StandardError.new('Test exception') }
+
+ let(:raven_required_options) do
{
configuration: Raven.configuration,
context: Raven.context,
@@ -103,9 +105,25 @@ RSpec.describe Gitlab::ErrorTracking::Processor::SidekiqProcessor do
}
end
- let(:event) { Raven::Event.new(required_options.merge(wrapped_value)) }
+ let(:raven_event) do
+ Raven::Event.new(raven_required_options.merge(wrapped_value))
+ end
+
+ let(:sentry_event) do
+ Sentry.get_current_client.event_from_exception(exception)
+ end
+
let(:result_hash) { described_class.call(event).to_hash }
+ before do
+ Sentry.get_current_scope.update_from_options(**wrapped_value)
+ Sentry.get_current_scope.apply_to_event(sentry_event)
+ end
+
+ after do
+ Sentry.get_current_scope.clear
+ end
+
context 'when there is Sidekiq data' do
let(:wrapped_value) { { extra: { sidekiq: value } } }
@@ -140,42 +158,90 @@ RSpec.describe Gitlab::ErrorTracking::Processor::SidekiqProcessor do
end
context 'when processing via the default error handler' do
- include_examples 'Sidekiq arguments', args_in_job_hash: true
+ context 'with Raven events' do
+ let(:event) { raven_event}
+
+ include_examples 'Sidekiq arguments', args_in_job_hash: true
+ end
+
+ context 'with Sentry events' do
+ let(:event) { sentry_event}
+
+ include_examples 'Sidekiq arguments', args_in_job_hash: true
+ end
end
context 'when processing via Gitlab::ErrorTracking' do
- include_examples 'Sidekiq arguments', args_in_job_hash: false
- end
+ context 'with Raven events' do
+ let(:event) { raven_event}
- context 'when a jobstr field is present' do
- let(:value) do
- {
- job: { 'args' => [1] },
- jobstr: { 'args' => [1] }.to_json
- }
+ include_examples 'Sidekiq arguments', args_in_job_hash: false
end
- it 'removes the jobstr' do
- expect(result_hash.dig(:extra, :sidekiq)).to eq(value.except(:jobstr))
+ context 'with Sentry events' do
+ let(:event) { sentry_event}
+
+ include_examples 'Sidekiq arguments', args_in_job_hash: false
end
end
- context 'when no jobstr value is present' do
- let(:value) { { job: { 'args' => [1] } } }
+ shared_examples 'handles jobstr fields' do
+ context 'when a jobstr field is present' do
+ let(:value) do
+ {
+ job: { 'args' => [1] },
+ jobstr: { 'args' => [1] }.to_json
+ }
+ end
+
+ it 'removes the jobstr' do
+ expect(result_hash.dig(:extra, :sidekiq)).to eq(value.except(:jobstr))
+ end
+ end
+
+ context 'when no jobstr value is present' do
+ let(:value) { { job: { 'args' => [1] } } }
- it 'does nothing' do
- expect(result_hash.dig(:extra, :sidekiq)).to eq(value)
+ it 'does nothing' do
+ expect(result_hash.dig(:extra, :sidekiq)).to eq(value)
+ end
end
end
+
+ context 'with Raven events' do
+ let(:event) { raven_event}
+
+ it_behaves_like 'handles jobstr fields'
+ end
+
+ context 'with Sentry events' do
+ let(:event) { sentry_event}
+
+ it_behaves_like 'handles jobstr fields'
+ end
end
context 'when there is no Sidekiq data' do
let(:value) { { tags: { foo: 'bar', baz: 'quux' } } }
let(:wrapped_value) { value }
- it 'does nothing' do
- expect(result_hash).to include(value)
- expect(result_hash.dig(:extra, :sidekiq)).to be_nil
+ shared_examples 'does nothing' do
+ it 'does nothing' do
+ expect(result_hash).to include(value)
+ expect(result_hash.dig(:extra, :sidekiq)).to be_nil
+ end
+ end
+
+ context 'with Raven events' do
+ let(:event) { raven_event}
+
+ it_behaves_like 'does nothing'
+ end
+
+ context 'with Sentry events' do
+ let(:event) { sentry_event}
+
+ it_behaves_like 'does nothing'
end
end
@@ -183,8 +249,22 @@ RSpec.describe Gitlab::ErrorTracking::Processor::SidekiqProcessor do
let(:value) { { other: 'foo' } }
let(:wrapped_value) { { extra: { sidekiq: value } } }
- it 'does nothing' do
- expect(result_hash.dig(:extra, :sidekiq)).to eq(value)
+ shared_examples 'does nothing' do
+ it 'does nothing' do
+ expect(result_hash.dig(:extra, :sidekiq)).to eq(value)
+ end
+ end
+
+ context 'with Raven events' do
+ let(:event) { raven_event}
+
+ it_behaves_like 'does nothing'
+ end
+
+ context 'with Sentry events' do
+ let(:event) { sentry_event}
+
+ it_behaves_like 'does nothing'
end
end
end
diff --git a/spec/lib/gitlab/error_tracking_spec.rb b/spec/lib/gitlab/error_tracking_spec.rb
index a5d44963f4b..936954fc1b6 100644
--- a/spec/lib/gitlab/error_tracking_spec.rb
+++ b/spec/lib/gitlab/error_tracking_spec.rb
@@ -3,13 +3,14 @@
require 'spec_helper'
require 'raven/transports/dummy'
+require 'sentry/transport/dummy_transport'
RSpec.describe Gitlab::ErrorTracking do
let(:exception) { RuntimeError.new('boom') }
let(:issue_url) { 'http://gitlab.com/gitlab-org/gitlab-foss/issues/1' }
let(:extra) { { issue_url: issue_url, some_other_info: 'info' } }
- let(:user) { create(:user) }
+ let_it_be(:user) { create(:user) }
let(:sentry_payload) do
{
@@ -43,17 +44,28 @@ RSpec.describe Gitlab::ErrorTracking do
}
end
- let(:sentry_event) { Gitlab::Json.parse(Raven.client.transport.events.last[1]) }
+ let(:raven_event) do
+ event = Raven.client.transport.events.last[1]
+ Gitlab::Json.parse(event)
+ end
+
+ let(:sentry_event) do
+ Sentry.get_current_client.transport.events.last
+ end
before do
+ stub_feature_flags(enable_old_sentry_integration: true)
+ stub_feature_flags(enable_new_sentry_integration: true)
stub_sentry_settings
- allow(described_class).to receive(:sentry_dsn).and_return(Gitlab.config.sentry.dsn)
+ allow(described_class).to receive(:sentry_configurable?) { true }
+
allow(Labkit::Correlation::CorrelationId).to receive(:current_id).and_return('cid')
allow(I18n).to receive(:locale).and_return('en')
described_class.configure do |config|
- config.encoding = 'json'
+ config.encoding = 'json' if config.respond_to?(:encoding=)
+ config.transport.transport_class = Sentry::DummyTransport if config.respond_to?(:transport)
end
end
@@ -63,6 +75,10 @@ RSpec.describe Gitlab::ErrorTracking do
end
end
+ after do
+ Sentry.get_current_scope.clear
+ end
+
describe '.track_and_raise_for_dev_exception' do
context 'when exceptions for dev should be raised' do
before do
@@ -71,6 +87,7 @@ RSpec.describe Gitlab::ErrorTracking do
it 'raises the exception' do
expect(Raven).to receive(:capture_exception).with(exception, sentry_payload)
+ expect(Sentry).to receive(:capture_exception).with(exception, sentry_payload)
expect do
described_class.track_and_raise_for_dev_exception(
@@ -89,6 +106,7 @@ RSpec.describe Gitlab::ErrorTracking do
it 'logs the exception with all attributes passed' do
expect(Raven).to receive(:capture_exception).with(exception, sentry_payload)
+ expect(Sentry).to receive(:capture_exception).with(exception, sentry_payload)
described_class.track_and_raise_for_dev_exception(
exception,
@@ -112,6 +130,7 @@ RSpec.describe Gitlab::ErrorTracking do
describe '.track_and_raise_exception' do
it 'always raises the exception' do
expect(Raven).to receive(:capture_exception).with(exception, sentry_payload)
+ expect(Sentry).to receive(:capture_exception).with(exception, sentry_payload)
expect do
described_class.track_and_raise_for_dev_exception(
@@ -136,20 +155,24 @@ RSpec.describe Gitlab::ErrorTracking do
end
describe '.track_exception' do
- subject(:track_exception) { described_class.track_exception(exception, extra) }
+ subject(:track_exception) do
+ described_class.track_exception(exception, extra)
+ end
before do
allow(Raven).to receive(:capture_exception).and_call_original
+ allow(Sentry).to receive(:capture_exception).and_call_original
allow(Gitlab::ErrorTracking::Logger).to receive(:error)
end
it 'calls Raven.capture_exception' do
track_exception
- expect(Raven).to have_received(:capture_exception).with(
- exception,
- sentry_payload
- )
+ expect(Raven)
+ .to have_received(:capture_exception).with(exception, sentry_payload)
+
+ expect(Sentry)
+ .to have_received(:capture_exception).with(exception, sentry_payload)
end
it 'calls Gitlab::ErrorTracking::Logger.error with formatted payload' do
@@ -172,7 +195,10 @@ RSpec.describe Gitlab::ErrorTracking do
context 'the exception implements :sentry_extra_data' do
let(:extra_info) { { event: 'explosion', size: :massive } }
- let(:exception) { double(message: 'bang!', sentry_extra_data: extra_info, backtrace: caller, cause: nil) }
+
+ before do
+ allow(exception).to receive(:sentry_extra_data).and_return(extra_info)
+ end
it 'includes the extra data from the exception in the tracking information' do
track_exception
@@ -180,29 +206,30 @@ RSpec.describe Gitlab::ErrorTracking do
expect(Raven).to have_received(:capture_exception).with(
exception, a_hash_including(extra: a_hash_including(extra_info))
)
+
+ expect(Sentry).to have_received(:capture_exception).with(
+ exception, a_hash_including(extra: a_hash_including(extra_info))
+ )
end
end
context 'the exception implements :sentry_extra_data, which returns nil' do
- let(:exception) { double(message: 'bang!', sentry_extra_data: nil, backtrace: caller, cause: nil) }
let(:extra) { { issue_url: issue_url } }
+ before do
+ allow(exception).to receive(:sentry_extra_data).and_return(nil)
+ end
+
it 'just includes the other extra info' do
track_exception
expect(Raven).to have_received(:capture_exception).with(
exception, a_hash_including(extra: a_hash_including(extra))
)
- end
- end
-
- context 'when the error is kind of an `ActiveRecord::StatementInvalid`' do
- let(:exception) { ActiveRecord::StatementInvalid.new(sql: 'SELECT "users".* FROM "users" WHERE "users"."id" = 1 AND "users"."foo" = $1') }
- it 'injects the normalized sql query into extra' do
- track_exception
-
- expect(sentry_event.dig('extra', 'sql')).to eq('SELECT "users".* FROM "users" WHERE "users"."id" = $2 AND "users"."foo" = $1')
+ expect(Sentry).to have_received(:capture_exception).with(
+ exception, a_hash_including(extra: a_hash_including(extra))
+ )
end
end
end
@@ -212,32 +239,65 @@ RSpec.describe Gitlab::ErrorTracking do
before do
allow(Raven).to receive(:capture_exception).and_call_original
+ allow(Sentry).to receive(:capture_exception).and_call_original
allow(Gitlab::ErrorTracking::Logger).to receive(:error)
end
context 'custom GitLab context when using Raven.capture_exception directly' do
- subject(:raven_capture_exception) { Raven.capture_exception(exception) }
+ subject(:track_exception) { Raven.capture_exception(exception) }
it 'merges a default set of tags into the existing tags' do
allow(Raven.context).to receive(:tags).and_return(foo: 'bar')
- raven_capture_exception
+ track_exception
- expect(sentry_event['tags']).to include('correlation_id', 'feature_category', 'foo', 'locale', 'program')
+ expect(raven_event['tags']).to include('correlation_id', 'feature_category', 'foo', 'locale', 'program')
end
it 'merges the current user information into the existing user information' do
Raven.user_context(id: -1)
- raven_capture_exception
+ track_exception
- expect(sentry_event['user']).to eq('id' => -1, 'username' => user.username)
+ expect(raven_event['user']).to eq('id' => -1, 'username' => user.username)
+ end
+ end
+
+ context 'custom GitLab context when using Sentry.capture_exception directly' do
+ subject(:track_exception) { Sentry.capture_exception(exception) }
+
+ it 'merges a default set of tags into the existing tags' do
+ Sentry.set_tags(foo: 'bar')
+
+ track_exception
+
+ expect(sentry_event.tags).to include(:correlation_id, :feature_category, :foo, :locale, :program)
+ end
+
+ it 'merges the current user information into the existing user information' do
+ Sentry.set_user(id: -1)
+
+ track_exception
+
+ expect(sentry_event.user).to eq(id: -1, username: user.username)
end
end
context 'with sidekiq args' do
context 'when the args does not have anything sensitive' do
- let(:extra) { { sidekiq: { 'class' => 'PostReceive', 'args' => [1, { 'id' => 2, 'name' => 'hello' }, 'some-value', 'another-value'] } } }
+ let(:extra) do
+ {
+ sidekiq: {
+ 'class' => 'PostReceive',
+ 'args' => [
+ 1,
+ { 'id' => 2, 'name' => 'hello' },
+ 'some-value',
+ 'another-value'
+ ]
+ }
+ }
+ end
it 'ensures extra.sidekiq.args is a string' do
track_exception
@@ -254,8 +314,10 @@ RSpec.describe Gitlab::ErrorTracking do
it 'does not filter parameters when sending to Sentry' do
track_exception
+ expected_data = [1, { 'id' => 2, 'name' => 'hello' }, 'some-value', 'another-value']
- expect(sentry_event.dig('extra', 'sidekiq', 'args')).to eq([1, { 'id' => 2, 'name' => 'hello' }, 'some-value', 'another-value'])
+ expect(raven_event.dig('extra', 'sidekiq', 'args')).to eq(expected_data)
+ expect(sentry_event.extra[:sidekiq]['args']).to eq(expected_data)
end
end
@@ -265,7 +327,8 @@ RSpec.describe Gitlab::ErrorTracking do
it 'filters sensitive arguments before sending and logging' do
track_exception
- expect(sentry_event.dig('extra', 'sidekiq', 'args')).to eq(['[FILTERED]', 1, 2])
+ expect(raven_event.dig('extra', 'sidekiq', 'args')).to eq(['[FILTERED]', 1, 2])
+ expect(sentry_event.extra[:sidekiq]['args']).to eq(['[FILTERED]', 1, 2])
expect(Gitlab::ErrorTracking::Logger).to have_received(:error).with(
hash_including(
'extra.sidekiq' => {
@@ -285,8 +348,10 @@ RSpec.describe Gitlab::ErrorTracking do
it 'sets the GRPC debug error string in the Sentry event and adds a custom fingerprint' do
track_exception
- expect(sentry_event.dig('extra', 'grpc_debug_error_string')).to eq('{"hello":1}')
- expect(sentry_event['fingerprint']).to eq(['GRPC::DeadlineExceeded', '4:unknown cause.'])
+ expect(raven_event.dig('extra', 'grpc_debug_error_string')).to eq('{"hello":1}')
+ expect(raven_event['fingerprint']).to eq(['GRPC::DeadlineExceeded', '4:unknown cause.'])
+ expect(sentry_event.extra[:grpc_debug_error_string]).to eq('{"hello":1}')
+ expect(sentry_event.fingerprint).to eq(['GRPC::DeadlineExceeded', '4:unknown cause.'])
end
end
@@ -296,8 +361,10 @@ RSpec.describe Gitlab::ErrorTracking do
it 'does not do any processing on the event' do
track_exception
- expect(sentry_event['extra']).not_to include('grpc_debug_error_string')
- expect(sentry_event['fingerprint']).to eq(['GRPC::DeadlineExceeded', '4:unknown cause'])
+ expect(raven_event['extra']).not_to include('grpc_debug_error_string')
+ expect(raven_event['fingerprint']).to eq(['GRPC::DeadlineExceeded', '4:unknown cause'])
+ expect(sentry_event.extra).not_to include(:grpc_debug_error_string)
+ expect(sentry_event.fingerprint).to eq(['GRPC::DeadlineExceeded', '4:unknown cause'])
end
end
end
diff --git a/spec/lib/gitlab/etag_caching/middleware_spec.rb b/spec/lib/gitlab/etag_caching/middleware_spec.rb
index 982c0d911bc..8228f95dd5e 100644
--- a/spec/lib/gitlab/etag_caching/middleware_spec.rb
+++ b/spec/lib/gitlab/etag_caching/middleware_spec.rb
@@ -174,7 +174,8 @@ RSpec.describe Gitlab::EtagCaching::Middleware, :clean_gitlab_redis_shared_state
it "pushes route's feature category to the context" do
expect(Gitlab::ApplicationContext).to receive(:push).with(
- feature_category: 'team_planning'
+ feature_category: 'team_planning',
+ caller_id: 'Projects::NotesController#index'
)
_, _, _ = middleware.call(build_request(path, if_none_match))
diff --git a/spec/lib/gitlab/etag_caching/router/rails_spec.rb b/spec/lib/gitlab/etag_caching/router/rails_spec.rb
new file mode 100644
index 00000000000..da6c11e3cb1
--- /dev/null
+++ b/spec/lib/gitlab/etag_caching/router/rails_spec.rb
@@ -0,0 +1,136 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::EtagCaching::Router::Rails do
+ it 'matches issue notes endpoint' do
+ result = match_route('/my-group/and-subgroup/here-comes-the-project/noteable/issue/1/notes')
+
+ expect(result).to be_present
+ expect(result.name).to eq 'issue_notes'
+ end
+
+ it 'matches MR notes endpoint' do
+ result = match_route('/my-group/and-subgroup/here-comes-the-project/noteable/merge_request/1/notes')
+
+ expect(result).to be_present
+ expect(result.name).to eq 'merge_request_notes'
+ end
+
+ it 'matches issue title endpoint' do
+ result = match_route('/my-group/my-project/-/issues/123/realtime_changes')
+
+ expect(result).to be_present
+ expect(result.name).to eq 'issue_title'
+ end
+
+ it 'matches with a project name that includes a suffix of create' do
+ result = match_route('/group/test-create/-/issues/123/realtime_changes')
+
+ expect(result).to be_present
+ expect(result.name).to eq 'issue_title'
+ end
+
+ it 'matches with a project name that includes a prefix of create' do
+ result = match_route('/group/create-test/-/issues/123/realtime_changes')
+
+ expect(result).to be_present
+ expect(result.name).to eq 'issue_title'
+ end
+
+ it 'matches project pipelines endpoint' do
+ result = match_route('/my-group/my-project/-/pipelines.json')
+
+ expect(result).to be_present
+ expect(result.name).to eq 'project_pipelines'
+ end
+
+ it 'matches commit pipelines endpoint' do
+ result = match_route('/my-group/my-project/-/commit/aa8260d253a53f73f6c26c734c72fdd600f6e6d4/pipelines.json')
+
+ expect(result).to be_present
+ expect(result.name).to eq 'commit_pipelines'
+ end
+
+ it 'matches new merge request pipelines endpoint' do
+ result = match_route('/my-group/my-project/-/merge_requests/new.json')
+
+ expect(result).to be_present
+ expect(result.name).to eq 'new_merge_request_pipelines'
+ end
+
+ it 'matches merge request pipelines endpoint' do
+ result = match_route('/my-group/my-project/-/merge_requests/234/pipelines.json')
+
+ expect(result).to be_present
+ expect(result.name).to eq 'merge_request_pipelines'
+ end
+
+ it 'matches build endpoint' do
+ result = match_route('/my-group/my-project/builds/234.json')
+
+ expect(result).to be_present
+ expect(result.name).to eq 'project_build'
+ end
+
+ it 'does not match blob with confusing name' do
+ result = match_route('/my-group/my-project/-/blob/master/pipelines.json')
+
+ expect(result).to be_blank
+ end
+
+ it 'matches the cluster environments path' do
+ result = match_route('/my-group/my-project/-/clusters/47/environments')
+
+ expect(result).to be_present
+ expect(result.name).to eq 'cluster_environments'
+ end
+
+ it 'matches the environments path' do
+ result = match_route('/my-group/my-project/-/environments.json')
+
+ expect(result).to be_present
+ expect(result.name).to eq 'environments'
+ end
+
+ it 'does not match the operations environments list path' do
+ result = match_route('/-/operations/environments.json')
+
+ expect(result).not_to be_present
+ end
+
+ it 'matches pipeline#show endpoint' do
+ result = match_route('/my-group/my-project/-/pipelines/2.json')
+
+ expect(result).to be_present
+ expect(result.name).to eq 'project_pipeline'
+ end
+
+ it 'has a valid feature category for every route', :aggregate_failures do
+ feature_categories = Gitlab::FeatureCategories.default.categories
+
+ described_class::ROUTES.each do |route|
+ expect(feature_categories).to include(route.feature_category), "#{route.name} has a category of #{route.feature_category}, which is not valid"
+ end
+ end
+
+ it 'has a caller_id for every route', :aggregate_failures do
+ described_class::ROUTES.each do |route|
+ expect(route.caller_id).to include('#'), "#{route.name} has caller_id #{route.caller_id}, which is not valid"
+ end
+ end
+
+ def match_route(path)
+ described_class.match(double(path_info: path))
+ end
+
+ describe '.cache_key' do
+ subject do
+ described_class.cache_key(double(path: '/my-group/my-project/builds/234.json'))
+ end
+
+ it 'uses request path as cache key' do
+ is_expected.to eq '/my-group/my-project/builds/234.json'
+ end
+ end
+end
diff --git a/spec/lib/gitlab/etag_caching/router/restful_spec.rb b/spec/lib/gitlab/etag_caching/router/restful_spec.rb
deleted file mode 100644
index a0fc480369c..00000000000
--- a/spec/lib/gitlab/etag_caching/router/restful_spec.rb
+++ /dev/null
@@ -1,130 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Gitlab::EtagCaching::Router::Restful do
- it 'matches issue notes endpoint' do
- result = match_route('/my-group/and-subgroup/here-comes-the-project/noteable/issue/1/notes')
-
- expect(result).to be_present
- expect(result.name).to eq 'issue_notes'
- end
-
- it 'matches MR notes endpoint' do
- result = match_route('/my-group/and-subgroup/here-comes-the-project/noteable/merge_request/1/notes')
-
- expect(result).to be_present
- expect(result.name).to eq 'merge_request_notes'
- end
-
- it 'matches issue title endpoint' do
- result = match_route('/my-group/my-project/-/issues/123/realtime_changes')
-
- expect(result).to be_present
- expect(result.name).to eq 'issue_title'
- end
-
- it 'matches with a project name that includes a suffix of create' do
- result = match_route('/group/test-create/-/issues/123/realtime_changes')
-
- expect(result).to be_present
- expect(result.name).to eq 'issue_title'
- end
-
- it 'matches with a project name that includes a prefix of create' do
- result = match_route('/group/create-test/-/issues/123/realtime_changes')
-
- expect(result).to be_present
- expect(result.name).to eq 'issue_title'
- end
-
- it 'matches project pipelines endpoint' do
- result = match_route('/my-group/my-project/-/pipelines.json')
-
- expect(result).to be_present
- expect(result.name).to eq 'project_pipelines'
- end
-
- it 'matches commit pipelines endpoint' do
- result = match_route('/my-group/my-project/-/commit/aa8260d253a53f73f6c26c734c72fdd600f6e6d4/pipelines.json')
-
- expect(result).to be_present
- expect(result.name).to eq 'commit_pipelines'
- end
-
- it 'matches new merge request pipelines endpoint' do
- result = match_route('/my-group/my-project/-/merge_requests/new.json')
-
- expect(result).to be_present
- expect(result.name).to eq 'new_merge_request_pipelines'
- end
-
- it 'matches merge request pipelines endpoint' do
- result = match_route('/my-group/my-project/-/merge_requests/234/pipelines.json')
-
- expect(result).to be_present
- expect(result.name).to eq 'merge_request_pipelines'
- end
-
- it 'matches build endpoint' do
- result = match_route('/my-group/my-project/builds/234.json')
-
- expect(result).to be_present
- expect(result.name).to eq 'project_build'
- end
-
- it 'does not match blob with confusing name' do
- result = match_route('/my-group/my-project/-/blob/master/pipelines.json')
-
- expect(result).to be_blank
- end
-
- it 'matches the cluster environments path' do
- result = match_route('/my-group/my-project/-/clusters/47/environments')
-
- expect(result).to be_present
- expect(result.name).to eq 'cluster_environments'
- end
-
- it 'matches the environments path' do
- result = match_route('/my-group/my-project/-/environments.json')
-
- expect(result).to be_present
- expect(result.name).to eq 'environments'
- end
-
- it 'does not match the operations environments list path' do
- result = match_route('/-/operations/environments.json')
-
- expect(result).not_to be_present
- end
-
- it 'matches pipeline#show endpoint' do
- result = match_route('/my-group/my-project/-/pipelines/2.json')
-
- expect(result).to be_present
- expect(result.name).to eq 'project_pipeline'
- end
-
- it 'has a valid feature category for every route', :aggregate_failures do
- feature_categories = Gitlab::FeatureCategories.default.categories
-
- described_class::ROUTES.each do |route|
- expect(feature_categories).to include(route.feature_category), "#{route.name} has a category of #{route.feature_category}, which is not valid"
- end
- end
-
- def match_route(path)
- described_class.match(double(path_info: path))
- end
-
- describe '.cache_key' do
- subject do
- described_class.cache_key(double(path: '/my-group/my-project/builds/234.json'))
- end
-
- it 'uses request path as cache key' do
- is_expected.to eq '/my-group/my-project/builds/234.json'
- end
- end
-end
diff --git a/spec/lib/gitlab/etag_caching/router_spec.rb b/spec/lib/gitlab/etag_caching/router_spec.rb
index ce728c41f48..8d2183bc03d 100644
--- a/spec/lib/gitlab/etag_caching/router_spec.rb
+++ b/spec/lib/gitlab/etag_caching/router_spec.rb
@@ -10,7 +10,7 @@ RSpec.describe Gitlab::EtagCaching::Router do
expect(result).to be_present
expect(result.name).to eq 'project_pipelines'
- expect(result.router).to eq Gitlab::EtagCaching::Router::Restful
+ expect(result.router).to eq Gitlab::EtagCaching::Router::Rails
end
end
diff --git a/spec/lib/gitlab/experiment/rollout/feature_spec.rb b/spec/lib/gitlab/experiment/rollout/feature_spec.rb
index d73757be79b..82603e6fe0f 100644
--- a/spec/lib/gitlab/experiment/rollout/feature_spec.rb
+++ b/spec/lib/gitlab/experiment/rollout/feature_spec.rb
@@ -9,9 +9,10 @@ RSpec.describe Gitlab::Experiment::Rollout::Feature, :experiment do
describe "#enabled?" do
before do
- allow(Feature::Definition).to receive(:get).and_return('_instance_')
- allow(Gitlab).to receive(:dev_env_or_com?).and_return(true)
- allow(Feature).to receive(:get).and_return(double(state: :on))
+ stub_feature_flags(gitlab_experiment: true)
+ allow(subject).to receive(:feature_flag_defined?).and_return(true)
+ allow(Gitlab).to receive(:com?).and_return(true)
+ allow(subject).to receive(:feature_flag_instance).and_return(double(state: :on))
end
it "is enabled when all criteria are met" do
@@ -19,19 +20,25 @@ RSpec.describe Gitlab::Experiment::Rollout::Feature, :experiment do
end
it "isn't enabled if the feature definition doesn't exist" do
- expect(Feature::Definition).to receive(:get).with('namespaced_stub').and_return(nil)
+ expect(subject).to receive(:feature_flag_defined?).and_return(false)
expect(subject).not_to be_enabled
end
it "isn't enabled if we're not in dev or dotcom environments" do
- expect(Gitlab).to receive(:dev_env_or_com?).and_return(false)
+ expect(Gitlab).to receive(:com?).and_return(false)
expect(subject).not_to be_enabled
end
it "isn't enabled if the feature flag state is :off" do
- expect(Feature).to receive(:get).with('namespaced_stub').and_return(double(state: :off))
+ expect(subject).to receive(:feature_flag_instance).and_return(double(state: :off))
+
+ expect(subject).not_to be_enabled
+ end
+
+ it "isn't enabled if the gitlab_experiment feature flag is false" do
+ stub_feature_flags(gitlab_experiment: false)
expect(subject).not_to be_enabled
end
diff --git a/spec/lib/gitlab/experimentation/controller_concern_spec.rb b/spec/lib/gitlab/experimentation/controller_concern_spec.rb
index 8a96771eeb8..435a0d56301 100644
--- a/spec/lib/gitlab/experimentation/controller_concern_spec.rb
+++ b/spec/lib/gitlab/experimentation/controller_concern_spec.rb
@@ -17,7 +17,7 @@ RSpec.describe Gitlab::Experimentation::ControllerConcern, type: :controller do
}
)
- allow(Gitlab).to receive(:dev_env_or_com?).and_return(is_gitlab_com)
+ allow(Gitlab).to receive(:com?).and_return(is_gitlab_com)
Feature.enable_percentage_of_time(:test_experiment_experiment_percentage, enabled_percentage)
end
diff --git a/spec/lib/gitlab/experimentation/experiment_spec.rb b/spec/lib/gitlab/experimentation/experiment_spec.rb
index d9bf85460b3..a5cc69b9538 100644
--- a/spec/lib/gitlab/experimentation/experiment_spec.rb
+++ b/spec/lib/gitlab/experimentation/experiment_spec.rb
@@ -25,7 +25,7 @@ RSpec.describe Gitlab::Experimentation::Experiment do
describe '#active?' do
before do
- allow(Gitlab).to receive(:dev_env_or_com?).and_return(on_gitlab_com)
+ allow(Gitlab).to receive(:com?).and_return(on_gitlab_com)
end
subject { experiment.active? }
diff --git a/spec/lib/gitlab/fips_spec.rb b/spec/lib/gitlab/fips_spec.rb
new file mode 100644
index 00000000000..4d19a44f617
--- /dev/null
+++ b/spec/lib/gitlab/fips_spec.rb
@@ -0,0 +1,51 @@
+# frozen_string_literal: true
+
+require "spec_helper"
+
+RSpec.describe Gitlab::FIPS do
+ describe ".enabled?" do
+ subject { described_class.enabled? }
+
+ let(:openssl_fips_mode) { false }
+ let(:fips_mode_env_var) { nil }
+
+ before do
+ expect(OpenSSL).to receive(:fips_mode).and_return(openssl_fips_mode)
+ stub_env("FIPS_MODE", fips_mode_env_var)
+ end
+
+ describe "OpenSSL auto-detection" do
+ context "OpenSSL is in FIPS mode" do
+ let(:openssl_fips_mode) { true }
+
+ it { is_expected.to be_truthy }
+ end
+
+ context "OpenSSL is not in FIPS mode" do
+ let(:openssl_fips_mode) { false }
+
+ it { is_expected.to be_falsey }
+ end
+ end
+
+ describe "manual configuration via env var" do
+ context "env var is not set" do
+ let(:fips_mode_env_var) { nil }
+
+ it { is_expected.to be_falsey }
+ end
+
+ context "env var is set to true" do
+ let(:fips_mode_env_var) { "true" }
+
+ it { is_expected.to be_truthy }
+ end
+
+ context "env var is set to false" do
+ let(:fips_mode_env_var) { "false" }
+
+ it { is_expected.to be_falsey }
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/form_builders/gitlab_ui_form_builder_spec.rb b/spec/lib/gitlab/form_builders/gitlab_ui_form_builder_spec.rb
index e160e88487b..a5f26a212ab 100644
--- a/spec/lib/gitlab/form_builders/gitlab_ui_form_builder_spec.rb
+++ b/spec/lib/gitlab/form_builders/gitlab_ui_form_builder_spec.rb
@@ -78,6 +78,29 @@ RSpec.describe Gitlab::FormBuilders::GitlabUiFormBuilder do
expect(fake_template).to have_received(:label).with(:user, :view_diffs_file_by_file, { class: %w(custom-control-label label-foo-bar), object: user, value: nil })
end
end
+
+ context 'with checkbox_options: { multiple: true }' do
+ let(:optional_args) do
+ {
+ checkbox_options: { multiple: true },
+ checked_value: 'one',
+ unchecked_value: false
+ }
+ end
+
+ it 'renders labels with correct for attributes' do
+ expected_html = <<~EOS
+ <div class="gl-form-checkbox custom-control custom-checkbox">
+ <input class="custom-control-input" type="checkbox" value="one" name="user[view_diffs_file_by_file][]" id="user_view_diffs_file_by_file_one" />
+ <label class="custom-control-label" for="user_view_diffs_file_by_file_one">
+ Show one file at a time on merge request&#39;s Changes tab
+ </label>
+ </div>
+ EOS
+
+ expect(checkbox_html).to eq(html_strip_whitespace(expected_html))
+ end
+ end
end
describe '#gitlab_ui_radio_component' do
diff --git a/spec/lib/gitlab/git/wiki_spec.rb b/spec/lib/gitlab/git/wiki_spec.rb
index ee0c0e2708e..dddcf8c40fc 100644
--- a/spec/lib/gitlab/git/wiki_spec.rb
+++ b/spec/lib/gitlab/git/wiki_spec.rb
@@ -48,14 +48,26 @@ RSpec.describe Gitlab::Git::Wiki do
end
it 'returns the right page' do
- expect(subject.page(title: 'page1', dir: '').url_path).to eq 'page1'
- expect(subject.page(title: 'page1', dir: 'foo').url_path).to eq 'foo/page1'
+ page = subject.page(title: 'page1', dir: '')
+ expect(page.url_path).to eq 'page1'
+ expect(page.raw_data).to eq 'content'
+
+ page = subject.page(title: 'page1', dir: 'foo')
+ expect(page.url_path).to eq 'foo/page1'
+ expect(page.raw_data).to eq 'content foo/page1'
end
it 'returns nil for invalid arguments' do
expect(subject.page(title: '')).to be_nil
expect(subject.page(title: 'foo', version: ':')).to be_nil
end
+
+ it 'does not return content if load_content param is set to false' do
+ page = subject.page(title: 'page1', dir: '', load_content: false)
+
+ expect(page.url_path).to eq 'page1'
+ expect(page.raw_data).to be_empty
+ end
end
describe '#preview_slug' do
diff --git a/spec/lib/gitlab/git_access_snippet_spec.rb b/spec/lib/gitlab/git_access_snippet_spec.rb
index d690a4b2db4..b6a61de87a6 100644
--- a/spec/lib/gitlab/git_access_snippet_spec.rb
+++ b/spec/lib/gitlab/git_access_snippet_spec.rb
@@ -397,38 +397,6 @@ RSpec.describe Gitlab::GitAccessSnippet do
end
end
- describe 'HEAD realignment' do
- let_it_be(:snippet) { create(:project_snippet, :private, :repository, project: project) }
-
- shared_examples 'HEAD is updated to the snippet default branch' do
- let(:actor) { snippet.author }
-
- specify do
- expect(snippet).to receive(:change_head_to_default_branch).and_call_original
-
- subject
- end
-
- context 'when an error is raised' do
- let(:actor) { nil }
-
- it 'does not realign HEAD' do
- expect(snippet).not_to receive(:change_head_to_default_branch).and_call_original
-
- expect { subject }.to raise_error(described_class::ForbiddenError)
- end
- end
- end
-
- it_behaves_like 'HEAD is updated to the snippet default branch' do
- subject { push_access_check }
- end
-
- it_behaves_like 'HEAD is updated to the snippet default branch' do
- subject { pull_access_check }
- end
- end
-
private
def raise_not_found(message_key)
diff --git a/spec/lib/gitlab/gitaly_client/operation_service_spec.rb b/spec/lib/gitlab/gitaly_client/operation_service_spec.rb
index f0115aa6b2b..0c04863f466 100644
--- a/spec/lib/gitlab/gitaly_client/operation_service_spec.rb
+++ b/spec/lib/gitlab/gitaly_client/operation_service_spec.rb
@@ -386,6 +386,73 @@ RSpec.describe Gitlab::GitalyClient::OperationService do
it_behaves_like 'cherry pick and revert errors'
end
+ describe '#rebase' do
+ let(:response) { Gitaly::UserRebaseConfirmableResponse.new }
+
+ subject do
+ client.rebase(
+ user,
+ '',
+ branch: 'master',
+ branch_sha: 'b83d6e391c22777fca1ed3012fce84f633d7fed0',
+ remote_repository: repository,
+ remote_branch: 'master'
+ )
+ end
+
+ shared_examples '#rebase with an error' do
+ it 'raises a GitError exception' do
+ expect_any_instance_of(Gitaly::OperationService::Stub)
+ .to receive(:user_rebase_confirmable)
+ .and_raise(raised_error)
+
+ expect { subject }.to raise_error(expected_error)
+ end
+ end
+
+ context 'when AccessError is raised' do
+ let(:raised_error) do
+ new_detailed_error(
+ GRPC::Core::StatusCodes::INTERNAL,
+ 'something failed',
+ Gitaly::UserRebaseConfirmableError.new(
+ access_check: Gitaly::AccessCheckError.new(
+ error_message: 'something went wrong'
+ )))
+ end
+
+ let(:expected_error) { Gitlab::Git::PreReceiveError }
+
+ it_behaves_like '#rebase with an error'
+ end
+
+ context 'when RebaseConflictError is raised' do
+ let(:raised_error) do
+ new_detailed_error(
+ GRPC::Core::StatusCodes::INTERNAL,
+ 'something failed',
+ Gitaly::UserSquashError.new(
+ rebase_conflict: Gitaly::MergeConflictError.new(
+ conflicting_files: ['conflicting-file']
+ )))
+ end
+
+ let(:expected_error) { Gitlab::Git::Repository::GitError }
+
+ it_behaves_like '#rebase with an error'
+ end
+
+ context 'when non-detailed gRPC error is raised' do
+ let(:raised_error) do
+ GRPC::Internal.new('non-detailed error')
+ end
+
+ let(:expected_error) { GRPC::Internal }
+
+ it_behaves_like '#rebase with an error'
+ end
+ end
+
describe '#user_squash' do
let(:start_sha) { 'b83d6e391c22777fca1ed3012fce84f633d7fed0' }
let(:end_sha) { '54cec5282aa9f21856362fe321c800c236a61615' }
@@ -437,41 +504,93 @@ RSpec.describe Gitlab::GitalyClient::OperationService do
end
end
- describe '#user_commit_files' do
- subject do
- client.user_commit_files(
- gitaly_user, 'my-branch', 'Commit files message', [], 'janedoe@example.com', 'Jane Doe',
- 'master', repository)
+ shared_examples '#user_squash with an error' do
+ it 'raises a GitError exception' do
+ expect_any_instance_of(Gitaly::OperationService::Stub)
+ .to receive(:user_squash).with(request, kind_of(Hash))
+ .and_raise(raised_error)
+
+ expect { subject }.to raise_error(expected_error)
end
+ end
- before do
- expect_any_instance_of(Gitaly::OperationService::Stub)
- .to receive(:user_commit_files).with(kind_of(Enumerator), kind_of(Hash))
- .and_return(response)
+ context 'when ResolveRevisionError is raised' do
+ let(:raised_error) do
+ new_detailed_error(
+ GRPC::Core::StatusCodes::INVALID_ARGUMENT,
+ 'something failed',
+ Gitaly::UserSquashError.new(
+ resolve_revision: Gitaly::ResolveRevisionError.new(
+ revision: start_sha
+ )))
end
- context 'when a pre_receive_error is present' do
- let(:response) { Gitaly::UserCommitFilesResponse.new(pre_receive_error: "GitLab: something failed") }
+ let(:expected_error) { Gitlab::Git::Repository::GitError }
- it 'raises a PreReceiveError' do
- expect { subject }.to raise_error(Gitlab::Git::PreReceiveError, "something failed")
- end
+ it_behaves_like '#user_squash with an error'
+ end
+
+ context 'when RebaseConflictError is raised' do
+ let(:raised_error) do
+ new_detailed_error(
+ GRPC::Core::StatusCodes::INTERNAL,
+ 'something failed',
+ Gitaly::UserSquashError.new(
+ rebase_conflict: Gitaly::MergeConflictError.new(
+ conflicting_files: ['conflicting-file']
+ )))
end
- context 'when an index_error is present' do
- let(:response) { Gitaly::UserCommitFilesResponse.new(index_error: "something failed") }
+ let(:expected_error) { Gitlab::Git::Repository::GitError }
- it 'raises a PreReceiveError' do
- expect { subject }.to raise_error(Gitlab::Git::Index::IndexError, "something failed")
- end
+ it_behaves_like '#user_squash with an error'
+ end
+
+ context 'when non-detailed gRPC error is raised' do
+ let(:raised_error) do
+ GRPC::Internal.new('non-detailed error')
+ end
+
+ let(:expected_error) { GRPC::Internal }
+
+ it_behaves_like '#user_squash with an error'
+ end
+ end
+
+ describe '#user_commit_files' do
+ subject do
+ client.user_commit_files(
+ gitaly_user, 'my-branch', 'Commit files message', [], 'janedoe@example.com', 'Jane Doe',
+ 'master', repository)
+ end
+
+ before do
+ expect_any_instance_of(Gitaly::OperationService::Stub)
+ .to receive(:user_commit_files).with(kind_of(Enumerator), kind_of(Hash))
+ .and_return(response)
+ end
+
+ context 'when a pre_receive_error is present' do
+ let(:response) { Gitaly::UserCommitFilesResponse.new(pre_receive_error: "GitLab: something failed") }
+
+ it 'raises a PreReceiveError' do
+ expect { subject }.to raise_error(Gitlab::Git::PreReceiveError, "something failed")
end
+ end
- context 'when branch_update is nil' do
- let(:response) { Gitaly::UserCommitFilesResponse.new }
+ context 'when an index_error is present' do
+ let(:response) { Gitaly::UserCommitFilesResponse.new(index_error: "something failed") }
- it { expect(subject).to be_nil }
+ it 'raises a PreReceiveError' do
+ expect { subject }.to raise_error(Gitlab::Git::Index::IndexError, "something failed")
end
end
+
+ context 'when branch_update is nil' do
+ let(:response) { Gitaly::UserCommitFilesResponse.new }
+
+ it { expect(subject).to be_nil }
+ end
end
describe '#user_commit_patches' do
diff --git a/spec/lib/gitlab/gitaly_client/repository_service_spec.rb b/spec/lib/gitlab/gitaly_client/repository_service_spec.rb
index 353726b56f6..39de9a65390 100644
--- a/spec/lib/gitlab/gitaly_client/repository_service_spec.rb
+++ b/spec/lib/gitlab/gitaly_client/repository_service_spec.rb
@@ -54,6 +54,28 @@ RSpec.describe Gitlab::GitalyClient::RepositoryService do
end
end
+ describe '#optimize_repository' do
+ it 'sends a optimize_repository message' do
+ expect_any_instance_of(Gitaly::RepositoryService::Stub)
+ .to receive(:optimize_repository)
+ .with(gitaly_request_with_path(storage_name, relative_path), kind_of(Hash))
+ .and_return(double(:optimize_repository))
+
+ client.optimize_repository
+ end
+ end
+
+ describe '#prune_unreachable_objects' do
+ it 'sends a prune_unreachable_objects message' do
+ expect_any_instance_of(Gitaly::RepositoryService::Stub)
+ .to receive(:prune_unreachable_objects)
+ .with(gitaly_request_with_path(storage_name, relative_path), kind_of(Hash))
+ .and_return(double(:prune_unreachable_objects))
+
+ client.prune_unreachable_objects
+ end
+ end
+
describe '#repository_size' do
it 'sends a repository_size message' do
expect_any_instance_of(Gitaly::RepositoryService::Stub)
@@ -196,6 +218,26 @@ RSpec.describe Gitlab::GitalyClient::RepositoryService do
end
end
+ describe '#create_repository' do
+ it 'sends a create_repository message without arguments' do
+ expect_any_instance_of(Gitaly::RepositoryService::Stub)
+ .to receive(:create_repository)
+ .with(gitaly_request_with_path(storage_name, relative_path).and(gitaly_request_with_params(default_branch: '')), kind_of(Hash))
+ .and_return(double)
+
+ client.create_repository
+ end
+
+ it 'sends a create_repository message with default branch' do
+ expect_any_instance_of(Gitaly::RepositoryService::Stub)
+ .to receive(:create_repository)
+ .with(gitaly_request_with_path(storage_name, relative_path).and(gitaly_request_with_params(default_branch: 'default-branch-name')), kind_of(Hash))
+ .and_return(double)
+
+ client.create_repository('default-branch-name')
+ end
+ end
+
describe '#create_from_snapshot' do
it 'sends a create_repository_from_snapshot message' do
expect_any_instance_of(Gitaly::RepositoryService::Stub)
diff --git a/spec/lib/gitlab/github_import/importer/diff_note_importer_spec.rb b/spec/lib/gitlab/github_import/importer/diff_note_importer_spec.rb
index c8e744ab262..321ad7d3238 100644
--- a/spec/lib/gitlab/github_import/importer/diff_note_importer_spec.rb
+++ b/spec/lib/gitlab/github_import/importer/diff_note_importer_spec.rb
@@ -12,6 +12,7 @@ RSpec.describe Gitlab::GithubImport::Importer::DiffNoteImporter, :aggregate_fail
let(:updated_at) { Time.new(2017, 1, 1, 12, 15).utc }
let(:note_body) { 'Hello' }
let(:file_path) { 'files/ruby/popen.rb' }
+ let(:end_line) { 15 }
let(:diff_hunk) do
'@@ -14 +14 @@
@@ -31,7 +32,7 @@ RSpec.describe Gitlab::GithubImport::Importer::DiffNoteImporter, :aggregate_fail
created_at: created_at,
updated_at: updated_at,
start_line: nil,
- end_line: 15,
+ end_line: end_line,
github_id: 1,
diff_hunk: diff_hunk,
side: 'RIGHT'
@@ -173,7 +174,24 @@ RSpec.describe Gitlab::GithubImport::Importer::DiffNoteImporter, :aggregate_fail
NOTE
end
- context 'when the note diff file creation fails' do
+ context 'when the note diff file creation fails with DiffNoteCreationError due to outdated suggestion' do
+ let(:end_line) { nil }
+
+ it 'falls back to the LegacyDiffNote' do
+ expect(Gitlab::GithubImport::Logger)
+ .to receive(:warn)
+ .with(
+ message: "Validation failed: Line code can't be blank, Line code must be a valid line code, Position is incomplete",
+ 'error.class': 'Gitlab::GithubImport::Importer::DiffNoteImporter::DiffNoteCreationError'
+ )
+
+ expect { subject.execute }
+ .to change(LegacyDiffNote, :count)
+ .and not_change(DiffNote, :count)
+ end
+ end
+
+ context 'when the note diff file creation fails with NoteDiffFileCreationError' do
it 'falls back to the LegacyDiffNote' do
exception = ::DiffNote::NoteDiffFileCreationError.new('Failed to create diff note file')
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 a70ff0bd82d..c1b0f4df29a 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
@@ -104,8 +104,13 @@ RSpec.describe Gitlab::GithubImport::Importer::PullRequestsImporter do
.and_yield(pull_request)
expect(Gitlab::GithubImport::ImportPullRequestWorker)
- .to receive(:perform_async)
- .with(project.id, an_instance_of(Hash), an_instance_of(String))
+ .to receive(:bulk_perform_in)
+ .with(
+ 1.second,
+ [[project.id, an_instance_of(Hash), an_instance_of(String)]],
+ batch_delay: 1.minute,
+ batch_size: 200
+ )
waiter = importer.parallel_import
diff --git a/spec/lib/gitlab/github_import/parallel_scheduling_spec.rb b/spec/lib/gitlab/github_import/parallel_scheduling_spec.rb
index f375e84e0fd..6a19afbc60d 100644
--- a/spec/lib/gitlab/github_import/parallel_scheduling_spec.rb
+++ b/spec/lib/gitlab/github_import/parallel_scheduling_spec.rb
@@ -22,6 +22,10 @@ RSpec.describe Gitlab::GithubImport::ParallelScheduling do
def collection_method
:issues
end
+
+ def parallel_import_batch
+ { size: 10, delay: 1.minute }
+ end
end
end
@@ -254,35 +258,61 @@ RSpec.describe Gitlab::GithubImport::ParallelScheduling do
describe '#parallel_import' do
let(:importer) { importer_class.new(project, client) }
+ let(:repr_class) { double(:representation) }
+ let(:worker_class) { double(:worker) }
+ let(:object) { double(:object) }
+ let(:batch_size) { 200 }
+ let(:batch_delay) { 1.minute }
- it 'imports data in parallel' do
- repr_class = double(:representation)
- worker_class = double(:worker)
- object = double(:object)
-
- expect(importer)
- .to receive(:each_object_to_import)
- .and_yield(object)
-
- expect(importer)
+ before do
+ allow(importer)
.to receive(:representation_class)
.and_return(repr_class)
- expect(importer)
+ allow(importer)
.to receive(:sidekiq_worker_class)
.and_return(worker_class)
- expect(repr_class)
+ allow(repr_class)
.to receive(:from_api_response)
.with(object)
.and_return({ title: 'Foo' })
+ end
+
+ context 'with multiple objects' do
+ before do
+ allow(importer).to receive(:parallel_import_batch) { { size: batch_size, delay: batch_delay } }
+ expect(importer).to receive(:each_object_to_import).and_yield(object).and_yield(object).and_yield(object)
+ end
- expect(worker_class)
- .to receive(:perform_async)
- .with(project.id, { title: 'Foo' }, an_instance_of(String))
+ it 'imports data in parallel batches with delays' do
+ expect(worker_class).to receive(:bulk_perform_in).with(1.second, [
+ [project.id, { title: 'Foo' }, an_instance_of(String)],
+ [project.id, { title: 'Foo' }, an_instance_of(String)],
+ [project.id, { title: 'Foo' }, an_instance_of(String)]
+ ], batch_size: batch_size, batch_delay: batch_delay)
+
+ importer.parallel_import
+ end
+ end
- expect(importer.parallel_import)
- .to be_an_instance_of(Gitlab::JobWaiter)
+ context 'when FF is disabled' do
+ before do
+ stub_feature_flags(spread_parallel_import: false)
+ end
+
+ it 'imports data in parallel' do
+ expect(importer)
+ .to receive(:each_object_to_import)
+ .and_yield(object)
+
+ expect(worker_class)
+ .to receive(:perform_async)
+ .with(project.id, { title: 'Foo' }, an_instance_of(String))
+
+ expect(importer.parallel_import)
+ .to be_an_instance_of(Gitlab::JobWaiter)
+ end
end
end
diff --git a/spec/lib/gitlab/graphql/loaders/batch_commit_loader_spec.rb b/spec/lib/gitlab/graphql/loaders/batch_commit_loader_spec.rb
new file mode 100644
index 00000000000..c7e8b34bbe0
--- /dev/null
+++ b/spec/lib/gitlab/graphql/loaders/batch_commit_loader_spec.rb
@@ -0,0 +1,48 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Graphql::Loaders::BatchCommitLoader do
+ include RepoHelpers
+
+ describe '#find' do
+ let_it_be(:first_project) { create(:project, :repository) }
+ let_it_be(:second_project) { create(:project, :repository) }
+
+ let_it_be(:first_commit) { first_project.commit(sample_commit.id) }
+ let_it_be(:second_commit) { first_project.commit(another_sample_commit.id) }
+ let_it_be(:third_commit) { second_project.commit(sample_big_commit.id) }
+
+ it 'finds a commit by id' do
+ result = described_class.new(
+ container_class: Project,
+ container_id: first_project.id,
+ oid: first_commit.id
+ ).find
+
+ expect(result.force).to eq(first_commit)
+ end
+
+ it 'only queries once' do
+ expect do
+ [
+ described_class.new(
+ container_class: Project,
+ container_id: first_project.id,
+ oid: first_commit.id
+ ).find,
+ described_class.new(
+ container_class: Project,
+ container_id: first_project.id,
+ oid: second_commit.id
+ ).find,
+ described_class.new(
+ container_class: Project,
+ container_id: second_project.id,
+ oid: third_commit.id
+ ).find
+ ].map(&:force)
+ end.not_to exceed_query_limit(2)
+ end
+ end
+end
diff --git a/spec/lib/gitlab/graphql/markdown_field_spec.rb b/spec/lib/gitlab/graphql/markdown_field_spec.rb
index c2253811e91..ed3f19d8cf2 100644
--- a/spec/lib/gitlab/graphql/markdown_field_spec.rb
+++ b/spec/lib/gitlab/graphql/markdown_field_spec.rb
@@ -11,7 +11,7 @@ RSpec.describe Gitlab::Graphql::MarkdownField do
expect(field.name).to eq('testHtml')
expect(field.description).to eq('The GitLab Flavored Markdown rendering of `hello`')
expect(field.type).to eq(GraphQL::Types::String)
- expect(field.to_graphql.complexity).to eq(5)
+ expect(field.complexity).to eq(5)
end
context 'developer warnings' do
@@ -43,7 +43,7 @@ RSpec.describe Gitlab::Graphql::MarkdownField do
let(:field) { type_class.fields['noteHtml'] }
it 'renders markdown from the same property as the field name without the `_html` suffix' do
- expect(field.to_graphql.resolve(type_instance, {}, context)).to eq(expected_markdown)
+ expect(field.resolve(type_instance, {}, context)).to eq(expected_markdown)
end
context 'when a `method` argument is passed' do
@@ -51,7 +51,7 @@ RSpec.describe Gitlab::Graphql::MarkdownField do
let(:field) { type_class.fields['testHtml'] }
it 'renders markdown from a specific property' do
- expect(field.to_graphql.resolve(type_instance, {}, context)).to eq(expected_markdown)
+ expect(field.resolve(type_instance, {}, context)).to eq(expected_markdown)
end
end
@@ -62,21 +62,21 @@ RSpec.describe Gitlab::Graphql::MarkdownField do
let(:note) { build(:note, note: "Referencing #{issue.to_reference(full: true)}") }
it 'renders markdown correctly' do
- expect(field.to_graphql.resolve(type_instance, {}, context)).to include(issue_path(issue))
+ expect(field.resolve(type_instance, {}, context)).to include(issue_path(issue))
end
context 'when the issue is not publicly accessible' do
let_it_be(:project) { create(:project, :private) }
it 'hides the references from users that are not allowed to see the reference' do
- expect(field.to_graphql.resolve(type_instance, {}, context)).not_to include(issue_path(issue))
+ expect(field.resolve(type_instance, {}, context)).not_to include(issue_path(issue))
end
it 'shows the reference to users that are allowed to see it' do
context = GraphQL::Query::Context.new(query: query, values: { current_user: project.first_owner }, object: nil)
type_instance = type_class.authorized_new(note, context)
- expect(field.to_graphql.resolve(type_instance, {}, context)).to include(issue_path(issue))
+ expect(field.resolve(type_instance, {}, context)).to include(issue_path(issue))
end
end
end
diff --git a/spec/lib/gitlab/graphql/mount_mutation_spec.rb b/spec/lib/gitlab/graphql/mount_mutation_spec.rb
index fe25e923506..09fd9eac714 100644
--- a/spec/lib/gitlab/graphql/mount_mutation_spec.rb
+++ b/spec/lib/gitlab/graphql/mount_mutation_spec.rb
@@ -17,7 +17,7 @@ RSpec.describe Gitlab::Graphql::MountMutation do
f.mount_mutation(mutation)
end
- mutation_type.get_field('testMutation').to_graphql
+ mutation_type.get_field('testMutation')
end
it 'mounts a mutation' do
@@ -31,7 +31,7 @@ RSpec.describe Gitlab::Graphql::MountMutation do
f.mount_aliased_mutation('MyAlias', mutation)
end
- mutation_type.get_field('myAlias').to_graphql
+ mutation_type.get_field('myAlias')
end
it 'mounts a mutation' do
@@ -43,11 +43,11 @@ RSpec.describe Gitlab::Graphql::MountMutation do
end
it 'has a correct type' do
- expect(field.type.name).to eq('MyAliasPayload')
+ expect(field.type.to_type_signature).to eq('MyAliasPayload')
end
it 'has a correct input argument' do
- expect(field.arguments['input'].type.unwrap.name).to eq('MyAliasInput')
+ expect(field.arguments['input'].type.unwrap.to_type_signature).to eq('MyAliasInput')
end
end
diff --git a/spec/lib/gitlab/harbor/client_spec.rb b/spec/lib/gitlab/harbor/client_spec.rb
new file mode 100644
index 00000000000..bc5b593370a
--- /dev/null
+++ b/spec/lib/gitlab/harbor/client_spec.rb
@@ -0,0 +1,28 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Harbor::Client do
+ let(:harbor_integration) { build(:harbor_integration) }
+
+ subject(:client) { described_class.new(harbor_integration) }
+
+ describe '#ping' do
+ let!(:harbor_ping_request) { stub_harbor_request("https://demo.goharbor.io/api/v2.0/ping") }
+
+ it "calls api/v2.0/ping successfully" do
+ expect(client.ping).to eq(success: true)
+ end
+ end
+
+ private
+
+ def stub_harbor_request(url, body: {}, status: 200, headers: {})
+ stub_request(:get, url)
+ .to_return(
+ status: status,
+ headers: { 'Content-Type' => 'application/json' }.merge(headers),
+ body: body.to_json
+ )
+ end
+end
diff --git a/spec/lib/gitlab/health_checks/db_check_spec.rb b/spec/lib/gitlab/health_checks/db_check_spec.rb
index 60ebc596a0f..09b2650eae8 100644
--- a/spec/lib/gitlab/health_checks/db_check_spec.rb
+++ b/spec/lib/gitlab/health_checks/db_check_spec.rb
@@ -4,5 +4,20 @@ require 'spec_helper'
require_relative './simple_check_shared'
RSpec.describe Gitlab::HealthChecks::DbCheck do
- include_examples 'simple_check', 'db_ping', 'Db', '1'
+ include_examples 'simple_check', 'db_ping', 'Db', Gitlab::Database.database_base_models.size
+
+ context 'with multiple databases' do
+ subject { described_class.readiness }
+
+ before do
+ allow(Gitlab::Database).to receive(:database_base_models)
+ .and_return({ main: ApplicationRecord, ci: Ci::ApplicationRecord }.with_indifferent_access)
+ end
+
+ it 'checks multiple databases' do
+ expect(ApplicationRecord.connection).to receive(:select_value).with('SELECT 1').and_call_original
+ expect(Ci::ApplicationRecord.connection).to receive(:select_value).with('SELECT 1').and_call_original
+ expect(subject).to have_attributes(success: true)
+ end
+ end
end
diff --git a/spec/lib/gitlab/highlight_spec.rb b/spec/lib/gitlab/highlight_spec.rb
index 1f06019c929..65d8c59fea7 100644
--- a/spec/lib/gitlab/highlight_spec.rb
+++ b/spec/lib/gitlab/highlight_spec.rb
@@ -53,10 +53,6 @@ RSpec.describe Gitlab::Highlight do
stub_config(extra: { 'maximum_text_highlight_size_kilobytes' => 0.0001 } ) # 1.024 bytes
end
- it 'increments the metric for oversized files' do
- expect { result }.to change { over_highlight_size_limit('file size: 0.0001') }.by(1)
- end
-
it 'returns plain version for long content' do
expect(result).to eq(%[<span id="LC1" class="line" lang="">(make-pathname :defaults name</span>\n<span id="LC2" class="line" lang="">:type "assem")</span>])
end
@@ -126,79 +122,29 @@ RSpec.describe Gitlab::Highlight do
end
context 'timeout' do
- subject { described_class.new('file.name', 'Contents') }
+ subject(:highlight) { described_class.new('file.rb', 'begin', language: 'ruby').highlight('Content') }
it 'utilizes timeout for web' do
expect(Timeout).to receive(:timeout).with(described_class::TIMEOUT_FOREGROUND).and_call_original
- subject.highlight("Content")
+ highlight
end
- it 'utilizes longer timeout for sidekiq' do
- allow(Gitlab::Runtime).to receive(:sidekiq?).and_return(true)
- expect(Timeout).to receive(:timeout).with(described_class::TIMEOUT_BACKGROUND).and_call_original
+ it 'falls back to plaintext on timeout' do
+ allow(Gitlab::ErrorTracking).to receive(:track_and_raise_for_dev_exception)
+ expect(Timeout).to receive(:timeout).and_raise(Timeout::Error)
- subject.highlight("Content")
- end
- end
+ expect(Rouge::Lexers::PlainText).to receive(:lex).and_call_original
- describe 'highlight timeouts' do
- let(:result) { described_class.highlight(file_name, content, language: "ruby") }
-
- context 'when there is an attempt' do
- it "increments the attempt counter with a defined language" do
- expect { result }.to change { highlight_attempt_total("ruby") }
- end
-
- it "increments the attempt counter with an undefined language" do
- expect do
- described_class.highlight(file_name, content)
- end.to change { highlight_attempt_total("undefined") }
- end
+ highlight
end
- context 'when there is a timeout error while highlighting' do
- before do
- allow(Timeout).to receive(:timeout).twice.and_raise(Timeout::Error)
- # This is done twice because it's rescued first and then
- # calls the original exception
- end
-
- it "increments the foreground counter if it's in the foreground" do
- expect { result }
- .to raise_error(Timeout::Error)
- .and change { highlight_timeout_total('foreground') }.by(1)
- .and not_change { highlight_timeout_total('background') }
- end
-
- it "increments the background counter if it's in the background" do
- allow(Gitlab::Runtime).to receive(:sidekiq?).and_return(true)
+ it 'utilizes longer timeout for sidekiq' do
+ allow(Gitlab::Runtime).to receive(:sidekiq?).and_return(true)
+ expect(Timeout).to receive(:timeout).with(described_class::TIMEOUT_BACKGROUND).and_call_original
- expect { result }
- .to raise_error(Timeout::Error)
- .and change { highlight_timeout_total('background') }.by(1)
- .and not_change { highlight_timeout_total('foreground') }
- end
+ highlight
end
end
end
-
- def highlight_timeout_total(source)
- Gitlab::Metrics
- .counter(:highlight_timeout, 'Counts the times highlights have timed out')
- .get(source: source)
- end
-
- def highlight_attempt_total(source)
- Gitlab::Metrics
- .counter(:file_highlighting_attempt, 'Counts the times highlighting has been attempted on a file')
- .get(source: source)
- end
-
- def over_highlight_size_limit(source)
- Gitlab::Metrics
- .counter(:over_highlight_size_limit,
- 'Count the times text has been over the highlight size limit')
- .get(source: source)
- end
end
diff --git a/spec/lib/gitlab/hook_data/issue_builder_spec.rb b/spec/lib/gitlab/hook_data/issue_builder_spec.rb
index 039b4c19522..b9490306410 100644
--- a/spec/lib/gitlab/hook_data/issue_builder_spec.rb
+++ b/spec/lib/gitlab/hook_data/issue_builder_spec.rb
@@ -63,5 +63,13 @@ RSpec.describe Gitlab::HookData::IssueBuilder do
.to eq("test![Issue_Image](#{Settings.gitlab.url}/#{expected_path})")
end
end
+
+ context 'for incident' do
+ let_it_be(:issue) { create(:incident, :with_escalation_status) }
+
+ it 'includes additional attr' do
+ expect(data).to include(:escalation_status)
+ end
+ end
end
end
diff --git a/spec/lib/gitlab/import_export/all_models.yml b/spec/lib/gitlab/import_export/all_models.yml
index ce13f405459..29a19e4cafd 100644
--- a/spec/lib/gitlab/import_export/all_models.yml
+++ b/spec/lib/gitlab/import_export/all_models.yml
@@ -34,6 +34,7 @@ issues:
- issuable_severity
- issuable_sla
- issue_assignees
+- search_data
- closed_by
- epic_issue
- epic
@@ -54,6 +55,7 @@ issues:
- status_page_published_incident
- namespace
- note_authors
+- user_note_authors
- issue_email_participants
- test_reports
- requirement
@@ -199,6 +201,7 @@ merge_requests:
- user_mentions
- system_note_metadata
- note_authors
+- user_note_authors
- cleanup_schedule
- compliance_violations
external_pull_requests:
@@ -392,6 +395,7 @@ project:
- mattermost_slash_commands_integration
- shimo_integration
- slack_slash_commands_integration
+- harbor_integration
- irker_integration
- packagist_integration
- pivotaltracker_integration
@@ -607,6 +611,7 @@ project:
- sync_events
- secure_files
- security_trainings
+- vulnerability_reads
award_emoji:
- awardable
- user
@@ -627,6 +632,8 @@ issuable_severity:
issue_assignees:
- issue
- assignee
+search_data:
+- issue
merge_request_assignees:
- merge_request
- assignee
@@ -771,6 +778,7 @@ epic:
- resource_state_events
- user_mentions
- note_authors
+- user_note_authors
- boards_epic_user_preferences
- epic_board_positions
epic_issue:
diff --git a/spec/lib/gitlab/import_export/base/relation_object_saver_spec.rb b/spec/lib/gitlab/import_export/base/relation_object_saver_spec.rb
new file mode 100644
index 00000000000..7c84b9604a6
--- /dev/null
+++ b/spec/lib/gitlab/import_export/base/relation_object_saver_spec.rb
@@ -0,0 +1,132 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::ImportExport::Base::RelationObjectSaver do
+ let(:project) { create(:project) }
+ let(:relation_object) { build(:issue, project: project) }
+ let(:relation_definition) { {} }
+ let(:importable) { project }
+ let(:relation_key) { 'issues' }
+
+ subject(:saver) do
+ described_class.new(
+ relation_object: relation_object,
+ relation_key: relation_key,
+ relation_definition: relation_definition,
+ importable: importable
+ )
+ end
+
+ describe '#save' do
+ before do
+ expect(relation_object).to receive(:save!).and_call_original
+ end
+
+ it 'saves relation object' do
+ expect { saver.execute }.to change(project.issues, :count).by(1)
+ end
+
+ context 'when subrelation is present' do
+ let(:notes) { build_list(:note, 6, project: project, importing: true) }
+ let(:relation_object) { build(:issue, project: project, notes: notes) }
+ let(:relation_definition) { { 'notes' => {} } }
+
+ it 'saves relation object with subrelations' do
+ expect(relation_object.notes).to receive(:<<).and_call_original
+
+ saver.execute
+
+ issue = project.issues.last
+ expect(issue.notes.count).to eq(6)
+ end
+ end
+
+ context 'when subrelation is not a collection' do
+ let(:sentry_issue) { build(:sentry_issue, importing: true) }
+ let(:relation_object) { build(:issue, project: project, sentry_issue: sentry_issue) }
+ let(:relation_definition) { { 'sentry_issue' => {} } }
+
+ it 'saves subrelation as part of the relation object itself' do
+ expect(relation_object.notes).not_to receive(:<<)
+
+ saver.execute
+
+ issue = project.issues.last
+ expect(issue.sentry_issue.persisted?).to eq(true)
+ end
+ end
+
+ context 'when subrelation collection count is small' do
+ let(:notes) { build_list(:note, 2, project: project, importing: true) }
+ let(:relation_object) { build(:issue, project: project, notes: notes) }
+ let(:relation_definition) { { 'notes' => {} } }
+
+ it 'saves subrelation as part of the relation object itself' do
+ expect(relation_object.notes).not_to receive(:<<)
+
+ saver.execute
+
+ issue = project.issues.last
+ expect(issue.notes.count).to eq(2)
+ end
+ end
+
+ context 'when some subrelations are invalid' do
+ let(:notes) { build_list(:note, 5, project: project, importing: true) }
+ let(:invalid_note) { build(:note) }
+ let(:relation_object) { build(:issue, project: project, notes: notes + [invalid_note]) }
+ let(:relation_definition) { { 'notes' => {} } }
+
+ it 'saves valid subrelations and logs invalid subrelation' do
+ expect(relation_object.notes).to receive(:<<).and_call_original
+ expect(Gitlab::Import::Logger)
+ .to receive(:info)
+ .with(
+ message: '[Project/Group Import] Invalid subrelation',
+ project_id: project.id,
+ relation_key: 'issues',
+ error_messages: "Noteable can't be blank and Project does not match noteable project"
+ )
+
+ saver.execute
+
+ issue = project.issues.last
+ import_failure = project.import_failures.last
+
+ expect(issue.notes.count).to eq(5)
+ expect(import_failure.source).to eq('RelationObjectSaver#save!')
+ expect(import_failure.exception_message).to eq("Noteable can't be blank and Project does not match noteable project")
+ end
+
+ context 'when importable is group' do
+ let(:relation_key) { 'labels' }
+ let(:relation_definition) { { 'priorities' => {} } }
+ let(:importable) { create(:group) }
+ let(:valid_priorities) { build_list(:label_priority, 5, importing: true) }
+ let(:invalid_priority) { build(:label_priority, priority: -1) }
+ let(:relation_object) { build(:group_label, group: importable, title: 'test', priorities: valid_priorities + [invalid_priority]) }
+
+ it 'logs invalid subrelation for a group' do
+ expect(Gitlab::Import::Logger)
+ .to receive(:info)
+ .with(
+ message: '[Project/Group Import] Invalid subrelation',
+ group_id: importable.id,
+ relation_key: 'labels',
+ error_messages: 'Priority must be greater than or equal to 0'
+ )
+
+ saver.execute
+
+ label = importable.labels.last
+ import_failure = importable.import_failures.last
+
+ expect(label.priorities.count).to eq(5)
+ expect(import_failure.source).to eq('RelationObjectSaver#save!')
+ expect(import_failure.exception_message).to eq('Priority must be greater than or equal to 0')
+ end
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/import_export/command_line_util_spec.rb b/spec/lib/gitlab/import_export/command_line_util_spec.rb
index 738a76d3360..f5913da08ba 100644
--- a/spec/lib/gitlab/import_export/command_line_util_spec.rb
+++ b/spec/lib/gitlab/import_export/command_line_util_spec.rb
@@ -17,6 +17,9 @@ RSpec.describe Gitlab::ImportExport::CommandLineUtil do
def initialize
@shared = Gitlab::ImportExport::Shared.new(nil)
end
+
+ # Make the included methods public for testing
+ public :download_or_copy_upload, :download
end.new
end
@@ -38,6 +41,156 @@ RSpec.describe Gitlab::ImportExport::CommandLineUtil do
expect(file_permissions("#{path}/uploads")).to eq(0755) # originally 555
end
+ describe '#download_or_copy_upload' do
+ let(:upload) { instance_double(Upload, local?: local) }
+ let(:uploader) { instance_double(ImportExportUploader, path: :path, url: :url, upload: upload) }
+ let(:upload_path) { '/some/path' }
+
+ context 'when the upload is local' do
+ let(:local) { true }
+
+ it 'copies the file' do
+ expect(subject).to receive(:copy_files).with(:path, upload_path)
+
+ subject.download_or_copy_upload(uploader, upload_path)
+ end
+ end
+
+ context 'when the upload is remote' do
+ let(:local) { false }
+
+ it 'downloads the file' do
+ expect(subject).to receive(:download).with(:url, upload_path, size_limit: nil)
+
+ subject.download_or_copy_upload(uploader, upload_path)
+ end
+ end
+ end
+
+ describe '#download' do
+ let(:content) { File.open('spec/fixtures/rails_sample.tif') }
+
+ context 'a non-localhost uri' do
+ before do
+ stub_request(:get, url)
+ .to_return(
+ status: status,
+ body: content
+ )
+ end
+
+ let(:url) { 'https://gitlab.com/file' }
+
+ context 'with ok status code' do
+ let(:status) { HTTP::Status::OK }
+
+ it 'gets the contents' do
+ Tempfile.create('test') do |file|
+ subject.download(url, file.path)
+ expect(file.read).to eq(File.open('spec/fixtures/rails_sample.tif').read)
+ end
+ end
+
+ it 'streams the contents via Gitlab::HTTP' do
+ expect(Gitlab::HTTP).to receive(:get).with(url, hash_including(stream_body: true))
+
+ Tempfile.create('test') do |file|
+ subject.download(url, file.path)
+ end
+ end
+
+ it 'does not get the content over the size_limit' do
+ Tempfile.create('test') do |file|
+ subject.download(url, file.path, size_limit: 300.kilobytes)
+ expect(file.read).to eq('')
+ end
+ end
+
+ it 'gets the content within the size_limit' do
+ Tempfile.create('test') do |file|
+ subject.download(url, file.path, size_limit: 400.kilobytes)
+ expect(file.read).to eq(File.open('spec/fixtures/rails_sample.tif').read)
+ end
+ end
+ end
+
+ %w[MOVED_PERMANENTLY FOUND TEMPORARY_REDIRECT].each do |code|
+ context "with a redirect status code #{code}" do
+ let(:status) { HTTP::Status.const_get(code, false) }
+
+ it 'logs the redirect' do
+ expect(Gitlab::Import::Logger).to receive(:warn)
+
+ Tempfile.create('test') do |file|
+ subject.download(url, file.path)
+ end
+ end
+ end
+ end
+
+ %w[ACCEPTED UNAUTHORIZED BAD_REQUEST].each do |code|
+ context "with an invalid status code #{code}" do
+ let(:status) { HTTP::Status.const_get(code, false) }
+
+ it 'throws an error' do
+ Tempfile.create('test') do |file|
+ expect { subject.download(url, file.path) }.to raise_error(Gitlab::ImportExport::Error)
+ end
+ end
+ end
+ end
+ end
+
+ context 'a localhost uri' do
+ include StubRequests
+
+ let(:status) { HTTP::Status::OK }
+ let(:url) { "#{host}/foo/bar" }
+ let(:host) { 'http://localhost:8081' }
+
+ before do
+ # Note: the hostname gets changed to an ip address due to dns_rebind_protection
+ stub_dns(url, ip_address: '127.0.0.1')
+ stub_request(:get, 'http://127.0.0.1:8081/foo/bar')
+ .to_return(
+ status: status,
+ body: content
+ )
+ end
+
+ it 'throws a blocked url error' do
+ Tempfile.create('test') do |file|
+ expect { subject.download(url, file.path) }.to raise_error((Gitlab::HTTP::BlockedUrlError))
+ end
+ end
+
+ context 'for object_storage uri' do
+ let(:enabled_object_storage_setting) do
+ {
+ 'object_store' =>
+ {
+ 'enabled' => true,
+ 'connection' => {
+ 'endpoint' => host
+ }
+ }
+ }
+ end
+
+ before do
+ allow(Settings).to receive(:external_diffs).and_return(enabled_object_storage_setting)
+ end
+
+ it 'gets the content' do
+ Tempfile.create('test') do |file|
+ subject.download(url, file.path)
+ expect(file.read).to eq(File.open('spec/fixtures/rails_sample.tif').read)
+ end
+ end
+ end
+ end
+ end
+
describe '#gzip' do
it 'compresses specified file' do
tempfile = Tempfile.new('test', path)
diff --git a/spec/lib/gitlab/import_export/file_importer_spec.rb b/spec/lib/gitlab/import_export/file_importer_spec.rb
index ed4436b7257..7b27f7183b0 100644
--- a/spec/lib/gitlab/import_export/file_importer_spec.rb
+++ b/spec/lib/gitlab/import_export/file_importer_spec.rb
@@ -72,6 +72,25 @@ RSpec.describe Gitlab::ImportExport::FileImporter do
expect(shared.export_path).to include('test/abcd')
end
+ context 'when the import file is not remote' do
+ include AfterNextHelpers
+
+ it 'downloads the file from a remote object storage' do
+ import_export_upload = build(:import_export_upload)
+ project = build( :project, import_export_upload: import_export_upload)
+
+ expect_next(described_class)
+ .to receive(:download_or_copy_upload)
+ .with(
+ import_export_upload.import_file,
+ kind_of(String),
+ size_limit: ::Import::GitlabProjects::RemoteFileValidator::FILE_SIZE_LIMIT
+ )
+
+ described_class.import(importable: project, archive_file: nil, shared: shared)
+ end
+ end
+
context 'when the import file is remote' do
include AfterNextHelpers
@@ -82,7 +101,11 @@ RSpec.describe Gitlab::ImportExport::FileImporter do
expect_next(described_class)
.to receive(:download)
- .with(file_url, kind_of(String))
+ .with(
+ file_url,
+ kind_of(String),
+ size_limit: ::Import::GitlabProjects::RemoteFileValidator::FILE_SIZE_LIMIT
+ )
described_class.import(importable: project, archive_file: nil, shared: shared)
end
diff --git a/spec/lib/gitlab/import_export/group/object_builder_spec.rb b/spec/lib/gitlab/import_export/group/object_builder_spec.rb
index 028bd5463a1..09f40199b31 100644
--- a/spec/lib/gitlab/import_export/group/object_builder_spec.rb
+++ b/spec/lib/gitlab/import_export/group/object_builder_spec.rb
@@ -51,16 +51,4 @@ RSpec.describe Gitlab::ImportExport::Group::ObjectBuilder do
expect(milestone.persisted?).to be true
end
end
-
- describe '#initialize' do
- context 'when attributes contain description as empty string' do
- let(:attributes) { base_attributes.merge('description' => '') }
-
- it 'converts empty string to nil' do
- builder = described_class.new(Label, attributes)
-
- expect(builder.send(:attributes)).to include({ 'description' => nil })
- end
- end
- end
end
diff --git a/spec/lib/gitlab/import_export/group/tree_restorer_spec.rb b/spec/lib/gitlab/import_export/group/tree_restorer_spec.rb
index b67d42d1b71..9b01005c2e9 100644
--- a/spec/lib/gitlab/import_export/group/tree_restorer_spec.rb
+++ b/spec/lib/gitlab/import_export/group/tree_restorer_spec.rb
@@ -5,116 +5,117 @@ require 'spec_helper'
RSpec.describe Gitlab::ImportExport::Group::TreeRestorer do
include ImportExport::CommonUtil
- describe 'restore group tree' do
- before_all do
- # Using an admin for import, so we can check assignment of existing members
- user = create(:admin, email: 'root@gitlabexample.com')
- create(:user, email: 'adriene.mcclure@gitlabexample.com')
- create(:user, email: 'gwendolyn_robel@gitlabexample.com')
+ shared_examples 'group restoration' do
+ describe 'restore group tree' do
+ before_all do
+ # Using an admin for import, so we can check assignment of existing members
+ user = create(:admin, email: 'root@gitlabexample.com')
+ create(:user, email: 'adriene.mcclure@gitlabexample.com')
+ create(:user, email: 'gwendolyn_robel@gitlabexample.com')
- RSpec::Mocks.with_temporary_scope do
- @group = create(:group, name: 'group', path: 'group')
- @shared = Gitlab::ImportExport::Shared.new(@group)
+ RSpec::Mocks.with_temporary_scope do
+ @group = create(:group, name: 'group', path: 'group')
+ @shared = Gitlab::ImportExport::Shared.new(@group)
- setup_import_export_config('group_exports/complex')
+ setup_import_export_config('group_exports/complex')
- group_tree_restorer = described_class.new(user: user, shared: @shared, group: @group)
+ group_tree_restorer = described_class.new(user: user, shared: @shared, group: @group)
- expect(group_tree_restorer.restore).to be_truthy
- expect(group_tree_restorer.groups_mapping).not_to be_empty
+ expect(group_tree_restorer.restore).to be_truthy
+ expect(group_tree_restorer.groups_mapping).not_to be_empty
+ end
end
- end
-
- it 'has the group description' do
- expect(Group.find_by_path('group').description).to eq('Group Description')
- end
- it 'has group labels' do
- expect(@group.labels.count).to eq(10)
- end
+ it 'has the group description' do
+ expect(Group.find_by_path('group').description).to eq('Group Description')
+ end
- context 'issue boards' do
- it 'has issue boards' do
- expect(@group.boards.count).to eq(1)
+ it 'has group labels' do
+ expect(@group.labels.count).to eq(10)
end
- it 'has board label lists' do
- lists = @group.boards.find_by(name: 'first board').lists
+ context 'issue boards' do
+ it 'has issue boards' do
+ expect(@group.boards.count).to eq(1)
+ end
+
+ it 'has board label lists' do
+ lists = @group.boards.find_by(name: 'first board').lists
- expect(lists.count).to eq(3)
- expect(lists.first.label.title).to eq('TSL')
- expect(lists.second.label.title).to eq('Sosync')
+ expect(lists.count).to eq(3)
+ expect(lists.first.label.title).to eq('TSL')
+ expect(lists.second.label.title).to eq('Sosync')
+ end
end
- end
- it 'has badges' do
- expect(@group.badges.count).to eq(1)
- end
+ it 'has badges' do
+ expect(@group.badges.count).to eq(1)
+ end
- it 'has milestones' do
- expect(@group.milestones.count).to eq(5)
- end
+ it 'has milestones' do
+ expect(@group.milestones.count).to eq(5)
+ end
- it 'has group children' do
- expect(@group.children.count).to eq(2)
- end
+ it 'has group children' do
+ expect(@group.children.count).to eq(2)
+ end
- it 'has group members' do
- expect(@group.members.map(&:user).map(&:email)).to contain_exactly(
- 'root@gitlabexample.com',
- 'adriene.mcclure@gitlabexample.com',
- 'gwendolyn_robel@gitlabexample.com'
- )
+ it 'has group members' do
+ expect(@group.members.map(&:user).map(&:email)).to contain_exactly(
+ 'root@gitlabexample.com',
+ 'adriene.mcclure@gitlabexample.com',
+ 'gwendolyn_robel@gitlabexample.com'
+ )
+ end
end
- end
- context 'child with no parent' do
- let(:user) { create(:user) }
- let(:group) { create(:group) }
- let(:shared) { Gitlab::ImportExport::Shared.new(group) }
- let(:group_tree_restorer) { described_class.new(user: user, shared: shared, group: group) }
+ context 'child with no parent' do
+ let(:user) { create(:user) }
+ let(:group) { create(:group) }
+ let(:shared) { Gitlab::ImportExport::Shared.new(group) }
+ let(:group_tree_restorer) { described_class.new(user: user, shared: shared, group: group) }
- before do
- setup_import_export_config('group_exports/child_with_no_parent')
- end
+ before do
+ setup_import_export_config('group_exports/child_with_no_parent')
+ end
- it 'captures import failures when a child group does not have a valid parent_id' do
- group_tree_restorer.restore
+ it 'captures import failures when a child group does not have a valid parent_id' do
+ group_tree_restorer.restore
- expect(group.import_failures.first.exception_message).to eq('Parent group not found')
+ expect(group.import_failures.first.exception_message).to eq('Parent group not found')
+ end
end
- end
- context 'when child group creation fails' do
- let(:user) { create(:user) }
- let(:group) { create(:group) }
- let(:shared) { Gitlab::ImportExport::Shared.new(group) }
- let(:group_tree_restorer) { described_class.new(user: user, shared: shared, group: group) }
+ context 'when child group creation fails' do
+ let(:user) { create(:user) }
+ let(:group) { create(:group) }
+ let(:shared) { Gitlab::ImportExport::Shared.new(group) }
+ let(:group_tree_restorer) { described_class.new(user: user, shared: shared, group: group) }
- before do
- setup_import_export_config('group_exports/child_short_name')
- end
+ before do
+ setup_import_export_config('group_exports/child_short_name')
+ end
- it 'captures import failure' do
- exception_message = 'Validation failed: Group URL is too short (minimum is 2 characters)'
+ it 'captures import failure' do
+ exception_message = 'Validation failed: Group URL is too short (minimum is 2 characters)'
- group_tree_restorer.restore
+ group_tree_restorer.restore
- expect(group.import_failures.first.exception_message).to eq(exception_message)
+ expect(group.import_failures.first.exception_message).to eq(exception_message)
+ end
end
- end
- context 'excluded attributes' do
- let!(:source_user) { create(:user, id: 123) }
- let!(:importer_user) { create(:user) }
- let(:group) { create(:group, name: 'user-inputed-name', path: 'user-inputed-path') }
- let(:shared) { Gitlab::ImportExport::Shared.new(group) }
- let(:group_tree_restorer) { described_class.new(user: importer_user, shared: shared, group: group) }
- let(:exported_file) { File.join(shared.export_path, 'tree/groups/4352.json') }
- let(:group_json) { Gitlab::Json.parse(IO.read(exported_file)) }
-
- shared_examples 'excluded attributes' do
- excluded_attributes = %w[
+ context 'excluded attributes' do
+ let!(:source_user) { create(:user, id: 123) }
+ let!(:importer_user) { create(:user) }
+ let(:group) { create(:group, name: 'user-inputed-name', path: 'user-inputed-path') }
+ let(:shared) { Gitlab::ImportExport::Shared.new(group) }
+ let(:group_tree_restorer) { described_class.new(user: importer_user, shared: shared, group: group) }
+ let(:exported_file) { File.join(shared.export_path, 'tree/groups/4352.json') }
+ let(:group_json) { Gitlab::Json.parse(IO.read(exported_file)) }
+
+ shared_examples 'excluded attributes' do
+ excluded_attributes = %w[
id
parent_id
owner_id
@@ -125,80 +126,97 @@ RSpec.describe Gitlab::ImportExport::Group::TreeRestorer do
saml_discovery_token
]
- before do
- group.add_owner(importer_user)
+ before do
+ group.add_owner(importer_user)
- setup_import_export_config('group_exports/complex')
+ setup_import_export_config('group_exports/complex')
- expect(File.exist?(exported_file)).to be_truthy
+ expect(File.exist?(exported_file)).to be_truthy
- group_tree_restorer.restore
- group.reload
- end
+ group_tree_restorer.restore
+ group.reload
+ end
- it 'does not import root group name' do
- expect(group.name).to eq('user-inputed-name')
- end
+ it 'does not import root group name' do
+ expect(group.name).to eq('user-inputed-name')
+ end
- it 'does not import root group path' do
- expect(group.path).to eq('user-inputed-path')
- end
+ it 'does not import root group path' do
+ expect(group.path).to eq('user-inputed-path')
+ end
- excluded_attributes.each do |excluded_attribute|
- it 'does not allow override of excluded attributes' do
- unless group.public_send(excluded_attribute).nil?
- expect(group_json[excluded_attribute]).not_to eq(group.public_send(excluded_attribute))
+ excluded_attributes.each do |excluded_attribute|
+ it 'does not allow override of excluded attributes' do
+ unless group.public_send(excluded_attribute).nil?
+ expect(group_json[excluded_attribute]).not_to eq(group.public_send(excluded_attribute))
+ end
end
end
end
- end
- include_examples 'excluded attributes'
- end
+ include_examples 'excluded attributes'
+ end
- context 'group.json file access check' do
- let(:user) { create(:user) }
- let!(:group) { create(:group, name: 'group2', path: 'group2') }
- let(:shared) { Gitlab::ImportExport::Shared.new(group) }
- let(:group_tree_restorer) { described_class.new(user: user, shared: shared, group: group) }
+ context 'group.json file access check' do
+ let(:user) { create(:user) }
+ let!(:group) { create(:group, name: 'group2', path: 'group2') }
+ let(:shared) { Gitlab::ImportExport::Shared.new(group) }
+ let(:group_tree_restorer) { described_class.new(user: user, shared: shared, group: group) }
- it 'does not read a symlink' do
- Dir.mktmpdir do |tmpdir|
- FileUtils.mkdir_p(File.join(tmpdir, 'tree', 'groups'))
- setup_symlink(tmpdir, 'tree/groups/_all.ndjson')
+ it 'does not read a symlink' do
+ Dir.mktmpdir do |tmpdir|
+ FileUtils.mkdir_p(File.join(tmpdir, 'tree', 'groups'))
+ setup_symlink(tmpdir, 'tree/groups/_all.ndjson')
- allow(shared).to receive(:export_path).and_return(tmpdir)
+ allow(shared).to receive(:export_path).and_return(tmpdir)
- expect(group_tree_restorer.restore).to eq(false)
- expect(shared.errors).to include('Incorrect JSON format')
+ expect(group_tree_restorer.restore).to eq(false)
+ expect(shared.errors).to include('Incorrect JSON format')
+ end
end
end
- end
- context 'group visibility levels' do
- let(:user) { create(:user) }
- let(:shared) { Gitlab::ImportExport::Shared.new(group) }
- let(:group_tree_restorer) { described_class.new(user: user, shared: shared, group: group) }
+ context 'group visibility levels' do
+ let(:user) { create(:user) }
+ let(:shared) { Gitlab::ImportExport::Shared.new(group) }
+ let(:group_tree_restorer) { described_class.new(user: user, shared: shared, group: group) }
- before do
- setup_import_export_config(filepath)
+ before do
+ setup_import_export_config(filepath)
- group_tree_restorer.restore
- end
+ group_tree_restorer.restore
+ end
- shared_examples 'with visibility level' do |visibility_level, expected_visibilities|
- context "when visibility level is #{visibility_level}" do
- let(:group) { create(:group, visibility_level) }
- let(:filepath) { "group_exports/visibility_levels/#{visibility_level}" }
+ shared_examples 'with visibility level' do |visibility_level, expected_visibilities|
+ context "when visibility level is #{visibility_level}" do
+ let(:group) { create(:group, visibility_level) }
+ let(:filepath) { "group_exports/visibility_levels/#{visibility_level}" }
- it "imports all subgroups as #{visibility_level}" do
- expect(group.children.map(&:visibility_level)).to match_array(expected_visibilities)
+ it "imports all subgroups as #{visibility_level}" do
+ expect(group.children.map(&:visibility_level)).to match_array(expected_visibilities)
+ end
end
end
+
+ include_examples 'with visibility level', :public, [20, 10, 0]
+ include_examples 'with visibility level', :private, [0, 0, 0]
+ include_examples 'with visibility level', :internal, [10, 10, 0]
+ end
+ end
+
+ context 'when import_relation_object_persistence feature flag is enabled' do
+ before do
+ stub_feature_flags(import_relation_object_persistence: true)
+ end
+
+ include_examples 'group restoration'
+ end
+
+ context 'when import_relation_object_persistence feature flag is disabled' do
+ before do
+ stub_feature_flags(import_relation_object_persistence: false)
end
- include_examples 'with visibility level', :public, [20, 10, 0]
- include_examples 'with visibility level', :private, [0, 0, 0]
- include_examples 'with visibility level', :internal, [10, 10, 0]
+ include_examples 'group restoration'
end
end
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 352af18c822..ba1cccf87ce 100644
--- a/spec/lib/gitlab/import_export/json/streaming_serializer_spec.rb
+++ b/spec/lib/gitlab/import_export/json/streaming_serializer_spec.rb
@@ -158,26 +158,10 @@ RSpec.describe Gitlab::ImportExport::Json::StreamingSerializer do
end
describe 'load balancing' do
- context 'when feature flag load_balancing_for_export_workers is enabled' do
- before do
- stub_feature_flags(load_balancing_for_export_workers: true)
- end
-
- it 'reads from replica' do
- expect(Gitlab::Database::LoadBalancing::Session.current).to receive(:use_replicas_for_read_queries).and_call_original
-
- subject.execute
- end
- end
+ it 'reads from replica' do
+ expect(Gitlab::Database::LoadBalancing::Session.current).to receive(:use_replicas_for_read_queries).and_call_original
- context 'when feature flag load_balancing_for_export_workers is disabled' do
- it 'reads from primary' do
- stub_feature_flags(load_balancing_for_export_workers: false)
-
- expect(Gitlab::Database::LoadBalancing::Session.current).not_to receive(:use_replicas_for_read_queries)
-
- subject.execute
- end
+ subject.execute
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 ffbbf9326ec..240d86077c4 100644
--- a/spec/lib/gitlab/import_export/project/relation_factory_spec.rb
+++ b/spec/lib/gitlab/import_export/project/relation_factory_spec.rb
@@ -401,4 +401,20 @@ RSpec.describe Gitlab::ImportExport::Project::RelationFactory, :use_clean_rails_
expect(created_object.value).to be_nil
end
end
+
+ context 'event object' do
+ let(:relation_sym) { :events }
+ let(:relation_hash) do
+ {
+ 'project_id' => project.id,
+ 'author_id' => admin.id,
+ 'action' => 'created',
+ 'target_type' => 'Issue'
+ }
+ end
+
+ it 'has preloaded project' do
+ expect(created_object.project).to equal(project)
+ end
+ end
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 8884722254d..fdf8260c058 100644
--- a/spec/lib/gitlab/import_export/project/tree_restorer_spec.rb
+++ b/spec/lib/gitlab/import_export/project/tree_restorer_spec.rb
@@ -1058,13 +1058,35 @@ RSpec.describe Gitlab::ImportExport::Project::TreeRestorer do
end
end
- context 'enable ndjson import' do
- it_behaves_like 'project tree restorer work properly', :legacy_reader, true
+ context 'when import_relation_object_persistence feature flag is enabled' do
+ before do
+ stub_feature_flags(import_relation_object_persistence: true)
+ end
+
+ context 'enable ndjson import' do
+ it_behaves_like 'project tree restorer work properly', :legacy_reader, true
+
+ it_behaves_like 'project tree restorer work properly', :ndjson_reader, true
+ end
- it_behaves_like 'project tree restorer work properly', :ndjson_reader, true
+ context 'disable ndjson import' do
+ it_behaves_like 'project tree restorer work properly', :legacy_reader, false
+ end
end
- context 'disable ndjson import' do
- it_behaves_like 'project tree restorer work properly', :legacy_reader, false
+ context 'when import_relation_object_persistence feature flag is disabled' do
+ before do
+ stub_feature_flags(import_relation_object_persistence: false)
+ end
+
+ context 'enable ndjson import' do
+ it_behaves_like 'project tree restorer work properly', :legacy_reader, true
+
+ it_behaves_like 'project tree restorer work properly', :ndjson_reader, true
+ end
+
+ context 'disable ndjson import' do
+ it_behaves_like 'project tree restorer work properly', :legacy_reader, false
+ 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 f019883a91e..e06fcb0cd3f 100644
--- a/spec/lib/gitlab/import_export/safe_model_attributes.yml
+++ b/spec/lib/gitlab/import_export/safe_model_attributes.yml
@@ -857,6 +857,7 @@ Epic:
- health_status
- external_key
- confidential
+ - color
EpicIssue:
- id
- relative_position
diff --git a/spec/lib/gitlab/integrations/sti_type_spec.rb b/spec/lib/gitlab/integrations/sti_type_spec.rb
deleted file mode 100644
index 1205b74dc9d..00000000000
--- a/spec/lib/gitlab/integrations/sti_type_spec.rb
+++ /dev/null
@@ -1,114 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Gitlab::Integrations::StiType do
- let(:types) { ['AsanaService', 'Integrations::Asana', Integrations::Asana] }
-
- describe '#serialize' do
- context 'SQL SELECT' do
- let(:expected_sql) do
- <<~SQL.strip
- SELECT "integrations".* FROM "integrations" WHERE "integrations"."type" = 'AsanaService'
- SQL
- end
-
- it 'forms SQL SELECT statements correctly' do
- sql_statements = types.map do |type|
- Integration.where(type: type).to_sql
- end
-
- expect(sql_statements).to all(eq(expected_sql))
- end
- end
-
- context 'SQL CREATE' do
- let(:expected_sql) do
- <<~SQL.strip
- INSERT INTO "integrations" ("type") VALUES ('AsanaService')
- SQL
- end
-
- it 'forms SQL CREATE statements correctly' do
- sql_statements = types.map do |type|
- record = ActiveRecord::QueryRecorder.new { Integration.insert({ type: type }) }
- record.log.first
- end
-
- expect(sql_statements).to all(include(expected_sql))
- end
- end
-
- context 'SQL UPDATE' do
- let(:expected_sql) do
- <<~SQL.strip
- UPDATE "integrations" SET "type" = 'AsanaService'
- SQL
- end
-
- let_it_be(:integration) { create(:integration) }
-
- it 'forms SQL UPDATE statements correctly' do
- sql_statements = types.map do |type|
- record = ActiveRecord::QueryRecorder.new { integration.update_column(:type, type) }
- record.log.first
- end
-
- expect(sql_statements).to all(include(expected_sql))
- end
- end
-
- context 'SQL DELETE' do
- let(:expected_sql) do
- <<~SQL.strip
- DELETE FROM "integrations" WHERE "integrations"."type" = 'AsanaService'
- SQL
- end
-
- it 'forms SQL DELETE statements correctly' do
- sql_statements = types.map do |type|
- record = ActiveRecord::QueryRecorder.new { Integration.delete_by(type: type) }
- record.log.first
- end
-
- expect(sql_statements).to all(match(expected_sql))
- end
- end
- end
-
- describe '#deserialize' do
- specify 'it deserializes type correctly', :aggregate_failures do
- types.each do |type|
- service = create(:integration, type: type)
-
- expect(service.type).to eq('AsanaService')
- end
- end
- end
-
- describe '#cast' do
- it 'casts type as model correctly', :aggregate_failures do
- create(:integration, type: 'AsanaService')
-
- types.each do |type|
- expect(Integration.find_by(type: type)).to be_kind_of(Integrations::Asana)
- end
- end
- end
-
- describe '#changed?' do
- it 'detects changes correctly', :aggregate_failures do
- service = create(:integration, type: 'AsanaService')
-
- types.each do |type|
- service.type = type
-
- expect(service).not_to be_changed
- end
-
- service.type = 'NewType'
-
- expect(service).to be_changed
- end
- end
-end
diff --git a/spec/lib/gitlab/json_cache_spec.rb b/spec/lib/gitlab/json_cache_spec.rb
index 7899d01b475..d7d28a94cfe 100644
--- a/spec/lib/gitlab/json_cache_spec.rb
+++ b/spec/lib/gitlab/json_cache_spec.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+# rubocop:disable Style/RedundantFetchBlock
require 'spec_helper'
@@ -8,7 +9,7 @@ RSpec.describe Gitlab::JsonCache do
let(:backend) { double('backend').as_null_object }
let(:namespace) { 'geo' }
let(:key) { 'foo' }
- let(:expanded_key) { "#{namespace}:#{key}:#{Gitlab::VERSION}:#{Rails.version}" }
+ let(:expanded_key) { "#{namespace}:#{key}:#{Gitlab.revision}" }
subject(:cache) { described_class.new(namespace: namespace, backend: backend) }
@@ -35,69 +36,63 @@ RSpec.describe Gitlab::JsonCache do
end
describe '#cache_key' do
- context 'when namespace is not defined' do
- context 'when cache_key_with_version is true' do
- it 'expands out the key with GitLab, and Rails versions' do
- cache = described_class.new(cache_key_with_version: true)
+ using RSpec::Parameterized::TableSyntax
- cache_key = cache.cache_key(key)
-
- expect(cache_key).to eq("#{key}:#{Gitlab::VERSION}:#{Rails.version}")
- end
- end
+ where(:namespace, :cache_key_strategy, :expanded_key) do
+ nil | :revision | "#{key}:#{Gitlab.revision}"
+ nil | :version | "#{key}:#{Gitlab::VERSION}:#{Rails.version}"
+ namespace | :revision | "#{namespace}:#{key}:#{Gitlab.revision}"
+ namespace | :version | "#{namespace}:#{key}:#{Gitlab::VERSION}:#{Rails.version}"
+ end
- context 'when cache_key_with_version is false' do
- it 'returns the key' do
- cache = described_class.new(namespace: nil, cache_key_with_version: false)
+ with_them do
+ let(:cache) { described_class.new(namespace: namespace, cache_key_strategy: cache_key_strategy) }
- cache_key = cache.cache_key(key)
+ subject { cache.cache_key(key) }
- expect(cache_key).to eq(key)
- end
- end
+ it { is_expected.to eq expanded_key }
end
- context 'when namespace is nil' do
- context 'when cache_key_with_version is true' do
- it 'expands out the key with GitLab, and Rails versions' do
- cache = described_class.new(cache_key_with_version: true)
-
- cache_key = cache.cache_key(key)
+ context 'when cache_key_strategy is unknown' do
+ let(:cache) { described_class.new(namespace: namespace, cache_key_strategy: 'unknown') }
- expect(cache_key).to eq("#{key}:#{Gitlab::VERSION}:#{Rails.version}")
- end
+ it 'raises KeyError' do
+ expect { cache.cache_key('key') }.to raise_error(KeyError)
end
+ end
+ end
- context 'when cache_key_with_version is false' do
- it 'returns the key' do
- cache = described_class.new(namespace: nil, cache_key_with_version: false)
+ describe '#namespace' do
+ it 'defaults to nil' do
+ cache = described_class.new
+ expect(cache.namespace).to be_nil
+ end
+ end
- cache_key = cache.cache_key(key)
+ describe '#strategy_key_component' do
+ subject { cache.strategy_key_component }
- expect(cache_key).to eq(key)
- end
- end
+ it 'defaults to Gitlab.revision' do
+ expect(described_class.new.strategy_key_component).to eq Gitlab.revision
end
- context 'when namespace is set' do
- context 'when cache_key_with_version is true' do
- it 'expands out the key with namespace and Rails version' do
- cache = described_class.new(namespace: namespace, cache_key_with_version: true)
+ context 'when cache_key_strategy is :revision' do
+ let(:cache) { described_class.new(cache_key_strategy: :revision) }
- cache_key = cache.cache_key(key)
+ it { is_expected.to eq Gitlab.revision }
+ end
- expect(cache_key).to eq("#{namespace}:#{key}:#{Gitlab::VERSION}:#{Rails.version}")
- end
- end
+ context 'when cache_key_strategy is :version' do
+ let(:cache) { described_class.new(cache_key_strategy: :version) }
- context 'when cache_key_with_version is false' do
- it 'expands out the key with namespace' do
- cache = described_class.new(namespace: namespace, cache_key_with_version: false)
+ it { is_expected.to eq [Gitlab::VERSION, Rails.version] }
+ end
- cache_key = cache.cache_key(key)
+ context 'when cache_key_strategy is invalid' do
+ let(:cache) { described_class.new(cache_key_strategy: 'unknown') }
- expect(cache_key).to eq("#{namespace}:#{key}")
- end
+ it 'raises KeyError' do
+ expect { subject }.to raise_error(KeyError)
end
end
end
@@ -553,3 +548,4 @@ RSpec.describe Gitlab::JsonCache do
end
end
end
+# rubocop:enable Style/RedundantFetchBlock
diff --git a/spec/lib/gitlab/kubernetes/kubeconfig/template_spec.rb b/spec/lib/gitlab/kubernetes/kubeconfig/template_spec.rb
index 057c4373329..7d1f1aea291 100644
--- a/spec/lib/gitlab/kubernetes/kubeconfig/template_spec.rb
+++ b/spec/lib/gitlab/kubernetes/kubeconfig/template_spec.rb
@@ -39,6 +39,51 @@ RSpec.describe Gitlab::Kubernetes::Kubeconfig::Template do
it { is_expected.to eq(YAML.dump(template.to_h.deep_stringify_keys)) }
end
+ describe '#merge_yaml' do
+ it 'appends to the configuration and overwrites the current context' do
+ template.add_cluster(name: 'hello-cluster', url: 'hello-url')
+ template.add_context(name: 'hello-context', cluster: 'hello-cluster', user: 'hello-user')
+ template.add_user(name: 'hello-user', token: 'hello-token')
+ ca_pem = Base64.strict_encode64('a certificate')
+ template.merge_yaml(<<~YAML)
+ apiVersion: v1
+ kind: Config
+ clusters:
+ - name: 'gitlab-deploy'
+ cluster:
+ server: url
+ certificate-authority-data: #{ca_pem.inspect}
+ contexts:
+ - name: gitlab-deploy
+ context:
+ cluster: gitlab-deploy
+ namespace: namespace
+ user: gitlab-deploy
+ current-context: gitlab-deploy
+ users:
+ - name: 'gitlab-deploy'
+ user: { token: token }
+ YAML
+ expect(template.to_h).to eq({
+ apiVersion: 'v1',
+ kind: 'Config',
+ clusters: [
+ { name: 'hello-cluster', cluster: { server: 'hello-url' } },
+ { name: 'gitlab-deploy', cluster: { server: 'url', 'certificate-authority-data': ca_pem } }
+ ],
+ contexts: [
+ { name: 'hello-context', context: { cluster: 'hello-cluster', user: 'hello-user' } },
+ { name: 'gitlab-deploy', context: { cluster: 'gitlab-deploy', namespace: 'namespace', user: 'gitlab-deploy' } }
+ ],
+ users: [
+ { name: 'hello-user', user: { token: 'hello-token' } },
+ { name: 'gitlab-deploy', user: { token: 'token' } }
+ ],
+ 'current-context': 'gitlab-deploy'
+ })
+ end
+ end
+
describe 'adding entries' do
let(:entry) { instance_double(entry_class, to_h: attributes) }
let(:attributes) do
diff --git a/spec/lib/gitlab/mail_room/authenticator_spec.rb b/spec/lib/gitlab/mail_room/authenticator_spec.rb
index 44120902661..2e62ed2d386 100644
--- a/spec/lib/gitlab/mail_room/authenticator_spec.rb
+++ b/spec/lib/gitlab/mail_room/authenticator_spec.rb
@@ -44,7 +44,7 @@ RSpec.describe Gitlab::MailRoom::Authenticator do
describe '#verify_api_request' do
let(:incoming_email_secret) { SecureRandom.hex(16) }
let(:service_desk_email_secret) { SecureRandom.hex(16) }
- let(:payload) { { iss: described_class::INTERNAL_API_REQUEST_JWT_ISSUER, iat: (Time.current - 5.minutes + 1.second).to_i } }
+ let(:payload) { { iss: Gitlab::MailRoom::INTERNAL_API_REQUEST_JWT_ISSUER, iat: (Time.current - 5.minutes + 1.second).to_i } }
before do
allow(described_class).to receive(:secret).with(:incoming_email).and_return(incoming_email_secret)
@@ -54,7 +54,7 @@ RSpec.describe Gitlab::MailRoom::Authenticator do
context 'verify a valid token' do
it 'returns the decoded payload' do
encoded_token = JWT.encode(payload, incoming_email_secret, 'HS256')
- headers = { described_class::INTERNAL_API_REQUEST_HEADER => encoded_token }
+ headers = { Gitlab::MailRoom::INTERNAL_API_REQUEST_HEADER => encoded_token }
expect(described_class.verify_api_request(headers, 'incoming_email')[0]).to match a_hash_including(
"iss" => "gitlab-mailroom",
@@ -62,7 +62,7 @@ RSpec.describe Gitlab::MailRoom::Authenticator do
)
encoded_token = JWT.encode(payload, service_desk_email_secret, 'HS256')
- headers = { described_class::INTERNAL_API_REQUEST_HEADER => encoded_token }
+ headers = { Gitlab::MailRoom::INTERNAL_API_REQUEST_HEADER => encoded_token }
expect(described_class.verify_api_request(headers, 'service_desk_email')[0]).to match a_hash_including(
"iss" => "gitlab-mailroom",
@@ -74,7 +74,7 @@ RSpec.describe Gitlab::MailRoom::Authenticator do
context 'verify an invalid token' do
it 'returns false' do
encoded_token = JWT.encode(payload, 'wrong secret', 'HS256')
- headers = { described_class::INTERNAL_API_REQUEST_HEADER => encoded_token }
+ headers = { Gitlab::MailRoom::INTERNAL_API_REQUEST_HEADER => encoded_token }
expect(described_class.verify_api_request(headers, 'incoming_email')).to eq(false)
end
@@ -83,7 +83,7 @@ RSpec.describe Gitlab::MailRoom::Authenticator do
context 'verify a valid token but wrong mailbox type' do
it 'returns false' do
encoded_token = JWT.encode(payload, incoming_email_secret, 'HS256')
- headers = { described_class::INTERNAL_API_REQUEST_HEADER => encoded_token }
+ headers = { Gitlab::MailRoom::INTERNAL_API_REQUEST_HEADER => encoded_token }
expect(described_class.verify_api_request(headers, 'service_desk_email')).to eq(false)
end
@@ -94,18 +94,18 @@ RSpec.describe Gitlab::MailRoom::Authenticator do
it 'returns false' do
encoded_token = JWT.encode(payload, incoming_email_secret, 'HS256')
- headers = { described_class::INTERNAL_API_REQUEST_HEADER => encoded_token }
+ headers = { Gitlab::MailRoom::INTERNAL_API_REQUEST_HEADER => encoded_token }
expect(described_class.verify_api_request(headers, 'incoming_email')).to eq(false)
end
end
context 'verify a valid token but expired' do
- let(:payload) { { iss: described_class::INTERNAL_API_REQUEST_JWT_ISSUER, iat: (Time.current - 5.minutes - 1.second).to_i } }
+ let(:payload) { { iss: Gitlab::MailRoom::INTERNAL_API_REQUEST_JWT_ISSUER, iat: (Time.current - 5.minutes - 1.second).to_i } }
it 'returns false' do
encoded_token = JWT.encode(payload, incoming_email_secret, 'HS256')
- headers = { described_class::INTERNAL_API_REQUEST_HEADER => encoded_token }
+ headers = { Gitlab::MailRoom::INTERNAL_API_REQUEST_HEADER => encoded_token }
expect(described_class.verify_api_request(headers, 'incoming_email')).to eq(false)
end
@@ -125,7 +125,7 @@ RSpec.describe Gitlab::MailRoom::Authenticator do
it 'returns false' do
encoded_token = JWT.encode(payload, incoming_email_secret, 'HS256')
- headers = { described_class::INTERNAL_API_REQUEST_HEADER => encoded_token }
+ headers = { Gitlab::MailRoom::INTERNAL_API_REQUEST_HEADER => encoded_token }
expect(described_class.verify_api_request(headers, 'incoming_email')).to eq(false)
end
@@ -133,7 +133,7 @@ RSpec.describe Gitlab::MailRoom::Authenticator do
context 'verify headers for a non-existing mailbox type' do
it 'returns false' do
- headers = { described_class::INTERNAL_API_REQUEST_HEADER => 'something' }
+ headers = { Gitlab::MailRoom::INTERNAL_API_REQUEST_HEADER => 'something' }
expect(described_class.verify_api_request(headers, 'invalid_mailbox_type')).to eq(false)
end
diff --git a/spec/lib/gitlab/mail_room/mail_room_spec.rb b/spec/lib/gitlab/mail_room/mail_room_spec.rb
index a4fcf71a012..12fb12ebd87 100644
--- a/spec/lib/gitlab/mail_room/mail_room_spec.rb
+++ b/spec/lib/gitlab/mail_room/mail_room_spec.rb
@@ -4,16 +4,30 @@ require 'spec_helper'
RSpec.describe Gitlab::MailRoom do
let(:default_port) { 143 }
+ let(:log_path) { Rails.root.join('log', 'mail_room_json.log').to_s }
+
+ let(:fake_redis_queues) do
+ double(
+ url: "localhost",
+ db: 99,
+ sentinels: [{ host: 'localhost', port: 1234 }],
+ sentinels?: true
+ )
+ end
+
let(:yml_config) do
{
enabled: true,
+ host: 'mail.example.com',
address: 'address@example.com',
+ user: 'user@example.com',
+ password: 'password',
port: default_port,
ssl: false,
start_tls: false,
mailbox: 'inbox',
idle_timeout: 60,
- log_path: Rails.root.join('log', 'mail_room_json.log').to_s,
+ log_path: log_path,
expunge_deleted: false
}
end
@@ -30,6 +44,7 @@ RSpec.describe Gitlab::MailRoom do
end
before do
+ allow(Gitlab::Redis::Queues).to receive(:new).and_return(fake_redis_queues)
allow(described_class).to receive(:load_yaml).and_return(configs)
described_class.instance_variable_set(:@enabled_configs, nil)
end
@@ -39,6 +54,8 @@ RSpec.describe Gitlab::MailRoom do
end
describe '#enabled_configs' do
+ let(:first_value) { described_class.enabled_configs.each_value.first }
+
context 'when both email and address is set' do
it 'returns email configs' do
expect(described_class.enabled_configs.size).to eq(2)
@@ -76,7 +93,7 @@ RSpec.describe Gitlab::MailRoom do
let(:custom_config) { { enabled: true, address: 'address@example.com' } }
it 'overwrites missing values with the default' do
- expect(described_class.enabled_configs.each_value.first[:port]).to eq(Gitlab::MailRoom::DEFAULT_CONFIG[:port])
+ expect(first_value[:port]).to eq(Gitlab::MailRoom::DEFAULT_CONFIG[:port])
end
end
@@ -85,23 +102,24 @@ RSpec.describe Gitlab::MailRoom do
it 'returns only encoming_email' do
expect(described_class.enabled_configs.size).to eq(1)
- expect(described_class.enabled_configs.each_value.first[:worker]).to eq('EmailReceiverWorker')
+ expect(first_value[:worker]).to eq('EmailReceiverWorker')
end
end
describe 'setting up redis settings' do
- let(:fake_redis_queues) { double(url: "localhost", db: 99, sentinels: "yes, them", sentinels?: true) }
-
- before do
- allow(Gitlab::Redis::Queues).to receive(:new).and_return(fake_redis_queues)
+ it 'sets delivery method to Sidekiq by default' do
+ config = first_value
+ expect(config).to include(
+ delivery_method: 'sidekiq'
+ )
end
it 'sets redis config' do
- config = described_class.enabled_configs.each_value.first
+ config = first_value
expect(config).to include(
redis_url: 'localhost',
redis_db: 99,
- sentinels: 'yes, them'
+ sentinels: [{ host: 'localhost', port: 1234 }]
)
end
end
@@ -111,7 +129,7 @@ RSpec.describe Gitlab::MailRoom do
let(:custom_config) { { log_path: 'tiny_log.log' } }
it 'expands the log path to an absolute value' do
- new_path = Pathname.new(described_class.enabled_configs.each_value.first[:log_path])
+ new_path = Pathname.new(first_value[:log_path])
expect(new_path.absolute?).to be_truthy
end
end
@@ -120,7 +138,7 @@ RSpec.describe Gitlab::MailRoom do
let(:custom_config) { { log_path: '/dev/null' } }
it 'leaves the path as-is' do
- expect(described_class.enabled_configs.each_value.first[:log_path]).to eq '/dev/null'
+ expect(first_value[:log_path]).to eq '/dev/null'
end
end
end
@@ -164,4 +182,148 @@ RSpec.describe Gitlab::MailRoom do
end
end
end
+
+ describe 'config/mail_room.yml' do
+ let(:mail_room_template) { ERB.new(File.read(Rails.root.join("./config/mail_room.yml"))).result }
+ let(:mail_room_yml) { YAML.safe_load(mail_room_template, permitted_classes: [Symbol]) }
+
+ shared_examples 'renders mail-specific config file correctly' do
+ it 'renders mail room config file correctly' do
+ expect(mail_room_yml[:mailboxes]).to be_an(Array)
+ expect(mail_room_yml[:mailboxes].length).to eq(2)
+
+ expect(mail_room_yml[:mailboxes]).to all(
+ match(
+ a_hash_including(
+ host: 'mail.example.com',
+ port: default_port,
+ ssl: false,
+ start_tls: false,
+ email: 'user@example.com',
+ password: 'password',
+ idle_timeout: 60,
+ logger: {
+ log_path: log_path
+ },
+ name: 'inbox',
+
+ delete_after_delivery: true,
+ expunge_deleted: false
+ )
+ )
+ )
+ end
+ end
+
+ shared_examples 'renders arbitration options correctly' do
+ it 'renders arbitration options correctly' do
+ expect(mail_room_yml[:mailboxes]).to be_an(Array)
+ expect(mail_room_yml[:mailboxes].length).to eq(2)
+ expect(mail_room_yml[:mailboxes]).to all(
+ match(
+ a_hash_including(
+ arbitration_method: "redis",
+ arbitration_options: {
+ redis_url: "localhost",
+ namespace: "mail_room:gitlab",
+ sentinels: [{ host: "localhost", port: 1234 }]
+ }
+ )
+ )
+ )
+ end
+ end
+
+ shared_examples 'renders the sidekiq delivery method and options correctly' do
+ it 'renders the sidekiq delivery method and options correctly' do
+ expect(mail_room_yml[:mailboxes]).to be_an(Array)
+ expect(mail_room_yml[:mailboxes].length).to eq(2)
+
+ expect(mail_room_yml[:mailboxes][0]).to match(
+ a_hash_including(
+ delivery_method: 'sidekiq',
+ delivery_options: {
+ redis_url: "localhost",
+ redis_db: 99,
+ namespace: "resque:gitlab",
+ queue: "email_receiver",
+ worker: "EmailReceiverWorker",
+ sentinels: [{ host: "localhost", port: 1234 }]
+ }
+ )
+ )
+ expect(mail_room_yml[:mailboxes][1]).to match(
+ a_hash_including(
+ delivery_method: 'sidekiq',
+ delivery_options: {
+ redis_url: "localhost",
+ redis_db: 99,
+ namespace: "resque:gitlab",
+ queue: "service_desk_email_receiver",
+ worker: "ServiceDeskEmailReceiverWorker",
+ sentinels: [{ host: "localhost", port: 1234 }]
+ }
+ )
+ )
+ end
+ end
+
+ context 'when delivery_method is implicit' do
+ it_behaves_like 'renders mail-specific config file correctly'
+ it_behaves_like 'renders arbitration options correctly'
+ it_behaves_like 'renders the sidekiq delivery method and options correctly'
+ end
+
+ context 'when delivery_method is explicitly sidekiq' do
+ let(:custom_config) { { delivery_method: 'sidekiq' } }
+
+ it_behaves_like 'renders mail-specific config file correctly'
+ it_behaves_like 'renders arbitration options correctly'
+ it_behaves_like 'renders the sidekiq delivery method and options correctly'
+ end
+
+ context 'when delivery_method is webhook (internally postback in mail_room)' do
+ let(:custom_config) do
+ {
+ delivery_method: 'webhook',
+ gitlab_url: 'http://gitlab.example',
+ secret_file: '/path/to/secret/file'
+ }
+ end
+
+ it_behaves_like 'renders mail-specific config file correctly'
+ it_behaves_like 'renders arbitration options correctly'
+
+ it 'renders the webhook (postback) delivery method and options correctly' do
+ expect(mail_room_yml[:mailboxes]).to be_an(Array)
+ expect(mail_room_yml[:mailboxes].length).to eq(2)
+
+ expect(mail_room_yml[:mailboxes][0]).to match(
+ a_hash_including(
+ delivery_method: 'postback',
+ delivery_options: {
+ delivery_url: "http://gitlab.example/api/v4/internal/mail_room/incoming_email",
+ jwt_auth_header: Gitlab::MailRoom::INTERNAL_API_REQUEST_HEADER,
+ jwt_issuer: Gitlab::MailRoom::INTERNAL_API_REQUEST_JWT_ISSUER,
+ jwt_algorithm: 'HS256',
+ jwt_secret_path: '/path/to/secret/file'
+ }
+ )
+ )
+
+ expect(mail_room_yml[:mailboxes][1]).to match(
+ a_hash_including(
+ delivery_method: 'postback',
+ delivery_options: {
+ delivery_url: "http://gitlab.example/api/v4/internal/mail_room/service_desk_email",
+ jwt_auth_header: Gitlab::MailRoom::INTERNAL_API_REQUEST_HEADER,
+ jwt_issuer: Gitlab::MailRoom::INTERNAL_API_REQUEST_JWT_ISSUER,
+ jwt_algorithm: 'HS256',
+ jwt_secret_path: '/path/to/secret/file'
+ }
+ )
+ )
+ end
+ end
+ end
end
diff --git a/spec/lib/gitlab/merge_requests/commit_message_generator_spec.rb b/spec/lib/gitlab/merge_requests/commit_message_generator_spec.rb
index 2407b497249..ad528dca81a 100644
--- a/spec/lib/gitlab/merge_requests/commit_message_generator_spec.rb
+++ b/spec/lib/gitlab/merge_requests/commit_message_generator_spec.rb
@@ -403,6 +403,90 @@ RSpec.describe Gitlab::MergeRequests::CommitMessageGenerator do
end
end
+ context 'when project has commit template with all_commits' do
+ let(message_template_name) { "All commits:\n%{all_commits}" }
+
+ it 'returns all commit messages' do
+ expect(result_message).to eq <<~MSG.rstrip
+ All commits:
+ * Feature added
+
+ Signed-off-by: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
+ MSG
+ end
+
+ context 'with 2 commits' do
+ let(:source_branch) { 'fix' }
+
+ it 'returns both messages' do
+ expect(result_message).to eq <<~MSG.rstrip
+ All commits:
+ * Test file for directories with a leading dot
+
+ * JS fix
+
+ Signed-off-by: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
+ MSG
+ end
+ end
+
+ context 'with over 100 commits' do
+ let(:source_branch) { 'signed-commits' }
+
+ it 'returns first 100 commits skipping merge commit' do
+ expected_message = <<~MSG
+ All commits:
+ * Multiple signatures commit
+
+ * Add conflicting file
+
+ * Add conflicting file
+
+ MSG
+ expected_message += (5..100).to_a.reverse
+ .map { |n| "* Unrelated signed commit #{n} to exceed page size of endpoint\n\n" }
+ .join.rstrip
+ expect(result_message).to eq expected_message
+ end
+ end
+
+ context 'when branch has no unmerged commits' do
+ let(:source_branch) { 'v1.1.0' }
+
+ it 'is an empty string' do
+ expect(result_message).to eq "All commits:\n"
+ end
+ end
+
+ context 'when branch has commit with message over 100kb' do
+ let(:source_branch) { 'add_commit_with_5mb_subject' }
+
+ it 'skips commit body' do
+ expect(result_message).to eq <<~MSG.rstrip
+ All commits:
+ * Commit with 5MB text subject
+
+ -- Skipped commit body exceeding 100KiB in size.
+
+ * Correct test_env.rb path for adding branch
+
+ * Add file with a _flattable_ path
+
+
+ (cherry picked from commit ce369011c189f62c815f5971d096b26759bab0d1)
+
+ * Add file larger than 1 mb
+
+ In order to test Max File Size push rule we need a file larger than 1 MB
+
+ * LFS tracks "*.lfs" through .gitattributes
+
+ * Update README.md to include `Usage in testing and development`
+ MSG
+ end
+ end
+ end
+
context 'user' do
subject { described_class.new(merge_request: merge_request, current_user: nil) }
@@ -466,6 +550,7 @@ RSpec.describe Gitlab::MergeRequests::CommitMessageGenerator do
approved_by:%{approved_by}
merged_by:%{merged_by}
co_authored_by:%{co_authored_by}
+ all_commits:%{all_commits}
MSG
it 'uses custom template' do
@@ -486,6 +571,9 @@ RSpec.describe Gitlab::MergeRequests::CommitMessageGenerator do
approved_by:
merged_by:#{current_user.name} <#{current_user.commit_email_or_default}>
co_authored_by:Co-authored-by: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
+ all_commits:* Feature added
+
+ Signed-off-by: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
MSG
end
end
diff --git a/spec/lib/gitlab/merge_requests/mergeability/check_result_spec.rb b/spec/lib/gitlab/merge_requests/mergeability/check_result_spec.rb
index 4f437e57600..50cfa6b64ea 100644
--- a/spec/lib/gitlab/merge_requests/mergeability/check_result_spec.rb
+++ b/spec/lib/gitlab/merge_requests/mergeability/check_result_spec.rb
@@ -70,8 +70,8 @@ RSpec.describe Gitlab::MergeRequests::Mergeability::CheckResult do
let(:payload) { { test: 'test' } }
let(:hash) do
{
- status: status,
- payload: payload
+ 'status' => status,
+ 'payload' => payload
}
end
diff --git a/spec/lib/gitlab/merge_requests/mergeability/results_store_spec.rb b/spec/lib/gitlab/merge_requests/mergeability/results_store_spec.rb
index d376dcb5b18..ed11f8ea6bb 100644
--- a/spec/lib/gitlab/merge_requests/mergeability/results_store_spec.rb
+++ b/spec/lib/gitlab/merge_requests/mergeability/results_store_spec.rb
@@ -10,10 +10,22 @@ RSpec.describe Gitlab::MergeRequests::Mergeability::ResultsStore do
let(:merge_request) { double }
describe '#read' do
- it 'calls #retrieve on the interface' do
- expect(interface).to receive(:retrieve_check).with(merge_check: merge_check)
+ let(:result_hash) { { 'status' => 'success', 'payload' => {} } }
- results_store.read(merge_check: merge_check)
+ it 'calls #retrieve_check on the interface' do
+ expect(interface).to receive(:retrieve_check).with(merge_check: merge_check).and_return(result_hash)
+
+ cached_result = results_store.read(merge_check: merge_check)
+
+ expect(cached_result.status).to eq(result_hash['status'].to_sym)
+ expect(cached_result.payload).to eq(result_hash['payload'])
+ end
+
+ context 'when #retrieve_check returns nil' do
+ it 'returns nil' do
+ expect(interface).to receive(:retrieve_check).with(merge_check: merge_check).and_return(nil)
+ expect(results_store.read(merge_check: merge_check)).to be_nil
+ end
end
end
diff --git a/spec/lib/gitlab/metrics/dashboard/cache_spec.rb b/spec/lib/gitlab/metrics/dashboard/cache_spec.rb
index 9467d441ae1..8c2edc85c35 100644
--- a/spec/lib/gitlab/metrics/dashboard/cache_spec.rb
+++ b/spec/lib/gitlab/metrics/dashboard/cache_spec.rb
@@ -1,4 +1,5 @@
# frozen_string_literal: true
+# rubocop:disable Style/RedundantFetchBlock
require 'spec_helper'
@@ -84,3 +85,4 @@ RSpec.describe Gitlab::Metrics::Dashboard::Cache, :use_clean_rails_memory_store_
end
end
end
+# rubocop:enable Style/RedundantFetchBlock
diff --git a/spec/lib/gitlab/null_request_store_spec.rb b/spec/lib/gitlab/null_request_store_spec.rb
index f600af2e31f..66700313c9a 100644
--- a/spec/lib/gitlab/null_request_store_spec.rb
+++ b/spec/lib/gitlab/null_request_store_spec.rb
@@ -49,7 +49,7 @@ RSpec.describe Gitlab::NullRequestStore do
describe '#fetch' do
it 'returns the block result' do
- expect(null_store.fetch('key') { 'block result' }).to eq('block result')
+ expect(null_store.fetch('key') { 'block result' }).to eq('block result') # rubocop:disable Style/RedundantFetchBlock
end
end
diff --git a/spec/lib/gitlab/omniauth_initializer_spec.rb b/spec/lib/gitlab/omniauth_initializer_spec.rb
index 42ae5844b95..8b959cf787f 100644
--- a/spec/lib/gitlab/omniauth_initializer_spec.rb
+++ b/spec/lib/gitlab/omniauth_initializer_spec.rb
@@ -5,7 +5,161 @@ require 'spec_helper'
RSpec.describe Gitlab::OmniauthInitializer do
let(:devise_config) { class_double(Devise) }
- subject { described_class.new(devise_config) }
+ subject(:initializer) { described_class.new(devise_config) }
+
+ describe '.arguments_for' do
+ let(:devise_config) { nil }
+
+ let(:arguments) { initializer.send(:arguments_for, provider) }
+
+ context 'when there are no args at all' do
+ let(:provider) { { 'name' => 'unknown' } }
+
+ it 'returns an empty array' do
+ expect(arguments).to eq []
+ end
+ end
+
+ context 'when there is an app_id and an app_secret' do
+ let(:provider) { { 'name' => 'unknown', 'app_id' => 1, 'app_secret' => 2 } }
+
+ it 'includes both of them, in positional order' do
+ expect(arguments).to eq [1, 2]
+ end
+ end
+
+ context 'when there is an app_id and an app_secret, and an array of args' do
+ let(:provider) do
+ {
+ 'name' => 'unknown',
+ 'app_id' => 1,
+ 'app_secret' => 2,
+ 'args' => %w[one two three]
+ }
+ end
+
+ it 'concatenates the args on the end' do
+ expect(arguments).to eq [1, 2, 'one', 'two', 'three']
+ end
+ end
+
+ context 'when there is an app_id and an app_secret, and an array of args, and default values' do
+ let(:provider) do
+ {
+ 'name' => 'unknown',
+ 'app_id' => 1,
+ 'app_secret' => 2,
+ 'args' => %w[one two three]
+ }
+ end
+
+ before do
+ expect(described_class)
+ .to receive(:default_arguments_for).with('unknown')
+ .and_return({ default_arg: :some_value })
+ end
+
+ it 'concatenates the args on the end' do
+ expect(arguments)
+ .to eq [1, 2, 'one', 'two', 'three', { default_arg: :some_value }]
+ end
+ end
+
+ context 'when there is an app_id and an app_secret, and a hash of args' do
+ let(:provider) do
+ {
+ 'name' => 'unknown',
+ 'app_id' => 1,
+ 'app_secret' => 2,
+ 'args' => { 'foo' => 100, 'bar' => 200, 'nested' => { 'value' => 300 } }
+ }
+ end
+
+ it 'concatenates the args on the end' do
+ expect(arguments)
+ .to eq [1, 2, { foo: 100, bar: 200, nested: { value: 300 } }]
+ end
+ end
+
+ context 'when there is an app_id and an app_secret, and a hash of args, and default arguments' do
+ let(:provider) do
+ {
+ 'name' => 'unknown',
+ 'app_id' => 1,
+ 'app_secret' => 2,
+ 'args' => { 'foo' => 100, 'bar' => 200, 'nested' => { 'value' => 300 } }
+ }
+ end
+
+ before do
+ expect(described_class)
+ .to receive(:default_arguments_for).with('unknown')
+ .and_return({ default_arg: :some_value })
+ end
+
+ it 'concatenates the args on the end' do
+ expect(arguments)
+ .to eq [1, 2, { default_arg: :some_value, foo: 100, bar: 200, nested: { value: 300 } }]
+ end
+ end
+
+ context 'when there is an app_id and an app_secret, no args, and default values' do
+ let(:provider) do
+ {
+ 'name' => 'unknown',
+ 'app_id' => 1,
+ 'app_secret' => 2
+ }
+ end
+
+ before do
+ expect(described_class)
+ .to receive(:default_arguments_for).with('unknown')
+ .and_return({ default_arg: :some_value })
+ end
+
+ it 'concatenates the args on the end' do
+ expect(arguments)
+ .to eq [1, 2, { default_arg: :some_value }]
+ end
+ end
+
+ context 'when there are args, of an unsupported type' do
+ let(:provider) do
+ {
+ 'name' => 'unknown',
+ 'args' => 1
+ }
+ end
+
+ context 'when there are default arguments' do
+ before do
+ expect(described_class)
+ .to receive(:default_arguments_for).with('unknown')
+ .and_return({ default_arg: :some_value })
+ end
+
+ it 'tracks a configuration error' do
+ expect(::Gitlab::ErrorTracking)
+ .to receive(:track_and_raise_for_dev_exception)
+ .with(described_class::ConfigurationError, provider_name: 'unknown', arguments_type: 'Integer')
+
+ expect(arguments)
+ .to eq [{ default_arg: :some_value }]
+ end
+ end
+
+ context 'when there are no default arguments' do
+ it 'tracks a configuration error' do
+ expect(::Gitlab::ErrorTracking)
+ .to receive(:track_and_raise_for_dev_exception)
+ .with(described_class::ConfigurationError, provider_name: 'unknown', arguments_type: 'Integer')
+
+ expect(arguments).to be_empty
+ end
+ end
+ end
+ end
describe '#execute' do
it 'configures providers from array' do
@@ -105,11 +259,50 @@ RSpec.describe Gitlab::OmniauthInitializer do
it 'configures defaults for gitlab' do
conf = {
'name' => 'gitlab',
- "args" => {}
+ "args" => { 'client_options' => { 'site' => generate(:url) } }
}
expect(devise_config).to receive(:omniauth).with(
:gitlab,
+ client_options: { site: conf.dig('args', 'client_options', 'site') },
+ authorize_params: { gl_auth_type: 'login' }
+ )
+
+ subject.execute([conf])
+ end
+
+ it 'configures defaults for gitlab, when arguments are not provided' do
+ conf = { 'name' => 'gitlab' }
+
+ expect(devise_config).to receive(:omniauth).with(
+ :gitlab,
+ authorize_params: { gl_auth_type: 'login' }
+ )
+
+ subject.execute([conf])
+ end
+
+ it 'configures defaults for gitlab, when array arguments are provided' do
+ conf = { 'name' => 'gitlab', 'args' => ['a'] }
+
+ expect(devise_config).to receive(:omniauth).with(
+ :gitlab,
+ 'a',
+ authorize_params: { gl_auth_type: 'login' }
+ )
+
+ subject.execute([conf])
+ end
+
+ it 'tracks a configuration error if the arguments are neither a hash nor an array' do
+ conf = { 'name' => 'gitlab', 'args' => 17 }
+
+ expect(::Gitlab::ErrorTracking)
+ .to receive(:track_and_raise_for_dev_exception)
+ .with(described_class::ConfigurationError, provider_name: 'gitlab', arguments_type: 'Integer')
+
+ expect(devise_config).to receive(:omniauth).with(
+ :gitlab,
authorize_params: { gl_auth_type: 'login' }
)
diff --git a/spec/lib/gitlab/pages/settings_spec.rb b/spec/lib/gitlab/pages/settings_spec.rb
index 1a7c808d1bf..9cfcded6196 100644
--- a/spec/lib/gitlab/pages/settings_spec.rb
+++ b/spec/lib/gitlab/pages/settings_spec.rb
@@ -13,7 +13,7 @@ RSpec.describe Gitlab::Pages::Settings do
context 'when running under a web server outside of test mode' do
before do
allow(::Gitlab::Runtime).to receive(:test_suite?).and_return(false)
- allow(::Gitlab::Runtime).to receive(:web_server?).and_return(true)
+ allow(::Gitlab::Runtime).to receive(:puma?).and_return(true)
end
it 'logs a DiskAccessDenied error' do
diff --git a/spec/lib/gitlab/patch/action_cable_redis_listener_spec.rb b/spec/lib/gitlab/patch/action_cable_redis_listener_spec.rb
new file mode 100644
index 00000000000..14f556ff348
--- /dev/null
+++ b/spec/lib/gitlab/patch/action_cable_redis_listener_spec.rb
@@ -0,0 +1,28 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Patch::ActionCableRedisListener do
+ let(:adapter) { instance_double('ActionCable::SubscriptionAdapter::Redis') }
+ let(:connection) { instance_double('Redis') }
+ let(:listener) { ActionCable::SubscriptionAdapter::Redis::Listener.new(adapter, nil) }
+
+ before do
+ allow(Thread).to receive(:new).and_yield
+ allow(adapter).to receive(:redis_connection_for_subscriptions).and_return(connection)
+ end
+
+ it 'catches Redis connection errors and restarts Action Cable' do
+ expect(connection).to receive(:without_reconnect).and_raise Redis::ConnectionError
+ expect(ActionCable).to receive_message_chain(:server, :restart)
+
+ expect { listener.add_channel('test_channel', nil) }.not_to raise_error
+ end
+
+ it 're-raises other exceptions' do
+ expect(connection).to receive(:without_reconnect).and_raise StandardError
+ expect(ActionCable).not_to receive(:server)
+
+ expect { listener.add_channel('test_channel', nil) }.to raise_error(StandardError)
+ end
+end
diff --git a/spec/lib/gitlab/path_regex_spec.rb b/spec/lib/gitlab/path_regex_spec.rb
index f0ba0f0459d..9876387512b 100644
--- a/spec/lib/gitlab/path_regex_spec.rb
+++ b/spec/lib/gitlab/path_regex_spec.rb
@@ -549,10 +549,11 @@ RSpec.describe Gitlab::PathRegex do
it { is_expected.to match('gitlab-foss') }
it { is_expected.to match('gitlab_foss') }
it { is_expected.to match('gitlab-org/gitlab-foss') }
+ it { is_expected.to match('a/b/c/d/e') }
it { is_expected.to match('100px.com/100px.ruby') }
- it 'only matches at most one slash' do
- expect(subject.match('foo/bar/baz')[0]).to eq('foo/bar')
+ it 'does not match beyond 4 slashes' do
+ expect(subject.match('foo/bar/baz/buz/zip/zap/zoo')[0]).to eq('foo/bar/baz/buz/zip')
end
it 'does not match other non-word characters' do
diff --git a/spec/lib/gitlab/process_supervisor_spec.rb b/spec/lib/gitlab/process_supervisor_spec.rb
new file mode 100644
index 00000000000..60b127dadda
--- /dev/null
+++ b/spec/lib/gitlab/process_supervisor_spec.rb
@@ -0,0 +1,170 @@
+# frozen_string_literal: true
+
+require_relative '../../../lib/gitlab/process_supervisor'
+
+RSpec.describe Gitlab::ProcessSupervisor do
+ let(:health_check_interval_seconds) { 0.1 }
+ let(:check_terminate_interval_seconds) { 1 }
+ let(:forwarded_signals) { [] }
+ let(:process_ids) { [spawn_process, spawn_process] }
+
+ def spawn_process
+ Process.spawn('while true; do sleep 1; done').tap do |pid|
+ Process.detach(pid)
+ end
+ end
+
+ subject(:supervisor) do
+ described_class.new(
+ health_check_interval_seconds: health_check_interval_seconds,
+ check_terminate_interval_seconds: check_terminate_interval_seconds,
+ terminate_timeout_seconds: 1 + check_terminate_interval_seconds,
+ forwarded_signals: forwarded_signals
+ )
+ end
+
+ after do
+ process_ids.each do |pid|
+ Process.kill('KILL', pid)
+ rescue Errno::ESRCH
+ # Ignore if a process wasn't actually alive.
+ end
+ end
+
+ describe '#supervise' do
+ context 'while supervised processes are alive' do
+ it 'does not invoke callback' do
+ expect(Gitlab::ProcessManagement.all_alive?(process_ids)).to be(true)
+ pids_killed = []
+
+ supervisor.supervise(process_ids) do |dead_pids|
+ pids_killed = dead_pids
+ []
+ end
+
+ # Wait several times the poll frequency of the supervisor.
+ sleep health_check_interval_seconds * 10
+
+ expect(pids_killed).to be_empty
+ expect(Gitlab::ProcessManagement.all_alive?(process_ids)).to be(true)
+ end
+ end
+
+ context 'when a supervised process dies' do
+ it 'triggers callback with the dead PIDs and adds new PIDs to supervised PIDs' do
+ expect(Gitlab::ProcessManagement.all_alive?(process_ids)).to be(true)
+ pids_killed = []
+
+ supervisor.supervise(process_ids) do |dead_pids|
+ pids_killed = dead_pids
+ [42] # Fake starting a new process in place of the terminated one.
+ end
+
+ # Terminate the supervised process.
+ Process.kill('TERM', process_ids.first)
+
+ await_condition(sleep_sec: health_check_interval_seconds) do
+ pids_killed == [process_ids.first]
+ end
+
+ expect(Gitlab::ProcessManagement.process_alive?(process_ids.first)).to be(false)
+ expect(Gitlab::ProcessManagement.process_alive?(process_ids.last)).to be(true)
+ expect(supervisor.supervised_pids).to match_array([process_ids.last, 42])
+ end
+ end
+
+ context 'signal handling' do
+ before do
+ allow(supervisor).to receive(:sleep)
+ allow(Gitlab::ProcessManagement).to receive(:trap_signals)
+ allow(Gitlab::ProcessManagement).to receive(:all_alive?).and_return(false)
+ allow(Gitlab::ProcessManagement).to receive(:signal_processes).with(process_ids, anything)
+ end
+
+ context 'termination signals' do
+ context 'when TERM results in timely shutdown of processes' do
+ it 'forwards them to observed processes without waiting for grace period to expire' do
+ allow(Gitlab::ProcessManagement).to receive(:any_alive?).and_return(false)
+
+ expect(Gitlab::ProcessManagement).to receive(:trap_signals).ordered.with(%i(INT TERM)).and_yield(:TERM)
+ expect(Gitlab::ProcessManagement).to receive(:signal_processes).ordered.with(process_ids, :TERM)
+ expect(supervisor).not_to receive(:sleep).with(check_terminate_interval_seconds)
+
+ supervisor.supervise(process_ids) { [] }
+ end
+ end
+
+ context 'when TERM does not result in timely shutdown of processes' do
+ it 'issues a KILL signal after the grace period expires' do
+ expect(Gitlab::ProcessManagement).to receive(:trap_signals).with(%i(INT TERM)).and_yield(:TERM)
+ expect(Gitlab::ProcessManagement).to receive(:signal_processes).ordered.with(process_ids, :TERM)
+ expect(supervisor).to receive(:sleep).ordered.with(check_terminate_interval_seconds).at_least(:once)
+ expect(Gitlab::ProcessManagement).to receive(:signal_processes).ordered.with(process_ids, '-KILL')
+
+ supervisor.supervise(process_ids) { [] }
+ end
+ end
+ end
+
+ context 'forwarded signals' do
+ let(:forwarded_signals) { %i(USR1) }
+
+ it 'forwards given signals to the observed processes' do
+ expect(Gitlab::ProcessManagement).to receive(:trap_signals).with(%i(USR1)).and_yield(:USR1)
+ expect(Gitlab::ProcessManagement).to receive(:signal_processes).ordered.with(process_ids, :USR1)
+
+ supervisor.supervise(process_ids) { [] }
+ end
+ end
+ end
+ end
+
+ describe '#shutdown' do
+ context 'when supervisor is supervising processes' do
+ before do
+ supervisor.supervise(process_ids)
+ end
+
+ context 'when supervisor is alive' do
+ it 'signals TERM then KILL to all supervised processes' do
+ expect(Gitlab::ProcessManagement).to receive(:signal_processes).ordered.with(process_ids, :TERM)
+ expect(Gitlab::ProcessManagement).to receive(:signal_processes).ordered.with(process_ids, '-KILL')
+
+ supervisor.shutdown
+ end
+
+ it 'stops the supervisor' do
+ expect { supervisor.shutdown }.to change { supervisor.alive }.from(true).to(false)
+ end
+ end
+
+ context 'when supervisor has already shut down' do
+ before do
+ supervisor.shutdown
+ end
+
+ it 'does nothing' do
+ expect(supervisor.alive).to be(false)
+ expect(Gitlab::ProcessManagement).not_to receive(:signal_processes)
+
+ supervisor.shutdown
+ end
+ end
+ end
+
+ context 'when supervisor never started' do
+ it 'does nothing' do
+ expect(supervisor.alive).to be(false)
+ expect(Gitlab::ProcessManagement).not_to receive(:signal_processes)
+
+ supervisor.shutdown
+ end
+ end
+ end
+
+ def await_condition(timeout_sec: 5, sleep_sec: 0.1)
+ Timeout.timeout(timeout_sec) do
+ sleep sleep_sec until yield
+ end
+ end
+end
diff --git a/spec/lib/gitlab/profiler_spec.rb b/spec/lib/gitlab/profiler_spec.rb
index 5187c96b511..bfe1a588489 100644
--- a/spec/lib/gitlab/profiler_spec.rb
+++ b/spec/lib/gitlab/profiler_spec.rb
@@ -58,6 +58,30 @@ RSpec.describe Gitlab::Profiler do
described_class.profile('/', user: user, private_token: private_token)
end
+
+ context 'with sampling profiler' do
+ it 'generates sampling data' do
+ user = double(:user)
+ temp_data = Tempfile.new
+
+ expect(described_class).to receive(:with_user).with(user).and_call_original
+ described_class.profile('/', user: user, sampling_mode: true, profiler_options: { out: temp_data.path })
+
+ expect(File.stat(temp_data).size).to be > 0
+ File.unlink(temp_data)
+ end
+
+ it 'saves sampling data with a randomly-generated filename' do
+ user = double(:user)
+
+ expect(described_class).to receive(:with_user).with(user).and_call_original
+ result = described_class.profile('/', user: user, sampling_mode: true)
+
+ expect(result).to be_a(File)
+ expect(File.stat(result.path).size).to be > 0
+ File.unlink(result.path)
+ end
+ end
end
describe '.create_custom_logger' do
diff --git a/spec/lib/gitlab/project_authorizations_spec.rb b/spec/lib/gitlab/project_authorizations_spec.rb
index 7852470196b..640cf9be453 100644
--- a/spec/lib/gitlab/project_authorizations_spec.rb
+++ b/spec/lib/gitlab/project_authorizations_spec.rb
@@ -37,7 +37,7 @@ RSpec.describe Gitlab::ProjectAuthorizations do
it 'includes the correct access levels' do
mapping = map_access_levels(authorizations)
- expect(mapping[owned_project.id]).to eq(Gitlab::Access::MAINTAINER)
+ expect(mapping[owned_project.id]).to eq(Gitlab::Access::OWNER)
expect(mapping[other_project.id]).to eq(Gitlab::Access::REPORTER)
expect(mapping[group_project.id]).to eq(Gitlab::Access::DEVELOPER)
end
diff --git a/spec/lib/gitlab/regex_spec.rb b/spec/lib/gitlab/regex_spec.rb
index 54a0b282e99..f3e8c440fba 100644
--- a/spec/lib/gitlab/regex_spec.rb
+++ b/spec/lib/gitlab/regex_spec.rb
@@ -990,4 +990,19 @@ RSpec.describe Gitlab::Regex do
it { is_expected.not_to match('../../../../../1.2.3') }
it { is_expected.not_to match('%2e%2e%2f1.2.3') }
end
+
+ describe '.saved_reply_name_regex' do
+ subject { described_class.saved_reply_name_regex }
+
+ it { is_expected.to match('test') }
+ it { is_expected.to match('test123') }
+ it { is_expected.to match('test-test') }
+ it { is_expected.to match('test-test_0123') }
+ it { is_expected.not_to match('test test') }
+ it { is_expected.not_to match('test-') }
+ it { is_expected.not_to match('/z/test_') }
+ it { is_expected.not_to match('.xtest_') }
+ it { is_expected.not_to match('.xt.est_') }
+ it { is_expected.not_to match('0test1') }
+ end
end
diff --git a/spec/lib/gitlab/runtime_spec.rb b/spec/lib/gitlab/runtime_spec.rb
index 402b72b9220..86640efed5a 100644
--- a/spec/lib/gitlab/runtime_spec.rb
+++ b/spec/lib/gitlab/runtime_spec.rb
@@ -80,6 +80,10 @@ RSpec.describe Gitlab::Runtime do
it_behaves_like "valid runtime", :puma, 3 + Gitlab::ActionCable::Config.worker_pool_size
+ it 'identifies as an application runtime' do
+ expect(Gitlab::Runtime.application?).to be true
+ end
+
context "when ActionCable worker pool size is configured" do
before do
stub_env('ACTION_CABLE_WORKER_POOL_SIZE', 10)
@@ -113,6 +117,10 @@ RSpec.describe Gitlab::Runtime do
end
it_behaves_like "valid runtime", :sidekiq, 5
+
+ it 'identifies as an application runtime' do
+ expect(Gitlab::Runtime.application?).to be true
+ end
end
context "console" do
@@ -121,6 +129,10 @@ RSpec.describe Gitlab::Runtime do
end
it_behaves_like "valid runtime", :console, 1
+
+ it 'does not identify as an application runtime' do
+ expect(Gitlab::Runtime.application?).to be false
+ end
end
context "test suite" do
@@ -129,6 +141,10 @@ RSpec.describe Gitlab::Runtime do
end
it_behaves_like "valid runtime", :test_suite, 1
+
+ it 'does not identify as an application runtime' do
+ expect(Gitlab::Runtime.application?).to be false
+ end
end
context "geo log cursor" do
@@ -145,5 +161,9 @@ RSpec.describe Gitlab::Runtime do
end
it_behaves_like "valid runtime", :rails_runner, 1
+
+ it 'does not identify as an application runtime' do
+ expect(Gitlab::Runtime.application?).to be false
+ end
end
end
diff --git a/spec/lib/gitlab/safe_request_loader_spec.rb b/spec/lib/gitlab/safe_request_loader_spec.rb
new file mode 100644
index 00000000000..504ce233e4d
--- /dev/null
+++ b/spec/lib/gitlab/safe_request_loader_spec.rb
@@ -0,0 +1,180 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::SafeRequestLoader, :aggregate_failures do
+ let(:resource_key) { '_key_' }
+ let(:resource_ids) { [] }
+ let(:args) { { resource_key: resource_key, resource_ids: resource_ids } }
+ let(:block) { proc { {} } }
+
+ describe '.execute', :request_store do
+ let(:resource_data) { { 'foo' => 'bar' } }
+
+ before do
+ Gitlab::SafeRequestStore[resource_key] = resource_data
+ end
+
+ subject(:execute_instance) { described_class.execute(**args, &block) }
+
+ it 'gets data from the store and returns it' do
+ expect(execute_instance.keys).to contain_exactly(*resource_data.keys)
+ expect(execute_instance).to match(a_hash_including(resource_data))
+ expect_store_to_be_updated
+ end
+ end
+
+ describe '#execute' do
+ subject(:execute_instance) { described_class.new(**args).execute(&block) }
+
+ context 'without a block' do
+ let(:block) { nil }
+
+ it 'raises an error' do
+ expect { execute_instance }.to raise_error(ArgumentError, 'Block is mandatory')
+ end
+ end
+
+ context 'when a resource_id is nil' do
+ let(:block) { proc { {} } }
+ let(:resource_ids) { [nil] }
+
+ it 'contains resource_data with nil key' do
+ expect(execute_instance.keys).to contain_exactly(nil)
+ expect(execute_instance).to match(a_hash_including(nil => nil))
+ end
+ end
+
+ context 'with SafeRequestStore considerations' do
+ let(:resource_data) { { 'foo' => 'bar' } }
+
+ before do
+ Gitlab::SafeRequestStore[resource_key] = resource_data
+ end
+
+ context 'when request store is active', :request_store do
+ it 'gets data from the store' do
+ expect(execute_instance.keys).to contain_exactly(*resource_data.keys)
+ expect(execute_instance).to match(a_hash_including(resource_data))
+ expect_store_to_be_updated
+ end
+
+ context 'with already loaded resource_ids', :request_store do
+ let(:resource_key) { 'foo_data' }
+ let(:existing_resource_data) { { 'foo' => 'zoo' } }
+ let(:block) { proc { { 'foo' => 'bar' } } }
+ let(:resource_ids) { ['foo'] }
+
+ before do
+ Gitlab::SafeRequestStore[resource_key] = existing_resource_data
+ end
+
+ it 'does not re-fetch data if resource_id already exists' do
+ expect(execute_instance.keys).to contain_exactly(*resource_ids)
+ expect(execute_instance).to match(a_hash_including(existing_resource_data))
+ expect_store_to_be_updated
+ end
+
+ context 'with mixture of new and existing resource_ids' do
+ let(:existing_resource_data) { { 'foo' => 'bar' } }
+ let(:resource_ids) { %w[foo bar] }
+
+ context 'when block does not filter for only the missing resource_ids' do
+ let(:block) { proc { { 'foo' => 'zoo', 'bar' => 'foo' } } }
+
+ it 'overwrites existing keyed data with results from the block' do
+ expect(execute_instance.keys).to contain_exactly(*resource_ids)
+ expect(execute_instance).to match(a_hash_including(block.call))
+ expect_store_to_be_updated
+ end
+ end
+
+ context 'when passing the missing resource_ids to a block that filters for them' do
+ let(:block) { proc { |rids| { 'foo' => 'zoo', 'bar' => 'foo' }.select { |k, _v| rids.include?(k) } } }
+
+ it 'only updates resource_data with keyed items that did not exist' do
+ expect(execute_instance.keys).to contain_exactly(*resource_ids)
+ expect(execute_instance).to match(a_hash_including({ 'foo' => 'bar', 'bar' => 'foo' }))
+ expect_store_to_be_updated
+ end
+ end
+
+ context 'with default_value for resource_ids that did not exist in the results' do
+ context 'when default_value is provided' do
+ let(:args) { { resource_key: resource_key, resource_ids: resource_ids, default_value: '_value_' } }
+
+ it 'populates a default value' do
+ expect(execute_instance.keys).to contain_exactly(*resource_ids)
+ expect(execute_instance).to match(a_hash_including({ 'foo' => 'bar', 'bar' => '_value_' }))
+ expect_store_to_be_updated
+ end
+ end
+
+ context 'when default_value is not provided' do
+ it 'populates a default_value of nil' do
+ expect(execute_instance.keys).to contain_exactly(*resource_ids)
+ expect(execute_instance).to match(a_hash_including({ 'foo' => 'bar', 'bar' => nil }))
+ expect_store_to_be_updated
+ end
+ end
+ end
+ end
+ end
+ end
+
+ context 'when request store is not active' do
+ let(:block) { proc { { 'foo' => 'bar' } } }
+ let(:resource_ids) { ['foo'] }
+
+ it 'has no data added from the store' do
+ expect(execute_instance).to eq(block.call)
+ end
+
+ context 'with mixture of new and existing resource_ids' do
+ let(:resource_ids) { %w[foo bar] }
+
+ context 'when block does not filter out existing resource_data keys' do
+ let(:block) { proc { { 'foo' => 'zoo', 'bar' => 'foo' } } }
+
+ it 'overwrites existing keyed data with results from the block' do
+ expect(execute_instance.keys).to contain_exactly(*resource_ids)
+ expect(execute_instance).to match(a_hash_including(block.call))
+ end
+ end
+
+ context 'when passing the missing resource_ids to a block that filters for them' do
+ let(:block) { proc { |rids| { 'foo' => 'zoo', 'bar' => 'foo' }.select { |k, _v| rids.include?(k) } } }
+
+ it 'only updates resource_data with keyed items that did not exist' do
+ expect(execute_instance.keys).to contain_exactly(*resource_ids)
+ expect(execute_instance).to match(a_hash_including({ 'foo' => 'zoo', 'bar' => 'foo' }))
+ end
+ end
+
+ context 'with default_value for resource_ids that did not exist in the results' do
+ context 'when default_value is provided' do
+ let(:args) { { resource_key: resource_key, resource_ids: resource_ids, default_value: '_value_' } }
+
+ it 'populates a default value' do
+ expect(execute_instance.keys).to contain_exactly(*resource_ids)
+ expect(execute_instance).to match(a_hash_including({ 'foo' => 'bar', 'bar' => '_value_' }))
+ end
+ end
+
+ context 'when default_value is not provided' do
+ it 'populates a default_value of nil' do
+ expect(execute_instance.keys).to contain_exactly(*resource_ids)
+ expect(execute_instance).to match(a_hash_including({ 'foo' => 'bar', 'bar' => nil }))
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+
+ def expect_store_to_be_updated
+ expect(execute_instance).to match(a_hash_including(Gitlab::SafeRequestStore[resource_key]))
+ expect(execute_instance.keys).to contain_exactly(*Gitlab::SafeRequestStore[resource_key].keys)
+ end
+end
diff --git a/spec/lib/gitlab/safe_request_store_spec.rb b/spec/lib/gitlab/safe_request_store_spec.rb
index 704102ccaee..accc491fbb7 100644
--- a/spec/lib/gitlab/safe_request_store_spec.rb
+++ b/spec/lib/gitlab/safe_request_store_spec.rb
@@ -183,7 +183,7 @@ RSpec.describe Gitlab::SafeRequestStore do
context 'when RequestStore is active', :request_store do
it 'uses RequestStore' do
expect do
- described_class.fetch('foo') { 'block result' }
+ described_class.fetch('foo') { 'block result' } # rubocop:disable Style/RedundantFetchBlock
end.to change { described_class.read('foo') }.from(nil).to('block result')
end
end
@@ -193,7 +193,7 @@ RSpec.describe Gitlab::SafeRequestStore do
RequestStore.clear! # Ensure clean
expect do
- described_class.fetch('foo') { 'block result' }
+ described_class.fetch('foo') { 'block result' } # rubocop:disable Style/RedundantFetchBlock
end.not_to change { described_class.read('foo') }.from(nil)
RequestStore.clear! # Clean up
diff --git a/spec/lib/gitlab/sanitizers/exif_spec.rb b/spec/lib/gitlab/sanitizers/exif_spec.rb
index fbda9e6d0be..623fa4bc48a 100644
--- a/spec/lib/gitlab/sanitizers/exif_spec.rb
+++ b/spec/lib/gitlab/sanitizers/exif_spec.rb
@@ -131,6 +131,124 @@ RSpec.describe Gitlab::Sanitizers::Exif do
end
end
+ describe '#clean_existing_path' do
+ let(:dry_run) { false }
+
+ let(:tmp_file) { Tempfile.new("rails_sample.jpg") }
+
+ subject { sanitizer.clean_existing_path(tmp_file.path, dry_run: dry_run) }
+
+ context "no dry run" do
+ let(:file_content) { fixture_file_upload('spec/fixtures/rails_sample.jpg') }
+
+ before do
+ File.open(tmp_file.path, "w+b") { |f| f.write file_content }
+ end
+
+ it "removes exif from the image" do
+ expected_args = ["exiftool", "-all=", "-tagsFromFile", "@", *Gitlab::Sanitizers::Exif::EXCLUDE_PARAMS, "--IPTC:all", "--XMP-iptcExt:all", kind_of(String)]
+
+ expect(sanitizer).to receive(:extra_tags).and_return(["", 0])
+ expect(sanitizer).to receive(:exec_remove_exif!).once.and_call_original
+ expect(Gitlab::Popen).to receive(:popen).with(expected_args) do |args|
+ File.write("#{args.last}_original", "foo") if args.last.start_with?(Dir.tmpdir)
+
+ [expected_args, 0]
+ end
+
+ subject
+ end
+
+ it "ignores image without exif" do
+ expected_args = ["exiftool", "-all", "-j", "-sort", "--IPTC:all", "--XMP-iptcExt:all", kind_of(String)]
+
+ expect(Gitlab::Popen).to receive(:popen).with(expected_args).and_return(["[{}]", 0])
+ expect(sanitizer).not_to receive(:exec_remove_exif!)
+
+ subject
+ end
+
+ it "raises an error if the exiftool fails with an error" do
+ expect(Gitlab::Popen).to receive(:popen).and_return(["error", 1])
+
+ expect { subject }.to raise_exception(RuntimeError, "failed to get exif tags: error")
+ end
+
+ context 'for files that do not have the correct MIME type from file' do
+ let(:mime_type) { 'text/plain' }
+
+ it 'cleans only jpg/tiff images with the correct mime types' do
+ expect(sanitizer).not_to receive(:extra_tags)
+
+ expect { subject }.to raise_error(RuntimeError, %r{File type text/plain not supported})
+ end
+ end
+
+ context 'skip_unallowed_types is false' do
+ context 'for files that do not have the correct MIME type from input content' do
+ let(:mime_type) { 'text/plain' }
+
+ it 'raises an error if not jpg/tiff images with the correct mime types' do
+ expect(sanitizer).not_to receive(:extra_tags)
+
+ expect do
+ sanitizer.clean_existing_path(tmp_file.path, content: file_content)
+ end.to raise_error(RuntimeError, %r{File type text/plain not supported})
+ end
+ end
+
+ context 'for files that do not have the correct MIME type from input content' do
+ let(:mime_type) { 'text/plain' }
+
+ it 'raises an error if not jpg/tiff images with the correct mime types' do
+ expect(sanitizer).not_to receive(:extra_tags)
+
+ expect do
+ sanitizer.clean_existing_path(tmp_file.path, content: file_content)
+ end.to raise_error(RuntimeError, %r{File type text/plain not supported})
+ end
+ end
+ end
+
+ context 'skip_unallowed_types is true' do
+ context 'for files that do not have the correct MIME type from input content' do
+ let(:mime_type) { 'text/plain' }
+
+ it 'cleans only jpg/tiff images with the correct mime types' do
+ expect(sanitizer).not_to receive(:extra_tags)
+
+ expect do
+ sanitizer.clean_existing_path(tmp_file.path, content: file_content, skip_unallowed_types: true)
+ end.not_to raise_error
+ end
+ end
+
+ context 'for files that do not have the correct MIME type from input content' do
+ let(:mime_type) { 'text/plain' }
+
+ it 'cleans only jpg/tiff images with the correct mime types' do
+ expect(sanitizer).not_to receive(:extra_tags)
+
+ expect do
+ sanitizer.clean_existing_path(tmp_file.path, content: file_content, skip_unallowed_types: true)
+ end.not_to raise_error
+ end
+ end
+ end
+ end
+
+ context "dry run" do
+ let(:dry_run) { true }
+
+ it "doesn't change the image" do
+ expect(sanitizer).to receive(:extra_tags).and_return({ 'foo' => 'bar' })
+ expect(sanitizer).not_to receive(:exec_remove_exif!)
+
+ subject
+ end
+ end
+ end
+
describe "#extra_tags" do
it "returns a list of keys for exif file" do
tags = '[{
diff --git a/spec/lib/gitlab/seeder_spec.rb b/spec/lib/gitlab/seeder_spec.rb
index 877461a7064..71d0a41ef98 100644
--- a/spec/lib/gitlab/seeder_spec.rb
+++ b/spec/lib/gitlab/seeder_spec.rb
@@ -4,6 +4,26 @@ require 'spec_helper'
RSpec.describe Gitlab::Seeder do
describe '.quiet' do
+ let(:database_base_models) do
+ {
+ main: ApplicationRecord,
+ ci: Ci::ApplicationRecord
+ }
+ end
+
+ it 'disables database logging' do
+ allow(Gitlab::Database).to receive(:database_base_models)
+ .and_return(database_base_models.with_indifferent_access)
+
+ described_class.quiet do
+ expect(ApplicationRecord.logger).to be_nil
+ expect(Ci::ApplicationRecord.logger).to be_nil
+ end
+
+ expect(ApplicationRecord.logger).not_to be_nil
+ expect(Ci::ApplicationRecord.logger).not_to be_nil
+ end
+
it 'disables mail deliveries' do
expect(ActionMailer::Base.perform_deliveries).to eq(true)
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 833de6ae624..8d46845548a 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
@@ -122,20 +122,6 @@ RSpec.describe Gitlab::SidekiqMiddleware::DuplicateJobs::DuplicateJob, :clean_gi
it_behaves_like 'sets Redis keys with correct TTL'
end
- context 'when preserve_latest_wal_locations_for_idempotent_jobs feature flag is disabled' do
- before do
- stub_feature_flags(preserve_latest_wal_locations_for_idempotent_jobs: false)
- end
-
- it "does not change the existing wal locations key's TTL" do
- expect { duplicate_job.check! }
- .to not_change { read_idempotency_key_with_ttl(existing_wal_location_key(idempotency_key, :main)) }
- .from([nil, -2])
- .and not_change { read_idempotency_key_with_ttl(existing_wal_location_key(idempotency_key, :ci)) }
- .from([nil, -2])
- end
- end
-
it "adds the idempotency key to the jobs payload" do
expect { duplicate_job.check! }.to change { job['idempotency_key'] }.from(nil).to(idempotency_key)
end
@@ -186,28 +172,6 @@ RSpec.describe Gitlab::SidekiqMiddleware::DuplicateJobs::DuplicateJob, :clean_gi
duplicate_job.check!
end
- context 'when preserve_latest_wal_locations_for_idempotent_jobs feature flag is disabled' do
- let(:existing_wal) { {} }
-
- before do
- stub_feature_flags(preserve_latest_wal_locations_for_idempotent_jobs: false)
- end
-
- it "doesn't call Sidekiq.redis" do
- expect(Sidekiq).not_to receive(:redis)
-
- duplicate_job.update_latest_wal_location!
- end
-
- it "doesn't update a wal location to redis with an offset" do
- expect { duplicate_job.update_latest_wal_location! }
- .to not_change { read_range_from_redis(wal_location_key(idempotency_key, :main)) }
- .from([])
- .and not_change { read_range_from_redis(wal_location_key(idempotency_key, :ci)) }
- .from([])
- end
- end
-
context "when the key doesn't exists in redis" do
let(:existing_wal) do
{
@@ -328,20 +292,6 @@ RSpec.describe Gitlab::SidekiqMiddleware::DuplicateJobs::DuplicateJob, :clean_gi
context 'when job is not deduplication and wal locations were not persisted' do
it { expect(duplicate_job.latest_wal_locations).to be_empty }
end
-
- context 'when preserve_latest_wal_locations_for_idempotent_jobs feature flag is disabled' do
- before do
- stub_feature_flags(preserve_latest_wal_locations_for_idempotent_jobs: false)
- end
-
- it "doesn't call Sidekiq.redis" do
- expect(Sidekiq).not_to receive(:redis)
-
- duplicate_job.latest_wal_locations
- end
-
- it { expect(duplicate_job.latest_wal_locations).to eq({}) }
- end
end
describe '#delete!' do
@@ -406,32 +356,6 @@ RSpec.describe Gitlab::SidekiqMiddleware::DuplicateJobs::DuplicateJob, :clean_gi
let(:key) { wal_location_key(idempotency_key, :ci) }
let(:from_value) { wal_locations[:ci] }
end
-
- context 'when preserve_latest_wal_locations_for_idempotent_jobs feature flag is disabled' do
- before do
- stub_feature_flags(preserve_latest_wal_locations_for_idempotent_jobs: false)
- end
-
- it_behaves_like 'does not delete key from redis', 'latest wal location keys for main database' do
- let(:key) { existing_wal_location_key(idempotency_key, :main) }
- let(:from_value) { wal_locations[:main] }
- end
-
- it_behaves_like 'does not delete key from redis', 'latest wal location keys for ci database' do
- let(:key) { existing_wal_location_key(idempotency_key, :ci) }
- let(:from_value) { wal_locations[:ci] }
- end
-
- it_behaves_like 'does not delete key from redis', 'latest wal location keys for main database' do
- let(:key) { wal_location_key(idempotency_key, :main) }
- let(:from_value) { wal_locations[:main] }
- end
-
- it_behaves_like 'does not delete key from redis', 'latest wal location keys for ci database' do
- let(:key) { wal_location_key(idempotency_key, :ci) }
- let(:from_value) { wal_locations[:ci] }
- end
- end
end
context 'when the idempotency key is not part of the job' do
@@ -666,16 +590,6 @@ RSpec.describe Gitlab::SidekiqMiddleware::DuplicateJobs::DuplicateJob, :clean_gi
it 'returns true' do
expect(duplicate_job).to be_idempotent
end
-
- context 'when preserve_latest_wal_locations_for_idempotent_jobs feature flag is disabled' do
- before do
- stub_feature_flags(preserve_latest_wal_locations_for_idempotent_jobs: false)
- end
-
- it 'returns false' do
- expect(duplicate_job).not_to be_idempotent
- end
- end
end
end
diff --git a/spec/lib/gitlab/untrusted_regexp/ruby_syntax_spec.rb b/spec/lib/gitlab/untrusted_regexp/ruby_syntax_spec.rb
index b021abc9f25..43f155091ad 100644
--- a/spec/lib/gitlab/untrusted_regexp/ruby_syntax_spec.rb
+++ b/spec/lib/gitlab/untrusted_regexp/ruby_syntax_spec.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-require 'spec_helper'
+require 'fast_spec_helper'
RSpec.describe Gitlab::UntrustedRegexp::RubySyntax do
describe '.matches_syntax?' do
@@ -71,44 +71,6 @@ RSpec.describe Gitlab::UntrustedRegexp::RubySyntax do
end
end
- context 'when unsafe regexp is used' do
- include StubFeatureFlags
-
- before do
- # When removed we could use `require 'fast_spec_helper'` again.
- stub_feature_flags(allow_unsafe_ruby_regexp: true)
-
- allow(Gitlab::UntrustedRegexp).to receive(:new).and_raise(RegexpError)
- end
-
- context 'when no fallback is enabled' do
- it 'raises an exception' do
- expect { described_class.fabricate!('/something/') }
- .to raise_error(RegexpError)
- end
- end
-
- context 'when fallback is used' do
- it 'fabricates regexp with a single flag' do
- regexp = described_class.fabricate!('/something/i', fallback: true)
-
- expect(regexp).to eq Regexp.new('something', Regexp::IGNORECASE)
- end
-
- it 'fabricates regexp with multiple flags' do
- regexp = described_class.fabricate!('/something/im', fallback: true)
-
- expect(regexp).to eq Regexp.new('something', Regexp::IGNORECASE | Regexp::MULTILINE)
- end
-
- it 'fabricates regexp without flags' do
- regexp = described_class.fabricate!('/something/', fallback: true)
-
- expect(regexp).to eq Regexp.new('something')
- end
- end
- end
-
context 'when regexp is a raw pattern' do
it 'raises an error' do
expect { described_class.fabricate!('some .* thing') }
diff --git a/spec/lib/gitlab/url_blocker_spec.rb b/spec/lib/gitlab/url_blocker_spec.rb
index 5b77290ce2e..57b0297a0a0 100644
--- a/spec/lib/gitlab/url_blocker_spec.rb
+++ b/spec/lib/gitlab/url_blocker_spec.rb
@@ -39,6 +39,73 @@ RSpec.describe Gitlab::UrlBlocker, :stub_invalid_dns_only do
end
end
+ context 'when URI is for a local object storage' do
+ let(:import_url) { "#{host}/external-diffs/merge_request_diffs/mr-1/diff-1" }
+ let(:enabled_object_storage_setting) do
+ {
+ 'object_store' =>
+ {
+ 'enabled' => true,
+ 'connection' => {
+ 'endpoint' => host
+ }
+ }
+ }
+ end
+
+ before do
+ allow(Settings).to receive(:external_diffs).and_return(enabled_object_storage_setting)
+ end
+
+ context 'when allow_object_storage is true' do
+ subject { described_class.validate!(import_url, allow_object_storage: true) }
+
+ context 'with a local domain name' do
+ let(:host) { 'http://review-minio-svc.svc:9000' }
+
+ before do
+ stub_dns(host, ip_address: '127.0.0.1')
+ end
+
+ it_behaves_like 'validates URI and hostname' do
+ let(:expected_uri) { 'http://127.0.0.1:9000/external-diffs/merge_request_diffs/mr-1/diff-1' }
+ let(:expected_hostname) { 'review-minio-svc.svc' }
+ end
+ end
+
+ context 'with an IP address' do
+ let(:host) { 'http://127.0.0.1:9000' }
+
+ it_behaves_like 'validates URI and hostname' do
+ let(:expected_uri) { 'http://127.0.0.1:9000/external-diffs/merge_request_diffs/mr-1/diff-1' }
+ let(:expected_hostname) { nil }
+ end
+ end
+ end
+
+ context 'when allow_object_storage is false' do
+ context 'with a local domain name' do
+ let(:host) { 'http://review-minio-svc.svc:9000' }
+
+ before do
+ stub_dns(host, ip_address: '127.0.0.1')
+ end
+
+ it 'raises an error' do
+ expect { subject }.to raise_error(described_class::BlockedUrlError)
+ end
+ end
+
+ context 'with an IP address' do
+ let(:host) { 'http://127.0.0.1:9000' }
+
+ it 'raises an error' do
+ expect { subject }.to raise_error(described_class::BlockedUrlError)
+ end
+ end
+ end
+ end
+
context 'when the URL hostname is a domain' do
context 'when domain can be resolved' do
let(:import_url) { 'https://example.org' }
@@ -299,6 +366,21 @@ RSpec.describe Gitlab::UrlBlocker, :stub_invalid_dns_only do
]
end
+ let(:limited_broadcast_address_variants) do
+ [
+ '255.255.255.255', # "normal" dotted decimal
+ '0377.0377.0377.0377', # Octal
+ '0377.00000000377.00377.0000377', # Still octal
+ '0xff.0xff.0xff.0xff', # hex
+ '0xffffffff', # still hex
+ '0xBaaaaaaaaaaaaaaaaffffffff', # padded hex
+ '255.255.255.255:65535', # with a port
+ '4294967295', # as an integer / dword
+ '[::ffff:ffff:ffff]', # short IPv6
+ '[0000:0000:0000:0000:0000:ffff:ffff:ffff]' # long IPv6
+ ]
+ end
+
let(:fake_domain) { 'www.fakedomain.fake' }
shared_examples 'allows local requests' do |url_blocker_attributes|
@@ -336,6 +418,12 @@ RSpec.describe Gitlab::UrlBlocker, :stub_invalid_dns_only do
expect(described_class).not_to be_blocked_url('http://[::ffff:a9fe:a864]', **url_blocker_attributes)
expect(described_class).not_to be_blocked_url('http://[fe80::c800:eff:fe74:8]', **url_blocker_attributes)
end
+
+ it 'allows limited broadcast address 255.255.255.255 and variants' do
+ limited_broadcast_address_variants.each do |variant|
+ expect(described_class).not_to be_blocked_url("https://#{variant}", **url_blocker_attributes), "Expected #{variant} to be allowed"
+ end
+ end
end
context 'true (default)' do
@@ -368,6 +456,17 @@ RSpec.describe Gitlab::UrlBlocker, :stub_invalid_dns_only do
expect(described_class).to be_blocked_url('http://[fe80::c800:eff:fe74:8]', allow_local_network: false)
end
+ it 'blocks limited broadcast address 255.255.255.255 and variants' do
+ # Raise BlockedUrlError for invalid URLs.
+ # The padded hex version, for example, is a valid URL on Mac but
+ # not on Ubuntu.
+ stub_env('RSPEC_ALLOW_INVALID_URLS', 'false')
+
+ limited_broadcast_address_variants.each do |variant|
+ expect(described_class).to be_blocked_url("https://#{variant}", allow_local_network: false), "Expected #{variant} to be blocked"
+ end
+ end
+
context 'when local domain/IP is allowed' do
let(:url_blocker_attributes) do
{
@@ -394,6 +493,7 @@ RSpec.describe Gitlab::UrlBlocker, :stub_invalid_dns_only do
'::ffff:169.254.168.100',
'::ffff:a9fe:a864',
'fe80::c800:eff:fe74:8',
+ '255.255.255.255',
# garbage IPs
'45645632345',
@@ -415,6 +515,10 @@ RSpec.describe Gitlab::UrlBlocker, :stub_invalid_dns_only do
expect(described_class).to be_blocked_url(url, **attrs)
end
end
+
+ it 'allows the limited broadcast address 255.255.255.255' do
+ expect(described_class).not_to be_blocked_url('http://255.255.255.255', **url_blocker_attributes)
+ end
end
context 'with domains in allowlist' do
diff --git a/spec/lib/gitlab/usage/metric_definition_spec.rb b/spec/lib/gitlab/usage/metric_definition_spec.rb
index a22b3a733bd..1127d1cd477 100644
--- a/spec/lib/gitlab/usage/metric_definition_spec.rb
+++ b/spec/lib/gitlab/usage/metric_definition_spec.rb
@@ -50,6 +50,28 @@ RSpec.describe Gitlab::Usage::MetricDefinition do
expect { described_class.definitions }.not_to raise_error
end
+ describe 'not_removed' do
+ let(:all_definitions) do
+ metrics_definitions = [
+ { key_path: 'metric1', instrumentation_class: 'RedisHLLMetric', status: 'active' },
+ { key_path: 'metric2', instrumentation_class: 'RedisHLLMetric', status: 'broken' },
+ { key_path: 'metric3', instrumentation_class: 'RedisHLLMetric', status: 'active' },
+ { key_path: 'metric4', instrumentation_class: 'RedisHLLMetric', status: 'removed' }
+ ]
+ metrics_definitions.map { |definition| described_class.new(definition[:key_path], definition.symbolize_keys) }
+ end
+
+ before do
+ allow(described_class).to receive(:all).and_return(all_definitions)
+ end
+
+ it 'includes metrics that are not removed' do
+ expect(described_class.not_removed.count).to eq(3)
+
+ expect(described_class.not_removed.keys).to match_array(%w(metric1 metric2 metric3))
+ end
+ end
+
describe '#with_instrumentation_class' do
let(:metric_status) { 'active' }
let(:all_definitions) do
diff --git a/spec/lib/gitlab/usage/metrics/instrumentations/cert_based_clusters_ff_metric_spec.rb b/spec/lib/gitlab/usage/metrics/instrumentations/cert_based_clusters_ff_metric_spec.rb
new file mode 100644
index 00000000000..09cc6ae71d4
--- /dev/null
+++ b/spec/lib/gitlab/usage/metrics/instrumentations/cert_based_clusters_ff_metric_spec.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Usage::Metrics::Instrumentations::CertBasedClustersFfMetric do
+ context 'with FF enabled' do
+ it_behaves_like 'a correct instrumented metric value', { time_frame: '7d', data_source: 'database' } do
+ let(:expected_value) { true }
+ end
+ end
+
+ context 'with FF disabled' do
+ before do
+ stub_feature_flags(certificate_based_clusters: false)
+ end
+
+ it_behaves_like 'a correct instrumented metric value', { time_frame: '7d', data_source: 'database' } do
+ let(:expected_value) { false }
+ end
+ end
+end
diff --git a/spec/lib/gitlab/usage/metrics/instrumentations/database_metric_spec.rb b/spec/lib/gitlab/usage/metrics/instrumentations/database_metric_spec.rb
index 4d84423cde4..ea5ae1970de 100644
--- a/spec/lib/gitlab/usage/metrics/instrumentations/database_metric_spec.rb
+++ b/spec/lib/gitlab/usage/metrics/instrumentations/database_metric_spec.rb
@@ -36,6 +36,28 @@ RSpec.describe Gitlab::Usage::Metrics::Instrumentations::DatabaseMetric do
expect(Rails.cache.read('metric_instrumentation/special_issue_count_maximum_id')).to eq(nil)
end
+ context 'with metric options specified with custom batch_size' do
+ subject do
+ described_class.tap do |metric_class|
+ metric_class.relation { Issue }
+ metric_class.operation :count
+ metric_class.start { metric_class.relation.minimum(:id) }
+ metric_class.finish { metric_class.relation.maximum(:id) }
+ metric_class.metric_options { { batch_size: 12345 } }
+ end.new(time_frame: 'all')
+ end
+
+ it 'calls metric with customized batch_size' do
+ expect(subject).to receive(:count).with(any_args, hash_including(batch_size: 12345, start: issues.min_by(&:id).id, finish: issues.max_by(&:id).id)).and_call_original
+
+ subject.value
+ end
+
+ it 'calculates a correct result' do
+ expect(subject.value).to eq(3)
+ end
+ end
+
context 'with start and finish not called' do
subject do
described_class.tap do |metric_class|
diff --git a/spec/lib/gitlab/usage/metrics/names_suggestions/generator_spec.rb b/spec/lib/gitlab/usage/metrics/names_suggestions/generator_spec.rb
index 0f95da74ff9..f81ad9b193d 100644
--- a/spec/lib/gitlab/usage/metrics/names_suggestions/generator_spec.rb
+++ b/spec/lib/gitlab/usage/metrics/names_suggestions/generator_spec.rb
@@ -27,8 +27,8 @@ RSpec.describe Gitlab::Usage::Metrics::NamesSuggestions::Generator do
context 'for count with default column metrics' do
it_behaves_like 'name suggestion' do
# corresponding metric is collected with count(Board)
- let(:key_path) { 'counts.boards' }
- let(:name_suggestion) { /count_boards/ }
+ let(:key_path) { 'counts.issues' }
+ let(:name_suggestion) { /count_issues/ }
end
end
diff --git a/spec/lib/gitlab/usage/service_ping/instrumented_payload_spec.rb b/spec/lib/gitlab/usage/service_ping/instrumented_payload_spec.rb
new file mode 100644
index 00000000000..76548483cfa
--- /dev/null
+++ b/spec/lib/gitlab/usage/service_ping/instrumented_payload_spec.rb
@@ -0,0 +1,49 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Usage::ServicePing::InstrumentedPayload do
+ let(:uuid) { "0000-0000-0000" }
+
+ before do
+ allow(ApplicationRecord.connection).to receive(:transaction_open?).and_return(false)
+ allow(Gitlab::CurrentSettings).to receive(:uuid).and_return(uuid)
+ end
+
+ context 'when building service ping with values' do
+ let(:metrics_key_paths) { %w(counts.boards uuid redis_hll_counters.search.i_search_total_monthly) }
+ let(:expected_payload) do
+ {
+ counts: { boards: 0 },
+ redis_hll_counters: { search: { i_search_total_monthly: 0 } },
+ uuid: uuid
+ }
+ end
+
+ it 'builds the service ping payload for the metrics key_paths' do
+ expect(described_class.new(metrics_key_paths, :with_value).build).to eq(expected_payload)
+ end
+ end
+
+ context 'when building service ping with instrumentations' do
+ let(:metrics_key_paths) { %w(counts.boards uuid redis_hll_counters.search.i_search_total_monthly) }
+ let(:expected_payload) do
+ {
+ counts: { boards: "SELECT COUNT(\"boards\".\"id\") FROM \"boards\"" },
+ redis_hll_counters: { search: { i_search_total_monthly: 0 } },
+ uuid: uuid
+ }
+ end
+
+ it 'builds the service ping payload for the metrics key_paths' do
+ expect(described_class.new(metrics_key_paths, :with_instrumentation).build).to eq(expected_payload)
+ end
+ end
+
+ context 'when missing instrumentation class' do
+ it 'returns empty hash' do
+ expect(described_class.new(['counts.ci_builds'], :with_instrumentation).build).to eq({})
+ expect(described_class.new(['counts.ci_builds'], :with_value).build).to eq({})
+ end
+ end
+end
diff --git a/spec/lib/gitlab/usage/service_ping/payload_keys_processor_spec.rb b/spec/lib/gitlab/usage/service_ping/payload_keys_processor_spec.rb
new file mode 100644
index 00000000000..dd4349b99df
--- /dev/null
+++ b/spec/lib/gitlab/usage/service_ping/payload_keys_processor_spec.rb
@@ -0,0 +1,56 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Usage::ServicePing::PayloadKeysProcessor do
+ context 'with an object metric' do
+ let(:payload) { { counts: { issues: 1, boards: 1 }, topology: { duration_d: 100 }, redis_hll_counters: { search: { i_search_total_monthly: 1 } } } }
+
+ it 'returns the payload keys that have a metric definition' do
+ expect(described_class.new(payload).key_paths).to match_array(['counts.issues', 'counts.boards', 'topology', 'redis_hll_counters.search.i_search_total_monthly'])
+ end
+ end
+
+ context 'with a missing metric definition' do
+ let(:payload) { { counts: { issues: 1, boards: 1 }, missing_definition: 1, topology: { duration_d: 100 } } }
+
+ it 'returns the payload keys that have a metric definition' do
+ expect(described_class.new(payload).key_paths).to match_array(['counts.issues', 'counts.boards', 'topology'])
+ end
+ end
+
+ context 'with array metric' do
+ let(:payload) { { counts: { issues: 1, boards: 1 }, settings: { collected_data_categories: ['standard'] }, topology: { duration_d: 100 } } }
+
+ it 'returns the payload keys that have a metric definition' do
+ expect(described_class.new(payload).key_paths).to match_array(['counts.issues', 'counts.boards', 'topology', 'settings.collected_data_categories'])
+ end
+ end
+
+ context 'missing_instrumented_metrics_key_paths' do
+ let(:payload) do
+ {
+ counts: { issues: 1, boards: 1 },
+ topology: { duration_d: 100 },
+ redis_hll_counters: { search: { i_search_total_monthly: 1 } }
+ }
+ end
+
+ let(:metrics_definitions) do
+ [
+ instance_double(::Gitlab::Usage::MetricDefinition, key: 'counts.issues'),
+ instance_double(::Gitlab::Usage::MetricDefinition, key: 'topology'),
+ instance_double(::Gitlab::Usage::MetricDefinition, key: 'redis_hll_counters.search.i_search_total_monthly'),
+ instance_double(::Gitlab::Usage::MetricDefinition, key: 'settings.collected_data_categories')
+ ]
+ end
+
+ before do
+ allow(::Gitlab::Usage::MetricDefinition).to receive(:with_instrumentation_class).and_return(metrics_definitions)
+ end
+
+ it 'returns the missing keys' do
+ expect(described_class.new(payload).missing_instrumented_metrics_key_paths).to match_array(['settings.collected_data_categories'])
+ end
+ end
+end
diff --git a/spec/lib/gitlab/usage/service_ping_report_spec.rb b/spec/lib/gitlab/usage/service_ping_report_spec.rb
index 9b9b24ad128..1f62ddd0bbb 100644
--- a/spec/lib/gitlab/usage/service_ping_report_spec.rb
+++ b/spec/lib/gitlab/usage/service_ping_report_spec.rb
@@ -3,66 +3,216 @@
require 'spec_helper'
RSpec.describe Gitlab::Usage::ServicePingReport, :use_clean_rails_memory_store_caching do
- let(:usage_data) { { uuid: "1111" } }
+ include UsageDataHelpers
- context 'for output: :all_metrics_values' do
- it 'generates the service ping' do
- expect(Gitlab::UsageData).to receive(:data)
+ let(:usage_data) { { uuid: "1111", counts: { issue: 0 } } }
- described_class.for(output: :all_metrics_values)
+ context 'when feature merge_service_ping_instrumented_metrics enabled' do
+ before do
+ stub_feature_flags(merge_service_ping_instrumented_metrics: true)
+
+ allow_next_instance_of(Gitlab::Usage::ServicePing::PayloadKeysProcessor) do |instance|
+ allow(instance).to receive(:missing_key_paths).and_return([])
+ end
+
+ allow_next_instance_of(Gitlab::Usage::ServicePing::InstrumentedPayload) do |instance|
+ allow(instance).to receive(:build).and_return({})
+ end
end
- end
- context 'for output: :metrics_queries' do
- it 'generates the service ping' do
- expect(Gitlab::UsageDataQueries).to receive(:data)
+ context 'all_metrics_values' do
+ it 'generates the service ping when there are no missing values' do
+ expect(Gitlab::UsageData).to receive(:data).and_return(usage_data)
+ expect(described_class.for(output: :all_metrics_values)).to eq({ uuid: "1111", counts: { issue: 0 } })
+ end
- described_class.for(output: :metrics_queries)
+ it 'generates the service ping with the missing values' do
+ expect_next_instance_of(Gitlab::Usage::ServicePing::PayloadKeysProcessor, usage_data) do |instance|
+ expect(instance).to receive(:missing_instrumented_metrics_key_paths).and_return(['counts.boards'])
+ end
+
+ expect_next_instance_of(Gitlab::Usage::ServicePing::InstrumentedPayload, ['counts.boards'], :with_value) do |instance|
+ expect(instance).to receive(:build).and_return({ counts: { boards: 1 } })
+ end
+
+ expect(Gitlab::UsageData).to receive(:data).and_return(usage_data)
+ expect(described_class.for(output: :all_metrics_values)).to eq({ uuid: "1111", counts: { issue: 0, boards: 1 } })
+ end
end
- end
- context 'for output: :non_sql_metrics_values' do
- it 'generates the service ping' do
- expect(Gitlab::UsageDataNonSqlMetrics).to receive(:data)
+ context 'for output: :metrics_queries' do
+ it 'generates the service ping' do
+ expect(Gitlab::UsageData).to receive(:data).and_return(usage_data)
+
+ described_class.for(output: :metrics_queries)
+ end
+ end
+
+ context 'for output: :non_sql_metrics_values' do
+ it 'generates the service ping' do
+ expect(Gitlab::UsageData).to receive(:data).and_return(usage_data)
- described_class.for(output: :non_sql_metrics_values)
+ described_class.for(output: :non_sql_metrics_values)
+ end
+ end
+
+ context 'when using cached' do
+ context 'for cached: true' do
+ let(:new_usage_data) { { uuid: "1112" } }
+
+ it 'caches the values' do
+ allow(Gitlab::UsageData).to receive(:data).and_return(usage_data, new_usage_data)
+
+ expect(described_class.for(output: :all_metrics_values)).to eq(usage_data)
+ expect(described_class.for(output: :all_metrics_values, cached: true)).to eq(usage_data)
+
+ expect(Rails.cache.fetch('usage_data')).to eq(usage_data)
+ end
+
+ it 'writes to cache and returns fresh data' do
+ allow(Gitlab::UsageData).to receive(:data).and_return(usage_data, new_usage_data)
+
+ expect(described_class.for(output: :all_metrics_values)).to eq(usage_data)
+ expect(described_class.for(output: :all_metrics_values)).to eq(new_usage_data)
+ expect(described_class.for(output: :all_metrics_values, cached: true)).to eq(new_usage_data)
+
+ expect(Rails.cache.fetch('usage_data')).to eq(new_usage_data)
+ end
+ end
+
+ context 'when no caching' do
+ let(:new_usage_data) { { uuid: "1112" } }
+
+ it 'returns fresh data' do
+ allow(Gitlab::UsageData).to receive(:data).and_return(usage_data, new_usage_data)
+
+ expect(described_class.for(output: :all_metrics_values)).to eq(usage_data)
+ expect(described_class.for(output: :all_metrics_values)).to eq(new_usage_data)
+
+ expect(Rails.cache.fetch('usage_data')).to eq(new_usage_data)
+ end
+ end
end
end
- context 'when using cached' do
- context 'for cached: true' do
- let(:new_usage_data) { { uuid: "1112" } }
+ context 'when feature merge_service_ping_instrumented_metrics disabled' do
+ before do
+ stub_feature_flags(merge_service_ping_instrumented_metrics: false)
+ end
- it 'caches the values' do
- allow(Gitlab::UsageData).to receive(:data).and_return(usage_data, new_usage_data)
+ context 'all_metrics_values' do
+ it 'generates the service ping when there are no missing values' do
+ expect(Gitlab::UsageData).to receive(:data).and_return(usage_data)
+ expect(described_class.for(output: :all_metrics_values)).to eq({ uuid: "1111", counts: { issue: 0 } })
+ end
+ end
- expect(described_class.for(output: :all_metrics_values)).to eq(usage_data)
- expect(described_class.for(output: :all_metrics_values, cached: true)).to eq(usage_data)
+ context 'for output: :metrics_queries' do
+ it 'generates the service ping' do
+ expect(Gitlab::UsageData).to receive(:data).and_return(usage_data)
- expect(Rails.cache.fetch('usage_data')).to eq(usage_data)
+ described_class.for(output: :metrics_queries)
end
+ end
- it 'writes to cache and returns fresh data' do
- allow(Gitlab::UsageData).to receive(:data).and_return(usage_data, new_usage_data)
+ context 'for output: :non_sql_metrics_values' do
+ it 'generates the service ping' do
+ expect(Gitlab::UsageData).to receive(:data).and_return(usage_data)
- expect(described_class.for(output: :all_metrics_values)).to eq(usage_data)
- expect(described_class.for(output: :all_metrics_values)).to eq(new_usage_data)
- expect(described_class.for(output: :all_metrics_values, cached: true)).to eq(new_usage_data)
+ described_class.for(output: :non_sql_metrics_values)
+ end
+ end
+ end
+
+ context 'cross test values against queries' do
+ # TODO: fix failing metrics https://gitlab.com/gitlab-org/gitlab/-/issues/353559
+ let(:failing_todo_metrics) do
+ ["counts.labels",
+ "counts.jira_imports_total_imported_issues_count",
+ "counts.in_product_marketing_email_create_0_sent",
+ "counts.in_product_marketing_email_create_0_cta_clicked",
+ "counts.in_product_marketing_email_create_1_sent",
+ "counts.in_product_marketing_email_create_1_cta_clicked",
+ "counts.in_product_marketing_email_create_2_sent",
+ "counts.in_product_marketing_email_create_2_cta_clicked",
+ "counts.in_product_marketing_email_verify_0_sent",
+ "counts.in_product_marketing_email_verify_0_cta_clicked",
+ "counts.in_product_marketing_email_verify_1_sent",
+ "counts.in_product_marketing_email_verify_1_cta_clicked",
+ "counts.in_product_marketing_email_verify_2_sent",
+ "counts.in_product_marketing_email_verify_2_cta_clicked",
+ "counts.in_product_marketing_email_trial_0_sent",
+ "counts.in_product_marketing_email_trial_0_cta_clicked",
+ "counts.in_product_marketing_email_trial_1_sent",
+ "counts.in_product_marketing_email_trial_1_cta_clicked",
+ "counts.in_product_marketing_email_trial_2_sent",
+ "counts.in_product_marketing_email_trial_2_cta_clicked",
+ "counts.in_product_marketing_email_team_0_sent",
+ "counts.in_product_marketing_email_team_0_cta_clicked",
+ "counts.in_product_marketing_email_team_1_sent",
+ "counts.in_product_marketing_email_team_1_cta_clicked",
+ "counts.in_product_marketing_email_team_2_sent",
+ "counts.in_product_marketing_email_team_2_cta_clicked",
+ "counts.in_product_marketing_email_experience_0_sent",
+ "counts.in_product_marketing_email_team_short_0_sent",
+ "counts.in_product_marketing_email_team_short_0_cta_clicked",
+ "counts.in_product_marketing_email_trial_short_0_sent",
+ "counts.in_product_marketing_email_trial_short_0_cta_clicked",
+ "counts.in_product_marketing_email_admin_verify_0_sent",
+ "counts.in_product_marketing_email_admin_verify_0_cta_clicked",
+ "counts.ldap_users",
+ "usage_activity_by_stage.create.projects_with_sectional_code_owner_rules",
+ "usage_activity_by_stage.monitor.clusters_integrations_prometheus",
+ "usage_activity_by_stage.monitor.projects_with_enabled_alert_integrations_histogram",
+ "usage_activity_by_stage_monthly.create.projects_with_sectional_code_owner_rules",
+ "usage_activity_by_stage_monthly.monitor.clusters_integrations_prometheus"]
+ end
- expect(Rails.cache.fetch('usage_data')).to eq(new_usage_data)
+ def fetch_value_by_query(query)
+ # Because test cases are run inside a transaction, if any query raise and error all queries that follows
+ # it are automatically canceled by PostgreSQL, to avoid that problem, and to provide exhaustive information
+ # about every metric, queries are wrapped explicitly in sub transactions.
+ ApplicationRecord.transaction do
+ ApplicationRecord.connection.execute(query)&.first&.values&.first
end
+ rescue ActiveRecord::StatementInvalid => e
+ e.message
+ end
+
+ def build_payload_from_queries(payload, accumulator = [], key_path = [])
+ payload.each do |key, value|
+ if value.is_a?(Hash)
+ build_payload_from_queries(value, accumulator, key_path.dup << key)
+ elsif value.is_a?(String) && /SELECT .* FROM.*/ =~ value
+ accumulator << [key_path.dup << key, value, fetch_value_by_query(value)]
+ end
+ end
+ accumulator
+ end
+
+ before do
+ stub_usage_data_connections
+ stub_object_store_settings
+ stub_prometheus_queries
+ memoized_constatns = Gitlab::UsageData::CE_MEMOIZED_VALUES
+ memoized_constatns += Gitlab::UsageData::EE_MEMOIZED_VALUES if defined? Gitlab::UsageData::EE_MEMOIZED_VALUES
+ memoized_constatns.each { |v| Gitlab::UsageData.clear_memoization(v) }
+ stub_database_flavor_check('Cloud SQL for PostgreSQL')
end
- context 'when no caching' do
- let(:new_usage_data) { { uuid: "1112" } }
+ let(:service_ping_payload) { described_class.for(output: :all_metrics_values) }
+ let(:metrics_queries_with_values) { build_payload_from_queries(described_class.for(output: :metrics_queries)) }
- it 'returns fresh data' do
- allow(Gitlab::UsageData).to receive(:data).and_return(usage_data, new_usage_data)
+ it 'generates queries that match collected data', :aggregate_failures do
+ message = "Expected %{query} result to match %{value} for %{key_path} metric"
- expect(described_class.for(output: :all_metrics_values)).to eq(usage_data)
- expect(described_class.for(output: :all_metrics_values)).to eq(new_usage_data)
+ metrics_queries_with_values.each do |key_path, query, value|
+ next if failing_todo_metrics.include?(key_path.join('.'))
- expect(Rails.cache.fetch('usage_data')).to eq(new_usage_data)
+ expect(value).to(
+ eq(service_ping_payload.dig(*key_path)),
+ message % { query: query, value: (value || 'NULL'), key_path: key_path.join('.') }
+ )
end
end
end
diff --git a/spec/lib/gitlab/usage_counters/pod_logs_spec.rb b/spec/lib/gitlab/usage_counters/pod_logs_spec.rb
new file mode 100644
index 00000000000..1059c519b19
--- /dev/null
+++ b/spec/lib/gitlab/usage_counters/pod_logs_spec.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::UsageCounters::PodLogs, :clean_gitlab_redis_shared_state do
+ it_behaves_like 'a usage counter'
+end
diff --git a/spec/lib/gitlab/usage_data_counters/hll_redis_counter_spec.rb b/spec/lib/gitlab/usage_data_counters/hll_redis_counter_spec.rb
index 5e74ea3293c..77cf94daa3f 100644
--- a/spec/lib/gitlab/usage_data_counters/hll_redis_counter_spec.rb
+++ b/spec/lib/gitlab/usage_data_counters/hll_redis_counter_spec.rb
@@ -50,7 +50,10 @@ RSpec.describe Gitlab::UsageDataCounters::HLLRedisCounter, :clean_gitlab_redis_s
'importer',
'network_policies',
'geo',
- 'growth'
+ 'growth',
+ 'work_items',
+ 'ci_users',
+ 'error_tracking'
)
end
end
diff --git a/spec/lib/gitlab/usage_data_counters/service_usage_data_counter_spec.rb b/spec/lib/gitlab/usage_data_counters/service_usage_data_counter_spec.rb
new file mode 100644
index 00000000000..ca6df5b260f
--- /dev/null
+++ b/spec/lib/gitlab/usage_data_counters/service_usage_data_counter_spec.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::UsageDataCounters::ServiceUsageDataCounter do
+ it_behaves_like 'a redis usage counter', 'Service Usage Data', :download_payload_click
+end
diff --git a/spec/lib/gitlab/usage_data_counters/work_item_activity_unique_counter_spec.rb b/spec/lib/gitlab/usage_data_counters/work_item_activity_unique_counter_spec.rb
new file mode 100644
index 00000000000..4561d898479
--- /dev/null
+++ b/spec/lib/gitlab/usage_data_counters/work_item_activity_unique_counter_spec.rb
@@ -0,0 +1,63 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::UsageDataCounters::WorkItemActivityUniqueCounter, :clean_gitlab_redis_shared_state do
+ let(:user) { build(:user, id: 1) }
+
+ shared_examples 'counter that does not track the event' do
+ it 'does not track the event' do
+ expect { 3.times { track_event } }.to not_change {
+ Gitlab::UsageDataCounters::HLLRedisCounter.unique_events(
+ event_names: event_name,
+ start_date: 2.weeks.ago,
+ end_date: 2.weeks.from_now
+ )
+ }
+ end
+ end
+
+ shared_examples 'work item unique counter' do
+ context 'when track_work_items_activity FF is enabled' do
+ it 'tracks a unique event only once' do
+ expect { 3.times { track_event } }.to change {
+ Gitlab::UsageDataCounters::HLLRedisCounter.unique_events(
+ event_names: event_name,
+ start_date: 2.weeks.ago,
+ end_date: 2.weeks.from_now
+ )
+ }.by(1)
+ end
+
+ context 'when author is nil' do
+ let(:user) { nil }
+
+ it_behaves_like 'counter that does not track the event'
+ end
+ end
+
+ context 'when track_work_items_activity FF is disabled' do
+ before do
+ stub_feature_flags(track_work_items_activity: false)
+ end
+
+ it_behaves_like 'counter that does not track the event'
+ end
+ end
+
+ describe '.track_work_item_created_action' do
+ subject(:track_event) { described_class.track_work_item_created_action(author: user) }
+
+ let(:event_name) { described_class::WORK_ITEM_CREATED }
+
+ it_behaves_like 'work item unique counter'
+ end
+
+ describe '.track_work_item_title_changed_action' do
+ subject(:track_event) { described_class.track_work_item_title_changed_action(author: user) }
+
+ let(:event_name) { described_class::WORK_ITEM_TITLE_CHANGED }
+
+ it_behaves_like 'work item unique counter'
+ end
+end
diff --git a/spec/lib/gitlab/usage_data_queries_spec.rb b/spec/lib/gitlab/usage_data_queries_spec.rb
index a8cf87d9364..c3ac9d7db90 100644
--- a/spec/lib/gitlab/usage_data_queries_spec.rb
+++ b/spec/lib/gitlab/usage_data_queries_spec.rb
@@ -45,6 +45,19 @@ RSpec.describe Gitlab::UsageDataQueries do
end
end
+ describe '.alt_usage_data' do
+ subject(:alt_usage_data) { described_class.alt_usage_data { 42 } }
+
+ it 'returns value when used with value' do
+ expect(described_class.alt_usage_data(1))
+ .to eq(alt_usage_data_value: 1)
+ end
+
+ it 'returns a stringified block for alt_usage_data with a block' do
+ expect(alt_usage_data[:alt_usage_data_block]).to start_with('#<Proc:')
+ end
+ end
+
describe '.sum' do
it 'returns the raw SQL' do
expect(described_class.sum(Issue, :weight)).to eq('SELECT SUM("issues"."weight") FROM "issues"')
diff --git a/spec/lib/gitlab/usage_data_spec.rb b/spec/lib/gitlab/usage_data_spec.rb
index bea07dd9c43..958df7baf72 100644
--- a/spec/lib/gitlab/usage_data_spec.rb
+++ b/spec/lib/gitlab/usage_data_spec.rb
@@ -507,6 +507,8 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
end
it 'gathers usage counts', :aggregate_failures do
+ stub_feature_flags(merge_service_ping_instrumented_metrics: false)
+
count_data = subject[:counts]
expect(count_data[:boards]).to eq(1)
expect(count_data[:projects]).to eq(4)
@@ -1098,6 +1100,20 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
expect(subject[:settings][:user_cap_feature_enabled]).to eq(Gitlab::CurrentSettings.new_user_signups_cap)
end
+ it 'reports status of the certificate_based_clusters feature flag as true' do
+ expect(subject[:settings][:certificate_based_clusters_ff]).to eq(true)
+ end
+
+ context 'with certificate_based_clusters disabled' do
+ before do
+ stub_feature_flags(certificate_based_clusters: false)
+ end
+
+ it 'reports status of the certificate_based_clusters feature flag as false' do
+ expect(subject[:settings][:certificate_based_clusters_ff]).to eq(false)
+ end
+ end
+
context 'snowplow stats' do
before do
stub_feature_flags(usage_data_instrumentation: false)
diff --git a/spec/lib/gitlab/utils/strong_memoize_spec.rb b/spec/lib/gitlab/utils/strong_memoize_spec.rb
index d9fa2e516e1..5350e090e2b 100644
--- a/spec/lib/gitlab/utils/strong_memoize_spec.rb
+++ b/spec/lib/gitlab/utils/strong_memoize_spec.rb
@@ -48,6 +48,36 @@ RSpec.describe Gitlab::Utils::StrongMemoize do
let(:value) { value }
it_behaves_like 'caching the value'
+
+ it 'raises exception for invalid key' do
+ expect { object.strong_memoize(10) { 20 } }.to raise_error /Invalid type of '10'/
+ end
+ end
+ end
+
+ context "memory allocation", type: :benchmark do
+ let(:value) { 'aaa' }
+
+ before do
+ object.method_name # warmup
+ end
+
+ [:method_name, "method_name"].each do |argument|
+ context "for #{argument.class}" do
+ it 'does allocate exactly one string when fetching value' do
+ expect do
+ object.strong_memoize(argument) { 10 }
+ end.to perform_allocation(1)
+ end
+
+ it 'does allocate exactly one string when storing value' do
+ object.clear_memoization(:method_name) # clear to force set
+
+ expect do
+ object.strong_memoize(argument) { 10 }
+ end.to perform_allocation(1)
+ end
+ end
end
end
end
diff --git a/spec/lib/gitlab/utils_spec.rb b/spec/lib/gitlab/utils_spec.rb
index ba6997adbf6..6b12fb4a84a 100644
--- a/spec/lib/gitlab/utils_spec.rb
+++ b/spec/lib/gitlab/utils_spec.rb
@@ -7,7 +7,7 @@ RSpec.describe Gitlab::Utils do
delegate :to_boolean, :boolean_to_yes_no, :slugify, :random_string, :which,
:ensure_array_from_string, :to_exclusive_sentence, :bytes_to_megabytes,
- :append_path, :check_path_traversal!, :allowlisted?, :check_allowed_absolute_path!, :decode_path, :ms_to_round_sec, to: :described_class
+ :append_path, :check_path_traversal!, :allowlisted?, :check_allowed_absolute_path!, :decode_path, :ms_to_round_sec, :check_allowed_absolute_path_and_path_traversal!, to: :described_class
describe '.check_path_traversal!' do
it 'detects path traversal in string without any separators' do
@@ -53,11 +53,80 @@ RSpec.describe Gitlab::Utils do
expect(check_path_traversal!('dir/.foo.rb')).to eq('dir/.foo.rb')
end
+ it 'logs potential path traversal attempts' do
+ expect(Gitlab::AppLogger).to receive(:warn).with(message: "Potential path traversal attempt detected", path: "..")
+ expect { check_path_traversal!('..') }.to raise_error(/Invalid path/)
+ end
+
+ it 'logs does nothing for a safe string' do
+ expect(Gitlab::AppLogger).not_to receive(:warn).with(message: "Potential path traversal attempt detected", path: "dir/.foo.rb")
+ expect(check_path_traversal!('dir/.foo.rb')).to eq('dir/.foo.rb')
+ end
+
it 'does nothing for a non-string' do
expect(check_path_traversal!(nil)).to be_nil
end
end
+ describe '.check_allowed_absolute_path_and_path_traversal!' do
+ let(:allowed_paths) { %w[/home/foo ./foo .test/foo ..test/foo dir/..foo.rb dir/.foo.rb] }
+
+ it 'detects path traversal in string without any separators' do
+ expect { check_allowed_absolute_path_and_path_traversal!('.', allowed_paths) }.to raise_error(/Invalid path/)
+ expect { check_allowed_absolute_path_and_path_traversal!('..', allowed_paths) }.to raise_error(/Invalid path/)
+ end
+
+ it 'detects path traversal at the start of the string' do
+ expect { check_allowed_absolute_path_and_path_traversal!('../foo', allowed_paths) }.to raise_error(/Invalid path/)
+ expect { check_allowed_absolute_path_and_path_traversal!('..\\foo', allowed_paths) }.to raise_error(/Invalid path/)
+ end
+
+ it 'detects path traversal at the start of the string, even to just the subdirectory' do
+ expect { check_allowed_absolute_path_and_path_traversal!('../', allowed_paths) }.to raise_error(/Invalid path/)
+ expect { check_allowed_absolute_path_and_path_traversal!('..\\', allowed_paths) }.to raise_error(/Invalid path/)
+ expect { check_allowed_absolute_path_and_path_traversal!('/../', allowed_paths) }.to raise_error(/Invalid path/)
+ expect { check_allowed_absolute_path_and_path_traversal!('\\..\\', allowed_paths) }.to raise_error(/Invalid path/)
+ end
+
+ it 'detects path traversal in the middle of the string' do
+ expect { check_allowed_absolute_path_and_path_traversal!('foo/../../bar', allowed_paths) }.to raise_error(/Invalid path/)
+ expect { check_allowed_absolute_path_and_path_traversal!('foo\\..\\..\\bar', allowed_paths) }.to raise_error(/Invalid path/)
+ expect { check_allowed_absolute_path_and_path_traversal!('foo/..\\bar', allowed_paths) }.to raise_error(/Invalid path/)
+ expect { check_allowed_absolute_path_and_path_traversal!('foo\\../bar', allowed_paths) }.to raise_error(/Invalid path/)
+ expect { check_allowed_absolute_path_and_path_traversal!('foo/..\\..\\..\\..\\../bar', allowed_paths) }.to raise_error(/Invalid path/)
+ end
+
+ it 'detects path traversal at the end of the string when slash-terminates' do
+ expect { check_allowed_absolute_path_and_path_traversal!('foo/../', allowed_paths) }.to raise_error(/Invalid path/)
+ expect { check_allowed_absolute_path_and_path_traversal!('foo\\..\\', allowed_paths) }.to raise_error(/Invalid path/)
+ end
+
+ it 'detects path traversal at the end of the string' do
+ expect { check_allowed_absolute_path_and_path_traversal!('foo/..', allowed_paths) }.to raise_error(/Invalid path/)
+ expect { check_allowed_absolute_path_and_path_traversal!('foo\\..', allowed_paths) }.to raise_error(/Invalid path/)
+ end
+
+ it 'does not return errors for a safe string' do
+ expect(check_allowed_absolute_path_and_path_traversal!('./foo', allowed_paths)).to be_nil
+ expect(check_allowed_absolute_path_and_path_traversal!('.test/foo', allowed_paths)).to be_nil
+ expect(check_allowed_absolute_path_and_path_traversal!('..test/foo', allowed_paths)).to be_nil
+ expect(check_allowed_absolute_path_and_path_traversal!('dir/..foo.rb', allowed_paths)).to be_nil
+ expect(check_allowed_absolute_path_and_path_traversal!('dir/.foo.rb', allowed_paths)).to be_nil
+ end
+
+ it 'raises error for a non-string' do
+ expect {check_allowed_absolute_path_and_path_traversal!(nil, allowed_paths)}.to raise_error(StandardError)
+ end
+
+ it 'raises an exception if an absolute path is not allowed' do
+ expect { check_allowed_absolute_path!('/etc/passwd', allowed_paths) }.to raise_error(StandardError)
+ end
+
+ it 'does nothing for an allowed absolute path' do
+ expect(check_allowed_absolute_path!('/home/foo', allowed_paths)).to be_nil
+ end
+ end
+
describe '.allowlisted?' do
let(:allowed_paths) { ['/home/foo', '/foo/bar', '/etc/passwd']}
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 3152dc2ad2f..c0629c8d795 100644
--- a/spec/lib/gitlab/wiki_pages/front_matter_parser_spec.rb
+++ b/spec/lib/gitlab/wiki_pages/front_matter_parser_spec.rb
@@ -3,11 +3,10 @@
require 'spec_helper'
RSpec.describe Gitlab::WikiPages::FrontMatterParser do
- subject(:parser) { described_class.new(raw_content, gate) }
+ subject(:parser) { described_class.new(raw_content) }
let(:content) { 'This is the content' }
let(:end_divider) { '---' }
- let(:gate) { stub_feature_flag_gate('Gate') }
let(:with_front_matter) do
<<~MD
@@ -62,32 +61,6 @@ RSpec.describe Gitlab::WikiPages::FrontMatterParser do
it { is_expected.to have_attributes(reason: :no_match) }
end
- context 'the feature flag is disabled' do
- let(:raw_content) { with_front_matter }
-
- before do
- stub_feature_flags(Gitlab::WikiPages::FrontMatterParser::FEATURE_FLAG => false)
- end
-
- it { is_expected.to have_attributes(front_matter: be_empty, content: raw_content) }
- end
-
- context 'the feature flag is enabled for the gated object' do
- let(:raw_content) { with_front_matter }
-
- before do
- stub_feature_flags(Gitlab::WikiPages::FrontMatterParser::FEATURE_FLAG => gate)
- end
-
- it do
- is_expected.to have_attributes(
- front_matter: have_correct_front_matter,
- content: content + "\n",
- reason: be_nil
- )
- end
- end
-
context 'the end divider is ...' do
let(:end_divider) { '...' }
let(:raw_content) { with_front_matter }
diff --git a/spec/lib/gitlab_spec.rb b/spec/lib/gitlab_spec.rb
index 57a4bdc9bb5..c44bb64a5c0 100644
--- a/spec/lib/gitlab_spec.rb
+++ b/spec/lib/gitlab_spec.rb
@@ -80,34 +80,53 @@ RSpec.describe Gitlab do
end
describe '.com?' do
- it "is true when on #{Gitlab::Saas.com_url}" do
- stub_config_setting(url: Gitlab::Saas.com_url)
+ context 'when not simulating SaaS' do
+ before do
+ stub_env('GITLAB_SIMULATE_SAAS', '0')
+ end
- expect(described_class.com?).to eq true
- end
+ it "is true when on #{Gitlab::Saas.com_url}" do
+ stub_config_setting(url: Gitlab::Saas.com_url)
- it "is true when on #{Gitlab::Saas.staging_com_url}" do
- stub_config_setting(url: Gitlab::Saas.staging_com_url)
+ expect(described_class.com?).to eq true
+ end
- expect(described_class.com?).to eq true
- end
+ it "is true when on #{Gitlab::Saas.staging_com_url}" do
+ stub_config_setting(url: Gitlab::Saas.staging_com_url)
- it 'is true when on other gitlab subdomain' do
- url_with_subdomain = Gitlab::Saas.com_url.gsub('https://', 'https://example.')
- stub_config_setting(url: url_with_subdomain)
+ expect(described_class.com?).to eq true
+ end
- expect(described_class.com?).to eq true
+ it 'is true when on other gitlab subdomain' do
+ url_with_subdomain = Gitlab::Saas.com_url.gsub('https://', 'https://example.')
+ stub_config_setting(url: url_with_subdomain)
+
+ expect(described_class.com?).to eq true
+ end
+
+ it 'is true when on other gitlab subdomain with hyphen' do
+ url_with_subdomain = Gitlab::Saas.com_url.gsub('https://', 'https://test-example.')
+ stub_config_setting(url: url_with_subdomain)
+
+ expect(described_class.com?).to eq true
+ end
+
+ it 'is false when not on GitLab.com' do
+ stub_config_setting(url: 'http://example.com')
+
+ expect(described_class.com?).to eq false
+ end
end
- it 'is true when on other gitlab subdomain with hyphen' do
- url_with_subdomain = Gitlab::Saas.com_url.gsub('https://', 'https://test-example.')
- stub_config_setting(url: url_with_subdomain)
+ it 'is true when GITLAB_SIMULATE_SAAS is true and in development' do
+ stub_rails_env('development')
+ stub_env('GITLAB_SIMULATE_SAAS', '1')
expect(described_class.com?).to eq true
end
- it 'is false when not on GitLab.com' do
- stub_config_setting(url: 'http://example.com')
+ it 'is false when GITLAB_SIMULATE_SAAS is true and in test' do
+ stub_env('GITLAB_SIMULATE_SAAS', '1')
expect(described_class.com?).to eq false
end
@@ -197,51 +216,71 @@ RSpec.describe Gitlab do
end
end
- describe '.dev_env_org_or_com?' do
+ describe '.org_or_com?' do
it 'is true when on .com' do
allow(described_class).to receive_messages(com?: true, org?: false)
- expect(described_class.dev_env_org_or_com?).to eq true
+ expect(described_class.org_or_com?).to eq true
end
it 'is true when org' do
allow(described_class).to receive_messages(com?: false, org?: true)
- expect(described_class.dev_env_org_or_com?).to eq true
- end
-
- it 'is true when dev env' do
- allow(described_class).to receive_messages(com?: false, org?: false)
- stub_rails_env('development')
-
- expect(described_class.dev_env_org_or_com?).to eq true
+ expect(described_class.org_or_com?).to eq true
end
it 'is false when not dev, org or com' do
allow(described_class).to receive_messages(com?: false, org?: false)
- expect(described_class.dev_env_org_or_com?).to eq false
+ expect(described_class.org_or_com?).to eq false
end
end
- describe '.dev_env_or_com?' do
- it 'is true when on .com' do
- allow(described_class).to receive(:com?).and_return(true)
+ describe '.simulate_com?' do
+ subject { described_class.simulate_com? }
- expect(described_class.dev_env_or_com?).to eq true
- end
+ context 'when GITLAB_SIMULATE_SAAS is true' do
+ before do
+ stub_env('GITLAB_SIMULATE_SAAS', '1')
+ end
- it 'is true when dev env' do
- allow(described_class).to receive(:com?).and_return(false)
- allow(Rails).to receive(:env).and_return(ActiveSupport::StringInquirer.new('development'))
+ it 'is false when test env' do
+ expect(subject).to eq false
+ end
+
+ it 'is true when dev env' do
+ stub_rails_env('development')
+
+ expect(subject).to eq true
+ end
+
+ it 'is false when env is not dev' do
+ stub_rails_env('production')
- expect(described_class.dev_env_or_com?).to eq true
+ expect(subject).to eq false
+ end
end
- it 'is false when not dev or com' do
- allow(described_class).to receive(:com?).and_return(false)
+ context 'when GITLAB_SIMULATE_SAAS is false' do
+ before do
+ stub_env('GITLAB_SIMULATE_SAAS', '0')
+ end
+
+ it 'is false when test env' do
+ expect(subject).to eq false
+ end
+
+ it 'is false when dev env' do
+ stub_rails_env('development')
+
+ expect(subject).to eq false
+ end
+
+ it 'is false when env is not dev or test' do
+ stub_rails_env('production')
- expect(described_class.dev_env_or_com?).to eq false
+ expect(subject).to eq false
+ end
end
end
diff --git a/spec/lib/google_api/cloud_platform/client_spec.rb b/spec/lib/google_api/cloud_platform/client_spec.rb
index 29e5445cfaa..a81ed38382b 100644
--- a/spec/lib/google_api/cloud_platform/client_spec.rb
+++ b/spec/lib/google_api/cloud_platform/client_spec.rb
@@ -334,4 +334,20 @@ RSpec.describe GoogleApi::CloudPlatform::Client do
is_expected.to eq(operation)
end
end
+
+ describe '#revoke_authorizations' do
+ subject { client.revoke_authorizations }
+
+ it 'calls the revoke endpoint' do
+ stub_request(:post, "https://oauth2.googleapis.com/revoke")
+ .with(
+ body: "token=token",
+ headers: {
+ 'Accept' => '*/*',
+ 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3',
+ 'User-Agent' => 'Ruby'
+ })
+ .to_return(status: 200, body: "", headers: {})
+ end
+ end
end
diff --git a/spec/lib/learn_gitlab/onboarding_spec.rb b/spec/lib/learn_gitlab/onboarding_spec.rb
index 6b4be65f3b2..8c7284ed7f5 100644
--- a/spec/lib/learn_gitlab/onboarding_spec.rb
+++ b/spec/lib/learn_gitlab/onboarding_spec.rb
@@ -9,7 +9,7 @@ RSpec.describe LearnGitlab::Onboarding do
let(:namespace) { build(:namespace) }
let_it_be(:tracked_action_columns) do
- tracked_actions = described_class::ACTION_ISSUE_IDS.keys + described_class::ACTION_DOC_URLS.keys
+ tracked_actions = described_class::ACTION_ISSUE_IDS.keys + described_class::ACTION_PATHS
tracked_actions.map { |key| OnboardingProgress.column_name(key) }
end
diff --git a/spec/lib/learn_gitlab/project_spec.rb b/spec/lib/learn_gitlab/project_spec.rb
index 5d649740c65..23784709817 100644
--- a/spec/lib/learn_gitlab/project_spec.rb
+++ b/spec/lib/learn_gitlab/project_spec.rb
@@ -5,7 +5,6 @@ require 'spec_helper'
RSpec.describe LearnGitlab::Project do
let_it_be(:current_user) { create(:user) }
let_it_be(:learn_gitlab_project) { create(:project, name: LearnGitlab::Project::PROJECT_NAME) }
- let_it_be(:learn_gitlab_ultimate_trial_project) { create(:project, name: LearnGitlab::Project::PROJECT_NAME_ULTIMATE_TRIAL) }
let_it_be(:learn_gitlab_board) { create(:board, project: learn_gitlab_project, name: LearnGitlab::Project::BOARD_NAME) }
let_it_be(:learn_gitlab_label) { create(:label, project: learn_gitlab_project, name: LearnGitlab::Project::LABEL_NAME) }
@@ -48,7 +47,7 @@ RSpec.describe LearnGitlab::Project do
it { is_expected.to eq learn_gitlab_project }
context 'when it is created during trial signup' do
- let_it_be(:learn_gitlab_project) { create(:project, name: LearnGitlab::Project::PROJECT_NAME_ULTIMATE_TRIAL) }
+ let_it_be(:learn_gitlab_project) { create(:project, name: LearnGitlab::Project::PROJECT_NAME_ULTIMATE_TRIAL, path: 'learn-gitlab-ultimate-trial') }
it { is_expected.to eq learn_gitlab_project }
end
diff --git a/spec/lib/peek/views/active_record_spec.rb b/spec/lib/peek/views/active_record_spec.rb
index c89f6a21b35..7bc15f40065 100644
--- a/spec/lib/peek/views/active_record_spec.rb
+++ b/spec/lib/peek/views/active_record_spec.rb
@@ -119,16 +119,4 @@ RSpec.describe Peek::Views::ActiveRecord, :request_store do
)
)
end
-
- context 'when the GITLAB_MULTIPLE_DATABASE_METRICS env var is disabled' do
- before do
- stub_env('GITLAB_MULTIPLE_DATABASE_METRICS', nil)
- end
-
- it 'does not include db_config_name field' do
- ActiveSupport::Notifications.publish('sql.active_record', Time.current, Time.current + 1.second, '1', event_1)
-
- expect(subject.results[:details][0][:db_config_name]).to be_nil
- end
- end
end
diff --git a/spec/lib/security/ci_configuration/sast_build_action_spec.rb b/spec/lib/security/ci_configuration/sast_build_action_spec.rb
index 6f702e51b73..efb8b0b9984 100644
--- a/spec/lib/security/ci_configuration/sast_build_action_spec.rb
+++ b/spec/lib/security/ci_configuration/sast_build_action_spec.rb
@@ -6,7 +6,7 @@ RSpec.describe Security::CiConfiguration::SastBuildAction do
let(:default_sast_values) do
{ 'global' =>
[
- { 'field' => 'SECURE_ANALYZERS_PREFIX', 'defaultValue' => 'registry.gitlab.com/gitlab-org/security-products/analyzers', 'value' => 'registry.gitlab.com/gitlab-org/security-products/analyzers' }
+ { 'field' => 'SECURE_ANALYZERS_PREFIX', 'defaultValue' => 'registry.gitlab.com/security-products', 'value' => 'registry.gitlab.com/security-products' }
],
'pipeline' =>
[
@@ -19,7 +19,7 @@ RSpec.describe Security::CiConfiguration::SastBuildAction do
let(:params) do
{ 'global' =>
[
- { 'field' => 'SECURE_ANALYZERS_PREFIX', 'defaultValue' => 'registry.gitlab.com/gitlab-org/security-products/analyzers', 'value' => 'new_registry' }
+ { 'field' => 'SECURE_ANALYZERS_PREFIX', 'defaultValue' => 'registry.gitlab.com/security-products', 'value' => 'new_registry' }
],
'pipeline' =>
[
@@ -164,7 +164,7 @@ RSpec.describe Security::CiConfiguration::SastBuildAction do
let(:params) do
{ 'global' =>
[
- { 'field' => 'SECURE_ANALYZERS_PREFIX', 'defaultValue' => 'registry.gitlab.com/gitlab-org/security-products/analyzers', 'value' => 'registry.gitlab.com/gitlab-org/security-products/analyzers' }
+ { 'field' => 'SECURE_ANALYZERS_PREFIX', 'defaultValue' => 'registry.gitlab.com/security-products', 'value' => 'registry.gitlab.com/security-products' }
],
'pipeline' =>
[
@@ -275,7 +275,7 @@ RSpec.describe Security::CiConfiguration::SastBuildAction do
let(:params) do
{ 'global' =>
[
- { 'field' => 'SECURE_ANALYZERS_PREFIX', 'defaultValue' => 'registry.gitlab.com/gitlab-org/security-products/analyzers', 'value' => '' }
+ { 'field' => 'SECURE_ANALYZERS_PREFIX', 'defaultValue' => 'registry.gitlab.com/security-products', 'value' => '' }
] }
end
diff --git a/spec/lib/security/ci_configuration/sast_iac_build_action_spec.rb b/spec/lib/security/ci_configuration/sast_iac_build_action_spec.rb
index 4c459058368..7b2a0d22918 100644
--- a/spec/lib/security/ci_configuration/sast_iac_build_action_spec.rb
+++ b/spec/lib/security/ci_configuration/sast_iac_build_action_spec.rb
@@ -7,12 +7,13 @@ RSpec.describe Security::CiConfiguration::SastIacBuildAction do
let(:params) { {} }
- context 'with existing .gitlab-ci.yml' do
- let(:auto_devops_enabled) { false }
+ shared_examples 'existing .gitlab-ci.yml tests' do
+ context 'with existing .gitlab-ci.yml' do
+ let(:auto_devops_enabled) { false }
- context 'sast iac has not been included' do
- let(:expected_yml) do
- <<-CI_YML.strip_heredoc
+ context 'sast iac has not been included' do
+ let(:expected_yml) do
+ <<-CI_YML.strip_heredoc
# You can override the included template(s) by including variable overrides
# SAST customization: https://docs.gitlab.com/ee/user/application_security/sast/#customizing-the-sast-settings
# Secret Detection customization: https://docs.gitlab.com/ee/user/application_security/secret_detection/#customizing-settings
@@ -28,39 +29,39 @@ RSpec.describe Security::CiConfiguration::SastIacBuildAction do
include:
- template: existing.yml
- template: Security/SAST-IaC.latest.gitlab-ci.yml
- CI_YML
- end
-
- context 'template includes are an array' do
- let(:gitlab_ci_content) do
- { "stages" => %w(test security),
- "variables" => { "RANDOM" => "make sure this persists" },
- "include" => [{ "template" => "existing.yml" }] }
+ CI_YML
end
- it 'generates the correct YML' do
- expect(result[:action]).to eq('update')
- expect(result[:content]).to eq(expected_yml)
- end
- end
-
- context 'template include is not an array' do
- let(:gitlab_ci_content) do
- { "stages" => %w(test security),
- "variables" => { "RANDOM" => "make sure this persists" },
- "include" => { "template" => "existing.yml" } }
+ context 'template includes are an array' do
+ let(:gitlab_ci_content) do
+ { "stages" => %w(test security),
+ "variables" => { "RANDOM" => "make sure this persists" },
+ "include" => [{ "template" => "existing.yml" }] }
+ end
+
+ it 'generates the correct YML' do
+ expect(result[:action]).to eq('update')
+ expect(result[:content]).to eq(expected_yml)
+ end
end
- it 'generates the correct YML' do
- expect(result[:action]).to eq('update')
- expect(result[:content]).to eq(expected_yml)
+ context 'template include is not an array' do
+ let(:gitlab_ci_content) do
+ { "stages" => %w(test security),
+ "variables" => { "RANDOM" => "make sure this persists" },
+ "include" => { "template" => "existing.yml" } }
+ end
+
+ it 'generates the correct YML' do
+ expect(result[:action]).to eq('update')
+ expect(result[:content]).to eq(expected_yml)
+ end
end
end
- end
- context 'secret_detection has been included' do
- let(:expected_yml) do
- <<-CI_YML.strip_heredoc
+ context 'secret_detection has been included' do
+ let(:expected_yml) do
+ <<-CI_YML.strip_heredoc
# You can override the included template(s) by including variable overrides
# SAST customization: https://docs.gitlab.com/ee/user/application_security/sast/#customizing-the-sast-settings
# Secret Detection customization: https://docs.gitlab.com/ee/user/application_security/secret_detection/#customizing-settings
@@ -74,37 +75,50 @@ RSpec.describe Security::CiConfiguration::SastIacBuildAction do
RANDOM: make sure this persists
include:
- template: Security/SAST-IaC.latest.gitlab-ci.yml
- CI_YML
- end
-
- context 'secret_detection template include are an array' do
- let(:gitlab_ci_content) do
- { "stages" => %w(test),
- "variables" => { "RANDOM" => "make sure this persists" },
- "include" => [{ "template" => "Security/SAST-IaC.latest.gitlab-ci.yml" }] }
+ CI_YML
end
- it 'generates the correct YML' do
- expect(result[:action]).to eq('update')
- expect(result[:content]).to eq(expected_yml)
- end
- end
-
- context 'secret_detection template include is not an array' do
- let(:gitlab_ci_content) do
- { "stages" => %w(test),
- "variables" => { "RANDOM" => "make sure this persists" },
- "include" => { "template" => "Security/SAST-IaC.latest.gitlab-ci.yml" } }
+ context 'secret_detection template include are an array' do
+ let(:gitlab_ci_content) do
+ { "stages" => %w(test),
+ "variables" => { "RANDOM" => "make sure this persists" },
+ "include" => [{ "template" => "Security/SAST-IaC.latest.gitlab-ci.yml" }] }
+ end
+
+ it 'generates the correct YML' do
+ expect(result[:action]).to eq('update')
+ expect(result[:content]).to eq(expected_yml)
+ end
end
- it 'generates the correct YML' do
- expect(result[:action]).to eq('update')
- expect(result[:content]).to eq(expected_yml)
+ context 'secret_detection template include is not an array' do
+ let(:gitlab_ci_content) do
+ { "stages" => %w(test),
+ "variables" => { "RANDOM" => "make sure this persists" },
+ "include" => { "template" => "Security/SAST-IaC.latest.gitlab-ci.yml" } }
+ end
+
+ it 'generates the correct YML' do
+ expect(result[:action]).to eq('update')
+ expect(result[:content]).to eq(expected_yml)
+ end
end
end
end
end
+ context 'with existing .gitlab-ci.yml and when the ci config file configuration was not set' do
+ subject(:result) { described_class.new(auto_devops_enabled, gitlab_ci_content).generate }
+
+ it_behaves_like 'existing .gitlab-ci.yml tests'
+ end
+
+ context 'with existing .gitlab-ci.yml and when the ci config file configuration was deleted' do
+ subject(:result) { described_class.new(auto_devops_enabled, gitlab_ci_content, ci_config_path: '').generate }
+
+ it_behaves_like 'existing .gitlab-ci.yml tests'
+ end
+
context 'with no .gitlab-ci.yml' do
let(:gitlab_ci_content) { nil }
diff --git a/spec/lib/serializers/unsafe_json_spec.rb b/spec/lib/serializers/unsafe_json_spec.rb
new file mode 100644
index 00000000000..9bf04f8f4aa
--- /dev/null
+++ b/spec/lib/serializers/unsafe_json_spec.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+require 'fast_spec_helper'
+require 'oj'
+
+RSpec.describe Serializers::UnsafeJson do
+ let(:result) { double(:result) }
+
+ describe '.dump' do
+ let(:obj) { { key: "value" } }
+
+ it 'calls object#to_json with unsafe: true and returns the result' do
+ expect(obj).to receive(:to_json).with(unsafe: true).and_return(result)
+ expect(described_class.dump(obj)).to eq(result)
+ end
+ end
+
+ describe '.load' do
+ let(:data_string) { '{"key":"value","variables":[{"key":"VAR1","value":"VALUE1"}]}' }
+ let(:data_hash) { Gitlab::Json.parse(data_string) }
+
+ it 'calls JSON.load and returns the result' do
+ expect(JSON).to receive(:load).with(data_hash).and_return(result)
+ expect(described_class.load(data_hash)).to eq(result)
+ end
+ end
+end
diff --git a/spec/lib/sidebars/concerns/work_item_hierarchy_spec.rb b/spec/lib/sidebars/concerns/work_item_hierarchy_spec.rb
deleted file mode 100644
index 2120341bf23..00000000000
--- a/spec/lib/sidebars/concerns/work_item_hierarchy_spec.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Sidebars::Concerns::WorkItemHierarchy do
- shared_examples 'hierarchy menu' do
- let(:item_id) { :hierarchy }
- specify { is_expected.not_to be_nil }
- end
-
- describe 'Project hierarchy menu item' do
- let_it_be_with_reload(:project) { create(:project, :repository) }
-
- let(:user) { project.owner }
- let(:context) { Sidebars::Projects::Context.new(current_user: user, container: project) }
-
- subject { Sidebars::Projects::Menus::ProjectInformationMenu.new(context).renderable_items.index { |e| e.item_id == item_id } }
-
- it_behaves_like 'hierarchy menu'
- end
-end
diff --git a/spec/lib/sidebars/groups/menus/kubernetes_menu_spec.rb b/spec/lib/sidebars/groups/menus/kubernetes_menu_spec.rb
index 76e58367c9d..36d5b3376b7 100644
--- a/spec/lib/sidebars/groups/menus/kubernetes_menu_spec.rb
+++ b/spec/lib/sidebars/groups/menus/kubernetes_menu_spec.rb
@@ -28,5 +28,15 @@ RSpec.describe Sidebars::Groups::Menus::KubernetesMenu do
expect(menu.render?).to eq false
end
end
+
+ context ':certificate_based_clusters feature flag is disabled' do
+ before do
+ stub_feature_flags(certificate_based_clusters: false)
+ end
+
+ it 'returns false' do
+ expect(menu.render?).to eq false
+ end
+ end
end
end
diff --git a/spec/lib/sidebars/groups/menus/packages_registries_menu_spec.rb b/spec/lib/sidebars/groups/menus/packages_registries_menu_spec.rb
index bc1fa3e88ff..d3cb18222b5 100644
--- a/spec/lib/sidebars/groups/menus/packages_registries_menu_spec.rb
+++ b/spec/lib/sidebars/groups/menus/packages_registries_menu_spec.rb
@@ -23,6 +23,7 @@ RSpec.describe Sidebars::Groups::Menus::PackagesRegistriesMenu do
context 'when menu does not have any menu item to show' do
it 'returns false' do
+ stub_feature_flags(harbor_registry_integration: false)
stub_container_registry_config(enabled: false)
stub_config(packages: { enabled: false })
stub_config(dependency_proxy: { enabled: false })
@@ -35,11 +36,13 @@ RSpec.describe Sidebars::Groups::Menus::PackagesRegistriesMenu do
describe '#link' do
let(:registry_enabled) { true }
let(:packages_enabled) { true }
+ let(:harbor_registry_integration) { true }
before do
stub_container_registry_config(enabled: registry_enabled)
stub_config(packages: { enabled: packages_enabled })
stub_config(dependency_proxy: { enabled: true })
+ stub_feature_flags(harbor_registry_integration: harbor_registry_integration)
end
subject { menu.link }
@@ -60,8 +63,16 @@ RSpec.describe Sidebars::Groups::Menus::PackagesRegistriesMenu do
context 'when Container Registry is not visible' do
let(:registry_enabled) { false }
- it 'menu link points to Dependency Proxy page' do
- expect(subject).to eq find_menu(menu, :dependency_proxy).link
+ it 'menu link points to Harbor Registry page' do
+ expect(subject).to eq find_menu(menu, :harbor_registry).link
+ end
+
+ context 'when Harbor Registry is not visible' do
+ let(:harbor_registry_integration) { false }
+
+ it 'menu link points to Dependency Proxy page' do
+ expect(subject).to eq find_menu(menu, :dependency_proxy).link
+ end
end
end
end
@@ -175,6 +186,26 @@ RSpec.describe Sidebars::Groups::Menus::PackagesRegistriesMenu do
it_behaves_like 'the menu entry is not available'
end
end
+
+ describe 'Harbor Registry' do
+ let(:item_id) { :harbor_registry }
+
+ before do
+ stub_feature_flags(harbor_registry_integration: harbor_registry_enabled)
+ end
+
+ context 'when config harbor registry setting is disabled' do
+ let(:harbor_registry_enabled) { false }
+
+ it_behaves_like 'the menu entry is not available'
+ end
+
+ context 'when config harbor registry setting is enabled' do
+ let(:harbor_registry_enabled) { true }
+
+ it_behaves_like 'the menu entry is available'
+ end
+ end
end
private
diff --git a/spec/lib/sidebars/groups/menus/settings_menu_spec.rb b/spec/lib/sidebars/groups/menus/settings_menu_spec.rb
index 252da8ea699..71b696516b6 100644
--- a/spec/lib/sidebars/groups/menus/settings_menu_spec.rb
+++ b/spec/lib/sidebars/groups/menus/settings_menu_spec.rb
@@ -72,6 +72,18 @@ RSpec.describe Sidebars::Groups::Menus::SettingsMenu do
let(:item_id) { :ci_cd }
it_behaves_like 'access rights checks'
+
+ describe 'when runner list group view is disabled' do
+ before do
+ stub_feature_flags(runner_list_group_view_vue_ui: false)
+ end
+
+ it_behaves_like 'access rights checks'
+
+ it 'has group runners as active_routes' do
+ expect(subject.active_routes[:path]).to match_array %w[ci_cd#show groups/runners#show groups/runners#edit]
+ end
+ end
end
describe 'Applications menu' do
diff --git a/spec/lib/sidebars/projects/menus/infrastructure_menu_spec.rb b/spec/lib/sidebars/projects/menus/infrastructure_menu_spec.rb
index 0e415ec6014..8a6b0e4e95d 100644
--- a/spec/lib/sidebars/projects/menus/infrastructure_menu_spec.rb
+++ b/spec/lib/sidebars/projects/menus/infrastructure_menu_spec.rb
@@ -92,6 +92,14 @@ RSpec.describe Sidebars::Projects::Menus::InfrastructureMenu do
let(:item_id) { :serverless }
it_behaves_like 'access rights checks'
+
+ context 'when feature :deprecated_serverless is disabled' do
+ before do
+ stub_feature_flags(deprecated_serverless: false)
+ end
+
+ it { is_expected.to be_nil }
+ end
end
describe 'Terraform' do
diff --git a/spec/lib/sidebars/projects/menus/packages_registries_menu_spec.rb b/spec/lib/sidebars/projects/menus/packages_registries_menu_spec.rb
index afe0b2a8951..9b78fc807bf 100644
--- a/spec/lib/sidebars/projects/menus/packages_registries_menu_spec.rb
+++ b/spec/lib/sidebars/projects/menus/packages_registries_menu_spec.rb
@@ -33,6 +33,7 @@ RSpec.describe Sidebars::Projects::Menus::PackagesRegistriesMenu do
before do
stub_container_registry_config(enabled: registry_enabled)
stub_config(packages: { enabled: packages_enabled })
+ stub_feature_flags(harbor_registry_integration: false)
end
context 'when Packages Registry is visible' do
@@ -144,5 +145,25 @@ RSpec.describe Sidebars::Projects::Menus::PackagesRegistriesMenu do
end
end
end
+
+ describe 'Harbor Registry' do
+ let(:item_id) { :harbor_registry }
+
+ context 'when config harbor registry setting is disabled' do
+ it 'does not add the menu item to the list' do
+ stub_feature_flags(harbor_registry_integration: false)
+
+ is_expected.to be_nil
+ end
+ end
+
+ context 'when config harbor registry setting is enabled' do
+ it 'the menu item is added to list of menu items' do
+ stub_feature_flags(harbor_registry_integration: true)
+
+ is_expected.not_to be_nil
+ end
+ end
+ end
end
end
diff --git a/spec/lib/sidebars/projects/menus/project_information_menu_spec.rb b/spec/lib/sidebars/projects/menus/project_information_menu_spec.rb
index 24625413ded..7ff06ac229e 100644
--- a/spec/lib/sidebars/projects/menus/project_information_menu_spec.rb
+++ b/spec/lib/sidebars/projects/menus/project_information_menu_spec.rb
@@ -59,11 +59,5 @@ RSpec.describe Sidebars::Projects::Menus::ProjectInformationMenu do
specify { is_expected.to be_nil }
end
end
-
- describe 'Hierarchy' do
- let(:item_id) { :hierarchy }
-
- specify { is_expected.not_to be_nil }
- end
end
end
diff --git a/spec/mailers/emails/profile_spec.rb b/spec/mailers/emails/profile_spec.rb
index af77989dbbc..1c4e4a670b4 100644
--- a/spec/mailers/emails/profile_spec.rb
+++ b/spec/mailers/emails/profile_spec.rb
@@ -123,6 +123,39 @@ RSpec.describe Emails::Profile do
end
end
+ describe 'user personal access token has been created' do
+ let_it_be(:user) { create(:user) }
+ let_it_be(:token) { create(:personal_access_token, user: user) }
+
+ context 'when valid' do
+ subject { Notify.access_token_created_email(user, token.name) }
+
+ 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
+ is_expected.to deliver_to user.email
+ end
+
+ it 'has the correct subject' do
+ is_expected.to have_subject /^A new personal access token has been created$/i
+ end
+
+ it 'provides the names of the token' do
+ is_expected.to have_body_text /#{token.name}/
+ end
+
+ it 'includes a link to personal access tokens page' do
+ is_expected.to have_body_text /#{profile_personal_access_tokens_path}/
+ end
+
+ it 'includes the email reason' do
+ is_expected.to have_body_text /You're receiving this email because of your account on localhost/
+ end
+ end
+ end
+
describe 'user personal access token is about to expire' do
let_it_be(:user) { create(:user) }
let_it_be(:expiring_token) { create(:personal_access_token, user: user, expires_at: 5.days.from_now) }
diff --git a/spec/metrics_server/metrics_server_spec.rb b/spec/metrics_server/metrics_server_spec.rb
index 860a3299d85..591840dcba2 100644
--- a/spec/metrics_server/metrics_server_spec.rb
+++ b/spec/metrics_server/metrics_server_spec.rb
@@ -1,13 +1,10 @@
# frozen_string_literal: true
-require 'fast_spec_helper'
+require 'spec_helper'
require_relative '../../metrics_server/metrics_server'
-require_relative '../support/helpers/next_instance_of'
RSpec.describe MetricsServer do # rubocop:disable RSpec/FilePath
- include NextInstanceOf
-
let(:prometheus_config) { ::Prometheus::Client.configuration }
let(:metrics_dir) { Dir.mktmpdir }
@@ -205,4 +202,47 @@ RSpec.describe MetricsServer do # rubocop:disable RSpec/FilePath
it_behaves_like 'a metrics exporter', 'sidekiq', 'sidekiq_exporter'
end
+
+ describe '.start_for_puma' do
+ let(:supervisor) { instance_double(Gitlab::ProcessSupervisor) }
+
+ before do
+ allow(Gitlab::ProcessSupervisor).to receive(:instance).and_return(supervisor)
+ end
+
+ it 'spawns a server process and supervises it' do
+ expect(Process).to receive(:spawn).with(
+ include('METRICS_SERVER_TARGET' => 'puma'), end_with('bin/metrics-server'), anything
+ ).once.and_return(42)
+ expect(supervisor).to receive(:supervise).with(42)
+
+ described_class.start_for_puma
+ end
+
+ context 'when the supervisor callback is invoked' do
+ context 'and the supervisor is alive' do
+ it 'restarts the metrics server' do
+ expect(supervisor).to receive(:alive).and_return(true)
+ expect(supervisor).to receive(:supervise).and_yield
+ expect(Process).to receive(:spawn).with(
+ include('METRICS_SERVER_TARGET' => 'puma'), end_with('bin/metrics-server'), anything
+ ).twice.and_return(42)
+
+ described_class.start_for_puma
+ end
+ end
+
+ context 'and the supervisor is not alive' do
+ it 'does not restart the server' do
+ expect(supervisor).to receive(:alive).and_return(false)
+ expect(supervisor).to receive(:supervise).and_yield
+ expect(Process).to receive(:spawn).with(
+ include('METRICS_SERVER_TARGET' => 'puma'), end_with('bin/metrics-server'), anything
+ ).once.and_return(42)
+
+ described_class.start_for_puma
+ end
+ end
+ end
+ end
end
diff --git a/spec/migrations/20210805192450_update_trial_plans_ci_daily_pipeline_schedule_triggers_spec.rb b/spec/migrations/20210805192450_update_trial_plans_ci_daily_pipeline_schedule_triggers_spec.rb
index 0b2f76baf1a..b1885b96adb 100644
--- a/spec/migrations/20210805192450_update_trial_plans_ci_daily_pipeline_schedule_triggers_spec.rb
+++ b/spec/migrations/20210805192450_update_trial_plans_ci_daily_pipeline_schedule_triggers_spec.rb
@@ -16,7 +16,7 @@ RSpec.describe UpdateTrialPlansCiDailyPipelineScheduleTriggers, :migration do
context 'when the environment is dev or com' do
before do
- allow(Gitlab).to receive(:dev_env_or_com?).and_return(true)
+ allow(Gitlab).to receive(:com?).and_return(true)
end
it 'sets the trial plan limits for ci_daily_pipeline_schedule_triggers' do
@@ -57,7 +57,7 @@ RSpec.describe UpdateTrialPlansCiDailyPipelineScheduleTriggers, :migration do
context 'when the environment is anything other than dev or com' do
before do
- allow(Gitlab).to receive(:dev_env_or_com?).and_return(false)
+ allow(Gitlab).to receive(:com?).and_return(false)
end
it 'does not update the plan limits' do
@@ -75,7 +75,7 @@ RSpec.describe UpdateTrialPlansCiDailyPipelineScheduleTriggers, :migration do
context 'when the environment is dev or com' do
before do
- allow(Gitlab).to receive(:dev_env_or_com?).and_return(true)
+ allow(Gitlab).to receive(:com?).and_return(true)
end
it 'sets the trial plan limits ci_daily_pipeline_schedule_triggers to zero' do
@@ -116,7 +116,7 @@ RSpec.describe UpdateTrialPlansCiDailyPipelineScheduleTriggers, :migration do
context 'when the environment is anything other than dev or com' do
before do
- allow(Gitlab).to receive(:dev_env_or_com?).and_return(false)
+ allow(Gitlab).to receive(:com?).and_return(false)
end
it 'does not change the ultimate trial plan limits' do
diff --git a/spec/migrations/20210812013042_remove_duplicate_project_authorizations_spec.rb b/spec/migrations/20210812013042_remove_duplicate_project_authorizations_spec.rb
new file mode 100644
index 00000000000..f734456b0b6
--- /dev/null
+++ b/spec/migrations/20210812013042_remove_duplicate_project_authorizations_spec.rb
@@ -0,0 +1,62 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!('remove_duplicate_project_authorizations')
+
+RSpec.describe RemoveDuplicateProjectAuthorizations, :migration do
+ let(:users) { table(:users) }
+ let(:namespaces) { table(:namespaces) }
+ let(:projects) { table(:projects) }
+ let(:project_authorizations) { table(:project_authorizations) }
+
+ let!(:user_1) { users.create! email: 'user1@example.com', projects_limit: 0 }
+ let!(:user_2) { users.create! email: 'user2@example.com', projects_limit: 0 }
+ let!(:namespace_1) { namespaces.create! name: 'namespace 1', path: 'namespace1' }
+ let!(:namespace_2) { namespaces.create! name: 'namespace 2', path: 'namespace2' }
+ let!(:project_1) { projects.create! namespace_id: namespace_1.id }
+ let!(:project_2) { projects.create! namespace_id: namespace_2.id }
+
+ before do
+ stub_const("#{described_class.name}::BATCH_SIZE", 2)
+ end
+
+ describe '#up' do
+ subject { migrate! }
+
+ context 'User with multiple projects' do
+ before do
+ project_authorizations.create! project_id: project_1.id, user_id: user_1.id, access_level: Gitlab::Access::DEVELOPER
+ project_authorizations.create! project_id: project_2.id, user_id: user_1.id, access_level: Gitlab::Access::DEVELOPER
+ end
+
+ it { expect { subject }.not_to change { ProjectAuthorization.count } }
+ end
+
+ context 'Project with multiple users' do
+ before do
+ project_authorizations.create! project_id: project_1.id, user_id: user_1.id, access_level: Gitlab::Access::DEVELOPER
+ project_authorizations.create! project_id: project_1.id, user_id: user_2.id, access_level: Gitlab::Access::DEVELOPER
+ end
+
+ it { expect { subject }.not_to change { ProjectAuthorization.count } }
+ end
+
+ context 'Same project and user but different access level' do
+ before do
+ project_authorizations.create! project_id: project_1.id, user_id: user_1.id, access_level: Gitlab::Access::DEVELOPER
+ project_authorizations.create! project_id: project_1.id, user_id: user_1.id, access_level: Gitlab::Access::MAINTAINER
+ project_authorizations.create! project_id: project_1.id, user_id: user_1.id, access_level: Gitlab::Access::REPORTER
+ end
+
+ it { expect { subject }.to change { ProjectAuthorization.count}.from(3).to(1) }
+
+ it 'retains the highest access level' do
+ subject
+
+ all_records = ProjectAuthorization.all.to_a
+ expect(all_records.count).to eq 1
+ expect(all_records.first.access_level).to eq Gitlab::Access::MAINTAINER
+ end
+ end
+ end
+end
diff --git a/spec/migrations/20220204194347_encrypt_integration_properties_spec.rb b/spec/migrations/20220204194347_encrypt_integration_properties_spec.rb
new file mode 100644
index 00000000000..78e3b43ff76
--- /dev/null
+++ b/spec/migrations/20220204194347_encrypt_integration_properties_spec.rb
@@ -0,0 +1,40 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+require_migration!
+
+RSpec.describe EncryptIntegrationProperties, :migration, schema: 20220204193000 do
+ subject(:migration) { described_class.new }
+
+ let(:integrations) { table(:integrations) }
+
+ before do
+ stub_const("#{described_class.name}::BATCH_SIZE", 2)
+ end
+
+ it 'correctly schedules background migrations', :aggregate_failures do
+ # update required
+ record1 = integrations.create!(properties: some_props)
+ record2 = integrations.create!(properties: some_props)
+ record3 = integrations.create!(properties: some_props)
+ record4 = integrations.create!(properties: nil)
+ record5 = integrations.create!(properties: nil)
+
+ Sidekiq::Testing.fake! do
+ freeze_time do
+ migrate!
+
+ expect(described_class::MIGRATION).to be_scheduled_migration(record1.id, record2.id)
+ expect(described_class::MIGRATION).to be_scheduled_migration(record3.id, record4.id)
+ expect(described_class::MIGRATION).to be_scheduled_migration(record5.id, record5.id)
+
+ expect(BackgroundMigrationWorker.jobs.size).to eq(3)
+ end
+ end
+ end
+
+ def some_props
+ { iid: generate(:iid), url: generate(:url), username: generate(:username) }.to_json
+ end
+end
diff --git a/spec/migrations/20220208080921_schedule_migrate_personal_namespace_project_maintainer_to_owner_spec.rb b/spec/migrations/20220208080921_schedule_migrate_personal_namespace_project_maintainer_to_owner_spec.rb
new file mode 100644
index 00000000000..41f3476dea8
--- /dev/null
+++ b/spec/migrations/20220208080921_schedule_migrate_personal_namespace_project_maintainer_to_owner_spec.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe ScheduleMigratePersonalNamespaceProjectMaintainerToOwner do
+ let_it_be(:migration) { described_class::MIGRATION }
+
+ describe '#up' do
+ it 'schedules background jobs for each batch of members' do
+ migrate!
+
+ expect(migration).to have_scheduled_batched_migration(
+ table_name: :members,
+ column_name: :id,
+ interval: described_class::INTERVAL
+ )
+ end
+ end
+end
diff --git a/spec/migrations/20220222192524_create_not_null_constraint_releases_tag_spec.rb b/spec/migrations/20220222192524_create_not_null_constraint_releases_tag_spec.rb
new file mode 100644
index 00000000000..bd7d992240a
--- /dev/null
+++ b/spec/migrations/20220222192524_create_not_null_constraint_releases_tag_spec.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+require 'spec_helper'
+require_migration!
+
+RSpec.describe CreateNotNullConstraintReleasesTag do
+ let_it_be(:releases) { table(:releases) }
+ let_it_be(:migration) { described_class.new }
+
+ before do
+ allow(migration).to receive(:transaction_open?).and_return(false)
+ allow(migration).to receive(:with_lock_retries).and_yield
+ end
+
+ it 'adds a check constraint to tags' do
+ constraint = releases.connection.check_constraints(:releases).find { |constraint| constraint.expression == "tag IS NOT NULL" }
+ expect(constraint).to be_nil
+
+ migration.up
+
+ constraint = releases.connection.check_constraints(:releases).find { |constraint| constraint.expression == "tag IS NOT NULL" }
+ expect(constraint).to be_a(ActiveRecord::ConnectionAdapters::CheckConstraintDefinition)
+ end
+end
diff --git a/spec/migrations/20220222192525_remove_null_releases_spec.rb b/spec/migrations/20220222192525_remove_null_releases_spec.rb
new file mode 100644
index 00000000000..6043f2c8cc8
--- /dev/null
+++ b/spec/migrations/20220222192525_remove_null_releases_spec.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+require 'spec_helper'
+
+require_migration!
+
+RSpec.describe RemoveNullReleases do
+ let(:releases) { table(:releases) }
+
+ before do
+ # we need to migrate to before previous migration so an invalid record can be created
+ migrate!
+ migration_context.down(previous_migration(3).version)
+
+ releases.create!(tag: 'good', name: 'good release', released_at: Time.now)
+ releases.create!(tag: nil, name: 'bad release', released_at: Time.now)
+ end
+
+ it 'deletes template records and associated data' do
+ expect { migrate! }
+ .to change { releases.count }.from(2).to(1)
+ end
+end
diff --git a/spec/migrations/20220305223212_add_security_training_providers_spec.rb b/spec/migrations/20220305223212_add_security_training_providers_spec.rb
new file mode 100644
index 00000000000..3d0089aaa8d
--- /dev/null
+++ b/spec/migrations/20220305223212_add_security_training_providers_spec.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe AddSecurityTrainingProviders, :migration do
+ include MigrationHelpers::WorkItemTypesHelper
+
+ let_it_be(:security_training_providers) { table(:security_training_providers) }
+
+ it 'creates default data' do
+ # Need to delete all as security training providers are seeded before entire test suite
+ security_training_providers.delete_all
+
+ reversible_migration do |migration|
+ migration.before -> {
+ expect(security_training_providers.count).to eq(0)
+ }
+
+ migration.after -> {
+ expect(security_training_providers.count).to eq(2)
+ }
+ end
+ end
+end
diff --git a/spec/migrations/20220307192610_remove_duplicate_project_tag_releases_spec.rb b/spec/migrations/20220307192610_remove_duplicate_project_tag_releases_spec.rb
new file mode 100644
index 00000000000..8a653869a9b
--- /dev/null
+++ b/spec/migrations/20220307192610_remove_duplicate_project_tag_releases_spec.rb
@@ -0,0 +1,47 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe RemoveDuplicateProjectTagReleases do
+ let(:namespaces) { table(:namespaces) }
+ let(:projects) { table(:projects) }
+ let(:users) { table(:users) }
+ let(:releases) { table(:releases) }
+
+ let(:namespace) { namespaces.create!(name: 'gitlab', path: 'gitlab-org') }
+ let(:project) { projects.create!(namespace_id: namespace.id, name: 'foo') }
+
+ let(:dup_releases) do
+ Array.new(4).fill do |i|
+ rel = releases.new(project_id: project.id,
+ tag: "duplicate tag",
+ released_at: (DateTime.now + i.days))
+ rel.save!(validate: false)
+ rel
+ end
+ end
+
+ let(:valid_release) do
+ releases.create!(
+ project_id: project.id,
+ tag: "valid tag",
+ released_at: DateTime.now
+ )
+ end
+
+ describe '#up' do
+ it "correctly removes duplicate tags from the same project" do
+ expect(dup_releases.length).to eq 4
+ expect(valid_release).not_to be nil
+ expect(releases.where(tag: 'duplicate tag').count).to eq 4
+ expect(releases.where(tag: 'valid tag').count).to eq 1
+
+ migrate!
+
+ expect(releases.where(tag: 'duplicate tag').count).to eq 1
+ expect(releases.where(tag: 'valid tag').count).to eq 1
+ expect(releases.all.map(&:tag)).to match_array ['valid tag', 'duplicate tag']
+ end
+ end
+end
diff --git a/spec/migrations/20220309084954_remove_leftover_external_pull_request_deletions_spec.rb b/spec/migrations/20220309084954_remove_leftover_external_pull_request_deletions_spec.rb
new file mode 100644
index 00000000000..c471fd86bf5
--- /dev/null
+++ b/spec/migrations/20220309084954_remove_leftover_external_pull_request_deletions_spec.rb
@@ -0,0 +1,43 @@
+# frozen_string_literal: true
+require 'spec_helper'
+
+require_migration!
+
+RSpec.describe RemoveLeftoverExternalPullRequestDeletions do
+ let(:deleted_records) { table(:loose_foreign_keys_deleted_records) }
+
+ let(:pending_record1) { deleted_records.create!(id: 1, fully_qualified_table_name: 'public.external_pull_requests', primary_key_value: 1, status: 1) }
+ let(:pending_record2) { deleted_records.create!(id: 2, fully_qualified_table_name: 'public.external_pull_requests', primary_key_value: 2, status: 1) }
+ let(:other_pending_record1) { deleted_records.create!(id: 3, fully_qualified_table_name: 'public.projects', primary_key_value: 1, status: 1) }
+ let(:other_pending_record2) { deleted_records.create!(id: 4, fully_qualified_table_name: 'public.ci_builds', primary_key_value: 1, status: 1) }
+ let(:processed_record1) { deleted_records.create!(id: 5, fully_qualified_table_name: 'public.external_pull_requests', primary_key_value: 3, status: 2) }
+ let(:other_processed_record1) { deleted_records.create!(id: 6, fully_qualified_table_name: 'public.ci_builds', primary_key_value: 2, status: 2) }
+
+ let!(:persisted_ids_before) do
+ [
+ pending_record1,
+ pending_record2,
+ other_pending_record1,
+ other_pending_record2,
+ processed_record1,
+ other_processed_record1
+ ].map(&:id).sort
+ end
+
+ let!(:persisted_ids_after) do
+ [
+ other_pending_record1,
+ other_pending_record2,
+ processed_record1,
+ other_processed_record1
+ ].map(&:id).sort
+ end
+
+ def all_ids
+ deleted_records.all.map(&:id).sort
+ end
+
+ it 'deletes pending external_pull_requests records' do
+ expect { migrate! }.to change { all_ids }.from(persisted_ids_before).to(persisted_ids_after)
+ end
+end
diff --git a/spec/migrations/20220310141349_remove_dependency_list_usage_data_from_redis_spec.rb b/spec/migrations/20220310141349_remove_dependency_list_usage_data_from_redis_spec.rb
new file mode 100644
index 00000000000..c00685c1397
--- /dev/null
+++ b/spec/migrations/20220310141349_remove_dependency_list_usage_data_from_redis_spec.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe RemoveDependencyListUsageDataFromRedis, :migration, :clean_gitlab_redis_shared_state do
+ let(:key) { "DEPENDENCY_LIST_USAGE_COUNTER" }
+
+ describe "#up" do
+ it 'removes the hash from redis' do
+ with_redis do |redis|
+ redis.hincrby(key, 1, 1)
+ redis.hincrby(key, 2, 1)
+ end
+
+ expect { migrate! }.to change { with_redis { |r| r.hgetall(key) } }.from({ '1' => '1', '2' => '1' }).to({})
+ end
+ end
+
+ def with_redis(&block)
+ Gitlab::Redis::SharedState.with(&block)
+ end
+end
diff --git a/spec/migrations/add_new_trail_plans_spec.rb b/spec/migrations/add_new_trail_plans_spec.rb
index 8ba6da11ad1..c1b488e8c3c 100644
--- a/spec/migrations/add_new_trail_plans_spec.rb
+++ b/spec/migrations/add_new_trail_plans_spec.rb
@@ -7,7 +7,7 @@ require_migration!
RSpec.describe AddNewTrailPlans, :migration do
describe '#up' do
before do
- allow(Gitlab).to receive(:dev_env_or_com?).and_return true
+ allow(Gitlab).to receive(:com?).and_return true
end
it 'creates 2 entries within the plans table' do
@@ -40,7 +40,7 @@ RSpec.describe AddNewTrailPlans, :migration do
context 'when the instance is not SaaS' do
before do
- allow(Gitlab).to receive(:dev_env_or_com?).and_return false
+ allow(Gitlab).to receive(:com?).and_return false
end
it 'does not create plans and plan limits and returns' do
@@ -58,7 +58,7 @@ RSpec.describe AddNewTrailPlans, :migration do
context 'when the instance is SaaS' do
before do
- allow(Gitlab).to receive(:dev_env_or_com?).and_return true
+ allow(Gitlab).to receive(:com?).and_return true
end
it 'removes the newly added ultimate and premium trial entries' do
@@ -77,7 +77,7 @@ RSpec.describe AddNewTrailPlans, :migration do
context 'when the instance is not SaaS' do
before do
- allow(Gitlab).to receive(:dev_env_or_com?).and_return false
+ allow(Gitlab).to receive(:com?).and_return false
table(:plans).create!(id: 1, name: 'ultimate_trial', title: 'Ultimate Trial')
table(:plans).create!(id: 2, name: 'premium_trial', title: 'Premium Trial')
table(:plan_limits).create!(id: 1, plan_id: 1)
diff --git a/spec/migrations/add_open_source_plan_spec.rb b/spec/migrations/add_open_source_plan_spec.rb
index 04b26662f82..6e1cd544141 100644
--- a/spec/migrations/add_open_source_plan_spec.rb
+++ b/spec/migrations/add_open_source_plan_spec.rb
@@ -7,7 +7,7 @@ require_migration!
RSpec.describe AddOpenSourcePlan, :migration do
describe '#up' do
before do
- allow(Gitlab).to receive(:dev_env_or_com?).and_return true
+ allow(Gitlab).to receive(:com?).and_return true
end
it 'creates 1 entry within the plans table' do
@@ -35,7 +35,7 @@ RSpec.describe AddOpenSourcePlan, :migration do
context 'when the instance is not SaaS' do
before do
- allow(Gitlab).to receive(:dev_env_or_com?).and_return false
+ allow(Gitlab).to receive(:com?).and_return false
end
it 'does not create plans and plan limits and returns' do
@@ -52,7 +52,7 @@ RSpec.describe AddOpenSourcePlan, :migration do
context 'when the instance is SaaS' do
before do
- allow(Gitlab).to receive(:dev_env_or_com?).and_return true
+ allow(Gitlab).to receive(:com?).and_return true
end
it 'removes the newly added opensource entry' do
@@ -70,7 +70,7 @@ RSpec.describe AddOpenSourcePlan, :migration do
context 'when the instance is not SaaS' do
before do
- allow(Gitlab).to receive(:dev_env_or_com?).and_return false
+ allow(Gitlab).to receive(:com?).and_return false
table(:plans).create!(id: 1, name: 'opensource', title: 'Open Source Program')
table(:plan_limits).create!(id: 1, plan_id: 1)
end
diff --git a/spec/migrations/backfill_all_project_namespaces_spec.rb b/spec/migrations/backfill_all_project_namespaces_spec.rb
new file mode 100644
index 00000000000..1bcaad783b2
--- /dev/null
+++ b/spec/migrations/backfill_all_project_namespaces_spec.rb
@@ -0,0 +1,37 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe BackfillAllProjectNamespaces, :migration do
+ let_it_be(:migration) { described_class::MIGRATION }
+
+ let(:projects) { table(:projects) }
+ let(:namespaces) { table(:namespaces) }
+ let(:user_namespace) { namespaces.create!(name: 'user1', path: 'user1', visibility_level: 20, type: 'User') }
+ let(:parent_group1) { namespaces.create!(name: 'parent_group1', path: 'parent_group1', visibility_level: 20, type: 'Group') }
+ let!(:parent_group1_project) { projects.create!(name: 'parent_group1_project', path: 'parent_group1_project', namespace_id: parent_group1.id, visibility_level: 20) }
+ let!(:user_namespace_project) { projects.create!(name: 'user1_project', path: 'user1_project', namespace_id: user_namespace.id, visibility_level: 20) }
+
+ describe '#up' do
+ it 'schedules background jobs for each batch of namespaces' do
+ migrate!
+
+ expect(migration).to have_scheduled_batched_migration(
+ table_name: :projects,
+ column_name: :id,
+ job_arguments: [nil, 'up'],
+ interval: described_class::DELAY_INTERVAL
+ )
+ end
+ end
+
+ describe '#down' do
+ it 'deletes all batched migration records' do
+ migrate!
+ schema_migrate_down!
+
+ expect(migration).not_to have_scheduled_batched_migration
+ end
+ end
+end
diff --git a/spec/migrations/backfill_cycle_analytics_aggregations_spec.rb b/spec/migrations/backfill_cycle_analytics_aggregations_spec.rb
new file mode 100644
index 00000000000..2a5d33742ce
--- /dev/null
+++ b/spec/migrations/backfill_cycle_analytics_aggregations_spec.rb
@@ -0,0 +1,36 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe BackfillCycleAnalyticsAggregations, :migration do
+ let(:migration) { described_class.new }
+
+ let(:aggregations) { table(:analytics_cycle_analytics_aggregations) }
+ let(:namespaces) { table(:namespaces) }
+ let(:group_value_streams) { table(:analytics_cycle_analytics_group_value_streams) }
+
+ context 'when there are value stream records' do
+ it 'inserts a record for each top-level namespace' do
+ group1 = namespaces.create!(path: 'aaa', name: 'aaa')
+ subgroup1 = namespaces.create!(path: 'bbb', name: 'bbb', parent_id: group1.id)
+ group2 = namespaces.create!(path: 'ccc', name: 'ccc')
+
+ namespaces.create!(path: 'ddd', name: 'ddd') # not used
+
+ group_value_streams.create!(name: 'for top level group', group_id: group2.id)
+ group_value_streams.create!(name: 'another for top level group', group_id: group2.id)
+
+ group_value_streams.create!(name: 'for subgroup', group_id: subgroup1.id)
+ group_value_streams.create!(name: 'another for subgroup', group_id: subgroup1.id)
+
+ migrate!
+
+ expect(aggregations.pluck(:group_id)).to match_array([group1.id, group2.id])
+ end
+ end
+
+ it 'does nothing' do
+ expect { migrate! }.not_to change { aggregations.count }
+ end
+end
diff --git a/spec/migrations/backfill_member_namespace_id_for_group_members_spec.rb b/spec/migrations/backfill_member_namespace_id_for_group_members_spec.rb
new file mode 100644
index 00000000000..0c0acf85d41
--- /dev/null
+++ b/spec/migrations/backfill_member_namespace_id_for_group_members_spec.rb
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe BackfillMemberNamespaceIdForGroupMembers do
+ let_it_be(:migration) { described_class::MIGRATION }
+
+ describe '#up' do
+ it 'schedules background jobs for each batch of group members' do
+ migrate!
+
+ expect(migration).to have_scheduled_batched_migration(
+ table_name: :members,
+ column_name: :id,
+ interval: described_class::INTERVAL
+ )
+ end
+ end
+
+ describe '#down' do
+ it 'deletes all batched migration records' do
+ migrate!
+ schema_migrate_down!
+
+ expect(migration).not_to have_scheduled_batched_migration
+ end
+ end
+end
diff --git a/spec/migrations/recreate_index_security_ci_builds_on_name_and_id_parser_with_new_features_spec.rb b/spec/migrations/recreate_index_security_ci_builds_on_name_and_id_parser_with_new_features_spec.rb
new file mode 100644
index 00000000000..8ec51d86779
--- /dev/null
+++ b/spec/migrations/recreate_index_security_ci_builds_on_name_and_id_parser_with_new_features_spec.rb
@@ -0,0 +1,28 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+require_migration!
+
+RSpec.describe RecreateIndexSecurityCiBuildsOnNameAndIdParserWithNewFeatures, :migration do
+ let(:db) { described_class.new }
+ let(:pg_class) { table(:pg_class) }
+ let(:pg_index) { table(:pg_index) }
+ let(:async_indexes) { table(:postgres_async_indexes) }
+
+ it 'recreates index' do
+ reversible_migration do |migration|
+ migration.before -> {
+ expect(async_indexes.where(name: described_class::OLD_INDEX_NAME).exists?).to be false
+ expect(db.index_exists?(described_class::TABLE, described_class::COLUMNS, name: described_class::OLD_INDEX_NAME)).to be true
+ expect(db.index_exists?(described_class::TABLE, described_class::COLUMNS, name: described_class::NEW_INDEX_NAME)).to be false
+ }
+
+ migration.after -> {
+ expect(async_indexes.where(name: described_class::OLD_INDEX_NAME).exists?).to be true
+ expect(db.index_exists?(described_class::TABLE, described_class::COLUMNS, name: described_class::OLD_INDEX_NAME)).to be false
+ expect(db.index_exists?(described_class::TABLE, described_class::COLUMNS, name: described_class::NEW_INDEX_NAME)).to be true
+ }
+ end
+ end
+end
diff --git a/spec/migrations/remove_not_null_contraint_on_title_from_sprints_spec.rb b/spec/migrations/remove_not_null_contraint_on_title_from_sprints_spec.rb
new file mode 100644
index 00000000000..fdafc4a5a89
--- /dev/null
+++ b/spec/migrations/remove_not_null_contraint_on_title_from_sprints_spec.rb
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+require_migration!
+
+RSpec.describe RemoveNotNullContraintOnTitleFromSprints, :migration, schema: 20220304052335 do
+ let(:migration) { described_class.new }
+ let(:namespaces) { table(:namespaces) }
+ let(:sprints) { table(:sprints) }
+ let(:iterations_cadences) { table(:iterations_cadences) }
+
+ let!(:group) { namespaces.create!(name: 'foo', path: 'foo') }
+ let!(:cadence) { iterations_cadences.create!(group_id: group.id, title: "cadence 1") }
+ let!(:iteration1) { sprints.create!(id: 1, title: 'a', group_id: group.id, iterations_cadence_id: cadence.id, start_date: Date.new(2021, 11, 1), due_date: Date.new(2021, 11, 5), iid: 1) }
+
+ describe '#down' do
+ it "removes null titles by setting them with ids" do
+ migration.up
+
+ iteration2 = sprints.create!(id: 2, title: nil, group_id: group.id, iterations_cadence_id: cadence.id, start_date: Date.new(2021, 12, 1), due_date: Date.new(2021, 12, 5), iid: 2)
+
+ migration.down
+
+ expect(iteration1.reload.title).to eq 'a'
+ expect(iteration2.reload.title).to eq '2'
+ end
+ end
+end
diff --git a/spec/migrations/update_application_settings_container_registry_exp_pol_worker_capacity_default_spec.rb b/spec/migrations/update_application_settings_container_registry_exp_pol_worker_capacity_default_spec.rb
new file mode 100644
index 00000000000..842456089fe
--- /dev/null
+++ b/spec/migrations/update_application_settings_container_registry_exp_pol_worker_capacity_default_spec.rb
@@ -0,0 +1,40 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe UpdateApplicationSettingsContainerRegistryExpPolWorkerCapacityDefault do
+ let(:settings) { table(:application_settings) }
+
+ context 'with no rows in the application_settings table' do
+ it 'does not insert a row' do
+ expect { migrate! }.to not_change { settings.count }
+ end
+ end
+
+ context 'with a row in the application_settings table' do
+ before do
+ settings.create!(container_registry_expiration_policies_worker_capacity: capacity)
+ end
+
+ context 'with container_registry_expiration_policy_worker_capacity set to a value different than 0' do
+ let(:capacity) { 1 }
+
+ it 'does not update the row' do
+ expect { migrate! }
+ .to not_change { settings.count }
+ .and not_change { settings.first.container_registry_expiration_policies_worker_capacity }
+ end
+ end
+
+ context 'with container_registry_expiration_policy_worker_capacity set to 0' do
+ let(:capacity) { 0 }
+
+ it 'updates the existing row' do
+ expect { migrate! }
+ .to not_change { settings.count }
+ .and change { settings.first.container_registry_expiration_policies_worker_capacity }.from(0).to(4)
+ end
+ end
+ end
+end
diff --git a/spec/models/analytics/cycle_analytics/aggregation_spec.rb b/spec/models/analytics/cycle_analytics/aggregation_spec.rb
new file mode 100644
index 00000000000..4bf737df56a
--- /dev/null
+++ b/spec/models/analytics/cycle_analytics/aggregation_spec.rb
@@ -0,0 +1,138 @@
+# frozen_string_literal: true
+require 'spec_helper'
+
+RSpec.describe Analytics::CycleAnalytics::Aggregation, type: :model do
+ describe 'associations' do
+ it { is_expected.to belong_to(:group).required }
+ end
+
+ describe 'validations' do
+ it { is_expected.not_to validate_presence_of(:group) }
+ it { is_expected.not_to validate_presence_of(:enabled) }
+
+ %i[incremental_runtimes_in_seconds incremental_processed_records last_full_run_runtimes_in_seconds last_full_run_processed_records].each do |column|
+ it "validates the array length of #{column}" do
+ record = described_class.new(column => [1] * 11)
+
+ expect(record).to be_invalid
+ expect(record.errors).to have_key(column)
+ end
+ end
+ end
+
+ describe '#safe_create_for_group' do
+ let_it_be(:group) { create(:group) }
+ let_it_be(:subgroup) { create(:group, parent: group) }
+
+ it 'creates the aggregation record' do
+ record = described_class.safe_create_for_group(group)
+
+ expect(record).to be_persisted
+ end
+
+ context 'when non top-level group is given' do
+ it 'creates the aggregation record for the top-level group' do
+ record = described_class.safe_create_for_group(subgroup)
+
+ expect(record).to be_persisted
+ end
+ end
+
+ context 'when the record is already present' do
+ it 'does nothing' do
+ described_class.safe_create_for_group(group)
+
+ expect do
+ described_class.safe_create_for_group(group)
+ described_class.safe_create_for_group(subgroup)
+ end.not_to change { described_class.count }
+ end
+ end
+ end
+
+ describe '#load_batch' do
+ let!(:aggregation1) { create(:cycle_analytics_aggregation, last_incremental_run_at: nil, last_consistency_check_updated_at: 3.days.ago).reload }
+ let!(:aggregation2) { create(:cycle_analytics_aggregation, last_incremental_run_at: 5.days.ago).reload }
+ let!(:aggregation3) { create(:cycle_analytics_aggregation, last_incremental_run_at: nil, last_consistency_check_updated_at: 2.days.ago).reload }
+ let!(:aggregation4) { create(:cycle_analytics_aggregation, last_incremental_run_at: 10.days.ago).reload }
+
+ before do
+ create(:cycle_analytics_aggregation, :disabled) # disabled rows are skipped
+ create(:cycle_analytics_aggregation, last_incremental_run_at: 1.day.ago, last_consistency_check_updated_at: 1.hour.ago) # "early" rows are filtered out
+ end
+
+ it 'loads records in priority order' do
+ batch = described_class.load_batch(2.days.ago).to_a
+
+ expect(batch.size).to eq(4)
+ first_two = batch.first(2)
+ last_two = batch.last(2)
+
+ # Using match_array because the order can be undeterministic for nil values.
+ expect(first_two).to match_array([aggregation1, aggregation3])
+ expect(last_two).to eq([aggregation4, aggregation2])
+ end
+
+ context 'when loading batch for last_consistency_check_updated_at' do
+ it 'loads records in priority order' do
+ batch = described_class.load_batch(1.day.ago, :last_consistency_check_updated_at).to_a
+
+ expect(batch.size).to eq(4)
+ first_two = batch.first(2)
+ last_two = batch.last(2)
+
+ expect(first_two).to match_array([aggregation2, aggregation4])
+ expect(last_two).to eq([aggregation1, aggregation3])
+ end
+ end
+ end
+
+ describe '#estimated_next_run_at' do
+ around do |example|
+ travel_to(Time.utc(2019, 3, 17, 13, 3)) { example.run }
+ end
+
+ # aggregation runs on every 10 minutes
+ let(:minutes_until_next_aggregation) { 7.minutes }
+
+ context 'when aggregation was not yet executed for the given group' do
+ let(:aggregation) { create(:cycle_analytics_aggregation, last_incremental_run_at: nil) }
+
+ it { expect(aggregation.estimated_next_run_at).to eq(nil) }
+ end
+
+ context 'when aggregation was already run' do
+ let!(:other_aggregation1) { create(:cycle_analytics_aggregation, last_incremental_run_at: 10.minutes.ago) }
+ let!(:other_aggregation2) { create(:cycle_analytics_aggregation, last_incremental_run_at: 15.minutes.ago) }
+ let!(:aggregation) { create(:cycle_analytics_aggregation, last_incremental_run_at: 5.minutes.ago) }
+
+ it 'returns the duration between the previous run timestamp and the earliest last_incremental_run_at' do
+ expect(aggregation.estimated_next_run_at).to eq((10.minutes + minutes_until_next_aggregation).from_now)
+ end
+
+ context 'when the aggregation has persisted previous runtimes' do
+ before do
+ aggregation.update!(incremental_runtimes_in_seconds: [30, 60, 90])
+ end
+
+ it 'adds the runtime to the estimation' do
+ expect(aggregation.estimated_next_run_at).to eq((10.minutes.seconds + 60.seconds + minutes_until_next_aggregation).from_now)
+ end
+ end
+ end
+
+ context 'when no records are present in the DB' do
+ it 'returns nil' do
+ expect(described_class.new.estimated_next_run_at).to eq(nil)
+ end
+ end
+
+ context 'when only one aggregation record present' do
+ let!(:aggregation) { create(:cycle_analytics_aggregation, last_incremental_run_at: 5.minutes.ago) }
+
+ it 'returns the minutes until the next aggregation' do
+ expect(aggregation.estimated_next_run_at).to eq(minutes_until_next_aggregation.from_now)
+ end
+ end
+ end
+end
diff --git a/spec/models/application_record_spec.rb b/spec/models/application_record_spec.rb
index 9c9a048999c..c1cd44e9007 100644
--- a/spec/models/application_record_spec.rb
+++ b/spec/models/application_record_spec.rb
@@ -104,6 +104,18 @@ RSpec.describe ApplicationRecord do
end
end
+ describe '.where_not_exists' do
+ it 'produces a WHERE NOT EXISTS query' do
+ create(:user, :two_factor_via_u2f)
+ user_2 = create(:user)
+
+ expect(
+ User.where_not_exists(
+ U2fRegistration.where(U2fRegistration.arel_table[:user_id].eq(User.arel_table[:id])))
+ ).to match_array([user_2])
+ end
+ end
+
describe '.transaction', :delete do
it 'opens a new transaction' do
expect(described_class.connection.transaction_open?).to be false
diff --git a/spec/models/application_setting_spec.rb b/spec/models/application_setting_spec.rb
index a962703d460..70331e8d78a 100644
--- a/spec/models/application_setting_spec.rb
+++ b/spec/models/application_setting_spec.rb
@@ -76,6 +76,8 @@ RSpec.describe ApplicationSetting do
it { is_expected.to validate_numericality_of(:container_registry_delete_tags_service_timeout).only_integer.is_greater_than_or_equal_to(0) }
it { is_expected.to validate_numericality_of(:container_registry_cleanup_tags_service_max_list_size).only_integer.is_greater_than_or_equal_to(0) }
it { is_expected.to validate_numericality_of(:container_registry_expiration_policies_worker_capacity).only_integer.is_greater_than_or_equal_to(0) }
+ it { is_expected.to allow_value(true).for(:container_registry_expiration_policies_caching) }
+ it { is_expected.to allow_value(false).for(:container_registry_expiration_policies_caching) }
it { is_expected.to validate_numericality_of(:container_registry_import_max_tags_count).only_integer.is_greater_than_or_equal_to(0) }
it { is_expected.to validate_numericality_of(:container_registry_import_max_retries).only_integer.is_greater_than_or_equal_to(0) }
@@ -141,7 +143,7 @@ RSpec.describe ApplicationSetting do
it { is_expected.not_to allow_value('default' => 101).for(:repository_storages_weighted).with_message("value for 'default' must be between 0 and 100") }
it { is_expected.not_to allow_value('default' => 100, shouldntexist: 50).for(:repository_storages_weighted).with_message("can't include: shouldntexist") }
- %i[notes_create_limit user_email_lookup_limit users_get_by_id_limit].each do |setting|
+ %i[notes_create_limit search_rate_limit search_rate_limit_unauthenticated users_get_by_id_limit].each do |setting|
it { is_expected.to allow_value(400).for(setting) }
it { is_expected.not_to allow_value('two').for(setting) }
it { is_expected.not_to allow_value(nil).for(setting) }
diff --git a/spec/models/broadcast_message_spec.rb b/spec/models/broadcast_message_spec.rb
index d981189c6f1..b0bfdabe13c 100644
--- a/spec/models/broadcast_message_spec.rb
+++ b/spec/models/broadcast_message_spec.rb
@@ -23,6 +23,8 @@ RSpec.describe BroadcastMessage do
it { is_expected.to allow_value(1).for(:broadcast_type) }
it { is_expected.not_to allow_value(nil).for(:broadcast_type) }
+ it { is_expected.not_to allow_value(nil).for(:target_access_levels) }
+ it { is_expected.to validate_inclusion_of(:target_access_levels).in_array(described_class::ALLOWED_TARGET_ACCESS_LEVELS) }
end
shared_examples 'time constrainted' do |broadcast_type|
@@ -60,7 +62,7 @@ RSpec.describe BroadcastMessage do
subject.call
- Timecop.travel(3.weeks) do
+ travel_to(3.weeks.from_now) do
subject.call
end
end
@@ -71,7 +73,7 @@ RSpec.describe BroadcastMessage do
expect(subject.call).to match_array([message])
expect(described_class.cache).to receive(:expire).and_call_original
- Timecop.travel(1.week) do
+ travel_to(1.week.from_now) do
2.times { expect(subject.call).to be_empty }
end
end
@@ -94,7 +96,7 @@ RSpec.describe BroadcastMessage do
expect(subject.call.length).to eq(1)
- Timecop.travel(future.starts_at) do
+ travel_to(future.starts_at + 1.second) do
expect(subject.call.length).to eq(2)
end
end
@@ -175,12 +177,112 @@ RSpec.describe BroadcastMessage do
end
end
+ shared_examples "matches with user access level" do |broadcast_type|
+ let_it_be(:target_access_levels) { [Gitlab::Access::GUEST] }
+
+ let(:feature_flag_state) { true }
+
+ before do
+ stub_feature_flags(role_targeted_broadcast_messages: feature_flag_state)
+ end
+
+ context 'when feature flag is disabled' do
+ let(:feature_flag_state) { false }
+
+ context 'when message is role-targeted' do
+ let_it_be(:message) { create(:broadcast_message, target_access_levels: target_access_levels, broadcast_type: broadcast_type) }
+
+ it 'does not return the message' do
+ expect(subject.call(nil, Gitlab::Access::GUEST)).to be_empty
+ end
+ end
+
+ context 'when message is not role-targeted' do
+ let_it_be(:message) { create(:broadcast_message, target_access_levels: [], broadcast_type: broadcast_type) }
+
+ it 'returns the message' do
+ expect(subject.call(nil, Gitlab::Access::GUEST)).to include(message)
+ end
+ end
+ end
+
+ context 'when target_access_levels is empty' do
+ let_it_be(:message) { create(:broadcast_message, target_access_levels: [], broadcast_type: broadcast_type) }
+
+ it 'returns the message if user access level is not nil' do
+ expect(subject.call(nil, Gitlab::Access::MINIMAL_ACCESS)).to include(message)
+ end
+
+ it 'returns the message if user access level is nil' do
+ expect(subject.call).to include(message)
+ end
+ end
+
+ context 'when target_access_levels is not empty' do
+ let_it_be(:message) { create(:broadcast_message, target_access_levels: target_access_levels, broadcast_type: broadcast_type) }
+
+ it "does not return the message if user access level is nil" do
+ expect(subject.call).to be_empty
+ end
+
+ it "returns the message if user access level is in target_access_levels" do
+ expect(subject.call(nil, Gitlab::Access::GUEST)).to include(message)
+ end
+
+ it "does not return the message if user access level is not in target_access_levels" do
+ expect(subject.call(nil, Gitlab::Access::MINIMAL_ACCESS)).to be_empty
+ end
+ end
+ end
+
+ shared_examples "handles stale cache data gracefully" do
+ # Regression test for https://gitlab.com/gitlab-org/gitlab/-/issues/353076
+ context 'when cache returns stale data (e.g. nil target_access_levels)' do
+ let(:message) { build(:broadcast_message, :banner, target_access_levels: nil) }
+ let(:cache) { Gitlab::JsonCache.new }
+
+ before do
+ cache.write(described_class::BANNER_CACHE_KEY, [message])
+ allow(BroadcastMessage).to receive(:cache) { cache }
+ end
+
+ it 'does not raise error (e.g. NoMethodError from nil.empty?)' do
+ expect { subject.call }.not_to raise_error
+ end
+
+ context 'when feature flag is disabled' do
+ it 'does not raise error (e.g. NoMethodError from nil.empty?)' do
+ stub_feature_flags(role_targeted_broadcast_messages: false)
+
+ expect { subject.call }.not_to raise_error
+ end
+ end
+ end
+ end
+
describe '.current', :use_clean_rails_memory_store_caching do
- subject { -> (path = nil) { described_class.current(path) } }
+ subject do
+ -> (path = nil, user_access_level = nil) do
+ described_class.current(current_path: path, user_access_level: user_access_level)
+ end
+ end
it_behaves_like 'time constrainted', :banner
it_behaves_like 'message cache', :banner
it_behaves_like 'matches with current path', :banner
+ it_behaves_like 'matches with user access level', :banner
+ it_behaves_like 'handles stale cache data gracefully'
+
+ context 'when message is from cache' do
+ before do
+ subject.call
+ end
+
+ it_behaves_like 'matches with current path', :banner
+ it_behaves_like 'matches with user access level', :banner
+ it_behaves_like 'matches with current path', :notification
+ it_behaves_like 'matches with user access level', :notification
+ end
it 'returns both types' do
banner_message = create(:broadcast_message, broadcast_type: :banner)
@@ -191,11 +293,26 @@ RSpec.describe BroadcastMessage do
end
describe '.current_banner_messages', :use_clean_rails_memory_store_caching do
- subject { -> (path = nil) { described_class.current_banner_messages(path) } }
+ subject do
+ -> (path = nil, user_access_level = nil) do
+ described_class.current_banner_messages(current_path: path, user_access_level: user_access_level)
+ end
+ end
it_behaves_like 'time constrainted', :banner
it_behaves_like 'message cache', :banner
it_behaves_like 'matches with current path', :banner
+ it_behaves_like 'matches with user access level', :banner
+ it_behaves_like 'handles stale cache data gracefully'
+
+ context 'when message is from cache' do
+ before do
+ subject.call
+ end
+
+ it_behaves_like 'matches with current path', :banner
+ it_behaves_like 'matches with user access level', :banner
+ end
it 'only returns banners' do
banner_message = create(:broadcast_message, broadcast_type: :banner)
@@ -206,11 +323,26 @@ RSpec.describe BroadcastMessage do
end
describe '.current_notification_messages', :use_clean_rails_memory_store_caching do
- subject { -> (path = nil) { described_class.current_notification_messages(path) } }
+ subject do
+ -> (path = nil, user_access_level = nil) do
+ described_class.current_notification_messages(current_path: path, user_access_level: user_access_level)
+ end
+ end
it_behaves_like 'time constrainted', :notification
it_behaves_like 'message cache', :notification
it_behaves_like 'matches with current path', :notification
+ it_behaves_like 'matches with user access level', :notification
+ it_behaves_like 'handles stale cache data gracefully'
+
+ context 'when message is from cache' do
+ before do
+ subject.call
+ end
+
+ it_behaves_like 'matches with current path', :notification
+ it_behaves_like 'matches with user access level', :notification
+ end
it 'only returns notifications' do
notification_message = create(:broadcast_message, broadcast_type: :notification)
@@ -286,9 +418,9 @@ RSpec.describe BroadcastMessage do
it 'flushes the Redis cache' do
message = create(:broadcast_message)
- expect(Rails.cache).to receive(:delete).with(described_class::CACHE_KEY)
- expect(Rails.cache).to receive(:delete).with(described_class::BANNER_CACHE_KEY)
- expect(Rails.cache).to receive(:delete).with(described_class::NOTIFICATION_CACHE_KEY)
+ expect(Rails.cache).to receive(:delete).with("#{described_class::CACHE_KEY}:#{Gitlab.revision}")
+ expect(Rails.cache).to receive(:delete).with("#{described_class::BANNER_CACHE_KEY}:#{Gitlab.revision}")
+ expect(Rails.cache).to receive(:delete).with("#{described_class::NOTIFICATION_CACHE_KEY}:#{Gitlab.revision}")
message.flush_redis_cache
end
diff --git a/spec/models/bulk_imports/export_status_spec.rb b/spec/models/bulk_imports/export_status_spec.rb
index 48f32a2092a..f945ad12244 100644
--- a/spec/models/bulk_imports/export_status_spec.rb
+++ b/spec/models/bulk_imports/export_status_spec.rb
@@ -55,6 +55,17 @@ RSpec.describe BulkImports::ExportStatus do
expect(subject.failed?).to eq(false)
end
end
+
+ context 'when export status is not present' do
+ let(:response_double) do
+ double(parsed_response: [])
+ end
+
+ it 'returns true' do
+ expect(subject.failed?).to eq(true)
+ expect(subject.error).to eq('Empty export status response')
+ end
+ end
end
describe '#error' do
diff --git a/spec/models/ci/bridge_spec.rb b/spec/models/ci/bridge_spec.rb
index 6fde55103f8..7c3c02a5ab7 100644
--- a/spec/models/ci/bridge_spec.rb
+++ b/spec/models/ci/bridge_spec.rb
@@ -7,6 +7,10 @@ RSpec.describe Ci::Bridge do
let_it_be(:target_project) { create(:project, name: 'project', namespace: create(:namespace, name: 'my')) }
let_it_be(:pipeline) { create(:ci_pipeline, project: project) }
+ before_all do
+ create(:ci_pipeline_variable, pipeline: pipeline, key: 'PVAR1', value: 'PVAL1')
+ end
+
let(:bridge) do
create(:ci_bridge, :variables, status: :created,
options: options,
@@ -215,6 +219,70 @@ RSpec.describe Ci::Bridge do
.to include(key: 'EXPANDED', value: '$EXPANDED')
end
end
+
+ context 'forward variables' do
+ using RSpec::Parameterized::TableSyntax
+
+ where(:yaml_variables, :pipeline_variables, :ff, :variables) do
+ nil | nil | true | %w[BRIDGE]
+ nil | false | true | %w[BRIDGE]
+ nil | true | true | %w[BRIDGE PVAR1]
+ false | nil | true | %w[]
+ false | false | true | %w[]
+ false | true | true | %w[PVAR1]
+ true | nil | true | %w[BRIDGE]
+ true | false | true | %w[BRIDGE]
+ true | true | true | %w[BRIDGE PVAR1]
+ nil | nil | false | %w[BRIDGE]
+ nil | false | false | %w[BRIDGE]
+ nil | true | false | %w[BRIDGE]
+ false | nil | false | %w[BRIDGE]
+ false | false | false | %w[BRIDGE]
+ false | true | false | %w[BRIDGE]
+ true | nil | false | %w[BRIDGE]
+ true | false | false | %w[BRIDGE]
+ true | true | false | %w[BRIDGE]
+ end
+
+ with_them do
+ let(:options) do
+ {
+ trigger: {
+ project: 'my/project',
+ branch: 'master',
+ forward: { yaml_variables: yaml_variables,
+ pipeline_variables: pipeline_variables }.compact
+ }
+ }
+ end
+
+ before do
+ stub_feature_flags(ci_trigger_forward_variables: ff)
+ end
+
+ it 'returns variables according to the forward value' do
+ expect(bridge.downstream_variables.map { |v| v[:key] }).to contain_exactly(*variables)
+ end
+ end
+
+ context 'when sending a variable via both yaml and pipeline' do
+ let(:pipeline) { create(:ci_pipeline, project: project) }
+
+ let(:options) do
+ { trigger: { project: 'my/project', forward: { pipeline_variables: true } } }
+ end
+
+ before do
+ create(:ci_pipeline_variable, pipeline: pipeline, key: 'BRIDGE', value: 'new value')
+ end
+
+ it 'uses the pipeline variable' do
+ expect(bridge.downstream_variables).to contain_exactly(
+ { key: 'BRIDGE', value: 'new value' }
+ )
+ end
+ end
+ end
end
describe 'metadata support' do
diff --git a/spec/models/ci/build_spec.rb b/spec/models/ci/build_spec.rb
index 90298f0e973..240b932638a 100644
--- a/spec/models/ci/build_spec.rb
+++ b/spec/models/ci/build_spec.rb
@@ -3510,6 +3510,38 @@ RSpec.describe Ci::Build do
end
end
+ context 'for harbor integration' do
+ let(:harbor_integration) { create(:harbor_integration) }
+
+ let(:harbor_variables) do
+ [
+ { key: 'HARBOR_URL', value: harbor_integration.url, public: true, masked: false },
+ { key: 'HARBOR_PROJECT', value: harbor_integration.project_name, public: true, masked: false },
+ { key: 'HARBOR_USERNAME', value: harbor_integration.username, public: true, masked: false },
+ { key: 'HARBOR_PASSWORD', value: harbor_integration.password, public: false, masked: true }
+ ]
+ end
+
+ context 'when harbor_integration exists' do
+ before do
+ build.project.update!(harbor_integration: harbor_integration)
+ end
+
+ it 'includes harbor variables' do
+ is_expected.to include(*harbor_variables)
+ end
+ end
+
+ context 'when harbor_integration does not exist' do
+ it 'does not include harbor variables' do
+ expect(subject.find { |v| v[:key] == 'HARBOR_URL'}).to be_nil
+ expect(subject.find { |v| v[:key] == 'HARBOR_PROJECT_NAME'}).to be_nil
+ expect(subject.find { |v| v[:key] == 'HARBOR_USERNAME'}).to be_nil
+ expect(subject.find { |v| v[:key] == 'HARBOR_PASSWORD'}).to be_nil
+ end
+ end
+ end
+
context 'when build has dependency which has dotenv variable' do
let!(:prepare) { create(:ci_build, pipeline: pipeline, stage_idx: 0) }
let!(:build) { create(:ci_build, pipeline: pipeline, stage_idx: 1, options: { dependencies: [prepare.name] }) }
diff --git a/spec/models/ci/group_variable_spec.rb b/spec/models/ci/group_variable_spec.rb
index 4cb3b9eef0c..3a4b836e453 100644
--- a/spec/models/ci/group_variable_spec.rb
+++ b/spec/models/ci/group_variable_spec.rb
@@ -43,6 +43,14 @@ RSpec.describe Ci::GroupVariable do
end
end
+ describe '.for_groups' do
+ let_it_be(:group) { create(:group) }
+ let_it_be(:group_variable) { create(:ci_group_variable, group: group) }
+ let_it_be(:other_variable) { create(:ci_group_variable) }
+
+ it { expect(described_class.for_groups([group.id])).to eq([group_variable]) }
+ end
+
it_behaves_like 'cleanup by a loose foreign key' do
let!(:model) { create(:ci_group_variable) }
diff --git a/spec/models/ci/pipeline_schedule_spec.rb b/spec/models/ci/pipeline_schedule_spec.rb
index 0f4f148775e..3c295fb345b 100644
--- a/spec/models/ci/pipeline_schedule_spec.rb
+++ b/spec/models/ci/pipeline_schedule_spec.rb
@@ -228,6 +228,66 @@ RSpec.describe Ci::PipelineSchedule do
end
end
+ describe '#for_tag?' do
+ context 'when the target is a tag' do
+ before do
+ subject.ref = 'refs/tags/v1.0'
+ end
+
+ it { expect(subject.for_tag?).to eq(true) }
+ end
+
+ context 'when the target is a branch' do
+ before do
+ subject.ref = 'refs/heads/main'
+ end
+
+ it { expect(subject.for_tag?).to eq(false) }
+ end
+
+ context 'when there is no ref' do
+ before do
+ subject.ref = nil
+ end
+
+ it { expect(subject.for_tag?).to eq(false) }
+ end
+ end
+
+ describe '#ref_for_display' do
+ context 'when the target is a tag' do
+ before do
+ subject.ref = 'refs/tags/v1.0'
+ end
+
+ it { expect(subject.ref_for_display).to eq('v1.0') }
+ end
+
+ context 'when the target is a branch' do
+ before do
+ subject.ref = 'refs/heads/main'
+ end
+
+ it { expect(subject.ref_for_display).to eq('main') }
+ end
+
+ context 'when the ref is ambiguous' do
+ before do
+ subject.ref = 'release-2.8'
+ end
+
+ it { expect(subject.ref_for_display).to eq('release-2.8') }
+ end
+
+ context 'when there is no ref' do
+ before do
+ subject.ref = nil
+ end
+
+ it { expect(subject.ref_for_display).to eq(nil) }
+ end
+ end
+
context 'loose foreign key on ci_pipeline_schedules.project_id' do
it_behaves_like 'cleanup by a loose foreign key' do
let!(:parent) { create(:project) }
diff --git a/spec/models/ci/pipeline_spec.rb b/spec/models/ci/pipeline_spec.rb
index c29cc04e0e9..294ec07ee3e 100644
--- a/spec/models/ci/pipeline_spec.rb
+++ b/spec/models/ci/pipeline_spec.rb
@@ -438,15 +438,6 @@ RSpec.describe Ci::Pipeline, :mailer, factory_default: :keep do
it { expect(pipeline).not_to be_merge_request }
end
-
- context 'when the feature flag is disabled' do
- before do
- stub_feature_flags(ci_pipeline_merge_request_presence_check: false)
- pipeline.update!(merge_request_id: non_existing_record_id)
- end
-
- it { expect(pipeline).to be_merge_request }
- end
end
describe '#detached_merge_request_pipeline?' do
@@ -2890,6 +2881,34 @@ RSpec.describe Ci::Pipeline, :mailer, factory_default: :keep do
end
end
+ describe '.cancelable' do
+ subject { described_class.cancelable }
+
+ shared_examples 'containing the pipeline' do |status|
+ context "when it's #{status} pipeline" do
+ let!(:pipeline) { create(:ci_pipeline, status: status) }
+
+ it { is_expected.to contain_exactly(pipeline) }
+ end
+ end
+
+ shared_examples 'not containing the pipeline' do |status|
+ context "when it's #{status} pipeline" do
+ let!(:pipeline) { create(:ci_pipeline, status: status) }
+
+ it { is_expected.to be_empty }
+ end
+ end
+
+ %i[running pending waiting_for_resource preparing created scheduled manual].each do |status|
+ it_behaves_like 'containing the pipeline', status
+ end
+
+ %i[failed success skipped canceled].each do |status|
+ it_behaves_like 'not containing the pipeline', status
+ end
+ end
+
describe '#retry_failed' do
subject(:latest_status) { pipeline.latest_statuses.pluck(:status) }
diff --git a/spec/models/ci/runner_spec.rb b/spec/models/ci/runner_spec.rb
index eb29db697a5..0620bb1ffc5 100644
--- a/spec/models/ci/runner_spec.rb
+++ b/spec/models/ci/runner_spec.rb
@@ -951,7 +951,7 @@ RSpec.describe Ci::Runner do
let!(:last_update) { runner.ensure_runner_queue_value }
before do
- Ci::UpdateRunnerService.new(runner).update(description: 'new runner') # rubocop: disable Rails/SaveBang
+ Ci::Runners::UpdateRunnerService.new(runner).update(description: 'new runner') # rubocop: disable Rails/SaveBang
end
it 'sets a new last_update value' do
diff --git a/spec/models/ci/secure_file_spec.rb b/spec/models/ci/secure_file_spec.rb
index ae57b63e7a4..4382385aaf5 100644
--- a/spec/models/ci/secure_file_spec.rb
+++ b/spec/models/ci/secure_file_spec.rb
@@ -17,6 +17,10 @@ RSpec.describe Ci::SecureFile do
it_behaves_like 'having unique enum values'
+ it_behaves_like 'includes Limitable concern' do
+ subject { build(:ci_secure_file, project: create(:project)) }
+ end
+
describe 'validations' do
it { is_expected.to validate_presence_of(:checksum) }
it { is_expected.to validate_presence_of(:file_store) }
diff --git a/spec/models/concerns/batch_destroy_dependent_associations_spec.rb b/spec/models/concerns/batch_destroy_dependent_associations_spec.rb
index 993afd47a57..358000ee174 100644
--- a/spec/models/concerns/batch_destroy_dependent_associations_spec.rb
+++ b/spec/models/concerns/batch_destroy_dependent_associations_spec.rb
@@ -6,10 +6,10 @@ RSpec.describe BatchDestroyDependentAssociations do
class TestProject < ActiveRecord::Base
self.table_name = 'projects'
- has_many :builds, dependent: :destroy
+ has_many :builds
has_many :notification_settings, as: :source, dependent: :delete_all
has_many :pages_domains
- has_many :todos
+ has_many :todos, dependent: :destroy
include BatchDestroyDependentAssociations
end
@@ -18,7 +18,7 @@ RSpec.describe BatchDestroyDependentAssociations do
let_it_be(:project) { TestProject.new }
it 'returns the right associations' do
- expect(project.dependent_associations_to_destroy.map(&:name)).to match_array([:builds])
+ expect(project.dependent_associations_to_destroy.map(&:name)).to match_array([:todos])
end
end
@@ -26,36 +26,35 @@ RSpec.describe BatchDestroyDependentAssociations do
let_it_be(:project) { create(:project) }
let_it_be(:build) { create(:ci_build, project: project) }
let_it_be(:notification_setting) { create(:notification_setting, project: project) }
+ let_it_be(:note) { create(:note, project: project) }
- let!(:todos) { create(:todo, project: project) }
+ it 'destroys multiple notes' do
+ create(:note, project: project)
- it 'destroys multiple builds' do
- create(:ci_build, project: project)
-
- expect(Ci::Build.count).to eq(2)
+ expect(Note.count).to eq(2)
project.destroy_dependent_associations_in_batches
- expect(Ci::Build.count).to eq(0)
+ expect(Note.count).to eq(0)
end
- it 'destroys builds in batches' do
- expect(project).to receive_message_chain(:builds, :find_each).and_yield(build)
- expect(build).to receive(:destroy).and_call_original
+ it 'destroys note in batches' do
+ expect(project).to receive_message_chain(:notes, :find_each).and_yield(note)
+ expect(note).to receive(:destroy).and_call_original
project.destroy_dependent_associations_in_batches
- expect(Ci::Build.count).to eq(0)
- expect(Todo.count).to eq(1)
+ expect(Ci::Build.count).to eq(1)
+ expect(Note.count).to eq(0)
expect(User.count).to be > 0
expect(NotificationSetting.count).to eq(User.count)
end
it 'excludes associations' do
- project.destroy_dependent_associations_in_batches(exclude: [:builds])
+ project.destroy_dependent_associations_in_batches(exclude: [:notes])
+ expect(Note.count).to eq(1)
expect(Ci::Build.count).to eq(1)
- expect(Todo.count).to eq(1)
expect(User.count).to be > 0
expect(NotificationSetting.count).to eq(User.count)
end
diff --git a/spec/models/concerns/blocks_json_serialization_spec.rb b/spec/models/concerns/blocks_json_serialization_spec.rb
deleted file mode 100644
index d811b47fa35..00000000000
--- a/spec/models/concerns/blocks_json_serialization_spec.rb
+++ /dev/null
@@ -1,22 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe BlocksJsonSerialization do
- before do
- stub_const('DummyModel', Class.new)
- DummyModel.class_eval do
- include BlocksJsonSerialization
- end
- end
-
- it 'blocks as_json' do
- expect { DummyModel.new.as_json }
- .to raise_error(described_class::JsonSerializationError, /DummyModel/)
- end
-
- it 'blocks to_json' do
- expect { DummyModel.new.to_json }
- .to raise_error(described_class::JsonSerializationError, /DummyModel/)
- end
-end
diff --git a/spec/models/concerns/blocks_unsafe_serialization_spec.rb b/spec/models/concerns/blocks_unsafe_serialization_spec.rb
new file mode 100644
index 00000000000..5c8f5035a58
--- /dev/null
+++ b/spec/models/concerns/blocks_unsafe_serialization_spec.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe BlocksUnsafeSerialization do
+ before do
+ stub_const('DummyModel', Class.new)
+ DummyModel.class_eval do
+ include ActiveModel::Serializers::JSON
+ include BlocksUnsafeSerialization
+ end
+ end
+
+ it_behaves_like 'blocks unsafe serialization' do
+ let(:object) { DummyModel.new }
+ end
+end
diff --git a/spec/models/concerns/ci/has_deployment_name_spec.rb b/spec/models/concerns/ci/has_deployment_name_spec.rb
new file mode 100644
index 00000000000..8c7338638b1
--- /dev/null
+++ b/spec/models/concerns/ci/has_deployment_name_spec.rb
@@ -0,0 +1,34 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Ci::HasDeploymentName do
+ describe 'deployment_name?' do
+ let(:build) { create(:ci_build) }
+
+ subject { build.branch? }
+
+ it 'does detect deployment names' do
+ build.name = 'deployment'
+
+ expect(build.deployment_name?).to be_truthy
+ end
+
+ it 'does detect partial deployment names' do
+ build.name = 'do a really cool deploy'
+
+ expect(build.deployment_name?).to be_truthy
+ end
+
+ it 'does not detect non-deployment names' do
+ build.name = 'testing'
+
+ expect(build.deployment_name?).to be_falsy
+ end
+
+ it 'is case insensitive' do
+ build.name = 'DEPLOY'
+ expect(build.deployment_name?).to be_truthy
+ end
+ end
+end
diff --git a/spec/models/concerns/deployment_platform_spec.rb b/spec/models/concerns/deployment_platform_spec.rb
index 7fa55184cf1..bd1afe844ac 100644
--- a/spec/models/concerns/deployment_platform_spec.rb
+++ b/spec/models/concerns/deployment_platform_spec.rb
@@ -12,16 +12,28 @@ RSpec.describe DeploymentPlatform do
let(:group) { create(:group) }
let(:project) { create(:project, group: group) }
+ shared_examples 'certificate_based_clusters is disabled' do
+ before do
+ stub_feature_flags(certificate_based_clusters: false)
+ end
+
+ it { is_expected.to be_nil }
+ end
+
shared_examples 'matching environment scope' do
it 'returns environment specific cluster' do
is_expected.to eq(cluster.platform_kubernetes)
end
+
+ it_behaves_like 'certificate_based_clusters is disabled'
end
shared_examples 'not matching environment scope' do
it 'returns default cluster' do
is_expected.to eq(default_cluster.platform_kubernetes)
end
+
+ it_behaves_like 'certificate_based_clusters is disabled'
end
context 'multiple clusters use the same management project' do
diff --git a/spec/models/concerns/issuable_link_spec.rb b/spec/models/concerns/issuable_link_spec.rb
new file mode 100644
index 00000000000..7be6d8a074d
--- /dev/null
+++ b/spec/models/concerns/issuable_link_spec.rb
@@ -0,0 +1,43 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe IssuableLink do
+ let(:test_class) do
+ Class.new(ApplicationRecord) do
+ include IssuableLink
+
+ self.table_name = 'issue_links'
+
+ belongs_to :source, class_name: 'Issue'
+ belongs_to :target, class_name: 'Issue'
+
+ def self.name
+ 'TestClass'
+ end
+ end
+ end
+
+ describe '.inverse_link_type' do
+ it 'returns the inverse type of link' do
+ expect(test_class.inverse_link_type('relates_to')).to eq('relates_to')
+ end
+ end
+
+ describe '.issuable_type' do
+ let_it_be(:source_issue) { create(:issue) }
+ let_it_be(:target_issue) { create(:issue) }
+
+ before do
+ test_class.create!(source: source_issue, target: target_issue)
+ end
+
+ context 'when opposite relation already exists' do
+ it 'raises NotImplementedError when performing validations' do
+ instance = test_class.new(source: target_issue, target: source_issue)
+
+ expect { instance.save! }.to raise_error(NotImplementedError)
+ end
+ end
+ end
+end
diff --git a/spec/models/concerns/issuable_spec.rb b/spec/models/concerns/issuable_spec.rb
index 832d5b44e5d..e3c0e3a7a2b 100644
--- a/spec/models/concerns/issuable_spec.rb
+++ b/spec/models/concerns/issuable_spec.rb
@@ -18,7 +18,6 @@ RSpec.describe Issuable do
it { is_expected.to have_many(:notes).dependent(:destroy) }
it { is_expected.to have_many(:todos) }
it { is_expected.to have_many(:labels) }
- it { is_expected.to have_many(:note_authors).through(:notes) }
context 'Notes' do
let!(:note) { create(:note, noteable: issue, project: issue.project) }
@@ -28,6 +27,23 @@ RSpec.describe Issuable do
expect(issue.notes).not_to be_authors_loaded
expect(scoped_issue.notes).to be_authors_loaded
end
+
+ describe 'note_authors' do
+ it { is_expected.to have_many(:note_authors).through(:notes) }
+ end
+
+ describe 'user_note_authors' do
+ let_it_be(:system_user) { create(:user) }
+
+ let!(:system_note) { create(:system_note, author: system_user, noteable: issue, project: issue.project) }
+
+ it 'filters the authors to those of user notes' do
+ authors = issue.user_note_authors
+
+ expect(authors).to include(note.author)
+ expect(authors).not_to include(system_user)
+ end
+ end
end
end
@@ -572,6 +588,27 @@ RSpec.describe Issuable do
issue.to_hook_data(user, old_associations: { severity: 'unknown' })
end
end
+
+ context 'escalation status is updated' do
+ let(:issue) { create(:incident, :with_escalation_status) }
+ let(:acknowledged) { IncidentManagement::IssuableEscalationStatus::STATUSES[:acknowledged] }
+
+ before do
+ issue.escalation_status.update!(status: acknowledged)
+
+ expect(Gitlab::HookData::IssuableBuilder).to receive(:new).with(issue).and_return(builder)
+ end
+
+ it 'delegates to Gitlab::HookData::IssuableBuilder#build' do
+ expect(builder).to receive(:build).with(
+ user: user,
+ changes: hash_including(
+ 'escalation_status' => %i(triggered acknowledged)
+ ))
+
+ issue.to_hook_data(user, old_associations: { escalation_status: :triggered })
+ end
+ end
end
describe '#labels_array' do
@@ -761,7 +798,7 @@ RSpec.describe Issuable do
it 'updates issues updated_at' do
issue
- Timecop.travel(1.minute.from_now) do
+ travel_to(2.minutes.from_now) do
expect { spend_time(1800) }.to change { issue.updated_at }
end
end
@@ -786,7 +823,7 @@ RSpec.describe Issuable do
context 'when time to subtract exceeds the total time spent' do
it 'raise a validation error' do
- Timecop.travel(1.minute.from_now) do
+ travel_to(1.minute.from_now) do
expect do
expect do
spend_time(-3600)
diff --git a/spec/models/concerns/mentionable_spec.rb b/spec/models/concerns/mentionable_spec.rb
index 3c095477ea9..9daea3438cb 100644
--- a/spec/models/concerns/mentionable_spec.rb
+++ b/spec/models/concerns/mentionable_spec.rb
@@ -9,6 +9,7 @@ RSpec.describe Mentionable do
include Mentionable
attr_accessor :project, :message
+
attr_mentionable :message
def author
diff --git a/spec/models/concerns/pg_full_text_searchable_spec.rb b/spec/models/concerns/pg_full_text_searchable_spec.rb
new file mode 100644
index 00000000000..db7f652f494
--- /dev/null
+++ b/spec/models/concerns/pg_full_text_searchable_spec.rb
@@ -0,0 +1,177 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe PgFullTextSearchable do
+ let(:project) { create(:project) }
+
+ let(:model_class) do
+ Class.new(ActiveRecord::Base) do
+ include PgFullTextSearchable
+
+ self.table_name = 'issues'
+
+ belongs_to :project
+ has_one :search_data, class_name: 'Issues::SearchData'
+
+ def persist_pg_full_text_search_vector(search_vector)
+ Issues::SearchData.upsert({ project_id: project_id, issue_id: id, search_vector: search_vector }, unique_by: %i(project_id issue_id))
+ end
+
+ def self.name
+ 'Issue'
+ end
+ end
+ end
+
+ describe '.pg_full_text_searchable' do
+ it 'sets pg_full_text_searchable_columns' do
+ model_class.pg_full_text_searchable columns: [{ name: 'title', weight: 'A' }]
+
+ expect(model_class.pg_full_text_searchable_columns).to eq({ 'title' => 'A' })
+ end
+
+ it 'raises an error when called twice' do
+ model_class.pg_full_text_searchable columns: [{ name: 'title', weight: 'A' }]
+
+ expect { model_class.pg_full_text_searchable columns: [{ name: 'title', weight: 'A' }] }.to raise_error('Full text search columns already defined!')
+ end
+ end
+
+ describe 'after commit hook' do
+ let(:model) { model_class.create!(project: project) }
+
+ before do
+ model_class.pg_full_text_searchable columns: [{ name: 'title', weight: 'A' }]
+ end
+
+ context 'when specified columns are changed' do
+ it 'calls update_search_data!' do
+ expect(model).to receive(:update_search_data!)
+
+ model.update!(title: 'A new title')
+ end
+ end
+
+ context 'when specified columns are not changed' do
+ it 'does not enqueue worker' do
+ expect(model).not_to receive(:update_search_data!)
+
+ model.update!(description: 'A new description')
+ end
+ end
+ end
+
+ describe '.pg_full_text_search' do
+ let(:english) { model_class.create!(project: project, title: 'title', description: 'something english') }
+ let(:with_accent) { model_class.create!(project: project, title: 'Jürgen', description: 'Ærøskøbing') }
+ let(:japanese) { model_class.create!(project: project, title: '日本語 title', description: 'another english description') }
+
+ before do
+ model_class.pg_full_text_searchable columns: [{ name: 'title', weight: 'A' }, { name: 'description', weight: 'B' }]
+
+ [english, with_accent, japanese].each(&:update_search_data!)
+ end
+
+ it 'searches across all fields' do
+ expect(model_class.pg_full_text_search('title english')).to contain_exactly(english, japanese)
+ end
+
+ it 'searches for exact term with quotes' do
+ expect(model_class.pg_full_text_search('"something english"')).to contain_exactly(english)
+ end
+
+ it 'ignores accents' do
+ expect(model_class.pg_full_text_search('jurgen')).to contain_exactly(with_accent)
+ end
+
+ it 'does not support searching by non-Latin characters' do
+ expect(model_class.pg_full_text_search('日本')).to be_empty
+ end
+ end
+
+ describe '#update_search_data!' do
+ let(:model) { model_class.create!(project: project, title: 'title', description: 'description') }
+
+ before do
+ model_class.pg_full_text_searchable columns: [{ name: 'title', weight: 'A' }, { name: 'description', weight: 'B' }]
+ end
+
+ it 'sets the correct weights' do
+ model.update_search_data!
+
+ expect(model.search_data.search_vector).to match(/'titl':1A/)
+ expect(model.search_data.search_vector).to match(/'descript':2B/)
+ end
+
+ context 'with accented and non-Latin characters' do
+ let(:model) { model_class.create!(project: project, title: '日本語', description: 'Jürgen') }
+
+ it 'transliterates accented characters and removes non-Latin ones' do
+ model.update_search_data!
+
+ expect(model.search_data.search_vector).not_to match(/日本語/)
+ expect(model.search_data.search_vector).to match(/jurgen/)
+ end
+ end
+
+ context 'with long words' do
+ let(:model) { model_class.create!(project: project, title: 'title ' + 'long/sequence+1' * 4, description: 'description ' + '@user1' * 20) }
+
+ it 'strips words that are 50 characters or longer' do
+ model.update_search_data!
+
+ expect(model.search_data.search_vector).to match(/'titl':1A/)
+ expect(model.search_data.search_vector).not_to match(/long/)
+ expect(model.search_data.search_vector).not_to match(/sequence/)
+
+ expect(model.search_data.search_vector).to match(/'descript':2B/)
+ expect(model.search_data.search_vector).not_to match(/@user1/)
+ end
+ end
+
+ context 'when upsert times out' do
+ it 're-raises the exception' do
+ expect(Issues::SearchData).to receive(:upsert).once.and_raise(ActiveRecord::StatementTimeout)
+
+ expect { model.update_search_data! }.to raise_error(ActiveRecord::StatementTimeout)
+ end
+ end
+
+ context 'with strings that go over tsvector limit', :delete do
+ let(:long_string) { Array.new(30_000) { SecureRandom.hex }.join(' ') }
+ let(:model) { model_class.create!(project: project, title: 'title', description: long_string) }
+
+ it 'does not raise an exception' do
+ expect(Gitlab::AppJsonLogger).to receive(:error).with(
+ a_hash_including(class: model_class.name, model_id: model.id)
+ )
+
+ expect { model.update_search_data! }.not_to raise_error
+
+ expect(model.search_data).to eq(nil)
+ end
+ end
+
+ context 'when model class does not implement persist_pg_full_text_search_vector' do
+ let(:model_class) do
+ Class.new(ActiveRecord::Base) do
+ include PgFullTextSearchable
+
+ self.table_name = 'issues'
+
+ belongs_to :project
+ has_one :search_data, class_name: 'Issues::SearchData'
+
+ def self.name
+ 'Issue'
+ end
+ end
+ end
+
+ it 'raises an error' do
+ expect { model.update_search_data! }.to raise_error(NotImplementedError)
+ end
+ end
+ end
+end
diff --git a/spec/models/concerns/runners_token_prefixable_spec.rb b/spec/models/concerns/runners_token_prefixable_spec.rb
index 6127203987f..29e7b8cf4f4 100644
--- a/spec/models/concerns/runners_token_prefixable_spec.rb
+++ b/spec/models/concerns/runners_token_prefixable_spec.rb
@@ -3,18 +3,11 @@
require 'spec_helper'
RSpec.describe RunnersTokenPrefixable do
- before do
- stub_const('DummyModel', Class.new)
- DummyModel.class_eval do
- include RunnersTokenPrefixable
- end
- end
-
- describe '.runners_token_prefix' do
- subject { DummyModel.new }
+ describe 'runners token prefix' do
+ subject { described_class::RUNNERS_TOKEN_PREFIX }
- it 'returns RUNNERS_TOKEN_PREFIX' do
- expect(subject.runners_token_prefix).to eq(RunnersTokenPrefixable::RUNNERS_TOKEN_PREFIX)
+ it 'has the correct value' do
+ expect(subject).to eq('GR1348941')
end
end
end
diff --git a/spec/models/concerns/sensitive_serializable_hash_spec.rb b/spec/models/concerns/sensitive_serializable_hash_spec.rb
new file mode 100644
index 00000000000..923f9e80c1f
--- /dev/null
+++ b/spec/models/concerns/sensitive_serializable_hash_spec.rb
@@ -0,0 +1,150 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe SensitiveSerializableHash do
+ describe '.prevent_from_serialization' do
+ let(:test_class) do
+ Class.new do
+ include ActiveModel::Serialization
+ include SensitiveSerializableHash
+
+ attr_accessor :name, :super_secret
+
+ prevent_from_serialization :super_secret
+
+ def attributes
+ { 'name' => nil, 'super_secret' => nil }
+ end
+ end
+ end
+
+ let(:model) { test_class.new }
+
+ it 'does not include the field in serializable_hash' do
+ expect(model.serializable_hash).not_to include('super_secret')
+ end
+
+ context 'unsafe_serialization_hash option' do
+ it 'includes the field in serializable_hash' do
+ expect(model.serializable_hash(unsafe_serialization_hash: true)).to include('super_secret')
+ end
+ end
+
+ context 'when prevent_sensitive_fields_from_serializable_hash feature flag is disabled' do
+ before do
+ stub_feature_flags(prevent_sensitive_fields_from_serializable_hash: false)
+ end
+
+ it 'includes the field in serializable_hash' do
+ expect(model.serializable_hash).to include('super_secret')
+ end
+ end
+ end
+
+ describe '#serializable_hash' do
+ shared_examples "attr_encrypted attribute" do |klass, attribute_name|
+ context "#{klass.name}\##{attribute_name}" do
+ let(:attributes) { [attribute_name, "encrypted_#{attribute_name}", "encrypted_#{attribute_name}_iv"] }
+
+ it 'has a encrypted_attributes field' do
+ expect(klass.encrypted_attributes).to include(attribute_name.to_sym)
+ end
+
+ it 'does not include the attribute in serializable_hash', :aggregate_failures do
+ attributes.each do |attribute|
+ expect(model.attributes).to include(attribute) # double-check the attribute does exist
+
+ expect(model.serializable_hash).not_to include(attribute)
+ expect(model.to_json).not_to include(attribute)
+ expect(model.as_json).not_to include(attribute)
+ end
+ end
+
+ context 'unsafe_serialization_hash option' do
+ it 'includes the field in serializable_hash' do
+ attributes.each do |attribute|
+ expect(model.attributes).to include(attribute) # double-check the attribute does exist
+
+ expect(model.serializable_hash(unsafe_serialization_hash: true)).to include(attribute)
+ expect(model.to_json(unsafe_serialization_hash: true)).to include(attribute)
+ expect(model.as_json(unsafe_serialization_hash: true)).to include(attribute)
+ end
+ end
+ end
+ end
+ end
+
+ it_behaves_like 'attr_encrypted attribute', WebHook, 'token' do
+ let_it_be(:model) { create(:system_hook) }
+ end
+
+ it_behaves_like 'attr_encrypted attribute', Ci::InstanceVariable, 'value' do
+ let_it_be(:model) { create(:ci_instance_variable) }
+ end
+
+ shared_examples "add_authentication_token_field attribute" do |klass, attribute_name, encrypted_attribute: true, digest_attribute: false|
+ context "#{klass.name}\##{attribute_name}" do
+ let(:attributes) do
+ if digest_attribute
+ ["#{attribute_name}_digest"]
+ elsif encrypted_attribute
+ [attribute_name, "#{attribute_name}_encrypted"]
+ else
+ [attribute_name]
+ end
+ end
+
+ it 'has a add_authentication_token_field field' do
+ expect(klass.token_authenticatable_fields).to include(attribute_name.to_sym)
+ end
+
+ it 'does not include the attribute in serializable_hash', :aggregate_failures do
+ attributes.each do |attribute|
+ expect(model.attributes).to include(attribute) # double-check the attribute does exist
+
+ expect(model.serializable_hash).not_to include(attribute)
+ expect(model.to_json).not_to include(attribute)
+ expect(model.as_json).not_to include(attribute)
+ end
+ end
+
+ context 'unsafe_serialization_hash option' do
+ it 'includes the field in serializable_hash' do
+ attributes.each do |attribute|
+ expect(model.attributes).to include(attribute) # double-check the attribute does exist
+
+ expect(model.serializable_hash(unsafe_serialization_hash: true)).to include(attribute)
+ expect(model.to_json(unsafe_serialization_hash: true)).to include(attribute)
+ expect(model.as_json(unsafe_serialization_hash: true)).to include(attribute)
+ end
+ end
+ end
+ end
+ end
+
+ it_behaves_like 'add_authentication_token_field attribute', Ci::Runner, 'token' do
+ let_it_be(:model) { create(:ci_runner) }
+
+ it 'does not include token_expires_at in serializable_hash' do
+ attribute = 'token_expires_at'
+
+ expect(model.attributes).to include(attribute) # double-check the attribute does exist
+
+ expect(model.serializable_hash).not_to include(attribute)
+ expect(model.to_json).not_to include(attribute)
+ expect(model.as_json).not_to include(attribute)
+ end
+ end
+
+ it_behaves_like 'add_authentication_token_field attribute', ApplicationSetting, 'health_check_access_token', encrypted_attribute: false do
+ # health_check_access_token_encrypted column does not exist
+ let_it_be(:model) { create(:application_setting) }
+ end
+
+ it_behaves_like 'add_authentication_token_field attribute', PersonalAccessToken, 'token', encrypted_attribute: false, digest_attribute: true do
+ # PersonalAccessToken only has token_digest column
+ let_it_be(:model) { create(:personal_access_token) }
+ end
+ end
+end
diff --git a/spec/models/concerns/spammable_spec.rb b/spec/models/concerns/spammable_spec.rb
index 5edaab56e2d..baa2d75705a 100644
--- a/spec/models/concerns/spammable_spec.rb
+++ b/spec/models/concerns/spammable_spec.rb
@@ -55,7 +55,7 @@ RSpec.describe Spammable do
subject { invalidate_if_spam(needs_recaptcha: true) }
it 'has an error related to spam on the model' do
- expect(subject.errors.messages[:base]).to match_array /solve the reCAPTCHA/
+ expect(subject.errors.messages[:base]).to match_array /content or solve the/
end
end
@@ -63,7 +63,7 @@ RSpec.describe Spammable do
subject { invalidate_if_spam(is_spam: true, needs_recaptcha: true) }
it 'has an error related to spam on the model' do
- expect(subject.errors.messages[:base]).to match_array /solve the reCAPTCHA/
+ expect(subject.errors.messages[:base]).to match_array /content or solve the/
end
end
diff --git a/spec/models/concerns/token_authenticatable_spec.rb b/spec/models/concerns/token_authenticatable_spec.rb
index 4534fd3664e..d7bfcc3f579 100644
--- a/spec/models/concerns/token_authenticatable_spec.rb
+++ b/spec/models/concerns/token_authenticatable_spec.rb
@@ -9,6 +9,12 @@ RSpec.shared_examples 'TokenAuthenticatable' do
it { is_expected.to respond_to("set_#{token_field}") }
it { is_expected.to respond_to("reset_#{token_field}!") }
end
+
+ describe 'SensitiveSerializableHash' do
+ it 'includes the token field in list of sensitive attributes prevented from serialization' do
+ expect(described_class.attributes_exempt_from_serializable_hash).to include(token_field)
+ end
+ end
end
RSpec.describe User, 'TokenAuthenticatable' do
diff --git a/spec/models/concerns/token_authenticatable_strategies/base_spec.rb b/spec/models/concerns/token_authenticatable_strategies/base_spec.rb
index bccef9b9554..89ddc797a9d 100644
--- a/spec/models/concerns/token_authenticatable_strategies/base_spec.rb
+++ b/spec/models/concerns/token_authenticatable_strategies/base_spec.rb
@@ -6,6 +6,24 @@ RSpec.describe TokenAuthenticatableStrategies::Base do
let(:instance) { double(:instance) }
let(:field) { double(:field) }
+ describe '#token_fields' do
+ let(:strategy) { described_class.new(instance, field, options) }
+ let(:field) { 'some_token' }
+ let(:options) { {} }
+
+ it 'includes the token field' do
+ expect(strategy.token_fields).to contain_exactly(field)
+ end
+
+ context 'with expires_at option' do
+ let(:options) { { expires_at: true } }
+
+ it 'includes the token_expires_at field' do
+ expect(strategy.token_fields).to contain_exactly(field, 'some_token_expires_at')
+ end
+ end
+ end
+
describe '.fabricate' do
context 'when digest stragegy is specified' do
it 'fabricates digest strategy object' do
diff --git a/spec/models/concerns/token_authenticatable_strategies/digest_spec.rb b/spec/models/concerns/token_authenticatable_strategies/digest_spec.rb
new file mode 100644
index 00000000000..bcd6e1e7316
--- /dev/null
+++ b/spec/models/concerns/token_authenticatable_strategies/digest_spec.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe TokenAuthenticatableStrategies::Digest do
+ let(:model) { class_double('Project') }
+ let(:options) { { digest: true } }
+
+ subject(:strategy) do
+ described_class.new(model, 'some_field', options)
+ end
+
+ describe '#token_fields' do
+ it 'includes the digest field' do
+ expect(strategy.token_fields).to contain_exactly('some_field', 'some_field_digest')
+ end
+ end
+end
diff --git a/spec/models/concerns/token_authenticatable_strategies/encrypted_spec.rb b/spec/models/concerns/token_authenticatable_strategies/encrypted_spec.rb
index 458dfb47394..e0ebb86585a 100644
--- a/spec/models/concerns/token_authenticatable_strategies/encrypted_spec.rb
+++ b/spec/models/concerns/token_authenticatable_strategies/encrypted_spec.rb
@@ -14,10 +14,18 @@ RSpec.describe TokenAuthenticatableStrategies::Encrypted do
Gitlab::CryptoHelper.aes256_gcm_encrypt('my-value')
end
- subject do
+ subject(:strategy) do
described_class.new(model, 'some_field', options)
end
+ describe '#token_fields' do
+ let(:options) { { encrypted: :required } }
+
+ it 'includes the encrypted field' do
+ expect(strategy.token_fields).to contain_exactly('some_field', 'some_field_encrypted')
+ end
+ end
+
describe '#find_token_authenticatable' do
context 'when encryption is required' do
let(:options) { { encrypted: :required } }
diff --git a/spec/models/container_repository_spec.rb b/spec/models/container_repository_spec.rb
index 7c0ae51223b..c8d86edc55f 100644
--- a/spec/models/container_repository_spec.rb
+++ b/spec/models/container_repository_spec.rb
@@ -653,6 +653,58 @@ RSpec.describe ContainerRepository, :aggregate_failures do
end
end
+ describe '#size' do
+ let(:on_com) { true }
+ let(:created_at) { described_class::MIGRATION_PHASE_1_STARTED_AT + 3.months }
+
+ subject { repository.size }
+
+ before do
+ allow(::Gitlab).to receive(:com?).and_return(on_com)
+ allow(repository).to receive(:created_at).and_return(created_at)
+ end
+
+ context 'supports gitlab api on .com with a recent repository' do
+ before do
+ expect(repository.gitlab_api_client).to receive(:supports_gitlab_api?).and_return(true)
+ expect(repository.gitlab_api_client).to receive(:repository_details).with(repository.path, with_size: true).and_return(response)
+ end
+
+ context 'with a size_bytes field' do
+ let(:response) { { 'size_bytes' => 12345 } }
+
+ it { is_expected.to eq(12345) }
+ end
+
+ context 'without a size_bytes field' do
+ let(:response) { { 'foo' => 'bar' } }
+
+ it { is_expected.to eq(nil) }
+ end
+ end
+
+ context 'does not support gitlab api' do
+ before do
+ expect(repository.gitlab_api_client).to receive(:supports_gitlab_api?).and_return(false)
+ expect(repository.gitlab_api_client).not_to receive(:repository_details)
+ end
+
+ it { is_expected.to eq(nil) }
+ end
+
+ context 'not on .com' do
+ let(:on_com) { false }
+
+ it { is_expected.to eq(nil) }
+ end
+
+ context 'with an old repository' do
+ let(:created_at) { described_class::MIGRATION_PHASE_1_STARTED_AT - 3.months }
+
+ it { is_expected.to eq(nil) }
+ end
+ end
+
describe '#reset_expiration_policy_started_at!' do
subject { repository.reset_expiration_policy_started_at! }
@@ -1203,7 +1255,7 @@ RSpec.describe ContainerRepository, :aggregate_failures do
subject { described_class.ready_for_import }
before do
- stub_application_setting(container_registry_import_target_plan: project.namespace.actual_plan_name)
+ stub_application_setting(container_registry_import_target_plan: root_group.actual_plan_name)
end
it 'works' do
diff --git a/spec/models/customer_relations/contact_spec.rb b/spec/models/customer_relations/contact_spec.rb
index c7b0f1bd3d4..18896962261 100644
--- a/spec/models/customer_relations/contact_spec.rb
+++ b/spec/models/customer_relations/contact_spec.rb
@@ -3,6 +3,8 @@
require 'spec_helper'
RSpec.describe CustomerRelations::Contact, type: :model do
+ let_it_be(:group) { create(:group) }
+
describe 'associations' do
it { is_expected.to belong_to(:group) }
it { is_expected.to belong_to(:organization).optional }
@@ -23,6 +25,8 @@ RSpec.describe CustomerRelations::Contact, type: :model do
it { is_expected.to validate_length_of(:email).is_at_most(255) }
it { is_expected.to validate_length_of(:description).is_at_most(1024) }
+ it { is_expected.to validate_uniqueness_of(:email).scoped_to(:group_id) }
+
it_behaves_like 'an object with RFC3696 compliant email-formatted attributes', :email
end
@@ -38,33 +42,15 @@ RSpec.describe CustomerRelations::Contact, type: :model do
it { expect(described_class.reference_postfix).to eq(']') }
end
- describe '#unique_email_for_group_hierarchy' do
- let_it_be(:parent) { create(:group) }
- let_it_be(:group) { create(:group, parent: parent) }
- let_it_be(:subgroup) { create(:group, parent: group) }
-
- let_it_be(:existing_contact) { create(:contact, group: group) }
-
- context 'with unique email for group hierarchy' do
+ describe '#root_group' do
+ context 'when root group' do
subject { build(:contact, group: group) }
it { is_expected.to be_valid }
end
- context 'with duplicate email in group' do
- subject { build(:contact, email: existing_contact.email, group: group) }
-
- it { is_expected.to be_invalid }
- end
-
- context 'with duplicate email in parent group' do
- subject { build(:contact, email: existing_contact.email, group: subgroup) }
-
- it { is_expected.to be_invalid }
- end
-
- context 'with duplicate email in subgroup' do
- subject { build(:contact, email: existing_contact.email, group: parent) }
+ context 'when subgroup' do
+ subject { build(:contact, group: create(:group, parent: group)) }
it { is_expected.to be_invalid }
end
@@ -82,7 +68,6 @@ RSpec.describe CustomerRelations::Contact, type: :model do
end
describe '#self.find_ids_by_emails' do
- let_it_be(:group) { create(:group) }
let_it_be(:group_contacts) { create_list(:contact, 2, group: group) }
let_it_be(:other_contacts) { create_list(:contact, 2) }
@@ -92,13 +77,6 @@ RSpec.describe CustomerRelations::Contact, type: :model do
expect(contact_ids).to match_array(group_contacts.pluck(:id))
end
- it 'returns ids of contacts from parent group' do
- subgroup = create(:group, parent: group)
- contact_ids = described_class.find_ids_by_emails(subgroup, group_contacts.pluck(:email))
-
- expect(contact_ids).to match_array(group_contacts.pluck(:id))
- end
-
it 'does not return ids of contacts from other groups' do
contact_ids = described_class.find_ids_by_emails(group, other_contacts.pluck(:email))
@@ -112,28 +90,17 @@ RSpec.describe CustomerRelations::Contact, type: :model do
end
describe '#self.exists_for_group?' do
- let(:group) { create(:group) }
- let(:subgroup) { create(:group, parent: group) }
-
- context 'with no contacts in group or parent' do
+ context 'with no contacts in group' do
it 'returns false' do
- expect(described_class.exists_for_group?(subgroup)).to be_falsey
+ expect(described_class.exists_for_group?(group)).to be_falsey
end
end
context 'with contacts in group' do
it 'returns true' do
- create(:contact, group: subgroup)
-
- expect(described_class.exists_for_group?(subgroup)).to be_truthy
- end
- end
-
- context 'with contacts in parent' do
- it 'returns true' do
create(:contact, group: group)
- expect(described_class.exists_for_group?(subgroup)).to be_truthy
+ expect(described_class.exists_for_group?(group)).to be_truthy
end
end
end
diff --git a/spec/models/customer_relations/issue_contact_spec.rb b/spec/models/customer_relations/issue_contact_spec.rb
index 39da0b64ea0..f1fb574f86f 100644
--- a/spec/models/customer_relations/issue_contact_spec.rb
+++ b/spec/models/customer_relations/issue_contact_spec.rb
@@ -6,7 +6,8 @@ RSpec.describe CustomerRelations::IssueContact do
let_it_be(:issue_contact, reload: true) { create(:issue_customer_relations_contact) }
let_it_be(:group) { create(:group) }
let_it_be(:subgroup) { create(:group, parent: group) }
- let_it_be(:project) { create(:project, group: subgroup) }
+ let_it_be(:project) { create(:project, group: group) }
+ let_it_be(:subgroup_project) { create(:project, group: subgroup) }
let_it_be(:issue) { create(:issue, project: project) }
subject { issue_contact }
@@ -27,33 +28,36 @@ RSpec.describe CustomerRelations::IssueContact do
let(:for_issue) { build(:issue_customer_relations_contact, :for_issue, issue: issue) }
let(:for_contact) { build(:issue_customer_relations_contact, :for_contact, contact: contact) }
- it 'uses objects from the same group', :aggregate_failures do
- expect(stubbed.contact.group).to eq(stubbed.issue.project.group)
- expect(built.contact.group).to eq(built.issue.project.group)
- expect(created.contact.group).to eq(created.issue.project.group)
+ context 'for root groups' do
+ it 'uses objects from the same group', :aggregate_failures do
+ expect(stubbed.contact.group).to eq(stubbed.issue.project.group)
+ expect(built.contact.group).to eq(built.issue.project.group)
+ expect(created.contact.group).to eq(created.issue.project.group)
+ end
end
- it 'builds using the same group', :aggregate_failures do
- expect(for_issue.contact.group).to eq(subgroup)
- expect(for_contact.issue.project.group).to eq(group)
+ context 'for subgroups' do
+ it 'builds using the root ancestor' do
+ expect(for_issue.contact.group).to eq(group)
+ end
end
end
describe 'validation' do
- it 'fails when the contact group does not belong to the issue group or ancestors' do
+ it 'fails when the contact group is unrelated to the issue group' do
built = build(:issue_customer_relations_contact, issue: create(:issue), contact: create(:contact))
expect(built).not_to be_valid
end
- it 'succeeds when the contact group is the same as the issue group' do
- built = build(:issue_customer_relations_contact, issue: create(:issue, project: project), contact: create(:contact, group: subgroup))
+ it 'succeeds when the contact belongs to a root group and is the same as the issue group' do
+ built = build(:issue_customer_relations_contact, issue: create(:issue, project: project), contact: create(:contact, group: group))
expect(built).to be_valid
end
- it 'succeeds when the contact group is an ancestor of the issue group' do
- built = build(:issue_customer_relations_contact, issue: create(:issue, project: project), contact: create(:contact, group: group))
+ it 'succeeds when the contact belongs to a root group and it is an ancestor of the issue group' do
+ built = build(:issue_customer_relations_contact, issue: create(:issue, project: subgroup_project), contact: create(:contact, group: group))
expect(built).to be_valid
end
diff --git a/spec/models/customer_relations/organization_spec.rb b/spec/models/customer_relations/organization_spec.rb
index 71b455ae8c8..9fe754b7605 100644
--- a/spec/models/customer_relations/organization_spec.rb
+++ b/spec/models/customer_relations/organization_spec.rb
@@ -3,6 +3,8 @@
require 'spec_helper'
RSpec.describe CustomerRelations::Organization, type: :model do
+ let_it_be(:group) { create(:group) }
+
describe 'associations' do
it { is_expected.to belong_to(:group).with_foreign_key('group_id') }
end
@@ -17,6 +19,20 @@ RSpec.describe CustomerRelations::Organization, type: :model do
it { is_expected.to validate_length_of(:description).is_at_most(1024) }
end
+ describe '#root_group' do
+ context 'when root group' do
+ subject { build(:organization, group: group) }
+
+ it { is_expected.to be_valid }
+ end
+
+ context 'when subgroup' do
+ subject { build(:organization, group: create(:group, parent: group)) }
+
+ it { is_expected.to be_invalid }
+ end
+ end
+
describe '#name' do
it 'strips name' do
organization = described_class.new(name: ' GitLab ')
@@ -27,7 +43,6 @@ RSpec.describe CustomerRelations::Organization, type: :model do
end
describe '#find_by_name' do
- let!(:group) { create(:group) }
let!(:organiztion1) { create(:organization, group: group, name: 'Test') }
let!(:organiztion2) { create(:organization, group: create(:group), name: 'Test') }
diff --git a/spec/models/dependency_proxy/blob_spec.rb b/spec/models/dependency_proxy/blob_spec.rb
index 10d06406ad7..cc62aecd1ab 100644
--- a/spec/models/dependency_proxy/blob_spec.rb
+++ b/spec/models/dependency_proxy/blob_spec.rb
@@ -5,6 +5,10 @@ RSpec.describe DependencyProxy::Blob, type: :model do
it_behaves_like 'ttl_expirable'
it_behaves_like 'destructible', factory: :dependency_proxy_blob
+ it_behaves_like 'updates namespace statistics' do
+ let(:statistic_source) { build(:dependency_proxy_blob, size: 10) }
+ end
+
describe 'relationships' do
it { is_expected.to belong_to(:group) }
end
diff --git a/spec/models/dependency_proxy/manifest_spec.rb b/spec/models/dependency_proxy/manifest_spec.rb
index ab7881b1d39..d43079f607a 100644
--- a/spec/models/dependency_proxy/manifest_spec.rb
+++ b/spec/models/dependency_proxy/manifest_spec.rb
@@ -5,6 +5,10 @@ RSpec.describe DependencyProxy::Manifest, type: :model do
it_behaves_like 'ttl_expirable'
it_behaves_like 'destructible', factory: :dependency_proxy_manifest
+ it_behaves_like 'updates namespace statistics' do
+ let(:statistic_source) { build(:dependency_proxy_manifest, size: 10) }
+ end
+
describe 'relationships' do
it { is_expected.to belong_to(:group) }
end
diff --git a/spec/models/environment_spec.rb b/spec/models/environment_spec.rb
index 112dc93658f..6144593395c 100644
--- a/spec/models/environment_spec.rb
+++ b/spec/models/environment_spec.rb
@@ -282,6 +282,13 @@ RSpec.describe Environment, :use_clean_rails_memory_store_caching do
'DEV' | described_class.tiers[:development]
'development' | described_class.tiers[:development]
'trunk' | described_class.tiers[:development]
+ 'dev' | described_class.tiers[:development]
+ 'review/app' | described_class.tiers[:development]
+ 'PRODUCTION' | described_class.tiers[:production]
+ 'prod' | described_class.tiers[:production]
+ 'prod-east-2' | described_class.tiers[:production]
+ 'us-prod-east' | described_class.tiers[:production]
+ 'fe-production' | described_class.tiers[:production]
'test' | described_class.tiers[:testing]
'TEST' | described_class.tiers[:testing]
'testing' | described_class.tiers[:testing]
@@ -290,6 +297,7 @@ RSpec.describe Environment, :use_clean_rails_memory_store_caching do
'production-test' | described_class.tiers[:testing]
'test-production' | described_class.tiers[:testing]
'QC' | described_class.tiers[:testing]
+ 'qa-env-2' | described_class.tiers[:testing]
'gstg' | described_class.tiers[:staging]
'staging' | described_class.tiers[:staging]
'stage' | described_class.tiers[:staging]
@@ -298,6 +306,10 @@ RSpec.describe Environment, :use_clean_rails_memory_store_caching do
'Pre-production' | described_class.tiers[:staging]
'pre' | described_class.tiers[:staging]
'Demo' | described_class.tiers[:staging]
+ 'staging' | described_class.tiers[:staging]
+ 'pre-prod' | described_class.tiers[:staging]
+ 'blue-kit-stage' | described_class.tiers[:staging]
+ 'pre-prod' | described_class.tiers[:staging]
'gprd' | described_class.tiers[:production]
'gprd-cny' | described_class.tiers[:production]
'production' | described_class.tiers[:production]
@@ -307,6 +319,8 @@ RSpec.describe Environment, :use_clean_rails_memory_store_caching do
'production/eu' | described_class.tiers[:production]
'PRODUCTION/EU' | described_class.tiers[:production]
'productioneu' | described_class.tiers[:production]
+ 'store-produce' | described_class.tiers[:production]
+ 'unproductive' | described_class.tiers[:production]
'production/www.gitlab.com' | described_class.tiers[:production]
'prod' | described_class.tiers[:production]
'PROD' | described_class.tiers[:production]
@@ -314,6 +328,7 @@ RSpec.describe Environment, :use_clean_rails_memory_store_caching do
'canary' | described_class.tiers[:other]
'other' | described_class.tiers[:other]
'EXP' | described_class.tiers[:other]
+ 'something-else' | described_class.tiers[:other]
end
with_them do
diff --git a/spec/models/error_tracking/project_error_tracking_setting_spec.rb b/spec/models/error_tracking/project_error_tracking_setting_spec.rb
index d17541b4a6c..d700eb5eaf7 100644
--- a/spec/models/error_tracking/project_error_tracking_setting_spec.rb
+++ b/spec/models/error_tracking/project_error_tracking_setting_spec.rb
@@ -535,6 +535,25 @@ RSpec.describe ErrorTracking::ProjectErrorTrackingSetting do
end
end
+ describe '#integrated_enabled?' do
+ using RSpec::Parameterized::TableSyntax
+
+ where(:enabled, :integrated, :integrated_enabled) do
+ true | false | false
+ false | true | false
+ true | true | true
+ end
+
+ with_them do
+ before do
+ subject.enabled = enabled
+ subject.integrated = integrated
+ end
+
+ it { expect(subject.integrated_enabled?).to eq(integrated_enabled) }
+ end
+ end
+
describe '#gitlab_dsn' do
let!(:client_key) { create(:error_tracking_client_key, project: project) }
diff --git a/spec/models/event_collection_spec.rb b/spec/models/event_collection_spec.rb
index 107447c9630..036072aab76 100644
--- a/spec/models/event_collection_spec.rb
+++ b/spec/models/event_collection_spec.rb
@@ -71,9 +71,9 @@ RSpec.describe EventCollection do
end
it 'can paginate through events' do
- events = described_class.new(projects, offset: 20).to_a
+ events = described_class.new(projects, limit: 5, offset: 15).to_a
- expect(events.length).to eq(2)
+ expect(events.length).to eq(5)
end
it 'returns an empty Array when crossing the maximum page number' do
@@ -124,6 +124,19 @@ RSpec.describe EventCollection do
expect(subject).to eq([event1])
end
+
+ context 'pagination through events' do
+ let_it_be(:project_events) { create_list(:event, 10, project: project) }
+ let_it_be(:group_events) { create_list(:event, 10, group: group, author: user) }
+
+ let(:subject) { described_class.new(projects, limit: 10, offset: 5, groups: groups).to_a }
+
+ it 'returns recent groups and projects events' do
+ recent_events_with_offset = (project_events[5..] + group_events[..4]).reverse
+
+ expect(subject).to eq(recent_events_with_offset)
+ end
+ end
end
end
end
diff --git a/spec/models/external_pull_request_spec.rb b/spec/models/external_pull_request_spec.rb
index 82da7cdf34b..10136dd0bdb 100644
--- a/spec/models/external_pull_request_spec.rb
+++ b/spec/models/external_pull_request_spec.rb
@@ -233,10 +233,6 @@ RSpec.describe ExternalPullRequest do
end
end
- it_behaves_like 'it has loose foreign keys' do
- let(:factory_name) { :external_pull_request }
- end
-
context 'loose foreign key on external_pull_requests.project_id' do
it_behaves_like 'cleanup by a loose foreign key' do
let!(:parent) { create(:project) }
diff --git a/spec/models/group_spec.rb b/spec/models/group_spec.rb
index b6c7d61a291..45a2c134077 100644
--- a/spec/models/group_spec.rb
+++ b/spec/models/group_spec.rb
@@ -385,23 +385,25 @@ RSpec.describe Group do
end
end
- before do
- subject
- reload_models(old_parent, new_parent, group)
- end
-
context 'within the same hierarchy' do
let!(:root) { create(:group).reload }
let!(:old_parent) { create(:group, parent: root) }
let!(:new_parent) { create(:group, parent: root) }
- it 'updates traversal_ids' do
- expect(group.traversal_ids).to eq [root.id, new_parent.id, group.id]
- end
+ context 'with FOR NO KEY UPDATE lock' do
+ before do
+ subject
+ reload_models(old_parent, new_parent, group)
+ end
- it_behaves_like 'hierarchy with traversal_ids'
- it_behaves_like 'locked row' do
- let(:row) { root }
+ it 'updates traversal_ids' do
+ expect(group.traversal_ids).to eq [root.id, new_parent.id, group.id]
+ end
+
+ it_behaves_like 'hierarchy with traversal_ids'
+ it_behaves_like 'locked row' do
+ let(:row) { root }
+ end
end
end
@@ -410,6 +412,11 @@ RSpec.describe Group do
let!(:new_parent) { create(:group) }
let!(:group) { create(:group, parent: old_parent) }
+ before do
+ subject
+ reload_models(old_parent, new_parent, group)
+ end
+
it 'updates traversal_ids' do
expect(group.traversal_ids).to eq [new_parent.id, group.id]
end
@@ -435,6 +442,11 @@ RSpec.describe Group do
let!(:old_parent) { nil }
let!(:new_parent) { create(:group) }
+ before do
+ subject
+ reload_models(old_parent, new_parent, group)
+ end
+
it 'updates traversal_ids' do
expect(group.traversal_ids).to eq [new_parent.id, group.id]
end
@@ -452,6 +464,11 @@ RSpec.describe Group do
let!(:old_parent) { create(:group) }
let!(:new_parent) { nil }
+ before do
+ subject
+ reload_models(old_parent, new_parent, group)
+ end
+
it 'updates traversal_ids' do
expect(group.traversal_ids).to eq [group.id]
end
@@ -1327,10 +1344,14 @@ RSpec.describe Group do
let!(:group) { create(:group, :nested) }
let!(:maintainer) { group.parent.add_user(create(:user), GroupMember::MAINTAINER) }
let!(:developer) { group.add_user(create(:user), GroupMember::DEVELOPER) }
+ let!(:pending_maintainer) { create(:group_member, :awaiting, :maintainer, group: group.parent) }
+ let!(:pending_developer) { create(:group_member, :awaiting, :developer, group: group) }
- it 'returns parents members' do
+ it 'returns parents active members' do
expect(group.members_with_parents).to include(developer)
expect(group.members_with_parents).to include(maintainer)
+ expect(group.members_with_parents).not_to include(pending_developer)
+ expect(group.members_with_parents).not_to include(pending_maintainer)
end
context 'group sharing' do
@@ -1340,9 +1361,11 @@ RSpec.describe Group do
create(:group_group_link, shared_group: shared_group, shared_with_group: group)
end
- it 'returns shared with group members' do
+ it 'returns shared with group active members' do
expect(shared_group.members_with_parents).to(
include(developer))
+ expect(shared_group.members_with_parents).not_to(
+ include(pending_developer))
end
end
end
@@ -2168,7 +2191,7 @@ RSpec.describe Group do
let(:group) { create(:group) }
- subject { group.first_auto_devops_config }
+ subject(:fetch_config) { group.first_auto_devops_config }
where(:instance_value, :group_value, :config) do
# Instance level enabled
@@ -2193,6 +2216,8 @@ RSpec.describe Group do
end
context 'with parent groups' do
+ let(:parent) { create(:group) }
+
where(:instance_value, :parent_value, :group_value, :config) do
# Instance level enabled
true | nil | nil | { status: true, scope: :instance }
@@ -2222,17 +2247,82 @@ RSpec.describe Group do
end
with_them do
+ def define_cache_expectations(cache_key)
+ if group_value.nil?
+ expect(Rails.cache).to receive(:fetch).with(start_with(cache_key), expires_in: 1.day)
+ else
+ expect(Rails.cache).not_to receive(:fetch).with(start_with(cache_key), expires_in: 1.day)
+ end
+ end
+
before do
stub_application_setting(auto_devops_enabled: instance_value)
- parent = create(:group, auto_devops_enabled: parent_value)
group.update!(
auto_devops_enabled: group_value,
parent: parent
)
+ parent.update!(auto_devops_enabled: parent_value)
+
+ group.reload # Reload so we get the populated traversal IDs
end
it { is_expected.to eq(config) }
+
+ it 'caches the parent config when group auto_devops_enabled is nil' do
+ cache_key = "namespaces:{#{group.traversal_ids.first}}:first_auto_devops_config:#{group.id}"
+ define_cache_expectations(cache_key)
+
+ fetch_config
+ end
+
+ context 'when traversal ID feature flags are disabled' do
+ before do
+ stub_feature_flags(sync_traversal_ids: false)
+ end
+
+ it 'caches the parent config when group auto_devops_enabled is nil' do
+ cache_key = "namespaces:{first_auto_devops_config}:#{group.id}"
+ define_cache_expectations(cache_key)
+
+ fetch_config
+ end
+ end
+ end
+
+ context 'cache expiration' do
+ before do
+ group.update!(parent: parent)
+
+ reload_models(parent)
+ end
+
+ it 'clears both self and descendant cache when the parent value is updated' do
+ expect(Rails.cache).to receive(:delete_multi)
+ .with(
+ match_array([
+ start_with("namespaces:{#{parent.traversal_ids.first}}:first_auto_devops_config:#{parent.id}"),
+ start_with("namespaces:{#{parent.traversal_ids.first}}:first_auto_devops_config:#{group.id}")
+ ])
+ )
+
+ parent.update!(auto_devops_enabled: true)
+ end
+
+ it 'only clears self cache when there are no dependents' do
+ expect(Rails.cache).to receive(:delete_multi)
+ .with([start_with("namespaces:{#{group.traversal_ids.first}}:first_auto_devops_config:#{group.id}")])
+
+ group.update!(auto_devops_enabled: true)
+ end
+
+ it 'does not clear cache when the feature is disabled' do
+ stub_feature_flags(namespaces_cache_first_auto_devops_config: false)
+
+ expect(Rails.cache).not_to receive(:delete_multi)
+
+ parent.update!(auto_devops_enabled: true)
+ end
end
end
end
@@ -2860,7 +2950,14 @@ RSpec.describe Group do
expect(group.crm_enabled?).to be_truthy
end
+
+ it 'returns true where crm_settings.state is enabled for subgroup' do
+ subgroup = create(:group, :crm_enabled, parent: group)
+
+ expect(subgroup.crm_enabled?).to be_truthy
+ end
end
+
describe '.get_ids_by_ids_or_paths' do
let(:group_path) { 'group_path' }
let!(:group) { create(:group, path: group_path) }
@@ -3149,12 +3246,4 @@ RSpec.describe Group do
it_behaves_like 'no effective expiration interval'
end
end
-
- describe '#runners_token' do
- let_it_be(:group) { create(:group) }
-
- subject { group }
-
- it_behaves_like 'it has a prefixable runners_token'
- end
end
diff --git a/spec/models/hooks/web_hook_log_spec.rb b/spec/models/hooks/web_hook_log_spec.rb
index 8dd9cf9e84a..9cfbb14e087 100644
--- a/spec/models/hooks/web_hook_log_spec.rb
+++ b/spec/models/hooks/web_hook_log_spec.rb
@@ -15,7 +15,7 @@ RSpec.describe WebHookLog do
let(:hook) { create(:project_hook) }
it 'does not return web hook logs that are too old' do
- create(:web_hook_log, web_hook: hook, created_at: 91.days.ago)
+ create(:web_hook_log, web_hook: hook, created_at: 10.days.ago)
expect(described_class.recent.size).to be_zero
end
diff --git a/spec/models/hooks/web_hook_spec.rb b/spec/models/hooks/web_hook_spec.rb
index 482e372543c..dd954e08156 100644
--- a/spec/models/hooks/web_hook_spec.rb
+++ b/spec/models/hooks/web_hook_spec.rb
@@ -432,6 +432,12 @@ RSpec.describe WebHook do
expect(hook).not_to be_temporarily_disabled
end
+
+ it 'can ignore the feature flag' do
+ stub_feature_flags(web_hooks_disable_failed: false)
+
+ expect(hook).to be_temporarily_disabled(ignore_flag: true)
+ end
end
end
@@ -454,6 +460,12 @@ RSpec.describe WebHook do
expect(hook).not_to be_permanently_disabled
end
+
+ it 'can ignore the feature flag' do
+ stub_feature_flags(web_hooks_disable_failed: false)
+
+ expect(hook).to be_permanently_disabled(ignore_flag: true)
+ end
end
end
diff --git a/spec/models/incident_management/issuable_escalation_status_spec.rb b/spec/models/incident_management/issuable_escalation_status_spec.rb
index c548357bd3f..f956be3a04e 100644
--- a/spec/models/incident_management/issuable_escalation_status_spec.rb
+++ b/spec/models/incident_management/issuable_escalation_status_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
RSpec.describe IncidentManagement::IssuableEscalationStatus do
- let_it_be(:issue) { create(:issue) }
+ let_it_be(:issue) { create(:incident) }
subject(:escalation_status) { build(:incident_management_issuable_escalation_status, issue: issue) }
diff --git a/spec/models/instance_configuration_spec.rb b/spec/models/instance_configuration_spec.rb
index 6b0d8d7ca4a..3af717798c3 100644
--- a/spec/models/instance_configuration_spec.rb
+++ b/spec/models/instance_configuration_spec.rb
@@ -206,7 +206,8 @@ RSpec.describe InstanceConfiguration do
group_download_export_limit: 1019,
group_import_limit: 1020,
raw_blob_request_limit: 1021,
- user_email_lookup_limit: 1022,
+ search_rate_limit: 1022,
+ search_rate_limit_unauthenticated: 1000,
users_get_by_id_limit: 1023
)
end
@@ -230,7 +231,8 @@ RSpec.describe InstanceConfiguration do
expect(rate_limits[:group_export_download]).to eq({ enabled: true, requests_per_period: 1019, period_in_seconds: 60 })
expect(rate_limits[:group_import]).to eq({ enabled: true, requests_per_period: 1020, period_in_seconds: 60 })
expect(rate_limits[:raw_blob]).to eq({ enabled: true, requests_per_period: 1021, period_in_seconds: 60 })
- expect(rate_limits[:user_email_lookup]).to eq({ enabled: true, requests_per_period: 1022, period_in_seconds: 60 })
+ expect(rate_limits[:search_rate_limit]).to eq({ enabled: true, requests_per_period: 1022, period_in_seconds: 60 })
+ expect(rate_limits[:search_rate_limit_unauthenticated]).to eq({ enabled: true, requests_per_period: 1000, period_in_seconds: 60 })
expect(rate_limits[:users_get_by_id]).to eq({ enabled: true, requests_per_period: 1023, period_in_seconds: 600 })
end
end
diff --git a/spec/models/integration_spec.rb b/spec/models/integration_spec.rb
index e822620ab80..48d8ba975b6 100644
--- a/spec/models/integration_spec.rb
+++ b/spec/models/integration_spec.rb
@@ -85,14 +85,14 @@ RSpec.describe Integration do
subject { described_class.by_type(type) }
- context 'when type is "JiraService"' do
- let(:type) { 'JiraService' }
+ context 'when type is "Integrations::JiraService"' do
+ let(:type) { 'Integrations::Jira' }
it { is_expected.to match_array([integration1, integration2]) }
end
- context 'when type is "RedmineService"' do
- let(:type) { 'RedmineService' }
+ context 'when type is "Integrations::Redmine"' do
+ let(:type) { 'Integrations::Redmine' }
it { is_expected.to match_array([integration3]) }
end
@@ -103,7 +103,7 @@ RSpec.describe Integration do
let!(:integration2) { create(:jira_integration) }
it 'returns the right group integration' do
- expect(described_class.for_group(group)).to match_array([integration1])
+ expect(described_class.for_group(group)).to contain_exactly(integration1)
end
end
@@ -268,7 +268,7 @@ RSpec.describe Integration do
describe '.build_from_integration' do
context 'when integration is invalid' do
let(:invalid_integration) do
- build(:prometheus_integration, :template, active: true, properties: {})
+ build(:prometheus_integration, :instance, active: true, properties: {})
.tap { |integration| integration.save!(validate: false) }
end
@@ -376,22 +376,24 @@ RSpec.describe Integration do
let_it_be(:instance_integration) { create(:jira_integration, :instance) }
it 'returns the instance integration' do
- expect(described_class.default_integration('JiraService', project)).to eq(instance_integration)
+ expect(described_class.default_integration('Integrations::Jira', project)).to eq(instance_integration)
end
it 'returns nil for nonexistent integration type' do
- expect(described_class.default_integration('HipchatService', project)).to eq(nil)
+ expect(described_class.default_integration('Integrations::Hipchat', project)).to eq(nil)
end
context 'with a group integration' do
+ let(:integration_name) { 'Integrations::Jira' }
+
let_it_be(:group_integration) { create(:jira_integration, group_id: group.id, project_id: nil) }
it 'returns the group integration for a project' do
- expect(described_class.default_integration('JiraService', project)).to eq(group_integration)
+ expect(described_class.default_integration(integration_name, project)).to eq(group_integration)
end
it 'returns the instance integration for a group' do
- expect(described_class.default_integration('JiraService', group)).to eq(instance_integration)
+ expect(described_class.default_integration(integration_name, group)).to eq(instance_integration)
end
context 'with a subgroup' do
@@ -400,18 +402,18 @@ RSpec.describe Integration do
let!(:project) { create(:project, group: subgroup) }
it 'returns the closest group integration for a project' do
- expect(described_class.default_integration('JiraService', project)).to eq(group_integration)
+ expect(described_class.default_integration(integration_name, project)).to eq(group_integration)
end
it 'returns the closest group integration for a subgroup' do
- expect(described_class.default_integration('JiraService', subgroup)).to eq(group_integration)
+ expect(described_class.default_integration(integration_name, subgroup)).to eq(group_integration)
end
context 'having a integration with custom settings' do
let!(:subgroup_integration) { create(:jira_integration, group_id: subgroup.id, project_id: nil) }
it 'returns the closest group integration for a project' do
- expect(described_class.default_integration('JiraService', project)).to eq(subgroup_integration)
+ expect(described_class.default_integration(integration_name, project)).to eq(subgroup_integration)
end
end
@@ -419,7 +421,7 @@ RSpec.describe Integration do
let!(:subgroup_integration) { create(:jira_integration, group_id: subgroup.id, project_id: nil, inherit_from_id: group_integration.id) }
it 'returns the closest group integration which does not inherit from its parent for a project' do
- expect(described_class.default_integration('JiraService', project)).to eq(group_integration)
+ expect(described_class.default_integration(integration_name, project)).to eq(group_integration)
end
end
end
@@ -556,13 +558,26 @@ RSpec.describe Integration do
end
end
- describe '.integration_name_to_model' do
- it 'returns the model for the given integration name' do
- expect(described_class.integration_name_to_model('asana')).to eq(Integrations::Asana)
+ describe '.integration_name_to_type' do
+ it 'handles a simple case' do
+ expect(described_class.integration_name_to_type(:asana)).to eq 'Integrations::Asana'
+ end
+
+ it 'raises an error if the name is unknown' do
+ expect { described_class.integration_name_to_type('foo') }
+ .to raise_exception(described_class::UnknownType, /foo/)
+ end
+
+ it 'handles all available_integration_names' do
+ types = described_class.available_integration_names.map { described_class.integration_name_to_type(_1) }
+
+ expect(types).to all(start_with('Integrations::'))
end
+ end
+ describe '.integration_name_to_model' do
it 'raises an error if integration name is invalid' do
- expect { described_class.integration_name_to_model('foo') }.to raise_exception(NameError, /uninitialized constant FooService/)
+ expect { described_class.integration_name_to_model('foo') }.to raise_exception(described_class::UnknownType, /foo/)
end
end
@@ -704,27 +719,63 @@ RSpec.describe Integration do
end
describe '#api_field_names' do
- let(:fake_integration) do
- Class.new(Integration) do
- def fields
- [
- { name: 'token' },
- { name: 'api_token' },
- { name: 'token_api' },
- { name: 'safe_token' },
- { name: 'key' },
- { name: 'api_key' },
- { name: 'password' },
- { name: 'password_field' },
- { name: 'some_safe_field' },
- { name: 'safe_field' }
- ].shuffle
- end
+ shared_examples 'api field names' do
+ it 'filters out sensitive fields' do
+ safe_fields = %w[some_safe_field safe_field url trojan_gift]
+
+ expect(fake_integration.new).to have_attributes(
+ api_field_names: match_array(safe_fields)
+ )
end
end
- it 'filters out sensitive fields' do
- expect(fake_integration.new).to have_attributes(api_field_names: match_array(%w[some_safe_field safe_field]))
+ context 'when the class overrides #fields' do
+ let(:fake_integration) do
+ Class.new(Integration) do
+ def fields
+ [
+ { name: 'token' },
+ { name: 'api_token' },
+ { name: 'token_api' },
+ { name: 'safe_token' },
+ { name: 'key' },
+ { name: 'api_key' },
+ { name: 'password' },
+ { name: 'password_field' },
+ { name: 'some_safe_field' },
+ { name: 'safe_field' },
+ { name: 'url' },
+ { name: 'trojan_horse', type: 'password' },
+ { name: 'trojan_gift', type: 'gift' }
+ ].shuffle
+ end
+ end
+ end
+
+ it_behaves_like 'api field names'
+ end
+
+ context 'when the class uses the field DSL' do
+ let(:fake_integration) do
+ Class.new(described_class) do
+ field :token
+ field :token
+ field :api_token
+ field :token_api
+ field :safe_token
+ field :key
+ field :api_key
+ field :password
+ field :password_field
+ field :some_safe_field
+ field :safe_field
+ field :url
+ field :trojan_horse, type: 'password'
+ field :trojan_gift, type: 'gift'
+ end
+ end
+
+ it_behaves_like 'api field names'
end
end
@@ -774,35 +825,33 @@ RSpec.describe Integration do
end
describe '.available_integration_names' do
- it 'calls the right methods' do
- expect(described_class).to receive(:integration_names).and_call_original
- expect(described_class).to receive(:dev_integration_names).and_call_original
- expect(described_class).to receive(:project_specific_integration_names).and_call_original
+ subject { described_class.available_integration_names }
- described_class.available_integration_names
+ before do
+ allow(described_class).to receive(:integration_names).and_return(%w(foo))
+ allow(described_class).to receive(:project_specific_integration_names).and_return(['bar'])
+ allow(described_class).to receive(:dev_integration_names).and_return(['baz'])
end
- it 'does not call project_specific_integration_names with include_project_specific false' do
- expect(described_class).to receive(:integration_names).and_call_original
- expect(described_class).to receive(:dev_integration_names).and_call_original
- expect(described_class).not_to receive(:project_specific_integration_names)
+ it { is_expected.to include('foo', 'bar', 'baz') }
- described_class.available_integration_names(include_project_specific: false)
+ context 'when `include_project_specific` is false' do
+ subject { described_class.available_integration_names(include_project_specific: false) }
+
+ it { is_expected.to include('foo', 'baz') }
+ it { is_expected.not_to include('bar') }
end
- it 'does not call dev_integration_names with include_dev false' do
- expect(described_class).to receive(:integration_names).and_call_original
- expect(described_class).not_to receive(:dev_integration_names)
- expect(described_class).to receive(:project_specific_integration_names).and_call_original
+ context 'when `include_dev` is false' do
+ subject { described_class.available_integration_names(include_dev: false) }
- described_class.available_integration_names(include_dev: false)
+ it { is_expected.to include('foo', 'bar') }
+ it { is_expected.not_to include('baz') }
end
-
- it { expect(described_class.available_integration_names).to include('jenkins') }
end
describe '.project_specific_integration_names' do
- it do
+ specify do
expect(described_class.project_specific_integration_names)
.to include(*described_class::PROJECT_SPECIFIC_INTEGRATION_NAMES)
end
@@ -823,4 +872,153 @@ RSpec.describe Integration do
expect(subject.password_fields).to eq([])
end
end
+
+ describe 'encrypted_properties' do
+ let(:properties) { { foo: 1, bar: true } }
+ let(:db_props) { properties.stringify_keys }
+ let(:record) { create(:integration, :instance, properties: properties) }
+
+ it 'contains the same data as properties' do
+ expect(record).to have_attributes(
+ properties: db_props,
+ encrypted_properties_tmp: db_props
+ )
+ end
+
+ it 'is persisted' do
+ encrypted_properties = described_class.id_in(record.id)
+
+ expect(encrypted_properties).to contain_exactly have_attributes(encrypted_properties_tmp: db_props)
+ end
+
+ it 'is updated when using prop_accessors' do
+ some_integration = Class.new(described_class) do
+ prop_accessor :foo
+ end
+
+ record = some_integration.new
+
+ record.foo = 'the foo'
+
+ expect(record.encrypted_properties_tmp).to eq({ 'foo' => 'the foo' })
+ end
+
+ it 'saves correctly using insert_all' do
+ hash = record.to_integration_hash
+ hash[:project_id] = project
+
+ expect do
+ described_class.insert_all([hash])
+ end.to change(described_class, :count).by(1)
+
+ expect(described_class.last).to have_attributes(encrypted_properties_tmp: db_props)
+ end
+
+ it 'is part of the to_integration_hash' do
+ hash = record.to_integration_hash
+
+ expect(hash).to include('encrypted_properties' => be_present, 'encrypted_properties_iv' => be_present)
+ expect(hash['encrypted_properties']).not_to eq(record.encrypted_properties)
+ expect(hash['encrypted_properties_iv']).not_to eq(record.encrypted_properties_iv)
+
+ decrypted = described_class.decrypt(:encrypted_properties_tmp,
+ hash['encrypted_properties'],
+ { iv: hash['encrypted_properties_iv'] })
+
+ expect(decrypted).to eq db_props
+ end
+
+ context 'when the properties are empty' do
+ let(:properties) { {} }
+
+ it 'is part of the to_integration_hash' do
+ hash = record.to_integration_hash
+
+ expect(hash).to include('encrypted_properties' => be_nil, 'encrypted_properties_iv' => be_nil)
+ end
+
+ it 'saves correctly using insert_all' do
+ hash = record.to_integration_hash
+ hash[:project_id] = project
+
+ expect do
+ described_class.insert_all([hash])
+ end.to change(described_class, :count).by(1)
+
+ expect(described_class.last).not_to eq record
+ expect(described_class.last).to have_attributes(encrypted_properties_tmp: db_props)
+ end
+ end
+ end
+
+ describe 'field DSL' do
+ let(:integration_type) do
+ Class.new(described_class) do
+ field :foo
+ field :foo_p, storage: :properties
+ field :foo_dt, storage: :data_fields
+
+ field :bar, type: 'password'
+ field :password
+
+ field :with_help,
+ help: -> { 'help' }
+
+ field :a_number,
+ type: 'number'
+ end
+ end
+
+ before do
+ allow(integration).to receive(:data_fields).and_return(data_fields)
+ end
+
+ let(:integration) { integration_type.new }
+ let(:data_fields) { Struct.new(:foo_dt).new }
+
+ it 'checks the value of storage' do
+ expect do
+ Class.new(described_class) { field(:foo, storage: 'bar') }
+ end.to raise_error(ArgumentError, /Unknown field storage/)
+ end
+
+ it 'provides prop_accessors' do
+ integration.foo = 1
+ expect(integration.foo).to eq 1
+ expect(integration.properties['foo']).to eq 1
+ expect(integration).to be_foo_changed
+
+ integration.foo_p = 2
+ expect(integration.foo_p).to eq 2
+ expect(integration.properties['foo_p']).to eq 2
+ expect(integration).to be_foo_p_changed
+ end
+
+ it 'provides data fields' do
+ integration.foo_dt = 3
+ expect(integration.foo_dt).to eq 3
+ expect(data_fields.foo_dt).to eq 3
+ expect(integration).to be_foo_dt_changed
+ end
+
+ it 'registers fields in the fields list' do
+ expect(integration.fields.pluck(:name)).to match_array %w[
+ foo foo_p foo_dt bar password with_help a_number
+ ]
+
+ expect(integration.api_field_names).to match_array %w[
+ foo foo_p foo_dt with_help a_number
+ ]
+ end
+
+ specify 'fields have expected attributes' do
+ expect(integration.fields).to include(
+ have_attributes(name: 'foo', type: 'text'),
+ have_attributes(name: 'bar', type: 'password'),
+ have_attributes(name: 'password', type: 'password'),
+ have_attributes(name: 'a_number', type: 'number'),
+ have_attributes(name: 'with_help', help: 'help')
+ )
+ end
+ end
end
diff --git a/spec/models/integrations/base_issue_tracker_spec.rb b/spec/models/integrations/base_issue_tracker_spec.rb
index 25e27e96a84..37f7d99717c 100644
--- a/spec/models/integrations/base_issue_tracker_spec.rb
+++ b/spec/models/integrations/base_issue_tracker_spec.rb
@@ -3,12 +3,12 @@
require 'spec_helper'
RSpec.describe Integrations::BaseIssueTracker do
- describe 'Validations' do
- let(:project) { create :project }
+ let(:integration) { Integrations::Redmine.new(project: project, active: true, issue_tracker_data: build(:issue_tracker_data)) }
- describe 'only one issue tracker per project' do
- let(:integration) { Integrations::Redmine.new(project: project, active: true, issue_tracker_data: build(:issue_tracker_data)) }
+ let_it_be_with_refind(:project) { create :project }
+ describe 'Validations' do
+ describe 'only one issue tracker per project' do
before do
create(:custom_issue_tracker_integration, project: project)
end
@@ -31,4 +31,18 @@ RSpec.describe Integrations::BaseIssueTracker do
end
end
end
+
+ describe '#activate_disabled_reason' do
+ subject { integration.activate_disabled_reason }
+
+ context 'when there is an existing issue tracker integration' do
+ let_it_be(:custom_tracker) { create(:custom_issue_tracker_integration, project: project) }
+
+ it { is_expected.to eq(trackers: [custom_tracker]) }
+ end
+
+ context 'when there is no existing issue tracker integration' do
+ it { is_expected.to be(nil) }
+ end
+ end
end
diff --git a/spec/models/integrations/field_spec.rb b/spec/models/integrations/field_spec.rb
new file mode 100644
index 00000000000..0d660c4a3ab
--- /dev/null
+++ b/spec/models/integrations/field_spec.rb
@@ -0,0 +1,118 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe ::Integrations::Field do
+ subject(:field) { described_class.new(**attrs) }
+
+ let(:attrs) { { name: nil } }
+
+ describe '#name' do
+ before do
+ attrs[:name] = :foo
+ end
+
+ it 'is stringified' do
+ expect(field.name).to eq 'foo'
+ expect(field[:name]).to eq 'foo'
+ end
+
+ context 'when not set' do
+ before do
+ attrs.delete(:name)
+ end
+
+ it 'complains' do
+ expect { field }.to raise_error(ArgumentError)
+ end
+ end
+ end
+
+ described_class::ATTRIBUTES.each do |name|
+ describe "##{name}" do
+ it "responds to #{name}" do
+ expect(field).to be_respond_to(name)
+ end
+
+ context 'when not set' do
+ before do
+ attrs.delete(name)
+ end
+
+ let(:have_correct_default) do
+ case name
+ when :api_only
+ be false
+ when :type
+ eq 'text'
+ else
+ be_nil
+ end
+ end
+
+ it 'has the correct default' do
+ expect(field[name]).to have_correct_default
+ expect(field.send(name)).to have_correct_default
+ end
+ end
+
+ context 'when set to a static value' do
+ before do
+ attrs[name] = :known
+ end
+
+ it 'is known' do
+ expect(field[name]).to eq(:known)
+ expect(field.send(name)).to eq(:known)
+ end
+ end
+
+ context 'when set to a dynamic value' do
+ before do
+ attrs[name] = -> { Time.current }
+ end
+
+ it 'is computed' do
+ start = Time.current
+
+ travel_to(start + 1.minute) do
+ expect(field[name]).to be_after(start)
+ expect(field.send(name)).to be_after(start)
+ end
+ end
+ end
+ end
+ end
+
+ describe '#sensitive' do
+ context 'when empty' do
+ it { is_expected.not_to be_sensitive }
+ end
+
+ context 'when a password field' do
+ before do
+ attrs[:type] = 'password'
+ end
+
+ it { is_expected.to be_sensitive }
+ end
+
+ %w[token api_token api_key secret_key secret_sauce password passphrase].each do |name|
+ context "when named #{name}" do
+ before do
+ attrs[:name] = name
+ end
+
+ it { is_expected.to be_sensitive }
+ end
+ end
+
+ context "when named url" do
+ before do
+ attrs[:name] = :url
+ end
+
+ it { is_expected.not_to be_sensitive }
+ end
+ end
+end
diff --git a/spec/models/integrations/harbor_spec.rb b/spec/models/integrations/harbor_spec.rb
new file mode 100644
index 00000000000..4a6eb27d63a
--- /dev/null
+++ b/spec/models/integrations/harbor_spec.rb
@@ -0,0 +1,133 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Integrations::Harbor do
+ let(:url) { 'https://demo.goharbor.io' }
+ let(:project_name) { 'testproject' }
+ let(:username) { 'harborusername' }
+ let(:password) { 'harborpassword' }
+ let(:harbor_integration) { create(:harbor_integration) }
+
+ describe "masked password" do
+ subject { build(:harbor_integration) }
+
+ it { is_expected.not_to allow_value('hello').for(:password) }
+ it { is_expected.not_to allow_value('hello world').for(:password) }
+ it { is_expected.not_to allow_value('hello$VARIABLEworld').for(:password) }
+ it { is_expected.not_to allow_value('hello\rworld').for(:password) }
+ it { is_expected.to allow_value('helloworld').for(:password) }
+ end
+
+ describe '#fields' do
+ it 'returns custom fields' do
+ expect(harbor_integration.fields.pluck(:name)).to eq(%w[url project_name username password])
+ end
+ end
+
+ describe '#test' do
+ let(:test_response) { "pong" }
+
+ before do
+ allow_next_instance_of(Gitlab::Harbor::Client) do |client|
+ allow(client).to receive(:ping).and_return(test_response)
+ end
+ end
+
+ it 'gets response from Gitlab::Harbor::Client#ping' do
+ expect(harbor_integration.test).to eq(test_response)
+ end
+ end
+
+ describe '#help' do
+ it 'renders prompt information' do
+ expect(harbor_integration.help).not_to be_empty
+ end
+ end
+
+ describe '.to_param' do
+ it 'returns the name of the integration' do
+ expect(described_class.to_param).to eq('harbor')
+ end
+ end
+
+ context 'ci variables' do
+ it 'returns vars when harbor_integration is activated' do
+ ci_vars = [
+ { key: 'HARBOR_URL', value: url },
+ { key: 'HARBOR_PROJECT', value: project_name },
+ { key: 'HARBOR_USERNAME', value: username },
+ { key: 'HARBOR_PASSWORD', value: password, public: false, masked: true }
+ ]
+
+ expect(harbor_integration.ci_variables).to match_array(ci_vars)
+ end
+
+ it 'returns [] when harbor_integration is inactive' do
+ harbor_integration.update!(active: false)
+ expect(harbor_integration.ci_variables).to match_array([])
+ end
+ end
+
+ describe 'before_validation :reset_username_and_password' do
+ context 'when username/password was previously set' do
+ it 'resets username and password if url changed' do
+ harbor_integration.url = 'https://anotherharbor.com'
+ harbor_integration.valid?
+
+ expect(harbor_integration.password).to be_nil
+ expect(harbor_integration.username).to be_nil
+ end
+
+ it 'does not reset password if username changed' do
+ harbor_integration.username = 'newusername'
+ harbor_integration.valid?
+
+ expect(harbor_integration.password).to eq('harborpassword')
+ end
+
+ it 'does not reset username if password changed' do
+ harbor_integration.password = 'newpassword'
+ harbor_integration.valid?
+
+ expect(harbor_integration.username).to eq('harborusername')
+ end
+
+ it "does not reset password if new url is set together with password, even if it's the same password" do
+ harbor_integration.url = 'https://anotherharbor.com'
+ harbor_integration.password = 'harborpassword'
+ harbor_integration.valid?
+
+ expect(harbor_integration.password).to eq('harborpassword')
+ expect(harbor_integration.username).to be_nil
+ expect(harbor_integration.url).to eq('https://anotherharbor.com')
+ end
+
+ it "does not reset username if new url is set together with username, even if it's the same username" do
+ harbor_integration.url = 'https://anotherharbor.com'
+ harbor_integration.username = 'harborusername'
+ harbor_integration.valid?
+
+ expect(harbor_integration.password).to be_nil
+ expect(harbor_integration.username).to eq('harborusername')
+ expect(harbor_integration.url).to eq('https://anotherharbor.com')
+ end
+ end
+
+ it 'saves password if new url is set together with password when no password was previously set' do
+ harbor_integration.password = nil
+ harbor_integration.username = nil
+
+ harbor_integration.url = 'https://anotherharbor.com'
+ harbor_integration.password = 'newpassword'
+ harbor_integration.username = 'newusername'
+ harbor_integration.save!
+
+ expect(harbor_integration).to have_attributes(
+ url: 'https://anotherharbor.com',
+ password: 'newpassword',
+ username: 'newusername'
+ )
+ end
+ end
+end
diff --git a/spec/models/integrations/jira_spec.rb b/spec/models/integrations/jira_spec.rb
index 6ce84c28044..08656bfe543 100644
--- a/spec/models/integrations/jira_spec.rb
+++ b/spec/models/integrations/jira_spec.rb
@@ -109,6 +109,32 @@ RSpec.describe Integrations::Jira do
end
end
+ describe '#sections' do
+ let(:integration) { create(:jira_integration) }
+
+ subject(:sections) { integration.sections.map { |s| s[:type] } }
+
+ context 'when project_level? is true' do
+ before do
+ allow(integration).to receive(:project_level?).and_return(true)
+ end
+
+ it 'includes SECTION_TYPE_JIRA_ISSUES' do
+ expect(sections).to include(described_class::SECTION_TYPE_JIRA_ISSUES)
+ end
+ end
+
+ context 'when project_level? is false' do
+ before do
+ allow(integration).to receive(:project_level?).and_return(false)
+ end
+
+ it 'does not include SECTION_TYPE_JIRA_ISSUES' do
+ expect(sections).not_to include(described_class::SECTION_TYPE_JIRA_ISSUES)
+ end
+ end
+ end
+
describe '.reference_pattern' do
using RSpec::Parameterized::TableSyntax
diff --git a/spec/models/integrations/slack_spec.rb b/spec/models/integrations/slack_spec.rb
index 4661d9c8291..9f69f4f51f8 100644
--- a/spec/models/integrations/slack_spec.rb
+++ b/spec/models/integrations/slack_spec.rb
@@ -7,7 +7,7 @@ RSpec.describe Integrations::Slack do
describe '#execute' do
before do
- stub_request(:post, "https://slack.service.url/")
+ stub_request(:post, slack_integration.webhook)
end
let_it_be(:slack_integration) { create(:integrations_slack, branches_to_be_notified: 'all') }
diff --git a/spec/models/issue_link_spec.rb b/spec/models/issue_link_spec.rb
index 433b51b8a70..9f77fcef5da 100644
--- a/spec/models/issue_link_spec.rb
+++ b/spec/models/issue_link_spec.rb
@@ -3,57 +3,42 @@
require 'spec_helper'
RSpec.describe IssueLink do
- describe 'Associations' do
- it { is_expected.to belong_to(:source).class_name('Issue') }
- it { is_expected.to belong_to(:target).class_name('Issue') }
+ it_behaves_like 'issuable link' do
+ let_it_be_with_reload(:issuable_link) { create(:issue_link) }
+ let_it_be(:issuable) { create(:issue) }
+ let(:issuable_class) { 'Issue' }
+ let(:issuable_link_factory) { :issue_link }
end
- describe 'link_type' do
- it { is_expected.to define_enum_for(:link_type).with_values(relates_to: 0, blocks: 1) }
-
- it 'provides the "related" as default link_type' do
- expect(create(:issue_link).link_type).to eq 'relates_to'
- end
+ describe '.issuable_type' do
+ it { expect(described_class.issuable_type).to eq(:issue) }
end
- describe 'Validation' do
- subject { create :issue_link }
+ describe 'Scopes' do
+ let_it_be(:issue1) { create(:issue) }
+ let_it_be(:issue2) { create(:issue) }
- it { is_expected.to validate_presence_of(:source) }
- it { is_expected.to validate_presence_of(:target) }
- it do
- is_expected.to validate_uniqueness_of(:source)
- .scoped_to(:target_id)
- .with_message(/already related/)
- end
+ describe '.for_source_issue' do
+ it 'includes linked issues for source issue' do
+ source_issue = create(:issue)
+ issue_link_1 = create(:issue_link, source: source_issue, target: issue1)
+ issue_link_2 = create(:issue_link, source: source_issue, target: issue2)
- it 'is not valid if an opposite link already exists' do
- issue_link = build(:issue_link, source: subject.target, target: subject.source)
+ result = described_class.for_source_issue(source_issue)
- expect(issue_link).to be_invalid
- expect(issue_link.errors[:source]).to include('is already related to this issue')
+ expect(result).to contain_exactly(issue_link_1, issue_link_2)
+ end
end
- context 'when it relates to itself' do
- let(:issue) { create :issue }
-
- context 'cannot be validated' do
- it 'does not invalidate object with self relation error' do
- issue_link = build :issue_link, source: issue, target: nil
-
- issue_link.valid?
-
- expect(issue_link.errors[:source]).to be_empty
- end
- end
+ describe '.for_target_issue' do
+ it 'includes linked issues for target issue' do
+ target_issue = create(:issue)
+ issue_link_1 = create(:issue_link, source: issue1, target: target_issue)
+ issue_link_2 = create(:issue_link, source: issue2, target: target_issue)
- context 'can be invalidated' do
- it 'invalidates object' do
- issue_link = build :issue_link, source: issue, target: issue
+ result = described_class.for_target_issue(target_issue)
- expect(issue_link).to be_invalid
- expect(issue_link.errors[:source]).to include('cannot be related to itself')
- end
+ expect(result).to contain_exactly(issue_link_1, issue_link_2)
end
end
end
diff --git a/spec/models/issue_spec.rb b/spec/models/issue_spec.rb
index 5af42cc67ea..29305ba435c 100644
--- a/spec/models/issue_spec.rb
+++ b/spec/models/issue_spec.rb
@@ -1167,7 +1167,6 @@ RSpec.describe Issue do
end
describe '#check_for_spam?' do
- using RSpec::Parameterized::TableSyntax
let_it_be(:support_bot) { ::User.support_bot }
where(:support_bot?, :visibility_level, :confidential, :new_attributes, :check_for_spam?) do
diff --git a/spec/models/label_spec.rb b/spec/models/label_spec.rb
index 14acaf11ca4..ff7ac0ebd2a 100644
--- a/spec/models/label_spec.rb
+++ b/spec/models/label_spec.rb
@@ -67,24 +67,21 @@ RSpec.describe Label do
label = described_class.new(color: ' #abcdef ')
label.valid?
- expect(label.color).to eq('#abcdef')
+ expect(label.color).to be_color('#abcdef')
end
it 'uses default color if color is missing' do
label = described_class.new(color: nil)
- expect(label.color).to be(Label::DEFAULT_COLOR)
+ expect(label.color).to be_color(Label::DEFAULT_COLOR)
end
end
describe '#text_color' do
it 'uses default color if color is missing' do
- expect(LabelsHelper).to receive(:text_color_for_bg).with(Label::DEFAULT_COLOR)
- .and_return(spy)
-
label = described_class.new(color: nil)
- label.text_color
+ expect(label.text_color).to eq(Label::DEFAULT_COLOR.contrast)
end
end
@@ -107,6 +104,12 @@ RSpec.describe Label do
label = described_class.new(description: '<b>foo & bar?</b>')
expect(label.description).to eq('foo & bar?')
end
+
+ it 'accepts an empty string' do
+ label = described_class.new(title: 'foo', description: 'bar')
+ label.update!(description: '')
+ expect(label.description).to eq('')
+ end
end
describe 'priorization' do
diff --git a/spec/models/merge_request_assignee_spec.rb b/spec/models/merge_request_assignee_spec.rb
index 58b802de8e0..1591c517049 100644
--- a/spec/models/merge_request_assignee_spec.rb
+++ b/spec/models/merge_request_assignee_spec.rb
@@ -51,4 +51,24 @@ RSpec.describe MergeRequestAssignee do
it { is_expected.to have_attributes(state: 'reviewed') }
end
+
+ describe '#attention_requested_by' do
+ let(:current_user) { create(:user) }
+
+ before do
+ subject.update!(updated_state_by: current_user)
+ end
+
+ context 'attention requested' do
+ it { expect(subject.attention_requested_by).to eq(current_user) }
+ end
+
+ context 'attention requested' do
+ before do
+ subject.update!(state: :reviewed)
+ end
+
+ it { expect(subject.attention_requested_by).to eq(nil) }
+ end
+ end
end
diff --git a/spec/models/merge_request_reviewer_spec.rb b/spec/models/merge_request_reviewer_spec.rb
index d99fd4afb0f..dd00c4d8627 100644
--- a/spec/models/merge_request_reviewer_spec.rb
+++ b/spec/models/merge_request_reviewer_spec.rb
@@ -25,4 +25,24 @@ RSpec.describe MergeRequestReviewer do
it { is_expected.to belong_to(:merge_request).class_name('MergeRequest') }
it { is_expected.to belong_to(:reviewer).class_name('User').inverse_of(:merge_request_reviewers) }
end
+
+ describe '#attention_requested_by' do
+ let(:current_user) { create(:user) }
+
+ before do
+ subject.update!(updated_state_by: current_user)
+ end
+
+ context 'attention requested' do
+ it { expect(subject.attention_requested_by).to eq(current_user) }
+ end
+
+ context 'attention requested' do
+ before do
+ subject.update!(state: :reviewed)
+ end
+
+ it { expect(subject.attention_requested_by).to eq(nil) }
+ end
+ end
end
diff --git a/spec/models/merge_request_spec.rb b/spec/models/merge_request_spec.rb
index f2f2023a992..0d15851e583 100644
--- a/spec/models/merge_request_spec.rb
+++ b/spec/models/merge_request_spec.rb
@@ -3225,52 +3225,44 @@ RSpec.describe MergeRequest, factory_default: :keep do
end
context 'when failed' do
- shared_examples 'failed skip_ci_check' do
- context 'when #mergeable_ci_state? is false' do
- before do
- allow(subject).to receive(:mergeable_ci_state?) { false }
- end
-
- it 'returns false' do
- expect(subject.mergeable_state?).to be_falsey
- end
-
- it 'returns true when skipping ci check' do
- expect(subject.mergeable_state?(skip_ci_check: true)).to be(true)
- end
+ context 'when #mergeable_ci_state? is false' do
+ before do
+ allow(subject).to receive(:mergeable_ci_state?) { false }
end
- context 'when #mergeable_discussions_state? is false' do
- before do
- allow(subject).to receive(:mergeable_discussions_state?) { false }
- end
-
- it 'returns false' do
- expect(subject.mergeable_state?).to be_falsey
- end
-
- it 'returns true when skipping discussions check' do
- expect(subject.mergeable_state?(skip_discussions_check: true)).to be(true)
- end
+ it 'returns false' do
+ expect(subject.mergeable_state?).to be_falsey
end
- end
- context 'when improved_mergeability_checks is on' do
- it_behaves_like 'failed skip_ci_check'
+ it 'returns true when skipping ci check' do
+ expect(subject.mergeable_state?(skip_ci_check: true)).to be(true)
+ end
end
- context 'when improved_mergeability_checks is off' do
+ context 'when #mergeable_discussions_state? is false' do
before do
- stub_feature_flags(improved_mergeability_checks: false)
+ allow(subject).to receive(:mergeable_discussions_state?) { false }
end
- it_behaves_like 'failed skip_ci_check'
+ it 'returns false' do
+ expect(subject.mergeable_state?).to be_falsey
+ end
+
+ it 'returns true when skipping discussions check' do
+ expect(subject.mergeable_state?(skip_discussions_check: true)).to be(true)
+ end
end
end
end
describe '#mergeable_state?' do
- context 'when merge state caching is on' do
+ it_behaves_like 'for mergeable_state'
+
+ context 'when improved_mergeability_checks is off' do
+ before do
+ stub_feature_flags(improved_mergeability_checks: false)
+ end
+
it_behaves_like 'for mergeable_state'
end
@@ -4249,6 +4241,29 @@ RSpec.describe MergeRequest, factory_default: :keep do
end
end
+ describe '#eager_fetch_ref!' do
+ let(:project) { create(:project, :repository) }
+
+ # We use build instead of create to test that an IID is allocated
+ subject { build(:merge_request, source_project: project) }
+
+ it 'fetches the ref correctly' do
+ expect(subject.iid).to be_nil
+
+ expect { subject.eager_fetch_ref! }.to change { subject.iid.to_i }.by(1)
+
+ expect(subject.target_project.repository.ref_exists?(subject.ref_path)).to be_truthy
+ end
+
+ it 'only fetches the ref once after saved' do
+ expect(subject.target_project.repository).to receive(:fetch_source_branch!).once.and_call_original
+
+ subject.save!
+
+ expect(subject.target_project.repository.ref_exists?(subject.ref_path)).to be_truthy
+ end
+ end
+
describe 'removing a merge request' do
it 'refreshes the number of open merge requests of the target project' do
project = subject.target_project
@@ -5086,4 +5101,34 @@ RSpec.describe MergeRequest, factory_default: :keep do
let!(:model) { create(:merge_request, head_pipeline: parent) }
end
end
+
+ describe '#merge_request_reviewers_with' do
+ let_it_be(:reviewer1) { create(:user) }
+ let_it_be(:reviewer2) { create(:user) }
+
+ before do
+ subject.update!(reviewers: [reviewer1, reviewer2])
+ end
+
+ it 'returns reviewers' do
+ reviewers = subject.merge_request_reviewers_with([reviewer1.id])
+
+ expect(reviewers).to match_array([subject.merge_request_reviewers[0]])
+ end
+ end
+
+ describe '#merge_request_assignees_with' do
+ let_it_be(:assignee1) { create(:user) }
+ let_it_be(:assignee2) { create(:user) }
+
+ before do
+ subject.update!(assignees: [assignee1, assignee2])
+ end
+
+ it 'returns assignees' do
+ assignees = subject.merge_request_assignees_with([assignee1.id])
+
+ expect(assignees).to match_array([subject.merge_request_assignees[0]])
+ end
+ end
end
diff --git a/spec/models/milestone_spec.rb b/spec/models/milestone_spec.rb
index bc592acc80f..06044cf53cc 100644
--- a/spec/models/milestone_spec.rb
+++ b/spec/models/milestone_spec.rb
@@ -65,6 +65,17 @@ RSpec.describe Milestone do
allow(subject).to receive(:set_iid).and_return(false)
end
+ describe 'title' do
+ it { is_expected.to validate_presence_of(:title) }
+
+ it 'is invalid if title would be empty after sanitation', :aggregate_failures do
+ milestone = build(:milestone, project: project, title: '<img src=x onerror=prompt(1)>')
+
+ expect(milestone).not_to be_valid
+ expect(milestone.errors[:title]).to include("can't be blank")
+ end
+ end
+
describe 'milestone_releases' do
let(:milestone) { build(:milestone, project: project) }
diff --git a/spec/models/namespace/root_storage_statistics_spec.rb b/spec/models/namespace/root_storage_statistics_spec.rb
index 11852828eab..c399a0084fb 100644
--- a/spec/models/namespace/root_storage_statistics_spec.rb
+++ b/spec/models/namespace/root_storage_statistics_spec.rb
@@ -178,7 +178,7 @@ RSpec.describe Namespace::RootStorageStatistics, type: :model do
snippets = create_list(:personal_snippet, 3, :repository, author: user)
snippets.each { |s| s.statistics.refresh! }
- total_personal_snippets_size = snippets.map { |s| s.statistics.repository_size }.sum
+ total_personal_snippets_size = snippets.sum { |s| s.statistics.repository_size }
root_storage_statistics.recalculate!
diff --git a/spec/models/namespace_spec.rb b/spec/models/namespace_spec.rb
index 1728d4fc3f3..ebd153f6f10 100644
--- a/spec/models/namespace_spec.rb
+++ b/spec/models/namespace_spec.rb
@@ -436,17 +436,7 @@ RSpec.describe Namespace do
it { expect(namespace.traversal_ids).to eq [namespace.id] }
end
- context 'with before_commit callback' do
- it_behaves_like 'default traversal_ids'
- end
-
- context 'with after_create callback' do
- before do
- stub_feature_flags(sync_traversal_ids_before_commit: false)
- end
-
- it_behaves_like 'default traversal_ids'
- end
+ it_behaves_like 'default traversal_ids'
end
describe "after_commit :expire_child_caches" do
diff --git a/spec/models/packages/pypi/metadatum_spec.rb b/spec/models/packages/pypi/metadatum_spec.rb
index 2c9893ef8f3..6c83c4ed143 100644
--- a/spec/models/packages/pypi/metadatum_spec.rb
+++ b/spec/models/packages/pypi/metadatum_spec.rb
@@ -8,6 +8,9 @@ RSpec.describe Packages::Pypi::Metadatum, type: :model do
describe 'validations' do
it { is_expected.to validate_presence_of(:package) }
+ it { is_expected.to allow_value('').for(:required_python) }
+ it { is_expected.not_to allow_value(nil).for(:required_python) }
+ it { is_expected.not_to allow_value('a' * 256).for(:required_python) }
describe '#pypi_package_type' do
it 'will not allow a package with a different package_type' do
diff --git a/spec/models/personal_access_token_spec.rb b/spec/models/personal_access_token_spec.rb
index 88206fbf48c..125ac7fb102 100644
--- a/spec/models/personal_access_token_spec.rb
+++ b/spec/models/personal_access_token_spec.rb
@@ -32,6 +32,17 @@ RSpec.describe PersonalAccessToken do
it { is_expected.to contain_exactly(project_access_token) }
end
+ describe '.owner_is_human' do
+ let_it_be(:user) { create(:user, :project_bot) }
+ let_it_be(:project_member) { create(:project_member, user: user) }
+ let_it_be(:personal_access_token) { create(:personal_access_token) }
+ let_it_be(:project_access_token) { create(:personal_access_token, user: user) }
+
+ subject { described_class.owner_is_human }
+
+ it { is_expected.to contain_exactly(personal_access_token) }
+ end
+
describe '.for_user' do
it 'returns personal access tokens of specified user only' do
user_1 = create(:user)
diff --git a/spec/models/preloaders/environments/deployment_preloader_spec.rb b/spec/models/preloaders/environments/deployment_preloader_spec.rb
index c1812d45628..3f2f28a069e 100644
--- a/spec/models/preloaders/environments/deployment_preloader_spec.rb
+++ b/spec/models/preloaders/environments/deployment_preloader_spec.rb
@@ -62,4 +62,22 @@ RSpec.describe Preloaders::Environments::DeploymentPreloader do
expect(default_preload_query).to be(false)
end
+
+ it 'sets environment on the associated deployment', :aggregate_failures do
+ preload_association(:last_deployment)
+
+ expect do
+ project.environments.each { |environment| environment.last_deployment.environment }
+ end.not_to exceed_query_limit(0)
+
+ project.environments.each do |environment|
+ expect(environment.last_deployment.environment).to eq(environment)
+ end
+ end
+
+ it 'does not attempt to set environment on a nil deployment' do
+ create(:environment, project: project, state: :available)
+
+ expect { preload_association(:last_deployment) }.not_to raise_error
+ end
end
diff --git a/spec/models/project_authorization_spec.rb b/spec/models/project_authorization_spec.rb
index 37da30fb54c..14220007966 100644
--- a/spec/models/project_authorization_spec.rb
+++ b/spec/models/project_authorization_spec.rb
@@ -3,6 +3,56 @@
require 'spec_helper'
RSpec.describe ProjectAuthorization do
+ describe 'unique user, project authorizations' do
+ let_it_be(:user) { create(:user) }
+ let_it_be(:project_1) { create(:project) }
+
+ let!(:project_auth) do
+ create(
+ :project_authorization,
+ user: user,
+ project: project_1,
+ access_level: Gitlab::Access::DEVELOPER
+ )
+ end
+
+ context 'with duplicate user and project authorization' do
+ subject { project_auth.dup }
+
+ it { is_expected.to be_invalid }
+
+ context 'after validation' do
+ before do
+ subject.valid?
+ end
+
+ it 'contains duplicate error' do
+ expect(subject.errors[:user]).to include('has already been taken')
+ end
+ end
+ end
+
+ context 'with multiple access levels for the same user and project' do
+ subject do
+ project_auth.dup.tap do |auth|
+ auth.access_level = Gitlab::Access::MAINTAINER
+ end
+ end
+
+ it { is_expected.to be_invalid }
+
+ context 'after validation' do
+ before do
+ subject.valid?
+ end
+
+ it 'contains duplicate error' do
+ expect(subject.errors[:user]).to include('has already been taken')
+ end
+ end
+ end
+ end
+
describe 'relations' do
it { is_expected.to belong_to(:user) }
it { is_expected.to belong_to(:project) }
diff --git a/spec/models/project_pages_metadatum_spec.rb b/spec/models/project_pages_metadatum_spec.rb
index af2f9b94871..31a533e0363 100644
--- a/spec/models/project_pages_metadatum_spec.rb
+++ b/spec/models/project_pages_metadatum_spec.rb
@@ -18,15 +18,4 @@ RSpec.describe ProjectPagesMetadatum do
expect(described_class.only_on_legacy_storage).to eq([legacy_storage_project.pages_metadatum])
end
end
-
- it_behaves_like 'cleanup by a loose foreign key' do
- let!(:model) do
- artifacts_archive = create(:ci_job_artifact, :legacy_archive)
- metadatum = artifacts_archive.project.pages_metadatum
- metadatum.artifacts_archive = artifacts_archive
- metadatum
- end
-
- let!(:parent) { model.artifacts_archive }
- end
end
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb
index 1d9b38c7aa4..fc7ac35ed41 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -64,6 +64,7 @@ RSpec.describe Project, factory_default: :keep do
it { is_expected.to have_one(:bamboo_integration) }
it { is_expected.to have_one(:teamcity_integration) }
it { is_expected.to have_one(:jira_integration) }
+ it { is_expected.to have_one(:harbor_integration) }
it { is_expected.to have_one(:redmine_integration) }
it { is_expected.to have_one(:youtrack_integration) }
it { is_expected.to have_one(:custom_issue_tracker_integration) }
@@ -134,7 +135,7 @@ RSpec.describe Project, factory_default: :keep do
it { is_expected.to have_many(:packages).class_name('Packages::Package') }
it { is_expected.to have_many(:package_files).class_name('Packages::PackageFile') }
it { is_expected.to have_many(:debian_distributions).class_name('Packages::Debian::ProjectDistribution').dependent(:destroy) }
- it { is_expected.to have_many(:pipeline_artifacts) }
+ it { is_expected.to have_many(:pipeline_artifacts).dependent(:restrict_with_error) }
it { is_expected.to have_many(:terraform_states).class_name('Terraform::State').inverse_of(:project) }
it { is_expected.to have_many(:timelogs) }
it { is_expected.to have_many(:error_tracking_errors).class_name('ErrorTracking::Error') }
@@ -142,6 +143,9 @@ RSpec.describe Project, factory_default: :keep do
it { is_expected.to have_many(:pending_builds).class_name('Ci::PendingBuild') }
it { is_expected.to have_many(:ci_feature_usages).class_name('Projects::CiFeatureUsage') }
it { is_expected.to have_many(:bulk_import_exports).class_name('BulkImports::Export') }
+ it { is_expected.to have_many(:job_artifacts).dependent(:restrict_with_error) }
+ it { is_expected.to have_many(:build_trace_chunks).through(:builds).dependent(:restrict_with_error) }
+ it { is_expected.to have_many(:secure_files).class_name('Ci::SecureFile').dependent(:restrict_with_error) }
# GitLab Pages
it { is_expected.to have_many(:pages_domains) }
@@ -202,6 +206,35 @@ RSpec.describe Project, factory_default: :keep do
end
end
+ context 'when project has object storage attached to it' do
+ let_it_be(:project) { create(:project) }
+
+ before do
+ create(:ci_job_artifact, project: project)
+ end
+
+ context 'when associated object storage object is not deleted before the project' do
+ it 'adds an error to project', :aggregate_failures do
+ expect { project.destroy! }.to raise_error(ActiveRecord::RecordNotDestroyed)
+
+ expect(project.errors).not_to be_empty
+ expect(project.errors.first.message).to eq("Cannot delete record because dependent job artifacts exist")
+ end
+ end
+
+ context 'when associated object storage object is deleted before the project' do
+ before do
+ project.job_artifacts.first.destroy!
+ end
+
+ it 'deletes the project' do
+ project.destroy!
+
+ expect { project.reload }.to raise_error(ActiveRecord::RecordNotFound)
+ end
+ end
+ end
+
context 'when creating a new project' do
let_it_be(:project) { create(:project) }
@@ -246,33 +279,9 @@ RSpec.describe Project, factory_default: :keep do
expect(project.project_namespace).to be_in_sync_with_project(project)
expect(project.reload.project_namespace.traversal_ids).to eq([project.namespace.traversal_ids, project.project_namespace.id].flatten.compact)
end
-
- context 'with FF disabled' do
- before do
- stub_feature_flags(create_project_namespace_on_project_create: false)
- end
-
- it 'does not create a project namespace' do
- project = build(:project, path: 'hopefully-valid-path2')
- project.save!
-
- expect(project).to be_persisted
- expect(project.project_namespace).to be_nil
- end
- end
- end
-
- context 'sync-ing traversal_ids in before_commit callback' do
- it_behaves_like 'creates project namespace'
end
- context 'sync-ing traversal_ids in after_create callback' do
- before do
- stub_feature_flags(sync_traversal_ids_before_commit: false)
- end
-
- it_behaves_like 'creates project namespace'
- end
+ it_behaves_like 'creates project namespace'
end
end
@@ -316,35 +325,6 @@ RSpec.describe Project, factory_default: :keep do
end
end
end
-
- context 'with create_project_namespace_on_project_create FF enabled' do
- it_behaves_like 'project update'
-
- it 'keeps project namespace in sync with project' do
- project = create(:project)
- project.update!(path: 'hopefully-valid-path1')
-
- expect(project).to be_persisted
- expect(project.project_namespace).to be_persisted
- expect(project.project_namespace).to be_in_sync_with_project(project)
- end
- end
-
- context 'with create_project_namespace_on_project_create FF disabled' do
- before do
- stub_feature_flags(create_project_namespace_on_project_create: false)
- end
-
- it_behaves_like 'project update'
-
- it 'does not create a project namespace when project is updated' do
- project = create(:project)
- project.update!(path: 'hopefully-valid-path1')
-
- expect(project).to be_persisted
- expect(project.project_namespace).to be_nil
- end
- end
end
context 'updating cd_cd_settings' do
@@ -627,10 +607,30 @@ RSpec.describe Project, factory_default: :keep do
expect(project).to be_valid
end
- it 'allows a path ending in a period' do
- project = build(:project, path: 'foo.')
+ context 'path is unchanged' do
+ let_it_be(:invalid_path_project) do
+ project = create(:project, :repository, :public)
+ project.update_attribute(:path, 'foo.')
+ project
+ end
- expect(project).to be_valid
+ it 'does not raise validation error for path for existing project' do
+ expect { invalid_path_project.update!(name: 'Foo') }.not_to raise_error
+ end
+ end
+
+ %w[. - _].each do |special_character|
+ it "rejects a path ending in '#{special_character}'" do
+ project = build(:project, path: "foo#{special_character}")
+
+ expect(project).not_to be_valid
+ end
+
+ it "rejects a path starting with '#{special_character}'" do
+ project = build(:project, path: "#{special_character}foo")
+
+ expect(project).not_to be_valid
+ end
end
end
end
@@ -782,8 +782,8 @@ RSpec.describe Project, factory_default: :keep do
end
it 'does not set an random token if one provided' do
- project = FactoryBot.create(:project, runners_token: "#{Project::RUNNERS_TOKEN_PREFIX}my-token")
- expect(project.runners_token).to eq("#{Project::RUNNERS_TOKEN_PREFIX}my-token")
+ project = FactoryBot.create(:project, runners_token: "#{RunnersTokenPrefixable::RUNNERS_TOKEN_PREFIX}my-token")
+ expect(project.runners_token).to eq("#{RunnersTokenPrefixable::RUNNERS_TOKEN_PREFIX}my-token")
end
end
@@ -1470,7 +1470,7 @@ RSpec.describe Project, factory_default: :keep do
context 'when there is an active external issue tracker integration' do
let!(:integration) do
- create(:integration, project: project, type: 'JiraService', category: 'issue_tracker', active: true)
+ create(:jira_integration, project: project, category: 'issue_tracker')
end
specify { is_expected.to eq(true) }
@@ -1489,7 +1489,7 @@ RSpec.describe Project, factory_default: :keep do
context 'when there are two active external issue tracker integrations' do
let_it_be(:second_integration) do
- create(:integration, project: project, type: 'CustomIssueTracker', category: 'issue_tracker', active: true)
+ create(:custom_issue_tracker_integration, project: project, category: 'issue_tracker')
end
it 'does not become false when external issue tracker integration is destroyed' do
@@ -6559,7 +6559,6 @@ RSpec.describe Project, factory_default: :keep do
describe '#mark_pages_as_deployed' do
let(:project) { create(:project) }
- let(:artifacts_archive) { create(:ci_job_artifact, project: project) }
it "works when artifacts_archive is missing" do
project.mark_pages_as_deployed
@@ -6571,7 +6570,7 @@ RSpec.describe Project, factory_default: :keep do
project.pages_metadatum.destroy!
project.reload
- project.mark_pages_as_deployed(artifacts_archive: artifacts_archive)
+ project.mark_pages_as_deployed
expect(project.pages_metadatum.reload.deployed).to eq(true)
end
@@ -6581,15 +6580,13 @@ RSpec.describe Project, factory_default: :keep do
pages_metadatum.update!(deployed: false)
expect do
- project.mark_pages_as_deployed(artifacts_archive: artifacts_archive)
+ project.mark_pages_as_deployed
end.to change { pages_metadatum.reload.deployed }.from(false).to(true)
- .and change { pages_metadatum.reload.artifacts_archive }.from(nil).to(artifacts_archive)
end
end
describe '#mark_pages_as_not_deployed' do
let(:project) { create(:project) }
- let(:artifacts_archive) { create(:ci_job_artifact, project: project) }
it "creates new record and sets deployed to false if none exists yet" do
project.pages_metadatum.destroy!
@@ -6602,12 +6599,11 @@ RSpec.describe Project, factory_default: :keep do
it "updates the existing record and sets deployed to false and clears artifacts_archive" do
pages_metadatum = project.pages_metadatum
- pages_metadatum.update!(deployed: true, artifacts_archive: artifacts_archive)
+ pages_metadatum.update!(deployed: true)
expect do
project.mark_pages_as_not_deployed
end.to change { pages_metadatum.reload.deployed }.from(true).to(false)
- .and change { pages_metadatum.reload.artifacts_archive }.from(artifacts_archive).to(nil)
end
end
@@ -6697,6 +6693,24 @@ RSpec.describe Project, factory_default: :keep do
end
describe '#access_request_approvers_to_be_notified' do
+ context 'for a personal project' do
+ let_it_be(:project) { create(:project) }
+ let_it_be(:maintainer) { create(:user) }
+
+ let(:owner_membership) { project.members.owners.find_by(user_id: project.namespace.owner_id) }
+
+ it 'includes only the owner of the personal project' do
+ expect(project.access_request_approvers_to_be_notified.to_a).to eq([owner_membership])
+ end
+
+ it 'includes the maintainers of the personal project, if any' do
+ project.add_maintainer(maintainer)
+ maintainer_membership = project.members.maintainers.find_by(user_id: maintainer.id)
+
+ expect(project.access_request_approvers_to_be_notified.to_a).to match_array([owner_membership, maintainer_membership])
+ end
+ end
+
let_it_be(:project) { create(:project, group: create(:group, :public)) }
it 'returns a maximum of ten maintainers of the project in recent_sign_in descending order' do
@@ -7504,6 +7518,14 @@ RSpec.describe Project, factory_default: :keep do
expect(project.save).to be_falsy
expect(project.reload.topics.map(&:name)).to eq(%w[topic1 topic2 topic3])
end
+
+ it 'does not add new topic if name is not unique (case insensitive)' do
+ project.topic_list = 'topic1, TOPIC2, topic3'
+
+ project.save!
+
+ expect(project.reload.topics.map(&:name)).to eq(%w[topic1 topic2 topic3])
+ end
end
context 'public topics counter' do
@@ -7956,53 +7978,41 @@ RSpec.describe Project, factory_default: :keep do
end
end
- describe '#context_commits_enabled?' do
- let_it_be(:group) { create(:group) }
- let_it_be(:project) { create(:project, namespace: group) }
-
- subject(:result) { project.context_commits_enabled? }
-
- context 'when context_commits feature flag is enabled' do
- before do
- stub_feature_flags(context_commits: true)
- end
-
- it { is_expected.to be_truthy }
- end
-
- context 'when context_commits feature flag is disabled' do
- before do
- stub_feature_flags(context_commits: false)
- end
+ describe '.not_hidden' do
+ it 'lists projects that are not hidden' do
+ project = create(:project)
+ hidden_project = create(:project, :hidden)
- it { is_expected.to be_falsey }
+ expect(described_class.not_hidden).to contain_exactly(project)
+ expect(described_class.not_hidden).not_to include(hidden_project)
end
+ end
- context 'when context_commits feature flag is enabled on project group' do
- before do
- stub_feature_flags(context_commits: group)
- end
+ describe '#pending_delete_or_hidden?' do
+ let_it_be(:project) { create(:project, name: 'test-project') }
- it { is_expected.to be_truthy }
+ where(:pending_delete, :hidden, :expected_result) do
+ true | false | true
+ true | true | true
+ false | true | true
+ false | false | false
end
- context 'when context_commits feature flag is enabled on another group' do
- let(:another_group) { create(:group) }
+ with_them do
+ it 'returns true if project is pending delete or hidden' do
+ project.pending_delete = pending_delete
+ project.hidden = hidden
+ project.save!
- before do
- stub_feature_flags(context_commits: another_group)
+ expect(project.pending_delete_or_hidden?).to eq(expected_result)
end
-
- it { is_expected.to be_falsey }
end
end
- describe '#runners_token' do
- let_it_be(:project) { create(:project) }
-
- subject { project }
+ describe 'serialization' do
+ let(:object) { build(:project) }
- it_behaves_like 'it has a prefixable runners_token'
+ it_behaves_like 'blocks unsafe serialization'
end
private
diff --git a/spec/models/project_team_spec.rb b/spec/models/project_team_spec.rb
index bfdebbc33df..5b11f9d828a 100644
--- a/spec/models/project_team_spec.rb
+++ b/spec/models/project_team_spec.rb
@@ -225,7 +225,7 @@ RSpec.describe ProjectTeam do
let_it_be(:maintainer) { create(:user) }
let_it_be(:developer) { create(:user) }
let_it_be(:guest) { create(:user) }
- let_it_be(:project) { create(:project, namespace: maintainer.namespace) }
+ let_it_be(:project) { create(:project, group: create(:group)) }
let_it_be(:access_levels) { [Gitlab::Access::DEVELOPER, Gitlab::Access::MAINTAINER] }
subject(:members_with_access_levels) { project.team.members_with_access_levels(access_levels) }
diff --git a/spec/models/projects/build_artifacts_size_refresh_spec.rb b/spec/models/projects/build_artifacts_size_refresh_spec.rb
new file mode 100644
index 00000000000..22c27c986f8
--- /dev/null
+++ b/spec/models/projects/build_artifacts_size_refresh_spec.rb
@@ -0,0 +1,227 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Projects::BuildArtifactsSizeRefresh, type: :model do
+ describe 'associations' do
+ it { is_expected.to belong_to(:project) }
+ end
+
+ it_behaves_like 'having unique enum values'
+
+ describe 'validations' do
+ it { is_expected.to validate_presence_of(:project) }
+ end
+
+ describe 'scopes' do
+ let_it_be(:refresh_1) { create(:project_build_artifacts_size_refresh, :running, updated_at: 4.days.ago) }
+ let_it_be(:refresh_2) { create(:project_build_artifacts_size_refresh, :running, updated_at: 2.days.ago) }
+ let_it_be(:refresh_3) { create(:project_build_artifacts_size_refresh, :pending) }
+ let_it_be(:refresh_4) { create(:project_build_artifacts_size_refresh, :created) }
+
+ describe 'stale' do
+ it 'returns records in running state and has not been updated for more than 3 days' do
+ expect(described_class.stale).to eq([refresh_1])
+ end
+ end
+
+ describe 'remaining' do
+ it 'returns stale, created, and pending records' do
+ expect(described_class.remaining).to match_array([refresh_1, refresh_3, refresh_4])
+ end
+ end
+ end
+
+ describe 'state machine', :clean_gitlab_redis_shared_state do
+ around do |example|
+ freeze_time { example.run }
+ end
+
+ let(:now) { Time.zone.now }
+
+ describe 'initial state' do
+ let(:refresh) { create(:project_build_artifacts_size_refresh) }
+
+ it 'defaults to created' do
+ expect(refresh).to be_created
+ end
+ end
+
+ describe '#process!' do
+ context 'when refresh state is created' do
+ let!(:refresh) do
+ create(
+ :project_build_artifacts_size_refresh,
+ :created,
+ updated_at: 2.days.ago,
+ refresh_started_at: nil,
+ last_job_artifact_id: nil
+ )
+ end
+
+ before do
+ stats = create(:project_statistics, project: refresh.project, build_artifacts_size: 120)
+ stats.increment_counter(:build_artifacts_size, 30)
+ end
+
+ it 'transitions the state to running' do
+ expect { refresh.process! }.to change { refresh.reload.state }.to(described_class::STATES[:running])
+ end
+
+ it 'sets the refresh_started_at' do
+ expect { refresh.process! }.to change { refresh.reload.refresh_started_at.to_i }.to(now.to_i)
+ end
+
+ it 'bumps the updated_at' do
+ expect { refresh.process! }.to change { refresh.reload.updated_at.to_i }.to(now.to_i)
+ end
+
+ it 'resets the build artifacts size stats' do
+ expect { refresh.process! }.to change { refresh.project.statistics.reload.build_artifacts_size }.to(0)
+ end
+
+ it 'resets the counter attribute to zero' do
+ expect { refresh.process! }.to change { refresh.project.statistics.get_counter_value(:build_artifacts_size) }.to(0)
+ end
+ end
+
+ context 'when refresh state is pending' do
+ let!(:refresh) do
+ create(
+ :project_build_artifacts_size_refresh,
+ :pending,
+ updated_at: 2.days.ago
+ )
+ end
+
+ before do
+ create(:project_statistics, project: refresh.project)
+ end
+
+ it 'transitions the state to running' do
+ expect { refresh.process! }.to change { refresh.reload.state }.to(described_class::STATES[:running])
+ end
+
+ it 'bumps the updated_at' do
+ expect { refresh.process! }.to change { refresh.reload.updated_at.to_i }.to(now.to_i)
+ end
+ end
+
+ context 'when refresh state is running' do
+ let!(:refresh) do
+ create(
+ :project_build_artifacts_size_refresh,
+ :running,
+ updated_at: 2.days.ago
+ )
+ end
+
+ before do
+ create(:project_statistics, project: refresh.project)
+ end
+
+ it 'keeps the state at running' do
+ expect { refresh.process! }.not_to change { refresh.reload.state }
+ end
+
+ it 'bumps the updated_at' do
+ # If this was a stale job, we want to bump the updated at now so that
+ # it won't be picked up by another worker while we're recalculating
+ expect { refresh.process! }.to change { refresh.reload.updated_at.to_i }.to(now.to_i)
+ end
+ end
+ end
+
+ describe '#requeue!' do
+ let!(:refresh) do
+ create(
+ :project_build_artifacts_size_refresh,
+ :running,
+ updated_at: 2.days.ago,
+ last_job_artifact_id: 111
+ )
+ end
+
+ let(:last_job_artifact_id) { 123 }
+
+ it 'transitions refresh state from running to pending' do
+ expect { refresh.requeue!(last_job_artifact_id) }.to change { refresh.reload.state }.to(described_class::STATES[:pending])
+ end
+
+ it 'bumps updated_at' do
+ expect { refresh.requeue!(last_job_artifact_id) }.to change { refresh.reload.updated_at.to_i }.to(now.to_i)
+ end
+
+ it 'updates last_job_artifact_id' do
+ expect { refresh.requeue!(last_job_artifact_id) }.to change { refresh.reload.last_job_artifact_id.to_i }.to(last_job_artifact_id)
+ end
+ end
+ end
+
+ describe '.process_next_refresh!' do
+ let!(:refresh_running) { create(:project_build_artifacts_size_refresh, :running) }
+ let!(:refresh_created) { create(:project_build_artifacts_size_refresh, :created) }
+ let!(:refresh_stale) { create(:project_build_artifacts_size_refresh, :stale) }
+ let!(:refresh_pending) { create(:project_build_artifacts_size_refresh, :pending) }
+
+ subject(:processed_refresh) { described_class.process_next_refresh! }
+
+ it 'picks the first record from the remaining work' do
+ expect(processed_refresh).to eq(refresh_created)
+ expect(processed_refresh.reload).to be_running
+ end
+ end
+
+ describe '.enqueue_refresh' do
+ let_it_be(:project_1) { create(:project) }
+ let_it_be(:project_2) { create(:project) }
+
+ let(:projects) { [project_1, project_1, project_2] }
+
+ it 'creates refresh records for each given project, skipping duplicates' do
+ expect { described_class.enqueue_refresh(projects) }
+ .to change { described_class.count }.from(0).to(2)
+
+ expect(described_class.first).to have_attributes(
+ project_id: project_1.id,
+ last_job_artifact_id: nil,
+ refresh_started_at: nil,
+ state: described_class::STATES[:created]
+ )
+
+ expect(described_class.last).to have_attributes(
+ project_id: project_2.id,
+ last_job_artifact_id: nil,
+ refresh_started_at: nil,
+ state: described_class::STATES[:created]
+ )
+ end
+ end
+
+ describe '#next_batch' do
+ let!(:project) { create(:project) }
+ let!(:artifact_1) { create(:ci_job_artifact, project: project, created_at: 14.days.ago) }
+ let!(:artifact_2) { create(:ci_job_artifact, project: project, created_at: 13.days.ago) }
+ let!(:artifact_3) { create(:ci_job_artifact, project: project, created_at: 12.days.ago) }
+
+ # This should not be included in the recalculation as it is created later than the refresh start time
+ let!(:future_artifact) { create(:ci_job_artifact, project: project, size: 8, created_at: refresh.refresh_started_at + 1.second) }
+
+ let!(:refresh) do
+ create(
+ :project_build_artifacts_size_refresh,
+ :pending,
+ project: project,
+ updated_at: 2.days.ago,
+ refresh_started_at: 10.days.ago,
+ last_job_artifact_id: artifact_1.id
+ )
+ end
+
+ subject(:batch) { refresh.next_batch(limit: 3) }
+
+ it 'returns the job artifact records that were created not later than the refresh_started_at and IDs greater than the last_job_artifact_id' do
+ expect(batch).to eq([artifact_2, artifact_3])
+ end
+ end
+end
diff --git a/spec/models/projects/topic_spec.rb b/spec/models/projects/topic_spec.rb
index 397c65f4d5c..aa3230da1e6 100644
--- a/spec/models/projects/topic_spec.rb
+++ b/spec/models/projects/topic_spec.rb
@@ -22,22 +22,22 @@ RSpec.describe Projects::Topic do
describe 'validations' do
it { is_expected.to validate_presence_of(:name) }
- it { is_expected.to validate_uniqueness_of(:name) }
+ it { is_expected.to validate_uniqueness_of(:name).case_insensitive }
it { is_expected.to validate_length_of(:name).is_at_most(255) }
it { is_expected.to validate_length_of(:description).is_at_most(1024) }
end
describe 'scopes' do
- describe 'order_by_total_projects_count' do
+ describe 'order_by_non_private_projects_count' do
let!(:topic1) { create(:topic, name: 'topicB') }
let!(:topic2) { create(:topic, name: 'topicC') }
let!(:topic3) { create(:topic, name: 'topicA') }
- let!(:project1) { create(:project, topic_list: 'topicC, topicA, topicB') }
- let!(:project2) { create(:project, topic_list: 'topicC, topicA') }
- let!(:project3) { create(:project, topic_list: 'topicC') }
+ let!(:project1) { create(:project, :public, topic_list: 'topicC, topicA, topicB') }
+ let!(:project2) { create(:project, :public, topic_list: 'topicC, topicA') }
+ let!(:project3) { create(:project, :public, topic_list: 'topicC') }
- it 'sorts topics by total_projects_count' do
- topics = described_class.order_by_total_projects_count
+ it 'sorts topics by non_private_projects_count' do
+ topics = described_class.order_by_non_private_projects_count
expect(topics.map(&:name)).to eq(%w[topicC topicA topicB topic])
end
diff --git a/spec/models/projects/triggered_hooks_spec.rb b/spec/models/projects/triggered_hooks_spec.rb
new file mode 100644
index 00000000000..3c885bdac8e
--- /dev/null
+++ b/spec/models/projects/triggered_hooks_spec.rb
@@ -0,0 +1,48 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Projects::TriggeredHooks do
+ let_it_be(:project) { create(:project) }
+
+ let_it_be(:universal_push_hook) { create(:project_hook, project: project, push_events: true) }
+ let_it_be(:selective_push_hook) { create(:project_hook, :with_push_branch_filter, project: project, push_events: true) }
+ let_it_be(:issues_hook) { create(:project_hook, project: project, issues_events: true, push_events: false) }
+
+ let(:wh_service) { instance_double(::WebHookService, async_execute: true) }
+
+ def run_hooks(scope, data)
+ hooks = described_class.new(scope, data)
+ hooks.add_hooks(ProjectHook.all)
+ hooks.execute
+ end
+
+ it 'executes hooks by scope' do
+ data = { some: 'data', as: 'json' }
+
+ expect_hook_execution(issues_hook, data, 'issue_hooks')
+
+ run_hooks(:issue_hooks, data)
+ end
+
+ it 'applies branch filters, when they match' do
+ data = { some: 'data', as: 'json', ref: "refs/heads/#{generate(:branch)}" }
+
+ expect_hook_execution(universal_push_hook, data, 'push_hooks')
+ expect_hook_execution(selective_push_hook, data, 'push_hooks')
+
+ run_hooks(:push_hooks, data)
+ end
+
+ it 'applies branch filters, when they do not match' do
+ data = { some: 'data', as: 'json', ref: "refs/heads/master}" }
+
+ expect_hook_execution(universal_push_hook, data, 'push_hooks')
+
+ run_hooks(:push_hooks, data)
+ end
+
+ def expect_hook_execution(hook, data, scope)
+ expect(WebHookService).to receive(:new).with(hook, data, scope).and_return(wh_service)
+ end
+end
diff --git a/spec/models/repository_spec.rb b/spec/models/repository_spec.rb
index e592a4964f5..215f83adf5d 100644
--- a/spec/models/repository_spec.rb
+++ b/spec/models/repository_spec.rb
@@ -3062,6 +3062,14 @@ RSpec.describe Repository do
repository.create_if_not_exists
end
+ it 'creates a repository with a default branch name' do
+ default_branch_name = 'branch-a'
+ repository.create_if_not_exists(default_branch_name)
+ repository.create_file(user, 'file', 'content', message: 'initial commit', branch_name: default_branch_name)
+
+ expect(repository.root_ref).to eq(default_branch_name)
+ end
+
context 'it does nothing if the repository already existed' do
let(:project) { create(:project, :repository) }
diff --git a/spec/models/snippet_spec.rb b/spec/models/snippet_spec.rb
index 92e4bc7d1a9..70afafce132 100644
--- a/spec/models/snippet_spec.rb
+++ b/spec/models/snippet_spec.rb
@@ -667,6 +667,16 @@ RSpec.describe Snippet do
expect(snippet.repository.exists?).to be_truthy
end
+ it 'sets the default branch' do
+ expect(snippet).to receive(:default_branch).and_return('default-branch-1')
+ expect(subject).to be_truthy
+
+ snippet.repository.create_file(snippet.author, 'file', 'content', message: 'initial commit', branch_name: 'default-branch-1')
+
+ expect(snippet.repository.exists?).to be_truthy
+ expect(snippet.repository.root_ref).to eq('default-branch-1')
+ end
+
it 'tracks snippet repository' do
expect do
subject
@@ -677,6 +687,7 @@ RSpec.describe Snippet do
expect(snippet).to receive(:repository_storage).and_return('picked')
expect(snippet).to receive(:repository_exists?).and_return(false)
expect(snippet.repository).to receive(:create_if_not_exists)
+ allow(snippet).to receive(:default_branch).and_return('picked')
subject
@@ -882,74 +893,4 @@ RSpec.describe Snippet do
it_behaves_like 'can move repository storage' do
let_it_be(:container) { create(:snippet, :repository) }
end
-
- describe '#change_head_to_default_branch' do
- let(:head_path) { Rails.root.join(TestEnv.repos_path, "#{snippet.disk_path}.git", 'HEAD') }
-
- subject { snippet.change_head_to_default_branch }
-
- context 'when repository does not exist' do
- let(:snippet) { create(:snippet) }
-
- it 'does nothing' do
- expect(snippet.repository_exists?).to eq false
- expect(snippet.repository.raw_repository).not_to receive(:write_ref)
-
- subject
- end
- end
-
- context 'when repository is empty' do
- let(:snippet) { create(:snippet, :empty_repo) }
-
- before do
- allow(Gitlab::CurrentSettings).to receive(:default_branch_name).and_return(default_branch)
- end
-
- context 'when default branch in settings is different from "master"' do
- let(:default_branch) { 'custom-branch' }
-
- it 'changes the HEAD reference to the default branch' do
- expect { subject }.to change { File.read(head_path).squish }.to("ref: refs/heads/#{default_branch}")
- end
- end
- end
-
- context 'when repository is not empty' do
- let(:snippet) { create(:snippet, :empty_repo) }
-
- before do
- populate_snippet_repo
- end
-
- context 'when HEAD branch is empty' do
- it 'changes HEAD to default branch' do
- File.write(head_path, 'ref: refs/heads/non_existen_branch')
- expect(File.read(head_path).squish).to eq 'ref: refs/heads/non_existen_branch'
-
- subject
-
- expect(File.read(head_path).squish).to eq 'ref: refs/heads/main'
- expect(snippet.list_files('HEAD')).not_to be_empty
- end
- end
-
- context 'when HEAD branch is not empty' do
- it 'does nothing' do
- File.write(head_path, 'ref: refs/heads/main')
-
- expect(snippet.repository.raw_repository).not_to receive(:write_ref)
-
- subject
- end
- end
-
- def populate_snippet_repo
- allow(Gitlab::CurrentSettings).to receive(:default_branch_name).and_return('main')
-
- data = [{ file_path: 'new_file_test', content: 'bar' }]
- snippet.snippet_repository.multi_files_action(snippet.author, data, branch_name: 'main', message: 'foo')
- end
- end
- end
end
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index e4f25c79e53..b16a76211eb 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -17,7 +17,7 @@ RSpec.describe User do
it { is_expected.to include_module(Referable) }
it { is_expected.to include_module(Sortable) }
it { is_expected.to include_module(TokenAuthenticatable) }
- it { is_expected.to include_module(BlocksJsonSerialization) }
+ it { is_expected.to include_module(BlocksUnsafeSerialization) }
it { is_expected.to include_module(AsyncDeviseEmail) }
end
@@ -116,6 +116,7 @@ RSpec.describe User do
it { is_expected.to have_many(:builds) }
it { is_expected.to have_many(:pipelines) }
it { is_expected.to have_many(:chat_names).dependent(:destroy) }
+ it { is_expected.to have_many(:saved_replies).class_name('::Users::SavedReply') }
it { is_expected.to have_many(:uploads) }
it { is_expected.to have_many(:reported_abuse_reports).dependent(:destroy).class_name('AbuseReport') }
it { is_expected.to have_many(:custom_attributes).class_name('UserCustomAttribute') }
@@ -498,7 +499,7 @@ RSpec.describe User do
end
describe 'email' do
- let(:expected_error) { _('is not allowed for sign-up. Check with your administrator.') }
+ let(:expected_error) { _('is not allowed for sign-up. Please use your regular email address. Check with your administrator.') }
context 'when no signup domains allowed' do
before do
@@ -550,7 +551,7 @@ RSpec.describe User do
user = create(:user, email: "info@test.example.com")
expect { user.update!(email: "test@notexample.com") }
- .to raise_error(StandardError, 'Validation failed: Email is not allowed. Check with your administrator.')
+ .to raise_error(StandardError, 'Validation failed: Email is not allowed. Please use your regular email address. Check with your administrator.')
end
end
@@ -623,7 +624,7 @@ RSpec.describe User do
user = create(:user, email: 'info@test.com')
expect { user.update!(email: 'info@example.com') }
- .to raise_error(StandardError, 'Validation failed: Email is not allowed. Check with your administrator.')
+ .to raise_error(StandardError, 'Validation failed: Email is not allowed. Please use your regular email address. Check with your administrator.')
end
end
@@ -700,7 +701,7 @@ RSpec.describe User do
user = create(:user, email: 'info@test.com')
expect { user.update!(email: 'info@gitlab.com') }
- .to raise_error(StandardError, 'Validation failed: Email is not allowed. Check with your administrator.')
+ .to raise_error(StandardError, 'Validation failed: Email is not allowed. Please use your regular email address. Check with your administrator.')
end
it 'does accept a valid email address' do
@@ -1171,8 +1172,8 @@ RSpec.describe User do
@user.update!(email: 'new_primary@example.com')
@user.reload
- expect(@user.emails.count).to eq 2
- expect(@user.emails.pluck(:email)).to match_array([@secondary.email, 'primary@example.com'])
+ expect(@user.emails.count).to eq 3
+ expect(@user.emails.pluck(:email)).to match_array([@secondary.email, 'primary@example.com', 'new_primary@example.com'])
end
context 'when the first email was unconfirmed and the second email gets confirmed' do
@@ -1593,6 +1594,66 @@ RSpec.describe User do
end
end
+ describe 'saving primary email to the emails table' do
+ context 'when calling skip_reconfirmation! while updating the primary email' do
+ let(:user) { create(:user, email: 'primary@example.com') }
+
+ it 'adds the new email to emails' do
+ user.skip_reconfirmation!
+ user.update!(email: 'new_primary@example.com')
+
+ expect(user.email).to eq('new_primary@example.com')
+ expect(user.unconfirmed_email).to be_nil
+ expect(user).to be_confirmed
+ expect(user.emails.pluck(:email)).to include('new_primary@example.com')
+ expect(user.emails.find_by(email: 'new_primary@example.com')).to be_confirmed
+ end
+ end
+
+ context 'when the email is changed but not confirmed' do
+ let(:user) { create(:user, email: 'primary@example.com') }
+
+ it 'does not add the new email to emails yet' do
+ user.update!(email: 'new_primary@example.com')
+
+ expect(user.unconfirmed_email).to eq('new_primary@example.com')
+ expect(user.email).to eq('primary@example.com')
+ expect(user).to be_confirmed
+ expect(user.emails.pluck(:email)).not_to include('new_primary@example.com')
+ end
+ end
+
+ context 'when the user is created as not confirmed' do
+ let(:user) { create(:user, :unconfirmed, email: 'primary@example.com') }
+
+ it 'does not add the email to emails yet' do
+ expect(user).not_to be_confirmed
+ expect(user.emails.pluck(:email)).not_to include('primary@example.com')
+ end
+ end
+
+ context 'when the user is created as confirmed' do
+ let(:user) { create(:user, email: 'primary@example.com', confirmed_at: DateTime.now.utc) }
+
+ it 'adds the email to emails' do
+ expect(user).to be_confirmed
+ expect(user.emails.pluck(:email)).to include('primary@example.com')
+ end
+ end
+
+ context 'when skip_confirmation! is called' do
+ let(:user) { build(:user, :unconfirmed, email: 'primary@example.com') }
+
+ it 'adds the email to emails' do
+ user.skip_confirmation!
+ user.save!
+
+ expect(user).to be_confirmed
+ expect(user.emails.pluck(:email)).to include('primary@example.com')
+ end
+ end
+ end
+
describe '#force_confirm' do
let(:expired_confirmation_sent_at) { Date.today - described_class.confirm_within - 7.days }
let(:extant_confirmation_sent_at) { Date.today }
@@ -3089,7 +3150,7 @@ RSpec.describe User do
describe '#ldap_identity' do
it 'returns ldap identity' do
- user = create :omniauth_user
+ user = create(:omniauth_user, :ldap)
expect(user.ldap_identity.provider).not_to be_empty
end
@@ -3717,7 +3778,7 @@ RSpec.describe User do
context 'with min_access_level' do
let!(:user) { create(:user) }
- let!(:project) { create(:project, :private, namespace: user.namespace) }
+ let!(:project) { create(:project, :private, group: create(:group)) }
before do
project.add_developer(user)
@@ -4712,6 +4773,7 @@ RSpec.describe User do
expect(cache_mock).to receive(:delete).with(['users', user.id, 'assigned_open_merge_requests_count'])
expect(cache_mock).to receive(:delete).with(['users', user.id, 'review_requested_open_merge_requests_count'])
+ expect(cache_mock).to receive(:delete).with(['users', user.id, 'attention_requested_open_merge_requests_count'])
allow(Rails).to receive(:cache).and_return(cache_mock)
@@ -4719,6 +4781,20 @@ RSpec.describe User do
end
end
+ describe '#invalidate_attention_requested_count' do
+ let(:user) { build_stubbed(:user) }
+
+ it 'invalidates cache for issue counter' do
+ cache_mock = double
+
+ expect(cache_mock).to receive(:delete).with(['users', user.id, 'attention_requested_open_merge_requests_count'])
+
+ allow(Rails).to receive(:cache).and_return(cache_mock)
+
+ user.invalidate_attention_requested_count
+ end
+ end
+
describe '#invalidate_personal_projects_count' do
let(:user) { build_stubbed(:user) }
@@ -4805,6 +4881,20 @@ RSpec.describe User do
end
end
+ describe '#attention_requested_open_merge_requests_count' do
+ it 'returns number of open merge requests from non-archived projects' do
+ user = create(:user)
+ project = create(:project, :public)
+ archived_project = create(:project, :public, :archived)
+
+ create(:merge_request, source_project: project, author: user, reviewers: [user])
+ create(:merge_request, :closed, source_project: project, author: user, reviewers: [user])
+ create(:merge_request, source_project: archived_project, author: user, reviewers: [user])
+
+ expect(user.attention_requested_open_merge_requests_count(force: true)).to eq 1
+ end
+ end
+
describe '#assigned_open_issues_count' do
it 'returns number of open issues from non-archived projects' do
user = create(:user)
diff --git a/spec/models/users/credit_card_validation_spec.rb b/spec/models/users/credit_card_validation_spec.rb
index 43edf7ed093..34cfd500c26 100644
--- a/spec/models/users/credit_card_validation_spec.rb
+++ b/spec/models/users/credit_card_validation_spec.rb
@@ -5,7 +5,7 @@ require 'spec_helper'
RSpec.describe Users::CreditCardValidation do
it { is_expected.to belong_to(:user) }
- it { is_expected.to validate_length_of(:holder_name).is_at_most(26) }
+ it { is_expected.to validate_length_of(:holder_name).is_at_most(50) }
it { is_expected.to validate_length_of(:network).is_at_most(32) }
it { is_expected.to validate_numericality_of(:last_digits).is_less_than_or_equal_to(9999) }
diff --git a/spec/models/users/saved_reply_spec.rb b/spec/models/users/saved_reply_spec.rb
new file mode 100644
index 00000000000..50138dba478
--- /dev/null
+++ b/spec/models/users/saved_reply_spec.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Users::SavedReply do
+ let_it_be(:saved_reply) { create(:saved_reply) }
+
+ describe 'validations' do
+ it { is_expected.to validate_presence_of(:user_id) }
+ it { is_expected.to validate_presence_of(:name) }
+ it { is_expected.to validate_presence_of(:content) }
+ it { is_expected.to validate_uniqueness_of(:name).scoped_to([:user_id]) }
+ it { is_expected.to validate_length_of(:name).is_at_most(255) }
+ it { is_expected.to validate_length_of(:content).is_at_most(10000) }
+ end
+end
diff --git a/spec/models/wiki_page_spec.rb b/spec/models/wiki_page_spec.rb
index 699dd35196f..0016d2f517b 100644
--- a/spec/models/wiki_page_spec.rb
+++ b/spec/models/wiki_page_spec.rb
@@ -24,14 +24,6 @@ RSpec.describe WikiPage do
container.wiki
end
- def disable_front_matter
- stub_feature_flags(Gitlab::WikiPages::FrontMatterParser::FEATURE_FLAG => false)
- end
-
- def enable_front_matter_for(thing)
- stub_feature_flags(Gitlab::WikiPages::FrontMatterParser::FEATURE_FLAG => thing)
- end
-
# Use for groups of tests that do not modify their `subject`.
#
# include_context 'subject is persisted page', title: 'my title'
@@ -48,12 +40,6 @@ RSpec.describe WikiPage do
it { expect(wiki_page).to have_attributes(front_matter: {}, content: content) }
end
- shared_examples 'a page with front-matter' do
- let(:front_matter) { { title: 'Foo', slugs: %w[slug_a slug_b] } }
-
- it { expect(wiki_page.front_matter).to eq(front_matter) }
- end
-
context 'the wiki page has front matter' do
let(:content) do
<<~MD
@@ -68,27 +54,13 @@ RSpec.describe WikiPage do
MD
end
- it_behaves_like 'a page with front-matter'
+ it 'has front-matter' do
+ expect(wiki_page.front_matter).to eq({ title: 'Foo', slugs: %w[slug_a slug_b] })
+ end
it 'strips the front matter from the content' do
expect(wiki_page.content.strip).to eq('My actual content')
end
-
- context 'the feature flag is off' do
- before do
- disable_front_matter
- end
-
- it_behaves_like 'a page without front-matter'
-
- context 'but enabled for the container' do
- before do
- enable_front_matter_for(container)
- end
-
- it_behaves_like 'a page with front-matter'
- end
- end
end
context 'the wiki page does not have front matter' do
@@ -471,29 +443,6 @@ RSpec.describe WikiPage do
end
end
- context 'the front-matter feature flag is not enabled' do
- before do
- disable_front_matter
- end
-
- it 'does not update the front-matter' do
- content = subject.content
- subject.update(front_matter: { slugs: ['x'] })
-
- page = wiki.find_page(subject.title)
-
- expect([subject, page]).to all(have_attributes(front_matter: be_empty, content: content))
- end
-
- context 'but it is enabled for the container' do
- before do
- enable_front_matter_for(container)
- end
-
- it_behaves_like 'able to update front-matter'
- end
- end
-
it 'updates the wiki-page front-matter and content together' do
content = 'totally new content'
subject.update(content: content, front_matter: { slugs: ['x'] })
diff --git a/spec/models/work_item_spec.rb b/spec/models/work_item_spec.rb
index 2fa1abda44a..e92ae746911 100644
--- a/spec/models/work_item_spec.rb
+++ b/spec/models/work_item_spec.rb
@@ -10,4 +10,16 @@ RSpec.describe WorkItem do
expect(work_item.noteable_target_type_name).to eq('issue')
end
end
+
+ describe 'callbacks' do
+ describe 'record_create_action' do
+ it 'records the creation action after saving' do
+ expect(Gitlab::UsageDataCounters::WorkItemActivityUniqueCounter).to receive(:track_work_item_created_action)
+ # During the work item transition we also want to track work items as issues
+ expect(Gitlab::UsageDataCounters::IssueActivityUniqueCounter).to receive(:track_issue_created_action)
+
+ create(:work_item)
+ end
+ end
+ end
end
diff --git a/spec/policies/application_setting_policy_spec.rb b/spec/policies/application_setting_policy_spec.rb
new file mode 100644
index 00000000000..f5f02d25c64
--- /dev/null
+++ b/spec/policies/application_setting_policy_spec.rb
@@ -0,0 +1,40 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe ApplicationSettingPolicy do
+ let(:current_user) { create(:user) }
+ let(:user) { create(:user) }
+
+ subject { described_class.new(current_user, [user]) }
+
+ describe 'update_runners_registration_token' do
+ context 'when anonymous' do
+ let(:current_user) { nil }
+
+ it { is_expected.not_to be_allowed(:update_runners_registration_token) }
+ end
+
+ context 'regular user' do
+ it { is_expected.not_to be_allowed(:update_runners_registration_token) }
+ end
+
+ context 'when external' do
+ let(:current_user) { build(:user, :external) }
+
+ it { is_expected.not_to be_allowed(:update_runners_registration_token) }
+ end
+
+ context 'admin' do
+ let(:current_user) { create(:admin) }
+
+ context 'when admin mode is enabled', :enable_admin_mode do
+ it { is_expected.to be_allowed(:update_runners_registration_token) }
+ end
+
+ context 'when admin mode is disabled' do
+ it { is_expected.to be_disallowed(:update_runners_registration_token) }
+ end
+ end
+ end
+end
diff --git a/spec/policies/global_policy_spec.rb b/spec/policies/global_policy_spec.rb
index ca9a5b1853c..04d7eca6f09 100644
--- a/spec/policies/global_policy_spec.rb
+++ b/spec/policies/global_policy_spec.rb
@@ -591,34 +591,4 @@ RSpec.describe GlobalPolicy do
it { is_expected.not_to be_allowed(:log_in) }
end
end
-
- describe 'update_runners_registration_token' do
- context 'when anonymous' do
- let(:current_user) { nil }
-
- it { is_expected.not_to be_allowed(:update_runners_registration_token) }
- end
-
- context 'regular user' do
- it { is_expected.not_to be_allowed(:update_runners_registration_token) }
- end
-
- context 'when external' do
- let(:current_user) { build(:user, :external) }
-
- it { is_expected.not_to be_allowed(:update_runners_registration_token) }
- end
-
- context 'admin' do
- let(:current_user) { create(:admin) }
-
- context 'when admin mode is enabled', :enable_admin_mode do
- it { is_expected.to be_allowed(:update_runners_registration_token) }
- end
-
- context 'when admin mode is disabled' do
- it { is_expected.to be_disallowed(:update_runners_registration_token) }
- end
- end
- end
end
diff --git a/spec/policies/group_policy_spec.rb b/spec/policies/group_policy_spec.rb
index 2607e285a80..ff59a2e04a7 100644
--- a/spec/policies/group_policy_spec.rb
+++ b/spec/policies/group_policy_spec.rb
@@ -1076,37 +1076,33 @@ RSpec.describe GroupPolicy do
end
describe 'register_group_runners' do
- shared_examples 'expected outcome based on runner registration control' do
- context 'with runner_registration_control FF disabled' do
- before do
- stub_feature_flags(runner_registration_control: false)
- end
+ context 'admin' do
+ let(:current_user) { admin }
- it { is_expected.to be_allowed(:register_group_runners) }
- end
+ context 'when admin mode is enabled', :enable_admin_mode do
+ context 'with runner_registration_control FF disabled' do
+ before do
+ stub_feature_flags(runner_registration_control: false)
+ end
- context 'with runner_registration_control FF enabled' do
- before do
- stub_feature_flags(runner_registration_control: true)
+ it { is_expected.to be_allowed(:register_group_runners) }
end
- context 'with group runner registration disabled' do
+ context 'with runner_registration_control FF enabled' do
before do
- stub_application_setting(valid_runner_registrars: ['project'])
+ stub_feature_flags(runner_registration_control: true)
end
- it { is_expected.to be_disallowed(:register_group_runners) }
- end
- end
- end
+ it { is_expected.to be_allowed(:register_group_runners) }
- context 'admin' do
- let(:current_user) { admin }
-
- context 'when admin mode is enabled', :enable_admin_mode do
- it { is_expected.to be_allowed(:register_group_runners) }
+ context 'with group runner registration disabled' do
+ before do
+ stub_application_setting(valid_runner_registrars: ['project'])
+ end
- it_behaves_like 'expected outcome based on runner registration control'
+ it { is_expected.to be_allowed(:register_group_runners) }
+ end
+ end
end
context 'when admin mode is disabled' do
@@ -1119,7 +1115,29 @@ RSpec.describe GroupPolicy do
it { is_expected.to be_allowed(:register_group_runners) }
- it_behaves_like 'expected outcome based on runner registration control'
+ context 'with runner_registration_control FF disabled' do
+ before do
+ stub_feature_flags(runner_registration_control: false)
+ end
+
+ it { is_expected.to be_allowed(:register_group_runners) }
+ end
+
+ context 'with runner_registration_control FF enabled' do
+ before do
+ stub_feature_flags(runner_registration_control: true)
+ end
+
+ it { is_expected.to be_allowed(:register_group_runners) }
+
+ context 'with group runner registration disabled' do
+ before do
+ stub_application_setting(valid_runner_registrars: ['project'])
+ end
+
+ it { is_expected.to be_disallowed(:register_group_runners) }
+ end
+ end
end
context 'with maintainer' do
diff --git a/spec/policies/issue_policy_spec.rb b/spec/policies/issue_policy_spec.rb
index 3805976b3e7..1fe9e430011 100644
--- a/spec/policies/issue_policy_spec.rb
+++ b/spec/policies/issue_policy_spec.rb
@@ -396,4 +396,36 @@ RSpec.describe IssuePolicy do
expect(policies).to be_allowed(:read_issue_iid)
end
end
+
+ describe 'set_issue_crm_contacts' do
+ let(:user) { create(:user) }
+ let(:subgroup) { create(:group, :crm_enabled, parent: create(:group, :crm_enabled)) }
+ let(:project) { create(:project, group: subgroup) }
+ let(:issue) { create(:issue, project: project) }
+ let(:policies) { described_class.new(user, issue) }
+
+ context 'when project reporter' do
+ it 'is disallowed' do
+ project.add_reporter(user)
+
+ expect(policies).to be_disallowed(:set_issue_crm_contacts)
+ end
+ end
+
+ context 'when subgroup reporter' do
+ it 'is allowed' do
+ subgroup.add_reporter(user)
+
+ expect(policies).to be_disallowed(:set_issue_crm_contacts)
+ end
+ end
+
+ context 'when root group reporter' do
+ it 'is allowed' do
+ subgroup.parent.add_reporter(user)
+
+ expect(policies).to be_allowed(:set_issue_crm_contacts)
+ end
+ end
+ end
end
diff --git a/spec/policies/project_policy_spec.rb b/spec/policies/project_policy_spec.rb
index 793b1fffd5f..0da37fc5378 100644
--- a/spec/policies/project_policy_spec.rb
+++ b/spec/policies/project_policy_spec.rb
@@ -1755,4 +1755,100 @@ RSpec.describe ProjectPolicy do
end
end
end
+
+ describe 'register_project_runners' do
+ context 'admin' do
+ let(:current_user) { admin }
+
+ context 'when admin mode is enabled', :enable_admin_mode do
+ context 'with runner_registration_control FF disabled' do
+ before do
+ stub_feature_flags(runner_registration_control: false)
+ end
+
+ it { is_expected.to be_allowed(:register_project_runners) }
+ end
+
+ context 'with runner_registration_control FF enabled' do
+ before do
+ stub_feature_flags(runner_registration_control: true)
+ end
+
+ it { is_expected.to be_allowed(:register_project_runners) }
+
+ context 'with project runner registration disabled' do
+ before do
+ stub_application_setting(valid_runner_registrars: ['group'])
+ end
+
+ it { is_expected.to be_allowed(:register_project_runners) }
+ end
+ end
+ end
+
+ context 'when admin mode is disabled' do
+ it { is_expected.to be_disallowed(:register_project_runners) }
+ end
+ end
+
+ context 'with owner' do
+ let(:current_user) { owner }
+
+ it { is_expected.to be_allowed(:register_project_runners) }
+
+ context 'with runner_registration_control FF disabled' do
+ before do
+ stub_feature_flags(runner_registration_control: false)
+ end
+
+ it { is_expected.to be_allowed(:register_project_runners) }
+ end
+
+ context 'with runner_registration_control FF enabled' do
+ before do
+ stub_feature_flags(runner_registration_control: true)
+ end
+
+ it { is_expected.to be_allowed(:register_project_runners) }
+
+ context 'with project runner registration disabled' do
+ before do
+ stub_application_setting(valid_runner_registrars: ['group'])
+ end
+
+ it { is_expected.to be_disallowed(:register_project_runners) }
+ end
+ end
+ end
+
+ context 'with maintainer' do
+ let(:current_user) { maintainer }
+
+ it { is_expected.to be_allowed(:register_project_runners) }
+ end
+
+ context 'with reporter' do
+ let(:current_user) { reporter }
+
+ it { is_expected.to be_disallowed(:register_project_runners) }
+ end
+
+ context 'with guest' do
+ let(:current_user) { guest }
+
+ it { is_expected.to be_disallowed(:register_project_runners) }
+ end
+
+ context 'with non member' do
+ let(:current_user) { create(:user) }
+
+ it { is_expected.to be_disallowed(:register_project_runners) }
+ end
+
+ context 'with anonymous' do
+ let(:current_user) { nil }
+
+ it { is_expected.to be_disallowed(:register_project_runners) }
+ end
+ end
end
diff --git a/spec/policies/work_item_policy_spec.rb b/spec/policies/work_item_policy_spec.rb
new file mode 100644
index 00000000000..08a22a95540
--- /dev/null
+++ b/spec/policies/work_item_policy_spec.rb
@@ -0,0 +1,94 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe WorkItemPolicy do
+ let_it_be(:project) { create(:project) }
+ let_it_be(:public_project) { create(:project, :public) }
+ let_it_be(:guest) { create(:user).tap { |user| project.add_guest(user) } }
+ let_it_be(:guest_author) { create(:user).tap { |user| project.add_guest(user) } }
+ let_it_be(:reporter) { create(:user).tap { |user| project.add_reporter(user) } }
+ let_it_be(:non_member_user) { create(:user) }
+ let_it_be(:work_item) { create(:work_item, project: project) }
+ let_it_be(:authored_work_item) { create(:work_item, project: project, author: guest_author) }
+ let_it_be(:public_work_item) { create(:work_item, project: public_project) }
+
+ let(:work_item_subject) { work_item }
+
+ subject { described_class.new(current_user, work_item_subject) }
+
+ before_all do
+ public_project.add_developer(guest_author)
+ end
+
+ describe 'read_work_item' do
+ context 'when project is public' do
+ let(:work_item_subject) { public_work_item }
+
+ context 'when user is not a member of the project' do
+ let(:current_user) { non_member_user }
+
+ it { is_expected.to be_allowed(:read_work_item) }
+ end
+
+ context 'when user is a member of the project' do
+ let(:current_user) { guest_author }
+
+ it { is_expected.to be_allowed(:read_work_item) }
+ end
+ end
+
+ context 'when project is private' do
+ let(:work_item_subject) { work_item }
+
+ context 'when user is not a member of the project' do
+ let(:current_user) { non_member_user }
+
+ it { is_expected.to be_disallowed(:read_work_item) }
+ end
+
+ context 'when user is a member of the project' do
+ let(:current_user) { guest_author }
+
+ it { is_expected.to be_allowed(:read_work_item) }
+ end
+ end
+ end
+
+ describe 'update_work_item' do
+ context 'when user is reporter' do
+ let(:current_user) { reporter }
+
+ it { is_expected.to be_allowed(:update_work_item) }
+ end
+
+ context 'when user is guest' do
+ let(:current_user) { guest }
+
+ it { is_expected.to be_disallowed(:update_work_item) }
+
+ context 'when guest authored the work item' do
+ let(:work_item_subject) { authored_work_item }
+ let(:current_user) { guest_author }
+
+ it { is_expected.to be_allowed(:update_work_item) }
+ end
+ end
+ end
+
+ describe 'delete_work_item' do
+ context 'when user is a member of the project' do
+ let(:work_item_subject) { work_item }
+ let(:current_user) { reporter }
+
+ it { is_expected.to be_disallowed(:delete_work_item) }
+
+ context 'when guest authored the work item' do
+ let(:work_item_subject) { authored_work_item }
+ let(:current_user) { guest_author }
+
+ it { is_expected.to be_allowed(:delete_work_item) }
+ end
+ end
+ end
+end
diff --git a/spec/presenters/blob_presenter_spec.rb b/spec/presenters/blob_presenter_spec.rb
index 225386d9596..80e08db6099 100644
--- a/spec/presenters/blob_presenter_spec.rb
+++ b/spec/presenters/blob_presenter_spec.rb
@@ -28,7 +28,7 @@ RSpec.describe BlobPresenter do
end
describe '#replace_path' do
- it { expect(presenter.replace_path).to eq("/#{project.full_path}/-/create/#{blob.commit_id}/#{blob.path}") }
+ it { expect(presenter.replace_path).to eq("/#{project.full_path}/-/update/#{blob.commit_id}/#{blob.path}") }
end
describe '#can_current_user_push_to_branch' do
@@ -71,6 +71,40 @@ RSpec.describe BlobPresenter do
end
end
+ context 'Gitpod' do
+ let(:gitpod_url) { "https://gitpod.io" }
+ let(:gitpod_application_enabled) { true }
+ let(:gitpod_user_enabled) { true }
+
+ before do
+ allow(user).to receive(:gitpod_enabled).and_return(gitpod_user_enabled)
+ allow(Gitlab::CurrentSettings).to receive(:gitpod_enabled).and_return(gitpod_application_enabled)
+ allow(Gitlab::CurrentSettings).to receive(:gitpod_url).and_return(gitpod_url)
+ end
+
+ context 'Gitpod enabled for application and user' do
+ describe '#gitpod_blob_url' do
+ it { expect(presenter.gitpod_blob_url).to eq("#{gitpod_url}##{"http://localhost/#{project.full_path}/-/tree/#{blob.commit_id}/#{blob.path}"}") }
+ end
+ end
+
+ context 'Gitpod disabled at application level' do
+ let(:gitpod_application_enabled) { false }
+
+ describe '#gitpod_blob_url' do
+ it { expect(presenter.gitpod_blob_url).to eq(nil) }
+ end
+ end
+
+ context 'Gitpod disabled at user level' do
+ let(:gitpod_user_enabled) { false }
+
+ describe '#gitpod_blob_url' do
+ it { expect(presenter.gitpod_blob_url).to eq(nil) }
+ end
+ end
+ end
+
describe '#find_file_path' do
it { expect(presenter.find_file_path).to eq("/#{project.full_path}/-/find_file/HEAD/files/ruby/regex.rb") }
end
@@ -154,6 +188,16 @@ RSpec.describe BlobPresenter do
end
end
+ describe '#code_navigation_path' do
+ let(:code_navigation_path) { Gitlab::CodeNavigationPath.new(project, blob.commit_id).full_json_path_for(blob.path) }
+
+ it { expect(presenter.code_navigation_path).to eq(code_navigation_path) }
+ end
+
+ describe '#project_blob_path_root' do
+ it { expect(presenter.project_blob_path_root).to eq("/#{project.full_path}/-/blob/HEAD") }
+ end
+
context 'given a Gitlab::Graphql::Representation::TreeEntry' do
let(:blob) { Gitlab::Graphql::Representation::TreeEntry.new(super(), repository) }
diff --git a/spec/presenters/blobs/notebook_presenter_spec.rb b/spec/presenters/blobs/notebook_presenter_spec.rb
new file mode 100644
index 00000000000..12f4ed67897
--- /dev/null
+++ b/spec/presenters/blobs/notebook_presenter_spec.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Blobs::NotebookPresenter do
+ include RepoHelpers
+
+ let(:project) { create(:project, :repository) }
+ let(:repository) { project.repository }
+ let(:blob) { repository.blob_at('HEAD', 'files/ruby/regex.rb') }
+ let(:user) { project.first_owner }
+ let(:git_blob) { blob.__getobj__ }
+
+ subject(:presenter) { described_class.new(blob, current_user: user) }
+
+ it 'highlight receives markdown' do
+ expect(Gitlab::Highlight).to receive(:highlight).with('files/ruby/regex.rb', git_blob.data, plain: nil, language: 'md')
+
+ presenter.highlight
+ end
+end
diff --git a/spec/presenters/ci/build_runner_presenter_spec.rb b/spec/presenters/ci/build_runner_presenter_spec.rb
index b8d0b093a24..d25102532a7 100644
--- a/spec/presenters/ci/build_runner_presenter_spec.rb
+++ b/spec/presenters/ci/build_runner_presenter_spec.rb
@@ -173,11 +173,7 @@ RSpec.describe Ci::BuildRunnerPresenter do
it 'returns the correct refspecs' do
is_expected.to contain_exactly("+refs/heads/#{build.ref}:refs/remotes/origin/#{build.ref}",
- "+#{pipeline.sha}:refs/pipelines/#{pipeline.id}")
- end
-
- it 'uses a SHA in the persistent refspec' do
- expect(subject[0]).to match(%r{^\+[0-9a-f]{40}:refs/pipelines/[0-9]+$})
+ "+refs/pipelines/#{pipeline.id}:refs/pipelines/#{pipeline.id}")
end
context 'when ref is tag' do
@@ -185,7 +181,7 @@ RSpec.describe Ci::BuildRunnerPresenter do
it 'returns the correct refspecs' do
is_expected.to contain_exactly("+refs/tags/#{build.ref}:refs/tags/#{build.ref}",
- "+#{pipeline.sha}:refs/pipelines/#{pipeline.id}")
+ "+refs/pipelines/#{pipeline.id}:refs/pipelines/#{pipeline.id}")
end
context 'when GIT_DEPTH is zero' do
@@ -196,7 +192,7 @@ RSpec.describe Ci::BuildRunnerPresenter do
it 'returns the correct refspecs' do
is_expected.to contain_exactly('+refs/tags/*:refs/tags/*',
'+refs/heads/*:refs/remotes/origin/*',
- "+#{pipeline.sha}:refs/pipelines/#{pipeline.id}")
+ "+refs/pipelines/#{pipeline.id}:refs/pipelines/#{pipeline.id}")
end
end
end
@@ -212,7 +208,7 @@ RSpec.describe Ci::BuildRunnerPresenter do
it 'returns the correct refspecs' do
is_expected
- .to contain_exactly("+#{pipeline.sha}:refs/pipelines/#{pipeline.id}")
+ .to contain_exactly("+refs/pipelines/#{pipeline.id}:refs/pipelines/#{pipeline.id}")
end
context 'when GIT_DEPTH is zero' do
@@ -222,7 +218,7 @@ RSpec.describe Ci::BuildRunnerPresenter do
it 'returns the correct refspecs' do
is_expected
- .to contain_exactly("+#{pipeline.sha}:refs/pipelines/#{pipeline.id}",
+ .to contain_exactly("+refs/pipelines/#{pipeline.id}:refs/pipelines/#{pipeline.id}",
'+refs/heads/*:refs/remotes/origin/*',
'+refs/tags/*:refs/tags/*')
end
@@ -232,7 +228,7 @@ RSpec.describe Ci::BuildRunnerPresenter do
let(:merge_request) { create(:merge_request, :with_legacy_detached_merge_request_pipeline) }
it 'returns the correct refspecs' do
- is_expected.to contain_exactly("+#{pipeline.sha}:refs/pipelines/#{pipeline.id}",
+ is_expected.to contain_exactly("+refs/pipelines/#{pipeline.id}:refs/pipelines/#{pipeline.id}",
"+refs/heads/#{build.ref}:refs/remotes/origin/#{build.ref}")
end
end
@@ -250,7 +246,7 @@ RSpec.describe Ci::BuildRunnerPresenter do
it 'exposes the persistent pipeline ref' do
is_expected
- .to contain_exactly("+#{pipeline.sha}:refs/pipelines/#{pipeline.id}",
+ .to contain_exactly("+refs/pipelines/#{pipeline.id}:refs/pipelines/#{pipeline.id}",
"+refs/heads/#{build.ref}:refs/remotes/origin/#{build.ref}")
end
end
diff --git a/spec/presenters/group_clusterable_presenter_spec.rb b/spec/presenters/group_clusterable_presenter_spec.rb
index b2dff2e3546..f6389ba723e 100644
--- a/spec/presenters/group_clusterable_presenter_spec.rb
+++ b/spec/presenters/group_clusterable_presenter_spec.rb
@@ -43,6 +43,12 @@ RSpec.describe GroupClusterablePresenter do
it { is_expected.to eq(new_group_cluster_path(group)) }
end
+ describe '#connect_path' do
+ subject { presenter.connect_path }
+
+ it { is_expected.to eq(connect_group_clusters_path(group)) }
+ end
+
describe '#authorize_aws_role_path' do
subject { presenter.authorize_aws_role_path }
diff --git a/spec/presenters/instance_clusterable_presenter_spec.rb b/spec/presenters/instance_clusterable_presenter_spec.rb
index 0ace57bbf4d..3e871bf7ba5 100644
--- a/spec/presenters/instance_clusterable_presenter_spec.rb
+++ b/spec/presenters/instance_clusterable_presenter_spec.rb
@@ -15,6 +15,12 @@ RSpec.describe InstanceClusterablePresenter do
it { is_expected.to eq(create_aws_admin_clusters_path) }
end
+ describe '#connect_path' do
+ subject { described_class.new(instance).connect_path }
+
+ it { is_expected.to eq(connect_admin_clusters_path) }
+ end
+
describe '#authorize_aws_role_path' do
subject { described_class.new(instance).authorize_aws_role_path }
diff --git a/spec/presenters/merge_request_presenter_spec.rb b/spec/presenters/merge_request_presenter_spec.rb
index 60296cca058..dbf5af095cb 100644
--- a/spec/presenters/merge_request_presenter_spec.rb
+++ b/spec/presenters/merge_request_presenter_spec.rb
@@ -162,10 +162,19 @@ RSpec.describe MergeRequestPresenter do
end
end
- describe '#assign_to_closing_issues_link' do
+ describe '#assign_to_closing_issues_path' do
subject do
described_class.new(resource, current_user: user)
- .assign_to_closing_issues_link
+ .assign_to_closing_issues_path
+ end
+
+ it { is_expected.to match("#{project.full_path}/-/merge_requests/#{resource.iid}/assign_related_issues") }
+ end
+
+ describe '#assign_to_closing_issues_count' do
+ subject do
+ described_class.new(resource, current_user: user)
+ .assign_to_closing_issues_count
end
before do
@@ -178,33 +187,28 @@ RSpec.describe MergeRequestPresenter do
let(:issue) { create(:issue) }
let(:assignable_issues) { [issue] }
- it 'returns correct link with correct text' do
+ it 'returns correct count' do
is_expected
- .to match("#{project.full_path}/-/merge_requests/#{resource.iid}/assign_related_issues")
-
- is_expected
- .to match("Assign yourself to this issue")
+ .to match(1)
end
end
context 'multiple closing issues' do
- let(:issues) { create_list(:issue, 2) }
+ let(:issues) { build_list(:issue, 2) }
let(:assignable_issues) { issues }
- it 'returns correct link with correct text' do
- is_expected
- .to match("#{project.full_path}/-/merge_requests/#{resource.iid}/assign_related_issues")
-
+ it 'returns correct count' do
is_expected
- .to match("Assign yourself to these issues")
+ .to match(2)
end
end
context 'no closing issue' do
let(:assignable_issues) { [] }
- it 'returns correct link with correct text' do
- is_expected.to be_nil
+ it 'returns correct count' do
+ is_expected
+ .to match(0)
end
end
end
diff --git a/spec/presenters/project_clusterable_presenter_spec.rb b/spec/presenters/project_clusterable_presenter_spec.rb
index 90b6671edd3..900630bb6e2 100644
--- a/spec/presenters/project_clusterable_presenter_spec.rb
+++ b/spec/presenters/project_clusterable_presenter_spec.rb
@@ -43,6 +43,12 @@ RSpec.describe ProjectClusterablePresenter do
it { is_expected.to eq(new_project_cluster_path(project)) }
end
+ describe '#connect_path' do
+ subject { presenter.connect_path }
+
+ it { is_expected.to eq(connect_project_clusters_path(project)) }
+ end
+
describe '#authorize_aws_role_path' do
subject { presenter.authorize_aws_role_path }
diff --git a/spec/presenters/project_presenter_spec.rb b/spec/presenters/project_presenter_spec.rb
index e4a08bd56c8..33a4a1b9d4c 100644
--- a/spec/presenters/project_presenter_spec.rb
+++ b/spec/presenters/project_presenter_spec.rb
@@ -747,10 +747,4 @@ RSpec.describe ProjectPresenter do
end
end
end
-
- describe '#add_code_quality_ci_yml_path' do
- subject { presenter.add_code_quality_ci_yml_path }
-
- it { is_expected.to match(/code_quality_walkthrough=true.*template=Code-Quality/) }
- end
end
diff --git a/spec/presenters/projects/security/configuration_presenter_spec.rb b/spec/presenters/projects/security/configuration_presenter_spec.rb
index 5f874ab5a3f..47ef0cf1192 100644
--- a/spec/presenters/projects/security/configuration_presenter_spec.rb
+++ b/spec/presenters/projects/security/configuration_presenter_spec.rb
@@ -13,8 +13,6 @@ RSpec.describe Projects::Security::ConfigurationPresenter do
before do
stub_licensed_features(licensed_scan_types.to_h { |type| [type, true] })
-
- stub_feature_flags(corpus_management_ui: false)
end
describe '#to_html_data_attribute' do
diff --git a/spec/presenters/search_service_presenter_spec.rb b/spec/presenters/search_service_presenter_spec.rb
index 06ece838d8d..af9fee8cfd9 100644
--- a/spec/presenters/search_service_presenter_spec.rb
+++ b/spec/presenters/search_service_presenter_spec.rb
@@ -4,13 +4,33 @@ require 'spec_helper'
RSpec.describe SearchServicePresenter do
let(:user) { create(:user) }
+ let(:search) { '' }
let(:search_service) { SearchService.new(user, search: search, scope: scope) }
let(:presenter) { described_class.new(search_service, current_user: user) }
+ describe '#search_objects' do
+ let(:search_objects) { Kaminari::PaginatableArray.new([]) }
+
+ context 'objects do not respond to eager_load' do
+ before do
+ allow(search_service).to receive(:search_objects).and_return(search_objects)
+ allow(search_objects).to receive(:respond_to?).with(:eager_load).and_return(false)
+ end
+
+ context 'users scope' do
+ let(:scope) { 'users' }
+
+ it 'does not eager load anything' do
+ expect(search_objects).not_to receive(:eager_load)
+ presenter.search_objects
+ end
+ end
+ end
+ end
+
describe '#show_results_status?' do
using RSpec::Parameterized::TableSyntax
- let(:search) { '' }
let(:scope) { nil }
before do
diff --git a/spec/presenters/user_presenter_spec.rb b/spec/presenters/user_presenter_spec.rb
index 9c51c0b0078..883eec68304 100644
--- a/spec/presenters/user_presenter_spec.rb
+++ b/spec/presenters/user_presenter_spec.rb
@@ -5,7 +5,9 @@ require 'spec_helper'
RSpec.describe UserPresenter do
let_it_be(:user) { create(:user) }
- subject(:presenter) { described_class.new(user) }
+ let(:current_user) { user }
+
+ subject(:presenter) { described_class.new(user, current_user: current_user) }
describe '#web_path' do
it { expect(presenter.web_path).to eq("/#{user.username}") }
@@ -14,4 +16,65 @@ RSpec.describe UserPresenter do
describe '#web_url' do
it { expect(presenter.web_url).to eq("http://localhost/#{user.username}") }
end
+
+ context 'Gitpod' do
+ let(:gitpod_url) { "https://gitpod.io" }
+ let(:gitpod_application_enabled) { true }
+
+ before do
+ allow(Gitlab::CurrentSettings).to receive(:gitpod_enabled).and_return(gitpod_application_enabled)
+ allow(Gitlab::CurrentSettings).to receive(:gitpod_url).and_return(gitpod_url)
+ end
+
+ context 'Gitpod enabled for application' do
+ describe '#preferences_gitpod_path' do
+ it { expect(presenter.preferences_gitpod_path).to eq("/-/profile/preferences#user_gitpod_enabled") }
+ end
+
+ describe '#profile_enable_gitpod_path' do
+ it { expect(presenter.profile_enable_gitpod_path).to eq("/-/profile?user%5Bgitpod_enabled%5D=true") }
+ end
+ end
+
+ context 'Gitpod disabled for application' do
+ let(:gitpod_application_enabled) { false }
+
+ describe '#preferences_gitpod_path' do
+ it { expect(presenter.preferences_gitpod_path).to eq(nil) }
+ end
+
+ describe '#profile_enable_gitpod_path' do
+ it { expect(presenter.profile_enable_gitpod_path).to eq(nil) }
+ end
+ end
+ end
+
+ describe '#saved_replies' do
+ let_it_be(:other_user) { create(:user) }
+ let_it_be(:saved_reply) { create(:saved_reply, user: user) }
+
+ context 'when feature is disabled' do
+ before do
+ stub_feature_flags(saved_replies: false)
+ end
+
+ it { expect(presenter.saved_replies).to eq(::Users::SavedReply.none) }
+ end
+
+ context 'when feature is enabled' do
+ before do
+ stub_feature_flags(saved_replies: current_user)
+ end
+
+ context 'when user has no permission to read saved replies' do
+ let(:current_user) { other_user }
+
+ it { expect(presenter.saved_replies).to eq(::Users::SavedReply.none) }
+ end
+
+ context 'when user has permission to read saved replies' do
+ it { expect(presenter.saved_replies).to eq([saved_reply]) }
+ end
+ end
+ end
end
diff --git a/spec/requests/admin/background_migrations_controller_spec.rb b/spec/requests/admin/background_migrations_controller_spec.rb
index 67c9c4df827..55971a00e55 100644
--- a/spec/requests/admin/background_migrations_controller_spec.rb
+++ b/spec/requests/admin/background_migrations_controller_spec.rb
@@ -16,7 +16,13 @@ RSpec.describe Admin::BackgroundMigrationsController, :enable_admin_mode do
create(:batched_background_migration_job, :failed, batched_migration: migration, batch_size: 10, min_value: 6, max_value: 15, attempts: 3)
allow_next_instance_of(Gitlab::BackgroundMigration::BatchingStrategies::PrimaryKeyBatchingStrategy) do |batch_class|
- allow(batch_class).to receive(:next_batch).with(anything, anything, batch_min_value: 6, batch_size: 5).and_return([6, 10])
+ allow(batch_class).to receive(:next_batch).with(
+ anything,
+ anything,
+ batch_min_value: 6,
+ batch_size: 5,
+ job_arguments: migration.job_arguments
+ ).and_return([6, 10])
end
end
diff --git a/spec/requests/api/admin/instance_clusters_spec.rb b/spec/requests/api/admin/instance_clusters_spec.rb
index ab3b6b718e1..7b3224f58c5 100644
--- a/spec/requests/api/admin/instance_clusters_spec.rb
+++ b/spec/requests/api/admin/instance_clusters_spec.rb
@@ -21,6 +21,10 @@ RSpec.describe ::API::Admin::InstanceClusters do
create_list(:cluster, 3, :provided_by_gcp, :instance, :production_environment)
end
+ include_examples ':certificate_based_clusters feature flag API responses' do
+ let(:subject) { get api("/admin/clusters", admin_user) }
+ end
+
context "when authenticated as a non-admin user" do
it 'returns 403' do
get api('/admin/clusters', regular_user)
@@ -62,6 +66,10 @@ RSpec.describe ::API::Admin::InstanceClusters do
let(:cluster_id) { cluster.id }
+ include_examples ':certificate_based_clusters feature flag API responses' do
+ let(:subject) { get api("/admin/clusters/#{cluster_id}", admin_user) }
+ end
+
context "when authenticated as admin" do
before do
get api("/admin/clusters/#{cluster_id}", admin_user)
@@ -188,6 +196,10 @@ RSpec.describe ::API::Admin::InstanceClusters do
}
end
+ include_examples ':certificate_based_clusters feature flag API responses' do
+ let(:subject) { post api('/admin/clusters/add', admin_user), params: cluster_params }
+ end
+
context 'authorized user' do
before do
post api('/admin/clusters/add', admin_user), params: cluster_params
@@ -317,6 +329,10 @@ RSpec.describe ::API::Admin::InstanceClusters do
create(:cluster, :instance, :provided_by_gcp, domain: 'old-domain.com')
end
+ include_examples ':certificate_based_clusters feature flag API responses' do
+ let(:subject) { put api("/admin/clusters/#{cluster.id}", admin_user), params: update_params }
+ end
+
context 'authorized user' do
before do
put api("/admin/clusters/#{cluster.id}", admin_user), params: update_params
@@ -448,6 +464,10 @@ RSpec.describe ::API::Admin::InstanceClusters do
create(:cluster, :instance, :provided_by_gcp)
end
+ include_examples ':certificate_based_clusters feature flag API responses' do
+ let(:subject) { delete api("/admin/clusters/#{cluster.id}", admin_user), params: cluster_params }
+ end
+
context 'authorized user' do
before do
delete api("/admin/clusters/#{cluster.id}", admin_user), params: cluster_params
diff --git a/spec/requests/api/broadcast_messages_spec.rb b/spec/requests/api/broadcast_messages_spec.rb
index b023ec398a2..76412c80f4c 100644
--- a/spec/requests/api/broadcast_messages_spec.rb
+++ b/spec/requests/api/broadcast_messages_spec.rb
@@ -17,7 +17,7 @@ RSpec.describe API::BroadcastMessages do
expect(response).to include_pagination_headers
expect(json_response).to be_kind_of(Array)
expect(json_response.first.keys)
- .to match_array(%w(id message starts_at ends_at color font active target_path broadcast_type dismissable))
+ .to match_array(%w(id message starts_at ends_at color font active target_access_levels target_path broadcast_type dismissable))
end
end
@@ -28,7 +28,7 @@ RSpec.describe API::BroadcastMessages do
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['id']).to eq message.id
expect(json_response.keys)
- .to match_array(%w(id message starts_at ends_at color font active target_path broadcast_type dismissable))
+ .to match_array(%w(id message starts_at ends_at color font active target_access_levels target_path broadcast_type dismissable))
end
end
@@ -77,6 +77,16 @@ RSpec.describe API::BroadcastMessages do
expect(json_response['font']).to eq attrs[:font]
end
+ it 'accepts target access levels' do
+ target_access_levels = [Gitlab::Access::GUEST, Gitlab::Access::DEVELOPER]
+ attrs = attributes_for(:broadcast_message, target_access_levels: target_access_levels)
+
+ post api('/broadcast_messages', admin), params: attrs
+
+ expect(response).to have_gitlab_http_status(:created)
+ expect(json_response['target_access_levels']).to eq attrs[:target_access_levels]
+ end
+
it 'accepts a target path' do
attrs = attributes_for(:broadcast_message, target_path: "*/welcome")
@@ -171,6 +181,15 @@ RSpec.describe API::BroadcastMessages do
expect { message.reload }.to change { message.message }.to('new message')
end
+ it 'accepts a new target_access_levels' do
+ attrs = { target_access_levels: [Gitlab::Access::MAINTAINER] }
+
+ put api("/broadcast_messages/#{message.id}", admin), params: attrs
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response['target_access_levels']).to eq attrs[:target_access_levels]
+ end
+
it 'accepts a new target_path' do
attrs = { target_path: '*/welcome' }
diff --git a/spec/requests/api/ci/jobs_spec.rb b/spec/requests/api/ci/jobs_spec.rb
index 7c85cbc31a5..f6dae7e8e23 100644
--- a/spec/requests/api/ci/jobs_spec.rb
+++ b/spec/requests/api/ci/jobs_spec.rb
@@ -707,12 +707,14 @@ RSpec.describe API::Ci::Jobs do
end
describe 'POST /projects/:id/jobs/:job_id/play' do
+ let(:params) { {} }
+
before do
- post api("/projects/#{project.id}/jobs/#{job.id}/play", api_user)
+ post api("/projects/#{project.id}/jobs/#{job.id}/play", api_user), params: params
end
context 'on a playable job' do
- let_it_be(:job) { create(:ci_bridge, :playable, pipeline: pipeline, downstream: project) }
+ let_it_be(:job) { create(:ci_build, :manual, project: project, pipeline: pipeline) }
before do
project.add_developer(user)
@@ -720,6 +722,8 @@ RSpec.describe API::Ci::Jobs do
context 'when user is authorized to trigger a manual action' do
context 'that is a bridge' do
+ let_it_be(:job) { create(:ci_bridge, :playable, pipeline: pipeline, downstream: project) }
+
it 'plays the job' do
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['user']['id']).to eq(user.id)
@@ -729,8 +733,6 @@ RSpec.describe API::Ci::Jobs do
end
context 'that is a build' do
- let_it_be(:job) { create(:ci_build, :manual, project: project, pipeline: pipeline) }
-
it 'plays the job' do
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['user']['id']).to eq(user.id)
@@ -738,6 +740,47 @@ RSpec.describe API::Ci::Jobs do
expect(job.reload).to be_pending
end
end
+
+ context 'when the user provides valid custom variables' do
+ let(:params) { { job_variables_attributes: [{ key: 'TEST_VAR', value: 'test' }] } }
+
+ it 'applies the variables to the job' do
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(job.reload).to be_pending
+ expect(job.job_variables.map(&:key)).to contain_exactly('TEST_VAR')
+ expect(job.job_variables.map(&:value)).to contain_exactly('test')
+ end
+ end
+
+ context 'when the user provides a variable without a key' do
+ let(:params) { { job_variables_attributes: [{ value: 'test' }] } }
+
+ it 'reports that the key is missing' do
+ expect(response).to have_gitlab_http_status(:bad_request)
+ expect(json_response['error']).to eq('job_variables_attributes[0][key] is missing')
+ expect(job.reload).to be_manual
+ end
+ end
+
+ context 'when the user provides a variable without a value' do
+ let(:params) { { job_variables_attributes: [{ key: 'TEST_VAR' }] } }
+
+ it 'reports that the value is missing' do
+ expect(response).to have_gitlab_http_status(:bad_request)
+ expect(json_response['error']).to eq('job_variables_attributes[0][value] is missing')
+ expect(job.reload).to be_manual
+ end
+ end
+
+ context 'when the user provides both valid and invalid variables' do
+ let(:params) { { job_variables_attributes: [{ key: 'TEST_VAR', value: 'test' }, { value: 'test2' }] } }
+
+ it 'reports the invalid variables and does not run the job' do
+ expect(response).to have_gitlab_http_status(:bad_request)
+ expect(json_response['error']).to eq('job_variables_attributes[1][key] is missing')
+ expect(job.reload).to be_manual
+ end
+ end
end
context 'when user is not authorized to trigger a manual action' do
diff --git a/spec/requests/api/ci/pipelines_spec.rb b/spec/requests/api/ci/pipelines_spec.rb
index 1b87a5e24f5..12faeec94da 100644
--- a/spec/requests/api/ci/pipelines_spec.rb
+++ b/spec/requests/api/ci/pipelines_spec.rb
@@ -1075,6 +1075,23 @@ RSpec.describe API::Ci::Pipelines do
expect(json_response['id']).to be nil
end
end
+
+ context 'handles errors' do
+ before do
+ service_response = ServiceResponse.error(http_status: 403, message: 'hello world')
+ allow_next_instance_of(::Ci::RetryPipelineService) do |service|
+ allow(service).to receive(:check_access).and_return(service_response)
+ end
+ end
+
+ it 'returns error' do
+ post api("/projects/#{project.id}/pipelines/#{pipeline.id}/retry", user)
+
+ expect(response).to have_gitlab_http_status(:forbidden)
+ expect(json_response['message']).to eq 'hello world'
+ expect(json_response['id']).to be nil
+ end
+ end
end
describe 'POST /projects/:id/pipelines/:pipeline_id/cancel' do
diff --git a/spec/requests/api/ci/runner/jobs_request_post_spec.rb b/spec/requests/api/ci/runner/jobs_request_post_spec.rb
index 68f7581bf06..d317386dc73 100644
--- a/spec/requests/api/ci/runner/jobs_request_post_spec.rb
+++ b/spec/requests/api/ci/runner/jobs_request_post_spec.rb
@@ -156,7 +156,7 @@ RSpec.describe API::Ci::Runner, :clean_gitlab_redis_shared_state do
'sha' => job.sha,
'before_sha' => job.before_sha,
'ref_type' => 'branch',
- 'refspecs' => ["+#{pipeline.sha}:refs/pipelines/#{pipeline.id}",
+ 'refspecs' => ["+refs/pipelines/#{pipeline.id}:refs/pipelines/#{pipeline.id}",
"+refs/heads/#{job.ref}:refs/remotes/origin/#{job.ref}"],
'depth' => project.ci_default_git_depth }
end
@@ -291,7 +291,7 @@ RSpec.describe API::Ci::Runner, :clean_gitlab_redis_shared_state do
expect(response).to have_gitlab_http_status(:created)
expect(json_response['git_info']['refspecs'])
- .to contain_exactly("+#{pipeline.sha}:refs/pipelines/#{pipeline.id}",
+ .to contain_exactly("+refs/pipelines/#{pipeline.id}:refs/pipelines/#{pipeline.id}",
'+refs/tags/*:refs/tags/*',
'+refs/heads/*:refs/remotes/origin/*')
end
@@ -359,7 +359,7 @@ RSpec.describe API::Ci::Runner, :clean_gitlab_redis_shared_state do
expect(response).to have_gitlab_http_status(:created)
expect(json_response['git_info']['refspecs'])
- .to contain_exactly("+#{pipeline.sha}:refs/pipelines/#{pipeline.id}",
+ .to contain_exactly("+refs/pipelines/#{pipeline.id}:refs/pipelines/#{pipeline.id}",
'+refs/tags/*:refs/tags/*',
'+refs/heads/*:refs/remotes/origin/*')
end
diff --git a/spec/requests/api/ci/runner/jobs_trace_spec.rb b/spec/requests/api/ci/runner/jobs_trace_spec.rb
index 2760e306693..d6928969beb 100644
--- a/spec/requests/api/ci/runner/jobs_trace_spec.rb
+++ b/spec/requests/api/ci/runner/jobs_trace_spec.rb
@@ -35,7 +35,7 @@ RSpec.describe API::Ci::Runner, :clean_gitlab_redis_trace_chunks do
let(:headers) { { API::Ci::Helpers::Runner::JOB_TOKEN_HEADER => job.token, 'Content-Type' => 'text/plain' } }
let(:headers_with_range) { headers.merge({ 'Content-Range' => '11-20' }) }
- let(:update_interval) { 10.seconds.to_i }
+ let(:update_interval) { 10.seconds }
before do
initial_patch_the_trace
@@ -81,7 +81,7 @@ RSpec.describe API::Ci::Runner, :clean_gitlab_redis_trace_chunks do
end
context 'when job was not updated recently' do
- let(:update_interval) { 15.minutes.to_i }
+ let(:update_interval) { 16.minutes }
it { expect { patch_the_trace }.to change { job.updated_at } }
@@ -293,10 +293,10 @@ RSpec.describe API::Ci::Runner, :clean_gitlab_redis_trace_chunks do
end
end
- Timecop.travel(job.updated_at + update_interval) do
+ travel_to(job.updated_at + update_interval) do
patch api("/jobs/#{job_id}/trace"), params: content, headers: request_headers
- job.reload
end
+ job.reload
end
def initial_patch_the_trace
diff --git a/spec/requests/api/ci/runner/runners_post_spec.rb b/spec/requests/api/ci/runner/runners_post_spec.rb
index 5eb5d3977a3..1d553751eea 100644
--- a/spec/requests/api/ci/runner/runners_post_spec.rb
+++ b/spec/requests/api/ci/runner/runners_post_spec.rb
@@ -15,7 +15,7 @@ RSpec.describe API::Ci::Runner, :clean_gitlab_redis_shared_state do
context 'when invalid token is provided' do
it 'returns 403 error' do
- allow_next_instance_of(::Ci::RegisterRunnerService) do |service|
+ allow_next_instance_of(::Ci::Runners::RegisterRunnerService) do |service|
allow(service).to receive(:execute).and_return(nil)
end
@@ -43,7 +43,7 @@ RSpec.describe API::Ci::Runner, :clean_gitlab_redis_shared_state do
let_it_be(:new_runner) { create(:ci_runner) }
before do
- allow_next_instance_of(::Ci::RegisterRunnerService) do |service|
+ allow_next_instance_of(::Ci::Runners::RegisterRunnerService) do |service|
expected_params = {
description: 'server.hostname',
maintenance_note: 'Some maintainer notes',
@@ -108,7 +108,7 @@ RSpec.describe API::Ci::Runner, :clean_gitlab_redis_shared_state do
let(:new_runner) { create(:ci_runner) }
it 'converts to maintenance_note param' do
- allow_next_instance_of(::Ci::RegisterRunnerService) do |service|
+ allow_next_instance_of(::Ci::Runners::RegisterRunnerService) do |service|
expect(service).to receive(:execute)
.once
.with('valid token', a_hash_including('maintenance_note' => 'Some maintainer notes')
@@ -133,7 +133,7 @@ RSpec.describe API::Ci::Runner, :clean_gitlab_redis_shared_state do
let_it_be(:new_runner) { create(:ci_runner) }
it 'uses active value in registration' do
- expect_next_instance_of(::Ci::RegisterRunnerService) do |service|
+ expect_next_instance_of(::Ci::Runners::RegisterRunnerService) do |service|
expected_params = { active: false }.stringify_keys
expect(service).to receive(:execute)
diff --git a/spec/requests/api/ci/runner/runners_reset_spec.rb b/spec/requests/api/ci/runner/runners_reset_spec.rb
new file mode 100644
index 00000000000..8a61012ead1
--- /dev/null
+++ b/spec/requests/api/ci/runner/runners_reset_spec.rb
@@ -0,0 +1,65 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe API::Ci::Runner, :clean_gitlab_redis_shared_state do
+ include StubGitlabCalls
+ include RedisHelpers
+ include WorkhorseHelpers
+
+ before do
+ stub_feature_flags(ci_enable_live_trace: true)
+ stub_feature_flags(runner_registration_control: false)
+ stub_gitlab_calls
+ stub_application_setting(valid_runner_registrars: ApplicationSetting::VALID_RUNNER_REGISTRAR_TYPES)
+ end
+
+ let_it_be(:group_settings) { create(:namespace_settings, runner_token_expiration_interval: 5.days.to_i) }
+ let_it_be(:group) { create(:group, namespace_settings: group_settings) }
+ let_it_be(:instance_runner, reload: true) { create(:ci_runner, :instance) }
+ let_it_be(:group_runner) { create(:ci_runner, :group, groups: [group], token_expires_at: 1.day.from_now) }
+
+ describe 'POST /runners/reset_authentication_token', :freeze_time do
+ context 'current token provided' do
+ it "resets authentication token when token doesn't have an expiration" do
+ expect do
+ post api("/runners/reset_authentication_token"), params: { token: instance_runner.reload.token }
+
+ expect(response).to have_gitlab_http_status(:success)
+ expect(json_response).to eq({ 'token' => instance_runner.reload.token, 'token_expires_at' => nil })
+ expect(instance_runner.reload.token_expires_at).to be_nil
+ end.to change { instance_runner.reload.token }
+ end
+
+ it 'resets authentication token when token is not expired' do
+ expect do
+ post api("/runners/reset_authentication_token"), params: { token: group_runner.reload.token }
+
+ expect(response).to have_gitlab_http_status(:success)
+ expect(json_response).to eq({ 'token' => group_runner.reload.token, 'token_expires_at' => group_runner.reload.token_expires_at.iso8601(3) })
+ expect(group_runner.reload.token_expires_at).to eq(5.days.from_now)
+ end.to change { group_runner.reload.token }
+ end
+
+ it 'does not reset authentication token when token is expired' do
+ expect do
+ instance_runner.update!(token_expires_at: 1.day.ago)
+ post api("/runners/reset_authentication_token"), params: { token: instance_runner.reload.token }
+
+ expect(response).to have_gitlab_http_status(:forbidden)
+ instance_runner.update!(token_expires_at: nil)
+ end.not_to change { instance_runner.reload.token }
+ end
+ end
+
+ context 'wrong current token provided' do
+ it 'does not reset authentication token' do
+ expect do
+ post api("/runners/reset_authentication_token"), params: { token: 'garbage' }
+
+ expect(response).to have_gitlab_http_status(:forbidden)
+ end.not_to change { instance_runner.reload.token }
+ end
+ end
+ end
+end
diff --git a/spec/requests/api/ci/runners_spec.rb b/spec/requests/api/ci/runners_spec.rb
index 336ce70d8d2..a1fda68b77b 100644
--- a/spec/requests/api/ci/runners_spec.rb
+++ b/spec/requests/api/ci/runners_spec.rb
@@ -530,7 +530,7 @@ RSpec.describe API::Ci::Runners do
context 'admin user' do
context 'when runner is shared' do
it 'deletes runner' do
- expect_next_instance_of(Ci::UnregisterRunnerService, shared_runner) do |service|
+ expect_next_instance_of(Ci::Runners::UnregisterRunnerService, shared_runner, admin) do |service|
expect(service).to receive(:execute).once.and_call_original
end
@@ -548,7 +548,7 @@ RSpec.describe API::Ci::Runners do
context 'when runner is not shared' do
it 'deletes used project runner' do
- expect_next_instance_of(Ci::UnregisterRunnerService, project_runner) do |service|
+ expect_next_instance_of(Ci::Runners::UnregisterRunnerService, project_runner, admin) do |service|
expect(service).to receive(:execute).once.and_call_original
end
@@ -561,7 +561,7 @@ RSpec.describe API::Ci::Runners do
end
it 'returns 404 if runner does not exist' do
- allow_next_instance_of(Ci::UnregisterRunnerService) do |service|
+ allow_next_instance_of(Ci::Runners::UnregisterRunnerService) do |service|
expect(service).not_to receive(:execute)
end
@@ -646,7 +646,7 @@ RSpec.describe API::Ci::Runners do
context 'unauthorized user' do
it 'does not delete project runner' do
- allow_next_instance_of(Ci::UnregisterRunnerService) do |service|
+ allow_next_instance_of(Ci::Runners::UnregisterRunnerService) do |service|
expect(service).not_to receive(:execute)
end
diff --git a/spec/requests/api/ci/secure_files_spec.rb b/spec/requests/api/ci/secure_files_spec.rb
index 5cf6999f60a..aa479cb8713 100644
--- a/spec/requests/api/ci/secure_files_spec.rb
+++ b/spec/requests/api/ci/secure_files_spec.rb
@@ -8,49 +8,72 @@ RSpec.describe API::Ci::SecureFiles do
stub_feature_flags(ci_secure_files: true)
end
- let_it_be(:user) { create(:user) }
- let_it_be(:user2) { create(:user) }
- let_it_be(:project) { create(:project, creator_id: user.id) }
- let_it_be(:maintainer) { create(:project_member, :maintainer, user: user, project: project) }
- let_it_be(:developer) { create(:project_member, :developer, user: user2, project: project) }
+ let_it_be(:maintainer) { create(:user) }
+ let_it_be(:developer) { create(:user) }
+ let_it_be(:guest) { create(:user) }
+ let_it_be(:anonymous) { create(:user) }
+ let_it_be(:project) { create(:project, creator_id: maintainer.id) }
let_it_be(:secure_file) { create(:ci_secure_file, project: project) }
+ before_all do
+ project.add_maintainer(maintainer)
+ project.add_developer(developer)
+ project.add_guest(guest)
+ end
+
describe 'GET /projects/:id/secure_files' do
context 'feature flag' do
it 'returns a 503 when the feature flag is disabled' do
stub_feature_flags(ci_secure_files: false)
- get api("/projects/#{project.id}/secure_files", user)
+ get api("/projects/#{project.id}/secure_files", maintainer)
expect(response).to have_gitlab_http_status(:service_unavailable)
end
it 'returns a 200 when the feature flag is enabled' do
- get api("/projects/#{project.id}/secure_files", user)
+ get api("/projects/#{project.id}/secure_files", maintainer)
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response).to be_a(Array)
+ end
+ end
+
+ context 'authenticated user with admin permissions' do
+ it 'returns project secure files' do
+ get api("/projects/#{project.id}/secure_files", maintainer)
expect(response).to have_gitlab_http_status(:ok)
expect(json_response).to be_a(Array)
end
end
- context 'authorized user with proper permissions' do
+ context 'authenticated user with read permissions' do
it 'returns project secure files' do
- get api("/projects/#{project.id}/secure_files", user)
+ get api("/projects/#{project.id}/secure_files", developer)
expect(response).to have_gitlab_http_status(:ok)
expect(json_response).to be_a(Array)
end
end
- context 'authorized user with invalid permissions' do
+ context 'authenticated user with guest permissions' do
it 'does not return project secure files' do
- get api("/projects/#{project.id}/secure_files", user2)
+ get api("/projects/#{project.id}/secure_files", guest)
expect(response).to have_gitlab_http_status(:forbidden)
end
end
- context 'unauthorized user' do
+ context 'authenticated user with no permissions' do
+ it 'does not return project secure files' do
+ get api("/projects/#{project.id}/secure_files", anonymous)
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+
+ context 'unauthenticated user' do
it 'does not return project secure files' do
get api("/projects/#{project.id}/secure_files")
@@ -60,9 +83,9 @@ RSpec.describe API::Ci::SecureFiles do
end
describe 'GET /projects/:id/secure_files/:secure_file_id' do
- context 'authorized user with proper permissions' do
+ context 'authenticated user with admin permissions' do
it 'returns project secure file details' do
- get api("/projects/#{project.id}/secure_files/#{secure_file.id}", user)
+ get api("/projects/#{project.id}/secure_files/#{secure_file.id}", maintainer)
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['name']).to eq(secure_file.name)
@@ -70,21 +93,31 @@ RSpec.describe API::Ci::SecureFiles do
end
it 'responds with 404 Not Found if requesting non-existing secure file' do
- get api("/projects/#{project.id}/secure_files/99999", user)
+ get api("/projects/#{project.id}/secure_files/#{non_existing_record_id}", maintainer)
expect(response).to have_gitlab_http_status(:not_found)
end
end
- context 'authorized user with invalid permissions' do
+ context 'authenticated user with read permissions' do
+ it 'returns project secure file details' do
+ get api("/projects/#{project.id}/secure_files/#{secure_file.id}", developer)
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response['name']).to eq(secure_file.name)
+ expect(json_response['permissions']).to eq(secure_file.permissions)
+ end
+ end
+
+ context 'authenticated user with no permissions' do
it 'does not return project secure file details' do
- get api("/projects/#{project.id}/secure_files/#{secure_file.id}", user2)
+ get api("/projects/#{project.id}/secure_files/#{secure_file.id}", anonymous)
- expect(response).to have_gitlab_http_status(:forbidden)
+ expect(response).to have_gitlab_http_status(:not_found)
end
end
- context 'unauthorized user' do
+ context 'unauthenticated user' do
it 'does not return project secure file details' do
get api("/projects/#{project.id}/secure_files/#{secure_file.id}")
@@ -94,34 +127,47 @@ RSpec.describe API::Ci::SecureFiles do
end
describe 'GET /projects/:id/secure_files/:secure_file_id/download' do
- context 'authorized user with proper permissions' do
+ context 'authenticated user with admin permissions' do
it 'returns a secure file' do
sample_file = fixture_file('ci_secure_files/upload-keystore.jks')
secure_file.file = CarrierWaveStringFile.new(sample_file)
secure_file.save!
- get api("/projects/#{project.id}/secure_files/#{secure_file.id}/download", user)
+ get api("/projects/#{project.id}/secure_files/#{secure_file.id}/download", maintainer)
expect(response).to have_gitlab_http_status(:ok)
expect(Base64.encode64(response.body)).to eq(Base64.encode64(sample_file))
end
it 'responds with 404 Not Found if requesting non-existing secure file' do
- get api("/projects/#{project.id}/secure_files/99999/download", user)
+ get api("/projects/#{project.id}/secure_files/#{non_existing_record_id}/download", maintainer)
expect(response).to have_gitlab_http_status(:not_found)
end
end
- context 'authorized user with invalid permissions' do
+ context 'authenticated user with read permissions' do
+ it 'returns a secure file' do
+ sample_file = fixture_file('ci_secure_files/upload-keystore.jks')
+ secure_file.file = CarrierWaveStringFile.new(sample_file)
+ secure_file.save!
+
+ get api("/projects/#{project.id}/secure_files/#{secure_file.id}/download", developer)
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(Base64.encode64(response.body)).to eq(Base64.encode64(sample_file))
+ end
+ end
+
+ context 'authenticated user with no permissions' do
it 'does not return project secure file details' do
- get api("/projects/#{project.id}/secure_files/#{secure_file.id}/download", user2)
+ get api("/projects/#{project.id}/secure_files/#{secure_file.id}/download", anonymous)
- expect(response).to have_gitlab_http_status(:forbidden)
+ expect(response).to have_gitlab_http_status(:not_found)
end
end
- context 'unauthorized user' do
+ context 'unauthenticated user' do
it 'does not return project secure file details' do
get api("/projects/#{project.id}/secure_files/#{secure_file.id}/download")
@@ -131,7 +177,7 @@ RSpec.describe API::Ci::SecureFiles do
end
describe 'POST /projects/:id/secure_files' do
- context 'authorized user with proper permissions' do
+ context 'authenticated user with admin permissions' do
it 'creates a secure file' do
params = {
file: fixture_file_upload('spec/fixtures/ci_secure_files/upload-keystore.jks'),
@@ -140,7 +186,7 @@ RSpec.describe API::Ci::SecureFiles do
}
expect do
- post api("/projects/#{project.id}/secure_files", user), params: params
+ post api("/projects/#{project.id}/secure_files", maintainer), params: params
end.to change {project.secure_files.count}.by(1)
expect(response).to have_gitlab_http_status(:created)
@@ -154,6 +200,7 @@ RSpec.describe API::Ci::SecureFiles do
Digest::SHA256.hexdigest(fixture_file('ci_secure_files/upload-keystore.jks'))
)
expect(json_response['id']).to eq(secure_file.id)
+ expect(Time.parse(json_response['created_at'])).to be_like_time(secure_file.created_at)
end
it 'creates a secure file with read_only permissions by default' do
@@ -163,7 +210,7 @@ RSpec.describe API::Ci::SecureFiles do
}
expect do
- post api("/projects/#{project.id}/secure_files", user), params: params
+ post api("/projects/#{project.id}/secure_files", maintainer), params: params
end.to change {project.secure_files.count}.by(1)
expect(json_response['permissions']).to eq('read_only')
@@ -176,11 +223,11 @@ RSpec.describe API::Ci::SecureFiles do
permissions: 'read_write'
}
- post api("/projects/#{project.id}/secure_files", user), params: post_params
+ post api("/projects/#{project.id}/secure_files", maintainer), params: post_params
secure_file_id = json_response['id']
- get api("/projects/#{project.id}/secure_files/#{secure_file_id}/download", user)
+ get api("/projects/#{project.id}/secure_files/#{secure_file_id}/download", maintainer)
expect(Base64.encode64(response.body)).to eq(Base64.encode64(fixture_file_upload('spec/fixtures/ci_secure_files/upload-keystore.jks').read))
end
@@ -188,7 +235,9 @@ RSpec.describe API::Ci::SecureFiles do
it 'returns an error when the file checksum fails to validate' do
secure_file.update!(checksum: 'foo')
- get api("/projects/#{project.id}/secure_files/#{secure_file.id}/download", user)
+ expect do
+ get api("/projects/#{project.id}/secure_files/#{secure_file.id}/download", maintainer)
+ end.not_to change { project.secure_files.count }
expect(response.code).to eq("500")
end
@@ -198,7 +247,9 @@ RSpec.describe API::Ci::SecureFiles do
name: 'upload-keystore.jks'
}
- post api("/projects/#{project.id}/secure_files", user), params: post_params
+ expect do
+ post api("/projects/#{project.id}/secure_files", maintainer), params: post_params
+ end.not_to change { project.secure_files.count }
expect(response).to have_gitlab_http_status(:bad_request)
expect(json_response['error']).to eq('file is missing')
@@ -209,7 +260,9 @@ RSpec.describe API::Ci::SecureFiles do
file: fixture_file_upload('spec/fixtures/ci_secure_files/upload-keystore.jks')
}
- post api("/projects/#{project.id}/secure_files", user), params: post_params
+ expect do
+ post api("/projects/#{project.id}/secure_files", maintainer), params: post_params
+ end.not_to change { project.secure_files.count }
expect(response).to have_gitlab_http_status(:bad_request)
expect(json_response['error']).to eq('name is missing')
@@ -222,7 +275,9 @@ RSpec.describe API::Ci::SecureFiles do
permissions: 'foo'
}
- post api("/projects/#{project.id}/secure_files", user), params: post_params
+ expect do
+ post api("/projects/#{project.id}/secure_files", maintainer), params: post_params
+ end.not_to change { project.secure_files.count }
expect(response).to have_gitlab_http_status(:bad_request)
expect(json_response['error']).to eq('permissions does not have a valid value')
@@ -240,7 +295,9 @@ RSpec.describe API::Ci::SecureFiles do
name: 'upload-keystore.jks'
}
- post api("/projects/#{project.id}/secure_files", user), params: post_params
+ expect do
+ post api("/projects/#{project.id}/secure_files", maintainer), params: post_params
+ end.not_to change { project.secure_files.count }
expect(response).to have_gitlab_http_status(:bad_request)
end
@@ -255,23 +312,39 @@ RSpec.describe API::Ci::SecureFiles do
name: 'upload-keystore.jks'
}
- post api("/projects/#{project.id}/secure_files", user), params: post_params
+ expect do
+ post api("/projects/#{project.id}/secure_files", maintainer), params: post_params
+ end.not_to change { project.secure_files.count }
expect(response).to have_gitlab_http_status(:payload_too_large)
end
end
- context 'authorized user with invalid permissions' do
+ context 'authenticated user with read permissions' do
it 'does not create a secure file' do
- post api("/projects/#{project.id}/secure_files", user2)
+ expect do
+ post api("/projects/#{project.id}/secure_files", developer)
+ end.not_to change { project.secure_files.count }
expect(response).to have_gitlab_http_status(:forbidden)
end
end
- context 'unauthorized user' do
+ context 'authenticated user with no permissions' do
it 'does not create a secure file' do
- post api("/projects/#{project.id}/secure_files")
+ expect do
+ post api("/projects/#{project.id}/secure_files", anonymous)
+ end.not_to change { project.secure_files.count }
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+
+ context 'unauthenticated user' do
+ it 'does not create a secure file' do
+ expect do
+ post api("/projects/#{project.id}/secure_files")
+ end.not_to change { project.secure_files.count }
expect(response).to have_gitlab_http_status(:unauthorized)
end
@@ -279,33 +352,49 @@ RSpec.describe API::Ci::SecureFiles do
end
describe 'DELETE /projects/:id/secure_files/:secure_file_id' do
- context 'authorized user with proper permissions' do
+ context 'authenticated user with admin permissions' do
it 'deletes the secure file' do
expect do
- delete api("/projects/#{project.id}/secure_files/#{secure_file.id}", user)
+ delete api("/projects/#{project.id}/secure_files/#{secure_file.id}", maintainer)
expect(response).to have_gitlab_http_status(:no_content)
- end.to change {project.secure_files.count}.by(-1)
+ end.to change { project.secure_files.count }
end
it 'responds with 404 Not Found if requesting non-existing secure_file' do
- delete api("/projects/#{project.id}/secure_files/99999", user)
+ expect do
+ delete api("/projects/#{project.id}/secure_files/#{non_existing_record_id}", maintainer)
+ end.not_to change { project.secure_files.count }
expect(response).to have_gitlab_http_status(:not_found)
end
end
- context 'authorized user with invalid permissions' do
+ context 'authenticated user with read permissions' do
it 'does not delete the secure_file' do
- delete api("/projects/#{project.id}/secure_files/#{secure_file.id}", user2)
+ expect do
+ delete api("/projects/#{project.id}/secure_files/#{secure_file.id}", developer)
+ end.not_to change { project.secure_files.count }
expect(response).to have_gitlab_http_status(:forbidden)
end
end
- context 'unauthorized user' do
+ context 'authenticated user with no permissions' do
it 'does not delete the secure_file' do
- delete api("/projects/#{project.id}/secure_files/#{secure_file.id}")
+ expect do
+ delete api("/projects/#{project.id}/secure_files/#{secure_file.id}", anonymous)
+ end.not_to change { project.secure_files.count }
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+
+ context 'unauthenticated user' do
+ it 'does not delete the secure_file' do
+ expect do
+ delete api("/projects/#{project.id}/secure_files/#{secure_file.id}")
+ end.not_to change { project.secure_files.count }
expect(response).to have_gitlab_http_status(:unauthorized)
end
diff --git a/spec/requests/api/commits_spec.rb b/spec/requests/api/commits_spec.rb
index 156a4cf5ff3..67c2ec91540 100644
--- a/spec/requests/api/commits_spec.rb
+++ b/spec/requests/api/commits_spec.rb
@@ -127,6 +127,15 @@ RSpec.describe API::Commits do
it_behaves_like 'project commits'
end
+ context 'when repository does not exist' do
+ let(:project) { create(:project, creator: user, path: 'my.project') }
+
+ it_behaves_like '404 response' do
+ let(:request) { get api(route, current_user) }
+ let(:message) { '404 Repository Not Found' }
+ end
+ end
+
context "path optional parameter" do
it "returns project commits matching provided path parameter" do
path = 'files/ruby/popen.rb'
diff --git a/spec/requests/api/container_repositories_spec.rb b/spec/requests/api/container_repositories_spec.rb
index 9809702467d..90f0243dbfc 100644
--- a/spec/requests/api/container_repositories_spec.rb
+++ b/spec/requests/api/container_repositories_spec.rb
@@ -3,6 +3,8 @@
require 'spec_helper'
RSpec.describe API::ContainerRepositories do
+ include_context 'container registry client stubs'
+
let_it_be(:project) { create(:project, :private) }
let_it_be(:reporter) { create(:user) }
let_it_be(:guest) { create(:user) }
@@ -103,6 +105,68 @@ RSpec.describe API::ContainerRepositories do
expect(json_response['tags_count']).to eq(2)
end
end
+
+ context 'with size param' do
+ let(:url) { "/registry/repositories/#{repository.id}?size=true" }
+ let(:on_com) { true }
+ let(:created_at) { ::ContainerRepository::MIGRATION_PHASE_1_STARTED_AT + 3.months }
+
+ before do
+ allow(::Gitlab).to receive(:com?).and_return(on_com)
+ repository.update_column(:created_at, created_at)
+ end
+
+ it 'returns a repository and its size' do
+ stub_container_registry_gitlab_api_support(supported: true) do |client|
+ stub_container_registry_gitlab_api_repository_details(client, path: repository.path, size_bytes: 12345)
+ end
+
+ subject
+
+ expect(json_response['size']).to eq(12345)
+ end
+
+ context 'with a network error' do
+ it 'returns an error message' do
+ stub_container_registry_gitlab_api_network_error
+
+ subject
+
+ expect(response).to have_gitlab_http_status(:service_unavailable)
+ expect(json_response['message']).to include('We are having trouble connecting to the Container Registry')
+ end
+ end
+
+ context 'with not supporting the gitlab api' do
+ it 'returns nil' do
+ stub_container_registry_gitlab_api_support(supported: false)
+
+ subject
+
+ expect(json_response['size']).to eq(nil)
+ end
+ end
+
+ context 'not on .com' do
+ let(:on_com) { false }
+
+ it 'returns nil' do
+ subject
+
+ expect(json_response['size']).to eq(nil)
+ end
+ end
+
+ context 'with an older container repository' do
+ let(:created_at) { ::ContainerRepository::MIGRATION_PHASE_1_STARTED_AT - 3.months }
+
+ it 'returns nil' do
+ subject
+
+ expect(json_response['size']).to eq(nil)
+ end
+ end
+ end
end
context 'with invalid repository id' do
diff --git a/spec/requests/api/deploy_tokens_spec.rb b/spec/requests/api/deploy_tokens_spec.rb
index 38380fa4460..b5f8da1f327 100644
--- a/spec/requests/api/deploy_tokens_spec.rb
+++ b/spec/requests/api/deploy_tokens_spec.rb
@@ -130,6 +130,55 @@ RSpec.describe API::DeployTokens do
end
end
+ describe 'GET /projects/:id/deploy_tokens/:token_id' do
+ subject do
+ get api("/projects/#{project.id}/deploy_tokens/#{deploy_token.id}", user)
+ response
+ end
+
+ context 'when unauthenticated' do
+ let(:user) { nil }
+
+ it { is_expected.to have_gitlab_http_status(:not_found) }
+ end
+
+ context 'when authenticated as non-admin user' do
+ before do
+ project.add_developer(user)
+ end
+
+ it { is_expected.to have_gitlab_http_status(:forbidden) }
+ end
+
+ context 'when authenticated as maintainer' do
+ before do
+ project.add_maintainer(user)
+ end
+
+ it { is_expected.to have_gitlab_http_status(:ok) }
+
+ it 'returns specific deploy token for the project' do
+ subject
+
+ expect(response).to match_response_schema('public_api/v4/deploy_token')
+ end
+
+ context 'invalid request' do
+ it 'returns not found with invalid project id' do
+ get api("/projects/bad_id/deploy_tokens/#{deploy_token.id}", user)
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+
+ it 'returns not found with invalid token id' do
+ get api("/projects/#{project.id}/deploy_tokens/#{non_existing_record_id}", user)
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+ end
+ end
+
describe 'GET /groups/:id/deploy_tokens' do
subject do
get api("/groups/#{group.id}/deploy_tokens", user)
@@ -188,6 +237,55 @@ RSpec.describe API::DeployTokens do
end
end
+ describe 'GET /groups/:id/deploy_tokens/:token_id' do
+ subject do
+ get api("/groups/#{group.id}/deploy_tokens/#{group_deploy_token.id}", user)
+ response
+ end
+
+ context 'when unauthenticated' do
+ let(:user) { nil }
+
+ it { is_expected.to have_gitlab_http_status(:forbidden) }
+ end
+
+ context 'when authenticated as non-admin user' do
+ before do
+ group.add_developer(user)
+ end
+
+ it { is_expected.to have_gitlab_http_status(:forbidden) }
+ end
+
+ context 'when authenticated as maintainer' do
+ before do
+ group.add_maintainer(user)
+ end
+
+ it { is_expected.to have_gitlab_http_status(:ok) }
+
+ it 'returns specific deploy token for the group' do
+ subject
+
+ expect(response).to match_response_schema('public_api/v4/deploy_token')
+ end
+
+ context 'invalid request' do
+ it 'returns not found with invalid group id' do
+ get api("/groups/bad_id/deploy_tokens/#{group_deploy_token.id}", user)
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+
+ it 'returns not found with invalid token id' do
+ get api("/groups/#{group.id}/deploy_tokens/#{non_existing_record_id}", user)
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+ end
+ end
+
describe 'DELETE /projects/:id/deploy_tokens/:token_id' do
subject do
delete api("/projects/#{project.id}/deploy_tokens/#{deploy_token.id}", user)
@@ -232,10 +330,10 @@ RSpec.describe API::DeployTokens do
it 'returns bad_request with invalid token id' do
expect(::Projects::DeployTokens::DestroyService).to receive(:new)
- .with(project, user, token_id: 999)
+ .with(project, user, token_id: non_existing_record_id)
.and_raise(ActiveRecord::RecordNotFound)
- delete api("/projects/#{project.id}/deploy_tokens/999", user)
+ delete api("/projects/#{project.id}/deploy_tokens/#{non_existing_record_id}", user)
expect(response).to have_gitlab_http_status(:not_found)
end
@@ -395,10 +493,10 @@ RSpec.describe API::DeployTokens do
it 'returns not found with invalid deploy token id' do
expect(::Groups::DeployTokens::DestroyService).to receive(:new)
- .with(group, user, token_id: 999)
+ .with(group, user, token_id: non_existing_record_id)
.and_raise(ActiveRecord::RecordNotFound)
- delete api("/groups/#{group.id}/deploy_tokens/999", user)
+ delete api("/groups/#{group.id}/deploy_tokens/#{non_existing_record_id}", user)
expect(response).to have_gitlab_http_status(:not_found)
end
diff --git a/spec/requests/api/error_tracking/collector_spec.rb b/spec/requests/api/error_tracking/collector_spec.rb
index 573da862b57..fa0b238dcad 100644
--- a/spec/requests/api/error_tracking/collector_spec.rb
+++ b/spec/requests/api/error_tracking/collector_spec.rb
@@ -26,7 +26,6 @@ RSpec.describe API::ErrorTracking::Collector do
RSpec.shared_examples 'successful request' do
it 'writes to the database and returns OK', :aggregate_failures do
expect { subject }.to change { ErrorTracking::ErrorEvent.count }.by(1)
-
expect(response).to have_gitlab_http_status(:ok)
end
end
@@ -42,6 +41,14 @@ RSpec.describe API::ErrorTracking::Collector do
it_behaves_like 'successful request'
+ context 'intergrated error tracking feature flag is disabled' do
+ before do
+ stub_feature_flags(integrated_error_tracking: false)
+ end
+
+ it_behaves_like 'not found'
+ end
+
context 'error tracking feature is disabled' do
before do
setting.update!(enabled: false)
@@ -171,6 +178,12 @@ RSpec.describe API::ErrorTracking::Collector do
it_behaves_like 'successful request'
end
+ context 'when JSON key transaction is empty string' do
+ let_it_be(:raw_event) { fixture_file('error_tracking/php_empty_transaction.json') }
+
+ it_behaves_like 'successful request'
+ end
+
context 'sentry_key as param and empty headers' do
let(:url) { "/error_tracking/collector/api/#{project.id}/store?sentry_key=#{sentry_key}" }
let(:headers) { {} }
diff --git a/spec/requests/api/error_tracking/project_settings_spec.rb b/spec/requests/api/error_tracking/project_settings_spec.rb
index 161e4f01ea5..c0c0680ef31 100644
--- a/spec/requests/api/error_tracking/project_settings_spec.rb
+++ b/spec/requests/api/error_tracking/project_settings_spec.rb
@@ -23,6 +23,21 @@ RSpec.describe API::ErrorTracking::ProjectSettings do
end
end
+ shared_examples 'returns project settings with false for integrated' do
+ specify do
+ make_request
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response).to eq(
+ 'active' => setting.reload.enabled,
+ 'project_name' => setting.project_name,
+ 'sentry_external_url' => setting.sentry_external_url,
+ 'api_url' => setting.api_url,
+ 'integrated' => false
+ )
+ end
+ end
+
shared_examples 'returns 404' do
it 'returns no project settings' do
make_request
@@ -46,7 +61,17 @@ RSpec.describe API::ErrorTracking::ProjectSettings do
end
context 'patch settings' do
- it_behaves_like 'returns project settings'
+ context 'integrated_error_tracking feature enabled' do
+ it_behaves_like 'returns project settings'
+ end
+
+ context 'integrated_error_tracking feature disabled' do
+ before do
+ stub_feature_flags(integrated_error_tracking: false)
+ end
+
+ it_behaves_like 'returns project settings with false for integrated'
+ end
it 'updates enabled flag' do
expect(setting).to be_enabled
@@ -84,13 +109,19 @@ RSpec.describe API::ErrorTracking::ProjectSettings do
context 'with integrated param' do
let(:params) { { active: true, integrated: true } }
- it 'updates the integrated flag' do
- expect(setting.integrated).to be_falsey
+ context 'integrated_error_tracking feature enabled' do
+ before do
+ stub_feature_flags(integrated_error_tracking: true)
+ end
- make_request
+ it 'updates the integrated flag' do
+ expect(setting.integrated).to be_falsey
+
+ make_request
- expect(json_response).to include('integrated' => true)
- expect(setting.reload.integrated).to be_truthy
+ expect(json_response).to include('integrated' => true)
+ expect(setting.reload.integrated).to be_truthy
+ end
end
end
end
@@ -170,7 +201,21 @@ RSpec.describe API::ErrorTracking::ProjectSettings do
end
context 'get settings' do
- it_behaves_like 'returns project settings'
+ context 'integrated_error_tracking feature enabled' do
+ before do
+ stub_feature_flags(integrated_error_tracking: true)
+ end
+
+ it_behaves_like 'returns project settings'
+ end
+
+ context 'integrated_error_tracking feature disabled' do
+ before do
+ stub_feature_flags(integrated_error_tracking: false)
+ end
+
+ it_behaves_like 'returns project settings with false for integrated'
+ end
end
end
diff --git a/spec/requests/api/generic_packages_spec.rb b/spec/requests/api/generic_packages_spec.rb
index e1d8a9f0229..3a5c6103781 100644
--- a/spec/requests/api/generic_packages_spec.rb
+++ b/spec/requests/api/generic_packages_spec.rb
@@ -170,17 +170,6 @@ RSpec.describe API::GenericPackages do
end
end
- context 'generic_packages feature flag is disabled' do
- it 'responds with 404 Not Found' do
- stub_feature_flags(generic_packages: false)
- project.add_developer(user)
-
- authorize_upload_file(workhorse_headers.merge(personal_access_token_header))
-
- expect(response).to have_gitlab_http_status(:not_found)
- end
- end
-
def authorize_upload_file(request_headers, package_name: 'mypackage', file_name: 'myfile.tar.gz')
url = "/projects/#{project.id}/packages/generic/#{package_name}/0.0.1/#{file_name}/authorize"
diff --git a/spec/requests/api/graphql/ci/pipelines_spec.rb b/spec/requests/api/graphql/ci/pipelines_spec.rb
index 5ae68be46a2..741af676b6d 100644
--- a/spec/requests/api/graphql/ci/pipelines_spec.rb
+++ b/spec/requests/api/graphql/ci/pipelines_spec.rb
@@ -528,4 +528,37 @@ RSpec.describe 'Query.project(fullPath).pipelines' do
end.not_to exceed_query_limit(control_count)
end
end
+
+ describe 'filtering' do
+ let(:query) do
+ %(
+ query {
+ project(fullPath: "#{project.full_path}") {
+ pipelines(updatedAfter: "#{updated_after_arg}", updatedBefore: "#{updated_before_arg}") {
+ nodes {
+ id
+ }}}}
+ )
+ end
+
+ context 'when filtered by updated_at' do
+ let_it_be(:oldish_pipeline) { create(:ci_empty_pipeline, project: project, updated_at: 3.days.ago) }
+ let_it_be(:older_pipeline) { create(:ci_empty_pipeline, project: project, updated_at: 10.days.ago) }
+
+ let(:updated_after_arg) { 5.days.ago }
+ let(:updated_before_arg) { 1.day.ago }
+
+ before do
+ post_graphql(query, current_user: user)
+ end
+
+ it_behaves_like 'a working graphql query'
+
+ it 'accepts filter params' do
+ pipeline_ids = graphql_data.dig('project', 'pipelines', 'nodes').map { |pipeline| pipeline.fetch('id') }
+
+ expect(pipeline_ids).to match_array(oldish_pipeline.to_global_id.to_s)
+ end
+ end
+ end
end
diff --git a/spec/requests/api/graphql/ci/runner_spec.rb b/spec/requests/api/graphql/ci/runner_spec.rb
index fa16b9e1ddd..b99a3d14fb9 100644
--- a/spec/requests/api/graphql/ci/runner_spec.rb
+++ b/spec/requests/api/graphql/ci/runner_spec.rb
@@ -196,39 +196,6 @@ RSpec.describe 'Query.runner(id)' do
it_behaves_like 'runner details fetch', :inactive_instance_runner
end
- describe 'for runner inside group request' do
- let(:query) do
- %(
- query {
- group(fullPath: "#{group.full_path}") {
- runners {
- edges {
- webUrl
- node {
- id
- }
- }
- }
- }
- }
- )
- end
-
- it 'retrieves webUrl field with expected value' do
- post_graphql(query, current_user: user)
-
- runner_data = graphql_data_at(:group, :runners, :edges)
- expect(runner_data).to match_array [
- a_hash_including(
- 'webUrl' => "http://localhost/groups/#{group.full_path}/-/runners/#{active_group_runner.id}",
- 'node' => {
- 'id' => active_group_runner.to_global_id.to_s
- }
- )
- ]
- end
- end
-
describe 'for group runner request' do
let(:query) do
%(
diff --git a/spec/requests/api/graphql/ci/runner_web_url_edge_spec.rb b/spec/requests/api/graphql/ci/runner_web_url_edge_spec.rb
new file mode 100644
index 00000000000..767e958ea82
--- /dev/null
+++ b/spec/requests/api/graphql/ci/runner_web_url_edge_spec.rb
@@ -0,0 +1,57 @@
+# frozen_string_literal: true
+require 'spec_helper'
+
+RSpec.describe 'RunnerWebUrlEdge' do
+ include GraphqlHelpers
+
+ describe 'inside a Query.group' do
+ let_it_be(:group) { create(:group) }
+ let_it_be(:group_runner) { create(:ci_runner, :group, groups: [group]) }
+
+ let(:edges_graphql_data) { graphql_data.dig('group', 'runners', 'edges') }
+
+ let(:query) do
+ <<~GQL
+ query($path: ID!) {
+ group(fullPath: $path) {
+ runners {
+ edges {
+ editUrl
+ webUrl
+ }
+ }
+ }
+ }
+ GQL
+ end
+
+ before do
+ post_graphql(query, current_user: user, variables: { path: group.full_path })
+ end
+
+ context 'with an authorized user' do
+ let(:user) { create_default(:user, :admin) }
+
+ it_behaves_like 'a working graphql query'
+
+ it 'returns correct URLs' do
+ expect(edges_graphql_data).to match_array [
+ {
+ 'editUrl' => Gitlab::Routing.url_helpers.edit_group_runner_url(group, group_runner),
+ 'webUrl' => Gitlab::Routing.url_helpers.group_runner_url(group, group_runner)
+ }
+ ]
+ end
+ end
+
+ context 'with an unauthorized user' do
+ let(:user) { create(:user) }
+
+ it_behaves_like 'a working graphql query'
+
+ it 'returns no edges' do
+ expect(edges_graphql_data).to be_empty
+ end
+ end
+ end
+end
diff --git a/spec/requests/api/graphql/container_repository/container_repository_details_spec.rb b/spec/requests/api/graphql/container_repository/container_repository_details_spec.rb
index 35a70a180a2..922a9ab277e 100644
--- a/spec/requests/api/graphql/container_repository/container_repository_details_spec.rb
+++ b/spec/requests/api/graphql/container_repository/container_repository_details_spec.rb
@@ -3,17 +3,19 @@ require 'spec_helper'
RSpec.describe 'container repository details' do
include_context 'container registry tags'
+ include_context 'container registry client stubs'
+
using RSpec::Parameterized::TableSyntax
include GraphqlHelpers
let_it_be_with_reload(:project) { create(:project) }
- let_it_be(:container_repository) { create(:container_repository, project: project) }
+ let_it_be_with_reload(:container_repository) { create(:container_repository, project: project) }
let(:query) do
graphql_query_for(
'containerRepository',
{ id: container_repository_global_id },
- all_graphql_fields_for('ContainerRepositoryDetails', excluded: ['pipeline'])
+ all_graphql_fields_for('ContainerRepositoryDetails', excluded: %w[pipeline size])
)
end
@@ -220,6 +222,80 @@ RSpec.describe 'container repository details' do
end
end
+ context 'size field' do
+ let(:size_response) { container_repository_details_response.dig('size') }
+ let(:on_com) { true }
+ let(:created_at) { ::ContainerRepository::MIGRATION_PHASE_1_STARTED_AT + 3.months }
+ let(:variables) do
+ { id: container_repository_global_id }
+ end
+
+ let(:query) do
+ <<~GQL
+ query($id: ID!) {
+ containerRepository(id: $id) {
+ size
+ }
+ }
+ GQL
+ end
+
+ before do
+ allow(::Gitlab).to receive(:com?).and_return(on_com)
+ container_repository.update_column(:created_at, created_at)
+ end
+
+ it 'returns the size' do
+ stub_container_registry_gitlab_api_support(supported: true) do |client|
+ stub_container_registry_gitlab_api_repository_details(client, path: container_repository.path, size_bytes: 12345)
+ end
+
+ subject
+
+ expect(size_response).to eq(12345)
+ end
+
+ context 'with a network error' do
+ it 'returns an error' do
+ stub_container_registry_gitlab_api_network_error
+
+ subject
+
+ expect_graphql_errors_to_include("Can't connect to the Container Registry. If this error persists, please review the troubleshooting documentation.")
+ end
+ end
+
+ context 'with not supporting the gitlab api' do
+ it 'returns nil' do
+ stub_container_registry_gitlab_api_support(supported: false)
+
+ subject
+
+ expect(size_response).to eq(nil)
+ end
+ end
+
+ context 'not on .com' do
+ let(:on_com) { false }
+
+ it 'returns nil' do
+ subject
+
+ expect(size_response).to eq(nil)
+ end
+ end
+
+ context 'with an older container repository' do
+ let(:created_at) { ::ContainerRepository::MIGRATION_PHASE_1_STARTED_AT - 3.months }
+
+ it 'returns nil' do
+ subject
+
+ expect(size_response).to eq(nil)
+ end
+ end
+ end
+
context 'with tags with a manifest containing nil fields' do
let(:tags_response) { container_repository_details_response.dig('tags', 'nodes') }
let(:errors) { container_repository_details_response.dig('errors') }
diff --git a/spec/requests/api/graphql/group/group_members_spec.rb b/spec/requests/api/graphql/group/group_members_spec.rb
index 06afb5b9a49..78852622835 100644
--- a/spec/requests/api/graphql/group/group_members_spec.rb
+++ b/spec/requests/api/graphql/group/group_members_spec.rb
@@ -53,6 +53,30 @@ RSpec.describe 'getting group members information' do
end
end
+ context "when requesting member's notification email" do
+ context 'when current_user is admin' do
+ let_it_be(:admin_user) { create(:user, :admin) }
+
+ it 'returns notification email' do
+ fetch_members_notification_email(current_user: admin_user)
+ notification_emails = graphql_data_at(:group, :group_members, :edges, :node, :notification_email)
+
+ expect(notification_emails).to all be_present
+ expect(graphql_errors).to be_nil
+ end
+ end
+
+ context 'when current_user is not admin' do
+ it 'returns an error' do
+ fetch_members_notification_email
+
+ expect(graphql_errors.first)
+ .to include('path' => ['group', 'groupMembers', 'edges', 0, 'node', 'notificationEmail'],
+ 'message' => a_string_including("you don't have permission to perform this action"))
+ end
+ end
+ end
+
context 'member relations' do
let_it_be(:child_group) { create(:group, :public, parent: parent_group) }
let_it_be(:grandchild_group) { create(:group, :public, parent: child_group) }
@@ -117,6 +141,10 @@ RSpec.describe 'getting group members information' do
post_graphql(members_query(group.full_path, args), current_user: current_user)
end
+ def fetch_members_notification_email(group: parent_group, current_user: user)
+ post_graphql(member_notification_email_query(group.full_path), current_user: current_user)
+ end
+
def members_query(group_path, args = {})
members_node = <<~NODE
edges {
@@ -134,6 +162,24 @@ RSpec.describe 'getting group members information' do
)
end
+ def member_notification_email_query(group_path)
+ members_node = <<~NODE
+ edges {
+ node {
+ user {
+ id
+ }
+ notificationEmail
+ }
+ }
+ NODE
+
+ graphql_query_for("group",
+ { full_path: group_path },
+ [query_graphql_field("groupMembers", {}, members_node)]
+ )
+ end
+
def expect_array_response(*items)
expect(response).to have_gitlab_http_status(:success)
member_gids = graphql_data_at(:group, :group_members, :edges, :node, :user, :id)
diff --git a/spec/requests/api/graphql/group/issues_spec.rb b/spec/requests/api/graphql/group/issues_spec.rb
index 332bf242e9c..26338f46611 100644
--- a/spec/requests/api/graphql/group/issues_spec.rb
+++ b/spec/requests/api/graphql/group/issues_spec.rb
@@ -44,6 +44,31 @@ RSpec.describe 'getting an issue list for a group' do
end
end
+ context 'when there are archived projects' do
+ let_it_be(:archived_project) { create(:project, :archived, group: group1) }
+ let_it_be(:archived_issue) { create(:issue, project: archived_project) }
+
+ before_all do
+ group1.add_developer(current_user)
+ end
+
+ it 'excludes issues from archived projects by default' do
+ post_graphql(query, current_user: current_user)
+
+ expect(issues_ids).to contain_exactly(issue1_gid, issue2_gid)
+ end
+
+ context 'when include_archived is true' do
+ let(:issue_filter_params) { { include_archived: true } }
+
+ it 'includes issues from archived projects' do
+ post_graphql(query, current_user: current_user)
+
+ expect(issues_ids).to contain_exactly(issue1_gid, issue2_gid, archived_issue.to_global_id.to_s)
+ end
+ end
+ end
+
context 'when there is a confidential issue' do
let_it_be(:confidential_issue1) { create(:issue, :confidential, project: project1) }
let_it_be(:confidential_issue2) { create(:issue, :confidential, project: project2) }
diff --git a/spec/requests/api/graphql/group/merge_requests_spec.rb b/spec/requests/api/graphql/group/merge_requests_spec.rb
index e9a5e558b1d..c0faff11c8d 100644
--- a/spec/requests/api/graphql/group/merge_requests_spec.rb
+++ b/spec/requests/api/graphql/group/merge_requests_spec.rb
@@ -16,6 +16,9 @@ RSpec.describe 'Query.group.mergeRequests' do
let_it_be(:project_x) { create(:project, :repository) }
let_it_be(:user) { create(:user, developer_projects: [project_x]) }
+ let_it_be(:archived_project) { create(:project, :archived, :repository, group: group) }
+ let_it_be(:archived_mr) { create(:merge_request, source_project: archived_project) }
+
let_it_be(:mr_attrs) do
{ target_branch: 'master' }
end
@@ -119,4 +122,22 @@ RSpec.describe 'Query.group.mergeRequests' do
expect(mrs_data).to match_array(expected_mrs(mrs_a + mrs_b + mrs_c))
end
end
+
+ describe 'passing include_archived: true' do
+ let(:query) do
+ <<~GQL
+ query($path: ID!) {
+ group(fullPath: $path) {
+ mergeRequests(includeArchived: true) { nodes { id } }
+ }
+ }
+ GQL
+ end
+
+ it 'can find all merge requests in the group, including from archived projects' do
+ post_graphql(query, current_user: user, variables: { path: group.full_path })
+
+ expect(mrs_data).to match_array(expected_mrs(mrs_a + mrs_b + [archived_mr]))
+ end
+ end
end
diff --git a/spec/requests/api/graphql/group/work_item_types_spec.rb b/spec/requests/api/graphql/group/work_item_types_spec.rb
index 0667e09d1e9..a33e3ae5427 100644
--- a/spec/requests/api/graphql/group/work_item_types_spec.rb
+++ b/spec/requests/api/graphql/group/work_item_types_spec.rb
@@ -64,8 +64,8 @@ RSpec.describe 'getting a list of work item types for a group' do
post_graphql(query, current_user: current_user)
end
- it 'makes the workItemTypes field unavailable' do
- expect(graphql_errors).to contain_exactly(hash_including("message" => "Field 'workItemTypes' doesn't exist on type 'Group'"))
+ it 'returns null' do
+ expect(graphql_data.dig('group', 'workItemTypes')).to be_nil
end
end
end
diff --git a/spec/requests/api/graphql/mutations/issues/set_crm_contacts_spec.rb b/spec/requests/api/graphql/mutations/issues/set_crm_contacts_spec.rb
index 79d687a2bdb..02b79dac489 100644
--- a/spec/requests/api/graphql/mutations/issues/set_crm_contacts_spec.rb
+++ b/spec/requests/api/graphql/mutations/issues/set_crm_contacts_spec.rb
@@ -9,12 +9,10 @@ RSpec.describe 'Setting issues crm contacts' do
let_it_be(:group) { create(:group, :crm_enabled) }
let_it_be(:subgroup) { create(:group, :crm_enabled, parent: group) }
let_it_be(:project) { create(:project, group: subgroup) }
- let_it_be(:group_contacts) { create_list(:contact, 4, group: group) }
- let_it_be(:subgroup_contacts) { create_list(:contact, 4, group: subgroup) }
+ let_it_be(:contacts) { create_list(:contact, 4, group: group) }
let(:issue) { create(:issue, project: project) }
let(:operation_mode) { Types::MutationOperationModeEnum.default_mode }
- let(:contacts) { subgroup_contacts }
let(:initial_contacts) { contacts[0..1] }
let(:mutation_contacts) { contacts[1..2] }
let(:contact_ids) { contact_global_ids(mutation_contacts) }
@@ -116,15 +114,7 @@ RSpec.describe 'Setting issues crm contacts' do
end
end
- context 'with issue group contacts' do
- let(:contacts) { subgroup_contacts }
-
- it_behaves_like 'successful mutation'
- end
-
- context 'with issue ancestor group contacts' do
- it_behaves_like 'successful mutation'
- end
+ it_behaves_like 'successful mutation'
context 'when the contact does not exist' do
let(:contact_ids) { ["gid://gitlab/CustomerRelations::Contact/#{non_existing_record_id}"] }
diff --git a/spec/requests/api/graphql/mutations/notes/create/note_spec.rb b/spec/requests/api/graphql/mutations/notes/create/note_spec.rb
index 87c752393ea..2bc671e4ca5 100644
--- a/spec/requests/api/graphql/mutations/notes/create/note_spec.rb
+++ b/spec/requests/api/graphql/mutations/notes/create/note_spec.rb
@@ -8,13 +8,16 @@ RSpec.describe 'Adding a Note' do
let_it_be(:current_user) { create(:user) }
let(:noteable) { create(:merge_request, source_project: project, target_project: project) }
- let(:project) { create(:project) }
+ let(:project) { create(:project, :repository) }
let(:discussion) { nil }
+ let(:head_sha) { nil }
+ let(:body) { 'Body text' }
let(:mutation) do
variables = {
noteable_id: GitlabSchema.id_from_object(noteable).to_s,
discussion_id: (GitlabSchema.id_from_object(discussion).to_s if discussion),
- body: 'Body text',
+ merge_request_diff_head_sha: head_sha.presence,
+ body: body,
confidential: true
}
@@ -54,7 +57,7 @@ RSpec.describe 'Adding a Note' do
let(:discussion) { create(:discussion_note).to_discussion }
it_behaves_like 'a mutation that returns top-level errors',
- errors: ["The discussion does not exist or you don't have permission to perform this action"]
+ errors: ["The discussion does not exist or you don't have permission to perform this action"]
end
context 'when the user has permission to create notes on the discussion' do
@@ -75,5 +78,29 @@ RSpec.describe 'Adding a Note' do
end
end
end
+
+ context 'when body only contains quick actions' do
+ let(:head_sha) { noteable.diff_head_sha }
+ let(:body) { '/merge' }
+
+ before do
+ project.add_developer(current_user)
+ end
+
+ # NOTE: Known issue https://gitlab.com/gitlab-org/gitlab/-/issues/346557
+ it 'returns a nil note and info about the command in errors' do
+ post_graphql_mutation(mutation, current_user: current_user)
+
+ expect(mutation_response).to include(
+ 'errors' => [/Merged this merge request/],
+ 'note' => nil
+ )
+ end
+
+ it 'starts the merge process' do
+ expect { post_graphql_mutation(mutation, current_user: current_user) }
+ .to change { noteable.reload.merge_jid.present? }.from(false).to(true)
+ end
+ end
end
end
diff --git a/spec/requests/api/graphql/mutations/work_items/create_from_task_spec.rb b/spec/requests/api/graphql/mutations/work_items/create_from_task_spec.rb
new file mode 100644
index 00000000000..8d33f8e1806
--- /dev/null
+++ b/spec/requests/api/graphql/mutations/work_items/create_from_task_spec.rb
@@ -0,0 +1,87 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe "Create a work item from a task in a work item's description" do
+ include GraphqlHelpers
+
+ let_it_be(:project) { create(:project) }
+ let_it_be(:developer) { create(:user).tap { |user| project.add_developer(user) } }
+ let_it_be(:work_item, refind: true) { create(:work_item, project: project, description: '- [ ] A task in a list', lock_version: 3) }
+
+ let(:lock_version) { work_item.lock_version }
+ let(:input) do
+ {
+ 'id' => work_item.to_global_id.to_s,
+ 'workItemData' => {
+ 'title' => 'A task in a list',
+ 'workItemTypeId' => WorkItems::Type.default_by_type(:task).to_global_id.to_s,
+ 'lineNumberStart' => 1,
+ 'lineNumberEnd' => 1,
+ 'lockVersion' => lock_version
+ }
+ }
+ end
+
+ let(:mutation) { graphql_mutation(:workItemCreateFromTask, input) }
+ let(:mutation_response) { graphql_mutation_response(:work_item_create_from_task) }
+
+ context 'the user is not allowed to update a work item' do
+ let(:current_user) { create(:user) }
+
+ it_behaves_like 'a mutation that returns a top-level access error'
+ end
+
+ context 'when user has permissions to create a work item' do
+ let(:current_user) { developer }
+
+ it 'creates the work item' do
+ expect do
+ post_graphql_mutation(mutation, current_user: current_user)
+ end.to change(WorkItem, :count).by(1)
+
+ created_work_item = WorkItem.last
+ work_item.reload
+
+ expect(response).to have_gitlab_http_status(:success)
+ expect(work_item.description).to eq("- [ ] #{created_work_item.to_reference}+")
+ expect(created_work_item.issue_type).to eq('task')
+ expect(created_work_item.work_item_type.base_type).to eq('task')
+ expect(mutation_response['workItem']).to include('id' => work_item.to_global_id.to_s)
+ expect(mutation_response['newWorkItem']).to include('id' => created_work_item.to_global_id.to_s)
+ end
+
+ context 'when creating a work item fails' do
+ let(:lock_version) { 2 }
+
+ it 'makes no changes to the DB and returns an error message' do
+ expect do
+ post_graphql_mutation(mutation, current_user: current_user)
+ work_item.reload
+ end.to not_change(WorkItem, :count).and(
+ not_change(work_item, :description)
+ )
+
+ expect(mutation_response['errors']).to contain_exactly('Stale work item. Check lock version')
+ end
+ end
+
+ it_behaves_like 'has spam protection' do
+ let(:mutation_class) { ::Mutations::WorkItems::CreateFromTask }
+ end
+
+ context 'when the work_items feature flag is disabled' do
+ before do
+ stub_feature_flags(work_items: false)
+ end
+
+ it 'does nothing and returns and error' do
+ expect do
+ post_graphql_mutation(mutation, current_user: current_user)
+ end.to not_change(WorkItem, :count)
+
+ expect(mutation_response['errors']).to contain_exactly('`work_items` feature flag disabled for this project')
+ end
+ end
+ end
+end
diff --git a/spec/requests/api/graphql/namespace_query_spec.rb b/spec/requests/api/graphql/namespace_query_spec.rb
index f7ee2bcb55d..e17469901c6 100644
--- a/spec/requests/api/graphql/namespace_query_spec.rb
+++ b/spec/requests/api/graphql/namespace_query_spec.rb
@@ -31,7 +31,8 @@ RSpec.describe 'Query' do
it 'fetches the expected data' do
expect(query_result).to include(
'fullPath' => target_namespace.full_path,
- 'name' => target_namespace.name
+ 'name' => target_namespace.name,
+ 'crossProjectPipelineAvailable' => target_namespace.licensed_feature_available?(:cross_project_pipeline)
)
end
end
diff --git a/spec/requests/api/graphql/project/jira_service_spec.rb b/spec/requests/api/graphql/project/jira_service_spec.rb
index 64e9e04ae44..d6abe94b873 100644
--- a/spec/requests/api/graphql/project/jira_service_spec.rb
+++ b/spec/requests/api/graphql/project/jira_service_spec.rb
@@ -16,6 +16,7 @@ RSpec.describe 'query Jira service' do
services(active: true, type: JIRA_SERVICE) {
nodes {
type
+ serviceType
}
}
}
@@ -23,7 +24,7 @@ RSpec.describe 'query Jira service' do
)
end
- let(:services) { graphql_data.dig('project', 'services', 'nodes')}
+ let(:services) { graphql_data.dig('project', 'services', 'nodes') }
it_behaves_like 'unauthorized users cannot read services'
@@ -35,10 +36,8 @@ RSpec.describe 'query Jira service' do
it_behaves_like 'a working graphql query'
- it 'retuns list of jira imports' do
- service = services.first
-
- expect(service['type']).to eq('JiraService')
+ it 'returns list of jira integrations' do
+ expect(services).to contain_exactly({ 'type' => 'JiraService', 'serviceType' => 'JIRA_SERVICE' })
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 353bf0356f6..cefe88aafc8 100644
--- a/spec/requests/api/graphql/project/merge_request_spec.rb
+++ b/spec/requests/api/graphql/project/merge_request_spec.rb
@@ -76,6 +76,24 @@ RSpec.describe 'getting merge request information nested in a project' do
end
end
+ context 'when the merge_request has committers' do
+ let(:mr_fields) do
+ <<~SELECT
+ committers { nodes { id username } }
+ SELECT
+ end
+
+ it 'includes committers' do
+ expected = merge_request.committers.map do |r|
+ a_hash_including('id' => global_id_of(r), 'username' => r.username)
+ end
+
+ post_graphql(query, current_user: current_user)
+
+ expect(graphql_data_at(:project, :merge_request, :committers, :nodes)).to match_array(expected)
+ end
+ end
+
describe 'diffStats' do
let(:mr_fields) do
<<~FIELDS
diff --git a/spec/requests/api/graphql/project/work_item_types_spec.rb b/spec/requests/api/graphql/project/work_item_types_spec.rb
index 2caaedda2a1..157961c3f66 100644
--- a/spec/requests/api/graphql/project/work_item_types_spec.rb
+++ b/spec/requests/api/graphql/project/work_item_types_spec.rb
@@ -64,8 +64,8 @@ RSpec.describe 'getting a list of work item types for a project' do
post_graphql(query, current_user: current_user)
end
- it 'makes the workItemTypes field unavailable' do
- expect(graphql_errors).to contain_exactly(hash_including("message" => "Field 'workItemTypes' doesn't exist on type 'Project'"))
+ it 'returns null' do
+ expect(graphql_data.dig('project', 'workItemTypes')).to be_nil
end
end
end
diff --git a/spec/requests/api/graphql/query_spec.rb b/spec/requests/api/graphql/query_spec.rb
index ecc7fffaef7..d650acc8354 100644
--- a/spec/requests/api/graphql/query_spec.rb
+++ b/spec/requests/api/graphql/query_spec.rb
@@ -11,6 +11,30 @@ RSpec.describe 'Query' do
let(:current_user) { developer }
+ describe 'gitpodEnabled field' do
+ let(:gitpod_enabled) { true }
+ let(:gitpod_enabled_query) do
+ <<~GRAPHQL
+ { gitpodEnabled }
+ GRAPHQL
+ end
+
+ before do
+ allow(Gitlab::CurrentSettings.current_application_settings).to receive(:gitpod_enabled).and_return(gitpod_enabled)
+ post_graphql(gitpod_enabled_query)
+ end
+
+ context 'When Gitpod is enabled for the application' do
+ it { expect(graphql_data).to include('gitpodEnabled' => true) }
+ end
+
+ context 'When Gitpod is disabled for the application' do
+ let(:gitpod_enabled) { false }
+
+ it { expect(graphql_data).to include('gitpodEnabled' => false) }
+ end
+ end
+
describe '.designManagement' do
include DesignManagementTestHelpers
diff --git a/spec/requests/api/graphql/work_item_spec.rb b/spec/requests/api/graphql/work_item_spec.rb
new file mode 100644
index 00000000000..bc5a8b3e006
--- /dev/null
+++ b/spec/requests/api/graphql/work_item_spec.rb
@@ -0,0 +1,75 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'Query.work_item(id)' do
+ include GraphqlHelpers
+
+ let_it_be(:developer) { create(:user) }
+ let_it_be(:project) { create(:project, :private).tap { |project| project.add_developer(developer) } }
+ let_it_be(:work_item) { create(:work_item, project: project) }
+
+ let(:current_user) { developer }
+ let(:work_item_data) { graphql_data['workItem'] }
+ let(:work_item_fields) { all_graphql_fields_for('WorkItem') }
+ let(:global_id) { work_item.to_gid.to_s }
+
+ let(:query) do
+ graphql_query_for('workItem', { 'id' => global_id }, work_item_fields)
+ end
+
+ context 'when the user can read the work item' do
+ before do
+ post_graphql(query, current_user: current_user)
+ end
+
+ it_behaves_like 'a working graphql query'
+
+ it 'returns all fields' do
+ expect(work_item_data).to include(
+ 'description' => work_item.description,
+ 'id' => work_item.to_gid.to_s,
+ 'iid' => work_item.iid.to_s,
+ 'lockVersion' => work_item.lock_version,
+ 'state' => "OPEN",
+ 'title' => work_item.title,
+ 'workItemType' => hash_including('id' => work_item.work_item_type.to_gid.to_s)
+ )
+ end
+
+ context 'when an Issue Global ID is provided' do
+ let(:global_id) { Issue.find(work_item.id).to_gid.to_s }
+
+ it 'allows an Issue GID as input' do
+ expect(work_item_data).to include('id' => work_item.to_gid.to_s)
+ end
+ end
+ end
+
+ context 'when the user can not read the work item' do
+ let(:current_user) { create(:user) }
+
+ before do
+ post_graphql(query)
+ end
+
+ it 'returns an access error' do
+ expect(work_item_data).to be_nil
+ expect(graphql_errors).to contain_exactly(
+ hash_including('message' => ::Gitlab::Graphql::Authorize::AuthorizeResource::RESOURCE_ACCESS_ERROR)
+ )
+ end
+ end
+
+ context 'when the work_items feature flag is disabled' do
+ before do
+ stub_feature_flags(work_items: false)
+ end
+
+ it 'returns nil' do
+ post_graphql(query)
+
+ expect(work_item_data).to be_nil
+ end
+ end
+end
diff --git a/spec/requests/api/group_clusters_spec.rb b/spec/requests/api/group_clusters_spec.rb
index c48b5007f91..8e127bf0710 100644
--- a/spec/requests/api/group_clusters_spec.rb
+++ b/spec/requests/api/group_clusters_spec.rb
@@ -22,6 +22,10 @@ RSpec.describe API::GroupClusters do
groups: [group])
end
+ include_examples ':certificate_based_clusters feature flag API responses' do
+ let(:subject) { get api("/groups/#{group.id}/clusters", current_user) }
+ end
+
context 'non-authorized user' do
it 'responds with 403' do
get api("/groups/#{group.id}/clusters", unauthorized_user)
@@ -66,6 +70,10 @@ RSpec.describe API::GroupClusters do
groups: [group])
end
+ include_examples ':certificate_based_clusters feature flag API responses' do
+ let(:subject) { get api("/groups/#{group.id}/clusters/#{cluster_id}", current_user) }
+ end
+
context 'non-authorized user' do
it 'responds with 403' do
get api("/groups/#{group.id}/clusters/#{cluster_id}", unauthorized_user)
@@ -181,6 +189,10 @@ RSpec.describe API::GroupClusters do
}
end
+ include_examples ':certificate_based_clusters feature flag API responses' do
+ let(:subject) { post api("/groups/#{group.id}/clusters/user", current_user), params: cluster_params }
+ end
+
context 'non-authorized user' do
it 'responds with 403' do
post api("/groups/#{group.id}/clusters/user", unauthorized_user), params: cluster_params
@@ -362,6 +374,10 @@ RSpec.describe API::GroupClusters do
groups: [group], domain: 'old-domain.com')
end
+ include_examples ':certificate_based_clusters feature flag API responses' do
+ let(:subject) { put api("/groups/#{group.id}/clusters/#{cluster.id}", current_user), params: update_params }
+ end
+
context 'non-authorized user' do
it 'responds with 403' do
put api("/groups/#{group.id}/clusters/#{cluster.id}", unauthorized_user), params: update_params
@@ -503,6 +519,10 @@ RSpec.describe API::GroupClusters do
groups: [group])
end
+ include_examples ':certificate_based_clusters feature flag API responses' do
+ let(:subject) { delete api("/groups/#{group.id}/clusters/#{cluster.id}", current_user), params: cluster_params }
+ end
+
context 'non-authorized user' do
it 'responds with 403' do
delete api("/groups/#{group.id}/clusters/#{cluster.id}", unauthorized_user), params: cluster_params
diff --git a/spec/requests/api/group_labels_spec.rb b/spec/requests/api/group_labels_spec.rb
index 11738e3cba8..34533da53dd 100644
--- a/spec/requests/api/group_labels_spec.rb
+++ b/spec/requests/api/group_labels_spec.rb
@@ -140,7 +140,7 @@ RSpec.describe API::GroupLabels do
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['name']).to eq(group_label1.name)
- expect(json_response['color']).to eq(group_label1.color)
+ expect(json_response['color']).to be_color(group_label1.color)
expect(json_response['description']).to eq(group_label1.description)
end
end
@@ -156,7 +156,7 @@ RSpec.describe API::GroupLabels do
expect(response).to have_gitlab_http_status(:created)
expect(json_response['name']).to eq(valid_new_label_title)
- expect(json_response['color']).to eq('#FFAABB')
+ expect(json_response['color']).to be_color('#FFAABB')
expect(json_response['description']).to eq('test')
end
@@ -169,7 +169,7 @@ RSpec.describe API::GroupLabels do
expect(response).to have_gitlab_http_status(:created)
expect(json_response['name']).to eq(valid_new_label_title)
- expect(json_response['color']).to eq('#FFAABB')
+ expect(json_response['color']).to be_color('#FFAABB')
expect(json_response['description']).to be_nil
end
@@ -276,7 +276,7 @@ RSpec.describe API::GroupLabels do
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['name']).to eq(valid_new_label_title)
- expect(json_response['color']).to eq('#FFFFFF')
+ expect(json_response['color']).to be_color('#FFFFFF')
expect(json_response['description']).to eq('test')
end
@@ -332,7 +332,7 @@ RSpec.describe API::GroupLabels do
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['name']).to eq(valid_new_label_title)
- expect(json_response['color']).to eq('#FFFFFF')
+ expect(json_response['color']).to be_color('#FFFFFF')
expect(json_response['description']).to eq('test')
end
diff --git a/spec/requests/api/integrations_spec.rb b/spec/requests/api/integrations_spec.rb
index 033c80a5696..220c58afbe9 100644
--- a/spec/requests/api/integrations_spec.rb
+++ b/spec/requests/api/integrations_spec.rb
@@ -10,6 +10,14 @@ RSpec.describe API::Integrations do
create(:project, creator_id: user.id, namespace: user.namespace)
end
+ # The API supports all integrations except the GitLab Slack Application
+ # integration; this integration must be installed via the UI.
+ def self.integration_names
+ names = Integration.available_integration_names
+ names.delete(Integrations::GitlabSlackApplication.to_param) if Gitlab.ee?
+ names
+ end
+
%w[integrations services].each do |endpoint|
describe "GET /projects/:id/#{endpoint}" do
it 'returns authentication error when unauthenticated' do
@@ -43,7 +51,7 @@ RSpec.describe API::Integrations do
end
end
- Integration.available_integration_names.each do |integration|
+ integration_names.each do |integration|
describe "PUT /projects/:id/#{endpoint}/#{integration.dasherize}" do
include_context integration
diff --git a/spec/requests/api/internal/kubernetes_spec.rb b/spec/requests/api/internal/kubernetes_spec.rb
index 59d185fe6c8..0e566dd8c0e 100644
--- a/spec/requests/api/internal/kubernetes_spec.rb
+++ b/spec/requests/api/internal/kubernetes_spec.rb
@@ -169,6 +169,7 @@ RSpec.describe API::Internal::Kubernetes do
'features' => {}
),
'gitaly_repository' => a_hash_including(
+ 'default_branch' => project.default_branch_or_main,
'storage_name' => project.repository_storage,
'relative_path' => project.disk_path + '.git',
'gl_repository' => "project-#{project.id}",
diff --git a/spec/requests/api/internal/mail_room_spec.rb b/spec/requests/api/internal/mail_room_spec.rb
index f3ca3708c0c..67ea617f90d 100644
--- a/spec/requests/api/internal/mail_room_spec.rb
+++ b/spec/requests/api/internal/mail_room_spec.rb
@@ -28,7 +28,7 @@ RSpec.describe API::Internal::MailRoom do
}
end
- let(:auth_payload) { { 'iss' => Gitlab::MailRoom::Authenticator::INTERNAL_API_REQUEST_JWT_ISSUER, 'iat' => (Time.now - 10.seconds).to_i } }
+ let(:auth_payload) { { 'iss' => Gitlab::MailRoom::INTERNAL_API_REQUEST_JWT_ISSUER, 'iat' => (Time.now - 10.seconds).to_i } }
let(:incoming_email_secret) { 'incoming_email_secret' }
let(:service_desk_email_secret) { 'service_desk_email_secret' }
@@ -51,7 +51,7 @@ RSpec.describe API::Internal::MailRoom do
context 'handle incoming_email successfully' do
let(:auth_headers) do
jwt_token = JWT.encode(auth_payload, incoming_email_secret, 'HS256')
- { Gitlab::MailRoom::Authenticator::INTERNAL_API_REQUEST_HEADER => jwt_token }
+ { Gitlab::MailRoom::INTERNAL_API_REQUEST_HEADER => jwt_token }
end
it 'schedules a EmailReceiverWorker job with raw email content' do
@@ -71,7 +71,7 @@ RSpec.describe API::Internal::MailRoom do
context 'handle service_desk_email successfully' do
let(:auth_headers) do
jwt_token = JWT.encode(auth_payload, service_desk_email_secret, 'HS256')
- { Gitlab::MailRoom::Authenticator::INTERNAL_API_REQUEST_HEADER => jwt_token }
+ { Gitlab::MailRoom::INTERNAL_API_REQUEST_HEADER => jwt_token }
end
it 'schedules a ServiceDeskEmailReceiverWorker job with raw email content' do
@@ -91,7 +91,7 @@ RSpec.describe API::Internal::MailRoom do
context 'email content exceeds limit' do
let(:auth_headers) do
jwt_token = JWT.encode(auth_payload, incoming_email_secret, 'HS256')
- { Gitlab::MailRoom::Authenticator::INTERNAL_API_REQUEST_HEADER => jwt_token }
+ { Gitlab::MailRoom::INTERNAL_API_REQUEST_HEADER => jwt_token }
end
before do
@@ -134,7 +134,7 @@ RSpec.describe API::Internal::MailRoom do
context 'wrong token authentication' do
let(:auth_headers) do
jwt_token = JWT.encode(auth_payload, 'wrongsecret', 'HS256')
- { Gitlab::MailRoom::Authenticator::INTERNAL_API_REQUEST_HEADER => jwt_token }
+ { Gitlab::MailRoom::INTERNAL_API_REQUEST_HEADER => jwt_token }
end
it 'responds with 401 Unauthorized' do
@@ -147,7 +147,7 @@ RSpec.describe API::Internal::MailRoom do
context 'wrong mailbox type authentication' do
let(:auth_headers) do
jwt_token = JWT.encode(auth_payload, service_desk_email_secret, 'HS256')
- { Gitlab::MailRoom::Authenticator::INTERNAL_API_REQUEST_HEADER => jwt_token }
+ { Gitlab::MailRoom::INTERNAL_API_REQUEST_HEADER => jwt_token }
end
it 'responds with 401 Unauthorized' do
@@ -160,7 +160,7 @@ RSpec.describe API::Internal::MailRoom do
context 'not supported mailbox type' do
let(:auth_headers) do
jwt_token = JWT.encode(auth_payload, incoming_email_secret, 'HS256')
- { Gitlab::MailRoom::Authenticator::INTERNAL_API_REQUEST_HEADER => jwt_token }
+ { Gitlab::MailRoom::INTERNAL_API_REQUEST_HEADER => jwt_token }
end
it 'responds with 401 Unauthorized' do
@@ -181,7 +181,7 @@ RSpec.describe API::Internal::MailRoom do
let(:auth_headers) do
jwt_token = JWT.encode(auth_payload, service_desk_email_secret, 'HS256')
- { Gitlab::MailRoom::Authenticator::INTERNAL_API_REQUEST_HEADER => jwt_token }
+ { Gitlab::MailRoom::INTERNAL_API_REQUEST_HEADER => jwt_token }
end
it 'responds with 401 Unauthorized' do
diff --git a/spec/requests/api/invitations_spec.rb b/spec/requests/api/invitations_spec.rb
index 702e6ef0a2a..741cf793a77 100644
--- a/spec/requests/api/invitations_spec.rb
+++ b/spec/requests/api/invitations_spec.rb
@@ -10,7 +10,7 @@ RSpec.describe API::Invitations do
let(:email) { 'email1@example.com' }
let(:email2) { 'email2@example.com' }
- let_it_be(:project) do
+ let_it_be(:project, reload: true) do
create(:project, :public, creator_id: maintainer.id, namespace: maintainer.namespace) do |project|
project.add_developer(developer)
project.add_maintainer(maintainer)
@@ -208,6 +208,25 @@ RSpec.describe API::Invitations do
end
end
+ context 'when adding project bot' do
+ let_it_be(:project_bot) { create(:user, :project_bot) }
+
+ before do
+ unrelated_project = create(:project)
+ unrelated_project.add_maintainer(project_bot)
+ end
+
+ it 'returns error' do
+ expect do
+ post invitations_url(source, maintainer),
+ params: { email: project_bot.email, access_level: Member::DEVELOPER }
+
+ expect(json_response['status']).to eq 'error'
+ expect(json_response['message'][project_bot.email]).to include('User project bots cannot be added to other groups / projects')
+ end.not_to change { source.members.count }
+ end
+ end
+
it "returns a message if member already exists" do
post invitations_url(source, maintainer),
params: { email: developer.email, access_level: Member::MAINTAINER }
diff --git a/spec/requests/api/issues/post_projects_issues_spec.rb b/spec/requests/api/issues/post_projects_issues_spec.rb
index 82692366589..7c8994ad9ba 100644
--- a/spec/requests/api/issues/post_projects_issues_spec.rb
+++ b/spec/requests/api/issues/post_projects_issues_spec.rb
@@ -447,7 +447,7 @@ RSpec.describe API::Issues do
post_issue
expect(response).to have_gitlab_http_status(:bad_request)
- expect(json_response['message']).to eq({ 'error' => 'Spam detected' })
+ expect(json_response['message']['base']).to match_array([/issue has been recognized as spam/])
end
it 'creates a new spam log entry' do
diff --git a/spec/requests/api/issues/put_projects_issues_spec.rb b/spec/requests/api/issues/put_projects_issues_spec.rb
index dac721cbea0..6ea77cc6578 100644
--- a/spec/requests/api/issues/put_projects_issues_spec.rb
+++ b/spec/requests/api/issues/put_projects_issues_spec.rb
@@ -199,8 +199,8 @@ RSpec.describe API::Issues do
expect(spam_service).to receive_messages(check_for_spam?: true)
end
- expect_next_instance_of(Spam::SpamVerdictService) do |verdict_service|
- expect(verdict_service).to receive(:execute).and_return(DISALLOW)
+ allow_next_instance_of(Spam::AkismetService) do |akismet_service|
+ allow(akismet_service).to receive(:spam?).and_return(true)
end
end
@@ -217,7 +217,7 @@ RSpec.describe API::Issues do
update_issue
expect(response).to have_gitlab_http_status(:bad_request)
- expect(json_response).to include('message' => { 'error' => 'Spam detected' })
+ expect(json_response['message']['base']).to match_array([/issue has been recognized as spam/])
end
it 'creates a new spam log entry' do
@@ -323,44 +323,44 @@ RSpec.describe API::Issues do
end
it 'removes all labels and touches the record' do
- Timecop.travel(1.minute.from_now) do
+ travel_to(2.minutes.from_now) do
put api_for_user, params: { labels: '' }
end
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['labels']).to eq([])
- expect(json_response['updated_at']).to be > Time.now
+ expect(json_response['updated_at']).to be > Time.current
end
it 'removes all labels and touches the record with labels param as array' do
- Timecop.travel(1.minute.from_now) do
+ travel_to(2.minutes.from_now) do
put api_for_user, params: { labels: [''] }
end
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['labels']).to eq([])
- expect(json_response['updated_at']).to be > Time.now
+ expect(json_response['updated_at']).to be > Time.current
end
it 'updates labels and touches the record' do
- Timecop.travel(1.minute.from_now) do
+ travel_to(2.minutes.from_now) do
put api_for_user, params: { labels: 'foo,bar' }
end
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['labels']).to contain_exactly('foo', 'bar')
- expect(json_response['updated_at']).to be > Time.now
+ expect(json_response['updated_at']).to be > Time.current
end
it 'updates labels and touches the record with labels param as array' do
- Timecop.travel(1.minute.from_now) do
+ travel_to(2.minutes.from_now) do
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'
- expect(json_response['updated_at']).to be > Time.now
+ expect(json_response['updated_at']).to be > Time.current
end
it 'allows special label names' do
diff --git a/spec/requests/api/labels_spec.rb b/spec/requests/api/labels_spec.rb
index db9d72245b3..48f2c45bd98 100644
--- a/spec/requests/api/labels_spec.rb
+++ b/spec/requests/api/labels_spec.rb
@@ -34,7 +34,7 @@ RSpec.describe API::Labels do
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['name']).to eq(valid_label_title_2)
- expect(json_response['color']).to eq(label1.color)
+ expect(json_response['color']).to be_color(label1.color)
end
it "returns 200 if colors is changed (#{route_type} route)" do
@@ -42,7 +42,7 @@ RSpec.describe API::Labels do
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['name']).to eq(label1.name)
- expect(json_response['color']).to eq('#FFFFFF')
+ expect(json_response['color']).to be_color('#FFFFFF')
end
it "returns 200 if a priority is added (#{route_type} route)" do
@@ -86,7 +86,7 @@ RSpec.describe API::Labels do
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['name']).to eq(valid_label_title_2)
- expect(json_response['color']).to eq('#FFFFFF')
+ expect(json_response['color']).to be_color('#FFFFFF')
expect(json_response['description']).to eq('test')
end
@@ -266,8 +266,8 @@ RSpec.describe API::Labels do
'open_merge_requests_count' => 0,
'name' => group_label.name,
'description' => nil,
- 'color' => a_string_matching(/^#\h{6}$/),
- 'text_color' => a_string_matching(/^#\h{6}$/),
+ 'color' => a_valid_color,
+ 'text_color' => a_valid_color,
'priority' => nil,
'subscribed' => false,
'is_project_label' => false)
@@ -277,8 +277,8 @@ RSpec.describe API::Labels do
'open_merge_requests_count' => 1,
'name' => priority_label.name,
'description' => nil,
- 'color' => a_string_matching(/^#\h{6}$/),
- 'text_color' => a_string_matching(/^#\h{6}$/),
+ 'color' => a_valid_color,
+ 'text_color' => a_valid_color,
'priority' => 3,
'subscribed' => false,
'is_project_label' => true)
@@ -336,7 +336,7 @@ RSpec.describe API::Labels do
expect(response).to have_gitlab_http_status(:created)
expect(json_response['name']).to eq(valid_label_title_2)
- expect(json_response['color']).to eq('#FFAABB')
+ expect(json_response['color']).to be_color('#FFAABB')
expect(json_response['description']).to eq('test')
expect(json_response['priority']).to eq(2)
end
@@ -350,7 +350,7 @@ RSpec.describe API::Labels do
expect(response).to have_gitlab_http_status(:created)
expect(json_response['name']).to eq(valid_label_title_2)
- expect(json_response['color']).to eq('#FFAABB')
+ expect(json_response['color']).to be_color('#FFAABB')
expect(json_response['description']).to be_nil
expect(json_response['priority']).to be_nil
end
@@ -365,7 +365,7 @@ RSpec.describe API::Labels do
expect(response).to have_gitlab_http_status(:created)
expect(json_response['name']).to eq(valid_label_title_2)
- expect(json_response['color']).to eq('#FFAABB')
+ expect(json_response['color']).to be_color('#FFAABB')
expect(json_response['description']).to be_nil
expect(json_response['priority']).to eq(3)
end
@@ -552,7 +552,7 @@ RSpec.describe API::Labels do
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['name']).to eq(label1.name)
- expect(json_response['color']).to eq(label1.color)
+ expect(json_response['color']).to be_color(label1.color.to_s)
end
context 'if group label already exists' do
diff --git a/spec/requests/api/members_spec.rb b/spec/requests/api/members_spec.rb
index 6186a43f992..561d81f9860 100644
--- a/spec/requests/api/members_spec.rb
+++ b/spec/requests/api/members_spec.rb
@@ -675,13 +675,13 @@ RSpec.describe API::Members do
end
context 'adding owner to project' do
- it 'returns 403' do
+ it 'returns created status' do
expect do
post api("/projects/#{project.id}/members", maintainer),
params: { user_id: stranger.id, access_level: Member::OWNER }
- expect(response).to have_gitlab_http_status(:bad_request)
- end.not_to change { project.members.count }
+ expect(response).to have_gitlab_http_status(:created)
+ end.to change { project.members.count }.by(1)
end
end
diff --git a/spec/requests/api/notes_spec.rb b/spec/requests/api/notes_spec.rb
index 3c28aed6cac..455400072bf 100644
--- a/spec/requests/api/notes_spec.rb
+++ b/spec/requests/api/notes_spec.rb
@@ -228,44 +228,83 @@ RSpec.describe API::Notes do
end
let(:request_body) { 'Hi!' }
+ let(:params) { { body: request_body } }
let(:request_path) { "/projects/#{project.id}/merge_requests/#{merge_request.iid}/notes" }
- subject { post api(request_path, user), params: { body: request_body } }
+ subject { post api(request_path, user), params: params }
context 'a command only note' do
- let(:request_body) { "/spend 1h" }
+ context '/spend' do
+ let(:request_body) { "/spend 1h" }
- before do
- project.add_developer(user)
- end
+ before do
+ project.add_developer(user)
+ end
- it 'returns 202 Accepted status' do
- subject
+ it 'returns 202 Accepted status' do
+ subject
- expect(response).to have_gitlab_http_status(:accepted)
- end
+ expect(response).to have_gitlab_http_status(:accepted)
+ end
- it 'does not actually create a new note' do
- expect { subject }.not_to change { Note.where(system: false).count }
- end
+ it 'does not actually create a new note' do
+ expect { subject }.not_to change { Note.where(system: false).count }
+ end
- it 'does however create a system note about the change', :sidekiq_inline do
- expect { subject }.to change { Note.system.count }.by(1)
- end
+ it 'does however create a system note about the change', :sidekiq_inline do
+ expect { subject }.to change { Note.system.count }.by(1)
+ end
+
+ it 'applies the commands' do
+ expect { subject }.to change { merge_request.reset.total_time_spent }
+ end
+
+ it 'reports the changes' do
+ subject
- it 'applies the commands' do
- expect { subject }.to change { merge_request.reset.total_time_spent }
+ expect(json_response).to include(
+ 'commands_changes' => include(
+ 'spend_time' => include('duration' => 3600)
+ ),
+ 'summary' => include('Added 1h spent time.')
+ )
+ end
end
- it 'reports the changes' do
- subject
+ context '/merge' do
+ let(:request_body) { "/merge" }
+ let(:project) { create(:project, :public, :repository) }
+ let(:merge_request) { create(:merge_request_with_multiple_diffs, source_project: project, target_project: project, author: user) }
+ let(:params) { { body: request_body, merge_request_diff_head_sha: merge_request.diff_head_sha } }
+
+ before do
+ project.add_developer(user)
+ end
+
+ it 'returns 202 Accepted status' do
+ subject
+
+ expect(response).to have_gitlab_http_status(:accepted)
+ end
+
+ it 'does not actually create a new note' do
+ expect { subject }.not_to change { Note.where(system: false).count }
+ end
+
+ it 'applies the commands' do
+ expect { subject }.to change { merge_request.reload.merge_jid.present? }.from(false).to(true)
+ end
- expect(json_response).to include(
- 'commands_changes' => include(
- 'spend_time' => include('duration' => 3600)
- ),
- 'summary' => include('Added 1h spent time.')
- )
+ it 'reports the changes' do
+ subject
+
+ expect(json_response).to include(
+ 'commands_changes' => include(
+ 'merge' => merge_request.diff_head_sha
+ ),
+ 'summary' => ['Merged this merge request.']
+ )
+ end
end
end
diff --git a/spec/requests/api/project_attributes.yml b/spec/requests/api/project_attributes.yml
index 8a6e87944ec..02d377efd95 100644
--- a/spec/requests/api/project_attributes.yml
+++ b/spec/requests/api/project_attributes.yml
@@ -9,6 +9,7 @@ itself: # project
- external_webhook_token
- has_external_issue_tracker
- has_external_wiki
+ - hidden
- import_source
- import_type
- import_url
@@ -121,7 +122,6 @@ project_feature:
- created_at
- metrics_dashboard_access_level
- project_id
- - security_and_compliance_access_level
- updated_at
computed_attributes:
- issues_enabled
diff --git a/spec/requests/api/project_clusters_spec.rb b/spec/requests/api/project_clusters_spec.rb
index b83b41a881a..4c7da78f0d4 100644
--- a/spec/requests/api/project_clusters_spec.rb
+++ b/spec/requests/api/project_clusters_spec.rb
@@ -24,6 +24,10 @@ RSpec.describe API::ProjectClusters do
projects: [project])
end
+ include_examples ':certificate_based_clusters feature flag API responses' do
+ let(:subject) { get api("/projects/#{project.id}/clusters", developer_user) }
+ end
+
context 'non-authorized user' do
it 'responds with 403' do
get api("/projects/#{project.id}/clusters", reporter_user)
@@ -67,6 +71,10 @@ RSpec.describe API::ProjectClusters do
projects: [project])
end
+ include_examples ':certificate_based_clusters feature flag API responses' do
+ let(:subject) { get api("/projects/#{project.id}/clusters/#{cluster_id}", developer_user) }
+ end
+
context 'non-authorized user' do
it 'responds with 403' do
get api("/projects/#{project.id}/clusters/#{cluster_id}", reporter_user)
@@ -182,6 +190,10 @@ RSpec.describe API::ProjectClusters do
}
end
+ include_examples ':certificate_based_clusters feature flag API responses' do
+ let(:subject) { post api("/projects/#{project.id}/clusters/user", maintainer_user), params: cluster_params }
+ end
+
context 'non-authorized user' do
it 'responds with 403' do
post api("/projects/#{project.id}/clusters/user", developer_user), params: cluster_params
@@ -361,6 +373,10 @@ RSpec.describe API::ProjectClusters do
projects: [project])
end
+ include_examples ':certificate_based_clusters feature flag API responses' do
+ let(:subject) { put api("/projects/#{project.id}/clusters/#{cluster.id}", maintainer_user), params: update_params }
+ end
+
context 'non-authorized user' do
it 'responds with 403' do
put api("/projects/#{project.id}/clusters/#{cluster.id}", developer_user), params: update_params
@@ -493,6 +509,10 @@ RSpec.describe API::ProjectClusters do
projects: [project])
end
+ include_examples ':certificate_based_clusters feature flag API responses' do
+ let(:subject) { delete api("/projects/#{project.id}/clusters/#{cluster.id}", maintainer_user), params: cluster_params }
+ end
+
context 'non-authorized user' do
it 'responds with 403' do
delete api("/projects/#{project.id}/clusters/#{cluster.id}", developer_user), params: cluster_params
diff --git a/spec/requests/api/project_import_spec.rb b/spec/requests/api/project_import_spec.rb
index 3ed08afd57d..a0f6d3d0081 100644
--- a/spec/requests/api/project_import_spec.rb
+++ b/spec/requests/api/project_import_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe API::ProjectImport do
+RSpec.describe API::ProjectImport, :aggregate_failures do
include WorkhorseHelpers
include AfterNextHelpers
@@ -47,7 +47,7 @@ RSpec.describe API::ProjectImport do
it 'executes a limited number of queries' do
control_count = ActiveRecord::QueryRecorder.new { subject }.count
- expect(control_count).to be <= 104
+ expect(control_count).to be <= 105
end
it 'schedules an import using a namespace' do
@@ -329,7 +329,7 @@ RSpec.describe API::ProjectImport do
)
service_response = ServiceResponse.success(payload: project)
- expect_next(::Import::GitlabProjects::CreateProjectFromRemoteFileService)
+ expect_next(::Import::GitlabProjects::CreateProjectService)
.to receive(:execute)
.and_return(service_response)
@@ -352,7 +352,86 @@ RSpec.describe API::ProjectImport do
message: 'Failed to import',
http_status: :bad_request
)
- expect_next(::Import::GitlabProjects::CreateProjectFromRemoteFileService)
+ expect_next(::Import::GitlabProjects::CreateProjectService)
+ .to receive(:execute)
+ .and_return(service_response)
+
+ subject
+
+ expect(response).to have_gitlab_http_status(:bad_request)
+ expect(json_response).to eq({
+ 'message' => 'Failed to import'
+ })
+ end
+ end
+ end
+ end
+
+ describe 'POST /projects/remote-import-s3' do
+ subject do
+ post api('/projects/remote-import-s3', user), params: params
+ end
+
+ let(:params) do
+ {
+ path: 'test-import',
+ region: 'region_name',
+ bucket_name: 'bucket_name',
+ file_key: 'file_key',
+ access_key_id: 'access_key_id',
+ secret_access_key: 'secret_access_key'
+ }
+ end
+
+ it_behaves_like 'requires authentication'
+
+ it 'returns NOT FOUND when the feature is disabled' do
+ stub_feature_flags(import_project_from_remote_file_s3: false)
+
+ subject
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+
+ context 'when the feature flag is enabled' do
+ before do
+ stub_feature_flags(import_project_from_remote_file_s3: true)
+ end
+
+ context 'when the response is successful' do
+ it 'schedules the import successfully' do
+ project = create(
+ :project,
+ namespace: user.namespace,
+ name: 'test-import',
+ path: 'test-import'
+ )
+
+ service_response = ServiceResponse.success(payload: project)
+ expect_next(::Import::GitlabProjects::CreateProjectService)
+ .to receive(:execute)
+ .and_return(service_response)
+
+ subject
+
+ expect(response).to have_gitlab_http_status(:created)
+ expect(json_response).to include({
+ 'id' => project.id,
+ 'name' => 'test-import',
+ 'name_with_namespace' => "#{user.namespace.name} / test-import",
+ 'path' => 'test-import',
+ 'path_with_namespace' => "#{user.namespace.path}/test-import"
+ })
+ end
+ end
+
+ context 'when the service returns an error' do
+ it 'fails to schedule the import' do
+ service_response = ServiceResponse.error(
+ message: 'Failed to import',
+ http_status: :bad_request
+ )
+ expect_next(::Import::GitlabProjects::CreateProjectService)
.to receive(:execute)
.and_return(service_response)
diff --git a/spec/requests/api/project_snippets_spec.rb b/spec/requests/api/project_snippets_spec.rb
index 512cbf7c321..72519ed1683 100644
--- a/spec/requests/api/project_snippets_spec.rb
+++ b/spec/requests/api/project_snippets_spec.rb
@@ -276,7 +276,7 @@ RSpec.describe API::ProjectSnippets do
it 'rejects the snippet' do
expect { subject }.not_to change { Snippet.count }
expect(response).to have_gitlab_http_status(:bad_request)
- expect(json_response['message']).to eq({ "error" => "Spam detected" })
+ expect(json_response['message']['error']).to match(/snippet has been recognized as spam/)
end
it 'creates a spam log' do
@@ -344,7 +344,7 @@ RSpec.describe API::ProjectSnippets do
.not_to change { snippet.reload.title }
expect(response).to have_gitlab_http_status(:bad_request)
- expect(json_response['message']).to eq({ "error" => "Spam detected" })
+ expect(json_response['message']['error']).to match(/snippet has been recognized as spam/)
end
it 'creates a spam log' do
diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb
index 02df82d14a8..fc1d815a64e 100644
--- a/spec/requests/api/projects_spec.rb
+++ b/spec/requests/api/projects_spec.rb
@@ -1077,6 +1077,7 @@ RSpec.describe API::Projects do
attrs[:operations_access_level] = 'disabled'
attrs[:analytics_access_level] = 'disabled'
attrs[:container_registry_access_level] = 'private'
+ attrs[:security_and_compliance_access_level] = 'private'
end
post api('/projects', user), params: project
@@ -1100,6 +1101,7 @@ RSpec.describe API::Projects do
expect(project.operations_access_level).to eq(ProjectFeature::DISABLED)
expect(project.project_feature.analytics_access_level).to eq(ProjectFeature::DISABLED)
expect(project.project_feature.container_registry_access_level).to eq(ProjectFeature::PRIVATE)
+ expect(project.project_feature.security_and_compliance_access_level).to eq(ProjectFeature::PRIVATE)
end
it 'assigns container_registry_enabled to project', :aggregate_failures do
@@ -2227,6 +2229,7 @@ RSpec.describe API::Projects do
expect(json_response['restrict_user_defined_variables']).to eq(project.restrict_user_defined_variables?)
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['operations_access_level']).to be_present
+ expect(json_response['security_and_compliance_access_level']).to be_present
end
it 'exposes all necessary attributes' do
@@ -2295,6 +2298,7 @@ RSpec.describe API::Projects do
expect(json_response['wiki_access_level']).to be_present
expect(json_response['builds_access_level']).to be_present
expect(json_response['operations_access_level']).to be_present
+ expect(json_response['security_and_compliance_access_level']).to be_present
expect(json_response).to have_key('emails_disabled')
expect(json_response['resolve_outdated_diff_discussions']).to eq(project.resolve_outdated_diff_discussions)
expect(json_response['remove_source_branch_after_merge']).to be_truthy
@@ -2542,9 +2546,11 @@ RSpec.describe API::Projects do
get api("/projects", user)
expect(response).to have_gitlab_http_status(:ok)
- expect(json_response.first['permissions']['project_access']['access_level'])
+ detail_of_project = json_response.find { |detail| detail['id'] == project.id }
+
+ expect(detail_of_project.dig('permissions', 'project_access', 'access_level'))
.to eq(Gitlab::Access::MAINTAINER)
- expect(json_response.first['permissions']['group_access']).to be_nil
+ expect(detail_of_project.dig('permissions', 'group_access')).to be_nil
end
end
@@ -3220,6 +3226,30 @@ RSpec.describe API::Projects do
expect(project.reload.container_registry_access_level).to eq(ProjectFeature::ENABLED)
end
+ it 'sets security_and_compliance_access_level', :aggregate_failures do
+ put api("/projects/#{project.id}", user), params: { security_and_compliance_access_level: 'private' }
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response['security_and_compliance_access_level']).to eq('private')
+ expect(Project.find_by(path: project[:path]).security_and_compliance_access_level).to eq(ProjectFeature::PRIVATE)
+ end
+
+ it 'sets operations_access_level', :aggregate_failures do
+ put api("/projects/#{project.id}", user), params: { operations_access_level: 'private' }
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response['operations_access_level']).to eq('private')
+ expect(Project.find_by(path: project[:path]).operations_access_level).to eq(ProjectFeature::PRIVATE)
+ end
+
+ it 'sets analytics_access_level', :aggregate_failures do
+ put api("/projects/#{project.id}", user), params: { analytics_access_level: 'private' }
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response['analytics_access_level']).to eq('private')
+ expect(Project.find_by(path: project[:path]).analytics_access_level).to eq(ProjectFeature::PRIVATE)
+ end
+
it 'returns 400 when nothing sent' do
project_param = {}
diff --git a/spec/requests/api/pypi_packages_spec.rb b/spec/requests/api/pypi_packages_spec.rb
index fcd2d56e655..078db4f1509 100644
--- a/spec/requests/api/pypi_packages_spec.rb
+++ b/spec/requests/api/pypi_packages_spec.rb
@@ -185,6 +185,14 @@ RSpec.describe API::PypiPackages do
it_behaves_like params[:shared_examples_name], params[:user_role], params[:expected_status], params[:member]
end
+
+ context 'without requires_python' do
+ let(:token) { personal_access_token.token }
+ let(:user_headers) { basic_auth_header(user.username, token) }
+ let(:headers) { user_headers.merge(workhorse_headers) }
+
+ it_behaves_like 'PyPI package creation', :developer, :created, true
+ end
end
context 'with required_python too big' do
diff --git a/spec/requests/api/releases_spec.rb b/spec/requests/api/releases_spec.rb
index cb9b6a072b1..6038682de1e 100644
--- a/spec/requests/api/releases_spec.rb
+++ b/spec/requests/api/releases_spec.rb
@@ -160,7 +160,7 @@ RSpec.describe API::Releases do
get api("/projects/#{project.id}/releases", maintainer)
end.count
- create_list(:release, 2, :with_evidence, project: project, tag: 'v0.1', author: maintainer)
+ create_list(:release, 2, :with_evidence, project: project, author: maintainer)
create_list(:release, 2, project: project)
create_list(:release_link, 2, release: project.releases.first)
create_list(:release_link, 2, release: project.releases.last)
@@ -467,10 +467,10 @@ RSpec.describe API::Releases do
it "exposes tag and commit" do
create(:release,
project: project,
- tag: 'v0.1',
+ tag: 'v0.0.1',
author: maintainer,
created_at: 2.days.ago)
- get api("/projects/#{project.id}/releases/v0.1", guest)
+ get api("/projects/#{project.id}/releases/v0.0.1", guest)
expect(response).to match_response_schema('public_api/v4/release')
end
diff --git a/spec/requests/api/repositories_spec.rb b/spec/requests/api/repositories_spec.rb
index f42fc7aabc2..1d199a72d1d 100644
--- a/spec/requests/api/repositories_spec.rb
+++ b/spec/requests/api/repositories_spec.rb
@@ -783,6 +783,13 @@ RSpec.describe API::Repositories do
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['notes']).to be_present
end
+
+ context 'when previous tag version does not exist' do
+ it_behaves_like '422 response' do
+ let(:request) { get api("/projects/#{project.id}/repository/changelog", user), params: { version: 'v0.0.0' } }
+ let(:message) { 'Failed to generate the changelog: The commit start range is unspecified, and no previous tag could be found to use instead' }
+ end
+ end
end
describe 'POST /projects/:id/repository/changelog' do
diff --git a/spec/requests/api/search_spec.rb b/spec/requests/api/search_spec.rb
index 24cd95781c3..4d2a69cd85b 100644
--- a/spec/requests/api/search_spec.rb
+++ b/spec/requests/api/search_spec.rb
@@ -8,6 +8,11 @@ RSpec.describe API::Search do
let_it_be(:project, reload: true) { create(:project, :wiki_repo, :public, name: 'awesome project', group: group) }
let_it_be(:repo_project) { create(:project, :public, :repository, group: group) }
+ before do
+ allow(Gitlab::ApplicationRateLimiter).to receive(:threshold).with(:search_rate_limit).and_return(1000)
+ allow(Gitlab::ApplicationRateLimiter).to receive(:threshold).with(:search_rate_limit_unauthenticated).and_return(1000)
+ end
+
shared_examples 'response is correct' do |schema:, size: 1|
it { expect(response).to have_gitlab_http_status(:ok) }
it { expect(response).to match_response_schema(schema) }
@@ -347,7 +352,7 @@ RSpec.describe API::Search do
end
end
- it_behaves_like 'rate limited endpoint', rate_limit_key: :user_email_lookup do
+ it_behaves_like 'rate limited endpoint', rate_limit_key: :search_rate_limit do
let(:current_user) { user }
def request
@@ -522,7 +527,7 @@ RSpec.describe API::Search do
it_behaves_like 'response is correct', schema: 'public_api/v4/user/basics'
end
- it_behaves_like 'rate limited endpoint', rate_limit_key: :user_email_lookup do
+ it_behaves_like 'rate limited endpoint', rate_limit_key: :search_rate_limit do
let(:current_user) { user }
def request
@@ -803,7 +808,7 @@ RSpec.describe API::Search do
end
end
- it_behaves_like 'rate limited endpoint', rate_limit_key: :user_email_lookup do
+ it_behaves_like 'rate limited endpoint', rate_limit_key: :search_rate_limit do
let(:current_user) { user }
def request
diff --git a/spec/requests/api/snippets_spec.rb b/spec/requests/api/snippets_spec.rb
index dd5e6ac8a5e..13160519996 100644
--- a/spec/requests/api/snippets_spec.rb
+++ b/spec/requests/api/snippets_spec.rb
@@ -325,7 +325,7 @@ RSpec.describe API::Snippets, factory_default: :keep do
expect { subject }.not_to change { Snippet.count }
expect(response).to have_gitlab_http_status(:bad_request)
- expect(json_response['message']).to eq({ "error" => "Spam detected" })
+ expect(json_response['message']['error']).to match(/snippet has been recognized as spam/)
end
it 'creates a spam log' do
@@ -392,7 +392,7 @@ RSpec.describe API::Snippets, factory_default: :keep do
.not_to change { snippet.reload.title }
expect(response).to have_gitlab_http_status(:bad_request)
- expect(json_response['message']).to eq({ "error" => "Spam detected" })
+ expect(json_response['message']['error']).to match(/snippet has been recognized as spam/)
end
it 'creates a spam log' do
diff --git a/spec/requests/api/system_hooks_spec.rb b/spec/requests/api/system_hooks_spec.rb
index 1511872d183..d94b70ec0f9 100644
--- a/spec/requests/api/system_hooks_spec.rb
+++ b/spec/requests/api/system_hooks_spec.rb
@@ -36,12 +36,57 @@ RSpec.describe API::SystemHooks do
expect(response).to have_gitlab_http_status(:ok)
expect(response).to include_pagination_headers
- expect(json_response).to be_an Array
+ expect(response).to match_response_schema('public_api/v4/system_hooks')
+ expect(json_response.first).not_to have_key("token")
expect(json_response.first['url']).to eq(hook.url)
expect(json_response.first['push_events']).to be false
expect(json_response.first['tag_push_events']).to be false
expect(json_response.first['merge_requests_events']).to be false
expect(json_response.first['repository_update_events']).to be true
+ expect(json_response.first['enable_ssl_verification']).to be true
+ end
+ end
+ end
+
+ describe "GET /hooks/:id" do
+ context "when no user" do
+ it "returns authentication error" do
+ get api("/hooks/#{hook.id}")
+
+ expect(response).to have_gitlab_http_status(:unauthorized)
+ end
+ end
+
+ context "when not an admin" do
+ it "returns forbidden error" do
+ get api("/hooks/#{hook.id}", user)
+
+ expect(response).to have_gitlab_http_status(:forbidden)
+ end
+ end
+
+ context "when authenticated as admin" do
+ it "gets a hook", :aggregate_failures do
+ get api("/hooks/#{hook.id}", admin)
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(response).to match_response_schema('public_api/v4/system_hook')
+ expect(json_response).to match(
+ 'id' => be(hook.id),
+ 'url' => eq(hook.url),
+ 'created_at' => eq(hook.created_at.iso8601(3)),
+ 'push_events' => be(hook.push_events),
+ 'tag_push_events' => be(hook.tag_push_events),
+ 'merge_requests_events' => be(hook.merge_requests_events),
+ 'repository_update_events' => be(hook.repository_update_events),
+ 'enable_ssl_verification' => be(hook.enable_ssl_verification)
+ )
+ end
+
+ it 'returns 404 if the system hook does not exist' do
+ get api("/hooks/#{non_existing_record_id}", admin)
+
+ expect(response).to have_gitlab_http_status(:not_found)
end
end
end
@@ -77,6 +122,7 @@ RSpec.describe API::SystemHooks do
post api('/hooks', admin), params: { url: 'http://mep.mep' }
expect(response).to have_gitlab_http_status(:created)
+ expect(response).to match_response_schema('public_api/v4/system_hook')
expect(json_response['enable_ssl_verification']).to be true
expect(json_response['push_events']).to be false
expect(json_response['tag_push_events']).to be false
@@ -98,6 +144,7 @@ RSpec.describe API::SystemHooks do
}
expect(response).to have_gitlab_http_status(:created)
+ expect(response).to match_response_schema('public_api/v4/system_hook')
expect(json_response['enable_ssl_verification']).to be false
expect(json_response['push_events']).to be true
expect(json_response['tag_push_events']).to be true
diff --git a/spec/requests/api/terraform/state_spec.rb b/spec/requests/api/terraform/state_spec.rb
index 24f38b04348..ae1e461d433 100644
--- a/spec/requests/api/terraform/state_spec.rb
+++ b/spec/requests/api/terraform/state_spec.rb
@@ -36,8 +36,8 @@ RSpec.describe API::Terraform::State do
let(:current_user) { maintainer }
it_behaves_like 'tracking unique hll events' do
- let(:target_id) { 'p_terraform_state_api_unique_users' }
- let(:expected_type) { instance_of(Integer) }
+ let(:target_event) { 'p_terraform_state_api_unique_users' }
+ let(:expected_value) { instance_of(Integer) }
end
end
end
diff --git a/spec/requests/api/topics_spec.rb b/spec/requests/api/topics_spec.rb
index 70eee8a1af9..5c17ca9581e 100644
--- a/spec/requests/api/topics_spec.rb
+++ b/spec/requests/api/topics_spec.rb
@@ -7,9 +7,9 @@ RSpec.describe API::Topics do
let_it_be(:file) { fixture_file_upload('spec/fixtures/dk.png') }
- let_it_be(:topic_1) { create(:topic, name: 'Git', total_projects_count: 1, avatar: file) }
- let_it_be(:topic_2) { create(:topic, name: 'GitLab', total_projects_count: 2) }
- let_it_be(:topic_3) { create(:topic, name: 'other-topic', total_projects_count: 3) }
+ let_it_be(:topic_1) { create(:topic, name: 'Git', total_projects_count: 1, non_private_projects_count: 1, avatar: file) }
+ let_it_be(:topic_2) { create(:topic, name: 'GitLab', total_projects_count: 2, non_private_projects_count: 2) }
+ let_it_be(:topic_3) { create(:topic, name: 'other-topic', total_projects_count: 3, non_private_projects_count: 3) }
let_it_be(:admin) { create(:user, :admin) }
let_it_be(:user) { create(:user) }
@@ -142,6 +142,13 @@ RSpec.describe API::Topics do
expect(response).to have_gitlab_http_status(:bad_request)
expect(json_response['error']).to eql('name is missing')
end
+
+ it 'returns 400 if name is not unique (case insensitive)' do
+ post api('/topics/', admin), params: { name: topic_1.name.downcase }
+
+ expect(response).to have_gitlab_http_status(:bad_request)
+ expect(json_response['message']['name']).to eq(['has already been taken'])
+ end
end
context 'as normal user' do
@@ -248,4 +255,43 @@ RSpec.describe API::Topics do
end
end
end
+
+ describe 'DELETE /topics', :aggregate_failures do
+ context 'as administrator' do
+ it 'deletes a topic' do
+ delete api("/topics/#{topic_3.id}", admin), params: { name: 'my-topic' }
+
+ expect(response).to have_gitlab_http_status(:no_content)
+ end
+
+ it 'returns 404 for non existing id' do
+ delete api("/topics/#{non_existing_record_id}", admin), params: { name: 'my-topic' }
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+
+ it 'returns 400 for invalid `id` parameter' do
+ delete api('/topics/invalid', admin), params: { name: 'my-topic' }
+
+ expect(response).to have_gitlab_http_status(:bad_request)
+ expect(json_response['error']).to eql('id is invalid')
+ end
+ end
+
+ context 'as normal user' do
+ it 'returns 403 Forbidden' do
+ delete api("/topics/#{topic_3.id}", user), params: { name: 'my-topic' }
+
+ expect(response).to have_gitlab_http_status(:forbidden)
+ end
+ end
+
+ context 'as anonymous' do
+ it 'returns 401 Unauthorized' do
+ delete api("/topics/#{topic_3.id}"), params: { name: 'my-topic' }
+
+ expect(response).to have_gitlab_http_status(:unauthorized)
+ end
+ end
+ end
end
diff --git a/spec/requests/api/user_counts_spec.rb b/spec/requests/api/user_counts_spec.rb
index ab2aa87d1b7..27ebf02dd81 100644
--- a/spec/requests/api/user_counts_spec.rb
+++ b/spec/requests/api/user_counts_spec.rb
@@ -43,6 +43,21 @@ RSpec.describe API::UserCounts do
expect(response).to have_gitlab_http_status(:ok)
expect(json_response).to be_a Hash
expect(json_response['merge_requests']).to eq(2)
+ expect(json_response['attention_requests']).to eq(2)
+ end
+
+ describe 'mr_attention_requests is disabled' do
+ before do
+ stub_feature_flags(mr_attention_requests: false)
+ end
+
+ it 'does not include attention_requests count' do
+ create(:merge_request, source_project: project, author: user, assignees: [user])
+
+ get api('/user_counts', user)
+
+ expect(json_response.key?('attention_requests')).to be(false)
+ end
end
end
diff --git a/spec/requests/api/users_spec.rb b/spec/requests/api/users_spec.rb
index 985e07bf174..2d71674273b 100644
--- a/spec/requests/api/users_spec.rb
+++ b/spec/requests/api/users_spec.rb
@@ -11,6 +11,7 @@ RSpec.describe API::Users do
let(:blocked_user) { create(:user, :blocked) }
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(:private_user) { create(:user, private_profile: true) }
let(:deactivated_user) { create(:user, state: 'deactivated') }
@@ -649,20 +650,6 @@ RSpec.describe API::Users do
expect(response).to have_gitlab_http_status(:ok)
end
end
-
- context 'when feature flag is disabled' do
- before do
- stub_feature_flags(rate_limit_user_by_id_endpoint: false)
- end
-
- it 'does not throttle the request' do
- expect(Gitlab::ApplicationRateLimiter).not_to receive(:throttled?)
-
- get api("/users/#{user.id}", user)
-
- expect(response).to have_gitlab_http_status(:ok)
- end
- end
end
context 'when job title is present' do
@@ -1307,10 +1294,10 @@ RSpec.describe API::Users do
end
it "updates user's existing identity" do
- put api("/users/#{omniauth_user.id}", admin), params: { provider: 'ldapmain', extern_uid: '654321' }
+ put api("/users/#{ldap_user.id}", admin), params: { provider: 'ldapmain', extern_uid: '654321' }
expect(response).to have_gitlab_http_status(:ok)
- expect(omniauth_user.reload.identities.first.extern_uid).to eq('654321')
+ expect(ldap_user.reload.identities.first.extern_uid).to eq('654321')
end
it 'updates user with new identity' do
@@ -1735,6 +1722,33 @@ RSpec.describe API::Users do
end
end
+ describe 'GET /user/:id/keys/:key_id' do
+ it 'gets existing key', :aggregate_failures do
+ user.keys << key
+
+ get api("/users/#{user.id}/keys/#{key.id}")
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response['title']).to eq(key.title)
+ end
+
+ it 'returns 404 error if user not found', :aggregate_failures do
+ user.keys << key
+
+ get api("/users/0/keys/#{key.id}")
+
+ 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 found', :aggregate_failures do
+ get api("/users/#{user.id}/keys/#{non_existing_record_id}")
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ expect(json_response['message']).to eq('404 Key Not Found')
+ end
+ end
+
describe 'DELETE /user/:id/keys/:key_id' do
context 'when unauthenticated' do
it 'returns authentication error' do
@@ -3103,6 +3117,18 @@ RSpec.describe API::Users do
expect(response.body).to eq('null')
end
end
+
+ context 'with the API initiating user' do
+ let(:user_id) { admin.id }
+
+ it 'does not block the API initiating user, returns 403' do
+ block_user
+
+ expect(response).to have_gitlab_http_status(:forbidden)
+ expect(json_response['message']).to eq('403 Forbidden - The API initiating user cannot be blocked by the API')
+ expect(admin.reload.state).to eq('active')
+ end
+ end
end
it 'is not available for non admin users' do
diff --git a/spec/requests/api/wikis_spec.rb b/spec/requests/api/wikis_spec.rb
index ec34dc7e7a1..06ae61ca5eb 100644
--- a/spec/requests/api/wikis_spec.rb
+++ b/spec/requests/api/wikis_spec.rb
@@ -31,7 +31,7 @@ RSpec.describe API::Wikis do
let(:project_wiki) { create(:project_wiki, project: project, user: user) }
let(:payload) { { content: 'content', format: 'rdoc', title: 'title' } }
- let(:expected_keys_with_content) { %w(content format slug title) }
+ let(:expected_keys_with_content) { %w(content format slug title encoding) }
let(:expected_keys_without_content) { %w(format slug title) }
let(:wiki) { project_wiki }
@@ -130,41 +130,42 @@ RSpec.describe API::Wikis do
describe 'GET /projects/:id/wikis/:slug' do
let(:page) { create(:wiki_page, wiki: project.wiki) }
let(:url) { "/projects/#{project.id}/wikis/#{page.slug}" }
+ let(:params) { {} }
+
+ subject(:request) { get api(url, user), params: params }
context 'when wiki is disabled' do
let(:project) { project_wiki_disabled }
+ before do
+ request
+ end
+
context 'when user is guest' do
- before do
- get api(url)
- end
+ let(:user) { nil }
include_examples 'wiki API 404 Project Not Found'
end
context 'when user is developer' do
- before do
- get api(url, developer)
- end
+ let(:user) { developer }
include_examples 'wiki API 403 Forbidden'
end
context 'when user is maintainer' do
- before do
- get api(url, maintainer)
- end
+ let(:user) { maintainer }
include_examples 'wiki API 403 Forbidden'
end
end
context 'when wiki is available only for team members' do
- let(:project) { create(:project, :wiki_repo, :wiki_private) }
+ let_it_be_with_reload(:project) { create(:project, :wiki_repo, :wiki_private) }
context 'when user is guest' do
before do
- get api(url)
+ request
end
include_examples 'wiki API 404 Project Not Found'
@@ -173,7 +174,6 @@ RSpec.describe API::Wikis do
context 'when user is developer' do
before do
project.add_developer(user)
- get api(url, user)
end
include_examples 'wikis API returns wiki page'
@@ -181,6 +181,10 @@ RSpec.describe API::Wikis do
context 'when page is not existing' do
let(:url) { "/projects/#{project.id}/wikis/unknown" }
+ before do
+ request
+ end
+
include_examples 'wiki API 404 Wiki Page Not Found'
end
end
@@ -188,8 +192,6 @@ RSpec.describe API::Wikis do
context 'when user is maintainer' do
before do
project.add_maintainer(user)
-
- get api(url, user)
end
include_examples 'wikis API returns wiki page'
@@ -197,17 +199,23 @@ RSpec.describe API::Wikis do
context 'when page is not existing' do
let(:url) { "/projects/#{project.id}/wikis/unknown" }
+ before do
+ request
+ end
+
include_examples 'wiki API 404 Wiki Page Not Found'
end
end
end
context 'when wiki is available for everyone with access' do
- let(:project) { create(:project, :wiki_repo) }
+ let_it_be_with_reload(:project) { create(:project, :wiki_repo) }
context 'when user is guest' do
+ let(:user) { nil }
+
before do
- get api(url)
+ request
end
include_examples 'wiki API 404 Project Not Found'
@@ -216,8 +224,6 @@ RSpec.describe API::Wikis do
context 'when user is developer' do
before do
project.add_developer(user)
-
- get api(url, user)
end
include_examples 'wikis API returns wiki page'
@@ -225,6 +231,10 @@ RSpec.describe API::Wikis do
context 'when page is not existing' do
let(:url) { "/projects/#{project.id}/wikis/unknown" }
+ before do
+ request
+ end
+
include_examples 'wiki API 404 Wiki Page Not Found'
end
end
@@ -232,8 +242,6 @@ RSpec.describe API::Wikis do
context 'when user is maintainer' do
before do
project.add_maintainer(user)
-
- get api(url, user)
end
include_examples 'wikis API returns wiki page'
@@ -241,6 +249,10 @@ RSpec.describe API::Wikis do
context 'when page is not existing' do
let(:url) { "/projects/#{project.id}/wikis/unknown" }
+ before do
+ request
+ end
+
include_examples 'wiki API 404 Wiki Page Not Found'
end
end
diff --git a/spec/requests/content_security_policy_spec.rb b/spec/requests/content_security_policy_spec.rb
new file mode 100644
index 00000000000..06fc5b0e190
--- /dev/null
+++ b/spec/requests/content_security_policy_spec.rb
@@ -0,0 +1,50 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+# The AnonymousController doesn't support setting the CSP
+# This is why an arbitrary test request was chosen instead
+# of testing in application_controller_spec.
+RSpec.describe 'Content Security Policy' do
+ let(:snowplow_host) { 'snowplow.example.com' }
+
+ shared_examples 'snowplow is not in the CSP' do
+ it 'does not add the snowplow collector hostname to the CSP' do
+ get explore_root_url
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(response.headers['Content-Security-Policy']).not_to include(snowplow_host)
+ end
+ end
+
+ describe 'GET #explore' do
+ context 'snowplow is enabled' do
+ before do
+ stub_application_setting(snowplow_enabled: true, snowplow_collector_hostname: snowplow_host)
+ end
+
+ it 'adds the snowplow collector hostname to the CSP' do
+ get explore_root_url
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(response.headers['Content-Security-Policy']).to include(snowplow_host)
+ end
+ end
+
+ context 'snowplow is enabled but host is not configured' do
+ before do
+ stub_application_setting(snowplow_enabled: true)
+ end
+
+ it_behaves_like 'snowplow is not in the CSP'
+ end
+
+ context 'snowplow is disabled' do
+ before do
+ stub_application_setting(snowplow_enabled: false, snowplow_collector_hostname: snowplow_host)
+ end
+
+ it_behaves_like 'snowplow is not in the CSP'
+ end
+ end
+end
diff --git a/spec/requests/git_http_spec.rb b/spec/requests/git_http_spec.rb
index 340ed7bde53..9f9e1cfd90e 100644
--- a/spec/requests/git_http_spec.rb
+++ b/spec/requests/git_http_spec.rb
@@ -1019,7 +1019,11 @@ RSpec.describe 'Git HTTP requests' do
let(:path) { "#{project.full_path}.git" }
context "when the project is public" do
- let(:project) { create(:project, :repository, :public, path: 'foo.') }
+ let(:project) do
+ project = create(:project, :repository, :public)
+ project.update_attribute(:path, 'foo.')
+ project
+ end
it_behaves_like 'pushes require Basic HTTP Authentication'
@@ -1158,7 +1162,11 @@ RSpec.describe 'Git HTTP requests' do
end
context "when the project is private" do
- let(:project) { create(:project, :repository, :private, path: 'foo.') }
+ let(:project) do
+ project = create(:project, :repository, :private)
+ project.update_attribute(:path, 'foo.')
+ project
+ end
it_behaves_like 'pulls require Basic HTTP Authentication'
it_behaves_like 'pushes require Basic HTTP Authentication'
@@ -1586,11 +1594,19 @@ RSpec.describe 'Git HTTP requests' do
end
it_behaves_like 'project path without .git suffix' do
- let(:repository_path) { create(:project, :repository, :public, path: 'project.').full_path }
+ let(:repository_path) do
+ project = create(:project, :repository, :public)
+ project.update_attribute(:path, 'project.')
+ project.full_path
+ end
end
context "retrieving an info/refs file" do
- let(:project) { create(:project, :repository, :public, path: 'project.') }
+ let(:project) do
+ project = create(:project, :repository, :public)
+ project.update_attribute(:path, 'project.')
+ project
+ end
context "when the file exists" do
before do
@@ -1625,7 +1641,11 @@ RSpec.describe 'Git HTTP requests' do
let(:path) { "/#{wiki.repository.full_path}.git" }
context "when the project is public" do
- let(:project) { create(:project, :wiki_repo, :public, :wiki_enabled, path: 'foo.') }
+ let(:project) do
+ project = create(:project, :wiki_repo, :public, :wiki_enabled)
+ project.update_attribute(:path, 'foo.')
+ project
+ end
it_behaves_like 'pushes require Basic HTTP Authentication'
@@ -1652,7 +1672,11 @@ RSpec.describe 'Git HTTP requests' do
end
context 'but the repo is disabled' do
- let(:project) { create(:project, :wiki_repo, :public, :repository_disabled, :wiki_enabled, path: 'foo.') }
+ let(:project) do
+ project = create(:project, :wiki_repo, :public, :repository_disabled, :wiki_enabled)
+ project.update_attribute(:path, 'foo.')
+ project
+ end
it_behaves_like 'pulls are allowed'
it_behaves_like 'pushes are allowed'
@@ -1673,7 +1697,11 @@ RSpec.describe 'Git HTTP requests' do
end
context "when the project is private" do
- let(:project) { create(:project, :wiki_repo, :private, :wiki_enabled, path: 'foo.') }
+ let(:project) do
+ project = create(:project, :wiki_repo, :private, :wiki_enabled)
+ project.update_attribute(:path, 'foo.')
+ project
+ end
it_behaves_like 'pulls require Basic HTTP Authentication'
it_behaves_like 'pushes require Basic HTTP Authentication'
@@ -1700,7 +1728,11 @@ RSpec.describe 'Git HTTP requests' do
end
context 'but the repo is disabled' do
- let(:project) { create(:project, :wiki_repo, :private, :repository_disabled, :wiki_enabled, path: 'foo.') }
+ let(:project) do
+ project = create(:project, :wiki_repo, :private, :repository_disabled, :wiki_enabled)
+ project.update_attribute(:path, 'foo.')
+ project
+ end
it 'allows clones' do
download(path, user: user.username, password: user.password) do |response|
diff --git a/spec/requests/groups/crm/contacts_controller_spec.rb b/spec/requests/groups/crm/contacts_controller_spec.rb
index 5d126c6ead5..4d8ca0fcd60 100644
--- a/spec/requests/groups/crm/contacts_controller_spec.rb
+++ b/spec/requests/groups/crm/contacts_controller_spec.rb
@@ -49,6 +49,12 @@ RSpec.describe Groups::Crm::ContactsController do
it_behaves_like 'response with 404 status'
end
+
+ context 'when subgroup' do
+ let(:group) { create(:group, :private, :crm_enabled, parent: create(:group)) }
+
+ it_behaves_like 'response with 404 status'
+ end
end
context 'with unauthorized user' do
diff --git a/spec/requests/groups/crm/organizations_controller_spec.rb b/spec/requests/groups/crm/organizations_controller_spec.rb
index f38300c3c5b..37ffac71772 100644
--- a/spec/requests/groups/crm/organizations_controller_spec.rb
+++ b/spec/requests/groups/crm/organizations_controller_spec.rb
@@ -49,6 +49,12 @@ RSpec.describe Groups::Crm::OrganizationsController do
it_behaves_like 'response with 404 status'
end
+
+ context 'when subgroup' do
+ let(:group) { create(:group, :private, :crm_enabled, parent: create(:group)) }
+
+ it_behaves_like 'response with 404 status'
+ end
end
context 'with unauthorized user' do
diff --git a/spec/requests/groups/deploy_tokens_controller_spec.rb b/spec/requests/groups/deploy_tokens_controller_spec.rb
new file mode 100644
index 00000000000..b3dce9b9cf1
--- /dev/null
+++ b/spec/requests/groups/deploy_tokens_controller_spec.rb
@@ -0,0 +1,40 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Groups::DeployTokensController do
+ let_it_be(:group) { create(:group) }
+ let_it_be(:user) { create(:user) }
+ let_it_be(:deploy_token) { create(:deploy_token, :group, groups: [group]) }
+ let_it_be(:params) do
+ { id: deploy_token.id, group_id: group }
+ end
+
+ before do
+ group.add_owner(user)
+
+ sign_in(user)
+ end
+
+ describe 'PUT /groups/:group_path_with_namespace/-/deploy_tokens/:id/revoke' do
+ subject(:put_revoke) do
+ put "/groups/#{group.full_path}/-/deploy_tokens/#{deploy_token.id}/revoke", params: params
+ end
+
+ it 'invokes the Groups::DeployTokens::RevokeService' do
+ expect(deploy_token.revoked).to eq(false)
+ expect(Groups::DeployTokens::RevokeService).to receive(:new).and_call_original
+
+ put_revoke
+
+ expect(deploy_token.reload.revoked).to eq(true)
+ end
+
+ it 'redirects to group repository settings with correct anchor' do
+ put_revoke
+
+ expect(response).to have_gitlab_http_status(:redirect)
+ expect(response).to redirect_to(group_settings_repository_path(group, anchor: 'js-deploy-tokens'))
+ end
+ end
+end
diff --git a/spec/requests/groups/harbor/repositories_controller_spec.rb b/spec/requests/groups/harbor/repositories_controller_spec.rb
new file mode 100644
index 00000000000..3e475dc410e
--- /dev/null
+++ b/spec/requests/groups/harbor/repositories_controller_spec.rb
@@ -0,0 +1,69 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Groups::Harbor::RepositoriesController do
+ let_it_be(:group, reload: true) { create(:group) }
+ let_it_be(:user) { create(:user) }
+
+ shared_examples 'responds with 404 status' do
+ it 'returns 404' do
+ subject
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+
+ shared_examples 'responds with 200 status' do
+ it 'renders the index template' do
+ subject
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(response).to render_template(:index)
+ end
+ end
+
+ before do
+ stub_feature_flags(harbor_registry_integration: true)
+ group.add_reporter(user)
+ login_as(user)
+ end
+
+ describe 'GET #index' do
+ subject do
+ get group_harbor_registries_path(group)
+ response
+ end
+
+ context 'with harbor registry feature flag enabled' do
+ it_behaves_like 'responds with 200 status'
+ end
+
+ context 'with harbor registry feature flag disabled' do
+ before do
+ stub_feature_flags(harbor_registry_integration: false)
+ end
+
+ it_behaves_like 'responds with 404 status'
+ end
+ end
+
+ describe 'GET #show' do
+ subject do
+ get group_harbor_registry_path(group, 1)
+ response
+ end
+
+ context 'with harbor registry feature flag enabled' do
+ it_behaves_like 'responds with 200 status'
+ end
+
+ context 'with harbor registry feature flag disabled' do
+ before do
+ stub_feature_flags(harbor_registry_integration: false)
+ end
+
+ it_behaves_like 'responds with 404 status'
+ end
+ end
+end
diff --git a/spec/requests/jira_connect/oauth_callbacks_controller_spec.rb b/spec/requests/jira_connect/oauth_callbacks_controller_spec.rb
new file mode 100644
index 00000000000..1e4628e5d59
--- /dev/null
+++ b/spec/requests/jira_connect/oauth_callbacks_controller_spec.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe JiraConnect::OauthCallbacksController do
+ describe 'GET /-/jira_connect/oauth_callbacks' do
+ context 'when logged in' do
+ let_it_be(:user) { create(:user) }
+
+ before do
+ sign_in(user)
+ end
+
+ it 'renders a page prompting the user to close the window' do
+ get '/-/jira_connect/oauth_callbacks'
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(response.body).to include('You can close this window.')
+ end
+ end
+ end
+end
diff --git a/spec/requests/projects/google_cloud/deployments_controller_spec.rb b/spec/requests/projects/google_cloud/deployments_controller_spec.rb
index fd356bc61c7..7bd9609a7dc 100644
--- a/spec/requests/projects/google_cloud/deployments_controller_spec.rb
+++ b/spec/requests/projects/google_cloud/deployments_controller_spec.rb
@@ -22,13 +22,21 @@ RSpec.describe Projects::GoogleCloud::DeploymentsController do
project.add_maintainer(user_maintainer)
end
- describe "Routes must be restricted behind Google OAuth2" do
+ describe "Routes must be restricted behind Google OAuth2", :snowplow do
context 'when a public request is made' do
it 'returns not found on GET request' do
urls_list.each do |url|
get url
expect(response).to have_gitlab_http_status(:not_found)
+ expect_snowplow_event(
+ category: 'Projects::GoogleCloud',
+ action: 'admin_project_google_cloud!',
+ label: 'access_denied',
+ property: 'invalid_user',
+ project: project,
+ user: nil
+ )
end
end
end
@@ -40,6 +48,14 @@ RSpec.describe Projects::GoogleCloud::DeploymentsController do
get url
expect(response).to have_gitlab_http_status(:not_found)
+ expect_snowplow_event(
+ category: 'Projects::GoogleCloud',
+ action: 'admin_project_google_cloud!',
+ label: 'access_denied',
+ property: 'invalid_user',
+ project: project,
+ user: nil
+ )
end
end
end
@@ -60,7 +76,7 @@ RSpec.describe Projects::GoogleCloud::DeploymentsController do
end
end
- describe 'Authorized GET project/-/google_cloud/deployments/cloud_run' do
+ describe 'Authorized GET project/-/google_cloud/deployments/cloud_run', :snowplow do
let_it_be(:url) { "#{project_google_cloud_deployments_cloud_run_path(project)}" }
before do
@@ -72,25 +88,39 @@ RSpec.describe Projects::GoogleCloud::DeploymentsController do
end
it 'redirects to google_cloud home on enable service error' do
- # since GPC_PROJECT_ID is not set, enable cloud run service should return an error
-
get url
expect(response).to redirect_to(project_google_cloud_index_path(project))
+ # since GPC_PROJECT_ID is not set, enable cloud run service should return an error
+ expect_snowplow_event(
+ category: 'Projects::GoogleCloud',
+ action: 'deployments#cloud_run',
+ label: 'enable_cloud_run_error',
+ extra: { message: 'No GCP projects found. Configure a service account or GCP_PROJECT_ID ci variable.',
+ status: :error },
+ project: project,
+ user: user_maintainer
+ )
end
- it 'tracks error and redirects to gcp_error' do
- mock_google_error = Google::Apis::ClientError.new('some_error')
+ it 'redirects to gcp_error' do
+ mock_gcp_error = Google::Apis::ClientError.new('some_error')
allow_next_instance_of(GoogleCloud::EnableCloudRunService) do |service|
- allow(service).to receive(:execute).and_raise(mock_google_error)
+ allow(service).to receive(:execute).and_raise(mock_gcp_error)
end
- expect(Gitlab::ErrorTracking).to receive(:track_exception).with(mock_google_error, { project_id: project.id })
-
get url
expect(response).to render_template(:gcp_error)
+ expect_snowplow_event(
+ category: 'Projects::GoogleCloud',
+ action: 'deployments#cloud_run',
+ label: 'gcp_error',
+ extra: mock_gcp_error,
+ project: project,
+ user: user_maintainer
+ )
end
context 'GCP_PROJECT_IDs are defined' do
@@ -106,6 +136,14 @@ RSpec.describe Projects::GoogleCloud::DeploymentsController do
get url
expect(response).to redirect_to(project_google_cloud_index_path(project))
+ expect_snowplow_event(
+ category: 'Projects::GoogleCloud',
+ action: 'deployments#cloud_run',
+ label: 'generate_pipeline_error',
+ extra: { status: :error },
+ project: project,
+ user: user_maintainer
+ )
end
it 'redirects to create merge request form' do
@@ -121,11 +159,24 @@ RSpec.describe Projects::GoogleCloud::DeploymentsController do
expect(response).to have_gitlab_http_status(:found)
expect(response.location).to include(project_new_merge_request_path(project))
+ expect_snowplow_event(
+ category: 'Projects::GoogleCloud',
+ action: 'deployments#cloud_run',
+ label: 'cloud_run_success',
+ extra: { "title": "Enable deployments to Cloud Run",
+ "description": "This merge request includes a Cloud Run deployment job in the pipeline definition (.gitlab-ci.yml).\n\nThe `deploy-to-cloud-run` job:\n* Requires the following environment variables\n * `GCP_PROJECT_ID`\n * `GCP_SERVICE_ACCOUNT_KEY`\n* Job definition can be found at: https://gitlab.com/gitlab-org/incubation-engineering/five-minute-production/library\n\nThis pipeline definition has been committed to the branch ``.\nYou may modify the pipeline definition further or accept the changes as-is if suitable.\n",
+ "source_project_id": project.id,
+ "target_project_id": project.id,
+ "source_branch": nil,
+ "target_branch": project.default_branch },
+ project: project,
+ user: user_maintainer
+ )
end
end
end
- describe 'Authorized GET project/-/google_cloud/deployments/cloud_storage' do
+ describe 'Authorized GET project/-/google_cloud/deployments/cloud_storage', :snowplow do
let_it_be(:url) { "#{project_google_cloud_deployments_cloud_storage_path(project)}" }
before do
diff --git a/spec/requests/projects/google_cloud/gcp_regions_controller_spec.rb b/spec/requests/projects/google_cloud/gcp_regions_controller_spec.rb
new file mode 100644
index 00000000000..56474b6520d
--- /dev/null
+++ b/spec/requests/projects/google_cloud/gcp_regions_controller_spec.rb
@@ -0,0 +1,152 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Projects::GoogleCloud::GcpRegionsController do
+ let_it_be(:project) { create(:project, :public, :repository) }
+ let_it_be(:repository) { project.repository }
+
+ let(:user_guest) { create(:user) }
+ let(:user_maintainer) { create(:user) }
+
+ RSpec.shared_examples "should track not_found event" do
+ it "tracks event" do
+ is_expected.to be(404)
+ expect_snowplow_event(
+ category: 'Projects::GoogleCloud',
+ action: 'admin_project_google_cloud!',
+ label: 'access_denied',
+ property: 'invalid_user',
+ project: project,
+ user: nil
+ )
+ end
+ end
+
+ RSpec.shared_examples "should track access_denied event" do
+ it "tracks event" do
+ is_expected.to be(404)
+ expect_snowplow_event(
+ category: 'Projects::GoogleCloud',
+ action: 'admin_project_google_cloud!',
+ label: 'access_denied',
+ property: 'invalid_user',
+ project: project,
+ user: nil
+ )
+ end
+ end
+
+ RSpec.shared_examples "should track feature_flag_disabled event" do |user|
+ it "tracks event" do
+ is_expected.to be(404)
+ expect_snowplow_event(
+ category: 'Projects::GoogleCloud',
+ action: 'feature_flag_enabled!',
+ label: 'access_denied',
+ property: 'feature_flag_not_enabled',
+ project: project,
+ user: user_maintainer
+ )
+ end
+ end
+
+ RSpec.shared_examples "should track gcp_error event" do |config|
+ it "tracks event" do
+ is_expected.to be(403)
+ expect_snowplow_event(
+ category: 'Projects::GoogleCloud',
+ action: 'google_oauth2_enabled!',
+ label: 'access_denied',
+ extra: { reason: 'google_oauth2_not_configured', config: config },
+ project: project,
+ user: user_maintainer
+ )
+ end
+ end
+
+ RSpec.shared_examples "should be not found" do
+ it 'returns not found' do
+ is_expected.to be(404)
+ end
+ end
+
+ RSpec.shared_examples "should be forbidden" do
+ it 'returns forbidden' do
+ is_expected.to be(403)
+ end
+ end
+
+ RSpec.shared_examples "public request should 404" do
+ it_behaves_like "should be not found"
+ it_behaves_like "should track not_found event"
+ end
+
+ RSpec.shared_examples "unauthorized access should 404" do
+ before do
+ project.add_guest(user_guest)
+ end
+
+ it_behaves_like "should be not found"
+ it_behaves_like "should track access_denied event"
+ end
+
+ describe 'GET #index', :snowplow do
+ subject { get project_google_cloud_gcp_regions_path(project) }
+
+ it_behaves_like "public request should 404"
+ it_behaves_like "unauthorized access should 404"
+
+ context 'when authorized members make requests' do
+ before do
+ project.add_maintainer(user_maintainer)
+ sign_in(user_maintainer)
+ end
+
+ it 'renders gcp_regions' do
+ is_expected.to render_template('projects/google_cloud/gcp_regions/index')
+ end
+
+ context 'but gitlab instance is not configured for google oauth2' do
+ unconfigured_google_oauth2 = Struct.new(:app_id, :app_secret)
+ .new('', '')
+
+ before do
+ allow(Gitlab::Auth::OAuth::Provider).to receive(:config_for)
+ .with('google_oauth2')
+ .and_return(unconfigured_google_oauth2)
+ end
+
+ it_behaves_like "should be forbidden"
+ it_behaves_like "should track gcp_error event", unconfigured_google_oauth2
+ end
+
+ context 'but feature flag is disabled' do
+ before do
+ stub_feature_flags(incubation_5mp_google_cloud: false)
+ end
+
+ it_behaves_like "should be not found"
+ it_behaves_like "should track feature_flag_disabled event"
+ end
+ end
+ end
+
+ describe 'POST #index', :snowplow do
+ subject { post project_google_cloud_gcp_regions_path(project), params: { gcp_region: 'region1', environment: 'env1' } }
+
+ it_behaves_like "public request should 404"
+ it_behaves_like "unauthorized access should 404"
+
+ context 'when authorized members make requests' do
+ before do
+ project.add_maintainer(user_maintainer)
+ sign_in(user_maintainer)
+ end
+
+ it 'redirects to google cloud index' do
+ is_expected.to redirect_to(project_google_cloud_index_path(project))
+ end
+ end
+ end
+end
diff --git a/spec/requests/projects/google_cloud/revoke_oauth_controller_spec.rb b/spec/requests/projects/google_cloud/revoke_oauth_controller_spec.rb
new file mode 100644
index 00000000000..07590d3710e
--- /dev/null
+++ b/spec/requests/projects/google_cloud/revoke_oauth_controller_spec.rb
@@ -0,0 +1,86 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Projects::GoogleCloud::RevokeOauthController do
+ include SessionHelpers
+
+ describe 'POST #create', :snowplow, :clean_gitlab_redis_sessions, :aggregate_failures do
+ let_it_be(:project) { create(:project, :public) }
+ let_it_be(:url) { project_google_cloud_revoke_oauth_index_path(project).to_s }
+
+ let(:user) { project.creator }
+
+ before do
+ sign_in(user)
+
+ stub_session(GoogleApi::CloudPlatform::Client.session_key_for_token => 'token')
+
+ allow_next_instance_of(GoogleApi::CloudPlatform::Client) do |client|
+ allow(client).to receive(:validate_token).and_return(true)
+ end
+ end
+
+ context 'when GCP token is invalid' do
+ before do
+ allow_next_instance_of(GoogleApi::CloudPlatform::Client) do |client|
+ allow(client).to receive(:validate_token).and_return(false)
+ end
+ end
+
+ it 'redirects to Google OAuth2 authorize URL' do
+ sign_in(user)
+
+ post url
+
+ expect(response).to redirect_to(assigns(:authorize_url))
+ end
+ end
+
+ context 'when revocation is successful' do
+ before do
+ stub_request(:post, "https://oauth2.googleapis.com/revoke")
+ .to_return(status: 200, body: "", headers: {})
+ end
+
+ it 'calls revoke endpoint and redirects' do
+ post url
+
+ expect(request.session[GoogleApi::CloudPlatform::Client.session_key_for_token]).to be_nil
+ expect(response).to redirect_to(project_google_cloud_index_path(project))
+ expect(flash[:notice]).to eq('Google OAuth2 token revocation requested')
+ expect_snowplow_event(
+ category: 'Projects::GoogleCloud',
+ action: 'revoke_oauth#create',
+ label: 'create',
+ property: 'success',
+ project: project,
+ user: user
+ )
+ end
+ end
+
+ context 'when revocation fails' do
+ before do
+ stub_request(:post, "https://oauth2.googleapis.com/revoke")
+ .to_return(status: 400, body: "", headers: {})
+ end
+
+ it 'calls revoke endpoint and redirects' do
+ post url
+
+ expect(request.session[GoogleApi::CloudPlatform::Client.session_key_for_token]).to be_nil
+ expect(response).to redirect_to(project_google_cloud_index_path(project))
+ expect(flash[:alert]).to eq('Google OAuth2 token revocation request failed')
+ expect_snowplow_event(
+ category: 'Projects::GoogleCloud',
+ action: 'revoke_oauth#create',
+ label: 'create',
+ property: 'failed',
+ project: project,
+ user: user
+ )
+ end
+ end
+ end
+end
diff --git a/spec/requests/projects/google_cloud/service_accounts_controller_spec.rb b/spec/requests/projects/google_cloud/service_accounts_controller_spec.rb
index 0f243a6a7a9..4b32965e2b0 100644
--- a/spec/requests/projects/google_cloud/service_accounts_controller_spec.rb
+++ b/spec/requests/projects/google_cloud/service_accounts_controller_spec.rb
@@ -5,7 +5,7 @@ require 'spec_helper'
RSpec.describe Projects::GoogleCloud::ServiceAccountsController do
let_it_be(:project) { create(:project, :public) }
- describe 'GET index' do
+ describe 'GET index', :snowplow do
let_it_be(:url) { "#{project_google_cloud_service_accounts_path(project)}" }
let(:user_guest) { create(:user) }
@@ -27,6 +27,14 @@ RSpec.describe Projects::GoogleCloud::ServiceAccountsController do
get url
expect(response).to have_gitlab_http_status(:not_found)
+ expect_snowplow_event(
+ category: 'Projects::GoogleCloud',
+ action: 'admin_project_google_cloud!',
+ label: 'access_denied',
+ property: 'invalid_user',
+ project: project,
+ user: nil
+ )
end
it 'returns not found on POST request' do
@@ -42,6 +50,14 @@ RSpec.describe Projects::GoogleCloud::ServiceAccountsController do
sign_in(unauthorized_member)
get url
+ expect_snowplow_event(
+ category: 'Projects::GoogleCloud',
+ action: 'admin_project_google_cloud!',
+ label: 'access_denied',
+ property: 'invalid_user',
+ project: project,
+ user: unauthorized_member
+ )
expect(response).to have_gitlab_http_status(:not_found)
end
@@ -52,6 +68,14 @@ RSpec.describe Projects::GoogleCloud::ServiceAccountsController do
sign_in(unauthorized_member)
post url
+ expect_snowplow_event(
+ category: 'Projects::GoogleCloud',
+ action: 'admin_project_google_cloud!',
+ label: 'access_denied',
+ property: 'invalid_user',
+ project: project,
+ user: unauthorized_member
+ )
expect(response).to have_gitlab_http_status(:not_found)
end
@@ -80,34 +104,75 @@ RSpec.describe Projects::GoogleCloud::ServiceAccountsController do
end
context 'and user has successfully completed the google oauth2 flow' do
- before do
- allow_next_instance_of(GoogleApi::CloudPlatform::Client) do |client|
- mock_service_account = Struct.new(:project_id, :unique_id, :email).new(123, 456, 'em@ai.l')
- allow(client).to receive(:validate_token).and_return(true)
- allow(client).to receive(:list_projects).and_return([{}, {}, {}])
- allow(client).to receive(:create_service_account).and_return(mock_service_account)
- allow(client).to receive(:create_service_account_key).and_return({})
- allow(client).to receive(:grant_service_account_roles)
+ context 'but the user does not have gcp projects' do
+ before do
+ allow_next_instance_of(GoogleApi::CloudPlatform::Client) do |client|
+ mock_service_account = Struct.new(:project_id, :unique_id, :email).new(123, 456, 'em@ai.l')
+ allow(client).to receive(:list_projects).and_return([])
+ allow(client).to receive(:validate_token).and_return(true)
+ allow(client).to receive(:create_service_account).and_return(mock_service_account)
+ allow(client).to receive(:create_service_account_key).and_return({})
+ allow(client).to receive(:grant_service_account_roles)
+ end
end
- end
- it 'returns success on GET' do
- authorized_members.each do |authorized_member|
- sign_in(authorized_member)
+ it 'renders no_gcp_projects' do
+ authorized_members.each do |authorized_member|
+ allow_next_instance_of(BranchesFinder) do |branches_finder|
+ allow(branches_finder).to receive(:execute).and_return([])
+ end
- get url
+ allow_next_instance_of(TagsFinder) do |branches_finder|
+ allow(branches_finder).to receive(:execute).and_return([])
+ end
+
+ sign_in(authorized_member)
- expect(response).to have_gitlab_http_status(:ok)
+ get url
+
+ expect(response).to render_template('projects/google_cloud/errors/no_gcp_projects')
+ end
end
end
- it 'returns success on POST' do
- authorized_members.each do |authorized_member|
- sign_in(authorized_member)
+ context 'user has three gcp_projects' do
+ before do
+ allow_next_instance_of(GoogleApi::CloudPlatform::Client) do |client|
+ mock_service_account = Struct.new(:project_id, :unique_id, :email).new(123, 456, 'em@ai.l')
+ allow(client).to receive(:list_projects).and_return([{}, {}, {}])
+ allow(client).to receive(:validate_token).and_return(true)
+ allow(client).to receive(:create_service_account).and_return(mock_service_account)
+ allow(client).to receive(:create_service_account_key).and_return({})
+ allow(client).to receive(:grant_service_account_roles)
+ end
+ end
- post url, params: { gcp_project: 'prj1', environment: 'env1' }
+ it 'returns success on GET' do
+ authorized_members.each do |authorized_member|
+ allow_next_instance_of(BranchesFinder) do |branches_finder|
+ allow(branches_finder).to receive(:execute).and_return([])
+ end
+
+ allow_next_instance_of(TagsFinder) do |branches_finder|
+ allow(branches_finder).to receive(:execute).and_return([])
+ end
+
+ sign_in(authorized_member)
+
+ get url
+
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+ end
+
+ it 'returns success on POST' do
+ authorized_members.each do |authorized_member|
+ sign_in(authorized_member)
+
+ post url, params: { gcp_project: 'prj1', ref: 'env1' }
- expect(response).to redirect_to(project_google_cloud_index_path(project))
+ expect(response).to redirect_to(project_google_cloud_index_path(project))
+ end
end
end
end
diff --git a/spec/requests/projects/google_cloud_controller_spec.rb b/spec/requests/projects/google_cloud_controller_spec.rb
index 37682152994..d0814990989 100644
--- a/spec/requests/projects/google_cloud_controller_spec.rb
+++ b/spec/requests/projects/google_cloud_controller_spec.rb
@@ -8,7 +8,7 @@ MockGoogleOAuth2Credentials = Struct.new(:app_id, :app_secret)
RSpec.describe Projects::GoogleCloudController do
let_it_be(:project) { create(:project, :public) }
- describe 'GET index' do
+ describe 'GET index', :snowplow do
let_it_be(:url) { "#{project_google_cloud_index_path(project)}" }
context 'when a public request is made' do
@@ -16,6 +16,13 @@ RSpec.describe Projects::GoogleCloudController do
get url
expect(response).to have_gitlab_http_status(:not_found)
+ expect_snowplow_event(
+ category: 'Projects::GoogleCloud',
+ action: 'admin_project_google_cloud!',
+ label: 'access_denied',
+ property: 'invalid_user',
+ project: project,
+ user: nil)
end
end
@@ -29,6 +36,14 @@ RSpec.describe Projects::GoogleCloudController do
get url
expect(response).to have_gitlab_http_status(:not_found)
+ expect_snowplow_event(
+ category: 'Projects::GoogleCloud',
+ action: 'admin_project_google_cloud!',
+ label: 'access_denied',
+ property: 'invalid_user',
+ project: project,
+ user: user
+ )
end
end
@@ -42,6 +57,14 @@ RSpec.describe Projects::GoogleCloudController do
get url
expect(response).to have_gitlab_http_status(:not_found)
+ expect_snowplow_event(
+ category: 'Projects::GoogleCloud',
+ action: 'admin_project_google_cloud!',
+ label: 'access_denied',
+ property: 'invalid_user',
+ project: project,
+ user: user
+ )
end
end
@@ -74,19 +97,26 @@ RSpec.describe Projects::GoogleCloudController do
let(:user) { project.creator }
context 'but gitlab instance is not configured for google oauth2' do
- before do
+ it 'returns forbidden' do
unconfigured_google_oauth2 = MockGoogleOAuth2Credentials.new('', '')
allow(Gitlab::Auth::OAuth::Provider).to receive(:config_for)
.with('google_oauth2')
.and_return(unconfigured_google_oauth2)
- end
- it 'returns forbidden' do
sign_in(user)
get url
expect(response).to have_gitlab_http_status(:forbidden)
+ expect_snowplow_event(
+ category: 'Projects::GoogleCloud',
+ action: 'google_oauth2_enabled!',
+ label: 'access_denied',
+ extra: { reason: 'google_oauth2_not_configured',
+ config: unconfigured_google_oauth2 },
+ project: project,
+ user: user
+ )
end
end
@@ -101,6 +131,46 @@ RSpec.describe Projects::GoogleCloudController do
get url
expect(response).to have_gitlab_http_status(:not_found)
+ expect_snowplow_event(
+ category: 'Projects::GoogleCloud',
+ action: 'feature_flag_enabled!',
+ label: 'access_denied',
+ property: 'feature_flag_not_enabled',
+ project: project,
+ user: user
+ )
+ end
+ end
+
+ context 'but google oauth2 token is not valid' do
+ it 'does not return revoke oauth url' do
+ allow_next_instance_of(GoogleApi::CloudPlatform::Client) do |client|
+ allow(client).to receive(:validate_token).and_return(false)
+ end
+
+ sign_in(user)
+
+ get url
+
+ expect(response).to be_successful
+ expect_snowplow_event(
+ category: 'Projects::GoogleCloud',
+ action: 'google_cloud#index',
+ label: 'index',
+ extra: {
+ screen: 'home',
+ serviceAccounts: [],
+ createServiceAccountUrl: project_google_cloud_service_accounts_path(project),
+ enableCloudRunUrl: project_google_cloud_deployments_cloud_run_path(project),
+ enableCloudStorageUrl: project_google_cloud_deployments_cloud_storage_path(project),
+ emptyIllustrationUrl: ActionController::Base.helpers.image_path('illustrations/pipelines_empty.svg'),
+ configureGcpRegionsUrl: project_google_cloud_gcp_regions_path(project),
+ gcpRegions: [],
+ revokeOauthUrl: nil
+ },
+ project: project,
+ user: user
+ )
end
end
end
diff --git a/spec/requests/projects/harbor/repositories_controller_spec.rb b/spec/requests/projects/harbor/repositories_controller_spec.rb
new file mode 100644
index 00000000000..cdb5a696d7e
--- /dev/null
+++ b/spec/requests/projects/harbor/repositories_controller_spec.rb
@@ -0,0 +1,69 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Projects::Harbor::RepositoriesController do
+ let_it_be(:project, reload: true) { create(:project) }
+ let_it_be(:user) { create(:user) }
+
+ shared_examples 'responds with 404 status' do
+ it 'returns 404' do
+ subject
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+
+ shared_examples 'responds with 200 status' do
+ it 'renders the index template' do
+ subject
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(response).to render_template(:index)
+ end
+ end
+
+ before do
+ stub_feature_flags(harbor_registry_integration: true)
+ project.add_developer(user)
+ sign_in(user)
+ end
+
+ describe 'GET #index' do
+ subject do
+ get project_harbor_registry_index_path(project)
+ response
+ end
+
+ context 'with harbor registry feature flag enabled' do
+ it_behaves_like 'responds with 200 status'
+ end
+
+ context 'with harbor registry feature flag disabled' do
+ before do
+ stub_feature_flags(harbor_registry_integration: false)
+ end
+
+ it_behaves_like 'responds with 404 status'
+ end
+ end
+
+ describe 'GET #show' do
+ subject do
+ get project_harbor_registry_path(project, 1)
+ response
+ end
+
+ context 'with harbor registry feature flag enabled' do
+ it_behaves_like 'responds with 200 status'
+ end
+
+ context 'with harbor registry feature flag disabled' do
+ before do
+ stub_feature_flags(harbor_registry_integration: false)
+ end
+
+ it_behaves_like 'responds with 404 status'
+ end
+ end
+end
diff --git a/spec/requests/projects/redirect_controller_spec.rb b/spec/requests/projects/redirect_controller_spec.rb
new file mode 100644
index 00000000000..3bbca3ca32b
--- /dev/null
+++ b/spec/requests/projects/redirect_controller_spec.rb
@@ -0,0 +1,66 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe "Projects::RedirectController requests" do
+ using RSpec::Parameterized::TableSyntax
+
+ let_it_be(:private_project) { create(:project, :private) }
+ let_it_be(:public_project) { create(:project, :public) }
+ let_it_be(:user) { create(:user) }
+
+ before_all do
+ private_project.add_developer(user)
+ end
+
+ describe 'GET redirect_from_id' do
+ where(:authenticated, :project, :is_found) do
+ true | ref(:private_project) | true
+ false | ref(:private_project) | false
+ true | ref(:public_project) | true
+ false | ref(:public_project) | true
+ true | build(:project, id: 0) | false
+ end
+
+ with_them do
+ before do
+ sign_in(user) if authenticated
+
+ get "/projects/#{project.id}"
+ end
+
+ if params[:is_found]
+ it 'redirects to the project page' do
+ expect(response).to have_gitlab_http_status(:found)
+ expect(response).to redirect_to(project_path(project))
+ end
+ else
+ it 'gives 404' do
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+ end
+ end
+
+ # This is a regression test for https://gitlab.com/gitlab-org/gitlab/-/issues/351058
+ context 'with sourcegraph enabled' do
+ let_it_be(:sourcegraph_url) { 'https://sourcegraph.test' }
+
+ before do
+ allow(Gitlab::CurrentSettings).to receive(:sourcegraph_url).and_return(sourcegraph_url)
+ allow(Gitlab::CurrentSettings).to receive(:sourcegraph_enabled).and_return(true)
+
+ sign_in(user)
+ end
+
+ context 'with projects/:id route' do
+ subject { get "/projects/#{public_project.id}" }
+
+ it 'redirects successfully' do
+ subject
+
+ expect(response).to redirect_to(project_path(public_project))
+ end
+ end
+ end
+end
diff --git a/spec/routing/project_routing_spec.rb b/spec/routing/project_routing_spec.rb
index f3d0179ffdd..65772895826 100644
--- a/spec/routing/project_routing_spec.rb
+++ b/spec/routing/project_routing_spec.rb
@@ -70,9 +70,11 @@ RSpec.describe 'project routing' do
route_to('projects#preview_markdown', namespace_id: 'gitlab', id: 'gitlabhq')
)
end
+ end
- it 'to #resolve' do
- expect(get('/projects/1')).to route_to('projects#resolve', id: '1')
+ describe Projects::RedirectController, 'routing' do
+ it 'to #redirect_from_id' do
+ expect(get('/projects/1')).to route_to('projects/redirect#redirect_from_id', id: '1')
end
end
@@ -395,7 +397,7 @@ RSpec.describe 'project routing' do
# DELETE /:project_id/project_members/:id(.:format) project_members#destroy
describe Projects::ProjectMembersController, 'routing' do
it_behaves_like 'resource routing' do
- let(:actions) { %i[index create update destroy] }
+ let(:actions) { %i[index update destroy] }
let(:base_path) { '/gitlab/gitlabhq/-/project_members' }
end
end
@@ -680,6 +682,32 @@ RSpec.describe 'project routing' do
end
end
+ describe Projects::ReleasesController, 'routing' do
+ it 'to #latest_permalink with a valid permalink path' do
+ expect(get('/gitlab/gitlabhq/-/releases/permalink/latest/downloads/release-binary.zip')).to route_to(
+ 'projects/releases#latest_permalink',
+ namespace_id: 'gitlab',
+ project_id: 'gitlabhq',
+ suffix_path: 'downloads/release-binary.zip'
+ )
+
+ expect(get('/gitlab/gitlabhq/-/releases/permalink/latest')).to route_to(
+ 'projects/releases#latest_permalink',
+ namespace_id: 'gitlab',
+ project_id: 'gitlabhq'
+ )
+ end
+
+ it 'to #show for the release with tag named permalink' do
+ expect(get('/gitlab/gitlabhq/-/releases/permalink')).to route_to(
+ 'projects/releases#show',
+ namespace_id: 'gitlab',
+ project_id: 'gitlabhq',
+ tag: 'permalink'
+ )
+ end
+ end
+
describe Projects::Registry::TagsController, 'routing' do
describe '#destroy' do
it 'correctly routes to a destroy action' do
@@ -899,6 +927,12 @@ RSpec.describe 'project routing' do
end
end
+ describe Projects::Ci::SecureFilesController, 'routing' do
+ it 'to #show' do
+ expect(get('/gitlab/gitlabhq/-/ci/secure_files')).to route_to('projects/ci/secure_files#show', namespace_id: 'gitlab', project_id: 'gitlabhq')
+ end
+ end
+
context 'with a non-existent project' do
it 'routes to 404 with get request' do
expect(get: "/gitlab/not_exist").to route_to(
diff --git a/spec/rubocop/cop/database/establish_connection_spec.rb b/spec/rubocop/cop/database/establish_connection_spec.rb
index a3c27d33cb0..3919872b5e7 100644
--- a/spec/rubocop/cop/database/establish_connection_spec.rb
+++ b/spec/rubocop/cop/database/establish_connection_spec.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-require 'spec_helper'
+require 'fast_spec_helper'
require_relative '../../../../rubocop/cop/database/establish_connection'
RSpec.describe RuboCop::Cop::Database::EstablishConnection do
diff --git a/spec/rubocop/cop/database/multiple_databases_spec.rb b/spec/rubocop/cop/database/multiple_databases_spec.rb
index 16b916d61db..8bcd4710305 100644
--- a/spec/rubocop/cop/database/multiple_databases_spec.rb
+++ b/spec/rubocop/cop/database/multiple_databases_spec.rb
@@ -12,4 +12,14 @@ RSpec.describe RuboCop::Cop::Database::MultipleDatabases do
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not use methods from ActiveRecord::Base, [...]
SOURCE
end
+
+ described_class::ALLOWED_METHODS.each do |method_name|
+ it "does not flag use of ActiveRecord::Base.#{method_name}" do
+ expect_no_offenses(<<~SOURCE)
+ ActiveRecord::Base.#{method_name} do
+ Project.save
+ end
+ SOURCE
+ end
+ end
end
diff --git a/spec/rubocop/cop/graphql/graphql_name_position_spec.rb b/spec/rubocop/cop/graphql/graphql_name_position_spec.rb
new file mode 100644
index 00000000000..42cc398ed84
--- /dev/null
+++ b/spec/rubocop/cop/graphql/graphql_name_position_spec.rb
@@ -0,0 +1,44 @@
+# frozen_string_literal: true
+
+require 'fast_spec_helper'
+
+require_relative '../../../../rubocop/cop/graphql/graphql_name_position'
+
+RSpec.describe RuboCop::Cop::Graphql::GraphqlNamePosition do
+ subject(:cop) { described_class.new }
+
+ it 'adds an offense when graphql_name is not on the first line' do
+ expect_offense(<<~TYPE)
+ module Types
+ class AType < BaseObject
+ ^^^^^^^^^^^^^^^^^^^^^^^^ `graphql_name` should be the first line of the class: https://docs.gitlab.com/ee/development/api_graphql_styleguide.html#naming-conventions
+ field :a_thing
+ field :another_thing
+ graphql_name 'ATypeName'
+ end
+ end
+ TYPE
+ end
+
+ it 'does not add an offense for classes that have no call to graphql_name' do
+ expect_no_offenses(<<~TYPE.strip)
+ module Types
+ class AType < BaseObject
+ authorize :an_ability, :second_ability
+
+ field :a_thing
+ end
+ end
+ TYPE
+ end
+
+ it 'does not add an offense for classes that only call graphql_name' do
+ expect_no_offenses(<<~TYPE.strip)
+ module Types
+ class AType < BaseObject
+ graphql_name 'ATypeName'
+ end
+ end
+ TYPE
+ end
+end
diff --git a/spec/rubocop/formatter/todo_formatter_spec.rb b/spec/rubocop/formatter/todo_formatter_spec.rb
new file mode 100644
index 00000000000..e1b1de33bfe
--- /dev/null
+++ b/spec/rubocop/formatter/todo_formatter_spec.rb
@@ -0,0 +1,284 @@
+# frozen_string_literal: true
+# rubocop:disable RSpec/VerifiedDoubles
+
+require 'fast_spec_helper'
+require 'stringio'
+require 'fileutils'
+
+require_relative '../../../rubocop/formatter/todo_formatter'
+require_relative '../../../rubocop/todo_dir'
+
+RSpec.describe RuboCop::Formatter::TodoFormatter do
+ let(:stdout) { StringIO.new }
+ let(:tmp_dir) { Dir.mktmpdir }
+ let(:real_tmp_dir) { File.join(tmp_dir, 'real') }
+ let(:symlink_tmp_dir) { File.join(tmp_dir, 'symlink') }
+ let(:rubocop_todo_dir) { "#{symlink_tmp_dir}/.rubocop_todo" }
+ let(:options) { { rubocop_todo_dir: rubocop_todo_dir } }
+ let(:todo_dir) { RuboCop::TodoDir.new(rubocop_todo_dir) }
+
+ subject(:formatter) { described_class.new(stdout, options) }
+
+ around do |example|
+ FileUtils.mkdir(real_tmp_dir)
+ FileUtils.symlink(real_tmp_dir, symlink_tmp_dir)
+
+ Dir.chdir(symlink_tmp_dir) do
+ example.run
+ end
+ end
+
+ after do
+ FileUtils.remove_entry(tmp_dir)
+ end
+
+ context 'with offenses detected' do
+ let(:offense) { fake_offense('A/Offense') }
+ let(:offense_too_many) { fake_offense('B/TooManyOffenses') }
+ let(:offense_autocorrect) { fake_offense('B/AutoCorrect') }
+
+ before do
+ stub_const("#{described_class}::MAX_OFFENSE_COUNT", 1)
+
+ stub_rubocop_registry(
+ 'A/Offense' => { autocorrectable: false },
+ 'B/AutoCorrect' => { autocorrectable: true }
+ )
+ end
+
+ def run_formatter
+ formatter.started(%w[a.rb b.rb c.rb d.rb])
+ formatter.file_finished('c.rb', [offense_too_many])
+ formatter.file_finished('a.rb', [offense_too_many, offense, offense_too_many])
+ formatter.file_finished('b.rb', [])
+ formatter.file_finished('d.rb', [offense_autocorrect])
+ formatter.finished(%w[a.rb b.rb c.rb d.rb])
+ end
+
+ it 'outputs its actions' do
+ run_formatter
+
+ expect(stdout.string).to eq(<<~OUTPUT)
+ Written to .rubocop_todo/a/offense.yml
+ Written to .rubocop_todo/b/auto_correct.yml
+ Written to .rubocop_todo/b/too_many_offenses.yml
+ OUTPUT
+ end
+
+ it 'creates YAML files', :aggregate_failures do
+ run_formatter
+
+ expect(rubocop_todo_dir_listing).to contain_exactly(
+ 'a/offense.yml', 'b/auto_correct.yml', 'b/too_many_offenses.yml'
+ )
+
+ expect(todo_yml('A/Offense')).to eq(<<~YAML)
+ ---
+ A/Offense:
+ Exclude:
+ - 'a.rb'
+ YAML
+
+ expect(todo_yml('B/AutoCorrect')).to eq(<<~YAML)
+ ---
+ # Cop supports --auto-correct.
+ B/AutoCorrect:
+ Exclude:
+ - 'd.rb'
+ YAML
+
+ expect(todo_yml('B/TooManyOffenses')).to eq(<<~YAML)
+ ---
+ B/TooManyOffenses:
+ Exclude:
+ - 'a.rb'
+ - 'c.rb'
+ YAML
+ end
+
+ context 'when cop previously not explicitly disabled' do
+ before do
+ todo_dir.write('B/TooManyOffenses', <<~YAML)
+ ---
+ B/TooManyOffenses:
+ Exclude:
+ - 'x.rb'
+ YAML
+ end
+
+ it 'does not disable cop' do
+ run_formatter
+
+ expect(todo_yml('B/TooManyOffenses')).to eq(<<~YAML)
+ ---
+ B/TooManyOffenses:
+ Exclude:
+ - 'a.rb'
+ - 'c.rb'
+ YAML
+ end
+ end
+
+ context 'when cop previously explicitly disabled in rubocop_todo/' do
+ before do
+ todo_dir.write('B/TooManyOffenses', <<~YAML)
+ ---
+ B/TooManyOffenses:
+ Enabled: false
+ Exclude:
+ - 'x.rb'
+ YAML
+
+ todo_dir.inspect_all
+ end
+
+ it 'keeps cop disabled' do
+ run_formatter
+
+ expect(todo_yml('B/TooManyOffenses')).to eq(<<~YAML)
+ ---
+ B/TooManyOffenses:
+ # Offense count: 3
+ # Temporarily disabled due to too many offenses
+ Enabled: false
+ Exclude:
+ - 'a.rb'
+ - 'c.rb'
+ YAML
+ end
+ end
+
+ context 'when cop previously explicitly disabled in rubocop_todo.yml' do
+ before do
+ File.write('.rubocop_todo.yml', <<~YAML)
+ ---
+ B/TooManyOffenses:
+ Enabled: false
+ Exclude:
+ - 'x.rb'
+ YAML
+ end
+
+ it 'keeps cop disabled' do
+ run_formatter
+
+ expect(todo_yml('B/TooManyOffenses')).to eq(<<~YAML)
+ ---
+ B/TooManyOffenses:
+ # Offense count: 3
+ # Temporarily disabled due to too many offenses
+ Enabled: false
+ Exclude:
+ - 'a.rb'
+ - 'c.rb'
+ YAML
+ end
+ end
+
+ context 'with cop configuration in both .rubocop_todo/ and .rubocop_todo.yml' do
+ before do
+ todo_dir.write('B/TooManyOffenses', <<~YAML)
+ ---
+ B/TooManyOffenses:
+ Exclude:
+ - 'a.rb'
+ YAML
+
+ todo_dir.write('A/Offense', <<~YAML)
+ ---
+ A/Offense:
+ Exclude:
+ - 'a.rb'
+ YAML
+
+ todo_dir.inspect_all
+
+ File.write('.rubocop_todo.yml', <<~YAML)
+ ---
+ B/TooManyOffenses:
+ Exclude:
+ - 'x.rb'
+ A/Offense:
+ Exclude:
+ - 'y.rb'
+ YAML
+ end
+
+ it 'raises an error' do
+ expect { run_formatter }.to raise_error(RuntimeError, <<~TXT)
+ Multiple configurations found for cops:
+ - A/Offense
+ - B/TooManyOffenses
+ TXT
+ end
+ end
+ end
+
+ context 'without offenses detected' do
+ before do
+ formatter.started(%w[a.rb b.rb])
+ formatter.file_finished('a.rb', [])
+ formatter.file_finished('b.rb', [])
+ formatter.finished(%w[a.rb b.rb])
+ end
+
+ it 'does not output anything' do
+ expect(stdout.string).to eq('')
+ end
+
+ it 'does not write any YAML files' do
+ expect(rubocop_todo_dir_listing).to be_empty
+ end
+ end
+
+ context 'without files to inspect' do
+ before do
+ formatter.started([])
+ formatter.finished([])
+ end
+
+ it 'does not output anything' do
+ expect(stdout.string).to eq('')
+ end
+
+ it 'does not write any YAML files' do
+ expect(rubocop_todo_dir_listing).to be_empty
+ end
+ end
+
+ private
+
+ def rubocop_todo_dir_listing
+ Dir.glob("#{rubocop_todo_dir}/**/*")
+ .select { |path| File.file?(path) }
+ .map { |path| path.delete_prefix("#{rubocop_todo_dir}/") }
+ end
+
+ def todo_yml(cop_name)
+ todo_dir.read(cop_name)
+ end
+
+ def fake_offense(cop_name)
+ double(:offense, cop_name: cop_name)
+ end
+
+ def stub_rubocop_registry(**cops)
+ rubocop_registry = double(:rubocop_registry)
+
+ allow(RuboCop::Cop::Registry).to receive(:global).and_return(rubocop_registry)
+
+ allow(rubocop_registry).to receive(:find_by_cop_name)
+ .with(String).and_return(nil)
+
+ cops.each do |cop_name, attributes|
+ allow(rubocop_registry).to receive(:find_by_cop_name)
+ .with(cop_name).and_return(fake_cop(**attributes))
+ end
+ end
+
+ def fake_cop(autocorrectable:)
+ double(:cop, support_autocorrect?: autocorrectable)
+ end
+end
+
+# rubocop:enable RSpec/VerifiedDoubles
diff --git a/spec/rubocop/todo_dir_spec.rb b/spec/rubocop/todo_dir_spec.rb
new file mode 100644
index 00000000000..ae59def885d
--- /dev/null
+++ b/spec/rubocop/todo_dir_spec.rb
@@ -0,0 +1,218 @@
+# frozen_string_literal: true
+
+require 'fast_spec_helper'
+require 'fileutils'
+require 'active_support/inflector/inflections'
+
+require_relative '../../rubocop/todo_dir'
+
+RSpec.describe RuboCop::TodoDir do
+ let(:todo_dir) { described_class.new(directory) }
+ let(:directory) { Dir.mktmpdir }
+ let(:cop_name) { 'RSpec/VariableInstance' }
+ let(:cop_name_underscore) { ActiveSupport::Inflector.underscore(cop_name) }
+ let(:yaml_path) { "#{File.join(directory, cop_name_underscore)}.yml" }
+
+ around do |example|
+ Dir.chdir(directory) do
+ example.run
+ end
+ end
+
+ after do
+ FileUtils.remove_entry(directory)
+ end
+
+ describe '#initialize' do
+ context 'when passing inflector' do
+ let(:fake_inflector) { double(:inflector) } # rubocop:disable RSpec/VerifiedDoubles
+ let(:todo_dir) { described_class.new(directory, inflector: fake_inflector) }
+
+ before do
+ allow(fake_inflector).to receive(:underscore)
+ .with(cop_name)
+ .and_return(cop_name_underscore)
+ end
+
+ it 'calls .underscore' do
+ todo_dir.write(cop_name, 'a')
+
+ expect(fake_inflector).to have_received(:underscore)
+ end
+ end
+ end
+
+ describe '#directory' do
+ subject { todo_dir.directory }
+
+ it { is_expected.to eq(directory) }
+ end
+
+ describe '#read' do
+ let(:content) { 'a' }
+
+ subject { todo_dir.read(cop_name) }
+
+ context 'when file exists' do
+ before do
+ todo_dir.write(cop_name, content)
+ end
+
+ it { is_expected.to eq(content) }
+ end
+
+ context 'when file is missing' do
+ it { is_expected.to be_nil }
+ end
+ end
+
+ describe '#write' do
+ let(:content) { 'a' }
+
+ subject { todo_dir.write(cop_name, content) }
+
+ it { is_expected.to eq(yaml_path) }
+
+ it 'writes content to YAML file' do
+ subject
+
+ expect(File.read(yaml_path)).to eq(content)
+ end
+ end
+
+ describe '#inspect' do
+ subject { todo_dir.inspect(cop_name) }
+
+ context 'with existing YAML file' do
+ before do
+ todo_dir.write(cop_name, 'a')
+ end
+
+ it { is_expected.to eq(true) }
+
+ it 'moves YAML file to .inspect' do
+ subject
+
+ expect(File).not_to exist(yaml_path)
+ expect(File).to exist("#{yaml_path}.inspect")
+ end
+ end
+
+ context 'with missing YAML file' do
+ it { is_expected.to eq(false) }
+ end
+ end
+
+ describe '#inspect_all' do
+ subject { todo_dir.inspect_all }
+
+ context 'with YAML files' do
+ before do
+ todo_dir.write(cop_name, 'a')
+ todo_dir.write('Other/Rule', 'a')
+ todo_dir.write('Very/Nested/Rule', 'a')
+ end
+
+ it { is_expected.to eq(3) }
+
+ it 'moves all YAML files to .inspect' do
+ subject
+
+ expect(Dir.glob('**/*.yml')).to be_empty
+ expect(Dir.glob('**/*.yml.inspect').size).to eq(3)
+ end
+ end
+
+ context 'with non-YAML files' do
+ before do
+ File.write('file', 'a')
+ File.write('file.txt', 'a')
+ File.write('file.yaml', 'a') # not .yml
+ end
+
+ it { is_expected.to eq(0) }
+
+ it 'does not move non-YAML files' do
+ subject
+
+ expect(Dir.glob('**/*'))
+ .to contain_exactly('file', 'file.txt', 'file.yaml')
+ end
+ end
+
+ context 'without files' do
+ it { is_expected.to eq(0) }
+ end
+ end
+
+ describe '#list_inspect' do
+ let(:content) { 'a' }
+
+ subject { todo_dir.list_inspect }
+
+ context 'when file exists and is being inspected' do
+ before do
+ todo_dir.write(cop_name, content)
+ todo_dir.inspect_all
+ end
+
+ it do
+ is_expected.to contain_exactly("#{yaml_path}.inspect")
+ end
+ end
+
+ context 'when file exists but not being inspected' do
+ before do
+ todo_dir.write(cop_name, content)
+ end
+
+ it { is_expected.to be_empty }
+ end
+
+ context 'when file is missing' do
+ it { is_expected.to be_empty }
+ end
+ end
+
+ describe '#delete_inspected' do
+ subject { todo_dir.delete_inspected }
+
+ context 'with YAML files' do
+ before do
+ todo_dir.write(cop_name, 'a')
+ todo_dir.write('Other/Rule', 'a')
+ todo_dir.write('Very/Nested/Rule', 'a')
+ todo_dir.inspect_all
+ end
+
+ it { is_expected.to eq(3) }
+
+ it 'deletes all .inspected YAML files' do
+ subject
+
+ expect(Dir.glob('**/*.yml.inspect')).to be_empty
+ end
+ end
+
+ context 'with non-YAML files' do
+ before do
+ File.write('file.inspect', 'a')
+ File.write('file.txt.inspect', 'a')
+ File.write('file.yaml.inspect', 'a') # not .yml
+ end
+
+ it { is_expected.to eq(0) }
+
+ it 'does not delete non-YAML files' do
+ subject
+
+ expect(Dir.glob('**/*')).to contain_exactly(
+ 'file.inspect', 'file.txt.inspect', 'file.yaml.inspect')
+ end
+ end
+
+ context 'without files' do
+ it { is_expected.to eq(0) }
+ end
+ end
+end
diff --git a/spec/serializers/ci/pipeline_entity_spec.rb b/spec/serializers/ci/pipeline_entity_spec.rb
index 4d9ed9fc22f..808dc38f653 100644
--- a/spec/serializers/ci/pipeline_entity_spec.rb
+++ b/spec/serializers/ci/pipeline_entity_spec.rb
@@ -224,7 +224,8 @@ RSpec.describe Ci::PipelineEntity do
end
it 'makes atached flag true' do
- expect(subject[:flags][:merge_request_pipeline]).to be_truthy
+ expect(subject[:flags][:merge_request_pipeline]).to be true
+ expect(subject[:flags][:merge_request]).to be true
end
it 'exposes source sha and target sha' do
diff --git a/spec/serializers/cluster_error_entity_spec.rb b/spec/serializers/cluster_error_entity_spec.rb
deleted file mode 100644
index 43ec41adf14..00000000000
--- a/spec/serializers/cluster_error_entity_spec.rb
+++ /dev/null
@@ -1,35 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe ClusterErrorEntity do
- describe '#as_json' do
- let(:cluster) { create(:cluster, :provided_by_user, :group) }
-
- subject { described_class.new(cluster).as_json }
-
- context 'when connection_error is present' do
- before do
- allow(cluster).to receive(:connection_error).and_return(:connection_error)
- end
-
- it { is_expected.to eq({ connection_error: :connection_error, metrics_connection_error: nil, node_connection_error: nil }) }
- end
-
- context 'when metrics_connection_error is present' do
- before do
- allow(cluster).to receive(:metrics_connection_error).and_return(:http_error)
- end
-
- it { is_expected.to eq({ connection_error: nil, metrics_connection_error: :http_error, node_connection_error: nil }) }
- end
-
- context 'when node_connection_error is present' do
- before do
- allow(cluster).to receive(:node_connection_error).and_return(:unknown_error)
- end
-
- it { is_expected.to eq({ connection_error: nil, metrics_connection_error: nil, node_connection_error: :unknown_error }) }
- end
- end
-end
diff --git a/spec/serializers/clusters/kubernetes_error_entity_spec.rb b/spec/serializers/clusters/kubernetes_error_entity_spec.rb
new file mode 100644
index 00000000000..1464e696c48
--- /dev/null
+++ b/spec/serializers/clusters/kubernetes_error_entity_spec.rb
@@ -0,0 +1,35 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Clusters::KubernetesErrorEntity do
+ describe '#as_json' do
+ let(:cluster) { create(:cluster, :provided_by_user, :group) }
+
+ subject { described_class.new(cluster).as_json }
+
+ context 'when connection_error is present' do
+ before do
+ allow(cluster).to receive(:connection_error).and_return(:connection_error)
+ end
+
+ it { is_expected.to eq({ connection_error: :connection_error, metrics_connection_error: nil, node_connection_error: nil }) }
+ end
+
+ context 'when metrics_connection_error is present' do
+ before do
+ allow(cluster).to receive(:metrics_connection_error).and_return(:http_error)
+ end
+
+ it { is_expected.to eq({ connection_error: nil, metrics_connection_error: :http_error, node_connection_error: nil }) }
+ end
+
+ context 'when node_connection_error is present' do
+ before do
+ allow(cluster).to receive(:node_connection_error).and_return(:unknown_error)
+ end
+
+ it { is_expected.to eq({ connection_error: nil, metrics_connection_error: nil, node_connection_error: :unknown_error }) }
+ end
+ end
+end
diff --git a/spec/serializers/environment_entity_spec.rb b/spec/serializers/environment_entity_spec.rb
index a6101f825e9..a59107ad309 100644
--- a/spec/serializers/environment_entity_spec.rb
+++ b/spec/serializers/environment_entity_spec.rb
@@ -31,7 +31,7 @@ RSpec.describe EnvironmentEntity do
end
it 'exposes core elements of environment' do
- expect(subject).to include(:id, :global_id, :name, :state, :environment_path)
+ expect(subject).to include(:id, :global_id, :name, :state, :environment_path, :tier)
end
it 'exposes folder path' do
diff --git a/spec/serializers/environment_serializer_spec.rb b/spec/serializers/environment_serializer_spec.rb
index 658062c9461..ec0dd735755 100644
--- a/spec/serializers/environment_serializer_spec.rb
+++ b/spec/serializers/environment_serializer_spec.rb
@@ -204,6 +204,25 @@ RSpec.describe EnvironmentSerializer do
json
end
+
+ # Validates possible bug that can arise when order_by is not honoured in the preloader.
+ # See: https://gitlab.com/gitlab-org/gitlab/-/issues/353966#note_861381504
+ it 'fetches the last and upcoming deployment correctly' do
+ last_deployment = nil
+ upcoming_deployment = nil
+ create(:environment, project: project).tap do |environment|
+ create(:deployment, :success, environment: environment, project: project)
+ last_deployment = create(:deployment, :success, environment: environment, project: project)
+
+ create(:deployment, :running, environment: environment, project: project)
+ upcoming_deployment = create(:deployment, :running, environment: environment, project: project)
+ end
+
+ response_json = json
+
+ expect(response_json.last[:last_deployment][:id]).to eq(last_deployment.id)
+ expect(response_json.last[:upcoming_deployment][:id]).to eq(upcoming_deployment.id)
+ end
end
def create_environment_with_associations(project)
diff --git a/spec/serializers/fork_namespace_entity_spec.rb b/spec/serializers/fork_namespace_entity_spec.rb
index 32223b0d41a..91c59c4bda8 100644
--- a/spec/serializers/fork_namespace_entity_spec.rb
+++ b/spec/serializers/fork_namespace_entity_spec.rb
@@ -59,26 +59,4 @@ RSpec.describe ForkNamespaceEntity do
it 'exposes human readable permission level' do
expect(json[:permission]).to eql 'Developer'
end
-
- it 'exposes can_create_project' do
- expect(json[:can_create_project]).to be true
- end
-
- context 'when fork_project_form feature flag is disabled' do
- before do
- stub_feature_flags(fork_project_form: false)
- end
-
- it 'sets can_create_project to true when user can create projects in namespace' do
- allow(user).to receive(:can?).with(:create_projects, namespace).and_return(true)
-
- expect(json[:can_create_project]).to be true
- end
-
- it 'sets can_create_project to false when user is not allowed create projects in namespace' do
- allow(user).to receive(:can?).with(:create_projects, namespace).and_return(false)
-
- expect(json[:can_create_project]).to be false
- end
- end
end
diff --git a/spec/serializers/issue_sidebar_basic_entity_spec.rb b/spec/serializers/issue_sidebar_basic_entity_spec.rb
index da07290f349..716c97f72af 100644
--- a/spec/serializers/issue_sidebar_basic_entity_spec.rb
+++ b/spec/serializers/issue_sidebar_basic_entity_spec.rb
@@ -3,9 +3,10 @@
require 'spec_helper'
RSpec.describe IssueSidebarBasicEntity do
- let_it_be(:project) { create(:project, :repository) }
+ let_it_be(:group) { create(:group, :crm_enabled) }
+ let_it_be(:project) { create(:project, :repository, group: group) }
let_it_be(:user) { create(:user, developer_projects: [project]) }
- let_it_be(:issue) { create(:issue, project: project, assignees: [user]) }
+ let_it_be_with_reload(:issue) { create(:issue, project: project, assignees: [user]) }
let(:serializer) { IssueSerializer.new(current_user: user, project: project) }
@@ -71,4 +72,27 @@ RSpec.describe IssueSidebarBasicEntity do
end
end
end
+
+ describe 'show_crm_contacts' do
+ using RSpec::Parameterized::TableSyntax
+
+ where(:is_reporter, :contacts_exist_for_group, :expected) do
+ false | false | false
+ false | true | false
+ true | false | false
+ true | true | true
+ end
+
+ with_them do
+ it 'sets proper boolean value for show_crm_contacts' do
+ allow(CustomerRelations::Contact).to receive(:exists_for_group?).with(group).and_return(contacts_exist_for_group)
+
+ if is_reporter
+ project.root_ancestor.add_reporter(user)
+ end
+
+ expect(entity[:show_crm_contacts]).to be(expected)
+ end
+ end
+ end
end
diff --git a/spec/serializers/label_serializer_spec.rb b/spec/serializers/label_serializer_spec.rb
index 40249450f7f..05c74fca8a8 100644
--- a/spec/serializers/label_serializer_spec.rb
+++ b/spec/serializers/label_serializer_spec.rb
@@ -40,7 +40,7 @@ RSpec.describe LabelSerializer do
expect(subject.keys).to eq([:id, :title, :color, :project_id, :text_color])
expect(subject[:id]).to eq(resource.id)
expect(subject[:title]).to eq(resource.title)
- expect(subject[:color]).to eq(resource.color)
+ expect(subject[:color]).to be_color(resource.color)
expect(subject[:text_color]).to eq(resource.text_color)
expect(subject[:project_id]).to eq(resource.project_id)
end
diff --git a/spec/serializers/merge_request_widget_entity_spec.rb b/spec/serializers/merge_request_widget_entity_spec.rb
index 1712df6266c..f0779f1c57c 100644
--- a/spec/serializers/merge_request_widget_entity_spec.rb
+++ b/spec/serializers/merge_request_widget_entity_spec.rb
@@ -59,7 +59,7 @@ RSpec.describe MergeRequestWidgetEntity do
data = described_class.new(resource, request: request, issues_links: true).as_json
expect(data).to include(:issues_links)
- expect(data[:issues_links]).to include(:assign_to_closing, :closing, :mentioned_but_not_closing, :closing_count, :mentioned_count)
+ expect(data[:issues_links]).to include(:assign_to_closing, :assign_to_closing_count, :closing, :mentioned_but_not_closing, :closing_count, :mentioned_count)
end
it 'omits issue links by default' do
diff --git a/spec/serializers/pipeline_details_entity_spec.rb b/spec/serializers/pipeline_details_entity_spec.rb
index 128f1922887..67f8860ed4a 100644
--- a/spec/serializers/pipeline_details_entity_spec.rb
+++ b/spec/serializers/pipeline_details_entity_spec.rb
@@ -70,20 +70,6 @@ RSpec.describe PipelineDetailsEntity do
expect(subject[:flags][:retryable]).to eq false
end
end
-
- it 'does not contain code_quality_build_path in details' do
- expect(subject[:details]).not_to include :code_quality_build_path
- end
-
- context 'when option code_quality_walkthrough is set and pipeline is a success' do
- let(:entity) do
- described_class.represent(pipeline, request: request, code_quality_walkthrough: true)
- end
-
- it 'contains details.code_quality_build_path' do
- expect(subject[:details]).to include :code_quality_build_path
- end
- end
end
context 'when pipeline is cancelable' do
diff --git a/spec/serializers/service_event_entity_spec.rb b/spec/serializers/service_event_entity_spec.rb
index f610c8f1488..db82e84fcf8 100644
--- a/spec/serializers/service_event_entity_spec.rb
+++ b/spec/serializers/service_event_entity_spec.rb
@@ -19,7 +19,7 @@ RSpec.describe ServiceEventEntity do
it 'exposes correct attributes' do
expect(subject[:description]).to eq('Trigger event for pushes to the repository.')
expect(subject[:name]).to eq('push_events')
- expect(subject[:title]).to eq('push')
+ expect(subject[:title]).to eq('Push')
expect(subject[:value]).to be(true)
end
end
@@ -31,7 +31,7 @@ RSpec.describe ServiceEventEntity do
it 'exposes correct attributes' do
expect(subject[:description]).to eq('Trigger event for new comments.')
expect(subject[:name]).to eq('note_events')
- expect(subject[:title]).to eq('note')
+ expect(subject[:title]).to eq('Note')
expect(subject[:value]).to eq(false)
expect(subject[:field][:name]).to eq('note_channel')
expect(subject[:field][:value]).to eq('note-channel')
diff --git a/spec/serializers/service_field_entity_spec.rb b/spec/serializers/service_field_entity_spec.rb
index a06fdf95159..3a574c522b0 100644
--- a/spec/serializers/service_field_entity_spec.rb
+++ b/spec/serializers/service_field_entity_spec.rb
@@ -20,6 +20,7 @@ RSpec.describe ServiceFieldEntity do
it 'exposes correct attributes' do
expected_hash = {
+ section: 'connection',
type: 'text',
name: 'username',
title: 'Username or Email',
@@ -40,6 +41,7 @@ RSpec.describe ServiceFieldEntity do
it 'exposes correct attributes but hides password' do
expected_hash = {
+ section: 'connection',
type: 'password',
name: 'password',
title: 'Enter new password or API token',
@@ -64,6 +66,7 @@ RSpec.describe ServiceFieldEntity do
it 'exposes correct attributes and casts value to Boolean' do
expected_hash = {
+ section: nil,
type: 'checkbox',
name: 'send_from_committer_email',
title: 'Send from committer',
@@ -84,6 +87,7 @@ RSpec.describe ServiceFieldEntity do
it 'exposes correct attributes' do
expected_hash = {
+ section: nil,
type: 'select',
name: 'branches_to_be_notified',
title: 'Branches for which notifications are to be sent',
diff --git a/spec/services/auth/container_registry_authentication_service_spec.rb b/spec/services/auth/container_registry_authentication_service_spec.rb
index 00841de9ff4..ba7acd3d3df 100644
--- a/spec/services/auth/container_registry_authentication_service_spec.rb
+++ b/spec/services/auth/container_registry_authentication_service_spec.rb
@@ -6,143 +6,4 @@ RSpec.describe Auth::ContainerRegistryAuthenticationService do
include AdminModeHelper
it_behaves_like 'a container registry auth service'
-
- context 'when in migration mode' do
- include_context 'container registry auth service context'
-
- let_it_be(:current_user) { create(:user) }
- let_it_be(:project) { create(:project) }
-
- before do
- project.add_developer(current_user)
- end
-
- shared_examples 'a modified token with migration eligibility' do |eligible|
- it_behaves_like 'a valid token'
- it { expect(payload['access']).to include(include('migration_eligible' => eligible)) }
- end
-
- shared_examples 'a modified token' do
- context 'with a non eligible root ancestor and project' do
- before do
- stub_feature_flags(container_registry_migration_phase1_deny: project.root_ancestor)
- stub_feature_flags(container_registry_migration_phase1_allow: false)
- end
-
- it_behaves_like 'a modified token with migration eligibility', false
- end
-
- context 'with a non eligible root ancestor and eligible project' do
- before do
- stub_feature_flags(container_registry_migration_phase1_deny: false)
- stub_feature_flags(container_registry_migration_phase1_deny: project.root_ancestor)
- stub_feature_flags(container_registry_migration_phase1_allow: project)
- end
-
- it_behaves_like 'a modified token with migration eligibility', false
- end
-
- context 'with an eligible root ancestor and non eligible project' do
- before do
- stub_feature_flags(container_registry_migration_phase1_deny: false)
- stub_feature_flags(container_registry_migration_phase1_allow: false)
- end
-
- it_behaves_like 'a modified token with migration eligibility', false
- end
-
- context 'with an eligible root ancestor and project' do
- before do
- stub_feature_flags(container_registry_migration_phase1_deny: false)
- stub_feature_flags(container_registry_migration_phase1_allow: project)
- end
-
- it_behaves_like 'a modified token with migration eligibility', true
- end
- end
-
- context 'with pull action' do
- let(:current_params) do
- { scopes: ["repository:#{project.full_path}:pull"] }
- end
-
- it_behaves_like 'a modified token'
- end
-
- context 'with push action' do
- let(:current_params) do
- { scopes: ["repository:#{project.full_path}:push"] }
- end
-
- it_behaves_like 'a modified token'
- end
-
- context 'with multiple actions' do
- let(:current_params) do
- { scopes: ["repository:#{project.full_path}:pull,push,delete"] }
- end
-
- it_behaves_like 'a modified token'
- end
-
- describe '#access_token' do
- let(:token) { described_class.access_token(%w[push], [project.full_path]) }
-
- subject { { token: token } }
-
- it_behaves_like 'a modified token'
- end
-
- context 'with a project with a path with trailing underscore' do
- let(:bad_project) { create(:project) }
-
- before do
- bad_project.update!(path: bad_project.path + '_')
- bad_project.add_developer(current_user)
- end
-
- describe '#full_access_token' do
- let(:token) { described_class.full_access_token(bad_project.full_path) }
- let(:access) do
- [{ 'type' => 'repository',
- 'name' => bad_project.full_path,
- 'actions' => ['*'],
- 'migration_eligible' => false }]
- end
-
- subject { { token: token } }
-
- it 'logs an exception and returns a valid access token' do
- expect(Gitlab::ErrorTracking).to receive(:track_and_raise_for_dev_exception)
-
- expect(token).to be_present
- expect(payload).to be_a(Hash)
- expect(payload).to include('access' => access)
- end
- end
- end
- end
-
- context 'when not in migration mode' do
- include_context 'container registry auth service context'
-
- let_it_be(:project) { create(:project) }
-
- before do
- stub_feature_flags(container_registry_migration_phase1: false)
- end
-
- shared_examples 'an unmodified token' do
- it_behaves_like 'a valid token'
- it { expect(payload['access']).not_to include(have_key('migration_eligible')) }
- end
-
- describe '#access_token' do
- let(:token) { described_class.access_token(%w[push], [project.full_path]) }
-
- subject { { token: token } }
-
- it_behaves_like 'an unmodified token'
- end
- end
end
diff --git a/spec/services/authorized_project_update/find_records_due_for_refresh_service_spec.rb b/spec/services/authorized_project_update/find_records_due_for_refresh_service_spec.rb
index c6b184bd003..691fb3f60f4 100644
--- a/spec/services/authorized_project_update/find_records_due_for_refresh_service_spec.rb
+++ b/spec/services/authorized_project_update/find_records_due_for_refresh_service_spec.rb
@@ -40,7 +40,7 @@ RSpec.describe AuthorizedProjectUpdate::FindRecordsDueForRefreshService do
it 'is called' do
ProjectAuthorization.delete_all
- expect(callback).to receive(:call).with(project.id, Gitlab::Access::MAINTAINER).once
+ expect(callback).to receive(:call).with(project.id, Gitlab::Access::OWNER).once
service.execute
end
@@ -60,20 +60,7 @@ RSpec.describe AuthorizedProjectUpdate::FindRecordsDueForRefreshService do
to_be_removed = [project2.id]
to_be_added = [
- { user_id: user.id, project_id: project.id, access_level: Gitlab::Access::MAINTAINER }
- ]
-
- expect(service.execute).to eq([to_be_removed, to_be_added])
- end
-
- it 'finds duplicate entries that has to be removed' do
- [Gitlab::Access::MAINTAINER, Gitlab::Access::REPORTER].each do |access_level|
- user.project_authorizations.create!(project: project, access_level: access_level)
- end
-
- to_be_removed = [project.id]
- to_be_added = [
- { user_id: user.id, project_id: project.id, access_level: Gitlab::Access::MAINTAINER }
+ { user_id: user.id, project_id: project.id, access_level: Gitlab::Access::OWNER }
]
expect(service.execute).to eq([to_be_removed, to_be_added])
@@ -85,7 +72,7 @@ RSpec.describe AuthorizedProjectUpdate::FindRecordsDueForRefreshService do
to_be_removed = [project.id]
to_be_added = [
- { user_id: user.id, project_id: project.id, access_level: Gitlab::Access::MAINTAINER }
+ { user_id: user.id, project_id: project.id, access_level: Gitlab::Access::OWNER }
]
expect(service.execute).to eq([to_be_removed, to_be_added])
@@ -143,16 +130,16 @@ RSpec.describe AuthorizedProjectUpdate::FindRecordsDueForRefreshService do
end
it 'sets the keys to the project IDs' do
- expect(hash.keys).to eq([project.id])
+ expect(hash.keys).to match_array([project.id])
end
it 'sets the values to the access levels' do
- expect(hash.values).to eq([Gitlab::Access::MAINTAINER])
+ expect(hash.values).to match_array([Gitlab::Access::OWNER])
end
context 'personal projects' do
it 'includes the project with the right access level' do
- expect(hash[project.id]).to eq(Gitlab::Access::MAINTAINER)
+ expect(hash[project.id]).to eq(Gitlab::Access::OWNER)
end
end
@@ -242,7 +229,7 @@ RSpec.describe AuthorizedProjectUpdate::FindRecordsDueForRefreshService do
value = hash.values[0]
expect(value.project_id).to eq(project.id)
- expect(value.access_level).to eq(Gitlab::Access::MAINTAINER)
+ expect(value.access_level).to eq(Gitlab::Access::OWNER)
end
end
@@ -267,7 +254,7 @@ RSpec.describe AuthorizedProjectUpdate::FindRecordsDueForRefreshService do
end
it 'includes the access level for every row' do
- expect(row.access_level).to eq(Gitlab::Access::MAINTAINER)
+ expect(row.access_level).to eq(Gitlab::Access::OWNER)
end
end
end
@@ -283,7 +270,7 @@ RSpec.describe AuthorizedProjectUpdate::FindRecordsDueForRefreshService do
rows = service.fresh_authorizations.to_a
expect(rows.length).to eq(1)
- expect(rows.first.access_level).to eq(Gitlab::Access::MAINTAINER)
+ expect(rows.first.access_level).to eq(Gitlab::Access::OWNER)
end
context 'every returned row' do
@@ -294,7 +281,7 @@ RSpec.describe AuthorizedProjectUpdate::FindRecordsDueForRefreshService do
end
it 'includes the access level' do
- expect(row.access_level).to eq(Gitlab::Access::MAINTAINER)
+ expect(row.access_level).to eq(Gitlab::Access::OWNER)
end
end
end
diff --git a/spec/services/bulk_create_integration_service_spec.rb b/spec/services/bulk_create_integration_service_spec.rb
index 63bdc39857c..68c5af33fd8 100644
--- a/spec/services/bulk_create_integration_service_spec.rb
+++ b/spec/services/bulk_create_integration_service_spec.rb
@@ -13,15 +13,23 @@ RSpec.describe BulkCreateIntegrationService do
let_it_be(:excluded_project) { create(:project, group: excluded_group) }
let(:instance_integration) { create(:jira_integration, :instance) }
- let(:template_integration) { create(:jira_integration, :template) }
- let(:excluded_attributes) { %w[id project_id group_id inherit_from_id instance template created_at updated_at] }
+ let(:excluded_attributes) do
+ %w[
+ id project_id group_id inherit_from_id instance template
+ created_at updated_at
+ encrypted_properties encrypted_properties_iv
+ ]
+ end
shared_examples 'creates integration from batch ids' do
+ def attributes(record)
+ record.reload.attributes.except(*excluded_attributes)
+ end
+
it 'updates the inherited integrations' do
described_class.new(integration, batch, association).execute
- expect(created_integration.attributes.except(*excluded_attributes))
- .to eq(integration.reload.attributes.except(*excluded_attributes))
+ expect(attributes(created_integration)).to eq attributes(integration)
end
context 'integration with data fields' do
@@ -30,8 +38,8 @@ RSpec.describe BulkCreateIntegrationService do
it 'updates the data fields from inherited integrations' do
described_class.new(integration, batch, association).execute
- expect(created_integration.reload.data_fields.attributes.except(*excluded_attributes))
- .to eq(integration.reload.data_fields.attributes.except(*excluded_attributes))
+ expect(attributes(created_integration.data_fields))
+ .to eq attributes(integration.data_fields)
end
end
end
diff --git a/spec/services/ci/abort_pipelines_service_spec.rb b/spec/services/ci/abort_pipelines_service_spec.rb
index e31a45cb123..db25faff70f 100644
--- a/spec/services/ci/abort_pipelines_service_spec.rb
+++ b/spec/services/ci/abort_pipelines_service_spec.rb
@@ -7,24 +7,51 @@ RSpec.describe Ci::AbortPipelinesService do
let_it_be(:project) { create(:project, namespace: user.namespace) }
let_it_be(:cancelable_pipeline, reload: true) { create(:ci_pipeline, :running, project: project, user: user) }
- let_it_be(:manual_pipeline, reload: true) { create(:ci_pipeline, status: :manual, project: project, user: user) } # not cancelable
+ let_it_be(:manual_pipeline, reload: true) { create(:ci_pipeline, status: :manual, project: project, user: user) }
let_it_be(:other_users_pipeline, reload: true) { create(:ci_pipeline, :running, project: project, user: create(:user)) } # not this user's pipeline
+
let_it_be(:cancelable_build, reload: true) { create(:ci_build, :running, pipeline: cancelable_pipeline) }
let_it_be(:non_cancelable_build, reload: true) { create(:ci_build, :success, pipeline: cancelable_pipeline) }
let_it_be(:cancelable_stage, reload: true) { create(:ci_stage_entity, name: 'stageA', status: :running, pipeline: cancelable_pipeline, project: project) }
let_it_be(:non_cancelable_stage, reload: true) { create(:ci_stage_entity, name: 'stageB', status: :success, pipeline: cancelable_pipeline, project: project) }
+ let_it_be(:manual_pipeline_cancelable_build, reload: true) { create(:ci_build, :created, pipeline: manual_pipeline) }
+ let_it_be(:manual_pipeline_non_cancelable_build, reload: true) { create(:ci_build, :manual, pipeline: manual_pipeline) }
+ let_it_be(:manual_pipeline_cancelable_stage, reload: true) { create(:ci_stage_entity, name: 'stageA', status: :created, pipeline: manual_pipeline, project: project) }
+ let_it_be(:manual_pipeline_non_cancelable_stage, reload: true) { create(:ci_stage_entity, name: 'stageB', status: :success, pipeline: manual_pipeline, project: project) }
+
describe '#execute' do
- def expect_correct_cancellations
+ def expect_correct_pipeline_cancellations
expect(cancelable_pipeline.finished_at).not_to be_nil
- expect(cancelable_pipeline.status).to eq('failed')
- expect((cancelable_pipeline.stages - [non_cancelable_stage]).map(&:status)).to all(eq('failed'))
- expect(cancelable_build.status).to eq('failed')
+ expect(cancelable_pipeline).to be_failed
+
+ expect(manual_pipeline.finished_at).not_to be_nil
+ expect(manual_pipeline).to be_failed
+ end
+
+ def expect_correct_stage_cancellations
+ expect(cancelable_pipeline.stages - [non_cancelable_stage]).to all(be_failed)
+ expect(manual_pipeline.stages - [manual_pipeline_non_cancelable_stage]).to all(be_failed)
+
+ expect(non_cancelable_stage).not_to be_failed
+ expect(manual_pipeline_non_cancelable_stage).not_to be_failed
+ end
+
+ def expect_correct_build_cancellations
+ expect(cancelable_build).to be_failed
expect(cancelable_build.finished_at).not_to be_nil
- expect(manual_pipeline.status).not_to eq('failed')
- expect(non_cancelable_stage.status).not_to eq('failed')
- expect(non_cancelable_build.status).not_to eq('failed')
+ expect(manual_pipeline_cancelable_build).to be_failed
+ expect(manual_pipeline_cancelable_build.finished_at).not_to be_nil
+
+ expect(non_cancelable_build).not_to be_failed
+ expect(manual_pipeline_non_cancelable_build).not_to be_failed
+ end
+
+ def expect_correct_cancellations
+ expect_correct_pipeline_cancellations
+ expect_correct_stage_cancellations
+ expect_correct_build_cancellations
end
context 'with project pipelines' do
diff --git a/spec/services/ci/after_requeue_job_service_spec.rb b/spec/services/ci/after_requeue_job_service_spec.rb
index d2acf3ad2f1..2f2baa15945 100644
--- a/spec/services/ci/after_requeue_job_service_spec.rb
+++ b/spec/services/ci/after_requeue_job_service_spec.rb
@@ -2,69 +2,236 @@
require 'spec_helper'
-RSpec.describe Ci::AfterRequeueJobService do
- let_it_be(:project) { create(:project) }
+RSpec.describe Ci::AfterRequeueJobService, :sidekiq_inline do
+ let_it_be(:project) { create(:project, :empty_repo) }
let_it_be(:user) { project.first_owner }
- let(:pipeline) { create(:ci_pipeline, project: project) }
+ before_all do
+ project.repository.create_file(user, 'init', 'init', message: 'init', branch_name: 'master')
+ end
- let!(:build1) { create(:ci_build, name: 'build1', pipeline: pipeline, stage_idx: 0) }
- let!(:test1) { create(:ci_build, :success, name: 'test1', pipeline: pipeline, stage_idx: 1) }
- let!(:test2) { create(:ci_build, :skipped, name: 'test2', pipeline: pipeline, stage_idx: 1) }
- let!(:test3) { create(:ci_build, :skipped, :dependent, name: 'test3', pipeline: pipeline, stage_idx: 1, needed: build1) }
- let!(:deploy) { create(:ci_build, :skipped, :dependent, name: 'deploy', pipeline: pipeline, stage_idx: 2, needed: test3) }
+ subject(:service) { described_class.new(project, user) }
- subject(:execute_service) { described_class.new(project, user).execute(build1) }
+ context 'stage-dag mixed pipeline' do
+ let(:config) do
+ <<-EOY
+ stages: [a, b, c]
- shared_examples 'processing subsequent skipped jobs' do
- it 'marks subsequent skipped jobs as processable' do
- expect(test1.reload).to be_success
- expect(test2.reload).to be_skipped
- expect(test3.reload).to be_skipped
- expect(deploy.reload).to be_skipped
+ a1:
+ stage: a
+ script: exit $(($RANDOM % 2))
+
+ a2:
+ stage: a
+ script: exit 0
+ needs: [a1]
- execute_service
+ b1:
+ stage: b
+ script: exit 0
+ needs: []
- expect(test1.reload).to be_success
- expect(test2.reload).to be_created
- expect(test3.reload).to be_created
- expect(deploy.reload).to be_created
+ b2:
+ stage: b
+ script: exit 0
+ needs: [a2]
+
+ c1:
+ stage: c
+ script: exit 0
+ needs: [b2]
+
+ c2:
+ stage: c
+ script: exit 0
+ EOY
end
- end
- it_behaves_like 'processing subsequent skipped jobs'
-
- context 'when there is a job need from the same stage' do
- let!(:build2) do
- create(:ci_build,
- :skipped,
- :dependent,
- name: 'build2',
- pipeline: pipeline,
- stage_idx: 0,
- scheduling_type: :dag,
- needed: build1)
+ let(:pipeline) do
+ Ci::CreatePipelineService.new(project, user, { ref: 'master' }).execute(:push).payload
end
- shared_examples 'processing the same stage job' do
- it 'marks subsequent skipped jobs as processable' do
- expect { execute_service }.to change { build2.reload.status }.from('skipped').to('created')
- end
+ let(:a1) { find_job('a1') }
+ let(:b1) { find_job('b1') }
+
+ before do
+ stub_ci_pipeline_yaml_file(config)
+ check_jobs_statuses(
+ a1: 'pending',
+ a2: 'created',
+ b1: 'pending',
+ b2: 'created',
+ c1: 'created',
+ c2: 'created'
+ )
+
+ b1.success!
+ check_jobs_statuses(
+ a1: 'pending',
+ a2: 'created',
+ b1: 'success',
+ b2: 'created',
+ c1: 'created',
+ c2: 'created'
+ )
+
+ a1.drop!
+ check_jobs_statuses(
+ a1: 'failed',
+ a2: 'skipped',
+ b1: 'success',
+ b2: 'skipped',
+ c1: 'skipped',
+ c2: 'skipped'
+ )
+
+ new_a1 = Ci::RetryBuildService.new(project, user).clone!(a1)
+ new_a1.enqueue!
+ check_jobs_statuses(
+ a1: 'pending',
+ a2: 'skipped',
+ b1: 'success',
+ b2: 'skipped',
+ c1: 'skipped',
+ c2: 'skipped'
+ )
end
- it_behaves_like 'processing subsequent skipped jobs'
- it_behaves_like 'processing the same stage job'
+ it 'marks subsequent skipped jobs as processable' do
+ execute_after_requeue_service(a1)
+
+ check_jobs_statuses(
+ a1: 'pending',
+ a2: 'created',
+ b1: 'success',
+ b2: 'created',
+ c1: 'created',
+ c2: 'created'
+ )
+ end
end
- context 'when the pipeline is a downstream pipeline and the bridge is depended' do
- let!(:trigger_job) { create(:ci_bridge, :strategy_depend, name: 'trigger_job', status: 'success') }
+ context 'stage-dag mixed pipeline with some same-stage needs' do
+ let(:config) do
+ <<-EOY
+ stages: [a, b, c]
+
+ a1:
+ stage: a
+ script: exit $(($RANDOM % 2))
+
+ a2:
+ stage: a
+ script: exit 0
+ needs: [a1]
+
+ b1:
+ stage: b
+ script: exit 0
+ needs: [b2]
+
+ b2:
+ stage: b
+ script: exit 0
+
+ c1:
+ stage: c
+ script: exit 0
+ needs: [b2]
+
+ c2:
+ stage: c
+ script: exit 0
+ EOY
+ end
+
+ let(:pipeline) do
+ Ci::CreatePipelineService.new(project, user, { ref: 'master' }).execute(:push).payload
+ end
+
+ let(:a1) { find_job('a1') }
before do
- create(:ci_sources_pipeline, pipeline: pipeline, source_job: trigger_job)
+ stub_ci_pipeline_yaml_file(config)
+ check_jobs_statuses(
+ a1: 'pending',
+ a2: 'created',
+ b1: 'created',
+ b2: 'created',
+ c1: 'created',
+ c2: 'created'
+ )
+
+ a1.drop!
+ check_jobs_statuses(
+ a1: 'failed',
+ a2: 'skipped',
+ b1: 'skipped',
+ b2: 'skipped',
+ c1: 'skipped',
+ c2: 'skipped'
+ )
+
+ new_a1 = Ci::RetryBuildService.new(project, user).clone!(a1)
+ new_a1.enqueue!
+ check_jobs_statuses(
+ a1: 'pending',
+ a2: 'skipped',
+ b1: 'skipped',
+ b2: 'skipped',
+ c1: 'skipped',
+ c2: 'skipped'
+ )
end
- it 'marks source bridge as pending' do
- expect { execute_service }.to change { trigger_job.reload.status }.from('success').to('pending')
+ it 'marks subsequent skipped jobs as processable' do
+ execute_after_requeue_service(a1)
+
+ check_jobs_statuses(
+ a1: 'pending',
+ a2: 'created',
+ b1: 'created',
+ b2: 'created',
+ c1: 'created',
+ c2: 'created'
+ )
+ end
+
+ context 'when the FF ci_fix_order_of_subsequent_jobs is disabled' do
+ before do
+ stub_feature_flags(ci_fix_order_of_subsequent_jobs: false)
+ end
+
+ it 'does not mark b1 as processable' do
+ execute_after_requeue_service(a1)
+
+ check_jobs_statuses(
+ a1: 'pending',
+ a2: 'created',
+ b1: 'skipped',
+ b2: 'created',
+ c1: 'created',
+ c2: 'created'
+ )
+ end
end
end
+
+ private
+
+ def find_job(name)
+ processables.find_by!(name: name)
+ end
+
+ def check_jobs_statuses(statuses)
+ expect(processables.order(:name).pluck(:name, :status)).to contain_exactly(*statuses.stringify_keys.to_a)
+ end
+
+ def processables
+ pipeline.processables.latest
+ end
+
+ def execute_after_requeue_service(processable)
+ service.execute(processable)
+ end
end
diff --git a/spec/services/ci/create_downstream_pipeline_service_spec.rb b/spec/services/ci/create_downstream_pipeline_service_spec.rb
index 43eb57df66c..6142704b00e 100644
--- a/spec/services/ci/create_downstream_pipeline_service_spec.rb
+++ b/spec/services/ci/create_downstream_pipeline_service_spec.rb
@@ -485,14 +485,6 @@ RSpec.describe Ci::CreateDownstreamPipelineService, '#execute' do
end
it_behaves_like 'detects cyclical pipelines'
-
- context 'when ci_drop_cyclical_triggered_pipelines is not enabled' do
- before do
- stub_feature_flags(ci_drop_cyclical_triggered_pipelines: false)
- end
-
- it_behaves_like 'passes cyclical pipeline precondition'
- end
end
context 'when source in the ancestry differ' do
diff --git a/spec/services/ci/create_pipeline_service/artifacts_spec.rb b/spec/services/ci/create_pipeline_service/artifacts_spec.rb
new file mode 100644
index 00000000000..1ec30d68666
--- /dev/null
+++ b/spec/services/ci/create_pipeline_service/artifacts_spec.rb
@@ -0,0 +1,67 @@
+# frozen_string_literal: true
+require 'spec_helper'
+
+RSpec.describe Ci::CreatePipelineService do
+ let_it_be(:project) { create(:project, :repository) }
+ let_it_be(:user) { project.first_owner }
+
+ let(:ref) { 'refs/heads/master' }
+ let(:source) { :push }
+
+ let(:service) { described_class.new(project, user, { ref: ref }) }
+ let(:pipeline) { service.execute(source).payload }
+
+ describe 'artifacts:' do
+ before do
+ stub_ci_pipeline_yaml_file(config)
+ allow_next_instance_of(Ci::BuildScheduleWorker) do |instance|
+ allow(instance).to receive(:perform).and_return(true)
+ end
+ end
+
+ describe 'reports:' do
+ context 'with valid config' do
+ let(:config) do
+ <<~YAML
+ test-job:
+ script: "echo 'hello world' > cobertura.xml"
+ artifacts:
+ reports:
+ coverage_report:
+ coverage_format: 'cobertura'
+ path: 'cobertura.xml'
+
+ dependency-scanning-job:
+ script: "echo 'hello world' > gl-dependency-scanning-report.json"
+ artifacts:
+ reports:
+ dependency_scanning: 'gl-dependency-scanning-report.json'
+ YAML
+ end
+
+ it 'creates pipeline with builds' do
+ expect(pipeline).to be_persisted
+ expect(pipeline).not_to have_yaml_errors
+ expect(pipeline.builds.pluck(:name)).to contain_exactly('test-job', 'dependency-scanning-job')
+ end
+ end
+
+ context 'with invalid config' do
+ let(:config) do
+ <<~YAML
+ test-job:
+ script: "echo 'hello world' > cobertura.xml"
+ artifacts:
+ reports:
+ foo: 'bar'
+ YAML
+ end
+
+ it 'creates pipeline with yaml errors' do
+ expect(pipeline).to be_persisted
+ expect(pipeline).to have_yaml_errors
+ end
+ end
+ end
+ end
+end
diff --git a/spec/services/ci/create_pipeline_service/parameter_content_spec.rb b/spec/services/ci/create_pipeline_service/parameter_content_spec.rb
index c28bc9d8c13..f593707f460 100644
--- a/spec/services/ci/create_pipeline_service/parameter_content_spec.rb
+++ b/spec/services/ci/create_pipeline_service/parameter_content_spec.rb
@@ -15,7 +15,7 @@ RSpec.describe Ci::CreatePipelineService do
variables:
DAST_VERSION: 1
- SECURE_ANALYZERS_PREFIX: "registry.gitlab.com/gitlab-org/security-products/analyzers"
+ SECURE_ANALYZERS_PREFIX: "registry.gitlab.com/security-products"
dast:
stage: dast
diff --git a/spec/services/ci/create_pipeline_service/tags_spec.rb b/spec/services/ci/create_pipeline_service/tags_spec.rb
index 61c2415fa33..0774f9fff2a 100644
--- a/spec/services/ci/create_pipeline_service/tags_spec.rb
+++ b/spec/services/ci/create_pipeline_service/tags_spec.rb
@@ -81,31 +81,6 @@ RSpec.describe Ci::CreatePipelineService do
end
end
- context 'when the feature flag is disabled' do
- before do
- stub_feature_flags(ci_bulk_insert_tags: false)
- end
-
- it 'executes N+1s queries' do
- stub_yaml_config(config_without_tags)
-
- # warm up the cached objects so we get a more accurate count
- create_pipeline
-
- control = ActiveRecord::QueryRecorder.new(skip_cached: false) do
- create_pipeline
- end
-
- stub_yaml_config(config)
-
- expect { pipeline }
- .to exceed_all_query_limit(control)
- .with_threshold(4)
-
- expect(pipeline).to be_created_successfully
- end
- end
-
context 'when tags are already persisted' do
it 'does not execute N+1 queries' do
# warm up the cached objects so we get a more accurate count
diff --git a/spec/services/ci/destroy_secure_file_service_spec.rb b/spec/services/ci/destroy_secure_file_service_spec.rb
new file mode 100644
index 00000000000..6a30d33f4ca
--- /dev/null
+++ b/spec/services/ci/destroy_secure_file_service_spec.rb
@@ -0,0 +1,32 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe ::Ci::DestroySecureFileService do
+ let_it_be(:maintainer_user) { create(:user) }
+ let_it_be(:developer_user) { create(:user) }
+ let_it_be(:project) { create(:project) }
+ let_it_be(:secure_file) { create(:ci_secure_file, project: project) }
+ let_it_be(:project_member) { create(:project_member, :maintainer, user: maintainer_user, project: project) }
+ let_it_be(:project_member2) { create(:project_member, :developer, user: developer_user, project: project) }
+
+ subject { described_class.new(project, user).execute(secure_file) }
+
+ context 'user is a maintainer' do
+ let(:user) { maintainer_user }
+
+ it 'destroys the secure file' do
+ subject
+
+ expect { secure_file.reload }.to raise_error(ActiveRecord::RecordNotFound)
+ end
+ end
+
+ context 'user is a developer' do
+ let(:user) { developer_user }
+
+ it 'raises an exception' do
+ expect { subject }.to raise_error(Gitlab::Access::AccessDeniedError)
+ end
+ end
+end
diff --git a/spec/services/ci/job_artifacts/create_service_spec.rb b/spec/services/ci/job_artifacts/create_service_spec.rb
index 2d309bfe425..b8487e438a9 100644
--- a/spec/services/ci/job_artifacts/create_service_spec.rb
+++ b/spec/services/ci/job_artifacts/create_service_spec.rb
@@ -175,7 +175,7 @@ RSpec.describe Ci::JobArtifacts::CreateService do
end
expect(subject[:status]).to eq(:success)
- expect(job.job_variables.as_json).to contain_exactly(
+ expect(job.job_variables.as_json(only: [:key, :value, :source])).to contain_exactly(
hash_including('key' => 'KEY1', 'value' => 'VAR1', 'source' => 'dotenv'),
hash_including('key' => 'KEY2', 'value' => 'VAR2', 'source' => 'dotenv'))
end
diff --git a/spec/services/ci/parse_dotenv_artifact_service_spec.rb b/spec/services/ci/parse_dotenv_artifact_service_spec.rb
index 6bf22b7c8b2..aaab849cd93 100644
--- a/spec/services/ci/parse_dotenv_artifact_service_spec.rb
+++ b/spec/services/ci/parse_dotenv_artifact_service_spec.rb
@@ -18,7 +18,7 @@ RSpec.describe Ci::ParseDotenvArtifactService do
it 'parses the artifact' do
expect(subject[:status]).to eq(:success)
- expect(build.job_variables.as_json).to contain_exactly(
+ expect(build.job_variables.as_json(only: [:key, :value])).to contain_exactly(
hash_including('key' => 'KEY1', 'value' => 'VAR1'),
hash_including('key' => 'KEY2', 'value' => 'VAR2'))
end
@@ -57,7 +57,7 @@ RSpec.describe Ci::ParseDotenvArtifactService do
expect(subject[:status]).to eq(:success)
- expect(build.job_variables.as_json).to contain_exactly(
+ expect(build.job_variables.as_json(only: [:key, :value])).to contain_exactly(
hash_including('key' => 'KEY1', 'value' => 'VAR4'),
hash_including('key' => 'KEY2', 'value' => 'VAR3'))
end
@@ -101,7 +101,7 @@ RSpec.describe Ci::ParseDotenvArtifactService do
it 'trims the trailing space' do
subject
- expect(build.job_variables.as_json).to contain_exactly(
+ expect(build.job_variables.as_json(only: [:key, :value])).to contain_exactly(
hash_including('key' => 'KEY1', 'value' => 'VAR1'))
end
end
@@ -112,7 +112,7 @@ RSpec.describe Ci::ParseDotenvArtifactService do
it 'parses the dotenv data' do
subject
- expect(build.job_variables.as_json).to contain_exactly(
+ expect(build.job_variables.as_json(only: [:key, :value])).to contain_exactly(
hash_including('key' => 'KEY', 'value' => 'VARCONTAINING=EQLS'))
end
end
@@ -133,7 +133,7 @@ RSpec.describe Ci::ParseDotenvArtifactService do
it 'parses the dotenv data' do
subject
- expect(build.job_variables.as_json).to contain_exactly(
+ expect(build.job_variables.as_json(only: [:key, :value])).to contain_exactly(
hash_including('key' => 'skateboard', 'value' => '🛹'))
end
end
@@ -154,7 +154,7 @@ RSpec.describe Ci::ParseDotenvArtifactService do
it 'parses the dotenv data' do
subject
- expect(build.job_variables.as_json).to contain_exactly(
+ expect(build.job_variables.as_json(only: [:key, :value])).to contain_exactly(
hash_including('key' => 'KEY1', 'value' => 'V A R 1'))
end
end
@@ -165,7 +165,7 @@ RSpec.describe Ci::ParseDotenvArtifactService do
it 'parses the value as-is' do
subject
- expect(build.job_variables.as_json).to contain_exactly(
+ expect(build.job_variables.as_json(only: [:key, :value])).to contain_exactly(
hash_including('key' => 'KEY1', 'value' => '"VAR1"'))
end
end
@@ -176,7 +176,7 @@ RSpec.describe Ci::ParseDotenvArtifactService do
it 'parses the value as-is' do
subject
- expect(build.job_variables.as_json).to contain_exactly(
+ expect(build.job_variables.as_json(only: [:key, :value])).to contain_exactly(
hash_including('key' => 'KEY1', 'value' => "'VAR1'"))
end
end
@@ -187,7 +187,7 @@ RSpec.describe Ci::ParseDotenvArtifactService do
it 'parses the value as-is' do
subject
- expect(build.job_variables.as_json).to contain_exactly(
+ expect(build.job_variables.as_json(only: [:key, :value])).to contain_exactly(
hash_including('key' => 'KEY1', 'value' => '" VAR1 "'))
end
end
@@ -208,7 +208,7 @@ RSpec.describe Ci::ParseDotenvArtifactService do
it 'parses the dotenv data' do
subject
- expect(build.job_variables.as_json).to contain_exactly(
+ expect(build.job_variables.as_json(only: [:key, :value])).to contain_exactly(
hash_including('key' => 'KEY1', 'value' => ''))
end
end
@@ -250,7 +250,7 @@ RSpec.describe Ci::ParseDotenvArtifactService do
it 'does not support variable expansion in dotenv parser' do
subject
- expect(build.job_variables.as_json).to contain_exactly(
+ expect(build.job_variables.as_json(only: [:key, :value])).to contain_exactly(
hash_including('key' => 'KEY1', 'value' => 'VAR1'),
hash_including('key' => 'KEY2', 'value' => '${KEY1}_Test'))
end
@@ -284,7 +284,7 @@ RSpec.describe Ci::ParseDotenvArtifactService do
it 'does not support comment in dotenv parser' do
subject
- expect(build.job_variables.as_json).to contain_exactly(
+ expect(build.job_variables.as_json(only: [:key, :value])).to contain_exactly(
hash_including('key' => 'KEY1', 'value' => 'VAR1 # This is variable'))
end
end
diff --git a/spec/services/ci/register_runner_service_spec.rb b/spec/services/ci/register_runner_service_spec.rb
deleted file mode 100644
index 491582bbd13..00000000000
--- a/spec/services/ci/register_runner_service_spec.rb
+++ /dev/null
@@ -1,234 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe ::Ci::RegisterRunnerService, '#execute' do
- let(:registration_token) { 'abcdefg123456' }
- let(:token) { }
- let(:args) { {} }
-
- before do
- stub_feature_flags(runner_registration_control: false)
- stub_application_setting(runners_registration_token: registration_token)
- stub_application_setting(valid_runner_registrars: ApplicationSetting::VALID_RUNNER_REGISTRAR_TYPES)
- end
-
- subject { described_class.new.execute(token, args) }
-
- context 'when no token is provided' do
- let(:token) { '' }
-
- it 'returns nil' do
- is_expected.to be_nil
- end
- end
-
- context 'when invalid token is provided' do
- let(:token) { 'invalid' }
-
- it 'returns nil' do
- is_expected.to be_nil
- end
- end
-
- context 'when valid token is provided' do
- context 'with a registration token' do
- let(:token) { registration_token }
-
- it 'creates runner with default values' do
- is_expected.to be_an_instance_of(::Ci::Runner)
- expect(subject.persisted?).to be_truthy
- expect(subject.run_untagged).to be true
- expect(subject.active).to be true
- expect(subject.token).not_to eq(registration_token)
- expect(subject).to be_instance_type
- end
-
- context 'with non-default arguments' do
- let(:args) do
- {
- description: 'some description',
- active: false,
- locked: true,
- run_untagged: false,
- tag_list: %w(tag1 tag2),
- access_level: 'ref_protected',
- maximum_timeout: 600,
- name: 'some name',
- version: 'some version',
- revision: 'some revision',
- platform: 'some platform',
- architecture: 'some architecture',
- ip_address: '10.0.0.1',
- config: {
- gpus: 'some gpu config'
- }
- }
- end
-
- it 'creates runner with specified values', :aggregate_failures do
- is_expected.to be_an_instance_of(::Ci::Runner)
- expect(subject.active).to eq args[:active]
- expect(subject.locked).to eq args[:locked]
- expect(subject.run_untagged).to eq args[:run_untagged]
- expect(subject.tags).to contain_exactly(
- an_object_having_attributes(name: 'tag1'),
- an_object_having_attributes(name: 'tag2')
- )
- expect(subject.access_level).to eq args[:access_level]
- expect(subject.maximum_timeout).to eq args[:maximum_timeout]
- expect(subject.name).to eq args[:name]
- expect(subject.version).to eq args[:version]
- expect(subject.revision).to eq args[:revision]
- expect(subject.platform).to eq args[:platform]
- expect(subject.architecture).to eq args[:architecture]
- expect(subject.ip_address).to eq args[:ip_address]
- end
- end
-
- context 'with runner token expiration interval', :freeze_time do
- before do
- stub_application_setting(runner_token_expiration_interval: 5.days)
- end
-
- it 'creates runner with token expiration' do
- is_expected.to be_an_instance_of(::Ci::Runner)
- expect(subject.token_expires_at).to eq(5.days.from_now)
- end
- end
- end
-
- context 'when project token is used' do
- let(:project) { create(:project) }
- let(:token) { project.runners_token }
-
- it 'creates project runner' do
- is_expected.to be_an_instance_of(::Ci::Runner)
- expect(project.runners.size).to eq(1)
- is_expected.to eq(project.runners.first)
- expect(subject.token).not_to eq(registration_token)
- expect(subject.token).not_to eq(project.runners_token)
- expect(subject).to be_project_type
- end
-
- context 'when it exceeds the application limits' do
- before do
- create(:ci_runner, runner_type: :project_type, projects: [project], contacted_at: 1.second.ago)
- create(:plan_limits, :default_plan, ci_registered_project_runners: 1)
- end
-
- it 'does not create runner' do
- is_expected.to be_an_instance_of(::Ci::Runner)
- expect(subject.persisted?).to be_falsey
- expect(subject.errors.messages).to eq('runner_projects.base': ['Maximum number of ci registered project runners (1) exceeded'])
- expect(project.runners.reload.size).to eq(1)
- end
- end
-
- context 'when abandoned runners cause application limits to not be exceeded' do
- before do
- create(:ci_runner, runner_type: :project_type, projects: [project], created_at: 14.months.ago, contacted_at: 13.months.ago)
- create(:plan_limits, :default_plan, ci_registered_project_runners: 1)
- end
-
- it 'creates runner' do
- is_expected.to be_an_instance_of(::Ci::Runner)
- expect(subject.errors).to be_empty
- expect(project.runners.reload.size).to eq(2)
- expect(project.runners.recent.size).to eq(1)
- end
- end
-
- context 'when valid runner registrars do not include project' do
- before do
- stub_application_setting(valid_runner_registrars: ['group'])
- end
-
- context 'when feature flag is enabled' do
- before do
- stub_feature_flags(runner_registration_control: true)
- end
-
- it 'returns 403 error' do
- is_expected.to be_nil
- end
- end
-
- context 'when feature flag is disabled' do
- it 'registers the runner' do
- is_expected.to be_an_instance_of(::Ci::Runner)
- expect(subject.errors).to be_empty
- expect(subject.active).to be true
- end
- end
- end
- end
-
- context 'when group token is used' do
- let(:group) { create(:group) }
- let(:token) { group.runners_token }
-
- it 'creates a group runner' do
- is_expected.to be_an_instance_of(::Ci::Runner)
- expect(subject.errors).to be_empty
- expect(group.runners.reload.size).to eq(1)
- expect(subject.token).not_to eq(registration_token)
- expect(subject.token).not_to eq(group.runners_token)
- expect(subject).to be_group_type
- end
-
- context 'when it exceeds the application limits' do
- before do
- create(:ci_runner, runner_type: :group_type, groups: [group], contacted_at: nil, created_at: 1.month.ago)
- create(:plan_limits, :default_plan, ci_registered_group_runners: 1)
- end
-
- it 'does not create runner' do
- is_expected.to be_an_instance_of(::Ci::Runner)
- expect(subject.persisted?).to be_falsey
- expect(subject.errors.messages).to eq('runner_namespaces.base': ['Maximum number of ci registered group runners (1) exceeded'])
- expect(group.runners.reload.size).to eq(1)
- end
- end
-
- context 'when abandoned runners cause application limits to not be exceeded' do
- before do
- create(:ci_runner, runner_type: :group_type, groups: [group], created_at: 4.months.ago, contacted_at: 3.months.ago)
- create(:ci_runner, runner_type: :group_type, groups: [group], contacted_at: nil, created_at: 4.months.ago)
- create(:plan_limits, :default_plan, ci_registered_group_runners: 1)
- end
-
- it 'creates runner' do
- is_expected.to be_an_instance_of(::Ci::Runner)
- expect(subject.errors).to be_empty
- expect(group.runners.reload.size).to eq(3)
- expect(group.runners.recent.size).to eq(1)
- end
- end
-
- context 'when valid runner registrars do not include group' do
- before do
- stub_application_setting(valid_runner_registrars: ['project'])
- end
-
- context 'when feature flag is enabled' do
- before do
- stub_feature_flags(runner_registration_control: true)
- end
-
- it 'returns nil' do
- is_expected.to be_nil
- end
- end
-
- context 'when feature flag is disabled' do
- it 'registers the runner' do
- is_expected.to be_an_instance_of(::Ci::Runner)
- expect(subject.errors).to be_empty
- expect(subject.active).to be true
- end
- end
- end
- end
- end
-end
diff --git a/spec/services/ci/retry_pipeline_service_spec.rb b/spec/services/ci/retry_pipeline_service_spec.rb
index 12106b70969..df1e159b5c0 100644
--- a/spec/services/ci/retry_pipeline_service_spec.rb
+++ b/spec/services/ci/retry_pipeline_service_spec.rb
@@ -137,7 +137,7 @@ RSpec.describe Ci::RetryPipelineService, '#execute' do
end
end
- context 'when the last stage was skipepd' do
+ context 'when the last stage was skipped' do
before do
create_build('build 1', :success, 0)
create_build('test 2', :failed, 1)
@@ -336,12 +336,32 @@ RSpec.describe Ci::RetryPipelineService, '#execute' do
expect(pipeline.reload).to be_running
end
end
+
+ context 'when user is not allowed to retry build' do
+ before do
+ build = create(:ci_build, pipeline: pipeline, status: :failed)
+ allow_next_instance_of(Ci::RetryBuildService) do |service|
+ allow(service).to receive(:can?).with(user, :update_build, build).and_return(false)
+ end
+ end
+
+ it 'returns an error' do
+ response = service.execute(pipeline)
+
+ expect(response.http_status).to eq(:forbidden)
+ expect(response.errors).to include('403 Forbidden')
+ expect(pipeline.reload).not_to be_running
+ end
+ end
end
context 'when user is not allowed to retry pipeline' do
- it 'raises an error' do
- expect { service.execute(pipeline) }
- .to raise_error Gitlab::Access::AccessDeniedError
+ it 'returns an error' do
+ response = service.execute(pipeline)
+
+ expect(response.http_status).to eq(:forbidden)
+ expect(response.errors).to include('403 Forbidden')
+ expect(pipeline.reload).not_to be_running
end
end
@@ -359,9 +379,12 @@ RSpec.describe Ci::RetryPipelineService, '#execute' do
create_build('verify', :canceled, 1)
end
- it 'raises an error' do
- expect { service.execute(pipeline) }
- .to raise_error Gitlab::Access::AccessDeniedError
+ it 'returns an error' do
+ response = service.execute(pipeline)
+
+ expect(response.http_status).to eq(:forbidden)
+ expect(response.errors).to include('403 Forbidden')
+ expect(pipeline.reload).not_to be_running
end
end
@@ -372,9 +395,12 @@ RSpec.describe Ci::RetryPipelineService, '#execute' do
create_build('verify', :canceled, 2)
end
- it 'raises an error' do
- expect { service.execute(pipeline) }
- .to raise_error Gitlab::Access::AccessDeniedError
+ it 'returns an error' do
+ response = service.execute(pipeline)
+
+ expect(response.http_status).to eq(:forbidden)
+ expect(response.errors).to include('403 Forbidden')
+ expect(pipeline.reload).not_to be_running
end
end
end
diff --git a/spec/services/ci/runners/assign_runner_service_spec.rb b/spec/services/ci/runners/assign_runner_service_spec.rb
new file mode 100644
index 00000000000..00b176bb759
--- /dev/null
+++ b/spec/services/ci/runners/assign_runner_service_spec.rb
@@ -0,0 +1,40 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe ::Ci::Runners::AssignRunnerService, '#execute' do
+ subject { described_class.new(runner, project, user).execute }
+
+ let_it_be(:runner) { create(:ci_runner, :project, projects: [project]) }
+ let_it_be(:project) { create(:project) }
+
+ context 'without user' do
+ let(:user) { nil }
+
+ it 'does not call assign_to on runner and returns false' do
+ expect(runner).not_to receive(:assign_to)
+
+ is_expected.to eq(false)
+ end
+ end
+
+ context 'with unauthorized user' do
+ let(:user) { build(:user) }
+
+ it 'does not call assign_to on runner and returns false' do
+ expect(runner).not_to receive(:assign_to)
+
+ is_expected.to eq(false)
+ end
+ end
+
+ context 'with admin user', :enable_admin_mode do
+ let(:user) { create_default(:user, :admin) }
+
+ it 'calls assign_to on runner and returns value unchanged' do
+ expect(runner).to receive(:assign_to).with(project, user).once.and_return('assign_to return value')
+
+ is_expected.to eq('assign_to return value')
+ end
+ end
+end
diff --git a/spec/services/ci/runners/register_runner_service_spec.rb b/spec/services/ci/runners/register_runner_service_spec.rb
new file mode 100644
index 00000000000..f43fd823078
--- /dev/null
+++ b/spec/services/ci/runners/register_runner_service_spec.rb
@@ -0,0 +1,234 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe ::Ci::Runners::RegisterRunnerService, '#execute' do
+ let(:registration_token) { 'abcdefg123456' }
+ let(:token) { }
+ let(:args) { {} }
+
+ before do
+ stub_feature_flags(runner_registration_control: false)
+ stub_application_setting(runners_registration_token: registration_token)
+ stub_application_setting(valid_runner_registrars: ApplicationSetting::VALID_RUNNER_REGISTRAR_TYPES)
+ end
+
+ subject { described_class.new.execute(token, args) }
+
+ context 'when no token is provided' do
+ let(:token) { '' }
+
+ it 'returns nil' do
+ is_expected.to be_nil
+ end
+ end
+
+ context 'when invalid token is provided' do
+ let(:token) { 'invalid' }
+
+ it 'returns nil' do
+ is_expected.to be_nil
+ end
+ end
+
+ context 'when valid token is provided' do
+ context 'with a registration token' do
+ let(:token) { registration_token }
+
+ it 'creates runner with default values' do
+ is_expected.to be_an_instance_of(::Ci::Runner)
+ expect(subject.persisted?).to be_truthy
+ expect(subject.run_untagged).to be true
+ expect(subject.active).to be true
+ expect(subject.token).not_to eq(registration_token)
+ expect(subject).to be_instance_type
+ end
+
+ context 'with non-default arguments' do
+ let(:args) do
+ {
+ description: 'some description',
+ active: false,
+ locked: true,
+ run_untagged: false,
+ tag_list: %w(tag1 tag2),
+ access_level: 'ref_protected',
+ maximum_timeout: 600,
+ name: 'some name',
+ version: 'some version',
+ revision: 'some revision',
+ platform: 'some platform',
+ architecture: 'some architecture',
+ ip_address: '10.0.0.1',
+ config: {
+ gpus: 'some gpu config'
+ }
+ }
+ end
+
+ it 'creates runner with specified values', :aggregate_failures do
+ is_expected.to be_an_instance_of(::Ci::Runner)
+ expect(subject.active).to eq args[:active]
+ expect(subject.locked).to eq args[:locked]
+ expect(subject.run_untagged).to eq args[:run_untagged]
+ expect(subject.tags).to contain_exactly(
+ an_object_having_attributes(name: 'tag1'),
+ an_object_having_attributes(name: 'tag2')
+ )
+ expect(subject.access_level).to eq args[:access_level]
+ expect(subject.maximum_timeout).to eq args[:maximum_timeout]
+ expect(subject.name).to eq args[:name]
+ expect(subject.version).to eq args[:version]
+ expect(subject.revision).to eq args[:revision]
+ expect(subject.platform).to eq args[:platform]
+ expect(subject.architecture).to eq args[:architecture]
+ expect(subject.ip_address).to eq args[:ip_address]
+ end
+ end
+
+ context 'with runner token expiration interval', :freeze_time do
+ before do
+ stub_application_setting(runner_token_expiration_interval: 5.days)
+ end
+
+ it 'creates runner with token expiration' do
+ is_expected.to be_an_instance_of(::Ci::Runner)
+ expect(subject.token_expires_at).to eq(5.days.from_now)
+ end
+ end
+ end
+
+ context 'when project token is used' do
+ let(:project) { create(:project) }
+ let(:token) { project.runners_token }
+
+ it 'creates project runner' do
+ is_expected.to be_an_instance_of(::Ci::Runner)
+ expect(project.runners.size).to eq(1)
+ is_expected.to eq(project.runners.first)
+ expect(subject.token).not_to eq(registration_token)
+ expect(subject.token).not_to eq(project.runners_token)
+ expect(subject).to be_project_type
+ end
+
+ context 'when it exceeds the application limits' do
+ before do
+ create(:ci_runner, runner_type: :project_type, projects: [project], contacted_at: 1.second.ago)
+ create(:plan_limits, :default_plan, ci_registered_project_runners: 1)
+ end
+
+ it 'does not create runner' do
+ is_expected.to be_an_instance_of(::Ci::Runner)
+ expect(subject.persisted?).to be_falsey
+ expect(subject.errors.messages).to eq('runner_projects.base': ['Maximum number of ci registered project runners (1) exceeded'])
+ expect(project.runners.reload.size).to eq(1)
+ end
+ end
+
+ context 'when abandoned runners cause application limits to not be exceeded' do
+ before do
+ create(:ci_runner, runner_type: :project_type, projects: [project], created_at: 14.months.ago, contacted_at: 13.months.ago)
+ create(:plan_limits, :default_plan, ci_registered_project_runners: 1)
+ end
+
+ it 'creates runner' do
+ is_expected.to be_an_instance_of(::Ci::Runner)
+ expect(subject.errors).to be_empty
+ expect(project.runners.reload.size).to eq(2)
+ expect(project.runners.recent.size).to eq(1)
+ end
+ end
+
+ context 'when valid runner registrars do not include project' do
+ before do
+ stub_application_setting(valid_runner_registrars: ['group'])
+ end
+
+ context 'when feature flag is enabled' do
+ before do
+ stub_feature_flags(runner_registration_control: true)
+ end
+
+ it 'returns 403 error' do
+ is_expected.to be_nil
+ end
+ end
+
+ context 'when feature flag is disabled' do
+ it 'registers the runner' do
+ is_expected.to be_an_instance_of(::Ci::Runner)
+ expect(subject.errors).to be_empty
+ expect(subject.active).to be true
+ end
+ end
+ end
+ end
+
+ context 'when group token is used' do
+ let(:group) { create(:group) }
+ let(:token) { group.runners_token }
+
+ it 'creates a group runner' do
+ is_expected.to be_an_instance_of(::Ci::Runner)
+ expect(subject.errors).to be_empty
+ expect(group.runners.reload.size).to eq(1)
+ expect(subject.token).not_to eq(registration_token)
+ expect(subject.token).not_to eq(group.runners_token)
+ expect(subject).to be_group_type
+ end
+
+ context 'when it exceeds the application limits' do
+ before do
+ create(:ci_runner, runner_type: :group_type, groups: [group], contacted_at: nil, created_at: 1.month.ago)
+ create(:plan_limits, :default_plan, ci_registered_group_runners: 1)
+ end
+
+ it 'does not create runner' do
+ is_expected.to be_an_instance_of(::Ci::Runner)
+ expect(subject.persisted?).to be_falsey
+ expect(subject.errors.messages).to eq('runner_namespaces.base': ['Maximum number of ci registered group runners (1) exceeded'])
+ expect(group.runners.reload.size).to eq(1)
+ end
+ end
+
+ context 'when abandoned runners cause application limits to not be exceeded' do
+ before do
+ create(:ci_runner, runner_type: :group_type, groups: [group], created_at: 4.months.ago, contacted_at: 3.months.ago)
+ create(:ci_runner, runner_type: :group_type, groups: [group], contacted_at: nil, created_at: 4.months.ago)
+ create(:plan_limits, :default_plan, ci_registered_group_runners: 1)
+ end
+
+ it 'creates runner' do
+ is_expected.to be_an_instance_of(::Ci::Runner)
+ expect(subject.errors).to be_empty
+ expect(group.runners.reload.size).to eq(3)
+ expect(group.runners.recent.size).to eq(1)
+ end
+ end
+
+ context 'when valid runner registrars do not include group' do
+ before do
+ stub_application_setting(valid_runner_registrars: ['project'])
+ end
+
+ context 'when feature flag is enabled' do
+ before do
+ stub_feature_flags(runner_registration_control: true)
+ end
+
+ it 'returns nil' do
+ is_expected.to be_nil
+ end
+ end
+
+ context 'when feature flag is disabled' do
+ it 'registers the runner' do
+ is_expected.to be_an_instance_of(::Ci::Runner)
+ expect(subject.errors).to be_empty
+ expect(subject.active).to be true
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/spec/services/ci/runners/reset_registration_token_service_spec.rb b/spec/services/ci/runners/reset_registration_token_service_spec.rb
new file mode 100644
index 00000000000..c4bfff51cc8
--- /dev/null
+++ b/spec/services/ci/runners/reset_registration_token_service_spec.rb
@@ -0,0 +1,76 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe ::Ci::Runners::ResetRegistrationTokenService, '#execute' do
+ subject { described_class.new(scope, current_user).execute }
+
+ let_it_be(:user) { build(:user) }
+ let_it_be(:admin_user) { create(:user, :admin) }
+
+ shared_examples 'a registration token reset operation' do
+ context 'without user' do
+ let(:current_user) { nil }
+
+ it 'does not reset registration token and returns nil' do
+ expect(scope).not_to receive(token_reset_method_name)
+
+ is_expected.to be_nil
+ end
+ end
+
+ context 'with unauthorized user' do
+ let(:current_user) { user }
+
+ it 'does not reset registration token and returns nil' do
+ expect(scope).not_to receive(token_reset_method_name)
+
+ is_expected.to be_nil
+ end
+ end
+
+ context 'with admin user', :enable_admin_mode do
+ let(:current_user) { admin_user }
+
+ it 'resets registration token and returns value unchanged' do
+ expect(scope).to receive(token_reset_method_name).once do
+ expect(scope).to receive(token_method_name).once.and_return("#{token_method_name} return value")
+ end
+
+ is_expected.to eq("#{token_method_name} return value")
+ end
+ end
+ end
+
+ context 'with instance scope' do
+ let_it_be(:scope) { create(:application_setting) }
+
+ before do
+ allow(ApplicationSetting).to receive(:current).and_return(scope)
+ allow(ApplicationSetting).to receive(:current_without_cache).and_return(scope)
+ end
+
+ it_behaves_like 'a registration token reset operation' do
+ let(:token_method_name) { :runners_registration_token }
+ let(:token_reset_method_name) { :reset_runners_registration_token! }
+ end
+ end
+
+ context 'with group scope' do
+ let_it_be(:scope) { create(:group) }
+
+ it_behaves_like 'a registration token reset operation' do
+ let(:token_method_name) { :runners_token }
+ let(:token_reset_method_name) { :reset_runners_token! }
+ end
+ end
+
+ context 'with project scope' do
+ let_it_be(:scope) { create(:project) }
+
+ it_behaves_like 'a registration token reset operation' do
+ let(:token_method_name) { :runners_token }
+ let(:token_reset_method_name) { :reset_runners_token! }
+ end
+ end
+end
diff --git a/spec/services/ci/runners/unassign_runner_service_spec.rb b/spec/services/ci/runners/unassign_runner_service_spec.rb
new file mode 100644
index 00000000000..3fb6925f4bd
--- /dev/null
+++ b/spec/services/ci/runners/unassign_runner_service_spec.rb
@@ -0,0 +1,43 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe ::Ci::Runners::UnassignRunnerService, '#execute' do
+ subject(:service) { described_class.new(runner_project, user).execute }
+
+ let_it_be(:runner) { create(:ci_runner, :project, projects: [project]) }
+ let_it_be(:project) { create(:project) }
+
+ let(:runner_project) { runner.runner_projects.last }
+
+ context 'without user' do
+ let(:user) { nil }
+
+ it 'does not destroy runner_project', :aggregate_failures do
+ expect(runner_project).not_to receive(:destroy)
+ expect { service }.not_to change { runner.runner_projects.count }.from(1)
+
+ is_expected.to eq(false)
+ end
+ end
+
+ context 'with unauthorized user' do
+ let(:user) { build(:user) }
+
+ it 'does not call destroy on runner_project' do
+ expect(runner).not_to receive(:destroy)
+
+ service
+ end
+ end
+
+ context 'with admin user', :enable_admin_mode do
+ let(:user) { create_default(:user, :admin) }
+
+ it 'destroys runner_project' do
+ expect(runner_project).to receive(:destroy).once
+
+ service
+ end
+ end
+end
diff --git a/spec/services/ci/runners/unregister_runner_service_spec.rb b/spec/services/ci/runners/unregister_runner_service_spec.rb
new file mode 100644
index 00000000000..df1a0a90067
--- /dev/null
+++ b/spec/services/ci/runners/unregister_runner_service_spec.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe ::Ci::Runners::UnregisterRunnerService, '#execute' do
+ subject { described_class.new(runner, 'some_token').execute }
+
+ let(:runner) { create(:ci_runner) }
+
+ it 'destroys runner' do
+ expect(runner).to receive(:destroy).once.and_call_original
+ expect { subject }.to change { Ci::Runner.count }.by(-1)
+ expect(runner[:errors]).to be_nil
+ end
+end
diff --git a/spec/services/ci/runners/update_runner_service_spec.rb b/spec/services/ci/runners/update_runner_service_spec.rb
new file mode 100644
index 00000000000..b02ea8f58b0
--- /dev/null
+++ b/spec/services/ci/runners/update_runner_service_spec.rb
@@ -0,0 +1,70 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Ci::Runners::UpdateRunnerService do
+ let(:runner) { create(:ci_runner) }
+
+ describe '#update' do
+ before do
+ allow(runner).to receive(:tick_runner_queue)
+ end
+
+ context 'with description params' do
+ let(:params) { { description: 'new runner' } }
+
+ it 'updates the runner and ticking the queue' do
+ expect(update).to be_truthy
+
+ runner.reload
+
+ expect(runner).to have_received(:tick_runner_queue)
+ expect(runner.description).to eq('new runner')
+ end
+ end
+
+ context 'with paused param' do
+ let(:params) { { paused: true } }
+
+ it 'updates the runner and ticking the queue' do
+ expect(runner.active).to be_truthy
+ expect(update).to be_truthy
+
+ runner.reload
+
+ expect(runner).to have_received(:tick_runner_queue)
+ expect(runner.active).to be_falsey
+ end
+ end
+
+ context 'with cost factor params' do
+ let(:params) { { public_projects_minutes_cost_factor: 1.1, private_projects_minutes_cost_factor: 2.2 }}
+
+ it 'updates the runner cost factors' do
+ expect(update).to be_truthy
+
+ runner.reload
+
+ expect(runner.public_projects_minutes_cost_factor).to eq(1.1)
+ expect(runner.private_projects_minutes_cost_factor).to eq(2.2)
+ end
+ end
+
+ context 'when params are not valid' do
+ let(:params) { { run_untagged: false } }
+
+ it 'does not update and give false because it is not valid' do
+ expect(update).to be_falsey
+
+ runner.reload
+
+ expect(runner).not_to have_received(:tick_runner_queue)
+ expect(runner.run_untagged).to be_truthy
+ end
+ end
+
+ def update
+ described_class.new(runner).update(params) # rubocop: disable Rails/SaveBang
+ end
+ end
+end
diff --git a/spec/services/ci/unregister_runner_service_spec.rb b/spec/services/ci/unregister_runner_service_spec.rb
deleted file mode 100644
index f427e04f228..00000000000
--- a/spec/services/ci/unregister_runner_service_spec.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe ::Ci::UnregisterRunnerService, '#execute' do
- subject { described_class.new(runner).execute }
-
- let(:runner) { create(:ci_runner) }
-
- it 'destroys runner' do
- expect(runner).to receive(:destroy).once.and_call_original
- expect { subject }.to change { Ci::Runner.count }.by(-1)
- expect(runner[:errors]).to be_nil
- end
-end
diff --git a/spec/services/ci/update_runner_service_spec.rb b/spec/services/ci/update_runner_service_spec.rb
deleted file mode 100644
index eee80bfef47..00000000000
--- a/spec/services/ci/update_runner_service_spec.rb
+++ /dev/null
@@ -1,70 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Ci::UpdateRunnerService do
- let(:runner) { create(:ci_runner) }
-
- describe '#update' do
- before do
- allow(runner).to receive(:tick_runner_queue)
- end
-
- context 'with description params' do
- let(:params) { { description: 'new runner' } }
-
- it 'updates the runner and ticking the queue' do
- expect(update).to be_truthy
-
- runner.reload
-
- expect(runner).to have_received(:tick_runner_queue)
- expect(runner.description).to eq('new runner')
- end
- end
-
- context 'with paused param' do
- let(:params) { { paused: true } }
-
- it 'updates the runner and ticking the queue' do
- expect(runner.active).to be_truthy
- expect(update).to be_truthy
-
- runner.reload
-
- expect(runner).to have_received(:tick_runner_queue)
- expect(runner.active).to be_falsey
- end
- end
-
- context 'with cost factor params' do
- let(:params) { { public_projects_minutes_cost_factor: 1.1, private_projects_minutes_cost_factor: 2.2 }}
-
- it 'updates the runner cost factors' do
- expect(update).to be_truthy
-
- runner.reload
-
- expect(runner.public_projects_minutes_cost_factor).to eq(1.1)
- expect(runner.private_projects_minutes_cost_factor).to eq(2.2)
- end
- end
-
- context 'when params are not valid' do
- let(:params) { { run_untagged: false } }
-
- it 'does not update and give false because it is not valid' do
- expect(update).to be_falsey
-
- runner.reload
-
- expect(runner).not_to have_received(:tick_runner_queue)
- expect(runner.run_untagged).to be_truthy
- end
- end
-
- def update
- described_class.new(runner).update(params) # rubocop: disable Rails/SaveBang
- end
- end
-end
diff --git a/spec/services/concerns/rate_limited_service_spec.rb b/spec/services/concerns/rate_limited_service_spec.rb
index 97f5ca53c0d..04007e8e75a 100644
--- a/spec/services/concerns/rate_limited_service_spec.rb
+++ b/spec/services/concerns/rate_limited_service_spec.rb
@@ -36,79 +36,28 @@ RSpec.describe RateLimitedService do
subject { described_class::RateLimiterScopedAndKeyed.new(key: key, opts: opts, rate_limiter: rate_limiter) }
describe '#rate_limit!' do
- let(:project_with_feature_enabled) { create(:project) }
- let(:project_without_feature_enabled) { create(:project) }
+ let_it_be(:project) { create(:project) }
+ let_it_be(:current_user) { create(:user) }
- let(:project) { nil }
-
- let(:current_user) { create(:user) }
let(:service) { instance_double(Issues::CreateService, project: project, current_user: current_user) }
let(:evaluated_scope) { [project, current_user] }
let(:evaluated_opts) { { scope: evaluated_scope, users_allowlist: %w[support-bot] } }
- let(:rate_limited_service_issues_create_feature_enabled) { nil }
-
- before do
- stub_feature_flags(rate_limited_service_issues_create: rate_limited_service_issues_create_feature_enabled)
- end
- shared_examples 'a service that does not attempt to throttle' do
- it 'does not attempt to throttle' do
- expect(rate_limiter).not_to receive(:throttled?)
+ context 'when rate limiting is not in effect' do
+ let(:throttled) { false }
+ it 'does not raise an exception' do
expect(subject.rate_limit!(service)).to be_nil
end
end
- shared_examples 'a service that does attempt to throttle' do
+ context 'when rate limiting is in effect' do
before do
- allow(rate_limiter).to receive(:throttled?).and_return(throttled)
- end
-
- context 'when rate limiting is not in effect' do
- let(:throttled) { false }
-
- it 'does not raise an exception' do
- expect(subject.rate_limit!(service)).to be_nil
- end
- end
-
- context 'when rate limiting is in effect' do
- let(:throttled) { true }
-
- it 'raises a RateLimitedError exception' do
- expect { subject.rate_limit!(service) }.to raise_error(described_class::RateLimitedError, 'This endpoint has been requested too many times. Try again later.')
- end
+ allow(rate_limiter).to receive(:throttled?).and_return(true)
end
- end
-
- context 'when :rate_limited_service_issues_create feature is globally disabled' do
- let(:rate_limited_service_issues_create_feature_enabled) { false }
-
- it_behaves_like 'a service that does not attempt to throttle'
- end
-
- context 'when :rate_limited_service_issues_create feature is globally enabled' do
- let(:throttled) { nil }
- let(:rate_limited_service_issues_create_feature_enabled) { true }
- let(:project) { project_without_feature_enabled }
-
- it_behaves_like 'a service that does attempt to throttle'
- end
-
- context 'when :rate_limited_service_issues_create feature is enabled for project_with_feature_enabled' do
- let(:throttled) { nil }
- let(:rate_limited_service_issues_create_feature_enabled) { project_with_feature_enabled }
-
- context 'for project_without_feature_enabled' do
- let(:project) { project_without_feature_enabled }
-
- it_behaves_like 'a service that does not attempt to throttle'
- end
-
- context 'for project_with_feature_enabled' do
- let(:project) { project_with_feature_enabled }
- it_behaves_like 'a service that does attempt to throttle'
+ it 'raises a RateLimitedError exception' do
+ expect { subject.rate_limit!(service) }.to raise_error(described_class::RateLimitedError, 'This endpoint has been requested too many times. Try again later.')
end
end
end
diff --git a/spec/services/error_tracking/base_service_spec.rb b/spec/services/error_tracking/base_service_spec.rb
index ffbda37d417..2f2052f0189 100644
--- a/spec/services/error_tracking/base_service_spec.rb
+++ b/spec/services/error_tracking/base_service_spec.rb
@@ -5,7 +5,7 @@ require 'spec_helper'
RSpec.describe ErrorTracking::BaseService do
describe '#compose_response' do
let(:project) { double('project') }
- let(:user) { double('user') }
+ let(:user) { double('user', id: non_existing_record_id) }
let(:service) { described_class.new(project, user) }
it 'returns bad_request error when response has an error key' do
@@ -68,6 +68,16 @@ RSpec.describe ErrorTracking::BaseService do
expect(result[:animal]).to eq(:fish)
expect(result[:status]).to eq(:success)
end
+
+ context 'when tracking_event is provided' do
+ let(:service) { described_class.new(project, user, tracking_event: :error_tracking_view_list) }
+
+ it_behaves_like 'tracking unique hll events' do
+ let(:target_event) { 'error_tracking_view_list' }
+ let(:expected_value) { non_existing_record_id }
+ let(:request) { service.send(:compose_response, data) }
+ end
+ end
end
end
end
diff --git a/spec/services/error_tracking/collect_error_service_spec.rb b/spec/services/error_tracking/collect_error_service_spec.rb
index 2b16612dac3..faca3c12a48 100644
--- a/spec/services/error_tracking/collect_error_service_spec.rb
+++ b/spec/services/error_tracking/collect_error_service_spec.rb
@@ -51,25 +51,30 @@ RSpec.describe ErrorTracking::CollectErrorService do
end
end
- context 'unusual payload' do
+ context 'with unusual payload' do
let(:modified_event) { parsed_event }
+ let(:event) { described_class.new(project, nil, event: modified_event).execute }
- context 'missing transaction' do
+ context 'when transaction is missing' do
it 'builds actor from stacktrace' do
modified_event.delete('transaction')
- event = described_class.new(project, nil, event: modified_event).execute
+ expect(event.error.actor).to eq 'find()'
+ end
+ end
+
+ context 'when transaction is an empty string' do \
+ it 'builds actor from stacktrace' do
+ modified_event['transaction'] = ''
expect(event.error.actor).to eq 'find()'
end
end
- context 'timestamp is numeric' do
+ context 'when timestamp is numeric' do
it 'parses timestamp' do
modified_event['timestamp'] = '1631015580.50'
- event = described_class.new(project, nil, event: modified_event).execute
-
expect(event.occurred_at).to eq '2021-09-07T11:53:00.5'
end
end
diff --git a/spec/services/google_cloud/create_service_accounts_service_spec.rb b/spec/services/google_cloud/create_service_accounts_service_spec.rb
index 53d21df713a..3f500e7c235 100644
--- a/spec/services/google_cloud/create_service_accounts_service_spec.rb
+++ b/spec/services/google_cloud/create_service_accounts_service_spec.rb
@@ -26,6 +26,8 @@ RSpec.describe GoogleCloud::CreateServiceAccountsService do
end
it 'creates unprotected vars', :aggregate_failures do
+ allow(ProtectedBranch).to receive(:protected?).and_return(false)
+
project = create(:project)
service = described_class.new(
@@ -45,5 +47,28 @@ RSpec.describe GoogleCloud::CreateServiceAccountsService do
expect(project.variables.second.protected).to eq(false)
expect(project.variables.third.protected).to eq(false)
end
+
+ it 'creates protected vars', :aggregate_failures do
+ allow(ProtectedBranch).to receive(:protected?).and_return(true)
+
+ project = create(:project)
+
+ service = described_class.new(
+ project,
+ nil,
+ google_oauth2_token: 'mock-token',
+ gcp_project_id: 'mock-gcp-project-id',
+ environment_name: '*'
+ )
+
+ response = service.execute
+
+ expect(response.status).to eq(:success)
+ expect(response.message).to eq('Service account generated successfully')
+ expect(project.variables.count).to eq(3)
+ expect(project.variables.first.protected).to eq(true)
+ expect(project.variables.second.protected).to eq(true)
+ expect(project.variables.third.protected).to eq(true)
+ end
end
end
diff --git a/spec/services/google_cloud/gcp_region_add_or_replace_service_spec.rb b/spec/services/google_cloud/gcp_region_add_or_replace_service_spec.rb
new file mode 100644
index 00000000000..e2f5a2e719e
--- /dev/null
+++ b/spec/services/google_cloud/gcp_region_add_or_replace_service_spec.rb
@@ -0,0 +1,28 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe GoogleCloud::GcpRegionAddOrReplaceService do
+ it 'adds and replaces GCP region vars' do
+ project = create(:project, :public)
+ service = described_class.new(project)
+
+ service.execute('env_1', 'loc_1')
+ service.execute('env_2', 'loc_2')
+ service.execute('env_1', 'loc_3')
+
+ list = project.variables.reload.filter { |variable| variable.key == Projects::GoogleCloudController::GCP_REGION_CI_VAR_KEY }
+ list = list.sort_by(&:environment_scope)
+
+ aggregate_failures 'testing list of gcp regions' do
+ expect(list.length).to eq(2)
+
+ # asserting that the first region is replaced
+ expect(list.first.environment_scope).to eq('env_1')
+ expect(list.first.value).to eq('loc_3')
+
+ expect(list.second.environment_scope).to eq('env_2')
+ expect(list.second.value).to eq('loc_2')
+ end
+ end
+end
diff --git a/spec/services/google_cloud/service_accounts_service_spec.rb b/spec/services/google_cloud/service_accounts_service_spec.rb
index 17c1f61a96e..10e387126a3 100644
--- a/spec/services/google_cloud/service_accounts_service_spec.rb
+++ b/spec/services/google_cloud/service_accounts_service_spec.rb
@@ -37,17 +37,17 @@ RSpec.describe GoogleCloud::ServiceAccountsService do
aggregate_failures 'testing list of service accounts' do
expect(list.length).to eq(3)
- expect(list.first[:environment]).to eq('*')
+ expect(list.first[:ref]).to eq('*')
expect(list.first[:gcp_project]).to eq('prj1')
expect(list.first[:service_account_exists]).to eq(false)
expect(list.first[:service_account_key_exists]).to eq(true)
- expect(list.second[:environment]).to eq('staging')
+ expect(list.second[:ref]).to eq('staging')
expect(list.second[:gcp_project]).to eq('prj2')
expect(list.second[:service_account_exists]).to eq(true)
expect(list.second[:service_account_key_exists]).to eq(false)
- expect(list.third[:environment]).to eq('production')
+ expect(list.third[:ref]).to eq('production')
expect(list.third[:gcp_project]).to eq('prj3')
expect(list.third[:service_account_exists]).to eq(true)
expect(list.third[:service_account_key_exists]).to eq(true)
@@ -68,12 +68,12 @@ RSpec.describe GoogleCloud::ServiceAccountsService do
aggregate_failures 'testing list of service accounts' do
expect(list.length).to eq(2)
- expect(list.first[:environment]).to eq('env_1')
+ expect(list.first[:ref]).to eq('env_1')
expect(list.first[:gcp_project]).to eq('gcp_prj_id_1')
expect(list.first[:service_account_exists]).to eq(true)
expect(list.first[:service_account_key_exists]).to eq(true)
- expect(list.second[:environment]).to eq('env_2')
+ expect(list.second[:ref]).to eq('env_2')
expect(list.second[:gcp_project]).to eq('gcp_prj_id_2')
expect(list.second[:service_account_exists]).to eq(true)
expect(list.second[:service_account_key_exists]).to eq(true)
@@ -89,12 +89,12 @@ RSpec.describe GoogleCloud::ServiceAccountsService do
expect(list.length).to eq(2)
# asserting that the first service account is replaced
- expect(list.first[:environment]).to eq('env_1')
+ expect(list.first[:ref]).to eq('env_1')
expect(list.first[:gcp_project]).to eq('new_project')
expect(list.first[:service_account_exists]).to eq(true)
expect(list.first[:service_account_key_exists]).to eq(true)
- expect(list.second[:environment]).to eq('env_2')
+ expect(list.second[:ref]).to eq('env_2')
expect(list.second[:gcp_project]).to eq('gcp_prj_id_2')
expect(list.second[:service_account_exists]).to eq(true)
expect(list.second[:service_account_key_exists]).to eq(true)
diff --git a/spec/services/groups/create_service_spec.rb b/spec/services/groups/create_service_spec.rb
index 7ec523a1f2b..819569d6e67 100644
--- a/spec/services/groups/create_service_spec.rb
+++ b/spec/services/groups/create_service_spec.rb
@@ -85,14 +85,6 @@ RSpec.describe Groups::CreateService, '#execute' do
context 'with before_commit callback' do
it_behaves_like 'has sync-ed traversal_ids'
end
-
- context 'with after_create callback' do
- before do
- stub_feature_flags(sync_traversal_ids_before_commit: false)
- end
-
- it_behaves_like 'has sync-ed traversal_ids'
- end
end
context 'when user can not create a group' do
@@ -119,17 +111,7 @@ RSpec.describe Groups::CreateService, '#execute' do
expect { subject }.not_to change(OnboardingProgress, :count).from(0)
end
- context 'with before_commit callback' do
- it_behaves_like 'has sync-ed traversal_ids'
- end
-
- context 'with after_create callback' do
- before do
- stub_feature_flags(sync_traversal_ids_before_commit: false)
- end
-
- it_behaves_like 'has sync-ed traversal_ids'
- end
+ it_behaves_like 'has sync-ed traversal_ids'
end
context 'as guest' do
diff --git a/spec/services/groups/deploy_tokens/revoke_service_spec.rb b/spec/services/groups/deploy_tokens/revoke_service_spec.rb
new file mode 100644
index 00000000000..fcf11bbb8e6
--- /dev/null
+++ b/spec/services/groups/deploy_tokens/revoke_service_spec.rb
@@ -0,0 +1,28 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Groups::DeployTokens::RevokeService do
+ let_it_be(:entity) { create(:group) }
+ let_it_be(:deploy_token) { create(:deploy_token, :group, groups: [entity]) }
+ let_it_be(:user) { create(:user) }
+ let_it_be(:deploy_token_params) { { id: deploy_token.id } }
+
+ describe '#execute' do
+ subject { described_class.new(entity, user, deploy_token_params).execute }
+
+ it "revokes a group deploy token" do
+ expect(deploy_token.revoked).to eq(false)
+
+ expect { subject }.to change { deploy_token.reload.revoked }.to eq(true)
+ end
+
+ context 'invalid token id' do
+ let(:deploy_token_params) { { token_id: non_existing_record_id } }
+
+ it 'raises an error' do
+ expect { subject }.to raise_error(ActiveRecord::RecordNotFound)
+ end
+ end
+ end
+end
diff --git a/spec/services/groups/destroy_service_spec.rb b/spec/services/groups/destroy_service_spec.rb
index 5135be8fff5..628943e40ff 100644
--- a/spec/services/groups/destroy_service_spec.rb
+++ b/spec/services/groups/destroy_service_spec.rb
@@ -3,8 +3,6 @@
require 'spec_helper'
RSpec.describe Groups::DestroyService do
- include DatabaseConnectionHelpers
-
let!(:user) { create(:user) }
let!(:group) { create(:group) }
let!(:nested_group) { create(:group, parent: group) }
@@ -112,6 +110,17 @@ RSpec.describe Groups::DestroyService do
end
end
+ context 'when group owner is blocked' do
+ before do
+ user.block!
+ end
+
+ it 'returns a more descriptive error message' do
+ expect { destroy_group(group, user, false) }
+ .to raise_error(Groups::DestroyService::DestroyError, "You can't delete this group because you're blocked.")
+ end
+ end
+
describe 'repository removal' do
before do
destroy_group(group, user, false)
diff --git a/spec/services/import/gitlab_projects/create_project_from_remote_file_service_spec.rb b/spec/services/import/gitlab_projects/create_project_from_remote_file_service_spec.rb
deleted file mode 100644
index 92c46cf7052..00000000000
--- a/spec/services/import/gitlab_projects/create_project_from_remote_file_service_spec.rb
+++ /dev/null
@@ -1,201 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe ::Import::GitlabProjects::CreateProjectFromRemoteFileService do
- let(:remote_url) { 'https://external.file.path/file' }
-
- let(:params) do
- {
- path: 'path',
- namespace: user.namespace,
- name: 'name',
- remote_import_url: remote_url
- }
- end
-
- let_it_be(:user) { create(:user) }
-
- subject { described_class.new(user, params) }
-
- shared_examples 'successfully import' do |content_type|
- it 'creates a project and returns a successful response' do
- stub_headers_for(remote_url, {
- 'content-type' => content_type,
- 'content-length' => '10'
- })
-
- response = nil
- expect { response = subject.execute }
- .to change(Project, :count).by(1)
-
- expect(response).to be_success
- expect(response.http_status).to eq(:ok)
- expect(response.payload).to be_instance_of(Project)
- expect(response.payload.name).to eq('name')
- expect(response.payload.path).to eq('path')
- expect(response.payload.namespace).to eq(user.namespace)
- end
- end
-
- it_behaves_like 'successfully import', 'application/gzip'
- it_behaves_like 'successfully import', 'application/x-tar'
-
- context 'when the file url is invalid' do
- it 'returns an erred response with the reason of the failure' do
- stub_application_setting(allow_local_requests_from_web_hooks_and_services: false)
-
- params[:remote_import_url] = 'https://localhost/file'
-
- response = nil
- expect { response = subject.execute }
- .not_to change(Project, :count)
-
- expect(response).not_to be_success
- expect(response.http_status).to eq(:bad_request)
- expect(response.message).to eq('Requests to localhost are not allowed')
- end
- end
-
- context 'validate file type' do
- it 'returns erred response when the file type is not informed' do
- stub_headers_for(remote_url, { 'content-length' => '10' })
-
- response = nil
- expect { response = subject.execute }
- .not_to change(Project, :count)
-
- expect(response).not_to be_success
- expect(response.http_status).to eq(:bad_request)
- expect(response.message)
- .to eq("Missing 'ContentType' header")
- end
-
- it 'returns erred response when the file type is not allowed' do
- stub_headers_for(remote_url, {
- 'content-type' => 'application/js',
- 'content-length' => '10'
- })
-
- response = nil
- expect { response = subject.execute }
- .not_to change(Project, :count)
-
- expect(response).not_to be_success
- expect(response.http_status).to eq(:bad_request)
- expect(response.message)
- .to eq("Remote file content type 'application/js' not allowed. (Allowed content types: application/gzip, application/x-tar)")
- end
- end
-
- context 'validate content type' do
- it 'returns erred response when the file size is not informed' do
- stub_headers_for(remote_url, { 'content-type' => 'application/gzip' })
-
- response = nil
- expect { response = subject.execute }
- .not_to change(Project, :count)
-
- expect(response).not_to be_success
- expect(response.http_status).to eq(:bad_request)
- expect(response.message)
- .to eq("Missing 'ContentLength' header")
- end
-
- it 'returns error response when the file size is a text' do
- stub_headers_for(remote_url, {
- 'content-type' => 'application/gzip',
- 'content-length' => 'some text'
- })
-
- response = nil
- expect { response = subject.execute }
- .not_to change(Project, :count)
-
- expect(response).not_to be_success
- expect(response.http_status).to eq(:bad_request)
- expect(response.message)
- .to eq("Missing 'ContentLength' header")
- end
-
- it 'returns erred response when the file is larger then allowed' do
- stub_headers_for(remote_url, {
- 'content-type' => 'application/gzip',
- 'content-length' => 11.gigabytes.to_s
- })
-
- response = nil
- expect { response = subject.execute }
- .not_to change(Project, :count)
-
- expect(response).not_to be_success
- expect(response.http_status).to eq(:bad_request)
- expect(response.message)
- .to eq('Remote file larger than limit. (limit 10 GB)')
- end
- end
-
- it 'does not validate content-type or content-length when the file is stored in AWS-S3' do
- stub_headers_for(remote_url, {
- 'Server' => 'AmazonS3',
- 'x-amz-request-id' => 'Something'
- })
-
- response = nil
- expect { response = subject.execute }
- .to change(Project, :count)
-
- expect(response).to be_success
- expect(response.http_status).to eq(:ok)
- end
-
- context 'when required parameters are not provided' do
- let(:params) { {} }
-
- it 'returns an erred response with the reason of the failure' do
- stub_application_setting(allow_local_requests_from_web_hooks_and_services: false)
-
- response = nil
- expect { response = subject.execute }
- .not_to change(Project, :count)
-
- expect(response).not_to be_success
- expect(response.http_status).to eq(:bad_request)
- expect(response.message).to eq("Parameter 'path' is required")
-
- expect(subject.errors.full_messages).to match_array([
- "Missing 'ContentLength' header",
- "Missing 'ContentType' header",
- "Parameter 'namespace' is required",
- "Parameter 'path' is required",
- "Parameter 'remote_import_url' is required"
- ])
- end
- end
-
- context 'when the project is invalid' do
- it 'returns an erred response with the reason of the failure' do
- create(:project, namespace: user.namespace, path: 'path')
-
- stub_headers_for(remote_url, {
- 'content-type' => 'application/gzip',
- 'content-length' => '10'
- })
-
- response = nil
- expect { response = subject.execute }
- .not_to change(Project, :count)
-
- expect(response).not_to be_success
- expect(response.http_status).to eq(:bad_request)
- expect(response.message).to eq('Path has already been taken')
- end
- end
-
- def stub_headers_for(url, headers = {})
- allow(Gitlab::HTTP)
- .to receive(:head)
- .with(url)
- .and_return(double(headers: headers))
- end
-end
diff --git a/spec/services/import/gitlab_projects/create_project_from_uploaded_file_service_spec.rb b/spec/services/import/gitlab_projects/create_project_from_uploaded_file_service_spec.rb
deleted file mode 100644
index a0e04a9a696..00000000000
--- a/spec/services/import/gitlab_projects/create_project_from_uploaded_file_service_spec.rb
+++ /dev/null
@@ -1,71 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe ::Import::GitlabProjects::CreateProjectFromUploadedFileService do
- let(:file_upload) do
- fixture_file_upload('spec/features/projects/import_export/test_project_export.tar.gz')
- end
-
- let(:params) do
- {
- path: 'path',
- namespace: user.namespace,
- name: 'name',
- file: file_upload
- }
- end
-
- let_it_be(:user) { create(:user) }
-
- subject { described_class.new(user, params) }
-
- it 'creates a project and returns a successful response' do
- response = nil
- expect { response = subject.execute }
- .to change(Project, :count).by(1)
-
- expect(response).to be_success
- expect(response.http_status).to eq(:ok)
- expect(response.payload).to be_instance_of(Project)
- expect(response.payload.name).to eq('name')
- expect(response.payload.path).to eq('path')
- expect(response.payload.namespace).to eq(user.namespace)
- end
-
- context 'when required parameters are not provided' do
- let(:params) { {} }
-
- it 'returns an erred response with the reason of the failure' do
- stub_application_setting(allow_local_requests_from_web_hooks_and_services: false)
-
- response = nil
- expect { response = subject.execute }
- .not_to change(Project, :count)
-
- expect(response).not_to be_success
- expect(response.http_status).to eq(:bad_request)
- expect(response.message).to eq("Parameter 'path' is required")
-
- expect(subject.errors.full_messages).to match_array([
- "Parameter 'namespace' is required",
- "Parameter 'path' is required",
- "Parameter 'file' is required"
- ])
- end
- end
-
- context 'when the project is invalid' do
- it 'returns an erred response with the reason of the failure' do
- create(:project, namespace: user.namespace, path: 'path')
-
- response = nil
- expect { response = subject.execute }
- .not_to change(Project, :count)
-
- expect(response).not_to be_success
- expect(response.http_status).to eq(:bad_request)
- expect(response.message).to eq('Path has already been taken')
- end
- end
-end
diff --git a/spec/services/import/gitlab_projects/create_project_service_spec.rb b/spec/services/import/gitlab_projects/create_project_service_spec.rb
new file mode 100644
index 00000000000..0da897448b8
--- /dev/null
+++ b/spec/services/import/gitlab_projects/create_project_service_spec.rb
@@ -0,0 +1,179 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe ::Import::GitlabProjects::CreateProjectService, :aggregate_failures do
+ let(:fake_file_acquisition_strategy) do
+ Class.new do
+ attr_reader :errors
+
+ def initialize(...)
+ @errors = ActiveModel::Errors.new(self)
+ end
+
+ def valid?
+ true
+ end
+
+ def project_params
+ {}
+ end
+ end
+ end
+
+ let(:params) do
+ {
+ path: 'path',
+ namespace: user.namespace,
+ name: 'name'
+ }
+ end
+
+ let_it_be(:user) { create(:user) }
+
+ subject { described_class.new(user, params: params, file_acquisition_strategy: FakeStrategy) }
+
+ before do
+ stub_const('FakeStrategy', fake_file_acquisition_strategy)
+ end
+
+ describe 'validation' do
+ it { expect(subject).to be_valid }
+
+ it 'validates presence of path' do
+ params[:path] = nil
+
+ invalid = described_class.new(user, params: params, file_acquisition_strategy: FakeStrategy)
+
+ expect(invalid).not_to be_valid
+ expect(invalid.errors.full_messages).to include("Path can't be blank")
+ end
+
+ it 'validates presence of name' do
+ params[:namespace] = nil
+
+ invalid = described_class.new(user, params: params, file_acquisition_strategy: FakeStrategy)
+
+ expect(invalid).not_to be_valid
+ expect(invalid.errors.full_messages).to include("Namespace can't be blank")
+ end
+
+ it 'is invalid if the strategy is invalid' do
+ expect_next_instance_of(FakeStrategy) do |strategy|
+ allow(strategy).to receive(:valid?).and_return(false)
+ allow(strategy).to receive(:errors).and_wrap_original do |original|
+ original.call.tap do |errors|
+ errors.add(:base, "some error")
+ end
+ end
+ end
+
+ invalid = described_class.new(user, params: params, file_acquisition_strategy: FakeStrategy)
+
+ expect(invalid).not_to be_valid
+ expect(invalid.errors.full_messages).to include("some error")
+ expect(invalid.errors.full_messages).to include("some error")
+ end
+ end
+
+ describe '#execute' do
+ it 'creates a project successfully' do
+ response = nil
+ expect { response = subject.execute }
+ .to change(Project, :count).by(1)
+
+ expect(response).to be_success
+ expect(response.http_status).to eq(:ok)
+ expect(response.payload).to be_instance_of(Project)
+ expect(response.payload.name).to eq('name')
+ expect(response.payload.path).to eq('path')
+ expect(response.payload.namespace).to eq(user.namespace)
+
+ project = Project.last
+ expect(project.name).to eq('name')
+ expect(project.path).to eq('path')
+ expect(project.namespace_id).to eq(user.namespace.id)
+ expect(project.import_type).to eq('gitlab_project')
+ end
+
+ context 'when the project creation raises an error' do
+ it 'fails to create a project' do
+ expect_next_instance_of(Projects::GitlabProjectsImportService) do |service|
+ expect(service).to receive(:execute).and_raise(StandardError, "failed to create project")
+ end
+
+ response = nil
+ expect { response = subject.execute }
+ .to change(Project, :count).by(0)
+
+ expect(response).to be_error
+ expect(response.http_status).to eq(:bad_request)
+ expect(response.message).to eq("failed to create project")
+ expect(response.payload).to eq(other_errors: [])
+ end
+ end
+
+ context 'when the validation fail' do
+ it 'fails to create a project' do
+ params.delete(:path)
+
+ response = nil
+ expect { response = subject.execute }
+ .to change(Project, :count).by(0)
+
+ expect(response).to be_error
+ expect(response.http_status).to eq(:bad_request)
+ expect(response.message).to eq("Path can't be blank")
+ expect(response.payload).to eq(other_errors: [])
+ end
+
+ context 'when the project contains multilple errors' do
+ it 'fails to create a project' do
+ params.merge!(name: '_ an invalid name _', path: '_ an invalid path _')
+
+ response = nil
+ expect { response = subject.execute }
+ .to change(Project, :count).by(0)
+
+ expect(response).to be_error
+ expect(response.http_status).to eq(:bad_request)
+ expect(response.message)
+ .to eq(%{Project namespace path can contain only letters, digits, '_', '-' and '.'. Cannot start with '-', end in '.git' or end in '.atom'})
+ expect(response.payload).to eq(other_errors: [
+ %{Path can contain only letters, digits, '_', '-' and '.'. Cannot start with '-', end in '.git' or end in '.atom'},
+ %{Path must not start or end with a special character and must not contain consecutive special characters.}
+ ])
+ end
+ end
+ end
+
+ context 'when the strategy adds project parameters' do
+ before do
+ expect_next_instance_of(FakeStrategy) do |strategy|
+ expect(strategy).to receive(:project_params).and_return(name: 'the strategy name')
+ end
+
+ subject.valid?
+ end
+
+ it 'merges the strategy project parameters' do
+ response = nil
+ expect { response = subject.execute }
+ .to change(Project, :count).by(1)
+
+ expect(response).to be_success
+ expect(response.http_status).to eq(:ok)
+ expect(response.payload).to be_instance_of(Project)
+ expect(response.payload.name).to eq('the strategy name')
+ expect(response.payload.path).to eq('path')
+ expect(response.payload.namespace).to eq(user.namespace)
+
+ project = Project.last
+ expect(project.name).to eq('the strategy name')
+ expect(project.path).to eq('path')
+ expect(project.namespace_id).to eq(user.namespace.id)
+ expect(project.import_type).to eq('gitlab_project')
+ end
+ end
+ end
+end
diff --git a/spec/services/import/gitlab_projects/file_acquisition_strategies/file_upload_spec.rb b/spec/services/import/gitlab_projects/file_acquisition_strategies/file_upload_spec.rb
new file mode 100644
index 00000000000..28af6219812
--- /dev/null
+++ b/spec/services/import/gitlab_projects/file_acquisition_strategies/file_upload_spec.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe ::Import::GitlabProjects::FileAcquisitionStrategies::FileUpload, :aggregate_failures do
+ let(:file) { UploadedFile.new( File.join('spec', 'features', 'projects', 'import_export', 'test_project_export.tar.gz') ) }
+
+ describe 'validation' do
+ it 'validates presence of file' do
+ valid = described_class.new(params: { file: file })
+ expect(valid).to be_valid
+
+ invalid = described_class.new(params: {})
+ expect(invalid).not_to be_valid
+ expect(invalid.errors.full_messages).to include("File must be uploaded")
+ end
+ end
+
+ describe '#project_params' do
+ it 'returns the file to upload in the params' do
+ subject = described_class.new(params: { file: file })
+
+ expect(subject.project_params).to eq(file: file)
+ end
+ end
+end
diff --git a/spec/services/import/gitlab_projects/file_acquisition_strategies/remote_file_s3_spec.rb b/spec/services/import/gitlab_projects/file_acquisition_strategies/remote_file_s3_spec.rb
new file mode 100644
index 00000000000..d9042e95149
--- /dev/null
+++ b/spec/services/import/gitlab_projects/file_acquisition_strategies/remote_file_s3_spec.rb
@@ -0,0 +1,136 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe ::Import::GitlabProjects::FileAcquisitionStrategies::RemoteFileS3, :aggregate_failures do
+ let(:region_name) { 'region_name' }
+ let(:bucket_name) { 'bucket_name' }
+ let(:file_key) { 'file_key' }
+ let(:access_key_id) { 'access_key_id' }
+ let(:secret_access_key) { 'secret_access_key' }
+ let(:file_exists) { true }
+ let(:content_type) { 'application/x-tar' }
+ let(:content_length) { 2.gigabytes }
+ let(:presigned_url) { 'https://external.file.path/file.tar.gz?PRESIGNED=true&TOKEN=some-token' }
+
+ let(:s3_double) do
+ instance_double(
+ Aws::S3::Object,
+ exists?: file_exists,
+ content_type: content_type,
+ content_length: content_length,
+ presigned_url: presigned_url
+ )
+ end
+
+ let(:params) do
+ {
+ region: region_name,
+ bucket_name: bucket_name,
+ file_key: file_key,
+ access_key_id: access_key_id,
+ secret_access_key: secret_access_key
+ }
+ end
+
+ subject { described_class.new(params: params) }
+
+ before do
+ # Avoid network requests
+ expect(Aws::S3::Client).to receive(:new).and_return(double)
+ expect(Aws::S3::Object).to receive(:new).and_return(s3_double)
+ end
+
+ describe 'validation' do
+ it { expect(subject).to be_valid }
+
+ %i[region bucket_name file_key access_key_id secret_access_key].each do |key|
+ context "#{key} validation" do
+ before do
+ params[key] = nil
+ end
+
+ it "validates presence of #{key}" do
+ expect(subject).not_to be_valid
+ expect(subject.errors.full_messages)
+ .to include("#{key.to_s.humanize} can't be blank")
+ end
+ end
+ end
+
+ context 'content-length validation' do
+ let(:content_length) { 11.gigabytes }
+
+ it 'validates the remote content-length' do
+ expect(subject).not_to be_valid
+ expect(subject.errors.full_messages)
+ .to include('Content length is too big (should be at most 10 GB)')
+ end
+ end
+
+ context 'content-type validation' do
+ let(:content_type) { 'unknown' }
+
+ it 'validates the remote content-type' do
+ expect(subject).not_to be_valid
+ expect(subject.errors.full_messages)
+ .to include("Content type 'unknown' not allowed. (Allowed: application/gzip, application/x-tar, application/x-gzip)")
+ end
+ end
+
+ context 'file_url validation' do
+ let(:presigned_url) { 'ftp://invalid.url/file.tar.gz' }
+
+ it 'validates the file_url scheme' do
+ expect(subject).not_to be_valid
+ expect(subject.errors.full_messages)
+ .to include("File url is blocked: Only allowed schemes are https")
+ end
+
+ context 'when localhost urls are not allowed' do
+ let(:presigned_url) { 'https://localhost:3000/file.tar.gz' }
+
+ it 'validates the file_url' do
+ stub_application_setting(allow_local_requests_from_web_hooks_and_services: false)
+
+ expect(subject).not_to be_valid
+ expect(subject.errors.full_messages)
+ .to include("File url is blocked: Requests to localhost are not allowed")
+ end
+ end
+ end
+
+ context 'when the remote file does not exist' do
+ it 'foo' do
+ expect(s3_double).to receive(:exists?).and_return(false)
+
+ expect(subject).not_to be_valid
+ expect(subject.errors.full_messages)
+ .to include("File not found 'file_key' in 'bucket_name'")
+ end
+ end
+
+ context 'when it fails to build the s3 object' do
+ it 'foo' do
+ expect(s3_double).to receive(:exists?).and_raise(StandardError, "some error")
+
+ expect(subject).not_to be_valid
+ expect(subject.errors.full_messages)
+ .to include("Failed to open 'file_key' in 'bucket_name': some error")
+ end
+ end
+ end
+
+ describe '#project_params' do
+ it 'returns import_export_upload in the params' do
+ subject = described_class.new(params: { remote_import_url: presigned_url })
+
+ expect(subject.project_params).to match(
+ import_export_upload: an_instance_of(::ImportExportUpload)
+ )
+ expect(subject.project_params[:import_export_upload]).to have_attributes(
+ remote_import_url: presigned_url
+ )
+ end
+ end
+end
diff --git a/spec/services/import/gitlab_projects/file_acquisition_strategies/remote_file_spec.rb b/spec/services/import/gitlab_projects/file_acquisition_strategies/remote_file_spec.rb
new file mode 100644
index 00000000000..8565299b9b7
--- /dev/null
+++ b/spec/services/import/gitlab_projects/file_acquisition_strategies/remote_file_spec.rb
@@ -0,0 +1,149 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe ::Import::GitlabProjects::FileAcquisitionStrategies::RemoteFile, :aggregate_failures do
+ let(:remote_url) { 'https://external.file.path/file.tar.gz' }
+ let(:params) { { remote_import_url: remote_url } }
+
+ subject { described_class.new(params: params) }
+
+ before do
+ stub_headers_for(remote_url, {
+ 'content-length' => 10.gigabytes,
+ 'content-type' => 'application/gzip'
+ })
+ end
+
+ describe 'validation' do
+ it { expect(subject).to be_valid }
+
+ context 'file_url validation' do
+ let(:remote_url) { 'ftp://invalid.url/file.tar.gz' }
+
+ it 'validates the file_url scheme' do
+ expect(subject).not_to be_valid
+ expect(subject.errors.full_messages)
+ .to include("File url is blocked: Only allowed schemes are https")
+ end
+
+ context 'when localhost urls are not allowed' do
+ let(:remote_url) { 'https://localhost:3000/file.tar.gz' }
+
+ it 'validates the file_url' do
+ stub_application_setting(allow_local_requests_from_web_hooks_and_services: false)
+
+ expect(subject).not_to be_valid
+ expect(subject.errors.full_messages)
+ .to include("File url is blocked: Requests to localhost are not allowed")
+ end
+ end
+ end
+
+ context 'when import_project_from_remote_file_s3 is enabled' do
+ before do
+ stub_feature_flags(import_project_from_remote_file_s3: true)
+ end
+
+ context 'when the HTTP request fail to recover the headers' do
+ it 'adds the error message' do
+ expect(Gitlab::HTTP)
+ .to receive(:head)
+ .and_raise(StandardError, 'request invalid')
+
+ expect(subject).not_to be_valid
+ expect(subject.errors.full_messages)
+ .to include('Failed to retrive headers: request invalid')
+ end
+ end
+
+ it 'validates the remote content-length' do
+ stub_headers_for(remote_url, { 'content-length' => 11.gigabytes })
+
+ expect(subject).not_to be_valid
+ expect(subject.errors.full_messages)
+ .to include('Content length is too big (should be at most 10 GB)')
+ end
+
+ it 'validates the remote content-type' do
+ stub_headers_for(remote_url, { 'content-type' => 'unknown' })
+
+ expect(subject).not_to be_valid
+ expect(subject.errors.full_messages)
+ .to include("Content type 'unknown' not allowed. (Allowed: application/gzip, application/x-tar, application/x-gzip)")
+ end
+
+ context 'when trying to import from AWS S3' do
+ it 'adds an error suggesting to use `projects/remote-import-s3`' do
+ stub_headers_for(
+ remote_url,
+ 'Server' => 'AmazonS3',
+ 'x-amz-request-id' => 'some-id'
+ )
+
+ expect(subject).not_to be_valid
+ expect(subject.errors.full_messages)
+ .to include('To import from AWS S3 use `projects/remote-import-s3`')
+ end
+ end
+ end
+
+ context 'when import_project_from_remote_file_s3 is disabled' do
+ before do
+ stub_feature_flags(import_project_from_remote_file_s3: false)
+ end
+
+ context 'when trying to import from AWS S3' do
+ it 'does not validate the remote content-length or content-type' do
+ stub_headers_for(
+ remote_url,
+ 'Server' => 'AmazonS3',
+ 'x-amz-request-id' => 'some-id',
+ 'content-length' => 11.gigabytes,
+ 'content-type' => 'unknown'
+ )
+
+ expect(subject).to be_valid
+ end
+ end
+
+ context 'when NOT trying to import from AWS S3' do
+ it 'validates content-length and content-type' do
+ stub_headers_for(
+ remote_url,
+ 'Server' => 'NOT AWS S3',
+ 'content-length' => 11.gigabytes,
+ 'content-type' => 'unknown'
+ )
+
+ expect(subject).not_to be_valid
+
+ expect(subject.errors.full_messages)
+ .to include("Content type 'unknown' not allowed. (Allowed: application/gzip, application/x-tar, application/x-gzip)")
+ expect(subject.errors.full_messages)
+ .to include('Content length is too big (should be at most 10 GB)')
+ end
+ end
+ end
+ end
+
+ describe '#project_params' do
+ it 'returns import_export_upload in the params' do
+ subject = described_class.new(params: { remote_import_url: remote_url })
+
+ expect(subject.project_params).to match(
+ import_export_upload: an_instance_of(::ImportExportUpload)
+ )
+ expect(subject.project_params[:import_export_upload]).to have_attributes(
+ remote_import_url: remote_url
+ )
+ end
+ end
+
+ def stub_headers_for(url, headers = {})
+ allow(Gitlab::HTTP)
+ .to receive(:head)
+ .with(remote_url, timeout: 1.second)
+ .and_return(double(headers: headers)) # rubocop: disable RSpec/VerifiedDoubles
+ end
+end
diff --git a/spec/services/issue_links/create_service_spec.rb b/spec/services/issue_links/create_service_spec.rb
index 1bca717acb7..9cb5980716a 100644
--- a/spec/services/issue_links/create_service_spec.rb
+++ b/spec/services/issue_links/create_service_spec.rb
@@ -4,180 +4,42 @@ require 'spec_helper'
RSpec.describe IssueLinks::CreateService do
describe '#execute' do
- let(:namespace) { create :namespace }
- let(:project) { create :project, namespace: namespace }
- let(:issue) { create :issue, project: project }
- let(:user) { create :user }
- let(:params) do
- {}
- end
+ let_it_be(:user) { create :user }
+ let_it_be(:namespace) { create :namespace }
+ let_it_be(:project) { create :project, namespace: namespace }
+ let_it_be(:issuable) { create :issue, project: project }
+ let_it_be(:issuable2) { create :issue, project: project }
+ let_it_be(:guest_issuable) { create :issue }
+ let_it_be(:another_project) { create :project, namespace: project.namespace }
+ let_it_be(:issuable3) { create :issue, project: another_project }
+ let_it_be(:issuable_a) { create :issue, project: project }
+ let_it_be(:issuable_b) { create :issue, project: project }
+ let_it_be(:issuable_link) { create :issue_link, source: issuable, target: issuable_b, link_type: IssueLink::TYPE_RELATES_TO }
+
+ let(:issuable_parent) { issuable.project }
+ let(:issuable_type) { :issue }
+ let(:issuable_link_class) { IssueLink }
+ let(:params) { {} }
before do
project.add_developer(user)
+ guest_issuable.project.add_guest(user)
+ another_project.add_developer(user)
end
- subject { described_class.new(issue, user, params).execute }
+ it_behaves_like 'issuable link creation'
- context 'when the reference list is empty' do
- let(:params) do
- { issuable_references: [] }
- end
+ context 'when target is an incident' do
+ let_it_be(:issue) { create(:incident, project: project) }
- it 'returns error' do
- is_expected.to eq(message: 'No matching issue found. Make sure that you are adding a valid issue URL.', status: :error, http_status: 404)
- end
- end
-
- context 'when Issue not found' do
let(:params) do
- { issuable_references: ["##{non_existing_record_iid}"] }
- end
-
- it 'returns error' do
- is_expected.to eq(message: 'No matching issue found. Make sure that you are adding a valid issue URL.', status: :error, http_status: 404)
+ { issuable_references: [issuable2.to_reference, issuable3.to_reference(another_project)] }
end
- it 'no relationship is created' do
- expect { subject }.not_to change(IssueLink, :count)
- end
- end
-
- context 'when user has no permission to target project Issue' do
- let(:target_issuable) { create :issue }
-
- let(:params) do
- { issuable_references: [target_issuable.to_reference(project)] }
- end
-
- it 'returns error' do
- target_issuable.project.add_guest(user)
-
- is_expected.to eq(message: 'No matching issue found. Make sure that you are adding a valid issue URL.', status: :error, http_status: 404)
- end
-
- it 'no relationship is created' do
- expect { subject }.not_to change(IssueLink, :count)
- end
- end
-
- context 'source and target are the same issue' do
- let(:params) do
- { issuable_references: [issue.to_reference] }
- end
-
- it 'does not create notes' do
- expect(SystemNoteService).not_to receive(:relate_issue)
-
- subject
- end
-
- it 'no relationship is created' do
- expect { subject }.not_to change(IssueLink, :count)
- end
- end
-
- context 'when there is an issue to relate' do
- let(:issue_a) { create :issue, project: project }
- let(:another_project) { create :project, namespace: project.namespace }
- let(:another_project_issue) { create :issue, project: another_project }
-
- let(:issue_a_ref) { issue_a.to_reference }
- let(:another_project_issue_ref) { another_project_issue.to_reference(project) }
-
- let(:params) do
- { issuable_references: [issue_a_ref, another_project_issue_ref] }
- end
-
- before do
- another_project.add_developer(user)
- end
-
- it 'creates relationships' do
- expect { subject }.to change(IssueLink, :count).from(0).to(2)
-
- expect(IssueLink.find_by!(target: issue_a)).to have_attributes(source: issue, link_type: 'relates_to')
- expect(IssueLink.find_by!(target: another_project_issue)).to have_attributes(source: issue, link_type: 'relates_to')
- end
-
- it 'returns success status' do
- is_expected.to eq(status: :success)
- end
-
- it 'creates notes' do
- # First two-way relation notes
- expect(SystemNoteService).to receive(:relate_issue)
- .with(issue, issue_a, user)
- expect(SystemNoteService).to receive(:relate_issue)
- .with(issue_a, issue, user)
-
- # Second two-way relation notes
- expect(SystemNoteService).to receive(:relate_issue)
- .with(issue, another_project_issue, user)
- expect(SystemNoteService).to receive(:relate_issue)
- .with(another_project_issue, issue, user)
-
- subject
- end
-
- context 'issue is an incident' do
- let(:issue) { create(:incident, project: project) }
-
- it_behaves_like 'an incident management tracked event', :incident_management_incident_relate do
- let(:current_user) { user }
- end
- end
- end
-
- context 'when reference of any already related issue is present' do
- let(:issue_a) { create :issue, project: project }
- let(:issue_b) { create :issue, project: project }
- let(:issue_c) { create :issue, project: project }
-
- before do
- create :issue_link, source: issue, target: issue_b, link_type: IssueLink::TYPE_RELATES_TO
- create :issue_link, source: issue, target: issue_c, link_type: IssueLink::TYPE_RELATES_TO
- end
-
- let(:params) do
- {
- issuable_references: [
- issue_a.to_reference,
- issue_b.to_reference,
- issue_c.to_reference
- ],
- link_type: IssueLink::TYPE_RELATES_TO
- }
- end
-
- it 'creates notes only for new relations' do
- expect(SystemNoteService).to receive(:relate_issue).with(issue, issue_a, anything)
- expect(SystemNoteService).to receive(:relate_issue).with(issue_a, issue, anything)
- expect(SystemNoteService).not_to receive(:relate_issue).with(issue, issue_b, anything)
- expect(SystemNoteService).not_to receive(:relate_issue).with(issue_b, issue, anything)
- expect(SystemNoteService).not_to receive(:relate_issue).with(issue, issue_c, anything)
- expect(SystemNoteService).not_to receive(:relate_issue).with(issue_c, issue, anything)
-
- subject
- end
- end
-
- context 'when there are invalid references' do
- let(:issue_a) { create :issue, project: project }
-
- let(:params) do
- { issuable_references: [issue.to_reference, issue_a.to_reference] }
- end
-
- it 'creates links only for valid references' do
- expect { subject }.to change { IssueLink.count }.by(1)
- end
+ subject { described_class.new(issue, user, params).execute }
- it 'returns error status' do
- expect(subject).to eq(
- status: :error,
- http_status: 422,
- message: "#{issue.to_reference} cannot be added: cannot be related to itself"
- )
+ it_behaves_like 'an incident management tracked event', :incident_management_incident_relate do
+ let(:current_user) { user }
end
end
end
diff --git a/spec/services/issue_links/destroy_service_spec.rb b/spec/services/issue_links/destroy_service_spec.rb
index f441629f892..a478a2c1448 100644
--- a/spec/services/issue_links/destroy_service_spec.rb
+++ b/spec/services/issue_links/destroy_service_spec.rb
@@ -4,65 +4,26 @@ require 'spec_helper'
RSpec.describe IssueLinks::DestroyService do
describe '#execute' do
- let(:project) { create(:project_empty_repo) }
- let(:user) { create(:user) }
+ let_it_be(:project) { create(:project_empty_repo, :private) }
+ let_it_be(:user) { create(:user) }
+ let_it_be(:issue_a) { create(:issue, project: project) }
+ let_it_be(:issue_b) { create(:issue, project: project) }
- subject { described_class.new(issue_link, user).execute }
+ let!(:issuable_link) { create(:issue_link, source: issue_a, target: issue_b) }
- context 'when successfully removes an issue link' do
- let(:issue_a) { create(:issue, project: project) }
- let(:issue_b) { create(:issue, project: project) }
+ subject { described_class.new(issuable_link, user).execute }
- let!(:issue_link) { create(:issue_link, source: issue_a, target: issue_b) }
+ it_behaves_like 'a destroyable issuable link'
+ context 'when target is an incident' do
before do
project.add_reporter(user)
end
- it 'removes related issue' do
- expect { subject }.to change(IssueLink, :count).from(1).to(0)
- end
-
- it 'creates notes' do
- # Two-way notes creation
- expect(SystemNoteService).to receive(:unrelate_issue)
- .with(issue_link.source, issue_link.target, user)
- expect(SystemNoteService).to receive(:unrelate_issue)
- .with(issue_link.target, issue_link.source, user)
-
- subject
- end
-
- it 'returns success message' do
- is_expected.to eq(message: 'Relation was removed', status: :success)
- end
-
- context 'target is an incident' do
- let(:issue_b) { create(:incident, project: project) }
-
- it_behaves_like 'an incident management tracked event', :incident_management_incident_unrelate do
- let(:current_user) { user }
- end
- end
- end
-
- context 'when failing to remove an issue link' do
- let(:unauthorized_project) { create(:project) }
- let(:issue_a) { create(:issue, project: project) }
- let(:issue_b) { create(:issue, project: unauthorized_project) }
-
- let!(:issue_link) { create(:issue_link, source: issue_a, target: issue_b) }
-
- it 'does not remove relation' do
- expect { subject }.not_to change(IssueLink, :count).from(1)
- end
-
- it 'does not create notes' do
- expect(SystemNoteService).not_to receive(:unrelate_issue)
- end
+ let(:issue_b) { create(:incident, project: project) }
- it 'returns error message' do
- is_expected.to eq(message: 'No Issue Link found', status: :error, http_status: 404)
+ it_behaves_like 'an incident management tracked event', :incident_management_incident_unrelate do
+ let(:current_user) { user }
end
end
end
diff --git a/spec/services/issues/create_service_spec.rb b/spec/services/issues/create_service_spec.rb
index f4bb1f0877b..6b7b72d83fc 100644
--- a/spec/services/issues/create_service_spec.rb
+++ b/spec/services/issues/create_service_spec.rb
@@ -11,22 +11,12 @@ RSpec.describe Issues::CreateService do
let(:spam_params) { double }
- describe '.rate_limiter_scoped_and_keyed' do
- it 'is set via the rate_limit call' do
- expect(described_class.rate_limiter_scoped_and_keyed).to be_a(RateLimitedService::RateLimiterScopedAndKeyed)
-
- expect(described_class.rate_limiter_scoped_and_keyed.key).to eq(:issues_create)
- expect(described_class.rate_limiter_scoped_and_keyed.opts[:scope]).to eq(%i[project current_user external_author])
- expect(described_class.rate_limiter_scoped_and_keyed.rate_limiter).to eq(Gitlab::ApplicationRateLimiter)
- end
- end
-
- describe '#rate_limiter_bypassed' do
- let(:subject) { described_class.new(project: project, spam_params: {}) }
-
- it 'is nil by default' do
- expect(subject.rate_limiter_bypassed).to be_nil
- end
+ it_behaves_like 'rate limited service' do
+ let(:key) { :issues_create }
+ let(:key_scope) { %i[project current_user external_author] }
+ let(:application_limit_key) { :issues_create_limit }
+ let(:created_model) { Issue }
+ let(:service) { described_class.new(project: project, current_user: user, params: { title: 'title' }, spam_params: double) }
end
describe '#execute' do
@@ -331,44 +321,6 @@ RSpec.describe Issues::CreateService do
described_class.new(project: project, current_user: user, params: opts, spam_params: spam_params).execute
end
- context 'when rate limiting is in effect', :freeze_time, :clean_gitlab_redis_rate_limiting do
- let(:user) { create(:user) }
-
- before do
- stub_feature_flags(rate_limited_service_issues_create: true)
- stub_application_setting(issues_create_limit: 1)
- end
-
- subject do
- 2.times { described_class.new(project: project, current_user: user, params: opts, spam_params: double).execute }
- end
-
- context 'when too many requests are sent by one user' do
- it 'raises an error' do
- expect do
- subject
- end.to raise_error(RateLimitedService::RateLimitedError)
- end
-
- it 'creates 1 issue' do
- expect do
- subject
- rescue RateLimitedService::RateLimitedError
- end.to change { Issue.count }.by(1)
- end
- end
-
- context 'when limit is higher than count of issues being created' do
- before do
- stub_application_setting(issues_create_limit: 2)
- end
-
- it 'creates 2 issues' do
- expect { subject }.to change { Issue.count }.by(2)
- end
- end
- end
-
context 'after_save callback to store_mentions' do
context 'when mentionable attributes change' do
let(:opts) { { title: 'Title', description: "Description with #{user.to_reference}" } }
@@ -574,6 +526,31 @@ RSpec.describe Issues::CreateService do
end
end
+ context 'add related issue' do
+ let_it_be(:related_issue) { create(:issue, project: project) }
+
+ let(:opts) do
+ { title: 'A new issue', add_related_issue: related_issue }
+ end
+
+ it 'ignores related issue if not accessible' do
+ expect { issue }.not_to change { IssueLink.count }
+ expect(issue).to be_persisted
+ end
+
+ context 'when user has access to the related issue' do
+ before do
+ project.add_developer(user)
+ end
+
+ it 'adds a link to the issue' do
+ expect { issue }.to change { IssueLink.count }.by(1)
+ expect(issue).to be_persisted
+ expect(issue.related_issues(user)).to eq([related_issue])
+ end
+ end
+ end
+
context 'checking spam' do
let(:params) do
{
diff --git a/spec/services/issues/set_crm_contacts_service_spec.rb b/spec/services/issues/set_crm_contacts_service_spec.rb
index 64011a7a003..b0befb9f77c 100644
--- a/spec/services/issues/set_crm_contacts_service_spec.rb
+++ b/spec/services/issues/set_crm_contacts_service_spec.rb
@@ -5,7 +5,7 @@ require 'spec_helper'
RSpec.describe Issues::SetCrmContactsService do
let_it_be(:user) { create(:user) }
let_it_be(:group) { create(:group, :crm_enabled) }
- let_it_be(:project) { create(:project, group: group) }
+ let_it_be(:project) { create(:project, group: create(:group, parent: group)) }
let_it_be(:contacts) { create_list(:contact, 4, group: group) }
let_it_be(:issue, reload: true) { create(:issue, project: project) }
let_it_be(:issue_contact_1) do
diff --git a/spec/services/issues/update_service_spec.rb b/spec/services/issues/update_service_spec.rb
index 95394ba6597..6d3c3dd4e39 100644
--- a/spec/services/issues/update_service_spec.rb
+++ b/spec/services/issues/update_service_spec.rb
@@ -1157,6 +1157,13 @@ RSpec.describe Issues::UpdateService, :mailer do
expect(issue.escalation_status.status_name).to eq(expected_status)
end
+
+ it 'triggers webhooks' do
+ expect(project).to receive(:execute_hooks).with(an_instance_of(Hash), :issue_hooks)
+ expect(project).to receive(:execute_integrations).with(an_instance_of(Hash), :issue_hooks)
+
+ update_issue(opts)
+ end
end
shared_examples 'does not change the status record' do
@@ -1169,7 +1176,8 @@ RSpec.describe Issues::UpdateService, :mailer do
end
it 'does not trigger side-effects' do
- expect(escalation_update_class).not_to receive(:new)
+ expect(project).not_to receive(:execute_hooks)
+ expect(project).not_to receive(:execute_integrations)
update_issue(opts)
end
@@ -1324,32 +1332,14 @@ RSpec.describe Issues::UpdateService, :mailer do
context 'broadcasting issue assignee updates' do
let(:update_params) { { assignee_ids: [user2.id] } }
- context 'when feature flag is enabled' do
- before do
- stub_feature_flags(broadcast_issue_updates: true)
- end
+ it 'triggers the GraphQL subscription' do
+ expect(GraphqlTriggers).to receive(:issuable_assignees_updated).with(issue)
- it 'triggers the GraphQL subscription' do
- expect(GraphqlTriggers).to receive(:issuable_assignees_updated).with(issue)
-
- update_issue(update_params)
- end
-
- context 'when assignee is not updated' do
- let(:update_params) { { title: 'Some other title' } }
-
- it 'does not trigger the GraphQL subscription' do
- expect(GraphqlTriggers).not_to receive(:issuable_assignees_updated).with(issue)
-
- update_issue(update_params)
- end
- end
+ update_issue(update_params)
end
- context 'when feature flag is disabled' do
- before do
- stub_feature_flags(broadcast_issue_updates: false)
- end
+ context 'when assignee is not updated' do
+ let(:update_params) { { title: 'Some other title' } }
it 'does not trigger the GraphQL subscription' do
expect(GraphqlTriggers).not_to receive(:issuable_assignees_updated).with(issue)
diff --git a/spec/services/labels/create_service_spec.rb b/spec/services/labels/create_service_spec.rb
index 7a31a5a7cae..02dec8ae690 100644
--- a/spec/services/labels/create_service_spec.rb
+++ b/spec/services/labels/create_service_spec.rb
@@ -14,7 +14,7 @@ RSpec.describe Labels::CreateService do
let(:unknown_color) { 'unknown' }
let(:no_color) { '' }
- let(:expected_saved_color) { hex_color }
+ let(:expected_saved_color) { ::Gitlab::Color.of(hex_color) }
context 'in a project' do
context 'with color in hex-code' do
@@ -47,7 +47,6 @@ RSpec.describe Labels::CreateService do
context 'with color surrounded by spaces' do
it 'creates a label' do
label = described_class.new(params_with(spaced_color)).execute(project: project)
-
expect(label).to be_persisted
expect(label.color).to eq expected_saved_color
end
diff --git a/spec/services/labels/promote_service_spec.rb b/spec/services/labels/promote_service_spec.rb
index 81c24b26c9f..a10aaa14030 100644
--- a/spec/services/labels/promote_service_spec.rb
+++ b/spec/services/labels/promote_service_spec.rb
@@ -202,7 +202,7 @@ RSpec.describe Labels::PromoteService do
expect(new_label.title).to eq(promoted_label_name)
expect(new_label.description).to eq(promoted_description)
- expect(new_label.color).to eq(promoted_color)
+ expect(new_label.color).to be_color(promoted_color)
end
it_behaves_like 'promoting a project label to a group label'
diff --git a/spec/services/labels/update_service_spec.rb b/spec/services/labels/update_service_spec.rb
index af2403656af..abc456f75f9 100644
--- a/spec/services/labels/update_service_spec.rb
+++ b/spec/services/labels/update_service_spec.rb
@@ -13,7 +13,7 @@ RSpec.describe Labels::UpdateService do
let(:unknown_color) { 'unknown' }
let(:no_color) { '' }
- let(:expected_saved_color) { hex_color }
+ let(:expected_saved_color) { ::Gitlab::Color.of(hex_color) }
before do
@label = Labels::CreateService.new(title: 'Initial', color: '#000000').execute(project: project)
diff --git a/spec/services/members/projects/creator_service_spec.rb b/spec/services/members/projects/creator_service_spec.rb
index c6917a21bcd..7ba183759bc 100644
--- a/spec/services/members/projects/creator_service_spec.rb
+++ b/spec/services/members/projects/creator_service_spec.rb
@@ -9,8 +9,8 @@ RSpec.describe Members::Projects::CreatorService do
end
describe '.access_levels' do
- it 'returns Gitlab::Access.sym_options' do
- expect(described_class.access_levels).to eq(Gitlab::Access.sym_options)
+ it 'returns Gitlab::Access.sym_options_with_owner' do
+ expect(described_class.access_levels).to eq(Gitlab::Access.sym_options_with_owner)
end
end
end
diff --git a/spec/services/merge_requests/approval_service_spec.rb b/spec/services/merge_requests/approval_service_spec.rb
index 4d20d62b864..9b064da44b8 100644
--- a/spec/services/merge_requests/approval_service_spec.rb
+++ b/spec/services/merge_requests/approval_service_spec.rb
@@ -61,7 +61,7 @@ RSpec.describe MergeRequests::ApprovalService do
it 'removes attention requested state' do
expect(MergeRequests::RemoveAttentionRequestedService).to receive(:new)
- .with(project: project, current_user: user, merge_request: merge_request, user: user)
+ .with(project: project, current_user: user, merge_request: merge_request)
.and_call_original
service.execute(merge_request)
diff --git a/spec/services/merge_requests/bulk_remove_attention_requested_service_spec.rb b/spec/services/merge_requests/bulk_remove_attention_requested_service_spec.rb
index ae8846974ce..b2326a28e63 100644
--- a/spec/services/merge_requests/bulk_remove_attention_requested_service_spec.rb
+++ b/spec/services/merge_requests/bulk_remove_attention_requested_service_spec.rb
@@ -40,6 +40,10 @@ RSpec.describe MergeRequests::BulkRemoveAttentionRequestedService do
expect(reviewer.state).to eq 'reviewed'
expect(assignee.state).to eq 'reviewed'
end
+
+ it_behaves_like 'invalidates attention request cache' do
+ let(:users) { [assignee_user, user] }
+ 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 a196c944eda..49f691e97e2 100644
--- a/spec/services/merge_requests/create_service_spec.rb
+++ b/spec/services/merge_requests/create_service_spec.rb
@@ -454,7 +454,7 @@ RSpec.describe MergeRequests::CreateService, :clean_gitlab_redis_shared_state do
end
end
- context 'when source and target projects are different' do
+ shared_examples 'when source and target projects are different' do
let(:target_project) { fork_project(project, nil, repository: true) }
let(:opts) do
@@ -497,9 +497,14 @@ RSpec.describe MergeRequests::CreateService, :clean_gitlab_redis_shared_state do
end
it 'creates the merge request', :sidekiq_might_not_need_inline do
+ expect_next_instance_of(MergeRequest) do |instance|
+ expect(instance).to receive(:eager_fetch_ref!).and_call_original
+ end
+
merge_request = described_class.new(project: project, current_user: user, params: opts).execute
expect(merge_request).to be_persisted
+ expect(merge_request.iid).to be > 0
end
it 'does not create the merge request when the target project is archived' do
@@ -511,6 +516,8 @@ RSpec.describe MergeRequests::CreateService, :clean_gitlab_redis_shared_state do
end
end
+ it_behaves_like 'when source and target projects are different'
+
context 'when user sets source project id' do
let(:another_project) { create(:project) }
diff --git a/spec/services/merge_requests/handle_assignees_change_service_spec.rb b/spec/services/merge_requests/handle_assignees_change_service_spec.rb
index fa3b1614e21..26f53f55b0f 100644
--- a/spec/services/merge_requests/handle_assignees_change_service_spec.rb
+++ b/spec/services/merge_requests/handle_assignees_change_service_spec.rb
@@ -89,12 +89,18 @@ RSpec.describe MergeRequests::HandleAssigneesChangeService do
it 'removes attention requested state' do
expect(MergeRequests::RemoveAttentionRequestedService).to receive(:new)
- .with(project: project, current_user: user, merge_request: merge_request, user: user)
+ .with(project: project, current_user: user, merge_request: merge_request)
.and_call_original
execute
end
+ it 'updates attention requested by of assignee' do
+ execute
+
+ expect(merge_request.find_assignee(assignee).updated_state_by).to eq(user)
+ end
+
it 'tracks users assigned event' do
expect(Gitlab::UsageDataCounters::MergeRequestActivityUniqueCounter)
.to receive(:track_users_assigned_to_mr).once.with(users: [assignee])
diff --git a/spec/services/merge_requests/merge_orchestration_service_spec.rb b/spec/services/merge_requests/merge_orchestration_service_spec.rb
index da37cc97857..ebcd2f0e277 100644
--- a/spec/services/merge_requests/merge_orchestration_service_spec.rb
+++ b/spec/services/merge_requests/merge_orchestration_service_spec.rb
@@ -64,7 +64,7 @@ RSpec.describe MergeRequests::MergeOrchestrationService do
context 'when merge request is not mergeable' do
before do
- allow(merge_request).to receive(:mergeable_state?) { false }
+ allow(merge_request).to receive(:mergeable?) { false }
end
it 'does nothing' do
@@ -87,7 +87,7 @@ RSpec.describe MergeRequests::MergeOrchestrationService do
context 'when merge request is not mergeable' do
before do
- allow(merge_request).to receive(:mergeable_state?) { false }
+ allow(merge_request).to receive(:mergeable?) { false }
end
it { is_expected.to eq(false) }
diff --git a/spec/services/merge_requests/mergeability/check_broken_status_service_spec.rb b/spec/services/merge_requests/mergeability/check_broken_status_service_spec.rb
new file mode 100644
index 00000000000..9e178c121ef
--- /dev/null
+++ b/spec/services/merge_requests/mergeability/check_broken_status_service_spec.rb
@@ -0,0 +1,43 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe MergeRequests::Mergeability::CheckBrokenStatusService do
+ subject(:check_broken_status) { described_class.new(merge_request: merge_request, params: {}) }
+
+ let(:merge_request) { build(:merge_request) }
+
+ describe '#execute' do
+ before do
+ expect(merge_request).to receive(:broken?).and_return(broken)
+ end
+
+ context 'when the merge request is broken' do
+ let(:broken) { true }
+
+ it 'returns a check result with status failed' do
+ expect(check_broken_status.execute.status).to eq Gitlab::MergeRequests::Mergeability::CheckResult::FAILED_STATUS
+ end
+ end
+
+ context 'when the merge request is not broken' do
+ let(:broken) { false }
+
+ it 'returns a check result with status success' do
+ expect(check_broken_status.execute.status).to eq Gitlab::MergeRequests::Mergeability::CheckResult::SUCCESS_STATUS
+ end
+ end
+ end
+
+ describe '#skip?' do
+ it 'returns false' do
+ expect(check_broken_status.skip?).to eq false
+ end
+ end
+
+ describe '#cacheable?' do
+ it 'returns false' do
+ expect(check_broken_status.cacheable?).to eq false
+ end
+ end
+end
diff --git a/spec/services/merge_requests/mergeability/check_discussions_status_service_spec.rb b/spec/services/merge_requests/mergeability/check_discussions_status_service_spec.rb
new file mode 100644
index 00000000000..c24d40967c4
--- /dev/null
+++ b/spec/services/merge_requests/mergeability/check_discussions_status_service_spec.rb
@@ -0,0 +1,57 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe MergeRequests::Mergeability::CheckDiscussionsStatusService do
+ subject(:check_discussions_status) { described_class.new(merge_request: merge_request, params: params) }
+
+ let(:merge_request) { build(:merge_request) }
+ let(:params) { { skip_discussions_check: skip_check } }
+ let(:skip_check) { false }
+
+ describe '#execute' do
+ before do
+ expect(merge_request).to receive(:mergeable_discussions_state?).and_return(mergeable)
+ end
+
+ context 'when the merge request is in a mergable state' do
+ let(:mergeable) { true }
+
+ it 'returns a check result with status success' do
+ expect(check_discussions_status.execute.status).to eq Gitlab::MergeRequests::Mergeability::CheckResult::SUCCESS_STATUS
+ end
+ end
+
+ context 'when the merge request is not in a mergeable state' do
+ let(:mergeable) { false }
+
+ it 'returns a check result with status failed' do
+ expect(check_discussions_status.execute.status).to eq Gitlab::MergeRequests::Mergeability::CheckResult::FAILED_STATUS
+ end
+ end
+ end
+
+ describe '#skip?' do
+ context 'when skip check is true' do
+ let(:skip_check) { true }
+
+ it 'returns true' do
+ expect(check_discussions_status.skip?).to eq true
+ end
+ end
+
+ context 'when skip check is false' do
+ let(:skip_check) { false }
+
+ it 'returns false' do
+ expect(check_discussions_status.skip?).to eq false
+ end
+ end
+ end
+
+ describe '#cacheable?' do
+ it 'returns false' do
+ expect(check_discussions_status.cacheable?).to eq false
+ end
+ end
+end
diff --git a/spec/services/merge_requests/mergeability/check_draft_status_service_spec.rb b/spec/services/merge_requests/mergeability/check_draft_status_service_spec.rb
new file mode 100644
index 00000000000..923cff220ef
--- /dev/null
+++ b/spec/services/merge_requests/mergeability/check_draft_status_service_spec.rb
@@ -0,0 +1,43 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe MergeRequests::Mergeability::CheckDraftStatusService do
+ subject(:check_draft_status) { described_class.new(merge_request: merge_request, params: {}) }
+
+ let(:merge_request) { build(:merge_request) }
+
+ describe '#execute' do
+ before do
+ expect(merge_request).to receive(:draft?).and_return(draft)
+ end
+
+ context 'when the merge request is a draft' do
+ let(:draft) { true }
+
+ it 'returns a check result with status failed' do
+ expect(check_draft_status.execute.status).to eq Gitlab::MergeRequests::Mergeability::CheckResult::FAILED_STATUS
+ end
+ end
+
+ context 'when the merge request is not a draft' do
+ let(:draft) { false }
+
+ it 'returns a check result with status success' do
+ expect(check_draft_status.execute.status).to eq Gitlab::MergeRequests::Mergeability::CheckResult::SUCCESS_STATUS
+ end
+ end
+ end
+
+ describe '#skip?' do
+ it 'returns false' do
+ expect(check_draft_status.skip?).to eq false
+ end
+ end
+
+ describe '#cacheable?' do
+ it 'returns false' do
+ expect(check_draft_status.cacheable?).to eq false
+ end
+ end
+end
diff --git a/spec/services/merge_requests/mergeability/check_open_status_service_spec.rb b/spec/services/merge_requests/mergeability/check_open_status_service_spec.rb
new file mode 100644
index 00000000000..b1c9a930317
--- /dev/null
+++ b/spec/services/merge_requests/mergeability/check_open_status_service_spec.rb
@@ -0,0 +1,43 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe MergeRequests::Mergeability::CheckOpenStatusService do
+ subject(:check_open_status) { described_class.new(merge_request: merge_request, params: {}) }
+
+ let(:merge_request) { build(:merge_request) }
+
+ describe '#execute' do
+ before do
+ expect(merge_request).to receive(:open?).and_return(open)
+ end
+
+ context 'when the merge request is open' do
+ let(:open) { true }
+
+ it 'returns a check result with status success' do
+ expect(check_open_status.execute.status).to eq Gitlab::MergeRequests::Mergeability::CheckResult::SUCCESS_STATUS
+ end
+ end
+
+ context 'when the merge request is not open' do
+ let(:open) { false }
+
+ it 'returns a check result with status failed' do
+ expect(check_open_status.execute.status).to eq Gitlab::MergeRequests::Mergeability::CheckResult::FAILED_STATUS
+ end
+ end
+ end
+
+ describe '#skip?' do
+ it 'returns false' do
+ expect(check_open_status.skip?).to eq false
+ end
+ end
+
+ describe '#cacheable?' do
+ it 'returns false' do
+ expect(check_open_status.cacheable?).to eq false
+ end
+ end
+end
diff --git a/spec/services/merge_requests/mergeability/run_checks_service_spec.rb b/spec/services/merge_requests/mergeability/run_checks_service_spec.rb
index 71ad23bc68c..d4ee4afd71d 100644
--- a/spec/services/merge_requests/mergeability/run_checks_service_spec.rb
+++ b/spec/services/merge_requests/mergeability/run_checks_service_spec.rb
@@ -35,12 +35,19 @@ RSpec.describe MergeRequests::Mergeability::RunChecksService do
context 'when a check is skipped' do
it 'does not execute the check' do
+ described_class::CHECKS.each do |check|
+ allow_next_instance_of(check) do |service|
+ allow(service).to receive(:skip?).and_return(false)
+ allow(service).to receive(:execute).and_return(success_result)
+ end
+ end
+
expect_next_instance_of(MergeRequests::Mergeability::CheckCiStatusService) do |service|
expect(service).to receive(:skip?).and_return(true)
expect(service).not_to receive(:execute)
end
- expect(execute).to match_array([])
+ expect(execute).to match_array([success_result, success_result, success_result, success_result])
end
end
@@ -49,6 +56,12 @@ RSpec.describe MergeRequests::Mergeability::RunChecksService do
let(:merge_check) { instance_double(MergeRequests::Mergeability::CheckCiStatusService) }
before do
+ described_class::CHECKS.each do |check|
+ allow_next_instance_of(check) do |service|
+ allow(service).to receive(:skip?).and_return(true)
+ end
+ end
+
expect(MergeRequests::Mergeability::CheckCiStatusService).to receive(:new).and_return(merge_check)
expect(merge_check).to receive(:skip?).and_return(false)
allow(merge_check).to receive(:cacheable?).and_return(cacheable)
diff --git a/spec/services/merge_requests/reload_merge_head_diff_service_spec.rb b/spec/services/merge_requests/reload_merge_head_diff_service_spec.rb
index b333d4af6cf..20b5cf5e3a1 100644
--- a/spec/services/merge_requests/reload_merge_head_diff_service_spec.rb
+++ b/spec/services/merge_requests/reload_merge_head_diff_service_spec.rb
@@ -47,15 +47,5 @@ RSpec.describe MergeRequests::ReloadMergeHeadDiffService do
expect(merge_request.reload.merge_head_diff).not_to eq(existing_merge_head_diff)
end
end
-
- context 'when default_merge_ref_for_diffs feature flag is disabled' do
- before do
- stub_feature_flags(default_merge_ref_for_diffs: false)
- end
-
- it 'returns error' do
- expect(subject[:status]).to eq(:error)
- end
- end
end
end
diff --git a/spec/services/merge_requests/remove_attention_requested_service_spec.rb b/spec/services/merge_requests/remove_attention_requested_service_spec.rb
index 875afc2dc7e..450204ebfdd 100644
--- a/spec/services/merge_requests/remove_attention_requested_service_spec.rb
+++ b/spec/services/merge_requests/remove_attention_requested_service_spec.rb
@@ -4,23 +4,20 @@ require 'spec_helper'
RSpec.describe MergeRequests::RemoveAttentionRequestedService do
let(:current_user) { create(:user) }
- let(:user) { create(:user) }
- let(:assignee_user) { create(:user) }
- let(:merge_request) { create(:merge_request, reviewers: [user], assignees: [assignee_user]) }
- let(:reviewer) { merge_request.find_reviewer(user) }
- let(:assignee) { merge_request.find_assignee(assignee_user) }
+ let(:merge_request) { create(:merge_request, reviewers: [current_user], assignees: [current_user]) }
+ let(:reviewer) { merge_request.find_reviewer(current_user) }
+ let(:assignee) { merge_request.find_assignee(current_user) }
let(:project) { merge_request.project }
- let(:service) { described_class.new(project: project, current_user: current_user, merge_request: merge_request, user: user) }
+ let(:service) { described_class.new(project: project, current_user: current_user, merge_request: merge_request) }
let(:result) { service.execute }
before do
project.add_developer(current_user)
- project.add_developer(user)
end
describe '#execute' do
context 'invalid permissions' do
- let(:service) { described_class.new(project: project, current_user: create(:user), merge_request: merge_request, user: user) }
+ let(:service) { described_class.new(project: project, current_user: create(:user), merge_request: merge_request) }
it 'returns an error' do
expect(result[:status]).to eq :error
@@ -28,7 +25,7 @@ RSpec.describe MergeRequests::RemoveAttentionRequestedService do
end
context 'reviewer does not exist' do
- let(:service) { described_class.new(project: project, current_user: current_user, merge_request: merge_request, user: create(:user)) }
+ let(:service) { described_class.new(project: project, current_user: create(:user), merge_request: merge_request) }
it 'returns an error' do
expect(result[:status]).to eq :error
@@ -46,10 +43,14 @@ RSpec.describe MergeRequests::RemoveAttentionRequestedService do
expect(reviewer.state).to eq 'reviewed'
end
+
+ it_behaves_like 'invalidates attention request cache' do
+ let(:users) { [current_user] }
+ end
end
context 'assignee exists' do
- let(:service) { described_class.new(project: project, current_user: current_user, merge_request: merge_request, user: assignee_user) }
+ let(:service) { described_class.new(project: project, current_user: current_user, merge_request: merge_request) }
before do
assignee.update!(state: :reviewed)
@@ -65,12 +66,16 @@ RSpec.describe MergeRequests::RemoveAttentionRequestedService do
expect(assignee.state).to eq 'reviewed'
end
+
+ it_behaves_like 'invalidates attention request cache' do
+ let(:users) { [current_user] }
+ end
end
context 'assignee is the same as reviewer' do
- let(:merge_request) { create(:merge_request, reviewers: [user], assignees: [user]) }
- let(:service) { described_class.new(project: project, current_user: current_user, merge_request: merge_request, user: user) }
- let(:assignee) { merge_request.find_assignee(user) }
+ let(:merge_request) { create(:merge_request, reviewers: [current_user], assignees: [current_user]) }
+ let(:service) { described_class.new(project: project, current_user: current_user, merge_request: merge_request) }
+ let(:assignee) { merge_request.find_assignee(current_user) }
it 'updates reviewers and assignees state' do
service.execute
diff --git a/spec/services/merge_requests/toggle_attention_requested_service_spec.rb b/spec/services/merge_requests/toggle_attention_requested_service_spec.rb
index 63fa61b8097..dcaac5d2699 100644
--- a/spec/services/merge_requests/toggle_attention_requested_service_spec.rb
+++ b/spec/services/merge_requests/toggle_attention_requested_service_spec.rb
@@ -59,6 +59,13 @@ RSpec.describe MergeRequests::ToggleAttentionRequestedService do
expect(reviewer.state).to eq 'attention_requested'
end
+ it 'adds who toggled attention' do
+ service.execute
+ reviewer.reload
+
+ expect(reviewer.updated_state_by).to eq current_user
+ end
+
it 'creates a new todo for the reviewer' do
expect(todo_service).to receive(:create_attention_requested_todo).with(merge_request, current_user, user)
@@ -73,11 +80,21 @@ RSpec.describe MergeRequests::ToggleAttentionRequestedService do
it 'removes attention requested state' do
expect(MergeRequests::RemoveAttentionRequestedService).to receive(:new)
- .with(project: project, current_user: current_user, merge_request: merge_request, user: current_user)
+ .with(project: project, current_user: current_user, merge_request: merge_request)
.and_call_original
service.execute
end
+
+ it 'invalidates cache' do
+ cache_mock = double
+
+ expect(cache_mock).to receive(:delete).with(['users', user.id, 'attention_requested_open_merge_requests_count'])
+
+ allow(Rails).to receive(:cache).and_return(cache_mock)
+
+ service.execute
+ end
end
context 'assignee exists' do
@@ -112,11 +129,15 @@ RSpec.describe MergeRequests::ToggleAttentionRequestedService do
it 'removes attention requested state' do
expect(MergeRequests::RemoveAttentionRequestedService).to receive(:new)
- .with(project: project, current_user: current_user, merge_request: merge_request, user: current_user)
+ .with(project: project, current_user: current_user, merge_request: merge_request)
.and_call_original
service.execute
end
+
+ it_behaves_like 'invalidates attention request cache' do
+ let(:users) { [assignee_user] }
+ end
end
context 'assignee is the same as reviewer' do
diff --git a/spec/services/merge_requests/update_service_spec.rb b/spec/services/merge_requests/update_service_spec.rb
index 48d9f019274..eb587797201 100644
--- a/spec/services/merge_requests/update_service_spec.rb
+++ b/spec/services/merge_requests/update_service_spec.rb
@@ -215,6 +215,14 @@ RSpec.describe MergeRequests::UpdateService, :mailer do
MergeRequests::UpdateService.new(project: project, current_user: user, params: opts).execute(merge_request)
end
+
+ it 'updates attention requested by of reviewer' do
+ opts[:reviewers] = [user2]
+
+ MergeRequests::UpdateService.new(project: project, current_user: user, params: opts).execute(merge_request)
+
+ expect(merge_request.find_reviewer(user2).updated_state_by).to eq(user)
+ end
end
context 'when reviewers did not change' do
diff --git a/spec/services/notification_service_spec.rb b/spec/services/notification_service_spec.rb
index 9cbc16f0c95..399b2b4be2d 100644
--- a/spec/services/notification_service_spec.rb
+++ b/spec/services/notification_service_spec.rb
@@ -7,7 +7,7 @@ RSpec.describe NotificationService, :mailer do
include ExternalAuthorizationServiceHelpers
include NotificationHelpers
- let_it_be_with_refind(:project) { create(:project, :public) }
+ let_it_be_with_refind(:project, reload: true) { create(:project, :public) }
let_it_be_with_refind(:assignee) { create(:user) }
let(:notification) { described_class.new }
@@ -258,6 +258,27 @@ RSpec.describe NotificationService, :mailer do
end
describe 'AccessToken' do
+ describe '#access_token_created' do
+ let_it_be(:user) { create(:user) }
+ let_it_be(:pat) { create(:personal_access_token, user: user) }
+
+ subject(:notification_service) { notification.access_token_created(user, pat.name) }
+
+ it 'sends email to the token owner' do
+ expect { notification_service }.to have_enqueued_email(user, pat.name, mail: "access_token_created_email")
+ end
+
+ context 'when user is not allowed to receive notifications' do
+ before do
+ user.block!
+ end
+
+ it 'does not send email to the token owner' do
+ expect { notification_service }.not_to have_enqueued_email(user, pat.name, mail: "access_token_created_email")
+ end
+ end
+ end
+
describe '#access_token_about_to_expire' do
let_it_be(:user) { create(:user) }
let_it_be(:pat) { create(:personal_access_token, user: user, expires_at: 5.days.from_now) }
@@ -1051,6 +1072,7 @@ RSpec.describe NotificationService, :mailer do
end
before do
+ project.reload
add_user_subscriptions(issue)
reset_delivered_emails!
update_custom_notification(:new_issue, @u_guest_custom, resource: project)
@@ -3312,7 +3334,7 @@ RSpec.describe NotificationService, :mailer do
describe "##{sym}" do
subject(:notify!) { notification.send(sym, domain) }
- it 'emails current watching maintainers' do
+ it 'emails current watching maintainers and owners' do
expect(Notify).to receive(:"#{sym}_email").at_least(:once).and_call_original
notify!
@@ -3410,7 +3432,7 @@ RSpec.describe NotificationService, :mailer do
reset_delivered_emails!
end
- it 'emails current watching maintainers' do
+ it 'emails current watching maintainers and owners' do
notification.remote_mirror_update_failed(remote_mirror)
should_only_email(u_maintainer1, u_maintainer2, u_owner)
diff --git a/spec/services/packages/pypi/create_package_service_spec.rb b/spec/services/packages/pypi/create_package_service_spec.rb
index 3d0c10724d4..f84a77f80f7 100644
--- a/spec/services/packages/pypi/create_package_service_spec.rb
+++ b/spec/services/packages/pypi/create_package_service_spec.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'spec_helper'
-RSpec.describe Packages::Pypi::CreatePackageService do
+RSpec.describe Packages::Pypi::CreatePackageService, :aggregate_failures do
include PackagesManagerApiSpecHelpers
let_it_be(:project) { create(:project) }
@@ -39,6 +39,18 @@ RSpec.describe Packages::Pypi::CreatePackageService do
end
end
+ context 'without required_python' do
+ before do
+ params.delete(:requires_python)
+ end
+
+ it 'creates the package' do
+ expect { subject }.to change { Packages::Package.pypi.count }.by(1)
+
+ expect(created_package.pypi_metadatum.required_python).to eq ''
+ end
+ end
+
context 'with an invalid metadata' do
let(:requires_python) { 'x' * 256 }
@@ -73,7 +85,7 @@ RSpec.describe Packages::Pypi::CreatePackageService do
.and raise_error(/File name has already been taken/)
end
- context 'with a pending_destruction package', :aggregate_failures do
+ context 'with a pending_destruction package' do
before do
Packages::Package.pypi.last.pending_destruction!
end
diff --git a/spec/services/personal_access_tokens/create_service_spec.rb b/spec/services/personal_access_tokens/create_service_spec.rb
index 842bebd13a1..b8a4c8f30d2 100644
--- a/spec/services/personal_access_tokens/create_service_spec.rb
+++ b/spec/services/personal_access_tokens/create_service_spec.rb
@@ -18,6 +18,14 @@ RSpec.describe PersonalAccessTokens::CreateService do
subject
end
+
+ it 'notifies the user' do
+ expect_next_instance_of(NotificationService) do |notification_service|
+ expect(notification_service).to receive(:access_token_created).with(user, params[:name])
+ end
+
+ subject
+ end
end
shared_examples_for 'an unsuccessfully created token' do
diff --git a/spec/services/projects/branches_by_mode_service_spec.rb b/spec/services/projects/branches_by_mode_service_spec.rb
index e8bcda8a9c4..9a63563b37b 100644
--- a/spec/services/projects/branches_by_mode_service_spec.rb
+++ b/spec/services/projects/branches_by_mode_service_spec.rb
@@ -13,20 +13,22 @@ RSpec.describe Projects::BranchesByModeService do
describe '#execute' do
context 'page is passed' do
- let(:params) { { page: 4, mode: 'all', offset: 3 } }
+ let(:page) { (TestEnv::BRANCH_SHA.length.to_f / Kaminari.config.default_per_page).ceil }
+ let(:params) { { page: page, mode: 'all', offset: page - 1 } }
it 'uses offset pagination' do
expect(finder).to receive(:fetch_branches_via_offset_pagination).and_call_original
branches, prev_page, next_page = subject
+ remaining = TestEnv::BRANCH_SHA.length % Kaminari.config.default_per_page
- expect(branches.size).to eq(11)
+ expect(branches.size).to eq(remaining > 0 ? remaining : 20)
expect(next_page).to be_nil
- expect(prev_page).to eq("/#{project.full_path}/-/branches/all?offset=2&page=3")
+ expect(prev_page).to eq("/#{project.full_path}/-/branches/all?offset=#{page - 2}&page=#{page - 1}")
end
context 'but the page does not contain any branches' do
- let(:params) { { page: 10, mode: 'all' } }
+ let(:params) { { page: 100, mode: 'all' } }
it 'uses offset pagination' do
expect(finder).to receive(:fetch_branches_via_offset_pagination).and_call_original
@@ -61,9 +63,10 @@ RSpec.describe Projects::BranchesByModeService do
expect(finder).to receive(:fetch_branches_via_offset_pagination).and_call_original
branches, prev_page, next_page = subject
+ expected_page_token = ERB::Util.url_encode(TestEnv::BRANCH_SHA.sort[19][0])
expect(branches.size).to eq(20)
- expect(next_page).to eq("/#{project.full_path}/-/branches/all?offset=1&page_token=conflict-resolvable")
+ expect(next_page).to eq("/#{project.full_path}/-/branches/all?offset=1&page_token=#{expected_page_token}")
expect(prev_page).to be_nil
end
end
@@ -75,26 +78,31 @@ RSpec.describe Projects::BranchesByModeService do
it 'returns branches for the first page' do
branches, prev_page, next_page = subject
+ expected_page_token = ERB::Util.url_encode(TestEnv::BRANCH_SHA.sort[19][0])
expect(branches.size).to eq(20)
- expect(next_page).to eq("/#{project.full_path}/-/branches/all?offset=1&page_token=conflict-resolvable")
+ expect(next_page).to eq("/#{project.full_path}/-/branches/all?offset=1&page_token=#{expected_page_token}")
expect(prev_page).to be_nil
end
context 'when second page is requested' do
- let(:params) { { page_token: 'conflict-resolvable', mode: 'all', sort: 'name_asc', offset: 1 } }
+ let(:page_token) { 'conflict-resolvable' }
+ let(:params) { { page_token: page_token, mode: 'all', sort: 'name_asc', offset: 1 } }
it 'returns branches for the first page' do
branches, prev_page, next_page = subject
+ branch_index = TestEnv::BRANCH_SHA.sort.find_index { |a| a[0] == page_token }
+ expected_page_token = ERB::Util.url_encode(TestEnv::BRANCH_SHA.sort[20 + branch_index][0])
expect(branches.size).to eq(20)
- expect(next_page).to eq("/#{project.full_path}/-/branches/all?offset=2&page_token=improve%2Fawesome&sort=name_asc")
+ expect(next_page).to eq("/#{project.full_path}/-/branches/all?offset=2&page_token=#{expected_page_token}&sort=name_asc")
expect(prev_page).to eq("/#{project.full_path}/-/branches/all?offset=0&page=1&sort=name_asc")
end
end
context 'when last page is requested' do
- let(:params) { { page_token: 'signed-commits', mode: 'all', sort: 'name_asc', offset: 4 } }
+ let(:page_token) { TestEnv::BRANCH_SHA.sort[-16][0] }
+ let(:params) { { page_token: page_token, mode: 'all', sort: 'name_asc', offset: 4 } }
it 'returns branches after the specified branch' do
branches, prev_page, next_page = subject
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 a41ba8216cc..38a3e00c8e7 100644
--- a/spec/services/projects/container_repository/cleanup_tags_service_spec.rb
+++ b/spec/services/projects/container_repository/cleanup_tags_service_spec.rb
@@ -267,12 +267,30 @@ RSpec.describe Projects::ContainerRepository::CleanupTagsService, :clean_gitlab_
'container_expiration_policy' => true }
end
- it 'succeeds without a user' do
+ before do
expect_delete(%w(Bb Ba C), container_expiration_policy: true)
+ end
+
+ it { is_expected.to eq(expected_service_response(deleted: %w(Bb Ba C), before_delete_size: 3)) }
+
+ context 'caching' do
+ it 'expects caching to be used' do
+ expect_caching
- expect_caching
+ subject
+ end
+
+ context 'when setting set to false' do
+ before do
+ stub_application_setting(container_registry_expiration_policies_caching: false)
+ end
- is_expected.to eq(expected_service_response(deleted: %w(Bb Ba C), before_delete_size: 3))
+ it 'does not use caching' do
+ expect_no_caching
+
+ subject
+ end
+ end
end
end
diff --git a/spec/services/projects/create_service_spec.rb b/spec/services/projects/create_service_spec.rb
index 10f694827e1..96a50b26871 100644
--- a/spec/services/projects/create_service_spec.rb
+++ b/spec/services/projects/create_service_spec.rb
@@ -23,11 +23,11 @@ RSpec.describe Projects::CreateService, '#execute' do
end
it 'creates labels on project creation' do
- created_label = project.labels.last
-
- expect(created_label.type).to eq('ProjectLabel')
- expect(created_label.project_id).to eq(project.id)
- expect(created_label.title).to eq('bug')
+ expect(project.labels).to include have_attributes(
+ type: eq('ProjectLabel'),
+ project_id: eq(project.id),
+ title: eq('bug')
+ )
end
context 'using gitlab project import' do
@@ -121,7 +121,8 @@ RSpec.describe Projects::CreateService, '#execute' do
expect(project).to be_valid
expect(project.first_owner).to eq(user)
- expect(project.team.maintainers).to include(user)
+ expect(project.team.maintainers).not_to include(user)
+ expect(project.team.owners).to contain_exactly(user)
expect(project.namespace).to eq(user.namespace)
expect(project.project_namespace).to be_in_sync_with_project(project)
end
@@ -162,7 +163,7 @@ RSpec.describe Projects::CreateService, '#execute' do
expect(project).to be_persisted
expect(project.owner).to eq(user)
expect(project.first_owner).to eq(user)
- expect(project.team.maintainers).to contain_exactly(user)
+ expect(project.team.owners).to contain_exactly(user)
expect(project.namespace).to eq(user.namespace)
expect(project.project_namespace).to be_in_sync_with_project(project)
end
@@ -205,17 +206,7 @@ RSpec.describe Projects::CreateService, '#execute' do
expect(project.project_namespace).to be_in_sync_with_project(project)
end
- context 'with before_commit callback' do
- it_behaves_like 'has sync-ed traversal_ids'
- end
-
- context 'with after_create callback' do
- before do
- stub_feature_flags(sync_traversal_ids_before_commit: false)
- end
-
- it_behaves_like 'has sync-ed traversal_ids'
- end
+ it_behaves_like 'has sync-ed traversal_ids'
end
context 'group sharing', :sidekiq_inline do
diff --git a/spec/services/projects/destroy_service_spec.rb b/spec/services/projects/destroy_service_spec.rb
index d60ec8c2958..cd923720631 100644
--- a/spec/services/projects/destroy_service_spec.rb
+++ b/spec/services/projects/destroy_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Projects::DestroyService, :aggregate_failures do
+RSpec.describe Projects::DestroyService, :aggregate_failures, :event_store_publisher do
include ProjectForksHelper
let_it_be(:user) { create(:user) }
@@ -15,7 +15,6 @@ RSpec.describe Projects::DestroyService, :aggregate_failures do
before do
stub_container_registry_config(enabled: true)
stub_container_registry_tags(repository: :any, tags: [])
- allow(Gitlab::EventStore).to receive(:publish)
end
shared_examples 'deleting the project' do
@@ -30,23 +29,8 @@ RSpec.describe Projects::DestroyService, :aggregate_failures do
it 'publishes a ProjectDeleted event with project id and namespace id' do
expected_data = { project_id: project.id, namespace_id: project.namespace_id }
- expect(Gitlab::EventStore)
- .to receive(:publish)
- .with(event_type(Projects::ProjectDeletedEvent).containing(expected_data))
- destroy_project(project, user, {})
- end
-
- context 'when feature flag publish_project_deleted_event is disabled' do
- before do
- stub_feature_flags(publish_project_deleted_event: false)
- end
-
- it 'does not publish an event' do
- expect(Gitlab::EventStore).not_to receive(:publish).with(event_type(Projects::ProjectDeletedEvent))
-
- destroy_project(project, user, {})
- end
+ expect { destroy_project(project, user, {}) }.to publish_event(Projects::ProjectDeletedEvent).with(expected_data)
end
end
@@ -59,6 +43,7 @@ RSpec.describe Projects::DestroyService, :aggregate_failures do
let!(:report_result) { create(:ci_build_report_result, build: build) }
let!(:pending_state) { create(:ci_build_pending_state, build: build) }
let!(:pipeline_artifact) { create(:ci_pipeline_artifact, pipeline: pipeline) }
+ let!(:secure_file) { create(:ci_secure_file, project: project) }
it 'deletes build and pipeline related records' do
expect { destroy_project(project, user, {}) }
@@ -72,6 +57,7 @@ RSpec.describe Projects::DestroyService, :aggregate_failures do
.and change { Ci::BuildReportResult.count }.by(-1)
.and change { Ci::BuildRunnerSession.count }.by(-1)
.and change { Ci::Pipeline.count }.by(-1)
+ .and change { Ci::SecureFile.count }.by(-1)
end
it 'avoids N+1 queries' do
@@ -449,11 +435,12 @@ RSpec.describe Projects::DestroyService, :aggregate_failures do
destroy_project(project, user)
end
- it 'calls the bulk snippet destroy service' do
+ it 'calls the bulk snippet destroy service with the hard_delete param set to true' do
expect(project.snippets.count).to eq 2
- expect(Snippets::BulkDestroyService).to receive(:new)
- .with(user, project.snippets).and_call_original
+ expect_next_instance_of(Snippets::BulkDestroyService, user, project.snippets) do |instance|
+ expect(instance).to receive(:execute).with(hard_delete: true).and_call_original
+ end
expect do
destroy_project(project, user)
@@ -461,11 +448,15 @@ RSpec.describe Projects::DestroyService, :aggregate_failures do
end
context 'when an error is raised deleting snippets' do
+ let(:error_message) { 'foo' }
+
it 'does not delete project' do
allow_next_instance_of(Snippets::BulkDestroyService) do |instance|
- allow(instance).to receive(:execute).and_return(ServiceResponse.error(message: 'foo'))
+ allow(instance).to receive(:execute).and_return(ServiceResponse.error(message: error_message))
end
+ expect(Gitlab::AppLogger).to receive(:error).with("Snippet deletion failed on #{project.full_path} with the following message: #{error_message}")
+ expect(Gitlab::AppLogger).to receive(:error).with(/Failed to remove project snippets/)
expect(destroy_project(project, user)).to be_falsey
expect(project.gitlab_shell.repository_exists?(project.repository_storage, path + '.git')).to be_truthy
end
diff --git a/spec/services/projects/import_service_spec.rb b/spec/services/projects/import_service_spec.rb
index ccfd119b55b..ab9f99f893d 100644
--- a/spec/services/projects/import_service_spec.rb
+++ b/spec/services/projects/import_service_spec.rb
@@ -199,12 +199,13 @@ RSpec.describe Projects::ImportService do
context 'with valid importer' do
before do
- stub_github_omniauth_provider
+ provider = double(:provider).as_null_object
+ stub_omniauth_setting(providers: [provider])
project.import_url = 'https://github.com/vim/vim.git'
project.import_type = 'github'
- allow(project).to receive(:import_data).and_return(double.as_null_object)
+ allow(project).to receive(:import_data).and_return(double(:import_data).as_null_object)
end
it 'succeeds if importer succeeds' do
@@ -296,22 +297,5 @@ RSpec.describe Projects::ImportService do
subject.execute
end
end
-
- def stub_github_omniauth_provider
- provider = ActiveSupport::InheritableOptions.new(
- 'name' => 'github',
- 'app_id' => 'asd123',
- 'app_secret' => 'asd123',
- 'args' => {
- 'client_options' => {
- 'site' => 'https://github.com/api/v3',
- 'authorize_url' => 'https://github.com/login/oauth/authorize',
- 'token_url' => 'https://github.com/login/oauth/access_token'
- }
- }
- )
-
- stub_omniauth_setting(providers: [provider])
- end
end
end
diff --git a/spec/services/projects/refresh_build_artifacts_size_statistics_service_spec.rb b/spec/services/projects/refresh_build_artifacts_size_statistics_service_spec.rb
new file mode 100644
index 00000000000..41de8c6bdbb
--- /dev/null
+++ b/spec/services/projects/refresh_build_artifacts_size_statistics_service_spec.rb
@@ -0,0 +1,102 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Projects::RefreshBuildArtifactsSizeStatisticsService, :clean_gitlab_redis_shared_state do
+ let(:service) { described_class.new }
+
+ describe '#execute' do
+ let_it_be(:project) { create(:project) }
+
+ let_it_be(:artifact_1) { create(:ci_job_artifact, project: project, size: 1, created_at: 14.days.ago) }
+ let_it_be(:artifact_2) { create(:ci_job_artifact, project: project, size: 2, created_at: 13.days.ago) }
+ let_it_be(:artifact_3) { create(:ci_job_artifact, project: project, size: 5, created_at: 12.days.ago) }
+
+ # This should not be included in the recalculation as it is created later than the refresh start time
+ let_it_be(:future_artifact) { create(:ci_job_artifact, project: project, size: 8, created_at: 2.days.from_now) }
+
+ let!(:refresh) do
+ create(
+ :project_build_artifacts_size_refresh,
+ :created,
+ project: project,
+ updated_at: 2.days.ago,
+ refresh_started_at: nil,
+ last_job_artifact_id: nil
+ )
+ end
+
+ let(:now) { Time.zone.now }
+
+ around do |example|
+ freeze_time { example.run }
+ end
+
+ before do
+ stub_const("#{described_class}::BATCH_SIZE", 2)
+
+ stats = create(:project_statistics, project: project, build_artifacts_size: 120)
+ stats.increment_counter(:build_artifacts_size, 30)
+ end
+
+ it 'resets the build artifacts size stats' do
+ expect { service.execute }.to change { project.statistics.reload.build_artifacts_size }.to(0)
+ end
+
+ it 'increments the counter attribute by the total size of the current batch of artifacts' do
+ expect { service.execute }.to change { project.statistics.get_counter_value(:build_artifacts_size) }.to(3)
+ end
+
+ it 'updates the last_job_artifact_id to the ID of the last artifact from the batch' do
+ expect { service.execute }.to change { refresh.reload.last_job_artifact_id.to_i }.to(artifact_2.id)
+ end
+
+ it 'requeues the refresh job' do
+ service.execute
+ expect(refresh.reload).to be_pending
+ end
+
+ context 'when an error happens after the recalculation has started' do
+ let!(:refresh) do
+ create(
+ :project_build_artifacts_size_refresh,
+ :pending,
+ project: project,
+ last_job_artifact_id: artifact_2.id
+ )
+ end
+
+ before do
+ allow(Gitlab::Redis::SharedState).to receive(:with).and_raise(StandardError, 'error')
+
+ expect { service.execute }.to raise_error(StandardError)
+ end
+
+ it 'keeps the last_job_artifact_id unchanged' do
+ expect(refresh.reload.last_job_artifact_id).to eq(artifact_2.id)
+ end
+
+ it 'keeps the state of the refresh record at running' do
+ expect(refresh.reload).to be_running
+ end
+ end
+
+ context 'when there are no more artifacts to recalculate for the next refresh job' do
+ let!(:refresh) do
+ create(
+ :project_build_artifacts_size_refresh,
+ :pending,
+ project: project,
+ updated_at: 2.days.ago,
+ refresh_started_at: now,
+ last_job_artifact_id: artifact_3.id
+ )
+ end
+
+ it 'deletes the refresh record' do
+ service.execute
+ expect(Projects::BuildArtifactsSizeRefresh.where(id: refresh.id)).not_to exist
+ end
+ end
+ end
+end
diff --git a/spec/services/projects/update_pages_service_spec.rb b/spec/services/projects/update_pages_service_spec.rb
index 5810024a1ef..6407b8d3940 100644
--- a/spec/services/projects/update_pages_service_spec.rb
+++ b/spec/services/projects/update_pages_service_spec.rb
@@ -39,7 +39,6 @@ RSpec.describe Projects::UpdatePagesService do
expect(project.pages_deployed?).to be_falsey
expect(execute).to eq(:success)
expect(project.pages_metadatum).to be_deployed
- expect(project.pages_metadatum.artifacts_archive).to eq(artifacts_archive)
expect(project.pages_deployed?).to be_truthy
end
diff --git a/spec/services/quick_actions/interpret_service_spec.rb b/spec/services/quick_actions/interpret_service_spec.rb
index afeb95a3ca3..94e0e8a9ea1 100644
--- a/spec/services/quick_actions/interpret_service_spec.rb
+++ b/spec/services/quick_actions/interpret_service_spec.rb
@@ -759,6 +759,7 @@ RSpec.describe QuickActions::InterpretService do
context 'merge command' do
let(:service) { described_class.new(project, developer, { merge_request_diff_head_sha: merge_request.diff_head_sha }) }
+ let(:merge_request) { create(:merge_request, source_project: repository_project) }
it_behaves_like 'merge immediately command' do
let(:content) { '/merge' }
@@ -789,7 +790,7 @@ RSpec.describe QuickActions::InterpretService do
context 'can not be merged when sha does not match' do
let(:service) { described_class.new(project, developer, { merge_request_diff_head_sha: 'othersha' }) }
- it_behaves_like 'failed command', 'Could not apply merge command.' do
+ it_behaves_like 'failed command', 'Branch has been updated since the merge was requested.' do
let(:content) { "/merge" }
let(:issuable) { merge_request }
end
@@ -799,10 +800,9 @@ RSpec.describe QuickActions::InterpretService do
let(:project) { repository_project }
let(:service) { described_class.new(project, developer, {}) }
- it 'precheck passes and returns merge command' do
- _, updates, _ = service.execute('/merge', merge_request)
-
- expect(updates).to eq(merge: nil)
+ it_behaves_like 'failed command', 'Merge request diff sha parameter is required for the merge quick action.' do
+ let(:content) { "/merge" }
+ let(:issuable) { merge_request }
end
end
diff --git a/spec/services/repositories/destroy_rollback_service_spec.rb b/spec/services/repositories/destroy_rollback_service_spec.rb
index 717e52f0e40..a52dff62760 100644
--- a/spec/services/repositories/destroy_rollback_service_spec.rb
+++ b/spec/services/repositories/destroy_rollback_service_spec.rb
@@ -43,16 +43,19 @@ RSpec.describe Repositories::DestroyRollbackService do
expect(repository).to receive(:disk_path).and_return('foo')
expect(repository).not_to receive(:before_delete)
- result = subject
+ expect(subject[:status]).to eq :success
+ end
- expect(result[:status]).to eq :success
+ it 'gracefully handles exception if the repository does not exist on disk' do
+ expect(repository).to receive(:before_delete).and_raise(Gitlab::Git::Repository::NoRepository)
+ expect(subject[:status]).to eq :success
end
context 'when move operation cannot be performed' do
let(:service) { described_class.new(repository) }
before do
- allow(service).to receive(:mv_repository).and_return(false)
+ expect(service).to receive(:mv_repository).and_return(false)
end
it 'returns error' do
@@ -66,6 +69,14 @@ RSpec.describe Repositories::DestroyRollbackService do
service.execute
end
+
+ context 'when repository does not exist' do
+ it 'returns success' do
+ allow(service).to receive(:repo_exists?).and_return(true, false)
+
+ expect(service.execute[:status]).to eq :success
+ end
+ end
end
def destroy_project(project, user)
diff --git a/spec/services/repositories/destroy_service_spec.rb b/spec/services/repositories/destroy_service_spec.rb
index 240f837e973..3766467d708 100644
--- a/spec/services/repositories/destroy_service_spec.rb
+++ b/spec/services/repositories/destroy_service_spec.rb
@@ -69,22 +69,23 @@ RSpec.describe Repositories::DestroyService do
expect(repository).to receive(:disk_path).and_return('foo')
expect(repository).not_to receive(:before_delete)
- result = subject
+ expect(subject[:status]).to eq :success
+ end
- expect(result[:status]).to eq :success
+ it 'gracefully handles exception if the repository does not exist on disk' do
+ expect(repository).to receive(:before_delete).and_raise(Gitlab::Git::Repository::NoRepository)
+ expect(subject[:status]).to eq :success
end
context 'when move operation cannot be performed' do
let(:service) { described_class.new(repository) }
before do
- allow(service).to receive(:mv_repository).and_return(false)
+ expect(service).to receive(:mv_repository).and_return(false)
end
it 'returns error' do
- result = service.execute
-
- expect(result[:status]).to eq :error
+ expect(service.execute[:status]).to eq :error
end
it 'logs the error' do
@@ -92,6 +93,15 @@ RSpec.describe Repositories::DestroyService do
service.execute
end
+
+ context 'when repository does not exist' do
+ it 'returns success' do
+ allow(service).to receive(:repo_exists?).and_return(true, false)
+
+ expect(Repositories::ShellDestroyService).not_to receive(:new)
+ expect(service.execute[:status]).to eq :success
+ end
+ end
end
context 'with a project wiki repository' do
diff --git a/spec/services/security/merge_reports_service_spec.rb b/spec/services/security/merge_reports_service_spec.rb
index 120ce12aa58..e61977297c5 100644
--- a/spec/services/security/merge_reports_service_spec.rb
+++ b/spec/services/security/merge_reports_service_spec.rb
@@ -153,7 +153,18 @@ RSpec.describe Security::MergeReportsService, '#execute' do
report_2.add_error('zoo', 'baz')
end
- it { is_expected.to eq([{ type: 'foo', message: 'bar' }, { type: 'zoo', message: 'baz' }]) }
+ it { is_expected.to match_array([{ type: 'foo', message: 'bar' }, { type: 'zoo', message: 'baz' }]) }
+ end
+
+ describe 'warnings on target report' do
+ subject { merged_report.warnings }
+
+ before do
+ report_1.add_warning('foo', 'bar')
+ report_2.add_warning('zoo', 'baz')
+ end
+
+ it { is_expected.to match_array([{ type: 'foo', message: 'bar' }, { type: 'zoo', message: 'baz' }]) }
end
it 'copies scanners into target report and eliminates duplicates' do
diff --git a/spec/services/service_ping/build_payload_service_spec.rb b/spec/services/service_ping/build_payload_service_spec.rb
index cd2685069c9..b90e5e66518 100644
--- a/spec/services/service_ping/build_payload_service_spec.rb
+++ b/spec/services/service_ping/build_payload_service_spec.rb
@@ -4,6 +4,10 @@ require 'spec_helper'
RSpec.describe ServicePing::BuildPayloadService do
describe '#execute', :without_license do
+ before do
+ stub_feature_flags(merge_service_ping_instrumented_metrics: false)
+ end
+
subject(:service_ping_payload) { described_class.new.execute }
include_context 'stubbed service ping metrics definitions' do
diff --git a/spec/services/spam/spam_action_service_spec.rb b/spec/services/spam/spam_action_service_spec.rb
index 8ddfa7ed3a0..bd8418d7092 100644
--- a/spec/services/spam/spam_action_service_spec.rb
+++ b/spec/services/spam/spam_action_service_spec.rb
@@ -170,26 +170,13 @@ RSpec.describe Spam::SpamActionService do
allow(fake_verdict_service).to receive(:execute).and_return(DISALLOW)
end
- context 'when allow_possible_spam feature flag is false' do
- before do
- stub_feature_flags(allow_possible_spam: false)
- end
+ it_behaves_like 'creates a spam log'
- it 'marks as spam' do
- response = subject
-
- expect(response.message).to match(expected_service_check_response_message)
- expect(issue).to be_spam
- end
- end
-
- context 'when allow_possible_spam feature flag is true' do
- it 'does not mark as spam' do
- response = subject
+ it 'marks as spam' do
+ response = subject
- expect(response.message).to match(expected_service_check_response_message)
- expect(issue).not_to be_spam
- end
+ expect(response.message).to match(expected_service_check_response_message)
+ expect(issue).to be_spam
end
end
@@ -198,26 +185,13 @@ RSpec.describe Spam::SpamActionService do
allow(fake_verdict_service).to receive(:execute).and_return(BLOCK_USER)
end
- context 'when allow_possible_spam feature flag is false' do
- before do
- stub_feature_flags(allow_possible_spam: false)
- end
-
- it 'marks as spam' do
- response = subject
+ it_behaves_like 'creates a spam log'
- expect(response.message).to match(expected_service_check_response_message)
- expect(issue).to be_spam
- end
- end
-
- context 'when allow_possible_spam feature flag is true' do
- it 'does not mark as spam' do
- response = subject
+ it 'marks as spam' do
+ response = subject
- expect(response.message).to match(expected_service_check_response_message)
- expect(issue).not_to be_spam
- end
+ expect(response.message).to match(expected_service_check_response_message)
+ expect(issue).to be_spam
end
end
@@ -226,37 +200,42 @@ RSpec.describe Spam::SpamActionService do
allow(fake_verdict_service).to receive(:execute).and_return(CONDITIONAL_ALLOW)
end
- context 'when allow_possible_spam feature flag is false' do
- before do
- stub_feature_flags(allow_possible_spam: false)
- end
+ it_behaves_like 'creates a spam log'
- it_behaves_like 'creates a spam log'
+ it 'does not mark as spam' do
+ response = subject
- it 'does not mark as spam' do
- response = subject
+ expect(response.message).to match(expected_service_check_response_message)
+ expect(issue).not_to be_spam
+ end
- expect(response.message).to match(expected_service_check_response_message)
- expect(issue).not_to be_spam
- end
+ it 'marks as needing reCAPTCHA' do
+ response = subject
- it 'marks as needing reCAPTCHA' do
- response = subject
+ expect(response.message).to match(expected_service_check_response_message)
+ expect(issue).to be_needs_recaptcha
+ end
+ end
- expect(response.message).to match(expected_service_check_response_message)
- expect(issue).to be_needs_recaptcha
- end
+ context 'when spam verdict service returns OVERRIDE_VIA_ALLOW_POSSIBLE_SPAM' do
+ before do
+ allow(fake_verdict_service).to receive(:execute).and_return(OVERRIDE_VIA_ALLOW_POSSIBLE_SPAM)
end
- context 'when allow_possible_spam feature flag is true' do
- it_behaves_like 'creates a spam log'
+ it_behaves_like 'creates a spam log'
- it 'does not mark as needing reCAPTCHA' do
- response = subject
+ it 'does not mark as spam' do
+ response = subject
+
+ expect(response.message).to match(expected_service_check_response_message)
+ expect(issue).not_to be_spam
+ end
+
+ it 'does not mark as needing CAPTCHA' do
+ response = subject
- expect(response.message).to match(expected_service_check_response_message)
- expect(issue.needs_recaptcha).to be_falsey
- end
+ expect(response.message).to match(expected_service_check_response_message)
+ expect(issue).not_to be_needs_recaptcha
end
end
diff --git a/spec/services/spam/spam_params_spec.rb b/spec/services/spam/spam_params_spec.rb
index e7e8b468adb..7e74641c0fa 100644
--- a/spec/services/spam/spam_params_spec.rb
+++ b/spec/services/spam/spam_params_spec.rb
@@ -3,18 +3,25 @@
require 'spec_helper'
RSpec.describe Spam::SpamParams do
+ shared_examples 'constructs from a request' do
+ it 'constructs from a request' do
+ expected = ::Spam::SpamParams.new(
+ captcha_response: captcha_response,
+ spam_log_id: spam_log_id,
+ ip_address: ip_address,
+ user_agent: user_agent,
+ referer: referer
+ )
+ expect(described_class.new_from_request(request: request)).to eq(expected)
+ end
+ end
+
describe '.new_from_request' do
let(:captcha_response) { 'abc123' }
let(:spam_log_id) { 42 }
let(:ip_address) { '0.0.0.0' }
let(:user_agent) { 'Lynx' }
let(:referer) { 'http://localhost' }
- let(:headers) do
- {
- 'X-GitLab-Captcha-Response' => captcha_response,
- 'X-GitLab-Spam-Log-Id' => spam_log_id
- }
- end
let(:env) do
{
@@ -24,17 +31,28 @@ RSpec.describe Spam::SpamParams do
}
end
- let(:request) {double(:request, headers: headers, env: env)}
+ let(:request) { double(:request, headers: headers, env: env) }
- it 'constructs from a request' do
- expected = ::Spam::SpamParams.new(
- captcha_response: captcha_response,
- spam_log_id: spam_log_id,
- ip_address: ip_address,
- user_agent: user_agent,
- referer: referer
- )
- expect(described_class.new_from_request(request: request)).to eq(expected)
+ context 'with a normal Rails request' do
+ let(:headers) do
+ {
+ 'X-GitLab-Captcha-Response' => captcha_response,
+ 'X-GitLab-Spam-Log-Id' => spam_log_id
+ }
+ end
+
+ it_behaves_like 'constructs from a request'
+ end
+
+ context 'with a grape request' do
+ let(:headers) do
+ {
+ 'X-Gitlab-Captcha-Response' => captcha_response,
+ 'X-Gitlab-Spam-Log-Id' => spam_log_id
+ }
+ end
+
+ it_behaves_like 'constructs from a request'
end
end
end
diff --git a/spec/services/spam/spam_verdict_service_spec.rb b/spec/services/spam/spam_verdict_service_spec.rb
index 99047f3233b..082b8f909f9 100644
--- a/spec/services/spam/spam_verdict_service_spec.rb
+++ b/spec/services/spam/spam_verdict_service_spec.rb
@@ -27,6 +27,10 @@ RSpec.describe Spam::SpamVerdictService do
extra_attributes
end
+ before do
+ stub_feature_flags(allow_possible_spam: false)
+ end
+
describe '#execute' do
subject { service.execute }
@@ -114,6 +118,32 @@ RSpec.describe Spam::SpamVerdictService do
end
end
+ context 'if allow_possible_spam flag is true' do
+ before do
+ stub_feature_flags(allow_possible_spam: true)
+ end
+
+ context 'and a service returns a verdict that should be overridden' do
+ before do
+ allow(service).to receive(:spamcheck_verdict).and_return([BLOCK_USER, attribs])
+ end
+
+ it 'overrides and renders the override verdict' do
+ expect(subject).to eq OVERRIDE_VIA_ALLOW_POSSIBLE_SPAM
+ end
+ end
+
+ context 'and a service returns a verdict that does not need to be overridden' do
+ before do
+ allow(service).to receive(:spamcheck_verdict).and_return([ALLOW, attribs])
+ end
+
+ it 'does not override and renders the original verdict' do
+ expect(subject).to eq ALLOW
+ end
+ end
+ end
+
context 'records metrics' do
let(:histogram) { instance_double(Prometheus::Client::Histogram) }
diff --git a/spec/services/system_note_service_spec.rb b/spec/services/system_note_service_spec.rb
index a719487a219..c322ec35e86 100644
--- a/spec/services/system_note_service_spec.rb
+++ b/spec/services/system_note_service_spec.rb
@@ -100,7 +100,7 @@ RSpec.describe SystemNoteService do
end
end
- describe '.relate_issue' do
+ describe '.relate_issuable' do
let(:noteable_ref) { double }
let(:noteable) { double }
@@ -110,14 +110,14 @@ RSpec.describe SystemNoteService do
it 'calls IssuableService' do
expect_next_instance_of(::SystemNotes::IssuablesService) do |service|
- expect(service).to receive(:relate_issue).with(noteable_ref)
+ expect(service).to receive(:relate_issuable).with(noteable_ref)
end
- described_class.relate_issue(noteable, noteable_ref, double)
+ described_class.relate_issuable(noteable, noteable_ref, double)
end
end
- describe '.unrelate_issue' do
+ describe '.unrelate_issuable' do
let(:noteable_ref) { double }
let(:noteable) { double }
@@ -127,10 +127,10 @@ RSpec.describe SystemNoteService do
it 'calls IssuableService' do
expect_next_instance_of(::SystemNotes::IssuablesService) do |service|
- expect(service).to receive(:unrelate_issue).with(noteable_ref)
+ expect(service).to receive(:unrelate_issuable).with(noteable_ref)
end
- described_class.unrelate_issue(noteable, noteable_ref, double)
+ described_class.unrelate_issuable(noteable, noteable_ref, double)
end
end
diff --git a/spec/services/system_notes/issuables_service_spec.rb b/spec/services/system_notes/issuables_service_spec.rb
index e1c97026418..5bc7ea82976 100644
--- a/spec/services/system_notes/issuables_service_spec.rb
+++ b/spec/services/system_notes/issuables_service_spec.rb
@@ -14,10 +14,10 @@ RSpec.describe ::SystemNotes::IssuablesService do
let(:service) { described_class.new(noteable: noteable, project: project, author: author) }
- describe '#relate_issue' do
+ describe '#relate_issuable' do
let(:noteable_ref) { create(:issue) }
- subject { service.relate_issue(noteable_ref) }
+ subject { service.relate_issuable(noteable_ref) }
it_behaves_like 'a system note' do
let(:action) { 'relate' }
@@ -30,10 +30,10 @@ RSpec.describe ::SystemNotes::IssuablesService do
end
end
- describe '#unrelate_issue' do
+ describe '#unrelate_issuable' do
let(:noteable_ref) { create(:issue) }
- subject { service.unrelate_issue(noteable_ref) }
+ subject { service.unrelate_issuable(noteable_ref) }
it_behaves_like 'a system note' do
let(:action) { 'unrelate' }
diff --git a/spec/services/todo_service_spec.rb b/spec/services/todo_service_spec.rb
index 7103cb0b66a..6e10d0281b7 100644
--- a/spec/services/todo_service_spec.rb
+++ b/spec/services/todo_service_spec.rb
@@ -628,12 +628,32 @@ RSpec.describe TodoService do
stub_feature_flags(multiple_todos: true)
end
- it 'creates a todo even if user already has a pending todo' do
+ it 'creates a MENTIONED todo even if user already has a pending MENTIONED todo' do
create(:todo, :mentioned, user: member, project: project, target: issue, author: author)
expect { service.update_issue(issue, author) }.to change(member.todos, :count)
end
+ it 'creates a DIRECTLY_ADDRESSED todo even if user already has a pending DIRECTLY_ADDRESSED todo' do
+ create(:todo, :directly_addressed, user: member, project: project, target: issue, author: author)
+
+ issue.update!(description: "#{member.to_reference}, what do you think?")
+
+ expect { service.update_issue(issue, author) }.to change(member.todos, :count)
+ end
+
+ it 'creates an ASSIGNED todo even if user already has a pending MARKED todo' do
+ create(:todo, :marked, user: john_doe, project: project, target: assigned_issue, author: author)
+
+ expect { service.reassigned_assignable(assigned_issue, author) }.to change(john_doe.todos, :count)
+ end
+
+ it 'does not create an ASSIGNED todo if user already has an ASSIGNED todo' do
+ create(:todo, :assigned, user: john_doe, project: project, target: assigned_issue, author: author)
+
+ expect { service.reassigned_assignable(assigned_issue, author) }.not_to change(john_doe.todos, :count)
+ end
+
it 'creates multiple todos if a user is assigned and mentioned in a new issue' do
assigned_issue.description = mentions
service.new_issue(assigned_issue, author)
diff --git a/spec/services/users/refresh_authorized_projects_service_spec.rb b/spec/services/users/refresh_authorized_projects_service_spec.rb
index a31902c7f16..e6ccb2b16e7 100644
--- a/spec/services/users/refresh_authorized_projects_service_spec.rb
+++ b/spec/services/users/refresh_authorized_projects_service_spec.rb
@@ -52,7 +52,7 @@ RSpec.describe Users::RefreshAuthorizedProjectsService do
it 'is called' do
ProjectAuthorization.delete_all
- expect(callback).to receive(:call).with(project.id, Gitlab::Access::MAINTAINER).once
+ expect(callback).to receive(:call).with(project.id, Gitlab::Access::OWNER).once
service.execute
end
@@ -73,7 +73,7 @@ RSpec.describe Users::RefreshAuthorizedProjectsService do
to_be_removed = [project_authorization.project_id]
to_be_added = [
- { user_id: user.id, project_id: project.id, access_level: Gitlab::Access::MAINTAINER }
+ { user_id: user.id, project_id: project.id, access_level: Gitlab::Access::OWNER }
]
expect(service).to receive(:update_authorizations)
@@ -82,31 +82,6 @@ RSpec.describe Users::RefreshAuthorizedProjectsService do
service.execute_without_lease
end
- it 'removes duplicate entries' do
- [Gitlab::Access::MAINTAINER, Gitlab::Access::REPORTER].each do |access_level|
- user.project_authorizations.create!(project: project, access_level: access_level)
- end
-
- to_be_removed = [project.id]
-
- to_be_added = [
- { user_id: user.id, project_id: project.id, access_level: Gitlab::Access::MAINTAINER }
- ]
- expect(service).to(
- receive(:update_authorizations)
- .with(to_be_removed, to_be_added)
- .and_call_original)
-
- service.execute_without_lease
-
- expect(user.project_authorizations.count).to eq(1)
- project_authorization = ProjectAuthorization.where(
- project_id: project.id,
- user_id: user.id,
- access_level: Gitlab::Access::MAINTAINER)
- expect(project_authorization).to exist
- end
-
it 'sets the access level of a project to the highest available level' do
user.project_authorizations.delete_all
@@ -116,7 +91,7 @@ RSpec.describe Users::RefreshAuthorizedProjectsService do
to_be_removed = [project_authorization.project_id]
to_be_added = [
- { user_id: user.id, project_id: project.id, access_level: Gitlab::Access::MAINTAINER }
+ { user_id: user.id, project_id: project.id, access_level: Gitlab::Access::OWNER }
]
expect(service).to receive(:update_authorizations)
diff --git a/spec/services/users/saved_replies/create_service_spec.rb b/spec/services/users/saved_replies/create_service_spec.rb
new file mode 100644
index 00000000000..e01b6248308
--- /dev/null
+++ b/spec/services/users/saved_replies/create_service_spec.rb
@@ -0,0 +1,44 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Users::SavedReplies::CreateService do
+ describe '#execute' do
+ let_it_be(:current_user) { create(:user) }
+ let_it_be(:saved_reply) { create(:saved_reply, user: current_user) }
+
+ subject { described_class.new(current_user: current_user, name: name, content: content).execute }
+
+ context 'when create fails' do
+ let(:name) { saved_reply.name }
+ let(:content) { '' }
+
+ it { is_expected.not_to be_success }
+
+ it 'does not create new Saved Reply in database' do
+ expect { subject }.not_to change(::Users::SavedReply, :count)
+ end
+
+ it 'returns error messages' do
+ expect(subject.errors).to match_array(["Content can't be blank", "Name has already been taken"])
+ end
+ end
+
+ context 'when create succeeds' do
+ let(:name) { 'new_saved_reply_name' }
+ let(:content) { 'New content for Saved Reply' }
+
+ it { is_expected.to be_success }
+
+ it 'creates new Saved Reply in database' do
+ expect { subject }.to change(::Users::SavedReply, :count).by(1)
+ end
+
+ it 'returns new saved reply', :aggregate_failures do
+ expect(subject[:saved_reply]).to eq(::Users::SavedReply.last)
+ expect(subject[:saved_reply].name).to eq(name)
+ expect(subject[:saved_reply].content).to eq(content)
+ end
+ end
+ end
+end
diff --git a/spec/services/users/saved_replies/update_service_spec.rb b/spec/services/users/saved_replies/update_service_spec.rb
new file mode 100644
index 00000000000..b67d09977c6
--- /dev/null
+++ b/spec/services/users/saved_replies/update_service_spec.rb
@@ -0,0 +1,40 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Users::SavedReplies::UpdateService do
+ describe '#execute' do
+ let_it_be(:current_user) { create(:user) }
+ let_it_be(:saved_reply) { create(:saved_reply, user: current_user) }
+ let_it_be(:other_saved_reply) { create(:saved_reply, user: current_user) }
+ let_it_be(:saved_reply_from_other_user) { create(:saved_reply) }
+
+ subject { described_class.new(current_user: current_user, saved_reply: saved_reply, name: name, content: content).execute }
+
+ context 'when update fails' do
+ let(:name) { other_saved_reply.name }
+ let(:content) { '' }
+
+ it { is_expected.not_to be_success }
+
+ it 'returns error messages' do
+ expect(subject.errors).to match_array(["Content can't be blank", "Name has already been taken"])
+ end
+ end
+
+ context 'when update succeeds' do
+ let(:name) { saved_reply_from_other_user.name }
+ let(:content) { 'New content for Saved Reply' }
+
+ it { is_expected.to be_success }
+
+ it 'updates new Saved Reply in database' do
+ expect { subject }.not_to change(::Users::SavedReply, :count)
+ end
+
+ it 'returns saved reply' do
+ expect(subject[:saved_reply]).to eq(saved_reply)
+ end
+ end
+ end
+end
diff --git a/spec/services/web_hook_service_spec.rb b/spec/services/web_hook_service_spec.rb
index 64371f97908..c938ad9ee39 100644
--- a/spec/services/web_hook_service_spec.rb
+++ b/spec/services/web_hook_service_spec.rb
@@ -14,10 +14,6 @@ RSpec.describe WebHookService, :request_store, :clean_gitlab_redis_shared_state
let(:service_instance) { described_class.new(project_hook, data, :push_hooks) }
- around do |example|
- travel_to(Time.current) { example.run }
- end
-
describe '#initialize' do
before do
stub_application_setting(setting_name => setting)
@@ -257,14 +253,6 @@ RSpec.describe WebHookService, :request_store, :clean_gitlab_redis_shared_state
end
context 'execution logging' do
- let(:hook_log) { project_hook.web_hook_logs.last }
-
- def run_service
- service_instance.execute
- ::WebHooks::LogExecutionWorker.drain
- project_hook.reload
- end
-
context 'with success' do
before do
stub_full_request(project_hook.url, method: :post).to_return(status: 200, body: 'Success')
@@ -280,42 +268,38 @@ RSpec.describe WebHookService, :request_store, :clean_gitlab_redis_shared_state
.with(hook: project_hook, log_data: Hash, response_category: :ok)
.and_return(double(execute: nil))
- run_service
+ service_instance.execute
end
end
- it 'log successful execution' do
- run_service
-
- expect(hook_log.trigger).to eq('push_hooks')
- expect(hook_log.url).to eq(project_hook.url)
- expect(hook_log.request_headers).to eq(headers)
- expect(hook_log.response_body).to eq('Success')
- expect(hook_log.response_status).to eq('200')
- expect(hook_log.execution_duration).to be > 0
- expect(hook_log.internal_error_message).to be_nil
- end
-
- it 'does not log in the service itself' do
- expect { service_instance.execute }.not_to change(::WebHookLog, :count)
- end
+ it 'queues LogExecutionWorker correctly' do
+ expect(WebHooks::LogExecutionWorker).to receive(:perform_async)
+ .with(
+ project_hook.id,
+ hash_including(
+ trigger: 'push_hooks',
+ url: project_hook.url,
+ request_headers: headers,
+ request_data: data,
+ response_body: 'Success',
+ response_headers: {},
+ response_status: 200,
+ execution_duration: be > 0,
+ internal_error_message: nil
+ ),
+ :ok,
+ nil
+ )
- it 'does not increment the failure count' do
- expect { run_service }.not_to change(project_hook, :recent_failures)
+ service_instance.execute
end
- it 'does not change the disabled_until attribute' do
- expect { run_service }.not_to change(project_hook, :disabled_until)
+ it 'queues LogExecutionWorker correctly, resulting in a log record (integration-style test)', :sidekiq_inline do
+ expect { service_instance.execute }.to change(::WebHookLog, :count).by(1)
end
- context 'when the hook had previously failed' do
- before do
- project_hook.update!(recent_failures: 2)
- end
-
- it 'resets the failure count' do
- expect { run_service }.to change(project_hook, :recent_failures).to(0)
- end
+ it 'does not log in the service itself' do
+ expect { service_instance.execute }.not_to change(::WebHookLog, :count)
end
end
@@ -324,45 +308,26 @@ RSpec.describe WebHookService, :request_store, :clean_gitlab_redis_shared_state
stub_full_request(project_hook.url, method: :post).to_return(status: 400, body: 'Bad request')
end
- it 'logs failed execution' do
- run_service
-
- expect(hook_log).to have_attributes(
- trigger: eq('push_hooks'),
- url: eq(project_hook.url),
- request_headers: eq(headers),
- response_body: eq('Bad request'),
- response_status: eq('400'),
- execution_duration: be > 0,
- internal_error_message: be_nil
- )
- end
-
- it 'increments the failure count' do
- expect { run_service }.to change(project_hook, :recent_failures).by(1)
- end
-
- it 'does not change the disabled_until attribute' do
- expect { run_service }.not_to change(project_hook, :disabled_until)
- end
-
- it 'does not allow the failure count to overflow' do
- project_hook.update!(recent_failures: 32767)
-
- expect { run_service }.not_to change(project_hook, :recent_failures)
- end
-
- context 'when the web_hooks_disable_failed FF is disabled' do
- before do
- # Hook will only be executed if the flag is disabled.
- stub_feature_flags(web_hooks_disable_failed: false)
- end
-
- it 'does not allow the failure count to overflow' do
- project_hook.update!(recent_failures: 32767)
+ it 'queues LogExecutionWorker correctly' do
+ expect(WebHooks::LogExecutionWorker).to receive(:perform_async)
+ .with(
+ project_hook.id,
+ hash_including(
+ trigger: 'push_hooks',
+ url: project_hook.url,
+ request_headers: headers,
+ request_data: data,
+ response_body: 'Bad request',
+ response_headers: {},
+ response_status: 400,
+ execution_duration: be > 0,
+ internal_error_message: nil
+ ),
+ :failed,
+ nil
+ )
- expect { run_service }.not_to change(project_hook, :recent_failures)
- end
+ service_instance.execute
end
end
@@ -371,65 +336,54 @@ RSpec.describe WebHookService, :request_store, :clean_gitlab_redis_shared_state
stub_full_request(project_hook.url, method: :post).to_raise(SocketError.new('Some HTTP Post error'))
end
- it 'log failed execution' do
- run_service
-
- expect(hook_log.trigger).to eq('push_hooks')
- expect(hook_log.url).to eq(project_hook.url)
- expect(hook_log.request_headers).to eq(headers)
- expect(hook_log.response_body).to eq('')
- expect(hook_log.response_status).to eq('internal error')
- expect(hook_log.execution_duration).to be > 0
- expect(hook_log.internal_error_message).to eq('Some HTTP Post error')
- end
-
- it 'does not increment the failure count' do
- expect { run_service }.not_to change(project_hook, :recent_failures)
- end
-
- it 'backs off' do
- expect { run_service }.to change(project_hook, :disabled_until)
- end
-
- it 'increases the backoff count' do
- expect { run_service }.to change(project_hook, :backoff_count).by(1)
- end
-
- context 'when the previous cool-off was near the maximum' do
- before do
- project_hook.update!(disabled_until: 5.minutes.ago, backoff_count: 8)
- end
-
- it 'sets the disabled_until attribute' do
- expect { run_service }.to change(project_hook, :disabled_until).to(1.day.from_now)
- end
- end
-
- context 'when we have backed-off many many times' do
- before do
- project_hook.update!(disabled_until: 5.minutes.ago, backoff_count: 365)
- end
+ it 'queues LogExecutionWorker correctly' do
+ expect(WebHooks::LogExecutionWorker).to receive(:perform_async)
+ .with(
+ project_hook.id,
+ hash_including(
+ trigger: 'push_hooks',
+ url: project_hook.url,
+ request_headers: headers,
+ request_data: data,
+ response_body: '',
+ response_headers: {},
+ response_status: 'internal error',
+ execution_duration: be > 0,
+ internal_error_message: 'Some HTTP Post error'
+ ),
+ :error,
+ nil
+ )
- it 'sets the disabled_until attribute' do
- expect { run_service }.to change(project_hook, :disabled_until).to(1.day.from_now)
- end
+ service_instance.execute
end
end
context 'with unsafe response body' do
before do
stub_full_request(project_hook.url, method: :post).to_return(status: 200, body: "\xBB")
- run_service
end
- it 'log successful execution' do
- expect(hook_log.trigger).to eq('push_hooks')
- expect(hook_log.url).to eq(project_hook.url)
- expect(hook_log.request_headers).to eq(headers)
- expect(hook_log.response_body).to eq('')
- expect(hook_log.response_status).to eq('200')
- expect(hook_log.execution_duration).to be > 0
- expect(hook_log.internal_error_message).to be_nil
+ it 'queues LogExecutionWorker with sanitized response_body' do
+ expect(WebHooks::LogExecutionWorker).to receive(:perform_async)
+ .with(
+ project_hook.id,
+ hash_including(
+ trigger: 'push_hooks',
+ url: project_hook.url,
+ request_headers: headers,
+ request_data: data,
+ response_body: '',
+ response_headers: {},
+ response_status: 200,
+ execution_duration: be > 0,
+ internal_error_message: nil
+ ),
+ :ok,
+ nil
+ )
+
+ service_instance.execute
end
end
end
diff --git a/spec/services/web_hooks/log_execution_service_spec.rb b/spec/services/web_hooks/log_execution_service_spec.rb
new file mode 100644
index 00000000000..0ba0372b99d
--- /dev/null
+++ b/spec/services/web_hooks/log_execution_service_spec.rb
@@ -0,0 +1,237 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe WebHooks::LogExecutionService do
+ include ExclusiveLeaseHelpers
+ using RSpec::Parameterized::TableSyntax
+
+ describe '#execute' do
+ around do |example|
+ travel_to(Time.current) { example.run }
+ end
+
+ let_it_be_with_reload(:project_hook) { create(:project_hook) }
+
+ let(:response_category) { :ok }
+ let(:data) do
+ {
+ trigger: 'trigger_name',
+ url: 'https://example.com',
+ request_headers: { 'Header' => 'header value' },
+ request_data: { 'Request Data' => 'request data value' },
+ response_body: 'Response body',
+ response_status: '200',
+ execution_duration: 1.2,
+ internal_error_message: 'error message'
+ }
+ end
+
+ subject(:service) { described_class.new(hook: project_hook, log_data: data, response_category: response_category) }
+
+ it 'logs the data' do
+ expect { service.execute }.to change(::WebHookLog, :count).by(1)
+
+ expect(WebHookLog.recent.first).to have_attributes(data)
+ end
+
+ context 'obtaining an exclusive lease' do
+ let(:lease_key) { "web_hooks:update_hook_failure_state:#{project_hook.id}" }
+
+ it 'updates failure state using a lease that ensures fresh state is written' do
+ service = described_class.new(hook: project_hook, log_data: data, response_category: :error)
+ WebHook.find(project_hook.id).update!(backoff_count: 1)
+
+ lease = stub_exclusive_lease(lease_key, timeout: described_class::LOCK_TTL)
+
+ expect(lease).to receive(:try_obtain)
+ expect(lease).to receive(:cancel)
+ expect { service.execute }.to change { WebHook.find(project_hook.id).backoff_count }.to(2)
+ end
+
+ context 'when a lease cannot be obtained' do
+ where(:response_category, :executable, :needs_updating) do
+ :ok | true | false
+ :ok | false | true
+ :failed | true | true
+ :failed | false | false
+ :error | true | true
+ :error | false | false
+ end
+
+ with_them do
+ subject(:service) { described_class.new(hook: project_hook, log_data: data, response_category: response_category) }
+
+ before do
+ stub_exclusive_lease_taken(lease_key, timeout: described_class::LOCK_TTL)
+ allow(project_hook).to receive(:executable?).and_return(executable)
+ end
+
+ it 'raises an error if the hook needs to be updated' do
+ if needs_updating
+ expect { service.execute }.to raise_error(Gitlab::ExclusiveLeaseHelpers::FailedToObtainLockError)
+ else
+ expect { service.execute }.not_to raise_error
+ end
+ end
+ end
+ end
+ end
+
+ context 'when response_category is :ok' do
+ it 'does not increment the failure count' do
+ expect { service.execute }.not_to change(project_hook, :recent_failures)
+ end
+
+ it 'does not change the disabled_until attribute' do
+ expect { service.execute }.not_to change(project_hook, :disabled_until)
+ end
+
+ context 'when the hook had previously failed' do
+ before do
+ project_hook.update!(recent_failures: 2)
+ end
+
+ it 'resets the failure count' do
+ expect { service.execute }.to change(project_hook, :recent_failures).to(0)
+ end
+
+ it 'sends a message to AuthLogger if the hook as not previously enabled' do
+ project_hook.update!(recent_failures: ::WebHook::FAILURE_THRESHOLD + 1)
+
+ expect(Gitlab::AuthLogger).to receive(:info).with include(
+ message: 'WebHook change active_state',
+ # identification
+ hook_id: project_hook.id,
+ hook_type: project_hook.type,
+ project_id: project_hook.project_id,
+ group_id: nil,
+ # relevant data
+ prev_state: :permanently_disabled,
+ new_state: :enabled,
+ duration: 1.2,
+ response_status: '200',
+ recent_hook_failures: 0
+ )
+
+ service.execute
+ end
+ end
+ end
+
+ context 'when response_category is :failed' do
+ let(:response_category) { :failed }
+
+ before do
+ data[:response_status] = '400'
+ end
+
+ it 'increments the failure count' do
+ expect { service.execute }.to change(project_hook, :recent_failures).by(1)
+ end
+
+ it 'does not change the disabled_until attribute' do
+ expect { service.execute }.not_to change(project_hook, :disabled_until)
+ end
+
+ it 'does not allow the failure count to overflow' do
+ project_hook.update!(recent_failures: 32767)
+
+ expect { service.execute }.not_to change(project_hook, :recent_failures)
+ end
+
+ context 'when the web_hooks_disable_failed FF is disabled' do
+ before do
+ # Hook will only be executed if the flag is disabled.
+ stub_feature_flags(web_hooks_disable_failed: false)
+ end
+
+ it 'does not allow the failure count to overflow' do
+ project_hook.update!(recent_failures: 32767)
+
+ expect { service.execute }.not_to change(project_hook, :recent_failures)
+ end
+ end
+
+ it 'sends a message to AuthLogger if the state would change' do
+ project_hook.update!(recent_failures: ::WebHook::FAILURE_THRESHOLD)
+
+ expect(Gitlab::AuthLogger).to receive(:info).with include(
+ message: 'WebHook change active_state',
+ # identification
+ hook_id: project_hook.id,
+ hook_type: project_hook.type,
+ project_id: project_hook.project_id,
+ group_id: nil,
+ # relevant data
+ prev_state: :enabled,
+ new_state: :permanently_disabled,
+ duration: (be > 0),
+ response_status: data[:response_status],
+ recent_hook_failures: ::WebHook::FAILURE_THRESHOLD + 1
+ )
+
+ service.execute
+ end
+ end
+
+ context 'when response_category is :error' do
+ let(:response_category) { :error }
+
+ before do
+ data[:response_status] = '500'
+ end
+
+ it 'does not increment the failure count' do
+ expect { service.execute }.not_to change(project_hook, :recent_failures)
+ end
+
+ it 'backs off' do
+ expect { service.execute }.to change(project_hook, :disabled_until)
+ end
+
+ it 'increases the backoff count' do
+ expect { service.execute }.to change(project_hook, :backoff_count).by(1)
+ end
+
+ it 'sends a message to AuthLogger if the state would change' do
+ expect(Gitlab::AuthLogger).to receive(:info).with include(
+ message: 'WebHook change active_state',
+ # identification
+ hook_id: project_hook.id,
+ hook_type: project_hook.type,
+ project_id: project_hook.project_id,
+ group_id: nil,
+ # relevant data
+ prev_state: :enabled,
+ new_state: :temporarily_disabled,
+ duration: (be > 0),
+ response_status: data[:response_status],
+ recent_hook_failures: 0
+ )
+
+ service.execute
+ end
+
+ context 'when the previous cool-off was near the maximum' do
+ before do
+ project_hook.update!(disabled_until: 5.minutes.ago, backoff_count: 8)
+ end
+
+ it 'sets the disabled_until attribute' do
+ expect { service.execute }.to change(project_hook, :disabled_until).to(1.day.from_now)
+ end
+ end
+
+ context 'when we have backed-off many many times' do
+ before do
+ project_hook.update!(disabled_until: 5.minutes.ago, backoff_count: 365)
+ end
+
+ it 'sets the disabled_until attribute' do
+ expect { service.execute }.to change(project_hook, :disabled_until).to(1.day.from_now)
+ end
+ end
+ end
+ end
+end
diff --git a/spec/services/work_items/create_and_link_service_spec.rb b/spec/services/work_items/create_and_link_service_spec.rb
new file mode 100644
index 00000000000..93c029bdab1
--- /dev/null
+++ b/spec/services/work_items/create_and_link_service_spec.rb
@@ -0,0 +1,96 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe WorkItems::CreateAndLinkService do
+ let_it_be(:group) { create(:group) }
+ let_it_be(:project) { create(:project, group: group) }
+ let_it_be(:user) { create(:user) }
+ let_it_be(:related_work_item) { create(:work_item, project: project) }
+
+ let(:spam_params) { double }
+ let(:link_params) { {} }
+ let(:params) do
+ {
+ title: 'Awesome work item',
+ description: 'please fix'
+ }
+ end
+
+ before_all do
+ project.add_developer(user)
+ end
+
+ describe '#execute' do
+ subject(:service_result) { described_class.new(project: project, current_user: user, params: params, spam_params: spam_params, link_params: link_params).execute }
+
+ before do
+ stub_spam_services
+ end
+
+ context 'when work item params are valid' do
+ it { is_expected.to be_success }
+
+ it 'creates a work item successfully with no links' do
+ expect do
+ service_result
+ end.to change(WorkItem, :count).by(1).and(
+ not_change(IssueLink, :count)
+ )
+ end
+
+ context 'when link params are valid' do
+ let(:link_params) { { issuable_references: [related_work_item.to_reference] } }
+
+ it 'creates a work item successfully with links' do
+ expect do
+ service_result
+ end.to change(WorkItem, :count).by(1).and(
+ change(IssueLink, :count).by(1)
+ )
+ end
+ end
+
+ context 'when link params are invalid' do
+ let(:link_params) { { issuable_references: ['invalid reference'] } }
+
+ it { is_expected.to be_error }
+
+ it 'does not create a link and does not rollback transaction' do
+ expect do
+ service_result
+ end.to not_change(IssueLink, :count).and(
+ change(WorkItem, :count).by(1)
+ )
+ end
+
+ it 'returns a link creation error message' do
+ expect(service_result.errors).to contain_exactly('No matching issue found. Make sure that you are adding a valid issue URL.')
+ end
+ end
+ end
+
+ context 'when work item params are invalid' do
+ let(:params) do
+ {
+ title: '',
+ description: 'invalid work item'
+ }
+ end
+
+ it { is_expected.to be_error }
+
+ it 'does not create a work item or links' do
+ expect do
+ service_result
+ end.to not_change(WorkItem, :count).and(
+ not_change(IssueLink, :count)
+ )
+ end
+
+ it 'returns work item errors' do
+ expect(service_result.errors).to contain_exactly("Title can't be blank")
+ end
+ end
+ end
+end
diff --git a/spec/services/work_items/create_from_task_service_spec.rb b/spec/services/work_items/create_from_task_service_spec.rb
new file mode 100644
index 00000000000..b4db925f053
--- /dev/null
+++ b/spec/services/work_items/create_from_task_service_spec.rb
@@ -0,0 +1,97 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe WorkItems::CreateFromTaskService do
+ let_it_be(:project) { create(:project) }
+ let_it_be(:developer) { create(:user) }
+ let_it_be(:list_work_item, refind: true) { create(:work_item, project: project, description: "- [ ] Item to be converted\n second line\n third line") }
+
+ let(:work_item_to_update) { list_work_item }
+ let(:spam_params) { double }
+ let(:link_params) { {} }
+ let(:current_user) { developer }
+ let(:params) do
+ {
+ title: 'Awesome work item',
+ work_item_type_id: WorkItems::Type.default_by_type(:task).id,
+ line_number_start: 1,
+ line_number_end: 3,
+ lock_version: work_item_to_update.lock_version
+ }
+ end
+
+ before_all do
+ project.add_developer(developer)
+ end
+
+ shared_examples 'CreateFromTask service with invalid params' do
+ it { is_expected.to be_error }
+
+ it 'does not create a work item or links' do
+ expect do
+ service_result
+ end.to not_change(WorkItem, :count).and(
+ not_change(IssueLink, :count)
+ )
+ end
+ end
+
+ describe '#execute' do
+ subject(:service_result) { described_class.new(work_item: work_item_to_update, current_user: current_user, work_item_params: params, spam_params: spam_params).execute }
+
+ before do
+ stub_spam_services
+ end
+
+ context 'when work item params are valid' do
+ it { is_expected.to be_success }
+
+ it 'creates a work item and links it to the original work item successfully' do
+ expect do
+ service_result
+ end.to change(WorkItem, :count).by(1).and(
+ change(IssueLink, :count)
+ )
+ end
+
+ it 'replaces the original issue markdown description with new work item reference' do
+ service_result
+
+ created_work_item = WorkItem.last
+
+ expect(list_work_item.description).to eq("- [ ] #{created_work_item.to_reference}+")
+ end
+ end
+
+ context 'when last operation fails' do
+ before do
+ params.merge!(line_number_start: 0)
+ end
+
+ it 'rollbacks all operations' do
+ expect do
+ service_result
+ end.to not_change(WorkItem, :count).and(
+ not_change(IssueLink, :count)
+ )
+ end
+
+ it { is_expected.to be_error }
+
+ it 'returns an error message' do
+ expect(service_result.errors).to contain_exactly('line_number_start must be greater than 0')
+ end
+ end
+
+ context 'when work item params are invalid' do
+ let(:params) { { title: '' } }
+
+ it_behaves_like 'CreateFromTask service with invalid params'
+
+ it 'returns work item errors' do
+ expect(service_result.errors).to contain_exactly("Title can't be blank")
+ end
+ end
+ end
+end
diff --git a/spec/services/work_items/task_list_reference_replacement_service_spec.rb b/spec/services/work_items/task_list_reference_replacement_service_spec.rb
new file mode 100644
index 00000000000..e7914eb4a92
--- /dev/null
+++ b/spec/services/work_items/task_list_reference_replacement_service_spec.rb
@@ -0,0 +1,106 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe WorkItems::TaskListReferenceReplacementService do
+ let_it_be(:project) { create(:project, :repository) }
+ let_it_be(:single_line_work_item, refind: true) { create(:work_item, project: project, description: '- [ ] single line', lock_version: 3) }
+ let_it_be(:multiple_line_work_item, refind: true) { create(:work_item, project: project, description: "Any text\n\n* [ ] Item to be converted\n second line\n third line", lock_version: 3) }
+
+ let(:line_number_start) { 3 }
+ let(:line_number_end) { 5 }
+ let(:title) { 'work item title' }
+ let(:reference) { 'any reference' }
+ let(:work_item) { multiple_line_work_item }
+ let(:lock_version) { 3 }
+ let(:expected_additional_text) { '' }
+
+ shared_examples 'successful work item task reference replacement service' do
+ it { is_expected.to be_success }
+
+ it 'replaces the original issue markdown description with new work item reference' do
+ result
+
+ expect(work_item.description).to eq("#{expected_additional_text}#{task_prefix} #{reference}+")
+ end
+ end
+
+ shared_examples 'failing work item task reference replacement service' do |error_message|
+ it { is_expected.to be_error }
+
+ it 'returns an error message' do
+ expect(result.errors).to contain_exactly(error_message)
+ end
+ end
+
+ describe '#execute' do
+ subject(:result) do
+ described_class.new(
+ work_item: work_item,
+ work_item_reference: reference,
+ line_number_start: line_number_start,
+ line_number_end: line_number_end,
+ title: title,
+ lock_version: lock_version
+ ).execute
+ end
+
+ context 'when task mardown spans a single line' do
+ let(:line_number_start) { 1 }
+ let(:line_number_end) { 1 }
+ let(:work_item) { single_line_work_item }
+ let(:task_prefix) { '- [ ]' }
+
+ it_behaves_like 'successful work item task reference replacement service'
+ end
+
+ context 'when task mardown spans multiple lines' do
+ let(:task_prefix) { '* [ ]' }
+ let(:expected_additional_text) { "Any text\n\n" }
+
+ it_behaves_like 'successful work item task reference replacement service'
+ end
+
+ context 'when description does not contain a task' do
+ let_it_be(:no_matching_work_item) { create(:work_item, project: project, description: 'no matching task') }
+
+ let(:work_item) { no_matching_work_item }
+
+ it_behaves_like 'failing work item task reference replacement service', 'Unable to detect a task on line 3'
+ end
+
+ context 'when description is empty' do
+ let_it_be(:empty_work_item) { create(:work_item, project: project, description: '') }
+
+ let(:work_item) { empty_work_item }
+
+ it_behaves_like 'failing work item task reference replacement service', "Work item description can't be blank"
+ end
+
+ context 'when line_number_start is lower than 1' do
+ let(:line_number_start) { 0 }
+
+ it_behaves_like 'failing work item task reference replacement service', 'line_number_start must be greater than 0'
+ end
+
+ context 'when line_number_end is lower than line_number_start' do
+ let(:line_number_end) { line_number_start - 1 }
+
+ it_behaves_like 'failing work item task reference replacement service', 'line_number_end must be greater or equal to line_number_start'
+ end
+
+ context 'when lock_version is older than current' do
+ let(:lock_version) { 2 }
+
+ it_behaves_like 'failing work item task reference replacement service', 'Stale work item. Check lock version'
+ end
+
+ context 'when work item is stale before updating' do
+ it_behaves_like 'failing work item task reference replacement service', 'Stale work item. Check lock version' do
+ before do
+ ::WorkItem.where(id: work_item.id).update_all(lock_version: lock_version + 1)
+ end
+ end
+ end
+ end
+end
diff --git a/spec/services/work_items/update_service_spec.rb b/spec/services/work_items/update_service_spec.rb
index f71f1060e40..b2d3f428899 100644
--- a/spec/services/work_items/update_service_spec.rb
+++ b/spec/services/work_items/update_service_spec.rb
@@ -23,6 +23,9 @@ RSpec.describe WorkItems::UpdateService do
it 'triggers issuable_title_updated graphql subscription' do
expect(GraphqlTriggers).to receive(:issuable_title_updated).with(work_item).and_call_original
+ expect(Gitlab::UsageDataCounters::WorkItemActivityUniqueCounter).to receive(:track_work_item_title_changed_action).with(author: current_user)
+ # During the work item transition we also want to track work items as issues
+ expect(Gitlab::UsageDataCounters::IssueActivityUniqueCounter).to receive(:track_issue_title_changed_action)
update_work_item
end
@@ -33,6 +36,7 @@ RSpec.describe WorkItems::UpdateService do
it 'does not trigger issuable_title_updated graphql subscription' do
expect(GraphqlTriggers).not_to receive(:issuable_title_updated)
+ expect(Gitlab::UsageDataCounters::WorkItemActivityUniqueCounter).not_to receive(:track_work_item_title_changed_action)
update_work_item
end
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index 37e9ef1d994..a72c8d2c4e8 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -199,6 +199,7 @@ RSpec.configure do |config|
config.include SidekiqMiddleware
config.include StubActionCableConnection, type: :channel
config.include StubSpamServices
+ config.include RSpec::Benchmark::Matchers, type: :benchmark
include StubFeatureFlags
@@ -252,6 +253,20 @@ RSpec.configure do |config|
::Ci::ApplicationRecord.set_open_transactions_baseline
end
+ config.around do |example|
+ if example.metadata.fetch(:stub_feature_flags, true)
+ # It doesn't make sense for this to default to enabled as we only plan to
+ # use this temporarily to override an environment variable but eventually
+ # we'll just use the environment variable value when we've completed the
+ # gradual rollout. This stub must happen in around block as there are other
+ # around blocks in tests that will run before this and get the wrong
+ # database connection.
+ stub_feature_flags(force_no_sharing_primary_model: false)
+ end
+
+ example.run
+ end
+
config.append_after do
ApplicationRecord.reset_open_transactions_baseline
::Ci::ApplicationRecord.reset_open_transactions_baseline
@@ -304,8 +319,6 @@ RSpec.configure do |config|
# As we're ready to change `master` usages to `main`, let's enable it
stub_feature_flags(main_branch_over_master: false)
- stub_feature_flags(issue_boards_filtered_search: false)
-
# Disable issue respositioning to avoid heavy load on database when importing big projects.
# This is only turned on when app is handling heavy project imports.
# Can be removed when we find a better way to deal with the problem.
@@ -445,11 +458,6 @@ RSpec.configure do |config|
end
end
- # Allows stdout to be redirected to reduce noise
- config.before(:each, :silence_stdout) do
- $stdout = StringIO.new
- end
-
# Makes diffs show entire non-truncated values.
config.before(:each, unlimited_max_formatted_output_length: true) do |_example|
config.expect_with :rspec do |c|
@@ -462,10 +470,6 @@ RSpec.configure do |config|
allow_any_instance_of(VersionCheck).to receive(:response).and_return({ "severity" => "success" })
end
- config.after(:each, :silence_stdout) do
- $stdout = STDOUT
- end
-
config.disable_monkey_patching!
end
diff --git a/spec/support/enable_multiple_database_metrics_by_default.rb b/spec/support/enable_multiple_database_metrics_by_default.rb
deleted file mode 100644
index 6eeb4acd3d6..00000000000
--- a/spec/support/enable_multiple_database_metrics_by_default.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-# frozen_string_literal: true
-
-RSpec.configure do |config|
- config.before do
- # Enable this by default in all tests so it behaves like a FF
- stub_env('GITLAB_MULTIPLE_DATABASE_METRICS', '1')
- end
-end
diff --git a/spec/support/event_store.rb b/spec/support/event_store.rb
new file mode 100644
index 00000000000..057a5550746
--- /dev/null
+++ b/spec/support/event_store.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+RSpec.configure do |config|
+ config.before(:each, :event_store_publisher) do
+ allow(Gitlab::EventStore).to receive(:publish)
+ end
+end
diff --git a/spec/support/helpers/ci/template_helpers.rb b/spec/support/helpers/ci/template_helpers.rb
index 7bab58a574e..598a5a0becc 100644
--- a/spec/support/helpers/ci/template_helpers.rb
+++ b/spec/support/helpers/ci/template_helpers.rb
@@ -3,7 +3,7 @@
module Ci
module TemplateHelpers
def secure_analyzers_prefix
- 'registry.gitlab.com/gitlab-org/security-products/analyzers'
+ 'registry.gitlab.com/security-products'
end
end
end
diff --git a/spec/support/helpers/content_security_policy_helpers.rb b/spec/support/helpers/content_security_policy_helpers.rb
new file mode 100644
index 00000000000..c9f15e65c74
--- /dev/null
+++ b/spec/support/helpers/content_security_policy_helpers.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+module ContentSecurityPolicyHelpers
+ # Expecting 2 calls to current_content_security_policy by default, once for
+ # the call that's being tested and once for the call in ApplicationController
+ def setup_csp_for_controller(controller_class, times = 2)
+ expect_next_instance_of(controller_class) do |controller|
+ expect(controller).to receive(:current_content_security_policy)
+ .and_return(ActionDispatch::ContentSecurityPolicy.new).exactly(times).times
+ end
+ end
+
+ # Expecting 2 calls to current_content_security_policy by default, once for
+ # the call that's being tested and once for the call in ApplicationController
+ def setup_existing_csp_for_controller(controller_class, csp, times = 2)
+ expect_next_instance_of(controller_class) do |controller|
+ expect(controller).to receive(:current_content_security_policy).and_return(csp).exactly(times).times
+ end
+ end
+end
diff --git a/spec/support/helpers/database_connection_helpers.rb b/spec/support/helpers/database_connection_helpers.rb
deleted file mode 100644
index 10ea7b5de91..00000000000
--- a/spec/support/helpers/database_connection_helpers.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-# frozen_string_literal: true
-
-module DatabaseConnectionHelpers
- def run_with_new_database_connection
- pool = ActiveRecord::Base.connection_pool
- conn = pool.checkout
- yield conn
- ensure
- pool.checkin(conn)
- end
-end
diff --git a/spec/support/helpers/graphql_helpers.rb b/spec/support/helpers/graphql_helpers.rb
index 8b7d1c753d5..ff8908e531a 100644
--- a/spec/support/helpers/graphql_helpers.rb
+++ b/spec/support/helpers/graphql_helpers.rb
@@ -552,6 +552,12 @@ module GraphqlHelpers
expect(flattened_errors).to be_empty
end
+ # Helps migrate to the new GraphQL interpreter,
+ # https://gitlab.com/gitlab-org/gitlab/-/issues/210556
+ def expect_graphql_error_to_be_created(error_class, match_message = nil)
+ expect { yield }.to raise_error(error_class, match_message)
+ end
+
def flattened_errors
Array.wrap(graphql_errors).flatten.compact
end
diff --git a/spec/support/helpers/migrations_helpers.rb b/spec/support/helpers/migrations_helpers.rb
index 0c5bf09f6b7..afa7ee84bda 100644
--- a/spec/support/helpers/migrations_helpers.rb
+++ b/spec/support/helpers/migrations_helpers.rb
@@ -13,6 +13,8 @@ module MigrationsHelpers
def self.name
table_name.singularize.camelcase
end
+
+ yield self if block_given?
end
end
@@ -104,9 +106,9 @@ module MigrationsHelpers
stub_env('IN_MEMORY_APPLICATION_SETTINGS', 'false')
end
- def previous_migration
- migrations.each_cons(2) do |previous, migration|
- break previous if migration.name == described_class.name
+ def previous_migration(steps_back = 2)
+ migrations.each_cons(steps_back) do |cons|
+ break cons.first if cons.last.name == described_class.name
end
end
diff --git a/spec/support/helpers/navbar_structure_helper.rb b/spec/support/helpers/navbar_structure_helper.rb
index 6fa69cbd6ad..fb06ebfdae2 100644
--- a/spec/support/helpers/navbar_structure_helper.rb
+++ b/spec/support/helpers/navbar_structure_helper.rb
@@ -77,6 +77,14 @@ module NavbarStructureHelper
)
end
+ def insert_harbor_registry_nav(within)
+ insert_after_sub_nav_item(
+ within,
+ within: _('Packages & Registries'),
+ new_sub_nav_item_name: _('Harbor Registry')
+ )
+ end
+
def insert_infrastructure_google_cloud_nav
insert_after_sub_nav_item(
_('Terraform'),
diff --git a/spec/support/helpers/next_found_instance_of.rb b/spec/support/helpers/next_found_instance_of.rb
index c8cdbaf2c5d..c7079e64ffd 100644
--- a/spec/support/helpers/next_found_instance_of.rb
+++ b/spec/support/helpers/next_found_instance_of.rb
@@ -2,19 +2,36 @@
module NextFoundInstanceOf
ERROR_MESSAGE = 'NextFoundInstanceOf mock helpers can only be used with ActiveRecord targets'
+ HELPER_METHOD_PATTERN = /(?:allow|expect)_next_found_(?<number>\d+)_instances_of/.freeze
- def expect_next_found_instance_of(klass)
+ def method_missing(method_name, ...)
+ return super unless match_data = method_name.match(HELPER_METHOD_PATTERN)
+
+ helper_method = method_name.to_s.sub("_#{match_data[:number]}", '')
+
+ public_send(helper_method, *args, match_data[:number].to_i, &block)
+ end
+
+ def expect_next_found_instance_of(klass, &block)
+ expect_next_found_instances_of(klass, nil, &block)
+ end
+
+ def expect_next_found_instances_of(klass, number)
check_if_active_record!(klass)
- stub_allocate(expect(klass), klass) do |expectation|
+ stub_allocate(expect(klass), klass, number) do |expectation|
yield(expectation)
end
end
- def allow_next_found_instance_of(klass)
+ def allow_next_found_instance_of(klass, &block)
+ allow_next_found_instances_of(klass, nil, &block)
+ end
+
+ def allow_next_found_instances_of(klass, number)
check_if_active_record!(klass)
- stub_allocate(allow(klass), klass) do |allowance|
+ stub_allocate(allow(klass), klass, number) do |allowance|
yield(allowance)
end
end
@@ -25,8 +42,11 @@ module NextFoundInstanceOf
raise ArgumentError, ERROR_MESSAGE unless klass < ActiveRecord::Base
end
- def stub_allocate(target, klass)
- target.to receive(:allocate).and_wrap_original do |method|
+ def stub_allocate(target, klass, number)
+ stub = receive(:allocate)
+ stub.exactly(number).times if number
+
+ target.to stub.and_wrap_original do |method|
method.call.tap do |allocation|
# ActiveRecord::Core.allocate returns a frozen object:
# https://github.com/rails/rails/blob/291a3d2ef29a3842d1156ada7526f4ee60dd2b59/activerecord/lib/active_record/core.rb#L620
diff --git a/spec/support/helpers/search_helpers.rb b/spec/support/helpers/search_helpers.rb
index 3d4ff4801a7..f5a1a97a1d0 100644
--- a/spec/support/helpers/search_helpers.rb
+++ b/spec/support/helpers/search_helpers.rb
@@ -11,8 +11,12 @@ module SearchHelpers
end
def submit_search(query)
- page.within('.search-form, .search-page-form') do
+ # Once the `new_header_search` feature flag has been removed
+ # We can remove the `.search-form` selector
+ # https://gitlab.com/gitlab-org/gitlab/-/issues/339348
+ page.within('.header-search, .search-form, .search-page-form') do
field = find_field('search')
+ field.click
field.fill_in(with: query)
if javascript_test?
diff --git a/spec/support/helpers/sorting_helper.rb b/spec/support/helpers/sorting_helper.rb
index f19f8c12928..6ff6dbb7800 100644
--- a/spec/support/helpers/sorting_helper.rb
+++ b/spec/support/helpers/sorting_helper.rb
@@ -26,6 +26,7 @@ module SortingHelper
include Comparable
attr_reader :value
+
delegate :==, :eql?, :hash, to: :value
def initialize(value)
diff --git a/spec/support/helpers/stub_configuration.rb b/spec/support/helpers/stub_configuration.rb
index 8c60dc30cdb..20f46396424 100644
--- a/spec/support/helpers/stub_configuration.rb
+++ b/spec/support/helpers/stub_configuration.rb
@@ -90,10 +90,18 @@ module StubConfiguration
allow(Gitlab.config.repositories).to receive(:storages).and_return(Settingslogic.new(messages))
end
- def stub_sentry_settings
- allow(Gitlab.config.sentry).to receive(:enabled).and_return(true)
- allow(Gitlab.config.sentry).to receive(:dsn).and_return('dummy://b44a0828b72421a6d8e99efd68d44fa8@example.com/42')
- allow(Gitlab.config.sentry).to receive(:clientside_dsn).and_return('dummy://b44a0828b72421a6d8e99efd68d44fa8@example.com/43')
+ def stub_sentry_settings(enabled: true)
+ allow(Gitlab.config.sentry).to receive(:enabled) { enabled }
+ allow(Gitlab::CurrentSettings).to receive(:sentry_enabled?) { enabled }
+
+ dsn = 'dummy://b44a0828b72421a6d8e99efd68d44fa8@example.com/42'
+ allow(Gitlab.config.sentry).to receive(:dsn) { dsn }
+ allow(Gitlab::CurrentSettings).to receive(:sentry_dsn) { dsn }
+
+ clientside_dsn = 'dummy://b44a0828b72421a6d8e99efd68d44fa8@example.com/43'
+ allow(Gitlab.config.sentry).to receive(:clientside_dsn) { clientside_dsn }
+ allow(Gitlab::CurrentSettings)
+ .to receive(:sentry_clientside_dsn) { clientside_dsn }
end
def stub_kerberos_setting(messages)
diff --git a/spec/support/helpers/terms_helper.rb b/spec/support/helpers/terms_helper.rb
index a61bae18f9a..2547ea62e37 100644
--- a/spec/support/helpers/terms_helper.rb
+++ b/spec/support/helpers/terms_helper.rb
@@ -15,7 +15,9 @@ module TermsHelper
end
def expect_to_be_on_terms_page
- expect(current_path).to eq terms_path
+ expect(page).to have_current_path terms_path, ignore_query: true
expect(page).to have_content('Please accept the Terms of Service before continuing.')
end
end
+
+TermsHelper.prepend_mod
diff --git a/spec/support/helpers/test_env.rb b/spec/support/helpers/test_env.rb
index 18c25f4b770..587d4e22828 100644
--- a/spec/support/helpers/test_env.rb
+++ b/spec/support/helpers/test_env.rb
@@ -54,7 +54,7 @@ module TestEnv
'wip' => 'b9238ee',
'csv' => '3dd0896',
'v1.1.0' => 'b83d6e3',
- 'add-ipython-files' => '532c837',
+ 'add-ipython-files' => 'a867a602',
'add-pdf-file' => 'e774ebd',
'squash-large-files' => '54cec52',
'add-pdf-text-binary' => '79faa7b',
@@ -80,7 +80,8 @@ module TestEnv
'invalid-utf8-diff-paths' => '99e4853',
'compare-with-merge-head-source' => 'f20a03d',
'compare-with-merge-head-target' => '2f1e176',
- 'trailers' => 'f0a5ed6'
+ 'trailers' => 'f0a5ed6',
+ 'add_commit_with_5mb_subject' => '8cf8e80'
}.freeze
# gitlab-test-fork is a fork of gitlab-fork, but we don't necessarily
diff --git a/spec/support/helpers/usage_data_helpers.rb b/spec/support/helpers/usage_data_helpers.rb
index 776ea37ffdc..b9f90b11a69 100644
--- a/spec/support/helpers/usage_data_helpers.rb
+++ b/spec/support/helpers/usage_data_helpers.rb
@@ -129,6 +129,7 @@ module UsageDataHelpers
uploads
web_hooks
user_preferences_user_gitpod_enabled
+ service_usage_data_download_payload_click
).push(*SMAU_KEYS)
USAGE_DATA_KEYS = %i(
diff --git a/spec/support/matchers/be_color.rb b/spec/support/matchers/be_color.rb
new file mode 100644
index 00000000000..8fe29d003f9
--- /dev/null
+++ b/spec/support/matchers/be_color.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+# Assert that this value is a valid color equal to the argument
+#
+# ```
+# expect(value).to be_color('#fff')
+# ```
+RSpec::Matchers.define :be_color do |expected|
+ match do |actual|
+ next false unless actual.present?
+
+ if expected
+ ::Gitlab::Color.of(actual) == ::Gitlab::Color.of(expected)
+ else
+ ::Gitlab::Color.of(actual).valid?
+ end
+ end
+end
+
+RSpec::Matchers.alias_matcher :a_valid_color, :be_color
diff --git a/spec/support/matchers/event_store.rb b/spec/support/matchers/event_store.rb
index 96a71ae3c22..eb5b37f39e5 100644
--- a/spec/support/matchers/event_store.rb
+++ b/spec/support/matchers/event_store.rb
@@ -1,12 +1,39 @@
# frozen_string_literal: true
-RSpec::Matchers.define :event_type do |event_class|
- match do |actual|
- actual.instance_of?(event_class) &&
- actual.data == @expected_data
+RSpec::Matchers.define :publish_event do |expected_event_class|
+ supports_block_expectations
+
+ match do |proc|
+ raise ArgumentError, 'This matcher only supports block expectation' unless proc.respond_to?(:call)
+
+ @events ||= []
+
+ allow(Gitlab::EventStore).to receive(:publish) do |published_event|
+ @events << published_event
+ end
+
+ proc.call
+
+ @events.any? do |event|
+ event.instance_of?(expected_event_class) && event.data == @expected_data
+ end
end
- chain :containing do |expected_data|
+ chain :with do |expected_data|
@expected_data = expected_data
end
+
+ failure_message do
+ "expected #{expected_event_class} with #{@expected_data} to be published, but got #{@events}"
+ end
+
+ match_when_negated do |proc|
+ raise ArgumentError, 'This matcher only supports block expectation' unless proc.respond_to?(:call)
+
+ allow(Gitlab::EventStore).to receive(:publish)
+
+ proc.call
+
+ expect(Gitlab::EventStore).not_to have_received(:publish).with(instance_of(expected_event_class))
+ end
end
diff --git a/spec/support/matchers/pushed_frontend_feature_flags_matcher.rb b/spec/support/matchers/pushed_frontend_feature_flags_matcher.rb
index b49d4da8cda..ecd174edec9 100644
--- a/spec/support/matchers/pushed_frontend_feature_flags_matcher.rb
+++ b/spec/support/matchers/pushed_frontend_feature_flags_matcher.rb
@@ -5,15 +5,19 @@ RSpec::Matchers.define :have_pushed_frontend_feature_flags do |expected|
"\"#{key}\":#{value}"
end
+ def html(actual)
+ actual.try(:html) || actual
+ end
+
match do |actual|
expected.all? do |feature_flag_name, enabled|
- page.html.include?(to_js(feature_flag_name, enabled))
+ html(actual).include?(to_js(feature_flag_name, enabled))
end
end
failure_message do |actual|
missing = expected.select do |feature_flag_name, enabled|
- !page.html.include?(to_js(feature_flag_name, enabled))
+ !html(actual).include?(to_js(feature_flag_name, enabled))
end
formatted_missing_flags = missing.map { |feature_flag_name, enabled| to_js(feature_flag_name, enabled) }.join("\n")
diff --git a/spec/support/sentry.rb b/spec/support/sentry.rb
new file mode 100644
index 00000000000..c439b6c0fd9
--- /dev/null
+++ b/spec/support/sentry.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+RSpec.configure do |config|
+ config.around(:example, :sentry) do |example|
+ dsn = Sentry.get_current_client.configuration.dsn
+ Sentry.get_current_client.configuration.dsn = 'dummy://b44a0828b72421a6d8e99efd68d44fa8@example.com/42'
+ begin
+ example.run
+ ensure
+ Sentry.get_current_client.configuration.dsn = dsn.to_s.presence
+ end
+ end
+end
diff --git a/spec/support/shared_contexts/cache_allowed_users_in_namespace_shared_context.rb b/spec/support/shared_contexts/cache_allowed_users_in_namespace_shared_context.rb
index bfb719fd840..f5aa4178ae6 100644
--- a/spec/support/shared_contexts/cache_allowed_users_in_namespace_shared_context.rb
+++ b/spec/support/shared_contexts/cache_allowed_users_in_namespace_shared_context.rb
@@ -10,7 +10,7 @@ RSpec.shared_examples 'allowed user IDs are cached' do
end
it 'caches the allowed user IDs in L1 cache for 1 minute', :use_clean_rails_memory_store_caching do
- Timecop.travel 2.minutes do
+ travel_to 2.minutes.from_now do
expect do
expect(described_class.l1_cache_backend).to receive(:fetch).and_call_original
expect(described_class.l2_cache_backend).to receive(:fetch).and_call_original
@@ -20,7 +20,7 @@ RSpec.shared_examples 'allowed user IDs are cached' do
end
it 'caches the allowed user IDs in L2 cache for 5 minutes', :use_clean_rails_memory_store_caching do
- Timecop.travel 6.minutes do
+ travel_to 6.minutes.from_now do
expect do
expect(described_class.l1_cache_backend).to receive(:fetch).and_call_original
expect(described_class.l2_cache_backend).to receive(:fetch).and_call_original
diff --git a/spec/support/shared_contexts/container_repositories_shared_context.rb b/spec/support/shared_contexts/container_repositories_shared_context.rb
index 7f61631dce0..9a9f80a3cbd 100644
--- a/spec/support/shared_contexts/container_repositories_shared_context.rb
+++ b/spec/support/shared_contexts/container_repositories_shared_context.rb
@@ -1,13 +1,16 @@
# frozen_string_literal: true
RSpec.shared_context 'importable repositories' do
- let_it_be(:project) { create(:project) }
+ let_it_be(:root_group) { create(:group) }
+ let_it_be(:group) { create(:group, parent_id: root_group.id) }
+ let_it_be(:project) { create(:project, namespace: group) }
let_it_be(:valid_container_repository) { create(:container_repository, project: project, created_at: 2.days.ago) }
let_it_be(:valid_container_repository2) { create(:container_repository, project: project, created_at: 1.year.ago) }
let_it_be(:importing_container_repository) { create(:container_repository, :importing, project: project, created_at: 2.days.ago) }
let_it_be(:new_container_repository) { create(:container_repository, project: project) }
- let_it_be(:denied_group) { create(:group) }
+ let_it_be(:denied_root_group) { create(:group) }
+ let_it_be(:denied_group) { create(:group, parent_id: denied_root_group.id) }
let_it_be(:denied_project) { create(:project, group: denied_group) }
let_it_be(:denied_container_repository) { create(:container_repository, project: denied_project, created_at: 2.days.ago) }
@@ -21,7 +24,7 @@ RSpec.shared_context 'importable repositories' do
Feature::FlipperGate.create!(
feature_key: 'container_registry_phase_2_deny_list',
key: 'actors',
- value: "Group:#{denied_group.id}"
+ value: "Group:#{denied_root_group.id}"
)
end
end
diff --git a/spec/support/shared_contexts/lib/container_registry/client_stubs_shared_context.rb b/spec/support/shared_contexts/lib/container_registry/client_stubs_shared_context.rb
new file mode 100644
index 00000000000..d857e683aa2
--- /dev/null
+++ b/spec/support/shared_contexts/lib/container_registry/client_stubs_shared_context.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+RSpec.shared_context 'container registry client stubs' do
+ def stub_container_registry_gitlab_api_support(supported: true)
+ allow_next_instance_of(ContainerRegistry::GitlabApiClient) do |client|
+ allow(client).to receive(:supports_gitlab_api?).and_return(supported)
+ yield client if block_given?
+ end
+ end
+
+ def stub_container_registry_gitlab_api_repository_details(client, path:, size_bytes:)
+ allow(client).to receive(:repository_details).with(path, with_size: true).and_return('size_bytes' => size_bytes)
+ end
+
+ def stub_container_registry_gitlab_api_network_error(client_method: :supports_gitlab_api?)
+ allow_next_instance_of(ContainerRegistry::GitlabApiClient) do |client|
+ allow(client).to receive(client_method).and_raise(::Faraday::Error, nil, nil)
+ end
+ end
+end
diff --git a/spec/support/shared_contexts/navbar_structure_context.rb b/spec/support/shared_contexts/navbar_structure_context.rb
index 576a8aa44fa..b4a71f52092 100644
--- a/spec/support/shared_contexts/navbar_structure_context.rb
+++ b/spec/support/shared_contexts/navbar_structure_context.rb
@@ -22,7 +22,6 @@ RSpec.shared_context 'project navbar structure' do
nav_sub_items: [
_('Activity'),
_('Labels'),
- _('Planning hierarchy'),
_('Members')
]
},
@@ -204,7 +203,7 @@ RSpec.shared_context 'group navbar structure' do
nav_sub_items: []
},
{
- nav_item: _('Group information'),
+ nav_item: group.root? ? _('Group information') : _('Subgroup information'),
nav_sub_items: [
_('Activity'),
_('Labels'),
diff --git a/spec/support/shared_contexts/spam_constants.rb b/spec/support/shared_contexts/spam_constants.rb
index e88a7c1b0df..03c5caa13b2 100644
--- a/spec/support/shared_contexts/spam_constants.rb
+++ b/spec/support/shared_contexts/spam_constants.rb
@@ -2,10 +2,11 @@
RSpec.shared_context 'includes Spam constants' do
before do
- stub_const('CONDITIONAL_ALLOW', Spam::SpamConstants::CONDITIONAL_ALLOW)
+ stub_const('BLOCK_USER', Spam::SpamConstants::BLOCK_USER)
stub_const('DISALLOW', Spam::SpamConstants::DISALLOW)
+ stub_const('CONDITIONAL_ALLOW', Spam::SpamConstants::CONDITIONAL_ALLOW)
+ stub_const('OVERRIDE_VIA_ALLOW_POSSIBLE_SPAM', Spam::SpamConstants::OVERRIDE_VIA_ALLOW_POSSIBLE_SPAM)
stub_const('ALLOW', Spam::SpamConstants::ALLOW)
- stub_const('BLOCK_USER', Spam::SpamConstants::BLOCK_USER)
stub_const('NOOP', Spam::SpamConstants::NOOP)
end
end
diff --git a/spec/support/shared_examples/attention_request_cache_invalidation_examples.rb b/spec/support/shared_examples/attention_request_cache_invalidation_examples.rb
new file mode 100644
index 00000000000..7fe696abc69
--- /dev/null
+++ b/spec/support/shared_examples/attention_request_cache_invalidation_examples.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+RSpec.shared_examples 'invalidates attention request cache' do
+ it 'invalidates the merge requests requiring attention count' do
+ cache_mock = double
+
+ users.each do |user|
+ expect(cache_mock).to receive(:delete).with(['users', user.id, 'attention_requested_open_merge_requests_count'])
+ end
+
+ allow(Rails).to receive(:cache).and_return(cache_mock)
+
+ service.execute
+ end
+end
diff --git a/spec/support/shared_examples/blocks_unsafe_serialization_shared_examples.rb b/spec/support/shared_examples/blocks_unsafe_serialization_shared_examples.rb
new file mode 100644
index 00000000000..db42e41344f
--- /dev/null
+++ b/spec/support/shared_examples/blocks_unsafe_serialization_shared_examples.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+# Requires a context with:
+# - object
+#
+RSpec.shared_examples 'blocks unsafe serialization' do
+ it 'blocks as_json' do
+ expect { object.as_json }.to raise_error(described_class::UnsafeSerializationError, /#{object.class.name}/)
+ end
+
+ it 'blocks to_json' do
+ expect { object.to_json }.to raise_error(described_class::UnsafeSerializationError, /#{object.class.name}/)
+ end
+end
+
+RSpec.shared_examples 'allows unsafe serialization' do
+ it 'allows as_json' do
+ expect { object.as_json }.not_to raise_error
+ end
+
+ it 'allows to_json' do
+ expect { object.to_json }.not_to raise_error
+ end
+end
diff --git a/spec/support/shared_examples/controllers/clusters_controller_shared_examples.rb b/spec/support/shared_examples/controllers/clusters_controller_shared_examples.rb
index aa17e72d08e..9fab7f3f94e 100644
--- a/spec/support/shared_examples/controllers/clusters_controller_shared_examples.rb
+++ b/spec/support/shared_examples/controllers/clusters_controller_shared_examples.rb
@@ -27,3 +27,33 @@ RSpec.shared_examples 'GET new cluster shared examples' do
end
end
end
+
+RSpec.shared_examples ':certificate_based_clusters feature flag index responses' do
+ context 'feature flag is disabled' do
+ before do
+ stub_feature_flags(certificate_based_clusters: false)
+ end
+
+ it 'does not list any clusters' do
+ subject
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(response).to render_template(:index)
+ expect(assigns(:clusters)).to be_empty
+ end
+ end
+end
+
+RSpec.shared_examples ':certificate_based_clusters feature flag controller responses' do
+ context 'feature flag is disabled' do
+ before do
+ stub_feature_flags(certificate_based_clusters: false)
+ end
+
+ it 'responds with :not_found' do
+ subject
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+end
diff --git a/spec/support/shared_examples/controllers/rate_limited_endpoint_shared_examples.rb b/spec/support/shared_examples/controllers/rate_limited_endpoint_shared_examples.rb
index bb2a4159071..20edca1ee9f 100644
--- a/spec/support/shared_examples/controllers/rate_limited_endpoint_shared_examples.rb
+++ b/spec/support/shared_examples/controllers/rate_limited_endpoint_shared_examples.rb
@@ -13,10 +13,16 @@ RSpec.shared_examples 'rate limited endpoint' do |rate_limit_key:|
env: :"#{rate_limit_key}_request_limit",
remote_ip: kind_of(String),
request_method: kind_of(String),
- path: kind_of(String),
- user_id: current_user.id,
- username: current_user.username
- }
+ path: kind_of(String)
+ }.merge(expected_user_attributes)
+ end
+
+ let(:expected_user_attributes) do
+ if defined?(current_user) && current_user.present?
+ { user_id: current_user.id, username: current_user.username }
+ else
+ {}
+ end
end
let(:error_message) { _('This endpoint has been requested too many times. Try again later.') }
diff --git a/spec/support/shared_examples/controllers/unique_hll_events_examples.rb b/spec/support/shared_examples/controllers/unique_hll_events_examples.rb
index 842ad89bafd..38c3157e898 100644
--- a/spec/support/shared_examples/controllers/unique_hll_events_examples.rb
+++ b/spec/support/shared_examples/controllers/unique_hll_events_examples.rb
@@ -2,14 +2,14 @@
#
# Requires a context containing:
# - request
-# - expected_type
-# - target_id
+# - expected_value
+# - target_event
RSpec.shared_examples 'tracking unique hll events' do
it 'tracks unique event' do
expect(Gitlab::UsageDataCounters::HLLRedisCounter).to(
receive(:track_event)
- .with(target_id, values: expected_type)
+ .with(target_event, values: expected_value)
.and_call_original # we call original to trigger additional validations; otherwise the method is stubbed
)
diff --git a/spec/support/shared_examples/controllers/uploads_actions_shared_examples.rb b/spec/support/shared_examples/controllers/uploads_actions_shared_examples.rb
index 5ed8dc7ce98..6dca94ecf0a 100644
--- a/spec/support/shared_examples/controllers/uploads_actions_shared_examples.rb
+++ b/spec/support/shared_examples/controllers/uploads_actions_shared_examples.rb
@@ -211,10 +211,22 @@ RSpec.shared_examples 'handle uploads' do
stub_feature_flags(enforce_auth_checks_on_uploads: true)
end
- it "responds with status 302" do
+ it "responds with appropriate status" do
show_upload
- expect(response).to have_gitlab_http_status(:redirect)
+ # We're switching here based on the class due to the feature
+ # flag :enforce_auth_checks_on_uploads switching on project.
+ # When it is enabled fully, we will apply the code it guards
+ # to both Projects::UploadsController as well as
+ # Groups::UploadsController.
+ #
+ # https://gitlab.com/gitlab-org/gitlab/-/issues/352291
+ #
+ if model.instance_of?(Group)
+ expect(response).to have_gitlab_http_status(:ok)
+ else
+ expect(response).to have_gitlab_http_status(:redirect)
+ end
end
end
@@ -305,7 +317,19 @@ RSpec.shared_examples 'handle uploads' do
it "responds with status 404" do
show_upload
- expect(response).to have_gitlab_http_status(:not_found)
+ # We're switching here based on the class due to the feature
+ # flag :enforce_auth_checks_on_uploads switching on
+ # project. When it is enabled fully, we will apply the
+ # code it guards to both Projects::UploadsController as
+ # well as Groups::UploadsController.
+ #
+ # https://gitlab.com/gitlab-org/gitlab/-/issues/352291
+ #
+ if model.instance_of?(Group)
+ expect(response).to have_gitlab_http_status(:ok)
+ else
+ expect(response).to have_gitlab_http_status(:not_found)
+ 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
index 1cb52c07069..bf26922d9c5 100644
--- a/spec/support/shared_examples/controllers/wiki_actions_shared_examples.rb
+++ b/spec/support/shared_examples/controllers/wiki_actions_shared_examples.rb
@@ -220,8 +220,8 @@ RSpec.shared_examples 'wiki controller actions' do
context 'page view tracking' do
it_behaves_like 'tracking unique hll events' do
- let(:target_id) { 'wiki_action' }
- let(:expected_type) { instance_of(String) }
+ let(:target_event) { 'wiki_action' }
+ let(:expected_value) { instance_of(String) }
end
it 'increases the page view counter' do
diff --git a/spec/support/shared_examples/features/clusters_shared_examples.rb b/spec/support/shared_examples/features/clusters_shared_examples.rb
new file mode 100644
index 00000000000..6ee60f20b2e
--- /dev/null
+++ b/spec/support/shared_examples/features/clusters_shared_examples.rb
@@ -0,0 +1,14 @@
+# frozen_string_literal: true
+
+RSpec.shared_examples "user disables a cluster" do
+ context 'when user disables the cluster' do
+ before do
+ page.find(:css, '.js-cluster-enable-toggle-area .js-project-feature-toggle').click
+ page.within('.js-cluster-details-form') { click_button 'Save changes' }
+ end
+
+ it 'user sees the successful message' do
+ expect(page).to have_content('Kubernetes cluster was successfully updated.')
+ end
+ end
+end
diff --git a/spec/support/shared_examples/features/container_registry_shared_examples.rb b/spec/support/shared_examples/features/container_registry_shared_examples.rb
index 06b2b8c621c..6aa7e6e6270 100644
--- a/spec/support/shared_examples/features/container_registry_shared_examples.rb
+++ b/spec/support/shared_examples/features/container_registry_shared_examples.rb
@@ -7,3 +7,20 @@ RSpec.shared_examples 'handling feature network errors with the container regist
expect(page).to have_content 'We are having trouble connecting to the Container Registry'
end
end
+
+RSpec.shared_examples 'rejecting tags destruction for an importing repository on' do |tags: []|
+ it 'rejects the tag destruction operation' do
+ service = instance_double('Projects::ContainerRepository::DeleteTagsService')
+ expect(service).to receive(:execute).with(container_repository) { { status: :error, message: 'repository importing' } }
+ expect(Projects::ContainerRepository::DeleteTagsService).to receive(:new).with(container_repository.project, user, tags: tags) { service }
+
+ first('[data-testid="additional-actions"]').click
+ first('[data-testid="single-delete-button"]').click
+ expect(find('.modal .modal-title')).to have_content _('Remove tag')
+ find('.modal .modal-footer .btn-danger').click
+
+ alert_body = find('.gl-alert-body')
+ expect(alert_body).to have_content('Tags temporarily cannot be marked for deletion. Please try again in a few minutes.')
+ expect(alert_body).to have_link('More details', href: help_page_path('user/packages/container_registry/index', anchor: 'tags-temporarily-cannot-be-marked-for-deletion'))
+ end
+end
diff --git a/spec/support/shared_examples/features/integrations/user_activates_mattermost_slash_command_integration_shared_examples.rb b/spec/support/shared_examples/features/integrations/user_activates_mattermost_slash_command_integration_shared_examples.rb
index cfa043322db..4c312b42c0a 100644
--- a/spec/support/shared_examples/features/integrations/user_activates_mattermost_slash_command_integration_shared_examples.rb
+++ b/spec/support/shared_examples/features/integrations/user_activates_mattermost_slash_command_integration_shared_examples.rb
@@ -18,7 +18,7 @@ RSpec.shared_examples 'user activates the Mattermost Slash Command integration'
click_active_checkbox
click_save_integration
- expect(current_path).to eq(edit_path)
+ expect(page).to have_current_path(edit_path, ignore_query: true)
expect(page).to have_content('Mattermost slash commands settings saved, but not active.')
end
@@ -28,7 +28,7 @@ RSpec.shared_examples 'user activates the Mattermost Slash Command integration'
fill_in 'service_token', with: token
click_save_integration
- expect(current_path).to eq(edit_path)
+ expect(page).to have_current_path(edit_path, ignore_query: true)
expect(page).to have_content('Mattermost slash commands settings saved and active.')
end
end
diff --git a/spec/support/shared_examples/features/manage_applications_shared_examples.rb b/spec/support/shared_examples/features/manage_applications_shared_examples.rb
index 27d50c67f24..3a8267b21da 100644
--- a/spec/support/shared_examples/features/manage_applications_shared_examples.rb
+++ b/spec/support/shared_examples/features/manage_applications_shared_examples.rb
@@ -5,7 +5,7 @@ RSpec.shared_examples 'manage applications' do
let_it_be(:application_name_changed) { "#{application_name} changed" }
let_it_be(:application_redirect_uri) { 'https://foo.bar' }
- it 'allows user to manage applications' do
+ it 'allows user to manage applications', :js do
visit new_application_path
expect(page).to have_content 'Add new application'
diff --git a/spec/support/shared_examples/features/multiple_assignees_widget_mr_shared_examples.rb b/spec/support/shared_examples/features/multiple_assignees_widget_mr_shared_examples.rb
new file mode 100644
index 00000000000..bbde448a1a1
--- /dev/null
+++ b/spec/support/shared_examples/features/multiple_assignees_widget_mr_shared_examples.rb
@@ -0,0 +1,47 @@
+# frozen_string_literal: true
+
+RSpec.shared_examples 'multiple assignees widget merge request' do |action, save_button_title|
+ it "#{action} a MR with multiple assignees", :js do
+ find('.js-assignee-search').click
+ page.within '.dropdown-menu-user' do
+ click_link user.name
+ click_link user2.name
+ end
+
+ # Extra click needed in order to toggle the dropdown
+ find('.js-assignee-search').click
+
+ expect(all('input[name="merge_request[assignee_ids][]"]', visible: false).map(&:value))
+ .to match_array([user.id.to_s, user2.id.to_s])
+
+ page.within '.js-assignee-search' do
+ expect(page).to have_content "#{user2.name} + 1 more"
+ end
+
+ click_button save_button_title
+
+ page.within '.issuable-sidebar' do
+ page.within '.assignee' do
+ expect(page).to have_content '2 Assignees'
+
+ click_button('Edit')
+
+ expect(page).to have_content user.name
+ expect(page).to have_content user2.name
+ end
+ end
+
+ page.within '.dropdown-menu-user' do
+ click_link user.name
+ end
+
+ page.within '.issuable-sidebar' do
+ page.within '.assignee' do
+ # Closing dropdown to persist
+ click_button('Apply')
+
+ expect(page).to have_content user2.name
+ end
+ end
+ end
+end
diff --git a/spec/support/shared_examples/features/project_upload_files_shared_examples.rb b/spec/support/shared_examples/features/project_upload_files_shared_examples.rb
index 85434ba7afd..066c3e17a09 100644
--- a/spec/support/shared_examples/features/project_upload_files_shared_examples.rb
+++ b/spec/support/shared_examples/features/project_upload_files_shared_examples.rb
@@ -24,7 +24,7 @@ RSpec.shared_examples 'it uploads and commits a new text file' do |drop: false|
click_button('Upload file')
expect(page).to have_content('New commit message')
- expect(current_path).to eq(project_new_merge_request_path(project))
+ expect(page).to have_current_path(project_new_merge_request_path(project), ignore_query: true)
click_link('Changes')
find("a[data-action='diffs']", text: 'Changes').click
@@ -129,7 +129,7 @@ RSpec.shared_examples 'it uploads and commits a new file to a forked project' do
fork = user.fork_of(project2.reload)
- expect(current_path).to eq(project_new_merge_request_path(fork))
+ expect(page).to have_current_path(project_new_merge_request_path(fork), ignore_query: true)
find("a[data-action='diffs']", text: 'Changes').click
diff --git a/spec/support/shared_examples/features/wiki/user_creates_wiki_page_shared_examples.rb b/spec/support/shared_examples/features/wiki/user_creates_wiki_page_shared_examples.rb
index dfc9a45bd0d..f676b6aa60d 100644
--- a/spec/support/shared_examples/features/wiki/user_creates_wiki_page_shared_examples.rb
+++ b/spec/support/shared_examples/features/wiki/user_creates_wiki_page_shared_examples.rb
@@ -50,7 +50,7 @@ RSpec.shared_examples 'User creates wiki page' do
click_on("Create page")
end
- expect(current_path).to include("one/two/three-test")
+ expect(page).to have_current_path(%r(one/two/three-test), ignore_query: true)
expect(page).to have_link(href: wiki_page_path(wiki, 'one/two/three-test'))
end
@@ -68,7 +68,7 @@ RSpec.shared_examples 'User creates wiki page' do
click_button("Create page")
end
- expect(current_path).to eq(wiki_page_path(wiki, "home"))
+ expect(page).to have_current_path(wiki_page_path(wiki, "home"), ignore_query: true)
expect(page).to have_content("test GitLab API doc Rake tasks Wiki header")
.and have_content("Home")
.and have_content("Last edited by #{user.name}")
@@ -76,7 +76,7 @@ RSpec.shared_examples 'User creates wiki page' do
click_link("test")
- expect(current_path).to eq(wiki_page_path(wiki, "test"))
+ expect(page).to have_current_path(wiki_page_path(wiki, "test"), ignore_query: true)
page.within(:css, ".wiki-page-header") do
expect(page).to have_content("Create New Page")
@@ -84,11 +84,11 @@ RSpec.shared_examples 'User creates wiki page' do
click_link("Home")
- expect(current_path).to eq(wiki_page_path(wiki, "home"))
+ expect(page).to have_current_path(wiki_page_path(wiki, "home"), ignore_query: true)
click_link("GitLab API")
- expect(current_path).to eq(wiki_page_path(wiki, "api"))
+ expect(page).to have_current_path(wiki_page_path(wiki, "api"), ignore_query: true)
page.within(:css, ".wiki-page-header") do
expect(page).to have_content("Create")
@@ -96,11 +96,11 @@ RSpec.shared_examples 'User creates wiki page' do
click_link("Home")
- expect(current_path).to eq(wiki_page_path(wiki, "home"))
+ expect(page).to have_current_path(wiki_page_path(wiki, "home"), ignore_query: true)
click_link("Rake tasks")
- expect(current_path).to eq(wiki_page_path(wiki, "raketasks"))
+ expect(page).to have_current_path(wiki_page_path(wiki, "raketasks"), ignore_query: true)
page.within(:css, ".wiki-page-header") do
expect(page).to have_content("Create")
diff --git a/spec/support/shared_examples/features/wiki/user_updates_wiki_page_shared_examples.rb b/spec/support/shared_examples/features/wiki/user_updates_wiki_page_shared_examples.rb
index a456b76b324..85490bffc0e 100644
--- a/spec/support/shared_examples/features/wiki/user_updates_wiki_page_shared_examples.rb
+++ b/spec/support/shared_examples/features/wiki/user_updates_wiki_page_shared_examples.rb
@@ -25,7 +25,7 @@ RSpec.shared_examples 'User updates wiki page' do
click_on('Cancel')
end
- expect(current_path).to eq wiki_path(wiki)
+ expect(page).to have_current_path wiki_path(wiki), ignore_query: true
end
it 'updates a page that has a path', :js do
@@ -36,7 +36,7 @@ RSpec.shared_examples 'User updates wiki page' do
click_on('Create page')
end
- expect(current_path).to include('one/two/three-test')
+ expect(page).to have_current_path(%r(one/two/three-test), ignore_query: true)
expect(find('.wiki-pages')).to have_content('three')
first(:link, text: 'three').click
@@ -45,7 +45,7 @@ RSpec.shared_examples 'User updates wiki page' do
click_on('Edit')
- expect(current_path).to include('one/two/three-test')
+ expect(page).to have_current_path(%r(one/two/three-test), ignore_query: true)
expect(page).to have_content('Edit Page')
fill_in('Content', with: 'Updated Wiki Content')
@@ -120,7 +120,7 @@ RSpec.shared_examples 'User updates wiki page' do
click_on('Cancel')
end
- expect(current_path).to eq(wiki_page_path(wiki, wiki_page))
+ expect(page).to have_current_path(wiki_page_path(wiki, wiki_page), ignore_query: true)
end
it_behaves_like 'wiki file attachments'
@@ -175,7 +175,7 @@ RSpec.shared_examples 'User updates wiki page' do
click_button('Save changes')
- expect(current_path).to eq(wiki_page_path(wiki, page_name))
+ expect(page).to have_current_path(wiki_page_path(wiki, page_name), ignore_query: true)
end
it 'moves the page to other dir', :js do
@@ -185,7 +185,7 @@ RSpec.shared_examples 'User updates wiki page' do
click_button('Save changes')
- expect(current_path).to eq(wiki_page_path(wiki, new_page_dir))
+ expect(page).to have_current_path(wiki_page_path(wiki, new_page_dir), ignore_query: true)
end
it 'remains in the same place if title has not changed', :js do
@@ -195,7 +195,7 @@ RSpec.shared_examples 'User updates wiki page' do
click_button('Save changes')
- expect(current_path).to eq(original_path)
+ expect(page).to have_current_path(original_path, ignore_query: true)
end
it 'can be moved to a different dir with a different name', :js do
@@ -205,7 +205,7 @@ RSpec.shared_examples 'User updates wiki page' do
click_button('Save changes')
- expect(current_path).to eq(wiki_page_path(wiki, new_page_dir))
+ expect(page).to have_current_path(wiki_page_path(wiki, new_page_dir), ignore_query: true)
end
it 'can be renamed and moved to the root folder', :js do
@@ -215,7 +215,7 @@ RSpec.shared_examples 'User updates wiki page' do
click_button('Save changes')
- expect(current_path).to eq(wiki_page_path(wiki, new_name))
+ expect(page).to have_current_path(wiki_page_path(wiki, new_name), ignore_query: true)
end
it 'squishes the title before creating the page', :js do
@@ -225,7 +225,7 @@ RSpec.shared_examples 'User updates wiki page' do
click_button('Save changes')
- expect(current_path).to eq(wiki_page_path(wiki, "foo1/bar1/#{page_name}"))
+ expect(page).to have_current_path(wiki_page_path(wiki, "foo1/bar1/#{page_name}"), ignore_query: true)
end
it_behaves_like 'wiki file attachments'
diff --git a/spec/support/shared_examples/features/wiki/user_views_wiki_page_shared_examples.rb b/spec/support/shared_examples/features/wiki/user_views_wiki_page_shared_examples.rb
index eec911f3b6f..a7c32932ba7 100644
--- a/spec/support/shared_examples/features/wiki/user_views_wiki_page_shared_examples.rb
+++ b/spec/support/shared_examples/features/wiki/user_views_wiki_page_shared_examples.rb
@@ -37,12 +37,12 @@ RSpec.shared_examples 'User views a wiki page' do
end
it 'shows the history of a page that has a path' do
- expect(current_path).to include('one/two/three-test')
+ expect(page).to have_current_path(%r(one/two/three-test))
first(:link, text: 'three').click
click_on('Page history')
- expect(current_path).to include('one/two/three-test')
+ expect(page).to have_current_path(%r(one/two/three-test))
page.within(:css, '.wiki-page-header') do
expect(page).to have_content('History')
@@ -50,7 +50,7 @@ RSpec.shared_examples 'User views a wiki page' do
end
it 'shows an old version of a page', :js do
- expect(current_path).to include('one/two/three-test')
+ expect(page).to have_current_path(%r(one/two/three-test))
expect(find('.wiki-pages')).to have_content('three')
first(:link, text: 'three').click
@@ -59,7 +59,7 @@ RSpec.shared_examples 'User views a wiki page' do
click_on('Edit')
- expect(current_path).to include('one/two/three-test')
+ expect(page).to have_current_path(%r(one/two/three-test))
expect(page).to have_content('Edit Page')
fill_in('Content', with: 'Updated Wiki Content')
@@ -93,13 +93,12 @@ RSpec.shared_examples 'User views a wiki page' do
let(:path) { upload_file_to_wiki(wiki, user, 'dk.png') }
it do
- expect(page).to have_xpath("//img[@data-src='#{wiki.wiki_base_path}/#{path}']")
+ expect(page).to have_xpath("//img[@src='#{wiki.wiki_base_path}/#{path}']")
expect(page).to have_link('image', href: "#{wiki.wiki_base_path}/#{path}")
click_on('image')
- expect(current_path).to match("wikis/#{path}")
- expect(page).not_to have_xpath('/html') # Page should render the image which means there is no html involved
+ expect(page).to have_current_path(%r(wikis/#{path}))
end
end
@@ -108,7 +107,7 @@ RSpec.shared_examples 'User views a wiki page' do
click_on('image')
- expect(current_path).to match("wikis/#{path}")
+ expect(page).to have_current_path(%r(wikis/#{path}))
expect(page).to have_content('Create New Page')
end
end
diff --git a/spec/support/shared_examples/features/wiki/user_views_wiki_pages_shared_examples.rb b/spec/support/shared_examples/features/wiki/user_views_wiki_pages_shared_examples.rb
index 314c2074eee..32cb2b1d187 100644
--- a/spec/support/shared_examples/features/wiki/user_views_wiki_pages_shared_examples.rb
+++ b/spec/support/shared_examples/features/wiki/user_views_wiki_pages_shared_examples.rb
@@ -60,7 +60,7 @@ RSpec.shared_examples 'User views wiki pages' do
before do
page.within('.wiki-sort-dropdown') do
click_button('Title')
- click_link('Created date')
+ click_button('Created date')
end
end
diff --git a/spec/support/shared_examples/graphql/members_shared_examples.rb b/spec/support/shared_examples/graphql/members_shared_examples.rb
index b0bdd27a95f..8e9e22f4359 100644
--- a/spec/support/shared_examples/graphql/members_shared_examples.rb
+++ b/spec/support/shared_examples/graphql/members_shared_examples.rb
@@ -76,8 +76,10 @@ RSpec.shared_examples 'querying members with a group' do
resolve(described_class, obj: resource, args: base_args.merge(args), ctx: { current_user: other_user })
end
- it 'raises an error' do
- expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
+ it 'generates an error' do
+ expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ResourceNotAvailable) do
+ subject
+ end
end
end
end
diff --git a/spec/support/shared_examples/graphql/mutations/security/ci_configuration_shared_examples.rb b/spec/support/shared_examples/graphql/mutations/security/ci_configuration_shared_examples.rb
index 14b2663a72c..21260e4d954 100644
--- a/spec/support/shared_examples/graphql/mutations/security/ci_configuration_shared_examples.rb
+++ b/spec/support/shared_examples/graphql/mutations/security/ci_configuration_shared_examples.rb
@@ -29,8 +29,10 @@ RSpec.shared_examples_for 'graphql mutations security ci configuration' do
describe '#resolve' do
let(:result) { subject }
- it 'raises an error if the resource is not accessible to the user' do
- expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
+ it 'generates an error if the resource is not accessible to the user' do
+ expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ResourceNotAvailable) do
+ subject
+ end
end
context 'when user does not have enough permissions' do
@@ -38,8 +40,10 @@ RSpec.shared_examples_for 'graphql mutations security ci configuration' do
project.add_guest(user)
end
- it 'raises an error' do
- expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
+ it 'generates an error' do
+ expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ResourceNotAvailable) do
+ subject
+ end
end
end
@@ -48,8 +52,10 @@ RSpec.shared_examples_for 'graphql mutations security ci configuration' do
create(:project_empty_repo).add_maintainer(user)
end
- it 'raises an error' do
- expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
+ it 'generates an error' do
+ expect_graphql_error_to_be_created(Gitlab::Graphql::Errors::ResourceNotAvailable) do
+ subject
+ end
end
end
diff --git a/spec/support/shared_examples/graphql/types/merge_request_interactions_type_shared_examples.rb b/spec/support/shared_examples/graphql/types/merge_request_interactions_type_shared_examples.rb
new file mode 100644
index 00000000000..0d0dbb112de
--- /dev/null
+++ b/spec/support/shared_examples/graphql/types/merge_request_interactions_type_shared_examples.rb
@@ -0,0 +1,57 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.shared_examples "a user type with merge request interaction type" do
+ specify { expect(described_class).to require_graphql_authorizations(:read_user) }
+
+ it 'has the expected fields' do
+ expected_fields = %w[
+ id
+ bot
+ user_permissions
+ snippets
+ name
+ username
+ email
+ publicEmail
+ avatarUrl
+ webUrl
+ webPath
+ todos
+ state
+ status
+ location
+ authoredMergeRequests
+ assignedMergeRequests
+ reviewRequestedMergeRequests
+ groupMemberships
+ groupCount
+ projectMemberships
+ starredProjects
+ callouts
+ merge_request_interaction
+ namespace
+ timelogs
+ groups
+ gitpodEnabled
+ preferencesGitpodPath
+ profileEnableGitpodPath
+ savedReplies
+ ]
+
+ expect(described_class).to have_graphql_fields(*expected_fields)
+ end
+
+ describe '#merge_request_interaction' do
+ subject { described_class.fields['mergeRequestInteraction'] }
+
+ it 'returns the correct type' do
+ is_expected.to have_graphql_type(Types::UserMergeRequestInteractionType)
+ end
+
+ it 'has the correct arguments' do
+ is_expected.to have_attributes(arguments: be_empty)
+ end
+ end
+end
diff --git a/spec/support/shared_examples/integrations/integration_settings_form.rb b/spec/support/shared_examples/integrations/integration_settings_form.rb
index d0bb40e43ee..d8a46180796 100644
--- a/spec/support/shared_examples/integrations/integration_settings_form.rb
+++ b/spec/support/shared_examples/integrations/integration_settings_form.rb
@@ -22,10 +22,7 @@ RSpec.shared_examples 'integration settings form' do
events = parse_json(trigger_events_for_integration(integration))
events.each do |trigger|
- # normalizing the title because capybara location is case sensitive
- title = normalize_title trigger[:title], integration
-
- expect(page).to have_field(title, type: 'checkbox', wait: 0),
+ expect(page).to have_field(trigger[:title], type: 'checkbox', wait: 0),
"#{integration.title} field #{title} checkbox not present"
end
end
@@ -35,12 +32,6 @@ RSpec.shared_examples 'integration settings form' do
private
- def normalize_title(title, integration)
- return 'Merge request' if integration.is_a?(Integrations::Jira) && title == 'merge_request'
-
- title.titlecase
- end
-
def parse_json(json)
Gitlab::Json.parse(json, symbolize_names: true)
end
diff --git a/spec/support/shared_examples/lib/gitlab/database/background_migration_job_shared_examples.rb b/spec/support/shared_examples/lib/gitlab/database/background_migration_job_shared_examples.rb
index 213f084be17..771ab89972c 100644
--- a/spec/support/shared_examples/lib/gitlab/database/background_migration_job_shared_examples.rb
+++ b/spec/support/shared_examples/lib/gitlab/database/background_migration_job_shared_examples.rb
@@ -2,7 +2,7 @@
RSpec.shared_examples 'marks background migration job records' do
it 'marks each job record as succeeded after processing' do
- create(:background_migration_job, class_name: "::#{described_class.name}",
+ create(:background_migration_job, class_name: "::#{described_class.name.demodulize}",
arguments: arguments)
expect(::Gitlab::Database::BackgroundMigrationJob).to receive(:mark_all_as_succeeded).and_call_original
@@ -13,7 +13,7 @@ RSpec.shared_examples 'marks background migration job records' do
end
it 'returns the number of job records marked as succeeded' do
- create(:background_migration_job, class_name: "::#{described_class.name}",
+ create(:background_migration_job, class_name: "::#{described_class.name.demodulize}",
arguments: arguments)
jobs_updated = subject.perform(*arguments)
diff --git a/spec/support/shared_examples/lib/gitlab/usage_data_counters/usage_counter_shared_examples.rb b/spec/support/shared_examples/lib/gitlab/usage_data_counters/usage_counter_shared_examples.rb
new file mode 100644
index 00000000000..848437577d7
--- /dev/null
+++ b/spec/support/shared_examples/lib/gitlab/usage_data_counters/usage_counter_shared_examples.rb
@@ -0,0 +1,40 @@
+# frozen_string_literal: true
+
+RSpec.shared_examples 'a usage counter' do
+ describe '.increment' do
+ let(:project_id) { 12 }
+
+ it 'intializes and increments the counter for the project by 1' do
+ expect do
+ described_class.increment(project_id)
+ end.to change { described_class.usage_totals[project_id] }.from(nil).to(1)
+ end
+ end
+
+ describe '.usage_totals' do
+ let(:usage_totals) { described_class.usage_totals }
+
+ context 'when the feature has not been used' do
+ it 'returns the total counts and counts per project' do
+ expect(usage_totals.keys).to eq([:total])
+ expect(usage_totals[:total]).to eq(0)
+ end
+ end
+
+ context 'when the feature has been used in multiple projects' do
+ let(:project1_id) { 12 }
+ let(:project2_id) { 16 }
+
+ before do
+ described_class.increment(project1_id)
+ described_class.increment(project2_id)
+ end
+
+ it 'returns the total counts and counts per project' do
+ expect(usage_totals[project1_id]).to eq(1)
+ expect(usage_totals[project2_id]).to eq(1)
+ expect(usage_totals[:total]).to eq(2)
+ end
+ end
+ end
+end
diff --git a/spec/support/shared_examples/lib/wikis_api_examples.rb b/spec/support/shared_examples/lib/wikis_api_examples.rb
index 2e4c667d37e..f068a7676ad 100644
--- a/spec/support/shared_examples/lib/wikis_api_examples.rb
+++ b/spec/support/shared_examples/lib/wikis_api_examples.rb
@@ -44,13 +44,70 @@ RSpec.shared_examples_for 'wikis API returns list of wiki pages' do
end
RSpec.shared_examples_for 'wikis API returns wiki page' do
- it 'returns the wiki page' do
- expect(response).to have_gitlab_http_status(:ok)
- expect(json_response.size).to eq(4)
- expect(json_response.keys).to match_array(expected_keys_with_content)
- expect(json_response['content']).to eq(page.content)
- expect(json_response['slug']).to eq(page.slug)
- expect(json_response['title']).to eq(page.title)
+ subject(:request) { get api(url, user), params: params }
+
+ shared_examples 'returns wiki page' do
+ before do
+ request
+ end
+
+ specify do
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response.size).to eq(5)
+ expect(json_response.keys).to match_array(expected_keys_with_content)
+ expect(json_response['content']).to eq(expected_content)
+ expect(json_response['slug']).to eq(page.slug)
+ expect(json_response['title']).to eq(page.title)
+ end
+ end
+
+ let(:expected_content) { page.content }
+
+ it_behaves_like 'returns wiki page'
+
+ context 'when render param is false' do
+ let(:params) { { render_html: false } }
+
+ it_behaves_like 'returns wiki page'
+ end
+
+ context 'when render param is true' do
+ let(:params) { { render_html: true } }
+ let(:expected_content) { '<p data-sourcepos="1:1-1:21" dir="auto">Content for wiki page</p>' }
+
+ it_behaves_like 'returns wiki page'
+ end
+
+ context 'when wiki page has versions' do
+ let(:new_content) { 'New content' }
+
+ before do
+ wiki.update_page(page.page, content: new_content, message: 'updated page')
+
+ expect(page.count_versions).to eq(2)
+
+ request
+ end
+
+ context 'when version param is not present' do
+ it 'retrieves the last version' do
+ expect(json_response['content']).to eq(new_content)
+ end
+ end
+
+ context 'when version param is set' do
+ let(:params) { { version: page.version.id } }
+
+ it 'retrieves the specific page version' do
+ expect(json_response['content']).to eq(page.content)
+ end
+
+ context 'when version param is not valid or inexistent' do
+ let(:params) { { version: 'foobar' } }
+
+ it_behaves_like 'wiki API 404 Wiki Page Not Found'
+ end
+ end
end
end
@@ -59,12 +116,13 @@ RSpec.shared_examples_for 'wikis API creates wiki page' do
post(api(url, user), params: payload)
expect(response).to have_gitlab_http_status(:created)
- expect(json_response.size).to eq(4)
+ expect(json_response.size).to eq(5)
expect(json_response.keys).to match_array(expected_keys_with_content)
expect(json_response['content']).to eq(payload[:content])
expect(json_response['slug']).to eq(payload[:title].tr(' ', '-'))
expect(json_response['title']).to eq(payload[:title])
expect(json_response['rdoc']).to eq(payload[:rdoc])
+ expect(json_response['encoding']).to eq('UTF-8')
end
[:title, :content].each do |part|
@@ -85,7 +143,7 @@ RSpec.shared_examples_for 'wikis API updates wiki page' do
put(api(url, user), params: payload)
expect(response).to have_gitlab_http_status(:ok)
- expect(json_response.size).to eq(4)
+ expect(json_response.size).to eq(5)
expect(json_response.keys).to match_array(expected_keys_with_content)
expect(json_response['content']).to eq(payload[:content])
expect(json_response['slug']).to eq(payload[:title].tr(' ', '-'))
diff --git a/spec/support/shared_examples/metrics/active_record_subscriber_shared_examples.rb b/spec/support/shared_examples/metrics/active_record_subscriber_shared_examples.rb
index 6e8c340582a..3f187a7e9e4 100644
--- a/spec/support/shared_examples/metrics/active_record_subscriber_shared_examples.rb
+++ b/spec/support/shared_examples/metrics/active_record_subscriber_shared_examples.rb
@@ -91,21 +91,6 @@ RSpec.shared_examples 'store ActiveRecord info in RequestStore' do |db_role|
end
end
end
-
- context 'when the GITLAB_MULTIPLE_DATABASE_METRICS env var is disabled' do
- before do
- stub_env('GITLAB_MULTIPLE_DATABASE_METRICS', nil)
- end
-
- it 'does not include per database metrics' do
- Gitlab::WithRequestStore.with_request_store do
- subscriber.sql(event)
-
- expect(described_class.db_counter_payload).not_to include(:"db_replica_#{db_config_name}_duration_s")
- expect(described_class.db_counter_payload).not_to include(:"db_replica_#{db_config_name}_count")
- end
- end
- end
end
RSpec.shared_examples 'record ActiveRecord metrics in a metrics transaction' do |db_role|
@@ -160,26 +145,6 @@ RSpec.shared_examples 'record ActiveRecord metrics in a metrics transaction' do
subscriber.sql(event)
end
-
- context 'when the GITLAB_MULTIPLE_DATABASE_METRICS env var is disabled' do
- before do
- stub_env('GITLAB_MULTIPLE_DATABASE_METRICS', nil)
- end
-
- it 'does not include db_config_name label' do
- allow(transaction).to receive(:increment) do |*args|
- labels = args[2] || {}
- expect(labels).not_to include(:db_config_name)
- end
-
- allow(transaction).to receive(:observe) do |*args|
- labels = args[2] || {}
- expect(labels).not_to include(:db_config_name)
- end
-
- subscriber.sql(event)
- end
- end
end
RSpec.shared_examples 'record ActiveRecord metrics' do |db_role|
diff --git a/spec/support/shared_examples/models/atomic_internal_id_shared_examples.rb b/spec/support/shared_examples/models/atomic_internal_id_shared_examples.rb
index fe85daa7235..bb15a3054ac 100644
--- a/spec/support/shared_examples/models/atomic_internal_id_shared_examples.rb
+++ b/spec/support/shared_examples/models/atomic_internal_id_shared_examples.rb
@@ -155,7 +155,7 @@ RSpec.shared_examples 'AtomicInternalId' do |validate_presence: true|
end
def expect_iid_to_be_set_and_rollback
- ActiveRecord::Base.transaction(requires_new: true) do
+ instance.transaction(requires_new: true) do
instance.save!
expect(read_internal_id).not_to be_nil
diff --git a/spec/support/shared_examples/models/concerns/integrations/slack_mattermost_notifier_shared_examples.rb b/spec/support/shared_examples/models/concerns/integrations/slack_mattermost_notifier_shared_examples.rb
index 2a976fb7421..d6415e98289 100644
--- a/spec/support/shared_examples/models/concerns/integrations/slack_mattermost_notifier_shared_examples.rb
+++ b/spec/support/shared_examples/models/concerns/integrations/slack_mattermost_notifier_shared_examples.rb
@@ -692,16 +692,6 @@ RSpec.shared_examples Integrations::SlackMattermostNotifier do |integration_name
context 'notification enabled for all branches' do
it_behaves_like "triggered #{integration_name} integration", event_type: "pipeline", branches_to_be_notified: "all"
end
-
- context 'when chat_notification_deployment_protected_branch_filter is disabled' do
- before do
- stub_feature_flags(chat_notification_deployment_protected_branch_filter: false)
- end
-
- context 'notification enabled only for default branch' do
- it_behaves_like "triggered #{integration_name} integration", event_type: "pipeline", branches_to_be_notified: "default"
- end
- end
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 07d687147bc..0ff0895b861 100644
--- a/spec/support/shared_examples/models/concerns/limitable_shared_examples.rb
+++ b/spec/support/shared_examples/models/concerns/limitable_shared_examples.rb
@@ -23,7 +23,7 @@ RSpec.shared_examples 'includes Limitable concern' do
context 'with an existing model' do
before do
- subject.dup.save!
+ subject.clone.save!
end
it 'cannot create new models exceeding the plan limits' do
diff --git a/spec/support/shared_examples/models/concerns/timebox_shared_examples.rb b/spec/support/shared_examples/models/concerns/timebox_shared_examples.rb
index 39121b73bc5..a2b4cdc33d0 100644
--- a/spec/support/shared_examples/models/concerns/timebox_shared_examples.rb
+++ b/spec/support/shared_examples/models/concerns/timebox_shared_examples.rb
@@ -66,17 +66,6 @@ RSpec.shared_examples 'a timebox' do |timebox_type|
end
end
- describe 'title' do
- it { is_expected.to validate_presence_of(:title) }
-
- it 'is invalid if title would be empty after sanitation' do
- timebox = build(timebox_type, *timebox_args, project: project, title: '<img src=x onerror=prompt(1)>')
-
- expect(timebox).not_to be_valid
- expect(timebox.errors[:title]).to include("can't be blank")
- end
- end
-
describe '#timebox_type_check' do
it 'is invalid if it has both project_id and group_id' do
timebox = build(timebox_type, *timebox_args, group: group)
diff --git a/spec/support/shared_examples/models/concerns/update_namespace_statistics_shared_examples.rb b/spec/support/shared_examples/models/concerns/update_namespace_statistics_shared_examples.rb
new file mode 100644
index 00000000000..255b6efa518
--- /dev/null
+++ b/spec/support/shared_examples/models/concerns/update_namespace_statistics_shared_examples.rb
@@ -0,0 +1,54 @@
+# frozen_string_literal: true
+
+RSpec.shared_examples 'updates namespace statistics' do
+ let(:namespace_statistics_name) { described_class.namespace_statistics_name }
+ let(:statistic_attribute) { described_class.statistic_attribute }
+
+ context 'when creating' do
+ before do
+ statistic_source.send("#{statistic_attribute}=", 10)
+ end
+
+ it 'schedules a statistic refresh' do
+ expect(Groups::UpdateStatisticsWorker)
+ .to receive(:perform_async)
+
+ statistic_source.save!
+ end
+ end
+
+ context 'when updating' do
+ before do
+ statistic_source.save!
+
+ expect(statistic_source).to be_persisted
+ end
+
+ context 'when the statistic attribute has not changed' do
+ it 'does not schedule a statistic refresh' do
+ expect(Groups::UpdateStatisticsWorker)
+ .not_to receive(:perform_async)
+
+ statistic_source.update!(file_name: 'new-file-name.txt')
+ end
+ end
+
+ context 'when the statistic attribute has changed' do
+ it 'schedules a statistic refresh' do
+ expect(Groups::UpdateStatisticsWorker)
+ .to receive(:perform_async)
+
+ statistic_source.update!(statistic_attribute => 20)
+ end
+ end
+ end
+
+ context 'when deleting' do
+ it 'schedules a statistic refresh' do
+ expect(Groups::UpdateStatisticsWorker)
+ .to receive(:perform_async)
+
+ statistic_source.destroy!
+ end
+ end
+end
diff --git a/spec/support/shared_examples/models/issuable_link_shared_examples.rb b/spec/support/shared_examples/models/issuable_link_shared_examples.rb
new file mode 100644
index 00000000000..ca98c2597a2
--- /dev/null
+++ b/spec/support/shared_examples/models/issuable_link_shared_examples.rb
@@ -0,0 +1,65 @@
+# frozen_string_literal: true
+
+# This shared example requires the following variables
+# issuable_link
+# issuable
+# issuable_class
+# issuable_link_factory
+RSpec.shared_examples 'issuable link' do
+ describe 'Associations' do
+ it { is_expected.to belong_to(:source).class_name(issuable.class.name) }
+ it { is_expected.to belong_to(:target).class_name(issuable.class.name) }
+ end
+
+ describe 'Validation' do
+ subject { issuable_link }
+
+ it { is_expected.to validate_presence_of(:source) }
+ it { is_expected.to validate_presence_of(:target) }
+ it do
+ is_expected.to validate_uniqueness_of(:source)
+ .scoped_to(:target_id)
+ .with_message(/already related/)
+ end
+
+ it 'is not valid if an opposite link already exists' do
+ issuable_link = create_issuable_link(subject.target, subject.source)
+
+ expect(issuable_link).to be_invalid
+ expect(issuable_link.errors[:source]).to include("is already related to this #{issuable.class.name.downcase}")
+ end
+
+ context 'when it relates to itself' do
+ context 'when target is nil' do
+ it 'does not invalidate object with self relation error' do
+ issuable_link = create_issuable_link(issuable, nil)
+
+ issuable_link.valid?
+
+ expect(issuable_link.errors[:source]).to be_empty
+ end
+ end
+
+ context 'when source and target are present' do
+ it 'invalidates object' do
+ issuable_link = create_issuable_link(issuable, issuable)
+
+ expect(issuable_link).to be_invalid
+ expect(issuable_link.errors[:source]).to include('cannot be related to itself')
+ end
+ end
+ end
+
+ def create_issuable_link(source, target)
+ build(issuable_link_factory, source: source, target: target)
+ end
+ end
+
+ describe '.link_type' do
+ it { is_expected.to define_enum_for(:link_type).with_values(relates_to: 0, blocks: 1) }
+
+ it 'provides the "related" as default link_type' do
+ expect(issuable_link.link_type).to eq 'relates_to'
+ end
+ end
+end
diff --git a/spec/support/shared_examples/models/member_shared_examples.rb b/spec/support/shared_examples/models/member_shared_examples.rb
index f7e09cfca62..17026f085bb 100644
--- a/spec/support/shared_examples/models/member_shared_examples.rb
+++ b/spec/support/shared_examples/models/member_shared_examples.rb
@@ -371,8 +371,7 @@ RSpec.shared_examples_for "bulk member creation" do
it 'returns a Member objects' do
members = described_class.add_users(source, [user1, user2], :maintainer)
- expect(members).to be_a Array
- expect(members.size).to eq(2)
+ expect(members.map(&:user)).to contain_exactly(user1, user2)
expect(members).to all(be_a(member_type))
expect(members).to all(be_persisted)
end
@@ -394,20 +393,18 @@ RSpec.shared_examples_for "bulk member creation" do
end
context 'with de-duplication' do
- it 'with the same user by id and user' do
+ it 'has the same user by id and user' do
members = described_class.add_users(source, [user1.id, user1, user1.id, user2, user2.id, user2], :maintainer)
- expect(members).to be_a Array
- expect(members.size).to eq(2)
+ expect(members.map(&:user)).to contain_exactly(user1, user2)
expect(members).to all(be_a(member_type))
expect(members).to all(be_persisted)
end
- it 'with the same user sent more than once' do
+ it 'has the same user sent more than once' do
members = described_class.add_users(source, [user1, user1], :maintainer)
- expect(members).to be_a Array
- expect(members.size).to eq(1)
+ expect(members.map(&:user)).to contain_exactly(user1)
expect(members).to all(be_a(member_type))
expect(members).to all(be_persisted)
end
@@ -418,15 +415,35 @@ RSpec.shared_examples_for "bulk member creation" do
source.add_user(user1, :developer)
end
- it 'supports existing users as expected' do
+ it 'has the same user sent more than once with the member already existing' do
+ expect do
+ members = described_class.add_users(source, [user1, user1, user2], :maintainer)
+ expect(members.map(&:user)).to contain_exactly(user1, user2)
+ expect(members).to all(be_a(member_type))
+ expect(members).to all(be_persisted)
+ end.to change { Member.count }.by(1)
+ end
+
+ it 'supports existing users as expected with user_ids passed' do
user3 = create(:user)
- members = described_class.add_users(source, [user1.id, user2, user3.id], :maintainer)
+ expect do
+ members = described_class.add_users(source, [user1.id, user2, user3.id], :maintainer)
+ expect(members.map(&:user)).to contain_exactly(user1, user2, user3)
+ expect(members).to all(be_a(member_type))
+ expect(members).to all(be_persisted)
+ end.to change { Member.count }.by(2)
+ end
+
+ it 'supports existing users as expected without user ids passed' do
+ user3 = create(:user)
- expect(members).to be_a Array
- expect(members.size).to eq(3)
- expect(members).to all(be_a(member_type))
- expect(members).to all(be_persisted)
+ expect do
+ members = described_class.add_users(source, [user1, user2, user3], :maintainer)
+ expect(members.map(&:user)).to contain_exactly(user1, user2, user3)
+ expect(members).to all(be_a(member_type))
+ expect(members).to all(be_persisted)
+ end.to change { Member.count }.by(2)
end
end
diff --git a/spec/support/shared_examples/models/resource_event_shared_examples.rb b/spec/support/shared_examples/models/resource_event_shared_examples.rb
index c0158f9b24b..80806ee768a 100644
--- a/spec/support/shared_examples/models/resource_event_shared_examples.rb
+++ b/spec/support/shared_examples/models/resource_event_shared_examples.rb
@@ -62,15 +62,15 @@ RSpec.shared_examples 'a resource event for issues' do
let_it_be(:issue2) { create(:issue, author: user1) }
let_it_be(:issue3) { create(:issue, author: user2) }
+ let_it_be(:event1) { create(described_class.name.underscore.to_sym, issue: issue1) }
+ let_it_be(:event2) { create(described_class.name.underscore.to_sym, issue: issue2) }
+ let_it_be(:event3) { create(described_class.name.underscore.to_sym, issue: issue1) }
+
describe 'associations' do
it { is_expected.to belong_to(:issue) }
end
describe '.by_issue' do
- let_it_be(:event1) { create(described_class.name.underscore.to_sym, issue: issue1) }
- let_it_be(:event2) { create(described_class.name.underscore.to_sym, issue: issue2) }
- let_it_be(:event3) { create(described_class.name.underscore.to_sym, issue: issue1) }
-
it 'returns the expected records for an issue with events' do
events = described_class.by_issue(issue1)
@@ -84,21 +84,29 @@ RSpec.shared_examples 'a resource event for issues' do
end
end
- describe '.by_issue_ids_and_created_at_earlier_or_equal_to' do
+ describe '.by_issue_ids' do
+ it 'returns the expected events' do
+ events = described_class.by_issue_ids([issue1.id])
+
+ expect(events).to contain_exactly(event1, event3)
+ end
+ end
+
+ describe '.by_created_at_earlier_or_equal_to' do
let_it_be(:event1) { create(described_class.name.underscore.to_sym, issue: issue1, created_at: '2020-03-10') }
let_it_be(:event2) { create(described_class.name.underscore.to_sym, issue: issue2, created_at: '2020-03-10') }
let_it_be(:event3) { create(described_class.name.underscore.to_sym, issue: issue1, created_at: '2020-03-12') }
- it 'returns the expected records for an issue with events' do
- events = described_class.by_issue_ids_and_created_at_earlier_or_equal_to([issue1.id, issue2.id], '2020-03-11 23:59:59')
+ it 'returns the expected events' do
+ events = described_class.by_created_at_earlier_or_equal_to('2020-03-11 23:59:59')
expect(events).to contain_exactly(event1, event2)
end
- it 'returns the expected records for an issue with no events' do
- events = described_class.by_issue_ids_and_created_at_earlier_or_equal_to(issue3, '2020-03-12')
+ it 'returns the expected events' do
+ events = described_class.by_created_at_earlier_or_equal_to('2020-03-12')
- expect(events).to be_empty
+ expect(events).to contain_exactly(event1, event2, event3)
end
end
diff --git a/spec/support/shared_examples/models/runners_token_prefix_shared_examples.rb b/spec/support/shared_examples/models/runners_token_prefix_shared_examples.rb
deleted file mode 100644
index 4dce445ac73..00000000000
--- a/spec/support/shared_examples/models/runners_token_prefix_shared_examples.rb
+++ /dev/null
@@ -1,13 +0,0 @@
-# frozen_string_literal: true
-
-RSpec.shared_examples 'it has a prefixable runners_token' do
- describe '#runners_token' do
- it 'has a runners_token_prefix' do
- expect(subject.runners_token_prefix).not_to be_empty
- end
-
- it 'starts with the runners_token_prefix' do
- expect(subject.runners_token).to start_with(subject.runners_token_prefix)
- end
- end
-end
diff --git a/spec/support/shared_examples/models/wiki_shared_examples.rb b/spec/support/shared_examples/models/wiki_shared_examples.rb
index bc5956e3eec..b3f79d9fe6e 100644
--- a/spec/support/shared_examples/models/wiki_shared_examples.rb
+++ b/spec/support/shared_examples/models/wiki_shared_examples.rb
@@ -599,36 +599,13 @@ RSpec.shared_examples 'wiki model' do
context 'when repository is empty' do
let(:wiki_container) { wiki_container_without_repo }
- it 'changes the HEAD reference to the default branch' do
- wiki.repository.create_if_not_exists
- wiki.repository.raw_repository.write_ref('HEAD', 'refs/heads/bar')
+ it 'creates the repository with the default branch' do
+ wiki.repository.create_if_not_exists(default_branch)
subject
expect(File.read(head_path).squish).to eq "ref: refs/heads/#{default_branch}"
end
end
-
- context 'when repository is not empty' do
- before do
- wiki.create_page('index', 'test content')
- end
-
- it 'does nothing when HEAD points to the right branch' do
- expect(wiki.repository.raw_repository).not_to receive(:write_ref)
-
- subject
- end
-
- context 'when HEAD points to the wrong branch' do
- it 'rewrites HEAD with the right branch' do
- wiki.repository.raw_repository.write_ref('HEAD', 'refs/heads/bar')
-
- subject
-
- expect(File.read(head_path).squish).to eq "ref: refs/heads/#{default_branch}"
- end
- end
- end
end
end
diff --git a/spec/support/shared_examples/namespaces/traversal_scope_examples.rb b/spec/support/shared_examples/namespaces/traversal_scope_examples.rb
index bcb5464ed5b..f1ace9878e9 100644
--- a/spec/support/shared_examples/namespaces/traversal_scope_examples.rb
+++ b/spec/support/shared_examples/namespaces/traversal_scope_examples.rb
@@ -90,7 +90,7 @@ RSpec.shared_examples 'namespace traversal scopes' do
it_behaves_like '.roots'
- it 'make recursive queries' do
+ it 'makes recursive queries' do
expect { described_class.where(id: [nested_group_1]).roots.load }.to make_queries_matching(/WITH RECURSIVE/)
end
end
@@ -126,7 +126,7 @@ RSpec.shared_examples 'namespace traversal scopes' do
end
context 'with offset and limit' do
- subject { described_class.where(id: [deep_nested_group_1, deep_nested_group_2]).offset(1).limit(1).self_and_ancestors }
+ subject { described_class.where(id: [deep_nested_group_1, deep_nested_group_2]).order(:traversal_ids).offset(1).limit(1).self_and_ancestors }
it { is_expected.to contain_exactly(group_2, nested_group_2, deep_nested_group_2) }
end
@@ -159,7 +159,7 @@ RSpec.shared_examples 'namespace traversal scopes' do
it_behaves_like '.self_and_ancestors'
- it 'make recursive queries' do
+ it 'makes recursive queries' do
expect { described_class.where(id: [nested_group_1]).self_and_ancestors.load }.to make_queries_matching(/WITH RECURSIVE/)
end
end
@@ -185,6 +185,7 @@ RSpec.shared_examples 'namespace traversal scopes' do
subject do
described_class
.where(id: [deep_nested_group_1, deep_nested_group_2])
+ .order(:traversal_ids)
.limit(1)
.offset(1)
.self_and_ancestor_ids
@@ -204,7 +205,7 @@ RSpec.shared_examples 'namespace traversal scopes' do
it_behaves_like '.self_and_ancestor_ids'
- it 'make recursive queries' do
+ it 'makes recursive queries' do
expect { described_class.where(id: [nested_group_1]).self_and_ancestor_ids.load }.not_to make_queries_matching(/WITH RECURSIVE/)
end
end
@@ -216,7 +217,7 @@ RSpec.shared_examples 'namespace traversal scopes' do
it_behaves_like '.self_and_ancestor_ids'
- it 'make recursive queries' do
+ it 'makes recursive queries' do
expect { described_class.where(id: [nested_group_1]).self_and_ancestor_ids.load }.to make_queries_matching(/WITH RECURSIVE/)
end
end
@@ -240,10 +241,20 @@ RSpec.shared_examples 'namespace traversal scopes' do
end
context 'with offset and limit' do
- subject { described_class.where(id: [group_1, group_2]).offset(1).limit(1).self_and_descendants }
+ subject { described_class.where(id: [group_1, group_2]).order(:traversal_ids).offset(1).limit(1).self_and_descendants }
it { is_expected.to contain_exactly(group_2, nested_group_2, deep_nested_group_2) }
end
+
+ context 'with nested query groups' do
+ let!(:nested_group_1b) { create(:group, parent: group_1) }
+ let!(:deep_nested_group_1b) { create(:group, parent: nested_group_1b) }
+ let(:group1_hierarchy) { [group_1, nested_group_1, deep_nested_group_1, nested_group_1b, deep_nested_group_1b] }
+
+ subject { described_class.where(id: [group_1, nested_group_1]).self_and_descendants }
+
+ it { is_expected.to match_array group1_hierarchy }
+ end
end
describe '.self_and_descendants' do
@@ -278,6 +289,7 @@ RSpec.shared_examples 'namespace traversal scopes' do
subject do
described_class
.where(id: [group_1, group_2])
+ .order(:traversal_ids)
.limit(1)
.offset(1)
.self_and_descendant_ids
@@ -340,7 +352,7 @@ RSpec.shared_examples 'namespace traversal scopes' do
it_behaves_like '.self_and_hierarchy'
- it 'make recursive queries' do
+ it 'makes recursive queries' do
base_groups = Group.where(id: nested_group_1)
expect { base_groups.self_and_hierarchy.load }.to make_queries_matching(/WITH RECURSIVE/)
end
diff --git a/spec/support/shared_examples/requests/api/conan_packages_shared_examples.rb b/spec/support/shared_examples/requests/api/conan_packages_shared_examples.rb
index b30c4186f0d..82c34f0d6ad 100644
--- a/spec/support/shared_examples/requests/api/conan_packages_shared_examples.rb
+++ b/spec/support/shared_examples/requests/api/conan_packages_shared_examples.rb
@@ -178,6 +178,25 @@ RSpec.shared_examples 'rejects invalid recipe' do
end
end
+RSpec.shared_examples 'handling validation error for package' do
+ context 'with validation error' do
+ before do
+ allow_next_instance_of(Packages::Package) do |instance|
+ instance.errors.add(:base, 'validation error')
+
+ allow(instance).to receive(:valid?).and_return(false)
+ end
+ end
+
+ it 'returns 400' do
+ subject
+
+ expect(response).to have_gitlab_http_status(:bad_request)
+ expect(json_response['message']).to include('Validation failed')
+ end
+ end
+end
+
RSpec.shared_examples 'handling empty values for username and channel' do
using RSpec::Parameterized::TableSyntax
@@ -678,6 +697,7 @@ RSpec.shared_examples 'workhorse recipe file upload endpoint' do
it_behaves_like 'uploads a package file'
it_behaves_like 'creates build_info when there is a job'
it_behaves_like 'handling empty values for username and channel'
+ it_behaves_like 'handling validation error for package'
end
RSpec.shared_examples 'workhorse package file upload endpoint' do
@@ -700,6 +720,7 @@ RSpec.shared_examples 'workhorse package file upload endpoint' do
it_behaves_like 'uploads a package file'
it_behaves_like 'creates build_info when there is a job'
it_behaves_like 'handling empty values for username and channel'
+ it_behaves_like 'handling validation error for package'
context 'tracking the conan_package.tgz upload' do
let(:file_name) { ::Packages::Conan::FileMetadatum::PACKAGE_BINARY }
diff --git a/spec/support/shared_examples/requests/api/time_tracking_shared_examples.rb b/spec/support/shared_examples/requests/api/time_tracking_shared_examples.rb
index 104e91add8b..381583ff2a9 100644
--- a/spec/support/shared_examples/requests/api/time_tracking_shared_examples.rb
+++ b/spec/support/shared_examples/requests/api/time_tracking_shared_examples.rb
@@ -86,7 +86,7 @@ RSpec.shared_examples 'time tracking endpoints' do |issuable_name|
end
it "add spent time for #{issuable_name}" do
- Timecop.travel(1.minute.from_now) do
+ travel_to(2.minutes.from_now) do
expect do
post api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.iid}/add_spent_time", user), params: { duration: '2h' }
end.to change { issuable.reload.updated_at }
@@ -98,7 +98,7 @@ RSpec.shared_examples 'time tracking endpoints' do |issuable_name|
context 'when subtracting time' do
it 'subtracts time of the total spent time' do
- Timecop.travel(1.minute.from_now) do
+ travel_to(2.minutes.from_now) do
expect do
issuable.update!(spend_time: { duration: 7200, user_id: user.id })
end.to change { issuable.reload.updated_at }
@@ -115,7 +115,7 @@ RSpec.shared_examples 'time tracking endpoints' do |issuable_name|
it 'does not modify the total time spent' do
issuable.update!(spend_time: { duration: 7200, user_id: user.id })
- Timecop.travel(1.minute.from_now) do
+ travel_to(2.minutes.from_now) do
expect do
post api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.iid}/add_spent_time", user), params: { duration: '-1w' }
end.not_to change { issuable.reload.updated_at }
@@ -160,7 +160,7 @@ RSpec.shared_examples 'time tracking endpoints' do |issuable_name|
end
it "resets spent time for #{issuable_name}" do
- Timecop.travel(1.minute.from_now) do
+ travel_to(2.minutes.from_now) do
expect do
post api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.iid}/reset_spent_time", user)
end.to change { issuable.reload.updated_at }
diff --git a/spec/support/shared_examples/requests/clusters/certificate_based_clusters_feature_flag_shared_examples.rb b/spec/support/shared_examples/requests/clusters/certificate_based_clusters_feature_flag_shared_examples.rb
new file mode 100644
index 00000000000..24d90bde814
--- /dev/null
+++ b/spec/support/shared_examples/requests/clusters/certificate_based_clusters_feature_flag_shared_examples.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+RSpec.shared_examples ':certificate_based_clusters feature flag API responses' do
+ context 'feature flag is disabled' do
+ before do
+ stub_feature_flags(certificate_based_clusters: false)
+ end
+
+ it 'responds with :not_found' do
+ subject
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+end
diff --git a/spec/support/shared_examples/row_lock_shared_examples.rb b/spec/support/shared_examples/row_lock_shared_examples.rb
index 5e003172215..24fb2d41bdf 100644
--- a/spec/support/shared_examples/row_lock_shared_examples.rb
+++ b/spec/support/shared_examples/row_lock_shared_examples.rb
@@ -7,7 +7,7 @@
RSpec.shared_examples 'locked row' do
it "has locked row" do
table_name = row.class.table_name
- ids_regex = /SELECT.*FROM.*#{table_name}.*"#{table_name}"."id" = #{row.id}.+FOR UPDATE/m
+ ids_regex = /SELECT.*FROM.*#{table_name}.*"#{table_name}"."id" = #{row.id}.+FOR NO KEY UPDATE/m
expect(recorded_queries.log).to include a_string_matching 'SAVEPOINT'
expect(recorded_queries.log).to include a_string_matching ids_regex
diff --git a/spec/support/shared_examples/sends_git_audit_streaming_event_shared_examples.rb b/spec/support/shared_examples/sends_git_audit_streaming_event_shared_examples.rb
new file mode 100644
index 00000000000..2c2be0152a0
--- /dev/null
+++ b/spec/support/shared_examples/sends_git_audit_streaming_event_shared_examples.rb
@@ -0,0 +1,61 @@
+# frozen_string_literal: true
+
+RSpec.shared_examples 'sends git audit streaming event' do
+ let_it_be(:user) { create(:user) }
+
+ before do
+ stub_licensed_features(external_audit_events: true)
+ end
+
+ subject {}
+
+ context 'for public groups and projects' do
+ let(:group) { create(:group, :public) }
+ let(:project) { create(:project, :public, :repository, namespace: group) }
+
+ before do
+ group.external_audit_event_destinations.create!(destination_url: 'http://example.com')
+ project.add_developer(user)
+ end
+
+ context 'when user not logged in' do
+ let(:key) { create(:key) }
+
+ before do
+ if request
+ request.headers.merge! auth_env(user.username, nil, nil)
+ end
+ end
+ it 'sends the audit streaming event' do
+ expect(AuditEvents::AuditEventStreamingWorker).not_to receive(:perform_async)
+ subject
+ end
+ end
+ end
+
+ context 'for private groups and projects' do
+ let(:group) { create(:group, :private) }
+ let(:project) { create(:project, :private, :repository, namespace: group) }
+
+ before do
+ group.external_audit_event_destinations.create!(destination_url: 'http://example.com')
+ project.add_developer(user)
+ sign_in(user)
+ end
+
+ context 'when user logged in' do
+ let(:key) { create(:key, user: user) }
+
+ before do
+ if request
+ password = user.try(:password) || user.try(:token)
+ request.headers.merge! auth_env(user.username, password, nil)
+ end
+ end
+ it 'sends the audit streaming event' do
+ expect(AuditEvents::AuditEventStreamingWorker).to receive(:perform_async).once
+ subject
+ end
+ end
+ end
+end
diff --git a/spec/support/shared_examples/serializers/environment_serializer_shared_examples.rb b/spec/support/shared_examples/serializers/environment_serializer_shared_examples.rb
index 9d7ae6bcb3d..87a33060435 100644
--- a/spec/support/shared_examples/serializers/environment_serializer_shared_examples.rb
+++ b/spec/support/shared_examples/serializers/environment_serializer_shared_examples.rb
@@ -1,13 +1,19 @@
# frozen_string_literal: true
-RSpec.shared_examples 'avoid N+1 on environments serialization' do
+RSpec.shared_examples 'avoid N+1 on environments serialization' do |ee: false|
+ # Investigating in https://gitlab.com/gitlab-org/gitlab/-/issues/353209
+ let(:query_threshold) { 1 + (ee ? 4 : 0) }
+
it 'avoids N+1 database queries with grouping', :request_store do
create_environment_with_associations(project)
control = ActiveRecord::QueryRecorder.new { serialize(grouping: true) }
create_environment_with_associations(project)
+ create_environment_with_associations(project)
- expect { serialize(grouping: true) }.not_to exceed_query_limit(control.count)
+ expect { serialize(grouping: true) }
+ .not_to exceed_query_limit(control.count)
+ .with_threshold(query_threshold)
end
it 'avoids N+1 database queries without grouping', :request_store do
@@ -16,8 +22,11 @@ RSpec.shared_examples 'avoid N+1 on environments serialization' do
control = ActiveRecord::QueryRecorder.new { serialize(grouping: false) }
create_environment_with_associations(project)
+ create_environment_with_associations(project)
- expect { serialize(grouping: false) }.not_to exceed_query_limit(control.count)
+ expect { serialize(grouping: false) }
+ .not_to exceed_query_limit(control.count)
+ .with_threshold(query_threshold)
end
it 'does not preload for environments that does not exist in the page', :request_store do
@@ -35,7 +44,7 @@ RSpec.shared_examples 'avoid N+1 on environments serialization' do
end
def serialize(grouping:, query: nil)
- query ||= { page: 1, per_page: 1 }
+ query ||= { page: 1, per_page: 20 }
request = double(url: "#{Gitlab.config.gitlab.url}:8080/api/v4/projects?#{query.to_query}", query_parameters: query)
EnvironmentSerializer.new(current_user: user, project: project).yield_self do |serializer|
diff --git a/spec/support/shared_examples/serializers/note_entity_shared_examples.rb b/spec/support/shared_examples/serializers/note_entity_shared_examples.rb
index 9af6ec45e49..2e557ca090c 100644
--- a/spec/support/shared_examples/serializers/note_entity_shared_examples.rb
+++ b/spec/support/shared_examples/serializers/note_entity_shared_examples.rb
@@ -68,6 +68,29 @@ RSpec.shared_examples 'note entity' do
end
end
+ describe ':outdated_line_change_path' do
+ before do
+ allow(note).to receive(:show_outdated_changes?).and_return(show_outdated_changes)
+ end
+
+ context 'when note shows outdated changes' do
+ let(:show_outdated_changes) { true }
+
+ it 'returns correct outdated_line_change_namespace_project_note_path' do
+ path = "/#{note.project.namespace.path}/#{note.project.path}/notes/#{note.id}/outdated_line_change"
+ expect(subject[:outdated_line_change_path]).to eq(path)
+ end
+ end
+
+ context 'when note does not show outdated changes' do
+ let(:show_outdated_changes) { false }
+
+ it 'does not expose outdated_line_change_path' do
+ expect(subject).not_to include(:outdated_line_change_path)
+ end
+ end
+ end
+
context 'when note was edited' do
before do
note.update!(updated_at: 1.minute.from_now, updated_by: user)
diff --git a/spec/support/shared_examples/services/container_registry_auth_service_shared_examples.rb b/spec/support/shared_examples/services/container_registry_auth_service_shared_examples.rb
index c808b9a5318..a780952d51b 100644
--- a/spec/support/shared_examples/services/container_registry_auth_service_shared_examples.rb
+++ b/spec/support/shared_examples/services/container_registry_auth_service_shared_examples.rb
@@ -69,10 +69,6 @@ RSpec.shared_examples 'a browsable' do
end
RSpec.shared_examples 'an accessible' do
- before do
- stub_feature_flags(container_registry_migration_phase1: false)
- end
-
let(:access) do
[{ 'type' => 'repository',
'name' => project.full_path,
@@ -161,10 +157,6 @@ end
RSpec.shared_examples 'a container registry auth service' do
include_context 'container registry auth service context'
- before do
- stub_feature_flags(container_registry_migration_phase1: false)
- end
-
describe '.full_access_token' do
let_it_be(:project) { create(:project) }
diff --git a/spec/support/shared_examples/services/incident_shared_examples.rb b/spec/support/shared_examples/services/incident_shared_examples.rb
index cc26cf87322..b533b095aac 100644
--- a/spec/support/shared_examples/services/incident_shared_examples.rb
+++ b/spec/support/shared_examples/services/incident_shared_examples.rb
@@ -70,7 +70,7 @@ RSpec.shared_examples 'incident management label service' do
expect(execute).to be_success
expect(execute.payload).to eq(label: label)
expect(label.title).to eq(title)
- expect(label.color).to eq(color)
+ expect(label.color).to be_color(color)
expect(label.description).to eq(description)
end
end
diff --git a/spec/support/shared_examples/services/issuable_links/create_links_shared_examples.rb b/spec/support/shared_examples/services/issuable_links/create_links_shared_examples.rb
new file mode 100644
index 00000000000..6146aae6b9b
--- /dev/null
+++ b/spec/support/shared_examples/services/issuable_links/create_links_shared_examples.rb
@@ -0,0 +1,133 @@
+# frozen_string_literal: true
+
+shared_examples 'issuable link creation' do
+ describe '#execute' do
+ subject { described_class.new(issuable, user, params).execute }
+
+ context 'when the reference list is empty' do
+ let(:params) do
+ { issuable_references: [] }
+ end
+
+ it 'returns error' do
+ is_expected.to eq(message: "No matching #{issuable_type} found. Make sure that you are adding a valid #{issuable_type} URL.", status: :error, http_status: 404)
+ end
+ end
+
+ context 'when Issuable not found' do
+ let(:params) do
+ { issuable_references: ["##{non_existing_record_iid}"] }
+ end
+
+ it 'returns error' do
+ is_expected.to eq(message: "No matching #{issuable_type} found. Make sure that you are adding a valid #{issuable_type} URL.", status: :error, http_status: 404)
+ end
+
+ it 'no relationship is created' do
+ expect { subject }.not_to change(issuable_link_class, :count)
+ end
+ end
+
+ context 'when user has no permission to target issuable' do
+ let(:params) do
+ { issuable_references: [guest_issuable.to_reference(issuable_parent)] }
+ end
+
+ it 'returns error' do
+ is_expected.to eq(message: "No matching #{issuable_type} found. Make sure that you are adding a valid #{issuable_type} URL.", status: :error, http_status: 404)
+ end
+
+ it 'no relationship is created' do
+ expect { subject }.not_to change(issuable_link_class, :count)
+ end
+ end
+
+ context 'source and target are the same issuable' do
+ let(:params) do
+ { issuable_references: [issuable.to_reference] }
+ end
+
+ it 'does not create notes' do
+ expect(SystemNoteService).not_to receive(:relate_issuable)
+
+ subject
+ end
+
+ it 'no relationship is created' do
+ expect { subject }.not_to change(issuable_link_class, :count)
+ end
+ end
+
+ context 'when there is an issuable to relate' do
+ let(:params) do
+ { issuable_references: [issuable2.to_reference, issuable3.to_reference(issuable_parent)] }
+ end
+
+ it 'creates relationships' do
+ expect { subject }.to change(issuable_link_class, :count).by(2)
+
+ expect(issuable_link_class.find_by!(target: issuable2)).to have_attributes(source: issuable, link_type: 'relates_to')
+ expect(issuable_link_class.find_by!(target: issuable3)).to have_attributes(source: issuable, link_type: 'relates_to')
+ end
+
+ it 'returns success status' do
+ is_expected.to eq(status: :success)
+ end
+
+ it 'creates notes' do
+ # First two-way relation notes
+ expect(SystemNoteService).to receive(:relate_issuable)
+ .with(issuable, issuable2, user)
+ expect(SystemNoteService).to receive(:relate_issuable)
+ .with(issuable2, issuable, user)
+
+ # Second two-way relation notes
+ expect(SystemNoteService).to receive(:relate_issuable)
+ .with(issuable, issuable3, user)
+ expect(SystemNoteService).to receive(:relate_issuable)
+ .with(issuable3, issuable, user)
+
+ subject
+ end
+ end
+
+ context 'when reference of any already related issue is present' do
+ let(:params) do
+ {
+ issuable_references: [
+ issuable_a.to_reference,
+ issuable_b.to_reference
+ ],
+ link_type: IssueLink::TYPE_RELATES_TO
+ }
+ end
+
+ it 'creates notes only for new relations' do
+ expect(SystemNoteService).to receive(:relate_issuable).with(issuable, issuable_a, anything)
+ expect(SystemNoteService).to receive(:relate_issuable).with(issuable_a, issuable, anything)
+ expect(SystemNoteService).not_to receive(:relate_issuable).with(issuable, issuable_b, anything)
+ expect(SystemNoteService).not_to receive(:relate_issuable).with(issuable_b, issuable, anything)
+
+ subject
+ end
+ end
+
+ context 'when there are invalid references' do
+ let(:params) do
+ { issuable_references: [issuable.to_reference, issuable_a.to_reference] }
+ end
+
+ it 'creates links only for valid references' do
+ expect { subject }.to change { issuable_link_class.count }.by(1)
+ end
+
+ it 'returns error status' do
+ expect(subject).to eq(
+ status: :error,
+ http_status: 422,
+ message: "#{issuable.to_reference} cannot be added: cannot be related to itself"
+ )
+ end
+ end
+ end
+end
diff --git a/spec/support/shared_examples/services/issuable_links/destroyable_issuable_links_shared_examples.rb b/spec/support/shared_examples/services/issuable_links/destroyable_issuable_links_shared_examples.rb
new file mode 100644
index 00000000000..53d637a9094
--- /dev/null
+++ b/spec/support/shared_examples/services/issuable_links/destroyable_issuable_links_shared_examples.rb
@@ -0,0 +1,42 @@
+# frozen_string_literal: true
+
+shared_examples 'a destroyable issuable link' do
+ context 'when successfully removes an issuable link' do
+ before do
+ issuable_link.source.resource_parent.add_reporter(user)
+ issuable_link.target.resource_parent.add_reporter(user)
+ end
+
+ it 'removes related issue' do
+ expect { subject }.to change(issuable_link.class, :count).by(-1)
+ end
+
+ it 'creates notes' do
+ # Two-way notes creation
+ expect(SystemNoteService).to receive(:unrelate_issuable)
+ .with(issuable_link.source, issuable_link.target, user)
+ expect(SystemNoteService).to receive(:unrelate_issuable)
+ .with(issuable_link.target, issuable_link.source, user)
+
+ subject
+ end
+
+ it 'returns success message' do
+ is_expected.to eq(message: 'Relation was removed', status: :success)
+ end
+ end
+
+ context 'when failing to remove an issuable link' do
+ it 'does not remove relation' do
+ expect { subject }.not_to change(issuable_link.class, :count).from(1)
+ end
+
+ it 'does not create notes' do
+ expect(SystemNoteService).not_to receive(:unrelate_issuable)
+ end
+
+ it 'returns error message' do
+ is_expected.to eq(message: "No #{issuable_link.class.model_name.human.titleize} found", status: :error, http_status: 404)
+ end
+ end
+end
diff --git a/spec/support/shared_examples/services/rate_limited_service_shared_examples.rb b/spec/support/shared_examples/services/rate_limited_service_shared_examples.rb
new file mode 100644
index 00000000000..b79f1a332a6
--- /dev/null
+++ b/spec/support/shared_examples/services/rate_limited_service_shared_examples.rb
@@ -0,0 +1,73 @@
+# frozen_string_literal: true
+
+# shared examples for testing rate limited functionality of a service
+#
+# following resources are expected to be set (example):
+# it_behaves_like 'rate limited service' do
+# let(:key) { :issues_create }
+# let(:key_scope) { %i[project current_user external_author] }
+# let(:application_limit_key) { :issues_create_limit }
+# let(:service) { described_class.new(project: project, current_user: user, params: { title: 'title' }, spam_params: double) }
+# let(:created_model) { Issue }
+# end
+
+RSpec.shared_examples 'rate limited service' do
+ describe '.rate_limiter_scoped_and_keyed' do
+ it 'is set via the rate_limit call' do
+ expect(described_class.rate_limiter_scoped_and_keyed).to be_a(RateLimitedService::RateLimiterScopedAndKeyed)
+
+ expect(described_class.rate_limiter_scoped_and_keyed.key).to eq(key)
+ expect(described_class.rate_limiter_scoped_and_keyed.opts[:scope]).to eq(key_scope)
+ expect(described_class.rate_limiter_scoped_and_keyed.rate_limiter).to eq(Gitlab::ApplicationRateLimiter)
+ end
+ end
+
+ describe '#rate_limiter_bypassed' do
+ it 'is nil by default' do
+ expect(service.rate_limiter_bypassed).to be_nil
+ end
+ end
+
+ describe '#execute' do
+ before do
+ stub_spam_services
+ end
+
+ context 'when rate limiting is in effect', :freeze_time, :clean_gitlab_redis_rate_limiting do
+ let(:user) { create(:user) }
+
+ before do
+ stub_application_setting(application_limit_key => 1)
+ end
+
+ subject do
+ 2.times { service.execute }
+ end
+
+ context 'when too many requests are sent by one user' do
+ it 'raises an error' do
+ expect do
+ subject
+ end.to raise_error(RateLimitedService::RateLimitedError)
+ end
+
+ it 'creates 1 issue' do
+ expect do
+ subject
+ rescue RateLimitedService::RateLimitedError
+ end.to change { created_model.count }.by(1)
+ end
+ end
+
+ context 'when limit is higher than count of issues being created' do
+ before do
+ stub_application_setting(issues_create_limit: 2)
+ end
+
+ it 'creates 2 issues' do
+ expect { subject }.to change { created_model.count }.by(2)
+ end
+ end
+ end
+ end
+end
diff --git a/spec/support/shared_examples/services/security/ci_configuration/create_service_shared_examples.rb b/spec/support/shared_examples/services/security/ci_configuration/create_service_shared_examples.rb
index 538fd2bb513..105c4247ff7 100644
--- a/spec/support/shared_examples/services/security/ci_configuration/create_service_shared_examples.rb
+++ b/spec/support/shared_examples/services/security/ci_configuration/create_service_shared_examples.rb
@@ -76,6 +76,18 @@ RSpec.shared_examples_for 'services security ci configuration create service' do
end
end
+ context 'when the project has a non-default ci config file' do
+ before do
+ project.ci_config_path = 'non-default/.gitlab-ci.yml'
+ end
+
+ it 'does track the snowplow event' do
+ subject
+
+ expect_snowplow_event(**snowplow_event)
+ end
+ end
+
unless skip_w_params
context 'with parameters' do
let(:params) { non_empty_params }
diff --git a/spec/support/shared_examples/workers/batched_background_migration_worker_shared_examples.rb b/spec/support/shared_examples/workers/batched_background_migration_worker_shared_examples.rb
new file mode 100644
index 00000000000..d202c4e00f0
--- /dev/null
+++ b/spec/support/shared_examples/workers/batched_background_migration_worker_shared_examples.rb
@@ -0,0 +1,198 @@
+# frozen_string_literal: true
+
+RSpec.shared_examples 'it runs batched background migration jobs' do |tracking_database|
+ include ExclusiveLeaseHelpers
+
+ describe 'defining the job attributes' do
+ it 'defines the data_consistency as always' do
+ expect(described_class.get_data_consistency).to eq(:always)
+ end
+
+ it 'defines the feature_category as database' do
+ expect(described_class.get_feature_category).to eq(:database)
+ end
+
+ it 'defines the idempotency as true' do
+ expect(described_class.idempotent?).to be_truthy
+ end
+ end
+
+ describe '.tracking_database' do
+ it 'does not raise an error' do
+ expect { described_class.tracking_database }.not_to raise_error
+ end
+
+ it 'overrides the method to return the tracking database' do
+ expect(described_class.tracking_database).to eq(tracking_database)
+ end
+ end
+
+ describe '.lease_key' do
+ let(:lease_key) { described_class.name.demodulize.underscore }
+
+ it 'does not raise an error' do
+ expect { described_class.lease_key }.not_to raise_error
+ end
+
+ it 'returns the lease key' do
+ expect(described_class.lease_key).to eq(lease_key)
+ end
+ end
+
+ describe '#perform' do
+ subject(:worker) { described_class.new }
+
+ context 'when the base model does not exist' do
+ before do
+ if Gitlab::Database.has_config?(tracking_database)
+ skip "because the base model for #{tracking_database} exists"
+ end
+ end
+
+ it 'does nothing' do
+ expect(worker).not_to receive(:active_migration)
+ expect(worker).not_to receive(:run_active_migration)
+
+ expect { worker.perform }.not_to raise_error
+ end
+
+ it 'logs a message indicating execution is skipped' do
+ expect(Sidekiq.logger).to receive(:info) do |payload|
+ expect(payload[:class]).to eq(described_class.name)
+ expect(payload[:database]).to eq(tracking_database)
+ expect(payload[:message]).to match(/skipping migration execution/)
+ end
+
+ expect { worker.perform }.not_to raise_error
+ end
+ end
+
+ context 'when the base model does exist' do
+ before do
+ unless Gitlab::Database.has_config?(tracking_database)
+ skip "because the base model for #{tracking_database} does not exist"
+ end
+ end
+
+ context 'when the feature flag is disabled' do
+ before do
+ stub_feature_flags(execute_batched_migrations_on_schedule: false)
+ end
+
+ it 'does nothing' do
+ expect(worker).not_to receive(:active_migration)
+ expect(worker).not_to receive(:run_active_migration)
+
+ worker.perform
+ end
+ end
+
+ context 'when the feature flag is enabled' do
+ before do
+ stub_feature_flags(execute_batched_migrations_on_schedule: true)
+
+ allow(Gitlab::Database::BackgroundMigration::BatchedMigration).to receive(:active_migration).and_return(nil)
+ end
+
+ context 'when no active migrations exist' do
+ it 'does nothing' do
+ expect(worker).not_to receive(:run_active_migration)
+
+ worker.perform
+ end
+ end
+
+ context 'when active migrations exist' do
+ let(:job_interval) { 5.minutes }
+ let(:lease_timeout) { 15.minutes }
+ let(:lease_key) { described_class.name.demodulize.underscore }
+ let(:migration) { build(:batched_background_migration, :active, interval: job_interval) }
+ let(:interval_variance) { described_class::INTERVAL_VARIANCE }
+
+ before do
+ allow(Gitlab::Database::BackgroundMigration::BatchedMigration).to receive(:active_migration)
+ .and_return(migration)
+
+ allow(migration).to receive(:interval_elapsed?).with(variance: interval_variance).and_return(true)
+ allow(migration).to receive(:reload)
+ end
+
+ context 'when the reloaded migration is no longer active' do
+ it 'does not run the migration' do
+ expect_to_obtain_exclusive_lease(lease_key, timeout: lease_timeout)
+
+ expect(migration).to receive(:reload)
+ expect(migration).to receive(:active?).and_return(false)
+
+ expect(worker).not_to receive(:run_active_migration)
+
+ worker.perform
+ end
+ end
+
+ context 'when the interval has not elapsed' do
+ it 'does not run the migration' do
+ expect_to_obtain_exclusive_lease(lease_key, timeout: lease_timeout)
+
+ expect(migration).to receive(:interval_elapsed?).with(variance: interval_variance).and_return(false)
+
+ expect(worker).not_to receive(:run_active_migration)
+
+ worker.perform
+ end
+ end
+
+ context 'when the reloaded migration is still active and the interval has elapsed' do
+ it 'runs the migration' do
+ expect_to_obtain_exclusive_lease(lease_key, timeout: lease_timeout)
+
+ expect_next_instance_of(Gitlab::Database::BackgroundMigration::BatchedMigrationRunner) do |instance|
+ expect(instance).to receive(:run_migration_job).with(migration)
+ end
+
+ expect(worker).to receive(:run_active_migration).and_call_original
+
+ worker.perform
+ end
+ end
+
+ context 'when the calculated timeout is less than the minimum allowed' do
+ let(:minimum_timeout) { described_class::MINIMUM_LEASE_TIMEOUT }
+ let(:job_interval) { 2.minutes }
+
+ it 'sets the lease timeout to the minimum value' do
+ expect_to_obtain_exclusive_lease(lease_key, timeout: minimum_timeout)
+
+ expect_next_instance_of(Gitlab::Database::BackgroundMigration::BatchedMigrationRunner) do |instance|
+ expect(instance).to receive(:run_migration_job).with(migration)
+ end
+
+ expect(worker).to receive(:run_active_migration).and_call_original
+
+ worker.perform
+ end
+ end
+
+ it 'always cleans up the exclusive lease' do
+ lease = stub_exclusive_lease_taken(lease_key, timeout: lease_timeout)
+
+ expect(lease).to receive(:try_obtain).and_return(true)
+
+ expect(worker).to receive(:run_active_migration).and_raise(RuntimeError, 'I broke')
+ expect(lease).to receive(:cancel)
+
+ expect { worker.perform }.to raise_error(RuntimeError, 'I broke')
+ end
+
+ it 'receives the correct connection' do
+ base_model = Gitlab::Database.database_base_models[tracking_database]
+
+ expect(Gitlab::Database::SharedModel).to receive(:using_connection).with(base_model.connection).and_yield
+
+ worker.perform
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/spec/support/shared_examples/workers/concerns/git_garbage_collect_methods_shared_examples.rb b/spec/support/shared_examples/workers/concerns/git_garbage_collect_methods_shared_examples.rb
index f2314793cb4..202606c6aa6 100644
--- a/spec/support/shared_examples/workers/concerns/git_garbage_collect_methods_shared_examples.rb
+++ b/spec/support/shared_examples/workers/concerns/git_garbage_collect_methods_shared_examples.rb
@@ -19,14 +19,28 @@ RSpec.shared_examples 'can collect git garbage' do |update_statistics: true|
end
shared_examples 'it calls Gitaly' do
- specify do
- repository_service = instance_double(Gitlab::GitalyClient::RepositoryService)
+ let(:repository_service) { instance_double(Gitlab::GitalyClient::RepositoryService) }
- expect(subject).to receive(:get_gitaly_client).with(task, repository.raw_repository).and_return(repository_service)
- expect(repository_service).to receive(gitaly_task)
+ specify do
+ expect_next_instance_of(Gitlab::GitalyClient::RepositoryService, repository.raw_repository) do |instance|
+ expect(instance).to receive(:optimize_repository).and_call_original
+ end
subject.perform(*params)
end
+
+ context 'when optimized_housekeeping feature is disabled' do
+ before do
+ stub_feature_flags(optimized_housekeeping: false)
+ end
+
+ specify do
+ expect(subject).to receive(:get_gitaly_client).with(task, repository.raw_repository).and_return(repository_service)
+ expect(repository_service).to receive(gitaly_task)
+
+ subject.perform(*params)
+ end
+ end
end
shared_examples 'it updates the resource statistics' do
@@ -70,12 +84,31 @@ RSpec.shared_examples 'can collect git garbage' do |update_statistics: true|
end
it 'handles gRPC errors' do
- allow_next_instance_of(Gitlab::GitalyClient::RepositoryService, repository.raw_repository) do |instance|
- allow(instance).to receive(:garbage_collect).and_raise(GRPC::NotFound)
+ repository_service = instance_double(Gitlab::GitalyClient::RepositoryService)
+
+ allow_next_instance_of(Projects::GitDeduplicationService) do |instance|
+ allow(instance).to receive(:execute)
end
+ allow(repository.raw_repository).to receive(:gitaly_repository_client).and_return(repository_service)
+ allow(repository_service).to receive(:optimize_repository).and_raise(GRPC::NotFound)
+
expect { subject.perform(*params) }.to raise_exception(Gitlab::Git::Repository::NoRepository)
end
+
+ context 'when optimized_housekeeping feature flag is disabled' do
+ before do
+ stub_feature_flags(optimized_housekeeping: false)
+ end
+
+ it 'handles gRPC errors' do
+ allow_next_instance_of(Gitlab::GitalyClient::RepositoryService, repository.raw_repository) do |instance|
+ allow(instance).to receive(:garbage_collect).and_raise(GRPC::NotFound)
+ end
+
+ expect { subject.perform(*params) }.to raise_exception(Gitlab::Git::Repository::NoRepository)
+ end
+ end
end
context 'with different lease than the active one' do
@@ -152,13 +185,8 @@ RSpec.shared_examples 'can collect git garbage' do |update_statistics: true|
expect(subject).to receive(:get_lease_uuid).and_return(lease_uuid)
end
- it 'calls Gitaly' do
- repository_service = instance_double(Gitlab::GitalyClient::RefService)
-
- expect(subject).to receive(:get_gitaly_client).with(task, repository.raw_repository).and_return(repository_service)
- expect(repository_service).to receive(gitaly_task)
-
- subject.perform(*params)
+ it_behaves_like 'it calls Gitaly' do
+ let(:repository_service) { instance_double(Gitlab::GitalyClient::RefService) }
end
it 'does not update the resource statistics' do
@@ -180,10 +208,26 @@ RSpec.shared_examples 'can collect git garbage' do |update_statistics: true|
it_behaves_like 'it updates the resource statistics' if update_statistics
end
+ context 'prune' do
+ before do
+ expect(subject).to receive(:get_lease_uuid).and_return(lease_uuid)
+ end
+
+ specify do
+ expect_next_instance_of(Gitlab::GitalyClient::RepositoryService, repository.raw_repository) do |instance|
+ expect(instance).to receive(:prune_unreachable_objects).and_call_original
+ end
+
+ subject.perform(resource.id, 'prune', lease_key, lease_uuid)
+ end
+ end
+
shared_examples 'gc tasks' do
before do
allow(subject).to receive(:get_lease_uuid).and_return(lease_uuid)
allow(subject).to receive(:bitmaps_enabled?).and_return(bitmaps_enabled)
+
+ stub_feature_flags(optimized_housekeeping: false)
end
it 'incremental repack adds a new packfile' do
diff --git a/spec/support/shared_examples/workers/concerns/reenqueuer_shared_examples.rb b/spec/support/shared_examples/workers/concerns/reenqueuer_shared_examples.rb
index d6e96ef37d6..d9105981b4b 100644
--- a/spec/support/shared_examples/workers/concerns/reenqueuer_shared_examples.rb
+++ b/spec/support/shared_examples/workers/concerns/reenqueuer_shared_examples.rb
@@ -30,18 +30,11 @@ end
# `job_args` to be arguments to #perform if it takes arguments
RSpec.shared_examples '#perform is rate limited to 1 call per' do |minimum_duration|
before do
- # Allow Timecop freeze and travel without the block form
- Timecop.safe_mode = false
- Timecop.freeze
+ freeze_time
time_travel_during_perform(actual_duration)
end
- after do
- Timecop.return
- Timecop.safe_mode = true
- end
-
let(:subject_perform) { defined?(job_args) ? subject.perform(job_args) : subject.perform }
context 'when the work finishes in 0 seconds' do
@@ -58,7 +51,7 @@ RSpec.shared_examples '#perform is rate limited to 1 call per' do |minimum_durat
let(:actual_duration) { 0.1 * minimum_duration }
it 'sleeps 90% of minimum duration' do
- expect(subject).to receive(:sleep).with(a_value_within(0.01).of(0.9 * minimum_duration))
+ expect(subject).to receive(:sleep).with(a_value_within(1).of(0.9 * minimum_duration))
subject_perform
end
@@ -68,7 +61,7 @@ RSpec.shared_examples '#perform is rate limited to 1 call per' do |minimum_durat
let(:actual_duration) { 0.9 * minimum_duration }
it 'sleeps 10% of minimum duration' do
- expect(subject).to receive(:sleep).with(a_value_within(0.01).of(0.1 * minimum_duration))
+ expect(subject).to receive(:sleep).with(a_value_within(1).of(0.1 * minimum_duration))
subject_perform
end
@@ -111,7 +104,7 @@ RSpec.shared_examples '#perform is rate limited to 1 call per' do |minimum_durat
allow(subject).to receive(:ensure_minimum_duration) do |minimum_duration, &block|
original_ensure_minimum_duration.call(minimum_duration) do
# Time travel inside the block inside ensure_minimum_duration
- Timecop.travel(actual_duration) if actual_duration && actual_duration > 0
+ travel_to(actual_duration.from_now) if actual_duration && actual_duration > 0
end
end
end
diff --git a/spec/support/silence_stdout.rb b/spec/support/silence_stdout.rb
new file mode 100644
index 00000000000..b2bc65c5cda
--- /dev/null
+++ b/spec/support/silence_stdout.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+RSpec.configure do |config|
+ # Allows stdout to be redirected to reduce noise
+ config.before(:each, :silence_stdout) do
+ $stdout = StringIO.new
+ end
+
+ config.after(:each, :silence_stdout) do
+ $stdout = STDOUT
+ end
+end
diff --git a/spec/support/view_component.rb b/spec/support/view_component.rb
new file mode 100644
index 00000000000..9166a06fc8c
--- /dev/null
+++ b/spec/support/view_component.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+require 'view_component/test_helpers'
+
+RSpec.configure do |config|
+ config.include ViewComponent::TestHelpers, type: :component
+ config.include Capybara::RSpecMatchers, type: :component
+end
diff --git a/spec/tasks/dev_rake_spec.rb b/spec/tasks/dev_rake_spec.rb
new file mode 100644
index 00000000000..7bc27d2732c
--- /dev/null
+++ b/spec/tasks/dev_rake_spec.rb
@@ -0,0 +1,38 @@
+# frozen_string_literal: true
+
+require 'rake_helper'
+
+RSpec.describe 'dev rake tasks' do
+ before do
+ Rake.application.rake_require 'tasks/gitlab/setup'
+ Rake.application.rake_require 'tasks/gitlab/shell'
+ Rake.application.rake_require 'tasks/dev'
+ end
+
+ describe 'setup' do
+ subject(:setup_task) { run_rake_task('dev:setup') }
+
+ let(:connections) { Gitlab::Database.database_base_models.values.map(&:connection) }
+
+ it 'sets up the development environment', :aggregate_failures do
+ expect(Rake::Task['gitlab:setup']).to receive(:invoke)
+
+ expect(connections).to all(receive(:execute).with('ANALYZE'))
+
+ expect(Rake::Task['gitlab:shell:setup']).to receive(:invoke)
+
+ setup_task
+ end
+ end
+
+ describe 'load' do
+ subject(:load_task) { run_rake_task('dev:load') }
+
+ it 'eager loads the application', :aggregate_failures do
+ expect(Rails.configuration).to receive(:eager_load=).with(true)
+ expect(Rails.application).to receive(:eager_load!)
+
+ load_task
+ end
+ end
+end
diff --git a/spec/tasks/gitlab/background_migrations_rake_spec.rb b/spec/tasks/gitlab/background_migrations_rake_spec.rb
index 079b4d3aea8..98920df71ee 100644
--- a/spec/tasks/gitlab/background_migrations_rake_spec.rb
+++ b/spec/tasks/gitlab/background_migrations_rake_spec.rb
@@ -10,6 +10,16 @@ RSpec.describe 'gitlab:background_migrations namespace rake tasks' do
describe 'finalize' do
subject(:finalize_task) { run_rake_task('gitlab:background_migrations:finalize', *arguments) }
+ let(:connection) { double(:connection) }
+ let(:main_model) { double(:model, connection: connection) }
+ let(:base_models) { { main: main_model } }
+ let(:databases) { [Gitlab::Database::MAIN_DATABASE_NAME] }
+
+ before do
+ allow(Gitlab::Database).to receive(:database_base_models).and_return(base_models)
+ allow(Gitlab::Database).to receive(:db_config_names).and_return(databases)
+ end
+
context 'without the proper arguments' do
let(:arguments) { %w[CopyColumnUsingBackgroundMigrationJob events id] }
@@ -26,24 +36,135 @@ RSpec.describe 'gitlab:background_migrations namespace rake tasks' do
it 'finalizes the matching migration' do
expect(Gitlab::Database::BackgroundMigration::BatchedMigrationRunner).to receive(:finalize)
- .with('CopyColumnUsingBackgroundMigrationJob', 'events', 'id', [%w[id1 id2]])
+ .with('CopyColumnUsingBackgroundMigrationJob', 'events', 'id', [%w[id1 id2]], connection: connection)
expect { finalize_task }.to output(/Done/).to_stdout
end
end
+
+ context 'when multiple database feature is enabled' do
+ subject(:finalize_task) { run_rake_task("gitlab:background_migrations:finalize:#{ci_database_name}", *arguments) }
+
+ let(:ci_database_name) { Gitlab::Database::CI_DATABASE_NAME }
+ let(:ci_model) { double(:model, connection: connection) }
+ let(:base_models) { { 'main' => main_model, 'ci' => ci_model } }
+ let(:databases) { [Gitlab::Database::MAIN_DATABASE_NAME, ci_database_name] }
+
+ before do
+ skip_if_multiple_databases_not_setup
+
+ allow(Gitlab::Database).to receive(:database_base_models).and_return(base_models)
+ end
+
+ it 'ignores geo' do
+ expect { run_rake_task('gitlab:background_migrations:finalize:geo}') }
+ .to raise_error(RuntimeError).with_message(/Don't know how to build task/)
+ end
+
+ context 'without the proper arguments' do
+ let(:arguments) { %w[CopyColumnUsingBackgroundMigrationJob events id] }
+
+ it 'exits without finalizing the migration' do
+ expect(Gitlab::Database::BackgroundMigration::BatchedMigrationRunner).not_to receive(:finalize)
+
+ expect { finalize_task }.to output(/Must specify job_arguments as an argument/).to_stdout
+ .and raise_error(SystemExit) { |error| expect(error.status).to eq(1) }
+ end
+ end
+
+ context 'with the proper arguments' do
+ let(:arguments) { %w[CopyColumnUsingBackgroundMigrationJob events id [["id1"\,"id2"]]] }
+
+ it 'finalizes the matching migration' do
+ expect(Gitlab::Database::BackgroundMigration::BatchedMigrationRunner).to receive(:finalize)
+ .with('CopyColumnUsingBackgroundMigrationJob', 'events', 'id', [%w[id1 id2]], connection: connection)
+
+ expect { finalize_task }.to output(/Done/).to_stdout
+ end
+ end
+
+ context 'when database name is not passed' do
+ it 'aborts the rake task' do
+ expect { run_rake_task('gitlab:background_migrations:finalize') }.to output(/Please specify the database/).to_stdout
+ .and raise_error(SystemExit) { |error| expect(error.status).to eq(1) }
+ end
+ end
+ end
end
describe 'status' do
subject(:status_task) { run_rake_task('gitlab:background_migrations:status') }
+ let(:migration1) { create(:batched_background_migration, :finished, job_arguments: [%w[id1 id2]]) }
+ let(:migration2) { create(:batched_background_migration, :failed, job_arguments: []) }
+
+ let(:main_database_name) { Gitlab::Database::MAIN_DATABASE_NAME }
+ let(:model) { Gitlab::Database.database_base_models[main_database_name] }
+ let(:connection) { double(:connection) }
+ let(:base_models) { { 'main' => model } }
+
+ around do |example|
+ Gitlab::Database::SharedModel.using_connection(model.connection) do
+ example.run
+ end
+ end
+
it 'outputs the status of background migrations' do
- migration1 = create(:batched_background_migration, :finished, job_arguments: [%w[id1 id2]])
- migration2 = create(:batched_background_migration, :failed, job_arguments: [])
+ allow(Gitlab::Database).to receive(:database_base_models).and_return(base_models)
expect { status_task }.to output(<<~OUTPUT).to_stdout
+ Database: #{main_database_name}
finished | #{migration1.job_class_name},#{migration1.table_name},#{migration1.column_name},[["id1","id2"]]
failed | #{migration2.job_class_name},#{migration2.table_name},#{migration2.column_name},[]
OUTPUT
end
+
+ context 'when multiple database feature is enabled' do
+ before do
+ skip_if_multiple_databases_not_setup
+ end
+
+ context 'with a single database' do
+ subject(:status_task) { run_rake_task("gitlab:background_migrations:status:#{main_database_name}") }
+
+ it 'outputs the status of background migrations' do
+ expect { status_task }.to output(<<~OUTPUT).to_stdout
+ Database: #{main_database_name}
+ finished | #{migration1.job_class_name},#{migration1.table_name},#{migration1.column_name},[["id1","id2"]]
+ failed | #{migration2.job_class_name},#{migration2.table_name},#{migration2.column_name},[]
+ OUTPUT
+ end
+
+ it 'ignores geo' do
+ expect { run_rake_task('gitlab:background_migrations:status:geo') }
+ .to raise_error(RuntimeError).with_message(/Don't know how to build task/)
+ end
+ end
+
+ context 'with multiple databases' do
+ subject(:status_task) { run_rake_task('gitlab:background_migrations:status') }
+
+ let(:base_models) { { 'main' => main_model, 'ci' => ci_model } }
+ let(:main_model) { double(:model, connection: connection) }
+ let(:ci_model) { double(:model, connection: connection) }
+
+ it 'outputs the status for each database' do
+ allow(Gitlab::Database).to receive(:database_base_models).and_return(base_models)
+
+ expect(Gitlab::Database::SharedModel).to receive(:using_connection).with(main_model.connection).and_yield
+ expect(Gitlab::Database::BackgroundMigration::BatchedMigration).to receive(:find_each).and_yield(migration1)
+
+ expect(Gitlab::Database::SharedModel).to receive(:using_connection).with(ci_model.connection).and_yield
+ expect(Gitlab::Database::BackgroundMigration::BatchedMigration).to receive(:find_each).and_yield(migration2)
+
+ expect { status_task }.to output(<<~OUTPUT).to_stdout
+ Database: main
+ finished | #{migration1.job_class_name},#{migration1.table_name},#{migration1.column_name},[["id1","id2"]]
+ Database: ci
+ failed | #{migration2.job_class_name},#{migration2.table_name},#{migration2.column_name},[]
+ OUTPUT
+ end
+ end
+ end
end
end
diff --git a/spec/tasks/gitlab/backup_rake_spec.rb b/spec/tasks/gitlab/backup_rake_spec.rb
index e9aa8cbb991..df9f2a0d3bb 100644
--- a/spec/tasks/gitlab/backup_rake_spec.rb
+++ b/spec/tasks/gitlab/backup_rake_spec.rb
@@ -72,7 +72,6 @@ RSpec.describe 'gitlab:app namespace rake task', :delete do
before do
allow(YAML).to receive(:load_file)
.and_return({ gitlab_version: gitlab_version })
- expect(Rake::Task['gitlab:db:drop_tables']).to receive(:invoke)
expect_next_instance_of(::Backup::Manager) do |instance|
backup_types.each do |subtask|
expect(instance).to receive(:run_restore_task).with(subtask).ordered
@@ -85,10 +84,6 @@ RSpec.describe 'gitlab:app namespace rake task', :delete do
it 'invokes restoration on match' do
expect { run_rake_task('gitlab:backup:restore') }.to output.to_stdout_from_any_process
end
-
- it 'prints timestamps on messages' do
- expect { run_rake_task('gitlab:backup:restore') }.to output(/.*\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2}\s[-+]\d{4}\s--\s.*/).to_stdout_from_any_process
- end
end
end
@@ -131,8 +126,6 @@ RSpec.describe 'gitlab:app namespace rake task', :delete do
allow(YAML).to receive(:load_file)
.and_return({ gitlab_version: Gitlab::VERSION })
- expect(Rake::Task['gitlab:db:drop_tables']).to receive(:invoke)
-
expect_next_instance_of(::Backup::Manager) do |instance|
backup_types.each do |subtask|
expect(instance).to receive(:run_restore_task).with(subtask).ordered
@@ -183,8 +176,8 @@ RSpec.describe 'gitlab:app namespace rake task', :delete do
expect(exit_status).to eq(0)
expect(tar_contents).to match(user_backup_path)
- expect(tar_contents).to match("#{user_backup_path}/custom_hooks.tar")
- expect(tar_contents).to match("#{user_backup_path}.bundle")
+ expect(tar_contents).to match("#{user_backup_path}/.+/001.custom_hooks.tar")
+ expect(tar_contents).to match("#{user_backup_path}/.+/001.bundle")
end
it 'restores files correctly' do
@@ -367,14 +360,14 @@ RSpec.describe 'gitlab:app namespace rake task', :delete do
expect(exit_status).to eq(0)
[
- "#{project_a.disk_path}.bundle",
- "#{project_a.disk_path}.wiki.bundle",
- "#{project_a.disk_path}.design.bundle",
- "#{project_b.disk_path}.bundle",
- "#{project_snippet_a.disk_path}.bundle",
- "#{project_snippet_b.disk_path}.bundle"
+ "#{project_a.disk_path}/.+/001.bundle",
+ "#{project_a.disk_path}.wiki/.+/001.bundle",
+ "#{project_a.disk_path}.design/.+/001.bundle",
+ "#{project_b.disk_path}/.+/001.bundle",
+ "#{project_snippet_a.disk_path}/.+/001.bundle",
+ "#{project_snippet_b.disk_path}/.+/001.bundle"
].each do |repo_name|
- expect(tar_lines.grep(/#{repo_name}/).size).to eq 1
+ expect(tar_lines).to include(a_string_matching(repo_name))
end
end
@@ -435,7 +428,7 @@ RSpec.describe 'gitlab:app namespace rake task', :delete do
expect(::Backup::Repositories).to receive(:new)
.with(anything, strategy: anything, max_concurrency: 5, max_storage_concurrency: 2)
.and_call_original
- expect(::Backup::GitalyBackup).to receive(:new).with(anything, max_parallelism: 5, storage_parallelism: 2).and_call_original
+ expect(::Backup::GitalyBackup).to receive(:new).with(anything, max_parallelism: 5, storage_parallelism: 2, incremental: false).and_call_original
expect { run_rake_task('gitlab:backup:create') }.to output.to_stdout_from_any_process
end
@@ -486,7 +479,6 @@ RSpec.describe 'gitlab:app namespace rake task', :delete do
allow(Rake::Task['gitlab:shell:setup'])
.to receive(:invoke).and_return(true)
- expect(Rake::Task['gitlab:db:drop_tables']).to receive :invoke
expect_next_instance_of(::Backup::Manager) do |instance|
(backup_types - %w{repositories uploads}).each do |subtask|
expect(instance).to receive(:run_restore_task).with(subtask).ordered
@@ -531,7 +523,6 @@ RSpec.describe 'gitlab:app namespace rake task', :delete do
allow(Rake::Task['gitlab:shell:setup'])
.to receive(:invoke).and_return(true)
- expect(Rake::Task['gitlab:db:drop_tables']).to receive :invoke
expect_next_instance_of(::Backup::Manager) do |instance|
backup_types.each do |subtask|
expect(instance).to receive(:run_restore_task).with(subtask).ordered
diff --git a/spec/tasks/gitlab/db_rake_spec.rb b/spec/tasks/gitlab/db_rake_spec.rb
index c3fd8135ae0..8d3ec7b1ee2 100644
--- a/spec/tasks/gitlab/db_rake_spec.rb
+++ b/spec/tasks/gitlab/db_rake_spec.rb
@@ -20,6 +20,14 @@ RSpec.describe 'gitlab:db namespace rake task', :silence_stdout do
allow(Rake::Task['db:seed_fu']).to receive(:invoke).and_return(true)
end
+ describe 'clear_all_connections' do
+ it 'calls clear_all_connections!' do
+ expect(ActiveRecord::Base).to receive(:clear_all_connections!)
+
+ run_rake_task('gitlab:db:clear_all_connections')
+ end
+ end
+
describe 'mark_migration_complete' do
context 'with a single database' do
let(:main_model) { ActiveRecord::Base }
@@ -253,45 +261,78 @@ RSpec.describe 'gitlab:db namespace rake task', :silence_stdout do
end
describe 'drop_tables' do
- subject { run_rake_task('gitlab:db:drop_tables') }
-
- let(:tables) { %w(one two) }
+ let(:tables) { %w(one two schema_migrations) }
let(:views) { %w(three four) }
- let(:connection) { ActiveRecord::Base.connection }
+ let(:schemas) { Gitlab::Database::EXTRA_SCHEMAS }
- before do
- allow(connection).to receive(:execute).and_return(nil)
+ context 'with a single database' do
+ let(:connection) { ActiveRecord::Base.connection }
+
+ before do
+ skip_if_multiple_databases_are_setup
+
+ allow(connection).to receive(:execute).and_return(nil)
+
+ allow(connection).to receive(:tables).and_return(tables)
+ allow(connection).to receive(:views).and_return(views)
+ end
+
+ it 'drops all objects for the database', :aggregate_failures do
+ expect_objects_to_be_dropped(connection)
- allow(connection).to receive(:tables).and_return(tables)
- allow(connection).to receive(:views).and_return(views)
+ run_rake_task('gitlab:db:drop_tables')
+ end
end
- it 'drops all tables, except schema_migrations' do
- expect(connection).to receive(:execute).with('DROP TABLE IF EXISTS "one" CASCADE')
- expect(connection).to receive(:execute).with('DROP TABLE IF EXISTS "two" CASCADE')
+ context 'with multiple databases', :aggregate_failures do
+ let(:main_model) { double(:model, connection: double(:connection, tables: tables, views: views)) }
+ let(:ci_model) { double(:model, connection: double(:connection, tables: tables, views: views)) }
+ let(:base_models) { { 'main' => main_model, 'ci' => ci_model } }
- subject
+ before do
+ skip_if_multiple_databases_not_setup
+
+ allow(Gitlab::Database).to receive(:database_base_models).and_return(base_models)
+
+ allow(main_model.connection).to receive(:table_exists?).with('schema_migrations').and_return(true)
+ allow(ci_model.connection).to receive(:table_exists?).with('schema_migrations').and_return(true)
+
+ (tables + views + schemas).each do |name|
+ allow(main_model.connection).to receive(:quote_table_name).with(name).and_return("\"#{name}\"")
+ allow(ci_model.connection).to receive(:quote_table_name).with(name).and_return("\"#{name}\"")
+ end
+ end
+
+ it 'drops all objects for all databases', :aggregate_failures do
+ expect_objects_to_be_dropped(main_model.connection)
+ expect_objects_to_be_dropped(ci_model.connection)
+
+ run_rake_task('gitlab:db:drop_tables')
+ end
+
+ context 'when the single database task is used' do
+ it 'drops all objects for the given database', :aggregate_failures do
+ expect_objects_to_be_dropped(main_model.connection)
+
+ expect(ci_model.connection).not_to receive(:execute)
+
+ run_rake_task('gitlab:db:drop_tables:main')
+ end
+ end
end
- it 'drops all views' do
+ def expect_objects_to_be_dropped(connection)
+ expect(connection).to receive(:execute).with('DROP TABLE IF EXISTS "one" CASCADE')
+ expect(connection).to receive(:execute).with('DROP TABLE IF EXISTS "two" CASCADE')
+
expect(connection).to receive(:execute).with('DROP VIEW IF EXISTS "three" CASCADE')
expect(connection).to receive(:execute).with('DROP VIEW IF EXISTS "four" CASCADE')
- subject
- end
-
- it 'truncates schema_migrations table' do
expect(connection).to receive(:execute).with('TRUNCATE schema_migrations')
- subject
- end
-
- it 'drops extra schemas' do
Gitlab::Database::EXTRA_SCHEMAS.each do |schema|
expect(connection).to receive(:execute).with("DROP SCHEMA IF EXISTS \"#{schema}\" CASCADE")
end
-
- subject
end
end
@@ -422,13 +463,11 @@ RSpec.describe 'gitlab:db namespace rake task', :silence_stdout do
context 'with multiple databases', :reestablished_active_record_base do
before do
- allow(ActiveRecord::Tasks::DatabaseTasks).to receive(:setup_initial_database_yaml).and_return([:main, :geo])
+ skip_if_multiple_databases_not_setup
end
describe 'db:structure:dump' do
it 'invokes gitlab:db:clean_structure_sql' do
- skip unless Gitlab.ee?
-
expect(Rake::Task['gitlab:db:clean_structure_sql']).to receive(:invoke).twice.and_return(true)
expect { run_rake_task('db:structure:dump:main') }.not_to raise_error
@@ -437,13 +476,33 @@ RSpec.describe 'gitlab:db namespace rake task', :silence_stdout do
describe 'db:schema:dump' do
it 'invokes gitlab:db:clean_structure_sql' do
- skip unless Gitlab.ee?
-
expect(Rake::Task['gitlab:db:clean_structure_sql']).to receive(:invoke).once.and_return(true)
expect { run_rake_task('db:schema:dump:main') }.not_to raise_error
end
end
+
+ describe 'db:migrate' do
+ it 'invokes gitlab:db:create_dynamic_partitions' do
+ expect(Rake::Task['gitlab:db:create_dynamic_partitions']).to receive(:invoke).once.and_return(true)
+
+ expect { run_rake_task('db:migrate:main') }.not_to raise_error
+ end
+ end
+
+ describe 'db:migrate:geo' do
+ it 'does not invoke gitlab:db:create_dynamic_partitions' do
+ skip 'Skipping because geo database is not setup' unless geo_configured?
+
+ expect(Rake::Task['gitlab:db:create_dynamic_partitions']).not_to receive(:invoke)
+
+ expect { run_rake_task('db:migrate:geo') }.not_to raise_error
+ end
+
+ def geo_configured?
+ !!ActiveRecord::Base.configurations.configs_for(env_name: Rails.env, name: 'geo')
+ end
+ end
end
describe 'gitlab:db:reset_as_non_superuser' do
diff --git a/spec/tasks/gitlab/refresh_project_statistics_build_artifacts_size_rake_spec.rb b/spec/tasks/gitlab/refresh_project_statistics_build_artifacts_size_rake_spec.rb
new file mode 100644
index 00000000000..e57704d0ebe
--- /dev/null
+++ b/spec/tasks/gitlab/refresh_project_statistics_build_artifacts_size_rake_spec.rb
@@ -0,0 +1,48 @@
+# frozen_string_literal: true
+
+require 'rake_helper'
+
+RSpec.describe 'gitlab:refresh_project_statistics_build_artifacts_size rake task', :silence_stdout do
+ let(:rake_task) { 'gitlab:refresh_project_statistics_build_artifacts_size' }
+
+ describe 'enqueuing build artifacts size statistics refresh for given list of project IDs' do
+ let_it_be(:project_1) { create(:project) }
+ let_it_be(:project_2) { create(:project) }
+ let_it_be(:project_3) { create(:project) }
+
+ let(:string_of_ids) { "#{project_1.id} #{project_2.id} #{project_3.id} 999999" }
+
+ before do
+ Rake.application.rake_require('tasks/gitlab/refresh_project_statistics_build_artifacts_size')
+
+ stub_const("BUILD_ARTIFACTS_SIZE_REFRESH_ENQUEUE_BATCH_SIZE", 2)
+ end
+
+ context 'when given a list of space-separated IDs through STDIN' do
+ before do
+ allow($stdin).to receive(:tty?).and_return(false)
+ allow($stdin).to receive(:read).and_return(string_of_ids)
+ end
+
+ it 'enqueues the projects for refresh' do
+ expect { run_rake_task(rake_task) }.to output(/Done/).to_stdout
+
+ expect(Projects::BuildArtifactsSizeRefresh.all.map(&:project)).to match_array([project_1, project_2, project_3])
+ end
+ end
+
+ context 'when given a list of space-separated IDs through rake argument' do
+ it 'enqueues the projects for refresh' do
+ expect { run_rake_task(rake_task, string_of_ids) }.to output(/Done/).to_stdout
+
+ expect(Projects::BuildArtifactsSizeRefresh.all.map(&:project)).to match_array([project_1, project_2, project_3])
+ end
+ end
+
+ context 'when not given any IDs' do
+ it 'returns an error message' do
+ expect { run_rake_task(rake_task) }.to output(/Please provide a string of space-separated project IDs/).to_stdout
+ end
+ end
+ end
+end
diff --git a/spec/tasks/gitlab/setup_rake_spec.rb b/spec/tasks/gitlab/setup_rake_spec.rb
new file mode 100644
index 00000000000..6e4d5087517
--- /dev/null
+++ b/spec/tasks/gitlab/setup_rake_spec.rb
@@ -0,0 +1,141 @@
+# frozen_string_literal: true
+
+require 'rake_helper'
+
+RSpec.describe 'gitlab:setup namespace rake tasks', :silence_stdout do
+ before do
+ Rake.application.rake_require 'active_record/railties/databases'
+ Rake.application.rake_require 'tasks/seed_fu'
+ Rake.application.rake_require 'tasks/gitlab/setup'
+ end
+
+ describe 'setup' do
+ subject(:setup_task) { run_rake_task('gitlab:setup') }
+
+ let(:storages) do
+ {
+ 'name1' => 'some details',
+ 'name2' => 'other details'
+ }
+ end
+
+ let(:server_service1) { double(:server_service) }
+ let(:server_service2) { double(:server_service) }
+
+ let(:connections) { Gitlab::Database.database_base_models.values.map(&:connection) }
+
+ before do
+ allow(Gitlab).to receive_message_chain('config.repositories.storages').and_return(storages)
+
+ stub_warn_user_is_not_gitlab
+
+ allow(main_object).to receive(:ask_to_continue)
+ end
+
+ it 'sets up the application', :aggregate_failures do
+ expect_gitaly_connections_to_be_checked
+
+ expect_connections_to_be_terminated
+ expect_database_to_be_setup
+
+ setup_task
+ end
+
+ context 'when an environment variable is set to force execution' do
+ before do
+ stub_env('force', 'yes')
+ end
+
+ it 'sets up the application without prompting the user', :aggregate_failures do
+ expect_gitaly_connections_to_be_checked
+
+ expect(main_object).not_to receive(:ask_to_continue)
+
+ expect_connections_to_be_terminated
+ expect_database_to_be_setup
+
+ setup_task
+ end
+ end
+
+ context 'when the gitaly connection check raises an error' do
+ it 'exits the task without setting up the database', :aggregate_failures do
+ expect(Gitlab::GitalyClient::ServerService).to receive(:new).with('name1').and_return(server_service1)
+ expect(server_service1).to receive(:info).and_raise(GRPC::Unavailable)
+
+ expect_connections_not_to_be_terminated
+ expect_database_not_to_be_setup
+
+ expect { setup_task }.to output(/Failed to connect to Gitaly/).to_stdout
+ .and raise_error(SystemExit) { |error| expect(error.status).to eq(1) }
+ end
+ end
+
+ context 'when the task is aborted' do
+ it 'exits without setting up the database', :aggregate_failures do
+ expect_gitaly_connections_to_be_checked
+
+ expect(main_object).to receive(:ask_to_continue).and_raise(Gitlab::TaskAbortedByUserError)
+
+ expect_connections_not_to_be_terminated
+ expect_database_not_to_be_setup
+
+ expect { setup_task }.to output(/Quitting/).to_stdout
+ .and raise_error(SystemExit) { |error| expect(error.status).to eq(1) }
+ end
+ end
+
+ context 'when in the production environment' do
+ it 'sets up the database without terminating connections', :aggregate_failures do
+ expect_gitaly_connections_to_be_checked
+
+ expect(Rails.env).to receive(:production?).and_return(true)
+
+ expect_connections_not_to_be_terminated
+ expect_database_to_be_setup
+
+ setup_task
+ end
+ end
+
+ context 'when the database is not found when terminating connections' do
+ it 'continues setting up the database', :aggregate_failures do
+ expect_gitaly_connections_to_be_checked
+
+ expect(connections).to all(receive(:execute).and_raise(ActiveRecord::NoDatabaseError))
+
+ expect_database_to_be_setup
+
+ setup_task
+ end
+ end
+
+ def expect_gitaly_connections_to_be_checked
+ expect(Gitlab::GitalyClient::ServerService).to receive(:new).with('name1').and_return(server_service1)
+ expect(server_service1).to receive(:info)
+
+ expect(Gitlab::GitalyClient::ServerService).to receive(:new).with('name2').and_return(server_service2)
+ expect(server_service2).to receive(:info)
+ end
+
+ def expect_connections_to_be_terminated
+ expect(connections).to all(receive(:execute).with(/SELECT pg_terminate_backend/))
+ end
+
+ def expect_connections_not_to_be_terminated
+ connections.each do |connection|
+ expect(connection).not_to receive(:execute)
+ end
+ end
+
+ def expect_database_to_be_setup
+ expect(Rake::Task['db:reset']).to receive(:invoke)
+ expect(Rake::Task['db:seed_fu']).to receive(:invoke)
+ end
+
+ def expect_database_not_to_be_setup
+ expect(Rake::Task['db:reset']).not_to receive(:invoke)
+ expect(Rake::Task['db:seed_fu']).not_to receive(:invoke)
+ end
+ end
+end
diff --git a/spec/tasks/rubocop_rake_spec.rb b/spec/tasks/rubocop_rake_spec.rb
new file mode 100644
index 00000000000..cf7e45aae28
--- /dev/null
+++ b/spec/tasks/rubocop_rake_spec.rb
@@ -0,0 +1,168 @@
+# frozen_string_literal: true
+# rubocop:disable RSpec/VerifiedDoubles
+
+require 'fast_spec_helper'
+require 'rake'
+require 'fileutils'
+
+require_relative '../support/silence_stdout'
+require_relative '../support/helpers/next_instance_of'
+require_relative '../support/helpers/rake_helpers'
+require_relative '../../rubocop/todo_dir'
+
+RSpec.describe 'rubocop rake tasks', :silence_stdout do
+ include RakeHelpers
+
+ before do
+ stub_const('Rails', double(:rails_env))
+ allow(Rails).to receive(:env).and_return(double(production?: false))
+
+ stub_const('ENV', ENV.to_hash.dup)
+
+ Rake.application.rake_require 'tasks/rubocop'
+ end
+
+ describe 'todo:generate', :aggregate_failures do
+ let(:tmp_dir) { Dir.mktmpdir }
+ let(:rubocop_todo_dir) { File.join(tmp_dir, '.rubocop_todo') }
+ let(:todo_dir) { RuboCop::TodoDir.new(rubocop_todo_dir) }
+
+ around do |example|
+ Dir.chdir(tmp_dir) do
+ with_inflections do
+ example.run
+ end
+ end
+ end
+
+ before do
+ allow(RuboCop::TodoDir).to receive(:new).and_return(todo_dir)
+
+ # This Ruby file will trigger the following 3 offenses.
+ File.write('a.rb', <<~RUBY)
+ a+b
+
+ RUBY
+
+ # Mimic GitLab's .rubocop_todo.yml avoids relying on RuboCop's
+ # default.yml configuration.
+ File.write('.rubocop.yml', <<~YAML)
+ <% unless ENV['REVEAL_RUBOCOP_TODO'] == '1' %>
+ <% Dir.glob('.rubocop_todo/**/*.yml').each do |rubocop_todo_yaml| %>
+ - '<%= rubocop_todo_yaml %>'
+ <% end %>
+ - '.rubocop_todo.yml'
+ <% end %>
+
+ AllCops:
+ NewCops: enable # Avoiding RuboCop warnings
+
+ Layout/SpaceAroundOperators:
+ Enabled: true
+
+ Layout/TrailingEmptyLines:
+ Enabled: true
+
+ Lint/Syntax:
+ Enabled: true
+
+ Style/FrozenStringLiteralComment:
+ Enabled: true
+ YAML
+
+ # Required to verify that we are revealing all TODOs via
+ # ENV['REVEAL_RUBOCOP_TODO'] = '1'.
+ # This file can be removed from specs after we've moved all offenses from
+ # .rubocop_todo.yml to .rubocop_todo/**/*.yml.
+ File.write('.rubocop_todo.yml', <<~YAML)
+ # Too many offenses
+ Layout/SpaceAroundOperators:
+ Enabled: false
+ YAML
+
+ # Previous offense now fixed.
+ todo_dir.write('Lint/Syntax', '')
+ end
+
+ after do
+ FileUtils.remove_entry(tmp_dir)
+ end
+
+ context 'without arguments' do
+ let(:run_task) { run_rake_task('rubocop:todo:generate') }
+
+ it 'generates TODOs for all RuboCop rules' do
+ expect { run_task }.to output(<<~OUTPUT).to_stdout
+ Generating RuboCop TODOs with:
+ rubocop --parallel --format RuboCop::Formatter::TodoFormatter
+
+ This might take a while...
+ Written to .rubocop_todo/layout/space_around_operators.yml
+ Written to .rubocop_todo/layout/trailing_empty_lines.yml
+ Written to .rubocop_todo/style/frozen_string_literal_comment.yml
+ OUTPUT
+
+ expect(rubocop_todo_dir_listing).to contain_exactly(
+ 'layout/space_around_operators.yml',
+ 'layout/trailing_empty_lines.yml',
+ 'style/frozen_string_literal_comment.yml'
+ )
+ end
+
+ it 'sets acronyms for inflections' do
+ run_task
+
+ expect(ActiveSupport::Inflector.inflections.acronyms).to include(
+ 'rspec' => 'RSpec',
+ 'graphql' => 'GraphQL'
+ )
+ end
+ end
+
+ context 'with cop names as arguments' do
+ let(:run_task) do
+ cop_names = %w[
+ Style/FrozenStringLiteralComment Layout/TrailingEmptyLines
+ Lint/Syntax
+ ]
+
+ run_rake_task('rubocop:todo:generate', cop_names)
+ end
+
+ it 'generates TODOs for given RuboCop cops' do
+ expect { run_task }.to output(<<~OUTPUT).to_stdout
+ Generating RuboCop TODOs with:
+ rubocop --parallel --format RuboCop::Formatter::TodoFormatter --only Layout/TrailingEmptyLines,Lint/Syntax,Style/FrozenStringLiteralComment
+
+ This might take a while...
+ Written to .rubocop_todo/layout/trailing_empty_lines.yml
+ Written to .rubocop_todo/style/frozen_string_literal_comment.yml
+ OUTPUT
+
+ expect(rubocop_todo_dir_listing).to contain_exactly(
+ 'layout/trailing_empty_lines.yml',
+ 'style/frozen_string_literal_comment.yml'
+ )
+ end
+ end
+
+ private
+
+ def rubocop_todo_dir_listing
+ Dir.glob("#{rubocop_todo_dir}/**/*")
+ .select { |path| File.file?(path) }
+ .map { |path| path.delete_prefix("#{rubocop_todo_dir}/") }
+ end
+
+ def with_inflections
+ original = ActiveSupport::Inflector::Inflections.instance_variable_get(:@__instance__)[:en]
+ ActiveSupport::Inflector::Inflections.instance_variable_set(:@__instance__, en: original.dup)
+
+ yield
+ ensure
+ ActiveSupport::Inflector::Inflections.instance_variable_set(:@__instance__, en: original)
+ end
+ end
+end
+
+# rubocop:enable RSpec/VerifiedDoubles
diff --git a/spec/tooling/danger/changelog_spec.rb b/spec/tooling/danger/changelog_spec.rb
deleted file mode 100644
index 377c3e881c9..00000000000
--- a/spec/tooling/danger/changelog_spec.rb
+++ /dev/null
@@ -1,467 +0,0 @@
-# frozen_string_literal: true
-
-require 'gitlab-dangerfiles'
-require 'gitlab/dangerfiles/spec_helper'
-
-require_relative '../../../tooling/danger/changelog'
-require_relative '../../../tooling/danger/project_helper'
-
-RSpec.describe Tooling::Danger::Changelog do
- include_context "with dangerfile"
-
- let(:fake_danger) { DangerSpecHelper.fake_danger.include(described_class) }
- let(:fake_project_helper) { double('fake-project-helper', helper: fake_helper).tap { |h| h.class.include(Tooling::Danger::ProjectHelper) } }
-
- subject(:changelog) { fake_danger.new(helper: fake_helper) }
-
- before do
- allow(changelog).to receive(:project_helper).and_return(fake_project_helper)
- end
-
- describe '#check_changelog_commit_categories' do
- context 'when all changelog commits are correct' do
- it 'does not produce any messages' do
- commit = double(:commit, message: "foo\nChangelog: fixed")
-
- allow(changelog).to receive(:changelog_commits).and_return([commit])
-
- expect(changelog).not_to receive(:fail)
-
- changelog.check_changelog_commit_categories
- end
- end
-
- context 'when a commit has an incorrect trailer' do
- it 'adds a message' do
- commit = double(:commit, message: "foo\nChangelog: foo", sha: '123')
-
- allow(changelog).to receive(:changelog_commits).and_return([commit])
-
- expect(changelog).to receive(:fail)
-
- changelog.check_changelog_commit_categories
- end
- end
- end
-
- describe '#check_changelog_trailer' do
- subject { changelog.check_changelog_trailer(commit) }
-
- context "when commit include a changelog trailer with an unknown category" do
- let(:commit) { double('commit', message: "Hello world\n\nChangelog: foo", sha: "abc123") }
-
- it { is_expected.to have_attributes(errors: ["Commit #{commit.sha} uses an invalid changelog category: foo"]) }
- end
-
- context 'when a commit uses the wrong casing for a trailer' do
- let(:commit) { double('commit', message: "Hello world\n\nchangelog: foo", sha: "abc123") }
-
- it { is_expected.to have_attributes(errors: ["The changelog trailer for commit #{commit.sha} must be `Changelog` (starting with a capital C), not `changelog`"]) }
- end
-
- described_class::CATEGORIES.each do |category|
- context "when commit include a changelog trailer with category set to '#{category}'" do
- let(:commit) { double('commit', message: "Hello world\n\nChangelog: #{category}", sha: "abc123") }
-
- it { is_expected.to have_attributes(errors: []) }
- end
- end
- end
-
- describe '#check_changelog_path' do
- let(:changelog_path) { 'changelog-path.yml' }
- let(:foss_change) { nil }
- let(:ee_change) { nil }
- let(:changelog_change) { nil }
- let(:changes) { changes_class.new([foss_change, ee_change, changelog_change].compact) }
-
- before do
- allow(changelog).to receive(:present?).and_return(true)
- end
-
- subject { changelog.check_changelog_path }
-
- context "when changelog is not present" do
- before do
- allow(changelog).to receive(:present?).and_return(false)
- end
-
- it { is_expected.to have_attributes(errors: [], warnings: [], markdowns: [], messages: []) }
- end
-
- context "with EE changes" do
- let(:ee_change) { change_class.new('ee/app/models/foo.rb', :added, :backend) }
-
- context "and a non-EE changelog, and changelog not required" do
- before do
- allow(changelog).to receive(:required?).and_return(false)
- allow(changelog).to receive(:ee_changelog?).and_return(false)
- end
-
- it { is_expected.to have_attributes(warnings: ["This MR changes code in `ee/`, but its Changelog commit is missing the [`EE: true` trailer](https://docs.gitlab.com/ee/development/changelog.html#gitlab-enterprise-changes). Consider adding it to your Changelog commits."]) }
- end
-
- context "and a EE changelog" do
- before do
- allow(changelog).to receive(:ee_changelog?).and_return(true)
- end
-
- it { is_expected.to have_attributes(errors: [], warnings: [], markdowns: [], messages: []) }
-
- context "and there are DB changes" do
- let(:foss_change) { change_class.new('db/migrate/foo.rb', :added, :migration) }
-
- it { is_expected.to have_attributes(warnings: ["This MR has a Changelog commit with the `EE: true` trailer, but there are database changes which [requires](https://docs.gitlab.com/ee/development/changelog.html#what-warrants-a-changelog-entry) the Changelog commit to not have the `EE: true` trailer. Consider removing the `EE: true` trailer from your commits."]) }
- end
- end
- end
-
- context "with no EE changes" do
- let(:foss_change) { change_class.new('app/models/foo.rb', :added, :backend) }
-
- context "and a non-EE changelog" do
- before do
- allow(changelog).to receive(:ee_changelog?).and_return(false)
- end
-
- it { is_expected.to have_attributes(errors: [], warnings: [], markdowns: [], messages: []) }
- end
-
- context "and a EE changelog" do
- before do
- allow(changelog).to receive(:ee_changelog?).and_return(true)
- end
-
- it { is_expected.to have_attributes(warnings: ["This MR has a Changelog commit for EE, but no code changes in `ee/`. Consider removing the `EE: true` trailer from your commits."]) }
- end
- end
- end
-
- describe '#required_reasons' do
- subject { changelog.required_reasons }
-
- context "added files contain a migration" do
- let(:changes) { changes_class.new([change_class.new('foo', :added, :migration)]) }
-
- it { is_expected.to include(:db_changes) }
- end
-
- context "removed files contains a feature flag" do
- let(:changes) { changes_class.new([change_class.new('foo', :deleted, :feature_flag)]) }
-
- it { is_expected.to include(:feature_flag_removed) }
- end
-
- context "added files do not contain a migration" do
- let(:changes) { changes_class.new([change_class.new('foo', :added, :frontend)]) }
-
- it { is_expected.to be_empty }
- end
-
- context "removed files do not contain a feature flag" do
- let(:changes) { changes_class.new([change_class.new('foo', :deleted, :backend)]) }
-
- it { is_expected.to be_empty }
- end
- end
-
- describe '#required?' do
- subject { changelog.required? }
-
- context 'added files contain a migration' do
- let(:changes) { changes_class.new([change_class.new('foo', :added, :migration)]) }
-
- it { is_expected.to be_truthy }
- end
-
- context "removed files contains a feature flag" do
- let(:changes) { changes_class.new([change_class.new('foo', :deleted, :feature_flag)]) }
-
- it { is_expected.to be_truthy }
- end
-
- context 'added files do not contain a migration' do
- let(:changes) { changes_class.new([change_class.new('foo', :added, :frontend)]) }
-
- it { is_expected.to be_falsey }
- end
-
- context "removed files do not contain a feature flag" do
- let(:changes) { changes_class.new([change_class.new('foo', :deleted, :backend)]) }
-
- it { is_expected.to be_falsey }
- end
- end
-
- describe '#optional?' do
- let(:category_with_changelog) { :backend }
- let(:label_with_changelog) { 'frontend' }
- let(:category_without_changelog) { Tooling::Danger::Changelog::NO_CHANGELOG_CATEGORIES.first }
- let(:label_without_changelog) { Tooling::Danger::Changelog::NO_CHANGELOG_LABELS.first }
-
- subject { changelog.optional? }
-
- context 'when MR contains only categories requiring no changelog' do
- let(:changes) { changes_class.new([change_class.new('foo', :modified, category_without_changelog)]) }
-
- it 'is falsey' do
- is_expected.to be_falsy
- end
- end
-
- context 'when MR contains a label that require no changelog' do
- let(:changes) { changes_class.new([change_class.new('foo', :modified, category_with_changelog)]) }
- let(:mr_labels) { [label_with_changelog, label_without_changelog] }
-
- it 'is falsey' do
- is_expected.to be_falsy
- end
- end
-
- context 'when MR contains a category that require changelog and a category that require no changelog' do
- let(:changes) { changes_class.new([change_class.new('foo', :modified, category_with_changelog), change_class.new('foo', :modified, category_without_changelog)]) }
-
- context 'with no labels' do
- it 'is truthy' do
- is_expected.to be_truthy
- end
- end
-
- context 'with changelog label' do
- let(:mr_labels) { ['type::feature'] }
-
- it 'is truthy' do
- is_expected.to be_truthy
- end
- end
-
- context 'with no changelog label' do
- let(:mr_labels) { ['type::tooling'] }
-
- it 'is truthy' do
- is_expected.to be_falsey
- end
- end
- end
- end
-
- describe '#present?' do
- it 'returns true when a Changelog commit is present' do
- allow(changelog)
- .to receive(:valid_changelog_commits)
- .and_return([double(:commit)])
-
- expect(changelog).to be_present
- end
-
- it 'returns false when a Changelog commit is missing' do
- allow(changelog).to receive(:valid_changelog_commits).and_return([])
-
- expect(changelog).not_to be_present
- end
- end
-
- describe '#changelog_commits' do
- it 'returns the commits that include a Changelog trailer' do
- commit1 = double(:commit, message: "foo\nChangelog: fixed")
- commit2 = double(:commit, message: "bar\nChangelog: kittens")
- commit3 = double(:commit, message: 'testing')
- git = double(:git)
-
- allow(changelog).to receive(:git).and_return(git)
- allow(git).to receive(:commits).and_return([commit1, commit2, commit3])
-
- expect(changelog.changelog_commits).to eq([commit1, commit2])
- end
- end
-
- describe '#valid_changelog_commits' do
- it 'returns the commits with a valid Changelog trailer' do
- commit1 = double(:commit, message: "foo\nChangelog: fixed")
- commit2 = double(:commit, message: "bar\nChangelog: kittens")
-
- allow(changelog)
- .to receive(:changelog_commits)
- .and_return([commit1, commit2])
-
- expect(changelog.valid_changelog_commits).to eq([commit1])
- end
- end
-
- describe '#ee_changelog?' do
- it 'returns true when an EE changelog commit is present' do
- commit = double(:commit, message: "foo\nEE: true")
-
- allow(changelog).to receive(:changelog_commits).and_return([commit])
-
- expect(changelog.ee_changelog?).to eq(true)
- end
-
- it 'returns false when an EE changelog commit is missing' do
- commit = double(:commit, message: 'foo')
-
- allow(changelog).to receive(:changelog_commits).and_return([commit])
-
- expect(changelog.ee_changelog?).to eq(false)
- end
- end
-
- describe '#modified_text' do
- subject { changelog.modified_text }
-
- context 'when in CI context' do
- shared_examples 'changelog modified text' do |key|
- specify do
- expect(subject).to include('CHANGELOG.md was edited')
- expect(subject).to include('`Changelog` trailer')
- expect(subject).to include('`EE: true`')
- end
- end
-
- before do
- allow(fake_helper).to receive(:ci?).and_return(true)
- end
-
- context "when title is not changed from sanitization", :aggregate_failures do
- let(:mr_title) { 'Fake Title' }
-
- it_behaves_like 'changelog modified text'
- end
-
- context "when title needs sanitization", :aggregate_failures do
- let(:mr_title) { 'DRAFT: Fake Title' }
-
- it_behaves_like 'changelog modified text'
- end
- end
-
- context 'when in local context' do
- let(:mr_title) { 'Fake Title' }
-
- before do
- allow(fake_helper).to receive(:ci?).and_return(false)
- end
-
- specify do
- expect(subject).to include('CHANGELOG.md was edited')
- expect(subject).not_to include('`Changelog` trailer')
- end
- end
- end
-
- describe '#required_texts' do
- let(:mr_title) { 'Fake Title' }
-
- subject { changelog.required_texts }
-
- context 'when in CI context' do
- before do
- allow(fake_helper).to receive(:ci?).and_return(true)
- end
-
- shared_examples 'changelog required text' do |key|
- specify do
- expect(subject).to have_key(key)
- expect(subject[key]).to include('CHANGELOG missing')
- expect(subject[key]).to include('`Changelog` trailer')
- end
- end
-
- context 'with a new migration file' do
- let(:changes) { changes_class.new([change_class.new('foo', :added, :migration)]) }
-
- context "when title is not changed from sanitization", :aggregate_failures do
- it_behaves_like 'changelog required text', :db_changes
- end
-
- context "when title needs sanitization", :aggregate_failures do
- let(:mr_title) { 'DRAFT: Fake Title' }
-
- it_behaves_like 'changelog required text', :db_changes
- end
- end
-
- context 'with a removed feature flag file' do
- let(:changes) { changes_class.new([change_class.new('foo', :deleted, :feature_flag)]) }
-
- it_behaves_like 'changelog required text', :feature_flag_removed
- end
- end
-
- context 'when in local context' do
- before do
- allow(fake_helper).to receive(:ci?).and_return(false)
- end
-
- shared_examples 'changelog required text' do |key|
- specify do
- expect(subject).to have_key(key)
- expect(subject[key]).to include('CHANGELOG missing')
- expect(subject[key]).not_to include('`Changelog` trailer')
- end
- end
-
- context 'with a new migration file' do
- let(:changes) { changes_class.new([change_class.new('foo', :added, :migration)]) }
-
- context "when title is not changed from sanitization", :aggregate_failures do
- it_behaves_like 'changelog required text', :db_changes
- end
-
- context "when title needs sanitization", :aggregate_failures do
- let(:mr_title) { 'DRAFT: Fake Title' }
-
- it_behaves_like 'changelog required text', :db_changes
- end
- end
-
- context 'with a removed feature flag file' do
- let(:changes) { changes_class.new([change_class.new('foo', :deleted, :feature_flag)]) }
-
- it_behaves_like 'changelog required text', :feature_flag_removed
- end
- end
- end
-
- describe '#optional_text' do
- subject { changelog.optional_text }
-
- context 'when in CI context' do
- shared_examples 'changelog optional text' do |key|
- specify do
- expect(subject).to include('CHANGELOG missing')
- expect(subject).to include('`Changelog` trailer')
- expect(subject).to include('EE: true')
- end
- end
-
- before do
- allow(fake_helper).to receive(:ci?).and_return(true)
- end
-
- context "when title is not changed from sanitization", :aggregate_failures do
- let(:mr_title) { 'Fake Title' }
-
- it_behaves_like 'changelog optional text'
- end
-
- context "when title needs sanitization", :aggregate_failures do
- let(:mr_title) { 'DRAFT: Fake Title' }
-
- it_behaves_like 'changelog optional text'
- end
- end
-
- context 'when in local context' do
- let(:mr_title) { 'Fake Title' }
-
- before do
- allow(fake_helper).to receive(:ci?).and_return(false)
- end
-
- specify do
- expect(subject).to include('CHANGELOG missing')
- end
- end
- end
-end
diff --git a/spec/tooling/danger/datateam_spec.rb b/spec/tooling/danger/datateam_spec.rb
index 3bcef3ac886..e6698dd8970 100644
--- a/spec/tooling/danger/datateam_spec.rb
+++ b/spec/tooling/danger/datateam_spec.rb
@@ -62,28 +62,28 @@ RSpec.describe Tooling::Danger::Datateam do
'with metric file changes and no performance indicator changes and other label' => {
modified_files: %w(config/metrics/20210216182127_user_secret_detection_jobs.yml),
changed_lines: ['-product_stage: growth'],
- mr_labels: ['type::tooling'],
+ mr_labels: ['type::maintenance'],
impacted: false,
impacted_files: []
},
'with performance indicator changes and other label' => {
modified_files: %w(config/metrics/20210216182127_user_secret_detection_jobs.yml app/models/user.rb),
changed_lines: ['+-gmau'],
- mr_labels: ['type::tooling'],
+ mr_labels: ['type::maintenance'],
impacted: true,
impacted_files: %w(config/metrics/20210216182127_user_secret_detection_jobs.yml)
},
'with performance indicator changes, Data Warehouse::Impact Check and other label' => {
modified_files: %w(config/metrics/20210216182127_user_secret_detection_jobs.yml app/models/user.rb),
changed_lines: ['+-gmau'],
- mr_labels: ['type::tooling', 'Data Warehouse::Impact Check'],
+ mr_labels: ['type::maintenance', 'Data Warehouse::Impact Check'],
impacted: false,
impacted_files: %w(config/metrics/20210216182127_user_secret_detection_jobs.yml)
},
'with performance indicator changes and other labels' => {
modified_files: %w(config/metrics/20210216182127_user_secret_detection_jobs.yml app/models/user.rb),
changed_lines: ['+-gmau'],
- mr_labels: ['type::tooling', 'Data Warehouse::Impacted'],
+ mr_labels: ['type::maintenance', 'Data Warehouse::Impacted'],
impacted: false,
impacted_files: %w(config/metrics/20210216182127_user_secret_detection_jobs.yml)
}
diff --git a/spec/tooling/danger/project_helper_spec.rb b/spec/tooling/danger/project_helper_spec.rb
index 1b416286f8e..902e01e2cbd 100644
--- a/spec/tooling/danger/project_helper_spec.rb
+++ b/spec/tooling/danger/project_helper_spec.rb
@@ -44,7 +44,7 @@ RSpec.describe Tooling::Danger::ProjectHelper do
'ee/README' | [:unknown]
'app/assets/foo' | [:frontend]
- 'app/views/foo' | [:frontend]
+ 'app/views/foo' | [:frontend, :backend]
'public/foo' | [:frontend]
'scripts/frontend/foo' | [:frontend]
'spec/frontend/bar' | [:frontend]
@@ -58,7 +58,7 @@ RSpec.describe Tooling::Danger::ProjectHelper do
'config/deep/foo.js' | [:frontend]
'ee/app/assets/foo' | [:frontend]
- 'ee/app/views/foo' | [:frontend]
+ 'ee/app/views/foo' | [:frontend, :backend]
'ee/spec/frontend/bar' | [:frontend]
'ee/spec/frontend_integration/bar' | [:frontend]
@@ -166,6 +166,8 @@ RSpec.describe Tooling::Danger::ProjectHelper do
'lib/gitlab/usage_data_counters/aggregated_metrics/common.yml' | [:product_intelligence]
'lib/gitlab/usage_data_counters/hll_redis_counter.rb' | [:backend, :product_intelligence]
'lib/gitlab/tracking.rb' | [:backend, :product_intelligence]
+ 'lib/gitlab/usage/service_ping_report.rb' | [:backend, :product_intelligence]
+ 'lib/gitlab/usage/metrics/key_path_processor.rb' | [:backend, :product_intelligence]
'spec/lib/gitlab/tracking_spec.rb' | [:backend, :product_intelligence]
'app/helpers/tracking_helper.rb' | [:backend, :product_intelligence]
'spec/helpers/tracking_helper_spec.rb' | [:backend, :product_intelligence]
@@ -181,6 +183,8 @@ RSpec.describe Tooling::Danger::ProjectHelper do
'config/metrics/schema.json' | [:product_intelligence]
'doc/api/usage_data.md' | [:product_intelligence]
'spec/lib/gitlab/usage_data_spec.rb' | [:product_intelligence]
+ 'spec/lib/gitlab/usage/service_ping_report.rb' | [:backend, :product_intelligence]
+ 'spec/lib/gitlab/usage/metrics/key_path_processor.rb' | [:backend, :product_intelligence]
'app/models/integration.rb' | [:integrations_be, :backend]
'ee/app/models/integrations/github.rb' | [:integrations_be, :backend]
@@ -213,6 +217,7 @@ RSpec.describe Tooling::Danger::ProjectHelper do
'ee/lib/ee/gitlab/integrations/sti_type.rb' | [:integrations_be, :backend]
'ee/lib/ee/api/helpers/integrations_helpers.rb' | [:integrations_be, :backend]
'ee/app/serializers/integrations/jira_serializers/issue_entity.rb' | [:integrations_be, :backend]
+ 'app/serializers/jira_connect/app_data_serializer.rb' | [:integrations_be, :backend]
'lib/api/github/entities.rb' | [:integrations_be, :backend]
'lib/api/v3/github.rb' | [:integrations_be, :backend]
'app/models/clusters/integrations/elastic_stack.rb' | [:backend]
@@ -227,9 +232,12 @@ RSpec.describe Tooling::Danger::ProjectHelper do
'ee/app/assets/javascripts/integrations/zentao/issues_list/graphql/queries/get_zentao_issues.query.graphql' | [:integrations_fe, :frontend]
'app/assets/javascripts/pages/projects/settings/integrations/show/index.js' | [:integrations_fe, :frontend]
'ee/app/assets/javascripts/pages/groups/hooks/index.js' | [:integrations_fe, :frontend]
- 'app/views/clusters/clusters/_integrations_tab.html.haml' | [:frontend]
+ 'app/views/clusters/clusters/_integrations_tab.html.haml' | [:frontend, :backend]
'app/assets/javascripts/alerts_settings/graphql/fragments/integration_item.fragment.graphql' | [:frontend]
'app/assets/javascripts/filtered_search/droplab/hook_input.js' | [:frontend]
+
+ 'app/views/layouts/header/_default.html.haml' | [:frontend, :backend]
+ 'app/views/layouts/header/_default.html.erb' | [:frontend, :backend]
end
with_them do
@@ -270,7 +278,7 @@ RSpec.describe Tooling::Danger::ProjectHelper do
describe '.local_warning_message' do
it 'returns an informational message with rules that can run' do
- expect(described_class.local_warning_message).to eq('==> Only the following Danger rules can be run locally: changelog, ci_config, database, documentation, duplicate_yarn_dependencies, eslint, gitaly, pajamas, pipeline, prettier, product_intelligence, utility_css, vue_shared_documentation, datateam')
+ expect(described_class.local_warning_message).to eq('==> Only the following Danger rules can be run locally: ci_config, database, documentation, duplicate_yarn_dependencies, eslint, gitaly, pajamas, pipeline, prettier, product_intelligence, utility_css, vue_shared_documentation, datateam')
end
end
@@ -302,18 +310,6 @@ RSpec.describe Tooling::Danger::ProjectHelper do
end
end
- describe '#all_ee_changes' do
- subject { project_helper.all_ee_changes }
-
- it 'returns all changed files starting with ee/' do
- changes = double
- expect(fake_helper).to receive(:changes).and_return(changes)
- expect(changes).to receive(:files).and_return(%w[fr/ee/beer.rb ee/wine.rb ee/lib/ido.rb ee.k])
-
- is_expected.to match_array(%w[ee/wine.rb ee/lib/ido.rb])
- end
- end
-
describe '#file_lines' do
let(:filename) { 'spec/foo_spec.rb' }
let(:file_spy) { spy }
diff --git a/spec/tooling/docs/deprecation_handling_spec.rb b/spec/tooling/docs/deprecation_handling_spec.rb
index e43f5c7147b..15dd69275c9 100644
--- a/spec/tooling/docs/deprecation_handling_spec.rb
+++ b/spec/tooling/docs/deprecation_handling_spec.rb
@@ -28,7 +28,7 @@ RSpec.describe Docs::DeprecationHandling do
milestones = arguments[:milestones]
entries = arguments[:entries]
- expect(milestones).to eq(['14.2', '14.10'])
+ expect(milestones).to eq(['14.10', '14.2'])
expect(entries.map { |e| e['name'] }).to eq(['a.yml', 'b.yml', 'c.yml'])
end
end
diff --git a/spec/tooling/quality/test_level_spec.rb b/spec/tooling/quality/test_level_spec.rb
index 33d3a5b49b3..c72e90dc713 100644
--- a/spec/tooling/quality/test_level_spec.rb
+++ b/spec/tooling/quality/test_level_spec.rb
@@ -28,7 +28,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,elastic,elastic_integration,experiments,events,factories,finders,frontend,graphql,haml_lint,helpers,initializers,javascripts,lib,metrics_server,models,policies,presenters,rack_servers,replicators,routing,rubocop,scripts,serializers,services,sidekiq,sidekiq_cluster,spam,support_specs,tasks,uploaders,validators,views,workers,tooling}{,/**/}*_spec.rb")
+ .to eq("spec/{bin,channels,config,db,dependencies,elastic,elastic_integration,experiments,events,factories,finders,frontend,graphql,haml_lint,helpers,initializers,javascripts,lib,metrics_server,models,policies,presenters,rack_servers,replicators,routing,rubocop,scripts,serializers,services,sidekiq,sidekiq_cluster,spam,support_specs,tasks,uploaders,validators,views,workers,tooling,component}{,/**/}*_spec.rb")
end
end
@@ -110,7 +110,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|elastic|elastic_integration|experiments|events|factories|finders|frontend|graphql|haml_lint|helpers|initializers|javascripts|lib|metrics_server|models|policies|presenters|rack_servers|replicators|routing|rubocop|scripts|serializers|services|sidekiq|sidekiq_cluster|spam|support_specs|tasks|uploaders|validators|views|workers|tooling)})
+ .to eq(%r{spec/(bin|channels|config|db|dependencies|elastic|elastic_integration|experiments|events|factories|finders|frontend|graphql|haml_lint|helpers|initializers|javascripts|lib|metrics_server|models|policies|presenters|rack_servers|replicators|routing|rubocop|scripts|serializers|services|sidekiq|sidekiq_cluster|spam|support_specs|tasks|uploaders|validators|views|workers|tooling|component)})
end
end
diff --git a/spec/validators/array_members_validator_spec.rb b/spec/validators/array_members_validator_spec.rb
index c6960925487..0e3ca4b5b7b 100644
--- a/spec/validators/array_members_validator_spec.rb
+++ b/spec/validators/array_members_validator_spec.rb
@@ -12,6 +12,7 @@ RSpec.describe ArrayMembersValidator do
include ActiveModel::Model
include ActiveModel::Validations
attr_accessor :children
+
validates :children, array_members: { member_class: child_class }
end
end
diff --git a/spec/validators/color_validator_spec.rb b/spec/validators/color_validator_spec.rb
index bd77b3df182..9c1339caffb 100644
--- a/spec/validators/color_validator_spec.rb
+++ b/spec/validators/color_validator_spec.rb
@@ -10,6 +10,7 @@ RSpec.describe ColorValidator do
include ActiveModel::Model
include ActiveModel::Validations
attr_accessor :color
+
validates :color, color: true
end.new
end
@@ -22,7 +23,12 @@ RSpec.describe ColorValidator do
'#ffff' | false
'#000111222' | false
'invalid' | false
+ 'red' | false
'000' | false
+ nil | true # use presence to validate non-nil
+ '' | false
+ Time.current | false
+ ::Gitlab::Color.of(:red) | true
end
with_them do
@@ -40,4 +46,22 @@ RSpec.describe ColorValidator do
Timeout.timeout(5.seconds) { subject.valid? }
end.not_to raise_error
end
+
+ context 'when color must be present' do
+ subject do
+ Class.new do
+ include ActiveModel::Model
+ include ActiveModel::Validations
+ attr_accessor :color
+
+ validates :color, color: true, presence: true
+ end.new
+ end
+
+ it 'rejects nil' do
+ subject.color = nil
+
+ expect(subject).not_to be_valid
+ end
+ end
end
diff --git a/spec/validators/cron_validator_spec.rb b/spec/validators/cron_validator_spec.rb
index dff3b506b89..bd7fe242957 100644
--- a/spec/validators/cron_validator_spec.rb
+++ b/spec/validators/cron_validator_spec.rb
@@ -8,6 +8,7 @@ RSpec.describe CronValidator do
include ActiveModel::Model
include ActiveModel::Validations
attr_accessor :cron
+
validates :cron, cron: true
def cron_timezone
@@ -34,6 +35,7 @@ RSpec.describe CronValidator do
include ActiveModel::Model
include ActiveModel::Validations
attr_accessor :cron_partytime
+
validates :cron_partytime, cron: true
end.new
end
diff --git a/spec/validators/future_date_validator_spec.rb b/spec/validators/future_date_validator_spec.rb
index 6814ba7c820..7af3d473bd9 100644
--- a/spec/validators/future_date_validator_spec.rb
+++ b/spec/validators/future_date_validator_spec.rb
@@ -8,6 +8,7 @@ RSpec.describe FutureDateValidator do
include ActiveModel::Model
include ActiveModel::Validations
attr_accessor :expires_at
+
validates :expires_at, future_date: true
end.new
end
diff --git a/spec/validators/import/gitlab_projects/remote_file_validator_spec.rb b/spec/validators/import/gitlab_projects/remote_file_validator_spec.rb
new file mode 100644
index 00000000000..428e0279821
--- /dev/null
+++ b/spec/validators/import/gitlab_projects/remote_file_validator_spec.rb
@@ -0,0 +1,70 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe ::Import::GitlabProjects::RemoteFileValidator, :aggregate_failures do
+ let(:validated_class) do
+ Class.new do
+ include ActiveModel::Validations
+
+ def self.name
+ 'AClass'
+ end
+
+ attr_accessor :content_type, :content_length
+
+ def initialize(content_length:, content_type:)
+ @content_type = content_type
+ @content_length = content_length
+ end
+ end
+ end
+
+ let(:validated_object) { validated_class.new(content_length: 1.gigabytes, content_type: 'application/gzip') }
+
+ subject { described_class.new }
+
+ it 'does nothing when the oject is valid' do
+ subject.validate(validated_object)
+
+ expect(validated_object.errors.full_messages).to be_empty
+ end
+
+ context 'content_length validation' do
+ it 'is invalid with file too small' do
+ validated_object.content_length = nil
+
+ subject.validate(validated_object)
+
+ expect(validated_object.errors.full_messages)
+ .to include('Content length is too small (should be at least 1 Byte)')
+ end
+
+ it 'is invalid with file too large' do
+ validated_object.content_length = (described_class::FILE_SIZE_LIMIT + 1).gigabytes
+
+ subject.validate(validated_object)
+
+ expect(validated_object.errors.full_messages)
+ .to include('Content length is too big (should be at most 10 GB)')
+ end
+ end
+
+ context 'content_type validation' do
+ it 'only allows ALLOWED_CONTENT_TYPES as content_type' do
+ described_class::ALLOWED_CONTENT_TYPES.each do |content_type|
+ validated_object.content_type = content_type
+ subject.validate(validated_object)
+
+ expect(validated_object.errors.to_a).to be_empty
+ end
+
+ validated_object.content_type = 'unknown'
+
+ subject.validate(validated_object)
+
+ expect(validated_object.errors.full_messages)
+ .to include("Content type 'unknown' not allowed. (Allowed: application/gzip, application/x-tar, application/x-gzip)")
+ end
+ end
+end
diff --git a/spec/views/admin/application_settings/_eks.html.haml_spec.rb b/spec/views/admin/application_settings/_eks.html.haml_spec.rb
index e407970c7a4..d16cbc7b299 100644
--- a/spec/views/admin/application_settings/_eks.html.haml_spec.rb
+++ b/spec/views/admin/application_settings/_eks.html.haml_spec.rb
@@ -16,8 +16,8 @@ RSpec.describe 'admin/application_settings/_eks' do
shared_examples 'EKS secret access key input' do
it 'renders an empty password field' do
render
- expect(rendered).to have_field('Secret access key', type: 'password')
- expect(page.find_field('Secret access key').value).to be_blank
+ expect(rendered).to have_field('AWS secret access key (Optional)', type: 'password')
+ expect(page.find_field('AWS secret access key (Optional)').value).to be_blank
end
end
diff --git a/spec/views/admin/application_settings/repository.html.haml_spec.rb b/spec/views/admin/application_settings/repository.html.haml_spec.rb
index 30047878b0f..e28a69d0f87 100644
--- a/spec/views/admin/application_settings/repository.html.haml_spec.rb
+++ b/spec/views/admin/application_settings/repository.html.haml_spec.rb
@@ -21,8 +21,9 @@ RSpec.describe 'admin/application_settings/repository.html.haml' do
it 'renders the correct setting section content' do
render
- expect(rendered).to have_content("Default initial branch name")
- expect(rendered).to have_content("The default name for the initial branch of new repositories created in the instance.")
+ expect(rendered).to have_content("Initial default branch name")
+ expect(rendered).to have_content("Set the initial name and protections for the default branch of new repositories created in the instance.")
+ expect(rendered).to have_content("Initial default branch protection")
end
end
end
diff --git a/spec/views/admin/broadcast_messages/index.html.haml_spec.rb b/spec/views/admin/broadcast_messages/index.html.haml_spec.rb
new file mode 100644
index 00000000000..e1dc76428df
--- /dev/null
+++ b/spec/views/admin/broadcast_messages/index.html.haml_spec.rb
@@ -0,0 +1,36 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'admin/broadcast_messages/index' do
+ describe 'Target roles select and table column' do
+ let(:feature_flag_state) { true }
+
+ let_it_be(:message) { create(:broadcast_message, broadcast_type: 'banner', target_access_levels: [Gitlab::Access::GUEST, Gitlab::Access::DEVELOPER]) }
+
+ before do
+ assign(:broadcast_messages, BroadcastMessage.page(1))
+ assign(:broadcast_message, BroadcastMessage.new)
+
+ stub_feature_flags(role_targeted_broadcast_messages: feature_flag_state)
+
+ render
+ end
+
+ it 'rendered' do
+ expect(rendered).to have_content('Target roles')
+ expect(rendered).to have_content('Owner')
+ expect(rendered).to have_content('Guest, Developer')
+ end
+
+ context 'when feature flag is off' do
+ let(:feature_flag_state) { false }
+
+ it 'is not rendered' do
+ expect(rendered).not_to have_content('Target roles')
+ expect(rendered).not_to have_content('Owner')
+ expect(rendered).not_to have_content('Guest, Developer')
+ end
+ end
+ end
+end
diff --git a/spec/views/devise/sessions/new.html.haml_spec.rb b/spec/views/devise/sessions/new.html.haml_spec.rb
index 0109d05abe4..e8232a2c067 100644
--- a/spec/views/devise/sessions/new.html.haml_spec.rb
+++ b/spec/views/devise/sessions/new.html.haml_spec.rb
@@ -9,7 +9,7 @@ RSpec.describe 'devise/sessions/new' do
before do
stub_devise
disable_captcha
- allow(Gitlab).to receive(:dev_env_or_com?).and_return(true)
+ allow(Gitlab).to receive(:com?).and_return(true)
end
it 'when flash is anything it renders marketing text' do
diff --git a/spec/views/devise/shared/_signup_box.html.haml_spec.rb b/spec/views/devise/shared/_signup_box.html.haml_spec.rb
index 37dbfd39f2d..1f0cd213f7b 100644
--- a/spec/views/devise/shared/_signup_box.html.haml_spec.rb
+++ b/spec/views/devise/shared/_signup_box.html.haml_spec.rb
@@ -27,7 +27,7 @@ RSpec.describe 'devise/shared/_signup_box' do
context 'when on .com' do
before do
- allow(Gitlab).to receive(:dev_env_or_com?).and_return(true)
+ allow(Gitlab).to receive(:com?).and_return(true)
end
it 'shows expected GitLab text' do
@@ -39,7 +39,7 @@ RSpec.describe 'devise/shared/_signup_box' do
context 'when not on .com' do
before do
- allow(Gitlab).to receive(:dev_env_or_com?).and_return(false)
+ allow(Gitlab).to receive(:com?).and_return(false)
end
it 'shows expected text without GitLab' do
@@ -53,7 +53,7 @@ RSpec.describe 'devise/shared/_signup_box' do
context 'when terms are not enforced' do
before do
allow(Gitlab::CurrentSettings.current_application_settings).to receive(:enforce_terms?).and_return(false)
- allow(Gitlab).to receive(:dev_env_or_com?).and_return(true)
+ allow(Gitlab).to receive(:com?).and_return(true)
end
it 'shows expected text with placeholders' do
diff --git a/spec/views/groups/group_members/index.html.haml_spec.rb b/spec/views/groups/group_members/index.html.haml_spec.rb
index 8e190c24495..40d4c9d33c9 100644
--- a/spec/views/groups/group_members/index.html.haml_spec.rb
+++ b/spec/views/groups/group_members/index.html.haml_spec.rb
@@ -10,7 +10,6 @@ RSpec.describe 'groups/group_members/index', :aggregate_failures do
allow(view).to receive(:group_members_app_data).and_return({})
allow(view).to receive(:current_user).and_return(user)
assign(:group, group)
- assign(:group_member, build(:group_member, group: group))
end
context 'when user can invite members for the group' do
@@ -18,42 +17,15 @@ RSpec.describe 'groups/group_members/index', :aggregate_failures do
group.add_owner(user)
end
- context 'when modal is enabled' do
- it 'renders as expected' do
- render
-
- expect(rendered).to have_content('Group members')
- expect(rendered).to have_content('You can invite a new member')
-
- expect(rendered).to have_selector('.js-invite-group-trigger')
- expect(rendered).to have_selector('.js-invite-members-trigger')
- expect(response).to render_template(partial: 'groups/_invite_members_modal')
-
- expect(rendered).not_to have_selector('#invite-member-tab')
- expect(rendered).not_to have_selector('#invite-group-tab')
- expect(response).not_to render_template(partial: 'shared/members/_invite_group')
- end
- end
-
- context 'when modal is not enabled' do
- before do
- stub_feature_flags(invite_members_group_modal: false)
- end
-
- it 'renders as expected' do
- render
-
- expect(rendered).to have_content('Group members')
- expect(rendered).to have_content('You can invite a new member')
+ it 'renders as expected' do
+ render
- expect(rendered).to have_selector('#invite-member-tab')
- expect(rendered).to have_selector('#invite-group-tab')
- expect(response).to render_template(partial: 'shared/members/_invite_group')
+ expect(rendered).to have_content('Group members')
+ expect(rendered).to have_content('You can invite a new member')
- expect(rendered).not_to have_selector('.js-invite-group-trigger')
- expect(rendered).not_to have_selector('.js-invite-members-trigger')
- expect(response).not_to render_template(partial: 'groups/_invite_members_modal')
- end
+ expect(rendered).to have_selector('.js-invite-group-trigger')
+ expect(rendered).to have_selector('.js-invite-members-trigger')
+ expect(response).to render_template(partial: 'groups/_invite_members_modal')
end
end
diff --git a/spec/views/layouts/_header_search.html.haml_spec.rb b/spec/views/layouts/_header_search.html.haml_spec.rb
new file mode 100644
index 00000000000..3ab4ae6a483
--- /dev/null
+++ b/spec/views/layouts/_header_search.html.haml_spec.rb
@@ -0,0 +1,113 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe 'layouts/_header_search' do
+ let(:project) { nil }
+ let(:group) { nil }
+ let(:scope) { nil }
+ let(:ref) { nil }
+ let(:code_search) { false }
+ let(:for_snippets) { false}
+
+ let(:header_search_context) do
+ {
+ project: project,
+ group: group,
+ scope: scope,
+ ref: ref,
+ code_search: code_search,
+ for_snippets: for_snippets
+ }
+ end
+
+ before do
+ allow(view).to receive(:header_search_context).and_return(header_search_context)
+ end
+
+ shared_examples 'hidden fields are properly set' do
+ context 'when search_context has a scope value' do
+ let(:scope) { 'issues' }
+
+ it 'sets scope input to issues' do
+ render
+
+ expect(rendered).to have_css("input[name='scope'][value='#{scope}']", count: 1, visible: false)
+ end
+ end
+
+ context 'when search_context has a code_search value' do
+ let(:code_search) { true }
+
+ it 'sets search_code input to true' do
+ render
+
+ expect(rendered).to have_css("input[name='search_code'][value='#{code_search}']", count: 1, visible: false)
+ end
+ end
+
+ context 'when search_context has a ref value' do
+ let(:ref) { 'test-branch' }
+
+ it 'sets repository_ref input to test-branch' do
+ render
+
+ expect(rendered).to have_css("input[name='repository_ref'][value='#{ref}']", count: 1, visible: false)
+ end
+ end
+
+ context 'when search_context has a for_snippets value' do
+ let(:for_snippets) { true }
+
+ it 'sets for_snippets input to true' do
+ render
+
+ expect(rendered).to have_css("input[name='snippets'][value='#{for_snippets}']", count: 1, visible: false)
+ end
+ end
+
+ context 'nav_source' do
+ it 'always set to navbar' do
+ render
+
+ expect(rendered).to have_css("input[name='nav_source'][value='navbar']", count: 1, visible: false)
+ end
+ end
+
+ context 'submit button' do
+ it 'always renders for specs' do
+ render
+
+ expect(rendered).to have_css('noscript button', text: 'Search')
+ end
+ end
+ end
+
+ context 'when doing a project level search' do
+ let(:project) do
+ { id: 123, name: 'foo' }
+ end
+
+ it 'sets project_id field' do
+ render
+
+ expect(rendered).to have_css("input[name='project_id'][value='#{project[:id]}']", count: 1, visible: false)
+ end
+
+ it_behaves_like 'hidden fields are properly set'
+ end
+
+ context 'when doing a group level search' do
+ let(:group) do
+ { id: 123, name: 'bar' }
+ end
+
+ it 'sets group_id field' do
+ render
+
+ expect(rendered).to have_css("input[name='group_id'][value='#{group[:id]}']", count: 1, visible: false)
+ end
+
+ it_behaves_like 'hidden fields are properly set'
+ end
+end
diff --git a/spec/views/layouts/_published_experiments.html.haml_spec.rb b/spec/views/layouts/_published_experiments.html.haml_spec.rb
index d1ade8ddd6e..84894554bd9 100644
--- a/spec/views/layouts/_published_experiments.html.haml_spec.rb
+++ b/spec/views/layouts/_published_experiments.html.haml_spec.rb
@@ -4,22 +4,20 @@ require 'spec_helper'
RSpec.describe 'layouts/_published_experiments', :experiment do
before do
- stub_const('TestControlExperiment', ApplicationExperiment)
- stub_const('TestCandidateExperiment', ApplicationExperiment)
- stub_const('TestExcludedExperiment', ApplicationExperiment)
+ # Stub each experiment to be enabled, otherwise tracking does not happen.
+ stub_experiments(
+ test_control: :control,
+ test_excluded: true,
+ test_published_only: :control,
+ test_candidate: :candidate,
+ test_variant: :variant_name
+ )
- TestControlExperiment.new('test_control').tap do |e|
- e.variant(:control)
- e.publish
- end
- TestCandidateExperiment.new('test_candidate').tap do |e|
- e.variant(:candidate)
- e.publish
- end
- TestExcludedExperiment.new('test_excluded').tap do |e|
- e.exclude!
- e.publish
- end
+ experiment(:test_control) { }
+ experiment(:test_excluded) { |e| e.exclude! }
+ experiment(:test_candidate) { |e| e.candidate { } }
+ experiment(:test_variant) { |e| e.variant(:variant_name) { } }
+ experiment(:test_published_only).publish
render
end
@@ -29,7 +27,9 @@ RSpec.describe 'layouts/_published_experiments', :experiment do
expect(output).to include('gl.experiments = {')
expect(output).to match(/"test_control":\{[^}]*"variant":"control"/)
- expect(output).to match(/"test_candidate":\{[^}]*"variant":"candidate"/)
expect(output).not_to include('"test_excluded"')
+ expect(output).to match(/"test_candidate":\{[^}]*"variant":"candidate"/)
+ expect(output).to match(/"test_variant":\{[^}]*"variant":"variant_name"/)
+ expect(output).to match(/"test_published_only":\{[^}]*"variant":"control"/)
end
end
diff --git a/spec/views/projects/commits/_commit.html.haml_spec.rb b/spec/views/projects/commits/_commit.html.haml_spec.rb
index 5c66fbe7dd7..da93871e0e4 100644
--- a/spec/views/projects/commits/_commit.html.haml_spec.rb
+++ b/spec/views/projects/commits/_commit.html.haml_spec.rb
@@ -33,7 +33,7 @@ RSpec.describe 'projects/commits/_commit.html.haml' do
let(:ref) { GpgHelpers::SIGNED_COMMIT_SHA }
it 'does not display a loading spinner for GPG status' do
- render partial: template, locals: {
+ render partial: template, formats: :html, locals: {
project: project,
ref: ref,
commit: commit
@@ -69,7 +69,7 @@ RSpec.describe 'projects/commits/_commit.html.haml' do
end
it 'does not display a ci status icon' do
- render partial: template, locals: {
+ render partial: template, formats: :html, locals: {
project: project,
ref: ref,
commit: commit
@@ -85,7 +85,7 @@ RSpec.describe 'projects/commits/_commit.html.haml' do
end
it 'does display a ci status icon when pipelines are enabled' do
- render partial: template, locals: {
+ render partial: template, formats: :html, locals: {
project: project,
ref: ref,
commit: commit
diff --git a/spec/views/projects/empty.html.haml_spec.rb b/spec/views/projects/empty.html.haml_spec.rb
index 416dfc10174..6077dda3c98 100644
--- a/spec/views/projects/empty.html.haml_spec.rb
+++ b/spec/views/projects/empty.html.haml_spec.rb
@@ -25,6 +25,21 @@ RSpec.describe 'projects/empty' do
expect(rendered).to have_content("git clone")
end
+
+ context 'when default branch name contains special shell characters' do
+ let(:branch_name) { ';rm -rf /' }
+
+ before do
+ allow(project).to receive(:default_branch_or_main).and_return(branch_name)
+ end
+
+ it 'escapes the default branch name' do
+ render
+
+ expect(rendered).not_to have_content(branch_name)
+ expect(rendered).to have_content(branch_name.shellescape)
+ end
+ end
end
context 'when user can not push code on the project' do
diff --git a/spec/views/projects/project_members/index.html.haml_spec.rb b/spec/views/projects/project_members/index.html.haml_spec.rb
index b9b0d57bcb5..7186a5f1766 100644
--- a/spec/views/projects/project_members/index.html.haml_spec.rb
+++ b/spec/views/projects/project_members/index.html.haml_spec.rb
@@ -11,7 +11,6 @@ RSpec.describe 'projects/project_members/index', :aggregate_failures do
allow(view).to receive(:project_members_app_data_json).and_return({})
allow(view).to receive(:current_user).and_return(user)
assign(:project, project)
- assign(:project_member, build(:project_member, project: source))
end
context 'when user can invite members for the project' do
@@ -44,38 +43,6 @@ RSpec.describe 'projects/project_members/index', :aggregate_failures do
end
end
end
-
- context 'when modal is not enabled' do
- before do
- stub_feature_flags(invite_members_group_modal: false)
- end
-
- it 'renders as expected' do
- render
-
- expect(rendered).to have_content('Project members')
- expect(rendered).to have_content('You can invite a new member')
- expect(rendered).not_to have_selector('.js-invite-group-trigger')
- expect(rendered).not_to have_selector('.js-invite-members-trigger')
- expect(rendered).not_to have_content('Members can be added by project')
- expect(response).not_to render_template(partial: 'projects/_invite_members_modal')
- expect(response).to render_template(partial: 'shared/members/_invite_member')
- end
-
- context 'when project can not be shared' do
- before do
- project.namespace.share_with_group_lock = true
- end
-
- it 'renders as expected' do
- render
-
- expect(rendered).to have_content('Project members')
- expect(rendered).to have_content('You can invite a new member')
- expect(response).not_to render_template(partial: 'projects/_invite_members_modal')
- end
- end
- end
end
context 'when user can not invite members or group for the project' do
diff --git a/spec/views/projects/runners/_specific_runners.html.haml_spec.rb b/spec/views/projects/runners/_specific_runners.html.haml_spec.rb
index ace3502dd1e..ce16e0d5ac6 100644
--- a/spec/views/projects/runners/_specific_runners.html.haml_spec.rb
+++ b/spec/views/projects/runners/_specific_runners.html.haml_spec.rb
@@ -11,12 +11,14 @@ RSpec.describe 'projects/runners/specific_runners.html.haml' do
@project = project
@assignable_runners = []
@project_runners = []
+ allow(view).to receive(:current_user).and_return(user)
allow(view).to receive(:reset_registration_token_namespace_project_settings_ci_cd_path).and_return('banana_url')
end
context 'when project runner registration is allowed' do
before do
stub_application_setting(valid_runner_registrars: ['project'])
+ allow(view).to receive(:can?).with(user, :register_project_runners, project).and_return(true)
end
it 'enables the Remove project button for a project' do
@@ -32,7 +34,7 @@ RSpec.describe 'projects/runners/specific_runners.html.haml' do
stub_application_setting(valid_runner_registrars: ['group'])
end
- it 'does not enable the the Remove project button for a project' do
+ it 'does not enable the Remove project button for a project' do
render 'projects/runners/specific_runners', project: project
expect(rendered).to have_content 'Please contact an admin to register runners.'
diff --git a/spec/views/projects/tags/index.html.haml_spec.rb b/spec/views/projects/tags/index.html.haml_spec.rb
index ebd526284d1..ae59c1aa4b2 100644
--- a/spec/views/projects/tags/index.html.haml_spec.rb
+++ b/spec/views/projects/tags/index.html.haml_spec.rb
@@ -6,7 +6,11 @@ RSpec.describe 'projects/tags/index.html.haml' do
let_it_be(:project) { create(:project, :repository) }
let_it_be(:tags) { project.repository.tags }
let_it_be(:git_tag) { project.repository.tags.last }
- let_it_be(:release) { create(:release, project: project, sha: git_tag.target_commit.sha) }
+ let_it_be(:release) do
+ create(:release, project: project,
+ sha: git_tag.target_commit.sha,
+ tag: 'v1.1.0')
+ end
let(:pipeline) { create(:ci_pipeline, :success, project: project, ref: git_tag.name, sha: release.sha) }
diff --git a/spec/views/search/_results.html.haml_spec.rb b/spec/views/search/_results.html.haml_spec.rb
index dcf1f46b46c..72e2d7131c0 100644
--- a/spec/views/search/_results.html.haml_spec.rb
+++ b/spec/views/search/_results.html.haml_spec.rb
@@ -58,17 +58,17 @@ RSpec.describe 'search/_results' do
context 'rendering all types of search results' do
let_it_be(:project) { create(:project, :repository, :wiki_repo) }
- let_it_be(:issue) { create(:issue, project: project, title: '*') }
- let_it_be(:merge_request) { create(:merge_request, title: '*', source_project: project, target_project: project) }
- let_it_be(:milestone) { create(:milestone, title: '*', project: project) }
- let_it_be(:note) { create(:discussion_note_on_issue, project: project, note: '*') }
- let_it_be(:wiki_blob) { create(:wiki_page, wiki: project.wiki, content: '*') }
+ let_it_be(:issue) { create(:issue, project: project, title: 'testing') }
+ let_it_be(:merge_request) { create(:merge_request, title: 'testing', source_project: project, target_project: project) }
+ let_it_be(:milestone) { create(:milestone, title: 'testing', project: project) }
+ let_it_be(:note) { create(:discussion_note_on_issue, project: project, note: 'testing') }
+ let_it_be(:wiki_blob) { create(:wiki_page, wiki: project.wiki, content: 'testing') }
let_it_be(:user) { create(:admin) }
%w[issues merge_requests].each do |search_scope|
context "when scope is #{search_scope}" do
let(:scope) { search_scope }
- let(:search_objects) { Gitlab::ProjectSearchResults.new(user, '*', project: project).objects(scope) }
+ let(:search_objects) { Gitlab::ProjectSearchResults.new(user, 'testing', project: project).objects(scope) }
context 'when admin mode is enabled', :enable_admin_mode do
it 'renders the click text event tracking attributes' do
@@ -96,10 +96,35 @@ RSpec.describe 'search/_results' do
end
end
+ describe 'git blame click tracking' do
+ let(:scope) { 'blobs' }
+ let(:search_objects) { Gitlab::ProjectSearchResults.new(user, 'testing', project: project).objects(scope) }
+
+ context 'when admin mode is enabled', :enable_admin_mode do
+ it 'renders the click link event tracking attributes' do
+ render
+
+ expect(rendered).to have_selector('[data-track-action=click_link]')
+ expect(rendered).to have_selector('[data-track-label=git_blame]')
+ expect(rendered).to have_selector('[data-track-property=search_result]')
+ end
+ end
+
+ context 'when admin mode is disabled' do
+ it 'does not render the click link event tracking attributes' do
+ render
+
+ expect(rendered).not_to have_selector('[data-track-action=click_link]')
+ expect(rendered).not_to have_selector('[data-track-label=git_blame]')
+ expect(rendered).not_to have_selector('[data-track-property=search_result]')
+ end
+ end
+ end
+
%w[blobs notes wiki_blobs milestones].each do |search_scope|
context "when scope is #{search_scope}" do
let(:scope) { search_scope }
- let(:search_objects) { Gitlab::ProjectSearchResults.new(user, '*', project: project).objects(scope) }
+ let(:search_objects) { Gitlab::ProjectSearchResults.new(user, 'testing', project: project).objects(scope) }
context 'when admin mode is enabled', :enable_admin_mode do
it 'renders the click text event tracking attributes' do
diff --git a/spec/views/shared/_gl_toggle.haml_spec.rb b/spec/views/shared/_gl_toggle.haml_spec.rb
deleted file mode 100644
index 3ac1ef30c84..00000000000
--- a/spec/views/shared/_gl_toggle.haml_spec.rb
+++ /dev/null
@@ -1,85 +0,0 @@
-# frozen_string_literal: true
-require 'spec_helper'
-
-RSpec.describe 'shared/_gl_toggle.html.haml' do
- context 'defaults' do
- before do
- render partial: 'shared/gl_toggle', locals: {
- classes: '.js-gl-toggle'
- }
- end
-
- it 'does not set a name' do
- expect(rendered).not_to have_selector('[data-name]')
- end
-
- it 'sets default is-checked attributes' do
- expect(rendered).to have_selector('[data-is-checked="false"]')
- end
-
- it 'sets default disabled attributes' do
- expect(rendered).to have_selector('[data-disabled="false"]')
- end
-
- it 'sets default is-loading attributes' do
- expect(rendered).to have_selector('[data-is-loading="false"]')
- end
-
- it 'does not set a label' do
- expect(rendered).not_to have_selector('[data-label]')
- end
-
- it 'does not set a label position' do
- expect(rendered).not_to have_selector('[data-label-position]')
- end
- end
-
- context 'with custom options' do
- before do
- render partial: 'shared/gl_toggle', locals: {
- classes: 'js-custom-gl-toggle',
- name: 'toggle-name',
- is_checked: true,
- disabled: true,
- is_loading: true,
- label: 'Custom label',
- label_position: 'top',
- data: {
- foo: 'bar'
- }
- }
- end
-
- it 'sets the custom class' do
- expect(rendered).to have_selector('.js-custom-gl-toggle')
- end
-
- it 'sets the custom name' do
- expect(rendered).to have_selector('[data-name="toggle-name"]')
- end
-
- it 'sets the custom is-checked attributes' do
- expect(rendered).to have_selector('[data-is-checked="true"]')
- end
-
- it 'sets the custom disabled attributes' do
- expect(rendered).to have_selector('[data-disabled="true"]')
- end
-
- it 'sets the custom is-loading attributes' do
- expect(rendered).to have_selector('[data-is-loading="true"]')
- end
-
- it 'sets the custom label' do
- expect(rendered).to have_selector('[data-label="Custom label"]')
- end
-
- it 'sets the cutom label position' do
- expect(rendered).to have_selector('[data-label-position="top"]')
- end
-
- it 'sets cutom data attributes' do
- expect(rendered).to have_selector('[data-foo="bar"]')
- end
- end
-end
diff --git a/spec/views/shared/_global_alert.html.haml_spec.rb b/spec/views/shared/_global_alert.html.haml_spec.rb
index 84198cbb75e..a400d5b39b0 100644
--- a/spec/views/shared/_global_alert.html.haml_spec.rb
+++ b/spec/views/shared/_global_alert.html.haml_spec.rb
@@ -43,33 +43,4 @@ RSpec.describe 'shared/_global_alert.html.haml' do
expect(rendered).not_to have_selector('.gl-dismiss-btn')
end
end
-
- context 'fixed layout' do
- before do
- allow(view).to receive(:fluid_layout).and_return(false)
- end
-
- it 'adds container classes' do
- render
-
- expect(rendered).to have_selector('.container-fluid.container-limited')
- end
-
- it 'does not add container classes if is_contained is true' do
- render partial: 'shared/global_alert', locals: { is_contained: true }
-
- expect(rendered).not_to have_selector('.container-fluid.container-limited')
- end
- end
-
- context 'fluid layout' do
- before do
- allow(view).to receive(:fluid_layout).and_return(true)
- render
- end
-
- it 'does not add container classes' do
- expect(rendered).not_to have_selector('.container-fluid.container-limited')
- end
- end
end
diff --git a/spec/views/shared/issuable/_sidebar.html.haml_spec.rb b/spec/views/shared/issuable/_sidebar.html.haml_spec.rb
index 2097b8890cc..43a723dbb2c 100644
--- a/spec/views/shared/issuable/_sidebar.html.haml_spec.rb
+++ b/spec/views/shared/issuable/_sidebar.html.haml_spec.rb
@@ -11,7 +11,7 @@ RSpec.describe 'shared/issuable/_sidebar.html.haml' do
end
context 'project in a group' do
- let_it_be(:group) { create(:group) }
+ let_it_be(:group) { create(:group, :crm_enabled) }
let_it_be(:project) { create(:project, group: group) }
let_it_be(:issue) { create(:issue, project: project) }
let_it_be(:incident) { create(:incident, project: project) }
@@ -35,5 +35,34 @@ RSpec.describe 'shared/issuable/_sidebar.html.haml' do
expect(rendered).not_to have_css('[data-testid="escalation_status_container"]')
end
end
+
+ context 'crm contacts widget' do
+ let(:issuable) { issue }
+
+ context 'without permission' do
+ it 'is expected not to be shown' do
+ create(:contact, group: group)
+
+ expect(rendered).not_to have_css('#js-issue-crm-contacts')
+ end
+ end
+
+ context 'without contacts' do
+ it 'is expected not to be shown' do
+ group.add_developer(user)
+
+ expect(rendered).not_to have_css('#js-issue-crm-contacts')
+ end
+ end
+
+ context 'with permission and contacts' do
+ it 'is expected to be shown' do
+ create(:contact, group: group)
+ group.add_developer(user)
+
+ expect(rendered).to have_css('#js-issue-crm-contacts')
+ end
+ end
+ end
end
end
diff --git a/spec/views/shared/wikis/_sidebar.html.haml_spec.rb b/spec/views/shared/wikis/_sidebar.html.haml_spec.rb
index bf050d601e3..0e7b657a154 100644
--- a/spec/views/shared/wikis/_sidebar.html.haml_spec.rb
+++ b/spec/views/shared/wikis/_sidebar.html.haml_spec.rb
@@ -31,7 +31,7 @@ RSpec.describe 'shared/wikis/_sidebar.html.haml' do
context 'The sidebar comes from a custom page' do
before do
- assign(:sidebar_page, double('WikiPage', path: 'sidebar.md', slug: 'sidebar', content: 'Some sidebar content'))
+ assign(:sidebar_page, double('WikiPage', path: 'sidebar.md', slug: 'sidebar', content: 'Some sidebar content', wiki: wiki))
end
it 'does not show an alert' do
diff --git a/spec/workers/bulk_imports/export_request_worker_spec.rb b/spec/workers/bulk_imports/export_request_worker_spec.rb
index f838bff528c..4f452e3dd60 100644
--- a/spec/workers/bulk_imports/export_request_worker_spec.rb
+++ b/spec/workers/bulk_imports/export_request_worker_spec.rb
@@ -28,6 +28,31 @@ RSpec.describe BulkImports::ExportRequestWorker do
perform_multiple(job_args)
end
+
+ context 'when network error is raised' do
+ it 'logs export failure and marks entity as failed' do
+ expect_next_instance_of(BulkImports::Clients::HTTP) do |client|
+ expect(client).to receive(:post).and_raise(BulkImports::NetworkError, 'Export error').twice
+ end
+
+ expect(Gitlab::Import::Logger).to receive(:warn).with(
+ bulk_import_entity_id: entity.id,
+ pipeline_class: 'ExportRequestWorker',
+ exception_class: 'BulkImports::NetworkError',
+ exception_message: 'Export error',
+ correlation_id_value: anything,
+ bulk_import_id: bulk_import.id,
+ bulk_import_entity_type: entity.source_type
+ ).twice
+
+ perform_multiple(job_args)
+
+ failure = entity.failures.last
+
+ expect(failure.pipeline_class).to eq('ExportRequestWorker')
+ expect(failure.exception_message).to eq('Export error')
+ end
+ end
end
end
diff --git a/spec/workers/bulk_imports/pipeline_worker_spec.rb b/spec/workers/bulk_imports/pipeline_worker_spec.rb
index 2da9195a6ef..cb7e70a6749 100644
--- a/spec/workers/bulk_imports/pipeline_worker_spec.rb
+++ b/spec/workers/bulk_imports/pipeline_worker_spec.rb
@@ -136,6 +136,34 @@ RSpec.describe BulkImports::PipelineWorker do
expect(pipeline_tracker.jid).to eq('jid')
end
+ context 'when entity is failed' do
+ it 'marks tracker as failed and logs the error' do
+ pipeline_tracker = create(
+ :bulk_import_tracker,
+ entity: entity,
+ pipeline_name: 'Pipeline',
+ status_event: 'enqueue'
+ )
+
+ entity.update!(status: -1)
+
+ expect_next_instance_of(Gitlab::Import::Logger) do |logger|
+ expect(logger)
+ .to receive(:error)
+ .with(
+ worker: described_class.name,
+ pipeline_name: 'Pipeline',
+ entity_id: entity.id,
+ message: 'Failed entity status'
+ )
+ end
+
+ subject.perform(pipeline_tracker.id, pipeline_tracker.stage, entity.id)
+
+ expect(pipeline_tracker.reload.status_name).to eq(:failed)
+ end
+ end
+
context 'when it is a network error' do
it 'reenqueue on retriable network errors' do
pipeline_tracker = create(
diff --git a/spec/workers/database/batched_background_migration/ci_database_worker_spec.rb b/spec/workers/database/batched_background_migration/ci_database_worker_spec.rb
new file mode 100644
index 00000000000..2663c650986
--- /dev/null
+++ b/spec/workers/database/batched_background_migration/ci_database_worker_spec.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Database::BatchedBackgroundMigration::CiDatabaseWorker, :clean_gitlab_redis_shared_state do
+ it_behaves_like 'it runs batched background migration jobs', 'ci'
+end
diff --git a/spec/workers/database/batched_background_migration_worker_spec.rb b/spec/workers/database/batched_background_migration_worker_spec.rb
index b13d1f5c7aa..a6c7db60abe 100644
--- a/spec/workers/database/batched_background_migration_worker_spec.rb
+++ b/spec/workers/database/batched_background_migration_worker_spec.rb
@@ -2,120 +2,6 @@
require 'spec_helper'
-RSpec.describe Database::BatchedBackgroundMigrationWorker, '#perform', :clean_gitlab_redis_shared_state do
- include ExclusiveLeaseHelpers
-
- let(:worker) { described_class.new }
-
- context 'when the feature flag is disabled' do
- before do
- stub_feature_flags(execute_batched_migrations_on_schedule: false)
- end
-
- it 'does nothing' do
- expect(worker).not_to receive(:active_migration)
- expect(worker).not_to receive(:run_active_migration)
-
- worker.perform
- end
- end
-
- context 'when the feature flag is enabled' do
- before do
- stub_feature_flags(execute_batched_migrations_on_schedule: true)
-
- allow(Gitlab::Database::BackgroundMigration::BatchedMigration).to receive(:active_migration).and_return(nil)
- end
-
- context 'when no active migrations exist' do
- it 'does nothing' do
- expect(worker).not_to receive(:run_active_migration)
-
- worker.perform
- end
- end
-
- context 'when active migrations exist' do
- let(:job_interval) { 5.minutes }
- let(:lease_timeout) { 15.minutes }
- let(:lease_key) { 'batched_background_migration_worker' }
- let(:migration) { build(:batched_background_migration, :active, interval: job_interval) }
- let(:interval_variance) { described_class::INTERVAL_VARIANCE }
-
- before do
- allow(Gitlab::Database::BackgroundMigration::BatchedMigration).to receive(:active_migration)
- .and_return(migration)
-
- allow(migration).to receive(:interval_elapsed?).with(variance: interval_variance).and_return(true)
- allow(migration).to receive(:reload)
- end
-
- context 'when the reloaded migration is no longer active' do
- it 'does not run the migration' do
- expect_to_obtain_exclusive_lease(lease_key, timeout: lease_timeout)
-
- expect(migration).to receive(:reload)
- expect(migration).to receive(:active?).and_return(false)
-
- expect(worker).not_to receive(:run_active_migration)
-
- worker.perform
- end
- end
-
- context 'when the interval has not elapsed' do
- it 'does not run the migration' do
- expect_to_obtain_exclusive_lease(lease_key, timeout: lease_timeout)
-
- expect(migration).to receive(:interval_elapsed?).with(variance: interval_variance).and_return(false)
-
- expect(worker).not_to receive(:run_active_migration)
-
- worker.perform
- end
- end
-
- context 'when the reloaded migration is still active and the interval has elapsed' do
- it 'runs the migration' do
- expect_to_obtain_exclusive_lease(lease_key, timeout: lease_timeout)
-
- expect_next_instance_of(Gitlab::Database::BackgroundMigration::BatchedMigrationRunner) do |instance|
- expect(instance).to receive(:run_migration_job).with(migration)
- end
-
- expect(worker).to receive(:run_active_migration).and_call_original
-
- worker.perform
- end
- end
-
- context 'when the calculated timeout is less than the minimum allowed' do
- let(:minimum_timeout) { described_class::MINIMUM_LEASE_TIMEOUT }
- let(:job_interval) { 2.minutes }
-
- it 'sets the lease timeout to the minimum value' do
- expect_to_obtain_exclusive_lease(lease_key, timeout: minimum_timeout)
-
- expect_next_instance_of(Gitlab::Database::BackgroundMigration::BatchedMigrationRunner) do |instance|
- expect(instance).to receive(:run_migration_job).with(migration)
- end
-
- expect(worker).to receive(:run_active_migration).and_call_original
-
- worker.perform
- end
- end
-
- it 'always cleans up the exclusive lease' do
- lease = stub_exclusive_lease_taken(lease_key, timeout: lease_timeout)
-
- expect(lease).to receive(:try_obtain).and_return(true)
-
- expect(worker).to receive(:run_active_migration).and_raise(RuntimeError, 'I broke')
- expect(lease).to receive(:cancel)
-
- expect { worker.perform }.to raise_error(RuntimeError, 'I broke')
- end
- end
- end
+RSpec.describe Database::BatchedBackgroundMigrationWorker do
+ it_behaves_like 'it runs batched background migration jobs', :main
end
diff --git a/spec/workers/deployments/hooks_worker_spec.rb b/spec/workers/deployments/hooks_worker_spec.rb
index 50ead66cfbf..29b3e8d3ee4 100644
--- a/spec/workers/deployments/hooks_worker_spec.rb
+++ b/spec/workers/deployments/hooks_worker_spec.rb
@@ -13,7 +13,7 @@ RSpec.describe Deployments::HooksWorker do
it 'executes project services for deployment_hooks' do
deployment = create(:deployment, :running)
project = deployment.project
- service = create(:integration, type: 'SlackService', project: project, deployment_events: true, active: true)
+ service = create(:integrations_slack, project: project, deployment_events: true)
expect(ProjectServiceWorker).to receive(:perform_async).with(service.id, an_instance_of(Hash))
@@ -23,7 +23,7 @@ RSpec.describe Deployments::HooksWorker do
it 'does not execute an inactive service' do
deployment = create(:deployment, :running)
project = deployment.project
- create(:integration, type: 'SlackService', project: project, deployment_events: true, active: false)
+ create(:integrations_slack, project: project, deployment_events: true, active: false)
expect(ProjectServiceWorker).not_to receive(:perform_async)
diff --git a/spec/workers/every_sidekiq_worker_spec.rb b/spec/workers/every_sidekiq_worker_spec.rb
index 1cd5d23d8fc..47205943f70 100644
--- a/spec/workers/every_sidekiq_worker_spec.rb
+++ b/spec/workers/every_sidekiq_worker_spec.rb
@@ -395,6 +395,7 @@ RSpec.describe 'Every Sidekiq worker' do
'Projects::PostCreationWorker' => 3,
'Projects::ScheduleBulkRepositoryShardMovesWorker' => 3,
'Projects::UpdateRepositoryStorageWorker' => 3,
+ 'Projects::RefreshBuildArtifactsSizeStatisticsWorker' => 0,
'Prometheus::CreateDefaultAlertsWorker' => 3,
'PropagateIntegrationGroupWorker' => 3,
'PropagateIntegrationInheritDescendantWorker' => 3,
diff --git a/spec/workers/loose_foreign_keys/cleanup_worker_spec.rb b/spec/workers/loose_foreign_keys/cleanup_worker_spec.rb
index 6f4389a7541..1814abfac1d 100644
--- a/spec/workers/loose_foreign_keys/cleanup_worker_spec.rb
+++ b/spec/workers/loose_foreign_keys/cleanup_worker_spec.rb
@@ -102,8 +102,22 @@ RSpec.describe LooseForeignKeys::CleanupWorker do
loose_fk_parent_table_2.delete_all
end
+ def perform_for(db:)
+ time = Time.current.midnight
+
+ if db == :main
+ time += 2.minutes
+ elsif db == :ci
+ time += 3.minutes
+ end
+
+ travel_to(time) do
+ described_class.new.perform
+ end
+ end
+
it 'cleans up all rows' do
- described_class.new.perform
+ perform_for(db: :main)
expect(loose_fk_child_table_1_1.count).to eq(0)
expect(loose_fk_child_table_1_2.where(parent_id_with_different_column: nil).count).to eq(4)
@@ -118,7 +132,7 @@ RSpec.describe LooseForeignKeys::CleanupWorker do
it 'cleans up all rows' do
expect(LooseForeignKeys::BatchCleanerService).to receive(:new).exactly(:twice).and_call_original
- described_class.new.perform
+ perform_for(db: :main)
expect(loose_fk_child_table_1_1.count).to eq(0)
expect(loose_fk_child_table_1_2.where(parent_id_with_different_column: nil).count).to eq(4)
@@ -137,25 +151,40 @@ RSpec.describe LooseForeignKeys::CleanupWorker do
end
it 'cleans up 2 rows' do
- expect { described_class.new.perform }.to change { count_deletable_rows }.by(-2)
+ expect { perform_for(db: :main) }.to change { count_deletable_rows }.by(-2)
end
end
describe 'multi-database support' do
- where(:current_minute, :configured_base_models, :expected_connection) do
- 2 | { main: ApplicationRecord, ci: Ci::ApplicationRecord } | ApplicationRecord.connection
- 3 | { main: ApplicationRecord, ci: Ci::ApplicationRecord } | Ci::ApplicationRecord.connection
- 2 | { main: ApplicationRecord } | ApplicationRecord.connection
- 3 | { main: ApplicationRecord } | ApplicationRecord.connection
+ where(:current_minute, :configured_base_models, :expected_connection_model) do
+ 2 | { main: 'ApplicationRecord', ci: 'Ci::ApplicationRecord' } | 'ApplicationRecord'
+ 3 | { main: 'ApplicationRecord', ci: 'Ci::ApplicationRecord' } | 'Ci::ApplicationRecord'
+ 2 | { main: 'ApplicationRecord' } | 'ApplicationRecord'
+ 3 | { main: 'ApplicationRecord' } | 'ApplicationRecord'
end
with_them do
+ let(:database_base_models) { configured_base_models.transform_values(&:constantize) }
+
+ let(:expected_connection) { expected_connection_model.constantize.connection }
+
before do
- allow(Gitlab::Database).to receive(:database_base_models).and_return(configured_base_models)
+ allow(Gitlab::Database).to receive(:database_base_models).and_return(database_base_models)
+
+ if database_base_models.has_key?(:ci)
+ Gitlab::Database::SharedModel.using_connection(database_base_models[:ci].connection) do
+ LooseForeignKeys::DeletedRecord.create!(fully_qualified_table_name: 'public._test_loose_fk_parent_table_1', primary_key_value: 999)
+ LooseForeignKeys::DeletedRecord.create!(fully_qualified_table_name: 'public._test_loose_fk_parent_table_1', primary_key_value: 9991)
+ end
+ end
end
it 'uses the correct connection' do
- LooseForeignKeys::DeletedRecord.count.times do
+ record_count = Gitlab::Database::SharedModel.using_connection(expected_connection) do
+ LooseForeignKeys::DeletedRecord.count
+ end
+
+ record_count.times do
expect_next_found_instance_of(LooseForeignKeys::DeletedRecord) do |instance|
expect(instance.class.connection).to eq(expected_connection)
end
diff --git a/spec/workers/projects/refresh_build_artifacts_size_statistics_worker_spec.rb b/spec/workers/projects/refresh_build_artifacts_size_statistics_worker_spec.rb
new file mode 100644
index 00000000000..4a6a525a5a7
--- /dev/null
+++ b/spec/workers/projects/refresh_build_artifacts_size_statistics_worker_spec.rb
@@ -0,0 +1,96 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Projects::RefreshBuildArtifactsSizeStatisticsWorker do
+ let(:worker) { described_class.new }
+
+ describe '#perform_work' do
+ before do
+ expect_next_instance_of(Projects::RefreshBuildArtifactsSizeStatisticsService) do |instance|
+ expect(instance).to receive(:execute).and_return(refresh)
+ end
+ end
+
+ context 'when refresh job is present' do
+ let(:refresh) do
+ build(
+ :project_build_artifacts_size_refresh,
+ :running,
+ project_id: 77,
+ last_job_artifact_id: 123
+ )
+ end
+
+ it 'logs refresh information' do
+ expect(worker).to receive(:log_extra_metadata_on_done).with(:project_id, refresh.project_id)
+ expect(worker).to receive(:log_extra_metadata_on_done).with(:last_job_artifact_id, refresh.last_job_artifact_id)
+ expect(worker).to receive(:log_extra_metadata_on_done).with(:last_batch, refresh.destroyed?)
+ expect(worker).to receive(:log_extra_metadata_on_done).with(:refresh_started_at, refresh.refresh_started_at)
+
+ worker.perform_work
+ end
+ end
+
+ context 'when refresh job is not present' do
+ let(:refresh) { nil }
+
+ it 'logs refresh information' do
+ expect(worker).not_to receive(:log_extra_metadata_on_done)
+
+ worker.perform_work
+ end
+ end
+ end
+
+ describe '#remaining_work_count' do
+ subject { worker.remaining_work_count }
+
+ context 'and there are remaining refresh jobs' do
+ before do
+ create_list(:project_build_artifacts_size_refresh, 2, :pending)
+ end
+
+ it { is_expected.to eq(1) }
+ end
+
+ context 'and there are no remaining refresh jobs' do
+ it { is_expected.to eq(0) }
+ end
+ end
+
+ describe '#max_running_jobs' do
+ subject { worker.max_running_jobs }
+
+ context 'when all projects_build_artifacts_size_refresh flags are enabled' do
+ it { is_expected.to eq(described_class::MAX_RUNNING_HIGH) }
+ end
+
+ context 'when projects_build_artifacts_size_refresh_high flags is disabled' do
+ before do
+ stub_feature_flags(projects_build_artifacts_size_refresh_high: false)
+ end
+
+ it { is_expected.to eq(described_class::MAX_RUNNING_MEDIUM) }
+ end
+
+ context 'when projects_build_artifacts_size_refresh_high and projects_build_artifacts_size_refresh_medium flags are disabled' do
+ before do
+ stub_feature_flags(projects_build_artifacts_size_refresh_high: false)
+ stub_feature_flags(projects_build_artifacts_size_refresh_medium: false)
+ end
+
+ it { is_expected.to eq(described_class::MAX_RUNNING_LOW) }
+ end
+
+ context 'when all projects_build_artifacts_size_refresh flags are disabled' do
+ before do
+ stub_feature_flags(projects_build_artifacts_size_refresh_low: false)
+ stub_feature_flags(projects_build_artifacts_size_refresh_medium: false)
+ stub_feature_flags(projects_build_artifacts_size_refresh_high: false)
+ end
+
+ it { is_expected.to eq(0) }
+ end
+ end
+end
diff --git a/spec/workers/projects/schedule_refresh_build_artifacts_size_statistics_worker_spec.rb b/spec/workers/projects/schedule_refresh_build_artifacts_size_statistics_worker_spec.rb
new file mode 100644
index 00000000000..b5775f37678
--- /dev/null
+++ b/spec/workers/projects/schedule_refresh_build_artifacts_size_statistics_worker_spec.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Projects::ScheduleRefreshBuildArtifactsSizeStatisticsWorker do
+ subject(:worker) { described_class.new }
+
+ describe '#perform' do
+ include_examples 'an idempotent worker' do
+ it 'schedules Projects::RefreshBuildArtifactsSizeStatisticsWorker to be performed with capacity' do
+ expect(Projects::RefreshBuildArtifactsSizeStatisticsWorker).to receive(:perform_with_capacity).twice
+
+ subject
+ end
+ end
+ end
+end
diff --git a/spec/workers/quality/test_data_cleanup_worker_spec.rb b/spec/workers/quality/test_data_cleanup_worker_spec.rb
new file mode 100644
index 00000000000..a17e6e0cb1a
--- /dev/null
+++ b/spec/workers/quality/test_data_cleanup_worker_spec.rb
@@ -0,0 +1,44 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Quality::TestDataCleanupWorker do
+ subject { described_class.new }
+
+ shared_examples 'successful deletion' do
+ before do
+ allow(Gitlab).to receive(:staging?).and_return(true)
+ end
+
+ it 'removes test groups' do
+ expect { subject.perform }.to change(Group, :count).by(-test_group_count)
+ end
+ end
+
+ describe "#perform" do
+ context 'with multiple test groups to remove' do
+ let(:test_group_count) { 5 }
+ let!(:groups_to_remove) { create_list(:group, test_group_count, :test_group) }
+ let!(:group_to_keep) { create(:group, path: 'test-group-fulfillment-keep', created_at: 1.day.ago) }
+ let!(:non_test_group) { create(:group) }
+ let(:non_test_owner_group) { create(:group, path: 'test-group-fulfillment1234', created_at: 4.days.ago) }
+
+ before do
+ non_test_owner_group.add_owner(create(:user))
+ end
+
+ it_behaves_like 'successful deletion'
+ end
+
+ context 'with paid groups' do
+ let(:test_group_count) { 1 }
+ let!(:paid_group) { create(:group, :test_group) }
+
+ before do
+ allow(paid_group).to receive(:paid?).and_return(true)
+ end
+
+ it_behaves_like 'successful deletion'
+ end
+ end
+end
diff --git a/spec/workers/web_hook_worker_spec.rb b/spec/workers/web_hook_worker_spec.rb
index dbdf7a2b978..e2ff36975c4 100644
--- a/spec/workers/web_hook_worker_spec.rb
+++ b/spec/workers/web_hook_worker_spec.rb
@@ -28,15 +28,6 @@ RSpec.describe WebHookWorker do
.to change { Gitlab::WebHooks::RecursionDetection::UUID.instance.request_uuid }.to(uuid)
end
- it 'retrieves recursion detection data, reinstates it, and cleans it from payload when passed through as data', :request_store, :aggregate_failures do
- uuid = SecureRandom.uuid
- full_data = data.merge({ _gitlab_recursion_detection_request_uuid: uuid })
-
- expect_next(WebHookService, project_hook, data.with_indifferent_access, hook_name, anything).to receive(:execute)
- expect { subject.perform(project_hook.id, full_data, hook_name) }
- .to change { Gitlab::WebHooks::RecursionDetection::UUID.instance.request_uuid }.to(uuid)
- end
-
it_behaves_like 'worker with data consistency',
described_class,
data_consistency: :delayed
diff --git a/storybook/config/webpack.config.js b/storybook/config/webpack.config.js
index 9d630dca970..51aaa1e18a6 100644
--- a/storybook/config/webpack.config.js
+++ b/storybook/config/webpack.config.js
@@ -2,13 +2,41 @@
const { statSync } = require('fs');
const path = require('path');
-const sass = require('node-sass'); // eslint-disable-line import/no-unresolved
-const { buildIncludePaths, resolveGlobUrl } = require('node-sass-magic-importer/dist/toolbox'); // eslint-disable-line import/no-unresolved
+const glob = require('glob');
+const sass = require('sass');
const webpack = require('webpack');
const IS_EE = require('../../config/helpers/is_ee_env');
const IS_JH = require('../../config/helpers/is_jh_env');
const gitlabWebpackConfig = require('../../config/webpack.config');
+const buildIncludePaths = (nodeSassIncludePaths, previouslyResolvedPath) => {
+ const includePaths = [];
+ if (path.isAbsolute(previouslyResolvedPath)) {
+ includePaths.push(path.dirname(previouslyResolvedPath));
+ }
+ return [...new Set([...includePaths, ...nodeSassIncludePaths.split(path.delimiter)])];
+};
+
+const resolveGlobUrl = (url, includePaths = []) => {
+ const filePaths = new Set();
+ if (glob.hasMagic(url)) {
+ includePaths.forEach((includePath) => {
+ const globPaths = glob.sync(url, { cwd: includePath });
+ globPaths.forEach((relativePath) => {
+ filePaths.add(
+ path
+ .resolve(includePath, relativePath)
+ // This fixes a problem with importing absolute paths on windows.
+ .split(`\\`)
+ .join(`/`),
+ );
+ });
+ });
+ return [...filePaths];
+ }
+ return null;
+};
+
const ROOT = path.resolve(__dirname, '../../');
const TRANSPARENT_1X1_PNG =
'url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==)';
diff --git a/storybook/package.json b/storybook/package.json
index 48083ed1ce3..f47b16b2eab 100644
--- a/storybook/package.json
+++ b/storybook/package.json
@@ -15,9 +15,8 @@
"@storybook/addon-essentials": "^6.2.9",
"@storybook/vue": "6.2.9",
"graphql-tag": "^2.12.5",
- "node-sass": "^4.14.1",
- "node-sass-magic-importer": "^5.3.2",
"postcss-loader": "3.0.0",
+ "sass": "^1.49.9",
"sass-loader": "^7.1.0",
"storybook-mirage": "^0.0.4"
}
diff --git a/storybook/yarn.lock b/storybook/yarn.lock
index d63618ebc65..39beb793906 100644
--- a/storybook/yarn.lock
+++ b/storybook/yarn.lock
@@ -2459,11 +2459,6 @@
resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d"
integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==
-abbrev@1:
- version "1.1.1"
- resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8"
- integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==
-
accepts@~1.3.7:
version "1.3.7"
resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd"
@@ -2538,7 +2533,7 @@ ajv-keywords@^3.1.0, ajv-keywords@^3.4.1, ajv-keywords@^3.5.2:
resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d"
integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==
-ajv@^6.1.0, ajv@^6.10.2, ajv@^6.12.2, ajv@^6.12.3, ajv@^6.12.4, ajv@^6.12.5:
+ajv@^6.1.0, ajv@^6.10.2, ajv@^6.12.2, ajv@^6.12.4, ajv@^6.12.5:
version "6.12.6"
resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4"
integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==
@@ -2548,11 +2543,6 @@ ajv@^6.1.0, ajv@^6.10.2, ajv@^6.12.2, ajv@^6.12.3, ajv@^6.12.4, ajv@^6.12.5:
json-schema-traverse "^0.4.1"
uri-js "^4.2.2"
-amdefine@>=0.0.4:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5"
- integrity sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=
-
ansi-align@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-3.0.0.tgz#b536b371cf687caaef236c18d3e21fe3797467cb"
@@ -2590,12 +2580,7 @@ ansi-regex@^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"
- integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=
-
-ansi-styles@^3.2.0, ansi-styles@^3.2.1:
+ansi-styles@^3.2.1:
version "3.2.1"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d"
integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==
@@ -2624,7 +2609,7 @@ anymatch@^2.0.0:
micromatch "^3.1.4"
normalize-path "^2.1.1"
-anymatch@^3.0.0, anymatch@^3.0.3, anymatch@~3.1.1:
+anymatch@^3.0.0, anymatch@^3.0.3, anymatch@~3.1.1, anymatch@~3.1.2:
version "3.1.2"
resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716"
integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==
@@ -2672,11 +2657,6 @@ arr-union@^3.1.0:
resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4"
integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=
-array-find-index@^1.0.1:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1"
- integrity sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=
-
array-flatten@1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2"
@@ -2765,23 +2745,11 @@ asn1.js@^5.2.0:
minimalistic-assert "^1.0.0"
safer-buffer "^2.1.0"
-asn1@~0.2.3:
- version "0.2.4"
- resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136"
- integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==
- dependencies:
- safer-buffer "~2.1.0"
-
assert-never@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/assert-never/-/assert-never-1.2.1.tgz#11f0e363bf146205fb08193b5c7b90f4d1cf44fe"
integrity sha512-TaTivMB6pYI1kXwrFlEhLeGfOqoDNdTxjCdwRfFFkEA30Eu+k48W34nlok2EYWJfFFzqaEmichdNM7th6M5HNw==
-assert-plus@1.0.0, assert-plus@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525"
- integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=
-
assert@^1.1.1:
version "1.5.0"
resolved "https://registry.yarnpkg.com/assert/-/assert-1.5.0.tgz#55c109aaf6e0aefdb3dc4b71240c70bf574b18eb"
@@ -2812,11 +2780,6 @@ async-each@^1.0.1:
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"
- integrity sha1-NhIfhFwFeBct5Bmpfb6x0W7DRUI=
-
asynckit@^0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
@@ -2845,16 +2808,6 @@ autoprefixer@^9.8.6:
postcss "^7.0.32"
postcss-value-parser "^4.1.0"
-aws-sign2@~0.7.0:
- version "0.7.0"
- resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8"
- integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=
-
-aws4@^1.8.0:
- version "1.11.0"
- resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.11.0.tgz#d61f46d83b2519250e2784daf5b09479a8b41c59"
- integrity sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==
-
axe-core@^4.1.1:
version "4.2.1"
resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.2.1.tgz#2e50bcf10ee5b819014f6e342e41e45096239e34"
@@ -3019,13 +2972,6 @@ batch-processor@1.0.0:
resolved "https://registry.yarnpkg.com/batch-processor/-/batch-processor-1.0.0.tgz#75c95c32b748e0850d10c2b168f6bdbe9891ace8"
integrity sha1-dclcMrdI4IUNEMKxaPa9vpiRrOg=
-bcrypt-pbkdf@^1.0.0:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e"
- integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=
- dependencies:
- tweetnacl "^0.14.3"
-
better-opn@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/better-opn/-/better-opn-2.1.1.tgz#94a55b4695dc79288f31d7d0e5f658320759f7c6"
@@ -3055,13 +3001,6 @@ bindings@^1.5.0:
dependencies:
file-uri-to-path "1.0.0"
-block-stream@*:
- version "0.0.9"
- resolved "https://registry.yarnpkg.com/block-stream/-/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a"
- integrity sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=
- dependencies:
- inherits "~2.0.0"
-
bluebird@^3.3.5, bluebird@^3.5.5, bluebird@^3.7.2:
version "3.7.2"
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f"
@@ -3362,14 +3301,6 @@ callsites@^3.0.0:
resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73"
integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==
-camel-case@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-3.0.0.tgz#ca3c3688a4e9cf3a4cda777dc4dcbc713249cf73"
- integrity sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M=
- dependencies:
- no-case "^2.2.0"
- upper-case "^1.1.1"
-
camel-case@^4.1.1:
version "4.1.2"
resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-4.1.2.tgz#9728072a954f805228225a6deea6b38461e1bd5a"
@@ -3383,20 +3314,7 @@ camelcase-css@2.0.1:
resolved "https://registry.yarnpkg.com/camelcase-css/-/camelcase-css-2.0.1.tgz#ee978f6947914cc30c6b44741b6ed1df7f043fd5"
integrity sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==
-camelcase-keys@^2.0.0:
- version "2.1.0"
- resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7"
- integrity sha1-MIvur/3ygRkFHvodkyITyRuPkuc=
- dependencies:
- camelcase "^2.0.0"
- map-obj "^1.0.0"
-
-camelcase@^2.0.0:
- version "2.1.1"
- resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f"
- integrity sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=
-
-camelcase@^5.0.0, camelcase@^5.3.1:
+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==
@@ -3418,11 +3336,6 @@ case-sensitive-paths-webpack-plugin@^2.3.0:
resolved "https://registry.yarnpkg.com/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.4.0.tgz#db64066c6422eed2e08cc14b986ca43796dbc6d4"
integrity sha512-roIFONhcxog0JSSWbvVAh3OocukmSgpqOH6YpMkCvav/ySIV3JKg4Dc8vYtQjYi/UxpNE36r/9v+VqTQqgkYmw==
-caseless@~0.12.0:
- version "0.12.0"
- resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
- integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=
-
ccount@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/ccount/-/ccount-1.1.0.tgz#246687debb6014735131be8abab2d93898f8d043"
@@ -3437,17 +3350,6 @@ chalk@2.4.2, chalk@^2.0.0, chalk@^2.4.1, chalk@^2.4.2:
escape-string-regexp "^1.0.5"
supports-color "^5.3.0"
-chalk@^1.1.1:
- version "1.1.3"
- resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98"
- integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=
- dependencies:
- ansi-styles "^2.2.1"
- escape-string-regexp "^1.0.2"
- has-ansi "^2.0.0"
- 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"
@@ -3464,30 +3366,6 @@ chalk@^4.0.0, chalk@^4.1.0:
ansi-styles "^4.1.0"
supports-color "^7.1.0"
-change-case@^3.0.1:
- version "3.1.0"
- resolved "https://registry.yarnpkg.com/change-case/-/change-case-3.1.0.tgz#0e611b7edc9952df2e8513b27b42de72647dd17e"
- integrity sha512-2AZp7uJZbYEzRPsFoa+ijKdvp9zsrnnt6+yFokfwEpeJm0xuJDVoxiRCAaTzyJND8GJkofo2IcKWaUZ/OECVzw==
- dependencies:
- camel-case "^3.0.0"
- constant-case "^2.0.0"
- dot-case "^2.1.0"
- header-case "^1.0.0"
- is-lower-case "^1.1.0"
- is-upper-case "^1.1.0"
- lower-case "^1.1.1"
- lower-case-first "^1.0.0"
- no-case "^2.3.2"
- param-case "^2.1.0"
- pascal-case "^2.0.0"
- path-case "^2.1.0"
- sentence-case "^2.1.0"
- snake-case "^2.1.0"
- swap-case "^1.1.0"
- title-case "^2.1.0"
- upper-case "^1.1.1"
- upper-case-first "^1.1.0"
-
character-entities-legacy@^1.0.0:
version "1.1.4"
resolved "https://registry.yarnpkg.com/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz#94bc1845dce70a5bb9d2ecc748725661293d8fc1"
@@ -3510,6 +3388,21 @@ character-reference-invalid@^1.0.0:
resolved "https://registry.yarnpkg.com/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz#083329cda0eae272ab3dbbf37e9a382c13af1560"
integrity sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==
+"chokidar@>=3.0.0 <4.0.0":
+ version "3.5.3"
+ resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd"
+ integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==
+ dependencies:
+ anymatch "~3.1.2"
+ braces "~3.0.2"
+ glob-parent "~5.1.2"
+ is-binary-path "~2.1.0"
+ is-glob "~4.0.1"
+ normalize-path "~3.0.0"
+ readdirp "~3.6.0"
+ optionalDependencies:
+ fsevents "~2.3.2"
+
chokidar@^2.1.8:
version "2.1.8"
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.8.tgz#804b3a7b6a99358c3c5c61e71d8728f041cff917"
@@ -3623,15 +3516,6 @@ clipboard@^2.0.0:
select "^1.1.2"
tiny-emitter "^2.0.0"
-cliui@^5.0.0:
- version "5.0.0"
- resolved "https://registry.yarnpkg.com/cliui/-/cliui-5.0.0.tgz#deefcfdb2e800784aa34f46fa08e06851c7bbbc5"
- integrity sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==
- dependencies:
- string-width "^3.1.0"
- strip-ansi "^5.2.0"
- wrap-ansi "^5.1.0"
-
clone-deep@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-4.0.1.tgz#c19fd9bdbbf85942b4fd979c84dcf7d5f07c2387"
@@ -3698,7 +3582,7 @@ colors@^1.1.2:
resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78"
integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==
-combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6:
+combined-stream@^1.0.8:
version "1.0.8"
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f"
integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==
@@ -3772,14 +3656,6 @@ consolidate@^0.16.0:
dependencies:
bluebird "^3.7.2"
-constant-case@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/constant-case/-/constant-case-2.0.0.tgz#4175764d389d3fa9c8ecd29186ed6005243b6a46"
- integrity sha1-QXV2TTidP6nI7NKRhu1gBSQ7akY=
- dependencies:
- snake-case "^2.1.0"
- upper-case "^1.1.1"
-
constantinople@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/constantinople/-/constantinople-4.0.1.tgz#0def113fa0e4dc8de83331a5cf79c8b325213151"
@@ -3864,7 +3740,7 @@ core-js@^3.0.4, core-js@^3.6.5, core-js@^3.8.2:
resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.13.1.tgz#30303fabd53638892062d8b4e802cac7599e9fb7"
integrity sha512-JqveUc4igkqwStL2RTRn/EPFGBOfEZHxJl/8ej1mXJR75V3go2mFF4bmUYkEIT1rveHKnkUlcJX/c+f1TyIovQ==
-core-util-is@1.0.2, core-util-is@~1.0.0:
+core-util-is@~1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=
@@ -3974,14 +3850,6 @@ cross-spawn@7.0.3:
shebang-command "^2.0.0"
which "^2.0.1"
-cross-spawn@^3.0.0:
- version "3.0.1"
- resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-3.0.1.tgz#1256037ecb9f0c5f79e3d6ef135e30770184b982"
- integrity sha1-ElYDfsufDF9549bvE14wdwGEuYI=
- dependencies:
- lru-cache "^4.0.1"
- which "^1.2.9"
-
cross-spawn@^6.0.0:
version "6.0.5"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4"
@@ -4029,14 +3897,6 @@ css-loader@^3.6.0:
schema-utils "^2.7.0"
semver "^6.3.0"
-css-node-extract@^2.1.3:
- version "2.1.3"
- resolved "https://registry.yarnpkg.com/css-node-extract/-/css-node-extract-2.1.3.tgz#ec388a857b8fdf13fefd94b3da733257162405da"
- integrity sha512-E7CzbC0I4uAs2dI8mPCVe+K37xuja5kjIugOotpwICFL7vzhmFMAPHvS/MF9gFrmv8DDUANsxrgyT/I3OLukcw==
- dependencies:
- change-case "^3.0.1"
- postcss "^6.0.14"
-
css-select@^2.0.2:
version "2.1.0"
resolved "https://registry.yarnpkg.com/css-select/-/css-select-2.1.0.tgz#6a34653356635934a81baca68d0255432105dbef"
@@ -4047,13 +3907,6 @@ css-select@^2.0.2:
domutils "^1.7.0"
nth-check "^1.0.2"
-css-selector-extract@^3.3.6:
- version "3.3.6"
- resolved "https://registry.yarnpkg.com/css-selector-extract/-/css-selector-extract-3.3.6.tgz#5cc670cfeae743015e80faf2d722d7818657e3e5"
- integrity sha512-bBI8ZJKKyR9iHvxXb4t3E6WTMkis94eINopVg7y2FmmMjLXUVduD7mPEcADi4i9FX4wOypFMFpySX+0keuefxg==
- dependencies:
- postcss "^6.0.14"
-
css-what@^3.2.1:
version "3.4.2"
resolved "https://registry.yarnpkg.com/css-what/-/css-what-3.4.2.tgz#ea7026fcb01777edbde52124e21f327e7ae950e4"
@@ -4074,25 +3927,11 @@ csstype@^3.0.2:
resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.8.tgz#d2266a792729fb227cd216fb572f43728e1ad340"
integrity sha512-jXKhWqXPmlUeoQnF/EhTtTl4C9SnrxSH/jZUih3jmO6lBKr99rP3/+FmrMj4EFpOXzMtXHAZkd3x0E6h6Fgflw==
-currently-unhandled@^0.4.1:
- version "0.4.1"
- resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea"
- integrity sha1-mI3zP+qxke95mmE2nddsF635V+o=
- dependencies:
- array-find-index "^1.0.1"
-
cyclist@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-1.0.1.tgz#596e9698fd0c80e12038c2b82d6eb1b35b6224d9"
integrity sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=
-dashdash@^1.12.0:
- version "1.14.1"
- resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0"
- integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=
- dependencies:
- assert-plus "^1.0.0"
-
debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0:
version "2.6.9"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
@@ -4114,11 +3953,6 @@ debug@^4.1.0, debug@^4.1.1:
dependencies:
ms "2.1.2"
-decamelize@^1.1.2, decamelize@^1.2.0:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290"
- integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=
-
decode-uri-component@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545"
@@ -4208,11 +4042,6 @@ detab@2.0.4:
dependencies:
repeat-string "^1.5.4"
-detect-file@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/detect-file/-/detect-file-1.0.0.tgz#f0d66d03672a825cb1b73bdb3fe62310c8e552b7"
- integrity sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=
-
detect-port-alt@1.1.6:
version "1.1.6"
resolved "https://registry.yarnpkg.com/detect-port-alt/-/detect-port-alt-1.1.6.tgz#24707deabe932d4a3cf621302027c2b266568275"
@@ -4314,13 +4143,6 @@ domutils@^1.5.1, domutils@^1.7.0:
dom-serializer "0"
domelementtype "1"
-dot-case@^2.1.0:
- version "2.1.1"
- resolved "https://registry.yarnpkg.com/dot-case/-/dot-case-2.1.1.tgz#34dcf37f50a8e93c2b3bca8bb7fb9155c7da3bee"
- integrity sha1-NNzzf1Co6TwrO8qLt/uRVcfaO+4=
- dependencies:
- no-case "^2.2.0"
-
dot-case@^3.0.4:
version "3.0.4"
resolved "https://registry.yarnpkg.com/dot-case/-/dot-case-3.0.4.tgz#9b2b670d00a431667a8a75ba29cd1b98809ce751"
@@ -4383,14 +4205,6 @@ duplexify@^3.4.2, duplexify@^3.6.0:
readable-stream "^2.0.0"
stream-shift "^1.0.0"
-ecc-jsbn@~0.1.1:
- version "0.1.2"
- resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9"
- integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=
- dependencies:
- jsbn "~0.1.0"
- safer-buffer "^2.1.0"
-
ee-first@1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
@@ -4488,7 +4302,7 @@ errno@^0.1.3, errno@~0.1.7:
dependencies:
prr "~1.0.1"
-error-ex@^1.2.0, error-ex@^1.3.1:
+error-ex@^1.3.1:
version "1.3.2"
resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf"
integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==
@@ -4570,7 +4384,7 @@ escape-string-regexp@2.0.0:
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344"
integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==
-escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5:
+escape-string-regexp@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=
@@ -4676,13 +4490,6 @@ expand-brackets@^2.1.4:
snapdragon "^0.8.1"
to-regex "^3.0.1"
-expand-tilde@^2.0.0, expand-tilde@^2.0.2:
- version "2.0.2"
- resolved "https://registry.yarnpkg.com/expand-tilde/-/expand-tilde-2.0.2.tgz#97e801aa052df02454de46b02bf621642cdc8502"
- integrity sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=
- dependencies:
- homedir-polyfill "^1.0.1"
-
express@^4.17.1:
version "4.17.1"
resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134"
@@ -4734,7 +4541,7 @@ extend-shallow@^3.0.0, extend-shallow@^3.0.2:
assign-symbols "^1.0.0"
is-extendable "^1.0.1"
-extend@^3.0.0, extend@~3.0.2:
+extend@^3.0.0:
version "3.0.2"
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa"
integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==
@@ -4753,16 +4560,6 @@ extglob@^2.0.4:
snapdragon "^0.8.1"
to-regex "^3.0.1"
-extsprintf@1.3.0:
- version "1.3.0"
- resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05"
- integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=
-
-extsprintf@^1.2.0:
- version "1.4.0"
- resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f"
- integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8=
-
fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3:
version "3.1.3"
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525"
@@ -4916,14 +4713,6 @@ find-up@4.1.0, find-up@^4.0.0, find-up@^4.1.0:
locate-path "^5.0.0"
path-exists "^4.0.0"
-find-up@^1.0.0:
- version "1.1.2"
- resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f"
- integrity sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=
- dependencies:
- path-exists "^2.0.0"
- pinkie-promise "^2.0.0"
-
find-up@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73"
@@ -4939,16 +4728,6 @@ find-up@^5.0.0:
locate-path "^6.0.0"
path-exists "^4.0.0"
-findup-sync@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-3.0.0.tgz#17b108f9ee512dfb7a5c7f3c8b27ea9e1a9c08d1"
- integrity sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg==
- dependencies:
- detect-file "^1.0.0"
- is-glob "^4.0.0"
- micromatch "^3.0.4"
- resolve-dir "^1.0.1"
-
flow-parser@0.*:
version "0.152.0"
resolved "https://registry.yarnpkg.com/flow-parser/-/flow-parser-0.152.0.tgz#a627aec1fdcfa243e2016469e44284a98169b996"
@@ -4967,11 +4746,6 @@ for-in@^1.0.2:
resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80"
integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=
-forever-agent@~0.6.1:
- version "0.6.1"
- resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
- integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=
-
fork-ts-checker-webpack-plugin@4.1.6, fork-ts-checker-webpack-plugin@^4.1.6:
version "4.1.6"
resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-4.1.6.tgz#5055c703febcf37fa06405d400c122b905167fc5"
@@ -5013,15 +4787,6 @@ form-data@^3.0.0:
combined-stream "^1.0.8"
mime-types "^2.1.12"
-form-data@~2.3.2:
- version "2.3.3"
- resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6"
- integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==
- dependencies:
- asynckit "^0.4.0"
- combined-stream "^1.0.6"
- mime-types "^2.1.12"
-
format@^0.2.0:
version "0.2.2"
resolved "https://registry.yarnpkg.com/format/-/format-0.2.2.tgz#d6170107e9efdc4ed30c9dc39016df942b5cb58b"
@@ -5108,21 +4873,11 @@ fsevents@^1.2.7:
bindings "^1.5.0"
nan "^2.12.1"
-fsevents@^2.1.2, fsevents@~2.3.1:
+fsevents@^2.1.2, fsevents@~2.3.1, fsevents@~2.3.2:
version "2.3.2"
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a"
integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==
-fstream@^1.0.0, fstream@^1.0.12:
- version "1.0.12"
- resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.12.tgz#4e8ba8ee2d48be4f7d0de505455548eae5932045"
- integrity sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==
- dependencies:
- graceful-fs "^4.1.2"
- inherits "~2.0.0"
- mkdirp ">=0.5 0"
- rimraf "2"
-
function-bind@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
@@ -5162,13 +4917,6 @@ gauge@~2.7.3:
strip-ansi "^3.0.1"
wide-align "^1.1.0"
-gaze@^1.0.0:
- version "1.1.3"
- resolved "https://registry.yarnpkg.com/gaze/-/gaze-1.1.3.tgz#c441733e13b927ac8c0ff0b4c3b033f28812924a"
- integrity sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g==
- dependencies:
- globule "^1.0.0"
-
generic-names@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/generic-names/-/generic-names-2.0.1.tgz#f8a378ead2ccaa7a34f0317b05554832ae41b872"
@@ -5181,11 +4929,6 @@ gensync@^1.0.0-beta.1, gensync@^1.0.0-beta.2:
resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0"
integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==
-get-caller-file@^2.0.1:
- version "2.0.5"
- resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e"
- integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==
-
get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6"
@@ -5200,11 +4943,6 @@ get-package-type@^0.1.0:
resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a"
integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==
-get-stdin@^4.0.1:
- version "4.0.1"
- resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe"
- integrity sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=
-
get-stream@^4.0.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5"
@@ -5217,13 +4955,6 @@ get-value@^2.0.3, get-value@^2.0.6:
resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28"
integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=
-getpass@^0.1.1:
- version "0.1.7"
- resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa"
- integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=
- dependencies:
- assert-plus "^1.0.0"
-
github-slugger@^1.0.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/github-slugger/-/github-slugger-1.3.0.tgz#9bd0a95c5efdfc46005e82a906ef8e2a059124c9"
@@ -5254,7 +4985,7 @@ glob-parent@^3.1.0:
is-glob "^3.1.0"
path-dirname "^1.0.0"
-glob-parent@^5.1.0, glob-parent@~5.1.0:
+glob-parent@^5.1.0, glob-parent@~5.1.0, glob-parent@~5.1.2:
version "5.1.2"
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4"
integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==
@@ -5273,7 +5004,7 @@ glob-to-regexp@^0.3.0:
resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz#8c5a1494d2066c570cc3bfe4496175acc4d502ab"
integrity sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs=
-glob@^7.0.0, glob@^7.0.3, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6, glob@~7.1.1:
+glob@^7.1.3, glob@^7.1.4, glob@^7.1.6:
version "7.1.7"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90"
integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==
@@ -5292,26 +5023,6 @@ global-modules@2.0.0:
dependencies:
global-prefix "^3.0.0"
-global-modules@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-1.0.0.tgz#6d770f0eb523ac78164d72b5e71a8877265cc3ea"
- integrity sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==
- dependencies:
- global-prefix "^1.0.1"
- is-windows "^1.0.1"
- resolve-dir "^1.0.0"
-
-global-prefix@^1.0.1:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-1.0.2.tgz#dbf743c6c14992593c655568cb66ed32c0122ebe"
- integrity sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=
- dependencies:
- expand-tilde "^2.0.2"
- homedir-polyfill "^1.0.1"
- ini "^1.3.4"
- is-windows "^1.0.1"
- which "^1.2.14"
-
global-prefix@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-3.0.0.tgz#fc85f73064df69f50421f47f883fe5b913ba9b97"
@@ -5367,15 +5078,6 @@ globby@^9.2.0:
pify "^4.0.1"
slash "^2.0.0"
-globule@^1.0.0:
- version "1.3.2"
- resolved "https://registry.yarnpkg.com/globule/-/globule-1.3.2.tgz#d8bdd9e9e4eef8f96e245999a5dee7eb5d8529c4"
- integrity sha512-7IDTQTIu2xzXkT+6mlluidnWo+BypnbSoEVVQCGfzqnl5Ik8d3e1d4wycb8Rj9tWW+Z39uPWsdlquqiqPCd/pA==
- dependencies:
- glob "~7.1.1"
- lodash "~4.17.10"
- minimatch "~3.0.2"
-
good-listener@^1.2.2:
version "1.2.2"
resolved "https://registry.yarnpkg.com/good-listener/-/good-listener-1.2.2.tgz#d53b30cdf9313dffb7dc9a0d477096aa6d145c50"
@@ -5408,26 +5110,6 @@ gzip-size@5.1.1:
duplexer "^0.1.1"
pify "^4.0.1"
-har-schema@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92"
- integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=
-
-har-validator@~5.1.3:
- version "5.1.5"
- resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.5.tgz#1f0803b9f8cb20c0fa13822df1ecddb36bde1efd"
- integrity sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==
- dependencies:
- ajv "^6.12.3"
- har-schema "^2.0.0"
-
-has-ansi@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91"
- integrity sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=
- dependencies:
- ansi-regex "^2.0.0"
-
has-bigints@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.1.tgz#64fe6acb020673e3b78db035a5af69aa9d07b113"
@@ -5598,14 +5280,6 @@ he@^1.2.0:
resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f"
integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==
-header-case@^1.0.0:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/header-case/-/header-case-1.0.1.tgz#9535973197c144b09613cd65d317ef19963bd02d"
- integrity sha1-lTWXMZfBRLCWE81l0xfvGZY70C0=
- dependencies:
- no-case "^2.2.0"
- upper-case "^1.1.3"
-
highlight.js@^10.1.1, highlight.js@~10.7.0:
version "10.7.2"
resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-10.7.2.tgz#89319b861edc66c48854ed1e6da21ea89f847360"
@@ -5627,13 +5301,6 @@ hoist-non-react-statics@^3.3.0:
dependencies:
react-is "^16.7.0"
-homedir-polyfill@^1.0.1:
- version "1.0.3"
- resolved "https://registry.yarnpkg.com/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz#743298cef4e5af3e194161fbadcc2151d3a058e8"
- integrity sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==
- dependencies:
- parse-passwd "^1.0.0"
-
hosted-git-info@^2.1.4:
version "2.8.9"
resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9"
@@ -5716,15 +5383,6 @@ http-errors@~1.7.2:
statuses ">= 1.5.0 < 2"
toidentifier "1.0.0"
-http-signature@~1.2.0:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1"
- integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=
- dependencies:
- assert-plus "^1.0.0"
- jsprim "^1.2.2"
- sshpk "^1.7.0"
-
https-browserify@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73"
@@ -5779,6 +5437,11 @@ immer@8.0.1:
resolved "https://registry.yarnpkg.com/immer/-/immer-8.0.1.tgz#9c73db683e2b3975c424fb0572af5889877ae656"
integrity sha512-aqXhGP7//Gui2+UrEtvxZxSquQVXTpZ7KDxfCcKAF3Vysvw0CViVaW9RZ1j1xlIYqaaaipBoqdqeibkc18PNvA==
+immutable@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.0.0.tgz#b86f78de6adef3608395efb269a91462797e2c23"
+ integrity sha512-zIE9hX70qew5qTUjSS7wi1iwj/l7+m54KWU247nhM3v806UdGj1yDndXj+IOYxxtW9zyLI+xqFNZjTuDaLUqFw==
+
import-cwd@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/import-cwd/-/import-cwd-2.1.0.tgz#aa6cf36e722761285cb371ec6519f53e2435b0a9"
@@ -5814,18 +5477,6 @@ imurmurhash@^0.1.4:
resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea"
integrity sha1-khi5srkoojixPcT7a21XbyMUU+o=
-in-publish@^2.0.0:
- version "2.0.1"
- resolved "https://registry.yarnpkg.com/in-publish/-/in-publish-2.0.1.tgz#948b1a535c8030561cea522f73f78f4be357e00c"
- integrity sha512-oDM0kUSNFC31ShNxHKUyfZKy8ZeXZBWMjMdZHKLOk13uvT27VTL/QzRGfRUcevJhpkZAvlhPYuXkF7eNWrtyxQ==
-
-indent-string@^2.1.0:
- version "2.1.0"
- resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80"
- integrity sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=
- dependencies:
- repeating "^2.0.0"
-
indent-string@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251"
@@ -5844,7 +5495,7 @@ inflight@^1.0.4:
once "^1.3.0"
wrappy "1"
-inherits@2, inherits@2.0.4, inherits@^2.0.0, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.0, inherits@~2.0.1, inherits@~2.0.3:
+inherits@2, inherits@2.0.4, inherits@^2.0.0, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3:
version "2.0.4"
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
@@ -5859,7 +5510,7 @@ inherits@2.0.3:
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=
-ini@^1.3.4, ini@^1.3.5:
+ini@^1.3.5:
version "1.3.8"
resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c"
integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==
@@ -6089,11 +5740,6 @@ is-extglob@^2.1.0, is-extglob@^2.1.1:
resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2"
integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=
-is-finite@^1.0.0:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.1.0.tgz#904135c77fb42c0641d6aa1bcdbc4daa8da082f3"
- integrity sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w==
-
is-fullwidth-code-point@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb"
@@ -6142,13 +5788,6 @@ is-hexadecimal@^1.0.0:
resolved "https://registry.yarnpkg.com/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz#cc35c97588da4bd49a8eedd6bc4082d44dcb23a7"
integrity sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==
-is-lower-case@^1.1.0:
- version "1.1.3"
- resolved "https://registry.yarnpkg.com/is-lower-case/-/is-lower-case-1.1.3.tgz#7e147be4768dc466db3bfb21cc60b31e6ad69393"
- integrity sha1-fhR75HaNxGbbO/shzGCzHmrWk5M=
- dependencies:
- lower-case "^1.1.0"
-
is-map@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/is-map/-/is-map-2.0.2.tgz#00922db8c9bf73e81b7a335827bc2a43f2b91127"
@@ -6238,23 +5877,11 @@ is-symbol@^1.0.2, is-symbol@^1.0.3:
dependencies:
has-symbols "^1.0.2"
-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=
-is-upper-case@^1.1.0:
- version "1.1.2"
- resolved "https://registry.yarnpkg.com/is-upper-case/-/is-upper-case-1.1.2.tgz#8d0b1fa7e7933a1e58483600ec7d9661cbaf756f"
- integrity sha1-jQsfp+eTOh5YSDYA7H2WYcuvdW8=
- dependencies:
- upper-case "^1.1.0"
-
-is-utf8@^0.2.0:
- version "0.2.1"
- resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72"
- integrity sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=
-
is-whitespace-character@^1.0.0:
version "1.0.4"
resolved "https://registry.yarnpkg.com/is-whitespace-character/-/is-whitespace-character-1.0.4.tgz#0858edd94a95594c7c9dd0b5c174ec6e45ee4aa7"
@@ -6265,7 +5892,7 @@ is-window@^1.0.2:
resolved "https://registry.yarnpkg.com/is-window/-/is-window-1.0.2.tgz#2c896ca53db97de45d3c33133a65d8c9f563480d"
integrity sha1-LIlspT25feRdPDMTOmXYyfVjSA0=
-is-windows@^1.0.1, is-windows@^1.0.2:
+is-windows@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d"
integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==
@@ -6319,11 +5946,6 @@ isobject@^4.0.0:
resolved "https://registry.yarnpkg.com/isobject/-/isobject-4.0.0.tgz#3f1c9155e73b192022a80819bacd0343711697b0"
integrity sha512-S/2fF5wH8SJA/kmwr6HYhK/RI/OkhD84k8ntalo0iJjZikgq1XFvR5M8NPT1x5F7fBwCG3qHfnzeP/Vh/ZxCUA==
-isstream@~0.1.2:
- version "0.1.2"
- resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
- integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=
-
istanbul-lib-coverage@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz#f5944a37c70b550b02a78a5c3b2055b280cec8ec"
@@ -6407,11 +6029,6 @@ jest-worker@^26.2.1, jest-worker@^26.6.2:
merge-stream "^2.0.0"
supports-color "^7.0.0"
-js-base64@^2.1.8:
- version "2.6.4"
- resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.6.4.tgz#f4e686c5de1ea1f867dbcad3d46d969428df98c4"
- integrity sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ==
-
js-string-escape@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/js-string-escape/-/js-string-escape-1.0.1.tgz#e2625badbc0d67c7533e9edc1068c587ae4137ef"
@@ -6435,11 +6052,6 @@ js-yaml@^3.13.1:
argparse "^1.0.7"
esprima "^4.0.0"
-jsbn@~0.1.0:
- version "0.1.1"
- resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
- integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM=
-
jscodeshift@^0.7.0:
version "0.7.1"
resolved "https://registry.yarnpkg.com/jscodeshift/-/jscodeshift-0.7.1.tgz#0236ad475d6f0770ca998a0160925d62b57d2507"
@@ -6489,16 +6101,6 @@ json-schema-traverse@^0.4.1:
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660"
integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==
-json-schema@0.2.3:
- version "0.2.3"
- resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13"
- integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=
-
-json-stringify-safe@~5.0.1:
- version "5.0.1"
- resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
- integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=
-
json5@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe"
@@ -6529,16 +6131,6 @@ jsonfile@^6.0.1:
optionalDependencies:
graceful-fs "^4.1.6"
-jsprim@^1.2.2:
- version "1.4.1"
- resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2"
- integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=
- dependencies:
- assert-plus "1.0.0"
- extsprintf "1.3.0"
- json-schema "0.2.3"
- verror "1.10.0"
-
jstransformer@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/jstransformer/-/jstransformer-1.0.0.tgz#ed8bf0921e2f3f1ed4d5c1a44f68709ed24722c3"
@@ -6617,17 +6209,6 @@ lines-and-columns@^1.1.6:
resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00"
integrity sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=
-load-json-file@^1.0.0:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0"
- integrity sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=
- dependencies:
- graceful-fs "^4.1.2"
- parse-json "^2.2.0"
- pify "^2.0.0"
- pinkie-promise "^2.0.0"
- strip-bom "^2.0.0"
-
loader-runner@^2.4.0:
version "2.4.0"
resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.4.0.tgz#ed47066bfe534d7e84c4c7b9998c2a75607d9357"
@@ -6688,7 +6269,7 @@ lodash.uniq@4.5.0:
resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=
-lodash@^4.0.0, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@~4.17.10:
+lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21:
version "4.17.21"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
@@ -6700,26 +6281,6 @@ loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.4.0:
dependencies:
js-tokens "^3.0.0 || ^4.0.0"
-loud-rejection@^1.0.0:
- version "1.6.0"
- resolved "https://registry.yarnpkg.com/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f"
- integrity sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=
- dependencies:
- currently-unhandled "^0.4.1"
- signal-exit "^3.0.0"
-
-lower-case-first@^1.0.0:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/lower-case-first/-/lower-case-first-1.0.2.tgz#e5da7c26f29a7073be02d52bac9980e5922adfa1"
- integrity sha1-5dp8JvKacHO+AtUrrJmA5ZIq36E=
- dependencies:
- lower-case "^1.1.2"
-
-lower-case@^1.1.0, lower-case@^1.1.1, lower-case@^1.1.2:
- version "1.1.4"
- resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-1.1.4.tgz#9a2cabd1b9e8e0ae993a4bf7d5875c39c42e8eac"
- integrity sha1-miyr0bno4K6ZOkv31YdcOcQujqw=
-
lower-case@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-2.0.2.tgz#6fa237c63dbdc4a82ca0fd882e4722dc5e634e28"
@@ -6735,7 +6296,7 @@ lowlight@^1.14.0:
fault "^1.0.0"
highlight.js "~10.7.0"
-lru-cache@^4.0.1, lru-cache@^4.1.5:
+lru-cache@^4.1.5:
version "4.1.5"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd"
integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==
@@ -6791,11 +6352,6 @@ map-cache@^0.2.2:
resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf"
integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=
-map-obj@^1.0.0, map-obj@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d"
- integrity sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=
-
map-or-similar@^1.5.0:
version "1.5.0"
resolved "https://registry.yarnpkg.com/map-or-similar/-/map-or-similar-1.5.0.tgz#6de2653174adfb5d9edc33c69d3e92a1b76faf08"
@@ -6908,22 +6464,6 @@ memory-fs@^0.5.0:
errno "^0.1.3"
readable-stream "^2.0.1"
-meow@^3.7.0:
- version "3.7.0"
- resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb"
- integrity sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=
- dependencies:
- camelcase-keys "^2.0.0"
- decamelize "^1.1.2"
- loud-rejection "^1.0.0"
- map-obj "^1.0.1"
- minimist "^1.1.3"
- normalize-package-data "^2.3.4"
- object-assign "^4.0.1"
- read-pkg-up "^1.0.1"
- redent "^1.0.0"
- trim-newlines "^1.0.0"
-
merge-descriptors@1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61"
@@ -6956,7 +6496,7 @@ microevent.ts@~0.1.1:
resolved "https://registry.yarnpkg.com/microevent.ts/-/microevent.ts-0.1.1.tgz#70b09b83f43df5172d0205a63025bce0f7357fa0"
integrity sha512-jo1OfR4TaEwd5HOrt5+tAZ9mqT4jmpNAusXtyfNzqVm9uiSYFZlKM1wYL4oU7azZW/PxQW53wM0S6OR1JHNa2g==
-micromatch@^3.0.4, micromatch@^3.1.10, micromatch@^3.1.4:
+micromatch@^3.1.10, micromatch@^3.1.4:
version "3.1.10"
resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23"
integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==
@@ -6996,7 +6536,7 @@ mime-db@1.47.0:
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.47.0.tgz#8cb313e59965d3c05cfbf898915a267af46a335c"
integrity sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw==
-mime-types@^2.1.12, mime-types@^2.1.27, mime-types@~2.1.19, mime-types@~2.1.24:
+mime-types@^2.1.12, mime-types@^2.1.27, mime-types@~2.1.24:
version "2.1.30"
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.30.tgz#6e7be8b4c479825f85ed6326695db73f9305d62d"
integrity sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg==
@@ -7030,14 +6570,14 @@ minimalistic-crypto-utils@^1.0.1:
resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a"
integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=
-minimatch@3.0.4, minimatch@^3.0.2, minimatch@^3.0.4, minimatch@~3.0.2:
+minimatch@3.0.4, minimatch@^3.0.2, minimatch@^3.0.4:
version "3.0.4"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==
dependencies:
brace-expansion "^1.1.7"
-minimist@^1.1.1, minimist@^1.1.3, minimist@^1.2.0, minimist@^1.2.5:
+minimist@^1.1.1, 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==
@@ -7102,7 +6642,7 @@ mixin-deep@^1.2.0:
for-in "^1.0.2"
is-extendable "^1.0.1"
-"mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@^0.5.3:
+mkdirp@^0.5.1, mkdirp@^0.5.3:
version "0.5.5"
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def"
integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==
@@ -7146,7 +6686,7 @@ ms@^2.1.1:
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
-nan@^2.12.1, nan@^2.13.2:
+nan@^2.12.1:
version "2.14.2"
resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.2.tgz#f5376400695168f4cc694ac9393d0c9585eeea19"
integrity sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==
@@ -7193,13 +6733,6 @@ nice-try@^1.0.4:
resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366"
integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==
-no-case@^2.2.0, no-case@^2.3.2:
- version "2.3.2"
- resolved "https://registry.yarnpkg.com/no-case/-/no-case-2.3.2.tgz#60b813396be39b3f1288a4c1ed5d1e7d28b464ac"
- integrity sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==
- dependencies:
- lower-case "^1.1.1"
-
no-case@^3.0.4:
version "3.0.4"
resolved "https://registry.yarnpkg.com/no-case/-/no-case-3.0.4.tgz#d361fd5c9800f558551a8369fc0dcd4662b6124d"
@@ -7220,24 +6753,6 @@ node-fetch@^2.6.1:
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052"
integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==
-node-gyp@^3.8.0:
- version "3.8.0"
- resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-3.8.0.tgz#540304261c330e80d0d5edce253a68cb3964218c"
- integrity sha512-3g8lYefrRRzvGeSowdJKAKyks8oUpLEd/DyPV4eMhVlhJ0aNaZqIrNUIPuEWWTAoPqyFkfGrM67MC69baqn6vA==
- dependencies:
- fstream "^1.0.0"
- glob "^7.0.3"
- graceful-fs "^4.1.2"
- mkdirp "^0.5.0"
- nopt "2 || 3"
- npmlog "0 || 1 || 2 || 3 || 4"
- osenv "0"
- request "^2.87.0"
- rimraf "2"
- semver "~5.3.0"
- tar "^2.0.0"
- which "1"
-
node-int64@^0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b"
@@ -7282,50 +6797,7 @@ node-releases@^1.1.61, node-releases@^1.1.71:
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.72.tgz#14802ab6b1039a79a0c7d662b610a5bbd76eacbe"
integrity sha512-LLUo+PpH3dU6XizX3iVoubUNheF/owjXCZZ5yACDxNnPtgFuludV1ZL3ayK1kVep42Rmm0+R9/Y60NQbZ2bifw==
-node-sass-magic-importer@^5.3.2:
- version "5.3.2"
- resolved "https://registry.yarnpkg.com/node-sass-magic-importer/-/node-sass-magic-importer-5.3.2.tgz#2f2248bb2e5cdb275ba34102ebf995edadf99175"
- integrity sha512-T3wTUdUoXQE3QN+EsyPpUXRI1Gj1lEsrySQ9Kzlzi15QGKi+uRa9fmvkcSy2y3BKgoj//7Mt9+s+7p0poMpg6Q==
- dependencies:
- css-node-extract "^2.1.3"
- css-selector-extract "^3.3.6"
- findup-sync "^3.0.0"
- glob "^7.1.3"
- object-hash "^1.3.1"
- postcss-scss "^2.0.0"
- resolve "^1.10.1"
-
-node-sass@^4.14.1:
- version "4.14.1"
- resolved "https://registry.yarnpkg.com/node-sass/-/node-sass-4.14.1.tgz#99c87ec2efb7047ed638fb4c9db7f3a42e2217b5"
- integrity sha512-sjCuOlvGyCJS40R8BscF5vhVlQjNN069NtQ1gSxyK1u9iqvn6tf7O1R4GNowVZfiZUCRt5MmMs1xd+4V/7Yr0g==
- dependencies:
- async-foreach "^0.1.3"
- chalk "^1.1.1"
- cross-spawn "^3.0.0"
- gaze "^1.0.0"
- get-stdin "^4.0.1"
- glob "^7.0.3"
- in-publish "^2.0.0"
- lodash "^4.17.15"
- meow "^3.7.0"
- mkdirp "^0.5.1"
- nan "^2.13.2"
- node-gyp "^3.8.0"
- npmlog "^4.0.0"
- request "^2.88.0"
- sass-graph "2.2.5"
- stdout-stream "^1.4.0"
- "true-case-path" "^1.0.2"
-
-"nopt@2 || 3":
- version "3.0.6"
- resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9"
- integrity sha1-xkZdvwirzU2zWTF/eaxopkayj/k=
- dependencies:
- abbrev "1"
-
-normalize-package-data@^2.3.2, normalize-package-data@^2.3.4, normalize-package-data@^2.5.0:
+normalize-package-data@^2.5.0:
version "2.5.0"
resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8"
integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==
@@ -7359,7 +6831,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.1.2:
+npmlog@^4.1.2:
version "4.1.2"
resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b"
integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==
@@ -7386,12 +6858,7 @@ 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=
-oauth-sign@~0.9.0:
- version "0.9.0"
- resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455"
- integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==
-
-object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1:
+object-assign@^4.1.0, object-assign@^4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=
@@ -7405,11 +6872,6 @@ object-copy@^0.1.0:
define-property "^0.2.5"
kind-of "^3.0.3"
-object-hash@^1.3.1:
- version "1.3.1"
- resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-1.3.1.tgz#fde452098a951cb145f039bb7d455449ddc126df"
- integrity sha512-OSuu/pU4ENM9kmREg0BdNrUDIl1heYa4mBZacJc+vVWz4GtAwu7jO8s4AIt2aGRUTqxykpWzI3Oqnsm13tTMDA==
-
object-inspect@^1.10.3, object-inspect@^1.9.0:
version "1.10.3"
resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.10.3.tgz#c2aa7d2d09f50c99375704f7a0adf24c5782d369"
@@ -7520,24 +6982,6 @@ os-browserify@^0.3.0:
resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27"
integrity sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=
-os-homedir@^1.0.0:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3"
- integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M=
-
-os-tmpdir@^1.0.0:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"
- integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=
-
-osenv@0:
- version "0.1.5"
- resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410"
- integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==
- dependencies:
- os-homedir "^1.0.0"
- os-tmpdir "^1.0.0"
-
overlayscrollbars@^1.13.1:
version "1.13.1"
resolved "https://registry.yarnpkg.com/overlayscrollbars/-/overlayscrollbars-1.13.1.tgz#0b840a88737f43a946b9d87875a2f9e421d0338a"
@@ -7649,13 +7093,6 @@ parallel-transform@^1.1.0:
inherits "^2.0.3"
readable-stream "^2.1.5"
-param-case@^2.1.0:
- version "2.1.1"
- resolved "https://registry.yarnpkg.com/param-case/-/param-case-2.1.1.tgz#df94fd8cf6531ecf75e6bef9a0858fbc72be2247"
- integrity sha1-35T9jPZTHs915r75oIWPvHK+Ikc=
- dependencies:
- no-case "^2.2.0"
-
param-case@^3.0.3:
version "3.0.4"
resolved "https://registry.yarnpkg.com/param-case/-/param-case-3.0.4.tgz#7d17fe4aa12bde34d4a77d91acfb6219caad01c5"
@@ -7694,13 +7131,6 @@ parse-entities@^2.0.0:
is-decimal "^1.0.0"
is-hexadecimal "^1.0.0"
-parse-json@^2.2.0:
- version "2.2.0"
- resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9"
- integrity sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=
- dependencies:
- error-ex "^1.2.0"
-
parse-json@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0"
@@ -7719,11 +7149,6 @@ parse-json@^5.0.0:
json-parse-even-better-errors "^2.3.0"
lines-and-columns "^1.1.6"
-parse-passwd@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6"
- integrity sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=
-
parse5@^6.0.0:
version "6.0.1"
resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b"
@@ -7734,14 +7159,6 @@ parseurl@~1.3.2, parseurl@~1.3.3:
resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4"
integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==
-pascal-case@^2.0.0:
- version "2.0.1"
- resolved "https://registry.yarnpkg.com/pascal-case/-/pascal-case-2.0.1.tgz#2d578d3455f660da65eca18ef95b4e0de912761e"
- integrity sha1-LVeNNFX2YNpl7KGO+VtODekSdh4=
- dependencies:
- camel-case "^3.0.0"
- upper-case-first "^1.1.0"
-
pascal-case@^3.1.2:
version "3.1.2"
resolved "https://registry.yarnpkg.com/pascal-case/-/pascal-case-3.1.2.tgz#b48e0ef2b98e205e7c1dae747d0b1508237660eb"
@@ -7760,25 +7177,11 @@ path-browserify@0.0.1:
resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.1.tgz#e6c4ddd7ed3aa27c68a20cc4e50e1a4ee83bbc4a"
integrity sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==
-path-case@^2.1.0:
- version "2.1.1"
- resolved "https://registry.yarnpkg.com/path-case/-/path-case-2.1.1.tgz#94b8037c372d3fe2906e465bb45e25d226e8eea5"
- integrity sha1-lLgDfDctP+KQbkZbtF4l0ibo7qU=
- dependencies:
- no-case "^2.2.0"
-
path-dirname@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0"
integrity sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=
-path-exists@^2.0.0:
- version "2.1.0"
- resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b"
- integrity sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=
- dependencies:
- pinkie-promise "^2.0.0"
-
path-exists@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515"
@@ -7814,15 +7217,6 @@ path-to-regexp@0.1.7:
resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c"
integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=
-path-type@^1.0.0:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441"
- integrity sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=
- dependencies:
- graceful-fs "^4.1.2"
- pify "^2.0.0"
- pinkie-promise "^2.0.0"
-
path-type@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f"
@@ -7846,21 +7240,11 @@ pbkdf2@^3.0.3:
safe-buffer "^5.0.1"
sha.js "^2.4.8"
-performance-now@^2.1.0:
- version "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.2.1, picomatch@^2.2.3:
version "2.3.0"
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972"
integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==
-pify@^2.0.0:
- version "2.3.0"
- resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c"
- integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw=
-
pify@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176"
@@ -7871,18 +7255,6 @@ pify@^4.0.1:
resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231"
integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==
-pinkie-promise@^2.0.0:
- version "2.0.1"
- resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa"
- integrity sha1-ITXW36ejWMBprJsXh3YogihFD/o=
- dependencies:
- pinkie "^2.0.0"
-
-pinkie@^2.0.0:
- version "2.0.4"
- resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870"
- integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA=
-
pirates@^4.0.0, pirates@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.1.tgz#643a92caf894566f91b2b986d2c66950a8e2fb87"
@@ -8048,13 +7420,6 @@ postcss-modules@^4.0.0:
postcss-modules-values "^4.0.0"
string-hash "^1.1.1"
-postcss-scss@^2.0.0:
- version "2.1.1"
- resolved "https://registry.yarnpkg.com/postcss-scss/-/postcss-scss-2.1.1.tgz#ec3a75fa29a55e016b90bf3269026c53c1d2b383"
- integrity sha512-jQmGnj0hSGLd9RscFw9LyuSVAa5Bl1/KBPqG1NQw9w8ND55nY4ZEsdlVuYJvLPpV+y0nwTV5v/4rHPzZRihQbA==
- dependencies:
- postcss "^7.0.6"
-
postcss-selector-parser@^6.0.0, postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4:
version "6.0.6"
resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.6.tgz#2c5bba8174ac2f6981ab631a42ab0ee54af332ea"
@@ -8068,15 +7433,6 @@ postcss-value-parser@^4.1.0:
resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz#443f6a20ced6481a2bda4fa8532a6e55d789a2cb"
integrity sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==
-postcss@^6.0.14:
- version "6.0.23"
- resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.23.tgz#61c82cc328ac60e677645f979054eb98bc0e3324"
- integrity sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==
- dependencies:
- chalk "^2.4.1"
- source-map "^0.6.1"
- supports-color "^5.4.0"
-
postcss@^7.0.0, postcss@^7.0.14, postcss@^7.0.26, postcss@^7.0.32, postcss@^7.0.35, postcss@^7.0.5, postcss@^7.0.6:
version "7.0.35"
resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.35.tgz#d2be00b998f7f211d8a276974079f2e92b970e24"
@@ -8223,11 +7579,6 @@ pseudomap@^1.0.2:
resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3"
integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM=
-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==
-
public-encrypt@^4.0.0:
version "4.0.3"
resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.3.tgz#4fcc9d77a07e48ba7527e7cbe0de33d0701331e0"
@@ -8378,7 +7729,7 @@ punycode@^1.2.4:
resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e"
integrity sha1-wNWmOycYgArY4esPpSachN1BhF4=
-punycode@^2.1.0, punycode@^2.1.1:
+punycode@^2.1.0:
version "2.1.1"
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==
@@ -8395,11 +7746,6 @@ qs@^6.10.0:
dependencies:
side-channel "^1.0.4"
-qs@~6.5.2:
- version "6.5.2"
- resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36"
- integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==
-
querystring-es3@^0.2.0:
version "0.2.1"
resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73"
@@ -8625,14 +7971,6 @@ react@16.14.0:
object-assign "^4.1.1"
prop-types "^15.6.2"
-read-pkg-up@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02"
- integrity sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=
- dependencies:
- find-up "^1.0.0"
- read-pkg "^1.0.0"
-
read-pkg-up@^7.0.1:
version "7.0.1"
resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-7.0.1.tgz#f3a6135758459733ae2b95638056e1854e7ef507"
@@ -8642,15 +7980,6 @@ read-pkg-up@^7.0.1:
read-pkg "^5.2.0"
type-fest "^0.8.1"
-read-pkg@^1.0.0:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28"
- integrity sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=
- dependencies:
- load-json-file "^1.0.0"
- normalize-package-data "^2.3.2"
- path-type "^1.0.0"
-
read-pkg@^5.2.0:
version "5.2.0"
resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-5.2.0.tgz#7bf295438ca5a33e56cd30e053b34ee7250c93cc"
@@ -8699,6 +8028,13 @@ readdirp@~3.5.0:
dependencies:
picomatch "^2.2.1"
+readdirp@~3.6.0:
+ version "3.6.0"
+ resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7"
+ integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==
+ dependencies:
+ picomatch "^2.2.1"
+
recast@0.20.4:
version "0.20.4"
resolved "https://registry.yarnpkg.com/recast/-/recast-0.20.4.tgz#db55983eac70c46b3fff96c8e467d65ffb4a7abc"
@@ -8726,14 +8062,6 @@ recursive-readdir@2.2.2:
dependencies:
minimatch "3.0.4"
-redent@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/redent/-/redent-1.0.0.tgz#cf916ab1fd5f1f16dfb20822dd6ec7f730c2afde"
- integrity sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=
- dependencies:
- indent-string "^2.1.0"
- strip-indent "^1.0.1"
-
refractor@^3.1.0:
version "3.3.1"
resolved "https://registry.yarnpkg.com/refractor/-/refractor-3.3.1.tgz#ebbc04b427ea81dc25ad333f7f67a0b5f4f0be3a"
@@ -8906,57 +8234,6 @@ repeat-string@^1.5.4, repeat-string@^1.6.1:
resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637"
integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc=
-repeating@^2.0.0:
- version "2.0.1"
- resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda"
- integrity sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=
- dependencies:
- is-finite "^1.0.0"
-
-request@^2.87.0, request@^2.88.0:
- 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"
- caseless "~0.12.0"
- combined-stream "~1.0.6"
- extend "~3.0.2"
- forever-agent "~0.6.1"
- form-data "~2.3.2"
- har-validator "~5.1.3"
- http-signature "~1.2.0"
- is-typedarray "~1.0.0"
- isstream "~0.1.2"
- json-stringify-safe "~5.0.1"
- mime-types "~2.1.19"
- oauth-sign "~0.9.0"
- performance-now "^2.1.0"
- qs "~6.5.2"
- safe-buffer "^5.1.2"
- tough-cookie "~2.5.0"
- tunnel-agent "^0.6.0"
- uuid "^3.3.2"
-
-require-directory@^2.1.1:
- version "2.1.1"
- resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42"
- integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I=
-
-require-main-filename@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b"
- integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==
-
-resolve-dir@^1.0.0, resolve-dir@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/resolve-dir/-/resolve-dir-1.0.1.tgz#79a40644c362be82f26effe739c9bb5382046f43"
- integrity sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=
- dependencies:
- expand-tilde "^2.0.0"
- global-modules "^1.0.0"
-
resolve-from@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748"
@@ -8977,7 +8254,7 @@ resolve-url@^0.2.1:
resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a"
integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=
-resolve@^1.10.0, resolve@^1.10.1, resolve@^1.12.0, resolve@^1.14.2, resolve@^1.15.1, resolve@^1.19.0, resolve@^1.3.2:
+resolve@^1.10.0, resolve@^1.12.0, resolve@^1.14.2, resolve@^1.15.1, resolve@^1.19.0, resolve@^1.3.2:
version "1.20.0"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975"
integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==
@@ -8995,7 +8272,7 @@ reusify@^1.0.4:
resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76"
integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==
-rimraf@2, rimraf@^2.2.8, rimraf@^2.5.4, rimraf@^2.6.3:
+rimraf@^2.2.8, rimraf@^2.5.4, rimraf@^2.6.3:
version "2.7.1"
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec"
integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==
@@ -9065,7 +8342,7 @@ safe-regex@^1.1.0:
dependencies:
ret "~0.1.10"
-"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0:
+"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.1.0:
version "2.1.2"
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
@@ -9085,16 +8362,6 @@ sane@^4.0.3:
minimist "^1.1.1"
walker "~1.0.5"
-sass-graph@2.2.5:
- version "2.2.5"
- resolved "https://registry.yarnpkg.com/sass-graph/-/sass-graph-2.2.5.tgz#a981c87446b8319d96dce0671e487879bd24c2e8"
- integrity sha512-VFWDAHOe6mRuT4mZRd4eKE+d8Uedrk6Xnh7Sh9b4NGufQLQjOrvf/MQoOdx+0s92L89FeyUUNfU597j/3uNpag==
- dependencies:
- glob "^7.0.0"
- lodash "^4.0.0"
- scss-tokenizer "^0.2.3"
- yargs "^13.3.2"
-
sass-loader@^7.1.0:
version "7.3.1"
resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-7.3.1.tgz#a5bf68a04bcea1c13ff842d747150f7ab7d0d23f"
@@ -9106,6 +8373,15 @@ sass-loader@^7.1.0:
pify "^4.0.1"
semver "^6.3.0"
+sass@^1.49.9:
+ version "1.49.9"
+ resolved "https://registry.yarnpkg.com/sass/-/sass-1.49.9.tgz#b15a189ecb0ca9e24634bae5d1ebc191809712f9"
+ integrity sha512-YlYWkkHP9fbwaFRZQRXgDi3mXZShslVmmo+FVK3kHLUELHHEYrCmL1x6IUjC7wLS6VuJSAFXRQS/DxdsC4xL1A==
+ dependencies:
+ chokidar ">=3.0.0 <4.0.0"
+ immutable "^4.0.0"
+ source-map-js ">=0.6.2 <2.0.0"
+
scheduler@^0.19.1:
version "0.19.1"
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.19.1.tgz#4f3e2ed2c1a7d65681f4c854fa8c5a1ccb40f196"
@@ -9150,14 +8426,6 @@ schema-utils@^3.0.0:
ajv "^6.12.5"
ajv-keywords "^3.5.2"
-scss-tokenizer@^0.2.3:
- version "0.2.3"
- resolved "https://registry.yarnpkg.com/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz#8eb06db9a9723333824d3f5530641149847ce5d1"
- integrity sha1-jrBtualyMzOCTT9VMGQRSYR85dE=
- dependencies:
- js-base64 "^2.1.8"
- source-map "^0.4.2"
-
select@^1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/select/-/select-1.1.2.tgz#0e7350acdec80b1108528786ec1d4418d11b396d"
@@ -9185,11 +8453,6 @@ semver@^7.3.2, semver@^7.3.4:
dependencies:
lru-cache "^6.0.0"
-semver@~5.3.0:
- version "5.3.0"
- resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f"
- integrity sha1-myzl094C0XxgEq0yaqa00M9U+U8=
-
send@0.17.1:
version "0.17.1"
resolved "https://registry.yarnpkg.com/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8"
@@ -9209,14 +8472,6 @@ send@0.17.1:
range-parser "~1.2.1"
statuses "~1.5.0"
-sentence-case@^2.1.0:
- version "2.1.1"
- resolved "https://registry.yarnpkg.com/sentence-case/-/sentence-case-2.1.1.tgz#1f6e2dda39c168bf92d13f86d4a918933f667ed4"
- integrity sha1-H24t2jnBaL+S0T+G1KkYkz9mftQ=
- dependencies:
- no-case "^2.2.0"
- upper-case-first "^1.1.2"
-
serialize-javascript@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-4.0.0.tgz#b525e1238489a5ecfc42afacc3fe99e666f4b1aa"
@@ -9245,7 +8500,7 @@ serve-static@1.14.1:
parseurl "~1.3.3"
send "0.17.1"
-set-blocking@^2.0.0, set-blocking@~2.0.0:
+set-blocking@~2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7"
integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc=
@@ -9348,13 +8603,6 @@ slash@^3.0.0:
resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634"
integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==
-snake-case@^2.1.0:
- version "2.1.0"
- resolved "https://registry.yarnpkg.com/snake-case/-/snake-case-2.1.0.tgz#41bdb1b73f30ec66a04d4e2cad1b76387d4d6d9f"
- integrity sha1-Qb2xtz8w7GagTU4srRt2OH1NbZ8=
- dependencies:
- no-case "^2.2.0"
-
snapdragon-node@^2.0.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b"
@@ -9390,6 +8638,11 @@ source-list-map@^2.0.0:
resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34"
integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==
+"source-map-js@>=0.6.2 <2.0.0":
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c"
+ integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==
+
source-map-js@^0.6.2:
version "0.6.2"
resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-0.6.2.tgz#0bb5de631b41cfbda6cfba8bd05a80efdfd2385e"
@@ -9419,13 +8672,6 @@ source-map-url@^0.4.0:
resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.1.tgz#0af66605a745a5a2f91cf1bbf8a7afbc283dec56"
integrity sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==
-source-map@^0.4.2:
- version "0.4.4"
- resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.4.4.tgz#eba4f5da9c0dc999de68032d8b4f76173652036b"
- integrity sha1-66T12pwNyZneaAMti092FzZSA2s=
- dependencies:
- amdefine ">=0.0.4"
-
source-map@^0.5.0, source-map@^0.5.6, source-map@^0.5.7:
version "0.5.7"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
@@ -9489,21 +8735,6 @@ sprintf-js@~1.0.2:
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=
-sshpk@^1.7.0:
- version "1.16.1"
- resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877"
- integrity sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==
- dependencies:
- asn1 "~0.2.3"
- assert-plus "^1.0.0"
- bcrypt-pbkdf "^1.0.0"
- dashdash "^1.12.0"
- ecc-jsbn "~0.1.1"
- getpass "^0.1.1"
- jsbn "~0.1.0"
- safer-buffer "^2.0.2"
- tweetnacl "~0.14.0"
-
ssri@^6.0.1:
version "6.0.2"
resolved "https://registry.yarnpkg.com/ssri/-/ssri-6.0.2.tgz#157939134f20464e7301ddba3e90ffa8f7728ac5"
@@ -9541,13 +8772,6 @@ static-extend@^0.1.1:
resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c"
integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=
-stdout-stream@^1.4.0:
- version "1.4.1"
- resolved "https://registry.yarnpkg.com/stdout-stream/-/stdout-stream-1.4.1.tgz#5ac174cdd5cd726104aa0c0b2bd83815d8d535de"
- integrity sha512-j4emi03KXqJWcIeF8eIXkjMFN1Cmb8gUlDYGeBALLPo5qdyTfA9bOtl8m33lRoC+vFMkP3gl0WsDr6+gzxbbTA==
- dependencies:
- readable-stream "^2.0.1"
-
store2@^2.12.0:
version "2.12.0"
resolved "https://registry.yarnpkg.com/store2/-/store2-2.12.0.tgz#e1f1b7e1a59b6083b2596a8d067f6ee88fd4d3cf"
@@ -9612,7 +8836,7 @@ string-width@^1.0.1:
is-fullwidth-code-point "^2.0.0"
strip-ansi "^4.0.0"
-string-width@^3.0.0, string-width@^3.1.0:
+string-width@^3.0.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961"
integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==
@@ -9713,32 +8937,18 @@ strip-ansi@^4.0.0:
dependencies:
ansi-regex "^3.0.0"
-strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0:
+strip-ansi@^5.1.0:
version "5.2.0"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae"
integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==
dependencies:
ansi-regex "^4.1.0"
-strip-bom@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e"
- integrity sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=
- dependencies:
- is-utf8 "^0.2.0"
-
strip-eof@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf"
integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=
-strip-indent@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-1.0.1.tgz#0c7962a6adefa7bbd4ac366460a638552ae1a0a2"
- integrity sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=
- dependencies:
- get-stdin "^4.0.1"
-
style-loader@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-1.3.0.tgz#828b4a3b3b7e7aa5847ce7bae9e874512114249e"
@@ -9754,12 +8964,7 @@ style-to-object@0.3.0, style-to-object@^0.3.0:
dependencies:
inline-style-parser "0.1.1"
-supports-color@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"
- integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=
-
-supports-color@^5.3.0, supports-color@^5.4.0:
+supports-color@^5.3.0:
version "5.5.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f"
integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==
@@ -9780,14 +8985,6 @@ supports-color@^7.0.0, supports-color@^7.1.0:
dependencies:
has-flag "^4.0.0"
-swap-case@^1.1.0:
- version "1.1.2"
- resolved "https://registry.yarnpkg.com/swap-case/-/swap-case-1.1.2.tgz#c39203a4587385fad3c850a0bd1bcafa081974e3"
- integrity sha1-w5IDpFhzhfrTyFCgvRvK+ggZdOM=
- dependencies:
- lower-case "^1.1.1"
- upper-case "^1.1.1"
-
symbol.prototype.description@^1.0.0:
version "1.0.4"
resolved "https://registry.yarnpkg.com/symbol.prototype.description/-/symbol.prototype.description-1.0.4.tgz#c30edd3fe8c040d941cf7dc15842be15adf66855"
@@ -9803,15 +9000,6 @@ tapable@^1.0.0, tapable@^1.1.3:
resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2"
integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==
-tar@^2.0.0:
- version "2.2.2"
- resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.2.tgz#0ca8848562c7299b8b446ff6a4d60cdbb23edc40"
- integrity sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA==
- dependencies:
- block-stream "*"
- fstream "^1.0.12"
- inherits "2"
-
tar@^6.0.2:
version "6.1.0"
resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.0.tgz#d1724e9bcc04b977b18d5c573b333a2207229a83"
@@ -9928,14 +9116,6 @@ tiny-emitter@^2.0.0:
resolved "https://registry.yarnpkg.com/tiny-emitter/-/tiny-emitter-2.1.0.tgz#1d1a56edfc51c43e863cbb5382a72330e3555423"
integrity sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==
-title-case@^2.1.0:
- version "2.1.1"
- resolved "https://registry.yarnpkg.com/title-case/-/title-case-2.1.1.tgz#3e127216da58d2bc5becf137ab91dae3a7cd8faa"
- integrity sha1-PhJyFtpY0rxb7PE3q5Ha46fNj6o=
- dependencies:
- no-case "^2.2.0"
- upper-case "^1.0.3"
-
tmpl@1.0.x:
version "1.0.4"
resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1"
@@ -9998,19 +9178,6 @@ token-stream@1.0.0:
resolved "https://registry.yarnpkg.com/token-stream/-/token-stream-1.0.0.tgz#cc200eab2613f4166d27ff9afc7ca56d49df6eb4"
integrity sha1-zCAOqyYT9BZtJ/+a/HylbUnfbrQ=
-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.28"
- punycode "^2.1.1"
-
-trim-newlines@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613"
- integrity sha1-WIeWa7WCpFA6QetST301ARgVphM=
-
trim-trailing-lines@^1.0.0:
version "1.1.4"
resolved "https://registry.yarnpkg.com/trim-trailing-lines/-/trim-trailing-lines-1.1.4.tgz#bd4abbec7cc880462f10b2c8b5ce1d8d1ec7c2c0"
@@ -10026,13 +9193,6 @@ trough@^1.0.0:
resolved "https://registry.yarnpkg.com/trough/-/trough-1.0.5.tgz#b8b639cefad7d0bb2abd37d433ff8293efa5f406"
integrity sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==
-"true-case-path@^1.0.2":
- version "1.0.3"
- resolved "https://registry.yarnpkg.com/true-case-path/-/true-case-path-1.0.3.tgz#f813b5a8c86b40da59606722b144e3225799f47d"
- integrity sha512-m6s2OdQe5wgpFMC+pAJ+q9djG82O2jcHPOI6RNg1yy9rCYR+WD6Nbpl32fDpfC56nirdRy+opFa/Vk7HYhqaew==
- dependencies:
- glob "^7.1.2"
-
ts-dedent@^2.0.0:
version "2.1.1"
resolved "https://registry.yarnpkg.com/ts-dedent/-/ts-dedent-2.1.1.tgz#6dd56870bb5493895171334fa5d7e929107e5bbc"
@@ -10079,18 +9239,6 @@ tty-browserify@0.0.0:
resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6"
integrity sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=
-tunnel-agent@^0.6.0:
- version "0.6.0"
- resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd"
- integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=
- dependencies:
- safe-buffer "^5.0.1"
-
-tweetnacl@^0.14.3, tweetnacl@~0.14.0:
- version "0.14.5"
- resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
- integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=
-
type-check@~0.3.2:
version "0.3.2"
resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72"
@@ -10296,18 +9444,6 @@ upath@^1.1.1:
resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894"
integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==
-upper-case-first@^1.1.0, upper-case-first@^1.1.2:
- version "1.1.2"
- resolved "https://registry.yarnpkg.com/upper-case-first/-/upper-case-first-1.1.2.tgz#5d79bedcff14419518fd2edb0a0507c9b6859115"
- integrity sha1-XXm+3P8UQZUY/S7bCgUHybaFkRU=
- dependencies:
- upper-case "^1.1.1"
-
-upper-case@^1.0.3, upper-case@^1.1.0, upper-case@^1.1.1, upper-case@^1.1.3:
- version "1.1.3"
- resolved "https://registry.yarnpkg.com/upper-case/-/upper-case-1.1.3.tgz#f6b4501c2ec4cdd26ba78be7222961de77621598"
- integrity sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg=
-
uri-js@^4.2.2:
version "4.4.1"
resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e"
@@ -10421,15 +9557,6 @@ vary@~1.1.2:
resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=
-verror@1.10.0:
- version "1.10.0"
- resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400"
- integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=
- dependencies:
- assert-plus "^1.0.0"
- core-util-is "1.0.2"
- extsprintf "^1.2.0"
-
vfile-location@^3.0.0, vfile-location@^3.2.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/vfile-location/-/vfile-location-3.2.0.tgz#d8e41fbcbd406063669ebf6c33d56ae8721d0f3c"
@@ -10623,12 +9750,7 @@ which-boxed-primitive@^1.0.2:
is-string "^1.0.5"
is-symbol "^1.0.3"
-which-module@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a"
- integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=
-
-which@1, which@^1.2.14, which@^1.2.9, which@^1.3.1:
+which@^1.2.9, which@^1.3.1:
version "1.3.1"
resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a"
integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==
@@ -10685,15 +9807,6 @@ worker-rpc@^0.1.0:
dependencies:
microevent.ts "~0.1.1"
-wrap-ansi@^5.1.0:
- version "5.1.0"
- resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09"
- integrity sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==
- dependencies:
- ansi-styles "^3.2.0"
- string-width "^3.0.0"
- strip-ansi "^5.0.0"
-
wrappy@1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
@@ -10748,30 +9861,6 @@ yaml@^1.10.0, yaml@^1.7.2:
resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b"
integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==
-yargs-parser@^13.1.2:
- version "13.1.2"
- resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.2.tgz#130f09702ebaeef2650d54ce6e3e5706f7a4fb38"
- integrity sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==
- dependencies:
- camelcase "^5.0.0"
- decamelize "^1.2.0"
-
-yargs@^13.3.2:
- version "13.3.2"
- resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.2.tgz#ad7ffefec1aa59565ac915f82dccb38a9c31a2dd"
- integrity sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==
- dependencies:
- cliui "^5.0.0"
- find-up "^3.0.0"
- get-caller-file "^2.0.1"
- require-directory "^2.1.1"
- require-main-filename "^2.0.0"
- set-blocking "^2.0.0"
- string-width "^3.0.0"
- which-module "^2.0.0"
- y18n "^4.0.0"
- yargs-parser "^13.1.2"
-
yocto-queue@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"
diff --git a/tooling/danger/changelog.rb b/tooling/danger/changelog.rb
deleted file mode 100644
index 6a392afac13..00000000000
--- a/tooling/danger/changelog.rb
+++ /dev/null
@@ -1,232 +0,0 @@
-# frozen_string_literal: true
-
-require 'gitlab/dangerfiles/title_linting'
-
-module Tooling
- module Danger
- module Changelog
- NO_CHANGELOG_LABELS = [
- 'type::tooling',
- 'tooling::pipelines',
- 'tooling::workflow',
- 'ci-build',
- 'meta'
- ].freeze
- NO_CHANGELOG_CATEGORIES = %i[docs none].freeze
- CHANGELOG_TRAILER_REGEX = /^(?<name>Changelog):\s*(?<category>.+)$/i.freeze
- CHANGELOG_EE_TRAILER_REGEX = /^EE: true$/.freeze
- CHANGELOG_MODIFIED_URL_TEXT = "**CHANGELOG.md was edited.** Please remove the additions and follow the [changelog guidelines](https://docs.gitlab.com/ee/development/changelog.html).\n\n"
- CHANGELOG_MISSING_URL_TEXT = "**[CHANGELOG missing](https://docs.gitlab.com/ee/development/changelog.html)**:\n\n"
-
- OPTIONAL_CHANGELOG_MESSAGE = {
- local: "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.",
- ci: <<~MSG
- If you want to create a changelog entry for GitLab FOSS, add the `Changelog` trailer to the commit message you want to add to the changelog.
-
- If you want to create a changelog entry for GitLab EE, also [add the `EE: true` trailer](https://docs.gitlab.com/ee/development/changelog.html#gitlab-enterprise-changes) to your commit message.
-
- 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
- }.freeze
- SEE_DOC = "See the [changelog documentation](https://docs.gitlab.com/ee/development/changelog.html)."
-
- REQUIRED_CHANGELOG_REASONS = {
- db_changes: 'introduces a database migration',
- feature_flag_removed: 'removes a feature flag'
- }.freeze
- REQUIRED_CHANGELOG_MESSAGE = {
- local: "This merge request requires a changelog entry because it [%<reason>s](https://docs.gitlab.com/ee/development/changelog.html#what-warrants-a-changelog-entry).",
- ci: <<~MSG
- To create a changelog entry, add the `Changelog` trailer to one of your Git commit messages.
-
- This merge request requires a changelog entry because it [%<reason>s](https://docs.gitlab.com/ee/development/changelog.html#what-warrants-a-changelog-entry).
- MSG
- }.freeze
-
- CATEGORIES = YAML
- .load_file(File.expand_path('../../.gitlab/changelog_config.yml', __dir__))
- .fetch('categories')
- .keys
- .freeze
-
- class ChangelogCheckResult
- attr_reader :errors, :warnings, :markdowns, :messages
-
- def initialize(errors: [], warnings: [], markdowns: [], messages: [])
- @errors = errors
- @warnings = warnings
- @markdowns = markdowns
- @messages = messages
- end
- private_class_method :new
-
- def self.empty
- new
- end
-
- def self.error(error)
- new(errors: [error])
- end
-
- def self.warning(warning)
- new(warnings: [warning])
- end
-
- def error(error)
- errors << error
- end
-
- def warning(warning)
- warnings << warning
- end
-
- def markdown(markdown)
- markdowns << markdown
- end
-
- def message(message)
- messages << message
- end
- end
-
- # rubocop:disable Style/SignalException
- def check!
- if git.modified_files.include?("CHANGELOG.md")
- fail modified_text
- end
-
- if present?
- add_danger_messages(check_changelog_path)
- elsif required?
- required_texts.each { |_, text| fail(text) } # rubocop:disable Lint/UnreachableLoop
- elsif optional?
- message optional_text
- end
-
- check_changelog_commit_categories
- end
- # rubocop:enable Style/SignalException
-
- # rubocop:disable Style/SignalException
- def add_danger_messages(check_result)
- check_result.errors.each { |error| fail(error) } # rubocop:disable Lint/UnreachableLoop
- check_result.warnings.each { |warning| warn(warning) }
- check_result.markdowns.each { |markdown_hash| markdown(**markdown_hash) }
- check_result.messages.each { |text| message(text) }
- end
- # rubocop:enable Style/SignalException
-
- def check_changelog_commit_categories
- changelog_commits.each do |commit|
- add_danger_messages(check_changelog_trailer(commit))
- end
- end
-
- def check_changelog_trailer(commit)
- trailer = commit.message.match(CHANGELOG_TRAILER_REGEX)
- name = trailer[:name]
- category = trailer[:category]
-
- unless name == 'Changelog'
- return ChangelogCheckResult.error("The changelog trailer for commit #{commit.sha} must be `Changelog` (starting with a capital C), not `#{name}`")
- end
-
- return ChangelogCheckResult.empty if CATEGORIES.include?(category)
-
- ChangelogCheckResult.error("Commit #{commit.sha} uses an invalid changelog category: #{category}")
- end
-
- def check_changelog_path
- check_result = ChangelogCheckResult.empty
- return check_result unless present?
-
- ee_changes = project_helper.all_ee_changes.dup
-
- if ee_changes.any? && !ee_changelog? && !required?
- check_result.warning("This MR changes code in `ee/`, but its Changelog commit is missing the [`EE: true` trailer](https://docs.gitlab.com/ee/development/changelog.html#gitlab-enterprise-changes). Consider adding it to your Changelog commits.")
- end
-
- if ee_changes.empty? && ee_changelog?
- check_result.warning("This MR has a Changelog commit for EE, but no code changes in `ee/`. Consider removing the `EE: true` trailer from your commits.")
- end
-
- if ee_changes.any? && ee_changelog? && required_reasons.include?(:db_changes)
- check_result.warning("This MR has a Changelog commit with the `EE: true` trailer, but there are database changes which [requires](https://docs.gitlab.com/ee/development/changelog.html#what-warrants-a-changelog-entry) the Changelog commit to not have the `EE: true` trailer. Consider removing the `EE: true` trailer from your commits.")
- end
-
- check_result
- end
-
- def required_reasons
- [].tap do |reasons|
- reasons << :db_changes if helper.changes.added.has_category?(:migration)
- reasons << :feature_flag_removed if helper.changes.deleted.has_category?(:feature_flag)
- end
- end
-
- def required?
- required_reasons.any?
- end
-
- def optional?
- categories_need_changelog? && mr_without_no_changelog_label?
- end
-
- def present?
- valid_changelog_commits.any?
- end
-
- def changelog_commits
- git.commits.select do |commit|
- commit.message.match?(CHANGELOG_TRAILER_REGEX)
- end
- end
-
- def valid_changelog_commits
- changelog_commits.select do |commit|
- trailer = commit.message.match(CHANGELOG_TRAILER_REGEX)
-
- CATEGORIES.include?(trailer[:category])
- end
- end
-
- def ee_changelog?
- changelog_commits.any? do |commit|
- commit.message.match?(CHANGELOG_EE_TRAILER_REGEX)
- end
- end
-
- def modified_text
- CHANGELOG_MODIFIED_URL_TEXT +
- (helper.ci? ? format(OPTIONAL_CHANGELOG_MESSAGE[:ci]) : OPTIONAL_CHANGELOG_MESSAGE[:local])
- end
-
- def required_texts
- required_reasons.each_with_object({}) do |required_reason, memo|
- memo[required_reason] =
- CHANGELOG_MISSING_URL_TEXT +
- (helper.ci? ? format(REQUIRED_CHANGELOG_MESSAGE[:ci], reason: REQUIRED_CHANGELOG_REASONS.fetch(required_reason)) : REQUIRED_CHANGELOG_MESSAGE[:local])
- end
- end
-
- def optional_text
- CHANGELOG_MISSING_URL_TEXT +
- (helper.ci? ? format(OPTIONAL_CHANGELOG_MESSAGE[:ci]) : OPTIONAL_CHANGELOG_MESSAGE[:local])
- end
-
- private
-
- def read_file(path)
- File.read(path)
- end
-
- def categories_need_changelog?
- (helper.changes.categories - NO_CHANGELOG_CATEGORIES).any?
- end
-
- def mr_without_no_changelog_label?
- (helper.mr_labels & NO_CHANGELOG_LABELS).empty?
- end
- end
- end
-end
diff --git a/tooling/danger/project_helper.rb b/tooling/danger/project_helper.rb
index eaf33608b83..02002e1d1b2 100644
--- a/tooling/danger/project_helper.rb
+++ b/tooling/danger/project_helper.rb
@@ -4,7 +4,6 @@ module Tooling
module Danger
module ProjectHelper
LOCAL_RULES ||= %w[
- changelog
ci_config
database
documentation
@@ -54,7 +53,7 @@ module Tooling
%r{\A(
((ee|jh)/)?app/((?!.*clusters)(?!.*alert_management)(?!.*views)(?!.*assets).+/)?integration.+ |
((ee|jh)/)?app/((?!.*search).+/)?project_service.+ |
- ((ee|jh)/)?app/(models|helpers|workers|services|controllers)/(.+/)?(jira_connect.+|.*hook.+) |
+ ((ee|jh)/)?app/(models|helpers|workers|services|serializers|controllers)/(.+/)?(jira_connect.+|.*hook.+) |
((ee|jh)/)?app/controllers/(.+/)?oauth/jira/.+ |
((ee|jh)/)?app/services/(.+/)?jira.+ |
((ee|jh)/)?app/workers/(.+/)?(propagate_integration.+|irker_worker\.rb) |
@@ -75,7 +74,9 @@ module Tooling
spec/frontend/tracking/.*\.js |
spec/frontend/tracking_spec\.js
)\z}x => [:frontend, :product_intelligence],
- %r{\A((ee|jh)/)?app/(assets|views)/} => :frontend,
+ %r{\A((ee|jh)/)?app/assets/} => :frontend,
+ %r{\A((ee|jh)/)?app/views/.*\.svg} => :frontend,
+ %r{\A((ee|jh)/)?app/views/} => [:frontend, :backend],
%r{\A((ee|jh)/)?public/} => :frontend,
%r{\A((ee|jh)/)?spec/(javascripts|frontend|frontend_integration)/} => :frontend,
%r{\A((ee|jh)/)?vendor/assets/} => :frontend,
@@ -133,6 +134,7 @@ module Tooling
%r{\A((ee|jh)/)?lib/gitlab/usage_data_counters/.*\.yml\z} => [:product_intelligence],
%r{\A((ee|jh)/)?config/(events|metrics)/((.*\.yml)|(schema\.json))\z} => [:product_intelligence],
%r{\A((ee|jh)/)?lib/gitlab/usage_data(_counters)?(/|\.rb)} => [:backend, :product_intelligence],
+ %r{\A((ee|jh)/)?(spec/)?lib/gitlab/usage(/|\.rb)} => [:backend, :product_intelligence],
%r{\A(
lib/gitlab/tracking\.rb |
spec/lib/gitlab/tracking_spec\.rb |
@@ -193,18 +195,10 @@ module Tooling
helper.ci? ? LOCAL_RULES | CI_ONLY_RULES : LOCAL_RULES
end
- def all_ee_changes
- helper.changes.files.grep(%r{\Aee/})
- end
-
def file_lines(filename)
read_file(filename).lines(chomp: true)
end
- def labels_to_add
- @labels_to_add ||= []
- end
-
private
def read_file(filename)
diff --git a/tooling/docs/deprecation_handling.rb b/tooling/docs/deprecation_handling.rb
index 7dfd3e1101d..a620eac4c91 100644
--- a/tooling/docs/deprecation_handling.rb
+++ b/tooling/docs/deprecation_handling.rb
@@ -25,7 +25,7 @@ module Docs
entries = entries.sort_by { |d| d["name"] }
milestones = entries.map { |entry| entry[milestone_key_name] }.uniq
- milestones = VersionSorter.sort(milestones)
+ milestones = VersionSorter.rsort(milestones)
load_template(template_path)
.result_with_hash(entries: entries, milestones: milestones)
diff --git a/tooling/graphql/docs/helper.rb b/tooling/graphql/docs/helper.rb
index ca153c806c4..e4f14129f3b 100644
--- a/tooling/graphql/docs/helper.rb
+++ b/tooling/graphql/docs/helper.rb
@@ -57,7 +57,7 @@ module Tooling
---
stage: Ecosystem
group: Integrations
- info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
+ info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
<!---
diff --git a/tooling/quality/test_level.rb b/tooling/quality/test_level.rb
index 624564ecd05..fd86708bb7d 100644
--- a/tooling/quality/test_level.rb
+++ b/tooling/quality/test_level.rb
@@ -55,6 +55,7 @@ module Quality
views
workers
tooling
+ component
],
integration: %w[
commands
diff --git a/vendor/assets/javascripts/vue-virtual-scroller/src/components/RecycleScroller.vue b/vendor/assets/javascripts/vue-virtual-scroller/src/components/RecycleScroller.vue
index 3ce35999d8a..d18c5f3ee97 100644
--- a/vendor/assets/javascripts/vue-virtual-scroller/src/components/RecycleScroller.vue
+++ b/vendor/assets/javascripts/vue-virtual-scroller/src/components/RecycleScroller.vue
@@ -59,6 +59,7 @@
<script>
import { ResizeObserver } from 'vue-resize'
+import 'vue-resize/dist/vue-resize.css'
import { ObserveVisibility } from 'vue-observe-visibility'
import ScrollParent from 'scrollparent'
import config from '../config'
diff --git a/workhorse/.tool-versions b/workhorse/.tool-versions
index 29cc9a03144..108bdd0f6a5 100644
--- a/workhorse/.tool-versions
+++ b/workhorse/.tool-versions
@@ -1 +1 @@
-golang 1.17.6
+golang 1.17.7
diff --git a/workhorse/backend.go b/workhorse/backend.go
index aef1214abc9..5aa246aa0e8 100644
--- a/workhorse/backend.go
+++ b/workhorse/backend.go
@@ -18,8 +18,8 @@ func parseAuthBackend(authBackend string) (*url.URL, error) {
}
}
- if backendURL.Scheme != "http" {
- return nil, fmt.Errorf("invalid scheme, only 'http' is allowed: %q", authBackend)
+ if backendURL.Scheme != "http" && backendURL.Scheme != "https" {
+ return nil, fmt.Errorf("invalid scheme, only 'http' and 'https' are allowed: %q", authBackend)
}
if backendURL.Host == "" {
diff --git a/workhorse/backend_test.go b/workhorse/backend_test.go
index c15947a75ad..8b62287fee4 100644
--- a/workhorse/backend_test.go
+++ b/workhorse/backend_test.go
@@ -10,7 +10,7 @@ func TestParseAuthBackendFailure(t *testing.T) {
failures := []string{
"",
"ftp://localhost",
- "https://example.com",
+ "gopher://example.com",
}
for _, example := range failures {
@@ -27,6 +27,7 @@ func TestParseAuthBackend(t *testing.T) {
{"localhost:3000", "localhost:3000", "http"},
{"http://localhost", "localhost", "http"},
{"localhost", "localhost", "http"},
+ {"https://localhost", "localhost", "https"},
}
for _, example := range successes {
diff --git a/workhorse/go.mod b/workhorse/go.mod
index 9fb4c25166b..3a264d41dac 100644
--- a/workhorse/go.mod
+++ b/workhorse/go.mod
@@ -28,7 +28,7 @@ require (
github.com/sirupsen/logrus v1.8.1
github.com/smartystreets/goconvey v1.6.4
github.com/stretchr/testify v1.7.0
- gitlab.com/gitlab-org/gitaly/v14 v14.3.0-rc2.0.20211007055622-df7dadcc3f74
+ gitlab.com/gitlab-org/gitaly/v14 v14.9.0-rc1
gitlab.com/gitlab-org/golang-archive-zip v0.1.1
gitlab.com/gitlab-org/labkit v1.6.0
gocloud.dev v0.23.0
diff --git a/workhorse/go.sum b/workhorse/go.sum
index 76590474a00..a565e93bfcc 100644
--- a/workhorse/go.sum
+++ b/workhorse/go.sum
@@ -108,6 +108,7 @@ github.com/HdrHistogram/hdrhistogram-go v1.1.0/go.mod h1:yDgFjdqOqDEKOvasDdhWNXY
github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY=
github.com/Joker/jade v1.0.1-0.20190614124447-d475f43051e7/go.mod h1:6E6s8o2AE4KhCrqr6GRJjdC/gNfTdxkIXvuGZZda2VM=
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
+github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0=
github.com/Microsoft/go-winio v0.4.19 h1:ZMZG0O5M8bhD0lgCURV8yu3hQ7TGvQ4L1ZW8+J0j9iE=
@@ -157,6 +158,8 @@ github.com/aws/aws-sdk-go v1.38.35 h1:7AlAO0FC+8nFjxiGKEmq0QLpiA8/XFr6eIxgRTwkdT
github.com/aws/aws-sdk-go v1.38.35/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro=
github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g=
github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g=
+github.com/beevik/ntp v0.3.0 h1:xzVrPrE4ziasFXgBVBZJDP0Wg/KpMwk2KHJ4Ba8GrDw=
+github.com/beevik/ntp v0.3.0/go.mod h1:hIHWr+l3+/clUnF44zdK+CWW7fO8dR5cIylAQ76NRpg=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
@@ -187,6 +190,7 @@ github.com/cloudflare/tableflip v1.2.2/go.mod h1:P4gRehmV6Z2bY5ao5ml9Pd8u6kuEnlB
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
+github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM=
@@ -195,6 +199,8 @@ github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
+github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
+github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/go-systemd/v22 v22.0.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk=
github.com/coreos/go-systemd/v22 v22.3.1/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
@@ -264,7 +270,6 @@ github.com/getsentry/raven-go v0.2.0 h1:no+xWJRb5ZI7eE8TWgIq1jLulQiIoLG0IfYxv5JY
github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ=
github.com/getsentry/sentry-go v0.5.1/go.mod h1:B8H7x8TYDPkeWPRzGpIiFO97LZP6rL8A3hEt8lUItMw=
github.com/getsentry/sentry-go v0.7.0/go.mod h1:pLFpD2Y5RHIKF9Bw3KH6/68DeN2K/XBJd8awjdPnUwg=
-github.com/getsentry/sentry-go v0.10.0 h1:6gwY+66NHKqyZrdi6O2jGdo7wGdo9b3B69E01NFgT5g=
github.com/getsentry/sentry-go v0.10.0/go.mod h1:kELm/9iCblqUYh+ZRML7PNdCvEuw24wBvJPYyi86cws=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s=
@@ -293,6 +298,7 @@ github.com/go-ini/ini v1.25.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3I
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o=
+github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
@@ -317,6 +323,7 @@ github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6Wezm
github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM=
github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
+github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
@@ -480,6 +487,44 @@ github.com/iris-contrib/i18n v0.0.0-20171121225848-987a633949d0/go.mod h1:pMCz62
github.com/iris-contrib/jade v1.1.3/go.mod h1:H/geBymxJhShH5kecoiOCSssPX7QWYH7UaeZTSWddIk=
github.com/iris-contrib/pongo2 v0.0.1/go.mod h1:Ssh+00+3GAZqSQb30AvBRNxBx7rf0GqwkjqxNd0u65g=
github.com/iris-contrib/schema v0.0.1/go.mod h1:urYA3uvUNG1TIIjOSCzHr9/LmbQo8LrOcOqfqxa4hXw=
+github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo=
+github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
+github.com/jackc/chunkreader/v2 v2.0.1/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
+github.com/jackc/pgconn v0.0.0-20190420214824-7e0022ef6ba3/go.mod h1:jkELnwuX+w9qN5YIfX0fl88Ehu4XC3keFuOJJk9pcnA=
+github.com/jackc/pgconn v0.0.0-20190824142844-760dd75542eb/go.mod h1:lLjNuW/+OfW9/pnVKPazfWOgNfH2aPem8YQ7ilXGvJE=
+github.com/jackc/pgconn v0.0.0-20190831204454-2fabfa3c18b7/go.mod h1:ZJKsE/KZfsUgOEh9hBm+xYTstcNHg7UPMVJqRfQxq4s=
+github.com/jackc/pgconn v1.8.0/go.mod h1:1C2Pb36bGIP9QHGBYCjnyhqu7Rv3sGshaQUvmfGIB/o=
+github.com/jackc/pgconn v1.9.0/go.mod h1:YctiPyvzfU11JFxoXokUOOKQXQmDMoJL9vJzHH8/2JY=
+github.com/jackc/pgconn v1.9.1-0.20210724152538-d89c8390a530/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI=
+github.com/jackc/pgconn v1.10.1/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI=
+github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8=
+github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE=
+github.com/jackc/pgmock v0.0.0-20201204152224-4fe30f7445fd/go.mod h1:hrBW0Enj2AZTNpt/7Y5rr2xe/9Mn757Wtb2xeBzPv2c=
+github.com/jackc/pgmock v0.0.0-20210724152146-4ad1a8207f65/go.mod h1:5R2h2EEX+qri8jOWMbJCtaPWkrrNc7OHwsp2TCqp7ak=
+github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
+github.com/jackc/pgproto3 v1.1.0/go.mod h1:eR5FA3leWg7p9aeAqi37XOTgTIbkABlvcPB3E5rlc78=
+github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190420180111-c116219b62db/go.mod h1:bhq50y+xrl9n5mRYyCBFKkpRVTLYJVWeCc+mEAI3yXA=
+github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190609003834-432c2951c711/go.mod h1:uH0AWtUmuShn0bcesswc4aBTWGvw0cAxIJp+6OB//Wg=
+github.com/jackc/pgproto3/v2 v2.0.0-rc3/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM=
+github.com/jackc/pgproto3/v2 v2.0.0-rc3.0.20190831210041-4c03ce451f29/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM=
+github.com/jackc/pgproto3/v2 v2.0.6/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
+github.com/jackc/pgproto3/v2 v2.1.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
+github.com/jackc/pgproto3/v2 v2.2.0/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
+github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E=
+github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01CGwFsrv11mJRHWJ6aifDLfdV3aVjFF0zg=
+github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc=
+github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrUS8lot6TQqcg7mtthZ9T0EoIBFiJcmcyw=
+github.com/jackc/pgtype v1.8.1-0.20210724151600-32e20a603178/go.mod h1:C516IlIV9NKqfsMCXTdChteoXmwgUceqaLfjg2e3NlM=
+github.com/jackc/pgtype v1.9.1/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4=
+github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y=
+github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM=
+github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc=
+github.com/jackc/pgx/v4 v4.12.1-0.20210724153913-640aa07df17c/go.mod h1:1QD0+tgSXP7iUjYm9C1NxKhny7lq6ee99u/z+IHFcgs=
+github.com/jackc/pgx/v4 v4.14.1/go.mod h1:RgDuE4Z34o7XE92RpLsvFiOEfrAUT0Xt2KxvX73W06M=
+github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
+github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
+github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
+github.com/jackc/puddle v1.2.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
github.com/jcmturner/gofork v0.0.0-20190328161633-dc7c13fece03/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o=
github.com/jcmturner/gofork v1.0.0/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o=
@@ -525,7 +570,6 @@ github.com/kataras/neffos v0.0.14/go.mod h1:8lqADm8PnbeFfL7CLXh1WHw53dG27MC3pgi2
github.com/kataras/pio v0.0.0-20190103105442-ea782b38602d/go.mod h1:NV88laa9UiiDuX9AhMbDPkGYSPugBOV6yTZB1l2K9Z0=
github.com/kataras/pio v0.0.2/go.mod h1:hAoW0t9UmXi4R5Oyq5Z4irTbaTsOemSrDGUtaTl7Dro=
github.com/kataras/sitemap v0.0.5/go.mod h1:KY2eugMKiPwsJgx7+U103YZehfvNGOXURubcGyk0Bz8=
-github.com/kelseyhightower/envconfig v1.3.0 h1:IvRS4f2VcIQy6j4ORGIf9145T/AsUB+oY8LyvN8BXNM=
github.com/kelseyhightower/envconfig v1.3.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg=
github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
@@ -547,18 +591,22 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
+github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/labstack/echo/v4 v4.1.11/go.mod h1:i541M3Fj6f76NZtHSj7TXnyM8n2gaodfvfxNnFqi74g=
github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k=
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
+github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
+github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.10.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
-github.com/lib/pq v1.10.1 h1:6VXZrLU0jHBYyAqrSPa+MgPfnSvTPuMgK+k0o5kVFWo=
github.com/lib/pq v1.10.1/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
+github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/libgit2/git2go v0.0.0-20190104134018-ecaeb7a21d47/go.mod h1:4bKN42efkbNYMZlvDfxGDxzl066GhpvIircZDsm8Y+Y=
github.com/libgit2/git2go/v31 v31.4.12/go.mod h1:c/rkJcBcUFx6wHaT++UwNpKvIsmPNqCeQ/vzO4DrEec=
+github.com/libgit2/git2go/v33 v33.0.6/go.mod h1:KdpqkU+6+++4oHna/MIOgx4GCQ92IPCdpVRMRI80J+4=
github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM=
github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20200305213919-a88bf8de3718/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM=
github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20210210170715-a8dfcb80d3a7 h1:YjW+hUb8Fh2S58z4av4t/0cBMK/Q0aP48RocCFsC8yI=
@@ -570,12 +618,14 @@ github.com/lightstep/lightstep-tracer-go v0.24.0/go.mod h1:RnONwHKg89zYPmF+Uig5P
github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
+github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-ieproxy v0.0.1 h1:qiyop7gCflfhwCzGyeT0gro3sF9AIg9HU98JORTkqfI=
github.com/mattn/go-ieproxy v0.0.1/go.mod h1:pYabZ6IHcRpFh7vIaLfK7rdcWgFEb3SFJ6/gNWuh88E=
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
+github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
@@ -668,7 +718,6 @@ github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FI
github.com/pborman/getopt v0.0.0-20170112200414-7148bc3a4c30/go.mod h1:85jBQOZwpVEaDAr341tbn15RS4fCAsIst0qp7i8ex1o=
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
-github.com/pelletier/go-toml v1.8.1 h1:1Nf83orprkJyknT6h7zbuEGUEjcyVlCxSUGTENmNCRM=
github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc=
github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac=
github.com/philhofer/fwd v1.0.0 h1:UbZqGr5Y38ApvM/V/jEljVxwocdweyH+vmYvRPBnbqQ=
@@ -721,7 +770,9 @@ github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.3.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/rogpeppe/go-internal v1.4.0/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
-github.com/rubenv/sql-migrate v0.0.0-20191213152630-06338513c237 h1:q6N3WgCVttyX9Fg3e4nrLohUXvAlTu44Ugc4m6qlezc=
+github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
+github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU=
+github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc=
github.com/rubenv/sql-migrate v0.0.0-20191213152630-06338513c237/go.mod h1:rtQlpHw+eR6UrqaS3kX1VYeaCxzCVdimDS7g5Ln4pPc=
github.com/rubyist/tracerx v0.0.0-20170927163412-787959303086/go.mod h1:YpdgDXpumPB/+EGmGTYHeiW/0QVFRzBYTNFaxWfPDk4=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
@@ -731,6 +782,7 @@ github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFo
github.com/ryszard/goskiplist v0.0.0-20150312221310-2dfbae5fcf46 h1:GHRpF1pTW19a8tTFrMLUcfWwyC0pnifVo2ClaLq+hP8=
github.com/ryszard/goskiplist v0.0.0-20150312221310-2dfbae5fcf46/go.mod h1:uAQ5PCi+MFsC7HjREoAz1BU+Mq60+05gifQSsHSDG/8=
github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E=
+github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
github.com/sebest/xff v0.0.0-20160910043805-6c115e0ffa35/go.mod h1:wozgYq9WEBQBaIJe4YZ0qTSFAMxmcwBhQH0fO0R34Z0=
@@ -745,6 +797,8 @@ github.com/shabbyrobe/gocovmerge v0.0.0-20190829150210-3e036491d500/go.mod h1:+n
github.com/shirou/gopsutil v2.20.1+incompatible h1:oIq9Cq4i84Hk8uQAUOG3eNdI/29hBawGrD5YRl6JRDY=
github.com/shirou/gopsutil v2.20.1+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
github.com/shogo82148/go-shuffle v0.0.0-20170808115208-59829097ff3b/go.mod h1:2htx6lmL0NGLHlO8ZCf+lQBGBHIbEujyywxJArf+2Yc=
+github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
+github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
github.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
@@ -827,12 +881,13 @@ github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=
github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0=
gitlab.com/gitlab-org/gitaly v1.68.0 h1:VlcJs1+PrhW7lqJUU7Fh1q8FMJujmbbivdfde/cwB98=
gitlab.com/gitlab-org/gitaly v1.68.0/go.mod h1:/pCsB918Zu5wFchZ9hLYin9WkJ2yQqdVNz0zlv5HbXg=
gitlab.com/gitlab-org/gitaly/v14 v14.0.0-rc1/go.mod h1:4Cz8tOAyueSZX5o6gYum1F/unupaOclxqETPcg4ODvQ=
-gitlab.com/gitlab-org/gitaly/v14 v14.3.0-rc2.0.20211007055622-df7dadcc3f74 h1:7R4FHfZ9lBH0BLtnGNjRmHvjz6epnXPodhiT0pR96PI=
-gitlab.com/gitlab-org/gitaly/v14 v14.3.0-rc2.0.20211007055622-df7dadcc3f74/go.mod h1:2McjFiZrwflPGtXSquCAXWzewmxTPytoI/vamNz/QPM=
+gitlab.com/gitlab-org/gitaly/v14 v14.9.0-rc1 h1:9vStRdXxcBQ8dHlVnpV28fwLOgyDkSFIpGnPqwzdTvw=
+gitlab.com/gitlab-org/gitaly/v14 v14.9.0-rc1/go.mod h1:Xk5pn6IWsejg3z2X6BRczC5QaI97PRF3GU5OrJ5Amkg=
gitlab.com/gitlab-org/gitlab-shell v1.9.8-0.20201117050822-3f9890ef73dc/go.mod h1:5QSTbpAHY2v0iIH5uHh2KA9w7sPUqPmnLjDApI/sv1U=
gitlab.com/gitlab-org/gitlab-shell v1.9.8-0.20210720163109-50da611814d2/go.mod h1:QWDYBwuy24qGMandtCngLRPzFgnGPg6LSNoJWPKmJMc=
gitlab.com/gitlab-org/golang-archive-zip v0.1.1 h1:35k9giivbxwF03+8A05Cm8YoxoakU8FBCj5gysjCTCE=
@@ -871,6 +926,7 @@ go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+
go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
+go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ=
@@ -882,12 +938,14 @@ golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnf
golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
@@ -897,8 +955,10 @@ golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPh
golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
-golang.org/x/crypto v0.0.0-20210506145944-38f3c27a63bf h1:B2n+Zi5QeYRDAEodEu72OS36gmTWjgpXr2+cWcBW90o=
golang.org/x/crypto v0.0.0-20210506145944-38f3c27a63bf/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
+golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 h1:/UOmuWzQfxxo9UtlXMwuQU8CMgg1eZXqTRwkSQJWKOI=
+golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
@@ -1039,6 +1099,7 @@ golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5h
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190310054646-10058d7d4faa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -1099,8 +1160,10 @@ golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210420205809-ac73e9fd8988/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210503080704-8803ae5d1324/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210503173754-0981d6026fa6 h1:cdsMqa2nXzqlgs183pHxtvoVwU7CyzaCTAUOg94af4c=
golang.org/x/sys v0.0.0-20210503173754-0981d6026fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20211102192858-4dd72447c267 h1:7zYaz3tjChtpayGDzu6H0hDAUM5zIGA2XW7kRNgQ0jc=
+golang.org/x/sys v0.0.0-20211102192858-4dd72447c267/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -1135,12 +1198,14 @@ golang.org/x/tools v0.0.0-20190327201419-c70d86f8b7cf/go.mod h1:LCzVGOaR6xXOjkQ3
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190422233926-fe54fb35175b/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
+golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20190829051458-42f498d34c4d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191004055002-72853e10c5a3/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
@@ -1185,6 +1250,8 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f
golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.0 h1:po9/4sTYwZU9lPhi1tOrb4hCv3qrhiQ77LZfGa2OjwY=
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
+golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -1343,8 +1410,8 @@ gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMy
gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o=
gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE=
gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y=
-gopkg.in/gorp.v1 v1.7.2 h1:j3DWlAyGVv8whO7AcIWznQ2Yj7yJkn34B8s63GViAAw=
gopkg.in/gorp.v1 v1.7.2/go.mod h1:Wo3h+DBQZIxATwftsglhdD/62zRFPhGhTiu5jUJmCaw=
+gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s=
gopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/jcmturner/aescts.v1 v1.0.1/go.mod h1:nsR8qBOg+OucoIW+WMhB3GspUQXq9XorLnQb9XtvcOo=
gopkg.in/jcmturner/dnsutils.v1 v1.0.1/go.mod h1:m3v+5svpVOhtFAP/wSz+yzh4Mc0Fg7eRhxkJMWSIz9Q=
diff --git a/workhorse/internal/artifacts/artifacts_store_test.go b/workhorse/internal/artifacts/artifacts_store_test.go
deleted file mode 100644
index f9fb28cf7ce..00000000000
--- a/workhorse/internal/artifacts/artifacts_store_test.go
+++ /dev/null
@@ -1,335 +0,0 @@
-package artifacts
-
-import (
- "archive/zip"
- "bytes"
- "crypto/md5"
- "encoding/hex"
- "fmt"
- "io/ioutil"
- "mime/multipart"
- "net/http"
- "net/http/httptest"
- "os"
- "testing"
- "time"
-
- "github.com/stretchr/testify/require"
-
- "gitlab.com/gitlab-org/gitlab/workhorse/internal/api"
- "gitlab.com/gitlab-org/gitlab/workhorse/internal/objectstore/test"
- "gitlab.com/gitlab-org/gitlab/workhorse/internal/testhelper"
-)
-
-func createTestZipArchive(t *testing.T) (data []byte, md5Hash string) {
- var buffer bytes.Buffer
- archive := zip.NewWriter(&buffer)
- fileInArchive, err := archive.Create("test.file")
- require.NoError(t, err)
- fmt.Fprint(fileInArchive, "test")
- archive.Close()
- data = buffer.Bytes()
-
- hasher := md5.New()
- hasher.Write(data)
- hexHash := hasher.Sum(nil)
- md5Hash = hex.EncodeToString(hexHash)
-
- return data, md5Hash
-}
-
-func createTestMultipartForm(t *testing.T, data []byte) (bytes.Buffer, string) {
- var buffer bytes.Buffer
- writer := multipart.NewWriter(&buffer)
- file, err := writer.CreateFormFile("file", "my.file")
- require.NoError(t, err)
- file.Write(data)
- writer.Close()
- return buffer, writer.FormDataContentType()
-}
-
-func testUploadArtifactsFromTestZip(t *testing.T, ts *httptest.Server) *httptest.ResponseRecorder {
- archiveData, _ := createTestZipArchive(t)
- contentBuffer, contentType := createTestMultipartForm(t, archiveData)
-
- return testUploadArtifacts(t, contentType, ts.URL+Path, &contentBuffer)
-}
-
-func TestUploadHandlerSendingToExternalStorage(t *testing.T) {
- tempPath, err := ioutil.TempDir("", "uploads")
- if err != nil {
- t.Fatal(err)
- }
- defer os.RemoveAll(tempPath)
-
- archiveData, md5 := createTestZipArchive(t)
- archiveFile, err := ioutil.TempFile("", "artifact.zip")
- require.NoError(t, err)
- defer os.Remove(archiveFile.Name())
- _, err = archiveFile.Write(archiveData)
- require.NoError(t, err)
- archiveFile.Close()
-
- storeServerCalled := 0
- storeServerMux := http.NewServeMux()
- storeServerMux.HandleFunc("/url/put", func(w http.ResponseWriter, r *http.Request) {
- require.Equal(t, "PUT", r.Method)
-
- receivedData, err := ioutil.ReadAll(r.Body)
- require.NoError(t, err)
- require.Equal(t, archiveData, receivedData)
-
- storeServerCalled++
- w.Header().Set("ETag", md5)
- w.WriteHeader(200)
- })
- storeServerMux.HandleFunc("/store-id", func(w http.ResponseWriter, r *http.Request) {
- http.ServeFile(w, r, archiveFile.Name())
- })
-
- responseProcessorCalled := 0
- responseProcessor := func(w http.ResponseWriter, r *http.Request) {
- require.Equal(t, "store-id", r.FormValue("file.remote_id"))
- require.NotEmpty(t, r.FormValue("file.remote_url"))
- w.WriteHeader(200)
- responseProcessorCalled++
- }
-
- storeServer := httptest.NewServer(storeServerMux)
- defer storeServer.Close()
-
- qs := fmt.Sprintf("?%s=%s", ArtifactFormatKey, ArtifactFormatZip)
-
- tests := []struct {
- name string
- preauth *api.Response
- }{
- {
- name: "ObjectStore Upload",
- preauth: &api.Response{
- RemoteObject: api.RemoteObject{
- StoreURL: storeServer.URL + "/url/put" + qs,
- ID: "store-id",
- GetURL: storeServer.URL + "/store-id",
- },
- },
- },
- }
-
- for _, test := range tests {
- t.Run(test.name, func(t *testing.T) {
- storeServerCalled = 0
- responseProcessorCalled = 0
-
- ts := testArtifactsUploadServer(t, test.preauth, responseProcessor)
- defer ts.Close()
-
- contentBuffer, contentType := createTestMultipartForm(t, archiveData)
- response := testUploadArtifacts(t, contentType, ts.URL+Path+qs, &contentBuffer)
- require.Equal(t, http.StatusOK, response.Code)
- testhelper.RequireResponseHeader(t, response, MetadataHeaderKey, MetadataHeaderPresent)
- require.Equal(t, 1, storeServerCalled, "store should be called only once")
- require.Equal(t, 1, responseProcessorCalled, "response processor should be called only once")
- })
- }
-}
-
-func TestUploadHandlerSendingToExternalStorageAndStorageServerUnreachable(t *testing.T) {
- tempPath, err := ioutil.TempDir("", "uploads")
- if err != nil {
- t.Fatal(err)
- }
- defer os.RemoveAll(tempPath)
-
- responseProcessor := func(w http.ResponseWriter, r *http.Request) {
- t.Fatal("it should not be called")
- }
-
- authResponse := &api.Response{
- TempPath: tempPath,
- RemoteObject: api.RemoteObject{
- StoreURL: "http://localhost:12323/invalid/url",
- ID: "store-id",
- },
- }
-
- ts := testArtifactsUploadServer(t, authResponse, responseProcessor)
- defer ts.Close()
-
- response := testUploadArtifactsFromTestZip(t, ts)
- require.Equal(t, http.StatusInternalServerError, response.Code)
-}
-
-func TestUploadHandlerSendingToExternalStorageAndInvalidURLIsUsed(t *testing.T) {
- tempPath, err := ioutil.TempDir("", "uploads")
- if err != nil {
- t.Fatal(err)
- }
- defer os.RemoveAll(tempPath)
-
- responseProcessor := func(w http.ResponseWriter, r *http.Request) {
- t.Fatal("it should not be called")
- }
-
- authResponse := &api.Response{
- TempPath: tempPath,
- RemoteObject: api.RemoteObject{
- StoreURL: "htt:////invalid-url",
- ID: "store-id",
- },
- }
-
- ts := testArtifactsUploadServer(t, authResponse, responseProcessor)
- defer ts.Close()
-
- response := testUploadArtifactsFromTestZip(t, ts)
- require.Equal(t, http.StatusInternalServerError, response.Code)
-}
-
-func TestUploadHandlerSendingToExternalStorageAndItReturnsAnError(t *testing.T) {
- putCalledTimes := 0
-
- storeServerMux := http.NewServeMux()
- storeServerMux.HandleFunc("/url/put", func(w http.ResponseWriter, r *http.Request) {
- putCalledTimes++
- require.Equal(t, "PUT", r.Method)
- w.WriteHeader(510)
- })
-
- responseProcessor := func(w http.ResponseWriter, r *http.Request) {
- t.Fatal("it should not be called")
- }
-
- storeServer := httptest.NewServer(storeServerMux)
- defer storeServer.Close()
-
- authResponse := &api.Response{
- RemoteObject: api.RemoteObject{
- StoreURL: storeServer.URL + "/url/put",
- ID: "store-id",
- },
- }
-
- ts := testArtifactsUploadServer(t, authResponse, responseProcessor)
- defer ts.Close()
-
- response := testUploadArtifactsFromTestZip(t, ts)
- require.Equal(t, http.StatusInternalServerError, response.Code)
- require.Equal(t, 1, putCalledTimes, "upload should be called only once")
-}
-
-func TestUploadHandlerSendingToExternalStorageAndSupportRequestTimeout(t *testing.T) {
- putCalledTimes := 0
-
- storeServerMux := http.NewServeMux()
- storeServerMux.HandleFunc("/url/put", func(w http.ResponseWriter, r *http.Request) {
- putCalledTimes++
- require.Equal(t, "PUT", r.Method)
- time.Sleep(10 * time.Second)
- w.WriteHeader(510)
- })
-
- responseProcessor := func(w http.ResponseWriter, r *http.Request) {
- t.Fatal("it should not be called")
- }
-
- storeServer := httptest.NewServer(storeServerMux)
- defer storeServer.Close()
-
- authResponse := &api.Response{
- RemoteObject: api.RemoteObject{
- StoreURL: storeServer.URL + "/url/put",
- ID: "store-id",
- Timeout: 1,
- },
- }
-
- ts := testArtifactsUploadServer(t, authResponse, responseProcessor)
- defer ts.Close()
-
- response := testUploadArtifactsFromTestZip(t, ts)
- require.Equal(t, http.StatusInternalServerError, response.Code)
- require.Equal(t, 1, putCalledTimes, "upload should be called only once")
-}
-
-func TestUploadHandlerMultipartUploadSizeLimit(t *testing.T) {
- os, server := test.StartObjectStore()
- defer server.Close()
-
- err := os.InitiateMultipartUpload(test.ObjectPath)
- require.NoError(t, err)
-
- objectURL := server.URL + test.ObjectPath
-
- uploadSize := 10
- preauth := &api.Response{
- RemoteObject: api.RemoteObject{
- ID: "store-id",
- MultipartUpload: &api.MultipartUploadParams{
- PartSize: 1,
- PartURLs: []string{objectURL + "?partNumber=1"},
- AbortURL: objectURL, // DELETE
- CompleteURL: objectURL, // POST
- },
- },
- }
-
- responseProcessor := func(w http.ResponseWriter, r *http.Request) {
- t.Fatal("it should not be called")
- }
-
- ts := testArtifactsUploadServer(t, preauth, responseProcessor)
- defer ts.Close()
-
- contentBuffer, contentType := createTestMultipartForm(t, make([]byte, uploadSize))
- response := testUploadArtifacts(t, contentType, ts.URL+Path, &contentBuffer)
- require.Equal(t, http.StatusRequestEntityTooLarge, response.Code)
- require.Eventually(t, func() bool {
- return !os.IsMultipartUpload(test.ObjectPath)
- }, time.Second, time.Millisecond, "MultipartUpload should not be in progress anymore")
- require.Empty(t, os.GetObjectMD5(test.ObjectPath), "upload should have failed, so the object should not exists")
-}
-
-func TestUploadHandlerMultipartUploadMaximumSizeFromApi(t *testing.T) {
- os, server := test.StartObjectStore()
- defer server.Close()
-
- err := os.InitiateMultipartUpload(test.ObjectPath)
- require.NoError(t, err)
-
- objectURL := server.URL + test.ObjectPath
-
- uploadSize := int64(10)
- maxSize := uploadSize - 1
- preauth := &api.Response{
- MaximumSize: maxSize,
- RemoteObject: api.RemoteObject{
- ID: "store-id",
- MultipartUpload: &api.MultipartUploadParams{
- PartSize: uploadSize,
- PartURLs: []string{objectURL + "?partNumber=1"},
- AbortURL: objectURL, // DELETE
- CompleteURL: objectURL, // POST
- },
- },
- }
-
- responseProcessor := func(w http.ResponseWriter, r *http.Request) {
- t.Fatal("it should not be called")
- }
-
- ts := testArtifactsUploadServer(t, preauth, responseProcessor)
- defer ts.Close()
-
- contentBuffer, contentType := createTestMultipartForm(t, make([]byte, uploadSize))
- response := testUploadArtifacts(t, contentType, ts.URL+Path, &contentBuffer)
- require.Equal(t, http.StatusRequestEntityTooLarge, response.Code)
-
- testhelper.Retry(t, 5*time.Second, func() error {
- if os.GetObjectMD5(test.ObjectPath) == "" {
- return nil
- }
-
- return fmt.Errorf("file is still present")
- })
-}
diff --git a/workhorse/internal/artifacts/artifacts_upload.go b/workhorse/internal/artifacts/artifacts_upload.go
deleted file mode 100644
index f1fd69082f8..00000000000
--- a/workhorse/internal/artifacts/artifacts_upload.go
+++ /dev/null
@@ -1,167 +0,0 @@
-package artifacts
-
-import (
- "context"
- "fmt"
- "io"
- "mime/multipart"
- "net/http"
- "os"
- "os/exec"
- "strings"
- "syscall"
-
- "github.com/prometheus/client_golang/prometheus"
- "github.com/prometheus/client_golang/prometheus/promauto"
- "gitlab.com/gitlab-org/labkit/log"
-
- "gitlab.com/gitlab-org/gitlab/workhorse/internal/api"
- "gitlab.com/gitlab-org/gitlab/workhorse/internal/filestore"
- "gitlab.com/gitlab-org/gitlab/workhorse/internal/helper"
- "gitlab.com/gitlab-org/gitlab/workhorse/internal/upload"
- "gitlab.com/gitlab-org/gitlab/workhorse/internal/zipartifacts"
-)
-
-// Sent by the runner: https://gitlab.com/gitlab-org/gitlab-runner/blob/c24da19ecce8808d9d2950896f70c94f5ea1cc2e/network/gitlab.go#L580
-const (
- ArtifactFormatKey = "artifact_format"
- ArtifactFormatZip = "zip"
- ArtifactFormatDefault = ""
-)
-
-var zipSubcommandsErrorsCounter = promauto.NewCounterVec(
- prometheus.CounterOpts{
- Name: "gitlab_workhorse_zip_subcommand_errors_total",
- Help: "Errors comming from subcommands used for processing ZIP archives",
- }, []string{"error"})
-
-type artifactsUploadProcessor struct {
- opts *filestore.SaveFileOpts
- format string
-
- upload.SavedFileTracker
-}
-
-func (a *artifactsUploadProcessor) generateMetadataFromZip(ctx context.Context, file *filestore.FileHandler) (*filestore.FileHandler, error) {
- metaReader, metaWriter := io.Pipe()
- defer metaWriter.Close()
-
- metaOpts := &filestore.SaveFileOpts{
- LocalTempPath: a.opts.LocalTempPath,
- TempFilePrefix: "metadata.gz",
- }
- if metaOpts.LocalTempPath == "" {
- metaOpts.LocalTempPath = os.TempDir()
- }
-
- fileName := file.LocalPath
- if fileName == "" {
- fileName = file.RemoteURL
- }
-
- zipMd := exec.CommandContext(ctx, "gitlab-zip-metadata", fileName)
- zipMd.Stderr = log.ContextLogger(ctx).Writer()
- zipMd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
- zipMd.Stdout = metaWriter
-
- if err := zipMd.Start(); err != nil {
- return nil, err
- }
- defer helper.CleanUpProcessGroup(zipMd)
-
- type saveResult struct {
- error
- *filestore.FileHandler
- }
- done := make(chan saveResult)
- go func() {
- var result saveResult
- result.FileHandler, result.error = filestore.SaveFileFromReader(ctx, metaReader, -1, metaOpts)
-
- done <- result
- }()
-
- if err := zipMd.Wait(); err != nil {
- st, ok := helper.ExitStatus(err)
-
- if !ok {
- return nil, err
- }
-
- zipSubcommandsErrorsCounter.WithLabelValues(zipartifacts.ErrorLabelByCode(st)).Inc()
-
- if st == zipartifacts.CodeNotZip {
- return nil, nil
- }
-
- if st == zipartifacts.CodeLimitsReached {
- return nil, zipartifacts.ErrBadMetadata
- }
- }
-
- metaWriter.Close()
- result := <-done
- return result.FileHandler, result.error
-}
-
-func (a *artifactsUploadProcessor) ProcessFile(ctx context.Context, formName string, file *filestore.FileHandler, writer *multipart.Writer) error {
- // ProcessFile for artifacts requires file form-data field name to eq `file`
-
- if formName != "file" {
- return fmt.Errorf("invalid form field: %q", formName)
- }
- if a.Count() > 0 {
- return fmt.Errorf("artifacts request contains more than one file")
- }
- a.Track(formName, file.LocalPath)
-
- select {
- case <-ctx.Done():
- return fmt.Errorf("ProcessFile: context done")
- default:
- }
-
- if !strings.EqualFold(a.format, ArtifactFormatZip) && a.format != ArtifactFormatDefault {
- return nil
- }
-
- // TODO: can we rely on disk for shipping metadata? Not if we split workhorse and rails in 2 different PODs
- metadata, err := a.generateMetadataFromZip(ctx, file)
- if err != nil {
- return err
- }
-
- if metadata != nil {
- fields, err := metadata.GitLabFinalizeFields("metadata")
- if err != nil {
- return fmt.Errorf("finalize metadata field error: %v", err)
- }
-
- for k, v := range fields {
- writer.WriteField(k, v)
- }
-
- a.Track("metadata", metadata.LocalPath)
- }
-
- return nil
-}
-
-func (a *artifactsUploadProcessor) Name() string {
- return "artifacts"
-}
-
-func UploadArtifacts(myAPI *api.API, h http.Handler, p upload.Preparer) http.Handler {
- return myAPI.PreAuthorizeHandler(func(w http.ResponseWriter, r *http.Request, a *api.Response) {
- opts, _, err := p.Prepare(a)
- if err != nil {
- helper.Fail500(w, r, fmt.Errorf("UploadArtifacts: error preparing file storage options"))
- return
- }
-
- format := r.URL.Query().Get(ArtifactFormatKey)
-
- mg := &artifactsUploadProcessor{opts: opts, format: format, SavedFileTracker: upload.SavedFileTracker{Request: r}}
- upload.InterceptMultipartFiles(w, r, h, a, mg, opts)
- }, "/authorize")
-}
diff --git a/workhorse/internal/artifacts/artifacts_upload_test.go b/workhorse/internal/artifacts/artifacts_upload_test.go
deleted file mode 100644
index 3e8a52be1a1..00000000000
--- a/workhorse/internal/artifacts/artifacts_upload_test.go
+++ /dev/null
@@ -1,322 +0,0 @@
-package artifacts
-
-import (
- "archive/zip"
- "bytes"
- "compress/gzip"
- "encoding/json"
- "fmt"
- "io"
- "io/ioutil"
- "mime/multipart"
- "net/http"
- "net/http/httptest"
- "os"
- "testing"
-
- "github.com/golang-jwt/jwt/v4"
-
- "gitlab.com/gitlab-org/gitlab/workhorse/internal/api"
- "gitlab.com/gitlab-org/gitlab/workhorse/internal/filestore"
- "gitlab.com/gitlab-org/gitlab/workhorse/internal/helper"
- "gitlab.com/gitlab-org/gitlab/workhorse/internal/proxy"
- "gitlab.com/gitlab-org/gitlab/workhorse/internal/testhelper"
- "gitlab.com/gitlab-org/gitlab/workhorse/internal/upload"
- "gitlab.com/gitlab-org/gitlab/workhorse/internal/upstream/roundtripper"
- "gitlab.com/gitlab-org/gitlab/workhorse/internal/zipartifacts"
-
- "github.com/stretchr/testify/require"
-)
-
-const (
- MetadataHeaderKey = "Metadata-Status"
- MetadataHeaderPresent = "present"
- MetadataHeaderMissing = "missing"
- Path = "/url/path"
-)
-
-func testArtifactsUploadServer(t *testing.T, authResponse *api.Response, bodyProcessor func(w http.ResponseWriter, r *http.Request)) *httptest.Server {
- mux := http.NewServeMux()
- mux.HandleFunc(Path+"/authorize", func(w http.ResponseWriter, r *http.Request) {
- if r.Method != "POST" {
- t.Fatal("Expected POST request")
- }
-
- w.Header().Set("Content-Type", api.ResponseContentType)
-
- data, err := json.Marshal(&authResponse)
- if err != nil {
- t.Fatal("Expected to marshal")
- }
- w.Write(data)
- })
- mux.HandleFunc(Path, func(w http.ResponseWriter, r *http.Request) {
- opts, err := filestore.GetOpts(authResponse)
- require.NoError(t, err)
-
- if r.Method != "POST" {
- t.Fatal("Expected POST request")
- }
- if opts.IsLocal() {
- if r.FormValue("file.path") == "" {
- t.Fatal("Expected file to be present")
- return
- }
-
- _, err := ioutil.ReadFile(r.FormValue("file.path"))
- if err != nil {
- t.Fatal("Expected file to be readable")
- return
- }
- } else {
- if r.FormValue("file.remote_url") == "" {
- t.Fatal("Expected file to be remote accessible")
- return
- }
- }
-
- if r.FormValue("metadata.path") != "" {
- metadata, err := ioutil.ReadFile(r.FormValue("metadata.path"))
- if err != nil {
- t.Fatal("Expected metadata to be readable")
- return
- }
- gz, err := gzip.NewReader(bytes.NewReader(metadata))
- if err != nil {
- t.Fatal("Expected metadata to be valid gzip")
- return
- }
- defer gz.Close()
- metadata, err = ioutil.ReadAll(gz)
- if err != nil {
- t.Fatal("Expected metadata to be valid")
- return
- }
- if !bytes.HasPrefix(metadata, []byte(zipartifacts.MetadataHeaderPrefix+zipartifacts.MetadataHeader)) {
- t.Fatal("Expected metadata to be of valid format")
- return
- }
-
- w.Header().Set(MetadataHeaderKey, MetadataHeaderPresent)
-
- } else {
- w.Header().Set(MetadataHeaderKey, MetadataHeaderMissing)
- }
-
- w.WriteHeader(http.StatusOK)
-
- if bodyProcessor != nil {
- bodyProcessor(w, r)
- }
- })
- return testhelper.TestServerWithHandler(nil, mux.ServeHTTP)
-}
-
-type testServer struct {
- url string
- writer *multipart.Writer
- buffer *bytes.Buffer
- fileWriter io.Writer
- cleanup func()
-}
-
-func setupWithTmpPath(t *testing.T, filename string, includeFormat bool, format string, authResponse *api.Response, bodyProcessor func(w http.ResponseWriter, r *http.Request)) *testServer {
- tempPath, err := ioutil.TempDir("", "uploads")
- require.NoError(t, err)
-
- if authResponse == nil {
- authResponse = &api.Response{TempPath: tempPath}
- }
-
- ts := testArtifactsUploadServer(t, authResponse, bodyProcessor)
-
- var buffer bytes.Buffer
- writer := multipart.NewWriter(&buffer)
- fileWriter, err := writer.CreateFormFile(filename, "my.file")
- require.NotNil(t, fileWriter)
- require.NoError(t, err)
-
- cleanup := func() {
- ts.Close()
- require.NoError(t, os.RemoveAll(tempPath))
- require.NoError(t, writer.Close())
- }
-
- qs := ""
-
- if includeFormat {
- qs = fmt.Sprintf("?%s=%s", ArtifactFormatKey, format)
- }
-
- return &testServer{url: ts.URL + Path + qs, writer: writer, buffer: &buffer, fileWriter: fileWriter, cleanup: cleanup}
-}
-
-func testUploadArtifacts(t *testing.T, contentType, url string, body io.Reader) *httptest.ResponseRecorder {
- httpRequest, err := http.NewRequest("POST", url, body)
- require.NoError(t, err)
-
- httpRequest.Header.Set("Content-Type", contentType)
- response := httptest.NewRecorder()
- parsedURL := helper.URLMustParse(url)
- roundTripper := roundtripper.NewTestBackendRoundTripper(parsedURL)
- testhelper.ConfigureSecret()
- apiClient := api.NewAPI(parsedURL, "123", roundTripper)
- proxyClient := proxy.NewProxy(parsedURL, "123", roundTripper)
- UploadArtifacts(apiClient, proxyClient, &upload.DefaultPreparer{}).ServeHTTP(response, httpRequest)
- return response
-}
-
-func TestUploadHandlerAddingMetadata(t *testing.T) {
- testCases := []struct {
- desc string
- format string
- includeFormat bool
- }{
- {
- desc: "ZIP format",
- format: ArtifactFormatZip,
- includeFormat: true,
- },
- {
- desc: "default format",
- format: ArtifactFormatDefault,
- includeFormat: true,
- },
- {
- desc: "default format without artifact_format",
- format: ArtifactFormatDefault,
- includeFormat: false,
- },
- }
-
- for _, tc := range testCases {
- t.Run(tc.desc, func(t *testing.T) {
- s := setupWithTmpPath(t, "file", tc.includeFormat, tc.format, nil,
- func(w http.ResponseWriter, r *http.Request) {
- token, err := jwt.ParseWithClaims(r.Header.Get(upload.RewrittenFieldsHeader), &upload.MultipartClaims{}, testhelper.ParseJWT)
- require.NoError(t, err)
-
- rewrittenFields := token.Claims.(*upload.MultipartClaims).RewrittenFields
- require.Equal(t, 2, len(rewrittenFields))
-
- require.Contains(t, rewrittenFields, "file")
- require.Contains(t, rewrittenFields, "metadata")
- require.Contains(t, r.PostForm, "file.gitlab-workhorse-upload")
- require.Contains(t, r.PostForm, "metadata.gitlab-workhorse-upload")
- },
- )
- defer s.cleanup()
-
- archive := zip.NewWriter(s.fileWriter)
- file, err := archive.Create("test.file")
- require.NotNil(t, file)
- require.NoError(t, err)
-
- require.NoError(t, archive.Close())
- require.NoError(t, s.writer.Close())
-
- response := testUploadArtifacts(t, s.writer.FormDataContentType(), s.url, s.buffer)
- require.Equal(t, http.StatusOK, response.Code)
- testhelper.RequireResponseHeader(t, response, MetadataHeaderKey, MetadataHeaderPresent)
- })
- }
-}
-
-func TestUploadHandlerTarArtifact(t *testing.T) {
- s := setupWithTmpPath(t, "file", true, "tar", nil,
- func(w http.ResponseWriter, r *http.Request) {
- token, err := jwt.ParseWithClaims(r.Header.Get(upload.RewrittenFieldsHeader), &upload.MultipartClaims{}, testhelper.ParseJWT)
- require.NoError(t, err)
-
- rewrittenFields := token.Claims.(*upload.MultipartClaims).RewrittenFields
- require.Equal(t, 1, len(rewrittenFields))
-
- require.Contains(t, rewrittenFields, "file")
- require.Contains(t, r.PostForm, "file.gitlab-workhorse-upload")
- },
- )
- defer s.cleanup()
-
- file, err := os.Open("../../testdata/tarfile.tar")
- require.NoError(t, err)
-
- _, err = io.Copy(s.fileWriter, file)
- require.NoError(t, err)
- require.NoError(t, file.Close())
- require.NoError(t, s.writer.Close())
-
- response := testUploadArtifacts(t, s.writer.FormDataContentType(), s.url, s.buffer)
- require.Equal(t, http.StatusOK, response.Code)
- testhelper.RequireResponseHeader(t, response, MetadataHeaderKey, MetadataHeaderMissing)
-}
-
-func TestUploadHandlerForUnsupportedArchive(t *testing.T) {
- s := setupWithTmpPath(t, "file", true, "other", nil, nil)
- defer s.cleanup()
- require.NoError(t, s.writer.Close())
-
- response := testUploadArtifacts(t, s.writer.FormDataContentType(), s.url, s.buffer)
- require.Equal(t, http.StatusOK, response.Code)
- testhelper.RequireResponseHeader(t, response, MetadataHeaderKey, MetadataHeaderMissing)
-}
-
-func TestUploadHandlerForMultipleFiles(t *testing.T) {
- s := setupWithTmpPath(t, "file", true, "", nil, nil)
- defer s.cleanup()
-
- file, err := s.writer.CreateFormFile("file", "my.file")
- require.NotNil(t, file)
- require.NoError(t, err)
- require.NoError(t, s.writer.Close())
-
- response := testUploadArtifacts(t, s.writer.FormDataContentType(), s.url, s.buffer)
- require.Equal(t, http.StatusInternalServerError, response.Code)
-}
-
-func TestUploadFormProcessing(t *testing.T) {
- s := setupWithTmpPath(t, "metadata", true, "", nil, nil)
- defer s.cleanup()
- require.NoError(t, s.writer.Close())
-
- response := testUploadArtifacts(t, s.writer.FormDataContentType(), s.url, s.buffer)
- require.Equal(t, http.StatusInternalServerError, response.Code)
-}
-
-func TestLsifFileProcessing(t *testing.T) {
- tempPath, err := ioutil.TempDir("", "uploads")
- require.NoError(t, err)
-
- s := setupWithTmpPath(t, "file", true, "zip", &api.Response{TempPath: tempPath, ProcessLsif: true}, nil)
- defer s.cleanup()
-
- file, err := os.Open("../../testdata/lsif/valid.lsif.zip")
- require.NoError(t, err)
-
- _, err = io.Copy(s.fileWriter, file)
- require.NoError(t, err)
- require.NoError(t, file.Close())
- require.NoError(t, s.writer.Close())
-
- response := testUploadArtifacts(t, s.writer.FormDataContentType(), s.url, s.buffer)
- require.Equal(t, http.StatusOK, response.Code)
- testhelper.RequireResponseHeader(t, response, MetadataHeaderKey, MetadataHeaderPresent)
-}
-
-func TestInvalidLsifFileProcessing(t *testing.T) {
- tempPath, err := ioutil.TempDir("", "uploads")
- require.NoError(t, err)
-
- s := setupWithTmpPath(t, "file", true, "zip", &api.Response{TempPath: tempPath, ProcessLsif: true}, nil)
- defer s.cleanup()
-
- file, err := os.Open("../../testdata/lsif/invalid.lsif.zip")
- require.NoError(t, err)
-
- _, err = io.Copy(s.fileWriter, file)
- require.NoError(t, err)
- require.NoError(t, file.Close())
- require.NoError(t, s.writer.Close())
-
- response := testUploadArtifacts(t, s.writer.FormDataContentType(), s.url, s.buffer)
- require.Equal(t, http.StatusInternalServerError, response.Code)
-}
diff --git a/workhorse/internal/filestore/file_handler.go b/workhorse/internal/filestore/file_handler.go
deleted file mode 100644
index dac8d4d6247..00000000000
--- a/workhorse/internal/filestore/file_handler.go
+++ /dev/null
@@ -1,259 +0,0 @@
-package filestore
-
-import (
- "context"
- "errors"
- "fmt"
- "io"
- "io/ioutil"
- "os"
- "strconv"
- "time"
-
- "github.com/golang-jwt/jwt/v4"
-
- "gitlab.com/gitlab-org/labkit/log"
-
- "gitlab.com/gitlab-org/gitlab/workhorse/internal/objectstore"
- "gitlab.com/gitlab-org/gitlab/workhorse/internal/secret"
-)
-
-type SizeError error
-
-// ErrEntityTooLarge means that the uploaded content is bigger then maximum allowed size
-var ErrEntityTooLarge = errors.New("entity is too large")
-
-// FileHandler represent a file that has been processed for upload
-// it may be either uploaded to an ObjectStore and/or saved on local path.
-type FileHandler struct {
- // LocalPath is the path on the disk where file has been stored
- LocalPath string
-
- // RemoteID is the objectID provided by GitLab Rails
- RemoteID string
- // RemoteURL is ObjectStore URL provided by GitLab Rails
- RemoteURL string
-
- // Size is the persisted file size
- Size int64
-
- // Name is the resource name to send back to GitLab rails.
- // It differ from the real file name in order to avoid file collisions
- Name string
-
- // a map containing different hashes
- hashes map[string]string
-
- // Duration of upload in seconds
- uploadDuration float64
-}
-
-type uploadClaims struct {
- Upload map[string]string `json:"upload"`
- jwt.StandardClaims
-}
-
-// SHA256 hash of the handled file
-func (fh *FileHandler) SHA256() string {
- return fh.hashes["sha256"]
-}
-
-// MD5 hash of the handled file
-func (fh *FileHandler) MD5() string {
- return fh.hashes["md5"]
-}
-
-// GitLabFinalizeFields returns a map with all the fields GitLab Rails needs in order to finalize the upload.
-func (fh *FileHandler) GitLabFinalizeFields(prefix string) (map[string]string, error) {
- // TODO: remove `data` these once rails fully and exclusively support `signedData` (https://gitlab.com/gitlab-org/gitlab/-/issues/324873)
- data := make(map[string]string)
- signedData := make(map[string]string)
- key := func(field string) string {
- if prefix == "" {
- return field
- }
-
- return fmt.Sprintf("%s.%s", prefix, field)
- }
-
- for k, v := range map[string]string{
- "name": fh.Name,
- "path": fh.LocalPath,
- "remote_url": fh.RemoteURL,
- "remote_id": fh.RemoteID,
- "size": strconv.FormatInt(fh.Size, 10),
- "upload_duration": strconv.FormatFloat(fh.uploadDuration, 'f', -1, 64),
- } {
- data[key(k)] = v
- signedData[k] = v
- }
-
- for hashName, hash := range fh.hashes {
- data[key(hashName)] = hash
- signedData[hashName] = hash
- }
-
- claims := uploadClaims{Upload: signedData, StandardClaims: secret.DefaultClaims}
- jwtData, err := secret.JWTTokenString(claims)
- if err != nil {
- return nil, err
- }
- data[key("gitlab-workhorse-upload")] = jwtData
-
- return data, nil
-}
-
-type consumer interface {
- Consume(context.Context, io.Reader, time.Time) (int64, error)
-}
-
-// SaveFileFromReader persists the provided reader content to all the location specified in opts. A cleanup will be performed once ctx is Done
-// Make sure the provided context will not expire before finalizing upload with GitLab Rails.
-func SaveFileFromReader(ctx context.Context, reader io.Reader, size int64, opts *SaveFileOpts) (*FileHandler, error) {
- fh := &FileHandler{
- Name: opts.TempFilePrefix,
- RemoteID: opts.RemoteID,
- RemoteURL: opts.RemoteURL,
- }
- uploadStartTime := time.Now()
- defer func() { fh.uploadDuration = time.Since(uploadStartTime).Seconds() }()
- hashes := newMultiHash()
- reader = io.TeeReader(reader, hashes.Writer)
-
- var clientMode string
- var uploadDestination consumer
- var err error
- switch {
- case opts.IsLocal():
- clientMode = "local"
- uploadDestination, err = fh.uploadLocalFile(ctx, opts)
- case opts.UseWorkhorseClientEnabled() && opts.ObjectStorageConfig.IsGoCloud():
- clientMode = fmt.Sprintf("go_cloud:%s", opts.ObjectStorageConfig.Provider)
- p := &objectstore.GoCloudObjectParams{
- Ctx: ctx,
- Mux: opts.ObjectStorageConfig.URLMux,
- BucketURL: opts.ObjectStorageConfig.GoCloudConfig.URL,
- ObjectName: opts.RemoteTempObjectID,
- }
- uploadDestination, err = objectstore.NewGoCloudObject(p)
- case opts.UseWorkhorseClientEnabled() && opts.ObjectStorageConfig.IsAWS() && opts.ObjectStorageConfig.IsValid():
- clientMode = "s3"
- uploadDestination, err = objectstore.NewS3Object(
- opts.RemoteTempObjectID,
- opts.ObjectStorageConfig.S3Credentials,
- opts.ObjectStorageConfig.S3Config,
- )
- case opts.IsMultipart():
- clientMode = "multipart"
- uploadDestination, err = objectstore.NewMultipart(
- opts.PresignedParts,
- opts.PresignedCompleteMultipart,
- opts.PresignedAbortMultipart,
- opts.PresignedDelete,
- opts.PutHeaders,
- opts.PartSize,
- )
- default:
- clientMode = "http"
- uploadDestination, err = objectstore.NewObject(
- opts.PresignedPut,
- opts.PresignedDelete,
- opts.PutHeaders,
- size,
- )
- }
-
- if err != nil {
- return nil, err
- }
-
- var hlr *hardLimitReader
- if opts.MaximumSize > 0 {
- if size > opts.MaximumSize {
- return nil, SizeError(fmt.Errorf("the upload size %d is over maximum of %d bytes", size, opts.MaximumSize))
- }
-
- hlr = &hardLimitReader{r: reader, n: opts.MaximumSize}
- reader = hlr
- }
-
- fh.Size, err = uploadDestination.Consume(ctx, reader, opts.Deadline)
- if err != nil {
- if (err == objectstore.ErrNotEnoughParts) || (hlr != nil && hlr.n < 0) {
- err = ErrEntityTooLarge
- }
- return nil, err
- }
-
- if size != -1 && size != fh.Size {
- return nil, SizeError(fmt.Errorf("expected %d bytes but got only %d", size, fh.Size))
- }
-
- logger := log.WithContextFields(ctx, log.Fields{
- "copied_bytes": fh.Size,
- "is_local": opts.IsLocal(),
- "is_multipart": opts.IsMultipart(),
- "is_remote": !opts.IsLocal(),
- "remote_id": opts.RemoteID,
- "temp_file_prefix": opts.TempFilePrefix,
- "client_mode": clientMode,
- })
-
- if opts.IsLocal() {
- logger = logger.WithField("local_temp_path", opts.LocalTempPath)
- } else {
- logger = logger.WithField("remote_temp_object", opts.RemoteTempObjectID)
- }
-
- logger.Info("saved file")
- fh.hashes = hashes.finish()
- return fh, nil
-}
-
-func (fh *FileHandler) uploadLocalFile(ctx context.Context, opts *SaveFileOpts) (consumer, error) {
- // make sure TempFolder exists
- err := os.MkdirAll(opts.LocalTempPath, 0700)
- if err != nil {
- return nil, fmt.Errorf("uploadLocalFile: mkdir %q: %v", opts.LocalTempPath, err)
- }
-
- file, err := ioutil.TempFile(opts.LocalTempPath, opts.TempFilePrefix)
- if err != nil {
- return nil, fmt.Errorf("uploadLocalFile: create file: %v", err)
- }
-
- go func() {
- <-ctx.Done()
- os.Remove(file.Name())
- }()
-
- fh.LocalPath = file.Name()
- return &localUpload{file}, nil
-}
-
-type localUpload struct{ io.WriteCloser }
-
-func (loc *localUpload) Consume(_ context.Context, r io.Reader, _ time.Time) (int64, error) {
- n, err := io.Copy(loc.WriteCloser, r)
- errClose := loc.Close()
- if err == nil {
- err = errClose
- }
- return n, err
-}
-
-// SaveFileFromDisk open the local file fileName and calls SaveFileFromReader
-func SaveFileFromDisk(ctx context.Context, fileName string, opts *SaveFileOpts) (fh *FileHandler, err error) {
- file, err := os.Open(fileName)
- if err != nil {
- return nil, err
- }
- defer file.Close()
-
- fi, err := file.Stat()
- if err != nil {
- return nil, err
- }
-
- return SaveFileFromReader(ctx, file, fi.Size(), opts)
-}
diff --git a/workhorse/internal/filestore/file_handler_test.go b/workhorse/internal/filestore/file_handler_test.go
deleted file mode 100644
index 2fd034bb761..00000000000
--- a/workhorse/internal/filestore/file_handler_test.go
+++ /dev/null
@@ -1,538 +0,0 @@
-package filestore_test
-
-import (
- "context"
- "errors"
- "fmt"
- "io/ioutil"
- "os"
- "path"
- "strconv"
- "strings"
- "testing"
- "time"
-
- "github.com/golang-jwt/jwt/v4"
- "github.com/stretchr/testify/require"
- "gocloud.dev/blob"
-
- "gitlab.com/gitlab-org/gitlab/workhorse/internal/config"
- "gitlab.com/gitlab-org/gitlab/workhorse/internal/filestore"
- "gitlab.com/gitlab-org/gitlab/workhorse/internal/objectstore/test"
- "gitlab.com/gitlab-org/gitlab/workhorse/internal/testhelper"
-)
-
-func testDeadline() time.Time {
- return time.Now().Add(filestore.DefaultObjectStoreTimeout)
-}
-
-func requireFileGetsRemovedAsync(t *testing.T, filePath string) {
- var err error
- require.Eventually(t, func() bool {
- _, err = os.Stat(filePath)
- return err != nil
- }, 10*time.Second, 10*time.Millisecond)
- require.True(t, os.IsNotExist(err), "File hasn't been deleted during cleanup")
-}
-
-func requireObjectStoreDeletedAsync(t *testing.T, expectedDeletes int, osStub *test.ObjectstoreStub) {
- require.Eventually(t, func() bool { return osStub.DeletesCnt() == expectedDeletes }, time.Second, time.Millisecond, "Object not deleted")
-}
-
-func TestSaveFileWrongSize(t *testing.T) {
- ctx, cancel := context.WithCancel(context.Background())
- defer cancel()
-
- tmpFolder, err := ioutil.TempDir("", "workhorse-test-tmp")
- require.NoError(t, err)
- defer os.RemoveAll(tmpFolder)
-
- opts := &filestore.SaveFileOpts{LocalTempPath: tmpFolder, TempFilePrefix: "test-file"}
- fh, err := filestore.SaveFileFromReader(ctx, strings.NewReader(test.ObjectContent), test.ObjectSize+1, opts)
- require.Error(t, err)
- _, isSizeError := err.(filestore.SizeError)
- require.True(t, isSizeError, "Should fail with SizeError")
- require.Nil(t, fh)
-}
-
-func TestSaveFileWithKnownSizeExceedLimit(t *testing.T) {
- ctx, cancel := context.WithCancel(context.Background())
- defer cancel()
-
- tmpFolder, err := ioutil.TempDir("", "workhorse-test-tmp")
- require.NoError(t, err)
- defer os.RemoveAll(tmpFolder)
-
- opts := &filestore.SaveFileOpts{LocalTempPath: tmpFolder, TempFilePrefix: "test-file", MaximumSize: test.ObjectSize - 1}
- fh, err := filestore.SaveFileFromReader(ctx, strings.NewReader(test.ObjectContent), test.ObjectSize, opts)
- require.Error(t, err)
- _, isSizeError := err.(filestore.SizeError)
- require.True(t, isSizeError, "Should fail with SizeError")
- require.Nil(t, fh)
-}
-
-func TestSaveFileWithUnknownSizeExceedLimit(t *testing.T) {
- ctx, cancel := context.WithCancel(context.Background())
- defer cancel()
-
- tmpFolder, err := ioutil.TempDir("", "workhorse-test-tmp")
- require.NoError(t, err)
- defer os.RemoveAll(tmpFolder)
-
- opts := &filestore.SaveFileOpts{LocalTempPath: tmpFolder, TempFilePrefix: "test-file", MaximumSize: test.ObjectSize - 1}
- fh, err := filestore.SaveFileFromReader(ctx, strings.NewReader(test.ObjectContent), -1, opts)
- require.Equal(t, err, filestore.ErrEntityTooLarge)
- require.Nil(t, fh)
-}
-
-func TestSaveFromDiskNotExistingFile(t *testing.T) {
- ctx, cancel := context.WithCancel(context.Background())
- defer cancel()
- fh, err := filestore.SaveFileFromDisk(ctx, "/I/do/not/exist", &filestore.SaveFileOpts{})
- require.Error(t, err, "SaveFileFromDisk should fail")
- require.True(t, os.IsNotExist(err), "Provided file should not exists")
- require.Nil(t, fh, "On error FileHandler should be nil")
-}
-
-func TestSaveFileWrongETag(t *testing.T) {
- tests := []struct {
- name string
- multipart bool
- }{
- {name: "single part"},
- {name: "multi part", multipart: true},
- }
-
- for _, spec := range tests {
- t.Run(spec.name, func(t *testing.T) {
- osStub, ts := test.StartObjectStoreWithCustomMD5(map[string]string{test.ObjectPath: "brokenMD5"})
- defer ts.Close()
-
- objectURL := ts.URL + test.ObjectPath
-
- opts := &filestore.SaveFileOpts{
- RemoteID: "test-file",
- RemoteURL: objectURL,
- PresignedPut: objectURL + "?Signature=ASignature",
- PresignedDelete: objectURL + "?Signature=AnotherSignature",
- Deadline: testDeadline(),
- }
- if spec.multipart {
- opts.PresignedParts = []string{objectURL + "?partNumber=1"}
- opts.PresignedCompleteMultipart = objectURL + "?Signature=CompleteSig"
- opts.PresignedAbortMultipart = objectURL + "?Signature=AbortSig"
- opts.PartSize = test.ObjectSize
-
- osStub.InitiateMultipartUpload(test.ObjectPath)
- }
- ctx, cancel := context.WithCancel(context.Background())
- fh, err := filestore.SaveFileFromReader(ctx, strings.NewReader(test.ObjectContent), test.ObjectSize, opts)
- require.Nil(t, fh)
- require.Error(t, err)
- require.Equal(t, 1, osStub.PutsCnt(), "File not uploaded")
-
- cancel() // this will trigger an async cleanup
- requireObjectStoreDeletedAsync(t, 1, osStub)
- require.False(t, spec.multipart && osStub.IsMultipartUpload(test.ObjectPath), "there must be no multipart upload in progress now")
- })
- }
-}
-
-func TestSaveFileFromDiskToLocalPath(t *testing.T) {
- f, err := ioutil.TempFile("", "workhorse-test")
- require.NoError(t, err)
- defer os.Remove(f.Name())
-
- _, err = fmt.Fprint(f, test.ObjectContent)
- require.NoError(t, err)
-
- tmpFolder, err := ioutil.TempDir("", "workhorse-test-tmp")
- require.NoError(t, err)
- defer os.RemoveAll(tmpFolder)
-
- ctx, cancel := context.WithCancel(context.Background())
- defer cancel()
-
- opts := &filestore.SaveFileOpts{LocalTempPath: tmpFolder}
- fh, err := filestore.SaveFileFromDisk(ctx, f.Name(), opts)
- require.NoError(t, err)
- require.NotNil(t, fh)
-
- require.NotEmpty(t, fh.LocalPath, "File not persisted on disk")
- _, err = os.Stat(fh.LocalPath)
- require.NoError(t, err)
-}
-
-func TestSaveFile(t *testing.T) {
- testhelper.ConfigureSecret()
-
- type remote int
- const (
- notRemote remote = iota
- remoteSingle
- remoteMultipart
- )
-
- tmpFolder, err := ioutil.TempDir("", "workhorse-test-tmp")
- require.NoError(t, err)
- defer os.RemoveAll(tmpFolder)
-
- tests := []struct {
- name string
- local bool
- remote remote
- }{
- {name: "Local only", local: true},
- {name: "Remote Single only", remote: remoteSingle},
- {name: "Remote Multipart only", remote: remoteMultipart},
- }
-
- for _, spec := range tests {
- t.Run(spec.name, func(t *testing.T) {
- var opts filestore.SaveFileOpts
- var expectedDeletes, expectedPuts int
-
- osStub, ts := test.StartObjectStore()
- defer ts.Close()
-
- switch spec.remote {
- case remoteSingle:
- objectURL := ts.URL + test.ObjectPath
-
- opts.RemoteID = "test-file"
- opts.RemoteURL = objectURL
- opts.PresignedPut = objectURL + "?Signature=ASignature"
- opts.PresignedDelete = objectURL + "?Signature=AnotherSignature"
- opts.Deadline = testDeadline()
-
- expectedDeletes = 1
- expectedPuts = 1
- case remoteMultipart:
- objectURL := ts.URL + test.ObjectPath
-
- opts.RemoteID = "test-file"
- opts.RemoteURL = objectURL
- opts.PresignedDelete = objectURL + "?Signature=AnotherSignature"
- opts.PartSize = int64(len(test.ObjectContent)/2) + 1
- opts.PresignedParts = []string{objectURL + "?partNumber=1", objectURL + "?partNumber=2"}
- opts.PresignedCompleteMultipart = objectURL + "?Signature=CompleteSignature"
- opts.Deadline = testDeadline()
-
- osStub.InitiateMultipartUpload(test.ObjectPath)
- expectedDeletes = 1
- expectedPuts = 2
- }
-
- if spec.local {
- opts.LocalTempPath = tmpFolder
- opts.TempFilePrefix = "test-file"
- }
-
- ctx, cancel := context.WithCancel(context.Background())
- defer cancel()
-
- fh, err := filestore.SaveFileFromReader(ctx, strings.NewReader(test.ObjectContent), test.ObjectSize, &opts)
- require.NoError(t, err)
- require.NotNil(t, fh)
-
- require.Equal(t, opts.RemoteID, fh.RemoteID)
- require.Equal(t, opts.RemoteURL, fh.RemoteURL)
-
- if spec.local {
- require.NotEmpty(t, fh.LocalPath, "File not persisted on disk")
- _, err := os.Stat(fh.LocalPath)
- require.NoError(t, err)
-
- dir := path.Dir(fh.LocalPath)
- require.Equal(t, opts.LocalTempPath, dir)
- filename := path.Base(fh.LocalPath)
- beginsWithPrefix := strings.HasPrefix(filename, opts.TempFilePrefix)
- require.True(t, beginsWithPrefix, fmt.Sprintf("LocalPath filename %q do not begin with TempFilePrefix %q", filename, opts.TempFilePrefix))
- } else {
- require.Empty(t, fh.LocalPath, "LocalPath must be empty for non local uploads")
- }
-
- require.Equal(t, test.ObjectSize, fh.Size)
- require.Equal(t, test.ObjectMD5, fh.MD5())
- require.Equal(t, test.ObjectSHA256, fh.SHA256())
-
- require.Equal(t, expectedPuts, osStub.PutsCnt(), "ObjectStore PutObject count mismatch")
- require.Equal(t, 0, osStub.DeletesCnt(), "File deleted too early")
-
- cancel() // this will trigger an async cleanup
- requireObjectStoreDeletedAsync(t, expectedDeletes, osStub)
- requireFileGetsRemovedAsync(t, fh.LocalPath)
-
- // checking generated fields
- fields, err := fh.GitLabFinalizeFields("file")
- require.NoError(t, err)
-
- checkFileHandlerWithFields(t, fh, fields, "file")
-
- token, jwtErr := jwt.ParseWithClaims(fields["file.gitlab-workhorse-upload"], &testhelper.UploadClaims{}, testhelper.ParseJWT)
- require.NoError(t, jwtErr)
-
- uploadFields := token.Claims.(*testhelper.UploadClaims).Upload
-
- checkFileHandlerWithFields(t, fh, uploadFields, "")
- })
- }
-}
-
-func TestSaveFileWithS3WorkhorseClient(t *testing.T) {
- tests := []struct {
- name string
- objectSize int64
- maxSize int64
- expectedErr error
- }{
- {
- name: "known size with no limit",
- objectSize: test.ObjectSize,
- },
- {
- name: "unknown size with no limit",
- objectSize: -1,
- },
- {
- name: "unknown object size with limit",
- objectSize: -1,
- maxSize: test.ObjectSize - 1,
- expectedErr: filestore.ErrEntityTooLarge,
- },
- }
-
- for _, tc := range tests {
- t.Run(tc.name, func(t *testing.T) {
-
- s3Creds, s3Config, sess, ts := test.SetupS3(t, "")
- defer ts.Close()
-
- ctx, cancel := context.WithCancel(context.Background())
- defer cancel()
-
- remoteObject := "tmp/test-file/1"
- opts := filestore.SaveFileOpts{
- RemoteID: "test-file",
- Deadline: testDeadline(),
- UseWorkhorseClient: true,
- RemoteTempObjectID: remoteObject,
- ObjectStorageConfig: filestore.ObjectStorageConfig{
- Provider: "AWS",
- S3Credentials: s3Creds,
- S3Config: s3Config,
- },
- MaximumSize: tc.maxSize,
- }
-
- _, err := filestore.SaveFileFromReader(ctx, strings.NewReader(test.ObjectContent), tc.objectSize, &opts)
-
- if tc.expectedErr == nil {
- require.NoError(t, err)
- test.S3ObjectExists(t, sess, s3Config, remoteObject, test.ObjectContent)
- } else {
- require.Equal(t, tc.expectedErr, err)
- test.S3ObjectDoesNotExist(t, sess, s3Config, remoteObject)
- }
- })
- }
-}
-
-func TestSaveFileWithAzureWorkhorseClient(t *testing.T) {
- mux, bucketDir, cleanup := test.SetupGoCloudFileBucket(t, "azblob")
- defer cleanup()
-
- ctx, cancel := context.WithCancel(context.Background())
- defer cancel()
-
- remoteObject := "tmp/test-file/1"
- opts := filestore.SaveFileOpts{
- RemoteID: "test-file",
- Deadline: testDeadline(),
- UseWorkhorseClient: true,
- RemoteTempObjectID: remoteObject,
- ObjectStorageConfig: filestore.ObjectStorageConfig{
- Provider: "AzureRM",
- URLMux: mux,
- GoCloudConfig: config.GoCloudConfig{URL: "azblob://test-container"},
- },
- }
-
- _, err := filestore.SaveFileFromReader(ctx, strings.NewReader(test.ObjectContent), test.ObjectSize, &opts)
- require.NoError(t, err)
-
- test.GoCloudObjectExists(t, bucketDir, remoteObject)
-}
-
-func TestSaveFileWithUnknownGoCloudScheme(t *testing.T) {
- ctx, cancel := context.WithCancel(context.Background())
- defer cancel()
-
- mux := new(blob.URLMux)
-
- remoteObject := "tmp/test-file/1"
- opts := filestore.SaveFileOpts{
- RemoteID: "test-file",
- Deadline: testDeadline(),
- UseWorkhorseClient: true,
- RemoteTempObjectID: remoteObject,
- ObjectStorageConfig: filestore.ObjectStorageConfig{
- Provider: "SomeCloud",
- URLMux: mux,
- GoCloudConfig: config.GoCloudConfig{URL: "foo://test-container"},
- },
- }
-
- _, err := filestore.SaveFileFromReader(ctx, strings.NewReader(test.ObjectContent), test.ObjectSize, &opts)
- require.Error(t, err)
-}
-
-func TestSaveMultipartInBodyFailure(t *testing.T) {
- osStub, ts := test.StartObjectStore()
- defer ts.Close()
-
- // this is a broken path because it contains bucket name but no key
- // this is the only way to get an in-body failure from our ObjectStoreStub
- objectPath := "/bucket-but-no-object-key"
- objectURL := ts.URL + objectPath
- opts := filestore.SaveFileOpts{
- RemoteID: "test-file",
- RemoteURL: objectURL,
- PartSize: test.ObjectSize,
- PresignedParts: []string{objectURL + "?partNumber=1", objectURL + "?partNumber=2"},
- PresignedCompleteMultipart: objectURL + "?Signature=CompleteSignature",
- Deadline: testDeadline(),
- }
-
- osStub.InitiateMultipartUpload(objectPath)
-
- ctx, cancel := context.WithCancel(context.Background())
- defer cancel()
-
- fh, err := filestore.SaveFileFromReader(ctx, strings.NewReader(test.ObjectContent), test.ObjectSize, &opts)
- require.Nil(t, fh)
- require.Error(t, err)
- require.EqualError(t, err, test.MultipartUploadInternalError().Error())
-}
-
-func TestSaveRemoteFileWithLimit(t *testing.T) {
- testhelper.ConfigureSecret()
-
- type remote int
- const (
- notRemote remote = iota
- remoteSingle
- remoteMultipart
- )
-
- remoteTypes := []remote{remoteSingle, remoteMultipart}
-
- tests := []struct {
- name string
- objectSize int64
- maxSize int64
- expectedErr error
- testData string
- }{
- {
- name: "known size with no limit",
- testData: test.ObjectContent,
- objectSize: test.ObjectSize,
- },
- {
- name: "unknown size with no limit",
- testData: test.ObjectContent,
- objectSize: -1,
- },
- {
- name: "unknown object size with limit",
- testData: test.ObjectContent,
- objectSize: -1,
- maxSize: test.ObjectSize - 1,
- expectedErr: filestore.ErrEntityTooLarge,
- },
- {
- name: "large object with unknown size with limit",
- testData: string(make([]byte, 20000)),
- objectSize: -1,
- maxSize: 19000,
- expectedErr: filestore.ErrEntityTooLarge,
- },
- }
-
- for _, tc := range tests {
- t.Run(tc.name, func(t *testing.T) {
- var opts filestore.SaveFileOpts
-
- for _, remoteType := range remoteTypes {
- tmpFolder, err := ioutil.TempDir("", "workhorse-test-tmp")
- require.NoError(t, err)
- defer os.RemoveAll(tmpFolder)
-
- osStub, ts := test.StartObjectStore()
- defer ts.Close()
-
- switch remoteType {
- case remoteSingle:
- objectURL := ts.URL + test.ObjectPath
-
- opts.RemoteID = "test-file"
- opts.RemoteURL = objectURL
- opts.PresignedPut = objectURL + "?Signature=ASignature"
- opts.PresignedDelete = objectURL + "?Signature=AnotherSignature"
- opts.Deadline = testDeadline()
- opts.MaximumSize = tc.maxSize
- case remoteMultipart:
- objectURL := ts.URL + test.ObjectPath
-
- opts.RemoteID = "test-file"
- opts.RemoteURL = objectURL
- opts.PresignedDelete = objectURL + "?Signature=AnotherSignature"
- opts.PartSize = int64(len(tc.testData)/2) + 1
- opts.PresignedParts = []string{objectURL + "?partNumber=1", objectURL + "?partNumber=2"}
- opts.PresignedCompleteMultipart = objectURL + "?Signature=CompleteSignature"
- opts.Deadline = testDeadline()
- opts.MaximumSize = tc.maxSize
-
- require.Less(t, int64(len(tc.testData)), int64(len(opts.PresignedParts))*opts.PartSize, "check part size calculation")
-
- osStub.InitiateMultipartUpload(test.ObjectPath)
- }
-
- ctx, cancel := context.WithCancel(context.Background())
- defer cancel()
-
- fh, err := filestore.SaveFileFromReader(ctx, strings.NewReader(tc.testData), tc.objectSize, &opts)
-
- if tc.expectedErr == nil {
- require.NoError(t, err)
- require.NotNil(t, fh)
- } else {
- require.True(t, errors.Is(err, tc.expectedErr))
- require.Nil(t, fh)
- }
- }
- })
- }
-}
-
-func checkFileHandlerWithFields(t *testing.T, fh *filestore.FileHandler, fields map[string]string, prefix string) {
- key := func(field string) string {
- if prefix == "" {
- return field
- }
-
- return fmt.Sprintf("%s.%s", prefix, field)
- }
-
- require.Equal(t, fh.Name, fields[key("name")])
- require.Equal(t, fh.LocalPath, fields[key("path")])
- require.Equal(t, fh.RemoteURL, fields[key("remote_url")])
- require.Equal(t, fh.RemoteID, fields[key("remote_id")])
- require.Equal(t, strconv.FormatInt(test.ObjectSize, 10), fields[key("size")])
- require.Equal(t, test.ObjectMD5, fields[key("md5")])
- require.Equal(t, test.ObjectSHA1, fields[key("sha1")])
- require.Equal(t, test.ObjectSHA256, fields[key("sha256")])
- require.Equal(t, test.ObjectSHA512, fields[key("sha512")])
- require.NotEmpty(t, fields[key("upload_duration")])
-}
diff --git a/workhorse/internal/filestore/multi_hash.go b/workhorse/internal/filestore/multi_hash.go
deleted file mode 100644
index 40efd3a5c1f..00000000000
--- a/workhorse/internal/filestore/multi_hash.go
+++ /dev/null
@@ -1,48 +0,0 @@
-package filestore
-
-import (
- "crypto/md5"
- "crypto/sha1"
- "crypto/sha256"
- "crypto/sha512"
- "encoding/hex"
- "hash"
- "io"
-)
-
-var hashFactories = map[string](func() hash.Hash){
- "md5": md5.New,
- "sha1": sha1.New,
- "sha256": sha256.New,
- "sha512": sha512.New,
-}
-
-type multiHash struct {
- io.Writer
- hashes map[string]hash.Hash
-}
-
-func newMultiHash() (m *multiHash) {
- m = &multiHash{}
- m.hashes = make(map[string]hash.Hash)
-
- var writers []io.Writer
- for hash, hashFactory := range hashFactories {
- writer := hashFactory()
-
- m.hashes[hash] = writer
- writers = append(writers, writer)
- }
-
- m.Writer = io.MultiWriter(writers...)
- return m
-}
-
-func (m *multiHash) finish() map[string]string {
- h := make(map[string]string)
- for hashName, hash := range m.hashes {
- checksum := hash.Sum(nil)
- h[hashName] = hex.EncodeToString(checksum)
- }
- return h
-}
diff --git a/workhorse/internal/filestore/reader.go b/workhorse/internal/filestore/reader.go
deleted file mode 100644
index b1045b991fc..00000000000
--- a/workhorse/internal/filestore/reader.go
+++ /dev/null
@@ -1,17 +0,0 @@
-package filestore
-
-import "io"
-
-type hardLimitReader struct {
- r io.Reader
- n int64
-}
-
-func (h *hardLimitReader) Read(p []byte) (int, error) {
- nRead, err := h.r.Read(p)
- h.n -= int64(nRead)
- if h.n < 0 {
- err = ErrEntityTooLarge
- }
- return nRead, err
-}
diff --git a/workhorse/internal/filestore/reader_test.go b/workhorse/internal/filestore/reader_test.go
deleted file mode 100644
index 424d921ecaf..00000000000
--- a/workhorse/internal/filestore/reader_test.go
+++ /dev/null
@@ -1,46 +0,0 @@
-package filestore
-
-import (
- "fmt"
- "io/ioutil"
- "strings"
- "testing"
- "testing/iotest"
-
- "github.com/stretchr/testify/require"
-)
-
-func TestHardLimitReader(t *testing.T) {
- const text = "hello world"
- r := iotest.OneByteReader(
- &hardLimitReader{
- r: strings.NewReader(text),
- n: int64(len(text)),
- },
- )
-
- out, err := ioutil.ReadAll(r)
- require.NoError(t, err)
- require.Equal(t, text, string(out))
-}
-
-func TestHardLimitReaderFail(t *testing.T) {
- const text = "hello world"
-
- for bufSize := len(text) / 2; bufSize < len(text)*2; bufSize++ {
- t.Run(fmt.Sprintf("bufsize:%d", bufSize), func(t *testing.T) {
- r := &hardLimitReader{
- r: iotest.DataErrReader(strings.NewReader(text)),
- n: int64(len(text)) - 1,
- }
- buf := make([]byte, bufSize)
-
- var err error
- for i := 0; err == nil && i < 1000; i++ {
- _, err = r.Read(buf)
- }
-
- require.Equal(t, ErrEntityTooLarge, err)
- })
- }
-}
diff --git a/workhorse/internal/filestore/save_file_opts.go b/workhorse/internal/filestore/save_file_opts.go
deleted file mode 100644
index 544101d693a..00000000000
--- a/workhorse/internal/filestore/save_file_opts.go
+++ /dev/null
@@ -1,171 +0,0 @@
-package filestore
-
-import (
- "errors"
- "strings"
- "time"
-
- "gocloud.dev/blob"
-
- "gitlab.com/gitlab-org/gitlab/workhorse/internal/api"
- "gitlab.com/gitlab-org/gitlab/workhorse/internal/config"
-)
-
-// DefaultObjectStoreTimeout is the timeout for ObjectStore upload operation
-const DefaultObjectStoreTimeout = 4 * time.Hour
-
-type ObjectStorageConfig struct {
- Provider string
-
- S3Credentials config.S3Credentials
- S3Config config.S3Config
-
- // GoCloud mux that maps azureblob:// and future URLs (e.g. s3://, gcs://, etc.) to a handler
- URLMux *blob.URLMux
-
- // Azure credentials are registered at startup in the GoCloud URLMux, so only the container name is needed
- GoCloudConfig config.GoCloudConfig
-}
-
-// SaveFileOpts represents all the options available for saving a file to object store
-type SaveFileOpts struct {
- // TempFilePrefix is the prefix used to create temporary local file
- TempFilePrefix string
- // LocalTempPath is the directory where to write a local copy of the file
- LocalTempPath string
- // RemoteID is the remote ObjectID provided by GitLab
- RemoteID string
- // RemoteURL is the final URL of the file
- RemoteURL string
- // PresignedPut is a presigned S3 PutObject compatible URL
- PresignedPut string
- // PresignedDelete is a presigned S3 DeleteObject compatible URL.
- PresignedDelete string
- // HTTP headers to be sent along with PUT request
- PutHeaders map[string]string
- // Whether to ignore Rails pre-signed URLs and have Workhorse directly access object storage provider
- UseWorkhorseClient bool
- // If UseWorkhorseClient is true, this is the temporary object name to store the file
- RemoteTempObjectID string
- // Workhorse object storage client (e.g. S3) parameters
- ObjectStorageConfig ObjectStorageConfig
- // Deadline it the S3 operation deadline, the upload will be aborted if not completed in time
- Deadline time.Time
- // The maximum accepted size in bytes of the upload
- MaximumSize int64
-
- //MultipartUpload parameters
- // PartSize is the exact size of each uploaded part. Only the last one can be smaller
- PartSize int64
- // PresignedParts contains the presigned URLs for each part
- PresignedParts []string
- // PresignedCompleteMultipart is a presigned URL for CompleteMulipartUpload
- PresignedCompleteMultipart string
- // PresignedAbortMultipart is a presigned URL for AbortMultipartUpload
- PresignedAbortMultipart string
-}
-
-// UseWorkhorseClientEnabled checks if the options require direct access to object storage
-func (s *SaveFileOpts) UseWorkhorseClientEnabled() bool {
- return s.UseWorkhorseClient && s.ObjectStorageConfig.IsValid() && s.RemoteTempObjectID != ""
-}
-
-// IsLocal checks if the options require the writing of the file on disk
-func (s *SaveFileOpts) IsLocal() bool {
- return s.LocalTempPath != ""
-}
-
-// IsMultipart checks if the options requires a Multipart upload
-func (s *SaveFileOpts) IsMultipart() bool {
- return s.PartSize > 0
-}
-
-// GetOpts converts GitLab api.Response to a proper SaveFileOpts
-func GetOpts(apiResponse *api.Response) (*SaveFileOpts, error) {
- timeout := time.Duration(apiResponse.RemoteObject.Timeout) * time.Second
- if timeout == 0 {
- timeout = DefaultObjectStoreTimeout
- }
-
- opts := SaveFileOpts{
- LocalTempPath: apiResponse.TempPath,
- RemoteID: apiResponse.RemoteObject.ID,
- RemoteURL: apiResponse.RemoteObject.GetURL,
- PresignedPut: apiResponse.RemoteObject.StoreURL,
- PresignedDelete: apiResponse.RemoteObject.DeleteURL,
- PutHeaders: apiResponse.RemoteObject.PutHeaders,
- UseWorkhorseClient: apiResponse.RemoteObject.UseWorkhorseClient,
- RemoteTempObjectID: apiResponse.RemoteObject.RemoteTempObjectID,
- Deadline: time.Now().Add(timeout),
- MaximumSize: apiResponse.MaximumSize,
- }
-
- if opts.LocalTempPath != "" && opts.RemoteID != "" {
- return nil, errors.New("API response has both TempPath and RemoteObject")
- }
-
- if opts.LocalTempPath == "" && opts.RemoteID == "" {
- return nil, errors.New("API response has neither TempPath nor RemoteObject")
- }
-
- objectStorageParams := apiResponse.RemoteObject.ObjectStorage
- if opts.UseWorkhorseClient && objectStorageParams != nil {
- opts.ObjectStorageConfig.Provider = objectStorageParams.Provider
- opts.ObjectStorageConfig.S3Config = objectStorageParams.S3Config
- opts.ObjectStorageConfig.GoCloudConfig = objectStorageParams.GoCloudConfig
- }
-
- // Backwards compatibility to ensure API servers that do not include the
- // CustomPutHeaders flag will default to the original content type.
- if !apiResponse.RemoteObject.CustomPutHeaders {
- opts.PutHeaders = make(map[string]string)
- opts.PutHeaders["Content-Type"] = "application/octet-stream"
- }
-
- if multiParams := apiResponse.RemoteObject.MultipartUpload; multiParams != nil {
- opts.PartSize = multiParams.PartSize
- opts.PresignedCompleteMultipart = multiParams.CompleteURL
- opts.PresignedAbortMultipart = multiParams.AbortURL
- opts.PresignedParts = append([]string(nil), multiParams.PartURLs...)
- }
-
- return &opts, nil
-}
-
-func (c *ObjectStorageConfig) IsAWS() bool {
- return strings.EqualFold(c.Provider, "AWS") || strings.EqualFold(c.Provider, "S3")
-}
-
-func (c *ObjectStorageConfig) IsAzure() bool {
- return strings.EqualFold(c.Provider, "AzureRM")
-}
-
-func (c *ObjectStorageConfig) IsGoCloud() bool {
- return c.GoCloudConfig.URL != ""
-}
-
-func (c *ObjectStorageConfig) IsValid() bool {
- if c.IsAWS() {
- return c.S3Config.Bucket != "" && c.s3CredentialsValid()
- } else if c.IsGoCloud() {
- // We could parse and validate the URL, but GoCloud providers
- // such as AzureRM don't have a fallback to normal HTTP, so we
- // always want to try the GoCloud path if there is a URL.
- return true
- }
-
- return false
-}
-
-func (c *ObjectStorageConfig) s3CredentialsValid() bool {
- // We need to be able to distinguish between two cases of AWS access:
- // 1. AWS access via key and secret, but credentials not configured in Workhorse
- // 2. IAM instance profiles used
- if c.S3Config.UseIamProfile {
- return true
- } else if c.S3Credentials.AwsAccessKeyID != "" && c.S3Credentials.AwsSecretAccessKey != "" {
- return true
- }
-
- return false
-}
diff --git a/workhorse/internal/filestore/save_file_opts_test.go b/workhorse/internal/filestore/save_file_opts_test.go
deleted file mode 100644
index f389b2054e5..00000000000
--- a/workhorse/internal/filestore/save_file_opts_test.go
+++ /dev/null
@@ -1,342 +0,0 @@
-package filestore_test
-
-import (
- "testing"
- "time"
-
- "github.com/stretchr/testify/require"
-
- "gitlab.com/gitlab-org/gitlab/workhorse/internal/api"
- "gitlab.com/gitlab-org/gitlab/workhorse/internal/config"
- "gitlab.com/gitlab-org/gitlab/workhorse/internal/filestore"
- "gitlab.com/gitlab-org/gitlab/workhorse/internal/objectstore/test"
-)
-
-func TestSaveFileOptsLocalAndRemote(t *testing.T) {
- tests := []struct {
- name string
- localTempPath string
- presignedPut string
- partSize int64
- isLocal bool
- isRemote bool
- isMultipart bool
- }{
- {
- name: "Only LocalTempPath",
- localTempPath: "/tmp",
- isLocal: true,
- },
- {
- name: "No paths",
- },
- {
- name: "Only remoteUrl",
- presignedPut: "http://example.com",
- },
- {
- name: "Multipart",
- partSize: 10,
- isMultipart: true,
- },
- }
-
- for _, test := range tests {
- t.Run(test.name, func(t *testing.T) {
- opts := filestore.SaveFileOpts{
- LocalTempPath: test.localTempPath,
- PresignedPut: test.presignedPut,
- PartSize: test.partSize,
- }
-
- require.Equal(t, test.isLocal, opts.IsLocal(), "IsLocal() mismatch")
- require.Equal(t, test.isMultipart, opts.IsMultipart(), "IsMultipart() mismatch")
- })
- }
-}
-
-func TestGetOpts(t *testing.T) {
- tests := []struct {
- name string
- multipart *api.MultipartUploadParams
- customPutHeaders bool
- putHeaders map[string]string
- }{
- {
- name: "Single upload",
- },
- {
- name: "Multipart upload",
- multipart: &api.MultipartUploadParams{
- PartSize: 10,
- CompleteURL: "http://complete",
- AbortURL: "http://abort",
- PartURLs: []string{"http://part1", "http://part2"},
- },
- },
- {
- name: "Single upload with custom content type",
- customPutHeaders: true,
- putHeaders: map[string]string{"Content-Type": "image/jpeg"},
- }, {
- name: "Multipart upload with custom content type",
- multipart: &api.MultipartUploadParams{
- PartSize: 10,
- CompleteURL: "http://complete",
- AbortURL: "http://abort",
- PartURLs: []string{"http://part1", "http://part2"},
- },
- customPutHeaders: true,
- putHeaders: map[string]string{"Content-Type": "image/jpeg"},
- },
- }
-
- for _, test := range tests {
- t.Run(test.name, func(t *testing.T) {
- apiResponse := &api.Response{
- RemoteObject: api.RemoteObject{
- Timeout: 10,
- ID: "id",
- GetURL: "http://get",
- StoreURL: "http://store",
- DeleteURL: "http://delete",
- MultipartUpload: test.multipart,
- CustomPutHeaders: test.customPutHeaders,
- PutHeaders: test.putHeaders,
- },
- }
- deadline := time.Now().Add(time.Duration(apiResponse.RemoteObject.Timeout) * time.Second)
- opts, err := filestore.GetOpts(apiResponse)
- require.NoError(t, err)
-
- require.Equal(t, apiResponse.TempPath, opts.LocalTempPath)
- require.WithinDuration(t, deadline, opts.Deadline, time.Second)
- require.Equal(t, apiResponse.RemoteObject.ID, opts.RemoteID)
- require.Equal(t, apiResponse.RemoteObject.GetURL, opts.RemoteURL)
- require.Equal(t, apiResponse.RemoteObject.StoreURL, opts.PresignedPut)
- require.Equal(t, apiResponse.RemoteObject.DeleteURL, opts.PresignedDelete)
- if test.customPutHeaders {
- require.Equal(t, opts.PutHeaders, apiResponse.RemoteObject.PutHeaders)
- } else {
- require.Equal(t, opts.PutHeaders, map[string]string{"Content-Type": "application/octet-stream"})
- }
-
- if test.multipart == nil {
- require.False(t, opts.IsMultipart())
- require.Empty(t, opts.PresignedCompleteMultipart)
- require.Empty(t, opts.PresignedAbortMultipart)
- require.Zero(t, opts.PartSize)
- require.Empty(t, opts.PresignedParts)
- } else {
- require.True(t, opts.IsMultipart())
- require.Equal(t, test.multipart.CompleteURL, opts.PresignedCompleteMultipart)
- require.Equal(t, test.multipart.AbortURL, opts.PresignedAbortMultipart)
- require.Equal(t, test.multipart.PartSize, opts.PartSize)
- require.Equal(t, test.multipart.PartURLs, opts.PresignedParts)
- }
- })
- }
-}
-
-func TestGetOptsFail(t *testing.T) {
- testCases := []struct {
- desc string
- in *api.Response
- }{
- {
- desc: "neither local nor remote",
- in: &api.Response{},
- },
- {
- desc: "both local and remote",
- in: &api.Response{TempPath: "/foobar", RemoteObject: api.RemoteObject{ID: "id"}},
- },
- }
-
- for _, tc := range testCases {
- t.Run(tc.desc, func(t *testing.T) {
- _, err := filestore.GetOpts(tc.in)
- require.Error(t, err, "expect input to be rejected")
- })
- }
-}
-
-func TestGetOptsDefaultTimeout(t *testing.T) {
- deadline := time.Now().Add(filestore.DefaultObjectStoreTimeout)
- opts, err := filestore.GetOpts(&api.Response{TempPath: "/foo/bar"})
- require.NoError(t, err)
-
- require.WithinDuration(t, deadline, opts.Deadline, time.Minute)
-}
-
-func TestUseWorkhorseClientEnabled(t *testing.T) {
- cfg := filestore.ObjectStorageConfig{
- Provider: "AWS",
- S3Config: config.S3Config{
- Bucket: "test-bucket",
- Region: "test-region",
- },
- S3Credentials: config.S3Credentials{
- AwsAccessKeyID: "test-key",
- AwsSecretAccessKey: "test-secret",
- },
- }
-
- missingCfg := cfg
- missingCfg.S3Credentials = config.S3Credentials{}
-
- iamConfig := missingCfg
- iamConfig.S3Config.UseIamProfile = true
-
- missingRegion := cfg
- missingRegion.S3Config.Region = ""
-
- tests := []struct {
- name string
- UseWorkhorseClient bool
- remoteTempObjectID string
- objectStorageConfig filestore.ObjectStorageConfig
- expected bool
- }{
- {
- name: "all direct access settings used",
- UseWorkhorseClient: true,
- remoteTempObjectID: "test-object",
- objectStorageConfig: cfg,
- expected: true,
- },
- {
- name: "missing AWS credentials",
- UseWorkhorseClient: true,
- remoteTempObjectID: "test-object",
- objectStorageConfig: missingCfg,
- expected: false,
- },
- {
- name: "direct access disabled",
- UseWorkhorseClient: false,
- remoteTempObjectID: "test-object",
- objectStorageConfig: cfg,
- expected: false,
- },
- {
- name: "with IAM instance profile",
- UseWorkhorseClient: true,
- remoteTempObjectID: "test-object",
- objectStorageConfig: iamConfig,
- expected: true,
- },
- {
- name: "missing remote temp object ID",
- UseWorkhorseClient: true,
- remoteTempObjectID: "",
- objectStorageConfig: cfg,
- expected: false,
- },
- {
- name: "missing S3 config",
- UseWorkhorseClient: true,
- remoteTempObjectID: "test-object",
- expected: false,
- },
- {
- name: "missing S3 bucket",
- UseWorkhorseClient: true,
- remoteTempObjectID: "test-object",
- objectStorageConfig: filestore.ObjectStorageConfig{
- Provider: "AWS",
- S3Config: config.S3Config{},
- },
- expected: false,
- },
- {
- name: "missing S3 region",
- UseWorkhorseClient: true,
- remoteTempObjectID: "test-object",
- objectStorageConfig: missingRegion,
- expected: true,
- },
- }
-
- for _, test := range tests {
- t.Run(test.name, func(t *testing.T) {
- apiResponse := &api.Response{
- RemoteObject: api.RemoteObject{
- Timeout: 10,
- ID: "id",
- UseWorkhorseClient: test.UseWorkhorseClient,
- RemoteTempObjectID: test.remoteTempObjectID,
- },
- }
- deadline := time.Now().Add(time.Duration(apiResponse.RemoteObject.Timeout) * time.Second)
- opts, err := filestore.GetOpts(apiResponse)
- require.NoError(t, err)
- opts.ObjectStorageConfig = test.objectStorageConfig
-
- require.Equal(t, apiResponse.TempPath, opts.LocalTempPath)
- require.WithinDuration(t, deadline, opts.Deadline, time.Second)
- require.Equal(t, apiResponse.RemoteObject.ID, opts.RemoteID)
- require.Equal(t, apiResponse.RemoteObject.UseWorkhorseClient, opts.UseWorkhorseClient)
- require.Equal(t, test.expected, opts.UseWorkhorseClientEnabled())
- })
- }
-}
-
-func TestGoCloudConfig(t *testing.T) {
- mux, _, cleanup := test.SetupGoCloudFileBucket(t, "azblob")
- defer cleanup()
-
- tests := []struct {
- name string
- provider string
- url string
- valid bool
- }{
- {
- name: "valid AzureRM config",
- provider: "AzureRM",
- url: "azblob:://test-container",
- valid: true,
- },
- {
- name: "invalid GoCloud scheme",
- provider: "AzureRM",
- url: "unknown:://test-container",
- valid: true,
- },
- }
-
- for _, test := range tests {
- t.Run(test.name, func(t *testing.T) {
- apiResponse := &api.Response{
- RemoteObject: api.RemoteObject{
- Timeout: 10,
- ID: "id",
- UseWorkhorseClient: true,
- RemoteTempObjectID: "test-object",
- ObjectStorage: &api.ObjectStorageParams{
- Provider: test.provider,
- GoCloudConfig: config.GoCloudConfig{
- URL: test.url,
- },
- },
- },
- }
- deadline := time.Now().Add(time.Duration(apiResponse.RemoteObject.Timeout) * time.Second)
- opts, err := filestore.GetOpts(apiResponse)
- require.NoError(t, err)
- opts.ObjectStorageConfig.URLMux = mux
-
- require.Equal(t, apiResponse.TempPath, opts.LocalTempPath)
- require.Equal(t, apiResponse.RemoteObject.RemoteTempObjectID, opts.RemoteTempObjectID)
- require.WithinDuration(t, deadline, opts.Deadline, time.Second)
- require.Equal(t, apiResponse.RemoteObject.ID, opts.RemoteID)
- require.Equal(t, apiResponse.RemoteObject.UseWorkhorseClient, opts.UseWorkhorseClient)
- require.Equal(t, test.provider, opts.ObjectStorageConfig.Provider)
- require.Equal(t, apiResponse.RemoteObject.ObjectStorage.GoCloudConfig, opts.ObjectStorageConfig.GoCloudConfig)
- require.True(t, opts.UseWorkhorseClientEnabled())
- require.Equal(t, test.valid, opts.ObjectStorageConfig.IsValid())
- require.False(t, opts.IsLocal())
- })
- }
-}
diff --git a/workhorse/internal/lfs/lfs.go b/workhorse/internal/lfs/lfs.go
deleted file mode 100644
index e26f59046ea..00000000000
--- a/workhorse/internal/lfs/lfs.go
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
-In this file we handle git lfs objects downloads and uploads
-*/
-
-package lfs
-
-import (
- "fmt"
-
- "gitlab.com/gitlab-org/gitlab/workhorse/internal/api"
- "gitlab.com/gitlab-org/gitlab/workhorse/internal/config"
- "gitlab.com/gitlab-org/gitlab/workhorse/internal/filestore"
- "gitlab.com/gitlab-org/gitlab/workhorse/internal/upload"
-)
-
-type object struct {
- size int64
- oid string
-}
-
-func (l *object) Verify(fh *filestore.FileHandler) error {
- if fh.Size != l.size {
- return fmt.Errorf("LFSObject: expected size %d, wrote %d", l.size, fh.Size)
- }
-
- if fh.SHA256() != l.oid {
- return fmt.Errorf("LFSObject: expected sha256 %s, got %s", l.oid, fh.SHA256())
- }
-
- return nil
-}
-
-type uploadPreparer struct {
- objectPreparer upload.Preparer
-}
-
-func NewLfsUploadPreparer(c config.Config, objectPreparer upload.Preparer) upload.Preparer {
- return &uploadPreparer{objectPreparer: objectPreparer}
-}
-
-func (l *uploadPreparer) Prepare(a *api.Response) (*filestore.SaveFileOpts, upload.Verifier, error) {
- opts, _, err := l.objectPreparer.Prepare(a)
- if err != nil {
- return nil, nil, err
- }
-
- opts.TempFilePrefix = a.LfsOid
-
- return opts, &object{oid: a.LfsOid, size: a.LfsSize}, nil
-}
diff --git a/workhorse/internal/lfs/lfs_test.go b/workhorse/internal/lfs/lfs_test.go
deleted file mode 100644
index 63b2628343e..00000000000
--- a/workhorse/internal/lfs/lfs_test.go
+++ /dev/null
@@ -1,61 +0,0 @@
-package lfs_test
-
-import (
- "testing"
-
- "gitlab.com/gitlab-org/gitlab/workhorse/internal/api"
- "gitlab.com/gitlab-org/gitlab/workhorse/internal/config"
- "gitlab.com/gitlab-org/gitlab/workhorse/internal/lfs"
- "gitlab.com/gitlab-org/gitlab/workhorse/internal/upload"
-
- "github.com/stretchr/testify/require"
-)
-
-func TestLfsUploadPreparerWithConfig(t *testing.T) {
- lfsOid := "abcd1234"
- creds := config.S3Credentials{
- AwsAccessKeyID: "test-key",
- AwsSecretAccessKey: "test-secret",
- }
-
- c := config.Config{
- ObjectStorageCredentials: config.ObjectStorageCredentials{
- Provider: "AWS",
- S3Credentials: creds,
- },
- }
-
- r := &api.Response{
- LfsOid: lfsOid,
- RemoteObject: api.RemoteObject{
- ID: "the upload ID",
- UseWorkhorseClient: true,
- ObjectStorage: &api.ObjectStorageParams{
- Provider: "AWS",
- },
- },
- }
-
- uploadPreparer := upload.NewObjectStoragePreparer(c)
- lfsPreparer := lfs.NewLfsUploadPreparer(c, uploadPreparer)
- opts, verifier, err := lfsPreparer.Prepare(r)
-
- require.NoError(t, err)
- require.Equal(t, lfsOid, opts.TempFilePrefix)
- require.True(t, opts.ObjectStorageConfig.IsAWS())
- require.True(t, opts.UseWorkhorseClient)
- require.Equal(t, creds, opts.ObjectStorageConfig.S3Credentials)
- require.NotNil(t, verifier)
-}
-
-func TestLfsUploadPreparerWithNoConfig(t *testing.T) {
- c := config.Config{}
- r := &api.Response{RemoteObject: api.RemoteObject{ID: "the upload ID"}}
- uploadPreparer := upload.NewObjectStoragePreparer(c)
- lfsPreparer := lfs.NewLfsUploadPreparer(c, uploadPreparer)
- opts, verifier, err := lfsPreparer.Prepare(r)
-
- require.NoError(t, err)
- require.False(t, opts.UseWorkhorseClient)
- require.NotNil(t, verifier)
-}
diff --git a/workhorse/internal/objectstore/gocloud_object_test.go b/workhorse/internal/objectstore/gocloud_object_test.go
deleted file mode 100644
index f320a65dbfb..00000000000
--- a/workhorse/internal/objectstore/gocloud_object_test.go
+++ /dev/null
@@ -1,56 +0,0 @@
-package objectstore_test
-
-import (
- "context"
- "fmt"
- "strings"
- "testing"
- "time"
-
- "github.com/stretchr/testify/require"
-
- "gitlab.com/gitlab-org/gitlab/workhorse/internal/objectstore"
- "gitlab.com/gitlab-org/gitlab/workhorse/internal/objectstore/test"
- "gitlab.com/gitlab-org/gitlab/workhorse/internal/testhelper"
-)
-
-func TestGoCloudObjectUpload(t *testing.T) {
- mux, _, cleanup := test.SetupGoCloudFileBucket(t, "azuretest")
- defer cleanup()
-
- ctx, cancel := context.WithCancel(context.Background())
- deadline := time.Now().Add(testTimeout)
-
- objectName := "test.png"
- testURL := "azuretest://azure.example.com/test-container"
- p := &objectstore.GoCloudObjectParams{Ctx: ctx, Mux: mux, BucketURL: testURL, ObjectName: objectName}
- object, err := objectstore.NewGoCloudObject(p)
- require.NotNil(t, object)
- require.NoError(t, err)
-
- // copy data
- n, err := object.Consume(ctx, strings.NewReader(test.ObjectContent), deadline)
- require.NoError(t, err)
- require.Equal(t, test.ObjectSize, n, "Uploaded file mismatch")
-
- bucket, err := mux.OpenBucket(ctx, testURL)
- require.NoError(t, err)
-
- // Verify the data was copied correctly.
- received, err := bucket.ReadAll(ctx, objectName)
- require.NoError(t, err)
- require.Equal(t, []byte(test.ObjectContent), received)
-
- cancel()
-
- testhelper.Retry(t, 5*time.Second, func() error {
- exists, err := bucket.Exists(ctx, objectName)
- require.NoError(t, err)
-
- if exists {
- return fmt.Errorf("file %s is still present", objectName)
- } else {
- return nil
- }
- })
-}
diff --git a/workhorse/internal/objectstore/multipart_test.go b/workhorse/internal/objectstore/multipart_test.go
deleted file mode 100644
index 42ab5b4e535..00000000000
--- a/workhorse/internal/objectstore/multipart_test.go
+++ /dev/null
@@ -1,64 +0,0 @@
-package objectstore_test
-
-import (
- "context"
- "io/ioutil"
- "net/http"
- "net/http/httptest"
- "strings"
- "testing"
- "time"
-
- "github.com/stretchr/testify/require"
-
- "gitlab.com/gitlab-org/gitlab/workhorse/internal/objectstore"
- "gitlab.com/gitlab-org/gitlab/workhorse/internal/objectstore/test"
-)
-
-func TestMultipartUploadWithUpcaseETags(t *testing.T) {
- ctx, cancel := context.WithCancel(context.Background())
- defer cancel()
-
- var putCnt, postCnt int
-
- ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- _, err := ioutil.ReadAll(r.Body)
- require.NoError(t, err)
- defer r.Body.Close()
-
- // Part upload request
- if r.Method == "PUT" {
- putCnt++
-
- w.Header().Set("ETag", strings.ToUpper(test.ObjectMD5))
- }
-
- // POST with CompleteMultipartUpload request
- if r.Method == "POST" {
- completeBody := `<CompleteMultipartUploadResult>
- <Bucket>test-bucket</Bucket>
- <ETag>No Longer Checked</ETag>
- </CompleteMultipartUploadResult>`
- postCnt++
-
- w.Write([]byte(completeBody))
- }
- }))
- defer ts.Close()
-
- deadline := time.Now().Add(testTimeout)
-
- m, err := objectstore.NewMultipart(
- []string{ts.URL}, // a single presigned part URL
- ts.URL, // the complete multipart upload URL
- "", // no abort
- "", // no delete
- map[string]string{}, // no custom headers
- test.ObjectSize) // parts size equal to the whole content. Only 1 part
- require.NoError(t, err)
-
- _, err = m.Consume(ctx, strings.NewReader(test.ObjectContent), deadline)
- require.NoError(t, err)
- require.Equal(t, 1, putCnt, "1 part expected")
- require.Equal(t, 1, postCnt, "1 complete multipart upload expected")
-}
diff --git a/workhorse/internal/objectstore/object_test.go b/workhorse/internal/objectstore/object_test.go
deleted file mode 100644
index b9c1fb2087b..00000000000
--- a/workhorse/internal/objectstore/object_test.go
+++ /dev/null
@@ -1,149 +0,0 @@
-package objectstore_test
-
-import (
- "context"
- "io"
- "net/http"
- "net/http/httptest"
- "strings"
- "testing"
- "time"
-
- "github.com/stretchr/testify/require"
-
- "gitlab.com/gitlab-org/gitlab/workhorse/internal/objectstore"
- "gitlab.com/gitlab-org/gitlab/workhorse/internal/objectstore/test"
-)
-
-const testTimeout = 10 * time.Second
-
-type osFactory func() (*test.ObjectstoreStub, *httptest.Server)
-
-func testObjectUploadNoErrors(t *testing.T, startObjectStore osFactory, useDeleteURL bool, contentType string) {
- osStub, ts := startObjectStore()
- defer ts.Close()
-
- objectURL := ts.URL + test.ObjectPath
- var deleteURL string
- if useDeleteURL {
- deleteURL = objectURL
- }
-
- putHeaders := map[string]string{"Content-Type": contentType}
-
- ctx, cancel := context.WithCancel(context.Background())
- defer cancel()
-
- deadline := time.Now().Add(testTimeout)
- object, err := objectstore.NewObject(objectURL, deleteURL, putHeaders, test.ObjectSize)
- require.NoError(t, err)
-
- // copy data
- n, err := object.Consume(ctx, strings.NewReader(test.ObjectContent), deadline)
- require.NoError(t, err)
- require.Equal(t, test.ObjectSize, n, "Uploaded file mismatch")
-
- require.Equal(t, contentType, osStub.GetHeader(test.ObjectPath, "Content-Type"))
-
- // Checking MD5 extraction
- require.Equal(t, osStub.GetObjectMD5(test.ObjectPath), object.ETag())
-
- // Checking cleanup
- cancel()
- require.Equal(t, 1, osStub.PutsCnt(), "Object hasn't been uploaded")
-
- var expectedDeleteCnt int
- if useDeleteURL {
- expectedDeleteCnt = 1
- }
- require.Eventually(t, func() bool { return osStub.DeletesCnt() == expectedDeleteCnt }, time.Second, time.Millisecond)
-
- if useDeleteURL {
- require.Equal(t, 1, osStub.DeletesCnt(), "Object hasn't been deleted")
- } else {
- require.Equal(t, 0, osStub.DeletesCnt(), "Object has been deleted")
- }
-}
-
-func TestObjectUpload(t *testing.T) {
- t.Run("with delete URL", func(t *testing.T) {
- testObjectUploadNoErrors(t, test.StartObjectStore, true, "application/octet-stream")
- })
- t.Run("without delete URL", func(t *testing.T) {
- testObjectUploadNoErrors(t, test.StartObjectStore, false, "application/octet-stream")
- })
- t.Run("with custom content type", func(t *testing.T) {
- testObjectUploadNoErrors(t, test.StartObjectStore, false, "image/jpeg")
- })
- t.Run("with upcase ETAG", func(t *testing.T) {
- factory := func() (*test.ObjectstoreStub, *httptest.Server) {
- md5s := map[string]string{
- test.ObjectPath: strings.ToUpper(test.ObjectMD5),
- }
-
- return test.StartObjectStoreWithCustomMD5(md5s)
- }
-
- testObjectUploadNoErrors(t, factory, false, "application/octet-stream")
- })
-}
-
-func TestObjectUpload404(t *testing.T) {
- ts := httptest.NewServer(http.NotFoundHandler())
- defer ts.Close()
-
- ctx, cancel := context.WithCancel(context.Background())
- defer cancel()
-
- deadline := time.Now().Add(testTimeout)
- objectURL := ts.URL + test.ObjectPath
- object, err := objectstore.NewObject(objectURL, "", map[string]string{}, test.ObjectSize)
- require.NoError(t, err)
- _, err = object.Consume(ctx, strings.NewReader(test.ObjectContent), deadline)
-
- require.Error(t, err)
- _, isStatusCodeError := err.(objectstore.StatusCodeError)
- require.True(t, isStatusCodeError, "Should fail with StatusCodeError")
- require.Contains(t, err.Error(), "404")
-}
-
-type endlessReader struct{}
-
-func (e *endlessReader) Read(p []byte) (n int, err error) {
- for i := 0; i < len(p); i++ {
- p[i] = '*'
- }
-
- return len(p), nil
-}
-
-// TestObjectUploadBrokenConnection purpose is to ensure that errors caused by the upload destination get propagated back correctly.
-// This is important for troubleshooting in production.
-func TestObjectUploadBrokenConnection(t *testing.T) {
- // This test server closes connection immediately
- ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- hj, ok := w.(http.Hijacker)
- if !ok {
- require.FailNow(t, "webserver doesn't support hijacking")
- }
- conn, _, err := hj.Hijack()
- if err != nil {
- http.Error(w, err.Error(), http.StatusInternalServerError)
- return
- }
- conn.Close()
- }))
- defer ts.Close()
-
- ctx, cancel := context.WithCancel(context.Background())
- defer cancel()
-
- deadline := time.Now().Add(testTimeout)
- objectURL := ts.URL + test.ObjectPath
- object, err := objectstore.NewObject(objectURL, "", map[string]string{}, -1)
- require.NoError(t, err)
-
- _, copyErr := object.Consume(ctx, &endlessReader{}, deadline)
- require.Error(t, copyErr)
- require.NotEqual(t, io.ErrClosedPipe, copyErr, "We are shadowing the real error")
-}
diff --git a/workhorse/internal/objectstore/s3_object_test.go b/workhorse/internal/objectstore/s3_object_test.go
deleted file mode 100644
index c7426e3843b..00000000000
--- a/workhorse/internal/objectstore/s3_object_test.go
+++ /dev/null
@@ -1,174 +0,0 @@
-package objectstore_test
-
-import (
- "context"
- "fmt"
- "io"
- "io/ioutil"
- "os"
- "path/filepath"
- "strings"
- "sync"
- "testing"
- "time"
-
- "github.com/aws/aws-sdk-go/aws/awserr"
- "github.com/aws/aws-sdk-go/aws/session"
- "github.com/aws/aws-sdk-go/service/s3"
- "github.com/stretchr/testify/require"
-
- "gitlab.com/gitlab-org/gitlab/workhorse/internal/config"
- "gitlab.com/gitlab-org/gitlab/workhorse/internal/objectstore"
- "gitlab.com/gitlab-org/gitlab/workhorse/internal/objectstore/test"
- "gitlab.com/gitlab-org/gitlab/workhorse/internal/testhelper"
-)
-
-type failedReader struct {
- io.Reader
-}
-
-func (r *failedReader) Read(p []byte) (int, error) {
- origErr := fmt.Errorf("entity is too large")
- return 0, awserr.New("Read", "read failed", origErr)
-}
-
-func TestS3ObjectUpload(t *testing.T) {
- testCases := []struct {
- encryption string
- }{
- {encryption: ""},
- {encryption: s3.ServerSideEncryptionAes256},
- {encryption: s3.ServerSideEncryptionAwsKms},
- }
-
- for _, tc := range testCases {
- t.Run(fmt.Sprintf("encryption=%v", tc.encryption), func(t *testing.T) {
- creds, config, sess, ts := test.SetupS3(t, tc.encryption)
- defer ts.Close()
-
- deadline := time.Now().Add(testTimeout)
- tmpDir, err := ioutil.TempDir("", "workhorse-test-")
- require.NoError(t, err)
- defer os.Remove(tmpDir)
-
- objectName := filepath.Join(tmpDir, "s3-test-data")
- ctx, cancel := context.WithCancel(context.Background())
-
- object, err := objectstore.NewS3Object(objectName, creds, config)
- require.NoError(t, err)
-
- // copy data
- n, err := object.Consume(ctx, strings.NewReader(test.ObjectContent), deadline)
- require.NoError(t, err)
- require.Equal(t, test.ObjectSize, n, "Uploaded file mismatch")
-
- test.S3ObjectExists(t, sess, config, objectName, test.ObjectContent)
- test.CheckS3Metadata(t, sess, config, objectName)
-
- cancel()
-
- testhelper.Retry(t, 5*time.Second, func() error {
- if test.S3ObjectDoesNotExist(t, sess, config, objectName) {
- return nil
- }
-
- return fmt.Errorf("file is still present")
- })
- })
- }
-}
-
-func TestConcurrentS3ObjectUpload(t *testing.T) {
- creds, uploadsConfig, uploadsSession, uploadServer := test.SetupS3WithBucket(t, "uploads", "")
- defer uploadServer.Close()
-
- // This will return a separate S3 endpoint
- _, artifactsConfig, artifactsSession, artifactsServer := test.SetupS3WithBucket(t, "artifacts", "")
- defer artifactsServer.Close()
-
- deadline := time.Now().Add(testTimeout)
- tmpDir, err := ioutil.TempDir("", "workhorse-test-")
- require.NoError(t, err)
- defer os.Remove(tmpDir)
-
- var wg sync.WaitGroup
-
- for i := 0; i < 4; i++ {
- wg.Add(1)
-
- go func(index int) {
- var sess *session.Session
- var config config.S3Config
-
- if index%2 == 0 {
- sess = uploadsSession
- config = uploadsConfig
- } else {
- sess = artifactsSession
- config = artifactsConfig
- }
-
- name := fmt.Sprintf("s3-test-data-%d", index)
- objectName := filepath.Join(tmpDir, name)
- ctx, cancel := context.WithCancel(context.Background())
- defer cancel()
-
- object, err := objectstore.NewS3Object(objectName, creds, config)
- require.NoError(t, err)
-
- // copy data
- n, err := object.Consume(ctx, strings.NewReader(test.ObjectContent), deadline)
- require.NoError(t, err)
- require.Equal(t, test.ObjectSize, n, "Uploaded file mismatch")
-
- test.S3ObjectExists(t, sess, config, objectName, test.ObjectContent)
- wg.Done()
- }(i)
- }
-
- wg.Wait()
-}
-
-func TestS3ObjectUploadCancel(t *testing.T) {
- creds, config, _, ts := test.SetupS3(t, "")
- defer ts.Close()
-
- ctx, cancel := context.WithCancel(context.Background())
-
- deadline := time.Now().Add(testTimeout)
- tmpDir, err := ioutil.TempDir("", "workhorse-test-")
- require.NoError(t, err)
- defer os.Remove(tmpDir)
-
- objectName := filepath.Join(tmpDir, "s3-test-data")
-
- object, err := objectstore.NewS3Object(objectName, creds, config)
-
- require.NoError(t, err)
-
- // Cancel the transfer before the data has been copied to ensure
- // we handle this gracefully.
- cancel()
-
- _, err = object.Consume(ctx, strings.NewReader(test.ObjectContent), deadline)
- require.Error(t, err)
- require.Equal(t, "context canceled", err.Error())
-}
-
-func TestS3ObjectUploadLimitReached(t *testing.T) {
- creds, config, _, ts := test.SetupS3(t, "")
- defer ts.Close()
-
- deadline := time.Now().Add(testTimeout)
- tmpDir, err := ioutil.TempDir("", "workhorse-test-")
- require.NoError(t, err)
- defer os.Remove(tmpDir)
-
- objectName := filepath.Join(tmpDir, "s3-test-data")
- object, err := objectstore.NewS3Object(objectName, creds, config)
- require.NoError(t, err)
-
- _, err = object.Consume(context.Background(), &failedReader{}, deadline)
- require.Error(t, err)
- require.Equal(t, "entity is too large", err.Error())
-}
diff --git a/workhorse/internal/objectstore/test/objectstore_stub.go b/workhorse/internal/objectstore/test/objectstore_stub.go
deleted file mode 100644
index ec5e271b759..00000000000
--- a/workhorse/internal/objectstore/test/objectstore_stub.go
+++ /dev/null
@@ -1,278 +0,0 @@
-package test
-
-import (
- "crypto/md5"
- "encoding/hex"
- "encoding/xml"
- "fmt"
- "io"
- "io/ioutil"
- "net/http"
- "net/http/httptest"
- "strconv"
- "strings"
- "sync"
-
- "gitlab.com/gitlab-org/gitlab/workhorse/internal/objectstore"
-)
-
-type partsEtagMap map[int]string
-
-// ObjectstoreStub is a testing implementation of ObjectStore.
-// Instead of storing objects it will just save md5sum.
-type ObjectstoreStub struct {
- // bucket contains md5sum of uploaded objects
- bucket map[string]string
- // overwriteMD5 contains overwrites for md5sum that should be return instead of the regular hash
- overwriteMD5 map[string]string
- // multipart is a map of MultipartUploads
- multipart map[string]partsEtagMap
- // HTTP header sent along request
- headers map[string]*http.Header
-
- puts int
- deletes int
-
- m sync.Mutex
-}
-
-// StartObjectStore will start an ObjectStore stub
-func StartObjectStore() (*ObjectstoreStub, *httptest.Server) {
- return StartObjectStoreWithCustomMD5(make(map[string]string))
-}
-
-// StartObjectStoreWithCustomMD5 will start an ObjectStore stub: md5Hashes contains overwrites for md5sum that should be return on PutObject
-func StartObjectStoreWithCustomMD5(md5Hashes map[string]string) (*ObjectstoreStub, *httptest.Server) {
- os := &ObjectstoreStub{
- bucket: make(map[string]string),
- multipart: make(map[string]partsEtagMap),
- overwriteMD5: make(map[string]string),
- headers: make(map[string]*http.Header),
- }
-
- for k, v := range md5Hashes {
- os.overwriteMD5[k] = v
- }
-
- return os, httptest.NewServer(os)
-}
-
-// PutsCnt counts PutObject invocations
-func (o *ObjectstoreStub) PutsCnt() int {
- o.m.Lock()
- defer o.m.Unlock()
-
- return o.puts
-}
-
-// DeletesCnt counts DeleteObject invocation of a valid object
-func (o *ObjectstoreStub) DeletesCnt() int {
- o.m.Lock()
- defer o.m.Unlock()
-
- return o.deletes
-}
-
-// GetObjectMD5 return the calculated MD5 of the object uploaded to path
-// it will return an empty string if no object has been uploaded on such path
-func (o *ObjectstoreStub) GetObjectMD5(path string) string {
- o.m.Lock()
- defer o.m.Unlock()
-
- return o.bucket[path]
-}
-
-// GetHeader returns a given HTTP header of the object uploaded to the path
-func (o *ObjectstoreStub) GetHeader(path, key string) string {
- o.m.Lock()
- defer o.m.Unlock()
-
- if val, ok := o.headers[path]; ok {
- return val.Get(key)
- }
-
- return ""
-}
-
-// InitiateMultipartUpload prepare the ObjectstoreStob to receive a MultipartUpload on path
-// It will return an error if a MultipartUpload is already in progress on that path
-// InitiateMultipartUpload is only used during test setup.
-// Workhorse's production code does not know how to initiate a multipart upload.
-//
-// Real S3 multipart uploads are more complicated than what we do here,
-// but this is enough to verify that workhorse's production code behaves as intended.
-func (o *ObjectstoreStub) InitiateMultipartUpload(path string) error {
- o.m.Lock()
- defer o.m.Unlock()
-
- if o.multipart[path] != nil {
- return fmt.Errorf("MultipartUpload for %q already in progress", path)
- }
-
- o.multipart[path] = make(partsEtagMap)
- return nil
-}
-
-// IsMultipartUpload check if the given path has a MultipartUpload in progress
-func (o *ObjectstoreStub) IsMultipartUpload(path string) bool {
- o.m.Lock()
- defer o.m.Unlock()
-
- return o.isMultipartUpload(path)
-}
-
-// isMultipartUpload is the lock free version of IsMultipartUpload
-func (o *ObjectstoreStub) isMultipartUpload(path string) bool {
- return o.multipart[path] != nil
-}
-
-func (o *ObjectstoreStub) removeObject(w http.ResponseWriter, r *http.Request) {
- o.m.Lock()
- defer o.m.Unlock()
-
- objectPath := r.URL.Path
- if o.isMultipartUpload(objectPath) {
- o.deletes++
- delete(o.multipart, objectPath)
-
- w.WriteHeader(200)
- } else if _, ok := o.bucket[objectPath]; ok {
- o.deletes++
- delete(o.bucket, objectPath)
-
- w.WriteHeader(200)
- } else {
- w.WriteHeader(404)
- }
-}
-
-func (o *ObjectstoreStub) putObject(w http.ResponseWriter, r *http.Request) {
- o.m.Lock()
- defer o.m.Unlock()
-
- objectPath := r.URL.Path
-
- etag, overwritten := o.overwriteMD5[objectPath]
- if !overwritten {
- hasher := md5.New()
- io.Copy(hasher, r.Body)
-
- checksum := hasher.Sum(nil)
- etag = hex.EncodeToString(checksum)
- }
-
- o.headers[objectPath] = &r.Header
- o.puts++
- if o.isMultipartUpload(objectPath) {
- pNumber := r.URL.Query().Get("partNumber")
- idx, err := strconv.Atoi(pNumber)
- if err != nil {
- http.Error(w, fmt.Sprintf("malformed partNumber: %v", err), 400)
- return
- }
-
- o.multipart[objectPath][idx] = etag
- } else {
- o.bucket[objectPath] = etag
- }
-
- w.Header().Set("ETag", etag)
- w.WriteHeader(200)
-}
-
-func MultipartUploadInternalError() *objectstore.CompleteMultipartUploadError {
- return &objectstore.CompleteMultipartUploadError{Code: "InternalError", Message: "malformed object path"}
-}
-
-func (o *ObjectstoreStub) completeMultipartUpload(w http.ResponseWriter, r *http.Request) {
- o.m.Lock()
- defer o.m.Unlock()
-
- objectPath := r.URL.Path
-
- multipart := o.multipart[objectPath]
- if multipart == nil {
- http.Error(w, "Unknown MultipartUpload", 404)
- return
- }
-
- buf, err := ioutil.ReadAll(r.Body)
- if err != nil {
- http.Error(w, err.Error(), 500)
- return
- }
-
- var msg objectstore.CompleteMultipartUpload
- err = xml.Unmarshal(buf, &msg)
- if err != nil {
- http.Error(w, err.Error(), 400)
- return
- }
-
- for _, part := range msg.Part {
- etag := multipart[part.PartNumber]
- if etag != part.ETag {
- msg := fmt.Sprintf("ETag mismatch on part %d. Expected %q got %q", part.PartNumber, etag, part.ETag)
- http.Error(w, msg, 400)
- return
- }
- }
-
- etag, overwritten := o.overwriteMD5[objectPath]
- if !overwritten {
- etag = "CompleteMultipartUploadETag"
- }
-
- o.bucket[objectPath] = etag
- delete(o.multipart, objectPath)
-
- w.Header().Set("ETag", etag)
- split := strings.SplitN(objectPath[1:], "/", 2)
- if len(split) < 2 {
- encodeXMLAnswer(w, MultipartUploadInternalError())
- return
- }
-
- bucket := split[0]
- key := split[1]
- answer := objectstore.CompleteMultipartUploadResult{
- Location: r.URL.String(),
- Bucket: bucket,
- Key: key,
- ETag: etag,
- }
- encodeXMLAnswer(w, answer)
-}
-
-func encodeXMLAnswer(w http.ResponseWriter, answer interface{}) {
- w.Header().Set("Content-Type", "text/xml")
-
- enc := xml.NewEncoder(w)
- if err := enc.Encode(answer); err != nil {
- http.Error(w, err.Error(), 500)
- }
-}
-
-func (o *ObjectstoreStub) ServeHTTP(w http.ResponseWriter, r *http.Request) {
- if r.Body != nil {
- defer r.Body.Close()
- }
-
- fmt.Println("ObjectStore Stub:", r.Method, r.URL.String())
-
- if r.URL.Path == "" {
- http.Error(w, "No path provided", 404)
- return
- }
-
- switch r.Method {
- case "DELETE":
- o.removeObject(w, r)
- case "PUT":
- o.putObject(w, r)
- case "POST":
- o.completeMultipartUpload(w, r)
- default:
- w.WriteHeader(404)
- }
-}
diff --git a/workhorse/internal/staticpages/servefile.go b/workhorse/internal/staticpages/servefile.go
index be314f181b7..18fcdadcbed 100644
--- a/workhorse/internal/staticpages/servefile.go
+++ b/workhorse/internal/staticpages/servefile.go
@@ -67,6 +67,9 @@ func (s *Static) ServeExisting(prefix urlprefix.Prefix, cache CacheMode, notFoun
notFoundHandler.ServeHTTP(w, r)
return
}
+
+ w.Header().Set("X-Content-Type-Options", "nosniff")
+
defer content.Close()
switch cache {
diff --git a/workhorse/internal/staticpages/servefile_test.go b/workhorse/internal/staticpages/servefile_test.go
index f27bd0ccaeb..67675beccf8 100644
--- a/workhorse/internal/staticpages/servefile_test.go
+++ b/workhorse/internal/staticpages/servefile_test.go
@@ -78,6 +78,7 @@ func TestServingTheActualFile(t *testing.T) {
w := httptest.NewRecorder()
st := &Static{DocumentRoot: dir}
st.ServeExisting("/", CacheDisabled, nil).ServeHTTP(w, httpRequest)
+ testhelper.RequireResponseHeader(t, w, "X-Content-Type-Options", "nosniff")
require.Equal(t, 200, w.Code)
if w.Body.String() != fileContent {
t.Error("We should serve the file: ", w.Body.String())
@@ -109,6 +110,7 @@ func TestExcludedPaths(t *testing.T) {
st.ServeExisting("/", CacheDisabled, nil).ServeHTTP(w, httpRequest)
if tc.found {
+ testhelper.RequireResponseHeader(t, w, "X-Content-Type-Options", "nosniff")
require.Equal(t, 200, w.Code)
require.Equal(t, tc.contents, w.Body.String())
} else {
@@ -144,6 +146,7 @@ func testServingThePregzippedFile(t *testing.T, enableGzip bool) {
w := httptest.NewRecorder()
st := &Static{DocumentRoot: dir}
st.ServeExisting("/", CacheDisabled, nil).ServeHTTP(w, httpRequest)
+ testhelper.RequireResponseHeader(t, w, "X-Content-Type-Options", "nosniff")
require.Equal(t, 200, w.Code)
if enableGzip {
testhelper.RequireResponseHeader(t, w, "Content-Encoding", "gzip")
diff --git a/workhorse/internal/testhelper/testhelper.go b/workhorse/internal/testhelper/testhelper.go
index dae8f9b3149..6bbdfddcd60 100644
--- a/workhorse/internal/testhelper/testhelper.go
+++ b/workhorse/internal/testhelper/testhelper.go
@@ -167,3 +167,16 @@ func Retry(t testing.TB, timeout time.Duration, fn func() error) {
}
t.Fatalf("test timeout after %v; last error: %v", timeout, err)
}
+
+func SetupStaticFileHelper(t *testing.T, fpath, content, directory string) string {
+ cwd, err := os.Getwd()
+ require.NoError(t, err, "get working directory")
+
+ absDocumentRoot := path.Join(cwd, directory)
+ require.NoError(t, os.MkdirAll(path.Join(absDocumentRoot, path.Dir(fpath)), 0755), "create document root")
+
+ staticFile := path.Join(absDocumentRoot, fpath)
+ require.NoError(t, ioutil.WriteFile(staticFile, []byte(content), 0666), "write file content")
+
+ return absDocumentRoot
+}
diff --git a/workhorse/internal/upload/accelerate.go b/workhorse/internal/upload/accelerate.go
deleted file mode 100644
index 28d3b3dee2e..00000000000
--- a/workhorse/internal/upload/accelerate.go
+++ /dev/null
@@ -1,37 +0,0 @@
-package upload
-
-import (
- "fmt"
- "net/http"
-
- "github.com/golang-jwt/jwt/v4"
-
- "gitlab.com/gitlab-org/gitlab/workhorse/internal/api"
- "gitlab.com/gitlab-org/gitlab/workhorse/internal/helper"
-)
-
-const RewrittenFieldsHeader = "Gitlab-Workhorse-Multipart-Fields"
-
-type MultipartClaims struct {
- RewrittenFields map[string]string `json:"rewritten_fields"`
- jwt.StandardClaims
-}
-
-// Multipart is a request middleware. If the request has a MIME multipart
-// request body, the middleware will iterate through the multipart parts.
-// When it finds a file part (filename != ""), the middleware will save
-// the file contents to a temporary location and replace the file part
-// with a reference to the temporary location.
-func Multipart(rails PreAuthorizer, h http.Handler, p Preparer) http.Handler {
- return rails.PreAuthorizeHandler(func(w http.ResponseWriter, r *http.Request, a *api.Response) {
- s := &SavedFileTracker{Request: r}
-
- opts, _, err := p.Prepare(a)
- if err != nil {
- helper.Fail500(w, r, fmt.Errorf("Multipart: error preparing file storage options"))
- return
- }
-
- InterceptMultipartFiles(w, r, h, a, s, opts)
- }, "/authorize")
-}
diff --git a/workhorse/internal/upload/artifacts_store_test.go b/workhorse/internal/upload/artifacts_store_test.go
new file mode 100644
index 00000000000..97e66fc37a4
--- /dev/null
+++ b/workhorse/internal/upload/artifacts_store_test.go
@@ -0,0 +1,335 @@
+package upload
+
+import (
+ "archive/zip"
+ "bytes"
+ "crypto/md5"
+ "encoding/hex"
+ "fmt"
+ "io/ioutil"
+ "mime/multipart"
+ "net/http"
+ "net/http/httptest"
+ "os"
+ "testing"
+ "time"
+
+ "github.com/stretchr/testify/require"
+
+ "gitlab.com/gitlab-org/gitlab/workhorse/internal/api"
+ "gitlab.com/gitlab-org/gitlab/workhorse/internal/testhelper"
+ "gitlab.com/gitlab-org/gitlab/workhorse/internal/upload/destination/objectstore/test"
+)
+
+func createTestZipArchive(t *testing.T) (data []byte, md5Hash string) {
+ var buffer bytes.Buffer
+ archive := zip.NewWriter(&buffer)
+ fileInArchive, err := archive.Create("test.file")
+ require.NoError(t, err)
+ fmt.Fprint(fileInArchive, "test")
+ archive.Close()
+ data = buffer.Bytes()
+
+ hasher := md5.New()
+ hasher.Write(data)
+ hexHash := hasher.Sum(nil)
+ md5Hash = hex.EncodeToString(hexHash)
+
+ return data, md5Hash
+}
+
+func createTestMultipartForm(t *testing.T, data []byte) (bytes.Buffer, string) {
+ var buffer bytes.Buffer
+ writer := multipart.NewWriter(&buffer)
+ file, err := writer.CreateFormFile("file", "my.file")
+ require.NoError(t, err)
+ file.Write(data)
+ writer.Close()
+ return buffer, writer.FormDataContentType()
+}
+
+func testUploadArtifactsFromTestZip(t *testing.T, ts *httptest.Server) *httptest.ResponseRecorder {
+ archiveData, _ := createTestZipArchive(t)
+ contentBuffer, contentType := createTestMultipartForm(t, archiveData)
+
+ return testUploadArtifacts(t, contentType, ts.URL+Path, &contentBuffer)
+}
+
+func TestUploadHandlerSendingToExternalStorage(t *testing.T) {
+ tempPath, err := ioutil.TempDir("", "uploads")
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer os.RemoveAll(tempPath)
+
+ archiveData, md5 := createTestZipArchive(t)
+ archiveFile, err := ioutil.TempFile("", "artifact.zip")
+ require.NoError(t, err)
+ defer os.Remove(archiveFile.Name())
+ _, err = archiveFile.Write(archiveData)
+ require.NoError(t, err)
+ archiveFile.Close()
+
+ storeServerCalled := 0
+ storeServerMux := http.NewServeMux()
+ storeServerMux.HandleFunc("/url/put", func(w http.ResponseWriter, r *http.Request) {
+ require.Equal(t, "PUT", r.Method)
+
+ receivedData, err := ioutil.ReadAll(r.Body)
+ require.NoError(t, err)
+ require.Equal(t, archiveData, receivedData)
+
+ storeServerCalled++
+ w.Header().Set("ETag", md5)
+ w.WriteHeader(200)
+ })
+ storeServerMux.HandleFunc("/store-id", func(w http.ResponseWriter, r *http.Request) {
+ http.ServeFile(w, r, archiveFile.Name())
+ })
+
+ responseProcessorCalled := 0
+ responseProcessor := func(w http.ResponseWriter, r *http.Request) {
+ require.Equal(t, "store-id", r.FormValue("file.remote_id"))
+ require.NotEmpty(t, r.FormValue("file.remote_url"))
+ w.WriteHeader(200)
+ responseProcessorCalled++
+ }
+
+ storeServer := httptest.NewServer(storeServerMux)
+ defer storeServer.Close()
+
+ qs := fmt.Sprintf("?%s=%s", ArtifactFormatKey, ArtifactFormatZip)
+
+ tests := []struct {
+ name string
+ preauth *api.Response
+ }{
+ {
+ name: "ObjectStore Upload",
+ preauth: &api.Response{
+ RemoteObject: api.RemoteObject{
+ StoreURL: storeServer.URL + "/url/put" + qs,
+ ID: "store-id",
+ GetURL: storeServer.URL + "/store-id",
+ },
+ },
+ },
+ }
+
+ for _, test := range tests {
+ t.Run(test.name, func(t *testing.T) {
+ storeServerCalled = 0
+ responseProcessorCalled = 0
+
+ ts := testArtifactsUploadServer(t, test.preauth, responseProcessor)
+ defer ts.Close()
+
+ contentBuffer, contentType := createTestMultipartForm(t, archiveData)
+ response := testUploadArtifacts(t, contentType, ts.URL+Path+qs, &contentBuffer)
+ require.Equal(t, http.StatusOK, response.Code)
+ testhelper.RequireResponseHeader(t, response, MetadataHeaderKey, MetadataHeaderPresent)
+ require.Equal(t, 1, storeServerCalled, "store should be called only once")
+ require.Equal(t, 1, responseProcessorCalled, "response processor should be called only once")
+ })
+ }
+}
+
+func TestUploadHandlerSendingToExternalStorageAndStorageServerUnreachable(t *testing.T) {
+ tempPath, err := ioutil.TempDir("", "uploads")
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer os.RemoveAll(tempPath)
+
+ responseProcessor := func(w http.ResponseWriter, r *http.Request) {
+ t.Fatal("it should not be called")
+ }
+
+ authResponse := &api.Response{
+ TempPath: tempPath,
+ RemoteObject: api.RemoteObject{
+ StoreURL: "http://localhost:12323/invalid/url",
+ ID: "store-id",
+ },
+ }
+
+ ts := testArtifactsUploadServer(t, authResponse, responseProcessor)
+ defer ts.Close()
+
+ response := testUploadArtifactsFromTestZip(t, ts)
+ require.Equal(t, http.StatusInternalServerError, response.Code)
+}
+
+func TestUploadHandlerSendingToExternalStorageAndInvalidURLIsUsed(t *testing.T) {
+ tempPath, err := ioutil.TempDir("", "uploads")
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer os.RemoveAll(tempPath)
+
+ responseProcessor := func(w http.ResponseWriter, r *http.Request) {
+ t.Fatal("it should not be called")
+ }
+
+ authResponse := &api.Response{
+ TempPath: tempPath,
+ RemoteObject: api.RemoteObject{
+ StoreURL: "htt:////invalid-url",
+ ID: "store-id",
+ },
+ }
+
+ ts := testArtifactsUploadServer(t, authResponse, responseProcessor)
+ defer ts.Close()
+
+ response := testUploadArtifactsFromTestZip(t, ts)
+ require.Equal(t, http.StatusInternalServerError, response.Code)
+}
+
+func TestUploadHandlerSendingToExternalStorageAndItReturnsAnError(t *testing.T) {
+ putCalledTimes := 0
+
+ storeServerMux := http.NewServeMux()
+ storeServerMux.HandleFunc("/url/put", func(w http.ResponseWriter, r *http.Request) {
+ putCalledTimes++
+ require.Equal(t, "PUT", r.Method)
+ w.WriteHeader(510)
+ })
+
+ responseProcessor := func(w http.ResponseWriter, r *http.Request) {
+ t.Fatal("it should not be called")
+ }
+
+ storeServer := httptest.NewServer(storeServerMux)
+ defer storeServer.Close()
+
+ authResponse := &api.Response{
+ RemoteObject: api.RemoteObject{
+ StoreURL: storeServer.URL + "/url/put",
+ ID: "store-id",
+ },
+ }
+
+ ts := testArtifactsUploadServer(t, authResponse, responseProcessor)
+ defer ts.Close()
+
+ response := testUploadArtifactsFromTestZip(t, ts)
+ require.Equal(t, http.StatusInternalServerError, response.Code)
+ require.Equal(t, 1, putCalledTimes, "upload should be called only once")
+}
+
+func TestUploadHandlerSendingToExternalStorageAndSupportRequestTimeout(t *testing.T) {
+ putCalledTimes := 0
+
+ storeServerMux := http.NewServeMux()
+ storeServerMux.HandleFunc("/url/put", func(w http.ResponseWriter, r *http.Request) {
+ putCalledTimes++
+ require.Equal(t, "PUT", r.Method)
+ time.Sleep(10 * time.Second)
+ w.WriteHeader(510)
+ })
+
+ responseProcessor := func(w http.ResponseWriter, r *http.Request) {
+ t.Fatal("it should not be called")
+ }
+
+ storeServer := httptest.NewServer(storeServerMux)
+ defer storeServer.Close()
+
+ authResponse := &api.Response{
+ RemoteObject: api.RemoteObject{
+ StoreURL: storeServer.URL + "/url/put",
+ ID: "store-id",
+ Timeout: 1,
+ },
+ }
+
+ ts := testArtifactsUploadServer(t, authResponse, responseProcessor)
+ defer ts.Close()
+
+ response := testUploadArtifactsFromTestZip(t, ts)
+ require.Equal(t, http.StatusInternalServerError, response.Code)
+ require.Equal(t, 1, putCalledTimes, "upload should be called only once")
+}
+
+func TestUploadHandlerMultipartUploadSizeLimit(t *testing.T) {
+ os, server := test.StartObjectStore()
+ defer server.Close()
+
+ err := os.InitiateMultipartUpload(test.ObjectPath)
+ require.NoError(t, err)
+
+ objectURL := server.URL + test.ObjectPath
+
+ uploadSize := 10
+ preauth := &api.Response{
+ RemoteObject: api.RemoteObject{
+ ID: "store-id",
+ MultipartUpload: &api.MultipartUploadParams{
+ PartSize: 1,
+ PartURLs: []string{objectURL + "?partNumber=1"},
+ AbortURL: objectURL, // DELETE
+ CompleteURL: objectURL, // POST
+ },
+ },
+ }
+
+ responseProcessor := func(w http.ResponseWriter, r *http.Request) {
+ t.Fatal("it should not be called")
+ }
+
+ ts := testArtifactsUploadServer(t, preauth, responseProcessor)
+ defer ts.Close()
+
+ contentBuffer, contentType := createTestMultipartForm(t, make([]byte, uploadSize))
+ response := testUploadArtifacts(t, contentType, ts.URL+Path, &contentBuffer)
+ require.Equal(t, http.StatusRequestEntityTooLarge, response.Code)
+ require.Eventually(t, func() bool {
+ return !os.IsMultipartUpload(test.ObjectPath)
+ }, time.Second, time.Millisecond, "MultipartUpload should not be in progress anymore")
+ require.Empty(t, os.GetObjectMD5(test.ObjectPath), "upload should have failed, so the object should not exists")
+}
+
+func TestUploadHandlerMultipartUploadMaximumSizeFromApi(t *testing.T) {
+ os, server := test.StartObjectStore()
+ defer server.Close()
+
+ err := os.InitiateMultipartUpload(test.ObjectPath)
+ require.NoError(t, err)
+
+ objectURL := server.URL + test.ObjectPath
+
+ uploadSize := int64(10)
+ maxSize := uploadSize - 1
+ preauth := &api.Response{
+ MaximumSize: maxSize,
+ RemoteObject: api.RemoteObject{
+ ID: "store-id",
+ MultipartUpload: &api.MultipartUploadParams{
+ PartSize: uploadSize,
+ PartURLs: []string{objectURL + "?partNumber=1"},
+ AbortURL: objectURL, // DELETE
+ CompleteURL: objectURL, // POST
+ },
+ },
+ }
+
+ responseProcessor := func(w http.ResponseWriter, r *http.Request) {
+ t.Fatal("it should not be called")
+ }
+
+ ts := testArtifactsUploadServer(t, preauth, responseProcessor)
+ defer ts.Close()
+
+ contentBuffer, contentType := createTestMultipartForm(t, make([]byte, uploadSize))
+ response := testUploadArtifacts(t, contentType, ts.URL+Path, &contentBuffer)
+ require.Equal(t, http.StatusRequestEntityTooLarge, response.Code)
+
+ testhelper.Retry(t, 5*time.Second, func() error {
+ if os.GetObjectMD5(test.ObjectPath) == "" {
+ return nil
+ }
+
+ return fmt.Errorf("file is still present")
+ })
+}
diff --git a/workhorse/internal/upload/artifacts_upload_test.go b/workhorse/internal/upload/artifacts_upload_test.go
new file mode 100644
index 00000000000..0a9e4ef3869
--- /dev/null
+++ b/workhorse/internal/upload/artifacts_upload_test.go
@@ -0,0 +1,331 @@
+package upload
+
+import (
+ "archive/zip"
+ "bytes"
+ "compress/gzip"
+ "encoding/json"
+ "fmt"
+ "io"
+ "io/ioutil"
+ "mime/multipart"
+ "net/http"
+ "net/http/httptest"
+ "os"
+ "testing"
+
+ "github.com/golang-jwt/jwt/v4"
+
+ "gitlab.com/gitlab-org/labkit/log"
+
+ "gitlab.com/gitlab-org/gitlab/workhorse/internal/api"
+ "gitlab.com/gitlab-org/gitlab/workhorse/internal/helper"
+ "gitlab.com/gitlab-org/gitlab/workhorse/internal/proxy"
+ "gitlab.com/gitlab-org/gitlab/workhorse/internal/testhelper"
+ "gitlab.com/gitlab-org/gitlab/workhorse/internal/upload/destination"
+ "gitlab.com/gitlab-org/gitlab/workhorse/internal/upstream/roundtripper"
+ "gitlab.com/gitlab-org/gitlab/workhorse/internal/zipartifacts"
+
+ "github.com/stretchr/testify/require"
+)
+
+const (
+ MetadataHeaderKey = "Metadata-Status"
+ MetadataHeaderPresent = "present"
+ MetadataHeaderMissing = "missing"
+ Path = "/url/path"
+)
+
+func TestMain(m *testing.M) {
+ if err := testhelper.BuildExecutables(); err != nil {
+ log.WithError(err).Fatal()
+ }
+
+ os.Exit(m.Run())
+}
+
+func testArtifactsUploadServer(t *testing.T, authResponse *api.Response, bodyProcessor func(w http.ResponseWriter, r *http.Request)) *httptest.Server {
+ mux := http.NewServeMux()
+ mux.HandleFunc(Path+"/authorize", func(w http.ResponseWriter, r *http.Request) {
+ if r.Method != "POST" {
+ t.Fatal("Expected POST request")
+ }
+
+ w.Header().Set("Content-Type", api.ResponseContentType)
+
+ data, err := json.Marshal(&authResponse)
+ if err != nil {
+ t.Fatal("Expected to marshal")
+ }
+ w.Write(data)
+ })
+ mux.HandleFunc(Path, func(w http.ResponseWriter, r *http.Request) {
+ opts, err := destination.GetOpts(authResponse)
+ require.NoError(t, err)
+
+ if r.Method != "POST" {
+ t.Fatal("Expected POST request")
+ }
+ if opts.IsLocal() {
+ if r.FormValue("file.path") == "" {
+ t.Fatal("Expected file to be present")
+ return
+ }
+
+ _, err := ioutil.ReadFile(r.FormValue("file.path"))
+ if err != nil {
+ t.Fatal("Expected file to be readable")
+ return
+ }
+ } else {
+ if r.FormValue("file.remote_url") == "" {
+ t.Fatal("Expected file to be remote accessible")
+ return
+ }
+ }
+
+ if r.FormValue("metadata.path") != "" {
+ metadata, err := ioutil.ReadFile(r.FormValue("metadata.path"))
+ if err != nil {
+ t.Fatal("Expected metadata to be readable")
+ return
+ }
+ gz, err := gzip.NewReader(bytes.NewReader(metadata))
+ if err != nil {
+ t.Fatal("Expected metadata to be valid gzip")
+ return
+ }
+ defer gz.Close()
+ metadata, err = ioutil.ReadAll(gz)
+ if err != nil {
+ t.Fatal("Expected metadata to be valid")
+ return
+ }
+ if !bytes.HasPrefix(metadata, []byte(zipartifacts.MetadataHeaderPrefix+zipartifacts.MetadataHeader)) {
+ t.Fatal("Expected metadata to be of valid format")
+ return
+ }
+
+ w.Header().Set(MetadataHeaderKey, MetadataHeaderPresent)
+
+ } else {
+ w.Header().Set(MetadataHeaderKey, MetadataHeaderMissing)
+ }
+
+ w.WriteHeader(http.StatusOK)
+
+ if bodyProcessor != nil {
+ bodyProcessor(w, r)
+ }
+ })
+ return testhelper.TestServerWithHandler(nil, mux.ServeHTTP)
+}
+
+type testServer struct {
+ url string
+ writer *multipart.Writer
+ buffer *bytes.Buffer
+ fileWriter io.Writer
+ cleanup func()
+}
+
+func setupWithTmpPath(t *testing.T, filename string, includeFormat bool, format string, authResponse *api.Response, bodyProcessor func(w http.ResponseWriter, r *http.Request)) *testServer {
+ tempPath, err := ioutil.TempDir("", "uploads")
+ require.NoError(t, err)
+
+ if authResponse == nil {
+ authResponse = &api.Response{TempPath: tempPath}
+ }
+
+ ts := testArtifactsUploadServer(t, authResponse, bodyProcessor)
+
+ var buffer bytes.Buffer
+ writer := multipart.NewWriter(&buffer)
+ fileWriter, err := writer.CreateFormFile(filename, "my.file")
+ require.NotNil(t, fileWriter)
+ require.NoError(t, err)
+
+ cleanup := func() {
+ ts.Close()
+ require.NoError(t, os.RemoveAll(tempPath))
+ require.NoError(t, writer.Close())
+ }
+
+ qs := ""
+
+ if includeFormat {
+ qs = fmt.Sprintf("?%s=%s", ArtifactFormatKey, format)
+ }
+
+ return &testServer{url: ts.URL + Path + qs, writer: writer, buffer: &buffer, fileWriter: fileWriter, cleanup: cleanup}
+}
+
+func testUploadArtifacts(t *testing.T, contentType, url string, body io.Reader) *httptest.ResponseRecorder {
+ httpRequest, err := http.NewRequest("POST", url, body)
+ require.NoError(t, err)
+
+ httpRequest.Header.Set("Content-Type", contentType)
+ response := httptest.NewRecorder()
+ parsedURL := helper.URLMustParse(url)
+ roundTripper := roundtripper.NewTestBackendRoundTripper(parsedURL)
+ testhelper.ConfigureSecret()
+ apiClient := api.NewAPI(parsedURL, "123", roundTripper)
+ proxyClient := proxy.NewProxy(parsedURL, "123", roundTripper)
+ Artifacts(apiClient, proxyClient, &DefaultPreparer{}).ServeHTTP(response, httpRequest)
+ return response
+}
+
+func TestUploadHandlerAddingMetadata(t *testing.T) {
+ testCases := []struct {
+ desc string
+ format string
+ includeFormat bool
+ }{
+ {
+ desc: "ZIP format",
+ format: ArtifactFormatZip,
+ includeFormat: true,
+ },
+ {
+ desc: "default format",
+ format: ArtifactFormatDefault,
+ includeFormat: true,
+ },
+ {
+ desc: "default format without artifact_format",
+ format: ArtifactFormatDefault,
+ includeFormat: false,
+ },
+ }
+
+ for _, tc := range testCases {
+ t.Run(tc.desc, func(t *testing.T) {
+ s := setupWithTmpPath(t, "file", tc.includeFormat, tc.format, nil,
+ func(w http.ResponseWriter, r *http.Request) {
+ token, err := jwt.ParseWithClaims(r.Header.Get(RewrittenFieldsHeader), &MultipartClaims{}, testhelper.ParseJWT)
+ require.NoError(t, err)
+
+ rewrittenFields := token.Claims.(*MultipartClaims).RewrittenFields
+ require.Equal(t, 2, len(rewrittenFields))
+
+ require.Contains(t, rewrittenFields, "file")
+ require.Contains(t, rewrittenFields, "metadata")
+ require.Contains(t, r.PostForm, "file.gitlab-workhorse-upload")
+ require.Contains(t, r.PostForm, "metadata.gitlab-workhorse-upload")
+ },
+ )
+ defer s.cleanup()
+
+ archive := zip.NewWriter(s.fileWriter)
+ file, err := archive.Create("test.file")
+ require.NotNil(t, file)
+ require.NoError(t, err)
+
+ require.NoError(t, archive.Close())
+ require.NoError(t, s.writer.Close())
+
+ response := testUploadArtifacts(t, s.writer.FormDataContentType(), s.url, s.buffer)
+ require.Equal(t, http.StatusOK, response.Code)
+ testhelper.RequireResponseHeader(t, response, MetadataHeaderKey, MetadataHeaderPresent)
+ })
+ }
+}
+
+func TestUploadHandlerTarArtifact(t *testing.T) {
+ s := setupWithTmpPath(t, "file", true, "tar", nil,
+ func(w http.ResponseWriter, r *http.Request) {
+ token, err := jwt.ParseWithClaims(r.Header.Get(RewrittenFieldsHeader), &MultipartClaims{}, testhelper.ParseJWT)
+ require.NoError(t, err)
+
+ rewrittenFields := token.Claims.(*MultipartClaims).RewrittenFields
+ require.Equal(t, 1, len(rewrittenFields))
+
+ require.Contains(t, rewrittenFields, "file")
+ require.Contains(t, r.PostForm, "file.gitlab-workhorse-upload")
+ },
+ )
+ defer s.cleanup()
+
+ file, err := os.Open("../../testdata/tarfile.tar")
+ require.NoError(t, err)
+
+ _, err = io.Copy(s.fileWriter, file)
+ require.NoError(t, err)
+ require.NoError(t, file.Close())
+ require.NoError(t, s.writer.Close())
+
+ response := testUploadArtifacts(t, s.writer.FormDataContentType(), s.url, s.buffer)
+ require.Equal(t, http.StatusOK, response.Code)
+ testhelper.RequireResponseHeader(t, response, MetadataHeaderKey, MetadataHeaderMissing)
+}
+
+func TestUploadHandlerForUnsupportedArchive(t *testing.T) {
+ s := setupWithTmpPath(t, "file", true, "other", nil, nil)
+ defer s.cleanup()
+ require.NoError(t, s.writer.Close())
+
+ response := testUploadArtifacts(t, s.writer.FormDataContentType(), s.url, s.buffer)
+ require.Equal(t, http.StatusOK, response.Code)
+ testhelper.RequireResponseHeader(t, response, MetadataHeaderKey, MetadataHeaderMissing)
+}
+
+func TestUploadHandlerForMultipleFiles(t *testing.T) {
+ s := setupWithTmpPath(t, "file", true, "", nil, nil)
+ defer s.cleanup()
+
+ file, err := s.writer.CreateFormFile("file", "my.file")
+ require.NotNil(t, file)
+ require.NoError(t, err)
+ require.NoError(t, s.writer.Close())
+
+ response := testUploadArtifacts(t, s.writer.FormDataContentType(), s.url, s.buffer)
+ require.Equal(t, http.StatusInternalServerError, response.Code)
+}
+
+func TestUploadFormProcessing(t *testing.T) {
+ s := setupWithTmpPath(t, "metadata", true, "", nil, nil)
+ defer s.cleanup()
+ require.NoError(t, s.writer.Close())
+
+ response := testUploadArtifacts(t, s.writer.FormDataContentType(), s.url, s.buffer)
+ require.Equal(t, http.StatusInternalServerError, response.Code)
+}
+
+func TestLsifFileProcessing(t *testing.T) {
+ tempPath, err := ioutil.TempDir("", "uploads")
+ require.NoError(t, err)
+
+ s := setupWithTmpPath(t, "file", true, "zip", &api.Response{TempPath: tempPath, ProcessLsif: true}, nil)
+ defer s.cleanup()
+
+ file, err := os.Open("../../testdata/lsif/valid.lsif.zip")
+ require.NoError(t, err)
+
+ _, err = io.Copy(s.fileWriter, file)
+ require.NoError(t, err)
+ require.NoError(t, file.Close())
+ require.NoError(t, s.writer.Close())
+
+ response := testUploadArtifacts(t, s.writer.FormDataContentType(), s.url, s.buffer)
+ require.Equal(t, http.StatusOK, response.Code)
+ testhelper.RequireResponseHeader(t, response, MetadataHeaderKey, MetadataHeaderPresent)
+}
+
+func TestInvalidLsifFileProcessing(t *testing.T) {
+ tempPath, err := ioutil.TempDir("", "uploads")
+ require.NoError(t, err)
+
+ s := setupWithTmpPath(t, "file", true, "zip", &api.Response{TempPath: tempPath, ProcessLsif: true}, nil)
+ defer s.cleanup()
+
+ file, err := os.Open("../../testdata/lsif/invalid.lsif.zip")
+ require.NoError(t, err)
+
+ _, err = io.Copy(s.fileWriter, file)
+ require.NoError(t, err)
+ require.NoError(t, file.Close())
+ require.NoError(t, s.writer.Close())
+
+ response := testUploadArtifacts(t, s.writer.FormDataContentType(), s.url, s.buffer)
+ require.Equal(t, http.StatusInternalServerError, response.Code)
+}
diff --git a/workhorse/internal/upload/artifacts_uploader.go b/workhorse/internal/upload/artifacts_uploader.go
new file mode 100644
index 00000000000..2a91a05fe3d
--- /dev/null
+++ b/workhorse/internal/upload/artifacts_uploader.go
@@ -0,0 +1,167 @@
+package upload
+
+import (
+ "context"
+ "fmt"
+ "io"
+ "mime/multipart"
+ "net/http"
+ "os"
+ "os/exec"
+ "strings"
+ "syscall"
+
+ "github.com/prometheus/client_golang/prometheus"
+ "github.com/prometheus/client_golang/prometheus/promauto"
+ "gitlab.com/gitlab-org/labkit/log"
+
+ "gitlab.com/gitlab-org/gitlab/workhorse/internal/api"
+ "gitlab.com/gitlab-org/gitlab/workhorse/internal/helper"
+ "gitlab.com/gitlab-org/gitlab/workhorse/internal/upload/destination"
+ "gitlab.com/gitlab-org/gitlab/workhorse/internal/zipartifacts"
+)
+
+// Sent by the runner: https://gitlab.com/gitlab-org/gitlab-runner/blob/c24da19ecce8808d9d2950896f70c94f5ea1cc2e/network/gitlab.go#L580
+const (
+ ArtifactFormatKey = "artifact_format"
+ ArtifactFormatZip = "zip"
+ ArtifactFormatDefault = ""
+)
+
+var zipSubcommandsErrorsCounter = promauto.NewCounterVec(
+ prometheus.CounterOpts{
+ Name: "gitlab_workhorse_zip_subcommand_errors_total",
+ Help: "Errors comming from subcommands used for processing ZIP archives",
+ }, []string{"error"})
+
+type artifactsUploadProcessor struct {
+ opts *destination.UploadOpts
+ format string
+
+ SavedFileTracker
+}
+
+// Artifacts is like a Multipart but specific for artifacts upload.
+func Artifacts(myAPI *api.API, h http.Handler, p Preparer) http.Handler {
+ return myAPI.PreAuthorizeHandler(func(w http.ResponseWriter, r *http.Request, a *api.Response) {
+ opts, _, err := p.Prepare(a)
+ if err != nil {
+ helper.Fail500(w, r, fmt.Errorf("UploadArtifacts: error preparing file storage options"))
+ return
+ }
+
+ format := r.URL.Query().Get(ArtifactFormatKey)
+
+ mg := &artifactsUploadProcessor{opts: opts, format: format, SavedFileTracker: SavedFileTracker{Request: r}}
+ interceptMultipartFiles(w, r, h, a, mg, opts)
+ }, "/authorize")
+}
+
+func (a *artifactsUploadProcessor) generateMetadataFromZip(ctx context.Context, file *destination.FileHandler) (*destination.FileHandler, error) {
+ metaReader, metaWriter := io.Pipe()
+ defer metaWriter.Close()
+
+ metaOpts := &destination.UploadOpts{
+ LocalTempPath: a.opts.LocalTempPath,
+ TempFilePrefix: "metadata.gz",
+ }
+ if metaOpts.LocalTempPath == "" {
+ metaOpts.LocalTempPath = os.TempDir()
+ }
+
+ fileName := file.LocalPath
+ if fileName == "" {
+ fileName = file.RemoteURL
+ }
+
+ zipMd := exec.CommandContext(ctx, "gitlab-zip-metadata", fileName)
+ zipMd.Stderr = log.ContextLogger(ctx).Writer()
+ zipMd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
+ zipMd.Stdout = metaWriter
+
+ if err := zipMd.Start(); err != nil {
+ return nil, err
+ }
+ defer helper.CleanUpProcessGroup(zipMd)
+
+ type saveResult struct {
+ error
+ *destination.FileHandler
+ }
+ done := make(chan saveResult)
+ go func() {
+ var result saveResult
+ result.FileHandler, result.error = destination.Upload(ctx, metaReader, -1, metaOpts)
+
+ done <- result
+ }()
+
+ if err := zipMd.Wait(); err != nil {
+ st, ok := helper.ExitStatus(err)
+
+ if !ok {
+ return nil, err
+ }
+
+ zipSubcommandsErrorsCounter.WithLabelValues(zipartifacts.ErrorLabelByCode(st)).Inc()
+
+ if st == zipartifacts.CodeNotZip {
+ return nil, nil
+ }
+
+ if st == zipartifacts.CodeLimitsReached {
+ return nil, zipartifacts.ErrBadMetadata
+ }
+ }
+
+ metaWriter.Close()
+ result := <-done
+ return result.FileHandler, result.error
+}
+
+func (a *artifactsUploadProcessor) ProcessFile(ctx context.Context, formName string, file *destination.FileHandler, writer *multipart.Writer) error {
+ // ProcessFile for artifacts requires file form-data field name to eq `file`
+
+ if formName != "file" {
+ return fmt.Errorf("invalid form field: %q", formName)
+ }
+ if a.Count() > 0 {
+ return fmt.Errorf("artifacts request contains more than one file")
+ }
+ a.Track(formName, file.LocalPath)
+
+ select {
+ case <-ctx.Done():
+ return fmt.Errorf("ProcessFile: context done")
+ default:
+ }
+
+ if !strings.EqualFold(a.format, ArtifactFormatZip) && a.format != ArtifactFormatDefault {
+ return nil
+ }
+
+ // TODO: can we rely on disk for shipping metadata? Not if we split workhorse and rails in 2 different PODs
+ metadata, err := a.generateMetadataFromZip(ctx, file)
+ if err != nil {
+ return err
+ }
+
+ if metadata != nil {
+ fields, err := metadata.GitLabFinalizeFields("metadata")
+ if err != nil {
+ return fmt.Errorf("finalize metadata field error: %v", err)
+ }
+
+ for k, v := range fields {
+ writer.WriteField(k, v)
+ }
+
+ a.Track("metadata", metadata.LocalPath)
+ }
+
+ return nil
+}
+
+func (a *artifactsUploadProcessor) Name() string {
+ return "artifacts"
+}
diff --git a/workhorse/internal/upload/body_uploader.go b/workhorse/internal/upload/body_uploader.go
index 6c53bd9241b..d831f9f43a1 100644
--- a/workhorse/internal/upload/body_uploader.go
+++ b/workhorse/internal/upload/body_uploader.go
@@ -8,41 +8,10 @@ import (
"strings"
"gitlab.com/gitlab-org/gitlab/workhorse/internal/api"
- "gitlab.com/gitlab-org/gitlab/workhorse/internal/filestore"
"gitlab.com/gitlab-org/gitlab/workhorse/internal/helper"
+ "gitlab.com/gitlab-org/gitlab/workhorse/internal/upload/destination"
)
-type PreAuthorizer interface {
- PreAuthorizeHandler(next api.HandleFunc, suffix string) http.Handler
-}
-
-// Verifier is an optional pluggable behavior for upload paths. If
-// Verify() returns an error, Workhorse will return an error response to
-// the client instead of propagating the request to Rails. The motivating
-// use case is Git LFS, where Workhorse checks the size and SHA256
-// checksum of the uploaded file.
-type Verifier interface {
- // Verify can abort the upload by returning an error
- Verify(handler *filestore.FileHandler) error
-}
-
-// Preparer is a pluggable behavior that interprets a Rails API response
-// and either tells Workhorse how to handle the upload, via the
-// SaveFileOpts and Verifier, or it rejects the request by returning a
-// non-nil error. Its intended use is to make sure the upload gets stored
-// in the right location: either a local directory, or one of several
-// supported object storage backends.
-type Preparer interface {
- Prepare(a *api.Response) (*filestore.SaveFileOpts, Verifier, error)
-}
-
-type DefaultPreparer struct{}
-
-func (s *DefaultPreparer) Prepare(a *api.Response) (*filestore.SaveFileOpts, Verifier, error) {
- opts, err := filestore.GetOpts(a)
- return opts, nil, err
-}
-
// RequestBody is a request middleware. It will store the request body to
// a location by determined an api.Response value. It then forwards the
// request to gitlab-rails without the original request body.
@@ -54,7 +23,7 @@ func RequestBody(rails PreAuthorizer, h http.Handler, p Preparer) http.Handler {
return
}
- fh, err := filestore.SaveFileFromReader(r.Context(), r.Body, r.ContentLength, opts)
+ fh, err := destination.Upload(r.Context(), r.Body, r.ContentLength, opts)
if err != nil {
helper.Fail500(w, r, fmt.Errorf("RequestBody: upload failed: %v", err))
return
diff --git a/workhorse/internal/upload/body_uploader_test.go b/workhorse/internal/upload/body_uploader_test.go
index b3d561ac131..47490db8780 100644
--- a/workhorse/internal/upload/body_uploader_test.go
+++ b/workhorse/internal/upload/body_uploader_test.go
@@ -15,8 +15,8 @@ import (
"github.com/stretchr/testify/require"
"gitlab.com/gitlab-org/gitlab/workhorse/internal/api"
- "gitlab.com/gitlab-org/gitlab/workhorse/internal/filestore"
"gitlab.com/gitlab-org/gitlab/workhorse/internal/testhelper"
+ "gitlab.com/gitlab-org/gitlab/workhorse/internal/upload/destination"
)
const (
@@ -169,8 +169,8 @@ type alwaysLocalPreparer struct {
prepareError error
}
-func (a *alwaysLocalPreparer) Prepare(_ *api.Response) (*filestore.SaveFileOpts, Verifier, error) {
- opts, err := filestore.GetOpts(&api.Response{TempPath: os.TempDir()})
+func (a *alwaysLocalPreparer) Prepare(_ *api.Response) (*destination.UploadOpts, Verifier, error) {
+ opts, err := destination.GetOpts(&api.Response{TempPath: os.TempDir()})
if err != nil {
return nil, nil, err
}
@@ -180,7 +180,7 @@ func (a *alwaysLocalPreparer) Prepare(_ *api.Response) (*filestore.SaveFileOpts,
type alwaysFailsVerifier struct{}
-func (alwaysFailsVerifier) Verify(handler *filestore.FileHandler) error {
+func (alwaysFailsVerifier) Verify(handler *destination.FileHandler) error {
return fmt.Errorf("Verification failed")
}
@@ -188,7 +188,7 @@ type mockVerifier struct {
invoked bool
}
-func (m *mockVerifier) Verify(handler *filestore.FileHandler) error {
+func (m *mockVerifier) Verify(handler *destination.FileHandler) error {
m.invoked = true
return nil
diff --git a/workhorse/internal/upload/destination/destination.go b/workhorse/internal/upload/destination/destination.go
new file mode 100644
index 00000000000..7a030e59a64
--- /dev/null
+++ b/workhorse/internal/upload/destination/destination.go
@@ -0,0 +1,236 @@
+// The destination package handles uploading to a specific destination (delegates
+// to filestore or objectstore packages) based on options from the pre-authorization
+// API and finalizing the upload.
+package destination
+
+import (
+ "context"
+ "errors"
+ "fmt"
+ "io"
+ "io/ioutil"
+ "os"
+ "strconv"
+ "time"
+
+ "github.com/golang-jwt/jwt/v4"
+
+ "gitlab.com/gitlab-org/labkit/log"
+
+ "gitlab.com/gitlab-org/gitlab/workhorse/internal/secret"
+ "gitlab.com/gitlab-org/gitlab/workhorse/internal/upload/destination/filestore"
+ "gitlab.com/gitlab-org/gitlab/workhorse/internal/upload/destination/objectstore"
+)
+
+type SizeError error
+
+// ErrEntityTooLarge means that the uploaded content is bigger then maximum allowed size
+var ErrEntityTooLarge = errors.New("entity is too large")
+
+// FileHandler represent a file that has been processed for upload
+// it may be either uploaded to an ObjectStore and/or saved on local path.
+type FileHandler struct {
+ // LocalPath is the path on the disk where file has been stored
+ LocalPath string
+
+ // RemoteID is the objectID provided by GitLab Rails
+ RemoteID string
+ // RemoteURL is ObjectStore URL provided by GitLab Rails
+ RemoteURL string
+
+ // Size is the persisted file size
+ Size int64
+
+ // Name is the resource name to send back to GitLab rails.
+ // It differ from the real file name in order to avoid file collisions
+ Name string
+
+ // a map containing different hashes
+ hashes map[string]string
+
+ // Duration of upload in seconds
+ uploadDuration float64
+}
+
+type uploadClaims struct {
+ Upload map[string]string `json:"upload"`
+ jwt.StandardClaims
+}
+
+// SHA256 hash of the handled file
+func (fh *FileHandler) SHA256() string {
+ return fh.hashes["sha256"]
+}
+
+// MD5 hash of the handled file
+func (fh *FileHandler) MD5() string {
+ return fh.hashes["md5"]
+}
+
+// GitLabFinalizeFields returns a map with all the fields GitLab Rails needs in order to finalize the upload.
+func (fh *FileHandler) GitLabFinalizeFields(prefix string) (map[string]string, error) {
+ // TODO: remove `data` these once rails fully and exclusively support `signedData` (https://gitlab.com/gitlab-org/gitlab/-/issues/324873)
+ data := make(map[string]string)
+ signedData := make(map[string]string)
+ key := func(field string) string {
+ if prefix == "" {
+ return field
+ }
+
+ return fmt.Sprintf("%s.%s", prefix, field)
+ }
+
+ for k, v := range map[string]string{
+ "name": fh.Name,
+ "path": fh.LocalPath,
+ "remote_url": fh.RemoteURL,
+ "remote_id": fh.RemoteID,
+ "size": strconv.FormatInt(fh.Size, 10),
+ "upload_duration": strconv.FormatFloat(fh.uploadDuration, 'f', -1, 64),
+ } {
+ data[key(k)] = v
+ signedData[k] = v
+ }
+
+ for hashName, hash := range fh.hashes {
+ data[key(hashName)] = hash
+ signedData[hashName] = hash
+ }
+
+ claims := uploadClaims{Upload: signedData, StandardClaims: secret.DefaultClaims}
+ jwtData, err := secret.JWTTokenString(claims)
+ if err != nil {
+ return nil, err
+ }
+ data[key("gitlab-workhorse-upload")] = jwtData
+
+ return data, nil
+}
+
+type consumer interface {
+ Consume(context.Context, io.Reader, time.Time) (int64, error)
+}
+
+// Upload persists the provided reader content to all the location specified in opts. A cleanup will be performed once ctx is Done
+// Make sure the provided context will not expire before finalizing upload with GitLab Rails.
+func Upload(ctx context.Context, reader io.Reader, size int64, opts *UploadOpts) (*FileHandler, error) {
+ fh := &FileHandler{
+ Name: opts.TempFilePrefix,
+ RemoteID: opts.RemoteID,
+ RemoteURL: opts.RemoteURL,
+ }
+ uploadStartTime := time.Now()
+ defer func() { fh.uploadDuration = time.Since(uploadStartTime).Seconds() }()
+ hashes := newMultiHash()
+ reader = io.TeeReader(reader, hashes.Writer)
+
+ var clientMode string
+ var uploadDestination consumer
+ var err error
+ switch {
+ case opts.IsLocal():
+ clientMode = "local"
+ uploadDestination, err = fh.newLocalFile(ctx, opts)
+ case opts.UseWorkhorseClientEnabled() && opts.ObjectStorageConfig.IsGoCloud():
+ clientMode = fmt.Sprintf("go_cloud:%s", opts.ObjectStorageConfig.Provider)
+ p := &objectstore.GoCloudObjectParams{
+ Ctx: ctx,
+ Mux: opts.ObjectStorageConfig.URLMux,
+ BucketURL: opts.ObjectStorageConfig.GoCloudConfig.URL,
+ ObjectName: opts.RemoteTempObjectID,
+ }
+ uploadDestination, err = objectstore.NewGoCloudObject(p)
+ case opts.UseWorkhorseClientEnabled() && opts.ObjectStorageConfig.IsAWS() && opts.ObjectStorageConfig.IsValid():
+ clientMode = "s3"
+ uploadDestination, err = objectstore.NewS3Object(
+ opts.RemoteTempObjectID,
+ opts.ObjectStorageConfig.S3Credentials,
+ opts.ObjectStorageConfig.S3Config,
+ )
+ case opts.IsMultipart():
+ clientMode = "multipart"
+ uploadDestination, err = objectstore.NewMultipart(
+ opts.PresignedParts,
+ opts.PresignedCompleteMultipart,
+ opts.PresignedAbortMultipart,
+ opts.PresignedDelete,
+ opts.PutHeaders,
+ opts.PartSize,
+ )
+ default:
+ clientMode = "http"
+ uploadDestination, err = objectstore.NewObject(
+ opts.PresignedPut,
+ opts.PresignedDelete,
+ opts.PutHeaders,
+ size,
+ )
+ }
+
+ if err != nil {
+ return nil, err
+ }
+
+ var hlr *hardLimitReader
+ if opts.MaximumSize > 0 {
+ if size > opts.MaximumSize {
+ return nil, SizeError(fmt.Errorf("the upload size %d is over maximum of %d bytes", size, opts.MaximumSize))
+ }
+
+ hlr = &hardLimitReader{r: reader, n: opts.MaximumSize}
+ reader = hlr
+ }
+
+ fh.Size, err = uploadDestination.Consume(ctx, reader, opts.Deadline)
+ if err != nil {
+ if (err == objectstore.ErrNotEnoughParts) || (hlr != nil && hlr.n < 0) {
+ err = ErrEntityTooLarge
+ }
+ return nil, err
+ }
+
+ if size != -1 && size != fh.Size {
+ return nil, SizeError(fmt.Errorf("expected %d bytes but got only %d", size, fh.Size))
+ }
+
+ logger := log.WithContextFields(ctx, log.Fields{
+ "copied_bytes": fh.Size,
+ "is_local": opts.IsLocal(),
+ "is_multipart": opts.IsMultipart(),
+ "is_remote": !opts.IsLocal(),
+ "remote_id": opts.RemoteID,
+ "temp_file_prefix": opts.TempFilePrefix,
+ "client_mode": clientMode,
+ })
+
+ if opts.IsLocal() {
+ logger = logger.WithField("local_temp_path", opts.LocalTempPath)
+ } else {
+ logger = logger.WithField("remote_temp_object", opts.RemoteTempObjectID)
+ }
+
+ logger.Info("saved file")
+ fh.hashes = hashes.finish()
+ return fh, nil
+}
+
+func (fh *FileHandler) newLocalFile(ctx context.Context, opts *UploadOpts) (consumer, error) {
+ // make sure TempFolder exists
+ err := os.MkdirAll(opts.LocalTempPath, 0700)
+ if err != nil {
+ return nil, fmt.Errorf("newLocalFile: mkdir %q: %v", opts.LocalTempPath, err)
+ }
+
+ file, err := ioutil.TempFile(opts.LocalTempPath, opts.TempFilePrefix)
+ if err != nil {
+ return nil, fmt.Errorf("newLocalFile: create file: %v", err)
+ }
+
+ go func() {
+ <-ctx.Done()
+ os.Remove(file.Name())
+ }()
+
+ fh.LocalPath = file.Name()
+ return &filestore.LocalFile{File: file}, nil
+}
diff --git a/workhorse/internal/upload/destination/destination_test.go b/workhorse/internal/upload/destination/destination_test.go
new file mode 100644
index 00000000000..ddf0ea24d60
--- /dev/null
+++ b/workhorse/internal/upload/destination/destination_test.go
@@ -0,0 +1,504 @@
+package destination_test
+
+import (
+ "context"
+ "errors"
+ "fmt"
+ "io/ioutil"
+ "os"
+ "path"
+ "strconv"
+ "strings"
+ "testing"
+ "time"
+
+ "github.com/golang-jwt/jwt/v4"
+ "github.com/stretchr/testify/require"
+ "gocloud.dev/blob"
+
+ "gitlab.com/gitlab-org/gitlab/workhorse/internal/config"
+ "gitlab.com/gitlab-org/gitlab/workhorse/internal/testhelper"
+ "gitlab.com/gitlab-org/gitlab/workhorse/internal/upload/destination"
+ "gitlab.com/gitlab-org/gitlab/workhorse/internal/upload/destination/objectstore/test"
+)
+
+func testDeadline() time.Time {
+ return time.Now().Add(destination.DefaultObjectStoreTimeout)
+}
+
+func requireFileGetsRemovedAsync(t *testing.T, filePath string) {
+ var err error
+ require.Eventually(t, func() bool {
+ _, err = os.Stat(filePath)
+ return err != nil
+ }, 10*time.Second, 10*time.Millisecond)
+ require.True(t, os.IsNotExist(err), "File hasn't been deleted during cleanup")
+}
+
+func requireObjectStoreDeletedAsync(t *testing.T, expectedDeletes int, osStub *test.ObjectstoreStub) {
+ require.Eventually(t, func() bool { return osStub.DeletesCnt() == expectedDeletes }, time.Second, time.Millisecond, "Object not deleted")
+}
+
+func TestUploadWrongSize(t *testing.T) {
+ ctx, cancel := context.WithCancel(context.Background())
+ defer cancel()
+
+ tmpFolder, err := ioutil.TempDir("", "workhorse-test-tmp")
+ require.NoError(t, err)
+ defer os.RemoveAll(tmpFolder)
+
+ opts := &destination.UploadOpts{LocalTempPath: tmpFolder, TempFilePrefix: "test-file"}
+ fh, err := destination.Upload(ctx, strings.NewReader(test.ObjectContent), test.ObjectSize+1, opts)
+ require.Error(t, err)
+ _, isSizeError := err.(destination.SizeError)
+ require.True(t, isSizeError, "Should fail with SizeError")
+ require.Nil(t, fh)
+}
+
+func TestUploadWithKnownSizeExceedLimit(t *testing.T) {
+ ctx, cancel := context.WithCancel(context.Background())
+ defer cancel()
+
+ tmpFolder, err := ioutil.TempDir("", "workhorse-test-tmp")
+ require.NoError(t, err)
+ defer os.RemoveAll(tmpFolder)
+
+ opts := &destination.UploadOpts{LocalTempPath: tmpFolder, TempFilePrefix: "test-file", MaximumSize: test.ObjectSize - 1}
+ fh, err := destination.Upload(ctx, strings.NewReader(test.ObjectContent), test.ObjectSize, opts)
+ require.Error(t, err)
+ _, isSizeError := err.(destination.SizeError)
+ require.True(t, isSizeError, "Should fail with SizeError")
+ require.Nil(t, fh)
+}
+
+func TestUploadWithUnknownSizeExceedLimit(t *testing.T) {
+ ctx, cancel := context.WithCancel(context.Background())
+ defer cancel()
+
+ tmpFolder, err := ioutil.TempDir("", "workhorse-test-tmp")
+ require.NoError(t, err)
+ defer os.RemoveAll(tmpFolder)
+
+ opts := &destination.UploadOpts{LocalTempPath: tmpFolder, TempFilePrefix: "test-file", MaximumSize: test.ObjectSize - 1}
+ fh, err := destination.Upload(ctx, strings.NewReader(test.ObjectContent), -1, opts)
+ require.Equal(t, err, destination.ErrEntityTooLarge)
+ require.Nil(t, fh)
+}
+
+func TestUploadWrongETag(t *testing.T) {
+ tests := []struct {
+ name string
+ multipart bool
+ }{
+ {name: "single part"},
+ {name: "multi part", multipart: true},
+ }
+
+ for _, spec := range tests {
+ t.Run(spec.name, func(t *testing.T) {
+ osStub, ts := test.StartObjectStoreWithCustomMD5(map[string]string{test.ObjectPath: "brokenMD5"})
+ defer ts.Close()
+
+ objectURL := ts.URL + test.ObjectPath
+
+ opts := &destination.UploadOpts{
+ RemoteID: "test-file",
+ RemoteURL: objectURL,
+ PresignedPut: objectURL + "?Signature=ASignature",
+ PresignedDelete: objectURL + "?Signature=AnotherSignature",
+ Deadline: testDeadline(),
+ }
+ if spec.multipart {
+ opts.PresignedParts = []string{objectURL + "?partNumber=1"}
+ opts.PresignedCompleteMultipart = objectURL + "?Signature=CompleteSig"
+ opts.PresignedAbortMultipart = objectURL + "?Signature=AbortSig"
+ opts.PartSize = test.ObjectSize
+
+ osStub.InitiateMultipartUpload(test.ObjectPath)
+ }
+ ctx, cancel := context.WithCancel(context.Background())
+ fh, err := destination.Upload(ctx, strings.NewReader(test.ObjectContent), test.ObjectSize, opts)
+ require.Nil(t, fh)
+ require.Error(t, err)
+ require.Equal(t, 1, osStub.PutsCnt(), "File not uploaded")
+
+ cancel() // this will trigger an async cleanup
+ requireObjectStoreDeletedAsync(t, 1, osStub)
+ require.False(t, spec.multipart && osStub.IsMultipartUpload(test.ObjectPath), "there must be no multipart upload in progress now")
+ })
+ }
+}
+
+func TestUpload(t *testing.T) {
+ testhelper.ConfigureSecret()
+
+ type remote int
+ const (
+ notRemote remote = iota
+ remoteSingle
+ remoteMultipart
+ )
+
+ tmpFolder, err := ioutil.TempDir("", "workhorse-test-tmp")
+ require.NoError(t, err)
+ defer os.RemoveAll(tmpFolder)
+
+ tests := []struct {
+ name string
+ local bool
+ remote remote
+ }{
+ {name: "Local only", local: true},
+ {name: "Remote Single only", remote: remoteSingle},
+ {name: "Remote Multipart only", remote: remoteMultipart},
+ }
+
+ for _, spec := range tests {
+ t.Run(spec.name, func(t *testing.T) {
+ var opts destination.UploadOpts
+ var expectedDeletes, expectedPuts int
+
+ osStub, ts := test.StartObjectStore()
+ defer ts.Close()
+
+ switch spec.remote {
+ case remoteSingle:
+ objectURL := ts.URL + test.ObjectPath
+
+ opts.RemoteID = "test-file"
+ opts.RemoteURL = objectURL
+ opts.PresignedPut = objectURL + "?Signature=ASignature"
+ opts.PresignedDelete = objectURL + "?Signature=AnotherSignature"
+ opts.Deadline = testDeadline()
+
+ expectedDeletes = 1
+ expectedPuts = 1
+ case remoteMultipart:
+ objectURL := ts.URL + test.ObjectPath
+
+ opts.RemoteID = "test-file"
+ opts.RemoteURL = objectURL
+ opts.PresignedDelete = objectURL + "?Signature=AnotherSignature"
+ opts.PartSize = int64(len(test.ObjectContent)/2) + 1
+ opts.PresignedParts = []string{objectURL + "?partNumber=1", objectURL + "?partNumber=2"}
+ opts.PresignedCompleteMultipart = objectURL + "?Signature=CompleteSignature"
+ opts.Deadline = testDeadline()
+
+ osStub.InitiateMultipartUpload(test.ObjectPath)
+ expectedDeletes = 1
+ expectedPuts = 2
+ }
+
+ if spec.local {
+ opts.LocalTempPath = tmpFolder
+ opts.TempFilePrefix = "test-file"
+ }
+
+ ctx, cancel := context.WithCancel(context.Background())
+ defer cancel()
+
+ fh, err := destination.Upload(ctx, strings.NewReader(test.ObjectContent), test.ObjectSize, &opts)
+ require.NoError(t, err)
+ require.NotNil(t, fh)
+
+ require.Equal(t, opts.RemoteID, fh.RemoteID)
+ require.Equal(t, opts.RemoteURL, fh.RemoteURL)
+
+ if spec.local {
+ require.NotEmpty(t, fh.LocalPath, "File not persisted on disk")
+ _, err := os.Stat(fh.LocalPath)
+ require.NoError(t, err)
+
+ dir := path.Dir(fh.LocalPath)
+ require.Equal(t, opts.LocalTempPath, dir)
+ filename := path.Base(fh.LocalPath)
+ beginsWithPrefix := strings.HasPrefix(filename, opts.TempFilePrefix)
+ require.True(t, beginsWithPrefix, fmt.Sprintf("LocalPath filename %q do not begin with TempFilePrefix %q", filename, opts.TempFilePrefix))
+ } else {
+ require.Empty(t, fh.LocalPath, "LocalPath must be empty for non local uploads")
+ }
+
+ require.Equal(t, test.ObjectSize, fh.Size)
+ require.Equal(t, test.ObjectMD5, fh.MD5())
+ require.Equal(t, test.ObjectSHA256, fh.SHA256())
+
+ require.Equal(t, expectedPuts, osStub.PutsCnt(), "ObjectStore PutObject count mismatch")
+ require.Equal(t, 0, osStub.DeletesCnt(), "File deleted too early")
+
+ cancel() // this will trigger an async cleanup
+ requireObjectStoreDeletedAsync(t, expectedDeletes, osStub)
+ requireFileGetsRemovedAsync(t, fh.LocalPath)
+
+ // checking generated fields
+ fields, err := fh.GitLabFinalizeFields("file")
+ require.NoError(t, err)
+
+ checkFileHandlerWithFields(t, fh, fields, "file")
+
+ token, jwtErr := jwt.ParseWithClaims(fields["file.gitlab-workhorse-upload"], &testhelper.UploadClaims{}, testhelper.ParseJWT)
+ require.NoError(t, jwtErr)
+
+ uploadFields := token.Claims.(*testhelper.UploadClaims).Upload
+
+ checkFileHandlerWithFields(t, fh, uploadFields, "")
+ })
+ }
+}
+
+func TestUploadWithS3WorkhorseClient(t *testing.T) {
+ tests := []struct {
+ name string
+ objectSize int64
+ maxSize int64
+ expectedErr error
+ }{
+ {
+ name: "known size with no limit",
+ objectSize: test.ObjectSize,
+ },
+ {
+ name: "unknown size with no limit",
+ objectSize: -1,
+ },
+ {
+ name: "unknown object size with limit",
+ objectSize: -1,
+ maxSize: test.ObjectSize - 1,
+ expectedErr: destination.ErrEntityTooLarge,
+ },
+ }
+
+ for _, tc := range tests {
+ t.Run(tc.name, func(t *testing.T) {
+
+ s3Creds, s3Config, sess, ts := test.SetupS3(t, "")
+ defer ts.Close()
+
+ ctx, cancel := context.WithCancel(context.Background())
+ defer cancel()
+
+ remoteObject := "tmp/test-file/1"
+ opts := destination.UploadOpts{
+ RemoteID: "test-file",
+ Deadline: testDeadline(),
+ UseWorkhorseClient: true,
+ RemoteTempObjectID: remoteObject,
+ ObjectStorageConfig: destination.ObjectStorageConfig{
+ Provider: "AWS",
+ S3Credentials: s3Creds,
+ S3Config: s3Config,
+ },
+ MaximumSize: tc.maxSize,
+ }
+
+ _, err := destination.Upload(ctx, strings.NewReader(test.ObjectContent), tc.objectSize, &opts)
+
+ if tc.expectedErr == nil {
+ require.NoError(t, err)
+ test.S3ObjectExists(t, sess, s3Config, remoteObject, test.ObjectContent)
+ } else {
+ require.Equal(t, tc.expectedErr, err)
+ test.S3ObjectDoesNotExist(t, sess, s3Config, remoteObject)
+ }
+ })
+ }
+}
+
+func TestUploadWithAzureWorkhorseClient(t *testing.T) {
+ mux, bucketDir, cleanup := test.SetupGoCloudFileBucket(t, "azblob")
+ defer cleanup()
+
+ ctx, cancel := context.WithCancel(context.Background())
+ defer cancel()
+
+ remoteObject := "tmp/test-file/1"
+ opts := destination.UploadOpts{
+ RemoteID: "test-file",
+ Deadline: testDeadline(),
+ UseWorkhorseClient: true,
+ RemoteTempObjectID: remoteObject,
+ ObjectStorageConfig: destination.ObjectStorageConfig{
+ Provider: "AzureRM",
+ URLMux: mux,
+ GoCloudConfig: config.GoCloudConfig{URL: "azblob://test-container"},
+ },
+ }
+
+ _, err := destination.Upload(ctx, strings.NewReader(test.ObjectContent), test.ObjectSize, &opts)
+ require.NoError(t, err)
+
+ test.GoCloudObjectExists(t, bucketDir, remoteObject)
+}
+
+func TestUploadWithUnknownGoCloudScheme(t *testing.T) {
+ ctx, cancel := context.WithCancel(context.Background())
+ defer cancel()
+
+ mux := new(blob.URLMux)
+
+ remoteObject := "tmp/test-file/1"
+ opts := destination.UploadOpts{
+ RemoteID: "test-file",
+ Deadline: testDeadline(),
+ UseWorkhorseClient: true,
+ RemoteTempObjectID: remoteObject,
+ ObjectStorageConfig: destination.ObjectStorageConfig{
+ Provider: "SomeCloud",
+ URLMux: mux,
+ GoCloudConfig: config.GoCloudConfig{URL: "foo://test-container"},
+ },
+ }
+
+ _, err := destination.Upload(ctx, strings.NewReader(test.ObjectContent), test.ObjectSize, &opts)
+ require.Error(t, err)
+}
+
+func TestUploadMultipartInBodyFailure(t *testing.T) {
+ osStub, ts := test.StartObjectStore()
+ defer ts.Close()
+
+ // this is a broken path because it contains bucket name but no key
+ // this is the only way to get an in-body failure from our ObjectStoreStub
+ objectPath := "/bucket-but-no-object-key"
+ objectURL := ts.URL + objectPath
+ opts := destination.UploadOpts{
+ RemoteID: "test-file",
+ RemoteURL: objectURL,
+ PartSize: test.ObjectSize,
+ PresignedParts: []string{objectURL + "?partNumber=1", objectURL + "?partNumber=2"},
+ PresignedCompleteMultipart: objectURL + "?Signature=CompleteSignature",
+ Deadline: testDeadline(),
+ }
+
+ osStub.InitiateMultipartUpload(objectPath)
+
+ ctx, cancel := context.WithCancel(context.Background())
+ defer cancel()
+
+ fh, err := destination.Upload(ctx, strings.NewReader(test.ObjectContent), test.ObjectSize, &opts)
+ require.Nil(t, fh)
+ require.Error(t, err)
+ require.EqualError(t, err, test.MultipartUploadInternalError().Error())
+}
+
+func TestUploadRemoteFileWithLimit(t *testing.T) {
+ testhelper.ConfigureSecret()
+
+ type remote int
+ const (
+ notRemote remote = iota
+ remoteSingle
+ remoteMultipart
+ )
+
+ remoteTypes := []remote{remoteSingle, remoteMultipart}
+
+ tests := []struct {
+ name string
+ objectSize int64
+ maxSize int64
+ expectedErr error
+ testData string
+ }{
+ {
+ name: "known size with no limit",
+ testData: test.ObjectContent,
+ objectSize: test.ObjectSize,
+ },
+ {
+ name: "unknown size with no limit",
+ testData: test.ObjectContent,
+ objectSize: -1,
+ },
+ {
+ name: "unknown object size with limit",
+ testData: test.ObjectContent,
+ objectSize: -1,
+ maxSize: test.ObjectSize - 1,
+ expectedErr: destination.ErrEntityTooLarge,
+ },
+ {
+ name: "large object with unknown size with limit",
+ testData: string(make([]byte, 20000)),
+ objectSize: -1,
+ maxSize: 19000,
+ expectedErr: destination.ErrEntityTooLarge,
+ },
+ }
+
+ for _, tc := range tests {
+ t.Run(tc.name, func(t *testing.T) {
+ var opts destination.UploadOpts
+
+ for _, remoteType := range remoteTypes {
+ tmpFolder, err := ioutil.TempDir("", "workhorse-test-tmp")
+ require.NoError(t, err)
+ defer os.RemoveAll(tmpFolder)
+
+ osStub, ts := test.StartObjectStore()
+ defer ts.Close()
+
+ switch remoteType {
+ case remoteSingle:
+ objectURL := ts.URL + test.ObjectPath
+
+ opts.RemoteID = "test-file"
+ opts.RemoteURL = objectURL
+ opts.PresignedPut = objectURL + "?Signature=ASignature"
+ opts.PresignedDelete = objectURL + "?Signature=AnotherSignature"
+ opts.Deadline = testDeadline()
+ opts.MaximumSize = tc.maxSize
+ case remoteMultipart:
+ objectURL := ts.URL + test.ObjectPath
+
+ opts.RemoteID = "test-file"
+ opts.RemoteURL = objectURL
+ opts.PresignedDelete = objectURL + "?Signature=AnotherSignature"
+ opts.PartSize = int64(len(tc.testData)/2) + 1
+ opts.PresignedParts = []string{objectURL + "?partNumber=1", objectURL + "?partNumber=2"}
+ opts.PresignedCompleteMultipart = objectURL + "?Signature=CompleteSignature"
+ opts.Deadline = testDeadline()
+ opts.MaximumSize = tc.maxSize
+
+ require.Less(t, int64(len(tc.testData)), int64(len(opts.PresignedParts))*opts.PartSize, "check part size calculation")
+
+ osStub.InitiateMultipartUpload(test.ObjectPath)
+ }
+
+ ctx, cancel := context.WithCancel(context.Background())
+ defer cancel()
+
+ fh, err := destination.Upload(ctx, strings.NewReader(tc.testData), tc.objectSize, &opts)
+
+ if tc.expectedErr == nil {
+ require.NoError(t, err)
+ require.NotNil(t, fh)
+ } else {
+ require.True(t, errors.Is(err, tc.expectedErr))
+ require.Nil(t, fh)
+ }
+ }
+ })
+ }
+}
+
+func checkFileHandlerWithFields(t *testing.T, fh *destination.FileHandler, fields map[string]string, prefix string) {
+ key := func(field string) string {
+ if prefix == "" {
+ return field
+ }
+
+ return fmt.Sprintf("%s.%s", prefix, field)
+ }
+
+ require.Equal(t, fh.Name, fields[key("name")])
+ require.Equal(t, fh.LocalPath, fields[key("path")])
+ require.Equal(t, fh.RemoteURL, fields[key("remote_url")])
+ require.Equal(t, fh.RemoteID, fields[key("remote_id")])
+ require.Equal(t, strconv.FormatInt(test.ObjectSize, 10), fields[key("size")])
+ require.Equal(t, test.ObjectMD5, fields[key("md5")])
+ require.Equal(t, test.ObjectSHA1, fields[key("sha1")])
+ require.Equal(t, test.ObjectSHA256, fields[key("sha256")])
+ require.Equal(t, test.ObjectSHA512, fields[key("sha512")])
+ require.NotEmpty(t, fields[key("upload_duration")])
+}
diff --git a/workhorse/internal/upload/destination/filestore/filestore.go b/workhorse/internal/upload/destination/filestore/filestore.go
new file mode 100644
index 00000000000..2d88874bf25
--- /dev/null
+++ b/workhorse/internal/upload/destination/filestore/filestore.go
@@ -0,0 +1,21 @@
+// The filestore package has a consumer specific to uploading to local disk storage.
+package filestore
+
+import (
+ "context"
+ "io"
+ "time"
+)
+
+type LocalFile struct {
+ File io.WriteCloser
+}
+
+func (lf *LocalFile) Consume(_ context.Context, r io.Reader, _ time.Time) (int64, error) {
+ n, err := io.Copy(lf.File, r)
+ errClose := lf.File.Close()
+ if err == nil {
+ err = errClose
+ }
+ return n, err
+}
diff --git a/workhorse/internal/upload/destination/filestore/filestore_test.go b/workhorse/internal/upload/destination/filestore/filestore_test.go
new file mode 100644
index 00000000000..ec67eae96b9
--- /dev/null
+++ b/workhorse/internal/upload/destination/filestore/filestore_test.go
@@ -0,0 +1,38 @@
+package filestore
+
+import (
+ "context"
+ "io/ioutil"
+ "os"
+ "strings"
+ "testing"
+ "time"
+
+ "github.com/stretchr/testify/require"
+)
+
+func TestConsume(t *testing.T) {
+ f, err := ioutil.TempFile("", "filestore-local-file")
+ if f != nil {
+ defer os.Remove(f.Name())
+ }
+ require.NoError(t, err)
+ defer f.Close()
+
+ localFile := &LocalFile{File: f}
+
+ ctx, cancel := context.WithCancel(context.Background())
+ defer cancel()
+
+ content := "file content"
+ reader := strings.NewReader(content)
+ var deadline time.Time
+
+ n, err := localFile.Consume(ctx, reader, deadline)
+ require.NoError(t, err)
+ require.Equal(t, int64(len(content)), n)
+
+ consumedContent, err := ioutil.ReadFile(f.Name())
+ require.NoError(t, err)
+ require.Equal(t, content, string(consumedContent))
+}
diff --git a/workhorse/internal/upload/destination/multi_hash.go b/workhorse/internal/upload/destination/multi_hash.go
new file mode 100644
index 00000000000..7d4884af3dc
--- /dev/null
+++ b/workhorse/internal/upload/destination/multi_hash.go
@@ -0,0 +1,48 @@
+package destination
+
+import (
+ "crypto/md5"
+ "crypto/sha1"
+ "crypto/sha256"
+ "crypto/sha512"
+ "encoding/hex"
+ "hash"
+ "io"
+)
+
+var hashFactories = map[string](func() hash.Hash){
+ "md5": md5.New,
+ "sha1": sha1.New,
+ "sha256": sha256.New,
+ "sha512": sha512.New,
+}
+
+type multiHash struct {
+ io.Writer
+ hashes map[string]hash.Hash
+}
+
+func newMultiHash() (m *multiHash) {
+ m = &multiHash{}
+ m.hashes = make(map[string]hash.Hash)
+
+ var writers []io.Writer
+ for hash, hashFactory := range hashFactories {
+ writer := hashFactory()
+
+ m.hashes[hash] = writer
+ writers = append(writers, writer)
+ }
+
+ m.Writer = io.MultiWriter(writers...)
+ return m
+}
+
+func (m *multiHash) finish() map[string]string {
+ h := make(map[string]string)
+ for hashName, hash := range m.hashes {
+ checksum := hash.Sum(nil)
+ h[hashName] = hex.EncodeToString(checksum)
+ }
+ return h
+}
diff --git a/workhorse/internal/upload/destination/objectstore/doc.go b/workhorse/internal/upload/destination/objectstore/doc.go
new file mode 100644
index 00000000000..00f98f230ec
--- /dev/null
+++ b/workhorse/internal/upload/destination/objectstore/doc.go
@@ -0,0 +1,3 @@
+// The objectstore package consists of a number of consumers specific to uploading
+// to object storage providers that are S3 compatible (e.g. AWS S3, GCP, Azure).
+package objectstore
diff --git a/workhorse/internal/objectstore/gocloud_object.go b/workhorse/internal/upload/destination/objectstore/gocloud_object.go
index 38545086994..38545086994 100644
--- a/workhorse/internal/objectstore/gocloud_object.go
+++ b/workhorse/internal/upload/destination/objectstore/gocloud_object.go
diff --git a/workhorse/internal/upload/destination/objectstore/gocloud_object_test.go b/workhorse/internal/upload/destination/objectstore/gocloud_object_test.go
new file mode 100644
index 00000000000..57b3a35b41e
--- /dev/null
+++ b/workhorse/internal/upload/destination/objectstore/gocloud_object_test.go
@@ -0,0 +1,56 @@
+package objectstore_test
+
+import (
+ "context"
+ "fmt"
+ "strings"
+ "testing"
+ "time"
+
+ "github.com/stretchr/testify/require"
+
+ "gitlab.com/gitlab-org/gitlab/workhorse/internal/testhelper"
+ "gitlab.com/gitlab-org/gitlab/workhorse/internal/upload/destination/objectstore"
+ "gitlab.com/gitlab-org/gitlab/workhorse/internal/upload/destination/objectstore/test"
+)
+
+func TestGoCloudObjectUpload(t *testing.T) {
+ mux, _, cleanup := test.SetupGoCloudFileBucket(t, "azuretest")
+ defer cleanup()
+
+ ctx, cancel := context.WithCancel(context.Background())
+ deadline := time.Now().Add(testTimeout)
+
+ objectName := "test.png"
+ testURL := "azuretest://azure.example.com/test-container"
+ p := &objectstore.GoCloudObjectParams{Ctx: ctx, Mux: mux, BucketURL: testURL, ObjectName: objectName}
+ object, err := objectstore.NewGoCloudObject(p)
+ require.NotNil(t, object)
+ require.NoError(t, err)
+
+ // copy data
+ n, err := object.Consume(ctx, strings.NewReader(test.ObjectContent), deadline)
+ require.NoError(t, err)
+ require.Equal(t, test.ObjectSize, n, "Uploaded file mismatch")
+
+ bucket, err := mux.OpenBucket(ctx, testURL)
+ require.NoError(t, err)
+
+ // Verify the data was copied correctly.
+ received, err := bucket.ReadAll(ctx, objectName)
+ require.NoError(t, err)
+ require.Equal(t, []byte(test.ObjectContent), received)
+
+ cancel()
+
+ testhelper.Retry(t, 5*time.Second, func() error {
+ exists, err := bucket.Exists(ctx, objectName)
+ require.NoError(t, err)
+
+ if exists {
+ return fmt.Errorf("file %s is still present", objectName)
+ } else {
+ return nil
+ }
+ })
+}
diff --git a/workhorse/internal/objectstore/multipart.go b/workhorse/internal/upload/destination/objectstore/multipart.go
index 4c5b64b27ee..4c5b64b27ee 100644
--- a/workhorse/internal/objectstore/multipart.go
+++ b/workhorse/internal/upload/destination/objectstore/multipart.go
diff --git a/workhorse/internal/upload/destination/objectstore/multipart_test.go b/workhorse/internal/upload/destination/objectstore/multipart_test.go
new file mode 100644
index 00000000000..4aff3467e30
--- /dev/null
+++ b/workhorse/internal/upload/destination/objectstore/multipart_test.go
@@ -0,0 +1,64 @@
+package objectstore_test
+
+import (
+ "context"
+ "io/ioutil"
+ "net/http"
+ "net/http/httptest"
+ "strings"
+ "testing"
+ "time"
+
+ "github.com/stretchr/testify/require"
+
+ "gitlab.com/gitlab-org/gitlab/workhorse/internal/upload/destination/objectstore"
+ "gitlab.com/gitlab-org/gitlab/workhorse/internal/upload/destination/objectstore/test"
+)
+
+func TestMultipartUploadWithUpcaseETags(t *testing.T) {
+ ctx, cancel := context.WithCancel(context.Background())
+ defer cancel()
+
+ var putCnt, postCnt int
+
+ ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ _, err := ioutil.ReadAll(r.Body)
+ require.NoError(t, err)
+ defer r.Body.Close()
+
+ // Part upload request
+ if r.Method == "PUT" {
+ putCnt++
+
+ w.Header().Set("ETag", strings.ToUpper(test.ObjectMD5))
+ }
+
+ // POST with CompleteMultipartUpload request
+ if r.Method == "POST" {
+ completeBody := `<CompleteMultipartUploadResult>
+ <Bucket>test-bucket</Bucket>
+ <ETag>No Longer Checked</ETag>
+ </CompleteMultipartUploadResult>`
+ postCnt++
+
+ w.Write([]byte(completeBody))
+ }
+ }))
+ defer ts.Close()
+
+ deadline := time.Now().Add(testTimeout)
+
+ m, err := objectstore.NewMultipart(
+ []string{ts.URL}, // a single presigned part URL
+ ts.URL, // the complete multipart upload URL
+ "", // no abort
+ "", // no delete
+ map[string]string{}, // no custom headers
+ test.ObjectSize) // parts size equal to the whole content. Only 1 part
+ require.NoError(t, err)
+
+ _, err = m.Consume(ctx, strings.NewReader(test.ObjectContent), deadline)
+ require.NoError(t, err)
+ require.Equal(t, 1, putCnt, "1 part expected")
+ require.Equal(t, 1, postCnt, "1 complete multipart upload expected")
+}
diff --git a/workhorse/internal/objectstore/object.go b/workhorse/internal/upload/destination/objectstore/object.go
index b7c4f12f009..b7c4f12f009 100644
--- a/workhorse/internal/objectstore/object.go
+++ b/workhorse/internal/upload/destination/objectstore/object.go
diff --git a/workhorse/internal/upload/destination/objectstore/object_test.go b/workhorse/internal/upload/destination/objectstore/object_test.go
new file mode 100644
index 00000000000..24117891b6d
--- /dev/null
+++ b/workhorse/internal/upload/destination/objectstore/object_test.go
@@ -0,0 +1,149 @@
+package objectstore_test
+
+import (
+ "context"
+ "io"
+ "net/http"
+ "net/http/httptest"
+ "strings"
+ "testing"
+ "time"
+
+ "github.com/stretchr/testify/require"
+
+ "gitlab.com/gitlab-org/gitlab/workhorse/internal/upload/destination/objectstore"
+ "gitlab.com/gitlab-org/gitlab/workhorse/internal/upload/destination/objectstore/test"
+)
+
+const testTimeout = 10 * time.Second
+
+type osFactory func() (*test.ObjectstoreStub, *httptest.Server)
+
+func testObjectUploadNoErrors(t *testing.T, startObjectStore osFactory, useDeleteURL bool, contentType string) {
+ osStub, ts := startObjectStore()
+ defer ts.Close()
+
+ objectURL := ts.URL + test.ObjectPath
+ var deleteURL string
+ if useDeleteURL {
+ deleteURL = objectURL
+ }
+
+ putHeaders := map[string]string{"Content-Type": contentType}
+
+ ctx, cancel := context.WithCancel(context.Background())
+ defer cancel()
+
+ deadline := time.Now().Add(testTimeout)
+ object, err := objectstore.NewObject(objectURL, deleteURL, putHeaders, test.ObjectSize)
+ require.NoError(t, err)
+
+ // copy data
+ n, err := object.Consume(ctx, strings.NewReader(test.ObjectContent), deadline)
+ require.NoError(t, err)
+ require.Equal(t, test.ObjectSize, n, "Uploaded file mismatch")
+
+ require.Equal(t, contentType, osStub.GetHeader(test.ObjectPath, "Content-Type"))
+
+ // Checking MD5 extraction
+ require.Equal(t, osStub.GetObjectMD5(test.ObjectPath), object.ETag())
+
+ // Checking cleanup
+ cancel()
+ require.Equal(t, 1, osStub.PutsCnt(), "Object hasn't been uploaded")
+
+ var expectedDeleteCnt int
+ if useDeleteURL {
+ expectedDeleteCnt = 1
+ }
+ require.Eventually(t, func() bool { return osStub.DeletesCnt() == expectedDeleteCnt }, time.Second, time.Millisecond)
+
+ if useDeleteURL {
+ require.Equal(t, 1, osStub.DeletesCnt(), "Object hasn't been deleted")
+ } else {
+ require.Equal(t, 0, osStub.DeletesCnt(), "Object has been deleted")
+ }
+}
+
+func TestObjectUpload(t *testing.T) {
+ t.Run("with delete URL", func(t *testing.T) {
+ testObjectUploadNoErrors(t, test.StartObjectStore, true, "application/octet-stream")
+ })
+ t.Run("without delete URL", func(t *testing.T) {
+ testObjectUploadNoErrors(t, test.StartObjectStore, false, "application/octet-stream")
+ })
+ t.Run("with custom content type", func(t *testing.T) {
+ testObjectUploadNoErrors(t, test.StartObjectStore, false, "image/jpeg")
+ })
+ t.Run("with upcase ETAG", func(t *testing.T) {
+ factory := func() (*test.ObjectstoreStub, *httptest.Server) {
+ md5s := map[string]string{
+ test.ObjectPath: strings.ToUpper(test.ObjectMD5),
+ }
+
+ return test.StartObjectStoreWithCustomMD5(md5s)
+ }
+
+ testObjectUploadNoErrors(t, factory, false, "application/octet-stream")
+ })
+}
+
+func TestObjectUpload404(t *testing.T) {
+ ts := httptest.NewServer(http.NotFoundHandler())
+ defer ts.Close()
+
+ ctx, cancel := context.WithCancel(context.Background())
+ defer cancel()
+
+ deadline := time.Now().Add(testTimeout)
+ objectURL := ts.URL + test.ObjectPath
+ object, err := objectstore.NewObject(objectURL, "", map[string]string{}, test.ObjectSize)
+ require.NoError(t, err)
+ _, err = object.Consume(ctx, strings.NewReader(test.ObjectContent), deadline)
+
+ require.Error(t, err)
+ _, isStatusCodeError := err.(objectstore.StatusCodeError)
+ require.True(t, isStatusCodeError, "Should fail with StatusCodeError")
+ require.Contains(t, err.Error(), "404")
+}
+
+type endlessReader struct{}
+
+func (e *endlessReader) Read(p []byte) (n int, err error) {
+ for i := 0; i < len(p); i++ {
+ p[i] = '*'
+ }
+
+ return len(p), nil
+}
+
+// TestObjectUploadBrokenConnection purpose is to ensure that errors caused by the upload destination get propagated back correctly.
+// This is important for troubleshooting in production.
+func TestObjectUploadBrokenConnection(t *testing.T) {
+ // This test server closes connection immediately
+ ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ hj, ok := w.(http.Hijacker)
+ if !ok {
+ require.FailNow(t, "webserver doesn't support hijacking")
+ }
+ conn, _, err := hj.Hijack()
+ if err != nil {
+ http.Error(w, err.Error(), http.StatusInternalServerError)
+ return
+ }
+ conn.Close()
+ }))
+ defer ts.Close()
+
+ ctx, cancel := context.WithCancel(context.Background())
+ defer cancel()
+
+ deadline := time.Now().Add(testTimeout)
+ objectURL := ts.URL + test.ObjectPath
+ object, err := objectstore.NewObject(objectURL, "", map[string]string{}, -1)
+ require.NoError(t, err)
+
+ _, copyErr := object.Consume(ctx, &endlessReader{}, deadline)
+ require.Error(t, copyErr)
+ require.NotEqual(t, io.ErrClosedPipe, copyErr, "We are shadowing the real error")
+}
diff --git a/workhorse/internal/objectstore/prometheus.go b/workhorse/internal/upload/destination/objectstore/prometheus.go
index 20762fb52bc..20762fb52bc 100644
--- a/workhorse/internal/objectstore/prometheus.go
+++ b/workhorse/internal/upload/destination/objectstore/prometheus.go
diff --git a/workhorse/internal/objectstore/s3_complete_multipart_api.go b/workhorse/internal/upload/destination/objectstore/s3_complete_multipart_api.go
index b84f5757f49..b84f5757f49 100644
--- a/workhorse/internal/objectstore/s3_complete_multipart_api.go
+++ b/workhorse/internal/upload/destination/objectstore/s3_complete_multipart_api.go
diff --git a/workhorse/internal/objectstore/s3_object.go b/workhorse/internal/upload/destination/objectstore/s3_object.go
index ce0cccc7eb1..ce0cccc7eb1 100644
--- a/workhorse/internal/objectstore/s3_object.go
+++ b/workhorse/internal/upload/destination/objectstore/s3_object.go
diff --git a/workhorse/internal/upload/destination/objectstore/s3_object_test.go b/workhorse/internal/upload/destination/objectstore/s3_object_test.go
new file mode 100644
index 00000000000..b81b0ae2024
--- /dev/null
+++ b/workhorse/internal/upload/destination/objectstore/s3_object_test.go
@@ -0,0 +1,174 @@
+package objectstore_test
+
+import (
+ "context"
+ "fmt"
+ "io"
+ "io/ioutil"
+ "os"
+ "path/filepath"
+ "strings"
+ "sync"
+ "testing"
+ "time"
+
+ "github.com/aws/aws-sdk-go/aws/awserr"
+ "github.com/aws/aws-sdk-go/aws/session"
+ "github.com/aws/aws-sdk-go/service/s3"
+ "github.com/stretchr/testify/require"
+
+ "gitlab.com/gitlab-org/gitlab/workhorse/internal/config"
+ "gitlab.com/gitlab-org/gitlab/workhorse/internal/testhelper"
+ "gitlab.com/gitlab-org/gitlab/workhorse/internal/upload/destination/objectstore"
+ "gitlab.com/gitlab-org/gitlab/workhorse/internal/upload/destination/objectstore/test"
+)
+
+type failedReader struct {
+ io.Reader
+}
+
+func (r *failedReader) Read(p []byte) (int, error) {
+ origErr := fmt.Errorf("entity is too large")
+ return 0, awserr.New("Read", "read failed", origErr)
+}
+
+func TestS3ObjectUpload(t *testing.T) {
+ testCases := []struct {
+ encryption string
+ }{
+ {encryption: ""},
+ {encryption: s3.ServerSideEncryptionAes256},
+ {encryption: s3.ServerSideEncryptionAwsKms},
+ }
+
+ for _, tc := range testCases {
+ t.Run(fmt.Sprintf("encryption=%v", tc.encryption), func(t *testing.T) {
+ creds, config, sess, ts := test.SetupS3(t, tc.encryption)
+ defer ts.Close()
+
+ deadline := time.Now().Add(testTimeout)
+ tmpDir, err := ioutil.TempDir("", "workhorse-test-")
+ require.NoError(t, err)
+ defer os.Remove(tmpDir)
+
+ objectName := filepath.Join(tmpDir, "s3-test-data")
+ ctx, cancel := context.WithCancel(context.Background())
+
+ object, err := objectstore.NewS3Object(objectName, creds, config)
+ require.NoError(t, err)
+
+ // copy data
+ n, err := object.Consume(ctx, strings.NewReader(test.ObjectContent), deadline)
+ require.NoError(t, err)
+ require.Equal(t, test.ObjectSize, n, "Uploaded file mismatch")
+
+ test.S3ObjectExists(t, sess, config, objectName, test.ObjectContent)
+ test.CheckS3Metadata(t, sess, config, objectName)
+
+ cancel()
+
+ testhelper.Retry(t, 5*time.Second, func() error {
+ if test.S3ObjectDoesNotExist(t, sess, config, objectName) {
+ return nil
+ }
+
+ return fmt.Errorf("file is still present")
+ })
+ })
+ }
+}
+
+func TestConcurrentS3ObjectUpload(t *testing.T) {
+ creds, uploadsConfig, uploadsSession, uploadServer := test.SetupS3WithBucket(t, "uploads", "")
+ defer uploadServer.Close()
+
+ // This will return a separate S3 endpoint
+ _, artifactsConfig, artifactsSession, artifactsServer := test.SetupS3WithBucket(t, "artifacts", "")
+ defer artifactsServer.Close()
+
+ deadline := time.Now().Add(testTimeout)
+ tmpDir, err := ioutil.TempDir("", "workhorse-test-")
+ require.NoError(t, err)
+ defer os.Remove(tmpDir)
+
+ var wg sync.WaitGroup
+
+ for i := 0; i < 4; i++ {
+ wg.Add(1)
+
+ go func(index int) {
+ var sess *session.Session
+ var config config.S3Config
+
+ if index%2 == 0 {
+ sess = uploadsSession
+ config = uploadsConfig
+ } else {
+ sess = artifactsSession
+ config = artifactsConfig
+ }
+
+ name := fmt.Sprintf("s3-test-data-%d", index)
+ objectName := filepath.Join(tmpDir, name)
+ ctx, cancel := context.WithCancel(context.Background())
+ defer cancel()
+
+ object, err := objectstore.NewS3Object(objectName, creds, config)
+ require.NoError(t, err)
+
+ // copy data
+ n, err := object.Consume(ctx, strings.NewReader(test.ObjectContent), deadline)
+ require.NoError(t, err)
+ require.Equal(t, test.ObjectSize, n, "Uploaded file mismatch")
+
+ test.S3ObjectExists(t, sess, config, objectName, test.ObjectContent)
+ wg.Done()
+ }(i)
+ }
+
+ wg.Wait()
+}
+
+func TestS3ObjectUploadCancel(t *testing.T) {
+ creds, config, _, ts := test.SetupS3(t, "")
+ defer ts.Close()
+
+ ctx, cancel := context.WithCancel(context.Background())
+
+ deadline := time.Now().Add(testTimeout)
+ tmpDir, err := ioutil.TempDir("", "workhorse-test-")
+ require.NoError(t, err)
+ defer os.Remove(tmpDir)
+
+ objectName := filepath.Join(tmpDir, "s3-test-data")
+
+ object, err := objectstore.NewS3Object(objectName, creds, config)
+
+ require.NoError(t, err)
+
+ // Cancel the transfer before the data has been copied to ensure
+ // we handle this gracefully.
+ cancel()
+
+ _, err = object.Consume(ctx, strings.NewReader(test.ObjectContent), deadline)
+ require.Error(t, err)
+ require.Equal(t, "context canceled", err.Error())
+}
+
+func TestS3ObjectUploadLimitReached(t *testing.T) {
+ creds, config, _, ts := test.SetupS3(t, "")
+ defer ts.Close()
+
+ deadline := time.Now().Add(testTimeout)
+ tmpDir, err := ioutil.TempDir("", "workhorse-test-")
+ require.NoError(t, err)
+ defer os.Remove(tmpDir)
+
+ objectName := filepath.Join(tmpDir, "s3-test-data")
+ object, err := objectstore.NewS3Object(objectName, creds, config)
+ require.NoError(t, err)
+
+ _, err = object.Consume(context.Background(), &failedReader{}, deadline)
+ require.Error(t, err)
+ require.Equal(t, "entity is too large", err.Error())
+}
diff --git a/workhorse/internal/objectstore/s3_session.go b/workhorse/internal/upload/destination/objectstore/s3_session.go
index a0c1f099145..a0c1f099145 100644
--- a/workhorse/internal/objectstore/s3_session.go
+++ b/workhorse/internal/upload/destination/objectstore/s3_session.go
diff --git a/workhorse/internal/objectstore/s3_session_test.go b/workhorse/internal/upload/destination/objectstore/s3_session_test.go
index 5d57b4f9af8..5d57b4f9af8 100644
--- a/workhorse/internal/objectstore/s3_session_test.go
+++ b/workhorse/internal/upload/destination/objectstore/s3_session_test.go
diff --git a/workhorse/internal/objectstore/test/consts.go b/workhorse/internal/upload/destination/objectstore/test/consts.go
index 7a1bcc28d45..7a1bcc28d45 100644
--- a/workhorse/internal/objectstore/test/consts.go
+++ b/workhorse/internal/upload/destination/objectstore/test/consts.go
diff --git a/workhorse/internal/objectstore/test/gocloud_stub.go b/workhorse/internal/upload/destination/objectstore/test/gocloud_stub.go
index cf22075e407..cf22075e407 100644
--- a/workhorse/internal/objectstore/test/gocloud_stub.go
+++ b/workhorse/internal/upload/destination/objectstore/test/gocloud_stub.go
diff --git a/workhorse/internal/upload/destination/objectstore/test/objectstore_stub.go b/workhorse/internal/upload/destination/objectstore/test/objectstore_stub.go
new file mode 100644
index 00000000000..d51a2de7456
--- /dev/null
+++ b/workhorse/internal/upload/destination/objectstore/test/objectstore_stub.go
@@ -0,0 +1,278 @@
+package test
+
+import (
+ "crypto/md5"
+ "encoding/hex"
+ "encoding/xml"
+ "fmt"
+ "io"
+ "io/ioutil"
+ "net/http"
+ "net/http/httptest"
+ "strconv"
+ "strings"
+ "sync"
+
+ "gitlab.com/gitlab-org/gitlab/workhorse/internal/upload/destination/objectstore"
+)
+
+type partsEtagMap map[int]string
+
+// ObjectstoreStub is a testing implementation of ObjectStore.
+// Instead of storing objects it will just save md5sum.
+type ObjectstoreStub struct {
+ // bucket contains md5sum of uploaded objects
+ bucket map[string]string
+ // overwriteMD5 contains overwrites for md5sum that should be return instead of the regular hash
+ overwriteMD5 map[string]string
+ // multipart is a map of MultipartUploads
+ multipart map[string]partsEtagMap
+ // HTTP header sent along request
+ headers map[string]*http.Header
+
+ puts int
+ deletes int
+
+ m sync.Mutex
+}
+
+// StartObjectStore will start an ObjectStore stub
+func StartObjectStore() (*ObjectstoreStub, *httptest.Server) {
+ return StartObjectStoreWithCustomMD5(make(map[string]string))
+}
+
+// StartObjectStoreWithCustomMD5 will start an ObjectStore stub: md5Hashes contains overwrites for md5sum that should be return on PutObject
+func StartObjectStoreWithCustomMD5(md5Hashes map[string]string) (*ObjectstoreStub, *httptest.Server) {
+ os := &ObjectstoreStub{
+ bucket: make(map[string]string),
+ multipart: make(map[string]partsEtagMap),
+ overwriteMD5: make(map[string]string),
+ headers: make(map[string]*http.Header),
+ }
+
+ for k, v := range md5Hashes {
+ os.overwriteMD5[k] = v
+ }
+
+ return os, httptest.NewServer(os)
+}
+
+// PutsCnt counts PutObject invocations
+func (o *ObjectstoreStub) PutsCnt() int {
+ o.m.Lock()
+ defer o.m.Unlock()
+
+ return o.puts
+}
+
+// DeletesCnt counts DeleteObject invocation of a valid object
+func (o *ObjectstoreStub) DeletesCnt() int {
+ o.m.Lock()
+ defer o.m.Unlock()
+
+ return o.deletes
+}
+
+// GetObjectMD5 return the calculated MD5 of the object uploaded to path
+// it will return an empty string if no object has been uploaded on such path
+func (o *ObjectstoreStub) GetObjectMD5(path string) string {
+ o.m.Lock()
+ defer o.m.Unlock()
+
+ return o.bucket[path]
+}
+
+// GetHeader returns a given HTTP header of the object uploaded to the path
+func (o *ObjectstoreStub) GetHeader(path, key string) string {
+ o.m.Lock()
+ defer o.m.Unlock()
+
+ if val, ok := o.headers[path]; ok {
+ return val.Get(key)
+ }
+
+ return ""
+}
+
+// InitiateMultipartUpload prepare the ObjectstoreStob to receive a MultipartUpload on path
+// It will return an error if a MultipartUpload is already in progress on that path
+// InitiateMultipartUpload is only used during test setup.
+// Workhorse's production code does not know how to initiate a multipart upload.
+//
+// Real S3 multipart uploads are more complicated than what we do here,
+// but this is enough to verify that workhorse's production code behaves as intended.
+func (o *ObjectstoreStub) InitiateMultipartUpload(path string) error {
+ o.m.Lock()
+ defer o.m.Unlock()
+
+ if o.multipart[path] != nil {
+ return fmt.Errorf("MultipartUpload for %q already in progress", path)
+ }
+
+ o.multipart[path] = make(partsEtagMap)
+ return nil
+}
+
+// IsMultipartUpload check if the given path has a MultipartUpload in progress
+func (o *ObjectstoreStub) IsMultipartUpload(path string) bool {
+ o.m.Lock()
+ defer o.m.Unlock()
+
+ return o.isMultipartUpload(path)
+}
+
+// isMultipartUpload is the lock free version of IsMultipartUpload
+func (o *ObjectstoreStub) isMultipartUpload(path string) bool {
+ return o.multipart[path] != nil
+}
+
+func (o *ObjectstoreStub) removeObject(w http.ResponseWriter, r *http.Request) {
+ o.m.Lock()
+ defer o.m.Unlock()
+
+ objectPath := r.URL.Path
+ if o.isMultipartUpload(objectPath) {
+ o.deletes++
+ delete(o.multipart, objectPath)
+
+ w.WriteHeader(200)
+ } else if _, ok := o.bucket[objectPath]; ok {
+ o.deletes++
+ delete(o.bucket, objectPath)
+
+ w.WriteHeader(200)
+ } else {
+ w.WriteHeader(404)
+ }
+}
+
+func (o *ObjectstoreStub) putObject(w http.ResponseWriter, r *http.Request) {
+ o.m.Lock()
+ defer o.m.Unlock()
+
+ objectPath := r.URL.Path
+
+ etag, overwritten := o.overwriteMD5[objectPath]
+ if !overwritten {
+ hasher := md5.New()
+ io.Copy(hasher, r.Body)
+
+ checksum := hasher.Sum(nil)
+ etag = hex.EncodeToString(checksum)
+ }
+
+ o.headers[objectPath] = &r.Header
+ o.puts++
+ if o.isMultipartUpload(objectPath) {
+ pNumber := r.URL.Query().Get("partNumber")
+ idx, err := strconv.Atoi(pNumber)
+ if err != nil {
+ http.Error(w, fmt.Sprintf("malformed partNumber: %v", err), 400)
+ return
+ }
+
+ o.multipart[objectPath][idx] = etag
+ } else {
+ o.bucket[objectPath] = etag
+ }
+
+ w.Header().Set("ETag", etag)
+ w.WriteHeader(200)
+}
+
+func MultipartUploadInternalError() *objectstore.CompleteMultipartUploadError {
+ return &objectstore.CompleteMultipartUploadError{Code: "InternalError", Message: "malformed object path"}
+}
+
+func (o *ObjectstoreStub) completeMultipartUpload(w http.ResponseWriter, r *http.Request) {
+ o.m.Lock()
+ defer o.m.Unlock()
+
+ objectPath := r.URL.Path
+
+ multipart := o.multipart[objectPath]
+ if multipart == nil {
+ http.Error(w, "Unknown MultipartUpload", 404)
+ return
+ }
+
+ buf, err := ioutil.ReadAll(r.Body)
+ if err != nil {
+ http.Error(w, err.Error(), 500)
+ return
+ }
+
+ var msg objectstore.CompleteMultipartUpload
+ err = xml.Unmarshal(buf, &msg)
+ if err != nil {
+ http.Error(w, err.Error(), 400)
+ return
+ }
+
+ for _, part := range msg.Part {
+ etag := multipart[part.PartNumber]
+ if etag != part.ETag {
+ msg := fmt.Sprintf("ETag mismatch on part %d. Expected %q got %q", part.PartNumber, etag, part.ETag)
+ http.Error(w, msg, 400)
+ return
+ }
+ }
+
+ etag, overwritten := o.overwriteMD5[objectPath]
+ if !overwritten {
+ etag = "CompleteMultipartUploadETag"
+ }
+
+ o.bucket[objectPath] = etag
+ delete(o.multipart, objectPath)
+
+ w.Header().Set("ETag", etag)
+ split := strings.SplitN(objectPath[1:], "/", 2)
+ if len(split) < 2 {
+ encodeXMLAnswer(w, MultipartUploadInternalError())
+ return
+ }
+
+ bucket := split[0]
+ key := split[1]
+ answer := objectstore.CompleteMultipartUploadResult{
+ Location: r.URL.String(),
+ Bucket: bucket,
+ Key: key,
+ ETag: etag,
+ }
+ encodeXMLAnswer(w, answer)
+}
+
+func encodeXMLAnswer(w http.ResponseWriter, answer interface{}) {
+ w.Header().Set("Content-Type", "text/xml")
+
+ enc := xml.NewEncoder(w)
+ if err := enc.Encode(answer); err != nil {
+ http.Error(w, err.Error(), 500)
+ }
+}
+
+func (o *ObjectstoreStub) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+ if r.Body != nil {
+ defer r.Body.Close()
+ }
+
+ fmt.Println("ObjectStore Stub:", r.Method, r.URL.String())
+
+ if r.URL.Path == "" {
+ http.Error(w, "No path provided", 404)
+ return
+ }
+
+ switch r.Method {
+ case "DELETE":
+ o.removeObject(w, r)
+ case "PUT":
+ o.putObject(w, r)
+ case "POST":
+ o.completeMultipartUpload(w, r)
+ default:
+ w.WriteHeader(404)
+ }
+}
diff --git a/workhorse/internal/objectstore/test/objectstore_stub_test.go b/workhorse/internal/upload/destination/objectstore/test/objectstore_stub_test.go
index 8c0d52a2d79..8c0d52a2d79 100644
--- a/workhorse/internal/objectstore/test/objectstore_stub_test.go
+++ b/workhorse/internal/upload/destination/objectstore/test/objectstore_stub_test.go
diff --git a/workhorse/internal/objectstore/test/s3_stub.go b/workhorse/internal/upload/destination/objectstore/test/s3_stub.go
index 6b83426b852..6b83426b852 100644
--- a/workhorse/internal/objectstore/test/s3_stub.go
+++ b/workhorse/internal/upload/destination/objectstore/test/s3_stub.go
diff --git a/workhorse/internal/objectstore/upload_strategy.go b/workhorse/internal/upload/destination/objectstore/upload_strategy.go
index 5707ba5f24e..5707ba5f24e 100644
--- a/workhorse/internal/objectstore/upload_strategy.go
+++ b/workhorse/internal/upload/destination/objectstore/upload_strategy.go
diff --git a/workhorse/internal/objectstore/uploader.go b/workhorse/internal/upload/destination/objectstore/uploader.go
index aedfbe55ead..aedfbe55ead 100644
--- a/workhorse/internal/objectstore/uploader.go
+++ b/workhorse/internal/upload/destination/objectstore/uploader.go
diff --git a/workhorse/internal/upload/destination/reader.go b/workhorse/internal/upload/destination/reader.go
new file mode 100644
index 00000000000..925a9468e14
--- /dev/null
+++ b/workhorse/internal/upload/destination/reader.go
@@ -0,0 +1,17 @@
+package destination
+
+import "io"
+
+type hardLimitReader struct {
+ r io.Reader
+ n int64
+}
+
+func (h *hardLimitReader) Read(p []byte) (int, error) {
+ nRead, err := h.r.Read(p)
+ h.n -= int64(nRead)
+ if h.n < 0 {
+ err = ErrEntityTooLarge
+ }
+ return nRead, err
+}
diff --git a/workhorse/internal/upload/destination/reader_test.go b/workhorse/internal/upload/destination/reader_test.go
new file mode 100644
index 00000000000..a26f7746a13
--- /dev/null
+++ b/workhorse/internal/upload/destination/reader_test.go
@@ -0,0 +1,46 @@
+package destination
+
+import (
+ "fmt"
+ "io/ioutil"
+ "strings"
+ "testing"
+ "testing/iotest"
+
+ "github.com/stretchr/testify/require"
+)
+
+func TestHardLimitReader(t *testing.T) {
+ const text = "hello world"
+ r := iotest.OneByteReader(
+ &hardLimitReader{
+ r: strings.NewReader(text),
+ n: int64(len(text)),
+ },
+ )
+
+ out, err := ioutil.ReadAll(r)
+ require.NoError(t, err)
+ require.Equal(t, text, string(out))
+}
+
+func TestHardLimitReaderFail(t *testing.T) {
+ const text = "hello world"
+
+ for bufSize := len(text) / 2; bufSize < len(text)*2; bufSize++ {
+ t.Run(fmt.Sprintf("bufsize:%d", bufSize), func(t *testing.T) {
+ r := &hardLimitReader{
+ r: iotest.DataErrReader(strings.NewReader(text)),
+ n: int64(len(text)) - 1,
+ }
+ buf := make([]byte, bufSize)
+
+ var err error
+ for i := 0; err == nil && i < 1000; i++ {
+ _, err = r.Read(buf)
+ }
+
+ require.Equal(t, ErrEntityTooLarge, err)
+ })
+ }
+}
diff --git a/workhorse/internal/upload/destination/upload_opts.go b/workhorse/internal/upload/destination/upload_opts.go
new file mode 100644
index 00000000000..750a79d7bc2
--- /dev/null
+++ b/workhorse/internal/upload/destination/upload_opts.go
@@ -0,0 +1,171 @@
+package destination
+
+import (
+ "errors"
+ "strings"
+ "time"
+
+ "gocloud.dev/blob"
+
+ "gitlab.com/gitlab-org/gitlab/workhorse/internal/api"
+ "gitlab.com/gitlab-org/gitlab/workhorse/internal/config"
+)
+
+// DefaultObjectStoreTimeout is the timeout for ObjectStore upload operation
+const DefaultObjectStoreTimeout = 4 * time.Hour
+
+type ObjectStorageConfig struct {
+ Provider string
+
+ S3Credentials config.S3Credentials
+ S3Config config.S3Config
+
+ // GoCloud mux that maps azureblob:// and future URLs (e.g. s3://, gcs://, etc.) to a handler
+ URLMux *blob.URLMux
+
+ // Azure credentials are registered at startup in the GoCloud URLMux, so only the container name is needed
+ GoCloudConfig config.GoCloudConfig
+}
+
+// UploadOpts represents all the options available for saving a file to object store
+type UploadOpts struct {
+ // TempFilePrefix is the prefix used to create temporary local file
+ TempFilePrefix string
+ // LocalTempPath is the directory where to write a local copy of the file
+ LocalTempPath string
+ // RemoteID is the remote ObjectID provided by GitLab
+ RemoteID string
+ // RemoteURL is the final URL of the file
+ RemoteURL string
+ // PresignedPut is a presigned S3 PutObject compatible URL
+ PresignedPut string
+ // PresignedDelete is a presigned S3 DeleteObject compatible URL.
+ PresignedDelete string
+ // HTTP headers to be sent along with PUT request
+ PutHeaders map[string]string
+ // Whether to ignore Rails pre-signed URLs and have Workhorse directly access object storage provider
+ UseWorkhorseClient bool
+ // If UseWorkhorseClient is true, this is the temporary object name to store the file
+ RemoteTempObjectID string
+ // Workhorse object storage client (e.g. S3) parameters
+ ObjectStorageConfig ObjectStorageConfig
+ // Deadline it the S3 operation deadline, the upload will be aborted if not completed in time
+ Deadline time.Time
+ // The maximum accepted size in bytes of the upload
+ MaximumSize int64
+
+ //MultipartUpload parameters
+ // PartSize is the exact size of each uploaded part. Only the last one can be smaller
+ PartSize int64
+ // PresignedParts contains the presigned URLs for each part
+ PresignedParts []string
+ // PresignedCompleteMultipart is a presigned URL for CompleteMulipartUpload
+ PresignedCompleteMultipart string
+ // PresignedAbortMultipart is a presigned URL for AbortMultipartUpload
+ PresignedAbortMultipart string
+}
+
+// UseWorkhorseClientEnabled checks if the options require direct access to object storage
+func (s *UploadOpts) UseWorkhorseClientEnabled() bool {
+ return s.UseWorkhorseClient && s.ObjectStorageConfig.IsValid() && s.RemoteTempObjectID != ""
+}
+
+// IsLocal checks if the options require the writing of the file on disk
+func (s *UploadOpts) IsLocal() bool {
+ return s.LocalTempPath != ""
+}
+
+// IsMultipart checks if the options requires a Multipart upload
+func (s *UploadOpts) IsMultipart() bool {
+ return s.PartSize > 0
+}
+
+// GetOpts converts GitLab api.Response to a proper UploadOpts
+func GetOpts(apiResponse *api.Response) (*UploadOpts, error) {
+ timeout := time.Duration(apiResponse.RemoteObject.Timeout) * time.Second
+ if timeout == 0 {
+ timeout = DefaultObjectStoreTimeout
+ }
+
+ opts := UploadOpts{
+ LocalTempPath: apiResponse.TempPath,
+ RemoteID: apiResponse.RemoteObject.ID,
+ RemoteURL: apiResponse.RemoteObject.GetURL,
+ PresignedPut: apiResponse.RemoteObject.StoreURL,
+ PresignedDelete: apiResponse.RemoteObject.DeleteURL,
+ PutHeaders: apiResponse.RemoteObject.PutHeaders,
+ UseWorkhorseClient: apiResponse.RemoteObject.UseWorkhorseClient,
+ RemoteTempObjectID: apiResponse.RemoteObject.RemoteTempObjectID,
+ Deadline: time.Now().Add(timeout),
+ MaximumSize: apiResponse.MaximumSize,
+ }
+
+ if opts.LocalTempPath != "" && opts.RemoteID != "" {
+ return nil, errors.New("API response has both TempPath and RemoteObject")
+ }
+
+ if opts.LocalTempPath == "" && opts.RemoteID == "" {
+ return nil, errors.New("API response has neither TempPath nor RemoteObject")
+ }
+
+ objectStorageParams := apiResponse.RemoteObject.ObjectStorage
+ if opts.UseWorkhorseClient && objectStorageParams != nil {
+ opts.ObjectStorageConfig.Provider = objectStorageParams.Provider
+ opts.ObjectStorageConfig.S3Config = objectStorageParams.S3Config
+ opts.ObjectStorageConfig.GoCloudConfig = objectStorageParams.GoCloudConfig
+ }
+
+ // Backwards compatibility to ensure API servers that do not include the
+ // CustomPutHeaders flag will default to the original content type.
+ if !apiResponse.RemoteObject.CustomPutHeaders {
+ opts.PutHeaders = make(map[string]string)
+ opts.PutHeaders["Content-Type"] = "application/octet-stream"
+ }
+
+ if multiParams := apiResponse.RemoteObject.MultipartUpload; multiParams != nil {
+ opts.PartSize = multiParams.PartSize
+ opts.PresignedCompleteMultipart = multiParams.CompleteURL
+ opts.PresignedAbortMultipart = multiParams.AbortURL
+ opts.PresignedParts = append([]string(nil), multiParams.PartURLs...)
+ }
+
+ return &opts, nil
+}
+
+func (c *ObjectStorageConfig) IsAWS() bool {
+ return strings.EqualFold(c.Provider, "AWS") || strings.EqualFold(c.Provider, "S3")
+}
+
+func (c *ObjectStorageConfig) IsAzure() bool {
+ return strings.EqualFold(c.Provider, "AzureRM")
+}
+
+func (c *ObjectStorageConfig) IsGoCloud() bool {
+ return c.GoCloudConfig.URL != ""
+}
+
+func (c *ObjectStorageConfig) IsValid() bool {
+ if c.IsAWS() {
+ return c.S3Config.Bucket != "" && c.s3CredentialsValid()
+ } else if c.IsGoCloud() {
+ // We could parse and validate the URL, but GoCloud providers
+ // such as AzureRM don't have a fallback to normal HTTP, so we
+ // always want to try the GoCloud path if there is a URL.
+ return true
+ }
+
+ return false
+}
+
+func (c *ObjectStorageConfig) s3CredentialsValid() bool {
+ // We need to be able to distinguish between two cases of AWS access:
+ // 1. AWS access via key and secret, but credentials not configured in Workhorse
+ // 2. IAM instance profiles used
+ if c.S3Config.UseIamProfile {
+ return true
+ } else if c.S3Credentials.AwsAccessKeyID != "" && c.S3Credentials.AwsSecretAccessKey != "" {
+ return true
+ }
+
+ return false
+}
diff --git a/workhorse/internal/upload/destination/upload_opts_test.go b/workhorse/internal/upload/destination/upload_opts_test.go
new file mode 100644
index 00000000000..fde726c985d
--- /dev/null
+++ b/workhorse/internal/upload/destination/upload_opts_test.go
@@ -0,0 +1,342 @@
+package destination_test
+
+import (
+ "testing"
+ "time"
+
+ "github.com/stretchr/testify/require"
+
+ "gitlab.com/gitlab-org/gitlab/workhorse/internal/api"
+ "gitlab.com/gitlab-org/gitlab/workhorse/internal/config"
+ "gitlab.com/gitlab-org/gitlab/workhorse/internal/upload/destination"
+ "gitlab.com/gitlab-org/gitlab/workhorse/internal/upload/destination/objectstore/test"
+)
+
+func TestUploadOptsLocalAndRemote(t *testing.T) {
+ tests := []struct {
+ name string
+ localTempPath string
+ presignedPut string
+ partSize int64
+ isLocal bool
+ isRemote bool
+ isMultipart bool
+ }{
+ {
+ name: "Only LocalTempPath",
+ localTempPath: "/tmp",
+ isLocal: true,
+ },
+ {
+ name: "No paths",
+ },
+ {
+ name: "Only remoteUrl",
+ presignedPut: "http://example.com",
+ },
+ {
+ name: "Multipart",
+ partSize: 10,
+ isMultipart: true,
+ },
+ }
+
+ for _, test := range tests {
+ t.Run(test.name, func(t *testing.T) {
+ opts := destination.UploadOpts{
+ LocalTempPath: test.localTempPath,
+ PresignedPut: test.presignedPut,
+ PartSize: test.partSize,
+ }
+
+ require.Equal(t, test.isLocal, opts.IsLocal(), "IsLocal() mismatch")
+ require.Equal(t, test.isMultipart, opts.IsMultipart(), "IsMultipart() mismatch")
+ })
+ }
+}
+
+func TestGetOpts(t *testing.T) {
+ tests := []struct {
+ name string
+ multipart *api.MultipartUploadParams
+ customPutHeaders bool
+ putHeaders map[string]string
+ }{
+ {
+ name: "Single upload",
+ },
+ {
+ name: "Multipart upload",
+ multipart: &api.MultipartUploadParams{
+ PartSize: 10,
+ CompleteURL: "http://complete",
+ AbortURL: "http://abort",
+ PartURLs: []string{"http://part1", "http://part2"},
+ },
+ },
+ {
+ name: "Single upload with custom content type",
+ customPutHeaders: true,
+ putHeaders: map[string]string{"Content-Type": "image/jpeg"},
+ }, {
+ name: "Multipart upload with custom content type",
+ multipart: &api.MultipartUploadParams{
+ PartSize: 10,
+ CompleteURL: "http://complete",
+ AbortURL: "http://abort",
+ PartURLs: []string{"http://part1", "http://part2"},
+ },
+ customPutHeaders: true,
+ putHeaders: map[string]string{"Content-Type": "image/jpeg"},
+ },
+ }
+
+ for _, test := range tests {
+ t.Run(test.name, func(t *testing.T) {
+ apiResponse := &api.Response{
+ RemoteObject: api.RemoteObject{
+ Timeout: 10,
+ ID: "id",
+ GetURL: "http://get",
+ StoreURL: "http://store",
+ DeleteURL: "http://delete",
+ MultipartUpload: test.multipart,
+ CustomPutHeaders: test.customPutHeaders,
+ PutHeaders: test.putHeaders,
+ },
+ }
+ deadline := time.Now().Add(time.Duration(apiResponse.RemoteObject.Timeout) * time.Second)
+ opts, err := destination.GetOpts(apiResponse)
+ require.NoError(t, err)
+
+ require.Equal(t, apiResponse.TempPath, opts.LocalTempPath)
+ require.WithinDuration(t, deadline, opts.Deadline, time.Second)
+ require.Equal(t, apiResponse.RemoteObject.ID, opts.RemoteID)
+ require.Equal(t, apiResponse.RemoteObject.GetURL, opts.RemoteURL)
+ require.Equal(t, apiResponse.RemoteObject.StoreURL, opts.PresignedPut)
+ require.Equal(t, apiResponse.RemoteObject.DeleteURL, opts.PresignedDelete)
+ if test.customPutHeaders {
+ require.Equal(t, opts.PutHeaders, apiResponse.RemoteObject.PutHeaders)
+ } else {
+ require.Equal(t, opts.PutHeaders, map[string]string{"Content-Type": "application/octet-stream"})
+ }
+
+ if test.multipart == nil {
+ require.False(t, opts.IsMultipart())
+ require.Empty(t, opts.PresignedCompleteMultipart)
+ require.Empty(t, opts.PresignedAbortMultipart)
+ require.Zero(t, opts.PartSize)
+ require.Empty(t, opts.PresignedParts)
+ } else {
+ require.True(t, opts.IsMultipart())
+ require.Equal(t, test.multipart.CompleteURL, opts.PresignedCompleteMultipart)
+ require.Equal(t, test.multipart.AbortURL, opts.PresignedAbortMultipart)
+ require.Equal(t, test.multipart.PartSize, opts.PartSize)
+ require.Equal(t, test.multipart.PartURLs, opts.PresignedParts)
+ }
+ })
+ }
+}
+
+func TestGetOptsFail(t *testing.T) {
+ testCases := []struct {
+ desc string
+ in *api.Response
+ }{
+ {
+ desc: "neither local nor remote",
+ in: &api.Response{},
+ },
+ {
+ desc: "both local and remote",
+ in: &api.Response{TempPath: "/foobar", RemoteObject: api.RemoteObject{ID: "id"}},
+ },
+ }
+
+ for _, tc := range testCases {
+ t.Run(tc.desc, func(t *testing.T) {
+ _, err := destination.GetOpts(tc.in)
+ require.Error(t, err, "expect input to be rejected")
+ })
+ }
+}
+
+func TestGetOptsDefaultTimeout(t *testing.T) {
+ deadline := time.Now().Add(destination.DefaultObjectStoreTimeout)
+ opts, err := destination.GetOpts(&api.Response{TempPath: "/foo/bar"})
+ require.NoError(t, err)
+
+ require.WithinDuration(t, deadline, opts.Deadline, time.Minute)
+}
+
+func TestUseWorkhorseClientEnabled(t *testing.T) {
+ cfg := destination.ObjectStorageConfig{
+ Provider: "AWS",
+ S3Config: config.S3Config{
+ Bucket: "test-bucket",
+ Region: "test-region",
+ },
+ S3Credentials: config.S3Credentials{
+ AwsAccessKeyID: "test-key",
+ AwsSecretAccessKey: "test-secret",
+ },
+ }
+
+ missingCfg := cfg
+ missingCfg.S3Credentials = config.S3Credentials{}
+
+ iamConfig := missingCfg
+ iamConfig.S3Config.UseIamProfile = true
+
+ missingRegion := cfg
+ missingRegion.S3Config.Region = ""
+
+ tests := []struct {
+ name string
+ UseWorkhorseClient bool
+ remoteTempObjectID string
+ objectStorageConfig destination.ObjectStorageConfig
+ expected bool
+ }{
+ {
+ name: "all direct access settings used",
+ UseWorkhorseClient: true,
+ remoteTempObjectID: "test-object",
+ objectStorageConfig: cfg,
+ expected: true,
+ },
+ {
+ name: "missing AWS credentials",
+ UseWorkhorseClient: true,
+ remoteTempObjectID: "test-object",
+ objectStorageConfig: missingCfg,
+ expected: false,
+ },
+ {
+ name: "direct access disabled",
+ UseWorkhorseClient: false,
+ remoteTempObjectID: "test-object",
+ objectStorageConfig: cfg,
+ expected: false,
+ },
+ {
+ name: "with IAM instance profile",
+ UseWorkhorseClient: true,
+ remoteTempObjectID: "test-object",
+ objectStorageConfig: iamConfig,
+ expected: true,
+ },
+ {
+ name: "missing remote temp object ID",
+ UseWorkhorseClient: true,
+ remoteTempObjectID: "",
+ objectStorageConfig: cfg,
+ expected: false,
+ },
+ {
+ name: "missing S3 config",
+ UseWorkhorseClient: true,
+ remoteTempObjectID: "test-object",
+ expected: false,
+ },
+ {
+ name: "missing S3 bucket",
+ UseWorkhorseClient: true,
+ remoteTempObjectID: "test-object",
+ objectStorageConfig: destination.ObjectStorageConfig{
+ Provider: "AWS",
+ S3Config: config.S3Config{},
+ },
+ expected: false,
+ },
+ {
+ name: "missing S3 region",
+ UseWorkhorseClient: true,
+ remoteTempObjectID: "test-object",
+ objectStorageConfig: missingRegion,
+ expected: true,
+ },
+ }
+
+ for _, test := range tests {
+ t.Run(test.name, func(t *testing.T) {
+ apiResponse := &api.Response{
+ RemoteObject: api.RemoteObject{
+ Timeout: 10,
+ ID: "id",
+ UseWorkhorseClient: test.UseWorkhorseClient,
+ RemoteTempObjectID: test.remoteTempObjectID,
+ },
+ }
+ deadline := time.Now().Add(time.Duration(apiResponse.RemoteObject.Timeout) * time.Second)
+ opts, err := destination.GetOpts(apiResponse)
+ require.NoError(t, err)
+ opts.ObjectStorageConfig = test.objectStorageConfig
+
+ require.Equal(t, apiResponse.TempPath, opts.LocalTempPath)
+ require.WithinDuration(t, deadline, opts.Deadline, time.Second)
+ require.Equal(t, apiResponse.RemoteObject.ID, opts.RemoteID)
+ require.Equal(t, apiResponse.RemoteObject.UseWorkhorseClient, opts.UseWorkhorseClient)
+ require.Equal(t, test.expected, opts.UseWorkhorseClientEnabled())
+ })
+ }
+}
+
+func TestGoCloudConfig(t *testing.T) {
+ mux, _, cleanup := test.SetupGoCloudFileBucket(t, "azblob")
+ defer cleanup()
+
+ tests := []struct {
+ name string
+ provider string
+ url string
+ valid bool
+ }{
+ {
+ name: "valid AzureRM config",
+ provider: "AzureRM",
+ url: "azblob:://test-container",
+ valid: true,
+ },
+ {
+ name: "invalid GoCloud scheme",
+ provider: "AzureRM",
+ url: "unknown:://test-container",
+ valid: true,
+ },
+ }
+
+ for _, test := range tests {
+ t.Run(test.name, func(t *testing.T) {
+ apiResponse := &api.Response{
+ RemoteObject: api.RemoteObject{
+ Timeout: 10,
+ ID: "id",
+ UseWorkhorseClient: true,
+ RemoteTempObjectID: "test-object",
+ ObjectStorage: &api.ObjectStorageParams{
+ Provider: test.provider,
+ GoCloudConfig: config.GoCloudConfig{
+ URL: test.url,
+ },
+ },
+ },
+ }
+ deadline := time.Now().Add(time.Duration(apiResponse.RemoteObject.Timeout) * time.Second)
+ opts, err := destination.GetOpts(apiResponse)
+ require.NoError(t, err)
+ opts.ObjectStorageConfig.URLMux = mux
+
+ require.Equal(t, apiResponse.TempPath, opts.LocalTempPath)
+ require.Equal(t, apiResponse.RemoteObject.RemoteTempObjectID, opts.RemoteTempObjectID)
+ require.WithinDuration(t, deadline, opts.Deadline, time.Second)
+ require.Equal(t, apiResponse.RemoteObject.ID, opts.RemoteID)
+ require.Equal(t, apiResponse.RemoteObject.UseWorkhorseClient, opts.UseWorkhorseClient)
+ require.Equal(t, test.provider, opts.ObjectStorageConfig.Provider)
+ require.Equal(t, apiResponse.RemoteObject.ObjectStorage.GoCloudConfig, opts.ObjectStorageConfig.GoCloudConfig)
+ require.True(t, opts.UseWorkhorseClientEnabled())
+ require.Equal(t, test.valid, opts.ObjectStorageConfig.IsValid())
+ require.False(t, opts.IsLocal())
+ })
+ }
+}
diff --git a/workhorse/internal/upload/lfs_preparer.go b/workhorse/internal/upload/lfs_preparer.go
new file mode 100644
index 00000000000..e7c5cf16a30
--- /dev/null
+++ b/workhorse/internal/upload/lfs_preparer.go
@@ -0,0 +1,47 @@
+package upload
+
+import (
+ "fmt"
+
+ "gitlab.com/gitlab-org/gitlab/workhorse/internal/api"
+ "gitlab.com/gitlab-org/gitlab/workhorse/internal/config"
+ "gitlab.com/gitlab-org/gitlab/workhorse/internal/upload/destination"
+)
+
+type object struct {
+ size int64
+ oid string
+}
+
+func (l *object) Verify(fh *destination.FileHandler) error {
+ if fh.Size != l.size {
+ return fmt.Errorf("LFSObject: expected size %d, wrote %d", l.size, fh.Size)
+ }
+
+ if fh.SHA256() != l.oid {
+ return fmt.Errorf("LFSObject: expected sha256 %s, got %s", l.oid, fh.SHA256())
+ }
+
+ return nil
+}
+
+type uploadPreparer struct {
+ objectPreparer Preparer
+}
+
+// NewLfs returns a new preparer instance which adds capability to a wrapped
+// preparer to set options required for a LFS upload.
+func NewLfsPreparer(c config.Config, objectPreparer Preparer) Preparer {
+ return &uploadPreparer{objectPreparer: objectPreparer}
+}
+
+func (l *uploadPreparer) Prepare(a *api.Response) (*destination.UploadOpts, Verifier, error) {
+ opts, _, err := l.objectPreparer.Prepare(a)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ opts.TempFilePrefix = a.LfsOid
+
+ return opts, &object{oid: a.LfsOid, size: a.LfsSize}, nil
+}
diff --git a/workhorse/internal/upload/lfs_preparer_test.go b/workhorse/internal/upload/lfs_preparer_test.go
new file mode 100644
index 00000000000..6be4a7c2955
--- /dev/null
+++ b/workhorse/internal/upload/lfs_preparer_test.go
@@ -0,0 +1,59 @@
+package upload
+
+import (
+ "testing"
+
+ "gitlab.com/gitlab-org/gitlab/workhorse/internal/api"
+ "gitlab.com/gitlab-org/gitlab/workhorse/internal/config"
+
+ "github.com/stretchr/testify/require"
+)
+
+func TestLfsPreparerWithConfig(t *testing.T) {
+ lfsOid := "abcd1234"
+ creds := config.S3Credentials{
+ AwsAccessKeyID: "test-key",
+ AwsSecretAccessKey: "test-secret",
+ }
+
+ c := config.Config{
+ ObjectStorageCredentials: config.ObjectStorageCredentials{
+ Provider: "AWS",
+ S3Credentials: creds,
+ },
+ }
+
+ r := &api.Response{
+ LfsOid: lfsOid,
+ RemoteObject: api.RemoteObject{
+ ID: "the upload ID",
+ UseWorkhorseClient: true,
+ ObjectStorage: &api.ObjectStorageParams{
+ Provider: "AWS",
+ },
+ },
+ }
+
+ uploadPreparer := NewObjectStoragePreparer(c)
+ lfsPreparer := NewLfsPreparer(c, uploadPreparer)
+ opts, verifier, err := lfsPreparer.Prepare(r)
+
+ require.NoError(t, err)
+ require.Equal(t, lfsOid, opts.TempFilePrefix)
+ require.True(t, opts.ObjectStorageConfig.IsAWS())
+ require.True(t, opts.UseWorkhorseClient)
+ require.Equal(t, creds, opts.ObjectStorageConfig.S3Credentials)
+ require.NotNil(t, verifier)
+}
+
+func TestLfsPreparerWithNoConfig(t *testing.T) {
+ c := config.Config{}
+ r := &api.Response{RemoteObject: api.RemoteObject{ID: "the upload ID"}}
+ uploadPreparer := NewObjectStoragePreparer(c)
+ lfsPreparer := NewLfsPreparer(c, uploadPreparer)
+ opts, verifier, err := lfsPreparer.Prepare(r)
+
+ require.NoError(t, err)
+ require.False(t, opts.UseWorkhorseClient)
+ require.NotNil(t, verifier)
+}
diff --git a/workhorse/internal/upload/multipart_uploader.go b/workhorse/internal/upload/multipart_uploader.go
new file mode 100644
index 00000000000..d0097f9e153
--- /dev/null
+++ b/workhorse/internal/upload/multipart_uploader.go
@@ -0,0 +1,28 @@
+package upload
+
+import (
+ "fmt"
+ "net/http"
+
+ "gitlab.com/gitlab-org/gitlab/workhorse/internal/api"
+ "gitlab.com/gitlab-org/gitlab/workhorse/internal/helper"
+)
+
+// Multipart is a request middleware. If the request has a MIME multipart
+// request body, the middleware will iterate through the multipart parts.
+// When it finds a file part (filename != ""), the middleware will save
+// the file contents to a temporary location and replace the file part
+// with a reference to the temporary location.
+func Multipart(rails PreAuthorizer, h http.Handler, p Preparer) http.Handler {
+ return rails.PreAuthorizeHandler(func(w http.ResponseWriter, r *http.Request, a *api.Response) {
+ s := &SavedFileTracker{Request: r}
+
+ opts, _, err := p.Prepare(a)
+ if err != nil {
+ helper.Fail500(w, r, fmt.Errorf("Multipart: error preparing file storage options"))
+ return
+ }
+
+ interceptMultipartFiles(w, r, h, a, s, opts)
+ }, "/authorize")
+}
diff --git a/workhorse/internal/upload/object_storage_preparer.go b/workhorse/internal/upload/object_storage_preparer.go
index 241cfc2d9d2..f28f598c895 100644
--- a/workhorse/internal/upload/object_storage_preparer.go
+++ b/workhorse/internal/upload/object_storage_preparer.go
@@ -3,7 +3,7 @@ package upload
import (
"gitlab.com/gitlab-org/gitlab/workhorse/internal/api"
"gitlab.com/gitlab-org/gitlab/workhorse/internal/config"
- "gitlab.com/gitlab-org/gitlab/workhorse/internal/filestore"
+ "gitlab.com/gitlab-org/gitlab/workhorse/internal/upload/destination"
)
type ObjectStoragePreparer struct {
@@ -11,12 +11,15 @@ type ObjectStoragePreparer struct {
credentials config.ObjectStorageCredentials
}
+// NewObjectStoragePreparer returns a new preparer instance which is responsible for
+// setting the object storage credentials and settings needed by an uploader
+// to upload to object storage.
func NewObjectStoragePreparer(c config.Config) Preparer {
return &ObjectStoragePreparer{credentials: c.ObjectStorageCredentials, config: c.ObjectStorageConfig}
}
-func (p *ObjectStoragePreparer) Prepare(a *api.Response) (*filestore.SaveFileOpts, Verifier, error) {
- opts, err := filestore.GetOpts(a)
+func (p *ObjectStoragePreparer) Prepare(a *api.Response) (*destination.UploadOpts, Verifier, error) {
+ opts, err := destination.GetOpts(a)
if err != nil {
return nil, nil, err
}
diff --git a/workhorse/internal/upload/preparer.go b/workhorse/internal/upload/preparer.go
new file mode 100644
index 00000000000..46a4cac01b5
--- /dev/null
+++ b/workhorse/internal/upload/preparer.go
@@ -0,0 +1,33 @@
+package upload
+
+import (
+ "gitlab.com/gitlab-org/gitlab/workhorse/internal/api"
+ "gitlab.com/gitlab-org/gitlab/workhorse/internal/upload/destination"
+)
+
+// Verifier is an optional pluggable behavior for upload paths. If
+// Verify() returns an error, Workhorse will return an error response to
+// the client instead of propagating the request to Rails. The motivating
+// use case is Git LFS, where Workhorse checks the size and SHA256
+// checksum of the uploaded file.
+type Verifier interface {
+ // Verify can abort the upload by returning an error
+ Verify(handler *destination.FileHandler) error
+}
+
+// Preparer is a pluggable behavior that interprets a Rails API response
+// and either tells Workhorse how to handle the upload, via the
+// UploadOpts and Verifier, or it rejects the request by returning a
+// non-nil error. Its intended use is to make sure the upload gets stored
+// in the right location: either a local directory, or one of several
+// supported object storage backends.
+type Preparer interface {
+ Prepare(a *api.Response) (*destination.UploadOpts, Verifier, error)
+}
+
+type DefaultPreparer struct{}
+
+func (s *DefaultPreparer) Prepare(a *api.Response) (*destination.UploadOpts, Verifier, error) {
+ opts, err := destination.GetOpts(a)
+ return opts, nil, err
+}
diff --git a/workhorse/internal/upload/rewrite.go b/workhorse/internal/upload/rewrite.go
index bbabe840ef5..ff5190226af 100644
--- a/workhorse/internal/upload/rewrite.go
+++ b/workhorse/internal/upload/rewrite.go
@@ -21,8 +21,8 @@ import (
"golang.org/x/image/tiff"
"gitlab.com/gitlab-org/gitlab/workhorse/internal/api"
- "gitlab.com/gitlab-org/gitlab/workhorse/internal/filestore"
"gitlab.com/gitlab-org/gitlab/workhorse/internal/lsif_transformer/parser"
+ "gitlab.com/gitlab-org/gitlab/workhorse/internal/upload/destination"
"gitlab.com/gitlab-org/gitlab/workhorse/internal/upload/exif"
)
@@ -68,7 +68,7 @@ type rewriter struct {
finalizedFields map[string]bool
}
-func rewriteFormFilesFromMultipart(r *http.Request, writer *multipart.Writer, preauth *api.Response, filter MultipartFormProcessor, opts *filestore.SaveFileOpts) error {
+func rewriteFormFilesFromMultipart(r *http.Request, writer *multipart.Writer, preauth *api.Response, filter MultipartFormProcessor, opts *destination.UploadOpts) error {
// Create multipart reader
reader, err := r.MultipartReader()
if err != nil {
@@ -128,7 +128,7 @@ func parseAndNormalizeContentDisposition(header textproto.MIMEHeader) (string, s
return params["name"], params["filename"]
}
-func (rew *rewriter) handleFilePart(ctx context.Context, name string, p *multipart.Part, opts *filestore.SaveFileOpts) error {
+func (rew *rewriter) handleFilePart(ctx context.Context, name string, p *multipart.Part, opts *destination.UploadOpts) error {
if rew.filter.Count() >= maxFilesAllowed {
return ErrTooManyFilesUploaded
}
@@ -164,10 +164,10 @@ func (rew *rewriter) handleFilePart(ctx context.Context, name string, p *multipa
defer inputReader.Close()
- fh, err := filestore.SaveFileFromReader(ctx, inputReader, -1, opts)
+ fh, err := destination.Upload(ctx, inputReader, -1, opts)
if err != nil {
switch err {
- case filestore.ErrEntityTooLarge, exif.ErrRemovingExif:
+ case destination.ErrEntityTooLarge, exif.ErrRemovingExif:
return err
default:
return fmt.Errorf("persisting multipart file: %v", err)
diff --git a/workhorse/internal/upload/saved_file_tracker.go b/workhorse/internal/upload/saved_file_tracker.go
index e6f9a8c9a88..b70a303a4a4 100644
--- a/workhorse/internal/upload/saved_file_tracker.go
+++ b/workhorse/internal/upload/saved_file_tracker.go
@@ -6,8 +6,8 @@ import (
"mime/multipart"
"net/http"
- "gitlab.com/gitlab-org/gitlab/workhorse/internal/filestore"
"gitlab.com/gitlab-org/gitlab/workhorse/internal/secret"
+ "gitlab.com/gitlab-org/gitlab/workhorse/internal/upload/destination"
)
type SavedFileTracker struct {
@@ -26,7 +26,7 @@ func (s *SavedFileTracker) Count() int {
return len(s.rewrittenFields)
}
-func (s *SavedFileTracker) ProcessFile(_ context.Context, fieldName string, file *filestore.FileHandler, _ *multipart.Writer) error {
+func (s *SavedFileTracker) ProcessFile(_ context.Context, fieldName string, file *destination.FileHandler, _ *multipart.Writer) error {
if _, ok := s.rewrittenFields[fieldName]; ok {
return fmt.Errorf("the %v field has already been processed", fieldName)
}
diff --git a/workhorse/internal/upload/saved_file_tracker_test.go b/workhorse/internal/upload/saved_file_tracker_test.go
index ba927db253e..4f323bf8888 100644
--- a/workhorse/internal/upload/saved_file_tracker_test.go
+++ b/workhorse/internal/upload/saved_file_tracker_test.go
@@ -10,8 +10,8 @@ import (
"github.com/stretchr/testify/require"
- "gitlab.com/gitlab-org/gitlab/workhorse/internal/filestore"
"gitlab.com/gitlab-org/gitlab/workhorse/internal/testhelper"
+ "gitlab.com/gitlab-org/gitlab/workhorse/internal/upload/destination"
)
func TestSavedFileTracking(t *testing.T) {
@@ -23,7 +23,7 @@ func TestSavedFileTracking(t *testing.T) {
tracker := SavedFileTracker{Request: r}
require.Equal(t, "accelerate", tracker.Name())
- file := &filestore.FileHandler{}
+ file := &destination.FileHandler{}
ctx := context.Background()
tracker.ProcessFile(ctx, "test", file, nil)
require.Equal(t, 1, tracker.Count())
@@ -40,7 +40,7 @@ func TestSavedFileTracking(t *testing.T) {
func TestDuplicatedFileProcessing(t *testing.T) {
tracker := SavedFileTracker{}
- file := &filestore.FileHandler{}
+ file := &destination.FileHandler{}
require.NoError(t, tracker.ProcessFile(context.Background(), "file", file, nil))
diff --git a/workhorse/internal/upload/uploads.go b/workhorse/internal/upload/uploads.go
index 1806e7563ce..8272a3d920d 100644
--- a/workhorse/internal/upload/uploads.go
+++ b/workhorse/internal/upload/uploads.go
@@ -8,27 +8,39 @@ import (
"mime/multipart"
"net/http"
+ "github.com/golang-jwt/jwt/v4"
+
"gitlab.com/gitlab-org/gitlab/workhorse/internal/api"
- "gitlab.com/gitlab-org/gitlab/workhorse/internal/filestore"
"gitlab.com/gitlab-org/gitlab/workhorse/internal/helper"
+ "gitlab.com/gitlab-org/gitlab/workhorse/internal/upload/destination"
"gitlab.com/gitlab-org/gitlab/workhorse/internal/upload/exif"
"gitlab.com/gitlab-org/gitlab/workhorse/internal/zipartifacts"
)
+const RewrittenFieldsHeader = "Gitlab-Workhorse-Multipart-Fields"
+
+type PreAuthorizer interface {
+ PreAuthorizeHandler(next api.HandleFunc, suffix string) http.Handler
+}
+
+type MultipartClaims struct {
+ RewrittenFields map[string]string `json:"rewritten_fields"`
+ jwt.StandardClaims
+}
+
// MultipartFormProcessor abstracts away implementation differences
// between generic MIME multipart file uploads and CI artifact uploads.
type MultipartFormProcessor interface {
- ProcessFile(ctx context.Context, formName string, file *filestore.FileHandler, writer *multipart.Writer) error
+ ProcessFile(ctx context.Context, formName string, file *destination.FileHandler, writer *multipart.Writer) error
ProcessField(ctx context.Context, formName string, writer *multipart.Writer) error
Finalize(ctx context.Context) error
Name() string
Count() int
}
-// InterceptMultipartFiles is the core of the implementation of
-// Multipart. Because it is also used for CI artifact uploads it is a
-// public function.
-func InterceptMultipartFiles(w http.ResponseWriter, r *http.Request, h http.Handler, preauth *api.Response, filter MultipartFormProcessor, opts *filestore.SaveFileOpts) {
+// interceptMultipartFiles is the core of the implementation of
+// Multipart.
+func interceptMultipartFiles(w http.ResponseWriter, r *http.Request, h http.Handler, preauth *api.Response, filter MultipartFormProcessor, opts *destination.UploadOpts) {
var body bytes.Buffer
writer := multipart.NewWriter(&body)
defer writer.Close()
@@ -43,7 +55,7 @@ func InterceptMultipartFiles(w http.ResponseWriter, r *http.Request, h http.Hand
helper.CaptureAndFail(w, r, err, err.Error(), http.StatusBadRequest)
case http.ErrNotMultipart:
h.ServeHTTP(w, r)
- case filestore.ErrEntityTooLarge:
+ case destination.ErrEntityTooLarge:
helper.RequestEntityTooLarge(w, r, err)
case zipartifacts.ErrBadMetadata:
helper.RequestEntityTooLarge(w, r, err)
diff --git a/workhorse/internal/upload/uploads_test.go b/workhorse/internal/upload/uploads_test.go
index f262bf94b08..9d787b10d1c 100644
--- a/workhorse/internal/upload/uploads_test.go
+++ b/workhorse/internal/upload/uploads_test.go
@@ -22,9 +22,9 @@ import (
"gitlab.com/gitlab-org/gitlab/workhorse/internal/api"
"gitlab.com/gitlab-org/gitlab/workhorse/internal/helper"
- "gitlab.com/gitlab-org/gitlab/workhorse/internal/objectstore/test"
"gitlab.com/gitlab-org/gitlab/workhorse/internal/proxy"
"gitlab.com/gitlab-org/gitlab/workhorse/internal/testhelper"
+ "gitlab.com/gitlab-org/gitlab/workhorse/internal/upload/destination/objectstore/test"
"gitlab.com/gitlab-org/gitlab/workhorse/internal/upstream/roundtripper"
)
@@ -78,7 +78,7 @@ func TestUploadHandlerForwardingRawData(t *testing.T) {
opts, _, err := preparer.Prepare(apiResponse)
require.NoError(t, err)
- InterceptMultipartFiles(response, httpRequest, handler, apiResponse, nil, opts)
+ interceptMultipartFiles(response, httpRequest, handler, apiResponse, nil, opts)
require.Equal(t, 202, response.Code)
require.Equal(t, "RESPONSE", response.Body.String(), "response body")
@@ -149,7 +149,7 @@ func TestUploadHandlerRewritingMultiPartData(t *testing.T) {
opts, _, err := preparer.Prepare(apiResponse)
require.NoError(t, err)
- InterceptMultipartFiles(response, httpRequest, handler, apiResponse, &testFormProcessor{}, opts)
+ interceptMultipartFiles(response, httpRequest, handler, apiResponse, &testFormProcessor{}, opts)
require.Equal(t, 202, response.Code)
cancel() // this will trigger an async cleanup
@@ -218,7 +218,7 @@ func TestUploadHandlerDetectingInjectedMultiPartData(t *testing.T) {
opts, _, err := preparer.Prepare(apiResponse)
require.NoError(t, err)
- InterceptMultipartFiles(response, httpRequest, handler, apiResponse, &testFormProcessor{}, opts)
+ interceptMultipartFiles(response, httpRequest, handler, apiResponse, &testFormProcessor{}, opts)
require.Equal(t, test.response, response.Code)
cancel() // this will trigger an async cleanup
@@ -248,7 +248,7 @@ func TestUploadProcessingField(t *testing.T) {
opts, _, err := preparer.Prepare(apiResponse)
require.NoError(t, err)
- InterceptMultipartFiles(response, httpRequest, nilHandler, apiResponse, &testFormProcessor{}, opts)
+ interceptMultipartFiles(response, httpRequest, nilHandler, apiResponse, &testFormProcessor{}, opts)
require.Equal(t, 500, response.Code)
}
@@ -279,7 +279,7 @@ func TestUploadingMultipleFiles(t *testing.T) {
opts, _, err := preparer.Prepare(apiResponse)
require.NoError(t, err)
- InterceptMultipartFiles(response, httpRequest, nilHandler, apiResponse, &testFormProcessor{}, opts)
+ interceptMultipartFiles(response, httpRequest, nilHandler, apiResponse, &testFormProcessor{}, opts)
require.Equal(t, 400, response.Code)
require.Equal(t, "upload request contains more than 10 files\n", response.Body.String())
@@ -335,7 +335,7 @@ func TestUploadProcessingFile(t *testing.T) {
opts, _, err := preparer.Prepare(apiResponse)
require.NoError(t, err)
- InterceptMultipartFiles(response, httpRequest, nilHandler, apiResponse, &testFormProcessor{}, opts)
+ interceptMultipartFiles(response, httpRequest, nilHandler, apiResponse, &testFormProcessor{}, opts)
require.Equal(t, 200, response.Code)
})
@@ -381,7 +381,7 @@ func TestInvalidFileNames(t *testing.T) {
opts, _, err := preparer.Prepare(apiResponse)
require.NoError(t, err)
- InterceptMultipartFiles(response, httpRequest, nilHandler, apiResponse, &SavedFileTracker{Request: httpRequest}, opts)
+ interceptMultipartFiles(response, httpRequest, nilHandler, apiResponse, &SavedFileTracker{Request: httpRequest}, opts)
require.Equal(t, testCase.code, response.Code)
require.Equal(t, testCase.expectedPrefix, opts.TempFilePrefix)
}
@@ -447,7 +447,7 @@ func TestContentDispositionRewrite(t *testing.T) {
opts, _, err := preparer.Prepare(apiResponse)
require.NoError(t, err)
- InterceptMultipartFiles(response, httpRequest, customHandler, apiResponse, &SavedFileTracker{Request: httpRequest}, opts)
+ interceptMultipartFiles(response, httpRequest, customHandler, apiResponse, &SavedFileTracker{Request: httpRequest}, opts)
upstreamRequest, err := http.ReadRequest(bufio.NewReader(&upstreamRequestBuffer))
require.NoError(t, err)
@@ -570,7 +570,7 @@ func runUploadTest(t *testing.T, image []byte, filename string, httpCode int, ts
opts, _, err := preparer.Prepare(apiResponse)
require.NoError(t, err)
- InterceptMultipartFiles(response, httpRequest, handler, apiResponse, &testFormProcessor{}, opts)
+ interceptMultipartFiles(response, httpRequest, handler, apiResponse, &testFormProcessor{}, opts)
require.Equal(t, httpCode, response.Code)
}
diff --git a/workhorse/internal/upstream/.gitignore b/workhorse/internal/upstream/.gitignore
new file mode 100644
index 00000000000..d63cd8b2c40
--- /dev/null
+++ b/workhorse/internal/upstream/.gitignore
@@ -0,0 +1 @@
+testdata/public
diff --git a/workhorse/internal/upstream/metrics.go b/workhorse/internal/upstream/metrics.go
index 1a11bdc8b53..27cc6bb045b 100644
--- a/workhorse/internal/upstream/metrics.go
+++ b/workhorse/internal/upstream/metrics.go
@@ -6,6 +6,8 @@ import (
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
"github.com/prometheus/client_golang/prometheus/promhttp"
+
+ "gitlab.com/gitlab-org/labkit/metrics"
)
const (
@@ -13,95 +15,7 @@ const (
httpSubsystem = "http"
)
-func secondsDurationBuckets() []float64 {
- return []float64{
- 0.005, /* 5ms */
- 0.025, /* 25ms */
- 0.1, /* 100ms */
- 0.5, /* 500ms */
- 1.0, /* 1s */
- 10.0, /* 10s */
- 30.0, /* 30s */
- 60.0, /* 1m */
- 300.0, /* 10m */
- }
-}
-
-func byteSizeBuckets() []float64 {
- return []float64{
- 10,
- 64,
- 256,
- 1024, /* 1kB */
- 64 * 1024, /* 64kB */
- 256 * 1024, /* 256kB */
- 1024 * 1024, /* 1mB */
- 64 * 1024 * 1024, /* 64mB */
- }
-}
-
var (
- httpInFlightRequests = promauto.NewGauge(prometheus.GaugeOpts{
- Namespace: namespace,
- Subsystem: httpSubsystem,
- Name: "in_flight_requests",
- Help: "A gauge of requests currently being served by workhorse.",
- })
-
- httpRequestsTotal = promauto.NewCounterVec(
- prometheus.CounterOpts{
- Namespace: namespace,
- Subsystem: httpSubsystem,
- Name: "requests_total",
- Help: "A counter for requests to workhorse.",
- },
- []string{"code", "method", "route"},
- )
-
- httpRequestDurationSeconds = promauto.NewHistogramVec(
- prometheus.HistogramOpts{
- Namespace: namespace,
- Subsystem: httpSubsystem,
- Name: "request_duration_seconds",
- Help: "A histogram of latencies for requests to workhorse.",
- Buckets: secondsDurationBuckets(),
- },
- []string{"code", "method", "route"},
- )
-
- httpRequestSizeBytes = promauto.NewHistogramVec(
- prometheus.HistogramOpts{
- Namespace: namespace,
- Subsystem: httpSubsystem,
- Name: "request_size_bytes",
- Help: "A histogram of sizes of requests to workhorse.",
- Buckets: byteSizeBuckets(),
- },
- []string{"code", "method", "route"},
- )
-
- httpResponseSizeBytes = promauto.NewHistogramVec(
- prometheus.HistogramOpts{
- Namespace: namespace,
- Subsystem: httpSubsystem,
- Name: "response_size_bytes",
- Help: "A histogram of response sizes for requests to workhorse.",
- Buckets: byteSizeBuckets(),
- },
- []string{"code", "method", "route"},
- )
-
- httpTimeToWriteHeaderSeconds = promauto.NewHistogramVec(
- prometheus.HistogramOpts{
- Namespace: namespace,
- Subsystem: httpSubsystem,
- Name: "time_to_write_header_seconds",
- Help: "A histogram of request durations until the response headers are written.",
- Buckets: secondsDurationBuckets(),
- },
- []string{"code", "method", "route"},
- )
-
httpGeoProxiedRequestsTotal = promauto.NewCounterVec(
prometheus.CounterOpts{
Namespace: namespace,
@@ -111,19 +25,12 @@ var (
},
[]string{"code", "method", "route"},
)
+
+ buildHandler = metrics.NewHandlerFactory(metrics.WithNamespace(namespace), metrics.WithLabels("route"))
)
func instrumentRoute(next http.Handler, method string, regexpStr string) http.Handler {
- handler := next
-
- handler = promhttp.InstrumentHandlerCounter(httpRequestsTotal.MustCurryWith(map[string]string{"route": regexpStr}), handler)
- handler = promhttp.InstrumentHandlerDuration(httpRequestDurationSeconds.MustCurryWith(map[string]string{"route": regexpStr}), handler)
- handler = promhttp.InstrumentHandlerInFlight(httpInFlightRequests, handler)
- handler = promhttp.InstrumentHandlerRequestSize(httpRequestSizeBytes.MustCurryWith(map[string]string{"route": regexpStr}), handler)
- handler = promhttp.InstrumentHandlerResponseSize(httpResponseSizeBytes.MustCurryWith(map[string]string{"route": regexpStr}), handler)
- handler = promhttp.InstrumentHandlerTimeToWriteHeader(httpTimeToWriteHeaderSeconds.MustCurryWith(map[string]string{"route": regexpStr}), handler)
-
- return handler
+ return buildHandler(next, metrics.WithLabelValues(map[string]string{"route": regexpStr}))
}
func instrumentGeoProxyRoute(next http.Handler, method string, regexpStr string) http.Handler {
diff --git a/workhorse/internal/upstream/routes.go b/workhorse/internal/upstream/routes.go
index b8089865ffe..b1d76dfc1bd 100644
--- a/workhorse/internal/upstream/routes.go
+++ b/workhorse/internal/upstream/routes.go
@@ -20,7 +20,6 @@ import (
"gitlab.com/gitlab-org/gitlab/workhorse/internal/git"
"gitlab.com/gitlab-org/gitlab/workhorse/internal/helper"
"gitlab.com/gitlab-org/gitlab/workhorse/internal/imageresizer"
- "gitlab.com/gitlab-org/gitlab/workhorse/internal/lfs"
proxypkg "gitlab.com/gitlab-org/gitlab/workhorse/internal/proxy"
"gitlab.com/gitlab-org/gitlab/workhorse/internal/queueing"
"gitlab.com/gitlab-org/gitlab/workhorse/internal/redis"
@@ -251,8 +250,8 @@ func configureRoutes(u *upstream) {
u.route("PUT", gitProjectPattern+`gitlab-lfs/objects/([0-9a-f]{64})/([0-9]+)\z`, upload.RequestBody(api, signingProxy, preparers.lfs), withMatcher(isContentType("application/octet-stream"))),
// CI Artifacts
- u.route("POST", apiPattern+`v4/jobs/[0-9]+/artifacts\z`, contentEncodingHandler(artifacts.UploadArtifacts(api, signingProxy, preparers.artifacts))),
- u.route("POST", ciAPIPattern+`v1/builds/[0-9]+/artifacts\z`, contentEncodingHandler(artifacts.UploadArtifacts(api, signingProxy, preparers.artifacts))),
+ u.route("POST", apiPattern+`v4/jobs/[0-9]+/artifacts\z`, contentEncodingHandler(upload.Artifacts(api, signingProxy, preparers.artifacts))),
+ u.route("POST", ciAPIPattern+`v1/builds/[0-9]+/artifacts\z`, contentEncodingHandler(upload.Artifacts(api, signingProxy, preparers.artifacts))),
// ActionCable websocket
u.wsRoute(`^/-/cable\z`, cableProxy),
@@ -318,9 +317,12 @@ func configureRoutes(u *upstream) {
// Group Import via UI upload acceleration
u.route("POST", importPattern+`gitlab_group`, upload.Multipart(api, signingProxy, preparers.uploads)),
- // Metric image upload
+ // Issuable Metric image upload
u.route("POST", apiProjectPattern+`issues/[0-9]+/metric_images\z`, upload.Multipart(api, signingProxy, preparers.uploads)),
+ // Alert Metric image upload
+ u.route("POST", apiProjectPattern+`alert_management_alerts/[0-9]+/metric_images\z`, upload.Multipart(api, signingProxy, preparers.uploads)),
+
// Requirements Import via UI upload acceleration
u.route("POST", projectPattern+`requirements_management/requirements/import_csv`, upload.Multipart(api, signingProxy, preparers.uploads)),
@@ -383,11 +385,10 @@ func configureRoutes(u *upstream) {
u.route("", "^/oauth/geo/(auth|callback|logout)$", defaultUpstream),
// Admin Area > Geo routes
- u.route("", "^/admin/geo$", defaultUpstream),
- u.route("", "^/admin/geo/", defaultUpstream),
+ u.route("", "^/admin/geo/replication/projects", defaultUpstream),
+ u.route("", "^/admin/geo/replication/designs", defaultUpstream),
// Geo API routes
- u.route("", "^/api/v4/geo_nodes", defaultUpstream),
u.route("", "^/api/v4/geo_replication", defaultUpstream),
u.route("", "^/api/v4/geo/proxy_git_ssh", defaultUpstream),
u.route("", "^/api/v4/geo/graphql", defaultUpstream),
@@ -395,6 +396,16 @@ func configureRoutes(u *upstream) {
// Internal API routes
u.route("", "^/api/v4/internal", defaultUpstream),
+ u.route(
+ "", `^/assets/`,
+ static.ServeExisting(
+ u.URLPrefix,
+ staticpages.CacheExpireMax,
+ assetsNotFoundHandler,
+ ),
+ withoutTracing(), // Tracing on assets is very noisy
+ ),
+
// Don't define a catch-all route. If a route does not match, then we know
// the request should be proxied.
}
@@ -405,7 +416,7 @@ func createUploadPreparers(cfg config.Config) uploadPreparers {
return uploadPreparers{
artifacts: defaultPreparer,
- lfs: lfs.NewLfsUploadPreparer(cfg, defaultPreparer),
+ lfs: upload.NewLfsPreparer(cfg, defaultPreparer),
packages: defaultPreparer,
uploads: defaultPreparer,
}
diff --git a/workhorse/internal/upstream/routes_test.go b/workhorse/internal/upstream/routes_test.go
index f196433f5b4..8a032519bdf 100644
--- a/workhorse/internal/upstream/routes_test.go
+++ b/workhorse/internal/upstream/routes_test.go
@@ -2,8 +2,26 @@ package upstream
import (
"testing"
+
+ "gitlab.com/gitlab-org/gitlab/workhorse/internal/testhelper"
)
+func TestAdminGeoPathsWithGeoProxy(t *testing.T) {
+ testCases := []testCase{
+ {"Regular admin/geo", "/admin/geo", "Geo primary received request to path /admin/geo"},
+ {"Specific object replication", "/admin/geo/replication/object_type", "Geo primary received request to path /admin/geo/replication/object_type"},
+ {"Specific object replication per-site", "/admin/geo/sites/2/replication/object_type", "Geo primary received request to path /admin/geo/sites/2/replication/object_type"},
+ {"Projects replication per-site", "/admin/geo/sites/2/replication/projects", "Geo primary received request to path /admin/geo/sites/2/replication/projects"},
+ {"Designs replication per-site", "/admin/geo/sites/2/replication/designs", "Geo primary received request to path /admin/geo/sites/2/replication/designs"},
+ {"Projects replication", "/admin/geo/replication/projects", "Local Rails server received request to path /admin/geo/replication/projects"},
+ {"Projects replication subpaths", "/admin/geo/replication/projects/2", "Local Rails server received request to path /admin/geo/replication/projects/2"},
+ {"Designs replication", "/admin/geo/replication/designs", "Local Rails server received request to path /admin/geo/replication/designs"},
+ {"Designs replication subpaths", "/admin/geo/replication/designs/3", "Local Rails server received request to path /admin/geo/replication/designs/3"},
+ }
+
+ runTestCasesWithGeoProxyEnabled(t, testCases)
+}
+
func TestProjectNotExistingGitHttpPullWithGeoProxy(t *testing.T) {
testCases := []testCase{
{"secondary info/refs", "/group/project.git/info/refs", "Local Rails server received request to path /group/project.git/info/refs"},
@@ -45,3 +63,15 @@ func TestProjectNotExistingGitSSHPushWithGeoProxy(t *testing.T) {
runTestCasesWithGeoProxyEnabled(t, testCases)
}
+
+func TestAssetsServedLocallyWithGeoProxy(t *testing.T) {
+ path := "/assets/static.txt"
+ content := "local geo asset"
+ testhelper.SetupStaticFileHelper(t, path, content, testDocumentRoot)
+
+ testCases := []testCase{
+ {"assets path", "/assets/static.txt", "local geo asset"},
+ }
+
+ runTestCasesWithGeoProxyEnabled(t, testCases)
+}
diff --git a/workhorse/main_test.go b/workhorse/main_test.go
index 349e2d78109..88db9e0103b 100644
--- a/workhorse/main_test.go
+++ b/workhorse/main_test.go
@@ -138,7 +138,7 @@ func TestDeniedXSendfileDownload(t *testing.T) {
func TestAllowedStaticFile(t *testing.T) {
content := "PUBLIC"
- require.NoError(t, setupStaticFile("static file.txt", content))
+ setupStaticFile(t, "static file.txt", content)
proxied := false
ts := testhelper.TestServerWithHandler(regexp.MustCompile(`.`), func(w http.ResponseWriter, r *http.Request) {
@@ -164,7 +164,7 @@ func TestAllowedStaticFile(t *testing.T) {
func TestStaticFileRelativeURL(t *testing.T) {
content := "PUBLIC"
- require.NoError(t, setupStaticFile("static.txt", content), "create public/static.txt")
+ setupStaticFile(t, "static.txt", content)
ts := testhelper.TestServerWithHandler(regexp.MustCompile(`.`), http.HandlerFunc(http.NotFound))
defer ts.Close()
@@ -182,7 +182,7 @@ func TestStaticFileRelativeURL(t *testing.T) {
func TestAllowedPublicUploadsFile(t *testing.T) {
content := "PRIVATE but allowed"
- require.NoError(t, setupStaticFile("uploads/static file.txt", content), "create public/uploads/static file.txt")
+ setupStaticFile(t, "uploads/static file.txt", content)
proxied := false
ts := testhelper.TestServerWithHandler(regexp.MustCompile(`.`), func(w http.ResponseWriter, r *http.Request) {
@@ -208,7 +208,7 @@ func TestAllowedPublicUploadsFile(t *testing.T) {
func TestDeniedPublicUploadsFile(t *testing.T) {
content := "PRIVATE"
- require.NoError(t, setupStaticFile("uploads/static.txt", content), "create public/uploads/static.txt")
+ setupStaticFile(t, "uploads/static.txt", content)
proxied := false
ts := testhelper.TestServerWithHandler(regexp.MustCompile(`.`), func(w http.ResponseWriter, _ *http.Request) {
@@ -241,7 +241,7 @@ This is a static error page for code 499
</body>
</html>
`
- require.NoError(t, setupStaticFile("499.html", errorPageBody))
+ setupStaticFile(t, "499.html", errorPageBody)
ts := testhelper.TestServerWithHandler(nil, func(w http.ResponseWriter, _ *http.Request) {
upstreamError := "499"
// This is the point of the test: the size of the upstream response body
@@ -266,7 +266,7 @@ This is a static error page for code 499
func TestGzipAssets(t *testing.T) {
path := "/assets/static.txt"
content := "asset"
- require.NoError(t, setupStaticFile(path, content))
+ setupStaticFile(t, path, content)
buf := &bytes.Buffer{}
gzipWriter := gzip.NewWriter(buf)
@@ -274,7 +274,7 @@ func TestGzipAssets(t *testing.T) {
require.NoError(t, err)
require.NoError(t, gzipWriter.Close())
contentGzip := buf.String()
- require.NoError(t, setupStaticFile(path+".gz", contentGzip))
+ setupStaticFile(t, path+".gz", contentGzip)
proxied := false
ts := testhelper.TestServerWithHandler(regexp.MustCompile(`.`), func(w http.ResponseWriter, r *http.Request) {
@@ -319,7 +319,7 @@ func TestGzipAssets(t *testing.T) {
func TestAltDocumentAssets(t *testing.T) {
path := "/assets/static.txt"
content := "asset"
- require.NoError(t, setupAltStaticFile(path, content))
+ setupAltStaticFile(t, path, content)
buf := &bytes.Buffer{}
gzipWriter := gzip.NewWriter(buf)
@@ -327,7 +327,7 @@ func TestAltDocumentAssets(t *testing.T) {
require.NoError(t, err)
require.NoError(t, gzipWriter.Close())
contentGzip := buf.String()
- require.NoError(t, setupAltStaticFile(path+".gz", contentGzip))
+ setupAltStaticFile(t, path+".gz", contentGzip)
proxied := false
ts := testhelper.TestServerWithHandler(regexp.MustCompile(`.`), func(w http.ResponseWriter, r *http.Request) {
@@ -712,25 +712,12 @@ func TestRejectUnknownMethod(t *testing.T) {
require.Equal(t, http.StatusMethodNotAllowed, resp.StatusCode)
}
-func setupStaticFile(fpath, content string) error {
- return setupStaticFileHelper(fpath, content, testDocumentRoot)
+func setupStaticFile(t *testing.T, fpath, content string) {
+ absDocumentRoot = testhelper.SetupStaticFileHelper(t, fpath, content, testDocumentRoot)
}
-func setupAltStaticFile(fpath, content string) error {
- return setupStaticFileHelper(fpath, content, testAltDocumentRoot)
-}
-
-func setupStaticFileHelper(fpath, content, directory string) error {
- cwd, err := os.Getwd()
- if err != nil {
- return err
- }
- absDocumentRoot = path.Join(cwd, directory)
- if err := os.MkdirAll(path.Join(absDocumentRoot, path.Dir(fpath)), 0755); err != nil {
- return err
- }
- staticFile := path.Join(absDocumentRoot, fpath)
- return ioutil.WriteFile(staticFile, []byte(content), 0666)
+func setupAltStaticFile(t *testing.T, fpath, content string) {
+ absDocumentRoot = testhelper.SetupStaticFileHelper(t, fpath, content, testAltDocumentRoot)
}
func prepareDownloadDir(t *testing.T) {
@@ -896,7 +883,7 @@ This is a static error page for code 503
</body>
</html>
`
- require.NoError(t, setupStaticFile("503.html", errorPageBody))
+ setupStaticFile(t, "503.html", errorPageBody)
ts := testhelper.TestServerWithHandler(regexp.MustCompile(`.`), func(w http.ResponseWriter, _ *http.Request) {
w.Header().Set("X-Gitlab-Custom-Error", "1")
diff --git a/workhorse/upload_test.go b/workhorse/upload_test.go
index 478cbdb1a44..180598ab260 100644
--- a/workhorse/upload_test.go
+++ b/workhorse/upload_test.go
@@ -141,6 +141,7 @@ func TestAcceleratedUpload(t *testing.T) {
{"POST", `/api/v4/projects/group%2Fsubgroup%2Fproject/packages/pypi`, true},
{"POST", `/api/v4/projects/9001/issues/30/metric_images`, true},
{"POST", `/api/v4/projects/group%2Fproject/issues/30/metric_images`, true},
+ {"POST", `/api/v4/projects/9001/alert_management_alerts/30/metric_images`, true},
{"POST", `/api/v4/projects/group%2Fsubgroup%2Fproject/issues/30/metric_images`, true},
{"POST", `/my/project/-/requirements_management/requirements/import_csv`, true},
{"POST", `/my/project/-/requirements_management/requirements/import_csv/`, true},
diff --git a/yarn.lock b/yarn.lock
index b05b46afdc5..fdf543d7c81 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -950,10 +950,10 @@
resolved "https://registry.yarnpkg.com/@gitlab/at.js/-/at.js-1.5.7.tgz#1ee6f838cc4410a1d797770934df91d90df8179e"
integrity sha512-c6ySRK/Ma7lxwpIVbSAF3P+xiTLrNTGTLRx4/pHK111AdFxwgUwrYF6aVZFXvmG65jHOJHoa0eQQ21RW6rm0Rg==
-"@gitlab/eslint-plugin@10.0.0":
- version "10.0.0"
- resolved "https://registry.yarnpkg.com/@gitlab/eslint-plugin/-/eslint-plugin-10.0.0.tgz#83430fb4d0a2467bb54975d0b5b9dc8016005722"
- integrity sha512-frCYzjQQaZ5kW1on3XwuVGhvYa6XjD6Q1POTbxDpzl6tNxSeTwOJohC6Joyw76e0Kw4fPQd/fHAfKQAB0AVQ7A==
+"@gitlab/eslint-plugin@11.0.0":
+ version "11.0.0"
+ resolved "https://registry.yarnpkg.com/@gitlab/eslint-plugin/-/eslint-plugin-11.0.0.tgz#90d71bc0c5f54ac066faba8c6f909b0df761d0bb"
+ integrity sha512-5t1eTu/+myitEP68ceKQRRE0S5R1QStlRVykivZFZDxGloCyAq1zE96ZwqsMzDtpfK5fmf1+7yxGw9CPdLUB/A==
dependencies:
babel-eslint "^10.0.3"
eslint-config-airbnb-base "^14.2.1"
@@ -981,20 +981,20 @@
stylelint-declaration-strict-value "1.8.0"
stylelint-scss "4.1.0"
-"@gitlab/svgs@2.5.0":
- version "2.5.0"
- resolved "https://registry.yarnpkg.com/@gitlab/svgs/-/svgs-2.5.0.tgz#e0569916fa858462b1801cc90ef8dd9706a12e96"
- integrity sha512-cH/EBs//wdkH6kG+kDpvRCIl63/A8JgjAhBJ+ZWucPgtNCDD6x6RDMGdQrxSqhYwcCKDoLStfcxmblBkuiSRXQ==
+"@gitlab/svgs@2.6.0":
+ version "2.6.0"
+ resolved "https://registry.yarnpkg.com/@gitlab/svgs/-/svgs-2.6.0.tgz#49f020b0a732f5df01138bd21b610a0a940badd6"
+ integrity sha512-jI8CHlrriePtUsognRkpZQWVsZe7ZjytmKakeYyU1aKvsnJ4fAeySlVkCAiqKbbZm3T/eeH/6b3jxHn24U0k0Q==
-"@gitlab/ui@36.6.0":
- version "36.6.0"
- resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-36.6.0.tgz#902ec76623de3b46d450fbe2074d00a39a58d61c"
- integrity sha512-hHuknkt4KTQVPEA8t+Cg29hocqMUv4bYfVH7Hinj3qFaIK32zMKUGQ2P/w5BG8R+cP9PTjw+WxNYc4WpRPpcUw==
+"@gitlab/ui@37.3.0":
+ version "37.3.0"
+ resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-37.3.0.tgz#7362ed42964abd049959455101540b8b78b42f5f"
+ integrity sha512-eCwXK9d+QdprgIftm/5OAZ/VjG+OdG23xpRlMeXllFigqEcELgnc742nmG7C3JG8Vlm84is7bliBbAQEWBTgbw==
dependencies:
"@babel/standalone" "^7.0.0"
bootstrap-vue "2.20.1"
copy-to-clipboard "^3.0.8"
- dompurify "^2.3.5"
+ dompurify "^2.3.6"
echarts "^5.2.1"
highlight.js "^10.6.0"
iframe-resizer "^4.3.2"
@@ -1542,10 +1542,10 @@
dom-accessibility-api "^0.5.1"
pretty-format "^26.4.2"
-"@tiptap/core@^2.0.0-beta.171":
- version "2.0.0-beta.171"
- resolved "https://registry.yarnpkg.com/@tiptap/core/-/core-2.0.0-beta.171.tgz#e681964c443383b81d2638c51fc3bbfda034a4fb"
- integrity sha512-4CdJfcchmBOFooWPBMJ7AxJISeTstMFriQv0RyReMt0Dpef/c9UoU+NkKLwwv5VRUX0M8dL5SzEhkB8wIODqlA==
+"@tiptap/core@^2.0.0-beta.174":
+ version "2.0.0-beta.174"
+ resolved "https://registry.yarnpkg.com/@tiptap/core/-/core-2.0.0-beta.174.tgz#cfdf16b7d7401e4b255dc69147d784f5f537b942"
+ integrity sha512-APQDto40PdvagG1HTwkKlieQS4Vp6GXNe7qgV1Qo2QCgJCLyxc/fXCTghtrOx0CQb+9JT7fjSLZxbSyUFXjx7Q==
dependencies:
"@types/prosemirror-commands" "^1.0.4"
"@types/prosemirror-keymap" "^1.0.4"
@@ -1567,10 +1567,10 @@
resolved "https://registry.yarnpkg.com/@tiptap/extension-blockquote/-/extension-blockquote-2.0.0-beta.26.tgz#e5ae4b7bd9376db37407a23e22080c7b11287f3b"
integrity sha512-A6yjcYovONJfOjQFk6vDYXswaCdCtCwjL7w9VTB0R2DLTuJvvRt9DWN0IDcMrj5G+aMgDq4GUUTitv+2Y8krDg==
-"@tiptap/extension-bold@^2.0.0-beta.25":
- version "2.0.0-beta.25"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-bold/-/extension-bold-2.0.0-beta.25.tgz#ec19e7c862d25bae49609c5d6a873f372c506dee"
- integrity sha512-ZNdgFYDxKo8lAp0Pqzu45I0JH3ah8/X5TCYg9zNg3QwLUFT16g2LlWDMUDGT5pH9aXxgtFaEdoVacu0EyhlPnQ==
+"@tiptap/extension-bold@^2.0.0-beta.26":
+ version "2.0.0-beta.26"
+ resolved "https://registry.yarnpkg.com/@tiptap/extension-bold/-/extension-bold-2.0.0-beta.26.tgz#aa1c7850df28cec8e0614fde437183bd4ae3e66b"
+ integrity sha512-pnO0I5sEQM3pmowjMGQ74adLzvc6HqGyLyqMizaGMicPu9uTYlSdId+qckYEEgPwPMaEShtv2Vg+ZHs7KVqfcg==
"@tiptap/extension-bubble-menu@^2.0.0-beta.55":
version "2.0.0-beta.55"
@@ -1665,15 +1665,15 @@
dependencies:
prosemirror-state "^1.3.4"
-"@tiptap/extension-image@^2.0.0-beta.25":
- version "2.0.0-beta.25"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-image/-/extension-image-2.0.0-beta.25.tgz#7fb001a6449a9a841ae4f42c258ad6a06022b523"
- integrity sha512-RgW5jFVS2QNDvFhBOz7H1hY6LjYcbVAa/mE4F4c3RPg3o7GJZXNoL9s+k0QkEM2GXAvY6fX+OICMBn8TSENXKA==
+"@tiptap/extension-image@^2.0.0-beta.27":
+ version "2.0.0-beta.27"
+ resolved "https://registry.yarnpkg.com/@tiptap/extension-image/-/extension-image-2.0.0-beta.27.tgz#62152240cfa7ead03080c38485c1ebda4a603d18"
+ integrity sha512-kdJ7V39yNdVWUco/RBe7WgvFevd81l+pU6+Je9HpelqBBP953wDttzLMuAWQB4AeLv9WhKSlORHiFv2SKsV5NA==
-"@tiptap/extension-italic@^2.0.0-beta.25":
- version "2.0.0-beta.25"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-italic/-/extension-italic-2.0.0-beta.25.tgz#c2ec95cc5baf855134883c5e261da4ab0d3b9479"
- integrity sha512-7PvhioTX9baVp5+AmmZU0qna+dFPZCRlSEN/GciH57N77d2uhJ/ZW5iQWTbvy5HBNddQB4Jts1UDIaC7WASrGA==
+"@tiptap/extension-italic@^2.0.0-beta.26":
+ version "2.0.0-beta.26"
+ resolved "https://registry.yarnpkg.com/@tiptap/extension-italic/-/extension-italic-2.0.0-beta.26.tgz#b00c9e32b81b1bd94eaed24bb2a22e44d5dc54a3"
+ integrity sha512-vejGe2ra4K5ipFOn1U9viqF9X9nPTX8WSJpSOux+9UbKjHpANy7bz69tp66OIi/Wh5L/MMDc+luH/04qfVnpZw==
"@tiptap/extension-link@^2.0.0-beta.36":
version "2.0.0-beta.36"
@@ -1896,6 +1896,13 @@
dependencies:
"@types/node" "*"
+"@types/hast@^2.0.0":
+ version "2.3.4"
+ resolved "https://registry.yarnpkg.com/@types/hast/-/hast-2.3.4.tgz#8aa5ef92c117d20d974a82bdfb6a648b08c0bafc"
+ integrity sha512-wLEm0QvaoawEDoTRwzTXp4b4jpwiJDvR5KMnFnVodm3scufTlBOWRD6N1OBf9TZMhjlNsSfcO5V+7AF4+Vy+9g==
+ dependencies:
+ "@types/unist" "*"
+
"@types/http-proxy@^1.17.8":
version "1.17.8"
resolved "https://registry.yarnpkg.com/@types/http-proxy/-/http-proxy-1.17.8.tgz#968c66903e7e42b483608030ee85800f22d03f55"
@@ -2119,6 +2126,11 @@
resolved "https://registry.yarnpkg.com/@types/ungap__global-this/-/ungap__global-this-0.3.1.tgz#18ce9f657da556037a29d50604335614ce703f4c"
integrity sha512-+/DsiV4CxXl6ZWefwHZDXSe1Slitz21tom38qPCaG0DYCS1NnDPIQDTKcmQ/tvK/edJUKkmuIDBJbmKDiB0r/g==
+"@types/unist@*":
+ version "2.0.6"
+ resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.6.tgz#250a7b16c3b91f672a24552ec64678eeb1d3a08d"
+ integrity sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==
+
"@types/websocket@1.0.4":
version "1.0.4"
resolved "https://registry.yarnpkg.com/@types/websocket/-/websocket-1.0.4.tgz#1dc497280d8049a5450854dd698ee7e6ea9e60b8"
@@ -4953,10 +4965,10 @@ dompurify@2.3.4:
resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-2.3.4.tgz#1cf5cf0105ccb4debdf6db162525bd41e6ddacc6"
integrity sha512-6BVcgOAVFXjI0JTjEvZy901Rghm+7fDQOrNIcxB4+gdhj6Kwp6T9VBhBY/AbagKHJocRkDYGd6wvI+p4/10xtQ==
-dompurify@^2.3.5:
- version "2.3.5"
- resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-2.3.5.tgz#c83ed5a3ae5ce23e52efe654ea052ffb358dd7e3"
- integrity sha512-kD+f8qEaa42+mjdOpKeztu9Mfx5bv9gVLO6K9jRx4uGvh6Wv06Srn4jr1wPNY2OOUGGSKHNFN+A8MA3v0E0QAQ==
+dompurify@^2.3.6:
+ version "2.3.6"
+ resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-2.3.6.tgz#2e019d7d7617aacac07cbbe3d88ae3ad354cf875"
+ integrity sha512-OFP2u/3T1R5CEgWCEONuJ1a5+MFKnOYpkywpUSxv/dj1LeBT1erK+JwM7zK0ROy2BRhqVCf0LRw/kHqKuMkVGg==
domutils@^2.5.2, domutils@^2.6.0:
version "2.6.0"
@@ -5130,11 +5142,6 @@ entities@^2.0.0, entities@~2.1.0:
resolved "https://registry.yarnpkg.com/entities/-/entities-2.1.0.tgz#992d3129cf7df6870b96c57858c249a120f8b8b5"
integrity sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==
-entities@~2.0.0:
- version "2.0.3"
- resolved "https://registry.yarnpkg.com/entities/-/entities-2.0.3.tgz#5c487e5742ab93c15abb5da22759b8590ec03b7f"
- integrity sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ==
-
envinfo@^7.7.3:
version "7.8.1"
resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.8.1.tgz#06377e3e5f4d379fea7ac592d5ad8927e0c4d475"
@@ -5773,6 +5780,13 @@ fault@^1.0.0:
dependencies:
format "^0.2.0"
+fault@^2.0.0:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/fault/-/fault-2.0.1.tgz#d47ca9f37ca26e4bd38374a7c500b5a384755b6c"
+ integrity sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ==
+ dependencies:
+ format "^0.2.0"
+
faye-websocket@^0.11.3:
version "0.11.3"
resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.3.tgz#5c0e9a8968e8912c286639fde977a8b209f2508e"
@@ -6402,10 +6416,10 @@ highlight.js@^10.6.0, highlight.js@~10.7.0:
resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-10.7.2.tgz#89319b861edc66c48854ed1e6da21ea89f847360"
integrity sha512-oFLl873u4usRM9K63j4ME9u3etNF0PLiJhSQ8rdfuL51Wn3zkD6drf9ZW0dOzjnZI22YYG24z30JcmfCZjMgYg==
-highlight.js@^11.3.1:
- version "11.3.1"
- resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-11.3.1.tgz#813078ef3aa519c61700f84fe9047231c5dc3291"
- integrity sha512-PUhCRnPjLtiLHZAQ5A/Dt5F8cWZeMyj9KRsACsWT+OD6OP0x6dp5OmT5jdx0JgEyPxPZZIPQpRN2TciUT7occw==
+highlight.js@^11.3.1, highlight.js@~11.4.0:
+ version "11.4.0"
+ resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-11.4.0.tgz#34ceadd49e1596ee5aba3d99346cdfd4845ee05a"
+ integrity sha512-nawlpCBCSASs7EdvZOYOYVkJpGmAOKMYZgZtUqSRqodZE0GRVcFKwo1RcpeOemqh9hyttTdd5wDBwHkuSyUfnA==
hmac-drbg@^1.0.1:
version "1.0.1"
@@ -7866,13 +7880,6 @@ lines-and-columns@^1.1.6:
resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00"
integrity sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=
-linkify-it@^2.0.0:
- version "2.2.0"
- resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-2.2.0.tgz#e3b54697e78bf915c70a38acd78fd09e0058b1cf"
- integrity sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw==
- dependencies:
- uc.micro "^1.0.1"
-
linkify-it@^3.0.1:
version "3.0.2"
resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-3.0.2.tgz#f55eeb8bc1d3ae754049e124ab3bb56d97797fb8"
@@ -8108,7 +8115,7 @@ lowercase-keys@^2.0.0:
resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479"
integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==
-lowlight@^1.17.0, lowlight@^1.20.0:
+lowlight@^1.20.0:
version "1.20.0"
resolved "https://registry.yarnpkg.com/lowlight/-/lowlight-1.20.0.tgz#ddb197d33462ad0d93bf19d17b6c301aa3941888"
integrity sha512-8Ktj+prEb1RoCPkEOrPMYUN/nCggB7qAWe3a7OpMjWQkh3l2RD5wKRQ+o8Q8YuI9RG/xs95waaI/E6ym/7NsTw==
@@ -8116,6 +8123,15 @@ lowlight@^1.17.0, lowlight@^1.20.0:
fault "^1.0.0"
highlight.js "~10.7.0"
+lowlight@^2.5.0:
+ version "2.5.0"
+ resolved "https://registry.yarnpkg.com/lowlight/-/lowlight-2.5.0.tgz#723a39fc0d9b911731a395b320519cbb0790ab14"
+ integrity sha512-OXGUch9JZu4q5r4Ir6QlUp5pBXMxS7NHaclhRiUlxNRcOSK0gtXZcVrsGP4eM7bv0/KDHg/TXQagx/X35EULsA==
+ dependencies:
+ "@types/hast" "^2.0.0"
+ fault "^2.0.0"
+ highlight.js "~11.4.0"
+
lru-cache@^4.1.2, lru-cache@^4.1.5:
version "4.1.5"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd"
@@ -8192,7 +8208,7 @@ map-visit@^1.0.0:
dependencies:
object-visit "^1.0.0"
-markdown-it@12.3.2:
+markdown-it@12.3.2, markdown-it@^12.0.0:
version "12.3.2"
resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-12.3.2.tgz#bf92ac92283fe983fe4de8ff8abfb5ad72cd0c90"
integrity sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==
@@ -8203,17 +8219,6 @@ markdown-it@12.3.2:
mdurl "^1.0.1"
uc.micro "^1.0.5"
-markdown-it@^10.0.0:
- version "10.0.0"
- resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-10.0.0.tgz#abfc64f141b1722d663402044e43927f1f50a8dc"
- integrity sha512-YWOP1j7UbDNz+TumYP1kpwnP0aEa711cJjrAQrzd0UXlbJfc5aAq0F/PZHjiioqDC1NKgvIMX+o+9Bk7yuM2dg==
- dependencies:
- argparse "^1.0.7"
- entities "~2.0.0"
- linkify-it "^2.0.0"
- mdurl "^1.0.1"
- uc.micro "^1.0.5"
-
markdownlint-cli@0.31.0:
version "0.31.0"
resolved "https://registry.yarnpkg.com/markdownlint-cli/-/markdownlint-cli-0.31.0.tgz#a44264a71066475228292b7af19d3d18b827676d"
@@ -9607,14 +9612,7 @@ prop-types@^15.7.2:
object-assign "^4.1.1"
react-is "^16.8.1"
-prosemirror-collab@^1.2.2:
- version "1.2.2"
- resolved "https://registry.yarnpkg.com/prosemirror-collab/-/prosemirror-collab-1.2.2.tgz#8d2c0e82779cfef5d051154bd0836428bd6d9c4a"
- integrity sha512-tBnHKMLgy5Qmx9MYVcLfs3pAyjtcqYYDd9kp3y+LSiQzkhMQDfZSV3NXWe4Gsly32adSef173BvObwfoSQL5MA==
- dependencies:
- prosemirror-state "^1.0.0"
-
-prosemirror-commands@^1.1.4, prosemirror-commands@^1.2.1:
+prosemirror-commands@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/prosemirror-commands/-/prosemirror-commands-1.2.1.tgz#eae0cb714df695260659b78ff5d201d3a037e50d"
integrity sha512-S/IkpXfpuLFsRynC2HQ5iYROUPiZskKS1+ClcWycGJvj4HMb/mVfeEkQrixYxgTl96EAh+RZQNWPC06GZXk5tQ==
@@ -9623,7 +9621,7 @@ prosemirror-commands@^1.1.4, prosemirror-commands@^1.2.1:
prosemirror-state "^1.0.0"
prosemirror-transform "^1.0.0"
-prosemirror-dropcursor@^1.3.2, prosemirror-dropcursor@^1.4.0:
+prosemirror-dropcursor@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/prosemirror-dropcursor/-/prosemirror-dropcursor-1.4.0.tgz#91a859d4ee79c99b1c0ba6ee61c093b195c0d9f0"
integrity sha512-6+YwTjmqDwlA/Dm+5wK67ezgqgjA/MhSDgaNxKUzH97SmeuWFXyLeDRxxOPZeSo7yTxcDGUCWTEjmQZsVBuMrQ==
@@ -9632,7 +9630,7 @@ prosemirror-dropcursor@^1.3.2, prosemirror-dropcursor@^1.4.0:
prosemirror-transform "^1.1.0"
prosemirror-view "^1.1.0"
-prosemirror-gapcursor@^1.1.5, prosemirror-gapcursor@^1.2.1:
+prosemirror-gapcursor@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/prosemirror-gapcursor/-/prosemirror-gapcursor-1.2.1.tgz#02365e1bcc1ad25d390b0fb7f0e94a7fc173ad75"
integrity sha512-PHa9lj27iM/g4C46gxVzsefuXVfy/LrGQH4QjMRht7VDBgw77iWYWn8ZHMWSFkwtr9jQEuxI5gccHHHwWG80nw==
@@ -9642,7 +9640,7 @@ prosemirror-gapcursor@^1.1.5, prosemirror-gapcursor@^1.2.1:
prosemirror-state "^1.0.0"
prosemirror-view "^1.0.0"
-prosemirror-history@^1.1.3, prosemirror-history@^1.2.0:
+prosemirror-history@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/prosemirror-history/-/prosemirror-history-1.2.0.tgz#04cc4df8d2f7b2a46651a2780de191ada6d465ea"
integrity sha512-B9v9xtf4fYbKxQwIr+3wtTDNLDZcmMMmGiI3TAPShnUzvo+Rmv1GiUrsQChY1meetHl7rhML2cppF3FTs7f7UQ==
@@ -9651,15 +9649,7 @@ prosemirror-history@^1.1.3, prosemirror-history@^1.2.0:
prosemirror-transform "^1.0.0"
rope-sequence "^1.3.0"
-prosemirror-inputrules@^1.1.2, prosemirror-inputrules@^1.1.3:
- version "1.1.3"
- resolved "https://registry.yarnpkg.com/prosemirror-inputrules/-/prosemirror-inputrules-1.1.3.tgz#93f9199ca02473259c30d7e352e4c14022d54638"
- integrity sha512-ZaHCLyBtvbyIHv0f5p6boQTIJjlD6o2NPZiEaZWT2DA+j591zS29QQEMT4lBqwcLW3qRSf7ZvoKNbf05YrsStw==
- dependencies:
- prosemirror-state "^1.0.0"
- prosemirror-transform "^1.0.0"
-
-prosemirror-keymap@^1.0.0, prosemirror-keymap@^1.1.2, prosemirror-keymap@^1.1.4, prosemirror-keymap@^1.1.5:
+prosemirror-keymap@^1.0.0, prosemirror-keymap@^1.1.2, prosemirror-keymap@^1.1.5:
version "1.1.5"
resolved "https://registry.yarnpkg.com/prosemirror-keymap/-/prosemirror-keymap-1.1.5.tgz#b5984c7d30f5c75956c853126c54e9e624c0327b"
integrity sha512-8SZgPH3K+GLsHL2wKuwBD9rxhsbnVBTwpHCO4VUO5GmqUQlxd/2GtBVWTsyLq4Dp3N9nGgPd3+lZFKUDuVp+Vw==
@@ -9667,15 +9657,15 @@ prosemirror-keymap@^1.0.0, prosemirror-keymap@^1.1.2, prosemirror-keymap@^1.1.4,
prosemirror-state "^1.0.0"
w3c-keyname "^2.2.0"
-prosemirror-markdown@1.6.0:
- version "1.6.0"
- resolved "https://registry.yarnpkg.com/prosemirror-markdown/-/prosemirror-markdown-1.6.0.tgz#141c88e03c8892f2e93cf58b1382ab0b6088d012"
- integrity sha512-y/gRpJIIrNArtkyMax7ypYafb+ZMjddbVHI+AwlcUfCLCCXK57cOmfBMKYVq9kdEKJYVdYHdoyWsVNn1nWLHUg==
+prosemirror-markdown@1.7.1:
+ version "1.7.1"
+ resolved "https://registry.yarnpkg.com/prosemirror-markdown/-/prosemirror-markdown-1.7.1.tgz#811a4846da1b3bb661ceb4b37efb89cc4f0cd4b8"
+ integrity sha512-d1lNRPlbwuncErkR/fv2n3ZEhAoS+0udByM2mZkyDHeY3ux3bUnj7J/ep1XS0FiXUjffixTKI0IAax3H82JbEg==
dependencies:
- markdown-it "^10.0.0"
+ markdown-it "^12.0.0"
prosemirror-model "^1.0.0"
-prosemirror-model@^1.0.0, prosemirror-model@^1.13.1, prosemirror-model@^1.16.0, prosemirror-model@^1.16.1, prosemirror-model@^1.2.0, prosemirror-model@^1.8.1:
+prosemirror-model@^1.0.0, prosemirror-model@^1.16.0, prosemirror-model@^1.16.1, prosemirror-model@^1.2.0, prosemirror-model@^1.8.1:
version "1.16.1"
resolved "https://registry.yarnpkg.com/prosemirror-model/-/prosemirror-model-1.16.1.tgz#fb388270bc9609b66298d6a7e15d0cc1d6c61253"
integrity sha512-r1/w0HDU40TtkXp0DyKBnFPYwd8FSlUSJmGCGFv4DeynfeSlyQF2FD0RQbVEMOe6P3PpUSXM6LZBV7W/YNZ4mA==
@@ -9689,7 +9679,7 @@ prosemirror-schema-basic@^1.0.0, prosemirror-schema-basic@^1.1.2:
dependencies:
prosemirror-model "^1.2.0"
-prosemirror-schema-list@^1.0.0, prosemirror-schema-list@^1.1.4, prosemirror-schema-list@^1.1.6:
+prosemirror-schema-list@^1.0.0, prosemirror-schema-list@^1.1.6:
version "1.1.6"
resolved "https://registry.yarnpkg.com/prosemirror-schema-list/-/prosemirror-schema-list-1.1.6.tgz#c3e13fe2f74750e4a53ff88d798dc0c4ccca6707"
integrity sha512-aFGEdaCWmJzouZ8DwedmvSsL50JpRkqhQ6tcpThwJONVVmCgI36LJHtoQ4VGZbusMavaBhXXr33zyD2IVsTlkw==
@@ -9697,7 +9687,7 @@ prosemirror-schema-list@^1.0.0, prosemirror-schema-list@^1.1.4, prosemirror-sche
prosemirror-model "^1.0.0"
prosemirror-transform "^1.0.0"
-prosemirror-state@^1.0.0, prosemirror-state@^1.2.2, prosemirror-state@^1.3.1, prosemirror-state@^1.3.3, prosemirror-state@^1.3.4:
+prosemirror-state@^1.0.0, prosemirror-state@^1.2.2, prosemirror-state@^1.3.1, prosemirror-state@^1.3.4:
version "1.3.4"
resolved "https://registry.yarnpkg.com/prosemirror-state/-/prosemirror-state-1.3.4.tgz#4c6b52628216e753fc901c6d2bfd84ce109e8952"
integrity sha512-Xkkrpd1y/TQ6HKzN3agsQIGRcLckUMA9u3j207L04mt8ToRgpGeyhbVv0HI7omDORIBHjR29b7AwlATFFf2GLA==
@@ -9725,17 +9715,17 @@ prosemirror-test-builder@^1.0.5:
prosemirror-schema-basic "^1.0.0"
prosemirror-schema-list "^1.0.0"
-prosemirror-transform@^1.0.0, prosemirror-transform@^1.1.0, prosemirror-transform@^1.2.1, prosemirror-transform@^1.2.8, prosemirror-transform@^1.3.3:
+prosemirror-transform@^1.0.0, prosemirror-transform@^1.1.0, prosemirror-transform@^1.2.1, prosemirror-transform@^1.3.3:
version "1.3.3"
resolved "https://registry.yarnpkg.com/prosemirror-transform/-/prosemirror-transform-1.3.3.tgz#5f6712b0577a119cc418686fe7588b6dd9b7464d"
integrity sha512-9NLVXy1Sfa2G6qPqhWMkEvwQQMTw7OyTqOZbJaGQWsCeH3hH5Cw+c5eNaLM1Uu75EyKLsEZhJ93XpHJBa6RX8A==
dependencies:
prosemirror-model "^1.0.0"
-prosemirror-view@^1.0.0, prosemirror-view@^1.1.0, prosemirror-view@^1.13.3, prosemirror-view@^1.16.5, prosemirror-view@^1.23.6:
- version "1.23.6"
- resolved "https://registry.yarnpkg.com/prosemirror-view/-/prosemirror-view-1.23.6.tgz#f514b3166942cb70aac4ac24d0a28c21c3897608"
- integrity sha512-B4DAzriNpI/AVoW0Lu6SVfX00jZZQxOVwdBQEjWlRbCdT9V0pvk4GQJ3JTFaib+b6BcPdRZ3MjWXz2xvV1rblA==
+prosemirror-view@^1.0.0, prosemirror-view@^1.1.0, prosemirror-view@^1.13.3, prosemirror-view@^1.23.6, prosemirror-view@^1.23.7:
+ version "1.23.7"
+ resolved "https://registry.yarnpkg.com/prosemirror-view/-/prosemirror-view-1.23.7.tgz#f003af94445ef456e397c18cf4bb995e7072097f"
+ integrity sha512-ugY+g/4UI2Ree1zzdvbyQWF2KpbFa7kxKMLHaEJcxiPaErnZiD5wZFqIgFinc7fY2v/QM3DLnJ++2I45ULRdrg==
dependencies:
prosemirror-model "^1.16.0"
prosemirror-state "^1.0.0"
@@ -11358,61 +11348,6 @@ tippy.js@^6.3.7:
dependencies:
"@popperjs/core" "^2.9.0"
-tiptap-commands@^1.17.1:
- version "1.17.1"
- resolved "https://registry.yarnpkg.com/tiptap-commands/-/tiptap-commands-1.17.1.tgz#a8974a26d87db57b2fd4fc56a552520c69e43a4a"
- integrity sha512-CyGvMD/c6fNer5LThWGtrVMXHAqHn93ivGQpqJ58x3HNZFuoIiF9QTWXAiWbY/4QrG0ANYHKCSe9n5afickTqw==
- dependencies:
- prosemirror-commands "^1.1.4"
- prosemirror-inputrules "^1.1.2"
- prosemirror-model "^1.13.1"
- prosemirror-schema-list "^1.1.4"
- prosemirror-state "^1.3.3"
- prosemirror-tables "^1.1.1"
- tiptap-utils "^1.13.1"
-
-tiptap-extensions@^1.35.2:
- version "1.35.2"
- resolved "https://registry.yarnpkg.com/tiptap-extensions/-/tiptap-extensions-1.35.2.tgz#83dd6ee703ae8c83b58c7608f97253fcc4f1a94c"
- integrity sha512-TIMbHVJe0/3aVeTeCmqGbatDkfxduPYFOffNCmuKR+h6oQNzTu6rLVhRzoNqktfxIoi/b44SiDPorTjSN72dCw==
- dependencies:
- lowlight "^1.17.0"
- prosemirror-collab "^1.2.2"
- prosemirror-history "^1.1.3"
- prosemirror-model "^1.13.1"
- prosemirror-state "^1.3.3"
- prosemirror-tables "^1.1.1"
- prosemirror-transform "^1.2.8"
- prosemirror-view "^1.16.5"
- tiptap "^1.32.2"
- tiptap-commands "^1.17.1"
- tiptap-utils "^1.13.1"
-
-tiptap-utils@^1.13.1:
- version "1.13.1"
- resolved "https://registry.yarnpkg.com/tiptap-utils/-/tiptap-utils-1.13.1.tgz#f2150ded432465d66aa03a5ab333803415cddd20"
- integrity sha512-RoCvMfkdu7fp9u7nsRr1OgsYU8RFjoHKHEKpx075rJ9X0t+j5Vxah9n6QzTTr4yjvcavq22WO2flFacm36zYtA==
- dependencies:
- prosemirror-model "^1.13.1"
- prosemirror-state "^1.3.3"
- prosemirror-tables "^1.1.1"
-
-tiptap@^1.32.2:
- version "1.32.2"
- resolved "https://registry.yarnpkg.com/tiptap/-/tiptap-1.32.2.tgz#cd6259e853652bfc6860758ff44ebb695d5edd1c"
- integrity sha512-5IwVj8nGo8y5V3jbdtoEd7xNUsi8Q0N6WV2Nfs70olqz3fldXkiImBrDhZJ4Anx8vhyP6PIBttrg0prFVmwIvw==
- dependencies:
- prosemirror-commands "^1.1.4"
- prosemirror-dropcursor "^1.3.2"
- prosemirror-gapcursor "^1.1.5"
- prosemirror-inputrules "^1.1.3"
- prosemirror-keymap "^1.1.4"
- prosemirror-model "^1.13.1"
- prosemirror-state "^1.3.3"
- prosemirror-view "^1.16.5"
- tiptap-commands "^1.17.1"
- tiptap-utils "^1.13.1"
-
tmpl@1.0.x:
version "1.0.4"
resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1"